diff options
610 files changed, 43866 insertions, 26201 deletions
diff --git a/Documentation/power/runtime_pm.txt b/Documentation/power/runtime_pm.txt index 356fd86..ab00eed 100644 --- a/Documentation/power/runtime_pm.txt +++ b/Documentation/power/runtime_pm.txt @@ -224,6 +224,12 @@ defined in include/linux/pm.h: RPM_SUSPENDED, which means that each device is initially regarded by the PM core as 'suspended', regardless of its real hardware status + unsigned int runtime_auto; + - if set, indicates that the user space has allowed the device driver to + power manage the device at run time via the /sys/devices/.../power/control + interface; it may only be modified with the help of the pm_runtime_allow() + and pm_runtime_forbid() helper functions + All of the above fields are members of the 'power' member of 'struct device'. 4. Run-time PM Device Helper Functions @@ -329,6 +335,20 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h: 'power.runtime_error' is set or 'power.disable_depth' is greater than zero) + bool pm_runtime_suspended(struct device *dev); + - return true if the device's runtime PM status is 'suspended', or false + otherwise + + void pm_runtime_allow(struct device *dev); + - set the power.runtime_auto flag for the device and decrease its usage + counter (used by the /sys/devices/.../power/control interface to + effectively allow the device to be power managed at run time) + + void pm_runtime_forbid(struct device *dev); + - unset the power.runtime_auto flag for the device and increase its usage + counter (used by the /sys/devices/.../power/control interface to + effectively prevent the device from being power managed at run time) + It is safe to execute the following helper functions from interrupt context: pm_request_idle() @@ -382,6 +402,18 @@ may be desirable to suspend the device as soon as ->probe() or ->remove() has finished, so the PM core uses pm_runtime_idle_sync() to invoke the subsystem-level idle callback for the device at that time. +The user space can effectively disallow the driver of the device to power manage +it at run time by changing the value of its /sys/devices/.../power/control +attribute to "on", which causes pm_runtime_forbid() to be called. In principle, +this mechanism may also be used by the driver to effectively turn off the +run-time power management of the device until the user space turns it on. +Namely, during the initialization the driver can make sure that the run-time PM +status of the device is 'active' and call pm_runtime_forbid(). It should be +noted, however, that if the user space has already intentionally changed the +value of /sys/devices/.../power/control to "auto" to allow the driver to power +manage the device at run time, the driver may confuse it by using +pm_runtime_forbid() this way. + 6. Run-time PM and System Sleep Run-time PM and system sleep (i.e., system suspend and hibernation, also known @@ -431,3 +463,64 @@ The PM core always increments the run-time usage counter before calling the ->prepare() callback and decrements it after calling the ->complete() callback. Hence disabling run-time PM temporarily like this will not cause any run-time suspend callbacks to be lost. + +7. Generic subsystem callbacks + +Subsystems may wish to conserve code space by using the set of generic power +management callbacks provided by the PM core, defined in +driver/base/power/generic_ops.c: + + int pm_generic_runtime_idle(struct device *dev); + - invoke the ->runtime_idle() callback provided by the driver of this + device, if defined, and call pm_runtime_suspend() for this device if the + return value is 0 or the callback is not defined + + int pm_generic_runtime_suspend(struct device *dev); + - invoke the ->runtime_suspend() callback provided by the driver of this + device and return its result, or return -EINVAL if not defined + + int pm_generic_runtime_resume(struct device *dev); + - invoke the ->runtime_resume() callback provided by the driver of this + device and return its result, or return -EINVAL if not defined + + int pm_generic_suspend(struct device *dev); + - if the device has not been suspended at run time, invoke the ->suspend() + callback provided by its driver and return its result, or return 0 if not + defined + + int pm_generic_resume(struct device *dev); + - invoke the ->resume() callback provided by the driver of this device and, + if successful, change the device's runtime PM status to 'active' + + int pm_generic_freeze(struct device *dev); + - if the device has not been suspended at run time, invoke the ->freeze() + callback provided by its driver and return its result, or return 0 if not + defined + + int pm_generic_thaw(struct device *dev); + - if the device has not been suspended at run time, invoke the ->thaw() + callback provided by its driver and return its result, or return 0 if not + defined + + int pm_generic_poweroff(struct device *dev); + - if the device has not been suspended at run time, invoke the ->poweroff() + callback provided by its driver and return its result, or return 0 if not + defined + + int pm_generic_restore(struct device *dev); + - invoke the ->restore() callback provided by the driver of this device and, + if successful, change the device's runtime PM status to 'active' + +These functions can be assigned to the ->runtime_idle(), ->runtime_suspend(), +->runtime_resume(), ->suspend(), ->resume(), ->freeze(), ->thaw(), ->poweroff(), +or ->restore() callback pointers in the subsystem-level dev_pm_ops structures. + +If a subsystem wishes to use all of them at the same time, it can simply assign +the GENERIC_SUBSYS_PM_OPS macro, defined in include/linux/pm.h, to its +dev_pm_ops structure pointer. + +Device drivers that wish to use the same function as a system suspend, freeze, +poweroff and run-time suspend callback, and similarly for system resume, thaw, +restore, and run-time resume, can achieve this with the help of the +UNIVERSAL_DEV_PM_OPS macro defined in include/linux/pm.h (possibly setting its +last argument to NULL). diff --git a/arch/parisc/Kconfig.debug b/arch/parisc/Kconfig.debug index bc989e5..7305ac8 100644 --- a/arch/parisc/Kconfig.debug +++ b/arch/parisc/Kconfig.debug @@ -12,4 +12,18 @@ config DEBUG_RODATA portion of the kernel code won't be covered by a TLB anymore. If in doubt, say "N". +config DEBUG_STRICT_USER_COPY_CHECKS + bool "Strict copy size checks" + depends on DEBUG_KERNEL && !TRACE_BRANCH_PROFILING + ---help--- + Enabling this option turns a certain set of sanity checks for user + copy operations into compile time failures. + + The copy_from_user() etc checks are there to help test if there + are sufficient security checks on the length argument of + the copy operation, by having gcc prove that the argument is + within bounds. + + If unsure, or if you run an older (pre 4.4) gcc, say N. + endmenu diff --git a/arch/parisc/include/asm/param.h b/arch/parisc/include/asm/param.h index 32e03d8..965d454 100644 --- a/arch/parisc/include/asm/param.h +++ b/arch/parisc/include/asm/param.h @@ -1,22 +1 @@ -#ifndef _ASMPARISC_PARAM_H -#define _ASMPARISC_PARAM_H - -#ifdef __KERNEL__ -#define HZ CONFIG_HZ -#define USER_HZ 100 /* some user API use "ticks" */ -#define CLOCKS_PER_SEC (USER_HZ) /* like times() */ -#endif - -#ifndef HZ -#define HZ 100 -#endif - -#define EXEC_PAGESIZE 4096 - -#ifndef NOGROUP -#define NOGROUP (-1) -#endif - -#define MAXHOSTNAMELEN 64 /* max length of hostname */ - -#endif +#include <asm-generic/param.h> diff --git a/arch/parisc/include/asm/system.h b/arch/parisc/include/asm/system.h index d91357b..4653c77 100644 --- a/arch/parisc/include/asm/system.h +++ b/arch/parisc/include/asm/system.h @@ -160,7 +160,7 @@ static inline void set_eiem(unsigned long val) ldcd). */ #define __PA_LDCW_ALIGNMENT 4 -#define __ldcw_align(a) ((volatile unsigned int *)a) +#define __ldcw_align(a) (&(a)->slock) #define __LDCW "ldcw,co" #endif /*!CONFIG_PA20*/ diff --git a/arch/parisc/include/asm/uaccess.h b/arch/parisc/include/asm/uaccess.h index 7cf799d..ff4cf9d 100644 --- a/arch/parisc/include/asm/uaccess.h +++ b/arch/parisc/include/asm/uaccess.h @@ -7,6 +7,7 @@ #include <asm/page.h> #include <asm/system.h> #include <asm/cache.h> +#include <asm/errno.h> #include <asm-generic/uaccess-unaligned.h> #define VERIFY_READ 0 @@ -234,13 +235,35 @@ extern long lstrnlen_user(const char __user *,long); unsigned long copy_to_user(void __user *dst, const void *src, unsigned long len); #define __copy_to_user copy_to_user -unsigned long copy_from_user(void *dst, const void __user *src, unsigned long len); -#define __copy_from_user copy_from_user +unsigned long __copy_from_user(void *dst, const void __user *src, unsigned long len); unsigned long copy_in_user(void __user *dst, const void __user *src, unsigned long len); #define __copy_in_user copy_in_user #define __copy_to_user_inatomic __copy_to_user #define __copy_from_user_inatomic __copy_from_user +extern void copy_from_user_overflow(void) +#ifdef CONFIG_DEBUG_STRICT_USER_COPY_CHECKS + __compiletime_error("copy_from_user() buffer size is not provably correct") +#else + __compiletime_warning("copy_from_user() buffer size is not provably correct") +#endif +; + +static inline unsigned long __must_check copy_from_user(void *to, + const void __user *from, + unsigned long n) +{ + int sz = __compiletime_object_size(to); + int ret = -EFAULT; + + if (likely(sz == -1 || !__builtin_constant_p(n) || sz >= n)) + ret = __copy_from_user(to, from, n); + else + copy_from_user_overflow(); + + return ret; +} + struct pt_regs; int fixup_exception(struct pt_regs *regs); diff --git a/arch/parisc/include/asm/unistd.h b/arch/parisc/include/asm/unistd.h index cda1583..1ce7d28 100644 --- a/arch/parisc/include/asm/unistd.h +++ b/arch/parisc/include/asm/unistd.h @@ -811,8 +811,10 @@ #define __NR_pwritev (__NR_Linux + 316) #define __NR_rt_tgsigqueueinfo (__NR_Linux + 317) #define __NR_perf_event_open (__NR_Linux + 318) +#define __NR_recvmmsg (__NR_Linux + 319) +#define __NR_accept4 (__NR_Linux + 320) -#define __NR_Linux_syscalls (__NR_perf_event_open + 1) +#define __NR_Linux_syscalls (__NR_accept4 + 1) #define __IGNORE_select /* newselect */ diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c index 1054baa..d054f3d 100644 --- a/arch/parisc/kernel/cache.c +++ b/arch/parisc/kernel/cache.c @@ -171,14 +171,14 @@ parisc_cache_init(void) cache_info.ic_conf.cc_cst, cache_info.ic_conf.cc_hv); - printk("D-TLB conf: sh %d page %d cst %d aid %d pad1 %d \n", + printk("D-TLB conf: sh %d page %d cst %d aid %d pad1 %d\n", cache_info.dt_conf.tc_sh, cache_info.dt_conf.tc_page, cache_info.dt_conf.tc_cst, cache_info.dt_conf.tc_aid, cache_info.dt_conf.tc_pad1); - printk("I-TLB conf: sh %d page %d cst %d aid %d pad1 %d \n", + printk("I-TLB conf: sh %d page %d cst %d aid %d pad1 %d\n", cache_info.it_conf.tc_sh, cache_info.it_conf.tc_page, cache_info.it_conf.tc_cst, diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S index 01c4fcf..de5f6da 100644 --- a/arch/parisc/kernel/syscall_table.S +++ b/arch/parisc/kernel/syscall_table.S @@ -417,6 +417,8 @@ ENTRY_COMP(pwritev) ENTRY_COMP(rt_tgsigqueueinfo) ENTRY_SAME(perf_event_open) + ENTRY_COMP(recvmmsg) + ENTRY_SAME(accept4) /* 320 */ /* Nothing yet */ diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c index a79c6f9..05511cc 100644 --- a/arch/parisc/kernel/time.c +++ b/arch/parisc/kernel/time.c @@ -250,9 +250,21 @@ static int __init rtc_init(void) } module_init(rtc_init); -void __init time_init(void) +void read_persistent_clock(struct timespec *ts) { static struct pdc_tod tod_data; + if (pdc_tod_read(&tod_data) == 0) { + ts->tv_sec = tod_data.tod_sec; + ts->tv_nsec = tod_data.tod_usec * 1000; + } else { + printk(KERN_ERR "Error reading tod clock\n"); + ts->tv_sec = 0; + ts->tv_nsec = 0; + } +} + +void __init time_init(void) +{ unsigned long current_cr16_khz; clocktick = (100 * PAGE0->mem_10msec) / HZ; @@ -264,19 +276,4 @@ void __init time_init(void) clocksource_cr16.mult = clocksource_khz2mult(current_cr16_khz, clocksource_cr16.shift); clocksource_register(&clocksource_cr16); - - if (pdc_tod_read(&tod_data) == 0) { - unsigned long flags; - - write_seqlock_irqsave(&xtime_lock, flags); - xtime.tv_sec = tod_data.tod_sec; - xtime.tv_nsec = tod_data.tod_usec * 1000; - set_normalized_timespec(&wall_to_monotonic, - -xtime.tv_sec, -xtime.tv_nsec); - write_sequnlock_irqrestore(&xtime_lock, flags); - } else { - printk(KERN_ERR "Error reading tod clock\n"); - xtime.tv_sec = 0; - xtime.tv_nsec = 0; - } } diff --git a/arch/parisc/kernel/unaligned.c b/arch/parisc/kernel/unaligned.c index e6f4b7a..92d977b 100644 --- a/arch/parisc/kernel/unaligned.c +++ b/arch/parisc/kernel/unaligned.c @@ -25,6 +25,7 @@ #include <linux/module.h> #include <linux/sched.h> #include <linux/signal.h> +#include <linux/ratelimit.h> #include <asm/uaccess.h> /* #define DEBUG_UNALIGNED 1 */ @@ -446,8 +447,7 @@ static int emulate_std(struct pt_regs *regs, int frreg, int flop) void handle_unaligned(struct pt_regs *regs) { - static unsigned long unaligned_count = 0; - static unsigned long last_time = 0; + static DEFINE_RATELIMIT_STATE(ratelimit, 5 * HZ, 5); unsigned long newbase = R1(regs->iir)?regs->gr[R1(regs->iir)]:0; int modify = 0; int ret = ERR_NOTHANDLED; @@ -460,14 +460,8 @@ void handle_unaligned(struct pt_regs *regs) goto force_sigbus; } - if (unaligned_count > 5 && - time_after(jiffies, last_time + 5 * HZ)) { - unaligned_count = 0; - last_time = jiffies; - } - - if (!(current->thread.flags & PARISC_UAC_NOPRINT) - && ++unaligned_count < 5) { + if (!(current->thread.flags & PARISC_UAC_NOPRINT) && + __ratelimit(&ratelimit)) { char buf[256]; sprintf(buf, "%s(%d): unaligned access to 0x" RFMT " at ip=0x" RFMT "\n", current->comm, task_pid_nr(current), regs->ior, regs->iaoq[0]); diff --git a/arch/parisc/lib/memcpy.c b/arch/parisc/lib/memcpy.c index abf41f4..1dbca5c 100644 --- a/arch/parisc/lib/memcpy.c +++ b/arch/parisc/lib/memcpy.c @@ -475,7 +475,8 @@ unsigned long copy_to_user(void __user *dst, const void *src, unsigned long len) return pa_memcpy((void __force *)dst, src, len); } -unsigned long copy_from_user(void *dst, const void __user *src, unsigned long len) +EXPORT_SYMBOL(__copy_from_user); +unsigned long __copy_from_user(void *dst, const void __user *src, unsigned long len) { mtsp(get_user_space(), 1); mtsp(get_kernel_space(), 2); diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c index be300aa..7da0fc9 100644 --- a/arch/sh/boards/mach-migor/setup.c +++ b/arch/sh/boards/mach-migor/setup.c @@ -419,6 +419,9 @@ static struct i2c_board_info migor_i2c_devices[] = { I2C_BOARD_INFO("migor_ts", 0x51), .irq = 38, /* IRQ6 */ }, + { + I2C_BOARD_INFO("wm8978", 0x1a), + }, }; static struct i2c_board_info migor_i2c_camera[] = { @@ -619,6 +622,19 @@ static int __init migor_devices_setup(void) platform_resource_setup_memory(&migor_ceu_device, "ceu", 4 << 20); + /* SIU: Port B */ + gpio_request(GPIO_FN_SIUBOLR, NULL); + gpio_request(GPIO_FN_SIUBOBT, NULL); + gpio_request(GPIO_FN_SIUBISLD, NULL); + gpio_request(GPIO_FN_SIUBOSLD, NULL); + gpio_request(GPIO_FN_SIUMCKB, NULL); + + /* + * The original driver sets SIUB OLR/OBT, ILR/IBT, and SIUA OLR/OBT to + * output. Need only SIUB, set to output for master mode (table 34.2) + */ + __raw_writew(__raw_readw(PORT_MSELCRA) | 1, PORT_MSELCRA); + i2c_register_board_info(0, migor_i2c_devices, ARRAY_SIZE(migor_i2c_devices)); diff --git a/arch/sh/boot/compressed/cache.c b/arch/sh/boot/compressed/cache.c index e27fc74..d0b77b6 100644 --- a/arch/sh/boot/compressed/cache.c +++ b/arch/sh/boot/compressed/cache.c @@ -5,7 +5,7 @@ int cache_control(unsigned int command) for (i = 0; i < (32 * 1024); i += 32) { (void)*p; - p += (32 / sizeof (int)); + p += (32 / sizeof(int)); } return 0; diff --git a/arch/sh/include/asm/cacheflush.h b/arch/sh/include/asm/cacheflush.h index da3ebec..1f4e562 100644 --- a/arch/sh/include/asm/cacheflush.h +++ b/arch/sh/include/asm/cacheflush.h @@ -86,8 +86,8 @@ extern void copy_from_user_page(struct vm_area_struct *vma, struct page *page, unsigned long vaddr, void *dst, const void *src, unsigned long len); -#define flush_cache_vmap(start, end) flush_cache_all() -#define flush_cache_vunmap(start, end) flush_cache_all() +#define flush_cache_vmap(start, end) local_flush_cache_all(NULL) +#define flush_cache_vunmap(start, end) local_flush_cache_all(NULL) #define flush_dcache_mmap_lock(mapping) do { } while (0) #define flush_dcache_mmap_unlock(mapping) do { } while (0) diff --git a/arch/sh/include/asm/dma-register.h b/arch/sh/include/asm/dma-register.h new file mode 100644 index 0000000..51cd78f --- /dev/null +++ b/arch/sh/include/asm/dma-register.h @@ -0,0 +1,51 @@ +/* + * Common header for the legacy SH DMA driver and the new dmaengine driver + * + * extracted from arch/sh/include/asm/dma-sh.h: + * + * Copyright (C) 2000 Takashi YOSHII + * Copyright (C) 2003 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#ifndef DMA_REGISTER_H +#define DMA_REGISTER_H + +/* DMA register */ +#define SAR 0x00 +#define DAR 0x04 +#define TCR 0x08 +#define CHCR 0x0C +#define DMAOR 0x40 + +/* DMAOR definitions */ +#define DMAOR_AE 0x00000004 +#define DMAOR_NMIF 0x00000002 +#define DMAOR_DME 0x00000001 + +/* Definitions for the SuperH DMAC */ +#define REQ_L 0x00000000 +#define REQ_E 0x00080000 +#define RACK_H 0x00000000 +#define RACK_L 0x00040000 +#define ACK_R 0x00000000 +#define ACK_W 0x00020000 +#define ACK_H 0x00000000 +#define ACK_L 0x00010000 +#define DM_INC 0x00004000 +#define DM_DEC 0x00008000 +#define DM_FIX 0x0000c000 +#define SM_INC 0x00001000 +#define SM_DEC 0x00002000 +#define SM_FIX 0x00003000 +#define RS_IN 0x00000200 +#define RS_OUT 0x00000300 +#define TS_BLK 0x00000040 +#define TM_BUR 0x00000020 +#define CHCR_DE 0x00000001 +#define CHCR_TE 0x00000002 +#define CHCR_IE 0x00000004 + +#endif diff --git a/arch/sh/include/asm/dma-sh.h b/arch/sh/include/asm/dma-sh.h index e934a2e..f3acb8e 100644 --- a/arch/sh/include/asm/dma-sh.h +++ b/arch/sh/include/asm/dma-sh.h @@ -11,7 +11,8 @@ #ifndef __DMA_SH_H #define __DMA_SH_H -#include <asm/dma.h> +#include <asm/dma-register.h> +#include <cpu/dma-register.h> #include <cpu/dma.h> /* DMAOR contorl: The DMAOR access size is different by CPU.*/ @@ -53,34 +54,6 @@ static int dmte_irq_map[] __maybe_unused = { #endif }; -/* Definitions for the SuperH DMAC */ -#define REQ_L 0x00000000 -#define REQ_E 0x00080000 -#define RACK_H 0x00000000 -#define RACK_L 0x00040000 -#define ACK_R 0x00000000 -#define ACK_W 0x00020000 -#define ACK_H 0x00000000 -#define ACK_L 0x00010000 -#define DM_INC 0x00004000 -#define DM_DEC 0x00008000 -#define DM_FIX 0x0000c000 -#define SM_INC 0x00001000 -#define SM_DEC 0x00002000 -#define SM_FIX 0x00003000 -#define RS_IN 0x00000200 -#define RS_OUT 0x00000300 -#define TS_BLK 0x00000040 -#define TM_BUR 0x00000020 -#define CHCR_DE 0x00000001 -#define CHCR_TE 0x00000002 -#define CHCR_IE 0x00000004 - -/* DMAOR definitions */ -#define DMAOR_AE 0x00000004 -#define DMAOR_NMIF 0x00000002 -#define DMAOR_DME 0x00000001 - /* * Define the default configuration for dual address memory-memory transfer. * The 0x400 value represents auto-request, external->external. @@ -111,61 +84,4 @@ static u32 dma_base_addr[] __maybe_unused = { #endif }; -/* DMA register */ -#define SAR 0x00 -#define DAR 0x04 -#define TCR 0x08 -#define CHCR 0x0C -#define DMAOR 0x40 - -/* - * for dma engine - * - * SuperH DMA mode - */ -#define SHDMA_MIX_IRQ (1 << 1) -#define SHDMA_DMAOR1 (1 << 2) -#define SHDMA_DMAE1 (1 << 3) - -enum sh_dmae_slave_chan_id { - SHDMA_SLAVE_SCIF0_TX, - SHDMA_SLAVE_SCIF0_RX, - SHDMA_SLAVE_SCIF1_TX, - SHDMA_SLAVE_SCIF1_RX, - SHDMA_SLAVE_SCIF2_TX, - SHDMA_SLAVE_SCIF2_RX, - SHDMA_SLAVE_SCIF3_TX, - SHDMA_SLAVE_SCIF3_RX, - SHDMA_SLAVE_SCIF4_TX, - SHDMA_SLAVE_SCIF4_RX, - SHDMA_SLAVE_SCIF5_TX, - SHDMA_SLAVE_SCIF5_RX, - SHDMA_SLAVE_SIUA_TX, - SHDMA_SLAVE_SIUA_RX, - SHDMA_SLAVE_SIUB_TX, - SHDMA_SLAVE_SIUB_RX, - SHDMA_SLAVE_NUMBER, /* Must stay last */ -}; - -struct sh_dmae_slave_config { - enum sh_dmae_slave_chan_id slave_id; - dma_addr_t addr; - u32 chcr; - char mid_rid; -}; - -struct sh_dmae_pdata { - unsigned int mode; - struct sh_dmae_slave_config *config; - int config_num; -}; - -struct device; - -struct sh_dmae_slave { - enum sh_dmae_slave_chan_id slave_id; /* Set by the platform */ - struct device *dma_dev; /* Set by the platform */ - struct sh_dmae_slave_config *config; /* Set by the driver */ -}; - #endif /* __DMA_SH_H */ diff --git a/arch/sh/include/asm/dmaengine.h b/arch/sh/include/asm/dmaengine.h new file mode 100644 index 0000000..bf2f30cf --- /dev/null +++ b/arch/sh/include/asm/dmaengine.h @@ -0,0 +1,93 @@ +/* + * Header for the new SH dmaengine driver + * + * Copyright (C) 2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef ASM_DMAENGINE_H +#define ASM_DMAENGINE_H + +#include <linux/dmaengine.h> +#include <linux/list.h> + +#include <asm/dma-register.h> + +#define SH_DMAC_MAX_CHANNELS 6 + +enum sh_dmae_slave_chan_id { + SHDMA_SLAVE_SCIF0_TX, + SHDMA_SLAVE_SCIF0_RX, + SHDMA_SLAVE_SCIF1_TX, + SHDMA_SLAVE_SCIF1_RX, + SHDMA_SLAVE_SCIF2_TX, + SHDMA_SLAVE_SCIF2_RX, + SHDMA_SLAVE_SCIF3_TX, + SHDMA_SLAVE_SCIF3_RX, + SHDMA_SLAVE_SCIF4_TX, + SHDMA_SLAVE_SCIF4_RX, + SHDMA_SLAVE_SCIF5_TX, + SHDMA_SLAVE_SCIF5_RX, + SHDMA_SLAVE_SIUA_TX, + SHDMA_SLAVE_SIUA_RX, + SHDMA_SLAVE_SIUB_TX, + SHDMA_SLAVE_SIUB_RX, + SHDMA_SLAVE_NUMBER, /* Must stay last */ +}; + +struct sh_dmae_slave_config { + enum sh_dmae_slave_chan_id slave_id; + dma_addr_t addr; + u32 chcr; + char mid_rid; +}; + +struct sh_dmae_channel { + unsigned int offset; + unsigned int dmars; + unsigned int dmars_bit; +}; + +struct sh_dmae_pdata { + struct sh_dmae_slave_config *slave; + int slave_num; + struct sh_dmae_channel *channel; + int channel_num; + unsigned int ts_low_shift; + unsigned int ts_low_mask; + unsigned int ts_high_shift; + unsigned int ts_high_mask; + unsigned int *ts_shift; + int ts_shift_num; + u16 dmaor_init; +}; + +struct device; + +/* Used by slave DMA clients to request DMA to/from a specific peripheral */ +struct sh_dmae_slave { + enum sh_dmae_slave_chan_id slave_id; /* Set by the platform */ + struct device *dma_dev; /* Set by the platform */ + struct sh_dmae_slave_config *config; /* Set by the driver */ +}; + +struct sh_dmae_regs { + u32 sar; /* SAR / source address */ + u32 dar; /* DAR / destination address */ + u32 tcr; /* TCR / transfer count */ +}; + +struct sh_desc { + struct sh_dmae_regs hw; + struct list_head node; + struct dma_async_tx_descriptor async_tx; + enum dma_data_direction direction; + dma_cookie_t cookie; + size_t partial; + int chunks; + int mark; +}; + +#endif diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h index 7dab7b23..f689554 100644 --- a/arch/sh/include/asm/io.h +++ b/arch/sh/include/asm/io.h @@ -291,21 +291,21 @@ unsigned long long poke_real_address_q(unsigned long long addr, * doesn't exist, so everything must go through page tables. */ #ifdef CONFIG_MMU -void __iomem *__ioremap_caller(unsigned long offset, unsigned long size, +void __iomem *__ioremap_caller(phys_addr_t offset, unsigned long size, pgprot_t prot, void *caller); void __iounmap(void __iomem *addr); static inline void __iomem * -__ioremap(unsigned long offset, unsigned long size, pgprot_t prot) +__ioremap(phys_addr_t offset, unsigned long size, pgprot_t prot) { return __ioremap_caller(offset, size, prot, __builtin_return_address(0)); } static inline void __iomem * -__ioremap_29bit(unsigned long offset, unsigned long size, pgprot_t prot) +__ioremap_29bit(phys_addr_t offset, unsigned long size, pgprot_t prot) { #ifdef CONFIG_29BIT - unsigned long last_addr = offset + size - 1; + phys_addr_t last_addr = offset + size - 1; /* * For P1 and P2 space this is trivial, as everything is already @@ -329,7 +329,7 @@ __ioremap_29bit(unsigned long offset, unsigned long size, pgprot_t prot) } static inline void __iomem * -__ioremap_mode(unsigned long offset, unsigned long size, pgprot_t prot) +__ioremap_mode(phys_addr_t offset, unsigned long size, pgprot_t prot) { void __iomem *ret; @@ -349,35 +349,32 @@ __ioremap_mode(unsigned long offset, unsigned long size, pgprot_t prot) #define __iounmap(addr) do { } while (0) #endif /* CONFIG_MMU */ -static inline void __iomem * -ioremap(unsigned long offset, unsigned long size) +static inline void __iomem *ioremap(phys_addr_t offset, unsigned long size) { return __ioremap_mode(offset, size, PAGE_KERNEL_NOCACHE); } static inline void __iomem * -ioremap_cache(unsigned long offset, unsigned long size) +ioremap_cache(phys_addr_t offset, unsigned long size) { return __ioremap_mode(offset, size, PAGE_KERNEL); } #ifdef CONFIG_HAVE_IOREMAP_PROT static inline void __iomem * -ioremap_prot(resource_size_t offset, unsigned long size, unsigned long flags) +ioremap_prot(phys_addr_t offset, unsigned long size, unsigned long flags) { return __ioremap_mode(offset, size, __pgprot(flags)); } #endif #ifdef CONFIG_IOREMAP_FIXED -extern void __iomem *ioremap_fixed(resource_size_t, unsigned long, - unsigned long, pgprot_t); +extern void __iomem *ioremap_fixed(phys_addr_t, unsigned long, pgprot_t); extern int iounmap_fixed(void __iomem *); extern void ioremap_fixed_init(void); #else static inline void __iomem * -ioremap_fixed(resource_size_t phys_addr, unsigned long offset, - unsigned long size, pgprot_t prot) +ioremap_fixed(phys_addr_t phys_addr, unsigned long size, pgprot_t prot) { BUG(); return NULL; diff --git a/arch/sh/include/asm/mmu.h b/arch/sh/include/asm/mmu.h index 15a05b6..19fe845 100644 --- a/arch/sh/include/asm/mmu.h +++ b/arch/sh/include/asm/mmu.h @@ -55,19 +55,29 @@ typedef struct { #ifdef CONFIG_PMB /* arch/sh/mm/pmb.c */ -long pmb_remap(unsigned long virt, unsigned long phys, - unsigned long size, pgprot_t prot); -void pmb_unmap(unsigned long addr); -void pmb_init(void); bool __in_29bit_mode(void); + +void pmb_init(void); +int pmb_bolt_mapping(unsigned long virt, phys_addr_t phys, + unsigned long size, pgprot_t prot); +void __iomem *pmb_remap_caller(phys_addr_t phys, unsigned long size, + pgprot_t prot, void *caller); +int pmb_unmap(void __iomem *addr); + #else -static inline long pmb_remap(unsigned long virt, unsigned long phys, - unsigned long size, pgprot_t prot) + +static inline void __iomem * +pmb_remap_caller(phys_addr_t phys, unsigned long size, + pgprot_t prot, void *caller) +{ + return NULL; +} + +static inline int pmb_unmap(void __iomem *addr) { return -EINVAL; } -#define pmb_unmap(addr) do { } while (0) #define pmb_init(addr) do { } while (0) #ifdef CONFIG_29BIT @@ -77,6 +87,13 @@ static inline long pmb_remap(unsigned long virt, unsigned long phys, #endif #endif /* CONFIG_PMB */ + +static inline void __iomem * +pmb_remap(phys_addr_t phys, unsigned long size, pgprot_t prot) +{ + return pmb_remap_caller(phys, size, prot, __builtin_return_address(0)); +} + #endif /* __ASSEMBLY__ */ #endif /* __MMU_H */ diff --git a/arch/sh/include/asm/siu.h b/arch/sh/include/asm/siu.h index 57565a3..f1b1e69 100644 --- a/arch/sh/include/asm/siu.h +++ b/arch/sh/include/asm/siu.h @@ -11,7 +11,7 @@ #ifndef ASM_SIU_H #define ASM_SIU_H -#include <asm/dma-sh.h> +#include <asm/dmaengine.h> struct device; diff --git a/arch/sh/include/asm/topology.h b/arch/sh/include/asm/topology.h index 37cdadd..88e7340 100644 --- a/arch/sh/include/asm/topology.h +++ b/arch/sh/include/asm/topology.h @@ -35,7 +35,7 @@ #define pcibus_to_node(bus) ((void)(bus), -1) #define cpumask_of_pcibus(bus) (pcibus_to_node(bus) == -1 ? \ - CPU_MASK_ALL_PTR : \ + cpu_all_mask : \ cpumask_of_node(pcibus_to_node(bus))) #endif diff --git a/arch/sh/include/cpu-sh3/cpu/dma-register.h b/arch/sh/include/cpu-sh3/cpu/dma-register.h new file mode 100644 index 0000000..2349e48 --- /dev/null +++ b/arch/sh/include/cpu-sh3/cpu/dma-register.h @@ -0,0 +1,41 @@ +/* + * SH3 CPU-specific DMA definitions, used by both DMA drivers + * + * Copyright (C) 2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef CPU_DMA_REGISTER_H +#define CPU_DMA_REGISTER_H + +#define CHCR_TS_LOW_MASK 0x18 +#define CHCR_TS_LOW_SHIFT 3 +#define CHCR_TS_HIGH_MASK 0 +#define CHCR_TS_HIGH_SHIFT 0 + +#define DMAOR_INIT DMAOR_DME + +/* + * The SuperH DMAC supports a number of transmit sizes, we list them here, + * with their respective values as they appear in the CHCR registers. + */ +enum { + XMIT_SZ_8BIT, + XMIT_SZ_16BIT, + XMIT_SZ_32BIT, + XMIT_SZ_128BIT, +}; + +/* log2(size / 8) - used to calculate number of transfers */ +#define TS_SHIFT { \ + [XMIT_SZ_8BIT] = 0, \ + [XMIT_SZ_16BIT] = 1, \ + [XMIT_SZ_32BIT] = 2, \ + [XMIT_SZ_128BIT] = 4, \ +} + +#define TS_INDEX2VAL(i) (((i) & 3) << CHCR_TS_LOW_SHIFT) + +#endif diff --git a/arch/sh/include/cpu-sh3/cpu/dma.h b/arch/sh/include/cpu-sh3/cpu/dma.h index 207811a..24e28b9 100644 --- a/arch/sh/include/cpu-sh3/cpu/dma.h +++ b/arch/sh/include/cpu-sh3/cpu/dma.h @@ -20,31 +20,4 @@ #define TS_32 0x00000010 #define TS_128 0x00000018 -#define CHCR_TS_LOW_MASK 0x18 -#define CHCR_TS_LOW_SHIFT 3 -#define CHCR_TS_HIGH_MASK 0 -#define CHCR_TS_HIGH_SHIFT 0 - -#define DMAOR_INIT DMAOR_DME - -/* - * The SuperH DMAC supports a number of transmit sizes, we list them here, - * with their respective values as they appear in the CHCR registers. - */ -enum { - XMIT_SZ_8BIT, - XMIT_SZ_16BIT, - XMIT_SZ_32BIT, - XMIT_SZ_128BIT, -}; - -#define TS_SHIFT { \ - [XMIT_SZ_8BIT] = 0, \ - [XMIT_SZ_16BIT] = 1, \ - [XMIT_SZ_32BIT] = 2, \ - [XMIT_SZ_128BIT] = 4, \ -} - -#define TS_INDEX2VAL(i) (((i) & 3) << CHCR_TS_LOW_SHIFT) - #endif /* __ASM_CPU_SH3_DMA_H */ diff --git a/arch/sh/include/cpu-sh4/cpu/dma-register.h b/arch/sh/include/cpu-sh4/cpu/dma-register.h new file mode 100644 index 0000000..55f9fec --- /dev/null +++ b/arch/sh/include/cpu-sh4/cpu/dma-register.h @@ -0,0 +1,112 @@ +/* + * SH4 CPU-specific DMA definitions, used by both DMA drivers + * + * Copyright (C) 2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef CPU_DMA_REGISTER_H +#define CPU_DMA_REGISTER_H + +/* SH7751/7760/7780 DMA IRQ sources */ + +#ifdef CONFIG_CPU_SH4A + +#define DMAOR_INIT DMAOR_DME + +#if defined(CONFIG_CPU_SUBTYPE_SH7343) || \ + defined(CONFIG_CPU_SUBTYPE_SH7730) +#define CHCR_TS_LOW_MASK 0x00000018 +#define CHCR_TS_LOW_SHIFT 3 +#define CHCR_TS_HIGH_MASK 0 +#define CHCR_TS_HIGH_SHIFT 0 +#elif defined(CONFIG_CPU_SUBTYPE_SH7722) || \ + defined(CONFIG_CPU_SUBTYPE_SH7724) +#define CHCR_TS_LOW_MASK 0x00000018 +#define CHCR_TS_LOW_SHIFT 3 +#define CHCR_TS_HIGH_MASK 0x00300000 +#define CHCR_TS_HIGH_SHIFT (20 - 2) /* 2 bits for shifted low TS */ +#elif defined(CONFIG_CPU_SUBTYPE_SH7763) || \ + defined(CONFIG_CPU_SUBTYPE_SH7764) +#define CHCR_TS_LOW_MASK 0x00000018 +#define CHCR_TS_LOW_SHIFT 3 +#define CHCR_TS_HIGH_MASK 0 +#define CHCR_TS_HIGH_SHIFT 0 +#elif defined(CONFIG_CPU_SUBTYPE_SH7723) +#define CHCR_TS_LOW_MASK 0x00000018 +#define CHCR_TS_LOW_SHIFT 3 +#define CHCR_TS_HIGH_MASK 0 +#define CHCR_TS_HIGH_SHIFT 0 +#elif defined(CONFIG_CPU_SUBTYPE_SH7780) +#define CHCR_TS_LOW_MASK 0x00000018 +#define CHCR_TS_LOW_SHIFT 3 +#define CHCR_TS_HIGH_MASK 0 +#define CHCR_TS_HIGH_SHIFT 0 +#else /* SH7785 */ +#define CHCR_TS_LOW_MASK 0x00000018 +#define CHCR_TS_LOW_SHIFT 3 +#define CHCR_TS_HIGH_MASK 0 +#define CHCR_TS_HIGH_SHIFT 0 +#endif + +/* Transmit sizes and respective CHCR register values */ +enum { + XMIT_SZ_8BIT = 0, + XMIT_SZ_16BIT = 1, + XMIT_SZ_32BIT = 2, + XMIT_SZ_64BIT = 7, + XMIT_SZ_128BIT = 3, + XMIT_SZ_256BIT = 4, + XMIT_SZ_128BIT_BLK = 0xb, + XMIT_SZ_256BIT_BLK = 0xc, +}; + +/* log2(size / 8) - used to calculate number of transfers */ +#define TS_SHIFT { \ + [XMIT_SZ_8BIT] = 0, \ + [XMIT_SZ_16BIT] = 1, \ + [XMIT_SZ_32BIT] = 2, \ + [XMIT_SZ_64BIT] = 3, \ + [XMIT_SZ_128BIT] = 4, \ + [XMIT_SZ_256BIT] = 5, \ + [XMIT_SZ_128BIT_BLK] = 4, \ + [XMIT_SZ_256BIT_BLK] = 5, \ +} + +#define TS_INDEX2VAL(i) ((((i) & 3) << CHCR_TS_LOW_SHIFT) | \ + ((((i) >> 2) & 3) << CHCR_TS_HIGH_SHIFT)) + +#else /* CONFIG_CPU_SH4A */ + +#define DMAOR_INIT (0x8000 | DMAOR_DME) + +#define CHCR_TS_LOW_MASK 0x70 +#define CHCR_TS_LOW_SHIFT 4 +#define CHCR_TS_HIGH_MASK 0 +#define CHCR_TS_HIGH_SHIFT 0 + +/* Transmit sizes and respective CHCR register values */ +enum { + XMIT_SZ_8BIT = 1, + XMIT_SZ_16BIT = 2, + XMIT_SZ_32BIT = 3, + XMIT_SZ_64BIT = 0, + XMIT_SZ_256BIT = 4, +}; + +/* log2(size / 8) - used to calculate number of transfers */ +#define TS_SHIFT { \ + [XMIT_SZ_8BIT] = 0, \ + [XMIT_SZ_16BIT] = 1, \ + [XMIT_SZ_32BIT] = 2, \ + [XMIT_SZ_64BIT] = 3, \ + [XMIT_SZ_256BIT] = 5, \ +} + +#define TS_INDEX2VAL(i) (((i) & 7) << CHCR_TS_LOW_SHIFT) + +#endif /* CONFIG_CPU_SH4A */ + +#endif diff --git a/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h b/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h index e734ea4..9647e68 100644 --- a/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h +++ b/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h @@ -8,20 +8,12 @@ #define DMAE0_IRQ 78 /* DMA Error IRQ*/ #define SH_DMAC_BASE0 0xFE008020 #define SH_DMARS_BASE0 0xFE009000 -#define CHCR_TS_LOW_MASK 0x00000018 -#define CHCR_TS_LOW_SHIFT 3 -#define CHCR_TS_HIGH_MASK 0 -#define CHCR_TS_HIGH_SHIFT 0 #elif defined(CONFIG_CPU_SUBTYPE_SH7722) #define DMTE0_IRQ 48 #define DMTE4_IRQ 76 #define DMAE0_IRQ 78 /* DMA Error IRQ*/ #define SH_DMAC_BASE0 0xFE008020 #define SH_DMARS_BASE0 0xFE009000 -#define CHCR_TS_LOW_MASK 0x00000018 -#define CHCR_TS_LOW_SHIFT 3 -#define CHCR_TS_HIGH_MASK 0x00300000 -#define CHCR_TS_HIGH_SHIFT 20 #elif defined(CONFIG_CPU_SUBTYPE_SH7763) || \ defined(CONFIG_CPU_SUBTYPE_SH7764) #define DMTE0_IRQ 34 @@ -29,10 +21,6 @@ #define DMAE0_IRQ 38 #define SH_DMAC_BASE0 0xFF608020 #define SH_DMARS_BASE0 0xFF609000 -#define CHCR_TS_LOW_MASK 0x00000018 -#define CHCR_TS_LOW_SHIFT 3 -#define CHCR_TS_HIGH_MASK 0 -#define CHCR_TS_HIGH_SHIFT 0 #elif defined(CONFIG_CPU_SUBTYPE_SH7723) #define DMTE0_IRQ 48 /* DMAC0A*/ #define DMTE4_IRQ 76 /* DMAC0B */ @@ -46,10 +34,6 @@ #define SH_DMAC_BASE0 0xFE008020 #define SH_DMAC_BASE1 0xFDC08020 #define SH_DMARS_BASE0 0xFDC09000 -#define CHCR_TS_LOW_MASK 0x00000018 -#define CHCR_TS_LOW_SHIFT 3 -#define CHCR_TS_HIGH_MASK 0 -#define CHCR_TS_HIGH_SHIFT 0 #elif defined(CONFIG_CPU_SUBTYPE_SH7724) #define DMTE0_IRQ 48 /* DMAC0A*/ #define DMTE4_IRQ 76 /* DMAC0B */ @@ -64,10 +48,6 @@ #define SH_DMAC_BASE1 0xFDC08020 #define SH_DMARS_BASE0 0xFE009000 #define SH_DMARS_BASE1 0xFDC09000 -#define CHCR_TS_LOW_MASK 0x00000018 -#define CHCR_TS_LOW_SHIFT 3 -#define CHCR_TS_HIGH_MASK 0x00600000 -#define CHCR_TS_HIGH_SHIFT 21 #elif defined(CONFIG_CPU_SUBTYPE_SH7780) #define DMTE0_IRQ 34 #define DMTE4_IRQ 44 @@ -80,10 +60,6 @@ #define SH_DMAC_BASE0 0xFC808020 #define SH_DMAC_BASE1 0xFC818020 #define SH_DMARS_BASE0 0xFC809000 -#define CHCR_TS_LOW_MASK 0x00000018 -#define CHCR_TS_LOW_SHIFT 3 -#define CHCR_TS_HIGH_MASK 0 -#define CHCR_TS_HIGH_SHIFT 0 #else /* SH7785 */ #define DMTE0_IRQ 33 #define DMTE4_IRQ 37 @@ -97,10 +73,6 @@ #define SH_DMAC_BASE0 0xFC808020 #define SH_DMAC_BASE1 0xFCC08020 #define SH_DMARS_BASE0 0xFC809000 -#define CHCR_TS_LOW_MASK 0x00000018 -#define CHCR_TS_LOW_SHIFT 3 -#define CHCR_TS_HIGH_MASK 0 -#define CHCR_TS_HIGH_SHIFT 0 #endif #define REQ_HE 0x000000C0 @@ -108,38 +80,4 @@ #define REQ_LE 0x00000040 #define TM_BURST 0x00000020 -/* - * The SuperH DMAC supports a number of transmit sizes, we list them here, - * with their respective values as they appear in the CHCR registers. - * - * Defaults to a 64-bit transfer size. - */ -enum { - XMIT_SZ_8BIT = 0, - XMIT_SZ_16BIT = 1, - XMIT_SZ_32BIT = 2, - XMIT_SZ_64BIT = 7, - XMIT_SZ_128BIT = 3, - XMIT_SZ_256BIT = 4, - XMIT_SZ_128BIT_BLK = 0xb, - XMIT_SZ_256BIT_BLK = 0xc, -}; - -/* - * The DMA count is defined as the number of bytes to transfer. - */ -#define TS_SHIFT { \ - [XMIT_SZ_8BIT] = 0, \ - [XMIT_SZ_16BIT] = 1, \ - [XMIT_SZ_32BIT] = 2, \ - [XMIT_SZ_64BIT] = 3, \ - [XMIT_SZ_128BIT] = 4, \ - [XMIT_SZ_256BIT] = 5, \ - [XMIT_SZ_128BIT_BLK] = 4, \ - [XMIT_SZ_256BIT_BLK] = 5, \ -} - -#define TS_INDEX2VAL(i) ((((i) & 3) << CHCR_TS_LOW_SHIFT) | \ - ((((i) >> 2) & 3) << CHCR_TS_HIGH_SHIFT)) - #endif /* __ASM_SH_CPU_SH4_DMA_SH7780_H */ diff --git a/arch/sh/include/cpu-sh4/cpu/dma.h b/arch/sh/include/cpu-sh4/cpu/dma.h index 114a369..ca747e9 100644 --- a/arch/sh/include/cpu-sh4/cpu/dma.h +++ b/arch/sh/include/cpu-sh4/cpu/dma.h @@ -5,9 +5,8 @@ #ifdef CONFIG_CPU_SH4A -#define DMAOR_INIT (DMAOR_DME) - #include <cpu/dma-sh4a.h> + #else /* CONFIG_CPU_SH4A */ /* * SH7750/SH7751/SH7760 @@ -17,7 +16,6 @@ #define DMTE6_IRQ 46 #define DMAE0_IRQ 38 -#define DMAOR_INIT (0x8000|DMAOR_DME) #define SH_DMAC_BASE0 0xffa00000 #define SH_DMAC_BASE1 0xffa00070 /* Definitions for the SuperH DMAC */ @@ -27,40 +25,8 @@ #define TS_32 0x00000030 #define TS_64 0x00000000 -#define CHCR_TS_LOW_MASK 0x70 -#define CHCR_TS_LOW_SHIFT 4 -#define CHCR_TS_HIGH_MASK 0 -#define CHCR_TS_HIGH_SHIFT 0 - #define DMAOR_COD 0x00000008 -/* - * The SuperH DMAC supports a number of transmit sizes, we list them here, - * with their respective values as they appear in the CHCR registers. - * - * Defaults to a 64-bit transfer size. - */ -enum { - XMIT_SZ_8BIT = 1, - XMIT_SZ_16BIT = 2, - XMIT_SZ_32BIT = 3, - XMIT_SZ_64BIT = 0, - XMIT_SZ_256BIT = 4, -}; - -/* - * The DMA count is defined as the number of bytes to transfer. - */ -#define TS_SHIFT { \ - [XMIT_SZ_8BIT] = 0, \ - [XMIT_SZ_16BIT] = 1, \ - [XMIT_SZ_32BIT] = 2, \ - [XMIT_SZ_64BIT] = 3, \ - [XMIT_SZ_256BIT] = 5, \ -} - -#define TS_INDEX2VAL(i) (((i) & 7) << CHCR_TS_LOW_SHIFT) - #endif #endif /* __ASM_CPU_SH4_DMA_H */ diff --git a/arch/sh/include/mach-migor/mach/migor.h b/arch/sh/include/mach-migor/mach/migor.h index cee6cb8..42fccf9 100644 --- a/arch/sh/include/mach-migor/mach/migor.h +++ b/arch/sh/include/mach-migor/mach/migor.h @@ -1,6 +1,7 @@ #ifndef __ASM_SH_MIGOR_H #define __ASM_SH_MIGOR_H +#define PORT_MSELCRA 0xa4050180 #define PORT_MSELCRB 0xa4050182 #define BSC_CS4BCR 0xfec10010 #define BSC_CS6ABCR 0xfec1001c diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c index ef3f978..fd7e363 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c @@ -7,19 +7,167 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. */ -#include <linux/platform_device.h> #include <linux/init.h> +#include <linux/mm.h> +#include <linux/platform_device.h> #include <linux/serial.h> #include <linux/serial_sci.h> -#include <linux/mm.h> +#include <linux/sh_timer.h> #include <linux/uio_driver.h> #include <linux/usb/m66592.h> -#include <linux/sh_timer.h> + #include <asm/clock.h> +#include <asm/dmaengine.h> #include <asm/mmzone.h> -#include <asm/dma-sh.h> +#include <asm/siu.h> + +#include <cpu/dma-register.h> #include <cpu/sh7722.h> +static struct sh_dmae_slave_config sh7722_dmae_slaves[] = { + { + .slave_id = SHDMA_SLAVE_SCIF0_TX, + .addr = 0xffe0000c, + .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), + .mid_rid = 0x21, + }, { + .slave_id = SHDMA_SLAVE_SCIF0_RX, + .addr = 0xffe00014, + .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), + .mid_rid = 0x22, + }, { + .slave_id = SHDMA_SLAVE_SCIF1_TX, + .addr = 0xffe1000c, + .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), + .mid_rid = 0x25, + }, { + .slave_id = SHDMA_SLAVE_SCIF1_RX, + .addr = 0xffe10014, + .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), + .mid_rid = 0x26, + }, { + .slave_id = SHDMA_SLAVE_SCIF2_TX, + .addr = 0xffe2000c, + .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), + .mid_rid = 0x29, + }, { + .slave_id = SHDMA_SLAVE_SCIF2_RX, + .addr = 0xffe20014, + .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), + .mid_rid = 0x2a, + }, { + .slave_id = SHDMA_SLAVE_SIUA_TX, + .addr = 0xa454c098, + .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_32BIT), + .mid_rid = 0xb1, + }, { + .slave_id = SHDMA_SLAVE_SIUA_RX, + .addr = 0xa454c090, + .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_32BIT), + .mid_rid = 0xb2, + }, { + .slave_id = SHDMA_SLAVE_SIUB_TX, + .addr = 0xa454c09c, + .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_32BIT), + .mid_rid = 0xb5, + }, { + .slave_id = SHDMA_SLAVE_SIUB_RX, + .addr = 0xa454c094, + .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_32BIT), + .mid_rid = 0xb6, + }, +}; + +static struct sh_dmae_channel sh7722_dmae_channels[] = { + { + .offset = 0, + .dmars = 0, + .dmars_bit = 0, + }, { + .offset = 0x10, + .dmars = 0, + .dmars_bit = 8, + }, { + .offset = 0x20, + .dmars = 4, + .dmars_bit = 0, + }, { + .offset = 0x30, + .dmars = 4, + .dmars_bit = 8, + }, { + .offset = 0x50, + .dmars = 8, + .dmars_bit = 0, + }, { + .offset = 0x60, + .dmars = 8, + .dmars_bit = 8, + } +}; + +static unsigned int ts_shift[] = TS_SHIFT; + +static struct sh_dmae_pdata dma_platform_data = { + .slave = sh7722_dmae_slaves, + .slave_num = ARRAY_SIZE(sh7722_dmae_slaves), + .channel = sh7722_dmae_channels, + .channel_num = ARRAY_SIZE(sh7722_dmae_channels), + .ts_low_shift = CHCR_TS_LOW_SHIFT, + .ts_low_mask = CHCR_TS_LOW_MASK, + .ts_high_shift = CHCR_TS_HIGH_SHIFT, + .ts_high_mask = CHCR_TS_HIGH_MASK, + .ts_shift = ts_shift, + .ts_shift_num = ARRAY_SIZE(ts_shift), + .dmaor_init = DMAOR_INIT, +}; + +static struct resource sh7722_dmae_resources[] = { + [0] = { + /* Channel registers and DMAOR */ + .start = 0xfe008020, + .end = 0xfe00808f, + .flags = IORESOURCE_MEM, + }, + [1] = { + /* DMARSx */ + .start = 0xfe009000, + .end = 0xfe00900b, + .flags = IORESOURCE_MEM, + }, + { + /* DMA error IRQ */ + .start = 78, + .end = 78, + .flags = IORESOURCE_IRQ, + }, + { + /* IRQ for channels 0-3 */ + .start = 48, + .end = 51, + .flags = IORESOURCE_IRQ, + }, + { + /* IRQ for channels 4-5 */ + .start = 76, + .end = 77, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device dma_device = { + .name = "sh-dma-engine", + .id = -1, + .resource = sh7722_dmae_resources, + .num_resources = ARRAY_SIZE(sh7722_dmae_resources), + .dev = { + .platform_data = &dma_platform_data, + }, + .archdata = { + .hwblk_id = HWBLK_DMAC, + }, +}; + /* Serial */ static struct plat_sci_port scif0_platform_data = { .mapbase = 0xffe00000, @@ -388,15 +536,36 @@ static struct platform_device tmu2_device = { }, }; -static struct sh_dmae_pdata dma_platform_data = { - .mode = 0, +static struct siu_platform siu_platform_data = { + .dma_dev = &dma_device.dev, + .dma_slave_tx_a = SHDMA_SLAVE_SIUA_TX, + .dma_slave_rx_a = SHDMA_SLAVE_SIUA_RX, + .dma_slave_tx_b = SHDMA_SLAVE_SIUB_TX, + .dma_slave_rx_b = SHDMA_SLAVE_SIUB_RX, }; -static struct platform_device dma_device = { - .name = "sh-dma-engine", +static struct resource siu_resources[] = { + [0] = { + .start = 0xa4540000, + .end = 0xa454c10f, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 108, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device siu_device = { + .name = "sh_siu", .id = -1, - .dev = { - .platform_data = &dma_platform_data, + .dev = { + .platform_data = &siu_platform_data, + }, + .resource = siu_resources, + .num_resources = ARRAY_SIZE(siu_resources), + .archdata = { + .hwblk_id = HWBLK_SIU, }, }; @@ -414,6 +583,7 @@ static struct platform_device *sh7722_devices[] __initdata = { &vpu_device, &veu_device, &jpu_device, + &siu_device, &dma_device, }; diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c index 31e3451..e7fa2a9 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c @@ -21,22 +21,189 @@ #include <linux/sh_timer.h> #include <linux/io.h> #include <linux/notifier.h> + #include <asm/suspend.h> #include <asm/clock.h> -#include <asm/dma-sh.h> +#include <asm/dmaengine.h> #include <asm/mmzone.h> + +#include <cpu/dma-register.h> #include <cpu/sh7724.h> /* DMA */ -static struct sh_dmae_pdata dma_platform_data = { - .mode = SHDMA_DMAOR1, +static struct sh_dmae_channel sh7724_dmae0_channels[] = { + { + .offset = 0, + .dmars = 0, + .dmars_bit = 0, + }, { + .offset = 0x10, + .dmars = 0, + .dmars_bit = 8, + }, { + .offset = 0x20, + .dmars = 4, + .dmars_bit = 0, + }, { + .offset = 0x30, + .dmars = 4, + .dmars_bit = 8, + }, { + .offset = 0x50, + .dmars = 8, + .dmars_bit = 0, + }, { + .offset = 0x60, + .dmars = 8, + .dmars_bit = 8, + } +}; + +static struct sh_dmae_channel sh7724_dmae1_channels[] = { + { + .offset = 0, + .dmars = 0, + .dmars_bit = 0, + }, { + .offset = 0x10, + .dmars = 0, + .dmars_bit = 8, + }, { + .offset = 0x20, + .dmars = 4, + .dmars_bit = 0, + }, { + .offset = 0x30, + .dmars = 4, + .dmars_bit = 8, + }, { + .offset = 0x50, + .dmars = 8, + .dmars_bit = 0, + }, { + .offset = 0x60, + .dmars = 8, + .dmars_bit = 8, + } +}; + +static unsigned int ts_shift[] = TS_SHIFT; + +static struct sh_dmae_pdata dma0_platform_data = { + .channel = sh7724_dmae0_channels, + .channel_num = ARRAY_SIZE(sh7724_dmae0_channels), + .ts_low_shift = CHCR_TS_LOW_SHIFT, + .ts_low_mask = CHCR_TS_LOW_MASK, + .ts_high_shift = CHCR_TS_HIGH_SHIFT, + .ts_high_mask = CHCR_TS_HIGH_MASK, + .ts_shift = ts_shift, + .ts_shift_num = ARRAY_SIZE(ts_shift), + .dmaor_init = DMAOR_INIT, +}; + +static struct sh_dmae_pdata dma1_platform_data = { + .channel = sh7724_dmae1_channels, + .channel_num = ARRAY_SIZE(sh7724_dmae1_channels), + .ts_low_shift = CHCR_TS_LOW_SHIFT, + .ts_low_mask = CHCR_TS_LOW_MASK, + .ts_high_shift = CHCR_TS_HIGH_SHIFT, + .ts_high_mask = CHCR_TS_HIGH_MASK, + .ts_shift = ts_shift, + .ts_shift_num = ARRAY_SIZE(ts_shift), + .dmaor_init = DMAOR_INIT, +}; + +/* Resource order important! */ +static struct resource sh7724_dmae0_resources[] = { + { + /* Channel registers and DMAOR */ + .start = 0xfe008020, + .end = 0xfe00808f, + .flags = IORESOURCE_MEM, + }, + { + /* DMARSx */ + .start = 0xfe009000, + .end = 0xfe00900b, + .flags = IORESOURCE_MEM, + }, + { + /* DMA error IRQ */ + .start = 78, + .end = 78, + .flags = IORESOURCE_IRQ, + }, + { + /* IRQ for channels 0-3 */ + .start = 48, + .end = 51, + .flags = IORESOURCE_IRQ, + }, + { + /* IRQ for channels 4-5 */ + .start = 76, + .end = 77, + .flags = IORESOURCE_IRQ, + }, }; -static struct platform_device dma_device = { - .name = "sh-dma-engine", - .id = -1, - .dev = { - .platform_data = &dma_platform_data, +/* Resource order important! */ +static struct resource sh7724_dmae1_resources[] = { + { + /* Channel registers and DMAOR */ + .start = 0xfdc08020, + .end = 0xfdc0808f, + .flags = IORESOURCE_MEM, + }, + { + /* DMARSx */ + .start = 0xfdc09000, + .end = 0xfdc0900b, + .flags = IORESOURCE_MEM, + }, + { + /* DMA error IRQ */ + .start = 74, + .end = 74, + .flags = IORESOURCE_IRQ, + }, + { + /* IRQ for channels 0-3 */ + .start = 40, + .end = 43, + .flags = IORESOURCE_IRQ, + }, + { + /* IRQ for channels 4-5 */ + .start = 72, + .end = 73, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device dma0_device = { + .name = "sh-dma-engine", + .id = 0, + .resource = sh7724_dmae0_resources, + .num_resources = ARRAY_SIZE(sh7724_dmae0_resources), + .dev = { + .platform_data = &dma0_platform_data, + }, + .archdata = { + .hwblk_id = HWBLK_DMAC0, + }, +}; + +static struct platform_device dma1_device = { + .name = "sh-dma-engine", + .id = 1, + .resource = sh7724_dmae1_resources, + .num_resources = ARRAY_SIZE(sh7724_dmae1_resources), + .dev = { + .platform_data = &dma1_platform_data, + }, + .archdata = { + .hwblk_id = HWBLK_DMAC1, }, }; @@ -663,7 +830,8 @@ static struct platform_device *sh7724_devices[] __initdata = { &tmu3_device, &tmu4_device, &tmu5_device, - &dma_device, + &dma0_device, + &dma1_device, &rtc_device, &iic0_device, &iic1_device, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c index f8f2161..02e792c 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c @@ -13,7 +13,10 @@ #include <linux/io.h> #include <linux/serial_sci.h> #include <linux/sh_timer.h> -#include <asm/dma-sh.h> + +#include <asm/dmaengine.h> + +#include <cpu/dma-register.h> static struct plat_sci_port scif0_platform_data = { .mapbase = 0xffe00000, @@ -247,15 +250,131 @@ static struct platform_device rtc_device = { .resource = rtc_resources, }; -static struct sh_dmae_pdata dma_platform_data = { - .mode = (SHDMA_MIX_IRQ | SHDMA_DMAOR1), +/* DMA */ +static struct sh_dmae_channel sh7780_dmae0_channels[] = { + { + .offset = 0, + .dmars = 0, + .dmars_bit = 0, + }, { + .offset = 0x10, + .dmars = 0, + .dmars_bit = 8, + }, { + .offset = 0x20, + .dmars = 4, + .dmars_bit = 0, + }, { + .offset = 0x30, + .dmars = 4, + .dmars_bit = 8, + }, { + .offset = 0x50, + .dmars = 8, + .dmars_bit = 0, + }, { + .offset = 0x60, + .dmars = 8, + .dmars_bit = 8, + } +}; + +static struct sh_dmae_channel sh7780_dmae1_channels[] = { + { + .offset = 0, + }, { + .offset = 0x10, + }, { + .offset = 0x20, + }, { + .offset = 0x30, + }, { + .offset = 0x50, + }, { + .offset = 0x60, + } +}; + +static unsigned int ts_shift[] = TS_SHIFT; + +static struct sh_dmae_pdata dma0_platform_data = { + .channel = sh7780_dmae0_channels, + .channel_num = ARRAY_SIZE(sh7780_dmae0_channels), + .ts_low_shift = CHCR_TS_LOW_SHIFT, + .ts_low_mask = CHCR_TS_LOW_MASK, + .ts_high_shift = CHCR_TS_HIGH_SHIFT, + .ts_high_mask = CHCR_TS_HIGH_MASK, + .ts_shift = ts_shift, + .ts_shift_num = ARRAY_SIZE(ts_shift), + .dmaor_init = DMAOR_INIT, +}; + +static struct sh_dmae_pdata dma1_platform_data = { + .channel = sh7780_dmae1_channels, + .channel_num = ARRAY_SIZE(sh7780_dmae1_channels), + .ts_low_shift = CHCR_TS_LOW_SHIFT, + .ts_low_mask = CHCR_TS_LOW_MASK, + .ts_high_shift = CHCR_TS_HIGH_SHIFT, + .ts_high_mask = CHCR_TS_HIGH_MASK, + .ts_shift = ts_shift, + .ts_shift_num = ARRAY_SIZE(ts_shift), + .dmaor_init = DMAOR_INIT, }; -static struct platform_device dma_device = { +static struct resource sh7780_dmae0_resources[] = { + [0] = { + /* Channel registers and DMAOR */ + .start = 0xfc808020, + .end = 0xfc80808f, + .flags = IORESOURCE_MEM, + }, + [1] = { + /* DMARSx */ + .start = 0xfc809000, + .end = 0xfc80900b, + .flags = IORESOURCE_MEM, + }, + { + /* Real DMA error IRQ is 38, and channel IRQs are 34-37, 44-45 */ + .start = 34, + .end = 34, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE, + }, +}; + +static struct resource sh7780_dmae1_resources[] = { + [0] = { + /* Channel registers and DMAOR */ + .start = 0xfc818020, + .end = 0xfc81808f, + .flags = IORESOURCE_MEM, + }, + /* DMAC1 has no DMARS */ + { + /* Real DMA error IRQ is 38, and channel IRQs are 46-47, 92-95 */ + .start = 46, + .end = 46, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE, + }, +}; + +static struct platform_device dma0_device = { .name = "sh-dma-engine", - .id = -1, + .id = 0, + .resource = sh7780_dmae0_resources, + .num_resources = ARRAY_SIZE(sh7780_dmae0_resources), .dev = { - .platform_data = &dma_platform_data, + .platform_data = &dma0_platform_data, + }, +}; + +static struct platform_device dma1_device = { + .name = "sh-dma-engine", + .id = 1, + .resource = sh7780_dmae1_resources, + .num_resources = ARRAY_SIZE(sh7780_dmae1_resources), + .dev = { + .platform_data = &dma1_platform_data, }, }; @@ -269,7 +388,8 @@ static struct platform_device *sh7780_devices[] __initdata = { &tmu4_device, &tmu5_device, &rtc_device, - &dma_device, + &dma0_device, + &dma1_device, }; static int __init sh7780_devices_setup(void) diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c index 23448d8..1fcd88b 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c @@ -14,9 +14,12 @@ #include <linux/io.h> #include <linux/mm.h> #include <linux/sh_timer.h> -#include <asm/dma-sh.h> + +#include <asm/dmaengine.h> #include <asm/mmzone.h> +#include <cpu/dma-register.h> + static struct plat_sci_port scif0_platform_data = { .mapbase = 0xffea0000, .flags = UPF_BOOT_AUTOCONF, @@ -295,15 +298,131 @@ static struct platform_device tmu5_device = { .num_resources = ARRAY_SIZE(tmu5_resources), }; -static struct sh_dmae_pdata dma_platform_data = { - .mode = (SHDMA_MIX_IRQ | SHDMA_DMAOR1), +/* DMA */ +static struct sh_dmae_channel sh7785_dmae0_channels[] = { + { + .offset = 0, + .dmars = 0, + .dmars_bit = 0, + }, { + .offset = 0x10, + .dmars = 0, + .dmars_bit = 8, + }, { + .offset = 0x20, + .dmars = 4, + .dmars_bit = 0, + }, { + .offset = 0x30, + .dmars = 4, + .dmars_bit = 8, + }, { + .offset = 0x50, + .dmars = 8, + .dmars_bit = 0, + }, { + .offset = 0x60, + .dmars = 8, + .dmars_bit = 8, + } +}; + +static struct sh_dmae_channel sh7785_dmae1_channels[] = { + { + .offset = 0, + }, { + .offset = 0x10, + }, { + .offset = 0x20, + }, { + .offset = 0x30, + }, { + .offset = 0x50, + }, { + .offset = 0x60, + } +}; + +static unsigned int ts_shift[] = TS_SHIFT; + +static struct sh_dmae_pdata dma0_platform_data = { + .channel = sh7785_dmae0_channels, + .channel_num = ARRAY_SIZE(sh7785_dmae0_channels), + .ts_low_shift = CHCR_TS_LOW_SHIFT, + .ts_low_mask = CHCR_TS_LOW_MASK, + .ts_high_shift = CHCR_TS_HIGH_SHIFT, + .ts_high_mask = CHCR_TS_HIGH_MASK, + .ts_shift = ts_shift, + .ts_shift_num = ARRAY_SIZE(ts_shift), + .dmaor_init = DMAOR_INIT, +}; + +static struct sh_dmae_pdata dma1_platform_data = { + .channel = sh7785_dmae1_channels, + .channel_num = ARRAY_SIZE(sh7785_dmae1_channels), + .ts_low_shift = CHCR_TS_LOW_SHIFT, + .ts_low_mask = CHCR_TS_LOW_MASK, + .ts_high_shift = CHCR_TS_HIGH_SHIFT, + .ts_high_mask = CHCR_TS_HIGH_MASK, + .ts_shift = ts_shift, + .ts_shift_num = ARRAY_SIZE(ts_shift), + .dmaor_init = DMAOR_INIT, }; -static struct platform_device dma_device = { +static struct resource sh7785_dmae0_resources[] = { + [0] = { + /* Channel registers and DMAOR */ + .start = 0xfc808020, + .end = 0xfc80808f, + .flags = IORESOURCE_MEM, + }, + [1] = { + /* DMARSx */ + .start = 0xfc809000, + .end = 0xfc80900b, + .flags = IORESOURCE_MEM, + }, + { + /* Real DMA error IRQ is 39, and channel IRQs are 33-38 */ + .start = 33, + .end = 33, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE, + }, +}; + +static struct resource sh7785_dmae1_resources[] = { + [0] = { + /* Channel registers and DMAOR */ + .start = 0xfcc08020, + .end = 0xfcc0808f, + .flags = IORESOURCE_MEM, + }, + /* DMAC1 has no DMARS */ + { + /* Real DMA error IRQ is 58, and channel IRQs are 52-57 */ + .start = 52, + .end = 52, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE, + }, +}; + +static struct platform_device dma0_device = { .name = "sh-dma-engine", - .id = -1, + .id = 0, + .resource = sh7785_dmae0_resources, + .num_resources = ARRAY_SIZE(sh7785_dmae0_resources), .dev = { - .platform_data = &dma_platform_data, + .platform_data = &dma0_platform_data, + }, +}; + +static struct platform_device dma1_device = { + .name = "sh-dma-engine", + .id = 1, + .resource = sh7785_dmae1_resources, + .num_resources = ARRAY_SIZE(sh7785_dmae1_resources), + .dev = { + .platform_data = &dma1_platform_data, }, }; @@ -320,7 +439,8 @@ static struct platform_device *sh7785_devices[] __initdata = { &tmu3_device, &tmu4_device, &tmu5_device, - &dma_device, + &dma0_device, + &dma1_device, }; static int __init sh7785_devices_setup(void) diff --git a/arch/sh/kernel/hw_breakpoint.c b/arch/sh/kernel/hw_breakpoint.c index e2f1753..675eea7 100644 --- a/arch/sh/kernel/hw_breakpoint.c +++ b/arch/sh/kernel/hw_breakpoint.c @@ -143,26 +143,6 @@ static int arch_check_va_in_kernelspace(unsigned long va, u8 hbp_len) return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE); } -/* - * Store a breakpoint's encoded address, length, and type. - */ -static int arch_store_info(struct perf_event *bp) -{ - struct arch_hw_breakpoint *info = counter_arch_bp(bp); - - /* - * User-space requests will always have the address field populated - * For kernel-addresses, either the address or symbol name can be - * specified. - */ - if (info->name) - info->address = (unsigned long)kallsyms_lookup_name(info->name); - if (info->address) - return 0; - - return -EINVAL; -} - int arch_bp_generic_fields(int sh_len, int sh_type, int *gen_len, int *gen_type) { @@ -276,10 +256,12 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp, return ret; } - ret = arch_store_info(bp); - - if (ret < 0) - return ret; + /* + * For kernel-addresses, either the address or symbol name can be + * specified. + */ + if (info->name) + info->address = (unsigned long)kallsyms_lookup_name(info->name); /* * Check that the low-order bits of the address are appropriate diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index 3459e70..8870d6b 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -443,7 +443,7 @@ void __init setup_arch(char **cmdline_p) nodes_clear(node_online_map); - /* Setup bootmem with available RAM */ + pmb_init(); lmb_init(); setup_memory(); sparse_init(); @@ -452,7 +452,6 @@ void __init setup_arch(char **cmdline_p) conswitchp = &dummy_con; #endif paging_init(); - pmb_init(); ioremap_fixed_init(); diff --git a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c index 953fa16..8a0072d 100644 --- a/arch/sh/kernel/time.c +++ b/arch/sh/kernel/time.c @@ -39,12 +39,12 @@ static int null_rtc_set_time(const time_t secs) void (*rtc_sh_get_time)(struct timespec *) = null_rtc_get_time; int (*rtc_sh_set_time)(const time_t) = null_rtc_set_time; -#ifdef CONFIG_GENERIC_CMOS_UPDATE void read_persistent_clock(struct timespec *ts) { rtc_sh_get_time(ts); } +#ifdef CONFIG_GENERIC_CMOS_UPDATE int update_persistent_clock(struct timespec now) { return rtc_sh_set_time(now.tv_sec); @@ -113,9 +113,5 @@ void __init time_init(void) hwblk_init(); clk_init(); - rtc_sh_get_time(&xtime); - set_normalized_timespec(&wall_to_monotonic, - -xtime.tv_sec, -xtime.tv_nsec); - late_time_init = sh_late_time_init; } diff --git a/arch/sh/lib/libgcc.h b/arch/sh/lib/libgcc.h index 3f19d1c..05909d58 100644 --- a/arch/sh/lib/libgcc.h +++ b/arch/sh/lib/libgcc.h @@ -17,8 +17,7 @@ struct DWstruct { #error I feel sick. #endif -typedef union -{ +typedef union { struct DWstruct s; long long ll; } DWunion; diff --git a/arch/sh/mm/ioremap.c b/arch/sh/mm/ioremap.c index c68d2d7..1ab2385 100644 --- a/arch/sh/mm/ioremap.c +++ b/arch/sh/mm/ioremap.c @@ -34,11 +34,12 @@ * caller shouldn't need to know that small detail. */ void __iomem * __init_refok -__ioremap_caller(unsigned long phys_addr, unsigned long size, +__ioremap_caller(phys_addr_t phys_addr, unsigned long size, pgprot_t pgprot, void *caller) { struct vm_struct *area; unsigned long offset, last_addr, addr, orig_addr; + void __iomem *mapped; /* Don't allow wraparound or zero size */ last_addr = phys_addr + size - 1; @@ -46,6 +47,20 @@ __ioremap_caller(unsigned long phys_addr, unsigned long size, return NULL; /* + * If we can't yet use the regular approach, go the fixmap route. + */ + if (!mem_init_done) + return ioremap_fixed(phys_addr, size, pgprot); + + /* + * First try to remap through the PMB. + * PMB entries are all pre-faulted. + */ + mapped = pmb_remap_caller(phys_addr, size, pgprot, caller); + if (mapped && !IS_ERR(mapped)) + return mapped; + + /* * Mappings have to be page-aligned */ offset = phys_addr & ~PAGE_MASK; @@ -53,12 +68,6 @@ __ioremap_caller(unsigned long phys_addr, unsigned long size, size = PAGE_ALIGN(last_addr+1) - phys_addr; /* - * If we can't yet use the regular approach, go the fixmap route. - */ - if (!mem_init_done) - return ioremap_fixed(phys_addr, offset, size, pgprot); - - /* * Ok, go for it.. */ area = get_vm_area_caller(size, VM_IOREMAP, caller); @@ -67,33 +76,10 @@ __ioremap_caller(unsigned long phys_addr, unsigned long size, area->phys_addr = phys_addr; orig_addr = addr = (unsigned long)area->addr; -#ifdef CONFIG_PMB - /* - * First try to remap through the PMB once a valid VMA has been - * established. Smaller allocations (or the rest of the size - * remaining after a PMB mapping due to the size not being - * perfectly aligned on a PMB size boundary) are then mapped - * through the UTLB using conventional page tables. - * - * PMB entries are all pre-faulted. - */ - if (unlikely(phys_addr >= P1SEG)) { - unsigned long mapped; - - mapped = pmb_remap(addr, phys_addr, size, pgprot); - if (likely(mapped)) { - addr += mapped; - phys_addr += mapped; - size -= mapped; - } + if (ioremap_page_range(addr, addr + size, phys_addr, pgprot)) { + vunmap((void *)orig_addr); + return NULL; } -#endif - - if (likely(size)) - if (ioremap_page_range(addr, addr + size, phys_addr, pgprot)) { - vunmap((void *)orig_addr); - return NULL; - } return (void __iomem *)(offset + (char *)orig_addr); } @@ -133,23 +119,11 @@ void __iounmap(void __iomem *addr) if (iounmap_fixed(addr) == 0) return; -#ifdef CONFIG_PMB /* - * Purge any PMB entries that may have been established for this - * mapping, then proceed with conventional VMA teardown. - * - * XXX: Note that due to the way that remove_vm_area() does - * matching of the resultant VMA, we aren't able to fast-forward - * the address past the PMB space until the end of the VMA where - * the page tables reside. As such, unmap_vm_area() will be - * forced to linearly scan over the area until it finds the page - * tables where PTEs that need to be unmapped actually reside, - * which is far from optimal. Perhaps we need to use a separate - * VMA for the PMB mappings? - * -- PFM. + * If the PMB handled it, there's nothing else to do. */ - pmb_unmap(vaddr); -#endif + if (pmb_unmap(addr) == 0) + return; p = remove_vm_area((void *)(vaddr & PAGE_MASK)); if (!p) { diff --git a/arch/sh/mm/ioremap_fixed.c b/arch/sh/mm/ioremap_fixed.c index 0b78b1e..7f682e5 100644 --- a/arch/sh/mm/ioremap_fixed.c +++ b/arch/sh/mm/ioremap_fixed.c @@ -45,14 +45,21 @@ void __init ioremap_fixed_init(void) } void __init __iomem * -ioremap_fixed(resource_size_t phys_addr, unsigned long offset, - unsigned long size, pgprot_t prot) +ioremap_fixed(phys_addr_t phys_addr, unsigned long size, pgprot_t prot) { enum fixed_addresses idx0, idx; struct ioremap_map *map; unsigned int nrpages; + unsigned long offset; int i, slot; + /* + * Mappings have to be page-aligned + */ + offset = phys_addr & ~PAGE_MASK; + phys_addr &= PAGE_MASK; + size = PAGE_ALIGN(phys_addr + size) - phys_addr; + slot = -1; for (i = 0; i < FIX_N_IOREMAPS; i++) { map = &ioremap_maps[i]; diff --git a/arch/sh/mm/numa.c b/arch/sh/mm/numa.c index 422e927..961b340 100644 --- a/arch/sh/mm/numa.c +++ b/arch/sh/mm/numa.c @@ -74,6 +74,9 @@ void __init setup_bootmem_node(int nid, unsigned long start, unsigned long end) start_pfn = start >> PAGE_SHIFT; end_pfn = end >> PAGE_SHIFT; + pmb_bolt_mapping((unsigned long)__va(start), start, end - start, + PAGE_KERNEL); + lmb_add(start, end - start); __add_active_range(nid, start_pfn, end_pfn); diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c index 198bcff..a4662e2 100644 --- a/arch/sh/mm/pmb.c +++ b/arch/sh/mm/pmb.c @@ -23,7 +23,8 @@ #include <linux/err.h> #include <linux/io.h> #include <linux/spinlock.h> -#include <linux/rwlock.h> +#include <linux/vmalloc.h> +#include <asm/cacheflush.h> #include <asm/sizes.h> #include <asm/system.h> #include <asm/uaccess.h> @@ -52,12 +53,24 @@ struct pmb_entry { struct pmb_entry *link; }; +static struct { + unsigned long size; + int flag; +} pmb_sizes[] = { + { .size = SZ_512M, .flag = PMB_SZ_512M, }, + { .size = SZ_128M, .flag = PMB_SZ_128M, }, + { .size = SZ_64M, .flag = PMB_SZ_64M, }, + { .size = SZ_16M, .flag = PMB_SZ_16M, }, +}; + static void pmb_unmap_entry(struct pmb_entry *, int depth); static DEFINE_RWLOCK(pmb_rwlock); static struct pmb_entry pmb_entry_list[NR_PMB_ENTRIES]; static DECLARE_BITMAP(pmb_map, NR_PMB_ENTRIES); +static unsigned int pmb_iomapping_enabled; + static __always_inline unsigned long mk_pmb_entry(unsigned int entry) { return (entry & PMB_E_MASK) << PMB_E_SHIFT; @@ -73,6 +86,142 @@ static __always_inline unsigned long mk_pmb_data(unsigned int entry) return mk_pmb_entry(entry) | PMB_DATA; } +static __always_inline unsigned int pmb_ppn_in_range(unsigned long ppn) +{ + return ppn >= __pa(memory_start) && ppn < __pa(memory_end); +} + +/* + * Ensure that the PMB entries match our cache configuration. + * + * When we are in 32-bit address extended mode, CCR.CB becomes + * invalid, so care must be taken to manually adjust cacheable + * translations. + */ +static __always_inline unsigned long pmb_cache_flags(void) +{ + unsigned long flags = 0; + +#if defined(CONFIG_CACHE_OFF) + flags |= PMB_WT | PMB_UB; +#elif defined(CONFIG_CACHE_WRITETHROUGH) + flags |= PMB_C | PMB_WT | PMB_UB; +#elif defined(CONFIG_CACHE_WRITEBACK) + flags |= PMB_C; +#endif + + return flags; +} + +/* + * Convert typical pgprot value to the PMB equivalent + */ +static inline unsigned long pgprot_to_pmb_flags(pgprot_t prot) +{ + unsigned long pmb_flags = 0; + u64 flags = pgprot_val(prot); + + if (flags & _PAGE_CACHABLE) + pmb_flags |= PMB_C; + if (flags & _PAGE_WT) + pmb_flags |= PMB_WT | PMB_UB; + + return pmb_flags; +} + +static inline bool pmb_can_merge(struct pmb_entry *a, struct pmb_entry *b) +{ + return (b->vpn == (a->vpn + a->size)) && + (b->ppn == (a->ppn + a->size)) && + (b->flags == a->flags); +} + +static bool pmb_mapping_exists(unsigned long vaddr, phys_addr_t phys, + unsigned long size) +{ + int i; + + read_lock(&pmb_rwlock); + + for (i = 0; i < ARRAY_SIZE(pmb_entry_list); i++) { + struct pmb_entry *pmbe, *iter; + unsigned long span; + + if (!test_bit(i, pmb_map)) + continue; + + pmbe = &pmb_entry_list[i]; + + /* + * See if VPN and PPN are bounded by an existing mapping. + */ + if ((vaddr < pmbe->vpn) || (vaddr >= (pmbe->vpn + pmbe->size))) + continue; + if ((phys < pmbe->ppn) || (phys >= (pmbe->ppn + pmbe->size))) + continue; + + /* + * Now see if we're in range of a simple mapping. + */ + if (size <= pmbe->size) { + read_unlock(&pmb_rwlock); + return true; + } + + span = pmbe->size; + + /* + * Finally for sizes that involve compound mappings, walk + * the chain. + */ + for (iter = pmbe->link; iter; iter = iter->link) + span += iter->size; + + /* + * Nothing else to do if the range requirements are met. + */ + if (size <= span) { + read_unlock(&pmb_rwlock); + return true; + } + } + + read_unlock(&pmb_rwlock); + return false; +} + +static bool pmb_size_valid(unsigned long size) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(pmb_sizes); i++) + if (pmb_sizes[i].size == size) + return true; + + return false; +} + +static inline bool pmb_addr_valid(unsigned long addr, unsigned long size) +{ + return (addr >= P1SEG && (addr + size - 1) < P3SEG); +} + +static inline bool pmb_prot_valid(pgprot_t prot) +{ + return (pgprot_val(prot) & _PAGE_USER) == 0; +} + +static int pmb_size_to_flags(unsigned long size) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(pmb_sizes); i++) + if (pmb_sizes[i].size == size) + return pmb_sizes[i].flag; + + return 0; +} + static int pmb_alloc_entry(void) { int pos; @@ -140,33 +289,22 @@ static void pmb_free(struct pmb_entry *pmbe) } /* - * Ensure that the PMB entries match our cache configuration. - * - * When we are in 32-bit address extended mode, CCR.CB becomes - * invalid, so care must be taken to manually adjust cacheable - * translations. + * Must be run uncached. */ -static __always_inline unsigned long pmb_cache_flags(void) +static void __set_pmb_entry(struct pmb_entry *pmbe) { - unsigned long flags = 0; + unsigned long addr, data; -#if defined(CONFIG_CACHE_WRITETHROUGH) - flags |= PMB_C | PMB_WT | PMB_UB; -#elif defined(CONFIG_CACHE_WRITEBACK) - flags |= PMB_C; -#endif + addr = mk_pmb_addr(pmbe->entry); + data = mk_pmb_data(pmbe->entry); - return flags; -} + jump_to_uncached(); -/* - * Must be run uncached. - */ -static void __set_pmb_entry(struct pmb_entry *pmbe) -{ - writel_uncached(pmbe->vpn | PMB_V, mk_pmb_addr(pmbe->entry)); - writel_uncached(pmbe->ppn | pmbe->flags | PMB_V, - mk_pmb_data(pmbe->entry)); + /* Set V-bit */ + __raw_writel(pmbe->vpn | PMB_V, addr); + __raw_writel(pmbe->ppn | pmbe->flags | PMB_V, data); + + back_to_cached(); } static void __clear_pmb_entry(struct pmb_entry *pmbe) @@ -194,144 +332,155 @@ static void set_pmb_entry(struct pmb_entry *pmbe) spin_unlock_irqrestore(&pmbe->lock, flags); } -static struct { - unsigned long size; - int flag; -} pmb_sizes[] = { - { .size = SZ_512M, .flag = PMB_SZ_512M, }, - { .size = SZ_128M, .flag = PMB_SZ_128M, }, - { .size = SZ_64M, .flag = PMB_SZ_64M, }, - { .size = SZ_16M, .flag = PMB_SZ_16M, }, -}; - -long pmb_remap(unsigned long vaddr, unsigned long phys, - unsigned long size, pgprot_t prot) +int pmb_bolt_mapping(unsigned long vaddr, phys_addr_t phys, + unsigned long size, pgprot_t prot) { struct pmb_entry *pmbp, *pmbe; - unsigned long wanted; - int pmb_flags, i; - long err; - u64 flags; + unsigned long orig_addr, orig_size; + unsigned long flags, pmb_flags; + int i, mapped; - flags = pgprot_val(prot); + if (!pmb_addr_valid(vaddr, size)) + return -EFAULT; + if (pmb_mapping_exists(vaddr, phys, size)) + return 0; - pmb_flags = PMB_WT | PMB_UB; - - /* Convert typical pgprot value to the PMB equivalent */ - if (flags & _PAGE_CACHABLE) { - pmb_flags |= PMB_C; + orig_addr = vaddr; + orig_size = size; - if ((flags & _PAGE_WT) == 0) - pmb_flags &= ~(PMB_WT | PMB_UB); - } + flush_tlb_kernel_range(vaddr, vaddr + size); + pmb_flags = pgprot_to_pmb_flags(prot); pmbp = NULL; - wanted = size; -again: - for (i = 0; i < ARRAY_SIZE(pmb_sizes); i++) { - unsigned long flags; + do { + for (i = mapped = 0; i < ARRAY_SIZE(pmb_sizes); i++) { + if (size < pmb_sizes[i].size) + continue; + + pmbe = pmb_alloc(vaddr, phys, pmb_flags | + pmb_sizes[i].flag, PMB_NO_ENTRY); + if (IS_ERR(pmbe)) { + pmb_unmap_entry(pmbp, mapped); + return PTR_ERR(pmbe); + } - if (size < pmb_sizes[i].size) - continue; + spin_lock_irqsave(&pmbe->lock, flags); - pmbe = pmb_alloc(vaddr, phys, pmb_flags | pmb_sizes[i].flag, - PMB_NO_ENTRY); - if (IS_ERR(pmbe)) { - err = PTR_ERR(pmbe); - goto out; - } + pmbe->size = pmb_sizes[i].size; - spin_lock_irqsave(&pmbe->lock, flags); + __set_pmb_entry(pmbe); - __set_pmb_entry(pmbe); + phys += pmbe->size; + vaddr += pmbe->size; + size -= pmbe->size; - phys += pmb_sizes[i].size; - vaddr += pmb_sizes[i].size; - size -= pmb_sizes[i].size; + /* + * Link adjacent entries that span multiple PMB + * entries for easier tear-down. + */ + if (likely(pmbp)) { + spin_lock(&pmbp->lock); + pmbp->link = pmbe; + spin_unlock(&pmbp->lock); + } - pmbe->size = pmb_sizes[i].size; + pmbp = pmbe; - /* - * Link adjacent entries that span multiple PMB entries - * for easier tear-down. - */ - if (likely(pmbp)) { - spin_lock(&pmbp->lock); - pmbp->link = pmbe; - spin_unlock(&pmbp->lock); + /* + * Instead of trying smaller sizes on every + * iteration (even if we succeed in allocating + * space), try using pmb_sizes[i].size again. + */ + i--; + mapped++; + + spin_unlock_irqrestore(&pmbe->lock, flags); } + } while (size >= SZ_16M); - pmbp = pmbe; + flush_cache_vmap(orig_addr, orig_addr + orig_size); - /* - * Instead of trying smaller sizes on every iteration - * (even if we succeed in allocating space), try using - * pmb_sizes[i].size again. - */ - i--; + return 0; +} - spin_unlock_irqrestore(&pmbe->lock, flags); - } +void __iomem *pmb_remap_caller(phys_addr_t phys, unsigned long size, + pgprot_t prot, void *caller) +{ + unsigned long vaddr; + phys_addr_t offset, last_addr; + phys_addr_t align_mask; + unsigned long aligned; + struct vm_struct *area; + int i, ret; - if (size >= SZ_16M) - goto again; + if (!pmb_iomapping_enabled) + return NULL; - return wanted - size; + /* + * Small mappings need to go through the TLB. + */ + if (size < SZ_16M) + return ERR_PTR(-EINVAL); + if (!pmb_prot_valid(prot)) + return ERR_PTR(-EINVAL); -out: - pmb_unmap_entry(pmbp, NR_PMB_ENTRIES); + for (i = 0; i < ARRAY_SIZE(pmb_sizes); i++) + if (size >= pmb_sizes[i].size) + break; + + last_addr = phys + size; + align_mask = ~(pmb_sizes[i].size - 1); + offset = phys & ~align_mask; + phys &= align_mask; + aligned = ALIGN(last_addr, pmb_sizes[i].size) - phys; + + /* + * XXX: This should really start from uncached_end, but this + * causes the MMU to reset, so for now we restrict it to the + * 0xb000...0xc000 range. + */ + area = __get_vm_area_caller(aligned, VM_IOREMAP, 0xb0000000, + P3SEG, caller); + if (!area) + return NULL; + + area->phys_addr = phys; + vaddr = (unsigned long)area->addr; + + ret = pmb_bolt_mapping(vaddr, phys, size, prot); + if (unlikely(ret != 0)) + return ERR_PTR(ret); - return err; + return (void __iomem *)(offset + (char *)vaddr); } -void pmb_unmap(unsigned long addr) +int pmb_unmap(void __iomem *addr) { struct pmb_entry *pmbe = NULL; - int i; + unsigned long vaddr = (unsigned long __force)addr; + int i, found = 0; read_lock(&pmb_rwlock); for (i = 0; i < ARRAY_SIZE(pmb_entry_list); i++) { if (test_bit(i, pmb_map)) { pmbe = &pmb_entry_list[i]; - if (pmbe->vpn == addr) + if (pmbe->vpn == vaddr) { + found = 1; break; + } } } read_unlock(&pmb_rwlock); - pmb_unmap_entry(pmbe, NR_PMB_ENTRIES); -} - -static bool pmb_can_merge(struct pmb_entry *a, struct pmb_entry *b) -{ - return (b->vpn == (a->vpn + a->size)) && - (b->ppn == (a->ppn + a->size)) && - (b->flags == a->flags); -} - -static bool pmb_size_valid(unsigned long size) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(pmb_sizes); i++) - if (pmb_sizes[i].size == size) - return true; - - return false; -} - -static int pmb_size_to_flags(unsigned long size) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(pmb_sizes); i++) - if (pmb_sizes[i].size == size) - return pmb_sizes[i].flag; + if (found) { + pmb_unmap_entry(pmbe, NR_PMB_ENTRIES); + return 0; + } - return 0; + return -EINVAL; } static void __pmb_unmap_entry(struct pmb_entry *pmbe, int depth) @@ -351,6 +500,8 @@ static void __pmb_unmap_entry(struct pmb_entry *pmbe, int depth) */ __clear_pmb_entry(pmbe); + flush_cache_vunmap(pmbe->vpn, pmbe->vpn + pmbe->size); + pmbe = pmblink->link; pmb_free(pmblink); @@ -369,11 +520,6 @@ static void pmb_unmap_entry(struct pmb_entry *pmbe, int depth) write_unlock_irqrestore(&pmb_rwlock, flags); } -static __always_inline unsigned int pmb_ppn_in_range(unsigned long ppn) -{ - return ppn >= __pa(memory_start) && ppn < __pa(memory_end); -} - static void __init pmb_notify(void) { int i; @@ -625,6 +771,18 @@ static void __init pmb_resize(void) } #endif +static int __init early_pmb(char *p) +{ + if (!p) + return 0; + + if (strstr(p, "iomap")) + pmb_iomapping_enabled = 1; + + return 0; +} +early_param("pmb", early_pmb); + void __init pmb_init(void) { /* Synchronize software state */ @@ -713,7 +871,7 @@ static int __init pmb_debugfs_init(void) return 0; } -postcore_initcall(pmb_debugfs_init); +subsys_initcall(pmb_debugfs_init); #ifdef CONFIG_PM static int pmb_sysdev_suspend(struct sys_device *dev, pm_message_t state) diff --git a/drivers/base/power/Makefile b/drivers/base/power/Makefile index 3ce3519..89de753 100644 --- a/drivers/base/power/Makefile +++ b/drivers/base/power/Makefile @@ -1,6 +1,7 @@ obj-$(CONFIG_PM) += sysfs.o obj-$(CONFIG_PM_SLEEP) += main.o obj-$(CONFIG_PM_RUNTIME) += runtime.o +obj-$(CONFIG_PM_OPS) += generic_ops.o obj-$(CONFIG_PM_TRACE_RTC) += trace.o ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG diff --git a/drivers/base/power/generic_ops.c b/drivers/base/power/generic_ops.c new file mode 100644 index 0000000..4b29d49 --- /dev/null +++ b/drivers/base/power/generic_ops.c @@ -0,0 +1,233 @@ +/* + * drivers/base/power/generic_ops.c - Generic PM callbacks for subsystems + * + * Copyright (c) 2010 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc. + * + * This file is released under the GPLv2. + */ + +#include <linux/pm.h> +#include <linux/pm_runtime.h> + +#ifdef CONFIG_PM_RUNTIME +/** + * pm_generic_runtime_idle - Generic runtime idle callback for subsystems. + * @dev: Device to handle. + * + * If PM operations are defined for the @dev's driver and they include + * ->runtime_idle(), execute it and return its error code, if nonzero. + * Otherwise, execute pm_runtime_suspend() for the device and return 0. + */ +int pm_generic_runtime_idle(struct device *dev) +{ + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + + if (pm && pm->runtime_idle) { + int ret = pm->runtime_idle(dev); + if (ret) + return ret; + } + + pm_runtime_suspend(dev); + return 0; +} +EXPORT_SYMBOL_GPL(pm_generic_runtime_idle); + +/** + * pm_generic_runtime_suspend - Generic runtime suspend callback for subsystems. + * @dev: Device to suspend. + * + * If PM operations are defined for the @dev's driver and they include + * ->runtime_suspend(), execute it and return its error code. Otherwise, + * return -EINVAL. + */ +int pm_generic_runtime_suspend(struct device *dev) +{ + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + int ret; + + ret = pm && pm->runtime_suspend ? pm->runtime_suspend(dev) : -EINVAL; + + return ret; +} +EXPORT_SYMBOL_GPL(pm_generic_runtime_suspend); + +/** + * pm_generic_runtime_resume - Generic runtime resume callback for subsystems. + * @dev: Device to resume. + * + * If PM operations are defined for the @dev's driver and they include + * ->runtime_resume(), execute it and return its error code. Otherwise, + * return -EINVAL. + */ +int pm_generic_runtime_resume(struct device *dev) +{ + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + int ret; + + ret = pm && pm->runtime_resume ? pm->runtime_resume(dev) : -EINVAL; + + return ret; +} +EXPORT_SYMBOL_GPL(pm_generic_runtime_resume); +#endif /* CONFIG_PM_RUNTIME */ + +#ifdef CONFIG_PM_SLEEP +/** + * __pm_generic_call - Generic suspend/freeze/poweroff/thaw subsystem callback. + * @dev: Device to handle. + * @event: PM transition of the system under way. + * + * If the device has not been suspended at run time, execute the + * suspend/freeze/poweroff/thaw callback provided by its driver, if defined, and + * return its error code. Otherwise, return zero. + */ +static int __pm_generic_call(struct device *dev, int event) +{ + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + int (*callback)(struct device *); + + if (!pm || pm_runtime_suspended(dev)) + return 0; + + switch (event) { + case PM_EVENT_SUSPEND: + callback = pm->suspend; + break; + case PM_EVENT_FREEZE: + callback = pm->freeze; + break; + case PM_EVENT_HIBERNATE: + callback = pm->poweroff; + break; + case PM_EVENT_THAW: + callback = pm->thaw; + break; + default: + callback = NULL; + break; + } + + return callback ? callback(dev) : 0; +} + +/** + * pm_generic_suspend - Generic suspend callback for subsystems. + * @dev: Device to suspend. + */ +int pm_generic_suspend(struct device *dev) +{ + return __pm_generic_call(dev, PM_EVENT_SUSPEND); +} +EXPORT_SYMBOL_GPL(pm_generic_suspend); + +/** + * pm_generic_freeze - Generic freeze callback for subsystems. + * @dev: Device to freeze. + */ +int pm_generic_freeze(struct device *dev) +{ + return __pm_generic_call(dev, PM_EVENT_FREEZE); +} +EXPORT_SYMBOL_GPL(pm_generic_freeze); + +/** + * pm_generic_poweroff - Generic poweroff callback for subsystems. + * @dev: Device to handle. + */ +int pm_generic_poweroff(struct device *dev) +{ + return __pm_generic_call(dev, PM_EVENT_HIBERNATE); +} +EXPORT_SYMBOL_GPL(pm_generic_poweroff); + +/** + * pm_generic_thaw - Generic thaw callback for subsystems. + * @dev: Device to thaw. + */ +int pm_generic_thaw(struct device *dev) +{ + return __pm_generic_call(dev, PM_EVENT_THAW); +} +EXPORT_SYMBOL_GPL(pm_generic_thaw); + +/** + * __pm_generic_resume - Generic resume/restore callback for subsystems. + * @dev: Device to handle. + * @event: PM transition of the system under way. + * + * Execute the resume/resotre callback provided by the @dev's driver, if + * defined. If it returns 0, change the device's runtime PM status to 'active'. + * Return the callback's error code. + */ +static int __pm_generic_resume(struct device *dev, int event) +{ + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + int (*callback)(struct device *); + int ret; + + if (!pm) + return 0; + + switch (event) { + case PM_EVENT_RESUME: + callback = pm->resume; + break; + case PM_EVENT_RESTORE: + callback = pm->restore; + break; + default: + callback = NULL; + break; + } + + if (!callback) + return 0; + + ret = callback(dev); + if (!ret) { + pm_runtime_disable(dev); + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + } + + return ret; +} + +/** + * pm_generic_resume - Generic resume callback for subsystems. + * @dev: Device to resume. + */ +int pm_generic_resume(struct device *dev) +{ + return __pm_generic_resume(dev, PM_EVENT_RESUME); +} +EXPORT_SYMBOL_GPL(pm_generic_resume); + +/** + * pm_generic_restore - Generic restore callback for subsystems. + * @dev: Device to restore. + */ +int pm_generic_restore(struct device *dev) +{ + return __pm_generic_resume(dev, PM_EVENT_RESTORE); +} +EXPORT_SYMBOL_GPL(pm_generic_restore); +#endif /* CONFIG_PM_SLEEP */ + +struct dev_pm_ops generic_subsys_pm_ops = { +#ifdef CONFIG_PM_SLEEP + .suspend = pm_generic_suspend, + .resume = pm_generic_resume, + .freeze = pm_generic_freeze, + .thaw = pm_generic_thaw, + .poweroff = pm_generic_poweroff, + .restore = pm_generic_restore, +#endif +#ifdef CONFIG_PM_RUNTIME + .runtime_suspend = pm_generic_runtime_suspend, + .runtime_resume = pm_generic_runtime_resume, + .runtime_idle = pm_generic_runtime_idle, +#endif +}; +EXPORT_SYMBOL_GPL(generic_subsys_pm_ops); diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c index b75ce8b..5d17e09 100644 --- a/drivers/dma/shdma.c +++ b/drivers/dma/shdma.c @@ -24,8 +24,10 @@ #include <linux/delay.h> #include <linux/dma-mapping.h> #include <linux/platform_device.h> -#include <cpu/dma.h> -#include <asm/dma-sh.h> +#include <linux/pm_runtime.h> + +#include <asm/dmaengine.h> + #include "shdma.h" /* DMA descriptor control */ @@ -38,30 +40,32 @@ enum sh_dmae_desc_status { }; #define NR_DESCS_PER_CHANNEL 32 -/* - * Define the default configuration for dual address memory-memory transfer. - * The 0x400 value represents auto-request, external->external. - * - * And this driver set 4byte burst mode. - * If you want to change mode, you need to change RS_DEFAULT of value. - * (ex 1byte burst mode -> (RS_DUAL & ~TS_32) - */ -#define RS_DEFAULT (RS_DUAL) +/* Default MEMCPY transfer size = 2^2 = 4 bytes */ +#define LOG2_DEFAULT_XFER_SIZE 2 /* A bitmask with bits enough for enum sh_dmae_slave_chan_id */ static unsigned long sh_dmae_slave_used[BITS_TO_LONGS(SHDMA_SLAVE_NUMBER)]; static void sh_dmae_chan_ld_cleanup(struct sh_dmae_chan *sh_chan, bool all); -#define SH_DMAC_CHAN_BASE(id) (dma_base_addr[id]) static void sh_dmae_writel(struct sh_dmae_chan *sh_dc, u32 data, u32 reg) { - ctrl_outl(data, SH_DMAC_CHAN_BASE(sh_dc->id) + reg); + __raw_writel(data, sh_dc->base + reg / sizeof(u32)); } static u32 sh_dmae_readl(struct sh_dmae_chan *sh_dc, u32 reg) { - return ctrl_inl(SH_DMAC_CHAN_BASE(sh_dc->id) + reg); + return __raw_readl(sh_dc->base + reg / sizeof(u32)); +} + +static u16 dmaor_read(struct sh_dmae_device *shdev) +{ + return __raw_readw(shdev->chan_reg + DMAOR / sizeof(u32)); +} + +static void dmaor_write(struct sh_dmae_device *shdev, u16 data) +{ + __raw_writew(data, shdev->chan_reg + DMAOR / sizeof(u32)); } /* @@ -69,24 +73,23 @@ static u32 sh_dmae_readl(struct sh_dmae_chan *sh_dc, u32 reg) * * SH7780 has two DMAOR register */ -static void sh_dmae_ctl_stop(int id) +static void sh_dmae_ctl_stop(struct sh_dmae_device *shdev) { - unsigned short dmaor = dmaor_read_reg(id); + unsigned short dmaor = dmaor_read(shdev); - dmaor &= ~(DMAOR_NMIF | DMAOR_AE); - dmaor_write_reg(id, dmaor); + dmaor_write(shdev, dmaor & ~(DMAOR_NMIF | DMAOR_AE | DMAOR_DME)); } -static int sh_dmae_rst(int id) +static int sh_dmae_rst(struct sh_dmae_device *shdev) { unsigned short dmaor; - sh_dmae_ctl_stop(id); - dmaor = dmaor_read_reg(id) | DMAOR_INIT; + sh_dmae_ctl_stop(shdev); + dmaor = dmaor_read(shdev) | shdev->pdata->dmaor_init; - dmaor_write_reg(id, dmaor); - if (dmaor_read_reg(id) & (DMAOR_AE | DMAOR_NMIF)) { - pr_warning(KERN_ERR "dma-sh: Can't initialize DMAOR.\n"); + dmaor_write(shdev, dmaor); + if (dmaor_read(shdev) & (DMAOR_AE | DMAOR_NMIF)) { + pr_warning("dma-sh: Can't initialize DMAOR.\n"); return -EINVAL; } return 0; @@ -102,13 +105,36 @@ static bool dmae_is_busy(struct sh_dmae_chan *sh_chan) return false; /* waiting */ } -static unsigned int ts_shift[] = TS_SHIFT; -static inline unsigned int calc_xmit_shift(u32 chcr) +static unsigned int calc_xmit_shift(struct sh_dmae_chan *sh_chan, u32 chcr) { - int cnt = ((chcr & CHCR_TS_LOW_MASK) >> CHCR_TS_LOW_SHIFT) | - ((chcr & CHCR_TS_HIGH_MASK) >> CHCR_TS_HIGH_SHIFT); + struct sh_dmae_device *shdev = container_of(sh_chan->common.device, + struct sh_dmae_device, common); + struct sh_dmae_pdata *pdata = shdev->pdata; + int cnt = ((chcr & pdata->ts_low_mask) >> pdata->ts_low_shift) | + ((chcr & pdata->ts_high_mask) >> pdata->ts_high_shift); + + if (cnt >= pdata->ts_shift_num) + cnt = 0; - return ts_shift[cnt]; + return pdata->ts_shift[cnt]; +} + +static u32 log2size_to_chcr(struct sh_dmae_chan *sh_chan, int l2size) +{ + struct sh_dmae_device *shdev = container_of(sh_chan->common.device, + struct sh_dmae_device, common); + struct sh_dmae_pdata *pdata = shdev->pdata; + int i; + + for (i = 0; i < pdata->ts_shift_num; i++) + if (pdata->ts_shift[i] == l2size) + break; + + if (i == pdata->ts_shift_num) + i = 0; + + return ((i << pdata->ts_low_shift) & pdata->ts_low_mask) | + ((i << pdata->ts_high_shift) & pdata->ts_high_mask); } static void dmae_set_reg(struct sh_dmae_chan *sh_chan, struct sh_dmae_regs *hw) @@ -136,8 +162,13 @@ static void dmae_halt(struct sh_dmae_chan *sh_chan) static void dmae_init(struct sh_dmae_chan *sh_chan) { - u32 chcr = RS_DEFAULT; /* default is DUAL mode */ - sh_chan->xmit_shift = calc_xmit_shift(chcr); + /* + * Default configuration for dual address memory-memory transfer. + * 0x400 represents auto-request. + */ + u32 chcr = DM_INC | SM_INC | 0x400 | log2size_to_chcr(sh_chan, + LOG2_DEFAULT_XFER_SIZE); + sh_chan->xmit_shift = calc_xmit_shift(sh_chan, chcr); sh_dmae_writel(sh_chan, chcr, CHCR); } @@ -147,37 +178,26 @@ static int dmae_set_chcr(struct sh_dmae_chan *sh_chan, u32 val) if (dmae_is_busy(sh_chan)) return -EBUSY; - sh_chan->xmit_shift = calc_xmit_shift(val); + sh_chan->xmit_shift = calc_xmit_shift(sh_chan, val); sh_dmae_writel(sh_chan, val, CHCR); return 0; } -#define DMARS_SHIFT 8 -#define DMARS_CHAN_MSK 0x01 static int dmae_set_dmars(struct sh_dmae_chan *sh_chan, u16 val) { - u32 addr; - int shift = 0; + struct sh_dmae_device *shdev = container_of(sh_chan->common.device, + struct sh_dmae_device, common); + struct sh_dmae_pdata *pdata = shdev->pdata; + struct sh_dmae_channel *chan_pdata = &pdata->channel[sh_chan->id]; + u16 __iomem *addr = shdev->dmars + chan_pdata->dmars / sizeof(u16); + int shift = chan_pdata->dmars_bit; if (dmae_is_busy(sh_chan)) return -EBUSY; - if (sh_chan->id & DMARS_CHAN_MSK) - shift = DMARS_SHIFT; - - if (sh_chan->id < 6) - /* DMA0RS0 - DMA0RS2 */ - addr = SH_DMARS_BASE0 + (sh_chan->id / 2) * 4; -#ifdef SH_DMARS_BASE1 - else if (sh_chan->id < 12) - /* DMA1RS0 - DMA1RS2 */ - addr = SH_DMARS_BASE1 + ((sh_chan->id - 6) / 2) * 4; -#endif - else - return -EINVAL; - - ctrl_outw((val << shift) | (ctrl_inw(addr) & (0xFF00 >> shift)), addr); + __raw_writew((__raw_readw(addr) & (0xff00 >> shift)) | (val << shift), + addr); return 0; } @@ -251,15 +271,15 @@ static struct sh_dmae_slave_config *sh_dmae_find_slave( struct dma_device *dma_dev = sh_chan->common.device; struct sh_dmae_device *shdev = container_of(dma_dev, struct sh_dmae_device, common); - struct sh_dmae_pdata *pdata = &shdev->pdata; + struct sh_dmae_pdata *pdata = shdev->pdata; int i; if ((unsigned)slave_id >= SHDMA_SLAVE_NUMBER) return NULL; - for (i = 0; i < pdata->config_num; i++) - if (pdata->config[i].slave_id == slave_id) - return pdata->config + i; + for (i = 0; i < pdata->slave_num; i++) + if (pdata->slave[i].slave_id == slave_id) + return pdata->slave + i; return NULL; } @@ -270,6 +290,8 @@ static int sh_dmae_alloc_chan_resources(struct dma_chan *chan) struct sh_desc *desc; struct sh_dmae_slave *param = chan->private; + pm_runtime_get_sync(sh_chan->dev); + /* * This relies on the guarantee from dmaengine that alloc_chan_resources * never runs concurrently with itself or free_chan_resources. @@ -288,9 +310,8 @@ static int sh_dmae_alloc_chan_resources(struct dma_chan *chan) dmae_set_dmars(sh_chan, cfg->mid_rid); dmae_set_chcr(sh_chan, cfg->chcr); - } else { - if ((sh_dmae_readl(sh_chan, CHCR) & 0x700) != 0x400) - dmae_set_chcr(sh_chan, RS_DEFAULT); + } else if ((sh_dmae_readl(sh_chan, CHCR) & 0xf00) != 0x400) { + dmae_init(sh_chan); } spin_lock_bh(&sh_chan->desc_lock); @@ -312,6 +333,9 @@ static int sh_dmae_alloc_chan_resources(struct dma_chan *chan) } spin_unlock_bh(&sh_chan->desc_lock); + if (!sh_chan->descs_allocated) + pm_runtime_put(sh_chan->dev); + return sh_chan->descs_allocated; } @@ -323,6 +347,7 @@ static void sh_dmae_free_chan_resources(struct dma_chan *chan) struct sh_dmae_chan *sh_chan = to_sh_chan(chan); struct sh_desc *desc, *_desc; LIST_HEAD(list); + int descs = sh_chan->descs_allocated; dmae_halt(sh_chan); @@ -343,6 +368,9 @@ static void sh_dmae_free_chan_resources(struct dma_chan *chan) spin_unlock_bh(&sh_chan->desc_lock); + if (descs > 0) + pm_runtime_put(sh_chan->dev); + list_for_each_entry_safe(desc, _desc, &list, node) kfree(desc); } @@ -559,6 +587,19 @@ static void sh_dmae_terminate_all(struct dma_chan *chan) if (!chan) return; + dmae_halt(sh_chan); + + spin_lock_bh(&sh_chan->desc_lock); + if (!list_empty(&sh_chan->ld_queue)) { + /* Record partial transfer */ + struct sh_desc *desc = list_entry(sh_chan->ld_queue.next, + struct sh_desc, node); + desc->partial = (desc->hw.tcr - sh_dmae_readl(sh_chan, TCR)) << + sh_chan->xmit_shift; + + } + spin_unlock_bh(&sh_chan->desc_lock); + sh_dmae_chan_ld_cleanup(sh_chan, true); } @@ -661,7 +702,7 @@ static void sh_dmae_chan_ld_cleanup(struct sh_dmae_chan *sh_chan, bool all) static void sh_chan_xfer_ld_queue(struct sh_dmae_chan *sh_chan) { - struct sh_desc *sd; + struct sh_desc *desc; spin_lock_bh(&sh_chan->desc_lock); /* DMA work check */ @@ -671,10 +712,13 @@ static void sh_chan_xfer_ld_queue(struct sh_dmae_chan *sh_chan) } /* Find the first not transferred desciptor */ - list_for_each_entry(sd, &sh_chan->ld_queue, node) - if (sd->mark == DESC_SUBMITTED) { + list_for_each_entry(desc, &sh_chan->ld_queue, node) + if (desc->mark == DESC_SUBMITTED) { + dev_dbg(sh_chan->dev, "Queue #%d to %d: %u@%x -> %x\n", + desc->async_tx.cookie, sh_chan->id, + desc->hw.tcr, desc->hw.sar, desc->hw.dar); /* Get the ld start address from ld_queue */ - dmae_set_reg(sh_chan, &sd->hw); + dmae_set_reg(sh_chan, &desc->hw); dmae_start(sh_chan); break; } @@ -696,6 +740,7 @@ static enum dma_status sh_dmae_is_complete(struct dma_chan *chan, struct sh_dmae_chan *sh_chan = to_sh_chan(chan); dma_cookie_t last_used; dma_cookie_t last_complete; + enum dma_status status; sh_dmae_chan_ld_cleanup(sh_chan, false); @@ -709,7 +754,27 @@ static enum dma_status sh_dmae_is_complete(struct dma_chan *chan, if (used) *used = last_used; - return dma_async_is_complete(cookie, last_complete, last_used); + spin_lock_bh(&sh_chan->desc_lock); + + status = dma_async_is_complete(cookie, last_complete, last_used); + + /* + * If we don't find cookie on the queue, it has been aborted and we have + * to report error + */ + if (status != DMA_SUCCESS) { + struct sh_desc *desc; + status = DMA_ERROR; + list_for_each_entry(desc, &sh_chan->ld_queue, node) + if (desc->cookie == cookie) { + status = DMA_IN_PROGRESS; + break; + } + } + + spin_unlock_bh(&sh_chan->desc_lock); + + return status; } static irqreturn_t sh_dmae_interrupt(int irq, void *data) @@ -732,40 +797,32 @@ static irqreturn_t sh_dmae_interrupt(int irq, void *data) #if defined(CONFIG_CPU_SH4) static irqreturn_t sh_dmae_err(int irq, void *data) { - int err = 0; struct sh_dmae_device *shdev = (struct sh_dmae_device *)data; + int i; - /* IRQ Multi */ - if (shdev->pdata.mode & SHDMA_MIX_IRQ) { - int __maybe_unused cnt = 0; - switch (irq) { -#if defined(DMTE6_IRQ) && defined(DMAE1_IRQ) - case DMTE6_IRQ: - cnt++; -#endif - case DMTE0_IRQ: - if (dmaor_read_reg(cnt) & (DMAOR_NMIF | DMAOR_AE)) { - disable_irq(irq); - return IRQ_HANDLED; + /* halt the dma controller */ + sh_dmae_ctl_stop(shdev); + + /* We cannot detect, which channel caused the error, have to reset all */ + for (i = 0; i < SH_DMAC_MAX_CHANNELS; i++) { + struct sh_dmae_chan *sh_chan = shdev->chan[i]; + if (sh_chan) { + struct sh_desc *desc; + /* Stop the channel */ + dmae_halt(sh_chan); + /* Complete all */ + list_for_each_entry(desc, &sh_chan->ld_queue, node) { + struct dma_async_tx_descriptor *tx = &desc->async_tx; + desc->mark = DESC_IDLE; + if (tx->callback) + tx->callback(tx->callback_param); } - default: - return IRQ_NONE; + list_splice_init(&sh_chan->ld_queue, &sh_chan->ld_free); } - } else { - /* reset dma controller */ - err = sh_dmae_rst(0); - if (err) - return err; -#ifdef SH_DMAC_BASE1 - if (shdev->pdata.mode & SHDMA_DMAOR1) { - err = sh_dmae_rst(1); - if (err) - return err; - } -#endif - disable_irq(irq); - return IRQ_HANDLED; } + sh_dmae_rst(shdev); + + return IRQ_HANDLED; } #endif @@ -796,19 +853,12 @@ static void dmae_do_tasklet(unsigned long data) sh_dmae_chan_ld_cleanup(sh_chan, false); } -static unsigned int get_dmae_irq(unsigned int id) -{ - unsigned int irq = 0; - if (id < ARRAY_SIZE(dmte_irq_map)) - irq = dmte_irq_map[id]; - return irq; -} - -static int __devinit sh_dmae_chan_probe(struct sh_dmae_device *shdev, int id) +static int __devinit sh_dmae_chan_probe(struct sh_dmae_device *shdev, int id, + int irq, unsigned long flags) { int err; - unsigned int irq = get_dmae_irq(id); - unsigned long irqflags = IRQF_DISABLED; + struct sh_dmae_channel *chan_pdata = &shdev->pdata->channel[id]; + struct platform_device *pdev = to_platform_device(shdev->common.dev); struct sh_dmae_chan *new_sh_chan; /* alloc channel */ @@ -819,8 +869,13 @@ static int __devinit sh_dmae_chan_probe(struct sh_dmae_device *shdev, int id) return -ENOMEM; } + /* copy struct dma_device */ + new_sh_chan->common.device = &shdev->common; + new_sh_chan->dev = shdev->common.dev; new_sh_chan->id = id; + new_sh_chan->irq = irq; + new_sh_chan->base = shdev->chan_reg + chan_pdata->offset / sizeof(u32); /* Init DMA tasklet */ tasklet_init(&new_sh_chan->tasklet, dmae_do_tasklet, @@ -835,29 +890,20 @@ static int __devinit sh_dmae_chan_probe(struct sh_dmae_device *shdev, int id) INIT_LIST_HEAD(&new_sh_chan->ld_queue); INIT_LIST_HEAD(&new_sh_chan->ld_free); - /* copy struct dma_device */ - new_sh_chan->common.device = &shdev->common; - /* Add the channel to DMA device channel list */ list_add_tail(&new_sh_chan->common.device_node, &shdev->common.channels); shdev->common.chancnt++; - if (shdev->pdata.mode & SHDMA_MIX_IRQ) { - irqflags = IRQF_SHARED; -#if defined(DMTE6_IRQ) - if (irq >= DMTE6_IRQ) - irq = DMTE6_IRQ; - else -#endif - irq = DMTE0_IRQ; - } - - snprintf(new_sh_chan->dev_id, sizeof(new_sh_chan->dev_id), - "sh-dmae%d", new_sh_chan->id); + if (pdev->id >= 0) + snprintf(new_sh_chan->dev_id, sizeof(new_sh_chan->dev_id), + "sh-dmae%d.%d", pdev->id, new_sh_chan->id); + else + snprintf(new_sh_chan->dev_id, sizeof(new_sh_chan->dev_id), + "sh-dma%d", new_sh_chan->id); /* set up channel irq */ - err = request_irq(irq, &sh_dmae_interrupt, irqflags, + err = request_irq(irq, &sh_dmae_interrupt, flags, new_sh_chan->dev_id, new_sh_chan); if (err) { dev_err(shdev->common.dev, "DMA channel %d request_irq error " @@ -881,12 +927,12 @@ static void sh_dmae_chan_remove(struct sh_dmae_device *shdev) for (i = shdev->common.chancnt - 1 ; i >= 0 ; i--) { if (shdev->chan[i]) { - struct sh_dmae_chan *shchan = shdev->chan[i]; - if (!(shdev->pdata.mode & SHDMA_MIX_IRQ)) - free_irq(dmte_irq_map[i], shchan); + struct sh_dmae_chan *sh_chan = shdev->chan[i]; - list_del(&shchan->common.device_node); - kfree(shchan); + free_irq(sh_chan->irq, sh_chan); + + list_del(&sh_chan->common.device_node); + kfree(sh_chan); shdev->chan[i] = NULL; } } @@ -895,47 +941,84 @@ static void sh_dmae_chan_remove(struct sh_dmae_device *shdev) static int __init sh_dmae_probe(struct platform_device *pdev) { - int err = 0, cnt, ecnt; - unsigned long irqflags = IRQF_DISABLED; -#if defined(CONFIG_CPU_SH4) - int eirq[] = { DMAE0_IRQ, -#if defined(DMAE1_IRQ) - DMAE1_IRQ -#endif - }; -#endif + struct sh_dmae_pdata *pdata = pdev->dev.platform_data; + unsigned long irqflags = IRQF_DISABLED, + chan_flag[SH_DMAC_MAX_CHANNELS] = {}; + int errirq, chan_irq[SH_DMAC_MAX_CHANNELS]; + int err, i, irq_cnt = 0, irqres = 0; struct sh_dmae_device *shdev; + struct resource *chan, *dmars, *errirq_res, *chanirq_res; /* get platform data */ - if (!pdev->dev.platform_data) + if (!pdata || !pdata->channel_num) return -ENODEV; + chan = platform_get_resource(pdev, IORESOURCE_MEM, 0); + /* DMARS area is optional, if absent, this controller cannot do slave DMA */ + dmars = platform_get_resource(pdev, IORESOURCE_MEM, 1); + /* + * IRQ resources: + * 1. there always must be at least one IRQ IO-resource. On SH4 it is + * the error IRQ, in which case it is the only IRQ in this resource: + * start == end. If it is the only IRQ resource, all channels also + * use the same IRQ. + * 2. DMA channel IRQ resources can be specified one per resource or in + * ranges (start != end) + * 3. iff all events (channels and, optionally, error) on this + * controller use the same IRQ, only one IRQ resource can be + * specified, otherwise there must be one IRQ per channel, even if + * some of them are equal + * 4. if all IRQs on this controller are equal or if some specific IRQs + * specify IORESOURCE_IRQ_SHAREABLE in their resources, they will be + * requested with the IRQF_SHARED flag + */ + errirq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!chan || !errirq_res) + return -ENODEV; + + if (!request_mem_region(chan->start, resource_size(chan), pdev->name)) { + dev_err(&pdev->dev, "DMAC register region already claimed\n"); + return -EBUSY; + } + + if (dmars && !request_mem_region(dmars->start, resource_size(dmars), pdev->name)) { + dev_err(&pdev->dev, "DMAC DMARS region already claimed\n"); + err = -EBUSY; + goto ermrdmars; + } + + err = -ENOMEM; shdev = kzalloc(sizeof(struct sh_dmae_device), GFP_KERNEL); if (!shdev) { - dev_err(&pdev->dev, "No enough memory\n"); - return -ENOMEM; + dev_err(&pdev->dev, "Not enough memory\n"); + goto ealloc; + } + + shdev->chan_reg = ioremap(chan->start, resource_size(chan)); + if (!shdev->chan_reg) + goto emapchan; + if (dmars) { + shdev->dmars = ioremap(dmars->start, resource_size(dmars)); + if (!shdev->dmars) + goto emapdmars; } /* platform data */ - memcpy(&shdev->pdata, pdev->dev.platform_data, - sizeof(struct sh_dmae_pdata)); + shdev->pdata = pdata; + + pm_runtime_enable(&pdev->dev); + pm_runtime_get_sync(&pdev->dev); /* reset dma controller */ - err = sh_dmae_rst(0); + err = sh_dmae_rst(shdev); if (err) goto rst_err; - /* SH7780/85/23 has DMAOR1 */ - if (shdev->pdata.mode & SHDMA_DMAOR1) { - err = sh_dmae_rst(1); - if (err) - goto rst_err; - } - INIT_LIST_HEAD(&shdev->common.channels); dma_cap_set(DMA_MEMCPY, shdev->common.cap_mask); - dma_cap_set(DMA_SLAVE, shdev->common.cap_mask); + if (dmars) + dma_cap_set(DMA_SLAVE, shdev->common.cap_mask); shdev->common.device_alloc_chan_resources = sh_dmae_alloc_chan_resources; @@ -950,37 +1033,72 @@ static int __init sh_dmae_probe(struct platform_device *pdev) shdev->common.dev = &pdev->dev; /* Default transfer size of 32 bytes requires 32-byte alignment */ - shdev->common.copy_align = 5; + shdev->common.copy_align = LOG2_DEFAULT_XFER_SIZE; #if defined(CONFIG_CPU_SH4) - /* Non Mix IRQ mode SH7722/SH7730 etc... */ - if (shdev->pdata.mode & SHDMA_MIX_IRQ) { + chanirq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 1); + + if (!chanirq_res) + chanirq_res = errirq_res; + else + irqres++; + + if (chanirq_res == errirq_res || + (errirq_res->flags & IORESOURCE_BITS) == IORESOURCE_IRQ_SHAREABLE) irqflags = IRQF_SHARED; - eirq[0] = DMTE0_IRQ; -#if defined(DMTE6_IRQ) && defined(DMAE1_IRQ) - eirq[1] = DMTE6_IRQ; -#endif + + errirq = errirq_res->start; + + err = request_irq(errirq, sh_dmae_err, irqflags, + "DMAC Address Error", shdev); + if (err) { + dev_err(&pdev->dev, + "DMA failed requesting irq #%d, error %d\n", + errirq, err); + goto eirq_err; } - for (ecnt = 0 ; ecnt < ARRAY_SIZE(eirq); ecnt++) { - err = request_irq(eirq[ecnt], sh_dmae_err, irqflags, - "DMAC Address Error", shdev); - if (err) { - dev_err(&pdev->dev, "DMA device request_irq" - "error (irq %d) with return %d\n", - eirq[ecnt], err); - goto eirq_err; +#else + chanirq_res = errirq_res; +#endif /* CONFIG_CPU_SH4 */ + + if (chanirq_res->start == chanirq_res->end && + !platform_get_resource(pdev, IORESOURCE_IRQ, 1)) { + /* Special case - all multiplexed */ + for (; irq_cnt < pdata->channel_num; irq_cnt++) { + chan_irq[irq_cnt] = chanirq_res->start; + chan_flag[irq_cnt] = IRQF_SHARED; } + } else { + do { + for (i = chanirq_res->start; i <= chanirq_res->end; i++) { + if ((errirq_res->flags & IORESOURCE_BITS) == + IORESOURCE_IRQ_SHAREABLE) + chan_flag[irq_cnt] = IRQF_SHARED; + else + chan_flag[irq_cnt] = IRQF_DISABLED; + dev_dbg(&pdev->dev, + "Found IRQ %d for channel %d\n", + i, irq_cnt); + chan_irq[irq_cnt++] = i; + } + chanirq_res = platform_get_resource(pdev, + IORESOURCE_IRQ, ++irqres); + } while (irq_cnt < pdata->channel_num && chanirq_res); } -#endif /* CONFIG_CPU_SH4 */ + + if (irq_cnt < pdata->channel_num) + goto eirqres; /* Create DMA Channel */ - for (cnt = 0 ; cnt < MAX_DMA_CHANNELS ; cnt++) { - err = sh_dmae_chan_probe(shdev, cnt); + for (i = 0; i < pdata->channel_num; i++) { + err = sh_dmae_chan_probe(shdev, i, chan_irq[i], chan_flag[i]); if (err) goto chan_probe_err; } + pm_runtime_put(&pdev->dev); + platform_set_drvdata(pdev, shdev); dma_async_device_register(&shdev->common); @@ -988,13 +1106,24 @@ static int __init sh_dmae_probe(struct platform_device *pdev) chan_probe_err: sh_dmae_chan_remove(shdev); - +eirqres: +#if defined(CONFIG_CPU_SH4) + free_irq(errirq, shdev); eirq_err: - for (ecnt-- ; ecnt >= 0; ecnt--) - free_irq(eirq[ecnt], shdev); - +#endif rst_err: + pm_runtime_put(&pdev->dev); + if (dmars) + iounmap(shdev->dmars); +emapdmars: + iounmap(shdev->chan_reg); +emapchan: kfree(shdev); +ealloc: + if (dmars) + release_mem_region(dmars->start, resource_size(dmars)); +ermrdmars: + release_mem_region(chan->start, resource_size(chan)); return err; } @@ -1002,36 +1131,39 @@ rst_err: static int __exit sh_dmae_remove(struct platform_device *pdev) { struct sh_dmae_device *shdev = platform_get_drvdata(pdev); + struct resource *res; + int errirq = platform_get_irq(pdev, 0); dma_async_device_unregister(&shdev->common); - if (shdev->pdata.mode & SHDMA_MIX_IRQ) { - free_irq(DMTE0_IRQ, shdev); -#if defined(DMTE6_IRQ) - free_irq(DMTE6_IRQ, shdev); -#endif - } + if (errirq > 0) + free_irq(errirq, shdev); /* channel data remove */ sh_dmae_chan_remove(shdev); - if (!(shdev->pdata.mode & SHDMA_MIX_IRQ)) { - free_irq(DMAE0_IRQ, shdev); -#if defined(DMAE1_IRQ) - free_irq(DMAE1_IRQ, shdev); -#endif - } + pm_runtime_disable(&pdev->dev); + + if (shdev->dmars) + iounmap(shdev->dmars); + iounmap(shdev->chan_reg); + kfree(shdev); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res) + release_mem_region(res->start, resource_size(res)); + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (res) + release_mem_region(res->start, resource_size(res)); + return 0; } static void sh_dmae_shutdown(struct platform_device *pdev) { struct sh_dmae_device *shdev = platform_get_drvdata(pdev); - sh_dmae_ctl_stop(0); - if (shdev->pdata.mode & SHDMA_DMAOR1) - sh_dmae_ctl_stop(1); + sh_dmae_ctl_stop(shdev); } static struct platform_driver sh_dmae_driver = { diff --git a/drivers/dma/shdma.h b/drivers/dma/shdma.h index 7e227f3..153609a 100644 --- a/drivers/dma/shdma.h +++ b/drivers/dma/shdma.h @@ -17,23 +17,9 @@ #include <linux/interrupt.h> #include <linux/list.h> -#define SH_DMA_TCR_MAX 0x00FFFFFF /* 16MB */ - -struct sh_dmae_regs { - u32 sar; /* SAR / source address */ - u32 dar; /* DAR / destination address */ - u32 tcr; /* TCR / transfer count */ -}; +#include <asm/dmaengine.h> -struct sh_desc { - struct sh_dmae_regs hw; - struct list_head node; - struct dma_async_tx_descriptor async_tx; - enum dma_data_direction direction; - dma_cookie_t cookie; - int chunks; - int mark; -}; +#define SH_DMA_TCR_MAX 0x00FFFFFF /* 16MB */ struct device; @@ -47,14 +33,18 @@ struct sh_dmae_chan { struct tasklet_struct tasklet; /* Tasklet */ int descs_allocated; /* desc count */ int xmit_shift; /* log_2(bytes_per_xfer) */ + int irq; int id; /* Raw id of this channel */ + u32 __iomem *base; char dev_id[16]; /* unique name per DMAC of channel */ }; struct sh_dmae_device { struct dma_device common; - struct sh_dmae_chan *chan[MAX_DMA_CHANNELS]; - struct sh_dmae_pdata pdata; + struct sh_dmae_chan *chan[SH_DMAC_MAX_CHANNELS]; + struct sh_dmae_pdata *pdata; + u32 __iomem *chan_reg; + u16 __iomem *dmars; }; #define to_sh_chan(chan) container_of(chan, struct sh_dmae_chan, common) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index a4cdbd5..fee678f 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -94,6 +94,23 @@ config GPIO_VR41XX help Say yes here to support the NEC VR4100 series General-purpose I/O Uint +config GPIO_SCH + tristate "Intel SCH GPIO" + depends on GPIOLIB && PCI + select MFD_CORE + select LPC_SCH + help + Say yes here to support GPIO interface on Intel Poulsbo SCH. + The Intel SCH contains a total of 14 GPIO pins. Ten GPIOs are + powered by the core power rail and are turned off during sleep + modes (S3 and higher). The remaining four GPIOs are powered by + the Intel SCH suspend power supply. These GPIOs remain + active during S3. The suspend powered GPIOs can be used to wake the + system from the Suspend-to-RAM state. + + This driver can also be built as a module. If so, the module + will be called sch-gpio. + comment "I2C GPIO expanders:" config GPIO_MAX7300 @@ -185,6 +202,20 @@ config GPIO_WM831X Say yes here to access the GPIO signals of WM831x power management chips from Wolfson Microelectronics. +config GPIO_WM8350 + tristate "WM8350 GPIOs" + depends on MFD_WM8350 + help + Say yes here to access the GPIO signals of WM8350 power management + chips from Wolfson Microelectronics. + +config GPIO_WM8994 + tristate "WM8994 GPIOs" + depends on MFD_WM8994 + help + Say yes here to access the GPIO signals of WM8994 audio hub + CODECs from Wolfson Microelectronics. + config GPIO_ADP5520 tristate "GPIO Support for ADP5520 PMIC" depends on PMIC_ADP5520 diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 128abf8..10f3f8d 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -25,3 +25,6 @@ obj-$(CONFIG_GPIO_BT8XX) += bt8xxgpio.o obj-$(CONFIG_GPIO_IT8761E) += it8761e_gpio.o obj-$(CONFIG_GPIO_VR41XX) += vr41xx_giu.o obj-$(CONFIG_GPIO_WM831X) += wm831x-gpio.o +obj-$(CONFIG_GPIO_WM8350) += wm8350-gpiolib.o +obj-$(CONFIG_GPIO_WM8994) += wm8994-gpio.o +obj-$(CONFIG_GPIO_SCH) += sch_gpio.o
\ No newline at end of file diff --git a/drivers/gpio/sch_gpio.c b/drivers/gpio/sch_gpio.c new file mode 100644 index 0000000..5835213 --- /dev/null +++ b/drivers/gpio/sch_gpio.c @@ -0,0 +1,295 @@ +/* + * sch_gpio.c - GPIO interface for Intel Poulsbo SCH + * + * Copyright (c) 2010 CompuLab Ltd + * Author: Denis Turischev <denis@compulab.co.il> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License 2 as published + * by the Free Software Foundation. + * + * 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; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/io.h> +#include <linux/errno.h> +#include <linux/acpi.h> +#include <linux/platform_device.h> + +#include <linux/gpio.h> + +static DEFINE_SPINLOCK(gpio_lock); + +#define CGEN (0x00) +#define CGIO (0x04) +#define CGLV (0x08) + +#define RGEN (0x20) +#define RGIO (0x24) +#define RGLV (0x28) + +static unsigned short gpio_ba; + +static int sch_gpio_core_direction_in(struct gpio_chip *gc, unsigned gpio_num) +{ + u8 curr_dirs; + unsigned short offset, bit; + + spin_lock(&gpio_lock); + + offset = CGIO + gpio_num / 8; + bit = gpio_num % 8; + + curr_dirs = inb(gpio_ba + offset); + + if (!(curr_dirs & (1 << bit))) + outb(curr_dirs | (1 << bit), gpio_ba + offset); + + spin_unlock(&gpio_lock); + return 0; +} + +static int sch_gpio_core_get(struct gpio_chip *gc, unsigned gpio_num) +{ + int res; + unsigned short offset, bit; + + offset = CGLV + gpio_num / 8; + bit = gpio_num % 8; + + res = !!(inb(gpio_ba + offset) & (1 << bit)); + return res; +} + +static void sch_gpio_core_set(struct gpio_chip *gc, unsigned gpio_num, int val) +{ + u8 curr_vals; + unsigned short offset, bit; + + spin_lock(&gpio_lock); + + offset = CGLV + gpio_num / 8; + bit = gpio_num % 8; + + curr_vals = inb(gpio_ba + offset); + + if (val) + outb(curr_vals | (1 << bit), gpio_ba + offset); + else + outb((curr_vals & ~(1 << bit)), gpio_ba + offset); + spin_unlock(&gpio_lock); +} + +static int sch_gpio_core_direction_out(struct gpio_chip *gc, + unsigned gpio_num, int val) +{ + u8 curr_dirs; + unsigned short offset, bit; + + sch_gpio_core_set(gc, gpio_num, val); + + spin_lock(&gpio_lock); + + offset = CGIO + gpio_num / 8; + bit = gpio_num % 8; + + curr_dirs = inb(gpio_ba + offset); + if (curr_dirs & (1 << bit)) + outb(curr_dirs & ~(1 << bit), gpio_ba + offset); + + spin_unlock(&gpio_lock); + return 0; +} + +static struct gpio_chip sch_gpio_core = { + .label = "sch_gpio_core", + .owner = THIS_MODULE, + .direction_input = sch_gpio_core_direction_in, + .get = sch_gpio_core_get, + .direction_output = sch_gpio_core_direction_out, + .set = sch_gpio_core_set, +}; + +static int sch_gpio_resume_direction_in(struct gpio_chip *gc, + unsigned gpio_num) +{ + u8 curr_dirs; + + spin_lock(&gpio_lock); + + curr_dirs = inb(gpio_ba + RGIO); + + if (!(curr_dirs & (1 << gpio_num))) + outb(curr_dirs | (1 << gpio_num) , gpio_ba + RGIO); + + spin_unlock(&gpio_lock); + return 0; +} + +static int sch_gpio_resume_get(struct gpio_chip *gc, unsigned gpio_num) +{ + return !!(inb(gpio_ba + RGLV) & (1 << gpio_num)); +} + +static void sch_gpio_resume_set(struct gpio_chip *gc, + unsigned gpio_num, int val) +{ + u8 curr_vals; + + spin_lock(&gpio_lock); + + curr_vals = inb(gpio_ba + RGLV); + + if (val) + outb(curr_vals | (1 << gpio_num), gpio_ba + RGLV); + else + outb((curr_vals & ~(1 << gpio_num)), gpio_ba + RGLV); + + spin_unlock(&gpio_lock); +} + +static int sch_gpio_resume_direction_out(struct gpio_chip *gc, + unsigned gpio_num, int val) +{ + u8 curr_dirs; + + sch_gpio_resume_set(gc, gpio_num, val); + + spin_lock(&gpio_lock); + + curr_dirs = inb(gpio_ba + RGIO); + if (curr_dirs & (1 << gpio_num)) + outb(curr_dirs & ~(1 << gpio_num), gpio_ba + RGIO); + + spin_unlock(&gpio_lock); + return 0; +} + +static struct gpio_chip sch_gpio_resume = { + .label = "sch_gpio_resume", + .owner = THIS_MODULE, + .direction_input = sch_gpio_resume_direction_in, + .get = sch_gpio_resume_get, + .direction_output = sch_gpio_resume_direction_out, + .set = sch_gpio_resume_set, +}; + +static int __devinit sch_gpio_probe(struct platform_device *pdev) +{ + struct resource *res; + int err; + + res = platform_get_resource(pdev, IORESOURCE_IO, 0); + if (!res) + return -EBUSY; + + if (!request_region(res->start, resource_size(res), pdev->name)) + return -EBUSY; + + gpio_ba = res->start; + + sch_gpio_core.base = 0; + sch_gpio_core.ngpio = 10; + sch_gpio_core.dev = &pdev->dev; + + sch_gpio_resume.base = 10; + sch_gpio_resume.ngpio = 4; + sch_gpio_resume.dev = &pdev->dev; + + err = gpiochip_add(&sch_gpio_core); + if (err < 0) + goto err_sch_gpio_core; + + err = gpiochip_add(&sch_gpio_resume); + if (err < 0) + goto err_sch_gpio_resume; + + /* + * GPIO[6:0] enabled by default + * GPIO7 is configured by the CMC as SLPIOVR + * Enable GPIO[9:8] core powered gpios explicitly + */ + outb(0x3, gpio_ba + CGEN + 1); + /* + * SUS_GPIO[2:0] enabled by default + * Enable SUS_GPIO3 resume powered gpio explicitly + */ + outb(0x8, gpio_ba + RGEN); + + return 0; + +err_sch_gpio_resume: + err = gpiochip_remove(&sch_gpio_core); + if (err) + dev_err(&pdev->dev, "%s failed, %d\n", + "gpiochip_remove()", err); + +err_sch_gpio_core: + release_region(res->start, resource_size(res)); + gpio_ba = 0; + + return err; +} + +static int __devexit sch_gpio_remove(struct platform_device *pdev) +{ + struct resource *res; + if (gpio_ba) { + int err; + + err = gpiochip_remove(&sch_gpio_core); + if (err) + dev_err(&pdev->dev, "%s failed, %d\n", + "gpiochip_remove()", err); + err = gpiochip_remove(&sch_gpio_resume); + if (err) + dev_err(&pdev->dev, "%s failed, %d\n", + "gpiochip_remove()", err); + + res = platform_get_resource(pdev, IORESOURCE_IO, 0); + + release_region(res->start, resource_size(res)); + gpio_ba = 0; + + return err; + } + + return 0; +} + +static struct platform_driver sch_gpio_driver = { + .driver = { + .name = "sch_gpio", + .owner = THIS_MODULE, + }, + .probe = sch_gpio_probe, + .remove = __devexit_p(sch_gpio_remove), +}; + +static int __init sch_gpio_init(void) +{ + return platform_driver_register(&sch_gpio_driver); +} + +static void __exit sch_gpio_exit(void) +{ + platform_driver_unregister(&sch_gpio_driver); +} + +module_init(sch_gpio_init); +module_exit(sch_gpio_exit); + +MODULE_AUTHOR("Denis Turischev <denis@compulab.co.il>"); +MODULE_DESCRIPTION("GPIO interface for Intel Poulsbo SCH"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:sch_gpio"); diff --git a/drivers/gpio/wm831x-gpio.c b/drivers/gpio/wm831x-gpio.c index b4468b6..d09021f 100644 --- a/drivers/gpio/wm831x-gpio.c +++ b/drivers/gpio/wm831x-gpio.c @@ -38,10 +38,14 @@ static int wm831x_gpio_direction_in(struct gpio_chip *chip, unsigned offset) { struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip); struct wm831x *wm831x = wm831x_gpio->wm831x; + int val = WM831X_GPN_DIR; + + if (wm831x->has_gpio_ena) + val |= WM831X_GPN_TRI; return wm831x_set_bits(wm831x, WM831X_GPIO1_CONTROL + offset, - WM831X_GPN_DIR | WM831X_GPN_TRI, - WM831X_GPN_DIR); + WM831X_GPN_DIR | WM831X_GPN_TRI | + WM831X_GPN_FN_MASK, val); } static int wm831x_gpio_get(struct gpio_chip *chip, unsigned offset) @@ -60,23 +64,36 @@ static int wm831x_gpio_get(struct gpio_chip *chip, unsigned offset) return 0; } -static int wm831x_gpio_direction_out(struct gpio_chip *chip, - unsigned offset, int value) +static void wm831x_gpio_set(struct gpio_chip *chip, unsigned offset, int value) { struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip); struct wm831x *wm831x = wm831x_gpio->wm831x; - return wm831x_set_bits(wm831x, WM831X_GPIO1_CONTROL + offset, - WM831X_GPN_DIR | WM831X_GPN_TRI, 0); + wm831x_set_bits(wm831x, WM831X_GPIO_LEVEL, 1 << offset, + value << offset); } -static void wm831x_gpio_set(struct gpio_chip *chip, unsigned offset, int value) +static int wm831x_gpio_direction_out(struct gpio_chip *chip, + unsigned offset, int value) { struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip); struct wm831x *wm831x = wm831x_gpio->wm831x; + int val = 0; + int ret; - wm831x_set_bits(wm831x, WM831X_GPIO_LEVEL, 1 << offset, - value << offset); + if (wm831x->has_gpio_ena) + val |= WM831X_GPN_TRI; + + ret = wm831x_set_bits(wm831x, WM831X_GPIO1_CONTROL + offset, + WM831X_GPN_DIR | WM831X_GPN_TRI | + WM831X_GPN_FN_MASK, val); + if (ret < 0) + return ret; + + /* Can only set GPIO state once it's in output mode */ + wm831x_gpio_set(chip, offset, value); + + return 0; } static int wm831x_gpio_to_irq(struct gpio_chip *chip, unsigned offset) @@ -95,7 +112,7 @@ static void wm831x_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) { struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip); struct wm831x *wm831x = wm831x_gpio->wm831x; - int i; + int i, tristated; for (i = 0; i < chip->ngpio; i++) { int gpio = i + chip->base; @@ -162,15 +179,19 @@ static void wm831x_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) break; } + tristated = reg & WM831X_GPN_TRI; + if (wm831x->has_gpio_ena) + tristated = !tristated; + seq_printf(s, " %s %s %s %s%s\n" " %s%s (0x%4x)\n", reg & WM831X_GPN_DIR ? "in" : "out", wm831x_gpio_get(chip, i) ? "high" : "low", pull, powerdomain, - reg & WM831X_GPN_POL ? " inverted" : "", + reg & WM831X_GPN_POL ? "" : " inverted", reg & WM831X_GPN_OD ? "open-drain" : "CMOS", - reg & WM831X_GPN_TRI ? " tristated" : "", + tristated ? " tristated" : "", reg); } } diff --git a/drivers/gpio/wm8350-gpiolib.c b/drivers/gpio/wm8350-gpiolib.c new file mode 100644 index 0000000..511840d --- /dev/null +++ b/drivers/gpio/wm8350-gpiolib.c @@ -0,0 +1,181 @@ +/* + * wm835x-gpiolib.c -- gpiolib support for Wolfson WM835x PMICs + * + * Copyright 2009 Wolfson Microelectronics PLC. + * + * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/gpio.h> +#include <linux/mfd/core.h> +#include <linux/platform_device.h> +#include <linux/seq_file.h> + +#include <linux/mfd/wm8350/core.h> +#include <linux/mfd/wm8350/gpio.h> + +struct wm8350_gpio_data { + struct wm8350 *wm8350; + struct gpio_chip gpio_chip; +}; + +static inline struct wm8350_gpio_data *to_wm8350_gpio(struct gpio_chip *chip) +{ + return container_of(chip, struct wm8350_gpio_data, gpio_chip); +} + +static int wm8350_gpio_direction_in(struct gpio_chip *chip, unsigned offset) +{ + struct wm8350_gpio_data *wm8350_gpio = to_wm8350_gpio(chip); + struct wm8350 *wm8350 = wm8350_gpio->wm8350; + + return wm8350_set_bits(wm8350, WM8350_GPIO_CONFIGURATION_I_O, + 1 << offset); +} + +static int wm8350_gpio_get(struct gpio_chip *chip, unsigned offset) +{ + struct wm8350_gpio_data *wm8350_gpio = to_wm8350_gpio(chip); + struct wm8350 *wm8350 = wm8350_gpio->wm8350; + int ret; + + ret = wm8350_reg_read(wm8350, WM8350_GPIO_LEVEL); + if (ret < 0) + return ret; + + if (ret & (1 << offset)) + return 1; + else + return 0; +} + +static void wm8350_gpio_set(struct gpio_chip *chip, unsigned offset, int value) +{ + struct wm8350_gpio_data *wm8350_gpio = to_wm8350_gpio(chip); + struct wm8350 *wm8350 = wm8350_gpio->wm8350; + + if (value) + wm8350_set_bits(wm8350, WM8350_GPIO_LEVEL, 1 << offset); + else + wm8350_clear_bits(wm8350, WM8350_GPIO_LEVEL, 1 << offset); +} + +static int wm8350_gpio_direction_out(struct gpio_chip *chip, + unsigned offset, int value) +{ + struct wm8350_gpio_data *wm8350_gpio = to_wm8350_gpio(chip); + struct wm8350 *wm8350 = wm8350_gpio->wm8350; + int ret; + + ret = wm8350_clear_bits(wm8350, WM8350_GPIO_CONFIGURATION_I_O, + 1 << offset); + if (ret < 0) + return ret; + + /* Don't have an atomic direction/value setup */ + wm8350_gpio_set(chip, offset, value); + + return 0; +} + +static int wm8350_gpio_to_irq(struct gpio_chip *chip, unsigned offset) +{ + struct wm8350_gpio_data *wm8350_gpio = to_wm8350_gpio(chip); + struct wm8350 *wm8350 = wm8350_gpio->wm8350; + + if (!wm8350->irq_base) + return -EINVAL; + + return wm8350->irq_base + WM8350_IRQ_GPIO(offset); +} + +static struct gpio_chip template_chip = { + .label = "wm8350", + .owner = THIS_MODULE, + .direction_input = wm8350_gpio_direction_in, + .get = wm8350_gpio_get, + .direction_output = wm8350_gpio_direction_out, + .set = wm8350_gpio_set, + .to_irq = wm8350_gpio_to_irq, + .can_sleep = 1, +}; + +static int __devinit wm8350_gpio_probe(struct platform_device *pdev) +{ + struct wm8350 *wm8350 = dev_get_drvdata(pdev->dev.parent); + struct wm8350_platform_data *pdata = wm8350->dev->platform_data; + struct wm8350_gpio_data *wm8350_gpio; + int ret; + + wm8350_gpio = kzalloc(sizeof(*wm8350_gpio), GFP_KERNEL); + if (wm8350_gpio == NULL) + return -ENOMEM; + + wm8350_gpio->wm8350 = wm8350; + wm8350_gpio->gpio_chip = template_chip; + wm8350_gpio->gpio_chip.ngpio = 13; + wm8350_gpio->gpio_chip.dev = &pdev->dev; + if (pdata && pdata->gpio_base) + wm8350_gpio->gpio_chip.base = pdata->gpio_base; + else + wm8350_gpio->gpio_chip.base = -1; + + ret = gpiochip_add(&wm8350_gpio->gpio_chip); + if (ret < 0) { + dev_err(&pdev->dev, "Could not register gpiochip, %d\n", + ret); + goto err; + } + + platform_set_drvdata(pdev, wm8350_gpio); + + return ret; + +err: + kfree(wm8350_gpio); + return ret; +} + +static int __devexit wm8350_gpio_remove(struct platform_device *pdev) +{ + struct wm8350_gpio_data *wm8350_gpio = platform_get_drvdata(pdev); + int ret; + + ret = gpiochip_remove(&wm8350_gpio->gpio_chip); + if (ret == 0) + kfree(wm8350_gpio); + + return ret; +} + +static struct platform_driver wm8350_gpio_driver = { + .driver.name = "wm8350-gpio", + .driver.owner = THIS_MODULE, + .probe = wm8350_gpio_probe, + .remove = __devexit_p(wm8350_gpio_remove), +}; + +static int __init wm8350_gpio_init(void) +{ + return platform_driver_register(&wm8350_gpio_driver); +} +subsys_initcall(wm8350_gpio_init); + +static void __exit wm8350_gpio_exit(void) +{ + platform_driver_unregister(&wm8350_gpio_driver); +} +module_exit(wm8350_gpio_exit); + +MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); +MODULE_DESCRIPTION("GPIO interface for WM8350 PMICs"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:wm8350-gpio"); diff --git a/drivers/gpio/wm8994-gpio.c b/drivers/gpio/wm8994-gpio.c new file mode 100644 index 0000000..de28b4a4 --- /dev/null +++ b/drivers/gpio/wm8994-gpio.c @@ -0,0 +1,204 @@ +/* + * wm8994-gpio.c -- gpiolib support for Wolfson WM8994 + * + * Copyright 2009 Wolfson Microelectronics PLC. + * + * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/gpio.h> +#include <linux/mfd/core.h> +#include <linux/platform_device.h> +#include <linux/seq_file.h> + +#include <linux/mfd/wm8994/core.h> +#include <linux/mfd/wm8994/pdata.h> +#include <linux/mfd/wm8994/gpio.h> +#include <linux/mfd/wm8994/registers.h> + +struct wm8994_gpio { + struct wm8994 *wm8994; + struct gpio_chip gpio_chip; +}; + +static inline struct wm8994_gpio *to_wm8994_gpio(struct gpio_chip *chip) +{ + return container_of(chip, struct wm8994_gpio, gpio_chip); +} + +static int wm8994_gpio_direction_in(struct gpio_chip *chip, unsigned offset) +{ + struct wm8994_gpio *wm8994_gpio = to_wm8994_gpio(chip); + struct wm8994 *wm8994 = wm8994_gpio->wm8994; + + return wm8994_set_bits(wm8994, WM8994_GPIO_1 + offset, + WM8994_GPN_DIR, WM8994_GPN_DIR); +} + +static int wm8994_gpio_get(struct gpio_chip *chip, unsigned offset) +{ + struct wm8994_gpio *wm8994_gpio = to_wm8994_gpio(chip); + struct wm8994 *wm8994 = wm8994_gpio->wm8994; + int ret; + + ret = wm8994_reg_read(wm8994, WM8994_GPIO_1 + offset); + if (ret < 0) + return ret; + + if (ret & WM8994_GPN_LVL) + return 1; + else + return 0; +} + +static int wm8994_gpio_direction_out(struct gpio_chip *chip, + unsigned offset, int value) +{ + struct wm8994_gpio *wm8994_gpio = to_wm8994_gpio(chip); + struct wm8994 *wm8994 = wm8994_gpio->wm8994; + + return wm8994_set_bits(wm8994, WM8994_GPIO_1 + offset, + WM8994_GPN_DIR, 0); +} + +static void wm8994_gpio_set(struct gpio_chip *chip, unsigned offset, int value) +{ + struct wm8994_gpio *wm8994_gpio = to_wm8994_gpio(chip); + struct wm8994 *wm8994 = wm8994_gpio->wm8994; + + if (value) + value = WM8994_GPN_LVL; + + wm8994_set_bits(wm8994, WM8994_GPIO_1 + offset, WM8994_GPN_LVL, value); +} + +#ifdef CONFIG_DEBUG_FS +static void wm8994_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) +{ + struct wm8994_gpio *wm8994_gpio = to_wm8994_gpio(chip); + struct wm8994 *wm8994 = wm8994_gpio->wm8994; + int i; + + for (i = 0; i < chip->ngpio; i++) { + int gpio = i + chip->base; + int reg; + const char *label; + + /* We report the GPIO even if it's not requested since + * we're also reporting things like alternate + * functions which apply even when the GPIO is not in + * use as a GPIO. + */ + label = gpiochip_is_requested(chip, i); + if (!label) + label = "Unrequested"; + + seq_printf(s, " gpio-%-3d (%-20.20s) ", gpio, label); + + reg = wm8994_reg_read(wm8994, WM8994_GPIO_1 + i); + if (reg < 0) { + dev_err(wm8994->dev, + "GPIO control %d read failed: %d\n", + gpio, reg); + seq_printf(s, "\n"); + continue; + } + + /* No decode yet; note that GPIO2 is special */ + seq_printf(s, "(%x)\n", reg); + } +} +#else +#define wm8994_gpio_dbg_show NULL +#endif + +static struct gpio_chip template_chip = { + .label = "wm8994", + .owner = THIS_MODULE, + .direction_input = wm8994_gpio_direction_in, + .get = wm8994_gpio_get, + .direction_output = wm8994_gpio_direction_out, + .set = wm8994_gpio_set, + .dbg_show = wm8994_gpio_dbg_show, + .can_sleep = 1, +}; + +static int __devinit wm8994_gpio_probe(struct platform_device *pdev) +{ + struct wm8994 *wm8994 = dev_get_drvdata(pdev->dev.parent); + struct wm8994_pdata *pdata = wm8994->dev->platform_data; + struct wm8994_gpio *wm8994_gpio; + int ret; + + wm8994_gpio = kzalloc(sizeof(*wm8994_gpio), GFP_KERNEL); + if (wm8994_gpio == NULL) + return -ENOMEM; + + wm8994_gpio->wm8994 = wm8994; + wm8994_gpio->gpio_chip = template_chip; + wm8994_gpio->gpio_chip.ngpio = WM8994_GPIO_MAX; + wm8994_gpio->gpio_chip.dev = &pdev->dev; + if (pdata && pdata->gpio_base) + wm8994_gpio->gpio_chip.base = pdata->gpio_base; + else + wm8994_gpio->gpio_chip.base = -1; + + ret = gpiochip_add(&wm8994_gpio->gpio_chip); + if (ret < 0) { + dev_err(&pdev->dev, "Could not register gpiochip, %d\n", + ret); + goto err; + } + + platform_set_drvdata(pdev, wm8994_gpio); + + return ret; + +err: + kfree(wm8994_gpio); + return ret; +} + +static int __devexit wm8994_gpio_remove(struct platform_device *pdev) +{ + struct wm8994_gpio *wm8994_gpio = platform_get_drvdata(pdev); + int ret; + + ret = gpiochip_remove(&wm8994_gpio->gpio_chip); + if (ret == 0) + kfree(wm8994_gpio); + + return ret; +} + +static struct platform_driver wm8994_gpio_driver = { + .driver.name = "wm8994-gpio", + .driver.owner = THIS_MODULE, + .probe = wm8994_gpio_probe, + .remove = __devexit_p(wm8994_gpio_remove), +}; + +static int __init wm8994_gpio_init(void) +{ + return platform_driver_register(&wm8994_gpio_driver); +} +subsys_initcall(wm8994_gpio_init); + +static void __exit wm8994_gpio_exit(void) +{ + platform_driver_unregister(&wm8994_gpio_driver); +} +module_exit(wm8994_gpio_exit); + +MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); +MODULE_DESCRIPTION("GPIO interface for WM8994"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:wm8994-gpio"); diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 02afe89..9c6170c 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -106,6 +106,8 @@ config I2C_I801 config I2C_ISCH tristate "Intel SCH SMBus 1.0" depends on PCI + select MFD_CORE + select LPC_SCH help Say Y here if you want to use SMBus controller on the Intel SCH based systems. diff --git a/drivers/i2c/busses/i2c-isch.c b/drivers/i2c/busses/i2c-isch.c index 69c22f7..ddc258e 100644 --- a/drivers/i2c/busses/i2c-isch.c +++ b/drivers/i2c/busses/i2c-isch.c @@ -27,7 +27,7 @@ */ #include <linux/module.h> -#include <linux/pci.h> +#include <linux/platform_device.h> #include <linux/kernel.h> #include <linux/delay.h> #include <linux/stddef.h> @@ -46,12 +46,6 @@ #define SMBHSTDAT1 (7 + sch_smba) #define SMBBLKDAT (0x20 + sch_smba) -/* count for request_region */ -#define SMBIOSIZE 64 - -/* PCI Address Constants */ -#define SMBBA_SCH 0x40 - /* Other settings */ #define MAX_TIMEOUT 500 @@ -63,7 +57,6 @@ #define SCH_BLOCK_DATA 0x05 static unsigned short sch_smba; -static struct pci_driver sch_driver; static struct i2c_adapter sch_adapter; /* @@ -256,37 +249,23 @@ static struct i2c_adapter sch_adapter = { .algo = &smbus_algorithm, }; -static const struct pci_device_id sch_ids[] = { - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SCH_LPC) }, - { 0, } -}; - -MODULE_DEVICE_TABLE(pci, sch_ids); - -static int __devinit sch_probe(struct pci_dev *dev, - const struct pci_device_id *id) +static int __devinit smbus_sch_probe(struct platform_device *dev) { + struct resource *res; int retval; - unsigned int smba; - pci_read_config_dword(dev, SMBBA_SCH, &smba); - if (!(smba & (1 << 31))) { - dev_err(&dev->dev, "SMBus I/O space disabled!\n"); - return -ENODEV; - } + res = platform_get_resource(dev, IORESOURCE_IO, 0); + if (!res) + return -EBUSY; - sch_smba = (unsigned short)smba; - if (sch_smba == 0) { - dev_err(&dev->dev, "SMBus base address uninitialized!\n"); - return -ENODEV; - } - if (acpi_check_region(sch_smba, SMBIOSIZE, sch_driver.name)) - return -ENODEV; - if (!request_region(sch_smba, SMBIOSIZE, sch_driver.name)) { + if (!request_region(res->start, resource_size(res), dev->name)) { dev_err(&dev->dev, "SMBus region 0x%x already in use!\n", sch_smba); return -EBUSY; } + + sch_smba = res->start; + dev_dbg(&dev->dev, "SMBA = 0x%X\n", sch_smba); /* set up the sysfs linkage to our parent device */ @@ -298,37 +277,43 @@ static int __devinit sch_probe(struct pci_dev *dev, retval = i2c_add_adapter(&sch_adapter); if (retval) { dev_err(&dev->dev, "Couldn't register adapter!\n"); - release_region(sch_smba, SMBIOSIZE); + release_region(res->start, resource_size(res)); sch_smba = 0; } return retval; } -static void __devexit sch_remove(struct pci_dev *dev) +static int __devexit smbus_sch_remove(struct platform_device *pdev) { + struct resource *res; if (sch_smba) { i2c_del_adapter(&sch_adapter); - release_region(sch_smba, SMBIOSIZE); + res = platform_get_resource(pdev, IORESOURCE_IO, 0); + release_region(res->start, resource_size(res)); sch_smba = 0; } + + return 0; } -static struct pci_driver sch_driver = { - .name = "isch_smbus", - .id_table = sch_ids, - .probe = sch_probe, - .remove = __devexit_p(sch_remove), +static struct platform_driver smbus_sch_driver = { + .driver = { + .name = "isch_smbus", + .owner = THIS_MODULE, + }, + .probe = smbus_sch_probe, + .remove = __devexit_p(smbus_sch_remove), }; static int __init i2c_sch_init(void) { - return pci_register_driver(&sch_driver); + return platform_driver_register(&smbus_sch_driver); } static void __exit i2c_sch_exit(void) { - pci_unregister_driver(&sch_driver); + platform_driver_unregister(&smbus_sch_driver); } MODULE_AUTHOR("Jacob Pan <jacob.jun.pan@intel.com>"); @@ -337,3 +322,4 @@ MODULE_LICENSE("GPL"); module_init(i2c_sch_init); module_exit(i2c_sch_exit); +MODULE_ALIAS("platform:isch_smbus"); diff --git a/drivers/input/misc/88pm860x_onkey.c b/drivers/input/misc/88pm860x_onkey.c new file mode 100644 index 0000000..69a48e8 --- /dev/null +++ b/drivers/input/misc/88pm860x_onkey.c @@ -0,0 +1,155 @@ +/* + * 88pm860x_onkey.c - Marvell 88PM860x ONKEY driver + * + * Copyright (C) 2009-2010 Marvell International Ltd. + * Haojian Zhuang <haojian.zhuang@marvell.com> + * + * This file is subject to the terms and conditions of the GNU General + * Public License. See the file "COPYING" in the main directory of this + * archive for more details. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/i2c.h> +#include <linux/input.h> +#include <linux/interrupt.h> +#include <linux/mfd/88pm860x.h> + +#define PM8607_WAKEUP 0x0b + +#define LONG_ONKEY_EN (1 << 1) +#define ONKEY_STATUS (1 << 0) + +struct pm860x_onkey_info { + struct input_dev *idev; + struct pm860x_chip *chip; + struct i2c_client *i2c; + struct device *dev; + int irq; +}; + +/* 88PM860x gives us an interrupt when ONKEY is held */ +static irqreturn_t pm860x_onkey_handler(int irq, void *data) +{ + struct pm860x_onkey_info *info = data; + int ret; + + ret = pm860x_reg_read(info->i2c, PM8607_STATUS_2); + ret &= ONKEY_STATUS; + input_report_key(info->idev, KEY_POWER, ret); + input_sync(info->idev); + + /* Enable 8-second long onkey detection */ + pm860x_set_bits(info->i2c, PM8607_WAKEUP, 3, LONG_ONKEY_EN); + return IRQ_HANDLED; +} + +static int __devinit pm860x_onkey_probe(struct platform_device *pdev) +{ + struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); + struct pm860x_onkey_info *info; + int irq, ret; + + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + dev_err(&pdev->dev, "No IRQ resource!\n"); + return -EINVAL; + } + + info = kzalloc(sizeof(struct pm860x_onkey_info), GFP_KERNEL); + if (!info) + return -ENOMEM; + info->chip = chip; + info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion; + info->dev = &pdev->dev; + info->irq = irq + chip->irq_base; + + info->idev = input_allocate_device(); + if (!info->idev) { + dev_err(chip->dev, "Failed to allocate input dev\n"); + ret = -ENOMEM; + goto out; + } + + info->idev->name = "88pm860x_on"; + info->idev->phys = "88pm860x_on/input0"; + info->idev->id.bustype = BUS_I2C; + info->idev->dev.parent = &pdev->dev; + info->irq = irq; + info->idev->evbit[0] = BIT_MASK(EV_KEY); + info->idev->keybit[BIT_WORD(KEY_POWER)] = BIT_MASK(KEY_POWER); + + ret = input_register_device(info->idev); + if (ret) { + dev_err(chip->dev, "Can't register input device: %d\n", ret); + goto out_reg; + } + + ret = request_threaded_irq(info->irq, NULL, pm860x_onkey_handler, + IRQF_ONESHOT, "onkey", info); + if (ret < 0) { + dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n", + info->irq, ret); + goto out_irq; + } + + platform_set_drvdata(pdev, info); + return 0; + +out_irq: + input_unregister_device(info->idev); + kfree(info); + return ret; + +out_reg: + input_free_device(info->idev); +out: + kfree(info); + return ret; +} + +static int __devexit pm860x_onkey_remove(struct platform_device *pdev) +{ + struct pm860x_onkey_info *info = platform_get_drvdata(pdev); + + free_irq(info->irq, info); + input_unregister_device(info->idev); + kfree(info); + return 0; +} + +static struct platform_driver pm860x_onkey_driver = { + .driver = { + .name = "88pm860x-onkey", + .owner = THIS_MODULE, + }, + .probe = pm860x_onkey_probe, + .remove = __devexit_p(pm860x_onkey_remove), +}; + +static int __init pm860x_onkey_init(void) +{ + return platform_driver_register(&pm860x_onkey_driver); +} +module_init(pm860x_onkey_init); + +static void __exit pm860x_onkey_exit(void) +{ + platform_driver_unregister(&pm860x_onkey_driver); +} +module_exit(pm860x_onkey_exit); + +MODULE_DESCRIPTION("Marvell 88PM860x ONKEY driver"); +MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>"); +MODULE_LICENSE("GPL"); diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 16ec523..7097bfe 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -12,6 +12,16 @@ menuconfig INPUT_MISC if INPUT_MISC +config INPUT_88PM860X_ONKEY + tristate "88PM860x ONKEY support" + depends on MFD_88PM860X + help + Support the ONKEY of Marvell 88PM860x PMICs as an input device + reporting power button status. + + To compile this driver as a module, choose M here: the module + will be called 88pm860x_onkey. + config INPUT_PCSPKR tristate "PC Speaker support" depends on PCSPKR_PLATFORM diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index a8b8485..b611615 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile @@ -4,6 +4,7 @@ # Each configuration option enables a list of files. +obj-$(CONFIG_INPUT_88PM860X_ONKEY) += 88pm860x_onkey.o obj-$(CONFIG_INPUT_APANEL) += apanel.o obj-$(CONFIG_INPUT_ATI_REMOTE) += ati_remote.o obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o diff --git a/drivers/input/touchscreen/88pm860x-ts.c b/drivers/input/touchscreen/88pm860x-ts.c new file mode 100644 index 0000000..286bb49 --- /dev/null +++ b/drivers/input/touchscreen/88pm860x-ts.c @@ -0,0 +1,236 @@ +/* + * Touchscreen driver for Marvell 88PM860x + * + * Copyright (C) 2009 Marvell International Ltd. + * Haojian Zhuang <haojian.zhuang@marvell.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/i2c.h> +#include <linux/input.h> +#include <linux/mfd/88pm860x.h> + +#define MEAS_LEN (8) +#define ACCURATE_BIT (12) + +/* touch register */ +#define MEAS_EN3 (0x52) + +#define MEAS_TSIX_1 (0x8D) +#define MEAS_TSIX_2 (0x8E) +#define MEAS_TSIY_1 (0x8F) +#define MEAS_TSIY_2 (0x90) +#define MEAS_TSIZ1_1 (0x91) +#define MEAS_TSIZ1_2 (0x92) +#define MEAS_TSIZ2_1 (0x93) +#define MEAS_TSIZ2_2 (0x94) + +/* bit definitions of touch */ +#define MEAS_PD_EN (1 << 3) +#define MEAS_TSIX_EN (1 << 4) +#define MEAS_TSIY_EN (1 << 5) +#define MEAS_TSIZ1_EN (1 << 6) +#define MEAS_TSIZ2_EN (1 << 7) + +struct pm860x_touch { + struct input_dev *idev; + struct i2c_client *i2c; + struct pm860x_chip *chip; + int irq; + int res_x; /* resistor of Xplate */ +}; + +static irqreturn_t pm860x_touch_handler(int irq, void *data) +{ + struct pm860x_touch *touch = data; + struct pm860x_chip *chip = touch->chip; + unsigned char buf[MEAS_LEN]; + int x, y, pen_down; + int z1, z2, rt = 0; + int ret; + + ret = pm860x_bulk_read(touch->i2c, MEAS_TSIX_1, MEAS_LEN, buf); + if (ret < 0) + goto out; + + pen_down = buf[1] & (1 << 6); + x = ((buf[0] & 0xFF) << 4) | (buf[1] & 0x0F); + y = ((buf[2] & 0xFF) << 4) | (buf[3] & 0x0F); + z1 = ((buf[4] & 0xFF) << 4) | (buf[5] & 0x0F); + z2 = ((buf[6] & 0xFF) << 4) | (buf[7] & 0x0F); + + if (pen_down) { + if ((x != 0) && (z1 != 0) && (touch->res_x != 0)) { + rt = z2 / z1 - 1; + rt = (rt * touch->res_x * x) >> ACCURATE_BIT; + dev_dbg(chip->dev, "z1:%d, z2:%d, rt:%d\n", + z1, z2, rt); + } + input_report_abs(touch->idev, ABS_X, x); + input_report_abs(touch->idev, ABS_Y, y); + input_report_abs(touch->idev, ABS_PRESSURE, rt); + input_report_key(touch->idev, BTN_TOUCH, 1); + dev_dbg(chip->dev, "pen down at [%d, %d].\n", x, y); + } else { + input_report_abs(touch->idev, ABS_PRESSURE, 0); + input_report_key(touch->idev, BTN_TOUCH, 0); + dev_dbg(chip->dev, "pen release\n"); + } + input_sync(touch->idev); + +out: + return IRQ_HANDLED; +} + +static int pm860x_touch_open(struct input_dev *dev) +{ + struct pm860x_touch *touch = input_get_drvdata(dev); + int data, ret; + + data = MEAS_PD_EN | MEAS_TSIX_EN | MEAS_TSIY_EN + | MEAS_TSIZ1_EN | MEAS_TSIZ2_EN; + ret = pm860x_set_bits(touch->i2c, MEAS_EN3, data, data); + if (ret < 0) + goto out; + return 0; +out: + return ret; +} + +static void pm860x_touch_close(struct input_dev *dev) +{ + struct pm860x_touch *touch = input_get_drvdata(dev); + int data; + + data = MEAS_PD_EN | MEAS_TSIX_EN | MEAS_TSIY_EN + | MEAS_TSIZ1_EN | MEAS_TSIZ2_EN; + pm860x_set_bits(touch->i2c, MEAS_EN3, data, 0); +} + +static int __devinit pm860x_touch_probe(struct platform_device *pdev) +{ + struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); + struct pm860x_platform_data *pm860x_pdata = \ + pdev->dev.parent->platform_data; + struct pm860x_touch_pdata *pdata = NULL; + struct pm860x_touch *touch; + int irq, ret; + + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + dev_err(&pdev->dev, "No IRQ resource!\n"); + return -EINVAL; + } + + if (!pm860x_pdata) { + dev_err(&pdev->dev, "platform data is missing\n"); + return -EINVAL; + } + + pdata = pm860x_pdata->touch; + if (!pdata) { + dev_err(&pdev->dev, "touchscreen data is missing\n"); + return -EINVAL; + } + + touch = kzalloc(sizeof(struct pm860x_touch), GFP_KERNEL); + if (touch == NULL) + return -ENOMEM; + dev_set_drvdata(&pdev->dev, touch); + + touch->idev = input_allocate_device(); + if (touch->idev == NULL) { + dev_err(&pdev->dev, "Failed to allocate input device!\n"); + ret = -ENOMEM; + goto out; + } + + touch->idev->name = "88pm860x-touch"; + touch->idev->phys = "88pm860x/input0"; + touch->idev->id.bustype = BUS_I2C; + touch->idev->dev.parent = &pdev->dev; + touch->idev->open = pm860x_touch_open; + touch->idev->close = pm860x_touch_close; + touch->chip = chip; + touch->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion; + touch->irq = irq + chip->irq_base; + touch->res_x = pdata->res_x; + input_set_drvdata(touch->idev, touch); + + ret = request_threaded_irq(touch->irq, NULL, pm860x_touch_handler, + IRQF_ONESHOT, "touch", touch); + if (ret < 0) + goto out_irq; + + __set_bit(EV_ABS, touch->idev->evbit); + __set_bit(ABS_X, touch->idev->absbit); + __set_bit(ABS_Y, touch->idev->absbit); + __set_bit(ABS_PRESSURE, touch->idev->absbit); + __set_bit(EV_SYN, touch->idev->evbit); + __set_bit(EV_KEY, touch->idev->evbit); + __set_bit(BTN_TOUCH, touch->idev->keybit); + + input_set_abs_params(touch->idev, ABS_X, 0, 1 << ACCURATE_BIT, 0, 0); + input_set_abs_params(touch->idev, ABS_Y, 0, 1 << ACCURATE_BIT, 0, 0); + input_set_abs_params(touch->idev, ABS_PRESSURE, 0, 1 << ACCURATE_BIT, + 0, 0); + + ret = input_register_device(touch->idev); + if (ret < 0) { + dev_err(chip->dev, "Failed to register touch!\n"); + goto out_rg; + } + + platform_set_drvdata(pdev, touch); + return 0; +out_rg: + free_irq(touch->irq, touch); +out_irq: + input_free_device(touch->idev); +out: + kfree(touch); + return ret; +} + +static int __devexit pm860x_touch_remove(struct platform_device *pdev) +{ + struct pm860x_touch *touch = platform_get_drvdata(pdev); + + input_unregister_device(touch->idev); + free_irq(touch->irq, touch); + platform_set_drvdata(pdev, NULL); + kfree(touch); + return 0; +} + +static struct platform_driver pm860x_touch_driver = { + .driver = { + .name = "88pm860x-touch", + .owner = THIS_MODULE, + }, + .probe = pm860x_touch_probe, + .remove = __devexit_p(pm860x_touch_remove), +}; + +static int __init pm860x_touch_init(void) +{ + return platform_driver_register(&pm860x_touch_driver); +} +module_init(pm860x_touch_init); + +static void __exit pm860x_touch_exit(void) +{ + platform_driver_unregister(&pm860x_touch_driver); +} +module_exit(pm860x_touch_exit); + +MODULE_DESCRIPTION("Touchscreen driver for Marvell Semiconductor 88PM860x"); +MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:88pm860x-touch"); + diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 6457e06..7208654 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -11,6 +11,18 @@ menuconfig INPUT_TOUCHSCREEN if INPUT_TOUCHSCREEN +config TOUCHSCREEN_88PM860X + tristate "Marvell 88PM860x touchscreen" + depends on MFD_88PM860X + help + Say Y here if you have a 88PM860x PMIC and want to enable + support for the built-in touchscreen. + + If unsure, say N. + + To compile this driver as a module, choose M here: the + module will be called 88pm860x-ts. + config TOUCHSCREEN_ADS7846 tristate "ADS7846/TSC2046 and ADS7843 based touchscreens" depends on SPI_MASTER diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index d61a3b4..7fef7d5 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -6,6 +6,7 @@ wm97xx-ts-y := wm97xx-core.o +obj-$(CONFIG_TOUCHSCREEN_88PM860X) += 88pm860x-ts.o obj-$(CONFIG_TOUCHSCREEN_AD7877) += ad7877.o obj-$(CONFIG_TOUCHSCREEN_AD7879) += ad7879.o obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index 8a0e1ec..e0b6431 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -17,6 +17,13 @@ config LEDS_CLASS comment "LED drivers" +config LEDS_88PM860X + tristate "LED Support for Marvell 88PM860x PMIC" + depends on LEDS_CLASS && MFD_88PM860X + help + This option enables support for on-chip LED drivers found on Marvell + Semiconductor 88PM8606 PMIC. + config LEDS_ATMEL_PWM tristate "LED Support using Atmel PWM outputs" depends on LEDS_CLASS && ATMEL_PWM diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index 9e63869..d76fb32 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile @@ -5,6 +5,7 @@ obj-$(CONFIG_LEDS_CLASS) += led-class.o obj-$(CONFIG_LEDS_TRIGGERS) += led-triggers.o # LED Platform Drivers +obj-$(CONFIG_LEDS_88PM860X) += leds-88pm860x.o obj-$(CONFIG_LEDS_ATMEL_PWM) += leds-atmel-pwm.o obj-$(CONFIG_LEDS_BD2802) += leds-bd2802.o obj-$(CONFIG_LEDS_LOCOMO) += leds-locomo.o diff --git a/drivers/leds/leds-88pm860x.c b/drivers/leds/leds-88pm860x.c new file mode 100644 index 0000000..d196073 --- /dev/null +++ b/drivers/leds/leds-88pm860x.c @@ -0,0 +1,325 @@ +/* + * LED driver for Marvell 88PM860x + * + * Copyright (C) 2009 Marvell International Ltd. + * Haojian Zhuang <haojian.zhuang@marvell.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/i2c.h> +#include <linux/leds.h> +#include <linux/workqueue.h> +#include <linux/mfd/88pm860x.h> + +#define LED_PWM_SHIFT (3) +#define LED_PWM_MASK (0x1F) +#define LED_CURRENT_MASK (0x07 << 5) + +#define LED_BLINK_ON_MASK (0x07) +#define LED_BLINK_PERIOD_MASK (0x0F << 3) +#define LED_BLINK_MASK (0x7F) + +#define LED_BLINK_ON(x) ((x & 0x7) * 66 + 66) +#define LED_BLINK_PERIOD(x) ((x & 0xF) * 530 + 930) +#define LED_BLINK_ON_MIN LED_BLINK_ON(0) +#define LED_BLINK_ON_MAX LED_BLINK_ON(0x7) +#define LED_BLINK_PERIOD_MIN LED_BLINK_PERIOD(0) +#define LED_BLINK_PERIOD_MAX LED_BLINK_PERIOD(0xE) +#define LED_TO_ON(x) ((x - 66) / 66) +#define LED_TO_PERIOD(x) ((x - 930) / 530) + +#define LED1_BLINK_EN (1 << 1) +#define LED2_BLINK_EN (1 << 2) + +enum { + SET_BRIGHTNESS, + SET_BLINK, +}; + +struct pm860x_led { + struct led_classdev cdev; + struct i2c_client *i2c; + struct work_struct work; + struct pm860x_chip *chip; + struct mutex lock; + char name[MFD_NAME_SIZE]; + + int port; + int iset; + int command; + int offset; + unsigned char brightness; + unsigned char current_brightness; + + int blink_data; + int blink_time; + int blink_on; + int blink_off; +}; + +/* return offset of color register */ +static inline int __led_off(int port) +{ + int ret = -EINVAL; + + switch (port) { + case PM8606_LED1_RED: + case PM8606_LED1_GREEN: + case PM8606_LED1_BLUE: + ret = port - PM8606_LED1_RED + PM8606_RGB1B; + break; + case PM8606_LED2_RED: + case PM8606_LED2_GREEN: + case PM8606_LED2_BLUE: + ret = port - PM8606_LED2_RED + PM8606_RGB2B; + break; + } + return ret; +} + +/* return offset of blink register */ +static inline int __blink_off(int port) +{ + int ret = -EINVAL; + + switch (port) { + case PM8606_LED1_RED: + case PM8606_LED1_GREEN: + case PM8606_LED1_BLUE: + ret = PM8606_RGB1A; + case PM8606_LED2_RED: + case PM8606_LED2_GREEN: + case PM8606_LED2_BLUE: + ret = PM8606_RGB2A; + } + return ret; +} + +static inline int __blink_ctl_mask(int port) +{ + int ret = -EINVAL; + + switch (port) { + case PM8606_LED1_RED: + case PM8606_LED1_GREEN: + case PM8606_LED1_BLUE: + ret = LED1_BLINK_EN; + break; + case PM8606_LED2_RED: + case PM8606_LED2_GREEN: + case PM8606_LED2_BLUE: + ret = LED2_BLINK_EN; + break; + } + return ret; +} + +static int __led_set(struct pm860x_led *led, int command) +{ + struct pm860x_chip *chip = led->chip; + int mask, ret; + + mutex_lock(&led->lock); + switch (command) { + case SET_BRIGHTNESS: + if ((led->current_brightness == 0) && led->brightness) { + if (led->iset) { + ret = pm860x_set_bits(led->i2c, led->offset, + LED_CURRENT_MASK, led->iset); + if (ret < 0) + goto out; + } + } else if (led->brightness == 0) { + ret = pm860x_set_bits(led->i2c, led->offset, + LED_CURRENT_MASK, 0); + if (ret < 0) + goto out; + } + ret = pm860x_set_bits(led->i2c, led->offset, LED_PWM_MASK, + led->brightness); + if (ret < 0) + goto out; + led->current_brightness = led->brightness; + dev_dbg(chip->dev, "Update LED. (reg:%d, brightness:%d)\n", + led->offset, led->brightness); + break; + case SET_BLINK: + ret = pm860x_set_bits(led->i2c, led->offset, + LED_BLINK_MASK, led->blink_data); + if (ret < 0) + goto out; + + mask = __blink_ctl_mask(led->port); + ret = pm860x_set_bits(led->i2c, PM8606_WLED3B, mask, mask); + if (ret < 0) + goto out; + dev_dbg(chip->dev, "LED blink delay on:%dms, delay off:%dms\n", + led->blink_on, led->blink_off); + break; + } +out: + mutex_unlock(&led->lock); + return 0; +} + +static void pm860x_led_work(struct work_struct *work) +{ + struct pm860x_led *led; + + led = container_of(work, struct pm860x_led, work); + __led_set(led, led->command); +} + +static void pm860x_led_set(struct led_classdev *cdev, + enum led_brightness value) +{ + struct pm860x_led *data = container_of(cdev, struct pm860x_led, cdev); + + data->offset = __led_off(data->port); + data->brightness = value >> 3; + data->command = SET_BRIGHTNESS; + schedule_work(&data->work); +} + +static int pm860x_led_blink(struct led_classdev *cdev, + unsigned long *delay_on, + unsigned long *delay_off) +{ + struct pm860x_led *data = container_of(cdev, struct pm860x_led, cdev); + int period, on; + + on = *delay_on; + if ((on < LED_BLINK_ON_MIN) || (on > LED_BLINK_ON_MAX)) + return -EINVAL; + + on = LED_TO_ON(on); + on = LED_BLINK_ON(on); + + period = on + *delay_off; + if ((period < LED_BLINK_PERIOD_MIN) || (period > LED_BLINK_PERIOD_MAX)) + return -EINVAL; + period = LED_TO_PERIOD(period); + period = LED_BLINK_PERIOD(period); + + data->offset = __blink_off(data->port); + data->blink_on = on; + data->blink_off = period - data->blink_on; + data->blink_data = (period << 3) | data->blink_on; + data->command = SET_BLINK; + schedule_work(&data->work); + + return 0; +} + +static int __check_device(struct pm860x_led_pdata *pdata, char *name) +{ + struct pm860x_led_pdata *p = pdata; + int ret = -EINVAL; + + while (p && p->id) { + if ((p->id != PM8606_ID_LED) || (p->flags < 0)) + break; + + if (!strncmp(name, pm860x_led_name[p->flags], + MFD_NAME_SIZE)) { + ret = (int)p->flags; + break; + } + p++; + } + return ret; +} + +static int pm860x_led_probe(struct platform_device *pdev) +{ + struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); + struct pm860x_platform_data *pm860x_pdata; + struct pm860x_led_pdata *pdata; + struct pm860x_led *data; + struct resource *res; + int ret; + + res = platform_get_resource(pdev, IORESOURCE_IO, 0); + if (res == NULL) { + dev_err(&pdev->dev, "No I/O resource!\n"); + return -EINVAL; + } + + if (pdev->dev.parent->platform_data) { + pm860x_pdata = pdev->dev.parent->platform_data; + pdata = pm860x_pdata->led; + } else + pdata = NULL; + + data = kzalloc(sizeof(struct pm860x_led), GFP_KERNEL); + if (data == NULL) + return -ENOMEM; + strncpy(data->name, res->name, MFD_NAME_SIZE); + dev_set_drvdata(&pdev->dev, data); + data->chip = chip; + data->i2c = (chip->id == CHIP_PM8606) ? chip->client : chip->companion; + data->iset = pdata->iset; + data->port = __check_device(pdata, data->name); + if (data->port < 0) + return -EINVAL; + + data->current_brightness = 0; + data->cdev.name = data->name; + data->cdev.brightness_set = pm860x_led_set; + data->cdev.blink_set = pm860x_led_blink; + mutex_init(&data->lock); + INIT_WORK(&data->work, pm860x_led_work); + + ret = led_classdev_register(chip->dev, &data->cdev); + if (ret < 0) { + dev_err(&pdev->dev, "Failed to register LED: %d\n", ret); + goto out; + } + return 0; +out: + kfree(data); + return ret; +} + +static int pm860x_led_remove(struct platform_device *pdev) +{ + struct pm860x_led *data = platform_get_drvdata(pdev); + + led_classdev_unregister(&data->cdev); + kfree(data); + + return 0; +} + +static struct platform_driver pm860x_led_driver = { + .driver = { + .name = "88pm860x-led", + .owner = THIS_MODULE, + }, + .probe = pm860x_led_probe, + .remove = pm860x_led_remove, +}; + +static int __devinit pm860x_led_init(void) +{ + return platform_driver_register(&pm860x_led_driver); +} +module_init(pm860x_led_init); + +static void __devexit pm860x_led_exit(void) +{ + platform_driver_unregister(&pm860x_led_driver); +} +module_exit(pm860x_led_exit); + +MODULE_DESCRIPTION("LED driver for Marvell PM860x"); +MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:88pm860x-led"); diff --git a/drivers/mfd/88pm8607.c b/drivers/mfd/88pm8607.c deleted file mode 100644 index 7e3f659..0000000 --- a/drivers/mfd/88pm8607.c +++ /dev/null @@ -1,302 +0,0 @@ -/* - * Base driver for Marvell 88PM8607 - * - * Copyright (C) 2009 Marvell International Ltd. - * Haojian Zhuang <haojian.zhuang@marvell.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/interrupt.h> -#include <linux/platform_device.h> -#include <linux/i2c.h> -#include <linux/mfd/core.h> -#include <linux/mfd/88pm8607.h> - - -#define PM8607_REG_RESOURCE(_start, _end) \ -{ \ - .start = PM8607_##_start, \ - .end = PM8607_##_end, \ - .flags = IORESOURCE_IO, \ -} - -static struct resource pm8607_regulator_resources[] = { - PM8607_REG_RESOURCE(BUCK1, BUCK1), - PM8607_REG_RESOURCE(BUCK2, BUCK2), - PM8607_REG_RESOURCE(BUCK3, BUCK3), - PM8607_REG_RESOURCE(LDO1, LDO1), - PM8607_REG_RESOURCE(LDO2, LDO2), - PM8607_REG_RESOURCE(LDO3, LDO3), - PM8607_REG_RESOURCE(LDO4, LDO4), - PM8607_REG_RESOURCE(LDO5, LDO5), - PM8607_REG_RESOURCE(LDO6, LDO6), - PM8607_REG_RESOURCE(LDO7, LDO7), - PM8607_REG_RESOURCE(LDO8, LDO8), - PM8607_REG_RESOURCE(LDO9, LDO9), - PM8607_REG_RESOURCE(LDO10, LDO10), - PM8607_REG_RESOURCE(LDO12, LDO12), - PM8607_REG_RESOURCE(LDO14, LDO14), -}; - -#define PM8607_REG_DEVS(_name, _id) \ -{ \ - .name = "88pm8607-" #_name, \ - .num_resources = 1, \ - .resources = &pm8607_regulator_resources[PM8607_ID_##_id], \ -} - -static struct mfd_cell pm8607_devs[] = { - PM8607_REG_DEVS(buck1, BUCK1), - PM8607_REG_DEVS(buck2, BUCK2), - PM8607_REG_DEVS(buck3, BUCK3), - PM8607_REG_DEVS(ldo1, LDO1), - PM8607_REG_DEVS(ldo2, LDO2), - PM8607_REG_DEVS(ldo3, LDO3), - PM8607_REG_DEVS(ldo4, LDO4), - PM8607_REG_DEVS(ldo5, LDO5), - PM8607_REG_DEVS(ldo6, LDO6), - PM8607_REG_DEVS(ldo7, LDO7), - PM8607_REG_DEVS(ldo8, LDO8), - PM8607_REG_DEVS(ldo9, LDO9), - PM8607_REG_DEVS(ldo10, LDO10), - PM8607_REG_DEVS(ldo12, LDO12), - PM8607_REG_DEVS(ldo14, LDO14), -}; - -static inline int pm8607_read_device(struct pm8607_chip *chip, - int reg, int bytes, void *dest) -{ - struct i2c_client *i2c = chip->client; - unsigned char data; - int ret; - - data = (unsigned char)reg; - ret = i2c_master_send(i2c, &data, 1); - if (ret < 0) - return ret; - - ret = i2c_master_recv(i2c, dest, bytes); - if (ret < 0) - return ret; - return 0; -} - -static inline int pm8607_write_device(struct pm8607_chip *chip, - int reg, int bytes, void *src) -{ - struct i2c_client *i2c = chip->client; - unsigned char buf[bytes + 1]; - int ret; - - buf[0] = (unsigned char)reg; - memcpy(&buf[1], src, bytes); - - ret = i2c_master_send(i2c, buf, bytes + 1); - if (ret < 0) - return ret; - return 0; -} - -int pm8607_reg_read(struct pm8607_chip *chip, int reg) -{ - unsigned char data; - int ret; - - mutex_lock(&chip->io_lock); - ret = chip->read(chip, reg, 1, &data); - mutex_unlock(&chip->io_lock); - - if (ret < 0) - return ret; - else - return (int)data; -} -EXPORT_SYMBOL(pm8607_reg_read); - -int pm8607_reg_write(struct pm8607_chip *chip, int reg, - unsigned char data) -{ - int ret; - - mutex_lock(&chip->io_lock); - ret = chip->write(chip, reg, 1, &data); - mutex_unlock(&chip->io_lock); - - return ret; -} -EXPORT_SYMBOL(pm8607_reg_write); - -int pm8607_bulk_read(struct pm8607_chip *chip, int reg, - int count, unsigned char *buf) -{ - int ret; - - mutex_lock(&chip->io_lock); - ret = chip->read(chip, reg, count, buf); - mutex_unlock(&chip->io_lock); - - return ret; -} -EXPORT_SYMBOL(pm8607_bulk_read); - -int pm8607_bulk_write(struct pm8607_chip *chip, int reg, - int count, unsigned char *buf) -{ - int ret; - - mutex_lock(&chip->io_lock); - ret = chip->write(chip, reg, count, buf); - mutex_unlock(&chip->io_lock); - - return ret; -} -EXPORT_SYMBOL(pm8607_bulk_write); - -int pm8607_set_bits(struct pm8607_chip *chip, int reg, - unsigned char mask, unsigned char data) -{ - unsigned char value; - int ret; - - mutex_lock(&chip->io_lock); - ret = chip->read(chip, reg, 1, &value); - if (ret < 0) - goto out; - value &= ~mask; - value |= data; - ret = chip->write(chip, reg, 1, &value); -out: - mutex_unlock(&chip->io_lock); - return ret; -} -EXPORT_SYMBOL(pm8607_set_bits); - - -static const struct i2c_device_id pm8607_id_table[] = { - { "88PM8607", 0 }, - {} -}; -MODULE_DEVICE_TABLE(i2c, pm8607_id_table); - - -static int __devinit pm8607_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct pm8607_platform_data *pdata = client->dev.platform_data; - struct pm8607_chip *chip; - int i, count; - int ret; - - chip = kzalloc(sizeof(struct pm8607_chip), GFP_KERNEL); - if (chip == NULL) - return -ENOMEM; - - chip->client = client; - chip->dev = &client->dev; - chip->read = pm8607_read_device; - chip->write = pm8607_write_device; - i2c_set_clientdata(client, chip); - - mutex_init(&chip->io_lock); - dev_set_drvdata(chip->dev, chip); - - ret = pm8607_reg_read(chip, PM8607_CHIP_ID); - if (ret < 0) { - dev_err(chip->dev, "Failed to read CHIP ID: %d\n", ret); - goto out; - } - if ((ret & CHIP_ID_MASK) == CHIP_ID) - dev_info(chip->dev, "Marvell 88PM8607 (ID: %02x) detected\n", - ret); - else { - dev_err(chip->dev, "Failed to detect Marvell 88PM8607. " - "Chip ID: %02x\n", ret); - goto out; - } - chip->chip_id = ret; - - ret = pm8607_reg_read(chip, PM8607_BUCK3); - if (ret < 0) { - dev_err(chip->dev, "Failed to read BUCK3 register: %d\n", ret); - goto out; - } - if (ret & PM8607_BUCK3_DOUBLE) - chip->buck3_double = 1; - - ret = pm8607_reg_read(chip, PM8607_MISC1); - if (ret < 0) { - dev_err(chip->dev, "Failed to read MISC1 register: %d\n", ret); - goto out; - } - if (pdata->i2c_port == PI2C_PORT) - ret |= PM8607_MISC1_PI2C; - else - ret &= ~PM8607_MISC1_PI2C; - ret = pm8607_reg_write(chip, PM8607_MISC1, ret); - if (ret < 0) { - dev_err(chip->dev, "Failed to write MISC1 register: %d\n", ret); - goto out; - } - - - count = ARRAY_SIZE(pm8607_devs); - for (i = 0; i < count; i++) { - ret = mfd_add_devices(chip->dev, i, &pm8607_devs[i], - 1, NULL, 0); - if (ret != 0) { - dev_err(chip->dev, "Failed to add subdevs\n"); - goto out; - } - } - - return 0; - -out: - i2c_set_clientdata(client, NULL); - kfree(chip); - return ret; -} - -static int __devexit pm8607_remove(struct i2c_client *client) -{ - struct pm8607_chip *chip = i2c_get_clientdata(client); - - mfd_remove_devices(chip->dev); - kfree(chip); - return 0; -} - -static struct i2c_driver pm8607_driver = { - .driver = { - .name = "88PM8607", - .owner = THIS_MODULE, - }, - .probe = pm8607_probe, - .remove = __devexit_p(pm8607_remove), - .id_table = pm8607_id_table, -}; - -static int __init pm8607_init(void) -{ - int ret; - ret = i2c_add_driver(&pm8607_driver); - if (ret != 0) - pr_err("Failed to register 88PM8607 I2C driver: %d\n", ret); - return ret; -} -subsys_initcall(pm8607_init); - -static void __exit pm8607_exit(void) -{ - i2c_del_driver(&pm8607_driver); -} -module_exit(pm8607_exit); - -MODULE_DESCRIPTION("PMIC Driver for Marvell 88PM8607"); -MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>"); -MODULE_LICENSE("GPL"); diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c new file mode 100644 index 0000000..6a14d2b --- /dev/null +++ b/drivers/mfd/88pm860x-core.c @@ -0,0 +1,740 @@ +/* + * Base driver for Marvell 88PM8607 + * + * Copyright (C) 2009 Marvell International Ltd. + * Haojian Zhuang <haojian.zhuang@marvell.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/i2c.h> +#include <linux/irq.h> +#include <linux/interrupt.h> +#include <linux/platform_device.h> +#include <linux/mfd/core.h> +#include <linux/mfd/88pm860x.h> + +#define INT_STATUS_NUM 3 + +char pm860x_backlight_name[][MFD_NAME_SIZE] = { + "backlight-0", + "backlight-1", + "backlight-2", +}; +EXPORT_SYMBOL(pm860x_backlight_name); + +char pm860x_led_name[][MFD_NAME_SIZE] = { + "led0-red", + "led0-green", + "led0-blue", + "led1-red", + "led1-green", + "led1-blue", +}; +EXPORT_SYMBOL(pm860x_led_name); + +#define PM8606_BACKLIGHT_RESOURCE(_i, _x) \ +{ \ + .name = pm860x_backlight_name[_i], \ + .start = PM8606_##_x, \ + .end = PM8606_##_x, \ + .flags = IORESOURCE_IO, \ +} + +static struct resource backlight_resources[] = { + PM8606_BACKLIGHT_RESOURCE(PM8606_BACKLIGHT1, WLED1A), + PM8606_BACKLIGHT_RESOURCE(PM8606_BACKLIGHT2, WLED2A), + PM8606_BACKLIGHT_RESOURCE(PM8606_BACKLIGHT3, WLED3A), +}; + +#define PM8606_BACKLIGHT_DEVS(_i) \ +{ \ + .name = "88pm860x-backlight", \ + .num_resources = 1, \ + .resources = &backlight_resources[_i], \ + .id = _i, \ +} + +static struct mfd_cell backlight_devs[] = { + PM8606_BACKLIGHT_DEVS(PM8606_BACKLIGHT1), + PM8606_BACKLIGHT_DEVS(PM8606_BACKLIGHT2), + PM8606_BACKLIGHT_DEVS(PM8606_BACKLIGHT3), +}; + +#define PM8606_LED_RESOURCE(_i, _x) \ +{ \ + .name = pm860x_led_name[_i], \ + .start = PM8606_##_x, \ + .end = PM8606_##_x, \ + .flags = IORESOURCE_IO, \ +} + +static struct resource led_resources[] = { + PM8606_LED_RESOURCE(PM8606_LED1_RED, RGB2B), + PM8606_LED_RESOURCE(PM8606_LED1_GREEN, RGB2C), + PM8606_LED_RESOURCE(PM8606_LED1_BLUE, RGB2D), + PM8606_LED_RESOURCE(PM8606_LED2_RED, RGB1B), + PM8606_LED_RESOURCE(PM8606_LED2_GREEN, RGB1C), + PM8606_LED_RESOURCE(PM8606_LED2_BLUE, RGB1D), +}; + +#define PM8606_LED_DEVS(_i) \ +{ \ + .name = "88pm860x-led", \ + .num_resources = 1, \ + .resources = &led_resources[_i], \ + .id = _i, \ +} + +static struct mfd_cell led_devs[] = { + PM8606_LED_DEVS(PM8606_LED1_RED), + PM8606_LED_DEVS(PM8606_LED1_GREEN), + PM8606_LED_DEVS(PM8606_LED1_BLUE), + PM8606_LED_DEVS(PM8606_LED2_RED), + PM8606_LED_DEVS(PM8606_LED2_GREEN), + PM8606_LED_DEVS(PM8606_LED2_BLUE), +}; + +static struct resource touch_resources[] = { + { + .start = PM8607_IRQ_PEN, + .end = PM8607_IRQ_PEN, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct mfd_cell touch_devs[] = { + { + .name = "88pm860x-touch", + .num_resources = 1, + .resources = &touch_resources[0], + }, +}; + +#define PM8607_REG_RESOURCE(_start, _end) \ +{ \ + .start = PM8607_##_start, \ + .end = PM8607_##_end, \ + .flags = IORESOURCE_IO, \ +} + +static struct resource power_supply_resources[] = { + { + .name = "88pm860x-power", + .start = PM8607_IRQ_CHG, + .end = PM8607_IRQ_CHG, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct mfd_cell power_devs[] = { + { + .name = "88pm860x-power", + .num_resources = 1, + .resources = &power_supply_resources[0], + .id = -1, + }, +}; + +static struct resource onkey_resources[] = { + { + .name = "88pm860x-onkey", + .start = PM8607_IRQ_ONKEY, + .end = PM8607_IRQ_ONKEY, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct mfd_cell onkey_devs[] = { + { + .name = "88pm860x-onkey", + .num_resources = 1, + .resources = &onkey_resources[0], + .id = -1, + }, +}; + +static struct resource regulator_resources[] = { + PM8607_REG_RESOURCE(BUCK1, BUCK1), + PM8607_REG_RESOURCE(BUCK2, BUCK2), + PM8607_REG_RESOURCE(BUCK3, BUCK3), + PM8607_REG_RESOURCE(LDO1, LDO1), + PM8607_REG_RESOURCE(LDO2, LDO2), + PM8607_REG_RESOURCE(LDO3, LDO3), + PM8607_REG_RESOURCE(LDO4, LDO4), + PM8607_REG_RESOURCE(LDO5, LDO5), + PM8607_REG_RESOURCE(LDO6, LDO6), + PM8607_REG_RESOURCE(LDO7, LDO7), + PM8607_REG_RESOURCE(LDO8, LDO8), + PM8607_REG_RESOURCE(LDO9, LDO9), + PM8607_REG_RESOURCE(LDO10, LDO10), + PM8607_REG_RESOURCE(LDO12, LDO12), + PM8607_REG_RESOURCE(LDO14, LDO14), +}; + +#define PM8607_REG_DEVS(_name, _id) \ +{ \ + .name = "88pm8607-" #_name, \ + .num_resources = 1, \ + .resources = ®ulator_resources[PM8607_ID_##_id], \ + .id = PM8607_ID_##_id, \ +} + +static struct mfd_cell regulator_devs[] = { + PM8607_REG_DEVS(buck1, BUCK1), + PM8607_REG_DEVS(buck2, BUCK2), + PM8607_REG_DEVS(buck3, BUCK3), + PM8607_REG_DEVS(ldo1, LDO1), + PM8607_REG_DEVS(ldo2, LDO2), + PM8607_REG_DEVS(ldo3, LDO3), + PM8607_REG_DEVS(ldo4, LDO4), + PM8607_REG_DEVS(ldo5, LDO5), + PM8607_REG_DEVS(ldo6, LDO6), + PM8607_REG_DEVS(ldo7, LDO7), + PM8607_REG_DEVS(ldo8, LDO8), + PM8607_REG_DEVS(ldo9, LDO9), + PM8607_REG_DEVS(ldo10, LDO10), + PM8607_REG_DEVS(ldo12, LDO12), + PM8607_REG_DEVS(ldo14, LDO14), +}; + +struct pm860x_irq_data { + int reg; + int mask_reg; + int enable; /* enable or not */ + int offs; /* bit offset in mask register */ +}; + +static struct pm860x_irq_data pm860x_irqs[] = { + [PM8607_IRQ_ONKEY] = { + .reg = PM8607_INT_STATUS1, + .mask_reg = PM8607_INT_MASK_1, + .offs = 1 << 0, + }, + [PM8607_IRQ_EXTON] = { + .reg = PM8607_INT_STATUS1, + .mask_reg = PM8607_INT_MASK_1, + .offs = 1 << 1, + }, + [PM8607_IRQ_CHG] = { + .reg = PM8607_INT_STATUS1, + .mask_reg = PM8607_INT_MASK_1, + .offs = 1 << 2, + }, + [PM8607_IRQ_BAT] = { + .reg = PM8607_INT_STATUS1, + .mask_reg = PM8607_INT_MASK_1, + .offs = 1 << 3, + }, + [PM8607_IRQ_RTC] = { + .reg = PM8607_INT_STATUS1, + .mask_reg = PM8607_INT_MASK_1, + .offs = 1 << 4, + }, + [PM8607_IRQ_CC] = { + .reg = PM8607_INT_STATUS1, + .mask_reg = PM8607_INT_MASK_1, + .offs = 1 << 5, + }, + [PM8607_IRQ_VBAT] = { + .reg = PM8607_INT_STATUS2, + .mask_reg = PM8607_INT_MASK_2, + .offs = 1 << 0, + }, + [PM8607_IRQ_VCHG] = { + .reg = PM8607_INT_STATUS2, + .mask_reg = PM8607_INT_MASK_2, + .offs = 1 << 1, + }, + [PM8607_IRQ_VSYS] = { + .reg = PM8607_INT_STATUS2, + .mask_reg = PM8607_INT_MASK_2, + .offs = 1 << 2, + }, + [PM8607_IRQ_TINT] = { + .reg = PM8607_INT_STATUS2, + .mask_reg = PM8607_INT_MASK_2, + .offs = 1 << 3, + }, + [PM8607_IRQ_GPADC0] = { + .reg = PM8607_INT_STATUS2, + .mask_reg = PM8607_INT_MASK_2, + .offs = 1 << 4, + }, + [PM8607_IRQ_GPADC1] = { + .reg = PM8607_INT_STATUS2, + .mask_reg = PM8607_INT_MASK_2, + .offs = 1 << 5, + }, + [PM8607_IRQ_GPADC2] = { + .reg = PM8607_INT_STATUS2, + .mask_reg = PM8607_INT_MASK_2, + .offs = 1 << 6, + }, + [PM8607_IRQ_GPADC3] = { + .reg = PM8607_INT_STATUS2, + .mask_reg = PM8607_INT_MASK_2, + .offs = 1 << 7, + }, + [PM8607_IRQ_AUDIO_SHORT] = { + .reg = PM8607_INT_STATUS3, + .mask_reg = PM8607_INT_MASK_3, + .offs = 1 << 0, + }, + [PM8607_IRQ_PEN] = { + .reg = PM8607_INT_STATUS3, + .mask_reg = PM8607_INT_MASK_3, + .offs = 1 << 1, + }, + [PM8607_IRQ_HEADSET] = { + .reg = PM8607_INT_STATUS3, + .mask_reg = PM8607_INT_MASK_3, + .offs = 1 << 2, + }, + [PM8607_IRQ_HOOK] = { + .reg = PM8607_INT_STATUS3, + .mask_reg = PM8607_INT_MASK_3, + .offs = 1 << 3, + }, + [PM8607_IRQ_MICIN] = { + .reg = PM8607_INT_STATUS3, + .mask_reg = PM8607_INT_MASK_3, + .offs = 1 << 4, + }, + [PM8607_IRQ_CHG_FAIL] = { + .reg = PM8607_INT_STATUS3, + .mask_reg = PM8607_INT_MASK_3, + .offs = 1 << 5, + }, + [PM8607_IRQ_CHG_DONE] = { + .reg = PM8607_INT_STATUS3, + .mask_reg = PM8607_INT_MASK_3, + .offs = 1 << 6, + }, + [PM8607_IRQ_CHG_FAULT] = { + .reg = PM8607_INT_STATUS3, + .mask_reg = PM8607_INT_MASK_3, + .offs = 1 << 7, + }, +}; + +static inline struct pm860x_irq_data *irq_to_pm860x(struct pm860x_chip *chip, + int irq) +{ + return &pm860x_irqs[irq - chip->irq_base]; +} + +static irqreturn_t pm860x_irq(int irq, void *data) +{ + struct pm860x_chip *chip = data; + struct pm860x_irq_data *irq_data; + struct i2c_client *i2c; + int read_reg = -1, value = 0; + int i; + + i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion; + for (i = 0; i < ARRAY_SIZE(pm860x_irqs); i++) { + irq_data = &pm860x_irqs[i]; + if (read_reg != irq_data->reg) { + read_reg = irq_data->reg; + value = pm860x_reg_read(i2c, irq_data->reg); + } + if (value & irq_data->enable) + handle_nested_irq(chip->irq_base + i); + } + return IRQ_HANDLED; +} + +static void pm860x_irq_lock(unsigned int irq) +{ + struct pm860x_chip *chip = get_irq_chip_data(irq); + + mutex_lock(&chip->irq_lock); +} + +static void pm860x_irq_sync_unlock(unsigned int irq) +{ + struct pm860x_chip *chip = get_irq_chip_data(irq); + struct pm860x_irq_data *irq_data; + struct i2c_client *i2c; + static unsigned char cached[3] = {0x0, 0x0, 0x0}; + unsigned char mask[3]; + int i; + + i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion; + /* Load cached value. In initial, all IRQs are masked */ + for (i = 0; i < 3; i++) + mask[i] = cached[i]; + for (i = 0; i < ARRAY_SIZE(pm860x_irqs); i++) { + irq_data = &pm860x_irqs[i]; + switch (irq_data->mask_reg) { + case PM8607_INT_MASK_1: + mask[0] &= ~irq_data->offs; + mask[0] |= irq_data->enable; + break; + case PM8607_INT_MASK_2: + mask[1] &= ~irq_data->offs; + mask[1] |= irq_data->enable; + break; + case PM8607_INT_MASK_3: + mask[2] &= ~irq_data->offs; + mask[2] |= irq_data->enable; + break; + default: + dev_err(chip->dev, "wrong IRQ\n"); + break; + } + } + /* update mask into registers */ + for (i = 0; i < 3; i++) { + if (mask[i] != cached[i]) { + cached[i] = mask[i]; + pm860x_reg_write(i2c, PM8607_INT_MASK_1 + i, mask[i]); + } + } + + mutex_unlock(&chip->irq_lock); +} + +static void pm860x_irq_enable(unsigned int irq) +{ + struct pm860x_chip *chip = get_irq_chip_data(irq); + pm860x_irqs[irq - chip->irq_base].enable + = pm860x_irqs[irq - chip->irq_base].offs; +} + +static void pm860x_irq_disable(unsigned int irq) +{ + struct pm860x_chip *chip = get_irq_chip_data(irq); + pm860x_irqs[irq - chip->irq_base].enable = 0; +} + +static struct irq_chip pm860x_irq_chip = { + .name = "88pm860x", + .bus_lock = pm860x_irq_lock, + .bus_sync_unlock = pm860x_irq_sync_unlock, + .enable = pm860x_irq_enable, + .disable = pm860x_irq_disable, +}; + +static int __devinit device_gpadc_init(struct pm860x_chip *chip, + struct pm860x_platform_data *pdata) +{ + struct i2c_client *i2c = (chip->id == CHIP_PM8607) ? chip->client \ + : chip->companion; + int use_gpadc = 0, data, ret; + + /* initialize GPADC without activating it */ + + if (pdata && pdata->touch) { + /* set GPADC MISC1 register */ + data = 0; + data |= (pdata->touch->gpadc_prebias << 1) + & PM8607_GPADC_PREBIAS_MASK; + data |= (pdata->touch->slot_cycle << 3) + & PM8607_GPADC_SLOT_CYCLE_MASK; + data |= (pdata->touch->off_scale << 5) + & PM8607_GPADC_OFF_SCALE_MASK; + data |= (pdata->touch->sw_cal << 7) + & PM8607_GPADC_SW_CAL_MASK; + if (data) { + ret = pm860x_reg_write(i2c, PM8607_GPADC_MISC1, data); + if (ret < 0) + goto out; + } + /* set tsi prebias time */ + if (pdata->touch->tsi_prebias) { + data = pdata->touch->tsi_prebias; + ret = pm860x_reg_write(i2c, PM8607_TSI_PREBIAS, data); + if (ret < 0) + goto out; + } + /* set prebias & prechg time of pen detect */ + data = 0; + data |= pdata->touch->pen_prebias & PM8607_PD_PREBIAS_MASK; + data |= (pdata->touch->pen_prechg << 5) + & PM8607_PD_PRECHG_MASK; + if (data) { + ret = pm860x_reg_write(i2c, PM8607_PD_PREBIAS, data); + if (ret < 0) + goto out; + } + + use_gpadc = 1; + } + + /* turn on GPADC */ + if (use_gpadc) { + ret = pm860x_set_bits(i2c, PM8607_GPADC_MISC1, + PM8607_GPADC_EN, PM8607_GPADC_EN); + } +out: + return ret; +} + +static int __devinit device_irq_init(struct pm860x_chip *chip, + struct pm860x_platform_data *pdata) +{ + struct i2c_client *i2c = (chip->id == CHIP_PM8607) ? chip->client \ + : chip->companion; + unsigned char status_buf[INT_STATUS_NUM]; + unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT; + struct irq_desc *desc; + int i, data, mask, ret = -EINVAL; + int __irq; + + if (!pdata || !pdata->irq_base) { + dev_warn(chip->dev, "No interrupt support on IRQ base\n"); + return -EINVAL; + } + + mask = PM8607_B0_MISC1_INV_INT | PM8607_B0_MISC1_INT_CLEAR + | PM8607_B0_MISC1_INT_MASK; + data = 0; + chip->irq_mode = 0; + if (pdata && pdata->irq_mode) { + /* + * irq_mode defines the way of clearing interrupt. If it's 1, + * clear IRQ by write. Otherwise, clear it by read. + * This control bit is valid from 88PM8607 B0 steping. + */ + data |= PM8607_B0_MISC1_INT_CLEAR; + chip->irq_mode = 1; + } + ret = pm860x_set_bits(i2c, PM8607_B0_MISC1, mask, data); + if (ret < 0) + goto out; + + /* mask all IRQs */ + memset(status_buf, 0, INT_STATUS_NUM); + ret = pm860x_bulk_write(i2c, PM8607_INT_MASK_1, + INT_STATUS_NUM, status_buf); + if (ret < 0) + goto out; + + if (chip->irq_mode) { + /* clear interrupt status by write */ + memset(status_buf, 0xFF, INT_STATUS_NUM); + ret = pm860x_bulk_write(i2c, PM8607_INT_STATUS1, + INT_STATUS_NUM, status_buf); + } else { + /* clear interrupt status by read */ + ret = pm860x_bulk_read(i2c, PM8607_INT_STATUS1, + INT_STATUS_NUM, status_buf); + } + if (ret < 0) + goto out; + + mutex_init(&chip->irq_lock); + chip->irq_base = pdata->irq_base; + chip->core_irq = i2c->irq; + if (!chip->core_irq) + goto out; + + desc = irq_to_desc(chip->core_irq); + + /* register IRQ by genirq */ + for (i = 0; i < ARRAY_SIZE(pm860x_irqs); i++) { + __irq = i + chip->irq_base; + set_irq_chip_data(__irq, chip); + set_irq_chip_and_handler(__irq, &pm860x_irq_chip, + handle_edge_irq); + set_irq_nested_thread(__irq, 1); +#ifdef CONFIG_ARM + set_irq_flags(__irq, IRQF_VALID); +#else + set_irq_noprobe(__irq); +#endif + } + + ret = request_threaded_irq(chip->core_irq, NULL, pm860x_irq, flags, + "88pm860x", chip); + if (ret) { + dev_err(chip->dev, "Failed to request IRQ: %d\n", ret); + chip->core_irq = 0; + } + + return 0; +out: + chip->core_irq = 0; + return ret; +} + +static void __devexit device_irq_exit(struct pm860x_chip *chip) +{ + if (chip->core_irq) + free_irq(chip->core_irq, chip); +} + +static void __devinit device_8606_init(struct pm860x_chip *chip, + struct i2c_client *i2c, + struct pm860x_platform_data *pdata) +{ + int ret; + + if (pdata && pdata->backlight) { + ret = mfd_add_devices(chip->dev, 0, &backlight_devs[0], + ARRAY_SIZE(backlight_devs), + &backlight_resources[0], 0); + if (ret < 0) { + dev_err(chip->dev, "Failed to add backlight " + "subdev\n"); + goto out_dev; + } + } + + if (pdata && pdata->led) { + ret = mfd_add_devices(chip->dev, 0, &led_devs[0], + ARRAY_SIZE(led_devs), + &led_resources[0], 0); + if (ret < 0) { + dev_err(chip->dev, "Failed to add led " + "subdev\n"); + goto out_dev; + } + } + return; +out_dev: + mfd_remove_devices(chip->dev); + device_irq_exit(chip); +} + +static void __devinit device_8607_init(struct pm860x_chip *chip, + struct i2c_client *i2c, + struct pm860x_platform_data *pdata) +{ + int data, ret; + + ret = pm860x_reg_read(i2c, PM8607_CHIP_ID); + if (ret < 0) { + dev_err(chip->dev, "Failed to read CHIP ID: %d\n", ret); + goto out; + } + if ((ret & PM8607_VERSION_MASK) == PM8607_VERSION) + dev_info(chip->dev, "Marvell 88PM8607 (ID: %02x) detected\n", + ret); + else { + dev_err(chip->dev, "Failed to detect Marvell 88PM8607. " + "Chip ID: %02x\n", ret); + goto out; + } + + ret = pm860x_reg_read(i2c, PM8607_BUCK3); + if (ret < 0) { + dev_err(chip->dev, "Failed to read BUCK3 register: %d\n", ret); + goto out; + } + if (ret & PM8607_BUCK3_DOUBLE) + chip->buck3_double = 1; + + ret = pm860x_reg_read(i2c, PM8607_B0_MISC1); + if (ret < 0) { + dev_err(chip->dev, "Failed to read MISC1 register: %d\n", ret); + goto out; + } + + if (pdata && (pdata->i2c_port == PI2C_PORT)) + data = PM8607_B0_MISC1_PI2C; + else + data = 0; + ret = pm860x_set_bits(i2c, PM8607_B0_MISC1, PM8607_B0_MISC1_PI2C, data); + if (ret < 0) { + dev_err(chip->dev, "Failed to access MISC1:%d\n", ret); + goto out; + } + + ret = device_gpadc_init(chip, pdata); + if (ret < 0) + goto out; + + ret = device_irq_init(chip, pdata); + if (ret < 0) + goto out; + + ret = mfd_add_devices(chip->dev, 0, ®ulator_devs[0], + ARRAY_SIZE(regulator_devs), + ®ulator_resources[0], 0); + if (ret < 0) { + dev_err(chip->dev, "Failed to add regulator subdev\n"); + goto out_dev; + } + + if (pdata && pdata->touch) { + ret = mfd_add_devices(chip->dev, 0, &touch_devs[0], + ARRAY_SIZE(touch_devs), + &touch_resources[0], 0); + if (ret < 0) { + dev_err(chip->dev, "Failed to add touch " + "subdev\n"); + goto out_dev; + } + } + + if (pdata && pdata->power) { + ret = mfd_add_devices(chip->dev, 0, &power_devs[0], + ARRAY_SIZE(power_devs), + &power_supply_resources[0], 0); + if (ret < 0) { + dev_err(chip->dev, "Failed to add power supply " + "subdev\n"); + goto out_dev; + } + } + + ret = mfd_add_devices(chip->dev, 0, &onkey_devs[0], + ARRAY_SIZE(onkey_devs), + &onkey_resources[0], 0); + if (ret < 0) { + dev_err(chip->dev, "Failed to add onkey subdev\n"); + goto out_dev; + } + + return; +out_dev: + mfd_remove_devices(chip->dev); + device_irq_exit(chip); +out: + return; +} + +int pm860x_device_init(struct pm860x_chip *chip, + struct pm860x_platform_data *pdata) +{ + chip->core_irq = 0; + + switch (chip->id) { + case CHIP_PM8606: + device_8606_init(chip, chip->client, pdata); + break; + case CHIP_PM8607: + device_8607_init(chip, chip->client, pdata); + break; + } + + if (chip->companion) { + switch (chip->id) { + case CHIP_PM8607: + device_8606_init(chip, chip->companion, pdata); + break; + case CHIP_PM8606: + device_8607_init(chip, chip->companion, pdata); + break; + } + } + + return 0; +} + +void pm860x_device_exit(struct pm860x_chip *chip) +{ + device_irq_exit(chip); + mfd_remove_devices(chip->dev); +} + +MODULE_DESCRIPTION("PMIC Driver for Marvell 88PM860x"); +MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>"); +MODULE_LICENSE("GPL"); diff --git a/drivers/mfd/88pm860x-i2c.c b/drivers/mfd/88pm860x-i2c.c new file mode 100644 index 0000000..c37e12b --- /dev/null +++ b/drivers/mfd/88pm860x-i2c.c @@ -0,0 +1,236 @@ +/* + * I2C driver for Marvell 88PM860x + * + * Copyright (C) 2009 Marvell International Ltd. + * Haojian Zhuang <haojian.zhuang@marvell.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/i2c.h> +#include <linux/mfd/88pm860x.h> + +static inline int pm860x_read_device(struct i2c_client *i2c, + int reg, int bytes, void *dest) +{ + unsigned char data; + int ret; + + data = (unsigned char)reg; + ret = i2c_master_send(i2c, &data, 1); + if (ret < 0) + return ret; + + ret = i2c_master_recv(i2c, dest, bytes); + if (ret < 0) + return ret; + return 0; +} + +static inline int pm860x_write_device(struct i2c_client *i2c, + int reg, int bytes, void *src) +{ + unsigned char buf[bytes + 1]; + int ret; + + buf[0] = (unsigned char)reg; + memcpy(&buf[1], src, bytes); + + ret = i2c_master_send(i2c, buf, bytes + 1); + if (ret < 0) + return ret; + return 0; +} + +int pm860x_reg_read(struct i2c_client *i2c, int reg) +{ + struct pm860x_chip *chip = i2c_get_clientdata(i2c); + unsigned char data; + int ret; + + mutex_lock(&chip->io_lock); + ret = pm860x_read_device(i2c, reg, 1, &data); + mutex_unlock(&chip->io_lock); + + if (ret < 0) + return ret; + else + return (int)data; +} +EXPORT_SYMBOL(pm860x_reg_read); + +int pm860x_reg_write(struct i2c_client *i2c, int reg, + unsigned char data) +{ + struct pm860x_chip *chip = i2c_get_clientdata(i2c); + int ret; + + mutex_lock(&chip->io_lock); + ret = pm860x_write_device(i2c, reg, 1, &data); + mutex_unlock(&chip->io_lock); + + return ret; +} +EXPORT_SYMBOL(pm860x_reg_write); + +int pm860x_bulk_read(struct i2c_client *i2c, int reg, + int count, unsigned char *buf) +{ + struct pm860x_chip *chip = i2c_get_clientdata(i2c); + int ret; + + mutex_lock(&chip->io_lock); + ret = pm860x_read_device(i2c, reg, count, buf); + mutex_unlock(&chip->io_lock); + + return ret; +} +EXPORT_SYMBOL(pm860x_bulk_read); + +int pm860x_bulk_write(struct i2c_client *i2c, int reg, + int count, unsigned char *buf) +{ + struct pm860x_chip *chip = i2c_get_clientdata(i2c); + int ret; + + mutex_lock(&chip->io_lock); + ret = pm860x_write_device(i2c, reg, count, buf); + mutex_unlock(&chip->io_lock); + + return ret; +} +EXPORT_SYMBOL(pm860x_bulk_write); + +int pm860x_set_bits(struct i2c_client *i2c, int reg, + unsigned char mask, unsigned char data) +{ + struct pm860x_chip *chip = i2c_get_clientdata(i2c); + unsigned char value; + int ret; + + mutex_lock(&chip->io_lock); + ret = pm860x_read_device(i2c, reg, 1, &value); + if (ret < 0) + goto out; + value &= ~mask; + value |= data; + ret = pm860x_write_device(i2c, reg, 1, &value); +out: + mutex_unlock(&chip->io_lock); + return ret; +} +EXPORT_SYMBOL(pm860x_set_bits); + + +static const struct i2c_device_id pm860x_id_table[] = { + { "88PM860x", 0 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, pm860x_id_table); + +static int verify_addr(struct i2c_client *i2c) +{ + unsigned short addr_8607[] = {0x30, 0x34}; + unsigned short addr_8606[] = {0x10, 0x11}; + int size, i; + + if (i2c == NULL) + return 0; + size = ARRAY_SIZE(addr_8606); + for (i = 0; i < size; i++) { + if (i2c->addr == *(addr_8606 + i)) + return CHIP_PM8606; + } + size = ARRAY_SIZE(addr_8607); + for (i = 0; i < size; i++) { + if (i2c->addr == *(addr_8607 + i)) + return CHIP_PM8607; + } + return 0; +} + +static int __devinit pm860x_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct pm860x_platform_data *pdata = client->dev.platform_data; + struct pm860x_chip *chip; + + if (!pdata) { + pr_info("No platform data in %s!\n", __func__); + return -EINVAL; + } + + chip = kzalloc(sizeof(struct pm860x_chip), GFP_KERNEL); + if (chip == NULL) + return -ENOMEM; + + chip->id = verify_addr(client); + chip->client = client; + i2c_set_clientdata(client, chip); + chip->dev = &client->dev; + mutex_init(&chip->io_lock); + dev_set_drvdata(chip->dev, chip); + + /* + * Both client and companion client shares same platform driver. + * Driver distinguishes them by pdata->companion_addr. + * pdata->companion_addr is only assigned if companion chip exists. + * At the same time, the companion_addr shouldn't equal to client + * address. + */ + if (pdata->companion_addr && (pdata->companion_addr != client->addr)) { + chip->companion_addr = pdata->companion_addr; + chip->companion = i2c_new_dummy(chip->client->adapter, + chip->companion_addr); + i2c_set_clientdata(chip->companion, chip); + } + + pm860x_device_init(chip, pdata); + return 0; +} + +static int __devexit pm860x_remove(struct i2c_client *client) +{ + struct pm860x_chip *chip = i2c_get_clientdata(client); + + pm860x_device_exit(chip); + i2c_unregister_device(chip->companion); + i2c_set_clientdata(chip->companion, NULL); + i2c_set_clientdata(chip->client, NULL); + kfree(chip); + return 0; +} + +static struct i2c_driver pm860x_driver = { + .driver = { + .name = "88PM860x", + .owner = THIS_MODULE, + }, + .probe = pm860x_probe, + .remove = __devexit_p(pm860x_remove), + .id_table = pm860x_id_table, +}; + +static int __init pm860x_i2c_init(void) +{ + int ret; + ret = i2c_add_driver(&pm860x_driver); + if (ret != 0) + pr_err("Failed to register 88PM860x I2C driver: %d\n", ret); + return ret; +} +subsys_initcall(pm860x_i2c_init); + +static void __exit pm860x_i2c_exit(void) +{ + i2c_del_driver(&pm860x_driver); +} +module_exit(pm860x_i2c_exit); + +MODULE_DESCRIPTION("I2C Driver for Marvell 88PM860x"); +MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>"); +MODULE_LICENSE("GPL"); diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index b670d10..951fa9b 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -9,6 +9,16 @@ config MFD_CORE tristate default n +config MFD_88PM860X + bool "Support Marvell 88PM8606/88PM8607" + depends on I2C=y + select MFD_CORE + help + This supports for Marvell 88PM8606/88PM8607 Power Management IC. + This includes the I2C driver and the core APIs _only_, you have to + select individual components like voltage regulators, RTC and + battery-charger under the corresponding menus. + config MFD_SM501 tristate "Support for Silicon Motion SM501" ---help--- @@ -37,7 +47,7 @@ config MFD_ASIC3 config MFD_SH_MOBILE_SDHI bool "Support for SuperH Mobile SDHI" - depends on SUPERH + depends on SUPERH || ARCH_SHMOBILE select MFD_CORE ---help--- This driver supports the SDHI hardware block found in many @@ -68,6 +78,15 @@ config HTC_PASIC3 HTC Magician devices, respectively. Actual functionality is handled by the leds-pasic3 and ds1wm drivers. +config HTC_I2CPLD + bool "HTC I2C PLD chip support" + depends on I2C=y && GPIOLIB + help + If you say yes here you get support for the supposed CPLD + found on omap850 HTC devices like the HTC Wizard and HTC Herald. + This device provides input and output GPIOs through an I2C + interface to one or more sub-chips. + config UCB1400_CORE tristate "Philips UCB1400 Core driver" depends on AC97_BUS @@ -184,6 +203,16 @@ config PMIC_ADP5520 individual components like LCD backlight, LEDs, GPIOs and Kepad under the corresponding menus. +config MFD_MAX8925 + bool "Maxim Semiconductor MAX8925 PMIC Support" + depends on I2C=y + select MFD_CORE + help + Say yes here to support for Maxim Semiconductor MAX8925. This is + a Power Management IC. This driver provies common support for + accessing the device, additional drivers must be enabled in order + to use the functionality of the device. + config MFD_WM8400 tristate "Support Wolfson Microelectronics WM8400" select MFD_CORE @@ -205,7 +234,7 @@ config MFD_WM831X functionality of the device. config MFD_WM8350 - tristate + bool config MFD_WM8350_CONFIG_MODE_0 bool @@ -256,9 +285,9 @@ config MFD_WM8352_CONFIG_MODE_3 depends on MFD_WM8350 config MFD_WM8350_I2C - tristate "Support Wolfson Microelectronics WM8350 with I2C" + bool "Support Wolfson Microelectronics WM8350 with I2C" select MFD_WM8350 - depends on I2C + depends on I2C=y help The WM8350 is an integrated audio and power management subsystem with watchdog and RTC functionality for embedded @@ -266,6 +295,18 @@ config MFD_WM8350_I2C I2C as the control interface. Additional options must be selected to enable support for the functionality of the chip. +config MFD_WM8994 + tristate "Support Wolfson Microelectronics WM8994" + select MFD_CORE + depends on I2C + help + The WM8994 is a highly integrated hi-fi CODEC designed for + smartphone applicatiosn. As well as audio functionality it + has on board GPIO and regulator functionality which is + supported via the relevant subsystems. This driver provides + core support for the WM8994, in order to use the actual + functionaltiy of the device other drivers must be enabled. + config MFD_PCF50633 tristate "Support for NXP PCF50633" depends on I2C @@ -300,8 +341,8 @@ config PCF50633_GPIO the PCF50633 chip. config AB3100_CORE - tristate "ST-Ericsson AB3100 Mixed Signal Circuit core functions" - depends on I2C + bool "ST-Ericsson AB3100 Mixed Signal Circuit core functions" + depends on I2C=y default y if ARCH_U300 help Select this to enable the AB3100 Mixed Signal IC core @@ -329,16 +370,6 @@ config EZX_PCAP This enables the PCAP ASIC present on EZX Phones. This is needed for MMC, TouchScreen, Sound, USB, etc.. -config MFD_88PM8607 - bool "Support Marvell 88PM8607" - depends on I2C=y - select MFD_CORE - help - This supports for Marvell 88PM8607 Power Management IC. This includes - the I2C driver and the core APIs _only_, you have to select - individual components like voltage regulators, RTC and - battery-charger under the corresponding menus. - config AB4500_CORE tristate "ST-Ericsson's AB4500 Mixed Signal Power management chip" depends on SPI @@ -358,6 +389,15 @@ config MFD_TIMBERDALE The timberdale FPGA can be found on the Intel Atom development board for in-vehicle infontainment, called Russellville. + +config LPC_SCH + tristate "Intel SCH LPC" + depends on PCI + select MFD_CORE + help + LPC bridge function of the Intel SCH provides support for + System Management Bus and General Purpose I/O. + endmenu menu "Multimedia Capabilities Port drivers" diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 78295d6..22715ad 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -2,12 +2,15 @@ # Makefile for multifunction miscellaneous devices # +88pm860x-objs := 88pm860x-core.o 88pm860x-i2c.o +obj-$(CONFIG_MFD_88PM860X) += 88pm860x.o obj-$(CONFIG_MFD_SM501) += sm501.o obj-$(CONFIG_MFD_ASIC3) += asic3.o tmio_core.o obj-$(CONFIG_MFD_SH_MOBILE_SDHI) += sh_mobile_sdhi.o obj-$(CONFIG_HTC_EGPIO) += htc-egpio.o obj-$(CONFIG_HTC_PASIC3) += htc-pasic3.o +obj-$(CONFIG_HTC_I2CPLD) += htc-i2cpld.o obj-$(CONFIG_MFD_DM355EVM_MSP) += dm355evm_msp.o @@ -22,6 +25,7 @@ wm8350-objs := wm8350-core.o wm8350-regmap.o wm8350-gpio.o wm8350-objs += wm8350-irq.o obj-$(CONFIG_MFD_WM8350) += wm8350.o obj-$(CONFIG_MFD_WM8350_I2C) += wm8350-i2c.o +obj-$(CONFIG_MFD_WM8994) += wm8994-core.o obj-$(CONFIG_TPS65010) += tps65010.o obj-$(CONFIG_MENELAUS) += menelaus.o @@ -47,6 +51,8 @@ endif obj-$(CONFIG_UCB1400_CORE) += ucb1400_core.o obj-$(CONFIG_PMIC_DA903X) += da903x.o +max8925-objs := max8925-core.o max8925-i2c.o +obj-$(CONFIG_MFD_MAX8925) += max8925.o obj-$(CONFIG_MFD_PCF50633) += pcf50633-core.o obj-$(CONFIG_PCF50633_ADC) += pcf50633-adc.o @@ -55,5 +61,5 @@ obj-$(CONFIG_AB3100_CORE) += ab3100-core.o obj-$(CONFIG_AB3100_OTP) += ab3100-otp.o obj-$(CONFIG_AB4500_CORE) += ab4500-core.o obj-$(CONFIG_MFD_TIMBERDALE) += timberdale.o -obj-$(CONFIG_MFD_88PM8607) += 88pm8607.o obj-$(CONFIG_PMIC_ADP5520) += adp5520.o +obj-$(CONFIG_LPC_SCH) += lpc_sch.o
\ No newline at end of file diff --git a/drivers/mfd/ab3100-core.c b/drivers/mfd/ab3100-core.c index fd42a80..a2ce3b6 100644 --- a/drivers/mfd/ab3100-core.c +++ b/drivers/mfd/ab3100-core.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009 ST-Ericsson + * Copyright (C) 2007-2010 ST-Ericsson * License terms: GNU General Public License (GPL) version 2 * Low-level core for exclusive access to the AB3100 IC on the I2C bus * and some basic chip-configuration. @@ -14,6 +14,7 @@ #include <linux/platform_device.h> #include <linux/device.h> #include <linux/interrupt.h> +#include <linux/random.h> #include <linux/debugfs.h> #include <linux/seq_file.h> #include <linux/uaccess.h> @@ -365,18 +366,23 @@ int ab3100_event_registers_startup_state_get(struct ab3100 *ab3100, } EXPORT_SYMBOL(ab3100_event_registers_startup_state_get); -/* Interrupt handling worker */ -static void ab3100_work(struct work_struct *work) +/* + * This is a threaded interrupt handler so we can make some + * I2C calls etc. + */ +static irqreturn_t ab3100_irq_handler(int irq, void *data) { - struct ab3100 *ab3100 = container_of(work, struct ab3100, work); + struct ab3100 *ab3100 = data; u8 event_regs[3]; u32 fatevent; int err; + add_interrupt_randomness(irq); + err = ab3100_get_register_page_interruptible(ab3100, AB3100_EVENTA1, event_regs, 3); if (err) - goto err_event_wq; + goto err_event; fatevent = (event_regs[0] << 16) | (event_regs[1] << 8) | @@ -398,29 +404,11 @@ static void ab3100_work(struct work_struct *work) dev_dbg(ab3100->dev, "IRQ Event: 0x%08x\n", fatevent); - /* By now the IRQ should be acked and deasserted so enable it again */ - enable_irq(ab3100->i2c_client->irq); - return; + return IRQ_HANDLED; - err_event_wq: + err_event: dev_dbg(ab3100->dev, - "error in event workqueue\n"); - /* Enable the IRQ anyway, what choice do we have? */ - enable_irq(ab3100->i2c_client->irq); - return; -} - -static irqreturn_t ab3100_irq_handler(int irq, void *data) -{ - struct ab3100 *ab3100 = data; - /* - * Disable the IRQ and dispatch a worker to handle the - * event. Since the chip resides on I2C this is slow - * stuff and we will re-enable the interrupts once th - * worker has finished. - */ - disable_irq_nosync(irq); - schedule_work(&ab3100->work); + "error reading event status\n"); return IRQ_HANDLED; } @@ -735,10 +723,7 @@ static struct platform_device ab3100_##devname##_device = { \ .id = -1, \ } -/* - * This lists all the subdevices and corresponding register - * ranges. - */ +/* This lists all the subdevices */ AB3100_DEVICE(dac, "ab3100-dac"); AB3100_DEVICE(leds, "ab3100-leds"); AB3100_DEVICE(power, "ab3100-power"); @@ -904,12 +889,11 @@ static int __init ab3100_probe(struct i2c_client *client, if (err) goto exit_no_setup; - INIT_WORK(&ab3100->work, ab3100_work); - + err = request_threaded_irq(client->irq, NULL, ab3100_irq_handler, + IRQF_ONESHOT, "ab3100-core", ab3100); /* This real unpredictable IRQ is of course sampled for entropy */ - err = request_irq(client->irq, ab3100_irq_handler, - IRQF_DISABLED | IRQF_SAMPLE_RANDOM, - "AB3100 IRQ", ab3100); + rand_initialize_irq(client->irq); + if (err) goto exit_no_irq; diff --git a/drivers/mfd/ab3100-otp.c b/drivers/mfd/ab3100-otp.c index 0499b20..b603469 100644 --- a/drivers/mfd/ab3100-otp.c +++ b/drivers/mfd/ab3100-otp.c @@ -13,6 +13,7 @@ #include <linux/platform_device.h> #include <linux/mfd/ab3100.h> #include <linux/debugfs.h> +#include <linux/seq_file.h> /* The OTP registers */ #define AB3100_OTP0 0xb0 @@ -95,11 +96,10 @@ static int __init ab3100_otp_read(struct ab3100_otp *otp) * This is a simple debugfs human-readable file that dumps out * the contents of the OTP. */ -#ifdef CONFIG_DEBUGFS -static int show_otp(struct seq_file *s, void *v) +#ifdef CONFIG_DEBUG_FS +static int ab3100_show_otp(struct seq_file *s, void *v) { struct ab3100_otp *otp = s->private; - int err; seq_printf(s, "OTP is %s\n", otp->locked ? "LOCKED" : "UNLOCKED"); seq_printf(s, "OTP clock switch startup is %uHz\n", otp->freq); @@ -113,7 +113,7 @@ static int show_otp(struct seq_file *s, void *v) static int ab3100_otp_open(struct inode *inode, struct file *file) { - return single_open(file, ab3100_otp_show, inode->i_private); + return single_open(file, ab3100_show_otp, inode->i_private); } static const struct file_operations ab3100_otp_operations = { @@ -131,13 +131,14 @@ static int __init ab3100_otp_init_debugfs(struct device *dev, &ab3100_otp_operations); if (!otp->debugfs) { dev_err(dev, "AB3100 debugfs OTP file registration failed!\n"); - return err; + return -ENOENT; } + return 0; } static void __exit ab3100_otp_exit_debugfs(struct ab3100_otp *otp) { - debugfs_remove_file(otp->debugfs); + debugfs_remove(otp->debugfs); } #else /* Compile this out if debugfs not selected */ diff --git a/drivers/mfd/htc-i2cpld.c b/drivers/mfd/htc-i2cpld.c new file mode 100644 index 0000000..37b9fda --- /dev/null +++ b/drivers/mfd/htc-i2cpld.c @@ -0,0 +1,710 @@ +/* + * htc-i2cpld.c + * Chip driver for an unknown CPLD chip found on omap850 HTC devices like + * the HTC Wizard and HTC Herald. + * The cpld is located on the i2c bus and acts as an input/output GPIO + * extender. + * + * Copyright (C) 2009 Cory Maccarrone <darkstar6262@gmail.com> + * + * Based on work done in the linwizard project + * Copyright (C) 2008-2009 Angelo Arrifano <miknix@gmail.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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/module.h> +#include <linux/interrupt.h> +#include <linux/platform_device.h> +#include <linux/i2c.h> +#include <linux/irq.h> +#include <linux/spinlock.h> +#include <linux/htcpld.h> +#include <linux/gpio.h> + +struct htcpld_chip { + spinlock_t lock; + + /* chip info */ + u8 reset; + u8 addr; + struct device *dev; + struct i2c_client *client; + + /* Output details */ + u8 cache_out; + struct gpio_chip chip_out; + + /* Input details */ + u8 cache_in; + struct gpio_chip chip_in; + + u16 irqs_enabled; + uint irq_start; + int nirqs; + + /* + * Work structure to allow for setting values outside of any + * possible interrupt context + */ + struct work_struct set_val_work; +}; + +struct htcpld_data { + /* irq info */ + u16 irqs_enabled; + uint irq_start; + int nirqs; + uint chained_irq; + unsigned int int_reset_gpio_hi; + unsigned int int_reset_gpio_lo; + + /* htcpld info */ + struct htcpld_chip *chip; + unsigned int nchips; +}; + +/* There does not appear to be a way to proactively mask interrupts + * on the htcpld chip itself. So, we simply ignore interrupts that + * aren't desired. */ +static void htcpld_mask(unsigned int irq) +{ + struct htcpld_chip *chip = get_irq_chip_data(irq); + chip->irqs_enabled &= ~(1 << (irq - chip->irq_start)); + pr_debug("HTCPLD mask %d %04x\n", irq, chip->irqs_enabled); +} +static void htcpld_unmask(unsigned int irq) +{ + struct htcpld_chip *chip = get_irq_chip_data(irq); + chip->irqs_enabled |= 1 << (irq - chip->irq_start); + pr_debug("HTCPLD unmask %d %04x\n", irq, chip->irqs_enabled); +} + +static int htcpld_set_type(unsigned int irq, unsigned int flags) +{ + struct irq_desc *d = irq_to_desc(irq); + + if (!d) { + pr_err("HTCPLD invalid IRQ: %d\n", irq); + return -EINVAL; + } + + if (flags & ~IRQ_TYPE_SENSE_MASK) + return -EINVAL; + + /* We only allow edge triggering */ + if (flags & (IRQ_TYPE_LEVEL_LOW|IRQ_TYPE_LEVEL_HIGH)) + return -EINVAL; + + d->status &= ~IRQ_TYPE_SENSE_MASK; + d->status |= flags; + + return 0; +} + +static struct irq_chip htcpld_muxed_chip = { + .name = "htcpld", + .mask = htcpld_mask, + .unmask = htcpld_unmask, + .set_type = htcpld_set_type, +}; + +/* To properly dispatch IRQ events, we need to read from the + * chip. This is an I2C action that could possibly sleep + * (which is bad in interrupt context) -- so we use a threaded + * interrupt handler to get around that. + */ +static irqreturn_t htcpld_handler(int irq, void *dev) +{ + struct htcpld_data *htcpld = dev; + unsigned int i; + unsigned long flags; + int irqpin; + struct irq_desc *desc; + + if (!htcpld) { + pr_debug("htcpld is null in ISR\n"); + return IRQ_HANDLED; + } + + /* + * For each chip, do a read of the chip and trigger any interrupts + * desired. The interrupts will be triggered from LSB to MSB (i.e. + * bit 0 first, then bit 1, etc.) + * + * For chips that have no interrupt range specified, just skip 'em. + */ + for (i = 0; i < htcpld->nchips; i++) { + struct htcpld_chip *chip = &htcpld->chip[i]; + struct i2c_client *client; + int val; + unsigned long uval, old_val; + + if (!chip) { + pr_debug("chip %d is null in ISR\n", i); + continue; + } + + if (chip->nirqs == 0) + continue; + + client = chip->client; + if (!client) { + pr_debug("client %d is null in ISR\n", i); + continue; + } + + /* Scan the chip */ + val = i2c_smbus_read_byte_data(client, chip->cache_out); + if (val < 0) { + /* Throw a warning and skip this chip */ + dev_warn(chip->dev, "Unable to read from chip: %d\n", + val); + continue; + } + + uval = (unsigned long)val; + + spin_lock_irqsave(&chip->lock, flags); + + /* Save away the old value so we can compare it */ + old_val = chip->cache_in; + + /* Write the new value */ + chip->cache_in = uval; + + spin_unlock_irqrestore(&chip->lock, flags); + + /* + * For each bit in the data (starting at bit 0), trigger + * associated interrupts. + */ + for (irqpin = 0; irqpin < chip->nirqs; irqpin++) { + unsigned oldb, newb; + int flags; + + irq = chip->irq_start + irqpin; + desc = irq_to_desc(irq); + flags = desc->status; + + /* Run the IRQ handler, but only if the bit value + * changed, and the proper flags are set */ + oldb = (old_val >> irqpin) & 1; + newb = (uval >> irqpin) & 1; + + if ((!oldb && newb && (flags & IRQ_TYPE_EDGE_RISING)) || + (oldb && !newb && + (flags & IRQ_TYPE_EDGE_FALLING))) { + pr_debug("fire IRQ %d\n", irqpin); + desc->handle_irq(irq, desc); + } + } + } + + /* + * In order to continue receiving interrupts, the int_reset_gpio must + * be asserted. + */ + if (htcpld->int_reset_gpio_hi) + gpio_set_value(htcpld->int_reset_gpio_hi, 1); + if (htcpld->int_reset_gpio_lo) + gpio_set_value(htcpld->int_reset_gpio_lo, 0); + + return IRQ_HANDLED; +} + +/* + * The GPIO set routines can be called from interrupt context, especially if, + * for example they're attached to the led-gpio framework and a trigger is + * enabled. As such, we declared work above in the htcpld_chip structure, + * and that work is scheduled in the set routine. The kernel can then run + * the I2C functions, which will sleep, in process context. + */ +void htcpld_chip_set(struct gpio_chip *chip, unsigned offset, int val) +{ + struct i2c_client *client; + struct htcpld_chip *chip_data; + unsigned long flags; + + chip_data = container_of(chip, struct htcpld_chip, chip_out); + if (!chip_data) + return; + + client = chip_data->client; + if (client == NULL) + return; + + spin_lock_irqsave(&chip_data->lock, flags); + if (val) + chip_data->cache_out |= (1 << offset); + else + chip_data->cache_out &= ~(1 << offset); + spin_unlock_irqrestore(&chip_data->lock, flags); + + schedule_work(&(chip_data->set_val_work)); +} + +void htcpld_chip_set_ni(struct work_struct *work) +{ + struct htcpld_chip *chip_data; + struct i2c_client *client; + + chip_data = container_of(work, struct htcpld_chip, set_val_work); + client = chip_data->client; + i2c_smbus_read_byte_data(client, chip_data->cache_out); +} + +int htcpld_chip_get(struct gpio_chip *chip, unsigned offset) +{ + struct htcpld_chip *chip_data; + int val = 0; + int is_input = 0; + + /* Try out first */ + chip_data = container_of(chip, struct htcpld_chip, chip_out); + if (!chip_data) { + /* Try in */ + is_input = 1; + chip_data = container_of(chip, struct htcpld_chip, chip_in); + if (!chip_data) + return -EINVAL; + } + + /* Determine if this is an input or output GPIO */ + if (!is_input) + /* Use the output cache */ + val = (chip_data->cache_out >> offset) & 1; + else + /* Use the input cache */ + val = (chip_data->cache_in >> offset) & 1; + + if (val) + return 1; + else + return 0; +} + +static int htcpld_direction_output(struct gpio_chip *chip, + unsigned offset, int value) +{ + htcpld_chip_set(chip, offset, value); + return 0; +} + +static int htcpld_direction_input(struct gpio_chip *chip, + unsigned offset) +{ + /* + * No-op: this function can only be called on the input chip. + * We do however make sure the offset is within range. + */ + return (offset < chip->ngpio) ? 0 : -EINVAL; +} + +int htcpld_chip_to_irq(struct gpio_chip *chip, unsigned offset) +{ + struct htcpld_chip *chip_data; + + chip_data = container_of(chip, struct htcpld_chip, chip_in); + + if (offset < chip_data->nirqs) + return chip_data->irq_start + offset; + else + return -EINVAL; +} + +void htcpld_chip_reset(struct i2c_client *client) +{ + struct htcpld_chip *chip_data = i2c_get_clientdata(client); + if (!chip_data) + return; + + i2c_smbus_read_byte_data( + client, (chip_data->cache_out = chip_data->reset)); +} + +static int __devinit htcpld_setup_chip_irq( + struct platform_device *pdev, + int chip_index) +{ + struct htcpld_data *htcpld; + struct device *dev = &pdev->dev; + struct htcpld_core_platform_data *pdata; + struct htcpld_chip *chip; + struct htcpld_chip_platform_data *plat_chip_data; + unsigned int irq, irq_end; + int ret = 0; + + /* Get the platform and driver data */ + pdata = dev->platform_data; + htcpld = platform_get_drvdata(pdev); + chip = &htcpld->chip[chip_index]; + plat_chip_data = &pdata->chip[chip_index]; + + /* Setup irq handlers */ + irq_end = chip->irq_start + chip->nirqs; + for (irq = chip->irq_start; irq < irq_end; irq++) { + set_irq_chip(irq, &htcpld_muxed_chip); + set_irq_chip_data(irq, chip); + set_irq_handler(irq, handle_simple_irq); +#ifdef CONFIG_ARM + set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); +#else + set_irq_probe(irq); +#endif + } + + return ret; +} + +static int __devinit htcpld_register_chip_i2c( + struct platform_device *pdev, + int chip_index) +{ + struct htcpld_data *htcpld; + struct device *dev = &pdev->dev; + struct htcpld_core_platform_data *pdata; + struct htcpld_chip *chip; + struct htcpld_chip_platform_data *plat_chip_data; + struct i2c_adapter *adapter; + struct i2c_client *client; + struct i2c_board_info info; + + /* Get the platform and driver data */ + pdata = dev->platform_data; + htcpld = platform_get_drvdata(pdev); + chip = &htcpld->chip[chip_index]; + plat_chip_data = &pdata->chip[chip_index]; + + adapter = i2c_get_adapter(pdata->i2c_adapter_id); + if (adapter == NULL) { + /* Eek, no such I2C adapter! Bail out. */ + dev_warn(dev, "Chip at i2c address 0x%x: Invalid i2c adapter %d\n", + plat_chip_data->addr, pdata->i2c_adapter_id); + return -ENODEV; + } + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE_DATA)) { + dev_warn(dev, "i2c adapter %d non-functional\n", + pdata->i2c_adapter_id); + return -EINVAL; + } + + memset(&info, 0, sizeof(struct i2c_board_info)); + info.addr = plat_chip_data->addr; + strlcpy(info.type, "htcpld-chip", I2C_NAME_SIZE); + info.platform_data = chip; + + /* Add the I2C device. This calls the probe() function. */ + client = i2c_new_device(adapter, &info); + if (!client) { + /* I2C device registration failed, contineu with the next */ + dev_warn(dev, "Unable to add I2C device for 0x%x\n", + plat_chip_data->addr); + return -ENODEV; + } + + i2c_set_clientdata(client, chip); + snprintf(client->name, I2C_NAME_SIZE, "Chip_0x%d", client->addr); + chip->client = client; + + /* Reset the chip */ + htcpld_chip_reset(client); + chip->cache_in = i2c_smbus_read_byte_data(client, chip->cache_out); + + return 0; +} + +static void __devinit htcpld_unregister_chip_i2c( + struct platform_device *pdev, + int chip_index) +{ + struct htcpld_data *htcpld; + struct htcpld_chip *chip; + + /* Get the platform and driver data */ + htcpld = platform_get_drvdata(pdev); + chip = &htcpld->chip[chip_index]; + + if (chip->client) + i2c_unregister_device(chip->client); +} + +static int __devinit htcpld_register_chip_gpio( + struct platform_device *pdev, + int chip_index) +{ + struct htcpld_data *htcpld; + struct device *dev = &pdev->dev; + struct htcpld_core_platform_data *pdata; + struct htcpld_chip *chip; + struct htcpld_chip_platform_data *plat_chip_data; + struct gpio_chip *gpio_chip; + int ret = 0; + + /* Get the platform and driver data */ + pdata = dev->platform_data; + htcpld = platform_get_drvdata(pdev); + chip = &htcpld->chip[chip_index]; + plat_chip_data = &pdata->chip[chip_index]; + + /* Setup the GPIO chips */ + gpio_chip = &(chip->chip_out); + gpio_chip->label = "htcpld-out"; + gpio_chip->dev = dev; + gpio_chip->owner = THIS_MODULE; + gpio_chip->get = htcpld_chip_get; + gpio_chip->set = htcpld_chip_set; + gpio_chip->direction_input = NULL; + gpio_chip->direction_output = htcpld_direction_output; + gpio_chip->base = plat_chip_data->gpio_out_base; + gpio_chip->ngpio = plat_chip_data->num_gpios; + + gpio_chip = &(chip->chip_in); + gpio_chip->label = "htcpld-in"; + gpio_chip->dev = dev; + gpio_chip->owner = THIS_MODULE; + gpio_chip->get = htcpld_chip_get; + gpio_chip->set = NULL; + gpio_chip->direction_input = htcpld_direction_input; + gpio_chip->direction_output = NULL; + gpio_chip->to_irq = htcpld_chip_to_irq; + gpio_chip->base = plat_chip_data->gpio_in_base; + gpio_chip->ngpio = plat_chip_data->num_gpios; + + /* Add the GPIO chips */ + ret = gpiochip_add(&(chip->chip_out)); + if (ret) { + dev_warn(dev, "Unable to register output GPIOs for 0x%x: %d\n", + plat_chip_data->addr, ret); + return ret; + } + + ret = gpiochip_add(&(chip->chip_in)); + if (ret) { + int error; + + dev_warn(dev, "Unable to register input GPIOs for 0x%x: %d\n", + plat_chip_data->addr, ret); + + error = gpiochip_remove(&(chip->chip_out)); + if (error) + dev_warn(dev, "Error while trying to unregister gpio chip: %d\n", error); + + return ret; + } + + return 0; +} + +static int __devinit htcpld_setup_chips(struct platform_device *pdev) +{ + struct htcpld_data *htcpld; + struct device *dev = &pdev->dev; + struct htcpld_core_platform_data *pdata; + int i; + + /* Get the platform and driver data */ + pdata = dev->platform_data; + htcpld = platform_get_drvdata(pdev); + + /* Setup each chip's output GPIOs */ + htcpld->nchips = pdata->num_chip; + htcpld->chip = kzalloc(sizeof(struct htcpld_chip) * htcpld->nchips, + GFP_KERNEL); + if (!htcpld->chip) { + dev_warn(dev, "Unable to allocate memory for chips\n"); + return -ENOMEM; + } + + /* Add the chips as best we can */ + for (i = 0; i < htcpld->nchips; i++) { + int ret; + + /* Setup the HTCPLD chips */ + htcpld->chip[i].reset = pdata->chip[i].reset; + htcpld->chip[i].cache_out = pdata->chip[i].reset; + htcpld->chip[i].cache_in = 0; + htcpld->chip[i].dev = dev; + htcpld->chip[i].irq_start = pdata->chip[i].irq_base; + htcpld->chip[i].nirqs = pdata->chip[i].num_irqs; + + INIT_WORK(&(htcpld->chip[i].set_val_work), &htcpld_chip_set_ni); + spin_lock_init(&(htcpld->chip[i].lock)); + + /* Setup the interrupts for the chip */ + if (htcpld->chained_irq) { + ret = htcpld_setup_chip_irq(pdev, i); + if (ret) + continue; + } + + /* Register the chip with I2C */ + ret = htcpld_register_chip_i2c(pdev, i); + if (ret) + continue; + + + /* Register the chips with the GPIO subsystem */ + ret = htcpld_register_chip_gpio(pdev, i); + if (ret) { + /* Unregister the chip from i2c and continue */ + htcpld_unregister_chip_i2c(pdev, i); + continue; + } + + dev_info(dev, "Registered chip at 0x%x\n", pdata->chip[i].addr); + } + + return 0; +} + +static int __devinit htcpld_core_probe(struct platform_device *pdev) +{ + struct htcpld_data *htcpld; + struct device *dev = &pdev->dev; + struct htcpld_core_platform_data *pdata; + struct resource *res; + int ret = 0; + + if (!dev) + return -ENODEV; + + pdata = dev->platform_data; + if (!pdata) { + dev_warn(dev, "Platform data not found for htcpld core!\n"); + return -ENXIO; + } + + htcpld = kzalloc(sizeof(struct htcpld_data), GFP_KERNEL); + if (!htcpld) + return -ENOMEM; + + /* Find chained irq */ + ret = -EINVAL; + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (res) { + int flags; + htcpld->chained_irq = res->start; + + /* Setup the chained interrupt handler */ + flags = IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING; + ret = request_threaded_irq(htcpld->chained_irq, + NULL, htcpld_handler, + flags, pdev->name, htcpld); + if (ret) { + dev_warn(dev, "Unable to setup chained irq handler: %d\n", ret); + goto fail; + } else + device_init_wakeup(dev, 0); + } + + /* Set the driver data */ + platform_set_drvdata(pdev, htcpld); + + /* Setup the htcpld chips */ + ret = htcpld_setup_chips(pdev); + if (ret) + goto fail; + + /* Request the GPIO(s) for the int reset and set them up */ + if (pdata->int_reset_gpio_hi) { + ret = gpio_request(pdata->int_reset_gpio_hi, "htcpld-core"); + if (ret) { + /* + * If it failed, that sucks, but we can probably + * continue on without it. + */ + dev_warn(dev, "Unable to request int_reset_gpio_hi -- interrupts may not work\n"); + htcpld->int_reset_gpio_hi = 0; + } else { + htcpld->int_reset_gpio_hi = pdata->int_reset_gpio_hi; + gpio_set_value(htcpld->int_reset_gpio_hi, 1); + } + } + + if (pdata->int_reset_gpio_lo) { + ret = gpio_request(pdata->int_reset_gpio_lo, "htcpld-core"); + if (ret) { + /* + * If it failed, that sucks, but we can probably + * continue on without it. + */ + dev_warn(dev, "Unable to request int_reset_gpio_lo -- interrupts may not work\n"); + htcpld->int_reset_gpio_lo = 0; + } else { + htcpld->int_reset_gpio_lo = pdata->int_reset_gpio_lo; + gpio_set_value(htcpld->int_reset_gpio_lo, 0); + } + } + + dev_info(dev, "Initialized successfully\n"); + return 0; + +fail: + kfree(htcpld); + return ret; +} + +/* The I2C Driver -- used internally */ +static const struct i2c_device_id htcpld_chip_id[] = { + { "htcpld-chip", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, htcpld_chip_id); + + +static struct i2c_driver htcpld_chip_driver = { + .driver = { + .name = "htcpld-chip", + }, + .id_table = htcpld_chip_id, +}; + +/* The Core Driver */ +static struct platform_driver htcpld_core_driver = { + .driver = { + .name = "i2c-htcpld", + }, +}; + +static int __init htcpld_core_init(void) +{ + int ret; + + /* Register the I2C Chip driver */ + ret = i2c_add_driver(&htcpld_chip_driver); + if (ret) + return ret; + + /* Probe for our chips */ + return platform_driver_probe(&htcpld_core_driver, htcpld_core_probe); +} + +static void __exit htcpld_core_exit(void) +{ + i2c_del_driver(&htcpld_chip_driver); + platform_driver_unregister(&htcpld_core_driver); +} + +module_init(htcpld_core_init); +module_exit(htcpld_core_exit); + +MODULE_AUTHOR("Cory Maccarrone <darkstar6262@gmail.com>"); +MODULE_DESCRIPTION("I2C HTC PLD Driver"); +MODULE_LICENSE("GPL"); + diff --git a/drivers/mfd/lpc_sch.c b/drivers/mfd/lpc_sch.c new file mode 100644 index 0000000..51b2f60 --- /dev/null +++ b/drivers/mfd/lpc_sch.c @@ -0,0 +1,133 @@ +/* + * lpc_sch.c - LPC interface for Intel Poulsbo SCH + * + * LPC bridge function of the Intel SCH contains many other + * functional units, such as Interrupt controllers, Timers, + * Power Management, System Management, GPIO, RTC, and LPC + * Configuration Registers. + * + * Copyright (c) 2010 CompuLab Ltd + * Author: Denis Turischev <denis@compulab.co.il> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License 2 as published + * by the Free Software Foundation. + * + * 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; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/errno.h> +#include <linux/acpi.h> +#include <linux/pci.h> +#include <linux/mfd/core.h> + +#define SMBASE 0x40 +#define SMBUS_IO_SIZE 64 + +#define GPIOBASE 0x44 +#define GPIO_IO_SIZE 64 + +static struct resource smbus_sch_resource = { + .flags = IORESOURCE_IO, +}; + + +static struct resource gpio_sch_resource = { + .flags = IORESOURCE_IO, +}; + +static struct mfd_cell lpc_sch_cells[] = { + { + .name = "isch_smbus", + .num_resources = 1, + .resources = &smbus_sch_resource, + }, + { + .name = "sch_gpio", + .num_resources = 1, + .resources = &gpio_sch_resource, + }, +}; + +static struct pci_device_id lpc_sch_ids[] = { + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SCH_LPC) }, + { 0, } +}; +MODULE_DEVICE_TABLE(pci, lpc_sch_ids); + +static int __devinit lpc_sch_probe(struct pci_dev *dev, + const struct pci_device_id *id) +{ + unsigned int base_addr_cfg; + unsigned short base_addr; + + pci_read_config_dword(dev, SMBASE, &base_addr_cfg); + if (!(base_addr_cfg & (1 << 31))) { + dev_err(&dev->dev, "Decode of the SMBus I/O range disabled\n"); + return -ENODEV; + } + base_addr = (unsigned short)base_addr_cfg; + if (base_addr == 0) { + dev_err(&dev->dev, "I/O space for SMBus uninitialized\n"); + return -ENODEV; + } + + smbus_sch_resource.start = base_addr; + smbus_sch_resource.end = base_addr + SMBUS_IO_SIZE - 1; + + pci_read_config_dword(dev, GPIOBASE, &base_addr_cfg); + if (!(base_addr_cfg & (1 << 31))) { + dev_err(&dev->dev, "Decode of the GPIO I/O range disabled\n"); + return -ENODEV; + } + base_addr = (unsigned short)base_addr_cfg; + if (base_addr == 0) { + dev_err(&dev->dev, "I/O space for GPIO uninitialized\n"); + return -ENODEV; + } + + gpio_sch_resource.start = base_addr; + gpio_sch_resource.end = base_addr + GPIO_IO_SIZE - 1; + + return mfd_add_devices(&dev->dev, -1, + lpc_sch_cells, ARRAY_SIZE(lpc_sch_cells), NULL, 0); +} + +static void __devexit lpc_sch_remove(struct pci_dev *dev) +{ + mfd_remove_devices(&dev->dev); +} + +static struct pci_driver lpc_sch_driver = { + .name = "lpc_sch", + .id_table = lpc_sch_ids, + .probe = lpc_sch_probe, + .remove = __devexit_p(lpc_sch_remove), +}; + +static int __init lpc_sch_init(void) +{ + return pci_register_driver(&lpc_sch_driver); +} + +static void __exit lpc_sch_exit(void) +{ + pci_unregister_driver(&lpc_sch_driver); +} + +module_init(lpc_sch_init); +module_exit(lpc_sch_exit); + +MODULE_AUTHOR("Denis Turischev <denis@compulab.co.il>"); +MODULE_DESCRIPTION("LPC interface for Intel Poulsbo SCH"); +MODULE_LICENSE("GPL"); diff --git a/drivers/mfd/max8925-core.c b/drivers/mfd/max8925-core.c new file mode 100644 index 0000000..85d63c0 --- /dev/null +++ b/drivers/mfd/max8925-core.c @@ -0,0 +1,656 @@ +/* + * Base driver for Maxim MAX8925 + * + * Copyright (C) 2009-2010 Marvell International Ltd. + * Haojian Zhuang <haojian.zhuang@marvell.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/i2c.h> +#include <linux/irq.h> +#include <linux/interrupt.h> +#include <linux/platform_device.h> +#include <linux/mfd/core.h> +#include <linux/mfd/max8925.h> + +static struct resource backlight_resources[] = { + { + .name = "max8925-backlight", + .start = MAX8925_WLED_MODE_CNTL, + .end = MAX8925_WLED_CNTL, + .flags = IORESOURCE_IO, + }, +}; + +static struct mfd_cell backlight_devs[] = { + { + .name = "max8925-backlight", + .num_resources = 1, + .resources = &backlight_resources[0], + .id = -1, + }, +}; + +static struct resource touch_resources[] = { + { + .name = "max8925-tsc", + .start = MAX8925_TSC_IRQ, + .end = MAX8925_ADC_RES_END, + .flags = IORESOURCE_IO, + }, +}; + +static struct mfd_cell touch_devs[] = { + { + .name = "max8925-touch", + .num_resources = 1, + .resources = &touch_resources[0], + .id = -1, + }, +}; + +static struct resource power_supply_resources[] = { + { + .name = "max8925-power", + .start = MAX8925_CHG_IRQ1, + .end = MAX8925_CHG_IRQ1_MASK, + .flags = IORESOURCE_IO, + }, +}; + +static struct mfd_cell power_devs[] = { + { + .name = "max8925-power", + .num_resources = 1, + .resources = &power_supply_resources[0], + .id = -1, + }, +}; + +static struct resource rtc_resources[] = { + { + .name = "max8925-rtc", + .start = MAX8925_RTC_IRQ, + .end = MAX8925_RTC_IRQ_MASK, + .flags = IORESOURCE_IO, + }, +}; + +static struct mfd_cell rtc_devs[] = { + { + .name = "max8925-rtc", + .num_resources = 1, + .resources = &rtc_resources[0], + .id = -1, + }, +}; + +#define MAX8925_REG_RESOURCE(_start, _end) \ +{ \ + .start = MAX8925_##_start, \ + .end = MAX8925_##_end, \ + .flags = IORESOURCE_IO, \ +} + +static struct resource regulator_resources[] = { + MAX8925_REG_RESOURCE(SDCTL1, SDCTL1), + MAX8925_REG_RESOURCE(SDCTL2, SDCTL2), + MAX8925_REG_RESOURCE(SDCTL3, SDCTL3), + MAX8925_REG_RESOURCE(LDOCTL1, LDOCTL1), + MAX8925_REG_RESOURCE(LDOCTL2, LDOCTL2), + MAX8925_REG_RESOURCE(LDOCTL3, LDOCTL3), + MAX8925_REG_RESOURCE(LDOCTL4, LDOCTL4), + MAX8925_REG_RESOURCE(LDOCTL5, LDOCTL5), + MAX8925_REG_RESOURCE(LDOCTL6, LDOCTL6), + MAX8925_REG_RESOURCE(LDOCTL7, LDOCTL7), + MAX8925_REG_RESOURCE(LDOCTL8, LDOCTL8), + MAX8925_REG_RESOURCE(LDOCTL9, LDOCTL9), + MAX8925_REG_RESOURCE(LDOCTL10, LDOCTL10), + MAX8925_REG_RESOURCE(LDOCTL11, LDOCTL11), + MAX8925_REG_RESOURCE(LDOCTL12, LDOCTL12), + MAX8925_REG_RESOURCE(LDOCTL13, LDOCTL13), + MAX8925_REG_RESOURCE(LDOCTL14, LDOCTL14), + MAX8925_REG_RESOURCE(LDOCTL15, LDOCTL15), + MAX8925_REG_RESOURCE(LDOCTL16, LDOCTL16), + MAX8925_REG_RESOURCE(LDOCTL17, LDOCTL17), + MAX8925_REG_RESOURCE(LDOCTL18, LDOCTL18), + MAX8925_REG_RESOURCE(LDOCTL19, LDOCTL19), + MAX8925_REG_RESOURCE(LDOCTL20, LDOCTL20), +}; + +#define MAX8925_REG_DEVS(_id) \ +{ \ + .name = "max8925-regulator", \ + .num_resources = 1, \ + .resources = ®ulator_resources[MAX8925_ID_##_id], \ + .id = MAX8925_ID_##_id, \ +} + +static struct mfd_cell regulator_devs[] = { + MAX8925_REG_DEVS(SD1), + MAX8925_REG_DEVS(SD2), + MAX8925_REG_DEVS(SD3), + MAX8925_REG_DEVS(LDO1), + MAX8925_REG_DEVS(LDO2), + MAX8925_REG_DEVS(LDO3), + MAX8925_REG_DEVS(LDO4), + MAX8925_REG_DEVS(LDO5), + MAX8925_REG_DEVS(LDO6), + MAX8925_REG_DEVS(LDO7), + MAX8925_REG_DEVS(LDO8), + MAX8925_REG_DEVS(LDO9), + MAX8925_REG_DEVS(LDO10), + MAX8925_REG_DEVS(LDO11), + MAX8925_REG_DEVS(LDO12), + MAX8925_REG_DEVS(LDO13), + MAX8925_REG_DEVS(LDO14), + MAX8925_REG_DEVS(LDO15), + MAX8925_REG_DEVS(LDO16), + MAX8925_REG_DEVS(LDO17), + MAX8925_REG_DEVS(LDO18), + MAX8925_REG_DEVS(LDO19), + MAX8925_REG_DEVS(LDO20), +}; + +enum { + FLAGS_ADC = 1, /* register in ADC component */ + FLAGS_RTC, /* register in RTC component */ +}; + +struct max8925_irq_data { + int reg; + int mask_reg; + int enable; /* enable or not */ + int offs; /* bit offset in mask register */ + int flags; + int tsc_irq; +}; + +static struct max8925_irq_data max8925_irqs[] = { + [MAX8925_IRQ_VCHG_DC_OVP] = { + .reg = MAX8925_CHG_IRQ1, + .mask_reg = MAX8925_CHG_IRQ1_MASK, + .offs = 1 << 0, + }, + [MAX8925_IRQ_VCHG_DC_F] = { + .reg = MAX8925_CHG_IRQ1, + .mask_reg = MAX8925_CHG_IRQ1_MASK, + .offs = 1 << 1, + }, + [MAX8925_IRQ_VCHG_DC_R] = { + .reg = MAX8925_CHG_IRQ1, + .mask_reg = MAX8925_CHG_IRQ1_MASK, + .offs = 1 << 2, + }, + [MAX8925_IRQ_VCHG_USB_OVP] = { + .reg = MAX8925_CHG_IRQ1, + .mask_reg = MAX8925_CHG_IRQ1_MASK, + .offs = 1 << 3, + }, + [MAX8925_IRQ_VCHG_USB_F] = { + .reg = MAX8925_CHG_IRQ1, + .mask_reg = MAX8925_CHG_IRQ1_MASK, + .offs = 1 << 4, + }, + [MAX8925_IRQ_VCHG_USB_R] = { + .reg = MAX8925_CHG_IRQ1, + .mask_reg = MAX8925_CHG_IRQ1_MASK, + .offs = 1 << 5, + }, + [MAX8925_IRQ_VCHG_THM_OK_R] = { + .reg = MAX8925_CHG_IRQ2, + .mask_reg = MAX8925_CHG_IRQ2_MASK, + .offs = 1 << 0, + }, + [MAX8925_IRQ_VCHG_THM_OK_F] = { + .reg = MAX8925_CHG_IRQ2, + .mask_reg = MAX8925_CHG_IRQ2_MASK, + .offs = 1 << 1, + }, + [MAX8925_IRQ_VCHG_SYSLOW_F] = { + .reg = MAX8925_CHG_IRQ2, + .mask_reg = MAX8925_CHG_IRQ2_MASK, + .offs = 1 << 2, + }, + [MAX8925_IRQ_VCHG_SYSLOW_R] = { + .reg = MAX8925_CHG_IRQ2, + .mask_reg = MAX8925_CHG_IRQ2_MASK, + .offs = 1 << 3, + }, + [MAX8925_IRQ_VCHG_RST] = { + .reg = MAX8925_CHG_IRQ2, + .mask_reg = MAX8925_CHG_IRQ2_MASK, + .offs = 1 << 4, + }, + [MAX8925_IRQ_VCHG_DONE] = { + .reg = MAX8925_CHG_IRQ2, + .mask_reg = MAX8925_CHG_IRQ2_MASK, + .offs = 1 << 5, + }, + [MAX8925_IRQ_VCHG_TOPOFF] = { + .reg = MAX8925_CHG_IRQ2, + .mask_reg = MAX8925_CHG_IRQ2_MASK, + .offs = 1 << 6, + }, + [MAX8925_IRQ_VCHG_TMR_FAULT] = { + .reg = MAX8925_CHG_IRQ2, + .mask_reg = MAX8925_CHG_IRQ2_MASK, + .offs = 1 << 7, + }, + [MAX8925_IRQ_GPM_RSTIN] = { + .reg = MAX8925_ON_OFF_IRQ1, + .mask_reg = MAX8925_ON_OFF_IRQ1_MASK, + .offs = 1 << 0, + }, + [MAX8925_IRQ_GPM_MPL] = { + .reg = MAX8925_ON_OFF_IRQ1, + .mask_reg = MAX8925_ON_OFF_IRQ1_MASK, + .offs = 1 << 1, + }, + [MAX8925_IRQ_GPM_SW_3SEC] = { + .reg = MAX8925_ON_OFF_IRQ1, + .mask_reg = MAX8925_ON_OFF_IRQ1_MASK, + .offs = 1 << 2, + }, + [MAX8925_IRQ_GPM_EXTON_F] = { + .reg = MAX8925_ON_OFF_IRQ1, + .mask_reg = MAX8925_ON_OFF_IRQ1_MASK, + .offs = 1 << 3, + }, + [MAX8925_IRQ_GPM_EXTON_R] = { + .reg = MAX8925_ON_OFF_IRQ1, + .mask_reg = MAX8925_ON_OFF_IRQ1_MASK, + .offs = 1 << 4, + }, + [MAX8925_IRQ_GPM_SW_1SEC] = { + .reg = MAX8925_ON_OFF_IRQ1, + .mask_reg = MAX8925_ON_OFF_IRQ1_MASK, + .offs = 1 << 5, + }, + [MAX8925_IRQ_GPM_SW_F] = { + .reg = MAX8925_ON_OFF_IRQ1, + .mask_reg = MAX8925_ON_OFF_IRQ1_MASK, + .offs = 1 << 6, + }, + [MAX8925_IRQ_GPM_SW_R] = { + .reg = MAX8925_ON_OFF_IRQ1, + .mask_reg = MAX8925_ON_OFF_IRQ1_MASK, + .offs = 1 << 7, + }, + [MAX8925_IRQ_GPM_SYSCKEN_F] = { + .reg = MAX8925_ON_OFF_IRQ2, + .mask_reg = MAX8925_ON_OFF_IRQ2_MASK, + .offs = 1 << 0, + }, + [MAX8925_IRQ_GPM_SYSCKEN_R] = { + .reg = MAX8925_ON_OFF_IRQ2, + .mask_reg = MAX8925_ON_OFF_IRQ2_MASK, + .offs = 1 << 1, + }, + [MAX8925_IRQ_RTC_ALARM1] = { + .reg = MAX8925_RTC_IRQ, + .mask_reg = MAX8925_RTC_IRQ_MASK, + .offs = 1 << 2, + .flags = FLAGS_RTC, + }, + [MAX8925_IRQ_RTC_ALARM0] = { + .reg = MAX8925_RTC_IRQ, + .mask_reg = MAX8925_RTC_IRQ_MASK, + .offs = 1 << 3, + .flags = FLAGS_RTC, + }, + [MAX8925_IRQ_TSC_STICK] = { + .reg = MAX8925_TSC_IRQ, + .mask_reg = MAX8925_TSC_IRQ_MASK, + .offs = 1 << 0, + .flags = FLAGS_ADC, + .tsc_irq = 1, + }, + [MAX8925_IRQ_TSC_NSTICK] = { + .reg = MAX8925_TSC_IRQ, + .mask_reg = MAX8925_TSC_IRQ_MASK, + .offs = 1 << 1, + .flags = FLAGS_ADC, + .tsc_irq = 1, + }, +}; + +static inline struct max8925_irq_data *irq_to_max8925(struct max8925_chip *chip, + int irq) +{ + return &max8925_irqs[irq - chip->irq_base]; +} + +static irqreturn_t max8925_irq(int irq, void *data) +{ + struct max8925_chip *chip = data; + struct max8925_irq_data *irq_data; + struct i2c_client *i2c; + int read_reg = -1, value = 0; + int i; + + for (i = 0; i < ARRAY_SIZE(max8925_irqs); i++) { + irq_data = &max8925_irqs[i]; + /* TSC IRQ should be serviced in max8925_tsc_irq() */ + if (irq_data->tsc_irq) + continue; + if (irq_data->flags == FLAGS_RTC) + i2c = chip->rtc; + else if (irq_data->flags == FLAGS_ADC) + i2c = chip->adc; + else + i2c = chip->i2c; + if (read_reg != irq_data->reg) { + read_reg = irq_data->reg; + value = max8925_reg_read(i2c, irq_data->reg); + } + if (value & irq_data->enable) + handle_nested_irq(chip->irq_base + i); + } + return IRQ_HANDLED; +} + +static irqreturn_t max8925_tsc_irq(int irq, void *data) +{ + struct max8925_chip *chip = data; + struct max8925_irq_data *irq_data; + struct i2c_client *i2c; + int read_reg = -1, value = 0; + int i; + + for (i = 0; i < ARRAY_SIZE(max8925_irqs); i++) { + irq_data = &max8925_irqs[i]; + /* non TSC IRQ should be serviced in max8925_irq() */ + if (!irq_data->tsc_irq) + continue; + if (irq_data->flags == FLAGS_RTC) + i2c = chip->rtc; + else if (irq_data->flags == FLAGS_ADC) + i2c = chip->adc; + else + i2c = chip->i2c; + if (read_reg != irq_data->reg) { + read_reg = irq_data->reg; + value = max8925_reg_read(i2c, irq_data->reg); + } + if (value & irq_data->enable) + handle_nested_irq(chip->irq_base + i); + } + return IRQ_HANDLED; +} + +static void max8925_irq_lock(unsigned int irq) +{ + struct max8925_chip *chip = get_irq_chip_data(irq); + + mutex_lock(&chip->irq_lock); +} + +static void max8925_irq_sync_unlock(unsigned int irq) +{ + struct max8925_chip *chip = get_irq_chip_data(irq); + struct max8925_irq_data *irq_data; + static unsigned char cache_chg[2] = {0xff, 0xff}; + static unsigned char cache_on[2] = {0xff, 0xff}; + static unsigned char cache_rtc = 0xff, cache_tsc = 0xff; + unsigned char irq_chg[2], irq_on[2]; + unsigned char irq_rtc, irq_tsc; + int i; + + /* Load cached value. In initial, all IRQs are masked */ + irq_chg[0] = cache_chg[0]; + irq_chg[1] = cache_chg[1]; + irq_on[0] = cache_on[0]; + irq_on[1] = cache_on[1]; + irq_rtc = cache_rtc; + irq_tsc = cache_tsc; + for (i = 0; i < ARRAY_SIZE(max8925_irqs); i++) { + irq_data = &max8925_irqs[i]; + switch (irq_data->mask_reg) { + case MAX8925_CHG_IRQ1_MASK: + irq_chg[0] &= irq_data->enable; + break; + case MAX8925_CHG_IRQ2_MASK: + irq_chg[1] &= irq_data->enable; + break; + case MAX8925_ON_OFF_IRQ1_MASK: + irq_on[0] &= irq_data->enable; + break; + case MAX8925_ON_OFF_IRQ2_MASK: + irq_on[1] &= irq_data->enable; + break; + case MAX8925_RTC_IRQ_MASK: + irq_rtc &= irq_data->enable; + break; + case MAX8925_TSC_IRQ_MASK: + irq_tsc &= irq_data->enable; + break; + default: + dev_err(chip->dev, "wrong IRQ\n"); + break; + } + } + /* update mask into registers */ + if (cache_chg[0] != irq_chg[0]) { + cache_chg[0] = irq_chg[0]; + max8925_reg_write(chip->i2c, MAX8925_CHG_IRQ1_MASK, + irq_chg[0]); + } + if (cache_chg[1] != irq_chg[1]) { + cache_chg[1] = irq_chg[1]; + max8925_reg_write(chip->i2c, MAX8925_CHG_IRQ2_MASK, + irq_chg[1]); + } + if (cache_on[0] != irq_on[0]) { + cache_on[0] = irq_on[0]; + max8925_reg_write(chip->i2c, MAX8925_ON_OFF_IRQ1_MASK, + irq_on[0]); + } + if (cache_on[1] != irq_on[1]) { + cache_on[1] = irq_on[1]; + max8925_reg_write(chip->i2c, MAX8925_ON_OFF_IRQ2_MASK, + irq_on[1]); + } + if (cache_rtc != irq_rtc) { + cache_rtc = irq_rtc; + max8925_reg_write(chip->rtc, MAX8925_RTC_IRQ_MASK, irq_rtc); + } + if (cache_tsc != irq_tsc) { + cache_tsc = irq_tsc; + max8925_reg_write(chip->adc, MAX8925_TSC_IRQ_MASK, irq_tsc); + } + + mutex_unlock(&chip->irq_lock); +} + +static void max8925_irq_enable(unsigned int irq) +{ + struct max8925_chip *chip = get_irq_chip_data(irq); + max8925_irqs[irq - chip->irq_base].enable + = max8925_irqs[irq - chip->irq_base].offs; +} + +static void max8925_irq_disable(unsigned int irq) +{ + struct max8925_chip *chip = get_irq_chip_data(irq); + max8925_irqs[irq - chip->irq_base].enable = 0; +} + +static struct irq_chip max8925_irq_chip = { + .name = "max8925", + .bus_lock = max8925_irq_lock, + .bus_sync_unlock = max8925_irq_sync_unlock, + .enable = max8925_irq_enable, + .disable = max8925_irq_disable, +}; + +static int max8925_irq_init(struct max8925_chip *chip, int irq, + struct max8925_platform_data *pdata) +{ + unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT; + struct irq_desc *desc; + int i, ret; + int __irq; + + if (!pdata || !pdata->irq_base) { + dev_warn(chip->dev, "No interrupt support on IRQ base\n"); + return -EINVAL; + } + /* clear all interrupts */ + max8925_reg_read(chip->i2c, MAX8925_CHG_IRQ1); + max8925_reg_read(chip->i2c, MAX8925_CHG_IRQ2); + max8925_reg_read(chip->i2c, MAX8925_ON_OFF_IRQ1); + max8925_reg_read(chip->i2c, MAX8925_ON_OFF_IRQ2); + max8925_reg_read(chip->rtc, MAX8925_RTC_IRQ); + max8925_reg_read(chip->adc, MAX8925_TSC_IRQ); + /* mask all interrupts */ + max8925_reg_write(chip->rtc, MAX8925_ALARM0_CNTL, 0); + max8925_reg_write(chip->rtc, MAX8925_ALARM1_CNTL, 0); + max8925_reg_write(chip->i2c, MAX8925_CHG_IRQ1_MASK, 0xff); + max8925_reg_write(chip->i2c, MAX8925_CHG_IRQ2_MASK, 0xff); + max8925_reg_write(chip->i2c, MAX8925_ON_OFF_IRQ1_MASK, 0xff); + max8925_reg_write(chip->i2c, MAX8925_ON_OFF_IRQ2_MASK, 0xff); + max8925_reg_write(chip->rtc, MAX8925_RTC_IRQ_MASK, 0xff); + max8925_reg_write(chip->adc, MAX8925_TSC_IRQ_MASK, 0xff); + + mutex_init(&chip->irq_lock); + chip->core_irq = irq; + chip->irq_base = pdata->irq_base; + desc = irq_to_desc(chip->core_irq); + + /* register with genirq */ + for (i = 0; i < ARRAY_SIZE(max8925_irqs); i++) { + __irq = i + chip->irq_base; + set_irq_chip_data(__irq, chip); + set_irq_chip_and_handler(__irq, &max8925_irq_chip, + handle_edge_irq); + set_irq_nested_thread(__irq, 1); +#ifdef CONFIG_ARM + set_irq_flags(__irq, IRQF_VALID); +#else + set_irq_noprobe(__irq); +#endif + } + if (!irq) { + dev_warn(chip->dev, "No interrupt support on core IRQ\n"); + goto tsc_irq; + } + + ret = request_threaded_irq(irq, NULL, max8925_irq, flags, + "max8925", chip); + if (ret) { + dev_err(chip->dev, "Failed to request core IRQ: %d\n", ret); + chip->core_irq = 0; + } +tsc_irq: + if (!pdata->tsc_irq) { + dev_warn(chip->dev, "No interrupt support on TSC IRQ\n"); + return 0; + } + chip->tsc_irq = pdata->tsc_irq; + + ret = request_threaded_irq(chip->tsc_irq, NULL, max8925_tsc_irq, + flags, "max8925-tsc", chip); + if (ret) { + dev_err(chip->dev, "Failed to request TSC IRQ: %d\n", ret); + chip->tsc_irq = 0; + } + return 0; +} + +int __devinit max8925_device_init(struct max8925_chip *chip, + struct max8925_platform_data *pdata) +{ + int ret; + + max8925_irq_init(chip, chip->i2c->irq, pdata); + + if (pdata && (pdata->power || pdata->touch)) { + /* enable ADC to control internal reference */ + max8925_set_bits(chip->i2c, MAX8925_RESET_CNFG, 1, 1); + /* enable internal reference for ADC */ + max8925_set_bits(chip->adc, MAX8925_TSC_CNFG1, 3, 2); + /* check for internal reference IRQ */ + do { + ret = max8925_reg_read(chip->adc, MAX8925_TSC_IRQ); + } while (ret & MAX8925_NREF_OK); + /* enaable ADC scheduler, interval is 1 second */ + max8925_set_bits(chip->adc, MAX8925_ADC_SCHED, 3, 2); + } + + /* enable Momentary Power Loss */ + max8925_set_bits(chip->rtc, MAX8925_MPL_CNTL, 1 << 4, 1 << 4); + + ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0], + ARRAY_SIZE(rtc_devs), + &rtc_resources[0], 0); + if (ret < 0) { + dev_err(chip->dev, "Failed to add rtc subdev\n"); + goto out; + } + if (pdata && pdata->regulator[0]) { + ret = mfd_add_devices(chip->dev, 0, ®ulator_devs[0], + ARRAY_SIZE(regulator_devs), + ®ulator_resources[0], 0); + if (ret < 0) { + dev_err(chip->dev, "Failed to add regulator subdev\n"); + goto out_dev; + } + } + + if (pdata && pdata->backlight) { + ret = mfd_add_devices(chip->dev, 0, &backlight_devs[0], + ARRAY_SIZE(backlight_devs), + &backlight_resources[0], 0); + if (ret < 0) { + dev_err(chip->dev, "Failed to add backlight subdev\n"); + goto out_dev; + } + } + + if (pdata && pdata->power) { + ret = mfd_add_devices(chip->dev, 0, &power_devs[0], + ARRAY_SIZE(power_devs), + &power_supply_resources[0], 0); + if (ret < 0) { + dev_err(chip->dev, "Failed to add power supply " + "subdev\n"); + goto out_dev; + } + } + + if (pdata && pdata->touch) { + ret = mfd_add_devices(chip->dev, 0, &touch_devs[0], + ARRAY_SIZE(touch_devs), + &touch_resources[0], 0); + if (ret < 0) { + dev_err(chip->dev, "Failed to add touch subdev\n"); + goto out_dev; + } + } + + return 0; +out_dev: + mfd_remove_devices(chip->dev); +out: + return ret; +} + +void __devexit max8925_device_exit(struct max8925_chip *chip) +{ + if (chip->core_irq) + free_irq(chip->core_irq, chip); + if (chip->tsc_irq) + free_irq(chip->tsc_irq, chip); + mfd_remove_devices(chip->dev); +} + + +MODULE_DESCRIPTION("PMIC Driver for Maxim MAX8925"); +MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com"); +MODULE_LICENSE("GPL"); diff --git a/drivers/mfd/max8925-i2c.c b/drivers/mfd/max8925-i2c.c new file mode 100644 index 0000000..c0b883c --- /dev/null +++ b/drivers/mfd/max8925-i2c.c @@ -0,0 +1,211 @@ +/* + * I2C driver for Maxim MAX8925 + * + * Copyright (C) 2009 Marvell International Ltd. + * Haojian Zhuang <haojian.zhuang@marvell.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/i2c.h> +#include <linux/mfd/max8925.h> + +#define RTC_I2C_ADDR 0x68 +#define ADC_I2C_ADDR 0x47 + +static inline int max8925_read_device(struct i2c_client *i2c, + int reg, int bytes, void *dest) +{ + int ret; + + if (bytes > 1) + ret = i2c_smbus_read_i2c_block_data(i2c, reg, bytes, dest); + else { + ret = i2c_smbus_read_byte_data(i2c, reg); + if (ret < 0) + return ret; + *(unsigned char *)dest = (unsigned char)ret; + } + return ret; +} + +static inline int max8925_write_device(struct i2c_client *i2c, + int reg, int bytes, void *src) +{ + unsigned char buf[bytes + 1]; + int ret; + + buf[0] = (unsigned char)reg; + memcpy(&buf[1], src, bytes); + + ret = i2c_master_send(i2c, buf, bytes + 1); + if (ret < 0) + return ret; + return 0; +} + +int max8925_reg_read(struct i2c_client *i2c, int reg) +{ + struct max8925_chip *chip = i2c_get_clientdata(i2c); + unsigned char data = 0; + int ret; + + mutex_lock(&chip->io_lock); + ret = max8925_read_device(i2c, reg, 1, &data); + mutex_unlock(&chip->io_lock); + + if (ret < 0) + return ret; + else + return (int)data; +} +EXPORT_SYMBOL(max8925_reg_read); + +int max8925_reg_write(struct i2c_client *i2c, int reg, + unsigned char data) +{ + struct max8925_chip *chip = i2c_get_clientdata(i2c); + int ret; + + mutex_lock(&chip->io_lock); + ret = max8925_write_device(i2c, reg, 1, &data); + mutex_unlock(&chip->io_lock); + + return ret; +} +EXPORT_SYMBOL(max8925_reg_write); + +int max8925_bulk_read(struct i2c_client *i2c, int reg, + int count, unsigned char *buf) +{ + struct max8925_chip *chip = i2c_get_clientdata(i2c); + int ret; + + mutex_lock(&chip->io_lock); + ret = max8925_read_device(i2c, reg, count, buf); + mutex_unlock(&chip->io_lock); + + return ret; +} +EXPORT_SYMBOL(max8925_bulk_read); + +int max8925_bulk_write(struct i2c_client *i2c, int reg, + int count, unsigned char *buf) +{ + struct max8925_chip *chip = i2c_get_clientdata(i2c); + int ret; + + mutex_lock(&chip->io_lock); + ret = max8925_write_device(i2c, reg, count, buf); + mutex_unlock(&chip->io_lock); + + return ret; +} +EXPORT_SYMBOL(max8925_bulk_write); + +int max8925_set_bits(struct i2c_client *i2c, int reg, + unsigned char mask, unsigned char data) +{ + struct max8925_chip *chip = i2c_get_clientdata(i2c); + unsigned char value; + int ret; + + mutex_lock(&chip->io_lock); + ret = max8925_read_device(i2c, reg, 1, &value); + if (ret < 0) + goto out; + value &= ~mask; + value |= data; + ret = max8925_write_device(i2c, reg, 1, &value); +out: + mutex_unlock(&chip->io_lock); + return ret; +} +EXPORT_SYMBOL(max8925_set_bits); + + +static const struct i2c_device_id max8925_id_table[] = { + { "max8925", 0 }, + { }, +}; +MODULE_DEVICE_TABLE(i2c, max8925_id_table); + +static int __devinit max8925_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct max8925_platform_data *pdata = client->dev.platform_data; + static struct max8925_chip *chip; + + if (!pdata) { + pr_info("%s: platform data is missing\n", __func__); + return -EINVAL; + } + + chip = kzalloc(sizeof(struct max8925_chip), GFP_KERNEL); + if (chip == NULL) + return -ENOMEM; + chip->i2c = client; + chip->dev = &client->dev; + i2c_set_clientdata(client, chip); + dev_set_drvdata(chip->dev, chip); + mutex_init(&chip->io_lock); + + chip->rtc = i2c_new_dummy(chip->i2c->adapter, RTC_I2C_ADDR); + i2c_set_clientdata(chip->rtc, chip); + + chip->adc = i2c_new_dummy(chip->i2c->adapter, ADC_I2C_ADDR); + i2c_set_clientdata(chip->adc, chip); + + max8925_device_init(chip, pdata); + + return 0; +} + +static int __devexit max8925_remove(struct i2c_client *client) +{ + struct max8925_chip *chip = i2c_get_clientdata(client); + + max8925_device_exit(chip); + i2c_unregister_device(chip->adc); + i2c_unregister_device(chip->rtc); + i2c_set_clientdata(chip->adc, NULL); + i2c_set_clientdata(chip->rtc, NULL); + i2c_set_clientdata(chip->i2c, NULL); + kfree(chip); + return 0; +} + +static struct i2c_driver max8925_driver = { + .driver = { + .name = "max8925", + .owner = THIS_MODULE, + }, + .probe = max8925_probe, + .remove = __devexit_p(max8925_remove), + .id_table = max8925_id_table, +}; + +static int __init max8925_i2c_init(void) +{ + int ret; + + ret = i2c_add_driver(&max8925_driver); + if (ret != 0) + pr_err("Failed to register MAX8925 I2C driver: %d\n", ret); + return ret; +} +subsys_initcall(max8925_i2c_init); + +static void __exit max8925_i2c_exit(void) +{ + i2c_del_driver(&max8925_driver); +} +module_exit(max8925_i2c_exit); + +MODULE_DESCRIPTION("I2C Driver for Maxim 8925"); +MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>"); +MODULE_LICENSE("GPL"); diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c index ae15e49..aa17f4b 100644 --- a/drivers/mfd/mfd-core.c +++ b/drivers/mfd/mfd-core.c @@ -13,6 +13,7 @@ #include <linux/kernel.h> #include <linux/platform_device.h> +#include <linux/acpi.h> #include <linux/mfd/core.h> static int mfd_add_device(struct device *parent, int id, @@ -62,6 +63,10 @@ static int mfd_add_device(struct device *parent, int id, res[r].start = cell->resources[r].start; res[r].end = cell->resources[r].end; } + + ret = acpi_check_resource_conflict(res); + if (ret) + goto fail_res; } platform_device_add_resources(pdev, res, cell->num_resources); diff --git a/drivers/mfd/sh_mobile_sdhi.c b/drivers/mfd/sh_mobile_sdhi.c index 03efae8..468fd36 100644 --- a/drivers/mfd/sh_mobile_sdhi.c +++ b/drivers/mfd/sh_mobile_sdhi.c @@ -21,7 +21,7 @@ #include <linux/kernel.h> #include <linux/clk.h> #include <linux/platform_device.h> - +#include <linux/mmc/host.h> #include <linux/mfd/core.h> #include <linux/mfd/tmio.h> #include <linux/mfd/sh_mobile_sdhi.h> @@ -95,9 +95,9 @@ static int __init sh_mobile_sdhi_probe(struct platform_device *pdev) clk_enable(priv->clk); - /* FIXME: silly const unsigned int hclk */ - *(unsigned int *)&priv->mmc_data.hclk = clk_get_rate(priv->clk); + priv->mmc_data.hclk = clk_get_rate(priv->clk); priv->mmc_data.set_pwr = sh_mobile_sdhi_set_pwr; + priv->mmc_data.capabilities = MMC_CAP_MMC_HIGHSPEED; memcpy(&priv->cell_mmc, &sh_mobile_sdhi_cell, sizeof(priv->cell_mmc)); priv->cell_mmc.driver_data = &priv->mmc_data; diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c index 0cc5eef..dc9ea95 100644 --- a/drivers/mfd/sm501.c +++ b/drivers/mfd/sm501.c @@ -1430,7 +1430,7 @@ static int __devinit sm501_plat_probe(struct platform_device *dev) } sm->regs_claim = request_mem_region(sm->io_res->start, - 0x100, "sm501"); + resource_size(sm->io_res), "sm501"); if (sm->regs_claim == NULL) { dev_err(&dev->dev, "cannot claim registers\n"); @@ -1440,8 +1440,7 @@ static int __devinit sm501_plat_probe(struct platform_device *dev) platform_set_drvdata(dev, sm); - sm->regs = ioremap(sm->io_res->start, - (sm->io_res->end - sm->io_res->start) - 1); + sm->regs = ioremap(sm->io_res->start, resource_size(sm->io_res)); if (sm->regs == NULL) { dev_err(&dev->dev, "cannot remap registers\n"); @@ -1645,7 +1644,7 @@ static int __devinit sm501_pci_probe(struct pci_dev *dev, sm->mem_res = &dev->resource[0]; sm->regs_claim = request_mem_region(sm->io_res->start, - 0x100, "sm501"); + resource_size(sm->io_res), "sm501"); if (sm->regs_claim == NULL) { dev_err(&dev->dev, "cannot claim registers\n"); err= -EBUSY; diff --git a/drivers/mfd/t7l66xb.c b/drivers/mfd/t7l66xb.c index bcf4687..26d9176 100644 --- a/drivers/mfd/t7l66xb.c +++ b/drivers/mfd/t7l66xb.c @@ -360,7 +360,7 @@ static int t7l66xb_probe(struct platform_device *dev) if (ret) goto err_request_scr; - t7l66xb->scr = ioremap(rscr->start, rscr->end - rscr->start + 1); + t7l66xb->scr = ioremap(rscr->start, resource_size(rscr)); if (!t7l66xb->scr) { ret = -ENOMEM; goto err_ioremap; @@ -403,12 +403,12 @@ static int t7l66xb_probe(struct platform_device *dev) err_ioremap: release_resource(&t7l66xb->rscr); err_request_scr: - kfree(t7l66xb); clk_put(t7l66xb->clk48m); err_clk48m_get: clk_put(t7l66xb->clk32k); err_clk32k_get: err_noirq: + kfree(t7l66xb); return ret; } diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c index 4bc5a08..c59e5c5 100644 --- a/drivers/mfd/tc6393xb.c +++ b/drivers/mfd/tc6393xb.c @@ -647,7 +647,7 @@ static int __devinit tc6393xb_probe(struct platform_device *dev) if (ret) goto err_request_scr; - tc6393xb->scr = ioremap(rscr->start, rscr->end - rscr->start + 1); + tc6393xb->scr = ioremap(rscr->start, resource_size(rscr)); if (!tc6393xb->scr) { ret = -ENOMEM; goto err_ioremap; diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c index 19a930d..562cd49 100644 --- a/drivers/mfd/twl-core.c +++ b/drivers/mfd/twl-core.c @@ -58,13 +58,6 @@ #define DRIVER_NAME "twl" -#if defined(CONFIG_TWL4030_BCI_BATTERY) || \ - defined(CONFIG_TWL4030_BCI_BATTERY_MODULE) -#define twl_has_bci() true -#else -#define twl_has_bci() false -#endif - #if defined(CONFIG_KEYBOARD_TWL4030) || defined(CONFIG_KEYBOARD_TWL4030_MODULE) #define twl_has_keypad() true #else @@ -130,7 +123,7 @@ #define TWL_NUM_SLAVES 4 #if defined(CONFIG_INPUT_TWL4030_PWRBUTTON) \ - || defined(CONFIG_INPUT_TWL4030_PWBUTTON_MODULE) + || defined(CONFIG_INPUT_TWL4030_PWRBUTTON_MODULE) #define twl_has_pwrbutton() true #else #define twl_has_pwrbutton() false @@ -205,6 +198,7 @@ /* subchip/slave 3 0x4B - AUDIO */ #define TWL6030_BASEADD_AUDIO 0x0000 #define TWL6030_BASEADD_RSV 0x0000 +#define TWL6030_BASEADD_ZERO 0x0000 /* Few power values */ #define R_CFG_BOOT 0x05 @@ -320,9 +314,11 @@ static struct twl_mapping twl6030_map[] = { { SUB_CHIP_ID1, TWL6030_BASEADD_CHARGER }, { SUB_CHIP_ID1, TWL6030_BASEADD_GASGAUGE }, { SUB_CHIP_ID1, TWL6030_BASEADD_PWM }, - { SUB_CHIP_ID2, TWL6030_BASEADD_RSV }, - { SUB_CHIP_ID2, TWL6030_BASEADD_RSV }, + { SUB_CHIP_ID0, TWL6030_BASEADD_ZERO }, + { SUB_CHIP_ID1, TWL6030_BASEADD_ZERO }, + { SUB_CHIP_ID2, TWL6030_BASEADD_ZERO }, + { SUB_CHIP_ID2, TWL6030_BASEADD_ZERO }, { SUB_CHIP_ID2, TWL6030_BASEADD_RSV }, { SUB_CHIP_ID2, TWL6030_BASEADD_RSV }, { SUB_CHIP_ID2, TWL6030_BASEADD_RSV }, @@ -588,18 +584,6 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) struct device *child; unsigned sub_chip_id; - if (twl_has_bci() && pdata->bci && - !(features & (TPS_SUBSET | TWL5031))) { - child = add_child(3, "twl4030_bci", - pdata->bci, sizeof(*pdata->bci), - false, - /* irq0 = CHG_PRES, irq1 = BCI */ - pdata->irq_base + BCI_PRES_INTR_OFFSET, - pdata->irq_base + BCI_INTR_OFFSET); - if (IS_ERR(child)) - return PTR_ERR(child); - } - if (twl_has_gpio() && pdata->gpio) { child = add_child(SUB_CHIP_ID1, "twl4030_gpio", pdata->gpio, sizeof(*pdata->gpio), @@ -977,6 +961,7 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id) int status; unsigned i; struct twl4030_platform_data *pdata = client->dev.platform_data; + u8 temp; if (!pdata) { dev_dbg(&client->dev, "no platform data?\n"); @@ -1044,6 +1029,18 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id) goto fail; } + /* Disable TWL4030/TWL5030 I2C Pull-up on I2C1 and I2C4(SR) interface. + * Program I2C_SCL_CTRL_PU(bit 0)=0, I2C_SDA_CTRL_PU (bit 2)=0, + * SR_I2C_SCL_CTRL_PU(bit 4)=0 and SR_I2C_SDA_CTRL_PU(bit 6)=0. + */ + + if (twl_class_is_4030()) { + twl_i2c_read_u8(TWL4030_MODULE_INTBR, &temp, REG_GPPUPDCTR1); + temp &= ~(SR_I2C_SDA_CTRL_PU | SR_I2C_SCL_CTRL_PU | \ + I2C_SDA_CTRL_PU | I2C_SCL_CTRL_PU); + twl_i2c_write_u8(TWL4030_MODULE_INTBR, temp, REG_GPPUPDCTR1); + } + status = add_children(pdata, id->driver_data); fail: if (status < 0) diff --git a/drivers/mfd/twl4030-power.c b/drivers/mfd/twl4030-power.c index 0815292..7efa878 100644 --- a/drivers/mfd/twl4030-power.c +++ b/drivers/mfd/twl4030-power.c @@ -405,7 +405,7 @@ static int __init twl4030_configure_resource(struct twl4030_resconfig *rconfig) if (rconfig->remap_sleep != TWL4030_RESCONFIG_UNDEF) { remap &= ~SLEEP_STATE_MASK; - remap |= rconfig->remap_off << SLEEP_STATE_SHIFT; + remap |= rconfig->remap_sleep << SLEEP_STATE_SHIFT; } err = twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, @@ -461,6 +461,56 @@ out: return err; } +int twl4030_remove_script(u8 flags) +{ + int err = 0; + + err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, R_KEY_1, + R_PROTECT_KEY); + if (err) { + pr_err("twl4030: unable to unlock PROTECT_KEY\n"); + return err; + } + + err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, R_KEY_2, + R_PROTECT_KEY); + if (err) { + pr_err("twl4030: unable to unlock PROTECT_KEY\n"); + return err; + } + + if (flags & TWL4030_WRST_SCRIPT) { + err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, END_OF_SCRIPT, + R_SEQ_ADD_WARM); + if (err) + return err; + } + if (flags & TWL4030_WAKEUP12_SCRIPT) { + if (err) + err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, END_OF_SCRIPT, + R_SEQ_ADD_S2A12); + return err; + } + if (flags & TWL4030_WAKEUP3_SCRIPT) { + err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, END_OF_SCRIPT, + R_SEQ_ADD_S2A3); + if (err) + return err; + } + if (flags & TWL4030_SLEEP_SCRIPT) { + err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, END_OF_SCRIPT, + R_SEQ_ADD_A2S); + if (err) + return err; + } + + err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0, R_PROTECT_KEY); + if (err) + pr_err("TWL4030 Unable to relock registers\n"); + + return err; +} + void __init twl4030_power_init(struct twl4030_power_data *twl4030_scripts) { int err = 0; diff --git a/drivers/mfd/ucb1x00-core.c b/drivers/mfd/ucb1x00-core.c index 252b741..b281217 100644 --- a/drivers/mfd/ucb1x00-core.c +++ b/drivers/mfd/ucb1x00-core.c @@ -27,6 +27,7 @@ #include <linux/mutex.h> #include <linux/mfd/ucb1x00.h> #include <linux/gpio.h> +#include <linux/semaphore.h> #include <mach/dma.h> #include <mach/hardware.h> diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c index 4b2021a..07101e9 100644 --- a/drivers/mfd/wm831x-core.c +++ b/drivers/mfd/wm831x-core.c @@ -321,7 +321,6 @@ EXPORT_SYMBOL_GPL(wm831x_set_bits); */ int wm831x_auxadc_read(struct wm831x *wm831x, enum wm831x_auxadc input) { - int tries = 10; int ret, src; mutex_lock(&wm831x->auxadc_lock); @@ -349,13 +348,14 @@ int wm831x_auxadc_read(struct wm831x *wm831x, enum wm831x_auxadc input) goto disable; } - do { - msleep(1); + /* Ignore the result to allow us to soldier on without IRQ hookup */ + wait_for_completion_timeout(&wm831x->auxadc_done, msecs_to_jiffies(5)); - ret = wm831x_reg_read(wm831x, WM831X_AUXADC_CONTROL); - if (ret < 0) - ret = WM831X_AUX_CVT_ENA; - } while ((ret & WM831X_AUX_CVT_ENA) && --tries); + ret = wm831x_reg_read(wm831x, WM831X_AUXADC_CONTROL); + if (ret < 0) { + dev_err(wm831x->dev, "AUXADC status read failed: %d\n", ret); + goto disable; + } if (ret & WM831X_AUX_CVT_ENA) { dev_err(wm831x->dev, "Timed out reading AUXADC\n"); @@ -390,6 +390,15 @@ out: } EXPORT_SYMBOL_GPL(wm831x_auxadc_read); +static irqreturn_t wm831x_auxadc_irq(int irq, void *irq_data) +{ + struct wm831x *wm831x = irq_data; + + complete(&wm831x->auxadc_done); + + return IRQ_HANDLED; +} + /** * wm831x_auxadc_read_uv: Read a voltage from the WM831x AUXADC * @@ -1411,6 +1420,7 @@ static int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq) mutex_init(&wm831x->io_lock); mutex_init(&wm831x->key_lock); mutex_init(&wm831x->auxadc_lock); + init_completion(&wm831x->auxadc_done); dev_set_drvdata(wm831x->dev, wm831x); ret = wm831x_reg_read(wm831x, WM831X_PARENT_ID); @@ -1449,18 +1459,33 @@ static int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq) case WM8310: parent = WM8310; wm831x->num_gpio = 16; + if (rev > 0) { + wm831x->has_gpio_ena = 1; + wm831x->has_cs_sts = 1; + } + dev_info(wm831x->dev, "WM8310 revision %c\n", 'A' + rev); break; case WM8311: parent = WM8311; wm831x->num_gpio = 16; + if (rev > 0) { + wm831x->has_gpio_ena = 1; + wm831x->has_cs_sts = 1; + } + dev_info(wm831x->dev, "WM8311 revision %c\n", 'A' + rev); break; case WM8312: parent = WM8312; wm831x->num_gpio = 16; + if (rev > 0) { + wm831x->has_gpio_ena = 1; + wm831x->has_cs_sts = 1; + } + dev_info(wm831x->dev, "WM8312 revision %c\n", 'A' + rev); break; @@ -1508,6 +1533,16 @@ static int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq) if (ret != 0) goto err; + if (wm831x->irq_base) { + ret = request_threaded_irq(wm831x->irq_base + + WM831X_IRQ_AUXADC_DATA, + NULL, wm831x_auxadc_irq, 0, + "auxadc", wm831x); + if (ret < 0) + dev_err(wm831x->dev, "AUXADC IRQ request failed: %d\n", + ret); + } + /* The core device is up, instantiate the subdevices. */ switch (parent) { case WM8310: @@ -1578,6 +1613,8 @@ static void wm831x_device_exit(struct wm831x *wm831x) { wm831x_otp_exit(wm831x); mfd_remove_devices(wm831x->dev); + if (wm831x->irq_base) + free_irq(wm831x->irq_base + WM831X_IRQ_AUXADC_DATA, wm831x); wm831x_irq_exit(wm831x); kfree(wm831x); } diff --git a/drivers/mfd/wm8350-core.c b/drivers/mfd/wm8350-core.c index 9a970bd..bd75807 100644 --- a/drivers/mfd/wm8350-core.c +++ b/drivers/mfd/wm8350-core.c @@ -339,7 +339,6 @@ EXPORT_SYMBOL_GPL(wm8350_reg_unlock); int wm8350_read_auxadc(struct wm8350 *wm8350, int channel, int scale, int vref) { u16 reg, result = 0; - int tries = 5; if (channel < WM8350_AUXADC_AUX1 || channel > WM8350_AUXADC_TEMP) return -EINVAL; @@ -363,12 +362,13 @@ int wm8350_read_auxadc(struct wm8350 *wm8350, int channel, int scale, int vref) reg |= 1 << channel | WM8350_AUXADC_POLL; wm8350_reg_write(wm8350, WM8350_DIGITISER_CONTROL_1, reg); - do { - schedule_timeout_interruptible(1); - reg = wm8350_reg_read(wm8350, WM8350_DIGITISER_CONTROL_1); - } while ((reg & WM8350_AUXADC_POLL) && --tries); + /* We ignore the result of the completion and just check for a + * conversion result, allowing us to soldier on if the IRQ + * infrastructure is not set up for the chip. */ + wait_for_completion_timeout(&wm8350->auxadc_done, msecs_to_jiffies(5)); - if (!tries) + reg = wm8350_reg_read(wm8350, WM8350_DIGITISER_CONTROL_1); + if (reg & WM8350_AUXADC_POLL) dev_err(wm8350->dev, "adc chn %d read timeout\n", channel); else result = wm8350_reg_read(wm8350, @@ -385,6 +385,15 @@ int wm8350_read_auxadc(struct wm8350 *wm8350, int channel, int scale, int vref) } EXPORT_SYMBOL_GPL(wm8350_read_auxadc); +static irqreturn_t wm8350_auxadc_irq(int irq, void *irq_data) +{ + struct wm8350 *wm8350 = irq_data; + + complete(&wm8350->auxadc_done); + + return IRQ_HANDLED; +} + /* * Cache is always host endian. */ @@ -682,11 +691,22 @@ int wm8350_device_init(struct wm8350 *wm8350, int irq, } mutex_init(&wm8350->auxadc_mutex); + init_completion(&wm8350->auxadc_done); ret = wm8350_irq_init(wm8350, irq, pdata); if (ret < 0) goto err; + if (wm8350->irq_base) { + ret = request_threaded_irq(wm8350->irq_base + + WM8350_IRQ_AUXADC_DATARDY, + NULL, wm8350_auxadc_irq, 0, + "auxadc", wm8350); + if (ret < 0) + dev_warn(wm8350->dev, + "Failed to request AUXADC IRQ: %d\n", ret); + } + if (pdata && pdata->init) { ret = pdata->init(wm8350); if (ret != 0) { @@ -736,6 +756,9 @@ void wm8350_device_exit(struct wm8350 *wm8350) platform_device_unregister(wm8350->gpio.pdev); platform_device_unregister(wm8350->codec.pdev); + if (wm8350->irq_base) + free_irq(wm8350->irq_base + WM8350_IRQ_AUXADC_DATARDY, wm8350); + wm8350_irq_exit(wm8350); kfree(wm8350->reg_cache); diff --git a/drivers/mfd/wm8350-irq.c b/drivers/mfd/wm8350-irq.c index 9025f29..f56c9ad 100644 --- a/drivers/mfd/wm8350-irq.c +++ b/drivers/mfd/wm8350-irq.c @@ -18,7 +18,7 @@ #include <linux/bug.h> #include <linux/device.h> #include <linux/interrupt.h> -#include <linux/workqueue.h> +#include <linux/irq.h> #include <linux/mfd/wm8350/core.h> #include <linux/mfd/wm8350/audio.h> @@ -29,8 +29,6 @@ #include <linux/mfd/wm8350/supply.h> #include <linux/mfd/wm8350/wdt.h> -#define WM8350_NUM_IRQ_REGS 7 - #define WM8350_INT_OFFSET_1 0 #define WM8350_INT_OFFSET_2 1 #define WM8350_POWER_UP_INT_OFFSET 2 @@ -366,19 +364,10 @@ static struct wm8350_irq_data wm8350_irqs[] = { }, }; -static void wm8350_irq_call_handler(struct wm8350 *wm8350, int irq) +static inline struct wm8350_irq_data *irq_to_wm8350_irq(struct wm8350 *wm8350, + int irq) { - mutex_lock(&wm8350->irq_mutex); - - if (wm8350->irq[irq].handler) - wm8350->irq[irq].handler(irq, wm8350->irq[irq].data); - else { - dev_err(wm8350->dev, "irq %d nobody cared. now masked.\n", - irq); - wm8350_mask_irq(wm8350, irq); - } - - mutex_unlock(&wm8350->irq_mutex); + return &wm8350_irqs[irq - wm8350->irq_base]; } /* @@ -386,7 +375,9 @@ static void wm8350_irq_call_handler(struct wm8350 *wm8350, int irq) * interrupts are clear on read the IRQ line will be reasserted and * the physical IRQ will be handled again if another interrupt is * asserted while we run - in the normal course of events this is a - * rare occurrence so we save I2C/SPI reads. + * rare occurrence so we save I2C/SPI reads. We're also assuming that + * it's rare to get lots of interrupts firing simultaneously so try to + * minimise I/O. */ static irqreturn_t wm8350_irq(int irq, void *irq_data) { @@ -397,7 +388,6 @@ static irqreturn_t wm8350_irq(int irq, void *irq_data) struct wm8350_irq_data *data; int i; - /* TODO: Use block reads to improve performance? */ level_one = wm8350_reg_read(wm8350, WM8350_SYSTEM_INTERRUPTS) & ~wm8350_reg_read(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK); @@ -416,93 +406,101 @@ static irqreturn_t wm8350_irq(int irq, void *irq_data) sub_reg[data->reg] = wm8350_reg_read(wm8350, WM8350_INT_STATUS_1 + data->reg); - sub_reg[data->reg] &= - ~wm8350_reg_read(wm8350, - WM8350_INT_STATUS_1_MASK + - data->reg); + sub_reg[data->reg] &= ~wm8350->irq_masks[data->reg]; read_done[data->reg] = 1; } if (sub_reg[data->reg] & data->mask) - wm8350_irq_call_handler(wm8350, i); + handle_nested_irq(wm8350->irq_base + i); } return IRQ_HANDLED; } -int wm8350_register_irq(struct wm8350 *wm8350, int irq, - irq_handler_t handler, unsigned long flags, - const char *name, void *data) +static void wm8350_irq_lock(unsigned int irq) { - if (irq < 0 || irq >= WM8350_NUM_IRQ || !handler) - return -EINVAL; - - if (wm8350->irq[irq].handler) - return -EBUSY; - - mutex_lock(&wm8350->irq_mutex); - wm8350->irq[irq].handler = handler; - wm8350->irq[irq].data = data; - mutex_unlock(&wm8350->irq_mutex); - - wm8350_unmask_irq(wm8350, irq); + struct wm8350 *wm8350 = get_irq_chip_data(irq); - return 0; + mutex_lock(&wm8350->irq_lock); } -EXPORT_SYMBOL_GPL(wm8350_register_irq); -int wm8350_free_irq(struct wm8350 *wm8350, int irq) +static void wm8350_irq_sync_unlock(unsigned int irq) { - if (irq < 0 || irq >= WM8350_NUM_IRQ) - return -EINVAL; + struct wm8350 *wm8350 = get_irq_chip_data(irq); + int i; - wm8350_mask_irq(wm8350, irq); + for (i = 0; i < ARRAY_SIZE(wm8350->irq_masks); i++) { + /* If there's been a change in the mask write it back + * to the hardware. */ + if (wm8350->irq_masks[i] != + wm8350->reg_cache[WM8350_INT_STATUS_1_MASK + i]) + WARN_ON(wm8350_reg_write(wm8350, + WM8350_INT_STATUS_1_MASK + i, + wm8350->irq_masks[i])); + } - mutex_lock(&wm8350->irq_mutex); - wm8350->irq[irq].handler = NULL; - mutex_unlock(&wm8350->irq_mutex); - return 0; + mutex_unlock(&wm8350->irq_lock); } -EXPORT_SYMBOL_GPL(wm8350_free_irq); -int wm8350_mask_irq(struct wm8350 *wm8350, int irq) +static void wm8350_irq_enable(unsigned int irq) { - return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK + - wm8350_irqs[irq].reg, - wm8350_irqs[irq].mask); + struct wm8350 *wm8350 = get_irq_chip_data(irq); + struct wm8350_irq_data *irq_data = irq_to_wm8350_irq(wm8350, irq); + + wm8350->irq_masks[irq_data->reg] &= ~irq_data->mask; } -EXPORT_SYMBOL_GPL(wm8350_mask_irq); -int wm8350_unmask_irq(struct wm8350 *wm8350, int irq) +static void wm8350_irq_disable(unsigned int irq) { - return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK + - wm8350_irqs[irq].reg, - wm8350_irqs[irq].mask); + struct wm8350 *wm8350 = get_irq_chip_data(irq); + struct wm8350_irq_data *irq_data = irq_to_wm8350_irq(wm8350, irq); + + wm8350->irq_masks[irq_data->reg] |= irq_data->mask; } -EXPORT_SYMBOL_GPL(wm8350_unmask_irq); + +static struct irq_chip wm8350_irq_chip = { + .name = "wm8350", + .bus_lock = wm8350_irq_lock, + .bus_sync_unlock = wm8350_irq_sync_unlock, + .disable = wm8350_irq_disable, + .enable = wm8350_irq_enable, +}; int wm8350_irq_init(struct wm8350 *wm8350, int irq, struct wm8350_platform_data *pdata) { - int ret; + int ret, cur_irq, i; int flags = IRQF_ONESHOT; if (!irq) { - dev_err(wm8350->dev, "No IRQ configured\n"); - return -EINVAL; + dev_warn(wm8350->dev, "No interrupt support, no core IRQ\n"); + return 0; + } + + if (!pdata || !pdata->irq_base) { + dev_warn(wm8350->dev, "No interrupt support, no IRQ base\n"); + return 0; } + /* Mask top level interrupts */ wm8350_reg_write(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK, 0xFFFF); - wm8350_reg_write(wm8350, WM8350_INT_STATUS_1_MASK, 0xFFFF); - wm8350_reg_write(wm8350, WM8350_INT_STATUS_2_MASK, 0xFFFF); - wm8350_reg_write(wm8350, WM8350_UNDER_VOLTAGE_INT_STATUS_MASK, 0xFFFF); - wm8350_reg_write(wm8350, WM8350_GPIO_INT_STATUS_MASK, 0xFFFF); - wm8350_reg_write(wm8350, WM8350_COMPARATOR_INT_STATUS_MASK, 0xFFFF); - mutex_init(&wm8350->irq_mutex); + /* Mask all individual interrupts by default and cache the + * masks. We read the masks back since there are unwritable + * bits in the mask registers. */ + for (i = 0; i < ARRAY_SIZE(wm8350->irq_masks); i++) { + wm8350_reg_write(wm8350, WM8350_INT_STATUS_1_MASK + i, + 0xFFFF); + wm8350->irq_masks[i] = + wm8350_reg_read(wm8350, + WM8350_INT_STATUS_1_MASK + i); + } + + mutex_init(&wm8350->irq_lock); wm8350->chip_irq = irq; + wm8350->irq_base = pdata->irq_base; - if (pdata && pdata->irq_high) { + if (pdata->irq_high) { flags |= IRQF_TRIGGER_HIGH; wm8350_set_bits(wm8350, WM8350_SYSTEM_CONTROL_1, @@ -514,11 +512,32 @@ int wm8350_irq_init(struct wm8350 *wm8350, int irq, WM8350_IRQ_POL); } + /* Register with genirq */ + for (cur_irq = wm8350->irq_base; + cur_irq < ARRAY_SIZE(wm8350_irqs) + wm8350->irq_base; + cur_irq++) { + set_irq_chip_data(cur_irq, wm8350); + set_irq_chip_and_handler(cur_irq, &wm8350_irq_chip, + handle_edge_irq); + set_irq_nested_thread(cur_irq, 1); + + /* ARM needs us to explicitly flag the IRQ as valid + * and will set them noprobe when we do so. */ +#ifdef CONFIG_ARM + set_irq_flags(cur_irq, IRQF_VALID); +#else + set_irq_noprobe(cur_irq); +#endif + } + ret = request_threaded_irq(irq, NULL, wm8350_irq, flags, "wm8350", wm8350); if (ret != 0) dev_err(wm8350->dev, "Failed to request IRQ: %d\n", ret); + /* Allow interrupts to fire */ + wm8350_reg_write(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK, 0); + return ret; } diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c new file mode 100644 index 0000000..844e1c1 --- /dev/null +++ b/drivers/mfd/wm8994-core.c @@ -0,0 +1,537 @@ +/* + * wm8994-core.c -- Device access for Wolfson WM8994 + * + * Copyright 2009 Wolfson Microelectronics PLC. + * + * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/i2c.h> +#include <linux/delay.h> +#include <linux/mfd/core.h> +#include <linux/regulator/consumer.h> +#include <linux/regulator/machine.h> + +#include <linux/mfd/wm8994/core.h> +#include <linux/mfd/wm8994/pdata.h> +#include <linux/mfd/wm8994/registers.h> + +static int wm8994_read(struct wm8994 *wm8994, unsigned short reg, + int bytes, void *dest) +{ + int ret, i; + u16 *buf = dest; + + BUG_ON(bytes % 2); + BUG_ON(bytes <= 0); + + ret = wm8994->read_dev(wm8994, reg, bytes, dest); + if (ret < 0) + return ret; + + for (i = 0; i < bytes / 2; i++) { + buf[i] = be16_to_cpu(buf[i]); + + dev_vdbg(wm8994->dev, "Read %04x from R%d(0x%x)\n", + buf[i], reg + i, reg + i); + } + + return 0; +} + +/** + * wm8994_reg_read: Read a single WM8994 register. + * + * @wm8994: Device to read from. + * @reg: Register to read. + */ +int wm8994_reg_read(struct wm8994 *wm8994, unsigned short reg) +{ + unsigned short val; + int ret; + + mutex_lock(&wm8994->io_lock); + + ret = wm8994_read(wm8994, reg, 2, &val); + + mutex_unlock(&wm8994->io_lock); + + if (ret < 0) + return ret; + else + return val; +} +EXPORT_SYMBOL_GPL(wm8994_reg_read); + +/** + * wm8994_bulk_read: Read multiple WM8994 registers + * + * @wm8994: Device to read from + * @reg: First register + * @count: Number of registers + * @buf: Buffer to fill. + */ +int wm8994_bulk_read(struct wm8994 *wm8994, unsigned short reg, + int count, u16 *buf) +{ + int ret; + + mutex_lock(&wm8994->io_lock); + + ret = wm8994_read(wm8994, reg, count * 2, buf); + + mutex_unlock(&wm8994->io_lock); + + return ret; +} +EXPORT_SYMBOL_GPL(wm8994_bulk_read); + +static int wm8994_write(struct wm8994 *wm8994, unsigned short reg, + int bytes, void *src) +{ + u16 *buf = src; + int i; + + BUG_ON(bytes % 2); + BUG_ON(bytes <= 0); + + for (i = 0; i < bytes / 2; i++) { + dev_vdbg(wm8994->dev, "Write %04x to R%d(0x%x)\n", + buf[i], reg + i, reg + i); + + buf[i] = cpu_to_be16(buf[i]); + } + + return wm8994->write_dev(wm8994, reg, bytes, src); +} + +/** + * wm8994_reg_write: Write a single WM8994 register. + * + * @wm8994: Device to write to. + * @reg: Register to write to. + * @val: Value to write. + */ +int wm8994_reg_write(struct wm8994 *wm8994, unsigned short reg, + unsigned short val) +{ + int ret; + + mutex_lock(&wm8994->io_lock); + + ret = wm8994_write(wm8994, reg, 2, &val); + + mutex_unlock(&wm8994->io_lock); + + return ret; +} +EXPORT_SYMBOL_GPL(wm8994_reg_write); + +/** + * wm8994_set_bits: Set the value of a bitfield in a WM8994 register + * + * @wm8994: Device to write to. + * @reg: Register to write to. + * @mask: Mask of bits to set. + * @val: Value to set (unshifted) + */ +int wm8994_set_bits(struct wm8994 *wm8994, unsigned short reg, + unsigned short mask, unsigned short val) +{ + int ret; + u16 r; + + mutex_lock(&wm8994->io_lock); + + ret = wm8994_read(wm8994, reg, 2, &r); + if (ret < 0) + goto out; + + r &= ~mask; + r |= val; + + ret = wm8994_write(wm8994, reg, 2, &r); + +out: + mutex_unlock(&wm8994->io_lock); + + return ret; +} +EXPORT_SYMBOL_GPL(wm8994_set_bits); + +static struct mfd_cell wm8994_regulator_devs[] = { + { .name = "wm8994-ldo", .id = 1 }, + { .name = "wm8994-ldo", .id = 2 }, +}; + +static struct mfd_cell wm8994_devs[] = { + { .name = "wm8994-codec" }, + { .name = "wm8994-gpio" }, +}; + +/* + * Supplies for the main bulk of CODEC; the LDO supplies are ignored + * and should be handled via the standard regulator API supply + * management. + */ +static const char *wm8994_main_supplies[] = { + "DBVDD", + "DCVDD", + "AVDD1", + "AVDD2", + "CPVDD", + "SPKVDD1", + "SPKVDD2", +}; + +#ifdef CONFIG_PM +static int wm8994_device_suspend(struct device *dev) +{ + struct wm8994 *wm8994 = dev_get_drvdata(dev); + int ret; + + /* GPIO configuration state is saved here since we may be configuring + * the GPIO alternate functions even if we're not using the gpiolib + * driver for them. + */ + ret = wm8994_read(wm8994, WM8994_GPIO_1, WM8994_NUM_GPIO_REGS * 2, + &wm8994->gpio_regs); + if (ret < 0) + dev_err(dev, "Failed to save GPIO registers: %d\n", ret); + + /* For similar reasons we also stash the regulator states */ + ret = wm8994_read(wm8994, WM8994_LDO_1, WM8994_NUM_LDO_REGS * 2, + &wm8994->ldo_regs); + if (ret < 0) + dev_err(dev, "Failed to save LDO registers: %d\n", ret); + + ret = regulator_bulk_disable(ARRAY_SIZE(wm8994_main_supplies), + wm8994->supplies); + if (ret != 0) { + dev_err(dev, "Failed to disable supplies: %d\n", ret); + return ret; + } + + return 0; +} + +static int wm8994_device_resume(struct device *dev) +{ + struct wm8994 *wm8994 = dev_get_drvdata(dev); + int ret; + + ret = regulator_bulk_enable(ARRAY_SIZE(wm8994_main_supplies), + wm8994->supplies); + if (ret != 0) { + dev_err(dev, "Failed to enable supplies: %d\n", ret); + return ret; + } + + ret = wm8994_write(wm8994, WM8994_LDO_1, WM8994_NUM_LDO_REGS * 2, + &wm8994->ldo_regs); + if (ret < 0) + dev_err(dev, "Failed to restore LDO registers: %d\n", ret); + + ret = wm8994_write(wm8994, WM8994_GPIO_1, WM8994_NUM_GPIO_REGS * 2, + &wm8994->gpio_regs); + if (ret < 0) + dev_err(dev, "Failed to restore GPIO registers: %d\n", ret); + + return 0; +} +#endif + +#ifdef CONFIG_REGULATOR +static int wm8994_ldo_in_use(struct wm8994_pdata *pdata, int ldo) +{ + struct wm8994_ldo_pdata *ldo_pdata; + + if (!pdata) + return 0; + + ldo_pdata = &pdata->ldo[ldo]; + + if (!ldo_pdata->init_data) + return 0; + + return ldo_pdata->init_data->num_consumer_supplies != 0; +} +#else +static int wm8994_ldo_in_use(struct wm8994_pdata *pdata, int ldo) +{ + return 0; +} +#endif + +/* + * Instantiate the generic non-control parts of the device. + */ +static int wm8994_device_init(struct wm8994 *wm8994, unsigned long id, int irq) +{ + struct wm8994_pdata *pdata = wm8994->dev->platform_data; + int ret, i; + + mutex_init(&wm8994->io_lock); + dev_set_drvdata(wm8994->dev, wm8994); + + /* Add the on-chip regulators first for bootstrapping */ + ret = mfd_add_devices(wm8994->dev, -1, + wm8994_regulator_devs, + ARRAY_SIZE(wm8994_regulator_devs), + NULL, 0); + if (ret != 0) { + dev_err(wm8994->dev, "Failed to add children: %d\n", ret); + goto err; + } + + wm8994->supplies = kzalloc(sizeof(struct regulator_bulk_data) * + ARRAY_SIZE(wm8994_main_supplies), + GFP_KERNEL); + if (!wm8994->supplies) + goto err; + + for (i = 0; i < ARRAY_SIZE(wm8994_main_supplies); i++) + wm8994->supplies[i].supply = wm8994_main_supplies[i]; + + ret = regulator_bulk_get(wm8994->dev, ARRAY_SIZE(wm8994_main_supplies), + wm8994->supplies); + if (ret != 0) { + dev_err(wm8994->dev, "Failed to get supplies: %d\n", ret); + goto err_supplies; + } + + ret = regulator_bulk_enable(ARRAY_SIZE(wm8994_main_supplies), + wm8994->supplies); + if (ret != 0) { + dev_err(wm8994->dev, "Failed to enable supplies: %d\n", ret); + goto err_get; + } + + ret = wm8994_reg_read(wm8994, WM8994_SOFTWARE_RESET); + if (ret < 0) { + dev_err(wm8994->dev, "Failed to read ID register\n"); + goto err_enable; + } + if (ret != 0x8994) { + dev_err(wm8994->dev, "Device is not a WM8994, ID is %x\n", + ret); + ret = -EINVAL; + goto err_enable; + } + + ret = wm8994_reg_read(wm8994, WM8994_CHIP_REVISION); + if (ret < 0) { + dev_err(wm8994->dev, "Failed to read revision register: %d\n", + ret); + goto err_enable; + } + + switch (ret) { + case 0: + case 1: + dev_warn(wm8994->dev, "revision %c not fully supported\n", + 'A' + ret); + break; + default: + dev_info(wm8994->dev, "revision %c\n", 'A' + ret); + break; + } + + + if (pdata) { + wm8994->gpio_base = pdata->gpio_base; + + /* GPIO configuration is only applied if it's non-zero */ + for (i = 0; i < ARRAY_SIZE(pdata->gpio_defaults); i++) { + if (pdata->gpio_defaults[i]) { + wm8994_set_bits(wm8994, WM8994_GPIO_1 + i, + 0xffff, + pdata->gpio_defaults[i]); + } + } + } + + /* In some system designs where the regulators are not in use, + * we can achieve a small reduction in leakage currents by + * floating LDO outputs. This bit makes no difference if the + * LDOs are enabled, it only affects cases where the LDOs were + * in operation and are then disabled. + */ + for (i = 0; i < WM8994_NUM_LDO_REGS; i++) { + if (wm8994_ldo_in_use(pdata, i)) + wm8994_set_bits(wm8994, WM8994_LDO_1 + i, + WM8994_LDO1_DISCH, WM8994_LDO1_DISCH); + else + wm8994_set_bits(wm8994, WM8994_LDO_1 + i, + WM8994_LDO1_DISCH, 0); + } + + ret = mfd_add_devices(wm8994->dev, -1, + wm8994_devs, ARRAY_SIZE(wm8994_devs), + NULL, 0); + if (ret != 0) { + dev_err(wm8994->dev, "Failed to add children: %d\n", ret); + goto err_enable; + } + + return 0; + +err_enable: + regulator_bulk_disable(ARRAY_SIZE(wm8994_main_supplies), + wm8994->supplies); +err_get: + regulator_bulk_free(ARRAY_SIZE(wm8994_main_supplies), wm8994->supplies); +err_supplies: + kfree(wm8994->supplies); +err: + mfd_remove_devices(wm8994->dev); + kfree(wm8994); + return ret; +} + +static void wm8994_device_exit(struct wm8994 *wm8994) +{ + mfd_remove_devices(wm8994->dev); + regulator_bulk_disable(ARRAY_SIZE(wm8994_main_supplies), + wm8994->supplies); + regulator_bulk_free(ARRAY_SIZE(wm8994_main_supplies), wm8994->supplies); + kfree(wm8994->supplies); + kfree(wm8994); +} + +static int wm8994_i2c_read_device(struct wm8994 *wm8994, unsigned short reg, + int bytes, void *dest) +{ + struct i2c_client *i2c = wm8994->control_data; + int ret; + u16 r = cpu_to_be16(reg); + + ret = i2c_master_send(i2c, (unsigned char *)&r, 2); + if (ret < 0) + return ret; + if (ret != 2) + return -EIO; + + ret = i2c_master_recv(i2c, dest, bytes); + if (ret < 0) + return ret; + if (ret != bytes) + return -EIO; + return 0; +} + +/* Currently we allocate the write buffer on the stack; this is OK for + * small writes - if we need to do large writes this will need to be + * revised. + */ +static int wm8994_i2c_write_device(struct wm8994 *wm8994, unsigned short reg, + int bytes, void *src) +{ + struct i2c_client *i2c = wm8994->control_data; + unsigned char msg[bytes + 2]; + int ret; + + reg = cpu_to_be16(reg); + memcpy(&msg[0], ®, 2); + memcpy(&msg[2], src, bytes); + + ret = i2c_master_send(i2c, msg, bytes + 2); + if (ret < 0) + return ret; + if (ret < bytes + 2) + return -EIO; + + return 0; +} + +static int wm8994_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + struct wm8994 *wm8994; + + wm8994 = kzalloc(sizeof(struct wm8994), GFP_KERNEL); + if (wm8994 == NULL) { + kfree(i2c); + return -ENOMEM; + } + + i2c_set_clientdata(i2c, wm8994); + wm8994->dev = &i2c->dev; + wm8994->control_data = i2c; + wm8994->read_dev = wm8994_i2c_read_device; + wm8994->write_dev = wm8994_i2c_write_device; + + return wm8994_device_init(wm8994, id->driver_data, i2c->irq); +} + +static int wm8994_i2c_remove(struct i2c_client *i2c) +{ + struct wm8994 *wm8994 = i2c_get_clientdata(i2c); + + wm8994_device_exit(wm8994); + + return 0; +} + +#ifdef CONFIG_PM +static int wm8994_i2c_suspend(struct i2c_client *i2c, pm_message_t state) +{ + return wm8994_device_suspend(&i2c->dev); +} + +static int wm8994_i2c_resume(struct i2c_client *i2c) +{ + return wm8994_device_resume(&i2c->dev); +} +#else +#define wm8994_i2c_suspend NULL +#define wm8994_i2c_resume NULL +#endif + +static const struct i2c_device_id wm8994_i2c_id[] = { + { "wm8994", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, wm8994_i2c_id); + +static struct i2c_driver wm8994_i2c_driver = { + .driver = { + .name = "wm8994", + .owner = THIS_MODULE, + }, + .probe = wm8994_i2c_probe, + .remove = wm8994_i2c_remove, + .suspend = wm8994_i2c_suspend, + .resume = wm8994_i2c_resume, + .id_table = wm8994_i2c_id, +}; + +static int __init wm8994_i2c_init(void) +{ + int ret; + + ret = i2c_add_driver(&wm8994_i2c_driver); + if (ret != 0) + pr_err("Failed to register wm8994 I2C driver: %d\n", ret); + + return ret; +} +module_init(wm8994_i2c_init); + +static void __exit wm8994_i2c_exit(void) +{ + i2c_del_driver(&wm8994_i2c_driver); +} +module_exit(wm8994_i2c_exit); + +MODULE_DESCRIPTION("Core support for the WM8994 audio CODEC"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 7b431bb..2e13b94 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -365,7 +365,7 @@ config MMC_SDRICOH_CS config MMC_TMIO tristate "Toshiba Mobile IO Controller (TMIO) MMC/SD function support" - depends on MFD_TMIO || MFD_ASIC3 || SUPERH + depends on MFD_TMIO || MFD_ASIC3 || MFD_SH_MOBILE_SDHI help This provides support for the SD/MMC cell found in TC6393XB, T7L66XB and also HTC ASIC3 diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c index e22c3fa..b2b577f 100644 --- a/drivers/mmc/host/tmio_mmc.c +++ b/drivers/mmc/host/tmio_mmc.c @@ -323,7 +323,7 @@ static irqreturn_t tmio_mmc_irq(int irq, void *devid) if (ireg & (TMIO_STAT_CARD_INSERT | TMIO_STAT_CARD_REMOVE)) { ack_mmc_irqs(host, TMIO_STAT_CARD_INSERT | TMIO_STAT_CARD_REMOVE); - mmc_detect_change(host->mmc, 0); + mmc_detect_change(host->mmc, msecs_to_jiffies(100)); } /* CRC and other errors */ @@ -550,6 +550,7 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev) mmc->ops = &tmio_mmc_ops; mmc->caps = MMC_CAP_4_BIT_DATA; + mmc->caps |= pdata->capabilities; mmc->f_max = pdata->hclk; mmc->f_min = mmc->f_max / 512; mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; @@ -568,14 +569,14 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev) if (ret >= 0) host->irq = ret; else - goto unmap_ctl; + goto cell_disable; disable_mmc_irqs(host, TMIO_MASK_ALL); ret = request_irq(host->irq, tmio_mmc_irq, IRQF_DISABLED | IRQF_TRIGGER_FALLING, dev_name(&dev->dev), host); if (ret) - goto unmap_ctl; + goto cell_disable; mmc_add_host(mmc); @@ -587,6 +588,9 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev) return 0; +cell_disable: + if (cell->disable) + cell->disable(dev); unmap_ctl: iounmap(host->ctl); host_free: @@ -597,6 +601,7 @@ out: static int __devexit tmio_mmc_remove(struct platform_device *dev) { + struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data; struct mmc_host *mmc = platform_get_drvdata(dev); platform_set_drvdata(dev, NULL); @@ -605,6 +610,8 @@ static int __devexit tmio_mmc_remove(struct platform_device *dev) struct tmio_mmc_host *host = mmc_priv(mmc); mmc_remove_host(mmc); free_irq(host->irq, host); + if (cell->disable) + cell->disable(dev); iounmap(host->ctl); mmc_free_host(mmc); } diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h index 692dc23..dafecfb 100644 --- a/drivers/mmc/host/tmio_mmc.h +++ b/drivers/mmc/host/tmio_mmc.h @@ -55,10 +55,8 @@ /* Define some IRQ masks */ /* This is the mask used at reset by the chip */ #define TMIO_MASK_ALL 0x837f031d -#define TMIO_MASK_READOP (TMIO_STAT_RXRDY | TMIO_STAT_DATAEND | \ - TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT) -#define TMIO_MASK_WRITEOP (TMIO_STAT_TXRQ | TMIO_STAT_DATAEND | \ - TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT) +#define TMIO_MASK_READOP (TMIO_STAT_RXRDY | TMIO_STAT_DATAEND) +#define TMIO_MASK_WRITEOP (TMIO_STAT_TXRQ | TMIO_STAT_DATAEND) #define TMIO_MASK_CMD (TMIO_STAT_CMDRESPEND | TMIO_STAT_CMDTIMEOUT | \ TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT) #define TMIO_MASK_IRQ (TMIO_MASK_READOP | TMIO_MASK_WRITEOP | TMIO_MASK_CMD) diff --git a/drivers/parisc/eisa_enumerator.c b/drivers/parisc/eisa_enumerator.c index 0be1d50..caa1531 100644 --- a/drivers/parisc/eisa_enumerator.c +++ b/drivers/parisc/eisa_enumerator.c @@ -460,7 +460,7 @@ static int init_slot(int slot, struct eeprom_eisa_slot_info *es) slot, id_string); print_eisa_id(id_string, es->eisa_slot_id); - printk(" expected %s \n", id_string); + printk(" expected %s\n", id_string); return -1; diff --git a/drivers/parisc/superio.c b/drivers/parisc/superio.c index a35c9c5..f7806d8 100644 --- a/drivers/parisc/superio.c +++ b/drivers/parisc/superio.c @@ -169,7 +169,7 @@ superio_init(struct pci_dev *pcidev) /* ...then properly fixup the USB to point at suckyio PIC */ sio->usb_pdev->irq = superio_fixup_irq(sio->usb_pdev); - printk(KERN_INFO PFX "Found NS87560 Legacy I/O device at %s (IRQ %i) \n", + printk(KERN_INFO PFX "Found NS87560 Legacy I/O device at %s (IRQ %i)\n", pci_name(pdev), pdev->irq); pci_read_config_dword (pdev, SIO_SP1BAR, &sio->sp1_base); diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index bf14672..faaa9b4 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -29,6 +29,13 @@ config APM_POWER Say Y here to enable support APM status emulation using battery class devices. +config MAX8925_POWER + tristate "MAX8925 battery charger support" + depends on MFD_MAX8925 + help + Say Y here to enable support for the battery charger in the Maxim + MAX8925 PMIC. + config WM831X_BACKUP tristate "WM831X backup battery charger support" depends on MFD_WM831X diff --git a/drivers/power/Makefile b/drivers/power/Makefile index 573597c..a2ba7c8 100644 --- a/drivers/power/Makefile +++ b/drivers/power/Makefile @@ -16,6 +16,7 @@ obj-$(CONFIG_POWER_SUPPLY) += power_supply.o obj-$(CONFIG_PDA_POWER) += pda_power.o obj-$(CONFIG_APM_POWER) += apm_power.o +obj-$(CONFIG_MAX8925_POWER) += max8925_power.o obj-$(CONFIG_WM831X_BACKUP) += wm831x_backup.o obj-$(CONFIG_WM831X_POWER) += wm831x_power.o obj-$(CONFIG_WM8350_POWER) += wm8350_power.o diff --git a/drivers/power/max8925_power.c b/drivers/power/max8925_power.c new file mode 100644 index 0000000..a1b4410 --- /dev/null +++ b/drivers/power/max8925_power.c @@ -0,0 +1,534 @@ +/* + * Battery driver for Maxim MAX8925 + * + * Copyright (c) 2009-2010 Marvell International Ltd. + * Haojian Zhuang <haojian.zhuang@marvell.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/module.h> +#include <linux/err.h> +#include <linux/i2c.h> +#include <linux/interrupt.h> +#include <linux/platform_device.h> +#include <linux/power_supply.h> +#include <linux/mfd/max8925.h> + +/* registers in GPM */ +#define MAX8925_OUT5VEN 0x54 +#define MAX8925_OUT3VEN 0x58 +#define MAX8925_CHG_CNTL1 0x7c + +/* bits definition */ +#define MAX8925_CHG_STAT_VSYSLOW (1 << 0) +#define MAX8925_CHG_STAT_MODE_MASK (3 << 2) +#define MAX8925_CHG_STAT_EN_MASK (1 << 4) +#define MAX8925_CHG_MBDET (1 << 1) +#define MAX8925_CHG_AC_RANGE_MASK (3 << 6) + +/* registers in ADC */ +#define MAX8925_ADC_RES_CNFG1 0x06 +#define MAX8925_ADC_AVG_CNFG1 0x07 +#define MAX8925_ADC_ACQ_CNFG1 0x08 +#define MAX8925_ADC_ACQ_CNFG2 0x09 +/* 2 bytes registers in below. MSB is 1st, LSB is 2nd. */ +#define MAX8925_ADC_AUX2 0x62 +#define MAX8925_ADC_VCHG 0x64 +#define MAX8925_ADC_VBBATT 0x66 +#define MAX8925_ADC_VMBATT 0x68 +#define MAX8925_ADC_ISNS 0x6a +#define MAX8925_ADC_THM 0x6c +#define MAX8925_ADC_TDIE 0x6e +#define MAX8925_CMD_AUX2 0xc8 +#define MAX8925_CMD_VCHG 0xd0 +#define MAX8925_CMD_VBBATT 0xd8 +#define MAX8925_CMD_VMBATT 0xe0 +#define MAX8925_CMD_ISNS 0xe8 +#define MAX8925_CMD_THM 0xf0 +#define MAX8925_CMD_TDIE 0xf8 + +enum { + MEASURE_AUX2, + MEASURE_VCHG, + MEASURE_VBBATT, + MEASURE_VMBATT, + MEASURE_ISNS, + MEASURE_THM, + MEASURE_TDIE, + MEASURE_MAX, +}; + +struct max8925_power_info { + struct max8925_chip *chip; + struct i2c_client *gpm; + struct i2c_client *adc; + + struct power_supply ac; + struct power_supply usb; + struct power_supply battery; + int irq_base; + unsigned ac_online:1; + unsigned usb_online:1; + unsigned bat_online:1; + unsigned chg_mode:2; + unsigned batt_detect:1; /* detecing MB by ID pin */ + unsigned topoff_threshold:2; + unsigned fast_charge:3; + + int (*set_charger) (int); +}; + +static int __set_charger(struct max8925_power_info *info, int enable) +{ + struct max8925_chip *chip = info->chip; + if (enable) { + /* enable charger in platform */ + if (info->set_charger) + info->set_charger(1); + /* enable charger */ + max8925_set_bits(info->gpm, MAX8925_CHG_CNTL1, 1 << 7, 0); + } else { + /* disable charge */ + max8925_set_bits(info->gpm, MAX8925_CHG_CNTL1, 1 << 7, 1 << 7); + if (info->set_charger) + info->set_charger(0); + } + dev_dbg(chip->dev, "%s\n", (enable) ? "Enable charger" + : "Disable charger"); + return 0; +} + +static irqreturn_t max8925_charger_handler(int irq, void *data) +{ + struct max8925_power_info *info = (struct max8925_power_info *)data; + struct max8925_chip *chip = info->chip; + + switch (irq - chip->irq_base) { + case MAX8925_IRQ_VCHG_DC_R: + info->ac_online = 1; + __set_charger(info, 1); + dev_dbg(chip->dev, "Adapter inserted\n"); + break; + case MAX8925_IRQ_VCHG_DC_F: + info->ac_online = 0; + __set_charger(info, 0); + dev_dbg(chip->dev, "Adapter is removal\n"); + break; + case MAX8925_IRQ_VCHG_USB_R: + info->usb_online = 1; + __set_charger(info, 1); + dev_dbg(chip->dev, "USB inserted\n"); + break; + case MAX8925_IRQ_VCHG_USB_F: + info->usb_online = 0; + __set_charger(info, 0); + dev_dbg(chip->dev, "USB is removal\n"); + break; + case MAX8925_IRQ_VCHG_THM_OK_F: + /* Battery is not ready yet */ + dev_dbg(chip->dev, "Battery temperature is out of range\n"); + case MAX8925_IRQ_VCHG_DC_OVP: + dev_dbg(chip->dev, "Error detection\n"); + __set_charger(info, 0); + break; + case MAX8925_IRQ_VCHG_THM_OK_R: + /* Battery is ready now */ + dev_dbg(chip->dev, "Battery temperature is in range\n"); + break; + case MAX8925_IRQ_VCHG_SYSLOW_R: + /* VSYS is low */ + dev_info(chip->dev, "Sys power is too low\n"); + break; + case MAX8925_IRQ_VCHG_SYSLOW_F: + dev_dbg(chip->dev, "Sys power is above low threshold\n"); + break; + case MAX8925_IRQ_VCHG_DONE: + __set_charger(info, 0); + dev_dbg(chip->dev, "Charging is done\n"); + break; + case MAX8925_IRQ_VCHG_TOPOFF: + dev_dbg(chip->dev, "Charging in top-off mode\n"); + break; + case MAX8925_IRQ_VCHG_TMR_FAULT: + __set_charger(info, 0); + dev_dbg(chip->dev, "Safe timer is expired\n"); + break; + case MAX8925_IRQ_VCHG_RST: + __set_charger(info, 0); + dev_dbg(chip->dev, "Charger is reset\n"); + break; + } + return IRQ_HANDLED; +} + +static int start_measure(struct max8925_power_info *info, int type) +{ + unsigned char buf[2] = {0, 0}; + int meas_reg = 0, ret; + + switch (type) { + case MEASURE_VCHG: + meas_reg = MAX8925_ADC_VCHG; + break; + case MEASURE_VBBATT: + meas_reg = MAX8925_ADC_VBBATT; + break; + case MEASURE_VMBATT: + meas_reg = MAX8925_ADC_VMBATT; + break; + case MEASURE_ISNS: + meas_reg = MAX8925_ADC_ISNS; + break; + default: + return -EINVAL; + } + + max8925_bulk_read(info->adc, meas_reg, 2, buf); + ret = (buf[0] << 4) | (buf[1] >> 4); + + return ret; +} + +static int max8925_ac_get_prop(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + struct max8925_power_info *info = dev_get_drvdata(psy->dev->parent); + int ret = 0; + + switch (psp) { + case POWER_SUPPLY_PROP_ONLINE: + val->intval = info->ac_online; + break; + case POWER_SUPPLY_PROP_VOLTAGE_NOW: + if (info->ac_online) { + ret = start_measure(info, MEASURE_VCHG); + if (ret >= 0) { + val->intval = ret << 1; /* unit is mV */ + goto out; + } + } + ret = -ENODATA; + break; + default: + ret = -ENODEV; + break; + } +out: + return ret; +} + +static enum power_supply_property max8925_ac_props[] = { + POWER_SUPPLY_PROP_ONLINE, + POWER_SUPPLY_PROP_VOLTAGE_NOW, +}; + +static int max8925_usb_get_prop(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + struct max8925_power_info *info = dev_get_drvdata(psy->dev->parent); + int ret = 0; + + switch (psp) { + case POWER_SUPPLY_PROP_ONLINE: + val->intval = info->usb_online; + break; + case POWER_SUPPLY_PROP_VOLTAGE_NOW: + if (info->usb_online) { + ret = start_measure(info, MEASURE_VCHG); + if (ret >= 0) { + val->intval = ret << 1; /* unit is mV */ + goto out; + } + } + ret = -ENODATA; + break; + default: + ret = -ENODEV; + break; + } +out: + return ret; +} + +static enum power_supply_property max8925_usb_props[] = { + POWER_SUPPLY_PROP_ONLINE, + POWER_SUPPLY_PROP_VOLTAGE_NOW, +}; + +static int max8925_bat_get_prop(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + struct max8925_power_info *info = dev_get_drvdata(psy->dev->parent); + long long int tmp = 0; + int ret = 0; + + switch (psp) { + case POWER_SUPPLY_PROP_ONLINE: + val->intval = info->bat_online; + break; + case POWER_SUPPLY_PROP_VOLTAGE_NOW: + if (info->bat_online) { + ret = start_measure(info, MEASURE_VMBATT); + if (ret >= 0) { + val->intval = ret << 1; /* unit is mV */ + ret = 0; + break; + } + } + ret = -ENODATA; + break; + case POWER_SUPPLY_PROP_CURRENT_NOW: + if (info->bat_online) { + ret = start_measure(info, MEASURE_ISNS); + if (ret >= 0) { + tmp = (long long int)ret * 6250 / 4096 - 3125; + ret = (int)tmp; + val->intval = 0; + if (ret > 0) + val->intval = ret; /* unit is mA */ + ret = 0; + break; + } + } + ret = -ENODATA; + break; + case POWER_SUPPLY_PROP_CHARGE_TYPE: + if (!info->bat_online) { + ret = -ENODATA; + break; + } + ret = max8925_reg_read(info->gpm, MAX8925_CHG_STATUS); + ret = (ret & MAX8925_CHG_STAT_MODE_MASK) >> 2; + switch (ret) { + case 1: + val->intval = POWER_SUPPLY_CHARGE_TYPE_FAST; + break; + case 0: + case 2: + val->intval = POWER_SUPPLY_CHARGE_TYPE_TRICKLE; + break; + case 3: + val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE; + break; + } + ret = 0; + break; + case POWER_SUPPLY_PROP_STATUS: + if (!info->bat_online) { + ret = -ENODATA; + break; + } + ret = max8925_reg_read(info->gpm, MAX8925_CHG_STATUS); + if (info->usb_online || info->ac_online) { + val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; + if (ret & MAX8925_CHG_STAT_EN_MASK) + val->intval = POWER_SUPPLY_STATUS_CHARGING; + } else + val->intval = POWER_SUPPLY_STATUS_DISCHARGING; + ret = 0; + break; + default: + ret = -ENODEV; + break; + } + return ret; +} + +static enum power_supply_property max8925_battery_props[] = { + POWER_SUPPLY_PROP_ONLINE, + POWER_SUPPLY_PROP_VOLTAGE_NOW, + POWER_SUPPLY_PROP_CURRENT_NOW, + POWER_SUPPLY_PROP_CHARGE_TYPE, + POWER_SUPPLY_PROP_STATUS, +}; + +#define REQUEST_IRQ(_irq, _name) \ +do { \ + ret = request_threaded_irq(chip->irq_base + _irq, NULL, \ + max8925_charger_handler, \ + IRQF_ONESHOT, _name, info); \ + if (ret) \ + dev_err(chip->dev, "Failed to request IRQ #%d: %d\n", \ + _irq, ret); \ +} while (0) + +static __devinit int max8925_init_charger(struct max8925_chip *chip, + struct max8925_power_info *info) +{ + int ret; + + REQUEST_IRQ(MAX8925_IRQ_VCHG_DC_OVP, "ac-ovp"); + REQUEST_IRQ(MAX8925_IRQ_VCHG_DC_F, "ac-remove"); + REQUEST_IRQ(MAX8925_IRQ_VCHG_DC_R, "ac-insert"); + REQUEST_IRQ(MAX8925_IRQ_VCHG_USB_OVP, "usb-ovp"); + REQUEST_IRQ(MAX8925_IRQ_VCHG_USB_F, "usb-remove"); + REQUEST_IRQ(MAX8925_IRQ_VCHG_USB_R, "usb-insert"); + REQUEST_IRQ(MAX8925_IRQ_VCHG_THM_OK_R, "batt-temp-in-range"); + REQUEST_IRQ(MAX8925_IRQ_VCHG_THM_OK_F, "batt-temp-out-range"); + REQUEST_IRQ(MAX8925_IRQ_VCHG_SYSLOW_F, "vsys-high"); + REQUEST_IRQ(MAX8925_IRQ_VCHG_SYSLOW_R, "vsys-low"); + REQUEST_IRQ(MAX8925_IRQ_VCHG_RST, "charger-reset"); + REQUEST_IRQ(MAX8925_IRQ_VCHG_DONE, "charger-done"); + REQUEST_IRQ(MAX8925_IRQ_VCHG_TOPOFF, "charger-topoff"); + REQUEST_IRQ(MAX8925_IRQ_VCHG_TMR_FAULT, "charger-timer-expire"); + + info->ac_online = 0; + info->usb_online = 0; + info->bat_online = 0; + ret = max8925_reg_read(info->gpm, MAX8925_CHG_STATUS); + if (ret >= 0) { + /* + * If battery detection is enabled, ID pin of battery is + * connected to MBDET pin of MAX8925. It could be used to + * detect battery presence. + * Otherwise, we have to assume that battery is always on. + */ + if (info->batt_detect) + info->bat_online = (ret & MAX8925_CHG_MBDET) ? 0 : 1; + else + info->bat_online = 1; + if (ret & MAX8925_CHG_AC_RANGE_MASK) + info->ac_online = 1; + else + info->ac_online = 0; + } + /* disable charge */ + max8925_set_bits(info->gpm, MAX8925_CHG_CNTL1, 1 << 7, 1 << 7); + /* set charging current in charge topoff mode */ + max8925_set_bits(info->gpm, MAX8925_CHG_CNTL1, 3 << 5, + info->topoff_threshold << 5); + /* set charing current in fast charge mode */ + max8925_set_bits(info->gpm, MAX8925_CHG_CNTL1, 7, info->fast_charge); + + return 0; +} + +static __devexit int max8925_deinit_charger(struct max8925_power_info *info) +{ + struct max8925_chip *chip = info->chip; + int irq; + + irq = chip->irq_base + MAX8925_IRQ_VCHG_DC_OVP; + for (; irq <= chip->irq_base + MAX8925_IRQ_VCHG_TMR_FAULT; irq++) + free_irq(irq, info); + + return 0; +} + +static __devinit int max8925_power_probe(struct platform_device *pdev) +{ + struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent); + struct max8925_platform_data *max8925_pdata; + struct max8925_power_pdata *pdata = NULL; + struct max8925_power_info *info; + int ret; + + if (pdev->dev.parent->platform_data) { + max8925_pdata = pdev->dev.parent->platform_data; + pdata = max8925_pdata->power; + } + + if (!pdata) { + dev_err(&pdev->dev, "platform data isn't assigned to " + "power supply\n"); + return -EINVAL; + } + + info = kzalloc(sizeof(struct max8925_power_info), GFP_KERNEL); + if (!info) + return -ENOMEM; + info->chip = chip; + info->gpm = chip->i2c; + info->adc = chip->adc; + + info->ac.name = "max8925-ac"; + info->ac.type = POWER_SUPPLY_TYPE_MAINS; + info->ac.properties = max8925_ac_props; + info->ac.num_properties = ARRAY_SIZE(max8925_ac_props); + info->ac.get_property = max8925_ac_get_prop; + ret = power_supply_register(&pdev->dev, &info->ac); + if (ret) + goto out; + info->ac.dev->parent = &pdev->dev; + + info->usb.name = "max8925-usb"; + info->usb.type = POWER_SUPPLY_TYPE_USB; + info->usb.properties = max8925_usb_props; + info->usb.num_properties = ARRAY_SIZE(max8925_usb_props); + info->usb.get_property = max8925_usb_get_prop; + ret = power_supply_register(&pdev->dev, &info->usb); + if (ret) + goto out_usb; + info->usb.dev->parent = &pdev->dev; + + info->battery.name = "max8925-battery"; + info->battery.type = POWER_SUPPLY_TYPE_BATTERY; + info->battery.properties = max8925_battery_props; + info->battery.num_properties = ARRAY_SIZE(max8925_battery_props); + info->battery.get_property = max8925_bat_get_prop; + ret = power_supply_register(&pdev->dev, &info->battery); + if (ret) + goto out_battery; + info->battery.dev->parent = &pdev->dev; + + info->batt_detect = pdata->batt_detect; + info->topoff_threshold = pdata->topoff_threshold; + info->fast_charge = pdata->fast_charge; + info->set_charger = pdata->set_charger; + dev_set_drvdata(&pdev->dev, info); + platform_set_drvdata(pdev, info); + + max8925_init_charger(chip, info); + return 0; +out_battery: + power_supply_unregister(&info->battery); +out_usb: + power_supply_unregister(&info->ac); +out: + kfree(info); + return ret; +} + +static __devexit int max8925_power_remove(struct platform_device *pdev) +{ + struct max8925_power_info *info = platform_get_drvdata(pdev); + + if (info) { + power_supply_unregister(&info->ac); + power_supply_unregister(&info->usb); + power_supply_unregister(&info->battery); + max8925_deinit_charger(info); + kfree(info); + } + return 0; +} + +static struct platform_driver max8925_power_driver = { + .probe = max8925_power_probe, + .remove = __devexit_p(max8925_power_remove), + .driver = { + .name = "max8925-power", + }, +}; + +static int __init max8925_power_init(void) +{ + return platform_driver_register(&max8925_power_driver); +} +module_init(max8925_power_init); + +static void __exit max8925_power_exit(void) +{ + platform_driver_unregister(&max8925_power_driver); +} +module_exit(max8925_power_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Power supply driver for MAX8925"); +MODULE_ALIAS("platform:max8925-power"); diff --git a/drivers/power/wm8350_power.c b/drivers/power/wm8350_power.c index ad4f071..0693902 100644 --- a/drivers/power/wm8350_power.c +++ b/drivers/power/wm8350_power.c @@ -190,7 +190,7 @@ static irqreturn_t wm8350_charger_handler(int irq, void *data) struct wm8350_power *power = &wm8350->power; struct wm8350_charger_policy *policy = power->policy; - switch (irq) { + switch (irq - wm8350->irq_base) { case WM8350_IRQ_CHG_BAT_FAIL: dev_err(wm8350->dev, "battery failed\n"); break; @@ -428,18 +428,18 @@ static void wm8350_init_charger(struct wm8350 *wm8350) static void free_charger_irq(struct wm8350 *wm8350) { - wm8350_free_irq(wm8350, WM8350_IRQ_CHG_BAT_HOT); - wm8350_free_irq(wm8350, WM8350_IRQ_CHG_BAT_COLD); - wm8350_free_irq(wm8350, WM8350_IRQ_CHG_BAT_FAIL); - wm8350_free_irq(wm8350, WM8350_IRQ_CHG_TO); - wm8350_free_irq(wm8350, WM8350_IRQ_CHG_END); - wm8350_free_irq(wm8350, WM8350_IRQ_CHG_START); - wm8350_free_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_3P9); - wm8350_free_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_3P1); - wm8350_free_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_2P85); - wm8350_free_irq(wm8350, WM8350_IRQ_EXT_USB_FB); - wm8350_free_irq(wm8350, WM8350_IRQ_EXT_WALL_FB); - wm8350_free_irq(wm8350, WM8350_IRQ_EXT_BAT_FB); + wm8350_free_irq(wm8350, WM8350_IRQ_CHG_BAT_HOT, wm8350); + wm8350_free_irq(wm8350, WM8350_IRQ_CHG_BAT_COLD, wm8350); + wm8350_free_irq(wm8350, WM8350_IRQ_CHG_BAT_FAIL, wm8350); + wm8350_free_irq(wm8350, WM8350_IRQ_CHG_TO, wm8350); + wm8350_free_irq(wm8350, WM8350_IRQ_CHG_END, wm8350); + wm8350_free_irq(wm8350, WM8350_IRQ_CHG_START, wm8350); + wm8350_free_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_3P9, wm8350); + wm8350_free_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_3P1, wm8350); + wm8350_free_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_2P85, wm8350); + wm8350_free_irq(wm8350, WM8350_IRQ_EXT_USB_FB, wm8350); + wm8350_free_irq(wm8350, WM8350_IRQ_EXT_WALL_FB, wm8350); + wm8350_free_irq(wm8350, WM8350_IRQ_EXT_BAT_FB, wm8350); } static __devinit int wm8350_power_probe(struct platform_device *pdev) diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c index 0471955..5fb83e2 100644 --- a/drivers/regulator/88pm8607.c +++ b/drivers/regulator/88pm8607.c @@ -11,15 +11,17 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/err.h> +#include <linux/i2c.h> #include <linux/platform_device.h> #include <linux/regulator/driver.h> #include <linux/regulator/machine.h> -#include <linux/mfd/88pm8607.h> +#include <linux/mfd/88pm860x.h> struct pm8607_regulator_info { struct regulator_desc desc; - struct pm8607_chip *chip; + struct pm860x_chip *chip; struct regulator_dev *regulator; + struct i2c_client *i2c; int min_uV; int max_uV; @@ -46,7 +48,6 @@ static inline int check_range(struct pm8607_regulator_info *info, static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index) { struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); - uint8_t chip_id = info->chip->chip_id; int ret = -EINVAL; switch (info->desc.id) { @@ -88,79 +89,29 @@ static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index) case PM8607_ID_LDO2: case PM8607_ID_LDO3: case PM8607_ID_LDO9: - switch (chip_id) { - case PM8607_CHIP_A0: - case PM8607_CHIP_A1: - ret = (index < 3) ? (index * 50000 + 1800000) : - ((index < 8) ? (index * 50000 + 2550000) : - -EINVAL); - break; - case PM8607_CHIP_B0: - ret = (index < 3) ? (index * 50000 + 1800000) : - ((index < 7) ? (index * 50000 + 2550000) : - 3300000); - break; - } + ret = (index < 3) ? (index * 50000 + 1800000) : + ((index < 7) ? (index * 50000 + 2550000) : + 3300000); break; case PM8607_ID_LDO4: - switch (chip_id) { - case PM8607_CHIP_A0: - case PM8607_CHIP_A1: - ret = (index < 3) ? (index * 50000 + 1800000) : - ((index < 8) ? (index * 50000 + 2550000) : - -EINVAL); - break; - case PM8607_CHIP_B0: - ret = (index < 3) ? (index * 50000 + 1800000) : - ((index < 6) ? (index * 50000 + 2550000) : - ((index == 6) ? 2900000 : 3300000)); - break; - } + ret = (index < 3) ? (index * 50000 + 1800000) : + ((index < 6) ? (index * 50000 + 2550000) : + ((index == 6) ? 2900000 : 3300000)); break; case PM8607_ID_LDO6: - switch (chip_id) { - case PM8607_CHIP_A0: - case PM8607_CHIP_A1: - ret = (index < 3) ? (index * 50000 + 1800000) : - ((index < 8) ? (index * 50000 + 2450000) : - -EINVAL); - break; - case PM8607_CHIP_B0: - ret = (index < 2) ? (index * 50000 + 1800000) : - ((index < 7) ? (index * 50000 + 2500000) : - 3300000); - break; - } + ret = (index < 2) ? (index * 50000 + 1800000) : + ((index < 7) ? (index * 50000 + 2500000) : + 3300000); break; case PM8607_ID_LDO10: - switch (chip_id) { - case PM8607_CHIP_A0: - case PM8607_CHIP_A1: - ret = (index < 3) ? (index * 50000 + 1800000) : - ((index < 8) ? (index * 50000 + 2550000) : - 1200000); - break; - case PM8607_CHIP_B0: - ret = (index < 3) ? (index * 50000 + 1800000) : - ((index < 7) ? (index * 50000 + 2550000) : - ((index == 7) ? 3300000 : 1200000)); - break; - } + ret = (index < 3) ? (index * 50000 + 1800000) : + ((index < 7) ? (index * 50000 + 2550000) : + ((index == 7) ? 3300000 : 1200000)); break; case PM8607_ID_LDO14: - switch (chip_id) { - case PM8607_CHIP_A0: - case PM8607_CHIP_A1: - ret = (index < 3) ? (index * 50000 + 1800000) : - ((index < 8) ? (index * 50000 + 2550000) : - -EINVAL); - break; - case PM8607_CHIP_B0: - ret = (index < 2) ? (index * 50000 + 1800000) : - ((index < 7) ? (index * 50000 + 2600000) : - 3300000); - break; - } + ret = (index < 2) ? (index * 50000 + 1800000) : + ((index < 7) ? (index * 50000 + 2600000) : + 3300000); break; } return ret; @@ -169,7 +120,6 @@ static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index) static int choose_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) { struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); - uint8_t chip_id = info->chip->chip_id; int val = -ENOENT; int ret; @@ -254,161 +204,77 @@ static int choose_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) case PM8607_ID_LDO2: case PM8607_ID_LDO3: case PM8607_ID_LDO9: - switch (chip_id) { - case PM8607_CHIP_A0: - case PM8607_CHIP_A1: - if (min_uV < 2700000) /* 1800mV ~ 1900mV / 50mV */ - if (min_uV <= 1800000) - val = 0; - else if (min_uV <= 1900000) - val = (min_uV - 1750001) / 50000; - else - val = 3; /* 2700mV */ - else { /* 2700mV ~ 2900mV / 50mV */ - if (min_uV <= 2900000) { - val = (min_uV - 2650001) / 50000; - val += 3; - } else - val = -EINVAL; - } - break; - case PM8607_CHIP_B0: - if (min_uV < 2700000) { /* 1800mV ~ 1900mV / 50mV */ - if (min_uV <= 1800000) - val = 0; - else if (min_uV <= 1900000) - val = (min_uV - 1750001) / 50000; - else - val = 3; /* 2700mV */ - } else { /* 2700mV ~ 2850mV / 50mV */ - if (min_uV <= 2850000) { - val = (min_uV - 2650001) / 50000; - val += 3; - } else if (min_uV <= 3300000) - val = 7; - else - val = -EINVAL; - } - break; + if (min_uV < 2700000) { /* 1800mV ~ 1900mV / 50mV */ + if (min_uV <= 1800000) + val = 0; + else if (min_uV <= 1900000) + val = (min_uV - 1750001) / 50000; + else + val = 3; /* 2700mV */ + } else { /* 2700mV ~ 2850mV / 50mV */ + if (min_uV <= 2850000) { + val = (min_uV - 2650001) / 50000; + val += 3; + } else if (min_uV <= 3300000) + val = 7; + else + val = -EINVAL; } break; case PM8607_ID_LDO4: - switch (chip_id) { - case PM8607_CHIP_A0: - case PM8607_CHIP_A1: - if (min_uV < 2700000) /* 1800mV ~ 1900mV / 50mV */ - if (min_uV <= 1800000) - val = 0; - else if (min_uV <= 1900000) - val = (min_uV - 1750001) / 50000; - else - val = 3; /* 2700mV */ - else { /* 2700mV ~ 2900mV / 50mV */ - if (min_uV <= 2900000) { - val = (min_uV - 2650001) / 50000; - val += 3; - } else - val = -EINVAL; - } - break; - case PM8607_CHIP_B0: - if (min_uV < 2700000) { /* 1800mV ~ 1900mV / 50mV */ - if (min_uV <= 1800000) - val = 0; - else if (min_uV <= 1900000) - val = (min_uV - 1750001) / 50000; - else - val = 3; /* 2700mV */ - } else { /* 2700mV ~ 2800mV / 50mV */ - if (min_uV <= 2850000) { - val = (min_uV - 2650001) / 50000; - val += 3; - } else if (min_uV <= 2900000) - val = 6; - else if (min_uV <= 3300000) - val = 7; - else - val = -EINVAL; - } - break; + if (min_uV < 2700000) { /* 1800mV ~ 1900mV / 50mV */ + if (min_uV <= 1800000) + val = 0; + else if (min_uV <= 1900000) + val = (min_uV - 1750001) / 50000; + else + val = 3; /* 2700mV */ + } else { /* 2700mV ~ 2800mV / 50mV */ + if (min_uV <= 2850000) { + val = (min_uV - 2650001) / 50000; + val += 3; + } else if (min_uV <= 2900000) + val = 6; + else if (min_uV <= 3300000) + val = 7; + else + val = -EINVAL; } break; case PM8607_ID_LDO6: - switch (chip_id) { - case PM8607_CHIP_A0: - case PM8607_CHIP_A1: - if (min_uV < 2600000) { /* 1800mV ~ 1900mV / 50mV */ - if (min_uV <= 1800000) - val = 0; - else if (min_uV <= 1900000) - val = (min_uV - 1750001) / 50000; - else - val = 3; /* 2600mV */ - } else { /* 2600mV ~ 2800mV / 50mV */ - if (min_uV <= 2800000) { - val = (min_uV - 2550001) / 50000; - val += 3; - } else - val = -EINVAL; - } - break; - case PM8607_CHIP_B0: - if (min_uV < 2600000) { /* 1800mV ~ 1850mV / 50mV */ - if (min_uV <= 1800000) - val = 0; - else if (min_uV <= 1850000) - val = (min_uV - 1750001) / 50000; - else - val = 2; /* 2600mV */ - } else { /* 2600mV ~ 2800mV / 50mV */ - if (min_uV <= 2800000) { - val = (min_uV - 2550001) / 50000; - val += 2; - } else if (min_uV <= 3300000) - val = 7; - else - val = -EINVAL; - } - break; + if (min_uV < 2600000) { /* 1800mV ~ 1850mV / 50mV */ + if (min_uV <= 1800000) + val = 0; + else if (min_uV <= 1850000) + val = (min_uV - 1750001) / 50000; + else + val = 2; /* 2600mV */ + } else { /* 2600mV ~ 2800mV / 50mV */ + if (min_uV <= 2800000) { + val = (min_uV - 2550001) / 50000; + val += 2; + } else if (min_uV <= 3300000) + val = 7; + else + val = -EINVAL; } break; case PM8607_ID_LDO14: - switch (chip_id) { - case PM8607_CHIP_A0: - case PM8607_CHIP_A1: - if (min_uV < 2700000) { /* 1800mV ~ 1900mV / 50mV */ - if (min_uV <= 1800000) - val = 0; - else if (min_uV <= 1900000) - val = (min_uV - 1750001) / 50000; - else - val = 3; /* 2700mV */ - } else { /* 2700mV ~ 2900mV / 50mV */ - if (min_uV <= 2900000) { - val = (min_uV - 2650001) / 50000; - val += 3; - } else - val = -EINVAL; - } - break; - case PM8607_CHIP_B0: - if (min_uV < 2700000) { /* 1800mV ~ 1850mV / 50mV */ - if (min_uV <= 1800000) - val = 0; - else if (min_uV <= 1850000) - val = (min_uV - 1750001) / 50000; - else - val = 2; /* 2700mV */ - } else { /* 2700mV ~ 2900mV / 50mV */ - if (min_uV <= 2900000) { - val = (min_uV - 2650001) / 50000; - val += 2; - } else if (min_uV <= 3300000) - val = 7; - else - val = -EINVAL; - } - break; + if (min_uV < 2700000) { /* 1800mV ~ 1850mV / 50mV */ + if (min_uV <= 1800000) + val = 0; + else if (min_uV <= 1850000) + val = (min_uV - 1750001) / 50000; + else + val = 2; /* 2700mV */ + } else { /* 2700mV ~ 2900mV / 50mV */ + if (min_uV <= 2900000) { + val = (min_uV - 2650001) / 50000; + val += 2; + } else if (min_uV <= 3300000) + val = 7; + else + val = -EINVAL; } break; } @@ -428,7 +294,6 @@ static int pm8607_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) { struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); - struct pm8607_chip *chip = info->chip; uint8_t val, mask; int ret; @@ -443,13 +308,13 @@ static int pm8607_set_voltage(struct regulator_dev *rdev, val = (uint8_t)(ret << info->vol_shift); mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; - ret = pm8607_set_bits(chip, info->vol_reg, mask, val); + ret = pm860x_set_bits(info->i2c, info->vol_reg, mask, val); if (ret) return ret; switch (info->desc.id) { case PM8607_ID_BUCK1: case PM8607_ID_BUCK3: - ret = pm8607_set_bits(chip, info->update_reg, + ret = pm860x_set_bits(info->i2c, info->update_reg, 1 << info->update_bit, 1 << info->update_bit); break; @@ -460,11 +325,10 @@ static int pm8607_set_voltage(struct regulator_dev *rdev, static int pm8607_get_voltage(struct regulator_dev *rdev) { struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); - struct pm8607_chip *chip = info->chip; uint8_t val, mask; int ret; - ret = pm8607_reg_read(chip, info->vol_reg); + ret = pm860x_reg_read(info->i2c, info->vol_reg); if (ret < 0) return ret; @@ -477,9 +341,8 @@ static int pm8607_get_voltage(struct regulator_dev *rdev) static int pm8607_enable(struct regulator_dev *rdev) { struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); - struct pm8607_chip *chip = info->chip; - return pm8607_set_bits(chip, info->enable_reg, + return pm860x_set_bits(info->i2c, info->enable_reg, 1 << info->enable_bit, 1 << info->enable_bit); } @@ -487,19 +350,17 @@ static int pm8607_enable(struct regulator_dev *rdev) static int pm8607_disable(struct regulator_dev *rdev) { struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); - struct pm8607_chip *chip = info->chip; - return pm8607_set_bits(chip, info->enable_reg, + return pm860x_set_bits(info->i2c, info->enable_reg, 1 << info->enable_bit, 0); } static int pm8607_is_enabled(struct regulator_dev *rdev) { struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); - struct pm8607_chip *chip = info->chip; int ret; - ret = pm8607_reg_read(chip, info->enable_reg); + ret = pm860x_reg_read(info->i2c, info->enable_reg); if (ret < 0) return ret; @@ -589,8 +450,8 @@ static inline struct pm8607_regulator_info *find_regulator_info(int id) static int __devinit pm8607_regulator_probe(struct platform_device *pdev) { - struct pm8607_chip *chip = dev_get_drvdata(pdev->dev.parent); - struct pm8607_platform_data *pdata = chip->dev->platform_data; + struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); + struct pm860x_platform_data *pdata = chip->dev->platform_data; struct pm8607_regulator_info *info = NULL; info = find_regulator_info(pdev->id); @@ -599,6 +460,7 @@ static int __devinit pm8607_regulator_probe(struct platform_device *pdev) return -EINVAL; } + info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion; info->chip = chip; info->regulator = regulator_register(&info->desc, &pdev->dev, diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 834b484..04f2e08 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -94,6 +94,12 @@ config REGULATOR_MAX8660 This driver controls a Maxim 8660/8661 voltage output regulator via I2C bus. +config REGULATOR_MAX8925 + tristate "Maxim MAX8925 Power Management IC" + depends on MFD_MAX8925 + help + Say y here to support the voltage regulaltor of Maxim MAX8925 PMIC. + config REGULATOR_TWL4030 bool "TI TWL4030/TWL5030/TWL6030/TPS695x0 PMIC" depends on TWL4030_CORE @@ -191,7 +197,7 @@ config REGULATOR_TPS6507X config REGULATOR_88PM8607 bool "Marvell 88PM8607 Power regulators" - depends on MFD_88PM8607=y + depends on MFD_88PM860X=y help This driver supports 88PM8607 voltage regulator chips. diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index e845b66..4e7feec 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -15,6 +15,7 @@ obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o obj-$(CONFIG_REGULATOR_MAX8649) += max8649.o obj-$(CONFIG_REGULATOR_MAX8660) += max8660.o +obj-$(CONFIG_REGULATOR_MAX8925) += max8925-regulator.o obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o obj-$(CONFIG_REGULATOR_WM831X) += wm831x-isink.o obj-$(CONFIG_REGULATOR_WM831X) += wm831x-ldo.o diff --git a/drivers/regulator/max8925-regulator.c b/drivers/regulator/max8925-regulator.c new file mode 100644 index 0000000..67873f0 --- /dev/null +++ b/drivers/regulator/max8925-regulator.c @@ -0,0 +1,306 @@ +/* + * Regulators driver for Maxim max8925 + * + * Copyright (C) 2009 Marvell International Ltd. + * Haojian Zhuang <haojian.zhuang@marvell.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/err.h> +#include <linux/i2c.h> +#include <linux/platform_device.h> +#include <linux/regulator/driver.h> +#include <linux/regulator/machine.h> +#include <linux/mfd/max8925.h> + +#define SD1_DVM_VMIN 850000 +#define SD1_DVM_VMAX 1000000 +#define SD1_DVM_STEP 50000 +#define SD1_DVM_SHIFT 5 /* SDCTL1 bit5 */ +#define SD1_DVM_EN 6 /* SDV1 bit 6 */ + +struct max8925_regulator_info { + struct regulator_desc desc; + struct regulator_dev *regulator; + struct i2c_client *i2c; + struct max8925_chip *chip; + + int min_uV; + int max_uV; + int step_uV; + int vol_reg; + int vol_shift; + int vol_nbits; + int enable_bit; + int enable_reg; +}; + +static inline int check_range(struct max8925_regulator_info *info, + int min_uV, int max_uV) +{ + if (min_uV < info->min_uV || min_uV > info->max_uV) + return -EINVAL; + + return 0; +} + +static int max8925_list_voltage(struct regulator_dev *rdev, unsigned index) +{ + struct max8925_regulator_info *info = rdev_get_drvdata(rdev); + return info->min_uV + index * info->step_uV; +} + +static int max8925_set_voltage(struct regulator_dev *rdev, + int min_uV, int max_uV) +{ + struct max8925_regulator_info *info = rdev_get_drvdata(rdev); + unsigned char data, mask; + + if (check_range(info, min_uV, max_uV)) { + dev_err(info->chip->dev, "invalid voltage range (%d, %d) uV\n", + min_uV, max_uV); + return -EINVAL; + } + data = (min_uV - info->min_uV + info->step_uV - 1) / info->step_uV; + data <<= info->vol_shift; + mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; + + return max8925_set_bits(info->i2c, info->vol_reg, mask, data); +} + +static int max8925_get_voltage(struct regulator_dev *rdev) +{ + struct max8925_regulator_info *info = rdev_get_drvdata(rdev); + unsigned char data, mask; + int ret; + + ret = max8925_reg_read(info->i2c, info->vol_reg); + if (ret < 0) + return ret; + mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; + data = (ret & mask) >> info->vol_shift; + + return max8925_list_voltage(rdev, data); +} + +static int max8925_enable(struct regulator_dev *rdev) +{ + struct max8925_regulator_info *info = rdev_get_drvdata(rdev); + + return max8925_set_bits(info->i2c, info->enable_reg, + 1 << info->enable_bit, + 1 << info->enable_bit); +} + +static int max8925_disable(struct regulator_dev *rdev) +{ + struct max8925_regulator_info *info = rdev_get_drvdata(rdev); + + return max8925_set_bits(info->i2c, info->enable_reg, + 1 << info->enable_bit, 0); +} + +static int max8925_is_enabled(struct regulator_dev *rdev) +{ + struct max8925_regulator_info *info = rdev_get_drvdata(rdev); + int ret; + + ret = max8925_reg_read(info->i2c, info->vol_reg); + if (ret < 0) + return ret; + + return ret & (1 << info->enable_bit); +} + +static int max8925_set_dvm_voltage(struct regulator_dev *rdev, int uV) +{ + struct max8925_regulator_info *info = rdev_get_drvdata(rdev); + unsigned char data, mask; + + if (uV < SD1_DVM_VMIN || uV > SD1_DVM_VMAX) + return -EINVAL; + + data = (uV - SD1_DVM_VMIN + SD1_DVM_STEP - 1) / SD1_DVM_STEP; + data <<= SD1_DVM_SHIFT; + mask = 3 << SD1_DVM_SHIFT; + + return max8925_set_bits(info->i2c, info->enable_reg, mask, data); +} + +static int max8925_set_dvm_enable(struct regulator_dev *rdev) +{ + struct max8925_regulator_info *info = rdev_get_drvdata(rdev); + + return max8925_set_bits(info->i2c, info->vol_reg, 1 << SD1_DVM_EN, + 1 << SD1_DVM_EN); +} + +static int max8925_set_dvm_disable(struct regulator_dev *rdev) +{ + struct max8925_regulator_info *info = rdev_get_drvdata(rdev); + + return max8925_set_bits(info->i2c, info->vol_reg, 1 << SD1_DVM_EN, 0); +} + +static struct regulator_ops max8925_regulator_sdv_ops = { + .set_voltage = max8925_set_voltage, + .get_voltage = max8925_get_voltage, + .enable = max8925_enable, + .disable = max8925_disable, + .is_enabled = max8925_is_enabled, + .set_suspend_voltage = max8925_set_dvm_voltage, + .set_suspend_enable = max8925_set_dvm_enable, + .set_suspend_disable = max8925_set_dvm_disable, +}; + +static struct regulator_ops max8925_regulator_ldo_ops = { + .set_voltage = max8925_set_voltage, + .get_voltage = max8925_get_voltage, + .enable = max8925_enable, + .disable = max8925_disable, + .is_enabled = max8925_is_enabled, +}; + +#define MAX8925_SDV(_id, min, max, step) \ +{ \ + .desc = { \ + .name = "SDV" #_id, \ + .ops = &max8925_regulator_sdv_ops, \ + .type = REGULATOR_VOLTAGE, \ + .id = MAX8925_ID_SD##_id, \ + .owner = THIS_MODULE, \ + }, \ + .min_uV = min * 1000, \ + .max_uV = max * 1000, \ + .step_uV = step * 1000, \ + .vol_reg = MAX8925_SDV##_id, \ + .vol_shift = 0, \ + .vol_nbits = 6, \ + .enable_reg = MAX8925_SDCTL##_id, \ + .enable_bit = 0, \ +} + +#define MAX8925_LDO(_id, min, max, step) \ +{ \ + .desc = { \ + .name = "LDO" #_id, \ + .ops = &max8925_regulator_ldo_ops, \ + .type = REGULATOR_VOLTAGE, \ + .id = MAX8925_ID_LDO##_id, \ + .owner = THIS_MODULE, \ + }, \ + .min_uV = min * 1000, \ + .max_uV = max * 1000, \ + .step_uV = step * 1000, \ + .vol_reg = MAX8925_LDOVOUT##_id, \ + .vol_shift = 0, \ + .vol_nbits = 6, \ + .enable_reg = MAX8925_LDOCTL##_id, \ + .enable_bit = 0, \ +} + +static struct max8925_regulator_info max8925_regulator_info[] = { + MAX8925_SDV(1, 637.5, 1425, 12.5), + MAX8925_SDV(2, 650, 2225, 25), + MAX8925_SDV(3, 750, 3900, 50), + + MAX8925_LDO(1, 750, 3900, 50), + MAX8925_LDO(2, 650, 2250, 25), + MAX8925_LDO(3, 650, 2250, 25), + MAX8925_LDO(4, 750, 3900, 50), + MAX8925_LDO(5, 750, 3900, 50), + MAX8925_LDO(6, 750, 3900, 50), + MAX8925_LDO(7, 750, 3900, 50), + MAX8925_LDO(8, 750, 3900, 50), + MAX8925_LDO(9, 750, 3900, 50), + MAX8925_LDO(10, 750, 3900, 50), + MAX8925_LDO(11, 750, 3900, 50), + MAX8925_LDO(12, 750, 3900, 50), + MAX8925_LDO(13, 750, 3900, 50), + MAX8925_LDO(14, 750, 3900, 50), + MAX8925_LDO(15, 750, 3900, 50), + MAX8925_LDO(16, 750, 3900, 50), + MAX8925_LDO(17, 650, 2250, 25), + MAX8925_LDO(18, 650, 2250, 25), + MAX8925_LDO(19, 750, 3900, 50), + MAX8925_LDO(20, 750, 3900, 50), +}; + +static inline struct max8925_regulator_info *find_regulator_info(int id) +{ + struct max8925_regulator_info *ri; + int i; + + for (i = 0; i < ARRAY_SIZE(max8925_regulator_info); i++) { + ri = &max8925_regulator_info[i]; + if (ri->desc.id == id) + return ri; + } + return NULL; +} + +static int __devinit max8925_regulator_probe(struct platform_device *pdev) +{ + struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent); + struct max8925_platform_data *pdata = chip->dev->platform_data; + struct max8925_regulator_info *ri = NULL; + struct regulator_dev *rdev; + + ri = find_regulator_info(pdev->id); + if (ri == NULL) { + dev_err(&pdev->dev, "invalid regulator ID specified\n"); + return -EINVAL; + } + ri->i2c = chip->i2c; + ri->chip = chip; + + rdev = regulator_register(&ri->desc, &pdev->dev, + pdata->regulator[pdev->id], ri); + if (IS_ERR(rdev)) { + dev_err(&pdev->dev, "failed to register regulator %s\n", + ri->desc.name); + return PTR_ERR(rdev); + } + + platform_set_drvdata(pdev, rdev); + return 0; +} + +static int __devexit max8925_regulator_remove(struct platform_device *pdev) +{ + struct regulator_dev *rdev = platform_get_drvdata(pdev); + + regulator_unregister(rdev); + return 0; +} + +static struct platform_driver max8925_regulator_driver = { + .driver = { + .name = "max8925-regulator", + .owner = THIS_MODULE, + }, + .probe = max8925_regulator_probe, + .remove = __devexit_p(max8925_regulator_remove), +}; + +static int __init max8925_regulator_init(void) +{ + return platform_driver_register(&max8925_regulator_driver); +} +subsys_initcall(max8925_regulator_init); + +static void __exit max8925_regulator_exit(void) +{ + platform_driver_unregister(&max8925_regulator_driver); +} +module_exit(max8925_regulator_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>"); +MODULE_DESCRIPTION("Regulator Driver for Maxim 8925 PMIC"); +MODULE_ALIAS("platform:max8925-regulator"); + diff --git a/drivers/regulator/wm8350-regulator.c b/drivers/regulator/wm8350-regulator.c index 94227dd..723cd1f 100644 --- a/drivers/regulator/wm8350-regulator.c +++ b/drivers/regulator/wm8350-regulator.c @@ -1453,7 +1453,7 @@ static int wm8350_regulator_remove(struct platform_device *pdev) struct regulator_dev *rdev = platform_get_drvdata(pdev); struct wm8350 *wm8350 = rdev_get_drvdata(rdev); - wm8350_free_irq(wm8350, wm8350_reg[pdev->id].irq); + wm8350_free_irq(wm8350, wm8350_reg[pdev->id].irq, rdev); regulator_unregister(rdev); diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 2bb8a8b..6a13037 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -175,6 +175,16 @@ config RTC_DRV_MAX6900 This driver can also be built as a module. If so, the module will be called rtc-max6900. +config RTC_DRV_MAX8925 + tristate "Maxim MAX8925" + depends on MFD_MAX8925 + help + If you say yes here you will get support for the + RTC of Maxim MAX8925 PMIC. + + This driver can also be built as a module. If so, the module + will be called rtc-max8925. + config RTC_DRV_RS5C372 tristate "Ricoh R2025S/D, RS5C372A/B, RV5C386, RV5C387A" help diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index b7148af..44ef194 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -52,6 +52,7 @@ obj-$(CONFIG_RTC_DRV_M48T59) += rtc-m48t59.o obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o obj-$(CONFIG_RTC_MXC) += rtc-mxc.o obj-$(CONFIG_RTC_DRV_MAX6900) += rtc-max6900.o +obj-$(CONFIG_RTC_DRV_MAX8925) += rtc-max8925.o obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o obj-$(CONFIG_RTC_DRV_MC13783) += rtc-mc13783.o obj-$(CONFIG_RTC_DRV_MSM6242) += rtc-msm6242.o diff --git a/drivers/rtc/rtc-max8925.c b/drivers/rtc/rtc-max8925.c new file mode 100644 index 0000000..acdbb17 --- /dev/null +++ b/drivers/rtc/rtc-max8925.c @@ -0,0 +1,314 @@ +/* + * RTC driver for Maxim MAX8925 + * + * Copyright (C) 2009-2010 Marvell International Ltd. + * Haojian Zhuang <haojian.zhuang@marvell.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/module.h> +#include <linux/i2c.h> +#include <linux/rtc.h> +#include <linux/platform_device.h> +#include <linux/mfd/max8925.h> + +enum { + RTC_SEC = 0, + RTC_MIN, + RTC_HOUR, + RTC_WEEKDAY, + RTC_DATE, + RTC_MONTH, + RTC_YEAR1, + RTC_YEAR2, +}; + +#define MAX8925_RTC_SEC 0x00 +#define MAX8925_RTC_MIN 0x01 +#define MAX8925_RTC_HOUR 0x02 +#define MAX8925_RTC_WEEKDAY 0x03 +#define MAX8925_RTC_DATE 0x04 +#define MAX8925_RTC_MONTH 0x05 +#define MAX8925_RTC_YEAR1 0x06 +#define MAX8925_RTC_YEAR2 0x07 +#define MAX8925_ALARM0_SEC 0x08 +#define MAX8925_ALARM0_MIN 0x09 +#define MAX8925_ALARM0_HOUR 0x0a +#define MAX8925_ALARM0_WEEKDAY 0x0b +#define MAX8925_ALARM0_DATE 0x0c +#define MAX8925_ALARM0_MON 0x0d +#define MAX8925_ALARM0_YEAR1 0x0e +#define MAX8925_ALARM0_YEAR2 0x0f +#define MAX8925_ALARM1_SEC 0x10 +#define MAX8925_ALARM1_MIN 0x11 +#define MAX8925_ALARM1_HOUR 0x12 +#define MAX8925_ALARM1_WEEKDAY 0x13 +#define MAX8925_ALARM1_DATE 0x14 +#define MAX8925_ALARM1_MON 0x15 +#define MAX8925_ALARM1_YEAR1 0x16 +#define MAX8925_ALARM1_YEAR2 0x17 +#define MAX8925_RTC_CNTL 0x1b +#define MAX8925_RTC_STATUS 0x20 + +#define TIME_NUM 8 +#define ALARM_1SEC (1 << 7) +#define HOUR_12 (1 << 7) +#define HOUR_AM_PM (1 << 5) +#define ALARM0_IRQ (1 << 3) +#define ALARM1_IRQ (1 << 2) +#define ALARM0_STATUS (1 << 2) +#define ALARM1_STATUS (1 << 1) + + +struct max8925_rtc_info { + struct rtc_device *rtc_dev; + struct max8925_chip *chip; + struct i2c_client *rtc; + struct device *dev; +}; + +static irqreturn_t rtc_update_handler(int irq, void *data) +{ + struct max8925_rtc_info *info = (struct max8925_rtc_info *)data; + + /* disable ALARM0 except for 1SEC alarm */ + max8925_set_bits(info->rtc, MAX8925_ALARM0_CNTL, 0x7f, 0); + rtc_update_irq(info->rtc_dev, 1, RTC_IRQF | RTC_AF); + return IRQ_HANDLED; +} + +static int tm_calc(struct rtc_time *tm, unsigned char *buf, int len) +{ + if (len < TIME_NUM) + return -EINVAL; + tm->tm_year = (buf[RTC_YEAR2] >> 4) * 1000 + + (buf[RTC_YEAR2] & 0xf) * 100 + + (buf[RTC_YEAR1] >> 4) * 10 + + (buf[RTC_YEAR1] & 0xf); + tm->tm_year -= 1900; + tm->tm_mon = ((buf[RTC_MONTH] >> 4) & 0x01) * 10 + + (buf[RTC_MONTH] & 0x0f); + tm->tm_mday = ((buf[RTC_DATE] >> 4) & 0x03) * 10 + + (buf[RTC_DATE] & 0x0f); + tm->tm_wday = buf[RTC_WEEKDAY] & 0x07; + if (buf[RTC_HOUR] & HOUR_12) { + tm->tm_hour = ((buf[RTC_HOUR] >> 4) & 0x1) * 10 + + (buf[RTC_HOUR] & 0x0f); + if (buf[RTC_HOUR] & HOUR_AM_PM) + tm->tm_hour += 12; + } else + tm->tm_hour = ((buf[RTC_HOUR] >> 4) & 0x03) * 10 + + (buf[RTC_HOUR] & 0x0f); + tm->tm_min = ((buf[RTC_MIN] >> 4) & 0x7) * 10 + + (buf[RTC_MIN] & 0x0f); + tm->tm_sec = ((buf[RTC_SEC] >> 4) & 0x7) * 10 + + (buf[RTC_SEC] & 0x0f); + return 0; +} + +static int data_calc(unsigned char *buf, struct rtc_time *tm, int len) +{ + unsigned char high, low; + + if (len < TIME_NUM) + return -EINVAL; + + high = (tm->tm_year + 1900) / 1000; + low = (tm->tm_year + 1900) / 100; + low = low - high * 10; + buf[RTC_YEAR2] = (high << 4) + low; + high = (tm->tm_year + 1900) / 10; + low = tm->tm_year + 1900; + low = low - high * 10; + high = high - (high / 10) * 10; + buf[RTC_YEAR1] = (high << 4) + low; + high = tm->tm_mon / 10; + low = tm->tm_mon; + low = low - high * 10; + buf[RTC_MONTH] = (high << 4) + low; + high = tm->tm_mday / 10; + low = tm->tm_mday; + low = low - high * 10; + buf[RTC_DATE] = (high << 4) + low; + buf[RTC_WEEKDAY] = tm->tm_wday; + high = tm->tm_hour / 10; + low = tm->tm_hour; + low = low - high * 10; + buf[RTC_HOUR] = (high << 4) + low; + high = tm->tm_min / 10; + low = tm->tm_min; + low = low - high * 10; + buf[RTC_MIN] = (high << 4) + low; + high = tm->tm_sec / 10; + low = tm->tm_sec; + low = low - high * 10; + buf[RTC_SEC] = (high << 4) + low; + return 0; +} + +static int max8925_rtc_read_time(struct device *dev, struct rtc_time *tm) +{ + struct max8925_rtc_info *info = dev_get_drvdata(dev); + unsigned char buf[TIME_NUM]; + int ret; + + ret = max8925_bulk_read(info->rtc, MAX8925_RTC_SEC, TIME_NUM, buf); + if (ret < 0) + goto out; + ret = tm_calc(tm, buf, TIME_NUM); +out: + return ret; +} + +static int max8925_rtc_set_time(struct device *dev, struct rtc_time *tm) +{ + struct max8925_rtc_info *info = dev_get_drvdata(dev); + unsigned char buf[TIME_NUM]; + int ret; + + ret = data_calc(buf, tm, TIME_NUM); + if (ret < 0) + goto out; + ret = max8925_bulk_write(info->rtc, MAX8925_RTC_SEC, TIME_NUM, buf); +out: + return ret; +} + +static int max8925_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) +{ + struct max8925_rtc_info *info = dev_get_drvdata(dev); + unsigned char buf[TIME_NUM]; + int ret; + + ret = max8925_bulk_read(info->rtc, MAX8925_ALARM0_SEC, TIME_NUM, buf); + if (ret < 0) + goto out; + ret = tm_calc(&alrm->time, buf, TIME_NUM); + if (ret < 0) + goto out; + ret = max8925_reg_read(info->rtc, MAX8925_RTC_IRQ_MASK); + if (ret < 0) + goto out; + if ((ret & ALARM0_IRQ) == 0) + alrm->enabled = 1; + else + alrm->enabled = 0; + ret = max8925_reg_read(info->rtc, MAX8925_RTC_STATUS); + if (ret < 0) + goto out; + if (ret & ALARM0_STATUS) + alrm->pending = 1; + else + alrm->pending = 0; +out: + return ret; +} + +static int max8925_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) +{ + struct max8925_rtc_info *info = dev_get_drvdata(dev); + unsigned char buf[TIME_NUM]; + int ret; + + ret = data_calc(buf, &alrm->time, TIME_NUM); + if (ret < 0) + goto out; + ret = max8925_bulk_write(info->rtc, MAX8925_ALARM0_SEC, TIME_NUM, buf); + if (ret < 0) + goto out; + /* only enable alarm on year/month/day/hour/min/sec */ + ret = max8925_reg_write(info->rtc, MAX8925_ALARM0_CNTL, 0x77); + if (ret < 0) + goto out; +out: + return ret; +} + +static const struct rtc_class_ops max8925_rtc_ops = { + .read_time = max8925_rtc_read_time, + .set_time = max8925_rtc_set_time, + .read_alarm = max8925_rtc_read_alarm, + .set_alarm = max8925_rtc_set_alarm, +}; + +static int __devinit max8925_rtc_probe(struct platform_device *pdev) +{ + struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent); + struct max8925_rtc_info *info; + int irq, ret; + + info = kzalloc(sizeof(struct max8925_rtc_info), GFP_KERNEL); + if (!info) + return -ENOMEM; + info->chip = chip; + info->rtc = chip->rtc; + info->dev = &pdev->dev; + irq = chip->irq_base + MAX8925_IRQ_RTC_ALARM0; + + ret = request_threaded_irq(irq, NULL, rtc_update_handler, + IRQF_ONESHOT, "rtc-alarm0", info); + if (ret < 0) { + dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n", + irq, ret); + goto out_irq; + } + + info->rtc_dev = rtc_device_register("max8925-rtc", &pdev->dev, + &max8925_rtc_ops, THIS_MODULE); + ret = PTR_ERR(info->rtc_dev); + if (IS_ERR(info->rtc_dev)) { + dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret); + goto out_rtc; + } + + dev_set_drvdata(&pdev->dev, info); + platform_set_drvdata(pdev, info); + + return 0; +out_rtc: + free_irq(chip->irq_base + MAX8925_IRQ_RTC_ALARM0, info); +out_irq: + kfree(info); + return ret; +} + +static int __devexit max8925_rtc_remove(struct platform_device *pdev) +{ + struct max8925_rtc_info *info = platform_get_drvdata(pdev); + + if (info) { + free_irq(info->chip->irq_base + MAX8925_IRQ_RTC_ALARM0, info); + rtc_device_unregister(info->rtc_dev); + kfree(info); + } + return 0; +} + +static struct platform_driver max8925_rtc_driver = { + .driver = { + .name = "max8925-rtc", + .owner = THIS_MODULE, + }, + .probe = max8925_rtc_probe, + .remove = __devexit_p(max8925_rtc_remove), +}; + +static int __init max8925_rtc_init(void) +{ + return platform_driver_register(&max8925_rtc_driver); +} +module_init(max8925_rtc_init); + +static void __exit max8925_rtc_exit(void) +{ + platform_driver_unregister(&max8925_rtc_driver); +} +module_exit(max8925_rtc_exit); + +MODULE_DESCRIPTION("Maxim MAX8925 RTC driver"); +MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>"); +MODULE_LICENSE("GPL"); + diff --git a/drivers/rtc/rtc-wm8350.c b/drivers/rtc/rtc-wm8350.c index f1e44052..3d0dc76 100644 --- a/drivers/rtc/rtc-wm8350.c +++ b/drivers/rtc/rtc-wm8350.c @@ -307,11 +307,18 @@ static int wm8350_rtc_update_irq_enable(struct device *dev, { struct wm8350 *wm8350 = dev_get_drvdata(dev); + /* Suppress duplicate changes since genirq nests enable and + * disable calls. */ + if (enabled == wm8350->rtc.update_enabled) + return 0; + if (enabled) wm8350_unmask_irq(wm8350, WM8350_IRQ_RTC_SEC); else wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_SEC); + wm8350->rtc.update_enabled = enabled; + return 0; } @@ -478,8 +485,8 @@ static int __devexit wm8350_rtc_remove(struct platform_device *pdev) struct wm8350 *wm8350 = platform_get_drvdata(pdev); struct wm8350_rtc *wm_rtc = &wm8350->rtc; - wm8350_free_irq(wm8350, WM8350_IRQ_RTC_SEC); - wm8350_free_irq(wm8350, WM8350_IRQ_RTC_ALM); + wm8350_free_irq(wm8350, WM8350_IRQ_RTC_SEC, wm8350); + wm8350_free_irq(wm8350, WM8350_IRQ_RTC_ALM, wm8350); rtc_device_unregister(wm_rtc->rtc); diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 746e070..d6ff733 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -1009,6 +1009,10 @@ config SERIAL_SH_SCI_CONSOLE depends on SERIAL_SH_SCI=y select SERIAL_CORE_CONSOLE +config SERIAL_SH_SCI_DMA + bool "DMA support" + depends on SERIAL_SH_SCI && SH_DMAE && EXPERIMENTAL + config SERIAL_PNX8XXX bool "Enable PNX8XXX SoCs' UART Support" depends on MIPS && (SOC_PNX8550 || SOC_PNX833X) diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 42f3333..980f394 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c @@ -48,6 +48,9 @@ #include <linux/ctype.h> #include <linux/err.h> #include <linux/list.h> +#include <linux/dmaengine.h> +#include <linux/scatterlist.h> +#include <linux/timer.h> #ifdef CONFIG_SUPERH #include <asm/sh_bios.h> @@ -84,6 +87,27 @@ struct sci_port { struct clk *dclk; struct list_head node; + struct dma_chan *chan_tx; + struct dma_chan *chan_rx; +#ifdef CONFIG_SERIAL_SH_SCI_DMA + struct device *dma_dev; + enum sh_dmae_slave_chan_id slave_tx; + enum sh_dmae_slave_chan_id slave_rx; + struct dma_async_tx_descriptor *desc_tx; + struct dma_async_tx_descriptor *desc_rx[2]; + dma_cookie_t cookie_tx; + dma_cookie_t cookie_rx[2]; + dma_cookie_t active_rx; + struct scatterlist sg_tx; + unsigned int sg_len_tx; + struct scatterlist sg_rx[2]; + size_t buf_len_rx; + struct sh_dmae_slave param_tx; + struct sh_dmae_slave param_rx; + struct work_struct work_tx; + struct work_struct work_rx; + struct timer_list rx_timer; +#endif }; struct sh_sci_priv { @@ -269,29 +293,44 @@ static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) defined(CONFIG_CPU_SUBTYPE_SH7780) || \ defined(CONFIG_CPU_SUBTYPE_SH7785) || \ defined(CONFIG_CPU_SUBTYPE_SH7786) -static inline int scif_txroom(struct uart_port *port) +static int scif_txfill(struct uart_port *port) { - return SCIF_TXROOM_MAX - (sci_in(port, SCTFDR) & 0xff); + return sci_in(port, SCTFDR) & 0xff; } -static inline int scif_rxroom(struct uart_port *port) +static int scif_txroom(struct uart_port *port) +{ + return SCIF_TXROOM_MAX - scif_txfill(port); +} + +static int scif_rxfill(struct uart_port *port) { return sci_in(port, SCRFDR) & 0xff; } #elif defined(CONFIG_CPU_SUBTYPE_SH7763) -static inline int scif_txroom(struct uart_port *port) +static int scif_txfill(struct uart_port *port) { - if ((port->mapbase == 0xffe00000) || - (port->mapbase == 0xffe08000)) { + if (port->mapbase == 0xffe00000 || + port->mapbase == 0xffe08000) /* SCIF0/1*/ - return SCIF_TXROOM_MAX - (sci_in(port, SCTFDR) & 0xff); - } else { + return sci_in(port, SCTFDR) & 0xff; + else /* SCIF2 */ - return SCIF2_TXROOM_MAX - (sci_in(port, SCFDR) >> 8); - } + return sci_in(port, SCFDR) >> 8; } -static inline int scif_rxroom(struct uart_port *port) +static int scif_txroom(struct uart_port *port) +{ + if (port->mapbase == 0xffe00000 || + port->mapbase == 0xffe08000) + /* SCIF0/1*/ + return SCIF_TXROOM_MAX - scif_txfill(port); + else + /* SCIF2 */ + return SCIF2_TXROOM_MAX - scif_txfill(port); +} + +static int scif_rxfill(struct uart_port *port) { if ((port->mapbase == 0xffe00000) || (port->mapbase == 0xffe08000)) { @@ -303,23 +342,33 @@ static inline int scif_rxroom(struct uart_port *port) } } #else -static inline int scif_txroom(struct uart_port *port) +static int scif_txfill(struct uart_port *port) +{ + return sci_in(port, SCFDR) >> 8; +} + +static int scif_txroom(struct uart_port *port) { - return SCIF_TXROOM_MAX - (sci_in(port, SCFDR) >> 8); + return SCIF_TXROOM_MAX - scif_txfill(port); } -static inline int scif_rxroom(struct uart_port *port) +static int scif_rxfill(struct uart_port *port) { return sci_in(port, SCFDR) & SCIF_RFDC_MASK; } #endif -static inline int sci_txroom(struct uart_port *port) +static int sci_txfill(struct uart_port *port) { - return (sci_in(port, SCxSR) & SCI_TDRE) != 0; + return !(sci_in(port, SCxSR) & SCI_TDRE); } -static inline int sci_rxroom(struct uart_port *port) +static int sci_txroom(struct uart_port *port) +{ + return !sci_txfill(port); +} + +static int sci_rxfill(struct uart_port *port) { return (sci_in(port, SCxSR) & SCxSR_RDxF(port)) != 0; } @@ -406,9 +455,9 @@ static inline void sci_receive_chars(struct uart_port *port) while (1) { if (port->type == PORT_SCI) - count = sci_rxroom(port); + count = sci_rxfill(port); else - count = scif_rxroom(port); + count = scif_rxfill(port); /* Don't copy more bytes than there is room for in the buffer */ count = tty_buffer_request_room(tty, count); @@ -453,10 +502,10 @@ static inline void sci_receive_chars(struct uart_port *port) } /* Store data and status */ - if (status&SCxSR_FER(port)) { + if (status & SCxSR_FER(port)) { flag = TTY_FRAME; dev_notice(port->dev, "frame error\n"); - } else if (status&SCxSR_PER(port)) { + } else if (status & SCxSR_PER(port)) { flag = TTY_PARITY; dev_notice(port->dev, "parity error\n"); } else @@ -618,13 +667,39 @@ static inline int sci_handle_breaks(struct uart_port *port) return copied; } -static irqreturn_t sci_rx_interrupt(int irq, void *port) +static irqreturn_t sci_rx_interrupt(int irq, void *ptr) { +#ifdef CONFIG_SERIAL_SH_SCI_DMA + struct uart_port *port = ptr; + struct sci_port *s = to_sci_port(port); + + if (s->chan_rx) { + unsigned long tout; + u16 scr = sci_in(port, SCSCR); + u16 ssr = sci_in(port, SCxSR); + + /* Disable future Rx interrupts */ + sci_out(port, SCSCR, scr & ~SCI_CTRL_FLAGS_RIE); + /* Clear current interrupt */ + sci_out(port, SCxSR, ssr & ~(1 | SCxSR_RDxF(port))); + /* Calculate delay for 1.5 DMA buffers */ + tout = (port->timeout - HZ / 50) * s->buf_len_rx * 3 / + port->fifosize / 2; + dev_dbg(port->dev, "Rx IRQ: setup timeout in %lu ms\n", + tout * 1000 / HZ); + if (tout < 2) + tout = 2; + mod_timer(&s->rx_timer, jiffies + tout); + + return IRQ_HANDLED; + } +#endif + /* I think sci_receive_chars has to be called irrespective * of whether the I_IXOFF is set, otherwise, how is the interrupt * to be disabled? */ - sci_receive_chars(port); + sci_receive_chars(ptr); return IRQ_HANDLED; } @@ -680,6 +755,7 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr) { unsigned short ssr_status, scr_status, err_enabled; struct uart_port *port = ptr; + struct sci_port *s = to_sci_port(port); irqreturn_t ret = IRQ_NONE; ssr_status = sci_in(port, SCxSR); @@ -687,10 +763,15 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr) err_enabled = scr_status & (SCI_CTRL_FLAGS_REIE | SCI_CTRL_FLAGS_RIE); /* Tx Interrupt */ - if ((ssr_status & SCxSR_TDxE(port)) && (scr_status & SCI_CTRL_FLAGS_TIE)) + if ((ssr_status & SCxSR_TDxE(port)) && (scr_status & SCI_CTRL_FLAGS_TIE) && + !s->chan_tx) ret = sci_tx_interrupt(irq, ptr); - /* Rx Interrupt */ - if ((ssr_status & SCxSR_RDxF(port)) && (scr_status & SCI_CTRL_FLAGS_RIE)) + /* + * Rx Interrupt: if we're using DMA, the DMA controller clears RDF / + * DR flags + */ + if (((ssr_status & SCxSR_RDxF(port)) || s->chan_rx) && + (scr_status & SCI_CTRL_FLAGS_RIE)) ret = sci_rx_interrupt(irq, ptr); /* Error Interrupt */ if ((ssr_status & SCxSR_ERRORS(port)) && err_enabled) @@ -699,6 +780,10 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr) if ((ssr_status & SCxSR_BRK(port)) && err_enabled) ret = sci_br_interrupt(irq, ptr); + WARN_ONCE(ret == IRQ_NONE, + "%s: %d IRQ %d, status %x, control %x\n", __func__, + irq, port->line, ssr_status, scr_status); + return ret; } @@ -800,7 +885,9 @@ static void sci_free_irq(struct sci_port *port) static unsigned int sci_tx_empty(struct uart_port *port) { unsigned short status = sci_in(port, SCxSR); - return status & SCxSR_TEND(port) ? TIOCSER_TEMT : 0; + unsigned short in_tx_fifo = scif_txfill(port); + + return (status & SCxSR_TEND(port)) && !in_tx_fifo ? TIOCSER_TEMT : 0; } static void sci_set_mctrl(struct uart_port *port, unsigned int mctrl) @@ -812,16 +899,297 @@ static void sci_set_mctrl(struct uart_port *port, unsigned int mctrl) static unsigned int sci_get_mctrl(struct uart_port *port) { - /* This routine is used for geting signals of: DTR, DCD, DSR, RI, + /* This routine is used for getting signals of: DTR, DCD, DSR, RI, and CTS/RTS */ return TIOCM_DTR | TIOCM_RTS | TIOCM_DSR; } +#ifdef CONFIG_SERIAL_SH_SCI_DMA +static void sci_dma_tx_complete(void *arg) +{ + struct sci_port *s = arg; + struct uart_port *port = &s->port; + struct circ_buf *xmit = &port->state->xmit; + unsigned long flags; + + dev_dbg(port->dev, "%s(%d)\n", __func__, port->line); + + spin_lock_irqsave(&port->lock, flags); + + xmit->tail += s->sg_tx.length; + xmit->tail &= UART_XMIT_SIZE - 1; + + port->icount.tx += s->sg_tx.length; + + async_tx_ack(s->desc_tx); + s->cookie_tx = -EINVAL; + s->desc_tx = NULL; + + spin_unlock_irqrestore(&port->lock, flags); + + if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) + uart_write_wakeup(port); + + if (uart_circ_chars_pending(xmit)) + schedule_work(&s->work_tx); +} + +/* Locking: called with port lock held */ +static int sci_dma_rx_push(struct sci_port *s, struct tty_struct *tty, + size_t count) +{ + struct uart_port *port = &s->port; + int i, active, room; + + room = tty_buffer_request_room(tty, count); + + if (s->active_rx == s->cookie_rx[0]) { + active = 0; + } else if (s->active_rx == s->cookie_rx[1]) { + active = 1; + } else { + dev_err(port->dev, "cookie %d not found!\n", s->active_rx); + return 0; + } + + if (room < count) + dev_warn(port->dev, "Rx overrun: dropping %u bytes\n", + count - room); + if (!room) + return room; + + for (i = 0; i < room; i++) + tty_insert_flip_char(tty, ((u8 *)sg_virt(&s->sg_rx[active]))[i], + TTY_NORMAL); + + port->icount.rx += room; + + return room; +} + +static void sci_dma_rx_complete(void *arg) +{ + struct sci_port *s = arg; + struct uart_port *port = &s->port; + struct tty_struct *tty = port->state->port.tty; + unsigned long flags; + int count; + + dev_dbg(port->dev, "%s(%d)\n", __func__, port->line); + + spin_lock_irqsave(&port->lock, flags); + + count = sci_dma_rx_push(s, tty, s->buf_len_rx); + + mod_timer(&s->rx_timer, jiffies + msecs_to_jiffies(5)); + + spin_unlock_irqrestore(&port->lock, flags); + + if (count) + tty_flip_buffer_push(tty); + + schedule_work(&s->work_rx); +} + +static void sci_start_rx(struct uart_port *port); +static void sci_start_tx(struct uart_port *port); + +static void sci_rx_dma_release(struct sci_port *s, bool enable_pio) +{ + struct dma_chan *chan = s->chan_rx; + struct uart_port *port = &s->port; + + s->chan_rx = NULL; + s->cookie_rx[0] = s->cookie_rx[1] = -EINVAL; + dma_release_channel(chan); + dma_free_coherent(port->dev, s->buf_len_rx * 2, + sg_virt(&s->sg_rx[0]), sg_dma_address(&s->sg_rx[0])); + if (enable_pio) + sci_start_rx(port); +} + +static void sci_tx_dma_release(struct sci_port *s, bool enable_pio) +{ + struct dma_chan *chan = s->chan_tx; + struct uart_port *port = &s->port; + + s->chan_tx = NULL; + s->cookie_tx = -EINVAL; + dma_release_channel(chan); + if (enable_pio) + sci_start_tx(port); +} + +static void sci_submit_rx(struct sci_port *s) +{ + struct dma_chan *chan = s->chan_rx; + int i; + + for (i = 0; i < 2; i++) { + struct scatterlist *sg = &s->sg_rx[i]; + struct dma_async_tx_descriptor *desc; + + desc = chan->device->device_prep_slave_sg(chan, + sg, 1, DMA_FROM_DEVICE, DMA_PREP_INTERRUPT); + + if (desc) { + s->desc_rx[i] = desc; + desc->callback = sci_dma_rx_complete; + desc->callback_param = s; + s->cookie_rx[i] = desc->tx_submit(desc); + } + + if (!desc || s->cookie_rx[i] < 0) { + if (i) { + async_tx_ack(s->desc_rx[0]); + s->cookie_rx[0] = -EINVAL; + } + if (desc) { + async_tx_ack(desc); + s->cookie_rx[i] = -EINVAL; + } + dev_warn(s->port.dev, + "failed to re-start DMA, using PIO\n"); + sci_rx_dma_release(s, true); + return; + } + } + + s->active_rx = s->cookie_rx[0]; + + dma_async_issue_pending(chan); +} + +static void work_fn_rx(struct work_struct *work) +{ + struct sci_port *s = container_of(work, struct sci_port, work_rx); + struct uart_port *port = &s->port; + struct dma_async_tx_descriptor *desc; + int new; + + if (s->active_rx == s->cookie_rx[0]) { + new = 0; + } else if (s->active_rx == s->cookie_rx[1]) { + new = 1; + } else { + dev_err(port->dev, "cookie %d not found!\n", s->active_rx); + return; + } + desc = s->desc_rx[new]; + + if (dma_async_is_tx_complete(s->chan_rx, s->active_rx, NULL, NULL) != + DMA_SUCCESS) { + /* Handle incomplete DMA receive */ + struct tty_struct *tty = port->state->port.tty; + struct dma_chan *chan = s->chan_rx; + struct sh_desc *sh_desc = container_of(desc, struct sh_desc, + async_tx); + unsigned long flags; + int count; + + chan->device->device_terminate_all(chan); + dev_dbg(port->dev, "Read %u bytes with cookie %d\n", + sh_desc->partial, sh_desc->cookie); + + spin_lock_irqsave(&port->lock, flags); + count = sci_dma_rx_push(s, tty, sh_desc->partial); + spin_unlock_irqrestore(&port->lock, flags); + + if (count) + tty_flip_buffer_push(tty); + + sci_submit_rx(s); + + return; + } + + s->cookie_rx[new] = desc->tx_submit(desc); + if (s->cookie_rx[new] < 0) { + dev_warn(port->dev, "Failed submitting Rx DMA descriptor\n"); + sci_rx_dma_release(s, true); + return; + } + + dev_dbg(port->dev, "%s: cookie %d #%d\n", __func__, + s->cookie_rx[new], new); + + s->active_rx = s->cookie_rx[!new]; +} + +static void work_fn_tx(struct work_struct *work) +{ + struct sci_port *s = container_of(work, struct sci_port, work_tx); + struct dma_async_tx_descriptor *desc; + struct dma_chan *chan = s->chan_tx; + struct uart_port *port = &s->port; + struct circ_buf *xmit = &port->state->xmit; + struct scatterlist *sg = &s->sg_tx; + + /* + * DMA is idle now. + * Port xmit buffer is already mapped, and it is one page... Just adjust + * offsets and lengths. Since it is a circular buffer, we have to + * transmit till the end, and then the rest. Take the port lock to get a + * consistent xmit buffer state. + */ + spin_lock_irq(&port->lock); + sg->offset = xmit->tail & (UART_XMIT_SIZE - 1); + sg->dma_address = (sg_dma_address(sg) & ~(UART_XMIT_SIZE - 1)) + + sg->offset; + sg->length = min((int)CIRC_CNT(xmit->head, xmit->tail, UART_XMIT_SIZE), + CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE)); + sg->dma_length = sg->length; + spin_unlock_irq(&port->lock); + + BUG_ON(!sg->length); + + desc = chan->device->device_prep_slave_sg(chan, + sg, s->sg_len_tx, DMA_TO_DEVICE, + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + if (!desc) { + /* switch to PIO */ + sci_tx_dma_release(s, true); + return; + } + + dma_sync_sg_for_device(port->dev, sg, 1, DMA_TO_DEVICE); + + spin_lock_irq(&port->lock); + s->desc_tx = desc; + desc->callback = sci_dma_tx_complete; + desc->callback_param = s; + spin_unlock_irq(&port->lock); + s->cookie_tx = desc->tx_submit(desc); + if (s->cookie_tx < 0) { + dev_warn(port->dev, "Failed submitting Tx DMA descriptor\n"); + /* switch to PIO */ + sci_tx_dma_release(s, true); + return; + } + + dev_dbg(port->dev, "%s: %p: %d...%d, cookie %d\n", __func__, + xmit->buf, xmit->tail, xmit->head, s->cookie_tx); + + dma_async_issue_pending(chan); +} +#endif + static void sci_start_tx(struct uart_port *port) { unsigned short ctrl; +#ifdef CONFIG_SERIAL_SH_SCI_DMA + struct sci_port *s = to_sci_port(port); + + if (s->chan_tx) { + if (!uart_circ_empty(&s->port.state->xmit) && s->cookie_tx < 0) + schedule_work(&s->work_tx); + + return; + } +#endif + /* Set TIE (Transmit Interrupt Enable) bit in SCSCR */ ctrl = sci_in(port, SCSCR); ctrl |= SCI_CTRL_FLAGS_TIE; @@ -838,13 +1206,12 @@ static void sci_stop_tx(struct uart_port *port) sci_out(port, SCSCR, ctrl); } -static void sci_start_rx(struct uart_port *port, unsigned int tty_start) +static void sci_start_rx(struct uart_port *port) { - unsigned short ctrl; + unsigned short ctrl = SCI_CTRL_FLAGS_RIE | SCI_CTRL_FLAGS_REIE; /* Set RIE (Receive Interrupt Enable) bit in SCSCR */ - ctrl = sci_in(port, SCSCR); - ctrl |= SCI_CTRL_FLAGS_RIE | SCI_CTRL_FLAGS_REIE; + ctrl |= sci_in(port, SCSCR); sci_out(port, SCSCR, ctrl); } @@ -868,16 +1235,154 @@ static void sci_break_ctl(struct uart_port *port, int break_state) /* Nothing here yet .. */ } +#ifdef CONFIG_SERIAL_SH_SCI_DMA +static bool filter(struct dma_chan *chan, void *slave) +{ + struct sh_dmae_slave *param = slave; + + dev_dbg(chan->device->dev, "%s: slave ID %d\n", __func__, + param->slave_id); + + if (param->dma_dev == chan->device->dev) { + chan->private = param; + return true; + } else { + return false; + } +} + +static void rx_timer_fn(unsigned long arg) +{ + struct sci_port *s = (struct sci_port *)arg; + struct uart_port *port = &s->port; + + u16 scr = sci_in(port, SCSCR); + sci_out(port, SCSCR, scr | SCI_CTRL_FLAGS_RIE); + dev_dbg(port->dev, "DMA Rx timed out\n"); + schedule_work(&s->work_rx); +} + +static void sci_request_dma(struct uart_port *port) +{ + struct sci_port *s = to_sci_port(port); + struct sh_dmae_slave *param; + struct dma_chan *chan; + dma_cap_mask_t mask; + int nent; + + dev_dbg(port->dev, "%s: port %d DMA %p\n", __func__, + port->line, s->dma_dev); + + if (!s->dma_dev) + return; + + dma_cap_zero(mask); + dma_cap_set(DMA_SLAVE, mask); + + param = &s->param_tx; + + /* Slave ID, e.g., SHDMA_SLAVE_SCIF0_TX */ + param->slave_id = s->slave_tx; + param->dma_dev = s->dma_dev; + + s->cookie_tx = -EINVAL; + chan = dma_request_channel(mask, filter, param); + dev_dbg(port->dev, "%s: TX: got channel %p\n", __func__, chan); + if (chan) { + s->chan_tx = chan; + sg_init_table(&s->sg_tx, 1); + /* UART circular tx buffer is an aligned page. */ + BUG_ON((int)port->state->xmit.buf & ~PAGE_MASK); + sg_set_page(&s->sg_tx, virt_to_page(port->state->xmit.buf), + UART_XMIT_SIZE, (int)port->state->xmit.buf & ~PAGE_MASK); + nent = dma_map_sg(port->dev, &s->sg_tx, 1, DMA_TO_DEVICE); + if (!nent) + sci_tx_dma_release(s, false); + else + dev_dbg(port->dev, "%s: mapped %d@%p to %x\n", __func__, + sg_dma_len(&s->sg_tx), + port->state->xmit.buf, sg_dma_address(&s->sg_tx)); + + s->sg_len_tx = nent; + + INIT_WORK(&s->work_tx, work_fn_tx); + } + + param = &s->param_rx; + + /* Slave ID, e.g., SHDMA_SLAVE_SCIF0_RX */ + param->slave_id = s->slave_rx; + param->dma_dev = s->dma_dev; + + chan = dma_request_channel(mask, filter, param); + dev_dbg(port->dev, "%s: RX: got channel %p\n", __func__, chan); + if (chan) { + dma_addr_t dma[2]; + void *buf[2]; + int i; + + s->chan_rx = chan; + + s->buf_len_rx = 2 * max(16, (int)port->fifosize); + buf[0] = dma_alloc_coherent(port->dev, s->buf_len_rx * 2, + &dma[0], GFP_KERNEL); + + if (!buf[0]) { + dev_warn(port->dev, + "failed to allocate dma buffer, using PIO\n"); + sci_rx_dma_release(s, true); + return; + } + + buf[1] = buf[0] + s->buf_len_rx; + dma[1] = dma[0] + s->buf_len_rx; + + for (i = 0; i < 2; i++) { + struct scatterlist *sg = &s->sg_rx[i]; + + sg_init_table(sg, 1); + sg_set_page(sg, virt_to_page(buf[i]), s->buf_len_rx, + (int)buf[i] & ~PAGE_MASK); + sg->dma_address = dma[i]; + sg->dma_length = sg->length; + } + + INIT_WORK(&s->work_rx, work_fn_rx); + setup_timer(&s->rx_timer, rx_timer_fn, (unsigned long)s); + + sci_submit_rx(s); + } +} + +static void sci_free_dma(struct uart_port *port) +{ + struct sci_port *s = to_sci_port(port); + + if (!s->dma_dev) + return; + + if (s->chan_tx) + sci_tx_dma_release(s, false); + if (s->chan_rx) + sci_rx_dma_release(s, false); +} +#endif + static int sci_startup(struct uart_port *port) { struct sci_port *s = to_sci_port(port); + dev_dbg(port->dev, "%s(%d)\n", __func__, port->line); + if (s->enable) s->enable(port); sci_request_irq(s); +#ifdef CONFIG_SERIAL_SH_SCI_DMA + sci_request_dma(port); +#endif sci_start_tx(port); - sci_start_rx(port, 1); + sci_start_rx(port); return 0; } @@ -886,8 +1391,13 @@ static void sci_shutdown(struct uart_port *port) { struct sci_port *s = to_sci_port(port); + dev_dbg(port->dev, "%s(%d)\n", __func__, port->line); + sci_stop_rx(port); sci_stop_tx(port); +#ifdef CONFIG_SERIAL_SH_SCI_DMA + sci_free_dma(port); +#endif sci_free_irq(s); if (s->disable) @@ -937,6 +1447,9 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, sci_out(port, SCSMR, smr_val); + dev_dbg(port->dev, "%s: SMR %x, t %x, SCSCR %x\n", __func__, smr_val, t, + SCSCR_INIT(port)); + if (t > 0) { if (t >= 256) { sci_out(port, SCSMR, (sci_in(port, SCSMR) & ~3) | 1); @@ -954,7 +1467,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, sci_out(port, SCSCR, SCSCR_INIT(port)); if ((termios->c_cflag & CREAD) != 0) - sci_start_rx(port, 0); + sci_start_rx(port); } static const char *sci_type(struct uart_port *port) @@ -1049,19 +1562,21 @@ static void __devinit sci_init_single(struct platform_device *dev, unsigned int index, struct plat_sci_port *p) { - sci_port->port.ops = &sci_uart_ops; - sci_port->port.iotype = UPIO_MEM; - sci_port->port.line = index; + struct uart_port *port = &sci_port->port; + + port->ops = &sci_uart_ops; + port->iotype = UPIO_MEM; + port->line = index; switch (p->type) { case PORT_SCIFA: - sci_port->port.fifosize = 64; + port->fifosize = 64; break; case PORT_SCIF: - sci_port->port.fifosize = 16; + port->fifosize = 16; break; default: - sci_port->port.fifosize = 1; + port->fifosize = 1; break; } @@ -1070,19 +1585,28 @@ static void __devinit sci_init_single(struct platform_device *dev, sci_port->dclk = clk_get(&dev->dev, "peripheral_clk"); sci_port->enable = sci_clk_enable; sci_port->disable = sci_clk_disable; - sci_port->port.dev = &dev->dev; + port->dev = &dev->dev; } sci_port->break_timer.data = (unsigned long)sci_port; sci_port->break_timer.function = sci_break_timer; init_timer(&sci_port->break_timer); - sci_port->port.mapbase = p->mapbase; - sci_port->port.membase = p->membase; + port->mapbase = p->mapbase; + port->membase = p->membase; - sci_port->port.irq = p->irqs[SCIx_TXI_IRQ]; - sci_port->port.flags = p->flags; - sci_port->type = sci_port->port.type = p->type; + port->irq = p->irqs[SCIx_TXI_IRQ]; + port->flags = p->flags; + sci_port->type = port->type = p->type; + +#ifdef CONFIG_SERIAL_SH_SCI_DMA + sci_port->dma_dev = p->dma_dev; + sci_port->slave_tx = p->dma_slave_tx; + sci_port->slave_rx = p->dma_slave_rx; + + dev_dbg(port->dev, "%s: DMA device %p, tx %d, rx %d\n", __func__, + p->dma_dev, p->dma_slave_tx, p->dma_slave_rx); +#endif memcpy(&sci_port->irqs, &p->irqs, sizeof(p->irqs)); } diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index fc2e963..7696a66 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -71,8 +71,6 @@ source "drivers/staging/asus_oled/Kconfig" source "drivers/staging/panel/Kconfig" -source "drivers/staging/altpciechdma/Kconfig" - source "drivers/staging/rtl8187se/Kconfig" source "drivers/staging/rtl8192su/Kconfig" @@ -81,20 +79,14 @@ source "drivers/staging/rtl8192u/Kconfig" source "drivers/staging/rtl8192e/Kconfig" -source "drivers/staging/mimio/Kconfig" - source "drivers/staging/frontier/Kconfig" source "drivers/staging/dream/Kconfig" source "drivers/staging/pohmelfs/Kconfig" -source "drivers/staging/b3dfg/Kconfig" - source "drivers/staging/phison/Kconfig" -source "drivers/staging/p9auth/Kconfig" - source "drivers/staging/line6/Kconfig" source "drivers/gpu/drm/vmwgfx/Kconfig" @@ -117,7 +109,7 @@ source "drivers/staging/hv/Kconfig" source "drivers/staging/vme/Kconfig" -source "drivers/staging/rar/Kconfig" +source "drivers/staging/rar_register/Kconfig" source "drivers/staging/sep/Kconfig" @@ -143,5 +135,9 @@ source "drivers/staging/netwave/Kconfig" source "drivers/staging/sm7xx/Kconfig" +source "drivers/staging/dt3155/Kconfig" + +source "drivers/staging/crystalhd/Kconfig" + endif # !STAGING_EXCLUDE_BUILD endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index b5e67b8..ea2e70e 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -18,18 +18,14 @@ obj-$(CONFIG_RT2870) += rt2870/ obj-$(CONFIG_COMEDI) += comedi/ obj-$(CONFIG_ASUS_OLED) += asus_oled/ obj-$(CONFIG_PANEL) += panel/ -obj-$(CONFIG_ALTERA_PCIE_CHDMA) += altpciechdma/ obj-$(CONFIG_R8187SE) += rtl8187se/ obj-$(CONFIG_RTL8192SU) += rtl8192su/ obj-$(CONFIG_RTL8192U) += rtl8192u/ obj-$(CONFIG_RTL8192E) += rtl8192e/ -obj-$(CONFIG_INPUT_MIMIO) += mimio/ obj-$(CONFIG_TRANZPORT) += frontier/ obj-$(CONFIG_DREAM) += dream/ obj-$(CONFIG_POHMELFS) += pohmelfs/ -obj-$(CONFIG_B3DFG) += b3dfg/ obj-$(CONFIG_IDE_PHISON) += phison/ -obj-$(CONFIG_PLAN9AUTH) += p9auth/ obj-$(CONFIG_LINE6_USB) += line6/ obj-$(CONFIG_USB_SERIAL_QUATECH2) += serqt_usb2/ obj-$(CONFIG_USB_SERIAL_QUATECH_USB2) += quatech_usb2/ @@ -39,7 +35,7 @@ obj-$(CONFIG_VT6656) += vt6656/ obj-$(CONFIG_FB_UDL) += udlfb/ obj-$(CONFIG_HYPERV) += hv/ obj-$(CONFIG_VME_BUS) += vme/ -obj-$(CONFIG_RAR_REGISTER) += rar/ +obj-$(CONFIG_RAR_REGISTER) += rar_register/ obj-$(CONFIG_DX_SEP) += sep/ obj-$(CONFIG_IIO) += iio/ obj-$(CONFIG_RAMZSWAP) += ramzswap/ @@ -53,3 +49,5 @@ obj-$(CONFIG_WAVELAN) += wavelan/ obj-$(CONFIG_PCMCIA_WAVELAN) += wavelan/ obj-$(CONFIG_PCMCIA_NETWAVE) += netwave/ obj-$(CONFIG_FB_SM7XX) += sm7xx/ +obj-$(CONFIG_DT3155) += dt3155/ +obj-$(CONFIG_CRYSTALHD) += crystalhd/ diff --git a/drivers/staging/altpciechdma/Kconfig b/drivers/staging/altpciechdma/Kconfig deleted file mode 100644 index 0f4bf92..0000000 --- a/drivers/staging/altpciechdma/Kconfig +++ /dev/null @@ -1,10 +0,0 @@ -config ALTERA_PCIE_CHDMA - tristate "Altera PCI Express Chaining DMA driver" - depends on PCI - default N - ---help--- - A reference driver that exercises the Chaining DMA logic reference - design generated along the Altera FPGA PCI Express soft or hard core, - only if instantiated using the MegaWizard, not the SOPC builder, of - Quartus 8.1. - diff --git a/drivers/staging/altpciechdma/Makefile b/drivers/staging/altpciechdma/Makefile deleted file mode 100644 index c08c843..0000000 --- a/drivers/staging/altpciechdma/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -obj-$(CONFIG_ALTERA_PCIE_CHDMA) += altpciechdma.o - diff --git a/drivers/staging/altpciechdma/TODO b/drivers/staging/altpciechdma/TODO deleted file mode 100644 index 12c945f..0000000 --- a/drivers/staging/altpciechdma/TODO +++ /dev/null @@ -1,15 +0,0 @@ -DONE: - - functionality similar to logic testbench - -TODO: - - checkpatch.pl cleanups. - - keep state of DMA engines. - - keep data structure that keeps state of each transfer. - - interrupt handler should iterate over outstanding descriptor tables. - - complete userspace cdev to read/write using the DMA engines. - - split off the DMA support functions in a module, re-usable by custom - drivers. - -Please coordinate work with, and send patches to -Leon Woestenberg <leon@sidebranch.com> - diff --git a/drivers/staging/altpciechdma/altpciechdma.c b/drivers/staging/altpciechdma/altpciechdma.c deleted file mode 100644 index 2f07dd4..0000000 --- a/drivers/staging/altpciechdma/altpciechdma.c +++ /dev/null @@ -1,1182 +0,0 @@ -/** - * Driver for Altera PCIe core chaining DMA reference design. - * - * Copyright (C) 2008 Leon Woestenberg <leon.woestenberg@axon.tv> - * Copyright (C) 2008 Nickolas Heppermann <heppermannwdt@gmail.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. - * - * 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., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * - * Rationale: This driver exercises the chaining DMA read and write engine - * in the reference design. It is meant as a complementary reference - * driver that can be used for testing early designs as well as a basis to - * write your custom driver. - * - * Status: Test results from Leon Woestenberg <leon.woestenberg@axon.tv>: - * - * Sendero Board w/ Cyclone II EP2C35F672C6N, PX1011A PCIe x1 PHY on a - * Dell Precision 370 PC, x86, kernel 2.6.20 from Ubuntu 7.04. - * - * Sendero Board w/ Cyclone II EP2C35F672C6N, PX1011A PCIe x1 PHY on a - * Freescale MPC8313E-RDB board, PowerPC, 2.6.24 w/ Freescale patches. - * - * Driver tests passed with PCIe Compiler 8.1. With PCIe 8.0 the DMA - * loopback test had reproducable compare errors. I assume a change - * in the compiler or reference design, but could not find evidence nor - * documentation on a change or fix in that direction. - * - * The reference design does not have readable locations and thus a - * dummy read, used to flush PCI posted writes, cannot be performed. - * - */ - -#include <linux/kernel.h> -#include <linux/cdev.h> -#include <linux/delay.h> -#include <linux/dma-mapping.h> -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/io.h> -#include <linux/jiffies.h> -#include <linux/module.h> -#include <linux/pci.h> - - -/* by default do not build the character device interface */ -/* XXX It is non-functional yet */ -#ifndef ALTPCIECHDMA_CDEV -# define ALTPCIECHDMA_CDEV 0 -#endif - -/* build the character device interface? */ -#if ALTPCIECHDMA_CDEV -# define MAX_CHDMA_SIZE (8 * 1024 * 1024) -# include "mapper_user_to_sg.h" -#endif - -/** driver name, mimicks Altera naming of the reference design */ -#define DRV_NAME "altpciechdma" -/** number of BARs on the device */ -#define APE_BAR_NUM (6) -/** BAR number where the RCSLAVE memory sits */ -#define APE_BAR_RCSLAVE (0) -/** BAR number where the Descriptor Header sits */ -#define APE_BAR_HEADER (2) - -/** maximum size in bytes of the descriptor table, chdma logic limit */ -#define APE_CHDMA_TABLE_SIZE (4096) -/* single transfer must not exceed 255 table entries. worst case this can be - * achieved by 255 scattered pages, with only a single byte in the head and - * tail pages. 253 * PAGE_SIZE is a safe upper bound for the transfer size. - */ -#define APE_CHDMA_MAX_TRANSFER_LEN (253 * PAGE_SIZE) - -/** - * Specifies those BARs to be mapped and the length of each mapping. - * - * Zero (0) means do not map, otherwise specifies the BAR lengths to be mapped. - * If the actual BAR length is less, this is considered an error; then - * reconfigure your PCIe core. - * - * @see ug_pci_express 8.0, table 7-2 at page 7-13. - */ -static const unsigned long bar_min_len[APE_BAR_NUM] = - { 32768, 0, 256, 0, 32768, 0 }; - -/** - * Descriptor Header, controls the DMA read engine or write engine. - * - * The descriptor header is the main data structure for starting DMA transfers. - * - * It sits in End Point (FPGA) memory BAR[2] for 32-bit or BAR[3:2] for 64-bit. - * It references a descriptor table which exists in Root Complex (PC) memory. - * Writing the rclast field starts the DMA operation, thus all other structures - * and fields must be setup before doing so. - * - * @see ug_pci_express 8.0, tables 7-3, 7-4 and 7-5 at page 7-14. - * @note This header must be written in four 32-bit (PCI DWORD) writes. - */ -struct ape_chdma_header { - /** - * w0 consists of two 16-bit fields: - * lsb u16 number; number of descriptors in ape_chdma_table - * msb u16 control; global control flags - */ - u32 w0; - /* bus address to ape_chdma_table in Root Complex memory */ - u32 bdt_addr_h; - u32 bdt_addr_l; - /** - * w3 consists of two 16-bit fields: - * - lsb u16 rclast; last descriptor number available in Root Complex - * - zero (0) means the first descriptor is ready, - * - one (1) means two descriptors are ready, etc. - * - msb u16 reserved; - * - * @note writing to this memory location starts the DMA operation! - */ - u32 w3; -} __attribute__ ((packed)); - -/** - * Descriptor Entry, describing a (non-scattered) single memory block transfer. - * - * There is one descriptor for each memory block involved in the transfer, a - * block being a contiguous address range on the bus. - * - * Multiple descriptors are chained by means of the ape_chdma_table data - * structure. - * - * @see ug_pci_express 8.0, tables 7-6, 7-7 and 7-8 at page 7-14 and page 7-15. - */ -struct ape_chdma_desc { - /** - * w0 consists of two 16-bit fields: - * number of DWORDS to transfer - * - lsb u16 length; - * global control - * - msb u16 control; - */ - u32 w0; - /* address of memory in the End Point */ - u32 ep_addr; - /* bus address of source or destination memory in the Root Complex */ - u32 rc_addr_h; - u32 rc_addr_l; -} __attribute__ ((packed)); - -/** - * Descriptor Table, an array of descriptors describing a chained transfer. - * - * An array of descriptors, preceded by workspace for the End Point. - * It exists in Root Complex memory. - * - * The End Point can update its last completed descriptor number in the - * eplast field if requested by setting the EPLAST_ENA bit either - * globally in the header's or locally in any descriptor's control field. - * - * @note this structure may not exceed 4096 bytes. This results in a - * maximum of 4096 / (4 * 4) - 1 = 255 descriptors per chained transfer. - * - * @see ug_pci_express 8.0, tables 7-9, 7-10 and 7-11 at page 7-17 and page 7-18. - */ -struct ape_chdma_table { - /* workspace 0x00-0x0b, reserved */ - u32 reserved1[3]; - /* workspace 0x0c-0x0f, last descriptor handled by End Point */ - u32 w3; - /* the actual array of descriptors - * 0x10-0x1f, 0x20-0x2f, ... 0xff0-0xfff (255 entries) - */ - struct ape_chdma_desc desc[255]; -} __attribute__ ((packed)); - -/** - * Altera PCI Express ('ape') board specific book keeping data - * - * Keeps state of the PCIe core and the Chaining DMA controller - * application. - */ -struct ape_dev { - /** the kernel pci device data structure provided by probe() */ - struct pci_dev *pci_dev; - /** - * kernel virtual address of the mapped BAR memory and IO regions of - * the End Point. Used by map_bars()/unmap_bars(). - */ - void * __iomem bar[APE_BAR_NUM]; - /** kernel virtual address for Descriptor Table in Root Complex memory */ - struct ape_chdma_table *table_virt; - /** - * bus address for the Descriptor Table in Root Complex memory, in - * CPU-native endianess - */ - dma_addr_t table_bus; - /* if the device regions could not be allocated, assume and remember it - * is in use by another driver; this driver must not disable the device. - */ - int in_use; - /* whether this driver enabled msi for the device */ - int msi_enabled; - /* whether this driver could obtain the regions */ - int got_regions; - /* irq line successfully requested by this driver, -1 otherwise */ - int irq_line; - /* board revision */ - u8 revision; - /* interrupt count, incremented by the interrupt handler */ - int irq_count; -#if ALTPCIECHDMA_CDEV - /* character device */ - dev_t cdevno; - struct cdev cdev; - /* user space scatter gather mapper */ - struct sg_mapping_t *sgm; -#endif -}; - -/** - * Using the subsystem vendor id and subsystem id, it is possible to - * distinguish between different cards bases around the same - * (third-party) logic core. - * - * Default Altera vendor and device ID's, and some (non-reserved) - * ID's are now used here that are used amongst the testers/developers. - */ -static const struct pci_device_id ids[] = { - { PCI_DEVICE(0x1172, 0xE001), }, - { PCI_DEVICE(0x2071, 0x2071), }, - { 0, } -}; -MODULE_DEVICE_TABLE(pci, ids); - -#if ALTPCIECHDMA_CDEV -/* prototypes for character device */ -static int sg_init(struct ape_dev *ape); -static void sg_exit(struct ape_dev *ape); -#endif - -/** - * altpciechdma_isr() - Interrupt handler - * - */ -static irqreturn_t altpciechdma_isr(int irq, void *dev_id) -{ - struct ape_dev *ape = (struct ape_dev *)dev_id; - if (!ape) - return IRQ_NONE; - ape->irq_count++; - return IRQ_HANDLED; -} - -static int __devinit scan_bars(struct ape_dev *ape, struct pci_dev *dev) -{ - int i; - for (i = 0; i < APE_BAR_NUM; i++) { - unsigned long bar_start = pci_resource_start(dev, i); - if (bar_start) { - unsigned long bar_end = pci_resource_end(dev, i); - unsigned long bar_flags = pci_resource_flags(dev, i); - printk(KERN_DEBUG "BAR%d 0x%08lx-0x%08lx flags 0x%08lx\n", - i, bar_start, bar_end, bar_flags); - } - } - return 0; -} - -/** - * Unmap the BAR regions that had been mapped earlier using map_bars() - */ -static void unmap_bars(struct ape_dev *ape, struct pci_dev *dev) -{ - int i; - for (i = 0; i < APE_BAR_NUM; i++) { - /* is this BAR mapped? */ - if (ape->bar[i]) { - /* unmap BAR */ - pci_iounmap(dev, ape->bar[i]); - ape->bar[i] = NULL; - } - } -} - -/** - * Map the device memory regions into kernel virtual address space after - * verifying their sizes respect the minimum sizes needed, given by the - * bar_min_len[] array. - */ -static int __devinit map_bars(struct ape_dev *ape, struct pci_dev *dev) -{ - int rc; - int i; - /* iterate through all the BARs */ - for (i = 0; i < APE_BAR_NUM; i++) { - unsigned long bar_start = pci_resource_start(dev, i); - unsigned long bar_end = pci_resource_end(dev, i); - unsigned long bar_length = bar_end - bar_start + 1; - ape->bar[i] = NULL; - /* do not map, and skip, BARs with length 0 */ - if (!bar_min_len[i]) - continue; - /* do not map BARs with address 0 */ - if (!bar_start || !bar_end) { - printk(KERN_DEBUG "BAR #%d is not present?!\n", i); - rc = -1; - goto fail; - } - bar_length = bar_end - bar_start + 1; - /* BAR length is less than driver requires? */ - if (bar_length < bar_min_len[i]) { - printk(KERN_DEBUG "BAR #%d length = %lu bytes but driver " - "requires at least %lu bytes\n", - i, bar_length, bar_min_len[i]); - rc = -1; - goto fail; - } - /* map the device memory or IO region into kernel virtual - * address space */ - ape->bar[i] = pci_iomap(dev, i, bar_min_len[i]); - if (!ape->bar[i]) { - printk(KERN_DEBUG "Could not map BAR #%d.\n", i); - rc = -1; - goto fail; - } - printk(KERN_DEBUG "BAR[%d] mapped at 0x%p with length %lu(/%lu).\n", i, - ape->bar[i], bar_min_len[i], bar_length); - } - /* successfully mapped all required BAR regions */ - rc = 0; - goto success; -fail: - /* unmap any BARs that we did map */ - unmap_bars(ape, dev); -success: - return rc; -} - -#if 0 /* not yet implemented fully FIXME add opcode */ -static void __devinit rcslave_test(struct ape_dev *ape, struct pci_dev *dev) -{ - u32 *rcslave_mem = (u32 *)ape->bar[APE_BAR_RCSLAVE]; - u32 result = 0; - /** this number is assumed to be different each time this test runs */ - u32 seed = (u32)jiffies; - u32 value = seed; - int i; - - /* write loop */ - value = seed; - for (i = 1024; i < 32768 / 4 ; i++) { - printk(KERN_DEBUG "Writing 0x%08x to 0x%p.\n", - (u32)value, (void *)rcslave_mem + i); - iowrite32(value, rcslave_mem + i); - value++; - } - /* read-back loop */ - value = seed; - for (i = 1024; i < 32768 / 4; i++) { - result = ioread32(rcslave_mem + i); - if (result != value) { - printk(KERN_DEBUG "Wrote 0x%08x to 0x%p, but read back 0x%08x.\n", - (u32)value, (void *)rcslave_mem + i, (u32)result); - break; - } - value++; - } -} -#endif - -/* obtain the 32 most significant (high) bits of a 32-bit or 64-bit address */ -#define pci_dma_h(addr) ((addr >> 16) >> 16) -/* obtain the 32 least significant (low) bits of a 32-bit or 64-bit address */ -#define pci_dma_l(addr) (addr & 0xffffffffUL) - -/* ape_fill_chdma_desc() - Fill a Altera PCI Express Chaining DMA descriptor - * - * @desc pointer to descriptor to be filled - * @addr root complex address - * @ep_addr end point address - * @len number of bytes, must be a multiple of 4. - */ -static inline void ape_chdma_desc_set(struct ape_chdma_desc *desc, dma_addr_t addr, u32 ep_addr, int len) -{ - BUG_ON(len & 3); - desc->w0 = cpu_to_le32(len / 4); - desc->ep_addr = cpu_to_le32(ep_addr); - desc->rc_addr_h = cpu_to_le32(pci_dma_h(addr)); - desc->rc_addr_l = cpu_to_le32(pci_dma_l(addr)); -} - -#if ALTPCIECHDMA_CDEV -/* - * ape_sg_to_chdma_table() - Create a device descriptor table from a scatterlist. - * - * The scatterlist must have been mapped by pci_map_sg(sgm->sgl). - * - * @sgl scatterlist. - * @nents Number of entries in the scatterlist. - * @first Start index in the scatterlist sgm->sgl. - * @ep_addr End Point address for the scatter/gather transfer. - * @desc pointer to first descriptor - * - * Returns Number of entries in the table on success, -1 on error. - */ -static int ape_sg_to_chdma_table(struct scatterlist *sgl, int nents, int first, struct ape_chdma_desc *desc, u32 ep_addr) -{ - int i = first, j = 0; - /* inspect first entry */ - dma_addr_t addr = sg_dma_address(&sgl[i]); - unsigned int len = sg_dma_len(&sgl[i]); - /* contiguous block */ - dma_addr_t cont_addr = addr; - unsigned int cont_len = len; - /* iterate over remaining entries */ - for (; j < 25 && i < nents - 1; i++) { - /* bus address of next entry i + 1 */ - dma_addr_t next = sg_dma_address(&sgl[i + 1]); - /* length of this entry i */ - len = sg_dma_len(&sgl[i]); - printk(KERN_DEBUG "%04d: addr=0x%Lx length=0x%08x\n", i, - (unsigned long long)addr, len); - /* entry i + 1 is non-contiguous with entry i? */ - if (next != addr + len) { - /* TODO create entry here (we could overwrite i) */ - printk(KERN_DEBUG "%4d: cont_addr=0x%Lx cont_len=0x%08x\n", j, - (unsigned long long)cont_addr, cont_len); - /* set descriptor for contiguous transfer */ - ape_chdma_desc_set(&desc[j], cont_addr, ep_addr, cont_len); - /* next end point memory address */ - ep_addr += cont_len; - /* start new contiguous block */ - cont_addr = next; - cont_len = 0; - j++; - } - /* add entry i + 1 to current contiguous block */ - cont_len += len; - /* goto entry i + 1 */ - addr = next; - } - /* TODO create entry here (we could overwrite i) */ - printk(KERN_DEBUG "%04d: addr=0x%Lx length=0x%08x\n", i, - (unsigned long long)addr, len); - printk(KERN_DEBUG "%4d: cont_addr=0x%Lx length=0x%08x\n", j, - (unsigned long long)cont_addr, cont_len); - j++; - return j; -} -#endif - -/* compare buffers */ -static inline int compare(u32 *p, u32 *q, int len) -{ - int result = -1; - int fail = 0; - int i; - for (i = 0; i < len / 4; i++) { - if (*p == *q) { - /* every so many u32 words, show equals */ - if ((i & 255) == 0) - printk(KERN_DEBUG "[%p] = 0x%08x [%p] = 0x%08x\n", p, *p, q, *q); - } else { - fail++; - /* show the first few miscompares */ - if (fail < 10) - printk(KERN_DEBUG "[%p] = 0x%08x != [%p] = 0x%08x ?!\n", p, *p, q, *q); - /* but stop after a while */ - else if (fail == 10) - printk(KERN_DEBUG "---more errors follow! not printed---\n"); - else - /* stop compare after this many errors */ - break; - } - p++; - q++; - } - if (!fail) - result = 0; - return result; -} - -/* dma_test() - Perform DMA loop back test to end point and back to root complex. - * - * Allocate a cache-coherent buffer in host memory, consisting of four pages. - * - * Fill the four memory pages such that each 32-bit word contains its own address. - * - * Now perform a loop back test, have the end point device copy the first buffer - * half to end point memory, then have it copy back into the second half. - * - * Create a descriptor table to copy the first buffer half into End Point - * memory. Instruct the End Point to do a DMA read using that table. - * - * Create a descriptor table to copy End Point memory to the second buffer - * half. Instruct the End Point to do a DMA write using that table. - * - * Compare results, fail or pass. - * - */ -static int __devinit dma_test(struct ape_dev *ape, struct pci_dev *dev) -{ - /* test result; guilty until proven innocent */ - int result = -1; - /* the DMA read header sits at address 0x00 of the DMA engine BAR */ - struct ape_chdma_header *write_header = (struct ape_chdma_header *)ape->bar[APE_BAR_HEADER]; - /* the write DMA header sits after the read header at address 0x10 */ - struct ape_chdma_header *read_header = write_header + 1; - /* virtual address of the allocated buffer */ - u8 *buffer_virt = 0; - /* bus address of the allocated buffer */ - dma_addr_t buffer_bus = 0; - int i, n = 0, irq_count; - - /* temporary value used to construct 32-bit data words */ - u32 w; - - printk(KERN_DEBUG "bar_tests(), PAGE_SIZE = 0x%0x\n", (int)PAGE_SIZE); - printk(KERN_DEBUG "write_header = 0x%p.\n", write_header); - printk(KERN_DEBUG "read_header = 0x%p.\n", read_header); - printk(KERN_DEBUG "&write_header->w3 = 0x%p\n", &write_header->w3); - printk(KERN_DEBUG "&read_header->w3 = 0x%p\n", &read_header->w3); - printk(KERN_DEBUG "ape->table_virt = 0x%p.\n", ape->table_virt); - - if (!write_header || !read_header || !ape->table_virt) - goto fail; - - /* allocate and map coherently-cached memory for a DMA-able buffer */ - /* @see Documentation/PCI/PCI-DMA-mapping.txt, near line 318 */ - buffer_virt = (u8 *)pci_alloc_consistent(dev, PAGE_SIZE * 4, &buffer_bus); - if (!buffer_virt) { - printk(KERN_DEBUG "Could not allocate coherent DMA buffer.\n"); - goto fail; - } - printk(KERN_DEBUG "Allocated cache-coherent DMA buffer (virtual address = %p, bus address = 0x%016llx).\n", - buffer_virt, (u64)buffer_bus); - - /* fill first half of buffer with its virtual address as data */ - for (i = 0; i < 4 * PAGE_SIZE; i += 4) -#if 0 - *(u32 *)(buffer_virt + i) = i / PAGE_SIZE + 1; -#else - *(u32 *)(buffer_virt + i) = (u32)(unsigned long)(buffer_virt + i); -#endif -#if 0 - compare((u32 *)buffer_virt, (u32 *)(buffer_virt + 2 * PAGE_SIZE), 8192); -#endif - -#if 0 - /* fill second half of buffer with zeroes */ - for (i = 2 * PAGE_SIZE; i < 4 * PAGE_SIZE; i += 4) - *(u32 *)(buffer_virt + i) = 0; -#endif - - /* invalidate EPLAST, outside 0-255, 0xFADE is from the testbench */ - ape->table_virt->w3 = cpu_to_le32(0x0000FADE); - - /* fill in first descriptor */ - n = 0; - /* read 8192 bytes from RC buffer to EP address 4096 */ - ape_chdma_desc_set(&ape->table_virt->desc[n], buffer_bus, 4096, 2 * PAGE_SIZE); -#if 1 - for (i = 0; i < 255; i++) - ape_chdma_desc_set(&ape->table_virt->desc[i], buffer_bus, 4096, 2 * PAGE_SIZE); - /* index of last descriptor */ - n = i - 1; -#endif -#if 0 - /* fill in next descriptor */ - n++; - /* read 1024 bytes from RC buffer to EP address 4096 + 1024 */ - ape_chdma_desc_set(&ape->table_virt->desc[n], buffer_bus + 1024, 4096 + 1024, 1024); -#endif - -#if 1 - /* enable MSI after the last descriptor is completed */ - if (ape->msi_enabled) - ape->table_virt->desc[n].w0 |= cpu_to_le32(1UL << 16)/*local MSI*/; -#endif -#if 0 - /* dump descriptor table for debugging */ - printk(KERN_DEBUG "Descriptor Table (Read, in Root Complex Memory, # = %d)\n", n + 1); - for (i = 0; i < 4 + (n + 1) * 4; i += 4) { - u32 *p = (u32 *)ape->table_virt; - p += i; - printk(KERN_DEBUG "0x%08x/0x%02x: 0x%08x (LEN=0x%x)\n", (u32)p, (u32)p & 15, *p, 4 * le32_to_cpu(*p)); - p++; - printk(KERN_DEBUG "0x%08x/0x%02x: 0x%08x (EPA=0x%x)\n", (u32)p, (u32)p & 15, *p, le32_to_cpu(*p)); - p++; - printk(KERN_DEBUG "0x%08x/0x%02x: 0x%08x (RCH=0x%x)\n", (u32)p, (u32)p & 15, *p, le32_to_cpu(*p)); - p++; - printk(KERN_DEBUG "0x%08x/0x%02x: 0x%08x (RCL=0x%x)\n", (u32)p, (u32)p & 15, *p, le32_to_cpu(*p)); - } -#endif - /* set available number of descriptors in table */ - w = (u32)(n + 1); - w |= (1UL << 18)/*global EPLAST_EN*/; -#if 0 - if (ape->msi_enabled) - w |= (1UL << 17)/*global MSI*/; -#endif - printk(KERN_DEBUG "writing 0x%08x to 0x%p\n", w, (void *)&read_header->w0); - iowrite32(w, &read_header->w0); - - /* write table address (higher 32-bits) */ - printk(KERN_DEBUG "writing 0x%08x to 0x%p\n", (u32)((ape->table_bus >> 16) >> 16), (void *)&read_header->bdt_addr_h); - iowrite32(pci_dma_h(ape->table_bus), &read_header->bdt_addr_h); - - /* write table address (lower 32-bits) */ - printk(KERN_DEBUG "writing 0x%08x to 0x%p\n", (u32)(ape->table_bus & 0xffffffffUL), (void *)&read_header->bdt_addr_l); - iowrite32(pci_dma_l(ape->table_bus), &read_header->bdt_addr_l); - - /* memory write barrier */ - wmb(); - printk(KERN_DEBUG "Flush posted writes\n"); - /** FIXME Add dummy read to flush posted writes but need a readable location! */ -#if 0 - (void)ioread32(); -#endif - - /* remember IRQ count before the transfer */ - irq_count = ape->irq_count; - /* write number of descriptors - this starts the DMA */ - printk(KERN_DEBUG "\nStart DMA read\n"); - printk(KERN_DEBUG "writing 0x%08x to 0x%p\n", (u32)n, (void *)&read_header->w3); - iowrite32(n, &read_header->w3); - printk(KERN_DEBUG "EPLAST = %lu\n", le32_to_cpu(*(u32 *)&ape->table_virt->w3) & 0xffffUL); - - /** memory write barrier */ - wmb(); - /* dummy read to flush posted writes */ - /* FIXME Need a readable location! */ -#if 0 - (void)ioread32(); -#endif - printk(KERN_DEBUG "POLL FOR READ:\n"); - /* poll for chain completion, 1000 times 1 millisecond */ - for (i = 0; i < 100; i++) { - volatile u32 *p = &ape->table_virt->w3; - u32 eplast = le32_to_cpu(*p) & 0xffffUL; - printk(KERN_DEBUG "EPLAST = %u, n = %d\n", eplast, n); - if (eplast == n) { - printk(KERN_DEBUG "DONE\n"); - /* print IRQ count before the transfer */ - printk(KERN_DEBUG "#IRQs during transfer: %d\n", ape->irq_count - irq_count); - break; - } - udelay(100); - } - - /* invalidate EPLAST, outside 0-255, 0xFADE is from the testbench */ - ape->table_virt->w3 = cpu_to_le32(0x0000FADE); - - /* setup first descriptor */ - n = 0; - ape_chdma_desc_set(&ape->table_virt->desc[n], buffer_bus + 8192, 4096, 2 * PAGE_SIZE); -#if 1 - for (i = 0; i < 255; i++) - ape_chdma_desc_set(&ape->table_virt->desc[i], buffer_bus + 8192, 4096, 2 * PAGE_SIZE); - - /* index of last descriptor */ - n = i - 1; -#endif -#if 1 /* test variable, make a module option later */ - if (ape->msi_enabled) - ape->table_virt->desc[n].w0 |= cpu_to_le32(1UL << 16)/*local MSI*/; -#endif -#if 0 - /* dump descriptor table for debugging */ - printk(KERN_DEBUG "Descriptor Table (Write, in Root Complex Memory, # = %d)\n", n + 1); - for (i = 0; i < 4 + (n + 1) * 4; i += 4) { - u32 *p = (u32 *)ape->table_virt; - p += i; - printk(KERN_DEBUG "0x%08x/0x%02x: 0x%08x (LEN=0x%x)\n", (u32)p, (u32)p & 15, *p, 4 * le32_to_cpu(*p)); - p++; - printk(KERN_DEBUG "0x%08x/0x%02x: 0x%08x (EPA=0x%x)\n", (u32)p, (u32)p & 15, *p, le32_to_cpu(*p)); - p++; - printk(KERN_DEBUG "0x%08x/0x%02x: 0x%08x (RCH=0x%x)\n", (u32)p, (u32)p & 15, *p, le32_to_cpu(*p)); - p++; - printk(KERN_DEBUG "0x%08x/0x%02x: 0x%08x (RCL=0x%x)\n", (u32)p, (u32)p & 15, *p, le32_to_cpu(*p)); - } -#endif - - /* set number of available descriptors in the table */ - w = (u32)(n + 1); - /* enable updates of eplast for each descriptor completion */ - w |= (u32)(1UL << 18)/*global EPLAST_EN*/; -#if 0 /* test variable, make a module option later */ - /* enable MSI for each descriptor completion */ - if (ape->msi_enabled) - w |= (1UL << 17)/*global MSI*/; -#endif - iowrite32(w, &write_header->w0); - iowrite32(pci_dma_h(ape->table_bus), &write_header->bdt_addr_h); - iowrite32(pci_dma_l(ape->table_bus), &write_header->bdt_addr_l); - - /** memory write barrier and flush posted writes */ - wmb(); - /* dummy read to flush posted writes */ - /* FIXME Need a readable location! */ -#if 0 - (void)ioread32(); -#endif - irq_count = ape->irq_count; - - printk(KERN_DEBUG "\nStart DMA write\n"); - iowrite32(n, &write_header->w3); - - /** memory write barrier */ - wmb(); - /** dummy read to flush posted writes */ - /* (void) ioread32(); */ - - printk(KERN_DEBUG "POLL FOR WRITE:\n"); - /* poll for completion, 1000 times 1 millisecond */ - for (i = 0; i < 100; i++) { - volatile u32 *p = &ape->table_virt->w3; - u32 eplast = le32_to_cpu(*p) & 0xffffUL; - printk(KERN_DEBUG "EPLAST = %u, n = %d\n", eplast, n); - if (eplast == n) { - printk(KERN_DEBUG "DONE\n"); - /* print IRQ count before the transfer */ - printk(KERN_DEBUG "#IRQs during transfer: %d\n", ape->irq_count - irq_count); - break; - } - udelay(100); - } - /* soft-reset DMA write engine */ - iowrite32(0x0000ffffUL, &write_header->w0); - /* soft-reset DMA read engine */ - iowrite32(0x0000ffffUL, &read_header->w0); - - /** memory write barrier */ - wmb(); - /* dummy read to flush posted writes */ - /* FIXME Need a readable location! */ -#if 0 - (void)ioread32(); -#endif - /* compare first half of buffer with second half, should be identical */ - result = compare((u32 *)buffer_virt, (u32 *)(buffer_virt + 2 * PAGE_SIZE), 8192); - printk(KERN_DEBUG "DMA loop back test %s.\n", result ? "FAILED" : "PASSED"); - - pci_free_consistent(dev, 4 * PAGE_SIZE, buffer_virt, buffer_bus); -fail: - printk(KERN_DEBUG "bar_tests() end, result %d\n", result); - return result; -} - -/* Called when the PCI sub system thinks we can control the given device. - * Inspect if we can support the device and if so take control of it. - * - * Return 0 when we have taken control of the given device. - * - * - allocate board specific bookkeeping - * - allocate coherently-mapped memory for the descriptor table - * - enable the board - * - verify board revision - * - request regions - * - query DMA mask - * - obtain and request irq - * - map regions into kernel address space - */ -static int __devinit probe(struct pci_dev *dev, const struct pci_device_id *id) -{ - int rc = 0; - struct ape_dev *ape = NULL; - u8 irq_pin, irq_line; - printk(KERN_DEBUG "probe(dev = 0x%p, pciid = 0x%p)\n", dev, id); - - /* allocate memory for per-board book keeping */ - ape = kzalloc(sizeof(struct ape_dev), GFP_KERNEL); - if (!ape) { - printk(KERN_DEBUG "Could not kzalloc()ate memory.\n"); - goto err_ape; - } - ape->pci_dev = dev; - dev_set_drvdata(&dev->dev, ape); - printk(KERN_DEBUG "probe() ape = 0x%p\n", ape); - - printk(KERN_DEBUG "sizeof(struct ape_chdma_table) = %d.\n", - (int)sizeof(struct ape_chdma_table)); - /* the reference design has a size restriction on the table size */ - BUG_ON(sizeof(struct ape_chdma_table) > APE_CHDMA_TABLE_SIZE); - - /* allocate and map coherently-cached memory for a descriptor table */ - /* @see LDD3 page 446 */ - ape->table_virt = (struct ape_chdma_table *)pci_alloc_consistent(dev, - APE_CHDMA_TABLE_SIZE, &ape->table_bus); - /* could not allocate table? */ - if (!ape->table_virt) { - printk(KERN_DEBUG "Could not dma_alloc()ate_coherent memory.\n"); - goto err_table; - } - - printk(KERN_DEBUG "table_virt = %p, table_bus = 0x%16llx.\n", - ape->table_virt, (u64)ape->table_bus); - - /* enable device */ - rc = pci_enable_device(dev); - if (rc) { - printk(KERN_DEBUG "pci_enable_device() failed\n"); - goto err_enable; - } - - /* enable bus master capability on device */ - pci_set_master(dev); - /* enable message signaled interrupts */ - rc = pci_enable_msi(dev); - /* could not use MSI? */ - if (rc) { - /* resort to legacy interrupts */ - printk(KERN_DEBUG "Could not enable MSI interrupting.\n"); - ape->msi_enabled = 0; - /* MSI enabled, remember for cleanup */ - } else { - printk(KERN_DEBUG "Enabled MSI interrupting.\n"); - ape->msi_enabled = 1; - } - - pci_read_config_byte(dev, PCI_REVISION_ID, &ape->revision); -#if 0 /* example */ - /* (for example) this driver does not support revision 0x42 */ - if (ape->revision == 0x42) { - printk(KERN_DEBUG "Revision 0x42 is not supported by this driver.\n"); - rc = -ENODEV; - goto err_rev; - } -#endif - /** XXX check for native or legacy PCIe endpoint? */ - - rc = pci_request_regions(dev, DRV_NAME); - /* could not request all regions? */ - if (rc) { - /* assume device is in use (and do not disable it later!) */ - ape->in_use = 1; - goto err_regions; - } - ape->got_regions = 1; - -#if 1 /* @todo For now, disable 64-bit, because I do not understand the implications (DAC!) */ - /* query for DMA transfer */ - /* @see Documentation/PCI/PCI-DMA-mapping.txt */ - if (!pci_set_dma_mask(dev, DMA_BIT_MASK(64))) { - pci_set_consistent_dma_mask(dev, DMA_BIT_MASK(64)); - /* use 64-bit DMA */ - printk(KERN_DEBUG "Using a 64-bit DMA mask.\n"); - } else -#endif - if (!pci_set_dma_mask(dev, DMA_BIT_MASK(32))) { - printk(KERN_DEBUG "Could not set 64-bit DMA mask.\n"); - pci_set_consistent_dma_mask(dev, DMA_BIT_MASK(32)); - /* use 32-bit DMA */ - printk(KERN_DEBUG "Using a 32-bit DMA mask.\n"); - } else { - printk(KERN_DEBUG "No suitable DMA possible.\n"); - /** @todo Choose proper error return code */ - rc = -1; - goto err_mask; - } - - rc = pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &irq_pin); - /* could not read? */ - if (rc) - goto err_irq; - printk(KERN_DEBUG "IRQ pin #%d (0=none, 1=INTA#...4=INTD#).\n", irq_pin); - - /* @see LDD3, page 318 */ - rc = pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq_line); - /* could not read? */ - if (rc) { - printk(KERN_DEBUG "Could not query PCI_INTERRUPT_LINE, error %d\n", rc); - goto err_irq; - } - printk(KERN_DEBUG "IRQ line #%d.\n", irq_line); -#if 1 - irq_line = dev->irq; - /* @see LDD3, page 259 */ - rc = request_irq(irq_line, altpciechdma_isr, IRQF_SHARED, DRV_NAME, (void *)ape); - if (rc) { - printk(KERN_DEBUG "Could not request IRQ #%d, error %d\n", irq_line, rc); - ape->irq_line = -1; - goto err_irq; - } - /* remember which irq we allocated */ - ape->irq_line = (int)irq_line; - printk(KERN_DEBUG "Succesfully requested IRQ #%d with dev_id 0x%p\n", irq_line, ape); -#endif - /* show BARs */ - scan_bars(ape, dev); - /* map BARs */ - rc = map_bars(ape, dev); - if (rc) - goto err_map; -#if ALTPCIECHDMA_CDEV - /* initialize character device */ - rc = sg_init(ape); - if (rc) - goto err_cdev; -#endif - /* perform DMA engines loop back test */ - rc = dma_test(ape, dev); - (void)rc; - /* successfully took the device */ - rc = 0; - printk(KERN_DEBUG "probe() successful.\n"); - goto end; -#if ALTPCIECHDMA_CDEV -err_cdev: - /* unmap the BARs */ - unmap_bars(ape, dev); -#endif -err_map: - /* free allocated irq */ - if (ape->irq_line >= 0) - free_irq(ape->irq_line, (void *)ape); -err_irq: - if (ape->msi_enabled) - pci_disable_msi(dev); - /* disable the device iff it is not in use */ - if (!ape->in_use) - pci_disable_device(dev); - if (ape->got_regions) - pci_release_regions(dev); -err_mask: -err_regions: -/*err_rev:*/ -/* clean up everything before device enable() */ -err_enable: - if (ape->table_virt) - pci_free_consistent(dev, APE_CHDMA_TABLE_SIZE, ape->table_virt, ape->table_bus); -/* clean up everything before allocating descriptor table */ -err_table: - if (ape) - kfree(ape); -err_ape: -end: - return rc; -} - -static void __devexit remove(struct pci_dev *dev) -{ - struct ape_dev *ape = dev_get_drvdata(&dev->dev); - - printk(KERN_DEBUG "remove(0x%p)\n", dev); - printk(KERN_DEBUG "remove(dev = 0x%p) where ape = 0x%p\n", dev, ape); - - /* remove character device */ -#if ALTPCIECHDMA_CDEV - sg_exit(ape); -#endif - - if (ape->table_virt) - pci_free_consistent(dev, APE_CHDMA_TABLE_SIZE, ape->table_virt, ape->table_bus); - - /* free IRQ - * @see LDD3 page 279 - */ - if (ape->irq_line >= 0) { - printk(KERN_DEBUG "Freeing IRQ #%d for dev_id 0x%08lx.\n", - ape->irq_line, (unsigned long)ape); - free_irq(ape->irq_line, (void *)ape); - } - /* MSI was enabled? */ - if (ape->msi_enabled) { - /* Disable MSI @see Documentation/MSI-HOWTO.txt */ - pci_disable_msi(dev); - ape->msi_enabled = 0; - } - /* unmap the BARs */ - unmap_bars(ape, dev); - if (!ape->in_use) - pci_disable_device(dev); - if (ape->got_regions) - /* to be called after device disable */ - pci_release_regions(dev); -} - -#if ALTPCIECHDMA_CDEV - -/* - * Called when the device goes from unused to used. - */ -static int sg_open(struct inode *inode, struct file *file) -{ - struct ape_dev *ape; - printk(KERN_DEBUG DRV_NAME "_open()\n"); - /* pointer to containing data structure of the character device inode */ - ape = container_of(inode->i_cdev, struct ape_dev, cdev); - /* create a reference to our device state in the opened file */ - file->private_data = ape; - /* create virtual memory mapper */ - ape->sgm = sg_create_mapper(MAX_CHDMA_SIZE); - return 0; -} - -/* - * Called when the device goes from used to unused. - */ -static int sg_close(struct inode *inode, struct file *file) -{ - /* fetch device specific data stored earlier during open */ - struct ape_dev *ape = (struct ape_dev *)file->private_data; - printk(KERN_DEBUG DRV_NAME "_close()\n"); - /* destroy virtual memory mapper */ - sg_destroy_mapper(ape->sgm); - return 0; -} - -static ssize_t sg_read(struct file *file, char __user *buf, size_t count, loff_t *pos) -{ - /* fetch device specific data stored earlier during open */ - struct ape_dev *ape = (struct ape_dev *)file->private_data; - (void)ape; - printk(KERN_DEBUG DRV_NAME "_read(buf=0x%p, count=%lld, pos=%llu)\n", buf, (s64)count, (u64)*pos); - return count; -} - -/* sg_write() - Write to the device - * - * @buf userspace buffer - * @count number of bytes in the userspace buffer - * - * Iterate over the userspace buffer, taking at most 255 * PAGE_SIZE bytes for - * each DMA transfer. - * For each transfer, get the user pages, build a sglist, map, build a - * descriptor table. submit the transfer. wait for the interrupt handler - * to wake us on completion. - */ -static ssize_t sg_write(struct file *file, const char __user *buf, size_t count, loff_t *pos) -{ - int hwnents, tents; - size_t transfer_len, remaining = count, done = 0; - u64 transfer_addr = (u64)buf; - /* fetch device specific data stored earlier during open */ - struct ape_dev *ape = (struct ape_dev *)file->private_data; - printk(KERN_DEBUG DRV_NAME "_write(buf=0x%p, count=%lld, pos=%llu)\n", - buf, (s64)count, (u64)*pos); - /* TODO transfer boundaries at PAGE_SIZE granularity */ - while (remaining > 0) { - /* limit DMA transfer size */ - transfer_len = (remaining < APE_CHDMA_MAX_TRANSFER_LEN) ? remaining : - APE_CHDMA_MAX_TRANSFER_LEN; - /* get all user space buffer pages and create a scattergather list */ - sgm_map_user_pages(ape->sgm, transfer_addr, transfer_len, 0/*read from userspace*/); - printk(KERN_DEBUG DRV_NAME "mapped_pages=%d\n", ape->sgm->mapped_pages); - /* map all entries in the scattergather list */ - hwnents = pci_map_sg(ape->pci_dev, ape->sgm->sgl, ape->sgm->mapped_pages, DMA_TO_DEVICE); - printk(KERN_DEBUG DRV_NAME "hwnents=%d\n", hwnents); - /* build device descriptor tables and submit them to the DMA engine */ - tents = ape_sg_to_chdma_table(ape->sgm->sgl, hwnents, 0, &ape->table_virt->desc[0], 4096); - printk(KERN_DEBUG DRV_NAME "tents=%d\n", hwnents); -#if 0 - while (tables) { - /* TODO build table */ - /* TODO submit table to the device */ - /* if engine stopped and unfinished work then start engine */ - } - put ourselves on wait queue -#endif - - dma_unmap_sg(NULL, ape->sgm->sgl, ape->sgm->mapped_pages, DMA_TO_DEVICE); - /* dirty and free the pages */ - sgm_unmap_user_pages(ape->sgm, 1/*dirtied*/); - /* book keeping */ - transfer_addr += transfer_len; - remaining -= transfer_len; - done += transfer_len; - } - return done; -} - -/* - * character device file operations - */ -static const struct file_operations sg_fops = { - .owner = THIS_MODULE, - .open = sg_open, - .release = sg_close, - .read = sg_read, - .write = sg_write, -}; - -/* sg_init() - Initialize character device - * - * XXX Should ideally be tied to the device, on device probe, not module init. - */ -static int sg_init(struct ape_dev *ape) -{ - int rc; - printk(KERN_DEBUG DRV_NAME " sg_init()\n"); - /* allocate a dynamically allocated character device node */ - rc = alloc_chrdev_region(&ape->cdevno, 0/*requested minor*/, 1/*count*/, DRV_NAME); - /* allocation failed? */ - if (rc < 0) { - printk("alloc_chrdev_region() = %d\n", rc); - goto fail_alloc; - } - /* couple the device file operations to the character device */ - cdev_init(&ape->cdev, &sg_fops); - ape->cdev.owner = THIS_MODULE; - /* bring character device live */ - rc = cdev_add(&ape->cdev, ape->cdevno, 1/*count*/); - if (rc < 0) { - printk("cdev_add() = %d\n", rc); - goto fail_add; - } - printk(KERN_DEBUG "altpciechdma = %d:%d\n", MAJOR(ape->cdevno), MINOR(ape->cdevno)); - return 0; -fail_add: - /* free the dynamically allocated character device node */ - unregister_chrdev_region(ape->cdevno, 1/*count*/); -fail_alloc: - return -1; -} - -/* sg_exit() - Cleanup character device - * - * XXX Should ideally be tied to the device, on device remove, not module exit. - */ - -static void sg_exit(struct ape_dev *ape) -{ - printk(KERN_DEBUG DRV_NAME " sg_exit()\n"); - /* remove the character device */ - cdev_del(&ape->cdev); - /* free the dynamically allocated character device node */ - unregister_chrdev_region(ape->cdevno, 1/*count*/); -} - -#endif /* ALTPCIECHDMA_CDEV */ - -/* used to register the driver with the PCI kernel sub system - * @see LDD3 page 311 - */ -static struct pci_driver pci_driver = { - .name = DRV_NAME, - .id_table = ids, - .probe = probe, - .remove = __devexit_p(remove), - /* resume, suspend are optional */ -}; - -/** - * alterapciechdma_init() - Module initialization, registers devices. - */ -static int __init alterapciechdma_init(void) -{ - int rc = 0; - printk(KERN_DEBUG DRV_NAME " init(), built at " __DATE__ " " __TIME__ "\n"); - /* register this driver with the PCI bus driver */ - rc = pci_register_driver(&pci_driver); - if (rc < 0) - return rc; - return 0; -} - -/** - * alterapciechdma_init() - Module cleanup, unregisters devices. - */ -static void __exit alterapciechdma_exit(void) -{ - printk(KERN_DEBUG DRV_NAME " exit(), built at " __DATE__ " " __TIME__ "\n"); - /* unregister this driver from the PCI bus driver */ - pci_unregister_driver(&pci_driver); -} - -MODULE_LICENSE("GPL"); - -module_init(alterapciechdma_init); -module_exit(alterapciechdma_exit); - diff --git a/drivers/staging/arlan/Makefile b/drivers/staging/arlan/Makefile index 9e58e5f..5a84d44 100644 --- a/drivers/staging/arlan/Makefile +++ b/drivers/staging/arlan/Makefile @@ -1,3 +1,3 @@ -obj-$(CONFIG_ARLAN) += arlan.o +obj-$(CONFIG_ARLAN) += arlan.o arlan-objs := arlan-main.o arlan-proc.o diff --git a/drivers/staging/arlan/arlan.h b/drivers/staging/arlan/arlan.h index fb3ad51..ffcd3ea 100644 --- a/drivers/staging/arlan/arlan.h +++ b/drivers/staging/arlan/arlan.h @@ -1,6 +1,6 @@ /* * Copyright (C) 1997 Cullen Jennings - * Copyright (C) 1998 Elmer.Joandi@ut.ee, +37-255-13500 + * Copyright (C) 1998 Elmer.Joandi@ut.ee, +37-255-13500 * GNU General Public License applies */ @@ -20,14 +20,14 @@ #include <linux/init.h> #include <linux/bitops.h> #include <asm/system.h> -#include <asm/io.h> +#include <linux/io.h> #include <linux/errno.h> #include <linux/delay.h> #include <linux/netdevice.h> #include <linux/etherdevice.h> -//#define ARLAN_DEBUGGING 1 +/* #define ARLAN_DEBUGGING 1 */ #define ARLAN_PROC_INTERFACE #define MAX_ARLANS 4 /* not more than 4 ! */ @@ -51,8 +51,8 @@ extern int arlan_debug; extern int arlan_entry_debug; extern int arlan_exit_debug; extern int testMemory; -extern int arlan_command(struct net_device * dev, int command); - +extern int arlan_command(struct net_device *dev, int command); + #define SIDUNKNOWN -1 #define radioNodeIdUNKNOWN -1 #define irqUNKNOWN 0 @@ -65,22 +65,21 @@ extern int arlan_command(struct net_device * dev, int command); #define registrationModeUNKNOWN -1 -#define IFDEBUG( L ) if ( (L) & arlan_debug ) -#define ARLAN_FAKE_HDR_LEN 12 +#define IFDEBUG(L) if ((L) & arlan_debug) +#define ARLAN_FAKE_HDR_LEN 12 #ifdef ARLAN_DEBUGGING #define DEBUG 1 #define ARLAN_ENTRY_EXIT_DEBUGGING 1 - #define ARLAN_DEBUG(a,b) printk(KERN_DEBUG a, b) + #define ARLAN_DEBUG(a, b) printk(KERN_DEBUG a, b) #else - #define ARLAN_DEBUG(a,b) + #define ARLAN_DEBUG(a, b) #endif #define ARLAN_SHMEM_SIZE 0x2000 -struct arlan_shmem -{ - /* Header Signature */ +struct arlan_shmem { + /* Header Signature */ volatile char textRegion[48]; volatile u_char resetFlag; volatile u_char diagnosticInfo; @@ -91,10 +90,10 @@ struct arlan_shmem volatile u_char hardwareType; volatile u_char majorHardwareVersion; volatile u_char minorHardwareVersion; - volatile u_char radioModule;// shows EEPROM, can be overridden at 0x111 - volatile u_char defaultChannelSet; // shows EEProm, can be overriiden at 0x10A + volatile u_char radioModule;/* shows EEPROM, can be overridden at 0x111 */ + volatile u_char defaultChannelSet; /* shows EEProm, can be overriiden at 0x10A */ volatile u_char _2[47]; - + /* Control/Status Block - 0x0080 */ volatile u_char interruptInProgress; /* not used by lancpu */ volatile u_char cntrlRegImage; /* not used by lancpu */ @@ -113,7 +112,7 @@ struct arlan_shmem volatile u_char rxQuality; volatile u_char scrambled; volatile u_char _4[1]; - + /* Transmit Status - 0x00b0 */ volatile u_char txStatus; volatile u_char txAckQuality; @@ -151,7 +150,7 @@ struct arlan_shmem volatile u_short routerId; volatile u_char _10[9]; volatile u_char txAttenuation; - volatile u_char systemId[4]; + volatile u_char systemId[4]; volatile u_short globalChecksum; volatile u_char _11[4]; volatile u_short maxDatagramSize; @@ -207,19 +206,19 @@ struct arlan_shmem volatile u_char hostcpuLock; volatile u_char lancpuLock; volatile u_char resetTime[18]; - + volatile u_char numDatagramsTransmitted[4]; volatile u_char numReTransmissions[4]; volatile u_char numFramesDiscarded[4]; volatile u_char numDatagramsReceived[4]; volatile u_char numDuplicateReceivedFrames[4]; volatile u_char numDatagramsDiscarded[4]; - + volatile u_short maxNumReTransmitDatagram; volatile u_short maxNumReTransmitFrames; volatile u_short maxNumConsecutiveDuplicateFrames; /* misaligned here so we have to go to characters */ - + volatile u_char numBytesTransmitted[4]; volatile u_char numBytesReceived[4]; volatile u_char numCRCErrors[4]; @@ -259,7 +258,7 @@ struct arlan_conf_stru { int channelNumber; int scramblingDisable; int txAttenuation; - int systemId; + int systemId; int maxDatagramSize; int maxFrameSize; int maxRetries; @@ -316,8 +315,7 @@ struct arlan_conf_stru { extern struct arlan_conf_stru arlan_conf[MAX_ARLANS]; -struct TxParam -{ +struct TxParam { volatile short offset; volatile short length; volatile u_char dest[6]; @@ -330,12 +328,12 @@ struct TxParam #define TX_RING_SIZE 2 /* Information that need to be kept for each board. */ struct arlan_private { - struct arlan_shmem __iomem * card; - struct arlan_shmem * conf; + struct arlan_shmem __iomem *card; + struct arlan_shmem *conf; - struct arlan_conf_stru * Conf; + struct arlan_conf_stru *Conf; int bad; - int reset; + int reset; unsigned long lastReset; struct timer_list timer; struct timer_list tx_delay_timer; @@ -407,38 +405,38 @@ struct arlan_private { #define TXBuffStart(dev) offsetof(struct arlan_shmem, txBuffer) #define TXBuffEnd(dev) offsetof(struct arlan_shmem, xxBuffer) - -#define READSHM(to,from,atype) {\ + +#define READSHM(to, from, atype) {\ atype tmp;\ - memcpy_fromio(&(tmp),&(from),sizeof(atype));\ + memcpy_fromio(&(tmp), &(from), sizeof(atype));\ to = tmp;\ } -#define READSHMEM(from,atype)\ +#define READSHMEM(from, atype)\ atype from; \ READSHM(from, arlan->from, atype); -#define WRITESHM(to,from,atype) \ +#define WRITESHM(to, from, atype) \ { atype tmpSHM = from;\ - memcpy_toio(&(to),&tmpSHM,sizeof(atype));\ + memcpy_toio(&(to), &tmpSHM, sizeof(atype));\ } -#define DEBUGSHM(levelSHM,stringSHM,stuff,atype) \ +#define DEBUGSHM(levelSHM, stringSHM, stuff, atype) \ { atype tmpSHM; \ - memcpy_fromio(&tmpSHM,&(stuff),sizeof(atype));\ - IFDEBUG(levelSHM) printk(stringSHM,tmpSHM);\ + memcpy_fromio(&tmpSHM, &(stuff), sizeof(atype));\ + IFDEBUG(levelSHM) printk(stringSHM, tmpSHM);\ } #define WRITESHMB(to, val) \ - writeb(val,&(to)) + writeb(val, &(to)) #define READSHMB(to) \ readb(&(to)) #define WRITESHMS(to, val) \ - writew(val,&(to)) + writew(val, &(to)) #define READSHMS(to) \ readw(&(to)) #define WRITESHMI(to, val) \ - writel(val,&(to)) + writel(val, &(to)) #define READSHMI(to) \ readl(&(to)) @@ -447,51 +445,51 @@ struct arlan_private { #define registrationBad(dev)\ - ( ( READSHMB(((struct arlan_private *)netdev_priv(dev))->card->registrationMode) > 0) && \ - ( READSHMB(((struct arlan_private *)netdev_priv(dev))->card->registrationStatus) == 0) ) + (( READSHMB(((struct arlan_private *)netdev_priv(dev))->card->registrationMode) > 0) && \ + ( READSHMB(((struct arlan_private *)netdev_priv(dev))->card->registrationStatus) == 0)) #define readControlRegister(dev)\ - READSHMB(((struct arlan_private *)netdev_priv(dev))->card->cntrlRegImage) + READSHMB(((struct arlan_private *)netdev_priv(dev))->card->cntrlRegImage) -#define writeControlRegister(dev, v){\ - WRITESHMB(((struct arlan_private *)netdev_priv(dev))->card->cntrlRegImage ,((v) &0xF) );\ - WRITESHMB(((struct arlan_private *)netdev_priv(dev))->card->controlRegister ,(v) );} +#define writeControlRegister(dev, v) {\ + WRITESHMB(((struct arlan_private *)netdev_priv(dev))->card->cntrlRegImage, ((v) & 0xF));\ + WRITESHMB(((struct arlan_private *)netdev_priv(dev))->card->controlRegister, (v)); } #define arlan_interrupt_lancpu(dev) {\ int cr; \ \ cr = readControlRegister(dev);\ - if (cr & ARLAN_CHANNEL_ATTENTION){ \ + if (cr & ARLAN_CHANNEL_ATTENTION) { \ writeControlRegister(dev, (cr & ~ARLAN_CHANNEL_ATTENTION));\ - }else \ + } else \ writeControlRegister(dev, (cr | ARLAN_CHANNEL_ATTENTION));\ } -#define clearChannelAttention(dev){ \ - writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_CHANNEL_ATTENTION);} +#define clearChannelAttention(dev) { \ + writeControlRegister(dev, readControlRegister(dev) & ~ARLAN_CHANNEL_ATTENTION); } #define setHardwareReset(dev) {\ - writeControlRegister(dev,readControlRegister(dev) | ARLAN_RESET);} + writeControlRegister(dev, readControlRegister(dev) | ARLAN_RESET); } #define clearHardwareReset(dev) {\ - writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_RESET);} -#define setInterruptEnable(dev){\ - writeControlRegister(dev,readControlRegister(dev) | ARLAN_INTERRUPT_ENABLE) ;} -#define clearInterruptEnable(dev){\ - writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_INTERRUPT_ENABLE) ;} -#define setClearInterrupt(dev){\ - writeControlRegister(dev,readControlRegister(dev) | ARLAN_CLEAR_INTERRUPT) ;} -#define clearClearInterrupt(dev){\ - writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_CLEAR_INTERRUPT);} -#define setPowerOff(dev){\ - writeControlRegister(dev,readControlRegister(dev) | (ARLAN_POWER && ARLAN_ACCESS));\ - writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_ACCESS);} -#define setPowerOn(dev){\ - writeControlRegister(dev,readControlRegister(dev) & ~(ARLAN_POWER)); } -#define arlan_lock_card_access(dev){\ - writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_ACCESS);} -#define arlan_unlock_card_access(dev){\ - writeControlRegister(dev,readControlRegister(dev) | ARLAN_ACCESS ); } + writeControlRegister(dev, readControlRegister(dev) & ~ARLAN_RESET); } +#define setInterruptEnable(dev) {\ + writeControlRegister(dev, readControlRegister(dev) | ARLAN_INTERRUPT_ENABLE) ; } +#define clearInterruptEnable(dev) {\ + writeControlRegister(dev, readControlRegister(dev) & ~ARLAN_INTERRUPT_ENABLE) ; } +#define setClearInterrupt(dev) {\ + writeControlRegister(dev, readControlRegister(dev) | ARLAN_CLEAR_INTERRUPT) ; } +#define clearClearInterrupt(dev) {\ + writeControlRegister(dev, readControlRegister(dev) & ~ARLAN_CLEAR_INTERRUPT); } +#define setPowerOff(dev) {\ + writeControlRegister(dev, readControlRegister(dev) | (ARLAN_POWER && ARLAN_ACCESS));\ + writeControlRegister(dev, readControlRegister(dev) & ~ARLAN_ACCESS); } +#define setPowerOn(dev) {\ + writeControlRegister(dev, readControlRegister(dev) & ~(ARLAN_POWER)); } +#define arlan_lock_card_access(dev) {\ + writeControlRegister(dev, readControlRegister(dev) & ~ARLAN_ACCESS); } +#define arlan_unlock_card_access(dev) {\ + writeControlRegister(dev, readControlRegister(dev) | ARLAN_ACCESS); } @@ -525,7 +523,6 @@ struct arlan_private { | ARLAN_COMMAND_RESET) - #define ARLAN_DEBUG_CHAIN_LOCKS 0x00001 #define ARLAN_DEBUG_RESET 0x00002 #define ARLAN_DEBUG_TIMING 0x00004 @@ -536,4 +533,3 @@ struct arlan_private { #define ARLAN_DEBUG_INTERRUPT 0x00080 #define ARLAN_DEBUG_STARTUP 0x00100 #define ARLAN_DEBUG_SHUTDOWN 0x00200 - diff --git a/drivers/staging/asus_oled/asus_oled.c b/drivers/staging/asus_oled/asus_oled.c index 43c57b7..cadb6f7 100644 --- a/drivers/staging/asus_oled/asus_oled.c +++ b/drivers/staging/asus_oled/asus_oled.c @@ -52,6 +52,10 @@ #define ASUS_OLED_DISP_HEIGHT 32 #define ASUS_OLED_PACKET_BUF_SIZE 256 +#define USB_VENDOR_ID_ASUS 0x0b05 +#define USB_DEVICE_ID_ASUS_LCM 0x1726 +#define USB_DEVICE_ID_ASUS_LCM2 0x175b + MODULE_AUTHOR("Jakub Schmidtke, sjakub@gmail.com"); MODULE_DESCRIPTION("Asus OLED Driver v" ASUS_OLED_VERSION); MODULE_LICENSE("GPL"); @@ -83,18 +87,20 @@ struct oled_dev_desc_str { }; /* table of devices that work with this driver */ -static struct usb_device_id id_table[] = { +static const struct usb_device_id id_table[] = { /* Asus G1/G2 (and variants)*/ - { USB_DEVICE(0x0b05, 0x1726) }, + { USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_LCM) }, /* Asus G50V (and possibly others - G70? G71?)*/ - { USB_DEVICE(0x0b05, 0x175b) }, + { USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_LCM2) }, { }, }; /* parameters of specific devices */ static struct oled_dev_desc_str oled_dev_desc_table[] = { - { 0x0b05, 0x1726, 128, PACK_MODE_G1, "G1/G2" }, - { 0x0b05, 0x175b, 256, PACK_MODE_G50, "G50" }, + { USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_LCM, 128, PACK_MODE_G1, + "G1/G2" }, + { USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_LCM2, 256, PACK_MODE_G50, + "G50" }, { }, }; @@ -424,6 +430,11 @@ static ssize_t odev_set_picture(struct asus_oled_dev *odev, kfree(odev->buf); odev->buf = kmalloc(odev->buf_size, GFP_KERNEL); + if (odev->buf == NULL) { + odev->buf_size = 0; + printk(ASUS_OLED_ERROR "Out of memory!\n"); + return -ENOMEM; + } memset(odev->buf, 0xff, odev->buf_size); diff --git a/drivers/staging/b3dfg/Kconfig b/drivers/staging/b3dfg/Kconfig deleted file mode 100644 index 9e6573c..0000000 --- a/drivers/staging/b3dfg/Kconfig +++ /dev/null @@ -1,10 +0,0 @@ -config B3DFG - tristate "Brontes 3d Frame Framegrabber" - depends on PCI - default n - ---help--- - This driver provides support for the Brontes 3d Framegrabber - PCI card. - - To compile this driver as a module, choose M here. The module - will be called b3dfg. diff --git a/drivers/staging/b3dfg/Makefile b/drivers/staging/b3dfg/Makefile deleted file mode 100644 index 91f439f..0000000 --- a/drivers/staging/b3dfg/Makefile +++ /dev/null @@ -1 +0,0 @@ -obj-$(CONFIG_B3DFG) += b3dfg.o diff --git a/drivers/staging/b3dfg/TODO b/drivers/staging/b3dfg/TODO deleted file mode 100644 index f5a9298..0000000 --- a/drivers/staging/b3dfg/TODO +++ /dev/null @@ -1,4 +0,0 @@ - - - queue/wait buffer presents filltime results for each frame? - - counting of dropped frames - - review endianness diff --git a/drivers/staging/b3dfg/b3dfg.c b/drivers/staging/b3dfg/b3dfg.c deleted file mode 100644 index 4a43c51..0000000 --- a/drivers/staging/b3dfg/b3dfg.c +++ /dev/null @@ -1,1100 +0,0 @@ - /* - * Brontes PCI frame grabber driver - * - * Copyright (C) 2008 3M Company - * Contact: Justin Bronder <jsbronder@brontes3d.com> - * Original Authors: Daniel Drake <ddrake@brontes3d.com> - * Duane Griffin <duaneg@dghda.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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include <linux/device.h> -#include <linux/fs.h> -#include <linux/interrupt.h> -#include <linux/spinlock.h> -#include <linux/ioctl.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/pci.h> -#include <linux/types.h> -#include <linux/cdev.h> -#include <linux/list.h> -#include <linux/poll.h> -#include <linux/wait.h> -#include <linux/mm.h> -#include <linux/uaccess.h> -#include <linux/sched.h> - -static unsigned int b3dfg_nbuf = 2; - -module_param_named(buffer_count, b3dfg_nbuf, uint, 0444); - -MODULE_PARM_DESC(buffer_count, "Number of buffers (min 2, default 2)"); - -MODULE_AUTHOR("Daniel Drake <ddrake@brontes3d.com>"); -MODULE_DESCRIPTION("Brontes frame grabber driver"); -MODULE_LICENSE("GPL"); - -#define DRIVER_NAME "b3dfg" -#define B3DFG_MAX_DEVS 4 -#define B3DFG_FRAMES_PER_BUFFER 3 - -#define B3DFG_BAR_REGS 0 -#define B3DFG_REGS_LENGTH 0x10000 - -#define B3DFG_IOC_MAGIC 0xb3 /* dfg :-) */ -#define B3DFG_IOCGFRMSZ _IOR(B3DFG_IOC_MAGIC, 1, int) -#define B3DFG_IOCTNUMBUFS _IO(B3DFG_IOC_MAGIC, 2) -#define B3DFG_IOCTTRANS _IO(B3DFG_IOC_MAGIC, 3) -#define B3DFG_IOCTQUEUEBUF _IO(B3DFG_IOC_MAGIC, 4) -#define B3DFG_IOCTPOLLBUF _IOWR(B3DFG_IOC_MAGIC, 5, struct b3dfg_poll) -#define B3DFG_IOCTWAITBUF _IOWR(B3DFG_IOC_MAGIC, 6, struct b3dfg_wait) -#define B3DFG_IOCGWANDSTAT _IOR(B3DFG_IOC_MAGIC, 7, int) - -enum { - /* number of 4kb pages per frame */ - B3D_REG_FRM_SIZE = 0x0, - - /* bit 0: set to enable interrupts - * bit 1: set to enable cable status change interrupts */ - B3D_REG_HW_CTRL = 0x4, - - /* bit 0-1 - 1-based ID of next pending frame transfer (0 = none) - * bit 2 indicates the previous DMA transfer has completed - * bit 3 indicates wand cable status change - * bit 8:15 - counter of number of discarded triplets */ - B3D_REG_DMA_STS = 0x8, - - /* bit 0: wand status (1 = present, 0 = disconnected) */ - B3D_REG_WAND_STS = 0xc, - - /* bus address for DMA transfers. lower 2 bits must be zero because DMA - * works with 32 bit word size. */ - B3D_REG_EC220_DMA_ADDR = 0x8000, - - /* bit 20:0 - number of 32 bit words to be transferred - * bit 21:31 - reserved */ - B3D_REG_EC220_TRF_SIZE = 0x8004, - - /* bit 0 - error bit - * bit 1 - interrupt bit (set to generate interrupt at end of transfer) - * bit 2 - start bit (set to start transfer) - * bit 3 - direction (0 = DMA_TO_DEVICE, 1 = DMA_FROM_DEVICE - * bit 4:31 - reserved */ - B3D_REG_EC220_DMA_STS = 0x8008, -}; - -enum b3dfg_buffer_state { - B3DFG_BUFFER_POLLED = 0, - B3DFG_BUFFER_PENDING, - B3DFG_BUFFER_POPULATED, -}; - -struct b3dfg_buffer { - unsigned char *frame[B3DFG_FRAMES_PER_BUFFER]; - struct list_head list; - u8 state; -}; - -struct b3dfg_dev { - - /* no protection needed: all finalized at initialization time */ - struct pci_dev *pdev; - struct cdev chardev; - struct device *dev; - void __iomem *regs; - unsigned int frame_size; - - /* - * Protects buffer state, including buffer_queue, triplet_ready, - * cur_dma_frame_idx & cur_dma_frame_addr. - */ - spinlock_t buffer_lock; - struct b3dfg_buffer *buffers; - struct list_head buffer_queue; - - /* Last frame in triplet transferred (-1 if none). */ - int cur_dma_frame_idx; - - /* Current frame's address for DMA. */ - dma_addr_t cur_dma_frame_addr; - - /* - * Protects cstate_tstamp. - * Nests inside buffer_lock. - */ - spinlock_t cstate_lock; - unsigned long cstate_tstamp; - - /* - * Protects triplets_dropped. - * Nests inside buffers_lock. - */ - spinlock_t triplets_dropped_lock; - unsigned int triplets_dropped; - - wait_queue_head_t buffer_waitqueue; - - unsigned int transmission_enabled:1; - unsigned int triplet_ready:1; -}; - -static u8 b3dfg_devices[B3DFG_MAX_DEVS]; - -static struct class *b3dfg_class; -static dev_t b3dfg_devt; - -static const struct pci_device_id b3dfg_ids[] __devinitdata = { - { PCI_DEVICE(0x0b3d, 0x0001) }, - { }, -}; - -MODULE_DEVICE_TABLE(pci, b3dfg_ids); - -/***** user-visible types *****/ - -struct b3dfg_poll { - int buffer_idx; - unsigned int triplets_dropped; -}; - -struct b3dfg_wait { - int buffer_idx; - unsigned int timeout; - unsigned int triplets_dropped; -}; - -/**** register I/O ****/ - -static u32 b3dfg_read32(struct b3dfg_dev *fgdev, u16 reg) -{ - return ioread32(fgdev->regs + reg); -} - -static void b3dfg_write32(struct b3dfg_dev *fgdev, u16 reg, u32 value) -{ - iowrite32(value, fgdev->regs + reg); -} - -/**** buffer management ****/ - -/* - * Program EC220 for transfer of a specific frame. - * Called with buffer_lock held. - */ -static int setup_frame_transfer(struct b3dfg_dev *fgdev, - struct b3dfg_buffer *buf, int frame) -{ - unsigned char *frm_addr; - dma_addr_t frm_addr_dma; - unsigned int frm_size = fgdev->frame_size; - - frm_addr = buf->frame[frame]; - frm_addr_dma = pci_map_single(fgdev->pdev, frm_addr, - frm_size, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(fgdev->pdev, frm_addr_dma)) - return -ENOMEM; - - fgdev->cur_dma_frame_addr = frm_addr_dma; - fgdev->cur_dma_frame_idx = frame; - - b3dfg_write32(fgdev, B3D_REG_EC220_DMA_ADDR, - cpu_to_le32(frm_addr_dma)); - b3dfg_write32(fgdev, B3D_REG_EC220_TRF_SIZE, - cpu_to_le32(frm_size >> 2)); - b3dfg_write32(fgdev, B3D_REG_EC220_DMA_STS, 0xf); - - return 0; -} - -/* Caller should hold buffer lock */ -static void dequeue_all_buffers(struct b3dfg_dev *fgdev) -{ - int i; - for (i = 0; i < b3dfg_nbuf; i++) { - struct b3dfg_buffer *buf = &fgdev->buffers[i]; - buf->state = B3DFG_BUFFER_POLLED; - list_del_init(&buf->list); - } -} - -/* queue a buffer to receive data */ -static int queue_buffer(struct b3dfg_dev *fgdev, int bufidx) -{ - struct device *dev = &fgdev->pdev->dev; - struct b3dfg_buffer *buf; - unsigned long flags; - int r = 0; - - spin_lock_irqsave(&fgdev->buffer_lock, flags); - if (bufidx < 0 || bufidx >= b3dfg_nbuf) { - dev_dbg(dev, "Invalid buffer index, %d\n", bufidx); - r = -ENOENT; - goto out; - } - buf = &fgdev->buffers[bufidx]; - - if (unlikely(buf->state == B3DFG_BUFFER_PENDING)) { - dev_dbg(dev, "buffer %d is already queued\n", bufidx); - r = -EINVAL; - goto out; - } - - buf->state = B3DFG_BUFFER_PENDING; - list_add_tail(&buf->list, &fgdev->buffer_queue); - - if (fgdev->transmission_enabled && fgdev->triplet_ready) { - dev_dbg(dev, "triplet is ready, pushing immediately\n"); - fgdev->triplet_ready = 0; - r = setup_frame_transfer(fgdev, buf, 0); - if (r) - dev_err(dev, "unable to map DMA buffer\n"); - } - -out: - spin_unlock_irqrestore(&fgdev->buffer_lock, flags); - return r; -} - -/* non-blocking buffer poll. returns 1 if data is present in the buffer, - * 0 otherwise */ -static int poll_buffer(struct b3dfg_dev *fgdev, void __user *arg) -{ - struct device *dev = &fgdev->pdev->dev; - struct b3dfg_poll p; - struct b3dfg_buffer *buf; - unsigned long flags; - int r = 1; - int arg_out = 0; - - if (copy_from_user(&p, arg, sizeof(p))) - return -EFAULT; - - if (unlikely(!fgdev->transmission_enabled)) { - dev_dbg(dev, "cannot poll, transmission disabled\n"); - return -EINVAL; - } - - if (p.buffer_idx < 0 || p.buffer_idx >= b3dfg_nbuf) - return -ENOENT; - - buf = &fgdev->buffers[p.buffer_idx]; - - spin_lock_irqsave(&fgdev->buffer_lock, flags); - - if (likely(buf->state == B3DFG_BUFFER_POPULATED)) { - arg_out = 1; - buf->state = B3DFG_BUFFER_POLLED; - - /* IRQs already disabled by spin_lock_irqsave above. */ - spin_lock(&fgdev->triplets_dropped_lock); - p.triplets_dropped = fgdev->triplets_dropped; - fgdev->triplets_dropped = 0; - spin_unlock(&fgdev->triplets_dropped_lock); - } else { - r = 0; - } - - spin_unlock_irqrestore(&fgdev->buffer_lock, flags); - - if (arg_out && copy_to_user(arg, &p, sizeof(p))) - r = -EFAULT; - - return r; -} - -static unsigned long get_cstate_change(struct b3dfg_dev *fgdev) -{ - unsigned long flags, when; - - spin_lock_irqsave(&fgdev->cstate_lock, flags); - when = fgdev->cstate_tstamp; - spin_unlock_irqrestore(&fgdev->cstate_lock, flags); - return when; -} - -static int is_event_ready(struct b3dfg_dev *fgdev, struct b3dfg_buffer *buf, - unsigned long when) -{ - int result; - unsigned long flags; - - spin_lock_irqsave(&fgdev->buffer_lock, flags); - spin_lock(&fgdev->cstate_lock); - result = (!fgdev->transmission_enabled || - buf->state == B3DFG_BUFFER_POPULATED || - when != fgdev->cstate_tstamp); - spin_unlock(&fgdev->cstate_lock); - spin_unlock_irqrestore(&fgdev->buffer_lock, flags); - - return result; -} - -/* sleep until a specific buffer becomes populated */ -static int wait_buffer(struct b3dfg_dev *fgdev, void __user *arg) -{ - struct device *dev = &fgdev->pdev->dev; - struct b3dfg_wait w; - struct b3dfg_buffer *buf; - unsigned long flags, when; - int r; - - if (copy_from_user(&w, arg, sizeof(w))) - return -EFAULT; - - if (!fgdev->transmission_enabled) { - dev_dbg(dev, "cannot wait, transmission disabled\n"); - return -EINVAL; - } - - if (w.buffer_idx < 0 || w.buffer_idx >= b3dfg_nbuf) - return -ENOENT; - - buf = &fgdev->buffers[w.buffer_idx]; - - spin_lock_irqsave(&fgdev->buffer_lock, flags); - - if (buf->state == B3DFG_BUFFER_POPULATED) { - r = w.timeout; - goto out_triplets_dropped; - } - - spin_unlock_irqrestore(&fgdev->buffer_lock, flags); - - when = get_cstate_change(fgdev); - if (w.timeout > 0) { - r = wait_event_interruptible_timeout(fgdev->buffer_waitqueue, - is_event_ready(fgdev, buf, when), - (w.timeout * HZ) / 1000); - - if (unlikely(r < 0)) - goto out; - - w.timeout = r * 1000 / HZ; - } else { - r = wait_event_interruptible(fgdev->buffer_waitqueue, - is_event_ready(fgdev, buf, when)); - - if (unlikely(r)) { - r = -ERESTARTSYS; - goto out; - } - } - - /* TODO: Inform the user via field(s) in w? */ - if (!fgdev->transmission_enabled || when != get_cstate_change(fgdev)) { - r = -EINVAL; - goto out; - } - - spin_lock_irqsave(&fgdev->buffer_lock, flags); - - if (buf->state != B3DFG_BUFFER_POPULATED) { - r = -ETIMEDOUT; - goto out_unlock; - } - - buf->state = B3DFG_BUFFER_POLLED; - -out_triplets_dropped: - - /* IRQs already disabled by spin_lock_irqsave above. */ - spin_lock(&fgdev->triplets_dropped_lock); - w.triplets_dropped = fgdev->triplets_dropped; - fgdev->triplets_dropped = 0; - spin_unlock(&fgdev->triplets_dropped_lock); - -out_unlock: - spin_unlock_irqrestore(&fgdev->buffer_lock, flags); - if (copy_to_user(arg, &w, sizeof(w))) - r = -EFAULT; -out: - return r; -} - -/* mmap page fault handler */ -static int b3dfg_vma_fault(struct vm_area_struct *vma, - struct vm_fault *vmf) -{ - struct b3dfg_dev *fgdev = vma->vm_file->private_data; - unsigned long off = vmf->pgoff << PAGE_SHIFT; - unsigned int frame_size = fgdev->frame_size; - unsigned int buf_size = frame_size * B3DFG_FRAMES_PER_BUFFER; - unsigned char *addr; - - /* determine which buffer the offset lies within */ - unsigned int buf_idx = off / buf_size; - /* and the offset into the buffer */ - unsigned int buf_off = off % buf_size; - - /* determine which frame inside the buffer the offset lies in */ - unsigned int frm_idx = buf_off / frame_size; - /* and the offset into the frame */ - unsigned int frm_off = buf_off % frame_size; - - if (unlikely(buf_idx >= b3dfg_nbuf)) - return VM_FAULT_SIGBUS; - - addr = fgdev->buffers[buf_idx].frame[frm_idx] + frm_off; - vm_insert_pfn(vma, (unsigned long)vmf->virtual_address, - virt_to_phys(addr) >> PAGE_SHIFT); - - return VM_FAULT_NOPAGE; -} - -static struct vm_operations_struct b3dfg_vm_ops = { - .fault = b3dfg_vma_fault, -}; - -static int get_wand_status(struct b3dfg_dev *fgdev, int __user *arg) -{ - u32 wndstat = b3dfg_read32(fgdev, B3D_REG_WAND_STS); - dev_dbg(&fgdev->pdev->dev, "wand status %x\n", wndstat); - return __put_user(wndstat & 0x1, arg); -} - -static int enable_transmission(struct b3dfg_dev *fgdev) -{ - unsigned long flags; - struct device *dev = &fgdev->pdev->dev; - - dev_dbg(dev, "enable transmission\n"); - - /* check the cable is plugged in. */ - if (!b3dfg_read32(fgdev, B3D_REG_WAND_STS)) { - dev_dbg(dev, "cannot start transmission without wand\n"); - return -EINVAL; - } - - spin_lock_irqsave(&fgdev->buffer_lock, flags); - - /* Handle racing enable_transmission calls. */ - if (fgdev->transmission_enabled) { - spin_unlock_irqrestore(&fgdev->buffer_lock, flags); - goto out; - } - - spin_lock(&fgdev->triplets_dropped_lock); - fgdev->triplets_dropped = 0; - spin_unlock(&fgdev->triplets_dropped_lock); - - fgdev->triplet_ready = 0; - fgdev->cur_dma_frame_idx = -1; - fgdev->transmission_enabled = 1; - - spin_unlock_irqrestore(&fgdev->buffer_lock, flags); - - /* Enable DMA and cable status interrupts. */ - b3dfg_write32(fgdev, B3D_REG_HW_CTRL, 0x03); - -out: - return 0; -} - -static void disable_transmission(struct b3dfg_dev *fgdev) -{ - struct device *dev = &fgdev->pdev->dev; - unsigned long flags; - u32 tmp; - - dev_dbg(dev, "disable transmission\n"); - - /* guarantee that no more interrupts will be serviced */ - spin_lock_irqsave(&fgdev->buffer_lock, flags); - fgdev->transmission_enabled = 0; - - b3dfg_write32(fgdev, B3D_REG_HW_CTRL, 0); - - /* FIXME: temporary debugging only. if the board stops transmitting, - * hitting ctrl+c and seeing this message is useful for determining - * the state of the board. */ - tmp = b3dfg_read32(fgdev, B3D_REG_DMA_STS); - dev_dbg(dev, "DMA_STS reads %x after TX stopped\n", tmp); - - dequeue_all_buffers(fgdev); - spin_unlock_irqrestore(&fgdev->buffer_lock, flags); - - wake_up_interruptible(&fgdev->buffer_waitqueue); -} - -static int set_transmission(struct b3dfg_dev *fgdev, int enabled) -{ - int res = 0; - - if (enabled && !fgdev->transmission_enabled) - res = enable_transmission(fgdev); - else if (!enabled && fgdev->transmission_enabled) - disable_transmission(fgdev); - - return res; -} - -/* Called in interrupt context. */ -static void handle_cstate_unplug(struct b3dfg_dev *fgdev) -{ - /* Disable all interrupts. */ - b3dfg_write32(fgdev, B3D_REG_HW_CTRL, 0); - - /* Stop transmission. */ - spin_lock(&fgdev->buffer_lock); - fgdev->transmission_enabled = 0; - - fgdev->cur_dma_frame_idx = -1; - fgdev->triplet_ready = 0; - if (fgdev->cur_dma_frame_addr) { - pci_unmap_single(fgdev->pdev, fgdev->cur_dma_frame_addr, - fgdev->frame_size, PCI_DMA_FROMDEVICE); - fgdev->cur_dma_frame_addr = 0; - } - dequeue_all_buffers(fgdev); - spin_unlock(&fgdev->buffer_lock); -} - -/* Called in interrupt context. */ -static void handle_cstate_change(struct b3dfg_dev *fgdev) -{ - u32 cstate = b3dfg_read32(fgdev, B3D_REG_WAND_STS); - unsigned long when; - struct device *dev = &fgdev->pdev->dev; - - dev_dbg(dev, "cable state change: %u\n", cstate); - - /* - * When the wand is unplugged we reset our state. The hardware will - * have done the same internally. - * - * Note we should never see a cable *plugged* event, as interrupts - * should only be enabled when transmitting, which requires the cable - * to be plugged. If we do see one it probably means the cable has been - * unplugged and re-plugged very rapidly. Possibly because it has a - * broken wire and is momentarily losing contact. - * - * TODO: At the moment if you plug in the cable then enable transmission - * the hardware will raise a couple of spurious interrupts, so - * just ignore them for now. - * - * Once the hardware is fixed we should complain and treat it as an - * unplug. Or at least track how frequently it is happening and do - * so if too many come in. - */ - if (cstate) { - dev_warn(dev, "ignoring unexpected plug event\n"); - return; - } - handle_cstate_unplug(fgdev); - - /* - * Record cable state change timestamp & wake anyone waiting - * on a cable state change. Be paranoid about ensuring events - * are not missed if we somehow get two interrupts in a jiffy. - */ - spin_lock(&fgdev->cstate_lock); - when = jiffies_64; - if (when <= fgdev->cstate_tstamp) - when = fgdev->cstate_tstamp + 1; - fgdev->cstate_tstamp = when; - wake_up_interruptible(&fgdev->buffer_waitqueue); - spin_unlock(&fgdev->cstate_lock); -} - -/* Called with buffer_lock held. */ -static void transfer_complete(struct b3dfg_dev *fgdev) -{ - struct b3dfg_buffer *buf; - struct device *dev = &fgdev->pdev->dev; - - pci_unmap_single(fgdev->pdev, fgdev->cur_dma_frame_addr, - fgdev->frame_size, PCI_DMA_FROMDEVICE); - fgdev->cur_dma_frame_addr = 0; - - buf = list_entry(fgdev->buffer_queue.next, struct b3dfg_buffer, list); - - dev_dbg(dev, "handle frame completion\n"); - if (fgdev->cur_dma_frame_idx == B3DFG_FRAMES_PER_BUFFER - 1) { - - /* last frame of that triplet completed */ - dev_dbg(dev, "triplet completed\n"); - buf->state = B3DFG_BUFFER_POPULATED; - list_del_init(&buf->list); - wake_up_interruptible(&fgdev->buffer_waitqueue); - } -} - -/* - * Called with buffer_lock held. - * - * Note that idx is the (1-based) *next* frame to be transferred, while - * cur_dma_frame_idx is the (0-based) *last* frame to have been transferred (or - * -1 if none). Thus there should be a difference of 2 between them. - */ -static bool setup_next_frame_transfer(struct b3dfg_dev *fgdev, int idx) -{ - struct b3dfg_buffer *buf; - struct device *dev = &fgdev->pdev->dev; - bool need_ack = 1; - - dev_dbg(dev, "program DMA transfer for next frame: %d\n", idx); - - buf = list_entry(fgdev->buffer_queue.next, struct b3dfg_buffer, list); - if (idx == fgdev->cur_dma_frame_idx + 2) { - if (setup_frame_transfer(fgdev, buf, idx - 1)) - dev_err(dev, "unable to map DMA buffer\n"); - need_ack = 0; - } else { - dev_err(dev, "frame mismatch, got %d, expected %d\n", - idx, fgdev->cur_dma_frame_idx + 2); - - /* FIXME: handle dropped triplets here */ - } - - return need_ack; -} - -static irqreturn_t b3dfg_intr(int irq, void *dev_id) -{ - struct b3dfg_dev *fgdev = dev_id; - struct device *dev = &fgdev->pdev->dev; - u32 sts; - u8 dropped; - bool need_ack = 1; - irqreturn_t res = IRQ_HANDLED; - - sts = b3dfg_read32(fgdev, B3D_REG_DMA_STS); - if (unlikely(sts == 0)) { - dev_warn(dev, "ignore interrupt, DMA status is 0\n"); - res = IRQ_NONE; - goto out; - } - - if (unlikely(!fgdev->transmission_enabled)) { - dev_warn(dev, "ignore interrupt, TX disabled\n"); - res = IRQ_HANDLED; - goto out; - } - - /* Handle dropped frames, as reported by the hardware. */ - dropped = (sts >> 8) & 0xff; - dev_dbg(dev, "intr: DMA_STS=%08x (drop=%d comp=%d next=%d)\n", - sts, dropped, !!(sts & 0x4), sts & 0x3); - if (unlikely(dropped > 0)) { - spin_lock(&fgdev->triplets_dropped_lock); - fgdev->triplets_dropped += dropped; - spin_unlock(&fgdev->triplets_dropped_lock); - } - - /* Handle a cable state change (i.e. the wand being unplugged). */ - if (sts & 0x08) { - handle_cstate_change(fgdev); - goto out; - } - - spin_lock(&fgdev->buffer_lock); - if (unlikely(list_empty(&fgdev->buffer_queue))) { - - /* FIXME need more sanity checking here */ - dev_info(dev, "buffer not ready for next transfer\n"); - fgdev->triplet_ready = 1; - goto out_unlock; - } - - /* Has a frame transfer been completed? */ - if (sts & 0x4) { - u32 dma_status = b3dfg_read32(fgdev, B3D_REG_EC220_DMA_STS); - - /* Check for DMA errors reported by the hardware. */ - if (unlikely(dma_status & 0x1)) { - dev_err(dev, "EC220 error: %08x\n", dma_status); - - /* FIXME flesh out error handling */ - goto out_unlock; - } - - /* Sanity check, we should have a frame index at this point. */ - if (unlikely(fgdev->cur_dma_frame_idx == -1)) { - dev_err(dev, "completed but no last idx?\n"); - - /* FIXME flesh out error handling */ - goto out_unlock; - } - - transfer_complete(fgdev); - } - - /* Is there another frame transfer pending? */ - if (sts & 0x3) - need_ack = setup_next_frame_transfer(fgdev, sts & 0x3); - else - fgdev->cur_dma_frame_idx = -1; - -out_unlock: - spin_unlock(&fgdev->buffer_lock); -out: - if (need_ack) { - dev_dbg(dev, "acknowledging interrupt\n"); - b3dfg_write32(fgdev, B3D_REG_EC220_DMA_STS, 0x0b); - } - return res; -} - -static int b3dfg_open(struct inode *inode, struct file *filp) -{ - struct b3dfg_dev *fgdev = - container_of(inode->i_cdev, struct b3dfg_dev, chardev); - - dev_dbg(&fgdev->pdev->dev, "open\n"); - filp->private_data = fgdev; - return 0; -} - -static int b3dfg_release(struct inode *inode, struct file *filp) -{ - struct b3dfg_dev *fgdev = filp->private_data; - dev_dbg(&fgdev->pdev->dev, "release\n"); - disable_transmission(fgdev); - return 0; -} - -static long b3dfg_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -{ - struct b3dfg_dev *fgdev = filp->private_data; - - switch (cmd) { - case B3DFG_IOCGFRMSZ: - return __put_user(fgdev->frame_size, (int __user *) arg); - case B3DFG_IOCGWANDSTAT: - return get_wand_status(fgdev, (int __user *) arg); - case B3DFG_IOCTTRANS: - return set_transmission(fgdev, (int) arg); - case B3DFG_IOCTQUEUEBUF: - return queue_buffer(fgdev, (int) arg); - case B3DFG_IOCTPOLLBUF: - return poll_buffer(fgdev, (void __user *) arg); - case B3DFG_IOCTWAITBUF: - return wait_buffer(fgdev, (void __user *) arg); - default: - dev_dbg(&fgdev->pdev->dev, "unrecognised ioctl %x\n", cmd); - return -EINVAL; - } -} - -static unsigned int b3dfg_poll(struct file *filp, poll_table *poll_table) -{ - struct b3dfg_dev *fgdev = filp->private_data; - unsigned long flags, when; - int i; - int r = 0; - - when = get_cstate_change(fgdev); - poll_wait(filp, &fgdev->buffer_waitqueue, poll_table); - - spin_lock_irqsave(&fgdev->buffer_lock, flags); - for (i = 0; i < b3dfg_nbuf; i++) { - if (fgdev->buffers[i].state == B3DFG_BUFFER_POPULATED) { - r = POLLIN | POLLRDNORM; - break; - } - } - spin_unlock_irqrestore(&fgdev->buffer_lock, flags); - - /* TODO: Confirm this is how we want to communicate the change. */ - if (!fgdev->transmission_enabled || when != get_cstate_change(fgdev)) - r = POLLERR; - - return r; -} - -static int b3dfg_mmap(struct file *filp, struct vm_area_struct *vma) -{ - struct b3dfg_dev *fgdev = filp->private_data; - unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; - unsigned long vsize = vma->vm_end - vma->vm_start; - unsigned long bufdatalen = b3dfg_nbuf * fgdev->frame_size * 3; - unsigned long psize = bufdatalen - offset; - int r = 0; - - if (vsize <= psize) { - vma->vm_flags |= VM_IO | VM_RESERVED | VM_CAN_NONLINEAR | - VM_PFNMAP; - vma->vm_ops = &b3dfg_vm_ops; - } else { - r = -EINVAL; - } - - return r; -} - -static struct file_operations b3dfg_fops = { - .owner = THIS_MODULE, - .open = b3dfg_open, - .release = b3dfg_release, - .unlocked_ioctl = b3dfg_ioctl, - .poll = b3dfg_poll, - .mmap = b3dfg_mmap, -}; - -static void free_all_frame_buffers(struct b3dfg_dev *fgdev) -{ - int i, j; - for (i = 0; i < b3dfg_nbuf; i++) - for (j = 0; j < B3DFG_FRAMES_PER_BUFFER; j++) - kfree(fgdev->buffers[i].frame[j]); - kfree(fgdev->buffers); -} - -/* initialize device and any data structures. called before any interrupts - * are enabled. */ -static int b3dfg_init_dev(struct b3dfg_dev *fgdev) -{ - int i, j; - u32 frm_size = b3dfg_read32(fgdev, B3D_REG_FRM_SIZE); - - /* Disable interrupts. In abnormal circumstances (e.g. after a crash) - * the board may still be transmitting from the previous session. If we - * ensure that interrupts are disabled before we later enable them, we - * are sure to capture a triplet from the start, rather than starting - * from frame 2 or 3. Disabling interrupts causes the FG to throw away - * all buffered data and stop buffering more until interrupts are - * enabled again. - */ - b3dfg_write32(fgdev, B3D_REG_HW_CTRL, 0); - - fgdev->frame_size = frm_size * 4096; - fgdev->buffers = kzalloc(sizeof(struct b3dfg_buffer) * b3dfg_nbuf, - GFP_KERNEL); - if (!fgdev->buffers) - goto err_no_buf; - for (i = 0; i < b3dfg_nbuf; i++) { - struct b3dfg_buffer *buf = &fgdev->buffers[i]; - for (j = 0; j < B3DFG_FRAMES_PER_BUFFER; j++) { - buf->frame[j] = kmalloc(fgdev->frame_size, GFP_KERNEL); - if (!buf->frame[j]) - goto err_no_mem; - } - INIT_LIST_HEAD(&buf->list); - } - - INIT_LIST_HEAD(&fgdev->buffer_queue); - init_waitqueue_head(&fgdev->buffer_waitqueue); - spin_lock_init(&fgdev->buffer_lock); - spin_lock_init(&fgdev->cstate_lock); - spin_lock_init(&fgdev->triplets_dropped_lock); - return 0; - -err_no_mem: - free_all_frame_buffers(fgdev); -err_no_buf: - return -ENOMEM; -} - -/* find next free minor number, returns -1 if none are availabile */ -static int get_free_minor(void) -{ - int i; - for (i = 0; i < B3DFG_MAX_DEVS; i++) { - if (b3dfg_devices[i] == 0) - return i; - } - return -1; -} - -static int __devinit b3dfg_probe(struct pci_dev *pdev, - const struct pci_device_id *id) -{ - struct b3dfg_dev *fgdev = kzalloc(sizeof(*fgdev), GFP_KERNEL); - int r = 0; - int minor = get_free_minor(); - dev_t devno = MKDEV(MAJOR(b3dfg_devt), minor); - unsigned long res_len; - resource_size_t res_base; - - if (fgdev == NULL) - return -ENOMEM; - - if (minor < 0) { - dev_err(&pdev->dev, "too many devices found!\n"); - r = -EIO; - goto err_free; - } - - b3dfg_devices[minor] = 1; - dev_info(&pdev->dev, "probe device with IRQ %d\n", pdev->irq); - - cdev_init(&fgdev->chardev, &b3dfg_fops); - fgdev->chardev.owner = THIS_MODULE; - - r = cdev_add(&fgdev->chardev, devno, 1); - if (r) { - dev_err(&pdev->dev, "cannot add char device\n"); - goto err_release_minor; - } - - fgdev->dev = device_create( - b3dfg_class, - &pdev->dev, - devno, - dev_get_drvdata(&pdev->dev), - DRIVER_NAME "%d", minor); - - if (IS_ERR(fgdev->dev)) { - dev_err(&pdev->dev, "cannot create device\n"); - r = PTR_ERR(fgdev->dev); - goto err_del_cdev; - } - - r = pci_enable_device(pdev); - if (r) { - dev_err(&pdev->dev, "cannot enable PCI device\n"); - goto err_dev_unreg; - } - - res_len = pci_resource_len(pdev, B3DFG_BAR_REGS); - if (res_len != B3DFG_REGS_LENGTH) { - dev_err(&pdev->dev, "invalid register resource size\n"); - r = -EIO; - goto err_disable; - } - - if (pci_resource_flags(pdev, B3DFG_BAR_REGS) - != (IORESOURCE_MEM | IORESOURCE_SIZEALIGN)) { - dev_err(&pdev->dev, "invalid resource flags\n"); - r = -EIO; - goto err_disable; - } - r = pci_request_regions(pdev, DRIVER_NAME); - if (r) { - dev_err(&pdev->dev, "cannot obtain PCI resources\n"); - goto err_disable; - } - - pci_set_master(pdev); - - r = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); - if (r) { - dev_err(&pdev->dev, "no usable DMA configuration\n"); - goto err_free_res; - } - - res_base = pci_resource_start(pdev, B3DFG_BAR_REGS); - fgdev->regs = ioremap_nocache(res_base, res_len); - if (!fgdev->regs) { - dev_err(&pdev->dev, "regs ioremap failed\n"); - r = -EIO; - goto err_free_res; - } - - fgdev->pdev = pdev; - pci_set_drvdata(pdev, fgdev); - r = b3dfg_init_dev(fgdev); - if (r < 0) { - dev_err(&pdev->dev, "failed to initalize device\n"); - goto err_unmap; - } - - r = request_irq(pdev->irq, b3dfg_intr, IRQF_SHARED, DRIVER_NAME, fgdev); - if (r) { - dev_err(&pdev->dev, "couldn't request irq %d\n", pdev->irq); - goto err_free_bufs; - } - - return 0; - -err_free_bufs: - free_all_frame_buffers(fgdev); -err_unmap: - iounmap(fgdev->regs); -err_free_res: - pci_release_regions(pdev); -err_disable: - pci_disable_device(pdev); -err_dev_unreg: - device_destroy(b3dfg_class, devno); -err_del_cdev: - cdev_del(&fgdev->chardev); -err_release_minor: - b3dfg_devices[minor] = 0; -err_free: - kfree(fgdev); - return r; -} - -static void __devexit b3dfg_remove(struct pci_dev *pdev) -{ - struct b3dfg_dev *fgdev = pci_get_drvdata(pdev); - unsigned int minor = MINOR(fgdev->chardev.dev); - - dev_dbg(&pdev->dev, "remove\n"); - - free_irq(pdev->irq, fgdev); - iounmap(fgdev->regs); - pci_release_regions(pdev); - pci_disable_device(pdev); - device_destroy(b3dfg_class, MKDEV(MAJOR(b3dfg_devt), minor)); - cdev_del(&fgdev->chardev); - free_all_frame_buffers(fgdev); - kfree(fgdev); - b3dfg_devices[minor] = 0; -} - -static struct pci_driver b3dfg_driver = { - .name = DRIVER_NAME, - .id_table = b3dfg_ids, - .probe = b3dfg_probe, - .remove = __devexit_p(b3dfg_remove), -}; - -static int __init b3dfg_module_init(void) -{ - int r; - - if (b3dfg_nbuf < 2) { - printk(KERN_ERR DRIVER_NAME - ": buffer_count is out of range (must be >= 2)"); - return -EINVAL; - } - - printk(KERN_INFO DRIVER_NAME ": loaded\n"); - - b3dfg_class = class_create(THIS_MODULE, DRIVER_NAME); - if (IS_ERR(b3dfg_class)) - return PTR_ERR(b3dfg_class); - - r = alloc_chrdev_region(&b3dfg_devt, 0, B3DFG_MAX_DEVS, DRIVER_NAME); - if (r) - goto err1; - - r = pci_register_driver(&b3dfg_driver); - if (r) - goto err2; - - return r; - -err2: - unregister_chrdev_region(b3dfg_devt, B3DFG_MAX_DEVS); -err1: - class_destroy(b3dfg_class); - return r; -} - -static void __exit b3dfg_module_exit(void) -{ - printk(KERN_INFO DRIVER_NAME ": unloaded\n"); - pci_unregister_driver(&b3dfg_driver); - unregister_chrdev_region(b3dfg_devt, B3DFG_MAX_DEVS); - class_destroy(b3dfg_class); -} - -module_init(b3dfg_module_init); -module_exit(b3dfg_module_exit); diff --git a/drivers/staging/batman-adv/Kconfig b/drivers/staging/batman-adv/Kconfig index 1d74dab..1e7e0a8 100644 --- a/drivers/staging/batman-adv/Kconfig +++ b/drivers/staging/batman-adv/Kconfig @@ -4,7 +4,7 @@ config BATMAN_ADV tristate "B.A.T.M.A.N. Advanced Meshing Protocol" - depends on PROC_FS && PACKET + depends on PROC_FS && NET default n ---help--- @@ -14,10 +14,10 @@ config BATMAN_ADV http://www.open-mesh.org/ for more information and user space tools. -config BATMAN_DEBUG +config BATMAN_ADV_DEBUG bool "B.A.T.M.A.N. debugging" depends on BATMAN_ADV != n - help + ---help--- This is an option for use by developers; most people should say N here. This enables compilation of support for diff --git a/drivers/staging/batman-adv/Makefile b/drivers/staging/batman-adv/Makefile index 02da871..42b4e63 100644 --- a/drivers/staging/batman-adv/Makefile +++ b/drivers/staging/batman-adv/Makefile @@ -19,4 +19,4 @@ # obj-m += batman-adv.o -batman-adv-objs := main.o proc.o send.o routing.o soft-interface.o device.o translation-table.o bitarray.o hash.o ring_buffer.o vis.o hard-interface.o aggregation.o log.o +batman-adv-objs := main.o proc.o send.o routing.o soft-interface.o device.o translation-table.o bitarray.o hash.o ring_buffer.o vis.o hard-interface.o aggregation.o originator.o diff --git a/drivers/staging/batman-adv/README b/drivers/staging/batman-adv/README index 3aaf393..7d666ad 100644 --- a/drivers/staging/batman-adv/README +++ b/drivers/staging/batman-adv/README @@ -1,4 +1,4 @@ -[state: 07-11-2009] +[state: 06-01-2010] BATMAN-ADV ---------- @@ -15,19 +15,6 @@ above B.A.T.M.A.N. Advanced, prominent examples are: IPv4, IPv6, DHCP, IPX. This is batman-advanced implemented as Linux kernel driver. It does not depend on any network (other) driver, and can be used on wifi as well as ethernet, vpn, etc ... (anything with ethernet-style layer 2). -It compiles against and should work with Linux 2.6.20 - 2.6.31. Supporting older -versions is not planned, but it's probably easy to backport it. If you work on a -backport, feel free to contact us. :-) - -COMPILE -------- -To compile against your currently installed kernel, just type: - -# make - -if you want to compile against some other kernel, use: - -# make KERNELPATH=/path/to/kernel USAGE ----- @@ -73,16 +60,9 @@ When configured as server, you can get a topology snapshot of your mesh: # cat /proc/net/batman-adv/vis -This output format is a graphviz formatted text file which can be -processed with graphviz-tools like dot. -The labels are similar/compatible to the ETX metric, 1.0 means perfect -connection (100%), 2.0 means 50%, 3.0 means 33% and so on. - -Alternatively, a JSON output format is available. The format can be set -using by writing either "dot_draw" or "json" into the vis_format file. -"dot_draw" is selected by default. - -echo "json" > /proc/net/batman-adv/vis_format +The output is in a generic raw format. Use the batctl tool (See below) +to convert this to other formats more suitable for graphing, eg +graphviz dot, or JSON data-interchange format. In very mobile scenarios, you might want to adjust the originator interval to a lower value. This will make the mesh more responsive to @@ -96,15 +76,59 @@ To deactivate batman, do: # echo "" > /proc/net/batman-adv/interfaces +LOGGING/DEBUGGING +----------------- + +All error messages, warnings and information messages are sent to the +kernel log. Depending on your operating system distribution this can be +read in one of a number of ways. Try using the commands: dmesg, +logread, or looking in the files /var/log/kern.log or +/var/log/syslog. All batman-adv messages are prefixed with +"batman-adv:" So to see just these messages try + +dmesg | grep batman-adv + +When investigating problems with your mesh network it is sometimes +necessary to see more detail debug messages. This must be enabled when +compiling the batman-adv module. Use "make menuconfig" and enable the +option "B.A.T.M.A.N. debugging". + +The additional debug output is by default disabled. It can be enabled +either at kernel module load time or during run time. To enable debug +output at module load time, add the module parameter debug=<value>. +<value> can take one of four values. + +0 - All debug output disabled +1 - Enable messages related to routing / flooding / broadcasting +2 - Enable route or hna added / changed / deleted +3 - Enable all messages + +e.g. + +modprobe batman-adv debug=2 + +will load the module and enable debug messages for when routes or HNAs +change. + +The debug output can also be changed at runtime using the file +/sys/module/batman-adv/parameters/debug. e.g. + +echo 2 > /sys/module/batman-adv/parameters/debug + +enables debug messages for when routes or HNAs + +The debug output is sent to the kernel logs. So try dmesg, logread etc +to see the debug messages. + BATCTL ------ -B.A.T.M.A.N. advanced operates on layer 2 and thus all hosts partici- -pating in the virtual switch are completely transparent for all proto- -cols above layer 2. Therefore the common diagnosis tools do not work as -expected. To overcome these problems batctl was created. At the moment -the batctl contains ping, traceroute, tcpdump and interfaces to the -kernel module settings. +B.A.T.M.A.N. advanced operates on layer 2 and thus all hosts +participating in the virtual switch are completely transparent for all +protocols above layer 2. Therefore the common diagnosis tools do not +work as expected. To overcome these problems batctl was created. At +the moment the batctl contains ping, traceroute, tcpdump and +interfaces to the kernel module settings. For more information, please see the manpage (man batctl). diff --git a/drivers/staging/batman-adv/TODO b/drivers/staging/batman-adv/TODO index ea6dcf9..2f15136 100644 --- a/drivers/staging/batman-adv/TODO +++ b/drivers/staging/batman-adv/TODO @@ -17,30 +17,6 @@ -> transtable_global (read-only) [outputs the global translation table] -> transtable_local (read-only) [outputs the local translation table] -=> vis "raw" data output -* the raw format shall replace dot draw / json to offer a neutral that can -* be converted -* the format (comma seperated entries): --> "mac" -> mac address of an originator (each line begins with it) --> "TQ mac value" -> src mac's link quality towards mac address --> "HNA mac" -> HNA announced by source mac --> "PRIMARY" -> this is a primary interface --> "SEC mac" -> secondary mac address of source (requires preceeding --> PRIMARY) - -=> logging -* the log level LOG_TYPE_CRIT, LOG_TYPE_WARN & LOG_TYPE_NOTICE will be -* unified to use printk -* LOG_TYPE_BATMAN & LOG_TYPE_ROUTES will also use printk but only after the -* internal debug level has been raised -* the internal debug level can be modified using a module parameter (debug) -* or at run time via /sys/module/batman-adv/parameters/debug -* make use of printk %pM support instead of converting mac addresses -* manually - -=> strip out all backward compatibility support to older kernels - (only found in compat.h) - => fix checkpatch.pl errors Please send all patches to: diff --git a/drivers/staging/batman-adv/aggregation.c b/drivers/staging/batman-adv/aggregation.c index 9c6e681..7917322 100644 --- a/drivers/staging/batman-adv/aggregation.c +++ b/drivers/staging/batman-adv/aggregation.c @@ -96,6 +96,7 @@ static void new_aggregated_packet(unsigned char *packet_buff, int own_packet) { struct forw_packet *forw_packet_aggr; + unsigned long flags; forw_packet_aggr = kmalloc(sizeof(struct forw_packet), GFP_ATOMIC); if (!forw_packet_aggr) @@ -115,6 +116,7 @@ static void new_aggregated_packet(unsigned char *packet_buff, packet_buff, forw_packet_aggr->packet_len); + forw_packet_aggr->skb = NULL; forw_packet_aggr->own = own_packet; forw_packet_aggr->if_incoming = if_incoming; forw_packet_aggr->num_packets = 0; @@ -126,9 +128,9 @@ static void new_aggregated_packet(unsigned char *packet_buff, forw_packet_aggr->direct_link_flags |= 1; /* add new packet to packet list */ - spin_lock(&forw_bat_list_lock); + spin_lock_irqsave(&forw_bat_list_lock, flags); hlist_add_head(&forw_packet_aggr->list, &forw_bat_list); - spin_unlock(&forw_bat_list_lock); + spin_unlock_irqrestore(&forw_bat_list_lock, flags); /* start timer for this packet */ INIT_DELAYED_WORK(&forw_packet_aggr->delayed_work, @@ -168,9 +170,10 @@ void add_bat_packet_to_list(unsigned char *packet_buff, int packet_len, struct batman_packet *batman_packet = (struct batman_packet *)packet_buff; bool direct_link = batman_packet->flags & DIRECTLINK ? 1 : 0; + unsigned long flags; /* find position for the packet in the forward queue */ - spin_lock(&forw_bat_list_lock); + spin_lock_irqsave(&forw_bat_list_lock, flags); /* own packets are not to be aggregated */ if ((atomic_read(&aggregation_enabled)) && (!own_packet)) { hlist_for_each_entry(forw_packet_pos, tmp_node, &forw_bat_list, @@ -191,7 +194,7 @@ void add_bat_packet_to_list(unsigned char *packet_buff, int packet_len, * suitable aggregation packet found */ if (forw_packet_aggr == NULL) { /* the following section can run without the lock */ - spin_unlock(&forw_bat_list_lock); + spin_unlock_irqrestore(&forw_bat_list_lock, flags); new_aggregated_packet(packet_buff, packet_len, send_time, direct_link, if_incoming, own_packet); @@ -199,7 +202,7 @@ void add_bat_packet_to_list(unsigned char *packet_buff, int packet_len, aggregate(forw_packet_aggr, packet_buff, packet_len, direct_link); - spin_unlock(&forw_bat_list_lock); + spin_unlock_irqrestore(&forw_bat_list_lock, flags); } } diff --git a/drivers/staging/batman-adv/bitarray.c b/drivers/staging/batman-adv/bitarray.c index 3c67f5f..212eef9 100644 --- a/drivers/staging/batman-adv/bitarray.c +++ b/drivers/staging/batman-adv/bitarray.c @@ -21,7 +21,6 @@ #include "main.h" #include "bitarray.h" -#include "log.h" /* returns true if the corresponding bit in the given seq_bits indicates true * and curr_seqno is within range of last_seqno */ @@ -80,8 +79,8 @@ void bit_shift(TYPE_OF_WORD *seq_bits, int32_t n) * from. * * left is high, right is low: FEDC BA98 7654 3210 - * ^^ ^^ - * vvvv + * ^^ ^^ + * vvvv * ^^^^ = from, vvvvv =to, we'd have word_num==1 and * word_offset==WORD_BIT_SIZE/2 ????? in this example. * (=24 bits) @@ -133,13 +132,13 @@ char bit_get_packet(TYPE_OF_WORD *seq_bits, int16_t seq_num_diff, (seq_num_diff < -TQ_LOCAL_WINDOW_SIZE)) { if (seq_num_diff > TQ_LOCAL_WINDOW_SIZE) - debug_log(LOG_TYPE_BATMAN, - "We missed a lot of packets (%i) !\n", - seq_num_diff-1); + bat_dbg(DBG_BATMAN, + "We missed a lot of packets (%i) !\n", + seq_num_diff-1); if (-seq_num_diff > TQ_LOCAL_WINDOW_SIZE) - debug_log(LOG_TYPE_BATMAN, - "Other host probably restarted !\n"); + bat_dbg(DBG_BATMAN, + "Other host probably restarted !\n"); for (i = 0; i < NUM_WORDS; i++) seq_bits[i] = 0; diff --git a/drivers/staging/batman-adv/compat.h b/drivers/staging/batman-adv/compat.h deleted file mode 100644 index f4e0a45..0000000 --- a/drivers/staging/batman-adv/compat.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: - * - * Marek Lindner, Simon Wunderlich - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - * - * This file contains macros for maintaining compatibility with older versions - * of the Linux kernel. - */ - -#include <linux/version.h> /* LINUX_VERSION_CODE */ - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) - -#define skb_set_network_header(_skb, _offset) \ - do { (_skb)->nh.raw = (_skb)->data + (_offset); } while (0) - -#define skb_reset_mac_header(_skb) \ - do { (_skb)->mac.raw = (_skb)->data; } while (0) - -#define list_first_entry(ptr, type, member) \ - list_entry((ptr)->next, type, member) - -#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) */ - - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26) - -#define device_create(_cls, _parent, _devt, _device, _fmt) \ - class_device_create(_cls, _parent, _devt, _device, _fmt) - -#define device_destroy(_cls, _device) \ - class_device_destroy(_cls, _device) - -#else - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27) - -#define device_create(_cls, _parent, _devt, _device, _fmt) \ - device_create_drvdata(_cls, _parent, _devt, _device, _fmt) - -#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27) */ - -#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26) */ - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23) - -#define cancel_delayed_work_sync(wq) cancel_rearming_delayed_work(wq) - -#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23) */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25) -#define strict_strtoul(cp, base, res) \ - ({ \ - int ret = 0; \ - char *endp; \ - *res = simple_strtoul(cp, &endp, base); \ - if (cp == endp) \ - ret = -EINVAL; \ - ret; \ -}) -#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25) */ diff --git a/drivers/staging/batman-adv/device.c b/drivers/staging/batman-adv/device.c index 1e7d1f8..e7f4421 100644 --- a/drivers/staging/batman-adv/device.c +++ b/drivers/staging/batman-adv/device.c @@ -19,14 +19,13 @@ * */ +#include <linux/device.h> #include "main.h" #include "device.h" -#include "log.h" #include "send.h" #include "types.h" #include "hash.h" - -#include "compat.h" +#include "hard-interface.h" static struct class *batman_class; @@ -60,7 +59,7 @@ int bat_device_setup(void) /* register our device - kernel assigns a free major number */ tmp_major = register_chrdev(0, DRIVER_DEVICE, &fops); if (tmp_major < 0) { - debug_log(LOG_TYPE_WARN, "Registering the character device failed with %d\n", + printk(KERN_ERR "batman-adv:Registering the character device failed with %d\n", tmp_major); return 0; } @@ -68,7 +67,7 @@ int bat_device_setup(void) batman_class = class_create(THIS_MODULE, "batman-adv"); if (IS_ERR(batman_class)) { - debug_log(LOG_TYPE_WARN, "Could not register class 'batman-adv' \n"); + printk(KERN_ERR "batman-adv:Could not register class 'batman-adv' \n"); return 0; } @@ -111,7 +110,7 @@ int bat_device_open(struct inode *inode, struct file *file) } if (device_client_hash[i] != device_client) { - debug_log(LOG_TYPE_WARN, "Error - can't add another packet client: maximum number of clients reached \n"); + printk(KERN_ERR "batman-adv:Error - can't add another packet client: maximum number of clients reached \n"); kfree(device_client); return -EXFULL; } @@ -119,7 +118,7 @@ int bat_device_open(struct inode *inode, struct file *file) INIT_LIST_HEAD(&device_client->queue_list); device_client->queue_len = 0; device_client->index = i; - device_client->lock = __SPIN_LOCK_UNLOCKED(device_client->lock); + spin_lock_init(&device_client->lock); init_waitqueue_head(&device_client->queue_wait); file->private_data = device_client; @@ -134,8 +133,9 @@ int bat_device_release(struct inode *inode, struct file *file) (struct device_client *)file->private_data; struct device_packet *device_packet; struct list_head *list_pos, *list_pos_tmp; + unsigned long flags; - spin_lock(&device_client->lock); + spin_lock_irqsave(&device_client->lock, flags); /* for all packets in the queue ... */ list_for_each_safe(list_pos, list_pos_tmp, &device_client->queue_list) { @@ -147,7 +147,7 @@ int bat_device_release(struct inode *inode, struct file *file) } device_client_hash[device_client->index] = NULL; - spin_unlock(&device_client->lock); + spin_unlock_irqrestore(&device_client->lock, flags); kfree(device_client); dec_module_count(); @@ -162,6 +162,7 @@ ssize_t bat_device_read(struct file *file, char __user *buf, size_t count, (struct device_client *)file->private_data; struct device_packet *device_packet; int error; + unsigned long flags; if ((file->f_flags & O_NONBLOCK) && (device_client->queue_len == 0)) return -EAGAIN; @@ -178,14 +179,14 @@ ssize_t bat_device_read(struct file *file, char __user *buf, size_t count, if (error) return error; - spin_lock(&device_client->lock); + spin_lock_irqsave(&device_client->lock, flags); device_packet = list_first_entry(&device_client->queue_list, struct device_packet, list); list_del(&device_packet->list); device_client->queue_len--; - spin_unlock(&device_client->lock); + spin_unlock_irqrestore(&device_client->lock, flags); error = __copy_to_user(buf, &device_packet->icmp_packet, sizeof(struct icmp_packet)); @@ -206,9 +207,11 @@ ssize_t bat_device_write(struct file *file, const char __user *buff, struct icmp_packet icmp_packet; struct orig_node *orig_node; struct batman_if *batman_if; + uint8_t dstaddr[ETH_ALEN]; + unsigned long flags; if (len < sizeof(struct icmp_packet)) { - debug_log(LOG_TYPE_NOTICE, "Error - can't send packet from char device: invalid packet size\n"); + bat_dbg(DBG_BATMAN, "batman-adv:Error - can't send packet from char device: invalid packet size\n"); return -EINVAL; } @@ -219,12 +222,12 @@ ssize_t bat_device_write(struct file *file, const char __user *buff, return -EFAULT; if (icmp_packet.packet_type != BAT_ICMP) { - debug_log(LOG_TYPE_NOTICE, "Error - can't send packet from char device: got bogus packet type (expected: BAT_ICMP)\n"); + bat_dbg(DBG_BATMAN, "batman-adv:Error - can't send packet from char device: got bogus packet type (expected: BAT_ICMP)\n"); return -EINVAL; } if (icmp_packet.msg_type != ECHO_REQUEST) { - debug_log(LOG_TYPE_NOTICE, "Error - can't send packet from char device: got bogus message type (expected: ECHO_REQUEST)\n"); + bat_dbg(DBG_BATMAN, "batman-adv:Error - can't send packet from char device: got bogus message type (expected: ECHO_REQUEST)\n"); return -EINVAL; } @@ -240,7 +243,7 @@ ssize_t bat_device_write(struct file *file, const char __user *buff, if (atomic_read(&module_state) != MODULE_ACTIVE) goto dst_unreach; - spin_lock(&orig_hash_lock); + spin_lock_irqsave(&orig_hash_lock, flags); orig_node = ((struct orig_node *)hash_find(orig_hash, icmp_packet.dst)); if (!orig_node) @@ -250,9 +253,15 @@ ssize_t bat_device_write(struct file *file, const char __user *buff, goto unlock; batman_if = orig_node->batman_if; + memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); + + spin_unlock_irqrestore(&orig_hash_lock, flags); if (!batman_if) - goto unlock; + goto dst_unreach; + + if (batman_if->if_active != IF_ACTIVE) + goto dst_unreach; memcpy(icmp_packet.orig, batman_if->net_dev->dev_addr, @@ -260,13 +269,12 @@ ssize_t bat_device_write(struct file *file, const char __user *buff, send_raw_packet((unsigned char *)&icmp_packet, sizeof(struct icmp_packet), - batman_if, orig_node->router->addr); + batman_if, dstaddr); - spin_unlock(&orig_hash_lock); goto out; unlock: - spin_unlock(&orig_hash_lock); + spin_unlock_irqrestore(&orig_hash_lock, flags); dst_unreach: icmp_packet.msg_type = DESTINATION_UNREACHABLE; bat_device_add_packet(device_client, &icmp_packet); @@ -291,6 +299,7 @@ void bat_device_add_packet(struct device_client *device_client, struct icmp_packet *icmp_packet) { struct device_packet *device_packet; + unsigned long flags; device_packet = kmalloc(sizeof(struct device_packet), GFP_KERNEL); @@ -301,12 +310,12 @@ void bat_device_add_packet(struct device_client *device_client, memcpy(&device_packet->icmp_packet, icmp_packet, sizeof(struct icmp_packet)); - spin_lock(&device_client->lock); + spin_lock_irqsave(&device_client->lock, flags); /* while waiting for the lock the device_client could have been * deleted */ if (!device_client_hash[icmp_packet->uid]) { - spin_unlock(&device_client->lock); + spin_unlock_irqrestore(&device_client->lock, flags); kfree(device_packet); return; } @@ -323,7 +332,7 @@ void bat_device_add_packet(struct device_client *device_client, device_client->queue_len--; } - spin_unlock(&device_client->lock); + spin_unlock_irqrestore(&device_client->lock, flags); wake_up(&device_client->queue_wait); } diff --git a/drivers/staging/batman-adv/hard-interface.c b/drivers/staging/batman-adv/hard-interface.c index 5ea35da..befd488 100644 --- a/drivers/staging/batman-adv/hard-interface.c +++ b/drivers/staging/batman-adv/hard-interface.c @@ -21,13 +21,11 @@ #include "main.h" #include "hard-interface.h" -#include "log.h" #include "soft-interface.h" #include "send.h" #include "translation-table.h" #include "routing.h" #include "hash.h" -#include "compat.h" #define MIN(x, y) ((x) < (y) ? (x) : (y)) @@ -75,7 +73,6 @@ int hardif_min_mtu(void) static void check_known_mac_addr(uint8_t *addr) { struct batman_if *batman_if; - char mac_string[ETH_STR_LEN]; rcu_read_lock(); list_for_each_entry_rcu(batman_if, &if_list, list) { @@ -86,10 +83,9 @@ static void check_known_mac_addr(uint8_t *addr) if (!compare_orig(batman_if->net_dev->dev_addr, addr)) continue; - addr_to_string(mac_string, addr); - debug_log(LOG_TYPE_WARN, "The newly added mac address (%s) already exists on: %s\n", - mac_string, batman_if->dev); - debug_log(LOG_TYPE_WARN, "It is strongly recommended to keep mac addresses unique to avoid problems!\n"); + printk(KERN_WARNING "batman-adv:The newly added mac address (%pM) already exists on: %s\n", + addr, batman_if->dev); + printk(KERN_WARNING "batman-adv:It is strongly recommended to keep mac addresses unique to avoid problems!\n"); } rcu_read_unlock(); } @@ -154,9 +150,6 @@ void hardif_deactivate_interface(struct batman_if *batman_if) if (batman_if->if_active != IF_ACTIVE) return; - if (batman_if->raw_sock) - sock_release(batman_if->raw_sock); - /** * batman_if->net_dev has been acquired by dev_get_by_name() in * proc_interfaces_write() and has to be unreferenced. @@ -165,22 +158,16 @@ void hardif_deactivate_interface(struct batman_if *batman_if) if (batman_if->net_dev) dev_put(batman_if->net_dev); - batman_if->raw_sock = NULL; - batman_if->net_dev = NULL; - batman_if->if_active = IF_INACTIVE; active_ifs--; - debug_log(LOG_TYPE_NOTICE, "Interface deactivated: %s\n", - batman_if->dev); + printk(KERN_INFO "batman-adv:Interface deactivated: %s\n", + batman_if->dev); } /* (re)activate given interface. */ static void hardif_activate_interface(struct batman_if *batman_if) { - struct sockaddr_ll bind_addr; - int retval; - if (batman_if->if_active != IF_INACTIVE) return; @@ -192,35 +179,8 @@ static void hardif_activate_interface(struct batman_if *batman_if) if (!batman_if->net_dev) goto dev_err; - retval = sock_create_kern(PF_PACKET, SOCK_RAW, - __constant_htons(ETH_P_BATMAN), - &batman_if->raw_sock); - - if (retval < 0) { - debug_log(LOG_TYPE_WARN, "Can't create raw socket: %i\n", - retval); - goto sock_err; - } - - bind_addr.sll_family = AF_PACKET; - bind_addr.sll_ifindex = batman_if->net_dev->ifindex; - bind_addr.sll_protocol = 0; /* is set by the kernel */ - - retval = kernel_bind(batman_if->raw_sock, - (struct sockaddr *)&bind_addr, sizeof(bind_addr)); - - if (retval < 0) { - debug_log(LOG_TYPE_WARN, "Can't create bind raw socket: %i\n", - retval); - goto bind_err; - } - check_known_mac_addr(batman_if->net_dev->dev_addr); - batman_if->raw_sock->sk->sk_user_data = - batman_if->raw_sock->sk->sk_data_ready; - batman_if->raw_sock->sk->sk_data_ready = batman_data_ready; - addr_to_string(batman_if->addr_str, batman_if->net_dev->dev_addr); memcpy(((struct batman_packet *)(batman_if->packet_buff))->orig, @@ -235,17 +195,12 @@ static void hardif_activate_interface(struct batman_if *batman_if) if (batman_if->if_num == 0) set_main_if_addr(batman_if->net_dev->dev_addr); - debug_log(LOG_TYPE_NOTICE, "Interface activated: %s\n", - batman_if->dev); + printk(KERN_INFO "batman-adv:Interface activated: %s\n", + batman_if->dev); return; -bind_err: - sock_release(batman_if->raw_sock); -sock_err: - dev_put(batman_if->net_dev); dev_err: - batman_if->raw_sock = NULL; batman_if->net_dev = NULL; } @@ -290,7 +245,7 @@ static int resize_orig(struct orig_node *orig_node, int if_num) data_ptr = kmalloc((if_num + 1) * sizeof(TYPE_OF_WORD) * NUM_WORDS, GFP_ATOMIC); if (!data_ptr) { - debug_log(LOG_TYPE_WARN, "Can't resize orig: out of memory\n"); + printk(KERN_ERR "batman-adv:Can't resize orig: out of memory\n"); return -1; } @@ -301,7 +256,7 @@ static int resize_orig(struct orig_node *orig_node, int if_num) data_ptr = kmalloc((if_num + 1) * sizeof(uint8_t), GFP_ATOMIC); if (!data_ptr) { - debug_log(LOG_TYPE_WARN, "Can't resize orig: out of memory\n"); + printk(KERN_ERR "batman-adv:Can't resize orig: out of memory\n"); return -1; } @@ -319,16 +274,16 @@ int hardif_add_interface(char *dev, int if_num) struct batman_if *batman_if; struct batman_packet *batman_packet; struct orig_node *orig_node; - struct hash_it_t *hashit = NULL; + unsigned long flags; + HASHIT(hashit); batman_if = kmalloc(sizeof(struct batman_if), GFP_KERNEL); if (!batman_if) { - debug_log(LOG_TYPE_WARN, "Can't add interface (%s): out of memory\n", dev); + printk(KERN_ERR "batman-adv:Can't add interface (%s): out of memory\n", dev); return -1; } - batman_if->raw_sock = NULL; batman_if->net_dev = NULL; if ((if_num == 0) && (num_hna > 0)) @@ -339,7 +294,7 @@ int hardif_add_interface(char *dev, int if_num) batman_if->packet_buff = kmalloc(batman_if->packet_len, GFP_KERNEL); if (!batman_if->packet_buff) { - debug_log(LOG_TYPE_WARN, "Can't add interface packet (%s): out of memory\n", dev); + printk(KERN_ERR "batman-adv:Can't add interface packet (%s): out of memory\n", dev); goto out; } @@ -348,7 +303,7 @@ int hardif_add_interface(char *dev, int if_num) batman_if->if_active = IF_INACTIVE; INIT_RCU_HEAD(&batman_if->rcu); - debug_log(LOG_TYPE_NOTICE, "Adding interface: %s\n", dev); + printk(KERN_INFO "batman-adv:Adding interface: %s\n", dev); avail_ifs++; INIT_LIST_HEAD(&batman_if->list); @@ -376,20 +331,20 @@ int hardif_add_interface(char *dev, int if_num) /* resize all orig nodes because orig_node->bcast_own(_sum) depend on * if_num */ - spin_lock(&orig_hash_lock); + spin_lock_irqsave(&orig_hash_lock, flags); - while (NULL != (hashit = hash_iterate(orig_hash, hashit))) { - orig_node = hashit->bucket->data; + while (hash_iterate(orig_hash, &hashit)) { + orig_node = hashit.bucket->data; if (resize_orig(orig_node, if_num) == -1) { - spin_unlock(&orig_hash_lock); + spin_unlock_irqrestore(&orig_hash_lock, flags); goto out; } } - spin_unlock(&orig_hash_lock); + spin_unlock_irqrestore(&orig_hash_lock, flags); if (!hardif_is_interface_up(batman_if->dev)) - debug_log(LOG_TYPE_WARN, "Not using interface %s (retrying later): interface not active\n", batman_if->dev); + printk(KERN_ERR "batman-adv:Not using interface %s (retrying later): interface not active\n", batman_if->dev); else hardif_activate_interface(batman_if); @@ -400,8 +355,7 @@ int hardif_add_interface(char *dev, int if_num) return 1; out: - if (batman_if->packet_buff) - kfree(batman_if->packet_buff); + kfree(batman_if->packet_buff); kfree(batman_if); kfree(dev); return -1; @@ -413,7 +367,7 @@ char hardif_get_active_if_num(void) } static int hard_if_event(struct notifier_block *this, - unsigned long event, void *ptr) + unsigned long event, void *ptr) { struct net_device *dev = (struct net_device *)ptr; struct batman_if *batman_if = get_batman_if_by_name(dev->name); @@ -436,7 +390,6 @@ static int hard_if_event(struct notifier_block *this, break; /* NETDEV_CHANGEADDR - mac address change - what are we doing here ? */ default: - /* debug_log(LOG_TYPE_CRIT, "hard_if_event: %s %i\n", dev->name, event); */ break; }; @@ -446,6 +399,122 @@ out: return NOTIFY_DONE; } +/* find batman interface by netdev. assumes rcu_read_lock on */ +static struct batman_if *find_batman_if(struct net_device *dev) +{ + struct batman_if *batman_if; + + rcu_read_lock(); + list_for_each_entry_rcu(batman_if, &if_list, list) { + if (batman_if->net_dev == dev) { + rcu_read_unlock(); + return batman_if; + } + } + rcu_read_unlock(); + return NULL; +} + + +/* receive a packet with the batman ethertype coming on a hard + * interface */ +int batman_skb_recv(struct sk_buff *skb, struct net_device *dev, + struct packet_type *ptype, struct net_device *orig_dev) +{ + struct batman_packet *batman_packet; + struct batman_if *batman_if; + struct net_device_stats *stats; + int ret; + + skb = skb_share_check(skb, GFP_ATOMIC); + + /* skb was released by skb_share_check() */ + if (!skb) + goto err_out; + + if (atomic_read(&module_state) != MODULE_ACTIVE) + goto err_free; + + /* packet should hold at least type and version */ + if (unlikely(skb_headlen(skb) < 2)) + goto err_free; + + /* expect a valid ethernet header here. */ + if (unlikely(skb->mac_len != sizeof(struct ethhdr) + || !skb_mac_header(skb))) + goto err_free; + + batman_if = find_batman_if(skb->dev); + if (!batman_if) + goto err_free; + + /* discard frames on not active interfaces */ + if (batman_if->if_active != IF_ACTIVE) + goto err_free; + + stats = (struct net_device_stats *)dev_get_stats(skb->dev); + if (stats) { + stats->rx_packets++; + stats->rx_bytes += skb->len; + } + + batman_packet = (struct batman_packet *)skb->data; + + if (batman_packet->version != COMPAT_VERSION) { + bat_dbg(DBG_BATMAN, + "Drop packet: incompatible batman version (%i)\n", + batman_packet->version); + goto err_free; + } + + /* all receive handlers return whether they received or reused + * the supplied skb. if not, we have to free the skb. */ + + switch (batman_packet->packet_type) { + /* batman originator packet */ + case BAT_PACKET: + ret = recv_bat_packet(skb, batman_if); + break; + + /* batman icmp packet */ + case BAT_ICMP: + ret = recv_icmp_packet(skb); + break; + + /* unicast packet */ + case BAT_UNICAST: + ret = recv_unicast_packet(skb); + break; + + /* broadcast packet */ + case BAT_BCAST: + ret = recv_bcast_packet(skb); + break; + + /* vis packet */ + case BAT_VIS: + ret = recv_vis_packet(skb); + break; + default: + ret = NET_RX_DROP; + } + + if (ret == NET_RX_DROP) + kfree_skb(skb); + + /* return NET_RX_SUCCESS in any case as we + * most probably dropped the packet for + * routing-logical reasons. */ + + return NET_RX_SUCCESS; + +err_free: + kfree_skb(skb); +err_out: + return NET_RX_DROP; +} + + struct notifier_block hard_if_notifier = { - .notifier_call = hard_if_event, + .notifier_call = hard_if_event, }; diff --git a/drivers/staging/batman-adv/hard-interface.h b/drivers/staging/batman-adv/hard-interface.h index 742358c..97c6ecb 100644 --- a/drivers/staging/batman-adv/hard-interface.h +++ b/drivers/staging/batman-adv/hard-interface.h @@ -32,5 +32,9 @@ void hardif_deactivate_interface(struct batman_if *batman_if); char hardif_get_active_if_num(void); void hardif_check_interfaces_status(void); void hardif_check_interfaces_status_wq(struct work_struct *work); +int batman_skb_recv(struct sk_buff *skb, + struct net_device *dev, + struct packet_type *ptype, + struct net_device *orig_dev); int hardif_min_mtu(void); void update_min_mtu(void); diff --git a/drivers/staging/batman-adv/hash.c b/drivers/staging/batman-adv/hash.c index 61cb4a2..5a2018d 100644 --- a/drivers/staging/batman-adv/hash.c +++ b/drivers/staging/batman-adv/hash.c @@ -64,24 +64,18 @@ void hash_destroy(struct hashtable_t *hash) kfree(hash); } -/* iterate though the hash. first element is selected with iter_in NULL. use - * the returned iterator to access the elements until hash_it_t returns NULL. */ +/* iterate though the hash. First element is selected if an iterator + * initialized with HASHIT() is supplied as iter. Use the returned + * (or supplied) iterator to access the elements until hash_iterate returns + * NULL. */ + struct hash_it_t *hash_iterate(struct hashtable_t *hash, - struct hash_it_t *iter_in) + struct hash_it_t *iter) { - struct hash_it_t *iter; - if (!hash) return NULL; - - if (iter_in == NULL) { - iter = kmalloc(sizeof(struct hash_it_t), GFP_ATOMIC); - iter->index = -1; - iter->bucket = NULL; - iter->prev_bucket = NULL; - } else { - iter = iter_in; - } + if (!iter) + return NULL; /* sanity checks first (if our bucket got deleted in the last * iteration): */ @@ -139,7 +133,6 @@ struct hash_it_t *hash_iterate(struct hashtable_t *hash, } /* nothing to iterate over anymore */ - kfree(iter); return NULL; } diff --git a/drivers/staging/batman-adv/hash.h b/drivers/staging/batman-adv/hash.h index bb60f08..a70d6d6 100644 --- a/drivers/staging/batman-adv/hash.h +++ b/drivers/staging/batman-adv/hash.h @@ -21,6 +21,11 @@ #ifndef _BATMAN_HASH_H #define _BATMAN_HASH_H +#define HASHIT(name) struct hash_it_t name = { \ + .index = -1, .bucket = NULL, \ + .prev_bucket = NULL, \ + .first_bucket = NULL } + typedef int (*hashdata_compare_cb)(void *, void *); typedef int (*hashdata_choose_cb)(void *, int); diff --git a/drivers/staging/batman-adv/log.c b/drivers/staging/batman-adv/log.c deleted file mode 100644 index f37c7f0..0000000 --- a/drivers/staging/batman-adv/log.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: - * - * Marek Lindner, Simon Wunderlich - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - */ - -#include "main.h" -#include "log.h" - -#define LOG_BUF_MASK (log_buf_len-1) -#define LOG_BUF(idx) (log_buf[(idx) & LOG_BUF_MASK]) - -static char log_buf[LOG_BUF_LEN]; -static int log_buf_len = LOG_BUF_LEN; -static unsigned long log_start; -static unsigned long log_end; -uint8_t log_level; - -static DEFINE_SPINLOCK(logbuf_lock); - -const struct file_operations proc_log_operations = { - .open = log_open, - .release = log_release, - .read = log_read, - .write = log_write, - .poll = log_poll, -}; - -static DECLARE_WAIT_QUEUE_HEAD(log_wait); - -static void emit_log_char(char c) -{ - LOG_BUF(log_end) = c; - log_end++; - - if (log_end - log_start > log_buf_len) - log_start = log_end - log_buf_len; -} - -static int fdebug_log(char *fmt, ...) -{ - int printed_len; - char *p; - va_list args; - static char debug_log_buf[256]; - unsigned long flags; - - spin_lock_irqsave(&logbuf_lock, flags); - va_start(args, fmt); - printed_len = vscnprintf(debug_log_buf, sizeof(debug_log_buf), fmt, - args); - va_end(args); - - for (p = debug_log_buf; *p != 0; p++) - emit_log_char(*p); - - spin_unlock_irqrestore(&logbuf_lock, flags); - - wake_up(&log_wait); - - return 0; -} - -int debug_log(int type, char *fmt, ...) -{ - va_list args; - int retval = 0; - char tmp_log_buf[256]; - - /* only critical information get into the official kernel log */ - if (type == LOG_TYPE_CRIT) { - va_start(args, fmt); - vscnprintf(tmp_log_buf, sizeof(tmp_log_buf), fmt, args); - printk(KERN_ERR "batman-adv: %s", tmp_log_buf); - va_end(args); - } - - if ((type == LOG_TYPE_CRIT) || (log_level & type)) { - va_start(args, fmt); - vscnprintf(tmp_log_buf, sizeof(tmp_log_buf), fmt, args); - fdebug_log("[%10u] %s", (jiffies / HZ), tmp_log_buf); - va_end(args); - } - - return retval; -} - -int log_open(struct inode *inode, struct file *file) -{ - inc_module_count(); - return 0; -} - -int log_release(struct inode *inode, struct file *file) -{ - dec_module_count(); - return 0; -} - -ssize_t log_read(struct file *file, char __user *buf, size_t count, - loff_t *ppos) -{ - int error, i = 0; - char c; - unsigned long flags; - - if ((file->f_flags & O_NONBLOCK) && !(log_end - log_start)) - return -EAGAIN; - - if ((!buf) || (count < 0)) - return -EINVAL; - - if (count == 0) - return 0; - - if (!access_ok(VERIFY_WRITE, buf, count)) - return -EFAULT; - - error = wait_event_interruptible(log_wait, (log_start - log_end)); - - if (error) - return error; - - spin_lock_irqsave(&logbuf_lock, flags); - - while ((!error) && (log_start != log_end) && (i < count)) { - c = LOG_BUF(log_start); - - log_start++; - - spin_unlock_irqrestore(&logbuf_lock, flags); - - error = __put_user(c, buf); - - spin_lock_irqsave(&logbuf_lock, flags); - - buf++; - i++; - - } - - spin_unlock_irqrestore(&logbuf_lock, flags); - - if (!error) - return i; - - return error; -} - -ssize_t log_write(struct file *file, const char __user *buf, size_t count, - loff_t *ppos) -{ - return count; -} - -unsigned int log_poll(struct file *file, poll_table *wait) -{ - poll_wait(file, &log_wait, wait); - - if (log_end - log_start) - return POLLIN | POLLRDNORM; - - return 0; -} diff --git a/drivers/staging/batman-adv/main.c b/drivers/staging/batman-adv/main.c index bb89bfc..2e0b482 100644 --- a/drivers/staging/batman-adv/main.c +++ b/drivers/staging/batman-adv/main.c @@ -21,9 +21,9 @@ #include "main.h" #include "proc.h" -#include "log.h" #include "routing.h" #include "send.h" +#include "originator.h" #include "soft-interface.h" #include "device.h" #include "translation-table.h" @@ -31,7 +31,6 @@ #include "types.h" #include "vis.h" #include "hash.h" -#include "compat.h" struct list_head if_list; struct hlist_head forw_bat_list; @@ -44,19 +43,34 @@ DEFINE_SPINLOCK(forw_bcast_list_lock); atomic_t originator_interval; atomic_t vis_interval; +atomic_t vis_mode; atomic_t aggregation_enabled; int16_t num_hna; int16_t num_ifs; struct net_device *soft_device; -static struct task_struct *kthread_task; - unsigned char broadcastAddr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; atomic_t module_state; +static struct packet_type batman_adv_packet_type __read_mostly = { + .type = __constant_htons(ETH_P_BATMAN), + .func = batman_skb_recv, +}; + struct workqueue_struct *bat_event_workqueue; +#ifdef CONFIG_BATMAN_ADV_DEBUG +int debug; + +module_param(debug, int, 0644); + +int bat_debug_type(int type) +{ + return debug & type; +} +#endif + int init_module(void) { int retval; @@ -70,6 +84,7 @@ int init_module(void) atomic_set(&originator_interval, 1000); atomic_set(&vis_interval, 1000);/* TODO: raise this later, this is only * for debugging now. */ + atomic_set(&vis_mode, VIS_TYPE_CLIENT_UPDATE); atomic_set(&aggregation_enabled, 1); /* the name should not be longer than 10 chars - see @@ -90,21 +105,22 @@ int init_module(void) interface_setup); if (!soft_device) { - debug_log(LOG_TYPE_CRIT, "Unable to allocate the batman interface\n"); + printk(KERN_ERR "batman-adv:Unable to allocate the batman interface\n"); goto end; } retval = register_netdev(soft_device); if (retval < 0) { - debug_log(LOG_TYPE_CRIT, "Unable to register the batman interface: %i\n", retval); + printk(KERN_ERR "batman-adv:Unable to register the batman interface: %i\n", retval); goto free_soft_device; } register_netdevice_notifier(&hard_if_notifier); + dev_add_pack(&batman_adv_packet_type); - debug_log(LOG_TYPE_CRIT, "B.A.T.M.A.N. advanced %s%s (compatibility version %i) loaded \n", - SOURCE_VERSION, REVISION_VERSION_STR, COMPAT_VERSION); + printk(KERN_INFO "batman-adv:B.A.T.M.A.N. advanced %s%s (compatibility version %i) loaded \n", + SOURCE_VERSION, REVISION_VERSION_STR, COMPAT_VERSION); return 0; @@ -124,6 +140,8 @@ void cleanup_module(void) soft_device = NULL; } + dev_remove_pack(&batman_adv_packet_type); + unregister_netdevice_notifier(&hard_if_notifier); cleanup_procfs(); @@ -151,22 +169,12 @@ void activate_module(void) if (vis_init() < 1) goto err; - /* (re)start kernel thread for packet processing */ - if (!kthread_task) { - kthread_task = kthread_run(packet_recv_thread, NULL, "batman-adv"); - - if (IS_ERR(kthread_task)) { - debug_log(LOG_TYPE_CRIT, "Unable to start packet receive thread\n"); - kthread_task = NULL; - } - } - update_min_mtu(); atomic_set(&module_state, MODULE_ACTIVE); goto end; err: - debug_log(LOG_TYPE_CRIT, "Unable to allocate memory for mesh information structures: out of mem ?\n"); + printk(KERN_ERR "batman-adv:Unable to allocate memory for mesh information structures: out of mem ?\n"); shutdown_module(); end: return; @@ -182,14 +190,7 @@ void shutdown_module(void) vis_quit(); - /* deactivate kernel thread for packet processing (if running) */ - if (kthread_task) { - atomic_set(&exit_cond, 1); - wake_up_interruptible(&thread_wait); - kthread_stop(kthread_task); - - kthread_task = NULL; - } + /* TODO: unregister BATMAN pack */ originator_free(); diff --git a/drivers/staging/batman-adv/main.h b/drivers/staging/batman-adv/main.h index facb6b7..deb41f5 100644 --- a/drivers/staging/batman-adv/main.h +++ b/drivers/staging/batman-adv/main.h @@ -33,16 +33,16 @@ #define TQ_MAX_VALUE 255 #define JITTER 20 -#define TTL 50 /* Time To Live of broadcast messages */ -#define MAX_ADDR 16 /* number of interfaces which can be added to +#define TTL 50 /* Time To Live of broadcast messages */ +#define MAX_ADDR 16 /* number of interfaces which can be added to * batman. */ -#define PURGE_TIMEOUT 200000 /* purge originators after time in ms if no +#define PURGE_TIMEOUT 200000 /* purge originators after time in ms if no * valid packet comes in -> TODO: check * influence on TQ_LOCAL_WINDOW_SIZE */ #define LOCAL_HNA_TIMEOUT 3600000 -#define TQ_LOCAL_WINDOW_SIZE 64 /* sliding packet range of received originator +#define TQ_LOCAL_WINDOW_SIZE 64 /* sliding packet range of received originator * messages in squence numbers (should be a * multiple of our word size) */ #define TQ_GLOBAL_WINDOW_SIZE 5 @@ -69,24 +69,27 @@ /* - * Logging + * Debug Messages */ -#define LOG_TYPE_CRIT 0 /* highest priority for fatal errors such as - * blocked sockets / failed packet delivery / - * programming errors */ -#define LOG_TYPE_WARN 1 /* warnings for small errors like wrong user - * input / damaged packets / etc */ -#define LOG_TYPE_NOTICE 2 /* notice information for new interfaces / - * changed settings / new originators / etc */ -#define LOG_TYPE_BATMAN 4 /* all messages related to routing / flooding / - * broadcasting / etc */ -#define LOG_TYPE_ROUTES 8 /* route or hna added / changed / deleted */ -#define LOG_TYPE_CRIT_NAME "critical" -#define LOG_TYPE_WARN_NAME "warnings" -#define LOG_TYPE_NOTICE_NAME "notices" -#define LOG_TYPE_BATMAN_NAME "batman" -#define LOG_TYPE_ROUTES_NAME "routes" +#define DBG_BATMAN 1 /* all messages related to routing / flooding / + * broadcasting / etc */ +#define DBG_ROUTES 2 /* route or hna added / changed / deleted */ + +#ifdef CONFIG_BATMAN_ADV_DEBUG +extern int debug; + +extern int bat_debug_type(int type); +#define bat_dbg(type, fmt, arg...) do { \ + if (bat_debug_type(type)) \ + printk(KERN_DEBUG "batman-adv:" fmt, ## arg); \ + } \ + while (0) +#else /* !CONFIG_BATMAN_ADV_DEBUG */ +#define bat_dbg(type, fmt, arg...) do { \ + } \ + while (0) +#endif /* * Vis @@ -127,6 +130,7 @@ extern spinlock_t forw_bcast_list_lock; extern atomic_t originator_interval; extern atomic_t vis_interval; +extern atomic_t vis_mode; extern atomic_t aggregation_enabled; extern int16_t num_hna; extern int16_t num_ifs; @@ -147,5 +151,3 @@ int choose_orig(void *data, int32_t size); int is_my_mac(uint8_t *addr); int is_bcast(uint8_t *addr); int is_mcast(uint8_t *addr); - - diff --git a/drivers/staging/batman-adv/originator.c b/drivers/staging/batman-adv/originator.c new file mode 100644 index 0000000..29c2411 --- /dev/null +++ b/drivers/staging/batman-adv/originator.c @@ -0,0 +1,252 @@ +/* + * Copyright (C) 2009 B.A.T.M.A.N. contributors: + * + * Marek Lindner, Simon Wunderlich + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +/* increase the reference counter for this originator */ + +#include "main.h" +#include "originator.h" +#include "hash.h" +#include "translation-table.h" +#include "routing.h" + +static DECLARE_DELAYED_WORK(purge_orig_wq, purge_orig); + +static void start_purge_timer(void) +{ + queue_delayed_work(bat_event_workqueue, &purge_orig_wq, 1 * HZ); +} + +int originator_init(void) +{ + unsigned long flags; + if (orig_hash) + return 1; + + spin_lock_irqsave(&orig_hash_lock, flags); + orig_hash = hash_new(128, compare_orig, choose_orig); + + if (!orig_hash) + goto err; + + spin_unlock_irqrestore(&orig_hash_lock, flags); + start_purge_timer(); + return 1; + +err: + spin_unlock_irqrestore(&orig_hash_lock, flags); + return 0; +} + +void originator_free(void) +{ + unsigned long flags; + + if (!orig_hash) + return; + + cancel_delayed_work_sync(&purge_orig_wq); + + spin_lock_irqsave(&orig_hash_lock, flags); + hash_delete(orig_hash, free_orig_node); + orig_hash = NULL; + spin_unlock_irqrestore(&orig_hash_lock, flags); +} + +struct neigh_node * +create_neighbor(struct orig_node *orig_node, struct orig_node *orig_neigh_node, + uint8_t *neigh, struct batman_if *if_incoming) +{ + struct neigh_node *neigh_node; + + bat_dbg(DBG_BATMAN, "Creating new last-hop neighbor of originator\n"); + + neigh_node = kzalloc(sizeof(struct neigh_node), GFP_ATOMIC); + if (!neigh_node) + return NULL; + + INIT_LIST_HEAD(&neigh_node->list); + + memcpy(neigh_node->addr, neigh, ETH_ALEN); + neigh_node->orig_node = orig_neigh_node; + neigh_node->if_incoming = if_incoming; + + list_add_tail(&neigh_node->list, &orig_node->neigh_list); + return neigh_node; +} + +void free_orig_node(void *data) +{ + struct list_head *list_pos, *list_pos_tmp; + struct neigh_node *neigh_node; + struct orig_node *orig_node = (struct orig_node *)data; + + /* for all neighbors towards this originator ... */ + list_for_each_safe(list_pos, list_pos_tmp, &orig_node->neigh_list) { + neigh_node = list_entry(list_pos, struct neigh_node, list); + + list_del(list_pos); + kfree(neigh_node); + } + + hna_global_del_orig(orig_node, "originator timed out"); + + kfree(orig_node->bcast_own); + kfree(orig_node->bcast_own_sum); + kfree(orig_node); +} + +/* this function finds or creates an originator entry for the given + * address if it does not exits */ +struct orig_node *get_orig_node(uint8_t *addr) +{ + struct orig_node *orig_node; + struct hashtable_t *swaphash; + int size; + + orig_node = ((struct orig_node *)hash_find(orig_hash, addr)); + + if (orig_node != NULL) + return orig_node; + + bat_dbg(DBG_BATMAN, "Creating new originator: %pM \n", addr); + + orig_node = kzalloc(sizeof(struct orig_node), GFP_ATOMIC); + if (!orig_node) + return NULL; + + INIT_LIST_HEAD(&orig_node->neigh_list); + + memcpy(orig_node->orig, addr, ETH_ALEN); + orig_node->router = NULL; + orig_node->batman_if = NULL; + orig_node->hna_buff = NULL; + + size = num_ifs * sizeof(TYPE_OF_WORD) * NUM_WORDS; + + orig_node->bcast_own = kzalloc(size, GFP_ATOMIC); + if (!orig_node->bcast_own) + goto free_orig_node; + + size = num_ifs * sizeof(uint8_t); + orig_node->bcast_own_sum = kzalloc(size, GFP_ATOMIC); + if (!orig_node->bcast_own_sum) + goto free_bcast_own; + + if (hash_add(orig_hash, orig_node) < 0) + goto free_bcast_own_sum; + + if (orig_hash->elements * 4 > orig_hash->size) { + swaphash = hash_resize(orig_hash, orig_hash->size * 2); + + if (swaphash == NULL) + printk(KERN_ERR + "batman-adv:Couldn't resize orig hash table \n"); + else + orig_hash = swaphash; + } + + return orig_node; +free_bcast_own_sum: + kfree(orig_node->bcast_own_sum); +free_bcast_own: + kfree(orig_node->bcast_own); +free_orig_node: + kfree(orig_node); + return NULL; +} + +static bool purge_orig_neighbors(struct orig_node *orig_node, + struct neigh_node **best_neigh_node) +{ + struct list_head *list_pos, *list_pos_tmp; + struct neigh_node *neigh_node; + bool neigh_purged = false; + + *best_neigh_node = NULL; + + + /* for all neighbors towards this originator ... */ + list_for_each_safe(list_pos, list_pos_tmp, &orig_node->neigh_list) { + neigh_node = list_entry(list_pos, struct neigh_node, list); + + if (time_after(jiffies, + (neigh_node->last_valid + + ((PURGE_TIMEOUT * HZ) / 1000)))) { + + bat_dbg(DBG_BATMAN, "neighbor timeout: originator %pM, neighbor: %pM, last_valid %lu\n", orig_node->orig, neigh_node->addr, (neigh_node->last_valid / HZ)); + + neigh_purged = true; + list_del(list_pos); + kfree(neigh_node); + } else { + if ((*best_neigh_node == NULL) || + (neigh_node->tq_avg > (*best_neigh_node)->tq_avg)) + *best_neigh_node = neigh_node; + } + } + return neigh_purged; +} + + +static bool purge_orig_node(struct orig_node *orig_node) +{ + struct neigh_node *best_neigh_node; + + if (time_after(jiffies, + (orig_node->last_valid + + ((2 * PURGE_TIMEOUT * HZ) / 1000)))) { + + bat_dbg(DBG_BATMAN, + "Originator timeout: originator %pM, last_valid %lu\n", + orig_node->orig, (orig_node->last_valid / HZ)); + return true; + } else { + if (purge_orig_neighbors(orig_node, &best_neigh_node)) + update_routes(orig_node, best_neigh_node, + orig_node->hna_buff, + orig_node->hna_buff_len); + } + return false; +} + +void purge_orig(struct work_struct *work) +{ + HASHIT(hashit); + struct orig_node *orig_node; + unsigned long flags; + + spin_lock_irqsave(&orig_hash_lock, flags); + + /* for all origins... */ + while (hash_iterate(orig_hash, &hashit)) { + orig_node = hashit.bucket->data; + if (purge_orig_node(orig_node)) { + hash_remove_bucket(orig_hash, &hashit); + free_orig_node(orig_node); + } + } + + spin_unlock_irqrestore(&orig_hash_lock, flags); + + start_purge_timer(); +} + + diff --git a/drivers/staging/batman-adv/log.h b/drivers/staging/batman-adv/originator.h index 780e3ab..6ef7a05 100644 --- a/drivers/staging/batman-adv/log.h +++ b/drivers/staging/batman-adv/originator.h @@ -19,14 +19,13 @@ * */ -extern const struct file_operations proc_log_operations; -extern uint8_t log_level; +int originator_init(void); +void free_orig_node(void *data); +void originator_free(void); +void purge_orig(struct work_struct *work); +struct orig_node *orig_find(char *mac); +struct orig_node *get_orig_node(uint8_t *addr); +struct neigh_node * +create_neighbor(struct orig_node *orig_node, struct orig_node *orig_neigh_node, + uint8_t *neigh, struct batman_if *if_incoming); -int debug_log(int type, char *fmt, ...); -int log_open(struct inode *inode, struct file *file); -int log_release(struct inode *inode, struct file *file); -ssize_t log_read(struct file *file, char __user *buf, size_t count, - loff_t *ppos); -ssize_t log_write(struct file *file, const char __user *buf, size_t count, - loff_t *ppos); -unsigned int log_poll(struct file *file, poll_table *wait); diff --git a/drivers/staging/batman-adv/packet.h b/drivers/staging/batman-adv/packet.h index 5627ca3..ad006ce 100644 --- a/drivers/staging/batman-adv/packet.h +++ b/drivers/staging/batman-adv/packet.h @@ -90,7 +90,7 @@ struct vis_packet { uint8_t entries; /* number of entries behind this struct */ uint8_t ttl; /* TTL */ uint8_t vis_orig[6]; /* originator that informs about its - * neighbours */ + * neighbors */ uint8_t target_orig[6]; /* who should receive this packet */ uint8_t sender_orig[6]; /* who sent or rebroadcasted this packet */ } __attribute__((packed)); diff --git a/drivers/staging/batman-adv/proc.c b/drivers/staging/batman-adv/proc.c index aac3df7..7de60e84 100644 --- a/drivers/staging/batman-adv/proc.c +++ b/drivers/staging/batman-adv/proc.c @@ -21,23 +21,18 @@ #include "main.h" #include "proc.h" -#include "log.h" #include "routing.h" #include "translation-table.h" #include "hard-interface.h" #include "types.h" #include "hash.h" #include "vis.h" -#include "compat.h" - -static uint8_t vis_format = DOT_DRAW; static struct proc_dir_entry *proc_batman_dir, *proc_interface_file; static struct proc_dir_entry *proc_orig_interval_file, *proc_originators_file; -static struct proc_dir_entry *proc_log_file, *proc_log_level_file; static struct proc_dir_entry *proc_transt_local_file; static struct proc_dir_entry *proc_transt_global_file; -static struct proc_dir_entry *proc_vis_file, *proc_vis_format_file; +static struct proc_dir_entry *proc_vis_srv_file, *proc_vis_data_file; static struct proc_dir_entry *proc_aggr_file; static int proc_interfaces_read(struct seq_file *seq, void *offset) @@ -68,7 +63,7 @@ static ssize_t proc_interfaces_write(struct file *instance, size_t count, loff_t *data) { char *if_string, *colon_ptr = NULL, *cr_ptr = NULL; - int not_copied = 0, if_num = 0; + int not_copied = 0, if_num = 0, add_success; struct batman_if *batman_if = NULL; if_string = kmalloc(count, GFP_KERNEL); @@ -77,8 +72,7 @@ static ssize_t proc_interfaces_write(struct file *instance, return -ENOMEM; if (count > IFNAMSIZ - 1) { - debug_log(LOG_TYPE_WARN, - "Can't add interface: device name is too long\n"); + printk(KERN_WARNING "batman-adv:Can't add interface: device name is too long\n"); goto end; } @@ -105,7 +99,7 @@ static ssize_t proc_interfaces_write(struct file *instance, rcu_read_lock(); list_for_each_entry_rcu(batman_if, &if_list, list) { if (strncmp(batman_if->dev, if_string, count) == 0) { - debug_log(LOG_TYPE_WARN, "Given interface is already active: %s\n", if_string); + printk(KERN_ERR "batman-adv:Given interface is already active: %s\n", if_string); rcu_read_unlock(); goto end; @@ -115,22 +109,17 @@ static ssize_t proc_interfaces_write(struct file *instance, } rcu_read_unlock(); - hardif_add_interface(if_string, if_num); + add_success = hardif_add_interface(if_string, if_num); + if (add_success < 0) + goto end; + + num_ifs = if_num + 1; if ((atomic_read(&module_state) == MODULE_INACTIVE) && (hardif_get_active_if_num() > 0)) activate_module(); - rcu_read_lock(); - if (list_empty(&if_list)) { - rcu_read_unlock(); - goto end; - } - rcu_read_unlock(); - - num_ifs = if_num + 1; return count; - end: kfree(if_string); return count; @@ -162,20 +151,18 @@ static ssize_t proc_orig_interval_write(struct file *file, retval = strict_strtoul(interval_string, 10, &originator_interval_tmp); if (retval) { - debug_log(LOG_TYPE_WARN, "New originator interval invalid\n"); + printk(KERN_ERR "batman-adv:New originator interval invalid\n"); goto end; } if (originator_interval_tmp <= JITTER * 2) { - debug_log(LOG_TYPE_WARN, - "New originator interval too small: %i (min: %i)\n", - originator_interval_tmp, JITTER * 2); + printk(KERN_WARNING "batman-adv:New originator interval too small: %li (min: %i)\n", + originator_interval_tmp, JITTER * 2); goto end; } - debug_log(LOG_TYPE_NOTICE, - "Changing originator interval from: %i to: %i\n", - atomic_read(&originator_interval), originator_interval_tmp); + printk(KERN_INFO "batman-adv:Changing originator interval from: %i to: %li\n", + atomic_read(&originator_interval), originator_interval_tmp); atomic_set(&originator_interval, originator_interval_tmp); @@ -191,11 +178,12 @@ static int proc_orig_interval_open(struct inode *inode, struct file *file) static int proc_originators_read(struct seq_file *seq, void *offset) { - struct hash_it_t *hashit = NULL; + HASHIT(hashit); struct orig_node *orig_node; struct neigh_node *neigh_node; int batman_count = 0; char orig_str[ETH_STR_LEN], router_str[ETH_STR_LEN]; + unsigned long flags; rcu_read_lock(); if (list_empty(&if_list)) { @@ -218,11 +206,11 @@ static int proc_originators_read(struct seq_file *seq, void *offset) ((struct batman_if *)if_list.next)->addr_str); rcu_read_unlock(); - spin_lock(&orig_hash_lock); + spin_lock_irqsave(&orig_hash_lock, flags); - while (NULL != (hashit = hash_iterate(orig_hash, hashit))) { + while (hash_iterate(orig_hash, &hashit)) { - orig_node = hashit->bucket->data; + orig_node = hashit.bucket->data; if (!orig_node->router) continue; @@ -249,7 +237,7 @@ static int proc_originators_read(struct seq_file *seq, void *offset) } - spin_unlock(&orig_hash_lock); + spin_unlock_irqrestore(&orig_hash_lock, flags); if (batman_count == 0) seq_printf(seq, "No batman nodes in range ... \n"); @@ -263,84 +251,6 @@ static int proc_originators_open(struct inode *inode, struct file *file) return single_open(file, proc_originators_read, NULL); } -static int proc_log_level_read(struct seq_file *seq, void *offset) -{ - - seq_printf(seq, "[x] %s (%d)\n", LOG_TYPE_CRIT_NAME, LOG_TYPE_CRIT); - seq_printf(seq, "[%c] %s (%d)\n", - (LOG_TYPE_WARN & log_level) ? 'x' : ' ', - LOG_TYPE_WARN_NAME, LOG_TYPE_WARN); - seq_printf(seq, "[%c] %s (%d)\n", - (LOG_TYPE_NOTICE & log_level) ? 'x' : ' ', - LOG_TYPE_NOTICE_NAME, LOG_TYPE_NOTICE); - seq_printf(seq, "[%c] %s (%d)\n", - (LOG_TYPE_BATMAN & log_level) ? 'x' : ' ', - LOG_TYPE_BATMAN_NAME, LOG_TYPE_BATMAN); - seq_printf(seq, "[%c] %s (%d)\n", - (LOG_TYPE_ROUTES & log_level) ? 'x' : ' ', - LOG_TYPE_ROUTES_NAME, LOG_TYPE_ROUTES); - return 0; -} - -static int proc_log_level_open(struct inode *inode, struct file *file) -{ - return single_open(file, proc_log_level_read, NULL); -} - -static ssize_t proc_log_level_write(struct file *instance, - const char __user *userbuffer, - size_t count, loff_t *data) -{ - char *log_level_string, *tokptr, *cp; - int finished, not_copied = 0; - unsigned long log_level_tmp = 0; - - log_level_string = kmalloc(count, GFP_KERNEL); - - if (!log_level_string) - return -ENOMEM; - - not_copied = copy_from_user(log_level_string, userbuffer, count); - log_level_string[count - not_copied - 1] = 0; - - if (strict_strtoul(log_level_string, 10, &log_level_tmp) < 0) { - /* was not a number, doing textual parsing */ - log_level_tmp = 0; - tokptr = log_level_string; - - for (cp = log_level_string, finished = 0; !finished; cp++) { - switch (*cp) { - case 0: - finished = 1; - case ' ': - case '\n': - case '\t': - *cp = 0; - /* compare */ - if (strcmp(tokptr, LOG_TYPE_WARN_NAME) == 0) - log_level_tmp |= LOG_TYPE_WARN; - if (strcmp(tokptr, LOG_TYPE_NOTICE_NAME) == 0) - log_level_tmp |= LOG_TYPE_NOTICE; - if (strcmp(tokptr, LOG_TYPE_BATMAN_NAME) == 0) - log_level_tmp |= LOG_TYPE_BATMAN; - if (strcmp(tokptr, LOG_TYPE_ROUTES_NAME) == 0) - log_level_tmp |= LOG_TYPE_ROUTES; - tokptr = cp + 1; - break; - default: - ; - } - } - } - - debug_log(LOG_TYPE_CRIT, "Changing log_level from: %i to: %i\n", - log_level, log_level_tmp); - log_level = log_level_tmp; - - kfree(log_level_string); - return count; -} - static int proc_transt_local_read(struct seq_file *seq, void *offset) { char *buf; @@ -405,172 +315,8 @@ static int proc_transt_global_open(struct inode *inode, struct file *file) return single_open(file, proc_transt_global_read, NULL); } -/* insert interface to the list of interfaces of one originator */ - -static void proc_vis_insert_interface(const uint8_t *interface, - struct vis_if_list **if_entry, - bool primary) -{ - /* Did we get an empty list? (then insert imediately) */ - if(*if_entry == NULL) { - *if_entry = kmalloc(sizeof(struct vis_if_list), GFP_KERNEL); - if (*if_entry == NULL) - return; - - (*if_entry)->primary = primary; - (*if_entry)->next = NULL; - memcpy((*if_entry)->addr, interface, ETH_ALEN); - } else { - struct vis_if_list *head_if_entry = *if_entry; - /* Do we already have this interface in our list? */ - while (!compare_orig((*if_entry)->addr, (void *)interface)) { - - /* Or did we reach the end (then append the interface) */ - if ((*if_entry)->next == NULL) { - (*if_entry)->next = kmalloc(sizeof(struct vis_if_list), GFP_KERNEL); - if ((*if_entry)->next == NULL) - return; - - memcpy((*if_entry)->next->addr, interface, ETH_ALEN); - (*if_entry)->next->primary = primary; - (*if_entry)->next->next = NULL; - break; - } - *if_entry = (*if_entry)->next; - } - /* Rewind the list to its head */ - *if_entry = head_if_entry; - } -} -/* read an entry */ - -static void proc_vis_read_entry(struct seq_file *seq, - struct vis_info_entry *entry, - struct vis_if_list **if_entry, - uint8_t *vis_orig, - uint8_t current_format, - uint8_t first_line) -{ - char from[40]; - char to[40]; - int int_part, frac_part; - - addr_to_string(to, entry->dest); - if (entry->quality == 0) { -#ifndef VIS_SUBCLUSTERS_DISABLED - proc_vis_insert_interface(vis_orig, if_entry, true); -#endif /* VIS_SUBCLUSTERS_DISABLED */ - addr_to_string(from, vis_orig); - if (current_format == DOT_DRAW) { - seq_printf(seq, "\t\"%s\" -> \"%s\" [label=\"HNA\"]\n", - from, to); - } else { - seq_printf(seq, - "%s\t{ router : \"%s\", gateway : \"%s\", label : \"HNA\" }", - (first_line ? "" : ",\n"), from, to); - } - } else { -#ifndef VIS_SUBCLUSTERS_DISABLED - proc_vis_insert_interface(entry->src, if_entry, compare_orig(entry->src, vis_orig)); -#endif /* VIS_SUBCLUSTERS_DISABLED */ - addr_to_string(from, entry->src); - - /* kernel has no printf-support for %f? it'd be better to return - * this in float. */ - - int_part = TQ_MAX_VALUE / entry->quality; - frac_part = 1000 * TQ_MAX_VALUE / entry->quality - int_part * 1000; - - if (current_format == DOT_DRAW) { - seq_printf(seq, - "\t\"%s\" -> \"%s\" [label=\"%d.%d\"]\n", - from, to, int_part, frac_part); - } else { - seq_printf(seq, - "%s\t{ router : \"%s\", neighbour : \"%s\", label : %d.%d }", - (first_line ? "" : ",\n"), from, to, int_part, frac_part); - } - } -} - - -static int proc_vis_read(struct seq_file *seq, void *offset) -{ - struct hash_it_t *hashit = NULL; - struct vis_info *info; - struct vis_info_entry *entries; - struct vis_if_list *if_entries = NULL; - int i; - uint8_t current_format, first_line = 1; -#ifndef VIS_SUBCLUSTERS_DISABLED - char tmp_addr_str[ETH_STR_LEN]; - struct vis_if_list *tmp_if_next; -#endif /* VIS_SUBCLUSTERS_DISABLED */ - - current_format = vis_format; - - rcu_read_lock(); - if (list_empty(&if_list) || (!is_vis_server())) { - rcu_read_unlock(); - if (current_format == DOT_DRAW) - seq_printf(seq, "digraph {\n}\n"); - goto end; - } - - rcu_read_unlock(); - - if (current_format == DOT_DRAW) - seq_printf(seq, "digraph {\n"); - - spin_lock(&vis_hash_lock); - while (NULL != (hashit = hash_iterate(vis_hash, hashit))) { - info = hashit->bucket->data; - entries = (struct vis_info_entry *) - ((char *)info + sizeof(struct vis_info)); - - for (i = 0; i < info->packet.entries; i++) { - proc_vis_read_entry(seq, &entries[i], &if_entries, - info->packet.vis_orig, - current_format, first_line); - if (first_line) - first_line = 0; - } - -#ifndef VIS_SUBCLUSTERS_DISABLED - /* Generate subgraphs from the collected items */ - if (current_format == DOT_DRAW) { - - addr_to_string(tmp_addr_str, info->packet.vis_orig); - seq_printf(seq, "\tsubgraph \"cluster_%s\" {\n", tmp_addr_str); - while (if_entries != NULL) { - - addr_to_string(tmp_addr_str, if_entries->addr); - if (if_entries->primary) - seq_printf(seq, "\t\t\"%s\" [peripheries=2]\n", tmp_addr_str); - else - seq_printf(seq, "\t\t\"%s\"\n", tmp_addr_str); - - /* ... and empty the list while doing this */ - tmp_if_next = if_entries->next; - kfree(if_entries); - if_entries = tmp_if_next; - } - seq_printf(seq, "\t}\n"); - } -#endif /* VIS_SUBCLUSTERS_DISABLED */ - } - spin_unlock(&vis_hash_lock); - - if (current_format == DOT_DRAW) - seq_printf(seq, "}\n"); - else - seq_printf(seq, "\n"); -end: - return 0; -} - /* setting the mode of the vis server by the user */ -static ssize_t proc_vis_write(struct file *file, const char __user * buffer, +static ssize_t proc_vis_srv_write(struct file *file, const char __user * buffer, size_t count, loff_t *ppos) { char *vis_mode_string; @@ -584,72 +330,84 @@ static ssize_t proc_vis_write(struct file *file, const char __user * buffer, not_copied = copy_from_user(vis_mode_string, buffer, count); vis_mode_string[count - not_copied - 1] = 0; - if (strcmp(vis_mode_string, "client") == 0) { - debug_log(LOG_TYPE_NOTICE, "Setting VIS mode to client\n"); - vis_set_mode(VIS_TYPE_CLIENT_UPDATE); - } else if (strcmp(vis_mode_string, "server") == 0) { - debug_log(LOG_TYPE_NOTICE, "Setting VIS mode to server\n"); - vis_set_mode(VIS_TYPE_SERVER_SYNC); + if ((strcmp(vis_mode_string, "client") == 0) || + (strcmp(vis_mode_string, "disabled") == 0)) { + printk(KERN_INFO "batman-adv:Setting VIS mode to client (disabling vis server)\n"); + atomic_set(&vis_mode, VIS_TYPE_CLIENT_UPDATE); + } else if ((strcmp(vis_mode_string, "server") == 0) || + (strcmp(vis_mode_string, "enabled") == 0)) { + printk(KERN_INFO "batman-adv:Setting VIS mode to server (enabling vis server)\n"); + atomic_set(&vis_mode, VIS_TYPE_SERVER_SYNC); } else - debug_log(LOG_TYPE_WARN, "Unknown VIS mode: %s\n", - vis_mode_string); + printk(KERN_ERR "batman-adv:Unknown VIS mode: %s\n", + vis_mode_string); kfree(vis_mode_string); return count; } -static int proc_vis_open(struct inode *inode, struct file *file) +static int proc_vis_srv_read(struct seq_file *seq, void *offset) { - return single_open(file, proc_vis_read, NULL); -} + int vis_server = atomic_read(&vis_mode); + + seq_printf(seq, "[%c] client mode (server disabled) \n", + (vis_server == VIS_TYPE_CLIENT_UPDATE) ? 'x' : ' '); + seq_printf(seq, "[%c] server mode (server enabled) \n", + (vis_server == VIS_TYPE_SERVER_SYNC) ? 'x' : ' '); -static int proc_vis_format_read(struct seq_file *seq, void *offset) -{ - uint8_t current_format = vis_format; - - seq_printf(seq, "[%c] %s\n", - (current_format == DOT_DRAW) ? 'x' : ' ', - VIS_FORMAT_DD_NAME); - seq_printf(seq, "[%c] %s\n", - (current_format == JSON) ? 'x' : ' ', - VIS_FORMAT_JSON_NAME); return 0; } -static int proc_vis_format_open(struct inode *inode, struct file *file) +static int proc_vis_srv_open(struct inode *inode, struct file *file) { - return single_open(file, proc_vis_format_read, NULL); + return single_open(file, proc_vis_srv_read, NULL); } -static ssize_t proc_vis_format_write(struct file *file, - const char __user *buffer, - size_t count, loff_t *ppos) +static int proc_vis_data_read(struct seq_file *seq, void *offset) { - char *vis_format_string; - int not_copied = 0; + HASHIT(hashit); + struct vis_info *info; + struct vis_info_entry *entries; + HLIST_HEAD(vis_if_list); + int i; + char tmp_addr_str[ETH_STR_LEN]; + unsigned long flags; + int vis_server = atomic_read(&vis_mode); + + rcu_read_lock(); + if (list_empty(&if_list) || (vis_server == VIS_TYPE_CLIENT_UPDATE)) { + rcu_read_unlock(); + goto end; + } - vis_format_string = kmalloc(count, GFP_KERNEL); + rcu_read_unlock(); - if (!vis_format_string) - return -ENOMEM; + spin_lock_irqsave(&vis_hash_lock, flags); + while (hash_iterate(vis_hash, &hashit)) { + info = hashit.bucket->data; + entries = (struct vis_info_entry *) + ((char *)info + sizeof(struct vis_info)); + addr_to_string(tmp_addr_str, info->packet.vis_orig); + seq_printf(seq, "%s,", tmp_addr_str); - not_copied = copy_from_user(vis_format_string, buffer, count); - vis_format_string[count - not_copied - 1] = 0; - - if (strcmp(vis_format_string, VIS_FORMAT_DD_NAME) == 0) { - debug_log(LOG_TYPE_NOTICE, "Setting VIS output format to: %s\n", - VIS_FORMAT_DD_NAME); - vis_format = DOT_DRAW; - } else if (strcmp(vis_format_string, VIS_FORMAT_JSON_NAME) == 0) { - debug_log(LOG_TYPE_NOTICE, "Setting VIS output format to: %s\n", - VIS_FORMAT_JSON_NAME); - vis_format = JSON; - } else - debug_log(LOG_TYPE_WARN, "Unknown VIS output format: %s\n", - vis_format_string); + for (i = 0; i < info->packet.entries; i++) { + proc_vis_read_entry(seq, &entries[i], &vis_if_list, + info->packet.vis_orig); + } - kfree(vis_format_string); - return count; + /* add primary/secondary records */ + proc_vis_read_prim_sec(seq, &vis_if_list); + seq_printf(seq, "\n"); + } + spin_unlock_irqrestore(&vis_hash_lock, flags); + +end: + return 0; +} + +static int proc_vis_data_open(struct inode *inode, struct file *file) +{ + return single_open(file, proc_vis_data_read, NULL); } static int proc_aggr_read(struct seq_file *seq, void *offset) @@ -665,6 +423,7 @@ static ssize_t proc_aggr_write(struct file *file, const char __user *buffer, char *aggr_string; int not_copied = 0; unsigned long aggregation_enabled_tmp; + int retval; aggr_string = kmalloc(count, GFP_KERNEL); @@ -674,22 +433,21 @@ static ssize_t proc_aggr_write(struct file *file, const char __user *buffer, not_copied = copy_from_user(aggr_string, buffer, count); aggr_string[count - not_copied - 1] = 0; - strict_strtoul(aggr_string, 10, &aggregation_enabled_tmp); + retval = strict_strtoul(aggr_string, 10, &aggregation_enabled_tmp); - if ((aggregation_enabled_tmp != 0) && (aggregation_enabled_tmp != 1)) { - debug_log(LOG_TYPE_WARN, "Aggregation can only be enabled (1) or disabled (0), given value: %li\n", aggregation_enabled_tmp); - goto end; + if (retval || aggregation_enabled_tmp > 1) { + printk(KERN_ERR "batman-adv:Aggregation can only be enabled (1) or disabled (0), given value: %li\n", aggregation_enabled_tmp); + } else { + printk(KERN_INFO "batman-adv:Changing aggregation from: %s (%i) to: %s (%li)\n", + (atomic_read(&aggregation_enabled) == 1 ? + "enabled" : "disabled"), + atomic_read(&aggregation_enabled), + (aggregation_enabled_tmp == 1 ? "enabled" : "disabled"), + aggregation_enabled_tmp); + atomic_set(&aggregation_enabled, + (unsigned)aggregation_enabled_tmp); } - debug_log(LOG_TYPE_NOTICE, "Changing aggregation from: %s (%i) to: %s (%li)\n", - (atomic_read(&aggregation_enabled) == 1 ? - "enabled" : "disabled"), - atomic_read(&aggregation_enabled), - (aggregation_enabled_tmp == 1 ? "enabled" : "disabled"), - aggregation_enabled_tmp); - - atomic_set(&aggregation_enabled, (unsigned)aggregation_enabled_tmp); -end: kfree(aggr_string); return count; } @@ -715,20 +473,20 @@ static const struct file_operations proc_aggr_fops = { .release = single_release, }; -static const struct file_operations proc_vis_format_fops = { +static const struct file_operations proc_vis_srv_fops = { .owner = THIS_MODULE, - .open = proc_vis_format_open, + .open = proc_vis_srv_open, .read = seq_read, - .write = proc_vis_format_write, + .write = proc_vis_srv_write, .llseek = seq_lseek, .release = single_release, }; -static const struct file_operations proc_vis_fops = { +static const struct file_operations proc_vis_data_fops = { .owner = THIS_MODULE, - .open = proc_vis_open, + .open = proc_vis_data_open, .read = seq_read, - .write = proc_vis_write, + .write = proc_dummy_write, .llseek = seq_lseek, .release = single_release, }; @@ -760,15 +518,6 @@ static const struct file_operations proc_transt_global_fops = { .release = single_release, }; -static const struct file_operations proc_log_level_fops = { - .owner = THIS_MODULE, - .open = proc_log_level_open, - .read = seq_read, - .write = proc_log_level_write, - .llseek = seq_lseek, - .release = single_release, -}; - static const struct file_operations proc_interfaces_fops = { .owner = THIS_MODULE, .open = proc_interfaces_open, @@ -795,12 +544,6 @@ void cleanup_procfs(void) if (proc_transt_local_file) remove_proc_entry(PROC_FILE_TRANST_LOCAL, proc_batman_dir); - if (proc_log_file) - remove_proc_entry(PROC_FILE_LOG, proc_batman_dir); - - if (proc_log_level_file) - remove_proc_entry(PROC_FILE_LOG_LEVEL, proc_batman_dir); - if (proc_originators_file) remove_proc_entry(PROC_FILE_ORIGINATORS, proc_batman_dir); @@ -810,11 +553,11 @@ void cleanup_procfs(void) if (proc_interface_file) remove_proc_entry(PROC_FILE_INTERFACES, proc_batman_dir); - if (proc_vis_file) - remove_proc_entry(PROC_FILE_VIS, proc_batman_dir); + if (proc_vis_data_file) + remove_proc_entry(PROC_FILE_VIS_DATA, proc_batman_dir); - if (proc_vis_format_file) - remove_proc_entry(PROC_FILE_VIS_FORMAT, proc_batman_dir); + if (proc_vis_srv_file) + remove_proc_entry(PROC_FILE_VIS_SRV, proc_batman_dir); if (proc_aggr_file) remove_proc_entry(PROC_FILE_AGGR, proc_batman_dir); @@ -862,17 +605,6 @@ int setup_procfs(void) return -EFAULT; } - proc_log_level_file = create_proc_entry(PROC_FILE_LOG_LEVEL, - S_IWUSR | S_IRUGO, - proc_batman_dir); - if (proc_log_level_file) { - proc_log_level_file->proc_fops = &proc_log_level_fops; - } else { - printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_LOG_LEVEL); - cleanup_procfs(); - return -EFAULT; - } - proc_originators_file = create_proc_entry(PROC_FILE_ORIGINATORS, S_IRUGO, proc_batman_dir); if (proc_originators_file) { @@ -883,16 +615,6 @@ int setup_procfs(void) return -EFAULT; } - proc_log_file = create_proc_entry(PROC_FILE_LOG, - S_IRUGO, proc_batman_dir); - if (proc_log_file) { - proc_log_file->proc_fops = &proc_log_operations; - } else { - printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_FILE_LOG, PROC_FILE_GATEWAYS); - cleanup_procfs(); - return -EFAULT; - } - proc_transt_local_file = create_proc_entry(PROC_FILE_TRANST_LOCAL, S_IRUGO, proc_batman_dir); if (proc_transt_local_file) { @@ -913,23 +635,23 @@ int setup_procfs(void) return -EFAULT; } - proc_vis_file = create_proc_entry(PROC_FILE_VIS, S_IWUSR | S_IRUGO, - proc_batman_dir); - if (proc_vis_file) { - proc_vis_file->proc_fops = &proc_vis_fops; + proc_vis_srv_file = create_proc_entry(PROC_FILE_VIS_SRV, + S_IWUSR | S_IRUGO, + proc_batman_dir); + if (proc_vis_srv_file) { + proc_vis_srv_file->proc_fops = &proc_vis_srv_fops; } else { - printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_VIS); + printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_VIS_SRV); cleanup_procfs(); return -EFAULT; } - proc_vis_format_file = create_proc_entry(PROC_FILE_VIS_FORMAT, - S_IWUSR | S_IRUGO, - proc_batman_dir); - if (proc_vis_format_file) { - proc_vis_format_file->proc_fops = &proc_vis_format_fops; + proc_vis_data_file = create_proc_entry(PROC_FILE_VIS_DATA, S_IRUGO, + proc_batman_dir); + if (proc_vis_data_file) { + proc_vis_data_file->proc_fops = &proc_vis_data_fops; } else { - printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_VIS_FORMAT); + printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_VIS_DATA); cleanup_procfs(); return -EFAULT; } @@ -946,5 +668,3 @@ int setup_procfs(void) return 0; } - - diff --git a/drivers/staging/batman-adv/proc.h b/drivers/staging/batman-adv/proc.h index 16d3efd..cd690e0 100644 --- a/drivers/staging/batman-adv/proc.h +++ b/drivers/staging/batman-adv/proc.h @@ -31,19 +31,10 @@ #define PROC_FILE_LOG_LEVEL "log_level" #define PROC_FILE_TRANST_LOCAL "transtable_local" #define PROC_FILE_TRANST_GLOBAL "transtable_global" -#define PROC_FILE_VIS "vis" -#define PROC_FILE_VIS_FORMAT "vis_format" +#define PROC_FILE_VIS_SRV "vis_server" +#define PROC_FILE_VIS_DATA "vis_data" #define PROC_FILE_AGGR "aggregate_ogm" void cleanup_procfs(void); int setup_procfs(void); -/* While scanning for vis-entries of a particular vis-originator - * this list collects its interfaces to create a subgraph/cluster - * out of them later - */ -struct vis_if_list { - uint8_t addr[ETH_ALEN]; - bool primary; - struct vis_if_list *next; -}; diff --git a/drivers/staging/batman-adv/routing.c b/drivers/staging/batman-adv/routing.c index 4a14c36..d89048b 100644 --- a/drivers/staging/batman-adv/routing.c +++ b/drivers/staging/batman-adv/routing.c @@ -19,304 +19,226 @@ * */ - - - - #include "main.h" #include "routing.h" -#include "log.h" #include "send.h" +#include "hash.h" #include "soft-interface.h" #include "hard-interface.h" #include "device.h" #include "translation-table.h" +#include "originator.h" #include "types.h" -#include "hash.h" #include "ring_buffer.h" #include "vis.h" #include "aggregation.h" -#include "compat.h" - - DECLARE_WAIT_QUEUE_HEAD(thread_wait); -static DECLARE_DELAYED_WORK(purge_orig_wq, purge_orig); - -static atomic_t data_ready_cond; -atomic_t exit_cond; - -static void start_purge_timer(void) -{ - queue_delayed_work(bat_event_workqueue, &purge_orig_wq, 1 * HZ); -} - -int originator_init(void) -{ - if (orig_hash) - return 1; - - spin_lock(&orig_hash_lock); - orig_hash = hash_new(128, compare_orig, choose_orig); - - if (!orig_hash) - goto err; - - spin_unlock(&orig_hash_lock); - start_purge_timer(); - return 1; - -err: - spin_unlock(&orig_hash_lock); - return 0; -} - -void originator_free(void) -{ - if (!orig_hash) - return; - - cancel_delayed_work_sync(&purge_orig_wq); - - spin_lock(&orig_hash_lock); - hash_delete(orig_hash, free_orig_node); - orig_hash = NULL; - spin_unlock(&orig_hash_lock); -} -static struct neigh_node *create_neighbor(struct orig_node *orig_node, struct orig_node *orig_neigh_node, uint8_t *neigh, struct batman_if *if_incoming) +void slide_own_bcast_window(struct batman_if *batman_if) { - struct neigh_node *neigh_node; + HASHIT(hashit); + struct orig_node *orig_node; + TYPE_OF_WORD *word; + unsigned long flags; - debug_log(LOG_TYPE_BATMAN, "Creating new last-hop neighbour of originator\n"); + spin_lock_irqsave(&orig_hash_lock, flags); - neigh_node = kmalloc(sizeof(struct neigh_node), GFP_ATOMIC); - memset(neigh_node, 0, sizeof(struct neigh_node)); - INIT_LIST_HEAD(&neigh_node->list); + while (hash_iterate(orig_hash, &hashit)) { + orig_node = hashit.bucket->data; + word = &(orig_node->bcast_own[batman_if->if_num * NUM_WORDS]); - memcpy(neigh_node->addr, neigh, ETH_ALEN); - neigh_node->orig_node = orig_neigh_node; - neigh_node->if_incoming = if_incoming; + bit_get_packet(word, 1, 0); + orig_node->bcast_own_sum[batman_if->if_num] = + bit_packet_count(word); + } - list_add_tail(&neigh_node->list, &orig_node->neigh_list); - return neigh_node; + spin_unlock_irqrestore(&orig_hash_lock, flags); } -void free_orig_node(void *data) +static void update_HNA(struct orig_node *orig_node, + unsigned char *hna_buff, int hna_buff_len) { - struct list_head *list_pos, *list_pos_tmp; - struct neigh_node *neigh_node; - struct orig_node *orig_node = (struct orig_node *)data; + if ((hna_buff_len != orig_node->hna_buff_len) || + ((hna_buff_len > 0) && + (orig_node->hna_buff_len > 0) && + (memcmp(orig_node->hna_buff, hna_buff, hna_buff_len) != 0))) { - /* for all neighbours towards this originator ... */ - list_for_each_safe(list_pos, list_pos_tmp, &orig_node->neigh_list) { - neigh_node = list_entry(list_pos, struct neigh_node, list); + if (orig_node->hna_buff_len > 0) + hna_global_del_orig(orig_node, + "originator changed hna"); - list_del(list_pos); - kfree(neigh_node); + if ((hna_buff_len > 0) && (hna_buff != NULL)) + hna_global_add_orig(orig_node, hna_buff, hna_buff_len); } - - hna_global_del_orig(orig_node, "originator timed out"); - - kfree(orig_node->bcast_own); - kfree(orig_node->bcast_own_sum); - kfree(orig_node); } -/* this function finds or creates an originator entry for the given address if it does not exits */ -static struct orig_node *get_orig_node(uint8_t *addr) +static void update_route(struct orig_node *orig_node, + struct neigh_node *neigh_node, + unsigned char *hna_buff, int hna_buff_len) { - struct orig_node *orig_node; - struct hashtable_t *swaphash; - char orig_str[ETH_STR_LEN]; - - orig_node = ((struct orig_node *)hash_find(orig_hash, addr)); - - if (orig_node != NULL) - return orig_node; - - addr_to_string(orig_str, addr); - debug_log(LOG_TYPE_BATMAN, "Creating new originator: %s \n", orig_str); - - orig_node = kmalloc(sizeof(struct orig_node), GFP_ATOMIC); - memset(orig_node, 0, sizeof(struct orig_node)); - INIT_LIST_HEAD(&orig_node->neigh_list); - - memcpy(orig_node->orig, addr, ETH_ALEN); - orig_node->router = NULL; - orig_node->batman_if = NULL; - orig_node->hna_buff = NULL; + /* route deleted */ + if ((orig_node->router != NULL) && (neigh_node == NULL)) { - orig_node->bcast_own = kmalloc(num_ifs * sizeof(TYPE_OF_WORD) * NUM_WORDS, GFP_ATOMIC); - memset(orig_node->bcast_own, 0, num_ifs * sizeof(TYPE_OF_WORD) * NUM_WORDS); + bat_dbg(DBG_ROUTES, "Deleting route towards: %pM\n", + orig_node->orig); + hna_global_del_orig(orig_node, "originator timed out"); - orig_node->bcast_own_sum = kmalloc(num_ifs * sizeof(uint8_t), GFP_ATOMIC); - memset(orig_node->bcast_own_sum, 0, num_ifs * sizeof(uint8_t)); - - hash_add(orig_hash, orig_node); + /* route added */ + } else if ((orig_node->router == NULL) && (neigh_node != NULL)) { - if (orig_hash->elements * 4 > orig_hash->size) { - swaphash = hash_resize(orig_hash, orig_hash->size * 2); + bat_dbg(DBG_ROUTES, + "Adding route towards: %pM (via %pM)\n", + orig_node->orig, neigh_node->addr); + hna_global_add_orig(orig_node, hna_buff, hna_buff_len); - if (swaphash == NULL) - debug_log(LOG_TYPE_CRIT, "Couldn't resize orig hash table \n"); - else - orig_hash = swaphash; + /* route changed */ + } else { + bat_dbg(DBG_ROUTES, "Changing route towards: %pM (now via %pM - was via %pM)\n", orig_node->orig, neigh_node->addr, orig_node->router->addr); } - return orig_node; -} - -void slide_own_bcast_window(struct batman_if *batman_if) -{ - struct hash_it_t *hashit = NULL; - struct orig_node *orig_node; - - spin_lock(&orig_hash_lock); - - while (NULL != (hashit = hash_iterate(orig_hash, hashit))) { - orig_node = hashit->bucket->data; - - bit_get_packet((TYPE_OF_WORD *)&(orig_node->bcast_own[batman_if->if_num * NUM_WORDS]), 1, 0); - orig_node->bcast_own_sum[batman_if->if_num] = bit_packet_count((TYPE_OF_WORD *)&(orig_node->bcast_own[batman_if->if_num * NUM_WORDS])); - } + if (neigh_node != NULL) + orig_node->batman_if = neigh_node->if_incoming; + else + orig_node->batman_if = NULL; - spin_unlock(&orig_hash_lock); + orig_node->router = neigh_node; } -static void update_routes(struct orig_node *orig_node, struct neigh_node *neigh_node, unsigned char *hna_buff, int hna_buff_len) + +void update_routes(struct orig_node *orig_node, + struct neigh_node *neigh_node, + unsigned char *hna_buff, int hna_buff_len) { - char orig_str[ETH_STR_LEN], neigh_str[ETH_STR_LEN], router_str[ETH_STR_LEN]; if (orig_node == NULL) return; - if (orig_node->router != neigh_node) { - addr_to_string(orig_str, orig_node->orig); - - /* route deleted */ - if ((orig_node->router != NULL) && (neigh_node == NULL)) { - - debug_log(LOG_TYPE_ROUTES, "Deleting route towards: %s\n", orig_str); - hna_global_del_orig(orig_node, "originator timed out"); - - /* route added */ - } else if ((orig_node->router == NULL) && (neigh_node != NULL)) { - - addr_to_string(neigh_str, neigh_node->addr); - debug_log(LOG_TYPE_ROUTES, "Adding route towards: %s (via %s)\n", orig_str, neigh_str); - hna_global_add_orig(orig_node, hna_buff, hna_buff_len); - - /* route changed */ - } else { - - addr_to_string(neigh_str, neigh_node->addr); - addr_to_string(router_str, orig_node->router->addr); - debug_log(LOG_TYPE_ROUTES, "Changing route towards: %s (now via %s - was via %s)\n", orig_str, neigh_str, router_str); - - } - - if (neigh_node != NULL) - orig_node->batman_if = neigh_node->if_incoming; - else - orig_node->batman_if = NULL; - - orig_node->router = neigh_node; - + if (orig_node->router != neigh_node) + update_route(orig_node, neigh_node, hna_buff, hna_buff_len); /* may be just HNA changed */ - } else { - - if ((hna_buff_len != orig_node->hna_buff_len) || ((hna_buff_len > 0) && (orig_node->hna_buff_len > 0) && (memcmp(orig_node->hna_buff, hna_buff, hna_buff_len) != 0))) { - - if (orig_node->hna_buff_len > 0) - hna_global_del_orig(orig_node, "originator changed hna"); - - if ((hna_buff_len > 0) && (hna_buff != NULL)) - hna_global_add_orig(orig_node, hna_buff, hna_buff_len); - - } - - } + else + update_HNA(orig_node, hna_buff, hna_buff_len); } -static int isBidirectionalNeigh(struct orig_node *orig_node, struct orig_node *orig_neigh_node, struct batman_packet *batman_packet, struct batman_if *if_incoming) +static int isBidirectionalNeigh(struct orig_node *orig_node, + struct orig_node *orig_neigh_node, + struct batman_packet *batman_packet, + struct batman_if *if_incoming) { struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL; - char orig_str[ETH_STR_LEN], neigh_str[ETH_STR_LEN]; unsigned char total_count; - addr_to_string(orig_str, orig_node->orig); - addr_to_string(neigh_str, orig_neigh_node->orig); - if (orig_node == orig_neigh_node) { - list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) { + list_for_each_entry(tmp_neigh_node, + &orig_node->neigh_list, + list) { - if (compare_orig(tmp_neigh_node->addr, orig_neigh_node->orig) && (tmp_neigh_node->if_incoming == if_incoming)) + if (compare_orig(tmp_neigh_node->addr, + orig_neigh_node->orig) && + (tmp_neigh_node->if_incoming == if_incoming)) neigh_node = tmp_neigh_node; } - if (neigh_node == NULL) - neigh_node = create_neighbor(orig_node, orig_neigh_node, orig_neigh_node->orig, if_incoming); + if (!neigh_node) + neigh_node = create_neighbor(orig_node, + orig_neigh_node, + orig_neigh_node->orig, + if_incoming); + /* create_neighbor failed, return 0 */ + if (!neigh_node) + return 0; neigh_node->last_valid = jiffies; } else { /* find packet count of corresponding one hop neighbor */ - list_for_each_entry(tmp_neigh_node, &orig_neigh_node->neigh_list, list) { + list_for_each_entry(tmp_neigh_node, + &orig_neigh_node->neigh_list, list) { - if (compare_orig(tmp_neigh_node->addr, orig_neigh_node->orig) && (tmp_neigh_node->if_incoming == if_incoming)) + if (compare_orig(tmp_neigh_node->addr, + orig_neigh_node->orig) && + (tmp_neigh_node->if_incoming == if_incoming)) neigh_node = tmp_neigh_node; } - if (neigh_node == NULL) - neigh_node = create_neighbor(orig_neigh_node, orig_neigh_node, orig_neigh_node->orig, if_incoming); + if (!neigh_node) + neigh_node = create_neighbor(orig_neigh_node, + orig_neigh_node, + orig_neigh_node->orig, + if_incoming); + /* create_neighbor failed, return 0 */ + if (!neigh_node) + return 0; } orig_node->last_valid = jiffies; /* pay attention to not get a value bigger than 100 % */ - total_count = (orig_neigh_node->bcast_own_sum[if_incoming->if_num] > neigh_node->real_packet_count ? neigh_node->real_packet_count : orig_neigh_node->bcast_own_sum[if_incoming->if_num]); + total_count = (orig_neigh_node->bcast_own_sum[if_incoming->if_num] > + neigh_node->real_packet_count ? + neigh_node->real_packet_count : + orig_neigh_node->bcast_own_sum[if_incoming->if_num]); /* if we have too few packets (too less data) we set tq_own to zero */ /* if we receive too few packets it is not considered bidirectional */ - if ((total_count < TQ_LOCAL_BIDRECT_SEND_MINIMUM) || (neigh_node->real_packet_count < TQ_LOCAL_BIDRECT_RECV_MINIMUM)) + if ((total_count < TQ_LOCAL_BIDRECT_SEND_MINIMUM) || + (neigh_node->real_packet_count < TQ_LOCAL_BIDRECT_RECV_MINIMUM)) orig_neigh_node->tq_own = 0; else - /* neigh_node->real_packet_count is never zero as we only purge old information when getting new information */ - orig_neigh_node->tq_own = (TQ_MAX_VALUE * total_count) / neigh_node->real_packet_count; + /* neigh_node->real_packet_count is never zero as we + * only purge old information when getting new + * information */ + orig_neigh_node->tq_own = (TQ_MAX_VALUE * total_count) / + neigh_node->real_packet_count; /* - * 1 - ((1-x) ** 3), normalized to TQ_MAX_VALUE - * this does affect the nearly-symmetric links only a little, - * but punishes asymmetric links more. - * this will give a value between 0 and TQ_MAX_VALUE + * 1 - ((1-x) ** 3), normalized to TQ_MAX_VALUE this does + * affect the nearly-symmetric links only a little, but + * punishes asymmetric links more. This will give a value + * between 0 and TQ_MAX_VALUE */ - orig_neigh_node->tq_asym_penalty = TQ_MAX_VALUE - (TQ_MAX_VALUE * - (TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count) * - (TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count) * - (TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count)) / - (TQ_LOCAL_WINDOW_SIZE * TQ_LOCAL_WINDOW_SIZE * TQ_LOCAL_WINDOW_SIZE); - - batman_packet->tq = ((batman_packet->tq * orig_neigh_node->tq_own * orig_neigh_node->tq_asym_penalty) / (TQ_MAX_VALUE * TQ_MAX_VALUE)); - - debug_log(LOG_TYPE_BATMAN, "bidirectional: orig = %-15s neigh = %-15s => own_bcast = %2i, real recv = %2i, local tq: %3i, asym_penalty: %3i, total tq: %3i \n", - orig_str, neigh_str, total_count, neigh_node->real_packet_count, orig_neigh_node->tq_own, orig_neigh_node->tq_asym_penalty, batman_packet->tq); - - /* if link has the minimum required transmission quality consider it bidirectional */ + orig_neigh_node->tq_asym_penalty = + TQ_MAX_VALUE - + (TQ_MAX_VALUE * + (TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count) * + (TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count) * + (TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count)) / + (TQ_LOCAL_WINDOW_SIZE * + TQ_LOCAL_WINDOW_SIZE * + TQ_LOCAL_WINDOW_SIZE); + + batman_packet->tq = ((batman_packet->tq * + orig_neigh_node->tq_own * + orig_neigh_node->tq_asym_penalty) / + (TQ_MAX_VALUE * TQ_MAX_VALUE)); + + bat_dbg(DBG_BATMAN, "bidirectional: orig = %-15pM neigh = %-15pM => own_bcast = %2i, real recv = %2i, local tq: %3i, asym_penalty: %3i, total tq: %3i \n", + orig_node->orig, orig_neigh_node->orig, total_count, + neigh_node->real_packet_count, orig_neigh_node->tq_own, + orig_neigh_node->tq_asym_penalty, batman_packet->tq); + + /* if link has the minimum required transmission quality + * consider it bidirectional */ if (batman_packet->tq >= TQ_TOTAL_BIDRECT_LIMIT) return 1; return 0; } -static void update_orig(struct orig_node *orig_node, struct ethhdr *ethhdr, struct batman_packet *batman_packet, struct batman_if *if_incoming, unsigned char *hna_buff, int hna_buff_len, char is_duplicate) +static void update_orig(struct orig_node *orig_node, struct ethhdr *ethhdr, + struct batman_packet *batman_packet, + struct batman_if *if_incoming, + unsigned char *hna_buff, int hna_buff_len, + char is_duplicate) { struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL; int tmp_hna_buff_len; - debug_log(LOG_TYPE_BATMAN, "update_originator(): Searching and updating originator entry of received packet \n"); + bat_dbg(DBG_BATMAN, "update_originator(): Searching and updating originator entry of received packet \n"); list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) { - if (compare_orig(tmp_neigh_node->addr, ethhdr->h_source) && (tmp_neigh_node->if_incoming == if_incoming)) { + if (compare_orig(tmp_neigh_node->addr, ethhdr->h_source) && + (tmp_neigh_node->if_incoming == if_incoming)) { neigh_node = tmp_neigh_node; continue; } @@ -324,19 +246,34 @@ static void update_orig(struct orig_node *orig_node, struct ethhdr *ethhdr, stru if (is_duplicate) continue; - ring_buffer_set(tmp_neigh_node->tq_recv, &tmp_neigh_node->tq_index, 0); - tmp_neigh_node->tq_avg = ring_buffer_avg(tmp_neigh_node->tq_recv); + ring_buffer_set(tmp_neigh_node->tq_recv, + &tmp_neigh_node->tq_index, 0); + tmp_neigh_node->tq_avg = + ring_buffer_avg(tmp_neigh_node->tq_recv); } - if (neigh_node == NULL) - neigh_node = create_neighbor(orig_node, get_orig_node(ethhdr->h_source), ethhdr->h_source, if_incoming); - else - debug_log(LOG_TYPE_BATMAN, "Updating existing last-hop neighbour of originator\n"); + if (!neigh_node) { + struct orig_node *orig_tmp; + + orig_tmp = get_orig_node(ethhdr->h_source); + if (!orig_tmp) + return; + + neigh_node = create_neighbor(orig_node, + orig_tmp, + ethhdr->h_source, if_incoming); + if (!neigh_node) + return; + } else + bat_dbg(DBG_BATMAN, + "Updating existing last-hop neighbor of originator\n"); orig_node->flags = batman_packet->flags; neigh_node->last_valid = jiffies; - ring_buffer_set(neigh_node->tq_recv, &neigh_node->tq_index, batman_packet->tq); + ring_buffer_set(neigh_node->tq_recv, + &neigh_node->tq_index, + batman_packet->tq); neigh_node->tq_avg = ring_buffer_avg(neigh_node->tq_recv); if (!is_duplicate) { @@ -344,9 +281,11 @@ static void update_orig(struct orig_node *orig_node, struct ethhdr *ethhdr, stru neigh_node->last_ttl = batman_packet->ttl; } - tmp_hna_buff_len = (hna_buff_len > batman_packet->num_hna * ETH_ALEN ? batman_packet->num_hna * ETH_ALEN : hna_buff_len); + tmp_hna_buff_len = (hna_buff_len > batman_packet->num_hna * ETH_ALEN ? + batman_packet->num_hna * ETH_ALEN : hna_buff_len); - /* if this neighbor already is our next hop there is nothing to change */ + /* if this neighbor already is our next hop there is nothing + * to change */ if (orig_node->router == neigh_node) goto update_hna; @@ -355,11 +294,12 @@ static void update_orig(struct orig_node *orig_node, struct ethhdr *ethhdr, stru (orig_node->router->tq_avg > neigh_node->tq_avg)) goto update_hna; - /* if the TQ is the same and the link not more symetric we won't consider it either */ + /* if the TQ is the same and the link not more symetric we + * won't consider it either */ if ((orig_node->router) && ((neigh_node->tq_avg == orig_node->router->tq_avg) && - (orig_node->router->orig_node->bcast_own_sum[if_incoming->if_num] >= - neigh_node->orig_node->bcast_own_sum[if_incoming->if_num]))) + (orig_node->router->orig_node->bcast_own_sum[if_incoming->if_num] + >= neigh_node->orig_node->bcast_own_sum[if_incoming->if_num]))) goto update_hna; update_routes(orig_node, neigh_node, hna_buff, tmp_hna_buff_len); @@ -367,60 +307,72 @@ static void update_orig(struct orig_node *orig_node, struct ethhdr *ethhdr, stru update_hna: update_routes(orig_node, orig_node->router, hna_buff, tmp_hna_buff_len); - return; } -static char count_real_packets(struct ethhdr *ethhdr, struct batman_packet *batman_packet, struct batman_if *if_incoming) +static char count_real_packets(struct ethhdr *ethhdr, + struct batman_packet *batman_packet, + struct batman_if *if_incoming) { struct orig_node *orig_node; struct neigh_node *tmp_neigh_node; char is_duplicate = 0; - + uint16_t seq_diff; orig_node = get_orig_node(batman_packet->orig); if (orig_node == NULL) return 0; - list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) { if (!is_duplicate) - is_duplicate = get_bit_status(tmp_neigh_node->real_bits, orig_node->last_real_seqno, batman_packet->seqno); - - if (compare_orig(tmp_neigh_node->addr, ethhdr->h_source) && (tmp_neigh_node->if_incoming == if_incoming)) - bit_get_packet(tmp_neigh_node->real_bits, batman_packet->seqno - orig_node->last_real_seqno, 1); + is_duplicate = + get_bit_status(tmp_neigh_node->real_bits, + orig_node->last_real_seqno, + batman_packet->seqno); + seq_diff = batman_packet->seqno - orig_node->last_real_seqno; + if (compare_orig(tmp_neigh_node->addr, ethhdr->h_source) && + (tmp_neigh_node->if_incoming == if_incoming)) + bit_get_packet(tmp_neigh_node->real_bits, seq_diff, 1); else - bit_get_packet(tmp_neigh_node->real_bits, batman_packet->seqno - orig_node->last_real_seqno, 0); + bit_get_packet(tmp_neigh_node->real_bits, seq_diff, 0); - tmp_neigh_node->real_packet_count = bit_packet_count(tmp_neigh_node->real_bits); + tmp_neigh_node->real_packet_count = + bit_packet_count(tmp_neigh_node->real_bits); } if (!is_duplicate) { - debug_log(LOG_TYPE_BATMAN, "updating last_seqno: old %d, new %d \n", orig_node->last_real_seqno, batman_packet->seqno); + bat_dbg(DBG_BATMAN, "updating last_seqno: old %d, new %d \n", + orig_node->last_real_seqno, batman_packet->seqno); orig_node->last_real_seqno = batman_packet->seqno; } return is_duplicate; } -void receive_bat_packet(struct ethhdr *ethhdr, struct batman_packet *batman_packet, unsigned char *hna_buff, int hna_buff_len, struct batman_if *if_incoming) +void receive_bat_packet(struct ethhdr *ethhdr, + struct batman_packet *batman_packet, + unsigned char *hna_buff, int hna_buff_len, + struct batman_if *if_incoming) { struct batman_if *batman_if; struct orig_node *orig_neigh_node, *orig_node; - char orig_str[ETH_STR_LEN], prev_sender_str[ETH_STR_LEN], neigh_str[ETH_STR_LEN]; char has_directlink_flag; - char is_my_addr = 0, is_my_orig = 0, is_my_oldorig = 0, is_broadcast = 0, is_bidirectional, is_single_hop_neigh, is_duplicate; + char is_my_addr = 0, is_my_orig = 0, is_my_oldorig = 0; + char is_broadcast = 0, is_bidirectional, is_single_hop_neigh; + char is_duplicate; unsigned short if_incoming_seqno; - /* Silently drop when the batman packet is actually not a correct packet. + /* Silently drop when the batman packet is actually not a + * correct packet. * * This might happen if a packet is padded (e.g. Ethernet has a * minimum frame length of 64 byte) and the aggregation interprets * it as an additional length. * - * TODO: A more sane solution would be to have a bit in the batman_packet - * to detect whether the packet is the last packet in an aggregation. - * Here we expect that the padding is always zero (or not 0x01) + * TODO: A more sane solution would be to have a bit in the + * batman_packet to detect whether the packet is the last + * packet in an aggregation. Here we expect that the padding + * is always zero (or not 0x01) */ if (batman_packet->packet_type != BAT_PACKET) return; @@ -428,27 +380,31 @@ void receive_bat_packet(struct ethhdr *ethhdr, struct batman_packet *batman_pack /* could be changed by schedule_own_packet() */ if_incoming_seqno = atomic_read(&if_incoming->seqno); - addr_to_string(orig_str, batman_packet->orig); - addr_to_string(prev_sender_str, batman_packet->prev_sender); - addr_to_string(neigh_str, ethhdr->h_source); - has_directlink_flag = (batman_packet->flags & DIRECTLINK ? 1 : 0); - is_single_hop_neigh = (compare_orig(ethhdr->h_source, batman_packet->orig) ? 1 : 0); + is_single_hop_neigh = (compare_orig(ethhdr->h_source, + batman_packet->orig) ? 1 : 0); - debug_log(LOG_TYPE_BATMAN, "Received BATMAN packet via NB: %s, IF: %s [%s] (from OG: %s, via prev OG: %s, seqno %d, tq %d, TTL %d, V %d, IDF %d) \n", neigh_str, if_incoming->dev, if_incoming->addr_str, orig_str, prev_sender_str, batman_packet->seqno, batman_packet->tq, batman_packet->ttl, batman_packet->version, has_directlink_flag); + bat_dbg(DBG_BATMAN, "Received BATMAN packet via NB: %pM, IF: %s [%s] (from OG: %pM, via prev OG: %pM, seqno %d, tq %d, TTL %d, V %d, IDF %d) \n", + ethhdr->h_source, if_incoming->dev, if_incoming->addr_str, + batman_packet->orig, batman_packet->prev_sender, + batman_packet->seqno, batman_packet->tq, batman_packet->ttl, + batman_packet->version, has_directlink_flag); list_for_each_entry_rcu(batman_if, &if_list, list) { if (batman_if->if_active != IF_ACTIVE) continue; - if (compare_orig(ethhdr->h_source, batman_if->net_dev->dev_addr)) + if (compare_orig(ethhdr->h_source, + batman_if->net_dev->dev_addr)) is_my_addr = 1; - if (compare_orig(batman_packet->orig, batman_if->net_dev->dev_addr)) + if (compare_orig(batman_packet->orig, + batman_if->net_dev->dev_addr)) is_my_orig = 1; - if (compare_orig(batman_packet->prev_sender, batman_if->net_dev->dev_addr)) + if (compare_orig(batman_packet->prev_sender, + batman_if->net_dev->dev_addr)) is_my_oldorig = 1; if (compare_orig(ethhdr->h_source, broadcastAddr)) @@ -456,44 +412,61 @@ void receive_bat_packet(struct ethhdr *ethhdr, struct batman_packet *batman_pack } if (batman_packet->version != COMPAT_VERSION) { - debug_log(LOG_TYPE_BATMAN, "Drop packet: incompatible batman version (%i) \n", batman_packet->version); + bat_dbg(DBG_BATMAN, + "Drop packet: incompatible batman version (%i)\n", + batman_packet->version); return; } if (is_my_addr) { - debug_log(LOG_TYPE_BATMAN, "Drop packet: received my own broadcast (sender: %s) \n", neigh_str); + bat_dbg(DBG_BATMAN, + "Drop packet: received my own broadcast (sender: %pM)\n", + ethhdr->h_source); return; } if (is_broadcast) { - debug_log(LOG_TYPE_BATMAN, "Drop packet: ignoring all packets with broadcast source addr (sender: %s) \n", neigh_str); + bat_dbg(DBG_BATMAN, "Drop packet: ignoring all packets with broadcast source addr (sender: %pM) \n", ethhdr->h_source); return; } if (is_my_orig) { + TYPE_OF_WORD *word; + int offset; + orig_neigh_node = get_orig_node(ethhdr->h_source); - /* neighbour has to indicate direct link and it has to come via the corresponding interface */ - /* if received seqno equals last send seqno save new seqno for bidirectional check */ - if (has_directlink_flag && compare_orig(if_incoming->net_dev->dev_addr, batman_packet->orig) && - (batman_packet->seqno - if_incoming_seqno + 2 == 0)) { - bit_mark((TYPE_OF_WORD *)&(orig_neigh_node->bcast_own[if_incoming->if_num * NUM_WORDS]), 0); - orig_neigh_node->bcast_own_sum[if_incoming->if_num] = bit_packet_count((TYPE_OF_WORD *)&(orig_neigh_node->bcast_own[if_incoming->if_num * NUM_WORDS])); + if (!orig_neigh_node) + return; + + /* neighbor has to indicate direct link and it has to + * come via the corresponding interface */ + /* if received seqno equals last send seqno save new + * seqno for bidirectional check */ + if (has_directlink_flag && + compare_orig(if_incoming->net_dev->dev_addr, + batman_packet->orig) && + (batman_packet->seqno - if_incoming_seqno + 2 == 0)) { + offset = if_incoming->if_num * NUM_WORDS; + word = &(orig_neigh_node->bcast_own[offset]); + bit_mark(word, 0); + orig_neigh_node->bcast_own_sum[if_incoming->if_num] = + bit_packet_count(word); } - debug_log(LOG_TYPE_BATMAN, "Drop packet: originator packet from myself (via neighbour) \n"); + bat_dbg(DBG_BATMAN, "Drop packet: originator packet from myself (via neighbor) \n"); return; } if (batman_packet->tq == 0) { count_real_packets(ethhdr, batman_packet, if_incoming); - debug_log(LOG_TYPE_BATMAN, "Drop packet: originator packet with tq equal 0 \n"); + bat_dbg(DBG_BATMAN, "Drop packet: originator packet with tq equal 0 \n"); return; } if (is_my_oldorig) { - debug_log(LOG_TYPE_BATMAN, "Drop packet: ignoring all rebroadcast echos (sender: %s) \n", neigh_str); + bat_dbg(DBG_BATMAN, "Drop packet: ignoring all rebroadcast echos (sender: %pM) \n", ethhdr->h_source); return; } @@ -504,507 +477,502 @@ void receive_bat_packet(struct ethhdr *ethhdr, struct batman_packet *batman_pack return; /* avoid temporary routing loops */ - if ((orig_node->router) && (orig_node->router->orig_node->router) && - (compare_orig(orig_node->router->addr, batman_packet->prev_sender)) && + if ((orig_node->router) && + (orig_node->router->orig_node->router) && + (compare_orig(orig_node->router->addr, + batman_packet->prev_sender)) && !(compare_orig(batman_packet->orig, batman_packet->prev_sender)) && - (compare_orig(orig_node->router->addr, orig_node->router->orig_node->router->addr))) { - debug_log(LOG_TYPE_BATMAN, "Drop packet: ignoring all rebroadcast packets that may make me loop (sender: %s) \n", neigh_str); + (compare_orig(orig_node->router->addr, + orig_node->router->orig_node->router->addr))) { + bat_dbg(DBG_BATMAN, "Drop packet: ignoring all rebroadcast packets that may make me loop (sender: %pM) \n", ethhdr->h_source); return; } - /* if sender is a direct neighbor the sender mac equals originator mac */ - orig_neigh_node = (is_single_hop_neigh ? orig_node : get_orig_node(ethhdr->h_source)); + /* if sender is a direct neighbor the sender mac equals + * originator mac */ + orig_neigh_node = (is_single_hop_neigh ? + orig_node : get_orig_node(ethhdr->h_source)); if (orig_neigh_node == NULL) return; - /* drop packet if sender is not a direct neighbor and if we don't route towards it */ - if (!is_single_hop_neigh && (orig_neigh_node->router == NULL)) { - debug_log(LOG_TYPE_BATMAN, "Drop packet: OGM via unknown neighbor! \n"); + /* drop packet if sender is not a direct neighbor and if we + * don't route towards it */ + if (!is_single_hop_neigh && + (orig_neigh_node->router == NULL)) { + bat_dbg(DBG_BATMAN, "Drop packet: OGM via unknown neighbor!\n"); return; } - is_bidirectional = isBidirectionalNeigh(orig_node, orig_neigh_node, batman_packet, if_incoming); + is_bidirectional = isBidirectionalNeigh(orig_node, orig_neigh_node, + batman_packet, if_incoming); - /* update ranking if it is not a duplicate or has the same seqno and similar ttl as the non-duplicate */ - if (is_bidirectional && (!is_duplicate || - ((orig_node->last_real_seqno == batman_packet->seqno) && - (orig_node->last_ttl - 3 <= batman_packet->ttl)))) - update_orig(orig_node, ethhdr, batman_packet, if_incoming, hna_buff, hna_buff_len, is_duplicate); + /* update ranking if it is not a duplicate or has the same + * seqno and similar ttl as the non-duplicate */ + if (is_bidirectional && + (!is_duplicate || + ((orig_node->last_real_seqno == batman_packet->seqno) && + (orig_node->last_ttl - 3 <= batman_packet->ttl)))) + update_orig(orig_node, ethhdr, batman_packet, + if_incoming, hna_buff, hna_buff_len, is_duplicate); - /* is single hop (direct) neighbour */ + /* is single hop (direct) neighbor */ if (is_single_hop_neigh) { /* mark direct link on incoming interface */ - schedule_forward_packet(orig_node, ethhdr, batman_packet, 1, hna_buff_len, if_incoming); + schedule_forward_packet(orig_node, ethhdr, batman_packet, + 1, hna_buff_len, if_incoming); - debug_log(LOG_TYPE_BATMAN, "Forwarding packet: rebroadcast neighbour packet with direct link flag \n"); + bat_dbg(DBG_BATMAN, "Forwarding packet: rebroadcast neighbor packet with direct link flag\n"); return; } /* multihop originator */ if (!is_bidirectional) { - debug_log(LOG_TYPE_BATMAN, "Drop packet: not received via bidirectional link\n"); + bat_dbg(DBG_BATMAN, + "Drop packet: not received via bidirectional link\n"); return; } if (is_duplicate) { - debug_log(LOG_TYPE_BATMAN, "Drop packet: duplicate packet received\n"); + bat_dbg(DBG_BATMAN, "Drop packet: duplicate packet received\n"); return; } - debug_log(LOG_TYPE_BATMAN, "Forwarding packet: rebroadcast originator packet \n"); - schedule_forward_packet(orig_node, ethhdr, batman_packet, 0, hna_buff_len, if_incoming); + bat_dbg(DBG_BATMAN, + "Forwarding packet: rebroadcast originator packet\n"); + schedule_forward_packet(orig_node, ethhdr, batman_packet, + 0, hna_buff_len, if_incoming); } -void purge_orig(struct work_struct *work) +int recv_bat_packet(struct sk_buff *skb, + struct batman_if *batman_if) { - struct list_head *list_pos, *list_pos_tmp; - struct hash_it_t *hashit = NULL; - struct orig_node *orig_node; - struct neigh_node *neigh_node, *best_neigh_node; - char orig_str[ETH_STR_LEN], neigh_str[ETH_STR_LEN], neigh_purged; - - spin_lock(&orig_hash_lock); - - /* for all origins... */ - while (NULL != (hashit = hash_iterate(orig_hash, hashit))) { - - orig_node = hashit->bucket->data; - addr_to_string(orig_str, orig_node->orig); - - if (time_after(jiffies, orig_node->last_valid + ((2 * PURGE_TIMEOUT * HZ) / 1000))) { - - debug_log(LOG_TYPE_BATMAN, "Originator timeout: originator %s, last_valid %u \n", orig_str, (orig_node->last_valid / HZ)); - - hash_remove_bucket(orig_hash, hashit); - free_orig_node(orig_node); - - } else { - - best_neigh_node = NULL; - neigh_purged = 0; - - /* for all neighbours towards this originator ... */ - list_for_each_safe(list_pos, list_pos_tmp, &orig_node->neigh_list) { - neigh_node = list_entry(list_pos, struct neigh_node, list); - - if (time_after(jiffies, neigh_node->last_valid + ((PURGE_TIMEOUT * HZ) / 1000))) { - - addr_to_string(neigh_str, neigh_node->addr); - debug_log(LOG_TYPE_BATMAN, "Neighbour timeout: originator %s, neighbour: %s, last_valid %u \n", orig_str, neigh_str, (neigh_node->last_valid / HZ)); - - neigh_purged = 1; - list_del(list_pos); - kfree(neigh_node); - - } else { - - if ((best_neigh_node == NULL) || (neigh_node->tq_avg > best_neigh_node->tq_avg)) - best_neigh_node = neigh_node; - - } - - } + struct ethhdr *ethhdr; + unsigned long flags; + + /* drop packet if it has not necessary minimum size */ + if (skb_headlen(skb) < sizeof(struct batman_packet)) + return NET_RX_DROP; + + ethhdr = (struct ethhdr *)skb_mac_header(skb); + + /* packet with broadcast indication but unicast recipient */ + if (!is_bcast(ethhdr->h_dest)) + return NET_RX_DROP; + + /* packet with broadcast sender address */ + if (is_bcast(ethhdr->h_source)) + return NET_RX_DROP; + + spin_lock_irqsave(&orig_hash_lock, flags); + /* TODO: we use headlen instead of "length", because + * only this data is paged in. */ + /* TODO: is another skb_copy needed here? there will be + * written on the data, but nobody (?) should further use + * this data */ + receive_aggr_bat_packet(ethhdr, + skb->data, + skb_headlen(skb), + batman_if); + spin_unlock_irqrestore(&orig_hash_lock, flags); + + kfree_skb(skb); + return NET_RX_SUCCESS; +} - if (neigh_purged) - update_routes(orig_node, best_neigh_node, orig_node->hna_buff, orig_node->hna_buff_len); +static int recv_my_icmp_packet(struct sk_buff *skb) +{ + struct orig_node *orig_node; + struct icmp_packet *icmp_packet; + struct ethhdr *ethhdr; + struct sk_buff *skb_old; + struct batman_if *batman_if; + int ret; + unsigned long flags; + uint8_t dstaddr[ETH_ALEN]; - } + icmp_packet = (struct icmp_packet *) skb->data; + ethhdr = (struct ethhdr *) skb_mac_header(skb); + /* add data to device queue */ + if (icmp_packet->msg_type != ECHO_REQUEST) { + bat_device_receive_packet(icmp_packet); + return NET_RX_DROP; } - spin_unlock(&orig_hash_lock); + /* answer echo request (ping) */ + /* get routing information */ + spin_lock_irqsave(&orig_hash_lock, flags); + orig_node = ((struct orig_node *)hash_find(orig_hash, + icmp_packet->orig)); + ret = NET_RX_DROP; + + if ((orig_node != NULL) && + (orig_node->batman_if != NULL) && + (orig_node->router != NULL)) { + + /* don't lock while sending the packets ... we therefore + * copy the required data before sending */ + batman_if = orig_node->batman_if; + memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); + spin_unlock_irqrestore(&orig_hash_lock, flags); + + /* create a copy of the skb, if needed, to modify it. */ + skb_old = NULL; + if (!skb_clone_writable(skb, sizeof(struct icmp_packet))) { + skb_old = skb; + skb = skb_copy(skb, GFP_ATOMIC); + if (!skb) + return NET_RX_DROP; + icmp_packet = (struct icmp_packet *) skb->data; + kfree_skb(skb_old); + } - start_purge_timer(); -} + memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN); + memcpy(icmp_packet->orig, ethhdr->h_dest, ETH_ALEN); + icmp_packet->msg_type = ECHO_REPLY; + icmp_packet->ttl = TTL; -static int receive_raw_packet(struct socket *raw_sock, unsigned char *packet_buff, int packet_buff_len) -{ - struct kvec iov; - struct msghdr msg; + send_skb_packet(skb, batman_if, dstaddr); + ret = NET_RX_SUCCESS; - iov.iov_base = packet_buff; - iov.iov_len = packet_buff_len; + } else + spin_unlock_irqrestore(&orig_hash_lock, flags); - msg.msg_flags = MSG_DONTWAIT; /* non-blocking */ - msg.msg_name = NULL; - msg.msg_namelen = 0; - msg.msg_control = NULL; - - return kernel_recvmsg(raw_sock, &msg, &iov, 1, packet_buff_len, MSG_DONTWAIT); + return ret; } -int packet_recv_thread(void *data) +static int recv_icmp_ttl_exceeded(struct sk_buff *skb) { - struct batman_if *batman_if; - struct ethhdr *ethhdr; - struct batman_packet *batman_packet; - struct unicast_packet *unicast_packet; - struct bcast_packet *bcast_packet; - struct icmp_packet *icmp_packet; - struct vis_packet *vis_packet; struct orig_node *orig_node; - unsigned char *packet_buff, src_str[ETH_STR_LEN], dst_str[ETH_STR_LEN]; - int vis_info_len; - int result; - - atomic_set(&data_ready_cond, 0); - atomic_set(&exit_cond, 0); - packet_buff = kmalloc(PACKBUFF_SIZE, GFP_KERNEL); - if (!packet_buff) { - debug_log(LOG_TYPE_CRIT, "Could allocate memory for the packet buffer. :(\n"); - return -1; + struct icmp_packet *icmp_packet; + struct ethhdr *ethhdr; + struct sk_buff *skb_old; + struct batman_if *batman_if; + int ret; + unsigned long flags; + uint8_t dstaddr[ETH_ALEN]; + + icmp_packet = (struct icmp_packet *)skb->data; + ethhdr = (struct ethhdr *)skb_mac_header(skb); + + /* send TTL exceeded if packet is an echo request (traceroute) */ + if (icmp_packet->msg_type != ECHO_REQUEST) { + printk(KERN_WARNING "batman-adv:Warning - can't forward icmp packet from %pM to %pM: ttl exceeded\n", + icmp_packet->orig, icmp_packet->dst); + return NET_RX_DROP; } - while ((!kthread_should_stop()) && (!atomic_read(&exit_cond))) { - - wait_event_interruptible(thread_wait, (atomic_read(&data_ready_cond) || atomic_read(&exit_cond))); - - atomic_set(&data_ready_cond, 0); - - if (kthread_should_stop() || atomic_read(&exit_cond)) - break; - - /* we only want to safely traverse the list, hard-interfaces - * won't be deleted anyway as long as this thread runs. */ - - rcu_read_lock(); - list_for_each_entry_rcu(batman_if, &if_list, list) { - rcu_read_unlock(); - - result = -1; - - while (1) { - if (batman_if->if_active != IF_ACTIVE) { - if (batman_if->if_active != IF_TO_BE_ACTIVATED) - debug_log(LOG_TYPE_NOTICE, - "Could not read from deactivated interface %s!\n", - batman_if->dev); - - if (batman_if->raw_sock) - receive_raw_packet(batman_if->raw_sock, packet_buff, PACKBUFF_SIZE); - result = 0; - break; - } - - result = receive_raw_packet(batman_if->raw_sock, packet_buff, PACKBUFF_SIZE); - if (result <= 0) - break; - - if (result < sizeof(struct ethhdr) + 2) - continue; - - ethhdr = (struct ethhdr *)packet_buff; - batman_packet = (struct batman_packet *)(packet_buff + sizeof(struct ethhdr)); - - if (batman_packet->version != COMPAT_VERSION) { - debug_log(LOG_TYPE_BATMAN, "Drop packet: incompatible batman version (%i) \n", batman_packet->version); - continue; - } - - switch (batman_packet->packet_type) { - /* batman originator packet */ - case BAT_PACKET: - /* packet with broadcast indication but unicast recipient */ - if (!is_bcast(ethhdr->h_dest)) - continue; - - /* packet with broadcast sender address */ - if (is_bcast(ethhdr->h_source)) - continue; - - /* drop packet if it has not at least one batman packet as payload */ - if (result < sizeof(struct ethhdr) + sizeof(struct batman_packet)) - continue; - - spin_lock(&orig_hash_lock); - receive_aggr_bat_packet(ethhdr, - packet_buff + sizeof(struct ethhdr), - result - sizeof(struct ethhdr), - batman_if); - spin_unlock(&orig_hash_lock); - - break; - - /* batman icmp packet */ - case BAT_ICMP: - /* packet with unicast indication but broadcast recipient */ - if (is_bcast(ethhdr->h_dest)) - continue; - - /* packet with broadcast sender address */ - if (is_bcast(ethhdr->h_source)) - continue; - - /* not for me */ - if (!is_my_mac(ethhdr->h_dest)) - continue; - - /* drop packet if it has not necessary minimum size */ - if (result < sizeof(struct ethhdr) + sizeof(struct icmp_packet)) - continue; - - icmp_packet = (struct icmp_packet *)(packet_buff + sizeof(struct ethhdr)); - - /* packet for me */ - if (is_my_mac(icmp_packet->dst)) { - - /* add data to device queue */ - if (icmp_packet->msg_type != ECHO_REQUEST) { - bat_device_receive_packet(icmp_packet); - continue; - } - - /* answer echo request (ping) */ - /* get routing information */ - spin_lock(&orig_hash_lock); - orig_node = ((struct orig_node *)hash_find(orig_hash, icmp_packet->orig)); - - if ((orig_node != NULL) && (orig_node->batman_if != NULL) && (orig_node->router != NULL)) { - - memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN); - memcpy(icmp_packet->orig, ethhdr->h_dest, ETH_ALEN); - icmp_packet->msg_type = ECHO_REPLY; - icmp_packet->ttl = TTL; - - send_raw_packet(packet_buff + sizeof(struct ethhdr), - result - sizeof(struct ethhdr), - orig_node->batman_if, - orig_node->router->addr); - - } - - spin_unlock(&orig_hash_lock); - continue; - - } - - /* TTL exceeded */ - if (icmp_packet->ttl < 2) { - - addr_to_string(src_str, icmp_packet->orig); - addr_to_string(dst_str, icmp_packet->dst); - - debug_log(LOG_TYPE_NOTICE, "Error - can't send packet from %s to %s: ttl exceeded\n", src_str, dst_str); - - /* send TTL exceeded if packet is an echo request (traceroute) */ - if (icmp_packet->msg_type != ECHO_REQUEST) - continue; - - /* get routing information */ - spin_lock(&orig_hash_lock); - orig_node = ((struct orig_node *)hash_find(orig_hash, icmp_packet->orig)); - - if ((orig_node != NULL) && (orig_node->batman_if != NULL) && (orig_node->router != NULL)) { - - memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN); - memcpy(icmp_packet->orig, ethhdr->h_dest, ETH_ALEN); - icmp_packet->msg_type = TTL_EXCEEDED; - icmp_packet->ttl = TTL; - - send_raw_packet(packet_buff + sizeof(struct ethhdr), - result - sizeof(struct ethhdr), - orig_node->batman_if, - orig_node->router->addr); + /* get routing information */ + spin_lock_irqsave(&orig_hash_lock, flags); + orig_node = ((struct orig_node *) + hash_find(orig_hash, icmp_packet->orig)); + ret = NET_RX_DROP; + + if ((orig_node != NULL) && + (orig_node->batman_if != NULL) && + (orig_node->router != NULL)) { + + /* don't lock while sending the packets ... we therefore + * copy the required data before sending */ + batman_if = orig_node->batman_if; + memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); + spin_unlock_irqrestore(&orig_hash_lock, flags); + + /* create a copy of the skb, if needed, to modify it. */ + if (!skb_clone_writable(skb, sizeof(struct icmp_packet))) { + skb_old = skb; + skb = skb_copy(skb, GFP_ATOMIC); + if (!skb) + return NET_RX_DROP; + icmp_packet = (struct icmp_packet *) skb->data; + kfree_skb(skb_old); + } - } + memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN); + memcpy(icmp_packet->orig, ethhdr->h_dest, ETH_ALEN); + icmp_packet->msg_type = TTL_EXCEEDED; + icmp_packet->ttl = TTL; - spin_unlock(&orig_hash_lock); - continue; + send_skb_packet(skb, batman_if, dstaddr); + ret = NET_RX_SUCCESS; - } + } else + spin_unlock_irqrestore(&orig_hash_lock, flags); - /* get routing information */ - spin_lock(&orig_hash_lock); - orig_node = ((struct orig_node *)hash_find(orig_hash, icmp_packet->dst)); + return ret; +} - if ((orig_node != NULL) && (orig_node->batman_if != NULL) && (orig_node->router != NULL)) { - /* decrement ttl */ - icmp_packet->ttl--; +int recv_icmp_packet(struct sk_buff *skb) +{ + struct icmp_packet *icmp_packet; + struct ethhdr *ethhdr; + struct orig_node *orig_node; + struct sk_buff *skb_old; + struct batman_if *batman_if; + int hdr_size = sizeof(struct icmp_packet); + int ret; + unsigned long flags; + uint8_t dstaddr[ETH_ALEN]; + + /* drop packet if it has not necessary minimum size */ + if (skb_headlen(skb) < hdr_size) + return NET_RX_DROP; + + ethhdr = (struct ethhdr *)skb_mac_header(skb); + + /* packet with unicast indication but broadcast recipient */ + if (is_bcast(ethhdr->h_dest)) + return NET_RX_DROP; + + /* packet with broadcast sender address */ + if (is_bcast(ethhdr->h_source)) + return NET_RX_DROP; + + /* not for me */ + if (!is_my_mac(ethhdr->h_dest)) + return NET_RX_DROP; + + icmp_packet = (struct icmp_packet *) skb->data; + + /* packet for me */ + if (is_my_mac(icmp_packet->dst)) + return recv_my_icmp_packet(skb); + + /* TTL exceeded */ + if (icmp_packet->ttl < 2) + return recv_icmp_ttl_exceeded(skb); + + ret = NET_RX_DROP; + + /* get routing information */ + spin_lock_irqsave(&orig_hash_lock, flags); + orig_node = ((struct orig_node *) + hash_find(orig_hash, icmp_packet->dst)); + + if ((orig_node != NULL) && + (orig_node->batman_if != NULL) && + (orig_node->router != NULL)) { + + /* don't lock while sending the packets ... we therefore + * copy the required data before sending */ + batman_if = orig_node->batman_if; + memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); + spin_unlock_irqrestore(&orig_hash_lock, flags); + + /* create a copy of the skb, if needed, to modify it. */ + if (!skb_clone_writable(skb, sizeof(struct icmp_packet))) { + skb_old = skb; + skb = skb_copy(skb, GFP_ATOMIC); + if (!skb) + return NET_RX_DROP; + icmp_packet = (struct icmp_packet *) skb->data; + kfree_skb(skb_old); + } - /* route it */ - send_raw_packet(packet_buff + sizeof(struct ethhdr), - result - sizeof(struct ethhdr), - orig_node->batman_if, - orig_node->router->addr); - } + /* decrement ttl */ + icmp_packet->ttl--; - spin_unlock(&orig_hash_lock); - break; + /* route it */ + send_skb_packet(skb, batman_if, dstaddr); + ret = NET_RX_SUCCESS; - /* unicast packet */ - case BAT_UNICAST: - /* packet with unicast indication but broadcast recipient */ - if (is_bcast(ethhdr->h_dest)) - continue; + } else + spin_unlock_irqrestore(&orig_hash_lock, flags); - /* packet with broadcast sender address */ - if (is_bcast(ethhdr->h_source)) - continue; + return ret; +} - /* not for me */ - if (!is_my_mac(ethhdr->h_dest)) - continue; +int recv_unicast_packet(struct sk_buff *skb) +{ + struct unicast_packet *unicast_packet; + struct orig_node *orig_node; + struct ethhdr *ethhdr; + struct batman_if *batman_if; + struct sk_buff *skb_old; + uint8_t dstaddr[ETH_ALEN]; + int hdr_size = sizeof(struct unicast_packet); + int ret; + unsigned long flags; - /* drop packet if it has not necessary minimum size */ - if (result < sizeof(struct ethhdr) + sizeof(struct unicast_packet)) - continue; + /* drop packet if it has not necessary minimum size */ + if (skb_headlen(skb) < hdr_size) + return NET_RX_DROP; - unicast_packet = (struct unicast_packet *)(packet_buff + sizeof(struct ethhdr)); + ethhdr = (struct ethhdr *) skb_mac_header(skb); - /* packet for me */ - if (is_my_mac(unicast_packet->dest)) { + /* packet with unicast indication but broadcast recipient */ + if (is_bcast(ethhdr->h_dest)) + return NET_RX_DROP; - interface_rx(soft_device, packet_buff + sizeof(struct ethhdr) + sizeof(struct unicast_packet), result - sizeof(struct ethhdr) - sizeof(struct unicast_packet)); - continue; + /* packet with broadcast sender address */ + if (is_bcast(ethhdr->h_source)) + return NET_RX_DROP; - } + /* not for me */ + if (!is_my_mac(ethhdr->h_dest)) + return NET_RX_DROP; - /* TTL exceeded */ - if (unicast_packet->ttl < 2) { - addr_to_string(src_str, ((struct ethhdr *)(unicast_packet + 1))->h_source); - addr_to_string(dst_str, unicast_packet->dest); + unicast_packet = (struct unicast_packet *) skb->data; - debug_log(LOG_TYPE_NOTICE, "Error - can't send packet from %s to %s: ttl exceeded\n", src_str, dst_str); - continue; - } + /* packet for me */ + if (is_my_mac(unicast_packet->dest)) { + interface_rx(skb, hdr_size); + return NET_RX_SUCCESS; + } - /* get routing information */ - spin_lock(&orig_hash_lock); - orig_node = ((struct orig_node *)hash_find(orig_hash, unicast_packet->dest)); + /* TTL exceeded */ + if (unicast_packet->ttl < 2) { + printk(KERN_WARNING "batman-adv:Warning - can't forward unicast packet from %pM to %pM: ttl exceeded\n", + ethhdr->h_source, unicast_packet->dest); + return NET_RX_DROP; + } - if ((orig_node != NULL) && (orig_node->batman_if != NULL) && (orig_node->router != NULL)) { - /* decrement ttl */ - unicast_packet->ttl--; + ret = NET_RX_DROP; + /* get routing information */ + spin_lock_irqsave(&orig_hash_lock, flags); + orig_node = ((struct orig_node *) + hash_find(orig_hash, unicast_packet->dest)); + + if ((orig_node != NULL) && + (orig_node->batman_if != NULL) && + (orig_node->router != NULL)) { + + /* don't lock while sending the packets ... we therefore + * copy the required data before sending */ + batman_if = orig_node->batman_if; + memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); + spin_unlock_irqrestore(&orig_hash_lock, flags); + + /* create a copy of the skb, if needed, to modify it. */ + if (!skb_clone_writable(skb, sizeof(struct unicast_packet))) { + skb_old = skb; + skb = skb_copy(skb, GFP_ATOMIC); + if (!skb) + return NET_RX_DROP; + unicast_packet = (struct unicast_packet *) skb->data; + kfree_skb(skb_old); + } + /* decrement ttl */ + unicast_packet->ttl--; - /* route it */ - send_raw_packet(packet_buff + sizeof(struct ethhdr), - result - sizeof(struct ethhdr), - orig_node->batman_if, - orig_node->router->addr); - } + /* route it */ + send_skb_packet(skb, batman_if, dstaddr); + ret = NET_RX_SUCCESS; - spin_unlock(&orig_hash_lock); - break; + } else + spin_unlock_irqrestore(&orig_hash_lock, flags); - /* broadcast packet */ - case BAT_BCAST: - /* packet with broadcast indication but unicast recipient */ - if (!is_bcast(ethhdr->h_dest)) - continue; + return ret; +} - /* packet with broadcast sender address */ - if (is_bcast(ethhdr->h_source)) - continue; - /* drop packet if it has not necessary minimum size */ - if (result < sizeof(struct ethhdr) + sizeof(struct bcast_packet)) - continue; +int recv_bcast_packet(struct sk_buff *skb) +{ + struct orig_node *orig_node; + struct bcast_packet *bcast_packet; + struct ethhdr *ethhdr; + int hdr_size = sizeof(struct bcast_packet); + unsigned long flags; - /* ignore broadcasts sent by myself */ - if (is_my_mac(ethhdr->h_source)) - continue; + /* drop packet if it has not necessary minimum size */ + if (skb_headlen(skb) < hdr_size) + return NET_RX_DROP; - bcast_packet = (struct bcast_packet *)(packet_buff + sizeof(struct ethhdr)); + ethhdr = (struct ethhdr *)skb_mac_header(skb); - /* ignore broadcasts originated by myself */ - if (is_my_mac(bcast_packet->orig)) - continue; + /* packet with broadcast indication but unicast recipient */ + if (!is_bcast(ethhdr->h_dest)) + return NET_RX_DROP; - spin_lock(&orig_hash_lock); - orig_node = ((struct orig_node *)hash_find(orig_hash, bcast_packet->orig)); + /* packet with broadcast sender address */ + if (is_bcast(ethhdr->h_source)) + return NET_RX_DROP; - if (orig_node == NULL) { - spin_unlock(&orig_hash_lock); - continue; - } + /* ignore broadcasts sent by myself */ + if (is_my_mac(ethhdr->h_source)) + return NET_RX_DROP; - /* check flood history */ - if (get_bit_status(orig_node->bcast_bits, orig_node->last_bcast_seqno, ntohs(bcast_packet->seqno))) { - spin_unlock(&orig_hash_lock); - continue; - } + bcast_packet = (struct bcast_packet *) skb->data; - /* mark broadcast in flood history */ - if (bit_get_packet(orig_node->bcast_bits, ntohs(bcast_packet->seqno) - orig_node->last_bcast_seqno, 1)) - orig_node->last_bcast_seqno = ntohs(bcast_packet->seqno); + /* ignore broadcasts originated by myself */ + if (is_my_mac(bcast_packet->orig)) + return NET_RX_DROP; - spin_unlock(&orig_hash_lock); + spin_lock_irqsave(&orig_hash_lock, flags); + orig_node = ((struct orig_node *) + hash_find(orig_hash, bcast_packet->orig)); - /* broadcast for me */ - interface_rx(soft_device, packet_buff + sizeof(struct ethhdr) + sizeof(struct bcast_packet), result - sizeof(struct ethhdr) - sizeof(struct bcast_packet)); + if (orig_node == NULL) { + spin_unlock_irqrestore(&orig_hash_lock, flags); + return NET_RX_DROP; + } - /* rebroadcast packet */ - add_bcast_packet_to_list(packet_buff + sizeof(struct ethhdr), - result - sizeof(struct ethhdr)); + /* check flood history */ + if (get_bit_status(orig_node->bcast_bits, + orig_node->last_bcast_seqno, + ntohs(bcast_packet->seqno))) { + spin_unlock_irqrestore(&orig_hash_lock, flags); + return NET_RX_DROP; + } - break; + /* mark broadcast in flood history */ + if (bit_get_packet(orig_node->bcast_bits, + ntohs(bcast_packet->seqno) - + orig_node->last_bcast_seqno, 1)) + orig_node->last_bcast_seqno = ntohs(bcast_packet->seqno); - /* vis packet */ - case BAT_VIS: - /* drop if too short. */ - if (result < sizeof(struct ethhdr) + sizeof(struct vis_packet)) - continue; + spin_unlock_irqrestore(&orig_hash_lock, flags); - /* not for me */ - if (!is_my_mac(ethhdr->h_dest)) - continue; + /* rebroadcast packet */ + add_bcast_packet_to_list(skb); - vis_packet = (struct vis_packet *)(packet_buff + sizeof(struct ethhdr)); - vis_info_len = result - sizeof(struct ethhdr) - sizeof(struct vis_packet); + /* broadcast for me */ + interface_rx(skb, hdr_size); - /* ignore own packets */ - if (is_my_mac(vis_packet->vis_orig)) - continue; + return NET_RX_SUCCESS; +} - if (is_my_mac(vis_packet->sender_orig)) - continue; +int recv_vis_packet(struct sk_buff *skb) +{ + struct vis_packet *vis_packet; + struct ethhdr *ethhdr; + int hdr_size = sizeof(struct vis_packet); - switch (vis_packet->vis_type) { - case VIS_TYPE_SERVER_SYNC: - receive_server_sync_packet(vis_packet, vis_info_len); - break; + if (skb_headlen(skb) < hdr_size) + return NET_RX_DROP; - case VIS_TYPE_CLIENT_UPDATE: - receive_client_update_packet(vis_packet, vis_info_len); - break; + vis_packet = (struct vis_packet *) skb->data; + ethhdr = (struct ethhdr *)skb_mac_header(skb); - default: /* ignore unknown packet */ - break; - } + /* not for me */ + if (!is_my_mac(ethhdr->h_dest)) + return NET_RX_DROP; - break; - } + /* ignore own packets */ + if (is_my_mac(vis_packet->vis_orig)) + return NET_RX_DROP; - } + if (is_my_mac(vis_packet->sender_orig)) + return NET_RX_DROP; - if ((result < 0) && (result != -EAGAIN)) - debug_log(LOG_TYPE_CRIT, "Could not receive packet from interface %s: %i\n", batman_if->dev, result); + switch (vis_packet->vis_type) { + case VIS_TYPE_SERVER_SYNC: + /* TODO: handle fragmented skbs properly */ + receive_server_sync_packet(vis_packet, skb_headlen(skb)); + break; - /* lock for the next iteration */ - rcu_read_lock(); - } - rcu_read_unlock(); + case VIS_TYPE_CLIENT_UPDATE: + /* TODO: handle fragmented skbs properly */ + receive_client_update_packet(vis_packet, skb_headlen(skb)); + break; + default: /* ignore unknown packet */ + break; } - kfree(packet_buff); - - /* do not exit until kthread_stop() is actually called, otherwise it will wait for us - * forever. */ - while (!kthread_should_stop()) - schedule(); - - return 0; -} - -void batman_data_ready(struct sock *sk, int len) -{ - void (*data_ready)(struct sock *, int) = sk->sk_user_data; - - data_ready(sk, len); - atomic_set(&data_ready_cond, 1); - wake_up_interruptible(&thread_wait); + /* We take a copy of the data in the packet, so we should + always free the skbuf. */ + return NET_RX_DROP; } - diff --git a/drivers/staging/batman-adv/routing.h b/drivers/staging/batman-adv/routing.h index 0123ea8..939b8d4 100644 --- a/drivers/staging/batman-adv/routing.h +++ b/drivers/staging/batman-adv/routing.h @@ -22,13 +22,18 @@ #include "types.h" extern wait_queue_head_t thread_wait; -extern atomic_t exit_cond; -int originator_init(void); -void free_orig_node(void *data); -void originator_free(void); void slide_own_bcast_window(struct batman_if *batman_if); -void batman_data_ready(struct sock *sk, int len); -void purge_orig(struct work_struct *work); -int packet_recv_thread(void *data); -void receive_bat_packet(struct ethhdr *ethhdr, struct batman_packet *batman_packet, unsigned char *hna_buff, int hna_buff_len, struct batman_if *if_incoming); +void receive_bat_packet(struct ethhdr *ethhdr, + struct batman_packet *batman_packet, + unsigned char *hna_buff, int hna_buff_len, + struct batman_if *if_incoming); +void update_routes(struct orig_node *orig_node, + struct neigh_node *neigh_node, + unsigned char *hna_buff, int hna_buff_len); +int recv_icmp_packet(struct sk_buff *skb); +int recv_unicast_packet(struct sk_buff *skb); +int recv_bcast_packet(struct sk_buff *skb); +int recv_vis_packet(struct sk_buff *skb); +int recv_bat_packet(struct sk_buff *skb, + struct batman_if *batman_if); diff --git a/drivers/staging/batman-adv/send.c b/drivers/staging/batman-adv/send.c index eb61750..2a9fac8 100644 --- a/drivers/staging/batman-adv/send.c +++ b/drivers/staging/batman-adv/send.c @@ -21,16 +21,14 @@ #include "main.h" #include "send.h" -#include "log.h" #include "routing.h" #include "translation-table.h" +#include "soft-interface.h" #include "hard-interface.h" #include "types.h" #include "vis.h" #include "aggregation.h" -#include "compat.h" - /* apply hop penalty for a normal link */ static uint8_t hop_penalty(const uint8_t tq) { @@ -59,51 +57,69 @@ static unsigned long forward_send_time(void) return send_time; } -/* sends a raw packet. */ -void send_raw_packet(unsigned char *pack_buff, int pack_buff_len, - struct batman_if *batman_if, uint8_t *dst_addr) +/* send out an already prepared packet to the given address via the + * specified batman interface */ +int send_skb_packet(struct sk_buff *skb, + struct batman_if *batman_if, + uint8_t *dst_addr) { struct ethhdr *ethhdr; - struct sk_buff *skb; - int retval; - char *data; if (batman_if->if_active != IF_ACTIVE) - return; + goto send_skb_err; + + if (unlikely(!batman_if->net_dev)) + goto send_skb_err; if (!(batman_if->net_dev->flags & IFF_UP)) { - debug_log(LOG_TYPE_WARN, - "Interface %s is not up - can't send packet via that interface (IF_TO_BE_DEACTIVATED was here) !\n", - batman_if->dev); - return; + printk(KERN_WARNING + "batman-adv:Interface %s is not up - can't send packet via that interface!\n", + batman_if->dev); + goto send_skb_err; } - skb = dev_alloc_skb(pack_buff_len + sizeof(struct ethhdr)); - if (!skb) - return; - data = skb_put(skb, pack_buff_len + sizeof(struct ethhdr)); + /* push to the ethernet header. */ + if (my_skb_push(skb, sizeof(struct ethhdr)) < 0) + goto send_skb_err; - memcpy(data + sizeof(struct ethhdr), pack_buff, pack_buff_len); + skb_reset_mac_header(skb); - ethhdr = (struct ethhdr *) data; + ethhdr = (struct ethhdr *) skb_mac_header(skb); memcpy(ethhdr->h_source, batman_if->net_dev->dev_addr, ETH_ALEN); memcpy(ethhdr->h_dest, dst_addr, ETH_ALEN); ethhdr->h_proto = __constant_htons(ETH_P_BATMAN); - skb_reset_mac_header(skb); skb_set_network_header(skb, ETH_HLEN); skb->priority = TC_PRIO_CONTROL; skb->protocol = __constant_htons(ETH_P_BATMAN); + skb->dev = batman_if->net_dev; /* dev_queue_xmit() returns a negative result on error. However on * congestion and traffic shaping, it drops and returns NET_XMIT_DROP * (which is > 0). This will not be treated as an error. */ - retval = dev_queue_xmit(skb); - if (retval < 0) - debug_log(LOG_TYPE_CRIT, - "Can't write to raw socket (IF_TO_BE_DEACTIVATED was here): %i\n", - retval); + + return dev_queue_xmit(skb); +send_skb_err: + kfree_skb(skb); + return NET_XMIT_DROP; +} + +/* sends a raw packet. */ +void send_raw_packet(unsigned char *pack_buff, int pack_buff_len, + struct batman_if *batman_if, uint8_t *dst_addr) +{ + struct sk_buff *skb; + char *data; + + skb = dev_alloc_skb(pack_buff_len + sizeof(struct ethhdr)); + if (!skb) + return; + data = skb_put(skb, pack_buff_len + sizeof(struct ethhdr)); + memcpy(data + sizeof(struct ethhdr), pack_buff, pack_buff_len); + /* pull back to the batman "network header" */ + skb_pull(skb, sizeof(struct ethhdr)); + send_skb_packet(skb, batman_if, dst_addr); } /* Send a packet to a given interface */ @@ -114,7 +130,6 @@ static void send_packet_to_if(struct forw_packet *forw_packet, uint8_t packet_num; int16_t buff_pos; struct batman_packet *batman_packet; - char orig_str[ETH_STR_LEN]; if (batman_if->if_active != IF_ACTIVE) return; @@ -136,19 +151,18 @@ static void send_packet_to_if(struct forw_packet *forw_packet, else batman_packet->flags &= ~DIRECTLINK; - addr_to_string(orig_str, batman_packet->orig); fwd_str = (packet_num > 0 ? "Forwarding" : (forw_packet->own ? "Sending own" : "Forwarding")); - debug_log(LOG_TYPE_BATMAN, - "%s %spacket (originator %s, seqno %d, TQ %d, TTL %d, IDF %s) on interface %s [%s]\n", - fwd_str, - (packet_num > 0 ? "aggregated " : ""), - orig_str, ntohs(batman_packet->seqno), - batman_packet->tq, batman_packet->ttl, - (batman_packet->flags & DIRECTLINK ? - "on" : "off"), - batman_if->dev, batman_if->addr_str); + bat_dbg(DBG_BATMAN, + "%s %spacket (originator %pM, seqno %d, TQ %d, TTL %d, IDF %s) on interface %s [%s]\n", + fwd_str, + (packet_num > 0 ? "aggregated " : ""), + batman_packet->orig, ntohs(batman_packet->seqno), + batman_packet->tq, batman_packet->ttl, + (batman_packet->flags & DIRECTLINK ? + "on" : "off"), + batman_if->dev, batman_if->addr_str); buff_pos += sizeof(struct batman_packet) + (batman_packet->num_hna * ETH_ALEN); @@ -168,32 +182,28 @@ static void send_packet(struct forw_packet *forw_packet) struct batman_if *batman_if; struct batman_packet *batman_packet = (struct batman_packet *)(forw_packet->packet_buff); - char orig_str[ETH_STR_LEN]; unsigned char directlink = (batman_packet->flags & DIRECTLINK ? 1 : 0); if (!forw_packet->if_incoming) { - debug_log(LOG_TYPE_CRIT, - "Error - can't forward packet: incoming iface not specified\n"); + printk(KERN_ERR "batman-adv: Error - can't forward packet: incoming iface not specified\n"); return; } if (forw_packet->if_incoming->if_active != IF_ACTIVE) return; - addr_to_string(orig_str, batman_packet->orig); - /* multihomed peer assumed */ /* non-primary OGMs are only broadcasted on their interface */ if ((directlink && (batman_packet->ttl == 1)) || (forw_packet->own && (forw_packet->if_incoming->if_num > 0))) { /* FIXME: what about aggregated packets ? */ - debug_log(LOG_TYPE_BATMAN, - "%s packet (originator %s, seqno %d, TTL %d) on interface %s [%s]\n", - (forw_packet->own ? "Sending own" : "Forwarding"), - orig_str, ntohs(batman_packet->seqno), - batman_packet->ttl, forw_packet->if_incoming->dev, - forw_packet->if_incoming->addr_str); + bat_dbg(DBG_BATMAN, + "%s packet (originator %pM, seqno %d, TTL %d) on interface %s [%s]\n", + (forw_packet->own ? "Sending own" : "Forwarding"), + batman_packet->orig, ntohs(batman_packet->seqno), + batman_packet->ttl, forw_packet->if_incoming->dev, + forw_packet->if_incoming->addr_str); send_raw_packet(forw_packet->packet_buff, forw_packet->packet_len, @@ -238,6 +248,7 @@ void schedule_own_packet(struct batman_if *batman_if) { unsigned long send_time; struct batman_packet *batman_packet; + int vis_server = atomic_read(&vis_mode); /** * the interface gets activated here to avoid race conditions between @@ -262,7 +273,7 @@ void schedule_own_packet(struct batman_if *batman_if) /* change sequence number to network order */ batman_packet->seqno = htons((uint16_t)atomic_read(&batman_if->seqno)); - if (is_vis_server()) + if (vis_server == VIS_TYPE_SERVER_SYNC) batman_packet->flags = VIS_SERVER; else batman_packet->flags = 0; @@ -286,7 +297,7 @@ void schedule_forward_packet(struct orig_node *orig_node, unsigned long send_time; if (batman_packet->ttl <= 1) { - debug_log(LOG_TYPE_BATMAN, "ttl exceeded \n"); + bat_dbg(DBG_BATMAN, "ttl exceeded \n"); return; } @@ -314,9 +325,9 @@ void schedule_forward_packet(struct orig_node *orig_node, /* apply hop penalty */ batman_packet->tq = hop_penalty(batman_packet->tq); - debug_log(LOG_TYPE_BATMAN, "Forwarding packet: tq_orig: %i, tq_avg: %i, tq_forw: %i, ttl_orig: %i, ttl_forw: %i \n", - in_tq, tq_avg, batman_packet->tq, in_ttl - 1, - batman_packet->ttl); + bat_dbg(DBG_BATMAN, "Forwarding packet: tq_orig: %i, tq_avg: %i, tq_forw: %i, ttl_orig: %i, ttl_forw: %i \n", + in_tq, tq_avg, batman_packet->tq, in_ttl - 1, + batman_packet->ttl); batman_packet->seqno = htons(batman_packet->seqno); @@ -333,6 +344,8 @@ void schedule_forward_packet(struct orig_node *orig_node, static void forw_packet_free(struct forw_packet *forw_packet) { + if (forw_packet->skb) + kfree_skb(forw_packet->skb); kfree(forw_packet->packet_buff); kfree(forw_packet); } @@ -340,12 +353,13 @@ static void forw_packet_free(struct forw_packet *forw_packet) static void _add_bcast_packet_to_list(struct forw_packet *forw_packet, unsigned long send_time) { + unsigned long flags; INIT_HLIST_NODE(&forw_packet->list); /* add new packet to packet list */ - spin_lock(&forw_bcast_list_lock); + spin_lock_irqsave(&forw_bcast_list_lock, flags); hlist_add_head(&forw_packet->list, &forw_bcast_list); - spin_unlock(&forw_bcast_list_lock); + spin_unlock_irqrestore(&forw_bcast_list_lock, flags); /* start timer for this packet */ INIT_DELAYED_WORK(&forw_packet->delayed_work, @@ -354,7 +368,7 @@ static void _add_bcast_packet_to_list(struct forw_packet *forw_packet, send_time); } -void add_bcast_packet_to_list(unsigned char *packet_buff, int packet_len) +void add_bcast_packet_to_list(struct sk_buff *skb) { struct forw_packet *forw_packet; @@ -362,14 +376,16 @@ void add_bcast_packet_to_list(unsigned char *packet_buff, int packet_len) if (!forw_packet) return; - forw_packet->packet_buff = kmalloc(packet_len, GFP_ATOMIC); - if (!forw_packet->packet_buff) { + skb = skb_copy(skb, GFP_ATOMIC); + if (!skb) { kfree(forw_packet); return; } - forw_packet->packet_len = packet_len; - memcpy(forw_packet->packet_buff, packet_buff, forw_packet->packet_len); + skb_reset_mac_header(skb); + + forw_packet->skb = skb; + forw_packet->packet_buff = NULL; /* how often did we send the bcast packet ? */ forw_packet->num_packets = 0; @@ -384,16 +400,20 @@ void send_outstanding_bcast_packet(struct work_struct *work) container_of(work, struct delayed_work, work); struct forw_packet *forw_packet = container_of(delayed_work, struct forw_packet, delayed_work); + unsigned long flags; + struct sk_buff *skb1; - spin_lock(&forw_bcast_list_lock); + spin_lock_irqsave(&forw_bcast_list_lock, flags); hlist_del(&forw_packet->list); - spin_unlock(&forw_bcast_list_lock); + spin_unlock_irqrestore(&forw_bcast_list_lock, flags); /* rebroadcast packet */ rcu_read_lock(); list_for_each_entry_rcu(batman_if, &if_list, list) { - send_raw_packet(forw_packet->packet_buff, - forw_packet->packet_len, + /* send a copy of the saved skb */ + skb1 = skb_copy(forw_packet->skb, GFP_ATOMIC); + if (skb1) + send_skb_packet(skb1, batman_if, broadcastAddr); } rcu_read_unlock(); @@ -415,10 +435,11 @@ void send_outstanding_bat_packet(struct work_struct *work) container_of(work, struct delayed_work, work); struct forw_packet *forw_packet = container_of(delayed_work, struct forw_packet, delayed_work); + unsigned long flags; - spin_lock(&forw_bat_list_lock); + spin_lock_irqsave(&forw_bat_list_lock, flags); hlist_del(&forw_packet->list); - spin_unlock(&forw_bat_list_lock); + spin_unlock_irqrestore(&forw_bat_list_lock, flags); send_packet(forw_packet); @@ -438,38 +459,39 @@ void purge_outstanding_packets(void) { struct forw_packet *forw_packet; struct hlist_node *tmp_node, *safe_tmp_node; + unsigned long flags; - debug_log(LOG_TYPE_BATMAN, "purge_outstanding_packets()\n"); + bat_dbg(DBG_BATMAN, "purge_outstanding_packets()\n"); /* free bcast list */ - spin_lock(&forw_bcast_list_lock); + spin_lock_irqsave(&forw_bcast_list_lock, flags); hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node, &forw_bcast_list, list) { - spin_unlock(&forw_bcast_list_lock); + spin_unlock_irqrestore(&forw_bcast_list_lock, flags); /** * send_outstanding_bcast_packet() will lock the list to * delete the item from the list */ cancel_delayed_work_sync(&forw_packet->delayed_work); - spin_lock(&forw_bcast_list_lock); + spin_lock_irqsave(&forw_bcast_list_lock, flags); } - spin_unlock(&forw_bcast_list_lock); + spin_unlock_irqrestore(&forw_bcast_list_lock, flags); /* free batman packet list */ - spin_lock(&forw_bat_list_lock); + spin_lock_irqsave(&forw_bat_list_lock, flags); hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node, &forw_bat_list, list) { - spin_unlock(&forw_bat_list_lock); + spin_unlock_irqrestore(&forw_bat_list_lock, flags); /** * send_outstanding_bat_packet() will lock the list to * delete the item from the list */ cancel_delayed_work_sync(&forw_packet->delayed_work); - spin_lock(&forw_bat_list_lock); + spin_lock_irqsave(&forw_bat_list_lock, flags); } - spin_unlock(&forw_bat_list_lock); + spin_unlock_irqrestore(&forw_bat_list_lock, flags); } diff --git a/drivers/staging/batman-adv/send.h b/drivers/staging/batman-adv/send.h index 59d5009..5fc6f34 100644 --- a/drivers/staging/batman-adv/send.h +++ b/drivers/staging/batman-adv/send.h @@ -22,6 +22,9 @@ #include "types.h" void send_own_packet_work(struct work_struct *work); +int send_skb_packet(struct sk_buff *skb, + struct batman_if *batman_if, + uint8_t *dst_addr); void send_raw_packet(unsigned char *pack_buff, int pack_buff_len, struct batman_if *batman_if, uint8_t *dst_addr); void schedule_own_packet(struct batman_if *batman_if); @@ -30,7 +33,7 @@ void schedule_forward_packet(struct orig_node *orig_node, struct batman_packet *batman_packet, uint8_t directlink, int hna_buff_len, struct batman_if *if_outgoing); -void add_bcast_packet_to_list(unsigned char *packet_buff, int packet_len); +void add_bcast_packet_to_list(struct sk_buff *skb); void send_outstanding_bcast_packet(struct work_struct *work); void send_outstanding_bat_packet(struct work_struct *work); void purge_outstanding_packets(void); diff --git a/drivers/staging/batman-adv/soft-interface.c b/drivers/staging/batman-adv/soft-interface.c index d543f50..c9b35d9f 100644 --- a/drivers/staging/batman-adv/soft-interface.c +++ b/drivers/staging/batman-adv/soft-interface.c @@ -24,18 +24,15 @@ #include "hard-interface.h" #include "send.h" #include "translation-table.h" -#include "log.h" #include "types.h" #include "hash.h" #include <linux/ethtool.h> #include <linux/etherdevice.h> -#include "compat.h" static uint16_t bcast_seqno = 1; /* give own bcast messages seq numbers to avoid * broadcast storms */ static int32_t skb_packets; static int32_t skb_bad_packets; -static int32_t lock_dropped; unsigned char mainIfAddr[ETH_ALEN]; static unsigned char mainIfAddr_default[ETH_ALEN]; @@ -68,12 +65,12 @@ int main_if_was_up(void) return (memcmp(mainIfAddr, mainIfAddr_default, ETH_ALEN) != 0 ? 1 : 0); } -static int my_skb_push(struct sk_buff *skb, unsigned int len) +int my_skb_push(struct sk_buff *skb, unsigned int len) { int result = 0; skb_packets++; - if (skb->data - len < skb->head) { + if (skb_headroom(skb) < len) { skb_bad_packets++; result = pskb_expand_head(skb, len, 0, GFP_ATOMIC); @@ -122,7 +119,7 @@ void interface_setup(struct net_device *dev) /* generate random address */ random_ether_addr(dev_addr); - memcpy(dev->dev_addr, dev_addr, sizeof(dev->dev_addr)); + memcpy(dev->dev_addr, dev_addr, ETH_ALEN); SET_ETHTOOL_OPS(dev, &bat_ethtool_ops); @@ -147,9 +144,18 @@ struct net_device_stats *interface_stats(struct net_device *dev) return &priv->stats; } -int interface_set_mac_addr(struct net_device *dev, void *addr) +int interface_set_mac_addr(struct net_device *dev, void *p) { - return -EBUSY; + struct sockaddr *addr = p; + + if (!is_valid_ether_addr(addr->sa_data)) + return -EADDRNOTAVAIL; + + hna_local_remove(dev->dev_addr, "mac address changed"); + memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); + hna_local_add(dev->dev_addr); + + return 0; } int interface_change_mtu(struct net_device *dev, int new_mtu) @@ -170,7 +176,10 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev) struct orig_node *orig_node; struct ethhdr *ethhdr = (struct ethhdr *)skb->data; struct bat_priv *priv = netdev_priv(dev); + struct batman_if *batman_if; + uint8_t dstaddr[6]; int data_len = skb->len; + unsigned long flags; if (atomic_read(&module_state) != MODULE_ACTIVE) goto dropped; @@ -186,7 +195,6 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev) goto dropped; bcast_packet = (struct bcast_packet *)skb->data; - bcast_packet->version = COMPAT_VERSION; /* batman packet type: broadcast */ @@ -195,27 +203,21 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev) /* hw address of first interface is the orig mac because only * this mac is known throughout the mesh */ memcpy(bcast_packet->orig, mainIfAddr, ETH_ALEN); + /* set broadcast sequence number */ bcast_packet->seqno = htons(bcast_seqno); bcast_seqno++; /* broadcast packet */ - add_bcast_packet_to_list(skb->data, skb->len); + add_bcast_packet_to_list(skb); + /* a copy is stored in the bcast list, therefore removing + * the original skb. */ + kfree_skb(skb); /* unicast packet */ } else { - - /* simply spin_lock()ing can deadlock when the lock is already - * hold. */ - /* TODO: defer the work in a working queue instead of - * dropping */ - if (!spin_trylock(&orig_hash_lock)) { - lock_dropped++; - debug_log(LOG_TYPE_NOTICE, "%d packets dropped because lock was hold\n", lock_dropped); - goto dropped; - } - + spin_lock_irqsave(&orig_hash_lock, flags); /* get routing information */ orig_node = ((struct orig_node *)hash_find(orig_hash, ethhdr->h_dest)); @@ -244,14 +246,17 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev) if (orig_node->batman_if->if_active != IF_ACTIVE) goto unlock; - send_raw_packet(skb->data, skb->len, - orig_node->batman_if, - orig_node->router->addr); + /* don't lock while sending the packets ... we therefore + * copy the required data before sending */ + + batman_if = orig_node->batman_if; + memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); + spin_unlock_irqrestore(&orig_hash_lock, flags); + + send_skb_packet(skb, batman_if, dstaddr); } else { goto unlock; } - - spin_unlock(&orig_hash_lock); } priv->stats.tx_packets++; @@ -259,42 +264,44 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev) goto end; unlock: - spin_unlock(&orig_hash_lock); + spin_unlock_irqrestore(&orig_hash_lock, flags); dropped: priv->stats.tx_dropped++; end: - kfree_skb(skb); - return 0; + return NETDEV_TX_OK; } -void interface_rx(struct net_device *dev, void *packet, int packet_len) +void interface_rx(struct sk_buff *skb, int hdr_size) { - struct sk_buff *skb; + struct net_device *dev = soft_device; struct bat_priv *priv = netdev_priv(dev); - skb = dev_alloc_skb(packet_len); - - if (!skb) { - priv->stats.rx_dropped++; - goto out; + /* check if enough space is available for pulling, and pull */ + if (!pskb_may_pull(skb, hdr_size)) { + kfree_skb(skb); + return; } + skb_pull_rcsum(skb, hdr_size); +/* skb_set_mac_header(skb, -sizeof(struct ethhdr));*/ - memcpy(skb_put(skb, packet_len), packet, packet_len); - - /* Write metadata, and then pass to the receive level */ skb->dev = dev; skb->protocol = eth_type_trans(skb, dev); - skb->ip_summed = CHECKSUM_UNNECESSARY; + + /* should not be neccesary anymore as we use skb_pull_rcsum() + * TODO: please verify this and remove this TODO + * -- Dec 21st 2009, Simon Wunderlich */ + +/* skb->ip_summed = CHECKSUM_UNNECESSARY;*/ + + /* TODO: set skb->pkt_type to PACKET_BROADCAST, PACKET_MULTICAST, + * PACKET_OTHERHOST or PACKET_HOST */ priv->stats.rx_packets++; - priv->stats.rx_bytes += packet_len; + priv->stats.rx_bytes += skb->len; dev->last_rx = jiffies; netif_rx(skb); - -out: - return; } /* ethtool */ @@ -330,7 +337,6 @@ static u32 bat_get_msglevel(struct net_device *dev) static void bat_set_msglevel(struct net_device *dev, u32 value) { - return; } static u32 bat_get_link(struct net_device *dev) diff --git a/drivers/staging/batman-adv/soft-interface.h b/drivers/staging/batman-adv/soft-interface.h index 515e276..c0cad81 100644 --- a/drivers/staging/batman-adv/soft-interface.h +++ b/drivers/staging/batman-adv/soft-interface.h @@ -28,6 +28,7 @@ struct net_device_stats *interface_stats(struct net_device *dev); int interface_set_mac_addr(struct net_device *dev, void *addr); int interface_change_mtu(struct net_device *dev, int new_mtu); int interface_tx(struct sk_buff *skb, struct net_device *dev); -void interface_rx(struct net_device *dev, void *packet, int packet_len); +void interface_rx(struct sk_buff *skb, int hdr_size); +int my_skb_push(struct sk_buff *skb, unsigned int len); extern unsigned char mainIfAddr[]; diff --git a/drivers/staging/batman-adv/translation-table.c b/drivers/staging/batman-adv/translation-table.c index c2190e1..d56f665 100644 --- a/drivers/staging/batman-adv/translation-table.c +++ b/drivers/staging/batman-adv/translation-table.c @@ -21,11 +21,9 @@ #include "main.h" #include "translation-table.h" -#include "log.h" #include "soft-interface.h" #include "types.h" #include "hash.h" -#include "compat.h" struct hashtable_t *hna_local_hash; static struct hashtable_t *hna_global_hash; @@ -62,7 +60,6 @@ void hna_local_add(uint8_t *addr) struct hna_local_entry *hna_local_entry; struct hna_global_entry *hna_global_entry; struct hashtable_t *swaphash; - char hna_str[ETH_STR_LEN]; unsigned long flags; spin_lock_irqsave(&hna_local_hash_lock, flags); @@ -75,19 +72,17 @@ void hna_local_add(uint8_t *addr) return; } - addr_to_string(hna_str, addr); - /* only announce as many hosts as possible in the batman-packet and space in batman_packet->num_hna That also should give a limit to MAC-flooding. */ if ((num_hna + 1 > (ETH_DATA_LEN - BAT_PACKET_LEN) / ETH_ALEN) || (num_hna + 1 > 255)) { - debug_log(LOG_TYPE_ROUTES, "Can't add new local hna entry (%s): number of local hna entries exceeds packet size \n", hna_str); + bat_dbg(DBG_ROUTES, "Can't add new local hna entry (%pM): number of local hna entries exceeds packet size \n", addr); return; } - debug_log(LOG_TYPE_ROUTES, "Creating new local hna entry: %s \n", - hna_str); + bat_dbg(DBG_ROUTES, "Creating new local hna entry: %pM \n", + addr); hna_local_entry = kmalloc(sizeof(struct hna_local_entry), GFP_ATOMIC); if (!hna_local_entry) @@ -113,7 +108,7 @@ void hna_local_add(uint8_t *addr) hna_local_hash->size * 2); if (swaphash == NULL) - debug_log(LOG_TYPE_CRIT, "Couldn't resize local hna hash table \n"); + printk(KERN_ERR "batman-adv:Couldn't resize local hna hash table \n"); else hna_local_hash = swaphash; } @@ -135,18 +130,18 @@ void hna_local_add(uint8_t *addr) int hna_local_fill_buffer(unsigned char *buff, int buff_len) { struct hna_local_entry *hna_local_entry; - struct hash_it_t *hashit = NULL; + HASHIT(hashit); int i = 0; unsigned long flags; spin_lock_irqsave(&hna_local_hash_lock, flags); - while (NULL != (hashit = hash_iterate(hna_local_hash, hashit))) { + while (hash_iterate(hna_local_hash, &hashit)) { if (buff_len < (i + 1) * ETH_ALEN) break; - hna_local_entry = hashit->bucket->data; + hna_local_entry = hashit.bucket->data; memcpy(buff + (i * ETH_ALEN), hna_local_entry->addr, ETH_ALEN); i++; @@ -164,18 +159,18 @@ int hna_local_fill_buffer(unsigned char *buff, int buff_len) int hna_local_fill_buffer_text(unsigned char *buff, int buff_len) { struct hna_local_entry *hna_local_entry; - struct hash_it_t *hashit = NULL; + HASHIT(hashit); int bytes_written = 0; unsigned long flags; spin_lock_irqsave(&hna_local_hash_lock, flags); - while (NULL != (hashit = hash_iterate(hna_local_hash, hashit))) { + while (hash_iterate(hna_local_hash, &hashit)) { if (buff_len < bytes_written + ETH_STR_LEN + 4) break; - hna_local_entry = hashit->bucket->data; + hna_local_entry = hashit.bucket->data; bytes_written += snprintf(buff + bytes_written, ETH_STR_LEN + 4, " * %02x:%02x:%02x:%02x:%02x:%02x\n", @@ -202,27 +197,39 @@ static void _hna_local_del(void *data) static void hna_local_del(struct hna_local_entry *hna_local_entry, char *message) { - char hna_str[ETH_STR_LEN]; - - addr_to_string(hna_str, hna_local_entry->addr); - debug_log(LOG_TYPE_ROUTES, "Deleting local hna entry (%s): %s \n", - hna_str, message); + bat_dbg(DBG_ROUTES, "Deleting local hna entry (%pM): %s \n", + hna_local_entry->addr, message); hash_remove(hna_local_hash, hna_local_entry->addr); _hna_local_del(hna_local_entry); } +void hna_local_remove(uint8_t *addr, char *message) +{ + struct hna_local_entry *hna_local_entry; + unsigned long flags; + + spin_lock_irqsave(&hna_local_hash_lock, flags); + + hna_local_entry = (struct hna_local_entry *) + hash_find(hna_local_hash, addr); + if (hna_local_entry) + hna_local_del(hna_local_entry, message); + + spin_unlock_irqrestore(&hna_local_hash_lock, flags); +} + void hna_local_purge(struct work_struct *work) { struct hna_local_entry *hna_local_entry; - struct hash_it_t *hashit = NULL; + HASHIT(hashit); unsigned long flags; unsigned long timeout; spin_lock_irqsave(&hna_local_hash_lock, flags); - while (NULL != (hashit = hash_iterate(hna_local_hash, hashit))) { - hna_local_entry = hashit->bucket->data; + while (hash_iterate(hna_local_hash, &hashit)) { + hna_local_entry = hashit.bucket->data; timeout = hna_local_entry->last_seen + ((LOCAL_HNA_TIMEOUT / 1000) * HZ); @@ -264,13 +271,10 @@ void hna_global_add_orig(struct orig_node *orig_node, struct hna_global_entry *hna_global_entry; struct hna_local_entry *hna_local_entry; struct hashtable_t *swaphash; - char hna_str[ETH_STR_LEN], orig_str[ETH_STR_LEN]; int hna_buff_count = 0; unsigned long flags; unsigned char *hna_ptr; - addr_to_string(orig_str, orig_node->orig); - while ((hna_buff_count + 1) * ETH_ALEN <= hna_buff_len) { spin_lock_irqsave(&hna_global_hash_lock, flags); @@ -290,8 +294,9 @@ void hna_global_add_orig(struct orig_node *orig_node, memcpy(hna_global_entry->addr, hna_ptr, ETH_ALEN); - addr_to_string(hna_str, hna_global_entry->addr); - debug_log(LOG_TYPE_ROUTES, "Creating new global hna entry: %s (via %s)\n", hna_str, orig_str); + bat_dbg(DBG_ROUTES, + "Creating new global hna entry: %pM (via %pM)\n", + hna_global_entry->addr, orig_node->orig); spin_lock_irqsave(&hna_global_hash_lock, flags); hash_add(hna_global_hash, hna_global_entry); @@ -316,14 +321,16 @@ void hna_global_add_orig(struct orig_node *orig_node, hna_buff_count++; } - orig_node->hna_buff_len = hna_buff_len; + /* initialize, and overwrite if malloc succeeds */ + orig_node->hna_buff = NULL; + orig_node->hna_buff_len = 0; - if (orig_node->hna_buff_len > 0) { - orig_node->hna_buff = kmalloc(orig_node->hna_buff_len, - GFP_ATOMIC); - memcpy(orig_node->hna_buff, hna_buff, orig_node->hna_buff_len); - } else { - orig_node->hna_buff = NULL; + if (hna_buff_len > 0) { + orig_node->hna_buff = kmalloc(hna_buff_len, GFP_ATOMIC); + if (orig_node->hna_buff) { + memcpy(orig_node->hna_buff, hna_buff, hna_buff_len); + orig_node->hna_buff_len = hna_buff_len; + } } spin_lock_irqsave(&hna_global_hash_lock, flags); @@ -333,7 +340,7 @@ void hna_global_add_orig(struct orig_node *orig_node, hna_global_hash->size * 2); if (swaphash == NULL) - debug_log(LOG_TYPE_CRIT, "Couldn't resize global hna hash table \n"); + printk(KERN_ERR "batman-adv:Couldn't resize global hna hash table \n"); else hna_global_hash = swaphash; } @@ -344,17 +351,17 @@ void hna_global_add_orig(struct orig_node *orig_node, int hna_global_fill_buffer_text(unsigned char *buff, int buff_len) { struct hna_global_entry *hna_global_entry; - struct hash_it_t *hashit = NULL; + HASHIT(hashit); int bytes_written = 0; unsigned long flags; spin_lock_irqsave(&hna_global_hash_lock, flags); - while (NULL != (hashit = hash_iterate(hna_global_hash, hashit))) { + while (hash_iterate(hna_global_hash, &hashit)) { if (buff_len < bytes_written + (2 * ETH_STR_LEN) + 10) break; - hna_global_entry = hashit->bucket->data; + hna_global_entry = hashit.bucket->data; bytes_written += snprintf(buff + bytes_written, (2 * ETH_STR_LEN) + 10, @@ -381,12 +388,9 @@ int hna_global_fill_buffer_text(unsigned char *buff, int buff_len) void _hna_global_del_orig(struct hna_global_entry *hna_global_entry, char *message) { - char hna_str[ETH_STR_LEN], orig_str[ETH_STR_LEN]; - - addr_to_string(orig_str, hna_global_entry->orig_node->orig); - addr_to_string(hna_str, hna_global_entry->addr); - - debug_log(LOG_TYPE_ROUTES, "Deleting global hna entry %s (via %s): %s \n", hna_str, orig_str, message); + bat_dbg(DBG_ROUTES, "Deleting global hna entry %pM (via %pM): %s \n", + hna_global_entry->addr, hna_global_entry->orig_node->orig, + message); hash_remove(hna_global_hash, hna_global_entry->addr); kfree(hna_global_entry); diff --git a/drivers/staging/batman-adv/translation-table.h b/drivers/staging/batman-adv/translation-table.h index f7da811..281125b 100644 --- a/drivers/staging/batman-adv/translation-table.h +++ b/drivers/staging/batman-adv/translation-table.h @@ -23,6 +23,7 @@ int hna_local_init(void); void hna_local_add(uint8_t *addr); +void hna_local_remove(uint8_t *addr, char *message); int hna_local_fill_buffer(unsigned char *buff, int buff_len); int hna_local_fill_buffer_text(unsigned char *buff, int buff_len); void hna_local_purge(struct work_struct *work); diff --git a/drivers/staging/batman-adv/types.h b/drivers/staging/batman-adv/types.h index 3a0ef0c..dec1b54 100644 --- a/drivers/staging/batman-adv/types.h +++ b/drivers/staging/batman-adv/types.h @@ -39,7 +39,6 @@ struct batman_if { char if_active; char addr_str[ETH_STR_LEN]; struct net_device *net_dev; - struct socket *raw_sock; atomic_t seqno; unsigned char *packet_buff; int packet_len; @@ -75,7 +74,7 @@ struct neigh_node { uint8_t tq_index; uint8_t tq_avg; uint8_t last_ttl; - unsigned long last_valid; /* when last packet via this neighbour was received */ + unsigned long last_valid; /* when last packet via this neighbor was received */ TYPE_OF_WORD real_bits[NUM_WORDS]; struct orig_node *orig_node; struct batman_if *if_incoming; @@ -113,6 +112,7 @@ struct forw_packet { /* structure for forw_list maintaining packet struct hlist_node list; unsigned long send_time; uint8_t own; + struct sk_buff *skb; unsigned char *packet_buff; uint16_t packet_len; uint32_t direct_link_flags; @@ -121,4 +121,14 @@ struct forw_packet { /* structure for forw_list maintaining packet struct batman_if *if_incoming; }; +/* While scanning for vis-entries of a particular vis-originator + * this list collects its interfaces to create a subgraph/cluster + * out of them later + */ +struct if_list_entry { + uint8_t addr[ETH_ALEN]; + bool primary; + struct hlist_node list; +}; + #endif diff --git a/drivers/staging/batman-adv/vis.c b/drivers/staging/batman-adv/vis.c index f6c9acb..fedec1b 100644 --- a/drivers/staging/batman-adv/vis.c +++ b/drivers/staging/batman-adv/vis.c @@ -23,11 +23,9 @@ #include "send.h" #include "translation-table.h" #include "vis.h" -#include "log.h" #include "soft-interface.h" #include "hard-interface.h" #include "hash.h" -#include "compat.h" struct hashtable_t *vis_hash; DEFINE_SPINLOCK(vis_hash_lock); @@ -50,39 +48,6 @@ static void free_info(void *data) kfree(info); } -/* set the mode of the visualization to client or server */ -void vis_set_mode(int mode) -{ - spin_lock(&vis_hash_lock); - - if (my_vis_info != NULL) - my_vis_info->packet.vis_type = mode; - - spin_unlock(&vis_hash_lock); -} - -/* is_vis_server(), locked outside */ -static int is_vis_server_locked(void) -{ - if (my_vis_info != NULL) - if (my_vis_info->packet.vis_type == VIS_TYPE_SERVER_SYNC) - return 1; - - return 0; -} - -/* get the current set mode */ -int is_vis_server(void) -{ - int ret = 0; - - spin_lock(&vis_hash_lock); - ret = is_vis_server_locked(); - spin_unlock(&vis_hash_lock); - - return ret; -} - /* Compare two vis packets, used by the hashing algorithm */ static int vis_info_cmp(void *data1, void *data2) { @@ -115,6 +80,68 @@ static int vis_info_choose(void *data, int size) return hash % size; } +/* insert interface to the list of interfaces of one originator, if it + * does not already exist in the list */ +static void proc_vis_insert_interface(const uint8_t *interface, + struct hlist_head *if_list, + bool primary) +{ + struct if_list_entry *entry; + struct hlist_node *pos; + + hlist_for_each_entry(entry, pos, if_list, list) { + if (compare_orig(entry->addr, (void *)interface)) + return; + } + + /* its a new address, add it to the list */ + entry = kmalloc(sizeof(*entry), GFP_KERNEL); + if (!entry) + return; + memcpy(entry->addr, interface, ETH_ALEN); + entry->primary = primary; + hlist_add_head(&entry->list, if_list); +} + +void proc_vis_read_prim_sec(struct seq_file *seq, + struct hlist_head *if_list) +{ + struct if_list_entry *entry; + struct hlist_node *pos, *n; + char tmp_addr_str[ETH_STR_LEN]; + + hlist_for_each_entry_safe(entry, pos, n, if_list, list) { + if (entry->primary) { + seq_printf(seq, "PRIMARY, "); + } else { + addr_to_string(tmp_addr_str, entry->addr); + seq_printf(seq, "SEC %s, ", tmp_addr_str); + } + + hlist_del(&entry->list); + kfree(entry); + } +} + +/* read an entry */ +void proc_vis_read_entry(struct seq_file *seq, + struct vis_info_entry *entry, + struct hlist_head *if_list, + uint8_t *vis_orig) +{ + char to[40]; + + addr_to_string(to, entry->dest); + if (entry->quality == 0) { + proc_vis_insert_interface(vis_orig, if_list, true); + seq_printf(seq, "HNA %s, ", to); + } else { + proc_vis_insert_interface(entry->src, if_list, + compare_orig(entry->src, vis_orig)); + seq_printf(seq, "TQ %s %d, ", to, entry->quality); + } +} + /* tries to add one entry to the receive list. */ static void recv_list_add(struct list_head *recv_list, char *mac) { @@ -208,21 +235,23 @@ void receive_server_sync_packet(struct vis_packet *vis_packet, int vis_info_len) { struct vis_info *info; int is_new; + unsigned long flags; + int vis_server = atomic_read(&vis_mode); - spin_lock(&vis_hash_lock); + spin_lock_irqsave(&vis_hash_lock, flags); info = add_packet(vis_packet, vis_info_len, &is_new); if (info == NULL) goto end; /* only if we are server ourselves and packet is newer than the one in * hash.*/ - if (is_vis_server_locked() && is_new) { + if (vis_server == VIS_TYPE_SERVER_SYNC && is_new) { memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN); if (list_empty(&info->send_list)) list_add_tail(&info->send_list, &send_list); } end: - spin_unlock(&vis_hash_lock); + spin_unlock_irqrestore(&vis_hash_lock, flags); } /* handle an incoming client update packet and schedule forward if needed. */ @@ -231,12 +260,14 @@ void receive_client_update_packet(struct vis_packet *vis_packet, { struct vis_info *info; int is_new; + unsigned long flags; + int vis_server = atomic_read(&vis_mode); /* clients shall not broadcast. */ if (is_bcast(vis_packet->target_orig)) return; - spin_lock(&vis_hash_lock); + spin_lock_irqsave(&vis_hash_lock, flags); info = add_packet(vis_packet, vis_info_len, &is_new); if (info == NULL) goto end; @@ -244,7 +275,7 @@ void receive_client_update_packet(struct vis_packet *vis_packet, /* send only if we're the target server or ... */ - if (is_vis_server_locked() && + if (vis_server == VIS_TYPE_SERVER_SYNC && is_my_mac(info->packet.target_orig) && is_new) { info->packet.vis_type = VIS_TYPE_SERVER_SYNC; /* upgrade! */ @@ -258,7 +289,7 @@ void receive_client_update_packet(struct vis_packet *vis_packet, list_add_tail(&info->send_list, &send_list); } end: - spin_unlock(&vis_hash_lock); + spin_unlock_irqrestore(&vis_hash_lock, flags); } /* Walk the originators and find the VIS server with the best tq. Set the packet @@ -267,12 +298,12 @@ end: * Must be called with the originator hash locked */ static int find_best_vis_server(struct vis_info *info) { - struct hash_it_t *hashit = NULL; + HASHIT(hashit); struct orig_node *orig_node; int best_tq = -1; - while (NULL != (hashit = hash_iterate(orig_hash, hashit))) { - orig_node = hashit->bucket->data; + while (hash_iterate(orig_hash, &hashit)) { + orig_node = hashit.bucket->data; if ((orig_node != NULL) && (orig_node->router != NULL) && (orig_node->flags & VIS_SERVER) && @@ -298,7 +329,8 @@ static bool vis_packet_full(struct vis_info *info) * returns 0 on success, -1 if no packet could be generated */ static int generate_vis_packet(void) { - struct hash_it_t *hashit = NULL; + HASHIT(hashit_local); + HASHIT(hashit_global); struct orig_node *orig_node; struct vis_info *info = (struct vis_info *)my_vis_info; struct vis_info_entry *entry, *entry_array; @@ -307,27 +339,27 @@ static int generate_vis_packet(void) unsigned long flags; info->first_seen = jiffies; + info->packet.vis_type = atomic_read(&vis_mode); - spin_lock(&orig_hash_lock); + spin_lock_irqsave(&orig_hash_lock, flags); memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN); info->packet.ttl = TTL; info->packet.seqno++; info->packet.entries = 0; - if (!is_vis_server_locked()) { + if (info->packet.vis_type == VIS_TYPE_CLIENT_UPDATE) { best_tq = find_best_vis_server(info); if (best_tq < 0) { - spin_unlock(&orig_hash_lock); + spin_unlock_irqrestore(&orig_hash_lock, flags); return -1; } } - hashit = NULL; entry_array = (struct vis_info_entry *) ((char *)info + sizeof(struct vis_info)); - while (NULL != (hashit = hash_iterate(orig_hash, hashit))) { - orig_node = hashit->bucket->data; + while (hash_iterate(orig_hash, &hashit_global)) { + orig_node = hashit_global.bucket->data; if (orig_node->router != NULL && compare_orig(orig_node->router->addr, orig_node->orig) && orig_node->batman_if @@ -342,18 +374,17 @@ static int generate_vis_packet(void) info->packet.entries++; if (vis_packet_full(info)) { - spin_unlock(&orig_hash_lock); + spin_unlock_irqrestore(&orig_hash_lock, flags); return 0; } } } - spin_unlock(&orig_hash_lock); + spin_unlock_irqrestore(&orig_hash_lock, flags); - hashit = NULL; spin_lock_irqsave(&hna_local_hash_lock, flags); - while (NULL != (hashit = hash_iterate(hna_local_hash, hashit))) { - hna_local_entry = hashit->bucket->data; + while (hash_iterate(hna_local_hash, &hashit_local)) { + hna_local_entry = hashit_local.bucket->data; entry = &entry_array[info->packet.entries]; memset(entry->src, 0, ETH_ALEN); memcpy(entry->dest, hna_local_entry->addr, ETH_ALEN); @@ -371,16 +402,16 @@ static int generate_vis_packet(void) static void purge_vis_packets(void) { - struct hash_it_t *hashit = NULL; + HASHIT(hashit); struct vis_info *info; - while (NULL != (hashit = hash_iterate(vis_hash, hashit))) { - info = hashit->bucket->data; + while (hash_iterate(vis_hash, &hashit)) { + info = hashit.bucket->data; if (info == my_vis_info) /* never purge own data. */ continue; if (time_after(jiffies, - info->first_seen + (VIS_TIMEOUT/1000)*HZ)) { - hash_remove_bucket(vis_hash, hashit); + info->first_seen + (VIS_TIMEOUT*HZ)/1000)) { + hash_remove_bucket(vis_hash, &hashit); free_info(info); } } @@ -388,14 +419,15 @@ static void purge_vis_packets(void) static void broadcast_vis_packet(struct vis_info *info, int packet_length) { - struct hash_it_t *hashit = NULL; + HASHIT(hashit); struct orig_node *orig_node; + unsigned long flags; - spin_lock(&orig_hash_lock); + spin_lock_irqsave(&orig_hash_lock, flags); /* send to all routers in range. */ - while (NULL != (hashit = hash_iterate(orig_hash, hashit))) { - orig_node = hashit->bucket->data; + while (hash_iterate(orig_hash, &hashit)) { + orig_node = hashit.bucket->data; /* if it's a vis server and reachable, send it. */ if (orig_node && @@ -418,14 +450,15 @@ static void broadcast_vis_packet(struct vis_info *info, int packet_length) } } memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN); - spin_unlock(&orig_hash_lock); + spin_unlock_irqrestore(&orig_hash_lock, flags); } static void unicast_vis_packet(struct vis_info *info, int packet_length) { struct orig_node *orig_node; + unsigned long flags; - spin_lock(&orig_hash_lock); + spin_lock_irqsave(&orig_hash_lock, flags); orig_node = ((struct orig_node *) hash_find(orig_hash, info->packet.target_orig)); @@ -436,7 +469,7 @@ static void unicast_vis_packet(struct vis_info *info, int packet_length) orig_node->batman_if, orig_node->router->addr); } - spin_unlock(&orig_hash_lock); + spin_unlock_irqrestore(&orig_hash_lock, flags); } /* only send one vis packet. called from send_vis_packets() */ @@ -445,8 +478,7 @@ static void send_vis_packet(struct vis_info *info) int packet_length; if (info->packet.ttl < 2) { - debug_log(LOG_TYPE_NOTICE, - "Error - can't send vis packet: ttl exceeded\n"); + printk(KERN_WARNING "batman-adv: Error - can't send vis packet: ttl exceeded\n"); return; } @@ -467,8 +499,9 @@ static void send_vis_packet(struct vis_info *info) static void send_vis_packets(struct work_struct *work) { struct vis_info *info, *temp; + unsigned long flags; - spin_lock(&vis_hash_lock); + spin_lock_irqsave(&vis_hash_lock, flags); purge_vis_packets(); if (generate_vis_packet() == 0) @@ -479,7 +512,7 @@ static void send_vis_packets(struct work_struct *work) list_del_init(&info->send_list); send_vis_packet(info); } - spin_unlock(&vis_hash_lock); + spin_unlock_irqrestore(&vis_hash_lock, flags); start_vis_timer(); } static DECLARE_DELAYED_WORK(vis_timer_wq, send_vis_packets); @@ -488,20 +521,21 @@ static DECLARE_DELAYED_WORK(vis_timer_wq, send_vis_packets); * initialized (e.g. bat0 is initialized, interfaces have been added) */ int vis_init(void) { + unsigned long flags; if (vis_hash) return 1; - spin_lock(&vis_hash_lock); + spin_lock_irqsave(&vis_hash_lock, flags); vis_hash = hash_new(256, vis_info_cmp, vis_info_choose); if (!vis_hash) { - debug_log(LOG_TYPE_CRIT, "Can't initialize vis_hash\n"); + printk(KERN_ERR "batman-adv:Can't initialize vis_hash\n"); goto err; } my_vis_info = kmalloc(1000, GFP_ATOMIC); if (!my_vis_info) { - debug_log(LOG_TYPE_CRIT, "Can't initialize vis packet\n"); + printk(KERN_ERR "batman-adv:Can't initialize vis packet\n"); goto err; } @@ -511,7 +545,6 @@ int vis_init(void) INIT_LIST_HEAD(&my_vis_info->send_list); my_vis_info->packet.version = COMPAT_VERSION; my_vis_info->packet.packet_type = BAT_VIS; - my_vis_info->packet.vis_type = VIS_TYPE_CLIENT_UPDATE; my_vis_info->packet.ttl = TTL; my_vis_info->packet.seqno = 0; my_vis_info->packet.entries = 0; @@ -522,19 +555,19 @@ int vis_init(void) memcpy(my_vis_info->packet.sender_orig, mainIfAddr, ETH_ALEN); if (hash_add(vis_hash, my_vis_info) < 0) { - debug_log(LOG_TYPE_CRIT, - "Can't add own vis packet into hash\n"); + printk(KERN_ERR + "batman-adv:Can't add own vis packet into hash\n"); free_info(my_vis_info); /* not in hash, need to remove it * manually. */ goto err; } - spin_unlock(&vis_hash_lock); + spin_unlock_irqrestore(&vis_hash_lock, flags); start_vis_timer(); return 1; err: - spin_unlock(&vis_hash_lock); + spin_unlock_irqrestore(&vis_hash_lock, flags); vis_quit(); return 0; } @@ -542,23 +575,23 @@ err: /* shutdown vis-server */ void vis_quit(void) { + unsigned long flags; if (!vis_hash) return; cancel_delayed_work_sync(&vis_timer_wq); - spin_lock(&vis_hash_lock); + spin_lock_irqsave(&vis_hash_lock, flags); /* properly remove, kill timers ... */ hash_delete(vis_hash, free_info); vis_hash = NULL; my_vis_info = NULL; - spin_unlock(&vis_hash_lock); + spin_unlock_irqrestore(&vis_hash_lock, flags); } /* schedule packets for (re)transmission */ static void start_vis_timer(void) { queue_delayed_work(bat_event_workqueue, &vis_timer_wq, - (atomic_read(&vis_interval)/1000) * HZ); + (atomic_read(&vis_interval) * HZ) / 1000); } - diff --git a/drivers/staging/batman-adv/vis.h b/drivers/staging/batman-adv/vis.h index 276faba..0cdafde 100644 --- a/drivers/staging/batman-adv/vis.h +++ b/drivers/staging/batman-adv/vis.h @@ -45,16 +45,15 @@ struct recvlist_node { uint8_t mac[ETH_ALEN]; }; -enum vis_formats { - DOT_DRAW, - JSON, -}; - extern struct hashtable_t *vis_hash; extern spinlock_t vis_hash_lock; -void vis_set_mode(int mode); -int is_vis_server(void); +void proc_vis_read_entry(struct seq_file *seq, + struct vis_info_entry *entry, + struct hlist_head *if_list, + uint8_t *vis_orig); +void proc_vis_read_prim_sec(struct seq_file *seq, + struct hlist_head *if_list); void receive_server_sync_packet(struct vis_packet *vis_packet, int vis_info_len); void receive_client_update_packet(struct vis_packet *vis_packet, diff --git a/drivers/staging/comedi/comedi_compat32.c b/drivers/staging/comedi/comedi_compat32.c index a9fdcda..581aa5f 100644 --- a/drivers/staging/comedi/comedi_compat32.c +++ b/drivers/staging/comedi/comedi_compat32.c @@ -26,7 +26,6 @@ #define __NO_VERSION__ #include "comedi.h" -#include <linux/smp_lock.h> #include <linux/uaccess.h> #include "comedi_compat32.h" diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 8117748..aca9674 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -63,7 +63,7 @@ module_param(comedi_debug, int, 0644); int comedi_autoconfig = 1; module_param(comedi_autoconfig, bool, 0444); -int comedi_num_legacy_minors = 0; +int comedi_num_legacy_minors; module_param(comedi_num_legacy_minors, int, 0444); static DEFINE_SPINLOCK(comedi_file_info_table_lock); @@ -1510,7 +1510,7 @@ static unsigned int comedi_poll(struct file *file, poll_table * wait) } static ssize_t comedi_write(struct file *file, const char *buf, size_t nbytes, - loff_t * offset) + loff_t *offset) { struct comedi_subdevice *s; struct comedi_async *async; @@ -1612,7 +1612,7 @@ done: } static ssize_t comedi_read(struct file *file, char *buf, size_t nbytes, - loff_t * offset) + loff_t *offset) { struct comedi_subdevice *s; struct comedi_async *async; @@ -2004,12 +2004,10 @@ void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s) if (async->cb_mask & s->async->events) { if (comedi_get_subdevice_runflags(s) & SRF_USER) { wake_up_interruptible(&async->wait_head); - if (s->subdev_flags & SDF_CMD_READ) { + if (s->subdev_flags & SDF_CMD_READ) kill_fasync(&dev->async_queue, SIGIO, POLL_IN); - } - if (s->subdev_flags & SDF_CMD_WRITE) { + if (s->subdev_flags & SDF_CMD_WRITE) kill_fasync(&dev->async_queue, SIGIO, POLL_OUT); - } } else { if (async->cb_func) async->cb_func(s->async->events, async->cb_arg); diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index c2a632d..44d6b62 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -44,7 +44,7 @@ #include <linux/cdev.h> #include <linux/dma-mapping.h> -#include <asm/io.h> +#include <linux/io.h> #include <asm/system.h> static int postconfig(struct comedi_device *dev); @@ -99,11 +99,10 @@ static void cleanup_device(struct comedi_device *dev) static void __comedi_device_detach(struct comedi_device *dev) { dev->attached = 0; - if (dev->driver) { + if (dev->driver) dev->driver->detach(dev); - } else { + else printk("BUG: dev->driver=NULL in comedi_device_detach()\n"); - } cleanup_device(dev); } @@ -380,9 +379,8 @@ static int insn_rw_emulate_bits(struct comedi_device *dev, if (ret < 0) return ret; - if (insn->insn == INSN_READ) { + if (insn->insn == INSN_READ) data[0] = (new_data[1] >> (chan - base_bitfield_channel)) & 1; - } return 1; } @@ -429,9 +427,9 @@ int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s, new_size = (new_size + PAGE_SIZE - 1) & PAGE_MASK; /* if no change is required, do nothing */ - if (async->prealloc_buf && async->prealloc_bufsz == new_size) { + if (async->prealloc_buf && async->prealloc_bufsz == new_size) return 0; - } + /* deallocate old buffer */ if (async->prealloc_buf) { vunmap(async->prealloc_buf); @@ -494,9 +492,9 @@ int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s, (void *) get_zeroed_page(GFP_KERNEL); } - if (async->buf_page_list[i].virt_addr == NULL) { + if (async->buf_page_list[i].virt_addr == NULL) break; - } + mem_map_reserve(virt_to_page (async->buf_page_list[i]. virt_addr)); @@ -619,9 +617,9 @@ unsigned int comedi_buf_write_alloc(struct comedi_async *async, { unsigned int free_end = async->buf_read_count + async->prealloc_bufsz; - if ((int)(async->buf_write_alloc_count + nbytes - free_end) > 0) { + if ((int)(async->buf_write_alloc_count + nbytes - free_end) > 0) nbytes = free_end - async->buf_write_alloc_count; - } + async->buf_write_alloc_count += nbytes; /* barrier insures the read of buf_read_count above occurs before we write data to the write-alloc'ed buffer space */ @@ -635,9 +633,9 @@ unsigned int comedi_buf_write_alloc_strict(struct comedi_async *async, { unsigned int free_end = async->buf_read_count + async->prealloc_bufsz; - if ((int)(async->buf_write_alloc_count + nbytes - free_end) > 0) { + if ((int)(async->buf_write_alloc_count + nbytes - free_end) > 0) nbytes = 0; - } + async->buf_write_alloc_count += nbytes; /* barrier insures the read of buf_read_count above occurs before we write data to the write-alloc'ed buffer space */ @@ -657,9 +655,9 @@ unsigned comedi_buf_write_free(struct comedi_async *async, unsigned int nbytes) async->buf_write_count += nbytes; async->buf_write_ptr += nbytes; comedi_buf_munge(async, async->buf_write_count - async->munge_count); - if (async->buf_write_ptr >= async->prealloc_bufsz) { + if (async->buf_write_ptr >= async->prealloc_bufsz) async->buf_write_ptr %= async->prealloc_bufsz; - } + return nbytes; } diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c index 0af12fd..fbc26a0 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c @@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY 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 -You shoud also find the complete GPL in the COPYING file accompanying this source code. +You should also find the complete GPL in the COPYING file accompanying this source code. @endverbatim */ diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c index f3e47e5..a6898e4 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c @@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY 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 -You shoud also find the complete GPL in the COPYING file accompanying this source code. +You should also find the complete GPL in the COPYING file accompanying this source code. @endverbatim */ diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c index a15c952..0e498e9 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c @@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY 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 -You shoud also find the complete GPL in the COPYING file accompanying this source code. +You should also find the complete GPL in the COPYING file accompanying this source code. @endverbatim */ diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c index 0fc2285..204d798 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c @@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY 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 -You shoud also find the complete GPL in the COPYING file accompanying this source code. +You should also find the complete GPL in the COPYING file accompanying this source code. @endverbatim */ diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c index 138a84f..148ce6f 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c @@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY 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 -You shoud also find the complete GPL in the COPYING file accompanying this source code. +You should also find the complete GPL in the COPYING file accompanying this source code. @endverbatim */ diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c index a445dab..6360de5 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c @@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY 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 -You shoud also find the complete GPL in the COPYING file accompanying this source code. +You should also find the complete GPL in the COPYING file accompanying this source code. @endverbatim */ diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c index 7e12544..344df94 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c @@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY 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 -You shoud also find the complete GPL in the COPYING file accompanying this source code. +You should also find the complete GPL in the COPYING file accompanying this source code. @endverbatim */ diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c index d3d78d3..de6f772 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c @@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY 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 -You shoud also find the complete GPL in the COPYING file accompanying this source code. +You should also find the complete GPL in the COPYING file accompanying this source code. @endverbatim */ diff --git a/drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.c b/drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.c index 6e9e7ed..97c10aa 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.c @@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY 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 -You shoud also find the complete GPL in the COPYING file accompanying this source code. +You should also find the complete GPL in the COPYING file accompanying this source code. @endverbatim */ @@ -173,11 +173,10 @@ int i_AddiHeaderRW_ReadEeprom(int i_NbOfWordsToRead, } while (dw_eeprom_busy == EEPROM_BUSY); /* Select the upper address part */ - if (i_Counter == 0) { + if (i_Counter == 0) b_ReadLowByte = pb_ReadByte[0]; - } else { + else b_ReadHighByte = pb_ReadByte[0]; - } /* Sleep */ msleep(1); diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index a56535f..8db5ab6 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY 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 -You shoud also find the complete GPL in the COPYING file accompanying this source code. +You should also find the complete GPL in the COPYING file accompanying this source code. @endverbatim */ diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.h b/drivers/staging/comedi/drivers/addi-data/addi_common.h index 3ab27cf..caeb6fd 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.h +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.h @@ -77,8 +77,8 @@ struct addi_board { int i_NbrAoChannel; /* num of D/A chans */ int i_AiMaxdata; /* resolution of A/D */ int i_AoMaxdata; /* resolution of D/A */ - const struct comedi_lrange *pr_AiRangelist; /* rangelist for A/D */ - const struct comedi_lrange *pr_AoRangelist; /* rangelist for D/A */ + const struct comedi_lrange *pr_AiRangelist; /* rangelist for A/D */ + const struct comedi_lrange *pr_AoRangelist; /* rangelist for D/A */ int i_NbrDiChannel; /* Number of DI channels */ int i_NbrDoChannel; /* Number of DO channels */ diff --git a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c index 69b4273..bea329f 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c @@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY 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 -You shoud also find the complete GPL in the COPYING file accompanying this source code. +You should also find the complete GPL in the COPYING file accompanying this source code. @endverbatim */ diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c index 47517a9..d7d768e 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c @@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY 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 -You shoud also find the complete GPL in the COPYING file accompanying this source code. +You should also find the complete GPL in the COPYING file accompanying this source code. @endverbatim */ diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c index 016721e..7912972 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c @@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY 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 -You shoud also find the complete GPL in the COPYING file accompanying this source code. +You should also find the complete GPL in the COPYING file accompanying this source code. @endverbatim */ diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c index 723a97b..fe06789 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c @@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY 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 -You shoud also find the complete GPL in the COPYING file accompanying this source code. +You should also find the complete GPL in the COPYING file accompanying this source code. @endverbatim */ @@ -54,7 +54,7 @@ You shoud also find the complete GPL in the COPYING file accompanying this sourc #include "hwdrv_apci1032.h" #include <linux/delay.h> /* Global variables */ -unsigned int ui_InterruptStatus = 0; +unsigned int ui_InterruptStatus; /* +----------------------------------------------------------------------------+ @@ -108,9 +108,9 @@ int i_APCI1032_ConfigDigitalInput(struct comedi_device *dev, struct comedi_subde ui_TmpValue = inl(devpriv->iobase + APCI1032_DIGITAL_IP_IRQ); } /* if (data[1] == ADDIDATA_OR) */ - else { + else outl(0x6, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ); - } /* else if(data[1] == ADDIDATA_OR) */ + /* else if(data[1] == ADDIDATA_OR) */ } /* if( data[0] == ADDIDATA_ENABLE) */ else { ul_Command1 = ul_Command1 & 0xFFFF0000; @@ -221,9 +221,9 @@ int i_APCI1032_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_sub } /* switch(ui_NoOfChannels) */ } /* if(data[1]==0) */ else { - if (data[1] == 1) { + if (data[1] == 1) *data = ui_InterruptStatus; - } /* if(data[1]==1) */ + /* if(data[1]==1) */ } /* else if(data[1]==0) */ return insn->n; } diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c index 36b929f..d5e06ad 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c @@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY 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 -You shoud also find the complete GPL in the COPYING file accompanying this source code. +You should also find the complete GPL in the COPYING file accompanying this source code. @endverbatim */ diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c index 866eb8d..7948c41 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c @@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY 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 -You shoud also find the complete GPL in the COPYING file accompanying this source code. +You should also find the complete GPL in the COPYING file accompanying this source code. @endverbatim */ diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c index 3ae663b..4413279 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c @@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY 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 -You shoud also find the complete GPL in the COPYING file accompanying this source code. +You should also find the complete GPL in the COPYING file accompanying this source code. @endverbatim */ diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c index 988e3fc..8bc88ad 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c @@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY 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 -You shoud also find the complete GPL in the COPYING file accompanying this source code. +You should also find the complete GPL in the COPYING file accompanying this source code. @endverbatim */ diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c index d348cd5..89783b1eb 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c @@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY 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 -You shoud also find the complete GPL in the COPYING file accompanying this source code. +You should also find the complete GPL in the COPYING file accompanying this source code. @endverbatim */ diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c index ec81708..2d32516 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c @@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY 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 -You shoud also find the complete GPL in the COPYING file accompanying this source code. +You should also find the complete GPL in the COPYING file accompanying this source code. @endverbatim */ diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c index aa159dc..e01889c 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c @@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY 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 -You shoud also find the complete GPL in the COPYING file accompanying this source code. +You should also find the complete GPL in the COPYING file accompanying this source code. @endverbatim */ diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 172fba8..f93ddd4 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY 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 -You shoud also find the complete GPL in the COPYING file accompanying this source code. +You should also find the complete GPL in the COPYING file accompanying this source code. @endverbatim */ @@ -45,7 +45,7 @@ You shoud also find the complete GPL in the COPYING file accompanying this sourc */ #include "hwdrv_apci3120.h" -static unsigned int ui_Temp = 0; +static unsigned int ui_Temp; /* FUNCTION DEFINITIONS */ @@ -98,25 +98,22 @@ int i_APCI3120_InsnConfigAnalogInput(struct comedi_device *dev, struct comedi_su devpriv->b_InterruptMode = APCI3120_EOS_MODE; - if (data[1]) { + if (data[1]) devpriv->b_EocEosInterrupt = APCI3120_ENABLE; - } else + else devpriv->b_EocEosInterrupt = APCI3120_DISABLE; /* Copy channel list and Range List to devpriv */ devpriv->ui_AiNbrofChannels = data[3]; - for (i = 0; i < devpriv->ui_AiNbrofChannels; i++) { + for (i = 0; i < devpriv->ui_AiNbrofChannels; i++) devpriv->ui_AiChannelList[i] = data[4 + i]; - } - } else /* EOC */ - { + } else { /* EOC */ devpriv->b_InterruptMode = APCI3120_EOC_MODE; - if (data[1]) { + if (data[1]) devpriv->b_EocEosInterrupt = APCI3120_ENABLE; - } else { + else devpriv->b_EocEosInterrupt = APCI3120_DISABLE; - } } return insn->n; @@ -166,13 +163,9 @@ int i_APCI3120_InsnReadAnalogInput(struct comedi_device *dev, struct comedi_subd devpriv->us_OutputRegister = 0; /* devpriv->b_DigitalOutputRegister=0; */ - if (insn->unused[0] == 222) /* second insn read */ - { - - for (i = 0; i < insn->n; i++) { + if (insn->unused[0] == 222) { /* second insn read */ + for (i = 0; i < insn->n; i++) data[i] = devpriv->ui_AiReadData[i]; - } - } else { devpriv->tsk_Current = current; /* Save the current process task structure */ /* @@ -519,9 +512,8 @@ int i_APCI3120_CommandTestAnalogInput(struct comedi_device *dev, struct comedi_s /* step 2: make sure trigger sources are unique and mutually compatible */ - if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT) { + if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT) err++; - } if (cmd->scan_begin_src != TRIG_TIMER && cmd->scan_begin_src != TRIG_FOLLOW) @@ -548,16 +540,14 @@ int i_APCI3120_CommandTestAnalogInput(struct comedi_device *dev, struct comedi_s err++; } - if (cmd->scan_begin_src == TRIG_TIMER) /* Test Delay timing */ - { + if (cmd->scan_begin_src == TRIG_TIMER) { /* Test Delay timing */ if (cmd->scan_begin_arg < this_board->ui_MinDelaytimeNs) { cmd->scan_begin_arg = this_board->ui_MinDelaytimeNs; err++; } } - if (cmd->convert_src == TRIG_TIMER) /* Test Acquisition timing */ - { + if (cmd->convert_src == TRIG_TIMER) { /* Test Acquisition timing */ if (cmd->scan_begin_src == TRIG_TIMER) { if ((cmd->convert_arg) && (cmd->convert_arg < @@ -653,11 +643,10 @@ int i_APCI3120_CommandAnalogInput(struct comedi_device *dev, struct comedi_subde /* UPDATE-0.7.57->0.7.68devpriv->ui_AiDataLength=s->async->data_len; */ devpriv->ui_AiDataLength = s->async->prealloc_bufsz; - if (cmd->stop_src == TRIG_COUNT) { + if (cmd->stop_src == TRIG_COUNT) devpriv->ui_AiNbrofScans = cmd->stop_arg; - } else { + else devpriv->ui_AiNbrofScans = 0; - } devpriv->ui_AiTimer0 = 0; /* variables changed to timer0,timer1 */ devpriv->ui_AiTimer1 = 0; @@ -849,9 +838,8 @@ int i_APCI3120_CyclicAnalogInput(int mode, struct comedi_device *dev, } /*** EL241003 End ******************************************************************************/ - if (devpriv->b_ExttrigEnable == APCI3120_ENABLE) { + if (devpriv->b_ExttrigEnable == APCI3120_ENABLE) i_APCI3120_ExttrigEnable(dev); /* activate EXT trigger */ - } switch (mode) { case 1: /* init timer0 in mode 2 */ @@ -1049,12 +1037,10 @@ int i_APCI3120_CyclicAnalogInput(int mode, struct comedi_device *dev, dmalen1 = 4; } } else { /* isn't output buff smaller that our DMA buff? */ - if (dmalen0 > (devpriv->ui_AiDataLength)) { + if (dmalen0 > (devpriv->ui_AiDataLength)) dmalen0 = devpriv->ui_AiDataLength; - } - if (dmalen1 > (devpriv->ui_AiDataLength)) { + if (dmalen1 > (devpriv->ui_AiDataLength)) dmalen1 = devpriv->ui_AiDataLength; - } } devpriv->ui_DmaBufferUsesize[0] = dmalen0; devpriv->ui_DmaBufferUsesize[1] = dmalen1; @@ -1356,11 +1342,10 @@ int i_APCI3120_SetupChannelList(struct comedi_device *dev, struct comedi_subdevi /* store range list to card */ us_TmpValue = CR_CHAN(chanlist[i]); /* get channel number; */ - if (CR_RANGE(chanlist[i]) < APCI3120_BIPOLAR_RANGES) { + if (CR_RANGE(chanlist[i]) < APCI3120_BIPOLAR_RANGES) us_TmpValue &= ((~APCI3120_UNIPOLAR) & 0xff); /* set bipolar */ - } else { + else us_TmpValue |= APCI3120_UNIPOLAR; /* enable unipolar...... */ - } gain = CR_RANGE(chanlist[i]); /* get gain number */ us_TmpValue |= ((gain & 0x03) << 4); /* <<4 for G0 and G1 bit in RAM */ @@ -1514,8 +1499,7 @@ void v_APCI3120_Interrupt(int irq, void *d) /* Check If EOS interrupt */ if ((int_daq & 0x2) && (devpriv->b_InterruptMode == APCI3120_EOS_MODE)) { - if (devpriv->b_EocEosInterrupt == APCI3120_ENABLE) /* enable this in without DMA ??? */ - { + if (devpriv->b_EocEosInterrupt == APCI3120_ENABLE) { /* enable this in without DMA ??? */ if (devpriv->b_AiCyclicAcquisition == APCI3120_ENABLE) { ui_Check = 0; @@ -1966,8 +1950,7 @@ int i_APCI3120_InsnConfigTimer(struct comedi_device *dev, struct comedi_subdevic APCI3120_DISABLE_EOS_INT; outb(devpriv->b_ModeSelectRegister, devpriv->iobase + APCI3120_WRITE_MODE_SELECT); - if (data[0] == APCI3120_TIMER) /* initialize timer */ - { + if (data[0] == APCI3120_TIMER) { /* initialize timer */ /* devpriv->b_ModeSelectRegister=devpriv->b_ModeSelectRegister | * APCI3120_ENABLE_TIMER_INT; */ @@ -2006,8 +1989,7 @@ int i_APCI3120_InsnConfigTimer(struct comedi_device *dev, struct comedi_subdevic /* timer2 in Timer mode enabled */ devpriv->b_Timer2Mode = APCI3120_TIMER; - } else /* Initialize Watch dog */ - { + } else { /* Initialize Watch dog */ /* Set the Timer 2 in mode 5(Watchdog) */ @@ -2092,8 +2074,7 @@ int i_APCI3120_InsnWriteTimer(struct comedi_device *dev, struct comedi_subdevice return -EINVAL; } - if (data[0] == 2) /* write new value */ - { + if (data[0] == 2) { /* write new value */ if (devpriv->b_Timer2Mode != APCI3120_TIMER) { comedi_error(dev, "write :timer2 not configured in TIMER MODE"); @@ -2113,13 +2094,11 @@ int i_APCI3120_InsnWriteTimer(struct comedi_device *dev, struct comedi_subdevice /* Reset FC_TIMER BIT */ inb(devpriv->iobase + APCI3120_TIMER_STATUS_REGISTER); - if (devpriv->b_Timer2Mode == APCI3120_TIMER) /* start timer */ - { + if (devpriv->b_Timer2Mode == APCI3120_TIMER) { /* start timer */ /* Enable Timer */ devpriv->b_ModeSelectRegister = devpriv->b_ModeSelectRegister & 0x0B; - } else /* start watch dog */ - { + } else { /* start watch dog */ /* Enable WatchDog */ devpriv->b_ModeSelectRegister = (devpriv-> @@ -2146,8 +2125,7 @@ int i_APCI3120_InsnWriteTimer(struct comedi_device *dev, struct comedi_subdevice outb(devpriv->b_ModeSelectRegister, devpriv->iobase + APCI3120_WRITE_MODE_SELECT); - if (devpriv->b_Timer2Mode == APCI3120_TIMER) /* start timer */ - { + if (devpriv->b_Timer2Mode == APCI3120_TIMER) { /* start timer */ /* For Timer mode is Gate2 must be activated **timer started */ devpriv->us_OutputRegister = devpriv-> @@ -2299,8 +2277,7 @@ int i_APCI3120_InsnReadTimer(struct comedi_device *dev, struct comedi_subdevice /* combining both words */ data[0] = (unsigned int) ((us_TmpValue) | ((us_TmpValue_2) << 16)); - } else /* Read watch dog status */ - { + } else { /* Read watch dog status */ us_StatusValue = inw(devpriv->iobase + APCI3120_RD_STATUS); us_StatusValue = @@ -2441,10 +2418,9 @@ int i_APCI3120_InsnConfigDigitalOutput(struct comedi_device *dev, devpriv->b_OutputMemoryStatus = APCI3120_DISABLE; devpriv->b_DigitalOutputRegister = 0; } - if (!devpriv->b_OutputMemoryStatus) { + if (!devpriv->b_OutputMemoryStatus) ui_Temp = 0; - - } /* if(!devpriv->b_OutputMemoryStatus ) */ + /* if(!devpriv->b_OutputMemoryStatus ) */ return insn->n; } @@ -2504,23 +2480,23 @@ int i_APCI3120_InsnBitsDigitalOutput(struct comedi_device *dev, /* +----------------------------------------------------------------------------+ -| Function name :int i_APCI3120_InsnWriteDigitalOutput(struct comedi_device *dev,| -|struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) | -| | +| Function name :int i_APCI3120_InsnWriteDigitalOutput(struct comedi_device *dev,| +|struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) | +| | +----------------------------------------------------------------------------+ -| Task : Write digiatl output | -| | +| Task : Write digiatl output | +| | +----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev | -| struct comedi_subdevice *s | -| struct comedi_insn *insn | -| unsigned int *data | - data[0] Value to be written - data[1] :1 Set digital o/p ON - data[1] 2 Set digital o/p OFF with memory ON +| Input Parameters : struct comedi_device *dev | +| struct comedi_subdevice *s | +| struct comedi_insn *insn | +| unsigned int *data | + data[0] Value to be written + data[1] :1 Set digital o/p ON + data[1] 2 Set digital o/p OFF with memory ON +----------------------------------------------------------------------------+ -| Return Value : | -| | +| Return Value : | +| | +----------------------------------------------------------------------------+ */ @@ -2615,8 +2591,7 @@ int i_APCI3120_InsnWriteAnalogOutput(struct comedi_device *dev, ui_Channel = CR_CHAN(insn->chanspec); /* this_board->i_hwdrv_InsnWriteAnalogOutput(dev, ui_Range, ui_Channel,data[0]); */ - if (ui_Range) /* if 1 then unipolar */ - { + if (ui_Range) { /* if 1 then unipolar */ if (data[0] != 0) data[0] = @@ -2627,8 +2602,7 @@ int i_APCI3120_InsnWriteAnalogOutput(struct comedi_device *dev, ((((ui_Channel & 0x03) << 14) & 0xC000) | (1 << 13) | 8192); - } else /* if 0 then bipolar */ - { + } else { /* if 0 then bipolar */ data[0] = ((((ui_Channel & 0x03) << 14) & 0xC000) | (0 << 13) | data[0]); @@ -2639,8 +2613,7 @@ int i_APCI3120_InsnWriteAnalogOutput(struct comedi_device *dev, * out put n values at the given channel. printk("\nwaiting for * DA_READY BIT"); */ - do /* Waiting of DA_READY BIT */ - { + do { /* Waiting of DA_READY BIT */ us_TmpValue = ((unsigned short) inw(devpriv->iobase + APCI3120_RD_STATUS)) & 0x0001; diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c index 98c2387..560c848 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c @@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY 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 -You shoud also find the complete GPL in the COPYING file accompanying this source code. +You should also find the complete GPL in the COPYING file accompanying this source code. @endverbatim */ diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c index 7b38d17..4ed441a 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c @@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY 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 -You shoud also find the complete GPL in the COPYING file accompanying this source code. +You should also find the complete GPL in the COPYING file accompanying this source code. @endverbatim */ diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c index 1d1e5fc..3692326 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c @@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY 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 -You shoud also find the complete GPL in the COPYING file accompanying this source code. +You should also find the complete GPL in the COPYING file accompanying this source code. @endverbatim */ @@ -1206,7 +1206,7 @@ int i_APCI3XXX_InsnWriteTTLIO(struct comedi_device *dev, if (b_Channel < 8) { /*****************************************************************************/ - /* Read port 0 (first digital output port) and set/reset the selcted channel */ + /* Read port 0 (first digital output port) and set/reset the selected channel */ /*****************************************************************************/ dw_Status = inl(devpriv->iobase + 80); @@ -1228,7 +1228,7 @@ int i_APCI3XXX_InsnWriteTTLIO(struct comedi_device *dev, if ((devpriv->ul_TTLPortConfiguration[0] & 0xFF) == 0xFF) { /*****************************************************************************/ - /* Read port 2 (first digital output port) and set/reset the selcted channel */ + /* Read port 2 (first digital output port) and set/reset the selected channel */ /*****************************************************************************/ dw_Status = inl(devpriv->iobase + 112); diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index 791ea83..9934a3c 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -88,9 +88,9 @@ Configuration options: #define IORANGE_9118 64 /* I hope */ #define PCI9118_CHANLEN 255 /* len of chanlist, some source say 256, but reality looks like 255 :-( */ -#define PCI9118_CNT0 0x00 /* R/W: 8254 couter 0 */ -#define PCI9118_CNT1 0x04 /* R/W: 8254 couter 0 */ -#define PCI9118_CNT2 0x08 /* R/W: 8254 couter 0 */ +#define PCI9118_CNT0 0x00 /* R/W: 8254 counter 0 */ +#define PCI9118_CNT1 0x04 /* R/W: 8254 counter 0 */ +#define PCI9118_CNT2 0x08 /* R/W: 8254 counter 0 */ #define PCI9118_CNTCTRL 0x0c /* W: 8254 counter control */ #define PCI9118_AD_DATA 0x10 /* R: A/D data */ #define PCI9118_DA1 0x10 /* W: D/A registers */ diff --git a/drivers/staging/comedi/drivers/adq12b.c b/drivers/staging/comedi/drivers/adq12b.c index c5ed8bb..f3ba645 100644 --- a/drivers/staging/comedi/drivers/adq12b.c +++ b/drivers/staging/comedi/drivers/adq12b.c @@ -42,23 +42,23 @@ If you do not specify any options, they will default to option 1: I/O base address. The following table is provided as a help of the hardware jumpers. - address jumper JADR - 0x300 1 (factory default) - 0x320 2 - 0x340 3 - 0x360 4 - 0x380 5 - 0x3A0 6 + address jumper JADR + 0x300 1 (factory default) + 0x320 2 + 0x340 3 + 0x360 4 + 0x380 5 + 0x3A0 6 option 2: unipolar/bipolar ADC selection: 0 -> bipolar, 1 -> unipolar - selection comedi_config option JUB - bipolar 0 2-3 (factory default) - unipolar 1 1-2 + selection comedi_config option JUB + bipolar 0 2-3 (factory default) + unipolar 1 1-2 option 3: single-ended/differential AI selection: 0 -> SE, 1 -> differential - selection comedi_config option JCHA JCHB + selection comedi_config option JCHA JCHB single-ended 0 1-2 1-2 (factory default) differential 1 2-3 2-3 @@ -140,7 +140,7 @@ static const struct adq12b_board adq12b_boards[] = { .ai_bits = 12, .di_chans = 8, .do_chans = 5 - }*/ + }*/ }; #define thisboard ((const struct adq12b_board *)dev->board_ptr) @@ -164,14 +164,15 @@ struct adq12b_private { static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it); static int adq12b_detach(struct comedi_device *dev); + static struct comedi_driver driver_adq12b = { -driver_name:"adq12b", -module:THIS_MODULE, -attach:adq12b_attach, -detach:adq12b_detach, -board_name:&adq12b_boards[0].name, -offset:sizeof(struct adq12b_board), -num_names:ARRAY_SIZE(adq12b_boards), + .driver_name = "adq12b", + .module = THIS_MODULE, + .attach = adq12b_attach, + .detach = adq12b_detach, + .board_name = &adq12b_boards[0].name, + .offset = sizeof(struct adq12b_board), + .num_names = ARRAY_SIZE(adq12b_boards), }; static int adq12b_ai_rinsn(struct comedi_device *dev, @@ -200,15 +201,16 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it) unipolar = it->options[1]; differential = it->options[2]; - printk("comedi%d: adq12b called with options base=0x%03lx, %s and %s\n", - dev->minor, iobase, (unipolar == 1) ? "unipolar" : "bipolar", + printk(KERN_INFO "comedi%d: adq12b called with options base=0x%03lx, " + "%s and %s\n", dev->minor, iobase, + (unipolar == 1) ? "unipolar" : "bipolar", (differential == 1) ? "differential" : "single-ended"); /* if no address was specified, try the default 0x300 */ if (iobase == 0) { - printk - ("comedi%d: adq12b warning: I/O base address not specified. Trying the default 0x300.\n", - dev->minor); + printk(KERN_WARNING "comedi%d: adq12b warning: I/O base " + "address not specified. Trying the default 0x300.\n", + dev->minor); iobase = 0x300; } @@ -259,11 +261,10 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->n_chan = thisboard->ai_se_chans; } - if (unipolar) { + if (unipolar) s->range_table = &range_adq12b_ai_unipolar; - } else { + else s->range_table = &range_adq12b_ai_bipolar; - } s->maxdata = (1 << thisboard->ai_bits) - 1; @@ -289,7 +290,7 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->range_table = &range_digital; s->insn_bits = adq12b_do_insn_bits; - printk("attached\n"); + printk(KERN_INFO "attached\n"); return 0; } @@ -309,7 +310,7 @@ static int adq12b_detach(struct comedi_device *dev) kfree(devpriv); - printk("comedi%d: adq12b: removed\n", dev->minor); + printk(KERN_INFO "comedi%d: adq12b: removed\n", dev->minor); return 0; } @@ -344,17 +345,18 @@ static int adq12b_ai_rinsn(struct comedi_device *dev, /* wait for end of convertion */ i = 0; do { -/* udelay(1); */ + /* udelay(1); */ status = inb(dev->iobase + ADQ12B_STINR); status = status & ADQ12B_EOC; } while (status == 0 && ++i < TIMEOUT); -/* } while (++i < 10); */ + /* } while (++i < 10); */ /* read data */ hi = inb(dev->iobase + ADQ12B_ADHIG); lo = inb(dev->iobase + ADQ12B_ADLOW); - /* printk("debug: chan=%d range=%d status=%d hi=%d lo=%d\n", channel, range, status, hi, lo); */ + /* printk("debug: chan=%d range=%d status=%d hi=%d lo=%d\n", + channel, range, status, hi, lo); */ data[n] = (hi << 8) | lo; } diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 951e579..394d2ea 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -84,9 +84,9 @@ Configuration options: #define PCI171x_DAREF 14 /* W: D/A reference control */ #define PCI171x_DI 16 /* R: digi inputs */ #define PCI171x_DO 16 /* R: digi inputs */ -#define PCI171x_CNT0 24 /* R/W: 8254 couter 0 */ -#define PCI171x_CNT1 26 /* R/W: 8254 couter 1 */ -#define PCI171x_CNT2 28 /* R/W: 8254 couter 2 */ +#define PCI171x_CNT0 24 /* R/W: 8254 counter 0 */ +#define PCI171x_CNT1 26 /* R/W: 8254 counter 1 */ +#define PCI171x_CNT2 28 /* R/W: 8254 counter 2 */ #define PCI171x_CNTCTRL 30 /* W: 8254 counter control */ /* upper bits from status register (PCI171x_STATUS) (lower is same woth control reg) */ @@ -724,6 +724,7 @@ static int move_block_from_fifo(struct comedi_device *dev, devpriv->ai_act_scan++; } } + s->async->cur_chan = j; DPRINTK("adv_pci1710 EDBG: END: move_block_from_fifo(...)\n"); return 0; } @@ -1034,14 +1035,6 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev, } } - if (!cmd->chanlist_len) { - cmd->chanlist_len = 1; - err++; - } - if (cmd->chanlist_len > this_board->n_aichan) { - cmd->chanlist_len = this_board->n_aichan; - err++; - } if (cmd->scan_end_arg != cmd->chanlist_len) { cmd->scan_end_arg = cmd->chanlist_len; err++; @@ -1230,6 +1223,12 @@ static void setup_channel_list(struct comedi_device *dev, DPRINTK("GS: %2d. [%4x]=%4x %4x\n", i, chanprog, range, devpriv->act_chanlist[i]); } +#ifdef PCI171x_PARANOIDCHECK + for ( ; i < n_chan; i++) { /* store remainder of channel list */ + devpriv->act_chanlist[i] = + (CR_CHAN(chanlist[i]) << 12) & 0xf000; + } +#endif devpriv->ai_et_MuxVal = CR_CHAN(chanlist[0]) | (CR_CHAN(chanlist[seglen - 1]) << 8); diff --git a/drivers/staging/comedi/drivers/aio_iiro_16.c b/drivers/staging/comedi/drivers/aio_iiro_16.c index 3857fd5..4baef9f 100644 --- a/drivers/staging/comedi/drivers/aio_iiro_16.c +++ b/drivers/staging/comedi/drivers/aio_iiro_16.c @@ -98,7 +98,7 @@ static int aio_iiro_16_attach(struct comedi_device *dev, int iobase; struct comedi_subdevice *s; - printk("comedi%d: aio_iiro_16: ", dev->minor); + printk(KERN_INFO "comedi%d: aio_iiro_16: ", dev->minor); dev->board_name = thisboard->name; @@ -140,7 +140,7 @@ static int aio_iiro_16_attach(struct comedi_device *dev, static int aio_iiro_16_detach(struct comedi_device *dev) { - printk("comedi%d: aio_iiro_16: remove\n", dev->minor); + printk(KERN_INFO "comedi%d: aio_iiro_16: remove\n", dev->minor); if (dev->iobase) release_region(dev->iobase, AIO_IIRO_16_SIZE); diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index 69ab281..204f30e 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -48,8 +48,8 @@ Passing a zero for an option is the same as leaving it unspecified. SUBDEVICES - PC218E PC212E PC215E/PCI215 - ------------- ------------- ------------- + PC218E PC212E PC215E/PCI215 + ------------- ------------- ------------- Subdevices 7 6 5 0 CTR-X1 PPI-X PPI-X 1 CTR-X2 CTR-Y1 PPI-Y @@ -59,8 +59,8 @@ SUBDEVICES 5 CTR-Z2 INTERRUPT 6 INTERRUPT - PC214E PC272E/PCI272 - ------------- ------------- + PC214E PC272E/PCI272 + ------------- ------------- Subdevices 4 4 0 PPI-X PPI-X 1 PPI-Y PPI-Y @@ -96,8 +96,8 @@ instructions are supported: 0 to 7 as follows: 0. CLK n, the counter channel's dedicated CLK input from the SK1 - connector. (N.B. for other values, the counter channel's CLKn - pin on the SK1 connector is an output!) + connector. (N.B. for other values, the counter channel's CLKn + pin on the SK1 connector is an output!) 1. Internal 10 MHz clock. 2. Internal 1 MHz clock. 3. Internal 100 kHz clock. @@ -105,8 +105,8 @@ instructions are supported: 5. Internal 1 kHz clock. 6. OUT n-1, the output of counter channel n-1 (see note 1 below). 7. Ext Clock, the counter chip's dedicated Ext Clock input from - the SK1 connector. This pin is shared by all three counter - channels on the chip. + the SK1 connector. This pin is shared by all three counter + channels on the chip. INSN_CONFIG_GET_CLOCK_SRC. Returns the counter channel's current clock source in data[1]. For internal clock sources, data[2] is set @@ -120,10 +120,10 @@ instructions are supported: 0. VCC (internal +5V d.c.), i.e. gate permanently enabled. 1. GND (internal 0V d.c.), i.e. gate permanently disabled. 2. GAT n, the counter channel's dedicated GAT input from the SK1 - connector. (N.B. for other values, the counter channel's GATn - pin on the SK1 connector is an output!) + connector. (N.B. for other values, the counter channel's GATn + pin on the SK1 connector is an output!) 3. /OUT n-2, the inverted output of counter channel n-2 (see note - 2 below). + 2 below). 4. Reserved. 5. Reserved. 6. Reserved. @@ -153,8 +153,8 @@ below. INTERRUPT SOURCES - PC218E PC212E PC215E/PCI215 - ------------- ------------- ------------- + PC218E PC212E PC215E/PCI215 + ------------- ------------- ------------- Sources 6 6 6 0 CTR-X1-OUT PPI-X-C0 PPI-X-C0 1 CTR-X2-OUT PPI-X-C3 PPI-X-C3 @@ -163,8 +163,8 @@ INTERRUPT SOURCES 4 CTR-Z1-OUT CTR-Z1-OUT CTR-Z1-OUT 5 CTR-Z2-OUT CTR-Z2-OUT CTR-Z2-OUT - PC214E PC272E/PCI272 - ------------- ------------- + PC214E PC272E/PCI272 + ------------- ------------- Sources 1 6 0 JUMPER-J5 PPI-X-C0 1 PPI-X-C3 @@ -435,11 +435,13 @@ MODULE_DEVICE_TABLE(pci, dio200_pci_table); * Useful for shorthand access to the particular board structure */ #define thisboard ((const struct dio200_board *)dev->board_ptr) -#define thislayout (&dio200_layouts[((struct dio200_board *)dev->board_ptr)->layout]) +#define thislayout (&dio200_layouts[((struct dio200_board *) \ + dev->board_ptr)->layout]) /* this structure is for data unique to this hardware driver. If several hardware drivers keep similar information in this structure, - feel free to suggest moving the variable to the struct comedi_device struct. */ + feel free to suggest moving the variable to the struct comedi_device struct. + */ struct dio200_private { #ifdef CONFIG_COMEDI_PCI struct pci_dev *pci_dev; /* PCI device */ @@ -603,9 +605,8 @@ static void dio200_stop_intr(struct comedi_device *dev, subpriv->active = 0; subpriv->enabled_isns = 0; - if (subpriv->has_int_sce) { + if (subpriv->has_int_sce) outb(0, subpriv->iobase); - } } /* @@ -629,16 +630,14 @@ static int dio200_start_intr(struct comedi_device *dev, /* Determine interrupt sources to enable. */ isn_bits = 0; if (cmd->chanlist) { - for (n = 0; n < cmd->chanlist_len; n++) { + for (n = 0; n < cmd->chanlist_len; n++) isn_bits |= (1U << CR_CHAN(cmd->chanlist[n])); - } } isn_bits &= subpriv->valid_isns; /* Enable interrupt sources. */ subpriv->enabled_isns = isn_bits; - if (subpriv->has_int_sce) { + if (subpriv->has_int_sce) outb(isn_bits, subpriv->iobase); - } } return retval; @@ -662,14 +661,13 @@ dio200_inttrig_start_intr(struct comedi_device *dev, struct comedi_subdevice *s, spin_lock_irqsave(&subpriv->spinlock, flags); s->async->inttrig = 0; - if (subpriv->active) { + if (subpriv->active) event = dio200_start_intr(dev, s); - } + spin_unlock_irqrestore(&subpriv->spinlock, flags); - if (event) { + if (event) comedi_event(dev, s); - } return 1; } @@ -726,9 +724,8 @@ static int dio200_handle_read_intr(struct comedi_device *dev, * Reenable them NOW to minimize the time they are disabled. */ cur_enabled = subpriv->enabled_isns; - if (subpriv->has_int_sce) { + if (subpriv->has_int_sce) outb(cur_enabled, subpriv->iobase); - } if (subpriv->active) { /* @@ -747,9 +744,8 @@ static int dio200_handle_read_intr(struct comedi_device *dev, len = s->async->cmd.chanlist_len; for (n = 0; n < len; n++) { ch = CR_CHAN(s->async->cmd.chanlist[n]); - if (triggered & (1U << ch)) { + if (triggered & (1U << ch)) val |= (1U << n); - } } /* Write the scan to the buffer. */ if (comedi_buf_put(s->async, val)) { @@ -781,9 +777,8 @@ static int dio200_handle_read_intr(struct comedi_device *dev, } spin_unlock_irqrestore(&subpriv->spinlock, flags); - if (oldevents != s->async->events) { + if (oldevents != s->async->events) comedi_event(dev, s); - } return (triggered != 0); } @@ -798,9 +793,9 @@ static int dio200_subdev_intr_cancel(struct comedi_device *dev, unsigned long flags; spin_lock_irqsave(&subpriv->spinlock, flags); - if (subpriv->active) { + if (subpriv->active) dio200_stop_intr(dev, s); - } + spin_unlock_irqrestore(&subpriv->spinlock, flags); return 0; @@ -846,7 +841,8 @@ dio200_subdev_intr_cmdtest(struct comedi_device *dev, if (err) return 1; - /* step 2: make sure trigger sources are unique and mutually compatible */ + /* step 2: make sure trigger sources are unique and mutually + compatible */ /* these tests are true if more than one _src bit is set */ if ((cmd->start_src & (cmd->start_src - 1)) != 0) @@ -952,9 +948,8 @@ static int dio200_subdev_intr_cmd(struct comedi_device *dev, } spin_unlock_irqrestore(&subpriv->spinlock, flags); - if (event) { + if (event) comedi_event(dev, s); - } return 0; } @@ -980,9 +975,8 @@ dio200_subdev_intr_init(struct comedi_device *dev, struct comedi_subdevice *s, subpriv->valid_isns = valid_isns; spin_lock_init(&subpriv->spinlock); - if (has_int_sce) { + if (has_int_sce) outb(0, subpriv->iobase); /* Disable interrupt sources. */ - } s->private = subpriv; s->type = COMEDI_SUBD_DI; @@ -1013,10 +1007,7 @@ dio200_subdev_intr_cleanup(struct comedi_device *dev, struct comedi_subdevice *s) { struct dio200_subdev_intr *subpriv = s->private; - - if (subpriv) { - kfree(subpriv); - } + kfree(subpriv); } /* @@ -1027,9 +1018,8 @@ static irqreturn_t dio200_interrupt(int irq, void *d) struct comedi_device *dev = d; int handled; - if (!dev->attached) { + if (!dev->attached) return IRQ_NONE; - } if (devpriv->intr_sd >= 0) { handled = dio200_handle_read_intr(dev, @@ -1266,10 +1256,7 @@ dio200_subdev_8254_cleanup(struct comedi_device *dev, struct comedi_subdevice *s) { struct dio200_subdev_intr *subpriv = s->private; - - if (subpriv) { - kfree(subpriv); - } + kfree(subpriv); } /* @@ -1348,9 +1335,8 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) #endif { ret = dio200_request_region(dev->minor, iobase, DIO200_IO_SIZE); - if (ret < 0) { + if (ret < 0) return ret; - } } dev->iobase = iobase; @@ -1371,17 +1357,17 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) ret = dio200_subdev_8254_init(dev, s, iobase, layout->sdinfo[n], layout->has_clk_gat_sce); - if (ret < 0) { + if (ret < 0) return ret; - } + break; case sd_8255: /* digital i/o subdevice (8255) */ ret = subdev_8255_init(dev, s, 0, iobase + layout->sdinfo[n]); - if (ret < 0) { + if (ret < 0) return ret; - } + break; case sd_intr: /* 'INTERRUPT' subdevice */ @@ -1392,9 +1378,9 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) layout->sdinfo[n], layout-> has_int_sce); - if (ret < 0) { + if (ret < 0) return ret; - } + devpriv->intr_sd = n; } else { s->type = COMEDI_SUBD_UNUSED; @@ -1407,9 +1393,8 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) } sdx = devpriv->intr_sd; - if (sdx >= 0 && sdx < dev->n_subdevices) { + if (sdx >= 0 && sdx < dev->n_subdevices) dev->read_subdev = &dev->subdevices[sdx]; - } dev->board_name = thisboard->name; @@ -1434,11 +1419,10 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) printk("(pci %s) ", pci_name(pci_dev)); #endif } - if (irq) { + if (irq) printk("(irq %u%s) ", irq, (dev->irq ? "" : " UNAVAILABLE")); - } else { + else printk("(no irq) "); - } printk("attached\n"); @@ -1461,9 +1445,8 @@ static int dio200_detach(struct comedi_device *dev) printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor, DIO200_DRIVER_NAME); - if (dev->irq) { + if (dev->irq) free_irq(dev->irq, dev); - } if (dev->subdevices) { layout = thislayout; for (n = 0; n < dev->n_subdevices; n++) { @@ -1486,22 +1469,19 @@ static int dio200_detach(struct comedi_device *dev) if (devpriv) { #ifdef CONFIG_COMEDI_PCI if (devpriv->pci_dev) { - if (dev->iobase) { + if (dev->iobase) comedi_pci_disable(devpriv->pci_dev); - } pci_dev_put(devpriv->pci_dev); } else #endif { - if (dev->iobase) { + if (dev->iobase) release_region(dev->iobase, DIO200_IO_SIZE); - } } } - if (dev->board_name) { + if (dev->board_name) printk(KERN_INFO "comedi%d: %s removed\n", dev->minor, dev->board_name); - } return 0; } diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c index 1032a81..a307d68 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236.c +++ b/drivers/staging/comedi/drivers/amplc_pc236.c @@ -78,18 +78,18 @@ unused. */ /* Disable interrupt, also clear any interrupt there */ #define PCI236_INTR_DISABLE (PLX9052_INTCSR_LI1ENAB_DISABLED \ - | PLX9052_INTCSR_LI1POL_HIGH \ - | PLX9052_INTCSR_LI2POL_HIGH \ - | PLX9052_INTCSR_PCIENAB_DISABLED \ - | PLX9052_INTCSR_LI1SEL_EDGE \ - | PLX9052_INTCSR_LI1CLRINT_ASSERTED) + | PLX9052_INTCSR_LI1POL_HIGH \ + | PLX9052_INTCSR_LI2POL_HIGH \ + | PLX9052_INTCSR_PCIENAB_DISABLED \ + | PLX9052_INTCSR_LI1SEL_EDGE \ + | PLX9052_INTCSR_LI1CLRINT_ASSERTED) /* Enable interrupt, also clear any interrupt there. */ #define PCI236_INTR_ENABLE (PLX9052_INTCSR_LI1ENAB_ENABLED \ - | PLX9052_INTCSR_LI1POL_HIGH \ - | PLX9052_INTCSR_LI2POL_HIGH \ - | PLX9052_INTCSR_PCIENAB_ENABLED \ - | PLX9052_INTCSR_LI1SEL_EDGE \ - | PLX9052_INTCSR_LI1CLRINT_ASSERTED) + | PLX9052_INTCSR_LI1POL_HIGH \ + | PLX9052_INTCSR_LI2POL_HIGH \ + | PLX9052_INTCSR_PCIENAB_ENABLED \ + | PLX9052_INTCSR_LI1SEL_EDGE \ + | PLX9052_INTCSR_LI1CLRINT_ASSERTED) /* * Board descriptions for Amplicon PC36AT and PCI236. @@ -150,12 +150,13 @@ MODULE_DEVICE_TABLE(pci, pc236_pci_table); /* this structure is for data unique to this hardware driver. If several hardware drivers keep similar information in this structure, - feel free to suggest moving the variable to the struct comedi_device struct. */ + feel free to suggest moving the variable to the struct comedi_device struct. + */ struct pc236_private { #ifdef CONFIG_COMEDI_PCI /* PCI device */ struct pci_dev *pci_dev; - unsigned long lcr_iobase; /* PLX PCI9052 config registers in PCIBAR1 */ + unsigned long lcr_iobase; /* PLX PCI9052 config registers in PCIBAR1 */ #endif int enable_irq; }; @@ -345,9 +346,8 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it) #endif { ret = pc236_request_region(dev->minor, iobase, PC236_IO_SIZE); - if (ret < 0) { + if (ret < 0) return ret; - } } dev->iobase = iobase; @@ -399,11 +399,10 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it) printk("(pci %s) ", pci_name(pci_dev)); #endif } - if (irq) { + if (irq) printk("(irq %u%s) ", irq, (dev->irq ? "" : " UNAVAILABLE")); - } else { + else printk("(no irq) "); - } printk("attached\n"); @@ -422,27 +421,24 @@ static int pc236_detach(struct comedi_device *dev) { printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor, PC236_DRIVER_NAME); - if (devpriv) { + if (devpriv) pc236_intr_disable(dev); - } + if (dev->irq) free_irq(dev->irq, dev); - if (dev->subdevices) { + if (dev->subdevices) subdev_8255_cleanup(dev, dev->subdevices + 0); - } if (devpriv) { #ifdef CONFIG_COMEDI_PCI if (devpriv->pci_dev) { - if (dev->iobase) { + if (dev->iobase) comedi_pci_disable(devpriv->pci_dev); - } pci_dev_put(devpriv->pci_dev); } else #endif { - if (dev->iobase) { + if (dev->iobase) release_region(dev->iobase, PC236_IO_SIZE); - } } } if (dev->board_name) { diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index d983687..b41e5e59 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -1536,20 +1536,12 @@ static int pci224_detach(struct comedi_device *dev) s = dev->subdevices + 0; /* AO subdevice */ - if (s->range_table_list) { - kfree(s->range_table_list); - } + kfree(s->range_table_list); } if (devpriv) { - if (devpriv->ao_readback) { - kfree(devpriv->ao_readback); - } - if (devpriv->ao_scan_vals) { - kfree(devpriv->ao_scan_vals); - } - if (devpriv->ao_scan_order) { - kfree(devpriv->ao_scan_order); - } + kfree(devpriv->ao_readback); + kfree(devpriv->ao_scan_vals); + kfree(devpriv->ao_scan_order); if (devpriv->pci_dev) { if (dev->iobase) { comedi_pci_disable(devpriv->pci_dev); diff --git a/drivers/staging/comedi/drivers/c6xdigio.c b/drivers/staging/comedi/drivers/c6xdigio.c index abb0532..fb0d5fa 100644 --- a/drivers/staging/comedi/drivers/c6xdigio.c +++ b/drivers/staging/comedi/drivers/c6xdigio.c @@ -45,7 +45,7 @@ http://robot0.ge.uiuc.edu/~spong/mecha/ #include <linux/interrupt.h> #include <linux/timex.h> #include <linux/timer.h> -#include <asm/io.h> +#include <linux/io.h> #include <linux/pnp.h> #include "../comedidev.h" @@ -220,11 +220,11 @@ static int C6X_encInput(unsigned long baseAddr, unsigned channel) /* printk("Inside C6X_encInput\n"); */ enc.value = 0; - if (channel == 0) { + if (channel == 0) ppcmd = 0x48; - } else { + else ppcmd = 0x50; - } + WriteByteToHwPort(baseAddr, ppcmd); tmp = ReadByteFromHwPort(baseAddr + 1); while (((tmp & 0x80) == 0) && (timeout < C6XDIGIO_TIME_OUT)) { @@ -391,9 +391,8 @@ static int c6xdigio_ei_insn_read(struct comedi_device *dev, int n; int chan = CR_CHAN(insn->chanspec); - for (n = 0; n < insn->n; n++) { + for (n = 0; n < insn->n; n++) data[n] = (C6X_encInput(dev->iobase, chan) & 0xffffff); - } return n; } @@ -420,9 +419,9 @@ static void board_init(struct comedi_device *dev) static const struct pnp_device_id c6xdigio_pnp_tbl[] = { /* Standard LPT Printer Port */ - {.id = "PNP0400",.driver_data = 0}, + {.id = "PNP0400", .driver_data = 0}, /* ECP Printer Port */ - {.id = "PNP0401",.driver_data = 0}, + {.id = "PNP0401", .driver_data = 0}, {} }; @@ -452,15 +451,14 @@ static int c6xdigio_attach(struct comedi_device *dev, if (result < 0) return result; - /* Make sure that PnP ports gets activated */ + /* Make sure that PnP ports get activated */ pnp_register_driver(&c6xdigio_pnp_driver); irq = it->options[1]; - if (irq > 0) { + if (irq > 0) printk("comedi%d: irq = %u ignored\n", dev->minor, irq); - } else if (irq == 0) { + else if (irq == 0) printk("comedi%d: no irq\n", dev->minor); - } s = dev->subdevices + 0; /* pwm output subdevice */ @@ -483,19 +481,19 @@ static int c6xdigio_attach(struct comedi_device *dev, s->maxdata = 0xffffff; s->range_table = &range_unknown; - /* s = dev->subdevices + 2; */ + /* s = dev->subdevices + 2; */ /* pwm output subdevice */ - /* s->type = COMEDI_SUBD_COUNTER; // Not sure what to put here */ - /* s->subdev_flags = SDF_WRITEABLE; */ - /* s->n_chan = 1; */ - /* s->trig[0] = c6xdigio_ei_init; */ - /* s->insn_read = c6xdigio_ei_init_insn_read; */ - /* s->insn_write = c6xdigio_ei_init_insn_write; */ - /* s->maxdata = 0xFFFF; // Really just a don't care */ - /* s->range_table = &range_unknown; // Not sure what to put here */ - - /* I will call this init anyway but more than likely the DSP board will not be connect */ - /* when device driver is loaded. */ + /* s->type = COMEDI_SUBD_COUNTER; // Not sure what to put here */ + /* s->subdev_flags = SDF_WRITEABLE; */ + /* s->n_chan = 1; */ + /* s->trig[0] = c6xdigio_ei_init; */ + /* s->insn_read = c6xdigio_ei_init_insn_read; */ + /* s->insn_write = c6xdigio_ei_init_insn_write; */ + /* s->maxdata = 0xFFFF; // Really just a don't care */ + /* s->range_table = &range_unknown; // Not sure what to put here */ + + /* I will call this init anyway but more than likely the DSP board */ + /* will not be connected when device driver is loaded. */ board_init(dev); return 0; @@ -503,16 +501,17 @@ static int c6xdigio_attach(struct comedi_device *dev, static int c6xdigio_detach(struct comedi_device *dev) { -/* board_halt(dev); may not need this */ + /* board_halt(dev); may not need this */ printk("comedi%d: c6xdigio: remove\n", dev->minor); - if (dev->iobase) { + if (dev->iobase) release_region(dev->iobase, C6XDIGIO_SIZE); - } - if (dev->irq) { + + /* Not using IRQ so I am not sure if I need this */ + if (dev->irq) free_irq(dev->irq, dev); - } /* Not using IRQ so I am not sure if I need this */ + pnp_unregister_driver(&c6xdigio_pnp_driver); return 0; diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c index f3e66c4..434591d 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas.c +++ b/drivers/staging/comedi/drivers/cb_pcidas.c @@ -518,7 +518,7 @@ static int trimpot_7376_write(struct comedi_device *dev, uint8_t value); static int trimpot_8402_write(struct comedi_device *dev, unsigned int channel, uint8_t value); static int nvram_read(struct comedi_device *dev, unsigned int address, - uint8_t * data); + uint8_t *data); static inline unsigned int cal_enable_bits(struct comedi_device *dev) { @@ -760,9 +760,8 @@ static int cb_pcidas_detach(struct comedi_device *dev) if (dev->subdevices) subdev_8255_cleanup(dev, dev->subdevices + 2); if (devpriv && devpriv->pci_dev) { - if (devpriv->s5933_config) { + if (devpriv->s5933_config) comedi_pci_disable(devpriv->pci_dev); - } pci_dev_put(devpriv->pci_dev); } @@ -1248,9 +1247,8 @@ static int cb_pcidas_ai_cmd(struct comedi_device *dev, cmd->flags & TRIG_ROUND_MASK); /* set number of conversions */ - if (cmd->stop_src == TRIG_COUNT) { + if (cmd->stop_src == TRIG_COUNT) devpriv->count = cmd->chanlist_len * cmd->stop_arg; - } /* enable interrupts */ spin_lock_irqsave(&dev->spinlock, flags); devpriv->adc_fifo_bits |= INTE; @@ -1449,9 +1447,8 @@ static int cb_pcidas_ao_cmd(struct comedi_device *dev, devpriv->ao_divisor2, 2); } /* set number of conversions */ - if (cmd->stop_src == TRIG_COUNT) { + if (cmd->stop_src == TRIG_COUNT) devpriv->ao_count = cmd->chanlist_len * cmd->stop_arg; - } /* set pacer source */ spin_lock_irqsave(&dev->spinlock, flags); switch (cmd->scan_begin_src) { @@ -1494,9 +1491,8 @@ static int cb_pcidas_ao_inttrig(struct comedi_device *dev, num_points * sizeof(short)); num_points = num_bytes / sizeof(short); - if (cmd->stop_src == TRIG_COUNT) { + if (cmd->stop_src == TRIG_COUNT) devpriv->ao_count -= num_points; - } /* write data to board's fifo */ outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer, num_bytes); @@ -1534,9 +1530,8 @@ static irqreturn_t cb_pcidas_interrupt(int irq, void *d) static const int timeout = 10000; unsigned long flags; - if (dev->attached == 0) { + if (dev->attached == 0) return IRQ_NONE; - } async = s->async; async->events = 0; @@ -1558,15 +1553,13 @@ static irqreturn_t cb_pcidas_interrupt(int irq, void *d) status = inw(devpriv->control_status + INT_ADCFIFO); #ifdef CB_PCIDAS_DEBUG - if ((status & (INT | EOAI | LADFUL | DAHFI | DAEMI)) == 0) { + if ((status & (INT | EOAI | LADFUL | DAHFI | DAEMI)) == 0) comedi_error(dev, "spurious interrupt"); - } #endif /* check for analog output interrupt */ - if (status & (DAHFI | DAEMI)) { + if (status & (DAHFI | DAEMI)) handle_ao_interrupt(dev, status); - } /* check for analog input interrupts */ /* if fifo half-full */ if (status & ADHFI) { @@ -1675,9 +1668,8 @@ static void handle_ao_interrupt(struct comedi_device *dev, unsigned int status) num_points * sizeof(short)); num_points = num_bytes / sizeof(short); - if (async->cmd.stop_src == TRIG_COUNT) { + if (async->cmd.stop_src == TRIG_COUNT) devpriv->ao_count -= num_points; - } /* write data to board's fifo */ outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer, num_points); @@ -1852,7 +1844,7 @@ static int wait_for_nvram_ready(unsigned long s5933_base_addr) } static int nvram_read(struct comedi_device *dev, unsigned int address, - uint8_t * data) + uint8_t *data) { unsigned long iobase = devpriv->s5933_config; diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c index 7823577..81829d6 100644 --- a/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/drivers/staging/comedi/drivers/cb_pcidda.c @@ -410,9 +410,8 @@ static int cb_pcidda_detach(struct comedi_device *dev) */ if (devpriv) { if (devpriv->pci_dev) { - if (devpriv->dac) { + if (devpriv->dac) comedi_pci_disable(devpriv->pci_dev); - } pci_dev_put(devpriv->pci_dev); } } @@ -677,9 +676,8 @@ static unsigned int cb_pcidda_serial_in(struct comedi_device *dev) for (i = 1; i <= value_width; i++) { /* read bits most significant bit first */ - if (inw_p(devpriv->dac + DACALIBRATION1) & SERIAL_OUT_BIT) { + if (inw_p(devpriv->dac + DACALIBRATION1) & SERIAL_OUT_BIT) value |= 1 << (value_width - i); - } } return value; @@ -716,9 +714,8 @@ static unsigned int cb_pcidda_read_eeprom(struct comedi_device *dev, /* send serial output stream to eeprom */ cal2_bits = SELECT_EEPROM_BIT | DESELECT_REF_DAC_BIT | DUMMY_BIT; /* deactivate caldacs (one caldac for every two channels) */ - for (i = 0; i < max_num_caldacs; i++) { + for (i = 0; i < max_num_caldacs; i++) cal2_bits |= DESELECT_CALDAC_BIT(i); - } outw_p(cal2_bits, devpriv->dac + DACALIBRATION2); /* tell eeprom we want to read */ @@ -756,9 +753,8 @@ static void cb_pcidda_write_caldac(struct comedi_device *dev, */ cal2_bits = DESELECT_REF_DAC_BIT | DUMMY_BIT; /* deactivate caldacs (one caldac for every two channels) */ - for (i = 0; i < max_num_caldacs; i++) { + for (i = 0; i < max_num_caldacs; i++) cal2_bits |= DESELECT_CALDAC_BIT(i); - } /* activate the caldac we want */ cal2_bits &= ~DESELECT_CALDAC_BIT(caldac); outw_p(cal2_bits, devpriv->dac + DACALIBRATION2); diff --git a/drivers/staging/comedi/drivers/cb_pcidio.c b/drivers/staging/comedi/drivers/cb_pcidio.c index 7daad0a..38ccd10 100644 --- a/drivers/staging/comedi/drivers/cb_pcidio.c +++ b/drivers/staging/comedi/drivers/cb_pcidio.c @@ -283,17 +283,15 @@ static int pcidio_detach(struct comedi_device *dev) printk("comedi%d: cb_pcidio: remove\n", dev->minor); if (devpriv) { if (devpriv->pci_dev) { - if (devpriv->dio_reg_base) { + if (devpriv->dio_reg_base) comedi_pci_disable(devpriv->pci_dev); - } pci_dev_put(devpriv->pci_dev); } } if (dev->subdevices) { int i; - for (i = 0; i < thisboard->n_8255; i++) { + for (i = 0; i < thisboard->n_8255; i++) subdev_8255_cleanup(dev, dev->subdevices + i); - } } return 0; } diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c index cbbca05..2e61727 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdas.c +++ b/drivers/staging/comedi/drivers/cb_pcimdas.c @@ -330,11 +330,10 @@ found: s = dev->subdevices + 2; /* digital i/o subdevice */ - if (thisboard->has_dio) { + if (thisboard->has_dio) subdev_8255_init(dev, s, NULL, devpriv->BADR4); - } else { + else s->type = COMEDI_SUBD_UNUSED; - } printk("attached\n"); @@ -365,9 +364,8 @@ static int cb_pcimdas_detach(struct comedi_device *dev) free_irq(dev->irq, dev); if (devpriv) { if (devpriv->pci_dev) { - if (devpriv->BADR0) { + if (devpriv->BADR0) comedi_pci_disable(devpriv->pci_dev); - } pci_dev_put(devpriv->pci_dev); } } diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c index 980fa0a..e32a317 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdda.c +++ b/drivers/staging/comedi/drivers/cb_pcimdda.c @@ -284,11 +284,10 @@ static int attach(struct comedi_device *dev, struct comedi_devconfig *it) s->n_chan = thisboard->ao_chans; s->maxdata = figure_out_maxdata(thisboard->ao_bits); /* this is hard-coded here */ - if (it->options[2]) { + if (it->options[2]) s->range_table = &range_bipolar10; - } else { + else s->range_table = &range_bipolar5; - } s->insn_write = &ao_winsn; s->insn_read = &ao_rinsn; @@ -337,9 +336,8 @@ static int detach(struct comedi_device *dev) } if (devpriv->pci_dev) { - if (devpriv->registers) { + if (devpriv->registers) comedi_pci_disable(devpriv->pci_dev); - } pci_dev_put(devpriv->pci_dev); } diff --git a/drivers/staging/comedi/drivers/comedi_bond.c b/drivers/staging/comedi/drivers/comedi_bond.c index cf39a24..d7260cc 100644 --- a/drivers/staging/comedi/drivers/comedi_bond.c +++ b/drivers/staging/comedi/drivers/comedi_bond.c @@ -417,7 +417,7 @@ static int doDevConfig(struct comedi_device *dev, struct comedi_devconfig *it) int sdev = -1, nchans, tmp; struct BondedDevice *bdev = NULL; - if (minor < 0 || minor > COMEDI_NUM_BOARD_MINORS) { + if (minor < 0 || minor >= COMEDI_NUM_BOARD_MINORS) { ERROR("Minor %d is invalid!\n", minor); return 0; } diff --git a/drivers/staging/comedi/drivers/contec_pci_dio.c b/drivers/staging/comedi/drivers/contec_pci_dio.c index b16d652..9511814 100644 --- a/drivers/staging/comedi/drivers/contec_pci_dio.c +++ b/drivers/staging/comedi/drivers/contec_pci_dio.c @@ -173,9 +173,8 @@ static int contec_detach(struct comedi_device *dev) printk("comedi%d: contec: remove\n", dev->minor); if (devpriv && devpriv->pci_dev) { - if (dev->iobase) { + if (dev->iobase) comedi_pci_disable(devpriv->pci_dev); - } pci_dev_put(devpriv->pci_dev); } diff --git a/drivers/staging/comedi/drivers/das08_cs.c b/drivers/staging/comedi/drivers/das08_cs.c index 9b945e5..f12ef1c 100644 --- a/drivers/staging/comedi/drivers/das08_cs.c +++ b/drivers/staging/comedi/drivers/das08_cs.c @@ -34,7 +34,7 @@ This is the PCMCIA-specific support split off from the das08 driver. Options (for pcm-das08): - NONE + NONE Command support does not exist, but could be added for this board. */ @@ -52,7 +52,7 @@ Command support does not exist, but could be added for this board. #include <pcmcia/cistpl.h> #include <pcmcia/ds.h> -static struct pcmcia_device *cur_dev = NULL; +static struct pcmcia_device *cur_dev; #define thisboard ((const struct das08_board_struct *)dev->board_ptr) diff --git a/drivers/staging/comedi/drivers/das6402.c b/drivers/staging/comedi/drivers/das6402.c index 92487f5..a404a18 100644 --- a/drivers/staging/comedi/drivers/das6402.c +++ b/drivers/staging/comedi/drivers/das6402.c @@ -45,7 +45,7 @@ This driver has suffered bitrot. #define DAS6402_SIZE 16 -#define N_WORDS 3000*64 +#define N_WORDS (3000*64) #define STOP 0 #define START 1 diff --git a/drivers/staging/comedi/drivers/das800.c b/drivers/staging/comedi/drivers/das800.c index ecb97cd..aadc497 100644 --- a/drivers/staging/comedi/drivers/das800.c +++ b/drivers/staging/comedi/drivers/das800.c @@ -399,9 +399,8 @@ static irqreturn_t das800_interrupt(int irq, void *d) } else { fifo_empty = 0; /* cio-das802/16 has no fifo empty status bit */ } - if (fifo_empty) { + if (fifo_empty) break; - } /* strip off extraneous bits for 12 bit cards */ if (thisboard->resolution == 12) dataPoint = (dataPoint >> 4) & 0xfff; @@ -457,9 +456,8 @@ static int das800_attach(struct comedi_device *dev, struct comedi_devconfig *it) int board; printk("comedi%d: das800: io 0x%lx", dev->minor, iobase); - if (irq) { + if (irq) printk(", irq %u", irq); - } printk("\n"); /* allocate and initialize dev->private */ diff --git a/drivers/staging/comedi/drivers/dmm32at.c b/drivers/staging/comedi/drivers/dmm32at.c index 9db9a46..d5cbd51 100644 --- a/drivers/staging/comedi/drivers/dmm32at.c +++ b/drivers/staging/comedi/drivers/dmm32at.c @@ -1048,11 +1048,10 @@ static int dmm32at_dio_insn_config(struct comedi_device *dev, * value COMEDI_INPUT or COMEDI_OUTPUT. */ /* if output clear the bit, otherwise set it */ - if (data[0] == COMEDI_OUTPUT) { + if (data[0] == COMEDI_OUTPUT) devpriv->dio_config &= ~chanbit; - } else { + else devpriv->dio_config |= chanbit; - } /* get access to the DIO regs */ dmm_outb(dev, DMM32AT_CNTRL, DMM32AT_DIOACC); /* set the DIO's to the new configuration setting */ diff --git a/drivers/staging/comedi/drivers/dt2801.c b/drivers/staging/comedi/drivers/dt2801.c index 7b9af5d..3f365ae 100644 --- a/drivers/staging/comedi/drivers/dt2801.c +++ b/drivers/staging/comedi/drivers/dt2801.c @@ -18,10 +18,10 @@ Configuration options: [1] - unused [2] - A/D reference 0=differential, 1=single-ended [3] - A/D range - 0 = [-10,10] + 0 = [-10, 10] 1 = [0,10] [4] - D/A 0 range - 0 = [-10,10] + 0 = [-10, 10] 1 = [-5,5] 2 = [-2.5,2.5] 3 = [0,10] @@ -279,9 +279,8 @@ static int dt2801_readdata(struct comedi_device *dev, int *data) do { stat = inb_p(dev->iobase + DT2801_STATUS); - if (stat & (DT_S_COMPOSITE_ERROR | DT_S_READY)) { + if (stat & (DT_S_COMPOSITE_ERROR | DT_S_READY)) return stat; - } if (stat & DT_S_DATA_OUT_READY) { *data = inb_p(dev->iobase + DT2801_DATA); return 0; @@ -315,9 +314,8 @@ static int dt2801_writedata(struct comedi_device *dev, unsigned int data) do { stat = inb_p(dev->iobase + DT2801_STATUS); - if (stat & DT_S_COMPOSITE_ERROR) { + if (stat & DT_S_COMPOSITE_ERROR) return stat; - } if (!(stat & DT_S_DATA_IN_FULL)) { outb_p(data & 0xff, dev->iobase + DT2801_DATA); return 0; @@ -354,18 +352,15 @@ static int dt2801_wait_for_ready(struct comedi_device *dev) int stat; stat = inb_p(dev->iobase + DT2801_STATUS); - if (stat & DT_S_READY) { + if (stat & DT_S_READY) return 0; - } do { stat = inb_p(dev->iobase + DT2801_STATUS); - if (stat & DT_S_COMPOSITE_ERROR) { + if (stat & DT_S_COMPOSITE_ERROR) return stat; - } - if (stat & DT_S_READY) { + if (stat & DT_S_READY) return 0; - } } while (--timeout > 0); return -ETIME; @@ -382,9 +377,8 @@ static int dt2801_writecmd(struct comedi_device *dev, int command) printk ("dt2801: composite-error in dt2801_writecmd(), ignoring\n"); } - if (!(stat & DT_S_READY)) { + if (!(stat & DT_S_READY)) printk("dt2801: !ready in dt2801_writecmd(), ignoring\n"); - } outb_p(command, dev->iobase + DT2801_CMD); return 0; @@ -418,9 +412,8 @@ static int dt2801_reset(struct comedi_device *dev) if (stat & DT_S_READY) break; } while (timeout--); - if (!timeout) { + if (!timeout) printk("dt2801: timeout 1 status=0x%02x\n", stat); - } /* printk("dt2801: reading dummy\n"); */ /* dt2801_readdata(dev,&board_code); */ @@ -436,9 +429,8 @@ static int dt2801_reset(struct comedi_device *dev) if (stat & DT_S_READY) break; } while (timeout--); - if (!timeout) { + if (!timeout) printk("dt2801: timeout 2 status=0x%02x\n", stat); - } DPRINTK("dt2801: reading code\n"); dt2801_readdata(dev, &board_code); @@ -623,11 +615,10 @@ static int dt2801_detach(struct comedi_device *dev) static int dt2801_error(struct comedi_device *dev, int stat) { if (stat < 0) { - if (stat == -ETIME) { + if (stat == -ETIME) printk("dt2801: timeout\n"); - } else { + else printk("dt2801: error %d\n", stat); - } return stat; } printk("dt2801: error status 0x%02x, resetting...\n", stat); diff --git a/drivers/staging/comedi/drivers/dt2815.c b/drivers/staging/comedi/drivers/dt2815.c index d1db93c..d1a4f78 100644 --- a/drivers/staging/comedi/drivers/dt2815.c +++ b/drivers/staging/comedi/drivers/dt2815.c @@ -34,19 +34,19 @@ Configuration options: [0] - I/O port base base address [1] - IRQ (unused) [2] - Voltage unipolar/bipolar configuration - 0 == unipolar 5V (0V -- +5V) - 1 == bipolar 5V (-5V -- +5V) + 0 == unipolar 5V (0V -- +5V) + 1 == bipolar 5V (-5V -- +5V) [3] - Current offset configuration - 0 == disabled (0mA -- +32mAV) - 1 == enabled (+4mA -- +20mAV) + 0 == disabled (0mA -- +32mAV) + 1 == enabled (+4mA -- +20mAV) [4] - Firmware program configuration - 0 == program 1 (see manual table 5-4) - 1 == program 2 (see manual table 5-4) - 2 == program 3 (see manual table 5-4) - 3 == program 4 (see manual table 5-4) + 0 == program 1 (see manual table 5-4) + 1 == program 2 (see manual table 5-4) + 2 == program 3 (see manual table 5-4) + 3 == program 4 (see manual table 5-4) [5] - Analog output 0 range configuration - 0 == voltage - 1 == current + 0 == voltage + 1 == current [6] - Analog output 1 range configuration (same options) [7] - Analog output 2 range configuration (same options) [8] - Analog output 3 range configuration (same options) @@ -61,17 +61,11 @@ Configuration options: #include <linux/ioport.h> #include <linux/delay.h> -static const struct comedi_lrange range_dt2815_ao_32_current = { 1, { - RANGE_mA(0, - 32) - } -}; +static const struct comedi_lrange + range_dt2815_ao_32_current = {1, {RANGE_mA(0, 32)} }; -static const struct comedi_lrange range_dt2815_ao_20_current = { 1, { - RANGE_mA(4, - 20) - } -}; +static const struct comedi_lrange + range_dt2815_ao_20_current = {1, {RANGE_mA(4, 20)} }; #define DT2815_SIZE 2 @@ -118,9 +112,8 @@ static int dt2815_ao_insn_read(struct comedi_device *dev, int i; int chan = CR_CHAN(insn->chanspec); - for (i = 0; i < insn->n; i++) { + for (i = 0; i < insn->n; i++) data[i] = devpriv->ao_readback[chan]; - } return i; } @@ -139,9 +132,8 @@ static int dt2815_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s, status = dt2815_wait_for_status(dev, 0x00); if (status != 0) { - printk - ("dt2815: failed to write low byte on %d reason %x\n", - chan, status); + printk(KERN_WARNING "dt2815: failed to write low byte " + "on %d reason %x\n", chan, status); return -EBUSY; } @@ -149,9 +141,8 @@ static int dt2815_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s, status = dt2815_wait_for_status(dev, 0x10); if (status != 0x10) { - printk - ("dt2815: failed to write high byte on %d reason %x\n", - chan, status); + printk(KERN_WARNING "dt2815: failed to write high byte " + "on %d reason %x\n", chan, status); return -EBUSY; } devpriv->ao_readback[chan] = data[i]; @@ -163,24 +154,24 @@ static int dt2815_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s, options[0] Board base address options[1] IRQ (not applicable) options[2] Voltage unipolar/bipolar configuration - 0 == unipolar 5V (0V -- +5V) - 1 == bipolar 5V (-5V -- +5V) + 0 == unipolar 5V (0V -- +5V) + 1 == bipolar 5V (-5V -- +5V) options[3] Current offset configuration - 0 == disabled (0mA -- +32mAV) - 1 == enabled (+4mA -- +20mAV) + 0 == disabled (0mA -- +32mAV) + 1 == enabled (+4mA -- +20mAV) options[4] Firmware program configuration - 0 == program 1 (see manual table 5-4) - 1 == program 2 (see manual table 5-4) - 2 == program 3 (see manual table 5-4) - 3 == program 4 (see manual table 5-4) + 0 == program 1 (see manual table 5-4) + 1 == program 2 (see manual table 5-4) + 2 == program 3 (see manual table 5-4) + 3 == program 4 (see manual table 5-4) options[5] Analog output 0 range configuration - 0 == voltage - 1 == current + 0 == voltage + 1 == current options[6] Analog output 1 range configuration ... options[12] Analog output 7 range configuration - 0 == voltage - 1 == current + 0 == voltage + 1 == current */ static int dt2815_attach(struct comedi_device *dev, struct comedi_devconfig *it) @@ -191,9 +182,9 @@ static int dt2815_attach(struct comedi_device *dev, struct comedi_devconfig *it) unsigned long iobase; iobase = it->options[0]; - printk("comedi%d: dt2815: 0x%04lx ", dev->minor, iobase); + printk(KERN_INFO "comedi%d: dt2815: 0x%04lx ", dev->minor, iobase); if (!request_region(iobase, DT2815_SIZE, "dt2815")) { - printk("I/O port conflict\n"); + printk(KERN_WARNING "I/O port conflict\n"); return -EIO; } @@ -236,19 +227,17 @@ static int dt2815_attach(struct comedi_device *dev, struct comedi_devconfig *it) unsigned int program; program = (it->options[4] & 0x3) << 3 | 0x7; outb(program, dev->iobase + DT2815_DATA); - printk(", program: 0x%x (@t=%d)\n", program, i); + printk(KERN_INFO ", program: 0x%x (@t=%d)\n", + program, i); break; } else if (status != 0x00) { - printk("dt2815: unexpected status 0x%x (@t=%d)\n", - status, i); - if (status & 0x60) { + printk(KERN_WARNING "dt2815: unexpected status 0x%x " + "(@t=%d)\n", status, i); + if (status & 0x60) outb(0x00, dev->iobase + DT2815_STATUS); - } } } - printk("\n"); - return 0; } @@ -260,7 +249,7 @@ static void dt2815_free_resources(struct comedi_device *dev) static int dt2815_detach(struct comedi_device *dev) { - printk("comedi%d: dt2815: remove\n", dev->minor); + printk(KERN_INFO "comedi%d: dt2815: remove\n", dev->minor); dt2815_free_resources(dev); diff --git a/drivers/staging/comedi/drivers/dt9812.c b/drivers/staging/comedi/drivers/dt9812.c index 312f4f2..96caae3 100644 --- a/drivers/staging/comedi/drivers/dt9812.c +++ b/drivers/staging/comedi/drivers/dt9812.c @@ -264,7 +264,7 @@ struct dt9812_usb_cmd { static DECLARE_MUTEX(dt9812_mutex); -static struct usb_device_id dt9812_table[] = { +static const struct usb_device_id dt9812_table[] = { {USB_DEVICE(0x0867, 0x9812)}, {} /* Terminating entry */ }; diff --git a/drivers/staging/comedi/drivers/fl512.c b/drivers/staging/comedi/drivers/fl512.c index 8fca180..a10a2b0 100644 --- a/drivers/staging/comedi/drivers/fl512.c +++ b/drivers/staging/comedi/drivers/fl512.c @@ -76,14 +76,14 @@ static int fl512_ai_insn(struct comedi_device *dev, unsigned long iobase = dev->iobase; for (n = 0; n < insn->n; n++) { /* sample n times on selected channel */ - /* XXX probably can move next step out of for() loop -- will make - * AI a little bit faster. */ + /* XXX probably can move next step out of for() loop -- will + * make AI a little bit faster. */ outb(chan, iobase + 2); /* select chan */ outb(0, iobase + 3); /* start conversion */ /* XXX should test "done" flag instead of delay */ udelay(30); /* sleep 30 usec */ lo_byte = inb(iobase + 2); /* low 8 byte */ - hi_byte = inb(iobase + 3) & 0xf; /* high 4 bit and mask */ + hi_byte = inb(iobase + 3) & 0xf; /* high 4 bit and mask */ data[n] = lo_byte + (hi_byte << 8); } return n; @@ -101,8 +101,10 @@ static int fl512_ao_insn(struct comedi_device *dev, unsigned long iobase = dev->iobase; /* get base address */ for (n = 0; n < insn->n; n++) { /* write n data set */ - outb(data[n] & 0x0ff, iobase + 4 + 2 * chan); /* write low byte */ - outb((data[n] & 0xf00) >> 8, iobase + 4 + 2 * chan); /* write high byte */ + /* write low byte */ + outb(data[n] & 0x0ff, iobase + 4 + 2 * chan); + /* write high byte */ + outb((data[n] & 0xf00) >> 8, iobase + 4 + 2 * chan); inb(iobase + 4 + 2 * chan); /* trig */ devpriv->ao_readback[chan] = data[n]; @@ -121,9 +123,8 @@ static int fl512_ao_insn_readback(struct comedi_device *dev, int n; int chan = CR_CHAN(insn->chanspec); - for (n = 0; n < insn->n; n++) { + for (n = 0; n < insn->n; n++) data[n] = devpriv->ao_readback[chan]; - } return n; } @@ -134,13 +135,15 @@ static int fl512_ao_insn_readback(struct comedi_device *dev, static int fl512_attach(struct comedi_device *dev, struct comedi_devconfig *it) { unsigned long iobase; - struct comedi_subdevice *s; /* pointer to the subdevice: - Analog in, Analog out, ( not made ->and Digital IO) */ + + /* pointer to the subdevice: Analog in, Analog out, + (not made ->and Digital IO) */ + struct comedi_subdevice *s; iobase = it->options[0]; - printk("comedi:%d fl512: 0x%04lx", dev->minor, iobase); + printk(KERN_INFO "comedi:%d fl512: 0x%04lx", dev->minor, iobase); if (!request_region(iobase, FL512_SIZE, "fl512")) { - printk(" I/O port conflict\n"); + printk(KERN_WARNING " I/O port conflict\n"); return -EIO; } dev->iobase = iobase; @@ -149,7 +152,7 @@ static int fl512_attach(struct comedi_device *dev, struct comedi_devconfig *it) return -ENOMEM; #if DEBUG - printk("malloc ok\n"); + printk(KERN_DEBUG "malloc ok\n"); #endif if (alloc_subdevices(dev, 2) < 0) @@ -160,24 +163,37 @@ static int fl512_attach(struct comedi_device *dev, struct comedi_devconfig *it) */ /* Analog indput */ s = dev->subdevices + 0; - s->type = COMEDI_SUBD_AI; /* define subdevice as Analog In */ - s->subdev_flags = SDF_READABLE | SDF_GROUND; /* you can read it from userspace */ - s->n_chan = 16; /* Number of Analog input channels */ - s->maxdata = 0x0fff; /* accept only 12 bits of data */ - s->range_table = &range_fl512; /* device use one of the ranges */ - s->insn_read = fl512_ai_insn; /* function to call when read AD */ - printk("comedi: fl512: subdevice 0 initialized\n"); + /* define subdevice as Analog In */ + s->type = COMEDI_SUBD_AI; + /* you can read it from userspace */ + s->subdev_flags = SDF_READABLE | SDF_GROUND; + /* Number of Analog input channels */ + s->n_chan = 16; + /* accept only 12 bits of data */ + s->maxdata = 0x0fff; + /* device use one of the ranges */ + s->range_table = &range_fl512; + /* function to call when read AD */ + s->insn_read = fl512_ai_insn; + printk(KERN_INFO "comedi: fl512: subdevice 0 initialized\n"); /* Analog output */ s = dev->subdevices + 1; - s->type = COMEDI_SUBD_AO; /* define subdevice as Analog OUT */ - s->subdev_flags = SDF_WRITABLE; /* you can write it from userspace */ - s->n_chan = 2; /* Number of Analog output channels */ - s->maxdata = 0x0fff; /* accept only 12 bits of data */ - s->range_table = &range_fl512; /* device use one of the ranges */ - s->insn_write = fl512_ao_insn; /* function to call when write DA */ - s->insn_read = fl512_ao_insn_readback; /* function to call when reading DA */ - printk("comedi: fl512: subdevice 1 initialized\n"); + /* define subdevice as Analog OUT */ + s->type = COMEDI_SUBD_AO; + /* you can write it from userspace */ + s->subdev_flags = SDF_WRITABLE; + /* Number of Analog output channels */ + s->n_chan = 2; + /* accept only 12 bits of data */ + s->maxdata = 0x0fff; + /* device use one of the ranges */ + s->range_table = &range_fl512; + /* function to call when write DA */ + s->insn_write = fl512_ao_insn; + /* function to call when reading DA */ + s->insn_read = fl512_ao_insn_readback; + printk(KERN_INFO "comedi: fl512: subdevice 1 initialized\n"); return 1; } @@ -186,6 +202,6 @@ static int fl512_detach(struct comedi_device *dev) { if (dev->iobase) release_region(dev->iobase, FL512_SIZE); - printk("comedi%d: fl512: dummy i detach\n", dev->minor); + printk(KERN_INFO "comedi%d: fl512: dummy i detach\n", dev->minor); return 0; } diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c index bd39784..fe5b495 100644 --- a/drivers/staging/comedi/drivers/jr3_pci.c +++ b/drivers/staging/comedi/drivers/jr3_pci.c @@ -954,6 +954,8 @@ out: return result; } +MODULE_FIRMWARE("comedi/jr3pci.idm"); + static int jr3_pci_detach(struct comedi_device *dev) { int i; diff --git a/drivers/staging/comedi/drivers/mpc624.c b/drivers/staging/comedi/drivers/mpc624.c index cb4da2a..12e72c8 100644 --- a/drivers/staging/comedi/drivers/mpc624.c +++ b/drivers/staging/comedi/drivers/mpc624.c @@ -284,7 +284,7 @@ static int mpc624_ai_rinsn(struct comedi_device *dev, outb(insn->chanspec, dev->iobase + MPC624_GNMUXCH); /* printk("Channel %d: \n", insn->chanspec); */ if (!insn->n) { - printk("MPC624: Warning, no data to aquire\n"); + printk("MPC624: Warning, no data to acquire\n"); return 0; } diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c index bbf75eb..c223f76 100644 --- a/drivers/staging/comedi/drivers/ni_65xx.c +++ b/drivers/staging/comedi/drivers/ni_65xx.c @@ -26,12 +26,13 @@ /* Driver: ni_65xx Description: National Instruments 65xx static dio boards -Author: Jon Grierson <jd@renko.co.uk>, Frank Mori Hess <fmhess@users.sourceforge.net> +Author: Jon Grierson <jd@renko.co.uk>, + Frank Mori Hess <fmhess@users.sourceforge.net> Status: testing -Devices: [National Instruments] PCI-6509 (ni_65xx), PXI-6509, PCI-6510, PCI-6511, - PXI-6511, PCI-6512, PXI-6512, PCI-6513, PXI-6513, PCI-6514, PXI-6514, PCI-6515, - PXI-6515, PCI-6516, PCI-6517, PCI-6518, PCI-6519, PCI-6520, PCI-6521, PXI-6521, - PCI-6528, PXI-6528 +Devices: [National Instruments] PCI-6509 (ni_65xx), PXI-6509, PCI-6510, + PCI-6511, PXI-6511, PCI-6512, PXI-6512, PCI-6513, PXI-6513, PCI-6514, + PXI-6514, PCI-6515, PXI-6515, PCI-6516, PCI-6517, PCI-6518, PCI-6519, + PCI-6520, PCI-6521, PXI-6521, PCI-6528, PXI-6528 Updated: Wed Oct 18 08:59:11 EDT 2006 Based on the PCI-6527 driver by ds. @@ -418,9 +419,10 @@ static int ni_65xx_dio_insn_bits(struct comedi_device *dev, return -EINVAL; base_bitfield_channel = CR_CHAN(insn->chanspec); for (j = 0; j < max_ports_per_bitfield; ++j) { - const unsigned port_offset = ni_65xx_port_by_channel(base_bitfield_channel) + j; + const unsigned port_offset = + ni_65xx_port_by_channel(base_bitfield_channel) + j; const unsigned port = - sprivate(s)->base_port + port_offset; + sprivate(s)->base_port + port_offset; unsigned base_port_channel; unsigned port_mask, port_data, port_read_bits; int bitshift; @@ -463,11 +465,11 @@ static int ni_65xx_dio_insn_bits(struct comedi_device *dev, * subdevice.) */ port_read_bits ^= 0xFF; } - if (bitshift > 0) { + if (bitshift > 0) port_read_bits <<= bitshift; - } else { + else port_read_bits >>= -bitshift; - } + read_bits |= port_read_bits; } data[1] = read_bits; @@ -532,7 +534,8 @@ static int ni_65xx_intr_cmdtest(struct comedi_device *dev, if (err) return 1; - /* step 2: make sure trigger sources are unique and mutually compatible */ + /* step 2: make sure trigger sources are unique and mutually + compatible */ if (err) return 2; @@ -652,7 +655,7 @@ static int ni_65xx_attach(struct comedi_device *dev, unsigned i; int ret; - printk("comedi%d: ni_65xx:", dev->minor); + printk(KERN_INFO "comedi%d: ni_65xx:", dev->minor); ret = alloc_private(dev, sizeof(struct ni_65xx_private)); if (ret < 0) @@ -664,15 +667,15 @@ static int ni_65xx_attach(struct comedi_device *dev, ret = mite_setup(private(dev)->mite); if (ret < 0) { - printk("error setting up mite\n"); + printk(KERN_WARNING "error setting up mite\n"); return ret; } dev->board_name = board(dev)->name; dev->irq = mite_irq(private(dev)->mite); - printk(" %s", dev->board_name); + printk(KERN_INFO " %s", dev->board_name); - printk(" ID=0x%02x", + printk(KERN_INFO " ID=0x%02x", readb(private(dev)->mite->daq_io_addr + ID_Register)); ret = alloc_subdevices(dev, 4); @@ -773,7 +776,7 @@ static int ni_65xx_attach(struct comedi_device *dev, "ni_65xx", dev); if (ret < 0) { dev->irq = 0; - printk(" irq not available"); + printk(KERN_WARNING " irq not available"); } printk("\n"); @@ -790,21 +793,17 @@ static int ni_65xx_detach(struct comedi_device *dev) Master_Interrupt_Control); } - if (dev->irq) { + if (dev->irq) free_irq(dev->irq, dev); - } if (private(dev)) { unsigned i; for (i = 0; i < dev->n_subdevices; ++i) { - if (dev->subdevices[i].private) { - kfree(dev->subdevices[i].private); - dev->subdevices[i].private = NULL; - } + kfree(dev->subdevices[i].private); + dev->subdevices[i].private = NULL; } - if (private(dev)->mite) { + if (private(dev)->mite) mite_unsetup(private(dev)->mite); - } } return 0; } @@ -830,7 +829,7 @@ static int ni_65xx_find_device(struct comedi_device *dev, int bus, int slot) } } } - printk("no device found\n"); + printk(KERN_WARNING "no device found\n"); mite_list_devices(); return -EIO; } diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 404d3c5..017630f 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -52,7 +52,8 @@ enum ni_660x_constants { }; #define NUM_PFI_CHANNELS 40 -/* really there are only up to 3 dma channels, but the register layout allows for 4 */ +/* really there are only up to 3 dma channels, but the register layout allows +for 4 */ #define MAX_DMA_CHANNEL 4 /* See Register-Level Programmer Manual page 3.1 */ @@ -198,7 +199,7 @@ struct NI_660xRegisterData { const char *name; /* Register Name */ int offset; /* Offset from base address from GPCT chip */ enum ni_660x_register_direction direction; - enum ni_660x_register_width size; /* 1 byte, 2 bytes, or 4 bytes */ + enum ni_660x_register_width size; /* 1 byte, 2 bytes, or 4 bytes */ }; static const struct NI_660xRegisterData registerData[NumRegisters] = { @@ -382,8 +383,8 @@ enum global_interrupt_config_register_bits { }; /* Offset of the GPCT chips from the base-adress of the card */ -static const unsigned GPCT_OFFSET[2] = { 0x0, 0x800 }; /* First chip is at base-address + - 0x00, etc. */ +/* First chip is at base-address + 0x00, etc. */ +static const unsigned GPCT_OFFSET[2] = { 0x0, 0x800 }; /* Board description*/ struct ni_660x_board { @@ -691,13 +692,13 @@ static enum NI_660x_Register ni_gpct_to_660x_register(enum ni_gpct_register reg) ni_660x_register = G0StatusRegister; break; case NITIO_G1_Status_Reg: - ni_660x_register = G0StatusRegister; + ni_660x_register = G1StatusRegister; break; case NITIO_G2_Status_Reg: - ni_660x_register = G0StatusRegister; + ni_660x_register = G2StatusRegister; break; case NITIO_G3_Status_Reg: - ni_660x_register = G0StatusRegister; + ni_660x_register = G3StatusRegister; break; case NITIO_G0_Interrupt_Enable_Reg: ni_660x_register = G0InterruptEnable; @@ -712,7 +713,7 @@ static enum NI_660x_Register ni_gpct_to_660x_register(enum ni_gpct_register reg) ni_660x_register = G3InterruptEnable; break; default: - printk("%s: unhandled register 0x%x in switch.\n", + printk(KERN_WARNING "%s: unhandled register 0x%x in switch.\n", __func__, reg); BUG(); return 0; @@ -737,7 +738,7 @@ static inline void ni_660x_write_register(struct comedi_device *dev, writel(bits, write_address); break; default: - printk("%s: %s: bug! unhandled case (reg=0x%x) in switch.\n", + printk(KERN_WARNING "%s: %s: bug! unhandled case (reg=0x%x) in switch.\n", __FILE__, __func__, reg); BUG(); break; @@ -760,7 +761,7 @@ static inline unsigned ni_660x_read_register(struct comedi_device *dev, return readl(read_address); break; default: - printk("%s: %s: bug! unhandled case (reg=0x%x) in switch.\n", + printk(KERN_WARNING "%s: %s: bug! unhandled case (reg=0x%x) in switch.\n", __FILE__, __func__, reg); BUG(); break; @@ -993,9 +994,9 @@ static int ni_660x_allocate_private(struct comedi_device *dev) spin_lock_init(&private(dev)->mite_channel_lock); spin_lock_init(&private(dev)->interrupt_lock); spin_lock_init(&private(dev)->soft_reg_copy_lock); - for (i = 0; i < NUM_PFI_CHANNELS; ++i) { + for (i = 0; i < NUM_PFI_CHANNELS; ++i) private(dev)->pfi_output_selects[i] = pfi_output_select_counter; - } + return 0; } @@ -1008,9 +1009,8 @@ static int ni_660x_alloc_mite_rings(struct comedi_device *dev) for (j = 0; j < counters_per_chip; ++j) { private(dev)->mite_rings[i][j] = mite_alloc_ring(private(dev)->mite); - if (private(dev)->mite_rings[i][j] == NULL) { + if (private(dev)->mite_rings[i][j] == NULL) return -ENOMEM; - } } } return 0; @@ -1022,9 +1022,8 @@ static void ni_660x_free_mite_rings(struct comedi_device *dev) unsigned j; for (i = 0; i < board(dev)->n_chips; ++i) { - for (j = 0; j < counters_per_chip; ++j) { + for (j = 0; j < counters_per_chip; ++j) mite_free_ring(private(dev)->mite_rings[i][j]); - } } } @@ -1036,7 +1035,7 @@ static int ni_660x_attach(struct comedi_device *dev, unsigned i; unsigned global_interrupt_config_bits; - printk("comedi%d: ni_660x: ", dev->minor); + printk(KERN_INFO "comedi%d: ni_660x: ", dev->minor); ret = ni_660x_allocate_private(dev); if (ret < 0) @@ -1049,7 +1048,7 @@ static int ni_660x_attach(struct comedi_device *dev, ret = mite_setup2(private(dev)->mite, 1); if (ret < 0) { - printk("error setting up mite\n"); + printk(KERN_WARNING "error setting up mite\n"); return ret; } comedi_set_hw_dev(dev, &private(dev)->mite->pcidev->dev); @@ -1057,7 +1056,7 @@ static int ni_660x_attach(struct comedi_device *dev, if (ret < 0) return ret; - printk(" %s ", dev->board_name); + printk(KERN_INFO " %s ", dev->board_name); dev->n_subdevices = 2 + NI_660X_MAX_NUM_COUNTERS; @@ -1078,15 +1077,16 @@ static int ni_660x_attach(struct comedi_device *dev, s->insn_bits = ni_660x_dio_insn_bits; s->insn_config = ni_660x_dio_insn_config; s->io_bits = 0; /* all bits default to input */ - /* we use the ioconfig registers to control dio direction, so zero output enables in stc dio control reg */ + /* we use the ioconfig registers to control dio direction, so zero + output enables in stc dio control reg */ ni_660x_write_register(dev, 0, 0, STCDIOControl); private(dev)->counter_dev = ni_gpct_device_construct(dev, - &ni_gpct_write_register, - &ni_gpct_read_register, - ni_gpct_variant_660x, - ni_660x_num_counters - (dev)); + &ni_gpct_write_register, + &ni_gpct_read_register, + ni_gpct_variant_660x, + ni_660x_num_counters + (dev)); if (private(dev)->counter_dev == NULL) return -ENOMEM; for (i = 0; i < NI_660X_MAX_NUM_COUNTERS; ++i) { @@ -1118,12 +1118,12 @@ static int ni_660x_attach(struct comedi_device *dev, s->type = COMEDI_SUBD_UNUSED; } } - for (i = 0; i < board(dev)->n_chips; ++i) { + for (i = 0; i < board(dev)->n_chips; ++i) init_tio_chip(dev, i); - } - for (i = 0; i < ni_660x_num_counters(dev); ++i) { + + for (i = 0; i < ni_660x_num_counters(dev); ++i) ni_tio_init_counter(&private(dev)->counter_dev->counters[i]); - } + for (i = 0; i < NUM_PFI_CHANNELS; ++i) { if (i < min_counter_pfi_chan) ni_660x_set_pfi_routing(dev, i, pfi_output_select_do); @@ -1134,13 +1134,13 @@ static int ni_660x_attach(struct comedi_device *dev, } /* to be safe, set counterswap bits on tio chips after all the counter outputs have been set to high impedance mode */ - for (i = 0; i < board(dev)->n_chips; ++i) { + for (i = 0; i < board(dev)->n_chips; ++i) set_tio_counterswap(dev, i); - } + ret = request_irq(mite_irq(private(dev)->mite), ni_660x_interrupt, IRQF_SHARED, "ni_660x", dev); if (ret < 0) { - printk(" irq not available\n"); + printk(KERN_WARNING " irq not available\n"); return ret; } dev->irq = mite_irq(private(dev)->mite); @@ -1149,13 +1149,13 @@ static int ni_660x_attach(struct comedi_device *dev, global_interrupt_config_bits |= Cascade_Int_Enable_Bit; ni_660x_write_register(dev, 0, global_interrupt_config_bits, GlobalInterruptConfigRegister); - printk("attached\n"); + printk(KERN_INFO "attached\n"); return 0; } static int ni_660x_detach(struct comedi_device *dev) { - printk("comedi%d: ni_660x: remove\n", dev->minor); + printk(KERN_INFO "comedi%d: ni_660x: remove\n", dev->minor); /* Free irq */ if (dev->irq) @@ -1193,9 +1193,8 @@ static void init_tio_chip(struct comedi_device *dev, int chipset) private(dev)-> dma_configuration_soft_copies[chipset], DMAConfigRegister); - for (i = 0; i < NUM_PFI_CHANNELS; ++i) { + for (i = 0; i < NUM_PFI_CHANNELS; ++i) ni_660x_write_register(dev, chipset, 0, IOConfigReg(i)); - } } static int @@ -1234,7 +1233,7 @@ static int ni_660x_find_device(struct comedi_device *dev, int bus, int slot) } } } - printk("no device found\n"); + printk(KERN_WARNING "no device found\n"); mite_list_devices(); return -EIO; } diff --git a/drivers/staging/comedi/drivers/ni_670x.c b/drivers/staging/comedi/drivers/ni_670x.c index 9b43547..1e792d5 100644 --- a/drivers/staging/comedi/drivers/ni_670x.c +++ b/drivers/staging/comedi/drivers/ni_670x.c @@ -93,7 +93,7 @@ static DEFINE_PCI_DEVICE_TABLE(ni_670x_pci_table) = { { PCI_VENDOR_ID_NATINST, 0x2c90, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { PCI_VENDOR_ID_NATINST, 0x1920, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - /* { PCI_VENDOR_ID_NATINST, 0x0000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, */ + /*{ PCI_VENDOR_ID_NATINST, 0x0000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },*/ { 0} }; @@ -151,7 +151,7 @@ static int ni_670x_attach(struct comedi_device *dev, int ret; int i; - printk("comedi%d: ni_670x: ", dev->minor); + printk(KERN_INFO "comedi%d: ni_670x: ", dev->minor); ret = alloc_private(dev, sizeof(struct ni_670x_private)); if (ret < 0) @@ -163,12 +163,12 @@ static int ni_670x_attach(struct comedi_device *dev, ret = mite_setup(devpriv->mite); if (ret < 0) { - printk("error setting up mite\n"); + printk(KERN_WARNING "error setting up mite\n"); return ret; } dev->board_name = thisboard->name; dev->irq = mite_irq(devpriv->mite); - printk(" %s", dev->board_name); + printk(KERN_INFO " %s", dev->board_name); if (alloc_subdevices(dev, 2) < 0) return -ENOMEM; @@ -207,21 +207,22 @@ static int ni_670x_attach(struct comedi_device *dev, s->insn_bits = ni_670x_dio_insn_bits; s->insn_config = ni_670x_dio_insn_config; - writel(0x10, devpriv->mite->daq_io_addr + MISC_CONTROL_OFFSET); /* Config of misc registers */ - writel(0x00, devpriv->mite->daq_io_addr + AO_CONTROL_OFFSET); /* Config of ao registers */ + /* Config of misc registers */ + writel(0x10, devpriv->mite->daq_io_addr + MISC_CONTROL_OFFSET); + /* Config of ao registers */ + writel(0x00, devpriv->mite->daq_io_addr + AO_CONTROL_OFFSET); - printk("attached\n"); + printk(KERN_INFO "attached\n"); return 1; } static int ni_670x_detach(struct comedi_device *dev) { - printk("comedi%d: ni_670x: remove\n", dev->minor); + printk(KERN_INFO "comedi%d: ni_670x: remove\n", dev->minor); + + kfree(dev->subdevices[0].range_table_list); - if (dev->subdevices[0].range_table_list) { - kfree(dev->subdevices[0].range_table_list); - } if (dev->private && devpriv->mite) mite_unsetup(devpriv->mite); @@ -250,8 +251,11 @@ static int ni_670x_ao_winsn(struct comedi_device *dev, vch(15) : 30 | ich(31) : 31 */ for (i = 0; i < insn->n; i++) { - writel(((chan & 15) << 1) | ((chan & 16) >> 4), devpriv->mite->daq_io_addr + AO_CHAN_OFFSET); /* First write in channel register which channel to use */ - writel(data[i], devpriv->mite->daq_io_addr + AO_VALUE_OFFSET); /* write channel value */ + /* First write in channel register which channel to use */ + writel(((chan & 15) << 1) | ((chan & 16) >> 4), + devpriv->mite->daq_io_addr + AO_CHAN_OFFSET); + /* write channel value */ + writel(data[i], devpriv->mite->daq_io_addr + AO_VALUE_OFFSET); devpriv->ao_readback[chan] = data[i]; } @@ -344,7 +348,7 @@ static int ni_670x_find_device(struct comedi_device *dev, int bus, int slot) } } } - printk("no device found\n"); + printk(KERN_INFO "no device found\n"); mite_list_devices(); return -EIO; } diff --git a/drivers/staging/comedi/drivers/ni_atmio.c b/drivers/staging/comedi/drivers/ni_atmio.c index 8ead311..003d00b 100644 --- a/drivers/staging/comedi/drivers/ni_atmio.c +++ b/drivers/staging/comedi/drivers/ni_atmio.c @@ -329,11 +329,11 @@ static uint16_t ni_atmio_win_in(struct comedi_device *dev, int addr) } static struct pnp_device_id device_ids[] = { - {.id = "NIC1900",.driver_data = 0}, - {.id = "NIC2400",.driver_data = 0}, - {.id = "NIC2500",.driver_data = 0}, - {.id = "NIC2600",.driver_data = 0}, - {.id = "NIC2700",.driver_data = 0}, + {.id = "NIC1900", .driver_data = 0}, + {.id = "NIC2400", .driver_data = 0}, + {.id = "NIC2500", .driver_data = 0}, + {.id = "NIC2600", .driver_data = 0}, + {.id = "NIC2700", .driver_data = 0}, {.id = ""} }; @@ -362,9 +362,9 @@ static int ni_atmio_detach(struct comedi_device *dev) if (dev->iobase) release_region(dev->iobase, NI_SIZE); - if (dev->irq) { + if (dev->irq) free_irq(dev->irq, dev); - } + if (devpriv->isapnp_dev) pnp_device_detach(devpriv->isapnp_dev); @@ -387,8 +387,8 @@ static int ni_isapnp_find_board(struct pnp_dev **dev) if (pnp_device_attach(isapnp_dev) < 0) { printk - ("ni_atmio: %s found but already active, skipping.\n", - ni_boards[i].name); + ("ni_atmio: %s found but already active, skipping.\n", + ni_boards[i].name); continue; } if (pnp_activate_dev(isapnp_dev) < 0) { @@ -496,9 +496,9 @@ static int ni_atmio_attach(struct comedi_device *dev, /* generic E series stuff in ni_mio_common.c */ ret = ni_E_init(dev, it); - if (ret < 0) { + if (ret < 0) return ret; - } + return 0; } @@ -509,16 +509,16 @@ static int ni_getboardtype(struct comedi_device *dev) int i; for (i = 0; i < n_ni_boards; i++) { - if (ni_boards[i].device_id == device_id) { + if (ni_boards[i].device_id == device_id) return i; - } + } - if (device_id == 255) { + if (device_id == 255) printk(" can't find board\n"); - } else if (device_id == 0) { + else if (device_id == 0) printk(" EEPROM read error (?) or device not found\n"); - } else { + else printk(" unknown device ID %d -- contact author\n", device_id); - } + return -1; } diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index ef5e118..c9b0395 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c @@ -76,13 +76,15 @@ struct dio700_board { static const struct dio700_board dio700_boards[] = { { .name = "daqcard-700", - .device_id = 0x4743, /* 0x10b is manufacturer id, 0x4743 is device id */ + /* 0x10b is manufacturer id, 0x4743 is device id */ + .device_id = 0x4743, .bustype = pcmcia_bustype, .have_dio = 1, }, { .name = "ni_daq_700", - .device_id = 0x4743, /* 0x10b is manufacturer id, 0x4743 is device id */ + /* 0x10b is manufacturer id, 0x4743 is device id */ + .device_id = 0x4743, .bustype = pcmcia_bustype, .have_dio = 1, }, @@ -309,11 +311,11 @@ int subdev_700_init(struct comedi_device *dev, struct comedi_subdevice *s, return -ENOMEM; CALLBACK_ARG = arg; - if (cb == NULL) { + if (cb == NULL) CALLBACK_FUNC = subdev_700_cb; - } else { + else CALLBACK_FUNC = cb; - } + s->insn_bits = subdev_700_insn; s->insn_config = subdev_700_insn_config; @@ -345,12 +347,10 @@ int subdev_700_init_irq(struct comedi_device *dev, struct comedi_subdevice *s, void subdev_700_cleanup(struct comedi_device *dev, struct comedi_subdevice *s) { - if (s->private) { - if (subdevpriv->have_irq) { - } + if (s->private) + if (subdevpriv->have_irq) - kfree(s->private); - } + kfree(s->private); } EXPORT_SYMBOL(subdev_700_init); @@ -390,9 +390,9 @@ static int dio700_attach(struct comedi_device *dev, struct comedi_devconfig *it) printk("comedi%d: ni_daq_700: %s, io 0x%lx", dev->minor, thisboard->name, iobase); #ifdef incomplete - if (irq) { + if (irq) printk(", irq %u", irq); - } + #endif printk("\n"); diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c index dc3f398..3c88caa 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.c +++ b/drivers/staging/comedi/drivers/ni_labpc.c @@ -90,8 +90,10 @@ NI manuals: #define DRV_NAME "ni_labpc" -#define LABPC_SIZE 32 /* size of io region used by board */ -#define LABPC_TIMER_BASE 500 /* 2 MHz master clock */ +/* size of io region used by board */ +#define LABPC_SIZE 32 +/* 2 MHz master clock */ +#define LABPC_TIMER_BASE 500 /* Registers for the lab-pc+ */ @@ -99,69 +101,110 @@ NI manuals: #define COMMAND1_REG 0x0 #define ADC_GAIN_MASK (0x7 << 4) #define ADC_CHAN_BITS(x) ((x) & 0x7) -#define ADC_SCAN_EN_BIT 0x80 /* enables multi channel scans */ +/* enables multi channel scans */ +#define ADC_SCAN_EN_BIT 0x80 #define COMMAND2_REG 0x1 -#define PRETRIG_BIT 0x1 /* enable pretriggering (used in conjunction with SWTRIG) */ -#define HWTRIG_BIT 0x2 /* enable paced conversions on external trigger */ -#define SWTRIG_BIT 0x4 /* enable paced conversions */ -#define CASCADE_BIT 0x8 /* use two cascaded counters for pacing */ +/* enable pretriggering (used in conjunction with SWTRIG) */ +#define PRETRIG_BIT 0x1 +/* enable paced conversions on external trigger */ +#define HWTRIG_BIT 0x2 +/* enable paced conversions */ +#define SWTRIG_BIT 0x4 +/* use two cascaded counters for pacing */ +#define CASCADE_BIT 0x8 #define DAC_PACED_BIT(channel) (0x40 << ((channel) & 0x1)) #define COMMAND3_REG 0x2 -#define DMA_EN_BIT 0x1 /* enable dma transfers */ -#define DIO_INTR_EN_BIT 0x2 /* enable interrupts for 8255 */ -#define DMATC_INTR_EN_BIT 0x4 /* enable dma terminal count interrupt */ -#define TIMER_INTR_EN_BIT 0x8 /* enable timer interrupt */ -#define ERR_INTR_EN_BIT 0x10 /* enable error interrupt */ -#define ADC_FNE_INTR_EN_BIT 0x20 /* enable fifo not empty interrupt */ +/* enable dma transfers */ +#define DMA_EN_BIT 0x1 +/* enable interrupts for 8255 */ +#define DIO_INTR_EN_BIT 0x2 +/* enable dma terminal count interrupt */ +#define DMATC_INTR_EN_BIT 0x4 +/* enable timer interrupt */ +#define TIMER_INTR_EN_BIT 0x8 +/* enable error interrupt */ +#define ERR_INTR_EN_BIT 0x10 +/* enable fifo not empty interrupt */ +#define ADC_FNE_INTR_EN_BIT 0x20 #define ADC_CONVERT_REG 0x3 #define DAC_LSB_REG(channel) (0x4 + 2 * ((channel) & 0x1)) #define DAC_MSB_REG(channel) (0x5 + 2 * ((channel) & 0x1)) #define ADC_CLEAR_REG 0x8 #define DMATC_CLEAR_REG 0xa #define TIMER_CLEAR_REG 0xc -#define COMMAND6_REG 0xe /* 1200 boards only */ -#define ADC_COMMON_BIT 0x1 /* select ground or common-mode reference */ -#define ADC_UNIP_BIT 0x2 /* adc unipolar */ -#define DAC_UNIP_BIT(channel) (0x4 << ((channel) & 0x1)) /* dac unipolar */ -#define ADC_FHF_INTR_EN_BIT 0x20 /* enable fifo half full interrupt */ -#define A1_INTR_EN_BIT 0x40 /* enable interrupt on end of hardware count */ -#define ADC_SCAN_UP_BIT 0x80 /* scan up from channel zero instead of down to zero */ +/* 1200 boards only */ +#define COMMAND6_REG 0xe +/* select ground or common-mode reference */ +#define ADC_COMMON_BIT 0x1 +/* adc unipolar */ +#define ADC_UNIP_BIT 0x2 +/* dac unipolar */ +#define DAC_UNIP_BIT(channel) (0x4 << ((channel) & 0x1)) +/* enable fifo half full interrupt */ +#define ADC_FHF_INTR_EN_BIT 0x20 +/* enable interrupt on end of hardware count */ +#define A1_INTR_EN_BIT 0x40 +/* scan up from channel zero instead of down to zero */ +#define ADC_SCAN_UP_BIT 0x80 #define COMMAND4_REG 0xf -#define INTERVAL_SCAN_EN_BIT 0x1 /* enables 'interval' scanning */ -#define EXT_SCAN_EN_BIT 0x2 /* enables external signal on counter b1 output to trigger scan */ -#define EXT_CONVERT_OUT_BIT 0x4 /* chooses direction (output or input) for EXTCONV* line */ -#define ADC_DIFF_BIT 0x8 /* chooses differential inputs for adc (in conjunction with board jumper) */ +/* enables 'interval' scanning */ +#define INTERVAL_SCAN_EN_BIT 0x1 +/* enables external signal on counter b1 output to trigger scan */ +#define EXT_SCAN_EN_BIT 0x2 +/* chooses direction (output or input) for EXTCONV* line */ +#define EXT_CONVERT_OUT_BIT 0x4 +/* chooses differential inputs for adc (in conjunction with board jumper) */ +#define ADC_DIFF_BIT 0x8 #define EXT_CONVERT_DISABLE_BIT 0x10 -#define COMMAND5_REG 0x1c /* 1200 boards only, calibration stuff */ -#define EEPROM_WRITE_UNPROTECT_BIT 0x4 /* enable eeprom for write */ -#define DITHER_EN_BIT 0x8 /* enable dithering */ -#define CALDAC_LOAD_BIT 0x10 /* load calibration dac */ -#define SCLOCK_BIT 0x20 /* serial clock - rising edge writes, falling edge reads */ -#define SDATA_BIT 0x40 /* serial data bit for writing to eeprom or calibration dacs */ -#define EEPROM_EN_BIT 0x80 /* enable eeprom for read/write */ +/* 1200 boards only, calibration stuff */ +#define COMMAND5_REG 0x1c +/* enable eeprom for write */ +#define EEPROM_WRITE_UNPROTECT_BIT 0x4 +/* enable dithering */ +#define DITHER_EN_BIT 0x8 +/* load calibration dac */ +#define CALDAC_LOAD_BIT 0x10 +/* serial clock - rising edge writes, falling edge reads */ +#define SCLOCK_BIT 0x20 +/* serial data bit for writing to eeprom or calibration dacs */ +#define SDATA_BIT 0x40 +/* enable eeprom for read/write */ +#define EEPROM_EN_BIT 0x80 #define INTERVAL_COUNT_REG 0x1e #define INTERVAL_LOAD_REG 0x1f #define INTERVAL_LOAD_BITS 0x1 /* read-only registers */ #define STATUS1_REG 0x0 -#define DATA_AVAIL_BIT 0x1 /* data is available in fifo */ -#define OVERRUN_BIT 0x2 /* overrun has occurred */ -#define OVERFLOW_BIT 0x4 /* fifo overflow */ -#define TIMER_BIT 0x8 /* timer interrupt has occured */ -#define DMATC_BIT 0x10 /* dma terminal count has occured */ -#define EXT_TRIG_BIT 0x40 /* external trigger has occured */ -#define STATUS2_REG 0x1d /* 1200 boards only */ -#define EEPROM_OUT_BIT 0x1 /* programmable eeprom serial output */ -#define A1_TC_BIT 0x2 /* counter A1 terminal count */ -#define FNHF_BIT 0x4 /* fifo not half full */ +/* data is available in fifo */ +#define DATA_AVAIL_BIT 0x1 +/* overrun has occurred */ +#define OVERRUN_BIT 0x2 +/* fifo overflow */ +#define OVERFLOW_BIT 0x4 +/* timer interrupt has occured */ +#define TIMER_BIT 0x8 +/* dma terminal count has occured */ +#define DMATC_BIT 0x10 +/* external trigger has occured */ +#define EXT_TRIG_BIT 0x40 +/* 1200 boards only */ +#define STATUS2_REG 0x1d +/* programmable eeprom serial output */ +#define EEPROM_OUT_BIT 0x1 +/* counter A1 terminal count */ +#define A1_TC_BIT 0x2 +/* fifo not half full */ +#define FNHF_BIT 0x4 #define ADC_FIFO_REG 0xa #define DIO_BASE_REG 0x10 #define COUNTER_A_BASE_REG 0x14 #define COUNTER_A_CONTROL_REG (COUNTER_A_BASE_REG + 0x3) -#define INIT_A0_BITS 0x14 /* check modes put conversion pacer output in harmless state (a0 mode 2) */ -#define INIT_A1_BITS 0x70 /* put hardware conversion counter output in harmless state (a1 mode 0) */ +/* check modes put conversion pacer output in harmless state (a0 mode 2) */ +#define INIT_A0_BITS 0x14 +/* put hardware conversion counter output in harmless state (a1 mode 0) */ +#define INIT_A1_BITS 0x70 #define COUNTER_B_BASE_REG 0x18 static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it); @@ -423,7 +466,7 @@ static const struct labpc_board_struct labpc_boards[] = { .ai_scan_up = 1, .memory_mapped_io = 1, }, - /* dummy entry so pci board works when comedi_config is passed driver name */ +/* dummy entry so pci board works when comedi_config is passed driver name */ { .name = DRV_NAME, .bustype = pci_bustype, @@ -436,8 +479,10 @@ static const struct labpc_board_struct labpc_boards[] = { */ #define thisboard ((struct labpc_board_struct *)dev->board_ptr) -static const int dma_buffer_size = 0xff00; /* size in bytes of dma buffer */ -static const int sample_size = 2; /* 2 bytes per sample */ +/* size in bytes of dma buffer */ +static const int dma_buffer_size = 0xff00; +/* 2 bytes per sample */ +static const int sample_size = 2; #define devpriv ((struct labpc_private *)dev->private) @@ -483,12 +528,10 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase, printk("comedi%d: ni_labpc: %s, io 0x%lx", dev->minor, thisboard->name, iobase); - if (irq) { + if (irq) printk(", irq %u", irq); - } - if (dma_chan) { + if (dma_chan) printk(", dma %u", dma_chan); - } printk("\n"); if (iobase == 0) { @@ -513,7 +556,7 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase, devpriv->read_byte = labpc_inb; devpriv->write_byte = labpc_outb; } - /* initialize board's command registers */ + /* initialize board's command registers */ devpriv->write_byte(devpriv->command1_bits, dev->iobase + COMMAND1_REG); devpriv->write_byte(devpriv->command2_bits, dev->iobase + COMMAND2_REG); devpriv->write_byte(devpriv->command3_bits, dev->iobase + COMMAND3_REG); @@ -538,12 +581,12 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase, } dev->irq = irq; - /* grab dma channel */ + /* grab dma channel */ if (dma_chan > 3) { printk(" invalid dma channel %u\n", dma_chan); return -EINVAL; } else if (dma_chan) { - /* allocate dma buffer */ + /* allocate dma buffer */ devpriv->dma_buffer = kmalloc(dma_buffer_size, GFP_KERNEL | GFP_DMA); if (devpriv->dma_buffer == NULL) { @@ -575,7 +618,7 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase, SDF_READABLE | SDF_GROUND | SDF_COMMON | SDF_DIFF | SDF_CMD_READ; s->n_chan = 8; s->len_chanlist = 8; - s->maxdata = (1 << 12) - 1; /* 12 bit resolution */ + s->maxdata = (1 << 12) - 1; /* 12 bit resolution */ s->range_table = thisboard->ai_range_table; s->do_cmd = labpc_ai_cmd; s->do_cmdtest = labpc_ai_cmdtest; @@ -585,8 +628,11 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase, /* analog output */ s = dev->subdevices + 1; if (thisboard->has_ao) { -/* Could provide command support, except it only has a one sample - * hardware buffer for analog output and no underrun flag. */ + /* + * Could provide command support, except it only has a + * one sample hardware buffer for analog output and no + * underrun flag. + */ s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND; s->n_chan = NUM_AO_CHAN; @@ -608,7 +654,8 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase, /* 8255 dio */ s = dev->subdevices + 2; - /* if board uses io memory we have to give a custom callback function to the 8255 driver */ + /* if board uses io memory we have to give a custom callback + * function to the 8255 driver */ if (thisboard->memory_mapped_io) subdev_8255_init(dev, s, labpc_dio_mem_callback, (unsigned long)(dev->iobase + DIO_BASE_REG)); @@ -640,14 +687,12 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase, s->insn_read = labpc_eeprom_read_insn; s->insn_write = labpc_eeprom_write_insn; - for (i = 0; i < EEPROM_SIZE; i++) { + for (i = 0; i < EEPROM_SIZE; i++) devpriv->eeprom_data[i] = labpc_eeprom_read(dev, i); - } #ifdef LABPC_DEBUG printk(" eeprom:"); - for (i = 0; i < EEPROM_SIZE; i++) { + for (i = 0; i < EEPROM_SIZE; i++) printk(" %i:0x%x ", i, devpriv->eeprom_data[i]); - } printk("\n"); #endif } else @@ -669,7 +714,7 @@ static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (alloc_private(dev, sizeof(struct labpc_private)) < 0) return -ENOMEM; - /* get base address, irq etc. based on bustype */ + /* get base address, irq etc. based on bustype */ switch (thisboard->bustype) { case isa_bustype: iobase = it->options[0]; @@ -679,9 +724,8 @@ static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it) case pci_bustype: #ifdef CONFIG_COMEDI_PCI retval = labpc_find_device(dev, it->options[0], it->options[1]); - if (retval < 0) { + if (retval < 0) return retval; - } retval = mite_setup(devpriv->mite); if (retval < 0) return retval; @@ -715,7 +759,7 @@ static int labpc_find_device(struct comedi_device *dev, int bus, int slot) for (mite = mite_devices; mite; mite = mite->next) { if (mite->used) continue; - /* if bus/slot are specified then make sure we have the right bus/slot */ +/* if bus/slot are specified then make sure we have the right bus/slot */ if (bus || slot) { if (bus != mite->pcidev->bus->number || slot != PCI_SLOT(mite->pcidev->devfn)) @@ -726,7 +770,7 @@ static int labpc_find_device(struct comedi_device *dev, int bus, int slot) continue; if (mite_device_id(mite) == labpc_boards[i].device_id) { devpriv->mite = mite; - /* fixup board pointer, in case we were using the dummy "ni_labpc" entry */ +/* fixup board pointer, in case we were using the dummy "ni_labpc" entry */ dev->board_ptr = &labpc_boards[i]; return 0; } @@ -994,7 +1038,7 @@ static int labpc_ai_cmdtest(struct comedi_device *dev, cmd->stop_src != TRIG_EXT && cmd->stop_src != TRIG_NONE) err++; - /* can't have external stop and start triggers at once */ + /* can't have external stop and start triggers at once */ if (cmd->start_src == TRIG_EXT && cmd->stop_src == TRIG_EXT) err++; @@ -1008,9 +1052,9 @@ static int labpc_ai_cmdtest(struct comedi_device *dev, err++; } - if (!cmd->chanlist_len) { + if (!cmd->chanlist_len) err++; - } + if (cmd->scan_end_arg != cmd->chanlist_len) { cmd->scan_end_arg = cmd->chanlist_len; err++; @@ -1022,7 +1066,7 @@ static int labpc_ai_cmdtest(struct comedi_device *dev, err++; } } - /* make sure scan timing is not too fast */ + /* make sure scan timing is not too fast */ if (cmd->scan_begin_src == TRIG_TIMER) { if (cmd->convert_src == TRIG_TIMER && cmd->scan_begin_arg < @@ -1038,7 +1082,7 @@ static int labpc_ai_cmdtest(struct comedi_device *dev, err++; } } - /* stop source */ + /* stop source */ switch (cmd->stop_src) { case TRIG_COUNT: if (!cmd->stop_arg) { @@ -1095,7 +1139,7 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) range = CR_RANGE(cmd->chanlist[0]); aref = CR_AREF(cmd->chanlist[0]); - /* make sure board is disabled before setting up aquisition */ + /* make sure board is disabled before setting up aquisition */ spin_lock_irqsave(&dev->spinlock, flags); devpriv->command2_bits &= ~SWTRIG_BIT & ~HWTRIG_BIT & ~PRETRIG_BIT; devpriv->write_byte(devpriv->command2_bits, dev->iobase + COMMAND2_REG); @@ -1105,9 +1149,9 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) devpriv->write_byte(devpriv->command3_bits, dev->iobase + COMMAND3_REG); /* initialize software conversion count */ - if (cmd->stop_src == TRIG_COUNT) { + if (cmd->stop_src == TRIG_COUNT) devpriv->count = cmd->stop_arg * cmd->chanlist_len; - } + /* setup hardware conversion counter */ if (cmd->stop_src == TRIG_EXT) { /* load counter a1 with count of 3 (pc+ manual says this is minimum allowed) using mode 0 */ @@ -1176,17 +1220,18 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) channel = CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1]); else channel = CR_CHAN(cmd->chanlist[0]); - /* munge channel bits for differential / scan disabled mode */ + /* munge channel bits for differential / scan disabled mode */ if (labpc_ai_scan_mode(cmd) != MODE_SINGLE_CHAN && aref == AREF_DIFF) channel *= 2; devpriv->command1_bits |= ADC_CHAN_BITS(channel); devpriv->command1_bits |= thisboard->ai_range_code[range]; devpriv->write_byte(devpriv->command1_bits, dev->iobase + COMMAND1_REG); - /* manual says to set scan enable bit on second pass */ + /* manual says to set scan enable bit on second pass */ if (labpc_ai_scan_mode(cmd) == MODE_MULT_CHAN_UP || labpc_ai_scan_mode(cmd) == MODE_MULT_CHAN_DOWN) { devpriv->command1_bits |= ADC_SCAN_EN_BIT; - /* need a brief delay before enabling scan, or scan list will get screwed when you switch + /* need a brief delay before enabling scan, or scan + * list will get screwed when you switch * between scan up to scan down mode - dunno why */ udelay(1); devpriv->write_byte(devpriv->command1_bits, @@ -1338,7 +1383,7 @@ static irqreturn_t labpc_interrupt(int irq, void *d) cmd = &async->cmd; async->events = 0; - /* read board status */ + /* read board status */ devpriv->status1_bits = devpriv->read_byte(dev->iobase + STATUS1_REG); if (thisboard->register_layout == labpc_1200_layout) devpriv->status2_bits = @@ -1352,7 +1397,7 @@ static irqreturn_t labpc_interrupt(int irq, void *d) } if (devpriv->status1_bits & OVERRUN_BIT) { - /* clear error interrupt */ + /* clear error interrupt */ devpriv->write_byte(0x1, dev->iobase + ADC_CLEAR_REG); async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; comedi_event(dev, s); @@ -1361,7 +1406,10 @@ static irqreturn_t labpc_interrupt(int irq, void *d) } if (devpriv->current_transfer == isa_dma_transfer) { - /* if a dma terminal count of external stop trigger has occurred */ + /* + * if a dma terminal count of external stop trigger + * has occurred + */ if (devpriv->status1_bits & DMATC_BIT || (thisboard->register_layout == labpc_1200_layout && devpriv->status2_bits & A1_TC_BIT)) { @@ -1479,9 +1527,9 @@ static void labpc_drain_dma(struct comedi_device *dev) } /* write data to comedi buffer */ - for (i = 0; i < num_points; i++) { + for (i = 0; i < num_points; i++) cfc_write_to_buffer(s, devpriv->dma_buffer[i]); - } + if (async->cmd.stop_src == TRIG_COUNT) devpriv->count -= num_points; @@ -1503,7 +1551,7 @@ static void handle_isa_dma(struct comedi_device *dev) devpriv->write_byte(0x1, dev->iobase + DMATC_CLEAR_REG); } -/* makes sure all data aquired by board is transfered to comedi (used +/* makes sure all data acquired by board is transfered to comedi (used * when aquisition is terminated by stop_src == TRIG_EXT). */ static void labpc_drain_dregs(struct comedi_device *dev) { @@ -1537,41 +1585,41 @@ static int labpc_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, chan = CR_CHAN(insn->chanspec); range = CR_RANGE(insn->chanspec); devpriv->command1_bits |= thisboard->ai_range_code[range]; - /* munge channel bits for differential/scan disabled mode */ + /* munge channel bits for differential/scan disabled mode */ if (CR_AREF(insn->chanspec) == AREF_DIFF) chan *= 2; devpriv->command1_bits |= ADC_CHAN_BITS(chan); devpriv->write_byte(devpriv->command1_bits, dev->iobase + COMMAND1_REG); - /* setup command6 register for 1200 boards */ + /* setup command6 register for 1200 boards */ if (thisboard->register_layout == labpc_1200_layout) { /* reference inputs to ground or common? */ if (CR_AREF(insn->chanspec) != AREF_GROUND) devpriv->command6_bits |= ADC_COMMON_BIT; else devpriv->command6_bits &= ~ADC_COMMON_BIT; - /* bipolar or unipolar range? */ + /* bipolar or unipolar range? */ if (thisboard->ai_range_is_unipolar[range]) devpriv->command6_bits |= ADC_UNIP_BIT; else devpriv->command6_bits &= ~ADC_UNIP_BIT; - /* don't interrupt on fifo half full */ + /* don't interrupt on fifo half full */ devpriv->command6_bits &= ~ADC_FHF_INTR_EN_BIT; - /* don't enable interrupt on counter a1 terminal count? */ + /* don't enable interrupt on counter a1 terminal count? */ devpriv->command6_bits &= ~A1_INTR_EN_BIT; - /* write to register */ + /* write to register */ devpriv->write_byte(devpriv->command6_bits, dev->iobase + COMMAND6_REG); } - /* setup command4 register */ + /* setup command4 register */ devpriv->command4_bits = 0; devpriv->command4_bits |= EXT_CONVERT_DISABLE_BIT; - /* single-ended/differential */ + /* single-ended/differential */ if (CR_AREF(insn->chanspec) == AREF_DIFF) devpriv->command4_bits |= ADC_DIFF_BIT; devpriv->write_byte(devpriv->command4_bits, dev->iobase + COMMAND4_REG); - /* initialize pacer counter output to make sure it doesn't cause any problems */ + /* initialize pacer counter output to make sure it doesn't cause any problems */ devpriv->write_byte(INIT_A0_BITS, dev->iobase + COUNTER_A_CONTROL_REG); labpc_clear_adc_fifo(dev); @@ -1608,7 +1656,7 @@ static int labpc_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, channel = CR_CHAN(insn->chanspec); - /* turn off pacing of analog output channel */ + /* turn off pacing of analog output channel */ /* note: hardware bug in daqcard-1200 means pacing cannot * be independently enabled/disabled for its the two channels */ spin_lock_irqsave(&dev->spinlock, flags); @@ -1616,7 +1664,7 @@ static int labpc_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, devpriv->write_byte(devpriv->command2_bits, dev->iobase + COMMAND2_REG); spin_unlock_irqrestore(&dev->spinlock, flags); - /* set range */ + /* set range */ if (thisboard->register_layout == labpc_1200_layout) { range = CR_RANGE(insn->chanspec); if (range & AO_RANGE_IS_UNIPOLAR) @@ -1627,13 +1675,13 @@ static int labpc_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, devpriv->write_byte(devpriv->command6_bits, dev->iobase + COMMAND6_REG); } - /* send data */ + /* send data */ lsb = data[0] & 0xff; msb = (data[0] >> 8) & 0xff; devpriv->write_byte(lsb, dev->iobase + DAC_LSB_REG(channel)); devpriv->write_byte(msb, dev->iobase + DAC_MSB_REG(channel)); - /* remember value for readback */ + /* remember value for readback */ devpriv->ao_value[channel] = data[0]; return 1; @@ -1705,14 +1753,14 @@ static unsigned int labpc_suggest_transfer_size(struct comedi_cmd cmd) if (cmd.convert_src == TRIG_TIMER) freq = 1000000000 / cmd.convert_arg; - /* return some default value */ + /* return some default value */ else freq = 0xffffffff; - /* make buffer fill in no more than 1/3 second */ + /* make buffer fill in no more than 1/3 second */ size = (freq / 3) * sample_size; - /* set a minimum and maximum size allowed */ + /* set a minimum and maximum size allowed */ if (size > dma_buffer_size) size = dma_buffer_size - dma_buffer_size % sample_size; else if (size < sample_size) @@ -1724,13 +1772,21 @@ static unsigned int labpc_suggest_transfer_size(struct comedi_cmd cmd) /* figures out what counter values to use based on command */ static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd) { - const int max_counter_value = 0x10000; /* max value for 16 bit counter in mode 2 */ - const int min_counter_value = 2; /* min value for 16 bit counter in mode 2 */ + /* max value for 16 bit counter in mode 2 */ + const int max_counter_value = 0x10000; + /* min value for 16 bit counter in mode 2 */ + const int min_counter_value = 2; unsigned int base_period; - /* if both convert and scan triggers are TRIG_TIMER, then they both rely on counter b0 */ + /* + * if both convert and scan triggers are TRIG_TIMER, then they + * both rely on counter b0 + */ if (labpc_ai_convert_period(cmd) && labpc_ai_scan_period(cmd)) { - /* pick the lowest b0 divisor value we can (for maximum input clock speed on convert and scan counters) */ + /* + * pick the lowest b0 divisor value we can (for maximum input + * clock speed on convert and scan counters) + */ devpriv->divisor_b0 = (labpc_ai_scan_period(cmd) - 1) / (LABPC_TIMER_BASE * max_counter_value) + 1; if (devpriv->divisor_b0 < min_counter_value) @@ -1780,7 +1836,10 @@ static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd) base_period * devpriv->divisor_a0); labpc_set_ai_scan_period(cmd, base_period * devpriv->divisor_b1); - /* if only one TRIG_TIMER is used, we can employ the generic cascaded timing functions */ + /* + * if only one TRIG_TIMER is used, we can employ the generic + * cascaded timing functions + */ } else if (labpc_ai_scan_period(cmd)) { unsigned int scan_period; @@ -1864,9 +1923,8 @@ static unsigned int labpc_serial_in(struct comedi_device *dev) udelay(1); devpriv->status2_bits = devpriv->read_byte(dev->iobase + STATUS2_REG); - if (devpriv->status2_bits & EEPROM_OUT_BIT) { + if (devpriv->status2_bits & EEPROM_OUT_BIT) value |= 1 << (value_width - i); - } } return value; @@ -1876,8 +1934,10 @@ static unsigned int labpc_eeprom_read(struct comedi_device *dev, unsigned int address) { unsigned int value; - const int read_instruction = 0x3; /* bits to tell eeprom to expect a read */ - const int write_length = 8; /* 8 bit write lengths to eeprom */ + /* bits to tell eeprom to expect a read */ + const int read_instruction = 0x3; + /* 8 bit write lengths to eeprom */ + const int write_length = 8; /* enable read/write to eeprom */ devpriv->command5_bits &= ~EEPROM_EN_BIT; diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c index d6d49c3..bd16f91 100644 --- a/drivers/staging/comedi/drivers/ni_mio_common.c +++ b/drivers/staging/comedi/drivers/ni_mio_common.c @@ -3795,7 +3795,7 @@ static int ni_cdo_inttrig(struct comedi_device *dev, struct comedi_subdevice *s, #endif int retval = 0; unsigned i; - const unsigned timeout = 100; + const unsigned timeout = 1000; s->async->inttrig = NULL; diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c index 2d88a5b..9d33751 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c @@ -1,8 +1,8 @@ /* comedi/drivers/ni_pcidio.c driver for National Instruments PCI-DIO-96/PCI-6508 - National Instruments PCI-DIO-32HS - National Instruments PCI-6503 + National Instruments PCI-DIO-32HS + National Instruments PCI-6503 COMEDI - Linux Control and Measurement Device Interface Copyright (C) 1999,2002 David A. Schleef <ds@schleef.org> @@ -518,7 +518,8 @@ static irqreturn_t nidio_interrupt(int irq, void *d) ni_pcidio_print_status(status); /* printk("buf[0]=%08x\n",*(unsigned int *)async->prealloc_buf); */ - /* printk("buf[4096]=%08x\n",*(unsigned int *)(async->prealloc_buf+4096)); */ + /* printk("buf[4096]=%08x\n", + *(unsigned int *)(async->prealloc_buf+4096)); */ spin_lock_irqsave(&devpriv->mite_channel_lock, irq_flags); if (devpriv->di_mite_chan) @@ -526,7 +527,9 @@ static irqreturn_t nidio_interrupt(int irq, void *d) #ifdef MITE_DEBUG mite_print_chsr(m_status); #endif - /* printk("mite_bytes_transferred: %d\n",mite_bytes_transferred(mite,DI_DMA_CHAN)); */ + /* printk("mite_bytes_transferred: %d\n", + mite_bytes_transferred(mite,DI_DMA_CHAN)); */ + /* mite_dump_regs(mite); */ if (m_status & CHSR_INT) { if (m_status & CHSR_LINKC) { @@ -565,7 +568,8 @@ static irqreturn_t nidio_interrupt(int irq, void *d) DPRINTK("too much work in interrupt\n"); writeb(0x00, devpriv->mite->daq_io_addr + - Master_DMA_And_Interrupt_Control); + Master_DMA_And_Interrupt_Control + ); goto out; } AuxData = @@ -579,8 +583,10 @@ static irqreturn_t nidio_interrupt(int irq, void *d) flags = readb(devpriv->mite->daq_io_addr + Group_1_Flags); } - /* DPRINTK("buf_int_count: %d\n",async->buf_int_count); */ - /* DPRINTK("1) IntEn=%d,flags=%d,status=%d\n",IntEn,flags,status); */ + /* DPRINTK("buf_int_count: %d\n", + async->buf_int_count); */ + /* DPRINTK("1) IntEn=%d,flags=%d,status=%d\n", + IntEn,flags,status); */ /* ni_pcidio_print_flags(flags); */ /* ni_pcidio_print_status(status); */ async->events |= COMEDI_CB_BLOCK; @@ -627,8 +633,8 @@ static irqreturn_t nidio_interrupt(int irq, void *d) flags = readb(devpriv->mite->daq_io_addr + Group_1_Flags); status = readb(devpriv->mite->daq_io_addr + Interrupt_And_Window_Status); - /* DPRINTK("loop end: IntEn=0x%02x,flags=0x%02x,status=0x%02x\n", */ - /* IntEn,flags,status); */ + /* DPRINTK("loop end: IntEn=0x%02x,flags=0x%02x," + "status=0x%02x\n", IntEn, flags, status); */ /* ni_pcidio_print_flags(flags); */ /* ni_pcidio_print_status(status); */ } @@ -655,11 +661,10 @@ static void ni_pcidio_print_flags(unsigned int flags) { int i; - printk("group_1_flags:"); + printk(KERN_INFO "group_1_flags:"); for (i = 7; i >= 0; i--) { - if (flags & (1 << i)) { + if (flags & (1 << i)) printk(" %s", flags_strings[i]); - } } printk("\n"); } @@ -673,11 +678,10 @@ static void ni_pcidio_print_status(unsigned int flags) { int i; - printk("group_status:"); + printk(KERN_INFO "group_status:"); for (i = 7; i >= 0; i--) { - if (flags & (1 << i)) { + if (flags & (1 << i)) printk(" %s", status_strings[i]); - } } printk("\n"); } @@ -793,7 +797,8 @@ static int ni_pcidio_cmdtest(struct comedi_device *dev, if (err) return 1; - /* step 2: make sure trigger sources are unique and mutually compatible */ + /* step 2: make sure trigger sources are unique and mutually + compatible */ /* note that mutual compatibility is not an issue here */ if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_INT) @@ -974,7 +979,8 @@ static int ni_pcidio_cmd(struct comedi_device *dev, struct comedi_subdevice *s) /* clear and enable interrupts */ writeb(0xff, devpriv->mite->daq_io_addr + Group_1_First_Clear); - /* writeb(ClearExpired,devpriv->mite->daq_io_addr+Group_1_Second_Clear); */ + /* writeb(ClearExpired, + devpriv->mite->daq_io_addr+Group_1_Second_Clear); */ writeb(IntEn, devpriv->mite->daq_io_addr + Interrupt_Control); writeb(0x03, @@ -1052,7 +1058,7 @@ static int ni_pcidio_change(struct comedi_device *dev, } static int pci_6534_load_fpga(struct comedi_device *dev, int fpga_index, - u8 * data, int data_len) + u8 *data, int data_len) { static const int timeout = 1000; int i, j; @@ -1066,9 +1072,8 @@ static int pci_6534_load_fpga(struct comedi_device *dev, int fpga_index, udelay(1); } if (i == timeout) { - printk - ("ni_pcidio: failed to load fpga %i, waiting for status 0x2\n", - fpga_index); + printk(KERN_WARNING "ni_pcidio: failed to load fpga %i, " + "waiting for status 0x2\n", fpga_index); return -EIO; } writew(0x80 | fpga_index, @@ -1079,9 +1084,8 @@ static int pci_6534_load_fpga(struct comedi_device *dev, int fpga_index, udelay(1); } if (i == timeout) { - printk - ("ni_pcidio: failed to load fpga %i, waiting for status 0x3\n", - fpga_index); + printk(KERN_WARNING "ni_pcidio: failed to load fpga %i, " + "waiting for status 0x3\n", fpga_index); return -EIO; } for (j = 0; j + 1 < data_len;) { @@ -1174,9 +1178,10 @@ static int nidio_attach(struct comedi_device *dev, struct comedi_devconfig *it) int n_subdevices; unsigned int irq; - printk("comedi%d: nidio:", dev->minor); + printk(KERN_INFO "comedi%d: nidio:", dev->minor); - if ((ret = alloc_private(dev, sizeof(struct nidio96_private))) < 0) + ret = alloc_private(dev, sizeof(struct nidio96_private)); + if (ret < 0) return ret; spin_lock_init(&devpriv->mite_channel_lock); @@ -1186,7 +1191,7 @@ static int nidio_attach(struct comedi_device *dev, struct comedi_devconfig *it) ret = mite_setup(devpriv->mite); if (ret < 0) { - printk("error setting up mite\n"); + printk(KERN_WARNING "error setting up mite\n"); return ret; } comedi_set_hw_dev(dev, &devpriv->mite->pcidev->dev); @@ -1196,18 +1201,19 @@ static int nidio_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->board_name = this_board->name; irq = mite_irq(devpriv->mite); - printk(" %s", dev->board_name); + printk(KERN_INFO " %s", dev->board_name); if (this_board->uses_firmware) { ret = pci_6534_upload_firmware(dev, it->options); if (ret < 0) return ret; } - if (!this_board->is_diodaq) { + if (!this_board->is_diodaq) n_subdevices = this_board->n_8255; - } else { + else n_subdevices = 1; - } - if ((ret = alloc_subdevices(dev, n_subdevices)) < 0) + + ret = alloc_subdevices(dev, n_subdevices); + if (ret < 0) return ret; if (!this_board->is_diodaq) { @@ -1220,7 +1226,7 @@ static int nidio_attach(struct comedi_device *dev, struct comedi_devconfig *it) } } else { - printk(" rev=%d", + printk(KERN_INFO " rev=%d", readb(devpriv->mite->daq_io_addr + Chip_Version)); s = dev->subdevices + 0; @@ -1253,9 +1259,9 @@ static int nidio_attach(struct comedi_device *dev, struct comedi_devconfig *it) ret = request_irq(irq, nidio_interrupt, IRQF_SHARED, "ni_pcidio", dev); - if (ret < 0) { - printk(" irq not available"); - } + if (ret < 0) + printk(KERN_WARNING " irq not available"); + dev->irq = irq; } @@ -1269,9 +1275,8 @@ static int nidio_detach(struct comedi_device *dev) int i; if (this_board && !this_board->is_diodaq) { - for (i = 0; i < this_board->n_8255; i++) { + for (i = 0; i < this_board->n_8255; i++) subdev_8255_cleanup(dev, dev->subdevices + i); - } } if (dev->irq) @@ -1310,7 +1315,7 @@ static int nidio_find_device(struct comedi_device *dev, int bus, int slot) } } } - printk("no device found\n"); + printk(KERN_WARNING "no device found\n"); mite_list_devices(); return -EIO; } diff --git a/drivers/staging/comedi/drivers/pcl711.c b/drivers/staging/comedi/drivers/pcl711.c index 4914784..a499f70 100644 --- a/drivers/staging/comedi/drivers/pcl711.c +++ b/drivers/staging/comedi/drivers/pcl711.c @@ -207,11 +207,10 @@ static irqreturn_t pcl711_interrupt(int irq, void *d) /* FIXME! Nothing else sets ntrig! */ if (!(--devpriv->ntrig)) { - if (this_board->is_8112) { + if (this_board->is_8112) outb(1, dev->iobase + PCL711_MODE); - } else { + else outb(0, dev->iobase + PCL711_MODE); - } s->async->events |= COMEDI_CB_EOA; } @@ -232,15 +231,15 @@ static void pcl711_set_changain(struct comedi_device *dev, int chan) /* * Set the correct channel. The two channel banks are switched * using the mask value. - * NB: To use differential channels, you should use mask = 0x30, - * but I haven't written the support for this yet. /JJ + * NB: To use differential channels, you should use + * mask = 0x30, but I haven't written the support for this + * yet. /JJ */ - if (chan_register >= 8) { + if (chan_register >= 8) chan_register = 0x20 | (chan_register & 0x7); - } else { + else chan_register |= 0x10; - } } else { outb(chan_register, dev->iobase + PCL711_MUX); } @@ -256,15 +255,13 @@ static int pcl711_ai_insn(struct comedi_device *dev, struct comedi_subdevice *s, for (n = 0; n < insn->n; n++) { /* - * Write the correct mode (software polling) and start polling by writing - * to the trigger register + * Write the correct mode (software polling) and start polling + * by writing to the trigger register */ outb(1, dev->iobase + PCL711_MODE); - if (this_board->is_8112) { - } else { + if (!this_board->is_8112) outb(0, dev->iobase + PCL711_SOFTTRIG); - } i = PCL711_TIMEOUT; while (--i) { @@ -462,9 +459,8 @@ static int pcl711_ao_insn_read(struct comedi_device *dev, int n; int chan = CR_CHAN(insn->chanspec); - for (n = 0; n < insn->n; n++) { + for (n = 0; n < insn->n; n++) data[n] = devpriv->ao_readback[chan]; - } return n; @@ -619,9 +615,8 @@ static int pcl711_attach(struct comedi_device *dev, struct comedi_devconfig *it) this is the "base value" for the mode register, which is used for the irq on the PCL711 */ - if (this_board->is_pcl711b) { + if (this_board->is_pcl711b) devpriv->mode = (dev->irq << 4); - } /* clear DAC */ outb(0, dev->iobase + PCL711_DA0_LO); diff --git a/drivers/staging/comedi/drivers/pcl724.c b/drivers/staging/comedi/drivers/pcl724.c index df1f4ef..0f103c3 100644 --- a/drivers/staging/comedi/drivers/pcl724.c +++ b/drivers/staging/comedi/drivers/pcl724.c @@ -17,7 +17,7 @@ [0] - IO Base [1] - IRQ (0=disable IRQ) IRQ isn't supported at this time! [2] -number of DIO: - 0, 144: 144 DIO configuration + 0, 144: 144 DIO configuration 1, 96: 96 DIO configuration */ /* @@ -137,8 +137,8 @@ static int pcl724_attach(struct comedi_device *dev, struct comedi_devconfig *it) iorange = this_board->io_range; if ((this_board->can_have96) && ((it->options[1] == 1) || (it->options[1] == 96))) - iorange = PCL722_96_SIZE; /* PCL-724 in 96 DIO configuration */ - printk("comedi%d: pcl724: board=%s, 0x%03lx ", dev->minor, + iorange = PCL722_96_SIZE; /* PCL-724 in 96 DIO configuration */ + printk(KERN_INFO "comedi%d: pcl724: board=%s, 0x%03lx ", dev->minor, this_board->name, iobase); if (!request_region(iobase, iorange, "pcl724")) { printk("I/O port conflict\n"); @@ -155,16 +155,16 @@ static int pcl724_attach(struct comedi_device *dev, struct comedi_devconfig *it) irq = it->options[1]; if (irq) { /* we want to use IRQ */ if (((1 << irq) & this_board->IRQbits) == 0) { - printk - (", IRQ %u is out of allowed range, DISABLING IT", - irq); + printk(KERN_WARNING + ", IRQ %u is out of allowed range, " + "DISABLING IT", irq); irq = 0; /* Bad IRQ */ } else { if (request_irq (irq, interrupt_pcl724, 0, "pcl724", dev)) { - printk - (", unable to allocate IRQ %u, DISABLING IT", - irq); + printk(KERN_WARNING + ", unable to allocate IRQ %u, " + "DISABLING IT", irq); irq = 0; /* Can't use IRQ */ } else { printk(", irq=%u", irq); @@ -207,16 +207,14 @@ static int pcl724_detach(struct comedi_device *dev) { int i; -/* printk("comedi%d: pcl724: remove\n",dev->minor); */ + /* printk("comedi%d: pcl724: remove\n",dev->minor); */ - for (i = 0; i < dev->n_subdevices; i++) { + for (i = 0; i < dev->n_subdevices; i++) subdev_8255_cleanup(dev, dev->subdevices + i); - } #ifdef PCL724_IRQ - if (dev->irq) { + if (dev->irq) free_irq(dev->irq, dev); - } #endif release_region(dev->iobase, this_board->io_range); diff --git a/drivers/staging/comedi/drivers/pcl725.c b/drivers/staging/comedi/drivers/pcl725.c index 1da4941..60261f4 100644 --- a/drivers/staging/comedi/drivers/pcl725.c +++ b/drivers/staging/comedi/drivers/pcl725.c @@ -66,7 +66,7 @@ static int pcl725_attach(struct comedi_device *dev, struct comedi_devconfig *it) unsigned long iobase; iobase = it->options[0]; - printk("comedi%d: pcl725: 0x%04lx ", dev->minor, iobase); + printk(KERN_INFO "comedi%d: pcl725: 0x%04lx ", dev->minor, iobase); if (!request_region(iobase, PCL725_SIZE, "pcl725")) { printk("I/O port conflict\n"); return -EIO; @@ -96,14 +96,14 @@ static int pcl725_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->insn_bits = pcl725_di_insn; s->range_table = &range_digital; - printk("\n"); + printk(KERN_INFO "\n"); return 0; } static int pcl725_detach(struct comedi_device *dev) { - printk("comedi%d: pcl725: remove\n", dev->minor); + printk(KERN_INFO "comedi%d: pcl725: remove\n", dev->minor); if (dev->iobase) release_region(dev->iobase, PCL725_SIZE); diff --git a/drivers/staging/comedi/drivers/pcl730.c b/drivers/staging/comedi/drivers/pcl730.c index c9859c9..e5e7bed 100644 --- a/drivers/staging/comedi/drivers/pcl730.c +++ b/drivers/staging/comedi/drivers/pcl730.c @@ -99,7 +99,7 @@ static int pcl730_attach(struct comedi_device *dev, struct comedi_devconfig *it) iobase = it->options[0]; iorange = this_board->io_range; - printk("comedi%d: pcl730: board=%s 0x%04lx ", dev->minor, + printk(KERN_INFO "comedi%d: pcl730: board=%s 0x%04lx ", dev->minor, this_board->name, iobase); if (!request_region(iobase, iorange, "pcl730")) { printk("I/O port conflict\n"); @@ -152,14 +152,14 @@ static int pcl730_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->range_table = &range_digital; s->private = (void *)PCL730_DIO_LO; - printk("\n"); + printk(KERN_INFO "\n"); return 0; } static int pcl730_detach(struct comedi_device *dev) { - printk("comedi%d: pcl730: remove\n", dev->minor); + printk(KERN_INFO "comedi%d: pcl730: remove\n", dev->minor); if (dev->iobase) release_region(dev->iobase, this_board->io_range); diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c index 0a5bc3d..d4634c4 100644 --- a/drivers/staging/comedi/drivers/pcl812.c +++ b/drivers/staging/comedi/drivers/pcl812.c @@ -955,6 +955,7 @@ static irqreturn_t interrupt_pcl812_ai_int(int irq, void *d) unsigned int mask, timeout; struct comedi_device *dev = d; struct comedi_subdevice *s = dev->subdevices + 0; + unsigned int next_chan; s->async->events = 0; @@ -993,9 +994,18 @@ static irqreturn_t interrupt_pcl812_ai_int(int irq, void *d) ((inb(dev->iobase + PCL812_AD_HI) << 8) | inb(dev->iobase + PCL812_AD_LO)) & mask); + /* Set up next channel. Added by abbotti 2010-01-20, but untested. */ + next_chan = s->async->cur_chan + 1; + if (next_chan >= devpriv->ai_n_chan) + next_chan = 0; + if (devpriv->ai_chanlist[s->async->cur_chan] != + devpriv->ai_chanlist[next_chan]) + setup_range_channel(dev, s, devpriv->ai_chanlist[next_chan], 0); + outb(0, dev->iobase + PCL812_CLRINT); /* clear INT request */ - if (s->async->cur_chan == 0) { /* one scan done */ + s->async->cur_chan = next_chan; + if (next_chan == 0) { /* one scan done */ devpriv->ai_act_scan++; if (!(devpriv->ai_neverending)) if (devpriv->ai_act_scan >= devpriv->ai_scans) { /* all data sampled */ @@ -1021,7 +1031,9 @@ static void transfer_from_dma_buf(struct comedi_device *dev, for (i = len; i; i--) { comedi_buf_put(s->async, ptr[bufptr++]); /* get one sample */ - if (s->async->cur_chan == 0) { + s->async->cur_chan++; + if (s->async->cur_chan >= devpriv->ai_n_chan) { + s->async->cur_chan = 0; devpriv->ai_act_scan++; if (!devpriv->ai_neverending) if (devpriv->ai_act_scan >= devpriv->ai_scans) { /* all data sampled */ diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c index 852fe24..9820759 100644 --- a/drivers/staging/comedi/drivers/pcl816.c +++ b/drivers/staging/comedi/drivers/pcl816.c @@ -202,6 +202,7 @@ struct pcl816_private { unsigned int ai_act_chanlist[16]; /* MUX setting for actual AI operations */ unsigned int ai_act_chanlist_len; /* how long is actual MUX list */ unsigned int ai_act_chanlist_pos; /* actual position in MUX list */ + unsigned int ai_n_chan; /* how many channels per scan */ unsigned int ai_poll_ptr; /* how many sampes transfer poll */ struct comedi_subdevice *sub_ai; /* ptr to AI subdevice */ #ifdef unused @@ -213,9 +214,12 @@ struct pcl816_private { /* ============================================================================== */ -static int check_and_setup_channel_list(struct comedi_device *dev, - struct comedi_subdevice *s, - unsigned int *chanlist, int chanlen); +static int check_channel_list(struct comedi_device *dev, + struct comedi_subdevice *s, + unsigned int *chanlist, unsigned int chanlen); +static void setup_channel_list(struct comedi_device *dev, + struct comedi_subdevice *s, + unsigned int *chanlist, unsigned int seglen); static int pcl816_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s); static void start_pacer(struct comedi_device *dev, int mode, @@ -320,7 +324,9 @@ static irqreturn_t interrupt_pcl816_ai_mode13_int(int irq, void *d) if (++devpriv->ai_act_chanlist_pos >= devpriv->ai_act_chanlist_len) devpriv->ai_act_chanlist_pos = 0; - if (s->async->cur_chan == 0) { + s->async->cur_chan++; + if (s->async->cur_chan >= devpriv->ai_n_chan) { + s->async->cur_chan = 0; devpriv->ai_act_scan++; } @@ -353,6 +359,11 @@ static void transfer_from_dma_buf(struct comedi_device *dev, if (++devpriv->ai_act_chanlist_pos >= devpriv->ai_act_chanlist_len) { devpriv->ai_act_chanlist_pos = 0; + } + + s->async->cur_chan++; + if (s->async->cur_chan >= devpriv->ai_n_chan) { + s->async->cur_chan = 0; devpriv->ai_act_scan++; } @@ -558,14 +569,6 @@ static int pcl816_ai_cmdtest(struct comedi_device *dev, } } - if (!cmd->chanlist_len) { - cmd->chanlist_len = 1; - err++; - } - if (cmd->chanlist_len > this_board->n_aichan) { - cmd->chanlist_len = this_board->n_aichan; - err++; - } if (cmd->scan_end_arg != cmd->chanlist_len) { cmd->scan_end_arg = cmd->chanlist_len; err++; @@ -603,6 +606,14 @@ static int pcl816_ai_cmdtest(struct comedi_device *dev, return 4; } + /* step 5: complain about special chanlist considerations */ + + if (cmd->chanlist) { + if (!check_channel_list(dev, s, cmd->chanlist, + cmd->chanlist_len)) + return 5; /* incorrect channels list */ + } + return 0; } @@ -610,6 +621,7 @@ static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { unsigned int divisor1 = 0, divisor2 = 0, dma_flags, bytes, dmairq; struct comedi_cmd *cmd = &s->async->cmd; + unsigned int seglen; if (cmd->start_src != TRIG_NOW) return -EINVAL; @@ -642,11 +654,13 @@ static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) start_pacer(dev, -1, 0, 0); /* stop pacer */ - if (!check_and_setup_channel_list(dev, s, cmd->chanlist, - cmd->chanlist_len)) + seglen = check_channel_list(dev, s, cmd->chanlist, cmd->chanlist_len); + if (seglen < 1) return -EINVAL; + setup_channel_list(dev, s, cmd->chanlist, seglen); udelay(1); + devpriv->ai_n_chan = cmd->chanlist_len; devpriv->ai_act_scan = 0; s->async->cur_chan = 0; devpriv->irq_blocked = 1; @@ -871,12 +885,12 @@ start_pacer(struct comedi_device *dev, int mode, unsigned int divisor1, /* ============================================================================== Check if channel list from user is builded correctly - If it's ok, then program scan/gain logic + If it's ok, then return non-zero length of repeated segment of channel list */ static int -check_and_setup_channel_list(struct comedi_device *dev, - struct comedi_subdevice *s, unsigned int *chanlist, - int chanlen) +check_channel_list(struct comedi_device *dev, + struct comedi_subdevice *s, unsigned int *chanlist, + unsigned int chanlen) { unsigned int chansegment[16]; unsigned int i, nowmustbechan, seglen, segpos; @@ -930,6 +944,20 @@ check_and_setup_channel_list(struct comedi_device *dev, seglen = 1; } + return seglen; /* we can serve this with MUX logic */ +} + +/* +============================================================================== + Program scan/gain logic with channel list. +*/ +static void +setup_channel_list(struct comedi_device *dev, + struct comedi_subdevice *s, unsigned int *chanlist, + unsigned int seglen) +{ + unsigned int i; + devpriv->ai_act_chanlist_len = seglen; devpriv->ai_act_chanlist_pos = 0; @@ -942,8 +970,6 @@ check_and_setup_channel_list(struct comedi_device *dev, udelay(1); outb(devpriv->ai_act_chanlist[0] | (devpriv->ai_act_chanlist[seglen - 1] << 4), dev->iobase + PCL816_MUX); /* select channel interval to scan */ - - return 1; /* we can serve this with MUX logic */ } #ifdef unused diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c index d048101..c9d7538 100644 --- a/drivers/staging/comedi/drivers/pcl818.c +++ b/drivers/staging/comedi/drivers/pcl818.c @@ -557,8 +557,14 @@ conv_finish: comedi_event(dev, s); return IRQ_HANDLED; } - if (s->async->cur_chan == 0) { + devpriv->act_chanlist_pos++; + if (devpriv->act_chanlist_pos >= devpriv->act_chanlist_len) { + devpriv->act_chanlist_pos = 0; + } + s->async->cur_chan++; + if (s->async->cur_chan >= devpriv->ai_n_chan) { /* printk("E"); */ + s->async->cur_chan = 0; devpriv->ai_act_scan--; } @@ -627,9 +633,13 @@ static irqreturn_t interrupt_pcl818_ai_mode13_dma(int irq, void *d) devpriv->act_chanlist_pos++; if (devpriv->act_chanlist_pos >= devpriv->act_chanlist_len) { - devpriv->ai_act_scan--; devpriv->act_chanlist_pos = 0; } + s->async->cur_chan++; + if (s->async->cur_chan >= devpriv->ai_n_chan) { + s->async->cur_chan = 0; + devpriv->ai_act_scan--; + } if (!devpriv->neverending_ai) if (devpriv->ai_act_scan == 0) { /* all data sampled */ @@ -717,7 +727,14 @@ static irqreturn_t interrupt_pcl818_ai_mode13_dma_rtc(int irq, void *d) comedi_buf_put(s->async, dmabuf[bufptr++] >> 4); /* get one sample */ bufptr &= (devpriv->dmasamplsize - 1); - if (s->async->cur_chan == 0) { + devpriv->act_chanlist_pos++; + if (devpriv->act_chanlist_pos >= + devpriv->act_chanlist_len) { + devpriv->act_chanlist_pos = 0; + } + s->async->cur_chan++; + if (s->async->cur_chan >= devpriv->ai_n_chan) { + s->async->cur_chan = 0; devpriv->ai_act_scan--; } @@ -796,7 +813,13 @@ static irqreturn_t interrupt_pcl818_ai_mode13_fifo(int irq, void *d) comedi_buf_put(s->async, (lo >> 4) | (inb(dev->iobase + PCL818_FI_DATAHI) << 4)); /* get one sample */ - if (s->async->cur_chan == 0) { + devpriv->act_chanlist_pos++; + if (devpriv->act_chanlist_pos >= devpriv->act_chanlist_len) { + devpriv->act_chanlist_pos = 0; + } + s->async->cur_chan++; + if (s->async->cur_chan >= devpriv->ai_n_chan) { + s->async->cur_chan = 0; devpriv->ai_act_scan--; } @@ -1369,14 +1392,6 @@ static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, } } - if (!cmd->chanlist_len) { - cmd->chanlist_len = 1; - err++; - } - if (cmd->chanlist_len > s->n_chan) { - cmd->chanlist_len = s->n_chan; - err++; - } if (cmd->scan_end_arg != cmd->chanlist_len) { cmd->scan_end_arg = cmd->chanlist_len; err++; diff --git a/drivers/staging/comedi/drivers/pcm3724.c b/drivers/staging/comedi/drivers/pcm3724.c index 5281182..ed61030 100644 --- a/drivers/staging/comedi/drivers/pcm3724.c +++ b/drivers/staging/comedi/drivers/pcm3724.c @@ -121,25 +121,22 @@ static int compute_buffer(int config, int devno, struct comedi_subdevice *s) { /* 1 in io_bits indicates output */ if (s->io_bits & 0x0000ff) { - if (devno == 0) { + if (devno == 0) config |= BUF_A0; - } else { + else config |= BUF_A1; - } } if (s->io_bits & 0x00ff00) { - if (devno == 0) { + if (devno == 0) config |= BUF_B0; - } else { + else config |= BUF_B1; - } } if (s->io_bits & 0xff0000) { - if (devno == 0) { + if (devno == 0) config |= BUF_C0; - } else { + else config |= BUF_C1; - } } return config; } @@ -155,26 +152,27 @@ static void do_3724_config(struct comedi_device *dev, buffer_config = 0; /* 1 in io_bits indicates output, 1 in config indicates input */ - if (!(s->io_bits & 0x0000ff)) { + if (!(s->io_bits & 0x0000ff)) config |= CR_A_IO; - } - if (!(s->io_bits & 0x00ff00)) { + + if (!(s->io_bits & 0x00ff00)) config |= CR_B_IO; - } - if (!(s->io_bits & 0xff0000)) { + + if (!(s->io_bits & 0xff0000)) config |= CR_C_IO; - } buffer_config = compute_buffer(0, 0, dev->subdevices); buffer_config = compute_buffer(buffer_config, 1, (dev->subdevices) + 1); - if (s == dev->subdevices) { + if (s == dev->subdevices) port_8255_cfg = dev->iobase + _8255_CR; - } else { + else port_8255_cfg = dev->iobase + SIZE_8255 + _8255_CR; - } + outb(buffer_config, dev->iobase + 8); /* update buffer register */ - /* printk("pcm3724 buffer_config (%lx) %d, %x\n", dev->iobase + _8255_CR, chanspec, buffer_config); */ + /* printk("pcm3724 buffer_config (%lx) %d, %x\n", + dev->iobase + _8255_CR, chanspec, buffer_config); */ + outb(config, port_8255_cfg); } @@ -189,29 +187,29 @@ static void enable_chan(struct comedi_device *dev, struct comedi_subdevice *s, priv = (struct priv_pcm3724 *)(dev->private); mask = 1 << CR_CHAN(chanspec); - if (s == dev->subdevices) { /* subdev 0 */ + if (s == dev->subdevices) /* subdev 0 */ priv->dio_1 |= mask; - } else { /* subdev 1 */ + else /* subdev 1 */ priv->dio_2 |= mask; - } - if (priv->dio_1 & 0xff0000) { + + if (priv->dio_1 & 0xff0000) gatecfg |= GATE_C0; - } - if (priv->dio_1 & 0xff00) { + + if (priv->dio_1 & 0xff00) gatecfg |= GATE_B0; - } - if (priv->dio_1 & 0xff) { + + if (priv->dio_1 & 0xff) gatecfg |= GATE_A0; - } - if (priv->dio_2 & 0xff0000) { + + if (priv->dio_2 & 0xff0000) gatecfg |= GATE_C1; - } - if (priv->dio_2 & 0xff00) { + + if (priv->dio_2 & 0xff00) gatecfg |= GATE_B1; - } - if (priv->dio_2 & 0xff) { + + if (priv->dio_2 & 0xff) gatecfg |= GATE_A1; - } + /* printk("gate control %x\n", gatecfg); */ outb(gatecfg, dev->iobase + 9); } @@ -225,15 +223,14 @@ static int subdev_3724_insn_config(struct comedi_device *dev, unsigned int bits; mask = 1 << CR_CHAN(insn->chanspec); - if (mask & 0x0000ff) { + if (mask & 0x0000ff) bits = 0x0000ff; - } else if (mask & 0x00ff00) { + else if (mask & 0x00ff00) bits = 0x00ff00; - } else if (mask & 0x0f0000) { + else if (mask & 0x0f0000) bits = 0x0f0000; - } else { + else bits = 0xf00000; - } switch (data[0]) { case INSN_CONFIG_DIO_INPUT: @@ -272,7 +269,7 @@ static int pcm3724_attach(struct comedi_device *dev, ((struct priv_pcm3724 *)(dev->private))->dio_1 = 0; ((struct priv_pcm3724 *)(dev->private))->dio_2 = 0; - printk("comedi%d: pcm3724: board=%s, 0x%03lx ", dev->minor, + printk(KERN_INFO "comedi%d: pcm3724: board=%s, 0x%03lx ", dev->minor, this_board->name, iobase); if (!iobase || !request_region(iobase, iorange, "pcm3724")) { printk("I/O port conflict\n"); @@ -281,7 +278,7 @@ static int pcm3724_attach(struct comedi_device *dev, dev->iobase = iobase; dev->board_name = this_board->name; - printk("\n"); + printk(KERN_INFO "\n"); n_subdevices = this_board->numofports; @@ -302,13 +299,11 @@ static int pcm3724_detach(struct comedi_device *dev) int i; if (dev->subdevices) { - for (i = 0; i < dev->n_subdevices; i++) { + for (i = 0; i < dev->n_subdevices; i++) subdev_8255_cleanup(dev, dev->subdevices + i); - } } - if (dev->iobase) { + if (dev->iobase) release_region(dev->iobase, this_board->io_range); - } return 0; } diff --git a/drivers/staging/comedi/drivers/pcm3730.c b/drivers/staging/comedi/drivers/pcm3730.c index 9e4adbd..22b7aae 100644 --- a/drivers/staging/comedi/drivers/pcm3730.c +++ b/drivers/staging/comedi/drivers/pcm3730.c @@ -73,7 +73,7 @@ static int pcm3730_attach(struct comedi_device *dev, unsigned long iobase; iobase = it->options[0]; - printk("comedi%d: pcm3730: 0x%04lx ", dev->minor, iobase); + printk(KERN_INFO "comedi%d: pcm3730: 0x%04lx ", dev->minor, iobase); if (!request_region(iobase, PCM3730_SIZE, "pcm3730")) { printk("I/O port conflict\n"); return -EIO; @@ -140,14 +140,14 @@ static int pcm3730_attach(struct comedi_device *dev, s->range_table = &range_digital; s->private = (void *)PCM3730_DIC; - printk("\n"); + printk(KERN_INFO "\n"); return 0; } static int pcm3730_detach(struct comedi_device *dev) { - printk("comedi%d: pcm3730: remove\n", dev->minor); + printk(KERN_INFO "comedi%d: pcm3730: remove\n", dev->minor); if (dev->iobase) release_region(dev->iobase, PCM3730_SIZE); diff --git a/drivers/staging/comedi/drivers/pcmad.c b/drivers/staging/comedi/drivers/pcmad.c index acac670..fab8092 100644 --- a/drivers/staging/comedi/drivers/pcmad.c +++ b/drivers/staging/comedi/drivers/pcmad.c @@ -34,11 +34,11 @@ Configuration options: [0] - I/O port base [1] - unused [2] - Analog input reference - 0 = single ended - 1 = differential + 0 = single ended + 1 = differential [3] - Analog input encoding (must match jumpers) - 0 = straight binary - 1 = two's complement + 0 = straight binary + 1 = two's complement */ #include <linux/interrupt.h> @@ -113,9 +113,8 @@ static int pcmad_ai_insn_read(struct comedi_device *dev, data[n] = inb(dev->iobase + PCMAD_LSB); data[n] |= (inb(dev->iobase + PCMAD_MSB) << 8); - if (devpriv->twos_comp) { + if (devpriv->twos_comp) data[n] ^= (1 << (this_board->n_ai_bits - 1)); - } } return n; @@ -135,11 +134,12 @@ static int pcmad_attach(struct comedi_device *dev, struct comedi_devconfig *it) unsigned long iobase; iobase = it->options[0]; - printk("comedi%d: pcmad: 0x%04lx ", dev->minor, iobase); + printk(KERN_INFO "comedi%d: pcmad: 0x%04lx ", dev->minor, iobase); if (!request_region(iobase, PCMAD_SIZE, "pcmad")) { - printk("I/O port conflict\n"); + printk(KERN_CONT "I/O port conflict\n"); return -EIO; } + printk(KERN_CONT "\n"); dev->iobase = iobase; ret = alloc_subdevices(dev, 1); @@ -166,11 +166,11 @@ static int pcmad_attach(struct comedi_device *dev, struct comedi_devconfig *it) static int pcmad_detach(struct comedi_device *dev) { - printk("comedi%d: pcmad: remove\n", dev->minor); + printk(KERN_INFO "comedi%d: pcmad: remove\n", dev->minor); - if (dev->irq) { + if (dev->irq) free_irq(dev->irq, dev); - } + if (dev->iobase) release_region(dev->iobase, PCMAD_SIZE); diff --git a/drivers/staging/comedi/drivers/pcmmio.c b/drivers/staging/comedi/drivers/pcmmio.c index 35ba939..6ca4105 100644 --- a/drivers/staging/comedi/drivers/pcmmio.c +++ b/drivers/staging/comedi/drivers/pcmmio.c @@ -550,7 +550,7 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (irq[0]) { printk("irq: %u ", irq[0]); - if (irq[1] && thisboard->dio_num_asics == 2) + if (thisboard->dio_num_asics == 2 && irq[1]) printk("second ASIC irq: %u ", irq[1]); } else { printk("(IRQ mode disabled) "); diff --git a/drivers/staging/comedi/drivers/poc.c b/drivers/staging/comedi/drivers/poc.c index d23e588..1ebc356 100644 --- a/drivers/staging/comedi/drivers/poc.c +++ b/drivers/staging/comedi/drivers/poc.c @@ -122,22 +122,21 @@ static int poc_attach(struct comedi_device *dev, struct comedi_devconfig *it) unsigned int iosize; iobase = it->options[0]; - printk("comedi%d: poc: using %s iobase 0x%lx\n", dev->minor, + printk(KERN_INFO "comedi%d: poc: using %s iobase 0x%lx\n", dev->minor, this_board->name, iobase); dev->board_name = this_board->name; if (iobase == 0) { - printk("io base address required\n"); + printk(KERN_ERR "io base address required\n"); return -EINVAL; } iosize = this_board->iosize; /* check if io addresses are available */ if (!request_region(iobase, iosize, "dac02")) { - printk - ("I/O port conflict: failed to allocate ports 0x%lx to 0x%lx\n", - iobase, iobase + iosize - 1); + printk(KERN_ERR "I/O port conflict: failed to allocate ports " + "0x%lx to 0x%lx\n", iobase, iobase + iosize - 1); return -EIO; } dev->iobase = iobase; @@ -156,9 +155,8 @@ static int poc_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->insn_write = this_board->winsn; s->insn_read = this_board->rinsn; s->insn_bits = this_board->insnbits; - if (s->type == COMEDI_SUBD_AO || s->type == COMEDI_SUBD_DO) { + if (s->type == COMEDI_SUBD_AO || s->type == COMEDI_SUBD_DO) s->subdev_flags = SDF_WRITABLE; - } return 0; } @@ -169,7 +167,7 @@ static int poc_detach(struct comedi_device *dev) if (dev->iobase) release_region(dev->iobase, this_board->iosize); - printk("comedi%d: dac02: remove\n", dev->minor); + printk(KERN_INFO "comedi%d: dac02: remove\n", dev->minor); return 0; } diff --git a/drivers/staging/comedi/drivers/rti800.c b/drivers/staging/comedi/drivers/rti800.c index 2c9d05b..028ed6f 100644 --- a/drivers/staging/comedi/drivers/rti800.c +++ b/drivers/staging/comedi/drivers/rti800.c @@ -32,22 +32,22 @@ Configuration options: [0] - I/O port base address [1] - IRQ [2] - A/D reference - 0 = differential - 1 = pseudodifferential (common) - 2 = single-ended + 0 = differential + 1 = pseudodifferential (common) + 2 = single-ended [3] - A/D range - 0 = [-10,10] - 1 = [-5,5] - 2 = [0,10] + 0 = [-10,10] + 1 = [-5,5] + 2 = [0,10] [4] - A/D encoding - 0 = two's complement - 1 = straight binary + 0 = two's complement + 1 = straight binary [5] - DAC 0 range - 0 = [-10,10] - 1 = [0,10] + 0 = [-10,10] + 1 = [0,10] [6] - DAC 0 encoding - 0 = two's complement - 1 = straight binary + 0 = two's complement + 1 = straight binary [7] - DAC 1 range (same as DAC 0) [8] - DAC 1 encoding (same as DAC 0) */ @@ -225,7 +225,7 @@ static int rti800_ai_insn_read(struct comedi_device *dev, for (t = RTI800_TIMEOUT; t; t--) { status = inb(dev->iobase + RTI800_CSR); if (status & RTI800_OVERRUN) { - printk("rti800: a/d overrun\n"); + printk(KERN_WARNING "rti800: a/d overrun\n"); outb(0, dev->iobase + RTI800_CLRFLAGS); return -EIO; } @@ -234,15 +234,14 @@ static int rti800_ai_insn_read(struct comedi_device *dev, udelay(1); } if (t == 0) { - printk("rti800: timeout\n"); + printk(KERN_WARNING "rti800: timeout\n"); return -ETIME; } data[i] = inb(dev->iobase + RTI800_ADCLO); data[i] |= (0xf & inb(dev->iobase + RTI800_ADCHI)) << 8; - if (devpriv->adc_coding == adc_2comp) { + if (devpriv->adc_coding == adc_2comp) data[i] ^= 0x800; - } } return i; @@ -271,9 +270,9 @@ static int rti800_ao_insn_write(struct comedi_device *dev, for (i = 0; i < insn->n; i++) { devpriv->ao_readback[chan] = d = data[i]; - if (devpriv->dac0_coding == dac_2comp) { + if (devpriv->dac0_coding == dac_2comp) d ^= 0x800; - } + outb(d & 0xff, dev->iobase + (chan ? RTI800_DAC1LO : RTI800_DAC0LO)); outb(d >> 8, @@ -315,15 +314,15 @@ static int rti800_do_insn_bits(struct comedi_device *dev, options[0] - I/O port options[1] - irq options[2] - a/d mux - 0=differential, 1=pseudodiff, 2=single + 0=differential, 1=pseudodiff, 2=single options[3] - a/d range - 0=bipolar10, 1=bipolar5, 2=unipolar10 + 0=bipolar10, 1=bipolar5, 2=unipolar10 options[4] - a/d coding - 0=2's comp, 1=straight binary + 0=2's comp, 1=straight binary options[5] - dac0 range - 0=bipolar10, 1=unipolar10 + 0=bipolar10, 1=unipolar10 options[6] - dac0 coding - 0=2's comp, 1=straight binary + 0=2's comp, 1=straight binary options[7] - dac1 range options[8] - dac1 coding */ @@ -336,15 +335,15 @@ static int rti800_attach(struct comedi_device *dev, struct comedi_devconfig *it) struct comedi_subdevice *s; iobase = it->options[0]; - printk("comedi%d: rti800: 0x%04lx ", dev->minor, iobase); + printk(KERN_INFO "comedi%d: rti800: 0x%04lx\n", dev->minor, iobase); if (!request_region(iobase, RTI800_SIZE, "rti800")) { - printk("I/O port conflict\n"); + printk(KERN_WARNING "I/O port conflict\n"); return -EIO; } dev->iobase = iobase; #ifdef DEBUG - printk("fingerprint=%x,%x,%x,%x,%x ", + printk(KERN_DEBUG "fingerprint=%x,%x,%x,%x,%x ", inb(dev->iobase + 0), inb(dev->iobase + 1), inb(dev->iobase + 2), @@ -357,15 +356,15 @@ static int rti800_attach(struct comedi_device *dev, struct comedi_devconfig *it) irq = it->options[1]; if (irq) { - printk("( irq = %u )", irq); + printk(KERN_INFO "( irq = %u )\n", irq); ret = request_irq(irq, rti800_interrupt, 0, "rti800", dev); if (ret < 0) { - printk(" Failed to allocate IRQ\n"); + printk(KERN_WARNING " Failed to allocate IRQ\n"); return ret; } dev->irq = irq; } else { - printk("( no irq )"); + printk(KERN_INFO "( no irq )\n"); } dev->board_name = this_board->name; @@ -461,14 +460,12 @@ static int rti800_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->type = COMEDI_SUBD_TIMER; #endif - printk("\n"); - return 0; } static int rti800_detach(struct comedi_device *dev) { - printk("comedi%d: rti800: remove\n", dev->minor); + printk(KERN_INFO "comedi%d: rti800: remove\n", dev->minor); if (dev->iobase) release_region(dev->iobase, RTI800_SIZE); diff --git a/drivers/staging/comedi/drivers/rti802.c b/drivers/staging/comedi/drivers/rti802.c index 2f75c73..2157edc 100644 --- a/drivers/staging/comedi/drivers/rti802.c +++ b/drivers/staging/comedi/drivers/rti802.c @@ -106,9 +106,9 @@ static int rti802_attach(struct comedi_device *dev, struct comedi_devconfig *it) unsigned long iobase; iobase = it->options[0]; - printk("comedi%d: rti802: 0x%04lx ", dev->minor, iobase); + printk(KERN_INFO "comedi%d: rti802: 0x%04lx ", dev->minor, iobase); if (!request_region(iobase, RTI802_SIZE, "rti802")) { - printk("I/O port conflict\n"); + printk(KERN_WARNING "I/O port conflict\n"); return -EIO; } dev->iobase = iobase; @@ -138,14 +138,12 @@ static int rti802_attach(struct comedi_device *dev, struct comedi_devconfig *it) ? &range_unipolar10 : &range_bipolar10; } - printk("\n"); - return 0; } static int rti802_detach(struct comedi_device *dev) { - printk("comedi%d: rti802: remove\n", dev->minor); + printk(KERN_INFO "comedi%d: rti802: remove\n", dev->minor); if (dev->iobase) release_region(dev->iobase, RTI802_SIZE); diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index fdd7ab9..a3cc933 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -140,7 +140,7 @@ struct s626_private { short allocatedBuf; uint8_t ai_cmd_running; /* ai_cmd is running */ uint8_t ai_continous; /* continous aquisition */ - int ai_sample_count; /* number of samples to aquire */ + int ai_sample_count; /* number of samples to acquire */ unsigned int ai_sample_timer; /* time between samples in units of the timer */ int ai_convert_count; /* conversion counter */ diff --git a/drivers/staging/comedi/drivers/serial2002.c b/drivers/staging/comedi/drivers/serial2002.c index db37dcd..dd2b903 100644 --- a/drivers/staging/comedi/drivers/serial2002.c +++ b/drivers/staging/comedi/drivers/serial2002.c @@ -397,7 +397,7 @@ static void serial_2002_open(struct comedi_device *dev) char port[20]; sprintf(port, "/dev/ttyS%d", devpriv->port); - devpriv->tty = filp_open(port, 0, O_RDWR); + devpriv->tty = filp_open(port, O_RDWR, 0); if (IS_ERR(devpriv->tty)) { printk("serial_2002: file open error = %ld\n", PTR_ERR(devpriv->tty)); diff --git a/drivers/staging/comedi/drivers/ssv_dnp.c b/drivers/staging/comedi/drivers/ssv_dnp.c index 4918fbf..17c92a5 100644 --- a/drivers/staging/comedi/drivers/ssv_dnp.c +++ b/drivers/staging/comedi/drivers/ssv_dnp.c @@ -300,11 +300,11 @@ static int dnp_dio_insn_config(struct comedi_device *dev, /* read 'old' direction of the port and set bits (out=1, in=0) */ register_buffer = inb(CSCDR); - if (data[0] == COMEDI_OUTPUT) { + if (data[0] == COMEDI_OUTPUT) register_buffer |= (1 << chan); - } else { + else register_buffer &= ~(1 << chan); - } + outb(register_buffer, CSCDR); return 1; diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index 9a1b559..8942ae4 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c @@ -95,7 +95,6 @@ sampling rate. If you sample two channels you get 4kHz and so on. #include <linux/slab.h> #include <linux/input.h> #include <linux/usb.h> -#include <linux/smp_lock.h> #include <linux/fcntl.h> #include <linux/compiler.h> #include <linux/firmware.h> @@ -289,7 +288,7 @@ struct usbduxsub { /* continous aquisition */ short int ai_continous; short int ao_continous; - /* number of samples to aquire */ + /* number of samples to acquire */ int ai_sample_count; int ao_sample_count; /* time between samples in units of the timer */ @@ -2833,7 +2832,7 @@ static struct comedi_driver driver_usbdux = { }; /* Table with the USB-devices: just now only testing IDs */ -static struct usb_device_id usbduxsub_table[] = { +static const struct usb_device_id usbduxsub_table[] = { {USB_DEVICE(0x13d8, 0x0001)}, {USB_DEVICE(0x13d8, 0x0002)}, {} /* Terminating entry */ diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c index 2e675cc..e89b818 100644 --- a/drivers/staging/comedi/drivers/usbduxfast.c +++ b/drivers/staging/comedi/drivers/usbduxfast.c @@ -44,7 +44,6 @@ #include <linux/slab.h> #include <linux/input.h> #include <linux/usb.h> -#include <linux/smp_lock.h> #include <linux/fcntl.h> #include <linux/compiler.h> #include "comedi_fc.h" @@ -182,7 +181,7 @@ struct usbduxfastsub_s { context */ short int ai_cmd_running; /* asynchronous command is running */ short int ai_continous; /* continous aquisition */ - long int ai_sample_count; /* number of samples to aquire */ + long int ai_sample_count; /* number of samples to acquire */ uint8_t *dux_commands; /* commands */ int ignore; /* counter which ignores the first buffers */ @@ -1769,7 +1768,7 @@ static struct comedi_driver driver_usbduxfast = { /* * Table with the USB-devices: just now only testing IDs */ -static struct usb_device_id usbduxfastsub_table[] = { +static const struct usb_device_id usbduxfastsub_table[] = { /* { USB_DEVICE(0x4b4, 0x8613) }, testing */ {USB_DEVICE(0x13d8, 0x0010)}, /* real ID */ {USB_DEVICE(0x13d8, 0x0011)}, /* real ID */ diff --git a/drivers/staging/comedi/drivers/vmk80xx.c b/drivers/staging/comedi/drivers/vmk80xx.c index c34a0b9..6479c38 100644 --- a/drivers/staging/comedi/drivers/vmk80xx.c +++ b/drivers/staging/comedi/drivers/vmk80xx.c @@ -75,7 +75,7 @@ enum { DEVICE_VMK8061 }; -static struct usb_device_id vmk80xx_id_table[] = { +static const struct usb_device_id vmk80xx_id_table[] = { {USB_DEVICE(0x10cf, 0x5500), .driver_info = DEVICE_VMK8055}, {USB_DEVICE(0x10cf, 0x5501), .driver_info = DEVICE_VMK8055}, {USB_DEVICE(0x10cf, 0x5502), .driver_info = DEVICE_VMK8055}, diff --git a/drivers/staging/crystalhd/Kconfig b/drivers/staging/crystalhd/Kconfig new file mode 100644 index 0000000..56b414b --- /dev/null +++ b/drivers/staging/crystalhd/Kconfig @@ -0,0 +1,6 @@ +config CRYSTALHD + tristate "Broadcom Crystal HD video decoder support" + depends on PCI + default n + help + Support for the Broadcom Crystal HD video decoder chipset diff --git a/drivers/staging/crystalhd/Makefile b/drivers/staging/crystalhd/Makefile new file mode 100644 index 0000000..e2af0ce --- /dev/null +++ b/drivers/staging/crystalhd/Makefile @@ -0,0 +1,6 @@ +obj-$(CONFIG_CRYSTALHD) += crystalhd.o + +crystalhd-objs := crystalhd_cmds.o \ + crystalhd_hw.o \ + crystalhd_lnx.o \ + crystalhd_misc.o diff --git a/drivers/staging/crystalhd/TODO b/drivers/staging/crystalhd/TODO new file mode 100644 index 0000000..69be5d0 --- /dev/null +++ b/drivers/staging/crystalhd/TODO @@ -0,0 +1,16 @@ +- Testing +- Cleanup return codes +- Cleanup typedefs +- Cleanup all WIN* references +- Allocate an Accelerator device class specific Major number, + since we don't have any other open sourced accelerators, it is the only + one in that category for now. + A somewhat similar device is the DXR2/3 + +Please send patches to: +Greg Kroah-Hartman <greg@kroah.com> +Naren Sankar <nsankar@broadcom.com> +Jarod Wilson <jarod@wilsonet.com> +Scott Davilla <davilla@4pi.com> +Manu Abraham <abraham.manu@gmail.com> + diff --git a/drivers/staging/crystalhd/bc_dts_defs.h b/drivers/staging/crystalhd/bc_dts_defs.h new file mode 100644 index 0000000..c34cc07 --- /dev/null +++ b/drivers/staging/crystalhd/bc_dts_defs.h @@ -0,0 +1,498 @@ +/******************************************************************** + * Copyright(c) 2006-2009 Broadcom Corporation. + * + * Name: bc_dts_defs.h + * + * Description: Common definitions for all components. Only types + * is allowed to be included from this file. + * + * AU + * + * HISTORY: + * + ******************************************************************** + * This header is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 2.1 of the License. + * + * This header 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 Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License + * along with this header. If not, see <http://www.gnu.org/licenses/>. + *******************************************************************/ + +#ifndef _BC_DTS_DEFS_H_ +#define _BC_DTS_DEFS_H_ + +#include "bc_dts_types.h" + +/* BIT Mask */ +#define BC_BIT(_x) (1 << (_x)) + +typedef enum _BC_STATUS { + BC_STS_SUCCESS = 0, + BC_STS_INV_ARG = 1, + BC_STS_BUSY = 2, + BC_STS_NOT_IMPL = 3, + BC_STS_PGM_QUIT = 4, + BC_STS_NO_ACCESS = 5, + BC_STS_INSUFF_RES = 6, + BC_STS_IO_ERROR = 7, + BC_STS_NO_DATA = 8, + BC_STS_VER_MISMATCH = 9, + BC_STS_TIMEOUT = 10, + BC_STS_FW_CMD_ERR = 11, + BC_STS_DEC_NOT_OPEN = 12, + BC_STS_ERR_USAGE = 13, + BC_STS_IO_USER_ABORT = 14, + BC_STS_IO_XFR_ERROR = 15, + BC_STS_DEC_NOT_STARTED = 16, + BC_STS_FWHEX_NOT_FOUND = 17, + BC_STS_FMT_CHANGE = 18, + BC_STS_HIF_ACCESS = 19, + BC_STS_CMD_CANCELLED = 20, + BC_STS_FW_AUTH_FAILED = 21, + BC_STS_BOOTLOADER_FAILED = 22, + BC_STS_CERT_VERIFY_ERROR = 23, + BC_STS_DEC_EXIST_OPEN = 24, + BC_STS_PENDING = 25, + BC_STS_CLK_NOCHG = 26, + + /* Must be the last one.*/ + BC_STS_ERROR = -1 +} BC_STATUS; + +/*------------------------------------------------------* + * Registry Key Definitions * + *------------------------------------------------------*/ +#define BC_REG_KEY_MAIN_PATH "Software\\Broadcom\\MediaPC\\70010" +#define BC_REG_KEY_FWPATH "FirmwareFilePath" +#define BC_REG_KEY_SEC_OPT "DbgOptions" + +/* + * Options: + * + * b[5] = Enable RSA KEY in EEPROM Support + * b[6] = Enable Old PIB scheme. (0 = Use PIB with video scheme) + * + * b[12] = Enable send message to NotifyIcon + * + */ + +typedef enum _BC_SW_OPTIONS { + BC_OPT_DOSER_OUT_ENCRYPT = BC_BIT(3), + BC_OPT_LINK_OUT_ENCRYPT = BC_BIT(29), +} BC_SW_OPTIONS; + +typedef struct _BC_REG_CONFIG{ + uint32_t DbgOptions; +} BC_REG_CONFIG; + +#if defined(__KERNEL__) || defined(__LINUX_USER__) +#else +/* Align data structures */ +#define ALIGN(x) __declspec(align(x)) +#endif + +/* mode + * b[0]..b[7] = _DtsDeviceOpenMode + * b[8] = Load new FW + * b[9] = Load file play back FW + * b[10] = Disk format (0 for HD DVD and 1 for BLU ray) + * b[11]-b[15] = default output resolution + * b[16] = Skip TX CPB Buffer Check + * b[17] = Adaptive Output Encrypt/Scramble Scheme + * b[18]-b[31] = reserved for future use + */ + +/* To allow multiple apps to open the device. */ +enum _DtsDeviceOpenMode { + DTS_PLAYBACK_MODE = 0, + DTS_DIAG_MODE, + DTS_MONITOR_MODE, + DTS_HWINIT_MODE +}; + +/* To enable the filter to selectively enable/disable fixes or erratas */ +enum _DtsDeviceFixMode { + DTS_LOAD_NEW_FW = BC_BIT(8), + DTS_LOAD_FILE_PLAY_FW = BC_BIT(9), + DTS_DISK_FMT_BD = BC_BIT(10), + /* b[11]-b[15] : Default output resolution */ + DTS_SKIP_TX_CHK_CPB = BC_BIT(16), + DTS_ADAPTIVE_OUTPUT_PER = BC_BIT(17), + DTS_INTELLIMAP = BC_BIT(18), + /* b[19]-b[21] : select clock frequency */ + DTS_PLAYBACK_DROP_RPT_MODE = BC_BIT(22) +}; + +#define DTS_DFLT_RESOLUTION(x) (x<<11) + +#define DTS_DFLT_CLOCK(x) (x<<19) + +/* F/W File Version corresponding to S/W Releases */ +enum _FW_FILE_VER { + /* S/W release: 02.04.02 F/W release 2.12.2.0 */ + BC_FW_VER_020402 = ((12<<16) | (2<<8) | (0)) +}; + +/*------------------------------------------------------* + * Stream Types for DtsOpenDecoder() * + *------------------------------------------------------*/ +enum _DtsOpenDecStreamTypes { + BC_STREAM_TYPE_ES = 0, + BC_STREAM_TYPE_PES = 1, + BC_STREAM_TYPE_TS = 2, + BC_STREAM_TYPE_ES_TSTAMP = 6, +}; + +/*------------------------------------------------------* + * Video Algorithms for DtsSetVideoParams() * + *------------------------------------------------------*/ +enum _DtsSetVideoParamsAlgo { + BC_VID_ALGO_H264 = 0, + BC_VID_ALGO_MPEG2 = 1, + BC_VID_ALGO_VC1 = 4, + BC_VID_ALGO_VC1MP = 7, +}; + +/*------------------------------------------------------* + * MPEG Extension to the PPB * + *------------------------------------------------------*/ +#define BC_MPEG_VALID_PANSCAN (1) + +typedef struct _BC_PIB_EXT_MPEG { + uint32_t valid; + /* Always valid, defaults to picture size if no + * sequence display extension in the stream. */ + uint32_t display_horizontal_size; + uint32_t display_vertical_size; + + /* MPEG_VALID_PANSCAN + * Offsets are a copy values from the MPEG stream. */ + uint32_t offset_count; + int32_t horizontal_offset[3]; + int32_t vertical_offset[3]; + +} BC_PIB_EXT_MPEG; + +/*------------------------------------------------------* + * H.264 Extension to the PPB * + *------------------------------------------------------*/ +/* Bit definitions for 'other.h264.valid' field */ +#define H264_VALID_PANSCAN (1) +#define H264_VALID_SPS_CROP (2) +#define H264_VALID_VUI (4) + +typedef struct _BC_PIB_EXT_H264 { + /* 'valid' specifies which fields (or sets of + * fields) below are valid. If the corresponding + * bit in 'valid' is NOT set then that field(s) + * is (are) not initialized. */ + uint32_t valid; + + /* H264_VALID_PANSCAN */ + uint32_t pan_scan_count; + int32_t pan_scan_left[3]; + int32_t pan_scan_right[3]; + int32_t pan_scan_top[3]; + int32_t pan_scan_bottom[3]; + + /* H264_VALID_SPS_CROP */ + int32_t sps_crop_left; + int32_t sps_crop_right; + int32_t sps_crop_top; + int32_t sps_crop_bottom; + + /* H264_VALID_VUI */ + uint32_t chroma_top; + uint32_t chroma_bottom; + +} BC_PIB_EXT_H264; + +/*------------------------------------------------------* + * VC1 Extension to the PPB * + *------------------------------------------------------*/ +#define VC1_VALID_PANSCAN (1) + +typedef struct _BC_PIB_EXT_VC1 { + uint32_t valid; + + /* Always valid, defaults to picture size if no + * sequence display extension in the stream. */ + uint32_t display_horizontal_size; + uint32_t display_vertical_size; + + /* VC1 pan scan windows */ + uint32_t num_panscan_windows; + int32_t ps_horiz_offset[4]; + int32_t ps_vert_offset[4]; + int32_t ps_width[4]; + int32_t ps_height[4]; + +} BC_PIB_EXT_VC1; + + +/*------------------------------------------------------* + * Picture Information Block * + *------------------------------------------------------*/ +#if defined(_WIN32) || defined(_WIN64) || defined(__LINUX_USER__) +/* Values for 'pulldown' field. '0' means no pulldown information + * was present for this picture. */ +enum { + vdecNoPulldownInfo = 0, + vdecTop = 1, + vdecBottom = 2, + vdecTopBottom = 3, + vdecBottomTop = 4, + vdecTopBottomTop = 5, + vdecBottomTopBottom = 6, + vdecFrame_X2 = 7, + vdecFrame_X3 = 8, + vdecFrame_X1 = 9, + vdecFrame_X4 = 10, +}; + +/* Values for the 'frame_rate' field. */ +enum { + vdecFrameRateUnknown = 0, + vdecFrameRate23_97, + vdecFrameRate24, + vdecFrameRate25, + vdecFrameRate29_97, + vdecFrameRate30, + vdecFrameRate50, + vdecFrameRate59_94, + vdecFrameRate60, +}; + +/* Values for the 'aspect_ratio' field. */ +enum { + vdecAspectRatioUnknown = 0, + vdecAspectRatioSquare, + vdecAspectRatio12_11, + vdecAspectRatio10_11, + vdecAspectRatio16_11, + vdecAspectRatio40_33, + vdecAspectRatio24_11, + vdecAspectRatio20_11, + vdecAspectRatio32_11, + vdecAspectRatio80_33, + vdecAspectRatio18_11, + vdecAspectRatio15_11, + vdecAspectRatio64_33, + vdecAspectRatio160_99, + vdecAspectRatio4_3, + vdecAspectRatio16_9, + vdecAspectRatio221_1, + vdecAspectRatioOther = 255, +}; + +/* Values for the 'colour_primaries' field. */ +enum { + vdecColourPrimariesUnknown = 0, + vdecColourPrimariesBT709, + vdecColourPrimariesUnspecified, + vdecColourPrimariesReserved, + vdecColourPrimariesBT470_2M = 4, + vdecColourPrimariesBT470_2BG, + vdecColourPrimariesSMPTE170M, + vdecColourPrimariesSMPTE240M, + vdecColourPrimariesGenericFilm, +}; + +enum { + vdecRESOLUTION_CUSTOM = 0x00000000, /* custom */ + vdecRESOLUTION_480i = 0x00000001, /* 480i */ + vdecRESOLUTION_1080i = 0x00000002, /* 1080i (1920x1080, 60i) */ + vdecRESOLUTION_NTSC = 0x00000003, /* NTSC (720x483, 60i) */ + vdecRESOLUTION_480p = 0x00000004, /* 480p (720x480, 60p) */ + vdecRESOLUTION_720p = 0x00000005, /* 720p (1280x720, 60p) */ + vdecRESOLUTION_PAL1 = 0x00000006, /* PAL_1 (720x576, 50i) */ + vdecRESOLUTION_1080i25 = 0x00000007, /* 1080i25 (1920x1080, 50i) */ + vdecRESOLUTION_720p50 = 0x00000008, /* 720p50 (1280x720, 50p) */ + vdecRESOLUTION_576p = 0x00000009, /* 576p (720x576, 50p) */ + vdecRESOLUTION_1080i29_97 = 0x0000000A, /* 1080i (1920x1080, 59.94i) */ + vdecRESOLUTION_720p59_94 = 0x0000000B, /* 720p (1280x720, 59.94p) */ + vdecRESOLUTION_SD_DVD = 0x0000000C, /* SD DVD (720x483, 60i) */ + vdecRESOLUTION_480p656 = 0x0000000D, /* 480p (720x480, 60p), output bus width 8 bit, clock 74.25MHz */ + vdecRESOLUTION_1080p23_976 = 0x0000000E, /* 1080p23_976 (1920x1080, 23.976p) */ + vdecRESOLUTION_720p23_976 = 0x0000000F, /* 720p23_976 (1280x720p, 23.976p) */ + vdecRESOLUTION_240p29_97 = 0x00000010, /* 240p (1440x240, 29.97p ) */ + vdecRESOLUTION_240p30 = 0x00000011, /* 240p (1440x240, 30p) */ + vdecRESOLUTION_288p25 = 0x00000012, /* 288p (1440x288p, 25p) */ + vdecRESOLUTION_1080p29_97 = 0x00000013, /* 1080p29_97 (1920x1080, 29.97p) */ + vdecRESOLUTION_1080p30 = 0x00000014, /* 1080p30 (1920x1080, 30p) */ + vdecRESOLUTION_1080p24 = 0x00000015, /* 1080p24 (1920x1080, 24p) */ + vdecRESOLUTION_1080p25 = 0x00000016, /* 1080p25 (1920x1080, 25p) */ + vdecRESOLUTION_720p24 = 0x00000017, /* 720p24 (1280x720, 25p) */ + vdecRESOLUTION_720p29_97 = 0x00000018, /* 720p29.97 (1280x720, 29.97p) */ + vdecRESOLUTION_480p23_976 = 0x00000019, /* 480p23.976 (720*480, 23.976) */ + vdecRESOLUTION_480p29_97 = 0x0000001A, /* 480p29.976 (720*480, 29.97p) */ + vdecRESOLUTION_576p25 = 0x0000001B, /* 576p25 (720*576, 25p) */ + /* For Zero Frame Rate */ + vdecRESOLUTION_480p0 = 0x0000001C, /* 480p (720x480, 0p) */ + vdecRESOLUTION_480i0 = 0x0000001D, /* 480i (720x480, 0i) */ + vdecRESOLUTION_576p0 = 0x0000001E, /* 576p (720x576, 0p) */ + vdecRESOLUTION_720p0 = 0x0000001F, /* 720p (1280x720, 0p) */ + vdecRESOLUTION_1080p0 = 0x00000020, /* 1080p (1920x1080, 0p) */ + vdecRESOLUTION_1080i0 = 0x00000021, /* 1080i (1920x1080, 0i) */ +}; + +/* Bit definitions for 'flags' field */ +#define VDEC_FLAG_EOS (0x0004) + +#define VDEC_FLAG_FRAME (0x0000) +#define VDEC_FLAG_FIELDPAIR (0x0008) +#define VDEC_FLAG_TOPFIELD (0x0010) +#define VDEC_FLAG_BOTTOMFIELD (0x0018) + +#define VDEC_FLAG_PROGRESSIVE_SRC (0x0000) +#define VDEC_FLAG_INTERLACED_SRC (0x0020) +#define VDEC_FLAG_UNKNOWN_SRC (0x0040) + +#define VDEC_FLAG_BOTTOM_FIRST (0x0080) +#define VDEC_FLAG_LAST_PICTURE (0x0100) + +#define VDEC_FLAG_PICTURE_META_DATA_PRESENT (0x40000) + +#endif /* _WIN32 || _WIN64 */ + +enum _BC_OUTPUT_FORMAT { + MODE420 = 0x0, + MODE422_YUY2 = 0x1, + MODE422_UYVY = 0x2, +}; + +typedef struct _BC_PIC_INFO_BLOCK { + /* Common fields. */ + uint64_t timeStamp; /* Timestamp */ + uint32_t picture_number; /* Ordinal display number */ + uint32_t width; /* pixels */ + uint32_t height; /* pixels */ + uint32_t chroma_format; /* 0x420, 0x422 or 0x444 */ + uint32_t pulldown; + uint32_t flags; + uint32_t frame_rate; + uint32_t aspect_ratio; + uint32_t colour_primaries; + uint32_t picture_meta_payload; + uint32_t sess_num; + uint32_t ycom; + uint32_t custom_aspect_ratio_width_height; + uint32_t n_drop; /* number of non-reference frames remaining to be dropped */ + + /* Protocol-specific extensions. */ + union { + BC_PIB_EXT_H264 h264; + BC_PIB_EXT_MPEG mpeg; + BC_PIB_EXT_VC1 vc1; + } other; + +} BC_PIC_INFO_BLOCK, *PBC_PIC_INFO_BLOCK; + +/*------------------------------------------------------* + * ProcOut Info * + *------------------------------------------------------*/ +/* Optional flags for ProcOut Interface.*/ +enum _POUT_OPTIONAL_IN_FLAGS_{ + /* Flags from App to Device */ + BC_POUT_FLAGS_YV12 = 0x01, /* Copy Data in YV12 format */ + BC_POUT_FLAGS_STRIDE = 0x02, /* Stride size is valid. */ + BC_POUT_FLAGS_SIZE = 0x04, /* Take size information from Application */ + BC_POUT_FLAGS_INTERLACED = 0x08, /* copy only half the bytes */ + BC_POUT_FLAGS_INTERLEAVED = 0x10, /* interleaved frame */ + + /* Flags from Device to APP */ + BC_POUT_FLAGS_FMT_CHANGE = 0x10000, /* Data is not VALID when this flag is set */ + BC_POUT_FLAGS_PIB_VALID = 0x20000, /* PIB Information valid */ + BC_POUT_FLAGS_ENCRYPTED = 0x40000, /* Data is encrypted. */ + BC_POUT_FLAGS_FLD_BOT = 0x80000, /* Bottom Field data */ +}; + +#if defined(__KERNEL__) || defined(__LINUX_USER__) +typedef BC_STATUS(*dts_pout_callback)(void *shnd, uint32_t width, uint32_t height, uint32_t stride, void *pOut); +#else +typedef BC_STATUS(*dts_pout_callback)(void *shnd, uint32_t width, uint32_t height, uint32_t stride, struct _BC_DTS_PROC_OUT *pOut); +#endif + +/* Line 21 Closed Caption */ +/* User Data */ +#define MAX_UD_SIZE 1792 /* 1920 - 128 */ + +typedef struct _BC_DTS_PROC_OUT { + uint8_t *Ybuff; /* Caller Supplied buffer for Y data */ + uint32_t YbuffSz; /* Caller Supplied Y buffer size */ + uint32_t YBuffDoneSz; /* Transferred Y datasize */ + + uint8_t *UVbuff; /* Caller Supplied buffer for UV data */ + uint32_t UVbuffSz; /* Caller Supplied UV buffer size */ + uint32_t UVBuffDoneSz; /* Transferred UV data size */ + + uint32_t StrideSz; /* Caller supplied Stride Size */ + uint32_t PoutFlags; /* Call IN Flags */ + + uint32_t discCnt; /* Picture discontinuity count */ + + BC_PIC_INFO_BLOCK PicInfo; /* Picture Information Block Data */ + + /* Line 21 Closed Caption */ + /* User Data */ + uint32_t UserDataSz; + uint8_t UserData[MAX_UD_SIZE]; + + void *hnd; + dts_pout_callback AppCallBack; + uint8_t DropFrames; + uint8_t b422Mode; /* Picture output Mode */ + uint8_t bPibEnc; /* PIB encrypted */ + uint8_t bRevertScramble; + +} BC_DTS_PROC_OUT; + +typedef struct _BC_DTS_STATUS { + uint8_t ReadyListCount; /* Number of frames in ready list (reported by driver) */ + uint8_t FreeListCount; /* Number of frame buffers free. (reported by driver) */ + uint8_t PowerStateChange; /* Number of active state power transitions (reported by driver) */ + uint8_t reserved_[1]; + + uint32_t FramesDropped; /* Number of frames dropped. (reported by DIL) */ + uint32_t FramesCaptured; /* Number of frames captured. (reported by DIL) */ + uint32_t FramesRepeated; /* Number of frames repeated. (reported by DIL) */ + + uint32_t InputCount; /* Times compressed video has been sent to the HW. + * i.e. Successful DtsProcInput() calls (reported by DIL) */ + uint64_t InputTotalSize; /* Amount of compressed video that has been sent to the HW. + * (reported by DIL) */ + uint32_t InputBusyCount; /* Times compressed video has attempted to be sent to the HW + * but the input FIFO was full. (reported by DIL) */ + + uint32_t PIBMissCount; /* Amount of times a PIB is invalid. (reported by DIL) */ + + uint32_t cpbEmptySize; /* supported only for H.264, specifically changed for + * Adobe. Report size of CPB buffer available. + * Reported by DIL */ + uint64_t NextTimeStamp; /* TimeStamp of the next picture that will be returned + * by a call to ProcOutput. Added for Adobe. Reported + * back from the driver */ + uint8_t reserved__[16]; + +} BC_DTS_STATUS; + +#define BC_SWAP32(_v) \ + ((((_v) & 0xFF000000)>>24)| \ + (((_v) & 0x00FF0000)>>8)| \ + (((_v) & 0x0000FF00)<<8)| \ + (((_v) & 0x000000FF)<<24)) + +#define WM_AGENT_TRAYICON_DECODER_OPEN 10001 +#define WM_AGENT_TRAYICON_DECODER_CLOSE 10002 +#define WM_AGENT_TRAYICON_DECODER_START 10003 +#define WM_AGENT_TRAYICON_DECODER_STOP 10004 +#define WM_AGENT_TRAYICON_DECODER_RUN 10005 +#define WM_AGENT_TRAYICON_DECODER_PAUSE 10006 + + +#endif /* _BC_DTS_DEFS_H_ */ diff --git a/drivers/staging/crystalhd/bc_dts_glob_lnx.h b/drivers/staging/crystalhd/bc_dts_glob_lnx.h new file mode 100644 index 0000000..b3125e3 --- /dev/null +++ b/drivers/staging/crystalhd/bc_dts_glob_lnx.h @@ -0,0 +1,299 @@ +/******************************************************************** + * Copyright(c) 2006-2009 Broadcom Corporation. + * + * Name: bc_dts_glob_lnx.h + * + * Description: Wrapper to Windows dts_glob.h for Link-Linux usage. + * The idea is to define additional Linux related defs + * in this file to avoid changes to existing Windows + * glob file. + * + * AU + * + * HISTORY: + * + ******************************************************************** + * This header is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 2.1 of the License. + * + * This header 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 Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License + * along with this header. If not, see <http://www.gnu.org/licenses/>. + *******************************************************************/ + +#ifndef _BC_DTS_GLOB_LNX_H_ +#define _BC_DTS_GLOB_LNX_H_ + +#ifdef __LINUX_USER__ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <ctype.h> +#include <string.h> +#include <errno.h> +#include <netdb.h> +#include <sys/time.h> +#include <time.h> +#include <arpa/inet.h> +#include <asm/param.h> +#include <linux/ioctl.h> +#include <sys/select.h> + +#define DRVIFLIB_INT_API + +#endif + +#include "bc_dts_defs.h" +#include "bcm_70012_regs.h" /* Link Register defs */ + +#define CRYSTALHD_API_NAME "crystalhd" +#define CRYSTALHD_API_DEV_NAME "/dev/crystalhd" + +/* + * These are SW stack tunable parameters shared + * between the driver and the application. + */ +enum _BC_DTS_GLOBALS { + BC_MAX_FW_CMD_BUFF_SZ = 0x40, /* FW passthrough cmd/rsp buffer size */ + PCI_CFG_SIZE = 256, /* PCI config size buffer */ + BC_IOCTL_DATA_POOL_SIZE = 8, /* BC_IOCTL_DATA Pool size */ + BC_LINK_MAX_OPENS = 3, /* Maximum simultaneous opens*/ + BC_LINK_MAX_SGLS = 1024, /* Maximum SG elements 4M/4K */ + BC_TX_LIST_CNT = 2, /* Max Tx DMA Rings */ + BC_RX_LIST_CNT = 8, /* Max Rx DMA Rings*/ + BC_PROC_OUTPUT_TIMEOUT = 3000, /* Milliseconds */ + BC_INFIFO_THRESHOLD = 0x10000, +}; + +typedef struct _BC_CMD_REG_ACC { + uint32_t Offset; + uint32_t Value; +} BC_CMD_REG_ACC; + +typedef struct _BC_CMD_DEV_MEM { + uint32_t StartOff; + uint32_t NumDwords; + uint32_t Rsrd; +} BC_CMD_DEV_MEM; + +/* FW Passthrough command structure */ +enum _bc_fw_cmd_flags { + BC_FW_CMD_FLAGS_NONE = 0, + BC_FW_CMD_PIB_QS = 0x01, +}; + +typedef struct _BC_FW_CMD { + uint32_t cmd[BC_MAX_FW_CMD_BUFF_SZ]; + uint32_t rsp[BC_MAX_FW_CMD_BUFF_SZ]; + uint32_t flags; + uint32_t add_data; +} BC_FW_CMD, *PBC_FW_CMD; + +typedef struct _BC_HW_TYPE { + uint16_t PciDevId; + uint16_t PciVenId; + uint8_t HwRev; + uint8_t Align[3]; +} BC_HW_TYPE; + +typedef struct _BC_PCI_CFG { + uint32_t Size; + uint32_t Offset; + uint8_t pci_cfg_space[PCI_CFG_SIZE]; +} BC_PCI_CFG; + +typedef struct _BC_VERSION_INFO_ { + uint8_t DriverMajor; + uint8_t DriverMinor; + uint16_t DriverRevision; +} BC_VERSION_INFO; + +typedef struct _BC_START_RX_CAP_ { + uint32_t Rsrd; + uint32_t StartDeliveryThsh; + uint32_t PauseThsh; + uint32_t ResumeThsh; +} BC_START_RX_CAP; + +typedef struct _BC_FLUSH_RX_CAP_ { + uint32_t Rsrd; + uint32_t bDiscardOnly; +} BC_FLUSH_RX_CAP; + +typedef struct _BC_DTS_STATS { + uint8_t drvRLL; + uint8_t drvFLL; + uint8_t eosDetected; + uint8_t pwr_state_change; + + /* Stats from App */ + uint32_t opFrameDropped; + uint32_t opFrameCaptured; + uint32_t ipSampleCnt; + uint64_t ipTotalSize; + uint32_t reptdFrames; + uint32_t pauseCount; + uint32_t pibMisses; + uint32_t discCounter; + + /* Stats from Driver */ + uint32_t TxFifoBsyCnt; + uint32_t intCount; + uint32_t DrvIgnIntrCnt; + uint32_t DrvTotalFrmDropped; + uint32_t DrvTotalHWErrs; + uint32_t DrvTotalPIBFlushCnt; + uint32_t DrvTotalFrmCaptured; + uint32_t DrvPIBMisses; + uint32_t DrvPauseTime; + uint32_t DrvRepeatedFrms; + uint32_t res1[13]; + +} BC_DTS_STATS; + +typedef struct _BC_PROC_INPUT_ { + uint8_t *pDmaBuff; + uint32_t BuffSz; + uint8_t Mapped; + uint8_t Encrypted; + uint8_t Rsrd[2]; + uint32_t DramOffset; /* For debug use only */ +} BC_PROC_INPUT, *PBC_PROC_INPUT; + +typedef struct _BC_DEC_YUV_BUFFS { + uint32_t b422Mode; + uint8_t *YuvBuff; + uint32_t YuvBuffSz; + uint32_t UVbuffOffset; + uint32_t YBuffDoneSz; + uint32_t UVBuffDoneSz; + uint32_t RefCnt; +} BC_DEC_YUV_BUFFS; + +enum _DECOUT_COMPLETION_FLAGS{ + COMP_FLAG_NO_INFO = 0x00, + COMP_FLAG_FMT_CHANGE = 0x01, + COMP_FLAG_PIB_VALID = 0x02, + COMP_FLAG_DATA_VALID = 0x04, + COMP_FLAG_DATA_ENC = 0x08, + COMP_FLAG_DATA_BOT = 0x10, +}; + +typedef struct _BC_DEC_OUT_BUFF{ + BC_DEC_YUV_BUFFS OutPutBuffs; + BC_PIC_INFO_BLOCK PibInfo; + uint32_t Flags; + uint32_t BadFrCnt; +} BC_DEC_OUT_BUFF; + +typedef struct _BC_NOTIFY_MODE { + uint32_t Mode; + uint32_t Rsvr[3]; +} BC_NOTIFY_MODE; + +typedef struct _BC_CLOCK { + uint32_t clk; + uint32_t Rsvr[3]; +} BC_CLOCK; + +typedef struct _BC_IOCTL_DATA { + BC_STATUS RetSts; + uint32_t IoctlDataSz; + uint32_t Timeout; + union { + BC_CMD_REG_ACC regAcc; + BC_CMD_DEV_MEM devMem; + BC_FW_CMD fwCmd; + BC_HW_TYPE hwType; + BC_PCI_CFG pciCfg; + BC_VERSION_INFO VerInfo; + BC_PROC_INPUT ProcInput; + BC_DEC_YUV_BUFFS RxBuffs; + BC_DEC_OUT_BUFF DecOutData; + BC_START_RX_CAP RxCap; + BC_FLUSH_RX_CAP FlushRxCap; + BC_DTS_STATS drvStat; + BC_NOTIFY_MODE NotifyMode; + BC_CLOCK clockValue; + } u; + struct _BC_IOCTL_DATA *next; +} BC_IOCTL_DATA; + +typedef enum _BC_DRV_CMD{ + DRV_CMD_VERSION = 0, /* Get SW version */ + DRV_CMD_GET_HWTYPE, /* Get HW version and type Dozer/Tank */ + DRV_CMD_REG_RD, /* Read Device Register */ + DRV_CMD_REG_WR, /* Write Device Register */ + DRV_CMD_FPGA_RD, /* Read FPGA Register */ + DRV_CMD_FPGA_WR, /* Wrtie FPGA Reister */ + DRV_CMD_MEM_RD, /* Read Device Memory */ + DRV_CMD_MEM_WR, /* Write Device Memory */ + DRV_CMD_RD_PCI_CFG, /* Read PCI Config Space */ + DRV_CMD_WR_PCI_CFG, /* Write the PCI Configuration Space*/ + DRV_CMD_FW_DOWNLOAD, /* Download Firmware */ + DRV_ISSUE_FW_CMD, /* Issue FW Cmd (pass through mode) */ + DRV_CMD_PROC_INPUT, /* Process Input Sample */ + DRV_CMD_ADD_RXBUFFS, /* Add Rx side buffers to driver pool */ + DRV_CMD_FETCH_RXBUFF, /* Get Rx DMAed buffer */ + DRV_CMD_START_RX_CAP, /* Start Rx Buffer Capture */ + DRV_CMD_FLUSH_RX_CAP, /* Stop the capture for now...we will enhance this later*/ + DRV_CMD_GET_DRV_STAT, /* Get Driver Internal Statistics */ + DRV_CMD_RST_DRV_STAT, /* Reset Driver Internal Statistics */ + DRV_CMD_NOTIFY_MODE, /* Notify the Mode to driver in which the application is Operating*/ + DRV_CMD_CHANGE_CLOCK, /* Change the core clock to either save power or improve performance */ + + /* MUST be the last one.. */ + DRV_CMD_END, /* End of the List.. */ +} BC_DRV_CMD; + +#define BC_IOC_BASE 'b' +#define BC_IOC_VOID _IOC_NONE +#define BC_IOC_IOWR(nr, type) _IOWR(BC_IOC_BASE, nr, type) +#define BC_IOCTL_MB BC_IOCTL_DATA + +#define BCM_IOC_GET_VERSION BC_IOC_IOWR(DRV_CMD_VERSION, BC_IOCTL_MB) +#define BCM_IOC_GET_HWTYPE BC_IOC_IOWR(DRV_CMD_GET_HWTYPE, BC_IOCTL_MB) +#define BCM_IOC_REG_RD BC_IOC_IOWR(DRV_CMD_REG_RD, BC_IOCTL_MB) +#define BCM_IOC_REG_WR BC_IOC_IOWR(DRV_CMD_REG_WR, BC_IOCTL_MB) +#define BCM_IOC_MEM_RD BC_IOC_IOWR(DRV_CMD_MEM_RD, BC_IOCTL_MB) +#define BCM_IOC_MEM_WR BC_IOC_IOWR(DRV_CMD_MEM_WR, BC_IOCTL_MB) +#define BCM_IOC_FPGA_RD BC_IOC_IOWR(DRV_CMD_FPGA_RD, BC_IOCTL_MB) +#define BCM_IOC_FPGA_WR BC_IOC_IOWR(DRV_CMD_FPGA_WR, BC_IOCTL_MB) +#define BCM_IOC_RD_PCI_CFG BC_IOC_IOWR(DRV_CMD_RD_PCI_CFG, BC_IOCTL_MB) +#define BCM_IOC_WR_PCI_CFG BC_IOC_IOWR(DRV_CMD_WR_PCI_CFG, BC_IOCTL_MB) +#define BCM_IOC_PROC_INPUT BC_IOC_IOWR(DRV_CMD_PROC_INPUT, BC_IOCTL_MB) +#define BCM_IOC_ADD_RXBUFFS BC_IOC_IOWR(DRV_CMD_ADD_RXBUFFS, BC_IOCTL_MB) +#define BCM_IOC_FETCH_RXBUFF BC_IOC_IOWR(DRV_CMD_FETCH_RXBUFF, BC_IOCTL_MB) +#define BCM_IOC_FW_CMD BC_IOC_IOWR(DRV_ISSUE_FW_CMD, BC_IOCTL_MB) +#define BCM_IOC_START_RX_CAP BC_IOC_IOWR(DRV_CMD_START_RX_CAP, BC_IOCTL_MB) +#define BCM_IOC_FLUSH_RX_CAP BC_IOC_IOWR(DRV_CMD_FLUSH_RX_CAP, BC_IOCTL_MB) +#define BCM_IOC_GET_DRV_STAT BC_IOC_IOWR(DRV_CMD_GET_DRV_STAT, BC_IOCTL_MB) +#define BCM_IOC_RST_DRV_STAT BC_IOC_IOWR(DRV_CMD_RST_DRV_STAT, BC_IOCTL_MB) +#define BCM_IOC_NOTIFY_MODE BC_IOC_IOWR(DRV_CMD_NOTIFY_MODE, BC_IOCTL_MB) +#define BCM_IOC_FW_DOWNLOAD BC_IOC_IOWR(DRV_CMD_FW_DOWNLOAD, BC_IOCTL_MB) +#define BCM_IOC_CHG_CLK BC_IOC_IOWR(DRV_CMD_CHANGE_CLOCK, BC_IOCTL_MB) +#define BCM_IOC_END BC_IOC_VOID + +/* Wrapper for main IOCTL data */ +typedef struct _crystalhd_ioctl_data { + BC_IOCTL_DATA udata; /* IOCTL from App..*/ + uint32_t u_id; /* Driver specific user ID */ + uint32_t cmd; /* Cmd ID for driver's use. */ + void *add_cdata; /* Additional command specific data..*/ + uint32_t add_cdata_sz; /* Additional command specific data size */ + struct _crystalhd_ioctl_data *next; /* List/Fifo management */ +} crystalhd_ioctl_data; + + +enum _crystalhd_kmod_ver{ + crystalhd_kmod_major = 0, + crystalhd_kmod_minor = 9, + crystalhd_kmod_rev = 27, +}; + +#endif diff --git a/drivers/staging/crystalhd/bc_dts_types.h b/drivers/staging/crystalhd/bc_dts_types.h new file mode 100644 index 0000000..ac0c817 --- /dev/null +++ b/drivers/staging/crystalhd/bc_dts_types.h @@ -0,0 +1,121 @@ +/******************************************************************** + * Copyright(c) 2006-2009 Broadcom Corporation. + * + * Name: bc_dts_types.h + * + * Description: Data types + * + * AU + * + * HISTORY: + * + ******************************************************************** + * This header is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 2.1 of the License. + * + * This header 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 Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License + * along with this header. If not, see <http://www.gnu.org/licenses/>. + *******************************************************************/ + +#ifndef _BC_DTS_TYPES_H_ +#define _BC_DTS_TYPES_H_ + +#ifdef __LINUX_USER__ // Don't include these for KERNEL.. +#include <stdint.h> +#endif + +#if defined(_WIN64) || defined(_WIN32) +typedef uint32_t U32; +typedef int32_t S32; +typedef uint16_t U16; +typedef int16_t S16; +typedef unsigned char U8; +typedef char S8; +#endif + +#ifndef PVOID +typedef void *PVOID; +#endif + +#ifndef BOOL +typedef int BOOL; +#endif + +#ifdef WIN32 + typedef unsigned __int64 U64; +#elif defined(_WIN64) + typedef uint64_t U64; +#endif + +#ifdef _WIN64 +#if !(defined(POINTER_32)) +#define POINTER_32 __ptr32 +#endif +#else /* _WIN32 */ +#define POINTER_32 +#endif + +#if defined(__KERNEL__) || defined(__LINUX_USER__) + +#ifdef __LINUX_USER__ /* Don't include these for KERNEL */ +typedef uint32_t ULONG; +typedef int32_t LONG; +typedef void *HANDLE; +#ifndef VOID +typedef void VOID; +#endif +typedef void *LPVOID; +typedef uint32_t DWORD; +typedef uint32_t UINT32; +typedef uint32_t *LPDWORD; +typedef unsigned char *PUCHAR; + +#ifndef TRUE + #define TRUE 1 +#endif + +#ifndef FALSE + #define FALSE 0 +#endif + +#define TEXT + +#else + +/* For Kernel usage.. */ +typedef bool bc_bool_t; +#endif + +#else + +#ifndef uint64_t +typedef struct _uint64_t { + uint32_t low_dw; + uint32_t hi_dw; +} uint64_t; +#endif + +#ifndef int32_t +typedef signed long int32_t; +#endif + +#ifndef uint32_t +typedef unsigned long uint32_t; +#endif + +#ifndef uint16_t +typedef unsigned short uint16_t; +#endif + +#ifndef uint8_t +typedef unsigned char uint8_t; +#endif +#endif + +#endif + diff --git a/drivers/staging/crystalhd/bcm_70012_regs.h b/drivers/staging/crystalhd/bcm_70012_regs.h new file mode 100644 index 0000000..6922f54 --- /dev/null +++ b/drivers/staging/crystalhd/bcm_70012_regs.h @@ -0,0 +1,757 @@ +/*************************************************************************** + * Copyright (c) 1999-2009, Broadcom Corporation. + * + * Name: bcm_70012_regs.h + * + * Description: BCM70012 registers + * + ******************************************************************** + * This header is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 2.1 of the License. + * + * This header 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 Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License + * along with this header. If not, see <http://www.gnu.org/licenses/>. + ***************************************************************************/ + +#ifndef MACFILE_H__ +#define MACFILE_H__ + +/** + * m = memory, c = core, r = register, f = field, d = data. + */ +#if !defined(GET_FIELD) && !defined(SET_FIELD) +#define BRCM_ALIGN(c,r,f) c##_##r##_##f##_ALIGN +#define BRCM_BITS(c,r,f) c##_##r##_##f##_BITS +#define BRCM_MASK(c,r,f) c##_##r##_##f##_MASK +#define BRCM_SHIFT(c,r,f) c##_##r##_##f##_SHIFT + +#define GET_FIELD(m,c,r,f) \ + ((((m) & BRCM_MASK(c,r,f)) >> BRCM_SHIFT(c,r,f)) << BRCM_ALIGN(c,r,f)) + +#define SET_FIELD(m,c,r,f,d) \ + ((m) = (((m) & ~BRCM_MASK(c,r,f)) | ((((d) >> BRCM_ALIGN(c,r,f)) << \ + BRCM_SHIFT(c,r,f)) & BRCM_MASK(c,r,f))) \ + ) + +#define SET_TYPE_FIELD(m,c,r,f,d) SET_FIELD(m,c,r,f,c##_##d) +#define SET_NAME_FIELD(m,c,r,f,d) SET_FIELD(m,c,r,f,c##_##r##_##f##_##d) +#define SET_VALUE_FIELD(m,c,r,f,d) SET_FIELD(m,c,r,f,d) + +#endif /* GET & SET */ + +/**************************************************************************** + * Core Enums. + ***************************************************************************/ +/**************************************************************************** + * Enums: AES_RGR_BRIDGE_RESET_CTRL + ***************************************************************************/ +#define AES_RGR_BRIDGE_RESET_CTRL_DEASSERT 0 +#define AES_RGR_BRIDGE_RESET_CTRL_ASSERT 1 + +/**************************************************************************** + * Enums: CCE_RGR_BRIDGE_RESET_CTRL + ***************************************************************************/ +#define CCE_RGR_BRIDGE_RESET_CTRL_DEASSERT 0 +#define CCE_RGR_BRIDGE_RESET_CTRL_ASSERT 1 + +/**************************************************************************** + * Enums: DBU_RGR_BRIDGE_RESET_CTRL + ***************************************************************************/ +#define DBU_RGR_BRIDGE_RESET_CTRL_DEASSERT 0 +#define DBU_RGR_BRIDGE_RESET_CTRL_ASSERT 1 + +/**************************************************************************** + * Enums: DCI_RGR_BRIDGE_RESET_CTRL + ***************************************************************************/ +#define DCI_RGR_BRIDGE_RESET_CTRL_DEASSERT 0 +#define DCI_RGR_BRIDGE_RESET_CTRL_ASSERT 1 + +/**************************************************************************** + * Enums: GISB_ARBITER_DEASSERT_ASSERT + ***************************************************************************/ +#define GISB_ARBITER_DEASSERT_ASSERT_DEASSERT 0 +#define GISB_ARBITER_DEASSERT_ASSERT_ASSERT 1 + +/**************************************************************************** + * Enums: GISB_ARBITER_UNMASK_MASK + ***************************************************************************/ +#define GISB_ARBITER_UNMASK_MASK_UNMASK 0 +#define GISB_ARBITER_UNMASK_MASK_MASK 1 + +/**************************************************************************** + * Enums: GISB_ARBITER_DISABLE_ENABLE + ***************************************************************************/ +#define GISB_ARBITER_DISABLE_ENABLE_DISABLE 0 +#define GISB_ARBITER_DISABLE_ENABLE_ENABLE 1 + +/**************************************************************************** + * Enums: I2C_GR_BRIDGE_RESET_CTRL + ***************************************************************************/ +#define I2C_GR_BRIDGE_RESET_CTRL_DEASSERT 0 +#define I2C_GR_BRIDGE_RESET_CTRL_ASSERT 1 + +/**************************************************************************** + * Enums: MISC_GR_BRIDGE_RESET_CTRL + ***************************************************************************/ +#define MISC_GR_BRIDGE_RESET_CTRL_DEASSERT 0 +#define MISC_GR_BRIDGE_RESET_CTRL_ASSERT 1 + +/**************************************************************************** + * Enums: OTP_GR_BRIDGE_RESET_CTRL + ***************************************************************************/ +#define OTP_GR_BRIDGE_RESET_CTRL_DEASSERT 0 +#define OTP_GR_BRIDGE_RESET_CTRL_ASSERT 1 + +/**************************************************************************** + * BCM70012_TGT_TOP_PCIE_CFG + ***************************************************************************/ +#define PCIE_CFG_DEVICE_VENDOR_ID 0x00000000 /* DEVICE_VENDOR_ID Register */ +#define PCIE_CFG_STATUS_COMMAND 0x00000004 /* STATUS_COMMAND Register */ +#define PCIE_CFG_PCI_CLASSCODE_AND_REVISION_ID 0x00000008 /* PCI_CLASSCODE_AND_REVISION_ID Register */ +#define PCIE_CFG_BIST_HEADER_TYPE_LATENCY_TIMER_CACHE_LINE_SIZE 0x0000000c /* BIST_HEADER_TYPE_LATENCY_TIMER_CACHE_LINE_SIZE Register */ +#define PCIE_CFG_BASE_ADDRESS_1 0x00000010 /* BASE_ADDRESS_1 Register */ +#define PCIE_CFG_BASE_ADDRESS_2 0x00000014 /* BASE_ADDRESS_2 Register */ +#define PCIE_CFG_BASE_ADDRESS_3 0x00000018 /* BASE_ADDRESS_3 Register */ +#define PCIE_CFG_BASE_ADDRESS_4 0x0000001c /* BASE_ADDRESS_4 Register */ +#define PCIE_CFG_CARDBUS_CIS_POINTER 0x00000028 /* CARDBUS_CIS_POINTER Register */ +#define PCIE_CFG_SUBSYSTEM_DEVICE_VENDOR_ID 0x0000002c /* SUBSYSTEM_DEVICE_VENDOR_ID Register */ +#define PCIE_CFG_EXPANSION_ROM_BASE_ADDRESS 0x00000030 /* EXPANSION_ROM_BASE_ADDRESS Register */ +#define PCIE_CFG_CAPABILITIES_POINTER 0x00000034 /* CAPABILITIES_POINTER Register */ +#define PCIE_CFG_INTERRUPT 0x0000003c /* INTERRUPT Register */ +#define PCIE_CFG_VPD_CAPABILITIES 0x00000040 /* VPD_CAPABILITIES Register */ +#define PCIE_CFG_VPD_DATA 0x00000044 /* VPD_DATA Register */ +#define PCIE_CFG_POWER_MANAGEMENT_CAPABILITY 0x00000048 /* POWER_MANAGEMENT_CAPABILITY Register */ +#define PCIE_CFG_POWER_MANAGEMENT_CONTROL_STATUS 0x0000004c /* POWER_MANAGEMENT_CONTROL_STATUS Register */ +#define PCIE_CFG_MSI_CAPABILITY_HEADER 0x00000050 /* MSI_CAPABILITY_HEADER Register */ +#define PCIE_CFG_MSI_LOWER_ADDRESS 0x00000054 /* MSI_LOWER_ADDRESS Register */ +#define PCIE_CFG_MSI_UPPER_ADDRESS_REGISTER 0x00000058 /* MSI_UPPER_ADDRESS_REGISTER Register */ +#define PCIE_CFG_MSI_DATA 0x0000005c /* MSI_DATA Register */ +#define PCIE_CFG_BROADCOM_VENDOR_SPECIFIC_CAPABILITY_HEADER 0x00000060 /* BROADCOM_VENDOR_SPECIFIC_CAPABILITY_HEADER Register */ +#define PCIE_CFG_RESET_COUNTERS_INITIAL_VALUES 0x00000064 /* RESET_COUNTERS_INITIAL_VALUES Register */ +#define PCIE_CFG_MISCELLANEOUS_HOST_CONTROL 0x00000068 /* MISCELLANEOUS_HOST_CONTROL Register */ +#define PCIE_CFG_SPARE 0x0000006c /* SPARE Register */ +#define PCIE_CFG_PCI_STATE 0x00000070 /* PCI_STATE Register */ +#define PCIE_CFG_CLOCK_CONTROL 0x00000074 /* CLOCK_CONTROL Register */ +#define PCIE_CFG_REGISTER_BASE 0x00000078 /* REGISTER_BASE Register */ +#define PCIE_CFG_MEMORY_BASE 0x0000007c /* MEMORY_BASE Register */ +#define PCIE_CFG_REGISTER_DATA 0x00000080 /* REGISTER_DATA Register */ +#define PCIE_CFG_MEMORY_DATA 0x00000084 /* MEMORY_DATA Register */ +#define PCIE_CFG_EXPANSION_ROM_BAR_SIZE 0x00000088 /* EXPANSION_ROM_BAR_SIZE Register */ +#define PCIE_CFG_EXPANSION_ROM_ADDRESS 0x0000008c /* EXPANSION_ROM_ADDRESS Register */ +#define PCIE_CFG_EXPANSION_ROM_DATA 0x00000090 /* EXPANSION_ROM_DATA Register */ +#define PCIE_CFG_VPD_INTERFACE 0x00000094 /* VPD_INTERFACE Register */ +#define PCIE_CFG_UNDI_RECEIVE_BD_STANDARD_PRODUCER_RING_PRODUCER_INDEX_MAILBOX_UPPER 0x00000098 /* UNDI_RECEIVE_BD_STANDARD_PRODUCER_RING_PRODUCER_INDEX_MAILBOX_UPPER Register */ +#define PCIE_CFG_UNDI_RECEIVE_BD_STANDARD_PRODUCER_RING_PRODUCER_INDEX_MAILBOX_LOWER 0x0000009c /* UNDI_RECEIVE_BD_STANDARD_PRODUCER_RING_PRODUCER_INDEX_MAILBOX_LOWER Register */ +#define PCIE_CFG_UNDI_RECEIVE_RETURN_RING_CONSUMER_INDEX_UPPER 0x000000a0 /* UNDI_RECEIVE_RETURN_RING_CONSUMER_INDEX_UPPER Register */ +#define PCIE_CFG_UNDI_RECEIVE_RETURN_RING_CONSUMER_INDEX_LOWER 0x000000a4 /* UNDI_RECEIVE_RETURN_RING_CONSUMER_INDEX_LOWER Register */ +#define PCIE_CFG_UNDI_SEND_BD_PRODUCER_INDEX_MAILBOX_UPPER 0x000000a8 /* UNDI_SEND_BD_PRODUCER_INDEX_MAILBOX_UPPER Register */ +#define PCIE_CFG_UNDI_SEND_BD_PRODUCER_INDEX_MAILBOX_LOWER 0x000000ac /* UNDI_SEND_BD_PRODUCER_INDEX_MAILBOX_LOWER Register */ +#define PCIE_CFG_INT_MAILBOX_UPPER 0x000000b0 /* INT_MAILBOX_UPPER Register */ +#define PCIE_CFG_INT_MAILBOX_LOWER 0x000000b4 /* INT_MAILBOX_LOWER Register */ +#define PCIE_CFG_PRODUCT_ID_AND_ASIC_REVISION 0x000000bc /* PRODUCT_ID_AND_ASIC_REVISION Register */ +#define PCIE_CFG_FUNCTION_EVENT 0x000000c0 /* FUNCTION_EVENT Register */ +#define PCIE_CFG_FUNCTION_EVENT_MASK 0x000000c4 /* FUNCTION_EVENT_MASK Register */ +#define PCIE_CFG_FUNCTION_PRESENT 0x000000c8 /* FUNCTION_PRESENT Register */ +#define PCIE_CFG_PCIE_CAPABILITIES 0x000000cc /* PCIE_CAPABILITIES Register */ +#define PCIE_CFG_DEVICE_CAPABILITIES 0x000000d0 /* DEVICE_CAPABILITIES Register */ +#define PCIE_CFG_DEVICE_STATUS_CONTROL 0x000000d4 /* DEVICE_STATUS_CONTROL Register */ +#define PCIE_CFG_LINK_CAPABILITY 0x000000d8 /* LINK_CAPABILITY Register */ +#define PCIE_CFG_LINK_STATUS_CONTROL 0x000000dc /* LINK_STATUS_CONTROL Register */ +#define PCIE_CFG_DEVICE_CAPABILITIES_2 0x000000f0 /* DEVICE_CAPABILITIES_2 Register */ +#define PCIE_CFG_DEVICE_STATUS_CONTROL_2 0x000000f4 /* DEVICE_STATUS_CONTROL_2 Register */ +#define PCIE_CFG_LINK_CAPABILITIES_2 0x000000f8 /* LINK_CAPABILITIES_2 Register */ +#define PCIE_CFG_LINK_STATUS_CONTROL_2 0x000000fc /* LINK_STATUS_CONTROL_2 Register */ +#define PCIE_CFG_ADVANCED_ERROR_REPORTING_ENHANCED_CAPABILITY_HEADER 0x00000100 /* ADVANCED_ERROR_REPORTING_ENHANCED_CAPABILITY_HEADER Register */ +#define PCIE_CFG_UNCORRECTABLE_ERROR_STATUS 0x00000104 /* UNCORRECTABLE_ERROR_STATUS Register */ +#define PCIE_CFG_UNCORRECTABLE_ERROR_MASK 0x00000108 /* UNCORRECTABLE_ERROR_MASK Register */ +#define PCIE_CFG_UNCORRECTABLE_ERROR_SEVERITY 0x0000010c /* UNCORRECTABLE_ERROR_SEVERITY Register */ +#define PCIE_CFG_CORRECTABLE_ERROR_STATUS 0x00000110 /* CORRECTABLE_ERROR_STATUS Register */ +#define PCIE_CFG_CORRECTABLE_ERROR_MASK 0x00000114 /* CORRECTABLE_ERROR_MASK Register */ +#define PCIE_CFG_ADVANCED_ERROR_CAPABILITIES_AND_CONTROL 0x00000118 /* ADVANCED_ERROR_CAPABILITIES_AND_CONTROL Register */ +#define PCIE_CFG_HEADER_LOG_1 0x0000011c /* HEADER_LOG_1 Register */ +#define PCIE_CFG_HEADER_LOG_2 0x00000120 /* HEADER_LOG_2 Register */ +#define PCIE_CFG_HEADER_LOG_3 0x00000124 /* HEADER_LOG_3 Register */ +#define PCIE_CFG_HEADER_LOG_4 0x00000128 /* HEADER_LOG_4 Register */ +#define PCIE_CFG_VIRTUAL_CHANNEL_ENHANCED_CAPABILITY_HEADER 0x0000013c /* VIRTUAL_CHANNEL_ENHANCED_CAPABILITY_HEADER Register */ +#define PCIE_CFG_PORT_VC_CAPABILITY 0x00000140 /* PORT_VC_CAPABILITY Register */ +#define PCIE_CFG_PORT_VC_CAPABILITY_2 0x00000144 /* PORT_VC_CAPABILITY_2 Register */ +#define PCIE_CFG_PORT_VC_STATUS_CONTROL 0x00000148 /* PORT_VC_STATUS_CONTROL Register */ +#define PCIE_CFG_VC_RESOURCE_CAPABILITY 0x0000014c /* VC_RESOURCE_CAPABILITY Register */ +#define PCIE_CFG_VC_RESOURCE_CONTROL 0x00000150 /* VC_RESOURCE_CONTROL Register */ +#define PCIE_CFG_VC_RESOURCE_STATUS 0x00000154 /* VC_RESOURCE_STATUS Register */ +#define PCIE_CFG_DEVICE_SERIAL_NO_ENHANCED_CAPABILITY_HEADER 0x00000160 /* DEVICE_SERIAL_NO_ENHANCED_CAPABILITY_HEADER Register */ +#define PCIE_CFG_DEVICE_SERIAL_NO_LOWER_DW 0x00000164 /* DEVICE_SERIAL_NO_LOWER_DW Register */ +#define PCIE_CFG_DEVICE_SERIAL_NO_UPPER_DW 0x00000168 /* DEVICE_SERIAL_NO_UPPER_DW Register */ +#define PCIE_CFG_POWER_BUDGETING_ENHANCED_CAPABILITY_HEADER 0x0000016c /* POWER_BUDGETING_ENHANCED_CAPABILITY_HEADER Register */ +#define PCIE_CFG_POWER_BUDGETING_DATA_SELECT 0x00000170 /* POWER_BUDGETING_DATA_SELECT Register */ +#define PCIE_CFG_POWER_BUDGETING_DATA 0x00000174 /* POWER_BUDGETING_DATA Register */ +#define PCIE_CFG_POWER_BUDGETING_CAPABILITY 0x00000178 /* POWER_BUDGETING_CAPABILITY Register */ +#define PCIE_CFG_FIRMWARE_POWER_BUDGETING_2_1 0x0000017c /* FIRMWARE_POWER_BUDGETING_2_1 Register */ +#define PCIE_CFG_FIRMWARE_POWER_BUDGETING_4_3 0x00000180 /* FIRMWARE_POWER_BUDGETING_4_3 Register */ +#define PCIE_CFG_FIRMWARE_POWER_BUDGETING_6_5 0x00000184 /* FIRMWARE_POWER_BUDGETING_6_5 Register */ +#define PCIE_CFG_FIRMWARE_POWER_BUDGETING_8_7 0x00000188 /* FIRMWARE_POWER_BUDGETING_8_7 Register */ +#define PCIE_CFG_PCIE_1_1_ADVISORY_NON_FATAL_ERROR_MASKING 0x0000018c /* PCIE_1_1_ADVISORY_NON_FATAL_ERROR_MASKING Register */ + + +/**************************************************************************** + * BCM70012_TGT_TOP_PCIE_TL + ***************************************************************************/ +#define PCIE_TL_TL_CONTROL 0x00000400 /* TL_CONTROL Register */ +#define PCIE_TL_TRANSACTION_CONFIGURATION 0x00000404 /* TRANSACTION_CONFIGURATION Register */ + + +/**************************************************************************** + * BCM70012_TGT_TOP_PCIE_DLL + ***************************************************************************/ +#define PCIE_DLL_DATA_LINK_CONTROL 0x00000500 /* DATA_LINK_CONTROL Register */ +#define PCIE_DLL_DATA_LINK_STATUS 0x00000504 /* DATA_LINK_STATUS Register */ + + +/**************************************************************************** + * BCM70012_TGT_TOP_INTR + ***************************************************************************/ +#define INTR_INTR_STATUS 0x00000700 /* Interrupt Status Register */ +#define INTR_INTR_SET 0x00000704 /* Interrupt Set Register */ +#define INTR_INTR_CLR_REG 0x00000708 /* Interrupt Clear Register */ +#define INTR_INTR_MSK_STS_REG 0x0000070c /* Interrupt Mask Status Register */ +#define INTR_INTR_MSK_SET_REG 0x00000710 /* Interrupt Mask Set Register */ +#define INTR_INTR_MSK_CLR_REG 0x00000714 /* Interrupt Mask Clear Register */ +#define INTR_EOI_CTRL 0x00000720 /* End of interrupt control register */ + + +/**************************************************************************** + * BCM70012_MISC_TOP_MISC1 + ***************************************************************************/ +#define MISC1_TX_FIRST_DESC_L_ADDR_LIST0 0x00000c00 /* Tx DMA Descriptor List0 First Descriptor lower Address */ +#define MISC1_TX_FIRST_DESC_U_ADDR_LIST0 0x00000c04 /* Tx DMA Descriptor List0 First Descriptor Upper Address */ +#define MISC1_TX_FIRST_DESC_L_ADDR_LIST1 0x00000c08 /* Tx DMA Descriptor List1 First Descriptor Lower Address */ +#define MISC1_TX_FIRST_DESC_U_ADDR_LIST1 0x00000c0c /* Tx DMA Descriptor List1 First Descriptor Upper Address */ +#define MISC1_TX_SW_DESC_LIST_CTRL_STS 0x00000c10 /* Tx DMA Software Descriptor List Control and Status */ +#define MISC1_TX_DMA_ERROR_STATUS 0x00000c18 /* Tx DMA Engine Error Status */ +#define MISC1_TX_DMA_LIST0_CUR_DESC_L_ADDR 0x00000c1c /* Tx DMA List0 Current Descriptor Lower Address */ +#define MISC1_TX_DMA_LIST0_CUR_DESC_U_ADDR 0x00000c20 /* Tx DMA List0 Current Descriptor Upper Address */ +#define MISC1_TX_DMA_LIST0_CUR_BYTE_CNT_REM 0x00000c24 /* Tx DMA List0 Current Descriptor Upper Address */ +#define MISC1_TX_DMA_LIST1_CUR_DESC_L_ADDR 0x00000c28 /* Tx DMA List1 Current Descriptor Lower Address */ +#define MISC1_TX_DMA_LIST1_CUR_DESC_U_ADDR 0x00000c2c /* Tx DMA List1 Current Descriptor Upper Address */ +#define MISC1_TX_DMA_LIST1_CUR_BYTE_CNT_REM 0x00000c30 /* Tx DMA List1 Current Descriptor Upper Address */ +#define MISC1_Y_RX_FIRST_DESC_L_ADDR_LIST0 0x00000c34 /* Y Rx Descriptor List0 First Descriptor Lower Address */ +#define MISC1_Y_RX_FIRST_DESC_U_ADDR_LIST0 0x00000c38 /* Y Rx Descriptor List0 First Descriptor Upper Address */ +#define MISC1_Y_RX_FIRST_DESC_L_ADDR_LIST1 0x00000c3c /* Y Rx Descriptor List1 First Descriptor Lower Address */ +#define MISC1_Y_RX_FIRST_DESC_U_ADDR_LIST1 0x00000c40 /* Y Rx Descriptor List1 First Descriptor Upper Address */ +#define MISC1_Y_RX_SW_DESC_LIST_CTRL_STS 0x00000c44 /* Y Rx Software Descriptor List Control and Status */ +#define MISC1_Y_RX_ERROR_STATUS 0x00000c4c /* Y Rx Engine Error Status */ +#define MISC1_Y_RX_LIST0_CUR_DESC_L_ADDR 0x00000c50 /* Y Rx List0 Current Descriptor Lower Address */ +#define MISC1_Y_RX_LIST0_CUR_DESC_U_ADDR 0x00000c54 /* Y Rx List0 Current Descriptor Upper Address */ +#define MISC1_Y_RX_LIST0_CUR_BYTE_CNT 0x00000c58 /* Y Rx List0 Current Descriptor Byte Count */ +#define MISC1_Y_RX_LIST1_CUR_DESC_L_ADDR 0x00000c5c /* Y Rx List1 Current Descriptor Lower address */ +#define MISC1_Y_RX_LIST1_CUR_DESC_U_ADDR 0x00000c60 /* Y Rx List1 Current Descriptor Upper address */ +#define MISC1_Y_RX_LIST1_CUR_BYTE_CNT 0x00000c64 /* Y Rx List1 Current Descriptor Byte Count */ +#define MISC1_UV_RX_FIRST_DESC_L_ADDR_LIST0 0x00000c68 /* UV Rx Descriptor List0 First Descriptor lower Address */ +#define MISC1_UV_RX_FIRST_DESC_U_ADDR_LIST0 0x00000c6c /* UV Rx Descriptor List0 First Descriptor Upper Address */ +#define MISC1_UV_RX_FIRST_DESC_L_ADDR_LIST1 0x00000c70 /* UV Rx Descriptor List1 First Descriptor Lower Address */ +#define MISC1_UV_RX_FIRST_DESC_U_ADDR_LIST1 0x00000c74 /* UV Rx Descriptor List1 First Descriptor Upper Address */ +#define MISC1_UV_RX_SW_DESC_LIST_CTRL_STS 0x00000c78 /* UV Rx Software Descriptor List Control and Status */ +#define MISC1_UV_RX_ERROR_STATUS 0x00000c7c /* UV Rx Engine Error Status */ +#define MISC1_UV_RX_LIST0_CUR_DESC_L_ADDR 0x00000c80 /* UV Rx List0 Current Descriptor Lower Address */ +#define MISC1_UV_RX_LIST0_CUR_DESC_U_ADDR 0x00000c84 /* UV Rx List0 Current Descriptor Upper Address */ +#define MISC1_UV_RX_LIST0_CUR_BYTE_CNT 0x00000c88 /* UV Rx List0 Current Descriptor Byte Count */ +#define MISC1_UV_RX_LIST1_CUR_DESC_L_ADDR 0x00000c8c /* UV Rx List1 Current Descriptor Lower Address */ +#define MISC1_UV_RX_LIST1_CUR_DESC_U_ADDR 0x00000c90 /* UV Rx List1 Current Descriptor Upper Address */ +#define MISC1_UV_RX_LIST1_CUR_BYTE_CNT 0x00000c94 /* UV Rx List1 Current Descriptor Byte Count */ +#define MISC1_DMA_DEBUG_OPTIONS_REG 0x00000c98 /* DMA Debug Options Register */ +#define MISC1_READ_CHANNEL_ERROR_STATUS 0x00000c9c /* Read Channel Error Status */ +#define MISC1_PCIE_DMA_CTRL 0x00000ca0 /* PCIE DMA Control Register */ + + +/**************************************************************************** + * BCM70012_MISC_TOP_MISC2 + ***************************************************************************/ +#define MISC2_GLOBAL_CTRL 0x00000d00 /* Global Control Register */ +#define MISC2_INTERNAL_STATUS 0x00000d04 /* Internal Status Register */ +#define MISC2_INTERNAL_STATUS_MUX_CTRL 0x00000d08 /* Internal Debug Mux Control */ +#define MISC2_DEBUG_FIFO_LENGTH 0x00000d0c /* Debug FIFO Length */ + + +/**************************************************************************** + * BCM70012_MISC_TOP_MISC3 + ***************************************************************************/ +#define MISC3_RESET_CTRL 0x00000e00 /* Reset Control Register */ +#define MISC3_BIST_CTRL 0x00000e04 /* BIST Control Register */ +#define MISC3_BIST_STATUS 0x00000e08 /* BIST Status Register */ +#define MISC3_RX_CHECKSUM 0x00000e0c /* Receive Checksum */ +#define MISC3_TX_CHECKSUM 0x00000e10 /* Transmit Checksum */ +#define MISC3_ECO_CTRL_CORE 0x00000e14 /* ECO Core Reset Control Register */ +#define MISC3_CSI_TEST_CTRL 0x00000e18 /* CSI Test Control Register */ +#define MISC3_HD_DVI_TEST_CTRL 0x00000e1c /* HD DVI Test Control Register */ + + +/**************************************************************************** + * BCM70012_MISC_TOP_MISC_PERST + ***************************************************************************/ +#define MISC_PERST_ECO_CTRL_PERST 0x00000e80 /* ECO PCIE Reset Control Register */ +#define MISC_PERST_DECODER_CTRL 0x00000e84 /* Decoder Control Register */ +#define MISC_PERST_CCE_STATUS 0x00000e88 /* Config Copy Engine Status */ +#define MISC_PERST_PCIE_DEBUG 0x00000e8c /* PCIE Debug Control Register */ +#define MISC_PERST_PCIE_DEBUG_STATUS 0x00000e90 /* PCIE Debug Status Register */ +#define MISC_PERST_VREG_CTRL 0x00000e94 /* Voltage Regulator Control Register */ +#define MISC_PERST_MEM_CTRL 0x00000e98 /* Memory Control Register */ +#define MISC_PERST_CLOCK_CTRL 0x00000e9c /* Clock Control Register */ + + +/**************************************************************************** + * BCM70012_MISC_TOP_GISB_ARBITER + ***************************************************************************/ +#define GISB_ARBITER_REVISION 0x00000f00 /* GISB ARBITER REVISION */ +#define GISB_ARBITER_SCRATCH 0x00000f04 /* GISB ARBITER Scratch Register */ +#define GISB_ARBITER_REQ_MASK 0x00000f08 /* GISB ARBITER Master Request Mask Register */ +#define GISB_ARBITER_TIMER 0x00000f0c /* GISB ARBITER Timer Value Register */ + + +/**************************************************************************** + * BCM70012_OTP_TOP_OTP + ***************************************************************************/ +#define OTP_CONFIG_INFO 0x00001400 /* OTP Configuration Register */ +#define OTP_CMD 0x00001404 /* OTP Command Register */ +#define OTP_STATUS 0x00001408 /* OTP Status Register */ +#define OTP_CONTENT_MISC 0x0000140c /* Content : Miscellaneous Register */ +#define OTP_CONTENT_AES_0 0x00001410 /* Content : AES Key 0 Register */ +#define OTP_CONTENT_AES_1 0x00001414 /* Content : AES Key 1 Register */ +#define OTP_CONTENT_AES_2 0x00001418 /* Content : AES Key 2 Register */ +#define OTP_CONTENT_AES_3 0x0000141c /* Content : AES Key 3 Register */ +#define OTP_CONTENT_SHA_0 0x00001420 /* Content : SHA Key 0 Register */ +#define OTP_CONTENT_SHA_1 0x00001424 /* Content : SHA Key 1 Register */ +#define OTP_CONTENT_SHA_2 0x00001428 /* Content : SHA Key 2 Register */ +#define OTP_CONTENT_SHA_3 0x0000142c /* Content : SHA Key 3 Register */ +#define OTP_CONTENT_SHA_4 0x00001430 /* Content : SHA Key 4 Register */ +#define OTP_CONTENT_SHA_5 0x00001434 /* Content : SHA Key 5 Register */ +#define OTP_CONTENT_SHA_6 0x00001438 /* Content : SHA Key 6 Register */ +#define OTP_CONTENT_SHA_7 0x0000143c /* Content : SHA Key 7 Register */ +#define OTP_CONTENT_CHECKSUM 0x00001440 /* Content : Checksum Register */ +#define OTP_PROG_CTRL 0x00001444 /* Programming Control Register */ +#define OTP_PROG_STATUS 0x00001448 /* Programming Status Register */ +#define OTP_PROG_PULSE 0x0000144c /* Program Pulse Width Register */ +#define OTP_VERIFY_PULSE 0x00001450 /* Verify Pulse Width Register */ +#define OTP_PROG_MASK 0x00001454 /* Program Mask Register */ +#define OTP_DATA_INPUT 0x00001458 /* Data Input Register */ +#define OTP_DATA_OUTPUT 0x0000145c /* Data Output Register */ + + +/**************************************************************************** + * BCM70012_AES_TOP_AES + ***************************************************************************/ +#define AES_CONFIG_INFO 0x00001800 /* AES Configuration Information Register */ +#define AES_CMD 0x00001804 /* AES Command Register */ +#define AES_STATUS 0x00001808 /* AES Status Register */ +#define AES_EEPROM_CONFIG 0x0000180c /* AES EEPROM Configuration Register */ +#define AES_EEPROM_DATA_0 0x00001810 /* AES EEPROM Data Register 0 */ +#define AES_EEPROM_DATA_1 0x00001814 /* AES EEPROM Data Register 1 */ +#define AES_EEPROM_DATA_2 0x00001818 /* AES EEPROM Data Register 2 */ +#define AES_EEPROM_DATA_3 0x0000181c /* AES EEPROM Data Register 3 */ + + +/**************************************************************************** + * BCM70012_DCI_TOP_DCI + ***************************************************************************/ +#define DCI_CMD 0x00001c00 /* DCI Command Register */ +#define DCI_STATUS 0x00001c04 /* DCI Status Register */ +#define DCI_DRAM_BASE_ADDR 0x00001c08 /* DRAM Base Address Register */ +#define DCI_FIRMWARE_ADDR 0x00001c0c /* Firmware Address Register */ +#define DCI_FIRMWARE_DATA 0x00001c10 /* Firmware Data Register */ +#define DCI_SIGNATURE_DATA_0 0x00001c14 /* Signature Data Register 0 */ +#define DCI_SIGNATURE_DATA_1 0x00001c18 /* Signature Data Register 1 */ +#define DCI_SIGNATURE_DATA_2 0x00001c1c /* Signature Data Register 2 */ +#define DCI_SIGNATURE_DATA_3 0x00001c20 /* Signature Data Register 3 */ +#define DCI_SIGNATURE_DATA_4 0x00001c24 /* Signature Data Register 4 */ +#define DCI_SIGNATURE_DATA_5 0x00001c28 /* Signature Data Register 5 */ +#define DCI_SIGNATURE_DATA_6 0x00001c2c /* Signature Data Register 6 */ +#define DCI_SIGNATURE_DATA_7 0x00001c30 /* Signature Data Register 7 */ + + +/**************************************************************************** + * BCM70012_TGT_TOP_INTR + ***************************************************************************/ +/**************************************************************************** + * INTR :: INTR_STATUS + ***************************************************************************/ +/* INTR :: INTR_STATUS :: reserved0 [31:26] */ +#define INTR_INTR_STATUS_reserved0_MASK 0xfc000000 +#define INTR_INTR_STATUS_reserved0_ALIGN 0 +#define INTR_INTR_STATUS_reserved0_BITS 6 +#define INTR_INTR_STATUS_reserved0_SHIFT 26 + +/* INTR :: INTR_STATUS :: PCIE_TGT_CA_ATTN [25:25] */ +#define INTR_INTR_STATUS_PCIE_TGT_CA_ATTN_MASK 0x02000000 +#define INTR_INTR_STATUS_PCIE_TGT_CA_ATTN_ALIGN 0 +#define INTR_INTR_STATUS_PCIE_TGT_CA_ATTN_BITS 1 +#define INTR_INTR_STATUS_PCIE_TGT_CA_ATTN_SHIFT 25 + +/* INTR :: INTR_STATUS :: PCIE_TGT_UR_ATTN [24:24] */ +#define INTR_INTR_STATUS_PCIE_TGT_UR_ATTN_MASK 0x01000000 +#define INTR_INTR_STATUS_PCIE_TGT_UR_ATTN_ALIGN 0 +#define INTR_INTR_STATUS_PCIE_TGT_UR_ATTN_BITS 1 +#define INTR_INTR_STATUS_PCIE_TGT_UR_ATTN_SHIFT 24 + +/* INTR :: INTR_STATUS :: reserved1 [23:14] */ +#define INTR_INTR_STATUS_reserved1_MASK 0x00ffc000 +#define INTR_INTR_STATUS_reserved1_ALIGN 0 +#define INTR_INTR_STATUS_reserved1_BITS 10 +#define INTR_INTR_STATUS_reserved1_SHIFT 14 + +/* INTR :: INTR_STATUS :: L1_UV_RX_DMA_ERR_INTR [13:13] */ +#define INTR_INTR_STATUS_L1_UV_RX_DMA_ERR_INTR_MASK 0x00002000 +#define INTR_INTR_STATUS_L1_UV_RX_DMA_ERR_INTR_ALIGN 0 +#define INTR_INTR_STATUS_L1_UV_RX_DMA_ERR_INTR_BITS 1 +#define INTR_INTR_STATUS_L1_UV_RX_DMA_ERR_INTR_SHIFT 13 + +/* INTR :: INTR_STATUS :: L1_UV_RX_DMA_DONE_INTR [12:12] */ +#define INTR_INTR_STATUS_L1_UV_RX_DMA_DONE_INTR_MASK 0x00001000 +#define INTR_INTR_STATUS_L1_UV_RX_DMA_DONE_INTR_ALIGN 0 +#define INTR_INTR_STATUS_L1_UV_RX_DMA_DONE_INTR_BITS 1 +#define INTR_INTR_STATUS_L1_UV_RX_DMA_DONE_INTR_SHIFT 12 + +/* INTR :: INTR_STATUS :: L1_Y_RX_DMA_ERR_INTR [11:11] */ +#define INTR_INTR_STATUS_L1_Y_RX_DMA_ERR_INTR_MASK 0x00000800 +#define INTR_INTR_STATUS_L1_Y_RX_DMA_ERR_INTR_ALIGN 0 +#define INTR_INTR_STATUS_L1_Y_RX_DMA_ERR_INTR_BITS 1 +#define INTR_INTR_STATUS_L1_Y_RX_DMA_ERR_INTR_SHIFT 11 + +/* INTR :: INTR_STATUS :: L1_Y_RX_DMA_DONE_INTR [10:10] */ +#define INTR_INTR_STATUS_L1_Y_RX_DMA_DONE_INTR_MASK 0x00000400 +#define INTR_INTR_STATUS_L1_Y_RX_DMA_DONE_INTR_ALIGN 0 +#define INTR_INTR_STATUS_L1_Y_RX_DMA_DONE_INTR_BITS 1 +#define INTR_INTR_STATUS_L1_Y_RX_DMA_DONE_INTR_SHIFT 10 + +/* INTR :: INTR_STATUS :: L1_TX_DMA_ERR_INTR [09:09] */ +#define INTR_INTR_STATUS_L1_TX_DMA_ERR_INTR_MASK 0x00000200 +#define INTR_INTR_STATUS_L1_TX_DMA_ERR_INTR_ALIGN 0 +#define INTR_INTR_STATUS_L1_TX_DMA_ERR_INTR_BITS 1 +#define INTR_INTR_STATUS_L1_TX_DMA_ERR_INTR_SHIFT 9 + +/* INTR :: INTR_STATUS :: L1_TX_DMA_DONE_INTR [08:08] */ +#define INTR_INTR_STATUS_L1_TX_DMA_DONE_INTR_MASK 0x00000100 +#define INTR_INTR_STATUS_L1_TX_DMA_DONE_INTR_ALIGN 0 +#define INTR_INTR_STATUS_L1_TX_DMA_DONE_INTR_BITS 1 +#define INTR_INTR_STATUS_L1_TX_DMA_DONE_INTR_SHIFT 8 + +/* INTR :: INTR_STATUS :: reserved2 [07:06] */ +#define INTR_INTR_STATUS_reserved2_MASK 0x000000c0 +#define INTR_INTR_STATUS_reserved2_ALIGN 0 +#define INTR_INTR_STATUS_reserved2_BITS 2 +#define INTR_INTR_STATUS_reserved2_SHIFT 6 + +/* INTR :: INTR_STATUS :: L0_UV_RX_DMA_ERR_INTR [05:05] */ +#define INTR_INTR_STATUS_L0_UV_RX_DMA_ERR_INTR_MASK 0x00000020 +#define INTR_INTR_STATUS_L0_UV_RX_DMA_ERR_INTR_ALIGN 0 +#define INTR_INTR_STATUS_L0_UV_RX_DMA_ERR_INTR_BITS 1 +#define INTR_INTR_STATUS_L0_UV_RX_DMA_ERR_INTR_SHIFT 5 + +/* INTR :: INTR_STATUS :: L0_UV_RX_DMA_DONE_INTR [04:04] */ +#define INTR_INTR_STATUS_L0_UV_RX_DMA_DONE_INTR_MASK 0x00000010 +#define INTR_INTR_STATUS_L0_UV_RX_DMA_DONE_INTR_ALIGN 0 +#define INTR_INTR_STATUS_L0_UV_RX_DMA_DONE_INTR_BITS 1 +#define INTR_INTR_STATUS_L0_UV_RX_DMA_DONE_INTR_SHIFT 4 + +/* INTR :: INTR_STATUS :: L0_Y_RX_DMA_ERR_INTR [03:03] */ +#define INTR_INTR_STATUS_L0_Y_RX_DMA_ERR_INTR_MASK 0x00000008 +#define INTR_INTR_STATUS_L0_Y_RX_DMA_ERR_INTR_ALIGN 0 +#define INTR_INTR_STATUS_L0_Y_RX_DMA_ERR_INTR_BITS 1 +#define INTR_INTR_STATUS_L0_Y_RX_DMA_ERR_INTR_SHIFT 3 + +/* INTR :: INTR_STATUS :: L0_Y_RX_DMA_DONE_INTR [02:02] */ +#define INTR_INTR_STATUS_L0_Y_RX_DMA_DONE_INTR_MASK 0x00000004 +#define INTR_INTR_STATUS_L0_Y_RX_DMA_DONE_INTR_ALIGN 0 +#define INTR_INTR_STATUS_L0_Y_RX_DMA_DONE_INTR_BITS 1 +#define INTR_INTR_STATUS_L0_Y_RX_DMA_DONE_INTR_SHIFT 2 + +/* INTR :: INTR_STATUS :: L0_TX_DMA_ERR_INTR [01:01] */ +#define INTR_INTR_STATUS_L0_TX_DMA_ERR_INTR_MASK 0x00000002 +#define INTR_INTR_STATUS_L0_TX_DMA_ERR_INTR_ALIGN 0 +#define INTR_INTR_STATUS_L0_TX_DMA_ERR_INTR_BITS 1 +#define INTR_INTR_STATUS_L0_TX_DMA_ERR_INTR_SHIFT 1 + +/* INTR :: INTR_STATUS :: L0_TX_DMA_DONE_INTR [00:00] */ +#define INTR_INTR_STATUS_L0_TX_DMA_DONE_INTR_MASK 0x00000001 +#define INTR_INTR_STATUS_L0_TX_DMA_DONE_INTR_ALIGN 0 +#define INTR_INTR_STATUS_L0_TX_DMA_DONE_INTR_BITS 1 +#define INTR_INTR_STATUS_L0_TX_DMA_DONE_INTR_SHIFT 0 + + +/**************************************************************************** + * MISC1 :: TX_SW_DESC_LIST_CTRL_STS + ***************************************************************************/ +/* MISC1 :: TX_SW_DESC_LIST_CTRL_STS :: reserved0 [31:04] */ +#define MISC1_TX_SW_DESC_LIST_CTRL_STS_reserved0_MASK 0xfffffff0 +#define MISC1_TX_SW_DESC_LIST_CTRL_STS_reserved0_ALIGN 0 +#define MISC1_TX_SW_DESC_LIST_CTRL_STS_reserved0_BITS 28 +#define MISC1_TX_SW_DESC_LIST_CTRL_STS_reserved0_SHIFT 4 + +/* MISC1 :: TX_SW_DESC_LIST_CTRL_STS :: DMA_DATA_SERV_PTR [03:03] */ +#define MISC1_TX_SW_DESC_LIST_CTRL_STS_DMA_DATA_SERV_PTR_MASK 0x00000008 +#define MISC1_TX_SW_DESC_LIST_CTRL_STS_DMA_DATA_SERV_PTR_ALIGN 0 +#define MISC1_TX_SW_DESC_LIST_CTRL_STS_DMA_DATA_SERV_PTR_BITS 1 +#define MISC1_TX_SW_DESC_LIST_CTRL_STS_DMA_DATA_SERV_PTR_SHIFT 3 + +/* MISC1 :: TX_SW_DESC_LIST_CTRL_STS :: DESC_SERV_PTR [02:02] */ +#define MISC1_TX_SW_DESC_LIST_CTRL_STS_DESC_SERV_PTR_MASK 0x00000004 +#define MISC1_TX_SW_DESC_LIST_CTRL_STS_DESC_SERV_PTR_ALIGN 0 +#define MISC1_TX_SW_DESC_LIST_CTRL_STS_DESC_SERV_PTR_BITS 1 +#define MISC1_TX_SW_DESC_LIST_CTRL_STS_DESC_SERV_PTR_SHIFT 2 + +/* MISC1 :: TX_SW_DESC_LIST_CTRL_STS :: TX_DMA_HALT_ON_ERROR [01:01] */ +#define MISC1_TX_SW_DESC_LIST_CTRL_STS_TX_DMA_HALT_ON_ERROR_MASK 0x00000002 +#define MISC1_TX_SW_DESC_LIST_CTRL_STS_TX_DMA_HALT_ON_ERROR_ALIGN 0 +#define MISC1_TX_SW_DESC_LIST_CTRL_STS_TX_DMA_HALT_ON_ERROR_BITS 1 +#define MISC1_TX_SW_DESC_LIST_CTRL_STS_TX_DMA_HALT_ON_ERROR_SHIFT 1 + +/* MISC1 :: TX_SW_DESC_LIST_CTRL_STS :: TX_DMA_RUN_STOP [00:00] */ +#define MISC1_TX_SW_DESC_LIST_CTRL_STS_TX_DMA_RUN_STOP_MASK 0x00000001 +#define MISC1_TX_SW_DESC_LIST_CTRL_STS_TX_DMA_RUN_STOP_ALIGN 0 +#define MISC1_TX_SW_DESC_LIST_CTRL_STS_TX_DMA_RUN_STOP_BITS 1 +#define MISC1_TX_SW_DESC_LIST_CTRL_STS_TX_DMA_RUN_STOP_SHIFT 0 + + +/**************************************************************************** + * MISC1 :: TX_DMA_ERROR_STATUS + ***************************************************************************/ +/* MISC1 :: TX_DMA_ERROR_STATUS :: reserved0 [31:10] */ +#define MISC1_TX_DMA_ERROR_STATUS_reserved0_MASK 0xfffffc00 +#define MISC1_TX_DMA_ERROR_STATUS_reserved0_ALIGN 0 +#define MISC1_TX_DMA_ERROR_STATUS_reserved0_BITS 22 +#define MISC1_TX_DMA_ERROR_STATUS_reserved0_SHIFT 10 + +/* MISC1 :: TX_DMA_ERROR_STATUS :: TX_L1_DESC_TX_ABORT_ERRORS [09:09] */ +#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_DESC_TX_ABORT_ERRORS_MASK 0x00000200 +#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_DESC_TX_ABORT_ERRORS_ALIGN 0 +#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_DESC_TX_ABORT_ERRORS_BITS 1 +#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_DESC_TX_ABORT_ERRORS_SHIFT 9 + +/* MISC1 :: TX_DMA_ERROR_STATUS :: reserved1 [08:08] */ +#define MISC1_TX_DMA_ERROR_STATUS_reserved1_MASK 0x00000100 +#define MISC1_TX_DMA_ERROR_STATUS_reserved1_ALIGN 0 +#define MISC1_TX_DMA_ERROR_STATUS_reserved1_BITS 1 +#define MISC1_TX_DMA_ERROR_STATUS_reserved1_SHIFT 8 + +/* MISC1 :: TX_DMA_ERROR_STATUS :: TX_L0_DESC_TX_ABORT_ERRORS [07:07] */ +#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_DESC_TX_ABORT_ERRORS_MASK 0x00000080 +#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_DESC_TX_ABORT_ERRORS_ALIGN 0 +#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_DESC_TX_ABORT_ERRORS_BITS 1 +#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_DESC_TX_ABORT_ERRORS_SHIFT 7 + +/* MISC1 :: TX_DMA_ERROR_STATUS :: reserved2 [06:06] */ +#define MISC1_TX_DMA_ERROR_STATUS_reserved2_MASK 0x00000040 +#define MISC1_TX_DMA_ERROR_STATUS_reserved2_ALIGN 0 +#define MISC1_TX_DMA_ERROR_STATUS_reserved2_BITS 1 +#define MISC1_TX_DMA_ERROR_STATUS_reserved2_SHIFT 6 + +/* MISC1 :: TX_DMA_ERROR_STATUS :: TX_L1_DMA_DATA_TX_ABORT_ERRORS [05:05] */ +#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_DMA_DATA_TX_ABORT_ERRORS_MASK 0x00000020 +#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_DMA_DATA_TX_ABORT_ERRORS_ALIGN 0 +#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_DMA_DATA_TX_ABORT_ERRORS_BITS 1 +#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_DMA_DATA_TX_ABORT_ERRORS_SHIFT 5 + +/* MISC1 :: TX_DMA_ERROR_STATUS :: TX_L1_FIFO_FULL_ERRORS [04:04] */ +#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_FIFO_FULL_ERRORS_MASK 0x00000010 +#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_FIFO_FULL_ERRORS_ALIGN 0 +#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_FIFO_FULL_ERRORS_BITS 1 +#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_FIFO_FULL_ERRORS_SHIFT 4 + +/* MISC1 :: TX_DMA_ERROR_STATUS :: reserved3 [03:03] */ +#define MISC1_TX_DMA_ERROR_STATUS_reserved3_MASK 0x00000008 +#define MISC1_TX_DMA_ERROR_STATUS_reserved3_ALIGN 0 +#define MISC1_TX_DMA_ERROR_STATUS_reserved3_BITS 1 +#define MISC1_TX_DMA_ERROR_STATUS_reserved3_SHIFT 3 + +/* MISC1 :: TX_DMA_ERROR_STATUS :: TX_L0_DMA_DATA_TX_ABORT_ERRORS [02:02] */ +#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_DMA_DATA_TX_ABORT_ERRORS_MASK 0x00000004 +#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_DMA_DATA_TX_ABORT_ERRORS_ALIGN 0 +#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_DMA_DATA_TX_ABORT_ERRORS_BITS 1 +#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_DMA_DATA_TX_ABORT_ERRORS_SHIFT 2 + +/* MISC1 :: TX_DMA_ERROR_STATUS :: TX_L0_FIFO_FULL_ERRORS [01:01] */ +#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_FIFO_FULL_ERRORS_MASK 0x00000002 +#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_FIFO_FULL_ERRORS_ALIGN 0 +#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_FIFO_FULL_ERRORS_BITS 1 +#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_FIFO_FULL_ERRORS_SHIFT 1 + +/* MISC1 :: TX_DMA_ERROR_STATUS :: reserved4 [00:00] */ +#define MISC1_TX_DMA_ERROR_STATUS_reserved4_MASK 0x00000001 +#define MISC1_TX_DMA_ERROR_STATUS_reserved4_ALIGN 0 +#define MISC1_TX_DMA_ERROR_STATUS_reserved4_BITS 1 +#define MISC1_TX_DMA_ERROR_STATUS_reserved4_SHIFT 0 + + +/**************************************************************************** + * MISC1 :: Y_RX_ERROR_STATUS + ***************************************************************************/ +/* MISC1 :: Y_RX_ERROR_STATUS :: reserved0 [31:14] */ +#define MISC1_Y_RX_ERROR_STATUS_reserved0_MASK 0xffffc000 +#define MISC1_Y_RX_ERROR_STATUS_reserved0_ALIGN 0 +#define MISC1_Y_RX_ERROR_STATUS_reserved0_BITS 18 +#define MISC1_Y_RX_ERROR_STATUS_reserved0_SHIFT 14 + +/* MISC1 :: Y_RX_ERROR_STATUS :: RX_L1_UNDERRUN_ERROR [13:13] */ +#define MISC1_Y_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_MASK 0x00002000 +#define MISC1_Y_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_ALIGN 0 +#define MISC1_Y_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_BITS 1 +#define MISC1_Y_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_SHIFT 13 + +/* MISC1 :: Y_RX_ERROR_STATUS :: RX_L1_OVERRUN_ERROR [12:12] */ +#define MISC1_Y_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_MASK 0x00001000 +#define MISC1_Y_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_ALIGN 0 +#define MISC1_Y_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_BITS 1 +#define MISC1_Y_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_SHIFT 12 + +/* MISC1 :: Y_RX_ERROR_STATUS :: RX_L0_UNDERRUN_ERROR [11:11] */ +#define MISC1_Y_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_MASK 0x00000800 +#define MISC1_Y_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_ALIGN 0 +#define MISC1_Y_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_BITS 1 +#define MISC1_Y_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_SHIFT 11 + +/* MISC1 :: Y_RX_ERROR_STATUS :: RX_L0_OVERRUN_ERROR [10:10] */ +#define MISC1_Y_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_MASK 0x00000400 +#define MISC1_Y_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_ALIGN 0 +#define MISC1_Y_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_BITS 1 +#define MISC1_Y_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_SHIFT 10 + +/* MISC1 :: Y_RX_ERROR_STATUS :: RX_L1_DESC_TX_ABORT_ERRORS [09:09] */ +#define MISC1_Y_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_MASK 0x00000200 +#define MISC1_Y_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_ALIGN 0 +#define MISC1_Y_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_BITS 1 +#define MISC1_Y_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_SHIFT 9 + +/* MISC1 :: Y_RX_ERROR_STATUS :: reserved1 [08:08] */ +#define MISC1_Y_RX_ERROR_STATUS_reserved1_MASK 0x00000100 +#define MISC1_Y_RX_ERROR_STATUS_reserved1_ALIGN 0 +#define MISC1_Y_RX_ERROR_STATUS_reserved1_BITS 1 +#define MISC1_Y_RX_ERROR_STATUS_reserved1_SHIFT 8 + +/* MISC1 :: Y_RX_ERROR_STATUS :: RX_L0_DESC_TX_ABORT_ERRORS [07:07] */ +#define MISC1_Y_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_MASK 0x00000080 +#define MISC1_Y_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_ALIGN 0 +#define MISC1_Y_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_BITS 1 +#define MISC1_Y_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_SHIFT 7 + +/* MISC1 :: Y_RX_ERROR_STATUS :: reserved2 [06:05] */ +#define MISC1_Y_RX_ERROR_STATUS_reserved2_MASK 0x00000060 +#define MISC1_Y_RX_ERROR_STATUS_reserved2_ALIGN 0 +#define MISC1_Y_RX_ERROR_STATUS_reserved2_BITS 2 +#define MISC1_Y_RX_ERROR_STATUS_reserved2_SHIFT 5 + +/* MISC1 :: Y_RX_ERROR_STATUS :: RX_L1_FIFO_FULL_ERRORS [04:04] */ +#define MISC1_Y_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_MASK 0x00000010 +#define MISC1_Y_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_ALIGN 0 +#define MISC1_Y_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_BITS 1 +#define MISC1_Y_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_SHIFT 4 + +/* MISC1 :: Y_RX_ERROR_STATUS :: reserved3 [03:02] */ +#define MISC1_Y_RX_ERROR_STATUS_reserved3_MASK 0x0000000c +#define MISC1_Y_RX_ERROR_STATUS_reserved3_ALIGN 0 +#define MISC1_Y_RX_ERROR_STATUS_reserved3_BITS 2 +#define MISC1_Y_RX_ERROR_STATUS_reserved3_SHIFT 2 + +/* MISC1 :: Y_RX_ERROR_STATUS :: RX_L0_FIFO_FULL_ERRORS [01:01] */ +#define MISC1_Y_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_MASK 0x00000002 +#define MISC1_Y_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_ALIGN 0 +#define MISC1_Y_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_BITS 1 +#define MISC1_Y_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_SHIFT 1 + +/* MISC1 :: Y_RX_ERROR_STATUS :: reserved4 [00:00] */ +#define MISC1_Y_RX_ERROR_STATUS_reserved4_MASK 0x00000001 +#define MISC1_Y_RX_ERROR_STATUS_reserved4_ALIGN 0 +#define MISC1_Y_RX_ERROR_STATUS_reserved4_BITS 1 +#define MISC1_Y_RX_ERROR_STATUS_reserved4_SHIFT 0 + + +/**************************************************************************** + * MISC1 :: UV_RX_ERROR_STATUS + ***************************************************************************/ +/* MISC1 :: UV_RX_ERROR_STATUS :: reserved0 [31:14] */ +#define MISC1_UV_RX_ERROR_STATUS_reserved0_MASK 0xffffc000 +#define MISC1_UV_RX_ERROR_STATUS_reserved0_ALIGN 0 +#define MISC1_UV_RX_ERROR_STATUS_reserved0_BITS 18 +#define MISC1_UV_RX_ERROR_STATUS_reserved0_SHIFT 14 + +/* MISC1 :: UV_RX_ERROR_STATUS :: RX_L1_UNDERRUN_ERROR [13:13] */ +#define MISC1_UV_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_MASK 0x00002000 +#define MISC1_UV_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_ALIGN 0 +#define MISC1_UV_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_BITS 1 +#define MISC1_UV_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_SHIFT 13 + +/* MISC1 :: UV_RX_ERROR_STATUS :: RX_L1_OVERRUN_ERROR [12:12] */ +#define MISC1_UV_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_MASK 0x00001000 +#define MISC1_UV_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_ALIGN 0 +#define MISC1_UV_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_BITS 1 +#define MISC1_UV_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_SHIFT 12 + +/* MISC1 :: UV_RX_ERROR_STATUS :: RX_L0_UNDERRUN_ERROR [11:11] */ +#define MISC1_UV_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_MASK 0x00000800 +#define MISC1_UV_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_ALIGN 0 +#define MISC1_UV_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_BITS 1 +#define MISC1_UV_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_SHIFT 11 + +/* MISC1 :: UV_RX_ERROR_STATUS :: RX_L0_OVERRUN_ERROR [10:10] */ +#define MISC1_UV_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_MASK 0x00000400 +#define MISC1_UV_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_ALIGN 0 +#define MISC1_UV_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_BITS 1 +#define MISC1_UV_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_SHIFT 10 + +/* MISC1 :: UV_RX_ERROR_STATUS :: RX_L1_DESC_TX_ABORT_ERRORS [09:09] */ +#define MISC1_UV_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_MASK 0x00000200 +#define MISC1_UV_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_ALIGN 0 +#define MISC1_UV_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_BITS 1 +#define MISC1_UV_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_SHIFT 9 + +/* MISC1 :: UV_RX_ERROR_STATUS :: reserved1 [08:08] */ +#define MISC1_UV_RX_ERROR_STATUS_reserved1_MASK 0x00000100 +#define MISC1_UV_RX_ERROR_STATUS_reserved1_ALIGN 0 +#define MISC1_UV_RX_ERROR_STATUS_reserved1_BITS 1 +#define MISC1_UV_RX_ERROR_STATUS_reserved1_SHIFT 8 + +/* MISC1 :: UV_RX_ERROR_STATUS :: RX_L0_DESC_TX_ABORT_ERRORS [07:07] */ +#define MISC1_UV_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_MASK 0x00000080 +#define MISC1_UV_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_ALIGN 0 +#define MISC1_UV_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_BITS 1 +#define MISC1_UV_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_SHIFT 7 + +/* MISC1 :: UV_RX_ERROR_STATUS :: reserved2 [06:05] */ +#define MISC1_UV_RX_ERROR_STATUS_reserved2_MASK 0x00000060 +#define MISC1_UV_RX_ERROR_STATUS_reserved2_ALIGN 0 +#define MISC1_UV_RX_ERROR_STATUS_reserved2_BITS 2 +#define MISC1_UV_RX_ERROR_STATUS_reserved2_SHIFT 5 + +/* MISC1 :: UV_RX_ERROR_STATUS :: RX_L1_FIFO_FULL_ERRORS [04:04] */ +#define MISC1_UV_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_MASK 0x00000010 +#define MISC1_UV_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_ALIGN 0 +#define MISC1_UV_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_BITS 1 +#define MISC1_UV_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_SHIFT 4 + +/* MISC1 :: UV_RX_ERROR_STATUS :: reserved3 [03:02] */ +#define MISC1_UV_RX_ERROR_STATUS_reserved3_MASK 0x0000000c +#define MISC1_UV_RX_ERROR_STATUS_reserved3_ALIGN 0 +#define MISC1_UV_RX_ERROR_STATUS_reserved3_BITS 2 +#define MISC1_UV_RX_ERROR_STATUS_reserved3_SHIFT 2 + +/* MISC1 :: UV_RX_ERROR_STATUS :: RX_L0_FIFO_FULL_ERRORS [01:01] */ +#define MISC1_UV_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_MASK 0x00000002 +#define MISC1_UV_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_ALIGN 0 +#define MISC1_UV_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_BITS 1 +#define MISC1_UV_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_SHIFT 1 + +/* MISC1 :: UV_RX_ERROR_STATUS :: reserved4 [00:00] */ +#define MISC1_UV_RX_ERROR_STATUS_reserved4_MASK 0x00000001 +#define MISC1_UV_RX_ERROR_STATUS_reserved4_ALIGN 0 +#define MISC1_UV_RX_ERROR_STATUS_reserved4_BITS 1 +#define MISC1_UV_RX_ERROR_STATUS_reserved4_SHIFT 0 + +/**************************************************************************** + * Datatype Definitions. + ***************************************************************************/ +#endif /* #ifndef MACFILE_H__ */ + +/* End of File */ + diff --git a/drivers/staging/crystalhd/crystalhd_cmds.c b/drivers/staging/crystalhd/crystalhd_cmds.c new file mode 100644 index 0000000..26145a8 --- /dev/null +++ b/drivers/staging/crystalhd/crystalhd_cmds.c @@ -0,0 +1,1058 @@ +/*************************************************************************** + * Copyright (c) 2005-2009, Broadcom Corporation. + * + * Name: crystalhd_cmds . c + * + * Description: + * BCM70010 Linux driver user command interfaces. + * + * HISTORY: + * + ********************************************************************** + * This file is part of the crystalhd device driver. + * + * This driver is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This driver is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this driver. If not, see <http://www.gnu.org/licenses/>. + **********************************************************************/ + +#include "crystalhd_cmds.h" +#include "crystalhd_hw.h" + +static struct crystalhd_user *bc_cproc_get_uid(struct crystalhd_cmd *ctx) +{ + struct crystalhd_user *user = NULL; + int i; + + for (i = 0; i < BC_LINK_MAX_OPENS; i++) { + if (!ctx->user[i].in_use) { + user = &ctx->user[i]; + break; + } + } + + return user; +} + +static int bc_cproc_get_user_count(struct crystalhd_cmd *ctx) +{ + int i, count = 0; + + for (i = 0; i < BC_LINK_MAX_OPENS; i++) { + if (ctx->user[i].in_use) + count++; + } + + return count; +} + +static void bc_cproc_mark_pwr_state(struct crystalhd_cmd *ctx) +{ + int i; + + for (i = 0; i < BC_LINK_MAX_OPENS; i++) { + if (!ctx->user[i].in_use) + continue; + if (ctx->user[i].mode == DTS_DIAG_MODE || + ctx->user[i].mode == DTS_PLAYBACK_MODE) { + ctx->pwr_state_change = 1; + break; + } + } +} + +static BC_STATUS bc_cproc_notify_mode(struct crystalhd_cmd *ctx, + crystalhd_ioctl_data *idata) +{ + int rc = 0, i = 0; + + if (!ctx || !idata) { + BCMLOG_ERR("Invalid Arg!!\n"); + return BC_STS_INV_ARG; + } + + if (ctx->user[idata->u_id].mode != DTS_MODE_INV) { + BCMLOG_ERR("Close the handle first..\n"); + return BC_STS_ERR_USAGE; + } + if (idata->udata.u.NotifyMode.Mode == DTS_MONITOR_MODE) { + ctx->user[idata->u_id].mode = idata->udata.u.NotifyMode.Mode; + return BC_STS_SUCCESS; + } + if (ctx->state != BC_LINK_INVALID) { + BCMLOG_ERR("Link invalid state %d \n", ctx->state); + return BC_STS_ERR_USAGE; + } + /* Check for duplicate playback sessions..*/ + for (i = 0; i < BC_LINK_MAX_OPENS; i++) { + if (ctx->user[i].mode == DTS_DIAG_MODE || + ctx->user[i].mode == DTS_PLAYBACK_MODE) { + BCMLOG_ERR("multiple playback sessions are not " + "supported..\n"); + return BC_STS_ERR_USAGE; + } + } + ctx->cin_wait_exit = 0; + ctx->user[idata->u_id].mode = idata->udata.u.NotifyMode.Mode; + /* Setup mmap pool for uaddr sgl mapping..*/ + rc = crystalhd_create_dio_pool(ctx->adp, BC_LINK_MAX_SGLS); + if (rc) + return BC_STS_ERROR; + + /* Setup Hardware DMA rings */ + return crystalhd_hw_setup_dma_rings(&ctx->hw_ctx); +} + +static BC_STATUS bc_cproc_get_version(struct crystalhd_cmd *ctx, + crystalhd_ioctl_data *idata) +{ + + if (!ctx || !idata) { + BCMLOG_ERR("Invalid Arg!!\n"); + return BC_STS_INV_ARG; + } + idata->udata.u.VerInfo.DriverMajor = crystalhd_kmod_major; + idata->udata.u.VerInfo.DriverMinor = crystalhd_kmod_minor; + idata->udata.u.VerInfo.DriverRevision = crystalhd_kmod_rev; + return BC_STS_SUCCESS; +} + + +static BC_STATUS bc_cproc_get_hwtype(struct crystalhd_cmd *ctx, crystalhd_ioctl_data *idata) +{ + if (!ctx || !idata) { + BCMLOG_ERR("Invalid Arg!!\n"); + return BC_STS_INV_ARG; + } + + crystalhd_pci_cfg_rd(ctx->adp, 0, 2, + (uint32_t *)&idata->udata.u.hwType.PciVenId); + crystalhd_pci_cfg_rd(ctx->adp, 2, 2, + (uint32_t *)&idata->udata.u.hwType.PciDevId); + crystalhd_pci_cfg_rd(ctx->adp, 8, 1, + (uint32_t *)&idata->udata.u.hwType.HwRev); + + return BC_STS_SUCCESS; +} + +static BC_STATUS bc_cproc_reg_rd(struct crystalhd_cmd *ctx, + crystalhd_ioctl_data *idata) +{ + if (!ctx || !idata) + return BC_STS_INV_ARG; + idata->udata.u.regAcc.Value = bc_dec_reg_rd(ctx->adp, + idata->udata.u.regAcc.Offset); + return BC_STS_SUCCESS; +} + +static BC_STATUS bc_cproc_reg_wr(struct crystalhd_cmd *ctx, + crystalhd_ioctl_data *idata) +{ + if (!ctx || !idata) + return BC_STS_INV_ARG; + + bc_dec_reg_wr(ctx->adp, idata->udata.u.regAcc.Offset, + idata->udata.u.regAcc.Value); + + return BC_STS_SUCCESS; +} + +static BC_STATUS bc_cproc_link_reg_rd(struct crystalhd_cmd *ctx, + crystalhd_ioctl_data *idata) +{ + if (!ctx || !idata) + return BC_STS_INV_ARG; + + idata->udata.u.regAcc.Value = crystalhd_reg_rd(ctx->adp, + idata->udata.u.regAcc.Offset); + return BC_STS_SUCCESS; +} + +static BC_STATUS bc_cproc_link_reg_wr(struct crystalhd_cmd *ctx, + crystalhd_ioctl_data *idata) +{ + if (!ctx || !idata) + return BC_STS_INV_ARG; + + crystalhd_reg_wr(ctx->adp, idata->udata.u.regAcc.Offset, + idata->udata.u.regAcc.Value); + + return BC_STS_SUCCESS; +} + +static BC_STATUS bc_cproc_mem_rd(struct crystalhd_cmd *ctx, + crystalhd_ioctl_data *idata) +{ + BC_STATUS sts = BC_STS_SUCCESS; + + if (!ctx || !idata || !idata->add_cdata) + return BC_STS_INV_ARG; + + if (idata->udata.u.devMem.NumDwords > (idata->add_cdata_sz / 4)) { + BCMLOG_ERR("insufficient buffer\n"); + return BC_STS_INV_ARG; + } + sts = crystalhd_mem_rd(ctx->adp, idata->udata.u.devMem.StartOff, + idata->udata.u.devMem.NumDwords, + (uint32_t *)idata->add_cdata); + return sts; + +} + +static BC_STATUS bc_cproc_mem_wr(struct crystalhd_cmd *ctx, + crystalhd_ioctl_data *idata) +{ + BC_STATUS sts = BC_STS_SUCCESS; + + if (!ctx || !idata || !idata->add_cdata) + return BC_STS_INV_ARG; + + if (idata->udata.u.devMem.NumDwords > (idata->add_cdata_sz / 4)) { + BCMLOG_ERR("insufficient buffer\n"); + return BC_STS_INV_ARG; + } + + sts = crystalhd_mem_wr(ctx->adp, idata->udata.u.devMem.StartOff, + idata->udata.u.devMem.NumDwords, + (uint32_t *)idata->add_cdata); + return sts; +} + +static BC_STATUS bc_cproc_cfg_rd(struct crystalhd_cmd *ctx, + crystalhd_ioctl_data *idata) +{ + uint32_t ix, cnt, off, len; + BC_STATUS sts = BC_STS_SUCCESS; + uint32_t *temp; + + if (!ctx || !idata) + return BC_STS_INV_ARG; + + temp = (uint32_t *) idata->udata.u.pciCfg.pci_cfg_space; + off = idata->udata.u.pciCfg.Offset; + len = idata->udata.u.pciCfg.Size; + + if (len <= 4) + return crystalhd_pci_cfg_rd(ctx->adp, off, len, temp); + + /* Truncate to dword alignment..*/ + len = 4; + cnt = idata->udata.u.pciCfg.Size / len; + for (ix = 0; ix < cnt; ix++) { + sts = crystalhd_pci_cfg_rd(ctx->adp, off, len, &temp[ix]); + if (sts != BC_STS_SUCCESS) { + BCMLOG_ERR("config read : %d\n", sts); + return sts; + } + off += len; + } + + return sts; +} + +static BC_STATUS bc_cproc_cfg_wr(struct crystalhd_cmd *ctx, + crystalhd_ioctl_data *idata) +{ + uint32_t ix, cnt, off, len; + BC_STATUS sts = BC_STS_SUCCESS; + uint32_t *temp; + + if (!ctx || !idata) + return BC_STS_INV_ARG; + + temp = (uint32_t *) idata->udata.u.pciCfg.pci_cfg_space; + off = idata->udata.u.pciCfg.Offset; + len = idata->udata.u.pciCfg.Size; + + if (len <= 4) + return crystalhd_pci_cfg_wr(ctx->adp, off, len, temp[0]); + + /* Truncate to dword alignment..*/ + len = 4; + cnt = idata->udata.u.pciCfg.Size / len; + for (ix = 0; ix < cnt; ix++) { + sts = crystalhd_pci_cfg_wr(ctx->adp, off, len, temp[ix]); + if (sts != BC_STS_SUCCESS) { + BCMLOG_ERR("config write : %d\n", sts); + return sts; + } + off += len; + } + + return sts; +} + +static BC_STATUS bc_cproc_download_fw(struct crystalhd_cmd *ctx, + crystalhd_ioctl_data *idata) +{ + BC_STATUS sts = BC_STS_SUCCESS; + + if (!ctx || !idata || !idata->add_cdata || !idata->add_cdata_sz) { + BCMLOG_ERR("Invalid Arg!!\n"); + return BC_STS_INV_ARG; + } + + if (ctx->state != BC_LINK_INVALID) { + BCMLOG_ERR("Link invalid state %d \n", ctx->state); + return BC_STS_ERR_USAGE; + } + + sts = crystalhd_download_fw(ctx->adp, (uint8_t *)idata->add_cdata, + idata->add_cdata_sz); + + if (sts != BC_STS_SUCCESS) { + BCMLOG_ERR("Firmware Download Failure!! - %d\n", sts); + } else + ctx->state |= BC_LINK_INIT; + + return sts; +} + +/* + * We use the FW_CMD interface to sync up playback state with application + * and firmware. This function will perform the required pre and post + * processing of the Firmware commands. + * + * Pause - + * Disable capture after decoder pause. + * Resume - + * First enable capture and issue decoder resume command. + * Flush - + * Abort pending input transfers and issue decoder flush command. + * + */ +static BC_STATUS bc_cproc_do_fw_cmd(struct crystalhd_cmd *ctx, crystalhd_ioctl_data *idata) +{ + BC_STATUS sts; + uint32_t *cmd; + + if (!(ctx->state & BC_LINK_INIT)) { + BCMLOG_ERR("Link invalid state %d \n", ctx->state); + return BC_STS_ERR_USAGE; + } + + cmd = idata->udata.u.fwCmd.cmd; + + /* Pre-Process */ + if (cmd[0] == eCMD_C011_DEC_CHAN_PAUSE) { + if (!cmd[3]) { + ctx->state &= ~BC_LINK_PAUSED; + crystalhd_hw_unpause(&ctx->hw_ctx); + } + } else if (cmd[0] == eCMD_C011_DEC_CHAN_FLUSH) { + BCMLOG(BCMLOG_INFO, "Flush issued\n"); + if (cmd[3]) + ctx->cin_wait_exit = 1; + } + + sts = crystalhd_do_fw_cmd(&ctx->hw_ctx, &idata->udata.u.fwCmd); + + if (sts != BC_STS_SUCCESS) { + BCMLOG(BCMLOG_INFO, "fw cmd %x failed\n", cmd[0]); + return sts; + } + + /* Post-Process */ + if (cmd[0] == eCMD_C011_DEC_CHAN_PAUSE) { + if (cmd[3]) { + ctx->state |= BC_LINK_PAUSED; + crystalhd_hw_pause(&ctx->hw_ctx); + } + } + + return sts; +} + +static void bc_proc_in_completion(crystalhd_dio_req *dio_hnd, + wait_queue_head_t *event, BC_STATUS sts) +{ + if (!dio_hnd || !event) { + BCMLOG_ERR("Invalid Arg!!\n"); + return; + } + if (sts == BC_STS_IO_USER_ABORT) + return; + + dio_hnd->uinfo.comp_sts = sts; + dio_hnd->uinfo.ev_sts = 1; + crystalhd_set_event(event); +} + +static BC_STATUS bc_cproc_codein_sleep(struct crystalhd_cmd *ctx) +{ + wait_queue_head_t sleep_ev; + int rc = 0; + + if (ctx->state & BC_LINK_SUSPEND) + return BC_STS_IO_USER_ABORT; + + if (ctx->cin_wait_exit) { + ctx->cin_wait_exit = 0; + return BC_STS_CMD_CANCELLED; + } + crystalhd_create_event(&sleep_ev); + crystalhd_wait_on_event(&sleep_ev, 0, 100, rc, 0); + if (rc == -EINTR) + return BC_STS_IO_USER_ABORT; + + return BC_STS_SUCCESS; +} + +static BC_STATUS bc_cproc_hw_txdma(struct crystalhd_cmd *ctx, + crystalhd_ioctl_data *idata, + crystalhd_dio_req *dio) +{ + uint32_t tx_listid = 0; + BC_STATUS sts = BC_STS_SUCCESS; + wait_queue_head_t event; + int rc = 0; + + if (!ctx || !idata || !dio) { + BCMLOG_ERR("Invalid Arg!!\n"); + return BC_STS_INV_ARG; + } + + crystalhd_create_event(&event); + + ctx->tx_list_id = 0; + /* msleep_interruptible(2000); */ + sts = crystalhd_hw_post_tx(&ctx->hw_ctx, dio, bc_proc_in_completion, + &event, &tx_listid, + idata->udata.u.ProcInput.Encrypted); + + while (sts == BC_STS_BUSY) { + sts = bc_cproc_codein_sleep(ctx); + if (sts != BC_STS_SUCCESS) + break; + sts = crystalhd_hw_post_tx(&ctx->hw_ctx, dio, + bc_proc_in_completion, + &event, &tx_listid, + idata->udata.u.ProcInput.Encrypted); + } + if (sts != BC_STS_SUCCESS) { + BCMLOG(BCMLOG_DBG, "_hw_txdma returning sts:%d\n", sts); + return sts; + } + if (ctx->cin_wait_exit) + ctx->cin_wait_exit = 0; + + ctx->tx_list_id = tx_listid; + + /* _post() succeeded.. wait for the completion. */ + crystalhd_wait_on_event(&event, (dio->uinfo.ev_sts), 3000, rc, 0); + ctx->tx_list_id = 0; + if (!rc) { + return dio->uinfo.comp_sts; + } else if (rc == -EBUSY) { + BCMLOG(BCMLOG_DBG, "_tx_post() T/O \n"); + sts = BC_STS_TIMEOUT; + } else if (rc == -EINTR) { + BCMLOG(BCMLOG_DBG, "Tx Wait Signal int.\n"); + sts = BC_STS_IO_USER_ABORT; + } else { + sts = BC_STS_IO_ERROR; + } + + /* We are cancelling the IO from the same context as the _post(). + * so no need to wait on the event again.. the return itself + * ensures the release of our resources. + */ + crystalhd_hw_cancel_tx(&ctx->hw_ctx, tx_listid); + + return sts; +} + +/* Helper function to check on user buffers */ +static BC_STATUS bc_cproc_check_inbuffs(bool pin, void *ubuff, uint32_t ub_sz, + uint32_t uv_off, bool en_422) +{ + if (!ubuff || !ub_sz) { + BCMLOG_ERR("%s->Invalid Arg %p %x\n", + ((pin) ? "TX" : "RX"), ubuff, ub_sz); + return BC_STS_INV_ARG; + } + + /* Check for alignment */ + if (((uintptr_t)ubuff) & 0x03) { + BCMLOG_ERR("%s-->Un-aligned address not implemented yet.. %p \n", + ((pin) ? "TX" : "RX"), ubuff); + return BC_STS_NOT_IMPL; + } + if (pin) + return BC_STS_SUCCESS; + + if (!en_422 && !uv_off) { + BCMLOG_ERR("Need UV offset for 420 mode.\n"); + return BC_STS_INV_ARG; + } + + if (en_422 && uv_off) { + BCMLOG_ERR("UV offset in 422 mode ??\n"); + return BC_STS_INV_ARG; + } + + return BC_STS_SUCCESS; +} + +static BC_STATUS bc_cproc_proc_input(struct crystalhd_cmd *ctx, crystalhd_ioctl_data *idata) +{ + void *ubuff; + uint32_t ub_sz; + crystalhd_dio_req *dio_hnd = NULL; + BC_STATUS sts = BC_STS_SUCCESS; + + if (!ctx || !idata) { + BCMLOG_ERR("Invalid Arg!!\n"); + return BC_STS_INV_ARG; + } + + ubuff = idata->udata.u.ProcInput.pDmaBuff; + ub_sz = idata->udata.u.ProcInput.BuffSz; + + sts = bc_cproc_check_inbuffs(1, ubuff, ub_sz, 0, 0); + if (sts != BC_STS_SUCCESS) + return sts; + + sts = crystalhd_map_dio(ctx->adp, ubuff, ub_sz, 0, 0, 1, &dio_hnd); + if (sts != BC_STS_SUCCESS) { + BCMLOG_ERR("dio map - %d \n", sts); + return sts; + } + + if (!dio_hnd) + return BC_STS_ERROR; + + sts = bc_cproc_hw_txdma(ctx, idata, dio_hnd); + + crystalhd_unmap_dio(ctx->adp, dio_hnd); + + return sts; +} + +static BC_STATUS bc_cproc_add_cap_buff(struct crystalhd_cmd *ctx, + crystalhd_ioctl_data *idata) +{ + void *ubuff; + uint32_t ub_sz, uv_off; + bool en_422; + crystalhd_dio_req *dio_hnd = NULL; + BC_STATUS sts = BC_STS_SUCCESS; + + if (!ctx || !idata) { + BCMLOG_ERR("Invalid Arg!!\n"); + return BC_STS_INV_ARG; + } + + ubuff = idata->udata.u.RxBuffs.YuvBuff; + ub_sz = idata->udata.u.RxBuffs.YuvBuffSz; + uv_off = idata->udata.u.RxBuffs.UVbuffOffset; + en_422 = idata->udata.u.RxBuffs.b422Mode; + + sts = bc_cproc_check_inbuffs(0, ubuff, ub_sz, uv_off, en_422); + if (sts != BC_STS_SUCCESS) + return sts; + + sts = crystalhd_map_dio(ctx->adp, ubuff, ub_sz, uv_off, + en_422, 0, &dio_hnd); + if (sts != BC_STS_SUCCESS) { + BCMLOG_ERR("dio map - %d \n", sts); + return sts; + } + + if (!dio_hnd) + return BC_STS_ERROR; + + sts = crystalhd_hw_add_cap_buffer(&ctx->hw_ctx, dio_hnd, (ctx->state == BC_LINK_READY)); + if ((sts != BC_STS_SUCCESS) && (sts != BC_STS_BUSY)) { + crystalhd_unmap_dio(ctx->adp, dio_hnd); + return sts; + } + + return BC_STS_SUCCESS; +} + +static BC_STATUS bc_cproc_fmt_change(struct crystalhd_cmd *ctx, + crystalhd_dio_req *dio) +{ + BC_STATUS sts = BC_STS_SUCCESS; + + sts = crystalhd_hw_add_cap_buffer(&ctx->hw_ctx, dio, 0); + if (sts != BC_STS_SUCCESS) + return sts; + + ctx->state |= BC_LINK_FMT_CHG; + if (ctx->state == BC_LINK_READY) + sts = crystalhd_hw_start_capture(&ctx->hw_ctx); + + return sts; +} + +static BC_STATUS bc_cproc_fetch_frame(struct crystalhd_cmd *ctx, + crystalhd_ioctl_data *idata) +{ + crystalhd_dio_req *dio = NULL; + BC_STATUS sts = BC_STS_SUCCESS; + BC_DEC_OUT_BUFF *frame; + + if (!ctx || !idata) { + BCMLOG_ERR("Invalid Arg!!\n"); + return BC_STS_INV_ARG; + } + + if (!(ctx->state & BC_LINK_CAP_EN)) { + BCMLOG(BCMLOG_DBG, "Capture not enabled..%x\n", ctx->state); + return BC_STS_ERR_USAGE; + } + + frame = &idata->udata.u.DecOutData; + + sts = crystalhd_hw_get_cap_buffer(&ctx->hw_ctx, &frame->PibInfo, &dio); + if (sts != BC_STS_SUCCESS) + return (ctx->state & BC_LINK_SUSPEND) ? BC_STS_IO_USER_ABORT : sts; + + frame->Flags = dio->uinfo.comp_flags; + + if (frame->Flags & COMP_FLAG_FMT_CHANGE) + return bc_cproc_fmt_change(ctx, dio); + + frame->OutPutBuffs.YuvBuff = dio->uinfo.xfr_buff; + frame->OutPutBuffs.YuvBuffSz = dio->uinfo.xfr_len; + frame->OutPutBuffs.UVbuffOffset = dio->uinfo.uv_offset; + frame->OutPutBuffs.b422Mode = dio->uinfo.b422mode; + + frame->OutPutBuffs.YBuffDoneSz = dio->uinfo.y_done_sz; + frame->OutPutBuffs.UVBuffDoneSz = dio->uinfo.uv_done_sz; + + crystalhd_unmap_dio(ctx->adp, dio); + + return BC_STS_SUCCESS; +} + +static BC_STATUS bc_cproc_start_capture(struct crystalhd_cmd *ctx, + crystalhd_ioctl_data *idata) +{ + ctx->state |= BC_LINK_CAP_EN; + if (ctx->state == BC_LINK_READY) + return crystalhd_hw_start_capture(&ctx->hw_ctx); + + return BC_STS_SUCCESS; +} + +static BC_STATUS bc_cproc_flush_cap_buffs(struct crystalhd_cmd *ctx, + crystalhd_ioctl_data *idata) +{ + crystalhd_dio_req *dio = NULL; + BC_STATUS sts = BC_STS_SUCCESS; + BC_DEC_OUT_BUFF *frame; + uint32_t count; + + if (!ctx || !idata) { + BCMLOG_ERR("Invalid Arg!!\n"); + return BC_STS_INV_ARG; + } + + if (!(ctx->state & BC_LINK_CAP_EN)) + return BC_STS_ERR_USAGE; + + /* We should ack flush even when we are in paused/suspend state */ + if (!(ctx->state & BC_LINK_READY)) + return crystalhd_hw_stop_capture(&ctx->hw_ctx); + + ctx->state &= ~(BC_LINK_CAP_EN|BC_LINK_FMT_CHG); + + frame = &idata->udata.u.DecOutData; + for (count = 0; count < BC_RX_LIST_CNT; count++) { + + sts = crystalhd_hw_get_cap_buffer(&ctx->hw_ctx, &frame->PibInfo, &dio); + if (sts != BC_STS_SUCCESS) + break; + + crystalhd_unmap_dio(ctx->adp, dio); + } + + return crystalhd_hw_stop_capture(&ctx->hw_ctx); +} + +static BC_STATUS bc_cproc_get_stats(struct crystalhd_cmd *ctx, + crystalhd_ioctl_data *idata) +{ + BC_DTS_STATS *stats; + struct crystalhd_hw_stats hw_stats; + + if (!ctx || !idata) { + BCMLOG_ERR("Invalid Arg!!\n"); + return BC_STS_INV_ARG; + } + + crystalhd_hw_stats(&ctx->hw_ctx, &hw_stats); + + stats = &idata->udata.u.drvStat; + stats->drvRLL = hw_stats.rdyq_count; + stats->drvFLL = hw_stats.freeq_count; + stats->DrvTotalFrmDropped = hw_stats.rx_errors; + stats->DrvTotalHWErrs = hw_stats.rx_errors + hw_stats.tx_errors; + stats->intCount = hw_stats.num_interrupts; + stats->DrvIgnIntrCnt = hw_stats.num_interrupts - + hw_stats.dev_interrupts; + stats->TxFifoBsyCnt = hw_stats.cin_busy; + stats->pauseCount = hw_stats.pause_cnt; + + if (ctx->pwr_state_change) + stats->pwr_state_change = 1; + if (ctx->state & BC_LINK_PAUSED) + stats->DrvPauseTime = 1; + + return BC_STS_SUCCESS; +} + +static BC_STATUS bc_cproc_reset_stats(struct crystalhd_cmd *ctx, + crystalhd_ioctl_data *idata) +{ + crystalhd_hw_stats(&ctx->hw_ctx, NULL); + + return BC_STS_SUCCESS; +} + +static BC_STATUS bc_cproc_chg_clk(struct crystalhd_cmd *ctx, + crystalhd_ioctl_data *idata) +{ + BC_CLOCK *clock; + uint32_t oldClk; + BC_STATUS sts = BC_STS_SUCCESS; + + if (!ctx || !idata) { + BCMLOG_ERR("Invalid Arg!!\n"); + return BC_STS_INV_ARG; + } + + clock = &idata->udata.u.clockValue; + oldClk = ctx->hw_ctx.core_clock_mhz; + ctx->hw_ctx.core_clock_mhz = clock->clk; + + if (ctx->state & BC_LINK_READY) { + sts = crystalhd_hw_set_core_clock(&ctx->hw_ctx); + if (sts == BC_STS_CLK_NOCHG) + ctx->hw_ctx.core_clock_mhz = oldClk; + } + + clock->clk = ctx->hw_ctx.core_clock_mhz; + + return sts; +} + +/*=============== Cmd Proc Table.. ======================================*/ +static const crystalhd_cmd_tbl_t g_crystalhd_cproc_tbl[] = { + { BCM_IOC_GET_VERSION, bc_cproc_get_version, 0}, + { BCM_IOC_GET_HWTYPE, bc_cproc_get_hwtype, 0}, + { BCM_IOC_REG_RD, bc_cproc_reg_rd, 0}, + { BCM_IOC_REG_WR, bc_cproc_reg_wr, 0}, + { BCM_IOC_FPGA_RD, bc_cproc_link_reg_rd, 0}, + { BCM_IOC_FPGA_WR, bc_cproc_link_reg_wr, 0}, + { BCM_IOC_MEM_RD, bc_cproc_mem_rd, 0}, + { BCM_IOC_MEM_WR, bc_cproc_mem_wr, 0}, + { BCM_IOC_RD_PCI_CFG, bc_cproc_cfg_rd, 0}, + { BCM_IOC_WR_PCI_CFG, bc_cproc_cfg_wr, 1}, + { BCM_IOC_FW_DOWNLOAD, bc_cproc_download_fw, 1}, + { BCM_IOC_FW_CMD, bc_cproc_do_fw_cmd, 1}, + { BCM_IOC_PROC_INPUT, bc_cproc_proc_input, 1}, + { BCM_IOC_ADD_RXBUFFS, bc_cproc_add_cap_buff, 1}, + { BCM_IOC_FETCH_RXBUFF, bc_cproc_fetch_frame, 1}, + { BCM_IOC_START_RX_CAP, bc_cproc_start_capture, 1}, + { BCM_IOC_FLUSH_RX_CAP, bc_cproc_flush_cap_buffs, 1}, + { BCM_IOC_GET_DRV_STAT, bc_cproc_get_stats, 0}, + { BCM_IOC_RST_DRV_STAT, bc_cproc_reset_stats, 0}, + { BCM_IOC_NOTIFY_MODE, bc_cproc_notify_mode, 0}, + { BCM_IOC_CHG_CLK, bc_cproc_chg_clk, 0}, + { BCM_IOC_END, NULL}, +}; + +/*=============== Cmd Proc Functions.. ===================================*/ + +/** + * crystalhd_suspend - Power management suspend request. + * @ctx: Command layer context. + * @idata: Iodata - required for internal use. + * + * Return: + * status + * + * 1. Set the state to Suspend. + * 2. Flush the Rx Buffers it will unmap all the buffers and + * stop the RxDMA engine. + * 3. Cancel The TX Io and Stop Dma Engine. + * 4. Put the DDR in to deep sleep. + * 5. Stop the hardware putting it in to Reset State. + * + * Current gstreamer frame work does not provide any power management + * related notification to user mode decoder plug-in. As a work-around + * we pass on the power mangement notification to our plug-in by completing + * all outstanding requests with BC_STS_IO_USER_ABORT return code. + */ +BC_STATUS crystalhd_suspend(struct crystalhd_cmd *ctx, crystalhd_ioctl_data *idata) +{ + BC_STATUS sts = BC_STS_SUCCESS; + + if (!ctx || !idata) { + BCMLOG_ERR("Invalid Parameters\n"); + return BC_STS_ERROR; + } + + if (ctx->state & BC_LINK_SUSPEND) + return BC_STS_SUCCESS; + + if (ctx->state == BC_LINK_INVALID) { + BCMLOG(BCMLOG_DBG, "Nothing To Do Suspend Success\n"); + return BC_STS_SUCCESS; + } + + ctx->state |= BC_LINK_SUSPEND; + + bc_cproc_mark_pwr_state(ctx); + + if (ctx->state & BC_LINK_CAP_EN) { + sts = bc_cproc_flush_cap_buffs(ctx, idata); + if (sts != BC_STS_SUCCESS) + return sts; + } + + if (ctx->tx_list_id) { + sts = crystalhd_hw_cancel_tx(&ctx->hw_ctx, ctx->tx_list_id); + if (sts != BC_STS_SUCCESS) + return sts; + } + + sts = crystalhd_hw_suspend(&ctx->hw_ctx); + if (sts != BC_STS_SUCCESS) + return sts; + + BCMLOG(BCMLOG_DBG, "BCM70012 suspend success\n"); + + return BC_STS_SUCCESS; +} + +/** + * crystalhd_resume - Resume frame capture. + * @ctx: Command layer contextx. + * + * Return: + * status + * + * + * Resume frame capture. + * + * PM_Resume can't resume the playback state back to pre-suspend state + * because we don't keep video clip related information within driver. + * To get back to the pre-suspend state App will re-open the device and + * start a new playback session from the pre-suspend clip position. + * + */ +BC_STATUS crystalhd_resume(struct crystalhd_cmd *ctx) +{ + BCMLOG(BCMLOG_DBG, "crystalhd_resume Success %x\n", ctx->state); + + bc_cproc_mark_pwr_state(ctx); + + return BC_STS_SUCCESS; +} + +/** + * crystalhd_user_open - Create application handle. + * @ctx: Command layer contextx. + * @user_ctx: User ID context. + * + * Return: + * status + * + * Creates an application specific UID and allocates + * application specific resources. HW layer initialization + * is done for the first open request. + */ +BC_STATUS crystalhd_user_open(struct crystalhd_cmd *ctx, + struct crystalhd_user **user_ctx) +{ + struct crystalhd_user *uc; + + if (!ctx || !user_ctx) { + BCMLOG_ERR("Invalid arg..\n"); + return BC_STS_INV_ARG; + } + + uc = bc_cproc_get_uid(ctx); + if (!uc) { + BCMLOG(BCMLOG_INFO, "No free user context...\n"); + return BC_STS_BUSY; + } + + BCMLOG(BCMLOG_INFO, "Opening new user[%x] handle\n", uc->uid); + + crystalhd_hw_open(&ctx->hw_ctx, ctx->adp); + + uc->in_use = 1; + + *user_ctx = uc; + + return BC_STS_SUCCESS; +} + +/** + * crystalhd_user_close - Close application handle. + * @ctx: Command layer contextx. + * @uc: User ID context. + * + * Return: + * status + * + * Closer aplication handle and release app specific + * resources. + */ +BC_STATUS crystalhd_user_close(struct crystalhd_cmd *ctx, struct crystalhd_user *uc) +{ + uint32_t mode = uc->mode; + + ctx->user[uc->uid].mode = DTS_MODE_INV; + ctx->user[uc->uid].in_use = 0; + ctx->cin_wait_exit = 1; + ctx->pwr_state_change = 0; + + BCMLOG(BCMLOG_INFO, "Closing user[%x] handle\n", uc->uid); + + if ((mode == DTS_DIAG_MODE) || (mode == DTS_PLAYBACK_MODE)) { + crystalhd_hw_free_dma_rings(&ctx->hw_ctx); + crystalhd_destroy_dio_pool(ctx->adp); + } else if (bc_cproc_get_user_count(ctx)) { + return BC_STS_SUCCESS; + } + + crystalhd_hw_close(&ctx->hw_ctx); + + ctx->state = BC_LINK_INVALID; + + return BC_STS_SUCCESS; +} + +/** + * crystalhd_setup_cmd_context - Setup Command layer resources. + * @ctx: Command layer contextx. + * @adp: Adapter context + * + * Return: + * status + * + * Called at the time of driver load. + */ +BC_STATUS __devinit crystalhd_setup_cmd_context(struct crystalhd_cmd *ctx, + struct crystalhd_adp *adp) +{ + int i = 0; + + if (!ctx || !adp) { + BCMLOG_ERR("Invalid arg!!\n"); + return BC_STS_INV_ARG; + } + + if (ctx->adp) + BCMLOG(BCMLOG_DBG, "Resetting Cmd context delete missing..\n"); + + ctx->adp = adp; + for (i = 0; i < BC_LINK_MAX_OPENS; i++) { + ctx->user[i].uid = i; + ctx->user[i].in_use = 0; + ctx->user[i].mode = DTS_MODE_INV; + } + + /*Open and Close the Hardware to put it in to sleep state*/ + crystalhd_hw_open(&ctx->hw_ctx, ctx->adp); + crystalhd_hw_close(&ctx->hw_ctx); + return BC_STS_SUCCESS; +} + +/** + * crystalhd_delete_cmd_context - Release Command layer resources. + * @ctx: Command layer contextx. + * + * Return: + * status + * + * Called at the time of driver un-load. + */ +BC_STATUS __devexit crystalhd_delete_cmd_context(struct crystalhd_cmd *ctx) +{ + BCMLOG(BCMLOG_DBG, "Deleting Command context..\n"); + + ctx->adp = NULL; + + return BC_STS_SUCCESS; +} + +/** + * crystalhd_get_cmd_proc - Cproc table lookup. + * @ctx: Command layer contextx. + * @cmd: IOCTL command code. + * @uc: User ID context. + * + * Return: + * command proc function pointer + * + * This function checks the process context, application's + * mode of operation and returns the function pointer + * from the cproc table. + */ +crystalhd_cmd_proc crystalhd_get_cmd_proc(struct crystalhd_cmd *ctx, uint32_t cmd, + struct crystalhd_user *uc) +{ + crystalhd_cmd_proc cproc = NULL; + unsigned int i, tbl_sz; + + if (!ctx) { + BCMLOG_ERR("Invalid arg.. Cmd[%d]\n", cmd); + return NULL; + } + + if ((cmd != BCM_IOC_GET_DRV_STAT) && (ctx->state & BC_LINK_SUSPEND)) { + BCMLOG_ERR("Invalid State [suspend Set].. Cmd[%d]\n", cmd); + return NULL; + } + + tbl_sz = sizeof(g_crystalhd_cproc_tbl) / sizeof(crystalhd_cmd_tbl_t); + for (i = 0; i < tbl_sz; i++) { + if (g_crystalhd_cproc_tbl[i].cmd_id == cmd) { + if ((uc->mode == DTS_MONITOR_MODE) && + (g_crystalhd_cproc_tbl[i].block_mon)) { + BCMLOG(BCMLOG_INFO, "Blocking cmd %d \n", cmd); + break; + } + cproc = g_crystalhd_cproc_tbl[i].cmd_proc; + break; + } + } + + return cproc; +} + +/** + * crystalhd_cmd_interrupt - ISR entry point + * @ctx: Command layer contextx. + * + * Return: + * TRUE: If interrupt from bcm70012 device. + * + * + * ISR entry point from OS layer. + */ +bool crystalhd_cmd_interrupt(struct crystalhd_cmd *ctx) +{ + if (!ctx) { + BCMLOG_ERR("Invalid arg..\n"); + return 0; + } + + return crystalhd_hw_interrupt(ctx->adp, &ctx->hw_ctx); +} diff --git a/drivers/staging/crystalhd/crystalhd_cmds.h b/drivers/staging/crystalhd/crystalhd_cmds.h new file mode 100644 index 0000000..6b290ae --- /dev/null +++ b/drivers/staging/crystalhd/crystalhd_cmds.h @@ -0,0 +1,88 @@ +/*************************************************************************** + * Copyright (c) 2005-2009, Broadcom Corporation. + * + * Name: crystalhd_cmds . h + * + * Description: + * BCM70010 Linux driver user command interfaces. + * + * HISTORY: + * + ********************************************************************** + * This file is part of the crystalhd device driver. + * + * This driver is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This driver is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this driver. If not, see <http://www.gnu.org/licenses/>. + **********************************************************************/ + +#ifndef _CRYSTALHD_CMDS_H_ +#define _CRYSTALHD_CMDS_H_ + +/* + * NOTE:: This is the main interface file between the Linux layer + * and the harware layer. This file will use the definitions + * from _dts_glob and dts_defs etc.. which are defined for + * windows. + */ +#include "crystalhd_misc.h" +#include "crystalhd_hw.h" + +enum _crystalhd_state{ + BC_LINK_INVALID = 0x00, + BC_LINK_INIT = 0x01, + BC_LINK_CAP_EN = 0x02, + BC_LINK_FMT_CHG = 0x04, + BC_LINK_SUSPEND = 0x10, + BC_LINK_PAUSED = 0x20, + BC_LINK_READY = (BC_LINK_INIT | BC_LINK_CAP_EN | BC_LINK_FMT_CHG), +}; + +struct crystalhd_user { + uint32_t uid; + uint32_t in_use; + uint32_t mode; +}; + +#define DTS_MODE_INV (-1) + +struct crystalhd_cmd { + uint32_t state; + struct crystalhd_adp *adp; + struct crystalhd_user user[BC_LINK_MAX_OPENS]; + + spinlock_t ctx_lock; + uint32_t tx_list_id; + uint32_t cin_wait_exit; + uint32_t pwr_state_change; + struct crystalhd_hw hw_ctx; +}; + +typedef BC_STATUS (*crystalhd_cmd_proc)(struct crystalhd_cmd *, crystalhd_ioctl_data *); + +typedef struct _crystalhd_cmd_tbl { + uint32_t cmd_id; + const crystalhd_cmd_proc cmd_proc; + uint32_t block_mon; +} crystalhd_cmd_tbl_t; + + +BC_STATUS crystalhd_suspend(struct crystalhd_cmd *ctx, crystalhd_ioctl_data *idata); +BC_STATUS crystalhd_resume(struct crystalhd_cmd *ctx); +crystalhd_cmd_proc crystalhd_get_cmd_proc(struct crystalhd_cmd *ctx, uint32_t cmd, + struct crystalhd_user *uc); +BC_STATUS crystalhd_user_open(struct crystalhd_cmd *ctx, struct crystalhd_user **user_ctx); +BC_STATUS crystalhd_user_close(struct crystalhd_cmd *ctx, struct crystalhd_user *uc); +BC_STATUS crystalhd_setup_cmd_context(struct crystalhd_cmd *ctx, struct crystalhd_adp *adp); +BC_STATUS crystalhd_delete_cmd_context(struct crystalhd_cmd *ctx); +bool crystalhd_cmd_interrupt(struct crystalhd_cmd *ctx); + +#endif diff --git a/drivers/staging/crystalhd/crystalhd_fw_if.h b/drivers/staging/crystalhd/crystalhd_fw_if.h new file mode 100644 index 0000000..261cd19 --- /dev/null +++ b/drivers/staging/crystalhd/crystalhd_fw_if.h @@ -0,0 +1,369 @@ +/*************************************************************************** + * Copyright (c) 2005-2009, Broadcom Corporation. + * + * Name: crystalhd_fw_if . h + * + * Description: + * BCM70012 Firmware interface definitions. + * + * HISTORY: + * + ********************************************************************** + * This file is part of the crystalhd device driver. + * + * This driver is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This driver is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this driver. If not, see <http://www.gnu.org/licenses/>. + **********************************************************************/ + +#ifndef _CRYSTALHD_FW_IF_H_ +#define _CRYSTALHD_FW_IF_H_ + +/* TBD: Pull in only required defs into this file.. */ + + + +/* User Data Header */ +typedef struct user_data { + struct user_data *next; + uint32_t type; + uint32_t size; +} UD_HDR; + + + +/*------------------------------------------------------* + * MPEG Extension to the PPB * + *------------------------------------------------------*/ +typedef struct { + uint32_t to_be_defined; + uint32_t valid; + + /* Always valid, defaults to picture size if no + sequence display extension in the stream. */ + uint32_t display_horizontal_size; + uint32_t display_vertical_size; + + /* MPEG_VALID_PANSCAN + Offsets are a copy values from the MPEG stream. */ + uint32_t offset_count; + int32_t horizontal_offset[3]; + int32_t vertical_offset[3]; + + /* MPEG_VALID_USERDATA + User data is in the form of a linked list. */ + int32_t userDataSize; + UD_HDR *userData; + +} PPB_MPEG; + + +/*------------------------------------------------------* + * VC1 Extension to the PPB * + *------------------------------------------------------*/ +typedef struct { + uint32_t to_be_defined; + uint32_t valid; + + /* Always valid, defaults to picture size if no + sequence display extension in the stream. */ + uint32_t display_horizontal_size; + uint32_t display_vertical_size; + + /* VC1 pan scan windows */ + uint32_t num_panscan_windows; + int32_t ps_horiz_offset[4]; + int32_t ps_vert_offset[4]; + int32_t ps_width[4]; + int32_t ps_height[4]; + + /* VC1_VALID_USERDATA + User data is in the form of a linked list. */ + int32_t userDataSize; + UD_HDR *userData; + +} PPB_VC1; + +/*------------------------------------------------------* + * H.264 Extension to the PPB * + *------------------------------------------------------*/ + +/** + * @brief Film grain SEI message. + * + * Content of the film grain SEI message. + */ + +/* maximum number of model-values as for Thomson spec(standard says 5) */ +#define MAX_FGT_MODEL_VALUE (3) + +/* maximum number of intervals(as many as 256 intervals?) */ +#define MAX_FGT_VALUE_INTERVAL (256) + +typedef struct FGT_SEI { + struct FGT_SEI *next; + unsigned char model_values[3][MAX_FGT_VALUE_INTERVAL][MAX_FGT_MODEL_VALUE]; + unsigned char upper_bound[3][MAX_FGT_VALUE_INTERVAL]; + unsigned char lower_bound[3][MAX_FGT_VALUE_INTERVAL]; + + unsigned char cancel_flag; /* Cancel flag: 1 no film grain. */ + unsigned char model_id; /* Model id. */ + + /* +unused SE based on Thomson spec */ + unsigned char color_desc_flag; /* Separate color descrition flag. */ + unsigned char bit_depth_luma; /* Bit depth luma minus 8. */ + unsigned char bit_depth_chroma; /* Bit depth chroma minus 8. */ + unsigned char full_range_flag; /* Full range flag. */ + unsigned char color_primaries; /* Color primaries. */ + unsigned char transfer_charact; /* Transfer characteristics. */ + unsigned char matrix_coeff; /*< Matrix coefficients. */ + /* -unused SE based on Thomson spec */ + + unsigned char blending_mode_id; /* Blending mode. */ + unsigned char log2_scale_factor; /* Log2 scale factor (2-7). */ + unsigned char comp_flag[3]; /* Components [0,2] parameters present flag. */ + unsigned char num_intervals_minus1[3]; /* Number of intensity level intervals. */ + unsigned char num_model_values[3]; /* Number of model values. */ + uint16_t repetition_period; /* Repetition period (0-16384) */ + +} FGT_SEI; + +typedef struct { + /* 'valid' specifies which fields (or sets of + * fields) below are valid. If the corresponding + * bit in 'valid' is NOT set then that field(s) + * is (are) not initialized. */ + uint32_t valid; + + int32_t poc_top; /* POC for Top Field/Frame */ + int32_t poc_bottom; /* POC for Bottom Field */ + uint32_t idr_pic_id; + + /* H264_VALID_PANSCAN */ + uint32_t pan_scan_count; + int32_t pan_scan_left[3]; + int32_t pan_scan_right[3]; + int32_t pan_scan_top[3]; + int32_t pan_scan_bottom[3]; + + /* H264_VALID_CT_TYPE */ + uint32_t ct_type_count; + uint32_t ct_type[3]; + + /* H264_VALID_SPS_CROP */ + int32_t sps_crop_left; + int32_t sps_crop_right; + int32_t sps_crop_top; + int32_t sps_crop_bottom; + + /* H264_VALID_VUI */ + uint32_t chroma_top; + uint32_t chroma_bottom; + + /* H264_VALID_USER */ + uint32_t user_data_size; + UD_HDR *user_data; + + /* H264 VALID FGT */ + FGT_SEI *pfgt; + +} PPB_H264; + +typedef struct { + /* Common fields. */ + uint32_t picture_number; /* Ordinal display number */ + uint32_t video_buffer; /* Video (picbuf) number */ + uint32_t video_address; /* Address of picbuf Y */ + uint32_t video_address_uv; /* Address of picbuf UV */ + uint32_t video_stripe; /* Picbuf stripe */ + uint32_t video_width; /* Picbuf width */ + uint32_t video_height; /* Picbuf height */ + + uint32_t channel_id; /* Decoder channel ID */ + uint32_t status; /* reserved */ + uint32_t width; /* pixels */ + uint32_t height; /* pixels */ + uint32_t chroma_format; /* see above */ + uint32_t pulldown; /* see above */ + uint32_t flags; /* see above */ + uint32_t pts; /* 32 LSBs of PTS */ + uint32_t protocol; /* protocolXXX (above) */ + + uint32_t frame_rate; /* see above */ + uint32_t matrix_coeff; /* see above */ + uint32_t aspect_ratio; /* see above */ + uint32_t colour_primaries; /* see above */ + uint32_t transfer_char; /* see above */ + uint32_t pcr_offset; /* 45kHz if PCR type; else 27MHz */ + uint32_t n_drop; /* Number of pictures to be dropped */ + + uint32_t custom_aspect_ratio_width_height; + /* upper 16-bits is Y and lower 16-bits is X */ + + uint32_t picture_tag; /* Indexing tag from BUD packets */ + uint32_t picture_done_payload; + uint32_t picture_meta_payload; + uint32_t reserved[1]; + + /* Protocol-specific extensions. */ + union { + PPB_H264 h264; + PPB_MPEG mpeg; + PPB_VC1 vc1; + } other; + +} PPB; + +typedef struct { + uint32_t bFormatChange; + uint32_t resolution; + uint32_t channelId; + uint32_t ppbPtr; + int32_t ptsStcOffset; + uint32_t zeroPanscanValid; + uint32_t dramOutBufAddr; + uint32_t yComponent; + PPB ppb; + +} C011_PIB; + + + +typedef struct { + uint32_t command; + uint32_t sequence; + uint32_t status; + uint32_t picBuf; + uint32_t picRelBuf; + uint32_t picInfoDeliveryQ; + uint32_t picInfoReleaseQ; + uint32_t channelStatus; + uint32_t userDataDeliveryQ; + uint32_t userDataReleaseQ; + uint32_t transportStreamCaptureAddr; + uint32_t asyncEventQ; + +} DecRspChannelStartVideo; + +#define eCMD_C011_CMD_BASE (0x73763000) + +/* host commands */ +typedef enum { + eCMD_TS_GET_NEXT_PIC = 0x7376F100, /* debug get next picture */ + eCMD_TS_GET_LAST_PIC = 0x7376F102, /* debug get last pic status */ + eCMD_TS_READ_WRITE_MEM = 0x7376F104, /* debug read write memory */ + + /* New API commands */ + /* General commands */ + eCMD_C011_INIT = eCMD_C011_CMD_BASE + 0x01, + eCMD_C011_RESET = eCMD_C011_CMD_BASE + 0x02, + eCMD_C011_SELF_TEST = eCMD_C011_CMD_BASE + 0x03, + eCMD_C011_GET_VERSION = eCMD_C011_CMD_BASE + 0x04, + eCMD_C011_GPIO = eCMD_C011_CMD_BASE + 0x05, + eCMD_C011_DEBUG_SETUP = eCMD_C011_CMD_BASE + 0x06, + + /* Decoding commands */ + eCMD_C011_DEC_CHAN_OPEN = eCMD_C011_CMD_BASE + 0x100, + eCMD_C011_DEC_CHAN_CLOSE = eCMD_C011_CMD_BASE + 0x101, + eCMD_C011_DEC_CHAN_ACTIVATE = eCMD_C011_CMD_BASE + 0x102, + eCMD_C011_DEC_CHAN_STATUS = eCMD_C011_CMD_BASE + 0x103, + eCMD_C011_DEC_CHAN_FLUSH = eCMD_C011_CMD_BASE + 0x104, + eCMD_C011_DEC_CHAN_TRICK_PLAY = eCMD_C011_CMD_BASE + 0x105, + eCMD_C011_DEC_CHAN_TS_PIDS = eCMD_C011_CMD_BASE + 0x106, + eCMD_C011_DEC_CHAN_PS_STREAM_ID = eCMD_C011_CMD_BASE + 0x107, + eCMD_C011_DEC_CHAN_INPUT_PARAMS = eCMD_C011_CMD_BASE + 0x108, + eCMD_C011_DEC_CHAN_VIDEO_OUTPUT = eCMD_C011_CMD_BASE + 0x109, + eCMD_C011_DEC_CHAN_OUTPUT_FORMAT = eCMD_C011_CMD_BASE + 0x10A, + eCMD_C011_DEC_CHAN_SCALING_FILTERS = eCMD_C011_CMD_BASE + 0x10B, + eCMD_C011_DEC_CHAN_OSD_MODE = eCMD_C011_CMD_BASE + 0x10D, + eCMD_C011_DEC_CHAN_DROP = eCMD_C011_CMD_BASE + 0x10E, + eCMD_C011_DEC_CHAN_RELEASE = eCMD_C011_CMD_BASE + 0x10F, + eCMD_C011_DEC_CHAN_STREAM_SETTINGS = eCMD_C011_CMD_BASE + 0x110, + eCMD_C011_DEC_CHAN_PAUSE_OUTPUT = eCMD_C011_CMD_BASE + 0x111, + eCMD_C011_DEC_CHAN_CHANGE = eCMD_C011_CMD_BASE + 0x112, + eCMD_C011_DEC_CHAN_SET_STC = eCMD_C011_CMD_BASE + 0x113, + eCMD_C011_DEC_CHAN_SET_PTS = eCMD_C011_CMD_BASE + 0x114, + eCMD_C011_DEC_CHAN_CC_MODE = eCMD_C011_CMD_BASE + 0x115, + eCMD_C011_DEC_CREATE_AUDIO_CONTEXT = eCMD_C011_CMD_BASE + 0x116, + eCMD_C011_DEC_COPY_AUDIO_CONTEXT = eCMD_C011_CMD_BASE + 0x117, + eCMD_C011_DEC_DELETE_AUDIO_CONTEXT = eCMD_C011_CMD_BASE + 0x118, + eCMD_C011_DEC_CHAN_SET_DECYPTION = eCMD_C011_CMD_BASE + 0x119, + eCMD_C011_DEC_CHAN_START_VIDEO = eCMD_C011_CMD_BASE + 0x11A, + eCMD_C011_DEC_CHAN_STOP_VIDEO = eCMD_C011_CMD_BASE + 0x11B, + eCMD_C011_DEC_CHAN_PIC_CAPTURE = eCMD_C011_CMD_BASE + 0x11C, + eCMD_C011_DEC_CHAN_PAUSE = eCMD_C011_CMD_BASE + 0x11D, + eCMD_C011_DEC_CHAN_PAUSE_STATE = eCMD_C011_CMD_BASE + 0x11E, + eCMD_C011_DEC_CHAN_SET_SLOWM_RATE = eCMD_C011_CMD_BASE + 0x11F, + eCMD_C011_DEC_CHAN_GET_SLOWM_RATE = eCMD_C011_CMD_BASE + 0x120, + eCMD_C011_DEC_CHAN_SET_FF_RATE = eCMD_C011_CMD_BASE + 0x121, + eCMD_C011_DEC_CHAN_GET_FF_RATE = eCMD_C011_CMD_BASE + 0x122, + eCMD_C011_DEC_CHAN_FRAME_ADVANCE = eCMD_C011_CMD_BASE + 0x123, + eCMD_C011_DEC_CHAN_SET_SKIP_PIC_MODE = eCMD_C011_CMD_BASE + 0x124, + eCMD_C011_DEC_CHAN_GET_SKIP_PIC_MODE = eCMD_C011_CMD_BASE + 0x125, + eCMD_C011_DEC_CHAN_FILL_PIC_BUF = eCMD_C011_CMD_BASE + 0x126, + eCMD_C011_DEC_CHAN_SET_CONTINUITY_CHECK = eCMD_C011_CMD_BASE + 0x127, + eCMD_C011_DEC_CHAN_GET_CONTINUITY_CHECK = eCMD_C011_CMD_BASE + 0x128, + eCMD_C011_DEC_CHAN_SET_BRCM_TRICK_MODE = eCMD_C011_CMD_BASE + 0x129, + eCMD_C011_DEC_CHAN_GET_BRCM_TRICK_MODE = eCMD_C011_CMD_BASE + 0x12A, + eCMD_C011_DEC_CHAN_REVERSE_FIELD_STATUS = eCMD_C011_CMD_BASE + 0x12B, + eCMD_C011_DEC_CHAN_I_PICTURE_FOUND = eCMD_C011_CMD_BASE + 0x12C, + eCMD_C011_DEC_CHAN_SET_PARAMETER = eCMD_C011_CMD_BASE + 0x12D, + eCMD_C011_DEC_CHAN_SET_USER_DATA_MODE = eCMD_C011_CMD_BASE + 0x12E, + eCMD_C011_DEC_CHAN_SET_PAUSE_DISPLAY_MODE = eCMD_C011_CMD_BASE + 0x12F, + eCMD_C011_DEC_CHAN_SET_SLOW_DISPLAY_MODE = eCMD_C011_CMD_BASE + 0x130, + eCMD_C011_DEC_CHAN_SET_FF_DISPLAY_MODE = eCMD_C011_CMD_BASE + 0x131, + eCMD_C011_DEC_CHAN_SET_DISPLAY_TIMING_MODE = eCMD_C011_CMD_BASE + 0x132, + eCMD_C011_DEC_CHAN_SET_DISPLAY_MODE = eCMD_C011_CMD_BASE + 0x133, + eCMD_C011_DEC_CHAN_GET_DISPLAY_MODE = eCMD_C011_CMD_BASE + 0x134, + eCMD_C011_DEC_CHAN_SET_REVERSE_FIELD = eCMD_C011_CMD_BASE + 0x135, + eCMD_C011_DEC_CHAN_STREAM_OPEN = eCMD_C011_CMD_BASE + 0x136, + eCMD_C011_DEC_CHAN_SET_PCR_PID = eCMD_C011_CMD_BASE + 0x137, + eCMD_C011_DEC_CHAN_SET_VID_PID = eCMD_C011_CMD_BASE + 0x138, + eCMD_C011_DEC_CHAN_SET_PAN_SCAN_MODE = eCMD_C011_CMD_BASE + 0x139, + eCMD_C011_DEC_CHAN_START_DISPLAY_AT_PTS = eCMD_C011_CMD_BASE + 0x140, + eCMD_C011_DEC_CHAN_STOP_DISPLAY_AT_PTS = eCMD_C011_CMD_BASE + 0x141, + eCMD_C011_DEC_CHAN_SET_DISPLAY_ORDER = eCMD_C011_CMD_BASE + 0x142, + eCMD_C011_DEC_CHAN_GET_DISPLAY_ORDER = eCMD_C011_CMD_BASE + 0x143, + eCMD_C011_DEC_CHAN_SET_HOST_TRICK_MODE = eCMD_C011_CMD_BASE + 0x144, + eCMD_C011_DEC_CHAN_SET_OPERATION_MODE = eCMD_C011_CMD_BASE + 0x145, + eCMD_C011_DEC_CHAN_DISPLAY_PAUSE_UNTO_PTS = eCMD_C011_CMD_BASE + 0x146, + eCMD_C011_DEC_CHAN_SET_PTS_STC_DIFF_THRESHOLD = eCMD_C011_CMD_BASE + 0x147, + eCMD_C011_DEC_CHAN_SEND_COMPRESSED_BUF = eCMD_C011_CMD_BASE + 0x148, + eCMD_C011_DEC_CHAN_SET_CLIPPING = eCMD_C011_CMD_BASE + 0x149, + eCMD_C011_DEC_CHAN_SET_PARAMETERS_FOR_HARD_RESET_INTERRUPT_TO_HOST + = eCMD_C011_CMD_BASE + 0x150, + + /* Decoder RevD commands */ + eCMD_C011_DEC_CHAN_SET_CSC = eCMD_C011_CMD_BASE + 0x180, /* color space conversion */ + eCMD_C011_DEC_CHAN_SET_RANGE_REMAP = eCMD_C011_CMD_BASE + 0x181, + eCMD_C011_DEC_CHAN_SET_FGT = eCMD_C011_CMD_BASE + 0x182, + /* Note: 0x183 not implemented yet in Rev D main */ + eCMD_C011_DEC_CHAN_SET_LASTPICTURE_PADDING = eCMD_C011_CMD_BASE + 0x183, + + /* Decoder 7412 commands (7412-only) */ + eCMD_C011_DEC_CHAN_SET_CONTENT_KEY = eCMD_C011_CMD_BASE + 0x190, + eCMD_C011_DEC_CHAN_SET_SESSION_KEY = eCMD_C011_CMD_BASE + 0x191, + eCMD_C011_DEC_CHAN_FMT_CHANGE_ACK = eCMD_C011_CMD_BASE + 0x192, + + eCMD_C011_DEC_CHAN_CUSTOM_VIDOUT = eCMD_C011_CMD_BASE + 0x1FF, + + /* Encoding commands */ + eCMD_C011_ENC_CHAN_OPEN = eCMD_C011_CMD_BASE + 0x200, + eCMD_C011_ENC_CHAN_CLOSE = eCMD_C011_CMD_BASE + 0x201, + eCMD_C011_ENC_CHAN_ACTIVATE = eCMD_C011_CMD_BASE + 0x202, + eCMD_C011_ENC_CHAN_CONTROL = eCMD_C011_CMD_BASE + 0x203, + eCMD_C011_ENC_CHAN_STATISTICS = eCMD_C011_CMD_BASE + 0x204, + + eNOTIFY_C011_ENC_CHAN_EVENT = eCMD_C011_CMD_BASE + 0x210, + +} eC011_TS_CMD; + +#endif diff --git a/drivers/staging/crystalhd/crystalhd_hw.c b/drivers/staging/crystalhd/crystalhd_hw.c new file mode 100644 index 0000000..01819d3 --- /dev/null +++ b/drivers/staging/crystalhd/crystalhd_hw.c @@ -0,0 +1,2395 @@ +/*************************************************************************** + * Copyright (c) 2005-2009, Broadcom Corporation. + * + * Name: crystalhd_hw . c + * + * Description: + * BCM70010 Linux driver HW layer. + * + ********************************************************************** + * This file is part of the crystalhd device driver. + * + * This driver is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This driver is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this driver. If not, see <http://www.gnu.org/licenses/>. + **********************************************************************/ + +#include <linux/pci.h> +#include <linux/delay.h> +#include "crystalhd_hw.h" + +/* Functions internal to this file */ + +static void crystalhd_enable_uarts(struct crystalhd_adp *adp) +{ + bc_dec_reg_wr(adp, UartSelectA, BSVS_UART_STREAM); + bc_dec_reg_wr(adp, UartSelectB, BSVS_UART_DEC_OUTER); +} + + +static void crystalhd_start_dram(struct crystalhd_adp *adp) +{ + bc_dec_reg_wr(adp, SDRAM_PARAM, ((40 / 5 - 1) << 0) | + /* tras (40ns tras)/(5ns period) -1 ((15/5 - 1) << 4) | // trcd */ + ((15 / 5 - 1) << 7) | /* trp */ + ((10 / 5 - 1) << 10) | /* trrd */ + ((15 / 5 + 1) << 12) | /* twr */ + ((2 + 1) << 16) | /* twtr */ + ((70 / 5 - 2) << 19) | /* trfc */ + (0 << 23)); + + bc_dec_reg_wr(adp, SDRAM_PRECHARGE, 0); + bc_dec_reg_wr(adp, SDRAM_EXT_MODE, 2); + bc_dec_reg_wr(adp, SDRAM_MODE, 0x132); + bc_dec_reg_wr(adp, SDRAM_PRECHARGE, 0); + bc_dec_reg_wr(adp, SDRAM_REFRESH, 0); + bc_dec_reg_wr(adp, SDRAM_REFRESH, 0); + bc_dec_reg_wr(adp, SDRAM_MODE, 0x32); + /* setting the refresh rate here */ + bc_dec_reg_wr(adp, SDRAM_REF_PARAM, ((1 << 12) | 96)); +} + + +static bool crystalhd_bring_out_of_rst(struct crystalhd_adp *adp) +{ + link_misc_perst_deco_ctrl rst_deco_cntrl; + link_misc_perst_clk_ctrl rst_clk_cntrl; + uint32_t temp; + + /* + * Link clocks: MISC_PERST_CLOCK_CTRL Clear PLL power down bit, + * delay to allow PLL to lock Clear alternate clock, stop clock bits + */ + rst_clk_cntrl.whole_reg = crystalhd_reg_rd(adp, MISC_PERST_CLOCK_CTRL); + rst_clk_cntrl.pll_pwr_dn = 0; + crystalhd_reg_wr(adp, MISC_PERST_CLOCK_CTRL, rst_clk_cntrl.whole_reg); + msleep_interruptible(50); + + rst_clk_cntrl.whole_reg = crystalhd_reg_rd(adp, MISC_PERST_CLOCK_CTRL); + rst_clk_cntrl.stop_core_clk = 0; + rst_clk_cntrl.sel_alt_clk = 0; + + crystalhd_reg_wr(adp, MISC_PERST_CLOCK_CTRL, rst_clk_cntrl.whole_reg); + msleep_interruptible(50); + + /* + * Bus Arbiter Timeout: GISB_ARBITER_TIMER + * Set internal bus arbiter timeout to 40us based on core clock speed + * (63MHz * 40us = 0x9D8) + */ + crystalhd_reg_wr(adp, GISB_ARBITER_TIMER, 0x9D8); + + /* + * Decoder clocks: MISC_PERST_DECODER_CTRL + * Enable clocks while 7412 reset is asserted, delay + * De-assert 7412 reset + */ + rst_deco_cntrl.whole_reg = crystalhd_reg_rd(adp, MISC_PERST_DECODER_CTRL); + rst_deco_cntrl.stop_bcm_7412_clk = 0; + rst_deco_cntrl.bcm7412_rst = 1; + crystalhd_reg_wr(adp, MISC_PERST_DECODER_CTRL, rst_deco_cntrl.whole_reg); + msleep_interruptible(10); + + rst_deco_cntrl.whole_reg = crystalhd_reg_rd(adp, MISC_PERST_DECODER_CTRL); + rst_deco_cntrl.bcm7412_rst = 0; + crystalhd_reg_wr(adp, MISC_PERST_DECODER_CTRL, rst_deco_cntrl.whole_reg); + msleep_interruptible(50); + + /* Disable OTP_CONTENT_MISC to 0 to disable all secure modes */ + crystalhd_reg_wr(adp, OTP_CONTENT_MISC, 0); + + /* Clear bit 29 of 0x404 */ + temp = crystalhd_reg_rd(adp, PCIE_TL_TRANSACTION_CONFIGURATION); + temp &= ~BC_BIT(29); + crystalhd_reg_wr(adp, PCIE_TL_TRANSACTION_CONFIGURATION, temp); + + /* 2.5V regulator must be set to 2.6 volts (+6%) */ + /* FIXME: jarod: what's the point of this reg read? */ + temp = crystalhd_reg_rd(adp, MISC_PERST_VREG_CTRL); + crystalhd_reg_wr(adp, MISC_PERST_VREG_CTRL, 0xF3); + + return true; +} + +static bool crystalhd_put_in_reset(struct crystalhd_adp *adp) +{ + link_misc_perst_deco_ctrl rst_deco_cntrl; + link_misc_perst_clk_ctrl rst_clk_cntrl; + uint32_t temp; + + /* + * Decoder clocks: MISC_PERST_DECODER_CTRL + * Assert 7412 reset, delay + * Assert 7412 stop clock + */ + rst_deco_cntrl.whole_reg = crystalhd_reg_rd(adp, MISC_PERST_DECODER_CTRL); + rst_deco_cntrl.stop_bcm_7412_clk = 1; + crystalhd_reg_wr(adp, MISC_PERST_DECODER_CTRL, rst_deco_cntrl.whole_reg); + msleep_interruptible(50); + + /* Bus Arbiter Timeout: GISB_ARBITER_TIMER + * Set internal bus arbiter timeout to 40us based on core clock speed + * (6.75MHZ * 40us = 0x10E) + */ + crystalhd_reg_wr(adp, GISB_ARBITER_TIMER, 0x10E); + + /* Link clocks: MISC_PERST_CLOCK_CTRL + * Stop core clk, delay + * Set alternate clk, delay, set PLL power down + */ + rst_clk_cntrl.whole_reg = crystalhd_reg_rd(adp, MISC_PERST_CLOCK_CTRL); + rst_clk_cntrl.stop_core_clk = 1; + rst_clk_cntrl.sel_alt_clk = 1; + crystalhd_reg_wr(adp, MISC_PERST_CLOCK_CTRL, rst_clk_cntrl.whole_reg); + msleep_interruptible(50); + + rst_clk_cntrl.whole_reg = crystalhd_reg_rd(adp, MISC_PERST_CLOCK_CTRL); + rst_clk_cntrl.pll_pwr_dn = 1; + crystalhd_reg_wr(adp, MISC_PERST_CLOCK_CTRL, rst_clk_cntrl.whole_reg); + + /* + * Read and restore the Transaction Configuration Register + * after core reset + */ + temp = crystalhd_reg_rd(adp, PCIE_TL_TRANSACTION_CONFIGURATION); + + /* + * Link core soft reset: MISC3_RESET_CTRL + * - Write BIT[0]=1 and read it back for core reset to take place + */ + crystalhd_reg_wr(adp, MISC3_RESET_CTRL, 1); + rst_deco_cntrl.whole_reg = crystalhd_reg_rd(adp, MISC3_RESET_CTRL); + msleep_interruptible(50); + + /* restore the transaction configuration register */ + crystalhd_reg_wr(adp, PCIE_TL_TRANSACTION_CONFIGURATION, temp); + + return true; +} + +static void crystalhd_disable_interrupts(struct crystalhd_adp *adp) +{ + intr_mask_reg intr_mask; + intr_mask.whole_reg = crystalhd_reg_rd(adp, INTR_INTR_MSK_STS_REG); + intr_mask.mask_pcie_err = 1; + intr_mask.mask_pcie_rbusmast_err = 1; + intr_mask.mask_pcie_rgr_bridge = 1; + intr_mask.mask_rx_done = 1; + intr_mask.mask_rx_err = 1; + intr_mask.mask_tx_done = 1; + intr_mask.mask_tx_err = 1; + crystalhd_reg_wr(adp, INTR_INTR_MSK_SET_REG, intr_mask.whole_reg); + + return; +} + +static void crystalhd_enable_interrupts(struct crystalhd_adp *adp) +{ + intr_mask_reg intr_mask; + intr_mask.whole_reg = crystalhd_reg_rd(adp, INTR_INTR_MSK_STS_REG); + intr_mask.mask_pcie_err = 1; + intr_mask.mask_pcie_rbusmast_err = 1; + intr_mask.mask_pcie_rgr_bridge = 1; + intr_mask.mask_rx_done = 1; + intr_mask.mask_rx_err = 1; + intr_mask.mask_tx_done = 1; + intr_mask.mask_tx_err = 1; + crystalhd_reg_wr(adp, INTR_INTR_MSK_CLR_REG, intr_mask.whole_reg); + + return; +} + +static void crystalhd_clear_errors(struct crystalhd_adp *adp) +{ + uint32_t reg; + + /* FIXME: jarod: wouldn't we want to write a 0 to the reg? Or does the write clear the bits specified? */ + reg = crystalhd_reg_rd(adp, MISC1_Y_RX_ERROR_STATUS); + if (reg) + crystalhd_reg_wr(adp, MISC1_Y_RX_ERROR_STATUS, reg); + + reg = crystalhd_reg_rd(adp, MISC1_UV_RX_ERROR_STATUS); + if (reg) + crystalhd_reg_wr(adp, MISC1_UV_RX_ERROR_STATUS, reg); + + reg = crystalhd_reg_rd(adp, MISC1_TX_DMA_ERROR_STATUS); + if (reg) + crystalhd_reg_wr(adp, MISC1_TX_DMA_ERROR_STATUS, reg); +} + +static void crystalhd_clear_interrupts(struct crystalhd_adp *adp) +{ + uint32_t intr_sts = crystalhd_reg_rd(adp, INTR_INTR_STATUS); + + if (intr_sts) { + crystalhd_reg_wr(adp, INTR_INTR_CLR_REG, intr_sts); + + /* Write End Of Interrupt for PCIE */ + crystalhd_reg_wr(adp, INTR_EOI_CTRL, 1); + } +} + +static void crystalhd_soft_rst(struct crystalhd_adp *adp) +{ + uint32_t val; + + /* Assert c011 soft reset*/ + bc_dec_reg_wr(adp, DecHt_HostSwReset, 0x00000001); + msleep_interruptible(50); + + /* Release c011 soft reset*/ + bc_dec_reg_wr(adp, DecHt_HostSwReset, 0x00000000); + + /* Disable Stuffing..*/ + val = crystalhd_reg_rd(adp, MISC2_GLOBAL_CTRL); + val |= BC_BIT(8); + crystalhd_reg_wr(adp, MISC2_GLOBAL_CTRL, val); +} + +static bool crystalhd_load_firmware_config(struct crystalhd_adp *adp) +{ + uint32_t i = 0, reg; + + crystalhd_reg_wr(adp, DCI_DRAM_BASE_ADDR, (BC_DRAM_FW_CFG_ADDR >> 19)); + + crystalhd_reg_wr(adp, AES_CMD, 0); + crystalhd_reg_wr(adp, AES_CONFIG_INFO, (BC_DRAM_FW_CFG_ADDR & 0x7FFFF)); + crystalhd_reg_wr(adp, AES_CMD, 0x1); + + /* FIXME: jarod: I've seen this fail, and introducing extra delays helps... */ + for (i = 0; i < 100; ++i) { + reg = crystalhd_reg_rd(adp, AES_STATUS); + if (reg & 0x1) + return true; + msleep_interruptible(10); + } + + return false; +} + + +static bool crystalhd_start_device(struct crystalhd_adp *adp) +{ + uint32_t dbg_options, glb_cntrl = 0, reg_pwrmgmt = 0; + + BCMLOG(BCMLOG_INFO, "Starting BCM70012 Device\n"); + + reg_pwrmgmt = crystalhd_reg_rd(adp, PCIE_DLL_DATA_LINK_CONTROL); + reg_pwrmgmt &= ~ASPM_L1_ENABLE; + + crystalhd_reg_wr(adp, PCIE_DLL_DATA_LINK_CONTROL, reg_pwrmgmt); + + if (!crystalhd_bring_out_of_rst(adp)) { + BCMLOG_ERR("Failed To Bring Link Out Of Reset\n"); + return false; + } + + crystalhd_disable_interrupts(adp); + + crystalhd_clear_errors(adp); + + crystalhd_clear_interrupts(adp); + + crystalhd_enable_interrupts(adp); + + /* Enable the option for getting the total no. of DWORDS + * that have been transfered by the RXDMA engine + */ + dbg_options = crystalhd_reg_rd(adp, MISC1_DMA_DEBUG_OPTIONS_REG); + dbg_options |= 0x10; + crystalhd_reg_wr(adp, MISC1_DMA_DEBUG_OPTIONS_REG, dbg_options); + + /* Enable PCI Global Control options */ + glb_cntrl = crystalhd_reg_rd(adp, MISC2_GLOBAL_CTRL); + glb_cntrl |= 0x100; + glb_cntrl |= 0x8000; + crystalhd_reg_wr(adp, MISC2_GLOBAL_CTRL, glb_cntrl); + + crystalhd_enable_interrupts(adp); + + crystalhd_soft_rst(adp); + crystalhd_start_dram(adp); + crystalhd_enable_uarts(adp); + + return true; +} + +static bool crystalhd_stop_device(struct crystalhd_adp *adp) +{ + uint32_t reg; + + BCMLOG(BCMLOG_INFO, "Stopping BCM70012 Device\n"); + /* Clear and disable interrupts */ + crystalhd_disable_interrupts(adp); + crystalhd_clear_errors(adp); + crystalhd_clear_interrupts(adp); + + if (!crystalhd_put_in_reset(adp)) + BCMLOG_ERR("Failed to Put Link To Reset State\n"); + + reg = crystalhd_reg_rd(adp, PCIE_DLL_DATA_LINK_CONTROL); + reg |= ASPM_L1_ENABLE; + crystalhd_reg_wr(adp, PCIE_DLL_DATA_LINK_CONTROL, reg); + + /* Set PCI Clk Req */ + reg = crystalhd_reg_rd(adp, PCIE_CLK_REQ_REG); + reg |= PCI_CLK_REQ_ENABLE; + crystalhd_reg_wr(adp, PCIE_CLK_REQ_REG, reg); + + return true; +} + +static crystalhd_rx_dma_pkt *crystalhd_hw_alloc_rx_pkt(struct crystalhd_hw *hw) +{ + unsigned long flags = 0; + crystalhd_rx_dma_pkt *temp = NULL; + + if (!hw) + return NULL; + + spin_lock_irqsave(&hw->lock, flags); + temp = hw->rx_pkt_pool_head; + if (temp) { + hw->rx_pkt_pool_head = hw->rx_pkt_pool_head->next; + temp->dio_req = NULL; + temp->pkt_tag = 0; + temp->flags = 0; + } + spin_unlock_irqrestore(&hw->lock, flags); + + return temp; +} + +static void crystalhd_hw_free_rx_pkt(struct crystalhd_hw *hw, + crystalhd_rx_dma_pkt *pkt) +{ + unsigned long flags = 0; + + if (!hw || !pkt) + return; + + spin_lock_irqsave(&hw->lock, flags); + pkt->next = hw->rx_pkt_pool_head; + hw->rx_pkt_pool_head = pkt; + spin_unlock_irqrestore(&hw->lock, flags); +} + +/* + * Call back from TX - IOQ deletion. + * + * This routine will release the TX DMA rings allocated + * druing setup_dma rings interface. + * + * Memory is allocated per DMA ring basis. This is just + * a place holder to be able to create the dio queues. + */ +static void crystalhd_tx_desc_rel_call_back(void *context, void *data) +{ +} + +/* + * Rx Packet release callback.. + * + * Release All user mapped capture buffers and Our DMA packets + * back to our free pool. The actual cleanup of the DMA + * ring descriptors happen during dma ring release. + */ +static void crystalhd_rx_pkt_rel_call_back(void *context, void *data) +{ + struct crystalhd_hw *hw = (struct crystalhd_hw *)context; + crystalhd_rx_dma_pkt *pkt = (crystalhd_rx_dma_pkt *)data; + + if (!pkt || !hw) { + BCMLOG_ERR("Invalid arg - %p %p\n", hw, pkt); + return; + } + + if (pkt->dio_req) + crystalhd_unmap_dio(hw->adp, pkt->dio_req); + else + BCMLOG_ERR("Missing dio_req: 0x%x\n", pkt->pkt_tag); + + crystalhd_hw_free_rx_pkt(hw, pkt); +} + +#define crystalhd_hw_delete_ioq(adp, q) \ + if (q) { \ + crystalhd_delete_dioq(adp, q); \ + q = NULL; \ + } + +static void crystalhd_hw_delete_ioqs(struct crystalhd_hw *hw) +{ + if (!hw) + return; + + BCMLOG(BCMLOG_DBG, "Deleting IOQs \n"); + crystalhd_hw_delete_ioq(hw->adp, hw->tx_actq); + crystalhd_hw_delete_ioq(hw->adp, hw->tx_freeq); + crystalhd_hw_delete_ioq(hw->adp, hw->rx_actq); + crystalhd_hw_delete_ioq(hw->adp, hw->rx_freeq); + crystalhd_hw_delete_ioq(hw->adp, hw->rx_rdyq); +} + +#define crystalhd_hw_create_ioq(sts, hw, q, cb) \ +do { \ + sts = crystalhd_create_dioq(hw->adp, &q, cb, hw); \ + if (sts != BC_STS_SUCCESS) \ + goto hw_create_ioq_err; \ +} while (0) + +/* + * Create IOQs.. + * + * TX - Active & Free + * RX - Active, Ready and Free. + */ +static BC_STATUS crystalhd_hw_create_ioqs(struct crystalhd_hw *hw) +{ + BC_STATUS sts = BC_STS_SUCCESS; + + if (!hw) { + BCMLOG_ERR("Invalid Arg!!\n"); + return BC_STS_INV_ARG; + } + + crystalhd_hw_create_ioq(sts, hw, hw->tx_freeq, + crystalhd_tx_desc_rel_call_back); + crystalhd_hw_create_ioq(sts, hw, hw->tx_actq, + crystalhd_tx_desc_rel_call_back); + + crystalhd_hw_create_ioq(sts, hw, hw->rx_freeq, + crystalhd_rx_pkt_rel_call_back); + crystalhd_hw_create_ioq(sts, hw, hw->rx_rdyq, + crystalhd_rx_pkt_rel_call_back); + crystalhd_hw_create_ioq(sts, hw, hw->rx_actq, + crystalhd_rx_pkt_rel_call_back); + + return sts; + +hw_create_ioq_err: + crystalhd_hw_delete_ioqs(hw); + + return sts; +} + + +static bool crystalhd_code_in_full(struct crystalhd_adp *adp, uint32_t needed_sz, + bool b_188_byte_pkts, uint8_t flags) +{ + uint32_t base, end, writep, readp; + uint32_t cpbSize, cpbFullness, fifoSize; + + if (flags & 0x02) { /* ASF Bit is set */ + base = bc_dec_reg_rd(adp, REG_Dec_TsAudCDB2Base); + end = bc_dec_reg_rd(adp, REG_Dec_TsAudCDB2End); + writep = bc_dec_reg_rd(adp, REG_Dec_TsAudCDB2Wrptr); + readp = bc_dec_reg_rd(adp, REG_Dec_TsAudCDB2Rdptr); + } else if (b_188_byte_pkts) { /*Encrypted 188 byte packets*/ + base = bc_dec_reg_rd(adp, REG_Dec_TsUser0Base); + end = bc_dec_reg_rd(adp, REG_Dec_TsUser0End); + writep = bc_dec_reg_rd(adp, REG_Dec_TsUser0Wrptr); + readp = bc_dec_reg_rd(adp, REG_Dec_TsUser0Rdptr); + } else { + base = bc_dec_reg_rd(adp, REG_DecCA_RegCinBase); + end = bc_dec_reg_rd(adp, REG_DecCA_RegCinEnd); + writep = bc_dec_reg_rd(adp, REG_DecCA_RegCinWrPtr); + readp = bc_dec_reg_rd(adp, REG_DecCA_RegCinRdPtr); + } + + cpbSize = end - base; + if (writep >= readp) + cpbFullness = writep - readp; + else + cpbFullness = (end - base) - (readp - writep); + + fifoSize = cpbSize - cpbFullness; + + if (fifoSize < BC_INFIFO_THRESHOLD) + return true; + + if (needed_sz > (fifoSize - BC_INFIFO_THRESHOLD)) + return true; + + return false; +} + +static BC_STATUS crystalhd_hw_tx_req_complete(struct crystalhd_hw *hw, + uint32_t list_id, BC_STATUS cs) +{ + tx_dma_pkt *tx_req; + + if (!hw || !list_id) { + BCMLOG_ERR("Invalid Arg..\n"); + return BC_STS_INV_ARG; + } + + hw->pwr_lock--; + + tx_req = (tx_dma_pkt *)crystalhd_dioq_find_and_fetch(hw->tx_actq, list_id); + if (!tx_req) { + if (cs != BC_STS_IO_USER_ABORT) + BCMLOG_ERR("Find and Fetch Did not find req\n"); + return BC_STS_NO_DATA; + } + + if (tx_req->call_back) { + tx_req->call_back(tx_req->dio_req, tx_req->cb_event, cs); + tx_req->dio_req = NULL; + tx_req->cb_event = NULL; + tx_req->call_back = NULL; + } else { + BCMLOG(BCMLOG_DBG, "Missing Tx Callback - %X\n", + tx_req->list_tag); + } + + /* Now put back the tx_list back in FreeQ */ + tx_req->list_tag = 0; + + return crystalhd_dioq_add(hw->tx_freeq, tx_req, false, 0); +} + +static bool crystalhd_tx_list0_handler(struct crystalhd_hw *hw, uint32_t err_sts) +{ + uint32_t err_mask, tmp; + unsigned long flags = 0; + + err_mask = MISC1_TX_DMA_ERROR_STATUS_TX_L0_DESC_TX_ABORT_ERRORS_MASK | + MISC1_TX_DMA_ERROR_STATUS_TX_L0_DMA_DATA_TX_ABORT_ERRORS_MASK | + MISC1_TX_DMA_ERROR_STATUS_TX_L0_FIFO_FULL_ERRORS_MASK; + + if (!(err_sts & err_mask)) + return false; + + BCMLOG_ERR("Error on Tx-L0 %x \n", err_sts); + + tmp = err_mask; + + if (err_sts & MISC1_TX_DMA_ERROR_STATUS_TX_L0_FIFO_FULL_ERRORS_MASK) + tmp &= ~MISC1_TX_DMA_ERROR_STATUS_TX_L0_FIFO_FULL_ERRORS_MASK; + + if (tmp) { + spin_lock_irqsave(&hw->lock, flags); + /* reset list index.*/ + hw->tx_list_post_index = 0; + spin_unlock_irqrestore(&hw->lock, flags); + } + + tmp = err_sts & err_mask; + crystalhd_reg_wr(hw->adp, MISC1_TX_DMA_ERROR_STATUS, tmp); + + return true; +} + +static bool crystalhd_tx_list1_handler(struct crystalhd_hw *hw, uint32_t err_sts) +{ + uint32_t err_mask, tmp; + unsigned long flags = 0; + + err_mask = MISC1_TX_DMA_ERROR_STATUS_TX_L1_DESC_TX_ABORT_ERRORS_MASK | + MISC1_TX_DMA_ERROR_STATUS_TX_L1_DMA_DATA_TX_ABORT_ERRORS_MASK | + MISC1_TX_DMA_ERROR_STATUS_TX_L1_FIFO_FULL_ERRORS_MASK; + + if (!(err_sts & err_mask)) + return false; + + BCMLOG_ERR("Error on Tx-L1 %x \n", err_sts); + + tmp = err_mask; + + if (err_sts & MISC1_TX_DMA_ERROR_STATUS_TX_L1_FIFO_FULL_ERRORS_MASK) + tmp &= ~MISC1_TX_DMA_ERROR_STATUS_TX_L1_FIFO_FULL_ERRORS_MASK; + + if (tmp) { + spin_lock_irqsave(&hw->lock, flags); + /* reset list index.*/ + hw->tx_list_post_index = 0; + spin_unlock_irqrestore(&hw->lock, flags); + } + + tmp = err_sts & err_mask; + crystalhd_reg_wr(hw->adp, MISC1_TX_DMA_ERROR_STATUS, tmp); + + return true; +} + +static void crystalhd_tx_isr(struct crystalhd_hw *hw, uint32_t int_sts) +{ + uint32_t err_sts; + + if (int_sts & INTR_INTR_STATUS_L0_TX_DMA_DONE_INTR_MASK) + crystalhd_hw_tx_req_complete(hw, hw->tx_ioq_tag_seed + 0, + BC_STS_SUCCESS); + + if (int_sts & INTR_INTR_STATUS_L1_TX_DMA_DONE_INTR_MASK) + crystalhd_hw_tx_req_complete(hw, hw->tx_ioq_tag_seed + 1, + BC_STS_SUCCESS); + + if (!(int_sts & (INTR_INTR_STATUS_L0_TX_DMA_ERR_INTR_MASK | + INTR_INTR_STATUS_L1_TX_DMA_ERR_INTR_MASK))) { + /* No error mask set.. */ + return; + } + + /* Handle Tx errors. */ + err_sts = crystalhd_reg_rd(hw->adp, MISC1_TX_DMA_ERROR_STATUS); + + if (crystalhd_tx_list0_handler(hw, err_sts)) + crystalhd_hw_tx_req_complete(hw, hw->tx_ioq_tag_seed + 0, + BC_STS_ERROR); + + if (crystalhd_tx_list1_handler(hw, err_sts)) + crystalhd_hw_tx_req_complete(hw, hw->tx_ioq_tag_seed + 1, + BC_STS_ERROR); + + hw->stats.tx_errors++; +} + +static void crystalhd_hw_dump_desc(pdma_descriptor p_dma_desc, + uint32_t ul_desc_index, uint32_t cnt) +{ + uint32_t ix, ll = 0; + + if (!p_dma_desc || !cnt) + return; + + /* FIXME: jarod: perhaps a modparam desc_debug to enable this, rather than + * setting ll (log level, I presume) to non-zero? */ + if (!ll) + return; + + for (ix = ul_desc_index; ix < (ul_desc_index + cnt); ix++) { + BCMLOG(ll, "%s[%d] Buff[%x:%x] Next:[%x:%x] XferSz:%x Intr:%x,Last:%x\n", + ((p_dma_desc[ul_desc_index].dma_dir) ? "TDesc" : "RDesc"), + ul_desc_index, + p_dma_desc[ul_desc_index].buff_addr_high, + p_dma_desc[ul_desc_index].buff_addr_low, + p_dma_desc[ul_desc_index].next_desc_addr_high, + p_dma_desc[ul_desc_index].next_desc_addr_low, + p_dma_desc[ul_desc_index].xfer_size, + p_dma_desc[ul_desc_index].intr_enable, + p_dma_desc[ul_desc_index].last_rec_indicator); + } + +} + +static BC_STATUS crystalhd_hw_fill_desc(crystalhd_dio_req *ioreq, + dma_descriptor *desc, + dma_addr_t desc_paddr_base, + uint32_t sg_cnt, uint32_t sg_st_ix, + uint32_t sg_st_off, uint32_t xfr_sz) +{ + uint32_t count = 0, ix = 0, sg_ix = 0, len = 0, last_desc_ix = 0; + dma_addr_t desc_phy_addr = desc_paddr_base; + addr_64 addr_temp; + + if (!ioreq || !desc || !desc_paddr_base || !xfr_sz || + (!sg_cnt && !ioreq->uinfo.dir_tx)) { + BCMLOG_ERR("Invalid Args\n"); + return BC_STS_INV_ARG; + } + + for (ix = 0; ix < sg_cnt; ix++) { + + /* Setup SGLE index. */ + sg_ix = ix + sg_st_ix; + + /* Get SGLE length */ + len = crystalhd_get_sgle_len(ioreq, sg_ix); + if (len % 4) { + BCMLOG_ERR(" len in sg %d %d %d\n", len, sg_ix, sg_cnt); + return BC_STS_NOT_IMPL; + } + /* Setup DMA desc with Phy addr & Length at current index. */ + addr_temp.full_addr = crystalhd_get_sgle_paddr(ioreq, sg_ix); + if (sg_ix == sg_st_ix) { + addr_temp.full_addr += sg_st_off; + len -= sg_st_off; + } + memset(&desc[ix], 0, sizeof(desc[ix])); + desc[ix].buff_addr_low = addr_temp.low_part; + desc[ix].buff_addr_high = addr_temp.high_part; + desc[ix].dma_dir = ioreq->uinfo.dir_tx; + + /* Chain DMA descriptor. */ + addr_temp.full_addr = desc_phy_addr + sizeof(dma_descriptor); + desc[ix].next_desc_addr_low = addr_temp.low_part; + desc[ix].next_desc_addr_high = addr_temp.high_part; + + if ((count + len) > xfr_sz) + len = xfr_sz - count; + + /* Debug.. */ + if ((!len) || (len > crystalhd_get_sgle_len(ioreq, sg_ix))) { + BCMLOG_ERR("inv-len(%x) Ix(%d) count:%x xfr_sz:%x sg_cnt:%d\n", + len, ix, count, xfr_sz, sg_cnt); + return BC_STS_ERROR; + } + /* Length expects Multiple of 4 */ + desc[ix].xfer_size = (len / 4); + + crystalhd_hw_dump_desc(desc, ix, 1); + + count += len; + desc_phy_addr += sizeof(dma_descriptor); + } + + last_desc_ix = ix - 1; + + if (ioreq->fb_size) { + memset(&desc[ix], 0, sizeof(desc[ix])); + addr_temp.full_addr = ioreq->fb_pa; + desc[ix].buff_addr_low = addr_temp.low_part; + desc[ix].buff_addr_high = addr_temp.high_part; + desc[ix].dma_dir = ioreq->uinfo.dir_tx; + desc[ix].xfer_size = 1; + desc[ix].fill_bytes = 4 - ioreq->fb_size; + count += ioreq->fb_size; + last_desc_ix++; + } + + /* setup last descriptor..*/ + desc[last_desc_ix].last_rec_indicator = 1; + desc[last_desc_ix].next_desc_addr_low = 0; + desc[last_desc_ix].next_desc_addr_high = 0; + desc[last_desc_ix].intr_enable = 1; + + crystalhd_hw_dump_desc(desc, last_desc_ix, 1); + + if (count != xfr_sz) { + BCMLOG_ERR("interal error sz curr:%x exp:%x\n", count, xfr_sz); + return BC_STS_ERROR; + } + + return BC_STS_SUCCESS; +} + +static BC_STATUS crystalhd_xlat_sgl_to_dma_desc(crystalhd_dio_req *ioreq, + pdma_desc_mem pdesc_mem, + uint32_t *uv_desc_index) +{ + dma_descriptor *desc = NULL; + dma_addr_t desc_paddr_base = 0; + uint32_t sg_cnt = 0, sg_st_ix = 0, sg_st_off = 0; + uint32_t xfr_sz = 0; + BC_STATUS sts = BC_STS_SUCCESS; + + /* Check params.. */ + if (!ioreq || !pdesc_mem || !uv_desc_index) { + BCMLOG_ERR("Invalid Args\n"); + return BC_STS_INV_ARG; + } + + if (!pdesc_mem->sz || !pdesc_mem->pdma_desc_start || + !ioreq->sg || (!ioreq->sg_cnt && !ioreq->uinfo.dir_tx)) { + BCMLOG_ERR("Invalid Args\n"); + return BC_STS_INV_ARG; + } + + if ((ioreq->uinfo.dir_tx) && (ioreq->uinfo.uv_offset)) { + BCMLOG_ERR("UV offset for TX??\n"); + return BC_STS_INV_ARG; + + } + + desc = pdesc_mem->pdma_desc_start; + desc_paddr_base = pdesc_mem->phy_addr; + + if (ioreq->uinfo.dir_tx || (ioreq->uinfo.uv_offset == 0)) { + sg_cnt = ioreq->sg_cnt; + xfr_sz = ioreq->uinfo.xfr_len; + } else { + sg_cnt = ioreq->uinfo.uv_sg_ix + 1; + xfr_sz = ioreq->uinfo.uv_offset; + } + + sts = crystalhd_hw_fill_desc(ioreq, desc, desc_paddr_base, sg_cnt, + sg_st_ix, sg_st_off, xfr_sz); + + if ((sts != BC_STS_SUCCESS) || !ioreq->uinfo.uv_offset) + return sts; + + /* Prepare for UV mapping.. */ + desc = &pdesc_mem->pdma_desc_start[sg_cnt]; + desc_paddr_base = pdesc_mem->phy_addr + + (sg_cnt * sizeof(dma_descriptor)); + + /* Done with desc addr.. now update sg stuff.*/ + sg_cnt = ioreq->sg_cnt - ioreq->uinfo.uv_sg_ix; + xfr_sz = ioreq->uinfo.xfr_len - ioreq->uinfo.uv_offset; + sg_st_ix = ioreq->uinfo.uv_sg_ix; + sg_st_off = ioreq->uinfo.uv_sg_off; + + sts = crystalhd_hw_fill_desc(ioreq, desc, desc_paddr_base, sg_cnt, + sg_st_ix, sg_st_off, xfr_sz); + if (sts != BC_STS_SUCCESS) + return sts; + + *uv_desc_index = sg_st_ix; + + return sts; +} + +static void crystalhd_start_tx_dma_engine(struct crystalhd_hw *hw) +{ + uint32_t dma_cntrl; + + dma_cntrl = crystalhd_reg_rd(hw->adp, MISC1_TX_SW_DESC_LIST_CTRL_STS); + if (!(dma_cntrl & DMA_START_BIT)) { + dma_cntrl |= DMA_START_BIT; + crystalhd_reg_wr(hw->adp, MISC1_TX_SW_DESC_LIST_CTRL_STS, + dma_cntrl); + } + + return; +} + +/* _CHECK_THIS_ + * + * Verify if the Stop generates a completion interrupt or not. + * if it does not generate an interrupt, then add polling here. + */ +static BC_STATUS crystalhd_stop_tx_dma_engine(struct crystalhd_hw *hw) +{ + uint32_t dma_cntrl, cnt = 30; + uint32_t l1 = 1, l2 = 1; + unsigned long flags = 0; + + dma_cntrl = crystalhd_reg_rd(hw->adp, MISC1_TX_SW_DESC_LIST_CTRL_STS); + + BCMLOG(BCMLOG_DBG, "Stopping TX DMA Engine..\n"); + + /* FIXME: jarod: invert dma_ctrl and check bit? or are there missing parens? */ + if (!dma_cntrl & DMA_START_BIT) { + BCMLOG(BCMLOG_DBG, "Already Stopped\n"); + return BC_STS_SUCCESS; + } + + crystalhd_disable_interrupts(hw->adp); + + /* Issue stop to HW */ + /* This bit when set gave problems. Please check*/ + dma_cntrl &= ~DMA_START_BIT; + crystalhd_reg_wr(hw->adp, MISC1_TX_SW_DESC_LIST_CTRL_STS, dma_cntrl); + + BCMLOG(BCMLOG_DBG, "Cleared the DMA Start bit\n"); + + /* Poll for 3seconds (30 * 100ms) on both the lists..*/ + while ((l1 || l2) && cnt) { + + if (l1) { + l1 = crystalhd_reg_rd(hw->adp, MISC1_TX_FIRST_DESC_L_ADDR_LIST0); + l1 &= DMA_START_BIT; + } + + if (l2) { + l2 = crystalhd_reg_rd(hw->adp, MISC1_TX_FIRST_DESC_L_ADDR_LIST1); + l2 &= DMA_START_BIT; + } + + msleep_interruptible(100); + + cnt--; + } + + if (!cnt) { + BCMLOG_ERR("Failed to stop TX DMA.. l1 %d, l2 %d\n", l1, l2); + crystalhd_enable_interrupts(hw->adp); + return BC_STS_ERROR; + } + + spin_lock_irqsave(&hw->lock, flags); + hw->tx_list_post_index = 0; + spin_unlock_irqrestore(&hw->lock, flags); + BCMLOG(BCMLOG_DBG, "stopped TX DMA..\n"); + crystalhd_enable_interrupts(hw->adp); + + return BC_STS_SUCCESS; +} + +static uint32_t crystalhd_get_pib_avail_cnt(struct crystalhd_hw *hw) +{ + /* + * Position of the PIB Entries can be found at + * 0th and the 1st location of the Circular list. + */ + uint32_t Q_addr; + uint32_t pib_cnt, r_offset, w_offset; + + Q_addr = hw->pib_del_Q_addr; + + /* Get the Read Pointer */ + crystalhd_mem_rd(hw->adp, Q_addr, 1, &r_offset); + + /* Get the Write Pointer */ + crystalhd_mem_rd(hw->adp, Q_addr + sizeof(uint32_t), 1, &w_offset); + + if (r_offset == w_offset) + return 0; /* Queue is empty */ + + if (w_offset > r_offset) + pib_cnt = w_offset - r_offset; + else + pib_cnt = (w_offset + MAX_PIB_Q_DEPTH) - + (r_offset + MIN_PIB_Q_DEPTH); + + if (pib_cnt > MAX_PIB_Q_DEPTH) { + BCMLOG_ERR("Invalid PIB Count (%u)\n", pib_cnt); + return 0; + } + + return pib_cnt; +} + +static uint32_t crystalhd_get_addr_from_pib_Q(struct crystalhd_hw *hw) +{ + uint32_t Q_addr; + uint32_t addr_entry, r_offset, w_offset; + + Q_addr = hw->pib_del_Q_addr; + + /* Get the Read Pointer 0Th Location is Read Pointer */ + crystalhd_mem_rd(hw->adp, Q_addr, 1, &r_offset); + + /* Get the Write Pointer 1st Location is Write pointer */ + crystalhd_mem_rd(hw->adp, Q_addr + sizeof(uint32_t), 1, &w_offset); + + /* Queue is empty */ + if (r_offset == w_offset) + return 0; + + if ((r_offset < MIN_PIB_Q_DEPTH) || (r_offset >= MAX_PIB_Q_DEPTH)) + return 0; + + /* Get the Actual Address of the PIB */ + crystalhd_mem_rd(hw->adp, Q_addr + (r_offset * sizeof(uint32_t)), + 1, &addr_entry); + + /* Increment the Read Pointer */ + r_offset++; + + if (MAX_PIB_Q_DEPTH == r_offset) + r_offset = MIN_PIB_Q_DEPTH; + + /* Write back the read pointer to It's Location */ + crystalhd_mem_wr(hw->adp, Q_addr, 1, &r_offset); + + return addr_entry; +} + +static bool crystalhd_rel_addr_to_pib_Q(struct crystalhd_hw *hw, uint32_t addr_to_rel) +{ + uint32_t Q_addr; + uint32_t r_offset, w_offset, n_offset; + + Q_addr = hw->pib_rel_Q_addr; + + /* Get the Read Pointer */ + crystalhd_mem_rd(hw->adp, Q_addr, 1, &r_offset); + + /* Get the Write Pointer */ + crystalhd_mem_rd(hw->adp, Q_addr + sizeof(uint32_t), 1, &w_offset); + + if ((r_offset < MIN_PIB_Q_DEPTH) || + (r_offset >= MAX_PIB_Q_DEPTH)) + return false; + + n_offset = w_offset + 1; + + if (MAX_PIB_Q_DEPTH == n_offset) + n_offset = MIN_PIB_Q_DEPTH; + + if (r_offset == n_offset) + return false; /* should never happen */ + + /* Write the DRAM ADDR to the Queue at Next Offset */ + crystalhd_mem_wr(hw->adp, Q_addr + (w_offset * sizeof(uint32_t)), + 1, &addr_to_rel); + + /* Put the New value of the write pointer in Queue */ + crystalhd_mem_wr(hw->adp, Q_addr + sizeof(uint32_t), 1, &n_offset); + + return true; +} + +static void cpy_pib_to_app(C011_PIB *src_pib, BC_PIC_INFO_BLOCK *dst_pib) +{ + if (!src_pib || !dst_pib) { + BCMLOG_ERR("Invalid Arguments\n"); + return; + } + + dst_pib->timeStamp = 0; + dst_pib->picture_number = src_pib->ppb.picture_number; + dst_pib->width = src_pib->ppb.width; + dst_pib->height = src_pib->ppb.height; + dst_pib->chroma_format = src_pib->ppb.chroma_format; + dst_pib->pulldown = src_pib->ppb.pulldown; + dst_pib->flags = src_pib->ppb.flags; + dst_pib->sess_num = src_pib->ptsStcOffset; + dst_pib->aspect_ratio = src_pib->ppb.aspect_ratio; + dst_pib->colour_primaries = src_pib->ppb.colour_primaries; + dst_pib->picture_meta_payload = src_pib->ppb.picture_meta_payload; + dst_pib->frame_rate = src_pib->resolution ; + return; +} + +static void crystalhd_hw_proc_pib(struct crystalhd_hw *hw) +{ + unsigned int cnt; + C011_PIB src_pib; + uint32_t pib_addr, pib_cnt; + BC_PIC_INFO_BLOCK *AppPib; + crystalhd_rx_dma_pkt *rx_pkt = NULL; + + pib_cnt = crystalhd_get_pib_avail_cnt(hw); + + if (!pib_cnt) + return; + + for (cnt = 0; cnt < pib_cnt; cnt++) { + + pib_addr = crystalhd_get_addr_from_pib_Q(hw); + crystalhd_mem_rd(hw->adp, pib_addr, sizeof(C011_PIB) / 4, + (uint32_t *)&src_pib); + + if (src_pib.bFormatChange) { + rx_pkt = (crystalhd_rx_dma_pkt *)crystalhd_dioq_fetch(hw->rx_freeq); + if (!rx_pkt) + return; + rx_pkt->flags = 0; + rx_pkt->flags |= COMP_FLAG_PIB_VALID | COMP_FLAG_FMT_CHANGE; + AppPib = &rx_pkt->pib; + cpy_pib_to_app(&src_pib, AppPib); + + BCMLOG(BCMLOG_DBG, + "App PIB:%x %x %x %x %x %x %x %x %x %x\n", + rx_pkt->pib.picture_number, + rx_pkt->pib.aspect_ratio, + rx_pkt->pib.chroma_format, + rx_pkt->pib.colour_primaries, + rx_pkt->pib.frame_rate, + rx_pkt->pib.height, + rx_pkt->pib.height, + rx_pkt->pib.n_drop, + rx_pkt->pib.pulldown, + rx_pkt->pib.ycom); + + crystalhd_dioq_add(hw->rx_rdyq, (void *)rx_pkt, true, rx_pkt->pkt_tag); + + } + + crystalhd_rel_addr_to_pib_Q(hw, pib_addr); + } +} + +static void crystalhd_start_rx_dma_engine(struct crystalhd_hw *hw) +{ + uint32_t dma_cntrl; + + dma_cntrl = crystalhd_reg_rd(hw->adp, MISC1_Y_RX_SW_DESC_LIST_CTRL_STS); + if (!(dma_cntrl & DMA_START_BIT)) { + dma_cntrl |= DMA_START_BIT; + crystalhd_reg_wr(hw->adp, MISC1_Y_RX_SW_DESC_LIST_CTRL_STS, dma_cntrl); + } + + dma_cntrl = crystalhd_reg_rd(hw->adp, MISC1_UV_RX_SW_DESC_LIST_CTRL_STS); + if (!(dma_cntrl & DMA_START_BIT)) { + dma_cntrl |= DMA_START_BIT; + crystalhd_reg_wr(hw->adp, MISC1_UV_RX_SW_DESC_LIST_CTRL_STS, dma_cntrl); + } + + return; +} + +static void crystalhd_stop_rx_dma_engine(struct crystalhd_hw *hw) +{ + uint32_t dma_cntrl = 0, count = 30; + uint32_t l0y = 1, l0uv = 1, l1y = 1, l1uv = 1; + + dma_cntrl = crystalhd_reg_rd(hw->adp, MISC1_Y_RX_SW_DESC_LIST_CTRL_STS); + if ((dma_cntrl & DMA_START_BIT)) { + dma_cntrl &= ~DMA_START_BIT; + crystalhd_reg_wr(hw->adp, MISC1_Y_RX_SW_DESC_LIST_CTRL_STS, dma_cntrl); + } + + dma_cntrl = crystalhd_reg_rd(hw->adp, MISC1_UV_RX_SW_DESC_LIST_CTRL_STS); + if ((dma_cntrl & DMA_START_BIT)) { + dma_cntrl &= ~DMA_START_BIT; + crystalhd_reg_wr(hw->adp, MISC1_UV_RX_SW_DESC_LIST_CTRL_STS, dma_cntrl); + } + + /* Poll for 3seconds (30 * 100ms) on both the lists..*/ + while ((l0y || l0uv || l1y || l1uv) && count) { + + if (l0y) { + l0y = crystalhd_reg_rd(hw->adp, MISC1_Y_RX_FIRST_DESC_L_ADDR_LIST0); + l0y &= DMA_START_BIT; + if (!l0y) { + hw->rx_list_sts[0] &= ~rx_waiting_y_intr; + } + } + + if (l1y) { + l1y = crystalhd_reg_rd(hw->adp, MISC1_Y_RX_FIRST_DESC_L_ADDR_LIST1); + l1y &= DMA_START_BIT; + if (!l1y) { + hw->rx_list_sts[1] &= ~rx_waiting_y_intr; + } + } + + if (l0uv) { + l0uv = crystalhd_reg_rd(hw->adp, MISC1_UV_RX_FIRST_DESC_L_ADDR_LIST0); + l0uv &= DMA_START_BIT; + if (!l0uv) { + hw->rx_list_sts[0] &= ~rx_waiting_uv_intr; + } + } + + if (l1uv) { + l1uv = crystalhd_reg_rd(hw->adp, MISC1_UV_RX_FIRST_DESC_L_ADDR_LIST1); + l1uv &= DMA_START_BIT; + if (!l1uv) { + hw->rx_list_sts[1] &= ~rx_waiting_uv_intr; + } + } + msleep_interruptible(100); + count--; + } + + hw->rx_list_post_index = 0; + + BCMLOG(BCMLOG_SSTEP, "Capture Stop: %d List0:Sts:%x List1:Sts:%x\n", + count, hw->rx_list_sts[0], hw->rx_list_sts[1]); +} + +static BC_STATUS crystalhd_hw_prog_rxdma(struct crystalhd_hw *hw, crystalhd_rx_dma_pkt *rx_pkt) +{ + uint32_t y_low_addr_reg, y_high_addr_reg; + uint32_t uv_low_addr_reg, uv_high_addr_reg; + addr_64 desc_addr; + unsigned long flags; + + if (!hw || !rx_pkt) { + BCMLOG_ERR("Invalid Arguments\n"); + return BC_STS_INV_ARG; + } + + if (hw->rx_list_post_index >= DMA_ENGINE_CNT) { + BCMLOG_ERR("List Out Of bounds %x\n", hw->rx_list_post_index); + return BC_STS_INV_ARG; + } + + spin_lock_irqsave(&hw->rx_lock, flags); + /* FIXME: jarod: sts_free is an enum for 0, in crystalhd_hw.h... yuk... */ + if (sts_free != hw->rx_list_sts[hw->rx_list_post_index]) { + spin_unlock_irqrestore(&hw->rx_lock, flags); + return BC_STS_BUSY; + } + + if (!hw->rx_list_post_index) { + y_low_addr_reg = MISC1_Y_RX_FIRST_DESC_L_ADDR_LIST0; + y_high_addr_reg = MISC1_Y_RX_FIRST_DESC_U_ADDR_LIST0; + uv_low_addr_reg = MISC1_UV_RX_FIRST_DESC_L_ADDR_LIST0; + uv_high_addr_reg = MISC1_UV_RX_FIRST_DESC_U_ADDR_LIST0; + } else { + y_low_addr_reg = MISC1_Y_RX_FIRST_DESC_L_ADDR_LIST1; + y_high_addr_reg = MISC1_Y_RX_FIRST_DESC_U_ADDR_LIST1; + uv_low_addr_reg = MISC1_UV_RX_FIRST_DESC_L_ADDR_LIST1; + uv_high_addr_reg = MISC1_UV_RX_FIRST_DESC_U_ADDR_LIST1; + } + rx_pkt->pkt_tag = hw->rx_pkt_tag_seed + hw->rx_list_post_index; + hw->rx_list_sts[hw->rx_list_post_index] |= rx_waiting_y_intr; + if (rx_pkt->uv_phy_addr) + hw->rx_list_sts[hw->rx_list_post_index] |= rx_waiting_uv_intr; + hw->rx_list_post_index = (hw->rx_list_post_index + 1) % DMA_ENGINE_CNT; + spin_unlock_irqrestore(&hw->rx_lock, flags); + + crystalhd_dioq_add(hw->rx_actq, (void *)rx_pkt, false, rx_pkt->pkt_tag); + + crystalhd_start_rx_dma_engine(hw); + /* Program the Y descriptor */ + desc_addr.full_addr = rx_pkt->desc_mem.phy_addr; + crystalhd_reg_wr(hw->adp, y_high_addr_reg, desc_addr.high_part); + crystalhd_reg_wr(hw->adp, y_low_addr_reg, desc_addr.low_part | 0x01); + + if (rx_pkt->uv_phy_addr) { + /* Program the UV descriptor */ + desc_addr.full_addr = rx_pkt->uv_phy_addr; + crystalhd_reg_wr(hw->adp, uv_high_addr_reg, desc_addr.high_part); + crystalhd_reg_wr(hw->adp, uv_low_addr_reg, desc_addr.low_part | 0x01); + } + + return BC_STS_SUCCESS; +} + +static BC_STATUS crystalhd_hw_post_cap_buff(struct crystalhd_hw *hw, + crystalhd_rx_dma_pkt *rx_pkt) +{ + BC_STATUS sts = crystalhd_hw_prog_rxdma(hw, rx_pkt); + + if (sts == BC_STS_BUSY) + crystalhd_dioq_add(hw->rx_freeq, (void *)rx_pkt, + false, rx_pkt->pkt_tag); + + return sts; +} + +static void crystalhd_get_dnsz(struct crystalhd_hw *hw, uint32_t list_index, + uint32_t *y_dw_dnsz, uint32_t *uv_dw_dnsz) +{ + uint32_t y_dn_sz_reg, uv_dn_sz_reg; + + if (!list_index) { + y_dn_sz_reg = MISC1_Y_RX_LIST0_CUR_BYTE_CNT; + uv_dn_sz_reg = MISC1_UV_RX_LIST0_CUR_BYTE_CNT; + } else { + y_dn_sz_reg = MISC1_Y_RX_LIST1_CUR_BYTE_CNT; + uv_dn_sz_reg = MISC1_UV_RX_LIST1_CUR_BYTE_CNT; + } + + *y_dw_dnsz = crystalhd_reg_rd(hw->adp, y_dn_sz_reg); + *uv_dw_dnsz = crystalhd_reg_rd(hw->adp, uv_dn_sz_reg); +} + +/* + * This function should be called only after making sure that the two DMA + * lists are free. This function does not check if DMA's are active, before + * turning off the DMA. + */ +static void crystalhd_hw_finalize_pause(struct crystalhd_hw *hw) +{ + uint32_t dma_cntrl, aspm; + + hw->stop_pending = 0; + + dma_cntrl = crystalhd_reg_rd(hw->adp, MISC1_Y_RX_SW_DESC_LIST_CTRL_STS); + if (dma_cntrl & DMA_START_BIT) { + dma_cntrl &= ~DMA_START_BIT; + crystalhd_reg_wr(hw->adp, MISC1_Y_RX_SW_DESC_LIST_CTRL_STS, dma_cntrl); + } + + dma_cntrl = crystalhd_reg_rd(hw->adp, MISC1_UV_RX_SW_DESC_LIST_CTRL_STS); + if (dma_cntrl & DMA_START_BIT) { + dma_cntrl &= ~DMA_START_BIT; + crystalhd_reg_wr(hw->adp, MISC1_UV_RX_SW_DESC_LIST_CTRL_STS, dma_cntrl); + } + hw->rx_list_post_index = 0; + + aspm = crystalhd_reg_rd(hw->adp, PCIE_DLL_DATA_LINK_CONTROL); + aspm |= ASPM_L1_ENABLE; + /* NAREN BCMLOG(BCMLOG_INFO, "aspm on\n"); */ + crystalhd_reg_wr(hw->adp, PCIE_DLL_DATA_LINK_CONTROL, aspm); +} + +static BC_STATUS crystalhd_rx_pkt_done(struct crystalhd_hw *hw, uint32_t list_index, + BC_STATUS comp_sts) +{ + crystalhd_rx_dma_pkt *rx_pkt = NULL; + uint32_t y_dw_dnsz, uv_dw_dnsz; + BC_STATUS sts = BC_STS_SUCCESS; + + if (!hw || list_index >= DMA_ENGINE_CNT) { + BCMLOG_ERR("Invalid Arguments\n"); + return BC_STS_INV_ARG; + } + + rx_pkt = crystalhd_dioq_find_and_fetch(hw->rx_actq, + hw->rx_pkt_tag_seed + list_index); + if (!rx_pkt) { + BCMLOG_ERR("Act-Q:PostIx:%x L0Sts:%x L1Sts:%x current L:%x tag:%x comp:%x\n", + hw->rx_list_post_index, hw->rx_list_sts[0], + hw->rx_list_sts[1], list_index, + hw->rx_pkt_tag_seed + list_index, comp_sts); + return BC_STS_INV_ARG; + } + + if (comp_sts == BC_STS_SUCCESS) { + crystalhd_get_dnsz(hw, list_index, &y_dw_dnsz, &uv_dw_dnsz); + rx_pkt->dio_req->uinfo.y_done_sz = y_dw_dnsz; + rx_pkt->flags = COMP_FLAG_DATA_VALID; + if (rx_pkt->uv_phy_addr) + rx_pkt->dio_req->uinfo.uv_done_sz = uv_dw_dnsz; + crystalhd_dioq_add(hw->rx_rdyq, rx_pkt, true, + hw->rx_pkt_tag_seed + list_index); + return sts; + } + + /* Check if we can post this DIO again. */ + return crystalhd_hw_post_cap_buff(hw, rx_pkt); +} + +static bool crystalhd_rx_list0_handler(struct crystalhd_hw *hw, uint32_t int_sts, + uint32_t y_err_sts, uint32_t uv_err_sts) +{ + uint32_t tmp; + list_sts tmp_lsts; + + if (!(y_err_sts & GET_Y0_ERR_MSK) && !(uv_err_sts & GET_UV0_ERR_MSK)) + return false; + + tmp_lsts = hw->rx_list_sts[0]; + + /* Y0 - DMA */ + tmp = y_err_sts & GET_Y0_ERR_MSK; + if (int_sts & INTR_INTR_STATUS_L0_Y_RX_DMA_DONE_INTR_MASK) + hw->rx_list_sts[0] &= ~rx_waiting_y_intr; + + if (y_err_sts & MISC1_Y_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_MASK) { + hw->rx_list_sts[0] &= ~rx_waiting_y_intr; + tmp &= ~MISC1_Y_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_MASK; + } + + if (y_err_sts & MISC1_Y_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_MASK) { + hw->rx_list_sts[0] &= ~rx_y_mask; + hw->rx_list_sts[0] |= rx_y_error; + tmp &= ~MISC1_Y_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_MASK; + } + + if (tmp) { + hw->rx_list_sts[0] &= ~rx_y_mask; + hw->rx_list_sts[0] |= rx_y_error; + hw->rx_list_post_index = 0; + } + + /* UV0 - DMA */ + tmp = uv_err_sts & GET_UV0_ERR_MSK; + if (int_sts & INTR_INTR_STATUS_L0_UV_RX_DMA_DONE_INTR_MASK) + hw->rx_list_sts[0] &= ~rx_waiting_uv_intr; + + if (uv_err_sts & MISC1_UV_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_MASK) { + hw->rx_list_sts[0] &= ~rx_waiting_uv_intr; + tmp &= ~MISC1_UV_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_MASK; + } + + if (uv_err_sts & MISC1_UV_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_MASK) { + hw->rx_list_sts[0] &= ~rx_uv_mask; + hw->rx_list_sts[0] |= rx_uv_error; + tmp &= ~MISC1_UV_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_MASK; + } + + if (tmp) { + hw->rx_list_sts[0] &= ~rx_uv_mask; + hw->rx_list_sts[0] |= rx_uv_error; + hw->rx_list_post_index = 0; + } + + if (y_err_sts & GET_Y0_ERR_MSK) { + tmp = y_err_sts & GET_Y0_ERR_MSK; + crystalhd_reg_wr(hw->adp, MISC1_Y_RX_ERROR_STATUS, tmp); + } + + if (uv_err_sts & GET_UV0_ERR_MSK) { + tmp = uv_err_sts & GET_UV0_ERR_MSK; + crystalhd_reg_wr(hw->adp, MISC1_UV_RX_ERROR_STATUS, tmp); + } + + return (tmp_lsts != hw->rx_list_sts[0]); +} + +static bool crystalhd_rx_list1_handler(struct crystalhd_hw *hw, uint32_t int_sts, + uint32_t y_err_sts, uint32_t uv_err_sts) +{ + uint32_t tmp; + list_sts tmp_lsts; + + if (!(y_err_sts & GET_Y1_ERR_MSK) && !(uv_err_sts & GET_UV1_ERR_MSK)) + return false; + + tmp_lsts = hw->rx_list_sts[1]; + + /* Y1 - DMA */ + tmp = y_err_sts & GET_Y1_ERR_MSK; + if (int_sts & INTR_INTR_STATUS_L1_Y_RX_DMA_DONE_INTR_MASK) + hw->rx_list_sts[1] &= ~rx_waiting_y_intr; + + if (y_err_sts & MISC1_Y_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_MASK) { + hw->rx_list_sts[1] &= ~rx_waiting_y_intr; + tmp &= ~MISC1_Y_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_MASK; + } + + if (y_err_sts & MISC1_Y_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_MASK) { + /* Add retry-support..*/ + hw->rx_list_sts[1] &= ~rx_y_mask; + hw->rx_list_sts[1] |= rx_y_error; + tmp &= ~MISC1_Y_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_MASK; + } + + if (tmp) { + hw->rx_list_sts[1] &= ~rx_y_mask; + hw->rx_list_sts[1] |= rx_y_error; + hw->rx_list_post_index = 0; + } + + /* UV1 - DMA */ + tmp = uv_err_sts & GET_UV1_ERR_MSK; + if (int_sts & INTR_INTR_STATUS_L1_UV_RX_DMA_DONE_INTR_MASK) { + hw->rx_list_sts[1] &= ~rx_waiting_uv_intr; + } + + if (uv_err_sts & MISC1_UV_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_MASK) { + hw->rx_list_sts[1] &= ~rx_waiting_uv_intr; + tmp &= ~MISC1_UV_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_MASK; + } + + if (uv_err_sts & MISC1_UV_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_MASK) { + /* Add retry-support*/ + hw->rx_list_sts[1] &= ~rx_uv_mask; + hw->rx_list_sts[1] |= rx_uv_error; + tmp &= ~MISC1_UV_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_MASK; + } + + if (tmp) { + hw->rx_list_sts[1] &= ~rx_uv_mask; + hw->rx_list_sts[1] |= rx_uv_error; + hw->rx_list_post_index = 0; + } + + if (y_err_sts & GET_Y1_ERR_MSK) { + tmp = y_err_sts & GET_Y1_ERR_MSK; + crystalhd_reg_wr(hw->adp, MISC1_Y_RX_ERROR_STATUS, tmp); + } + + if (uv_err_sts & GET_UV1_ERR_MSK) { + tmp = uv_err_sts & GET_UV1_ERR_MSK; + crystalhd_reg_wr(hw->adp, MISC1_UV_RX_ERROR_STATUS, tmp); + } + + return (tmp_lsts != hw->rx_list_sts[1]); +} + + +static void crystalhd_rx_isr(struct crystalhd_hw *hw, uint32_t intr_sts) +{ + unsigned long flags; + uint32_t i, list_avail = 0; + BC_STATUS comp_sts = BC_STS_NO_DATA; + uint32_t y_err_sts, uv_err_sts, y_dn_sz = 0, uv_dn_sz = 0; + bool ret = 0; + + if (!hw) { + BCMLOG_ERR("Invalid Arguments\n"); + return; + } + + if (!(intr_sts & GET_RX_INTR_MASK)) + return; + + y_err_sts = crystalhd_reg_rd(hw->adp, MISC1_Y_RX_ERROR_STATUS); + uv_err_sts = crystalhd_reg_rd(hw->adp, MISC1_UV_RX_ERROR_STATUS); + + for (i = 0; i < DMA_ENGINE_CNT; i++) { + /* Update States..*/ + spin_lock_irqsave(&hw->rx_lock, flags); + if (i == 0) + ret = crystalhd_rx_list0_handler(hw, intr_sts, y_err_sts, uv_err_sts); + else + ret = crystalhd_rx_list1_handler(hw, intr_sts, y_err_sts, uv_err_sts); + if (ret) { + switch (hw->rx_list_sts[i]) { + case sts_free: + comp_sts = BC_STS_SUCCESS; + list_avail = 1; + break; + case rx_y_error: + case rx_uv_error: + case rx_sts_error: + /* We got error on both or Y or uv. */ + hw->stats.rx_errors++; + crystalhd_get_dnsz(hw, i, &y_dn_sz, &uv_dn_sz); + /* FIXME: jarod: this is where my mini pci-e card is tripping up */ + BCMLOG(BCMLOG_DBG, "list_index:%x rx[%d] Y:%x " + "UV:%x Int:%x YDnSz:%x UVDnSz:%x\n", + i, hw->stats.rx_errors, y_err_sts, + uv_err_sts, intr_sts, y_dn_sz, uv_dn_sz); + hw->rx_list_sts[i] = sts_free; + comp_sts = BC_STS_ERROR; + break; + default: + /* Wait for completion..*/ + comp_sts = BC_STS_NO_DATA; + break; + } + } + spin_unlock_irqrestore(&hw->rx_lock, flags); + + /* handle completion...*/ + if (comp_sts != BC_STS_NO_DATA) { + crystalhd_rx_pkt_done(hw, i, comp_sts); + comp_sts = BC_STS_NO_DATA; + } + } + + if (list_avail) { + if (hw->stop_pending) { + if ((hw->rx_list_sts[0] == sts_free) && + (hw->rx_list_sts[1] == sts_free)) + crystalhd_hw_finalize_pause(hw); + } else { + crystalhd_hw_start_capture(hw); + } + } +} + +static BC_STATUS crystalhd_fw_cmd_post_proc(struct crystalhd_hw *hw, + BC_FW_CMD *fw_cmd) +{ + BC_STATUS sts = BC_STS_SUCCESS; + DecRspChannelStartVideo *st_rsp = NULL; + + switch (fw_cmd->cmd[0]) { + case eCMD_C011_DEC_CHAN_START_VIDEO: + st_rsp = (DecRspChannelStartVideo *)fw_cmd->rsp; + hw->pib_del_Q_addr = st_rsp->picInfoDeliveryQ; + hw->pib_rel_Q_addr = st_rsp->picInfoReleaseQ; + BCMLOG(BCMLOG_DBG, "DelQAddr:%x RelQAddr:%x\n", + hw->pib_del_Q_addr, hw->pib_rel_Q_addr); + break; + case eCMD_C011_INIT: + if (!(crystalhd_load_firmware_config(hw->adp))) { + BCMLOG_ERR("Invalid Params.\n"); + sts = BC_STS_FW_AUTH_FAILED; + } + break; + default: + break; + } + return sts; +} + +static BC_STATUS crystalhd_put_ddr2sleep(struct crystalhd_hw *hw) +{ + uint32_t reg; + link_misc_perst_decoder_ctrl rst_cntrl_reg; + + /* Pulse reset pin of 7412 (MISC_PERST_DECODER_CTRL) */ + rst_cntrl_reg.whole_reg = crystalhd_reg_rd(hw->adp, MISC_PERST_DECODER_CTRL); + + rst_cntrl_reg.bcm_7412_rst = 1; + crystalhd_reg_wr(hw->adp, MISC_PERST_DECODER_CTRL, rst_cntrl_reg.whole_reg); + msleep_interruptible(50); + + rst_cntrl_reg.bcm_7412_rst = 0; + crystalhd_reg_wr(hw->adp, MISC_PERST_DECODER_CTRL, rst_cntrl_reg.whole_reg); + + /* Close all banks, put DDR in idle */ + bc_dec_reg_wr(hw->adp, SDRAM_PRECHARGE, 0); + + /* Set bit 25 (drop CKE pin of DDR) */ + reg = bc_dec_reg_rd(hw->adp, SDRAM_PARAM); + reg |= 0x02000000; + bc_dec_reg_wr(hw->adp, SDRAM_PARAM, reg); + + /* Reset the audio block */ + bc_dec_reg_wr(hw->adp, AUD_DSP_MISC_SOFT_RESET, 0x1); + + /* Power down Raptor PLL */ + reg = bc_dec_reg_rd(hw->adp, DecHt_PllCCtl); + reg |= 0x00008000; + bc_dec_reg_wr(hw->adp, DecHt_PllCCtl, reg); + + /* Power down all Audio PLL */ + bc_dec_reg_wr(hw->adp, AIO_MISC_PLL_RESET, 0x1); + + /* Power down video clock (75MHz) */ + reg = bc_dec_reg_rd(hw->adp, DecHt_PllECtl); + reg |= 0x00008000; + bc_dec_reg_wr(hw->adp, DecHt_PllECtl, reg); + + /* Power down video clock (75MHz) */ + reg = bc_dec_reg_rd(hw->adp, DecHt_PllDCtl); + reg |= 0x00008000; + bc_dec_reg_wr(hw->adp, DecHt_PllDCtl, reg); + + /* Power down core clock (200MHz) */ + reg = bc_dec_reg_rd(hw->adp, DecHt_PllACtl); + reg |= 0x00008000; + bc_dec_reg_wr(hw->adp, DecHt_PllACtl, reg); + + /* Power down core clock (200MHz) */ + reg = bc_dec_reg_rd(hw->adp, DecHt_PllBCtl); + reg |= 0x00008000; + bc_dec_reg_wr(hw->adp, DecHt_PllBCtl, reg); + + return BC_STS_SUCCESS; +} + +/************************************************ +** +*************************************************/ + +BC_STATUS crystalhd_download_fw(struct crystalhd_adp *adp, void *buffer, uint32_t sz) +{ + uint32_t reg_data, cnt, *temp_buff; + uint32_t fw_sig_len = 36; + uint32_t dram_offset = BC_FWIMG_ST_ADDR, sig_reg; + + BCMLOG_ENTER; + + if (!adp || !buffer || !sz) { + BCMLOG_ERR("Invalid Params.\n"); + return BC_STS_INV_ARG; + } + + reg_data = crystalhd_reg_rd(adp, OTP_CMD); + if (!(reg_data & 0x02)) { + BCMLOG_ERR("Invalid hw config.. otp not programmed\n"); + return BC_STS_ERROR; + } + + reg_data = 0; + crystalhd_reg_wr(adp, DCI_CMD, 0); + reg_data |= BC_BIT(0); + crystalhd_reg_wr(adp, DCI_CMD, reg_data); + + reg_data = 0; + cnt = 1000; + msleep_interruptible(10); + + while (reg_data != BC_BIT(4)) { + reg_data = crystalhd_reg_rd(adp, DCI_STATUS); + reg_data &= BC_BIT(4); + if (--cnt == 0) { + BCMLOG_ERR("Firmware Download RDY Timeout.\n"); + return BC_STS_TIMEOUT; + } + } + + msleep_interruptible(10); + /* Load the FW to the FW_ADDR field in the DCI_FIRMWARE_ADDR */ + crystalhd_reg_wr(adp, DCI_FIRMWARE_ADDR, dram_offset); + temp_buff = (uint32_t *)buffer; + for (cnt = 0; cnt < (sz - fw_sig_len); cnt += 4) { + crystalhd_reg_wr(adp, DCI_DRAM_BASE_ADDR, (dram_offset >> 19)); + crystalhd_reg_wr(adp, DCI_FIRMWARE_DATA, *temp_buff); + dram_offset += 4; + temp_buff++; + } + msleep_interruptible(10); + + temp_buff++; + + sig_reg = (uint32_t)DCI_SIGNATURE_DATA_7; + for (cnt = 0; cnt < 8; cnt++) { + uint32_t swapped_data = *temp_buff; + swapped_data = bswap_32_1(swapped_data); + crystalhd_reg_wr(adp, sig_reg, swapped_data); + sig_reg -= 4; + temp_buff++; + } + msleep_interruptible(10); + + reg_data = 0; + reg_data |= BC_BIT(1); + crystalhd_reg_wr(adp, DCI_CMD, reg_data); + msleep_interruptible(10); + + reg_data = 0; + reg_data = crystalhd_reg_rd(adp, DCI_STATUS); + + if ((reg_data & BC_BIT(9)) == BC_BIT(9)) { + cnt = 1000; + while ((reg_data & BC_BIT(0)) != BC_BIT(0)) { + reg_data = crystalhd_reg_rd(adp, DCI_STATUS); + reg_data &= BC_BIT(0); + if (!(--cnt)) + break; + msleep_interruptible(10); + } + reg_data = 0; + reg_data = crystalhd_reg_rd(adp, DCI_CMD); + reg_data |= BC_BIT(4); + crystalhd_reg_wr(adp, DCI_CMD, reg_data); + + } else { + BCMLOG_ERR("F/w Signature mismatch\n"); + return BC_STS_FW_AUTH_FAILED; + } + + BCMLOG(BCMLOG_INFO, "Firmware Downloaded Successfully\n"); + return BC_STS_SUCCESS;; +} + +BC_STATUS crystalhd_do_fw_cmd(struct crystalhd_hw *hw, BC_FW_CMD *fw_cmd) +{ + uint32_t cnt = 0, cmd_res_addr; + uint32_t *cmd_buff, *res_buff; + wait_queue_head_t fw_cmd_event; + int rc = 0; + BC_STATUS sts; + + crystalhd_create_event(&fw_cmd_event); + + BCMLOG_ENTER; + + if (!hw || !fw_cmd) { + BCMLOG_ERR("Invalid Arguments\n"); + return BC_STS_INV_ARG; + } + + cmd_buff = fw_cmd->cmd; + res_buff = fw_cmd->rsp; + + if (!cmd_buff || !res_buff) { + BCMLOG_ERR("Invalid Parameters for F/W Command \n"); + return BC_STS_INV_ARG; + } + + hw->pwr_lock++; + + hw->fwcmd_evt_sts = 0; + hw->pfw_cmd_event = &fw_cmd_event; + + /*Write the command to the memory*/ + crystalhd_mem_wr(hw->adp, TS_Host2CpuSnd, FW_CMD_BUFF_SZ, cmd_buff); + + /*Memory Read for memory arbitrator flush*/ + crystalhd_mem_rd(hw->adp, TS_Host2CpuSnd, 1, &cnt); + + /* Write the command address to mailbox */ + bc_dec_reg_wr(hw->adp, Hst2CpuMbx1, TS_Host2CpuSnd); + msleep_interruptible(50); + + crystalhd_wait_on_event(&fw_cmd_event, hw->fwcmd_evt_sts, 20000, rc, 0); + + if (!rc) { + sts = BC_STS_SUCCESS; + } else if (rc == -EBUSY) { + BCMLOG_ERR("Firmware command T/O\n"); + sts = BC_STS_TIMEOUT; + } else if (rc == -EINTR) { + BCMLOG(BCMLOG_DBG, "FwCmd Wait Signal int.\n"); + sts = BC_STS_IO_USER_ABORT; + } else { + BCMLOG_ERR("FwCmd IO Error.\n"); + sts = BC_STS_IO_ERROR; + } + + if (sts != BC_STS_SUCCESS) { + BCMLOG_ERR("FwCmd Failed.\n"); + hw->pwr_lock--; + return sts; + } + + /*Get the Responce Address*/ + cmd_res_addr = bc_dec_reg_rd(hw->adp, Cpu2HstMbx1); + + /*Read the Response*/ + crystalhd_mem_rd(hw->adp, cmd_res_addr, FW_CMD_BUFF_SZ, res_buff); + + hw->pwr_lock--; + + if (res_buff[2] != C011_RET_SUCCESS) { + BCMLOG_ERR("res_buff[2] != C011_RET_SUCCESS\n"); + return BC_STS_FW_CMD_ERR; + } + + sts = crystalhd_fw_cmd_post_proc(hw, fw_cmd); + if (sts != BC_STS_SUCCESS) + BCMLOG_ERR("crystalhd_fw_cmd_post_proc Failed.\n"); + + return sts; +} + +bool crystalhd_hw_interrupt(struct crystalhd_adp *adp, struct crystalhd_hw *hw) +{ + uint32_t intr_sts = 0; + uint32_t deco_intr = 0; + bool rc = 0; + + if (!adp || !hw->dev_started) + return rc; + + hw->stats.num_interrupts++; + hw->pwr_lock++; + + deco_intr = bc_dec_reg_rd(adp, Stream2Host_Intr_Sts); + intr_sts = crystalhd_reg_rd(adp, INTR_INTR_STATUS); + + if (intr_sts) { + /* let system know we processed interrupt..*/ + rc = 1; + hw->stats.dev_interrupts++; + } + + if (deco_intr && (deco_intr != 0xdeaddead)) { + + if (deco_intr & 0x80000000) { + /*Set the Event and the status flag*/ + if (hw->pfw_cmd_event) { + hw->fwcmd_evt_sts = 1; + crystalhd_set_event(hw->pfw_cmd_event); + } + } + + if (deco_intr & BC_BIT(1)) + crystalhd_hw_proc_pib(hw); + + bc_dec_reg_wr(adp, Stream2Host_Intr_Sts, deco_intr); + /* FIXME: jarod: No udelay? might this be the real reason mini pci-e cards were stalling out? */ + bc_dec_reg_wr(adp, Stream2Host_Intr_Sts, 0); + rc = 1; + } + + /* Rx interrupts */ + crystalhd_rx_isr(hw, intr_sts); + + /* Tx interrupts*/ + crystalhd_tx_isr(hw, intr_sts); + + /* Clear interrupts */ + if (rc) { + if (intr_sts) + crystalhd_reg_wr(adp, INTR_INTR_CLR_REG, intr_sts); + + crystalhd_reg_wr(adp, INTR_EOI_CTRL, 1); + } + + hw->pwr_lock--; + + return rc; +} + +BC_STATUS crystalhd_hw_open(struct crystalhd_hw *hw, struct crystalhd_adp *adp) +{ + if (!hw || !adp) { + BCMLOG_ERR("Invalid Arguments\n"); + return BC_STS_INV_ARG; + } + + if (hw->dev_started) + return BC_STS_SUCCESS; + + memset(hw, 0, sizeof(struct crystalhd_hw)); + + hw->adp = adp; + spin_lock_init(&hw->lock); + spin_lock_init(&hw->rx_lock); + /* FIXME: jarod: what are these magic numbers?!? */ + hw->tx_ioq_tag_seed = 0x70023070; + hw->rx_pkt_tag_seed = 0x70029070; + + hw->stop_pending = 0; + crystalhd_start_device(hw->adp); + hw->dev_started = true; + + /* set initial core clock */ + hw->core_clock_mhz = CLOCK_PRESET; + hw->prev_n = 0; + hw->pwr_lock = 0; + crystalhd_hw_set_core_clock(hw); + + return BC_STS_SUCCESS; +} + +BC_STATUS crystalhd_hw_close(struct crystalhd_hw *hw) +{ + if (!hw) { + BCMLOG_ERR("Invalid Arguments\n"); + return BC_STS_INV_ARG; + } + + if (!hw->dev_started) + return BC_STS_SUCCESS; + + /* Stop and DDR sleep will happen in here */ + crystalhd_hw_suspend(hw); + hw->dev_started = false; + + return BC_STS_SUCCESS; +} + +BC_STATUS crystalhd_hw_setup_dma_rings(struct crystalhd_hw *hw) +{ + unsigned int i; + void *mem; + size_t mem_len; + dma_addr_t phy_addr; + BC_STATUS sts = BC_STS_SUCCESS; + crystalhd_rx_dma_pkt *rpkt; + + if (!hw || !hw->adp) { + BCMLOG_ERR("Invalid Arguments\n"); + return BC_STS_INV_ARG; + } + + sts = crystalhd_hw_create_ioqs(hw); + if (sts != BC_STS_SUCCESS) { + BCMLOG_ERR("Failed to create IOQs..\n"); + return sts; + } + + mem_len = BC_LINK_MAX_SGLS * sizeof(dma_descriptor); + + for (i = 0; i < BC_TX_LIST_CNT; i++) { + mem = bc_kern_dma_alloc(hw->adp, mem_len, &phy_addr); + if (mem) { + memset(mem, 0, mem_len); + } else { + BCMLOG_ERR("Insufficient Memory For TX\n"); + crystalhd_hw_free_dma_rings(hw); + return BC_STS_INSUFF_RES; + } + /* rx_pkt_pool -- static memory allocation */ + hw->tx_pkt_pool[i].desc_mem.pdma_desc_start = mem; + hw->tx_pkt_pool[i].desc_mem.phy_addr = phy_addr; + hw->tx_pkt_pool[i].desc_mem.sz = BC_LINK_MAX_SGLS * + sizeof(dma_descriptor); + hw->tx_pkt_pool[i].list_tag = 0; + + /* Add TX dma requests to Free Queue..*/ + sts = crystalhd_dioq_add(hw->tx_freeq, + &hw->tx_pkt_pool[i], false, 0); + if (sts != BC_STS_SUCCESS) { + crystalhd_hw_free_dma_rings(hw); + return sts; + } + } + + for (i = 0; i < BC_RX_LIST_CNT; i++) { + rpkt = kzalloc(sizeof(*rpkt), GFP_KERNEL); + if (!rpkt) { + BCMLOG_ERR("Insufficient Memory For RX\n"); + crystalhd_hw_free_dma_rings(hw); + return BC_STS_INSUFF_RES; + } + + mem = bc_kern_dma_alloc(hw->adp, mem_len, &phy_addr); + if (mem) { + memset(mem, 0, mem_len); + } else { + BCMLOG_ERR("Insufficient Memory For RX\n"); + crystalhd_hw_free_dma_rings(hw); + return BC_STS_INSUFF_RES; + } + rpkt->desc_mem.pdma_desc_start = mem; + rpkt->desc_mem.phy_addr = phy_addr; + rpkt->desc_mem.sz = BC_LINK_MAX_SGLS * sizeof(dma_descriptor); + rpkt->pkt_tag = hw->rx_pkt_tag_seed + i; + crystalhd_hw_free_rx_pkt(hw, rpkt); + } + + return BC_STS_SUCCESS; +} + +BC_STATUS crystalhd_hw_free_dma_rings(struct crystalhd_hw *hw) +{ + unsigned int i; + crystalhd_rx_dma_pkt *rpkt = NULL; + + if (!hw || !hw->adp) { + BCMLOG_ERR("Invalid Arguments\n"); + return BC_STS_INV_ARG; + } + + /* Delete all IOQs.. */ + crystalhd_hw_delete_ioqs(hw); + + for (i = 0; i < BC_TX_LIST_CNT; i++) { + if (hw->tx_pkt_pool[i].desc_mem.pdma_desc_start) { + bc_kern_dma_free(hw->adp, + hw->tx_pkt_pool[i].desc_mem.sz, + hw->tx_pkt_pool[i].desc_mem.pdma_desc_start, + hw->tx_pkt_pool[i].desc_mem.phy_addr); + + hw->tx_pkt_pool[i].desc_mem.pdma_desc_start = NULL; + } + } + + BCMLOG(BCMLOG_DBG, "Releasing RX Pkt pool\n"); + do { + rpkt = crystalhd_hw_alloc_rx_pkt(hw); + if (!rpkt) + break; + bc_kern_dma_free(hw->adp, rpkt->desc_mem.sz, + rpkt->desc_mem.pdma_desc_start, + rpkt->desc_mem.phy_addr); + kfree(rpkt); + } while (rpkt); + + return BC_STS_SUCCESS; +} + +BC_STATUS crystalhd_hw_post_tx(struct crystalhd_hw *hw, crystalhd_dio_req *ioreq, + hw_comp_callback call_back, + wait_queue_head_t *cb_event, uint32_t *list_id, + uint8_t data_flags) +{ + tx_dma_pkt *tx_dma_packet = NULL; + uint32_t first_desc_u_addr, first_desc_l_addr; + uint32_t low_addr, high_addr; + addr_64 desc_addr; + BC_STATUS sts, add_sts; + uint32_t dummy_index = 0; + unsigned long flags; + bool rc; + + if (!hw || !ioreq || !call_back || !cb_event || !list_id) { + BCMLOG_ERR("Invalid Arguments\n"); + return BC_STS_INV_ARG; + } + + /* + * Since we hit code in busy condition very frequently, + * we will check the code in status first before + * checking the availability of free elem. + * + * This will avoid the Q fetch/add in normal condition. + */ + rc = crystalhd_code_in_full(hw->adp, ioreq->uinfo.xfr_len, + false, data_flags); + if (rc) { + hw->stats.cin_busy++; + return BC_STS_BUSY; + } + + /* Get a list from TxFreeQ */ + tx_dma_packet = (tx_dma_pkt *)crystalhd_dioq_fetch(hw->tx_freeq); + if (!tx_dma_packet) { + BCMLOG_ERR("No empty elements..\n"); + return BC_STS_ERR_USAGE; + } + + sts = crystalhd_xlat_sgl_to_dma_desc(ioreq, + &tx_dma_packet->desc_mem, + &dummy_index); + if (sts != BC_STS_SUCCESS) { + add_sts = crystalhd_dioq_add(hw->tx_freeq, tx_dma_packet, + false, 0); + if (add_sts != BC_STS_SUCCESS) + BCMLOG_ERR("double fault..\n"); + + return sts; + } + + hw->pwr_lock++; + + desc_addr.full_addr = tx_dma_packet->desc_mem.phy_addr; + low_addr = desc_addr.low_part; + high_addr = desc_addr.high_part; + + tx_dma_packet->call_back = call_back; + tx_dma_packet->cb_event = cb_event; + tx_dma_packet->dio_req = ioreq; + + spin_lock_irqsave(&hw->lock, flags); + + if (hw->tx_list_post_index == 0) { + first_desc_u_addr = MISC1_TX_FIRST_DESC_U_ADDR_LIST0; + first_desc_l_addr = MISC1_TX_FIRST_DESC_L_ADDR_LIST0; + } else { + first_desc_u_addr = MISC1_TX_FIRST_DESC_U_ADDR_LIST1; + first_desc_l_addr = MISC1_TX_FIRST_DESC_L_ADDR_LIST1; + } + + *list_id = tx_dma_packet->list_tag = hw->tx_ioq_tag_seed + + hw->tx_list_post_index; + + hw->tx_list_post_index = (hw->tx_list_post_index + 1) % DMA_ENGINE_CNT; + + spin_unlock_irqrestore(&hw->lock, flags); + + + /* Insert in Active Q..*/ + crystalhd_dioq_add(hw->tx_actq, tx_dma_packet, false, + tx_dma_packet->list_tag); + + /* + * Interrupt will come as soon as you write + * the valid bit. So be ready for that. All + * the initialization should happen before that. + */ + crystalhd_start_tx_dma_engine(hw); + crystalhd_reg_wr(hw->adp, first_desc_u_addr, desc_addr.high_part); + + crystalhd_reg_wr(hw->adp, first_desc_l_addr, desc_addr.low_part | 0x01); + /* Be sure we set the valid bit ^^^^ */ + + return BC_STS_SUCCESS; +} + +/* + * This is a force cancel and we are racing with ISR. + * + * Will try to remove the req from ActQ before ISR gets it. + * If ISR gets it first then the completion happens in the + * normal path and we will return _STS_NO_DATA from here. + * + * FIX_ME: Not Tested the actual condition.. + */ +BC_STATUS crystalhd_hw_cancel_tx(struct crystalhd_hw *hw, uint32_t list_id) +{ + if (!hw || !list_id) { + BCMLOG_ERR("Invalid Arguments\n"); + return BC_STS_INV_ARG; + } + + crystalhd_stop_tx_dma_engine(hw); + crystalhd_hw_tx_req_complete(hw, list_id, BC_STS_IO_USER_ABORT); + + return BC_STS_SUCCESS; +} + +BC_STATUS crystalhd_hw_add_cap_buffer(struct crystalhd_hw *hw, + crystalhd_dio_req *ioreq, bool en_post) +{ + crystalhd_rx_dma_pkt *rpkt; + uint32_t tag, uv_desc_ix = 0; + BC_STATUS sts; + + if (!hw || !ioreq) { + BCMLOG_ERR("Invalid Arguments\n"); + return BC_STS_INV_ARG; + } + + rpkt = crystalhd_hw_alloc_rx_pkt(hw); + if (!rpkt) { + BCMLOG_ERR("Insufficient resources\n"); + return BC_STS_INSUFF_RES; + } + + rpkt->dio_req = ioreq; + tag = rpkt->pkt_tag; + + sts = crystalhd_xlat_sgl_to_dma_desc(ioreq, &rpkt->desc_mem, &uv_desc_ix); + if (sts != BC_STS_SUCCESS) + return sts; + + rpkt->uv_phy_addr = 0; + + /* Store the address of UV in the rx packet for post*/ + if (uv_desc_ix) + rpkt->uv_phy_addr = rpkt->desc_mem.phy_addr + + (sizeof(dma_descriptor) * (uv_desc_ix + 1)); + + if (en_post) + sts = crystalhd_hw_post_cap_buff(hw, rpkt); + else + sts = crystalhd_dioq_add(hw->rx_freeq, rpkt, false, tag); + + return sts; +} + +BC_STATUS crystalhd_hw_get_cap_buffer(struct crystalhd_hw *hw, + BC_PIC_INFO_BLOCK *pib, + crystalhd_dio_req **ioreq) +{ + crystalhd_rx_dma_pkt *rpkt; + uint32_t timeout = BC_PROC_OUTPUT_TIMEOUT / 1000; + uint32_t sig_pending = 0; + + + if (!hw || !ioreq || !pib) { + BCMLOG_ERR("Invalid Arguments\n"); + return BC_STS_INV_ARG; + } + + rpkt = crystalhd_dioq_fetch_wait(hw->rx_rdyq, timeout, &sig_pending); + if (!rpkt) { + if (sig_pending) { + BCMLOG(BCMLOG_INFO, "wait on frame time out %d\n", sig_pending); + return BC_STS_IO_USER_ABORT; + } else { + return BC_STS_TIMEOUT; + } + } + + rpkt->dio_req->uinfo.comp_flags = rpkt->flags; + + if (rpkt->flags & COMP_FLAG_PIB_VALID) + memcpy(pib, &rpkt->pib, sizeof(*pib)); + + *ioreq = rpkt->dio_req; + + crystalhd_hw_free_rx_pkt(hw, rpkt); + + return BC_STS_SUCCESS; +} + +BC_STATUS crystalhd_hw_start_capture(struct crystalhd_hw *hw) +{ + crystalhd_rx_dma_pkt *rx_pkt; + BC_STATUS sts; + uint32_t i; + + if (!hw) { + BCMLOG_ERR("Invalid Arguments\n"); + return BC_STS_INV_ARG; + } + + /* This is start of capture.. Post to both the lists.. */ + for (i = 0; i < DMA_ENGINE_CNT; i++) { + rx_pkt = crystalhd_dioq_fetch(hw->rx_freeq); + if (!rx_pkt) + return BC_STS_NO_DATA; + sts = crystalhd_hw_post_cap_buff(hw, rx_pkt); + if (BC_STS_SUCCESS != sts) + break; + + } + + return BC_STS_SUCCESS; +} + +BC_STATUS crystalhd_hw_stop_capture(struct crystalhd_hw *hw) +{ + void *temp = NULL; + + if (!hw) { + BCMLOG_ERR("Invalid Arguments\n"); + return BC_STS_INV_ARG; + } + + crystalhd_stop_rx_dma_engine(hw); + + do { + temp = crystalhd_dioq_fetch(hw->rx_freeq); + if (temp) + crystalhd_rx_pkt_rel_call_back(hw, temp); + } while (temp); + + return BC_STS_SUCCESS; +} + +BC_STATUS crystalhd_hw_pause(struct crystalhd_hw *hw) +{ + hw->stats.pause_cnt++; + hw->stop_pending = 1; + + if ((hw->rx_list_sts[0] == sts_free) && + (hw->rx_list_sts[1] == sts_free)) + crystalhd_hw_finalize_pause(hw); + + return BC_STS_SUCCESS; +} + +BC_STATUS crystalhd_hw_unpause(struct crystalhd_hw *hw) +{ + BC_STATUS sts; + uint32_t aspm; + + hw->stop_pending = 0; + + aspm = crystalhd_reg_rd(hw->adp, PCIE_DLL_DATA_LINK_CONTROL); + aspm &= ~ASPM_L1_ENABLE; +/* NAREN BCMLOG(BCMLOG_INFO, "aspm off\n"); */ + crystalhd_reg_wr(hw->adp, PCIE_DLL_DATA_LINK_CONTROL, aspm); + + sts = crystalhd_hw_start_capture(hw); + return sts; +} + +BC_STATUS crystalhd_hw_suspend(struct crystalhd_hw *hw) +{ + BC_STATUS sts; + + if (!hw) { + BCMLOG_ERR("Invalid Arguments\n"); + return BC_STS_INV_ARG; + } + + sts = crystalhd_put_ddr2sleep(hw); + if (sts != BC_STS_SUCCESS) { + BCMLOG_ERR("Failed to Put DDR To Sleep!!\n"); + return BC_STS_ERROR; + } + + if (!crystalhd_stop_device(hw->adp)) { + BCMLOG_ERR("Failed to Stop Device!!\n"); + return BC_STS_ERROR; + } + + return BC_STS_SUCCESS; +} + +void crystalhd_hw_stats(struct crystalhd_hw *hw, struct crystalhd_hw_stats *stats) +{ + if (!hw) { + BCMLOG_ERR("Invalid Arguments\n"); + return; + } + + /* if called w/NULL stats, its a req to zero out the stats */ + if (!stats) { + memset(&hw->stats, 0, sizeof(hw->stats)); + return; + } + + hw->stats.freeq_count = crystalhd_dioq_count(hw->rx_freeq); + hw->stats.rdyq_count = crystalhd_dioq_count(hw->rx_rdyq); + memcpy(stats, &hw->stats, sizeof(*stats)); +} + +BC_STATUS crystalhd_hw_set_core_clock(struct crystalhd_hw *hw) +{ + uint32_t reg, n, i; + uint32_t vco_mg, refresh_reg; + + if (!hw) { + BCMLOG_ERR("Invalid Arguments\n"); + return BC_STS_INV_ARG; + } + + /* FIXME: jarod: wha? */ + /*n = (hw->core_clock_mhz * 3) / 20 + 1; */ + n = hw->core_clock_mhz/5; + + if (n == hw->prev_n) + return BC_STS_CLK_NOCHG; + + if (hw->pwr_lock > 0) { + /* BCMLOG(BCMLOG_INFO,"pwr_lock is %u\n", hw->pwr_lock) */ + return BC_STS_CLK_NOCHG; + } + + i = n * 27; + if (i < 560) + vco_mg = 0; + else if (i < 900) + vco_mg = 1; + else if (i < 1030) + vco_mg = 2; + else + vco_mg = 3; + + reg = bc_dec_reg_rd(hw->adp, DecHt_PllACtl); + + reg &= 0xFFFFCFC0; + reg |= n; + reg |= vco_mg << 12; + + BCMLOG(BCMLOG_INFO, "clock is moving to %d with n %d with vco_mg %d\n", + hw->core_clock_mhz, n, vco_mg); + + /* Change the DRAM refresh rate to accomodate the new frequency */ + /* refresh reg = ((refresh_rate * clock_rate)/16) - 1; rounding up*/ + refresh_reg = (7 * hw->core_clock_mhz / 16); + bc_dec_reg_wr(hw->adp, SDRAM_REF_PARAM, ((1 << 12) | refresh_reg)); + + bc_dec_reg_wr(hw->adp, DecHt_PllACtl, reg); + + i = 0; + + for (i = 0; i < 10; i++) { + reg = bc_dec_reg_rd(hw->adp, DecHt_PllACtl); + + if (reg & 0x00020000) { + hw->prev_n = n; + /* FIXME: jarod: outputting a random "C" is... confusing... */ + BCMLOG(BCMLOG_INFO, "C"); + return BC_STS_SUCCESS; + } else { + msleep_interruptible(10); + } + } + BCMLOG(BCMLOG_INFO, "clk change failed\n"); + return BC_STS_CLK_NOCHG; +} diff --git a/drivers/staging/crystalhd/crystalhd_hw.h b/drivers/staging/crystalhd/crystalhd_hw.h new file mode 100644 index 0000000..1c6318e --- /dev/null +++ b/drivers/staging/crystalhd/crystalhd_hw.h @@ -0,0 +1,398 @@ +/*************************************************************************** + * Copyright (c) 2005-2009, Broadcom Corporation. + * + * Name: crystalhd_hw . h + * + * Description: + * BCM70012 Linux driver hardware layer. + * + * HISTORY: + * + ********************************************************************** + * This file is part of the crystalhd device driver. + * + * This driver is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This driver is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this driver. If not, see <http://www.gnu.org/licenses/>. + **********************************************************************/ + +#ifndef _CRYSTALHD_HW_H_ +#define _CRYSTALHD_HW_H_ + +#include "crystalhd_misc.h" +#include "crystalhd_fw_if.h" + +/* HW constants..*/ +#define DMA_ENGINE_CNT 2 +#define MAX_PIB_Q_DEPTH 64 +#define MIN_PIB_Q_DEPTH 2 +#define WR_POINTER_OFF 4 + +#define ASPM_L1_ENABLE (BC_BIT(27)) + +/************************************************* + 7412 Decoder Registers. +**************************************************/ +#define FW_CMD_BUFF_SZ 64 +#define TS_Host2CpuSnd 0x00000100 +#define Hst2CpuMbx1 0x00100F00 +#define Cpu2HstMbx1 0x00100F04 +#define MbxStat1 0x00100F08 +#define Stream2Host_Intr_Sts 0x00100F24 +#define C011_RET_SUCCESS 0x0 /* Reutrn status of firmware command. */ + +/* TS input status register */ +#define TS_StreamAFIFOStatus 0x0010044C +#define TS_StreamBFIFOStatus 0x0010084C + +/*UART Selection definitions*/ +#define UartSelectA 0x00100300 +#define UartSelectB 0x00100304 + +#define BSVS_UART_DEC_NONE 0x00 +#define BSVS_UART_DEC_OUTER 0x01 +#define BSVS_UART_DEC_INNER 0x02 +#define BSVS_UART_STREAM 0x03 + +/* Code-In fifo */ +#define REG_DecCA_RegCinCTL 0xa00 +#define REG_DecCA_RegCinBase 0xa0c +#define REG_DecCA_RegCinEnd 0xa10 +#define REG_DecCA_RegCinWrPtr 0xa04 +#define REG_DecCA_RegCinRdPtr 0xa08 + +#define REG_Dec_TsUser0Base 0x100864 +#define REG_Dec_TsUser0Rdptr 0x100868 +#define REG_Dec_TsUser0Wrptr 0x10086C +#define REG_Dec_TsUser0End 0x100874 + +/* ASF Case ...*/ +#define REG_Dec_TsAudCDB2Base 0x10036c +#define REG_Dec_TsAudCDB2Rdptr 0x100378 +#define REG_Dec_TsAudCDB2Wrptr 0x100374 +#define REG_Dec_TsAudCDB2End 0x100370 + +/* DRAM bringup Registers */ +#define SDRAM_PARAM 0x00040804 +#define SDRAM_PRECHARGE 0x000408B0 +#define SDRAM_EXT_MODE 0x000408A4 +#define SDRAM_MODE 0x000408A0 +#define SDRAM_REFRESH 0x00040890 +#define SDRAM_REF_PARAM 0x00040808 + +#define DecHt_PllACtl 0x34000C +#define DecHt_PllBCtl 0x340010 +#define DecHt_PllCCtl 0x340014 +#define DecHt_PllDCtl 0x340034 +#define DecHt_PllECtl 0x340038 +#define AUD_DSP_MISC_SOFT_RESET 0x00240104 +#define AIO_MISC_PLL_RESET 0x0026000C +#define PCIE_CLK_REQ_REG 0xDC +#define PCI_CLK_REQ_ENABLE (BC_BIT(8)) + +/************************************************* + F/W Copy engine definitions.. +**************************************************/ +#define BC_FWIMG_ST_ADDR 0x00000000 +/* FIXME: jarod: there's a kernel function that'll do this for us... */ +#define rotr32_1(x, n) (((x) >> n) | ((x) << (32 - n))) +#define bswap_32_1(x) ((rotr32_1((x), 24) & 0x00ff00ff) | (rotr32_1((x), 8) & 0xff00ff00)) + +#define DecHt_HostSwReset 0x340000 +#define BC_DRAM_FW_CFG_ADDR 0x001c2000 + +typedef union _addr_64_ { + struct { + uint32_t low_part; + uint32_t high_part; + }; + + uint64_t full_addr; + +} addr_64; + +typedef union _intr_mask_reg_ { + struct { + uint32_t mask_tx_done:1; + uint32_t mask_tx_err:1; + uint32_t mask_rx_done:1; + uint32_t mask_rx_err:1; + uint32_t mask_pcie_err:1; + uint32_t mask_pcie_rbusmast_err:1; + uint32_t mask_pcie_rgr_bridge:1; + uint32_t reserved:25; + }; + + uint32_t whole_reg; + +} intr_mask_reg; + +typedef union _link_misc_perst_deco_ctrl_ { + struct { + uint32_t bcm7412_rst:1; /* 1 -> BCM7412 is held in reset. Reset value 1.*/ + uint32_t reserved0:3; /* Reserved.No Effect*/ + uint32_t stop_bcm_7412_clk:1; /* 1 ->Stops branch of 27MHz clk used to clk BCM7412*/ + uint32_t reserved1:27; /* Reseved. No Effect*/ + }; + + uint32_t whole_reg; + +} link_misc_perst_deco_ctrl; + +typedef union _link_misc_perst_clk_ctrl_ { + struct { + uint32_t sel_alt_clk:1; /* When set, selects a 6.75MHz clock as the source of core_clk */ + uint32_t stop_core_clk:1; /* When set, stops the branch of core_clk that is not needed for low power operation */ + uint32_t pll_pwr_dn:1; /* When set, powers down the main PLL. The alternate clock bit should be set + to select an alternate clock before setting this bit.*/ + uint32_t reserved0:5; /* Reserved */ + uint32_t pll_mult:8; /* This setting controls the multiplier for the PLL. */ + uint32_t pll_div:4; /* This setting controls the divider for the PLL. */ + uint32_t reserved1:12; /* Reserved */ + }; + + uint32_t whole_reg; + +} link_misc_perst_clk_ctrl; + + +typedef union _link_misc_perst_decoder_ctrl_ { + struct { + uint32_t bcm_7412_rst:1; /* 1 -> BCM7412 is held in reset. Reset value 1.*/ + uint32_t res0:3; /* Reserved.No Effect*/ + uint32_t stop_7412_clk:1; /* 1 ->Stops branch of 27MHz clk used to clk BCM7412*/ + uint32_t res1:27; /* Reseved. No Effect */ + }; + + uint32_t whole_reg; + +} link_misc_perst_decoder_ctrl; + + +typedef union _desc_low_addr_reg_ { + struct { + uint32_t list_valid:1; + uint32_t reserved:4; + uint32_t low_addr:27; + }; + + uint32_t whole_reg; + +} desc_low_addr_reg; + +typedef struct _dma_descriptor_ { /* 8 32-bit values */ + /* 0th u32 */ + uint32_t sdram_buff_addr:28; /* bits 0-27: SDRAM Address */ + uint32_t res0:4; /* bits 28-31: Reserved */ + + /* 1st u32 */ + uint32_t buff_addr_low; /* 1 buffer address low */ + uint32_t buff_addr_high; /* 2 buffer address high */ + + /* 3rd u32 */ + uint32_t res2:2; /* 0-1 - Reserved */ + uint32_t xfer_size:23; /* 2-24 = Xfer size in words */ + uint32_t res3:6; /* 25-30 reserved */ + uint32_t intr_enable:1; /* 31 - Interrupt After this desc */ + + /* 4th u32 */ + uint32_t endian_xlat_align:2; /* 0-1 Endian Translation */ + uint32_t next_desc_cont:1; /* 2 - Next desc is in contig memory */ + uint32_t res4:25; /* 3 - 27 Reserved bits */ + uint32_t fill_bytes:2; /* 28-29 Bits Fill Bytes */ + uint32_t dma_dir:1; /* 30 bit DMA Direction */ + uint32_t last_rec_indicator:1; /* 31 bit Last Record Indicator */ + + /* 5th u32 */ + uint32_t next_desc_addr_low; /* 32-bits Next Desc Addr lower */ + + /* 6th u32 */ + uint32_t next_desc_addr_high; /* 32-bits Next Desc Addr Higher */ + + /* 7th u32 */ + uint32_t res8; /* Last 32bits reserved */ + +} dma_descriptor, *pdma_descriptor; + +/* + * We will allocate the memory in 4K pages + * the linked list will be a list of 32 byte descriptors. + * The virtual address will determine what should be freed. + */ +typedef struct _dma_desc_mem_ { + pdma_descriptor pdma_desc_start; /* 32-bytes for dma descriptor. should be first element */ + dma_addr_t phy_addr; /* physical address of each DMA desc */ + uint32_t sz; + struct _dma_desc_mem_ *Next; /* points to Next Descriptor in chain */ + +} dma_desc_mem, *pdma_desc_mem; + + + +typedef enum _list_sts_ { + sts_free = 0, + + /* RX-Y Bits 0:7 */ + rx_waiting_y_intr = 0x00000001, + rx_y_error = 0x00000004, + + /* RX-UV Bits 8:16 */ + rx_waiting_uv_intr = 0x0000100, + rx_uv_error = 0x0000400, + + rx_sts_waiting = (rx_waiting_y_intr|rx_waiting_uv_intr), + rx_sts_error = (rx_y_error|rx_uv_error), + + rx_y_mask = 0x000000FF, + rx_uv_mask = 0x0000FF00, + +} list_sts; + +typedef struct _tx_dma_pkt_ { + dma_desc_mem desc_mem; + hw_comp_callback call_back; + crystalhd_dio_req *dio_req; + wait_queue_head_t *cb_event; + uint32_t list_tag; + +} tx_dma_pkt; + +typedef struct _crystalhd_rx_dma_pkt { + dma_desc_mem desc_mem; + crystalhd_dio_req *dio_req; + uint32_t pkt_tag; + uint32_t flags; + BC_PIC_INFO_BLOCK pib; + dma_addr_t uv_phy_addr; + struct _crystalhd_rx_dma_pkt *next; + +} crystalhd_rx_dma_pkt; + +struct crystalhd_hw_stats{ + uint32_t rx_errors; + uint32_t tx_errors; + uint32_t freeq_count; + uint32_t rdyq_count; + uint32_t num_interrupts; + uint32_t dev_interrupts; + uint32_t cin_busy; + uint32_t pause_cnt; +}; + +struct crystalhd_hw { + tx_dma_pkt tx_pkt_pool[DMA_ENGINE_CNT]; + spinlock_t lock; + + uint32_t tx_ioq_tag_seed; + uint32_t tx_list_post_index; + + crystalhd_rx_dma_pkt *rx_pkt_pool_head; + uint32_t rx_pkt_tag_seed; + + bool dev_started; + void *adp; + + wait_queue_head_t *pfw_cmd_event; + int fwcmd_evt_sts; + + uint32_t pib_del_Q_addr; + uint32_t pib_rel_Q_addr; + + crystalhd_dioq_t *tx_freeq; + crystalhd_dioq_t *tx_actq; + + /* Rx DMA Engine Specific Locks */ + spinlock_t rx_lock; + uint32_t rx_list_post_index; + list_sts rx_list_sts[DMA_ENGINE_CNT]; + crystalhd_dioq_t *rx_rdyq; + crystalhd_dioq_t *rx_freeq; + crystalhd_dioq_t *rx_actq; + uint32_t stop_pending; + + /* HW counters.. */ + struct crystalhd_hw_stats stats; + + /* Core clock in MHz */ + uint32_t core_clock_mhz; + uint32_t prev_n; + uint32_t pwr_lock; +}; + +/* Clock defines for power control */ +#define CLOCK_PRESET 175 + +/* DMA engine register BIT mask wrappers.. */ +#define DMA_START_BIT MISC1_TX_SW_DESC_LIST_CTRL_STS_TX_DMA_RUN_STOP_MASK + +#define GET_RX_INTR_MASK (INTR_INTR_STATUS_L1_UV_RX_DMA_ERR_INTR_MASK | \ + INTR_INTR_STATUS_L1_UV_RX_DMA_DONE_INTR_MASK | \ + INTR_INTR_STATUS_L1_Y_RX_DMA_ERR_INTR_MASK | \ + INTR_INTR_STATUS_L1_Y_RX_DMA_DONE_INTR_MASK | \ + INTR_INTR_STATUS_L0_UV_RX_DMA_ERR_INTR_MASK | \ + INTR_INTR_STATUS_L0_UV_RX_DMA_DONE_INTR_MASK | \ + INTR_INTR_STATUS_L0_Y_RX_DMA_ERR_INTR_MASK | \ + INTR_INTR_STATUS_L0_Y_RX_DMA_DONE_INTR_MASK) + +#define GET_Y0_ERR_MSK (MISC1_Y_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_MASK | \ + MISC1_Y_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_MASK | \ + MISC1_Y_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_MASK | \ + MISC1_Y_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_MASK) + +#define GET_UV0_ERR_MSK (MISC1_UV_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_MASK | \ + MISC1_UV_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_MASK | \ + MISC1_UV_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_MASK | \ + MISC1_UV_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_MASK) + +#define GET_Y1_ERR_MSK (MISC1_Y_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_MASK | \ + MISC1_Y_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_MASK | \ + MISC1_Y_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_MASK | \ + MISC1_Y_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_MASK) + +#define GET_UV1_ERR_MSK (MISC1_UV_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_MASK | \ + MISC1_UV_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_MASK | \ + MISC1_UV_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_MASK | \ + MISC1_UV_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_MASK) + + +/**** API Exposed to the other layers ****/ +BC_STATUS crystalhd_download_fw(struct crystalhd_adp *adp, + void *buffer, uint32_t sz); +BC_STATUS crystalhd_do_fw_cmd(struct crystalhd_hw *hw, BC_FW_CMD *fw_cmd); +bool crystalhd_hw_interrupt(struct crystalhd_adp *adp, struct crystalhd_hw *hw); +BC_STATUS crystalhd_hw_open(struct crystalhd_hw *, struct crystalhd_adp *); +BC_STATUS crystalhd_hw_close(struct crystalhd_hw *); +BC_STATUS crystalhd_hw_setup_dma_rings(struct crystalhd_hw *); +BC_STATUS crystalhd_hw_free_dma_rings(struct crystalhd_hw *); + + +BC_STATUS crystalhd_hw_post_tx(struct crystalhd_hw *hw, crystalhd_dio_req *ioreq, + hw_comp_callback call_back, + wait_queue_head_t *cb_event, + uint32_t *list_id, uint8_t data_flags); + +BC_STATUS crystalhd_hw_pause(struct crystalhd_hw *hw); +BC_STATUS crystalhd_hw_unpause(struct crystalhd_hw *hw); +BC_STATUS crystalhd_hw_suspend(struct crystalhd_hw *hw); +BC_STATUS crystalhd_hw_cancel_tx(struct crystalhd_hw *hw, uint32_t list_id); +BC_STATUS crystalhd_hw_add_cap_buffer(struct crystalhd_hw *hw, + crystalhd_dio_req *ioreq, bool en_post); +BC_STATUS crystalhd_hw_get_cap_buffer(struct crystalhd_hw *hw, + BC_PIC_INFO_BLOCK *pib, + crystalhd_dio_req **ioreq); +BC_STATUS crystalhd_hw_stop_capture(struct crystalhd_hw *hw); +BC_STATUS crystalhd_hw_start_capture(struct crystalhd_hw *hw); +void crystalhd_hw_stats(struct crystalhd_hw *hw, struct crystalhd_hw_stats *stats); + +/* API to program the core clock on the decoder */ +BC_STATUS crystalhd_hw_set_core_clock(struct crystalhd_hw *); + +#endif diff --git a/drivers/staging/crystalhd/crystalhd_lnx.c b/drivers/staging/crystalhd/crystalhd_lnx.c new file mode 100644 index 0000000..3eac70a --- /dev/null +++ b/drivers/staging/crystalhd/crystalhd_lnx.c @@ -0,0 +1,765 @@ +/*************************************************************************** + BCM70010 Linux driver + Copyright (c) 2005-2009, Broadcom Corporation. + + This driver is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, version 2 of the License. + + This driver is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this driver. If not, see <http://www.gnu.org/licenses/>. +***************************************************************************/ + +#include <linux/version.h> + +#include "crystalhd_lnx.h" + +static struct class *crystalhd_class; + +static struct crystalhd_adp *g_adp_info; + +static irqreturn_t chd_dec_isr(int irq, void *arg) +{ + struct crystalhd_adp *adp = (struct crystalhd_adp *) arg; + int rc = 0; + if (adp) + rc = crystalhd_cmd_interrupt(&adp->cmds); + + return IRQ_RETVAL(rc); +} + +static int chd_dec_enable_int(struct crystalhd_adp *adp) +{ + int rc = 0; + + if (!adp || !adp->pdev) { + BCMLOG_ERR("Invalid arg!!\n"); + return -EINVAL; + } + + if (adp->pdev->msi_enabled) + adp->msi = 1; + else + adp->msi = pci_enable_msi(adp->pdev); + + rc = request_irq(adp->pdev->irq, chd_dec_isr, IRQF_SHARED, + adp->name, (void *)adp); + if (rc) { + BCMLOG_ERR("Interrupt request failed.. \n"); + pci_disable_msi(adp->pdev); + } + + return rc; +} + +static int chd_dec_disable_int(struct crystalhd_adp *adp) +{ + if (!adp || !adp->pdev) { + BCMLOG_ERR("Invalid arg!!\n"); + return -EINVAL; + } + + free_irq(adp->pdev->irq, adp); + + if (adp->msi) + pci_disable_msi(adp->pdev); + + return 0; +} + +crystalhd_ioctl_data *chd_dec_alloc_iodata(struct crystalhd_adp *adp, bool isr) +{ + unsigned long flags = 0; + crystalhd_ioctl_data *temp; + + if (!adp) + return NULL; + + spin_lock_irqsave(&adp->lock, flags); + + temp = adp->idata_free_head; + if (temp) { + adp->idata_free_head = adp->idata_free_head->next; + memset(temp, 0, sizeof(*temp)); + } + + spin_unlock_irqrestore(&adp->lock, flags); + return temp; +} + +void chd_dec_free_iodata(struct crystalhd_adp *adp, crystalhd_ioctl_data *iodata, + bool isr) +{ + unsigned long flags = 0; + + if (!adp || !iodata) + return; + + spin_lock_irqsave(&adp->lock, flags); + iodata->next = adp->idata_free_head; + adp->idata_free_head = iodata; + spin_unlock_irqrestore(&adp->lock, flags); +} + +static inline int crystalhd_user_data(unsigned long ud, void *dr, int size, int set) +{ + int rc; + + if (!ud || !dr) { + BCMLOG_ERR("Invalid arg \n"); + return -EINVAL; + } + + if (set) + rc = copy_to_user((void *)ud, dr, size); + else + rc = copy_from_user(dr, (void *)ud, size); + + if (rc) { + BCMLOG_ERR("Invalid args for command \n"); + rc = -EFAULT; + } + + return rc; +} + +static int chd_dec_fetch_cdata(struct crystalhd_adp *adp, crystalhd_ioctl_data *io, + uint32_t m_sz, unsigned long ua) +{ + unsigned long ua_off; + int rc = 0; + + if (!adp || !io || !ua || !m_sz) { + BCMLOG_ERR("Invalid Arg!!\n"); + return -EINVAL; + } + + io->add_cdata = vmalloc(m_sz); + if (!io->add_cdata) { + BCMLOG_ERR("kalloc fail for sz:%x\n", m_sz); + return -ENOMEM; + } + + io->add_cdata_sz = m_sz; + ua_off = ua + sizeof(io->udata); + rc = crystalhd_user_data(ua_off, io->add_cdata, io->add_cdata_sz, 0); + if (rc) { + BCMLOG_ERR("failed to pull add_cdata sz:%x ua_off:%x\n", + io->add_cdata_sz, (unsigned int)ua_off); + if (io->add_cdata) { + kfree(io->add_cdata); + io->add_cdata = NULL; + } + return -ENODATA; + } + + return rc; +} + +static int chd_dec_release_cdata(struct crystalhd_adp *adp, + crystalhd_ioctl_data *io, unsigned long ua) +{ + unsigned long ua_off; + int rc; + + if (!adp || !io || !ua) { + BCMLOG_ERR("Invalid Arg!!\n"); + return -EINVAL; + } + + if (io->cmd != BCM_IOC_FW_DOWNLOAD) { + ua_off = ua + sizeof(io->udata); + rc = crystalhd_user_data(ua_off, io->add_cdata, + io->add_cdata_sz, 1); + if (rc) { + BCMLOG_ERR("failed to push add_cdata sz:%x ua_off:%x\n", + io->add_cdata_sz, (unsigned int)ua_off); + return -ENODATA; + } + } + + if (io->add_cdata) { + vfree(io->add_cdata); + io->add_cdata = NULL; + } + + return 0; +} + +static int chd_dec_proc_user_data(struct crystalhd_adp *adp, + crystalhd_ioctl_data *io, + unsigned long ua, int set) +{ + int rc; + uint32_t m_sz = 0; + + if (!adp || !io || !ua) { + BCMLOG_ERR("Invalid Arg!!\n"); + return -EINVAL; + } + + rc = crystalhd_user_data(ua, &io->udata, sizeof(io->udata), set); + if (rc) { + BCMLOG_ERR("failed to %s iodata \n", (set ? "set" : "get")); + return rc; + } + + switch (io->cmd) { + case BCM_IOC_MEM_RD: + case BCM_IOC_MEM_WR: + case BCM_IOC_FW_DOWNLOAD: + m_sz = io->udata.u.devMem.NumDwords * 4; + if (set) + rc = chd_dec_release_cdata(adp, io, ua); + else + rc = chd_dec_fetch_cdata(adp, io, m_sz, ua); + break; + default: + break; + } + + return rc; +} + +static int chd_dec_api_cmd(struct crystalhd_adp *adp, unsigned long ua, + uint32_t uid, uint32_t cmd, crystalhd_cmd_proc func) +{ + int rc; + crystalhd_ioctl_data *temp; + BC_STATUS sts = BC_STS_SUCCESS; + + temp = chd_dec_alloc_iodata(adp, 0); + if (!temp) { + BCMLOG_ERR("Failed to get iodata..\n"); + return -EINVAL; + } + + temp->u_id = uid; + temp->cmd = cmd; + + rc = chd_dec_proc_user_data(adp, temp, ua, 0); + if (!rc) { + sts = func(&adp->cmds, temp); + if (sts == BC_STS_PENDING) + sts = BC_STS_NOT_IMPL; + temp->udata.RetSts = sts; + rc = chd_dec_proc_user_data(adp, temp, ua, 1); + } + + if (temp) { + chd_dec_free_iodata(adp, temp, 0); + temp = NULL; + } + + return rc; +} + +/* API interfaces */ +static int chd_dec_ioctl(struct inode *in, struct file *fd, + unsigned int cmd, unsigned long ua) +{ + struct crystalhd_adp *adp = chd_get_adp(); + crystalhd_cmd_proc cproc; + struct crystalhd_user *uc; + + if (!adp || !fd) { + BCMLOG_ERR("Invalid adp\n"); + return -EINVAL; + } + + uc = (struct crystalhd_user *)fd->private_data; + if (!uc) { + BCMLOG_ERR("Failed to get uc\n"); + return -ENODATA; + } + + cproc = crystalhd_get_cmd_proc(&adp->cmds, cmd, uc); + if (!cproc) { + BCMLOG_ERR("Unhandled command: %d\n", cmd); + return -EINVAL; + } + + return chd_dec_api_cmd(adp, ua, uc->uid, cmd, cproc); +} + +static int chd_dec_open(struct inode *in, struct file *fd) +{ + struct crystalhd_adp *adp = chd_get_adp(); + int rc = 0; + BC_STATUS sts = BC_STS_SUCCESS; + struct crystalhd_user *uc = NULL; + + BCMLOG_ENTER; + if (!adp) { + BCMLOG_ERR("Invalid adp\n"); + return -EINVAL; + } + + if (adp->cfg_users >= BC_LINK_MAX_OPENS) { + BCMLOG(BCMLOG_INFO, "Already in use.%d\n", adp->cfg_users); + return -EBUSY; + } + + sts = crystalhd_user_open(&adp->cmds, &uc); + if (sts != BC_STS_SUCCESS) { + BCMLOG_ERR("cmd_user_open - %d \n", sts); + rc = -EBUSY; + } + + adp->cfg_users++; + + fd->private_data = uc; + + return rc; +} + +static int chd_dec_close(struct inode *in, struct file *fd) +{ + struct crystalhd_adp *adp = chd_get_adp(); + struct crystalhd_user *uc; + + BCMLOG_ENTER; + if (!adp) { + BCMLOG_ERR("Invalid adp \n"); + return -EINVAL; + } + + uc = (struct crystalhd_user *)fd->private_data; + if (!uc) { + BCMLOG_ERR("Failed to get uc\n"); + return -ENODATA; + } + + crystalhd_user_close(&adp->cmds, uc); + + adp->cfg_users--; + + return 0; +} + +static const struct file_operations chd_dec_fops = { + .owner = THIS_MODULE, + .ioctl = chd_dec_ioctl, + .open = chd_dec_open, + .release = chd_dec_close, +}; + +static int __devinit chd_dec_init_chdev(struct crystalhd_adp *adp) +{ + crystalhd_ioctl_data *temp; + struct device *dev; + int rc = -ENODEV, i = 0; + + if (!adp) + goto fail; + + adp->chd_dec_major = register_chrdev(0, CRYSTALHD_API_NAME, + &chd_dec_fops); + if (adp->chd_dec_major < 0) { + BCMLOG_ERR("Failed to create config dev\n"); + rc = adp->chd_dec_major; + goto fail; + } + + /* register crystalhd class */ + crystalhd_class = class_create(THIS_MODULE, "crystalhd"); + if (IS_ERR(crystalhd_class)) { + BCMLOG_ERR("failed to create class\n"); + goto fail; + } + + dev = device_create(crystalhd_class, NULL, MKDEV(adp->chd_dec_major, 0), + NULL, "crystalhd"); + if (!dev) { + BCMLOG_ERR("failed to create device\n"); + goto device_create_fail; + } + + rc = crystalhd_create_elem_pool(adp, BC_LINK_ELEM_POOL_SZ); + if (rc) { + BCMLOG_ERR("failed to create device\n"); + goto elem_pool_fail; + } + + /* Allocate general purpose ioctl pool. */ + for (i = 0; i < CHD_IODATA_POOL_SZ; i++) { + /* FIXME: jarod: why atomic? */ + temp = kzalloc(sizeof(crystalhd_ioctl_data), GFP_ATOMIC); + if (!temp) { + BCMLOG_ERR("ioctl data pool kzalloc failed\n"); + rc = -ENOMEM; + goto kzalloc_fail; + } + /* Add to global pool.. */ + chd_dec_free_iodata(adp, temp, 0); + } + + return 0; + +kzalloc_fail: + crystalhd_delete_elem_pool(adp); +elem_pool_fail: + device_destroy(crystalhd_class, MKDEV(adp->chd_dec_major, 0)); +device_create_fail: + class_destroy(crystalhd_class); +fail: + return rc; +} + +static void __devexit chd_dec_release_chdev(struct crystalhd_adp *adp) +{ + crystalhd_ioctl_data *temp = NULL; + if (!adp) + return; + + if (adp->chd_dec_major > 0) { + /* unregister crystalhd class */ + device_destroy(crystalhd_class, MKDEV(adp->chd_dec_major, 0)); + unregister_chrdev(adp->chd_dec_major, CRYSTALHD_API_NAME); + BCMLOG(BCMLOG_INFO, "released api device - %d\n", + adp->chd_dec_major); + class_destroy(crystalhd_class); + } + adp->chd_dec_major = 0; + + /* Clear iodata pool.. */ + do { + temp = chd_dec_alloc_iodata(adp, 0); + if (temp) + kfree(temp); + } while (temp); + + crystalhd_delete_elem_pool(adp); +} + +static int __devinit chd_pci_reserve_mem(struct crystalhd_adp *pinfo) +{ + int rc; + unsigned long bar2 = pci_resource_start(pinfo->pdev, 2); + uint32_t mem_len = pci_resource_len(pinfo->pdev, 2); + unsigned long bar0 = pci_resource_start(pinfo->pdev, 0); + uint32_t i2o_len = pci_resource_len(pinfo->pdev, 0); + + BCMLOG(BCMLOG_SSTEP, "bar2:0x%lx-0x%08x bar0:0x%lx-0x%08x\n", + bar2, mem_len, bar0, i2o_len); + + rc = check_mem_region(bar2, mem_len); + if (rc) { + BCMLOG_ERR("No valid mem region...\n"); + return -ENOMEM; + } + + pinfo->addr = ioremap_nocache(bar2, mem_len); + if (!pinfo->addr) { + BCMLOG_ERR("Failed to remap mem region...\n"); + return -ENOMEM; + } + + pinfo->pci_mem_start = bar2; + pinfo->pci_mem_len = mem_len; + + rc = check_mem_region(bar0, i2o_len); + if (rc) { + BCMLOG_ERR("No valid mem region...\n"); + return -ENOMEM; + } + + pinfo->i2o_addr = ioremap_nocache(bar0, i2o_len); + if (!pinfo->i2o_addr) { + BCMLOG_ERR("Failed to remap mem region...\n"); + return -ENOMEM; + } + + pinfo->pci_i2o_start = bar0; + pinfo->pci_i2o_len = i2o_len; + + rc = pci_request_regions(pinfo->pdev, pinfo->name); + if (rc < 0) { + BCMLOG_ERR("Region request failed: %d\n", rc); + return rc; + } + + BCMLOG(BCMLOG_SSTEP, "Mapped addr:0x%08lx i2o_addr:0x%08lx\n", + (unsigned long)pinfo->addr, (unsigned long)pinfo->i2o_addr); + + return 0; +} + +static void __devexit chd_pci_release_mem(struct crystalhd_adp *pinfo) +{ + if (!pinfo) + return; + + if (pinfo->addr) + iounmap(pinfo->addr); + + if (pinfo->i2o_addr) + iounmap(pinfo->i2o_addr); + + pci_release_regions(pinfo->pdev); +} + + +static void __devexit chd_dec_pci_remove(struct pci_dev *pdev) +{ + struct crystalhd_adp *pinfo; + BC_STATUS sts = BC_STS_SUCCESS; + + BCMLOG_ENTER; + + pinfo = (struct crystalhd_adp *) pci_get_drvdata(pdev); + if (!pinfo) { + BCMLOG_ERR("could not get adp\n"); + return; + } + + sts = crystalhd_delete_cmd_context(&pinfo->cmds); + if (sts != BC_STS_SUCCESS) + BCMLOG_ERR("cmd delete :%d \n", sts); + + chd_dec_release_chdev(pinfo); + + chd_dec_disable_int(pinfo); + + chd_pci_release_mem(pinfo); + pci_disable_device(pinfo->pdev); + + kfree(pinfo); + g_adp_info = NULL; +} + +static int __devinit chd_dec_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *entry) +{ + struct crystalhd_adp *pinfo; + int rc; + BC_STATUS sts = BC_STS_SUCCESS; + + BCMLOG(BCMLOG_DBG, "PCI_INFO: Vendor:0x%04x Device:0x%04x " + "s_vendor:0x%04x s_device: 0x%04x\n", + pdev->vendor, pdev->device, pdev->subsystem_vendor, + pdev->subsystem_device); + + /* FIXME: jarod: why atomic? */ + pinfo = kzalloc(sizeof(struct crystalhd_adp), GFP_ATOMIC); + if (!pinfo) { + BCMLOG_ERR("Failed to allocate memory\n"); + return -ENOMEM; + } + + pinfo->pdev = pdev; + + rc = pci_enable_device(pdev); + if (rc) { + BCMLOG_ERR("Failed to enable PCI device\n"); + return rc; + } + + snprintf(pinfo->name, 31, "crystalhd_pci_e:%d:%d:%d", + pdev->bus->number, PCI_SLOT(pdev->devfn), + PCI_FUNC(pdev->devfn)); + + rc = chd_pci_reserve_mem(pinfo); + if (rc) { + BCMLOG_ERR("Failed to setup memory regions.\n"); + return -ENOMEM; + } + + pinfo->present = 1; + pinfo->drv_data = entry->driver_data; + + /* Setup adapter level lock.. */ + spin_lock_init(&pinfo->lock); + + /* setup api stuff.. */ + chd_dec_init_chdev(pinfo); + rc = chd_dec_enable_int(pinfo); + if (rc) { + BCMLOG_ERR("_enable_int err:%d \n", rc); + pci_disable_device(pdev); + return -ENODEV; + } + + /* Set dma mask... */ + if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { + pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)); + pinfo->dmabits = 64; + } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) { + pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); + pinfo->dmabits = 32; + } else { + BCMLOG_ERR("Unabled to setup DMA %d\n", rc); + pci_disable_device(pdev); + return -ENODEV; + } + + sts = crystalhd_setup_cmd_context(&pinfo->cmds, pinfo); + if (sts != BC_STS_SUCCESS) { + BCMLOG_ERR("cmd setup :%d \n", sts); + pci_disable_device(pdev); + return -ENODEV; + } + + pci_set_master(pdev); + + pci_set_drvdata(pdev, pinfo); + + g_adp_info = pinfo; + + return 0; +} + +#ifdef CONFIG_PM +int chd_dec_pci_suspend(struct pci_dev *pdev, pm_message_t state) +{ + struct crystalhd_adp *adp; + crystalhd_ioctl_data *temp; + BC_STATUS sts = BC_STS_SUCCESS; + + adp = (struct crystalhd_adp *)pci_get_drvdata(pdev); + if (!adp) { + BCMLOG_ERR("could not get adp\n"); + return -ENODEV; + } + + temp = chd_dec_alloc_iodata(adp, false); + if (!temp) { + BCMLOG_ERR("could not get ioctl data\n"); + return -ENODEV; + } + + sts = crystalhd_suspend(&adp->cmds, temp); + if (sts != BC_STS_SUCCESS) { + BCMLOG_ERR("BCM70012 Suspend %d\n", sts); + return -ENODEV; + } + + chd_dec_free_iodata(adp, temp, false); + chd_dec_disable_int(adp); + pci_save_state(pdev); + + /* Disable IO/bus master/irq router */ + pci_disable_device(pdev); + pci_set_power_state(pdev, pci_choose_state(pdev, state)); + return 0; +} + +int chd_dec_pci_resume(struct pci_dev *pdev) +{ + struct crystalhd_adp *adp; + BC_STATUS sts = BC_STS_SUCCESS; + int rc; + + adp = (struct crystalhd_adp *)pci_get_drvdata(pdev); + if (!adp) { + BCMLOG_ERR("could not get adp\n"); + return -ENODEV; + } + + pci_set_power_state(pdev, PCI_D0); + pci_restore_state(pdev); + + /* device's irq possibly is changed, driver should take care */ + if (pci_enable_device(pdev)) { + BCMLOG_ERR("Failed to enable PCI device\n"); + return 1; + } + + pci_set_master(pdev); + + rc = chd_dec_enable_int(adp); + if (rc) { + BCMLOG_ERR("_enable_int err:%d \n", rc); + pci_disable_device(pdev); + return -ENODEV; + } + + sts = crystalhd_resume(&adp->cmds); + if (sts != BC_STS_SUCCESS) { + BCMLOG_ERR("BCM70012 Resume %d\n", sts); + pci_disable_device(pdev); + return -ENODEV; + } + + return 0; +} +#endif + +static DEFINE_PCI_DEVICE_TABLE(chd_dec_pci_id_table) = { + { PCI_VDEVICE(BROADCOM, 0x1612), 8 }, + { 0, }, +}; +MODULE_DEVICE_TABLE(pci, chd_dec_pci_id_table); + +static struct pci_driver bc_chd_70012_driver = { + .name = "Broadcom 70012 Decoder", + .probe = chd_dec_pci_probe, + .remove = __devexit_p(chd_dec_pci_remove), + .id_table = chd_dec_pci_id_table, +#ifdef CONFIG_PM + .suspend = chd_dec_pci_suspend, + .resume = chd_dec_pci_resume +#endif +}; + +void chd_set_log_level(struct crystalhd_adp *adp, char *arg) +{ + if ((!arg) || (strlen(arg) < 3)) + g_linklog_level = BCMLOG_ERROR | BCMLOG_DATA; + else if (!strncmp(arg, "sstep", 5)) + g_linklog_level = BCMLOG_INFO | BCMLOG_DATA | BCMLOG_DBG | + BCMLOG_SSTEP | BCMLOG_ERROR; + else if (!strncmp(arg, "info", 4)) + g_linklog_level = BCMLOG_ERROR | BCMLOG_DATA | BCMLOG_INFO; + else if (!strncmp(arg, "debug", 5)) + g_linklog_level = BCMLOG_ERROR | BCMLOG_DATA | BCMLOG_INFO | + BCMLOG_DBG; + else if (!strncmp(arg, "pball", 5)) + g_linklog_level = 0xFFFFFFFF & ~(BCMLOG_SPINLOCK); + else if (!strncmp(arg, "silent", 6)) + g_linklog_level = 0; + else + g_linklog_level = 0; +} + +struct crystalhd_adp *chd_get_adp(void) +{ + return g_adp_info; +} + +static int __init chd_dec_module_init(void) +{ + int rc; + + chd_set_log_level(NULL, "debug"); + BCMLOG(BCMLOG_DATA, "Loading crystalhd %d.%d.%d \n", + crystalhd_kmod_major, crystalhd_kmod_minor, crystalhd_kmod_rev); + + rc = pci_register_driver(&bc_chd_70012_driver); + + if (rc < 0) + BCMLOG_ERR("Could not find any devices. err:%d \n", rc); + + return rc; +} +module_init(chd_dec_module_init); + +static void __exit chd_dec_module_cleanup(void) +{ + BCMLOG(BCMLOG_DATA, "unloading crystalhd %d.%d.%d \n", + crystalhd_kmod_major, crystalhd_kmod_minor, crystalhd_kmod_rev); + + pci_unregister_driver(&bc_chd_70012_driver); +} +module_exit(chd_dec_module_cleanup); + +MODULE_AUTHOR("Naren Sankar <nsankar@broadcom.com>"); +MODULE_AUTHOR("Prasad Bolisetty <prasadb@broadcom.com>"); +MODULE_DESCRIPTION(CRYSTAL_HD_NAME); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("bcm70012"); diff --git a/drivers/staging/crystalhd/crystalhd_lnx.h b/drivers/staging/crystalhd/crystalhd_lnx.h new file mode 100644 index 0000000..d338ae9 --- /dev/null +++ b/drivers/staging/crystalhd/crystalhd_lnx.h @@ -0,0 +1,96 @@ +/*************************************************************************** + * Copyright (c) 2005-2009, Broadcom Corporation. + * + * Name: crystalhd_lnx . c + * + * Description: + * BCM70012 Linux driver + * + * HISTORY: + * + ********************************************************************** + * This file is part of the crystalhd device driver. + * + * This driver is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This driver is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this driver. If not, see <http://www.gnu.org/licenses/>. + **********************************************************************/ + +#ifndef _CRYSTALHD_LNX_H_ +#define _CRYSTALHD_LNX_H_ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/string.h> +#include <linux/mm.h> +#include <linux/tty.h> +#include <linux/slab.h> +#include <linux/delay.h> +#include <linux/fb.h> +#include <linux/pci.h> +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/pagemap.h> +#include <linux/vmalloc.h> + +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/pgtable.h> +#include <asm/system.h> +#include <asm/uaccess.h> + +#include "crystalhd_cmds.h" + +#define CRYSTAL_HD_NAME "Broadcom Crystal HD Decoder (BCM70012) Driver" + + +/* OS specific PCI information structure and adapter information. */ +struct crystalhd_adp { + /* Hardware borad/PCI specifics */ + char name[32]; + struct pci_dev *pdev; + + unsigned long pci_mem_start; + uint32_t pci_mem_len; + void *addr; + + unsigned long pci_i2o_start; + uint32_t pci_i2o_len; + void *i2o_addr; + + unsigned int drv_data; + unsigned int dmabits; /* 32 | 64 */ + unsigned int registered; + unsigned int present; + unsigned int msi; + + spinlock_t lock; + + /* API Related */ + unsigned int chd_dec_major; + unsigned int cfg_users; + + crystalhd_ioctl_data *idata_free_head; /* ioctl data pool */ + crystalhd_elem_t *elem_pool_head; /* Queue element pool */ + + struct crystalhd_cmd cmds; + + crystalhd_dio_req *ua_map_free_head; + struct pci_pool *fill_byte_pool; +}; + + +struct crystalhd_adp *chd_get_adp(void); +void chd_set_log_level(struct crystalhd_adp *adp, char *arg); + +#endif + diff --git a/drivers/staging/crystalhd/crystalhd_misc.c b/drivers/staging/crystalhd/crystalhd_misc.c new file mode 100644 index 0000000..587dcc4 --- /dev/null +++ b/drivers/staging/crystalhd/crystalhd_misc.c @@ -0,0 +1,1030 @@ +/*************************************************************************** + * Copyright (c) 2005-2009, Broadcom Corporation. + * + * Name: crystalhd_misc . c + * + * Description: + * BCM70012 Linux driver misc routines. + * + * HISTORY: + * + ********************************************************************** + * This file is part of the crystalhd device driver. + * + * This driver is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This driver is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this driver. If not, see <http://www.gnu.org/licenses/>. + **********************************************************************/ + +#include "crystalhd_misc.h" +#include "crystalhd_lnx.h" + +uint32_t g_linklog_level; + +static inline uint32_t crystalhd_dram_rd(struct crystalhd_adp *adp, uint32_t mem_off) +{ + crystalhd_reg_wr(adp, DCI_DRAM_BASE_ADDR, (mem_off >> 19)); + return bc_dec_reg_rd(adp, (0x00380000 | (mem_off & 0x0007FFFF))); +} + +static inline void crystalhd_dram_wr(struct crystalhd_adp *adp, uint32_t mem_off, uint32_t val) +{ + crystalhd_reg_wr(adp, DCI_DRAM_BASE_ADDR, (mem_off >> 19)); + bc_dec_reg_wr(adp, (0x00380000 | (mem_off & 0x0007FFFF)), val); +} + +static inline BC_STATUS bc_chk_dram_range(struct crystalhd_adp *adp, uint32_t start_off, uint32_t cnt) +{ + return BC_STS_SUCCESS; +} + +static crystalhd_dio_req *crystalhd_alloc_dio(struct crystalhd_adp *adp) +{ + unsigned long flags = 0; + crystalhd_dio_req *temp = NULL; + + if (!adp) { + BCMLOG_ERR("Invalid Arg!!\n"); + return temp; + } + + spin_lock_irqsave(&adp->lock, flags); + temp = adp->ua_map_free_head; + if (temp) + adp->ua_map_free_head = adp->ua_map_free_head->next; + spin_unlock_irqrestore(&adp->lock, flags); + + return temp; +} + +static void crystalhd_free_dio(struct crystalhd_adp *adp, crystalhd_dio_req *dio) +{ + unsigned long flags = 0; + + if (!adp || !dio) + return; + spin_lock_irqsave(&adp->lock, flags); + dio->sig = crystalhd_dio_inv; + dio->page_cnt = 0; + dio->fb_size = 0; + memset(&dio->uinfo, 0, sizeof(dio->uinfo)); + dio->next = adp->ua_map_free_head; + adp->ua_map_free_head = dio; + spin_unlock_irqrestore(&adp->lock, flags); +} + +static crystalhd_elem_t *crystalhd_alloc_elem(struct crystalhd_adp *adp) +{ + unsigned long flags = 0; + crystalhd_elem_t *temp = NULL; + + if (!adp) + return temp; + spin_lock_irqsave(&adp->lock, flags); + temp = adp->elem_pool_head; + if (temp) { + adp->elem_pool_head = adp->elem_pool_head->flink; + memset(temp, 0, sizeof(*temp)); + } + spin_unlock_irqrestore(&adp->lock, flags); + + return temp; +} +static void crystalhd_free_elem(struct crystalhd_adp *adp, crystalhd_elem_t *elem) +{ + unsigned long flags = 0; + + if (!adp || !elem) + return; + spin_lock_irqsave(&adp->lock, flags); + elem->flink = adp->elem_pool_head; + adp->elem_pool_head = elem; + spin_unlock_irqrestore(&adp->lock, flags); +} + +static inline void crystalhd_set_sg(struct scatterlist *sg, struct page *page, + unsigned int len, unsigned int offset) +{ + sg_set_page(sg, page, len, offset); +#ifdef CONFIG_X86_64 + sg->dma_length = len; +#endif +} + +static inline void crystalhd_init_sg(struct scatterlist *sg, unsigned int entries) +{ + /* http://lkml.org/lkml/2007/11/27/68 */ + sg_init_table(sg, entries); +} + +/*========================== Extern ========================================*/ +/** + * bc_dec_reg_rd - Read 7412's device register. + * @adp: Adapter instance + * @reg_off: Register offset. + * + * Return: + * 32bit value read + * + * 7412's device register read routine. This interface use + * 7412's device access range mapped from BAR-2 (4M) of PCIe + * configuration space. + */ +uint32_t bc_dec_reg_rd(struct crystalhd_adp *adp, uint32_t reg_off) +{ + if (!adp || (reg_off > adp->pci_mem_len)) { + BCMLOG_ERR("dec_rd_reg_off outof range: 0x%08x\n", reg_off); + return 0; + } + + return readl(adp->addr + reg_off); +} + +/** + * bc_dec_reg_wr - Write 7412's device register + * @adp: Adapter instance + * @reg_off: Register offset. + * @val: Dword value to be written. + * + * Return: + * none. + * + * 7412's device register write routine. This interface use + * 7412's device access range mapped from BAR-2 (4M) of PCIe + * configuration space. + */ +void bc_dec_reg_wr(struct crystalhd_adp *adp, uint32_t reg_off, uint32_t val) +{ + if (!adp || (reg_off > adp->pci_mem_len)) { + BCMLOG_ERR("dec_wr_reg_off outof range: 0x%08x\n", reg_off); + return; + } + writel(val, adp->addr + reg_off); + udelay(8); +} + +/** + * crystalhd_reg_rd - Read Link's device register. + * @adp: Adapter instance + * @reg_off: Register offset. + * + * Return: + * 32bit value read + * + * Link device register read routine. This interface use + * Link's device access range mapped from BAR-1 (64K) of PCIe + * configuration space. + * + */ +uint32_t crystalhd_reg_rd(struct crystalhd_adp *adp, uint32_t reg_off) +{ + if (!adp || (reg_off > adp->pci_i2o_len)) { + BCMLOG_ERR("link_rd_reg_off outof range: 0x%08x\n", reg_off); + return 0; + } + return readl(adp->i2o_addr + reg_off); +} + +/** + * crystalhd_reg_wr - Write Link's device register + * @adp: Adapter instance + * @reg_off: Register offset. + * @val: Dword value to be written. + * + * Return: + * none. + * + * Link device register write routine. This interface use + * Link's device access range mapped from BAR-1 (64K) of PCIe + * configuration space. + * + */ +void crystalhd_reg_wr(struct crystalhd_adp *adp, uint32_t reg_off, uint32_t val) +{ + if (!adp || (reg_off > adp->pci_i2o_len)) { + BCMLOG_ERR("link_wr_reg_off outof range: 0x%08x\n", reg_off); + return; + } + writel(val, adp->i2o_addr + reg_off); +} + +/** + * crystalhd_mem_rd - Read data from 7412's DRAM area. + * @adp: Adapter instance + * @start_off: Start offset. + * @dw_cnt: Count in dwords. + * @rd_buff: Buffer to copy the data from dram. + * + * Return: + * Status. + * + * 7412's Dram read routine. + */ +BC_STATUS crystalhd_mem_rd(struct crystalhd_adp *adp, uint32_t start_off, + uint32_t dw_cnt, uint32_t *rd_buff) +{ + uint32_t ix = 0; + + if (!adp || !rd_buff || + (bc_chk_dram_range(adp, start_off, dw_cnt) != BC_STS_SUCCESS)) { + BCMLOG_ERR("Invalid arg \n"); + return BC_STS_INV_ARG; + } + for (ix = 0; ix < dw_cnt; ix++) + rd_buff[ix] = crystalhd_dram_rd(adp, (start_off + (ix * 4))); + + return BC_STS_SUCCESS; +} + +/** + * crystalhd_mem_wr - Write data to 7412's DRAM area. + * @adp: Adapter instance + * @start_off: Start offset. + * @dw_cnt: Count in dwords. + * @wr_buff: Data Buffer to be written. + * + * Return: + * Status. + * + * 7412's Dram write routine. + */ +BC_STATUS crystalhd_mem_wr(struct crystalhd_adp *adp, uint32_t start_off, + uint32_t dw_cnt, uint32_t *wr_buff) +{ + uint32_t ix = 0; + + if (!adp || !wr_buff || + (bc_chk_dram_range(adp, start_off, dw_cnt) != BC_STS_SUCCESS)) { + BCMLOG_ERR("Invalid arg \n"); + return BC_STS_INV_ARG; + } + + for (ix = 0; ix < dw_cnt; ix++) + crystalhd_dram_wr(adp, (start_off + (ix * 4)), wr_buff[ix]); + + return BC_STS_SUCCESS; +} +/** + * crystalhd_pci_cfg_rd - PCIe config read + * @adp: Adapter instance + * @off: PCI config space offset. + * @len: Size -- Byte, Word & dword. + * @val: Value read + * + * Return: + * Status. + * + * Get value from Link's PCIe config space. + */ +BC_STATUS crystalhd_pci_cfg_rd(struct crystalhd_adp *adp, uint32_t off, + uint32_t len, uint32_t *val) +{ + BC_STATUS sts = BC_STS_SUCCESS; + int rc = 0; + + if (!adp || !val) { + BCMLOG_ERR("Invalid arg \n"); + return BC_STS_INV_ARG; + } + + switch (len) { + case 1: + rc = pci_read_config_byte(adp->pdev, off, (u8 *)val); + break; + case 2: + rc = pci_read_config_word(adp->pdev, off, (u16 *)val); + break; + case 4: + rc = pci_read_config_dword(adp->pdev, off, (u32 *)val); + break; + default: + rc = -EINVAL; + sts = BC_STS_INV_ARG; + BCMLOG_ERR("Invalid len:%d\n", len); + }; + + if (rc && (sts == BC_STS_SUCCESS)) + sts = BC_STS_ERROR; + + return sts; +} + +/** + * crystalhd_pci_cfg_wr - PCIe config write + * @adp: Adapter instance + * @off: PCI config space offset. + * @len: Size -- Byte, Word & dword. + * @val: Value to be written + * + * Return: + * Status. + * + * Set value to Link's PCIe config space. + */ +BC_STATUS crystalhd_pci_cfg_wr(struct crystalhd_adp *adp, uint32_t off, + uint32_t len, uint32_t val) +{ + BC_STATUS sts = BC_STS_SUCCESS; + int rc = 0; + + if (!adp || !val) { + BCMLOG_ERR("Invalid arg \n"); + return BC_STS_INV_ARG; + } + + switch (len) { + case 1: + rc = pci_write_config_byte(adp->pdev, off, (u8)val); + break; + case 2: + rc = pci_write_config_word(adp->pdev, off, (u16)val); + break; + case 4: + rc = pci_write_config_dword(adp->pdev, off, val); + break; + default: + rc = -EINVAL; + sts = BC_STS_INV_ARG; + BCMLOG_ERR("Invalid len:%d\n", len); + }; + + if (rc && (sts == BC_STS_SUCCESS)) + sts = BC_STS_ERROR; + + return sts; +} + +/** + * bc_kern_dma_alloc - Allocate memory for Dma rings + * @adp: Adapter instance + * @sz: Size of the memory to allocate. + * @phy_addr: Physical address of the memory allocated. + * Typedef to system's dma_addr_t (u64) + * + * Return: + * Pointer to allocated memory.. + * + * Wrapper to Linux kernel interface. + * + */ +void *bc_kern_dma_alloc(struct crystalhd_adp *adp, uint32_t sz, + dma_addr_t *phy_addr) +{ + void *temp = NULL; + + if (!adp || !sz || !phy_addr) { + BCMLOG_ERR("Invalide Arg..\n"); + return temp; + } + + temp = pci_alloc_consistent(adp->pdev, sz, phy_addr); + if (temp) + memset(temp, 0, sz); + + return temp; +} + +/** + * bc_kern_dma_free - Release Dma ring memory. + * @adp: Adapter instance + * @sz: Size of the memory to allocate. + * @ka: Kernel virtual address returned during _dio_alloc() + * @phy_addr: Physical address of the memory allocated. + * Typedef to system's dma_addr_t (u64) + * + * Return: + * none. + */ +void bc_kern_dma_free(struct crystalhd_adp *adp, uint32_t sz, void *ka, + dma_addr_t phy_addr) +{ + if (!adp || !ka || !sz || !phy_addr) { + BCMLOG_ERR("Invalide Arg..\n"); + return; + } + + pci_free_consistent(adp->pdev, sz, ka, phy_addr); +} + +/** + * crystalhd_create_dioq - Create Generic DIO queue + * @adp: Adapter instance + * @dioq_hnd: Handle to the dio queue created + * @cb : Optional - Call back To free the element. + * @cbctx: Context to pass to callback. + * + * Return: + * status + * + * Initialize Generic DIO queue to hold any data. Callback + * will be used to free elements while deleting the queue. + */ +BC_STATUS crystalhd_create_dioq(struct crystalhd_adp *adp, + crystalhd_dioq_t **dioq_hnd, + crystalhd_data_free_cb cb, void *cbctx) +{ + crystalhd_dioq_t *dioq = NULL; + + if (!adp || !dioq_hnd) { + BCMLOG_ERR("Invalid arg!!\n"); + return BC_STS_INV_ARG; + } + + dioq = kzalloc(sizeof(*dioq), GFP_KERNEL); + if (!dioq) + return BC_STS_INSUFF_RES; + + spin_lock_init(&dioq->lock); + dioq->sig = BC_LINK_DIOQ_SIG; + dioq->head = (crystalhd_elem_t *)&dioq->head; + dioq->tail = (crystalhd_elem_t *)&dioq->head; + crystalhd_create_event(&dioq->event); + dioq->adp = adp; + dioq->data_rel_cb = cb; + dioq->cb_context = cbctx; + *dioq_hnd = dioq; + + return BC_STS_SUCCESS; +} + +/** + * crystalhd_delete_dioq - Delete Generic DIO queue + * @adp: Adapter instance + * @dioq: DIOQ instance.. + * + * Return: + * None. + * + * Release Generic DIO queue. This function will remove + * all the entries from the Queue and will release data + * by calling the call back provided during creation. + * + */ +void crystalhd_delete_dioq(struct crystalhd_adp *adp, crystalhd_dioq_t *dioq) +{ + void *temp; + + if (!dioq || (dioq->sig != BC_LINK_DIOQ_SIG)) + return; + + do { + temp = crystalhd_dioq_fetch(dioq); + if (temp && dioq->data_rel_cb) + dioq->data_rel_cb(dioq->cb_context, temp); + } while (temp); + dioq->sig = 0; + kfree(dioq); +} + +/** + * crystalhd_dioq_add - Add new DIO request element. + * @ioq: DIO queue instance + * @t: DIO request to be added. + * @wake: True - Wake up suspended process. + * @tag: Special tag to assign - For search and get. + * + * Return: + * Status. + * + * Insert new element to Q tail. + */ +BC_STATUS crystalhd_dioq_add(crystalhd_dioq_t *ioq, void *data, + bool wake, uint32_t tag) +{ + unsigned long flags = 0; + crystalhd_elem_t *tmp; + + if (!ioq || (ioq->sig != BC_LINK_DIOQ_SIG) || !data) { + BCMLOG_ERR("Invalid arg!!\n"); + return BC_STS_INV_ARG; + } + + tmp = crystalhd_alloc_elem(ioq->adp); + if (!tmp) { + BCMLOG_ERR("No free elements.\n"); + return BC_STS_INSUFF_RES; + } + + tmp->data = data; + tmp->tag = tag; + spin_lock_irqsave(&ioq->lock, flags); + tmp->flink = (crystalhd_elem_t *)&ioq->head; + tmp->blink = ioq->tail; + tmp->flink->blink = tmp; + tmp->blink->flink = tmp; + ioq->count++; + spin_unlock_irqrestore(&ioq->lock, flags); + + if (wake) + crystalhd_set_event(&ioq->event); + + return BC_STS_SUCCESS; +} + +/** + * crystalhd_dioq_fetch - Fetch element from head. + * @ioq: DIO queue instance + * + * Return: + * data element from the head.. + * + * Remove an element from Queue. + */ +void *crystalhd_dioq_fetch(crystalhd_dioq_t *ioq) +{ + unsigned long flags = 0; + crystalhd_elem_t *tmp; + crystalhd_elem_t *ret = NULL; + void *data = NULL; + + if (!ioq || (ioq->sig != BC_LINK_DIOQ_SIG)) { + BCMLOG_ERR("Invalid arg!!\n"); + return data; + } + + spin_lock_irqsave(&ioq->lock, flags); + tmp = ioq->head; + if (tmp != (crystalhd_elem_t *)&ioq->head) { + ret = tmp; + tmp->flink->blink = tmp->blink; + tmp->blink->flink = tmp->flink; + ioq->count--; + } + spin_unlock_irqrestore(&ioq->lock, flags); + if (ret) { + data = ret->data; + crystalhd_free_elem(ioq->adp, ret); + } + + return data; +} +/** + * crystalhd_dioq_find_and_fetch - Search the tag and Fetch element + * @ioq: DIO queue instance + * @tag: Tag to search for. + * + * Return: + * element from the head.. + * + * Search TAG and remove the element. + */ +void *crystalhd_dioq_find_and_fetch(crystalhd_dioq_t *ioq, uint32_t tag) +{ + unsigned long flags = 0; + crystalhd_elem_t *tmp; + crystalhd_elem_t *ret = NULL; + void *data = NULL; + + if (!ioq || (ioq->sig != BC_LINK_DIOQ_SIG)) { + BCMLOG_ERR("Invalid arg!!\n"); + return data; + } + + spin_lock_irqsave(&ioq->lock, flags); + tmp = ioq->head; + while (tmp != (crystalhd_elem_t *)&ioq->head) { + if (tmp->tag == tag) { + ret = tmp; + tmp->flink->blink = tmp->blink; + tmp->blink->flink = tmp->flink; + ioq->count--; + break; + } + tmp = tmp->flink; + } + spin_unlock_irqrestore(&ioq->lock, flags); + + if (ret) { + data = ret->data; + crystalhd_free_elem(ioq->adp, ret); + } + + return data; +} + +/** + * crystalhd_dioq_fetch_wait - Fetch element from Head. + * @ioq: DIO queue instance + * @to_secs: Wait timeout in seconds.. + * + * Return: + * element from the head.. + * + * Return element from head if Q is not empty. Wait for new element + * if Q is empty for Timeout seconds. + */ +void *crystalhd_dioq_fetch_wait(crystalhd_dioq_t *ioq, uint32_t to_secs, + uint32_t *sig_pend) +{ + unsigned long flags = 0; + int rc = 0, count; + void *tmp = NULL; + + if (!ioq || (ioq->sig != BC_LINK_DIOQ_SIG) || !to_secs || !sig_pend) { + BCMLOG_ERR("Invalid arg!!\n"); + return tmp; + } + + count = to_secs; + spin_lock_irqsave(&ioq->lock, flags); + while ((ioq->count == 0) && count) { + spin_unlock_irqrestore(&ioq->lock, flags); + + crystalhd_wait_on_event(&ioq->event, (ioq->count > 0), 1000, rc, 0); + if (rc == 0) { + goto out; + } else if (rc == -EINTR) { + BCMLOG(BCMLOG_INFO, "Cancelling fetch wait\n"); + *sig_pend = 1; + return tmp; + } + spin_lock_irqsave(&ioq->lock, flags); + count--; + } + spin_unlock_irqrestore(&ioq->lock, flags); + +out: + return crystalhd_dioq_fetch(ioq); +} + +/** + * crystalhd_map_dio - Map user address for DMA + * @adp: Adapter instance + * @ubuff: User buffer to map. + * @ubuff_sz: User buffer size. + * @uv_offset: UV buffer offset. + * @en_422mode: TRUE:422 FALSE:420 Capture mode. + * @dir_tx: TRUE for Tx (To device from host) + * @dio_hnd: Handle to mapped DIO request. + * + * Return: + * Status. + * + * This routine maps user address and lock pages for DMA. + * + */ +BC_STATUS crystalhd_map_dio(struct crystalhd_adp *adp, void *ubuff, + uint32_t ubuff_sz, uint32_t uv_offset, + bool en_422mode, bool dir_tx, + crystalhd_dio_req **dio_hnd) +{ + crystalhd_dio_req *dio; + /* FIXME: jarod: should some of these unsigned longs be uint32_t or uintptr_t? */ + unsigned long start = 0, end = 0, uaddr = 0, count = 0; + unsigned long spsz = 0, uv_start = 0; + int i = 0, rw = 0, res = 0, nr_pages = 0, skip_fb_sg = 0; + + if (!adp || !ubuff || !ubuff_sz || !dio_hnd) { + BCMLOG_ERR("Invalid arg \n"); + return BC_STS_INV_ARG; + } + /* Compute pages */ + uaddr = (unsigned long)ubuff; + count = (unsigned long)ubuff_sz; + end = (uaddr + count + PAGE_SIZE - 1) >> PAGE_SHIFT; + start = uaddr >> PAGE_SHIFT; + nr_pages = end - start; + + if (!count || ((uaddr + count) < uaddr)) { + BCMLOG_ERR("User addr overflow!!\n"); + return BC_STS_INV_ARG; + } + + dio = crystalhd_alloc_dio(adp); + if (!dio) { + BCMLOG_ERR("dio pool empty..\n"); + return BC_STS_INSUFF_RES; + } + + if (dir_tx) { + rw = WRITE; + dio->direction = DMA_TO_DEVICE; + } else { + rw = READ; + dio->direction = DMA_FROM_DEVICE; + } + + if (nr_pages > dio->max_pages) { + BCMLOG_ERR("max_pages(%d) exceeded(%d)!!\n", + dio->max_pages, nr_pages); + crystalhd_unmap_dio(adp, dio); + return BC_STS_INSUFF_RES; + } + + if (uv_offset) { + uv_start = (uaddr + (unsigned long)uv_offset) >> PAGE_SHIFT; + dio->uinfo.uv_sg_ix = uv_start - start; + dio->uinfo.uv_sg_off = ((uaddr + (unsigned long)uv_offset) & ~PAGE_MASK); + } + + dio->fb_size = ubuff_sz & 0x03; + if (dio->fb_size) { + res = copy_from_user(dio->fb_va, + (void *)(uaddr + count - dio->fb_size), + dio->fb_size); + if (res) { + BCMLOG_ERR("failed %d to copy %u fill bytes from %p\n", + res, dio->fb_size, + (void *)(uaddr + count-dio->fb_size)); + crystalhd_unmap_dio(adp, dio); + return BC_STS_INSUFF_RES; + } + } + + down_read(¤t->mm->mmap_sem); + res = get_user_pages(current, current->mm, uaddr, nr_pages, rw == READ, + 0, dio->pages, NULL); + up_read(¤t->mm->mmap_sem); + + /* Save for release..*/ + dio->sig = crystalhd_dio_locked; + if (res < nr_pages) { + BCMLOG_ERR("get pages failed: %d-%d\n", nr_pages, res); + dio->page_cnt = res; + crystalhd_unmap_dio(adp, dio); + return BC_STS_ERROR; + } + + dio->page_cnt = nr_pages; + /* Get scatter/gather */ + crystalhd_init_sg(dio->sg, dio->page_cnt); + crystalhd_set_sg(&dio->sg[0], dio->pages[0], 0, uaddr & ~PAGE_MASK); + if (nr_pages > 1) { + dio->sg[0].length = PAGE_SIZE - dio->sg[0].offset; + +#ifdef CONFIG_X86_64 + dio->sg[0].dma_length = dio->sg[0].length; +#endif + count -= dio->sg[0].length; + for (i = 1; i < nr_pages; i++) { + if (count < 4) { + spsz = count; + skip_fb_sg = 1; + } else { + spsz = (count < PAGE_SIZE) ? + (count & ~0x03) : PAGE_SIZE; + } + crystalhd_set_sg(&dio->sg[i], dio->pages[i], spsz, 0); + count -= spsz; + } + } else { + if (count < 4) { + dio->sg[0].length = count; + skip_fb_sg = 1; + } else { + dio->sg[0].length = count - dio->fb_size; + } +#ifdef CONFIG_X86_64 + dio->sg[0].dma_length = dio->sg[0].length; +#endif + } + dio->sg_cnt = pci_map_sg(adp->pdev, dio->sg, + dio->page_cnt, dio->direction); + if (dio->sg_cnt <= 0) { + BCMLOG_ERR("sg map %d-%d \n", dio->sg_cnt, dio->page_cnt); + crystalhd_unmap_dio(adp, dio); + return BC_STS_ERROR; + } + if (dio->sg_cnt && skip_fb_sg) + dio->sg_cnt -= 1; + dio->sig = crystalhd_dio_sg_mapped; + /* Fill in User info.. */ + dio->uinfo.xfr_len = ubuff_sz; + dio->uinfo.xfr_buff = ubuff; + dio->uinfo.uv_offset = uv_offset; + dio->uinfo.b422mode = en_422mode; + dio->uinfo.dir_tx = dir_tx; + + *dio_hnd = dio; + + return BC_STS_SUCCESS; +} + +/** + * crystalhd_unmap_sgl - Release mapped resources + * @adp: Adapter instance + * @dio: DIO request instance + * + * Return: + * Status. + * + * This routine is to unmap the user buffer pages. + */ +BC_STATUS crystalhd_unmap_dio(struct crystalhd_adp *adp, crystalhd_dio_req *dio) +{ + struct page *page = NULL; + int j = 0; + + if (!adp || !dio) { + BCMLOG_ERR("Invalid arg \n"); + return BC_STS_INV_ARG; + } + + if ((dio->page_cnt > 0) && (dio->sig != crystalhd_dio_inv)) { + for (j = 0; j < dio->page_cnt; j++) { + page = dio->pages[j]; + if (page) { + if (!PageReserved(page) && + (dio->direction == DMA_FROM_DEVICE)) + SetPageDirty(page); + page_cache_release(page); + } + } + } + if (dio->sig == crystalhd_dio_sg_mapped) + pci_unmap_sg(adp->pdev, dio->sg, dio->page_cnt, dio->direction); + + crystalhd_free_dio(adp, dio); + + return BC_STS_SUCCESS; +} + +/** + * crystalhd_create_dio_pool - Allocate mem pool for DIO management. + * @adp: Adapter instance + * @max_pages: Max pages for size calculation. + * + * Return: + * system error. + * + * This routine creates a memory pool to hold dio context for + * for HW Direct IO operation. + */ +int crystalhd_create_dio_pool(struct crystalhd_adp *adp, uint32_t max_pages) +{ + uint32_t asz = 0, i = 0; + uint8_t *temp; + crystalhd_dio_req *dio; + + if (!adp || !max_pages) { + BCMLOG_ERR("Invalid Arg!!\n"); + return -EINVAL; + } + + /* Get dma memory for fill byte handling..*/ + adp->fill_byte_pool = pci_pool_create("crystalhd_fbyte", + adp->pdev, 8, 8, 0); + if (!adp->fill_byte_pool) { + BCMLOG_ERR("failed to create fill byte pool\n"); + return -ENOMEM; + } + + /* Get the max size from user based on 420/422 modes */ + asz = (sizeof(*dio->pages) * max_pages) + + (sizeof(*dio->sg) * max_pages) + sizeof(*dio); + + BCMLOG(BCMLOG_DBG, "Initializing Dio pool %d %d %x %p\n", + BC_LINK_SG_POOL_SZ, max_pages, asz, adp->fill_byte_pool); + + for (i = 0; i < BC_LINK_SG_POOL_SZ; i++) { + temp = (uint8_t *)kzalloc(asz, GFP_KERNEL); + if ((temp) == NULL) { + BCMLOG_ERR("Failed to alloc %d mem\n", asz); + return -ENOMEM; + } + + dio = (crystalhd_dio_req *)temp; + temp += sizeof(*dio); + dio->pages = (struct page **)temp; + temp += (sizeof(*dio->pages) * max_pages); + dio->sg = (struct scatterlist *)temp; + dio->max_pages = max_pages; + dio->fb_va = pci_pool_alloc(adp->fill_byte_pool, GFP_KERNEL, + &dio->fb_pa); + if (!dio->fb_va) { + BCMLOG_ERR("fill byte alloc failed.\n"); + return -ENOMEM; + } + + crystalhd_free_dio(adp, dio); + } + + return 0; +} + +/** + * crystalhd_destroy_dio_pool - Release DIO mem pool. + * @adp: Adapter instance + * + * Return: + * none. + * + * This routine releases dio memory pool during close. + */ +void crystalhd_destroy_dio_pool(struct crystalhd_adp *adp) +{ + crystalhd_dio_req *dio; + int count = 0; + + if (!adp) { + BCMLOG_ERR("Invalid Arg!!\n"); + return; + } + + do { + dio = crystalhd_alloc_dio(adp); + if (dio) { + if (dio->fb_va) + pci_pool_free(adp->fill_byte_pool, + dio->fb_va, dio->fb_pa); + count++; + kfree(dio); + } + } while (dio); + + if (adp->fill_byte_pool) { + pci_pool_destroy(adp->fill_byte_pool); + adp->fill_byte_pool = NULL; + } + + BCMLOG(BCMLOG_DBG, "Released dio pool %d \n", count); +} + +/** + * crystalhd_create_elem_pool - List element pool creation. + * @adp: Adapter instance + * @pool_size: Number of elements in the pool. + * + * Return: + * 0 - success, <0 error + * + * Create general purpose list element pool to hold pending, + * and active requests. + */ +int __devinit crystalhd_create_elem_pool(struct crystalhd_adp *adp, + uint32_t pool_size) +{ + uint32_t i; + crystalhd_elem_t *temp; + + if (!adp || !pool_size) + return -EINVAL; + + for (i = 0; i < pool_size; i++) { + temp = kzalloc(sizeof(*temp), GFP_KERNEL); + if (!temp) { + BCMLOG_ERR("kalloc failed \n"); + return -ENOMEM; + } + crystalhd_free_elem(adp, temp); + } + BCMLOG(BCMLOG_DBG, "allocated %d elem\n", pool_size); + return 0; +} + +/** + * crystalhd_delete_elem_pool - List element pool deletion. + * @adp: Adapter instance + * + * Return: + * none + * + * Delete general purpose list element pool. + */ +void crystalhd_delete_elem_pool(struct crystalhd_adp *adp) +{ + crystalhd_elem_t *temp; + int dbg_cnt = 0; + + if (!adp) + return; + + do { + temp = crystalhd_alloc_elem(adp); + if (temp) { + kfree(temp); + dbg_cnt++; + } + } while (temp); + + BCMLOG(BCMLOG_DBG, "released %d elem\n", dbg_cnt); +} + +/*================ Debug support routines.. ================================*/ +void crystalhd_show_buffer(uint32_t off, uint8_t *buff, uint32_t dwcount) +{ + uint32_t i, k = 1; + + for (i = 0; i < dwcount; i++) { + if (k == 1) + BCMLOG(BCMLOG_DATA, "0x%08X : ", off); + + BCMLOG(BCMLOG_DATA, " 0x%08X ", *((uint32_t *)buff)); + + buff += sizeof(uint32_t); + off += sizeof(uint32_t); + k++; + if ((i == dwcount - 1) || (k > 4)) { + BCMLOG(BCMLOG_DATA, "\n"); + k = 1; + } + } +} diff --git a/drivers/staging/crystalhd/crystalhd_misc.h b/drivers/staging/crystalhd/crystalhd_misc.h new file mode 100644 index 0000000..a2aa6ad --- /dev/null +++ b/drivers/staging/crystalhd/crystalhd_misc.h @@ -0,0 +1,229 @@ +/*************************************************************************** + * Copyright (c) 2005-2009, Broadcom Corporation. + * + * Name: crystalhd_misc . h + * + * Description: + * BCM70012 Linux driver general purpose routines. + * Includes reg/mem read and write routines. + * + * HISTORY: + * + ********************************************************************** + * This file is part of the crystalhd device driver. + * + * This driver is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This driver is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this driver. If not, see <http://www.gnu.org/licenses/>. + **********************************************************************/ + +#ifndef _CRYSTALHD_MISC_H_ +#define _CRYSTALHD_MISC_H_ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/string.h> +#include <linux/ioctl.h> +#include <linux/dma-mapping.h> +#include <linux/version.h> +#include <linux/sched.h> +#include <asm/system.h> +#include "bc_dts_glob_lnx.h" + +/* Global log level variable defined in crystal_misc.c file */ +extern uint32_t g_linklog_level; + +/* Global element pool for all Queue management. + * TX: Active = BC_TX_LIST_CNT, Free = BC_TX_LIST_CNT. + * RX: Free = BC_RX_LIST_CNT, Active = 2 + * FW-CMD: 4 + */ +#define BC_LINK_ELEM_POOL_SZ ((BC_TX_LIST_CNT * 2) + BC_RX_LIST_CNT + 2 + 4) + +/* Driver's IODATA pool count */ +#define CHD_IODATA_POOL_SZ (BC_IOCTL_DATA_POOL_SIZE * BC_LINK_MAX_OPENS) + +/* Scatter Gather memory pool size for Tx and Rx */ +#define BC_LINK_SG_POOL_SZ (BC_TX_LIST_CNT + BC_RX_LIST_CNT) + +enum _crystalhd_dio_sig { + crystalhd_dio_inv = 0, + crystalhd_dio_locked, + crystalhd_dio_sg_mapped, +}; + +struct crystalhd_dio_user_info { + void *xfr_buff; + uint32_t xfr_len; + uint32_t uv_offset; + bool dir_tx; + + uint32_t uv_sg_ix; + uint32_t uv_sg_off; + int comp_sts; + int ev_sts; + uint32_t y_done_sz; + uint32_t uv_done_sz; + uint32_t comp_flags; + bool b422mode; +}; + +typedef struct _crystalhd_dio_req { + uint32_t sig; + uint32_t max_pages; + struct page **pages; + struct scatterlist *sg; + int sg_cnt; + int page_cnt; + int direction; + struct crystalhd_dio_user_info uinfo; + void *fb_va; + uint32_t fb_size; + dma_addr_t fb_pa; + struct _crystalhd_dio_req *next; +} crystalhd_dio_req; + +#define BC_LINK_DIOQ_SIG (0x09223280) + +typedef struct _crystalhd_elem_s { + struct _crystalhd_elem_s *flink; + struct _crystalhd_elem_s *blink; + void *data; + uint32_t tag; +} crystalhd_elem_t; + +typedef void (*crystalhd_data_free_cb)(void *context, void *data); + +typedef struct _crystalhd_dioq_s { + uint32_t sig; + struct crystalhd_adp *adp; + crystalhd_elem_t *head; + crystalhd_elem_t *tail; + uint32_t count; + spinlock_t lock; + wait_queue_head_t event; + crystalhd_data_free_cb data_rel_cb; + void *cb_context; +} crystalhd_dioq_t; + +typedef void (*hw_comp_callback)(crystalhd_dio_req *, + wait_queue_head_t *event, BC_STATUS sts); + +/*========= Decoder (7412) register access routines.================= */ +uint32_t bc_dec_reg_rd(struct crystalhd_adp *, uint32_t); +void bc_dec_reg_wr(struct crystalhd_adp *, uint32_t, uint32_t); + +/*========= Link (70012) register access routines.. =================*/ +uint32_t crystalhd_reg_rd(struct crystalhd_adp *, uint32_t); +void crystalhd_reg_wr(struct crystalhd_adp *, uint32_t, uint32_t); + +/*========= Decoder (7412) memory access routines..=================*/ +BC_STATUS crystalhd_mem_rd(struct crystalhd_adp *, uint32_t, uint32_t, uint32_t *); +BC_STATUS crystalhd_mem_wr(struct crystalhd_adp *, uint32_t, uint32_t, uint32_t *); + +/*==========Link (70012) PCIe Config access routines.================*/ +BC_STATUS crystalhd_pci_cfg_rd(struct crystalhd_adp *, uint32_t, uint32_t, uint32_t *); +BC_STATUS crystalhd_pci_cfg_wr(struct crystalhd_adp *, uint32_t, uint32_t, uint32_t); + +/*========= Linux Kernel Interface routines. ======================= */ +void *bc_kern_dma_alloc(struct crystalhd_adp *, uint32_t, dma_addr_t *); +void bc_kern_dma_free(struct crystalhd_adp *, uint32_t, + void *, dma_addr_t); +#define crystalhd_create_event(_ev) init_waitqueue_head(_ev) +#define crystalhd_set_event(_ev) wake_up_interruptible(_ev) +#define crystalhd_wait_on_event(ev, condition, timeout, ret, nosig) \ +do { \ + DECLARE_WAITQUEUE(entry, current); \ + unsigned long end = jiffies + ((timeout * HZ) / 1000); \ + ret = 0; \ + add_wait_queue(ev, &entry); \ + for (;;) { \ + __set_current_state(TASK_INTERRUPTIBLE); \ + if (condition) { \ + break; \ + } \ + if (time_after_eq(jiffies, end)) { \ + ret = -EBUSY; \ + break; \ + } \ + schedule_timeout((HZ / 100 > 1) ? HZ / 100 : 1); \ + if (!nosig && signal_pending(current)) { \ + ret = -EINTR; \ + break; \ + } \ + } \ + __set_current_state(TASK_RUNNING); \ + remove_wait_queue(ev, &entry); \ +} while (0) + +/*================ Direct IO mapping routines ==================*/ +extern int crystalhd_create_dio_pool(struct crystalhd_adp *, uint32_t); +extern void crystalhd_destroy_dio_pool(struct crystalhd_adp *); +extern BC_STATUS crystalhd_map_dio(struct crystalhd_adp *, void *, uint32_t, + uint32_t, bool, bool, crystalhd_dio_req**); + +extern BC_STATUS crystalhd_unmap_dio(struct crystalhd_adp *, crystalhd_dio_req*); +#define crystalhd_get_sgle_paddr(_dio, _ix) (cpu_to_le64(sg_dma_address(&_dio->sg[_ix]))) +#define crystalhd_get_sgle_len(_dio, _ix) (cpu_to_le32(sg_dma_len(&_dio->sg[_ix]))) + +/*================ General Purpose Queues ==================*/ +extern BC_STATUS crystalhd_create_dioq(struct crystalhd_adp *, crystalhd_dioq_t **, crystalhd_data_free_cb , void *); +extern void crystalhd_delete_dioq(struct crystalhd_adp *, crystalhd_dioq_t *); +extern BC_STATUS crystalhd_dioq_add(crystalhd_dioq_t *ioq, void *data, bool wake, uint32_t tag); +extern void *crystalhd_dioq_fetch(crystalhd_dioq_t *ioq); +extern void *crystalhd_dioq_find_and_fetch(crystalhd_dioq_t *ioq, uint32_t tag); +extern void *crystalhd_dioq_fetch_wait(crystalhd_dioq_t *ioq, uint32_t to_secs, uint32_t *sig_pend); + +#define crystalhd_dioq_count(_ioq) ((_ioq) ? _ioq->count : 0) + +extern int crystalhd_create_elem_pool(struct crystalhd_adp *, uint32_t); +extern void crystalhd_delete_elem_pool(struct crystalhd_adp *); + + +/*================ Debug routines/macros .. ================================*/ +extern void crystalhd_show_buffer(uint32_t off, uint8_t *buff, uint32_t dwcount); + +enum _chd_log_levels { + BCMLOG_ERROR = 0x80000000, /* Don't disable this option */ + BCMLOG_DATA = 0x40000000, /* Data, enable by default */ + BCMLOG_SPINLOCK = 0x20000000, /* Spcial case for Spin locks*/ + + /* Following are allowed only in debug mode */ + BCMLOG_INFO = 0x00000001, /* Generic informational */ + BCMLOG_DBG = 0x00000002, /* First level Debug info */ + BCMLOG_SSTEP = 0x00000004, /* Stepping information */ + BCMLOG_ENTER_LEAVE = 0x00000008, /* stack tracking */ +}; + +#define BCMLOG_ENTER \ +if (g_linklog_level & BCMLOG_ENTER_LEAVE) { \ + printk("Entered %s\n", __func__); \ +} + +#define BCMLOG_LEAVE \ +if (g_linklog_level & BCMLOG_ENTER_LEAVE) { \ + printk("Leaving %s\n", __func__); \ +} + +#define BCMLOG(trace, fmt, args...) \ +if (g_linklog_level & trace) { \ + printk(fmt, ##args); \ +} + +#define BCMLOG_ERR(fmt, args...) \ +do { \ + if (g_linklog_level & BCMLOG_ERROR) { \ + printk("*ERR*:%s:%d: "fmt, __FILE__, __LINE__, ##args); \ + } \ +} while (0); + +#endif diff --git a/drivers/staging/cx25821/cx25821-audups11.c b/drivers/staging/cx25821/cx25821-audups11.c index 89c8fe2..46c7f78 100644 --- a/drivers/staging/cx25821/cx25821-audups11.c +++ b/drivers/staging/cx25821/cx25821-audups11.c @@ -343,10 +343,11 @@ static int vidioc_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctl) { struct cx25821_fh *fh = priv; - struct cx25821_dev *dev = fh->dev; + struct cx25821_dev *dev; int err; if (fh) { + dev = fh->dev; err = v4l2_prio_check(&dev->prio, &fh->prio); if (0 != err) return err; diff --git a/drivers/staging/cx25821/cx25821-medusa-video.c b/drivers/staging/cx25821/cx25821-medusa-video.c index 1eb079b..d601620 100644 --- a/drivers/staging/cx25821/cx25821-medusa-video.c +++ b/drivers/staging/cx25821/cx25821-medusa-video.c @@ -795,10 +795,8 @@ int medusa_video_init(struct cx25821_dev *dev) value &= 0xFFFFFFDF; ret_val = cx25821_i2c_write(&dev->i2c_bus[0], MON_A_CTRL, value); - if (ret_val < 0) { - mutex_unlock(&dev->lock); + if (ret_val < 0) return -EINVAL; - } mutex_unlock(&dev->lock); diff --git a/drivers/staging/cx25821/cx25821-video.c b/drivers/staging/cx25821/cx25821-video.c index c7c14c7..8cd3986 100644 --- a/drivers/staging/cx25821/cx25821-video.c +++ b/drivers/staging/cx25821/cx25821-video.c @@ -876,7 +876,7 @@ int cx25821_enum_input(struct cx25821_dev *dev, struct v4l2_input *i) dprintk(1, "%s()\n", __func__); n = i->index; - if (n > 2) + if (n >= 2) return -EINVAL; if (0 == INPUT(n)->type) @@ -963,10 +963,11 @@ int cx25821_set_freq(struct cx25821_dev *dev, struct v4l2_frequency *f) int vidioc_s_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { struct cx25821_fh *fh = priv; - struct cx25821_dev *dev = fh->dev; + struct cx25821_dev *dev; int err; if (fh) { + dev = fh->dev; err = v4l2_prio_check(&dev->prio, &fh->prio); if (0 != err) return err; diff --git a/drivers/staging/dream/camera/Kconfig b/drivers/staging/dream/camera/Kconfig index 0a3e903..bfb6d24 100644 --- a/drivers/staging/dream/camera/Kconfig +++ b/drivers/staging/dream/camera/Kconfig @@ -15,7 +15,7 @@ config MSM_CAMERA_DEBUG config MSM_CAMERA_FLASH bool "Qualcomm MSM camera flash support" - depends on MSM_CAMERA + depends on MSM_CAMERA && BROKEN ---help--- Enable support for LED flash for msm camera diff --git a/drivers/staging/dream/camera/Makefile b/drivers/staging/dream/camera/Makefile index 4429ae5..db228d7 100644 --- a/drivers/staging/dream/camera/Makefile +++ b/drivers/staging/dream/camera/Makefile @@ -1,3 +1,4 @@ +EXTRA_CFLAGS=-Idrivers/staging/dream/include obj-$(CONFIG_MT9T013) += mt9t013.o mt9t013_reg.o obj-$(CONFIG_MT9D112) += mt9d112.o mt9d112_reg.o obj-$(CONFIG_MT9P012) += mt9p012_fox.o mt9p012_reg.o diff --git a/drivers/staging/dream/camera/msm_camera.c b/drivers/staging/dream/camera/msm_camera.c index 7d93877..dc7c603 100644 --- a/drivers/staging/dream/camera/msm_camera.c +++ b/drivers/staging/dream/camera/msm_camera.c @@ -2,7 +2,7 @@ * Copyright (C) 2008-2009 QUALCOMM Incorporated. */ -//FIXME: most allocations need not be GFP_ATOMIC +/* FIXME: most allocations need not be GFP_ATOMIC */ /* FIXME: management of mutexes */ /* FIXME: msm_pmem_region_lookup return values */ /* FIXME: way too many copy to/from user */ @@ -76,14 +76,14 @@ static LIST_HEAD(msm_sensors); list_del_init(&qcmd->list); \ kfree(qcmd); \ }; \ -} while(0) +} while (0) #define MSM_DRAIN_QUEUE(sync, name) do { \ unsigned long flags; \ spin_lock_irqsave(&(sync)->name##_lock, flags); \ MSM_DRAIN_QUEUE_NOSYNC(sync, name); \ spin_unlock_irqrestore(&(sync)->name##_lock, flags); \ -} while(0) +} while (0) static int check_overlap(struct hlist_head *ptype, unsigned long paddr, @@ -361,7 +361,7 @@ static int __msm_get_frame(struct msm_sync *sync, if (!frame->buffer) { pr_err("%s: cannot get frame, invalid lookup address " "y=%x cbcr=%x offset=%d\n", - __FUNCTION__, + __func__, pphy->y_phy, pphy->cbcr_phy, frame->y_off); @@ -455,7 +455,7 @@ static int msm_disable_vfe(struct msm_sync *sync, void __user *arg) return rc; } -static struct msm_queue_cmd* __msm_control(struct msm_sync *sync, +static struct msm_queue_cmd *__msm_control(struct msm_sync *sync, struct msm_control_device_queue *queue, struct msm_queue_cmd *qcmd, int timeout) @@ -592,8 +592,7 @@ end: * a result of a successful completion, we are freeing the qcmd that * we dequeued from queue->ctrl_status_q. */ - if (qcmd) - kfree(qcmd); + kfree(qcmd); CDBG("msm_control: end rc = %d\n", rc); return rc; @@ -670,7 +669,7 @@ static int msm_get_stats(struct msm_sync *sync, void __user *arg) &(stats.fd)); if (!stats.buffer) { pr_err("%s: msm_pmem_stats_ptov_lookup error\n", - __FUNCTION__); + __func__); rc = -EINVAL; goto failure; } @@ -718,8 +717,7 @@ static int msm_get_stats(struct msm_sync *sync, void __user *arg) buf.fmain.buffer = (unsigned long)region.vaddr; buf.fmain.fd = region.fd; - } - else { + } else { pr_err("%s: pmem lookup failed\n", __func__); rc = -EINVAL; @@ -796,8 +794,7 @@ static int msm_get_stats(struct msm_sync *sync, void __user *arg) } failure: - if (qcmd) - kfree(qcmd); + kfree(qcmd); CDBG("msm_get_stats: %d\n", rc); return rc; @@ -838,8 +835,8 @@ static int msm_ctrl_cmd_done(struct msm_control_device *ctrl_pmsm, kfree(qcmd); goto end; } - } - else ctrlcmd->value = NULL; + } else + ctrlcmd->value = NULL; end: CDBG("msm_ctrl_cmd_done: end rc = %d\n", rc); @@ -869,14 +866,14 @@ static int msm_config_vfe(struct msm_sync *sync, void __user *arg) return -EFAULT; } - switch(cfgcmd.cmd_type) { + switch (cfgcmd.cmd_type) { case CMD_STATS_ENABLE: axi_data.bufnum1 = msm_pmem_region_lookup(&sync->stats, MSM_PMEM_AEC_AWB, ®ion[0], NUM_WB_EXP_STAT_OUTPUT_BUFFERS); if (!axi_data.bufnum1) { - pr_err("%s: pmem region lookup error\n", __FUNCTION__); + pr_err("%s: pmem region lookup error\n", __func__); return -EINVAL; } axi_data.region = ®ion[0]; @@ -888,7 +885,7 @@ static int msm_config_vfe(struct msm_sync *sync, void __user *arg) MSM_PMEM_AF, ®ion[0], NUM_AF_STAT_OUTPUT_BUFFERS); if (!axi_data.bufnum1) { - pr_err("%s: pmem region lookup error\n", __FUNCTION__); + pr_err("%s: pmem region lookup error\n", __func__); return -EINVAL; } axi_data.region = ®ion[0]; @@ -899,7 +896,7 @@ static int msm_config_vfe(struct msm_sync *sync, void __user *arg) break; default: pr_err("%s: unknown command type %d\n", - __FUNCTION__, cfgcmd.cmd_type); + __func__, cfgcmd.cmd_type); return -EINVAL; } @@ -928,7 +925,7 @@ static int msm_frame_axi_cfg(struct msm_sync *sync, msm_pmem_region_lookup(&sync->frame, pmem_type, ®ion[0], 8); if (!axi_data.bufnum1) { - pr_err("%s: pmem region lookup error\n", __FUNCTION__); + pr_err("%s: pmem region lookup error\n", __func__); return -EINVAL; } break; @@ -939,7 +936,7 @@ static int msm_frame_axi_cfg(struct msm_sync *sync, msm_pmem_region_lookup(&sync->frame, pmem_type, ®ion[0], 8); if (!axi_data.bufnum2) { - pr_err("%s: pmem region lookup error\n", __FUNCTION__); + pr_err("%s: pmem region lookup error\n", __func__); return -EINVAL; } break; @@ -950,7 +947,7 @@ static int msm_frame_axi_cfg(struct msm_sync *sync, msm_pmem_region_lookup(&sync->frame, pmem_type, ®ion[0], 8); if (!axi_data.bufnum1) { - pr_err("%s: pmem region lookup error\n", __FUNCTION__); + pr_err("%s: pmem region lookup error\n", __func__); return -EINVAL; } @@ -959,7 +956,7 @@ static int msm_frame_axi_cfg(struct msm_sync *sync, msm_pmem_region_lookup(&sync->frame, pmem_type, ®ion[axi_data.bufnum1], 8); if (!axi_data.bufnum2) { - pr_err("%s: pmem region lookup error\n", __FUNCTION__); + pr_err("%s: pmem region lookup error\n", __func__); return -EINVAL; } break; @@ -970,7 +967,7 @@ static int msm_frame_axi_cfg(struct msm_sync *sync, msm_pmem_region_lookup(&sync->frame, pmem_type, ®ion[0], 8); if (!axi_data.bufnum2) { - pr_err("%s: pmem region lookup error\n", __FUNCTION__); + pr_err("%s: pmem region lookup error\n", __func__); return -EINVAL; } break; @@ -981,7 +978,7 @@ static int msm_frame_axi_cfg(struct msm_sync *sync, default: pr_err("%s: unknown command type %d\n", - __FUNCTION__, cfgcmd->cmd_type); + __func__, cfgcmd->cmd_type); return -EINVAL; } @@ -1047,7 +1044,7 @@ static int __msm_put_frame_buf(struct msm_sync *sync, rc = sync->vfefn.vfe_config(&cfgcmd, &pphy); } else { pr_err("%s: msm_pmem_frame_vtop_lookup failed\n", - __FUNCTION__); + __func__); rc = -EINVAL; } @@ -1131,7 +1128,7 @@ static int msm_stats_axi_cfg(struct msm_sync *sync, break; default: pr_err("%s: unknown command type %d\n", - __FUNCTION__, cfgcmd->cmd_type); + __func__, cfgcmd->cmd_type); return -EINVAL; } @@ -1140,7 +1137,7 @@ static int msm_stats_axi_cfg(struct msm_sync *sync, msm_pmem_region_lookup(&sync->stats, pmem_type, ®ion[0], NUM_WB_EXP_STAT_OUTPUT_BUFFERS); if (!axi_data.bufnum1) { - pr_err("%s: pmem region lookup error\n", __FUNCTION__); + pr_err("%s: pmem region lookup error\n", __func__); return -EINVAL; } axi_data.region = ®ion[0]; @@ -1177,7 +1174,7 @@ static int msm_put_stats_buffer(struct msm_sync *sync, void __user *arg) cfgcmd.cmd_type = CMD_STATS_AF_BUF_RELEASE; else { pr_err("%s: invalid buf type %d\n", - __FUNCTION__, + __func__, buf.type); rc = -EINVAL; goto put_done; @@ -1223,7 +1220,7 @@ static int msm_axi_config(struct msm_sync *sync, void __user *arg) default: pr_err("%s: unknown command type %d\n", - __FUNCTION__, + __func__, cfgcmd.cmd_type); return -EINVAL; } @@ -1622,7 +1619,8 @@ static int msm_release_control(struct inode *node, struct file *filep) int rc; struct msm_control_device *ctrl_pmsm = filep->private_data; struct msm_device *pmsm = ctrl_pmsm->pmsm; - printk("msm_camera: RELEASE %s\n", filep->f_path.dentry->d_name.name); + printk(KERN_INFO "msm_camera: RELEASE %s\n", + filep->f_path.dentry->d_name.name); rc = __msm_release(pmsm->sync); if (!rc) { MSM_DRAIN_QUEUE(&ctrl_pmsm->ctrl_q, ctrl_status_q); @@ -1636,7 +1634,8 @@ static int msm_release_frame(struct inode *node, struct file *filep) { int rc; struct msm_device *pmsm = filep->private_data; - printk("msm_camera: RELEASE %s\n", filep->f_path.dentry->d_name.name); + printk(KERN_INFO "msm_camera: RELEASE %s\n", + filep->f_path.dentry->d_name.name); rc = __msm_release(pmsm->sync); if (!rc) { MSM_DRAIN_QUEUE(pmsm->sync, prev_frame_q); @@ -1720,7 +1719,7 @@ static void msm_vfe_sync(struct msm_vfe_resp *vdata, qcmd->type = qtype; if (qtype == MSM_CAM_Q_VFE_MSG) { - switch(vdata->type) { + switch (vdata->type) { case VFE_MSG_OUTPUT1: case VFE_MSG_OUTPUT2: qcmd_frame = @@ -1885,8 +1884,10 @@ static int msm_open_control(struct inode *inode, struct file *filep) return -ENOMEM; rc = msm_open_common(inode, filep, 0); - if (rc < 0) + if (rc < 0) { + kfree(ctrl_pmsm); return rc; + } ctrl_pmsm->pmsm = filep->private_data; filep->private_data = ctrl_pmsm; @@ -1929,7 +1930,7 @@ static int __msm_v4l2_control(struct msm_sync *sync, memcpy(out->value, ctrl->value, ctrl->length); end: - if (rcmd) kfree(rcmd); + kfree(rcmd); CDBG("__msm_v4l2_control: end rc = %d\n", rc); return rc; } diff --git a/drivers/staging/dream/camera/msm_vfe7x.c b/drivers/staging/dream/camera/msm_vfe7x.c index 33ab3ac..62fd24d 100644 --- a/drivers/staging/dream/camera/msm_vfe7x.c +++ b/drivers/staging/dream/camera/msm_vfe7x.c @@ -255,8 +255,7 @@ static int vfe_7x_init(struct msm_vfe_callback *presp, extlen = sizeof(struct vfe_frame_extra); - extdata = - kmalloc(sizeof(extlen), GFP_ATOMIC); + extdata = kmalloc(extlen, GFP_ATOMIC); if (!extdata) { rc = -ENOMEM; goto init_fail; diff --git a/drivers/staging/dream/camera/s5k3e2fx.c b/drivers/staging/dream/camera/s5k3e2fx.c index edba198..841792e 100644 --- a/drivers/staging/dream/camera/s5k3e2fx.c +++ b/drivers/staging/dream/camera/s5k3e2fx.c @@ -743,12 +743,12 @@ static int s5k3e2fx_sensor_open_init(const struct msm_camera_sensor_info *data) } /* initialize AF */ - if ((rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr, - 0x3146, 0x3A)) < 0) + rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr, 0x3146, 0x3A); + if (rc < 0) goto init_fail1; - if ((rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr, - 0x3130, 0x03)) < 0) + rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr, 0x3130, 0x03); + if (rc < 0) goto init_fail1; goto init_done; @@ -814,20 +814,20 @@ static uint16_t s5k3e2fx_get_prev_lines_pf(void) static uint16_t s5k3e2fx_get_prev_pixels_pl(void) { - return (s5k3e2fx_reg_pat[S_RES_PREVIEW].size_w + - s5k3e2fx_reg_pat[S_RES_PREVIEW].blk_p); + return s5k3e2fx_reg_pat[S_RES_PREVIEW].size_w + + s5k3e2fx_reg_pat[S_RES_PREVIEW].blk_p; } static uint16_t s5k3e2fx_get_pict_lines_pf(void) { - return (s5k3e2fx_reg_pat[S_RES_CAPTURE].size_h + - s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_l); + return s5k3e2fx_reg_pat[S_RES_CAPTURE].size_h + + s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_l; } static uint16_t s5k3e2fx_get_pict_pixels_pl(void) { - return (s5k3e2fx_reg_pat[S_RES_CAPTURE].size_w + - s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_p); + return s5k3e2fx_reg_pat[S_RES_CAPTURE].size_w + + s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_p; } static uint32_t s5k3e2fx_get_pict_max_exp_lc(void) @@ -1093,14 +1093,10 @@ static int32_t s5k3e2fx_move_focus(int direction, int32_t num_steps) actual_step = step_direction * (int16_t)num_steps; pos_offset = init_code + s5k3e2fx_ctrl->curr_lens_pos; - gain = actual_step * 0x400 / 5; + gain = ((actual_step << 10) / 5) >> 10; - for (i = 0; i <= 4; i++) { - if (actual_step >= 0) - s_move[i] = ((((i+1)*gain+0x200) - (i*gain+0x200))/0x400); - else - s_move[i] = ((((i+1)*gain-0x200) - (i*gain-0x200))/0x400); - } + for (i = 0; i <= 4; i++) + s_move[i] = gain; /* Ring Damping Code */ for (i = 0; i <= 4; i++) { diff --git a/drivers/staging/dream/include/linux/android_pmem.h b/drivers/staging/dream/include/linux/android_pmem.h new file mode 100644 index 0000000..2fc05d7 --- /dev/null +++ b/drivers/staging/dream/include/linux/android_pmem.h @@ -0,0 +1,80 @@ +/* drivers/staging/dream/include/linux/android_pmem.h + * + * Copyright (C) 2007 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ + +#ifndef _ANDROID_PMEM_H_ +#define _ANDROID_PMEM_H_ + +#define PMEM_IOCTL_MAGIC 'p' +#define PMEM_GET_PHYS _IOW(PMEM_IOCTL_MAGIC, 1, unsigned int) +#define PMEM_MAP _IOW(PMEM_IOCTL_MAGIC, 2, unsigned int) +#define PMEM_GET_SIZE _IOW(PMEM_IOCTL_MAGIC, 3, unsigned int) +#define PMEM_UNMAP _IOW(PMEM_IOCTL_MAGIC, 4, unsigned int) +/* This ioctl will allocate pmem space, backing the file, it will fail + * if the file already has an allocation, pass it the len as the argument + * to the ioctl */ +#define PMEM_ALLOCATE _IOW(PMEM_IOCTL_MAGIC, 5, unsigned int) +/* This will connect a one pmem file to another, pass the file that is already + * backed in memory as the argument to the ioctl + */ +#define PMEM_CONNECT _IOW(PMEM_IOCTL_MAGIC, 6, unsigned int) +/* Returns the total size of the pmem region it is sent to as a pmem_region + * struct (with offset set to 0). + */ +#define PMEM_GET_TOTAL_SIZE _IOW(PMEM_IOCTL_MAGIC, 7, unsigned int) +/* Revokes gpu registers and resets the gpu. Pass a pointer to the + * start of the mapped gpu regs (the vaddr returned by mmap) as the argument. + */ +#define HW3D_REVOKE_GPU _IOW(PMEM_IOCTL_MAGIC, 8, unsigned int) +#define HW3D_GRANT_GPU _IOW(PMEM_IOCTL_MAGIC, 9, unsigned int) +#define HW3D_WAIT_FOR_INTERRUPT _IOW(PMEM_IOCTL_MAGIC, 10, unsigned int) + +int get_pmem_file(int fd, unsigned long *start, unsigned long *vstart, + unsigned long *end, struct file **filp); +int get_pmem_user_addr(struct file *file, unsigned long *start, + unsigned long *end); +void put_pmem_file(struct file* file); +void flush_pmem_file(struct file *file, unsigned long start, unsigned long len); + +struct android_pmem_platform_data +{ + const char* name; + /* starting physical address of memory region */ + unsigned long start; + /* size of memory region */ + unsigned long size; + /* set to indicate the region should not be managed with an allocator */ + unsigned no_allocator; + /* set to indicate maps of this region should be cached, if a mix of + * cached and uncached is desired, set this and open the device with + * O_SYNC to get an uncached region */ + unsigned cached; + /* The MSM7k has bits to enable a write buffer in the bus controller*/ + unsigned buffered; +}; + +struct pmem_region { + unsigned long offset; + unsigned long len; +}; + +int pmem_setup(struct android_pmem_platform_data *pdata, + long (*ioctl)(struct file *, unsigned int, unsigned long), + int (*release)(struct inode *, struct file *)); + +int pmem_remap(struct pmem_region *region, struct file *file, + unsigned operation); + +#endif //_ANDROID_PPP_H_ + diff --git a/drivers/staging/dream/include/linux/gpio_event.h b/drivers/staging/dream/include/linux/gpio_event.h new file mode 100644 index 0000000..ffc5da3 --- /dev/null +++ b/drivers/staging/dream/include/linux/gpio_event.h @@ -0,0 +1,154 @@ +/* drivers/staging/dream/include/linux/gpio_event.h + * + * Copyright (C) 2007 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ + +#ifndef _LINUX_GPIO_EVENT_H +#define _LINUX_GPIO_EVENT_H + +#include <linux/input.h> + +enum { + GPIO_EVENT_FUNC_UNINIT = 0x0, + GPIO_EVENT_FUNC_INIT = 0x1, + GPIO_EVENT_FUNC_SUSPEND = 0x2, + GPIO_EVENT_FUNC_RESUME = 0x3, +}; +struct gpio_event_info { + int (*func)(struct input_dev *input_dev, + struct gpio_event_info *info, + void **data, int func); + int (*event)(struct input_dev *input_dev, + struct gpio_event_info *info, + void **data, unsigned int type, + unsigned int code, int value); /* out events */ +}; + +struct gpio_event_platform_data { + const char *name; + struct gpio_event_info **info; + size_t info_count; + int (*power)(const struct gpio_event_platform_data *pdata, bool on); +}; + +#define GPIO_EVENT_DEV_NAME "gpio-event" + +/* Key matrix */ + +enum gpio_event_matrix_flags { + /* unset: drive active output low, set: drive active output high */ + GPIOKPF_ACTIVE_HIGH = 1U << 0, + GPIOKPF_DEBOUNCE = 1U << 1, + GPIOKPF_REMOVE_SOME_PHANTOM_KEYS = 1U << 2, + GPIOKPF_REMOVE_PHANTOM_KEYS = GPIOKPF_REMOVE_SOME_PHANTOM_KEYS | + GPIOKPF_DEBOUNCE, + GPIOKPF_DRIVE_INACTIVE = 1U << 3, + GPIOKPF_LEVEL_TRIGGERED_IRQ = 1U << 4, + GPIOKPF_PRINT_UNMAPPED_KEYS = 1U << 16, + GPIOKPF_PRINT_MAPPED_KEYS = 1U << 17, + GPIOKPF_PRINT_PHANTOM_KEYS = 1U << 18, +}; + +extern int gpio_event_matrix_func(struct input_dev *input_dev, + struct gpio_event_info *info, void **data, int func); +struct gpio_event_matrix_info { + /* initialize to gpio_event_matrix_func */ + struct gpio_event_info info; + /* size must be ninputs * noutputs */ + const unsigned short *keymap; + unsigned int *input_gpios; + unsigned int *output_gpios; + unsigned int ninputs; + unsigned int noutputs; + /* time to wait before reading inputs after driving each output */ + ktime_t settle_time; + /* time to wait before scanning the keypad a second time */ + ktime_t debounce_delay; + ktime_t poll_time; + unsigned flags; +}; + +/* Directly connected inputs and outputs */ + +enum gpio_event_direct_flags { + GPIOEDF_ACTIVE_HIGH = 1U << 0, +/* GPIOEDF_USE_DOWN_IRQ = 1U << 1, */ +/* GPIOEDF_USE_IRQ = (1U << 2) | GPIOIDF_USE_DOWN_IRQ, */ + GPIOEDF_PRINT_KEYS = 1U << 8, + GPIOEDF_PRINT_KEY_DEBOUNCE = 1U << 9, +}; + +struct gpio_event_direct_entry { + uint32_t gpio:23; + uint32_t code:9; +}; + +/* inputs */ +extern int gpio_event_input_func(struct input_dev *input_dev, + struct gpio_event_info *info, void **data, int func); +struct gpio_event_input_info { + /* initialize to gpio_event_input_func */ + struct gpio_event_info info; + ktime_t debounce_time; + ktime_t poll_time; + uint16_t flags; + uint16_t type; + const struct gpio_event_direct_entry *keymap; + size_t keymap_size; +}; + +/* outputs */ +extern int gpio_event_output_func(struct input_dev *input_dev, + struct gpio_event_info *info, void **data, int func); +extern int gpio_event_output_event(struct input_dev *input_dev, + struct gpio_event_info *info, void **data, + unsigned int type, unsigned int code, int value); +struct gpio_event_output_info { + /* initialize to gpio_event_output_func and gpio_event_output_event */ + struct gpio_event_info info; + uint16_t flags; + uint16_t type; + const struct gpio_event_direct_entry *keymap; + size_t keymap_size; +}; + + +/* axes */ + +enum gpio_event_axis_flags { + GPIOEAF_PRINT_UNKNOWN_DIRECTION = 1U << 16, + GPIOEAF_PRINT_RAW = 1U << 17, + GPIOEAF_PRINT_EVENT = 1U << 18, +}; + +extern int gpio_event_axis_func(struct input_dev *input_dev, + struct gpio_event_info *info, void **data, int func); +struct gpio_event_axis_info { + /* initialize to gpio_event_axis_func */ + struct gpio_event_info info; + uint8_t count; + uint8_t type; /* EV_REL or EV_ABS */ + uint16_t code; + uint16_t decoded_size; + uint16_t (*map)(struct gpio_event_axis_info *info, uint16_t in); + uint32_t *gpio; + uint32_t flags; +}; +#define gpio_axis_2bit_gray_map gpio_axis_4bit_gray_map +#define gpio_axis_3bit_gray_map gpio_axis_4bit_gray_map +uint16_t gpio_axis_4bit_gray_map( + struct gpio_event_axis_info *info, uint16_t in); +uint16_t gpio_axis_5bit_singletrack_map( + struct gpio_event_axis_info *info, uint16_t in); + +#endif diff --git a/drivers/staging/dream/include/linux/msm_adsp.h b/drivers/staging/dream/include/linux/msm_adsp.h new file mode 100644 index 0000000..e775f3e --- /dev/null +++ b/drivers/staging/dream/include/linux/msm_adsp.h @@ -0,0 +1,84 @@ +/* drivers/staging/dream/include/linux/msm_adsp.h + * + * Copyright (c) QUALCOMM Incorporated + * Copyright (C) 2007 Google, Inc. + * Author: Iliyan Malchev <ibm@android.com> + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ +#ifndef __LINUX_MSM_ADSP_H +#define __LINUX_MSM_ADSP_H + +#include <linux/types.h> +#include <linux/ioctl.h> + +#define ADSP_IOCTL_MAGIC 'q' + +/* ADSP_IOCTL_WRITE_COMMAND */ +struct adsp_command_t { + uint16_t queue; + uint32_t len; /* bytes */ + uint8_t *data; +}; + +/* ADSP_IOCTL_GET_EVENT */ +struct adsp_event_t { + uint16_t type; /* 1 == event (RPC), 0 == message (adsp) */ + uint32_t timeout_ms; /* -1 for infinite, 0 for immediate return */ + uint16_t msg_id; + uint16_t flags; /* 1 == 16--bit event, 0 == 32-bit event */ + uint32_t len; /* size in, number of bytes out */ + uint8_t *data; +}; + +#define ADSP_IOCTL_ENABLE \ + _IOR(ADSP_IOCTL_MAGIC, 1, unsigned) + +#define ADSP_IOCTL_DISABLE \ + _IOR(ADSP_IOCTL_MAGIC, 2, unsigned) + +#define ADSP_IOCTL_DISABLE_ACK \ + _IOR(ADSP_IOCTL_MAGIC, 3, unsigned) + +#define ADSP_IOCTL_WRITE_COMMAND \ + _IOR(ADSP_IOCTL_MAGIC, 4, struct adsp_command_t *) + +#define ADSP_IOCTL_GET_EVENT \ + _IOWR(ADSP_IOCTL_MAGIC, 5, struct adsp_event_data_t *) + +#define ADSP_IOCTL_SET_CLKRATE \ + _IOR(ADSP_IOCTL_MAGIC, 6, unsigned) + +#define ADSP_IOCTL_DISABLE_EVENT_RSP \ + _IOR(ADSP_IOCTL_MAGIC, 10, unsigned) + +struct adsp_pmem_info { + int fd; + void *vaddr; +}; + +#define ADSP_IOCTL_REGISTER_PMEM \ + _IOW(ADSP_IOCTL_MAGIC, 13, unsigned) + +#define ADSP_IOCTL_UNREGISTER_PMEM \ + _IOW(ADSP_IOCTL_MAGIC, 14, unsigned) + +/* Cause any further GET_EVENT ioctls to fail (-ENODEV) + * until the device is closed and reopened. Useful for + * terminating event dispatch threads + */ +#define ADSP_IOCTL_ABORT_EVENT_READ \ + _IOW(ADSP_IOCTL_MAGIC, 15, unsigned) + +#define ADSP_IOCTL_LINK_TASK \ + _IOW(ADSP_IOCTL_MAGIC, 16, unsigned) + +#endif diff --git a/drivers/staging/dream/include/linux/msm_audio.h b/drivers/staging/dream/include/linux/msm_audio.h new file mode 100644 index 0000000..cfbdaa0 --- /dev/null +++ b/drivers/staging/dream/include/linux/msm_audio.h @@ -0,0 +1,115 @@ +/* drivers/staging/dream/include/linux/msm_audio.h + * + * Copyright (C) 2008 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ + +#ifndef __LINUX_MSM_AUDIO_H +#define __LINUX_MSM_AUDIO_H + +#include <linux/types.h> +#include <linux/ioctl.h> +#include <asm/sizes.h> + +/* PCM Audio */ + +#define AUDIO_IOCTL_MAGIC 'a' + +#define AUDIO_START _IOW(AUDIO_IOCTL_MAGIC, 0, unsigned) +#define AUDIO_STOP _IOW(AUDIO_IOCTL_MAGIC, 1, unsigned) +#define AUDIO_FLUSH _IOW(AUDIO_IOCTL_MAGIC, 2, unsigned) +#define AUDIO_GET_CONFIG _IOR(AUDIO_IOCTL_MAGIC, 3, unsigned) +#define AUDIO_SET_CONFIG _IOW(AUDIO_IOCTL_MAGIC, 4, unsigned) +#define AUDIO_GET_STATS _IOR(AUDIO_IOCTL_MAGIC, 5, unsigned) +#define AUDIO_ENABLE_AUDPP _IOW(AUDIO_IOCTL_MAGIC, 6, unsigned) +#define AUDIO_SET_ADRC _IOW(AUDIO_IOCTL_MAGIC, 7, unsigned) +#define AUDIO_SET_EQ _IOW(AUDIO_IOCTL_MAGIC, 8, unsigned) +#define AUDIO_SET_RX_IIR _IOW(AUDIO_IOCTL_MAGIC, 9, unsigned) +#define AUDIO_SET_VOLUME _IOW(AUDIO_IOCTL_MAGIC, 10, unsigned) +#define AUDIO_ENABLE_AUDPRE _IOW(AUDIO_IOCTL_MAGIC, 11, unsigned) +#define AUDIO_SET_AGC _IOW(AUDIO_IOCTL_MAGIC, 12, unsigned) +#define AUDIO_SET_NS _IOW(AUDIO_IOCTL_MAGIC, 13, unsigned) +#define AUDIO_SET_TX_IIR _IOW(AUDIO_IOCTL_MAGIC, 14, unsigned) +#define AUDIO_PAUSE _IOW(AUDIO_IOCTL_MAGIC, 15, unsigned) +#define AUDIO_GET_PCM_CONFIG _IOR(AUDIO_IOCTL_MAGIC, 30, unsigned) +#define AUDIO_SET_PCM_CONFIG _IOW(AUDIO_IOCTL_MAGIC, 31, unsigned) +#define AUDIO_SWITCH_DEVICE _IOW(AUDIO_IOCTL_MAGIC, 32, unsigned) + +#define AUDIO_MAX_COMMON_IOCTL_NUM 100 + +#define AUDIO_MAX_COMMON_IOCTL_NUM 100 + +struct msm_audio_config { + uint32_t buffer_size; + uint32_t buffer_count; + uint32_t channel_count; + uint32_t sample_rate; + uint32_t type; + uint32_t unused[3]; +}; + +struct msm_audio_stats { + uint32_t byte_count; + uint32_t sample_count; + uint32_t unused[2]; +}; + +/* Audio routing */ + +#define SND_IOCTL_MAGIC 's' + +#define SND_MUTE_UNMUTED 0 +#define SND_MUTE_MUTED 1 + +struct msm_snd_device_config { + uint32_t device; + uint32_t ear_mute; + uint32_t mic_mute; +}; + +#define SND_SET_DEVICE _IOW(SND_IOCTL_MAGIC, 2, struct msm_device_config *) + +#define SND_METHOD_VOICE 0 + +struct msm_snd_volume_config { + uint32_t device; + uint32_t method; + uint32_t volume; +}; + +#define SND_SET_VOLUME _IOW(SND_IOCTL_MAGIC, 3, struct msm_snd_volume_config *) + +/* Returns the number of SND endpoints supported. */ + +#define SND_GET_NUM_ENDPOINTS _IOR(SND_IOCTL_MAGIC, 4, unsigned *) + +struct msm_snd_endpoint { + int id; /* input and output */ + char name[64]; /* output only */ +}; + +/* Takes an index between 0 and one less than the number returned by + * SND_GET_NUM_ENDPOINTS, and returns the SND index and name of a + * SND endpoint. On input, the .id field contains the number of the + * endpoint, and on exit it contains the SND index, while .name contains + * the description of the endpoint. + */ + +#define SND_GET_ENDPOINT _IOWR(SND_IOCTL_MAGIC, 5, struct msm_snd_endpoint *) + +struct msm_audio_pcm_config { + uint32_t pcm_feedback; /* 0 - disable > 0 - enable */ + uint32_t buffer_count; /* Number of buffers to allocate */ + uint32_t buffer_size; /* Size of buffer for capturing of + PCM samples */ +}; +#endif diff --git a/drivers/staging/dream/include/linux/msm_rpcrouter.h b/drivers/staging/dream/include/linux/msm_rpcrouter.h new file mode 100644 index 0000000..64845fb --- /dev/null +++ b/drivers/staging/dream/include/linux/msm_rpcrouter.h @@ -0,0 +1,47 @@ +/* drivers/staging/dream/include/linux/msm_rpcrouter.h + * + * Copyright (c) QUALCOMM Incorporated + * Copyright (C) 2007 Google, Inc. + * Author: San Mehat <san@android.com> + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ +#ifndef __LINUX_MSM_RPCROUTER_H +#define __LINUX_MSM_RPCROUTER_H + +#include <linux/types.h> +#include <linux/ioctl.h> + +#define RPC_ROUTER_VERSION_V1 0x00010000 + +struct rpcrouter_ioctl_server_args { + uint32_t prog; + uint32_t vers; +}; + +#define RPC_ROUTER_IOCTL_MAGIC (0xC1) + +#define RPC_ROUTER_IOCTL_GET_VERSION \ + _IOR(RPC_ROUTER_IOCTL_MAGIC, 0, unsigned int) + +#define RPC_ROUTER_IOCTL_GET_MTU \ + _IOR(RPC_ROUTER_IOCTL_MAGIC, 1, unsigned int) + +#define RPC_ROUTER_IOCTL_REGISTER_SERVER \ + _IOWR(RPC_ROUTER_IOCTL_MAGIC, 2, unsigned int) + +#define RPC_ROUTER_IOCTL_UNREGISTER_SERVER \ + _IOWR(RPC_ROUTER_IOCTL_MAGIC, 3, unsigned int) + +#define RPC_ROUTER_IOCTL_GET_MINOR_VERSION \ + _IOW(RPC_ROUTER_IOCTL_MAGIC, 4, unsigned int) + +#endif diff --git a/drivers/staging/dream/include/linux/wakelock.h b/drivers/staging/dream/include/linux/wakelock.h new file mode 100644 index 0000000..93c31a4 --- /dev/null +++ b/drivers/staging/dream/include/linux/wakelock.h @@ -0,0 +1,91 @@ +/* drivers/staging/dream/include/linux/wakelock.h + * + * Copyright (C) 2007-2008 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ + +#ifndef _LINUX_WAKELOCK_H +#define _LINUX_WAKELOCK_H + +#include <linux/list.h> +#include <linux/ktime.h> + +/* A wake_lock prevents the system from entering suspend or other low power + * states when active. If the type is set to WAKE_LOCK_SUSPEND, the wake_lock + * prevents a full system suspend. If the type is WAKE_LOCK_IDLE, low power + * states that cause large interrupt latencies or that disable a set of + * interrupts will not entered from idle until the wake_locks are released. + */ + +enum { + WAKE_LOCK_SUSPEND, /* Prevent suspend */ + WAKE_LOCK_IDLE, /* Prevent low power idle */ + WAKE_LOCK_TYPE_COUNT +}; + +struct wake_lock { +#ifdef CONFIG_HAS_WAKELOCK + struct list_head link; + int flags; + const char *name; + unsigned long expires; +#ifdef CONFIG_WAKELOCK_STAT + struct { + int count; + int expire_count; + int wakeup_count; + ktime_t total_time; + ktime_t prevent_suspend_time; + ktime_t max_time; + ktime_t last_time; + } stat; +#endif +#endif +}; + +#ifdef CONFIG_HAS_WAKELOCK + +void wake_lock_init(struct wake_lock *lock, int type, const char *name); +void wake_lock_destroy(struct wake_lock *lock); +void wake_lock(struct wake_lock *lock); +void wake_lock_timeout(struct wake_lock *lock, long timeout); +void wake_unlock(struct wake_lock *lock); + +/* wake_lock_active returns a non-zero value if the wake_lock is currently + * locked. If the wake_lock has a timeout, it does not check the timeout + * but if the timeout had aready been checked it will return 0. + */ +int wake_lock_active(struct wake_lock *lock); + +/* has_wake_lock returns 0 if no wake locks of the specified type are active, + * and non-zero if one or more wake locks are held. Specifically it returns + * -1 if one or more wake locks with no timeout are active or the + * number of jiffies until all active wake locks time out. + */ +long has_wake_lock(int type); + +#else + +static inline void wake_lock_init(struct wake_lock *lock, int type, + const char *name) {} +static inline void wake_lock_destroy(struct wake_lock *lock) {} +static inline void wake_lock(struct wake_lock *lock) {} +static inline void wake_lock_timeout(struct wake_lock *lock, long timeout) {} +static inline void wake_unlock(struct wake_lock *lock) {} + +static inline int wake_lock_active(struct wake_lock *lock) { return 0; } +static inline long has_wake_lock(int type) { return 0; } + +#endif + +#endif + diff --git a/drivers/staging/dream/include/mach/camera.h b/drivers/staging/dream/include/mach/camera.h new file mode 100644 index 0000000..c20f042 --- /dev/null +++ b/drivers/staging/dream/include/mach/camera.h @@ -0,0 +1,279 @@ +/* + * Copyright (C) 2008-2009 QUALCOMM Incorporated. + */ + +#ifndef __ASM__ARCH_CAMERA_H +#define __ASM__ARCH_CAMERA_H + +#include <linux/list.h> +#include <linux/poll.h> +#include <linux/cdev.h> +#include <linux/platform_device.h> +#include "linux/types.h" + +#include <mach/board.h> +#include <media/msm_camera.h> + +#ifdef CONFIG_MSM_CAMERA_DEBUG +#define CDBG(fmt, args...) printk(KERN_INFO "msm_camera: " fmt, ##args) +#else +#define CDBG(fmt, args...) do { } while (0) +#endif + +#define MSM_CAMERA_MSG 0 +#define MSM_CAMERA_EVT 1 +#define NUM_WB_EXP_NEUTRAL_REGION_LINES 4 +#define NUM_WB_EXP_STAT_OUTPUT_BUFFERS 3 +#define NUM_AUTOFOCUS_MULTI_WINDOW_GRIDS 16 +#define NUM_AF_STAT_OUTPUT_BUFFERS 3 + +enum msm_queue { + MSM_CAM_Q_CTRL, /* control command or control command status */ + MSM_CAM_Q_VFE_EVT, /* adsp event */ + MSM_CAM_Q_VFE_MSG, /* adsp message */ + MSM_CAM_Q_V4L2_REQ, /* v4l2 request */ +}; + +enum vfe_resp_msg { + VFE_EVENT, + VFE_MSG_GENERAL, + VFE_MSG_SNAPSHOT, + VFE_MSG_OUTPUT1, + VFE_MSG_OUTPUT2, + VFE_MSG_STATS_AF, + VFE_MSG_STATS_WE, +}; + +struct msm_vfe_phy_info { + uint32_t sbuf_phy; + uint32_t y_phy; + uint32_t cbcr_phy; +}; + +struct msm_vfe_resp { + enum vfe_resp_msg type; + struct msm_vfe_evt_msg evt_msg; + struct msm_vfe_phy_info phy; + void *extdata; + int32_t extlen; +}; + +struct msm_vfe_callback { + void (*vfe_resp)(struct msm_vfe_resp *, + enum msm_queue, void *syncdata); + void* (*vfe_alloc)(int, void *syncdata); +}; + +struct msm_camvfe_fn { + int (*vfe_init)(struct msm_vfe_callback *, struct platform_device *); + int (*vfe_enable)(struct camera_enable_cmd *); + int (*vfe_config)(struct msm_vfe_cfg_cmd *, void *); + int (*vfe_disable)(struct camera_enable_cmd *, + struct platform_device *dev); + void (*vfe_release)(struct platform_device *); +}; + +struct msm_sensor_ctrl { + int (*s_init)(const struct msm_camera_sensor_info *); + int (*s_release)(void); + int (*s_config)(void __user *); +}; + +struct msm_sync { + /* These two queues are accessed from a process context only. */ + struct hlist_head frame; /* most-frequently accessed */ + struct hlist_head stats; + + /* The message queue is used by the control thread to send commands + * to the config thread, and also by the DSP to send messages to the + * config thread. Thus it is the only queue that is accessed from + * both interrupt and process context. + */ + spinlock_t msg_event_q_lock; + struct list_head msg_event_q; + wait_queue_head_t msg_event_wait; + + /* This queue contains preview frames. It is accessed by the DSP (in + * in interrupt context, and by the frame thread. + */ + spinlock_t prev_frame_q_lock; + struct list_head prev_frame_q; + wait_queue_head_t prev_frame_wait; + int unblock_poll_frame; + + /* This queue contains snapshot frames. It is accessed by the DSP (in + * interrupt context, and by the control thread. + */ + spinlock_t pict_frame_q_lock; + struct list_head pict_frame_q; + wait_queue_head_t pict_frame_wait; + + struct msm_camera_sensor_info *sdata; + struct msm_camvfe_fn vfefn; + struct msm_sensor_ctrl sctrl; + struct platform_device *pdev; + uint8_t opencnt; + void *cropinfo; + int croplen; + unsigned pict_pp; + + const char *apps_id; + + struct mutex lock; + struct list_head list; +}; + +#define MSM_APPS_ID_V4L2 "msm_v4l2" +#define MSM_APPS_ID_PROP "msm_qct" + +struct msm_device { + struct msm_sync *sync; /* most-frequently accessed */ + struct device *device; + struct cdev cdev; + /* opened is meaningful only for the config and frame nodes, + * which may be opened only once. + */ + atomic_t opened; +}; + +struct msm_control_device_queue { + spinlock_t ctrl_status_q_lock; + struct list_head ctrl_status_q; + wait_queue_head_t ctrl_status_wait; +}; + +struct msm_control_device { + struct msm_device *pmsm; + + /* This queue used by the config thread to send responses back to the + * control thread. It is accessed only from a process context. + */ + struct msm_control_device_queue ctrl_q; +}; + +/* this structure is used in kernel */ +struct msm_queue_cmd { + struct list_head list; + enum msm_queue type; + void *command; +}; + +struct register_address_value_pair { + uint16_t register_address; + uint16_t register_value; +}; + +struct msm_pmem_region { + struct hlist_node list; + int type; + void *vaddr; + unsigned long paddr; + unsigned long len; + struct file *file; + uint32_t y_off; + uint32_t cbcr_off; + int fd; + uint8_t active; +}; + +struct axidata { + uint32_t bufnum1; + uint32_t bufnum2; + struct msm_pmem_region *region; +}; + +#ifdef CONFIG_MSM_CAMERA_FLASH +int msm_camera_flash_set_led_state(unsigned led_state); +#else +static inline int msm_camera_flash_set_led_state(unsigned led_state) +{ + return -ENOTSUPP; +} +#endif + +/* Below functions are added for V4L2 kernel APIs */ +struct msm_v4l2_driver { + struct msm_sync *sync; + int (*open)(struct msm_sync *, const char *apps_id); + int (*release)(struct msm_sync *); + int (*ctrl)(struct msm_sync *, struct msm_ctrl_cmd *); + int (*reg_pmem)(struct msm_sync *, struct msm_pmem_info *); + int (*get_frame) (struct msm_sync *, struct msm_frame *); + int (*put_frame) (struct msm_sync *, struct msm_frame *); + int (*get_pict) (struct msm_sync *, struct msm_ctrl_cmd *); + unsigned int (*drv_poll) (struct msm_sync *, struct file *, + struct poll_table_struct *); +}; + +int msm_v4l2_register(struct msm_v4l2_driver *); +int msm_v4l2_unregister(struct msm_v4l2_driver *); + +void msm_camvfe_init(void); +int msm_camvfe_check(void *); +void msm_camvfe_fn_init(struct msm_camvfe_fn *, void *); +int msm_camera_drv_start(struct platform_device *dev, + int (*sensor_probe)(const struct msm_camera_sensor_info *, + struct msm_sensor_ctrl *)); + +enum msm_camio_clk_type { + CAMIO_VFE_MDC_CLK, + CAMIO_MDC_CLK, + CAMIO_VFE_CLK, + CAMIO_VFE_AXI_CLK, + + CAMIO_MAX_CLK +}; + +enum msm_camio_clk_src_type { + MSM_CAMIO_CLK_SRC_INTERNAL, + MSM_CAMIO_CLK_SRC_EXTERNAL, + MSM_CAMIO_CLK_SRC_MAX +}; + +enum msm_s_test_mode { + S_TEST_OFF, + S_TEST_1, + S_TEST_2, + S_TEST_3 +}; + +enum msm_s_resolution { + S_QTR_SIZE, + S_FULL_SIZE, + S_INVALID_SIZE +}; + +enum msm_s_reg_update { + /* Sensor egisters that need to be updated during initialization */ + S_REG_INIT, + /* Sensor egisters that needs periodic I2C writes */ + S_UPDATE_PERIODIC, + /* All the sensor Registers will be updated */ + S_UPDATE_ALL, + /* Not valid update */ + S_UPDATE_INVALID +}; + +enum msm_s_setting { + S_RES_PREVIEW, + S_RES_CAPTURE +}; + +int msm_camio_enable(struct platform_device *dev); + +int msm_camio_clk_enable(enum msm_camio_clk_type clk); +int msm_camio_clk_disable(enum msm_camio_clk_type clk); +int msm_camio_clk_config(uint32_t freq); +void msm_camio_clk_rate_set(int rate); +void msm_camio_clk_axi_rate_set(int rate); + +void msm_camio_camif_pad_reg_reset(void); +void msm_camio_camif_pad_reg_reset_2(void); + +void msm_camio_vfe_blk_reset(void); + +void msm_camio_clk_sel(enum msm_camio_clk_src_type); +void msm_camio_disable(struct platform_device *); +int msm_camio_probe_on(struct platform_device *); +int msm_camio_probe_off(struct platform_device *); +#endif diff --git a/drivers/staging/dream/include/mach/msm_adsp.h b/drivers/staging/dream/include/mach/msm_adsp.h new file mode 100644 index 0000000..a081683 --- /dev/null +++ b/drivers/staging/dream/include/mach/msm_adsp.h @@ -0,0 +1,112 @@ +/* include/asm-arm/arch-msm/msm_adsp.h + * + * Copyright (C) 2008 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ + +#ifndef __ASM__ARCH_MSM_ADSP_H +#define __ASM__ARCH_MSM_ADSP_H + +struct msm_adsp_module; + +struct msm_adsp_ops { + /* event is called from interrupt context when a message + * arrives from the DSP. Use the provided function pointer + * to copy the message into a local buffer. Do NOT call + * it multiple times. + */ + void (*event)(void *driver_data, unsigned id, size_t len, + void (*getevent)(void *ptr, size_t len)); +}; + +/* Get, Put, Enable, and Disable are synchronous and must only + * be called from thread context. Enable and Disable will block + * up to one second in the event of a fatal DSP error but are + * much faster otherwise. + */ +int msm_adsp_get(const char *name, struct msm_adsp_module **module, + struct msm_adsp_ops *ops, void *driver_data); +void msm_adsp_put(struct msm_adsp_module *module); +int msm_adsp_enable(struct msm_adsp_module *module); +int msm_adsp_disable(struct msm_adsp_module *module); +int adsp_set_clkrate(struct msm_adsp_module *module, unsigned long clk_rate); + +/* Write is safe to call from interrupt context. + */ +int msm_adsp_write(struct msm_adsp_module *module, + unsigned queue_id, + void *data, size_t len); + +#if CONFIG_MSM_AMSS_VERSION >= 6350 +/* Command Queue Indexes */ +#define QDSP_lpmCommandQueue 0 +#define QDSP_mpuAfeQueue 1 +#define QDSP_mpuGraphicsCmdQueue 2 +#define QDSP_mpuModmathCmdQueue 3 +#define QDSP_mpuVDecCmdQueue 4 +#define QDSP_mpuVDecPktQueue 5 +#define QDSP_mpuVEncCmdQueue 6 +#define QDSP_rxMpuDecCmdQueue 7 +#define QDSP_rxMpuDecPktQueue 8 +#define QDSP_txMpuEncQueue 9 +#define QDSP_uPAudPPCmd1Queue 10 +#define QDSP_uPAudPPCmd2Queue 11 +#define QDSP_uPAudPPCmd3Queue 12 +#define QDSP_uPAudPlay0BitStreamCtrlQueue 13 +#define QDSP_uPAudPlay1BitStreamCtrlQueue 14 +#define QDSP_uPAudPlay2BitStreamCtrlQueue 15 +#define QDSP_uPAudPlay3BitStreamCtrlQueue 16 +#define QDSP_uPAudPlay4BitStreamCtrlQueue 17 +#define QDSP_uPAudPreProcCmdQueue 18 +#define QDSP_uPAudRecBitStreamQueue 19 +#define QDSP_uPAudRecCmdQueue 20 +#define QDSP_uPDiagQueue 21 +#define QDSP_uPJpegActionCmdQueue 22 +#define QDSP_uPJpegCfgCmdQueue 23 +#define QDSP_uPVocProcQueue 24 +#define QDSP_vfeCommandQueue 25 +#define QDSP_vfeCommandScaleQueue 26 +#define QDSP_vfeCommandTableQueue 27 +#define QDSP_MAX_NUM_QUEUES 28 +#else +/* Command Queue Indexes */ +#define QDSP_lpmCommandQueue 0 +#define QDSP_mpuAfeQueue 1 +#define QDSP_mpuGraphicsCmdQueue 2 +#define QDSP_mpuModmathCmdQueue 3 +#define QDSP_mpuVDecCmdQueue 4 +#define QDSP_mpuVDecPktQueue 5 +#define QDSP_mpuVEncCmdQueue 6 +#define QDSP_rxMpuDecCmdQueue 7 +#define QDSP_rxMpuDecPktQueue 8 +#define QDSP_txMpuEncQueue 9 +#define QDSP_uPAudPPCmd1Queue 10 +#define QDSP_uPAudPPCmd2Queue 11 +#define QDSP_uPAudPPCmd3Queue 12 +#define QDSP_uPAudPlay0BitStreamCtrlQueue 13 +#define QDSP_uPAudPlay1BitStreamCtrlQueue 14 +#define QDSP_uPAudPlay2BitStreamCtrlQueue 15 +#define QDSP_uPAudPlay3BitStreamCtrlQueue 16 +#define QDSP_uPAudPlay4BitStreamCtrlQueue 17 +#define QDSP_uPAudPreProcCmdQueue 18 +#define QDSP_uPAudRecBitStreamQueue 19 +#define QDSP_uPAudRecCmdQueue 20 +#define QDSP_uPJpegActionCmdQueue 21 +#define QDSP_uPJpegCfgCmdQueue 22 +#define QDSP_uPVocProcQueue 23 +#define QDSP_vfeCommandQueue 24 +#define QDSP_vfeCommandScaleQueue 25 +#define QDSP_vfeCommandTableQueue 26 +#define QDSP_QUEUE_MAX 26 +#endif + +#endif diff --git a/drivers/staging/dream/include/mach/msm_rpcrouter.h b/drivers/staging/dream/include/mach/msm_rpcrouter.h new file mode 100644 index 0000000..9724ece --- /dev/null +++ b/drivers/staging/dream/include/mach/msm_rpcrouter.h @@ -0,0 +1,179 @@ +/** include/asm-arm/arch-msm/msm_rpcrouter.h + * + * Copyright (C) 2007 Google, Inc. + * Copyright (c) 2007-2009 QUALCOMM Incorporated + * Author: San Mehat <san@android.com> + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ + +#ifndef __ASM__ARCH_MSM_RPCROUTER_H +#define __ASM__ARCH_MSM_RPCROUTER_H + +#include <linux/types.h> +#include <linux/list.h> +#include <linux/platform_device.h> + +#if CONFIG_MSM_AMSS_VERSION >= 6350 +/* RPC API version structure + * Version bit 31 : 1->hashkey versioning, + * 0->major-minor (backward compatible) versioning + * hashkey versioning: + * Version bits 31-0 hashkey + * major-minor (backward compatible) versioning + * Version bits 30-28 reserved (no match) + * Version bits 27-16 major (must match) + * Version bits 15-0 minor (greater or equal) + */ +#define RPC_VERSION_MODE_MASK 0x80000000 +#define RPC_VERSION_MAJOR_MASK 0x0fff0000 +#define RPC_VERSION_MAJOR_OFFSET 16 +#define RPC_VERSION_MINOR_MASK 0x0000ffff + +#define MSM_RPC_VERS(major, minor) \ + ((uint32_t)((((major) << RPC_VERSION_MAJOR_OFFSET) & \ + RPC_VERSION_MAJOR_MASK) | \ + ((minor) & RPC_VERSION_MINOR_MASK))) +#define MSM_RPC_GET_MAJOR(vers) (((vers) & RPC_VERSION_MAJOR_MASK) >> \ + RPC_VERSION_MAJOR_OFFSET) +#define MSM_RPC_GET_MINOR(vers) ((vers) & RPC_VERSION_MINOR_MASK) +#else +#define MSM_RPC_VERS(major, minor) (major) +#define MSM_RPC_GET_MAJOR(vers) (vers) +#define MSM_RPC_GET_MINOR(vers) 0 +#endif + +struct msm_rpc_endpoint; + +struct rpcsvr_platform_device +{ + struct platform_device base; + uint32_t prog; + uint32_t vers; +}; + +#define RPC_DATA_IN 0 +/* + * Structures for sending / receiving direct RPC requests + * XXX: Any cred/verif lengths > 0 not supported + */ + +struct rpc_request_hdr +{ + uint32_t xid; + uint32_t type; /* 0 */ + uint32_t rpc_vers; /* 2 */ + uint32_t prog; + uint32_t vers; + uint32_t procedure; + uint32_t cred_flavor; + uint32_t cred_length; + uint32_t verf_flavor; + uint32_t verf_length; +}; + +typedef struct +{ + uint32_t low; + uint32_t high; +} rpc_reply_progmismatch_data; + +typedef struct +{ +} rpc_denied_reply_hdr; + +typedef struct +{ + uint32_t verf_flavor; + uint32_t verf_length; + uint32_t accept_stat; +#define RPC_ACCEPTSTAT_SUCCESS 0 +#define RPC_ACCEPTSTAT_PROG_UNAVAIL 1 +#define RPC_ACCEPTSTAT_PROG_MISMATCH 2 +#define RPC_ACCEPTSTAT_PROC_UNAVAIL 3 +#define RPC_ACCEPTSTAT_GARBAGE_ARGS 4 +#define RPC_ACCEPTSTAT_SYSTEM_ERR 5 +#define RPC_ACCEPTSTAT_PROG_LOCKED 6 + /* + * Following data is dependant on accept_stat + * If ACCEPTSTAT == PROG_MISMATCH then there is a + * 'rpc_reply_progmismatch_data' structure following the header. + * Otherwise the data is procedure specific + */ +} rpc_accepted_reply_hdr; + +struct rpc_reply_hdr +{ + uint32_t xid; + uint32_t type; + uint32_t reply_stat; +#define RPCMSG_REPLYSTAT_ACCEPTED 0 +#define RPCMSG_REPLYSTAT_DENIED 1 + union { + rpc_accepted_reply_hdr acc_hdr; + rpc_denied_reply_hdr dny_hdr; + } data; +}; + +/* flags for msm_rpc_connect() */ +#define MSM_RPC_UNINTERRUPTIBLE 0x0001 + +/* use IS_ERR() to check for failure */ +struct msm_rpc_endpoint *msm_rpc_open(void); +/* Connect with the specified server version */ +struct msm_rpc_endpoint *msm_rpc_connect(uint32_t prog, uint32_t vers, unsigned flags); +uint32_t msm_rpc_get_vers(struct msm_rpc_endpoint *ept); +/* check if server version can handle client requested version */ +int msm_rpc_is_compatible_version(uint32_t server_version, + uint32_t client_version); + +int msm_rpc_close(struct msm_rpc_endpoint *ept); +int msm_rpc_write(struct msm_rpc_endpoint *ept, + void *data, int len); +int msm_rpc_read(struct msm_rpc_endpoint *ept, + void **data, unsigned len, long timeout); +void msm_rpc_setup_req(struct rpc_request_hdr *hdr, + uint32_t prog, uint32_t vers, uint32_t proc); +int msm_rpc_register_server(struct msm_rpc_endpoint *ept, + uint32_t prog, uint32_t vers); +int msm_rpc_unregister_server(struct msm_rpc_endpoint *ept, + uint32_t prog, uint32_t vers); + +/* simple blocking rpc call + * + * request is mandatory and must have a rpc_request_hdr + * at the start. The header will be filled out for you. + * + * reply provides a buffer for replies of reply_max_size + */ +int msm_rpc_call_reply(struct msm_rpc_endpoint *ept, uint32_t proc, + void *request, int request_size, + void *reply, int reply_max_size, + long timeout); +int msm_rpc_call(struct msm_rpc_endpoint *ept, uint32_t proc, + void *request, int request_size, + long timeout); + +struct msm_rpc_server +{ + struct list_head list; + uint32_t flags; + + uint32_t prog; + uint32_t vers; + + int (*rpc_call)(struct msm_rpc_server *server, + struct rpc_request_hdr *req, unsigned len); +}; + +int msm_rpc_create_server(struct msm_rpc_server *server); + +#endif diff --git a/drivers/staging/dream/include/mach/msm_smd.h b/drivers/staging/dream/include/mach/msm_smd.h new file mode 100644 index 0000000..bdf7731 --- /dev/null +++ b/drivers/staging/dream/include/mach/msm_smd.h @@ -0,0 +1,107 @@ +/* linux/include/asm-arm/arch-msm/msm_smd.h + * + * Copyright (C) 2007 Google, Inc. + * Author: Brian Swetland <swetland@google.com> + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ + +#ifndef __ASM_ARCH_MSM_SMD_H +#define __ASM_ARCH_MSM_SMD_H + +typedef struct smd_channel smd_channel_t; + +/* warning: notify() may be called before open returns */ +int smd_open(const char *name, smd_channel_t **ch, void *priv, + void (*notify)(void *priv, unsigned event)); + +#define SMD_EVENT_DATA 1 +#define SMD_EVENT_OPEN 2 +#define SMD_EVENT_CLOSE 3 + +int smd_close(smd_channel_t *ch); + +/* passing a null pointer for data reads and discards */ +int smd_read(smd_channel_t *ch, void *data, int len); + +/* Write to stream channels may do a partial write and return +** the length actually written. +** Write to packet channels will never do a partial write -- +** it will return the requested length written or an error. +*/ +int smd_write(smd_channel_t *ch, const void *data, int len); + +int smd_write_avail(smd_channel_t *ch); +int smd_read_avail(smd_channel_t *ch); + +/* Returns the total size of the current packet being read. +** Returns 0 if no packets available or a stream channel. +*/ +int smd_cur_packet_size(smd_channel_t *ch); + +/* used for tty unthrottling and the like -- causes the notify() +** callback to be called from the same lock context as is used +** when it is called from channel updates +*/ +void smd_kick(smd_channel_t *ch); + + +#if 0 +/* these are interruptable waits which will block you until the specified +** number of bytes are readable or writable. +*/ +int smd_wait_until_readable(smd_channel_t *ch, int bytes); +int smd_wait_until_writable(smd_channel_t *ch, int bytes); +#endif + +typedef enum +{ + SMD_PORT_DS = 0, + SMD_PORT_DIAG, + SMD_PORT_RPC_CALL, + SMD_PORT_RPC_REPLY, + SMD_PORT_BT, + SMD_PORT_CONTROL, + SMD_PORT_MEMCPY_SPARE1, + SMD_PORT_DATA1, + SMD_PORT_DATA2, + SMD_PORT_DATA3, + SMD_PORT_DATA4, + SMD_PORT_DATA5, + SMD_PORT_DATA6, + SMD_PORT_DATA7, + SMD_PORT_DATA8, + SMD_PORT_DATA9, + SMD_PORT_DATA10, + SMD_PORT_DATA11, + SMD_PORT_DATA12, + SMD_PORT_DATA13, + SMD_PORT_DATA14, + SMD_PORT_DATA15, + SMD_PORT_DATA16, + SMD_PORT_DATA17, + SMD_PORT_DATA18, + SMD_PORT_DATA19, + SMD_PORT_DATA20, + SMD_PORT_GPS_NMEA, + SMD_PORT_BRIDGE_1, + SMD_PORT_BRIDGE_2, + SMD_PORT_BRIDGE_3, + SMD_PORT_BRIDGE_4, + SMD_PORT_BRIDGE_5, + SMD_PORT_LOOPBACK, + SMD_PORT_CS_APPS_MODEM, + SMD_PORT_CS_APPS_DSP, + SMD_PORT_CS_MODEM_DSP, + SMD_NUM_PORTS, +} smd_port_id_type; + +#endif diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5audplaycmdi.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5audplaycmdi.h new file mode 100644 index 0000000..0b6a312 --- /dev/null +++ b/drivers/staging/dream/include/mach/qdsp5/qdsp5audplaycmdi.h @@ -0,0 +1,94 @@ +#ifndef QDSP5AUDPLAYCMDI_H +#define QDSP5AUDPLAYCMDI_H + +/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* + + Q D S P 5 A U D I O P L A Y T A S K C O M M A N D S + +GENERAL DESCRIPTION + Command Interface for AUDPLAYTASK on QDSP5 + +REFERENCES + None + +EXTERNALIZED FUNCTIONS + + audplay_cmd_dec_data_avail + Send buffer to AUDPLAY task + + +Copyright(c) 1992 - 2009 by QUALCOMM, Incorporated. + +This software is licensed under the terms of the GNU General Public +License version 2, as published by the Free Software Foundation, and +may be copied, distributed, and modified under those terms. + +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. + +*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ +/*=========================================================================== + + EDIT HISTORY FOR FILE + +This section contains comments describing changes made to this file. +Notice that changes are listed in reverse chronological order. + +$Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audplaycmdi.h#2 $ + +===========================================================================*/ + +#define AUDPLAY_CMD_BITSTREAM_DATA_AVAIL 0x0000 +#define AUDPLAY_CMD_BITSTREAM_DATA_AVAIL_LEN \ + sizeof(audplay_cmd_bitstream_data_avail) + +/* Type specification of dec_data_avail message sent to AUDPLAYTASK +*/ +typedef struct { + /*command ID*/ + unsigned int cmd_id; + + /* Decoder ID for which message is being sent */ + unsigned int decoder_id; + + /* Start address of data in ARM global memory */ + unsigned int buf_ptr; + + /* Number of 16-bit words of bit-stream data contiguously available at the + * above-mentioned address. */ + unsigned int buf_size; + + /* Partition number used by audPlayTask to communicate with DSP's RTOS + * kernel */ + unsigned int partition_number; +} __attribute__((packed)) audplay_cmd_bitstream_data_avail; + +#define AUDPLAY_CMD_HPCM_BUF_CFG 0x0003 +#define AUDPLAY_CMD_HPCM_BUF_CFG_LEN \ + sizeof(struct audplay_cmd_hpcm_buf_cfg) + +struct audplay_cmd_hpcm_buf_cfg { + unsigned int cmd_id; + unsigned int hostpcm_config; + unsigned int feedback_frequency; + unsigned int byte_swap; + unsigned int max_buffers; + unsigned int partition_number; +} __attribute__((packed)); + +#define AUDPLAY_CMD_BUFFER_REFRESH 0x0004 +#define AUDPLAY_CMD_BUFFER_REFRESH_LEN \ + sizeof(struct audplay_cmd_buffer_update) + +struct audplay_cmd_buffer_refresh { + unsigned int cmd_id; + unsigned int num_buffers; + unsigned int buf_read_count; + unsigned int buf0_address; + unsigned int buf0_length; + unsigned int buf1_address; + unsigned int buf1_length; +} __attribute__((packed)); +#endif /* QDSP5AUDPLAYCMD_H */ diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5audplaymsg.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5audplaymsg.h new file mode 100644 index 0000000..c63034b --- /dev/null +++ b/drivers/staging/dream/include/mach/qdsp5/qdsp5audplaymsg.h @@ -0,0 +1,70 @@ +#ifndef QDSP5AUDPLAYMSG_H +#define QDSP5AUDPLAYMSG_H + +/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* + + Q D S P 5 A U D I O P L A Y T A S K M S G + +GENERAL DESCRIPTION + Message sent by AUDPLAY task + +REFERENCES + None + + +Copyright(c) 1992 - 2009 by QUALCOMM, Incorporated. + +This software is licensed under the terms of the GNU General Public +License version 2, as published by the Free Software Foundation, and +may be copied, distributed, and modified under those terms. + +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. + +*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ +/*=========================================================================== + + EDIT HISTORY FOR FILE + +This section contains comments describing changes made to this file. +Notice that changes are listed in reverse chronological order. + +$Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audplaymsg.h#3 $ + +===========================================================================*/ +#define AUDPLAY_MSG_DEC_NEEDS_DATA 0x0001 +#define AUDPLAY_MSG_DEC_NEEDS_DATA_MSG_LEN \ + sizeof(audplay_msg_dec_needs_data) + +typedef struct{ + /* reserved*/ + unsigned int dec_id; + + /* The read pointer offset of external memory until which the + * bitstream has been DMAed in. */ + unsigned int adecDataReadPtrOffset; + + /* The buffer size of external memory. */ + unsigned int adecDataBufSize; + + unsigned int bitstream_free_len; + unsigned int bitstream_write_ptr; + unsigned int bitstarem_buf_start; + unsigned int bitstream_buf_len; +} __attribute__((packed)) audplay_msg_dec_needs_data; + +#define AUDPLAY_MSG_BUFFER_UPDATE 0x0004 +#define AUDPLAY_MSG_BUFFER_UPDATE_LEN \ + sizeof(struct audplay_msg_buffer_update) + +struct audplay_msg_buffer_update { + unsigned int buffer_write_count; + unsigned int num_of_buffer; + unsigned int buf0_address; + unsigned int buf0_length; + unsigned int buf1_address; + unsigned int buf1_length; +} __attribute__((packed)); +#endif /* QDSP5AUDPLAYMSG_H */ diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5audppcmdi.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5audppcmdi.h new file mode 100644 index 0000000..8bee9c6 --- /dev/null +++ b/drivers/staging/dream/include/mach/qdsp5/qdsp5audppcmdi.h @@ -0,0 +1,914 @@ +#ifndef QDSP5AUDPPCMDI_H +#define QDSP5AUDPPCMDI_H + +/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* + + A U D I O P O S T P R O C E S S I N G I N T E R N A L C O M M A N D S + +GENERAL DESCRIPTION + This file contains defintions of format blocks of commands + that are accepted by AUDPP Task + +REFERENCES + None + +EXTERNALIZED FUNCTIONS + None + +Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated. + +This software is licensed under the terms of the GNU General Public +License version 2, as published by the Free Software Foundation, and +may be copied, distributed, and modified under those terms. + +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. + +*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ +/*=========================================================================== + + EDIT HISTORY FOR FILE + +This section contains comments describing changes made to this file. +Notice that changes are listed in reverse chronological order. + +$Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audppcmdi.h#2 $ + +===========================================================================*/ + +/* + * ARM to AUDPPTASK Commands + * + * ARM uses three command queues to communicate with AUDPPTASK + * 1)uPAudPPCmd1Queue : Used for more frequent and shorter length commands + * Location : MEMA + * Buffer Size : 6 words + * No of buffers in a queue : 20 for gaming audio and 5 for other images + * 2)uPAudPPCmd2Queue : Used for commands which are not much lengthier + * Location : MEMA + * Buffer Size : 23 + * No of buffers in a queue : 2 + * 3)uPAudOOCmd3Queue : Used for lengthier and more frequent commands + * Location : MEMA + * Buffer Size : 145 + * No of buffers in a queue : 3 + */ + +/* + * Commands Related to uPAudPPCmd1Queue + */ + +/* + * Command Structure to enable or disable the active decoders + */ + +#define AUDPP_CMD_CFG_DEC_TYPE 0x0001 +#define AUDPP_CMD_CFG_DEC_TYPE_LEN sizeof(audpp_cmd_cfg_dec_type) + +/* Enable the decoder */ +#define AUDPP_CMD_DEC_TYPE_M 0x000F + +#define AUDPP_CMD_ENA_DEC_V 0x4000 +#define AUDPP_CMD_DIS_DEC_V 0x0000 +#define AUDPP_CMD_DEC_STATE_M 0x4000 + +#define AUDPP_CMD_UPDATDE_CFG_DEC 0x8000 +#define AUDPP_CMD_DONT_UPDATE_CFG_DEC 0x0000 + + +/* Type specification of cmd_cfg_dec */ + +typedef struct { + unsigned short cmd_id; + unsigned short dec0_cfg; + unsigned short dec1_cfg; + unsigned short dec2_cfg; + unsigned short dec3_cfg; + unsigned short dec4_cfg; +} __attribute__((packed)) audpp_cmd_cfg_dec_type; + +/* + * Command Structure to Pause , Resume and flushes the selected audio decoders + */ + +#define AUDPP_CMD_DEC_CTRL 0x0002 +#define AUDPP_CMD_DEC_CTRL_LEN sizeof(audpp_cmd_dec_ctrl) + +/* Decoder control commands for pause, resume and flush */ +#define AUDPP_CMD_FLUSH_V 0x2000 + +#define AUDPP_CMD_PAUSE_V 0x4000 +#define AUDPP_CMD_RESUME_V 0x0000 + +#define AUDPP_CMD_UPDATE_V 0x8000 +#define AUDPP_CMD_IGNORE_V 0x0000 + + +/* Type Spec for decoder control command*/ + +typedef struct { + unsigned short cmd_id; + unsigned short dec0_ctrl; + unsigned short dec1_ctrl; + unsigned short dec2_ctrl; + unsigned short dec3_ctrl; + unsigned short dec4_ctrl; +} __attribute__((packed)) audpp_cmd_dec_ctrl; + +/* + * Command Structure to Configure the AVSync FeedBack Mechanism + */ + +#define AUDPP_CMD_AVSYNC 0x0003 +#define AUDPP_CMD_AVSYNC_LEN sizeof(audpp_cmd_avsync) + +typedef struct { + unsigned short cmd_id; + unsigned short object_number; + unsigned short interrupt_interval_lsw; + unsigned short interrupt_interval_msw; +} __attribute__((packed)) audpp_cmd_avsync; + +/* + * Command Structure to enable or disable(sleep) the AUDPPTASK + */ + +#define AUDPP_CMD_CFG 0x0004 +#define AUDPP_CMD_CFG_LEN sizeof(audpp_cmd_cfg) + +#define AUDPP_CMD_CFG_SLEEP 0x0000 +#define AUDPP_CMD_CFG_ENABLE 0xFFFF + +typedef struct { + unsigned short cmd_id; + unsigned short cfg; +} __attribute__((packed)) audpp_cmd_cfg; + +/* + * Command Structure to Inject or drop the specified no of samples + */ + +#define AUDPP_CMD_ADJUST_SAMP 0x0005 +#define AUDPP_CMD_ADJUST_SAMP_LEN sizeof(audpp_cmd_adjust_samp) + +#define AUDPP_CMD_SAMP_DROP -1 +#define AUDPP_CMD_SAMP_INSERT 0x0001 + +#define AUDPP_CMD_NUM_SAMPLES 0x0001 + +typedef struct { + unsigned short cmd_id; + unsigned short object_no; + signed short sample_insert_or_drop; + unsigned short num_samples; +} __attribute__((packed)) audpp_cmd_adjust_samp; + +/* + * Command Structure to Configure AVSync Feedback Mechanism + */ + +#define AUDPP_CMD_AVSYNC_CMD_2 0x0006 +#define AUDPP_CMD_AVSYNC_CMD_2_LEN sizeof(audpp_cmd_avsync_cmd_2) + +typedef struct { + unsigned short cmd_id; + unsigned short object_number; + unsigned short interrupt_interval_lsw; + unsigned short interrupt_interval_msw; + unsigned short sample_counter_dlsw; + unsigned short sample_counter_dmsw; + unsigned short sample_counter_msw; + unsigned short byte_counter_dlsw; + unsigned short byte_counter_dmsw; + unsigned short byte_counter_msw; +} __attribute__((packed)) audpp_cmd_avsync_cmd_2; + +/* + * Command Structure to Configure AVSync Feedback Mechanism + */ + +#define AUDPP_CMD_AVSYNC_CMD_3 0x0007 +#define AUDPP_CMD_AVSYNC_CMD_3_LEN sizeof(audpp_cmd_avsync_cmd_3) + +typedef struct { + unsigned short cmd_id; + unsigned short object_number; + unsigned short interrupt_interval_lsw; + unsigned short interrupt_interval_msw; + unsigned short sample_counter_dlsw; + unsigned short sample_counter_dmsw; + unsigned short sample_counter_msw; + unsigned short byte_counter_dlsw; + unsigned short byte_counter_dmsw; + unsigned short byte_counter_msw; +} __attribute__((packed)) audpp_cmd_avsync_cmd_3; + +#define AUDPP_CMD_ROUTING_MODE 0x0008 +#define AUDPP_CMD_ROUTING_MODE_LEN \ +sizeof(struct audpp_cmd_routing_mode) + +struct audpp_cmd_routing_mode { + unsigned short cmd_id; + unsigned short object_number; + unsigned short routing_mode; +} __attribute__((packed)); + +/* + * Commands Related to uPAudPPCmd2Queue + */ + +/* + * Command Structure to configure Per decoder Parameters (Common) + */ + +#define AUDPP_CMD_CFG_ADEC_PARAMS 0x0000 +#define AUDPP_CMD_CFG_ADEC_PARAMS_COMMON_LEN \ + sizeof(audpp_cmd_cfg_adec_params_common) + +#define AUDPP_CMD_STATUS_MSG_FLAG_ENA_FCM 0x4000 +#define AUDPP_CMD_STATUS_MSG_FLAG_DIS_FCM 0x0000 + +#define AUDPP_CMD_STATUS_MSG_FLAG_ENA_DCM 0x8000 +#define AUDPP_CMD_STATUS_MSG_FLAG_DIS_DCM 0x0000 + +/* Sampling frequency*/ +#define AUDPP_CMD_SAMP_RATE_96000 0x0000 +#define AUDPP_CMD_SAMP_RATE_88200 0x0001 +#define AUDPP_CMD_SAMP_RATE_64000 0x0002 +#define AUDPP_CMD_SAMP_RATE_48000 0x0003 +#define AUDPP_CMD_SAMP_RATE_44100 0x0004 +#define AUDPP_CMD_SAMP_RATE_32000 0x0005 +#define AUDPP_CMD_SAMP_RATE_24000 0x0006 +#define AUDPP_CMD_SAMP_RATE_22050 0x0007 +#define AUDPP_CMD_SAMP_RATE_16000 0x0008 +#define AUDPP_CMD_SAMP_RATE_12000 0x0009 +#define AUDPP_CMD_SAMP_RATE_11025 0x000A +#define AUDPP_CMD_SAMP_RATE_8000 0x000B + + +/* + * Type specification of cmd_adec_cfg sent to all decoder + */ + +typedef struct { + unsigned short cmd_id; + unsigned short length; + unsigned short dec_id; + unsigned short status_msg_flag; + unsigned short decoder_frame_counter_msg_period; + unsigned short input_sampling_frequency; +} __attribute__((packed)) audpp_cmd_cfg_adec_params_common; + +/* + * Command Structure to configure Per decoder Parameters (Wav) + */ + +#define AUDPP_CMD_CFG_ADEC_PARAMS_WAV_LEN \ + sizeof(audpp_cmd_cfg_adec_params_wav) + + +#define AUDPP_CMD_WAV_STEREO_CFG_MONO 0x0001 +#define AUDPP_CMD_WAV_STEREO_CFG_STEREO 0x0002 + +#define AUDPP_CMD_WAV_PCM_WIDTH_8 0x0000 +#define AUDPP_CMD_WAV_PCM_WIDTH_16 0x0001 +#define AUDPP_CMD_WAV_PCM_WIDTH_32 0x0002 + +typedef struct { + audpp_cmd_cfg_adec_params_common common; + unsigned short stereo_cfg; + unsigned short pcm_width; + unsigned short sign; +} __attribute__((packed)) audpp_cmd_cfg_adec_params_wav; + +/* + * Command Structure to configure Per decoder Parameters (ADPCM) + */ + +#define AUDPP_CMD_CFG_ADEC_PARAMS_ADPCM_LEN \ + sizeof(audpp_cmd_cfg_adec_params_adpcm) + + +#define AUDPP_CMD_ADPCM_STEREO_CFG_MONO 0x0001 +#define AUDPP_CMD_ADPCM_STEREO_CFG_STEREO 0x0002 + +typedef struct { + audpp_cmd_cfg_adec_params_common common; + unsigned short stereo_cfg; + unsigned short block_size; +} __attribute__((packed)) audpp_cmd_cfg_adec_params_adpcm; + +/* + * Command Structure to configure Per decoder Parameters (MP3) + */ + +#define AUDPP_CMD_CFG_ADEC_PARAMS_MP3_LEN \ + sizeof(audpp_cmd_cfg_adec_params_mp3) + +typedef struct { + audpp_cmd_cfg_adec_params_common common; +} __attribute__((packed)) audpp_cmd_cfg_adec_params_mp3; + + +/* + * Command Structure to configure Per decoder Parameters (AAC) + */ + +#define AUDPP_CMD_CFG_ADEC_PARAMS_AAC_LEN \ + sizeof(audpp_cmd_cfg_adec_params_aac) + + +#define AUDPP_CMD_AAC_FORMAT_ADTS -1 +#define AUDPP_CMD_AAC_FORMAT_RAW 0x0000 +#define AUDPP_CMD_AAC_FORMAT_PSUEDO_RAW 0x0001 +#define AUDPP_CMD_AAC_FORMAT_LOAS 0x0002 + +#define AUDPP_CMD_AAC_AUDIO_OBJECT_LC 0x0002 +#define AUDPP_CMD_AAC_AUDIO_OBJECT_LTP 0x0004 +#define AUDPP_CMD_AAC_AUDIO_OBJECT_ERLC 0x0011 + +#define AUDPP_CMD_AAC_SBR_ON_FLAG_ON 0x0001 +#define AUDPP_CMD_AAC_SBR_ON_FLAG_OFF 0x0000 + +#define AUDPP_CMD_AAC_SBR_PS_ON_FLAG_ON 0x0001 +#define AUDPP_CMD_AAC_SBR_PS_ON_FLAG_OFF 0x0000 + +typedef struct { + audpp_cmd_cfg_adec_params_common common; + signed short format; + unsigned short audio_object; + unsigned short ep_config; + unsigned short aac_section_data_resilience_flag; + unsigned short aac_scalefactor_data_resilience_flag; + unsigned short aac_spectral_data_resilience_flag; + unsigned short sbr_on_flag; + unsigned short sbr_ps_on_flag; + unsigned short dual_mono_mode; + unsigned short channel_configuration; +} __attribute__((packed)) audpp_cmd_cfg_adec_params_aac; + +/* + * Command Structure to configure Per decoder Parameters (V13K) + */ + +#define AUDPP_CMD_CFG_ADEC_PARAMS_V13K_LEN \ + sizeof(struct audpp_cmd_cfg_adec_params_v13k) + + +#define AUDPP_CMD_STEREO_CFG_MONO 0x0001 +#define AUDPP_CMD_STEREO_CFG_STEREO 0x0002 + +struct audpp_cmd_cfg_adec_params_v13k { + audpp_cmd_cfg_adec_params_common common; + unsigned short stereo_cfg; +} __attribute__((packed)); + +#define AUDPP_CMD_CFG_ADEC_PARAMS_EVRC_LEN \ + sizeof(struct audpp_cmd_cfg_adec_params_evrc) + +struct audpp_cmd_cfg_adec_params_evrc { + audpp_cmd_cfg_adec_params_common common; + unsigned short stereo_cfg; +} __attribute__ ((packed)); + +/* + * Command Structure to configure the HOST PCM interface + */ + +#define AUDPP_CMD_PCM_INTF 0x0001 +#define AUDPP_CMD_PCM_INTF_2 0x0002 +#define AUDPP_CMD_PCM_INTF_LEN sizeof(audpp_cmd_pcm_intf) + +#define AUDPP_CMD_PCM_INTF_MONO_V 0x0001 +#define AUDPP_CMD_PCM_INTF_STEREO_V 0x0002 + +/* These two values differentiate the two types of commands that could be issued + * Interface configuration command and Buffer update command */ + +#define AUDPP_CMD_PCM_INTF_CONFIG_CMD_V 0x0000 +#define AUDPP_CMD_PCM_INTF_BUFFER_CMD_V -1 + +#define AUDPP_CMD_PCM_INTF_RX_ENA_M 0x000F +#define AUDPP_CMD_PCM_INTF_RX_ENA_ARMTODSP_V 0x0008 +#define AUDPP_CMD_PCM_INTF_RX_ENA_DSPTOARM_V 0x0004 + +/* These flags control the enabling and disabling of the interface together + * with host interface bit mask. */ + +#define AUDPP_CMD_PCM_INTF_ENA_V -1 +#define AUDPP_CMD_PCM_INTF_DIS_V 0x0000 + + +#define AUDPP_CMD_PCM_INTF_FULL_DUPLEX 0x0 +#define AUDPP_CMD_PCM_INTF_HALF_DUPLEX_TODSP 0x1 + + +#define AUDPP_CMD_PCM_INTF_OBJECT_NUM 0x5 +#define AUDPP_CMD_PCM_INTF_COMMON_OBJECT_NUM 0x6 + + +typedef struct { + unsigned short cmd_id; + unsigned short object_num; + signed short config; + unsigned short intf_type; + + /* DSP -> ARM Configuration */ + unsigned short read_buf1LSW; + unsigned short read_buf1MSW; + unsigned short read_buf1_len; + + unsigned short read_buf2LSW; + unsigned short read_buf2MSW; + unsigned short read_buf2_len; + /* 0:HOST_PCM_INTF disable + ** 0xFFFF: HOST_PCM_INTF enable + */ + signed short dsp_to_arm_flag; + unsigned short partition_number; + + /* ARM -> DSP Configuration */ + unsigned short write_buf1LSW; + unsigned short write_buf1MSW; + unsigned short write_buf1_len; + + unsigned short write_buf2LSW; + unsigned short write_buf2MSW; + unsigned short write_buf2_len; + + /* 0:HOST_PCM_INTF disable + ** 0xFFFF: HOST_PCM_INTF enable + */ + signed short arm_to_rx_flag; + unsigned short weight_decoder_to_rx; + unsigned short weight_arm_to_rx; + + unsigned short partition_number_arm_to_dsp; + unsigned short sample_rate; + unsigned short channel_mode; +} __attribute__((packed)) audpp_cmd_pcm_intf; + +/* + ** BUFFER UPDATE COMMAND + */ +#define AUDPP_CMD_PCM_INTF_SEND_BUF_PARAMS_LEN \ + sizeof(audpp_cmd_pcm_intf_send_buffer) + +typedef struct { + unsigned short cmd_id; + unsigned short host_pcm_object; + /* set config = 0xFFFF for configuration*/ + signed short config; + unsigned short intf_type; + unsigned short dsp_to_arm_buf_id; + unsigned short arm_to_dsp_buf_id; + unsigned short arm_to_dsp_buf_len; +} __attribute__((packed)) audpp_cmd_pcm_intf_send_buffer; + + +/* + * Commands Related to uPAudPPCmd3Queue + */ + +/* + * Command Structure to configure post processing params (Commmon) + */ + +#define AUDPP_CMD_CFG_OBJECT_PARAMS 0x0000 +#define AUDPP_CMD_CFG_OBJECT_PARAMS_COMMON_LEN \ + sizeof(audpp_cmd_cfg_object_params_common) + +#define AUDPP_CMD_OBJ0_UPDATE 0x8000 +#define AUDPP_CMD_OBJ0_DONT_UPDATE 0x0000 + +#define AUDPP_CMD_OBJ1_UPDATE 0x8000 +#define AUDPP_CMD_OBJ1_DONT_UPDATE 0x0000 + +#define AUDPP_CMD_OBJ2_UPDATE 0x8000 +#define AUDPP_CMD_OBJ2_DONT_UPDATE 0x0000 + +#define AUDPP_CMD_OBJ3_UPDATE 0x8000 +#define AUDPP_CMD_OBJ3_DONT_UPDATE 0x0000 + +#define AUDPP_CMD_OBJ4_UPDATE 0x8000 +#define AUDPP_CMD_OBJ4_DONT_UPDATE 0x0000 + +#define AUDPP_CMD_HPCM_UPDATE 0x8000 +#define AUDPP_CMD_HPCM_DONT_UPDATE 0x0000 + +#define AUDPP_CMD_COMMON_CFG_UPDATE 0x8000 +#define AUDPP_CMD_COMMON_CFG_DONT_UPDATE 0x0000 + +typedef struct { + unsigned short cmd_id; + unsigned short obj0_cfg; + unsigned short obj1_cfg; + unsigned short obj2_cfg; + unsigned short obj3_cfg; + unsigned short obj4_cfg; + unsigned short host_pcm_obj_cfg; + unsigned short comman_cfg; + unsigned short command_type; +} __attribute__((packed)) audpp_cmd_cfg_object_params_common; + +/* + * Command Structure to configure post processing params (Volume) + */ + +#define AUDPP_CMD_CFG_OBJECT_PARAMS_VOLUME_LEN \ + sizeof(audpp_cmd_cfg_object_params_volume) + +typedef struct { + audpp_cmd_cfg_object_params_common common; + unsigned short volume; + unsigned short pan; +} __attribute__((packed)) audpp_cmd_cfg_object_params_volume; + +/* + * Command Structure to configure post processing params (PCM Filter) --DOUBT + */ + +typedef struct { + unsigned short numerator_b0_filter_lsw; + unsigned short numerator_b0_filter_msw; + unsigned short numerator_b1_filter_lsw; + unsigned short numerator_b1_filter_msw; + unsigned short numerator_b2_filter_lsw; + unsigned short numerator_b2_filter_msw; +} __attribute__((packed)) numerator; + +typedef struct { + unsigned short denominator_a0_filter_lsw; + unsigned short denominator_a0_filter_msw; + unsigned short denominator_a1_filter_lsw; + unsigned short denominator_a1_filter_msw; +} __attribute__((packed)) denominator; + +typedef struct { + unsigned short shift_factor_0; +} __attribute__((packed)) shift_factor; + +typedef struct { + unsigned short pan_filter_0; +} __attribute__((packed)) pan; + +typedef struct { + numerator numerator_filter; + denominator denominator_filter; + shift_factor shift_factor_filter; + pan pan_filter; +} __attribute__((packed)) filter_1; + +typedef struct { + numerator numerator_filter[2]; + denominator denominator_filter[2]; + shift_factor shift_factor_filter[2]; + pan pan_filter[2]; +} __attribute__((packed)) filter_2; + +typedef struct { + numerator numerator_filter[3]; + denominator denominator_filter[3]; + shift_factor shift_factor_filter[3]; + pan pan_filter[3]; +} __attribute__((packed)) filter_3; + +typedef struct { + numerator numerator_filter[4]; + denominator denominator_filter[4]; + shift_factor shift_factor_filter[4]; + pan pan_filter[4]; +} __attribute__((packed)) filter_4; + +#define AUDPP_CMD_CFG_OBJECT_PARAMS_PCM_LEN \ + sizeof(audpp_cmd_cfg_object_params_pcm) + + +typedef struct { + audpp_cmd_cfg_object_params_common common; + unsigned short active_flag; + unsigned short num_bands; + union { + filter_1 filter_1_params; + filter_2 filter_2_params; + filter_3 filter_3_params; + filter_4 filter_4_params; + } __attribute__((packed)) params_filter; +} __attribute__((packed)) audpp_cmd_cfg_object_params_pcm; + + +/* + * Command Structure to configure post processing parameters (equalizer) + */ + +#define AUDPP_CMD_CFG_OBJECT_PARAMS_EQALIZER_LEN \ + sizeof(audpp_cmd_cfg_object_params_eqalizer) + +typedef struct { + unsigned short numerator_coeff_0_lsw; + unsigned short numerator_coeff_0_msw; + unsigned short numerator_coeff_1_lsw; + unsigned short numerator_coeff_1_msw; + unsigned short numerator_coeff_2_lsw; + unsigned short numerator_coeff_2_msw; +} __attribute__((packed)) eq_numerator; + +typedef struct { + unsigned short denominator_coeff_0_lsw; + unsigned short denominator_coeff_0_msw; + unsigned short denominator_coeff_1_lsw; + unsigned short denominator_coeff_1_msw; +} __attribute__((packed)) eq_denominator; + +typedef struct { + unsigned short shift_factor; +} __attribute__((packed)) eq_shiftfactor; + +typedef struct { + eq_numerator numerator; + eq_denominator denominator; + eq_shiftfactor shiftfactor; +} __attribute__((packed)) eq_coeff_1; + +typedef struct { + eq_numerator numerator[2]; + eq_denominator denominator[2]; + eq_shiftfactor shiftfactor[2]; +} __attribute__((packed)) eq_coeff_2; + +typedef struct { + eq_numerator numerator[3]; + eq_denominator denominator[3]; + eq_shiftfactor shiftfactor[3]; +} __attribute__((packed)) eq_coeff_3; + +typedef struct { + eq_numerator numerator[4]; + eq_denominator denominator[4]; + eq_shiftfactor shiftfactor[4]; +} __attribute__((packed)) eq_coeff_4; + +typedef struct { + eq_numerator numerator[5]; + eq_denominator denominator[5]; + eq_shiftfactor shiftfactor[5]; +} __attribute__((packed)) eq_coeff_5; + +typedef struct { + eq_numerator numerator[6]; + eq_denominator denominator[6]; + eq_shiftfactor shiftfactor[6]; +} __attribute__((packed)) eq_coeff_6; + +typedef struct { + eq_numerator numerator[7]; + eq_denominator denominator[7]; + eq_shiftfactor shiftfactor[7]; +} __attribute__((packed)) eq_coeff_7; + +typedef struct { + eq_numerator numerator[8]; + eq_denominator denominator[8]; + eq_shiftfactor shiftfactor[8]; +} __attribute__((packed)) eq_coeff_8; + +typedef struct { + eq_numerator numerator[9]; + eq_denominator denominator[9]; + eq_shiftfactor shiftfactor[9]; +} __attribute__((packed)) eq_coeff_9; + +typedef struct { + eq_numerator numerator[10]; + eq_denominator denominator[10]; + eq_shiftfactor shiftfactor[10]; +} __attribute__((packed)) eq_coeff_10; + +typedef struct { + eq_numerator numerator[11]; + eq_denominator denominator[11]; + eq_shiftfactor shiftfactor[11]; +} __attribute__((packed)) eq_coeff_11; + +typedef struct { + eq_numerator numerator[12]; + eq_denominator denominator[12]; + eq_shiftfactor shiftfactor[12]; +} __attribute__((packed)) eq_coeff_12; + + +typedef struct { + audpp_cmd_cfg_object_params_common common; + unsigned short eq_flag; + unsigned short num_bands; + union { + eq_coeff_1 eq_coeffs_1; + eq_coeff_2 eq_coeffs_2; + eq_coeff_3 eq_coeffs_3; + eq_coeff_4 eq_coeffs_4; + eq_coeff_5 eq_coeffs_5; + eq_coeff_6 eq_coeffs_6; + eq_coeff_7 eq_coeffs_7; + eq_coeff_8 eq_coeffs_8; + eq_coeff_9 eq_coeffs_9; + eq_coeff_10 eq_coeffs_10; + eq_coeff_11 eq_coeffs_11; + eq_coeff_12 eq_coeffs_12; + } __attribute__((packed)) eq_coeff; +} __attribute__((packed)) audpp_cmd_cfg_object_params_eqalizer; + + +/* + * Command Structure to configure post processing parameters (ADRC) + */ + +#define AUDPP_CMD_CFG_OBJECT_PARAMS_ADRC_LEN \ + sizeof(audpp_cmd_cfg_object_params_adrc) + + +#define AUDPP_CMD_ADRC_FLAG_DIS 0x0000 +#define AUDPP_CMD_ADRC_FLAG_ENA -1 + +typedef struct { + audpp_cmd_cfg_object_params_common common; + signed short adrc_flag; + unsigned short compression_th; + unsigned short compression_slope; + unsigned short rms_time; + unsigned short attack_const_lsw; + unsigned short attack_const_msw; + unsigned short release_const_lsw; + unsigned short release_const_msw; + unsigned short adrc_system_delay; +} __attribute__((packed)) audpp_cmd_cfg_object_params_adrc; + +/* + * Command Structure to configure post processing parameters(Spectrum Analizer) + */ + +#define AUDPP_CMD_CFG_OBJECT_PARAMS_SPECTRAM_LEN \ + sizeof(audpp_cmd_cfg_object_params_spectram) + + +typedef struct { + audpp_cmd_cfg_object_params_common common; + unsigned short sample_interval; + unsigned short num_coeff; +} __attribute__((packed)) audpp_cmd_cfg_object_params_spectram; + +/* + * Command Structure to configure post processing parameters (QConcert) + */ + +#define AUDPP_CMD_CFG_OBJECT_PARAMS_QCONCERT_LEN \ + sizeof(audpp_cmd_cfg_object_params_qconcert) + + +#define AUDPP_CMD_QCON_ENA_FLAG_ENA -1 +#define AUDPP_CMD_QCON_ENA_FLAG_DIS 0x0000 + +#define AUDPP_CMD_QCON_OP_MODE_HEADPHONE -1 +#define AUDPP_CMD_QCON_OP_MODE_SPEAKER_FRONT 0x0000 +#define AUDPP_CMD_QCON_OP_MODE_SPEAKER_SIDE 0x0001 +#define AUDPP_CMD_QCON_OP_MODE_SPEAKER_DESKTOP 0x0002 + +#define AUDPP_CMD_QCON_GAIN_UNIT 0x7FFF +#define AUDPP_CMD_QCON_GAIN_SIX_DB 0x4027 + + +#define AUDPP_CMD_QCON_EXPANSION_MAX 0x7FFF + + +typedef struct { + audpp_cmd_cfg_object_params_common common; + signed short enable_flag; + signed short output_mode; + signed short gain; + signed short expansion; + signed short delay; + unsigned short stages_per_mode; +} __attribute__((packed)) audpp_cmd_cfg_object_params_qconcert; + +/* + * Command Structure to configure post processing parameters (Side Chain) + */ + +#define AUDPP_CMD_CFG_OBJECT_PARAMS_SIDECHAIN_LEN \ + sizeof(audpp_cmd_cfg_object_params_sidechain) + + +#define AUDPP_CMD_SIDECHAIN_ACTIVE_FLAG_DIS 0x0000 +#define AUDPP_CMD_SIDECHAIN_ACTIVE_FLAG_ENA -1 + +typedef struct { + audpp_cmd_cfg_object_params_common common; + signed short active_flag; + unsigned short num_bands; + union { + filter_1 filter_1_params; + filter_2 filter_2_params; + filter_3 filter_3_params; + filter_4 filter_4_params; + } __attribute__((packed)) params_filter; +} __attribute__((packed)) audpp_cmd_cfg_object_params_sidechain; + + +/* + * Command Structure to configure post processing parameters (QAFX) + */ + +#define AUDPP_CMD_CFG_OBJECT_PARAMS_QAFX_LEN \ + sizeof(audpp_cmd_cfg_object_params_qafx) + +#define AUDPP_CMD_QAFX_ENA_DISA 0x0000 +#define AUDPP_CMD_QAFX_ENA_ENA_CFG -1 +#define AUDPP_CMD_QAFX_ENA_DIS_CFG 0x0001 + +#define AUDPP_CMD_QAFX_CMD_TYPE_ENV 0x0100 +#define AUDPP_CMD_QAFX_CMD_TYPE_OBJ 0x0010 +#define AUDPP_CMD_QAFX_CMD_TYPE_QUERY 0x1000 + +#define AUDPP_CMD_QAFX_CMDS_ENV_OP_MODE 0x0100 +#define AUDPP_CMD_QAFX_CMDS_ENV_LIS_POS 0x0101 +#define AUDPP_CMD_QAFX_CMDS_ENV_LIS_ORI 0x0102 +#define AUDPP_CMD_QAFX_CMDS_ENV_LIS_VEL 0X0103 +#define AUDPP_CMD_QAFX_CMDS_ENV_ENV_RES 0x0107 + +#define AUDPP_CMD_QAFX_CMDS_OBJ_SAMP_FREQ 0x0010 +#define AUDPP_CMD_QAFX_CMDS_OBJ_VOL 0x0011 +#define AUDPP_CMD_QAFX_CMDS_OBJ_DIST 0x0012 +#define AUDPP_CMD_QAFX_CMDS_OBJ_POS 0x0013 +#define AUDPP_CMD_QAFX_CMDS_OBJ_VEL 0x0014 + + +typedef struct { + audpp_cmd_cfg_object_params_common common; + signed short enable; + unsigned short command_type; + unsigned short num_commands; + unsigned short commands; +} __attribute__((packed)) audpp_cmd_cfg_object_params_qafx; + +/* + * Command Structure to enable , disable or configure the reverberation effect + * (Common) + */ + +#define AUDPP_CMD_REVERB_CONFIG 0x0001 +#define AUDPP_CMD_REVERB_CONFIG_COMMON_LEN \ + sizeof(audpp_cmd_reverb_config_common) + +#define AUDPP_CMD_ENA_ENA 0xFFFF +#define AUDPP_CMD_ENA_DIS 0x0000 +#define AUDPP_CMD_ENA_CFG 0x0001 + +#define AUDPP_CMD_CMD_TYPE_ENV 0x0104 +#define AUDPP_CMD_CMD_TYPE_OBJ 0x0015 +#define AUDPP_CMD_CMD_TYPE_QUERY 0x1000 + + +typedef struct { + unsigned short cmd_id; + unsigned short enable; + unsigned short cmd_type; +} __attribute__((packed)) audpp_cmd_reverb_config_common; + +/* + * Command Structure to enable , disable or configure the reverberation effect + * (ENV-0x0104) + */ + +#define AUDPP_CMD_REVERB_CONFIG_ENV_104_LEN \ + sizeof(audpp_cmd_reverb_config_env_104) + +typedef struct { + audpp_cmd_reverb_config_common common; + unsigned short env_gain; + unsigned short decay_msw; + unsigned short decay_lsw; + unsigned short decay_timeratio_msw; + unsigned short decay_timeratio_lsw; + unsigned short delay_time; + unsigned short reverb_gain; + unsigned short reverb_delay; +} __attribute__((packed)) audpp_cmd_reverb_config_env_104; + +/* + * Command Structure to enable , disable or configure the reverberation effect + * (ENV-0x0015) + */ + +#define AUDPP_CMD_REVERB_CONFIG_ENV_15_LEN \ + sizeof(audpp_cmd_reverb_config_env_15) + +typedef struct { + audpp_cmd_reverb_config_common common; + unsigned short object_num; + unsigned short absolute_gain; +} __attribute__((packed)) audpp_cmd_reverb_config_env_15; + + +#endif /* QDSP5AUDPPCMDI_H */ + diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5audppmsg.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5audppmsg.h new file mode 100644 index 0000000..44fea22 --- /dev/null +++ b/drivers/staging/dream/include/mach/qdsp5/qdsp5audppmsg.h @@ -0,0 +1,318 @@ +#ifndef QDSP5AUDPPMSG_H +#define QDSP5AUDPPMSG_H + +/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* + + Q D S P 5 A U D I O P O S T P R O C E S S I N G M S G + +GENERAL DESCRIPTION + Messages sent by AUDPPTASK to ARM + +REFERENCES + None + +EXTERNALIZED FUNCTIONS + None + +Copyright(c) 1992 - 2009 by QUALCOMM, Incorporated. + +This software is licensed under the terms of the GNU General Public +License version 2, as published by the Free Software Foundation, and +may be copied, distributed, and modified under those terms. + +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. + +*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ +/*=========================================================================== + + EDIT HISTORY FOR FILE + +This section contains comments describing changes made to this file. +Notice that changes are listed in reverse chronological order. + + $Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audppmsg.h#4 $ + +===========================================================================*/ + +/* + * AUDPPTASK uses audPPuPRlist to send messages to the ARM + * Location : MEMA + * Buffer Size : 45 + * No of Buffers in a queue : 5 for gaming audio and 1 for other images + */ + +/* + * MSG to Informs the ARM os Success/Failure of bringing up the decoder + */ + +#define AUDPP_MSG_STATUS_MSG 0x0001 +#define AUDPP_MSG_STATUS_MSG_LEN \ + sizeof(audpp_msg_status_msg) + +#define AUDPP_MSG_STATUS_SLEEP 0x0000 +#define AUDPP_MSG__STATUS_INIT 0x0001 +#define AUDPP_MSG_MSG_STATUS_CFG 0x0002 +#define AUDPP_MSG_STATUS_PLAY 0x0003 + +#define AUDPP_MSG_REASON_MIPS 0x0000 +#define AUDPP_MSG_REASON_MEM 0x0001 + +typedef struct{ + unsigned short dec_id; + unsigned short status; + unsigned short reason; +} __attribute__((packed)) audpp_msg_status_msg; + +/* + * MSG to communicate the spectrum analyzer output bands to the ARM + */ +#define AUDPP_MSG_SPA_BANDS 0x0002 +#define AUDPP_MSG_SPA_BANDS_LEN \ + sizeof(audpp_msg_spa_bands) + +typedef struct { + unsigned short current_object; + unsigned short spa_band_1; + unsigned short spa_band_2; + unsigned short spa_band_3; + unsigned short spa_band_4; + unsigned short spa_band_5; + unsigned short spa_band_6; + unsigned short spa_band_7; + unsigned short spa_band_8; + unsigned short spa_band_9; + unsigned short spa_band_10; + unsigned short spa_band_11; + unsigned short spa_band_12; + unsigned short spa_band_13; + unsigned short spa_band_14; + unsigned short spa_band_15; + unsigned short spa_band_16; + unsigned short spa_band_17; + unsigned short spa_band_18; + unsigned short spa_band_19; + unsigned short spa_band_20; + unsigned short spa_band_21; + unsigned short spa_band_22; + unsigned short spa_band_23; + unsigned short spa_band_24; + unsigned short spa_band_25; + unsigned short spa_band_26; + unsigned short spa_band_27; + unsigned short spa_band_28; + unsigned short spa_band_29; + unsigned short spa_band_30; + unsigned short spa_band_31; + unsigned short spa_band_32; +} __attribute__((packed)) audpp_msg_spa_bands; + +/* + * MSG to communicate the PCM I/O buffer status to ARM + */ +#define AUDPP_MSG_HOST_PCM_INTF_MSG 0x0003 +#define AUDPP_MSG_HOST_PCM_INTF_MSG_LEN \ + sizeof(audpp_msg_host_pcm_intf_msg) + +#define AUDPP_MSG_HOSTPCM_ID_TX_ARM 0x0000 +#define AUDPP_MSG_HOSTPCM_ID_ARM_TX 0x0001 +#define AUDPP_MSG_HOSTPCM_ID_RX_ARM 0x0002 +#define AUDPP_MSG_HOSTPCM_ID_ARM_RX 0x0003 + +#define AUDPP_MSG_SAMP_FREQ_INDX_96000 0x0000 +#define AUDPP_MSG_SAMP_FREQ_INDX_88200 0x0001 +#define AUDPP_MSG_SAMP_FREQ_INDX_64000 0x0002 +#define AUDPP_MSG_SAMP_FREQ_INDX_48000 0x0003 +#define AUDPP_MSG_SAMP_FREQ_INDX_44100 0x0004 +#define AUDPP_MSG_SAMP_FREQ_INDX_32000 0x0005 +#define AUDPP_MSG_SAMP_FREQ_INDX_24000 0x0006 +#define AUDPP_MSG_SAMP_FREQ_INDX_22050 0x0007 +#define AUDPP_MSG_SAMP_FREQ_INDX_16000 0x0008 +#define AUDPP_MSG_SAMP_FREQ_INDX_12000 0x0009 +#define AUDPP_MSG_SAMP_FREQ_INDX_11025 0x000A +#define AUDPP_MSG_SAMP_FREQ_INDX_8000 0x000B + +#define AUDPP_MSG_CHANNEL_MODE_MONO 0x0001 +#define AUDPP_MSG_CHANNEL_MODE_STEREO 0x0002 + +typedef struct{ + unsigned short obj_num; + unsigned short numbers_of_samples; + unsigned short host_pcm_id; + unsigned short buf_indx; + unsigned short samp_freq_indx; + unsigned short channel_mode; +} __attribute__((packed)) audpp_msg_host_pcm_intf_msg; + + +/* + * MSG to communicate 3D position of the source and listener , source volume + * source rolloff, source orientation + */ + +#define AUDPP_MSG_QAFX_POS 0x0004 +#define AUDPP_MSG_QAFX_POS_LEN \ + sizeof(audpp_msg_qafx_pos) + +typedef struct { + unsigned short current_object; + unsigned short x_pos_lis_msw; + unsigned short x_pos_lis_lsw; + unsigned short y_pos_lis_msw; + unsigned short y_pos_lis_lsw; + unsigned short z_pos_lis_msw; + unsigned short z_pos_lis_lsw; + unsigned short x_fwd_msw; + unsigned short x_fwd_lsw; + unsigned short y_fwd_msw; + unsigned short y_fwd_lsw; + unsigned short z_fwd_msw; + unsigned short z_fwd_lsw; + unsigned short x_up_msw; + unsigned short x_up_lsw; + unsigned short y_up_msw; + unsigned short y_up_lsw; + unsigned short z_up_msw; + unsigned short z_up_lsw; + unsigned short x_vel_lis_msw; + unsigned short x_vel_lis_lsw; + unsigned short y_vel_lis_msw; + unsigned short y_vel_lis_lsw; + unsigned short z_vel_lis_msw; + unsigned short z_vel_lis_lsw; + unsigned short threed_enable_flag; + unsigned short volume; + unsigned short x_pos_source_msw; + unsigned short x_pos_source_lsw; + unsigned short y_pos_source_msw; + unsigned short y_pos_source_lsw; + unsigned short z_pos_source_msw; + unsigned short z_pos_source_lsw; + unsigned short max_dist_0_msw; + unsigned short max_dist_0_lsw; + unsigned short min_dist_0_msw; + unsigned short min_dist_0_lsw; + unsigned short roll_off_factor; + unsigned short mute_after_max_flag; + unsigned short x_vel_source_msw; + unsigned short x_vel_source_lsw; + unsigned short y_vel_source_msw; + unsigned short y_vel_source_lsw; + unsigned short z_vel_source_msw; + unsigned short z_vel_source_lsw; +} __attribute__((packed)) audpp_msg_qafx_pos; + +/* + * MSG to provide AVSYNC feedback from DSP to ARM + */ + +#define AUDPP_MSG_AVSYNC_MSG 0x0005 +#define AUDPP_MSG_AVSYNC_MSG_LEN \ + sizeof(audpp_msg_avsync_msg) + +typedef struct { + unsigned short active_flag; + unsigned short num_samples_counter0_HSW; + unsigned short num_samples_counter0_MSW; + unsigned short num_samples_counter0_LSW; + unsigned short num_bytes_counter0_HSW; + unsigned short num_bytes_counter0_MSW; + unsigned short num_bytes_counter0_LSW; + unsigned short samp_freq_obj_0; + unsigned short samp_freq_obj_1; + unsigned short samp_freq_obj_2; + unsigned short samp_freq_obj_3; + unsigned short samp_freq_obj_4; + unsigned short samp_freq_obj_5; + unsigned short samp_freq_obj_6; + unsigned short samp_freq_obj_7; + unsigned short samp_freq_obj_8; + unsigned short samp_freq_obj_9; + unsigned short samp_freq_obj_10; + unsigned short samp_freq_obj_11; + unsigned short samp_freq_obj_12; + unsigned short samp_freq_obj_13; + unsigned short samp_freq_obj_14; + unsigned short samp_freq_obj_15; + unsigned short num_samples_counter4_HSW; + unsigned short num_samples_counter4_MSW; + unsigned short num_samples_counter4_LSW; + unsigned short num_bytes_counter4_HSW; + unsigned short num_bytes_counter4_MSW; + unsigned short num_bytes_counter4_LSW; +} __attribute__((packed)) audpp_msg_avsync_msg; + +/* + * MSG to provide PCM DMA Missed feedback from the DSP to ARM + */ + +#define AUDPP_MSG_PCMDMAMISSED 0x0006 +#define AUDPP_MSG_PCMDMAMISSED_LEN \ + sizeof(audpp_msg_pcmdmamissed); + +typedef struct{ + /* + ** Bit 0 0 = PCM DMA not missed for object 0 + ** 1 = PCM DMA missed for object0 + ** Bit 1 0 = PCM DMA not missed for object 1 + ** 1 = PCM DMA missed for object1 + ** Bit 2 0 = PCM DMA not missed for object 2 + ** 1 = PCM DMA missed for object2 + ** Bit 3 0 = PCM DMA not missed for object 3 + ** 1 = PCM DMA missed for object3 + ** Bit 4 0 = PCM DMA not missed for object 4 + ** 1 = PCM DMA missed for object4 + */ + unsigned short pcmdmamissed; +} __attribute__((packed)) audpp_msg_pcmdmamissed; + +/* + * MSG to AUDPP enable or disable feedback form DSP to ARM + */ + +#define AUDPP_MSG_CFG_MSG 0x0007 +#define AUDPP_MSG_CFG_MSG_LEN \ + sizeof(audpp_msg_cfg_msg) + +#define AUDPP_MSG_ENA_ENA 0xFFFF +#define AUDPP_MSG_ENA_DIS 0x0000 + +typedef struct{ + /* Enabled - 0xffff + ** Disabled - 0 + */ + unsigned short enabled; +} __attribute__((packed)) audpp_msg_cfg_msg; + +/* + * MSG to communicate the reverb per object volume + */ + +#define AUDPP_MSG_QREVERB_VOLUME 0x0008 +#define AUDPP_MSG_QREVERB_VOLUME_LEN \ + sizeof(audpp_msg_qreverb_volume) + + +typedef struct { + unsigned short obj_0_gain; + unsigned short obj_1_gain; + unsigned short obj_2_gain; + unsigned short obj_3_gain; + unsigned short obj_4_gain; + unsigned short hpcm_obj_volume; +} __attribute__((packed)) audpp_msg_qreverb_volume; + +#define AUDPP_MSG_ROUTING_ACK 0x0009 +#define AUDPP_MSG_ROUTING_ACK_LEN \ + sizeof(struct audpp_msg_routing_ack) + +struct audpp_msg_routing_ack { + unsigned short dec_id; + unsigned short routing_mode; +} __attribute__((packed)); + +#define AUDPP_MSG_FLUSH_ACK 0x000A + +#endif /* QDSP5AUDPPMSG_H */ diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5audpreproccmdi.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5audpreproccmdi.h new file mode 100644 index 0000000..06d33d5 --- /dev/null +++ b/drivers/staging/dream/include/mach/qdsp5/qdsp5audpreproccmdi.h @@ -0,0 +1,256 @@ +#ifndef QDSP5AUDPREPROCCMDI_H +#define QDSP5AUDPREPROCCMDI_H + +/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* + + A U D I O P R E P R O C E S S I N G I N T E R N A L C O M M A N D S + +GENERAL DESCRIPTION + This file contains defintions of format blocks of commands + that are accepted by AUDPREPROC Task + +REFERENCES + None + +EXTERNALIZED FUNCTIONS + None + +Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated. + +This software is licensed under the terms of the GNU General Public +License version 2, as published by the Free Software Foundation, and +may be copied, distributed, and modified under those terms. + +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. + +*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ +/*=========================================================================== + + EDIT HISTORY FOR FILE + +This section contains comments describing changes made to this file. +Notice that changes are listed in reverse chronological order. + +$Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audpreproccmdi.h#2 $ + +===========================================================================*/ + +/* + * AUDIOPREPROC COMMANDS: + * ARM uses uPAudPreProcCmdQueue to communicate with AUDPREPROCTASK + * Location : MEMB + * Buffer size : 51 + * Number of buffers in a queue : 3 + */ + +/* + * Command to configure the parameters of AGC + */ + +#define AUDPREPROC_CMD_CFG_AGC_PARAMS 0x0000 +#define AUDPREPROC_CMD_CFG_AGC_PARAMS_LEN \ + sizeof(audpreproc_cmd_cfg_agc_params) + +#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_SLOPE 0x0009 +#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_TH 0x000A +#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_EXP_SLOPE 0x000B +#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_EXP_TH 0x000C +#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_AIG_FLAG 0x000D +#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_STATIC_GAIN 0x000E +#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_TX_AGC_ENA_FLAG 0x000F + +#define AUDPREPROC_CMD_TX_AGC_ENA_FLAG_ENA -1 +#define AUDPREPROC_CMD_TX_AGC_ENA_FLAG_DIS 0x0000 + +#define AUDPREPROC_CMD_ADP_GAIN_FLAG_ENA_ADP_GAIN -1 +#define AUDPREPROC_CMD_ADP_GAIN_FLAG_ENA_STATIC_GAIN 0x0000 + +#define AUDPREPROC_CMD_PARAM_MASK_RMS_TAY 0x0004 +#define AUDPREPROC_CMD_PARAM_MASK_RELEASEK 0x0005 +#define AUDPREPROC_CMD_PARAM_MASK_DELAY 0x0006 +#define AUDPREPROC_CMD_PARAM_MASK_ATTACKK 0x0007 +#define AUDPREPROC_CMD_PARAM_MASK_LEAKRATE_SLOW 0x0008 +#define AUDPREPROC_CMD_PARAM_MASK_LEAKRATE_FAST 0x0009 +#define AUDPREPROC_CMD_PARAM_MASK_AIG_RELEASEK 0x000A +#define AUDPREPROC_CMD_PARAM_MASK_AIG_MIN 0x000B +#define AUDPREPROC_CMD_PARAM_MASK_AIG_MAX 0x000C +#define AUDPREPROC_CMD_PARAM_MASK_LEAK_UP 0x000D +#define AUDPREPROC_CMD_PARAM_MASK_LEAK_DOWN 0x000E +#define AUDPREPROC_CMD_PARAM_MASK_AIG_ATTACKK 0x000F + +typedef struct { + unsigned short cmd_id; + unsigned short tx_agc_param_mask; + unsigned short tx_agc_enable_flag; + unsigned short static_gain; + signed short adaptive_gain_flag; + unsigned short expander_th; + unsigned short expander_slope; + unsigned short compressor_th; + unsigned short compressor_slope; + unsigned short param_mask; + unsigned short aig_attackk; + unsigned short aig_leak_down; + unsigned short aig_leak_up; + unsigned short aig_max; + unsigned short aig_min; + unsigned short aig_releasek; + unsigned short aig_leakrate_fast; + unsigned short aig_leakrate_slow; + unsigned short attackk_msw; + unsigned short attackk_lsw; + unsigned short delay; + unsigned short releasek_msw; + unsigned short releasek_lsw; + unsigned short rms_tav; +} __attribute__((packed)) audpreproc_cmd_cfg_agc_params; + + +/* + * Command to configure the params of Advanved AGC + */ + +#define AUDPREPROC_CMD_CFG_AGC_PARAMS_2 0x0001 +#define AUDPREPROC_CMD_CFG_AGC_PARAMS_2_LEN \ + sizeof(audpreproc_cmd_cfg_agc_params_2) + +#define AUDPREPROC_CMD_2_TX_AGC_ENA_FLAG_ENA -1; +#define AUDPREPROC_CMD_2_TX_AGC_ENA_FLAG_DIS 0x0000; + +typedef struct { + unsigned short cmd_id; + unsigned short agc_param_mask; + signed short tx_agc_enable_flag; + unsigned short comp_static_gain; + unsigned short exp_th; + unsigned short exp_slope; + unsigned short comp_th; + unsigned short comp_slope; + unsigned short comp_rms_tav; + unsigned short comp_samp_mask; + unsigned short comp_attackk_msw; + unsigned short comp_attackk_lsw; + unsigned short comp_releasek_msw; + unsigned short comp_releasek_lsw; + unsigned short comp_delay; + unsigned short comp_makeup_gain; +} __attribute__((packed)) audpreproc_cmd_cfg_agc_params_2; + +/* + * Command to configure params for ns + */ + +#define AUDPREPROC_CMD_CFG_NS_PARAMS 0x0002 +#define AUDPREPROC_CMD_CFG_NS_PARAMS_LEN \ + sizeof(audpreproc_cmd_cfg_ns_params) + +#define AUDPREPROC_CMD_EC_MODE_NEW_NLMS_ENA 0x0001 +#define AUDPREPROC_CMD_EC_MODE_NEW_NLMS_DIS 0x0000 +#define AUDPREPROC_CMD_EC_MODE_NEW_DES_ENA 0x0002 +#define AUDPREPROC_CMD_EC_MODE_NEW_DES_DIS 0x0000 +#define AUDPREPROC_CMD_EC_MODE_NEW_NS_ENA 0x0004 +#define AUDPREPROC_CMD_EC_MODE_NEW_NS_DIS 0x0000 +#define AUDPREPROC_CMD_EC_MODE_NEW_CNI_ENA 0x0008 +#define AUDPREPROC_CMD_EC_MODE_NEW_CNI_DIS 0x0000 + +#define AUDPREPROC_CMD_EC_MODE_NEW_NLES_ENA 0x0010 +#define AUDPREPROC_CMD_EC_MODE_NEW_NLES_DIS 0x0000 +#define AUDPREPROC_CMD_EC_MODE_NEW_HB_ENA 0x0020 +#define AUDPREPROC_CMD_EC_MODE_NEW_HB_DIS 0x0000 +#define AUDPREPROC_CMD_EC_MODE_NEW_VA_ENA 0x0040 +#define AUDPREPROC_CMD_EC_MODE_NEW_VA_DIS 0x0000 +#define AUDPREPROC_CMD_EC_MODE_NEW_PCD_ENA 0x0080 +#define AUDPREPROC_CMD_EC_MODE_NEW_PCD_DIS 0x0000 +#define AUDPREPROC_CMD_EC_MODE_NEW_FEHI_ENA 0x0100 +#define AUDPREPROC_CMD_EC_MODE_NEW_FEHI_DIS 0x0000 +#define AUDPREPROC_CMD_EC_MODE_NEW_NEHI_ENA 0x0200 +#define AUDPREPROC_CMD_EC_MODE_NEW_NEHI_DIS 0x0000 +#define AUDPREPROC_CMD_EC_MODE_NEW_NLPP_ENA 0x0400 +#define AUDPREPROC_CMD_EC_MODE_NEW_NLPP_DIS 0x0000 +#define AUDPREPROC_CMD_EC_MODE_NEW_FNE_ENA 0x0800 +#define AUDPREPROC_CMD_EC_MODE_NEW_FNE_DIS 0x0000 +#define AUDPREPROC_CMD_EC_MODE_NEW_PRENLMS_ENA 0x1000 +#define AUDPREPROC_CMD_EC_MODE_NEW_PRENLMS_DIS 0x0000 + +typedef struct { + unsigned short cmd_id; + unsigned short ec_mode_new; + unsigned short dens_gamma_n; + unsigned short dens_nfe_block_size; + unsigned short dens_limit_ns; + unsigned short dens_limit_ns_d; + unsigned short wb_gamma_e; + unsigned short wb_gamma_n; +} __attribute__((packed)) audpreproc_cmd_cfg_ns_params; + +/* + * Command to configure parameters for IIR tuning filter + */ + +#define AUDPREPROC_CMD_CFG_IIR_TUNING_FILTER_PARAMS 0x0003 +#define AUDPREPROC_CMD_CFG_IIR_TUNING_FILTER_PARAMS_LEN \ + sizeof(audpreproc_cmd_cfg_iir_tuning_filter_params) + +#define AUDPREPROC_CMD_IIR_ACTIVE_FLAG_DIS 0x0000 +#define AUDPREPROC_CMD_IIR_ACTIVE_FLAG_ENA 0x0001 + +typedef struct { + unsigned short cmd_id; + unsigned short active_flag; + unsigned short num_bands; + unsigned short numerator_coeff_b0_filter0_lsw; + unsigned short numerator_coeff_b0_filter0_msw; + unsigned short numerator_coeff_b1_filter0_lsw; + unsigned short numerator_coeff_b1_filter0_msw; + unsigned short numerator_coeff_b2_filter0_lsw; + unsigned short numerator_coeff_b2_filter0_msw; + unsigned short numerator_coeff_b0_filter1_lsw; + unsigned short numerator_coeff_b0_filter1_msw; + unsigned short numerator_coeff_b1_filter1_lsw; + unsigned short numerator_coeff_b1_filter1_msw; + unsigned short numerator_coeff_b2_filter1_lsw; + unsigned short numerator_coeff_b2_filter1_msw; + unsigned short numerator_coeff_b0_filter2_lsw; + unsigned short numerator_coeff_b0_filter2_msw; + unsigned short numerator_coeff_b1_filter2_lsw; + unsigned short numerator_coeff_b1_filter2_msw; + unsigned short numerator_coeff_b2_filter2_lsw; + unsigned short numerator_coeff_b2_filter2_msw; + unsigned short numerator_coeff_b0_filter3_lsw; + unsigned short numerator_coeff_b0_filter3_msw; + unsigned short numerator_coeff_b1_filter3_lsw; + unsigned short numerator_coeff_b1_filter3_msw; + unsigned short numerator_coeff_b2_filter3_lsw; + unsigned short numerator_coeff_b2_filter3_msw; + unsigned short denominator_coeff_a0_filter0_lsw; + unsigned short denominator_coeff_a0_filter0_msw; + unsigned short denominator_coeff_a1_filter0_lsw; + unsigned short denominator_coeff_a1_filter0_msw; + unsigned short denominator_coeff_a0_filter1_lsw; + unsigned short denominator_coeff_a0_filter1_msw; + unsigned short denominator_coeff_a1_filter1_lsw; + unsigned short denominator_coeff_a1_filter1_msw; + unsigned short denominator_coeff_a0_filter2_lsw; + unsigned short denominator_coeff_a0_filter2_msw; + unsigned short denominator_coeff_a1_filter2_lsw; + unsigned short denominator_coeff_a1_filter2_msw; + unsigned short denominator_coeff_a0_filter3_lsw; + unsigned short denominator_coeff_a0_filter3_msw; + unsigned short denominator_coeff_a1_filter3_lsw; + unsigned short denominator_coeff_a1_filter3_msw; + + unsigned short shift_factor_filter0; + unsigned short shift_factor_filter1; + unsigned short shift_factor_filter2; + unsigned short shift_factor_filter3; + + unsigned short channel_selected0; + unsigned short channel_selected1; + unsigned short channel_selected2; + unsigned short channel_selected3; +} __attribute__((packed))audpreproc_cmd_cfg_iir_tuning_filter_params; + +#endif diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5audpreprocmsg.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5audpreprocmsg.h new file mode 100644 index 0000000..f40e41e --- /dev/null +++ b/drivers/staging/dream/include/mach/qdsp5/qdsp5audpreprocmsg.h @@ -0,0 +1,85 @@ +#ifndef QDSP5AUDPREPROCMSG_H +#define QDSP5AUDPREPROCMSG_H + +/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* + + A U D I O P R E P R O C E S S I N G M E S S A G E S + +GENERAL DESCRIPTION + This file contains defintions of format blocks of messages + that are rcvd by AUDPREPROC Task + +REFERENCES + None + +EXTERNALIZED FUNCTIONS + None + +Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated. + +This software is licensed under the terms of the GNU General Public +License version 2, as published by the Free Software Foundation, and +may be copied, distributed, and modified under those terms. + +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. + +*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ +/*=========================================================================== + + EDIT HISTORY FOR FILE + +This section contains comments describing changes made to this file. +Notice that changes are listed in reverse chronological order. + + $Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audpreprocmsg.h#3 $ + +===========================================================================*/ + +/* + * ADSPREPROCTASK Messages + * AUDPREPROCTASK uses audPreProcUpRlist to communicate with ARM + * Location : MEMA + * Message Length : 2 + */ + +/* + * Message to indicate particular feature has been enabled or disabled + */ + + +#define AUDPREPROC_MSG_CMD_CFG_DONE_MSG 0x0000 +#define AUDPREPROC_MSG_CMD_CFG_DONE_MSG_LEN \ + sizeof(audpreproc_msg_cmd_cfg_done_msg) + +#define AUDPREPROC_MSG_TYPE_AGC 0x0000 +#define AUDPREPROC_MSG_TYPE_NOISE_REDUCTION 0x0001 +#define AUDPREPROC_MSG_TYPE_IIR_FILTER 0x0002 + + +#define AUDPREPROC_MSG_STATUS_FLAG_ENA -1 +#define AUDPREPROC_MSG_STATUS_FLAG_DIS 0x0000 + +typedef struct { + unsigned short type; + signed short status_flag; +} __attribute__((packed)) audpreproc_msg_cmd_cfg_done_msg; + + +/* + * Message to indicate particular feature has selected for wrong samp freq + */ + +#define AUDPREPROC_MSG_ERROR_MSG_ID 0x0001 +#define AUDPREPROC_MSG_ERROR_MSG_ID_LEN \ + sizeof(audpreproc_msg_error_msg_id) + +#define AUDPREPROC_MSG_ERR_INDEX_NS 0x0000 + +typedef struct { + unsigned short err_index; +} __attribute__((packed)) audpreproc_msg_error_msg_id; + +#endif diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5audreccmdi.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5audreccmdi.h new file mode 100644 index 0000000..d03ee02 --- /dev/null +++ b/drivers/staging/dream/include/mach/qdsp5/qdsp5audreccmdi.h @@ -0,0 +1,176 @@ +#ifndef QDSP5AUDRECCMDI_H +#define QDSP5AUDRECCMDI_H + +/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* + + A U D I O R E C O R D I N T E R N A L C O M M A N D S + +GENERAL DESCRIPTION + This file contains defintions of format blocks of commands + that are accepted by AUDREC Task + +REFERENCES + None + +EXTERNALIZED FUNCTIONS + None + +Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated. + +This software is licensed under the terms of the GNU General Public +License version 2, as published by the Free Software Foundation, and +may be copied, distributed, and modified under those terms. + +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. + +*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + +This section contains comments describing changes made to this file. +Notice that changes are listed in reverse chronological order. + + $Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audreccmdi.h#3 $ + +============================================================================*/ + +/* + * AUDRECTASK COMMANDS + * ARM uses 2 queues to communicate with the AUDRECTASK + * 1.uPAudRecCmdQueue + * Location :MEMC + * Buffer Size : 8 + * No of Buffers in a queue : 3 + * 2.audRecUpBitStreamQueue + * Location : MEMC + * Buffer Size : 4 + * No of buffers in a queue : 2 + */ + +/* + * Commands on uPAudRecCmdQueue + */ + +/* + * Command to initiate and terminate the audio recording section + */ + +#define AUDREC_CMD_CFG 0x0000 +#define AUDREC_CMD_CFG_LEN sizeof(audrec_cmd_cfg) + +#define AUDREC_CMD_TYPE_0_INDEX_WAV 0x0000 +#define AUDREC_CMD_TYPE_0_INDEX_AAC 0x0001 + +#define AUDREC_CMD_TYPE_0_ENA 0x4000 +#define AUDREC_CMD_TYPE_0_DIS 0x0000 + +#define AUDREC_CMD_TYPE_0_NOUPDATE 0x0000 +#define AUDREC_CMD_TYPE_0_UPDATE 0x8000 + +#define AUDREC_CMD_TYPE_1_INDEX_SBC 0x0002 + +#define AUDREC_CMD_TYPE_1_ENA 0x4000 +#define AUDREC_CMD_TYPE_1_DIS 0x0000 + +#define AUDREC_CMD_TYPE_1_NOUPDATE 0x0000 +#define AUDREC_CMD_TYPE_1_UPDATE 0x8000 + +typedef struct { + unsigned short cmd_id; + unsigned short type_0; + unsigned short type_1; +} __attribute__((packed)) audrec_cmd_cfg; + + +/* + * Command to configure the recording parameters for RecType0(AAC/WAV) encoder + */ + +#define AUDREC_CMD_AREC0PARAM_CFG 0x0001 +#define AUDREC_CMD_AREC0PARAM_CFG_LEN \ + sizeof(audrec_cmd_arec0param_cfg) + +#define AUDREC_CMD_SAMP_RATE_INDX_8000 0x000B +#define AUDREC_CMD_SAMP_RATE_INDX_11025 0x000A +#define AUDREC_CMD_SAMP_RATE_INDX_12000 0x0009 +#define AUDREC_CMD_SAMP_RATE_INDX_16000 0x0008 +#define AUDREC_CMD_SAMP_RATE_INDX_22050 0x0007 +#define AUDREC_CMD_SAMP_RATE_INDX_24000 0x0006 +#define AUDREC_CMD_SAMP_RATE_INDX_32000 0x0005 +#define AUDREC_CMD_SAMP_RATE_INDX_44100 0x0004 +#define AUDREC_CMD_SAMP_RATE_INDX_48000 0x0003 + +#define AUDREC_CMD_STEREO_MODE_MONO 0x0000 +#define AUDREC_CMD_STEREO_MODE_STEREO 0x0001 + +typedef struct { + unsigned short cmd_id; + unsigned short ptr_to_extpkt_buffer_msw; + unsigned short ptr_to_extpkt_buffer_lsw; + unsigned short buf_len; + unsigned short samp_rate_index; + unsigned short stereo_mode; + unsigned short rec_quality; +} __attribute__((packed)) audrec_cmd_arec0param_cfg; + +/* + * Command to configure the recording parameters for RecType1(SBC) encoder + */ + +#define AUDREC_CMD_AREC1PARAM_CFG 0x0002 +#define AUDREC_CMD_AREC1PARAM_CFG_LEN \ + sizeof(audrec_cmd_arec1param_cfg) + +#define AUDREC_CMD_PARAM_BUF_BLOCKS_4 0x0000 +#define AUDREC_CMD_PARAM_BUF_BLOCKS_8 0x0001 +#define AUDREC_CMD_PARAM_BUF_BLOCKS_12 0x0002 +#define AUDREC_CMD_PARAM_BUF_BLOCKS_16 0x0003 + +#define AUDREC_CMD_PARAM_BUF_SUB_BANDS_8 0x0010 +#define AUDREC_CMD_PARAM_BUF_MODE_MONO 0x0000 +#define AUDREC_CMD_PARAM_BUF_MODE_DUAL 0x0040 +#define AUDREC_CMD_PARAM_BUF_MODE_STEREO 0x0050 +#define AUDREC_CMD_PARAM_BUF_MODE_JSTEREO 0x0060 +#define AUDREC_CMD_PARAM_BUF_LOUDNESS 0x0000 +#define AUDREC_CMD_PARAM_BUF_SNR 0x0100 +#define AUDREC_CMD_PARAM_BUF_BASIC_VER 0x0000 + +typedef struct { + unsigned short cmd_id; + unsigned short ptr_to_extpkt_buffer_msw; + unsigned short ptr_to_extpkt_buffer_lsw; + unsigned short buf_len; + unsigned short param_buf; + unsigned short bit_rate_0; + unsigned short bit_rate_1; +} __attribute__((packed)) audrec_cmd_arec1param_cfg; + + +/* + * Commands on audRecUpBitStreamQueue + */ + +/* + * Command to indicate the current packet read count + */ + +#define AUDREC_CMD_PACKET_EXT_PTR 0x0000 +#define AUDREC_CMD_PACKET_EXT_PTR_LEN \ + sizeof(audrec_cmd_packet_ext_ptr) + +#define AUDREC_CMD_TYPE_0 0x0000 +#define AUDREC_CMD_TYPE_1 0x0001 + +typedef struct { + unsigned short cmd_id; + unsigned short type; + unsigned short curr_rec_count_msw; + unsigned short curr_rec_count_lsw; +} __attribute__((packed)) audrec_cmd_packet_ext_ptr; + +#endif diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5audrecmsg.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5audrecmsg.h new file mode 100644 index 0000000..bb6eb50 --- /dev/null +++ b/drivers/staging/dream/include/mach/qdsp5/qdsp5audrecmsg.h @@ -0,0 +1,127 @@ +#ifndef QDSP5AUDRECMSGI_H +#define QDSP5AUDRECMSGI_H + +/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* + + A U D I O R E C O R D M E S S A G E S + +GENERAL DESCRIPTION + This file contains defintions of format blocks of messages + that are sent by AUDREC Task + +REFERENCES + None + +EXTERNALIZED FUNCTIONS + None + +Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated. + +This software is licensed under the terms of the GNU General Public +License version 2, as published by the Free Software Foundation, and +may be copied, distributed, and modified under those terms. + +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. + +*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + +This section contains comments describing changes made to this file. +Notice that changes are listed in reverse chronological order. + + $Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audrecmsg.h#3 $ + +============================================================================*/ + +/* + * AUDRECTASK MESSAGES + * AUDRECTASK uses audRecUpRlist to communicate with ARM + * Location : MEMC + * Buffer size : 4 + * No of buffers in a queue : 2 + */ + +/* + * Message to notify that config command is done + */ + +#define AUDREC_MSG_CMD_CFG_DONE_MSG 0x0002 +#define AUDREC_MSG_CMD_CFG_DONE_MSG_LEN \ + sizeof(audrec_msg_cmd_cfg_done_msg) + + +#define AUDREC_MSG_CFG_DONE_TYPE_0_ENA 0x4000 +#define AUDREC_MSG_CFG_DONE_TYPE_0_DIS 0x0000 + +#define AUDREC_MSG_CFG_DONE_TYPE_0_NO_UPDATE 0x0000 +#define AUDREC_MSG_CFG_DONE_TYPE_0_UPDATE 0x8000 + +#define AUDREC_MSG_CFG_DONE_TYPE_1_ENA 0x4000 +#define AUDREC_MSG_CFG_DONE_TYPE_1_DIS 0x0000 + +#define AUDREC_MSG_CFG_DONE_TYPE_1_NO_UPDATE 0x0000 +#define AUDREC_MSG_CFG_DONE_TYPE_1_UPDATE 0x8000 + +typedef struct { + unsigned short type_0; + unsigned short type_1; +} __attribute__((packed))audrec_msg_cmd_cfg_done_msg; + + +/* + * Message to notify arec0/1 cfg done and recording params revd by task + */ + +#define AUDREC_MSG_CMD_AREC_PARAM_CFG_DONE_MSG 0x0003 +#define AUDREC_MSG_CMD_AREC_PARAM_CFG_DONE_MSG_LEN \ + sizeof(audrec_msg_cmd_arec_param_cfg_done_msg) + +#define AUDREC_MSG_AREC_PARAM_TYPE_0 0x0000 +#define AUDREC_MSG_AREC_PARAM_TYPE_1 0x0001 + +typedef struct { + unsigned short type; +} __attribute__((packed))audrec_msg_cmd_arec_param_cfg_done_msg; + + +/* + * Message to notify no more buffers are available in ext mem to DME + */ + +#define AUDREC_MSG_FATAL_ERR_MSG 0x0004 +#define AUDREC_MSG_FATAL_ERR_MSG_LEN \ + sizeof(audrec_msg_fatal_err_msg) + +#define AUDREC_MSG_FATAL_ERR_TYPE_0 0x0000 +#define AUDREC_MSG_FATAL_ERR_TYPE_1 0x0001 + +typedef struct { + unsigned short type; +} __attribute__((packed))audrec_msg_fatal_err_msg; + +/* + * Message to notify DME deliverd the encoded pkt to ext pkt buffer + */ + +#define AUDREC_MSG_PACKET_READY_MSG 0x0005 +#define AUDREC_MSG_PACKET_READY_MSG_LEN \ + sizeof(audrec_msg_packet_ready_msg) + +#define AUDREC_MSG_PACKET_READY_TYPE_0 0x0000 +#define AUDREC_MSG_PACKET_READY_TYPE_1 0x0001 + +typedef struct { + unsigned short type; + unsigned short pkt_counter_msw; + unsigned short pkt_counter_lsw; + unsigned short pkt_read_cnt_msw; + unsigned short pkt_read_cnt_lsw; +} __attribute__((packed))audrec_msg_packet_ready_msg; + +#endif diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5jpegcmdi.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5jpegcmdi.h new file mode 100644 index 0000000..574ad6b --- /dev/null +++ b/drivers/staging/dream/include/mach/qdsp5/qdsp5jpegcmdi.h @@ -0,0 +1,376 @@ +#ifndef QDSP5VIDJPEGCMDI_H +#define QDSP5VIDJPEGCMDI_H + +/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* + + J P E G I N T E R N A L C O M M A N D S + +GENERAL DESCRIPTION + This file contains defintions of format blocks of commands + that are accepted by JPEG Task + +REFERENCES + None + +EXTERNALIZED FUNCTIONS + None + +Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated. + +This software is licensed under the terms of the GNU General Public +License version 2, as published by the Free Software Foundation, and +may be copied, distributed, and modified under those terms. + +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. + +*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ +/*=========================================================================== + + EDIT HISTORY FOR FILE + +This section contains comments describing changes made to this file. +Notice that changes are listed in reverse chronological order. + +$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5jpegcmdi.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $ +Revision History: +when who what, where, why +-------- --- ---------------------------------------------------------- +06/09/08 sv initial version +===========================================================================*/ + +/* + * ARM to JPEG configuration commands are passed through the + * uPJpegCfgCmdQueue + */ + +/* + * Command to configure JPEG Encoder + */ + +#define JPEG_CMD_ENC_CFG 0x0000 +#define JPEG_CMD_ENC_CFG_LEN sizeof(jpeg_cmd_enc_cfg) + +#define JPEG_CMD_ENC_PROCESS_CFG_OP_ROTATION_0 0x0000 +#define JPEG_CMD_ENC_PROCESS_CFG_OP_ROTATION_90 0x0100 +#define JPEG_CMD_ENC_PROCESS_CFG_OP_ROTATION_180 0x0200 +#define JPEG_CMD_ENC_PROCESS_CFG_OP_ROTATION_270 0x0300 +#define JPEG_CMD_ENC_PROCESS_CFG_IP_DATA_FORMAT_M 0x0003 +#define JPEG_CMD_ENC_PROCESS_CFG_IP_DATA_FORMAT_H2V2 0x0000 +#define JPEG_CMD_ENC_PROCESS_CFG_IP_DATA_FORMAT_H2V1 0x0001 +#define JPEG_CMD_ENC_PROCESS_CFG_IP_DATA_FORMAT_H1V2 0x0002 + +#define JPEG_CMD_IP_SIZE_CFG_LUMA_HEIGHT_M 0x0000FFFF +#define JPEG_CMD_IP_SIZE_CFG_LUMA_WIDTH_M 0xFFFF0000 +#define JPEG_CMD_ENC_UPSAMP_IP_SIZE_CFG_ENA 0x0001 +#define JPEG_CMD_ENC_UPSAMP_IP_SIZE_CFG_DIS 0x0000 + +#define JPEG_CMD_FRAG_SIZE_LUMA_HEIGHT_M 0xFFFF + +typedef struct { + unsigned int cmd_id; + unsigned int process_cfg; + unsigned int ip_size_cfg; + unsigned int op_size_cfg; + unsigned int frag_cfg; + unsigned int frag_cfg_part[16]; + + unsigned int part_num; + + unsigned int op_buf_0_cfg_part1; + unsigned int op_buf_0_cfg_part2; + unsigned int op_buf_1_cfg_part1; + unsigned int op_buf_1_cfg_part2; + + unsigned int luma_qunt_table[32]; + unsigned int chroma_qunt_table[32]; + + unsigned int upsamp_ip_size_cfg; + unsigned int upsamp_ip_frame_off; + unsigned int upsamp_pp_filter_coeff[64]; +} __attribute__((packed)) jpeg_cmd_enc_cfg; + +/* + * Command to configure JPEG Decoder + */ + +#define JPEG_CMD_DEC_CFG 0x0001 +#define JPEG_CMD_DEC_CFG_LEN sizeof(jpeg_cmd_dec_cfg) + +#define JPEG_CMD_DEC_OP_DATA_FORMAT_M 0x0001 +#define JPEG_CMD_DEC_OP_DATA_FORMAT_H2V2 0x0000 +#define JPEG_CMD_DEC_OP_DATA_FORMAT_H2V1 0x0001 + +#define JPEG_CMD_DEC_OP_DATA_FORMAT_SCALE_FACTOR_8 0x000000 +#define JPEG_CMD_DEC_OP_DATA_FORMAT_SCALE_FACTOR_4 0x010000 +#define JPEG_CMD_DEC_OP_DATA_FORMAT_SCALE_FACTOR_2 0x020000 +#define JPEG_CMD_DEC_OP_DATA_FORMAT_SCALE_FACTOR_1 0x030000 + +#define JPEG_CMD_DEC_IP_STREAM_BUF_CFG_PART3_NOT_FINAL 0x0000 +#define JPEG_CMD_DEC_IP_STREAM_BUF_CFG_PART3_FINAL 0x0001 + + +typedef struct { + unsigned int cmd_id; + unsigned int img_dimension_cfg; + unsigned int op_data_format; + unsigned int restart_interval; + unsigned int ip_buf_partition_num; + unsigned int ip_stream_buf_cfg_part1; + unsigned int ip_stream_buf_cfg_part2; + unsigned int ip_stream_buf_cfg_part3; + unsigned int op_stream_buf_0_cfg_part1; + unsigned int op_stream_buf_0_cfg_part2; + unsigned int op_stream_buf_0_cfg_part3; + unsigned int op_stream_buf_1_cfg_part1; + unsigned int op_stream_buf_1_cfg_part2; + unsigned int op_stream_buf_1_cfg_part3; + unsigned int luma_qunt_table_0_3; + unsigned int luma_qunt_table_4_7; + unsigned int luma_qunt_table_8_11; + unsigned int luma_qunt_table_12_15; + unsigned int luma_qunt_table_16_19; + unsigned int luma_qunt_table_20_23; + unsigned int luma_qunt_table_24_27; + unsigned int luma_qunt_table_28_31; + unsigned int luma_qunt_table_32_35; + unsigned int luma_qunt_table_36_39; + unsigned int luma_qunt_table_40_43; + unsigned int luma_qunt_table_44_47; + unsigned int luma_qunt_table_48_51; + unsigned int luma_qunt_table_52_55; + unsigned int luma_qunt_table_56_59; + unsigned int luma_qunt_table_60_63; + unsigned int chroma_qunt_table_0_3; + unsigned int chroma_qunt_table_4_7; + unsigned int chroma_qunt_table_8_11; + unsigned int chroma_qunt_table_12_15; + unsigned int chroma_qunt_table_16_19; + unsigned int chroma_qunt_table_20_23; + unsigned int chroma_qunt_table_24_27; + unsigned int chroma_qunt_table_28_31; + unsigned int chroma_qunt_table_32_35; + unsigned int chroma_qunt_table_36_39; + unsigned int chroma_qunt_table_40_43; + unsigned int chroma_qunt_table_44_47; + unsigned int chroma_qunt_table_48_51; + unsigned int chroma_qunt_table_52_55; + unsigned int chroma_qunt_table_56_59; + unsigned int chroma_qunt_table_60_63; + unsigned int luma_dc_hm_code_cnt_table_0_3; + unsigned int luma_dc_hm_code_cnt_table_4_7; + unsigned int luma_dc_hm_code_cnt_table_8_11; + unsigned int luma_dc_hm_code_cnt_table_12_15; + unsigned int luma_dc_hm_code_val_table_0_3; + unsigned int luma_dc_hm_code_val_table_4_7; + unsigned int luma_dc_hm_code_val_table_8_11; + unsigned int chroma_dc_hm_code_cnt_table_0_3; + unsigned int chroma_dc_hm_code_cnt_table_4_7; + unsigned int chroma_dc_hm_code_cnt_table_8_11; + unsigned int chroma_dc_hm_code_cnt_table_12_15; + unsigned int chroma_dc_hm_code_val_table_0_3; + unsigned int chroma_dc_hm_code_val_table_4_7; + unsigned int chroma_dc_hm_code_val_table_8_11; + unsigned int luma_ac_hm_code_cnt_table_0_3; + unsigned int luma_ac_hm_code_cnt_table_4_7; + unsigned int luma_ac_hm_code_cnt_table_8_11; + unsigned int luma_ac_hm_code_cnt_table_12_15; + unsigned int luma_ac_hm_code_val_table_0_3; + unsigned int luma_ac_hm_code_val_table_4_7; + unsigned int luma_ac_hm_code_val_table_8_11; + unsigned int luma_ac_hm_code_val_table_12_15; + unsigned int luma_ac_hm_code_val_table_16_19; + unsigned int luma_ac_hm_code_val_table_20_23; + unsigned int luma_ac_hm_code_val_table_24_27; + unsigned int luma_ac_hm_code_val_table_28_31; + unsigned int luma_ac_hm_code_val_table_32_35; + unsigned int luma_ac_hm_code_val_table_36_39; + unsigned int luma_ac_hm_code_val_table_40_43; + unsigned int luma_ac_hm_code_val_table_44_47; + unsigned int luma_ac_hm_code_val_table_48_51; + unsigned int luma_ac_hm_code_val_table_52_55; + unsigned int luma_ac_hm_code_val_table_56_59; + unsigned int luma_ac_hm_code_val_table_60_63; + unsigned int luma_ac_hm_code_val_table_64_67; + unsigned int luma_ac_hm_code_val_table_68_71; + unsigned int luma_ac_hm_code_val_table_72_75; + unsigned int luma_ac_hm_code_val_table_76_79; + unsigned int luma_ac_hm_code_val_table_80_83; + unsigned int luma_ac_hm_code_val_table_84_87; + unsigned int luma_ac_hm_code_val_table_88_91; + unsigned int luma_ac_hm_code_val_table_92_95; + unsigned int luma_ac_hm_code_val_table_96_99; + unsigned int luma_ac_hm_code_val_table_100_103; + unsigned int luma_ac_hm_code_val_table_104_107; + unsigned int luma_ac_hm_code_val_table_108_111; + unsigned int luma_ac_hm_code_val_table_112_115; + unsigned int luma_ac_hm_code_val_table_116_119; + unsigned int luma_ac_hm_code_val_table_120_123; + unsigned int luma_ac_hm_code_val_table_124_127; + unsigned int luma_ac_hm_code_val_table_128_131; + unsigned int luma_ac_hm_code_val_table_132_135; + unsigned int luma_ac_hm_code_val_table_136_139; + unsigned int luma_ac_hm_code_val_table_140_143; + unsigned int luma_ac_hm_code_val_table_144_147; + unsigned int luma_ac_hm_code_val_table_148_151; + unsigned int luma_ac_hm_code_val_table_152_155; + unsigned int luma_ac_hm_code_val_table_156_159; + unsigned int luma_ac_hm_code_val_table_160_161; + unsigned int chroma_ac_hm_code_cnt_table_0_3; + unsigned int chroma_ac_hm_code_cnt_table_4_7; + unsigned int chroma_ac_hm_code_cnt_table_8_11; + unsigned int chroma_ac_hm_code_cnt_table_12_15; + unsigned int chroma_ac_hm_code_val_table_0_3; + unsigned int chroma_ac_hm_code_val_table_4_7; + unsigned int chroma_ac_hm_code_val_table_8_11; + unsigned int chroma_ac_hm_code_val_table_12_15; + unsigned int chroma_ac_hm_code_val_table_16_19; + unsigned int chroma_ac_hm_code_val_table_20_23; + unsigned int chroma_ac_hm_code_val_table_24_27; + unsigned int chroma_ac_hm_code_val_table_28_31; + unsigned int chroma_ac_hm_code_val_table_32_35; + unsigned int chroma_ac_hm_code_val_table_36_39; + unsigned int chroma_ac_hm_code_val_table_40_43; + unsigned int chroma_ac_hm_code_val_table_44_47; + unsigned int chroma_ac_hm_code_val_table_48_51; + unsigned int chroma_ac_hm_code_val_table_52_55; + unsigned int chroma_ac_hm_code_val_table_56_59; + unsigned int chroma_ac_hm_code_val_table_60_63; + unsigned int chroma_ac_hm_code_val_table_64_67; + unsigned int chroma_ac_hm_code_val_table_68_71; + unsigned int chroma_ac_hm_code_val_table_72_75; + unsigned int chroma_ac_hm_code_val_table_76_79; + unsigned int chroma_ac_hm_code_val_table_80_83; + unsigned int chroma_ac_hm_code_val_table_84_87; + unsigned int chroma_ac_hm_code_val_table_88_91; + unsigned int chroma_ac_hm_code_val_table_92_95; + unsigned int chroma_ac_hm_code_val_table_96_99; + unsigned int chroma_ac_hm_code_val_table_100_103; + unsigned int chroma_ac_hm_code_val_table_104_107; + unsigned int chroma_ac_hm_code_val_table_108_111; + unsigned int chroma_ac_hm_code_val_table_112_115; + unsigned int chroma_ac_hm_code_val_table_116_119; + unsigned int chroma_ac_hm_code_val_table_120_123; + unsigned int chroma_ac_hm_code_val_table_124_127; + unsigned int chroma_ac_hm_code_val_table_128_131; + unsigned int chroma_ac_hm_code_val_table_132_135; + unsigned int chroma_ac_hm_code_val_table_136_139; + unsigned int chroma_ac_hm_code_val_table_140_143; + unsigned int chroma_ac_hm_code_val_table_144_147; + unsigned int chroma_ac_hm_code_val_table_148_151; + unsigned int chroma_ac_hm_code_val_table_152_155; + unsigned int chroma_ac_hm_code_val_table_156_159; + unsigned int chroma_ac_hm_code_val_table_160_161; +} __attribute__((packed)) jpeg_cmd_dec_cfg; + + +/* + * ARM to JPEG configuration commands are passed through the + * uPJpegActionCmdQueue + */ + +/* + * Command to start the encode process + */ + +#define JPEG_CMD_ENC_ENCODE 0x0000 +#define JPEG_CMD_ENC_ENCODE_LEN sizeof(jpeg_cmd_enc_encode) + + +typedef struct { + unsigned short cmd_id; +} __attribute__((packed)) jpeg_cmd_enc_encode; + + +/* + * Command to transition from current state of encoder to IDLE state + */ + +#define JPEG_CMD_ENC_IDLE 0x0001 +#define JPEG_CMD_ENC_IDLE_LEN sizeof(jpeg_cmd_enc_idle) + + +typedef struct { + unsigned short cmd_id; +} __attribute__((packed)) jpeg_cmd_enc_idle; + + +/* + * Command to inform the encoder that another buffer is ready + */ + +#define JPEG_CMD_ENC_OP_CONSUMED 0x0002 +#define JPEG_CMD_ENC_OP_CONSUMED_LEN sizeof(jpeg_cmd_enc_op_consumed) + + +typedef struct { + unsigned int cmd_id; + unsigned int op_buf_addr; + unsigned int op_buf_size; +} __attribute__((packed)) jpeg_cmd_enc_op_consumed; + + +/* + * Command to start the decoding process + */ + +#define JPEG_CMD_DEC_DECODE 0x0003 +#define JPEG_CMD_DEC_DECODE_LEN sizeof(jpeg_cmd_dec_decode) + + +typedef struct { + unsigned short cmd_id; +} __attribute__((packed)) jpeg_cmd_dec_decode; + + +/* + * Command to transition from the current state of decoder to IDLE + */ + +#define JPEG_CMD_DEC_IDLE 0x0004 +#define JPEG_CMD_DEC_IDLE_LEN sizeof(jpeg_cmd_dec_idle) + + +typedef struct { + unsigned short cmd_id; +} __attribute__((packed)) jpeg_cmd_dec_idle; + + +/* + * Command to inform that an op buffer is ready for use + */ + +#define JPEG_CMD_DEC_OP_CONSUMED 0x0005 +#define JPEG_CMD_DEC_OP_CONSUMED_LEN sizeof(jpeg_cmd_dec_op_consumed) + + +typedef struct { + unsigned int cmd_id; + unsigned int luma_op_buf_addr; + unsigned int luma_op_buf_size; + unsigned int chroma_op_buf_addr; +} __attribute__((packed)) jpeg_cmd_dec_op_consumed; + + +/* + * Command to pass a new ip buffer to the jpeg decoder + */ + +#define JPEG_CMD_DEC_IP 0x0006 +#define JPEG_CMD_DEC_IP_LEN sizeof(jpeg_cmd_dec_ip_len) + +#define JPEG_CMD_EOI_INDICATOR_NOT_END 0x0000 +#define JPEG_CMD_EOI_INDICATOR_END 0x0001 + +typedef struct { + unsigned int cmd_id; + unsigned int ip_buf_addr; + unsigned int ip_buf_size; + unsigned int eoi_indicator; +} __attribute__((packed)) jpeg_cmd_dec_ip; + + + +#endif diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5jpegmsg.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5jpegmsg.h new file mode 100644 index 0000000..d11aa3f --- /dev/null +++ b/drivers/staging/dream/include/mach/qdsp5/qdsp5jpegmsg.h @@ -0,0 +1,177 @@ +#ifndef QDSP5VIDJPEGMSGI_H +#define QDSP5VIDJPEGMSGI_H + +/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* + + J P E G I N T E R N A L M E S S A G E S + +GENERAL DESCRIPTION + This file contains defintions of format blocks of messages + that are sent by JPEG Task + +REFERENCES + None + +EXTERNALIZED FUNCTIONS + None + +Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated. + +This software is licensed under the terms of the GNU General Public +License version 2, as published by the Free Software Foundation, and +may be copied, distributed, and modified under those terms. + +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. + +*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ +/*=========================================================================== + + EDIT HISTORY FOR FILE + +This section contains comments describing changes made to this file. +Notice that changes are listed in reverse chronological order. + +$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5jpegmsg.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $ +Revision History: + +when who what, where, why +-------- --- ---------------------------------------------------------- +05/10/08 sv initial version +===========================================================================*/ + +/* + * Messages from JPEG task to ARM through jpeguPMsgQueue + */ + +/* + * Message is ACK for CMD_JPEGE_ENCODE cmd + */ + +#define JPEG_MSG_ENC_ENCODE_ACK 0x0000 +#define JPEG_MSG_ENC_ENCODE_ACK_LEN \ + sizeof(jpeg_msg_enc_encode_ack) + +typedef struct { +} __attribute__((packed)) jpeg_msg_enc_encode_ack; + + +/* + * Message informs the up when op buffer is ready for consumption and + * when encoding is complete or errors + */ + +#define JPEG_MSG_ENC_OP_PRODUCED 0x0001 +#define JPEG_MSG_ENC_OP_PRODUCED_LEN \ + sizeof(jpeg_msg_enc_op_produced) + +#define JPEG_MSGOP_OP_BUF_STATUS_ENC_DONE_PROGRESS 0x0000 +#define JPEG_MSGOP_OP_BUF_STATUS_ENC_DONE_COMPLETE 0x0001 +#define JPEG_MSGOP_OP_BUF_STATUS_ENC_ERR 0x10000 + +typedef struct { + unsigned int op_buf_addr; + unsigned int op_buf_size; + unsigned int op_buf_status; +} __attribute__((packed)) jpeg_msg_enc_op_produced; + + +/* + * Message to ack CMD_JPEGE_IDLE + */ + +#define JPEG_MSG_ENC_IDLE_ACK 0x0002 +#define JPEG_MSG_ENC_IDLE_ACK_LEN sizeof(jpeg_msg_enc_idle_ack) + + +typedef struct { +} __attribute__ ((packed)) jpeg_msg_enc_idle_ack; + + +/* + * Message to indicate the illegal command + */ + +#define JPEG_MSG_ENC_ILLEGAL_COMMAND 0x0003 +#define JPEG_MSG_ENC_ILLEGAL_COMMAND_LEN \ + sizeof(jpeg_msg_enc_illegal_command) + +typedef struct { + unsigned int status; +} __attribute__((packed)) jpeg_msg_enc_illegal_command; + + +/* + * Message to ACK CMD_JPEGD_DECODE + */ + +#define JPEG_MSG_DEC_DECODE_ACK 0x0004 +#define JPEG_MSG_DEC_DECODE_ACK_LEN \ + sizeof(jpeg_msg_dec_decode_ack) + + +typedef struct { +} __attribute__((packed)) jpeg_msg_dec_decode_ack; + + +/* + * Message to inform up that an op buffer is ready for consumption and when + * decoding is complete or an error occurs + */ + +#define JPEG_MSG_DEC_OP_PRODUCED 0x0005 +#define JPEG_MSG_DEC_OP_PRODUCED_LEN \ + sizeof(jpeg_msg_dec_op_produced) + +#define JPEG_MSG_DEC_OP_BUF_STATUS_PROGRESS 0x0000 +#define JPEG_MSG_DEC_OP_BUF_STATUS_DONE 0x0001 + +typedef struct { + unsigned int luma_op_buf_addr; + unsigned int chroma_op_buf_addr; + unsigned int num_mcus; + unsigned int op_buf_status; +} __attribute__((packed)) jpeg_msg_dec_op_produced; + +/* + * Message to ack CMD_JPEGD_IDLE cmd + */ + +#define JPEG_MSG_DEC_IDLE_ACK 0x0006 +#define JPEG_MSG_DEC_IDLE_ACK_LEN sizeof(jpeg_msg_dec_idle_ack) + + +typedef struct { +} __attribute__((packed)) jpeg_msg_dec_idle_ack; + + +/* + * Message to indicate illegal cmd was received + */ + +#define JPEG_MSG_DEC_ILLEGAL_COMMAND 0x0007 +#define JPEG_MSG_DEC_ILLEGAL_COMMAND_LEN \ + sizeof(jpeg_msg_dec_illegal_command) + + +typedef struct { + unsigned int status; +} __attribute__((packed)) jpeg_msg_dec_illegal_command; + +/* + * Message to request up for the next segment of ip bit stream + */ + +#define JPEG_MSG_DEC_IP_REQUEST 0x0008 +#define JPEG_MSG_DEC_IP_REQUEST_LEN \ + sizeof(jpeg_msg_dec_ip_request) + + +typedef struct { +} __attribute__((packed)) jpeg_msg_dec_ip_request; + + + +#endif diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5lpmcmdi.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5lpmcmdi.h new file mode 100644 index 0000000..6c76e2c --- /dev/null +++ b/drivers/staging/dream/include/mach/qdsp5/qdsp5lpmcmdi.h @@ -0,0 +1,82 @@ +#ifndef QDSP5LPMCMDI_H +#define QDSP5LPMCMDI_H + +/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* + + L P M I N T E R N A L C O M M A N D S + +GENERAL DESCRIPTION + This file contains defintions of format blocks of commands + that are accepted by LPM Task + +REFERENCES + None + +EXTERNALIZED FUNCTIONS + None + +Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated. + +This software is licensed under the terms of the GNU General Public +License version 2, as published by the Free Software Foundation, and +may be copied, distributed, and modified under those terms. + +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. + +*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ +/*=========================================================================== + + EDIT HISTORY FOR FILE + +This section contains comments describing changes made to this file. +Notice that changes are listed in reverse chronological order. + + +$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5lpmcmdi.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $ +Revision History: + +when who what, where, why +-------- --- ---------------------------------------------------------- +06/12/08 sv initial version +===========================================================================*/ + + +/* + * Command to start LPM processing based on the config params + */ + +#define LPM_CMD_START 0x0000 +#define LPM_CMD_START_LEN sizeof(lpm_cmd_start) + +#define LPM_CMD_SPATIAL_FILTER_PART_OPMODE_0 0x00000000 +#define LPM_CMD_SPATIAL_FILTER_PART_OPMODE_1 0x00010000 +typedef struct { + unsigned int cmd_id; + unsigned int ip_data_cfg_part1; + unsigned int ip_data_cfg_part2; + unsigned int ip_data_cfg_part3; + unsigned int ip_data_cfg_part4; + unsigned int op_data_cfg_part1; + unsigned int op_data_cfg_part2; + unsigned int op_data_cfg_part3; + unsigned int spatial_filter_part[32]; +} __attribute__((packed)) lpm_cmd_start; + + + +/* + * Command to stop LPM processing + */ + +#define LPM_CMD_IDLE 0x0001 +#define LPM_CMD_IDLE_LEN sizeof(lpm_cmd_idle) + +typedef struct { + unsigned int cmd_id; +} __attribute__((packed)) lpm_cmd_idle; + + +#endif diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5lpmmsg.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5lpmmsg.h new file mode 100644 index 0000000..3d1039d --- /dev/null +++ b/drivers/staging/dream/include/mach/qdsp5/qdsp5lpmmsg.h @@ -0,0 +1,80 @@ +#ifndef QDSP5LPMMSGI_H +#define QDSP5LPMMSGI_H + +/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* + + L P M I N T E R N A L M E S S A G E S + +GENERAL DESCRIPTION + This file contains defintions of format blocks of commands + that are accepted by LPM Task + +REFERENCES + None + +EXTERNALIZED FUNCTIONS + None + +Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated. + +This software is licensed under the terms of the GNU General Public +License version 2, as published by the Free Software Foundation, and +may be copied, distributed, and modified under those terms. + +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. + +*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ +/*=========================================================================== + + EDIT HISTORY FOR FILE + +This section contains comments describing changes made to this file. +Notice that changes are listed in reverse chronological order. + +$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5lpmmsg.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $ +Revision History: + +when who what, where, why +-------- --- ---------------------------------------------------------- +06/12/08 sv initial version +===========================================================================*/ + +/* + * Message to acknowledge CMD_LPM_IDLE command + */ + +#define LPM_MSG_IDLE_ACK 0x0000 +#define LPM_MSG_IDLE_ACK_LEN sizeof(lpm_msg_idle_ack) + +typedef struct { +} __attribute__((packed)) lpm_msg_idle_ack; + + +/* + * Message to acknowledge CMD_LPM_START command + */ + + +#define LPM_MSG_START_ACK 0x0001 +#define LPM_MSG_START_ACK_LEN sizeof(lpm_msg_start_ack) + + +typedef struct { +} __attribute__((packed)) lpm_msg_start_ack; + + +/* + * Message to notify the ARM that LPM processing is complete + */ + +#define LPM_MSG_DONE 0x0002 +#define LPM_MSG_DONE_LEN sizeof(lpm_msg_done) + +typedef struct { +} __attribute__((packed)) lpm_msg_done; + + +#endif diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5vdeccmdi.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5vdeccmdi.h new file mode 100644 index 0000000..3a32ee9 --- /dev/null +++ b/drivers/staging/dream/include/mach/qdsp5/qdsp5vdeccmdi.h @@ -0,0 +1,235 @@ +#ifndef QDSP5VIDDECCMDI_H +#define QDSP5VIDDECCMDI_H + +/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* + + V I D E O D E C O D E R I N T E R N A L C O M M A N D S + +GENERAL DESCRIPTION + This file contains defintions of format blocks of commands + that are accepted by VIDDEC Task + +REFERENCES + None + +EXTERNALIZED FUNCTIONS + None + +Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated. + +This software is licensed under the terms of the GNU General Public +License version 2, as published by the Free Software Foundation, and +may be copied, distributed, and modified under those terms. + +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. + +*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ +/*=========================================================================== + + EDIT HISTORY FOR FILE + +This section contains comments describing changes made to this file. +Notice that changes are listed in reverse chronological order. + +$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5vdeccmdi.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $ +Revision History: + +when who what, where, why +-------- --- ---------------------------------------------------------- +05/10/08 ac initial version +===========================================================================*/ + + +/* + * Command to inform VIDDEC that new subframe packet is ready + */ + +#define VIDDEC_CMD_SUBFRAME_PKT 0x0000 +#define VIDDEC_CMD_SUBFRAME_PKT_LEN \ + sizeof(viddec_cmd_subframe_pkt) + +#define VIDDEC_CMD_SF_INFO_1_DM_DMA_STATS_EXCHANGE_FLAG_DM 0x0000 +#define VIDDEC_CMD_SF_INFO_1_DM_DMA_STATS_EXCHANGE_FLAG_DMA 0x0001 + +#define VIDDEC_CMD_SF_INFO_0_SUBFRAME_CONTI 0x0000 +#define VIDDEC_CMD_SF_INFO_0_SUBFRAME_FIRST 0x0001 +#define VIDDEC_CMD_SF_INFO_0_SUBFRAME_LAST 0x0002 +#define VIDDEC_CMD_SF_INFO_0_SUBFRAME_FIRST_AND_LAST 0x0003 + +#define VIDDEC_CMD_CODEC_SELECTION_WORD_MPEG_4 0x0000 +#define VIDDEC_CMD_CODEC_SELECTION_WORD_H_263_P0 0x0001 +#define VIDDEC_CMD_CODEC_SELECTION_WORD_H_264 0x0002 +#define VIDDEC_CMD_CODEC_SELECTION_WORD_H_263_p3 0x0003 +#define VIDDEC_CMD_CODEC_SELECTION_WORD_RV9 0x0004 +#define VIDDEC_CMD_CODEC_SELECTION_WORD_WMV9 0x0005 +#define VIDDEC_CMD_CODEC_SELECTION_WORD_SMCDB 0x0006 +#define VIDDEC_CMD_CODEC_SELECTION_WORD_QFRE 0x0007 +#define VIDDEC_CMD_CODEC_SELECTION_WORD_VLD 0x0008 + +typedef struct { + unsigned short cmd_id; + unsigned short packet_seq_number; + unsigned short codec_instance_id; + unsigned short subframe_packet_size_high; + unsigned short subframe_packet_size_low; + unsigned short subframe_packet_high; + unsigned short subframe_packet_low; + unsigned short subframe_packet_partition; + unsigned short statistics_packet_size_high; + unsigned short statistics_packet_size_low; + unsigned short statistics_packet_high; + unsigned short statistics_packet_low; + unsigned short statistics_partition; + unsigned short subframe_info_1; + unsigned short subframe_info_0; + unsigned short codec_selection_word; + unsigned short num_mbs; +} __attribute__((packed)) viddec_cmd_subframe_pkt; + + +/* + * Command to inform VIDDEC task that post processing is required for the frame + */ + +#define VIDDEC_CMD_PP_ENABLE 0x0001 +#define VIDDEC_CMD_PP_ENABLE_LEN \ + sizeof(viddec_cmd_pp_enable) + +#define VIDDEC_CMD_PP_INFO_0_DM_DMA_LS_EXCHANGE_FLAG_DM 0x0000 +#define VIDDEC_CMD_PP_INFO_0_DM_DMA_LS_EXCHANGE_FLAG_DMA 0x0001 + +typedef struct { + unsigned short cmd_id; + unsigned short packet_seq_num; + unsigned short codec_instance_id; + unsigned short postproc_info_0; + unsigned short codec_selection_word; + unsigned short pp_output_addr_high; + unsigned short pp_output_addr_low; + unsigned short postproc_info_1; + unsigned short load_sharing_packet_size_high; + unsigned short load_sharing_packet_size_low; + unsigned short load_sharing_packet_high; + unsigned short load_sharing_packet_low; + unsigned short load_sharing_partition; + unsigned short pp_param_0; + unsigned short pp_param_1; + unsigned short pp_param_2; + unsigned short pp_param_3; +} __attribute__((packed)) viddec_cmd_pp_enable; + + +/* + * FRAME Header Packet : It is at the start of new frame + */ + +#define VIDDEC_CMD_FRAME_HEADER_PACKET 0x0002 +#define VIDDEC_CMD_FRAME_HEADER_PACKET_LEN \ + sizeof(viddec_cmd_frame_header_packet) + +#define VIDDEC_CMD_FRAME_INFO_0_ERROR_SKIP 0x0000 +#define VIDDEC_CMD_FRAME_INFO_0_ERROR_BLACK 0x0800 + +typedef struct { + unsigned short packet_id; + unsigned short x_dimension; + unsigned short y_dimension; + unsigned short line_width; + unsigned short frame_info_0; + unsigned short frame_buffer_0_high; + unsigned short frame_buffer_0_low; + unsigned short frame_buffer_1_high; + unsigned short frame_buffer_1_low; + unsigned short frame_buffer_2_high; + unsigned short frame_buffer_2_low; + unsigned short frame_buffer_3_high; + unsigned short frame_buffer_3_low; + unsigned short frame_buffer_4_high; + unsigned short frame_buffer_4_low; + unsigned short frame_buffer_5_high; + unsigned short frame_buffer_5_low; + unsigned short frame_buffer_6_high; + unsigned short frame_buffer_6_low; + unsigned short frame_buffer_7_high; + unsigned short frame_buffer_7_low; + unsigned short frame_buffer_8_high; + unsigned short frame_buffer_8_low; + unsigned short frame_buffer_9_high; + unsigned short frame_buffer_9_low; + unsigned short frame_buffer_10_high; + unsigned short frame_buffer_10_low; + unsigned short frame_buffer_11_high; + unsigned short frame_buffer_11_low; + unsigned short frame_buffer_12_high; + unsigned short frame_buffer_12_low; + unsigned short frame_buffer_13_high; + unsigned short frame_buffer_13_low; + unsigned short frame_buffer_14_high; + unsigned short frame_buffer_14_low; + unsigned short frame_buffer_15_high; + unsigned short frame_buffer_15_low; + unsigned short output_frame_buffer_high; + unsigned short output_frame_buffer_low; + unsigned short end_of_packet_marker; +} __attribute__((packed)) viddec_cmd_frame_header_packet; + + +/* + * SLICE HEADER PACKET + * I-Slice and P-Slice + */ + +#define VIDDEC_CMD_SLICE_HEADER_PKT_ISLICE 0x0003 +#define VIDDEC_CMD_SLICE_HEADER_PKT_ISLICE_LEN \ + sizeof(viddec_cmd_slice_header_pkt_islice) + +#define VIDDEC_CMD_ISLICE_INFO_1_MOD_SLICE_TYPE_PSLICE 0x0000 +#define VIDDEC_CMD_ISLICE_INFO_1_MOD_SLICE_TYPE_BSLICE 0x0100 +#define VIDDEC_CMD_ISLICE_INFO_1_MOD_SLICE_TYPE_ISLICE 0x0200 +#define VIDDEC_CMD_ISLICE_INFO_1_MOD_SLICE_TYPE_SPSLICE 0x0300 +#define VIDDEC_CMD_ISLICE_INFO_1_MOD_SLICE_TYPE_SISLICE 0x0400 +#define VIDDEC_CMD_ISLICE_INFO_1_NOPADDING 0x0000 +#define VIDDEC_CMD_ISLICE_INFO_1_PADDING 0x0800 + +#define VIDDEC_CMD_ISLICE_EOP_MARKER 0x7FFF + +typedef struct { + unsigned short cmd_id; + unsigned short packet_id; + unsigned short slice_info_0; + unsigned short slice_info_1; + unsigned short slice_info_2; + unsigned short num_bytes_in_rbsp_high; + unsigned short num_bytes_in_rbsp_low; + unsigned short num_bytes_in_rbsp_consumed; + unsigned short end_of_packet_marker; +} __attribute__((packed)) viddec_cmd_slice_header_pkt_islice; + + +#define VIDDEC_CMD_SLICE_HEADER_PKT_PSLICE 0x0003 +#define VIDDEC_CMD_SLICE_HEADER_PKT_PSLICE_LEN \ + sizeof(viddec_cmd_slice_header_pkt_pslice) + + +typedef struct { + unsigned short cmd_id; + unsigned short packet_id; + unsigned short slice_info_0; + unsigned short slice_info_1; + unsigned short slice_info_2; + unsigned short slice_info_3; + unsigned short refidx_l0_map_tab_info_0; + unsigned short refidx_l0_map_tab_info_1; + unsigned short refidx_l0_map_tab_info_2; + unsigned short refidx_l0_map_tab_info_3; + unsigned short num_bytes_in_rbsp_high; + unsigned short num_bytes_in_rbsp_low; + unsigned short num_bytes_in_rbsp_consumed; + unsigned short end_of_packet_marker; +} __attribute__((packed)) viddec_cmd_slice_header_pkt_pslice; + + +#endif diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5vdecmsg.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5vdecmsg.h new file mode 100644 index 0000000..c1744c1 --- /dev/null +++ b/drivers/staging/dream/include/mach/qdsp5/qdsp5vdecmsg.h @@ -0,0 +1,107 @@ +#ifndef QDSP5VIDDECMSGI_H +#define QDSP5VIDDECMSGI_H + +/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* + + V I D E O D E C O D E R I N T E R N A L M E S S A G E S + +GENERAL DESCRIPTION + This file contains defintions of format blocks of messages + that are sent by VIDDEC Task + +REFERENCES + None + +EXTERNALIZED FUNCTIONS + None + +Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated. + +This software is licensed under the terms of the GNU General Public +License version 2, as published by the Free Software Foundation, and +may be copied, distributed, and modified under those terms. + +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. + +*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ +/*=========================================================================== + + EDIT HISTORY FOR FILE + +This section contains comments describing changes made to this file. +Notice that changes are listed in reverse chronological order. + +$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5vdecmsg.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $ +Revision History: + +when who what, where, why +-------- --- ---------------------------------------------------------- +05/10/08 ac initial version +===========================================================================*/ + +/* + * Message to inform ARM which VDEC_SUBFRAME_PKT_CMD processed by VIDDEC TASK + */ + +#define VIDDEC_MSG_SUBF_DONE 0x0000 +#define VIDDEC_MSG_SUBF_DONE_LEN \ + sizeof(viddec_msg_subf_done) + +typedef struct { + unsigned short packet_seq_number; + unsigned short codec_instance_id; +} __attribute__((packed)) viddec_msg_subf_done; + + +/* + * Message to inform ARM one frame has been decoded + */ + +#define VIDDEC_MSG_FRAME_DONE 0x0001 +#define VIDDEC_MSG_FRAME_DONE_LEN \ + sizeof(viddec_msg_frame_done) + +typedef struct { + unsigned short packet_seq_number; + unsigned short codec_instance_id; +} __attribute__((packed)) viddec_msg_frame_done; + + +/* + * Message to inform ARM that post processing frame has been decoded + */ + +#define VIDDEC_MSG_PP_ENABLE_CMD_DONE 0x0002 +#define VIDDEC_MSG_PP_ENABLE_CMD_DONE_LEN \ + sizeof(viddec_msg_pp_enable_cmd_done) + +typedef struct { + unsigned short packet_seq_number; + unsigned short codec_instance_id; +} __attribute__((packed)) viddec_msg_pp_enable_cmd_done; + + +/* + * Message to inform ARM that one post processing frame has been decoded + */ + + +#define VIDDEC_MSG_PP_FRAME_DONE 0x0003 +#define VIDDEC_MSG_PP_FRAME_DONE_LEN \ + sizeof(viddec_msg_pp_frame_done) + +#define VIDDEC_MSG_DISP_WORTHY_DISP 0x0000 +#define VIDDEC_MSG_DISP_WORTHY_DISP_NONE 0xFFFF + + +typedef struct { + unsigned short packet_seq_number; + unsigned short codec_instance_id; + unsigned short display_worthy; +} __attribute__((packed)) viddec_msg_pp_frame_done; + + +#endif diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5venccmdi.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5venccmdi.h new file mode 100644 index 0000000..819544d --- /dev/null +++ b/drivers/staging/dream/include/mach/qdsp5/qdsp5venccmdi.h @@ -0,0 +1,212 @@ +#ifndef QDSP5VIDENCCMDI_H +#define QDSP5VIDENCCMDI_H + +/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* + + V I D E O E N C O D E R I N T E R N A L C O M M A N D S + +GENERAL DESCRIPTION + This file contains defintions of format blocks of commands + that are accepted by VIDENC Task + +REFERENCES + None + +EXTERNALIZED FUNCTIONS + None + +Copyright(c) 2008 by QUALCOMM, Incorporated. +*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ +/*=========================================================================== + + EDIT HISTORY FOR FILE + +This section contains comments describing changes made to this file. +Notice that changes are listed in reverse chronological order. + +Revision History: + +when who what, where, why +-------- --- ---------------------------------------------------------- +09/25/08 umeshp initial version +===========================================================================*/ + + #define VIDENC_CMD_CFG 0x0000 + #define VIDENC_CMD_ACTIVE 0x0001 + #define VIDENC_CMD_IDLE 0x0002 + #define VIDENC_CMD_FRAME_START 0x0003 + #define VIDENC_CMD_STATUS_QUERY 0x0004 + #define VIDENC_CMD_RC_CFG 0x0005 + #define VIDENC_CMD_DIS_CFG 0x0006 + #define VIDENC_CMD_DIS 0x0007 + #define VIDENC_CMD_INTRA_REFRESH 0x0008 + #define VIDENC_CMD_DIGITAL_ZOOM 0x0009 + + +/* + * Command to pass the frame message information to VIDENC + */ + + +#define VIDENC_CMD_FRAME_START_LEN \ + sizeof(videnc_cmd_frame_start) + +typedef struct { + unsigned short cmd_id; + unsigned short frame_info; + unsigned short frame_rho_budget_word_high; + unsigned short frame_rho_budget_word_low; + unsigned short input_luma_addr_high; + unsigned short input_luma_addr_low; + unsigned short input_chroma_addr_high; + unsigned short input_chroma_addr_low; + unsigned short ref_vop_buf_ptr_high; + unsigned short ref_vop_buf_ptr_low; + unsigned short enc_pkt_buf_ptr_high; + unsigned short enc_pkt_buf_ptr_low; + unsigned short enc_pkt_buf_size_high; + unsigned short enc_pkt_buf_size_low; + unsigned short unfilt_recon_vop_buf_ptr_high; + unsigned short unfilt_recon_vop_buf_ptr_low; + unsigned short filt_recon_vop_buf_ptr_high; + unsigned short filt_recon_vop_buf_ptr_low; +} __attribute__((packed)) videnc_cmd_frame_start; + +/* + * Command to pass the frame-level digital stabilization parameters to VIDENC + */ + + +#define VIDENC_CMD_DIS_LEN \ + sizeof(videnc_cmd_dis) + +typedef struct { + unsigned short cmd_id; + unsigned short vfe_out_prev_luma_addr_high; + unsigned short vfe_out_prev_luma_addr_low; + unsigned short stabilization_info; +} __attribute__((packed)) videnc_cmd_dis; + +/* + * Command to pass the codec related parameters to VIDENC + */ + + +#define VIDENC_CMD_CFG_LEN \ + sizeof(videnc_cmd_cfg) + +typedef struct { + unsigned short cmd_id; + unsigned short cfg_info_0; + unsigned short cfg_info_1; + unsigned short four_mv_threshold; + unsigned short ise_fse_mv_cost_fac; + unsigned short venc_frame_dim; + unsigned short venc_DM_partition; +} __attribute__((packed)) videnc_cmd_cfg; + +/* + * Command to start the video encoding + */ + + +#define VIDENC_CMD_ACTIVE_LEN \ + sizeof(videnc_cmd_active) + +typedef struct { + unsigned short cmd_id; +} __attribute__((packed)) videnc_cmd_active; + +/* + * Command to stop the video encoding + */ + + +#define VIDENC_CMD_IDLE_LEN \ + sizeof(videnc_cmd_idle) + +typedef struct { + unsigned short cmd_id; +} __attribute__((packed)) videnc_cmd_idle; + +/* + * Command to query staus of VIDENC + */ + + +#define VIDENC_CMD_STATUS_QUERY_LEN \ + sizeof(videnc_cmd_status_query) + +typedef struct { + unsigned short cmd_id; +} __attribute__((packed)) videnc_cmd_status_query; + +/* + * Command to set rate control for a frame + */ + + +#define VIDENC_CMD_RC_CFG_LEN \ + sizeof(videnc_cmd_rc_cfg) + +typedef struct { + unsigned short cmd_id; + unsigned short max_frame_qp_delta; + unsigned short max_min_frame_qp; +} __attribute__((packed)) videnc_cmd_rc_cfg; + +/* + * Command to set intra-refreshing + */ + + +#define VIDENC_CMD_INTRA_REFRESH_LEN \ + sizeof(videnc_cmd_intra_refresh) + +typedef struct { + unsigned short cmd_id; + unsigned short num_mb_refresh; + unsigned short mb_index[15]; +} __attribute__((packed)) videnc_cmd_intra_refresh; + +/* + * Command to pass digital zoom information to the VIDENC + */ +#define VIDENC_CMD_DIGITAL_ZOOM_LEN \ + sizeof(videnc_cmd_digital_zoom) + +typedef struct { + unsigned short cmd_id; + unsigned short digital_zoom_en; + unsigned short luma_frame_shift_X; + unsigned short luma_frame_shift_Y; + unsigned short up_ip_luma_rows; + unsigned short up_ip_luma_cols; + unsigned short up_ip_chroma_rows; + unsigned short up_ip_chroma_cols; + unsigned short luma_ph_incr_V_low; + unsigned short luma_ph_incr_V_high; + unsigned short luma_ph_incr_H_low; + unsigned short luma_ph_incr_H_high; + unsigned short chroma_ph_incr_V_low; + unsigned short chroma_ph_incr_V_high; + unsigned short chroma_ph_incr_H_low; + unsigned short chroma_ph_incr_H_high; +} __attribute__((packed)) videnc_cmd_digital_zoom; + +/* + * Command to configure digital stabilization parameters + */ + +#define VIDENC_CMD_DIS_CFG_LEN \ + sizeof(videnc_cmd_dis_cfg) + +typedef struct { + unsigned short cmd_id; + unsigned short image_stab_subf_start_row_col; + unsigned short image_stab_subf_dim; + unsigned short image_stab_info_0; +} __attribute__((packed)) videnc_cmd_dis_cfg; + + +#endif diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5vfecmdi.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5vfecmdi.h new file mode 100644 index 0000000..55e8fc2 --- /dev/null +++ b/drivers/staging/dream/include/mach/qdsp5/qdsp5vfecmdi.h @@ -0,0 +1,910 @@ +#ifndef QDSP5VFECMDI_H +#define QDSP5VFECMDI_H + +/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* + + V F E I N T E R N A L C O M M A N D S + +GENERAL DESCRIPTION + This file contains defintions of format blocks of commands + that are accepted by VFE Task + +REFERENCES + None + +EXTERNALIZED FUNCTIONS + None + +Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated. + +This software is licensed under the terms of the GNU General Public +License version 2, as published by the Free Software Foundation, and +may be copied, distributed, and modified under those terms. + +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. + +*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ +/*=========================================================================== + + EDIT HISTORY FOR FILE + +This section contains comments describing changes made to this file. +Notice that changes are listed in reverse chronological order. + +$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5vfecmdi.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $ +Revision History: + +when who what, where, why +-------- --- ---------------------------------------------------------- +06/12/08 sv initial version +===========================================================================*/ + +/****************************************************************************** + * Commands through vfeCommandScaleQueue + *****************************************************************************/ + +/* + * Command to program scaler for op1 . max op of scaler is VGA + */ + + +#define VFE_CMD_SCALE_OP1_CFG 0x0000 +#define VFE_CMD_SCALE_OP1_CFG_LEN \ + sizeof(vfe_cmd_scale_op1_cfg) + +#define VFE_CMD_SCALE_OP1_SEL_IP_SEL_Y_STANDARD 0x0000 +#define VFE_CMD_SCALE_OP1_SEL_IP_SEL_Y_CASCADED 0x0001 +#define VFE_CMD_SCALE_OP1_SEL_H_Y_SCALER_DIS 0x0000 +#define VFE_CMD_SCALE_OP1_SEL_H_Y_SCALER_ENA 0x0002 +#define VFE_CMD_SCALE_OP1_SEL_H_PP_Y_SCALER_DIS 0x0000 +#define VFE_CMD_SCALE_OP1_SEL_H_PP_Y_SCALER_ENA 0x0004 +#define VFE_CMD_SCALE_OP1_SEL_V_Y_SCALER_DIS 0x0000 +#define VFE_CMD_SCALE_OP1_SEL_V_Y_SCALER_ENA 0x0008 +#define VFE_CMD_SCALE_OP1_SEL_V_PP_Y_SCALER_DIS 0x0000 +#define VFE_CMD_SCALE_OP1_SEL_V_PP_Y_SCALER_ENA 0x0010 +#define VFE_CMD_SCALE_OP1_SEL_IP_SEL_CBCR_STANDARD 0x0000 +#define VFE_CMD_SCALE_OP1_SEL_IP_SEL_CBCR_CASCADED 0x0020 +#define VFE_CMD_SCALE_OP1_SEL_H_CBCR_SCALER_DIS 0x0000 +#define VFE_CMD_SCALE_OP1_SEL_H_CBCR_SCALER_ENA 0x0040 +#define VFE_CMD_SCALE_OP1_SEL_V_CBCR_SCALER_DIS 0x0000 +#define VFE_CMD_SCALE_OP1_SEL_V_CBCR_SCALER_ENA 0x0080 + +#define VFE_CMD_OP1_PP_Y_SCALER_CFG_PART1_DONT_LOAD_COEFFS 0x80000000 +#define VFE_CMD_OP1_PP_Y_SCALER_CFG_PART1_LOAD_COEFFS 0x80000000 + +typedef struct { + unsigned int cmd_id; + unsigned int scale_op1_sel; + unsigned int y_scaler_cfg_part1; + unsigned int y_scaler_cfg_part2; + unsigned int cbcr_scaler_cfg_part1; + unsigned int cbcr_scaler_cfg_part2; + unsigned int cbcr_scaler_cfg_part3; + unsigned int pp_y_scaler_cfg_part1; + unsigned int pp_y_scaler_cfg_part2; + unsigned int y_scaler_v_coeff_bank_part1[16]; + unsigned int y_scaler_v_coeff_bank_part2[16]; + unsigned int y_scaler_h_coeff_bank_part1[16]; + unsigned int y_scaler_h_coeff_bank_part2[16]; +} __attribute__((packed)) vfe_cmd_scale_op1_cfg; + + +/* + * Command to program scaler for op2 + */ + +#define VFE_CMD_SCALE_OP2_CFG 0x0001 +#define VFE_CMD_SCALE_OP2_CFG_LEN \ + sizeof(vfe_cmd_scale_op2_cfg) + +#define VFE_CMD_SCALE_OP2_SEL_IP_SEL_Y_STANDARD 0x0000 +#define VFE_CMD_SCALE_OP2_SEL_IP_SEL_Y_CASCADED 0x0001 +#define VFE_CMD_SCALE_OP2_SEL_H_Y_SCALER_DIS 0x0000 +#define VFE_CMD_SCALE_OP2_SEL_H_Y_SCALER_ENA 0x0002 +#define VFE_CMD_SCALE_OP2_SEL_H_PP_Y_SCALER_DIS 0x0000 +#define VFE_CMD_SCALE_OP2_SEL_H_PP_Y_SCALER_ENA 0x0004 +#define VFE_CMD_SCALE_OP2_SEL_V_Y_SCALER_DIS 0x0000 +#define VFE_CMD_SCALE_OP2_SEL_V_Y_SCALER_ENA 0x0008 +#define VFE_CMD_SCALE_OP2_SEL_V_PP_Y_SCALER_DIS 0x0000 +#define VFE_CMD_SCALE_OP2_SEL_V_PP_Y_SCALER_ENA 0x0010 +#define VFE_CMD_SCALE_OP2_SEL_IP_SEL_CBCR_STANDARD 0x0000 +#define VFE_CMD_SCALE_OP2_SEL_IP_SEL_CBCR_CASCADED 0x0020 +#define VFE_CMD_SCALE_OP2_SEL_H_CBCR_SCALER_DIS 0x0000 +#define VFE_CMD_SCALE_OP2_SEL_H_CBCR_SCALER_ENA 0x0040 +#define VFE_CMD_SCALE_OP2_SEL_V_CBCR_SCALER_DIS 0x0000 +#define VFE_CMD_SCALE_OP2_SEL_V_CBCR_SCALER_ENA 0x0080 + +#define VFE_CMD_OP2_PP_Y_SCALER_CFG_PART1_DONT_LOAD_COEFFS 0x80000000 +#define VFE_CMD_OP2_PP_Y_SCALER_CFG_PART1_LOAD_COEFFS 0x80000000 + +typedef struct { + unsigned int cmd_id; + unsigned int scale_op2_sel; + unsigned int y_scaler_cfg_part1; + unsigned int y_scaler_cfg_part2; + unsigned int cbcr_scaler_cfg_part1; + unsigned int cbcr_scaler_cfg_part2; + unsigned int cbcr_scaler_cfg_part3; + unsigned int pp_y_scaler_cfg_part1; + unsigned int pp_y_scaler_cfg_part2; + unsigned int y_scaler_v_coeff_bank_part1[16]; + unsigned int y_scaler_v_coeff_bank_part2[16]; + unsigned int y_scaler_h_coeff_bank_part1[16]; + unsigned int y_scaler_h_coeff_bank_part2[16]; +} __attribute__((packed)) vfe_cmd_scale_op2_cfg; + + +/****************************************************************************** + * Commands through vfeCommandTableQueue + *****************************************************************************/ + +/* + * Command to program the AXI ip paths + */ + +#define VFE_CMD_AXI_IP_CFG 0x0000 +#define VFE_CMD_AXI_IP_CFG_LEN sizeof(vfe_cmd_axi_ip_cfg) + +#define VFE_CMD_IP_SEL_IP_FORMAT_8 0x0000 +#define VFE_CMD_IP_SEL_IP_FORMAT_10 0x0001 +#define VFE_CMD_IP_SEL_IP_FORMAT_12 0x0002 + +typedef struct { + unsigned int cmd_id; + unsigned int ip_sel; + unsigned int ip_cfg_part1; + unsigned int ip_cfg_part2; + unsigned int ip_unpack_cfg_part[6]; + unsigned int ip_buf_addr[8]; +} __attribute__ ((packed)) vfe_cmd_axi_ip_cfg; + + +/* + * Command to program axi op paths + */ + +#define VFE_CMD_AXI_OP_CFG 0x0001 +#define VFE_CMD_AXI_OP_CFG_LEN sizeof(vfe_cmd_axi_op_cfg) + +#define VFE_CMD_OP_SEL_OP1 0x0000 +#define VFE_CMD_OP_SEL_OP2 0x0001 +#define VFE_CMD_OP_SEL_OP1_OP2 0x0002 +#define VFE_CMD_OP_SEL_CTOA 0x0003 +#define VFE_CMD_OP_SEL_CTOA_OP1 0x0004 +#define VFE_CMD_OP_SEL_CTOA_OP2 0x0005 +#define VFE_CMD_OP_SEL_OP_FORMAT_8 0x0000 +#define VFE_CMD_OP_SEL_OP_FORMAT_10 0x0008 +#define VFE_CMD_OP_SEL_OP_FORMAT_12 0x0010 + + +typedef struct { + unsigned int cmd_id; + unsigned int op_sel; + unsigned int op1_y_cfg_part1; + unsigned int op1_y_cfg_part2; + unsigned int op1_cbcr_cfg_part1; + unsigned int op1_cbcr_cfg_part2; + unsigned int op2_y_cfg_part1; + unsigned int op2_y_cfg_part2; + unsigned int op2_cbcr_cfg_part1; + unsigned int op2_cbcr_cfg_part2; + unsigned int op1_buf1_addr[16]; + unsigned int op2_buf1_addr[16]; +} __attribute__((packed)) vfe_cmd_axi_op_cfg; + + + + +/* + * Command to program the roll off correction module + */ + +#define VFE_CMD_ROLLOFF_CFG 0x0002 +#define VFE_CMD_ROLLOFF_CFG_LEN \ + sizeof(vfe_cmd_rolloff_cfg) + + +typedef struct { + unsigned int cmd_id; + unsigned int correction_opt_center_pos; + unsigned int radius_square_entry[32]; + unsigned int red_table_entry[32]; + unsigned int green_table_entry[32]; + unsigned int blue_table_entry[32]; +} __attribute__((packed)) vfe_cmd_rolloff_cfg; + +/* + * Command to program RGB gamma table + */ + +#define VFE_CMD_RGB_GAMMA_CFG 0x0003 +#define VFE_CMD_RGB_GAMMA_CFG_LEN \ + sizeof(vfe_cmd_rgb_gamma_cfg) + +#define VFE_CMD_RGB_GAMMA_SEL_LINEAR 0x0000 +#define VFE_CMD_RGB_GAMMA_SEL_PW_LINEAR 0x0001 +typedef struct { + unsigned int cmd_id; + unsigned int rgb_gamma_sel; + unsigned int rgb_gamma_entry[256]; +} __attribute__((packed)) vfe_cmd_rgb_gamma_cfg; + + +/* + * Command to program luma gamma table for the noise reduction path + */ + +#define VFE_CMD_Y_GAMMA_CFG 0x0004 +#define VFE_CMD_Y_GAMMA_CFG_LEN \ + sizeof(vfe_cmd_y_gamma_cfg) + +#define VFE_CMD_Y_GAMMA_SEL_LINEAR 0x0000 +#define VFE_CMD_Y_GAMMA_SEL_PW_LINEAR 0x0001 + +typedef struct { + unsigned int cmd_id; + unsigned int y_gamma_sel; + unsigned int y_gamma_entry[256]; +} __attribute__((packed)) vfe_cmd_y_gamma_cfg; + + + +/****************************************************************************** + * Commands through vfeCommandQueue + *****************************************************************************/ + +/* + * Command to reset the VFE to a known good state.All previously programmed + * Params will be lost + */ + + +#define VFE_CMD_RESET 0x0000 +#define VFE_CMD_RESET_LEN sizeof(vfe_cmd_reset) + + +typedef struct { + unsigned short cmd_id; +} __attribute__((packed)) vfe_cmd_reset; + + +/* + * Command to start VFE processing based on the config params + */ + + +#define VFE_CMD_START 0x0001 +#define VFE_CMD_START_LEN sizeof(vfe_cmd_start) + +#define VFE_CMD_STARTUP_PARAMS_SRC_CAMIF 0x0000 +#define VFE_CMD_STARTUP_PARAMS_SRC_AXI 0x0001 +#define VFE_CMD_STARTUP_PARAMS_MODE_CONTINUOUS 0x0000 +#define VFE_CMD_STARTUP_PARAMS_MODE_SNAPSHOT 0x0002 + +#define VFE_CMD_IMAGE_PL_BLACK_LVL_CORR_DIS 0x0000 +#define VFE_CMD_IMAGE_PL_BLACK_LVL_CORR_ENA 0x0001 +#define VFE_CMD_IMAGE_PL_ROLLOFF_CORR_DIS 0x0000 +#define VFE_CMD_IMAGE_PL_ROLLOFF_CORR_ENA 0x0002 +#define VFE_CMD_IMAGE_PL_WHITE_BAL_DIS 0x0000 +#define VFE_CMD_IMAGE_PL_WHITE_BAL_ENA 0x0004 +#define VFE_CMD_IMAGE_PL_RGB_GAMMA_DIS 0x0000 +#define VFE_CMD_IMAGE_PL_RGB_GAMMA_ENA 0x0008 +#define VFE_CMD_IMAGE_PL_LUMA_NOISE_RED_PATH_DIS 0x0000 +#define VFE_CMD_IMAGE_PL_LUMA_NOISE_RED_PATH_ENA 0x0010 +#define VFE_CMD_IMAGE_PL_ADP_FILTER_DIS 0x0000 +#define VFE_CMD_IMAGE_PL_ADP_FILTER_ENA 0x0020 +#define VFE_CMD_IMAGE_PL_CHROMA_SAMP_DIS 0x0000 +#define VFE_CMD_IMAGE_PL_CHROMA_SAMP_ENA 0x0040 + + +typedef struct { + unsigned int cmd_id; + unsigned int startup_params; + unsigned int image_pipeline; + unsigned int frame_dimension; +} __attribute__((packed)) vfe_cmd_start; + + +/* + * Command to halt all processing + */ + +#define VFE_CMD_STOP 0x0002 +#define VFE_CMD_STOP_LEN sizeof(vfe_cmd_stop) + +typedef struct { + unsigned short cmd_id; +} __attribute__((packed)) vfe_cmd_stop; + + +/* + * Command to commit the params that have been programmed to take + * effect on the next frame + */ + +#define VFE_CMD_UPDATE 0x0003 +#define VFE_CMD_UPDATE_LEN sizeof(vfe_cmd_update) + + +typedef struct { + unsigned short cmd_id; +} __attribute__((packed)) vfe_cmd_update; + + +/* + * Command to program CAMIF module + */ + +#define VFE_CMD_CAMIF_CFG 0x0004 +#define VFE_CMD_CAMIF_CFG_LEN sizeof(vfe_cmd_camif_cfg) + +#define VFE_CMD_CFG_VSYNC_SYNC_EDGE_HIGH 0x0000 +#define VFE_CMD_CFG_VSYNC_SYNC_EDGE_LOW 0x0002 +#define VFE_CMD_CFG_HSYNC_SYNC_EDGE_HIGH 0x0000 +#define VFE_CMD_CFG_HSYNC_SYNC_EDGE_LOW 0x0004 +#define VFE_CMD_CFG_SYNC_MODE_APS 0x0000 +#define VFE_CMD_CFG_SYNC_MODE_EFS 0X0008 +#define VFE_CMD_CFG_SYNC_MODE_ELS 0x0010 +#define VFE_CMD_CFG_SYNC_MODE_RVD 0x0018 +#define VFE_CMD_CFG_VFE_SUBSAMP_EN_DIS 0x0000 +#define VFE_CMD_CFG_VFE_SUBSAMP_EN_ENA 0x0020 +#define VFE_CMD_CFG_BUS_SUBSAMP_EN_DIS 0x0000 +#define VFE_CMD_CFG_BUS_SUBSAMP_EN_ENA 0x0080 +#define VFE_CMD_CFG_IRQ_SUBSAMP_EN_DIS 0x0000 +#define VFE_CMD_CFG_IRQ_SUBSAMP_EN_ENA 0x0800 + +#define VFE_CMD_SUBSAMP2_CFG_PIXEL_SKIP_16 0x0000 +#define VFE_CMD_SUBSAMP2_CFG_PIXEL_SKIP_12 0x0010 + +#define VFE_CMD_EPOCH_IRQ_1_DIS 0x0000 +#define VFE_CMD_EPOCH_IRQ_1_ENA 0x4000 +#define VFE_CMD_EPOCH_IRQ_2_DIS 0x0000 +#define VFE_CMD_EPOCH_IRQ_2_ENA 0x8000 + +typedef struct { + unsigned int cmd_id; + unsigned int cfg; + unsigned int efs_cfg; + unsigned int frame_cfg; + unsigned int window_width_cfg; + unsigned int window_height_cfg; + unsigned int subsamp1_cfg; + unsigned int subsamp2_cfg; + unsigned int epoch_irq; +} __attribute__((packed)) vfe_cmd_camif_cfg; + + + +/* + * Command to program the black level module + */ + +#define VFE_CMD_BLACK_LVL_CFG 0x0005 +#define VFE_CMD_BLACK_LVL_CFG_LEN sizeof(vfe_cmd_black_lvl_cfg) + +#define VFE_CMD_BL_SEL_MANUAL 0x0000 +#define VFE_CMD_BL_SEL_AUTO 0x0001 + +typedef struct { + unsigned int cmd_id; + unsigned int black_lvl_sel; + unsigned int cfg_part[3]; +} __attribute__((packed)) vfe_cmd_black_lvl_cfg; + + +/* + * Command to program the active region by cropping the region of interest + */ + +#define VFE_CMD_ACTIVE_REGION_CFG 0x0006 +#define VFE_CMD_ACTIVE_REGION_CFG_LEN \ + sizeof(vfe_cmd_active_region_cfg) + + +typedef struct { + unsigned int cmd_id; + unsigned int cfg_part1; + unsigned int cfg_part2; +} __attribute__((packed)) vfe_cmd_active_region_cfg; + + + +/* + * Command to program the defective pixel correction(DPC) , + * adaptive bayer filter (ABF) and demosaic modules + */ + +#define VFE_CMD_DEMOSAIC_CFG 0x0007 +#define VFE_CMD_DEMOSAIC_CFG_LEN sizeof(vfe_cmd_demosaic_cfg) + +#define VFE_CMD_DEMOSAIC_PART1_ABF_EN_DIS 0x0000 +#define VFE_CMD_DEMOSAIC_PART1_ABF_EN_ENA 0x0001 +#define VFE_CMD_DEMOSAIC_PART1_DPC_EN_DIS 0x0000 +#define VFE_CMD_DEMOSAIC_PART1_DPC_EN_ENA 0x0002 +#define VFE_CMD_DEMOSAIC_PART1_FORCE_ABF_OFF 0x0000 +#define VFE_CMD_DEMOSAIC_PART1_FORCE_ABF_ON 0x0004 +#define VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_1 0x00000000 +#define VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_2 0x10000000 +#define VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_4 0x20000000 +#define VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_8 0x30000000 +#define VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_1_2 0x50000000 +#define VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_1_4 0x60000000 +#define VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_1_8 0x70000000 + +typedef struct { + unsigned int cmd_id; + unsigned int demosaic_part1; + unsigned int demosaic_part2; + unsigned int demosaic_part3; + unsigned int demosaic_part4; + unsigned int demosaic_part5; +} __attribute__((packed)) vfe_cmd_demosaic_cfg; + + +/* + * Command to program the ip format + */ + +#define VFE_CMD_IP_FORMAT_CFG 0x0008 +#define VFE_CMD_IP_FORMAT_CFG_LEN \ + sizeof(vfe_cmd_ip_format_cfg) + +#define VFE_CMD_IP_FORMAT_SEL_RGRG 0x0000 +#define VFE_CMD_IP_FORMAT_SEL_GRGR 0x0001 +#define VFE_CMD_IP_FORMAT_SEL_BGBG 0x0002 +#define VFE_CMD_IP_FORMAT_SEL_GBGB 0x0003 +#define VFE_CMD_IP_FORMAT_SEL_YCBYCR 0x0004 +#define VFE_CMD_IP_FORMAT_SEL_YCRYCB 0x0005 +#define VFE_CMD_IP_FORMAT_SEL_CBYCRY 0x0006 +#define VFE_CMD_IP_FORMAT_SEL_CRYCBY 0x0007 +#define VFE_CMD_IP_FORMAT_SEL_NO_CHROMA 0x0000 +#define VFE_CMD_IP_FORMAT_SEL_CHROMA 0x0008 + + +typedef struct { + unsigned int cmd_id; + unsigned int ip_format_sel; + unsigned int balance_gains_part1; + unsigned int balance_gains_part2; +} __attribute__((packed)) vfe_cmd_ip_format_cfg; + + + +/* + * Command to program max and min allowed op values + */ + +#define VFE_CMD_OP_CLAMP_CFG 0x0009 +#define VFE_CMD_OP_CLAMP_CFG_LEN \ + sizeof(vfe_cmd_op_clamp_cfg) + +typedef struct { + unsigned int cmd_id; + unsigned int op_clamp_max; + unsigned int op_clamp_min; +} __attribute__((packed)) vfe_cmd_op_clamp_cfg; + + +/* + * Command to program chroma sub sample module + */ + +#define VFE_CMD_CHROMA_SUBSAMPLE_CFG 0x000A +#define VFE_CMD_CHROMA_SUBSAMPLE_CFG_LEN \ + sizeof(vfe_cmd_chroma_subsample_cfg) + +#define VFE_CMD_CHROMA_SUBSAMP_SEL_H_INTERESTIAL_SAMPS 0x0000 +#define VFE_CMD_CHROMA_SUBSAMP_SEL_H_COSITED_SAMPS 0x0001 +#define VFE_CMD_CHROMA_SUBSAMP_SEL_V_INTERESTIAL_SAMPS 0x0000 +#define VFE_CMD_CHROMA_SUBSAMP_SEL_V_COSITED_SAMPS 0x0002 +#define VFE_CMD_CHROMA_SUBSAMP_SEL_H_SUBSAMP_DIS 0x0000 +#define VFE_CMD_CHROMA_SUBSAMP_SEL_H_SUBSAMP_ENA 0x0004 +#define VFE_CMD_CHROMA_SUBSAMP_SEL_V_SUBSAMP_DIS 0x0000 +#define VFE_CMD_CHROMA_SUBSAMP_SEL_V_SUBSAMP_ENA 0x0008 + +typedef struct { + unsigned int cmd_id; + unsigned int chroma_subsamp_sel; +} __attribute__((packed)) vfe_cmd_chroma_subsample_cfg; + + +/* + * Command to program the white balance module + */ + +#define VFE_CMD_WHITE_BALANCE_CFG 0x000B +#define VFE_CMD_WHITE_BALANCE_CFG_LEN \ + sizeof(vfe_cmd_white_balance_cfg) + +typedef struct { + unsigned int cmd_id; + unsigned int white_balance_gains; +} __attribute__((packed)) vfe_cmd_white_balance_cfg; + + +/* + * Command to program the color processing module + */ + +#define VFE_CMD_COLOR_PROCESS_CFG 0x000C +#define VFE_CMD_COLOR_PROCESS_CFG_LEN \ + sizeof(vfe_cmd_color_process_cfg) + +#define VFE_CMD_COLOR_CORRE_PART7_Q7_FACTORS 0x0000 +#define VFE_CMD_COLOR_CORRE_PART7_Q8_FACTORS 0x0001 +#define VFE_CMD_COLOR_CORRE_PART7_Q9_FACTORS 0x0002 +#define VFE_CMD_COLOR_CORRE_PART7_Q10_FACTORS 0x0003 + +typedef struct { + unsigned int cmd_id; + unsigned int color_correction_part1; + unsigned int color_correction_part2; + unsigned int color_correction_part3; + unsigned int color_correction_part4; + unsigned int color_correction_part5; + unsigned int color_correction_part6; + unsigned int color_correction_part7; + unsigned int chroma_enhance_part1; + unsigned int chroma_enhance_part2; + unsigned int chroma_enhance_part3; + unsigned int chroma_enhance_part4; + unsigned int chroma_enhance_part5; + unsigned int luma_calc_part1; + unsigned int luma_calc_part2; +} __attribute__((packed)) vfe_cmd_color_process_cfg; + + +/* + * Command to program adaptive filter module + */ + +#define VFE_CMD_ADP_FILTER_CFG 0x000D +#define VFE_CMD_ADP_FILTER_CFG_LEN \ + sizeof(vfe_cmd_adp_filter_cfg) + +#define VFE_CMD_ASF_CFG_PART_SMOOTH_FILTER_DIS 0x0000 +#define VFE_CMD_ASF_CFG_PART_SMOOTH_FILTER_ENA 0x0001 +#define VFE_CMD_ASF_CFG_PART_NO_SHARP_MODE 0x0000 +#define VFE_CMD_ASF_CFG_PART_SINGLE_FILTER 0x0002 +#define VFE_CMD_ASF_CFG_PART_DUAL_FILTER 0x0004 +#define VFE_CMD_ASF_CFG_PART_SHARP_MODE 0x0007 + +typedef struct { + unsigned int cmd_id; + unsigned int asf_cfg_part[7]; +} __attribute__((packed)) vfe_cmd_adp_filter_cfg; + + +/* + * Command to program for frame skip pattern for op1 and op2 + */ + +#define VFE_CMD_FRAME_SKIP_CFG 0x000E +#define VFE_CMD_FRAME_SKIP_CFG_LEN \ + sizeof(vfe_cmd_frame_skip_cfg) + +typedef struct { + unsigned int cmd_id; + unsigned int frame_skip_pattern_op1; + unsigned int frame_skip_pattern_op2; +} __attribute__((packed)) vfe_cmd_frame_skip_cfg; + + +/* + * Command to program field-of-view crop for digital zoom + */ + +#define VFE_CMD_FOV_CROP 0x000F +#define VFE_CMD_FOV_CROP_LEN sizeof(vfe_cmd_fov_crop) + +typedef struct { + unsigned int cmd_id; + unsigned int fov_crop_part1; + unsigned int fov_crop_part2; +} __attribute__((packed)) vfe_cmd_fov_crop; + + + +/* + * Command to program auto focus(AF) statistics module + */ + +#define VFE_CMD_STATS_AUTOFOCUS_CFG 0x0010 +#define VFE_CMD_STATS_AUTOFOCUS_CFG_LEN \ + sizeof(vfe_cmd_stats_autofocus_cfg) + +#define VFE_CMD_AF_STATS_SEL_STATS_DIS 0x0000 +#define VFE_CMD_AF_STATS_SEL_STATS_ENA 0x0001 +#define VFE_CMD_AF_STATS_SEL_PRI_FIXED 0x0000 +#define VFE_CMD_AF_STATS_SEL_PRI_VAR 0x0002 +#define VFE_CMD_AF_STATS_CFG_PART_METRIC_SUM 0x00000000 +#define VFE_CMD_AF_STATS_CFG_PART_METRIC_MAX 0x00200000 + +typedef struct { + unsigned int cmd_id; + unsigned int af_stats_sel; + unsigned int af_stats_cfg_part[8]; + unsigned int af_stats_op_buf_hdr; + unsigned int af_stats_op_buf[3]; +} __attribute__((packed)) vfe_cmd_stats_autofocus_cfg; + + +/* + * Command to program White balance(wb) and exposure (exp) + * statistics module + */ + +#define VFE_CMD_STATS_WB_EXP_CFG 0x0011 +#define VFE_CMD_STATS_WB_EXP_CFG_LEN \ + sizeof(vfe_cmd_stats_wb_exp_cfg) + +#define VFE_CMD_WB_EXP_STATS_SEL_STATS_DIS 0x0000 +#define VFE_CMD_WB_EXP_STATS_SEL_STATS_ENA 0x0001 +#define VFE_CMD_WB_EXP_STATS_SEL_PRI_FIXED 0x0000 +#define VFE_CMD_WB_EXP_STATS_SEL_PRI_VAR 0x0002 + +#define VFE_CMD_WB_EXP_STATS_CFG_PART1_EXP_REG_8_8 0x0000 +#define VFE_CMD_WB_EXP_STATS_CFG_PART1_EXP_REG_16_16 0x0001 +#define VFE_CMD_WB_EXP_STATS_CFG_PART1_EXP_SREG_8_8 0x0000 +#define VFE_CMD_WB_EXP_STATS_CFG_PART1_EXP_SREG_4_4 0x0002 + +typedef struct { + unsigned int cmd_id; + unsigned int wb_exp_stats_sel; + unsigned int wb_exp_stats_cfg_part1; + unsigned int wb_exp_stats_cfg_part2; + unsigned int wb_exp_stats_cfg_part3; + unsigned int wb_exp_stats_cfg_part4; + unsigned int wb_exp_stats_op_buf_hdr; + unsigned int wb_exp_stats_op_buf[3]; +} __attribute__((packed)) vfe_cmd_stats_wb_exp_cfg; + + +/* + * Command to program histogram(hg) stats module + */ + +#define VFE_CMD_STATS_HG_CFG 0x0012 +#define VFE_CMD_STATS_HG_CFG_LEN \ + sizeof(vfe_cmd_stats_hg_cfg) + +#define VFE_CMD_HG_STATS_SEL_PRI_FIXED 0x0000 +#define VFE_CMD_HG_STATS_SEL_PRI_VAR 0x0002 + +typedef struct { + unsigned int cmd_id; + unsigned int hg_stats_sel; + unsigned int hg_stats_cfg_part1; + unsigned int hg_stats_cfg_part2; + unsigned int hg_stats_op_buf_hdr; + unsigned int hg_stats_op_buf; +} __attribute__((packed)) vfe_cmd_stats_hg_cfg; + + +/* + * Command to acknowledge last MSG_VFE_OP1 message + */ + +#define VFE_CMD_OP1_ACK 0x0013 +#define VFE_CMD_OP1_ACK_LEN sizeof(vfe_cmd_op1_ack) + +typedef struct { + unsigned int cmd_id; + unsigned int op1_buf_y_addr; + unsigned int op1_buf_cbcr_addr; +} __attribute__((packed)) vfe_cmd_op1_ack; + + + +/* + * Command to acknowledge last MSG_VFE_OP2 message + */ + +#define VFE_CMD_OP2_ACK 0x0014 +#define VFE_CMD_OP2_ACK_LEN sizeof(vfe_cmd_op2_ack) + +typedef struct { + unsigned int cmd_id; + unsigned int op2_buf_y_addr; + unsigned int op2_buf_cbcr_addr; +} __attribute__((packed)) vfe_cmd_op2_ack; + + + +/* + * Command to acknowledge MSG_VFE_STATS_AUTOFOCUS msg + */ + +#define VFE_CMD_STATS_AF_ACK 0x0015 +#define VFE_CMD_STATS_AF_ACK_LEN sizeof(vfe_cmd_stats_af_ack) + + +typedef struct { + unsigned int cmd_id; + unsigned int af_stats_op_buf; +} __attribute__((packed)) vfe_cmd_stats_af_ack; + + +/* + * Command to acknowledge MSG_VFE_STATS_WB_EXP msg + */ + +#define VFE_CMD_STATS_WB_EXP_ACK 0x0016 +#define VFE_CMD_STATS_WB_EXP_ACK_LEN sizeof(vfe_cmd_stats_wb_exp_ack) + +typedef struct { + unsigned int cmd_id; + unsigned int wb_exp_stats_op_buf; +} __attribute__((packed)) vfe_cmd_stats_wb_exp_ack; + + +/* + * Command to acknowledge MSG_VFE_EPOCH1 message + */ + +#define VFE_CMD_EPOCH1_ACK 0x0017 +#define VFE_CMD_EPOCH1_ACK_LEN sizeof(vfe_cmd_epoch1_ack) + +typedef struct { + unsigned short cmd_id; +} __attribute__((packed)) vfe_cmd_epoch1_ack; + + +/* + * Command to acknowledge MSG_VFE_EPOCH2 message + */ + +#define VFE_CMD_EPOCH2_ACK 0x0018 +#define VFE_CMD_EPOCH2_ACK_LEN sizeof(vfe_cmd_epoch2_ack) + +typedef struct { + unsigned short cmd_id; +} __attribute__((packed)) vfe_cmd_epoch2_ack; + + + +/* + * Command to configure, enable or disable synchronous timer1 + */ + +#define VFE_CMD_SYNC_TIMER1_CFG 0x0019 +#define VFE_CMD_SYNC_TIMER1_CFG_LEN \ + sizeof(vfe_cmd_sync_timer1_cfg) + +#define VFE_CMD_SYNC_T1_CFG_PART1_TIMER_DIS 0x0000 +#define VFE_CMD_SYNC_T1_CFG_PART1_TIMER_ENA 0x0001 +#define VFE_CMD_SYNC_T1_CFG_PART1_POL_HIGH 0x0000 +#define VFE_CMD_SYNC_T1_CFG_PART1_POL_LOW 0x0002 + +typedef struct { + unsigned int cmd_id; + unsigned int sync_t1_cfg_part1; + unsigned int sync_t1_h_sync_countdown; + unsigned int sync_t1_pclk_countdown; + unsigned int sync_t1_duration; +} __attribute__((packed)) vfe_cmd_sync_timer1_cfg; + + +/* + * Command to configure, enable or disable synchronous timer1 + */ + +#define VFE_CMD_SYNC_TIMER2_CFG 0x001A +#define VFE_CMD_SYNC_TIMER2_CFG_LEN \ + sizeof(vfe_cmd_sync_timer2_cfg) + +#define VFE_CMD_SYNC_T2_CFG_PART1_TIMER_DIS 0x0000 +#define VFE_CMD_SYNC_T2_CFG_PART1_TIMER_ENA 0x0001 +#define VFE_CMD_SYNC_T2_CFG_PART1_POL_HIGH 0x0000 +#define VFE_CMD_SYNC_T2_CFG_PART1_POL_LOW 0x0002 + +typedef struct { + unsigned int cmd_id; + unsigned int sync_t2_cfg_part1; + unsigned int sync_t2_h_sync_countdown; + unsigned int sync_t2_pclk_countdown; + unsigned int sync_t2_duration; +} __attribute__((packed)) vfe_cmd_sync_timer2_cfg; + + +/* + * Command to configure and start asynchronous timer1 + */ + +#define VFE_CMD_ASYNC_TIMER1_START 0x001B +#define VFE_CMD_ASYNC_TIMER1_START_LEN \ + sizeof(vfe_cmd_async_timer1_start) + +#define VFE_CMD_ASYNC_T1_POLARITY_A_HIGH 0x0000 +#define VFE_CMD_ASYNC_T1_POLARITY_A_LOW 0x0001 +#define VFE_CMD_ASYNC_T1_POLARITY_B_HIGH 0x0000 +#define VFE_CMD_ASYNC_T1_POLARITY_B_LOW 0x0002 + +typedef struct { + unsigned int cmd_id; + unsigned int async_t1a_cfg; + unsigned int async_t1b_cfg; + unsigned int async_t1_polarity; +} __attribute__((packed)) vfe_cmd_async_timer1_start; + + +/* + * Command to configure and start asynchronous timer2 + */ + +#define VFE_CMD_ASYNC_TIMER2_START 0x001C +#define VFE_CMD_ASYNC_TIMER2_START_LEN \ + sizeof(vfe_cmd_async_timer2_start) + +#define VFE_CMD_ASYNC_T2_POLARITY_A_HIGH 0x0000 +#define VFE_CMD_ASYNC_T2_POLARITY_A_LOW 0x0001 +#define VFE_CMD_ASYNC_T2_POLARITY_B_HIGH 0x0000 +#define VFE_CMD_ASYNC_T2_POLARITY_B_LOW 0x0002 + +typedef struct { + unsigned int cmd_id; + unsigned int async_t2a_cfg; + unsigned int async_t2b_cfg; + unsigned int async_t2_polarity; +} __attribute__((packed)) vfe_cmd_async_timer2_start; + + +/* + * Command to program partial configurations of auto focus(af) + */ + +#define VFE_CMD_STATS_AF_UPDATE 0x001D +#define VFE_CMD_STATS_AF_UPDATE_LEN \ + sizeof(vfe_cmd_stats_af_update) + +#define VFE_CMD_AF_UPDATE_PART1_WINDOW_ONE 0x00000000 +#define VFE_CMD_AF_UPDATE_PART1_WINDOW_MULTI 0x80000000 + +typedef struct { + unsigned int cmd_id; + unsigned int af_update_part1; + unsigned int af_update_part2; +} __attribute__((packed)) vfe_cmd_stats_af_update; + + +/* + * Command to program partial cfg of wb and exp + */ + +#define VFE_CMD_STATS_WB_EXP_UPDATE 0x001E +#define VFE_CMD_STATS_WB_EXP_UPDATE_LEN \ + sizeof(vfe_cmd_stats_wb_exp_update) + +#define VFE_CMD_WB_EXP_UPDATE_PART1_REGIONS_8_8 0x0000 +#define VFE_CMD_WB_EXP_UPDATE_PART1_REGIONS_16_16 0x0001 +#define VFE_CMD_WB_EXP_UPDATE_PART1_SREGIONS_8_8 0x0000 +#define VFE_CMD_WB_EXP_UPDATE_PART1_SREGIONS_4_4 0x0002 + +typedef struct { + unsigned int cmd_id; + unsigned int wb_exp_update_part1; + unsigned int wb_exp_update_part2; + unsigned int wb_exp_update_part3; + unsigned int wb_exp_update_part4; +} __attribute__((packed)) vfe_cmd_stats_wb_exp_update; + + + +/* + * Command to re program the CAMIF FRAME CONFIG settings + */ + +#define VFE_CMD_UPDATE_CAMIF_FRAME_CFG 0x001F +#define VFE_CMD_UPDATE_CAMIF_FRAME_CFG_LEN \ + sizeof(vfe_cmd_update_camif_frame_cfg) + +typedef struct { + unsigned int cmd_id; + unsigned int camif_frame_cfg; +} __attribute__((packed)) vfe_cmd_update_camif_frame_cfg; + + +#endif diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5vfemsg.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5vfemsg.h new file mode 100644 index 0000000..0053cfb --- /dev/null +++ b/drivers/staging/dream/include/mach/qdsp5/qdsp5vfemsg.h @@ -0,0 +1,290 @@ +#ifndef QDSP5VFEMSGI_H +#define QDSP5VFEMSGI_H + +/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* + + V F E I N T E R N A L M E S S A G E S + +GENERAL DESCRIPTION + This file contains defintions of format blocks of commands + that are sent by VFE Task + +REFERENCES + None + +EXTERNALIZED FUNCTIONS + None + +Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated. + +This software is licensed under the terms of the GNU General Public +License version 2, as published by the Free Software Foundation, and +may be copied, distributed, and modified under those terms. + +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. + +*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ +/*=========================================================================== + + EDIT HISTORY FOR FILE + +This section contains comments describing changes made to this file. +Notice that changes are listed in reverse chronological order. + +$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5vfemsg.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $ +Revision History: + +when who what, where, why +-------- --- ---------------------------------------------------------- +06/12/08 sv initial version +===========================================================================*/ + + +/* + * Message to acknowledge CMD_VFE_REST command + */ + +#define VFE_MSG_RESET_ACK 0x0000 +#define VFE_MSG_RESET_ACK_LEN sizeof(vfe_msg_reset_ack) + +typedef struct { +} __attribute__((packed)) vfe_msg_reset_ack; + + +/* + * Message to acknowledge CMD_VFE_START command + */ + +#define VFE_MSG_START_ACK 0x0001 +#define VFE_MSG_START_ACK_LEN sizeof(vfe_msg_start_ack) + +typedef struct { +} __attribute__((packed)) vfe_msg_start_ack; + +/* + * Message to acknowledge CMD_VFE_STOP command + */ + +#define VFE_MSG_STOP_ACK 0x0002 +#define VFE_MSG_STOP_ACK_LEN sizeof(vfe_msg_stop_ack) + +typedef struct { +} __attribute__((packed)) vfe_msg_stop_ack; + + +/* + * Message to acknowledge CMD_VFE_UPDATE command + */ + +#define VFE_MSG_UPDATE_ACK 0x0003 +#define VFE_MSG_UPDATE_ACK_LEN sizeof(vfe_msg_update_ack) + +typedef struct { +} __attribute__((packed)) vfe_msg_update_ack; + + +/* + * Message to notify the ARM that snapshot processing is complete + * and that the VFE is now STATE_VFE_IDLE + */ + +#define VFE_MSG_SNAPSHOT_DONE 0x0004 +#define VFE_MSG_SNAPSHOT_DONE_LEN \ + sizeof(vfe_msg_snapshot_done) + +typedef struct { +} __attribute__((packed)) vfe_msg_snapshot_done; + + + +/* + * Message to notify ARM that illegal cmd was received and + * system is in the IDLE state + */ + +#define VFE_MSG_ILLEGAL_CMD 0x0005 +#define VFE_MSG_ILLEGAL_CMD_LEN \ + sizeof(vfe_msg_illegal_cmd) + +typedef struct { + unsigned int status; +} __attribute__((packed)) vfe_msg_illegal_cmd; + + +/* + * Message to notify ARM that op1 buf is full and ready + */ + +#define VFE_MSG_OP1 0x0006 +#define VFE_MSG_OP1_LEN sizeof(vfe_msg_op1) + +typedef struct { + unsigned int op1_buf_y_addr; + unsigned int op1_buf_cbcr_addr; + unsigned int black_level_even_col; + unsigned int black_level_odd_col; + unsigned int defect_pixels_detected; + unsigned int asf_max_edge; +} __attribute__((packed)) vfe_msg_op1; + + +/* + * Message to notify ARM that op2 buf is full and ready + */ + +#define VFE_MSG_OP2 0x0007 +#define VFE_MSG_OP2_LEN sizeof(vfe_msg_op2) + +typedef struct { + unsigned int op2_buf_y_addr; + unsigned int op2_buf_cbcr_addr; + unsigned int black_level_even_col; + unsigned int black_level_odd_col; + unsigned int defect_pixels_detected; + unsigned int asf_max_edge; +} __attribute__((packed)) vfe_msg_op2; + + +/* + * Message to notify ARM that autofocus(af) stats are ready + */ + +#define VFE_MSG_STATS_AF 0x0008 +#define VFE_MSG_STATS_AF_LEN sizeof(vfe_msg_stats_af) + +typedef struct { + unsigned int af_stats_op_buffer; +} __attribute__((packed)) vfe_msg_stats_af; + + +/* + * Message to notify ARM that white balance(wb) and exposure (exp) + * stats are ready + */ + +#define VFE_MSG_STATS_WB_EXP 0x0009 +#define VFE_MSG_STATS_WB_EXP_LEN \ + sizeof(vfe_msg_stats_wb_exp) + +typedef struct { + unsigned int wb_exp_stats_op_buf; +} __attribute__((packed)) vfe_msg_stats_wb_exp; + + +/* + * Message to notify the ARM that histogram(hg) stats are ready + */ + +#define VFE_MSG_STATS_HG 0x000A +#define VFE_MSG_STATS_HG_LEN sizeof(vfe_msg_stats_hg) + +typedef struct { + unsigned int hg_stats_op_buf; +} __attribute__((packed)) vfe_msg_stats_hg; + + +/* + * Message to notify the ARM that epoch1 event occurred in the CAMIF + */ + +#define VFE_MSG_EPOCH1 0x000B +#define VFE_MSG_EPOCH1_LEN sizeof(vfe_msg_epoch1) + +typedef struct { +} __attribute__((packed)) vfe_msg_epoch1; + + +/* + * Message to notify the ARM that epoch2 event occurred in the CAMIF + */ + +#define VFE_MSG_EPOCH2 0x000C +#define VFE_MSG_EPOCH2_LEN sizeof(vfe_msg_epoch2) + +typedef struct { +} __attribute__((packed)) vfe_msg_epoch2; + + +/* + * Message to notify the ARM that sync timer1 op is completed + */ + +#define VFE_MSG_SYNC_T1_DONE 0x000D +#define VFE_MSG_SYNC_T1_DONE_LEN sizeof(vfe_msg_sync_t1_done) + +typedef struct { +} __attribute__((packed)) vfe_msg_sync_t1_done; + + +/* + * Message to notify the ARM that sync timer2 op is completed + */ + +#define VFE_MSG_SYNC_T2_DONE 0x000E +#define VFE_MSG_SYNC_T2_DONE_LEN sizeof(vfe_msg_sync_t2_done) + +typedef struct { +} __attribute__((packed)) vfe_msg_sync_t2_done; + + +/* + * Message to notify the ARM that async t1 operation completed + */ + +#define VFE_MSG_ASYNC_T1_DONE 0x000F +#define VFE_MSG_ASYNC_T1_DONE_LEN sizeof(vfe_msg_async_t1_done) + +typedef struct { +} __attribute__((packed)) vfe_msg_async_t1_done; + + + +/* + * Message to notify the ARM that async t2 operation completed + */ + +#define VFE_MSG_ASYNC_T2_DONE 0x0010 +#define VFE_MSG_ASYNC_T2_DONE_LEN sizeof(vfe_msg_async_t2_done) + +typedef struct { +} __attribute__((packed)) vfe_msg_async_t2_done; + + + +/* + * Message to notify the ARM that an error has occurred + */ + +#define VFE_MSG_ERROR 0x0011 +#define VFE_MSG_ERROR_LEN sizeof(vfe_msg_error) + +#define VFE_MSG_ERR_COND_NO_CAMIF_ERR 0x0000 +#define VFE_MSG_ERR_COND_CAMIF_ERR 0x0001 +#define VFE_MSG_ERR_COND_OP1_Y_NO_BUS_OF 0x0000 +#define VFE_MSG_ERR_COND_OP1_Y_BUS_OF 0x0002 +#define VFE_MSG_ERR_COND_OP1_CBCR_NO_BUS_OF 0x0000 +#define VFE_MSG_ERR_COND_OP1_CBCR_BUS_OF 0x0004 +#define VFE_MSG_ERR_COND_OP2_Y_NO_BUS_OF 0x0000 +#define VFE_MSG_ERR_COND_OP2_Y_BUS_OF 0x0008 +#define VFE_MSG_ERR_COND_OP2_CBCR_NO_BUS_OF 0x0000 +#define VFE_MSG_ERR_COND_OP2_CBCR_BUS_OF 0x0010 +#define VFE_MSG_ERR_COND_AF_NO_BUS_OF 0x0000 +#define VFE_MSG_ERR_COND_AF_BUS_OF 0x0020 +#define VFE_MSG_ERR_COND_WB_EXP_NO_BUS_OF 0x0000 +#define VFE_MSG_ERR_COND_WB_EXP_BUS_OF 0x0040 +#define VFE_MSG_ERR_COND_NO_AXI_ERR 0x0000 +#define VFE_MSG_ERR_COND_AXI_ERR 0x0080 + +#define VFE_MSG_CAMIF_STS_IDLE 0x0000 +#define VFE_MSG_CAMIF_STS_CAPTURE_DATA 0x0001 + +typedef struct { + unsigned int err_cond; + unsigned int camif_sts; +} __attribute__((packed)) vfe_msg_error; + + +#endif diff --git a/drivers/staging/dream/include/media/msm_camera.h b/drivers/staging/dream/include/media/msm_camera.h new file mode 100644 index 0000000..09812d6 --- /dev/null +++ b/drivers/staging/dream/include/media/msm_camera.h @@ -0,0 +1,388 @@ +/* + * Copyright (C) 2008-2009 QUALCOMM Incorporated. + */ +#ifndef __LINUX_MSM_CAMERA_H +#define __LINUX_MSM_CAMERA_H + +#include <linux/types.h> +#include <asm/sizes.h> +#include <linux/ioctl.h> + +#define MSM_CAM_IOCTL_MAGIC 'm' + +#define MSM_CAM_IOCTL_GET_SENSOR_INFO \ + _IOR(MSM_CAM_IOCTL_MAGIC, 1, struct msm_camsensor_info *) + +#define MSM_CAM_IOCTL_REGISTER_PMEM \ + _IOW(MSM_CAM_IOCTL_MAGIC, 2, struct msm_pmem_info *) + +#define MSM_CAM_IOCTL_UNREGISTER_PMEM \ + _IOW(MSM_CAM_IOCTL_MAGIC, 3, unsigned) + +#define MSM_CAM_IOCTL_CTRL_COMMAND \ + _IOW(MSM_CAM_IOCTL_MAGIC, 4, struct msm_ctrl_cmd *) + +#define MSM_CAM_IOCTL_CONFIG_VFE \ + _IOW(MSM_CAM_IOCTL_MAGIC, 5, struct msm_camera_vfe_cfg_cmd *) + +#define MSM_CAM_IOCTL_GET_STATS \ + _IOR(MSM_CAM_IOCTL_MAGIC, 6, struct msm_camera_stats_event_ctrl *) + +#define MSM_CAM_IOCTL_GETFRAME \ + _IOR(MSM_CAM_IOCTL_MAGIC, 7, struct msm_camera_get_frame *) + +#define MSM_CAM_IOCTL_ENABLE_VFE \ + _IOW(MSM_CAM_IOCTL_MAGIC, 8, struct camera_enable_cmd *) + +#define MSM_CAM_IOCTL_CTRL_CMD_DONE \ + _IOW(MSM_CAM_IOCTL_MAGIC, 9, struct camera_cmd *) + +#define MSM_CAM_IOCTL_CONFIG_CMD \ + _IOW(MSM_CAM_IOCTL_MAGIC, 10, struct camera_cmd *) + +#define MSM_CAM_IOCTL_DISABLE_VFE \ + _IOW(MSM_CAM_IOCTL_MAGIC, 11, struct camera_enable_cmd *) + +#define MSM_CAM_IOCTL_PAD_REG_RESET2 \ + _IOW(MSM_CAM_IOCTL_MAGIC, 12, struct camera_enable_cmd *) + +#define MSM_CAM_IOCTL_VFE_APPS_RESET \ + _IOW(MSM_CAM_IOCTL_MAGIC, 13, struct camera_enable_cmd *) + +#define MSM_CAM_IOCTL_RELEASE_FRAME_BUFFER \ + _IOW(MSM_CAM_IOCTL_MAGIC, 14, struct camera_enable_cmd *) + +#define MSM_CAM_IOCTL_RELEASE_STATS_BUFFER \ + _IOW(MSM_CAM_IOCTL_MAGIC, 15, struct msm_stats_buf *) + +#define MSM_CAM_IOCTL_AXI_CONFIG \ + _IOW(MSM_CAM_IOCTL_MAGIC, 16, struct msm_camera_vfe_cfg_cmd *) + +#define MSM_CAM_IOCTL_GET_PICTURE \ + _IOW(MSM_CAM_IOCTL_MAGIC, 17, struct msm_camera_ctrl_cmd *) + +#define MSM_CAM_IOCTL_SET_CROP \ + _IOW(MSM_CAM_IOCTL_MAGIC, 18, struct crop_info *) + +#define MSM_CAM_IOCTL_PICT_PP \ + _IOW(MSM_CAM_IOCTL_MAGIC, 19, uint8_t *) + +#define MSM_CAM_IOCTL_PICT_PP_DONE \ + _IOW(MSM_CAM_IOCTL_MAGIC, 20, struct msm_snapshot_pp_status *) + +#define MSM_CAM_IOCTL_SENSOR_IO_CFG \ + _IOW(MSM_CAM_IOCTL_MAGIC, 21, struct sensor_cfg_data *) + +#define MSM_CAMERA_LED_OFF 0 +#define MSM_CAMERA_LED_LOW 1 +#define MSM_CAMERA_LED_HIGH 2 + +#define MSM_CAM_IOCTL_FLASH_LED_CFG \ + _IOW(MSM_CAM_IOCTL_MAGIC, 22, unsigned *) + +#define MSM_CAM_IOCTL_UNBLOCK_POLL_FRAME \ + _IO(MSM_CAM_IOCTL_MAGIC, 23) + +#define MSM_CAM_IOCTL_CTRL_COMMAND_2 \ + _IOW(MSM_CAM_IOCTL_MAGIC, 24, struct msm_ctrl_cmd *) + +#define MAX_SENSOR_NUM 3 +#define MAX_SENSOR_NAME 32 + +#define MSM_CAM_CTRL_CMD_DONE 0 +#define MSM_CAM_SENSOR_VFE_CMD 1 + +/***************************************************** + * structure + *****************************************************/ + +/* define five type of structures for userspace <==> kernel + * space communication: + * command 1 - 2 are from userspace ==> kernel + * command 3 - 4 are from kernel ==> userspace + * + * 1. control command: control command(from control thread), + * control status (from config thread); + */ +struct msm_ctrl_cmd { + uint16_t type; + uint16_t length; + void *value; + uint16_t status; + uint32_t timeout_ms; + int resp_fd; /* FIXME: to be used by the kernel, pass-through for now */ +}; + +struct msm_vfe_evt_msg { + unsigned short type; /* 1 == event (RPC), 0 == message (adsp) */ + unsigned short msg_id; + unsigned int len; /* size in, number of bytes out */ + void *data; +}; + +#define MSM_CAM_RESP_CTRL 0 +#define MSM_CAM_RESP_STAT_EVT_MSG 1 +#define MSM_CAM_RESP_V4L2 2 +#define MSM_CAM_RESP_MAX 3 + +/* this one is used to send ctrl/status up to config thread */ +struct msm_stats_event_ctrl { + /* 0 - ctrl_cmd from control thread, + * 1 - stats/event kernel, + * 2 - V4L control or read request */ + int resptype; + int timeout_ms; + struct msm_ctrl_cmd ctrl_cmd; + /* struct vfe_event_t stats_event; */ + struct msm_vfe_evt_msg stats_event; +}; + +/* 2. config command: config command(from config thread); */ +struct msm_camera_cfg_cmd { + /* what to config: + * 1 - sensor config, 2 - vfe config */ + uint16_t cfg_type; + + /* sensor config type */ + uint16_t cmd_type; + uint16_t queue; + uint16_t length; + void *value; +}; + +#define CMD_GENERAL 0 +#define CMD_AXI_CFG_OUT1 1 +#define CMD_AXI_CFG_SNAP_O1_AND_O2 2 +#define CMD_AXI_CFG_OUT2 3 +#define CMD_PICT_T_AXI_CFG 4 +#define CMD_PICT_M_AXI_CFG 5 +#define CMD_RAW_PICT_AXI_CFG 6 +#define CMD_STATS_AXI_CFG 7 +#define CMD_STATS_AF_AXI_CFG 8 +#define CMD_FRAME_BUF_RELEASE 9 +#define CMD_PREV_BUF_CFG 10 +#define CMD_SNAP_BUF_RELEASE 11 +#define CMD_SNAP_BUF_CFG 12 +#define CMD_STATS_DISABLE 13 +#define CMD_STATS_ENABLE 14 +#define CMD_STATS_AF_ENABLE 15 +#define CMD_STATS_BUF_RELEASE 16 +#define CMD_STATS_AF_BUF_RELEASE 17 +#define UPDATE_STATS_INVALID 18 + +/* vfe config command: config command(from config thread)*/ +struct msm_vfe_cfg_cmd { + int cmd_type; + uint16_t length; + void *value; +}; + +#define MAX_CAMERA_ENABLE_NAME_LEN 32 +struct camera_enable_cmd { + char name[MAX_CAMERA_ENABLE_NAME_LEN]; +}; + +#define MSM_PMEM_OUTPUT1 0 +#define MSM_PMEM_OUTPUT2 1 +#define MSM_PMEM_OUTPUT1_OUTPUT2 2 +#define MSM_PMEM_THUMBAIL 3 +#define MSM_PMEM_MAINIMG 4 +#define MSM_PMEM_RAW_MAINIMG 5 +#define MSM_PMEM_AEC_AWB 6 +#define MSM_PMEM_AF 7 +#define MSM_PMEM_MAX 8 + +#define FRAME_PREVIEW_OUTPUT1 0 +#define FRAME_PREVIEW_OUTPUT2 1 +#define FRAME_SNAPSHOT 2 +#define FRAME_THUMBAIL 3 +#define FRAME_RAW_SNAPSHOT 4 +#define FRAME_MAX 5 + +struct msm_pmem_info { + int type; + int fd; + void *vaddr; + uint32_t y_off; + uint32_t cbcr_off; + uint8_t active; +}; + +struct outputCfg { + uint32_t height; + uint32_t width; + + uint32_t window_height_firstline; + uint32_t window_height_lastline; +}; + +#define OUTPUT_1 0 +#define OUTPUT_2 1 +#define OUTPUT_1_AND_2 2 +#define CAMIF_TO_AXI_VIA_OUTPUT_2 3 +#define OUTPUT_1_AND_CAMIF_TO_AXI_VIA_OUTPUT_2 4 +#define OUTPUT_2_AND_CAMIF_TO_AXI_VIA_OUTPUT_1 5 +#define LAST_AXI_OUTPUT_MODE_ENUM = OUTPUT_2_AND_CAMIF_TO_AXI_VIA_OUTPUT_1 6 + +#define MSM_FRAME_PREV_1 0 +#define MSM_FRAME_PREV_2 1 +#define MSM_FRAME_ENC 2 + +struct msm_frame { + int path; + unsigned long buffer; + uint32_t y_off; + uint32_t cbcr_off; + int fd; + + void *cropinfo; + int croplen; +}; + +#define STAT_AEAW 0 +#define STAT_AF 1 +#define STAT_MAX 2 + +struct msm_stats_buf { + int type; + unsigned long buffer; + int fd; +}; + +#define MSM_V4L2_VID_CAP_TYPE 0 +#define MSM_V4L2_STREAM_ON 1 +#define MSM_V4L2_STREAM_OFF 2 +#define MSM_V4L2_SNAPSHOT 3 +#define MSM_V4L2_QUERY_CTRL 4 +#define MSM_V4L2_GET_CTRL 5 +#define MSM_V4L2_SET_CTRL 6 +#define MSM_V4L2_QUERY 7 +#define MSM_V4L2_MAX 8 + +struct crop_info { + void *info; + int len; +}; + +struct msm_postproc { + int ftnum; + struct msm_frame fthumnail; + int fmnum; + struct msm_frame fmain; +}; + +struct msm_snapshot_pp_status { + void *status; +}; + +#define CFG_SET_MODE 0 +#define CFG_SET_EFFECT 1 +#define CFG_START 2 +#define CFG_PWR_UP 3 +#define CFG_PWR_DOWN 4 +#define CFG_WRITE_EXPOSURE_GAIN 5 +#define CFG_SET_DEFAULT_FOCUS 6 +#define CFG_MOVE_FOCUS 7 +#define CFG_REGISTER_TO_REAL_GAIN 8 +#define CFG_REAL_TO_REGISTER_GAIN 9 +#define CFG_SET_FPS 10 +#define CFG_SET_PICT_FPS 11 +#define CFG_SET_BRIGHTNESS 12 +#define CFG_SET_CONTRAST 13 +#define CFG_SET_ZOOM 14 +#define CFG_SET_EXPOSURE_MODE 15 +#define CFG_SET_WB 16 +#define CFG_SET_ANTIBANDING 17 +#define CFG_SET_EXP_GAIN 18 +#define CFG_SET_PICT_EXP_GAIN 19 +#define CFG_SET_LENS_SHADING 20 +#define CFG_GET_PICT_FPS 21 +#define CFG_GET_PREV_L_PF 22 +#define CFG_GET_PREV_P_PL 23 +#define CFG_GET_PICT_L_PF 24 +#define CFG_GET_PICT_P_PL 25 +#define CFG_GET_AF_MAX_STEPS 26 +#define CFG_GET_PICT_MAX_EXP_LC 27 +#define CFG_MAX 28 + +#define MOVE_NEAR 0 +#define MOVE_FAR 1 + +#define SENSOR_PREVIEW_MODE 0 +#define SENSOR_SNAPSHOT_MODE 1 +#define SENSOR_RAW_SNAPSHOT_MODE 2 + +#define SENSOR_QTR_SIZE 0 +#define SENSOR_FULL_SIZE 1 +#define SENSOR_INVALID_SIZE 2 + +#define CAMERA_EFFECT_OFF 0 +#define CAMERA_EFFECT_MONO 1 +#define CAMERA_EFFECT_NEGATIVE 2 +#define CAMERA_EFFECT_SOLARIZE 3 +#define CAMERA_EFFECT_PASTEL 4 +#define CAMERA_EFFECT_MOSAIC 5 +#define CAMERA_EFFECT_RESIZE 6 +#define CAMERA_EFFECT_SEPIA 7 +#define CAMERA_EFFECT_POSTERIZE 8 +#define CAMERA_EFFECT_WHITEBOARD 9 +#define CAMERA_EFFECT_BLACKBOARD 10 +#define CAMERA_EFFECT_AQUA 11 +#define CAMERA_EFFECT_MAX 12 + +struct sensor_pict_fps { + uint16_t prevfps; + uint16_t pictfps; +}; + +struct exp_gain_cfg { + uint16_t gain; + uint32_t line; +}; + +struct focus_cfg { + int32_t steps; + int dir; +}; + +struct fps_cfg { + uint16_t f_mult; + uint16_t fps_div; + uint32_t pict_fps_div; +}; + +struct sensor_cfg_data { + int cfgtype; + int mode; + int rs; + uint8_t max_steps; + + union { + int8_t effect; + uint8_t lens_shading; + uint16_t prevl_pf; + uint16_t prevp_pl; + uint16_t pictl_pf; + uint16_t pictp_pl; + uint32_t pict_max_exp_lc; + uint16_t p_fps; + struct sensor_pict_fps gfps; + struct exp_gain_cfg exp_gain; + struct focus_cfg focus; + struct fps_cfg fps; + } cfg; +}; + +#define GET_NAME 0 +#define GET_PREVIEW_LINE_PER_FRAME 1 +#define GET_PREVIEW_PIXELS_PER_LINE 2 +#define GET_SNAPSHOT_LINE_PER_FRAME 3 +#define GET_SNAPSHOT_PIXELS_PER_LINE 4 +#define GET_SNAPSHOT_FPS 5 +#define GET_SNAPSHOT_MAX_EP_LINE_CNT 6 + +struct msm_camsensor_info { + char name[MAX_SENSOR_NAME]; + uint8_t flash_enabled; +}; +#endif /* __LINUX_MSM_CAMERA_H */ diff --git a/drivers/staging/dream/pmem.c b/drivers/staging/dream/pmem.c index def6468..503ba21 100644 --- a/drivers/staging/dream/pmem.c +++ b/drivers/staging/dream/pmem.c @@ -37,17 +37,17 @@ * the file should not be released until put_pmem_file is called */ #define PMEM_FLAGS_BUSY 0x1 /* indicates that this is a suballocation of a larger master range */ -#define PMEM_FLAGS_CONNECTED 0x1 << 1 +#define PMEM_FLAGS_CONNECTED ( 0x1 << 1 ) /* indicates this is a master and not a sub allocation and that it is mmaped */ -#define PMEM_FLAGS_MASTERMAP 0x1 << 2 +#define PMEM_FLAGS_MASTERMAP ( 0x1 << 2 ) /* submap and unsubmap flags indicate: * 00: subregion has never been mmaped * 10: subregion has been mmaped, reference to the mm was taken * 11: subretion has ben released, refernece to the mm still held * 01: subretion has been released, reference to the mm has been released */ -#define PMEM_FLAGS_SUBMAP 0x1 << 3 -#define PMEM_FLAGS_UNSUBMAP 0x1 << 4 +#define PMEM_FLAGS_SUBMAP ( 0x1 << 3 ) +#define PMEM_FLAGS_UNSUBMAP ( 0x1 << 4 ) struct pmem_data { @@ -91,7 +91,7 @@ struct pmem_region_node { #define PMEM_DEBUG_MSGS 0 #if PMEM_DEBUG_MSGS -#define DLOG(fmt,args...) \ +#define DLOG(fmt, args...) \ do { printk(KERN_INFO "[%s:%s:%d] "fmt, __FILE__, __func__, __LINE__, \ ##args); } \ while (0) @@ -152,7 +152,7 @@ struct pmem_info { static struct pmem_info pmem[PMEM_MAX_DEVICES]; static int id_count; -#define PMEM_IS_FREE(id, index) !(pmem[id].bitmap[index].allocated) +#define PMEM_IS_FREE(id, index) ( !(pmem[id].bitmap[index].allocated) ) #define PMEM_ORDER(id, index) pmem[id].bitmap[index].order #define PMEM_BUDDY_INDEX(id, index) (index ^ (1 << PMEM_ORDER(id, index))) #define PMEM_NEXT_INDEX(id, index) (index + (1 << PMEM_ORDER(id, index))) @@ -708,9 +708,8 @@ int get_pmem_addr(struct file *file, unsigned long *start, struct pmem_data *data; int id; - if (!is_pmem_file(file) || !has_allocation(file)) { + if (!is_pmem_file(file) || !has_allocation(file)) return -1; - } data = (struct pmem_data *)file->private_data; if (data->index == -1) { @@ -789,9 +788,8 @@ void flush_pmem_file(struct file *file, unsigned long offset, unsigned long len) struct list_head *elt; void *flush_start, *flush_end; - if (!is_pmem_file(file) || !has_allocation(file)) { + if (!is_pmem_file(file) || !has_allocation(file)) return; - } id = get_id(file); data = (struct pmem_data *)file->private_data; @@ -833,7 +831,7 @@ static int pmem_connect(unsigned long connect, struct file *file) src_file = fget_light(connect, &put_needed); DLOG("connect %p to %p\n", file, src_file); if (!src_file) { - printk("pmem: src file not found!\n"); + printk(KERN_INFO "pmem: src file not found!\n"); ret = -EINVAL; goto err_no_file; } @@ -846,7 +844,7 @@ static int pmem_connect(unsigned long connect, struct file *file) src_data = (struct pmem_data *)src_file->private_data; if (has_allocation(file) && (data->index != src_data->index)) { - printk("pmem: file is already mapped but doesn't match this" + printk(KERN_INFO "pmem: file is already mapped but doesn't match this" " src_file!\n"); ret = -EINVAL; goto err_bad_file; @@ -885,7 +883,7 @@ lock_mm: mm = get_task_mm(data->task); if (!mm) { #if PMEM_DEBUG - printk("pmem: can't remap task is gone!\n"); + printk(KERN_DEBUG "pmem: can't remap task is gone!\n"); #endif up_read(&data->sem); return -1; @@ -936,7 +934,7 @@ int pmem_remap(struct pmem_region *region, struct file *file, if (unlikely(!PMEM_IS_PAGE_ALIGNED(region->offset) || !PMEM_IS_PAGE_ALIGNED(region->len))) { #if PMEM_DEBUG - printk("pmem: request for unaligned pmem suballocation " + printk(KERN_DEBUG "pmem: request for unaligned pmem suballocation " "%lx %lx\n", region->offset, region->len); #endif return -EINVAL; diff --git a/drivers/staging/dream/qdsp5/Makefile b/drivers/staging/dream/qdsp5/Makefile index 991d4a7..beedaaf 100644 --- a/drivers/staging/dream/qdsp5/Makefile +++ b/drivers/staging/dream/qdsp5/Makefile @@ -1,3 +1,4 @@ +EXTRA_CFLAGS=-Idrivers/staging/dream/include obj-y += adsp.o ifeq ($(CONFIG_MSM_AMSS_VERSION_6350),y) obj-y += adsp_info.o diff --git a/drivers/staging/dream/qdsp5/audio_mp3.c b/drivers/staging/dream/qdsp5/audio_mp3.c index b95574f..7ed6e26 100644 --- a/drivers/staging/dream/qdsp5/audio_mp3.c +++ b/drivers/staging/dream/qdsp5/audio_mp3.c @@ -650,8 +650,7 @@ static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) &audio->read_phys, GFP_KERNEL); if (!audio->read_data) { - pr_err("audio_mp3: malloc pcm \ - buf failed\n"); + pr_err("audio_mp3: malloc pcm buf failed\n"); rc = -1; } else { uint8_t index; diff --git a/drivers/staging/dream/smd/Makefile b/drivers/staging/dream/smd/Makefile index 892c741..1c87618 100644 --- a/drivers/staging/dream/smd/Makefile +++ b/drivers/staging/dream/smd/Makefile @@ -1,3 +1,4 @@ +EXTRA_CFLAGS=-Idrivers/staging/dream/include obj-$(CONFIG_MSM_SMD) += smd.o smd_tty.o smd_qmi.o obj-$(CONFIG_MSM_ONCRPCROUTER) += smd_rpcrouter.o obj-$(CONFIG_MSM_ONCRPCROUTER) += smd_rpcrouter_device.o diff --git a/drivers/staging/dream/smd/smd_rpcrouter.c b/drivers/staging/dream/smd/smd_rpcrouter.c index 5ac2cd4..69911a7 100644 --- a/drivers/staging/dream/smd/smd_rpcrouter.c +++ b/drivers/staging/dream/smd/smd_rpcrouter.c @@ -38,8 +38,6 @@ #include <linux/platform_device.h> #include <linux/uaccess.h> -#include <asm/byteorder.h> - #include <mach/msm_smd.h> #include "smd_rpcrouter.h" diff --git a/drivers/staging/dt3155/Kconfig b/drivers/staging/dt3155/Kconfig new file mode 100644 index 0000000..4a3293c --- /dev/null +++ b/drivers/staging/dt3155/Kconfig @@ -0,0 +1,4 @@ +config DT3155 + tristate "DT3155 Digitizer support" + depends on PCI + diff --git a/drivers/staging/dt3155/Makefile b/drivers/staging/dt3155/Makefile new file mode 100644 index 0000000..136f21f --- /dev/null +++ b/drivers/staging/dt3155/Makefile @@ -0,0 +1,6 @@ +obj-$(CONFIG_DT3155) += dt3155.o +dt3155-objs := \ + dt3155_drv.o \ + dt3155_isr.o \ + dt3155_io.o \ + allocator.o diff --git a/drivers/staging/dt3155/TODO b/drivers/staging/dt3155/TODO new file mode 100644 index 0000000..3baa3b6 --- /dev/null +++ b/drivers/staging/dt3155/TODO @@ -0,0 +1,10 @@ +TODO: + - fix checkpatch.pl issues + - remove old kernel support, it is not needed + - convert to proper PCI device API + - fix sparse warnings + - audit for correct subsystem interaction + - review review review! + +Please send patches to Greg Kroah-Hartman <greg@kroah.com> +and Scott Smedley <ss@aao.gov.au> diff --git a/drivers/staging/dt3155/allocator.README b/drivers/staging/dt3155/allocator.README new file mode 100644 index 0000000..05700b6 --- /dev/null +++ b/drivers/staging/dt3155/allocator.README @@ -0,0 +1,98 @@ + +The allocator shown here exploits high memory. This document explains +how a user can deal with drivers uses this allocator and how a +programmer can link in the module. + +The module is being used by my pxc and pxdrv device drivers (as well as +other ones), available from ftp.systemy.it/pub/develop and +ftp.linux.it/pub/People/Rubini + + User's manual + ============= + + +One of the most compelling problems with any DMA-capable device is the +allocation of a suitable memory buffer. The "allocator" module tries +to deal with the problem in a clean way. The module is able to use +high memory (above the one used in normal operation) for DMA +allocation. + +To prevent the kernel for using high memory, so that it remains +available for DMA, you should pass a command line argument to the +kernel. Command line arguments can be passed to Lilo, to Loadlin or +to whichever loader you are using (unless it's very poor in design). +For Lilo, either use "append=" in /etc/lilo.conf or add commandline +arguments to the interactive prompt. For example, I have a 32MB box +and reserve two megs for DMA: + +In lilo.conf: + image = /zImage + label = linux + append = "mem=30M" + +Or, interactively: + LILO: linux mem=30M + +Once the kernel is booted with the right command-line argument, any +driver linked with the allocator module will be able to get +DMA-capable memory without much trouble (unless the various drivers +need more memory than available). + +The module implements an alloc/free mechanism, so that it can serve +multiple drivers at the same time. Note however that the allocator +uses all of high memory and assumes to be the only piece of software +using such memory. + + + Programmer's manual + =================== + +The allocator, as released, is designed to be linked to a device +driver. In this case, the driver must call allocator_init() before +using the allocator and must call allocator_cleanup() before +unloading. This is usually done from within init_module() and +cleanup_module(). If the allocator is linked to a driver, it won't be +possible for several drivers to allocate high DMA memory, as explained +above. + +It is possible, on the other hand, to compile the module as a standalone +module, so that several modules can rely on the allocator for they DMA +buffers. To compile the allocator as a standalone module, do the +following in this directory (or provide a suitable Makefile, or edit +the source code): + + make allocator.o CC="gcc -Dallocator_init=init_module -Dallocator_cleanup=cleanup_module -include /usr/include/linux/module.h" + +The previous commandline tells to include <linux/module.h> in the +first place, and to rename the init and cleanup function to the ones +needed for module loading and unloading. Drivers using a standalone +allocator won't need to call allocator_init() nor allocator_cleanup(). + +The allocator exports the following functions (declared in allocator.h): + + unsigned long allocator_allocate_dma (unsigned long kilobytes, + int priority); + + This function returns a physical address, over high_memory, + which corresponds to an area of at least "kilobytes" kilobytes. + The area will be owned by the module calling the function. + The returned address can be passed to device boards, to instruct + their DMA controllers, via phys_to_bus(). The address can be used + by C code after vremap()/ioremap(). The "priority" argument should + be GFP_KERNEL or GFP_ATOMIC, according to the context of the + caller; it is used to call kmalloc(), as the allocator must keep + track of any region it gives away. In case of error the function + returns 0, and the caller is expected to issue a -ENOMEM error. + + + void allocator_free_dma (unsigned long address); + + This function is the reverse of the previous one. If a driver + doesn't free the DMA memory it allocated, the allocator will + consider such memory as busy. Note, however, that + allocator_cleanup() calls kfree() on every region it reclaimed, + so that a driver with the allocator linked in can avoid calling + allocator_free_dma() at unload time. + + + diff --git a/drivers/staging/dt3155/allocator.c b/drivers/staging/dt3155/allocator.c new file mode 100644 index 0000000..c74234c --- /dev/null +++ b/drivers/staging/dt3155/allocator.c @@ -0,0 +1,295 @@ +/* + * allocator.c -- allocate after high_memory, if available + * + * NOTE: this is different from my previous allocator, the one that + * assembles pages, which revealed itself both slow and unreliable. + * + * Copyright (C) 1998 rubini@linux.it (Alessandro Rubini) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + +-- Changes -- + + Date Programmer Description of changes made + ------------------------------------------------------------------- + 02-Aug-2002 NJC allocator now steps in 1MB increments, rather + than doubling its size each time. + Also, allocator_init(u32 *) now returns + (in the first arg) the size of the free + space. This is no longer consistent with + using the allocator as a module, and some changes + may be necessary for that purpose. This was + designed to work with the DT3155 driver, in + stand alone mode only!!! + 26-Oct-2009 SS Port to 2.6.30 kernel. + */ + + +#ifndef __KERNEL__ +# define __KERNEL__ +#endif +#ifndef MODULE +# define MODULE +#endif + +#include <linux/version.h> + +#include <linux/sched.h> +#include <linux/kernel.h> +#include <linux/fs.h> +#include <linux/proc_fs.h> +#include <linux/errno.h> +#include <linux/types.h> +#include <linux/mm.h> /* PAGE_ALIGN() */ +#include <linux/io.h> + +#include <asm/page.h> + +/*#define ALL_DEBUG*/ +#define ALL_MSG "allocator: " + +#undef PDEBUG /* undef it, just in case */ +#ifdef ALL_DEBUG +# define __static +# define DUMP_LIST() dump_list() +# ifdef __KERNEL__ + /* This one if debugging is on, and kernel space */ +# define PDEBUG(fmt, args...) printk(KERN_DEBUG ALL_MSG fmt, ## args) +# else + /* This one for user space */ +# define PDEBUG(fmt, args...) fprintf(stderr, fmt, ## args) +# endif +#else +# define PDEBUG(fmt, args...) /* not debugging: nothing */ +# define DUMP_LIST() +# define __static static +#endif + +#undef PDEBUGG +#define PDEBUGG(fmt, args...) +/*#define PDEBUGG(fmt, args...) printk( KERN_DEBUG ALL_MSG fmt, ## args)*/ + + +int allocator_himem = 1; /* 0 = probe, pos. = megs, neg. = disable */ +int allocator_step = 1; /* This is the step size in MB */ +int allocator_probe = 1; /* This is a flag -- 1=probe, 0=don't probe */ + +static unsigned long allocator_buffer; /* physical address */ +static unsigned long allocator_buffer_size; /* kilobytes */ + +/* + * The allocator keeps a list of DMA areas, so multiple devices + * can coexist. The list is kept sorted by address + */ + +struct allocator_struct { + unsigned long address; + unsigned long size; + struct allocator_struct *next; +}; + +struct allocator_struct *allocator_list; + + +#ifdef ALL_DEBUG +static int dump_list(void) +{ + struct allocator_struct *ptr; + + PDEBUG("Current list:\n"); + for (ptr = allocator_list; ptr; ptr = ptr->next) + PDEBUG("0x%08lx (size %likB)\n", ptr->address, ptr->size>>10); + return 0; +} +#endif + +/* ======================================================================== + * This function is the actual allocator. + * + * If space is available in high memory (as detected at load time), that + * one is returned. The return value is a physical address (i.e., it can + * be used straight ahead for DMA, but needs remapping for program use). + */ + +unsigned long allocator_allocate_dma(unsigned long kilobytes, int prio) +{ + struct allocator_struct *ptr = allocator_list, *newptr; + unsigned long bytes = kilobytes << 10; + + /* check if high memory is available */ + if (!allocator_buffer) + return 0; + + /* Round it to a multiple of the pagesize */ + bytes = PAGE_ALIGN(bytes); + PDEBUG("request for %li bytes\n", bytes); + + while (ptr && ptr->next) { + if (ptr->next->address - (ptr->address + ptr->size) >= bytes) + break; /* enough space */ + ptr = ptr->next; + } + if (!ptr->next) { + DUMP_LIST(); + PDEBUG("alloc failed\n"); + return 0; /* end of list */ + } + newptr = kmalloc(sizeof(struct allocator_struct), prio); + if (!newptr) + return 0; + + /* ok, now stick it after ptr */ + newptr->address = ptr->address + ptr->size; + newptr->size = bytes; + newptr->next = ptr->next; + ptr->next = newptr; + + DUMP_LIST(); + PDEBUG("returning 0x%08lx\n", newptr->address); + return newptr->address; +} + +int allocator_free_dma(unsigned long address) +{ + struct allocator_struct *ptr = allocator_list, *prev; + + while (ptr && ptr->next) { + if (ptr->next->address == address) + break; + ptr = ptr->next; + } + /* the one being freed is ptr->next */ + prev = ptr; ptr = ptr->next; + + if (!ptr) { + printk(KERN_ERR ALL_MSG + "free_dma(0x%08lx) but add. not allocated\n", + ptr->address); + return -EINVAL; + } + PDEBUGG("freeing: %08lx (%li) next %08lx\n", ptr->address, ptr->size, + ptr->next->address); + prev->next = ptr->next; + kfree(ptr); + + /* dump_list(); */ + return 0; +} + +/* ======================================================================== + * Init and cleanup + * + * On cleanup everything is released. If the list is not empty, that a + * problem of our clients + */ +int allocator_init(u32 *allocator_max) +{ + /* check how much free memory is there */ + void *remapped; + unsigned long max; + unsigned long trial_size = allocator_himem<<20; + unsigned long last_trial = 0; + unsigned long step = allocator_step<<20; + unsigned long i = 0; + struct allocator_struct *head, *tail; + char test_string[] = "0123456789abcde"; /* 16 bytes */ + + PDEBUGG("himem = %i\n", allocator_himem); + if (allocator_himem < 0) /* don't even try */ + return -EINVAL; + + if (!trial_size) + trial_size = 1<<20; /* not specified: try one meg */ + + while (1) { + remapped = ioremap(__pa(high_memory), trial_size); + if (!remapped) { + PDEBUGG("%li megs failed!\n", trial_size>>20); + break; + } + PDEBUGG("Trying %li megs (at %p, %p)\n", trial_size>>20, + (void *)__pa(high_memory), remapped); + for (i = last_trial; i < trial_size; i += 16) { + strcpy((char *)(remapped)+i, test_string); + if (strcmp((char *)(remapped)+i, test_string)) + break; + } + iounmap((void *)remapped); + schedule(); + last_trial = trial_size; + if (i == trial_size) + trial_size += step; /* increment, if all went well */ + else { + PDEBUGG("%li megs copy test failed!\n", trial_size>>20); + break; + } + if (!allocator_probe) + break; + } + PDEBUG("%li megs (%li k, %li b)\n", i>>20, i>>10, i); + allocator_buffer_size = i>>10; /* kilobytes */ + allocator_buffer = __pa(high_memory); + if (!allocator_buffer_size) { + printk(KERN_WARNING ALL_MSG "no free high memory to use\n"); + return -ENOMEM; + } + + /* + * to simplify things, always have two cells in the list: + * the first and the last. This avoids some conditionals and + * extra code when allocating and deallocating: we only play + * in the middle of the list + */ + head = kmalloc(sizeof(struct allocator_struct), GFP_KERNEL); + if (!head) + return -ENOMEM; + tail = kmalloc(sizeof(struct allocator_struct), GFP_KERNEL); + if (!tail) { + kfree(head); + return -ENOMEM; + } + + max = allocator_buffer_size<<10; + + head->size = tail->size = 0; + head->address = allocator_buffer; + tail->address = allocator_buffer + max; + head->next = tail; + tail->next = NULL; + allocator_list = head; + + /* Back to the user code, in KB */ + *allocator_max = allocator_buffer_size; + + return 0; /* ok, ready */ +} + +void allocator_cleanup(void) +{ + struct allocator_struct *ptr, *next; + + for (ptr = allocator_list; ptr; ptr = next) { + next = ptr->next; + PDEBUG("freeing list: 0x%08lx\n", ptr->address); + kfree(ptr); + } + + allocator_buffer = 0; + allocator_buffer_size = 0; + allocator_list = NULL; +} + + diff --git a/drivers/staging/dt3155/allocator.h b/drivers/staging/dt3155/allocator.h new file mode 100644 index 0000000..bdf3268 --- /dev/null +++ b/drivers/staging/dt3155/allocator.h @@ -0,0 +1,28 @@ +/* + * allocator.h -- prototypes for allocating high memory + * + * NOTE: this is different from my previous allocator, the one that + * assembles pages, which revealed itself both slow and unreliable. + * + * Copyright (C) 1998 rubini@linux.it (Alessandro Rubini) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +void allocator_free_dma(unsigned long address); +unsigned long allocator_allocate_dma(unsigned long kilobytes, int priority); +int allocator_init(u32 *); +void allocator_cleanup(void); diff --git a/drivers/staging/dt3155/dt3155.h b/drivers/staging/dt3155/dt3155.h new file mode 100644 index 0000000..1bf7863 --- /dev/null +++ b/drivers/staging/dt3155/dt3155.h @@ -0,0 +1,171 @@ +/* + +Copyright 1996,2002,2005 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan, + Jason Lapenta, Scott Smedley + +This file is part of the DT3155 Device Driver. + +The DT3155 Device Driver is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The DT3155 Device Driver is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty +of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with the DT3155 Device Driver; if not, write to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +MA 02111-1307 USA + +-- Changes -- + + Date Programmer Description of changes made + ------------------------------------------------------------------- + 03-Jul-2000 JML n/a + 10-Oct-2001 SS port to 2.4 kernel. + 24-Jul-2002 SS remove unused code & added GPL licence. + 05-Aug-2005 SS port to 2.6 kernel; make CCIR mode default. + +*/ + +#ifndef _DT3155_INC +#define _DT3155_INC + +#ifdef __KERNEL__ +#include <linux/types.h> +#include <linux/time.h> /* struct timeval */ +#else +#include <sys/ioctl.h> +#include <sys/param.h> +#include <sys/time.h> +#include <unistd.h> +#endif + + +#define TRUE 1 +#define FALSE 0 + +/* Uncomment this for 50Hz CCIR */ +#define CCIR 1 + +/* Can be 1 or 2 */ +#define MAXBOARDS 1 + +#define BOARD_MAX_BUFFS 3 +#define MAXBUFFERS (BOARD_MAX_BUFFS*MAXBOARDS) + +#define PCI_PAGE_SIZE (1 << 12) + +#ifdef CCIR +#define DT3155_MAX_ROWS 576 +#define DT3155_MAX_COLS 768 +#define FORMAT50HZ TRUE +#else +#define DT3155_MAX_ROWS 480 +#define DT3155_MAX_COLS 640 +#define FORMAT50HZ FALSE +#endif + +/* Configuration structure */ +struct dt3155_config_s { + u32 acq_mode; + u32 cols, rows; + u32 continuous; +}; + + +/* hold data for each frame */ +typedef struct { + u32 addr; /* address of the buffer with the frame */ + u32 tag; /* unique number for the frame */ + struct timeval time; /* time that capture took place */ +} frame_info_t; + +/* + * Structure for interrupt and buffer handling. + * This is the setup for 1 card + */ +struct dt3155_fbuffer_s { + int nbuffers; + + frame_info_t frame_info[BOARD_MAX_BUFFS]; + + int empty_buffers[BOARD_MAX_BUFFS]; /* indexes empty frames */ + int empty_len; /* Number of empty buffers */ + /* Zero means empty */ + + int active_buf; /* Where data is currently dma'ing */ + int locked_buf; /* Buffers used by user */ + + int ready_que[BOARD_MAX_BUFFS]; + u32 ready_head; /* The most recent buffer located here */ + u32 ready_len; /* The number of ready buffers */ + + int even_happened; + int even_stopped; + + int stop_acquire; /* Flag to stop interrupts */ + u32 frame_count; /* Counter for frames acquired by this card */ +}; + + + +#define DT3155_MODE_FRAME 1 +#define DT3155_MODE_FIELD 2 + +#define DT3155_SNAP 1 +#define DT3155_ACQ 2 + +/* There is one status structure for each card. */ +typedef struct dt3155_status_s { + int fixed_mode; /* if 1, we are in fixed frame mode */ + u32 reg_addr; /* Register address for a single card */ + u32 mem_addr; /* Buffer start addr for this card */ + u32 mem_size; /* This is the amount of mem available */ + u32 irq; /* this card's irq */ + struct dt3155_config_s config; /* configuration struct */ + struct dt3155_fbuffer_s fbuffer; /* frame buffer state struct */ + u32 state; /* this card's state */ + u32 device_installed; /* Flag if installed. 1=installed */ +} dt3155_status_t; + +/* Reference to global status structure */ +extern struct dt3155_status_s dt3155_status[MAXBOARDS]; + +#define DT3155_STATE_IDLE 0x00 +#define DT3155_STATE_FRAME 0x01 +#define DT3155_STATE_FLD 0x02 +#define DT3155_STATE_STOP 0x100 +#define DT3155_STATE_ERROR 0x200 +#define DT3155_STATE_MODE 0x0ff + +#define DT3155_IOC_MAGIC '!' + +#define DT3155_SET_CONFIG _IOW(DT3155_IOC_MAGIC, 1, struct dt3155_config_s) +#define DT3155_GET_CONFIG _IOR(DT3155_IOC_MAGIC, 2, struct dt3155_status_s) +#define DT3155_STOP _IO(DT3155_IOC_MAGIC, 3) +#define DT3155_START _IO(DT3155_IOC_MAGIC, 4) +#define DT3155_FLUSH _IO(DT3155_IOC_MAGIC, 5) +#define DT3155_IOC_MAXNR 5 + +/* Error codes */ + +#define DT_ERR_NO_BUFFERS 0x10000 /* not used but it might be one day */ +#define DT_ERR_CORRUPT 0x20000 +#define DT_ERR_OVERRUN 0x30000 +#define DT_ERR_I2C_TIMEOUT 0x40000 +#define DT_ERR_MASK 0xff0000/* not used but it might be one day */ + +/* User code will probably want to declare one of these for each card */ +typedef struct dt3155_read_s { + u32 offset; + u32 frame_seq; + u32 state; + + frame_info_t frame_info; +} dt3155_read_t; + +#endif /* _DT3155_inc */ diff --git a/drivers/staging/dt3155/dt3155.sysvinit b/drivers/staging/dt3155/dt3155.sysvinit new file mode 100644 index 0000000..92ec093 --- /dev/null +++ b/drivers/staging/dt3155/dt3155.sysvinit @@ -0,0 +1,60 @@ +#! /bin/sh +# +# Module load/unload script for use with SysV-style /etc/init.d/ systems. +# On a Debian system, copy this to /etc/init.d/dt3155 and then run +# /usr/sbin/update-rc.d dt3155 defaults 55 +# to create the appropriate /etc/rc?.d/[SK]55dt3155 start/stop links. +# (The "55" is arbitrary but is what I use to load this rather late.) +# +# Andy Dougherty Feb 22 2000 doughera@lafayette.edu +# Dept. of Physics +# Lafayette College, Easton PA 18042 +# + +PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin + +# Edit to point to your local copy. +FILE=/usr/local/lib/modules/dt3155/dt3155.o +NAME="dt3155" +DESC="dt3155 Frame Grabber module" +DEV="dt3155" + +if test ! -f $FILE; then + echo "Unable to locate $FILE" + exit 0 +fi + +set -e + +case "$1" in + start) + echo -n "Loading $DESC " + if /sbin/insmod -v -f $FILE; then + major=`grep $DEV /proc/devices | awk "{print \\$1}"` + rm -f /dev/dt3155? + mknod /dev/dt3155a c $major 0 + mknod /dev/dt3155b c $major 1 + chmod go+rw /dev/dt3155? + echo + else + echo "$FILE not loaded." + fi + ;; + stop) + echo -n "Unloading $DESC: " + if /sbin/rmmod $NAME ; then + echo + else + echo "$DEV not removed" + exit 0 + fi + rm -f /dev/dt3155? + ;; + *) + echo "Usage: /etc/init.d/$NAME {start|stop}" + exit 1 + ;; +esac + +exit 0 + diff --git a/drivers/staging/dt3155/dt3155_drv.c b/drivers/staging/dt3155/dt3155_drv.c new file mode 100644 index 0000000..a67c622 --- /dev/null +++ b/drivers/staging/dt3155/dt3155_drv.c @@ -0,0 +1,1095 @@ +/* + +Copyright 1996,2002,2005 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan, + Jason Lapenta, Scott Smedley, Greg Sharp + +This file is part of the DT3155 Device Driver. + +The DT3155 Device Driver is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The DT3155 Device Driver is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty +of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with the DT3155 Device Driver; if not, write to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +MA 02111-1307 USA + +-- Changes -- + + Date Programmer Description of changes made + ------------------------------------------------------------------- + 03-Jul-2000 JML n/a + 10-Oct-2001 SS port to 2.4 kernel + 02-Apr-2002 SS Mods to use allocator as a standalone module; + Merged John Roll's changes (john@cfa.harvard.edu) + to make work with multiple boards. + 02-Jul-2002 SS Merged James Rose's chages (rosejr@purdue.edu) to: + * fix successive interrupt-driven captures + * add select/poll support. + 10-Jul-2002 GCS Add error check when ndevices > MAXBOARDS. + 02-Aug-2002 GCS Fix field mode so that odd (lower) field is stored + in lower half of buffer. + 05-Aug-2005 SS port to 2.6 kernel. + 26-Oct-2009 SS port to 2.6.30 kernel. + +-- Notes -- + +** appended "mem=124" in lilo.conf to allow for 4megs free on my 128meg system. + * using allocator.c and allocator.h from o'reilly book (alessandro rubini) + ftp://ftp.systemy.it/pub/develop (see README.allocator) + + + might want to get rid of MAXboards for allocating initial buffer. + confusing and not necessary + + + in cleanup_module the MOD_IN_USE looks like it is check after it should + + * GFP_DMA should not be set with a PCI system (pg 291) + + - NJC why are only two buffers allowed? (see isr, approx line 358) + +*/ + +extern void printques(int); + +#ifdef MODULE +#include <linux/module.h> +#include <linux/interrupt.h> + + +MODULE_LICENSE("GPL"); + +#endif + +#ifndef CONFIG_PCI +#error "DT3155 : Kernel PCI support not enabled (DT3155 drive requires PCI)" +#endif + +#include <linux/pci.h> +#include <linux/types.h> +#include <linux/poll.h> +#include <linux/sched.h> + +#include <asm/io.h> +#include <asm/uaccess.h> + +#include "dt3155.h" +#include "dt3155_drv.h" +#include "dt3155_isr.h" +#include "dt3155_io.h" +#include "allocator.h" + +/* Error variable. Zero means no error. */ +int dt3155_errno = 0; + +#ifndef PCI_DEVICE_ID_INTEL_7116 +#define PCI_DEVICE_ID_INTEL_7116 0x1223 +#endif + +#define DT3155_VENDORID PCI_VENDOR_ID_INTEL +#define DT3155_DEVICEID PCI_DEVICE_ID_INTEL_7116 +#define MAXPCI 16 + +#ifdef DT_DEBUG +#define DT_3155_DEBUG_MSG(x,y) printk(x,y) +#else +#define DT_3155_DEBUG_MSG(x,y) +#endif + +/* wait queue for interrupts */ +wait_queue_head_t dt3155_read_wait_queue[ MAXBOARDS ]; + +#define DT_3155_SUCCESS 0 +#define DT_3155_FAILURE -EIO + +/* set to dynamicaly allocate, but it is tunable: */ +/* insmod DT_3155 dt3155 dt3155_major=XX */ +int dt3155_major = 0; + +/* The minor numbers are 0 and 1 ... they are not tunable. + * They are used as the indices for the structure vectors, + * and register address vectors + */ + +/* Global structures and variables */ + +/* Status of each device */ +struct dt3155_status_s dt3155_status[ MAXBOARDS ]; + +/* kernel logical address of the board */ +u8 *dt3155_lbase[ MAXBOARDS ] = { NULL +#if MAXBOARDS == 2 + , NULL +#endif +}; +/* DT3155 registers */ +u8 *dt3155_bbase = NULL; /* kernel logical address of the * + * buffer region */ +u32 dt3155_dev_open[ MAXBOARDS ] = {0 +#if MAXBOARDS == 2 + , 0 +#endif +}; + +u32 ndevices = 0; +u32 unique_tag = 0;; + + +/* + * Stops interrupt generation right away and resets the status + * to idle. I don't know why this works and the other way doesn't. + * (James Rose) + */ +static void quick_stop (int minor) +{ + // TODO: scott was here +#if 1 + ReadMReg((dt3155_lbase[ minor ] + INT_CSR), int_csr_r.reg); + /* disable interrupts */ + int_csr_r.fld.FLD_END_EVE_EN = 0; + int_csr_r.fld.FLD_END_ODD_EN = 0; + WriteMReg((dt3155_lbase[ minor ] + INT_CSR), int_csr_r.reg ); + + dt3155_status[ minor ].state &= ~(DT3155_STATE_STOP|0xff); + /* mark the system stopped: */ + dt3155_status[ minor ].state |= DT3155_STATE_IDLE; + dt3155_fbuffer[ minor ]->stop_acquire = 0; + dt3155_fbuffer[ minor ]->even_stopped = 0; +#else + dt3155_status[minor].state |= DT3155_STATE_STOP; + dt3155_status[minor].fbuffer.stop_acquire = 1; +#endif + +} + + +/***************************************************** + * dt3155_isr() Interrupt service routien + * + * - looks like this isr supports IRQ sharing (or could) JML + * - Assumes irq's are disabled, via SA_INTERRUPT flag + * being set in request_irq() call from init_module() + *****************************************************/ +static inline void dt3155_isr( int irq, void *dev_id, struct pt_regs *regs ) +{ + int minor = -1; + int index; + unsigned long flags; + u32 buffer_addr; + + /* find out who issued the interrupt */ + for ( index = 0; index < ndevices; index++ ) { + if( dev_id == (void*) &dt3155_status[ index ]) + { + minor = index; + break; + } + } + + /* hopefully we should not get here */ + if ( minor < 0 || minor >= MAXBOARDS ) { + printk(KERN_ERR "dt3155_isr called with invalid dev_id\n"); + return; + } + + /* Check for corruption and set a flag if so */ + ReadMReg( (dt3155_lbase[ minor ] + CSR1), csr1_r.reg ); + + if ( (csr1_r.fld.FLD_CRPT_EVE) || (csr1_r.fld.FLD_CRPT_ODD) ) + { + /* TODO: this should probably stop acquisition */ + /* and set some flags so that dt3155_read */ + /* returns an error next time it is called */ + dt3155_errno = DT_ERR_CORRUPT; + printk("dt3155: corrupt field\n"); + return; + } + + ReadMReg((dt3155_lbase[ minor ] + INT_CSR), int_csr_r.reg); + + /* Handle the even field ... */ + if (int_csr_r.fld.FLD_END_EVE) + { + if ( (dt3155_status[ minor ].state & DT3155_STATE_MODE) == + DT3155_STATE_FLD ) + { + dt3155_fbuffer[ minor ]->frame_count++; + } + + ReadI2C(dt3155_lbase[ minor ], EVEN_CSR, &i2c_even_csr.reg); + + /* Clear the interrupt? */ + int_csr_r.fld.FLD_END_EVE = 1; + + /* disable the interrupt if last field */ + if (dt3155_fbuffer[ minor ]->stop_acquire) + { + printk("dt3155: even stopped.\n"); + dt3155_fbuffer[ minor ]->even_stopped = 1; + if (i2c_even_csr.fld.SNGL_EVE) + { + int_csr_r.fld.FLD_END_EVE_EN = 0; + } + else + { + i2c_even_csr.fld.SNGL_EVE = 1; + } + } + + WriteMReg( (dt3155_lbase[ minor ] + INT_CSR), int_csr_r.reg ); + + /* Set up next DMA if we are doing FIELDS */ + if ( (dt3155_status[ minor ].state & DT3155_STATE_MODE ) == + DT3155_STATE_FLD) + { + /* GCS (Aug 2, 2002) -- In field mode, dma the odd field + into the lower half of the buffer */ + const u32 stride = dt3155_status[ minor ].config.cols; + buffer_addr = dt3155_fbuffer[ minor ]-> + frame_info[ dt3155_fbuffer[ minor ]->active_buf ].addr + + (DT3155_MAX_ROWS / 2) * stride; + local_save_flags(flags); + local_irq_disable(); + wake_up_interruptible( &dt3155_read_wait_queue[ minor ] ); + + /* Set up the DMA address for the next field */ + local_irq_restore(flags); + WriteMReg((dt3155_lbase[ minor ] + ODD_DMA_START), buffer_addr); + } + + /* Check for errors. */ + i2c_even_csr.fld.DONE_EVE = 1; + if ( i2c_even_csr.fld.ERROR_EVE ) + dt3155_errno = DT_ERR_OVERRUN; + + WriteI2C( dt3155_lbase[ minor ], EVEN_CSR, i2c_even_csr.reg ); + + /* Note that we actually saw an even field meaning */ + /* that subsequent odd field complete the frame */ + dt3155_fbuffer[ minor ]->even_happened = 1; + + /* recording the time that the even field finished, this should be */ + /* about time in the middle of the frame */ + do_gettimeofday( &(dt3155_fbuffer[ minor ]-> + frame_info[ dt3155_fbuffer[ minor ]-> + active_buf ].time) ); + return; + } + + /* ... now handle the odd field */ + if ( int_csr_r.fld.FLD_END_ODD ) + { + ReadI2C( dt3155_lbase[ minor ], ODD_CSR, &i2c_odd_csr.reg ); + + /* Clear the interrupt? */ + int_csr_r.fld.FLD_END_ODD = 1; + + if (dt3155_fbuffer[ minor ]->even_happened || + (dt3155_status[ minor ].state & DT3155_STATE_MODE) == + DT3155_STATE_FLD) + { + dt3155_fbuffer[ minor ]->frame_count++; + } + + if ( dt3155_fbuffer[ minor ]->stop_acquire && + dt3155_fbuffer[ minor ]->even_stopped ) + { + printk(KERN_DEBUG "dt3155: stopping odd..\n"); + if ( i2c_odd_csr.fld.SNGL_ODD ) + { + /* disable interrupts */ + int_csr_r.fld.FLD_END_ODD_EN = 0; + dt3155_status[ minor ].state &= ~(DT3155_STATE_STOP|0xff); + + /* mark the system stopped: */ + dt3155_status[ minor ].state |= DT3155_STATE_IDLE; + dt3155_fbuffer[ minor ]->stop_acquire = 0; + dt3155_fbuffer[ minor ]->even_stopped = 0; + + printk(KERN_DEBUG "dt3155: state is now %x\n", + dt3155_status[minor].state); + } + else + { + i2c_odd_csr.fld.SNGL_ODD = 1; + } + } + + WriteMReg( (dt3155_lbase[ minor ] + INT_CSR), int_csr_r.reg ); + + /* if the odd field has been acquired, then */ + /* change the next dma location for both fields */ + /* and wake up the process if sleeping */ + if ( dt3155_fbuffer[ minor ]->even_happened || + (dt3155_status[ minor ].state & DT3155_STATE_MODE) == + DT3155_STATE_FLD ) + { + + local_save_flags(flags); + local_irq_disable(); + +#ifdef DEBUG_QUES_B + printques( minor ); +#endif + if ( dt3155_fbuffer[ minor ]->nbuffers > 2 ) + { + if ( !are_empty_buffers( minor ) ) + { + /* The number of active + locked buffers is + * at most 2, and since there are none empty, there + * must be at least nbuffers-2 ready buffers. + * This is where we 'drop frames', oldest first. */ + push_empty( pop_ready( minor ), minor ); + } + + /* The ready_que can't be full, since we know + * there is one active buffer right now, so it's safe + * to push the active buf on the ready_que. */ + push_ready( minor, dt3155_fbuffer[ minor ]->active_buf ); + /* There's at least 1 empty -- make it active */ + dt3155_fbuffer[ minor ]->active_buf = pop_empty( minor ); + dt3155_fbuffer[ minor ]-> + frame_info[ dt3155_fbuffer[ minor ]-> + active_buf ].tag = ++unique_tag; + } + else /* nbuffers == 2, special case */ + { /* There is 1 active buffer. + * If there is a locked buffer, keep the active buffer + * the same -- that means we drop a frame. + */ + if ( dt3155_fbuffer[ minor ]->locked_buf < 0 ) + { + push_ready( minor, + dt3155_fbuffer[ minor ]->active_buf ); + if (are_empty_buffers( minor ) ) + { + dt3155_fbuffer[ minor ]->active_buf = + pop_empty( minor ); + } + else + { /* no empty or locked buffers, so use a readybuf */ + dt3155_fbuffer[ minor ]->active_buf = + pop_ready( minor ); + } + } + } + +#ifdef DEBUG_QUES_B + printques( minor ); +#endif + + dt3155_fbuffer[ minor ]->even_happened = 0; + + wake_up_interruptible( &dt3155_read_wait_queue[ minor ] ); + + local_irq_restore(flags); + } + + + /* Set up the DMA address for the next frame/field */ + buffer_addr = dt3155_fbuffer[ minor ]-> + frame_info[ dt3155_fbuffer[ minor ]->active_buf ].addr; + if ( (dt3155_status[ minor ].state & DT3155_STATE_MODE) == + DT3155_STATE_FLD ) + { + WriteMReg((dt3155_lbase[ minor ] + EVEN_DMA_START), buffer_addr); + } + else + { + WriteMReg((dt3155_lbase[ minor ] + EVEN_DMA_START), buffer_addr); + + WriteMReg((dt3155_lbase[ minor ] + ODD_DMA_START), buffer_addr + + dt3155_status[ minor ].config.cols); + } + + /* Do error checking */ + i2c_odd_csr.fld.DONE_ODD = 1; + if ( i2c_odd_csr.fld.ERROR_ODD ) + dt3155_errno = DT_ERR_OVERRUN; + + WriteI2C(dt3155_lbase[ minor ], ODD_CSR, i2c_odd_csr.reg ); + + return; + } + /* If we get here, the Odd Field wasn't it either... */ + printk( "neither even nor odd. shared perhaps?\n"); +} + +/***************************************************** + * init_isr(int minor) + * turns on interupt generation for the card + * designated by "minor". + * It is called *only* from inside ioctl(). + *****************************************************/ +static void dt3155_init_isr(int minor) +{ + const u32 stride = dt3155_status[ minor ].config.cols; + + switch (dt3155_status[ minor ].state & DT3155_STATE_MODE) + { + case DT3155_STATE_FLD: + { + even_dma_start_r = dt3155_status[ minor ]. + fbuffer.frame_info[ dt3155_status[ minor ].fbuffer.active_buf ].addr; + even_dma_stride_r = 0; + odd_dma_stride_r = 0; + + WriteMReg((dt3155_lbase[ minor ] + EVEN_DMA_START), + even_dma_start_r); + WriteMReg((dt3155_lbase[ minor ] + EVEN_DMA_STRIDE), + even_dma_stride_r); + WriteMReg((dt3155_lbase[ minor ] + ODD_DMA_STRIDE), + odd_dma_stride_r); + break; + } + + case DT3155_STATE_FRAME: + default: + { + even_dma_start_r = dt3155_status[ minor ]. + fbuffer.frame_info[ dt3155_status[ minor ].fbuffer.active_buf ].addr; + odd_dma_start_r = even_dma_start_r + stride; + even_dma_stride_r = stride; + odd_dma_stride_r = stride; + + WriteMReg((dt3155_lbase[ minor ] + EVEN_DMA_START), + even_dma_start_r); + WriteMReg((dt3155_lbase[ minor ] + ODD_DMA_START), + odd_dma_start_r); + WriteMReg((dt3155_lbase[ minor ] + EVEN_DMA_STRIDE), + even_dma_stride_r); + WriteMReg((dt3155_lbase[ minor ] + ODD_DMA_STRIDE), + odd_dma_stride_r); + break; + } + } + + /* 50/60 Hz should be set before this point but let's make sure it is */ + /* right anyway */ + + ReadI2C(dt3155_lbase[ minor ], CONFIG, &i2c_csr2.reg); + i2c_csr2.fld.HZ50 = FORMAT50HZ; + WriteI2C(dt3155_lbase[ minor ], CONFIG, i2c_config.reg); + + /* enable busmaster chip, clear flags */ + + /* + * TODO: + * shouldn't we be concered with continuous values of + * DT3155_SNAP & DT3155_ACQ here? (SS) + */ + + csr1_r.reg = 0; + csr1_r.fld.CAP_CONT_EVE = 1; /* use continuous capture bits to */ + csr1_r.fld.CAP_CONT_ODD = 1; /* enable */ + csr1_r.fld.FLD_DN_EVE = 1; /* writing a 1 clears flags */ + csr1_r.fld.FLD_DN_ODD = 1; + csr1_r.fld.SRST = 1; /* reset - must be 1 */ + csr1_r.fld.FIFO_EN = 1; /* fifo control - must be 1 */ + csr1_r.fld.FLD_CRPT_EVE = 1; /* writing a 1 clears flags */ + csr1_r.fld.FLD_CRPT_ODD = 1; + + WriteMReg((dt3155_lbase[ minor ] + CSR1),csr1_r.reg); + + /* Enable interrupts at the end of each field */ + + int_csr_r.reg = 0; + int_csr_r.fld.FLD_END_EVE_EN = 1; + int_csr_r.fld.FLD_END_ODD_EN = 1; + int_csr_r.fld.FLD_START_EN = 0; + + WriteMReg((dt3155_lbase[ minor ] + INT_CSR), int_csr_r.reg); + + /* start internal BUSY bits */ + + ReadI2C(dt3155_lbase[ minor ], CSR2, &i2c_csr2.reg); + i2c_csr2.fld.BUSY_ODD = 1; + i2c_csr2.fld.BUSY_EVE = 1; + WriteI2C(dt3155_lbase[ minor ], CSR2, i2c_csr2.reg); + + /* Now its up to the interrupt routine!! */ + + return; +} + + +/***************************************************** + * ioctl() + * + *****************************************************/ +static int dt3155_ioctl(struct inode *inode, + struct file *file, + unsigned int cmd, + unsigned long arg) +{ + int minor = MINOR(inode->i_rdev); /* What device are we ioctl()'ing? */ + + if ( minor >= MAXBOARDS || minor < 0 ) + return -ENODEV; + + /* make sure it is valid command */ + if (_IOC_NR(cmd) > DT3155_IOC_MAXNR) + { + printk("DT3155: invalid IOCTL(0x%x)\n",cmd); + printk("DT3155: Valid commands (0x%x), (0x%x), (0x%x), (0x%x), (0x%x)\n", + (unsigned int)DT3155_GET_CONFIG, + (unsigned int)DT3155_SET_CONFIG, + (unsigned int)DT3155_START, + (unsigned int)DT3155_STOP, + (unsigned int)DT3155_FLUSH); + return -EINVAL; + } + + switch (cmd) + { + case DT3155_SET_CONFIG: + { + if (dt3155_status[minor].state != DT3155_STATE_IDLE) + return -EBUSY; + + { + struct dt3155_config_s tmp; + if (copy_from_user((void *)&tmp, (void *) arg, sizeof(tmp))) + return -EFAULT; + /* check for valid settings */ + if (tmp.rows > DT3155_MAX_ROWS || + tmp.cols > DT3155_MAX_COLS || + (tmp.acq_mode != DT3155_MODE_FRAME && + tmp.acq_mode != DT3155_MODE_FIELD) || + (tmp.continuous != DT3155_SNAP && + tmp.continuous != DT3155_ACQ)) + { + return -EINVAL; + } + dt3155_status[minor].config = tmp; + } + return 0; + } + case DT3155_GET_CONFIG: + { + if (copy_to_user((void *) arg, (void *) &dt3155_status[minor], + sizeof(dt3155_status_t) )) + return -EFAULT; + return 0; + } + case DT3155_FLUSH: /* Flushes the buffers -- ensures fresh data */ + { + if (dt3155_status[minor].state != DT3155_STATE_IDLE) + return -EBUSY; + return dt3155_flush(minor); + } + case DT3155_STOP: + { + if (dt3155_status[minor].state & DT3155_STATE_STOP || + dt3155_status[minor].fbuffer.stop_acquire) + return -EBUSY; + + if (dt3155_status[minor].state == DT3155_STATE_IDLE) + return 0; + + quick_stop(minor); + if (copy_to_user((void *) arg, (void *) &dt3155_status[minor], + sizeof(dt3155_status_t))) + return -EFAULT; + return 0; + } + case DT3155_START: + { + if (dt3155_status[minor].state != DT3155_STATE_IDLE) + return -EBUSY; + + dt3155_status[minor].fbuffer.stop_acquire = 0; + dt3155_status[minor].fbuffer.frame_count = 0; + + /* Set the MODE in the status -- we default to FRAME */ + if (dt3155_status[minor].config.acq_mode == DT3155_MODE_FIELD) + { + dt3155_status[minor].state = DT3155_STATE_FLD; + } + else + { + dt3155_status[minor].state = DT3155_STATE_FRAME; + } + + dt3155_init_isr(minor); + if (copy_to_user( (void *) arg, (void *) &dt3155_status[minor], + sizeof(dt3155_status_t))) + return -EFAULT; + return 0; + } + default: + { + printk("DT3155: invalid IOCTL(0x%x)\n",cmd); + printk("DT3155: Valid commands (0x%x), (0x%x), (0x%x), (0x%x), (0x%x)\n", + (unsigned int)DT3155_GET_CONFIG, + (unsigned int)DT3155_SET_CONFIG, + DT3155_START, DT3155_STOP, DT3155_FLUSH); + return -ENOSYS; + } + } + return -ENOSYS; +} + +/***************************************************** + * mmap() + * + * only allow the user to mmap the registers and buffer + * It is quite possible that this is broken, since the + * addition of of the capacity for two cards!!!!!!!! + * It *looks* like it should work but since I'm not + * sure how to use it, I'm not actually sure. (NJC? ditto by SS) + *****************************************************/ +static int dt3155_mmap (struct file * file, struct vm_area_struct * vma) +{ + /* which device are we mmapping? */ + int minor = MINOR(file->f_dentry->d_inode->i_rdev); + unsigned long offset; + offset = vma->vm_pgoff << PAGE_SHIFT; + + if (offset >= __pa(high_memory) || (file->f_flags & O_SYNC)) + vma->vm_flags |= VM_IO; + + /* Don't try to swap out physical pages.. */ + vma->vm_flags |= VM_RESERVED; + + /* they are mapping the registers or the buffer */ + if ((offset == dt3155_status[minor].reg_addr && + vma->vm_end - vma->vm_start == PCI_PAGE_SIZE) || + (offset == dt3155_status[minor].mem_addr && + vma->vm_end - vma->vm_start == dt3155_status[minor].mem_size)) + { + if (remap_pfn_range(vma, + vma->vm_start, + offset >> PAGE_SHIFT, + vma->vm_end - vma->vm_start, + vma->vm_page_prot)) { + printk("DT3155: remap_page_range() failed.\n"); + return -EAGAIN; + } + } + else + { + printk("DT3155: dt3155_mmap() bad call.\n"); + return -ENXIO; + } + + return 0; +} + + +/***************************************************** + * open() + * + * Our special open code. + * MOD_INC_USE_COUNT make sure that the driver memory is not freed + * while the device is in use. + *****************************************************/ +static int dt3155_open( struct inode* inode, struct file* filep) +{ + int minor = MINOR(inode->i_rdev); /* what device are we opening? */ + if (dt3155_dev_open[ minor ]) { + printk ("DT3155: Already opened by another process.\n"); + return -EBUSY; + } + + if (dt3155_status[ minor ].device_installed==0) + { + printk("DT3155 Open Error: No such device dt3155 minor number %d\n", + minor); + return -EIO; + } + + if (dt3155_status[ minor ].state != DT3155_STATE_IDLE) { + printk ("DT3155: Not in idle state (state = %x)\n", + dt3155_status[ minor ].state); + return -EBUSY; + } + + printk("DT3155: Device opened.\n"); + + dt3155_dev_open[ minor ] = 1 ; + + dt3155_flush( minor ); + + /* Disable ALL interrupts */ + int_csr_r.reg = 0; + WriteMReg( (dt3155_lbase[ minor ] + INT_CSR), int_csr_r.reg ); + + init_waitqueue_head(&(dt3155_read_wait_queue[minor])); + + return 0; +} + + +/***************************************************** + * close() + * + * Now decrement the use count. + * + *****************************************************/ +static int dt3155_close( struct inode *inode, struct file *filep) +{ + int minor; + + minor = MINOR(inode->i_rdev); /* which device are we closing */ + if (!dt3155_dev_open[ minor ]) + { + printk("DT3155: attempt to CLOSE a not OPEN device\n"); + } + else + { + dt3155_dev_open[ minor ] = 0; + + if (dt3155_status[ minor ].state != DT3155_STATE_IDLE) + { + quick_stop(minor); + } + } + return 0; +} + +/***************************************************** + * read() + * + *****************************************************/ +static ssize_t dt3155_read(struct file *filep, char __user *buf, + size_t count, loff_t *ppos) +{ + /* which device are we reading from? */ + int minor = MINOR(filep->f_dentry->d_inode->i_rdev); + u32 offset; + int frame_index; + frame_info_t *frame_info_p; + + /* TODO: this should check the error flag and */ + /* return an error on hardware failures */ + if (count != sizeof(dt3155_read_t)) + { + printk("DT3155 ERROR (NJC): count is not right\n"); + return -EINVAL; + } + + + /* Hack here -- I'm going to allow reading even when idle. + * this is so that the frames can be read after STOP has + * been called. Leaving it here, commented out, as a reminder + * for a short while to make sure there are no problems. + * Note that if the driver is not opened in non_blocking mode, + * and the device is idle, then it could sit here forever! */ + + /* if (dt3155_status[minor].state == DT3155_STATE_IDLE)*/ + /* return -EBUSY;*/ + + /* non-blocking reads should return if no data */ + if (filep->f_flags & O_NDELAY) + { + if ((frame_index = dt3155_get_ready_buffer(minor)) < 0) { + /*printk( "dt3155: no buffers available (?)\n");*/ + /* printques(minor); */ + return -EAGAIN; + } + } + else + { + /* + * sleep till data arrives , or we get interrupted. + * Note that wait_event_interruptible() does not actually + * sleep/wait if it's condition evaluates to true upon entry. + */ + wait_event_interruptible(dt3155_read_wait_queue[minor], + (frame_index = dt3155_get_ready_buffer(minor)) + >= 0); + + if (frame_index < 0) + { + printk ("DT3155: read: interrupted\n"); + quick_stop (minor); + printques(minor); + return -EINTR; + } + } + + frame_info_p = &dt3155_status[minor].fbuffer.frame_info[frame_index]; + + /* make this an offset */ + offset = frame_info_p->addr - dt3155_status[minor].mem_addr; + + put_user(offset, (unsigned int *) buf); + buf += sizeof(u32); + put_user( dt3155_status[minor].fbuffer.frame_count, (unsigned int *) buf); + buf += sizeof(u32); + put_user(dt3155_status[minor].state, (unsigned int *) buf); + buf += sizeof(u32); + if (copy_to_user(buf, frame_info_p, sizeof(frame_info_t))) + return -EFAULT; + + return sizeof(dt3155_read_t); +} + +static unsigned int dt3155_poll (struct file * filp, poll_table *wait) +{ + int minor = MINOR(filp->f_dentry->d_inode->i_rdev); + + if (!is_ready_buf_empty(minor)) + return POLLIN | POLLRDNORM; + + poll_wait (filp, &dt3155_read_wait_queue[minor], wait); + + return 0; +} + + +/***************************************************** + * file operations supported by DT3155 driver + * needed by init_module + * register_chrdev + *****************************************************/ +static struct file_operations dt3155_fops = { + read: dt3155_read, + ioctl: dt3155_ioctl, + mmap: dt3155_mmap, + poll: dt3155_poll, + open: dt3155_open, + release: dt3155_close +}; + + +/***************************************************** + * find_PCI(); + * + * PCI has been totally reworked in 2.1.. + *****************************************************/ +static int find_PCI (void) +{ + struct pci_dev *pci_dev = NULL; + int error, pci_index = 0; + unsigned short rev_device; + unsigned long base; + unsigned char irq; + + while ((pci_dev = pci_get_device + (DT3155_VENDORID, DT3155_DEVICEID, pci_dev)) != NULL) + { + pci_index ++; + + /* Is it really there? */ + if ((error = + pci_read_config_word(pci_dev, PCI_CLASS_DEVICE, &rev_device))) + continue; + + /* Found a board */ + DT_3155_DEBUG_MSG("DT3155: Device number %d \n", pci_index); + + /* Make sure the driver was compiled with enough buffers to handle + this many boards */ + if (pci_index > MAXBOARDS) { + printk("DT3155: ERROR - found %d devices, but driver only configured " + "for %d devices\n" + "DT3155: Please change MAXBOARDS in dt3155.h\n", + pci_index, MAXBOARDS); + goto err; + } + + /* Now, just go out and make sure that this/these device(s) is/are + actually mapped into the kernel address space */ + if ((error = pci_read_config_dword( pci_dev, PCI_BASE_ADDRESS_0, + (u32 *) &base))) + { + printk("DT3155: Was not able to find device \n"); + goto err; + } + + DT_3155_DEBUG_MSG("DT3155: Base address 0 for device is %lx \n", base); + dt3155_status[pci_index-1].reg_addr = base; + + /* Remap the base address to a logical address through which we + * can access it. */ + dt3155_lbase[ pci_index - 1 ] = ioremap(base,PCI_PAGE_SIZE); + dt3155_status[ pci_index - 1 ].reg_addr = base; + DT_3155_DEBUG_MSG("DT3155: New logical address is %p \n", + dt3155_lbase[pci_index-1]); + if ( !dt3155_lbase[pci_index-1] ) + { + printk("DT3155: Unable to remap control registers\n"); + goto err; + } + + if ( (error = pci_read_config_byte( pci_dev, PCI_INTERRUPT_LINE, &irq)) ) + { + printk("DT3155: Was not able to find device \n"); + goto err; + } + + DT_3155_DEBUG_MSG("DT3155: IRQ is %d \n",irq); + dt3155_status[ pci_index-1 ].irq = irq; + /* Set flag: kth device found! */ + dt3155_status[ pci_index-1 ].device_installed = 1; + printk("DT3155: Installing device %d w/irq %d and address %p\n", + pci_index, + dt3155_status[pci_index-1].irq, + dt3155_lbase[pci_index-1]); + + } + ndevices = pci_index; + + return DT_3155_SUCCESS; + +err: + pci_dev_put(pci_dev); + return DT_3155_FAILURE; +} + +u32 allocatorAddr = 0; + +/***************************************************** + * init_module() + *****************************************************/ +int init_module(void) +{ + int index; + int rcode = 0; + char *devname[ MAXBOARDS ]; + + devname[ 0 ] = "dt3155a"; +#if MAXBOARDS == 2 + devname[ 1 ] = "dt3155b"; +#endif + + printk("DT3155: Loading module...\n"); + + /* Register the device driver */ + rcode = register_chrdev( dt3155_major, "dt3155", &dt3155_fops ); + if( rcode < 0 ) + { + printk( KERN_INFO "DT3155: register_chrdev failed \n"); + return rcode; + } + + if( dt3155_major == 0 ) + dt3155_major = rcode; /* dynamic */ + + + /* init the status variables. */ + /* DMA memory is taken care of in setup_buffers() */ + for ( index = 0; index < MAXBOARDS; index++ ) + { + dt3155_status[ index ].config.acq_mode = DT3155_MODE_FRAME; + dt3155_status[ index ].config.continuous = DT3155_ACQ; + dt3155_status[ index ].config.cols = DT3155_MAX_COLS; + dt3155_status[ index ].config.rows = DT3155_MAX_ROWS; + dt3155_status[ index ].state = DT3155_STATE_IDLE; + + /* find_PCI() will check if devices are installed; */ + /* first assume they're not: */ + dt3155_status[ index ].mem_addr = 0; + dt3155_status[ index ].mem_size = 0; + dt3155_status[ index ].state = DT3155_STATE_IDLE; + dt3155_status[ index ].device_installed = 0; + } + + /* Now let's find the hardware. find_PCI() will set ndevices to the + * number of cards found in this machine. */ + { + if ( (rcode = find_PCI()) != DT_3155_SUCCESS ) + { + printk("DT3155 error: find_PCI() failed to find dt3155 board(s)\n"); + unregister_chrdev( dt3155_major, "dt3155" ); + return rcode; + } + } + + /* Ok, time to setup the frame buffers */ + if( (rcode = dt3155_setup_buffers(&allocatorAddr)) < 0 ) + { + printk("DT3155: Error: setting up buffer not large enough."); + unregister_chrdev( dt3155_major, "dt3155" ); + return rcode; + } + + /* If we are this far, then there is enough RAM */ + /* for the buffers: Print the configuration. */ + for( index = 0; index < ndevices; index++ ) + { + printk("DT3155: Device = %d; acq_mode = %d; " + "continuous = %d; cols = %d; rows = %d;\n", + index , + dt3155_status[ index ].config.acq_mode, + dt3155_status[ index ].config.continuous, + dt3155_status[ index ].config.cols, + dt3155_status[ index ].config.rows); + printk("DT3155: m_addr = 0x%x; m_size = %ld; " + "state = %d; device_installed = %d\n", + dt3155_status[ index ].mem_addr, + (long int)dt3155_status[ index ].mem_size, + dt3155_status[ index ].state, + dt3155_status[ index ].device_installed); + } + + /* Disable ALL interrupts */ + int_csr_r.reg = 0; + for( index = 0; index < ndevices; index++ ) + { + WriteMReg( (dt3155_lbase[ index ] + INT_CSR), int_csr_r.reg ); + if( dt3155_status[ index ].device_installed ) + { + /* + * This driver *looks* like it can handle sharing interrupts, + * but I can't actually test myself. I've had reports that it + * DOES work so I'll enable it for now. This comment will remain + * as a reminder in case any problems arise. (SS) + */ + /* in older kernels flags are: SA_SHIRQ | SA_INTERRUPT */ + rcode = request_irq( dt3155_status[ index ].irq, (void *)dt3155_isr, + IRQF_SHARED | IRQF_DISABLED, devname[ index ], + (void*) &dt3155_status[index]); + if( rcode < 0 ) + { + printk("DT3155: minor %d request_irq failed for IRQ %d\n", + index, dt3155_status[index].irq); + unregister_chrdev( dt3155_major, "dt3155" ); + return rcode; + } + } + } + + printk("DT3155: finished loading\n"); + + return 0; +} + +/***************************************************** + * cleanup_module(void) + * + *****************************************************/ +void cleanup_module(void) +{ + int index; + + printk("DT3155: cleanup_module called\n"); + + /* removed DMA allocated with the allocator */ +#ifdef STANDALONE_ALLOCATOR + if (allocatorAddr != 0) + allocator_free_dma(allocatorAddr); +#else + allocator_cleanup(); +#endif + + unregister_chrdev( dt3155_major, "dt3155" ); + + for( index = 0; index < ndevices; index++ ) + { + if( dt3155_status[ index ].device_installed == 1 ) + { + printk( "DT3155: Freeing irq %d for device %d\n", + dt3155_status[ index ].irq, index ); + free_irq( dt3155_status[ index ].irq, (void*)&dt3155_status[index] ); + } + } +} + diff --git a/drivers/staging/dt3155/dt3155_drv.h b/drivers/staging/dt3155/dt3155_drv.h new file mode 100644 index 0000000..95e68c3 --- /dev/null +++ b/drivers/staging/dt3155/dt3155_drv.h @@ -0,0 +1,45 @@ +/* + +Copyright 1996,2002 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan, + Scott Smedley + +This file is part of the DT3155 Device Driver. + +The DT3155 Device Driver is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The DT3155 Device Driver is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty +of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with the DT3155 Device Driver; if not, write to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +MA 02111-1307 USA +*/ + +#ifndef DT3155_DRV_INC +#define DT3155_DRV_INC + +/* kernel logical address of the frame grabbers */ +extern u8 *dt3155_lbase[MAXBOARDS]; + +/* kernel logical address of ram buffer */ +extern u8 *dt3155_bbase; + +#ifdef __KERNEL__ +#include <linux/wait.h> + +/* wait queue for reads */ +extern wait_queue_head_t dt3155_read_wait_queue[MAXBOARDS]; +#endif + +/* number of devices */ +extern u32 ndevices; + +extern int dt3155_errno; + +#endif diff --git a/drivers/staging/dt3155/dt3155_io.c b/drivers/staging/dt3155/dt3155_io.c new file mode 100644 index 0000000..6b9c685 --- /dev/null +++ b/drivers/staging/dt3155/dt3155_io.c @@ -0,0 +1,175 @@ +/* + * Copyright 1996,2002,2005 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan, + * Jason Lapenta, Scott Smedley + * + * This file is part of the DT3155 Device Driver. + * + * The DT3155 Device Driver is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * The DT3155 Device Driver is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + */ + +/* + * This file provides some basic register io routines. It is modified from + * demo code provided by Data Translations. + */ + +#include <linux/delay.h> +#include "dt3155.h" +#include "dt3155_io.h" +#include "dt3155_drv.h" + + +/****** local copies of board's 32 bit registers ******/ +u32 even_dma_start_r; /* bit 0 should always be 0 */ +u32 odd_dma_start_r; /* .. */ +u32 even_dma_stride_r; /* bits 0&1 should always be 0 */ +u32 odd_dma_stride_r; /* .. */ +u32 even_pixel_fmt_r; +u32 odd_pixel_fmt_r; + +FIFO_TRIGGER_R fifo_trigger_r; +XFER_MODE_R xfer_mode_r; +CSR1_R csr1_r; +RETRY_WAIT_CNT_R retry_wait_cnt_r; +INT_CSR_R int_csr_r; + +u32 even_fld_mask_r; +u32 odd_fld_mask_r; + +MASK_LENGTH_R mask_length_r; +FIFO_FLAG_CNT_R fifo_flag_cnt_r; +IIC_CLK_DUR_R iic_clk_dur_r; +IIC_CSR1_R iic_csr1_r; +IIC_CSR2_R iic_csr2_r; +DMA_UPPER_LMT_R even_dma_upper_lmt_r; +DMA_UPPER_LMT_R odd_dma_upper_lmt_r; + + + +/******** local copies of board's 8 bit I2C registers ******/ +I2C_CSR2 i2c_csr2; +I2C_EVEN_CSR i2c_even_csr; +I2C_ODD_CSR i2c_odd_csr; +I2C_CONFIG i2c_config; +u8 i2c_dt_id; +u8 i2c_x_clip_start; +u8 i2c_y_clip_start; +u8 i2c_x_clip_end; +u8 i2c_y_clip_end; +u8 i2c_ad_addr; +u8 i2c_ad_lut; +I2C_AD_CMD i2c_ad_cmd; +u8 i2c_dig_out; +u8 i2c_pm_lut_addr; +u8 i2c_pm_lut_data; + +/* + * wait_ibsyclr() + * + * This function handles read/write timing and r/w timeout error + * + * Returns TRUE if NEW_CYCLE clears + * Returns FALSE if NEW_CYCLE doesn't clear in roughly 3 msecs, otherwise + * returns 0 + */ +static int wait_ibsyclr(u8 *lpReg) +{ + /* wait 100 microseconds */ + udelay(100L); + /* __delay(loops_per_sec/10000); */ + if (iic_csr2_r.fld.NEW_CYCLE) { + /* if NEW_CYCLE didn't clear */ + /* TIMEOUT ERROR */ + dt3155_errno = DT_ERR_I2C_TIMEOUT; + return FALSE; + } else + return TRUE; /* no error */ +} + +/* + * WriteI2C() + * + * This function handles writing to 8-bit DT3155 registers + * + * 1st parameter is pointer to 32-bit register base address + * 2nd parameter is reg. index; + * 3rd is value to be written + * + * Returns TRUE - Successful completion + * FALSE - Timeout error - cycle did not complete! + */ +int WriteI2C(u8 *lpReg, u_short wIregIndex, u8 byVal) +{ + int writestat; /* status for return */ + + /* read 32 bit IIC_CSR2 register data into union */ + + ReadMReg((lpReg + IIC_CSR2), iic_csr2_r.reg); + + /* for write operation */ + iic_csr2_r.fld.DIR_RD = 0; + /* I2C address of I2C register: */ + iic_csr2_r.fld.DIR_ADDR = wIregIndex; + /* 8 bit data to be written to I2C reg */ + iic_csr2_r.fld.DIR_WR_DATA = byVal; + /* will start a direct I2C cycle: */ + iic_csr2_r.fld.NEW_CYCLE = 1; + + /* xfer union data into 32 bit IIC_CSR2 register */ + WriteMReg((lpReg + IIC_CSR2), iic_csr2_r.reg); + + /* wait for IIC cycle to finish */ + writestat = wait_ibsyclr(lpReg); + return writestat; +} + +/* + * ReadI2C() + * + * This function handles reading from 8-bit DT3155 registers + * + * 1st parameter is pointer to 32-bit register base address + * 2nd parameter is reg. index; + * 3rd is adrs of value to be read + * + * Returns TRUE - Successful completion + * FALSE - Timeout error - cycle did not complete! + */ +int ReadI2C(u8 *lpReg, u_short wIregIndex, u8 *byVal) +{ + int writestat; /* status for return */ + + /* read 32 bit IIC_CSR2 register data into union */ + ReadMReg((lpReg + IIC_CSR2), iic_csr2_r.reg); + + /* for read operation */ + iic_csr2_r.fld.DIR_RD = 1; + + /* I2C address of I2C register: */ + iic_csr2_r.fld.DIR_ADDR = wIregIndex; + + /* will start a direct I2C cycle: */ + iic_csr2_r.fld.NEW_CYCLE = 1; + + /* xfer union's data into 32 bit IIC_CSR2 register */ + WriteMReg((lpReg + IIC_CSR2), iic_csr2_r.reg); + + /* wait for IIC cycle to finish */ + writestat = wait_ibsyclr(lpReg); + + /* Next 2 commands read 32 bit IIC_CSR1 register's data into union */ + /* first read data is in IIC_CSR1 */ + ReadMReg((lpReg + IIC_CSR1), iic_csr1_r.reg); + + /* now get data u8 out of register */ + *byVal = (u8) iic_csr1_r.fld.RD_DATA; + + return writestat; +} diff --git a/drivers/staging/dt3155/dt3155_io.h b/drivers/staging/dt3155/dt3155_io.h new file mode 100644 index 0000000..d1a2510 --- /dev/null +++ b/drivers/staging/dt3155/dt3155_io.h @@ -0,0 +1,358 @@ +/* + +Copyright 1996,2002 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan, + Jason Lapenta, Scott Smedley + +This file is part of the DT3155 Device Driver. + +The DT3155 Device Driver is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The DT3155 Device Driver is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty +of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with the DT3155 Device Driver; if not, write to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +MA 02111-1307 USA + + +-- Changes -- + + Date Programmer Description of changes made + ------------------------------------------------------------------- + 24-Jul-2002 SS GPL licence. + +*/ + +/* This code is a modified version of examples provided by Data Translations.*/ + +#ifndef DT3155_IO_INC +#define DT3155_IO_INC + +/* macros to access registers */ + +#define WriteMReg(Address, Data) (*((u32 *)(Address)) = Data) +#define ReadMReg(Address, Data) (Data = *((u32 *)(Address))) + +/***************** 32 bit register globals **************/ + +/* offsets for 32-bit memory mapped registers */ + +#define EVEN_DMA_START 0x000 +#define ODD_DMA_START 0x00C +#define EVEN_DMA_STRIDE 0x018 +#define ODD_DMA_STRIDE 0x024 +#define EVEN_PIXEL_FMT 0x030 +#define ODD_PIXEL_FMT 0x034 +#define FIFO_TRIGGER 0x038 +#define XFER_MODE 0x03C +#define CSR1 0x040 +#define RETRY_WAIT_CNT 0x044 +#define INT_CSR 0x048 +#define EVEN_FLD_MASK 0x04C +#define ODD_FLD_MASK 0x050 +#define MASK_LENGTH 0x054 +#define FIFO_FLAG_CNT 0x058 +#define IIC_CLK_DUR 0x05C +#define IIC_CSR1 0x060 +#define IIC_CSR2 0x064 +#define EVEN_DMA_UPPR_LMT 0x08C +#define ODD_DMA_UPPR_LMT 0x090 + +#define CLK_DUR_VAL 0x01010101 + + + +/******** Assignments and Typedefs for 32 bit Memory Mapped Registers ********/ + +typedef union fifo_trigger_tag { + u32 reg; + struct { + u32 PACKED:6; + u32 :9; + u32 PLANER:7; + u32 :9; + } fld; +} FIFO_TRIGGER_R; + +typedef union xfer_mode_tag { + u32 reg; + struct { + u32 :2; + u32 FIELD_TOGGLE:1; + u32 :5; + u32 :2; + u32 :22; + } fld; +} XFER_MODE_R; + +typedef union csr1_tag { + u32 reg; + struct { + u32 CAP_CONT_EVE:1; + u32 CAP_CONT_ODD:1; + u32 CAP_SNGL_EVE:1; + u32 CAP_SNGL_ODD:1; + u32 FLD_DN_EVE :1; + u32 FLD_DN_ODD :1; + u32 SRST :1; + u32 FIFO_EN :1; + u32 FLD_CRPT_EVE:1; + u32 FLD_CRPT_ODD:1; + u32 ADDR_ERR_EVE:1; + u32 ADDR_ERR_ODD:1; + u32 CRPT_DIS :1; + u32 RANGE_EN :1; + u32 :16; + } fld; +} CSR1_R; + +typedef union retry_wait_cnt_tag { + u32 reg; + struct { + u32 RTRY_WAIT_CNT:8; + u32 :24; + } fld; +} RETRY_WAIT_CNT_R; + +typedef union int_csr_tag { + u32 reg; + struct { + u32 FLD_END_EVE :1; + u32 FLD_END_ODD :1; + u32 FLD_START :1; + u32 :5; + u32 FLD_END_EVE_EN:1; + u32 FLD_END_ODD_EN:1; + u32 FLD_START_EN :1; + u32 :21; + } fld; +} INT_CSR_R; + +typedef union mask_length_tag { + u32 reg; + struct { + u32 MASK_LEN_EVE:5; + u32 :11; + u32 MASK_LEN_ODD:5; + u32 :11; + } fld; +} MASK_LENGTH_R; + +typedef union fifo_flag_cnt_tag { + u32 reg; + struct { + u32 AF_COUNT:7; + u32 :9; + u32 AE_COUNT:7; + u32 :9; + } fld; +} FIFO_FLAG_CNT_R; + +typedef union iic_clk_dur { + u32 reg; + struct { + u32 PHASE_1:8; + u32 PHASE_2:8; + u32 PHASE_3:8; + u32 PHASE_4:8; + } fld; +} IIC_CLK_DUR_R; + +typedef union iic_csr1_tag { + u32 reg; + struct { + u32 AUTO_EN :1; + u32 BYPASS :1; + u32 SDA_OUT :1; + u32 SCL_OUT :1; + u32 :4; + u32 AUTO_ABORT :1; + u32 DIRECT_ABORT:1; + u32 SDA_IN :1; + u32 SCL_IN :1; + u32 :4; + u32 AUTO_ADDR :8; + u32 RD_DATA :8; + } fld; +} IIC_CSR1_R; + +/********************************** + * iic_csr2_tag + */ +typedef union iic_csr2_tag { + u32 reg; + struct { + u32 DIR_WR_DATA :8; + u32 DIR_SUB_ADDR:8; + u32 DIR_RD :1; + u32 DIR_ADDR :7; + u32 NEW_CYCLE :1; + u32 :7; + } fld; +} IIC_CSR2_R; + +/* use for both EVEN and ODD DMA UPPER LIMITS */ + +/* + * dma_upper_lmt_tag + */ +typedef union dma_upper_lmt_tag { + u32 reg; + struct { + u32 DMA_UPPER_LMT_VAL:24; + u32 :8; + } fld; +} DMA_UPPER_LMT_R; + + +/* + * Global declarations of local copies of boards' 32 bit registers + */ +extern u32 even_dma_start_r; /* bit 0 should always be 0 */ +extern u32 odd_dma_start_r; /* .. */ +extern u32 even_dma_stride_r; /* bits 0&1 should always be 0 */ +extern u32 odd_dma_stride_r; /* .. */ +extern u32 even_pixel_fmt_r; +extern u32 odd_pixel_fmt_r; + +extern FIFO_TRIGGER_R fifo_trigger_r; +extern XFER_MODE_R xfer_mode_r; +extern CSR1_R csr1_r; +extern RETRY_WAIT_CNT_R retry_wait_cnt_r; +extern INT_CSR_R int_csr_r; + +extern u32 even_fld_mask_r; +extern u32 odd_fld_mask_r; + +extern MASK_LENGTH_R mask_length_r; +extern FIFO_FLAG_CNT_R fifo_flag_cnt_r; +extern IIC_CLK_DUR_R iic_clk_dur_r; +extern IIC_CSR1_R iic_csr1_r; +extern IIC_CSR2_R iic_csr2_r; +extern DMA_UPPER_LMT_R even_dma_upper_lmt_r; +extern DMA_UPPER_LMT_R odd_dma_upper_lmt_r; + + + +/***************** 8 bit I2C register globals ***********/ +#define CSR2 0x010 /* indices of 8-bit I2C mapped reg's*/ +#define EVEN_CSR 0x011 +#define ODD_CSR 0x012 +#define CONFIG 0x013 +#define DT_ID 0x01F +#define X_CLIP_START 0x020 +#define Y_CLIP_START 0x022 +#define X_CLIP_END 0x024 +#define Y_CLIP_END 0x026 +#define AD_ADDR 0x030 +#define AD_LUT 0x031 +#define AD_CMD 0x032 +#define DIG_OUT 0x040 +#define PM_LUT_ADDR 0x050 +#define PM_LUT_DATA 0x051 + + +/******** Assignments and Typedefs for 8 bit I2C Registers********************/ + +typedef union i2c_csr2_tag { + u8 reg; + struct { + u8 CHROM_FIL:1; + u8 SYNC_SNTL:1; + u8 HZ50:1; + u8 SYNC_PRESENT:1; + u8 BUSY_EVE:1; + u8 BUSY_ODD:1; + u8 DISP_PASS:1; + } fld; +} I2C_CSR2; + +typedef union i2c_even_csr_tag { + u8 reg; + struct { + u8 DONE_EVE :1; + u8 SNGL_EVE :1; + u8 ERROR_EVE:1; + u8 :5; + } fld; +} I2C_EVEN_CSR; + +typedef union i2c_odd_csr_tag { + u8 reg; + struct { + u8 DONE_ODD:1; + u8 SNGL_ODD:1; + u8 ERROR_ODD:1; + u8 :5; + } fld; +} I2C_ODD_CSR; + +typedef union i2c_config_tag { + u8 reg; + struct { + u8 ACQ_MODE:2; + u8 EXT_TRIG_EN:1; + u8 EXT_TRIG_POL:1; + u8 H_SCALE:1; + u8 CLIP:1; + u8 PM_LUT_SEL:1; + u8 PM_LUT_PGM:1; + } fld; +} I2C_CONFIG; + + +typedef union i2c_ad_cmd_tag { + /* bits can have 3 different meanings depending on value of AD_ADDR */ + u8 reg; + /* Bt252 Command Register if AD_ADDR = 00h */ + struct { + u8 :2; + u8 SYNC_LVL_SEL:2; + u8 SYNC_CNL_SEL:2; + u8 DIGITIZE_CNL_SEL1:2; + } bt252_command; + + /* Bt252 IOUT0 register if AD_ADDR = 01h */ + struct { + u8 IOUT_DATA:8; + } bt252_iout0; + + /* BT252 IOUT1 register if AD_ADDR = 02h */ + struct { + u8 IOUT_DATA:8; + } bt252_iout1; +} I2C_AD_CMD; + + +/***** Global declarations of local copies of boards' 8 bit I2C registers ***/ + +extern I2C_CSR2 i2c_csr2; +extern I2C_EVEN_CSR i2c_even_csr; +extern I2C_ODD_CSR i2c_odd_csr; +extern I2C_CONFIG i2c_config; +extern u8 i2c_dt_id; +extern u8 i2c_x_clip_start; +extern u8 i2c_y_clip_start; +extern u8 i2c_x_clip_end; +extern u8 i2c_y_clip_end; +extern u8 i2c_ad_addr; +extern u8 i2c_ad_lut; +extern I2C_AD_CMD i2c_ad_cmd; +extern u8 i2c_dig_out; +extern u8 i2c_pm_lut_addr; +extern u8 i2c_pm_lut_data; + +/* Functions for Global use */ + +/* access 8-bit IIC registers */ + +extern int ReadI2C(u8 *lpReg, u_short wIregIndex, u8 *byVal); +extern int WriteI2C(u8 *lpReg, u_short wIregIndex, u8 byVal); + +#endif diff --git a/drivers/staging/dt3155/dt3155_isr.c b/drivers/staging/dt3155/dt3155_isr.c new file mode 100644 index 0000000..fd7f93d --- /dev/null +++ b/drivers/staging/dt3155/dt3155_isr.c @@ -0,0 +1,516 @@ +/* + +Copyright 1996,2002,2005 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan, + Jason Lapenta, Scott Smedley, Greg Sharp + +This file is part of the DT3155 Device Driver. + +The DT3155 Device Driver is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The DT3155 Device Driver is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty +of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with the DT3155 Device Driver; if not, write to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +MA 02111-1307 USA + + File: dt3155_isr.c +Purpose: Buffer management routines, and other routines for the ISR + (the actual isr is in dt3155_drv.c) + +-- Changes -- + + Date Programmer Description of changes made + ------------------------------------------------------------------- + 03-Jul-2000 JML n/a + 02-Apr-2002 SS Mods to make work with separate allocator + module; Merged John Roll's mods to make work with + multiple boards. + 10-Jul-2002 GCS Complete rewrite of setup_buffers to disallow + buffers which span a 4MB boundary. + 24-Jul-2002 SS GPL licence. + 30-Jul-2002 NJC Added support for buffer loop. + 31-Jul-2002 NJC Complete rewrite of buffer management + 02-Aug-2002 NJC Including slab.h instead of malloc.h (no warning). + Also, allocator_init() now returns allocator_max + so cleaned up allocate_buffers() accordingly. + 08-Aug-2005 SS port to 2.6 kernel. + +*/ + +#include <asm/system.h> +#include <linux/slab.h> +#include <linux/sched.h> +#include <linux/types.h> + +#include "dt3155.h" +#include "dt3155_drv.h" +#include "dt3155_io.h" +#include "dt3155_isr.h" +#include "allocator.h" + +#define FOUR_MB (0x0400000) /* Can't DMA accross a 4MB boundary!*/ +#define UPPER_10_BITS (0x3FF<<22) /* Can't DMA accross a 4MB boundary!*/ + + +/* Pointer into global structure for handling buffers */ +struct dt3155_fbuffer_s *dt3155_fbuffer[MAXBOARDS] = {NULL +#if MAXBOARDS == 2 + , NULL +#endif +}; + +/****************************************************************************** + * Simple array based que struct + * + * Some handy functions using the buffering structure. + *****************************************************************************/ + + +/*************************** + * are_empty_buffers + * m is minor # of device + ***************************/ +inline bool are_empty_buffers( int m ) +{ + return ( dt3155_fbuffer[ m ]->empty_len ); +} + +/************************** + * push_empty + * m is minor # of device + * + * This is slightly confusing. The number empty_len is the literal # + * of empty buffers. After calling, empty_len-1 is the index into the + * empty buffer stack. So, if empty_len == 1, there is one empty buffer, + * given by dt3155_fbuffer[m]->empty_buffers[0]. + * empty_buffers should never fill up, though this is not checked. + **************************/ +inline void push_empty( int index, int m ) +{ + dt3155_fbuffer[m]->empty_buffers[ dt3155_fbuffer[m]->empty_len ] = index; + dt3155_fbuffer[m]->empty_len++; +} + +/************************** + * pop_empty( m ) + * m is minor # of device + **************************/ +inline int pop_empty( int m ) +{ + dt3155_fbuffer[m]->empty_len--; + return dt3155_fbuffer[m]->empty_buffers[ dt3155_fbuffer[m]->empty_len ]; +} + +/************************* + * is_ready_buf_empty( m ) + * m is minor # of device + *************************/ +inline bool is_ready_buf_empty( int m ) +{ + return ((dt3155_fbuffer[ m ]->ready_len) == 0); +} + +/************************* + * is_ready_buf_full( m ) + * m is minor # of device + * this should *never* be true if there are any active, locked or empty + * buffers, since it corresponds to nbuffers ready buffers!! + * 7/31/02: total rewrite. --NJC + *************************/ +inline bool is_ready_buf_full( int m ) +{ + return ( dt3155_fbuffer[ m ]->ready_len == dt3155_fbuffer[ m ]->nbuffers ); +} + +/***************************************************** + * push_ready( m, buffer ) + * m is minor # of device + * + *****************************************************/ +inline void push_ready( int m, int index ) +{ + int head = dt3155_fbuffer[m]->ready_head; + + dt3155_fbuffer[ m ]->ready_que[ head ] = index; + dt3155_fbuffer[ m ]->ready_head = ( (head + 1) % + (dt3155_fbuffer[ m ]->nbuffers) ); + dt3155_fbuffer[ m ]->ready_len++; + +} + +/***************************************************** + * get_tail() + * m is minor # of device + * + * Simply comptutes the tail given the head and the length. + *****************************************************/ +static inline int get_tail( int m ) +{ + return ((dt3155_fbuffer[ m ]->ready_head - + dt3155_fbuffer[ m ]->ready_len + + dt3155_fbuffer[ m ]->nbuffers)% + (dt3155_fbuffer[ m ]->nbuffers)); +} + + + +/***************************************************** + * pop_ready() + * m is minor # of device + * + * This assumes that there is a ready buffer ready... should + * be checked (e.g. with is_ready_buf_empty() prior to call. + *****************************************************/ +inline int pop_ready( int m ) +{ + int tail; + tail = get_tail(m); + dt3155_fbuffer[ m ]->ready_len--; + return dt3155_fbuffer[ m ]->ready_que[ tail ]; +} + + +/***************************************************** + * printques + * m is minor # of device + *****************************************************/ +inline void printques( int m ) +{ + int head = dt3155_fbuffer[ m ]->ready_head; + int tail; + int num = dt3155_fbuffer[ m ]->nbuffers; + int frame_index; + int index; + + tail = get_tail(m); + + printk("\n R:"); + for ( index = tail; index != head; index++, index = index % (num) ) + { + frame_index = dt3155_fbuffer[ m ]->ready_que[ index ]; + printk(" %d ", frame_index ); + } + + printk("\n E:"); + for ( index = 0; index < dt3155_fbuffer[ m ]->empty_len; index++ ) + { + frame_index = dt3155_fbuffer[ m ]->empty_buffers[ index ]; + printk(" %d ", frame_index ); + } + + frame_index = dt3155_fbuffer[ m ]->active_buf; + printk("\n A: %d", frame_index); + + frame_index = dt3155_fbuffer[ m ]->locked_buf; + printk("\n L: %d \n", frame_index ); + +} + +/***************************************************** + * adjust_4MB + * + * If a buffer intersects the 4MB boundary, push + * the start address up to the beginning of the + * next 4MB chunk (assuming bufsize < 4MB). + *****************************************************/ +u32 adjust_4MB (u32 buf_addr, u32 bufsize) { + if (((buf_addr+bufsize) & UPPER_10_BITS) != (buf_addr & UPPER_10_BITS)) + return (buf_addr+bufsize) & UPPER_10_BITS; + else + return buf_addr; +} + + +/***************************************************** + * allocate_buffers + * + * Try to allocate enough memory for all requested + * buffers. If there is not enough free space + * try for less memory. + *****************************************************/ +void allocate_buffers (u32 *buf_addr, u32* total_size_kbs, + u32 bufsize) +{ + /* Compute the minimum amount of memory guaranteed to hold all + MAXBUFFERS such that no buffer crosses the 4MB boundary. + Store this value in the variable "full_size" */ + + u32 allocator_max; + u32 bufs_per_chunk = (FOUR_MB / bufsize); + u32 filled_chunks = (MAXBUFFERS-1) / bufs_per_chunk; + u32 leftover_bufs = MAXBUFFERS - filled_chunks * bufs_per_chunk; + + u32 full_size = bufsize /* possibly unusable part of 1st chunk */ + + filled_chunks * FOUR_MB /* max # of completely filled 4mb chunks */ + + leftover_bufs * bufsize; /* these buffs will be in a partly filled + chunk at beginning or end */ + + u32 full_size_kbs = 1 + (full_size-1) / 1024; + u32 min_size_kbs = 2*ndevices*bufsize / 1024; + u32 size_kbs; + + /* Now, try to allocate full_size. If this fails, keep trying for + less & less memory until it succeeds. */ +#ifndef STANDALONE_ALLOCATOR + /* initialize the allocator */ + allocator_init(&allocator_max); +#endif + size_kbs = full_size_kbs; + *buf_addr = 0; + printk("DT3155: We would like to get: %d KB\n", full_size_kbs); + printk("DT3155: ...but need at least: %d KB\n", min_size_kbs); + printk("DT3155: ...the allocator has: %d KB\n", allocator_max); + size_kbs = (full_size_kbs <= allocator_max ? full_size_kbs : allocator_max); + if (size_kbs > min_size_kbs) { + if ((*buf_addr = allocator_allocate_dma (size_kbs, GFP_KERNEL)) != 0) { + printk("DT3155: Managed to allocate: %d KB\n", size_kbs); + *total_size_kbs = size_kbs; + return; + } + } + /* If we got here, the allocation failed */ + printk ("DT3155: Allocator failed!\n"); + *buf_addr = 0; + *total_size_kbs = 0; + return; + +} + + +/***************************************************** + * dt3155_setup_buffers + * + * setup_buffers just puts the buffering system into + * a consistent state before the start of interrupts + * + * JML : it looks like all the buffers need to be + * continuous. So I'm going to try and allocate one + * continuous buffer. + * + * GCS : Fix DMA problems when buffer spans + * 4MB boundary. Also, add error checking. This + * function will return -ENOMEM when not enough memory. + *****************************************************/ +u32 dt3155_setup_buffers(u32 *allocatorAddr) + +{ + u32 index; + u32 rambuff_addr; /* start of allocation */ + u32 rambuff_size; /* total size allocated to driver */ + u32 rambuff_acm; /* accumlator, keep track of how much + is left after being split up*/ + u32 rambuff_end; /* end of rambuff */ + u32 numbufs; /* number of useful buffers allocated (per device) */ + u32 bufsize = DT3155_MAX_ROWS * DT3155_MAX_COLS; + int m; /* minor # of device, looped for all devs */ + + /* zero the fbuffer status and address structure */ + for ( m = 0; m < ndevices; m++) + { + dt3155_fbuffer[ m ] = &(dt3155_status[ m ].fbuffer); + + /* Make sure the buffering variables are consistent */ + { + u8 *ptr = (u8 *) dt3155_fbuffer[ m ]; + for( index = 0; index < sizeof(struct dt3155_fbuffer_s); index++) + *(ptr++)=0; + } + } + + /* allocate a large contiguous chunk of RAM */ + allocate_buffers (&rambuff_addr, &rambuff_size, bufsize); + printk("DT3155: mem info\n"); + printk(" - rambuf_addr = 0x%x \n", rambuff_addr); + printk(" - length (kb) = %u \n", rambuff_size); + if( rambuff_addr == 0 ) + { + printk( KERN_INFO + "DT3155: Error setup_buffers() allocator dma failed \n" ); + return -ENOMEM; + } + *allocatorAddr = rambuff_addr; + rambuff_end = rambuff_addr + 1024 * rambuff_size; + + /* after allocation, we need to count how many useful buffers there + are so we can give an equal number to each device */ + rambuff_acm = rambuff_addr; + for ( index = 0; index < MAXBUFFERS; index++) { + rambuff_acm = adjust_4MB (rambuff_acm, bufsize);/*avoid spanning 4MB bdry*/ + if (rambuff_acm + bufsize > rambuff_end) + break; + rambuff_acm += bufsize; + } + /* Following line is OK, will waste buffers if index + * not evenly divisible by ndevices -NJC*/ + numbufs = index / ndevices; + printk(" - numbufs = %u\n", numbufs); + if (numbufs < 2) { + printk( KERN_INFO + "DT3155: Error setup_buffers() couldn't allocate 2 bufs/board\n" ); + return -ENOMEM; + } + + /* now that we have board memory we spit it up */ + /* between the boards and the buffers */ + rambuff_acm = rambuff_addr; + for ( m = 0; m < ndevices; m ++) + { + rambuff_acm = adjust_4MB (rambuff_acm, bufsize); + + /* Save the start of this boards buffer space (for mmap). */ + dt3155_status[ m ].mem_addr = rambuff_acm; + + for (index = 0; index < numbufs; index++) + { + rambuff_acm = adjust_4MB (rambuff_acm, bufsize); + if (rambuff_acm + bufsize > rambuff_end) { + /* Should never happen */ + printk ("DT3155 PROGRAM ERROR (GCS)\n" + "Error distributing allocated buffers\n"); + return -ENOMEM; + } + + dt3155_fbuffer[ m ]->frame_info[ index ].addr = rambuff_acm; + push_empty( index, m ); + /* printk(" - Buffer : %lx\n", + * dt3155_fbuffer[ m ]->frame_info[ index ].addr ); + */ + dt3155_fbuffer[ m ]->nbuffers += 1; + rambuff_acm += bufsize; + } + + /* Make sure there is an active buffer there. */ + dt3155_fbuffer[ m ]->active_buf = pop_empty( m ); + dt3155_fbuffer[ m ]->even_happened = 0; + dt3155_fbuffer[ m ]->even_stopped = 0; + + /* make sure there is no locked_buf JML 2/28/00 */ + dt3155_fbuffer[ m ]->locked_buf = -1; + + dt3155_status[ m ].mem_size = + rambuff_acm - dt3155_status[ m ].mem_addr; + + /* setup the ready queue */ + dt3155_fbuffer[ m ]->ready_head = 0; + dt3155_fbuffer[ m ]->ready_len = 0; + printk("Available buffers for device %d: %d\n", + m, dt3155_fbuffer[ m ]->nbuffers); + } + + return 1; +} + +/***************************************************** + * internal_release_locked_buffer + * + * The internal function for releasing a locked buffer. + * It assumes interrupts are turned off. + * + * m is minor number of device + *****************************************************/ +static inline void internal_release_locked_buffer( int m ) +{ + /* Pointer into global structure for handling buffers */ + if ( dt3155_fbuffer[ m ]->locked_buf >= 0 ) + { + push_empty( dt3155_fbuffer[ m ]->locked_buf, m ); + dt3155_fbuffer[ m ]->locked_buf = -1; + } +} + + +/***************************************************** + * dt3155_release_locked_buffer() + * m is minor # of device + * + * The user function of the above. + * + *****************************************************/ +inline void dt3155_release_locked_buffer( int m ) +{ + unsigned long int flags; + local_save_flags(flags); + local_irq_disable(); + internal_release_locked_buffer(m); + local_irq_restore(flags); +} + + +/***************************************************** + * dt3155_flush() + * m is minor # of device + * + *****************************************************/ +inline int dt3155_flush( int m ) +{ + int index; + unsigned long int flags; + local_save_flags(flags); + local_irq_disable(); + + internal_release_locked_buffer( m ); + dt3155_fbuffer[ m ]->empty_len = 0; + + for ( index = 0; index < dt3155_fbuffer[ m ]->nbuffers; index++ ) + push_empty( index, m ); + + /* Make sure there is an active buffer there. */ + dt3155_fbuffer[ m ]->active_buf = pop_empty( m ); + + dt3155_fbuffer[ m ]->even_happened = 0; + dt3155_fbuffer[ m ]->even_stopped = 0; + + /* setup the ready queue */ + dt3155_fbuffer[ m ]->ready_head = 0; + dt3155_fbuffer[ m ]->ready_len = 0; + + local_irq_restore(flags); + + return 0; +} + +/***************************************************** + * dt3155_get_ready_buffer() + * m is minor # of device + * + * get_ready_buffer will grab the next chunk of data + * if it is already there, otherwise it returns 0. + * If the user has a buffer locked it will unlock + * that buffer before returning the new one. + *****************************************************/ +inline int dt3155_get_ready_buffer( int m ) +{ + int frame_index; + unsigned long int flags; + local_save_flags(flags); + local_irq_disable(); + +#ifdef DEBUG_QUES_A + printques( m ); +#endif + + internal_release_locked_buffer( m ); + + if (is_ready_buf_empty( m )) + frame_index = -1; + else + { + frame_index = pop_ready( m ); + dt3155_fbuffer[ m ]->locked_buf = frame_index; + } + +#ifdef DEBUG_QUES_B + printques( m ); +#endif + + local_irq_restore(flags); + + return frame_index; +} diff --git a/drivers/staging/dt3155/dt3155_isr.h b/drivers/staging/dt3155/dt3155_isr.h new file mode 100644 index 0000000..7595cb1 --- /dev/null +++ b/drivers/staging/dt3155/dt3155_isr.h @@ -0,0 +1,77 @@ +/* + +Copyright 1996,2002 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan, + Jason Lapenta, Scott Smedley + +This file is part of the DT3155 Device Driver. + +The DT3155 Device Driver is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The DT3155 Device Driver is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty +of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with the DT3155 Device Driver; if not, write to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +MA 02111-1307 USA + + +-- Changes -- + + Date Programmer Description of changes made + ------------------------------------------------------------------- + 03-Jul-2000 JML n/a + 24-Jul-2002 SS GPL licence. + 26-Oct-2009 SS Porting to 2.6.30 kernel. + +-- notes -- + +*/ + +#ifndef DT3155_ISR_H +#define DT3155_ISR_H + +extern struct dt3155_fbuffer_s *dt3155_fbuffer[MAXBOARDS]; + +/* User functions for buffering */ +/* Initialize the buffering system. This should */ +/* be called prior to enabling interrupts */ + +u32 dt3155_setup_buffers(u32 *allocatorAddr); + +/* Get the next frame of data if it is ready. Returns */ +/* zero if no data is ready. If there is data but */ +/* the user has a locked buffer, it will unlock that */ +/* buffer and return it to the free list. */ + +int dt3155_get_ready_buffer(int minor); + +/* Return a locked buffer to the free list */ + +void dt3155_release_locked_buffer(int minor); + +/* Flush the buffer system */ +int dt3155_flush(int minor); + +/********************************** + * Simple array based que struct + **********************************/ + +bool are_empty_buffers(int minor); +void push_empty(int index, int minor); + +int pop_empty(int minor); + +bool is_ready_buf_empty(int minor); +bool is_ready_buf_full(int minor); + +void push_ready(int minor, int index); +int pop_ready(int minor); + + +#endif diff --git a/drivers/staging/et131x/et1310_address_map.h b/drivers/staging/et131x/et1310_address_map.h index e715e4d..ea746ba 100644 --- a/drivers/staging/et131x/et1310_address_map.h +++ b/drivers/staging/et131x/et1310_address_map.h @@ -149,7 +149,7 @@ * GLOBAL Module of JAGCore Address Mapping * Located at address 0x0000 */ -typedef struct _GLOBAL_t { /* Location: */ +struct global_regs { /* Location: */ u32 txq_start_addr; /* 0x0000 */ u32 txq_end_addr; /* 0x0004 */ u32 rxq_start_addr; /* 0x0008 */ @@ -165,9 +165,7 @@ typedef struct _GLOBAL_t { /* Location: */ u32 msi_config; /* 0x0030 */ u32 loopback; /* 0x0034 */ u32 watchdog_timer; /* 0x0038 */ -} GLOBAL_t, *PGLOBAL_t; - -/* END OF GLOBAL REGISTER ADDRESS MAP */ +}; /* START OF TXDMA REGISTER ADDRESS MAP */ @@ -255,7 +253,7 @@ extern inline void add_12bit(u32 *v, int n) * Tx DMA Module of JAGCore Address Mapping * Located at address 0x1000 */ -typedef struct _TXDMA_t { /* Location: */ +struct txdma_regs { /* Location: */ u32 csr; /* 0x1000 */ u32 pr_base_hi; /* 0x1004 */ u32 pr_base_lo; /* 0x1008 */ @@ -282,7 +280,7 @@ typedef struct _TXDMA_t { /* Location: */ u32 DroppedTLPCount; /* 0x105c */ u32 NewServiceComplete; /* 0x1060 */ u32 EthernetPacketCount; /* 0x1064 */ -} TXDMA_t, *PTXDMA_t; +}; /* END OF TXDMA REGISTER ADDRESS MAP */ @@ -292,45 +290,25 @@ typedef struct _TXDMA_t { /* Location: */ /* * structure for control status reg in rxdma address map * Located at address 0x2000 + * + * CSR + * 0: halt + * 1-3: tc + * 4: fbr_big_endian + * 5: psr_big_endian + * 6: pkt_big_endian + * 7: dma_big_endian + * 8-9: fbr0_size + * 10: fbr0_enable + * 11-12: fbr1_size + * 13: fbr1_enable + * 14: unused + * 15: pkt_drop_disable + * 16: pkt_done_flush + * 17: halt_status + * 18-31: unused */ -typedef union _RXDMA_CSR_t { - u32 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u32 unused2:14; /* bits 18-31 */ - u32 halt_status:1; /* bit 17 */ - u32 pkt_done_flush:1; /* bit 16 */ - u32 pkt_drop_disable:1; /* bit 15 */ - u32 unused1:1; /* bit 14 */ - u32 fbr1_enable:1; /* bit 13 */ - u32 fbr1_size:2; /* bits 11-12 */ - u32 fbr0_enable:1; /* bit 10 */ - u32 fbr0_size:2; /* bits 8-9 */ - u32 dma_big_endian:1; /* bit 7 */ - u32 pkt_big_endian:1; /* bit 6 */ - u32 psr_big_endian:1; /* bit 5 */ - u32 fbr_big_endian:1; /* bit 4 */ - u32 tc:3; /* bits 1-3 */ - u32 halt:1; /* bit 0 */ -#else - u32 halt:1; /* bit 0 */ - u32 tc:3; /* bits 1-3 */ - u32 fbr_big_endian:1; /* bit 4 */ - u32 psr_big_endian:1; /* bit 5 */ - u32 pkt_big_endian:1; /* bit 6 */ - u32 dma_big_endian:1; /* bit 7 */ - u32 fbr0_size:2; /* bits 8-9 */ - u32 fbr0_enable:1; /* bit 10 */ - u32 fbr1_size:2; /* bits 11-12 */ - u32 fbr1_enable:1; /* bit 13 */ - u32 unused1:1; /* bit 14 */ - u32 pkt_drop_disable:1; /* bit 15 */ - u32 pkt_done_flush:1; /* bit 16 */ - u32 halt_status:1; /* bit 17 */ - u32 unused2:14; /* bits 18-31 */ -#endif - } bits; -} RXDMA_CSR_t, *PRXDMA_CSR_t; + /* * structure for dma writeback lo reg in rxdma address map @@ -451,18 +429,6 @@ typedef union _RXDMA_CSR_t { * 31-10: unused * 9-0: fbr ndesc */ -typedef union _RXDMA_FBR_NUM_DES_t { - u32 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u32 unused:22; /* bits 10-31 */ - u32 fbr_ndesc:10; /* bits 0-9 */ -#else - u32 fbr_ndesc:10; /* bits 0-9 */ - u32 unused:22; /* bits 10-31 */ -#endif - } bits; -} RXDMA_FBR_NUM_DES_t, *PRXDMA_FBR_NUM_DES_t; /* * structure for free buffer ring 0 available offset reg in rxdma address map @@ -532,8 +498,8 @@ typedef union _RXDMA_FBR_NUM_DES_t { * Rx DMA Module of JAGCore Address Mapping * Located at address 0x2000 */ -typedef struct _RXDMA_t { /* Location: */ - RXDMA_CSR_t csr; /* 0x2000 */ +struct rxdma_regs { /* Location: */ + u32 csr; /* 0x2000 */ u32 dma_wb_base_lo; /* 0x2004 */ u32 dma_wb_base_hi; /* 0x2008 */ u32 num_pkt_done; /* 0x200C */ @@ -562,7 +528,7 @@ typedef struct _RXDMA_t { /* Location: */ u32 fbr1_full_offset; /* 0x2068 */ u32 fbr1_rd_index; /* 0x206C */ u32 fbr1_min_des; /* 0x2070 */ -} RXDMA_t, *PRXDMA_t; +}; /* END OF RXDMA REGISTER ADDRESS MAP */ @@ -572,33 +538,18 @@ typedef struct _RXDMA_t { /* Location: */ /* * structure for control reg in txmac address map * located at address 0x3000 + * + * bits + * 31-8: unused + * 7: cklseg_disable + * 6: ckbcnt_disable + * 5: cksegnum + * 4: async_disable + * 3: fc_disable + * 2: mcif_disable + * 1: mif_disable + * 0: txmac_en */ -typedef union _TXMAC_CTL_t { - u32 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u32 unused:24; /* bits 8-31 */ - u32 cklseg_diable:1; /* bit 7 */ - u32 ckbcnt_disable:1; /* bit 6 */ - u32 cksegnum:1; /* bit 5 */ - u32 async_disable:1; /* bit 4 */ - u32 fc_disable:1; /* bit 3 */ - u32 mcif_disable:1; /* bit 2 */ - u32 mif_disable:1; /* bit 1 */ - u32 txmac_en:1; /* bit 0 */ -#else - u32 txmac_en:1; /* bit 0 */ - u32 mif_disable:1; /* bit 1 mac interface */ - u32 mcif_disable:1; /* bit 2 mem. contr. interface */ - u32 fc_disable:1; /* bit 3 */ - u32 async_disable:1; /* bit 4 */ - u32 cksegnum:1; /* bit 5 */ - u32 ckbcnt_disable:1; /* bit 6 */ - u32 cklseg_diable:1; /* bit 7 */ - u32 unused:24; /* bits 8-31 */ -#endif - } bits; -} TXMAC_CTL_t, *PTXMAC_CTL_t; /* * structure for shadow pointer reg in txmac address map @@ -612,23 +563,12 @@ typedef union _TXMAC_CTL_t { /* * structure for error count reg in txmac address map * located at address 0x3008 + * + * 31-12: unused + * 11-8: reserved + * 7-4: txq_underrun + * 3-0: fifo_underrun */ -typedef union _TXMAC_ERR_CNT_t { - u32 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u32 unused:20; /* bits 12-31 */ - u32 reserved:4; /* bits 8-11 */ - u32 txq_underrun:4; /* bits 4-7 */ - u32 fifo_underrun:4; /* bits 0-3 */ -#else - u32 fifo_underrun:4; /* bits 0-3 */ - u32 txq_underrun:4; /* bits 4-7 */ - u32 reserved:4; /* bits 8-11 */ - u32 unused:20; /* bits 12-31 */ -#endif - } bits; -} TXMAC_ERR_CNT_t, *PTXMAC_ERR_CNT_t; /* * structure for max fill reg in txmac address map @@ -657,64 +597,32 @@ typedef union _TXMAC_ERR_CNT_t { /* * structure for error reg in txmac address map * located at address 0x3018 + * + * 31-9: unused + * 8: fifo_underrun + * 7-6: unused + * 5: ctrl2_err + * 4: txq_underrun + * 3: bcnt_err + * 2: lseg_err + * 1: segnum_err + * 0: seg0_err */ -typedef union _TXMAC_ERR_t { - u32 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u32 unused2:23; /* bits 9-31 */ - u32 fifo_underrun:1; /* bit 8 */ - u32 unused1:2; /* bits 6-7 */ - u32 ctrl2_err:1; /* bit 5 */ - u32 txq_underrun:1; /* bit 4 */ - u32 bcnt_err:1; /* bit 3 */ - u32 lseg_err:1; /* bit 2 */ - u32 segnum_err:1; /* bit 1 */ - u32 seg0_err:1; /* bit 0 */ -#else - u32 seg0_err:1; /* bit 0 */ - u32 segnum_err:1; /* bit 1 */ - u32 lseg_err:1; /* bit 2 */ - u32 bcnt_err:1; /* bit 3 */ - u32 txq_underrun:1; /* bit 4 */ - u32 ctrl2_err:1; /* bit 5 */ - u32 unused1:2; /* bits 6-7 */ - u32 fifo_underrun:1; /* bit 8 */ - u32 unused2:23; /* bits 9-31 */ -#endif - } bits; -} TXMAC_ERR_t, *PTXMAC_ERR_t; /* * structure for error interrupt reg in txmac address map * located at address 0x301C + * + * 31-9: unused + * 8: fifo_underrun + * 7-6: unused + * 5: ctrl2_err + * 4: txq_underrun + * 3: bcnt_err + * 2: lseg_err + * 1: segnum_err + * 0: seg0_err */ -typedef union _TXMAC_ERR_INT_t { - u32 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u32 unused2:23; /* bits 9-31 */ - u32 fifo_underrun:1; /* bit 8 */ - u32 unused1:2; /* bits 6-7 */ - u32 ctrl2_err:1; /* bit 5 */ - u32 txq_underrun:1; /* bit 4 */ - u32 bcnt_err:1; /* bit 3 */ - u32 lseg_err:1; /* bit 2 */ - u32 segnum_err:1; /* bit 1 */ - u32 seg0_err:1; /* bit 0 */ -#else - u32 seg0_err:1; /* bit 0 */ - u32 segnum_err:1; /* bit 1 */ - u32 lseg_err:1; /* bit 2 */ - u32 bcnt_err:1; /* bit 3 */ - u32 txq_underrun:1; /* bit 4 */ - u32 ctrl2_err:1; /* bit 5 */ - u32 unused1:2; /* bits 6-7 */ - u32 fifo_underrun:1; /* bit 8 */ - u32 unused2:23; /* bits 9-31 */ -#endif - } bits; -} TXMAC_ERR_INT_t, *PTXMAC_ERR_INT_t; /* * structure for error interrupt reg in txmac address map @@ -728,17 +636,17 @@ typedef union _TXMAC_ERR_INT_t { /* * Tx MAC Module of JAGCore Address Mapping */ -typedef struct _TXMAC_t { /* Location: */ - TXMAC_CTL_t ctl; /* 0x3000 */ +struct txmac_regs { /* Location: */ + u32 ctl; /* 0x3000 */ u32 shadow_ptr; /* 0x3004 */ - TXMAC_ERR_CNT_t err_cnt; /* 0x3008 */ + u32 err_cnt; /* 0x3008 */ u32 max_fill; /* 0x300C */ u32 cf_param; /* 0x3010 */ u32 tx_test; /* 0x3014 */ - TXMAC_ERR_t err; /* 0x3018 */ - TXMAC_ERR_INT_t err_int; /* 0x301C */ + u32 err; /* 0x3018 */ + u32 err_int; /* 0x301C */ u32 bp_ctrl; /* 0x3020 */ -} TXMAC_t, *PTXMAC_t; +}; /* END OF TXMAC REGISTER ADDRESS MAP */ @@ -747,106 +655,47 @@ typedef struct _TXMAC_t { /* Location: */ /* * structure for rxmac control reg in rxmac address map * located at address 0x4000 + * + * 31-7: reserved + * 6: rxmac_int_disable + * 5: async_disable + * 4: mif_disable + * 3: wol_disable + * 2: pkt_filter_disable + * 1: mcif_disable + * 0: rxmac_en */ -typedef union _RXMAC_CTRL_t { - u32 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u32 reserved:25; /* bits 7-31 */ - u32 rxmac_int_disable:1; /* bit 6 */ - u32 async_disable:1; /* bit 5 */ - u32 mif_disable:1; /* bit 4 */ - u32 wol_disable:1; /* bit 3 */ - u32 pkt_filter_disable:1; /* bit 2 */ - u32 mcif_disable:1; /* bit 1 */ - u32 rxmac_en:1; /* bit 0 */ -#else - u32 rxmac_en:1; /* bit 0 */ - u32 mcif_disable:1; /* bit 1 */ - u32 pkt_filter_disable:1; /* bit 2 */ - u32 wol_disable:1; /* bit 3 */ - u32 mif_disable:1; /* bit 4 */ - u32 async_disable:1; /* bit 5 */ - u32 rxmac_int_disable:1; /* bit 6 */ - u32 reserved:25; /* bits 7-31 */ -#endif - } bits; -} RXMAC_CTRL_t, *PRXMAC_CTRL_t; /* * structure for Wake On Lan Control and CRC 0 reg in rxmac address map * located at address 0x4004 + * 31-16: crc + * 15-12: reserved + * 11: ignore_pp + * 10: ignore_mp + * 9: clr_intr + * 8: ignore_link_chg + * 7: ignore_uni + * 6: ignore_multi + * 5: ignore_broad + * 4-0: valid_crc 4-0 */ -typedef union _RXMAC_WOL_CTL_CRC0_t { - u32 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u32 crc0:16; /* bits 16-31 */ - u32 reserve:4; /* bits 12-15 */ - u32 ignore_pp:1; /* bit 11 */ - u32 ignore_mp:1; /* bit 10 */ - u32 clr_intr:1; /* bit 9 */ - u32 ignore_link_chg:1; /* bit 8 */ - u32 ignore_uni:1; /* bit 7 */ - u32 ignore_multi:1; /* bit 6 */ - u32 ignore_broad:1; /* bit 5 */ - u32 valid_crc4:1; /* bit 4 */ - u32 valid_crc3:1; /* bit 3 */ - u32 valid_crc2:1; /* bit 2 */ - u32 valid_crc1:1; /* bit 1 */ - u32 valid_crc0:1; /* bit 0 */ -#else - u32 valid_crc0:1; /* bit 0 */ - u32 valid_crc1:1; /* bit 1 */ - u32 valid_crc2:1; /* bit 2 */ - u32 valid_crc3:1; /* bit 3 */ - u32 valid_crc4:1; /* bit 4 */ - u32 ignore_broad:1; /* bit 5 */ - u32 ignore_multi:1; /* bit 6 */ - u32 ignore_uni:1; /* bit 7 */ - u32 ignore_link_chg:1; /* bit 8 */ - u32 clr_intr:1; /* bit 9 */ - u32 ignore_mp:1; /* bit 10 */ - u32 ignore_pp:1; /* bit 11 */ - u32 reserve:4; /* bits 12-15 */ - u32 crc0:16; /* bits 16-31 */ -#endif - } bits; -} RXMAC_WOL_CTL_CRC0_t, *PRXMAC_WOL_CTL_CRC0_t; /* * structure for CRC 1 and CRC 2 reg in rxmac address map * located at address 0x4008 + * + * 31-16: crc2 + * 15-0: crc1 */ -typedef union _RXMAC_WOL_CRC12_t { - u32 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u32 crc2:16; /* bits 16-31 */ - u32 crc1:16; /* bits 0-15 */ -#else - u32 crc1:16; /* bits 0-15 */ - u32 crc2:16; /* bits 16-31 */ -#endif - } bits; -} RXMAC_WOL_CRC12_t, *PRXMAC_WOL_CRC12_t; /* * structure for CRC 3 and CRC 4 reg in rxmac address map * located at address 0x400C + * + * 31-16: crc4 + * 15-0: crc3 */ -typedef union _RXMAC_WOL_CRC34_t { - u32 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u32 crc4:16; /* bits 16-31 */ - u32 crc3:16; /* bits 0-15 */ -#else - u32 crc3:16; /* bits 0-15 */ - u32 crc4:16; /* bits 16-31 */ -#endif - } bits; -} RXMAC_WOL_CRC34_t, *PRXMAC_WOL_CRC34_t; /* * structure for Wake On Lan Source Address Lo reg in rxmac address map @@ -966,164 +815,84 @@ typedef union _RXMAC_UNI_PF_ADDR3_t { /* * structure for Packet Filter Control reg in rxmac address map * located at address 0x4084 + * + * 31-23: unused + * 22-16: min_pkt_size + * 15-4: unused + * 3: filter_frag_en + * 2: filter_uni_en + * 1: filter_multi_en + * 0: filter_broad_en */ -typedef union _RXMAC_PF_CTRL_t { - u32 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u32 unused2:9; /* bits 23-31 */ - u32 min_pkt_size:7; /* bits 16-22 */ - u32 unused1:12; /* bits 4-15 */ - u32 filter_frag_en:1; /* bit 3 */ - u32 filter_uni_en:1; /* bit 2 */ - u32 filter_multi_en:1; /* bit 1 */ - u32 filter_broad_en:1; /* bit 0 */ -#else - u32 filter_broad_en:1; /* bit 0 */ - u32 filter_multi_en:1; /* bit 1 */ - u32 filter_uni_en:1; /* bit 2 */ - u32 filter_frag_en:1; /* bit 3 */ - u32 unused1:12; /* bits 4-15 */ - u32 min_pkt_size:7; /* bits 16-22 */ - u32 unused2:9; /* bits 23-31 */ -#endif - } bits; -} RXMAC_PF_CTRL_t, *PRXMAC_PF_CTRL_t; /* * structure for Memory Controller Interface Control Max Segment reg in rxmac * address map. Located at address 0x4088 + * + * 31-10: reserved + * 9-2: max_size + * 1: fc_en + * 0: seg_en */ -typedef union _RXMAC_MCIF_CTRL_MAX_SEG_t { - u32 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u32 reserved:22; /* bits 10-31 */ - u32 max_size:8; /* bits 2-9 */ - u32 fc_en:1; /* bit 1 */ - u32 seg_en:1; /* bit 0 */ -#else - u32 seg_en:1; /* bit 0 */ - u32 fc_en:1; /* bit 1 */ - u32 max_size:8; /* bits 2-9 */ - u32 reserved:22; /* bits 10-31 */ -#endif - } bits; -} RXMAC_MCIF_CTRL_MAX_SEG_t, *PRXMAC_MCIF_CTRL_MAX_SEG_t; /* * structure for Memory Controller Interface Water Mark reg in rxmac address * map. Located at address 0x408C + * + * 31-26: unused + * 25-16: mark_hi + * 15-10: unused + * 9-0: mark_lo */ -typedef union _RXMAC_MCIF_WATER_MARK_t { - u32 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u32 reserved2:6; /* bits 26-31 */ - u32 mark_hi:10; /* bits 16-25 */ - u32 reserved1:6; /* bits 10-15 */ - u32 mark_lo:10; /* bits 0-9 */ -#else - u32 mark_lo:10; /* bits 0-9 */ - u32 reserved1:6; /* bits 10-15 */ - u32 mark_hi:10; /* bits 16-25 */ - u32 reserved2:6; /* bits 26-31 */ -#endif - } bits; -} RXMAC_MCIF_WATER_MARK_t, *PRXMAC_MCIF_WATER_MARK_t; /* * structure for Rx Queue Dialog reg in rxmac address map. * located at address 0x4090 + * + * 31-26: reserved + * 25-16: rd_ptr + * 15-10: reserved + * 9-0: wr_ptr */ -typedef union _RXMAC_RXQ_DIAG_t { - u32 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u32 reserved2:6; /* bits 26-31 */ - u32 rd_ptr:10; /* bits 16-25 */ - u32 reserved1:6; /* bits 10-15 */ - u32 wr_ptr:10; /* bits 0-9 */ -#else - u32 wr_ptr:10; /* bits 0-9 */ - u32 reserved1:6; /* bits 10-15 */ - u32 rd_ptr:10; /* bits 16-25 */ - u32 reserved2:6; /* bits 26-31 */ -#endif - } bits; -} RXMAC_RXQ_DIAG_t, *PRXMAC_RXQ_DIAG_t; /* * structure for space availiable reg in rxmac address map. * located at address 0x4094 + * + * 31-17: reserved + * 16: space_avail_en + * 15-10: reserved + * 9-0: space_avail */ -typedef union _RXMAC_SPACE_AVAIL_t { - u32 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u32 reserved2:15; /* bits 17-31 */ - u32 space_avail_en:1; /* bit 16 */ - u32 reserved1:6; /* bits 10-15 */ - u32 space_avail:10; /* bits 0-9 */ -#else - u32 space_avail:10; /* bits 0-9 */ - u32 reserved1:6; /* bits 10-15 */ - u32 space_avail_en:1; /* bit 16 */ - u32 reserved2:15; /* bits 17-31 */ -#endif - } bits; -} RXMAC_SPACE_AVAIL_t, *PRXMAC_SPACE_AVAIL_t; /* * structure for management interface reg in rxmac address map. * located at address 0x4098 + * + * 31-18: reserved + * 17: drop_pkt_en + * 16-0: drop_pkt_mask */ -typedef union _RXMAC_MIF_CTL_t { - u32 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u32 reserve:14; /* bits 18-31 */ - u32 drop_pkt_en:1; /* bit 17 */ - u32 drop_pkt_mask:17; /* bits 0-16 */ -#else - u32 drop_pkt_mask:17; /* bits 0-16 */ - u32 drop_pkt_en:1; /* bit 17 */ - u32 reserve:14; /* bits 18-31 */ -#endif - } bits; -} RXMAC_MIF_CTL_t, *PRXMAC_MIF_CTL_t; /* * structure for Error reg in rxmac address map. * located at address 0x409C + * + * 31-4: unused + * 3: mif + * 2: async + * 1: pkt_filter + * 0: mcif */ -typedef union _RXMAC_ERROR_REG_t { - u32 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u32 reserve:28; /* bits 4-31 */ - u32 mif:1; /* bit 3 */ - u32 async:1; /* bit 2 */ - u32 pkt_filter:1; /* bit 1 */ - u32 mcif:1; /* bit 0 */ -#else - u32 mcif:1; /* bit 0 */ - u32 pkt_filter:1; /* bit 1 */ - u32 async:1; /* bit 2 */ - u32 mif:1; /* bit 3 */ - u32 reserve:28; /* bits 4-31 */ -#endif - } bits; -} RXMAC_ERROR_REG_t, *PRXMAC_ERROR_REG_t; /* * Rx MAC Module of JAGCore Address Mapping */ typedef struct _RXMAC_t { /* Location: */ - RXMAC_CTRL_t ctrl; /* 0x4000 */ - RXMAC_WOL_CTL_CRC0_t crc0; /* 0x4004 */ - RXMAC_WOL_CRC12_t crc12; /* 0x4008 */ - RXMAC_WOL_CRC34_t crc34; /* 0x400C */ + u32 ctrl; /* 0x4000 */ + u32 crc0; /* 0x4004 */ + u32 crc12; /* 0x4008 */ + u32 crc34; /* 0x400C */ RXMAC_WOL_SA_LO_t sa_lo; /* 0x4010 */ RXMAC_WOL_SA_HI_t sa_hi; /* 0x4014 */ u32 mask0_word0; /* 0x4018 */ @@ -1153,17 +922,17 @@ typedef struct _RXMAC_t { /* Location: */ u32 multi_hash2; /* 0x4078 */ u32 multi_hash3; /* 0x407C */ u32 multi_hash4; /* 0x4080 */ - RXMAC_PF_CTRL_t pf_ctrl; /* 0x4084 */ - RXMAC_MCIF_CTRL_MAX_SEG_t mcif_ctrl_max_seg; /* 0x4088 */ - RXMAC_MCIF_WATER_MARK_t mcif_water_mark; /* 0x408C */ - RXMAC_RXQ_DIAG_t rxq_diag; /* 0x4090 */ - RXMAC_SPACE_AVAIL_t space_avail; /* 0x4094 */ - - RXMAC_MIF_CTL_t mif_ctrl; /* 0x4098 */ - RXMAC_ERROR_REG_t err_reg; /* 0x409C */ + u32 pf_ctrl; /* 0x4084 */ + u32 mcif_ctrl_max_seg; /* 0x4088 */ + u32 mcif_water_mark; /* 0x408C */ + u32 rxq_diag; /* 0x4090 */ + u32 space_avail; /* 0x4094 */ + + u32 mif_ctrl; /* 0x4098 */ + u32 err_reg; /* 0x409C */ } RXMAC_t, *PRXMAC_t; -/* END OF TXMAC REGISTER ADDRESS MAP */ +/* END OF RXMAC REGISTER ADDRESS MAP */ /* START OF MAC REGISTER ADDRESS MAP */ @@ -1337,37 +1106,19 @@ typedef struct _RXMAC_t { /* Location: */ /* * structure for Interface Status reg in mac address map. * located at address 0x503C + * + * 31-10: reserved + * 9: excess_defer + * 8: clash + * 7: phy_jabber + * 6: phy_link_ok + * 5: phy_full_duplex + * 4: phy_speed + * 3: pe100x_link_fail + * 2: pe10t_loss_carrier + * 1: pe10t_sqe_error + * 0: pe10t_jabber */ -typedef union _MAC_IF_STAT_t { - u32 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u32 reserved:22; /* bits 10-31 */ - u32 excess_defer:1; /* bit 9 */ - u32 clash:1; /* bit 8 */ - u32 phy_jabber:1; /* bit 7 */ - u32 phy_link_ok:1; /* bit 6 */ - u32 phy_full_duplex:1; /* bit 5 */ - u32 phy_speed:1; /* bit 4 */ - u32 pe100x_link_fail:1; /* bit 3 */ - u32 pe10t_loss_carrie:1; /* bit 2 */ - u32 pe10t_sqe_error:1; /* bit 1 */ - u32 pe10t_jabber:1; /* bit 0 */ -#else - u32 pe10t_jabber:1; /* bit 0 */ - u32 pe10t_sqe_error:1; /* bit 1 */ - u32 pe10t_loss_carrie:1; /* bit 2 */ - u32 pe100x_link_fail:1; /* bit 3 */ - u32 phy_speed:1; /* bit 4 */ - u32 phy_full_duplex:1; /* bit 5 */ - u32 phy_link_ok:1; /* bit 6 */ - u32 phy_jabber:1; /* bit 7 */ - u32 clash:1; /* bit 8 */ - u32 excess_defer:1; /* bit 9 */ - u32 reserved:22; /* bits 10-31 */ -#endif - } bits; -} MAC_IF_STAT_t, *PMAC_IF_STAT_t; /* * structure for Mac Station Address, Part 1 reg in mac address map. @@ -1428,7 +1179,7 @@ typedef struct _MAC_t { /* Location: */ u32 mii_mgmt_stat; /* 0x5030 */ u32 mii_mgmt_indicator; /* 0x5034 */ u32 if_ctrl; /* 0x5038 */ - MAC_IF_STAT_t if_stat; /* 0x503C */ + u32 if_stat; /* 0x503C */ MAC_STATION_ADDR1_t station_addr_1; /* 0x5040 */ MAC_STATION_ADDR2_t station_addr_2; /* 0x5044 */ } MAC_t, *PMAC_t; @@ -1498,8 +1249,9 @@ typedef struct _MAC_t { /* Location: */ /* * MAC STATS Module of JAGCore Address Mapping */ -typedef struct _MAC_STAT_t { /* Location: */ - u32 pad[32]; /* 0x6000 - 607C */ +struct macstat_regs +{ /* Location: */ + u32 pad[32]; /* 0x6000 - 607C */ /* Tx/Rx 0-64 Byte Frame Counter */ u32 TR64; /* 0x6080 */ @@ -1644,7 +1396,7 @@ typedef struct _MAC_STAT_t { /* Location: */ /* Carry Register Two Mask Register */ u32 Carry2M; /* 0x613C */ -} MAC_STAT_t, *PMAC_STAT_t; +}; /* END OF MAC STAT REGISTER ADDRESS MAP */ @@ -1682,70 +1434,49 @@ typedef struct _MAC_STAT_t { /* Location: */ /* * Memory Control Module of JAGCore Address Mapping */ -typedef struct _MMC_t { /* Location: */ +struct mmc_regs { /* Location: */ u32 mmc_ctrl; /* 0x7000 */ u32 sram_access; /* 0x7004 */ u32 sram_word1; /* 0x7008 */ u32 sram_word2; /* 0x700C */ u32 sram_word3; /* 0x7010 */ u32 sram_word4; /* 0x7014 */ -} MMC_t, *PMMC_t; +}; /* END OF MMC REGISTER ADDRESS MAP */ -/* START OF EXP ROM REGISTER ADDRESS MAP */ - -/* - * Expansion ROM Module of JAGCore Address Mapping - */ - -/* Take this out until it is not empty */ -#if 0 -typedef struct _EXP_ROM_t { - -} EXP_ROM_t, *PEXP_ROM_t; -#endif - -/* END OF EXP ROM REGISTER ADDRESS MAP */ - - /* * JAGCore Address Mapping */ typedef struct _ADDRESS_MAP_t { - GLOBAL_t global; + struct global_regs global; /* unused section of global address map */ - u8 unused_global[4096 - sizeof(GLOBAL_t)]; - TXDMA_t txdma; + u8 unused_global[4096 - sizeof(struct global_regs)]; + struct txdma_regs txdma; /* unused section of txdma address map */ - u8 unused_txdma[4096 - sizeof(TXDMA_t)]; - RXDMA_t rxdma; + u8 unused_txdma[4096 - sizeof(struct txdma_regs)]; + struct rxdma_regs rxdma; /* unused section of rxdma address map */ - u8 unused_rxdma[4096 - sizeof(RXDMA_t)]; - TXMAC_t txmac; + u8 unused_rxdma[4096 - sizeof(struct rxdma_regs)]; + struct txmac_regs txmac; /* unused section of txmac address map */ - u8 unused_txmac[4096 - sizeof(TXMAC_t)]; + u8 unused_txmac[4096 - sizeof(struct txmac_regs)]; RXMAC_t rxmac; /* unused section of rxmac address map */ u8 unused_rxmac[4096 - sizeof(RXMAC_t)]; MAC_t mac; /* unused section of mac address map */ u8 unused_mac[4096 - sizeof(MAC_t)]; - MAC_STAT_t macStat; + struct macstat_regs macstat; /* unused section of mac stat address map */ - u8 unused_mac_stat[4096 - sizeof(MAC_STAT_t)]; - MMC_t mmc; + u8 unused_mac_stat[4096 - sizeof(struct macstat_regs)]; + struct mmc_regs mmc; /* unused section of mmc address map */ - u8 unused_mmc[4096 - sizeof(MMC_t)]; + u8 unused_mmc[4096 - sizeof(struct mmc_regs)]; /* unused section of address map */ u8 unused_[1015808]; -/* Take this out until it is not empty */ -#if 0 - EXP_ROM_t exp_rom; -#endif - u8 unused_exp_rom[4096]; /* MGS-size TBD */ u8 unused__[524288]; /* unused section of address map */ } ADDRESS_MAP_t, *PADDRESS_MAP_t; diff --git a/drivers/staging/et131x/et1310_eeprom.c b/drivers/staging/et131x/et1310_eeprom.c index bcca1f8..3ca2536 100644 --- a/drivers/staging/et131x/et1310_eeprom.c +++ b/drivers/staging/et131x/et1310_eeprom.c @@ -84,17 +84,42 @@ #include <linux/ioport.h> #include "et1310_phy.h" -#include "et1310_pm.h" -#include "et1310_jagcore.h" -#include "et1310_eeprom.h" - #include "et131x_adapter.h" -#include "et131x_initpci.h" -#include "et131x_isr.h" - -#include "et1310_tx.h" +#include "et131x.h" +/* + * EEPROM Defines + */ +/* LBCIF Register Groups (addressed via 32-bit offsets) */ +#define LBCIF_DWORD0_GROUP 0xAC +#define LBCIF_DWORD1_GROUP 0xB0 + +/* LBCIF Registers (addressed via 8-bit offsets) */ +#define LBCIF_ADDRESS_REGISTER 0xAC +#define LBCIF_DATA_REGISTER 0xB0 +#define LBCIF_CONTROL_REGISTER 0xB1 +#define LBCIF_STATUS_REGISTER 0xB2 + +/* LBCIF Control Register Bits */ +#define LBCIF_CONTROL_SEQUENTIAL_READ 0x01 +#define LBCIF_CONTROL_PAGE_WRITE 0x02 +#define LBCIF_CONTROL_EEPROM_RELOAD 0x08 +#define LBCIF_CONTROL_TWO_BYTE_ADDR 0x20 +#define LBCIF_CONTROL_I2C_WRITE 0x40 +#define LBCIF_CONTROL_LBCIF_ENABLE 0x80 + +/* LBCIF Status Register Bits */ +#define LBCIF_STATUS_PHY_QUEUE_AVAIL 0x01 +#define LBCIF_STATUS_I2C_IDLE 0x02 +#define LBCIF_STATUS_ACK_ERROR 0x04 +#define LBCIF_STATUS_GENERAL_ERROR 0x08 +#define LBCIF_STATUS_CHECKSUM_ERROR 0x40 +#define LBCIF_STATUS_EEPROM_PRESENT 0x80 + +/* Miscellaneous Constraints */ +#define MAX_NUM_REGISTER_POLLS 1000 +#define MAX_NUM_WRITE_RETRIES 2 static int eeprom_wait_ready(struct pci_dev *pdev, u32 *status) { diff --git a/drivers/staging/et131x/et1310_eeprom.h b/drivers/staging/et131x/et1310_eeprom.h deleted file mode 100644 index 6a6c6a6..0000000 --- a/drivers/staging/et131x/et1310_eeprom.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Agere Systems Inc. - * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs - * - * Copyright © 2005 Agere Systems Inc. - * All rights reserved. - * http://www.agere.com - * - *------------------------------------------------------------------------------ - * - * et1310_eeprom.h - Defines, structs, enums, prototypes, etc. used for EEPROM - * access routines - * - *------------------------------------------------------------------------------ - * - * SOFTWARE LICENSE - * - * This software is provided subject to the following terms and conditions, - * which you should read carefully before using the software. Using this - * software indicates your acceptance of these terms and conditions. If you do - * not agree with these terms and conditions, do not use the software. - * - * Copyright © 2005 Agere Systems Inc. - * All rights reserved. - * - * Redistribution and use in source or binary forms, with or without - * modifications, are permitted provided that the following conditions are met: - * - * . Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following Disclaimer as comments in the code as - * well as in the documentation and/or other materials provided with the - * distribution. - * - * . Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following Disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * . Neither the name of Agere Systems Inc. nor the names of the contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * Disclaimer - * - * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY - * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN - * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - */ - -#ifndef __ET1310_EEPROM_H__ -#define __ET1310_EEPROM_H__ - -#include "et1310_address_map.h" - -/* - * EEPROM Defines - */ - -/* LBCIF Register Groups (addressed via 32-bit offsets) */ -#define LBCIF_DWORD0_GROUP 0xAC -#define LBCIF_DWORD1_GROUP 0xB0 - -/* LBCIF Registers (addressed via 8-bit offsets) */ -#define LBCIF_ADDRESS_REGISTER 0xAC -#define LBCIF_DATA_REGISTER 0xB0 -#define LBCIF_CONTROL_REGISTER 0xB1 -#define LBCIF_STATUS_REGISTER 0xB2 - -/* LBCIF Control Register Bits */ -#define LBCIF_CONTROL_SEQUENTIAL_READ 0x01 -#define LBCIF_CONTROL_PAGE_WRITE 0x02 -#define LBCIF_CONTROL_EEPROM_RELOAD 0x08 -#define LBCIF_CONTROL_TWO_BYTE_ADDR 0x20 -#define LBCIF_CONTROL_I2C_WRITE 0x40 -#define LBCIF_CONTROL_LBCIF_ENABLE 0x80 - -/* LBCIF Status Register Bits */ -#define LBCIF_STATUS_PHY_QUEUE_AVAIL 0x01 -#define LBCIF_STATUS_I2C_IDLE 0x02 -#define LBCIF_STATUS_ACK_ERROR 0x04 -#define LBCIF_STATUS_GENERAL_ERROR 0x08 -#define LBCIF_STATUS_CHECKSUM_ERROR 0x40 -#define LBCIF_STATUS_EEPROM_PRESENT 0x80 - -/* Miscellaneous Constraints */ -#define MAX_NUM_REGISTER_POLLS 1000 -#define MAX_NUM_WRITE_RETRIES 2 - -/* Forward declaration of the private adapter structure */ -struct et131x_adapter; - -int et131x_init_eeprom(struct et131x_adapter *etdev); - -#endif /* _ET1310_EEPROM_H_ */ diff --git a/drivers/staging/et131x/et1310_jagcore.h b/drivers/staging/et131x/et1310_jagcore.h deleted file mode 100644 index 0807a01..0000000 --- a/drivers/staging/et131x/et1310_jagcore.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Agere Systems Inc. - * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs - * - * Copyright © 2005 Agere Systems Inc. - * All rights reserved. - * http://www.agere.com - * - *------------------------------------------------------------------------------ - * - * et1310_jagcore.h - Defines, structs, enums, prototypes, etc. pertaining to - * the JAGCore - * - *------------------------------------------------------------------------------ - * - * SOFTWARE LICENSE - * - * This software is provided subject to the following terms and conditions, - * which you should read carefully before using the software. Using this - * software indicates your acceptance of these terms and conditions. If you do - * not agree with these terms and conditions, do not use the software. - * - * Copyright © 2005 Agere Systems Inc. - * All rights reserved. - * - * Redistribution and use in source or binary forms, with or without - * modifications, are permitted provided that the following conditions are met: - * - * . Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following Disclaimer as comments in the code as - * well as in the documentation and/or other materials provided with the - * distribution. - * - * . Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following Disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * . Neither the name of Agere Systems Inc. nor the names of the contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * Disclaimer - * - * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY - * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN - * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - */ - -#ifndef __ET1310_JAGCORE_H__ -#define __ET1310_JAGCORE_H__ - -#include "et1310_address_map.h" - - -#define INTERNAL_MEM_SIZE 0x400 /* 1024 of internal memory */ -#define INTERNAL_MEM_RX_OFFSET 0x1FF /* 50% Tx, 50% Rx */ - -/* - * For interrupts, normal running is: - * rxdma_xfr_done, phy_interrupt, mac_stat_interrupt, - * watchdog_interrupt & txdma_xfer_done - * - * In both cases, when flow control is enabled for either Tx or bi-direction, - * we additional enable rx_fbr0_low and rx_fbr1_low, so we know when the - * buffer rings are running low. - */ -#define INT_MASK_DISABLE 0xffffffff - -/* NOTE: Masking out MAC_STAT Interrupt for now... - * #define INT_MASK_ENABLE 0xfff6bf17 - * #define INT_MASK_ENABLE_NO_FLOW 0xfff6bfd7 - */ -#define INT_MASK_ENABLE 0xfffebf17 -#define INT_MASK_ENABLE_NO_FLOW 0xfffebfd7 - -/* Forward declaration of the private adapter structure */ -struct et131x_adapter; - -void ConfigGlobalRegs(struct et131x_adapter *pAdapter); -void ConfigMMCRegs(struct et131x_adapter *pAdapter); -void et131x_enable_interrupts(struct et131x_adapter *adapter); -void et131x_disable_interrupts(struct et131x_adapter *adapter); - -#endif /* __ET1310_JAGCORE_H__ */ diff --git a/drivers/staging/et131x/et1310_mac.c b/drivers/staging/et131x/et1310_mac.c index b8a1f20..a292b1e 100644 --- a/drivers/staging/et131x/et1310_mac.c +++ b/drivers/staging/et131x/et1310_mac.c @@ -85,12 +85,19 @@ #include <linux/crc32.h> #include "et1310_phy.h" -#include "et1310_pm.h" -#include "et1310_jagcore.h" -#include "et1310_mac.h" - #include "et131x_adapter.h" -#include "et131x_initpci.h" +#include "et131x.h" + + +#define COUNTER_WRAP_28_BIT 0x10000000 +#define COUNTER_WRAP_22_BIT 0x400000 +#define COUNTER_WRAP_16_BIT 0x10000 +#define COUNTER_WRAP_12_BIT 0x1000 + +#define COUNTER_MASK_28_BIT (COUNTER_WRAP_28_BIT - 1) +#define COUNTER_MASK_22_BIT (COUNTER_WRAP_22_BIT - 1) +#define COUNTER_MASK_16_BIT (COUNTER_WRAP_16_BIT - 1) +#define COUNTER_MASK_12_BIT (COUNTER_WRAP_12_BIT - 1) /** * ConfigMacRegs1 - Initialize the first part of MAC regs @@ -163,9 +170,9 @@ void ConfigMACRegs2(struct et131x_adapter *etdev) u32 cfg1; u32 cfg2; u32 ifctrl; - TXMAC_CTL_t ctl; + u32 ctl; - ctl.value = readl(&etdev->regs->txmac.ctl.value); + ctl = readl(&etdev->regs->txmac.ctl); cfg1 = readl(&pMac->cfg1); cfg2 = readl(&pMac->cfg2); ifctrl = readl(&pMac->if_ctrl); @@ -219,9 +226,8 @@ void ConfigMACRegs2(struct et131x_adapter *etdev) } /* Enable TXMAC */ - ctl.bits.txmac_en = 0x1; - ctl.bits.fc_disable = 0x1; - writel(ctl.value, &etdev->regs->txmac.ctl.value); + ctl |= 0x05; /* TX mac enable, FC disable */ + writel(ctl, &etdev->regs->txmac.ctl); /* Ready to start the RXDMA/TXDMA engine */ if (etdev->Flags & fMP_ADAPTER_LOWER_POWER) { @@ -235,15 +241,15 @@ void ConfigRxMacRegs(struct et131x_adapter *etdev) struct _RXMAC_t __iomem *pRxMac = &etdev->regs->rxmac; RXMAC_WOL_SA_LO_t sa_lo; RXMAC_WOL_SA_HI_t sa_hi; - RXMAC_PF_CTRL_t pf_ctrl = { 0 }; + u32 pf_ctrl = 0; /* Disable the MAC while it is being configured (also disable WOL) */ - writel(0x8, &pRxMac->ctrl.value); + writel(0x8, &pRxMac->ctrl); /* Initialize WOL to disabled. */ - writel(0, &pRxMac->crc0.value); - writel(0, &pRxMac->crc12.value); - writel(0, &pRxMac->crc34.value); + writel(0, &pRxMac->crc0); + writel(0, &pRxMac->crc12); + writel(0, &pRxMac->crc34); /* We need to set the WOL mask0 - mask4 next. We initialize it to * its default Values of 0x00000000 because there are not WOL masks @@ -286,12 +292,12 @@ void ConfigRxMacRegs(struct et131x_adapter *etdev) writel(sa_hi.value, &pRxMac->sa_hi.value); /* Disable all Packet Filtering */ - writel(0, &pRxMac->pf_ctrl.value); + writel(0, &pRxMac->pf_ctrl); /* Let's initialize the Unicast Packet filtering address */ if (etdev->PacketFilter & ET131X_PACKET_TYPE_DIRECTED) { SetupDeviceForUnicast(etdev); - pf_ctrl.bits.filter_uni_en = 1; + pf_ctrl |= 4; /* Unicast filter */ } else { writel(0, &pRxMac->uni_pf_addr1.value); writel(0, &pRxMac->uni_pf_addr2.value); @@ -299,20 +305,16 @@ void ConfigRxMacRegs(struct et131x_adapter *etdev) } /* Let's initialize the Multicast hash */ - if (etdev->PacketFilter & ET131X_PACKET_TYPE_ALL_MULTICAST) { - pf_ctrl.bits.filter_multi_en = 0; - } else { - pf_ctrl.bits.filter_multi_en = 1; + if (!(etdev->PacketFilter & ET131X_PACKET_TYPE_ALL_MULTICAST)) { + pf_ctrl |= 2; /* Multicast filter */ SetupDeviceForMulticast(etdev); } /* Runt packet filtering. Didn't work in version A silicon. */ - pf_ctrl.bits.min_pkt_size = NIC_MIN_PACKET_SIZE + 4; - pf_ctrl.bits.filter_frag_en = 1; - - if (etdev->RegistryJumboPacket > 8192) { - RXMAC_MCIF_CTRL_MAX_SEG_t mcif_ctrl_max_seg; + pf_ctrl |= (NIC_MIN_PACKET_SIZE + 4) << 16; + pf_ctrl |= 8; /* Fragment filter */ + if (etdev->RegistryJumboPacket > 8192) /* In order to transmit jumbo packets greater than 8k, the * FIFO between RxMAC and RxDMA needs to be reduced in size * to (16k - Jumbo packet size). In order to implement this, @@ -320,25 +322,21 @@ void ConfigRxMacRegs(struct et131x_adapter *etdev) * packets down into segments which are (max_size * 16). In * this case we selected 256 bytes, since this is the size of * the PCI-Express TLP's that the 1310 uses. + * + * seg_en on, fc_en off, size 0x10 */ - mcif_ctrl_max_seg.bits.seg_en = 0x1; - mcif_ctrl_max_seg.bits.fc_en = 0x0; - mcif_ctrl_max_seg.bits.max_size = 0x10; - - writel(mcif_ctrl_max_seg.value, - &pRxMac->mcif_ctrl_max_seg.value); - } else { - writel(0, &pRxMac->mcif_ctrl_max_seg.value); - } + writel(0x41, &pRxMac->mcif_ctrl_max_seg); + else + writel(0, &pRxMac->mcif_ctrl_max_seg); /* Initialize the MCIF water marks */ - writel(0, &pRxMac->mcif_water_mark.value); + writel(0, &pRxMac->mcif_water_mark); /* Initialize the MIF control */ - writel(0, &pRxMac->mif_ctrl.value); + writel(0, &pRxMac->mif_ctrl); /* Initialize the Space Available Register */ - writel(0, &pRxMac->space_avail.value); + writel(0, &pRxMac->space_avail); /* Initialize the the mif_ctrl register * bit 3: Receive code error. One or more nibbles were signaled as @@ -354,9 +352,9 @@ void ConfigRxMacRegs(struct et131x_adapter *etdev) * bit 17: Drop packet enable */ if (etdev->linkspeed == TRUEPHY_SPEED_100MBPS) - writel(0x30038, &pRxMac->mif_ctrl.value); + writel(0x30038, &pRxMac->mif_ctrl); else - writel(0x30030, &pRxMac->mif_ctrl.value); + writel(0x30030, &pRxMac->mif_ctrl); /* Finally we initialize RxMac to be enabled & WOL disabled. Packet * filter is always enabled since it is where the runt packets are @@ -364,28 +362,28 @@ void ConfigRxMacRegs(struct et131x_adapter *etdev) * dropping doesn't work, so it is disabled in the pf_ctrl register, * but we still leave the packet filter on. */ - writel(pf_ctrl.value, &pRxMac->pf_ctrl.value); - writel(0x9, &pRxMac->ctrl.value); + writel(pf_ctrl, &pRxMac->pf_ctrl); + writel(0x9, &pRxMac->ctrl); } void ConfigTxMacRegs(struct et131x_adapter *etdev) { - struct _TXMAC_t __iomem *pTxMac = &etdev->regs->txmac; + struct txmac_regs *txmac = &etdev->regs->txmac; /* We need to update the Control Frame Parameters * cfpt - control frame pause timer set to 64 (0x40) * cfep - control frame extended pause timer set to 0x0 */ if (etdev->FlowControl == None) - writel(0, &pTxMac->cf_param); + writel(0, &txmac->cf_param); else - writel(0x40, &pTxMac->cf_param); + writel(0x40, &txmac->cf_param); } void ConfigMacStatRegs(struct et131x_adapter *etdev) { - struct _MAC_STAT_t __iomem *macstat = - &etdev->regs->macStat; + struct macstat_regs __iomem *macstat = + &etdev->regs->macstat; /* Next we need to initialize all the MAC_STAT registers to zero on * the device. @@ -456,8 +454,8 @@ void ConfigFlowControl(struct et131x_adapter *etdev) void UpdateMacStatHostCounters(struct et131x_adapter *etdev) { struct _ce_stats_t *stats = &etdev->Stats; - struct _MAC_STAT_t __iomem *macstat = - &etdev->regs->macStat; + struct macstat_regs __iomem *macstat = + &etdev->regs->macstat; stats->collisions += readl(&macstat->TNcl); stats->first_collision += readl(&macstat->TScl); @@ -493,11 +491,11 @@ void HandleMacStatInterrupt(struct et131x_adapter *etdev) /* Read the interrupt bits from the register(s). These are Clear On * Write. */ - Carry1 = readl(&etdev->regs->macStat.Carry1); - Carry2 = readl(&etdev->regs->macStat.Carry2); + Carry1 = readl(&etdev->regs->macstat.Carry1); + Carry2 = readl(&etdev->regs->macstat.Carry2); - writel(Carry1, &etdev->regs->macStat.Carry1); - writel(Carry2, &etdev->regs->macStat.Carry2); + writel(Carry1, &etdev->regs->macstat.Carry1); + writel(Carry2, &etdev->regs->macstat.Carry2); /* We need to do update the host copy of all the MAC_STAT counters. * For each counter, check it's overflow bit. If the overflow bit is diff --git a/drivers/staging/et131x/et1310_mac.h b/drivers/staging/et131x/et1310_mac.h deleted file mode 100644 index 2c38595..0000000 --- a/drivers/staging/et131x/et1310_mac.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Agere Systems Inc. - * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs - * - * Copyright © 2005 Agere Systems Inc. - * All rights reserved. - * http://www.agere.com - * - *------------------------------------------------------------------------------ - * - * et1310_mac.h - Defines, structs, enums, prototypes, etc. pertaining to the - * MAC. - * - *------------------------------------------------------------------------------ - * - * SOFTWARE LICENSE - * - * This software is provided subject to the following terms and conditions, - * which you should read carefully before using the software. Using this - * software indicates your acceptance of these terms and conditions. If you do - * not agree with these terms and conditions, do not use the software. - * - * Copyright © 2005 Agere Systems Inc. - * All rights reserved. - * - * Redistribution and use in source or binary forms, with or without - * modifications, are permitted provided that the following conditions are met: - * - * . Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following Disclaimer as comments in the code as - * well as in the documentation and/or other materials provided with the - * distribution. - * - * . Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following Disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * . Neither the name of Agere Systems Inc. nor the names of the contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * Disclaimer - * - * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY - * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN - * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - */ - -#ifndef _ET1310_MAC_H_ -#define _ET1310_MAC_H_ - - -#include "et1310_address_map.h" - - -#define COUNTER_WRAP_28_BIT 0x10000000 -#define COUNTER_WRAP_22_BIT 0x400000 -#define COUNTER_WRAP_16_BIT 0x10000 -#define COUNTER_WRAP_12_BIT 0x1000 - -#define COUNTER_MASK_28_BIT (COUNTER_WRAP_28_BIT - 1) -#define COUNTER_MASK_22_BIT (COUNTER_WRAP_22_BIT - 1) -#define COUNTER_MASK_16_BIT (COUNTER_WRAP_16_BIT - 1) -#define COUNTER_MASK_12_BIT (COUNTER_WRAP_12_BIT - 1) - -#define UPDATE_COUNTER(HostCnt, DevCnt) \ - HostCnt = HostCnt + DevCnt; - -/* Forward declaration of the private adapter structure */ -struct et131x_adapter; - -void ConfigMACRegs1(struct et131x_adapter *adapter); -void ConfigMACRegs2(struct et131x_adapter *adapter); -void ConfigRxMacRegs(struct et131x_adapter *adapter); -void ConfigTxMacRegs(struct et131x_adapter *adapter); -void ConfigMacStatRegs(struct et131x_adapter *adapter); -void ConfigFlowControl(struct et131x_adapter *adapter); -void UpdateMacStatHostCounters(struct et131x_adapter *adapter); -void HandleMacStatInterrupt(struct et131x_adapter *adapter); -void SetupDeviceForMulticast(struct et131x_adapter *adapter); -void SetupDeviceForUnicast(struct et131x_adapter *adapter); - -#endif /* _ET1310_MAC_H_ */ diff --git a/drivers/staging/et131x/et1310_phy.c b/drivers/staging/et131x/et1310_phy.c index 6ecad61..4a55fbf 100644 --- a/drivers/staging/et131x/et1310_phy.c +++ b/drivers/staging/et131x/et1310_phy.c @@ -85,17 +85,14 @@ #include <linux/random.h> #include "et1310_phy.h" -#include "et1310_pm.h" -#include "et1310_jagcore.h" #include "et131x_adapter.h" -#include "et131x_netdev.h" -#include "et131x_initpci.h" #include "et1310_address_map.h" #include "et1310_tx.h" #include "et1310_rx.h" -#include "et1310_mac.h" + +#include "et131x.h" /* Prototypes for functions with local scope */ static void et131x_xcvr_init(struct et131x_adapter *etdev); diff --git a/drivers/staging/et131x/et1310_phy.h b/drivers/staging/et131x/et1310_phy.h index 758b9b2..47907ba 100644 --- a/drivers/staging/et131x/et1310_phy.h +++ b/drivers/staging/et131x/et1310_phy.h @@ -736,32 +736,8 @@ typedef union _MI_LCR2_t { /* MI Register 29 - 31: Reserved Reg(0x1D - 0x1E) */ -/* Forward declaration of the private adapter structure */ -struct et131x_adapter; /* Prototypes for ET1310_phy.c */ -int et131x_xcvr_find(struct et131x_adapter *adapter); -void et131x_setphy_normal(struct et131x_adapter *adapter); - -/* static inline function does not work because et131x_adapter is not always - * defined - */ -int PhyMiRead(struct et131x_adapter *adapter, u8 xcvrAddr, - u8 xcvrReg, u16 *value); -#define MiRead(adapter, xcvrReg, value) \ - PhyMiRead((adapter), (adapter)->Stats.xcvr_addr, (xcvrReg), (value)) - -int32_t MiWrite(struct et131x_adapter *adapter, - u8 xcvReg, u16 value); -void et131x_Mii_check(struct et131x_adapter *pAdapter, - MI_BMSR_t bmsr, MI_BMSR_t bmsr_ints); - -/* This last is not strictly required (the driver could call the TPAL - * version instead), but this sets the adapter up correctly, and calls the - * access routine indirectly. This protects the driver from changes in TPAL. - */ -void SetPhy_10BaseTHalfDuplex(struct et131x_adapter *adapter); - /* Defines for PHY access routines */ /* Define bit operation flags */ @@ -843,14 +819,4 @@ void SetPhy_10BaseTHalfDuplex(struct et131x_adapter *adapter); /* #define TRU_VMI_LINK_CONTROL_REGISTER 29 */ /* #define TRU_VMI_TIMING_CONTROL_REGISTER */ -/* Prototypes for PHY access routines */ -void ET1310_PhyInit(struct et131x_adapter *adapter); -void ET1310_PhyReset(struct et131x_adapter *adapter); -void ET1310_PhyPowerDown(struct et131x_adapter *adapter, bool down); -void ET1310_PhyAdvertise1000BaseT(struct et131x_adapter *adapter, - u16 duplex); -void ET1310_PhyAccessMiBit(struct et131x_adapter *adapter, - u16 action, - u16 regnum, u16 bitnum, u8 *value); - #endif /* _ET1310_PHY_H_ */ diff --git a/drivers/staging/et131x/et1310_pm.c b/drivers/staging/et131x/et1310_pm.c index 7d07723..41019e3 100644 --- a/drivers/staging/et131x/et1310_pm.c +++ b/drivers/staging/et131x/et1310_pm.c @@ -83,13 +83,9 @@ #include <linux/ioport.h> #include "et1310_phy.h" -#include "et1310_pm.h" -#include "et1310_jagcore.h" -#include "et1310_mac.h" #include "et1310_rx.h" - #include "et131x_adapter.h" -#include "et131x_initpci.h" +#include "et131x.h" /** * EnablePhyComa - called when network cable is unplugged diff --git a/drivers/staging/et131x/et1310_pm.h b/drivers/staging/et131x/et1310_pm.h deleted file mode 100644 index 295f3ab..0000000 --- a/drivers/staging/et131x/et1310_pm.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Agere Systems Inc. - * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs - * - * Copyright © 2005 Agere Systems Inc. - * All rights reserved. - * http://www.agere.com - * - *------------------------------------------------------------------------------ - * - * et1310_pm.h - Defines, structs, enums, prototypes, etc. pertaining to power - * management. - * - *------------------------------------------------------------------------------ - * - * SOFTWARE LICENSE - * - * This software is provided subject to the following terms and conditions, - * which you should read carefully before using the software. Using this - * software indicates your acceptance of these terms and conditions. If you do - * not agree with these terms and conditions, do not use the software. - * - * Copyright © 2005 Agere Systems Inc. - * All rights reserved. - * - * Redistribution and use in source or binary forms, with or without - * modifications, are permitted provided that the following conditions are met: - * - * . Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following Disclaimer as comments in the code as - * well as in the documentation and/or other materials provided with the - * distribution. - * - * . Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following Disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * . Neither the name of Agere Systems Inc. nor the names of the contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * Disclaimer - * - * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY - * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN - * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - */ - -#ifndef _ET1310_PM_H_ -#define _ET1310_PM_H_ - -#include "et1310_address_map.h" - -typedef struct _MP_POWER_MGMT { - /* variable putting the phy into coma mode when boot up with no cable - * plugged in after 5 seconds - */ - u8 TransPhyComaModeOnBoot; - - /* Next two used to save power information at power down. This - * information will be used during power up to set up parts of Power - * Management in JAGCore - */ - u16 PowerDownSpeed; - u8 PowerDownDuplex; -} MP_POWER_MGMT, *PMP_POWER_MGMT; - -/* Forward declaration of the private adapter structure - */ -struct et131x_adapter; - -void EnablePhyComa(struct et131x_adapter *adapter); -void DisablePhyComa(struct et131x_adapter *adapter); - -#endif /* _ET1310_PM_H_ */ diff --git a/drivers/staging/et131x/et1310_rx.c b/drivers/staging/et131x/et1310_rx.c index 81c1a74..54686e2 100644 --- a/drivers/staging/et131x/et1310_rx.c +++ b/drivers/staging/et131x/et1310_rx.c @@ -84,14 +84,9 @@ #include <linux/ioport.h> #include "et1310_phy.h" -#include "et1310_pm.h" -#include "et1310_jagcore.h" - #include "et131x_adapter.h" -#include "et131x_initpci.h" - #include "et1310_rx.h" - +#include "et131x.h" void nic_return_rfd(struct et131x_adapter *etdev, PMP_RFD pMpRfd); @@ -109,17 +104,16 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) u32 i, j; u32 bufsize; u32 pktStatRingSize, FBRChunkSize; - RX_RING_t *rx_ring; + struct rx_ring *rx_ring; /* Setup some convenience pointers */ - rx_ring = (RX_RING_t *) &adapter->RxRing; + rx_ring = &adapter->rx_ring; /* Alloc memory for the lookup table */ #ifdef USE_FBR0 - rx_ring->Fbr[0] = kmalloc(sizeof(FBRLOOKUPTABLE), GFP_KERNEL); + rx_ring->fbr[0] = kmalloc(sizeof(struct fbr_lookup), GFP_KERNEL); #endif - - rx_ring->Fbr[1] = kmalloc(sizeof(FBRLOOKUPTABLE), GFP_KERNEL); + rx_ring->fbr[1] = kmalloc(sizeof(struct fbr_lookup), GFP_KERNEL); /* The first thing we will do is configure the sizes of the buffer * rings. These will change based on jumbo packet support. Larger @@ -163,14 +157,14 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) } #ifdef USE_FBR0 - adapter->RxRing.PsrNumEntries = adapter->RxRing.Fbr0NumEntries + - adapter->RxRing.Fbr1NumEntries; + adapter->rx_ring.PsrNumEntries = adapter->rx_ring.Fbr0NumEntries + + adapter->rx_ring.Fbr1NumEntries; #else - adapter->RxRing.PsrNumEntries = adapter->RxRing.Fbr1NumEntries; + adapter->rx_ring.PsrNumEntries = adapter->rx_ring.Fbr1NumEntries; #endif /* Allocate an area of memory for Free Buffer Ring 1 */ - bufsize = (sizeof(FBR_DESC_t) * rx_ring->Fbr1NumEntries) + 0xfff; + bufsize = (sizeof(struct fbr_desc) * rx_ring->Fbr1NumEntries) + 0xfff; rx_ring->pFbr1RingVa = pci_alloc_consistent(adapter->pdev, bufsize, &rx_ring->pFbr1RingPa); @@ -194,12 +188,12 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) &rx_ring->Fbr1Realpa, &rx_ring->Fbr1offset, 0x0FFF); - rx_ring->pFbr1RingVa = (void *)((uint8_t *) rx_ring->pFbr1RingVa + + rx_ring->pFbr1RingVa = (void *)((u8 *) rx_ring->pFbr1RingVa + rx_ring->Fbr1offset); #ifdef USE_FBR0 /* Allocate an area of memory for Free Buffer Ring 0 */ - bufsize = (sizeof(FBR_DESC_t) * rx_ring->Fbr0NumEntries) + 0xfff; + bufsize = (sizeof(struct fbr_desc) * rx_ring->Fbr0NumEntries) + 0xfff; rx_ring->pFbr0RingVa = pci_alloc_consistent(adapter->pdev, bufsize, &rx_ring->pFbr0RingPa); @@ -223,7 +217,7 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) &rx_ring->Fbr0Realpa, &rx_ring->Fbr0offset, 0x0FFF); - rx_ring->pFbr0RingVa = (void *)((uint8_t *) rx_ring->pFbr0RingVa + + rx_ring->pFbr0RingVa = (void *)((u8 *) rx_ring->pFbr0RingVa + rx_ring->Fbr0offset); #endif @@ -270,23 +264,23 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) /* Save the Virtual address of this index for quick * access later */ - rx_ring->Fbr[1]->Va[index] = - (uint8_t *) rx_ring->Fbr1MemVa[i] + + rx_ring->fbr[1]->virt[index] = + (u8 *) rx_ring->Fbr1MemVa[i] + (j * rx_ring->Fbr1BufferSize) + Fbr1Offset; /* now store the physical address in the descriptor * so the device can access it */ - rx_ring->Fbr[1]->PAHigh[index] = + rx_ring->fbr[1]->bus_high[index] = (u32) (Fbr1TempPa >> 32); - rx_ring->Fbr[1]->PALow[index] = (u32) Fbr1TempPa; + rx_ring->fbr[1]->bus_low[index] = (u32) Fbr1TempPa; Fbr1TempPa += rx_ring->Fbr1BufferSize; - rx_ring->Fbr[1]->Buffer1[index] = - rx_ring->Fbr[1]->Va[index]; - rx_ring->Fbr[1]->Buffer2[index] = - rx_ring->Fbr[1]->Va[index] - 4; + rx_ring->fbr[1]->buffer1[index] = + rx_ring->fbr[1]->virt[index]; + rx_ring->fbr[1]->buffer2[index] = + rx_ring->fbr[1]->virt[index] - 4; } } @@ -319,27 +313,27 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) for (j = 0; j < FBR_CHUNKS; j++) { u32 index = (i * FBR_CHUNKS) + j; - rx_ring->Fbr[0]->Va[index] = - (uint8_t *) rx_ring->Fbr0MemVa[i] + + rx_ring->fbr[0]->virt[index] = + (u8 *) rx_ring->Fbr0MemVa[i] + (j * rx_ring->Fbr0BufferSize) + Fbr0Offset; - rx_ring->Fbr[0]->PAHigh[index] = + rx_ring->fbr[0]->bus_high[index] = (u32) (Fbr0TempPa >> 32); - rx_ring->Fbr[0]->PALow[index] = (u32) Fbr0TempPa; + rx_ring->fbr[0]->bus_low[index] = (u32) Fbr0TempPa; Fbr0TempPa += rx_ring->Fbr0BufferSize; - rx_ring->Fbr[0]->Buffer1[index] = - rx_ring->Fbr[0]->Va[index]; - rx_ring->Fbr[0]->Buffer2[index] = - rx_ring->Fbr[0]->Va[index] - 4; + rx_ring->fbr[0]->buffer1[index] = + rx_ring->fbr[0]->virt[index]; + rx_ring->fbr[0]->buffer2[index] = + rx_ring->fbr[0]->virt[index] - 4; } } #endif /* Allocate an area of memory for FIFO of Packet Status ring entries */ pktStatRingSize = - sizeof(PKT_STAT_DESC_t) * adapter->RxRing.PsrNumEntries; + sizeof(struct pkt_stat_desc) * adapter->rx_ring.PsrNumEntries; rx_ring->pPSRingVa = pci_alloc_consistent(adapter->pdev, pktStatRingSize, @@ -360,16 +354,16 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) */ /* Allocate an area of memory for writeback of status information */ - rx_ring->pRxStatusVa = pci_alloc_consistent(adapter->pdev, - sizeof(RX_STATUS_BLOCK_t), - &rx_ring->pRxStatusPa); - if (!rx_ring->pRxStatusVa) { + rx_ring->rx_status_block = pci_alloc_consistent(adapter->pdev, + sizeof(struct rx_status_block), + &rx_ring->rx_status_bus); + if (!rx_ring->rx_status_block) { dev_err(&adapter->pdev->dev, "Cannot alloc memory for Status Block\n"); return -ENOMEM; } rx_ring->NumRfd = NIC_DEFAULT_NUM_RFD; - printk("PRS %lx\n", (unsigned long)rx_ring->pRxStatusPa); + printk("PRS %lx\n", (unsigned long)rx_ring->rx_status_bus); /* Recv * pci_pool_create initializes a lookaside list. After successful @@ -403,10 +397,10 @@ void et131x_rx_dma_memory_free(struct et131x_adapter *adapter) u32 bufsize; u32 pktStatRingSize; PMP_RFD rfd; - RX_RING_t *rx_ring; + struct rx_ring *rx_ring; /* Setup some convenience pointers */ - rx_ring = (RX_RING_t *) &adapter->RxRing; + rx_ring = &adapter->rx_ring; /* Free RFDs and associated packet descriptors */ WARN_ON(rx_ring->nReadyRecv != rx_ring->NumRfd); @@ -417,7 +411,7 @@ void et131x_rx_dma_memory_free(struct et131x_adapter *adapter) list_del(&rfd->list_node); rfd->Packet = NULL; - kmem_cache_free(adapter->RxRing.RecvLookaside, rfd); + kmem_cache_free(adapter->rx_ring.RecvLookaside, rfd); } /* Free Free Buffer Ring 1 */ @@ -447,15 +441,14 @@ void et131x_rx_dma_memory_free(struct et131x_adapter *adapter) } /* Now the FIFO itself */ - rx_ring->pFbr1RingVa = (void *)((uint8_t *) + rx_ring->pFbr1RingVa = (void *)((u8 *) rx_ring->pFbr1RingVa - rx_ring->Fbr1offset); - bufsize = - (sizeof(FBR_DESC_t) * rx_ring->Fbr1NumEntries) + 0xfff; + bufsize = (sizeof(struct fbr_desc) * rx_ring->Fbr1NumEntries) + + 0xfff; - pci_free_consistent(adapter->pdev, - bufsize, - rx_ring->pFbr1RingVa, rx_ring->pFbr1RingPa); + pci_free_consistent(adapter->pdev, bufsize, + rx_ring->pFbr1RingVa, rx_ring->pFbr1RingPa); rx_ring->pFbr1RingVa = NULL; } @@ -481,11 +474,11 @@ void et131x_rx_dma_memory_free(struct et131x_adapter *adapter) } /* Now the FIFO itself */ - rx_ring->pFbr0RingVa = (void *)((uint8_t *) + rx_ring->pFbr0RingVa = (void *)((u8 *) rx_ring->pFbr0RingVa - rx_ring->Fbr0offset); - bufsize = - (sizeof(FBR_DESC_t) * rx_ring->Fbr0NumEntries) + 0xfff; + bufsize = (sizeof(struct fbr_desc) * rx_ring->Fbr0NumEntries) + + 0xfff; pci_free_consistent(adapter->pdev, bufsize, @@ -498,7 +491,7 @@ void et131x_rx_dma_memory_free(struct et131x_adapter *adapter) /* Free Packet Status Ring */ if (rx_ring->pPSRingVa) { pktStatRingSize = - sizeof(PKT_STAT_DESC_t) * adapter->RxRing.PsrNumEntries; + sizeof(struct pkt_stat_desc) * adapter->rx_ring.PsrNumEntries; pci_free_consistent(adapter->pdev, pktStatRingSize, rx_ring->pPSRingVa, rx_ring->pPSRingPa); @@ -507,12 +500,11 @@ void et131x_rx_dma_memory_free(struct et131x_adapter *adapter) } /* Free area of memory for the writeback of status information */ - if (rx_ring->pRxStatusVa) { + if (rx_ring->rx_status_block) { pci_free_consistent(adapter->pdev, - sizeof(RX_STATUS_BLOCK_t), - rx_ring->pRxStatusVa, rx_ring->pRxStatusPa); - - rx_ring->pRxStatusVa = NULL; + sizeof(struct rx_status_block), + rx_ring->rx_status_block, rx_ring->rx_status_bus); + rx_ring->rx_status_block = NULL; } /* Free receive buffer pool */ @@ -527,10 +519,10 @@ void et131x_rx_dma_memory_free(struct et131x_adapter *adapter) /* Free the FBR Lookup Table */ #ifdef USE_FBR0 - kfree(rx_ring->Fbr[0]); + kfree(rx_ring->fbr[0]); #endif - kfree(rx_ring->Fbr[1]); + kfree(rx_ring->fbr[1]); /* Reset Counters */ rx_ring->nReadyRecv = 0; @@ -548,10 +540,10 @@ int et131x_init_recv(struct et131x_adapter *adapter) PMP_RFD rfd = NULL; u32 rfdct; u32 numrfd = 0; - RX_RING_t *rx_ring = NULL; + struct rx_ring *rx_ring; /* Setup some convenience pointers */ - rx_ring = (RX_RING_t *) &adapter->RxRing; + rx_ring = &adapter->rx_ring; /* Setup each RFD */ for (rfdct = 0; rfdct < rx_ring->NumRfd; rfdct++) { @@ -594,9 +586,9 @@ int et131x_init_recv(struct et131x_adapter *adapter) */ void ConfigRxDmaRegs(struct et131x_adapter *etdev) { - struct _RXDMA_t __iomem *rx_dma = &etdev->regs->rxdma; - struct _rx_ring_t *rx_local = &etdev->RxRing; - PFBR_DESC_t fbr_entry; + struct rxdma_regs __iomem *rx_dma = &etdev->regs->rxdma; + struct rx_ring *rx_local = &etdev->rx_ring; + struct fbr_desc *fbr_entry; u32 entry; u32 psr_num_des; unsigned long flags; @@ -611,11 +603,11 @@ void ConfigRxDmaRegs(struct et131x_adapter *etdev) * are ever returned, make sure the high part is retrieved here * before storing the adjusted address. */ - writel((u32) ((u64)rx_local->pRxStatusPa >> 32), + writel((u32) ((u64)rx_local->rx_status_bus >> 32), &rx_dma->dma_wb_base_hi); - writel((u32) rx_local->pRxStatusPa, &rx_dma->dma_wb_base_lo); + writel((u32) rx_local->rx_status_bus, &rx_dma->dma_wb_base_lo); - memset(rx_local->pRxStatusVa, 0, sizeof(RX_STATUS_BLOCK_t)); + memset(rx_local->rx_status_block, 0, sizeof(struct rx_status_block)); /* Set the address and parameters of the packet status ring into the * 1310's registers @@ -636,11 +628,11 @@ void ConfigRxDmaRegs(struct et131x_adapter *etdev) rx_local->local_psr_full = 0; /* Now's the best time to initialize FBR1 contents */ - fbr_entry = (PFBR_DESC_t) rx_local->pFbr1RingVa; + fbr_entry = (struct fbr_desc *) rx_local->pFbr1RingVa; for (entry = 0; entry < rx_local->Fbr1NumEntries; entry++) { - fbr_entry->addr_hi = rx_local->Fbr[1]->PAHigh[entry]; - fbr_entry->addr_lo = rx_local->Fbr[1]->PALow[entry]; - fbr_entry->word2.bits.bi = entry; + fbr_entry->addr_hi = rx_local->fbr[1]->bus_high[entry]; + fbr_entry->addr_lo = rx_local->fbr[1]->bus_low[entry]; + fbr_entry->word2 = entry; fbr_entry++; } @@ -661,11 +653,11 @@ void ConfigRxDmaRegs(struct et131x_adapter *etdev) #ifdef USE_FBR0 /* Now's the best time to initialize FBR0 contents */ - fbr_entry = (PFBR_DESC_t) rx_local->pFbr0RingVa; + fbr_entry = (struct fbr_desc *) rx_local->pFbr0RingVa; for (entry = 0; entry < rx_local->Fbr0NumEntries; entry++) { - fbr_entry->addr_hi = rx_local->Fbr[0]->PAHigh[entry]; - fbr_entry->addr_lo = rx_local->Fbr[0]->PALow[entry]; - fbr_entry->word2.bits.bi = entry; + fbr_entry->addr_hi = rx_local->fbr[0]->bus_high[entry]; + fbr_entry->addr_lo = rx_local->fbr[0]->bus_low[entry]; + fbr_entry->word2 = entry; fbr_entry++; } @@ -721,18 +713,17 @@ void SetRxDmaTimer(struct et131x_adapter *etdev) */ void et131x_rx_dma_disable(struct et131x_adapter *etdev) { - RXDMA_CSR_t csr; - + u32 csr; /* Setup the receive dma configuration register */ - writel(0x00002001, &etdev->regs->rxdma.csr.value); - csr.value = readl(&etdev->regs->rxdma.csr.value); - if (csr.bits.halt_status != 1) { + writel(0x00002001, &etdev->regs->rxdma.csr); + csr = readl(&etdev->regs->rxdma.csr); + if ((csr & 0x00020000) != 1) { /* Check halt status (bit 17) */ udelay(5); - csr.value = readl(&etdev->regs->rxdma.csr.value); - if (csr.bits.halt_status != 1) + csr = readl(&etdev->regs->rxdma.csr); + if ((csr & 0x00020000) != 1) dev_err(&etdev->pdev->dev, - "RX Dma failed to enter halt state. CSR 0x%08x\n", - csr.value); + "RX Dma failed to enter halt state. CSR 0x%08x\n", + csr); } } @@ -743,34 +734,33 @@ void et131x_rx_dma_disable(struct et131x_adapter *etdev) void et131x_rx_dma_enable(struct et131x_adapter *etdev) { /* Setup the receive dma configuration register for normal operation */ - RXDMA_CSR_t csr = { 0 }; - - csr.bits.fbr1_enable = 1; - if (etdev->RxRing.Fbr1BufferSize == 4096) - csr.bits.fbr1_size = 1; - else if (etdev->RxRing.Fbr1BufferSize == 8192) - csr.bits.fbr1_size = 2; - else if (etdev->RxRing.Fbr1BufferSize == 16384) - csr.bits.fbr1_size = 3; + u32 csr = 0x2000; /* FBR1 enable */ + + if (etdev->rx_ring.Fbr1BufferSize == 4096) + csr |= 0x0800; + else if (etdev->rx_ring.Fbr1BufferSize == 8192) + csr |= 0x1000; + else if (etdev->rx_ring.Fbr1BufferSize == 16384) + csr |= 0x1800; #ifdef USE_FBR0 - csr.bits.fbr0_enable = 1; - if (etdev->RxRing.Fbr0BufferSize == 256) - csr.bits.fbr0_size = 1; - else if (etdev->RxRing.Fbr0BufferSize == 512) - csr.bits.fbr0_size = 2; - else if (etdev->RxRing.Fbr0BufferSize == 1024) - csr.bits.fbr0_size = 3; + csr |= 0x0400; /* FBR0 enable */ + if (etdev->rx_ring.Fbr0BufferSize == 256) + csr |= 0x0100; + else if (etdev->rx_ring.Fbr0BufferSize == 512) + csr |= 0x0200; + else if (etdev->rx_ring.Fbr0BufferSize == 1024) + csr |= 0x0300; #endif - writel(csr.value, &etdev->regs->rxdma.csr.value); + writel(csr, &etdev->regs->rxdma.csr); - csr.value = readl(&etdev->regs->rxdma.csr.value); - if (csr.bits.halt_status != 0) { + csr = readl(&etdev->regs->rxdma.csr); + if ((csr & 0x00020000) != 0) { udelay(5); - csr.value = readl(&etdev->regs->rxdma.csr.value); - if (csr.bits.halt_status != 0) { + csr = readl(&etdev->regs->rxdma.csr); + if ((csr & 0x00020000) != 0) { dev_err(&etdev->pdev->dev, "RX Dma failed to exit halt state. CSR 0x%08x\n", - csr.value); + csr); } } } @@ -788,46 +778,44 @@ void et131x_rx_dma_enable(struct et131x_adapter *etdev) */ PMP_RFD nic_rx_pkts(struct et131x_adapter *etdev) { - struct _rx_ring_t *rx_local = &etdev->RxRing; - PRX_STATUS_BLOCK_t status; - PPKT_STAT_DESC_t psr; + struct rx_ring *rx_local = &etdev->rx_ring; + struct rx_status_block *status; + struct pkt_stat_desc *psr; PMP_RFD rfd; u32 i; - uint8_t *buf; + u8 *buf; unsigned long flags; struct list_head *element; - uint8_t rindex; - uint16_t bindex; + u8 rindex; + u16 bindex; u32 len; - PKT_STAT_DESC_WORD0_t Word0; + u32 word0; + u32 word1; /* RX Status block is written by the DMA engine prior to every * interrupt. It contains the next to be used entry in the Packet * Status Ring, and also the two Free Buffer rings. */ - status = (PRX_STATUS_BLOCK_t) rx_local->pRxStatusVa; + status = rx_local->rx_status_block; + word1 = status->Word1 >> 16; /* Get the useful bits */ - /* FIXME: tidy later when conversions complete */ - if (status->Word1.bits.PSRoffset == - (rx_local->local_psr_full & 0xFFF) && - status->Word1.bits.PSRwrap == - ((rx_local->local_psr_full >> 12) & 1)) { + /* Check the PSR and wrap bits do not match */ + if ((word1 & 0x1FFF) == (rx_local->local_psr_full & 0x1FFF)) /* Looks like this ring is not updated yet */ return NULL; - } /* The packet status ring indicates that data is available. */ - psr = (PPKT_STAT_DESC_t) (rx_local->pPSRingVa) + + psr = (struct pkt_stat_desc *) (rx_local->pPSRingVa) + (rx_local->local_psr_full & 0xFFF); /* Grab any information that is required once the PSR is * advanced, since we can no longer rely on the memory being * accurate */ - len = psr->word1.bits.length; - rindex = (uint8_t) psr->word1.bits.ri; - bindex = (uint16_t) psr->word1.bits.bi; - Word0 = psr->word0; + len = psr->word1 & 0xFFFF; + rindex = (psr->word1 >> 26) & 0x03; + bindex = (psr->word1 >> 16) & 0x3FF; + word0 = psr->word0; /* Indicate that we have used this PSR entry. */ /* FIXME wrap 12 */ @@ -842,9 +830,8 @@ PMP_RFD nic_rx_pkts(struct et131x_adapter *etdev) &etdev->regs->rxdma.psr_full_offset); #ifndef USE_FBR0 - if (rindex != 1) { + if (rindex != 1) return NULL; - } #endif #ifdef USE_FBR0 @@ -899,7 +886,7 @@ PMP_RFD nic_rx_pkts(struct et131x_adapter *etdev) if (len) { if (etdev->ReplicaPhyLoopbk == 1) { - buf = rx_local->Fbr[rindex]->Va[bindex]; + buf = rx_local->fbr[rindex]->virt[bindex]; if (memcmp(&buf[6], &etdev->CurrentAddress[0], ETH_ALEN) == 0) { @@ -911,8 +898,8 @@ PMP_RFD nic_rx_pkts(struct et131x_adapter *etdev) } /* Determine if this is a multicast packet coming in */ - if ((Word0.value & ALCATEL_MULTICAST_PKT) && - !(Word0.value & ALCATEL_BROADCAST_PKT)) { + if ((word0 & ALCATEL_MULTICAST_PKT) && + !(word0 & ALCATEL_BROADCAST_PKT)) { /* Promiscuous mode and Multicast mode are * not mutually exclusive as was first * thought. I guess Promiscuous is just @@ -923,8 +910,8 @@ PMP_RFD nic_rx_pkts(struct et131x_adapter *etdev) if ((etdev->PacketFilter & ET131X_PACKET_TYPE_MULTICAST) && !(etdev->PacketFilter & ET131X_PACKET_TYPE_PROMISCUOUS) && !(etdev->PacketFilter & ET131X_PACKET_TYPE_ALL_MULTICAST)) { - buf = rx_local->Fbr[rindex]-> - Va[bindex]; + buf = rx_local->fbr[rindex]-> + virt[bindex]; /* Loop through our list to see if the * destination address of this packet @@ -963,7 +950,7 @@ PMP_RFD nic_rx_pkts(struct et131x_adapter *etdev) if (len > 0) etdev->Stats.multircv++; - } else if (Word0.value & ALCATEL_BROADCAST_PKT) + } else if (word0 & ALCATEL_BROADCAST_PKT) etdev->Stats.brdcstrcv++; else /* Not sure what this counter measures in @@ -990,7 +977,7 @@ PMP_RFD nic_rx_pkts(struct et131x_adapter *etdev) etdev->net_stats.rx_bytes += rfd->PacketSize; memcpy(skb_put(skb, rfd->PacketSize), - rx_local->Fbr[rindex]->Va[bindex], + rx_local->fbr[rindex]->virt[bindex], rfd->PacketSize); skb->dev = etdev->netdev; @@ -1014,7 +1001,7 @@ PMP_RFD nic_rx_pkts(struct et131x_adapter *etdev) */ void et131x_reset_recv(struct et131x_adapter *etdev) { - WARN_ON(list_empty(&etdev->RxRing.RecvList)); + WARN_ON(list_empty(&etdev->rx_ring.RecvList)); } @@ -1032,8 +1019,8 @@ void et131x_handle_recv_interrupt(struct et131x_adapter *etdev) /* Process up to available RFD's */ while (count < NUM_PACKETS_HANDLED) { - if (list_empty(&etdev->RxRing.RecvList)) { - WARN_ON(etdev->RxRing.nReadyRecv != 0); + if (list_empty(&etdev->rx_ring.RecvList)) { + WARN_ON(etdev->rx_ring.nReadyRecv != 0); done = false; break; } @@ -1058,7 +1045,7 @@ void et131x_handle_recv_interrupt(struct et131x_adapter *etdev) etdev->Stats.ipackets++; /* Set the status on the packet, either resources or success */ - if (etdev->RxRing.nReadyRecv < RFD_LOW_WATER_MARK) { + if (etdev->rx_ring.nReadyRecv < RFD_LOW_WATER_MARK) { dev_warn(&etdev->pdev->dev, "RFD's are running out\n"); } @@ -1066,12 +1053,12 @@ void et131x_handle_recv_interrupt(struct et131x_adapter *etdev) } if (count == NUM_PACKETS_HANDLED || !done) { - etdev->RxRing.UnfinishedReceives = true; + etdev->rx_ring.UnfinishedReceives = true; writel(PARM_TX_TIME_INT_DEF * NANO_IN_A_MICRO, &etdev->regs->global.watchdog_timer); } else /* Watchdog timer will disable itself if appropriate. */ - etdev->RxRing.UnfinishedReceives = false; + etdev->rx_ring.UnfinishedReceives = false; } static inline u32 bump_fbr(u32 *fbr, u32 limit) @@ -1099,10 +1086,10 @@ static inline u32 bump_fbr(u32 *fbr, u32 limit) */ void nic_return_rfd(struct et131x_adapter *etdev, PMP_RFD rfd) { - struct _rx_ring_t *rx_local = &etdev->RxRing; - struct _RXDMA_t __iomem *rx_dma = &etdev->regs->rxdma; - uint16_t bi = rfd->bufferindex; - uint8_t ri = rfd->ringindex; + struct rx_ring *rx_local = &etdev->rx_ring; + struct rxdma_regs __iomem *rx_dma = &etdev->regs->rxdma; + u16 bi = rfd->bufferindex; + u8 ri = rfd->ringindex; unsigned long flags; /* We don't use any of the OOB data besides status. Otherwise, we @@ -1116,17 +1103,17 @@ void nic_return_rfd(struct et131x_adapter *etdev, PMP_RFD rfd) spin_lock_irqsave(&etdev->FbrLock, flags); if (ri == 1) { - PFBR_DESC_t next = - (PFBR_DESC_t) (rx_local->pFbr1RingVa) + - INDEX10(rx_local->local_Fbr1_full); + struct fbr_desc *next = + (struct fbr_desc *) (rx_local->pFbr1RingVa) + + INDEX10(rx_local->local_Fbr1_full); /* Handle the Free Buffer Ring advancement here. Write * the PA / Buffer Index for the returned buffer into * the oldest (next to be freed)FBR entry */ - next->addr_hi = rx_local->Fbr[1]->PAHigh[bi]; - next->addr_lo = rx_local->Fbr[1]->PALow[bi]; - next->word2.value = bi; + next->addr_hi = rx_local->fbr[1]->bus_high[bi]; + next->addr_lo = rx_local->fbr[1]->bus_low[bi]; + next->word2 = bi; writel(bump_fbr(&rx_local->local_Fbr1_full, rx_local->Fbr1NumEntries - 1), @@ -1134,17 +1121,17 @@ void nic_return_rfd(struct et131x_adapter *etdev, PMP_RFD rfd) } #ifdef USE_FBR0 else { - PFBR_DESC_t next = - (PFBR_DESC_t) rx_local->pFbr0RingVa + - INDEX10(rx_local->local_Fbr0_full); + struct fbr_desc *next = (struct fbr_desc *) + rx_local->pFbr0RingVa + + INDEX10(rx_local->local_Fbr0_full); /* Handle the Free Buffer Ring advancement here. Write * the PA / Buffer Index for the returned buffer into * the oldest (next to be freed) FBR entry */ - next->addr_hi = rx_local->Fbr[0]->PAHigh[bi]; - next->addr_lo = rx_local->Fbr[0]->PALow[bi]; - next->word2.value = bi; + next->addr_hi = rx_local->fbr[0]->bus_high[bi]; + next->addr_lo = rx_local->fbr[0]->bus_low[bi]; + next->word2 = bi; writel(bump_fbr(&rx_local->local_Fbr0_full, rx_local->Fbr0NumEntries - 1), diff --git a/drivers/staging/et131x/et1310_rx.h b/drivers/staging/et131x/et1310_rx.h index 6951459..ca84a91 100644 --- a/drivers/staging/et131x/et1310_rx.h +++ b/drivers/staging/et131x/et1310_rx.h @@ -91,120 +91,60 @@ #define ALCATEL_BROADCAST_PKT 0x02000000 /* typedefs for Free Buffer Descriptors */ -typedef union _FBR_WORD2_t { - u32 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u32 reserved:22; /* bits 10-31 */ - u32 bi:10; /* bits 0-9(Buffer Index) */ -#else - u32 bi:10; /* bits 0-9(Buffer Index) */ - u32 reserved:22; /* bit 10-31 */ -#endif - } bits; -} FBR_WORD2_t, *PFBR_WORD2_t; - -typedef struct _FBR_DESC_t { +struct fbr_desc +{ u32 addr_lo; u32 addr_hi; - FBR_WORD2_t word2; -} FBR_DESC_t, *PFBR_DESC_t; - -/* Typedefs for Packet Status Ring Descriptors */ -typedef union _PKT_STAT_DESC_WORD0_t { - u32 value; - struct { -#ifdef _BIT_FIELDS_HTOL - /* top 16 bits are from the Alcatel Status Word as enumerated in */ - /* PE-MCXMAC Data Sheet IPD DS54 0210-1 (also IPD-DS80 0205-2) */ -#if 0 - u32 asw_trunc:1; /* bit 31(Rx frame truncated) */ -#endif - u32 asw_long_evt:1; /* bit 31(Rx long event) */ - u32 asw_VLAN_tag:1; /* bit 30(VLAN tag detected) */ - u32 asw_unsupported_op:1; /* bit 29(unsupported OP code) */ - u32 asw_pause_frame:1; /* bit 28(is a pause frame) */ - u32 asw_control_frame:1; /* bit 27(is a control frame) */ - u32 asw_dribble_nibble:1; /* bit 26(spurious bits after EOP) */ - u32 asw_broadcast:1; /* bit 25(has a broadcast address) */ - u32 asw_multicast:1; /* bit 24(has a multicast address) */ - u32 asw_OK:1; /* bit 23(valid CRC + no code error) */ - u32 asw_too_long:1; /* bit 22(frame length > 1518 bytes) */ - u32 asw_len_chk_err:1; /* bit 21(frame length field incorrect) */ - u32 asw_CRC_err:1; /* bit 20(CRC error) */ - u32 asw_code_err:1; /* bit 19(one or more nibbles signalled as errors) */ - u32 asw_false_carrier_event:1; /* bit 18(bad carrier since last good packet) */ - u32 asw_RX_DV_event:1; /* bit 17(short receive event detected) */ - u32 asw_prev_pkt_dropped:1;/* bit 16(e.g. IFG too small on previous) */ - u32 unused:5; /* bits 11-15 */ - u32 vp:1; /* bit 10(VLAN Packet) */ - u32 jp:1; /* bit 9(Jumbo Packet) */ - u32 ft:1; /* bit 8(Frame Truncated) */ - u32 drop:1; /* bit 7(Drop packet) */ - u32 rxmac_error:1; /* bit 6(RXMAC Error Indicator) */ - u32 wol:1; /* bit 5(WOL Event) */ - u32 tcpp:1; /* bit 4(TCP checksum pass) */ - u32 tcpa:1; /* bit 3(TCP checksum assist) */ - u32 ipp:1; /* bit 2(IP checksum pass) */ - u32 ipa:1; /* bit 1(IP checksum assist) */ - u32 hp:1; /* bit 0(hash pass) */ -#else - u32 hp:1; /* bit 0(hash pass) */ - u32 ipa:1; /* bit 1(IP checksum assist) */ - u32 ipp:1; /* bit 2(IP checksum pass) */ - u32 tcpa:1; /* bit 3(TCP checksum assist) */ - u32 tcpp:1; /* bit 4(TCP checksum pass) */ - u32 wol:1; /* bit 5(WOL Event) */ - u32 rxmac_error:1; /* bit 6(RXMAC Error Indicator) */ - u32 drop:1; /* bit 7(Drop packet) */ - u32 ft:1; /* bit 8(Frame Truncated) */ - u32 jp:1; /* bit 9(Jumbo Packet) */ - u32 vp:1; /* bit 10(VLAN Packet) */ - u32 unused:5; /* bits 11-15 */ - u32 asw_prev_pkt_dropped:1;/* bit 16(e.g. IFG too small on previous) */ - u32 asw_RX_DV_event:1; /* bit 17(short receive event detected) */ - u32 asw_false_carrier_event:1; /* bit 18(bad carrier since last good packet) */ - u32 asw_code_err:1; /* bit 19(one or more nibbles signalled as errors) */ - u32 asw_CRC_err:1; /* bit 20(CRC error) */ - u32 asw_len_chk_err:1; /* bit 21(frame length field incorrect) */ - u32 asw_too_long:1; /* bit 22(frame length > 1518 bytes) */ - u32 asw_OK:1; /* bit 23(valid CRC + no code error) */ - u32 asw_multicast:1; /* bit 24(has a multicast address) */ - u32 asw_broadcast:1; /* bit 25(has a broadcast address) */ - u32 asw_dribble_nibble:1; /* bit 26(spurious bits after EOP) */ - u32 asw_control_frame:1; /* bit 27(is a control frame) */ - u32 asw_pause_frame:1; /* bit 28(is a pause frame) */ - u32 asw_unsupported_op:1; /* bit 29(unsupported OP code) */ - u32 asw_VLAN_tag:1; /* bit 30(VLAN tag detected) */ - u32 asw_long_evt:1; /* bit 31(Rx long event) */ -#if 0 - u32 asw_trunc:1; /* bit 31(Rx frame truncated) */ -#endif -#endif - } bits; -} PKT_STAT_DESC_WORD0_t, *PPKT_STAT_WORD0_t; + u32 word2; /* Bits 10-31 reserved, 0-9 descriptor */ +}; -typedef union _PKT_STAT_DESC_WORD1_t { - u32 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u32 unused:4; /* bits 28-31 */ - u32 ri:2; /* bits 26-27(Ring Index) */ - u32 bi:10; /* bits 16-25(Buffer Index) */ - u32 length:16; /* bit 0-15(length in bytes) */ -#else - u32 length:16; /* bit 0-15(length in bytes) */ - u32 bi:10; /* bits 16-25(Buffer Index) */ - u32 ri:2; /* bits 26-27(Ring Index) */ - u32 unused:4; /* bits 28-31 */ -#endif - } bits; -} PKT_STAT_DESC_WORD1_t, *PPKT_STAT_WORD1_t; +/* Packet Status Ring Descriptors + * + * Word 0: + * + * top 16 bits are from the Alcatel Status Word as enumerated in + * PE-MCXMAC Data Sheet IPD DS54 0210-1 (also IPD-DS80 0205-2) + * + * 0: hp hash pass + * 1: ipa IP checksum assist + * 2: ipp IP checksum pass + * 3: tcpa TCP checksum assist + * 4: tcpp TCP checksum pass + * 5: wol WOL Event + * 6: rxmac_error RXMAC Error Indicator + * 7: drop Drop packet + * 8: ft Frame Truncated + * 9: jp Jumbo Packet + * 10: vp VLAN Packet + * 11-15: unused + * 16: asw_prev_pkt_dropped e.g. IFG too small on previous + * 17: asw_RX_DV_event short receive event detected + * 18: asw_false_carrier_event bad carrier since last good packet + * 19: asw_code_err one or more nibbles signalled as errors + * 20: asw_CRC_err CRC error + * 21: asw_len_chk_err frame length field incorrect + * 22: asw_too_long frame length > 1518 bytes + * 23: asw_OK valid CRC + no code error + * 24: asw_multicast has a multicast address + * 25: asw_broadcast has a broadcast address + * 26: asw_dribble_nibble spurious bits after EOP + * 27: asw_control_frame is a control frame + * 28: asw_pause_frame is a pause frame + * 29: asw_unsupported_op unsupported OP code + * 30: asw_VLAN_tag VLAN tag detected + * 31: asw_long_evt Rx long event + * + * Word 1: + * 0-15: length length in bytes + * 16-25: bi Buffer Index + * 26-27: ri Ring Index + * 28-31: reserved + */ -typedef struct _PKT_STAT_DESC_t { - PKT_STAT_DESC_WORD0_t word0; - PKT_STAT_DESC_WORD1_t word1; -} PKT_STAT_DESC_t, *PPKT_STAT_DESC_t; +struct pkt_stat_desc { + u32 word0; + u32 word1; +}; /* Typedefs for the RX DMA status word */ @@ -223,59 +163,38 @@ typedef struct _PKT_STAT_DESC_t { * RXSTAT_WORD1_t structure holds part of the status bits of the Rx DMA engine * that get copied out to memory by the ET-1310. Word 3 is a 32 bit word * which contains the Packet Status Ring available offset. + * + * bit 0-15 reserved + * bit 16-27 PSRoffset + * bit 28 PSRwrap + * bit 29-31 unused */ -#define RXSTAT1_OFFSET 16 -#define RXSTAT1_MASK 0xFFF -#define RXSTAT1_WRAP 0x10000000 - -typedef union _rxstat_word1_t { - u32 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u32 PSRunused:3; /* bits 29-31 */ - u32 PSRwrap:1; /* bit 28 */ - u32 PSRoffset:12; /* bits 16-27 */ - u32 reserved:16; /* bits 0-15 */ -#else - u32 reserved:16; /* bits 0-15 */ - u32 PSRoffset:12; /* bits 16-27 */ - u32 PSRwrap:1; /* bit 28 */ - u32 PSRunused:3; /* bits 29-31 */ -#endif - } bits; -} RXSTAT_WORD1_t, *PRXSTAT_WORD1_t; - /* - * RX_STATUS_BLOCK_t is sructure representing the status of the Rx DMA engine - * it sits in free memory, and is pointed to by 0x101c / 0x1020 + * struct rx_status_block is a structure representing the status of the Rx + * DMA engine it sits in free memory, and is pointed to by 0x101c / 0x1020 */ -typedef struct _rx_status_block_t { +struct rx_status_block { u32 Word0; - RXSTAT_WORD1_t Word1; -} RX_STATUS_BLOCK_t, *PRX_STATUS_BLOCK_t; + u32 Word1; +}; /* * Structure for look-up table holding free buffer ring pointers */ -typedef struct _FbrLookupTable { - void *Va[MAX_DESC_PER_RING_RX]; - void *Buffer1[MAX_DESC_PER_RING_RX]; - void *Buffer2[MAX_DESC_PER_RING_RX]; - u32 PAHigh[MAX_DESC_PER_RING_RX]; - u32 PALow[MAX_DESC_PER_RING_RX]; -} FBRLOOKUPTABLE, *PFBRLOOKUPTABLE; - -typedef enum { - ONE_PACKET_INTERRUPT, - FOUR_PACKET_INTERRUPT -} eRX_INTERRUPT_STATE_t, *PeRX_INTERRUPT_STATE_t; +struct fbr_lookup { + void *virt[MAX_DESC_PER_RING_RX]; + void *buffer1[MAX_DESC_PER_RING_RX]; + void *buffer2[MAX_DESC_PER_RING_RX]; + u32 bus_high[MAX_DESC_PER_RING_RX]; + u32 bus_low[MAX_DESC_PER_RING_RX]; +}; /* - * RX_RING_t is sructure representing the adaptor's local reference(s) to the - * rings + * struct rx_ring is the ssructure representing the adaptor's local + * reference(s) to the rings */ -typedef struct _rx_ring_t { +struct rx_ring { #ifdef USE_FBR0 void *pFbr0RingVa; dma_addr_t pFbr0RingPa; @@ -293,7 +212,7 @@ typedef struct _rx_ring_t { dma_addr_t Fbr1MemPa[MAX_DESC_PER_RING_RX / FBR_CHUNKS]; uint64_t Fbr1Realpa; uint64_t Fbr1offset; - FBRLOOKUPTABLE *Fbr[2]; + struct fbr_lookup *fbr[2]; /* One per ring */ u32 local_Fbr1_full; u32 Fbr1NumEntries; u32 Fbr1BufferSize; @@ -303,8 +222,8 @@ typedef struct _rx_ring_t { u32 local_psr_full; u32 PsrNumEntries; - void *pRxStatusVa; - dma_addr_t pRxStatusPa; + struct rx_status_block *rx_status_block; + dma_addr_t rx_status_bus; struct list_head RecvBufferPool; @@ -320,30 +239,6 @@ typedef struct _rx_ring_t { /* lookaside lists */ struct kmem_cache *RecvLookaside; -} RX_RING_t, *PRX_RING_t; - -/* Forward reference of RFD */ -struct _MP_RFD; - -/* Forward declaration of the private adapter structure */ -struct et131x_adapter; - -/* PROTOTYPES for Initialization */ -int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter); -void et131x_rx_dma_memory_free(struct et131x_adapter *adapter); -int et131x_rfd_resources_alloc(struct et131x_adapter *adapter, - struct _MP_RFD *pMpRfd); -void et131x_rfd_resources_free(struct et131x_adapter *adapter, - struct _MP_RFD *pMpRfd); -int et131x_init_recv(struct et131x_adapter *adapter); - -void ConfigRxDmaRegs(struct et131x_adapter *adapter); -void SetRxDmaTimer(struct et131x_adapter *adapter); -void et131x_rx_dma_disable(struct et131x_adapter *adapter); -void et131x_rx_dma_enable(struct et131x_adapter *adapter); - -void et131x_reset_recv(struct et131x_adapter *adapter); - -void et131x_handle_recv_interrupt(struct et131x_adapter *adapter); +}; #endif /* __ET1310_RX_H__ */ diff --git a/drivers/staging/et131x/et1310_tx.c b/drivers/staging/et131x/et1310_tx.c index 977e8b3..b6ff20f 100644 --- a/drivers/staging/et131x/et1310_tx.c +++ b/drivers/staging/et131x/et1310_tx.c @@ -84,15 +84,9 @@ #include <linux/ioport.h> #include "et1310_phy.h" -#include "et1310_pm.h" -#include "et1310_jagcore.h" - #include "et131x_adapter.h" -#include "et131x_initpci.h" -#include "et131x_isr.h" - #include "et1310_tx.h" - +#include "et131x.h" static inline void et131x_free_send_packet(struct et131x_adapter *etdev, struct tcb *tcb); @@ -200,7 +194,7 @@ void et131x_tx_dma_memory_free(struct et131x_adapter *adapter) */ void ConfigTxDmaRegs(struct et131x_adapter *etdev) { - struct _TXDMA_t __iomem *txdma = &etdev->regs->txdma; + struct txdma_regs __iomem *txdma = &etdev->regs->txdma; /* Load the hardware with the start of the transmit descriptor ring. */ writel((u32) ((u64)etdev->tx_ring.tx_desc_ring_pa >> 32), diff --git a/drivers/staging/et131x/et1310_tx.h b/drivers/staging/et131x/et1310_tx.h index 4f0ea81..82d06e9 100644 --- a/drivers/staging/et131x/et1310_tx.h +++ b/drivers/staging/et131x/et1310_tx.h @@ -147,18 +147,4 @@ struct tx_ring { int since_irq; }; -/* Forward declaration of the private adapter structure */ -struct et131x_adapter; - -/* PROTOTYPES for et1310_tx.c */ -int et131x_tx_dma_memory_alloc(struct et131x_adapter *adapter); -void et131x_tx_dma_memory_free(struct et131x_adapter *adapter); -void ConfigTxDmaRegs(struct et131x_adapter *adapter); -void et131x_init_send(struct et131x_adapter *adapter); -void et131x_tx_dma_disable(struct et131x_adapter *adapter); -void et131x_tx_dma_enable(struct et131x_adapter *adapter); -void et131x_handle_send_interrupt(struct et131x_adapter *adapter); -void et131x_free_busy_send_packets(struct et131x_adapter *adapter); -int et131x_send_packets(struct sk_buff *skb, struct net_device *netdev); - #endif /* __ET1310_TX_H__ */ diff --git a/drivers/staging/et131x/et131x.h b/drivers/staging/et131x/et131x.h new file mode 100644 index 0000000..a8abfe6 --- /dev/null +++ b/drivers/staging/et131x/et131x.h @@ -0,0 +1,153 @@ +/* + * Merged from files + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, are permitted provided that the following conditions are met: + * + * . Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following Disclaimer as comments in the code as + * well as in the documentation and/or other materials provided with the + * distribution. + * + * . Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following Disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + */ + +/* et131x_eeprom.c */ +int et131x_init_eeprom(struct et131x_adapter *etdev); + +/* et131x_initpci.c */ +void ConfigGlobalRegs(struct et131x_adapter *pAdapter); +void ConfigMMCRegs(struct et131x_adapter *pAdapter); +void et131x_enable_interrupts(struct et131x_adapter *adapter); +void et131x_disable_interrupts(struct et131x_adapter *adapter); +void et131x_align_allocated_memory(struct et131x_adapter *adapter, + u64 *phys_addr, + u64 *offset, u64 mask); + +int et131x_adapter_setup(struct et131x_adapter *adapter); +int et131x_adapter_memory_alloc(struct et131x_adapter *adapter); +void et131x_adapter_memory_free(struct et131x_adapter *adapter); +void et131x_hwaddr_init(struct et131x_adapter *adapter); +void et131x_soft_reset(struct et131x_adapter *adapter); + +/* et131x_isr.c */ +irqreturn_t et131x_isr(int irq, void *dev_id); +void et131x_isr_handler(struct work_struct *work); + +/* et1310_mac.c */ +void ConfigMACRegs1(struct et131x_adapter *adapter); +void ConfigMACRegs2(struct et131x_adapter *adapter); +void ConfigRxMacRegs(struct et131x_adapter *adapter); +void ConfigTxMacRegs(struct et131x_adapter *adapter); +void ConfigMacStatRegs(struct et131x_adapter *adapter); +void ConfigFlowControl(struct et131x_adapter *adapter); +void UpdateMacStatHostCounters(struct et131x_adapter *adapter); +void HandleMacStatInterrupt(struct et131x_adapter *adapter); +void SetupDeviceForMulticast(struct et131x_adapter *adapter); +void SetupDeviceForUnicast(struct et131x_adapter *adapter); + +/* et131x_netdev.c */ +struct net_device *et131x_device_alloc(void); + +/* et131x_pm.c */ +void EnablePhyComa(struct et131x_adapter *adapter); +void DisablePhyComa(struct et131x_adapter *adapter); + +/* et131x_phy.c */ +void ET1310_PhyInit(struct et131x_adapter *adapter); +void ET1310_PhyReset(struct et131x_adapter *adapter); +void ET1310_PhyPowerDown(struct et131x_adapter *adapter, bool down); +void ET1310_PhyAdvertise1000BaseT(struct et131x_adapter *adapter, + u16 duplex); +void ET1310_PhyAccessMiBit(struct et131x_adapter *adapter, + u16 action, + u16 regnum, u16 bitnum, u8 *value); + +int et131x_xcvr_find(struct et131x_adapter *adapter); +void et131x_setphy_normal(struct et131x_adapter *adapter); + +/* static inline function does not work because et131x_adapter is not always + * defined + */ +int PhyMiRead(struct et131x_adapter *adapter, u8 xcvrAddr, + u8 xcvrReg, u16 *value); +#define MiRead(adapter, xcvrReg, value) \ + PhyMiRead((adapter), (adapter)->Stats.xcvr_addr, (xcvrReg), (value)) + +int32_t MiWrite(struct et131x_adapter *adapter, + u8 xcvReg, u16 value); +void et131x_Mii_check(struct et131x_adapter *pAdapter, + MI_BMSR_t bmsr, MI_BMSR_t bmsr_ints); + +/* This last is not strictly required (the driver could call the TPAL + * version instead), but this sets the adapter up correctly, and calls the + * access routine indirectly. This protects the driver from changes in TPAL. + */ +void SetPhy_10BaseTHalfDuplex(struct et131x_adapter *adapter); + + +/* et1310_rx.c */ +int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter); +void et131x_rx_dma_memory_free(struct et131x_adapter *adapter); +int et131x_rfd_resources_alloc(struct et131x_adapter *adapter, + struct _MP_RFD *pMpRfd); +void et131x_rfd_resources_free(struct et131x_adapter *adapter, + struct _MP_RFD *pMpRfd); +int et131x_init_recv(struct et131x_adapter *adapter); + +void ConfigRxDmaRegs(struct et131x_adapter *adapter); +void SetRxDmaTimer(struct et131x_adapter *adapter); +void et131x_rx_dma_disable(struct et131x_adapter *adapter); +void et131x_rx_dma_enable(struct et131x_adapter *adapter); + +void et131x_reset_recv(struct et131x_adapter *adapter); + +void et131x_handle_recv_interrupt(struct et131x_adapter *adapter); + +/* et131x_tx.c */ +int et131x_tx_dma_memory_alloc(struct et131x_adapter *adapter); +void et131x_tx_dma_memory_free(struct et131x_adapter *adapter); +void ConfigTxDmaRegs(struct et131x_adapter *adapter); +void et131x_init_send(struct et131x_adapter *adapter); +void et131x_tx_dma_disable(struct et131x_adapter *adapter); +void et131x_tx_dma_enable(struct et131x_adapter *adapter); +void et131x_handle_send_interrupt(struct et131x_adapter *adapter); +void et131x_free_busy_send_packets(struct et131x_adapter *adapter); +int et131x_send_packets(struct sk_buff *skb, struct net_device *netdev); + diff --git a/drivers/staging/et131x/et131x_adapter.h b/drivers/staging/et131x/et131x_adapter.h index 3f7f37a..64a678f 100644 --- a/drivers/staging/et131x/et131x_adapter.h +++ b/drivers/staging/et131x/et131x_adapter.h @@ -77,38 +77,11 @@ */ #define NUM_TRAFFIC_CLASSES 1 -/* - * There are three ways of counting errors - if there are more than X errors - * in Y packets (represented by the "SAMPLE" macros), if there are more than - * N errors in a S mSec time period (the "PERIOD" macros), or if there are - * consecutive packets with errors (CONSEC_ERRORED_THRESH). This last covers - * for "Bursty" errors, and the errored packets may well not be contiguous, - * but several errors where the packet counter has changed by less than a - * small amount will cause this count to increment. - */ -#define TX_PACKETS_IN_SAMPLE 10000 -#define TX_MAX_ERRORS_IN_SAMPLE 50 - #define TX_ERROR_PERIOD 1000 -#define TX_MAX_ERRORS_IN_PERIOD 10 - -#define LINK_DETECTION_TIMER 5000 - -#define TX_CONSEC_RANGE 5 -#define TX_CONSEC_ERRORED_THRESH 10 #define LO_MARK_PERCENT_FOR_PSR 15 #define LO_MARK_PERCENT_FOR_RX 15 -/* Counters for error rate monitoring */ -typedef struct _MP_ERR_COUNTERS { - u32 PktCountTxPackets; - u32 PktCountTxErrors; - u32 TimerBasedTxErrors; - u32 PktCountLastError; - u32 ErredConsecPackets; -} MP_ERR_COUNTERS, *PMP_ERR_COUNTERS; - /* RFD (Receive Frame Descriptor) */ typedef struct _MP_RFD { struct list_head list_node; @@ -174,6 +147,20 @@ typedef struct _ce_stats_t { u32 InterruptStatus; } CE_STATS_t, *PCE_STATS_t; +typedef struct _MP_POWER_MGMT { + /* variable putting the phy into coma mode when boot up with no cable + * plugged in after 5 seconds + */ + u8 TransPhyComaModeOnBoot; + + /* Next two used to save power information at power down. This + * information will be used during power up to set up parts of Power + * Management in JAGCore + */ + u16 PowerDownSpeed; + u8 PowerDownDuplex; +} MP_POWER_MGMT, *PMP_POWER_MGMT; + /* The private adapter structure */ struct et131x_adapter { struct net_device *netdev; @@ -248,7 +235,7 @@ struct et131x_adapter { struct tx_ring tx_ring; /* Rx Memory Variables */ - RX_RING_t RxRing; + struct rx_ring rx_ring; /* Loopback specifics */ u8 ReplicaPhyLoopbk; /* Replica Enable */ diff --git a/drivers/staging/et131x/et131x_config.h b/drivers/staging/et131x/et131x_config.h deleted file mode 100644 index 642c0f6..0000000 --- a/drivers/staging/et131x/et131x_config.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Agere Systems Inc. - * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs - * - * Copyright © 2005 Agere Systems Inc. - * All rights reserved. - * http://www.agere.com - * - *------------------------------------------------------------------------------ - * - * et131x_config.h - Defines, structs, enums, prototypes, etc. to support - * et131x_config.c - * - *------------------------------------------------------------------------------ - * - * SOFTWARE LICENSE - * - * This software is provided subject to the following terms and conditions, - * which you should read carefully before using the software. Using this - * software indicates your acceptance of these terms and conditions. If you do - * not agree with these terms and conditions, do not use the software. - * - * Copyright © 2005 Agere Systems Inc. - * All rights reserved. - * - * Redistribution and use in source or binary forms, with or without - * modifications, are permitted provided that the following conditions are met: - * - * . Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following Disclaimer as comments in the code as - * well as in the documentation and/or other materials provided with the - * distribution. - * - * . Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following Disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * . Neither the name of Agere Systems Inc. nor the names of the contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * Disclaimer - * - * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY - * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN - * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - */ - -#ifndef __ET131X_CONFIG_H__ -#define __ET131X_CONFIG_H__ - -/* Forward declaration of the private adapter structure */ -struct et131x_adapter; - -void et131x_config_parse(struct et131x_adapter *adapter); - -#endif /* __ET131X_CONFIG_H__ */ diff --git a/drivers/staging/et131x/et131x_initpci.c b/drivers/staging/et131x/et131x_initpci.c index 0892b6a..5ad7e5a 100644 --- a/drivers/staging/et131x/et131x_initpci.c +++ b/drivers/staging/et131x/et131x_initpci.c @@ -87,20 +87,16 @@ #include <linux/random.h> #include "et1310_phy.h" -#include "et1310_pm.h" -#include "et1310_jagcore.h" #include "et131x_adapter.h" -#include "et131x_netdev.h" -#include "et131x_config.h" -#include "et131x_isr.h" #include "et1310_address_map.h" #include "et1310_tx.h" #include "et1310_rx.h" -#include "et1310_mac.h" -#include "et1310_eeprom.h" +#include "et131x.h" +#define INTERNAL_MEM_SIZE 0x400 /* 1024 of internal memory */ +#define INTERNAL_MEM_RX_OFFSET 0x1FF /* 50% Tx, 50% Rx */ /* Defines for Parameter Default/Min/Max vaules */ #define PARM_SPEED_DUPLEX_MIN 0 @@ -327,7 +323,7 @@ void et131x_link_detection_handler(unsigned long data) */ void ConfigGlobalRegs(struct et131x_adapter *etdev) { - struct _GLOBAL_t __iomem *regs = &etdev->regs->global; + struct global_regs __iomem *regs = &etdev->regs->global; writel(0, ®s->rxq_start_addr); writel(INTERNAL_MEM_SIZE - 1, ®s->txq_end_addr); diff --git a/drivers/staging/et131x/et131x_initpci.h b/drivers/staging/et131x/et131x_initpci.h deleted file mode 100644 index 7269569..0000000 --- a/drivers/staging/et131x/et131x_initpci.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Agere Systems Inc. - * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs - * - * Copyright © 2005 Agere Systems Inc. - * All rights reserved. - * http://www.agere.com - * - *------------------------------------------------------------------------------ - * - * et131x_initpci.h - Header which includes common data and function prototypes - * related to the driver's PCI (and PCI Express) information. - * - *------------------------------------------------------------------------------ - * - * SOFTWARE LICENSE - * - * This software is provided subject to the following terms and conditions, - * which you should read carefully before using the software. Using this - * software indicates your acceptance of these terms and conditions. If you do - * not agree with these terms and conditions, do not use the software. - * - * Copyright © 2005 Agere Systems Inc. - * All rights reserved. - * - * Redistribution and use in source or binary forms, with or without - * modifications, are permitted provided that the following conditions are met: - * - * . Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following Disclaimer as comments in the code as - * well as in the documentation and/or other materials provided with the - * distribution. - * - * . Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following Disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * . Neither the name of Agere Systems Inc. nor the names of the contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * Disclaimer - * - * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY - * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN - * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - */ - -#ifndef __ET131X_INITPCI_H__ -#define __ET131X_INITPCI_H__ - -/* Function Prototypes */ -void et131x_align_allocated_memory(struct et131x_adapter *adapter, - u64 *phys_addr, - u64 *offset, u64 mask); - -int et131x_adapter_setup(struct et131x_adapter *adapter); -int et131x_adapter_memory_alloc(struct et131x_adapter *adapter); -void et131x_adapter_memory_free(struct et131x_adapter *adapter); -void et131x_hwaddr_init(struct et131x_adapter *adapter); -void et131x_soft_reset(struct et131x_adapter *adapter); - -#endif /* __ET131X_INITPCI_H__ */ diff --git a/drivers/staging/et131x/et131x_isr.c b/drivers/staging/et131x/et131x_isr.c index f6d452d..8b6e0b7 100644 --- a/drivers/staging/et131x/et131x_isr.c +++ b/drivers/staging/et131x/et131x_isr.c @@ -85,11 +85,27 @@ #include <linux/ioport.h> #include "et1310_phy.h" -#include "et1310_pm.h" -#include "et1310_jagcore.h" -#include "et1310_mac.h" - #include "et131x_adapter.h" +#include "et131x.h" + +/* + * For interrupts, normal running is: + * rxdma_xfr_done, phy_interrupt, mac_stat_interrupt, + * watchdog_interrupt & txdma_xfer_done + * + * In both cases, when flow control is enabled for either Tx or bi-direction, + * we additional enable rx_fbr0_low and rx_fbr1_low, so we know when the + * buffer rings are running low. + */ +#define INT_MASK_DISABLE 0xffffffff + +/* NOTE: Masking out MAC_STAT Interrupt for now... + * #define INT_MASK_ENABLE 0xfff6bf17 + * #define INT_MASK_ENABLE_NO_FLOW 0xfff6bfd7 + */ +#define INT_MASK_ENABLE 0xfffebf17 +#define INT_MASK_ENABLE_NO_FLOW 0xfffebfd7 + /** * et131x_enable_interrupts - enable interrupt @@ -185,7 +201,7 @@ irqreturn_t et131x_isr(int irq, void *dev_id) if (++tcb->stale > 1) status |= ET_INTR_TXDMA_ISR; - if (adapter->RxRing.UnfinishedReceives) + if (adapter->rx_ring.UnfinishedReceives) status |= ET_INTR_RXDMA_XFR_DONE; else if (tcb == NULL) writel(0, &adapter->regs->global.watchdog_timer); @@ -390,7 +406,7 @@ void et131x_isr_handler(struct work_struct *work) /* Let's move on to the TxMac */ if (status & ET_INTR_TXMAC) { - u32 err = readl(&iomem->txmac.err.value); + u32 err = readl(&iomem->txmac.err); /* * When any of the errors occur and TXMAC generates @@ -425,12 +441,12 @@ void et131x_isr_handler(struct work_struct *work) dev_warn(&etdev->pdev->dev, "RXMAC interrupt, error 0x%08x. Requesting reset\n", - readl(&iomem->rxmac.err_reg.value)); + readl(&iomem->rxmac.err_reg)); dev_warn(&etdev->pdev->dev, "Enable 0x%08x, Diag 0x%08x\n", - readl(&iomem->rxmac.ctrl.value), - readl(&iomem->rxmac.rxq_diag.value)); + readl(&iomem->rxmac.ctrl), + readl(&iomem->rxmac.rxq_diag)); /* * If we are debugging, we want to see this error, diff --git a/drivers/staging/et131x/et131x_isr.h b/drivers/staging/et131x/et131x_isr.h deleted file mode 100644 index 906d577..0000000 --- a/drivers/staging/et131x/et131x_isr.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Agere Systems Inc. - * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs - * - * Copyright © 2005 Agere Systems Inc. - * All rights reserved. - * http://www.agere.com - * - *------------------------------------------------------------------------------ - * - * et131x_isr.h - Defines, structs, enums, prototypes, etc. pertaining to the - * ISR processing code. - * - *------------------------------------------------------------------------------ - * - * SOFTWARE LICENSE - * - * This software is provided subject to the following terms and conditions, - * which you should read carefully before using the software. Using this - * software indicates your acceptance of these terms and conditions. If you do - * not agree with these terms and conditions, do not use the software. - * - * Copyright © 2005 Agere Systems Inc. - * All rights reserved. - * - * Redistribution and use in source or binary forms, with or without - * modifications, are permitted provided that the following conditions are met: - * - * . Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following Disclaimer as comments in the code as - * well as in the documentation and/or other materials provided with the - * distribution. - * - * . Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following Disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * . Neither the name of Agere Systems Inc. nor the names of the contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * Disclaimer - * - * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY - * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN - * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - */ - -#ifndef __ET131X_ISR_H__ -#define __ET131X_ISR_H__ - -irqreturn_t et131x_isr(int irq, void *dev_id); -void et131x_isr_handler(struct work_struct *work); - -#endif /* __ET131X_ISR_H__ */ diff --git a/drivers/staging/et131x/et131x_netdev.c b/drivers/staging/et131x/et131x_netdev.c index edb78ae..40f8954 100644 --- a/drivers/staging/et131x/et131x_netdev.c +++ b/drivers/staging/et131x/et131x_netdev.c @@ -85,14 +85,9 @@ #include <linux/ioport.h> #include "et1310_phy.h" -#include "et1310_pm.h" -#include "et1310_jagcore.h" -#include "et1310_mac.h" #include "et1310_tx.h" - #include "et131x_adapter.h" -#include "et131x_isr.h" -#include "et131x_initpci.h" +#include "et131x.h" struct net_device_stats *et131x_stats(struct net_device *netdev); int et131x_open(struct net_device *netdev); @@ -339,66 +334,64 @@ int et131x_ioctl(struct net_device *netdev, struct ifreq *reqbuf, int cmd) * et131x_set_packet_filter - Configures the Rx Packet filtering on the device * @adapter: pointer to our private adapter structure * + * FIXME: lot of dups with MAC code + * * Returns 0 on success, errno on failure */ int et131x_set_packet_filter(struct et131x_adapter *adapter) { int status = 0; uint32_t filter = adapter->PacketFilter; - RXMAC_CTRL_t ctrl; - RXMAC_PF_CTRL_t pf_ctrl; + u32 ctrl; + u32 pf_ctrl; - ctrl.value = readl(&adapter->regs->rxmac.ctrl.value); - pf_ctrl.value = readl(&adapter->regs->rxmac.pf_ctrl.value); + ctrl = readl(&adapter->regs->rxmac.ctrl); + pf_ctrl = readl(&adapter->regs->rxmac.pf_ctrl); /* Default to disabled packet filtering. Enable it in the individual * case statements that require the device to filter something */ - ctrl.bits.pkt_filter_disable = 1; + ctrl |= 0x04; /* Set us to be in promiscuous mode so we receive everything, this * is also true when we get a packet filter of 0 */ - if ((filter & ET131X_PACKET_TYPE_PROMISCUOUS) || filter == 0) { - pf_ctrl.bits.filter_broad_en = 0; - pf_ctrl.bits.filter_multi_en = 0; - pf_ctrl.bits.filter_uni_en = 0; - } else { + if ((filter & ET131X_PACKET_TYPE_PROMISCUOUS) || filter == 0) + pf_ctrl &= ~7; /* Clear filter bits */ + else { /* * Set us up with Multicast packet filtering. Three cases are * possible - (1) we have a multi-cast list, (2) we receive ALL * multicast entries or (3) we receive none. */ - if (filter & ET131X_PACKET_TYPE_ALL_MULTICAST) { - pf_ctrl.bits.filter_multi_en = 0; - } else { + if (filter & ET131X_PACKET_TYPE_ALL_MULTICAST) + pf_ctrl &= ~2; /* Multicast filter bit */ + else { SetupDeviceForMulticast(adapter); - pf_ctrl.bits.filter_multi_en = 1; - ctrl.bits.pkt_filter_disable = 0; + pf_ctrl |= 2; + ctrl &= ~0x04; } /* Set us up with Unicast packet filtering */ if (filter & ET131X_PACKET_TYPE_DIRECTED) { SetupDeviceForUnicast(adapter); - pf_ctrl.bits.filter_uni_en = 1; - ctrl.bits.pkt_filter_disable = 0; + pf_ctrl |= 4; + ctrl &= ~0x04; } /* Set us up with Broadcast packet filtering */ if (filter & ET131X_PACKET_TYPE_BROADCAST) { - pf_ctrl.bits.filter_broad_en = 1; - ctrl.bits.pkt_filter_disable = 0; - } else { - pf_ctrl.bits.filter_broad_en = 0; - } + pf_ctrl |= 1; /* Broadcast filter bit */ + ctrl &= ~0x04; + } else + pf_ctrl &= ~1; /* Setup the receive mac configuration registers - Packet * Filter control + the enable / disable for packet filter * in the control reg. */ - writel(pf_ctrl.value, - &adapter->regs->rxmac.pf_ctrl.value); - writel(ctrl.value, &adapter->regs->rxmac.ctrl.value); + writel(pf_ctrl, &adapter->regs->rxmac.pf_ctrl); + writel(ctrl, &adapter->regs->rxmac.ctrl); } return status; } @@ -675,12 +668,8 @@ int et131x_set_mac_addr(struct net_device *netdev, void *new_mac) memcpy(netdev->dev_addr, address->sa_data, netdev->addr_len); - printk(KERN_INFO - "%s: Setting MAC address to %02x:%02x:%02x:%02x:%02x:%02x\n", - netdev->name, - netdev->dev_addr[0], netdev->dev_addr[1], - netdev->dev_addr[2], netdev->dev_addr[3], - netdev->dev_addr[4], netdev->dev_addr[5]); + printk(KERN_INFO "%s: Setting MAC address to %pM\n", + netdev->name, netdev->dev_addr); /* Free Rx DMA memory */ et131x_adapter_memory_free(adapter); diff --git a/drivers/staging/et131x/et131x_netdev.h b/drivers/staging/et131x/et131x_netdev.h deleted file mode 100644 index 1eb4a92..0000000 --- a/drivers/staging/et131x/et131x_netdev.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Agere Systems Inc. - * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs - * - * Copyright © 2005 Agere Systems Inc. - * All rights reserved. - * http://www.agere.com - * - *------------------------------------------------------------------------------ - * - * et131x_netdev.h - Defines, structs, enums, prototypes, etc. related to the - * driver's net_device support. - * - *------------------------------------------------------------------------------ - * - * SOFTWARE LICENSE - * - * This software is provided subject to the following terms and conditions, - * which you should read carefully before using the software. Using this - * software indicates your acceptance of these terms and conditions. If you do - * not agree with these terms and conditions, do not use the software. - * - * Copyright © 2005 Agere Systems Inc. - * All rights reserved. - * - * Redistribution and use in source or binary forms, with or without - * modifications, are permitted provided that the following conditions are met: - * - * . Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following Disclaimer as comments in the code as - * well as in the documentation and/or other materials provided with the - * distribution. - * - * . Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following Disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * . Neither the name of Agere Systems Inc. nor the names of the contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * Disclaimer - * - * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY - * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN - * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - */ - -#ifndef __ET131X_NETDEV_H__ -#define __ET131X_NETDEV_H__ - -struct net_device *et131x_device_alloc(void); - -#endif /* __ET131X_NETDEV_H__ */ diff --git a/drivers/staging/et131x/et131x_version.h b/drivers/staging/et131x/et131x_version.h index 568f6c8..2aa9bda 100644 --- a/drivers/staging/et131x/et131x_version.h +++ b/drivers/staging/et131x/et131x_version.h @@ -62,20 +62,13 @@ #define DRIVER_LICENSE "Dual BSD/GPL" #define DRIVER_DEVICE_STRING "ET1310" #define DRIVER_NAME "et131x" -#define DRIVER_MAJOR_VERSION 1 -#define DRIVER_MINOR_VERSION 2 -#define DRIVER_PATCH_VERSION 3 -#define DRIVER_VERSION_STRING "1.2.3" +#define DRIVER_VERSION_STRING "1.2.3-lk" #define DRIVER_VENDOR "Agere Systems, http://www.agere.com" #define DRIVER_DESC "10/100/1000 Base-T Ethernet Driver" -#define STRUCT_MODULE "net" /* blux: missed by the kernel */ - #define DRIVER_INFO DRIVER_DESC " for the "\ DRIVER_DEVICE_STRING ", v" \ DRIVER_VERSION_STRING " by " \ DRIVER_VENDOR -#define DRIVER_NAME_EXT "et131x.ko" - #endif /* __ET131X_VERSION_H__ */ diff --git a/drivers/staging/frontier/alphatrack.c b/drivers/staging/frontier/alphatrack.c index 15aed87..a50a215 100644 --- a/drivers/staging/frontier/alphatrack.c +++ b/drivers/staging/frontier/alphatrack.c @@ -58,7 +58,7 @@ #endif /* table of devices that work with this driver */ -static struct usb_device_id usb_alphatrack_table[] = { +static const struct usb_device_id usb_alphatrack_table[] = { {USB_DEVICE(VENDOR_ID, PRODUCT_ID)}, {} /* Terminating entry */ }; diff --git a/drivers/staging/frontier/tranzport.c b/drivers/staging/frontier/tranzport.c index ef8fcc8..2f03f43 100644 --- a/drivers/staging/frontier/tranzport.c +++ b/drivers/staging/frontier/tranzport.c @@ -55,7 +55,7 @@ #endif /* table of devices that work with this driver */ -static struct usb_device_id usb_tranzport_table[] = { +static const struct usb_device_id usb_tranzport_table[] = { {USB_DEVICE(VENDOR_ID, PRODUCT_ID)}, {} /* Terminating entry */ }; diff --git a/drivers/staging/go7007/go7007-driver.c b/drivers/staging/go7007/go7007-driver.c index fb1345f..d42ba16 100644 --- a/drivers/staging/go7007/go7007-driver.c +++ b/drivers/staging/go7007/go7007-driver.c @@ -128,6 +128,8 @@ static int go7007_load_encoder(struct go7007 *go) return rv; } +MODULE_FIRMWARE("go7007fw.bin"); + /* * Boot the encoder and register the I2C adapter if requested. Do the * minimum initialization necessary, since the board-specific code may diff --git a/drivers/staging/go7007/go7007-usb.c b/drivers/staging/go7007/go7007-usb.c index 1e89dc0..ee278f6 100644 --- a/drivers/staging/go7007/go7007-usb.c +++ b/drivers/staging/go7007/go7007-usb.c @@ -444,7 +444,9 @@ static struct go7007_usb_board board_sensoray_2250 = { }, }; -static struct usb_device_id go7007_usb_id_table[] = { +MODULE_FIRMWARE("go7007tv.bin"); + +static const struct usb_device_id go7007_usb_id_table[] = { { .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION | USB_DEVICE_ID_MATCH_INT_INFO, diff --git a/drivers/staging/go7007/s2250-board.c b/drivers/staging/go7007/s2250-board.c index c324f6e..dc89502 100644 --- a/drivers/staging/go7007/s2250-board.c +++ b/drivers/staging/go7007/s2250-board.c @@ -667,7 +667,7 @@ static int s2250_remove(struct i2c_client *client) return 0; } -static struct i2c_device_id s2250_id[] = { +static const struct i2c_device_id s2250_id[] = { { "s2250", 0 }, { } }; diff --git a/drivers/staging/go7007/s2250-loader.c b/drivers/staging/go7007/s2250-loader.c index c152ab9..1de2dfb 100644 --- a/drivers/staging/go7007/s2250-loader.c +++ b/drivers/staging/go7007/s2250-loader.c @@ -139,7 +139,7 @@ failed2: static void s2250loader_disconnect(struct usb_interface *interface) { - pdevice_extension_t s = usb_get_intfdata(interface); + pdevice_extension_t s; printk(KERN_INFO "s2250: disconnect\n"); lock_kernel(); s = usb_get_intfdata(interface); @@ -148,7 +148,7 @@ static void s2250loader_disconnect(struct usb_interface *interface) unlock_kernel(); } -static struct usb_device_id s2250loader_ids[] = { +static const struct usb_device_id s2250loader_ids[] = { {USB_DEVICE(0x1943, 0xa250)}, {} /* Terminating entry */ }; diff --git a/drivers/staging/go7007/saa7134-go7007.c b/drivers/staging/go7007/saa7134-go7007.c index 665bbf5..b25d7d2 100644 --- a/drivers/staging/go7007/saa7134-go7007.c +++ b/drivers/staging/go7007/saa7134-go7007.c @@ -84,6 +84,7 @@ static struct go7007_board_info board_voyager = { }, }, }; +MODULE_FIRMWARE("go7007tv.bin"); /********************* Driver for GPIO HPI interface *********************/ diff --git a/drivers/staging/go7007/wis-ov7640.c b/drivers/staging/go7007/wis-ov7640.c index 04d6d3a..4f0cbdd 100644 --- a/drivers/staging/go7007/wis-ov7640.c +++ b/drivers/staging/go7007/wis-ov7640.c @@ -77,7 +77,7 @@ static int wis_ov7640_remove(struct i2c_client *client) return 0; } -static struct i2c_device_id wis_ov7640_id[] = { +static const struct i2c_device_id wis_ov7640_id[] = { { "wis_ov7640", 0 }, { } }; diff --git a/drivers/staging/go7007/wis-saa7113.c b/drivers/staging/go7007/wis-saa7113.c index 9ab893b..d196e16f 100644 --- a/drivers/staging/go7007/wis-saa7113.c +++ b/drivers/staging/go7007/wis-saa7113.c @@ -304,7 +304,7 @@ static int wis_saa7113_remove(struct i2c_client *client) return 0; } -static struct i2c_device_id wis_saa7113_id[] = { +static const struct i2c_device_id wis_saa7113_id[] = { { "wis_saa7113", 0 }, { } }; diff --git a/drivers/staging/go7007/wis-saa7115.c b/drivers/staging/go7007/wis-saa7115.c index 8687ad2..0f2b4a0 100644 --- a/drivers/staging/go7007/wis-saa7115.c +++ b/drivers/staging/go7007/wis-saa7115.c @@ -437,7 +437,7 @@ static int wis_saa7115_remove(struct i2c_client *client) return 0; } -static struct i2c_device_id wis_saa7115_id[] = { +static const struct i2c_device_id wis_saa7115_id[] = { { "wis_saa7115", 0 }, { } }; diff --git a/drivers/staging/go7007/wis-sony-tuner.c b/drivers/staging/go7007/wis-sony-tuner.c index 086896c..c723e4a 100644 --- a/drivers/staging/go7007/wis-sony-tuner.c +++ b/drivers/staging/go7007/wis-sony-tuner.c @@ -688,7 +688,7 @@ static int wis_sony_tuner_remove(struct i2c_client *client) return 0; } -static struct i2c_device_id wis_sony_tuner_id[] = { +static const struct i2c_device_id wis_sony_tuner_id[] = { { "wis_sony_tuner", 0 }, { } }; diff --git a/drivers/staging/go7007/wis-tw2804.c b/drivers/staging/go7007/wis-tw2804.c index e15794a..1983839 100644 --- a/drivers/staging/go7007/wis-tw2804.c +++ b/drivers/staging/go7007/wis-tw2804.c @@ -327,7 +327,7 @@ static int wis_tw2804_remove(struct i2c_client *client) return 0; } -static struct i2c_device_id wis_tw2804_id[] = { +static const struct i2c_device_id wis_tw2804_id[] = { { "wis_tw2804", 0 }, { } }; diff --git a/drivers/staging/go7007/wis-tw9903.c b/drivers/staging/go7007/wis-tw9903.c index 506dca6..f97e2be 100644 --- a/drivers/staging/go7007/wis-tw9903.c +++ b/drivers/staging/go7007/wis-tw9903.c @@ -309,7 +309,7 @@ static int wis_tw9903_remove(struct i2c_client *client) return 0; } -static struct i2c_device_id wis_tw9903_id[] = { +static const struct i2c_device_id wis_tw9903_id[] = { { "wis_tw9903", 0 }, { } }; diff --git a/drivers/staging/go7007/wis-uda1342.c b/drivers/staging/go7007/wis-uda1342.c index 739c7ae..5c4eb49 100644 --- a/drivers/staging/go7007/wis-uda1342.c +++ b/drivers/staging/go7007/wis-uda1342.c @@ -82,7 +82,7 @@ static int wis_uda1342_remove(struct i2c_client *client) return 0; } -static struct i2c_device_id wis_uda1342_id[] = { +static const struct i2c_device_id wis_uda1342_id[] = { { "wis_uda1342", 0 }, { } }; diff --git a/drivers/staging/hv/Channel.c b/drivers/staging/hv/Channel.c index 746370e..d46eb14 100644 --- a/drivers/staging/hv/Channel.c +++ b/drivers/staging/hv/Channel.c @@ -991,9 +991,8 @@ void VmbusChannelOnTimer(unsigned long data) { struct vmbus_channel *channel = (struct vmbus_channel *)data; - if (channel->OnChannelCallback) { + if (channel->OnChannelCallback) channel->OnChannelCallback(channel->ChannelCallbackContext); - } } /** diff --git a/drivers/staging/hv/Hv.c b/drivers/staging/hv/Hv.c index c2809f2..51149e6 100644 --- a/drivers/staging/hv/Hv.c +++ b/drivers/staging/hv/Hv.c @@ -208,50 +208,51 @@ int HvInit(void) /* HvQueryHypervisorFeatures(maxLeaf); */ /* - * Determine if we are running on xenlinux (ie x2v shim) or native - * linux + * We only support running on top of Hyper-V */ rdmsrl(HV_X64_MSR_GUEST_OS_ID, gHvContext.GuestId); - if (gHvContext.GuestId == 0) { - /* Write our OS info */ - wrmsrl(HV_X64_MSR_GUEST_OS_ID, HV_LINUX_GUEST_ID); - gHvContext.GuestId = HV_LINUX_GUEST_ID; + + if (gHvContext.GuestId != 0) { + DPRINT_ERR(VMBUS, "Unknown guest id (0x%llx)!!", + gHvContext.GuestId); + goto Cleanup; } + /* Write our OS info */ + wrmsrl(HV_X64_MSR_GUEST_OS_ID, HV_LINUX_GUEST_ID); + gHvContext.GuestId = HV_LINUX_GUEST_ID; + /* See if the hypercall page is already set */ rdmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64); - if (gHvContext.GuestId == HV_LINUX_GUEST_ID) { - /* Allocate the hypercall page memory */ - /* virtAddr = osd_PageAlloc(1); */ - virtAddr = osd_VirtualAllocExec(PAGE_SIZE); - - if (!virtAddr) { - DPRINT_ERR(VMBUS, - "unable to allocate hypercall page!!"); - goto Cleanup; - } - hypercallMsr.Enable = 1; - /* hypercallMsr.GuestPhysicalAddress = - * virt_to_phys(virtAddr) >> PAGE_SHIFT; */ - hypercallMsr.GuestPhysicalAddress = vmalloc_to_pfn(virtAddr); - wrmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64); + /* + * Allocate the hypercall page memory + * virtAddr = osd_PageAlloc(1); + */ + virtAddr = osd_VirtualAllocExec(PAGE_SIZE); - /* Confirm that hypercall page did get setup. */ - hypercallMsr.AsUINT64 = 0; - rdmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64); - if (!hypercallMsr.Enable) { - DPRINT_ERR(VMBUS, "unable to set hypercall page!!"); - goto Cleanup; - } + if (!virtAddr) { + DPRINT_ERR(VMBUS, + "unable to allocate hypercall page!!"); + goto Cleanup; + } - gHvContext.HypercallPage = virtAddr; - } else { - DPRINT_ERR(VMBUS, "Unknown guest id (0x%llx)!!", - gHvContext.GuestId); + hypercallMsr.Enable = 1; + + hypercallMsr.GuestPhysicalAddress = vmalloc_to_pfn(virtAddr); + wrmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64); + + /* Confirm that hypercall page did get setup. */ + hypercallMsr.AsUINT64 = 0; + rdmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64); + + if (!hypercallMsr.Enable) { + DPRINT_ERR(VMBUS, "unable to set hypercall page!!"); goto Cleanup; } + gHvContext.HypercallPage = virtAddr; + DPRINT_INFO(VMBUS, "Hypercall page VA=%p, PA=0x%0llx", gHvContext.HypercallPage, (u64)hypercallMsr.GuestPhysicalAddress << PAGE_SHIFT); @@ -273,8 +274,6 @@ int HvInit(void) gHvContext.SignalEventParam->FlagNumber = 0; gHvContext.SignalEventParam->RsvdZ = 0; - /* DPRINT_DBG(VMBUS, "My id %llu", HvGetCurrentPartitionId()); */ - DPRINT_EXIT(VMBUS); return ret; @@ -311,17 +310,14 @@ void HvCleanup(void) kfree(gHvContext.SignalEventBuffer); } - if (gHvContext.GuestId == HV_LINUX_GUEST_ID) { - if (gHvContext.HypercallPage) { - hypercallMsr.AsUINT64 = 0; - wrmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64); - vfree(gHvContext.HypercallPage); - gHvContext.HypercallPage = NULL; - } + if (gHvContext.HypercallPage) { + hypercallMsr.AsUINT64 = 0; + wrmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64); + vfree(gHvContext.HypercallPage); + gHvContext.HypercallPage = NULL; } DPRINT_EXIT(VMBUS); - } /** @@ -393,7 +389,7 @@ void HvSynicInit(void *irqarg) union hv_synic_siefp siefp; union hv_synic_sint sharedSint; union hv_synic_scontrol sctrl; - u64 guestID; + u32 irqVector = *((u32 *)(irqarg)); int cpu = smp_processor_id(); @@ -409,71 +405,41 @@ void HvSynicInit(void *irqarg) DPRINT_INFO(VMBUS, "SynIC version: %llx", version); - /* TODO: Handle SMP */ - if (gHvContext.GuestId == HV_XENLINUX_GUEST_ID) { - DPRINT_INFO(VMBUS, "Skipping SIMP and SIEFP setup since " - "it is already set."); - - rdmsrl(HV_X64_MSR_SIMP, simp.AsUINT64); - rdmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64); - - DPRINT_DBG(VMBUS, "Simp: %llx, Sifep: %llx", - simp.AsUINT64, siefp.AsUINT64); - - /* - * Determine if we are running on xenlinux (ie x2v shim) or - * native linux - */ - rdmsrl(HV_X64_MSR_GUEST_OS_ID, guestID); - if (guestID == HV_LINUX_GUEST_ID) { - gHvContext.synICMessagePage[cpu] = - phys_to_virt(simp.BaseSimpGpa << PAGE_SHIFT); - gHvContext.synICEventPage[cpu] = - phys_to_virt(siefp.BaseSiefpGpa << PAGE_SHIFT); - } else { - DPRINT_ERR(VMBUS, "unknown guest id!!"); - goto Cleanup; - } - DPRINT_DBG(VMBUS, "MAPPED: Simp: %p, Sifep: %p", - gHvContext.synICMessagePage[cpu], - gHvContext.synICEventPage[cpu]); - } else { - gHvContext.synICMessagePage[cpu] = (void *)get_zeroed_page(GFP_ATOMIC); - if (gHvContext.synICMessagePage[cpu] == NULL) { - DPRINT_ERR(VMBUS, - "unable to allocate SYNIC message page!!"); - goto Cleanup; - } + gHvContext.synICMessagePage[cpu] = (void *)get_zeroed_page(GFP_ATOMIC); - gHvContext.synICEventPage[cpu] = (void *)get_zeroed_page(GFP_ATOMIC); - if (gHvContext.synICEventPage[cpu] == NULL) { - DPRINT_ERR(VMBUS, - "unable to allocate SYNIC event page!!"); - goto Cleanup; - } + if (gHvContext.synICMessagePage[cpu] == NULL) { + DPRINT_ERR(VMBUS, + "unable to allocate SYNIC message page!!"); + goto Cleanup; + } - /* Setup the Synic's message page */ - rdmsrl(HV_X64_MSR_SIMP, simp.AsUINT64); - simp.SimpEnabled = 1; - simp.BaseSimpGpa = virt_to_phys(gHvContext.synICMessagePage[cpu]) - >> PAGE_SHIFT; + gHvContext.synICEventPage[cpu] = (void *)get_zeroed_page(GFP_ATOMIC); - DPRINT_DBG(VMBUS, "HV_X64_MSR_SIMP msr set to: %llx", - simp.AsUINT64); + if (gHvContext.synICEventPage[cpu] == NULL) { + DPRINT_ERR(VMBUS, + "unable to allocate SYNIC event page!!"); + goto Cleanup; + } - wrmsrl(HV_X64_MSR_SIMP, simp.AsUINT64); + /* Setup the Synic's message page */ + rdmsrl(HV_X64_MSR_SIMP, simp.AsUINT64); + simp.SimpEnabled = 1; + simp.BaseSimpGpa = virt_to_phys(gHvContext.synICMessagePage[cpu]) + >> PAGE_SHIFT; - /* Setup the Synic's event page */ - rdmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64); - siefp.SiefpEnabled = 1; - siefp.BaseSiefpGpa = virt_to_phys(gHvContext.synICEventPage[cpu]) - >> PAGE_SHIFT; + DPRINT_DBG(VMBUS, "HV_X64_MSR_SIMP msr set to: %llx", simp.AsUINT64); - DPRINT_DBG(VMBUS, "HV_X64_MSR_SIEFP msr set to: %llx", - siefp.AsUINT64); + wrmsrl(HV_X64_MSR_SIMP, simp.AsUINT64); - wrmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64); - } + /* Setup the Synic's event page */ + rdmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64); + siefp.SiefpEnabled = 1; + siefp.BaseSiefpGpa = virt_to_phys(gHvContext.synICEventPage[cpu]) + >> PAGE_SHIFT; + + DPRINT_DBG(VMBUS, "HV_X64_MSR_SIEFP msr set to: %llx", siefp.AsUINT64); + + wrmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64); /* Setup the interception SINT. */ /* wrmsrl((HV_X64_MSR_SINT0 + HV_SYNIC_INTERCEPTION_SINT_INDEX), */ @@ -505,13 +471,11 @@ void HvSynicInit(void *irqarg) return; Cleanup: - if (gHvContext.GuestId == HV_LINUX_GUEST_ID) { - if (gHvContext.synICEventPage[cpu]) - osd_PageFree(gHvContext.synICEventPage[cpu], 1); + if (gHvContext.synICEventPage[cpu]) + osd_PageFree(gHvContext.synICEventPage[cpu], 1); - if (gHvContext.synICMessagePage[cpu]) - osd_PageFree(gHvContext.synICMessagePage[cpu], 1); - } + if (gHvContext.synICMessagePage[cpu]) + osd_PageFree(gHvContext.synICMessagePage[cpu], 1); DPRINT_EXIT(VMBUS); return; @@ -542,27 +506,20 @@ void HvSynicCleanup(void *arg) /* Disable the interrupt */ wrmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, sharedSint.AsUINT64); - /* - * Disable and free the resources only if we are running as - * native linux since in xenlinux, we are sharing the - * resources with the x2v shim - */ - if (gHvContext.GuestId == HV_LINUX_GUEST_ID) { - rdmsrl(HV_X64_MSR_SIMP, simp.AsUINT64); - simp.SimpEnabled = 0; - simp.BaseSimpGpa = 0; + rdmsrl(HV_X64_MSR_SIMP, simp.AsUINT64); + simp.SimpEnabled = 0; + simp.BaseSimpGpa = 0; - wrmsrl(HV_X64_MSR_SIMP, simp.AsUINT64); + wrmsrl(HV_X64_MSR_SIMP, simp.AsUINT64); - rdmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64); - siefp.SiefpEnabled = 0; - siefp.BaseSiefpGpa = 0; + rdmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64); + siefp.SiefpEnabled = 0; + siefp.BaseSiefpGpa = 0; - wrmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64); + wrmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64); - osd_PageFree(gHvContext.synICMessagePage[cpu], 1); - osd_PageFree(gHvContext.synICEventPage[cpu], 1); - } + osd_PageFree(gHvContext.synICMessagePage[cpu], 1); + osd_PageFree(gHvContext.synICEventPage[cpu], 1); DPRINT_EXIT(VMBUS); } diff --git a/drivers/staging/hv/Hv.h b/drivers/staging/hv/Hv.h index fce4b5c..41f5ebb 100644 --- a/drivers/staging/hv/Hv.h +++ b/drivers/staging/hv/Hv.h @@ -41,11 +41,6 @@ enum { #define HV_PRESENT_BIT 0x80000000 -#define HV_XENLINUX_GUEST_ID_LO 0x00000000 -#define HV_XENLINUX_GUEST_ID_HI 0x0B00B135 -#define HV_XENLINUX_GUEST_ID (((u64)HV_XENLINUX_GUEST_ID_HI << 32) \ - | HV_XENLINUX_GUEST_ID_LO) - #define HV_LINUX_GUEST_ID_LO 0x00000000 #define HV_LINUX_GUEST_ID_HI 0xB16B00B5 #define HV_LINUX_GUEST_ID (((u64)HV_LINUX_GUEST_ID_HI << 32) | \ @@ -102,8 +97,9 @@ struct hv_input_signal_event_buffer { }; struct hv_context { - /* XenLinux or native Linux. If XenLinux, the hypercall and synic pages - * has already been initialized */ + /* We only support running on top of Hyper-V + * So at this point this really can only contain the Hyper-V ID + */ u64 GuestId; void *HypercallPage; diff --git a/drivers/staging/hv/NetVscApi.h b/drivers/staging/hv/NetVscApi.h index 1ce2b74..95d7a32 100644 --- a/drivers/staging/hv/NetVscApi.h +++ b/drivers/staging/hv/NetVscApi.h @@ -105,8 +105,6 @@ struct netvsc_driver { void (*OnLinkStatusChanged)(struct hv_device *dev, u32 Status); /* Specific to this driver */ - int (*OnOpen)(struct hv_device *dev); - int (*OnClose)(struct hv_device *dev); int (*OnSend)(struct hv_device *dev, struct hv_netvsc_packet *packet); void *Context; @@ -119,5 +117,7 @@ struct netvsc_device_info { /* Interface */ int NetVscInitialize(struct hv_driver *drv); +int RndisFilterOnOpen(struct hv_device *Device); +int RndisFilterOnClose(struct hv_device *Device); #endif /* _NETVSC_API_H_ */ diff --git a/drivers/staging/hv/RingBuffer.c b/drivers/staging/hv/RingBuffer.c index f69ae33..80b8a2c 100644 --- a/drivers/staging/hv/RingBuffer.c +++ b/drivers/staging/hv/RingBuffer.c @@ -48,7 +48,7 @@ Description: static inline void GetRingBufferAvailBytes(RING_BUFFER_INFO *rbi, u32 *read, u32 *write) { - u32 read_loc,write_loc; + u32 read_loc, write_loc; /* Capture the read/write indices before they changed */ read_loc = rbi->RingBuffer->ReadIndex; @@ -68,7 +68,7 @@ Description: --*/ static inline u32 -GetNextWriteLocation(RING_BUFFER_INFO* RingInfo) +GetNextWriteLocation(RING_BUFFER_INFO *RingInfo) { u32 next = RingInfo->RingBuffer->WriteIndex; @@ -87,7 +87,7 @@ Description: --*/ static inline void -SetNextWriteLocation(RING_BUFFER_INFO* RingInfo, u32 NextWriteLocation) +SetNextWriteLocation(RING_BUFFER_INFO *RingInfo, u32 NextWriteLocation) { RingInfo->RingBuffer->WriteIndex = NextWriteLocation; } @@ -102,7 +102,7 @@ Description: --*/ static inline u32 -GetNextReadLocation(RING_BUFFER_INFO* RingInfo) +GetNextReadLocation(RING_BUFFER_INFO *RingInfo) { u32 next = RingInfo->RingBuffer->ReadIndex; @@ -122,7 +122,7 @@ Description: --*/ static inline u32 -GetNextReadLocationWithOffset(RING_BUFFER_INFO* RingInfo, u32 Offset) +GetNextReadLocationWithOffset(RING_BUFFER_INFO *RingInfo, u32 Offset) { u32 next = RingInfo->RingBuffer->ReadIndex; @@ -143,7 +143,7 @@ Description: --*/ static inline void -SetNextReadLocation(RING_BUFFER_INFO* RingInfo, u32 NextReadLocation) +SetNextReadLocation(RING_BUFFER_INFO *RingInfo, u32 NextReadLocation) { RingInfo->RingBuffer->ReadIndex = NextReadLocation; } @@ -159,7 +159,7 @@ Description: --*/ static inline void * -GetRingBuffer(RING_BUFFER_INFO* RingInfo) +GetRingBuffer(RING_BUFFER_INFO *RingInfo) { return (void *)RingInfo->RingBuffer->Buffer; } @@ -175,7 +175,7 @@ Description: --*/ static inline u32 -GetRingBufferSize(RING_BUFFER_INFO* RingInfo) +GetRingBufferSize(RING_BUFFER_INFO *RingInfo) { return RingInfo->RingDataSize; } @@ -190,9 +190,10 @@ Description: --*/ static inline u64 -GetRingBufferIndices(RING_BUFFER_INFO* RingInfo) +GetRingBufferIndices(RING_BUFFER_INFO *RingInfo) { - return ((u64)RingInfo->RingBuffer->WriteIndex << 32) || RingInfo->RingBuffer->ReadIndex; + return ((u64)RingInfo->RingBuffer->WriteIndex << 32) + || RingInfo->RingBuffer->ReadIndex; } @@ -210,9 +211,14 @@ void DumpRingInfo(RING_BUFFER_INFO *RingInfo, char *Prefix) u32 bytesAvailToWrite; u32 bytesAvailToRead; - GetRingBufferAvailBytes(RingInfo, &bytesAvailToRead, &bytesAvailToWrite); + GetRingBufferAvailBytes(RingInfo, + &bytesAvailToRead, + &bytesAvailToWrite); - DPRINT(VMBUS, DEBUG_RING_LVL, "%s <<ringinfo %p buffer %p avail write %u avail read %u read idx %u write idx %u>>", + DPRINT(VMBUS, + DEBUG_RING_LVL, + "%s <<ringinfo %p buffer %p avail write %u " + "avail read %u read idx %u write idx %u>>", Prefix, RingInfo, RingInfo->RingBuffer->Buffer, @@ -229,13 +235,13 @@ static u32 CopyToRingBuffer( RING_BUFFER_INFO *RingInfo, u32 StartWriteOffset, - void * Src, + void *Src, u32 SrcLen); static u32 CopyFromRingBuffer( RING_BUFFER_INFO *RingInfo, - void * Dest, + void *Dest, u32 DestLen, u32 StartReadOffset); @@ -256,15 +262,15 @@ void RingBufferGetDebugInfo(RING_BUFFER_INFO *RingInfo, u32 bytesAvailToWrite; u32 bytesAvailToRead; - if (RingInfo->RingBuffer) - { - GetRingBufferAvailBytes(RingInfo, &bytesAvailToRead, &bytesAvailToWrite); + if (RingInfo->RingBuffer) { + GetRingBufferAvailBytes(RingInfo, + &bytesAvailToRead, + &bytesAvailToWrite); DebugInfo->BytesAvailToRead = bytesAvailToRead; DebugInfo->BytesAvailToWrite = bytesAvailToWrite; DebugInfo->CurrentReadIndex = RingInfo->RingBuffer->ReadIndex; DebugInfo->CurrentWriteIndex = RingInfo->RingBuffer->WriteIndex; - DebugInfo->CurrentInterruptMask = RingInfo->RingBuffer->InterruptMask; } } @@ -299,7 +305,7 @@ int RingBufferInit(RING_BUFFER_INFO *RingInfo, void *Buffer, u32 BufferLen) memset(RingInfo, 0, sizeof(RING_BUFFER_INFO)); - RingInfo->RingBuffer = (RING_BUFFER*)Buffer; + RingInfo->RingBuffer = (RING_BUFFER *)Buffer; RingInfo->RingBuffer->ReadIndex = RingInfo->RingBuffer->WriteIndex = 0; RingInfo->RingSize = BufferLen; @@ -319,7 +325,7 @@ Description: Cleanup the ring buffer --*/ -void RingBufferCleanup(RING_BUFFER_INFO* RingInfo) +void RingBufferCleanup(RING_BUFFER_INFO *RingInfo) { } @@ -335,14 +341,14 @@ Description: int RingBufferWrite(RING_BUFFER_INFO *OutRingInfo, struct scatterlist *sglist, u32 sgcount) { - int i=0; + int i = 0; u32 byteAvailToWrite; u32 byteAvailToRead; - u32 totalBytesToWrite=0; + u32 totalBytesToWrite = 0; struct scatterlist *sg; volatile u32 nextWriteLocation; - u64 prevIndices=0; + u64 prevIndices = 0; unsigned long flags; DPRINT_ENTER(VMBUS); @@ -356,17 +362,23 @@ int RingBufferWrite(RING_BUFFER_INFO *OutRingInfo, spin_lock_irqsave(&OutRingInfo->ring_lock, flags); - GetRingBufferAvailBytes(OutRingInfo, &byteAvailToRead, &byteAvailToWrite); + GetRingBufferAvailBytes(OutRingInfo, + &byteAvailToRead, + &byteAvailToWrite); DPRINT_DBG(VMBUS, "Writing %u bytes...", totalBytesToWrite); /* DumpRingInfo(OutRingInfo, "BEFORE "); */ - /* If there is only room for the packet, assume it is full. Otherwise, the next time around, we think the ring buffer */ + /* If there is only room for the packet, assume it is full. */ + /* Otherwise, the next time around, we think the ring buffer */ /* is empty since the read index == write index */ - if (byteAvailToWrite <= totalBytesToWrite) - { - DPRINT_DBG(VMBUS, "No more space left on outbound ring buffer (needed %u, avail %u)", totalBytesToWrite, byteAvailToWrite); + if (byteAvailToWrite <= totalBytesToWrite) { + DPRINT_DBG(VMBUS, + "No more space left on outbound ring buffer " + "(needed %u, avail %u)", + totalBytesToWrite, + byteAvailToWrite); spin_unlock_irqrestore(&OutRingInfo->ring_lock, flags); @@ -423,17 +435,22 @@ int RingBufferPeek(RING_BUFFER_INFO *InRingInfo, void *Buffer, u32 BufferLen) { u32 bytesAvailToWrite; u32 bytesAvailToRead; - u32 nextReadLocation=0; + u32 nextReadLocation = 0; unsigned long flags; spin_lock_irqsave(&InRingInfo->ring_lock, flags); - GetRingBufferAvailBytes(InRingInfo, &bytesAvailToRead, &bytesAvailToWrite); + GetRingBufferAvailBytes(InRingInfo, + &bytesAvailToRead, + &bytesAvailToWrite); /* Make sure there is something to read */ - if (bytesAvailToRead < BufferLen ) - { - /* DPRINT_DBG(VMBUS, "got callback but not enough to read <avail to read %d read size %d>!!", bytesAvailToRead, BufferLen); */ + if (bytesAvailToRead < BufferLen) { + /* DPRINT_DBG(VMBUS, + "got callback but not enough to read " + "<avail to read %d read size %d>!!", + bytesAvailToRead, + BufferLen); */ spin_unlock_irqrestore(&InRingInfo->ring_lock, flags); @@ -444,9 +461,9 @@ int RingBufferPeek(RING_BUFFER_INFO *InRingInfo, void *Buffer, u32 BufferLen) nextReadLocation = GetNextReadLocation(InRingInfo); nextReadLocation = CopyFromRingBuffer(InRingInfo, - Buffer, - BufferLen, - nextReadLocation); + Buffer, + BufferLen, + nextReadLocation); spin_unlock_irqrestore(&InRingInfo->ring_lock, flags); @@ -468,24 +485,29 @@ int RingBufferRead(RING_BUFFER_INFO *InRingInfo, void *Buffer, { u32 bytesAvailToWrite; u32 bytesAvailToRead; - u32 nextReadLocation=0; - u64 prevIndices=0; + u32 nextReadLocation = 0; + u64 prevIndices = 0; unsigned long flags; ASSERT(BufferLen > 0); spin_lock_irqsave(&InRingInfo->ring_lock, flags); - GetRingBufferAvailBytes(InRingInfo, &bytesAvailToRead, &bytesAvailToWrite); + GetRingBufferAvailBytes(InRingInfo, + &bytesAvailToRead, + &bytesAvailToWrite); DPRINT_DBG(VMBUS, "Reading %u bytes...", BufferLen); /* DumpRingInfo(InRingInfo, "BEFORE "); */ /* Make sure there is something to read */ - if (bytesAvailToRead < BufferLen ) - { - DPRINT_DBG(VMBUS, "got callback but not enough to read <avail to read %d read size %d>!!", bytesAvailToRead, BufferLen); + if (bytesAvailToRead < BufferLen) { + DPRINT_DBG(VMBUS, + "got callback but not enough to read " + "<avail to read %d read size %d>!!", + bytesAvailToRead, + BufferLen); spin_unlock_irqrestore(&InRingInfo->ring_lock, flags); @@ -495,17 +517,18 @@ int RingBufferRead(RING_BUFFER_INFO *InRingInfo, void *Buffer, nextReadLocation = GetNextReadLocationWithOffset(InRingInfo, Offset); nextReadLocation = CopyFromRingBuffer(InRingInfo, - Buffer, - BufferLen, - nextReadLocation); + Buffer, + BufferLen, + nextReadLocation); nextReadLocation = CopyFromRingBuffer(InRingInfo, - &prevIndices, - sizeof(u64), - nextReadLocation); + &prevIndices, + sizeof(u64), + nextReadLocation); /* Make sure all reads are done before we update the read index since */ - /* the writer may start writing to the read area once the read index is updated */ + /* the writer may start writing to the read area once the read index */ + /*is updated */ mb(); /* Update the read index */ @@ -533,25 +556,22 @@ static u32 CopyToRingBuffer( RING_BUFFER_INFO *RingInfo, u32 StartWriteOffset, - void * Src, + void *Src, u32 SrcLen) { - void * ringBuffer=GetRingBuffer(RingInfo); - u32 ringBufferSize=GetRingBufferSize(RingInfo); + void *ringBuffer = GetRingBuffer(RingInfo); + u32 ringBufferSize = GetRingBufferSize(RingInfo); u32 fragLen; - if (SrcLen > ringBufferSize - StartWriteOffset) /* wrap-around detected! */ - { + /* wrap-around detected! */ + if (SrcLen > ringBufferSize - StartWriteOffset) { DPRINT_DBG(VMBUS, "wrap-around detected!"); fragLen = ringBufferSize - StartWriteOffset; memcpy(ringBuffer + StartWriteOffset, Src, fragLen); memcpy(ringBuffer, Src + fragLen, SrcLen - fragLen); - } - else - { + } else memcpy(ringBuffer + StartWriteOffset, Src, SrcLen); - } StartWriteOffset += SrcLen; StartWriteOffset %= ringBufferSize; @@ -573,28 +593,27 @@ Description: static u32 CopyFromRingBuffer( RING_BUFFER_INFO *RingInfo, - void * Dest, + void *Dest, u32 DestLen, u32 StartReadOffset) { - void * ringBuffer=GetRingBuffer(RingInfo); - u32 ringBufferSize=GetRingBufferSize(RingInfo); + void *ringBuffer = GetRingBuffer(RingInfo); + u32 ringBufferSize = GetRingBufferSize(RingInfo); u32 fragLen; - if (DestLen > ringBufferSize - StartReadOffset) /* wrap-around detected at the src */ - { + /* wrap-around detected at the src */ + if (DestLen > ringBufferSize - StartReadOffset) { DPRINT_DBG(VMBUS, "src wrap-around detected!"); fragLen = ringBufferSize - StartReadOffset; memcpy(Dest, ringBuffer + StartReadOffset, fragLen); memcpy(Dest + fragLen, ringBuffer, DestLen - fragLen); - } - else - { + } else + memcpy(Dest, ringBuffer + StartReadOffset, DestLen); - } + StartReadOffset += DestLen; StartReadOffset %= ringBufferSize; diff --git a/drivers/staging/hv/RndisFilter.c b/drivers/staging/hv/RndisFilter.c index 26d7997..1ab7fa9 100644 --- a/drivers/staging/hv/RndisFilter.c +++ b/drivers/staging/hv/RndisFilter.c @@ -85,10 +85,6 @@ static int RndisFilterOnDeviceRemove(struct hv_device *Device); static void RndisFilterOnCleanup(struct hv_driver *Driver); -static int RndisFilterOnOpen(struct hv_device *Device); - -static int RndisFilterOnClose(struct hv_device *Device); - static int RndisFilterOnSend(struct hv_device *Device, struct hv_netvsc_packet *Packet); @@ -654,8 +650,6 @@ int RndisFilterInit(struct netvsc_driver *Driver) Driver->Base.OnDeviceRemove = RndisFilterOnDeviceRemove; Driver->Base.OnCleanup = RndisFilterOnCleanup; Driver->OnSend = RndisFilterOnSend; - Driver->OnOpen = RndisFilterOnOpen; - Driver->OnClose = RndisFilterOnClose; /* Driver->QueryLinkStatus = RndisFilterQueryDeviceLinkStatus; */ Driver->OnReceiveCallback = RndisFilterOnReceive; @@ -888,7 +882,7 @@ static void RndisFilterOnCleanup(struct hv_driver *Driver) DPRINT_EXIT(NETVSC); } -static int RndisFilterOnOpen(struct hv_device *Device) +int RndisFilterOnOpen(struct hv_device *Device) { int ret; struct netvsc_device *netDevice = Device->Extension; @@ -903,7 +897,7 @@ static int RndisFilterOnOpen(struct hv_device *Device) return ret; } -static int RndisFilterOnClose(struct hv_device *Device) +int RndisFilterOnClose(struct hv_device *Device) { int ret; struct netvsc_device *netDevice = Device->Extension; diff --git a/drivers/staging/hv/StorVsc.c b/drivers/staging/hv/StorVsc.c index 2f7c425..38ea140 100644 --- a/drivers/staging/hv/StorVsc.c +++ b/drivers/staging/hv/StorVsc.c @@ -625,7 +625,7 @@ static int StorVscOnDeviceRemove(struct hv_device *Device) return 0; } -static int StorVscOnHostReset(struct hv_device *Device) +int StorVscOnHostReset(struct hv_device *Device) { struct storvsc_device *storDevice; struct storvsc_request_extension *request; @@ -842,7 +842,6 @@ int StorVscInitialize(struct hv_driver *Driver) storDriver->Base.OnCleanup = StorVscOnCleanup; storDriver->OnIORequest = StorVscOnIORequest; - storDriver->OnHostReset = StorVscOnHostReset; DPRINT_EXIT(STORVSC); diff --git a/drivers/staging/hv/StorVscApi.h b/drivers/staging/hv/StorVscApi.h index 69c1406..126a858 100644 --- a/drivers/staging/hv/StorVscApi.h +++ b/drivers/staging/hv/StorVscApi.h @@ -91,13 +91,9 @@ struct storvsc_driver_object { /* Maximum # of requests in flight per channel/device */ u32 MaxOutstandingRequestsPerChannel; - /* Set by the caller to allow us to re-enumerate the bus on the host */ - void (*OnHostRescan)(struct hv_device *Device); - /* Specific to this driver */ int (*OnIORequest)(struct hv_device *Device, struct hv_storvsc_request *Request); - int (*OnHostReset)(struct hv_device *Device); }; struct storvsc_device_info { @@ -108,6 +104,7 @@ struct storvsc_device_info { /* Interface */ int StorVscInitialize(struct hv_driver *driver); +int StorVscOnHostReset(struct hv_device *Device); int BlkVscInitialize(struct hv_driver *driver); #endif /* _STORVSC_API_H_ */ diff --git a/drivers/staging/hv/VersionInfo.h b/drivers/staging/hv/VersionInfo.h index 9c3641d..10d7b19 100644 --- a/drivers/staging/hv/VersionInfo.h +++ b/drivers/staging/hv/VersionInfo.h @@ -24,8 +24,24 @@ #ifndef __HV_VERSION_INFO #define __HV_VERSION_INFO -static const char VersionDate[] = __DATE__; -static const char VersionTime[] = __TIME__; -static const char VersionDesc[] = "Version 2.0"; +/* + * We use the same version numbering for all Hyper-V modules. + * + * Definition of versioning is as follows; + * + * Major Number Changes for these scenarios; + * 1. When a new version of Windows Hyper-V + * is released. + * 2. A Major change has occurred in the + * Linux IC's. + * (For example the merge for the first time + * into the kernel) Every time the Major Number + * changes, the Revision number is reset to 0. + * Minor Number Changes when new functionality is added + * to the Linux IC's that is not a bug fix. + * + */ +#define HV_DRV_VERSION "3.0" + #endif diff --git a/drivers/staging/hv/Vmbus.c b/drivers/staging/hv/Vmbus.c index 35a023e..3d0a240 100644 --- a/drivers/staging/hv/Vmbus.c +++ b/drivers/staging/hv/Vmbus.c @@ -273,10 +273,8 @@ int VmbusInitialize(struct hv_driver *drv) DPRINT_ENTER(VMBUS); - DPRINT_INFO(VMBUS, "+++++++ Build Date=%s %s +++++++", - VersionDate, VersionTime); - DPRINT_INFO(VMBUS, "+++++++ Build Description=%s +++++++", - VersionDesc); + DPRINT_INFO(VMBUS, "+++++++ HV Driver version = %s +++++++", + HV_DRV_VERSION); DPRINT_INFO(VMBUS, "+++++++ Vmbus supported version = %d +++++++", VMBUS_REVISION_NUMBER); DPRINT_INFO(VMBUS, "+++++++ Vmbus using SINT %d +++++++", diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index 45d9081..abeac12 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -31,6 +31,7 @@ #include <scsi/scsi_dbg.h> #include "osd.h" #include "logging.h" +#include "VersionInfo.h" #include "vmbus.h" #include "StorVscApi.h" @@ -92,7 +93,7 @@ struct blkvsc_request { /* Per device structure */ struct block_device_context { /* point back to our device context */ - struct device_context *device_ctx; + struct vm_device *device_ctx; struct kmem_cache *request_pool; spinlock_t lock; struct gendisk *gd; @@ -254,7 +255,7 @@ static int blkvsc_probe(struct device *device) (struct blkvsc_driver_context *)driver_ctx; struct storvsc_driver_object *storvsc_drv_obj = &blkvsc_drv_ctx->drv_obj; - struct device_context *device_ctx = device_to_device_context(device); + struct vm_device *device_ctx = device_to_vm_device(device); struct hv_device *device_obj = &device_ctx->device_obj; struct block_device_context *blkdev = NULL; @@ -742,7 +743,7 @@ static int blkvsc_remove(struct device *device) (struct blkvsc_driver_context *)driver_ctx; struct storvsc_driver_object *storvsc_drv_obj = &blkvsc_drv_ctx->drv_obj; - struct device_context *device_ctx = device_to_device_context(device); + struct vm_device *device_ctx = device_to_vm_device(device); struct hv_device *device_obj = &device_ctx->device_obj; struct block_device_context *blkdev = dev_get_drvdata(device); unsigned long flags; @@ -862,7 +863,7 @@ static int blkvsc_submit_request(struct blkvsc_request *blkvsc_req, void (*request_completion)(struct hv_storvsc_request *)) { struct block_device_context *blkdev = blkvsc_req->dev; - struct device_context *device_ctx = blkdev->device_ctx; + struct vm_device *device_ctx = blkdev->device_ctx; struct driver_context *driver_ctx = driver_to_driver_context(device_ctx->device.driver); struct blkvsc_driver_context *blkvsc_drv_ctx = @@ -1504,6 +1505,7 @@ static void __exit blkvsc_exit(void) } MODULE_LICENSE("GPL"); +MODULE_VERSION(HV_DRV_VERSION); module_param(blkvsc_ringbuffer_size, int, S_IRUGO); module_init(blkvsc_init); module_exit(blkvsc_exit); diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c index 0d7459e..1af3dcb 100644 --- a/drivers/staging/hv/netvsc_drv.c +++ b/drivers/staging/hv/netvsc_drv.c @@ -35,14 +35,13 @@ #include <net/pkt_sched.h> #include "osd.h" #include "logging.h" +#include "VersionInfo.h" #include "vmbus.h" #include "NetVscApi.h" -MODULE_LICENSE("GPL"); - struct net_device_context { /* point back to our device context */ - struct device_context *device_ctx; + struct vm_device *device_ctx; struct net_device_stats stats; }; @@ -72,11 +71,6 @@ static void netvsc_set_multicast_list(struct net_device *net) static int netvsc_open(struct net_device *net) { struct net_device_context *net_device_ctx = netdev_priv(net); - struct driver_context *driver_ctx = - driver_to_driver_context(net_device_ctx->device_ctx->device.driver); - struct netvsc_driver_context *net_drv_ctx = - (struct netvsc_driver_context *)driver_ctx; - struct netvsc_driver *net_drv_obj = &net_drv_ctx->drv_obj; struct hv_device *device_obj = &net_device_ctx->device_ctx->device_obj; int ret = 0; @@ -87,7 +81,7 @@ static int netvsc_open(struct net_device *net) sizeof(struct net_device_stats)); /* Open up the device */ - ret = net_drv_obj->OnOpen(device_obj); + ret = RndisFilterOnOpen(device_obj); if (ret != 0) { DPRINT_ERR(NETVSC_DRV, "unable to open device (ret %d).", ret); @@ -106,11 +100,6 @@ static int netvsc_open(struct net_device *net) static int netvsc_close(struct net_device *net) { struct net_device_context *net_device_ctx = netdev_priv(net); - struct driver_context *driver_ctx = - driver_to_driver_context(net_device_ctx->device_ctx->device.driver); - struct netvsc_driver_context *net_drv_ctx = - (struct netvsc_driver_context *)driver_ctx; - struct netvsc_driver *net_drv_obj = &net_drv_ctx->drv_obj; struct hv_device *device_obj = &net_device_ctx->device_ctx->device_obj; int ret; @@ -118,7 +107,7 @@ static int netvsc_close(struct net_device *net) netif_stop_queue(net); - ret = net_drv_obj->OnClose(device_obj); + ret = RndisFilterOnClose(device_obj); if (ret != 0) DPRINT_ERR(NETVSC_DRV, "unable to close device (ret %d).", ret); @@ -282,7 +271,7 @@ retry_send: static void netvsc_linkstatus_callback(struct hv_device *device_obj, unsigned int status) { - struct device_context *device_ctx = to_device_context(device_obj); + struct vm_device *device_ctx = to_vm_device(device_obj); struct net_device *net = dev_get_drvdata(&device_ctx->device); DPRINT_ENTER(NETVSC_DRV); @@ -309,7 +298,7 @@ static void netvsc_linkstatus_callback(struct hv_device *device_obj, static int netvsc_recv_callback(struct hv_device *device_obj, struct hv_netvsc_packet *packet) { - struct device_context *device_ctx = to_device_context(device_obj); + struct vm_device *device_ctx = to_vm_device(device_obj); struct net_device *net = dev_get_drvdata(&device_ctx->device); struct net_device_context *net_device_ctx; struct sk_buff *skb; @@ -401,7 +390,7 @@ static int netvsc_probe(struct device *device) struct netvsc_driver_context *net_drv_ctx = (struct netvsc_driver_context *)driver_ctx; struct netvsc_driver *net_drv_obj = &net_drv_ctx->drv_obj; - struct device_context *device_ctx = device_to_device_context(device); + struct vm_device *device_ctx = device_to_vm_device(device); struct hv_device *device_obj = &device_ctx->device_obj; struct net_device *net = NULL; struct net_device_context *net_device_ctx; @@ -473,7 +462,7 @@ static int netvsc_remove(struct device *device) struct netvsc_driver_context *net_drv_ctx = (struct netvsc_driver_context *)driver_ctx; struct netvsc_driver *net_drv_obj = &net_drv_ctx->drv_obj; - struct device_context *device_ctx = device_to_device_context(device); + struct vm_device *device_ctx = device_to_vm_device(device); struct net_device *net = dev_get_drvdata(&device_ctx->device); struct hv_device *device_obj = &device_ctx->device_obj; int ret; @@ -613,6 +602,8 @@ static void __exit netvsc_exit(void) DPRINT_EXIT(NETVSC_DRV); } +MODULE_LICENSE("GPL"); +MODULE_VERSION(HV_DRV_VERSION); module_param(netvsc_ringbuffer_size, int, S_IRUGO); module_init(netvsc_init); diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index d49dc21..3988f4b 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -32,6 +32,7 @@ #include <scsi/scsi_dbg.h> #include "osd.h" #include "logging.h" +#include "VersionInfo.h" #include "vmbus.h" #include "StorVscApi.h" @@ -39,10 +40,8 @@ struct host_device_context { /* must be 1st field * FIXME this is a bug */ - struct work_struct host_rescan_work; - /* point back to our device context */ - struct device_context *device_ctx; + struct vm_device *device_ctx; struct kmem_cache *request_pool; unsigned int port; unsigned char path; @@ -77,8 +76,6 @@ static int storvsc_queuecommand(struct scsi_cmnd *scmnd, static int storvsc_device_alloc(struct scsi_device *); static int storvsc_device_configure(struct scsi_device *); static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd); -static void storvsc_host_rescan_callback(struct work_struct *work); -static void storvsc_host_rescan(struct hv_device *device_obj); static int storvsc_remove(struct device *dev); static struct scatterlist *create_bounce_buffer(struct scatterlist *sgl, @@ -94,8 +91,6 @@ static unsigned int copy_to_bounce_buffer(struct scatterlist *orig_sgl, struct scatterlist *bounce_sgl, unsigned int orig_sgl_count); -static int storvsc_report_luns(struct scsi_device *sdev, unsigned int luns[], - unsigned int *lun_count); static int storvsc_get_chs(struct scsi_device *sdev, struct block_device *bdev, sector_t capacity, int *info); @@ -148,7 +143,6 @@ static int storvsc_drv_init(int (*drv_init)(struct hv_driver *drv)) vmbus_get_interface(&storvsc_drv_obj->Base.VmbusChannelInterface); storvsc_drv_obj->RingBufferSize = storvsc_ringbuffer_size; - storvsc_drv_obj->OnHostRescan = storvsc_host_rescan; /* Callback to client driver to complete the initialization */ drv_init(&storvsc_drv_obj->Base); @@ -240,7 +234,7 @@ static int storvsc_probe(struct device *device) (struct storvsc_driver_context *)driver_ctx; struct storvsc_driver_object *storvsc_drv_obj = &storvsc_drv_ctx->drv_obj; - struct device_context *device_ctx = device_to_device_context(device); + struct vm_device *device_ctx = device_to_vm_device(device); struct hv_device *device_obj = &device_ctx->device_obj; struct Scsi_Host *host; struct host_device_context *host_device_ctx; @@ -266,9 +260,6 @@ static int storvsc_probe(struct device *device) host_device_ctx->port = host->host_no; host_device_ctx->device_ctx = device_ctx; - INIT_WORK(&host_device_ctx->host_rescan_work, - storvsc_host_rescan_callback); - host_device_ctx->request_pool = kmem_cache_create(dev_name(&device_ctx->device), sizeof(struct storvsc_cmd_request) + @@ -339,7 +330,7 @@ static int storvsc_remove(struct device *device) (struct storvsc_driver_context *)driver_ctx; struct storvsc_driver_object *storvsc_drv_obj = &storvsc_drv_ctx->drv_obj; - struct device_context *device_ctx = device_to_device_context(device); + struct vm_device *device_ctx = device_to_vm_device(device); struct hv_device *device_obj = &device_ctx->device_obj; struct Scsi_Host *host = dev_get_drvdata(device); struct host_device_context *host_device_ctx = @@ -640,7 +631,7 @@ static int storvsc_queuecommand(struct scsi_cmnd *scmnd, int ret; struct host_device_context *host_device_ctx = (struct host_device_context *)scmnd->device->host->hostdata; - struct device_context *device_ctx = host_device_ctx->device_ctx; + struct vm_device *device_ctx = host_device_ctx->device_ctx; struct driver_context *driver_ctx = driver_to_driver_context(device_ctx->device.driver); struct storvsc_driver_context *storvsc_drv_ctx = @@ -879,14 +870,7 @@ static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd) int ret; struct host_device_context *host_device_ctx = (struct host_device_context *)scmnd->device->host->hostdata; - struct device_context *device_ctx = host_device_ctx->device_ctx; - struct driver_context *driver_ctx = - driver_to_driver_context(device_ctx->device.driver); - struct storvsc_driver_context *storvsc_drv_ctx = - (struct storvsc_driver_context *)driver_ctx; - - struct storvsc_driver_object *storvsc_drv_obj = - &storvsc_drv_ctx->drv_obj; + struct vm_device *device_ctx = host_device_ctx->device_ctx; DPRINT_ENTER(STORVSC_DRV); @@ -894,8 +878,7 @@ static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd) scmnd->device, &device_ctx->device_obj); /* Invokes the vsc to reset the host/bus */ - ASSERT(storvsc_drv_obj->OnHostReset); - ret = storvsc_drv_obj->OnHostReset(&device_ctx->device_obj); + ret = StorVscOnHostReset(&device_ctx->device_obj); if (ret != 0) { DPRINT_EXIT(STORVSC_DRV); return ret; @@ -909,201 +892,6 @@ static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd) return ret; } -/** - * storvsc_host_rescan - Rescan the scsi HBA - */ -static void storvsc_host_rescan_callback(struct work_struct *work) -{ - struct hv_device *device_obj = - &((struct host_device_context *)work)->device_ctx->device_obj; - struct device_context *device_ctx = to_device_context(device_obj); - struct Scsi_Host *host = dev_get_drvdata(&device_ctx->device); - struct scsi_device *sdev; - struct host_device_context *host_device_ctx; - struct scsi_device **sdevs_remove_list; - unsigned int sdevs_count = 0; - unsigned int found; - unsigned int i; - unsigned int lun_count = 0; - unsigned int *lun_list; - - DPRINT_ENTER(STORVSC_DRV); - - host_device_ctx = (struct host_device_context *)host->hostdata; - lun_list = kcalloc(STORVSC_MAX_LUNS_PER_TARGET, sizeof(unsigned int), - GFP_ATOMIC); - if (!lun_list) { - DPRINT_ERR(STORVSC_DRV, "unable to allocate lun list"); - return; - } - - sdevs_remove_list = kcalloc(STORVSC_MAX_LUNS_PER_TARGET, - sizeof(void *), GFP_ATOMIC); - if (!sdevs_remove_list) { - kfree(lun_list); - DPRINT_ERR(STORVSC_DRV, "unable to allocate lun remove list"); - return; - } - - DPRINT_INFO(STORVSC_DRV, "rescanning host for new scsi devices..."); - - /* Rescan for new device */ - scsi_scan_target(&host->shost_gendev, host_device_ctx->path, - host_device_ctx->target, SCAN_WILD_CARD, 1); - - DPRINT_INFO(STORVSC_DRV, "rescanning host for removed scsi device..."); - - /* Use the 1st device to send the report luns cmd */ - shost_for_each_device(sdev, host) { - lun_count = STORVSC_MAX_LUNS_PER_TARGET; - storvsc_report_luns(sdev, lun_list, &lun_count); - - DPRINT_INFO(STORVSC_DRV, - "report luns on scsi device (%p) found %u luns ", - sdev, lun_count); - DPRINT_INFO(STORVSC_DRV, - "existing luns on scsi device (%p) host (%d)", - sdev, host->host_no); - - scsi_device_put(sdev); - break; - } - - for (i = 0; i < lun_count; i++) - DPRINT_INFO(STORVSC_DRV, "%d) lun %u", i, lun_list[i]); - - /* Rescan for devices that may have been removed. - * We do not have to worry that new devices may have been added since - * this callback is serialized by the workqueue ie add/remove are done - * here. - */ - shost_for_each_device(sdev, host) { - /* See if this device is still here */ - found = 0; - for (i = 0; i < lun_count; i++) { - if (sdev->lun == lun_list[i]) { - found = 1; - break; - } - } - if (!found) { - DPRINT_INFO(STORVSC_DRV, "lun (%u) does not exists", - sdev->lun); - sdevs_remove_list[sdevs_count++] = sdev; - } - } - - /* Now remove the devices */ - for (i = 0; i < sdevs_count; i++) { - DPRINT_INFO(STORVSC_DRV, - "removing scsi device (%p) lun (%u)...", - sdevs_remove_list[i], sdevs_remove_list[i]->lun); - - /* make sure it is not removed from underneath us */ - if (!scsi_device_get(sdevs_remove_list[i])) { - scsi_remove_device(sdevs_remove_list[i]); - scsi_device_put(sdevs_remove_list[i]); - } - } - - DPRINT_INFO(STORVSC_DRV, "rescan completed on dev obj (%p) " - "target (%u) bus (%u)", device_obj, - host_device_ctx->target, host_device_ctx->path); - - kfree(lun_list); - kfree(sdevs_remove_list); - - DPRINT_EXIT(STORVSC_DRV); -} - -static int storvsc_report_luns(struct scsi_device *sdev, unsigned int luns[], - unsigned int *lun_count) -{ - int i, j; - unsigned int lun = 0; - unsigned int num_luns; - int result; - unsigned char *data; - struct scsi_sense_hdr sshdr; - unsigned char cmd[16] = {0}; - /* Add 1 to cover the report_lun header */ - unsigned int report_len = 8 * (STORVSC_MAX_LUNS_PER_TARGET+1); - unsigned long long *report_luns; - const unsigned int in_lun_count = *lun_count; - - *lun_count = 0; - - report_luns = kzalloc(report_len, GFP_ATOMIC); - if (!report_luns) - return -ENOMEM; - - cmd[0] = REPORT_LUNS; - - /* cmd length */ - *(unsigned int *)&cmd[6] = cpu_to_be32(report_len); - - result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, - (unsigned char *)report_luns, report_len, - &sshdr, 30 * HZ, 3, NULL); - if (result != 0) { - kfree(report_luns); - return -EBUSY; - } - - /* get the length from the first four bytes */ - report_len = be32_to_cpu(*(unsigned int *)&report_luns[0]); - - num_luns = (report_len / sizeof(unsigned long long)); - if (num_luns > in_lun_count) { - kfree(report_luns); - return -EINVAL; - } - - *lun_count = num_luns; - - DPRINT_DBG(STORVSC_DRV, - "report luns on scsi device (%p) found %u luns ", - sdev, num_luns); - - /* lun id starts at 1 */ - for (i = 1; i < num_luns + 1; i++) { - lun = 0; - data = (unsigned char *)&report_luns[i]; - for (j = 0; j < sizeof(lun); j += 2) { - lun = lun | (((data[j] << 8) | data[j + 1]) << - (j * 8)); - } - - luns[i-1] = lun; - } - - kfree(report_luns); - return 0; -} - -static void storvsc_host_rescan(struct hv_device *device_obj) -{ - struct device_context *device_ctx = to_device_context(device_obj); - struct Scsi_Host *host = dev_get_drvdata(&device_ctx->device); - struct host_device_context *host_device_ctx; - - DPRINT_ENTER(STORVSC_DRV); - - host_device_ctx = (struct host_device_context *)host->hostdata; - - DPRINT_INFO(STORVSC_DRV, "initiating rescan on dev obj (%p) " - "target (%u) bus (%u)...", device_obj, - host_device_ctx->target, host_device_ctx->path); - - /* - * We need to queue this since the scanning may block and the caller - * may be in an intr context - */ - /* scsi_queue_work(host, &host_device_ctx->host_rescan_work); */ - schedule_work(&host_device_ctx->host_rescan_work); - DPRINT_EXIT(STORVSC_DRV); -} - static int storvsc_get_chs(struct scsi_device *sdev, struct block_device * bdev, sector_t capacity, int *info) { @@ -1203,6 +991,7 @@ static void __exit storvsc_exit(void) } MODULE_LICENSE("GPL"); +MODULE_VERSION(HV_DRV_VERSION); module_param(storvsc_ringbuffer_size, int, S_IRUGO); module_init(storvsc_init); module_exit(storvsc_exit); diff --git a/drivers/staging/hv/vmbus.h b/drivers/staging/hv/vmbus.h index ae0a896..6404b84 100644 --- a/drivers/staging/hv/vmbus.h +++ b/drivers/staging/hv/vmbus.h @@ -43,23 +43,23 @@ struct driver_context { void (*shutdown)(struct device *); }; -struct device_context { +struct vm_device { struct work_struct probe_failed_work_item; struct hv_guid class_id; struct hv_guid device_id; int probe_error; - struct device device; struct hv_device device_obj; + struct device device; }; -static inline struct device_context *to_device_context(struct hv_device *d) +static inline struct vm_device *to_vm_device(struct hv_device *d) { - return container_of(d, struct device_context, device_obj); + return container_of(d, struct vm_device, device_obj); } -static inline struct device_context *device_to_device_context(struct device *d) +static inline struct vm_device *device_to_vm_device(struct device *d) { - return container_of(d, struct device_context, device); + return container_of(d, struct vm_device, device); } static inline struct driver_context *driver_to_driver_context(struct device_driver *d) diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 894eecf..2c90619 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -24,6 +24,9 @@ #include <linux/irq.h> #include <linux/interrupt.h> #include <linux/sysctl.h> +#include <linux/pci.h> +#include <linux/dmi.h> +#include "VersionInfo.h" #include "osd.h" #include "logging.h" #include "vmbus.h" @@ -47,7 +50,7 @@ struct vmbus_driver_context { struct tasklet_struct event_dpc; /* The bus root device */ - struct device_context device_ctx; + struct vm_device device_ctx; }; static int vmbus_match(struct device *device, struct device_driver *driver); @@ -135,7 +138,7 @@ static ssize_t vmbus_show_device_attr(struct device *dev, struct device_attribute *dev_attr, char *buf) { - struct device_context *device_ctx = device_to_device_context(dev); + struct vm_device *device_ctx = device_to_vm_device(dev); struct hv_device_info device_info; memset(&device_info, 0, sizeof(struct hv_device_info)); @@ -245,7 +248,7 @@ static int vmbus_bus_init(int (*drv_init)(struct hv_driver *drv)) { struct vmbus_driver_context *vmbus_drv_ctx = &g_vmbus_drv; struct vmbus_driver *vmbus_drv_obj = &g_vmbus_drv.drv_obj; - struct device_context *dev_ctx = &g_vmbus_drv.device_ctx; + struct vm_device *dev_ctx = &g_vmbus_drv.device_ctx; int ret; unsigned int vector; @@ -307,7 +310,7 @@ static int vmbus_bus_init(int (*drv_init)(struct hv_driver *drv)) DPRINT_INFO(VMBUS_DRV, "irq 0x%x vector 0x%x", vmbus_irq, vector); /* Call to bus driver to add the root device */ - memset(dev_ctx, 0, sizeof(struct device_context)); + memset(dev_ctx, 0, sizeof(struct vm_device)); ret = vmbus_drv_obj->Base.OnDeviceAdd(&dev_ctx->device_obj, &vector); if (ret != 0) { @@ -368,7 +371,7 @@ static void vmbus_bus_exit(void) struct vmbus_driver *vmbus_drv_obj = &g_vmbus_drv.drv_obj; struct vmbus_driver_context *vmbus_drv_ctx = &g_vmbus_drv; - struct device_context *dev_ctx = &g_vmbus_drv.device_ctx; + struct vm_device *dev_ctx = &g_vmbus_drv.device_ctx; DPRINT_ENTER(VMBUS_DRV); @@ -471,13 +474,13 @@ static struct hv_device *vmbus_child_device_create(struct hv_guid *type, struct hv_guid *instance, void *context) { - struct device_context *child_device_ctx; + struct vm_device *child_device_ctx; struct hv_device *child_device_obj; DPRINT_ENTER(VMBUS_DRV); /* Allocate the new child device */ - child_device_ctx = kzalloc(sizeof(struct device_context), GFP_KERNEL); + child_device_ctx = kzalloc(sizeof(struct vm_device), GFP_KERNEL); if (!child_device_ctx) { DPRINT_ERR(VMBUS_DRV, "unable to allocate device_context for child device"); @@ -526,10 +529,10 @@ static int vmbus_child_device_register(struct hv_device *root_device_obj, struct hv_device *child_device_obj) { int ret = 0; - struct device_context *root_device_ctx = - to_device_context(root_device_obj); - struct device_context *child_device_ctx = - to_device_context(child_device_obj); + struct vm_device *root_device_ctx = + to_vm_device(root_device_obj); + struct vm_device *child_device_ctx = + to_vm_device(child_device_obj); static atomic_t device_num = ATOMIC_INIT(0); DPRINT_ENTER(VMBUS_DRV); @@ -572,7 +575,7 @@ static int vmbus_child_device_register(struct hv_device *root_device_obj, */ static void vmbus_child_device_unregister(struct hv_device *device_obj) { - struct device_context *device_ctx = to_device_context(device_obj); + struct vm_device *device_ctx = to_vm_device(device_obj); DPRINT_ENTER(VMBUS_DRV); @@ -610,7 +613,7 @@ static void vmbus_child_device_destroy(struct hv_device *device_obj) */ static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env) { - struct device_context *device_ctx = device_to_device_context(device); + struct vm_device *device_ctx = device_to_vm_device(device); int ret; DPRINT_ENTER(VMBUS_DRV); @@ -687,7 +690,7 @@ static int vmbus_match(struct device *device, struct device_driver *driver) { int match = 0; struct driver_context *driver_ctx = driver_to_driver_context(driver); - struct device_context *device_ctx = device_to_device_context(device); + struct vm_device *device_ctx = device_to_vm_device(device); DPRINT_ENTER(VMBUS_DRV); @@ -724,7 +727,7 @@ static int vmbus_match(struct device *device, struct device_driver *driver) */ static void vmbus_probe_failed_cb(struct work_struct *context) { - struct device_context *device_ctx = (struct device_context *)context; + struct vm_device *device_ctx = (struct vm_device *)context; DPRINT_ENTER(VMBUS_DRV); @@ -746,8 +749,8 @@ static int vmbus_probe(struct device *child_device) int ret = 0; struct driver_context *driver_ctx = driver_to_driver_context(child_device->driver); - struct device_context *device_ctx = - device_to_device_context(child_device); + struct vm_device *device_ctx = + device_to_vm_device(child_device); DPRINT_ENTER(VMBUS_DRV); @@ -871,7 +874,7 @@ static void vmbus_bus_release(struct device *device) */ static void vmbus_device_release(struct device *device) { - struct device_context *device_ctx = device_to_device_context(device); + struct vm_device *device_ctx = device_to_vm_device(device); DPRINT_ENTER(VMBUS_DRV); @@ -946,6 +949,19 @@ static irqreturn_t vmbus_isr(int irq, void *dev_id) } } +static struct dmi_system_id __initdata microsoft_hv_dmi_table[] = { + { + .ident = "Hyper-V", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), + DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"), + DMI_MATCH(DMI_BOARD_NAME, "Virtual Machine"), + }, + }, + { }, +}; +MODULE_DEVICE_TABLE(dmi, microsoft_hv_dmi_table); + static int __init vmbus_init(void) { int ret = 0; @@ -957,6 +973,9 @@ static int __init vmbus_init(void) vmbus_loglevel, HIWORD(vmbus_loglevel), LOWORD(vmbus_loglevel)); /* Todo: it is used for loglevel, to be ported to new kernel. */ + if (!dmi_check_system(microsoft_hv_dmi_table)) + return -ENODEV; + ret = vmbus_bus_init(VmbusInitialize); DPRINT_EXIT(VMBUS_DRV); @@ -973,7 +992,20 @@ static void __exit vmbus_exit(void) return; } +/* + * We use a PCI table to determine if we should autoload this driver This is + * needed by distro tools to determine if the hyperv drivers should be + * installed and/or configured. We don't do anything else with the table, but + * it needs to be present. + */ +const static struct pci_device_id microsoft_hv_pci_table[] = { + { PCI_DEVICE(0x1414, 0x5353) }, /* VGA compatible controller */ + { 0 } +}; +MODULE_DEVICE_TABLE(pci, microsoft_hv_pci_table); + MODULE_LICENSE("GPL"); +MODULE_VERSION(HV_DRV_VERSION); module_param(vmbus_irq, int, S_IRUGO); module_param(vmbus_loglevel, int, S_IRUGO); diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c index 768f448..b456dfc 100644 --- a/drivers/staging/iio/industrialio-core.c +++ b/drivers/staging/iio/industrialio-core.c @@ -79,11 +79,14 @@ EXPORT_SYMBOL(__iio_change_event); /* Does anyone care? */ mutex_lock(&ev_int->event_list_lock); if (test_bit(IIO_BUSY_BIT_POS, &ev_int->handler.flags)) { - if (ev_int->current_events == ev_int->max_events) + if (ev_int->current_events == ev_int->max_events) { + mutex_unlock(&ev_int->event_list_lock); return 0; + } ev = kmalloc(sizeof(*ev), GFP_KERNEL); if (ev == NULL) { ret = -ENOMEM; + mutex_unlock(&ev_int->event_list_lock); goto error_ret; } ev->ev.id = ev_code; @@ -115,7 +118,7 @@ int iio_push_event(struct iio_dev *dev_info, EXPORT_SYMBOL(iio_push_event); /* Generic interrupt line interrupt handler */ -irqreturn_t iio_interrupt_handler(int irq, void *_int_info) +static irqreturn_t iio_interrupt_handler(int irq, void *_int_info) { struct iio_interrupt *int_info = _int_info; struct iio_dev *dev_info = int_info->dev_info; @@ -249,10 +252,10 @@ void iio_remove_event_from_list(struct iio_event_handler_list *el, } EXPORT_SYMBOL(iio_remove_event_from_list); -ssize_t iio_event_chrdev_read(struct file *filep, - char *buf, - size_t count, - loff_t *f_ps) +static ssize_t iio_event_chrdev_read(struct file *filep, + char __user *buf, + size_t count, + loff_t *f_ps) { struct iio_event_interface *ev_int = filep->private_data; struct iio_detected_event_list *el; @@ -289,16 +292,16 @@ ssize_t iio_event_chrdev_read(struct file *filep, mutex_unlock(&ev_int->event_list_lock); /* * Possible concurency issue if an update of this event is on its way - * through. May lead to new even being removed whilst the reported event - * was the unescalated event. In typical use case this is not a problem - * as userspace will say read half the buffer due to a 50% full event - * which would make the correct 100% full incorrect anyway. + * through. May lead to new event being removed whilst the reported + * event was the unescalated event. In typical use case this is not a + * problem as userspace will say read half the buffer due to a 50% + * full event which would make the correct 100% full incorrect anyway. */ - spin_lock(&el->shared_pointer->lock); - if (el->shared_pointer) + if (el->shared_pointer) { + spin_lock(&el->shared_pointer->lock); (el->shared_pointer->ev_p) = NULL; - spin_unlock(&el->shared_pointer->lock); - + spin_unlock(&el->shared_pointer->lock); + } kfree(el); return len; @@ -310,7 +313,7 @@ error_ret: return ret; } -int iio_event_chrdev_release(struct inode *inode, struct file *filep) +static int iio_event_chrdev_release(struct inode *inode, struct file *filep) { struct iio_handler *hand = iio_cdev_to_handler(inode->i_cdev); struct iio_event_interface *ev_int = hand->private; @@ -332,7 +335,7 @@ int iio_event_chrdev_release(struct inode *inode, struct file *filep) return 0; } -int iio_event_chrdev_open(struct inode *inode, struct file *filep) +static int iio_event_chrdev_open(struct inode *inode, struct file *filep) { struct iio_handler *hand = iio_cdev_to_handler(inode->i_cdev); struct iio_event_interface *ev_int = hand->private; diff --git a/drivers/staging/iio/ring_generic.h b/drivers/staging/iio/ring_generic.h index 93b91b2..09044ad 100644 --- a/drivers/staging/iio/ring_generic.h +++ b/drivers/staging/iio/ring_generic.h @@ -146,8 +146,7 @@ static inline void __iio_init_ring_buffer(struct iio_ring_buffer *ring, ring->length = length; ring->loopcount = 0; ring->shared_ev_pointer.ev_p = 0; - ring->shared_ev_pointer.lock = - __SPIN_LOCK_UNLOCKED(ring->shared_ev_pointer->loc); + spin_lock_init(&ring->shared_ev_pointer.lock); } /** diff --git a/drivers/staging/iio/ring_sw.c b/drivers/staging/iio/ring_sw.c index 359ff92..6f7f4d5 100644 --- a/drivers/staging/iio/ring_sw.c +++ b/drivers/staging/iio/ring_sw.c @@ -8,7 +8,6 @@ */ #include <linux/kernel.h> -#include <linux/device.h> #include <linux/module.h> #include <linux/device.h> #include <linux/workqueue.h> @@ -21,7 +20,7 @@ static inline int __iio_init_sw_ring_buffer(struct iio_sw_ring_buffer *ring, return -EINVAL; __iio_init_ring_buffer(&ring->buf, bytes_per_datum, length); - ring->use_lock = __SPIN_LOCK_UNLOCKED((ring)->use_lock); + spin_lock_init(&ring->use_lock); ring->data = kmalloc(length*ring->buf.bpd, GFP_KERNEL); ring->read_p = 0; ring->write_p = 0; diff --git a/drivers/staging/iio/trigger_consumer.h b/drivers/staging/iio/trigger_consumer.h index a02d70b..9d52d96 100644 --- a/drivers/staging/iio/trigger_consumer.h +++ b/drivers/staging/iio/trigger_consumer.h @@ -27,7 +27,7 @@ int iio_device_unregister_trigger_consumer(struct iio_dev *dev_info); * iio_device_register_trigger_consumer() - set up an iio_dev to use triggers * @dev_info: iio_dev associated with the device that will consume the trigger **/ -int iio_device_register_trigger_consumer(struct iio_dev *dev_info) +static int iio_device_register_trigger_consumer(struct iio_dev *dev_info) { return 0; }; @@ -36,7 +36,7 @@ int iio_device_register_trigger_consumer(struct iio_dev *dev_info) * iio_device_unregister_trigger_consumer() - reverse the registration process * @dev_info: iio_dev associated with the device that consumed the trigger **/ -int iio_device_unregister_trigger_consumer(struct iio_dev *dev_info) +static int iio_device_unregister_trigger_consumer(struct iio_dev *dev_info) { return 0; }; diff --git a/drivers/staging/line6/driver.c b/drivers/staging/line6/driver.c index e4078a9..0392a4b 100644 --- a/drivers/staging/line6/driver.c +++ b/drivers/staging/line6/driver.c @@ -33,7 +33,7 @@ /* table of devices that work with this driver */ -static struct usb_device_id line6_id_table[] = { +static const struct usb_device_id line6_id_table[] = { { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXT) }, { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXTLIVE) }, { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXTPRO) }, diff --git a/drivers/staging/line6/variax.c b/drivers/staging/line6/variax.c index 48d834b..58fef82 100644 --- a/drivers/staging/line6/variax.c +++ b/drivers/staging/line6/variax.c @@ -254,7 +254,7 @@ static ssize_t variax_set_active(struct device *dev, if (ret) return ret; - variax->buffer_activate[VARIAX_OFFSET_ACTIVATE] = value ? 1: 0; + variax->buffer_activate[VARIAX_OFFSET_ACTIVATE] = value ? 1 : 0; line6_send_raw_message_async(&variax->line6, variax->buffer_activate, sizeof(variax_activate)); return count; diff --git a/drivers/staging/mimio/Kconfig b/drivers/staging/mimio/Kconfig deleted file mode 100644 index 505dcb2..0000000 --- a/drivers/staging/mimio/Kconfig +++ /dev/null @@ -1,10 +0,0 @@ -config INPUT_MIMIO - tristate "Mimio Xi interactive whiteboard support" - depends on USB && INPUT - default N - help - Say Y here if you want to use a Mimio Xi interactive - whiteboard device. - - To compile this driver as a module, choose M here: the - module will be called mimio. diff --git a/drivers/staging/mimio/Makefile b/drivers/staging/mimio/Makefile deleted file mode 100644 index 77807ee..0000000 --- a/drivers/staging/mimio/Makefile +++ /dev/null @@ -1 +0,0 @@ -obj-$(CONFIG_INPUT_MIMIO) += mimio.o diff --git a/drivers/staging/mimio/mimio.c b/drivers/staging/mimio/mimio.c deleted file mode 100644 index 1ba8103..0000000 --- a/drivers/staging/mimio/mimio.c +++ /dev/null @@ -1,914 +0,0 @@ -/* - * Hardware event => input event mapping: - * - * - * - input.h:#define BTN_TOOL_PEN 0x140 black - input.h:#define BTN_TOOL_RUBBER 0x141 blue - input.h:#define BTN_TOOL_BRUSH 0x142 green - input.h:#define BTN_TOOL_PENCIL 0x143 red - input.h:#define BTN_TOOL_AIRBRUSH 0x144 eraser - input.h:#define BTN_TOOL_FINGER 0x145 small eraser - input.h:#define BTN_TOOL_MOUSE 0x146 mimio interactive - input.h:#define BTN_TOOL_LENS 0x147 mimio interactive but1 - input.h:#define LOCALBTN_TOOL_EXTRA1 0x14a mimio interactive but2 == BTN_TOUCH - input.h:#define LOCALBTN_TOOL_EXTRA2 0x14b mimio extra pens (orange, brown, yellow, purple) == BTN_STYLUS - input.h:#define LOCALBTN_TOOL_EXTRA3 0x14c unused == BTN_STYLUS2 - input.h:#define BTN_TOOL_DOUBLETAP 0x14d unused - input.h:#define BTN_TOOL_TRIPLETAP 0x14e unused - * - * MIMIO_EV_PENDOWN(MIMIO_PEN_K) => EV_KEY BIT(BTN_TOOL_PEN) - * MIMIO_EV_PENDOWN(MIMIO_PEN_B) => EV_KEY BIT(BTN_TOOL_RUBBER) - * MIMIO_EV_PENDOWN(MIMIO_PEN_G) => EV_KEY BIT(BTN_TOOL_BRUSH) - * MIMIO_EV_PENDOWN(MIMIO_PEN_R) => EV_KEY BIT(BTN_TOOL_PENCIL) - * MIMIO_EV_PENDOWN(MIMIO_PEN_E) => EV_KEY BIT(BTN_TOOL_AIRBRUSH) - * MIMIO_EV_PENDOWN(MIMIO_PEN_ES) => EV_KEY BIT(BTN_TOOL_FINGER) - * MIMIO_EV_PENDOWN(MIMIO_PEN_I) => EV_KEY BIT(BTN_TOOL_MOUSE) - * MIMIO_EV_PENDOWN(MIMIO_PEN_IL) => EV_KEY BIT(BTN_TOOL_LENS) - * MIMIO_EV_PENDOWN(MIMIO_PEN_IR) => EV_KEY BIT(BTN_TOOL_DOUBLETAP) - * MIMIO_EV_PENDOWN(MIMIO_PEN_EX) => EV_KEY BIT(BTN_TOOL_TRIPLETAP) - * MIMIO_EV_PENDATA => EV_ABS BIT(ABS_X), BIT(ABS_Y) - * MIMIO_EV_MEMRESET => EV_KEY BIT(BTN_0) - * MIMIO_EV_ACC(ACC_NEWPAGE) => EV_KEY BIT(BTN_1) - * MIMIO_EV_ACC(ACC_TAGPAGE) => EV_KEY BIT(BTN_2) - * MIMIO_EV_ACC(ACC_PRINTPAGE) => EV_KEY BIT(BTN_3) - * MIMIO_EV_ACC(ACC_MAXIMIZE) => EV_KEY BIT(BTN_4) - * MIMIO_EV_ACC(ACC_FINDCTLPNL) => EV_KEY BIT(BTN_5) - * - * - * open issues: - * - cold-load of data captured when mimio in standalone mode not yet - * supported; need to snoop Win32 box to see datastream for this. - * - mimio mouse not yet supported; need to snoop Win32 box to see the - * datastream for this. - */ -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/spinlock.h> -#include <linux/input.h> -#include <linux/usb.h> - -#define DRIVER_VERSION "v0.031" -#define DRIVER_AUTHOR "mwilder@cs.nmsu.edu" -#define DRIVER_DESC "USB mimio-xi driver" - -enum {UPVALUE, DOWNVALUE, MOVEVALUE}; - -#define MIMIO_XRANGE_MAX 9600 -#define MIMIO_YRANGE_MAX 4800 - -#define LOCALBTN_TOOL_EXTRA1 BTN_TOUCH -#define LOCALBTN_TOOL_EXTRA2 BTN_STYLUS -#define LOCALBTN_TOOL_EXTRA3 BTN_STYLUS2 - -#define MIMIO_VENDOR_ID 0x08d3 -#define MIMIO_PRODUCT_ID 0x0001 -#define MIMIO_MAXPAYLOAD (8) -#define MIMIO_MAXNAMELEN (64) -#define MIMIO_TXWAIT (1) -#define MIMIO_TXDONE (2) - -#define MIMIO_EV_PENDOWN (0x22) -#define MIMIO_EV_PENDATA (0x24) -#define MIMIO_EV_PENUP (0x51) -#define MIMIO_EV_MEMRESET (0x45) -#define MIMIO_EV_ACC (0xb2) - -#define MIMIO_PEN_K (1) /* black pen */ -#define MIMIO_PEN_B (2) /* blue pen */ -#define MIMIO_PEN_G (3) /* green pen */ -#define MIMIO_PEN_R (4) /* red pen */ -/* 5, 6, 7, 8 are extra pens */ -#define MIMIO_PEN_E (9) /* big eraser */ -#define MIMIO_PEN_ES (10) /* lil eraser */ -#define MIMIO_PENJUMP_START (10) -#define MIMIO_PENJUMP (6) -#define MIMIO_PEN_I (17) /* mimio interactive */ -#define MIMIO_PEN_IL (18) /* mimio interactive button 1 */ -#define MIMIO_PEN_IR (19) /* mimio interactive button 2 */ - -#define MIMIO_PEN_MAX (MIMIO_PEN_IR) - -#define ACC_DONE (0) -#define ACC_NEWPAGE (1) -#define ACC_TAGPAGE (2) -#define ACC_PRINTPAGE (4) -#define ACC_MAXIMIZE (8) -#define ACC_FINDCTLPNL (16) - -#define isvalidtxsize(n) ((n) > 0 && (n) <= MIMIO_MAXPAYLOAD) - - -struct pktbuf { - unsigned char instr; - unsigned char buf[16]; - unsigned char *p; - unsigned char *q; -}; - -struct usbintendpt { - dma_addr_t dma; - struct urb *urb; - unsigned char *buf; - struct usb_endpoint_descriptor *desc; -}; - -struct mimio { - struct input_dev *idev; - struct usb_device *udev; - struct usb_interface *uifc; - int open; - int present; - int greeted; - int txflags; - char phys[MIMIO_MAXNAMELEN]; - struct usbintendpt in; - struct usbintendpt out; - struct pktbuf pktbuf; - unsigned char minor; - wait_queue_head_t waitq; - spinlock_t txlock; - void (*rxhandler)(struct mimio *, unsigned char *, unsigned int); - int last_pen_down; -}; - -static void mimio_close(struct input_dev *); -static void mimio_dealloc(struct mimio *); -static void mimio_disconnect(struct usb_interface *); -static int mimio_greet(struct mimio *); -static void mimio_irq_in(struct urb *); -static void mimio_irq_out(struct urb *); -static int mimio_open(struct input_dev *); -static int mimio_probe(struct usb_interface *, const struct usb_device_id *); -static void mimio_rx_handler(struct mimio *, unsigned char *, unsigned int); -static int mimio_tx(struct mimio *, const char *, int); - -static char mimio_name[] = "VirtualInk mimio-Xi"; -static struct usb_device_id mimio_table [] = { - { USB_DEVICE(MIMIO_VENDOR_ID, MIMIO_PRODUCT_ID) }, - { USB_DEVICE(0x0525, 0xa4a0) }, /* gadget zero firmware */ - { } -}; - -MODULE_DEVICE_TABLE(usb, mimio_table); - -static struct usb_driver mimio_driver = { - .name = "mimio", - .probe = mimio_probe, - .disconnect = mimio_disconnect, - .id_table = mimio_table, -}; - -static DECLARE_MUTEX(disconnect_sem); - -static void mimio_close(struct input_dev *idev) -{ - struct mimio *mimio; - - mimio = input_get_drvdata(idev); - if (!mimio) { - dev_err(&idev->dev, "null mimio attached to input device\n"); - return; - } - - if (mimio->open <= 0) - dev_err(&idev->dev, "mimio not open.\n"); - else - mimio->open--; - - if (mimio->present == 0 && mimio->open == 0) - mimio_dealloc(mimio); -} - -static void mimio_dealloc(struct mimio *mimio) -{ - if (mimio == NULL) - return; - - usb_kill_urb(mimio->in.urb); - - usb_kill_urb(mimio->out.urb); - - if (mimio->idev) { - input_unregister_device(mimio->idev); - if (mimio->idev->grab) - input_close_device(mimio->idev->grab); - else - dev_dbg(&mimio->idev->dev, "mimio->idev->grab == NULL" - " -- didn't call input_close_device\n"); - } - - usb_free_urb(mimio->in.urb); - - usb_free_urb(mimio->out.urb); - - if (mimio->in.buf) { - usb_buffer_free(mimio->udev, MIMIO_MAXPAYLOAD, mimio->in.buf, - mimio->in.dma); - } - - if (mimio->out.buf) - usb_buffer_free(mimio->udev, MIMIO_MAXPAYLOAD, mimio->out.buf, - mimio->out.dma); - - if (mimio->idev) - input_free_device(mimio->idev); - - kfree(mimio); -} - -static void mimio_disconnect(struct usb_interface *ifc) -{ - struct mimio *mimio; - - down(&disconnect_sem); - - mimio = usb_get_intfdata(ifc); - usb_set_intfdata(ifc, NULL); - dev_dbg(&mimio->idev->dev, "disconnect\n"); - - if (mimio) { - mimio->present = 0; - - if (mimio->open <= 0) - mimio_dealloc(mimio); - } - - up(&disconnect_sem); -} - -static int mimio_greet(struct mimio *mimio) -{ - const struct grtpkt { - int nbytes; - unsigned delay; - char data[8]; - } grtpkts[] = { - { 3, 0, { 0x11, 0x55, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00 } }, - { 5, 0, { 0x53, 0x55, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00 } }, - { 5, 0, { 0x43, 0x55, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00 } }, - { 5, 0, { 0x33, 0x55, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00 } }, - { 5, 0, { 0x13, 0x00, 0x5e, 0x02, 0x4f, 0x00, 0x00, 0x00 } }, - { 5, 0, { 0x13, 0x00, 0x04, 0x03, 0x14, 0x00, 0x00, 0x00 } }, - { 5, 2, { 0x13, 0x00, 0x00, 0x04, 0x17, 0x00, 0x00, 0x00 } }, - { 5, 0, { 0x13, 0x00, 0x0d, 0x08, 0x16, 0x00, 0x00, 0x00 } }, - { 5, 0, { 0x13, 0x00, 0x4d, 0x01, 0x5f, 0x00, 0x00, 0x00 } }, - { 3, 0, { 0xf1, 0x55, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00 } }, - { 7, 2, { 0x52, 0x55, 0x00, 0x07, 0x31, 0x55, 0x64, 0x00 } }, - { 0, 0, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, - }; - int rslt; - const struct grtpkt *pkt; - - for (pkt = grtpkts; pkt->nbytes; pkt++) { - rslt = mimio_tx(mimio, pkt->data, pkt->nbytes); - if (rslt) - return rslt; - if (pkt->delay) - msleep(pkt->delay); - } - - return 0; -} - -static void mimio_irq_in(struct urb *urb) -{ - int rslt; - char *data; - const char *reason = "going down"; - struct mimio *mimio; - - mimio = urb->context; - - if (mimio == NULL) - /* paranoia */ - return; - - switch (urb->status) { - case 0: - /* success */ - break; - case -ETIMEDOUT: - reason = "timeout -- unplugged?"; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - dev_dbg(&mimio->idev->dev, "%s.\n", reason); - return; - default: - dev_dbg(&mimio->idev->dev, "unknown urb-status: %d.\n", - urb->status); - goto exit; - } - data = mimio->in.buf; - - if (mimio->rxhandler) - mimio->rxhandler(mimio, data, urb->actual_length); -exit: - /* - * Keep listening to device on same urb. - */ - rslt = usb_submit_urb(urb, GFP_ATOMIC); - if (rslt) - dev_err(&mimio->idev->dev, "usb_submit_urb failure: %d.\n", - rslt); -} - -static void mimio_irq_out(struct urb *urb) -{ - unsigned long flags; - struct mimio *mimio; - - mimio = urb->context; - - if (urb->status) - dev_dbg(&mimio->idev->dev, "urb-status: %d.\n", urb->status); - - spin_lock_irqsave(&mimio->txlock, flags); - mimio->txflags |= MIMIO_TXDONE; - spin_unlock_irqrestore(&mimio->txlock, flags); - wmb(); - wake_up(&mimio->waitq); -} - -static int mimio_open(struct input_dev *idev) -{ - int rslt; - struct mimio *mimio; - - rslt = 0; - down(&disconnect_sem); - mimio = input_get_drvdata(idev); - dev_dbg(&idev->dev, "mimio_open\n"); - - if (mimio == NULL) { - dev_err(&idev->dev, "null mimio.\n"); - rslt = -ENODEV; - goto exit; - } - - if (mimio->open++) - goto exit; - - if (mimio->present && !mimio->greeted) { - struct urb *urb = mimio->in.urb; - mimio->in.urb->dev = mimio->udev; - rslt = usb_submit_urb(mimio->in.urb, GFP_KERNEL); - if (rslt) { - dev_err(&idev->dev, "usb_submit_urb failure " - "(res = %d: %s). Not greeting.\n", - rslt, - (!urb ? "urb is NULL" : - (urb->hcpriv ? "urb->hcpriv is non-NULL" : - (!urb->complete ? "urb is not complete" : - (urb->number_of_packets <= 0 ? "urb has no packets" : - (urb->interval <= 0 ? "urb interval too small" : - "urb interval too large or some other error")))))); - rslt = -EIO; - goto exit; - } - rslt = mimio_greet(mimio); - if (rslt == 0) { - dev_dbg(&idev->dev, "Mimio greeted OK.\n"); - mimio->greeted = 1; - } else { - dev_dbg(&idev->dev, "Mimio greet Failure (%d)\n", - rslt); - } - } - -exit: - up(&disconnect_sem); - return rslt; -} - -static int mimio_probe(struct usb_interface *ifc, - const struct usb_device_id *id) -{ - char path[64]; - int pipe, maxp; - struct mimio *mimio; - struct usb_device *udev; - struct usb_host_interface *hostifc; - struct input_dev *input_dev; - int res = 0; - int i; - - udev = interface_to_usbdev(ifc); - - mimio = kzalloc(sizeof(struct mimio), GFP_KERNEL); - if (!mimio) - return -ENOMEM; - - input_dev = input_allocate_device(); - if (!input_dev) { - mimio_dealloc(mimio); - return -ENOMEM; - } - - mimio->uifc = ifc; - mimio->udev = udev; - mimio->pktbuf.p = mimio->pktbuf.buf; - mimio->pktbuf.q = mimio->pktbuf.buf; - /* init_input_dev(mimio->idev); */ - mimio->idev = input_dev; - init_waitqueue_head(&mimio->waitq); - spin_lock_init(&mimio->txlock); - hostifc = ifc->cur_altsetting; - - if (hostifc->desc.bNumEndpoints != 2) { - dev_err(&udev->dev, "Unexpected endpoint count: %d.\n", - hostifc->desc.bNumEndpoints); - mimio_dealloc(mimio); - return -ENODEV; - } - - mimio->in.desc = &(hostifc->endpoint[0].desc); - mimio->out.desc = &(hostifc->endpoint[1].desc); - - mimio->in.buf = usb_buffer_alloc(udev, MIMIO_MAXPAYLOAD, GFP_KERNEL, - &mimio->in.dma); - mimio->out.buf = usb_buffer_alloc(udev, MIMIO_MAXPAYLOAD, GFP_KERNEL, - &mimio->out.dma); - - if (mimio->in.buf == NULL || mimio->out.buf == NULL) { - dev_err(&udev->dev, "usb_buffer_alloc failure.\n"); - mimio_dealloc(mimio); - return -ENOMEM; - } - - mimio->in.urb = usb_alloc_urb(0, GFP_KERNEL); - mimio->out.urb = usb_alloc_urb(0, GFP_KERNEL); - - if (mimio->in.urb == NULL || mimio->out.urb == NULL) { - dev_err(&udev->dev, "usb_alloc_urb failure.\n"); - mimio_dealloc(mimio); - return -ENOMEM; - } - - /* - * Build the input urb. - */ - pipe = usb_rcvintpipe(udev, mimio->in.desc->bEndpointAddress); - maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe)); - if (maxp > MIMIO_MAXPAYLOAD) - maxp = MIMIO_MAXPAYLOAD; - usb_fill_int_urb(mimio->in.urb, udev, pipe, mimio->in.buf, maxp, - mimio_irq_in, mimio, mimio->in.desc->bInterval); - mimio->in.urb->transfer_dma = mimio->in.dma; - mimio->in.urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - - /* - * Build the output urb. - */ - pipe = usb_sndintpipe(udev, mimio->out.desc->bEndpointAddress); - maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe)); - if (maxp > MIMIO_MAXPAYLOAD) - maxp = MIMIO_MAXPAYLOAD; - usb_fill_int_urb(mimio->out.urb, udev, pipe, mimio->out.buf, maxp, - mimio_irq_out, mimio, mimio->out.desc->bInterval); - mimio->out.urb->transfer_dma = mimio->out.dma; - mimio->out.urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - - /* - * Build input device info - */ - usb_make_path(udev, path, 64); - snprintf(mimio->phys, MIMIO_MAXNAMELEN, "%s/input0", path); - input_set_drvdata(input_dev, mimio); - /* input_dev->dev = &ifc->dev; */ - input_dev->open = mimio_open; - input_dev->close = mimio_close; - input_dev->name = mimio_name; - input_dev->phys = mimio->phys; - input_dev->dev.parent = &ifc->dev; - - input_dev->id.bustype = BUS_USB; - input_dev->id.vendor = le16_to_cpu(udev->descriptor.idVendor); - input_dev->id.product = le16_to_cpu(udev->descriptor.idProduct); - input_dev->id.version = le16_to_cpu(udev->descriptor.bcdDevice); - - input_dev->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS); - for (i = BTN_TOOL_PEN; i <= LOCALBTN_TOOL_EXTRA2; ++i) - set_bit(i, input_dev->keybit); - - input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_0) | - BIT_MASK(BTN_1) | - BIT_MASK(BTN_2) | - BIT_MASK(BTN_3) | - BIT_MASK(BTN_4) | - BIT_MASK(BTN_5); - /* input_dev->keybit[BTN_MOUSE] |= BIT(BTN_LEFT); */ - input_dev->absbit[0] |= BIT_MASK(ABS_X) | BIT_MASK(ABS_Y); - input_set_abs_params(input_dev, ABS_X, 0, MIMIO_XRANGE_MAX, 0, 0); - input_set_abs_params(input_dev, ABS_Y, 0, MIMIO_YRANGE_MAX, 0, 0); - input_dev->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC); - -#if 0 - input_dev->absmin[ABS_X] = 0; - input_dev->absmin[ABS_Y] = 0; - input_dev->absmax[ABS_X] = 9600; - input_dev->absmax[ABS_Y] = 4800; - input_dev->absfuzz[ABS_X] = 0; - input_dev->absfuzz[ABS_Y] = 0; - input_dev->absflat[ABS_X] = 0; - input_dev->absflat[ABS_Y] = 0; -#endif - -#if 0 - /* this will just reduce the precision */ - input_dev->absfuzz[ABS_X] = 8; /* experimental; may need to change */ - input_dev->absfuzz[ABS_Y] = 8; /* experimental; may need to change */ -#endif - - /* - * Register the input device. - */ - res = input_register_device(mimio->idev); - if (res) { - dev_err(&udev->dev, "input_register_device failure (%d)\n", - res); - mimio_dealloc(mimio); - return -EIO; - } - dev_dbg(&mimio->idev->dev, "input: %s on %s (res = %d).\n", - input_dev->name, input_dev->phys, res); - - usb_set_intfdata(ifc, mimio); - mimio->present = 1; - - /* - * Submit the input urb to the usb subsystem. - */ - mimio->in.urb->dev = mimio->udev; - res = usb_submit_urb(mimio->in.urb, GFP_KERNEL); - if (res) { - dev_err(&mimio->idev->dev, "usb_submit_urb failure (%d)\n", - res); - mimio_dealloc(mimio); - return -EIO; - } - - /* - * Attempt to greet the mimio after giving - * it some post-init settling time. - * - * note: sometimes this sleep interval isn't - * long enough to permit the device to re-init - * after a hot-swap; maybe need to bump it up. - * - * As it is, this probably breaks module unloading support! - */ - msleep(1024); - - res = mimio_greet(mimio); - if (res == 0) { - dev_dbg(&mimio->idev->dev, "Mimio greeted OK.\n"); - mimio->greeted = 1; - mimio->rxhandler = mimio_rx_handler; - } else { - dev_dbg(&mimio->idev->dev, "Mimio greet Failure (%d)\n", res); - } - - return 0; -} - -static int handle_mimio_rx_penupdown(struct mimio *mimio, - int down, - const char *const instr[], - const int instr_ofst[]) -{ - int penid, x; - if (mimio->pktbuf.q - mimio->pktbuf.p < (down ? 4 : 3)) - return 1; /* partial pkt */ - - if (down) { - x = *mimio->pktbuf.p ^ *(mimio->pktbuf.p + 1) ^ - *(mimio->pktbuf.p + 2); - if (x != *(mimio->pktbuf.p + 3)) { - dev_dbg(&mimio->idev->dev, "EV_PEN%s: bad xsum.\n", - down ? "DOWN":"UP"); - /* skip this event data */ - mimio->pktbuf.p += 4; - /* decode any remaining events */ - return 0; - } - penid = mimio->pktbuf.instr = *(mimio->pktbuf.p + 2); - if (penid > MIMIO_PEN_MAX) { - dev_dbg(&mimio->idev->dev, - "Unmapped penID (not in [0, %d]): %d\n", - MIMIO_PEN_MAX, (int)mimio->pktbuf.instr); - penid = mimio->pktbuf.instr = 0; - } - mimio->last_pen_down = penid; - } else { - penid = mimio->last_pen_down; - } - dev_dbg(&mimio->idev->dev, "%s (id %d, code %d) %s.\n", instr[penid], - instr_ofst[penid], penid, down ? "down" : "up"); - - if (instr_ofst[penid] >= 0) { - int code = BTN_TOOL_PEN + instr_ofst[penid]; - int value = down ? DOWNVALUE : UPVALUE; - if (code > KEY_MAX) - dev_dbg(&mimio->idev->dev, "input_event will ignore " - "-- code (%d) > KEY_MAX\n", code); - if (!test_bit(code, mimio->idev->keybit)) - dev_dbg(&mimio->idev->dev, "input_event will ignore " - "-- bit for code (%d) not enabled\n", code); - if (!!test_bit(code, mimio->idev->key) == value) - dev_dbg(&mimio->idev->dev, "input_event will ignore " - "-- bit for code (%d) already set to %d\n", - code, value); - if (value != DOWNVALUE) { - /* input_regs(mimio->idev, regs); */ - input_report_key(mimio->idev, code, value); - input_sync(mimio->idev); - } else { - /* wait until we get some coordinates */ - } - } else { - dev_dbg(&mimio->idev->dev, "penID offset[%d] == %d is < 0 " - "- not sending\n", penid, instr_ofst[penid]); - } - mimio->pktbuf.p += down ? 4 : 3; /* 3 for up, 4 for down */ - return 0; -} - -/* - * Stay tuned for partial-packet excitement. - * - * This routine buffers data packets received from the mimio device - * in the mimio's data space. This buffering is necessary because - * the mimio's in endpoint can serve us partial packets of data, and - * we want the driver to support the servicing of multiple mimios. - * Empirical evidence gathered so far suggests that the method of - * buffering packet data in the mimio's data space works. Previous - * versions of this driver did not buffer packet data in each mimio's - * data-space, and were therefore not able to service multiple mimios. - * Note that since the caller of this routine is running in interrupt - * context, care needs to be taken to ensure that this routine does not - * become bloated, and it may be that another spinlock is needed in each - * mimio to guard the buffered packet data properly. - */ -static void mimio_rx_handler(struct mimio *mimio, - unsigned char *data, - unsigned int nbytes) -{ - struct device *dev = &mimio->idev->dev; - unsigned int x; - unsigned int y; - static const char * const instr[] = { - "?0", - "black pen", "blue pen", "green pen", "red pen", - "brown pen", "orange pen", "purple pen", "yellow pen", - "big eraser", "lil eraser", - "?11", "?12", "?13", "?14", "?15", "?16", - "mimio interactive", "interactive button1", - "interactive button2" - }; - - /* Mimio Interactive gives: - * down: [0x22 0x01 0x11 0x32 0x24] - * b1 : [0x22 0x01 0x12 0x31 0x24] - * b2 : [0x22 0x01 0x13 0x30 0x24] - */ - static const int instr_ofst[] = { - -1, - 0, 1, 2, 3, - 9, 9, 9, 9, - 4, 5, - -1, -1, -1, -1, -1, -1, - 6, 7, 8, - }; - - memcpy(mimio->pktbuf.q, data, nbytes); - mimio->pktbuf.q += nbytes; - - while (mimio->pktbuf.p < mimio->pktbuf.q) { - int t = *mimio->pktbuf.p; - switch (t) { - case MIMIO_EV_PENUP: - case MIMIO_EV_PENDOWN: - if (handle_mimio_rx_penupdown(mimio, - t == MIMIO_EV_PENDOWN, - instr, instr_ofst)) - return; /* partial packet */ - break; - - case MIMIO_EV_PENDATA: - if (mimio->pktbuf.q - mimio->pktbuf.p < 6) - /* partial pkt */ - return; - x = *mimio->pktbuf.p ^ *(mimio->pktbuf.p + 1) ^ - *(mimio->pktbuf.p + 2) ^ - *(mimio->pktbuf.p + 3) ^ - *(mimio->pktbuf.p + 4); - if (x != *(mimio->pktbuf.p + 5)) { - dev_dbg(dev, "EV_PENDATA: bad xsum.\n"); - mimio->pktbuf.p += 6; /* skip this event data */ - break; /* decode any remaining events */ - } - x = *(mimio->pktbuf.p + 1); - x <<= 8; - x |= *(mimio->pktbuf.p + 2); - y = *(mimio->pktbuf.p + 3); - y <<= 8; - y |= *(mimio->pktbuf.p + 4); - dev_dbg(dev, "coord: (%d, %d)\n", x, y); - if (instr_ofst[mimio->pktbuf.instr] >= 0) { - int code = BTN_TOOL_PEN + - instr_ofst[mimio->last_pen_down]; -#if 0 - /* Utter hack to ensure we get forwarded _AND_ - * so we can identify when a complete signal is - * received */ - mimio->idev->abs[ABS_Y] = -1; - mimio->idev->abs[ABS_X] = -1; -#endif - /* input_regs(mimio->idev, regs); */ - input_report_abs(mimio->idev, ABS_X, x); - input_report_abs(mimio->idev, ABS_Y, y); - /* fake a penup */ - change_bit(code, mimio->idev->key); - input_report_key(mimio->idev, - code, - DOWNVALUE); - /* always sync here */ - mimio->idev->sync = 0; - input_sync(mimio->idev); - } - mimio->pktbuf.p += 6; - break; - case MIMIO_EV_MEMRESET: - if (mimio->pktbuf.q - mimio->pktbuf.p < 7) - /* partial pkt */ - return; - dev_dbg(dev, "mem-reset.\n"); - /* input_regs(mimio->idev, regs); */ - input_event(mimio->idev, EV_KEY, BTN_0, 1); - input_event(mimio->idev, EV_KEY, BTN_0, 0); - input_sync(mimio->idev); - mimio->pktbuf.p += 7; - break; - case MIMIO_EV_ACC: - if (mimio->pktbuf.q - mimio->pktbuf.p < 4) - /* partial pkt */ - return; - x = *mimio->pktbuf.p ^ *(mimio->pktbuf.p + 1) ^ - *(mimio->pktbuf.p + 2); - if (x != *(mimio->pktbuf.p + 3)) { - dev_dbg(dev, "EV_ACC: bad xsum.\n"); - mimio->pktbuf.p += 4; /* skip this event data */ - break; /* decode any remaining events */ - } - switch (*(mimio->pktbuf.p + 2)) { - case ACC_NEWPAGE: - dev_dbg(&mimio->idev->dev, "new-page.\n"); - /* input_regs(mimio->idev, regs); */ - input_event(mimio->idev, EV_KEY, BTN_1, 1); - input_event(mimio->idev, EV_KEY, BTN_1, 0); - input_sync(mimio->idev); - break; - case ACC_TAGPAGE: - dev_dbg(&mimio->idev->dev, "tag-page.\n"); - /* input_regs(mimio->idev, regs); */ - input_event(mimio->idev, EV_KEY, BTN_2, 1); - input_event(mimio->idev, EV_KEY, BTN_2, 0); - input_sync(mimio->idev); - break; - case ACC_PRINTPAGE: - dev_dbg(&mimio->idev->dev, "print-page.\n"); - /* input_regs(mimio->idev, regs);*/ - input_event(mimio->idev, EV_KEY, BTN_3, 1); - input_event(mimio->idev, EV_KEY, BTN_3, 0); - input_sync(mimio->idev); - break; - case ACC_MAXIMIZE: - dev_dbg(&mimio->idev->dev, - "maximize-window.\n"); - /* input_regs(mimio->idev, regs); */ - input_event(mimio->idev, EV_KEY, BTN_4, 1); - input_event(mimio->idev, EV_KEY, BTN_4, 0); - input_sync(mimio->idev); - break; - case ACC_FINDCTLPNL: - dev_dbg(&mimio->idev->dev, "find-ctl-panel.\n"); - /* input_regs(mimio->idev, regs); */ - input_event(mimio->idev, EV_KEY, BTN_5, 1); - input_event(mimio->idev, EV_KEY, BTN_5, 0); - input_sync(mimio->idev); - break; - case ACC_DONE: - dev_dbg(&mimio->idev->dev, "acc-done.\n"); - /* no event is dispatched to the input - * subsystem for this device event. - */ - break; - default: - dev_dbg(dev, "unknown acc event.\n"); - break; - } - mimio->pktbuf.p += 4; - break; - default: - mimio->pktbuf.p++; - break; - } - } - - /* - * No partial event was received, so reset mimio's pktbuf ptrs. - */ - mimio->pktbuf.p = mimio->pktbuf.q = mimio->pktbuf.buf; -} - -static int mimio_tx(struct mimio *mimio, const char *buf, int nbytes) -{ - int rslt; - int timeout; - unsigned long flags; - DECLARE_WAITQUEUE(wait, current); - - if (!(isvalidtxsize(nbytes))) { - dev_err(&mimio->idev->dev, "invalid arg: nbytes: %d.\n", - nbytes); - return -EINVAL; - } - - /* - * Init the out urb and copy the data to send. - */ - mimio->out.urb->dev = mimio->udev; - mimio->out.urb->transfer_buffer_length = nbytes; - memcpy(mimio->out.urb->transfer_buffer, buf, nbytes); - - /* - * Send the data. - */ - spin_lock_irqsave(&mimio->txlock, flags); - mimio->txflags = MIMIO_TXWAIT; - rslt = usb_submit_urb(mimio->out.urb, GFP_ATOMIC); - spin_unlock_irqrestore(&mimio->txlock, flags); - dev_dbg(&mimio->idev->dev, "rslt: %d.\n", rslt); - - if (rslt) { - dev_err(&mimio->idev->dev, "usb_submit_urb failure: %d.\n", - rslt); - return rslt; - } - - /* - * Wait for completion to be signalled (the mimio_irq_out - * completion routine will or MIMIO_TXDONE in with txflags). - */ - timeout = HZ; - set_current_state(TASK_INTERRUPTIBLE); - add_wait_queue(&mimio->waitq, &wait); - - while (timeout && ((mimio->txflags & MIMIO_TXDONE) == 0)) { - timeout = schedule_timeout(timeout); - rmb(); - } - - if ((mimio->txflags & MIMIO_TXDONE) == 0) - dev_dbg(&mimio->idev->dev, "tx timed out.\n"); - - /* - * Now that completion has been signalled, - * unlink the urb so that it can be recycled. - */ - set_current_state(TASK_RUNNING); - remove_wait_queue(&mimio->waitq, &wait); - usb_unlink_urb(mimio->out.urb); - - return rslt; -} - -static int __init mimio_init(void) -{ - int rslt; - - rslt = usb_register(&mimio_driver); - if (rslt != 0) { - err("%s: usb_register failure: %d", __func__, rslt); - return rslt; - } - - printk(KERN_INFO KBUILD_MODNAME ":" - DRIVER_DESC " " DRIVER_VERSION "\n"); - return rslt; -} - -static void __exit mimio_exit(void) -{ - usb_deregister(&mimio_driver); -} - -module_init(mimio_init); -module_exit(mimio_exit); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/otus/80211core/cagg.c b/drivers/staging/otus/80211core/cagg.c index dbd0a5f..f9514c0 100644 --- a/drivers/staging/otus/80211core/cagg.c +++ b/drivers/staging/otus/80211core/cagg.c @@ -1832,14 +1832,12 @@ u16_t zfAggRxClear(zdev_t* dev, u32_t time) struct agg_tid_rx* zfAggRxEnabled(zdev_t* dev, zbuf_t* buf) { - u16_t dst0, src[3], ac, aid, fragOff; - u8_t up; + u16_t dst0, src[3], aid; u16_t offset = 0; u16_t seq_no; u16_t frameType; u16_t frameCtrl; u16_t frameSubtype; - u32_t tcp_seq; //struct aggSta *agg_sta; #if ZM_AGG_FPGA_REORDERING struct agg_tid_rx *tid_rx; @@ -1864,13 +1862,17 @@ struct agg_tid_rx* zfAggRxEnabled(zdev_t* dev, zbuf_t* buf) return NULL; } #ifdef ZM_ENABLE_PERFORMANCE_EVALUATION - tcp_seq = zmw_rx_buf_readb(dev, buf, 22+36) << 24; - tcp_seq += zmw_rx_buf_readb(dev, buf, 22+37) << 16; - tcp_seq += zmw_rx_buf_readb(dev, buf, 22+38) << 8; - tcp_seq += zmw_rx_buf_readb(dev, buf, 22+39); + { + u32_t tcp_seq; + + tcp_seq = zmw_rx_buf_readb(dev, buf, 22+36) << 24; + tcp_seq += zmw_rx_buf_readb(dev, buf, 22+37) << 16; + tcp_seq += zmw_rx_buf_readb(dev, buf, 22+38) << 8; + tcp_seq += zmw_rx_buf_readb(dev, buf, 22+39); + ZM_SEQ_DEBUG("In %5d, %12u\n", seq_no, tcp_seq); + } #endif - ZM_SEQ_DEBUG("In %5d, %12u\n", seq_no, tcp_seq); dst0 = zmw_rx_buf_readh(dev, buf, offset+4); src[0] = zmw_rx_buf_readh(dev, buf, offset+10); diff --git a/drivers/staging/otus/80211core/ccmd.c b/drivers/staging/otus/80211core/ccmd.c index 8da28ee..3e3d9b5 100644 --- a/drivers/staging/otus/80211core/ccmd.c +++ b/drivers/staging/otus/80211core/ccmd.c @@ -1659,7 +1659,7 @@ void zfiWlanSetPacketTypePromiscuous(zdev_t *dev, u32_t setValue) if (setValue) { /* write register for sniffer mode */ zfHpSetSnifferMode(dev, 1); - zm_msg0_mm(ZM_LV_1, "enalbe sniffer mode"); + zm_msg0_mm(ZM_LV_1, "enable sniffer mode"); } else { zfHpSetSnifferMode(dev, 0); zm_msg0_mm(ZM_LV_0, "disalbe sniffer mode"); diff --git a/drivers/staging/otus/80211core/cfunc.c b/drivers/staging/otus/80211core/cfunc.c index d7c49d7..e0a9f38 100644 --- a/drivers/staging/otus/80211core/cfunc.c +++ b/drivers/staging/otus/80211core/cfunc.c @@ -1194,8 +1194,6 @@ u16_t zfFindMinimumUtilizationChannelIndex(zdev_t* dev, u16_t* array, u16_t coun u8_t i; u16_t tempMinIndex, tempMinValue; - zmw_get_wlan_dev(dev); - i = 1; tempMinIndex = 0; tempMinValue = array[tempMinIndex]; diff --git a/drivers/staging/otus/80211core/cmm.c b/drivers/staging/otus/80211core/cmm.c index a6c1b41..484e753 100644 --- a/drivers/staging/otus/80211core/cmm.c +++ b/drivers/staging/otus/80211core/cmm.c @@ -346,8 +346,6 @@ u16_t zfFindSuperGElement(zdev_t* dev, zbuf_t* buf, u8_t type) u8_t super_feature; u8_t ouiSuperG[6] = {0x00,0x03,0x7f,0x01, 0x01, 0x00}; - zmw_get_wlan_dev(dev); - /* Get offset of first element */ subType = (zmw_rx_buf_readb(dev, buf, 0) >> 4); if ((offset = zgElementOffsetTable[subType]) == 0xff) @@ -411,8 +409,6 @@ u16_t zfFindXRElement(zdev_t* dev, zbuf_t* buf, u8_t type) u8_t id; u8_t ouixr[6] = {0x00,0x03,0x7f,0x03, 0x01, 0x00}; - zmw_get_wlan_dev(dev); - /* Get offset of first element */ subType = (zmw_rx_buf_readb(dev, buf, 0) >> 4); if ((offset = zgElementOffsetTable[subType]) == 0xff) diff --git a/drivers/staging/otus/80211core/cmmsta.c b/drivers/staging/otus/80211core/cmmsta.c index a11d559..c3fd475 100644 --- a/drivers/staging/otus/80211core/cmmsta.c +++ b/drivers/staging/otus/80211core/cmmsta.c @@ -2808,7 +2808,7 @@ void zfStaProcessProbeReq(zdev_t* dev, zbuf_t* buf, u16_t* src) zmw_get_wlan_dev(dev); /* check mode : AP/IBSS */ - if ((wd->wlanMode != ZM_MODE_AP) || (wd->wlanMode != ZM_MODE_IBSS)) + if ((wd->wlanMode != ZM_MODE_AP) && (wd->wlanMode != ZM_MODE_IBSS)) { zm_msg0_mm(ZM_LV_3, "Ignore probe req"); return; @@ -4848,8 +4848,6 @@ u16_t zfStaAddIePowerCap(zdev_t* dev, zbuf_t* buf, u16_t offset) u8_t MaxTxPower; u8_t MinTxPower; - zmw_get_wlan_dev(dev); - /* Element ID */ zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_POWER_CAPABILITY); @@ -5276,7 +5274,6 @@ u16_t zfStaRxValidateFrame(zdev_t* dev, zbuf_t* buf) u8_t da0; //u16_t sa[3]; u16_t ret; - u16_t i; //u8_t sa0; zmw_get_wlan_dev(dev); @@ -5738,8 +5735,6 @@ u16_t zfComputeBssInfoWeightValue(zdev_t *dev, u8_t isBMode, u8_t isHT, u8_t isH u8_t weightOfN40BelowThr = 16; u8_t weightOfN40UpThr = 32; - zmw_get_wlan_dev(dev); - if( isBMode == 0 ) return (signalStrength + weightOfB); // pure b mode , do not add the weight value for this AP ! else diff --git a/drivers/staging/otus/80211core/cpsmgr.c b/drivers/staging/otus/80211core/cpsmgr.c index cf73cac..98e1f0c 100644 --- a/drivers/staging/otus/80211core/cpsmgr.c +++ b/drivers/staging/otus/80211core/cpsmgr.c @@ -381,8 +381,6 @@ static void zfPowerSavingMgrSleepIfIdle(zdev_t *dev) static void zfPowerSavingMgrDisconnectMain(zdev_t* dev) { - zmw_get_wlan_dev(dev); - #ifdef ZM_ENABLE_DISCONNECT_PS switch(wd->sta.psMgr.state) { diff --git a/drivers/staging/otus/80211core/cscanmgr.c b/drivers/staging/otus/80211core/cscanmgr.c index b32835c..be7d8eb 100644 --- a/drivers/staging/otus/80211core/cscanmgr.c +++ b/drivers/staging/otus/80211core/cscanmgr.c @@ -289,8 +289,6 @@ static void zfScanMgrEventSetFreqCompleteCb(zdev_t* dev) static void zfScanMgrEventScanCompleteCb(zdev_t* dev) { - zmw_get_wlan_dev(dev); - if ((zfStaIsConnected(dev)) && (!zfPowerSavingMgrIsSleeping(dev))) { zfSendNullData(dev, 0); diff --git a/drivers/staging/otus/80211core/ctkip.c b/drivers/staging/otus/80211core/ctkip.c index be42f7a..ca07402 100644 --- a/drivers/staging/otus/80211core/ctkip.c +++ b/drivers/staging/otus/80211core/ctkip.c @@ -255,7 +255,8 @@ void zfTkipInit(u8_t* key, u8_t* ta, struct zsTkipSeed* pSeed, u8_t* initIv) zfMemoryCopy(pSeed->ta, ta, 6); zfMemoryCopy(pSeed->tk, key, 16); - iv16 = *initIv++; + iv16 = *initIv; + initIv++; iv16 += *initIv<<8; initIv++; @@ -264,7 +265,7 @@ void zfTkipInit(u8_t* key, u8_t* ta, struct zsTkipSeed* pSeed, u8_t* initIv) for(i=0; i<4; i++) // initiv is little endian { iv32 += *initIv<<(i*8); - *initIv++; + initIv++; } pSeed->iv32 = iv32+1; // Force Recalculating on Tkip Phase1 diff --git a/drivers/staging/otus/80211core/ctxrx.c b/drivers/staging/otus/80211core/ctxrx.c index ac54d5a..4e7f4bd 100644 --- a/drivers/staging/otus/80211core/ctxrx.c +++ b/drivers/staging/otus/80211core/ctxrx.c @@ -536,8 +536,7 @@ void zfProtRspSim(zdev_t* dev, zbuf_t* buf) zm_msg2_rx(ZM_LV_2, "ip1=", dip[1]); //ARP request to 192.168.1.15 - if ((arpOp == 0x0100) && (dip[0] == 0xa8c0) && (dip[1] == 0x0f01)); - { + if ((arpOp == 0x0100) && (dip[0] == 0xa8c0) && (dip[1] == 0x0f01)) { zm_msg0_rx(ZM_LV_2, "ARP"); /* ARP response */ zmw_rx_buf_writeh(dev, buf, 20, 0x0200); @@ -883,7 +882,6 @@ zlError: /************************************************************************/ u16_t zfTxSendEth(zdev_t* dev, zbuf_t* buf, u16_t port, u16_t bufType, u16_t flag) { - u16_t err; //u16_t addrTblSize; //struct zsAddrTbl addrTbl; u16_t removeLen; @@ -905,7 +903,6 @@ u16_t zfTxSendEth(zdev_t* dev, zbuf_t* buf, u16_t port, u16_t bufType, u16_t fla u8_t qosType, keyIdx = 0; u16_t fragOff; u16_t newFlag; - struct zsMicVar* pMicKey; u8_t tkipFrameOffset = 0; zmw_get_wlan_dev(dev); @@ -1693,8 +1690,6 @@ void zfShowTxEAPOL(zdev_t* dev, zbuf_t* buf, u16_t offset) u16_t packetLen, keyInfo, keyLen, keyDataLen, length, Op_Code; u32_t replayCounterH, replayCounterL, vendorId, VendorType; - zmw_get_wlan_dev(dev); - zm_debug_msg1("EAPOL Packet size = ", zfwBufGetSize(dev, buf)); /* EAPOL packet type */ @@ -2437,7 +2432,6 @@ void zfiRecv80211(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo* addInfo) u16_t IvOffset; u8_t keyLen = 5; u8_t iv[3]; - u8_t *wepKey; u8_t keyIdx; IvOffset = offset + ZM_SIZE_OF_WLAN_DATA_HEADER; diff --git a/drivers/staging/otus/80211core/ledmgr.c b/drivers/staging/otus/80211core/ledmgr.c index 1e104a9..eafce0b 100644 --- a/drivers/staging/otus/80211core/ledmgr.c +++ b/drivers/staging/otus/80211core/ledmgr.c @@ -187,7 +187,6 @@ void zfLedCtrlType2_scan(zdev_t* dev); void zfLedCtrlType2(zdev_t* dev) { - u32_t ton, toff, tmp, period; u16_t OperateLED; zmw_get_wlan_dev(dev); diff --git a/drivers/staging/otus/80211core/pub_zfi.h b/drivers/staging/otus/80211core/pub_zfi.h index b7b7f45..5202e5a 100644 --- a/drivers/staging/otus/80211core/pub_zfi.h +++ b/drivers/staging/otus/80211core/pub_zfi.h @@ -814,7 +814,6 @@ extern void zfiRxPerformanceReg(zdev_t* dev, u32_t reg, u32_t rsp); #define ZM_PERFORMANCE_RX_AMSDU(dev, buf, len) #define ZM_PERFORMANCE_RX_FLUSH(dev) #define ZM_PERFORMANCE_RX_CLEAR(dev) -#define ZM_SEQ_DEBUG #define ZM_PERFORMANCE_RX_REORDER(dev) #endif /***** End of section 3 *****/ diff --git a/drivers/staging/otus/Kconfig b/drivers/staging/otus/Kconfig index f6cc262..e918134 100644 --- a/drivers/staging/otus/Kconfig +++ b/drivers/staging/otus/Kconfig @@ -1,6 +1,8 @@ config OTUS tristate "Atheros OTUS 802.11n USB wireless support" depends on USB && WLAN && MAC80211 + select WIRELESS_EXT + select WEXT_PRIV default N ---help--- Enable support for Atheros 802.11n USB hardware: diff --git a/drivers/staging/otus/apdbg.c b/drivers/staging/otus/apdbg.c index 0eb93f1..b59028e 100644 --- a/drivers/staging/otus/apdbg.c +++ b/drivers/staging/otus/apdbg.c @@ -90,8 +90,27 @@ struct zdap_ioctl { #endif -char hex(char); -unsigned char asctohex(char *str); +static char hex(char v) +{ + if (isdigit(v)) + return v - '0'; + else if (isxdigit(v)) + return tolower(v) - 'a' + 10; + else + return 0; +} + +static unsigned char asctohex(char *str) +{ + unsigned char value; + + value = hex(*str) & 0x0f; + value = value << 4; + str++; + value |= hex(*str) & 0x0f; + + return value; +} char *prgname; @@ -109,10 +128,10 @@ int set_ioctl(int sock, struct ifreq *req) int read_reg(int sock, struct ifreq *req) { - struct zdap_ioctl *zdreq = 0; + struct zdap_ioctl *zdreq = NULL; if (!set_ioctl(sock, req)) - return -1; + return -1; /* * zdreq = (struct zdap_ioctl *)req->ifr_data; @@ -125,7 +144,7 @@ int read_reg(int sock, struct ifreq *req) int read_mem(int sock, struct ifreq *req) { - struct zdap_ioctl *zdreq = 0; + struct zdap_ioctl *zdreq = NULL; int i; if (!set_ioctl(sock, req)) @@ -368,7 +387,7 @@ int main(int argc, char **argv) zdreq.addr = addr; zdreq.cmd = ZM_IOCTL_SET_PIBSS_MODE; - } else { + } else { fprintf(stderr, "error action\n"); exit(1); } @@ -380,25 +399,3 @@ fail: exit(0); } -unsigned char asctohex(char *str) -{ - unsigned char value; - - value = hex(*str) & 0x0f; - value = value << 4; - str++; - value |= hex(*str) & 0x0f; - - return value; -} - -char hex(char v) -{ - if (isdigit(v)) - return v - '0'; - else if (isxdigit(v)) - return tolower(v) - 'a' + 10; - else - return 0; -} - diff --git a/drivers/staging/otus/hal/hpmain.c b/drivers/staging/otus/hal/hpmain.c index 94f9cbb..8dff5b9 100644 --- a/drivers/staging/otus/hal/hpmain.c +++ b/drivers/staging/otus/hal/hpmain.c @@ -1316,7 +1316,6 @@ void zfHpSetFrequencyEx(zdev_t* dev, u32_t frequency, u8_t bw40, u8_t extOffset, u8_t initRF) { u32_t cmd[9]; - u32_t cmdB[3]; u16_t ret; u8_t old_band; u8_t new_band; @@ -3434,7 +3433,6 @@ void zfSetPowerCalTable(zdev_t* dev, u32_t frequency, u8_t bw40, u8_t extOffset) /* Write PHY regs 672-703 */ for (i=0; i<128; i+=4) { - u32_t regAddr = 0x9800 + (672 * 4); u32_t val; val = ((u32_t)vpd_chain1[i+3]<<24) | @@ -3485,7 +3483,6 @@ void zfSetPowerCalTable(zdev_t* dev, u32_t frequency, u8_t bw40, u8_t extOffset) /* Write PHY regs 672-703 + 0x1000 */ for (i=0; i<128; i+=4) { - u32_t regAddr = 0x9800 + (672 * 4) + 0x1000; u32_t val; val = ((u32_t)vpd_chain3[i+3]<<24) | @@ -4584,7 +4581,6 @@ void zfHpSetRollCallTable(zdev_t* dev) void zfHpSetTTSIFSTime(zdev_t* dev, u8_t sifs_time) { u32_t reg_value = 0; - zmw_get_wlan_dev(dev); sifs_time &= 0x3f; reg_value = 0x14400b | (((u32_t)sifs_time)<<24); diff --git a/drivers/staging/otus/hal/hpreg.c b/drivers/staging/otus/hal/hpreg.c index d9894fe..178777c 100644 --- a/drivers/staging/otus/hal/hpreg.c +++ b/drivers/staging/otus/hal/hpreg.c @@ -786,45 +786,6 @@ enum { WT1_5760_5800, }; -static REG_DMN_FREQ_BAND regDmn5GhzTurboFreq[] = { - { 5130, 5210, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T1_5130_5210 */ - { 5250, 5330, 5, 6, 40, 40, DFS_FCC3, NO_PSCAN, 0, 0}, /* T1_5250_5330 */ - { 5370, 5490, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T1_5370_5490 */ - { 5530, 5650, 5, 6, 40, 40, DFS_FCC3, NO_PSCAN, 0, 0}, /* T1_5530_5650 */ - - { 5150, 5190, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T1_5150_5190 */ - { 5230, 5310, 5, 6, 40, 40, DFS_FCC3, NO_PSCAN, 0, 0}, /* T1_5230_5310 */ - { 5350, 5470, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T1_5350_5470 */ - { 5510, 5670, 5, 6, 40, 40, DFS_FCC3, NO_PSCAN, 0, 0}, /* T1_5510_5670 */ - - { 5200, 5240, 17, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T1_5200_5240 */ - { 5200, 5240, 23, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T2_5200_5240 */ - { 5210, 5210, 17, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T1_5210_5210 */ - { 5210, 5210, 23, 0, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T2_5210_5210 */ - - { 5280, 5280, 23, 6, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0, 0}, /* T1_5280_5280 */ - { 5280, 5280, 20, 6, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0, 0}, /* T2_5280_5280 */ - { 5250, 5250, 17, 0, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0, 0}, /* T1_5250_5250 */ - { 5290, 5290, 20, 0, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0, 0}, /* T1_5290_5290 */ - { 5250, 5290, 20, 0, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0, 0}, /* T1_5250_5290 */ - { 5250, 5290, 23, 6, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0, 0}, /* T2_5250_5290 */ - - { 5540, 5660, 20, 6, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0, 0}, /* T1_5540_5660 */ - { 5760, 5800, 20, 0, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T1_5760_5800 */ - { 5760, 5800, 30, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T2_5760_5800 */ - - { 5765, 5805, 30, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T1_5765_5805 */ - - /* - * Below are the WWR frequencies - */ - - { 5210, 5250, 15, 0, 40, 40, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0, 0}, /* WT1_5210_5250 */ - { 5290, 5290, 18, 0, 40, 40, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0, 0}, /* WT1_5290_5290 */ - { 5540, 5660, 20, 0, 40, 40, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0, 0}, /* WT1_5540_5660 */ - { 5760, 5800, 20, 0, 40, 40, NO_DFS, PSCAN_WWR, 0, 0}, /* WT1_5760_5800 */ -}; - /* * 2GHz 11b channel tags */ @@ -864,45 +825,6 @@ enum { W2_2484_2484, }; -static REG_DMN_FREQ_BAND regDmn2GhzFreq[] = { - { 2312, 2372, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* F1_2312_2372 */ - { 2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* F2_2312_2372 */ - - { 2412, 2472, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* F1_2412_2472 */ - { 2412, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA, 0, 0}, /* F2_2412_2472 */ - { 2412, 2472, 30, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* F3_2412_2472 */ - - { 2412, 2462, 27, 6, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* F1_2412_2462 */ - { 2412, 2462, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA, 0, 0}, /* F2_2412_2462 */ - { 2432, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* F1_2432_2442 */ - - { 2457, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* F1_2457_2472 */ - - { 2467, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA2 | PSCAN_MKKA, 0, 0}, /* F1_2467_2472 */ - - { 2484, 2484, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* F1_2484_2484 */ - { 2484, 2484, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA | PSCAN_MKKA1 | PSCAN_MKKA2, 0, 0}, /* F2_2484_2484 */ - - { 2512, 2732, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* F1_2512_2732 */ - - /* - * WWR have powers opened up to 20dBm. Limits should often come from CTL/Max powers - */ - - { 2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* W1_2312_2372 */ - { 2412, 2412, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* W1_2412_2412 */ - { 2417, 2432, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* W1_2417_2432 */ - { 2437, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* W1_2437_2442 */ - { 2447, 2457, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* W1_2447_2457 */ - { 2462, 2462, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* W1_2462_2462 */ - { 2467, 2467, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0, 0}, /* W1_2467_2467 */ - { 2467, 2467, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0, 0}, /* W2_2467_2467 */ - { 2472, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0, 0}, /* W1_2472_2472 */ - { 2472, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0, 0}, /* W2_2472_2472 */ - { 2484, 2484, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0, 0}, /* W1_2484_2484 */ - { 2484, 2484, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0, 0}, /* W2_2484_2484 */ -}; - /* * 2GHz 11g channel tags @@ -984,16 +906,6 @@ enum { T1_2512_2732 }; -static REG_DMN_FREQ_BAND regDmn2Ghz11gTurboFreq[] = { - { 2312, 2372, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T1_2312_2372 */ - { 2437, 2437, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T1_2437_2437 */ - { 2437, 2437, 20, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T2_2437_2437 */ - { 2437, 2437, 18, 6, 40, 40, NO_DFS, PSCAN_WWR, 0, 0}, /* T3_2437_2437 */ - { 2512, 2732, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T1_2512_2732 */ -}; - - - /* * 2GHz 11n frequency tags */ @@ -1005,15 +917,6 @@ enum { NG_DEMO_ALL_CHANNELS, }; -static REG_DMN_FREQ_BAND regDmn2Ghz11ngFreq[] = { - { 2422, 2452, 20, 0, 40, 5, NO_DFS, NO_PSCAN, 0, 0}, /* NG1_2422_2452 */ - { 2422, 2452, 27, 0, 40, 5, NO_DFS, NO_PSCAN, 0, 0}, /* NG2_2422_2452 */ - { 2422, 2452, 30, 0, 40, 5, NO_DFS, NO_PSCAN, 0, 0}, /* NG3_2422_2452 */ - - { 2312, 2732, 27, 6, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* NG_DEMO_ALL_CHANNELS */ -}; - - /* * 5GHz 11n frequency tags */ @@ -1050,42 +953,6 @@ enum { NA_DEMO_ALL_CHANNELS, }; -static REG_DMN_FREQ_BAND regDmn5Ghz11naFreq[] = { - /* - * ToDo: This table needs to be completely populated with 5GHz 11n properties - */ - { 5190, 5230, 15, 0, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* NA1_5190_5230 */ - { 5190, 5230, 17, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* NA2_5190_5230 */ - { 5190, 5230, 18, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* NA3_5190_5230 */ - { 5190, 5230, 20, 0, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* NA4_5190_5230 */ - { 5190, 5230, 23, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* NA5_5190_5230 */ - - { 5270, 5270, 23, 6, 40, 40, DFS_FCC3|DFS_ETSI, NO_PSCAN, 0, 1}, /* NA1_5270_5270 */ - - { 5270, 5310, 18, 6, 40, 40, DFS_FCC3|DFS_ETSI, NO_PSCAN, 0, 1}, /* NA1_5270_5310 */ - { 5270, 5310, 20, 0, 40, 40, DFS_FCC3|DFS_ETSI|DFS_MKK4, NO_PSCAN, 0, 1}, /* NA2_5270_5310 */ - { 5270, 5310, 23, 6, 40, 40, DFS_FCC3|DFS_ETSI, NO_PSCAN, 0, 1}, /* NA3_5270_5310 */ - { 5270, 5310, 30, 6, 40, 40, DFS_FCC3|DFS_ETSI, NO_PSCAN, 0, 1}, /* NA4_5270_5310 */ - - { 5310, 5310, 17, 6, 40, 40, DFS_FCC3|DFS_ETSI, NO_PSCAN, 0, 1}, /* NA1_5310_5310 */ - - { 5510, 5630, 30, 6, 40, 40, DFS_FCC3|DFS_ETSI, NO_PSCAN, 0, 1}, /* NA1_5510_5630 */ - - { 5510, 5670, 20, 6, 40, 40, DFS_FCC3|DFS_ETSI|DFS_MKK4, NO_PSCAN, 0, 1}, /* NA1_5510_5670 */ - { 5510, 5670, 27, 0, 40, 40, DFS_FCC3|DFS_ETSI, NO_PSCAN, 0, 1}, /* NA2_5510_5670 */ - { 5510, 5670, 30, 6, 40, 40, DFS_FCC3, NO_PSCAN, 0, 1}, /* NA3_5510_5670 */ - - { 5755, 5795, 17, 0, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* NA1_5755_5795 */ - { 5755, 5795, 20, 6, 40, 40, DFS_ETSI, NO_PSCAN, 0, 0}, /* NA2_5755_5795 */ - { 5755, 5795, 23, 0, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* NA3_5755_5795 */ - { 5755, 5795, 30, 0, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* NA4_5755_5795 */ - { 5755, 5795, 30, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* NA5_5755_5795 */ - - { 5795, 5795, 30, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* NA1_5795_5795 */ - - { 4920, 6100, 30, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* NA_DEMO_ALL_CHANNELS */ -}; - typedef struct regDomain { u16_t regDmnEnum; /* value from EnumRd table */ u8_t conformanceTestLimit; diff --git a/drivers/staging/otus/hal/hprw.c b/drivers/staging/otus/hal/hprw.c index d9fad47..4dbd5fb 100644 --- a/drivers/staging/otus/hal/hprw.c +++ b/drivers/staging/otus/hal/hprw.c @@ -282,7 +282,6 @@ void zfIdlRsp(zdev_t* dev, u32_t* rsp, u16_t rspLen) else if (src == ZM_OID_FLASH_READ) { u32_t datalen; - u16_t i; datalen = (rsp[0] & 255); diff --git a/drivers/staging/otus/ioctl.c b/drivers/staging/otus/ioctl.c index 6808e69..8c47b1a 100644 --- a/drivers/staging/otus/ioctl.c +++ b/drivers/staging/otus/ioctl.c @@ -866,15 +866,15 @@ int usbdrvwext_giwscan(struct net_device *dev, char *current_ev = extra; char *end_buf; int i; - /* struct zsBssList BssList; */ - struct zsBssListV1 *pBssList = kmalloc(sizeof(struct zsBssListV1), - GFP_KERNEL); /* BssList = wd->sta.pBssList; */ /* zmw_get_wlan_dev(dev); */ if (macp->DeviceOpened != 1) return 0; + /* struct zsBssList BssList; */ + struct zsBssListV1 *pBssList = kmalloc(sizeof(struct zsBssListV1), + GFP_KERNEL); if (data->length == 0) end_buf = extra + IW_SCAN_MAX_DATA; else @@ -930,7 +930,7 @@ int usbdrvwext_siwessid(struct net_device *dev, return -EINVAL; if (essid->flags == 1) { - if (essid->length > (IW_ESSID_MAX_SIZE + 1)) + if (essid->length > IW_ESSID_MAX_SIZE) return -E2BIG; if (copy_from_user(&EssidBuf, essid->pointer, essid->length)) @@ -2227,7 +2227,8 @@ int usbdrv_wpa_ioctl(struct net_device *dev, struct athr_wlan_param *zdparm) case ZD_CMD_SCAN_REQ: printk(KERN_ERR "usbdrv_wpa_ioctl: ZD_CMD_SCAN_REQ\n"); break; - case ZD_CMD_SET_GENERIC_ELEMENT: + case ZD_CMD_SET_GENERIC_ELEMENT: { + u8_t len, *wpaie; printk(KERN_ERR "usbdrv_wpa_ioctl:" " ZD_CMD_SET_GENERIC_ELEMENT\n"); @@ -2250,8 +2251,8 @@ int usbdrv_wpa_ioctl(struct net_device *dev, struct athr_wlan_param *zdparm) /* zfiWlanSetWpaIe(dev, zdparm->u.generic_elem.data, * zdparm->u.generic_elem.len); */ - u8_t len = zdparm->u.generic_elem.len; - u8_t *wpaie = (u8_t *)zdparm->u.generic_elem.data; + len = zdparm->u.generic_elem.len; + wpaie = zdparm->u.generic_elem.data; printk(KERN_ERR "wd->ap.wpaLen : % d\n", len); @@ -2273,6 +2274,7 @@ int usbdrv_wpa_ioctl(struct net_device *dev, struct athr_wlan_param *zdparm) * #endif */ break; + } /* #ifdef ZM_HOSTAPD_SUPPORT */ case ZD_CMD_GET_TSC: diff --git a/drivers/staging/otus/usbdrv.c b/drivers/staging/otus/usbdrv.c index b0adbc8..5e6a120 100644 --- a/drivers/staging/otus/usbdrv.c +++ b/drivers/staging/otus/usbdrv.c @@ -829,7 +829,7 @@ int zfLnxRegisterVapDev(struct net_device* parentDev, u16_t vapId) { /* Allocate net device structure */ vap[vapId].dev = alloc_etherdev(0); - printk("Register vap dev=%x\n", (u32_t)vap[vapId].dev); + printk("Register vap dev=%p\n", vap[vapId].dev); if(vap[vapId].dev == NULL) { printk("alloc_etherdev fail\n"); @@ -883,7 +883,7 @@ int zfLnxUnregisterVapDev(struct net_device* parentDev, u16_t vapId) printk("Unregister VAP dev : %s\n", vap[vapId].dev->name); if(vap[vapId].dev != NULL) { - printk("Unregister vap dev=%x\n", (u32_t)vap[vapId].dev); + printk("Unregister vap dev=%p\n", vap[vapId].dev); // //unregister_netdevice(wds[wdsId].dev); unregister_netdev(vap[vapId].dev); diff --git a/drivers/staging/otus/wrap_pkt.c b/drivers/staging/otus/wrap_pkt.c index 75bb952..a2f5cb1 100644 --- a/drivers/staging/otus/wrap_pkt.c +++ b/drivers/staging/otus/wrap_pkt.c @@ -58,7 +58,7 @@ void zfLnxRecv80211(zdev_t *dev, zbuf_t *buf, struct zsAdditionInfo *addInfo) skb1 = skb_copy(buf, GFP_ATOMIC); if (skb1 != NULL) { skb1->dev = dev; - skb1->mac_header = skb1->data; + skb_reset_mac_header(skb1); skb1->ip_summed = CHECKSUM_NONE; skb1->pkt_type = PACKET_OTHERHOST; /* ETH_P_80211_RAW */ @@ -85,13 +85,7 @@ void zfLnxRecvEth(zdev_t *dev, zbuf_t *buf, u16_t port) /* new_buf = dev_alloc_skb(2048); */ new_buf = dev_alloc_skb(buf->len); -#ifdef NET_SKBUFF_DATA_USES_OFFSET - new_buf->tail = 0; - new_buf->len = 0; -#else - new_buf->tail = new_buf->data; - new_buf->len = 0; -#endif + skb_reset_tail_pointer(new_buf); skb_put(new_buf, buf->len); memcpy(new_buf->data, buf->data, buf->len); diff --git a/drivers/staging/otus/zdusb.c b/drivers/staging/otus/zdusb.c index 2a6d937..4cd9b7f 100644 --- a/drivers/staging/otus/zdusb.c +++ b/drivers/staging/otus/zdusb.c @@ -45,7 +45,7 @@ MODULE_LICENSE("Dual BSD/GPL"); static const char driver_name[] = "Otus"; /* table of devices that work with this driver */ -static struct usb_device_id zd1221_ids [] = { +static const struct usb_device_id zd1221_ids[] = { { USB_DEVICE(VENDOR_ATHR, PRODUCT_AR9170) }, { USB_DEVICE(VENDOR_DLINK, PRODUCT_DWA160A) }, { USB_DEVICE(VENDOR_NETGEAR, PRODUCT_WNDA3100) }, diff --git a/drivers/staging/p9auth/Kconfig b/drivers/staging/p9auth/Kconfig deleted file mode 100644 index d1c66d2..0000000 --- a/drivers/staging/p9auth/Kconfig +++ /dev/null @@ -1,9 +0,0 @@ -config PLAN9AUTH - tristate "Plan 9 style capability device implementation" - default n - depends on CRYPTO - help - This module implements the Plan 9 style capability device. - - To compile this driver as a module, choose - M here: the module will be called p9auth. diff --git a/drivers/staging/p9auth/Makefile b/drivers/staging/p9auth/Makefile deleted file mode 100644 index 3ebf6ff..0000000 --- a/drivers/staging/p9auth/Makefile +++ /dev/null @@ -1 +0,0 @@ -obj-$(CONFIG_PLAN9AUTH) += p9auth.o diff --git a/drivers/staging/p9auth/p9auth.c b/drivers/staging/p9auth/p9auth.c deleted file mode 100644 index db79626..0000000 --- a/drivers/staging/p9auth/p9auth.c +++ /dev/null @@ -1,408 +0,0 @@ -/* - * Plan 9 style capability device implementation for the Linux Kernel - * - * Copyright 2008, 2009 Ashwin Ganti <ashwin.ganti@gmail.com> - * - * Released under the GPLv2 - * - */ -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/moduleparam.h> -#include <linux/slab.h> -#include <linux/fs.h> -#include <linux/errno.h> -#include <linux/fcntl.h> -#include <linux/cdev.h> -#include <linux/uaccess.h> -#include <linux/list.h> -#include <linux/mm.h> -#include <linux/string.h> -#include <linux/crypto.h> -#include <linux/highmem.h> -#include <linux/scatterlist.h> -#include <linux/sched.h> -#include <linux/cred.h> - -#ifndef CAP_MAJOR -#define CAP_MAJOR 0 -#endif - -#ifndef CAP_NR_DEVS -#define CAP_NR_DEVS 2 /* caphash and capuse */ -#endif - -#ifndef CAP_NODE_SIZE -#define CAP_NODE_SIZE 20 -#endif - -#define MAX_DIGEST_SIZE 20 - -struct cap_node { - char data[CAP_NODE_SIZE]; - struct list_head list; -}; - -struct cap_dev { - struct cap_node *head; - int node_size; - unsigned long size; - struct semaphore sem; - struct cdev cdev; -}; - -static int cap_major = CAP_MAJOR; -static int cap_minor; -static int cap_nr_devs = CAP_NR_DEVS; -static int cap_node_size = CAP_NODE_SIZE; - -module_param(cap_major, int, S_IRUGO); -module_param(cap_minor, int, S_IRUGO); -module_param(cap_nr_devs, int, S_IRUGO); - -MODULE_AUTHOR("Ashwin Ganti"); -MODULE_LICENSE("GPL"); - -static struct cap_dev *cap_devices; - -static void hexdump(unsigned char *buf, unsigned int len) -{ - while (len--) - printk("%02x", *buf++); - printk("\n"); -} - -static char *cap_hash(char *plain_text, unsigned int plain_text_size, - char *key, unsigned int key_size) -{ - struct scatterlist sg; - char *result; - struct crypto_hash *tfm; - struct hash_desc desc; - int ret; - - tfm = crypto_alloc_hash("hmac(sha1)", 0, CRYPTO_ALG_ASYNC); - if (IS_ERR(tfm)) { - printk(KERN_ERR - "failed to load transform for hmac(sha1): %ld\n", - PTR_ERR(tfm)); - return NULL; - } - - desc.tfm = tfm; - desc.flags = 0; - - result = kzalloc(MAX_DIGEST_SIZE, GFP_KERNEL); - if (!result) { - printk(KERN_ERR "out of memory!\n"); - goto out; - } - - sg_set_buf(&sg, plain_text, plain_text_size); - - ret = crypto_hash_setkey(tfm, key, key_size); - if (ret) { - printk(KERN_ERR "setkey() failed ret=%d\n", ret); - kfree(result); - result = NULL; - goto out; - } - - ret = crypto_hash_digest(&desc, &sg, plain_text_size, result); - if (ret) { - printk(KERN_ERR "digest () failed ret=%d\n", ret); - kfree(result); - result = NULL; - goto out; - } - - printk(KERN_DEBUG "crypto hash digest size %d\n", - crypto_hash_digestsize(tfm)); - hexdump(result, MAX_DIGEST_SIZE); - -out: - crypto_free_hash(tfm); - return result; -} - -static int cap_trim(struct cap_dev *dev) -{ - struct cap_node *tmp; - struct list_head *pos, *q; - if (dev->head != NULL) { - list_for_each_safe(pos, q, &(dev->head->list)) { - tmp = list_entry(pos, struct cap_node, list); - list_del(pos); - kfree(tmp); - } - } - return 0; -} - -static int cap_open(struct inode *inode, struct file *filp) -{ - struct cap_dev *dev; - dev = container_of(inode->i_cdev, struct cap_dev, cdev); - filp->private_data = dev; - - /* trim to 0 the length of the device if open was write-only */ - if ((filp->f_flags & O_ACCMODE) == O_WRONLY) { - if (down_interruptible(&dev->sem)) - return -ERESTARTSYS; - cap_trim(dev); - up(&dev->sem); - } - /* initialise the head if it is NULL */ - if (dev->head == NULL) { - dev->head = kmalloc(sizeof(struct cap_node), GFP_KERNEL); - INIT_LIST_HEAD(&(dev->head->list)); - } - return 0; -} - -static int cap_release(struct inode *inode, struct file *filp) -{ - return 0; -} - -static ssize_t cap_write(struct file *filp, const char __user *buf, - size_t count, loff_t *f_pos) -{ - struct cap_node *node_ptr, *tmp; - struct list_head *pos; - struct cap_dev *dev = filp->private_data; - ssize_t retval = -ENOMEM; - struct cred *new; - int len, target_int, source_int, flag = 0; - char *user_buf, *user_buf_running, *source_user, *target_user, - *rand_str, *hash_str, *result; - - if (down_interruptible(&dev->sem)) - return -ERESTARTSYS; - - user_buf_running = NULL; - hash_str = NULL; - node_ptr = kmalloc(sizeof(struct cap_node), GFP_KERNEL); - user_buf = kzalloc(count+1, GFP_KERNEL); - if (!node_ptr || !user_buf) - goto out; - - if (copy_from_user(user_buf, buf, count)) { - retval = -EFAULT; - goto out; - } - - /* - * If the minor number is 0 ( /dev/caphash ) then simply add the - * hashed capability supplied by the user to the list of hashes - */ - if (0 == iminor(filp->f_dentry->d_inode)) { - if (count > CAP_NODE_SIZE) { - retval = -EINVAL; - goto out; - } - printk(KERN_INFO "Capability being written to /dev/caphash : \n"); - hexdump(user_buf, count); - memcpy(node_ptr->data, user_buf, count); - list_add(&(node_ptr->list), &(dev->head->list)); - node_ptr = NULL; - } else { - char *tmpu; - if (!cap_devices[0].head || - list_empty(&(cap_devices[0].head->list))) { - retval = -EINVAL; - goto out; - } - /* - * break the supplied string into tokens with @ as the - * delimiter If the string is "user1@user2@randomstring" we - * need to split it and hash 'user1@user2' using 'randomstring' - * as the key. - */ - tmpu = user_buf_running = kstrdup(user_buf, GFP_KERNEL); - source_user = strsep(&tmpu, "@"); - target_user = strsep(&tmpu, "@"); - rand_str = tmpu; - if (!source_user || !target_user || !rand_str) { - retval = -EINVAL; - goto out; - } - - /* hash the string user1@user2 with rand_str as the key */ - len = strlen(source_user) + strlen(target_user) + 1; - /* src, @, len, \0 */ - hash_str = kzalloc(len+1, GFP_KERNEL); - strcat(hash_str, source_user); - strcat(hash_str, "@"); - strcat(hash_str, target_user); - - printk(KERN_ALERT "the source user is %s \n", source_user); - printk(KERN_ALERT "the target user is %s \n", target_user); - - result = cap_hash(hash_str, len, rand_str, strlen(rand_str)); - if (NULL == result) { - retval = -EFAULT; - goto out; - } - memcpy(node_ptr->data, result, CAP_NODE_SIZE); /* why? */ - /* Change the process's uid if the hash is present in the - * list of hashes - */ - list_for_each(pos, &(cap_devices->head->list)) { - /* - * Change the user id of the process if the hashes - * match - */ - if (0 == - memcmp(result, - list_entry(pos, struct cap_node, - list)->data, - CAP_NODE_SIZE)) { - target_int = (unsigned int) - simple_strtol(target_user, NULL, 0); - source_int = (unsigned int) - simple_strtol(source_user, NULL, 0); - flag = 1; - - /* - * Check whether the process writing to capuse - * is actually owned by the source owner - */ - if (source_int != current_uid()) { - printk(KERN_ALERT - "Process is not owned by the source user of the capability.\n"); - retval = -EFAULT; - goto out; - } - /* - * What all id's need to be changed here? uid, - * euid, fsid, savedids ?? Currently I am - * changing the effective user id since most of - * the authorisation decisions are based on it - */ - new = prepare_creds(); - if (!new) { - retval = -ENOMEM; - goto out; - } - new->uid = (uid_t) target_int; - new->euid = (uid_t) target_int; - retval = commit_creds(new); - if (retval) - goto out; - - /* - * Remove the capability from the list and - * break - */ - tmp = list_entry(pos, struct cap_node, list); - list_del(pos); - kfree(tmp); - break; - } - } - if (0 == flag) { - /* - * The capability is not present in the list of the - * hashes stored, hence return failure - */ - printk(KERN_ALERT - "Invalid capabiliy written to /dev/capuse \n"); - retval = -EFAULT; - goto out; - } - } - *f_pos += count; - retval = count; - /* update the size */ - if (dev->size < *f_pos) - dev->size = *f_pos; - -out: - kfree(node_ptr); - kfree(user_buf); - kfree(user_buf_running); - kfree(hash_str); - up(&dev->sem); - return retval; -} - -static const struct file_operations cap_fops = { - .owner = THIS_MODULE, - .write = cap_write, - .open = cap_open, - .release = cap_release, -}; - -/* no __exit here because it can be called by the init function */ -static void cap_cleanup_module(void) -{ - int i; - dev_t devno = MKDEV(cap_major, cap_minor); - if (cap_devices) { - for (i = 0; i < cap_nr_devs; i++) { - cap_trim(cap_devices + i); - cdev_del(&cap_devices[i].cdev); - } - kfree(cap_devices); - } - unregister_chrdev_region(devno, cap_nr_devs); - -} - -static void cap_setup_cdev(struct cap_dev *dev, int index) -{ - int err, devno = MKDEV(cap_major, cap_minor + index); - cdev_init(&dev->cdev, &cap_fops); - dev->cdev.owner = THIS_MODULE; - dev->cdev.ops = &cap_fops; - err = cdev_add(&dev->cdev, devno, 1); - if (err) - printk(KERN_NOTICE "Error %d adding cap%d", err, index); -} - -static int __init cap_init_module(void) -{ - int result, i; - dev_t dev = 0; - - if (cap_major) { - dev = MKDEV(cap_major, cap_minor); - result = register_chrdev_region(dev, cap_nr_devs, "cap"); - } else { - result = alloc_chrdev_region(&dev, cap_minor, cap_nr_devs, - "cap"); - cap_major = MAJOR(dev); - } - - if (result < 0) { - printk(KERN_WARNING "cap: can't get major %d\n", - cap_major); - return result; - } - - cap_devices = kzalloc(cap_nr_devs * sizeof(struct cap_dev), - GFP_KERNEL); - if (!cap_devices) { - result = -ENOMEM; - goto fail; - } - - /* Initialize each device. */ - for (i = 0; i < cap_nr_devs; i++) { - cap_devices[i].node_size = cap_node_size; - init_MUTEX(&cap_devices[i].sem); - cap_setup_cdev(&cap_devices[i], i); - } - - return 0; - -fail: - cap_cleanup_module(); - return result; -} - -module_init(cap_init_module); -module_exit(cap_cleanup_module); - - diff --git a/drivers/staging/panel/panel.c b/drivers/staging/panel/panel.c index 95c93e8..377884f 100644 --- a/drivers/staging/panel/panel.c +++ b/drivers/staging/panel/panel.c @@ -41,7 +41,6 @@ #include <linux/signal.h> #include <linux/sched.h> #include <linux/spinlock.h> -#include <linux/smp_lock.h> #include <linux/interrupt.h> #include <linux/miscdevice.h> #include <linux/slab.h> diff --git a/drivers/staging/phison/phison.c b/drivers/staging/phison/phison.c index fcba78d..0c495ea 100644 --- a/drivers/staging/phison/phison.c +++ b/drivers/staging/phison/phison.c @@ -69,7 +69,7 @@ static int phison_init_one(struct pci_dev *pdev, const struct pci_device_id *id) return ret; } -static struct pci_device_id phison_pci_tbl[] = { +static const struct pci_device_id phison_pci_tbl[] = { { PCI_VENDOR_ID_PHISON, PCI_DEVICE_ID_PS5000, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE << 8, 0xffff00, 0 }, { 0, }, diff --git a/drivers/staging/pohmelfs/inode.c b/drivers/staging/pohmelfs/inode.c index 11fc4d5..6327552 100644 --- a/drivers/staging/pohmelfs/inode.c +++ b/drivers/staging/pohmelfs/inode.c @@ -36,6 +36,7 @@ #define POHMELFS_MAGIC_NUM 0x504f482e static struct kmem_cache *pohmelfs_inode_cache; +static atomic_t psb_bdi_num = ATOMIC_INIT(0); /* * Removes inode from all trees, drops local name cache and removes all queued @@ -322,7 +323,7 @@ int pohmelfs_write_create_inode(struct pohmelfs_inode *pi) t = netfs_trans_alloc(psb, err + 1, 0, 0); if (!t) { err = -ENOMEM; - goto err_out_put; + goto err_out_exit; } t->complete = pohmelfs_write_inode_complete; t->private = igrab(inode); @@ -395,7 +396,8 @@ int pohmelfs_remove_child(struct pohmelfs_inode *pi, struct pohmelfs_name *n) /* * Writeback for given inode. */ -static int pohmelfs_write_inode(struct inode *inode, int sync) +static int pohmelfs_write_inode(struct inode *inode, + struct writeback_control *wbc) { struct pohmelfs_inode *pi = POHMELFS_I(inode); @@ -1331,6 +1333,8 @@ static void pohmelfs_put_super(struct super_block *sb) pohmelfs_crypto_exit(psb); pohmelfs_state_exit(psb); + bdi_destroy(&psb->bdi); + kfree(psb); sb->s_fs_info = NULL; } @@ -1767,8 +1771,7 @@ static int pohmelfs_show_stats(struct seq_file *m, struct vfsmount *mnt) seq_printf(m, "%u ", ctl->idx); if (ctl->addr.sa_family == AF_INET) { struct sockaddr_in *sin = (struct sockaddr_in *)&st->ctl.addr; - /* seq_printf(m, "%pi4:%u", &sin->sin_addr.s_addr, ntohs(sin->sin_port)); */ - seq_printf(m, "%u.%u.%u.%u:%u", NIPQUAD(sin->sin_addr.s_addr), ntohs(sin->sin_port)); + seq_printf(m, "%pI4:%u", &sin->sin_addr.s_addr, ntohs(sin->sin_port)); } else if (ctl->addr.sa_family == AF_INET6) { struct sockaddr_in6 *sin = (struct sockaddr_in6 *)&st->ctl.addr; seq_printf(m, "%pi6:%u", &sin->sin6_addr, ntohs(sin->sin6_port)); @@ -1815,11 +1818,22 @@ static int pohmelfs_fill_super(struct super_block *sb, void *data, int silent) if (!psb) goto err_out_exit; + err = bdi_init(&psb->bdi); + if (err) + goto err_out_free_sb; + + err = bdi_register(&psb->bdi, NULL, "pfs-%d", atomic_inc_return(&psb_bdi_num)); + if (err) { + bdi_destroy(&psb->bdi); + goto err_out_free_sb; + } + sb->s_fs_info = psb; sb->s_op = &pohmelfs_sb_ops; sb->s_magic = POHMELFS_MAGIC_NUM; sb->s_maxbytes = MAX_LFS_FILESIZE; sb->s_blocksize = PAGE_SIZE; + sb->s_bdi = &psb->bdi; psb->sb = sb; @@ -1863,11 +1877,11 @@ static int pohmelfs_fill_super(struct super_block *sb, void *data, int silent) err = pohmelfs_parse_options((char *) data, psb, 0); if (err) - goto err_out_free_sb; + goto err_out_free_bdi; err = pohmelfs_copy_crypto(psb); if (err) - goto err_out_free_sb; + goto err_out_free_bdi; err = pohmelfs_state_init(psb); if (err) @@ -1916,6 +1930,8 @@ err_out_state_exit: err_out_free_strings: kfree(psb->cipher_string); kfree(psb->hash_string); +err_out_free_bdi: + bdi_destroy(&psb->bdi); err_out_free_sb: kfree(psb); err_out_exit: diff --git a/drivers/staging/pohmelfs/netfs.h b/drivers/staging/pohmelfs/netfs.h index 623a07d..01cba00 100644 --- a/drivers/staging/pohmelfs/netfs.h +++ b/drivers/staging/pohmelfs/netfs.h @@ -18,6 +18,7 @@ #include <linux/types.h> #include <linux/connector.h> +#include <linux/backing-dev.h> #define POHMELFS_CN_IDX 5 #define POHMELFS_CN_VAL 0 @@ -624,6 +625,8 @@ struct pohmelfs_sb { struct super_block *sb; + struct backing_dev_info bdi; + /* * Algorithm strings. */ diff --git a/drivers/staging/quatech_usb2/quatech_usb2.c b/drivers/staging/quatech_usb2/quatech_usb2.c index f7726f1..1561f74 100644 --- a/drivers/staging/quatech_usb2/quatech_usb2.c +++ b/drivers/staging/quatech_usb2/quatech_usb2.c @@ -116,7 +116,7 @@ static int debug; #define FOURTHCHAR ((unsigned char *)(urb->transfer_buffer))[i + 3] #define FIFTHCHAR ((unsigned char *)(urb->transfer_buffer))[i + 4] -static struct usb_device_id quausb2_id_table[] = { +static const struct usb_device_id quausb2_id_table[] = { {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_SSU2_100)}, {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_DSU2_100)}, {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_DSU2_400)}, diff --git a/drivers/staging/ramzswap/Kconfig b/drivers/staging/ramzswap/Kconfig index 24e2569..127b3c6 100644 --- a/drivers/staging/ramzswap/Kconfig +++ b/drivers/staging/ramzswap/Kconfig @@ -5,7 +5,7 @@ config RAMZSWAP select LZO_DECOMPRESS default n help - Creates virtual block devices which can be used (only) as a swap + Creates virtual block devices which can (only) be used as swap disks. Pages swapped to these disks are compressed and stored in memory itself. diff --git a/drivers/staging/ramzswap/ramzswap.txt b/drivers/staging/ramzswap/ramzswap.txt index e9f1619..9694acf 100644 --- a/drivers/staging/ramzswap/ramzswap.txt +++ b/drivers/staging/ramzswap/ramzswap.txt @@ -5,9 +5,9 @@ Project home: http://compcache.googlecode.com/ * Introduction -It creates RAM based block devices which can be used (only) as swap disks. -Pages swapped to these devices are compressed and stored in memory itself. -See project home for use cases, performance numbers and a lot more. +The ramzswap module creates RAM based block devices which can (only) be used as +swap disks. Pages swapped to these devices are compressed and stored in memory +itself. See project home for use cases, performance numbers and a lot more. Individual ramzswap devices are configured and initialized using rzscontrol userspace utility as shown in examples below. See rzscontrol man page for more diff --git a/drivers/staging/ramzswap/ramzswap_drv.c b/drivers/staging/ramzswap/ramzswap_drv.c index 989fac5..5e422e2 100644 --- a/drivers/staging/ramzswap/ramzswap_drv.c +++ b/drivers/staging/ramzswap/ramzswap_drv.c @@ -1,7 +1,7 @@ /* * Compressed RAM based swap device * - * Copyright (C) 2008, 2009 Nitin Gupta + * Copyright (C) 2008, 2009, 2010 Nitin Gupta * * This code is released using a dual license strategy: BSD/GPL * You can choose the licence that better fits your requirements. @@ -24,12 +24,10 @@ #include <linux/genhd.h> #include <linux/highmem.h> #include <linux/lzo.h> -#include <linux/mutex.h> #include <linux/string.h> #include <linux/swap.h> #include <linux/swapops.h> #include <linux/vmalloc.h> -#include <linux/version.h> #include "ramzswap_drv.h" @@ -222,7 +220,7 @@ out: return ret; } -void ramzswap_ioctl_get_stats(struct ramzswap *rzs, +static void ramzswap_ioctl_get_stats(struct ramzswap *rzs, struct ramzswap_ioctl_stats *s) { strncpy(s->backing_swap_name, rzs->backing_swap_name, @@ -240,7 +238,8 @@ void ramzswap_ioctl_get_stats(struct ramzswap *rzs, mem_used = xv_get_total_size_bytes(rzs->mem_pool) + (rs->pages_expand << PAGE_SHIFT); - succ_writes = rs->num_writes - rs->failed_writes; + succ_writes = rzs_stat64_read(rzs, &rs->num_writes) - + rzs_stat64_read(rzs, &rs->failed_writes); if (succ_writes && rs->pages_stored) { good_compress_perc = rs->good_compress * 100 @@ -249,11 +248,12 @@ void ramzswap_ioctl_get_stats(struct ramzswap *rzs, / rs->pages_stored; } - s->num_reads = rs->num_reads; - s->num_writes = rs->num_writes; - s->failed_reads = rs->failed_reads; - s->failed_writes = rs->failed_writes; - s->invalid_io = rs->invalid_io; + s->num_reads = rzs_stat64_read(rzs, &rs->num_reads); + s->num_writes = rzs_stat64_read(rzs, &rs->num_writes); + s->failed_reads = rzs_stat64_read(rzs, &rs->failed_reads); + s->failed_writes = rzs_stat64_read(rzs, &rs->failed_writes); + s->invalid_io = rzs_stat64_read(rzs, &rs->invalid_io); + s->notify_free = rzs_stat64_read(rzs, &rs->notify_free); s->pages_zero = rs->pages_zero; s->good_compress_pct = good_compress_perc; @@ -265,8 +265,8 @@ void ramzswap_ioctl_get_stats(struct ramzswap *rzs, s->compr_data_size = rs->compr_size; s->mem_used_total = mem_used; - s->bdev_num_reads = rs->bdev_num_reads; - s->bdev_num_writes = rs->bdev_num_writes; + s->bdev_num_reads = rzs_stat64_read(rzs, &rs->bdev_num_reads); + s->bdev_num_writes = rzs_stat64_read(rzs, &rs->bdev_num_writes); } #endif /* CONFIG_RAMZSWAP_STATS */ } @@ -502,6 +502,14 @@ static int setup_backing_swap(struct ramzswap *rzs) goto bad_param; } disksize = i_size_read(inode); + /* + * Can happen if user gives an extended partition as + * backing swap or simply a bad disk. + */ + if (!disksize) { + pr_err("Error reading backing swap size.\n"); + goto bad_param; + } } else if (S_ISREG(inode->i_mode)) { bdev = inode->i_sb->s_bdev; if (IS_SWAPFILE(inode)) { @@ -519,7 +527,6 @@ static int setup_backing_swap(struct ramzswap *rzs) rzs->swap_file = swap_file; rzs->backing_swap = bdev; rzs->disksize = disksize; - BUG_ON(!rzs->disksize); return 0; @@ -537,7 +544,7 @@ out: * Map logical page number 'pagenum' to physical page number * on backing swap device. For block device, this is a nop. */ -u32 map_backing_swap_page(struct ramzswap *rzs, u32 pagenum) +static u32 map_backing_swap_page(struct ramzswap *rzs, u32 pagenum) { u32 skip_pages, entries_per_page; size_t delta, se_offset, skipped; @@ -593,9 +600,13 @@ static void ramzswap_free_page(struct ramzswap *rzs, size_t index) u32 offset = rzs->table[index].offset; if (unlikely(!page)) { + /* + * No memory is allocated for zero filled pages. + * Simply clear zero page flag. + */ if (rzs_test_flag(rzs, index, RZS_ZERO)) { rzs_clear_flag(rzs, index, RZS_ZERO); - stat_dec(rzs->stats.pages_zero); + rzs_stat_dec(&rzs->stats.pages_zero); } return; } @@ -604,7 +615,7 @@ static void ramzswap_free_page(struct ramzswap *rzs, size_t index) clen = PAGE_SIZE; __free_page(page); rzs_clear_flag(rzs, index, RZS_UNCOMPRESSED); - stat_dec(rzs->stats.pages_expand); + rzs_stat_dec(&rzs->stats.pages_expand); goto out; } @@ -614,11 +625,11 @@ static void ramzswap_free_page(struct ramzswap *rzs, size_t index) xv_free(rzs->mem_pool, page, offset); if (clen <= PAGE_SIZE / 2) - stat_dec(rzs->stats.good_compress); + rzs_stat_dec(&rzs->stats.good_compress); out: rzs->stats.compr_size -= clen; - stat_dec(rzs->stats.pages_stored); + rzs_stat_dec(&rzs->stats.pages_stored); rzs->table[index].page = NULL; rzs->table[index].offset = 0; @@ -664,7 +675,6 @@ static int handle_uncompressed_page(struct ramzswap *rzs, struct bio *bio) return 0; } - /* * Called when request page is not present in ramzswap. * Its either in backing swap device (if present) or @@ -680,8 +690,8 @@ static int handle_ramzswap_fault(struct ramzswap *rzs, struct bio *bio) */ if (rzs->backing_swap) { u32 pagenum; - stat_dec(rzs->stats.num_reads); - stat_inc(rzs->stats.bdev_num_reads); + rzs_stat64_dec(rzs, &rzs->stats.num_reads); + rzs_stat64_inc(rzs, &rzs->stats.bdev_num_reads); bio->bi_bdev = rzs->backing_swap; /* @@ -719,7 +729,7 @@ static int ramzswap_read(struct ramzswap *rzs, struct bio *bio) struct zobj_header *zheader; unsigned char *user_mem, *cmem; - stat_inc(rzs->stats.num_reads); + rzs_stat64_inc(rzs, &rzs->stats.num_reads); page = bio->bi_io_vec[0].bv_page; index = bio->bi_sector >> SECTORS_PER_PAGE_SHIFT; @@ -731,7 +741,7 @@ static int ramzswap_read(struct ramzswap *rzs, struct bio *bio) if (!rzs->table[index].page) return handle_ramzswap_fault(rzs, bio); - /* Page is stored uncompressed since its incompressible */ + /* Page is stored uncompressed since it's incompressible */ if (unlikely(rzs_test_flag(rzs, index, RZS_UNCOMPRESSED))) return handle_uncompressed_page(rzs, bio); @@ -753,7 +763,7 @@ static int ramzswap_read(struct ramzswap *rzs, struct bio *bio) if (unlikely(ret != LZO_E_OK)) { pr_err("Decompression failed! err=%d, page=%u\n", ret, index); - stat_inc(rzs->stats.failed_reads); + rzs_stat64_inc(rzs, &rzs->stats.failed_reads); goto out; } @@ -777,7 +787,7 @@ static int ramzswap_write(struct ramzswap *rzs, struct bio *bio) struct page *page, *page_store; unsigned char *user_mem, *cmem, *src; - stat_inc(rzs->stats.num_writes); + rzs_stat64_inc(rzs, &rzs->stats.num_writes); page = bio->bi_io_vec[0].bv_page; index = bio->bi_sector >> SECTORS_PER_PAGE_SHIFT; @@ -789,25 +799,16 @@ static int ramzswap_write(struct ramzswap *rzs, struct bio *bio) * is no longer referenced by any process. So, its now safe * to free the memory that was allocated for this page. */ - if (rzs->table[index].page) + if (rzs->table[index].page || rzs_test_flag(rzs, index, RZS_ZERO)) ramzswap_free_page(rzs, index); - /* - * No memory ia allocated for zero filled pages. - * Simply clear zero page flag. - */ - if (rzs_test_flag(rzs, index, RZS_ZERO)) { - stat_dec(rzs->stats.pages_zero); - rzs_clear_flag(rzs, index, RZS_ZERO); - } - mutex_lock(&rzs->lock); user_mem = kmap_atomic(page, KM_USER0); if (page_zero_filled(user_mem)) { kunmap_atomic(user_mem, KM_USER0); mutex_unlock(&rzs->lock); - stat_inc(rzs->stats.pages_zero); + rzs_stat_inc(&rzs->stats.pages_zero); rzs_set_flag(rzs, index, RZS_ZERO); set_bit(BIO_UPTODATE, &bio->bi_flags); @@ -831,7 +832,7 @@ static int ramzswap_write(struct ramzswap *rzs, struct bio *bio) if (unlikely(ret != LZO_E_OK)) { mutex_unlock(&rzs->lock); pr_err("Compression failed! err=%d\n", ret); - stat_inc(rzs->stats.failed_writes); + rzs_stat64_inc(rzs, &rzs->stats.failed_writes); goto out; } @@ -854,13 +855,13 @@ static int ramzswap_write(struct ramzswap *rzs, struct bio *bio) mutex_unlock(&rzs->lock); pr_info("Error allocating memory for incompressible " "page: %u\n", index); - stat_inc(rzs->stats.failed_writes); + rzs_stat64_inc(rzs, &rzs->stats.failed_writes); goto out; } offset = 0; rzs_set_flag(rzs, index, RZS_UNCOMPRESSED); - stat_inc(rzs->stats.pages_expand); + rzs_stat_inc(&rzs->stats.pages_expand); rzs->table[index].page = page_store; src = kmap_atomic(page, KM_USER0); goto memstore; @@ -872,7 +873,7 @@ static int ramzswap_write(struct ramzswap *rzs, struct bio *bio) mutex_unlock(&rzs->lock); pr_info("Error allocating memory for compressed " "page: %u, size=%zu\n", index, clen); - stat_inc(rzs->stats.failed_writes); + rzs_stat64_inc(rzs, &rzs->stats.failed_writes); if (rzs->backing_swap) fwd_write_request = 1; goto out; @@ -901,9 +902,9 @@ memstore: /* Update stats */ rzs->stats.compr_size += clen; - stat_inc(rzs->stats.pages_stored); + rzs_stat_inc(&rzs->stats.pages_stored); if (clen <= PAGE_SIZE / 2) - stat_inc(rzs->stats.good_compress); + rzs_stat_inc(&rzs->stats.good_compress); mutex_unlock(&rzs->lock); @@ -913,7 +914,7 @@ memstore: out: if (fwd_write_request) { - stat_inc(rzs->stats.bdev_num_writes); + rzs_stat64_inc(rzs, &rzs->stats.bdev_num_writes); bio->bi_bdev = rzs->backing_swap; #if 0 /* @@ -941,7 +942,6 @@ out: return 0; } - /* * Check if request is within bounds and page aligned. */ @@ -975,7 +975,7 @@ static int ramzswap_make_request(struct request_queue *queue, struct bio *bio) } if (!valid_swap_request(rzs, bio)) { - stat_inc(rzs->stats.invalid_io); + rzs_stat64_inc(rzs, &rzs->stats.invalid_io); bio_io_error(bio); return 0; } @@ -1000,6 +1000,9 @@ static void reset_device(struct ramzswap *rzs) unsigned entries_per_page; unsigned long num_table_pages, entry = 0; + /* Do not accept any new I/O request */ + rzs->init_done = 0; + if (rzs->backing_swap && !rzs->num_extents) is_backing_blkdev = 1; @@ -1066,6 +1069,7 @@ static void reset_device(struct ramzswap *rzs) bd_release(rzs->backing_swap); filp_close(rzs->swap_file, NULL); rzs->backing_swap = NULL; + memset(rzs->backing_swap_name, 0, MAX_SWAP_NAME_LEN); } /* Reset stats */ @@ -1073,9 +1077,6 @@ static void reset_device(struct ramzswap *rzs) rzs->disksize = 0; rzs->memlimit = 0; - - /* Back to uninitialized state */ - rzs->init_done = 0; } static int ramzswap_ioctl_init_device(struct ramzswap *rzs) @@ -1276,6 +1277,11 @@ static int ramzswap_ioctl(struct block_device *bdev, fmode_t mode, ret = -EBUSY; goto out; } + + /* Make sure all pending I/O is finished */ + if (bdev) + fsync_bdev(bdev); + ret = ramzswap_ioctl_reset_device(rzs); break; @@ -1293,16 +1299,20 @@ static struct block_device_operations ramzswap_devops = { .owner = THIS_MODULE, }; -static void create_device(struct ramzswap *rzs, int device_id) +static int create_device(struct ramzswap *rzs, int device_id) { + int ret = 0; + mutex_init(&rzs->lock); + spin_lock_init(&rzs->stat64_lock); INIT_LIST_HEAD(&rzs->backing_swap_extent_list); rzs->queue = blk_alloc_queue(GFP_KERNEL); if (!rzs->queue) { pr_err("Error allocating disk queue for device %d\n", device_id); - return; + ret = -ENOMEM; + goto out; } blk_queue_make_request(rzs->queue, ramzswap_make_request); @@ -1314,7 +1324,8 @@ static void create_device(struct ramzswap *rzs, int device_id) blk_cleanup_queue(rzs->queue); pr_warning("Error allocating disk structure for device %d\n", device_id); - return; + ret = -ENOMEM; + goto out; } rzs->disk->major = ramzswap_major; @@ -1329,9 +1340,16 @@ static void create_device(struct ramzswap *rzs, int device_id) * or set equal to backing swap device (if provided) */ set_capacity(rzs->disk, 0); + + blk_queue_physical_block_size(rzs->disk->queue, PAGE_SIZE); + blk_queue_logical_block_size(rzs->disk->queue, PAGE_SIZE); + add_disk(rzs->disk); rzs->init_done = 0; + +out: + return ret; } static void destroy_device(struct ramzswap *rzs) @@ -1347,18 +1365,20 @@ static void destroy_device(struct ramzswap *rzs) static int __init ramzswap_init(void) { - int i, ret; + int ret, dev_id; if (num_devices > max_num_devices) { pr_warning("Invalid value for num_devices: %u\n", num_devices); - return -EINVAL; + ret = -EINVAL; + goto out; } ramzswap_major = register_blkdev(0, "ramzswap"); if (ramzswap_major <= 0) { pr_warning("Unable to get major number\n"); - return -EBUSY; + ret = -EBUSY; + goto out; } if (!num_devices) { @@ -1371,15 +1391,23 @@ static int __init ramzswap_init(void) devices = kzalloc(num_devices * sizeof(struct ramzswap), GFP_KERNEL); if (!devices) { ret = -ENOMEM; - goto out; + goto unregister; } - for (i = 0; i < num_devices; i++) - create_device(&devices[i], i); + for (dev_id = 0; dev_id < num_devices; dev_id++) { + ret = create_device(&devices[dev_id], dev_id); + if (ret) + goto free_devices; + } return 0; -out: + +free_devices: + while (dev_id) + destroy_device(&devices[--dev_id]); +unregister: unregister_blkdev(ramzswap_major, "ramzswap"); +out: return ret; } diff --git a/drivers/staging/ramzswap/ramzswap_drv.h b/drivers/staging/ramzswap/ramzswap_drv.h index a6ea240..c7e0e76 100644 --- a/drivers/staging/ramzswap/ramzswap_drv.h +++ b/drivers/staging/ramzswap/ramzswap_drv.h @@ -1,7 +1,7 @@ /* * Compressed RAM based swap device * - * Copyright (C) 2008, 2009 Nitin Gupta + * Copyright (C) 2008, 2009, 2010 Nitin Gupta * * This code is released using a dual license strategy: BSD/GPL * You can choose the licence that better fits your requirements. @@ -15,6 +15,9 @@ #ifndef _RAMZSWAP_DRV_H_ #define _RAMZSWAP_DRV_H_ +#include <linux/spinlock.h> +#include <linux/mutex.h> + #include "ramzswap_ioctl.h" #include "xvmalloc.h" @@ -71,15 +74,6 @@ static const unsigned max_zpage_size_nobdev = PAGE_SIZE / 4 * 3; #define SECTORS_PER_PAGE_SHIFT (PAGE_SHIFT - SECTOR_SHIFT) #define SECTORS_PER_PAGE (1 << SECTORS_PER_PAGE_SHIFT) -/* Debugging and Stats */ -#if defined(CONFIG_RAMZSWAP_STATS) -#define stat_inc(stat) ((stat)++) -#define stat_dec(stat) ((stat)--) -#else -#define stat_inc(x) -#define stat_dec(x) -#endif - /* Flags for ramzswap pages (table[page_no].flags) */ enum rzs_pageflags { /* Page is stored uncompressed */ @@ -102,7 +96,7 @@ struct table { u16 offset; u8 count; /* object ref count (not yet used) */ u8 flags; -} __attribute__((aligned(4)));; +} __attribute__((aligned(4))); /* * Swap extent information in case backing swap is a regular @@ -121,9 +115,10 @@ struct ramzswap_stats { #if defined(CONFIG_RAMZSWAP_STATS) u64 num_reads; /* failed + successful */ u64 num_writes; /* --do-- */ - u64 failed_reads; /* can happen when memory is too low */ - u64 failed_writes; /* should NEVER! happen */ + u64 failed_reads; /* should NEVER! happen */ + u64 failed_writes; /* can happen when memory is too low */ u64 invalid_io; /* non-swap I/O requests */ + u64 notify_free; /* no. of swap slot free notifications */ u32 pages_zero; /* no. of zero filled pages */ u32 pages_stored; /* no. of pages currently stored */ u32 good_compress; /* % of pages with compression ratio<=50% */ @@ -138,6 +133,7 @@ struct ramzswap { void *compress_workmem; void *compress_buffer; struct table *table; + spinlock_t stat64_lock; /* protect 64-bit stats */ struct mutex lock; struct request_queue *queue; struct gendisk *disk; @@ -167,5 +163,48 @@ struct ramzswap { /*-- */ -#endif +/* Debugging and Stats */ +#if defined(CONFIG_RAMZSWAP_STATS) +static void rzs_stat_inc(u32 *v) +{ + *v = *v + 1; +} + +static void rzs_stat_dec(u32 *v) +{ + *v = *v - 1; +} + +static void rzs_stat64_inc(struct ramzswap *rzs, u64 *v) +{ + spin_lock(&rzs->stat64_lock); + *v = *v + 1; + spin_unlock(&rzs->stat64_lock); +} + +static void rzs_stat64_dec(struct ramzswap *rzs, u64 *v) +{ + spin_lock(&rzs->stat64_lock); + *v = *v - 1; + spin_unlock(&rzs->stat64_lock); +} + +static u64 rzs_stat64_read(struct ramzswap *rzs, u64 *v) +{ + u64 val; + + spin_lock(&rzs->stat64_lock); + val = *v; + spin_unlock(&rzs->stat64_lock); + + return val; +} +#else +#define rzs_stat_inc(v) +#define rzs_stat_dec(v) +#define rzs_stat64_inc(r, v) +#define rzs_stat64_dec(r, v) +#define rzs_stat64_read(r, v) +#endif /* CONFIG_RAMZSWAP_STATS */ +#endif diff --git a/drivers/staging/ramzswap/ramzswap_ioctl.h b/drivers/staging/ramzswap/ramzswap_ioctl.h index c713a09..d26076d 100644 --- a/drivers/staging/ramzswap/ramzswap_ioctl.h +++ b/drivers/staging/ramzswap/ramzswap_ioctl.h @@ -1,7 +1,7 @@ /* * Compressed RAM based swap device * - * Copyright (C) 2008, 2009 Nitin Gupta + * Copyright (C) 2008, 2009, 2010 Nitin Gupta * * This code is released using a dual license strategy: BSD/GPL * You can choose the licence that better fits your requirements. @@ -24,9 +24,10 @@ struct ramzswap_ioctl_stats { * size (if present) */ u64 num_reads; /* failed + successful */ u64 num_writes; /* --do-- */ - u64 failed_reads; /* can happen when memory is too low */ - u64 failed_writes; /* should NEVER! happen */ + u64 failed_reads; /* should NEVER! happen */ + u64 failed_writes; /* can happen when memory is too low */ u64 invalid_io; /* non-swap I/O requests */ + u64 notify_free; /* no. of swap slot free notifications */ u32 pages_zero; /* no. of zero filled pages */ u32 good_compress_pct; /* no. of pages with compression ratio<=50% */ u32 pages_expand_pct; /* no. of incompressible pages */ diff --git a/drivers/staging/ramzswap/xvmalloc.c b/drivers/staging/ramzswap/xvmalloc.c index b3e986c..3fdbb8a 100644 --- a/drivers/staging/ramzswap/xvmalloc.c +++ b/drivers/staging/ramzswap/xvmalloc.c @@ -1,7 +1,7 @@ /* * xvmalloc memory allocator * - * Copyright (C) 2008, 2009 Nitin Gupta + * Copyright (C) 2008, 2009, 2010 Nitin Gupta * * This code is released using a dual license strategy: BSD/GPL * You can choose the licence that better fits your requirements. @@ -273,7 +273,7 @@ static void remove_block(struct xv_pool *pool, struct page *page, u32 offset, } /* - * Allocate a page and add it freelist of given pool. + * Allocate a page and add it to freelist of given pool. */ static int grow_pool(struct xv_pool *pool, gfp_t flags) { diff --git a/drivers/staging/ramzswap/xvmalloc.h b/drivers/staging/ramzswap/xvmalloc.h index 010c6fe..5b1a81a 100644 --- a/drivers/staging/ramzswap/xvmalloc.h +++ b/drivers/staging/ramzswap/xvmalloc.h @@ -1,7 +1,7 @@ /* * xvmalloc memory allocator * - * Copyright (C) 2008, 2009 Nitin Gupta + * Copyright (C) 2008, 2009, 2010 Nitin Gupta * * This code is released using a dual license strategy: BSD/GPL * You can choose the licence that better fits your requirements. diff --git a/drivers/staging/ramzswap/xvmalloc_int.h b/drivers/staging/ramzswap/xvmalloc_int.h index 03c1a65..e23ed5c 100644 --- a/drivers/staging/ramzswap/xvmalloc_int.h +++ b/drivers/staging/ramzswap/xvmalloc_int.h @@ -1,7 +1,7 @@ /* * xvmalloc memory allocator * - * Copyright (C) 2008, 2009 Nitin Gupta + * Copyright (C) 2008, 2009, 2010 Nitin Gupta * * This code is released using a dual license strategy: BSD/GPL * You can choose the licence that better fits your requirements. @@ -62,7 +62,7 @@ struct link_free { struct block_header { union { - /* This common header must be ALIGN bytes */ + /* This common header must be XV_ALIGN bytes */ u8 common[XV_ALIGN]; struct { u16 size; diff --git a/drivers/staging/rar/Kconfig b/drivers/staging/rar/Kconfig deleted file mode 100644 index 17f8bf3..0000000 --- a/drivers/staging/rar/Kconfig +++ /dev/null @@ -1,17 +0,0 @@ -# -# RAR device configuration -# - -menu "RAR Register Driver" -# -# Restricted Access Register Manager -# -config RAR_REGISTER - tristate "Restricted Access Region Register Driver" - default n - ---help--- - This driver allows other kernel drivers access to the - contents of the restricted access region control - registers. - -endmenu diff --git a/drivers/staging/rar/Makefile b/drivers/staging/rar/Makefile deleted file mode 100644 index 5422ed0..0000000 --- a/drivers/staging/rar/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -EXTRA_CFLAGS += -DLITTLE__ENDIAN -obj-$(CONFIG_RAR_REGISTER) += rar_driver.o diff --git a/drivers/staging/rar/rar_driver.c b/drivers/staging/rar/rar_driver.c deleted file mode 100644 index d85d189..0000000 --- a/drivers/staging/rar/rar_driver.c +++ /dev/null @@ -1,444 +0,0 @@ -#include <linux/init.h> -#include <linux/module.h> -#include <linux/fs.h> -#include <linux/cdev.h> -#include <linux/kdev_t.h> -#include <linux/semaphore.h> -#include <linux/mm.h> -#include <linux/poll.h> -#include <linux/wait.h> -#include <linux/ioctl.h> -#include <linux/ioport.h> -#include <linux/io.h> -#include <linux/interrupt.h> -#include <linux/pagemap.h> -#include <linux/pci.h> -#include <linux/firmware.h> -#include <linux/sched.h> -#include "rar_driver.h" - -/* The following defines are for the IPC process to retrieve RAR in */ - -/* === Lincroft Message Bus Interface === */ -/* Message Control Register */ -#define LNC_MCR_OFFSET 0xD0 - -/* Message Data Register */ -#define LNC_MDR_OFFSET 0xD4 - -/* Message Opcodes */ -#define LNC_MESSAGE_READ_OPCODE 0xD0 -#define LNC_MESSAGE_WRITE_OPCODE 0xE0 - -/* Message Write Byte Enables */ -#define LNC_MESSAGE_BYTE_WRITE_ENABLES 0xF - -/* B-unit Port */ -#define LNC_BUNIT_PORT 0x3 - -/* === Lincroft B-Unit Registers - Programmed by IA32 firmware === */ -#define LNC_BRAR0L 0x10 -#define LNC_BRAR0H 0x11 -#define LNC_BRAR1L 0x12 -#define LNC_BRAR1H 0x13 - -/* Reserved for SeP */ -#define LNC_BRAR2L 0x14 -#define LNC_BRAR2H 0x15 - - -/* This structure is only used during module initialization. */ -struct RAR_offsets { - int low; /* Register offset for low RAR physical address. */ - int high; /* Register offset for high RAR physical address. */ -}; - -struct pci_dev *rar_dev; -static uint32_t registered; - -/* Moorestown supports three restricted access regions. */ -#define MRST_NUM_RAR 3 - -struct RAR_address_struct rar_addr[MRST_NUM_RAR]; - -/* prototype for init */ -static int __init rar_init_handler(void); -static void __exit rar_exit_handler(void); - -/* - function that is activated on the successfull probe of the RAR device -*/ -static int __devinit rar_probe(struct pci_dev *pdev, const struct pci_device_id *ent); - -static struct pci_device_id rar_pci_id_tbl[] = { - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4110) }, - { 0 } -}; - -MODULE_DEVICE_TABLE(pci, rar_pci_id_tbl); - -/* field for registering driver to PCI device */ -static struct pci_driver rar_pci_driver = { - .name = "rar_driver", - .id_table = rar_pci_id_tbl, - .probe = rar_probe -}; - -/* This function is used to retrieved RAR info using the IPC message - bus interface */ -static int memrar_get_rar_addr(struct pci_dev* pdev, - int offset, - u32 *addr) -{ - /* - * ======== The Lincroft Message Bus Interface ======== - * Lincroft registers may be obtained from the PCI - * (the Host Bridge) using the Lincroft Message Bus - * Interface. That message bus interface is generally - * comprised of two registers: a control register (MCR, 0xDO) - * and a data register (MDR, 0xD4). - * - * The MCR (message control register) format is the following: - * 1. [31:24]: Opcode - * 2. [23:16]: Port - * 3. [15:8]: Register Offset - * 4. [7:4]: Byte Enables (use 0xF to set all of these bits - * to 1) - * 5. [3:0]: reserved - * - * Read (0xD0) and write (0xE0) opcodes are written to the - * control register when reading and writing to Lincroft - * registers, respectively. - * - * We're interested in registers found in the Lincroft - * B-unit. The B-unit port is 0x3. - * - * The six B-unit RAR register offsets we use are listed - * earlier in this file. - * - * Lastly writing to the MCR register requires the "Byte - * enables" bits to be set to 1. This may be achieved by - * writing 0xF at bit 4. - * - * The MDR (message data register) format is the following: - * 1. [31:0]: Read/Write Data - * - * Data being read from this register is only available after - * writing the appropriate control message to the MCR - * register. - * - * Data being written to this register must be written before - * writing the appropriate control message to the MCR - * register. - */ - - int result = 0; /* result */ - /* Construct control message */ - u32 const message = - (LNC_MESSAGE_READ_OPCODE << 24) - | (LNC_BUNIT_PORT << 16) - | (offset << 8) - | (LNC_MESSAGE_BYTE_WRITE_ENABLES << 4); - - printk(KERN_WARNING "rar- offset to LNC MSG is %x\n",offset); - - if (addr == 0) - return -EINVAL; - - /* Send the control message */ - result = pci_write_config_dword(pdev, - LNC_MCR_OFFSET, - message); - - printk(KERN_WARNING "rar- result from send ctl register is %x\n" - ,result); - - if (!result) - result = pci_read_config_dword(pdev, - LNC_MDR_OFFSET, - addr); - - printk(KERN_WARNING "rar- result from read data register is %x\n", - result); - - printk(KERN_WARNING "rar- value read from data register is %x\n", - *addr); - - if (result) - return -1; - else - return 0; -} - -static int memrar_set_rar_addr(struct pci_dev* pdev, - int offset, - u32 addr) -{ - /* - * ======== The Lincroft Message Bus Interface ======== - * Lincroft registers may be obtained from the PCI - * (the Host Bridge) using the Lincroft Message Bus - * Interface. That message bus interface is generally - * comprised of two registers: a control register (MCR, 0xDO) - * and a data register (MDR, 0xD4). - * - * The MCR (message control register) format is the following: - * 1. [31:24]: Opcode - * 2. [23:16]: Port - * 3. [15:8]: Register Offset - * 4. [7:4]: Byte Enables (use 0xF to set all of these bits - * to 1) - * 5. [3:0]: reserved - * - * Read (0xD0) and write (0xE0) opcodes are written to the - * control register when reading and writing to Lincroft - * registers, respectively. - * - * We're interested in registers found in the Lincroft - * B-unit. The B-unit port is 0x3. - * - * The six B-unit RAR register offsets we use are listed - * earlier in this file. - * - * Lastly writing to the MCR register requires the "Byte - * enables" bits to be set to 1. This may be achieved by - * writing 0xF at bit 4. - * - * The MDR (message data register) format is the following: - * 1. [31:0]: Read/Write Data - * - * Data being read from this register is only available after - * writing the appropriate control message to the MCR - * register. - * - * Data being written to this register must be written before - * writing the appropriate control message to the MCR - * register. - */ - - int result = 0; /* result */ - - /* Construct control message */ - u32 const message = - (LNC_MESSAGE_WRITE_OPCODE << 24) - | (LNC_BUNIT_PORT << 16) - | (offset << 8) - | (LNC_MESSAGE_BYTE_WRITE_ENABLES << 4); - - printk(KERN_WARNING "rar- offset to LNC MSG is %x\n",offset); - - if (addr == 0) - return -EINVAL; - - /* Send the control message */ - result = pci_write_config_dword(pdev, - LNC_MDR_OFFSET, - addr); - - printk(KERN_WARNING "rar- result from send ctl register is %x\n" - ,result); - - if (!result) - result = pci_write_config_dword(pdev, - LNC_MCR_OFFSET, - message); - - printk(KERN_WARNING "rar- result from write data register is %x\n", - result); - - printk(KERN_WARNING "rar- value read to data register is %x\n", - addr); - - if (result) - return -1; - else - return 0; -} - -/* - - * Initialize RAR parameters, such as physical addresses, etc. - - */ -static int memrar_init_rar_params(struct pci_dev *pdev) -{ - struct RAR_offsets const offsets[] = { - { LNC_BRAR0L, LNC_BRAR0H }, - { LNC_BRAR1L, LNC_BRAR1H }, - { LNC_BRAR2L, LNC_BRAR2H } - }; - - size_t const num_offsets = sizeof(offsets) / sizeof(offsets[0]); - struct RAR_offsets const *end = offsets + num_offsets; - struct RAR_offsets const *i; - unsigned int n = 0; - int result = 0; - - /* Retrieve RAR start and end physical addresses. */ - - /* - * Access the RAR registers through the Lincroft Message Bus - * Interface on PCI device: 00:00.0 Host bridge. - */ - - /* struct pci_dev *pdev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0)); */ - - if (pdev == NULL) - return -ENODEV; - - for (i = offsets; i != end; ++i, ++n) { - if (memrar_get_rar_addr (pdev, - (*i).low, - &(rar_addr[n].low)) != 0 - || memrar_get_rar_addr (pdev, - (*i).high, - &(rar_addr[n].high)) != 0) { - result = -1; - break; - } - } - - /* Done accessing the device. */ - /* pci_dev_put(pdev); */ - - if (result == 0) { - if(1) { - size_t z; - for (z = 0; z != MRST_NUM_RAR; ++z) { - printk(KERN_WARNING "rar - BRAR[%Zd] physical address low\n" - "\tlow: 0x%08x\n" - "\thigh: 0x%08x\n", - z, - rar_addr[z].low, - rar_addr[z].high); - } - } - } - - return result; -} - -/* - function that is activated on the successfull probe of the RAR device -*/ -static int __devinit rar_probe(struct pci_dev *pdev, const struct pci_device_id *ent) -{ - /* error */ - int error; - - /*------------------------ - CODE - ---------------------------*/ - - DEBUG_PRINT_0(RAR_DEBUG_LEVEL_EXTENDED, - "Rar pci probe starting\n"); - error = 0; - - /* enable the device */ - error = pci_enable_device(pdev); - if (error) { - DEBUG_PRINT_0(RAR_DEBUG_LEVEL_EXTENDED, - "error enabling pci device\n"); - goto end_function; - } - - rar_dev = pdev; - registered = 1; - - /* Initialize the RAR parameters, which have to be retrieved */ - /* via the message bus service */ - error=memrar_init_rar_params(rar_dev); - - if (error) { - DEBUG_PRINT_0(RAR_DEBUG_LEVEL_EXTENDED, - "error getting RAR addresses device\n"); - registered = 0; - goto end_function; - } - -end_function: - - return error; -} - -/* - this function registers th driver to - the device subsystem( either PCI, USB, etc) -*/ -static int __init rar_init_handler(void) -{ - return pci_register_driver(&rar_pci_driver); -} - -static void __exit rar_exit_handler(void) -{ - pci_unregister_driver(&rar_pci_driver); -} - -module_init(rar_init_handler); -module_exit(rar_exit_handler); - -MODULE_LICENSE("GPL"); - - -/* The get_rar_address function is used by other device drivers - * to obtain RAR address information on a RAR. It takes two - * parameter: - * - * int rar_index - * The rar_index is an index to the rar for which you wish to retrieve - * the address information. - * Values can be 0,1, or 2. - * - * struct RAR_address_struct is a pointer to a place to which the function - * can return the address structure for the RAR. - * - * The function returns a 0 upon success or a -1 if there is no RAR - * facility on this system. - */ -int get_rar_address(int rar_index,struct RAR_address_struct *addresses) -{ - if (registered && (rar_index < 3) && (rar_index >= 0)) { - *addresses=rar_addr[rar_index]; - /* strip off lock bit information */ - addresses->low = addresses->low & 0xfffffff0; - addresses->high = addresses->high & 0xfffffff0; - return 0; - } - - else { - return -ENODEV; - } -} - - -EXPORT_SYMBOL(get_rar_address); - -/* The lock_rar function is ued by other device drivers to lock an RAR. - * once an RAR is locked, it stays locked until the next system reboot. - * The function takes one parameter: - * - * int rar_index - * The rar_index is an index to the rar that you want to lock. - * Values can be 0,1, or 2. - * - * The function returns a 0 upon success or a -1 if there is no RAR - * facility on this system. - */ -int lock_rar(int rar_index) -{ - u32 working_addr; - int result; -if (registered && (rar_index < 3) && (rar_index >= 0)) { - /* first make sure that lock bits are clear (this does lock) */ - working_addr=rar_addr[rar_index].low & 0xfffffff0; - - /* now send that value to the register using the IPC */ - result=memrar_set_rar_addr(rar_dev,rar_index,working_addr); - return result; - } - -else { - return -ENODEV; - } -} diff --git a/drivers/staging/rar/rar_driver.h b/drivers/staging/rar/rar_driver.h deleted file mode 100644 index 3690f98..0000000 --- a/drivers/staging/rar/rar_driver.h +++ /dev/null @@ -1,99 +0,0 @@ -/* === RAR Physical Addresses === */ -struct RAR_address_struct { - u32 low; - u32 high; -}; - -/* The get_rar_address function is used by other device drivers - * to obtain RAR address information on a RAR. It takes two - * parameter: - * - * int rar_index - * The rar_index is an index to the rar for which you wish to retrieve - * the address information. - * Values can be 0,1, or 2. - * - * struct RAR_address_struct is a pointer to a place to which the function - * can return the address structure for the RAR. - * - * The function returns a 0 upon success or a -1 if there is no RAR - * facility on this system. - */ -int get_rar_address(int rar_index,struct RAR_address_struct *addresses); - - -/* The lock_rar function is ued by other device drivers to lock an RAR. - * once an RAR is locked, it stays locked until the next system reboot. - * The function takes one parameter: - * - * int rar_index - * The rar_index is an index to the rar that you want to lock. - * Values can be 0,1, or 2. - * - * The function returns a 0 upon success or a -1 if there is no RAR - * facility on this system. - */ -int lock_rar(int rar_index); - - -/* DEBUG LEVEL MASKS */ -#define RAR_DEBUG_LEVEL_BASIC 0x1 - -#define RAR_DEBUG_LEVEL_REGISTERS 0x2 - -#define RAR_DEBUG_LEVEL_EXTENDED 0x4 - -#define DEBUG_LEVEL 0x7 - -/* FUNCTIONAL MACROS */ - -/* debug macro without paramaters */ -#define DEBUG_PRINT_0(DEBUG_LEVEL , info) \ -do \ -{ \ - if(DEBUG_LEVEL) \ - { \ - printk(KERN_WARNING info); \ - } \ -}while(0) - -/* debug macro with 1 paramater */ -#define DEBUG_PRINT_1(DEBUG_LEVEL , info , param1) \ -do \ -{ \ - if(DEBUG_LEVEL) \ - { \ - printk(KERN_WARNING info , param1); \ - } \ -}while(0) - -/* debug macro with 2 paramaters */ -#define DEBUG_PRINT_2(DEBUG_LEVEL , info , param1, param2) \ -do \ -{ \ - if(DEBUG_LEVEL) \ - { \ - printk(KERN_WARNING info , param1, param2); \ - } \ -}while(0) - -/* debug macro with 3 paramaters */ -#define DEBUG_PRINT_3(DEBUG_LEVEL , info , param1, param2 , param3) \ -do \ -{ \ - if(DEBUG_LEVEL) \ - { \ - printk(KERN_WARNING info , param1, param2 , param3); \ - } \ -}while(0) - -/* debug macro with 4 paramaters */ -#define DEBUG_PRINT_4(DEBUG_LEVEL , info , param1, param2 , param3 , param4) \ -do \ -{ \ - if(DEBUG_LEVEL) \ - { \ - printk(KERN_WARNING info , param1, param2 , param3 , param4); \ - } \ -}while(0) - diff --git a/drivers/staging/rar_register/Kconfig b/drivers/staging/rar_register/Kconfig new file mode 100644 index 0000000..3f73839 --- /dev/null +++ b/drivers/staging/rar_register/Kconfig @@ -0,0 +1,30 @@ +# +# RAR device configuration +# + +menu "RAR Register Driver" +# +# Restricted Access Register Manager +# +config RAR_REGISTER + tristate "Restricted Access Region Register Driver" + default n + ---help--- + This driver allows other kernel drivers access to the + contents of the restricted access region control + registers. + + The restricted access region control registers + (rar_registers) are used to pass address and + locking information on restricted access regions + to other drivers that use restricted access regions + + The restricted access regions are regions of memory + on the Intel MID Platform that are not accessible to + the x86 processor, but are accessible to dedicated + processors on board peripheral devices. + + The purpose of the restricted access regions is to + protect sensitive data from compromise by unauthorized + programs running on the x86 processor. +endmenu diff --git a/drivers/staging/rar_register/Makefile b/drivers/staging/rar_register/Makefile new file mode 100644 index 0000000..d5954cc --- /dev/null +++ b/drivers/staging/rar_register/Makefile @@ -0,0 +1,2 @@ +EXTRA_CFLAGS += -DLITTLE__ENDIAN +obj-$(CONFIG_RAR_REGISTER) += rar_register.o diff --git a/drivers/staging/rar_register/rar_register.c b/drivers/staging/rar_register/rar_register.c new file mode 100644 index 0000000..bfc0e31 --- /dev/null +++ b/drivers/staging/rar_register/rar_register.c @@ -0,0 +1,615 @@ +/* + * rar_register.c - An Intel Restricted Access Region register driver + * + * Copyright(c) 2009 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * ------------------------------------------------------------------- + * 20091204 Mark Allyn <mark.a.allyn@intel.com> + * Ossama Othman <ossama.othman@intel.com> + * Cleanup per feedback from Alan Cox and Arjan Van De Ven + * + * 20090806 Ossama Othman <ossama.othman@intel.com> + * Return zero high address if upper 22 bits is zero. + * Cleaned up checkpatch errors. + * Clarified that driver is dealing with bus addresses. + * + * 20090702 Ossama Othman <ossama.othman@intel.com> + * Removed unnecessary include directives + * Cleaned up spinlocks. + * Cleaned up logging. + * Improved invalid parameter checks. + * Fixed and simplified RAR address retrieval and RAR locking + * code. + * + * 20090626 Mark Allyn <mark.a.allyn@intel.com> + * Initial publish + */ + +#define DEBUG 1 + +#include "rar_register.h" + +#include <linux/module.h> +#include <linux/pci.h> +#include <linux/spinlock.h> +#include <linux/device.h> +#include <linux/kernel.h> + +/* === Lincroft Message Bus Interface === */ +/* Message Control Register */ +#define LNC_MCR_OFFSET 0xD0 + +/* Maximum number of clients (other drivers using this driver) */ +#define MAX_RAR_CLIENTS 10 + +/* Message Data Register */ +#define LNC_MDR_OFFSET 0xD4 + +/* Message Opcodes */ +#define LNC_MESSAGE_READ_OPCODE 0xD0 +#define LNC_MESSAGE_WRITE_OPCODE 0xE0 + +/* Message Write Byte Enables */ +#define LNC_MESSAGE_BYTE_WRITE_ENABLES 0xF + +/* B-unit Port */ +#define LNC_BUNIT_PORT 0x3 + +/* === Lincroft B-Unit Registers - Programmed by IA32 firmware === */ +#define LNC_BRAR0L 0x10 +#define LNC_BRAR0H 0x11 +#define LNC_BRAR1L 0x12 +#define LNC_BRAR1H 0x13 + +/* Reserved for SeP */ +#define LNC_BRAR2L 0x14 +#define LNC_BRAR2H 0x15 + +/* Moorestown supports three restricted access regions. */ +#define MRST_NUM_RAR 3 + + +/* RAR Bus Address Range */ +struct RAR_address_range { + dma_addr_t low; + dma_addr_t high; +}; + +/* Structure containing low and high RAR register offsets. */ +struct RAR_offsets { + u32 low; /* Register offset for low RAR bus address. */ + u32 high; /* Register offset for high RAR bus address. */ +}; + +struct client { + int (*client_callback)(void *client_data); + void *customer_data; + int client_called; + }; + +static DEFINE_MUTEX(rar_mutex); +static DEFINE_MUTEX(lnc_reg_mutex); + +struct RAR_device { + struct RAR_offsets const rar_offsets[MRST_NUM_RAR]; + struct RAR_address_range rar_addr[MRST_NUM_RAR]; + struct pci_dev *rar_dev; + bool registered; + }; + +/* this platform has only one rar_device for 3 rar regions */ +static struct RAR_device my_rar_device = { + .rar_offsets = { + [0].low = LNC_BRAR0L, + [0].high = LNC_BRAR0H, + [1].low = LNC_BRAR1L, + [1].high = LNC_BRAR1H, + [2].low = LNC_BRAR2L, + [2].high = LNC_BRAR2H + } +}; + +/* this data is for handling requests from other drivers which arrive + * prior to this driver initializing + */ + +static struct client clients[MAX_RAR_CLIENTS]; +static int num_clients; + +/* + * This function is used to retrieved RAR info using the Lincroft + * message bus interface. + */ +static int retrieve_rar_addr(struct pci_dev *pdev, + int offset, + dma_addr_t *addr) +{ + /* + * ======== The Lincroft Message Bus Interface ======== + * Lincroft registers may be obtained from the PCI + * (the Host Bridge) using the Lincroft Message Bus + * Interface. That message bus interface is generally + * comprised of two registers: a control register (MCR, 0xDO) + * and a data register (MDR, 0xD4). + * + * The MCR (message control register) format is the following: + * 1. [31:24]: Opcode + * 2. [23:16]: Port + * 3. [15:8]: Register Offset + * 4. [7:4]: Byte Enables (use 0xF to set all of these bits + * to 1) + * 5. [3:0]: reserved + * + * Read (0xD0) and write (0xE0) opcodes are written to the + * control register when reading and writing to Lincroft + * registers, respectively. + * + * We're interested in registers found in the Lincroft + * B-unit. The B-unit port is 0x3. + * + * The six B-unit RAR register offsets we use are listed + * earlier in this file. + * + * Lastly writing to the MCR register requires the "Byte + * enables" bits to be set to 1. This may be achieved by + * writing 0xF at bit 4. + * + * The MDR (message data register) format is the following: + * 1. [31:0]: Read/Write Data + * + * Data being read from this register is only available after + * writing the appropriate control message to the MCR + * register. + * + * Data being written to this register must be written before + * writing the appropriate control message to the MCR + * register. + */ + + int result; + + /* Construct control message */ + u32 const message = + (LNC_MESSAGE_READ_OPCODE << 24) + | (LNC_BUNIT_PORT << 16) + | (offset << 8) + | (LNC_MESSAGE_BYTE_WRITE_ENABLES << 4); + + dev_dbg(&pdev->dev, "Offset for 'get' LNC MSG is %x\n", offset); + + if (addr == 0) { + WARN_ON(1); + return -EINVAL; + } + + /* + * We synchronize access to the Lincroft MCR and MDR registers + * until BOTH the command is issued through the MCR register + * and the corresponding data is read from the MDR register. + * Otherwise a race condition would exist between accesses to + * both registers. + */ + + mutex_lock(&lnc_reg_mutex); + + /* Send the control message */ + result = pci_write_config_dword(pdev, LNC_MCR_OFFSET, message); + + dev_dbg(&pdev->dev, "Result from send ctl register is %x\n", result); + + if (!result) { + result = pci_read_config_dword(pdev, LNC_MDR_OFFSET, + (u32 *)addr); + dev_dbg(&pdev->dev, + "Result from read data register is %x\n", result); + + dev_dbg(&pdev->dev, + "Value read from data register is %lx\n", + (unsigned long)*addr); + } + + mutex_unlock(&lnc_reg_mutex); + + return result; +} + +static int set_rar_address(struct pci_dev *pdev, + int offset, + dma_addr_t addr) +{ + /* + * Data being written to this register must be written before + * writing the appropriate control message to the MCR + * register. + * @note See rar_get_address() for a description of the + * message bus interface being used here. + */ + + int result = 0; + + /* Construct control message */ + u32 const message = (LNC_MESSAGE_WRITE_OPCODE << 24) + | (LNC_BUNIT_PORT << 16) + | (offset << 8) + | (LNC_MESSAGE_BYTE_WRITE_ENABLES << 4); + + if (addr == 0) { + WARN_ON(1); + return -EINVAL; + } + + dev_dbg(&pdev->dev, "Offset for 'set' LNC MSG is %x\n", offset); + + /* + * We synchronize access to the Lincroft MCR and MDR registers + * until BOTH the command is issued through the MCR register + * and the corresponding data is read from the MDR register. + * Otherwise a race condition would exist between accesses to + * both registers. + */ + + mutex_lock(&lnc_reg_mutex); + + /* Send the control message */ + result = pci_write_config_dword(pdev, LNC_MDR_OFFSET, addr); + + dev_dbg(&pdev->dev, "Result from write data register is %x\n", result); + + if (!result) { + dev_dbg(&pdev->dev, + "Value written to data register is %lx\n", + (unsigned long)addr); + + result = pci_write_config_dword(pdev, LNC_MCR_OFFSET, message); + + dev_dbg(&pdev->dev, "Result from send ctl register is %x\n", + result); + } + + mutex_unlock(&lnc_reg_mutex); + + return result; +} + +/* +* Initialize RAR parameters, such as bus addresses, etc. +*/ +static int init_rar_params(struct pci_dev *pdev) +{ + unsigned int i; + int result = 0; + + /* Retrieve RAR start and end bus addresses. + * Access the RAR registers through the Lincroft Message Bus + * Interface on PCI device: 00:00.0 Host bridge. + */ + + for (i = 0; i < MRST_NUM_RAR; ++i) { + struct RAR_offsets const *offset = + &my_rar_device.rar_offsets[i]; + struct RAR_address_range *addr = &my_rar_device.rar_addr[i]; + + if ((retrieve_rar_addr(pdev, offset->low, &addr->low) != 0) + || (retrieve_rar_addr(pdev, offset->high, &addr->high) != 0)) { + result = -1; + break; + } + + /* + * Only the upper 22 bits of the RAR addresses are + * stored in their corresponding RAR registers so we + * must set the lower 10 bits accordingly. + + * The low address has its lower 10 bits cleared, and + * the high address has all its lower 10 bits set, + * e.g.: + * low = 0x2ffffc00 + */ + + addr->low &= (dma_addr_t)0xfffffc00u; + + /* + * Set bits 9:0 on uppser address if bits 31:10 are non + * zero; otherwize clear all bits + */ + + if ((addr->high & 0xfffffc00u) == 0) + addr->high = 0; + else + addr->high |= 0x3ffu; + } + /* Done accessing the device. */ + + if (result == 0) { + int z; + for (z = 0; z != MRST_NUM_RAR; ++z) { + /* + * "BRAR" refers to the RAR registers in the + * Lincroft B-unit. + */ + dev_info(&pdev->dev, "BRAR[%u] bus address range = " + "[%lx, %lx]\n", z, + (unsigned long)my_rar_device.rar_addr[z].low, + (unsigned long)my_rar_device.rar_addr[z].high); + } + } + + return result; +} + +/* + * The rar_get_address function is used by other device drivers + * to obtain RAR address information on a RAR. It takes three + * parameters: + * + * int rar_index + * The rar_index is an index to the rar for which you wish to retrieve + * the address information. + * Values can be 0,1, or 2. + * + * The function returns a 0 upon success or a -1 if there is no RAR + * facility on this system. + */ +int rar_get_address(int rar_index, + dma_addr_t *start_address, + dma_addr_t *end_address) +{ + int result = -ENODEV; + + if (my_rar_device.registered) { + if (start_address == 0 || end_address == 0 + || rar_index >= MRST_NUM_RAR || rar_index < 0) { + result = -EINVAL; + } else { + *start_address = + my_rar_device.rar_addr[rar_index].low; + *end_address = + my_rar_device.rar_addr[rar_index].high; + + result = 0; + } + } + + return result; +} +EXPORT_SYMBOL(rar_get_address); + +/* + * The rar_lock function is ued by other device drivers to lock an RAR. + * once an RAR is locked, it stays locked until the next system reboot. + * The function takes one parameter: + * + * int rar_index + * The rar_index is an index to the rar that you want to lock. + * Values can be 0,1, or 2. + * + * The function returns a 0 upon success or a -1 if there is no RAR + * facility on this system. + */ +int rar_lock(int rar_index) +{ + int result = -ENODEV; + + if (rar_index >= MRST_NUM_RAR || rar_index < 0) { + result = -EINVAL; + return result; + } + + dev_dbg(&my_rar_device.rar_dev->dev, "rar_lock mutex locking\n"); + mutex_lock(&rar_mutex); + + if (my_rar_device.registered) { + + dma_addr_t low = my_rar_device.rar_addr[rar_index].low & + 0xfffffc00u; + + dma_addr_t high = my_rar_device.rar_addr[rar_index].high & + 0xfffffc00u; + + /* + * Only allow I/O from the graphics and Langwell; + * Not from the x96 processor + */ + if (rar_index == (int)RAR_TYPE_VIDEO) { + low |= 0x00000009; + high |= 0x00000015; + } + + else if (rar_index == (int)RAR_TYPE_AUDIO) { + /* Only allow I/O from Langwell; nothing from x86 */ + low |= 0x00000008; + high |= 0x00000018; + } + + else + /* Read-only from all agents */ + high |= 0x00000018; + + /* + * Now program the register using the Lincroft message + * bus interface. + */ + result = set_rar_address(my_rar_device.rar_dev, + my_rar_device.rar_offsets[rar_index].low, + low); + + if (result == 0) + result = set_rar_address( + my_rar_device.rar_dev, + my_rar_device.rar_offsets[rar_index].high, + high); + } + + dev_dbg(&my_rar_device.rar_dev->dev, "rar_lock mutex unlocking\n"); + mutex_unlock(&rar_mutex); + return result; +} +EXPORT_SYMBOL(rar_lock); + +/* The register_rar function is to used by other device drivers + * to ensure that this driver is ready. As we cannot be sure of + * the compile/execute order of dirvers in ther kernel, it is + * best to give this driver a callback function to call when + * it is ready to give out addresses. The callback function + * would have those steps that continue the initialization of + * a driver that do require a valid RAR address. One of those + * steps would be to call rar_get_address() + * This function return 0 on success an -1 on failure. +*/ +int register_rar(int (*callback)(void *yourparameter), void *yourparameter) +{ + + int result = -ENODEV; + + if (callback == NULL) + return -EINVAL; + + mutex_lock(&rar_mutex); + + if (my_rar_device.registered) { + + mutex_unlock(&rar_mutex); + /* + * if the driver already registered, then we can simply + * call the callback right now + */ + + return (*callback)(yourparameter); + } + + if (num_clients < MRST_NUM_RAR) { + + clients[num_clients].client_callback = callback; + clients[num_clients].customer_data = yourparameter; + num_clients += 1; + result = 0; + } + + mutex_unlock(&rar_mutex); + return result; + +} +EXPORT_SYMBOL(register_rar); + +/* Suspend - returns -ENOSYS */ +static int rar_suspend(struct pci_dev *dev, pm_message_t state) +{ + return -ENOSYS; +} + +static int rar_resume(struct pci_dev *dev) +{ + return -ENOSYS; +} + +/* + * This function registers the driver with the device subsystem ( + * either PCI, USB, etc). + * Function that is activaed on the succesful probe of the RAR device + * (Moorestown host controller). + */ +static int rar_probe(struct pci_dev *dev, const struct pci_device_id *id) +{ + int error; + int counter; + + dev_dbg(&dev->dev, "PCI probe starting\n"); + + /* enable the device */ + error = pci_enable_device(dev); + if (error) { + dev_err(&dev->dev, + "Error enabling RAR register PCI device\n"); + goto end_function; + } + + /* we have only one device; fill in the rar_device structure */ + my_rar_device.rar_dev = dev; + + /* + * Initialize the RAR parameters, which have to be retrieved + * via the message bus interface. + */ + error = init_rar_params(dev); + if (error) { + pci_disable_device(dev); + + dev_err(&dev->dev, + "Error retrieving RAR addresses\n"); + + goto end_function; + } + + dev_dbg(&dev->dev, "PCI probe locking\n"); + mutex_lock(&rar_mutex); + my_rar_device.registered = 1; + + /* now call anyone who has registered (using callbacks) */ + for (counter = 0; counter < num_clients; counter += 1) { + if (clients[counter].client_callback) { + error = (*clients[counter].client_callback)( + clients[counter].customer_data); + /* set callback to NULL to indicate it has been done */ + clients[counter].client_callback = NULL; + dev_dbg(&my_rar_device.rar_dev->dev, + "Callback called for %d\n", + counter); + } + } + + dev_dbg(&dev->dev, "PCI probe unlocking\n"); + mutex_unlock(&rar_mutex); + +end_function: + + return error; +} + +const struct pci_device_id rar_pci_id_tbl[] = { + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_RAR_DEVICE_ID) }, + { 0 } +}; + +MODULE_DEVICE_TABLE(pci, rar_pci_id_tbl); + +const struct pci_device_id *my_id_table = rar_pci_id_tbl; + +/* field for registering driver to PCI device */ +static struct pci_driver rar_pci_driver = { + .name = "rar_register_driver", + .id_table = rar_pci_id_tbl, + .probe = rar_probe, + .suspend = rar_suspend, + .resume = rar_resume +}; + +static int __init rar_init_handler(void) +{ + return pci_register_driver(&rar_pci_driver); +} + +static void __exit rar_exit_handler(void) +{ + pci_unregister_driver(&rar_pci_driver); +} + +module_init(rar_init_handler); +module_exit(rar_exit_handler); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Intel Restricted Access Region Register Driver"); diff --git a/drivers/staging/rar_register/rar_register.h b/drivers/staging/rar_register/rar_register.h new file mode 100644 index 0000000..29ade0f --- /dev/null +++ b/drivers/staging/rar_register/rar_register.h @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2010 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General + * Public License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * The full GNU General Public License is included in this + * distribution in the file called COPYING. + */ + + +#ifndef _RAR_REGISTER_H +#define _RAR_REGISTER_H + +# include <linux/types.h> + +/* following are used both in drivers as well as user space apps */ +enum RAR_type { + RAR_TYPE_VIDEO = 0, + RAR_TYPE_AUDIO, + RAR_TYPE_IMAGE, + RAR_TYPE_DATA +}; + +#ifdef __KERNEL__ + +/* PCI device id for controller */ +#define PCI_RAR_DEVICE_ID 0x4110 + +/* The register_rar function is to used by other device drivers + * to ensure that this driver is ready. As we cannot be sure of + * the compile/execute order of dirvers in ther kernel, it is + * best to give this driver a callback function to call when + * it is ready to give out addresses. The callback function + * would have those steps that continue the initialization of + * a driver that do require a valid RAR address. One of those + * steps would be to call get_rar_address() + * This function return 0 on success an -1 on failure. + */ +int register_rar(int (*callback)(void *yourparameter), void *yourparameter); + +/* The get_rar_address function is used by other device drivers + * to obtain RAR address information on a RAR. It takes two + * parameter: + * + * int rar_index + * The rar_index is an index to the rar for which you wish to retrieve + * the address information. + * Values can be 0,1, or 2. + * + * struct RAR_address_struct is a pointer to a place to which the function + * can return the address structure for the RAR. + * + * The function returns a 0 upon success or a -1 if there is no RAR + * facility on this system. + */ +int rar_get_address(int rar_index, + dma_addr_t *start_address, + dma_addr_t *end_address); + +/* The lock_rar function is ued by other device drivers to lock an RAR. + * once an RAR is locked, it stays locked until the next system reboot. + * The function takes one parameter: + * + * int rar_index + * The rar_index is an index to the rar that you want to lock. + * Values can be 0,1, or 2. + * + * The function returns a 0 upon success or a -1 if there is no RAR + * facility on this system. + */ +int rar_lock(int rar_index); + +#endif /* __KERNEL__ */ +#endif /* _RAR_REGISTER_H */ diff --git a/drivers/staging/rt2860/Kconfig b/drivers/staging/rt2860/Kconfig index f9962b6..f3a7e47 100644 --- a/drivers/staging/rt2860/Kconfig +++ b/drivers/staging/rt2860/Kconfig @@ -3,6 +3,8 @@ config RT2860 depends on PCI && X86 && WLAN select WIRELESS_EXT select WEXT_PRIV + select CRC_CCITT + select FW_LOADER ---help--- This is an experimental driver for the Ralink 2860 and 3090 wireless chips. diff --git a/drivers/staging/rt2860/common/firmware.h b/drivers/staging/rt2860/common/firmware.h deleted file mode 100644 index 2fecd32..0000000 --- a/drivers/staging/rt2860/common/firmware.h +++ /dev/null @@ -1,558 +0,0 @@ -/* - Copyright (c) 2007, Ralink Technology Corporation - All rights reserved. - - Redistribution. Redistribution and use in binary form, without - modification, are permitted provided that the following conditions are - met: - - * Redistributions must reproduce the above copyright notice and the - following disclaimer in the documentation and/or other materials - provided with the distribution. - * Neither the name of Ralink Technology Corporation nor the names of its - suppliers may be used to endorse or promote products derived from this - software without specific prior written permission. - * No reverse engineering, decompilation, or disassembly of this software - is permitted. - - Limited patent license. Ralink Technology Corporation grants a world-wide, - royalty-free, non-exclusive license under patents it now or hereafter - owns or controls to make, have made, use, import, offer to sell and - sell ("Utilize") this software, but solely to the extent that any - such patent is necessary to Utilize the software alone, or in - combination with an operating system licensed under an approved Open - Source license as listed by the Open Source Initiative at - http://opensource.org/licenses. The patent license shall not apply to - any other combinations which include this software. No hardware per - se is licensed hereunder. - - DISCLAIMER. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. -*/ -/* AUTO GEN PLEASE DO NOT MODIFY IT */ -/* AUTO GEN PLEASE DO NOT MODIFY IT */ - - -u8 FirmwareImage_2860 [] = { -0x02, 0x03, 0x5e, 0x02, 0x02, 0xb1, 0x22, 0x22, 0xff, 0xff, 0xff, 0x02, 0x01, 0x82, 0xff, 0xff, -0xff, 0xff, 0xff, 0x02, 0x00, 0x1e, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02, 0x01, 0x33, 0xc0, 0xe0, -0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x18, 0xc2, 0xaf, 0x30, 0x45, 0x03, -0x12, 0x10, 0x09, 0x90, 0x04, 0x16, 0xe0, 0x30, 0xe3, 0x03, 0x74, 0x08, 0xf0, 0x90, 0x04, 0x14, -0xe0, 0x20, 0xe7, 0x03, 0x02, 0x00, 0xcb, 0x74, 0x80, 0xf0, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x2f, -0x90, 0x04, 0x04, 0xe0, 0x24, 0xcf, 0x60, 0x30, 0x14, 0x60, 0x42, 0x24, 0xe2, 0x60, 0x47, 0x14, -0x60, 0x55, 0x24, 0x21, 0x70, 0x60, 0xe5, 0x55, 0x24, 0xfe, 0x60, 0x07, 0x14, 0x60, 0x08, 0x24, -0x02, 0x70, 0x08, 0x7d, 0x01, 0x80, 0x28, 0x7d, 0x02, 0x80, 0x24, 0x90, 0x70, 0x10, 0xe0, 0xf5, -0x50, 0x85, 0x2f, 0x40, 0xd2, 0x01, 0x80, 0x3e, 0xe5, 0x55, 0x64, 0x03, 0x60, 0x04, 0xe5, 0x55, -0x70, 0x04, 0x7d, 0x02, 0x80, 0x09, 0x85, 0x2f, 0x41, 0xd2, 0x02, 0x80, 0x29, 0xad, 0x55, 0xaf, -0x2f, 0x12, 0x02, 0x8d, 0x80, 0x20, 0x90, 0x70, 0x10, 0xe0, 0xf5, 0x47, 0x90, 0x70, 0x11, 0xe0, -0xf5, 0x44, 0x12, 0x10, 0x25, 0x80, 0x06, 0x90, 0x70, 0x10, 0xe0, 0xf5, 0x45, 0xe4, 0xfd, 0xaf, -0x2f, 0x12, 0x02, 0x8d, 0xd2, 0x04, 0x90, 0x70, 0x13, 0xe4, 0xf0, 0xd2, 0xaf, 0xd0, 0xd0, 0xd0, -0x82, 0xd0, 0x83, 0xd0, 0xf0, 0xd0, 0xe0, 0x32, 0x90, 0x70, 0x2a, 0xe0, 0x30, 0xe1, 0x53, 0xc2, -0xaf, 0x90, 0x70, 0x28, 0xe0, 0x90, 0x10, 0x1c, 0xf0, 0x90, 0x70, 0x29, 0xe0, 0x90, 0x10, 0x1d, -0xf0, 0x90, 0x70, 0x2a, 0xe0, 0x90, 0x10, 0x1e, 0xf0, 0x90, 0x10, 0x1c, 0xe0, 0xf5, 0x30, 0x90, -0x10, 0x1e, 0xe0, 0x20, 0xe1, 0xf3, 0x90, 0x10, 0x1c, 0xe0, 0x90, 0x70, 0x28, 0xf0, 0x90, 0x10, -0x1d, 0xe0, 0x90, 0x70, 0x29, 0xf0, 0x90, 0x10, 0x1e, 0xe0, 0x90, 0x70, 0x2a, 0xf0, 0x30, 0x4a, -0x0d, 0x90, 0x70, 0x24, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x02, 0x2c, 0x74, 0xff, 0xf0, 0xc2, 0x05, -0xd2, 0xaf, 0x22, 0xc0, 0xe0, 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0xe8, 0xc0, 0xe0, -0xe9, 0xc0, 0xe0, 0xea, 0xc0, 0xe0, 0xeb, 0xc0, 0xe0, 0xec, 0xc0, 0xe0, 0xed, 0xc0, 0xe0, 0xee, -0xc0, 0xe0, 0xef, 0xc0, 0xe0, 0xc2, 0xaf, 0x30, 0x45, 0x03, 0x12, 0x10, 0x12, 0xd2, 0xaf, 0xd0, -0xe0, 0xff, 0xd0, 0xe0, 0xfe, 0xd0, 0xe0, 0xfd, 0xd0, 0xe0, 0xfc, 0xd0, 0xe0, 0xfb, 0xd0, 0xe0, -0xfa, 0xd0, 0xe0, 0xf9, 0xd0, 0xe0, 0xf8, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xf0, 0xd0, -0xe0, 0x32, 0xc0, 0xe0, 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x10, 0xc2, -0xaf, 0x30, 0x45, 0x03, 0x12, 0x10, 0x0c, 0x30, 0x58, 0x0a, 0xe5, 0x54, 0x60, 0x04, 0x15, 0x54, -0x80, 0x02, 0xc2, 0x58, 0x30, 0x59, 0x0a, 0xe5, 0x50, 0x60, 0x04, 0x15, 0x50, 0x80, 0x02, 0xc2, -0x59, 0xd5, 0x53, 0x07, 0x30, 0x60, 0x04, 0x15, 0x46, 0xd2, 0x04, 0x30, 0x45, 0x03, 0x12, 0x10, -0x0f, 0xc2, 0x8d, 0xd2, 0xaf, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xf0, 0xd0, 0xe0, 0x32, -0x12, 0x02, 0xd3, 0x30, 0x45, 0x03, 0x12, 0x10, 0x03, 0x30, 0x01, 0x06, 0x20, 0x09, 0x03, 0x12, -0x10, 0x1c, 0x30, 0x02, 0x06, 0x20, 0x0a, 0x03, 0x12, 0x10, 0x1f, 0x30, 0x03, 0x06, 0x20, 0x0b, -0x03, 0x12, 0x10, 0x1f, 0x30, 0x04, 0x06, 0x20, 0x0c, 0x03, 0x12, 0x10, 0x22, 0x20, 0x13, 0x09, -0x20, 0x11, 0x06, 0xe5, 0x2b, 0x45, 0x2c, 0x60, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0xa9, 0x12, -0x02, 0xec, 0x80, 0xbf, 0xc2, 0x43, 0xd2, 0x45, 0xe4, 0xf5, 0x20, 0xf5, 0x21, 0xf5, 0x53, 0xf5, -0x46, 0xf5, 0x2b, 0xf5, 0x2c, 0xc2, 0x42, 0xf5, 0x51, 0xf5, 0x52, 0xf5, 0x55, 0x90, 0x04, 0x18, -0x74, 0x80, 0xf0, 0x90, 0x04, 0x1a, 0x74, 0x08, 0xf0, 0xc2, 0x19, 0xc2, 0x18, 0xc2, 0x1a, 0x22, -0xc8, 0xef, 0xc8, 0xe6, 0xfa, 0x08, 0xe6, 0x4a, 0x60, 0x0c, 0xc8, 0xef, 0xc8, 0x08, 0xe6, 0x16, -0x18, 0x70, 0x01, 0x16, 0xc3, 0x22, 0xed, 0x24, 0xff, 0xfd, 0xec, 0x34, 0xff, 0xc8, 0xef, 0xc8, -0xf6, 0x08, 0xc6, 0xed, 0xc6, 0xd3, 0x22, 0xd0, 0x83, 0xd0, 0x82, 0xf8, 0xe4, 0x93, 0x70, 0x12, -0x74, 0x01, 0x93, 0x70, 0x0d, 0xa3, 0xa3, 0x93, 0xf8, 0x74, 0x01, 0x93, 0xf5, 0x82, 0x88, 0x83, -0xe4, 0x73, 0x74, 0x02, 0x93, 0x68, 0x60, 0xef, 0xa3, 0xa3, 0xa3, 0x80, 0xdf, 0xef, 0xf4, 0x60, -0x1f, 0xe4, 0xfe, 0x12, 0x03, 0x6a, 0xe0, 0xb4, 0xff, 0x12, 0x12, 0x03, 0x6a, 0xef, 0xf0, 0x74, -0x1c, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xed, 0xf0, 0x22, 0x0e, 0xbe, 0x04, 0xe3, -0x22, 0xc0, 0xe0, 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x08, 0xc2, 0xaf, -0x30, 0x45, 0x03, 0x12, 0x10, 0x06, 0xd2, 0xaf, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xf0, -0xd0, 0xe0, 0x32, 0xc2, 0xaf, 0x12, 0x00, 0x06, 0x12, 0x02, 0x14, 0x12, 0x03, 0x1c, 0xe4, 0xf5, -0x22, 0xf5, 0x47, 0x90, 0x04, 0x00, 0x74, 0x80, 0xf0, 0xd2, 0xaf, 0x22, 0x30, 0x45, 0x03, 0x12, -0x10, 0x15, 0xe5, 0x20, 0x70, 0x03, 0x20, 0x10, 0x03, 0x30, 0x11, 0x03, 0x43, 0x87, 0x01, 0x22, -0xc0, 0x2a, 0x74, 0x03, 0xc0, 0xe0, 0xc0, 0x82, 0xc0, 0x83, 0x75, 0x2a, 0x0a, 0x22, 0xc0, 0x2a, -0x74, 0x03, 0xc0, 0xe0, 0xc0, 0x82, 0xc0, 0x83, 0x75, 0x2a, 0x18, 0x22, 0x75, 0x89, 0x02, 0xe4, -0xf5, 0x8c, 0xf5, 0x8a, 0xf5, 0x88, 0xf5, 0xb8, 0xf5, 0xe8, 0x75, 0x90, 0x18, 0xd2, 0x8c, 0x75, -0xa8, 0x05, 0x22, 0xce, 0xef, 0xce, 0xee, 0x60, 0x08, 0x7f, 0xff, 0x12, 0x03, 0x80, 0x1e, 0x80, -0xf5, 0x22, 0xc8, 0xef, 0xc8, 0xe6, 0x60, 0x03, 0x16, 0xc3, 0x22, 0xed, 0x14, 0xf6, 0xd3, 0x22, -0xc8, 0xef, 0xc8, 0xe6, 0x60, 0x06, 0x16, 0xe6, 0x24, 0xff, 0xb3, 0x22, 0xc3, 0x22, 0x78, 0x7f, -0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x5f, 0x02, 0x01, 0xd0, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, -0x34, 0x70, 0xf5, 0x83, 0x22, 0xef, 0x90, 0x03, 0x7e, 0x93, 0x90, 0x03, 0x00, 0x73, 0x0a, 0x18, -0xef, 0x60, 0x03, 0x1f, 0x80, 0xfa, 0x22, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0x02, 0x10, 0x28, 0x02, 0x10, 0x3b, 0x02, 0x10, 0x3c, 0x02, 0x12, 0xb8, 0x02, -0x12, 0xb9, 0x02, 0x13, 0x3e, 0x02, 0x13, 0x3f, 0xc3, 0x22, 0xff, 0xff, 0x02, 0x16, 0x56, 0x02, -0x17, 0x6b, 0x02, 0x14, 0x2a, 0x02, 0x13, 0x40, 0x30, 0x05, 0x06, 0x20, 0x0d, 0x03, 0x12, 0x00, -0xd8, 0x30, 0x06, 0x06, 0x20, 0x0e, 0x03, 0x12, 0x18, 0x5e, 0x22, 0x22, 0x90, 0x04, 0x14, 0xe0, -0x20, 0xe7, 0x03, 0x02, 0x12, 0xb7, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x56, 0x90, 0x04, 0x04, 0xe0, -0x12, 0x02, 0x67, 0x11, 0x4e, 0x30, 0x11, 0x25, 0x31, 0x10, 0x87, 0x33, 0x10, 0xaa, 0x34, 0x10, -0xc3, 0x35, 0x11, 0x57, 0x50, 0x11, 0x7b, 0x51, 0x11, 0x84, 0x52, 0x11, 0x84, 0x53, 0x11, 0x84, -0x54, 0x11, 0xc5, 0x55, 0x11, 0xdc, 0x70, 0x12, 0x07, 0x71, 0x12, 0x34, 0x72, 0x12, 0x5e, 0x80, -0x12, 0x81, 0x83, 0x00, 0x00, 0x12, 0xb7, 0x75, 0x24, 0x05, 0x75, 0x25, 0xdc, 0x90, 0x70, 0x9f, -0x74, 0x12, 0xf0, 0xd2, 0x18, 0xd2, 0x61, 0x75, 0x35, 0x0d, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, -0x56, 0xf4, 0x70, 0x03, 0x02, 0x12, 0xb7, 0x02, 0x12, 0xaa, 0xc2, 0x18, 0x90, 0x01, 0x14, 0xe0, -0x54, 0xfd, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x12, 0xb7, -0x02, 0x12, 0xaa, 0xe5, 0x55, 0x64, 0x02, 0x70, 0x37, 0x90, 0x70, 0x10, 0xe0, 0x60, 0x08, 0x90, -0x01, 0x0d, 0x74, 0x09, 0xf0, 0x80, 0x25, 0xe5, 0x34, 0x14, 0x60, 0x0a, 0x14, 0x60, 0x0f, 0x14, -0x60, 0x14, 0x24, 0x03, 0x70, 0x16, 0x90, 0x01, 0x0d, 0x74, 0x08, 0xf0, 0x80, 0x0e, 0x90, 0x01, -0x0d, 0x74, 0x0b, 0xf0, 0x80, 0x06, 0x90, 0x01, 0x0d, 0x74, 0x1b, 0xf0, 0x7d, 0x01, 0x80, 0x02, -0x7d, 0x02, 0xaf, 0x56, 0x12, 0x02, 0x8d, 0x90, 0x70, 0x11, 0xe0, 0x24, 0xff, 0x92, 0x1b, 0x90, -0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, -0x12, 0xb7, 0x02, 0x12, 0xaa, 0x20, 0x02, 0x03, 0x30, 0x03, 0x1d, 0x7d, 0x02, 0xaf, 0x56, 0x12, -0x02, 0x8d, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, -0x70, 0x03, 0x02, 0x12, 0xb7, 0x02, 0x12, 0xaa, 0x85, 0x56, 0x41, 0xd2, 0x02, 0x22, 0x90, 0x70, -0x11, 0xe0, 0x24, 0xff, 0x92, 0x1b, 0x22, 0x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, 0x64, 0x02, 0x60, -0x03, 0x02, 0x12, 0xb7, 0x90, 0x70, 0x11, 0xe0, 0x64, 0x08, 0x60, 0x08, 0xe0, 0x64, 0x20, 0x60, -0x03, 0x02, 0x12, 0xb7, 0x75, 0x4e, 0x03, 0x75, 0x4f, 0x20, 0x22, 0x90, 0x70, 0x11, 0xe0, 0x24, -0xff, 0x92, 0x47, 0x22, 0x90, 0x04, 0x04, 0xe0, 0x25, 0xe0, 0x24, 0x5d, 0xf5, 0x57, 0x90, 0x70, -0x10, 0xe0, 0xff, 0x74, 0x47, 0x25, 0x57, 0xf8, 0xc6, 0xef, 0xc6, 0x90, 0x70, 0x11, 0xe0, 0xff, -0x74, 0x48, 0x25, 0x57, 0xf8, 0xc6, 0xef, 0xc6, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x02, 0x8d, 0x90, -0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, -0x12, 0xb7, 0x02, 0x12, 0xaa, 0xe5, 0x47, 0xb4, 0x07, 0x08, 0x90, 0x70, 0x11, 0xe0, 0x54, 0x07, -0xf5, 0x26, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x02, 0x8d, 0xd2, 0x04, 0x22, 0x90, 0x70, 0x10, 0xe0, -0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed, 0xf8, 0xe6, 0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x02, -0x8d, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, -0x03, 0x02, 0x12, 0xb7, 0x02, 0x12, 0xaa, 0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, -0xfd, 0xed, 0xf5, 0x82, 0x8e, 0x83, 0xe0, 0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x02, 0x8d, 0x90, -0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, -0x12, 0xb7, 0x80, 0x76, 0xe4, 0xf5, 0x4e, 0xf5, 0x4f, 0x75, 0x26, 0xff, 0xc2, 0x19, 0xc2, 0x18, -0xc2, 0x1a, 0x75, 0x34, 0xff, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x02, 0x8d, 0x90, 0x04, 0x14, 0x74, -0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x5b, 0x80, 0x4c, 0x90, 0x70, -0x10, 0xe0, 0x24, 0xff, 0x92, 0x4a, 0xd2, 0x05, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x02, 0x8d, 0x90, -0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x38, 0x80, -0x29, 0x90, 0x70, 0x10, 0xe0, 0xf5, 0x34, 0xd3, 0x94, 0x00, 0x40, 0x07, 0x90, 0x01, 0x0d, 0xe0, -0x54, 0xfb, 0xf0, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x02, 0x8d, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, -0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x0d, 0x90, 0x70, 0x25, 0xe0, 0x44, 0x01, -0xf0, 0x90, 0x02, 0x2c, 0x74, 0xff, 0xf0, 0x22, 0x22, 0xe5, 0x53, 0x60, 0x03, 0x02, 0x13, 0x3d, -0xe5, 0x4f, 0x45, 0x4e, 0x60, 0x08, 0xe5, 0x4f, 0x15, 0x4f, 0x70, 0x02, 0x15, 0x4e, 0xa2, 0x19, -0xe4, 0x33, 0x90, 0x70, 0x90, 0xf0, 0xa2, 0x18, 0xe4, 0x33, 0xa3, 0xf0, 0x30, 0x19, 0x4d, 0x90, -0x70, 0x98, 0x74, 0x23, 0xf0, 0xa3, 0xe5, 0x25, 0xf0, 0xe5, 0x24, 0xa3, 0xf0, 0x7f, 0x35, 0x7d, -0x32, 0x12, 0x03, 0x42, 0x50, 0x09, 0x90, 0x10, 0x04, 0xe0, 0x54, 0xf7, 0xf0, 0xd2, 0x06, 0xe5, -0x35, 0xd3, 0x94, 0x10, 0x40, 0x1e, 0x30, 0x1a, 0x1b, 0xc2, 0x1a, 0xa2, 0x18, 0x92, 0x19, 0x20, -0x19, 0x12, 0x90, 0x04, 0x09, 0xe0, 0x54, 0xdd, 0xf0, 0x90, 0x10, 0x04, 0xe0, 0x44, 0x08, 0xf0, -0xc2, 0x61, 0xd2, 0x03, 0xe5, 0x35, 0xb4, 0x0b, 0x14, 0xd2, 0x03, 0x22, 0xe4, 0xf5, 0x35, 0xa2, -0x18, 0x92, 0x19, 0x30, 0x19, 0x07, 0x90, 0x04, 0x09, 0xe0, 0x44, 0x22, 0xf0, 0x22, 0x22, 0x22, -0xc2, 0x4b, 0xc2, 0x4c, 0xe5, 0x44, 0x12, 0x02, 0x67, 0x13, 0x62, 0x00, 0x13, 0xf5, 0x04, 0x13, -0xf1, 0x08, 0x13, 0xcc, 0x10, 0x13, 0x76, 0x20, 0x13, 0x96, 0x60, 0x13, 0xa7, 0xa0, 0x00, 0x00, -0x13, 0xf7, 0x85, 0x48, 0x43, 0x85, 0x4a, 0x42, 0x85, 0x4c, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x60, -0x03, 0x02, 0x13, 0xf7, 0x80, 0x1b, 0xe5, 0x48, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4a, 0xc4, -0x54, 0x0f, 0xf5, 0x42, 0xe5, 0x4c, 0xc4, 0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, -0x66, 0x53, 0x43, 0x0f, 0x80, 0x61, 0x85, 0x49, 0x43, 0x85, 0x4b, 0x42, 0x85, 0x4d, 0x5e, 0xe5, -0x47, 0x64, 0x06, 0x70, 0x52, 0x80, 0x1b, 0xe5, 0x49, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4b, -0xc4, 0x54, 0x0f, 0xf5, 0x42, 0xe5, 0x4d, 0xc4, 0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, -0x70, 0x35, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x10, 0xf5, 0x43, 0x80, 0x2b, 0xe5, 0x47, 0xb4, 0x04, -0x06, 0x53, 0x5e, 0xfb, 0x75, 0x42, 0x09, 0xe5, 0x47, 0xb4, 0x05, 0x06, 0x43, 0x5e, 0x04, 0x75, -0x42, 0x09, 0xe5, 0x47, 0xb4, 0x06, 0x10, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x30, 0xf5, 0x43, 0x80, -0x06, 0xd2, 0x4b, 0x80, 0x02, 0xd2, 0x4c, 0xe4, 0xf5, 0x38, 0xe5, 0x42, 0xc4, 0x54, 0xf0, 0xff, -0xe5, 0x43, 0x54, 0x0f, 0x4f, 0xf5, 0x5f, 0x90, 0x70, 0x44, 0xf0, 0xa3, 0xe5, 0x5e, 0xf0, 0xa3, -0xe5, 0x4a, 0xf0, 0xa3, 0xe5, 0x48, 0xf0, 0xa3, 0xe5, 0x4c, 0xf0, 0xa3, 0xe5, 0x44, 0xf0, 0xa3, -0xe5, 0x42, 0xf0, 0xa3, 0xe5, 0x43, 0xf0, 0xd2, 0x60, 0x22, 0xe5, 0x47, 0x60, 0x10, 0x24, 0xc0, -0x70, 0x03, 0x12, 0x16, 0x36, 0x12, 0x14, 0x3f, 0xc2, 0xaf, 0xc2, 0x04, 0xd2, 0xaf, 0x22, 0xc2, -0xaf, 0x90, 0x04, 0x14, 0xe0, 0x54, 0x0e, 0x60, 0x04, 0xd2, 0x1c, 0x80, 0x08, 0xe5, 0x4e, 0x45, -0x4f, 0x24, 0xff, 0x92, 0x1c, 0xd2, 0xaf, 0x90, 0x04, 0x14, 0xe0, 0xa2, 0xe4, 0x92, 0x1d, 0x74, -0x1e, 0xf0, 0xe5, 0x5f, 0x54, 0x0f, 0xf5, 0x2d, 0xe5, 0x38, 0x70, 0x13, 0x30, 0x1c, 0x05, 0xe5, -0x5f, 0x20, 0xe5, 0x0b, 0x30, 0x1d, 0x19, 0xe5, 0x5f, 0x54, 0x30, 0xff, 0xbf, 0x30, 0x11, 0xe5, -0x38, 0x70, 0x05, 0x75, 0x38, 0x0c, 0x80, 0x02, 0x15, 0x38, 0xd2, 0x6c, 0xd2, 0x6d, 0x80, 0x0f, -0xe5, 0x5f, 0x30, 0xe6, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0xe5, -0x47, 0x64, 0x03, 0x70, 0x21, 0x30, 0x4b, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x18, 0xe5, 0x38, -0x70, 0x03, 0x30, 0x4c, 0x11, 0xc2, 0x4c, 0xe5, 0x38, 0x70, 0x05, 0x75, 0x38, 0x07, 0x80, 0x02, -0x15, 0x38, 0xd2, 0x6c, 0xd2, 0x6d, 0x90, 0x70, 0x46, 0xe5, 0x2d, 0xf0, 0x20, 0x69, 0x07, 0xe5, -0x5e, 0x20, 0xe0, 0x02, 0xb2, 0x68, 0x20, 0x6b, 0x07, 0xe5, 0x5e, 0x20, 0xe1, 0x02, 0xb2, 0x6a, -0x20, 0x6d, 0x07, 0xe5, 0x5e, 0x20, 0xe2, 0x02, 0xb2, 0x6c, 0x90, 0x70, 0x47, 0xe5, 0x2d, 0xf0, -0x75, 0x2e, 0x40, 0x20, 0x69, 0x04, 0xa2, 0x68, 0x80, 0x15, 0x30, 0x68, 0x06, 0xe5, 0x46, 0xa2, -0xe3, 0x80, 0x0c, 0xe5, 0x46, 0x54, 0xf0, 0xff, 0xbf, 0xf0, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, -0x73, 0x92, 0x72, 0x20, 0x6b, 0x04, 0xa2, 0x6a, 0x80, 0x15, 0x30, 0x6a, 0x06, 0xe5, 0x46, 0xa2, -0xe3, 0x80, 0x0c, 0xe5, 0x46, 0x54, 0xf0, 0xff, 0xbf, 0xf0, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, -0x75, 0x92, 0x74, 0x20, 0x6d, 0x04, 0xa2, 0x6c, 0x80, 0x15, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, -0xe3, 0x80, 0x0c, 0xe5, 0x46, 0x54, 0xf0, 0xff, 0xbf, 0xf0, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, -0x71, 0x92, 0x70, 0x90, 0x10, 0x2f, 0xe5, 0x2e, 0xf0, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x46, 0x90, -0x02, 0x29, 0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x43, 0xc4, 0x54, 0x0f, 0x14, 0x60, 0x14, 0x24, 0xfe, -0x60, 0x1f, 0x24, 0x03, 0x60, 0x03, 0x02, 0x16, 0x35, 0x90, 0x02, 0x28, 0xe0, 0x30, 0x47, 0x0d, -0x80, 0x07, 0x90, 0x02, 0x28, 0xe0, 0x20, 0x47, 0x04, 0x54, 0xfe, 0xf0, 0x22, 0x44, 0x01, 0xf0, -0x22, 0xe5, 0x46, 0x30, 0xe3, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0x90, 0x02, 0x28, 0xe0, -0x54, 0xfe, 0x4f, 0xf0, 0x22, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x03, 0x02, 0x16, 0x35, 0xf5, 0x27, -0x90, 0x02, 0x29, 0xe0, 0x54, 0xfc, 0xf0, 0xe5, 0x26, 0x14, 0x60, 0x26, 0x14, 0x60, 0x2e, 0x14, -0x60, 0x36, 0x24, 0x03, 0x70, 0x5f, 0xe5, 0x46, 0x13, 0x13, 0x13, 0x54, 0x1f, 0x75, 0xf0, 0x03, -0x84, 0xaf, 0xf0, 0x20, 0x47, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xef, 0x6e, 0x24, 0xff, -0x80, 0x02, 0xa2, 0x47, 0x92, 0x39, 0xa2, 0x47, 0xb3, 0x92, 0x38, 0x80, 0x3f, 0xe5, 0x46, 0x30, -0xe3, 0x03, 0xd3, 0x80, 0x27, 0xc3, 0x80, 0x24, 0xe5, 0x46, 0x30, 0xe3, 0x0d, 0x54, 0x70, 0xc3, -0x94, 0x60, 0x50, 0x06, 0x7e, 0x00, 0x7f, 0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0x20, 0x47, -0x04, 0x7d, 0x01, 0x80, 0x02, 0x7d, 0x00, 0xef, 0x6d, 0x4e, 0x24, 0xff, 0x92, 0x38, 0xa2, 0x47, -0xb3, 0x92, 0x39, 0x80, 0x07, 0xa2, 0x47, 0xb3, 0x92, 0x38, 0x92, 0x39, 0x90, 0x02, 0x28, 0xe0, -0x54, 0xfc, 0x45, 0x27, 0xf0, 0x22, 0xe4, 0x90, 0x02, 0x29, 0xf0, 0x30, 0x47, 0x04, 0xaf, 0x45, -0x80, 0x04, 0xe5, 0x45, 0xf4, 0xff, 0x90, 0x02, 0x28, 0xef, 0xf0, 0x22, 0x8f, 0x50, 0xd2, 0x59, -0x22, 0x8f, 0x54, 0xd2, 0x58, 0x22, 0xe4, 0xf5, 0x30, 0xc2, 0xaf, 0xe5, 0x51, 0x14, 0x60, 0x4a, -0x14, 0x60, 0x6a, 0x24, 0x02, 0x60, 0x03, 0x02, 0x17, 0x4c, 0xd2, 0x59, 0x75, 0x55, 0x01, 0x20, -0x19, 0x1c, 0x90, 0x02, 0x08, 0xe0, 0x54, 0xfe, 0xf0, 0xe0, 0x20, 0xe1, 0x23, 0x90, 0x04, 0x34, -0xe0, 0xb4, 0x02, 0x1c, 0xa3, 0xe0, 0xb4, 0x02, 0x17, 0xa3, 0xe0, 0xb4, 0x02, 0x12, 0x7f, 0x20, -0x12, 0x16, 0x4c, 0x90, 0x10, 0x04, 0xe0, 0x54, 0xf3, 0xf0, 0x75, 0x51, 0x01, 0x02, 0x17, 0x4c, -0xe5, 0x50, 0x70, 0x06, 0x75, 0x30, 0x03, 0x02, 0x17, 0x4c, 0x90, 0x12, 0x00, 0xe0, 0x54, 0x03, -0x70, 0x15, 0x7f, 0x20, 0x12, 0x16, 0x4c, 0x20, 0x19, 0x07, 0x90, 0x02, 0x08, 0xe0, 0x54, 0xfb, -0xf0, 0x75, 0x51, 0x02, 0x02, 0x17, 0x4c, 0xe5, 0x50, 0x70, 0x02, 0x80, 0x7a, 0x20, 0x19, 0x0f, -0x90, 0x02, 0x08, 0xe0, 0x20, 0xe3, 0x6c, 0x90, 0x04, 0x37, 0xe0, 0x64, 0x22, 0x70, 0x64, 0x90, -0x12, 0x04, 0x74, 0x0a, 0xf0, 0x30, 0x1b, 0x11, 0x90, 0x13, 0x28, 0xe0, 0x54, 0xf0, 0xf0, 0xa3, -0xe0, 0x54, 0xf0, 0xf0, 0xa3, 0xe0, 0x54, 0xfa, 0xf0, 0x20, 0x19, 0x07, 0x90, 0x04, 0x01, 0xe0, -0x44, 0x10, 0xf0, 0xe5, 0x34, 0xf4, 0x90, 0x04, 0x01, 0x60, 0x06, 0xe0, 0x54, 0xfb, 0xf0, 0x80, -0x04, 0xe0, 0x54, 0xf9, 0xf0, 0x20, 0x19, 0x07, 0x90, 0x12, 0x04, 0xe0, 0x44, 0x04, 0xf0, 0xe5, -0x34, 0xf4, 0x60, 0x14, 0x90, 0x01, 0x0d, 0xe0, 0xf5, 0x33, 0xe5, 0x34, 0xd3, 0x94, 0x02, 0x40, -0x07, 0x90, 0x12, 0x04, 0xe0, 0x54, 0xfd, 0xf0, 0x75, 0x30, 0x01, 0x75, 0x55, 0x02, 0xe4, 0xf5, -0x51, 0x80, 0x09, 0xe5, 0x50, 0x70, 0x05, 0x75, 0x30, 0x03, 0xf5, 0x51, 0xe5, 0x30, 0x60, 0x18, -0xc2, 0x01, 0xe4, 0xf5, 0x51, 0xc2, 0x59, 0x20, 0x19, 0x0e, 0xad, 0x30, 0xaf, 0x40, 0x12, 0x18, -0x2a, 0xe5, 0x30, 0xb4, 0x03, 0x02, 0xd2, 0x03, 0xd2, 0xaf, 0x22, 0xc2, 0xaf, 0x30, 0x01, 0x0e, -0xe4, 0xf5, 0x51, 0xc2, 0x59, 0xc2, 0x01, 0x7d, 0x02, 0xaf, 0x40, 0x12, 0x18, 0x2a, 0xe5, 0x52, -0x14, 0x60, 0x55, 0x14, 0x60, 0x2f, 0x24, 0x02, 0x60, 0x03, 0x02, 0x18, 0x27, 0xe5, 0x34, 0xf4, -0x60, 0x23, 0xe5, 0x34, 0xd3, 0x94, 0x02, 0x40, 0x16, 0x90, 0x12, 0x04, 0xe0, 0x44, 0x02, 0xf0, -0x90, 0x01, 0x0d, 0xe0, 0x20, 0xe3, 0x03, 0x02, 0x18, 0x27, 0x7f, 0x50, 0x12, 0x16, 0x51, 0x75, -0x52, 0x02, 0x75, 0x55, 0x03, 0xe5, 0x34, 0xf4, 0x60, 0x0a, 0xe5, 0x54, 0x70, 0x69, 0x90, 0x01, -0x0d, 0xe5, 0x33, 0xf0, 0x90, 0x12, 0x04, 0xe0, 0x54, 0xfb, 0xf0, 0x7f, 0x20, 0x12, 0x16, 0x51, -0x75, 0x52, 0x01, 0x75, 0x55, 0x03, 0x80, 0x4f, 0xe5, 0x54, 0x70, 0x4b, 0x90, 0x04, 0x01, 0xe0, -0x44, 0x0e, 0xf0, 0x20, 0x19, 0x04, 0xe0, 0x54, 0xef, 0xf0, 0x90, 0x13, 0x28, 0xe0, 0x44, 0x0f, -0xf0, 0xa3, 0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x05, 0xf0, 0x90, 0x12, 0x04, 0x74, 0x03, -0xf0, 0x20, 0x19, 0x07, 0x90, 0x02, 0x08, 0xe0, 0x44, 0x05, 0xf0, 0x90, 0x10, 0x04, 0xe0, 0x44, -0x0c, 0xf0, 0xe4, 0xf5, 0x52, 0xf5, 0x55, 0x30, 0x02, 0x0b, 0xc2, 0x02, 0x7d, 0x01, 0xaf, 0x41, -0x12, 0x18, 0x2a, 0x80, 0x02, 0xc2, 0x03, 0xd2, 0xaf, 0x22, 0xef, 0xf4, 0x60, 0x2d, 0xe4, 0xfe, -0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xe0, 0xb4, 0xff, 0x19, 0x74, 0x14, -0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xef, 0xf0, 0x74, 0x1c, 0x2e, 0xf5, 0x82, 0xe4, -0x34, 0x70, 0xf5, 0x83, 0xed, 0xf0, 0x22, 0x0e, 0xbe, 0x04, 0xd5, 0x22, 0x22, 0x22, 0x20, 0x19, -0x03, 0x02, 0x19, 0x0f, 0x90, 0x70, 0x80, 0xe0, 0x04, 0xf0, 0x90, 0x04, 0x37, 0xe0, 0x30, 0xe5, -0x03, 0x02, 0x19, 0x0b, 0x90, 0x04, 0x28, 0xe0, 0xf5, 0x31, 0xa3, 0xe0, 0xf5, 0x30, 0xf5, 0x32, -0xe4, 0xf5, 0x37, 0x90, 0x70, 0x81, 0xe0, 0x04, 0xf0, 0x90, 0x70, 0x82, 0xe0, 0x04, 0xf0, 0xe5, -0x32, 0x75, 0xf0, 0x80, 0xa4, 0x24, 0x00, 0xff, 0xe5, 0xf0, 0x34, 0x80, 0xfe, 0xe5, 0x30, 0x65, -0x32, 0x70, 0x05, 0xfc, 0x7d, 0x18, 0x80, 0x04, 0x7c, 0x00, 0x7d, 0x00, 0xef, 0x2d, 0xff, 0xee, -0x3c, 0xfe, 0x12, 0x19, 0x10, 0x50, 0x25, 0x90, 0x70, 0x83, 0xe0, 0x04, 0xf0, 0x90, 0x01, 0x14, -0xe0, 0x44, 0x02, 0xf0, 0xe0, 0x30, 0xe1, 0x06, 0x90, 0x70, 0x92, 0x74, 0x45, 0xf0, 0x90, 0x70, -0x93, 0xe0, 0x04, 0xf0, 0x90, 0x04, 0x01, 0xe0, 0x90, 0x70, 0x94, 0xf0, 0xe5, 0x32, 0x65, 0x31, -0x60, 0x10, 0xe4, 0x25, 0x32, 0xff, 0xe4, 0x34, 0x80, 0x8f, 0x82, 0xf5, 0x83, 0xe0, 0xf5, 0x32, -0x80, 0x97, 0x90, 0x04, 0x10, 0x74, 0x01, 0xf0, 0x90, 0x04, 0x28, 0xe5, 0x31, 0xf0, 0xa3, 0xe5, -0x30, 0xf0, 0x90, 0x04, 0x11, 0x74, 0x01, 0xf0, 0x02, 0x18, 0x6a, 0xc2, 0x06, 0xd2, 0x1a, 0x22, -0x90, 0x70, 0x84, 0xe5, 0x37, 0xf0, 0xc3, 0x94, 0x06, 0x50, 0x19, 0x8f, 0x82, 0x8e, 0x83, 0xe0, -0xb4, 0xff, 0x07, 0x05, 0x37, 0xe4, 0xf5, 0x36, 0x80, 0x59, 0xe4, 0xf5, 0x37, 0x8f, 0x82, 0x8e, -0x83, 0xf0, 0x80, 0x4f, 0xe5, 0x36, 0x75, 0xf0, 0x06, 0x84, 0x74, 0x08, 0x25, 0xf0, 0xf5, 0x82, -0xe4, 0x34, 0x10, 0xf5, 0x83, 0xe0, 0xfd, 0x8f, 0x82, 0x8e, 0x83, 0xe0, 0xfc, 0x6d, 0x70, 0x30, -0x90, 0x70, 0x88, 0xe0, 0x04, 0xf0, 0xa3, 0xe0, 0xfd, 0xd3, 0x95, 0x37, 0x40, 0x02, 0x80, 0x02, -0xad, 0x37, 0x90, 0x70, 0x89, 0xed, 0xf0, 0x05, 0x37, 0x05, 0x36, 0xe5, 0x36, 0x75, 0xf0, 0x06, -0x84, 0x74, 0x8a, 0x25, 0xf0, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xec, 0xf0, 0x80, 0x03, -0xe4, 0xf5, 0x37, 0x0f, 0xbf, 0x00, 0x01, 0x0e, 0xef, 0x54, 0x7f, 0x60, 0x0a, 0xe5, 0x37, 0xc3, -0x94, 0x4e, 0x50, 0x03, 0x02, 0x19, 0x10, 0xe5, 0x37, 0xb4, 0x4e, 0x03, 0xd3, 0x80, 0x01, 0xc3, -0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x94, 0xeb, } ; diff --git a/drivers/staging/rt2860/common/firmware_3070.h b/drivers/staging/rt2860/common/firmware_3070.h deleted file mode 100644 index b710d40..0000000 --- a/drivers/staging/rt2860/common/firmware_3070.h +++ /dev/null @@ -1,517 +0,0 @@ -/* AUTO GEN PLEASE DO NOT MODIFY IT */ -/* AUTO GEN PLEASE DO NOT MODIFY IT */ - - -u8 FirmwareImage_3070 [] = { -0xff, 0xff, 0xff, 0x02, 0x10, 0x28, 0x02, 0x10, 0x32, 0x02, 0x10, 0x78, 0x02, 0x13, 0x1f, 0x02, -0x13, 0x20, 0x02, 0x13, 0x3f, 0x02, 0x13, 0x44, 0x12, 0x13, 0x40, 0x22, 0x02, 0x17, 0xae, 0x02, -0x18, 0xd2, 0x02, 0x14, 0x3d, 0x02, 0x13, 0x78, 0x30, 0x05, 0x06, 0x20, 0x0d, 0x03, 0x12, 0x19, -0x95, 0x22, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe3, 0x1b, 0xe5, 0x4c, 0x30, 0xe0, 0x04, 0x7f, 0x40, -0x80, 0x02, 0x7f, 0x00, 0x90, 0x10, 0x2f, 0xef, 0xf0, 0x90, 0x01, 0x8c, 0x74, 0x08, 0xf0, 0xe4, -0x90, 0x01, 0xa7, 0xf0, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe0, 0x1c, 0x90, 0x01, 0x80, 0xe0, 0xb4, -0x02, 0x15, 0xa3, 0xe0, 0xb4, 0x01, 0x10, 0x90, 0x01, 0x84, 0xe0, 0xb4, 0x81, 0x09, 0x90, 0x01, -0x8c, 0x74, 0x01, 0xf0, 0x12, 0x0d, 0xc8, 0x22, 0x90, 0x04, 0x14, 0xe0, 0x20, 0xe7, 0x03, 0x02, -0x13, 0x1e, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x56, 0x90, 0x04, 0x04, 0xe0, 0x12, 0x0a, 0x9d, 0x10, -0xd9, 0x31, 0x10, 0xbd, 0x36, 0x11, 0x02, 0x50, 0x11, 0x39, 0x51, 0x11, 0x42, 0x52, 0x11, 0x42, -0x53, 0x11, 0x42, 0x54, 0x11, 0x83, 0x55, 0x11, 0xd2, 0x56, 0x12, 0x25, 0x70, 0x12, 0x50, 0x71, -0x12, 0x7e, 0x72, 0x12, 0xd5, 0x73, 0x12, 0xf6, 0x80, 0x00, 0x00, 0x13, 0x1e, 0x90, 0x70, 0x11, -0xe0, 0xf5, 0x3c, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe5, 0x56, -0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e, 0x02, 0x13, 0x17, 0x20, 0x02, 0x03, 0x30, 0x03, 0x1d, 0x7d, -0x02, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, -0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e, 0x02, 0x13, 0x17, 0x85, 0x56, 0x41, 0xd2, -0x02, 0x22, 0x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, 0xff, 0xbf, 0x0a, 0x0d, 0x90, 0x70, 0x11, 0xe0, -0xb4, 0x08, 0x06, 0x75, 0x4e, 0x01, 0x75, 0x4f, 0x84, 0x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, 0xff, -0xbf, 0x02, 0x12, 0x90, 0x70, 0x11, 0xe0, 0x64, 0x08, 0x60, 0x04, 0xe0, 0xb4, 0x20, 0x06, 0x75, -0x4e, 0x03, 0x75, 0x4f, 0x20, 0xe4, 0xf5, 0x27, 0x22, 0x90, 0x70, 0x11, 0xe0, 0x24, 0xff, 0x92, -0x47, 0x22, 0x90, 0x04, 0x04, 0xe0, 0x25, 0xe0, 0x24, 0x5d, 0xf5, 0x57, 0x90, 0x70, 0x10, 0xe0, -0xff, 0x74, 0x47, 0x25, 0x57, 0xf8, 0xc6, 0xef, 0xc6, 0x90, 0x70, 0x11, 0xe0, 0xff, 0x74, 0x48, -0x25, 0x57, 0xf8, 0xc6, 0xef, 0xc6, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, -0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e, -0x02, 0x13, 0x17, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x1d, 0xe5, 0x47, 0x64, 0x08, 0x60, 0x17, 0xe5, -0x47, 0x64, 0x09, 0x60, 0x11, 0xe5, 0x47, 0x64, 0x0a, 0x60, 0x0b, 0xe5, 0x47, 0x64, 0x0b, 0x60, -0x05, 0xe5, 0x47, 0xb4, 0x0c, 0x08, 0x90, 0x70, 0x11, 0xe0, 0x54, 0x0f, 0xf5, 0x3a, 0xe5, 0x47, -0xb4, 0x09, 0x08, 0xe5, 0x3a, 0xb4, 0x03, 0x03, 0xe4, 0xf5, 0x46, 0xe5, 0x47, 0xb4, 0x0a, 0x08, -0xe5, 0x3a, 0xb4, 0x01, 0x03, 0xe4, 0xf5, 0x46, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0xd2, -0x04, 0x22, 0x90, 0x70, 0x11, 0xe0, 0xf4, 0xff, 0x90, 0x70, 0x10, 0xe0, 0x5f, 0xff, 0x90, 0x70, -0x11, 0xe0, 0x55, 0x27, 0x4f, 0x90, 0x70, 0x18, 0xf0, 0x90, 0x70, 0x11, 0xe0, 0x90, 0x70, 0x19, -0xf0, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x30, 0x15, 0x03, 0xd2, 0x14, 0x22, 0x90, 0x70, -0x18, 0xe0, 0xf5, 0x27, 0x90, 0x02, 0x29, 0xe0, 0xff, 0x90, 0x70, 0x19, 0xe0, 0xfe, 0xef, 0x5e, -0x90, 0x02, 0x29, 0xf0, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5, 0x27, 0xf4, 0xff, 0x90, -0x02, 0x28, 0xef, 0xf0, 0x22, 0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed, -0xf8, 0xe6, 0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, -0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e, 0x02, 0x13, 0x17, -0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed, 0xf5, 0x82, 0x8e, 0x83, 0xe0, -0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, -0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e, 0x02, 0x13, 0x17, 0x90, 0x10, -0x00, 0xe0, 0xf5, 0x57, 0x90, 0x10, 0x02, 0xe0, 0xf5, 0x58, 0xa3, 0xe0, 0xf5, 0x59, 0xe5, 0x58, -0xb4, 0x70, 0x1e, 0xe5, 0x59, 0xb4, 0x30, 0x19, 0x90, 0x05, 0x08, 0xe0, 0x44, 0x01, 0xf0, 0xfd, -0x90, 0x05, 0x05, 0xe0, 0x54, 0xfb, 0xf0, 0x44, 0x04, 0xf0, 0xed, 0x54, 0xfe, 0x90, 0x05, 0x08, -0xf0, 0xe4, 0xf5, 0x4e, 0xf5, 0x4f, 0x75, 0x3a, 0xff, 0x75, 0x3c, 0xff, 0xad, 0x57, 0xaf, 0x56, -0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, -0xf4, 0x60, 0x4b, 0x80, 0x42, 0x90, 0x70, 0x10, 0xe0, 0x24, 0xff, 0x92, 0x93, 0xe4, 0xfd, 0xaf, -0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, -0x56, 0xf4, 0x60, 0x2a, 0x80, 0x21, 0x90, 0x70, 0x10, 0xe0, 0x24, 0xff, 0x92, 0x4a, 0xd2, 0x05, -0xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, -0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x07, 0x90, 0x70, 0x25, 0xe0, 0x44, 0x01, 0xf0, 0x22, 0x22, -0xe5, 0x53, 0x70, 0x1a, 0x30, 0x60, 0x09, 0xb2, 0x4d, 0x30, 0x4d, 0x04, 0x05, 0x46, 0xc2, 0x04, -0xe5, 0x4f, 0x45, 0x4e, 0x60, 0x08, 0xe5, 0x4f, 0x15, 0x4f, 0x70, 0x02, 0x15, 0x4e, 0x22, 0x22, -0xc2, 0x42, 0xd3, 0x22, 0x30, 0x14, 0x30, 0x90, 0x70, 0x19, 0xe0, 0x55, 0x27, 0xff, 0x90, 0x70, -0x18, 0xe0, 0x4f, 0xf5, 0x27, 0x90, 0x02, 0x29, 0xe0, 0xff, 0x90, 0x70, 0x19, 0xe0, 0xfe, 0xef, -0x5e, 0x90, 0x02, 0x29, 0xf0, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5, 0x27, 0xf4, 0xff, -0x90, 0x02, 0x28, 0xef, 0xf0, 0xc2, 0x14, 0x22, 0xc2, 0x4b, 0xc2, 0x4c, 0xe5, 0x44, 0x12, 0x0a, -0x9d, 0x13, 0x9a, 0x00, 0x14, 0x28, 0x04, 0x14, 0x24, 0x08, 0x14, 0x04, 0x10, 0x13, 0xae, 0x20, -0x13, 0xce, 0x60, 0x13, 0xdf, 0xa0, 0x00, 0x00, 0x14, 0x2a, 0x85, 0x48, 0x43, 0x85, 0x4a, 0x42, -0x85, 0x4c, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x60, 0x03, 0x02, 0x14, 0x2a, 0x80, 0x1b, 0xe5, 0x48, -0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4a, 0xc4, 0x54, 0x0f, 0xf5, 0x42, 0xe5, 0x4c, 0xc4, 0x54, -0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x61, 0x53, 0x43, 0x0f, 0x80, 0x5c, 0x85, 0x49, -0x43, 0x85, 0x4b, 0x42, 0x85, 0x4d, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x4d, 0x80, 0x1b, 0xe5, -0x49, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4b, 0xc4, 0x54, 0x0f, 0xf5, 0x42, 0xe5, 0x4d, 0xc4, -0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x30, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x10, -0xf5, 0x43, 0x80, 0x26, 0xe5, 0x47, 0x64, 0x04, 0x60, 0x05, 0xe5, 0x47, 0xb4, 0x05, 0x06, 0x43, -0x5e, 0x04, 0x75, 0x42, 0x09, 0xe5, 0x47, 0xb4, 0x06, 0x10, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x30, -0xf5, 0x43, 0x80, 0x06, 0xd2, 0x4b, 0x80, 0x02, 0xd2, 0x4c, 0xe4, 0xf5, 0x25, 0xe5, 0x42, 0xc4, -0x54, 0xf0, 0xff, 0xe5, 0x43, 0x54, 0x0f, 0x4f, 0xf5, 0x5f, 0xd2, 0x60, 0x22, 0xd2, 0x15, 0xe5, -0x47, 0x24, 0xf5, 0x60, 0x0b, 0x24, 0xcb, 0x60, 0x07, 0x24, 0x40, 0x70, 0x06, 0xc2, 0x15, 0x22, -0x12, 0x17, 0x79, 0x12, 0x14, 0x5f, 0xc2, 0x15, 0xc2, 0xaf, 0xc2, 0x04, 0xd2, 0xaf, 0x22, 0xc2, -0xaf, 0x90, 0x04, 0x14, 0xe0, 0x54, 0x0e, 0x60, 0x04, 0xd2, 0x18, 0x80, 0x08, 0xe5, 0x4e, 0x45, -0x4f, 0x24, 0xff, 0x92, 0x18, 0xd2, 0xaf, 0x90, 0x04, 0x14, 0xe0, 0xa2, 0xe4, 0x92, 0x19, 0x74, -0x1e, 0xf0, 0xe5, 0x5f, 0x54, 0x0f, 0xf5, 0x2d, 0xe5, 0x25, 0x70, 0x13, 0x30, 0x18, 0x05, 0xe5, -0x5f, 0x20, 0xe5, 0x0b, 0x30, 0x19, 0x19, 0xe5, 0x5f, 0x54, 0x30, 0xff, 0xbf, 0x30, 0x11, 0xe5, -0x25, 0x70, 0x05, 0x75, 0x25, 0x0c, 0x80, 0x02, 0x15, 0x25, 0xd2, 0x6c, 0xd2, 0x6d, 0x80, 0x0f, -0xe5, 0x5f, 0x30, 0xe6, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0xe5, -0x47, 0x64, 0x03, 0x70, 0x21, 0x30, 0x4b, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x18, 0xe5, 0x25, -0x70, 0x03, 0x30, 0x4c, 0x11, 0xc2, 0x4c, 0xe5, 0x25, 0x70, 0x05, 0x75, 0x25, 0x07, 0x80, 0x02, -0x15, 0x25, 0xd2, 0x6c, 0xd2, 0x6d, 0xe5, 0x47, 0xb4, 0x09, 0x14, 0xe5, 0x44, 0x20, 0xe3, 0x0b, -0xe5, 0x3a, 0x64, 0x02, 0x60, 0x05, 0xe5, 0x3a, 0xb4, 0x03, 0x04, 0xc2, 0x6c, 0xd2, 0x6d, 0xe5, -0x47, 0xb4, 0x0a, 0x13, 0xe5, 0x3a, 0xb4, 0x01, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x08, 0xe5, -0x3a, 0x70, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0x20, 0x69, 0x07, 0xe5, 0x5e, 0x20, 0xe0, 0x02, 0xb2, -0x68, 0x20, 0x6b, 0x07, 0xe5, 0x5e, 0x20, 0xe1, 0x02, 0xb2, 0x6a, 0x20, 0x6d, 0x07, 0xe5, 0x5e, -0x20, 0xe2, 0x02, 0xb2, 0x6c, 0x75, 0x2e, 0x40, 0x20, 0x69, 0x04, 0xa2, 0x68, 0x80, 0x26, 0x30, -0x68, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe2, 0x04, 0x7f, 0x01, 0x80, -0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, -0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x73, 0x92, 0x72, 0x20, 0x6b, 0x04, 0xa2, 0x6a, 0x80, 0x26, -0x30, 0x6a, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe0, 0x04, 0x7f, 0x01, -0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02, -0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x75, 0x92, 0x74, 0x20, 0x6d, 0x04, 0xa2, 0x6c, 0x80, -0x26, 0xe5, 0x47, 0x64, 0x0a, 0x70, 0x22, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, 0xe3, 0x80, 0x17, -0xe5, 0x3a, 0xb4, 0x01, 0x06, 0xe5, 0x46, 0xa2, 0xe3, 0x80, 0x34, 0xe5, 0x46, 0x20, 0xe4, 0x03, -0x30, 0xe5, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x80, 0x26, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, 0xe2, -0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe1, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, -0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, -0x71, 0x92, 0x70, 0x90, 0x10, 0x00, 0xe0, 0x90, 0x10, 0x2c, 0xf0, 0x90, 0x10, 0x03, 0xe0, 0xc3, -0x94, 0x30, 0x40, 0x14, 0xa2, 0x71, 0x92, 0x77, 0xa2, 0x70, 0x92, 0x76, 0xe5, 0x2e, 0x13, 0x13, -0x54, 0x3f, 0xf5, 0x2e, 0xc2, 0x77, 0xd2, 0x76, 0x90, 0x10, 0x2f, 0xe5, 0x2e, 0xf0, 0xe5, 0x47, -0x64, 0x06, 0x70, 0x39, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x43, 0xc4, 0x54, 0x0f, -0x14, 0x60, 0x0c, 0x24, 0xfe, 0x60, 0x0c, 0x24, 0x03, 0x70, 0x13, 0xc2, 0x38, 0x80, 0x0f, 0xd2, -0x38, 0x80, 0x0b, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x38, 0x30, 0x47, -0x05, 0xaf, 0x27, 0x02, 0x17, 0x73, 0xe5, 0x27, 0xf4, 0xff, 0x02, 0x17, 0x73, 0xe5, 0x47, 0x64, -0x07, 0x60, 0x0f, 0xe5, 0x47, 0x64, 0x08, 0x60, 0x09, 0xe5, 0x47, 0x64, 0x09, 0x60, 0x03, 0x02, -0x16, 0xf2, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfc, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x22, 0x14, 0x60, -0x25, 0x14, 0x60, 0x2d, 0x24, 0xfc, 0x60, 0x49, 0x24, 0xf9, 0x60, 0x14, 0x24, 0x0e, 0x70, 0x50, -0xe5, 0x46, 0x13, 0x13, 0x54, 0x3f, 0x75, 0xf0, 0x03, 0x84, 0xe5, 0xf0, 0x24, 0xff, 0x80, 0x3a, -0xd2, 0x39, 0xc2, 0x38, 0x80, 0x3e, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x1d, 0xc3, 0x80, -0x1a, 0xe5, 0x46, 0x30, 0xe2, 0x0d, 0x54, 0x38, 0xc3, 0x94, 0x30, 0x50, 0x06, 0x7e, 0x00, 0x7f, -0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0xee, 0x4f, 0x24, 0xff, 0x92, 0x38, 0xc2, 0x39, 0x80, -0x13, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x39, 0xc2, 0x38, 0x80, 0x04, -0xc2, 0x38, 0xc2, 0x39, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5, 0x27, 0xf4, 0xff, 0x02, -0x17, 0x73, 0xe5, 0x47, 0x64, 0x0c, 0x60, 0x06, 0xe5, 0x47, 0x64, 0x0b, 0x70, 0x7a, 0x90, 0x02, -0x29, 0xe0, 0x54, 0xfd, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x20, 0x14, 0x60, 0x21, 0x14, 0x60, 0x2b, -0x24, 0xfc, 0x60, 0x45, 0x24, 0xf9, 0x60, 0x12, 0x24, 0x0e, 0x70, 0x4a, 0xe5, 0x46, 0x13, 0x13, -0x54, 0x3f, 0x75, 0xf0, 0x03, 0x84, 0xe5, 0xf0, 0x80, 0x29, 0xd2, 0x39, 0x80, 0x3a, 0xe5, 0x46, -0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x39, 0x80, 0x2d, 0xe5, 0x46, 0x30, 0xe2, 0x0d, -0x54, 0x38, 0xc3, 0x94, 0x30, 0x50, 0x06, 0x7e, 0x00, 0x7f, 0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f, -0x00, 0xee, 0x4f, 0x24, 0xff, 0x92, 0x39, 0x80, 0x0f, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, -0x01, 0xc3, 0x92, 0x39, 0x80, 0x02, 0xc2, 0x39, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5, -0x27, 0xf4, 0xff, 0x90, 0x02, 0x28, 0xef, 0xf0, 0x22, 0xe5, 0x47, 0xb4, 0x0b, 0x10, 0x90, 0x02, -0x29, 0xe0, 0x54, 0xeb, 0xf0, 0xe5, 0x27, 0x54, 0xeb, 0x45, 0x45, 0xf5, 0x27, 0x22, 0xe4, 0x90, -0x02, 0x29, 0xf0, 0x30, 0x47, 0x04, 0xaf, 0x45, 0x80, 0x04, 0xe5, 0x45, 0xf4, 0xff, 0x90, 0x02, -0x28, 0xef, 0xf0, 0x22, 0x8f, 0x50, 0xd2, 0x59, 0x22, 0x8f, 0x54, 0xd2, 0x58, 0x22, 0xe4, 0xf5, -0x62, 0xc2, 0xaf, 0xe5, 0x51, 0x14, 0x60, 0x48, 0x14, 0x60, 0x66, 0x24, 0x02, 0x60, 0x03, 0x02, -0x18, 0xb6, 0xd2, 0x59, 0x75, 0x55, 0x01, 0x90, 0x02, 0xa2, 0xe0, 0x54, 0x7f, 0xf0, 0xa3, 0xe0, -0x20, 0xe7, 0x23, 0x90, 0x04, 0x34, 0xe0, 0xb4, 0x02, 0x1c, 0xa3, 0xe0, 0xb4, 0x02, 0x17, 0xa3, -0xe0, 0xb4, 0x02, 0x12, 0x7f, 0x20, 0x12, 0x17, 0xa4, 0x90, 0x10, 0x04, 0xe0, 0x54, 0xf3, 0xf0, -0x75, 0x51, 0x01, 0x02, 0x18, 0xb6, 0xe5, 0x50, 0x70, 0x06, 0x75, 0x62, 0x03, 0x02, 0x18, 0xb6, -0x90, 0x12, 0x00, 0xe0, 0x54, 0x03, 0x70, 0x12, 0x7f, 0x20, 0x12, 0x17, 0xa4, 0x90, 0x02, 0xa2, -0xe0, 0x54, 0xbf, 0xf0, 0x75, 0x51, 0x02, 0x02, 0x18, 0xb6, 0xe5, 0x50, 0x70, 0x03, 0x02, 0x18, -0xb1, 0x90, 0x02, 0xa3, 0xe0, 0x30, 0xe6, 0x03, 0x02, 0x18, 0xad, 0x90, 0x04, 0x37, 0xe0, 0x64, -0x22, 0x70, 0x7a, 0x90, 0x01, 0x8a, 0x74, 0x7e, 0xf0, 0x90, 0x01, 0x96, 0xf0, 0x90, 0x12, 0x04, -0x74, 0x0a, 0xf0, 0xe5, 0x58, 0xb4, 0x72, 0x15, 0xe5, 0x59, 0xb4, 0x35, 0x10, 0xe4, 0x90, 0x05, -0x00, 0xf0, 0xa3, 0x74, 0x08, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0x74, 0x03, 0xf0, 0x7f, 0x01, 0x12, -0x0d, 0x2a, 0x90, 0x13, 0x28, 0xe0, 0x54, 0xf0, 0xf0, 0xa3, 0xe0, 0x54, 0xf0, 0xf0, 0xe5, 0x59, -0xb4, 0x35, 0x14, 0xe5, 0x3c, 0xf4, 0x60, 0x06, 0xa3, 0xe0, 0x54, 0xf3, 0x80, 0x14, 0x90, 0x13, -0x2a, 0xe0, 0x54, 0xfb, 0xf0, 0x80, 0x14, 0xe5, 0x3c, 0xf4, 0x90, 0x13, 0x2a, 0x60, 0x08, 0xe0, -0x54, 0xf2, 0x45, 0x3c, 0xf0, 0x80, 0x04, 0xe0, 0x54, 0xfa, 0xf0, 0x90, 0x04, 0x01, 0xe0, 0x54, -0xfd, 0xf0, 0x75, 0x62, 0x01, 0x75, 0x55, 0x02, 0xe4, 0xf5, 0x51, 0x80, 0x09, 0xe5, 0x50, 0x70, -0x05, 0x75, 0x62, 0x03, 0xf5, 0x51, 0xe5, 0x62, 0x60, 0x15, 0xc2, 0x01, 0xe4, 0xf5, 0x51, 0xc2, -0x59, 0xad, 0x62, 0xaf, 0x40, 0x12, 0x19, 0x61, 0xe5, 0x62, 0xb4, 0x03, 0x02, 0xd2, 0x03, 0xd2, -0xaf, 0x22, 0xc2, 0xaf, 0x30, 0x01, 0x12, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xf5, 0x51, 0xc2, 0x59, -0xc2, 0x01, 0x7d, 0x02, 0xaf, 0x40, 0x12, 0x19, 0x61, 0xe5, 0x52, 0x14, 0x60, 0x09, 0x04, 0x70, -0x6d, 0x75, 0x52, 0x01, 0x75, 0x55, 0x03, 0x90, 0x04, 0x01, 0xe0, 0x44, 0x0e, 0xf0, 0x90, 0x13, -0x28, 0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x05, 0xf0, 0x90, -0x12, 0x04, 0x74, 0x03, 0xf0, 0xe5, 0x58, 0xb4, 0x72, 0x16, 0xe5, 0x59, 0xb4, 0x35, 0x11, 0x90, -0x05, 0x00, 0x74, 0xe2, 0xf0, 0xa3, 0x74, 0x08, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0x74, 0x03, 0xf0, -0x7f, 0x01, 0x12, 0x0d, 0x2a, 0x90, 0x02, 0xa2, 0xe0, 0x44, 0xc0, 0xf0, 0x90, 0x10, 0x04, 0xe0, -0x44, 0x0c, 0xf0, 0xe4, 0xf5, 0x52, 0xf5, 0x55, 0x30, 0x02, 0x09, 0xc2, 0x02, 0x7d, 0x01, 0xaf, -0x41, 0x12, 0x19, 0x61, 0x30, 0x03, 0x02, 0xc2, 0x03, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xd2, 0xaf, -0x22, 0xef, 0xf4, 0x60, 0x2d, 0xe4, 0xfe, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, -0x83, 0xe0, 0xb4, 0xff, 0x19, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xef, -0xf0, 0x74, 0x1c, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xed, 0xf0, 0x22, 0x0e, 0xbe, -0x04, 0xd5, 0x22, 0x22, 0x22, 0x90, 0x70, 0x2a, 0xe0, 0x30, 0xe1, 0x4d, 0xc2, 0xaf, 0x90, 0x70, -0x28, 0xe0, 0x90, 0x10, 0x1c, 0xf0, 0x90, 0x70, 0x29, 0xe0, 0x90, 0x10, 0x1d, 0xf0, 0x90, 0x70, -0x2a, 0xe0, 0x90, 0x10, 0x1e, 0xf0, 0x90, 0x10, 0x1c, 0xe0, 0xf5, 0x62, 0x90, 0x10, 0x1e, 0xe0, -0x20, 0xe1, 0xf3, 0x90, 0x10, 0x1c, 0xe0, 0x90, 0x70, 0x28, 0xf0, 0x90, 0x10, 0x1d, 0xe0, 0x90, -0x70, 0x29, 0xf0, 0x90, 0x10, 0x1e, 0xe0, 0x90, 0x70, 0x2a, 0xf0, 0x30, 0x4a, 0x07, 0x90, 0x70, -0x24, 0xe0, 0x44, 0x01, 0xf0, 0xc2, 0x05, 0xd2, 0xaf, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x7b, 0xc4, -0xff, 0xff, 0xff, 0x02, 0x10, 0x28, 0x02, 0x10, 0x32, 0x02, 0x10, 0x78, 0x02, 0x13, 0x1f, 0x02, -0x13, 0x20, 0x02, 0x13, 0x3f, 0x02, 0x13, 0x44, 0x12, 0x13, 0x40, 0x22, 0x02, 0x17, 0xae, 0x02, -0x18, 0xd2, 0x02, 0x14, 0x3d, 0x02, 0x13, 0x78, 0x30, 0x05, 0x06, 0x20, 0x0d, 0x03, 0x12, 0x19, -0x95, 0x22, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe3, 0x1b, 0xe5, 0x4c, 0x30, 0xe0, 0x04, 0x7f, 0x40, -0x80, 0x02, 0x7f, 0x00, 0x90, 0x10, 0x2f, 0xef, 0xf0, 0x90, 0x01, 0x8c, 0x74, 0x08, 0xf0, 0xe4, -0x90, 0x01, 0xa7, 0xf0, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe0, 0x1c, 0x90, 0x01, 0x80, 0xe0, 0xb4, -0x02, 0x15, 0xa3, 0xe0, 0xb4, 0x01, 0x10, 0x90, 0x01, 0x84, 0xe0, 0xb4, 0x81, 0x09, 0x90, 0x01, -0x8c, 0x74, 0x01, 0xf0, 0x12, 0x0d, 0xdd, 0x22, 0x90, 0x04, 0x14, 0xe0, 0x20, 0xe7, 0x03, 0x02, -0x13, 0x1e, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x56, 0x90, 0x04, 0x04, 0xe0, 0x12, 0x0a, 0xb6, 0x10, -0xd9, 0x31, 0x10, 0xbd, 0x36, 0x11, 0x02, 0x50, 0x11, 0x39, 0x51, 0x11, 0x42, 0x52, 0x11, 0x42, -0x53, 0x11, 0x42, 0x54, 0x11, 0x83, 0x55, 0x11, 0xd2, 0x56, 0x12, 0x25, 0x70, 0x12, 0x50, 0x71, -0x12, 0x7e, 0x72, 0x12, 0xd5, 0x73, 0x12, 0xf6, 0x80, 0x00, 0x00, 0x13, 0x1e, 0x90, 0x70, 0x11, -0xe0, 0xf5, 0x3c, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe5, 0x56, -0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e, 0x02, 0x13, 0x17, 0x20, 0x02, 0x03, 0x30, 0x03, 0x1d, 0x7d, -0x02, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, -0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e, 0x02, 0x13, 0x17, 0x85, 0x56, 0x41, 0xd2, -0x02, 0x22, 0x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, 0xff, 0xbf, 0x0a, 0x0d, 0x90, 0x70, 0x11, 0xe0, -0xb4, 0x08, 0x06, 0x75, 0x4e, 0x01, 0x75, 0x4f, 0x84, 0x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, 0xff, -0xbf, 0x02, 0x12, 0x90, 0x70, 0x11, 0xe0, 0x64, 0x08, 0x60, 0x04, 0xe0, 0xb4, 0x20, 0x06, 0x75, -0x4e, 0x03, 0x75, 0x4f, 0x20, 0xe4, 0xf5, 0x27, 0x22, 0x90, 0x70, 0x11, 0xe0, 0x24, 0xff, 0x92, -0x47, 0x22, 0x90, 0x04, 0x04, 0xe0, 0x25, 0xe0, 0x24, 0x5d, 0xf5, 0x57, 0x90, 0x70, 0x10, 0xe0, -0xff, 0x74, 0x47, 0x25, 0x57, 0xf8, 0xc6, 0xef, 0xc6, 0x90, 0x70, 0x11, 0xe0, 0xff, 0x74, 0x48, -0x25, 0x57, 0xf8, 0xc6, 0xef, 0xc6, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, -0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e, -0x02, 0x13, 0x17, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x1d, 0xe5, 0x47, 0x64, 0x08, 0x60, 0x17, 0xe5, -0x47, 0x64, 0x09, 0x60, 0x11, 0xe5, 0x47, 0x64, 0x0a, 0x60, 0x0b, 0xe5, 0x47, 0x64, 0x0b, 0x60, -0x05, 0xe5, 0x47, 0xb4, 0x0c, 0x08, 0x90, 0x70, 0x11, 0xe0, 0x54, 0x0f, 0xf5, 0x3a, 0xe5, 0x47, -0xb4, 0x09, 0x08, 0xe5, 0x3a, 0xb4, 0x03, 0x03, 0xe4, 0xf5, 0x46, 0xe5, 0x47, 0xb4, 0x0a, 0x08, -0xe5, 0x3a, 0xb4, 0x01, 0x03, 0xe4, 0xf5, 0x46, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0xd2, -0x04, 0x22, 0x90, 0x70, 0x11, 0xe0, 0xf4, 0xff, 0x90, 0x70, 0x10, 0xe0, 0x5f, 0xff, 0x90, 0x70, -0x11, 0xe0, 0x55, 0x27, 0x4f, 0x90, 0x70, 0x18, 0xf0, 0x90, 0x70, 0x11, 0xe0, 0x90, 0x70, 0x19, -0xf0, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x30, 0x15, 0x03, 0xd2, 0x14, 0x22, 0x90, 0x70, -0x18, 0xe0, 0xf5, 0x27, 0x90, 0x02, 0x29, 0xe0, 0xff, 0x90, 0x70, 0x19, 0xe0, 0xfe, 0xef, 0x5e, -0x90, 0x02, 0x29, 0xf0, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5, 0x27, 0xf4, 0xff, 0x90, -0x02, 0x28, 0xef, 0xf0, 0x22, 0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed, -0xf8, 0xe6, 0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, -0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e, 0x02, 0x13, 0x17, -0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed, 0xf5, 0x82, 0x8e, 0x83, 0xe0, -0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, -0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e, 0x02, 0x13, 0x17, 0x90, 0x10, -0x00, 0xe0, 0xf5, 0x57, 0x90, 0x10, 0x02, 0xe0, 0xf5, 0x58, 0xa3, 0xe0, 0xf5, 0x59, 0xe5, 0x58, -0xb4, 0x70, 0x1e, 0xe5, 0x59, 0xb4, 0x30, 0x19, 0x90, 0x05, 0x08, 0xe0, 0x44, 0x01, 0xf0, 0xfd, -0x90, 0x05, 0x05, 0xe0, 0x54, 0xfb, 0xf0, 0x44, 0x04, 0xf0, 0xed, 0x54, 0xfe, 0x90, 0x05, 0x08, -0xf0, 0xe4, 0xf5, 0x4e, 0xf5, 0x4f, 0x75, 0x3a, 0xff, 0x75, 0x3c, 0xff, 0xad, 0x57, 0xaf, 0x56, -0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, -0xf4, 0x60, 0x4b, 0x80, 0x42, 0x90, 0x70, 0x10, 0xe0, 0x24, 0xff, 0x92, 0x93, 0xe4, 0xfd, 0xaf, -0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, -0x56, 0xf4, 0x60, 0x2a, 0x80, 0x21, 0x90, 0x70, 0x10, 0xe0, 0x24, 0xff, 0x92, 0x4a, 0xd2, 0x05, -0xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, -0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x07, 0x90, 0x70, 0x25, 0xe0, 0x44, 0x01, 0xf0, 0x22, 0x22, -0xe5, 0x53, 0x70, 0x1a, 0x30, 0x60, 0x09, 0xb2, 0x4d, 0x30, 0x4d, 0x04, 0x05, 0x46, 0xc2, 0x04, -0xe5, 0x4f, 0x45, 0x4e, 0x60, 0x08, 0xe5, 0x4f, 0x15, 0x4f, 0x70, 0x02, 0x15, 0x4e, 0x22, 0x22, -0xc2, 0x42, 0xd3, 0x22, 0x30, 0x14, 0x30, 0x90, 0x70, 0x19, 0xe0, 0x55, 0x27, 0xff, 0x90, 0x70, -0x18, 0xe0, 0x4f, 0xf5, 0x27, 0x90, 0x02, 0x29, 0xe0, 0xff, 0x90, 0x70, 0x19, 0xe0, 0xfe, 0xef, -0x5e, 0x90, 0x02, 0x29, 0xf0, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5, 0x27, 0xf4, 0xff, -0x90, 0x02, 0x28, 0xef, 0xf0, 0xc2, 0x14, 0x22, 0xc2, 0x4b, 0xc2, 0x4c, 0xe5, 0x44, 0x12, 0x0a, -0xb6, 0x13, 0x9a, 0x00, 0x14, 0x28, 0x04, 0x14, 0x24, 0x08, 0x14, 0x04, 0x10, 0x13, 0xae, 0x20, -0x13, 0xce, 0x60, 0x13, 0xdf, 0xa0, 0x00, 0x00, 0x14, 0x2a, 0x85, 0x48, 0x43, 0x85, 0x4a, 0x42, -0x85, 0x4c, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x60, 0x03, 0x02, 0x14, 0x2a, 0x80, 0x1b, 0xe5, 0x48, -0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4a, 0xc4, 0x54, 0x0f, 0xf5, 0x42, 0xe5, 0x4c, 0xc4, 0x54, -0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x61, 0x53, 0x43, 0x0f, 0x80, 0x5c, 0x85, 0x49, -0x43, 0x85, 0x4b, 0x42, 0x85, 0x4d, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x4d, 0x80, 0x1b, 0xe5, -0x49, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4b, 0xc4, 0x54, 0x0f, 0xf5, 0x42, 0xe5, 0x4d, 0xc4, -0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x30, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x10, -0xf5, 0x43, 0x80, 0x26, 0xe5, 0x47, 0x64, 0x04, 0x60, 0x05, 0xe5, 0x47, 0xb4, 0x05, 0x06, 0x43, -0x5e, 0x04, 0x75, 0x42, 0x09, 0xe5, 0x47, 0xb4, 0x06, 0x10, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x30, -0xf5, 0x43, 0x80, 0x06, 0xd2, 0x4b, 0x80, 0x02, 0xd2, 0x4c, 0xe4, 0xf5, 0x25, 0xe5, 0x42, 0xc4, -0x54, 0xf0, 0xff, 0xe5, 0x43, 0x54, 0x0f, 0x4f, 0xf5, 0x5f, 0xd2, 0x60, 0x22, 0xd2, 0x15, 0xe5, -0x47, 0x24, 0xf5, 0x60, 0x0b, 0x24, 0xcb, 0x60, 0x07, 0x24, 0x40, 0x70, 0x06, 0xc2, 0x15, 0x22, -0x12, 0x17, 0x79, 0x12, 0x14, 0x5f, 0xc2, 0x15, 0xc2, 0xaf, 0xc2, 0x04, 0xd2, 0xaf, 0x22, 0xc2, -0xaf, 0x90, 0x04, 0x14, 0xe0, 0x54, 0x0e, 0x60, 0x04, 0xd2, 0x18, 0x80, 0x08, 0xe5, 0x4e, 0x45, -0x4f, 0x24, 0xff, 0x92, 0x18, 0xd2, 0xaf, 0x90, 0x04, 0x14, 0xe0, 0xa2, 0xe4, 0x92, 0x19, 0x74, -0x1e, 0xf0, 0xe5, 0x5f, 0x54, 0x0f, 0xf5, 0x2d, 0xe5, 0x25, 0x70, 0x13, 0x30, 0x18, 0x05, 0xe5, -0x5f, 0x20, 0xe5, 0x0b, 0x30, 0x19, 0x19, 0xe5, 0x5f, 0x54, 0x30, 0xff, 0xbf, 0x30, 0x11, 0xe5, -0x25, 0x70, 0x05, 0x75, 0x25, 0x0c, 0x80, 0x02, 0x15, 0x25, 0xd2, 0x6c, 0xd2, 0x6d, 0x80, 0x0f, -0xe5, 0x5f, 0x30, 0xe6, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0xe5, -0x47, 0x64, 0x03, 0x70, 0x21, 0x30, 0x4b, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x18, 0xe5, 0x25, -0x70, 0x03, 0x30, 0x4c, 0x11, 0xc2, 0x4c, 0xe5, 0x25, 0x70, 0x05, 0x75, 0x25, 0x07, 0x80, 0x02, -0x15, 0x25, 0xd2, 0x6c, 0xd2, 0x6d, 0xe5, 0x47, 0xb4, 0x09, 0x14, 0xe5, 0x44, 0x20, 0xe3, 0x0b, -0xe5, 0x3a, 0x64, 0x02, 0x60, 0x05, 0xe5, 0x3a, 0xb4, 0x03, 0x04, 0xc2, 0x6c, 0xd2, 0x6d, 0xe5, -0x47, 0xb4, 0x0a, 0x13, 0xe5, 0x3a, 0xb4, 0x01, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x08, 0xe5, -0x3a, 0x70, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0x20, 0x69, 0x07, 0xe5, 0x5e, 0x20, 0xe0, 0x02, 0xb2, -0x68, 0x20, 0x6b, 0x07, 0xe5, 0x5e, 0x20, 0xe1, 0x02, 0xb2, 0x6a, 0x20, 0x6d, 0x07, 0xe5, 0x5e, -0x20, 0xe2, 0x02, 0xb2, 0x6c, 0x75, 0x2e, 0x40, 0x20, 0x69, 0x04, 0xa2, 0x68, 0x80, 0x26, 0x30, -0x68, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe2, 0x04, 0x7f, 0x01, 0x80, -0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, -0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x73, 0x92, 0x72, 0x20, 0x6b, 0x04, 0xa2, 0x6a, 0x80, 0x26, -0x30, 0x6a, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe0, 0x04, 0x7f, 0x01, -0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02, -0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x75, 0x92, 0x74, 0x20, 0x6d, 0x04, 0xa2, 0x6c, 0x80, -0x26, 0xe5, 0x47, 0x64, 0x0a, 0x70, 0x22, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, 0xe3, 0x80, 0x17, -0xe5, 0x3a, 0xb4, 0x01, 0x06, 0xe5, 0x46, 0xa2, 0xe3, 0x80, 0x34, 0xe5, 0x46, 0x20, 0xe4, 0x03, -0x30, 0xe5, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x80, 0x26, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, 0xe2, -0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe1, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, -0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, -0x71, 0x92, 0x70, 0x90, 0x10, 0x00, 0xe0, 0x90, 0x10, 0x2c, 0xf0, 0x90, 0x10, 0x03, 0xe0, 0xc3, -0x94, 0x30, 0x40, 0x14, 0xa2, 0x71, 0x92, 0x77, 0xa2, 0x70, 0x92, 0x76, 0xe5, 0x2e, 0x13, 0x13, -0x54, 0x3f, 0xf5, 0x2e, 0xc2, 0x77, 0xd2, 0x76, 0x90, 0x10, 0x2f, 0xe5, 0x2e, 0xf0, 0xe5, 0x47, -0x64, 0x06, 0x70, 0x39, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x43, 0xc4, 0x54, 0x0f, -0x14, 0x60, 0x0c, 0x24, 0xfe, 0x60, 0x0c, 0x24, 0x03, 0x70, 0x13, 0xc2, 0x38, 0x80, 0x0f, 0xd2, -0x38, 0x80, 0x0b, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x38, 0x30, 0x47, -0x05, 0xaf, 0x27, 0x02, 0x17, 0x73, 0xe5, 0x27, 0xf4, 0xff, 0x02, 0x17, 0x73, 0xe5, 0x47, 0x64, -0x07, 0x60, 0x0f, 0xe5, 0x47, 0x64, 0x08, 0x60, 0x09, 0xe5, 0x47, 0x64, 0x09, 0x60, 0x03, 0x02, -0x16, 0xf2, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfc, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x22, 0x14, 0x60, -0x25, 0x14, 0x60, 0x2d, 0x24, 0xfc, 0x60, 0x49, 0x24, 0xf9, 0x60, 0x14, 0x24, 0x0e, 0x70, 0x50, -0xe5, 0x46, 0x13, 0x13, 0x54, 0x3f, 0x75, 0xf0, 0x03, 0x84, 0xe5, 0xf0, 0x24, 0xff, 0x80, 0x3a, -0xd2, 0x39, 0xc2, 0x38, 0x80, 0x3e, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x1d, 0xc3, 0x80, -0x1a, 0xe5, 0x46, 0x30, 0xe2, 0x0d, 0x54, 0x38, 0xc3, 0x94, 0x30, 0x50, 0x06, 0x7e, 0x00, 0x7f, -0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0xee, 0x4f, 0x24, 0xff, 0x92, 0x38, 0xc2, 0x39, 0x80, -0x13, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x39, 0xc2, 0x38, 0x80, 0x04, -0xc2, 0x38, 0xc2, 0x39, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5, 0x27, 0xf4, 0xff, 0x02, -0x17, 0x73, 0xe5, 0x47, 0x64, 0x0c, 0x60, 0x06, 0xe5, 0x47, 0x64, 0x0b, 0x70, 0x7a, 0x90, 0x02, -0x29, 0xe0, 0x54, 0xfd, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x20, 0x14, 0x60, 0x21, 0x14, 0x60, 0x2b, -0x24, 0xfc, 0x60, 0x45, 0x24, 0xf9, 0x60, 0x12, 0x24, 0x0e, 0x70, 0x4a, 0xe5, 0x46, 0x13, 0x13, -0x54, 0x3f, 0x75, 0xf0, 0x03, 0x84, 0xe5, 0xf0, 0x80, 0x29, 0xd2, 0x39, 0x80, 0x3a, 0xe5, 0x46, -0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x39, 0x80, 0x2d, 0xe5, 0x46, 0x30, 0xe2, 0x0d, -0x54, 0x38, 0xc3, 0x94, 0x30, 0x50, 0x06, 0x7e, 0x00, 0x7f, 0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f, -0x00, 0xee, 0x4f, 0x24, 0xff, 0x92, 0x39, 0x80, 0x0f, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, -0x01, 0xc3, 0x92, 0x39, 0x80, 0x02, 0xc2, 0x39, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5, -0x27, 0xf4, 0xff, 0x90, 0x02, 0x28, 0xef, 0xf0, 0x22, 0xe5, 0x47, 0xb4, 0x0b, 0x10, 0x90, 0x02, -0x29, 0xe0, 0x54, 0xeb, 0xf0, 0xe5, 0x27, 0x54, 0xeb, 0x45, 0x45, 0xf5, 0x27, 0x22, 0xe4, 0x90, -0x02, 0x29, 0xf0, 0x30, 0x47, 0x04, 0xaf, 0x45, 0x80, 0x04, 0xe5, 0x45, 0xf4, 0xff, 0x90, 0x02, -0x28, 0xef, 0xf0, 0x22, 0x8f, 0x50, 0xd2, 0x59, 0x22, 0x8f, 0x54, 0xd2, 0x58, 0x22, 0xe4, 0xf5, -0x62, 0xc2, 0xaf, 0xe5, 0x51, 0x14, 0x60, 0x48, 0x14, 0x60, 0x66, 0x24, 0x02, 0x60, 0x03, 0x02, -0x18, 0xb6, 0xd2, 0x59, 0x75, 0x55, 0x01, 0x90, 0x02, 0xa2, 0xe0, 0x54, 0x7f, 0xf0, 0xa3, 0xe0, -0x20, 0xe7, 0x23, 0x90, 0x04, 0x34, 0xe0, 0xb4, 0x02, 0x1c, 0xa3, 0xe0, 0xb4, 0x02, 0x17, 0xa3, -0xe0, 0xb4, 0x02, 0x12, 0x7f, 0x20, 0x12, 0x17, 0xa4, 0x90, 0x10, 0x04, 0xe0, 0x54, 0xf3, 0xf0, -0x75, 0x51, 0x01, 0x02, 0x18, 0xb6, 0xe5, 0x50, 0x70, 0x06, 0x75, 0x62, 0x03, 0x02, 0x18, 0xb6, -0x90, 0x12, 0x00, 0xe0, 0x54, 0x03, 0x70, 0x12, 0x7f, 0x20, 0x12, 0x17, 0xa4, 0x90, 0x02, 0xa2, -0xe0, 0x54, 0xbf, 0xf0, 0x75, 0x51, 0x02, 0x02, 0x18, 0xb6, 0xe5, 0x50, 0x70, 0x03, 0x02, 0x18, -0xb1, 0x90, 0x02, 0xa3, 0xe0, 0x30, 0xe6, 0x03, 0x02, 0x18, 0xad, 0x90, 0x04, 0x37, 0xe0, 0x64, -0x22, 0x70, 0x7a, 0x90, 0x01, 0x8a, 0x74, 0x7e, 0xf0, 0x90, 0x01, 0x96, 0xf0, 0x90, 0x12, 0x04, -0x74, 0x0a, 0xf0, 0xe5, 0x58, 0xb4, 0x72, 0x15, 0xe5, 0x59, 0xb4, 0x35, 0x10, 0xe4, 0x90, 0x05, -0x00, 0xf0, 0xa3, 0x74, 0x08, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0x74, 0x03, 0xf0, 0x7f, 0x01, 0x12, -0x0d, 0x48, 0x90, 0x13, 0x28, 0xe0, 0x54, 0xf0, 0xf0, 0xa3, 0xe0, 0x54, 0xf0, 0xf0, 0xe5, 0x59, -0xb4, 0x35, 0x14, 0xe5, 0x3c, 0xf4, 0x60, 0x06, 0xa3, 0xe0, 0x54, 0xf3, 0x80, 0x14, 0x90, 0x13, -0x2a, 0xe0, 0x54, 0xfb, 0xf0, 0x80, 0x14, 0xe5, 0x3c, 0xf4, 0x90, 0x13, 0x2a, 0x60, 0x08, 0xe0, -0x54, 0xf2, 0x45, 0x3c, 0xf0, 0x80, 0x04, 0xe0, 0x54, 0xfa, 0xf0, 0x90, 0x04, 0x01, 0xe0, 0x54, -0xfd, 0xf0, 0x75, 0x62, 0x01, 0x75, 0x55, 0x02, 0xe4, 0xf5, 0x51, 0x80, 0x09, 0xe5, 0x50, 0x70, -0x05, 0x75, 0x62, 0x03, 0xf5, 0x51, 0xe5, 0x62, 0x60, 0x15, 0xc2, 0x01, 0xe4, 0xf5, 0x51, 0xc2, -0x59, 0xad, 0x62, 0xaf, 0x40, 0x12, 0x19, 0x61, 0xe5, 0x62, 0xb4, 0x03, 0x02, 0xd2, 0x03, 0xd2, -0xaf, 0x22, 0xc2, 0xaf, 0x30, 0x01, 0x12, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xf5, 0x51, 0xc2, 0x59, -0xc2, 0x01, 0x7d, 0x02, 0xaf, 0x40, 0x12, 0x19, 0x61, 0xe5, 0x52, 0x14, 0x60, 0x09, 0x04, 0x70, -0x6d, 0x75, 0x52, 0x01, 0x75, 0x55, 0x03, 0x90, 0x04, 0x01, 0xe0, 0x44, 0x0e, 0xf0, 0x90, 0x13, -0x28, 0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x05, 0xf0, 0x90, -0x12, 0x04, 0x74, 0x03, 0xf0, 0xe5, 0x58, 0xb4, 0x72, 0x16, 0xe5, 0x59, 0xb4, 0x35, 0x11, 0x90, -0x05, 0x00, 0x74, 0xe2, 0xf0, 0xa3, 0x74, 0x08, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0x74, 0x03, 0xf0, -0x7f, 0x01, 0x12, 0x0d, 0x48, 0x90, 0x02, 0xa2, 0xe0, 0x44, 0xc0, 0xf0, 0x90, 0x10, 0x04, 0xe0, -0x44, 0x0c, 0xf0, 0xe4, 0xf5, 0x52, 0xf5, 0x55, 0x30, 0x02, 0x09, 0xc2, 0x02, 0x7d, 0x01, 0xaf, -0x41, 0x12, 0x19, 0x61, 0x30, 0x03, 0x02, 0xc2, 0x03, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xd2, 0xaf, -0x22, 0xef, 0xf4, 0x60, 0x2d, 0xe4, 0xfe, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, -0x83, 0xe0, 0xb4, 0xff, 0x19, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xef, -0xf0, 0x74, 0x1c, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xed, 0xf0, 0x22, 0x0e, 0xbe, -0x04, 0xd5, 0x22, 0x22, 0x22, 0x90, 0x70, 0x2a, 0xe0, 0x30, 0xe1, 0x4d, 0xc2, 0xaf, 0x90, 0x70, -0x28, 0xe0, 0x90, 0x10, 0x1c, 0xf0, 0x90, 0x70, 0x29, 0xe0, 0x90, 0x10, 0x1d, 0xf0, 0x90, 0x70, -0x2a, 0xe0, 0x90, 0x10, 0x1e, 0xf0, 0x90, 0x10, 0x1c, 0xe0, 0xf5, 0x62, 0x90, 0x10, 0x1e, 0xe0, -0x20, 0xe1, 0xf3, 0x90, 0x10, 0x1c, 0xe0, 0x90, 0x70, 0x28, 0xf0, 0x90, 0x10, 0x1d, 0xe0, 0x90, -0x70, 0x29, 0xf0, 0x90, 0x10, 0x1e, 0xe0, 0x90, 0x70, 0x2a, 0xf0, 0x30, 0x4a, 0x07, 0x90, 0x70, -0x24, 0xe0, 0x44, 0x01, 0xf0, 0xc2, 0x05, 0xd2, 0xaf, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x65, 0xd3, } ; diff --git a/drivers/staging/rt2860/common/rtmp_mcu.c b/drivers/staging/rt2860/common/rtmp_mcu.c index 9f03901..844d4b9 100644 --- a/drivers/staging/rt2860/common/rtmp_mcu.c +++ b/drivers/staging/rt2860/common/rtmp_mcu.c @@ -37,35 +37,38 @@ #include "../rt_config.h" -#if defined(RT2860) || defined(RT3090) -#include "firmware.h" -#include "../../rt3090/firmware.h" -#endif -#ifdef RT2870 -#include "../../rt3070/firmware.h" -#include "firmware_3070.h" -#endif - -#include <linux/bitrev.h> +#include <linux/crc-ccitt.h> +#include <linux/firmware.h> #ifdef RTMP_MAC_USB -/* */ -/* RT2870 Firmware Spec only used 1 oct for version expression */ -/* */ -#define FIRMWARE_MINOR_VERSION 7 -#endif /* RTMP_MAC_USB // */ -/* New 8k byte firmware size for RT3071/RT3072 */ -#define FIRMWAREIMAGE_MAX_LENGTH 0x2000 -#define FIRMWAREIMAGE_LENGTH (sizeof (FirmwareImage) / sizeof(u8)) -#define FIRMWARE_MAJOR_VERSION 0 +#define FIRMWAREIMAGE_LENGTH 0x1000 -#define FIRMWAREIMAGEV1_LENGTH 0x1000 -#define FIRMWAREIMAGEV2_LENGTH 0x1000 +#define FIRMWARE_2870_MIN_VERSION 12 +#define FIRMWARE_2870_FILENAME "rt2870.bin" +MODULE_FIRMWARE(FIRMWARE_2870_FILENAME); -#ifdef RTMP_MAC_PCI -#define FIRMWARE_MINOR_VERSION 2 -#endif /* RTMP_MAC_PCI // */ +#define FIRMWARE_3070_MIN_VERSION 17 +#define FIRMWARE_3070_FILENAME "rt3070.bin" +MODULE_FIRMWARE(FIRMWARE_3070_FILENAME); + +#define FIRMWARE_3071_MIN_VERSION 17 +#define FIRMWARE_3071_FILENAME "rt3071.bin" /* for RT3071/RT3072 */ +MODULE_FIRMWARE(FIRMWARE_3071_FILENAME); + +#else /* RTMP_MAC_PCI */ + +#define FIRMWAREIMAGE_LENGTH 0x2000 + +#define FIRMWARE_2860_MIN_VERSION 11 +#define FIRMWARE_2860_FILENAME "rt2860.bin" +MODULE_FIRMWARE(FIRMWARE_2860_FILENAME); + +#define FIRMWARE_3090_MIN_VERSION 19 +#define FIRMWARE_3090_FILENAME "rt3090.bin" /* for RT3090/RT3390 */ +MODULE_FIRMWARE(FIRMWARE_3090_FILENAME); + +#endif /* ======================================================================== @@ -90,6 +93,78 @@ int RtmpAsicEraseFirmware(struct rt_rtmp_adapter *pAd) return 0; } +static const struct firmware *rtmp_get_firmware(struct rt_rtmp_adapter *adapter) +{ + const char *name; + const struct firmware *fw = NULL; + u8 min_version; + struct device *dev; + int err; + + if (adapter->firmware) + return adapter->firmware; + +#ifdef RTMP_MAC_USB + if (IS_RT3071(adapter)) { + name = FIRMWARE_3071_FILENAME; + min_version = FIRMWARE_3071_MIN_VERSION; + } else if (IS_RT3070(adapter)) { + name = FIRMWARE_3070_FILENAME; + min_version = FIRMWARE_3070_MIN_VERSION; + } else { + name = FIRMWARE_2870_FILENAME; + min_version = FIRMWARE_2870_MIN_VERSION; + } + dev = &((struct os_cookie *)adapter->OS_Cookie)->pUsb_Dev->dev; +#else /* RTMP_MAC_PCI */ + if (IS_RT3090(adapter) || IS_RT3390(adapter)) { + name = FIRMWARE_3090_FILENAME; + min_version = FIRMWARE_3090_MIN_VERSION; + } else { + name = FIRMWARE_2860_FILENAME; + min_version = FIRMWARE_2860_MIN_VERSION; + } + dev = &((struct os_cookie *)adapter->OS_Cookie)->pci_dev->dev; +#endif + + err = request_firmware(&fw, name, dev); + if (err) { + dev_err(dev, "firmware file %s request failed (%d)\n", + name, err); + return NULL; + } + + if (fw->size < FIRMWAREIMAGE_LENGTH) { + dev_err(dev, "firmware file %s size is invalid\n", name); + goto invalid; + } + + /* is it new enough? */ + adapter->FirmwareVersion = fw->data[FIRMWAREIMAGE_LENGTH - 3]; + if (adapter->FirmwareVersion < min_version) { + dev_err(dev, + "firmware file %s is too old;" + " driver requires v%d or later\n", + name, min_version); + goto invalid; + } + + /* is the internal CRC correct? */ + if (crc_ccitt(0xffff, fw->data, FIRMWAREIMAGE_LENGTH - 2) != + (fw->data[FIRMWAREIMAGE_LENGTH - 2] | + (fw->data[FIRMWAREIMAGE_LENGTH - 1] << 8))) { + dev_err(dev, "firmware file %s failed internal CRC\n", name); + goto invalid; + } + + adapter->firmware = fw; + return fw; + +invalid: + release_firmware(fw); + return NULL; +} + /* ======================================================================== @@ -109,46 +184,16 @@ int RtmpAsicEraseFirmware(struct rt_rtmp_adapter *pAd) */ int RtmpAsicLoadFirmware(struct rt_rtmp_adapter *pAd) { - + const struct firmware *fw; int Status = NDIS_STATUS_SUCCESS; - u8 *pFirmwareImage = NULL; - unsigned long FileLength, Index; + unsigned long Index; u32 MacReg = 0; -#ifdef RTMP_MAC_USB - u32 Version = (pAd->MACVersion >> 16); -#endif - /* New 8k byte firmware size for RT3071/RT3072 */ - { -#ifdef RTMP_MAC_PCI - if (IS_RT3090(pAd) || IS_RT3390(pAd)) { - pFirmwareImage = FirmwareImage_3090; - FileLength = FIRMWAREIMAGE_MAX_LENGTH; - } else { - pFirmwareImage = FirmwareImage_2860; - FileLength = FIRMWAREIMAGE_MAX_LENGTH; - } -#endif /* RTMP_MAC_PCI // */ -#ifdef RTMP_MAC_USB - /* the firmware image consists of two parts */ - if ((Version != 0x2860) && (Version != 0x2872) && (Version != 0x3070)) { /* use the second part */ - /*printk("KH:Use New Version,part2\n"); */ - pFirmwareImage = - (u8 *)& - FirmwareImage_3070[FIRMWAREIMAGEV1_LENGTH]; - FileLength = FIRMWAREIMAGEV2_LENGTH; - } else { - /*printk("KH:Use New Version,part1\n"); */ - if (Version == 0x3070) - pFirmwareImage = FirmwareImage_3070; - else - pFirmwareImage = FirmwareImage_2870; - FileLength = FIRMWAREIMAGEV1_LENGTH; - } -#endif /* RTMP_MAC_USB // */ - } + fw = rtmp_get_firmware(pAd); + if (!fw) + return NDIS_STATUS_FAILURE; - RTMP_WRITE_FIRMWARE(pAd, pFirmwareImage, FileLength); + RTMP_WRITE_FIRMWARE(pAd, fw->data, FIRMWAREIMAGE_LENGTH); /* check if MCU is ready */ Index = 0; @@ -221,7 +266,7 @@ int RtmpAsicSendCommandToMcu(struct rt_rtmp_adapter *pAd, ("AsicSendCommanToMcu::Mail box is busy\n")); } while (i++ < 100); - if (i >= 100) { + if (i > 100) { DBGPRINT_ERR(("H2M_MAILBOX still hold by MCU. command fail\n")); return FALSE; } diff --git a/drivers/staging/rt2860/rt_linux.c b/drivers/staging/rt2860/rt_linux.c index 9357fb2..b5c78ae 100644 --- a/drivers/staging/rt2860/rt_linux.c +++ b/drivers/staging/rt2860/rt_linux.c @@ -25,6 +25,7 @@ ************************************************************************* */ +#include <linux/firmware.h> #include <linux/sched.h> #include "rt_config.h" @@ -260,6 +261,8 @@ void RTMPFreeAdapter(struct rt_rtmp_adapter *pAd) NdisFreeSpinLock(&pAd->irq_lock); + release_firmware(pAd->firmware); + vfree(pAd); /* pci_free_consistent(os_cookie->pci_dev,sizeof(struct rt_rtmp_adapter),pAd,os_cookie->pAd_pa); */ if (os_cookie) kfree(os_cookie); @@ -462,9 +465,9 @@ void *duplicate_pkt(struct rt_rtmp_adapter *pAd, if ((skb = __dev_alloc_skb(HdrLen + DataSize + 2, MEM_ALLOC_FLAG)) != NULL) { skb_reserve(skb, 2); - NdisMoveMemory(skb->tail, pHeader802_3, HdrLen); + NdisMoveMemory(skb_tail_pointer(skb), pHeader802_3, HdrLen); skb_put(skb, HdrLen); - NdisMoveMemory(skb->tail, pData, DataSize); + NdisMoveMemory(skb_tail_pointer(skb), pData, DataSize); skb_put(skb, DataSize); skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID); pPacket = OSPKT_TO_RTPKT(skb); @@ -515,7 +518,7 @@ void *ClonePacket(struct rt_rtmp_adapter *pAd, pClonedPkt->dev = pRxPkt->dev; pClonedPkt->data = pData; pClonedPkt->len = DataSize; - pClonedPkt->tail = pClonedPkt->data + pClonedPkt->len; + skb_set_tail_pointer(pClonedPkt, DataSize) ASSERT(DataSize < 1530); } return pClonedPkt; @@ -535,7 +538,7 @@ void update_os_packet_info(struct rt_rtmp_adapter *pAd, pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID); pOSPkt->data = pRxBlk->pData; pOSPkt->len = pRxBlk->DataSize; - pOSPkt->tail = pOSPkt->data + pOSPkt->len; + skb_set_tail_pointer(pOSPkt, pOSPkt->len); } void wlan_802_11_to_802_3_packet(struct rt_rtmp_adapter *pAd, @@ -553,7 +556,7 @@ void wlan_802_11_to_802_3_packet(struct rt_rtmp_adapter *pAd, pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID); pOSPkt->data = pRxBlk->pData; pOSPkt->len = pRxBlk->DataSize; - pOSPkt->tail = pOSPkt->data + pOSPkt->len; + skb_set_tail_pointer(pOSPkt, pOSPkt->len); /* */ /* copy 802.3 header */ diff --git a/drivers/staging/rt2860/rt_linux.h b/drivers/staging/rt2860/rt_linux.h index f85508d..a7c540f 100644 --- a/drivers/staging/rt2860/rt_linux.h +++ b/drivers/staging/rt2860/rt_linux.h @@ -658,9 +658,9 @@ void linux_pci_unmap_single(void *handle, dma_addr_t dma_addr, size_t size, (RTPKT_TO_OSPKT(_pkt)->len) = (_len) #define GET_OS_PKT_DATATAIL(_pkt) \ - (RTPKT_TO_OSPKT(_pkt)->tail) + (skb_tail_pointer(RTPKT_TO_OSPKT(_pkt)) #define SET_OS_PKT_DATATAIL(_pkt, _start, _len) \ - ((RTPKT_TO_OSPKT(_pkt))->tail) = (u8 *)((_start) + (_len)) + (skb_set_tail_pointer(RTPKT_TO_OSPKT(_pkt), _len)) #define GET_OS_PKT_HEAD(_pkt) \ (RTPKT_TO_OSPKT(_pkt)->head) diff --git a/drivers/staging/rt2860/rt_main_dev.c b/drivers/staging/rt2860/rt_main_dev.c index c3d9280..fbddb00 100644 --- a/drivers/staging/rt2860/rt_main_dev.c +++ b/drivers/staging/rt2860/rt_main_dev.c @@ -216,7 +216,7 @@ int rt28xx_close(struct net_device *dev) u32 i = 0; #ifdef RTMP_MAC_USB - DECLARE_WAIT_QUEUE_HEAD(unlink_wakeup); + DECLARE_WAIT_QUEUE_HEAD_ONSTACK(unlink_wakeup); DECLARE_WAITQUEUE(wait, current); #endif /* RTMP_MAC_USB // */ diff --git a/drivers/staging/rt2860/rtmp.h b/drivers/staging/rt2860/rtmp.h index c50abf4..4401a55 100644 --- a/drivers/staging/rt2860/rtmp.h +++ b/drivers/staging/rt2860/rtmp.h @@ -1719,6 +1719,7 @@ struct rt_rtmp_adapter { void *OS_Cookie; /* save specific structure relative to OS */ struct net_device *net_dev; unsigned long VirtualIfCnt; + const struct firmware *firmware; struct rt_rtmp_chip_op chipOps; u16 ThisTbttNumToNextWakeUp; @@ -4043,10 +4044,10 @@ int RTUSBMultiRead(struct rt_rtmp_adapter *pAd, u16 Offset, u8 *pData, u16 length); int RTUSBMultiWrite(struct rt_rtmp_adapter *pAd, - u16 Offset, u8 *pData, u16 length); + u16 Offset, const u8 *pData, u16 length); int RTUSBMultiWrite_OneByte(struct rt_rtmp_adapter *pAd, - u16 Offset, u8 *pData); + u16 Offset, const u8 *pData); int RTUSBReadBBPRegister(struct rt_rtmp_adapter *pAd, u8 Id, u8 *pValue); @@ -4112,7 +4113,7 @@ int RTUSBSingleWrite(struct rt_rtmp_adapter *pAd, u16 Offset, u16 Value); int RTUSBFirmwareWrite(struct rt_rtmp_adapter *pAd, - u8 *pFwImage, unsigned long FwLen); + const u8 *pFwImage, unsigned long FwLen); int RTUSBVenderReset(struct rt_rtmp_adapter *pAd); diff --git a/drivers/staging/rt2860/sta/connect.c b/drivers/staging/rt2860/sta/connect.c index 17e59ba..55732b1 100644 --- a/drivers/staging/rt2860/sta/connect.c +++ b/drivers/staging/rt2860/sta/connect.c @@ -62,8 +62,8 @@ u8 CipherSuiteWpaNoneAes[] = { u8 CipherSuiteWpaNoneAesLen = (sizeof(CipherSuiteWpaNoneAes) / sizeof(u8)); -/* The following MACRO is called after 1. starting an new IBSS, 2. succesfully JOIN an IBSS, */ -/* or 3. succesfully ASSOCIATE to a BSS, 4. successfully RE_ASSOCIATE to a BSS */ +/* The following MACRO is called after 1. starting an new IBSS, 2. successfully JOIN an IBSS, */ +/* or 3. successfully ASSOCIATE to a BSS, 4. successfully RE_ASSOCIATE to a BSS */ /* All settings successfuly negotiated furing MLME state machines become final settings */ /* and are copied to pAd->StaActive */ #define COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(_pAd) \ diff --git a/drivers/staging/rt2860/sta_ioctl.c b/drivers/staging/rt2860/sta_ioctl.c index d8fbe6c..de4b627 100644 --- a/drivers/staging/rt2860/sta_ioctl.c +++ b/drivers/staging/rt2860/sta_ioctl.c @@ -975,10 +975,7 @@ int rt_ioctl_giwscan(struct net_device *dev, /*================================ */ memset(&iwe, 0, sizeof(iwe)); iwe.cmd = SIOCGIWFREQ; - if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter)) - iwe.u.freq.m = pAdapter->ScanTab.BssEntry[i].Channel; - else - iwe.u.freq.m = pAdapter->ScanTab.BssEntry[i].Channel; + iwe.u.freq.m = pAdapter->ScanTab.BssEntry[i].Channel; iwe.u.freq.e = 0; iwe.u.freq.i = 0; diff --git a/drivers/staging/rt2860/usb_main_dev.c b/drivers/staging/rt2860/usb_main_dev.c index 925a236..1873a79 100644 --- a/drivers/staging/rt2860/usb_main_dev.c +++ b/drivers/staging/rt2860/usb_main_dev.c @@ -216,10 +216,6 @@ static int rt2870_suspend(struct usb_interface *intf, pm_message_t state); static int rt2870_resume(struct usb_interface *intf); #endif /* CONFIG_PM // */ -static int rtusb_probe(struct usb_interface *intf, - const struct usb_device_id *id); -static void rtusb_disconnect(struct usb_interface *intf); - static BOOLEAN USBDevConfigInit(IN struct usb_device *dev, IN struct usb_interface *intf, struct rt_rtmp_adapter *pAd) @@ -296,7 +292,7 @@ static BOOLEAN USBDevConfigInit(IN struct usb_device *dev, } -static int rtusb_probe(struct usb_interface *intf, +static int __devinit rtusb_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct rt_rtmp_adapter *pAd; diff --git a/drivers/staging/rt2870/Kconfig b/drivers/staging/rt2870/Kconfig index fd3ba3a..6ea172b 100644 --- a/drivers/staging/rt2870/Kconfig +++ b/drivers/staging/rt2870/Kconfig @@ -3,5 +3,7 @@ config RT2870 depends on USB && X86 && WLAN select WIRELESS_EXT select WEXT_PRIV + select CRC_CCITT + select FW_LOADER ---help--- This is an experimental driver for the Ralink xx70 wireless chips. diff --git a/drivers/staging/rt2870/common/rtusb_io.c b/drivers/staging/rt2870/common/rtusb_io.c index 34443f2..cf0d2f5 100644 --- a/drivers/staging/rt2870/common/rtusb_io.c +++ b/drivers/staging/rt2870/common/rtusb_io.c @@ -84,7 +84,7 @@ static int RTUSBFirmwareRun(struct rt_rtmp_adapter *pAd) ======================================================================== */ int RTUSBFirmwareWrite(struct rt_rtmp_adapter *pAd, - u8 *pFwImage, unsigned long FwLen) + const u8 *pFwImage, unsigned long FwLen) { u32 MacReg; int Status; @@ -167,7 +167,7 @@ int RTUSBMultiRead(struct rt_rtmp_adapter *pAd, ======================================================================== */ int RTUSBMultiWrite_OneByte(struct rt_rtmp_adapter *pAd, - u16 Offset, u8 *pData) + u16 Offset, const u8 *pData) { int Status; @@ -175,18 +175,18 @@ int RTUSBMultiWrite_OneByte(struct rt_rtmp_adapter *pAd, Status = RTUSB_VendorRequest(pAd, USBD_TRANSFER_DIRECTION_OUT, DEVICE_VENDOR_REQUEST_OUT, - 0x6, 0, Offset, pData, 1); + 0x6, 0, Offset, (u8 *)pData, 1); return Status; } int RTUSBMultiWrite(struct rt_rtmp_adapter *pAd, - u16 Offset, u8 *pData, u16 length) + u16 Offset, const u8 *pData, u16 length) { int Status; u16 index = 0, Value; - u8 *pSrc = pData; + const u8 *pSrc = pData; u16 resude = 0; resude = length % 2; diff --git a/drivers/staging/rt3070/firmware.h b/drivers/staging/rt3070/firmware.h deleted file mode 100644 index 5cf9cbc..0000000 --- a/drivers/staging/rt3070/firmware.h +++ /dev/null @@ -1,558 +0,0 @@ -/* - Copyright (c) 2007, Ralink Technology Corporation - All rights reserved. - - Redistribution. Redistribution and use in binary form, without - modification, are permitted provided that the following conditions are - met: - - * Redistributions must reproduce the above copyright notice and the - following disclaimer in the documentation and/or other materials - provided with the distribution. - * Neither the name of Ralink Technology Corporation nor the names of its - suppliers may be used to endorse or promote products derived from this - software without specific prior written permission. - * No reverse engineering, decompilation, or disassembly of this software - is permitted. - - Limited patent license. Ralink Technology Corporation grants a world-wide, - royalty-free, non-exclusive license under patents it now or hereafter - owns or controls to make, have made, use, import, offer to sell and - sell ("Utilize") this software, but solely to the extent that any - such patent is necessary to Utilize the software alone, or in - combination with an operating system licensed under an approved Open - Source license as listed by the Open Source Initiative at - http://opensource.org/licenses. The patent license shall not apply to - any other combinations which include this software. No hardware per - se is licensed hereunder. - - DISCLAIMER. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. -*/ -/* AUTO GEN PLEASE DO NOT MODIFY IT */ -/* AUTO GEN PLEASE DO NOT MODIFY IT */ - - -u8 FirmwareImage_2870 [] = { -0xff, 0xff, 0xff, 0x02, 0x10, 0x28, 0x02, 0x10, 0x32, 0x02, 0x10, 0x78, 0x02, 0x12, 0x67, 0x02, -0x12, 0x68, 0x02, 0x12, 0x87, 0x02, 0x12, 0x8c, 0x12, 0x12, 0x88, 0x22, 0x02, 0x16, 0x49, 0x02, -0x17, 0x1f, 0x02, 0x13, 0x77, 0x02, 0x12, 0x8d, 0x30, 0x05, 0x06, 0x20, 0x0d, 0x03, 0x12, 0x17, -0xc1, 0x22, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe3, 0x1b, 0xe5, 0x4c, 0x30, 0xe0, 0x04, 0x7f, 0x40, -0x80, 0x02, 0x7f, 0x00, 0x90, 0x10, 0x2f, 0xef, 0xf0, 0x90, 0x01, 0x8c, 0x74, 0x08, 0xf0, 0xe4, -0x90, 0x01, 0xa7, 0xf0, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe0, 0x1c, 0x90, 0x01, 0x80, 0xe0, 0xb4, -0x02, 0x15, 0xa3, 0xe0, 0xb4, 0x01, 0x10, 0x90, 0x01, 0x84, 0xe0, 0xb4, 0x81, 0x09, 0x90, 0x01, -0x8c, 0x74, 0x01, 0xf0, 0x12, 0x0d, 0xc8, 0x22, 0x90, 0x04, 0x14, 0xe0, 0x20, 0xe7, 0x03, 0x02, -0x12, 0x66, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x56, 0x90, 0x04, 0x04, 0xe0, 0x12, 0x0a, 0x9d, 0x10, -0xb7, 0x31, 0x10, 0xe0, 0x50, 0x11, 0x04, 0x51, 0x11, 0x0d, 0x52, 0x11, 0x0d, 0x53, 0x11, 0x0d, -0x54, 0x11, 0x4e, 0x55, 0x11, 0x7e, 0x70, 0x11, 0xa9, 0x71, 0x11, 0xd7, 0x72, 0x12, 0x1d, 0x73, -0x12, 0x3e, 0x80, 0x00, 0x00, 0x12, 0x66, 0x20, 0x02, 0x03, 0x30, 0x03, 0x1d, 0x7d, 0x02, 0xaf, -0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, -0x56, 0xf4, 0x70, 0x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0x85, 0x56, 0x41, 0xd2, 0x02, 0x22, -0x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, 0x64, 0x02, 0x60, 0x03, 0x02, 0x12, 0x66, 0x90, 0x70, 0x11, -0xe0, 0x64, 0x08, 0x60, 0x08, 0xe0, 0x64, 0x20, 0x60, 0x03, 0x02, 0x12, 0x66, 0x75, 0x4e, 0x03, -0x75, 0x4f, 0x20, 0x22, 0x90, 0x70, 0x11, 0xe0, 0x24, 0xff, 0x92, 0x47, 0x22, 0x90, 0x04, 0x04, -0xe0, 0x25, 0xe0, 0x24, 0x5d, 0xf5, 0x57, 0x90, 0x70, 0x10, 0xe0, 0xff, 0x74, 0x47, 0x25, 0x57, -0xf8, 0xc6, 0xef, 0xc6, 0x90, 0x70, 0x11, 0xe0, 0xff, 0x74, 0x48, 0x25, 0x57, 0xf8, 0xc6, 0xef, -0xc6, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, -0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0xe5, 0x47, -0x64, 0x07, 0x60, 0x0b, 0xe5, 0x47, 0x64, 0x08, 0x60, 0x05, 0xe5, 0x47, 0xb4, 0x09, 0x08, 0x90, -0x70, 0x11, 0xe0, 0x54, 0x0f, 0xf5, 0x3a, 0xe5, 0x47, 0xb4, 0x09, 0x08, 0xe5, 0x3a, 0xb4, 0x03, -0x03, 0xe4, 0xf5, 0x46, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0xd2, 0x04, 0x22, 0x90, 0x70, -0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed, 0xf8, 0xe6, 0xf5, 0x57, 0xfd, 0xaf, 0x56, -0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, -0xf4, 0x70, 0x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70, -0x11, 0xe0, 0xfd, 0xed, 0xf5, 0x82, 0x8e, 0x83, 0xe0, 0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x0b, -0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, -0x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0x90, 0x10, 0x02, 0xe0, 0xb4, 0x70, 0x1e, 0xa3, 0xe0, -0xb4, 0x30, 0x19, 0x90, 0x05, 0x08, 0xe0, 0x44, 0x01, 0xf0, 0xfd, 0x90, 0x05, 0x05, 0xe0, 0x54, -0xfb, 0xf0, 0x44, 0x04, 0xf0, 0xed, 0x54, 0xfe, 0x90, 0x05, 0x08, 0xf0, 0xe4, 0xf5, 0x4e, 0xf5, -0x4f, 0x75, 0x3a, 0xff, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, -0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x4b, 0x80, 0x42, 0x90, 0x70, 0x10, -0xe0, 0x24, 0xff, 0x92, 0x93, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, -0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x2a, 0x80, 0x21, 0x90, 0x70, -0x10, 0xe0, 0x24, 0xff, 0x92, 0x4a, 0xd2, 0x05, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, -0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x07, 0x90, -0x70, 0x25, 0xe0, 0x44, 0x01, 0xf0, 0x22, 0x22, 0xe5, 0x53, 0x70, 0x1a, 0x30, 0x60, 0x09, 0xb2, -0x4d, 0x30, 0x4d, 0x04, 0x05, 0x46, 0xc2, 0x04, 0xe5, 0x4f, 0x45, 0x4e, 0x60, 0x08, 0xe5, 0x4f, -0x15, 0x4f, 0x70, 0x02, 0x15, 0x4e, 0x22, 0x22, 0xc2, 0x42, 0xd3, 0x22, 0x22, 0xc2, 0x4b, 0xc2, -0x4c, 0xe5, 0x44, 0x12, 0x0a, 0x9d, 0x12, 0xaf, 0x00, 0x13, 0x42, 0x04, 0x13, 0x3e, 0x08, 0x13, -0x19, 0x10, 0x12, 0xc3, 0x20, 0x12, 0xe3, 0x60, 0x12, 0xf4, 0xa0, 0x00, 0x00, 0x13, 0x44, 0x85, -0x48, 0x43, 0x85, 0x4a, 0x42, 0x85, 0x4c, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x60, 0x03, 0x02, 0x13, -0x44, 0x80, 0x1b, 0xe5, 0x48, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4a, 0xc4, 0x54, 0x0f, 0xf5, -0x42, 0xe5, 0x4c, 0xc4, 0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x66, 0x53, 0x43, -0x0f, 0x80, 0x61, 0x85, 0x49, 0x43, 0x85, 0x4b, 0x42, 0x85, 0x4d, 0x5e, 0xe5, 0x47, 0x64, 0x06, -0x70, 0x52, 0x80, 0x1b, 0xe5, 0x49, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4b, 0xc4, 0x54, 0x0f, -0xf5, 0x42, 0xe5, 0x4d, 0xc4, 0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x35, 0xe5, -0x43, 0x54, 0x0f, 0x44, 0x10, 0xf5, 0x43, 0x80, 0x2b, 0xe5, 0x47, 0xb4, 0x04, 0x06, 0x53, 0x5e, -0xfb, 0x75, 0x42, 0x09, 0xe5, 0x47, 0xb4, 0x05, 0x06, 0x43, 0x5e, 0x04, 0x75, 0x42, 0x09, 0xe5, -0x47, 0xb4, 0x06, 0x10, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x30, 0xf5, 0x43, 0x80, 0x06, 0xd2, 0x4b, -0x80, 0x02, 0xd2, 0x4c, 0xe4, 0xf5, 0x25, 0xe5, 0x42, 0xc4, 0x54, 0xf0, 0xff, 0xe5, 0x43, 0x54, -0x0f, 0x4f, 0xf5, 0x5f, 0x90, 0x70, 0x44, 0xf0, 0xa3, 0xe5, 0x5e, 0xf0, 0xa3, 0xe5, 0x4a, 0xf0, -0xa3, 0xe5, 0x48, 0xf0, 0xa3, 0xe5, 0x4c, 0xf0, 0xa3, 0xe5, 0x44, 0xf0, 0xa3, 0xe5, 0x42, 0xf0, -0xa3, 0xe5, 0x43, 0xf0, 0xd2, 0x60, 0x22, 0xe5, 0x47, 0x60, 0x10, 0x24, 0xc0, 0x70, 0x03, 0x12, -0x16, 0x29, 0x12, 0x13, 0x8c, 0xc2, 0xaf, 0xc2, 0x04, 0xd2, 0xaf, 0x22, 0xc2, 0xaf, 0x90, 0x04, -0x14, 0xe0, 0x54, 0x0e, 0x60, 0x04, 0xd2, 0x18, 0x80, 0x08, 0xe5, 0x4e, 0x45, 0x4f, 0x24, 0xff, -0x92, 0x18, 0xd2, 0xaf, 0x90, 0x04, 0x14, 0xe0, 0xa2, 0xe4, 0x92, 0x19, 0x74, 0x1e, 0xf0, 0xe5, -0x5f, 0x54, 0x0f, 0xf5, 0x2d, 0xe5, 0x25, 0x70, 0x13, 0x30, 0x18, 0x05, 0xe5, 0x5f, 0x20, 0xe5, -0x0b, 0x30, 0x19, 0x19, 0xe5, 0x5f, 0x54, 0x30, 0xff, 0xbf, 0x30, 0x11, 0xe5, 0x25, 0x70, 0x05, -0x75, 0x25, 0x0c, 0x80, 0x02, 0x15, 0x25, 0xd2, 0x6c, 0xd2, 0x6d, 0x80, 0x0f, 0xe5, 0x5f, 0x30, -0xe6, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0xe5, 0x47, 0x64, 0x03, -0x70, 0x21, 0x30, 0x4b, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x18, 0xe5, 0x25, 0x70, 0x03, 0x30, -0x4c, 0x11, 0xc2, 0x4c, 0xe5, 0x25, 0x70, 0x05, 0x75, 0x25, 0x07, 0x80, 0x02, 0x15, 0x25, 0xd2, -0x6c, 0xd2, 0x6d, 0xe5, 0x47, 0xb4, 0x09, 0x14, 0xe5, 0x44, 0x20, 0xe3, 0x0b, 0xe5, 0x3a, 0x64, -0x02, 0x60, 0x05, 0xe5, 0x3a, 0xb4, 0x03, 0x04, 0xc2, 0x6c, 0xd2, 0x6d, 0x90, 0x70, 0x46, 0xe5, -0x2d, 0xf0, 0x20, 0x69, 0x07, 0xe5, 0x5e, 0x20, 0xe0, 0x02, 0xb2, 0x68, 0x20, 0x6b, 0x07, 0xe5, -0x5e, 0x20, 0xe1, 0x02, 0xb2, 0x6a, 0x20, 0x6d, 0x07, 0xe5, 0x5e, 0x20, 0xe2, 0x02, 0xb2, 0x6c, -0x90, 0x70, 0x47, 0xe5, 0x2d, 0xf0, 0x75, 0x2e, 0x40, 0x20, 0x69, 0x04, 0xa2, 0x68, 0x80, 0x26, -0x30, 0x68, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe2, 0x04, 0x7f, 0x01, -0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02, -0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x73, 0x92, 0x72, 0x20, 0x6b, 0x04, 0xa2, 0x6a, 0x80, -0x26, 0x30, 0x6a, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe0, 0x04, 0x7f, -0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, -0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x75, 0x92, 0x74, 0x20, 0x6d, 0x04, 0xa2, 0x6c, -0x80, 0x26, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe1, 0x04, -0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, -0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x71, 0x92, 0x70, 0x90, 0x10, 0x00, 0xe0, -0x90, 0x10, 0x2f, 0xf0, 0x90, 0x10, 0x03, 0xe0, 0xc3, 0x94, 0x30, 0x40, 0x14, 0xa2, 0x71, 0x92, -0x77, 0xa2, 0x70, 0x92, 0x76, 0xe5, 0x2e, 0x13, 0x13, 0x54, 0x3f, 0xf5, 0x2e, 0xc2, 0x77, 0xd2, -0x76, 0x90, 0x10, 0x2f, 0xe5, 0x2e, 0xf0, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x4c, 0x90, 0x02, 0x29, -0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x43, 0xc4, 0x54, 0x0f, 0x14, 0x60, 0x14, 0x24, 0xfe, 0x60, 0x23, -0x24, 0x03, 0x60, 0x03, 0x02, 0x16, 0x18, 0x90, 0x02, 0x28, 0xe0, 0x30, 0x47, 0x0f, 0x80, 0x07, -0x90, 0x02, 0x28, 0xe0, 0x20, 0x47, 0x06, 0x54, 0xfe, 0xf0, 0x02, 0x16, 0x18, 0x44, 0x01, 0xf0, -0x02, 0x16, 0x18, 0xe5, 0x46, 0x30, 0xe2, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0x90, 0x02, -0x28, 0xe0, 0x54, 0xfe, 0x4f, 0xf0, 0x02, 0x16, 0x18, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x0f, 0xe5, -0x47, 0x64, 0x08, 0x60, 0x09, 0xe5, 0x47, 0x64, 0x09, 0x60, 0x03, 0x02, 0x16, 0x18, 0xe4, 0xf5, -0x27, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfc, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x2d, 0x14, 0x60, 0x2e, -0x14, 0x60, 0x36, 0x24, 0xfc, 0x60, 0x5f, 0x24, 0xf9, 0x60, 0x1f, 0x24, 0x0e, 0x70, 0x69, 0xe5, -0x46, 0x13, 0x13, 0x54, 0x3f, 0x75, 0xf0, 0x03, 0x84, 0xaf, 0xf0, 0x20, 0x47, 0x04, 0x7e, 0x01, -0x80, 0x02, 0x7e, 0x00, 0xef, 0x6e, 0x24, 0xff, 0x80, 0x45, 0xa2, 0x47, 0x80, 0x41, 0xe5, 0x46, -0x30, 0xe2, 0x03, 0xd3, 0x80, 0x27, 0xc3, 0x80, 0x24, 0xe5, 0x46, 0x30, 0xe2, 0x0d, 0x54, 0x38, -0xc3, 0x94, 0x30, 0x50, 0x06, 0x7e, 0x00, 0x7f, 0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0x20, -0x47, 0x04, 0x7d, 0x01, 0x80, 0x02, 0x7d, 0x00, 0xef, 0x6d, 0x4e, 0x24, 0xff, 0x92, 0x38, 0xa2, -0x47, 0xb3, 0x92, 0x39, 0x80, 0x19, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, -0x39, 0xa2, 0x47, 0xb3, 0x92, 0x38, 0x80, 0x07, 0xa2, 0x47, 0xb3, 0x92, 0x38, 0x92, 0x39, 0x90, -0x02, 0x28, 0xe0, 0x54, 0xfc, 0x45, 0x27, 0xf0, 0x90, 0x70, 0x9c, 0xe5, 0x3a, 0xf0, 0xa3, 0xe5, -0x47, 0xf0, 0x90, 0x70, 0x41, 0xe5, 0x3a, 0xf0, 0x22, 0xe4, 0x90, 0x02, 0x29, 0xf0, 0x30, 0x47, -0x04, 0xaf, 0x45, 0x80, 0x04, 0xe5, 0x45, 0xf4, 0xff, 0x90, 0x02, 0x28, 0xef, 0xf0, 0x22, 0x8f, -0x50, 0xd2, 0x59, 0x22, 0x8f, 0x54, 0xd2, 0x58, 0x22, 0xe4, 0xf5, 0x62, 0xc2, 0xaf, 0xe5, 0x51, -0x14, 0x60, 0x46, 0x14, 0x60, 0x62, 0x24, 0x02, 0x60, 0x03, 0x02, 0x17, 0x03, 0xd2, 0x59, 0x75, -0x55, 0x01, 0x90, 0x02, 0xa2, 0xe0, 0x54, 0x7f, 0xf0, 0xa3, 0xe0, 0x20, 0xe7, 0x22, 0x90, 0x04, -0x34, 0xe0, 0xb4, 0x02, 0x1b, 0xa3, 0xe0, 0xb4, 0x02, 0x16, 0xa3, 0xe0, 0xb4, 0x02, 0x11, 0x7f, -0x20, 0x12, 0x16, 0x3f, 0x90, 0x10, 0x04, 0xe0, 0x54, 0xf3, 0xf0, 0x75, 0x51, 0x01, 0x80, 0x73, -0xe5, 0x50, 0x70, 0x05, 0x75, 0x62, 0x03, 0x80, 0x6a, 0x90, 0x12, 0x00, 0xe0, 0x54, 0x03, 0x70, -0x11, 0x7f, 0x20, 0x12, 0x16, 0x3f, 0x90, 0x02, 0xa2, 0xe0, 0x54, 0xbf, 0xf0, 0x75, 0x51, 0x02, -0x80, 0x51, 0xe5, 0x50, 0x70, 0x02, 0x80, 0x46, 0x90, 0x02, 0xa3, 0xe0, 0x20, 0xe6, 0x3b, 0x90, -0x04, 0x37, 0xe0, 0x64, 0x22, 0x70, 0x33, 0x90, 0x01, 0x8a, 0x74, 0x7e, 0xf0, 0x90, 0x01, 0x96, -0xf0, 0x90, 0x12, 0x04, 0x74, 0x0a, 0xf0, 0x90, 0x13, 0x28, 0xe0, 0x54, 0xf0, 0xf0, 0xa3, 0xe0, -0x54, 0xf0, 0xf0, 0xa3, 0xe0, 0x54, 0xfa, 0xf0, 0x90, 0x04, 0x01, 0xe0, 0x54, 0xf9, 0xf0, 0x75, -0x62, 0x01, 0x75, 0x55, 0x02, 0xe4, 0xf5, 0x51, 0x80, 0x09, 0xe5, 0x50, 0x70, 0x05, 0x75, 0x62, -0x03, 0xf5, 0x51, 0xe5, 0x62, 0x60, 0x15, 0xc2, 0x01, 0xe4, 0xf5, 0x51, 0xc2, 0x59, 0xad, 0x62, -0xaf, 0x40, 0x12, 0x17, 0x8d, 0xe5, 0x62, 0xb4, 0x03, 0x02, 0xd2, 0x03, 0xd2, 0xaf, 0x22, 0xc2, -0xaf, 0x30, 0x01, 0x12, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xf5, 0x51, 0xc2, 0x59, 0xc2, 0x01, 0x7d, -0x02, 0xaf, 0x40, 0x12, 0x17, 0x8d, 0xe5, 0x52, 0x14, 0x60, 0x09, 0x04, 0x70, 0x4c, 0x75, 0x52, -0x01, 0x75, 0x55, 0x03, 0x90, 0x04, 0x01, 0xe0, 0x44, 0x0e, 0xf0, 0x90, 0x13, 0x28, 0xe0, 0x44, -0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x05, 0xf0, 0x90, 0x12, 0x04, 0x74, -0x03, 0xf0, 0x90, 0x02, 0xa2, 0xe0, 0x44, 0xc0, 0xf0, 0x90, 0x10, 0x04, 0xe0, 0x44, 0x0c, 0xf0, -0xe4, 0xf5, 0x52, 0xf5, 0x55, 0x30, 0x02, 0x0b, 0xc2, 0x02, 0x7d, 0x01, 0xaf, 0x41, 0x12, 0x17, -0x8d, 0x80, 0x02, 0xc2, 0x03, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xd2, 0xaf, 0x22, 0xef, 0xf4, 0x60, -0x2d, 0xe4, 0xfe, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xe0, 0xb4, 0xff, -0x19, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xef, 0xf0, 0x74, 0x1c, 0x2e, -0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xed, 0xf0, 0x22, 0x0e, 0xbe, 0x04, 0xd5, 0x22, 0x22, -0x22, 0x90, 0x70, 0x2a, 0xe0, 0x30, 0xe1, 0x4d, 0xc2, 0xaf, 0x90, 0x70, 0x28, 0xe0, 0x90, 0x10, -0x1c, 0xf0, 0x90, 0x70, 0x29, 0xe0, 0x90, 0x10, 0x1d, 0xf0, 0x90, 0x70, 0x2a, 0xe0, 0x90, 0x10, -0x1e, 0xf0, 0x90, 0x10, 0x1c, 0xe0, 0xf5, 0x62, 0x90, 0x10, 0x1e, 0xe0, 0x20, 0xe1, 0xf3, 0x90, -0x10, 0x1c, 0xe0, 0x90, 0x70, 0x28, 0xf0, 0x90, 0x10, 0x1d, 0xe0, 0x90, 0x70, 0x29, 0xf0, 0x90, -0x10, 0x1e, 0xe0, 0x90, 0x70, 0x2a, 0xf0, 0x30, 0x4a, 0x07, 0x90, 0x70, 0x24, 0xe0, 0x44, 0x01, -0xf0, 0xc2, 0x05, 0xd2, 0xaf, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x94, 0x3f, -0xff, 0xff, 0xff, 0x02, 0x10, 0x28, 0x02, 0x10, 0x32, 0x02, 0x10, 0x78, 0x02, 0x12, 0x67, 0x02, -0x12, 0x68, 0x02, 0x12, 0x87, 0x02, 0x12, 0x8c, 0x12, 0x12, 0x88, 0x22, 0x02, 0x16, 0x49, 0x02, -0x17, 0x1f, 0x02, 0x13, 0x77, 0x02, 0x12, 0x8d, 0x30, 0x05, 0x06, 0x20, 0x0d, 0x03, 0x12, 0x17, -0xc1, 0x22, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe3, 0x1b, 0xe5, 0x4c, 0x30, 0xe0, 0x04, 0x7f, 0x40, -0x80, 0x02, 0x7f, 0x00, 0x90, 0x10, 0x2f, 0xef, 0xf0, 0x90, 0x01, 0x8c, 0x74, 0x08, 0xf0, 0xe4, -0x90, 0x01, 0xa7, 0xf0, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe0, 0x1c, 0x90, 0x01, 0x80, 0xe0, 0xb4, -0x02, 0x15, 0xa3, 0xe0, 0xb4, 0x01, 0x10, 0x90, 0x01, 0x84, 0xe0, 0xb4, 0x81, 0x09, 0x90, 0x01, -0x8c, 0x74, 0x01, 0xf0, 0x12, 0x0d, 0xdd, 0x22, 0x90, 0x04, 0x14, 0xe0, 0x20, 0xe7, 0x03, 0x02, -0x12, 0x66, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x56, 0x90, 0x04, 0x04, 0xe0, 0x12, 0x0a, 0xb6, 0x10, -0xb7, 0x31, 0x10, 0xe0, 0x50, 0x11, 0x04, 0x51, 0x11, 0x0d, 0x52, 0x11, 0x0d, 0x53, 0x11, 0x0d, -0x54, 0x11, 0x4e, 0x55, 0x11, 0x7e, 0x70, 0x11, 0xa9, 0x71, 0x11, 0xd7, 0x72, 0x12, 0x1d, 0x73, -0x12, 0x3e, 0x80, 0x00, 0x00, 0x12, 0x66, 0x20, 0x02, 0x03, 0x30, 0x03, 0x1d, 0x7d, 0x02, 0xaf, -0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, -0x56, 0xf4, 0x70, 0x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0x85, 0x56, 0x41, 0xd2, 0x02, 0x22, -0x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, 0x64, 0x02, 0x60, 0x03, 0x02, 0x12, 0x66, 0x90, 0x70, 0x11, -0xe0, 0x64, 0x08, 0x60, 0x08, 0xe0, 0x64, 0x20, 0x60, 0x03, 0x02, 0x12, 0x66, 0x75, 0x4e, 0x03, -0x75, 0x4f, 0x20, 0x22, 0x90, 0x70, 0x11, 0xe0, 0x24, 0xff, 0x92, 0x47, 0x22, 0x90, 0x04, 0x04, -0xe0, 0x25, 0xe0, 0x24, 0x5d, 0xf5, 0x57, 0x90, 0x70, 0x10, 0xe0, 0xff, 0x74, 0x47, 0x25, 0x57, -0xf8, 0xc6, 0xef, 0xc6, 0x90, 0x70, 0x11, 0xe0, 0xff, 0x74, 0x48, 0x25, 0x57, 0xf8, 0xc6, 0xef, -0xc6, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, -0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0xe5, 0x47, -0x64, 0x07, 0x60, 0x0b, 0xe5, 0x47, 0x64, 0x08, 0x60, 0x05, 0xe5, 0x47, 0xb4, 0x09, 0x08, 0x90, -0x70, 0x11, 0xe0, 0x54, 0x0f, 0xf5, 0x3a, 0xe5, 0x47, 0xb4, 0x09, 0x08, 0xe5, 0x3a, 0xb4, 0x03, -0x03, 0xe4, 0xf5, 0x46, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0xd2, 0x04, 0x22, 0x90, 0x70, -0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed, 0xf8, 0xe6, 0xf5, 0x57, 0xfd, 0xaf, 0x56, -0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, -0xf4, 0x70, 0x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70, -0x11, 0xe0, 0xfd, 0xed, 0xf5, 0x82, 0x8e, 0x83, 0xe0, 0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x0b, -0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, -0x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0x90, 0x10, 0x02, 0xe0, 0xb4, 0x70, 0x1e, 0xa3, 0xe0, -0xb4, 0x30, 0x19, 0x90, 0x05, 0x08, 0xe0, 0x44, 0x01, 0xf0, 0xfd, 0x90, 0x05, 0x05, 0xe0, 0x54, -0xfb, 0xf0, 0x44, 0x04, 0xf0, 0xed, 0x54, 0xfe, 0x90, 0x05, 0x08, 0xf0, 0xe4, 0xf5, 0x4e, 0xf5, -0x4f, 0x75, 0x3a, 0xff, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, -0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x4b, 0x80, 0x42, 0x90, 0x70, 0x10, -0xe0, 0x24, 0xff, 0x92, 0x93, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, -0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x2a, 0x80, 0x21, 0x90, 0x70, -0x10, 0xe0, 0x24, 0xff, 0x92, 0x4a, 0xd2, 0x05, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, -0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x07, 0x90, -0x70, 0x25, 0xe0, 0x44, 0x01, 0xf0, 0x22, 0x22, 0xe5, 0x53, 0x70, 0x1a, 0x30, 0x60, 0x09, 0xb2, -0x4d, 0x30, 0x4d, 0x04, 0x05, 0x46, 0xc2, 0x04, 0xe5, 0x4f, 0x45, 0x4e, 0x60, 0x08, 0xe5, 0x4f, -0x15, 0x4f, 0x70, 0x02, 0x15, 0x4e, 0x22, 0x22, 0xc2, 0x42, 0xd3, 0x22, 0x22, 0xc2, 0x4b, 0xc2, -0x4c, 0xe5, 0x44, 0x12, 0x0a, 0xb6, 0x12, 0xaf, 0x00, 0x13, 0x42, 0x04, 0x13, 0x3e, 0x08, 0x13, -0x19, 0x10, 0x12, 0xc3, 0x20, 0x12, 0xe3, 0x60, 0x12, 0xf4, 0xa0, 0x00, 0x00, 0x13, 0x44, 0x85, -0x48, 0x43, 0x85, 0x4a, 0x42, 0x85, 0x4c, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x60, 0x03, 0x02, 0x13, -0x44, 0x80, 0x1b, 0xe5, 0x48, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4a, 0xc4, 0x54, 0x0f, 0xf5, -0x42, 0xe5, 0x4c, 0xc4, 0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x66, 0x53, 0x43, -0x0f, 0x80, 0x61, 0x85, 0x49, 0x43, 0x85, 0x4b, 0x42, 0x85, 0x4d, 0x5e, 0xe5, 0x47, 0x64, 0x06, -0x70, 0x52, 0x80, 0x1b, 0xe5, 0x49, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4b, 0xc4, 0x54, 0x0f, -0xf5, 0x42, 0xe5, 0x4d, 0xc4, 0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x35, 0xe5, -0x43, 0x54, 0x0f, 0x44, 0x10, 0xf5, 0x43, 0x80, 0x2b, 0xe5, 0x47, 0xb4, 0x04, 0x06, 0x53, 0x5e, -0xfb, 0x75, 0x42, 0x09, 0xe5, 0x47, 0xb4, 0x05, 0x06, 0x43, 0x5e, 0x04, 0x75, 0x42, 0x09, 0xe5, -0x47, 0xb4, 0x06, 0x10, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x30, 0xf5, 0x43, 0x80, 0x06, 0xd2, 0x4b, -0x80, 0x02, 0xd2, 0x4c, 0xe4, 0xf5, 0x25, 0xe5, 0x42, 0xc4, 0x54, 0xf0, 0xff, 0xe5, 0x43, 0x54, -0x0f, 0x4f, 0xf5, 0x5f, 0x90, 0x70, 0x44, 0xf0, 0xa3, 0xe5, 0x5e, 0xf0, 0xa3, 0xe5, 0x4a, 0xf0, -0xa3, 0xe5, 0x48, 0xf0, 0xa3, 0xe5, 0x4c, 0xf0, 0xa3, 0xe5, 0x44, 0xf0, 0xa3, 0xe5, 0x42, 0xf0, -0xa3, 0xe5, 0x43, 0xf0, 0xd2, 0x60, 0x22, 0xe5, 0x47, 0x60, 0x10, 0x24, 0xc0, 0x70, 0x03, 0x12, -0x16, 0x29, 0x12, 0x13, 0x8c, 0xc2, 0xaf, 0xc2, 0x04, 0xd2, 0xaf, 0x22, 0xc2, 0xaf, 0x90, 0x04, -0x14, 0xe0, 0x54, 0x0e, 0x60, 0x04, 0xd2, 0x18, 0x80, 0x08, 0xe5, 0x4e, 0x45, 0x4f, 0x24, 0xff, -0x92, 0x18, 0xd2, 0xaf, 0x90, 0x04, 0x14, 0xe0, 0xa2, 0xe4, 0x92, 0x19, 0x74, 0x1e, 0xf0, 0xe5, -0x5f, 0x54, 0x0f, 0xf5, 0x2d, 0xe5, 0x25, 0x70, 0x13, 0x30, 0x18, 0x05, 0xe5, 0x5f, 0x20, 0xe5, -0x0b, 0x30, 0x19, 0x19, 0xe5, 0x5f, 0x54, 0x30, 0xff, 0xbf, 0x30, 0x11, 0xe5, 0x25, 0x70, 0x05, -0x75, 0x25, 0x0c, 0x80, 0x02, 0x15, 0x25, 0xd2, 0x6c, 0xd2, 0x6d, 0x80, 0x0f, 0xe5, 0x5f, 0x30, -0xe6, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0xe5, 0x47, 0x64, 0x03, -0x70, 0x21, 0x30, 0x4b, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x18, 0xe5, 0x25, 0x70, 0x03, 0x30, -0x4c, 0x11, 0xc2, 0x4c, 0xe5, 0x25, 0x70, 0x05, 0x75, 0x25, 0x07, 0x80, 0x02, 0x15, 0x25, 0xd2, -0x6c, 0xd2, 0x6d, 0xe5, 0x47, 0xb4, 0x09, 0x14, 0xe5, 0x44, 0x20, 0xe3, 0x0b, 0xe5, 0x3a, 0x64, -0x02, 0x60, 0x05, 0xe5, 0x3a, 0xb4, 0x03, 0x04, 0xc2, 0x6c, 0xd2, 0x6d, 0x90, 0x70, 0x46, 0xe5, -0x2d, 0xf0, 0x20, 0x69, 0x07, 0xe5, 0x5e, 0x20, 0xe0, 0x02, 0xb2, 0x68, 0x20, 0x6b, 0x07, 0xe5, -0x5e, 0x20, 0xe1, 0x02, 0xb2, 0x6a, 0x20, 0x6d, 0x07, 0xe5, 0x5e, 0x20, 0xe2, 0x02, 0xb2, 0x6c, -0x90, 0x70, 0x47, 0xe5, 0x2d, 0xf0, 0x75, 0x2e, 0x40, 0x20, 0x69, 0x04, 0xa2, 0x68, 0x80, 0x26, -0x30, 0x68, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe2, 0x04, 0x7f, 0x01, -0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02, -0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x73, 0x92, 0x72, 0x20, 0x6b, 0x04, 0xa2, 0x6a, 0x80, -0x26, 0x30, 0x6a, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe0, 0x04, 0x7f, -0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, -0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x75, 0x92, 0x74, 0x20, 0x6d, 0x04, 0xa2, 0x6c, -0x80, 0x26, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe1, 0x04, -0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, -0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x71, 0x92, 0x70, 0x90, 0x10, 0x00, 0xe0, -0x90, 0x10, 0x2f, 0xf0, 0x90, 0x10, 0x03, 0xe0, 0xc3, 0x94, 0x30, 0x40, 0x14, 0xa2, 0x71, 0x92, -0x77, 0xa2, 0x70, 0x92, 0x76, 0xe5, 0x2e, 0x13, 0x13, 0x54, 0x3f, 0xf5, 0x2e, 0xc2, 0x77, 0xd2, -0x76, 0x90, 0x10, 0x2f, 0xe5, 0x2e, 0xf0, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x4c, 0x90, 0x02, 0x29, -0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x43, 0xc4, 0x54, 0x0f, 0x14, 0x60, 0x14, 0x24, 0xfe, 0x60, 0x23, -0x24, 0x03, 0x60, 0x03, 0x02, 0x16, 0x18, 0x90, 0x02, 0x28, 0xe0, 0x30, 0x47, 0x0f, 0x80, 0x07, -0x90, 0x02, 0x28, 0xe0, 0x20, 0x47, 0x06, 0x54, 0xfe, 0xf0, 0x02, 0x16, 0x18, 0x44, 0x01, 0xf0, -0x02, 0x16, 0x18, 0xe5, 0x46, 0x30, 0xe2, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0x90, 0x02, -0x28, 0xe0, 0x54, 0xfe, 0x4f, 0xf0, 0x02, 0x16, 0x18, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x0f, 0xe5, -0x47, 0x64, 0x08, 0x60, 0x09, 0xe5, 0x47, 0x64, 0x09, 0x60, 0x03, 0x02, 0x16, 0x18, 0xe4, 0xf5, -0x27, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfc, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x2d, 0x14, 0x60, 0x2e, -0x14, 0x60, 0x36, 0x24, 0xfc, 0x60, 0x5f, 0x24, 0xf9, 0x60, 0x1f, 0x24, 0x0e, 0x70, 0x69, 0xe5, -0x46, 0x13, 0x13, 0x54, 0x3f, 0x75, 0xf0, 0x03, 0x84, 0xaf, 0xf0, 0x20, 0x47, 0x04, 0x7e, 0x01, -0x80, 0x02, 0x7e, 0x00, 0xef, 0x6e, 0x24, 0xff, 0x80, 0x45, 0xa2, 0x47, 0x80, 0x41, 0xe5, 0x46, -0x30, 0xe2, 0x03, 0xd3, 0x80, 0x27, 0xc3, 0x80, 0x24, 0xe5, 0x46, 0x30, 0xe2, 0x0d, 0x54, 0x38, -0xc3, 0x94, 0x30, 0x50, 0x06, 0x7e, 0x00, 0x7f, 0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0x20, -0x47, 0x04, 0x7d, 0x01, 0x80, 0x02, 0x7d, 0x00, 0xef, 0x6d, 0x4e, 0x24, 0xff, 0x92, 0x38, 0xa2, -0x47, 0xb3, 0x92, 0x39, 0x80, 0x19, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, -0x39, 0xa2, 0x47, 0xb3, 0x92, 0x38, 0x80, 0x07, 0xa2, 0x47, 0xb3, 0x92, 0x38, 0x92, 0x39, 0x90, -0x02, 0x28, 0xe0, 0x54, 0xfc, 0x45, 0x27, 0xf0, 0x90, 0x70, 0x9c, 0xe5, 0x3a, 0xf0, 0xa3, 0xe5, -0x47, 0xf0, 0x90, 0x70, 0x41, 0xe5, 0x3a, 0xf0, 0x22, 0xe4, 0x90, 0x02, 0x29, 0xf0, 0x30, 0x47, -0x04, 0xaf, 0x45, 0x80, 0x04, 0xe5, 0x45, 0xf4, 0xff, 0x90, 0x02, 0x28, 0xef, 0xf0, 0x22, 0x8f, -0x50, 0xd2, 0x59, 0x22, 0x8f, 0x54, 0xd2, 0x58, 0x22, 0xe4, 0xf5, 0x62, 0xc2, 0xaf, 0xe5, 0x51, -0x14, 0x60, 0x46, 0x14, 0x60, 0x62, 0x24, 0x02, 0x60, 0x03, 0x02, 0x17, 0x03, 0xd2, 0x59, 0x75, -0x55, 0x01, 0x90, 0x02, 0xa2, 0xe0, 0x54, 0x7f, 0xf0, 0xa3, 0xe0, 0x20, 0xe7, 0x22, 0x90, 0x04, -0x34, 0xe0, 0xb4, 0x02, 0x1b, 0xa3, 0xe0, 0xb4, 0x02, 0x16, 0xa3, 0xe0, 0xb4, 0x02, 0x11, 0x7f, -0x20, 0x12, 0x16, 0x3f, 0x90, 0x10, 0x04, 0xe0, 0x54, 0xf3, 0xf0, 0x75, 0x51, 0x01, 0x80, 0x73, -0xe5, 0x50, 0x70, 0x05, 0x75, 0x62, 0x03, 0x80, 0x6a, 0x90, 0x12, 0x00, 0xe0, 0x54, 0x03, 0x70, -0x11, 0x7f, 0x20, 0x12, 0x16, 0x3f, 0x90, 0x02, 0xa2, 0xe0, 0x54, 0xbf, 0xf0, 0x75, 0x51, 0x02, -0x80, 0x51, 0xe5, 0x50, 0x70, 0x02, 0x80, 0x46, 0x90, 0x02, 0xa3, 0xe0, 0x20, 0xe6, 0x3b, 0x90, -0x04, 0x37, 0xe0, 0x64, 0x22, 0x70, 0x33, 0x90, 0x01, 0x8a, 0x74, 0x7e, 0xf0, 0x90, 0x01, 0x96, -0xf0, 0x90, 0x12, 0x04, 0x74, 0x0a, 0xf0, 0x90, 0x13, 0x28, 0xe0, 0x54, 0xf0, 0xf0, 0xa3, 0xe0, -0x54, 0xf0, 0xf0, 0xa3, 0xe0, 0x54, 0xfa, 0xf0, 0x90, 0x04, 0x01, 0xe0, 0x54, 0xf9, 0xf0, 0x75, -0x62, 0x01, 0x75, 0x55, 0x02, 0xe4, 0xf5, 0x51, 0x80, 0x09, 0xe5, 0x50, 0x70, 0x05, 0x75, 0x62, -0x03, 0xf5, 0x51, 0xe5, 0x62, 0x60, 0x15, 0xc2, 0x01, 0xe4, 0xf5, 0x51, 0xc2, 0x59, 0xad, 0x62, -0xaf, 0x40, 0x12, 0x17, 0x8d, 0xe5, 0x62, 0xb4, 0x03, 0x02, 0xd2, 0x03, 0xd2, 0xaf, 0x22, 0xc2, -0xaf, 0x30, 0x01, 0x12, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xf5, 0x51, 0xc2, 0x59, 0xc2, 0x01, 0x7d, -0x02, 0xaf, 0x40, 0x12, 0x17, 0x8d, 0xe5, 0x52, 0x14, 0x60, 0x09, 0x04, 0x70, 0x4c, 0x75, 0x52, -0x01, 0x75, 0x55, 0x03, 0x90, 0x04, 0x01, 0xe0, 0x44, 0x0e, 0xf0, 0x90, 0x13, 0x28, 0xe0, 0x44, -0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x05, 0xf0, 0x90, 0x12, 0x04, 0x74, -0x03, 0xf0, 0x90, 0x02, 0xa2, 0xe0, 0x44, 0xc0, 0xf0, 0x90, 0x10, 0x04, 0xe0, 0x44, 0x0c, 0xf0, -0xe4, 0xf5, 0x52, 0xf5, 0x55, 0x30, 0x02, 0x0b, 0xc2, 0x02, 0x7d, 0x01, 0xaf, 0x41, 0x12, 0x17, -0x8d, 0x80, 0x02, 0xc2, 0x03, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xd2, 0xaf, 0x22, 0xef, 0xf4, 0x60, -0x2d, 0xe4, 0xfe, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xe0, 0xb4, 0xff, -0x19, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xef, 0xf0, 0x74, 0x1c, 0x2e, -0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xed, 0xf0, 0x22, 0x0e, 0xbe, 0x04, 0xd5, 0x22, 0x22, -0x22, 0x90, 0x70, 0x2a, 0xe0, 0x30, 0xe1, 0x4d, 0xc2, 0xaf, 0x90, 0x70, 0x28, 0xe0, 0x90, 0x10, -0x1c, 0xf0, 0x90, 0x70, 0x29, 0xe0, 0x90, 0x10, 0x1d, 0xf0, 0x90, 0x70, 0x2a, 0xe0, 0x90, 0x10, -0x1e, 0xf0, 0x90, 0x10, 0x1c, 0xe0, 0xf5, 0x62, 0x90, 0x10, 0x1e, 0xe0, 0x20, 0xe1, 0xf3, 0x90, -0x10, 0x1c, 0xe0, 0x90, 0x70, 0x28, 0xf0, 0x90, 0x10, 0x1d, 0xe0, 0x90, 0x70, 0x29, 0xf0, 0x90, -0x10, 0x1e, 0xe0, 0x90, 0x70, 0x2a, 0xf0, 0x30, 0x4a, 0x07, 0x90, 0x70, 0x24, 0xe0, 0x44, 0x01, -0xf0, 0xc2, 0x05, 0xd2, 0xaf, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x9b, 0xc0, } ; diff --git a/drivers/staging/rt3070/md4.h b/drivers/staging/rt3070/md4.h index a9cc7b0..b3fb637 100644 --- a/drivers/staging/rt3070/md4.h +++ b/drivers/staging/rt3070/md4.h @@ -35,8 +35,8 @@ typedef struct _MD4_CTX_ { u8 buffer[64]; /* input buffer */ } MD4_CTX; -void MD4Init (MD4_CTX *); -void MD4Update (MD4_CTX *, u8 *, UINT); -void MD4Final (u8 [16], MD4_CTX *); +void MD4Init(MD4_CTX *); +void MD4Update(MD4_CTX *, u8 *, UINT); +void MD4Final(u8 [16], MD4_CTX *); -#endif //__MD4_H__
\ No newline at end of file +#endif /*__MD4_H__*/ diff --git a/drivers/staging/rt3090/firmware.h b/drivers/staging/rt3090/firmware.h deleted file mode 100644 index 17056e2..0000000 --- a/drivers/staging/rt3090/firmware.h +++ /dev/null @@ -1,517 +0,0 @@ -/* AUTO GEN PLEASE DO NOT MODIFY IT */ -/* AUTO GEN PLEASE DO NOT MODIFY IT */ - - -u8 FirmwareImage_3090 [] = { -0x02, 0x02, 0xf3, 0x02, 0x02, 0xa1, 0x22, 0x22, 0xff, 0xff, 0xff, 0x02, 0x01, 0x27, 0xff, 0xff, -0xff, 0xff, 0xff, 0x02, 0x00, 0x1e, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02, 0x00, 0xd8, 0xc0, 0xe0, -0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x18, 0xc2, 0xaf, 0x30, 0x45, 0x03, -0x12, 0x10, 0x09, 0x90, 0x04, 0x16, 0xe0, 0x30, 0xe3, 0x03, 0x74, 0x08, 0xf0, 0x90, 0x04, 0x14, -0xe0, 0x20, 0xe7, 0x03, 0x02, 0x00, 0xcb, 0x74, 0x80, 0xf0, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x36, -0x90, 0x04, 0x04, 0xe0, 0x24, 0xcf, 0x60, 0x30, 0x14, 0x60, 0x42, 0x24, 0xe2, 0x60, 0x47, 0x14, -0x60, 0x55, 0x24, 0x21, 0x70, 0x60, 0xe5, 0x55, 0x24, 0xfe, 0x60, 0x07, 0x14, 0x60, 0x08, 0x24, -0x02, 0x70, 0x08, 0x7d, 0x01, 0x80, 0x28, 0x7d, 0x02, 0x80, 0x24, 0x90, 0x70, 0x10, 0xe0, 0xf5, -0x50, 0x85, 0x36, 0x40, 0xd2, 0x01, 0x80, 0x3e, 0xe5, 0x55, 0x64, 0x03, 0x60, 0x04, 0xe5, 0x55, -0x70, 0x04, 0x7d, 0x02, 0x80, 0x09, 0x85, 0x36, 0x41, 0xd2, 0x02, 0x80, 0x29, 0xad, 0x55, 0xaf, -0x36, 0x12, 0x02, 0x7d, 0x80, 0x20, 0x90, 0x70, 0x10, 0xe0, 0xf5, 0x47, 0x90, 0x70, 0x11, 0xe0, -0xf5, 0x44, 0x12, 0x10, 0x25, 0x80, 0x06, 0x90, 0x70, 0x10, 0xe0, 0xf5, 0x45, 0xe4, 0xfd, 0xaf, -0x36, 0x12, 0x02, 0x7d, 0xd2, 0x04, 0x90, 0x70, 0x13, 0xe4, 0xf0, 0xd2, 0xaf, 0xd0, 0xd0, 0xd0, -0x82, 0xd0, 0x83, 0xd0, 0xf0, 0xd0, 0xe0, 0x32, 0xc0, 0xe0, 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, -0xc0, 0xd0, 0xe8, 0xc0, 0xe0, 0xe9, 0xc0, 0xe0, 0xea, 0xc0, 0xe0, 0xeb, 0xc0, 0xe0, 0xec, 0xc0, -0xe0, 0xed, 0xc0, 0xe0, 0xee, 0xc0, 0xe0, 0xef, 0xc0, 0xe0, 0xc2, 0xaf, 0x30, 0x45, 0x03, 0x12, -0x10, 0x12, 0xd2, 0xaf, 0xd0, 0xe0, 0xff, 0xd0, 0xe0, 0xfe, 0xd0, 0xe0, 0xfd, 0xd0, 0xe0, 0xfc, -0xd0, 0xe0, 0xfb, 0xd0, 0xe0, 0xfa, 0xd0, 0xe0, 0xf9, 0xd0, 0xe0, 0xf8, 0xd0, 0xd0, 0xd0, 0x82, -0xd0, 0x83, 0xd0, 0xf0, 0xd0, 0xe0, 0x32, 0xc0, 0xe0, 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, -0xd0, 0x75, 0xd0, 0x10, 0xc2, 0xaf, 0x30, 0x45, 0x03, 0x12, 0x10, 0x0c, 0x30, 0x58, 0x0a, 0xe5, -0x54, 0x60, 0x04, 0x15, 0x54, 0x80, 0x02, 0xc2, 0x58, 0x30, 0x59, 0x0a, 0xe5, 0x50, 0x60, 0x04, -0x15, 0x50, 0x80, 0x02, 0xc2, 0x59, 0xd5, 0x53, 0x07, 0x30, 0x60, 0x04, 0x15, 0x46, 0xd2, 0x04, -0x30, 0x45, 0x03, 0x12, 0x10, 0x0f, 0xc2, 0x8d, 0xd2, 0xaf, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, -0xd0, 0xf0, 0xd0, 0xe0, 0x32, 0x90, 0x70, 0x2a, 0xe0, 0x30, 0xe1, 0x43, 0xc2, 0xaf, 0x90, 0x70, -0x28, 0xe0, 0x90, 0x10, 0x1c, 0xf0, 0x90, 0x70, 0x29, 0xe0, 0x90, 0x10, 0x1d, 0xf0, 0x90, 0x70, -0x2a, 0xe0, 0x90, 0x10, 0x1e, 0xf0, 0x90, 0x10, 0x1c, 0xe0, 0xf5, 0x37, 0x90, 0x10, 0x1e, 0xe0, -0x20, 0xe1, 0xf3, 0x90, 0x10, 0x1c, 0xe0, 0x90, 0x70, 0x28, 0xf0, 0x90, 0x10, 0x1d, 0xe0, 0x90, -0x70, 0x29, 0xf0, 0x90, 0x10, 0x1e, 0xe0, 0x90, 0x70, 0x2a, 0xf0, 0xc2, 0x05, 0xd2, 0xaf, 0x22, -0x12, 0x02, 0xc3, 0x30, 0x45, 0x03, 0x12, 0x10, 0x03, 0x30, 0x01, 0x06, 0x20, 0x09, 0x03, 0x12, -0x10, 0x1c, 0x30, 0x02, 0x06, 0x20, 0x0a, 0x03, 0x12, 0x10, 0x1f, 0x30, 0x03, 0x06, 0x20, 0x0b, -0x03, 0x12, 0x10, 0x1f, 0x30, 0x04, 0x06, 0x20, 0x0c, 0x03, 0x12, 0x10, 0x22, 0x20, 0x13, 0x09, -0x20, 0x11, 0x06, 0xe5, 0x2b, 0x45, 0x2c, 0x60, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0xa9, 0x12, -0x03, 0x1c, 0x80, 0xbf, 0xc2, 0x43, 0xd2, 0x45, 0xe4, 0xf5, 0x20, 0xf5, 0x21, 0xf5, 0x53, 0xf5, -0x46, 0xf5, 0x2b, 0xf5, 0x2c, 0xc2, 0x42, 0xf5, 0x51, 0xf5, 0x52, 0xf5, 0x55, 0x90, 0x04, 0x18, -0x74, 0x80, 0xf0, 0x90, 0x04, 0x1a, 0x74, 0x08, 0xf0, 0xc2, 0x1a, 0xc2, 0x18, 0xc2, 0x1b, 0x22, -0xc8, 0xef, 0xc8, 0xe6, 0xfa, 0x08, 0xe6, 0x4a, 0x60, 0x0c, 0xc8, 0xef, 0xc8, 0x08, 0xe6, 0x16, -0x18, 0x70, 0x01, 0x16, 0xc3, 0x22, 0xed, 0x24, 0xff, 0xfd, 0xec, 0x34, 0xff, 0xc8, 0xef, 0xc8, -0xf6, 0x08, 0xc6, 0xed, 0xc6, 0xd3, 0x22, 0xd0, 0x83, 0xd0, 0x82, 0xf8, 0xe4, 0x93, 0x70, 0x12, -0x74, 0x01, 0x93, 0x70, 0x0d, 0xa3, 0xa3, 0x93, 0xf8, 0x74, 0x01, 0x93, 0xf5, 0x82, 0x88, 0x83, -0xe4, 0x73, 0x74, 0x02, 0x93, 0x68, 0x60, 0xef, 0xa3, 0xa3, 0xa3, 0x80, 0xdf, 0xef, 0xf4, 0x60, -0x1f, 0xe4, 0xfe, 0x12, 0x03, 0x5b, 0xe0, 0xb4, 0xff, 0x12, 0x12, 0x03, 0x5b, 0xef, 0xf0, 0x74, -0x1c, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xed, 0xf0, 0x22, 0x0e, 0xbe, 0x04, 0xe3, -0x22, 0xc0, 0xe0, 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x08, 0xc2, 0xaf, -0x30, 0x45, 0x03, 0x12, 0x10, 0x06, 0xd2, 0xaf, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xf0, -0xd0, 0xe0, 0x32, 0xc2, 0xaf, 0x12, 0x00, 0x06, 0x12, 0x02, 0x04, 0x12, 0x02, 0xdc, 0xe4, 0xf5, -0x22, 0xf5, 0x47, 0x90, 0x04, 0x00, 0x74, 0x80, 0xf0, 0xd2, 0xaf, 0x22, 0x75, 0x89, 0x02, 0xe4, -0xf5, 0x8c, 0xf5, 0x8a, 0xf5, 0x88, 0xf5, 0xb8, 0xf5, 0xe8, 0x75, 0x90, 0x18, 0xd2, 0x8c, 0x75, -0xa8, 0x05, 0x22, 0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x5f, 0x02, 0x01, 0xc0, 0xff, -0xc0, 0x26, 0x74, 0x03, 0xc0, 0xe0, 0xc0, 0x82, 0xc0, 0x83, 0x75, 0x26, 0x0a, 0x22, 0xc0, 0x26, -0x74, 0x03, 0xc0, 0xe0, 0xc0, 0x82, 0xc0, 0x83, 0x75, 0x26, 0x18, 0x22, 0x30, 0x45, 0x03, 0x12, -0x10, 0x15, 0xe5, 0x20, 0x70, 0x03, 0x20, 0x10, 0x03, 0x30, 0x11, 0x03, 0x43, 0x87, 0x01, 0x22, -0xce, 0xef, 0xce, 0xee, 0x60, 0x08, 0x7f, 0xff, 0x12, 0x03, 0x71, 0x1e, 0x80, 0xf5, 0x22, 0xc8, -0xef, 0xc8, 0xe6, 0x60, 0x03, 0x16, 0xc3, 0x22, 0xed, 0x14, 0xf6, 0xd3, 0x22, 0xc8, 0xef, 0xc8, -0xe6, 0x60, 0x06, 0x16, 0xe6, 0x24, 0xff, 0xb3, 0x22, 0xc3, 0x22, 0x74, 0x14, 0x2e, 0xf5, 0x82, -0xe4, 0x34, 0x70, 0xf5, 0x83, 0x22, 0xef, 0x90, 0x03, 0x6f, 0x93, 0x90, 0x03, 0x00, 0x73, 0x0a, -0x18, 0xef, 0x60, 0x03, 0x1f, 0x80, 0xfa, 0x22, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0x02, 0x10, 0x28, 0x02, 0x10, 0x3b, 0x02, 0x10, 0x3c, 0x02, 0x13, 0x68, 0x02, -0x13, 0x69, 0x02, 0x14, 0x1e, 0x02, 0x14, 0x1f, 0xc3, 0x22, 0xff, 0xff, 0x02, 0x19, 0xa1, 0x02, -0x1b, 0x31, 0x02, 0x14, 0xea, 0x02, 0x14, 0x20, 0x30, 0x05, 0x06, 0x20, 0x0d, 0x03, 0x12, 0x01, -0x75, 0x30, 0x06, 0x06, 0x20, 0x0e, 0x03, 0x12, 0x1c, 0x4f, 0x22, 0x22, 0x90, 0x04, 0x14, 0xe0, -0x20, 0xe7, 0x03, 0x02, 0x13, 0x67, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x56, 0x90, 0x04, 0x04, 0xe0, -0x12, 0x02, 0x57, 0x11, 0x11, 0x30, 0x10, 0xe2, 0x31, 0x10, 0x90, 0x33, 0x10, 0xa0, 0x34, 0x10, -0xbe, 0x35, 0x10, 0xac, 0x36, 0x11, 0x1f, 0x50, 0x11, 0x68, 0x51, 0x11, 0x71, 0x52, 0x11, 0x71, -0x53, 0x11, 0x71, 0x54, 0x11, 0xb3, 0x55, 0x12, 0x16, 0x70, 0x12, 0x42, 0x71, 0x12, 0x71, 0x72, -0x12, 0xda, 0x73, 0x12, 0xfe, 0x80, 0x13, 0x29, 0x83, 0x13, 0x47, 0x84, 0x00, 0x00, 0x13, 0x67, -0xd2, 0x18, 0xd2, 0x61, 0x75, 0x35, 0x2a, 0x75, 0x32, 0x0b, 0x75, 0x33, 0xb8, 0x02, 0x13, 0x62, -0xc2, 0x18, 0x90, 0x01, 0x14, 0xe0, 0x54, 0xfd, 0xf0, 0x02, 0x13, 0x62, 0x90, 0x70, 0x11, 0xe0, -0xf5, 0x3c, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0x22, 0xe5, 0x55, -0xb4, 0x02, 0x0f, 0xe5, 0x59, 0xb4, 0x28, 0x06, 0x90, 0x01, 0x0d, 0x74, 0x08, 0xf0, 0x7d, 0x01, -0x80, 0x02, 0x7d, 0x02, 0xaf, 0x56, 0x12, 0x02, 0x7d, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0x02, -0x13, 0x62, 0x20, 0x02, 0x03, 0x30, 0x03, 0x10, 0x7d, 0x02, 0xaf, 0x56, 0x12, 0x02, 0x7d, 0x90, -0x04, 0x14, 0x74, 0x80, 0xf0, 0x02, 0x13, 0x62, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40, 0x0c, 0x90, -0x01, 0x0c, 0xe0, 0x44, 0x02, 0xf0, 0xa3, 0xe0, 0x44, 0x04, 0xf0, 0x85, 0x56, 0x41, 0xd2, 0x02, -0x22, 0x90, 0x70, 0x11, 0xe0, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x67, 0xe0, 0xf5, 0x30, 0x22, 0xe5, -0x34, 0xc3, 0x94, 0x03, 0x40, 0x07, 0xe5, 0x55, 0x60, 0x03, 0x02, 0x13, 0x67, 0x90, 0x70, 0x10, -0xe0, 0x54, 0x7f, 0xff, 0xbf, 0x0a, 0x0d, 0x90, 0x70, 0x11, 0xe0, 0xb4, 0x08, 0x06, 0x75, 0x4e, -0x01, 0x75, 0x4f, 0x84, 0x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, 0x64, 0x02, 0x60, 0x03, 0x02, 0x13, -0x67, 0x90, 0x70, 0x11, 0xe0, 0x64, 0x08, 0x60, 0x08, 0xe0, 0x64, 0x20, 0x60, 0x03, 0x02, 0x13, -0x67, 0x75, 0x4e, 0x03, 0x75, 0x4f, 0x20, 0x22, 0x90, 0x70, 0x11, 0xe0, 0x24, 0xff, 0x92, 0x47, -0x22, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40, 0x07, 0xe5, 0x55, 0x60, 0x03, 0x02, 0x13, 0x09, 0x90, -0x04, 0x04, 0xe0, 0x25, 0xe0, 0x24, 0x5d, 0xf5, 0x57, 0x90, 0x70, 0x10, 0xe0, 0xff, 0x74, 0x47, -0x25, 0x57, 0xf8, 0xc6, 0xef, 0xc6, 0x90, 0x70, 0x11, 0xe0, 0xff, 0x74, 0x48, 0x25, 0x57, 0xf8, -0xc6, 0xef, 0xc6, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x02, 0x7d, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, -0x02, 0x13, 0x62, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40, 0x07, 0xe5, 0x55, 0x60, 0x03, 0x02, 0x13, -0x09, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x23, 0xe5, 0x47, 0x64, 0x08, 0x60, 0x1d, 0xe5, 0x47, 0x64, -0x09, 0x60, 0x17, 0xe5, 0x47, 0x64, 0x0a, 0x60, 0x11, 0xe5, 0x47, 0x64, 0x0b, 0x60, 0x0b, 0xe5, -0x47, 0x64, 0x0d, 0x60, 0x05, 0xe5, 0x47, 0xb4, 0x0d, 0x08, 0x90, 0x70, 0x11, 0xe0, 0x54, 0x0f, -0xf5, 0x3a, 0xe5, 0x47, 0xb4, 0x09, 0x08, 0xe5, 0x3a, 0xb4, 0x03, 0x03, 0xe4, 0xf5, 0x46, 0xe5, -0x47, 0xb4, 0x0a, 0x08, 0xe5, 0x3a, 0xb4, 0x01, 0x03, 0xe4, 0xf5, 0x46, 0xe4, 0xfd, 0xaf, 0x56, -0x12, 0x02, 0x7d, 0xd2, 0x04, 0x22, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40, 0x07, 0xe5, 0x55, 0x60, -0x03, 0x02, 0x13, 0x09, 0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed, 0xf8, -0xe6, 0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x02, 0x7d, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0x02, -0x13, 0x62, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40, 0x07, 0xe5, 0x55, 0x60, 0x03, 0x02, 0x13, 0x09, -0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed, 0xf5, 0x82, 0x8e, 0x83, 0xe0, -0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x02, 0x7d, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0x02, 0x13, -0x62, 0x90, 0x10, 0x00, 0xe0, 0xf5, 0x57, 0x90, 0x10, 0x02, 0xe0, 0xf5, 0x58, 0xa3, 0xe0, 0xf5, -0x59, 0xe5, 0x58, 0xb4, 0x70, 0x1e, 0xe5, 0x59, 0xb4, 0x30, 0x19, 0x90, 0x05, 0x08, 0xe0, 0x44, -0x01, 0xf0, 0xfd, 0x90, 0x05, 0x05, 0xe0, 0x54, 0xfb, 0xf0, 0x44, 0x04, 0xf0, 0xed, 0x54, 0xfe, -0x90, 0x05, 0x08, 0xf0, 0xe4, 0xf5, 0x4e, 0xf5, 0x4f, 0x75, 0x3a, 0xff, 0xc2, 0x1a, 0xc2, 0x18, -0xc2, 0x1b, 0xf5, 0x34, 0x90, 0x05, 0xa4, 0x74, 0x11, 0xf0, 0xa3, 0x74, 0xff, 0xf0, 0xa3, 0x74, -0x03, 0xf0, 0xe4, 0xf5, 0x30, 0xc2, 0x19, 0x75, 0x3c, 0xff, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x02, -0x7d, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0x02, 0x13, 0x62, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40, -0x06, 0xe5, 0x55, 0x60, 0x02, 0x80, 0x22, 0x90, 0x70, 0x10, 0xe0, 0x24, 0xff, 0x92, 0x93, 0xe4, -0xfd, 0xaf, 0x56, 0x12, 0x02, 0x7d, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0x80, 0x64, 0xe5, 0x34, -0xc3, 0x94, 0x03, 0x40, 0x0b, 0xe5, 0x55, 0x60, 0x07, 0x7d, 0x03, 0xaf, 0x56, 0x02, 0x02, 0x7d, -0x90, 0x70, 0x10, 0xe0, 0x24, 0xff, 0x92, 0x4a, 0xd2, 0x05, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x02, -0x7d, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0x80, 0x39, 0xe4, 0xf5, 0x34, 0xf5, 0x30, 0x90, 0x70, -0x10, 0xe0, 0xf4, 0x60, 0x03, 0xe0, 0xf5, 0x34, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x02, 0x7d, 0x90, -0x04, 0x14, 0x74, 0x80, 0xf0, 0x80, 0x1b, 0xd2, 0x19, 0x05, 0x2f, 0xe5, 0x2f, 0xb4, 0x1a, 0x03, -0xe4, 0xf5, 0x2f, 0xd2, 0x04, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x02, 0x7d, 0x90, 0x04, 0x14, 0x74, -0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0x22, 0x22, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40, 0x17, -0xe5, 0x55, 0xb4, 0x02, 0x12, 0xe5, 0x30, 0x60, 0x0e, 0x30, 0x60, 0x0b, 0x74, 0xfd, 0x25, 0x46, -0xf5, 0x46, 0xd2, 0x04, 0xe4, 0xf5, 0x53, 0xe5, 0x53, 0x60, 0x03, 0x02, 0x14, 0x1d, 0x30, 0x60, -0x21, 0xb2, 0x4d, 0x30, 0x4d, 0x1c, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40, 0x11, 0xe5, 0x55, 0xb4, -0x02, 0x0c, 0xe5, 0x30, 0x60, 0x08, 0x74, 0x03, 0x25, 0x46, 0xf5, 0x46, 0x80, 0x02, 0x05, 0x46, -0xc2, 0x04, 0xe5, 0x4f, 0x45, 0x4e, 0x60, 0x08, 0xe5, 0x4f, 0x15, 0x4f, 0x70, 0x02, 0x15, 0x4e, -0x30, 0x1a, 0x49, 0x7f, 0x32, 0x7d, 0xb8, 0x7c, 0x0b, 0x12, 0x02, 0x30, 0x50, 0x06, 0x90, 0x04, -0x10, 0x74, 0x40, 0xf0, 0x7f, 0x35, 0x7d, 0x32, 0x12, 0x03, 0x3f, 0x50, 0x09, 0x90, 0x10, 0x04, -0xe0, 0x54, 0xf7, 0xf0, 0xd2, 0x06, 0xe5, 0x35, 0xd3, 0x94, 0x2d, 0x40, 0x30, 0x30, 0x1b, 0x2d, -0xc2, 0x1b, 0xa2, 0x18, 0x92, 0x1a, 0x20, 0x1a, 0x24, 0x90, 0x04, 0x09, 0xe0, 0x54, 0xdd, 0xf0, -0x90, 0x10, 0x04, 0xe0, 0x44, 0x08, 0xf0, 0xc2, 0x61, 0xd2, 0x03, 0x22, 0xe4, 0xf5, 0x35, 0xa2, -0x18, 0x92, 0x1a, 0x30, 0x1a, 0x07, 0x90, 0x04, 0x09, 0xe0, 0x44, 0x22, 0xf0, 0x22, 0x22, 0x22, -0xc2, 0x4b, 0xc2, 0x4c, 0xe5, 0x44, 0x12, 0x02, 0x57, 0x14, 0x42, 0x00, 0x14, 0xd5, 0x04, 0x14, -0xd1, 0x08, 0x14, 0xac, 0x10, 0x14, 0x56, 0x20, 0x14, 0x76, 0x60, 0x14, 0x87, 0xa0, 0x00, 0x00, -0x14, 0xd7, 0x85, 0x48, 0x43, 0x85, 0x4a, 0x42, 0x85, 0x4c, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x60, -0x03, 0x02, 0x14, 0xd7, 0x80, 0x1b, 0xe5, 0x48, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4a, 0xc4, -0x54, 0x0f, 0xf5, 0x42, 0xe5, 0x4c, 0xc4, 0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, -0x66, 0x53, 0x43, 0x0f, 0x80, 0x61, 0x85, 0x49, 0x43, 0x85, 0x4b, 0x42, 0x85, 0x4d, 0x5e, 0xe5, -0x47, 0x64, 0x06, 0x70, 0x52, 0x80, 0x1b, 0xe5, 0x49, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4b, -0xc4, 0x54, 0x0f, 0xf5, 0x42, 0xe5, 0x4d, 0xc4, 0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, -0x70, 0x35, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x10, 0xf5, 0x43, 0x80, 0x2b, 0xe5, 0x47, 0xb4, 0x04, -0x06, 0x53, 0x5e, 0xfb, 0x75, 0x42, 0x09, 0xe5, 0x47, 0xb4, 0x05, 0x06, 0x43, 0x5e, 0x04, 0x75, -0x42, 0x09, 0xe5, 0x47, 0xb4, 0x06, 0x10, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x30, 0xf5, 0x43, 0x80, -0x06, 0xd2, 0x4b, 0x80, 0x02, 0xd2, 0x4c, 0xe4, 0xf5, 0x2a, 0xe5, 0x42, 0xc4, 0x54, 0xf0, 0xff, -0xe5, 0x43, 0x54, 0x0f, 0x4f, 0xf5, 0x5f, 0xd2, 0x60, 0x22, 0xe5, 0x47, 0x60, 0x1a, 0x24, 0xc0, -0x60, 0x0a, 0x24, 0x35, 0x70, 0x09, 0x12, 0x19, 0x5f, 0x12, 0x15, 0x09, 0x12, 0x19, 0x5f, 0x12, -0x15, 0x09, 0xc2, 0xaf, 0xc2, 0x04, 0xd2, 0xaf, 0x22, 0xc2, 0xaf, 0x90, 0x04, 0x14, 0xe0, 0x54, -0x0e, 0x60, 0x04, 0xd2, 0x1c, 0x80, 0x08, 0xe5, 0x4e, 0x45, 0x4f, 0x24, 0xff, 0x92, 0x1c, 0xd2, -0xaf, 0x90, 0x04, 0x14, 0xe0, 0xa2, 0xe4, 0x92, 0x1d, 0x74, 0x1e, 0xf0, 0xe5, 0x5f, 0x54, 0x0f, -0xf5, 0x2d, 0xe5, 0x2a, 0x70, 0x13, 0x30, 0x1c, 0x05, 0xe5, 0x5f, 0x20, 0xe5, 0x0b, 0x30, 0x1d, -0x29, 0xe5, 0x5f, 0x54, 0x30, 0x64, 0x30, 0x70, 0x21, 0xe5, 0x2a, 0x70, 0x15, 0xe5, 0x34, 0xc3, -0x94, 0x03, 0x40, 0x09, 0xe5, 0x30, 0x60, 0x05, 0x75, 0x2a, 0x05, 0x80, 0x07, 0x75, 0x2a, 0x0c, -0x80, 0x02, 0x15, 0x2a, 0xd2, 0x6c, 0xd2, 0x6d, 0x80, 0x0f, 0xe5, 0x5f, 0x30, 0xe6, 0x06, 0xc2, -0x6c, 0xd2, 0x6d, 0x80, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0xe5, 0x47, 0x64, 0x03, 0x70, 0x21, 0x30, -0x4b, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x18, 0xe5, 0x2a, 0x70, 0x03, 0x30, 0x4c, 0x11, 0xc2, -0x4c, 0xe5, 0x2a, 0x70, 0x05, 0x75, 0x2a, 0x07, 0x80, 0x02, 0x15, 0x2a, 0xd2, 0x6c, 0xd2, 0x6d, -0xe5, 0x47, 0xb4, 0x09, 0x14, 0xe5, 0x44, 0x20, 0xe3, 0x0b, 0xe5, 0x3a, 0x64, 0x02, 0x60, 0x05, -0xe5, 0x3a, 0xb4, 0x03, 0x04, 0xc2, 0x6c, 0xd2, 0x6d, 0xe5, 0x47, 0xb4, 0x0a, 0x13, 0xe5, 0x3a, -0xb4, 0x01, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x08, 0xe5, 0x3a, 0x70, 0x04, 0xd2, 0x6c, 0xc2, -0x6d, 0x20, 0x69, 0x07, 0xe5, 0x5e, 0x20, 0xe0, 0x02, 0xb2, 0x68, 0x20, 0x6b, 0x07, 0xe5, 0x5e, -0x20, 0xe1, 0x02, 0xb2, 0x6a, 0x20, 0x6d, 0x07, 0xe5, 0x5e, 0x20, 0xe2, 0x02, 0xb2, 0x6c, 0x75, -0x2e, 0x40, 0x20, 0x69, 0x04, 0xa2, 0x68, 0x80, 0x45, 0x30, 0x68, 0x06, 0xe5, 0x46, 0xa2, 0xe2, -0x80, 0x3c, 0x30, 0x19, 0x1c, 0xe5, 0x5e, 0x20, 0xe2, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, -0xe5, 0x2f, 0xb4, 0x19, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x80, -0x1d, 0xe5, 0x5e, 0x20, 0xe2, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, -0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x73, -0x92, 0x72, 0x20, 0x6b, 0x04, 0xa2, 0x6a, 0x80, 0x45, 0x30, 0x6a, 0x06, 0xe5, 0x46, 0xa2, 0xe2, -0x80, 0x3c, 0x30, 0x19, 0x1c, 0xe5, 0x5e, 0x20, 0xe0, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, -0xe5, 0x2f, 0xb4, 0x19, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x80, -0x1d, 0xe5, 0x5e, 0x20, 0xe0, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, -0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x75, -0x92, 0x74, 0x20, 0x6d, 0x04, 0xa2, 0x6c, 0x80, 0x64, 0xe5, 0x47, 0x64, 0x0a, 0x70, 0x19, 0xe5, -0x3a, 0xb4, 0x01, 0x06, 0xe5, 0x46, 0xa2, 0xe3, 0x80, 0x53, 0xe5, 0x46, 0x20, 0xe4, 0x03, 0x30, -0xe5, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x80, 0x45, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, -0x3c, 0x30, 0x19, 0x1c, 0xe5, 0x5e, 0x20, 0xe1, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, -0x2f, 0xb4, 0x19, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x80, 0x1d, -0xe5, 0x5e, 0x20, 0xe1, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, -0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x71, 0x92, -0x70, 0x90, 0x10, 0x00, 0xe0, 0x90, 0x10, 0x2c, 0xf0, 0x90, 0x10, 0x03, 0xe0, 0xc3, 0x94, 0x30, -0x40, 0x14, 0xa2, 0x71, 0x92, 0x77, 0xa2, 0x70, 0x92, 0x76, 0xe5, 0x2e, 0x13, 0x13, 0x54, 0x3f, -0xf5, 0x2e, 0xc2, 0x77, 0xd2, 0x76, 0x90, 0x10, 0x2f, 0xe5, 0x2e, 0xf0, 0xe5, 0x47, 0x64, 0x06, -0x70, 0x46, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x43, 0xc4, 0x54, 0x0f, 0x14, 0x60, -0x14, 0x24, 0xfe, 0x60, 0x1f, 0x24, 0x03, 0x60, 0x03, 0x02, 0x19, 0x5e, 0x90, 0x02, 0x28, 0xe0, -0x30, 0x47, 0x0d, 0x80, 0x07, 0x90, 0x02, 0x28, 0xe0, 0x20, 0x47, 0x04, 0x54, 0xfe, 0xf0, 0x22, -0x44, 0x01, 0xf0, 0x22, 0xe5, 0x46, 0x30, 0xe2, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0x90, -0x02, 0x28, 0xe0, 0x54, 0xfe, 0x4f, 0xf0, 0x22, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x0f, 0xe5, 0x47, -0x64, 0x08, 0x60, 0x09, 0xe5, 0x47, 0x64, 0x09, 0x60, 0x03, 0x02, 0x18, 0x27, 0xe4, 0xf5, 0x27, -0x90, 0x02, 0x29, 0xe0, 0x54, 0xfc, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x2d, 0x14, 0x60, 0x2e, 0x14, -0x60, 0x36, 0x24, 0xfc, 0x60, 0x5f, 0x24, 0xf9, 0x60, 0x1f, 0x24, 0x0e, 0x70, 0x69, 0xe5, 0x46, -0x13, 0x13, 0x54, 0x3f, 0x75, 0xf0, 0x03, 0x84, 0xaf, 0xf0, 0x20, 0x47, 0x04, 0x7e, 0x01, 0x80, -0x02, 0x7e, 0x00, 0xef, 0x6e, 0x24, 0xff, 0x80, 0x45, 0xa2, 0x47, 0x80, 0x41, 0xe5, 0x46, 0x30, -0xe2, 0x03, 0xd3, 0x80, 0x27, 0xc3, 0x80, 0x24, 0xe5, 0x46, 0x30, 0xe2, 0x0d, 0x54, 0x38, 0xc3, -0x94, 0x30, 0x50, 0x06, 0x7e, 0x00, 0x7f, 0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0x20, 0x47, -0x04, 0x7d, 0x01, 0x80, 0x02, 0x7d, 0x00, 0xef, 0x6d, 0x4e, 0x24, 0xff, 0x92, 0x38, 0xa2, 0x47, -0xb3, 0x92, 0x39, 0x80, 0x19, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x39, -0xa2, 0x47, 0xb3, 0x92, 0x38, 0x80, 0x07, 0xa2, 0x47, 0xb3, 0x92, 0x38, 0x92, 0x39, 0x90, 0x02, -0x28, 0xe0, 0x54, 0xfc, 0x02, 0x19, 0x5b, 0xe5, 0x47, 0x64, 0x0c, 0x60, 0x09, 0xe5, 0x47, 0x64, -0x0b, 0x60, 0x03, 0x02, 0x18, 0xc6, 0xe4, 0xf5, 0x27, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfd, 0xf0, -0xe5, 0x3a, 0x14, 0x60, 0x2b, 0x14, 0x60, 0x2e, 0x14, 0x60, 0x38, 0x24, 0xfc, 0x60, 0x5c, 0x24, -0xf9, 0x60, 0x1d, 0x24, 0x0e, 0x70, 0x61, 0xe5, 0x46, 0x13, 0x13, 0x54, 0x3f, 0x75, 0xf0, 0x03, -0x84, 0xaf, 0xf0, 0x20, 0x47, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xef, 0x6e, 0x80, 0x35, -0xa2, 0x47, 0x92, 0x39, 0x80, 0x47, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, -0x39, 0x80, 0x3a, 0xe5, 0x46, 0x30, 0xe2, 0x0d, 0x54, 0x38, 0xc3, 0x94, 0x30, 0x50, 0x06, 0x7e, -0x00, 0x7f, 0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0x20, 0x47, 0x04, 0x7d, 0x01, 0x80, 0x02, -0x7d, 0x00, 0xef, 0x6d, 0x4e, 0x24, 0xff, 0x92, 0x39, 0x80, 0x12, 0xe5, 0x46, 0x30, 0xe2, 0x03, -0xd3, 0x80, 0x01, 0xc3, 0x92, 0x39, 0x80, 0x05, 0xa2, 0x47, 0xb3, 0x92, 0x39, 0x90, 0x02, 0x28, -0xe0, 0x54, 0xfd, 0x02, 0x19, 0x5b, 0xe5, 0x47, 0x64, 0x0d, 0x60, 0x03, 0x02, 0x19, 0x5e, 0xf5, -0x27, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xef, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x2b, 0x14, 0x60, 0x2e, -0x14, 0x60, 0x38, 0x24, 0xfc, 0x60, 0x5c, 0x24, 0xf9, 0x60, 0x1d, 0x24, 0x0e, 0x70, 0x61, 0xe5, -0x46, 0x13, 0x13, 0x54, 0x3f, 0x75, 0xf0, 0x03, 0x84, 0xaf, 0xf0, 0x20, 0x47, 0x04, 0x7e, 0x01, -0x80, 0x02, 0x7e, 0x00, 0xef, 0x6e, 0x80, 0x35, 0xa2, 0x47, 0x92, 0x3c, 0x80, 0x47, 0xe5, 0x46, -0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x3c, 0x80, 0x3a, 0xe5, 0x46, 0x30, 0xe2, 0x0d, -0x54, 0x38, 0xc3, 0x94, 0x30, 0x50, 0x06, 0x7e, 0x00, 0x7f, 0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f, -0x00, 0x20, 0x47, 0x04, 0x7d, 0x01, 0x80, 0x02, 0x7d, 0x00, 0xef, 0x6d, 0x4e, 0x24, 0xff, 0x92, -0x3c, 0x80, 0x12, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x3c, 0x80, 0x05, -0xa2, 0x47, 0xb3, 0x92, 0x3c, 0x90, 0x02, 0x28, 0xe0, 0x54, 0xef, 0x45, 0x27, 0xf0, 0x22, 0xe5, -0x47, 0x64, 0x0b, 0x70, 0x1c, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xeb, 0xf0, 0x30, 0x47, 0x04, 0xaf, -0x45, 0x80, 0x05, 0xe5, 0x45, 0x64, 0x14, 0xff, 0x90, 0x02, 0x28, 0xe0, 0x54, 0xeb, 0x4f, 0xf0, -0x22, 0xe4, 0x90, 0x02, 0x29, 0xf0, 0x30, 0x47, 0x04, 0xaf, 0x45, 0x80, 0x04, 0xe5, 0x45, 0xf4, -0xff, 0x90, 0x02, 0x28, 0xef, 0xf0, 0x22, 0x8f, 0x50, 0xd2, 0x59, 0x22, 0x8f, 0x54, 0xd2, 0x58, -0x22, 0xe4, 0xf5, 0x37, 0xc2, 0xaf, 0xe5, 0x51, 0x14, 0x60, 0x4a, 0x14, 0x60, 0x6b, 0x24, 0x02, -0x60, 0x03, 0x02, 0x1b, 0x12, 0xd2, 0x59, 0x75, 0x55, 0x01, 0x20, 0x1a, 0x1c, 0x90, 0x02, 0x08, -0xe0, 0x54, 0xfe, 0xf0, 0xe0, 0x20, 0xe1, 0x23, 0x90, 0x04, 0x34, 0xe0, 0xb4, 0x02, 0x1c, 0xa3, -0xe0, 0xb4, 0x02, 0x17, 0xa3, 0xe0, 0xb4, 0x02, 0x12, 0x7f, 0x20, 0x12, 0x19, 0x97, 0x90, 0x10, -0x04, 0xe0, 0x54, 0xf3, 0xf0, 0x75, 0x51, 0x01, 0x02, 0x1b, 0x12, 0xe5, 0x50, 0x70, 0x06, 0x75, -0x37, 0x03, 0x02, 0x1b, 0x12, 0x90, 0x12, 0x00, 0xe0, 0x54, 0x03, 0x70, 0x15, 0x7f, 0x20, 0x12, -0x19, 0x97, 0x20, 0x1a, 0x07, 0x90, 0x02, 0x08, 0xe0, 0x54, 0xfb, 0xf0, 0x75, 0x51, 0x02, 0x02, -0x1b, 0x12, 0xe5, 0x50, 0x70, 0x03, 0x02, 0x1b, 0x0d, 0x20, 0x1a, 0x15, 0x90, 0x02, 0x08, 0xe0, -0x30, 0xe3, 0x03, 0x02, 0x1b, 0x09, 0x90, 0x04, 0x37, 0xe0, 0x64, 0x22, 0x60, 0x03, 0x02, 0x1b, -0x09, 0x90, 0x12, 0x04, 0x74, 0x0a, 0xf0, 0xe5, 0x58, 0xb4, 0x72, 0x15, 0xe5, 0x59, 0xb4, 0x35, -0x10, 0xe4, 0x90, 0x05, 0x00, 0xf0, 0xa3, 0x74, 0x08, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0x74, 0x03, -0xf0, 0x7f, 0x01, 0x12, 0x03, 0x30, 0x90, 0x13, 0x28, 0xe0, 0x54, 0xf0, 0xf0, 0xa3, 0xe0, 0x54, -0xf0, 0xf0, 0xe5, 0x59, 0xb4, 0x35, 0x14, 0xe5, 0x3c, 0xf4, 0x60, 0x06, 0xa3, 0xe0, 0x54, 0xf3, -0x80, 0x14, 0x90, 0x13, 0x2a, 0xe0, 0x54, 0xfb, 0xf0, 0x80, 0x14, 0xe5, 0x3c, 0xf4, 0x90, 0x13, -0x2a, 0x60, 0x08, 0xe0, 0x54, 0xf2, 0x45, 0x3c, 0xf0, 0x80, 0x04, 0xe0, 0x54, 0xfa, 0xf0, 0x20, -0x1a, 0x07, 0x90, 0x04, 0x01, 0xe0, 0x44, 0x10, 0xf0, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40, 0x09, -0xe5, 0x30, 0x70, 0x05, 0x75, 0x8c, 0x40, 0x80, 0x03, 0x75, 0x8c, 0x80, 0x90, 0x04, 0x01, 0xe0, -0x54, 0xfd, 0xf0, 0x20, 0x1a, 0x07, 0x90, 0x12, 0x04, 0xe0, 0x44, 0x04, 0xf0, 0xe5, 0x59, 0xb4, -0x28, 0x06, 0x90, 0x01, 0x0d, 0xe0, 0xf5, 0x31, 0xe5, 0x34, 0xc3, 0x94, 0x02, 0x40, 0x14, 0x90, -0x01, 0x0d, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x59, 0x64, 0x35, 0x60, 0x07, 0x90, 0x12, 0x04, 0xe0, -0x54, 0xfd, 0xf0, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40, 0x14, 0x20, 0x02, 0x11, 0x20, 0x03, 0x0e, -0x90, 0x01, 0x0d, 0xe0, 0x54, 0xfb, 0xf0, 0x90, 0x01, 0x0c, 0xe0, 0x54, 0xfd, 0xf0, 0x75, 0x37, -0x01, 0x75, 0x55, 0x02, 0xe4, 0xf5, 0x51, 0x80, 0x09, 0xe5, 0x50, 0x70, 0x05, 0x75, 0x37, 0x03, -0xf5, 0x51, 0xe5, 0x37, 0x60, 0x18, 0xc2, 0x01, 0xe4, 0xf5, 0x51, 0xc2, 0x59, 0x20, 0x1a, 0x0e, -0xad, 0x37, 0xaf, 0x40, 0x12, 0x1c, 0x1b, 0xe5, 0x37, 0xb4, 0x03, 0x02, 0xd2, 0x03, 0xd2, 0xaf, -0x22, 0xc2, 0xaf, 0x30, 0x01, 0x0e, 0xe4, 0xf5, 0x51, 0xc2, 0x59, 0xc2, 0x01, 0x7d, 0x02, 0xaf, -0x40, 0x12, 0x1c, 0x1b, 0xe5, 0x52, 0x14, 0x60, 0x5c, 0x14, 0x60, 0x3a, 0x24, 0x02, 0x60, 0x03, -0x02, 0x1c, 0x18, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40, 0x0c, 0x90, 0x01, 0x0c, 0xe0, 0x44, 0x02, -0xf0, 0xa3, 0xe0, 0x44, 0x04, 0xf0, 0xe5, 0x34, 0xc3, 0x94, 0x02, 0x40, 0x13, 0x90, 0x12, 0x04, -0xe0, 0x44, 0x02, 0xf0, 0x7f, 0x32, 0x12, 0x03, 0x30, 0x90, 0x01, 0x0d, 0xe0, 0x54, 0xfe, 0xf0, -0x75, 0x52, 0x02, 0x75, 0x55, 0x03, 0xe5, 0x59, 0xb4, 0x28, 0x06, 0x90, 0x01, 0x0d, 0xe5, 0x31, -0xf0, 0x90, 0x12, 0x04, 0xe0, 0x54, 0xfb, 0xf0, 0x7f, 0x20, 0x12, 0x19, 0x9c, 0x75, 0x52, 0x01, -0x75, 0x55, 0x03, 0x80, 0x73, 0xe5, 0x54, 0x70, 0x6f, 0x90, 0x04, 0x01, 0xe0, 0x44, 0x0e, 0xf0, -0x20, 0x1a, 0x04, 0xe0, 0x54, 0xef, 0xf0, 0xe4, 0xf5, 0x8c, 0x90, 0x13, 0x28, 0xe0, 0x44, 0x0f, -0xf0, 0xa3, 0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x05, 0xf0, 0x90, 0x12, 0x04, 0x74, 0x03, -0xf0, 0xe5, 0x58, 0xb4, 0x72, 0x16, 0xe5, 0x59, 0xb4, 0x35, 0x11, 0x90, 0x05, 0x00, 0x74, 0xe2, -0xf0, 0xa3, 0x74, 0x08, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0x74, 0x03, 0xf0, 0x7f, 0x01, 0x12, 0x03, -0x30, 0x20, 0x1a, 0x07, 0x90, 0x02, 0x08, 0xe0, 0x44, 0x05, 0xf0, 0x90, 0x10, 0x04, 0xe0, 0x44, -0x0c, 0xf0, 0xe4, 0xf5, 0x52, 0xf5, 0x55, 0x30, 0x02, 0x09, 0xc2, 0x02, 0x7d, 0x01, 0xaf, 0x41, -0x12, 0x1c, 0x1b, 0x30, 0x03, 0x02, 0xc2, 0x03, 0xd2, 0xaf, 0x22, 0xef, 0xf4, 0x60, 0x2d, 0xe4, -0xfe, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xe0, 0xb4, 0xff, 0x19, 0x74, -0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xef, 0xf0, 0x74, 0x1c, 0x2e, 0xf5, 0x82, -0xe4, 0x34, 0x70, 0xf5, 0x83, 0xed, 0xf0, 0x22, 0x0e, 0xbe, 0x04, 0xd5, 0x22, 0x22, 0x22, 0x30, -0x1a, 0x77, 0x90, 0x04, 0x37, 0xe0, 0x20, 0xe5, 0x6c, 0x90, 0x04, 0x28, 0xe0, 0xf5, 0x38, 0xa3, -0xe0, 0xf5, 0x37, 0xf5, 0x39, 0xe4, 0xf5, 0x25, 0xe5, 0x39, 0x75, 0xf0, 0x80, 0xa4, 0x24, 0x00, -0xff, 0xe5, 0xf0, 0x34, 0x80, 0xfe, 0xe5, 0x37, 0x65, 0x39, 0x70, 0x05, 0xfc, 0x7d, 0x28, 0x80, -0x04, 0x7c, 0x00, 0x7d, 0x00, 0xef, 0x2d, 0xff, 0xee, 0x3c, 0xfe, 0x12, 0x1c, 0xca, 0x50, 0x07, -0x90, 0x01, 0x14, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x39, 0x65, 0x38, 0x60, 0x10, 0xe4, 0x25, 0x39, -0xff, 0xe4, 0x34, 0x80, 0x8f, 0x82, 0xf5, 0x83, 0xe0, 0xf5, 0x39, 0x80, 0xbb, 0x90, 0x04, 0x10, -0x74, 0x01, 0xf0, 0x90, 0x04, 0x28, 0xe5, 0x38, 0xf0, 0xa3, 0xe5, 0x37, 0xf0, 0x90, 0x04, 0x11, -0x74, 0x01, 0xf0, 0x80, 0x8d, 0xc2, 0x06, 0xd2, 0x1b, 0x22, 0xe5, 0x25, 0xc3, 0x94, 0x06, 0x50, -0x19, 0x8f, 0x82, 0x8e, 0x83, 0xe0, 0xb4, 0xff, 0x07, 0x05, 0x25, 0xe4, 0xf5, 0x24, 0x80, 0x2e, -0xe4, 0xf5, 0x25, 0x8f, 0x82, 0x8e, 0x83, 0xf0, 0x80, 0x24, 0xe5, 0x24, 0x75, 0xf0, 0x06, 0x84, -0x74, 0x08, 0x25, 0xf0, 0xf5, 0x82, 0xe4, 0x34, 0x10, 0xf5, 0x83, 0xe0, 0xfd, 0x8f, 0x82, 0x8e, -0x83, 0xe0, 0x6d, 0x70, 0x06, 0x05, 0x25, 0x05, 0x24, 0x80, 0x03, 0xe4, 0xf5, 0x25, 0x0f, 0xbf, -0x00, 0x01, 0x0e, 0xef, 0x54, 0x7f, 0x60, 0x07, 0xe5, 0x25, 0xc3, 0x94, 0x2a, 0x40, 0xab, 0xe5, -0x25, 0xb4, 0x2a, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xe3, 0x34, } ; diff --git a/drivers/staging/rtl8187se/Kconfig b/drivers/staging/rtl8187se/Kconfig index e24a6f7..155a78e 100644 --- a/drivers/staging/rtl8187se/Kconfig +++ b/drivers/staging/rtl8187se/Kconfig @@ -3,6 +3,7 @@ config R8187SE depends on PCI && WLAN select WIRELESS_EXT select WEXT_PRIV + select EEPROM_93CX6 default N ---help--- If built as a module, it will be called r8187se.ko. diff --git a/drivers/staging/rtl8187se/Makefile b/drivers/staging/rtl8187se/Makefile index b395acf..e6adf91 100644 --- a/drivers/staging/rtl8187se/Makefile +++ b/drivers/staging/rtl8187se/Makefile @@ -18,7 +18,6 @@ EXTRA_CFLAGS += -DENABLE_LPS r8187se-objs := \ r8180_core.o \ - r8180_93cx6.o \ r8180_wx.o \ r8180_rtl8225z2.o \ r8185b_init.o \ diff --git a/drivers/staging/rtl8187se/TODO b/drivers/staging/rtl8187se/TODO index a762e79..704949a 100644 --- a/drivers/staging/rtl8187se/TODO +++ b/drivers/staging/rtl8187se/TODO @@ -5,7 +5,6 @@ TODO: - switch to use shared "librtl" instead of private ieee80211 stack - switch to use LIB80211 - switch to use MAC80211 -- switch to use EEPROM_93CX6 - use kernel coding style - checkpatch.pl fixes - sparse fixes diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211.h b/drivers/staging/rtl8187se/ieee80211/ieee80211.h index 9086047..4cd95c3 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211.h @@ -29,6 +29,7 @@ #include <linux/jiffies.h> #include <linux/timer.h> #include <linux/sched.h> +#include <linux/semaphore.h> #include <linux/wireless.h> #include <linux/ieee80211.h> @@ -161,10 +162,6 @@ do { if (ieee80211_debug_level & (level)) \ #define IEEE80211_DEBUG(level, fmt, args...) do {} while (0) #endif /* CONFIG_IEEE80211_DEBUG */ -#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x" -#define MAC_ARG(x) ((u8 *)(x))[0], ((u8 *)(x))[1], ((u8 *)(x))[2], \ - ((u8 *)(x))[3], ((u8 *)(x))[4], ((u8 *)(x))[5] - /* * To use the debug system; * diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c index 172e8f3..40f1b99 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c @@ -285,7 +285,7 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) if (!(keyidx & (1 << 5))) { if (net_ratelimit()) { printk(KERN_DEBUG "CCMP: received packet without ExtIV" - " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2)); + " flag from %pM\n", hdr->addr2); } key->dot11RSNAStatsCCMPFormatErrors++; return -2; @@ -298,9 +298,9 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) } if (!key->key_set) { if (net_ratelimit()) { - printk(KERN_DEBUG "CCMP: received packet from " MAC_FMT + printk(KERN_DEBUG "CCMP: received packet from %pM" " with keyid=%d that does not have a configured" - " key\n", MAC_ARG(hdr->addr2), keyidx); + " key\n", hdr->addr2, keyidx); } return -3; } @@ -315,11 +315,9 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) { if (net_ratelimit()) { - printk(KERN_DEBUG "CCMP: replay detected: STA=" MAC_FMT - " previous PN %02x%02x%02x%02x%02x%02x " - "received PN %02x%02x%02x%02x%02x%02x\n", - MAC_ARG(hdr->addr2), MAC_ARG(key->rx_pn), - MAC_ARG(pn)); + printk(KERN_DEBUG "CCMP: replay detected: STA=%pM" + " previous PN %pm received PN %pm\n", + hdr->addr2, key->rx_pn, pn); } key->dot11RSNAStatsCCMPReplays++; return -4; @@ -347,7 +345,7 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) if (memcmp(mic, a, CCMP_MIC_LEN) != 0) { if (net_ratelimit()) { printk(KERN_DEBUG "CCMP: decrypt failed: STA=" - MAC_FMT "\n", MAC_ARG(hdr->addr2)); + "%pM\n", hdr->addr2); } key->dot11RSNAStatsCCMPDecryptErrors++; return -5; @@ -423,11 +421,10 @@ static char * ieee80211_ccmp_print_stats(char *p, void *priv) { struct ieee80211_ccmp_data *ccmp = priv; p += sprintf(p, "key[%d] alg=CCMP key_set=%d " - "tx_pn=%02x%02x%02x%02x%02x%02x " - "rx_pn=%02x%02x%02x%02x%02x%02x " + "tx_pn=%pm rx_pn=%pm " "format_errors=%d replays=%d decrypt_errors=%d\n", ccmp->key_idx, ccmp->key_set, - MAC_ARG(ccmp->tx_pn), MAC_ARG(ccmp->rx_pn), + ccmp->tx_pn, ccmp->rx_pn, ccmp->dot11RSNAStatsCCMPFormatErrors, ccmp->dot11RSNAStatsCCMPReplays, ccmp->dot11RSNAStatsCCMPDecryptErrors); diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c index e6d8385..a525411 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c @@ -385,7 +385,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) if (!(keyidx & (1 << 5))) { if (net_ratelimit()) { printk(KERN_DEBUG "TKIP: received packet without ExtIV" - " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2)); + " flag from %pM\n", hdr->addr2); } return -2; } @@ -397,9 +397,9 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) } if (!tkey->key_set) { if (net_ratelimit()) { - printk(KERN_DEBUG "TKIP: received packet from " MAC_FMT + printk(KERN_DEBUG "TKIP: received packet from %pM" " with keyid=%d that does not have a configured" - " key\n", MAC_ARG(hdr->addr2), keyidx); + " key\n", hdr->addr2, keyidx); } return -3; } @@ -410,9 +410,9 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) if (iv32 < tkey->rx_iv32 || (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) { if (net_ratelimit()) { - printk(KERN_DEBUG "TKIP: replay detected: STA=" MAC_FMT + printk(KERN_DEBUG "TKIP: replay detected: STA=%pM" " previous TSC %08x%04x received TSC " - "%08x%04x\n", MAC_ARG(hdr->addr2), + "%08x%04x\n", hdr->addr2, tkey->rx_iv32, tkey->rx_iv16, iv32, iv16); } tkey->dot11RSNAStatsTKIPReplays++; @@ -431,8 +431,8 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) { if (net_ratelimit()) { printk(KERN_DEBUG ": TKIP: failed to decrypt " - "received packet from " MAC_FMT "\n", - MAC_ARG(hdr->addr2)); + "received packet from %pM\n", + hdr->addr2); } return -7; } @@ -450,7 +450,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) } if (net_ratelimit()) { printk(KERN_DEBUG "TKIP: ICV error detected: STA=" - MAC_FMT "\n", MAC_ARG(hdr->addr2)); + "%pM\n", hdr->addr2); } tkey->dot11RSNAStatsTKIPICVErrors++; return -5; @@ -604,8 +604,8 @@ static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx, struct ieee80211_hdr_4addr *hdr; hdr = (struct ieee80211_hdr_4addr *)skb->data; printk(KERN_DEBUG "%s: Michael MIC verification failed for " - "MSDU from " MAC_FMT " keyidx=%d\n", - skb->dev ? skb->dev->name : "N/A", MAC_ARG(hdr->addr2), + "MSDU from %pM keyidx=%d\n", + skb->dev ? skb->dev->name : "N/A", hdr->addr2, keyidx); if (skb->dev) ieee80211_michael_mic_failure(skb->dev, hdr, keyidx); diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c index 9128c18..2b7080c 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c @@ -311,8 +311,8 @@ ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb, strcmp(crypt->ops->name, "TKIP") == 0) { if (net_ratelimit()) { printk(KERN_DEBUG "%s: TKIP countermeasures: dropped " - "received packet from " MAC_FMT "\n", - ieee->dev->name, MAC_ARG(hdr->addr2)); + "received packet from %pM\n", + ieee->dev->name, hdr->addr2); } return -1; } @@ -323,8 +323,8 @@ ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb, atomic_dec(&crypt->refcnt); if (res < 0) { IEEE80211_DEBUG_DROP( - "decryption failed (SA=" MAC_FMT - ") res=%d\n", MAC_ARG(hdr->addr2), res); + "decryption failed (SA=%pM" + ") res=%d\n", hdr->addr2, res); if (res == -2) IEEE80211_DEBUG_DROP("Decryption failed ICV " "mismatch (key %d)\n", @@ -356,8 +356,8 @@ ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device* ieee, struct sk_buff *s atomic_dec(&crypt->refcnt); if (res < 0) { printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed" - " (SA=" MAC_FMT " keyidx=%d)\n", - ieee->dev->name, MAC_ARG(hdr->addr2), keyidx); + " (SA=%pM keyidx=%d)\n", + ieee->dev->name, hdr->addr2, keyidx); return -1; } @@ -550,8 +550,8 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, * frames silently instead of filling system log with * these reports. */ IEEE80211_DEBUG_DROP("Decryption failed (not set)" - " (SA=" MAC_FMT ")\n", - MAC_ARG(hdr->addr2)); + " (SA=%pM)\n", + hdr->addr2); ieee->ieee_stats.rx_discards_undecryptable++; goto rx_dropped; } @@ -709,8 +709,8 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, } else { IEEE80211_DEBUG_DROP( "encryption configured, but RX " - "frame not encrypted (SA=" MAC_FMT ")\n", - MAC_ARG(hdr->addr2)); + "frame not encrypted (SA=%pM)\n", + hdr->addr2); goto rx_dropped; } } @@ -729,9 +729,9 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, !ieee80211_is_eapol_frame(ieee, skb, hdrlen)) { IEEE80211_DEBUG_DROP( "dropped unencrypted RX data " - "frame from " MAC_FMT + "frame from %pM" " (drop_unencrypted=1)\n", - MAC_ARG(hdr->addr2)); + hdr->addr2); goto rx_dropped; } /* @@ -1196,11 +1196,11 @@ inline int ieee80211_network_init( } if (network->mode == 0) { - IEEE80211_DEBUG_SCAN("Filtered out '%s (" MAC_FMT ")' " + IEEE80211_DEBUG_SCAN("Filtered out '%s (%pM)' " "network.\n", escape_essid(network->ssid, network->ssid_len), - MAC_ARG(network->bssid)); + network->bssid); return 1; } @@ -1341,9 +1341,9 @@ inline void ieee80211_process_probe_response( memset(&network, 0, sizeof(struct ieee80211_network)); IEEE80211_DEBUG_SCAN( - "'%s' (" MAC_FMT "): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n", + "'%s' (%pM): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n", escape_essid(info_element->data, info_element->len), - MAC_ARG(beacon->header.addr3), + beacon->header.addr3, (beacon->capability & (1<<0xf)) ? '1' : '0', (beacon->capability & (1<<0xe)) ? '1' : '0', (beacon->capability & (1<<0xd)) ? '1' : '0', @@ -1362,10 +1362,10 @@ inline void ieee80211_process_probe_response( (beacon->capability & (1<<0x0)) ? '1' : '0'); if (ieee80211_network_init(ieee, beacon, &network, stats)) { - IEEE80211_DEBUG_SCAN("Dropped '%s' (" MAC_FMT ") via %s.\n", + IEEE80211_DEBUG_SCAN("Dropped '%s' (%pM) via %s.\n", escape_essid(info_element->data, info_element->len), - MAC_ARG(beacon->header.addr3), + beacon->header.addr3, WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_PROBE_RESP ? "PROBE RESPONSE" : "BEACON"); @@ -1464,11 +1464,11 @@ inline void ieee80211_process_probe_response( /* If there are no more slots, expire the oldest */ list_del(&oldest->list); target = oldest; - IEEE80211_DEBUG_SCAN("Expired '%s' (" MAC_FMT ") from " + IEEE80211_DEBUG_SCAN("Expired '%s' (%pM) from " "network list.\n", escape_essid(target->ssid, target->ssid_len), - MAC_ARG(target->bssid)); + target->bssid); } else { /* Otherwise just pull from the free list */ target = list_entry(ieee->network_free_list.next, @@ -1478,10 +1478,10 @@ inline void ieee80211_process_probe_response( #ifdef CONFIG_IEEE80211_DEBUG - IEEE80211_DEBUG_SCAN("Adding '%s' (" MAC_FMT ") via %s.\n", + IEEE80211_DEBUG_SCAN("Adding '%s' (%pM) via %s.\n", escape_essid(network.ssid, network.ssid_len), - MAC_ARG(network.bssid), + network.bssid, WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_PROBE_RESP ? "PROBE RESPONSE" : "BEACON"); @@ -1492,10 +1492,10 @@ inline void ieee80211_process_probe_response( if(ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) ieee80211_softmac_new_net(ieee,&network); } else { - IEEE80211_DEBUG_SCAN("Updating '%s' (" MAC_FMT ") via %s.\n", + IEEE80211_DEBUG_SCAN("Updating '%s' (%pM) via %s.\n", escape_essid(target->ssid, target->ssid_len), - MAC_ARG(target->bssid), + target->bssid, WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_PROBE_RESP ? "PROBE RESPONSE" : "BEACON"); diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c index a215067..c2f472e 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c @@ -1573,7 +1573,7 @@ ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb) ieee80211_resp_to_assoc_rq(ieee, dest); } - printk(KERN_INFO"New client associated: "MAC_FMT"\n", MAC_ARG(dest)); + printk(KERN_INFO"New client associated: %pM\n", dest); } diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c index f1d6cb4..ad42bcd 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c @@ -482,8 +482,7 @@ int ieee80211_wx_set_power(struct ieee80211_device *ieee, (!ieee->enter_sleep_state) || (!ieee->ps_is_queue_empty)){ - printk("ERROR. PS mode is tryied to be use but\ -driver missed a callback\n\n"); + printk("ERROR. PS mode tried to be use but driver missed a callback\n\n"); return -1; } diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c index 69bd021..6cb31e1 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c @@ -198,8 +198,8 @@ int ieee80211_encrypt_fragment( header = (struct ieee80211_hdr_4addr *)frag->data; if (net_ratelimit()) { printk(KERN_DEBUG "%s: TKIP countermeasures: dropped " - "TX packet to " MAC_FMT "\n", - ieee->dev->name, MAC_ARG(header->addr1)); + "TX packet to %pM\n", + ieee->dev->name, header->addr1); } return -1; } @@ -407,7 +407,7 @@ int ieee80211_rtl_xmit(struct sk_buff *skb, memcpy(&header.addr2, src, ETH_ALEN); memcpy(&header.addr3, ieee->current_network.bssid, ETH_ALEN); } - // printk(KERN_WARNING "essid MAC address is "MAC_FMT, MAC_ARG(&header.addr1)); + // printk(KERN_WARNING "essid MAC address is %pM", &header.addr1); header.frame_ctl = cpu_to_le16(fc); //hdr_len = IEEE80211_3ADDR_LEN; diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c index 6aad48f..bd5e77b 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c @@ -234,10 +234,10 @@ int ieee80211_wx_get_scan(struct ieee80211_device *ieee, else IEEE80211_DEBUG_SCAN( "Not showing network '%s (" - MAC_FMT ")' due to age (%lums).\n", + "%pM)' due to age (%lums).\n", escape_essid(network->ssid, network->ssid_len), - MAC_ARG(network->bssid), + network->bssid, (jiffies - network->last_scanned) / (HZ / 100)); } } @@ -694,7 +694,7 @@ int ieee80211_wx_set_auth(struct ieee80211_device *ieee, #if 1 case IW_AUTH_WPA_ENABLED: ieee->wpa_enabled = (data->value)?1:0; - //printk("enalbe wpa:%d\n", ieee->wpa_enabled); + //printk("enable wpa:%d\n", ieee->wpa_enabled); break; #endif diff --git a/drivers/staging/rtl8187se/r8180.h b/drivers/staging/rtl8187se/r8180.h index ce82888..d15bdf6 100644 --- a/drivers/staging/rtl8187se/r8180.h +++ b/drivers/staging/rtl8187se/r8180.h @@ -366,7 +366,6 @@ typedef struct r8180_priv short diversity; u8 cs_treshold; short rcr_csense; - short rf_chip; u32 key0[4]; short (*rf_set_sens)(struct net_device *dev,short sens); void (*rf_set_chan)(struct net_device *dev,short ch); @@ -479,9 +478,6 @@ typedef struct r8180_priv u8 retry_rts; u16 rts; -//add for RF power on power off by lizhaoming 080512 - u8 RegThreeWireMode; // See "Three wire mode" defined above, 2006.05.31, by rcnjko. - //by amy for led LED_STRATEGY_8185 LedStrategy; //by amy for led diff --git a/drivers/staging/rtl8187se/r8180_93cx6.c b/drivers/staging/rtl8187se/r8180_93cx6.c deleted file mode 100644 index 7e4711f..0000000 --- a/drivers/staging/rtl8187se/r8180_93cx6.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - This files contains card eeprom (93c46 or 93c56) programming routines, - memory is addressed by 16 bits words. - - This is part of rtl8180 OpenSource driver. - Copyright (C) Andrea Merello 2004 <andreamrl@tiscali.it> - Released under the terms of GPL (General Public Licence) - - Parts of this driver are based on the GPL part of the - official realtek driver. - - Parts of this driver are based on the rtl8180 driver skeleton - from Patric Schenke & Andres Salomon. - - Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver. - - We want to tanks the Authors of those projects and the Ndiswrapper - project Authors. -*/ - -#include "r8180_93cx6.h" - -void eprom_cs(struct net_device *dev, short bit) -{ - if(bit) - write_nic_byte(dev, EPROM_CMD, - (1<<EPROM_CS_SHIFT) | \ - read_nic_byte(dev, EPROM_CMD)); //enable EPROM - else - write_nic_byte(dev, EPROM_CMD, read_nic_byte(dev, EPROM_CMD)\ - &~(1<<EPROM_CS_SHIFT)); //disable EPROM - - force_pci_posting(dev); - udelay(EPROM_DELAY); -} - - -void eprom_ck_cycle(struct net_device *dev) -{ - write_nic_byte(dev, EPROM_CMD, - (1<<EPROM_CK_SHIFT) | read_nic_byte(dev,EPROM_CMD)); - force_pci_posting(dev); - udelay(EPROM_DELAY); - write_nic_byte(dev, EPROM_CMD, - read_nic_byte(dev, EPROM_CMD) &~ (1<<EPROM_CK_SHIFT)); - force_pci_posting(dev); - udelay(EPROM_DELAY); -} - - -void eprom_w(struct net_device *dev,short bit) -{ - if(bit) - write_nic_byte(dev, EPROM_CMD, (1<<EPROM_W_SHIFT) | \ - read_nic_byte(dev,EPROM_CMD)); - else - write_nic_byte(dev, EPROM_CMD, read_nic_byte(dev,EPROM_CMD)\ - &~(1<<EPROM_W_SHIFT)); - - force_pci_posting(dev); - udelay(EPROM_DELAY); -} - - -short eprom_r(struct net_device *dev) -{ - short bit; - - bit=(read_nic_byte(dev, EPROM_CMD) & (1<<EPROM_R_SHIFT) ); - udelay(EPROM_DELAY); - - if(bit) return 1; - return 0; -} - - -void eprom_send_bits_string(struct net_device *dev, short b[], int len) -{ - int i; - - for(i=0; i<len; i++){ - eprom_w(dev, b[i]); - eprom_ck_cycle(dev); - } -} - - -u32 eprom_read(struct net_device *dev, u32 addr) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - short read_cmd[]={1,1,0}; - short addr_str[8]; - int i; - int addr_len; - u32 ret; - - ret=0; - //enable EPROM programming - write_nic_byte(dev, EPROM_CMD, - (EPROM_CMD_PROGRAM<<EPROM_CMD_OPERATING_MODE_SHIFT)); - force_pci_posting(dev); - udelay(EPROM_DELAY); - - if (priv->epromtype==EPROM_93c56){ - addr_str[7]=addr & 1; - addr_str[6]=addr & (1<<1); - addr_str[5]=addr & (1<<2); - addr_str[4]=addr & (1<<3); - addr_str[3]=addr & (1<<4); - addr_str[2]=addr & (1<<5); - addr_str[1]=addr & (1<<6); - addr_str[0]=addr & (1<<7); - addr_len=8; - }else{ - addr_str[5]=addr & 1; - addr_str[4]=addr & (1<<1); - addr_str[3]=addr & (1<<2); - addr_str[2]=addr & (1<<3); - addr_str[1]=addr & (1<<4); - addr_str[0]=addr & (1<<5); - addr_len=6; - } - eprom_cs(dev, 1); - eprom_ck_cycle(dev); - eprom_send_bits_string(dev, read_cmd, 3); - eprom_send_bits_string(dev, addr_str, addr_len); - - //keep chip pin D to low state while reading. - //I'm unsure if it is necessary, but anyway shouldn't hurt - eprom_w(dev, 0); - - for(i=0;i<16;i++){ - //eeprom needs a clk cycle between writing opcode&adr - //and reading data. (eeprom outs a dummy 0) - eprom_ck_cycle(dev); - ret |= (eprom_r(dev)<<(15-i)); - } - - eprom_cs(dev, 0); - eprom_ck_cycle(dev); - - //disable EPROM programming - write_nic_byte(dev, EPROM_CMD, - (EPROM_CMD_NORMAL<<EPROM_CMD_OPERATING_MODE_SHIFT)); - return ret; -} diff --git a/drivers/staging/rtl8187se/r8180_93cx6.h b/drivers/staging/rtl8187se/r8180_93cx6.h index 36ae100..79e7391 100644 --- a/drivers/staging/rtl8187se/r8180_93cx6.h +++ b/drivers/staging/rtl8187se/r8180_93cx6.h @@ -45,13 +45,10 @@ #define EPROM_TXPW_OFDM_CH1_2 0x20 -//#define EPROM_TXPW_CH1_2 0x10 -#define EPROM_TXPW_CH1_2 0x30 -#define EPROM_TXPW_CH3_4 0x11 -#define EPROM_TXPW_CH5_6 0x12 -#define EPROM_TXPW_CH7_8 0x13 -#define EPROM_TXPW_CH9_10 0x14 -#define EPROM_TXPW_CH11_12 0x15 -#define EPROM_TXPW_CH13_14 0x16 - -u32 eprom_read(struct net_device *dev,u32 addr); //reads a 16 bits word +#define EPROM_TXPW_CH1_2 0x30 + +#define RTL818X_EEPROM_CMD_READ (1 << 0) +#define RTL818X_EEPROM_CMD_WRITE (1 << 1) +#define RTL818X_EEPROM_CMD_CK (1 << 2) +#define RTL818X_EEPROM_CMD_CS (1 << 3) + diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c index 1847f38..b1757ac 100644 --- a/drivers/staging/rtl8187se/r8180_core.c +++ b/drivers/staging/rtl8187se/r8180_core.c @@ -31,6 +31,7 @@ #undef DUMMY_RX #include <linux/syscalls.h> +#include <linux/eeprom_93cx6.h> #include "r8180_hw.h" #include "r8180.h" @@ -41,13 +42,6 @@ #include "ieee80211/dot11d.h" -#ifndef PCI_VENDOR_ID_BELKIN - #define PCI_VENDOR_ID_BELKIN 0x1799 -#endif -#ifndef PCI_VENDOR_ID_DLINK - #define PCI_VENDOR_ID_DLINK 0x1186 -#endif - static struct pci_device_id rtl8180_pci_id_tbl[] __devinitdata = { { .vendor = PCI_VENDOR_ID_REALTEK, @@ -669,11 +663,8 @@ unsigned char STRENGTH_MAP[] = { void rtl8180_RSSI_calc(struct net_device *dev, u8 *rssi, u8 *qual) { - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); u32 temp; u32 temp2; - u32 temp3; - u32 lsb; u32 q; u32 orig_qual; u8 _rssi; @@ -695,88 +686,6 @@ void rtl8180_RSSI_calc(struct net_device *dev, u8 *rssi, u8 *qual) *qual = temp; temp2 = *rssi; - switch(priv->rf_chip){ - case RFCHIPID_RFMD: - lsb = temp2 & 1; - temp2 &= 0x7e; - if ( !lsb || !(temp2 <= 0x3c) ) { - temp2 = 0x64; - } else { - temp2 = 100 * temp2 / 0x3c; - } - *rssi = temp2 & 0xff; - _rssi = temp2 & 0xff; - break; - case RFCHIPID_INTERSIL: - lsb = temp2; - temp2 &= 0xfffffffe; - temp2 *= 251; - temp3 = temp2; - temp2 <<= 6; - temp3 += temp2; - temp3 <<= 1; - temp2 = 0x4950df; - temp2 -= temp3; - lsb &= 1; - if ( temp2 <= 0x3e0000 ) { - if ( temp2 < 0xffef0000 ) - temp2 = 0xffef0000; - } else { - temp2 = 0x3e0000; - } - if ( !lsb ) { - temp2 -= 0xf0000; - } else { - temp2 += 0xf0000; - } - - temp3 = 0x4d0000; - temp3 -= temp2; - temp3 *= 100; - temp3 = temp3 / 0x6d; - temp3 >>= 0x10; - _rssi = temp3 & 0xff; - *rssi = temp3 & 0xff; - break; - case RFCHIPID_GCT: - lsb = temp2 & 1; - temp2 &= 0x7e; - if ( ! lsb || !(temp2 <= 0x3c) ){ - temp2 = 0x64; - } else { - temp2 = (100 * temp2) / 0x3c; - } - *rssi = temp2 & 0xff; - _rssi = temp2 & 0xff; - break; - case RFCHIPID_PHILIPS: - if( orig_qual <= 0x4e ){ - _rssi = STRENGTH_MAP[orig_qual]; - *rssi = _rssi; - } else { - orig_qual -= 0x80; - if ( !orig_qual ){ - _rssi = 1; - *rssi = 1; - } else { - _rssi = 0x32; - *rssi = 0x32; - } - } - break; - case RFCHIPID_MAXIM: - lsb = temp2 & 1; - temp2 &= 0x7e; - temp2 >>= 1; - temp2 += 0x42; - if( lsb != 0 ){ - temp2 += 0xa; - } - *rssi = temp2 & 0xff; - _rssi = temp2 & 0xff; - break; - } - if ( _rssi < 0x64 ){ if ( _rssi == 0 ) { *rssi = 1; @@ -1421,11 +1330,9 @@ u16 N_DBPSOfRate(u16 DataRate) return N_DBPS; } -//{by amy 080312 // // Description: // For Netgear case, they want good-looking singal strength. -// 2004.12.05, by rcnjko. // long NetgearSignalStrengthTranslate(long LastSS, long CurrSS) { @@ -1481,7 +1388,6 @@ long TranslateToDbm8185(u8 SignalStrengthIndex) // This is different with PerformSignalSmoothing8185 in smoothing fomula. // No dramatic adjustion is apply because dynamic mechanism need some degree // of correctness. Ported from 8187B. -// 2007-02-26, by Bruce. // void PerformUndecoratedSignalSmoothing8185(struct r8180_priv *priv, bool bCckRate) @@ -1502,7 +1408,6 @@ void PerformUndecoratedSignalSmoothing8185(struct r8180_priv *priv, priv->CurCCKRSSI = 0; } -//by amy 080312} /* This is rough RX isr handling routine*/ void rtl8180_rx(struct net_device *dev) @@ -1638,7 +1543,7 @@ void rtl8180_rx(struct net_device *dev) } signal=(unsigned char)(((*(priv->rxringtail+3))& (0x00ff0000))>>16); - signal=(signal&0xfe)>>1; // Modify by hikaru 6.6 + signal = (signal & 0xfe) >> 1; quality=(unsigned char)((*(priv->rxringtail+3)) & (0xff)); @@ -1652,7 +1557,6 @@ void rtl8180_rx(struct net_device *dev) stats.rate = rtl8180_rate2rate(rate); Antenna = (((*(priv->rxringtail +3))& (0x00008000)) == 0 )? 0:1 ; -//by amy for antenna if(!rtl8180_IsWirelessBMode(stats.rate)) { // OFDM rate. @@ -1691,11 +1595,10 @@ void rtl8180_rx(struct net_device *dev) RXAGC=(95-RXAGC)*100/65; } priv->SignalStrength = (u8)RXAGC; - priv->RecvSignalPower = RxAGC_dBm ; // It can use directly by SD3 CMLin + priv->RecvSignalPower = RxAGC_dBm; priv->RxPower = rxpower; priv->RSSI = RSSI; -//{by amy 080312 - // SQ translation formular is provided by SD3 DZ. 2006.06.27, by rcnjko. + /* SQ translation formula is provided by SD3 DZ. 2006.06.27 */ if(quality >= 127) quality = 1;//0; //0 will cause epc to show signal zero , walk aroud now; else if(quality < 27) @@ -1712,7 +1615,6 @@ void rtl8180_rx(struct net_device *dev) // printk("==========================>rx : RXAGC is %d,signalstrength is %d\n",RXAGC,stats.signalstrength); stats.rssi = priv->wstats.qual.qual = priv->SignalQuality; stats.noise = priv->wstats.qual.noise = 100 - priv ->wstats.qual.qual; -//by amy 080312} bHwError = (((*(priv->rxringtail))& (0x00000fff)) == 4080)| (((*(priv->rxringtail))& (0x04000000)) != 0 ) | (((*(priv->rxringtail))& (0x08000000)) != 0 )| (((~(*(priv->rxringtail)))& (0x10000000)) != 0 )| (((~(*(priv->rxringtail)))& (0x20000000)) != 0 ); bCRC = ((*(priv->rxringtail)) & (0x00002000)) >> 13; @@ -1725,11 +1627,12 @@ void rtl8180_rx(struct net_device *dev) (eqMacAddr(priv->ieee80211->current_network.bssid, (fc & IEEE80211_FCTL_TODS)? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS )? hdr->addr2 : hdr->addr3)) && (!bHwError) && (!bCRC)&& (!bICV)) { -//by amy 080312 - // Perform signal smoothing for dynamic mechanism on demand. - // This is different with PerformSignalSmoothing8185 in smoothing fomula. - // No dramatic adjustion is apply because dynamic mechanism need some degree - // of correctness. 2007.01.23, by shien chang. + /* Perform signal smoothing for dynamic + * mechanism on demand. This is different + * with PerformSignalSmoothing8185 in smoothing + * fomula. No dramatic adjustion is apply + * because dynamic mechanism need some degree + * of correctness. */ PerformUndecoratedSignalSmoothing8185(priv,bCckRate); // // For good-looking singal strength. @@ -1749,12 +1652,9 @@ void rtl8180_rx(struct net_device *dev) // Figure out which antenna that received the lasted packet. priv->LastRxPktAntenna = Antenna ? 1 : 0; // 0: aux, 1: main. -//by amy 080312 SwAntennaDiversityRxOk8185(dev, priv->SignalStrength); } -//by amy for antenna -#ifndef DUMMY_RX if(first){ if(!priv->rx_skb_complete){ /* seems that HW sometimes fails to reiceve and @@ -1810,19 +1710,12 @@ void rtl8180_rx(struct net_device *dev) if(last && !priv->rx_skb_complete){ if(priv->rx_skb->len > 4) skb_trim(priv->rx_skb,priv->rx_skb->len-4); -#ifndef RX_DONT_PASS_UL if(!ieee80211_rtl_rx(priv->ieee80211, - priv->rx_skb, &stats)){ -#endif // RX_DONT_PASS_UL - + priv->rx_skb, &stats)) dev_kfree_skb_any(priv->rx_skb); -#ifndef RX_DONT_PASS_UL - } -#endif priv->rx_skb_complete=1; } -#endif //DUMMY_RX pci_dma_sync_single_for_device(priv->pdev, priv->rxbuffer->dma, priv->rxbuffersize * \ @@ -2056,7 +1949,7 @@ short rtl8180_tx(struct net_device *dev, u8* txbuf, int len, int priority, u16 RtsDur = 0; u16 ThisFrameTime = 0; u16 TxDescDuration = 0; - u8 ownbit_flag = false; //added by david woo for sync Tx, 2007.12.14 + u8 ownbit_flag = false; switch(priority) { case MANAGE_PRIORITY: @@ -2123,7 +2016,8 @@ short rtl8180_tx(struct net_device *dev, u8* txbuf, int len, int priority, //YJ,add,080828,for Keep alive priv->NumTxUnicast++; - // Figure out ACK rate according to BSS basic rate and Tx rate, 2006.03.08 by rcnjko. + /* Figure out ACK rate according to BSS basic rate + * and Tx rate. */ AckTime = ComputeTxTime(14, 10,0, 0); // AckCTSLng = 14 use 1M bps send if ( ((len + sCrcLng) > priv->rts) && priv->rts ) @@ -2206,7 +2100,7 @@ short rtl8180_tx(struct net_device *dev, u8* txbuf, int len, int priority, *tail |= (1<<15); /* no encrypt */ if(remain==len && !descfrag) { - ownbit_flag = false; //added by david woo,2007.12.14 + ownbit_flag = false; *tail = *tail| (1<<29) ; //fist segment of the packet *tail = *tail |(len); } else { @@ -2556,27 +2450,16 @@ void watch_dog_adaptive(unsigned long data) } // Tx High Power Mechanism. -#ifdef HIGH_POWER if(CheckHighPower((struct net_device *)data)) - { queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->tx_pw_wq); - } -#endif // Tx Power Tracking on 87SE. -#ifdef TX_TRACK - //if( priv->bTxPowerTrack ) //lzm mod 080826 - if( CheckTxPwrTracking((struct net_device *)data)); + if (CheckTxPwrTracking((struct net_device *)data)) TxPwrTracking87SE((struct net_device *)data); -#endif // Perform DIG immediately. -#ifdef SW_DIG if(CheckDig((struct net_device *)data) == true) - { queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->hw_dig_wq); - } -#endif rtl8180_watch_dog((struct net_device *)data); queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->GPIOChangeRFWorkItem); @@ -2675,6 +2558,36 @@ static void rtl8180_link_detect_init(plink_detect_t plink_detect) } //YJ,add,080828,end +static void rtl8187se_eeprom_register_read(struct eeprom_93cx6 *eeprom) +{ + struct net_device *dev = eeprom->data; + u8 reg = read_nic_byte(dev, EPROM_CMD); + + eeprom->reg_data_in = reg & RTL818X_EEPROM_CMD_WRITE; + eeprom->reg_data_out = reg & RTL818X_EEPROM_CMD_READ; + eeprom->reg_data_clock = reg & RTL818X_EEPROM_CMD_CK; + eeprom->reg_chip_select = reg & RTL818X_EEPROM_CMD_CS; +} + +static void rtl8187se_eeprom_register_write(struct eeprom_93cx6 *eeprom) +{ + struct net_device *dev = eeprom->data; + u8 reg = 2 << 6; + + if (eeprom->reg_data_in) + reg |= RTL818X_EEPROM_CMD_WRITE; + if (eeprom->reg_data_out) + reg |= RTL818X_EEPROM_CMD_READ; + if (eeprom->reg_data_clock) + reg |= RTL818X_EEPROM_CMD_CK; + if (eeprom->reg_chip_select) + reg |= RTL818X_EEPROM_CMD_CS; + + write_nic_byte(dev, EPROM_CMD, reg); + read_nic_byte(dev, EPROM_CMD); + udelay(10); +} + short rtl8180_init(struct net_device *dev) { struct r8180_priv *priv = ieee80211_priv(dev); @@ -2683,8 +2596,16 @@ short rtl8180_init(struct net_device *dev) u32 usValue; u16 tmpu16; int i, j; + struct eeprom_93cx6 eeprom; + u16 eeprom_val; + + eeprom.data = dev; + eeprom.register_read = rtl8187se_eeprom_register_read; + eeprom.register_write = rtl8187se_eeprom_register_write; + eeprom.width = PCI_EEPROM_WIDTH_93C46; - priv->channel_plan = eprom_read(dev, EEPROM_COUNTRY_CODE>>1) & 0xFF; + eeprom_93cx6_read(&eeprom, EEPROM_COUNTRY_CODE>>1, &eeprom_val); + priv->channel_plan = eeprom_val & 0xFF; if(priv->channel_plan > COUNTRY_CODE_GLOBAL_DOMAIN){ printk("rtl8180_init:Error channel plan! Set to default.\n"); priv->channel_plan = 0; @@ -2701,8 +2622,6 @@ short rtl8180_init(struct net_device *dev) priv->txbeaconcount = 2; priv->rx_skb_complete = 1; - priv->RegThreeWireMode = HW_THREE_WIRE_SI; - priv->RFChangeInProgress = false; priv->SetRFPowerStateInProgress = false; priv->RFProgType = 0; @@ -2747,10 +2666,8 @@ short rtl8180_init(struct net_device *dev) priv->TxPollingTimes = 0;//lzm add 080826 priv->bLeisurePs = true; priv->dot11PowerSaveMode = eActive; -//by amy for antenna priv->AdMinCheckPeriod = 5; priv->AdMaxCheckPeriod = 10; -// Lower signal strength threshold to fit the HW participation in antenna diversity. +by amy 080312 priv->AdMaxRxSsThreshold = 30;//60->30 priv->AdRxSsThreshold = 20;//50->20 priv->AdCheckPeriod = priv->AdMinCheckPeriod; @@ -2765,8 +2682,6 @@ short rtl8180_init(struct net_device *dev) init_timer(&priv->SwAntennaDiversityTimer); priv->SwAntennaDiversityTimer.data = (unsigned long)dev; priv->SwAntennaDiversityTimer.function = (void *)SwAntennaDiversityTimerCallback; -//by amy for antenna -//{by amy 080312 priv->bDigMechanism = 1; priv->InitialGain = 6; priv->bXtalCalibration = false; @@ -2803,58 +2718,63 @@ short rtl8180_init(struct net_device *dev) priv->NumTxUnicast = 0; priv->keepAliveLevel = DEFAULT_KEEP_ALIVE_LEVEL; priv->PowerProfile = POWER_PROFILE_AC; - priv->CurrRetryCnt=0; - priv->LastRetryCnt=0; - priv->LastTxokCnt=0; - priv->LastRxokCnt=0; - priv->LastRetryRate=0; - priv->bTryuping=0; - priv->CurrTxRate=0; - priv->CurrRetryRate=0; - priv->TryupingCount=0; - priv->TryupingCountNoData=0; - priv->TryDownCountLowData=0; - priv->LastTxOKBytes=0; - priv->LastFailTxRate=0; - priv->LastFailTxRateSS=0; - priv->FailTxRateCount=0; - priv->LastTxThroughput=0; - priv->NumTxOkBytesTotal=0; + priv->CurrRetryCnt = 0; + priv->LastRetryCnt = 0; + priv->LastTxokCnt = 0; + priv->LastRxokCnt = 0; + priv->LastRetryRate = 0; + priv->bTryuping = 0; + priv->CurrTxRate = 0; + priv->CurrRetryRate = 0; + priv->TryupingCount = 0; + priv->TryupingCountNoData = 0; + priv->TryDownCountLowData = 0; + priv->LastTxOKBytes = 0; + priv->LastFailTxRate = 0; + priv->LastFailTxRateSS = 0; + priv->FailTxRateCount = 0; + priv->LastTxThroughput = 0; + priv->NumTxOkBytesTotal = 0; priv->ForcedDataRate = 0; priv->RegBModeGainStage = 1; - priv->promisc = (dev->flags & IFF_PROMISC) ? 1:0; + priv->promisc = (dev->flags & IFF_PROMISC) ? 1 : 0; spin_lock_init(&priv->irq_lock); spin_lock_init(&priv->irq_th_lock); spin_lock_init(&priv->tx_lock); spin_lock_init(&priv->ps_lock); spin_lock_init(&priv->rf_ps_lock); - sema_init(&priv->wx_sem,1); - sema_init(&priv->rf_state,1); - INIT_WORK(&priv->reset_wq,(void*) rtl8180_restart_wq); - INIT_WORK(&priv->tx_irq_wq,(void*) rtl8180_tx_irq_wq); - INIT_DELAYED_WORK(&priv->ieee80211->hw_wakeup_wq,(void*) rtl8180_hw_wakeup_wq); - INIT_DELAYED_WORK(&priv->ieee80211->hw_sleep_wq,(void*) rtl8180_hw_sleep_wq); - INIT_WORK(&priv->ieee80211->wmm_param_update_wq,(void*) rtl8180_wmm_param_update); - INIT_DELAYED_WORK(&priv->ieee80211->rate_adapter_wq,(void*)rtl8180_rate_adapter);//+by amy 080312 - INIT_DELAYED_WORK(&priv->ieee80211->hw_dig_wq,(void*)rtl8180_hw_dig_wq);//+by amy 080312 - INIT_DELAYED_WORK(&priv->ieee80211->tx_pw_wq,(void*)rtl8180_tx_pw_wq);//+by amy 080312 - - INIT_DELAYED_WORK(&priv->ieee80211->GPIOChangeRFWorkItem,(void*) GPIOChangeRFWorkItemCallBack); - + sema_init(&priv->wx_sem, 1); + sema_init(&priv->rf_state, 1); + INIT_WORK(&priv->reset_wq, (void *)rtl8180_restart_wq); + INIT_WORK(&priv->tx_irq_wq, (void *)rtl8180_tx_irq_wq); + INIT_DELAYED_WORK(&priv->ieee80211->hw_wakeup_wq, + (void *)rtl8180_hw_wakeup_wq); + INIT_DELAYED_WORK(&priv->ieee80211->hw_sleep_wq, + (void *)rtl8180_hw_sleep_wq); + INIT_WORK(&priv->ieee80211->wmm_param_update_wq, + (void *)rtl8180_wmm_param_update); + INIT_DELAYED_WORK(&priv->ieee80211->rate_adapter_wq, + (void *)rtl8180_rate_adapter); + INIT_DELAYED_WORK(&priv->ieee80211->hw_dig_wq, + (void *)rtl8180_hw_dig_wq); + INIT_DELAYED_WORK(&priv->ieee80211->tx_pw_wq, + (void *)rtl8180_tx_pw_wq); + INIT_DELAYED_WORK(&priv->ieee80211->GPIOChangeRFWorkItem, + (void *) GPIOChangeRFWorkItemCallBack); tasklet_init(&priv->irq_rx_tasklet, (void(*)(unsigned long)) rtl8180_irq_rx_tasklet, (unsigned long)priv); - init_timer(&priv->watch_dog_timer); + init_timer(&priv->watch_dog_timer); priv->watch_dog_timer.data = (unsigned long)dev; priv->watch_dog_timer.function = watch_dog_adaptive; - init_timer(&priv->rateadapter_timer); - priv->rateadapter_timer.data = (unsigned long)dev; - priv->rateadapter_timer.function = timer_rate_adaptive; - priv->RateAdaptivePeriod= RATE_ADAPTIVE_TIMER_PERIOD; - priv->bEnhanceTxPwr=false; + init_timer(&priv->rateadapter_timer); + priv->rateadapter_timer.data = (unsigned long)dev; + priv->rateadapter_timer.function = timer_rate_adaptive; + priv->RateAdaptivePeriod = RATE_ADAPTIVE_TIMER_PERIOD; + priv->bEnhanceTxPwr = false; priv->ieee80211->softmac_hard_start_xmit = rtl8180_hard_start_xmit; priv->ieee80211->set_chan = rtl8180_set_chan; @@ -2877,30 +2797,28 @@ short rtl8180_init(struct net_device *dev) priv->CSMethod = (0x01 << 29); - priv->TransmitConfig = - 1<<TCR_DurProcMode_OFFSET | //for RTL8185B, duration setting by HW - (7<<TCR_MXDMA_OFFSET) | // Max DMA Burst Size per Tx DMA Burst, 7: reservied. - (priv->ShortRetryLimit<<TCR_SRL_OFFSET) | // Short retry limit - (priv->LongRetryLimit<<TCR_LRL_OFFSET) | // Long retry limit - (0 ? TCR_SAT : 0); // FALSE: HW provies PLCP length and LENGEXT, TURE: SW proiveds them - - priv->ReceiveConfig = - RCR_AMF | RCR_ADF | //accept management/data - RCR_ACF | //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko. - RCR_AB | RCR_AM | RCR_APM | //accept BC/MC/UC - (7<<RCR_MXDMA_OFFSET) | // Max DMA Burst Size per Rx DMA Burst, 7: unlimited. - (priv->EarlyRxThreshold<<RCR_FIFO_OFFSET) | // Rx FIFO Threshold, 7: No Rx threshold. - (priv->EarlyRxThreshold == 7 ? RCR_ONLYERLPKT:0); + priv->TransmitConfig = TCR_DurProcMode_OFFSET | + (7<<TCR_MXDMA_OFFSET) | + (priv->ShortRetryLimit<<TCR_SRL_OFFSET) | + (priv->LongRetryLimit<<TCR_LRL_OFFSET) | + (0 ? TCR_SAT : 0); + + priv->ReceiveConfig = RCR_AMF | RCR_ADF | RCR_ACF | + RCR_AB | RCR_AM | RCR_APM | + (7<<RCR_MXDMA_OFFSET) | + (priv->EarlyRxThreshold<<RCR_FIFO_OFFSET) | + (priv->EarlyRxThreshold == 7 ? + RCR_ONLYERLPKT : 0); priv->IntrMask = IMR_TMGDOK | IMR_TBDER | IMR_THPDER | - IMR_THPDER | IMR_THPDOK | - IMR_TVODER | IMR_TVODOK | - IMR_TVIDER | IMR_TVIDOK | - IMR_TBEDER | IMR_TBEDOK | - IMR_TBKDER | IMR_TBKDOK | - IMR_RDU | // To handle the defragmentation not enough Rx descriptors case. Annie, 2006-03-27. - IMR_RER | IMR_ROK | - IMR_RQoSOK; // <NOTE> ROK and RQoSOK are mutually exclusive, so, we must handle RQoSOK interrupt to receive QoS frames, 2005.12.09, by rcnjko. + IMR_THPDER | IMR_THPDOK | + IMR_TVODER | IMR_TVODOK | + IMR_TVIDER | IMR_TVIDOK | + IMR_TBEDER | IMR_TBEDOK | + IMR_TBKDER | IMR_TBKDOK | + IMR_RDU | + IMR_RER | IMR_ROK | + IMR_RQoSOK; priv->InitialGain = 6; @@ -2913,7 +2831,8 @@ short rtl8180_init(struct net_device *dev) // just for sync 85 priv->enable_gpio0 = 0; - usValue = eprom_read(dev, EEPROM_SW_REVD_OFFSET); + eeprom_93cx6_read(&eeprom, EEPROM_SW_REVD_OFFSET, &eeprom_val); + usValue = eeprom_val; DMESG("usValue is 0x%x\n",usValue); //3Read AntennaDiversity @@ -2953,54 +2872,46 @@ short rtl8180_init(struct net_device *dev) else priv->epromtype=EPROM_93c46; - dev->dev_addr[0]=eprom_read(dev,MAC_ADR) & 0xff; - dev->dev_addr[1]=(eprom_read(dev,MAC_ADR) & 0xff00)>>8; - dev->dev_addr[2]=eprom_read(dev,MAC_ADR+1) & 0xff; - dev->dev_addr[3]=(eprom_read(dev,MAC_ADR+1) & 0xff00)>>8; - dev->dev_addr[4]=eprom_read(dev,MAC_ADR+2) & 0xff; - dev->dev_addr[5]=(eprom_read(dev,MAC_ADR+2) & 0xff00)>>8; + eeprom_93cx6_multiread(&eeprom, 0x7, (__le16 *) + dev->dev_addr, 3); for(i=1,j=0; i<14; i+=2,j++){ - word = eprom_read(dev,EPROM_TXPW_CH1_2 + j); + eeprom_93cx6_read(&eeprom, EPROM_TXPW_CH1_2 + j, &word); priv->chtxpwr[i]=word & 0xff; priv->chtxpwr[i+1]=(word & 0xff00)>>8; } for (i = 1, j = 0; i < 14; i += 2, j++) { - word = eprom_read(dev, EPROM_TXPW_OFDM_CH1_2 + j); + eeprom_93cx6_read(&eeprom, EPROM_TXPW_OFDM_CH1_2 + j, &word); priv->chtxpwr_ofdm[i] = word & 0xff; - priv->chtxpwr_ofdm[i+1] = (word & 0xff00)>>8; + priv->chtxpwr_ofdm[i+1] = (word & 0xff00) >> 8; } - //3Read crystal calibtration and thermal meter indication on 87SE. - - // By SD3 SY's request. Added by Roger, 2007.12.11. + /* 3Read crystal calibtration and thermal meter indication on 87SE. */ + eeprom_93cx6_read(&eeprom, EEPROM_RSV>>1, &tmpu16); - tmpu16 = eprom_read(dev, EEPROM_RSV>>1); + /* Crystal calibration for Xin and Xout resp. */ + priv->XtalCal_Xout = tmpu16 & EEPROM_XTAL_CAL_XOUT_MASK; + priv->XtalCal_Xin = (tmpu16 & EEPROM_XTAL_CAL_XIN_MASK) >> 4; + if ((tmpu16 & EEPROM_XTAL_CAL_ENABLE) >> 12) + priv->bXtalCalibration = true; - // Crystal calibration for Xin and Xout resp. - priv->XtalCal_Xout = tmpu16 & EEPROM_XTAL_CAL_XOUT_MASK; // 0~7.5pF - priv->XtalCal_Xin = (tmpu16 & EEPROM_XTAL_CAL_XIN_MASK)>>4; // 0~7.5pF - if((tmpu16 & EEPROM_XTAL_CAL_ENABLE)>>12) - priv->bXtalCalibration = true; + /* Thermal meter reference indication. */ + priv->ThermalMeter = (u8)((tmpu16 & EEPROM_THERMAL_METER_MASK) >> 8); + if ((tmpu16 & EEPROM_THERMAL_METER_ENABLE) >> 13) + priv->bTxPowerTrack = true; - // Thermal meter reference indication. - priv->ThermalMeter = (u8)((tmpu16 & EEPROM_THERMAL_METER_MASK)>>8); - if((tmpu16 & EEPROM_THERMAL_METER_ENABLE)>>13) - priv->bTxPowerTrack = true; - - word = eprom_read(dev,EPROM_TXPW_BASE); + eeprom_93cx6_read(&eeprom, EPROM_TXPW_BASE, &word); priv->cck_txpwr_base = word & 0xf; priv->ofdm_txpwr_base = (word>>4) & 0xf; - version = eprom_read(dev,EPROM_VERSION); + eeprom_93cx6_read(&eeprom, EPROM_VERSION, &version); DMESG("EEPROM version %x",version); priv->rcr_csense = 3; - priv->cs_treshold = (eprom_read(dev, ENERGY_TRESHOLD) & 0xff00) >> 8; - - priv->rf_chip = 0xff & eprom_read(dev, RFCHIPID); + eeprom_93cx6_read(&eeprom, ENERGY_TRESHOLD, &eeprom_val); + priv->cs_treshold = (eeprom_val & 0xff00) >> 8; - priv->rf_chip = RF_ZEBRA4; + eeprom_93cx6_read(&eeprom, RFCHIPID, &eeprom_val); priv->rf_sleep = rtl8225z4_rf_sleep; priv->rf_wakeup = rtl8225z4_rf_wakeup; DMESGW("**PLEASE** REPORT SUCCESSFUL/UNSUCCESSFUL TO Realtek!"); @@ -3010,7 +2921,6 @@ short rtl8180_init(struct net_device *dev) priv->rf_set_chan = rtl8225z2_rf_set_chan; priv->rf_set_sens = NULL; - if (0!=alloc_rx_desc_ring(dev, priv->rxbuffersize, priv->rxringcount)) return -ENOMEM; @@ -3042,11 +2952,7 @@ short rtl8180_init(struct net_device *dev) TX_BEACON_RING_ADDR)) return -ENOMEM; -#if !defined(SA_SHIRQ) if(request_irq(dev->irq, (void *)rtl8180_interrupt, IRQF_SHARED, dev->name, dev)){ -#else - if(request_irq(dev->irq, (void *)rtl8180_interrupt, SA_SHIRQ, dev->name, dev)){ -#endif DMESGE("Error allocating IRQ %d",dev->irq); return -1; }else{ @@ -3169,43 +3075,6 @@ void write_phy_cck (struct net_device *dev, u8 adr, u32 data) rtl8185_write_phy(dev, adr, data | 0x10000); } -/* 70*3 = 210 ms - * I hope this is enougth - */ -#define MAX_PHY 70 -void write_phy(struct net_device *dev, u8 adr, u8 data) -{ - u32 phy; - int i; - - phy = 0xff0000; - phy |= adr; - phy |= 0x80; /* this should enable writing */ - phy |= (data<<8); - - //PHY_ADR, PHY_R and PHY_W are contig and treated as one dword - write_nic_dword(dev,PHY_ADR, phy); - - phy= 0xffff00; - phy |= adr; - - write_nic_dword(dev,PHY_ADR, phy); - for(i=0;i<MAX_PHY;i++){ - phy=read_nic_dword(dev,PHY_ADR); - phy= phy & 0xff0000; - phy= phy >> 16; - if(phy == data){ //SUCCESS! - force_pci_posting(dev); - mdelay(3); //random value - return; - }else{ - force_pci_posting(dev); - mdelay(3); //random value - } - } - DMESGW ("Phy writing %x %x failed!", adr,data); -} - void rtl8185_set_rate(struct net_device *dev) { int i; @@ -3335,7 +3204,6 @@ static struct net_device_stats *rtl8180_stats(struct net_device *dev) } // // Change current and default preamble mode. -// 2005.01.06, by rcnjko. // bool MgntActSet_802_11_PowerSaveMode( @@ -3454,7 +3322,6 @@ void rtl8180_watch_dog(struct net_device *dev) MgntLinkKeepAlive(priv); //YJ,add,080828,for LPS -#ifdef ENABLE_LPS if (priv->PowerProfile == POWER_PROFILE_BATTERY) priv->bLeisurePs = true; else if (priv->PowerProfile == POWER_PROFILE_AC) { @@ -3464,7 +3331,6 @@ void rtl8180_watch_dog(struct net_device *dev) if(priv->ieee80211->state == IEEE80211_LINKED){ priv->link_detect.NumRxOkInPeriod = priv->ieee80211->NumRxDataInPeriod; - //printk("TxOk=%d RxOk=%d\n", priv->link_detect.NumTxOkInPeriod, priv->link_detect.NumRxOkInPeriod); if( priv->link_detect.NumRxOkInPeriod> 666 || priv->link_detect.NumTxOkInPeriod> 666 ) { bBusyTraffic = true; @@ -3481,7 +3347,6 @@ void rtl8180_watch_dog(struct net_device *dev) LeisurePSLeave(priv); } else LeisurePSLeave(priv); -#endif priv->link_detect.bBusyTraffic = bBusyTraffic; priv->link_detect.NumRxOkInPeriod = 0; priv->link_detect.NumTxOkInPeriod = 0; @@ -3503,16 +3368,11 @@ int _rtl8180_up(struct net_device *dev) if(priv->ieee80211->iw_mode == IW_MODE_ADHOC) IPSLeave(dev); } -#ifdef RATE_ADAPT timer_rate_adaptive((unsigned long)dev); -#endif watch_dog_adaptive((unsigned long)dev); -#ifdef SW_ANTE if(priv->bSwAntennaDiverity) SwAntennaDiversityTimerCallback(dev); -#endif ieee80211_softmac_start_protocol(priv->ieee80211); - return 0; } @@ -3748,7 +3608,7 @@ static int __devinit rtl8180_pci_probe(struct pci_dev *pdev, dev->wireless_handlers = &r8180_wx_handlers_def; dev->type=ARPHRD_ETHER; - dev->watchdog_timeo = HZ*3; //added by david woo, 2007.12.13 + dev->watchdog_timeo = HZ*3; if (dev_alloc_name(dev, ifname) < 0){ DMESG("Oops: devname already taken! Trying wlan%%d...\n"); @@ -3864,8 +3724,7 @@ static int __init rtl8180_pci_module_init(void) return ret; } - printk(KERN_INFO "\nLinux kernel driver for RTL8180 \ -/ RTL8185 based WLAN cards\n"); + printk(KERN_INFO "\nLinux kernel driver for RTL8180 / RTL8185 based WLAN cards\n"); printk(KERN_INFO "Copyright (c) 2004-2005, Andrea Merello\n"); DMESG("Initializing module"); DMESG("Wireless extensions version %d", WIRELESS_EXT); @@ -4236,60 +4095,51 @@ void GPIOChangeRFWorkItemCallBack(struct work_struct *work) static char *envp[] = {"HOME=/", "TERM=linux", "PATH=/usr/bin:/bin", NULL}; static int readf_count = 0; -#ifdef ENABLE_LPS if(readf_count % 10 == 0) priv->PowerProfile = read_acadapter_file("/proc/acpi/ac_adapter/AC0/state"); readf_count = (readf_count+1)%0xffff; -#endif - { - // We should turn off LED before polling FF51[4]. + /* We should turn off LED before polling FF51[4]. */ - //Turn off LED. - btPSR = read_nic_byte(dev, PSR); - write_nic_byte(dev, PSR, (btPSR & ~BIT3)); + /* Turn off LED. */ + btPSR = read_nic_byte(dev, PSR); + write_nic_byte(dev, PSR, (btPSR & ~BIT3)); - //It need to delay 4us suggested by Jong, 2008-01-16 - udelay(4); + /* It need to delay 4us suggested by Jong, 2008-01-16 */ + udelay(4); - //HW radio On/Off according to the value of FF51[4](config0) - btConfig0 = btPSR = read_nic_byte(dev, CONFIG0); + /* HW radio On/Off according to the value of FF51[4](config0) */ + btConfig0 = btPSR = read_nic_byte(dev, CONFIG0); - //Turn on LED. - write_nic_byte(dev, PSR, btPSR| BIT3); + eRfPowerStateToSet = (btConfig0 & BIT4) ? eRfOn : eRfOff; - eRfPowerStateToSet = (btConfig0 & BIT4) ? eRfOn : eRfOff; + /* Turn LED back on when radio enabled */ + if (eRfPowerStateToSet == eRfOn) + write_nic_byte(dev, PSR, btPSR | BIT3); - if((priv->ieee80211->bHwRadioOff == true) && (eRfPowerStateToSet == eRfOn)) - { - priv->ieee80211->bHwRadioOff = false; - bActuallySet = true; - } - else if((priv->ieee80211->bHwRadioOff == false) && (eRfPowerStateToSet == eRfOff)) - { - priv->ieee80211->bHwRadioOff = true; - bActuallySet = true; - } + if ((priv->ieee80211->bHwRadioOff == true) && + (eRfPowerStateToSet == eRfOn)) { + priv->ieee80211->bHwRadioOff = false; + bActuallySet = true; + } else if ((priv->ieee80211->bHwRadioOff == false) && + (eRfPowerStateToSet == eRfOff)) { + priv->ieee80211->bHwRadioOff = true; + bActuallySet = true; + } - if(bActuallySet) - { - MgntActSet_RF_State(dev, eRfPowerStateToSet, RF_CHANGE_BY_HW); - - /* To update the UI status for Power status changed */ - if(priv->ieee80211->bHwRadioOff == true) - argv[1] = "RFOFF"; - else{ - //if(!priv->RfOffReason) - argv[1] = "RFON"; - //else - // argv[1] = "RFOFF"; - } - argv[0] = RadioPowerPath; - argv[2] = NULL; - - call_usermodehelper(RadioPowerPath,argv,envp,1); - } - } + if (bActuallySet) { + MgntActSet_RF_State(dev, eRfPowerStateToSet, RF_CHANGE_BY_HW); + + /* To update the UI status for Power status changed */ + if (priv->ieee80211->bHwRadioOff == true) + argv[1] = "RFOFF"; + else + argv[1] = "RFON"; + argv[0] = RadioPowerPath; + argv[2] = NULL; + + call_usermodehelper(RadioPowerPath, argv, envp, 1); + } } static u8 read_acadapter_file(char *filename) diff --git a/drivers/staging/rtl8187se/r8180_dm.c b/drivers/staging/rtl8187se/r8180_dm.c index cbca58d..fc49078 100644 --- a/drivers/staging/rtl8187se/r8180_dm.c +++ b/drivers/staging/rtl8187se/r8180_dm.c @@ -282,30 +282,13 @@ DIG_Zebra( // Dispatch DIG implementation according to RF. // void -DynamicInitGain( - struct net_device *dev - ) +DynamicInitGain(struct net_device *dev) { - struct r8180_priv *priv = ieee80211_priv(dev); - - switch(priv->rf_chip) - { - case RF_ZEBRA2: // [AnnieWorkaround] For Zebra2, 2005-08-01. - case RF_ZEBRA4: - DIG_Zebra( dev ); - break; - - default: - printk("DynamicInitGain(): unknown RFChipID(%d) !!!\n", priv->rf_chip); - break; - } + DIG_Zebra(dev); } void rtl8180_hw_dig_wq (struct work_struct *work) { -// struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq); -// struct ieee80211_device * ieee = (struct ieee80211_device*) -// container_of(work, struct ieee80211_device, watch_dog_wq); struct delayed_work *dwork = to_delayed_work(work); struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_dig_wq); struct net_device *dev = ieee->dev; @@ -1310,44 +1293,24 @@ SetAntenna8185( switch(u1bAntennaIndex) { case 0: - switch(priv->rf_chip) - { - case RF_ZEBRA2: - case RF_ZEBRA4: - // Mac register, main antenna - write_nic_byte(dev, ANTSEL, 0x03); - //base band - write_phy_cck(dev,0x11, 0x9b); // Config CCK RX antenna. - write_phy_ofdm(dev, 0x0d, 0x5c); // Config OFDM RX antenna. - - - bAntennaSwitched = true; - break; + /* Mac register, main antenna */ + write_nic_byte(dev, ANTSEL, 0x03); + /* base band */ + write_phy_cck(dev, 0x11, 0x9b); /* Config CCK RX antenna. */ + write_phy_ofdm(dev, 0x0d, 0x5c); /* Config OFDM RX antenna. */ - default: - printk("SetAntenna8185: unknown RFChipID(%d)\n", priv->rf_chip); - break; - } + bAntennaSwitched = true; break; case 1: - switch(priv->rf_chip) - { - case RF_ZEBRA2: - case RF_ZEBRA4: - // Mac register, aux antenna - write_nic_byte(dev, ANTSEL, 0x00); - //base band - write_phy_cck(dev, 0x11, 0xbb); // Config CCK RX antenna. - write_phy_ofdm(dev, 0x0d, 0x54); // Config OFDM RX antenna. - - bAntennaSwitched = true; - break; + /* Mac register, aux antenna */ + write_nic_byte(dev, ANTSEL, 0x00); + /* base band */ + write_phy_cck(dev, 0x11, 0xbb); /* Config CCK RX antenna. */ + write_phy_ofdm(dev, 0x0d, 0x54); /* Config OFDM RX antenna. */ + + bAntennaSwitched = true; - default: - printk("SetAntenna8185: unknown RFChipID(%d)\n", priv->rf_chip); - break; - } break; default: diff --git a/drivers/staging/rtl8187se/r8180_rtl8225z2.c b/drivers/staging/rtl8187se/r8180_rtl8225z2.c index afe10f0..6edf5a4 100644 --- a/drivers/staging/rtl8187se/r8180_rtl8225z2.c +++ b/drivers/staging/rtl8187se/r8180_rtl8225z2.c @@ -854,134 +854,48 @@ bool SetZebraRFPowerState8185(struct net_device *dev, btConfig3 = read_nic_byte(dev, CONFIG3); write_nic_byte(dev, CONFIG3, (btConfig3 | CONFIG3_PARM_En)); - switch (priv->rf_chip) { - case RF_ZEBRA2: - switch (eRFPowerState) { - case eRfOn: - RF_WriteReg(dev,0x4,0x9FF); + switch (eRFPowerState) { + case eRfOn: + write_nic_word(dev, 0x37C, 0x00EC); - write_nic_dword(dev, ANAPARAM, ANAPARM_ON); - write_nic_dword(dev, ANAPARAM2, ANAPARM2_ON); + /* turn on AFE */ + write_nic_byte(dev, 0x54, 0x00); + write_nic_byte(dev, 0x62, 0x00); - write_nic_byte(dev, CONFIG4, priv->RFProgType); + /* turn on RF */ + RF_WriteReg(dev, 0x0, 0x009f); udelay(500); + RF_WriteReg(dev, 0x4, 0x0972); udelay(500); - /* turn on CCK and OFDM */ - u1bTmp = read_nic_byte(dev, 0x24E); - write_nic_byte(dev, 0x24E, (u1bTmp & (~(BIT5 | BIT6)))); - break; - case eRfSleep: - break; - case eRfOff: - break; - default: - bResult = false; - break; - } - break; - case RF_ZEBRA4: - switch (eRFPowerState) { - case eRfOn: - write_nic_word(dev, 0x37C, 0x00EC); - - /* turn on AFE */ - write_nic_byte(dev, 0x54, 0x00); - write_nic_byte(dev, 0x62, 0x00); - - /* turn on RF */ - RF_WriteReg(dev, 0x0, 0x009f); udelay(500); - RF_WriteReg(dev, 0x4, 0x0972); udelay(500); - - /* turn on RF again */ - RF_WriteReg(dev, 0x0, 0x009f); udelay(500); - RF_WriteReg(dev, 0x4, 0x0972); udelay(500); + /* turn on RF again */ + RF_WriteReg(dev, 0x0, 0x009f); udelay(500); + RF_WriteReg(dev, 0x4, 0x0972); udelay(500); - /* turn on BB */ - write_phy_ofdm(dev,0x10,0x40); - write_phy_ofdm(dev,0x12,0x40); - - /* Avoid power down at init time. */ - write_nic_byte(dev, CONFIG4, priv->RFProgType); - - u1bTmp = read_nic_byte(dev, 0x24E); - write_nic_byte(dev, 0x24E, (u1bTmp & (~(BIT5 | BIT6)))); - break; - case eRfSleep: - for (QueueID = 0, i = 0; QueueID < 6;) { - if (get_curr_tx_free_desc(dev, QueueID) == priv->txringcount) { - QueueID++; - continue; - } else { - priv->TxPollingTimes ++; - if (priv->TxPollingTimes >= LPS_MAX_SLEEP_WAITING_TIMES_87SE) { - bActionAllowed = false; - break; - } else - udelay(10); - } - } + /* turn on BB */ + write_phy_ofdm(dev, 0x10, 0x40); + write_phy_ofdm(dev, 0x12, 0x40); - if (bActionAllowed) { - /* turn off BB RXIQ matrix to cut off rx signal */ - write_phy_ofdm(dev, 0x10, 0x00); - write_phy_ofdm(dev, 0x12, 0x00); - - /* turn off RF */ - RF_WriteReg(dev, 0x4, 0x0000); - RF_WriteReg(dev, 0x0, 0x0000); - - /* turn off AFE except PLL */ - write_nic_byte(dev, 0x62, 0xff); - write_nic_byte(dev, 0x54, 0xec); - - mdelay(1); - - { - int i = 0; - while (true) { - u8 tmp24F = read_nic_byte(dev, 0x24f); - - if ((tmp24F == 0x01) || (tmp24F == 0x09)) { - bTurnOffBB = true; - break; - } else { - udelay(10); - i++; - priv->TxPollingTimes++; - - if (priv->TxPollingTimes >= LPS_MAX_SLEEP_WAITING_TIMES_87SE) { - bTurnOffBB = false; - break; - } else - udelay(10); - } - } - } - - if (bTurnOffBB) { - /* turn off BB */ - u1bTmp = read_nic_byte(dev, 0x24E); - write_nic_byte(dev, 0x24E, (u1bTmp | BIT5 | BIT6)); - - /* turn off AFE PLL */ - write_nic_byte(dev, 0x54, 0xFC); - write_nic_word(dev, 0x37C, 0x00FC); - } - } - break; - case eRfOff: - for (QueueID = 0, i = 0; QueueID < 6;) { - if (get_curr_tx_free_desc(dev, QueueID) == priv->txringcount) { - QueueID++; - continue; - } else { - udelay(10); - i++; - } + /* Avoid power down at init time. */ + write_nic_byte(dev, CONFIG4, priv->RFProgType); - if (i >= MAX_DOZE_WAITING_TIMES_85B) + u1bTmp = read_nic_byte(dev, 0x24E); + write_nic_byte(dev, 0x24E, (u1bTmp & (~(BIT5 | BIT6)))); + break; + case eRfSleep: + for (QueueID = 0, i = 0; QueueID < 6;) { + if (get_curr_tx_free_desc(dev, QueueID) == priv->txringcount) { + QueueID++; + continue; + } else { + priv->TxPollingTimes++; + if (priv->TxPollingTimes >= LPS_MAX_SLEEP_WAITING_TIMES_87SE) { + bActionAllowed = false; break; + } else + udelay(10); } + } + if (bActionAllowed) { /* turn off BB RXIQ matrix to cut off rx signal */ write_phy_ofdm(dev, 0x10, 0x00); write_phy_ofdm(dev, 0x12, 0x00); @@ -998,22 +912,23 @@ bool SetZebraRFPowerState8185(struct net_device *dev, { int i = 0; - - while (true) - { + while (true) { u8 tmp24F = read_nic_byte(dev, 0x24f); if ((tmp24F == 0x01) || (tmp24F == 0x09)) { bTurnOffBB = true; break; } else { - bTurnOffBB = false; udelay(10); i++; - } + priv->TxPollingTimes++; - if (i > MAX_POLLING_24F_TIMES_87SE) - break; + if (priv->TxPollingTimes >= LPS_MAX_SLEEP_WAITING_TIMES_87SE) { + bTurnOffBB = false; + break; + } else + udelay(10); + } } } @@ -1022,15 +937,68 @@ bool SetZebraRFPowerState8185(struct net_device *dev, u1bTmp = read_nic_byte(dev, 0x24E); write_nic_byte(dev, 0x24E, (u1bTmp | BIT5 | BIT6)); - /* turn off AFE PLL (80M) */ + /* turn off AFE PLL */ write_nic_byte(dev, 0x54, 0xFC); write_nic_word(dev, 0x37C, 0x00FC); } - break; - default: - bResult = false; - printk("SetZebraRFPowerState8185(): unknown state to set: 0x%X!!!\n", eRFPowerState); - break; + } + break; + case eRfOff: + for (QueueID = 0, i = 0; QueueID < 6;) { + if (get_curr_tx_free_desc(dev, QueueID) == priv->txringcount) { + QueueID++; + continue; + } else { + udelay(10); + i++; + } + + if (i >= MAX_DOZE_WAITING_TIMES_85B) + break; + } + + /* turn off BB RXIQ matrix to cut off rx signal */ + write_phy_ofdm(dev, 0x10, 0x00); + write_phy_ofdm(dev, 0x12, 0x00); + + /* turn off RF */ + RF_WriteReg(dev, 0x4, 0x0000); + RF_WriteReg(dev, 0x0, 0x0000); + + /* turn off AFE except PLL */ + write_nic_byte(dev, 0x62, 0xff); + write_nic_byte(dev, 0x54, 0xec); + + mdelay(1); + + { + int i = 0; + + while (true) { + u8 tmp24F = read_nic_byte(dev, 0x24f); + + if ((tmp24F == 0x01) || (tmp24F == 0x09)) { + bTurnOffBB = true; + break; + } else { + bTurnOffBB = false; + udelay(10); + i++; + } + + if (i > MAX_POLLING_24F_TIMES_87SE) + break; + } + } + + if (bTurnOffBB) { + /* turn off BB */ + u1bTmp = read_nic_byte(dev, 0x24E); + write_nic_byte(dev, 0x24E, (u1bTmp | BIT5 | BIT6)); + + /* turn off AFE PLL (80M) */ + write_nic_byte(dev, 0x54, 0xFC); + write_nic_word(dev, 0x37C, 0x00FC); } break; } diff --git a/drivers/staging/rtl8187se/r8185b_init.c b/drivers/staging/rtl8187se/r8185b_init.c index 50309f2..a0ece1f 100644 --- a/drivers/staging/rtl8187se/r8185b_init.c +++ b/drivers/staging/rtl8187se/r8185b_init.c @@ -238,100 +238,12 @@ PlatformIORead4Byte( return data; } -void -SetOutputEnableOfRfPins( - struct net_device *dev - ) +void SetOutputEnableOfRfPins(struct net_device *dev) { - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - - switch(priv->rf_chip) - { - case RFCHIPID_RTL8225: - case RF_ZEBRA2: - case RF_ZEBRA4: - write_nic_word(dev, RFPinsEnable, 0x1bff); - //write_nic_word(dev, RFPinsEnable, 0x1fff); - break; - } + write_nic_word(dev, RFPinsEnable, 0x1bff); } -void -ZEBRA_RFSerialWrite( - struct net_device *dev, - u32 data2Write, - u8 totalLength, - u8 low2high - ) -{ - ThreeWireReg twreg; - int i; - u16 oval,oval2,oval3; - u32 mask; - u16 UshortBuffer; - - u8 u1bTmp; - // RTL8187S HSSI Read/Write Function - u1bTmp = read_nic_byte(dev, RF_SW_CONFIG); - u1bTmp |= RF_SW_CFG_SI; //reg08[1]=1 Serial Interface(SI) - write_nic_byte(dev, RF_SW_CONFIG, u1bTmp); - UshortBuffer = read_nic_word(dev, RFPinsOutput); - oval = UshortBuffer & 0xfff8; // We shall clear bit0, 1, 2 first, 2005.10.28, by rcnjko. - - oval2 = read_nic_word(dev, RFPinsEnable); - oval3 = read_nic_word(dev, RFPinsSelect); - - // <RJ_NOTE> 3-wire should be controled by HW when we finish SW 3-wire programming. 2005.08.10, by rcnjko. - oval3 &= 0xfff8; - - write_nic_word(dev, RFPinsEnable, (oval2|0x0007)); // Set To Output Enable - write_nic_word(dev, RFPinsSelect, (oval3|0x0007)); // Set To SW Switch - udelay(10); - - // Add this to avoid hardware and software 3-wire conflict. - // 2005.03.01, by rcnjko. - twreg.longData = 0; - twreg.struc.enableB = 1; - write_nic_word(dev, RFPinsOutput, (twreg.longData|oval)); // Set SI_EN (RFLE) - udelay(2); - twreg.struc.enableB = 0; - write_nic_word(dev, RFPinsOutput, (twreg.longData|oval)); // Clear SI_EN (RFLE) - udelay(10); - - mask = (low2high)?0x01:((u32)0x01<<(totalLength-1)); - - for(i=0; i<totalLength/2; i++) - { - twreg.struc.data = ((data2Write&mask)!=0) ? 1 : 0; - write_nic_word(dev, RFPinsOutput, (twreg.longData|oval)); - twreg.struc.clk = 1; - write_nic_word(dev, RFPinsOutput, (twreg.longData|oval)); - write_nic_word(dev, RFPinsOutput, (twreg.longData|oval)); - - mask = (low2high)?(mask<<1):(mask>>1); - twreg.struc.data = ((data2Write&mask)!=0) ? 1 : 0; - write_nic_word(dev, RFPinsOutput, (twreg.longData|oval)); - write_nic_word(dev, RFPinsOutput, (twreg.longData|oval)); - twreg.struc.clk = 0; - write_nic_word(dev, RFPinsOutput, (twreg.longData|oval)); - mask = (low2high)?(mask<<1):(mask>>1); - } - - twreg.struc.enableB = 1; - twreg.struc.clk = 0; - twreg.struc.data = 0; - write_nic_word(dev, RFPinsOutput, twreg.longData|oval); - udelay(10); - - write_nic_word(dev, RFPinsOutput, oval|0x0004); - write_nic_word(dev, RFPinsSelect, oval3|0x0000); - - SetOutputEnableOfRfPins(dev); -} -//by amy - - -int +static int HwHSSIThreeWire( struct net_device *dev, u8 *pDataBuf, @@ -469,420 +381,30 @@ HwHSSIThreeWire( return bResult; } -//by amy - -int -HwThreeWire( - struct net_device *dev, - u8 *pDataBuf, - u8 nDataBufBitCnt, - int bHold, - int bWrite - ) -{ - int bResult = 1; - u8 TryCnt; - u8 u1bTmp; - - do - { - // Check if WE and RE are cleared. - for(TryCnt = 0; TryCnt < TC_3W_POLL_MAX_TRY_CNT; TryCnt++) - { - u1bTmp = read_nic_byte(dev, SW_3W_CMD1); - if( (u1bTmp & (SW_3W_CMD1_RE|SW_3W_CMD1_WE)) == 0 ) - { - break; - } - udelay(10); - } - if (TryCnt == TC_3W_POLL_MAX_TRY_CNT) - panic("HwThreeWire(): CmdReg: %#X RE|WE bits are not clear!!\n", u1bTmp); - - // Fill up data buffer for write operation. - if(nDataBufBitCnt == 16) - { - write_nic_word(dev, SW_3W_DB0, *((u16 *)pDataBuf)); - } - else if(nDataBufBitCnt == 64) - { - write_nic_dword(dev, SW_3W_DB0, *((u32 *)pDataBuf)); - write_nic_dword(dev, SW_3W_DB1, *((u32 *)(pDataBuf + 4))); - } - else - { - int idx; - int ByteCnt = nDataBufBitCnt / 8; - - if ((nDataBufBitCnt % 8) != 0) - panic("HwThreeWire(): nDataBufBitCnt(%d) should be multiple of 8!!!\n", - nDataBufBitCnt); - - if (nDataBufBitCnt > 64) - panic("HwThreeWire(): nDataBufBitCnt(%d) should <= 64!!!\n", - nDataBufBitCnt); - - for(idx = 0; idx < ByteCnt; idx++) - { - write_nic_byte(dev, (SW_3W_DB0+idx), *(pDataBuf+idx)); - } - } - - // Fill up length field. - u1bTmp = (u8)(nDataBufBitCnt - 1); // Number of bits - 1. - if(bHold) - u1bTmp |= SW_3W_CMD0_HOLD; - write_nic_byte(dev, SW_3W_CMD0, u1bTmp); - - // Set up command: WE or RE. - if(bWrite) - { - write_nic_byte(dev, SW_3W_CMD1, SW_3W_CMD1_WE); - } - else - { - write_nic_byte(dev, SW_3W_CMD1, SW_3W_CMD1_RE); - } - - // Check if WE and RE are cleared and DONE is set. - for(TryCnt = 0; TryCnt < TC_3W_POLL_MAX_TRY_CNT; TryCnt++) - { - u1bTmp = read_nic_byte(dev, SW_3W_CMD1); - if( (u1bTmp & (SW_3W_CMD1_RE|SW_3W_CMD1_WE)) == 0 && - (u1bTmp & SW_3W_CMD1_DONE) != 0 ) - { - break; - } - udelay(10); - } - if(TryCnt == TC_3W_POLL_MAX_TRY_CNT) - { - //RT_ASSERT(TryCnt != TC_3W_POLL_MAX_TRY_CNT, - // ("HwThreeWire(): CmdReg: %#X RE|WE bits are not clear or DONE is not set!!\n", u1bTmp)); - // Workaround suggested by wcchu: clear WE here. 2006.07.07, by rcnjko. - write_nic_byte(dev, SW_3W_CMD1, 0); - } - - // Read back data for read operation. - // <RJ_TODO> I am not sure if this is correct output format of a read operation. - if(bWrite == 0) - { - if(nDataBufBitCnt == 16) - { - *((u16 *)pDataBuf) = read_nic_word(dev, SW_3W_DB0); - } - else if(nDataBufBitCnt == 64) - { - *((u32 *)pDataBuf) = read_nic_dword(dev, SW_3W_DB0); - *((u32 *)(pDataBuf + 4)) = read_nic_dword(dev, SW_3W_DB1); - } - else - { - int idx; - int ByteCnt = nDataBufBitCnt / 8; - - if ((nDataBufBitCnt % 8) != 0) - panic("HwThreeWire(): nDataBufBitCnt(%d) should be multiple of 8!!!\n", - nDataBufBitCnt); - - if (nDataBufBitCnt > 64) - panic("HwThreeWire(): nDataBufBitCnt(%d) should <= 64!!!\n", - nDataBufBitCnt); - - for(idx = 0; idx < ByteCnt; idx++) - { - *(pDataBuf+idx) = read_nic_byte(dev, (SW_3W_DB0+idx)); - } - } - } - - }while(0); - - return bResult; -} - void -RF_WriteReg( - struct net_device *dev, - u8 offset, - u32 data - ) +RF_WriteReg(struct net_device *dev, u8 offset, u32 data) { - //RFReg reg; - u32 data2Write; - u8 len; - u8 low2high; - //u32 RF_Read = 0; - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - - - switch(priv->rf_chip) - { - case RFCHIPID_RTL8225: - case RF_ZEBRA2: // Annie 2006-05-12. - case RF_ZEBRA4: //by amy - switch(priv->RegThreeWireMode) - { - case SW_THREE_WIRE: - { // Perform SW 3-wire programming by driver. - data2Write = (data << 4) | (u32)(offset & 0x0f); - len = 16; - low2high = 0; - ZEBRA_RFSerialWrite(dev, data2Write, len, low2high); - } - break; + u32 data2Write; + u8 len; - case HW_THREE_WIRE: - { // Pure HW 3-wire. - data2Write = (data << 4) | (u32)(offset & 0x0f); - len = 16; - HwThreeWire( - dev, - (u8 *)(&data2Write), // pDataBuf, - len, // nDataBufBitCnt, - 0, // bHold, - 1); // bWrite - } - break; - case HW_THREE_WIRE_PI: //Parallel Interface - { // Pure HW 3-wire. - data2Write = (data << 4) | (u32)(offset & 0x0f); - len = 16; - HwHSSIThreeWire( - dev, - (u8*)(&data2Write), // pDataBuf, - len, // nDataBufBitCnt, - 0, // bSI - 1); // bWrite - - //printk("33333\n"); - } - break; - - case HW_THREE_WIRE_SI: //Serial Interface - { // Pure HW 3-wire. - data2Write = (data << 4) | (u32)(offset & 0x0f); - len = 16; -// printk(" enter ZEBRA_RFSerialWrite\n "); -// low2high = 0; -// ZEBRA_RFSerialWrite(dev, data2Write, len, low2high); - - HwHSSIThreeWire( - dev, - (u8*)(&data2Write), // pDataBuf, - len, // nDataBufBitCnt, - 1, // bSI - 1); // bWrite - -// printk(" exit ZEBRA_RFSerialWrite\n "); - } - break; - - - default: - DMESGE("RF_WriteReg(): invalid RegThreeWireMode(%d) !!!", priv->RegThreeWireMode); - break; - } - break; - - default: - DMESGE("RF_WriteReg(): unknown RFChipID: %#X", priv->rf_chip); - break; - } -} - - -void -ZEBRA_RFSerialRead( - struct net_device *dev, - u32 data2Write, - u8 wLength, - u32 *data2Read, - u8 rLength, - u8 low2high - ) -{ - ThreeWireReg twreg; - int i; - u16 oval,oval2,oval3,tmp, wReg80; - u32 mask; - u8 u1bTmp; - ThreeWireReg tdata; - //PHAL_DATA_8187 pHalData = GetHalData8187(pAdapter); - { // RTL8187S HSSI Read/Write Function - u1bTmp = read_nic_byte(dev, RF_SW_CONFIG); - u1bTmp |= RF_SW_CFG_SI; //reg08[1]=1 Serial Interface(SI) - write_nic_byte(dev, RF_SW_CONFIG, u1bTmp); - } - - wReg80 = oval = read_nic_word(dev, RFPinsOutput); - oval2 = read_nic_word(dev, RFPinsEnable); - oval3 = read_nic_word(dev, RFPinsSelect); - - write_nic_word(dev, RFPinsEnable, oval2|0xf); - write_nic_word(dev, RFPinsSelect, oval3|0xf); - - *data2Read = 0; - - // We must clear BIT0-3 here, otherwise, - // SW_Enalbe will be true when we first call ZEBRA_RFSerialRead() after 8187MPVC open, - // which will cause the value read become 0. 2005.04.11, by rcnjko. - oval &= ~0xf; - - // Avoid collision with hardware three-wire. - twreg.longData = 0; - twreg.struc.enableB = 1; - write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(4); - - twreg.longData = 0; - twreg.struc.enableB = 0; - twreg.struc.clk = 0; - twreg.struc.read_write = 0; - write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(5); - - mask = (low2high) ? 0x01 : ((u32)0x01<<(32-1)); - for(i = 0; i < wLength/2; i++) - { - twreg.struc.data = ((data2Write&mask) != 0) ? 1 : 0; - write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(1); - twreg.struc.clk = 1; - write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2); - write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2); - - mask = (low2high) ? (mask<<1): (mask>>1); - - if(i == 2) - { - // Commented out by Jackie, 2004.08.26. <RJ_NOTE> We must comment out the following two lines for we cannot pull down VCOPDN during RF Serail Read. - //PlatformEFIOWrite2Byte(pAdapter, RFPinsEnable, 0xe); // turn off data enable - //PlatformEFIOWrite2Byte(pAdapter, RFPinsSelect, 0xe); - - twreg.struc.read_write=1; - write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2); - twreg.struc.clk = 0; - write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2); - break; - } - twreg.struc.data = ((data2Write&mask) != 0) ? 1: 0; - write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2); - write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2); - - twreg.struc.clk = 0; - write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(1); - - mask = (low2high) ? (mask<<1) : (mask>>1); - } - - twreg.struc.clk = 0; - twreg.struc.data = 0; - write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2); - mask = (low2high) ? 0x01 : ((u32)0x01 << (12-1)); - - // - // 061016, by rcnjko: - // We must set data pin to HW controled, otherwise RF can't driver it and - // value RF register won't be able to read back properly. - // - write_nic_word(dev, RFPinsEnable, ( ((oval2|0x0E) & (~0x01))) ); + /* Pure HW 3-wire. */ + data2Write = (data << 4) | (u32)(offset & 0x0f); + len = 16; - for(i = 0; i < rLength; i++) - { - write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(1); - twreg.struc.clk = 1; - write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2); - write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2); - write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2); - tmp = read_nic_word(dev, RFPinsInput); - tdata.longData = tmp; - *data2Read |= tdata.struc.clk ? mask : 0; - - twreg.struc.clk = 0; - write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2); - - mask = (low2high) ? (mask<<1) : (mask>>1); - } - twreg.struc.enableB = 1; - twreg.struc.clk = 0; - twreg.struc.data = 0; - twreg.struc.read_write = 1; - write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2); - - //PlatformEFIOWrite2Byte(pAdapter, RFPinsEnable, oval2|0x8); // Set To Output Enable - write_nic_word(dev, RFPinsEnable, oval2); // Set To Output Enable, <RJ_NOTE> We cannot enable BIT3 here, otherwise, we will failed to switch channel. 2005.04.12. - //PlatformEFIOWrite2Byte(pAdapter, RFPinsEnable, 0x1bff); - write_nic_word(dev, RFPinsSelect, oval3); // Set To SW Switch - //PlatformEFIOWrite2Byte(pAdapter, RFPinsSelect, 0x0488); - write_nic_word(dev, RFPinsOutput, 0x3a0); - //PlatformEFIOWrite2Byte(pAdapter, RFPinsOutput, 0x0480); + HwHSSIThreeWire(dev, (u8 *)(&data2Write), len, 1, 1); } - -u32 -RF_ReadReg( - struct net_device *dev, - u8 offset - ) +u32 RF_ReadReg(struct net_device *dev, u8 offset) { - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - u32 data2Write; - u8 wlen; - u8 rlen; - u8 low2high; - u32 dataRead; + u32 data2Write; + u8 wlen; + u32 dataRead; - switch(priv->rf_chip) - { - case RFCHIPID_RTL8225: - case RF_ZEBRA2: - case RF_ZEBRA4: - switch(priv->RegThreeWireMode) - { - case HW_THREE_WIRE_PI: // For 87S Parallel Interface. - { - data2Write = ((u32)(offset&0x0f)); - wlen=16; - HwHSSIThreeWire( - dev, - (u8*)(&data2Write), // pDataBuf, - wlen, // nDataBufBitCnt, - 0, // bSI - 0); // bWrite - dataRead= data2Write; - } - break; - - case HW_THREE_WIRE_SI: // For 87S Serial Interface. - { - data2Write = ((u32)(offset&0x0f)) ; - wlen=16; - HwHSSIThreeWire( - dev, - (u8*)(&data2Write), // pDataBuf, - wlen, // nDataBufBitCnt, - 1, // bSI - 0 // bWrite - ); - dataRead= data2Write; - } - break; - - // Perform SW 3-wire programming by driver. - default: - { - data2Write = ((u32)(offset&0x1f)) << 27; // For Zebra E-cut. 2005.04.11, by rcnjko. - wlen = 6; - rlen = 12; - low2high = 0; - ZEBRA_RFSerialRead(dev, data2Write, wlen,&dataRead,rlen, low2high); - } - break; - } - break; - default: - dataRead = 0; - break; - } + data2Write = ((u32)(offset & 0x0f)); + wlen = 16; + HwHSSIThreeWire(dev, (u8 *)(&data2Write), wlen, 1, 0); + dataRead = data2Write; return dataRead; } @@ -1043,15 +565,12 @@ ZEBRA_Config_85BASIC_HardCode( // Page0 : reg0-reg15 -// RF_WriteReg(dev, 0x00, 0x003f); mdelay(1);//1 RF_WriteReg(dev, 0x00, 0x009f); mdelay(1);// 1 RF_WriteReg(dev, 0x01, 0x06e0); mdelay(1); -// RF_WriteReg(dev, 0x02, 0x004c); mdelay(1);//2 RF_WriteReg(dev, 0x02, 0x004d); mdelay(1);// 2 -// RF_WriteReg(dev, 0x03, 0x0000); mdelay(1);//3 RF_WriteReg(dev, 0x03, 0x07f1); mdelay(1);// 3 RF_WriteReg(dev, 0x04, 0x0975); mdelay(1); @@ -1080,8 +599,6 @@ ZEBRA_Config_85BASIC_HardCode( RF_WriteReg(dev, 0x07, 0x01A0); mdelay(1); // Don't write RF23/RF24 to make a difference between 87S C cut and D cut. asked by SD3 stevenl. -// RF_WriteReg(dev, 0x08, 0x0597); mdelay(1); -// RF_WriteReg(dev, 0x09, 0x050a); mdelay(1); RF_WriteReg(dev, 0x0a, 0x0001); mdelay(1); RF_WriteReg(dev, 0x0b, 0x0418); mdelay(1); @@ -1097,7 +614,6 @@ ZEBRA_Config_85BASIC_HardCode( RF_WriteReg(dev, 0x0f, 0x0acc); mdelay(1); -// RF_WriteReg(dev, 0x00, 0x017f); mdelay(1);//6 RF_WriteReg(dev, 0x00, 0x01d7); mdelay(1);// 6 RF_WriteReg(dev, 0x03, 0x0e00); mdelay(1); @@ -1106,20 +622,14 @@ ZEBRA_Config_85BASIC_HardCode( { RF_WriteReg(dev, 0x01, i); mdelay(1); RF_WriteReg(dev, 0x02, ZEBRA_RF_RX_GAIN_TABLE[i]); mdelay(1); - //DbgPrint("RF - 0x%x = 0x%x", i, ZEBRA_RF_RX_GAIN_TABLE[i]); } RF_WriteReg(dev, 0x05, 0x0203); mdelay(1); /// 203, 343 - //RF_WriteReg(dev, 0x06, 0x0300); mdelay(1); // 400 RF_WriteReg(dev, 0x06, 0x0200); mdelay(1); // 400 RF_WriteReg(dev, 0x00, 0x0137); mdelay(1); // switch to reg16-reg30, and HSSI disable 137 mdelay(10); // Deay 10 ms. //0xfd -// RF_WriteReg(dev, 0x0c, 0x09be); mdelay(1); // 7 - //RF_WriteReg(dev, 0x0c, 0x07be); mdelay(1); - //mdelay(10); // Deay 10 ms. //0xfd - RF_WriteReg(dev, 0x0d, 0x0008); mdelay(1); // Z4 synthesizer loop filter setting, 392 mdelay(10); // Deay 10 ms. //0xfd @@ -1165,10 +675,8 @@ ZEBRA_Config_85BASIC_HardCode( RF_WriteReg(dev, 0x0f, 0x0acc); mdelay(1); } //by amy 080312 -// RF_WriteReg(dev, 0x0f, 0x0acc); mdelay(1); //-by amy 080312 RF_WriteReg(dev, 0x00, 0x00bf); mdelay(1); // switch to reg0-reg15, and HSSI enable -// RF_WriteReg(dev, 0x0d, 0x009f); mdelay(1); // Rx BB start calibration, 00c//-edward RF_WriteReg(dev, 0x0d, 0x08df); mdelay(1); // Rx BB start calibration, 00c//+edward RF_WriteReg(dev, 0x02, 0x004d); mdelay(1); // temperature meter off RF_WriteReg(dev, 0x04, 0x0975); mdelay(1); // Rx mode @@ -1217,13 +725,10 @@ ZEBRA_Config_85BASIC_HardCode( // AGC.txt //============================================================================= -// PlatformIOWrite4Byte( dev, PhyAddr, 0x00001280); // Annie, 2006-05-05 write_phy_ofdm(dev, 0x00, 0x12); - //WriteBBPortUchar(dev, 0x00001280); for (i=0; i<128; i++) { - //DbgPrint("AGC - [%x+1] = 0x%x\n", i, ZEBRA_AGC[i+1]); data = ZEBRA_AGC[i+1]; data = data << 8; @@ -1239,7 +744,6 @@ ZEBRA_Config_85BASIC_HardCode( } PlatformIOWrite4Byte( dev, PhyAddr, 0x00001080); // Annie, 2006-05-05 - //WriteBBPortUchar(dev, 0x00001080); //============================================================================= @@ -1252,8 +756,6 @@ ZEBRA_Config_85BASIC_HardCode( u4bRegOffset=i; u4bRegValue=OFDM_CONFIG[i]; - //DbgPrint("OFDM - 0x%x = 0x%x\n", u4bRegOffset, u4bRegValue); - WriteBBPortUchar(dev, (0x00000080 | (u4bRegOffset & 0x7f) | @@ -1277,9 +779,6 @@ UpdateInitialGain( ) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - //unsigned char* IGTable; - //u8 DIG_CurrentInitialGain = 4; - //unsigned char u1Tmp; //lzm add 080826 if(priv->eRFPowerState != eRfOn) @@ -1291,81 +790,59 @@ UpdateInitialGain( return; } - switch(priv->rf_chip) - { - case RF_ZEBRA4: - // Dynamic set initial gain, follow 87B - switch(priv->InitialGain) - { - case 1: //m861dBm - //DMESG("RTL8187 + 8225 Initial Gain State 1: -82 dBm \n"); - write_phy_ofdm(dev, 0x17, 0x26); mdelay(1); - write_phy_ofdm(dev, 0x24, 0x86); mdelay(1); - write_phy_ofdm(dev, 0x05, 0xfa); mdelay(1); - break; - - case 2: //m862dBm - //DMESG("RTL8187 + 8225 Initial Gain State 2: -82 dBm \n"); - write_phy_ofdm(dev, 0x17, 0x36); mdelay(1); - write_phy_ofdm(dev, 0x24, 0x86); mdelay(1); - write_phy_ofdm(dev, 0x05, 0xfa); mdelay(1); - break; - - case 3: //m863dBm - //DMESG("RTL8187 + 8225 Initial Gain State 3: -82 dBm \n"); - write_phy_ofdm(dev, 0x17, 0x36); mdelay(1); - write_phy_ofdm(dev, 0x24, 0x86); mdelay(1); - write_phy_ofdm(dev, 0x05, 0xfb); mdelay(1); - break; - - case 4: //m864dBm - //DMESG("RTL8187 + 8225 Initial Gain State 4: -78 dBm \n"); - write_phy_ofdm(dev, 0x17, 0x46); mdelay(1); - write_phy_ofdm(dev, 0x24, 0x86); mdelay(1); - write_phy_ofdm(dev, 0x05, 0xfb); mdelay(1); - break; + switch (priv->InitialGain) { + case 1: /* m861dBm */ + write_phy_ofdm(dev, 0x17, 0x26); mdelay(1); + write_phy_ofdm(dev, 0x24, 0x86); mdelay(1); + write_phy_ofdm(dev, 0x05, 0xfa); mdelay(1); + break; - case 5: //m82dBm - //DMESG("RTL8187 + 8225 Initial Gain State 5: -74 dBm \n"); - write_phy_ofdm(dev, 0x17, 0x46); mdelay(1); - write_phy_ofdm(dev, 0x24, 0x96); mdelay(1); - write_phy_ofdm(dev, 0x05, 0xfb); mdelay(1); - break; + case 2: /* m862dBm */ + write_phy_ofdm(dev, 0x17, 0x36); mdelay(1); + write_phy_ofdm(dev, 0x24, 0x86); mdelay(1); + write_phy_ofdm(dev, 0x05, 0xfa); mdelay(1); + break; - case 6: //m78dBm - //DMESG ("RTL8187 + 8225 Initial Gain State 6: -70 dBm \n"); - write_phy_ofdm(dev, 0x17, 0x56); mdelay(1); - write_phy_ofdm(dev, 0x24, 0x96); mdelay(1); - write_phy_ofdm(dev, 0x05, 0xfc); mdelay(1); - break; + case 3: /* m863dBm */ + write_phy_ofdm(dev, 0x17, 0x36); mdelay(1); + write_phy_ofdm(dev, 0x24, 0x86); mdelay(1); + write_phy_ofdm(dev, 0x05, 0xfb); mdelay(1); + break; - case 7: //m74dBm - //DMESG("RTL8187 + 8225 Initial Gain State 7: -66 dBm \n"); - write_phy_ofdm(dev, 0x17, 0x56); mdelay(1); - write_phy_ofdm(dev, 0x24, 0xa6); mdelay(1); - write_phy_ofdm(dev, 0x05, 0xfc); mdelay(1); - break; + case 4: /* m864dBm */ + write_phy_ofdm(dev, 0x17, 0x46); mdelay(1); + write_phy_ofdm(dev, 0x24, 0x86); mdelay(1); + write_phy_ofdm(dev, 0x05, 0xfb); mdelay(1); + break; - case 8: - //DMESG("RTL8187 + 8225 Initial Gain State 8:\n"); - write_phy_ofdm(dev, 0x17, 0x66); mdelay(1); - write_phy_ofdm(dev, 0x24, 0xb6); mdelay(1); - write_phy_ofdm(dev, 0x05, 0xfc); mdelay(1); - break; + case 5: /* m82dBm */ + write_phy_ofdm(dev, 0x17, 0x46); mdelay(1); + write_phy_ofdm(dev, 0x24, 0x96); mdelay(1); + write_phy_ofdm(dev, 0x05, 0xfb); mdelay(1); + break; + case 6: /* m78dBm */ + write_phy_ofdm(dev, 0x17, 0x56); mdelay(1); + write_phy_ofdm(dev, 0x24, 0x96); mdelay(1); + write_phy_ofdm(dev, 0x05, 0xfc); mdelay(1); + break; - default: //MP - //DMESG("RTL8187 + 8225 Initial Gain State 1: -82 dBm (default)\n"); - write_phy_ofdm(dev, 0x17, 0x26); mdelay(1); - write_phy_ofdm(dev, 0x24, 0x86); mdelay(1); - write_phy_ofdm(dev, 0x05, 0xfa); mdelay(1); - break; - } + case 7: /* m74dBm */ + write_phy_ofdm(dev, 0x17, 0x56); mdelay(1); + write_phy_ofdm(dev, 0x24, 0xa6); mdelay(1); + write_phy_ofdm(dev, 0x05, 0xfc); mdelay(1); break; + case 8: + write_phy_ofdm(dev, 0x17, 0x66); mdelay(1); + write_phy_ofdm(dev, 0x24, 0xb6); mdelay(1); + write_phy_ofdm(dev, 0x05, 0xfc); mdelay(1); + break; - default: - DMESG("UpdateInitialGain(): unknown RFChipID: %#X\n", priv->rf_chip); + default: /* MP */ + write_phy_ofdm(dev, 0x17, 0x26); mdelay(1); + write_phy_ofdm(dev, 0x24, 0x86); mdelay(1); + write_phy_ofdm(dev, 0x05, 0xfa); mdelay(1); break; } } @@ -1379,13 +856,11 @@ InitTxPwrTracking87SE( struct net_device *dev ) { - //struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); u32 u4bRfReg; u4bRfReg = RF_ReadReg(dev, 0x02); // Enable Thermal meter indication. - //printk("InitTxPwrTracking87SE(): Enable thermal meter indication, Write RF[0x02] = %#x", u4bRfReg|PWR_METER_EN); RF_WriteReg(dev, 0x02, u4bRfReg|PWR_METER_EN); mdelay(1); } @@ -1397,21 +872,14 @@ PhyConfig8185( struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); write_nic_dword(dev, RCR, priv->ReceiveConfig); priv->RFProgType = read_nic_byte(dev, CONFIG4) & 0x03; - // RF config - switch(priv->rf_chip) - { - case RF_ZEBRA2: - case RF_ZEBRA4: - ZEBRA_Config_85BASIC_HardCode( dev); - break; - } + /* RF config */ + ZEBRA_Config_85BASIC_HardCode(dev); //{by amy 080312 // Set default initial gain state to 4, approved by SD3 DZ, by Bruce, 2007-06-06. if(priv->bDigMechanism) { if(priv->InitialGain == 0) priv->InitialGain = 4; - //printk("PhyConfig8185(): DIG is enabled, set default initial gain index to %d\n", priv->InitialGain); } // @@ -1429,34 +897,17 @@ PhyConfig8185( return; } - - - void HwConfigureRTL8185( struct net_device *dev ) { //RTL8185_TODO: Determine Retrylimit, TxAGC, AutoRateFallback control. -// u8 bUNIVERSAL_CONTROL_RL = 1; u8 bUNIVERSAL_CONTROL_RL = 0; - u8 bUNIVERSAL_CONTROL_AGC = 1; u8 bUNIVERSAL_CONTROL_ANT = 1; u8 bAUTO_RATE_FALLBACK_CTL = 1; u8 val8; - //struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - //struct ieee80211_device *ieee = priv->ieee80211; - //if(IS_WIRELESS_MODE_A(dev) || IS_WIRELESS_MODE_G(dev)) -//{by amy 080312 if((ieee->mode == IEEE_G)||(ieee->mode == IEEE_A)) -// { -// write_nic_word(dev, BRSR, 0xffff); -// } -// else -// { -// write_nic_word(dev, BRSR, 0x000f); -// } -//by amy 080312} write_nic_word(dev, BRSR, 0x0fff); // Retry limit val8 = read_nic_byte(dev, CW_CONF); @@ -1507,20 +958,11 @@ HwConfigureRTL8185( val8 |= RATE_FALLBACK_CTL_ENABLE | RATE_FALLBACK_CTL_AUTO_STEP1; // <RJ_TODO_8185B> We shall set up the ARFR according to user's setting. - //write_nic_word(dev, ARFR, 0x0fff); // set 1M ~ 54M -//by amy - // Aadded by Roger, 2007.11.15. PlatformIOWrite2Byte(dev, ARFR, 0x0fff); //set 1M ~ 54Mbps. -//by amy - } - else - { } write_nic_byte(dev, RATE_FALLBACK, val8); } - - static void MacConfig_85BASIC_HardCode( struct net_device *dev) @@ -1548,14 +990,11 @@ MacConfig_85BASIC_HardCode( { u4bRegOffset |= (u4bPageIndex << 8); } - //DbgPrint("MAC - 0x%x = 0x%x\n", u4bRegOffset, u4bRegValue); write_nic_byte(dev, u4bRegOffset, (u8)u4bRegValue); } //============================================================================ } - - static void MacConfig_85BASIC( struct net_device *dev) @@ -1578,8 +1017,6 @@ MacConfig_85BASIC( PlatformIOWrite1Byte(dev, 0x1F8, 0x00); // Asked for by SD3 CM Lin, 2006.06.27, by rcnjko. - //PlatformIOWrite4Byte(dev, RFTiming, 0x00004001); -//by amy // power save parameter based on "87SE power save parameters 20071127.doc", as follow. //Enable DA10 TX power saving @@ -1598,35 +1035,18 @@ MacConfig_85BASIC( write_nic_word(dev, 0x378, 0x0560); write_nic_word(dev, 0x37A, 0x0560); write_nic_word(dev, 0x37C, 0x00EC); -// write_nic_word(dev, 0x37E, 0x00FE);//-edward write_nic_word(dev, 0x37E, 0x00EC);//+edward write_nic_byte(dev, 0x24E,0x01); -//by amy - } - - - u8 GetSupportedWirelessMode8185( struct net_device *dev ) { u8 btSupportedWirelessMode = 0; - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - - switch(priv->rf_chip) - { - case RF_ZEBRA2: - case RF_ZEBRA4: - btSupportedWirelessMode = (WIRELESS_MODE_B | WIRELESS_MODE_G); - break; - default: - btSupportedWirelessMode = WIRELESS_MODE_B; - break; - } + btSupportedWirelessMode = (WIRELESS_MODE_B | WIRELESS_MODE_G); return btSupportedWirelessMode; } @@ -1641,7 +1061,6 @@ ActUpdateChannelAccessSetting( struct ieee80211_device *ieee = priv->ieee80211; AC_CODING eACI; AC_PARAM AcParam; - //PSTA_QOS pStaQos = Adapter->MgntInfo.pStaQos; u8 bFollowLegacySetting = 0; u8 u1bAIFS; @@ -1663,40 +1082,14 @@ ActUpdateChannelAccessSetting( ChnlAccessSetting->CWmaxIndex = 7; // 2006.06.02, by rcnjko. write_nic_byte(dev, SIFS, ChnlAccessSetting->SIFS_Timer); - //Adapter->HalFunc.SetHwRegHandler( Adapter, HW_VAR_SLOT_TIME, &ChnlAccessSetting->SlotTimeTimer ); // Rewrited from directly use PlatformEFIOWrite1Byte(), by Annie, 2006-03-29. write_nic_byte(dev, SLOT, ChnlAccessSetting->SlotTimeTimer); // Rewrited from directly use PlatformEFIOWrite1Byte(), by Annie, 2006-03-29. u1bAIFS = aSifsTime + (2 * ChnlAccessSetting->SlotTimeTimer ); - //write_nic_byte(dev, AC_VO_PARAM, u1bAIFS); - //write_nic_byte(dev, AC_VI_PARAM, u1bAIFS); - //write_nic_byte(dev, AC_BE_PARAM, u1bAIFS); - //write_nic_byte(dev, AC_BK_PARAM, u1bAIFS); - write_nic_byte(dev, EIFS, ChnlAccessSetting->EIFS_Timer); write_nic_byte(dev, AckTimeOutReg, 0x5B); // <RJ_EXPR_QOS> Suggested by wcchu, it is the default value of EIFS register, 2005.12.08. -#ifdef TODO - // <RJ_TODO_NOW_8185B> Update ECWmin/ECWmax, AIFS, TXOP Limit of each AC to the value defined by SPEC. - if( pStaQos->CurrentQosMode > QOS_DISABLE ) - { // QoS mode. - if(pStaQos->QBssWirelessMode == WirelessMode) - { - // Follow AC Parameters of the QBSS. - for(eACI = 0; eACI < AC_MAX; eACI++) - { - Adapter->HalFunc.SetHwRegHandler(Adapter, HW_VAR_AC_PARAM, (pu1Byte)(&(pStaQos->WMMParamEle.AcParam[eACI])) ); - } - } - else - { - // Follow Default WMM AC Parameters. - bFollowLegacySetting = 1; - } - } - else -#endif { // Legacy 802.11. bFollowLegacySetting = 1; @@ -1719,14 +1112,12 @@ ActUpdateChannelAccessSetting( AcParam.f.TXOPLimit = 0; //lzm reserved 080826 -#if 1 // For turbo mode setting. port from 87B by Isaiah 2008-08-01 if( ieee->current_network.Turbo_Enable == 1 ) AcParam.f.TXOPLimit = 0x01FF; // For 87SE with Intel 4965 Ad-Hoc mode have poor throughput (19MB) if (ieee->iw_mode == IW_MODE_ADHOC) AcParam.f.TXOPLimit = 0x0020; -#endif for(eACI = 0; eACI < AC_MAX; eACI++) { @@ -1770,18 +1161,13 @@ ActUpdateChannelAccessSetting( // Cehck ACM bit. // If it is set, immediately set ACM control bit to downgrading AC for passing WMM testplan. Annie, 2005-12-13. - //write_nic_byte(dev, ACM_CONTROL, pAcParam->f.AciAifsn); { PACI_AIFSN pAciAifsn = (PACI_AIFSN)(&pAcParam->f.AciAifsn); AC_CODING eACI = pAciAifsn->f.ACI; //modified Joseph //for 8187B AsynIORead issue -#ifdef TODO - u8 AcmCtrl = pHalData->AcmControl; -#else u8 AcmCtrl = 0; -#endif if( pAciAifsn->f.ACM ) { // ACM bit is 1. switch(eACI) @@ -1823,19 +1209,10 @@ ActUpdateChannelAccessSetting( break; } } - - //printk(KERN_WARNING "SetHwReg8185(): [HW_VAR_ACM_CTRL] Write 0x%X\n", AcmCtrl); - -#ifdef TO_DO - pHalData->AcmControl = AcmCtrl; -#endif - //write_nic_byte(dev, ACM_CONTROL, AcmCtrl); write_nic_byte(dev, ACM_CONTROL, 0); } } } - - } } @@ -1847,7 +1224,6 @@ ActSetWirelessMode8185( { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); struct ieee80211_device *ieee = priv->ieee80211; - //PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo); u8 btSupportedWirelessMode = GetSupportedWirelessMode8185(dev); if( (btWirelessMode & btSupportedWirelessMode) == 0 ) @@ -1880,24 +1256,11 @@ ActSetWirelessMode8185( } } - - // 2. Swtich band: RF or BB specific actions, - // for example, refresh tables in omc8255, or change initial gain if necessary. - switch(priv->rf_chip) - { - case RF_ZEBRA2: - case RF_ZEBRA4: - { - // Nothing to do for Zebra to switch band. - // Update current wireless mode if we swtich to specified band successfully. - ieee->mode = (WIRELESS_MODE)btWirelessMode; - } - break; - - default: - DMESGW("ActSetWirelessMode8185(): unsupported RF: 0x%X !!!\n", priv->rf_chip); - break; - } + /* 2. Swtich band: RF or BB specific actions, + * for example, refresh tables in omc8255, or change initial gain if necessary. + * Nothing to do for Zebra to switch band. + * Update current wireless mode if we swtich to specified band successfully. */ + ieee->mode = (WIRELESS_MODE)btWirelessMode; // 3. Change related setting. if( ieee->mode == WIRELESS_MODE_A ){ @@ -1909,7 +1272,6 @@ ActSetWirelessMode8185( else if( ieee->mode == WIRELESS_MODE_G ){ DMESG("WIRELESS_MODE_G\n"); } - ActUpdateChannelAccessSetting( dev, ieee->mode, &priv->ChannelAccessSetting); } @@ -1927,11 +1289,7 @@ DrvIFIndicateDisassociation( u16 reason ) { - //printk("==> DrvIFIndicateDisassociation()\n"); - // nothing is needed after disassociation request. - - //printk("<== DrvIFIndicateDisassociation()\n"); } void MgntDisconnectIBSS( @@ -1941,11 +1299,7 @@ MgntDisconnectIBSS( struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); u8 i; - //printk("XXXXXXXXXX MgntDisconnect IBSS\n"); - DrvIFIndicateDisassociation(dev, unspec_reason); - -// PlatformZeroMemory( pMgntInfo->Bssid, 6 ); for(i=0;i<6;i++) priv->ieee80211->current_network.bssid[i] = 0x55; priv->ieee80211->state = IEEE80211_NOLINK; @@ -1957,16 +1311,10 @@ MgntDisconnectIBSS( // Because Bcn DMA isn't complete, mgnt queue would stuck until Bcn packet send. // Disable Beacon Queue Own bit, suggested by jong -// Adapter->HalFunc.SetTxDescOWNHandler(Adapter, BEACON_QUEUE, 0, 0); ieee80211_stop_send_beacons(priv->ieee80211); priv->ieee80211->link_change(dev); notify_wx_assoc_event(priv->ieee80211); - - // Stop SW Beacon.Use hw beacon so do not need to do so.by amy - -// MgntIndicateMediaStatus( Adapter, RT_MEDIA_DISCONNECT, GENERAL_INDICATE ); - } void MlmeDisassociateRequest( @@ -1986,14 +1334,8 @@ MlmeDisassociateRequest( DrvIFIndicateDisassociation(dev, unspec_reason); - // pMgntInfo->AsocTimestamp = 0; for(i=0;i<6;i++) priv->ieee80211->current_network.bssid[i] = 0x22; -// pMgntInfo->mBrates.Length = 0; -// Adapter->HalFunc.SetHwRegHandler( Adapter, HW_VAR_BASIC_RATE, (pu1Byte)(&pMgntInfo->mBrates) ); - ieee80211_disassociate(priv->ieee80211); - - } } @@ -2011,23 +1353,12 @@ MgntDisconnectAP( // I move SecClearAllKeys() to MgntActSet_802_11_DISASSOCIATE(). // // //2004/09/15, kcwu, the key should be cleared, or the new handshaking will not success -// SecClearAllKeys(Adapter); // In WPA WPA2 need to Clear all key ... because new key will set after new handshaking. -#ifdef TODO - if( pMgntInfo->SecurityInfo.AuthMode > RT_802_11AuthModeAutoSwitch || - (pMgntInfo->bAPSuportCCKM && pMgntInfo->bCCX8021xenable) ) // In CCKM mode will Clear key - { - SecClearAllKeys(Adapter); - RT_TRACE(COMP_SEC, DBG_LOUD,("======>CCKM clear key...")) - } -#endif // 2004.10.11, by rcnjko. - //MlmeDisassociateRequest( Adapter, pMgntInfo->Bssid, disas_lv_ss ); MlmeDisassociateRequest( dev, priv->ieee80211->current_network.bssid, asRsn ); priv->ieee80211->state = IEEE80211_NOLINK; -// pMgntInfo->AsocTimestamp = 0; } bool MgntDisconnect( @@ -2039,20 +1370,7 @@ MgntDisconnect( // // Schedule an workitem to wake up for ps mode, 070109, by rcnjko. // -#ifdef TODO - if(pMgntInfo->mPss != eAwake) - { - // - // Using AwkaeTimer to prevent mismatch ps state. - // In the timer the state will be changed according to the RF is being awoke or not. By Bruce, 2007-10-31. - // - // PlatformScheduleWorkItem( &(pMgntInfo->AwakeWorkItem) ); - PlatformSetTimer( Adapter, &(pMgntInfo->AwakeTimer), 0 ); - } -#endif - // Indication of disassociation event. - //DrvIFIndicateDisassociation(Adapter, asRsn); if(IS_DOT11D_ENABLE(priv->ieee80211)) Dot11d_Reset(priv->ieee80211); // In adhoc mode, update beacon frame. @@ -2060,8 +1378,6 @@ MgntDisconnect( { if( priv->ieee80211->iw_mode == IW_MODE_ADHOC ) { -// RT_TRACE(COMP_MLME, DBG_LOUD, ("MgntDisconnect() ===> MgntDisconnectIBSS\n")); - //printk("MgntDisconnect() ===> MgntDisconnectIBSS\n"); MgntDisconnectIBSS(dev); } if( priv->ieee80211->iw_mode == IW_MODE_INFRA ) @@ -2071,17 +1387,10 @@ MgntDisconnect( // e.g. OID_802_11_DISASSOCIATE in Windows while as MgntDisconnectAP() is // used to handle disassociation related things to AP, e.g. send Disassoc // frame to AP. 2005.01.27, by rcnjko. -// SecClearAllKeys(Adapter); - -// RT_TRACE(COMP_MLME, DBG_LOUD, ("MgntDisconnect() ===> MgntDisconnectAP\n")); - //printk("MgntDisconnect() ===> MgntDisconnectAP\n"); MgntDisconnectAP(dev, asRsn); } - // Inidicate Disconnect, 2005.02.23, by rcnjko. -// MgntIndicateMediaStatus( Adapter, RT_MEDIA_DISCONNECT, GENERAL_INDICATE); } - return true; } // @@ -2101,25 +1410,12 @@ SetRFPowerState( struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); bool bResult = false; -// printk("---------> SetRFPowerState(): eRFPowerState(%d)\n", eRFPowerState); if(eRFPowerState == priv->eRFPowerState) { -// printk("<--------- SetRFPowerState(): discard the request for eRFPowerState(%d) is the same.\n", eRFPowerState); return bResult; } - switch(priv->rf_chip) - { - case RF_ZEBRA2: - case RF_ZEBRA4: - bResult = SetZebraRFPowerState8185(dev, eRFPowerState); - break; - - default: - printk("SetRFPowerState8185(): unknown RFChipID: 0x%X!!!\n", priv->rf_chip); - break;; -} -// printk("<--------- SetRFPowerState(): bResult(%d)\n", bResult); + bResult = SetZebraRFPowerState8185(dev, eRFPowerState); return bResult; } @@ -2149,33 +1445,25 @@ MgntActSet_RF_State( RT_RF_POWER_STATE rtState; u16 RFWaitCounter = 0; unsigned long flag; -// printk("===>MgntActSet_RF_State(): StateToSet(%d), ChangeSource(0x%x)\n",StateToSet, ChangeSource); // // Prevent the race condition of RF state change. By Bruce, 2007-11-28. // Only one thread can change the RF state at one time, and others should wait to be executed. // -#if 1 while(true) { -// down(&priv->rf_state); spin_lock_irqsave(&priv->rf_ps_lock,flag); if(priv->RFChangeInProgress) { -// printk("====================>haha111111111\n"); -// up(&priv->rf_state); -// RT_TRACE(COMP_RF, DBG_LOUD, ("MgntActSet_RF_State(): RF Change in progress! Wait to set..StateToSet(%d).\n", StateToSet)); spin_unlock_irqrestore(&priv->rf_ps_lock,flag); // Set RF after the previous action is done. while(priv->RFChangeInProgress) { RFWaitCounter ++; -// RT_TRACE(COMP_RF, DBG_LOUD, ("MgntActSet_RF_State(): Wait 1 ms (%d times)...\n", RFWaitCounter)); udelay(1000); // 1 ms // Wait too long, return FALSE to avoid to be stuck here. if(RFWaitCounter > 1000) // 1sec { -// RT_ASSERT(FALSE, ("MgntActSet_RF_State(): Wait too logn to set RF\n")); printk("MgntActSet_RF_State(): Wait too long to set RF\n"); // TODO: Reset RF state? return false; @@ -2184,17 +1472,13 @@ MgntActSet_RF_State( } else { -// printk("========================>haha2\n"); priv->RFChangeInProgress = true; -// up(&priv->rf_state); spin_unlock_irqrestore(&priv->rf_ps_lock,flag); break; } } -#endif rtState = priv->eRFPowerState; - switch(StateToSet) { case eRfOn: @@ -2215,7 +1499,6 @@ MgntActSet_RF_State( } } else -// RT_TRACE(COMP_RF, DBG_LOUD, ("MgntActSet_RF_State - eRfon reject pMgntInfo->RfOffReason= 0x%x, ChangeSource=0x%X\n", pMgntInfo->RfOffReason, ChangeSource)); ; break; @@ -2232,38 +1515,26 @@ MgntActSet_RF_State( // // Calling MgntDisconnect() instead of MgntActSet_802_11_DISASSOCIATE(), // because we do NOT need to set ssid to dummy ones. - // Revised by Roger, 2007.12.04. // MgntDisconnect( dev, disas_lv_ss ); // Clear content of bssDesc[] and bssDesc4Query[] to avoid reporting old bss to UI. - // 2007.05.28, by shien chang. -// PlatformZeroMemory( pMgntInfo->bssDesc, sizeof(RT_WLAN_BSS)*MAX_BSS_DESC ); -// pMgntInfo->NumBssDesc = 0; -// PlatformZeroMemory( pMgntInfo->bssDesc4Query, sizeof(RT_WLAN_BSS)*MAX_BSS_DESC ); -// pMgntInfo->NumBssDesc4Query = 0; } - - priv->RfOffReason |= ChangeSource; bActionAllowed = true; break; - case eRfSleep: priv->RfOffReason |= ChangeSource; bActionAllowed = true; break; - default: break; } if(bActionAllowed) { -// RT_TRACE(COMP_RF, DBG_LOUD, ("MgntActSet_RF_State(): Action is allowed.... StateToSet(%d), RfOffReason(%#X)\n", StateToSet, pMgntInfo->RfOffReason)); // Config HW to the specified mode. -// printk("MgntActSet_RF_State(): Action is allowed.... StateToSet(%d), RfOffReason(%#X)\n", StateToSet, priv->RfOffReason); SetRFPowerState(dev, StateToSet); // Turn on RF. @@ -2273,7 +1544,6 @@ MgntActSet_RF_State( if(bConnectBySSID) { // by amy not supported -// MgntActSet_802_11_SSID(Adapter, Adapter->MgntInfo.Ssid.Octet, Adapter->MgntInfo.Ssid.Length, TRUE ); } } // Turn off RF. @@ -2282,18 +1552,11 @@ MgntActSet_RF_State( HalDisableRx8185Dummy(dev); } } - else - { - // printk("MgntActSet_RF_State(): Action is rejected.... StateToSet(%d), ChangeSource(%#X), RfOffReason(%#X)\n", StateToSet, ChangeSource, priv->RfOffReason); - } // Release RF spinlock -// down(&priv->rf_state); spin_lock_irqsave(&priv->rf_ps_lock,flag); priv->RFChangeInProgress = false; -// up(&priv->rf_state); spin_unlock_irqrestore(&priv->rf_ps_lock,flag); -// printk("<===MgntActSet_RF_State()\n"); return bActionAllowed; } void @@ -2302,15 +1565,12 @@ InactivePowerSave( ) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - //u8 index = 0; - // // This flag "bSwRfProcessing", indicates the status of IPS procedure, should be set if the IPS workitem // is really scheduled. // The old code, sets this flag before scheduling the IPS workitem and however, at the same time the // previous IPS workitem did not end yet, fails to schedule the current workitem. Thus, bSwRfProcessing // blocks the IPS procedure of switching RF. - // By Bruce, 2007-12-25. // priv->bSwRfProcessing = true; @@ -2326,7 +1586,6 @@ InactivePowerSave( // // Description: // Enter the inactive power save mode. RF will be off -// 2007.08.17, by shien chang. // void IPSEnter( @@ -2335,13 +1594,11 @@ IPSEnter( { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); RT_RF_POWER_STATE rtState; - //printk("==============================>enter IPS\n"); if (priv->bInactivePs) { rtState = priv->eRFPowerState; // - // Added by Bruce, 2007-12-25. // Do not enter IPS in the following conditions: // (1) RF is already OFF or Sleep // (2) bSwRfProcessing (indicates the IPS is still under going) @@ -2352,12 +1609,10 @@ IPSEnter( if (rtState == eRfOn && !priv->bSwRfProcessing && (priv->ieee80211->state != IEEE80211_LINKED )) { - // printk("IPSEnter(): Turn off RF.\n"); priv->eInactivePowerState = eRfOff; InactivePowerSave(dev); } } -// printk("priv->eRFPowerState is %d\n",priv->eRFPowerState); } void IPSLeave( @@ -2366,20 +1621,17 @@ IPSLeave( { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); RT_RF_POWER_STATE rtState; - //printk("===================================>leave IPS\n"); if (priv->bInactivePs) { rtState = priv->eRFPowerState; if ((rtState == eRfOff || rtState == eRfSleep) && (!priv->bSwRfProcessing) && priv->RfOffReason <= RF_CHANGE_BY_IPS) { -// printk("IPSLeave(): Turn on RF.\n"); priv->eInactivePowerState = eRfOn; InactivePowerSave(dev); } } -// printk("priv->eRFPowerState is %d\n",priv->eRFPowerState); } -//by amy for power save + void rtl8185b_adapter_start(struct net_device *dev) { struct r8180_priv *priv = ieee80211_priv(dev); @@ -2388,75 +1640,45 @@ void rtl8185b_adapter_start(struct net_device *dev) u8 SupportedWirelessMode; u8 InitWirelessMode; u8 bInvalidWirelessMode = 0; - //int i; u8 tmpu8; - //u8 u1tmp,u2tmp; u8 btCR9346; u8 TmpU1b; u8 btPSR; - //rtl8180_rtx_disable(dev); -//{by amy 080312 write_nic_byte(dev,0x24e, (BIT5|BIT6|BIT0)); -//by amy 080312} rtl8180_reset(dev); priv->dma_poll_mask = 0; priv->dma_poll_stop_mask = 0; - //rtl8180_beacon_tx_disable(dev); - HwConfigureRTL8185(dev); - write_nic_dword(dev, MAC0, ((u32*)dev->dev_addr)[0]); write_nic_word(dev, MAC4, ((u32*)dev->dev_addr)[1] & 0xffff ); - write_nic_byte(dev, MSR, read_nic_byte(dev, MSR) & 0xf3); // default network type to 'No Link' - - //write_nic_byte(dev, BRSR, 0x0); // Set BRSR= 1M - write_nic_word(dev, BcnItv, 100); write_nic_word(dev, AtimWnd, 2); - - //PlatformEFIOWrite2Byte(dev, FEMR, 0xFFFF); PlatformIOWrite2Byte(dev, FEMR, 0xFFFF); - write_nic_byte(dev, WPA_CONFIG, 0); - MacConfig_85BASIC(dev); - // Override the RFSW_CTRL (MAC offset 0x272-0x273), 2006.06.07, by rcnjko. // BT_DEMO_BOARD type PlatformIOWrite2Byte(dev, RFSW_CTRL, 0x569a); -//by amy -//#ifdef CONFIG_RTL818X_S - // for jong required -// PlatformIOWrite2Byte(dev, RFSW_CTRL, 0x9a56); -//#endif -//by amy - //BT_QA_BOARD - //PlatformIOWrite2Byte(dev, RFSW_CTRL, 0x9a56); //----------------------------------------------------------------------------- // Set up PHY related. //----------------------------------------------------------------------------- // Enable Config3.PARAM_En to revise AnaaParm. write_nic_byte(dev, CR9346, 0xc0); // enable config register write -//by amy tmpu8 = read_nic_byte(dev, CONFIG3); write_nic_byte(dev, CONFIG3, (tmpu8 |CONFIG3_PARM_En) ); -//by amy // Turn on Analog power. // Asked for by William, otherwise, MAC 3-wire can't work, 2006.06.27, by rcnjko. write_nic_dword(dev, ANAPARAM2, ANAPARM2_ASIC_ON); write_nic_dword(dev, ANAPARAM, ANAPARM_ASIC_ON); -//by amy write_nic_word(dev, ANAPARAM3, 0x0010); -//by amy write_nic_byte(dev, CONFIG3, tmpu8); write_nic_byte(dev, CR9346, 0x00); -//{by amy 080312 for led // enable EEM0 and EEM1 in 9346CR btCR9346 = read_nic_byte(dev, CR9346); write_nic_byte(dev, CR9346, (btCR9346|0xC0) ); @@ -2474,7 +1696,6 @@ void rtl8185b_adapter_start(struct net_device *dev) // B-cut RF Radio on/off 5e[3]=0 btPSR = read_nic_byte(dev, PSR); write_nic_byte(dev, PSR, (btPSR | BIT3)); -//by amy 080312 for led} // setup initial timing for RFE. write_nic_word(dev, RFPinsOutput, 0x0480); SetOutputEnableOfRfPins(dev); @@ -2537,55 +1758,19 @@ void rtl8185b_adapter_start(struct net_device *dev) InitWirelessMode = ieee->mode; } //by amy for power save -// printk("initialize ENABLE_IPS\n"); priv->eRFPowerState = eRfOff; priv->RfOffReason = 0; { - // u32 tmp2; - // u32 tmp = jiffies; MgntActSet_RF_State(dev, eRfOn, 0); - // tmp2 = jiffies; - // printk("rf on cost jiffies:%lx\n", (tmp2-tmp)*1000/HZ); } -// DrvIFIndicateCurrentPhyStatus(priv); // // If inactive power mode is enabled, disable rf while in disconnected state. - // 2007.07.16, by shien chang. // if (priv->bInactivePs) { - // u32 tmp2; - // u32 tmp = jiffies; MgntActSet_RF_State(dev,eRfOff, RF_CHANGE_BY_IPS); - // tmp2 = jiffies; - // printk("rf off cost jiffies:%lx\n", (tmp2-tmp)*1000/HZ); - } -// IPSEnter(dev); //by amy for power save -#ifdef TODO - // Turn off RF if necessary. 2005.08.23, by rcnjko. - // We shall turn off RF after setting CMDR, otherwise, - // RF will be turnned on after we enable MAC Tx/Rx. - if(Adapter->MgntInfo.RegRfOff == TRUE) - { - SetRFPowerState8185(Adapter, RF_OFF); - } - else - { - SetRFPowerState8185(Adapter, RF_ON); - } -#endif - -/* //these is equal with above TODO. - write_nic_byte(dev, CR9346, 0xc0); // enable config register write - write_nic_byte(dev, CONFIG3, read_nic_byte(dev, CONFIG3) | CONFIG3_PARM_En); - RF_WriteReg(dev, 0x4, 0x9FF); - write_nic_dword(dev, ANAPARAM2, ANAPARM2_ASIC_ON); - write_nic_dword(dev, ANAPARAM, ANAPARM_ASIC_ON); - write_nic_byte(dev, CONFIG3, (read_nic_byte(dev, CONFIG3)&(~CONFIG3_PARM_En))); - write_nic_byte(dev, CR9346, 0x00); -*/ ActSetWirelessMode8185(dev, (u8)(InitWirelessMode)); @@ -2594,14 +1779,11 @@ void rtl8185b_adapter_start(struct net_device *dev) rtl8185b_irq_enable(dev); netif_start_queue(dev); - } - void rtl8185b_rx_enable(struct net_device *dev) { u8 cmd; - //u32 rxconf; /* for now we accept data, management & ctl frame*/ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); @@ -2613,11 +1795,6 @@ void rtl8185b_rx_enable(struct net_device *dev) priv->ReceiveConfig = priv->ReceiveConfig | RCR_AAP; } - /*if(priv->ieee80211->iw_mode == IW_MODE_MASTER){ - rxconf = rxconf | (1<<ACCEPT_ALLMAC_FRAME_SHIFT); - rxconf = rxconf | (1<<RX_CHECK_BSSID_SHIFT); - }*/ - if(priv->ieee80211->iw_mode == IW_MODE_MONITOR){ priv->ReceiveConfig = priv->ReceiveConfig | RCR_ACF | RCR_APWRMGT | RCR_AICV; } @@ -2629,9 +1806,6 @@ void rtl8185b_rx_enable(struct net_device *dev) fix_rx_fifo(dev); -#ifdef DEBUG_RX - DMESG("rxconf: %x %x",priv->ReceiveConfig ,read_nic_dword(dev,RCR)); -#endif cmd=read_nic_byte(dev,CMD); write_nic_byte(dev,CMD,cmd | (1<<CMD_RX_ENABLE_SHIFT)); @@ -2640,9 +1814,7 @@ void rtl8185b_rx_enable(struct net_device *dev) void rtl8185b_tx_enable(struct net_device *dev) { u8 cmd; - //u8 tx_agc_ctl; u8 byte; - //u32 txconf; struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); write_nic_dword(dev, TCR, priv->TransmitConfig); @@ -2652,21 +1824,7 @@ void rtl8185b_tx_enable(struct net_device *dev) fix_tx_fifo(dev); -#ifdef DEBUG_TX - DMESG("txconf: %x %x",priv->TransmitConfig,read_nic_dword(dev,TCR)); -#endif - cmd=read_nic_byte(dev,CMD); write_nic_byte(dev,CMD,cmd | (1<<CMD_TX_ENABLE_SHIFT)); - - //write_nic_dword(dev,TX_CONF,txconf); - - -/* - rtl8180_set_mode(dev,EPROM_CMD_CONFIG); - write_nic_byte(dev, TX_DMA_POLLING, priv->dma_poll_mask); - rtl8180_set_mode(dev,EPROM_CMD_NORMAL); - */ } - diff --git a/drivers/staging/rtl8192e/Makefile b/drivers/staging/rtl8192e/Makefile index 5e4aa95..e032c3e 100644 --- a/drivers/staging/rtl8192e/Makefile +++ b/drivers/staging/rtl8192e/Makefile @@ -1,13 +1,15 @@ NIC_SELECT = RTL8192E - EXTRA_CFLAGS += -DRTL8192E EXTRA_CFLAGS += -std=gnu89 EXTRA_CFLAGS += -O2 EXTRA_CFLAGS += -DTHOMAS_TURBO EXTRA_CFLAGS += -DENABLE_DOT11D -r8192_pci-objs := \ +EXTRA_CFLAGS += -DENABLE_IPS +EXTRA_CFLAGS += -DENABLE_LPS + +r8192e_pci-objs := \ r8192E_core.o \ r8180_93cx6.o \ r8192E_wx.o \ @@ -31,4 +33,5 @@ r8192_pci-objs := \ ieee80211/ieee80211_crypt_ccmp.o \ ieee80211/ieee80211_crypt_wep.o -obj-$(CONFIG_RTL8192E) += r8192_pci.o +obj-$(CONFIG_RTL8192E) += r8192e_pci.o + diff --git a/drivers/staging/rtl8192e/dot11d.h b/drivers/staging/rtl8192e/dot11d.h index 15b7a4b..5b0e2db 100644 --- a/drivers/staging/rtl8192e/dot11d.h +++ b/drivers/staging/rtl8192e/dot11d.h @@ -1,102 +1,96 @@ -#ifndef __INC_DOT11D_H -#define __INC_DOT11D_H +#ifndef INC_DOT11D_H +#define INC_DOT11D_H #ifdef ENABLE_DOT11D #include "ieee80211.h" -//#define ENABLE_DOT11D - -//#define DOT11D_MAX_CHNL_NUM 83 - typedef struct _CHNL_TXPOWER_TRIPLE { u8 FirstChnl; u8 NumChnls; u8 MaxTxPowerInDbm; -}CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE; +} CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE; typedef enum _DOT11D_STATE { DOT11D_STATE_NONE = 0, DOT11D_STATE_LEARNED, DOT11D_STATE_DONE, -}DOT11D_STATE; +} DOT11D_STATE; + +/** + * struct _RT_DOT11D_INFO + * @CountryIeLen: value greater than 0 if @CountryIeBuf contains + * valid country information element. + * @chanell_map: holds channel values + * 0 - invalid, + * 1 - valid (active scan), + * 2 - valid (passive scan) + * @CountryIeSrcAddr - Source AP of the country IE + */ typedef struct _RT_DOT11D_INFO { - //DECLARE_RT_OBJECT(RT_DOT11D_INFO); + bool bEnabled; - bool bEnabled; // dot11MultiDomainCapabilityEnabled + u16 CountryIeLen; + u8 CountryIeBuf[MAX_IE_LEN]; + u8 CountryIeSrcAddr[6]; + u8 CountryIeWatchdog; - u16 CountryIeLen; // > 0 if CountryIeBuf[] contains valid country information element. - u8 CountryIeBuf[MAX_IE_LEN]; - u8 CountryIeSrcAddr[6]; // Source AP of the country IE. - u8 CountryIeWatchdog; - - u8 channel_map[MAX_CHANNEL_NUMBER+1]; //!!!Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan) - //u8 ChnlListLen; // #Bytes valid in ChnlList[]. - //u8 ChnlList[DOT11D_MAX_CHNL_NUM]; - u8 MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1]; + u8 channel_map[MAX_CHANNEL_NUMBER+1]; + u8 MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1]; DOT11D_STATE State; -}RT_DOT11D_INFO, *PRT_DOT11D_INFO; -#define eqMacAddr(a,b) ( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 ) -#define cpMacAddr(des,src) ((des)[0]=(src)[0],(des)[1]=(src)[1],(des)[2]=(src)[2],(des)[3]=(src)[3],(des)[4]=(src)[4],(des)[5]=(src)[5]) -#define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO)((__pIeeeDev)->pDot11dInfo)) +} RT_DOT11D_INFO, *PRT_DOT11D_INFO; + +#define eqMacAddr(a, b) (((a)[0] == (b)[0] && (a)[1] == (b)[1] && (a)[2] == \ + (b)[2] && (a)[3] == (b)[3] && (a)[4] == (b)[4] && \ + (a)[5] == (b)[5]) ? 1 : 0) + +#define cpMacAddr(des, src) ((des)[0] = (src)[0], (des)[1] = (src)[1], \ + (des)[2] = (src)[2], (des)[3] = (src)[3], \ + (des)[4] = (src)[4], (des)[5] = (src)[5]) + +#define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO) \ + ((__pIeeeDev)->pDot11dInfo)) #define IS_DOT11D_ENABLE(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->bEnabled -#define IS_COUNTRY_IE_VALID(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0) +#define IS_COUNTRY_IE_VALID(__pIeeeDev) \ + (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0) -#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa) -#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa) +#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) \ + eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa) + +#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) \ + cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa) #define IS_COUNTRY_IE_CHANGED(__pIeeeDev, __Ie) \ - (((__Ie).Length == 0 || (__Ie).Length != GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? \ - FALSE : \ - (!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, (__Ie).Octet, (__Ie).Length))) + (((__Ie).Length == 0 || (__Ie).Length != \ + GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? FALSE : \ + (!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, \ + (__Ie).Octet, (__Ie).Length))) #define CIE_WATCHDOG_TH 1 #define GET_CIE_WATCHDOG(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog #define RESET_CIE_WATCHDOG(__pIeeeDev) GET_CIE_WATCHDOG(__pIeeeDev) = 0 #define UPDATE_CIE_WATCHDOG(__pIeeeDev) ++GET_CIE_WATCHDOG(__pIeeeDev) -#define IS_DOT11D_STATE_DONE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE) - - -void -Dot11d_Init( - struct ieee80211_device *dev - ); - -void -Dot11d_Reset( - struct ieee80211_device *dev - ); - -void -Dot11d_UpdateCountryIe( - struct ieee80211_device *dev, - u8 * pTaddr, - u16 CoutryIeLen, - u8 * pCoutryIe - ); - -u8 -DOT11D_GetMaxTxPwrInDbm( - struct ieee80211_device *dev, - u8 Channel - ); - -void -DOT11D_ScanComplete( - struct ieee80211_device * dev - ); - -int IsLegalChannel( - struct ieee80211_device * dev, - u8 channel -); - -int ToLegalChannel( - struct ieee80211_device * dev, - u8 channel -); -#endif //ENABLE_DOT11D -#endif // #ifndef __INC_DOT11D_H +#define IS_DOT11D_STATE_DONE(__pIeeeDev) \ + (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE) + + +void Dot11d_Init(struct ieee80211_device *dev); + +void Dot11d_Reset(struct ieee80211_device *dev); + +void Dot11d_UpdateCountryIe(struct ieee80211_device *dev, u8 *pTaddr, + u16 CoutryIeLen, u8 *pCoutryIe); + +u8 DOT11D_GetMaxTxPwrInDbm(struct ieee80211_device *dev, u8 channel); + +void DOT11D_ScanComplete(struct ieee80211_device *dev); + +int IsLegalChannel(struct ieee80211_device *dev, u8 channel); + +int ToLegalChannel(struct ieee80211_device *dev, u8 channel); + +#endif /* ENABLE_DOT11D */ +#endif /* INC_DOT11D_H */ diff --git a/drivers/staging/rtl8192e/ieee80211.h b/drivers/staging/rtl8192e/ieee80211.h index 3ba9e9e..c39249e 100644 --- a/drivers/staging/rtl8192e/ieee80211.h +++ b/drivers/staging/rtl8192e/ieee80211.h @@ -547,9 +547,6 @@ do { if (ieee80211_debug_level & (level)) \ /* debug macros not dependent on CONFIG_IEEE80211_DEBUG */ -#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x" -#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5] - /* * To use the debug system; * diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211.h b/drivers/staging/rtl8192e/ieee80211/ieee80211.h index aa76390..1f613a2 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211.h @@ -35,6 +35,7 @@ #endif #include <linux/timer.h> #include <linux/sched.h> +#include <linux/semaphore.h> #include <linux/delay.h> #include <linux/wireless.h> @@ -180,6 +181,8 @@ typedef struct cb_desc { u8 DrvAggrNum; u16 pkt_size; u8 reserved12; + + u8 bdhcp; }cb_desc, *pcb_desc; /*--------------------------Define -------------------------------------------*/ @@ -615,9 +618,6 @@ do { if (ieee80211_debug_level & (level)) \ /* debug macros not dependent on CONFIG_IEEE80211_DEBUG */ -#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x" -#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5] - /* * To use the debug system; * @@ -743,6 +743,8 @@ struct ieee80211_snap_hdr { #define WLAN_FC_GET_VERS(fc) ((fc) & IEEE80211_FCTL_VERS) #define WLAN_FC_GET_TYPE(fc) ((fc) & IEEE80211_FCTL_FTYPE) #define WLAN_FC_GET_STYPE(fc) ((fc) & IEEE80211_FCTL_STYPE) +#define WLAN_FC_MORE_DATA(fc) ((fc) & IEEE80211_FCTL_MOREDATA) + #define WLAN_FC_GET_FRAMETYPE(fc) ((fc) & IEEE80211_FCTL_FRAMETYPE) #define WLAN_GET_SEQ_FRAG(seq) ((seq) & IEEE80211_SCTL_FRAG) @@ -1055,7 +1057,7 @@ struct ieee80211_device; #define SEC_ALG_NONE 0 #define SEC_ALG_WEP 1 #define SEC_ALG_TKIP 2 -#define SEC_ALG_CCMP 3 +#define SEC_ALG_CCMP 4 #define WEP_KEYS 4 #define WEP_KEY_LEN 13 @@ -1124,6 +1126,14 @@ enum ieee80211_mfie { /* Minimal header; can be used for passing 802.11 frames with sufficient * information to determine what type of underlying data type is actually * stored in the data. */ + struct ieee80211_pspoll_hdr { + __le16 frame_ctl; + __le16 aid; + u8 bssid[ETH_ALEN]; + u8 ta[ETH_ALEN]; + //u8 payload[0]; +} __attribute__ ((packed)); + struct ieee80211_hdr { __le16 frame_ctl; __le16 duration_id; @@ -1660,6 +1670,7 @@ struct ieee80211_network { bool ralink_cap_exist; bool atheros_cap_exist; bool cisco_cap_exist; + bool marvell_cap_exist; bool unknown_cap_exist; // u8 berp_info; bool berp_info_valid; @@ -1865,6 +1876,19 @@ typedef struct _RT_POWER_SAVE_CONTROL // Leisre Poswer Save : Disable RF if connected but traffic is not busy // bool bLeisurePs; + u32 PowerProfile; + u8 LpsIdleCount; + u8 RegMaxLPSAwakeIntvl; + u8 LPSAwakeIntvl; + + u32 CurPsLevel; + u32 RegRfPsLevel; + + bool bFwCtrlLPS; + u8 FWCtrlPSMode; + + bool LinkReqInIPSRFOffPgs; + bool BufConnectinfoBefore; }RT_POWER_SAVE_CONTROL,*PRT_POWER_SAVE_CONTROL; @@ -1905,14 +1929,121 @@ typedef struct _RT_LINK_DETECT_T{ u32 NumTxOkInPeriod; u32 NumRxOkInPeriod; + u32 NumRxUnicastOkInPeriod; bool bBusyTraffic; }RT_LINK_DETECT_T, *PRT_LINK_DETECT_T; +//added by amy 090330 +typedef enum _HW_VARIABLES{ + HW_VAR_ETHER_ADDR, + HW_VAR_MULTICAST_REG, + HW_VAR_BASIC_RATE, + HW_VAR_BSSID, + HW_VAR_MEDIA_STATUS, + HW_VAR_SECURITY_CONF, + HW_VAR_BEACON_INTERVAL, + HW_VAR_ATIM_WINDOW, + HW_VAR_LISTEN_INTERVAL, + HW_VAR_CS_COUNTER, + HW_VAR_DEFAULTKEY0, + HW_VAR_DEFAULTKEY1, + HW_VAR_DEFAULTKEY2, + HW_VAR_DEFAULTKEY3, + HW_VAR_SIFS, + HW_VAR_DIFS, + HW_VAR_EIFS, + HW_VAR_SLOT_TIME, + HW_VAR_ACK_PREAMBLE, + HW_VAR_CW_CONFIG, + HW_VAR_CW_VALUES, + HW_VAR_RATE_FALLBACK_CONTROL, + HW_VAR_CONTENTION_WINDOW, + HW_VAR_RETRY_COUNT, + HW_VAR_TR_SWITCH, + HW_VAR_COMMAND, // For Command Register, Annie, 2006-04-07. + HW_VAR_WPA_CONFIG, //2004/08/23, kcwu, for 8187 Security config + HW_VAR_AMPDU_MIN_SPACE, // The spacing between sub-frame. Roger, 2008.07.04. + HW_VAR_SHORTGI_DENSITY, // The density for shortGI. Roger, 2008.07.04. + HW_VAR_AMPDU_FACTOR, + HW_VAR_MCS_RATE_AVAILABLE, + HW_VAR_AC_PARAM, // For AC Parameters, 2005.12.01, by rcnjko. + HW_VAR_ACM_CTRL, // For ACM Control, Annie, 2005-12-13. + HW_VAR_DIS_Req_Qsize, // For DIS_Reg_Qsize, Joseph + HW_VAR_CCX_CHNL_LOAD, // For CCX 2 channel load request, 2006.05.04. + HW_VAR_CCX_NOISE_HISTOGRAM, // For CCX 2 noise histogram request, 2006.05.04. + HW_VAR_CCX_CLM_NHM, // For CCX 2 parallel channel load request and noise histogram request, 2006.05.12. + HW_VAR_TxOPLimit, // For turbo mode related settings, added by Roger, 2006.12.07 + HW_VAR_TURBO_MODE, // For turbo mode related settings, added by Roger, 2006.12.15. + HW_VAR_RF_STATE, // For change or query RF power state, 061214, rcnjko. + HW_VAR_RF_OFF_BY_HW, // For UI to query if external HW signal disable RF, 061229, rcnjko. + HW_VAR_BUS_SPEED, // In unit of bps. 2006.07.03, by rcnjko. + HW_VAR_SET_DEV_POWER, // Set to low power, added by LanHsin, 2007. + + //1!!!!!!!!!!!!!!!!!!!!!!!!!!! + //1Attention Please!!!<11n or 8190 specific code should be put below this line> + //1!!!!!!!!!!!!!!!!!!!!!!!!!!! + HW_VAR_RCR, //for RCR, David 2006,05,11 + HW_VAR_RATR_0, + HW_VAR_RRSR, + HW_VAR_CPU_RST, + HW_VAR_CECHK_BSSID, + HW_VAR_LBK_MODE, // Set lookback mode, 2008.06.11. added by Roger. + // Set HW related setting for 11N AES bug. + HW_VAR_AES_11N_FIX, + // Set Usb Rx Aggregation + HW_VAR_USB_RX_AGGR, + HW_VAR_USER_CONTROL_TURBO_MODE, + HW_VAR_RETRY_LIMIT, +#ifndef _RTL8192_EXT_PATCH_ + HW_VAR_INIT_TX_RATE, //Get Current Tx rate register. 2008.12.10. Added by tynli +#endif + HW_VAR_TX_RATE_REG, //Get Current Tx rate register. 2008.12.10. Added by tynli + HW_VAR_EFUSE_USAGE, //Get current EFUSE utilization. 2008.12.19. Added by Roger. + HW_VAR_EFUSE_BYTES, + HW_VAR_AUTOLOAD_STATUS, //Get current autoload status, 0: autoload success, 1: autoload fail. 2008.12.19. Added by Roger. + HW_VAR_RF_2R_DISABLE, // 2R disable + HW_VAR_SET_RPWM, + HW_VAR_H2C_FW_PWRMODE, // For setting FW related H2C cmd structure. by tynli. 2009.2.18 + HW_VAR_H2C_FW_JOINBSSRPT, // For setting FW related H2C cmd structure. by tynli. 2009.2.18 + HW_VAR_1X1_RECV_COMBINE, // For 1T2R but only 1SS, Add by hpfan 2009.04.16 hpfan + HW_VAR_STOP_SEND_BEACON, + HW_VAR_TSF_TIMER, // Read from TSF register to get the current TSF timer, by Bruce, 2009-07-22. + HW_VAR_IO_CMD, + HW_VAR_HANDLE_FW_C2H, //Added by tynli. For handling FW C2H command. 2009.10.07. + HW_VAR_DL_FW_RSVD_PAGE, //Added by tynli. Download the packets that FW will use to RSVD page. 2009.10.14. + HW_VAR_AID, //Added by tynli. + HW_VAR_HW_SEQ_ENABLE, //Added by tynli. 2009.10.20. + HW_VAR_UPDATE_TSF, //Added by tynli. 2009.10.22. For Hw count TBTT time. + HW_VAR_BCN_VALID, //Added by tynli. + HW_VAR_FWLPS_RF_ON //Added by tynli. 2009.11.09. For checking if Fw finishs RF on sequence. +}HW_VARIABLES; + +#define RT_CHECK_FOR_HANG_PERIOD 2 struct ieee80211_device { struct net_device *dev; struct ieee80211_security sec; + bool need_sw_enc; +#ifdef ENABLE_LPS + bool bAwakePktSent; + u8 LPSDelayCnt; + bool bIsAggregateFrame; + bool polling; + void (*LeisurePSLeave)(struct net_device *dev); +#endif + +#ifdef ENABLE_IPS + bool proto_stoppping; + bool wx_set_enc; + struct semaphore ips_sem; + struct work_struct ips_leave_wq; + void (*ieee80211_ips_leave_wq) (struct net_device *dev); + void (*ieee80211_ips_leave)(struct net_device *dev); +#endif + void (*SetHwRegHandler)(struct net_device *dev,u8 variable,u8* val); + u8 (*rtllib_ap_sec_type)(struct ieee80211_device *ieee); + //hw security related // u8 hwsec_support; //support? u8 hwsec_active; //hw security active. @@ -2319,7 +2450,7 @@ struct ieee80211_device { * stop_send_bacons is NOT guaranteed to be called only * after start_send_beacons. */ - void (*start_send_beacons) (struct net_device *dev,u16 tx_rate); + void (*start_send_beacons) (struct net_device *dev); void (*stop_send_beacons) (struct net_device *dev); /* power save mode related */ @@ -2373,6 +2504,19 @@ struct ieee80211_device { u8 priv[0]; }; +#define RT_RF_OFF_LEVL_ASPM BIT0 // PCI ASPM +#define RT_RF_OFF_LEVL_CLK_REQ BIT1 // PCI clock request +#define RT_RF_OFF_LEVL_PCI_D3 BIT2 // PCI D3 mode +#define RT_RF_OFF_LEVL_HALT_NIC BIT3 // NIC halt, re-initialize hw parameters +#define RT_RF_OFF_LEVL_FREE_FW BIT4 // FW free, re-download the FW +#define RT_RF_OFF_LEVL_FW_32K BIT5 // FW in 32k +#define RT_RF_PS_LEVEL_ALWAYS_ASPM BIT6 // Always enable ASPM and Clock Req in initialization. +#define RT_RF_LPS_DISALBE_2R BIT30 // When LPS is on, disable 2R if no packet is received or transmittd. +#define RT_RF_LPS_LEVEL_ASPM BIT31 // LPS with ASPM +#define RT_IN_PS_LEVEL(pPSC, _PS_FLAG) ((pPSC->CurPsLevel & _PS_FLAG) ? true : false) +#define RT_CLEAR_PS_LEVEL(pPSC, _PS_FLAG) (pPSC->CurPsLevel &= (~(_PS_FLAG))) +#define RT_SET_PS_LEVEL(pPSC, _PS_FLAG) (pPSC->CurPsLevel |= _PS_FLAG) + #define IEEE_A (1<<0) #define IEEE_B (1<<1) #define IEEE_G (1<<2) @@ -2609,9 +2753,9 @@ extern void ieee80211_stop_scan(struct ieee80211_device *ieee); extern void ieee80211_start_scan_syncro(struct ieee80211_device *ieee); extern void ieee80211_check_all_nets(struct ieee80211_device *ieee); extern void ieee80211_start_protocol(struct ieee80211_device *ieee); -extern void ieee80211_stop_protocol(struct ieee80211_device *ieee); +extern void ieee80211_stop_protocol(struct ieee80211_device *ieee,u8 shutdown); extern void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee); -extern void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee); +extern void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee,u8 shutdown); extern void ieee80211_reset_queue(struct ieee80211_device *ieee); extern void ieee80211_rtl_wake_queue(struct ieee80211_device *ieee); extern void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee); @@ -2798,5 +2942,7 @@ extern int ieee80211_parse_info_param(struct ieee80211_device *ieee, struct ieee80211_rx_stats *stats); void ieee80211_indicate_packets(struct ieee80211_device *ieee, struct ieee80211_rxb** prxbIndicateArray,u8 index); +void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee, short pwr); +void ieee80211_sta_ps_send_pspoll_frame(struct ieee80211_device *ieee); #define RT_ASOC_RETRY_LIMIT 5 #endif /* IEEE80211_H */ diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.c index b1c5493..b3c9bf4 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.c @@ -225,7 +225,7 @@ out: } -void __exit ieee80211_crypto_deinit(void) +void ieee80211_crypto_deinit(void) { struct list_head *ptr, *n; diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_ccmp.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_ccmp.c index ab871b3..1776f7e 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_ccmp.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_ccmp.c @@ -331,7 +331,7 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) if (!(keyidx & (1 << 5))) { if (net_ratelimit()) { printk(KERN_DEBUG "CCMP: received packet without ExtIV" - " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2)); + " flag from %pM\n", hdr->addr2); } key->dot11RSNAStatsCCMPFormatErrors++; return -2; @@ -344,9 +344,9 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) } if (!key->key_set) { if (net_ratelimit()) { - printk(KERN_DEBUG "CCMP: received packet from " MAC_FMT + printk(KERN_DEBUG "CCMP: received packet from %pM" " with keyid=%d that does not have a configured" - " key\n", MAC_ARG(hdr->addr2), keyidx); + " key\n", hdr->addr2, keyidx); } return -3; } @@ -361,11 +361,9 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) { if (net_ratelimit()) { - printk(KERN_DEBUG "CCMP: replay detected: STA=" MAC_FMT - " previous PN %02x%02x%02x%02x%02x%02x " - "received PN %02x%02x%02x%02x%02x%02x\n", - MAC_ARG(hdr->addr2), MAC_ARG(key->rx_pn), - MAC_ARG(pn)); + //printk(KERN_DEBUG "CCMP: replay detected: STA=%pM" + // " previous PN %pm received PN %pm\n", + // hdr->addr2, key->rx_pn, pn); } key->dot11RSNAStatsCCMPReplays++; return -4; @@ -402,7 +400,7 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) if (memcmp(mic, a, CCMP_MIC_LEN) != 0) { if (net_ratelimit()) { printk(KERN_DEBUG "CCMP: decrypt failed: STA=" - MAC_FMT "\n", MAC_ARG(hdr->addr2)); + "%pM\n", hdr->addr2); } key->dot11RSNAStatsCCMPDecryptErrors++; return -5; @@ -477,12 +475,19 @@ static int ieee80211_ccmp_get_key(void *key, int len, u8 *seq, void *priv) static char * ieee80211_ccmp_print_stats(char *p, void *priv) { struct ieee80211_ccmp_data *ccmp = priv; - p += sprintf(p, "key[%d] alg=CCMP key_set=%d " - "tx_pn=%02x%02x%02x%02x%02x%02x " - "rx_pn=%02x%02x%02x%02x%02x%02x " - "format_errors=%d replays=%d decrypt_errors=%d\n", - ccmp->key_idx, ccmp->key_set, - MAC_ARG(ccmp->tx_pn), MAC_ARG(ccmp->rx_pn), + int i; + + p += sprintf(p, "key[%d] alg=CCMP key_set=%d tx_pn=", + ccmp->key_idx, ccmp->key_set); + + for (i = 0; i < ARRAY_SIZE(ccmp->tx_pn); i++) + p += sprintf(p, "%02x", ccmp->tx_pn[i]); + + sprintf(p, " rx_pn="); + for (i = 0; i < ARRAY_SIZE(ccmp->rx_pn); i++) + p += sprintf(p, "%02x", ccmp->tx_pn[i]); + + p += sprintf(p, " format_errors=%d replays=%d decrypt_errors=%d\n", ccmp->dot11RSNAStatsCCMPFormatErrors, ccmp->dot11RSNAStatsCCMPReplays, ccmp->dot11RSNAStatsCCMPDecryptErrors); @@ -519,7 +524,7 @@ int __init ieee80211_crypto_ccmp_init(void) } -void __exit ieee80211_crypto_ccmp_exit(void) +void ieee80211_crypto_ccmp_exit(void) { ieee80211_unregister_crypto_ops(&ieee80211_crypt_ccmp); } diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_tkip.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_tkip.c index 7a1797e..03cb21e 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_tkip.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_tkip.c @@ -520,7 +520,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) if (!(keyidx & (1 << 5))) { if (net_ratelimit()) { printk(KERN_DEBUG "TKIP: received packet without ExtIV" - " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2)); + " flag from %pM\n", hdr->addr2); } return -2; } @@ -532,9 +532,9 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) } if (!tkey->key_set) { if (net_ratelimit()) { - printk(KERN_DEBUG "TKIP: received packet from " MAC_FMT + printk(KERN_DEBUG "TKIP: received packet from %pM" " with keyid=%d that does not have a configured" - " key\n", MAC_ARG(hdr->addr2), keyidx); + " key\n", hdr->addr2, keyidx); } return -3; } @@ -547,9 +547,9 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) if (iv32 < tkey->rx_iv32 || (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) { if (net_ratelimit()) { - printk(KERN_DEBUG "TKIP: replay detected: STA=" MAC_FMT + printk(KERN_DEBUG "TKIP: replay detected: STA=%pM" " previous TSC %08x%04x received TSC " - "%08x%04x\n", MAC_ARG(hdr->addr2), + "%08x%04x\n", hdr->addr2, tkey->rx_iv32, tkey->rx_iv16, iv32, iv16); } tkey->dot11RSNAStatsTKIPReplays++; @@ -582,8 +582,8 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) { if (net_ratelimit()) { printk(KERN_DEBUG ": TKIP: failed to decrypt " - "received packet from " MAC_FMT "\n", - MAC_ARG(hdr->addr2)); + "received packet from %pM\n", + hdr->addr2); } return -7; } @@ -606,8 +606,9 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) tkey->rx_phase1_done = 0; } if (net_ratelimit()) { - printk(KERN_DEBUG "TKIP: ICV error detected: STA=" - MAC_FMT "\n", MAC_ARG(hdr->addr2)); + printk(KERN_DEBUG + "TKIP: ICV error detected: STA=%pM\n", + hdr->addr2); } tkey->dot11RSNAStatsTKIPICVErrors++; return -5; @@ -816,8 +817,8 @@ static void ieee80211_michael_mic_failure(struct net_device *dev, /* TODO: needed parameters: count, keyid, key type, TSC */ sprintf(buf, "MLME-MICHAELMICFAILURE.indication(keyid=%d %scast addr=" - MAC_FMT ")", keyidx, hdr->addr1[0] & 0x01 ? "broad" : "uni", - MAC_ARG(hdr->addr2)); + "%pM)", keyidx, hdr->addr1[0] & 0x01 ? "broad" : "uni", + hdr->addr2); memset(&wrqu, 0, sizeof(wrqu)); wrqu.data.length = strlen(buf); wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf); @@ -862,8 +863,8 @@ static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx, struct ieee80211_hdr_4addr *hdr; hdr = (struct ieee80211_hdr_4addr *) skb->data; printk(KERN_DEBUG "%s: Michael MIC verification failed for " - "MSDU from " MAC_FMT " keyidx=%d\n", - skb->dev ? skb->dev->name : "N/A", MAC_ARG(hdr->addr2), + "MSDU from %pM keyidx=%d\n", + skb->dev ? skb->dev->name : "N/A", hdr->addr2, keyidx); if (skb->dev) ieee80211_michael_mic_failure(skb->dev, hdr, keyidx); @@ -1011,7 +1012,7 @@ int __init ieee80211_crypto_tkip_init(void) } -void __exit ieee80211_crypto_tkip_exit(void) +void ieee80211_crypto_tkip_exit(void) { ieee80211_unregister_crypto_ops(&ieee80211_crypt_tkip); } diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c index 06d9171..ce265ae 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c @@ -312,6 +312,17 @@ static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee, if (skb->len < 24) return 0; +#if 1 + if (ieee->hwsec_active) + { + cb_desc *tcb_desc = (cb_desc *)(skb->cb+ MAX_DEV_ADDR_SIZE); + tcb_desc->bHwSec = 1; + + if(ieee->need_sw_enc) + tcb_desc->bHwSec = 0; + } +#endif + hdr = (struct ieee80211_hdr_4addr *) skb->data; fc = le16_to_cpu(hdr->frame_ctl); @@ -366,8 +377,8 @@ ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb, strcmp(crypt->ops->name, "TKIP") == 0) { if (net_ratelimit()) { printk(KERN_DEBUG "%s: TKIP countermeasures: dropped " - "received packet from " MAC_FMT "\n", - ieee->dev->name, MAC_ARG(hdr->addr2)); + "received packet from %pM\n", + ieee->dev->name, hdr->addr2); } return -1; } @@ -378,8 +389,8 @@ ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb, atomic_dec(&crypt->refcnt); if (res < 0) { IEEE80211_DEBUG_DROP( - "decryption failed (SA=" MAC_FMT - ") res=%d\n", MAC_ARG(hdr->addr2), res); + "decryption failed (SA=%pM" + ") res=%d\n", hdr->addr2, res); if (res == -2) IEEE80211_DEBUG_DROP("Decryption failed ICV " "mismatch (key %d)\n", @@ -406,6 +417,10 @@ ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device* ieee, struct sk_buff *s { cb_desc *tcb_desc = (cb_desc *)(skb->cb+ MAX_DEV_ADDR_SIZE); tcb_desc->bHwSec = 1; + + if(ieee->need_sw_enc) + tcb_desc->bHwSec = 0; + } hdr = (struct ieee80211_hdr_4addr *) skb->data; @@ -416,8 +431,8 @@ ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device* ieee, struct sk_buff *s atomic_dec(&crypt->refcnt); if (res < 0) { printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed" - " (SA=" MAC_FMT " keyidx=%d)\n", - ieee->dev->name, MAC_ARG(hdr->addr2), keyidx); + " (SA=%pM keyidx=%d)\n", + ieee->dev->name, hdr->addr2, keyidx); return -1; } @@ -799,7 +814,7 @@ void RxReorderIndicatePacket( struct ieee80211_device *ieee, #endif } -u8 parse_subframe(struct sk_buff *skb, +u8 parse_subframe(struct ieee80211_device* ieee,struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats, struct ieee80211_rxb *rxb,u8* src,u8* dst) { @@ -839,6 +854,7 @@ u8 parse_subframe(struct sk_buff *skb, } skb_pull(skb, LLCOffset); + ieee->bIsAggregateFrame = bIsAggregateFrame;//added by amy for Leisure PS if(!bIsAggregateFrame) { rxb->nr_subframes = 1; @@ -940,6 +956,7 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, u8 TID = 0; u16 SeqNum = 0; PRX_TS_RECORD pTS = NULL; + bool unicast_packet = false; //bool bIsAggregateFrame = false; //added by amy for reorder #ifdef NOT_YET @@ -1045,8 +1062,8 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, * frames silently instead of filling system log with * these reports. */ IEEE80211_DEBUG_DROP("Decryption failed (not set)" - " (SA=" MAC_FMT ")\n", - MAC_ARG(hdr->addr2)); + " (SA=%pM)\n", + hdr->addr2); ieee->ieee_stats.rx_discards_undecryptable++; goto rx_dropped; } @@ -1114,8 +1131,8 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, (keyidx = hostap_rx_frame_decrypt(ieee, skb, crypt)) < 0) { printk(KERN_DEBUG "%s: failed to decrypt mgmt::auth " - "from " MAC_FMT "\n", dev->name, - MAC_ARG(hdr->addr2)); + "from %pM\n", dev->name, + hdr->addr2); /* TODO: could inform hostapd about this so that it * could send auth failure report */ goto rx_dropped; @@ -1215,6 +1232,24 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, if (memcmp(bssid, ieee->current_network.bssid, ETH_ALEN)) goto rx_dropped; +#ifdef ENABLE_LPS + if ((ieee->iw_mode == IW_MODE_INFRA) && (ieee->sta_sleep == 1) + && (ieee->polling)) { + if (WLAN_FC_MORE_DATA(fc)) { + /* more data bit is set, let's request a new frame from the AP */ + ieee80211_sta_ps_send_pspoll_frame(ieee); + } else { + ieee->polling = false; + } + } +#endif + + ieee->need_sw_enc = 0; + + if((!rx_stats->Decrypted)){ + ieee->need_sw_enc = 1; + } + /* skb: hdr + (possibly fragmented, possibly encrypted) payload */ if (ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) && @@ -1296,6 +1331,9 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, ieee->LinkDetectInfo.NumRxOkInPeriod++; hdr = (struct ieee80211_hdr_4addr *) skb->data; + if((!is_multicast_ether_addr(hdr->addr1)) && (!is_broadcast_ether_addr(hdr->addr1))) + unicast_packet = true; + if (crypt && !(fc & IEEE80211_FCTL_WEP) && !ieee->open_wep) { if (/*ieee->ieee802_1x &&*/ ieee80211_is_eapol_frame(ieee, skb, hdrlen)) { @@ -1311,8 +1349,8 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, } else { IEEE80211_DEBUG_DROP( "encryption configured, but RX " - "frame not encrypted (SA=" MAC_FMT ")\n", - MAC_ARG(hdr->addr2)); + "frame not encrypted (SA=%pM)\n", + hdr->addr2); goto rx_dropped; } } @@ -1331,9 +1369,9 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, !ieee80211_is_eapol_frame(ieee, skb, hdrlen)) { IEEE80211_DEBUG_DROP( "dropped unencrypted RX data " - "frame from " MAC_FMT + "frame from %pM" " (drop_unencrypted=1)\n", - MAC_ARG(hdr->addr2)); + hdr->addr2); goto rx_dropped; } /* @@ -1367,7 +1405,7 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, } /* to parse amsdu packets */ /* qos data packets & reserved bit is 1 */ - if(parse_subframe(skb,rx_stats,rxb,src,dst) == 0) { + if(parse_subframe(ieee, skb,rx_stats,rxb,src,dst) == 0) { /* only to free rxb, and not submit the packets to upper layer */ for(i =0; i < rxb->nr_subframes; i++) { dev_kfree_skb(rxb->subframes[i]); @@ -1377,6 +1415,32 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, goto rx_dropped; } +#ifdef ENABLE_LPS + if(unicast_packet) + { + if (type == IEEE80211_FTYPE_DATA) + { + + if(ieee->bIsAggregateFrame) + ieee->LinkDetectInfo.NumRxUnicastOkInPeriod+=rxb->nr_subframes; + else + ieee->LinkDetectInfo.NumRxUnicastOkInPeriod++; + + // 2009.03.03 Leave DC mode immediately when detect high traffic + // DbgPrint("ending Seq %d\n", Frame_SeqNum(pduOS)); + if((ieee->state == IEEE80211_LINKED) /*&& !MgntInitAdapterInProgress(pMgntInfo)*/) + { + if( ((ieee->LinkDetectInfo.NumRxUnicastOkInPeriod +ieee->LinkDetectInfo.NumTxOkInPeriod) > 8 ) || + (ieee->LinkDetectInfo.NumRxUnicastOkInPeriod > 2) ) + { + if(ieee->LeisurePSLeave) + ieee->LeisurePSLeave(dev); + } + } + } + } +#endif + ieee->last_rx_ps_time = jiffies; //added by amy for reorder if(ieee->pHTInfo->bCurRxReorderEnable == false ||pTS == NULL){ @@ -2013,12 +2077,22 @@ int ieee80211_parse_info_param(struct ieee80211_device *ieee, info_element->data[1] == 0x13 && info_element->data[2] == 0x74)) { - printk("========>%s(): athros AP is exist\n",__FUNCTION__); + //printk("========>%s(): athros AP is exist\n",__FUNCTION__); network->atheros_cap_exist = true; } else network->atheros_cap_exist = false; + if ((info_element->len >= 3 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0x50 && + info_element->data[2] == 0x43) ) + { + network->marvell_cap_exist = true; + //printk("========>%s(): marvel AP is exist\n",__FUNCTION__); + } + + if(info_element->len >= 3 && info_element->data[0] == 0x00 && info_element->data[1] == 0x40 && @@ -2219,7 +2293,8 @@ int ieee80211_parse_info_param(struct ieee80211_device *ieee, } if(!network->atheros_cap_exist && !network->broadcom_cap_exist && - !network->cisco_cap_exist && !network->ralink_cap_exist && !network->bssht.bdRT2RTAggregation) + !network->cisco_cap_exist && !network->ralink_cap_exist && !network->bssht.bdRT2RTAggregation && + !network->marvell_cap_exist) { network->unknown_cap_exist = true; } @@ -2333,6 +2408,7 @@ static inline int ieee80211_network_init( network->broadcom_cap_exist = false; network->ralink_cap_exist = false; network->atheros_cap_exist = false; + network->marvell_cap_exist = false; network->cisco_cap_exist = false; network->unknown_cap_exist = false; #ifdef THOMAS_TURBO @@ -2369,11 +2445,11 @@ static inline int ieee80211_network_init( } if (network->mode == 0) { - IEEE80211_DEBUG_SCAN("Filtered out '%s (" MAC_FMT ")' " + IEEE80211_DEBUG_SCAN("Filtered out '%s (%pM)' " "network.\n", escape_essid(network->ssid, network->ssid_len), - MAC_ARG(network->bssid)); + network->bssid); return 1; } @@ -2463,6 +2539,7 @@ static inline void update_network(struct ieee80211_network *dst, dst->broadcom_cap_exist = src->broadcom_cap_exist; dst->ralink_cap_exist = src->ralink_cap_exist; dst->atheros_cap_exist = src->atheros_cap_exist; + dst->marvell_cap_exist = src->marvell_cap_exist; dst->cisco_cap_exist = src->cisco_cap_exist; dst->unknown_cap_exist = src->unknown_cap_exist; memcpy(dst->wpa_ie, src->wpa_ie, src->wpa_ie_len); @@ -2557,9 +2634,9 @@ static inline void ieee80211_process_probe_response( memset(&network, 0, sizeof(struct ieee80211_network)); IEEE80211_DEBUG_SCAN( - "'%s' (" MAC_FMT "): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n", + "'%s' (%pM): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n", escape_essid(info_element->data, info_element->len), - MAC_ARG(beacon->header.addr3), + beacon->header.addr3, (beacon->capability & (1<<0xf)) ? '1' : '0', (beacon->capability & (1<<0xe)) ? '1' : '0', (beacon->capability & (1<<0xd)) ? '1' : '0', @@ -2578,10 +2655,10 @@ static inline void ieee80211_process_probe_response( (beacon->capability & (1<<0x0)) ? '1' : '0'); if (ieee80211_network_init(ieee, beacon, &network, stats)) { - IEEE80211_DEBUG_SCAN("Dropped '%s' (" MAC_FMT ") via %s.\n", + IEEE80211_DEBUG_SCAN("Dropped '%s' (%pM) via %s.\n", escape_essid(info_element->data, info_element->len), - MAC_ARG(beacon->header.addr3), + beacon->header.addr3, WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_PROBE_RESP ? "PROBE RESPONSE" : "BEACON"); @@ -2692,11 +2769,11 @@ static inline void ieee80211_process_probe_response( /* If there are no more slots, expire the oldest */ list_del(&oldest->list); target = oldest; - IEEE80211_DEBUG_SCAN("Expired '%s' (" MAC_FMT ") from " + IEEE80211_DEBUG_SCAN("Expired '%s' (%pM) from " "network list.\n", escape_essid(target->ssid, target->ssid_len), - MAC_ARG(target->bssid)); + target->bssid); } else { /* Otherwise just pull from the free list */ target = list_entry(ieee->network_free_list.next, @@ -2706,10 +2783,10 @@ static inline void ieee80211_process_probe_response( #ifdef CONFIG_IEEE80211_DEBUG - IEEE80211_DEBUG_SCAN("Adding '%s' (" MAC_FMT ") via %s.\n", + IEEE80211_DEBUG_SCAN("Adding '%s' (%pM) via %s.\n", escape_essid(network.ssid, network.ssid_len), - MAC_ARG(network.bssid), + network.bssid, WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_PROBE_RESP ? "PROBE RESPONSE" : "BEACON"); @@ -2719,10 +2796,10 @@ static inline void ieee80211_process_probe_response( if(ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) ieee80211_softmac_new_net(ieee,&network); } else { - IEEE80211_DEBUG_SCAN("Updating '%s' (" MAC_FMT ") via %s.\n", + IEEE80211_DEBUG_SCAN("Updating '%s' (%pM) via %s.\n", escape_essid(target->ssid, target->ssid_len), - MAC_ARG(target->bssid), + target->bssid, WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_PROBE_RESP ? "PROBE RESPONSE" : "BEACON"); @@ -2761,12 +2838,14 @@ void ieee80211_rx_mgt(struct ieee80211_device *ieee, struct ieee80211_hdr_4addr *header, struct ieee80211_rx_stats *stats) { +#if 0 if(ieee->sta_sleep || (ieee->ps != IEEE80211_PS_DISABLED && ieee->iw_mode == IW_MODE_INFRA && ieee->state == IEEE80211_LINKED)) { tasklet_schedule(&ieee->ps_task); } +#endif if(WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_PROBE_RESP && WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_BEACON) @@ -2780,6 +2859,15 @@ void ieee80211_rx_mgt(struct ieee80211_device *ieee, IEEE80211_DEBUG_SCAN("Beacon\n"); ieee80211_process_probe_response( ieee, (struct ieee80211_probe_response *)header, stats); + + //printk("----------->%s()\n", __func__); + if(ieee->sta_sleep || (ieee->ps != IEEE80211_PS_DISABLED && + ieee->iw_mode == IW_MODE_INFRA && + ieee->state == IEEE80211_LINKED)) + { + tasklet_schedule(&ieee->ps_task); + } + break; case IEEE80211_STYPE_PROBE_RESP: diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c index 6d1ddec..ea96c49 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c @@ -646,7 +646,7 @@ void ieee80211_stop_send_beacons(struct ieee80211_device *ieee) void ieee80211_start_send_beacons(struct ieee80211_device *ieee) { if(ieee->start_send_beacons) - ieee->start_send_beacons(ieee->dev,ieee->basic_rate); + ieee->start_send_beacons(ieee->dev); if(ieee->softmac_features & IEEE_SOFTMAC_BEACONS) ieee80211_beacons_start(ieee); } @@ -686,6 +686,11 @@ void ieee80211_stop_scan(struct ieee80211_device *ieee) /* called with ieee->lock held */ void ieee80211_rtl_start_scan(struct ieee80211_device *ieee) { +#ifdef ENABLE_IPS + if(ieee->ieee80211_ips_leave_wq != NULL) + ieee->ieee80211_ips_leave_wq(ieee->dev); +#endif + #ifdef ENABLE_DOT11D if(IS_DOT11D_ENABLE(ieee) ) { @@ -1093,6 +1098,40 @@ struct sk_buff* ieee80211_null_func(struct ieee80211_device *ieee,short pwr) } +struct sk_buff* ieee80211_pspoll_func(struct ieee80211_device *ieee) +{ + struct sk_buff *skb; + struct ieee80211_pspoll_hdr* hdr; + +#ifdef USB_USE_ALIGNMENT + u32 Tmpaddr=0; + int alignment=0; + skb = dev_alloc_skb(sizeof(struct ieee80211_pspoll_hdr) + ieee->tx_headroom + USB_512B_ALIGNMENT_SIZE); +#else + skb = dev_alloc_skb(sizeof(struct ieee80211_pspoll_hdr)+ieee->tx_headroom); +#endif + if (!skb) + return NULL; + +#ifdef USB_USE_ALIGNMENT + Tmpaddr = (u32)skb->data; + alignment = Tmpaddr & 0x1ff; + skb_reserve(skb,(USB_512B_ALIGNMENT_SIZE - alignment)); +#endif + skb_reserve(skb, ieee->tx_headroom); + + hdr = (struct ieee80211_pspoll_hdr*)skb_put(skb,sizeof(struct ieee80211_pspoll_hdr)); + + memcpy(hdr->bssid, ieee->current_network.bssid, ETH_ALEN); + memcpy(hdr->ta, ieee->dev->dev_addr, ETH_ALEN); + + hdr->aid = cpu_to_le16(ieee->assoc_id | 0xc000); + hdr->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_CTL |IEEE80211_STYPE_PSPOLL | IEEE80211_FCTL_PM); + + return skb; + +} + void ieee80211_resp_to_assoc_rq(struct ieee80211_device *ieee, u8* dest) { @@ -1582,6 +1621,11 @@ void ieee80211_associate_procedure_wq(struct ieee80211_device *ieee) { #endif ieee->sync_scan_hurryup = 1; +#ifdef ENABLE_IPS + if(ieee->ieee80211_ips_leave != NULL) + ieee->ieee80211_ips_leave(ieee->dev); +#endif + down(&ieee->wx_sem); if (ieee->data_hard_stop) @@ -1592,6 +1636,17 @@ void ieee80211_associate_procedure_wq(struct ieee80211_device *ieee) //ieee->set_chan(ieee->dev, ieee->current_network.channel); HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT); +#ifdef ENABLE_IPS + if(ieee->eRFPowerState == eRfOff) + { + if(ieee->ieee80211_ips_leave_wq != NULL) + ieee->ieee80211_ips_leave_wq(ieee->dev); + + up(&ieee->wx_sem); + return; + } +#endif + ieee->associate_seq = 1; ieee80211_associate_step1(ieee); @@ -1897,7 +1952,7 @@ ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb) ieee80211_resp_to_assoc_rq(ieee, dest); } - printk(KERN_INFO"New client associated: "MAC_FMT"\n", MAC_ARG(dest)); + printk(KERN_INFO"New client associated: %pM\n", dest); //FIXME #if 0 spin_lock_irqsave(&ieee->lock,flags); @@ -1918,43 +1973,92 @@ void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee, short pwr) } +void ieee80211_sta_ps_send_pspoll_frame(struct ieee80211_device *ieee) +{ + + struct sk_buff *buf = ieee80211_pspoll_func(ieee); + + if (buf) + softmac_ps_mgmt_xmit(buf, ieee); + +} short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h, u32 *time_l) { int timeout = ieee->ps_timeout; u8 dtim; - /*if(ieee->ps == IEEE80211_PS_DISABLED || - ieee->iw_mode != IW_MODE_INFRA || - ieee->state != IEEE80211_LINKED) + PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(ieee->PowerSaveControl)); + if(ieee->LPSDelayCnt) + { + //printk("===============>Delay enter LPS for DHCP and ARP packets...\n"); + ieee->LPSDelayCnt --; return 0; - */ + } + dtim = ieee->current_network.dtim_data; - //printk("DTIM\n"); +// printk("%s():DTIM:%d\n",__FUNCTION__,dtim); if(!(dtim & IEEE80211_DTIM_VALID)) return 0; timeout = ieee->current_network.beacon_interval; //should we use ps_timeout value or beacon_interval //printk("VALID\n"); ieee->current_network.dtim_data = IEEE80211_DTIM_INVALID; - - if(dtim & ((IEEE80211_DTIM_UCAST | IEEE80211_DTIM_MBCAST)& ieee->ps)) + /* there's no need to nofity AP that I find you buffered with broadcast packet */ + if(dtim & (IEEE80211_DTIM_UCAST & ieee->ps)) return 2; - if(!time_after(jiffies, ieee->dev->trans_start + MSECS(timeout))) + if(!time_after(jiffies, ieee->dev->trans_start + MSECS(timeout))){ +// printk("%s():111Oh Oh ,it is not time out return 0\n",__FUNCTION__); return 0; - - if(!time_after(jiffies, ieee->last_rx_ps_time + MSECS(timeout))) + } + if(!time_after(jiffies, ieee->last_rx_ps_time + MSECS(timeout))){ +// printk("%s():222Oh Oh ,it is not time out return 0\n",__FUNCTION__); return 0; - + } if((ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE ) && (ieee->mgmt_queue_tail != ieee->mgmt_queue_head)) return 0; if(time_l){ + if(ieee->bAwakePktSent == true) { + pPSC->LPSAwakeIntvl = 1;//tx wake one beacon + } else { + u8 MaxPeriod = 1; + + if(pPSC->LPSAwakeIntvl == 0) + pPSC->LPSAwakeIntvl = 1; + //pNdisCommon->RegLPSMaxIntvl /// 0x0 - eFastPs, 0xFF -DTIM, 0xNN - 0xNN * BeaconIntvl + if(pPSC->RegMaxLPSAwakeIntvl == 0) // Default (0x0 - eFastPs, 0xFF -DTIM, 0xNN - 0xNN * BeaconIntvl) + MaxPeriod = 1; // 1 Beacon interval + else if(pPSC->RegMaxLPSAwakeIntvl == 0xFF) // DTIM + MaxPeriod = ieee->current_network.dtim_period; + else + MaxPeriod = pPSC->RegMaxLPSAwakeIntvl; + pPSC->LPSAwakeIntvl = (pPSC->LPSAwakeIntvl >= MaxPeriod) ? MaxPeriod : (pPSC->LPSAwakeIntvl + 1); + } + { + u8 LPSAwakeIntvl_tmp = 0; + u8 period = ieee->current_network.dtim_period; + u8 count = ieee->current_network.tim.tim_count; + if(count == 0 ) { + if(pPSC->LPSAwakeIntvl > period) + LPSAwakeIntvl_tmp = period + (pPSC->LPSAwakeIntvl - period) -((pPSC->LPSAwakeIntvl-period)%period); + else + LPSAwakeIntvl_tmp = pPSC->LPSAwakeIntvl; + + } else { + if(pPSC->LPSAwakeIntvl > ieee->current_network.tim.tim_count) + LPSAwakeIntvl_tmp = count + (pPSC->LPSAwakeIntvl - count) -((pPSC->LPSAwakeIntvl-count)%period); + else + LPSAwakeIntvl_tmp = pPSC->LPSAwakeIntvl;//ieee->current_network.tim.tim_count;//pPSC->LPSAwakeIntvl; + } + //printk("=========>%s()assoc_id:%d(%#x),bAwakePktSent:%d,DTIM:%d, sleep interval:%d, LPSAwakeIntvl_tmp:%d, count:%d\n",__func__,ieee->assoc_id,cpu_to_le16(ieee->assoc_id),ieee->bAwakePktSent,ieee->current_network.dtim_period,pPSC->LPSAwakeIntvl,LPSAwakeIntvl_tmp,count); + *time_l = ieee->current_network.last_dtim_sta_time[0] - + (ieee->current_network.beacon_interval); + + MSECS(ieee->current_network.beacon_interval * LPSAwakeIntvl_tmp); // * ieee->current_network.dtim_period) * 1000; } + } if(time_h){ *time_h = ieee->current_network.last_dtim_sta_time[1]; @@ -1982,6 +2086,8 @@ inline void ieee80211_sta_ps(struct ieee80211_device *ieee) ieee->state != IEEE80211_LINKED)){ // #warning CHECK_LOCK_HERE + printk("=====>%s(): no need to ps,wake up!! ieee->ps is %d,ieee->iw_mode is %d,ieee->state is %d\n", + __FUNCTION__,ieee->ps,ieee->iw_mode,ieee->state); spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2); ieee80211_sta_wakeup(ieee, 1); @@ -1991,27 +2097,27 @@ inline void ieee80211_sta_ps(struct ieee80211_device *ieee) sleep = ieee80211_sta_ps_sleep(ieee,&th, &tl); /* 2 wake, 1 sleep, 0 do nothing */ - if(sleep == 0) + if(sleep == 0)//it is not time out or dtim is not valid + { + //printk("===========>sleep is 0,do nothing\n"); goto out; - + } if(sleep == 1){ - - if(ieee->sta_sleep == 1) + //printk("===========>sleep is 1,to sleep\n"); + if(ieee->sta_sleep == 1){ + //printk("%s(1): sta_sleep = 1, sleep again ++++++++++ \n", __func__); ieee->enter_sleep_state(ieee->dev,th,tl); + } else if(ieee->sta_sleep == 0){ // printk("send null 1\n"); spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2); if(ieee->ps_is_queue_empty(ieee->dev)){ - - ieee->sta_sleep = 2; - ieee->ack_tx_to_ieee = 1; - + //printk("%s(2): sta_sleep = 0, notify AP we will sleeped ++++++++++ SendNullFunctionData\n", __func__); ieee80211_sta_ps_send_null_frame(ieee,1); - ieee->ps_th = th; ieee->ps_tl = tl; } @@ -2019,11 +2125,13 @@ inline void ieee80211_sta_ps(struct ieee80211_device *ieee) } + ieee->bAwakePktSent = false;//after null to power save we set it to false. not listen every beacon. }else if(sleep == 2){ -//#warning CHECK_LOCK_HERE + //printk("==========>sleep is 2,to wakeup\n"); spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2); + //printk("%s(3): pkt buffered in ap will awake ++++++++++ ieee80211_sta_wakeup\n", __func__); ieee80211_sta_wakeup(ieee,1); spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2); @@ -2038,9 +2146,19 @@ void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl) { if(ieee->sta_sleep == 0){ if(nl){ - printk("Warning: driver is probably failing to report TX ps error\n"); - ieee->ack_tx_to_ieee = 1; - ieee80211_sta_ps_send_null_frame(ieee, 0); + if(ieee->pHTInfo->IOTAction & HT_IOT_ACT_NULL_DATA_POWER_SAVING) + { + //printk("%s(1): notify AP we are awaked ++++++++++ SendNullFunctionData\n", __func__); + //printk("Warning: driver is probably failing to report TX ps error\n"); + ieee->ack_tx_to_ieee = 1; + ieee80211_sta_ps_send_null_frame(ieee, 0); + } + else + { + ieee->ack_tx_to_ieee = 1; + //printk("%s(2): notify AP we are awaked ++++++++++ Send PS-Poll\n", __func__); + ieee80211_sta_ps_send_pspoll_frame(ieee); + } } return; @@ -2048,12 +2166,27 @@ void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl) if(ieee->sta_sleep == 1) ieee->sta_wake_up(ieee->dev); + if(nl){ - ieee->sta_sleep = 0; + if(ieee->pHTInfo->IOTAction & HT_IOT_ACT_NULL_DATA_POWER_SAVING) + { + //printk("%s(3): notify AP we are awaked ++++++++++ SendNullFunctionData\n", __func__); + //printk("Warning: driver is probably failing to report TX ps error\n"); + ieee->ack_tx_to_ieee = 1; + ieee80211_sta_ps_send_null_frame(ieee, 0); + } + else + { + ieee->ack_tx_to_ieee = 1; + ieee->polling = true; + //printk("%s(4): notify AP we are awaked ++++++++++ Send PS-Poll\n", __func__); + //ieee80211_sta_ps_send_null_frame(ieee, 0); + ieee80211_sta_ps_send_pspoll_frame(ieee); + } - if(nl){ - ieee->ack_tx_to_ieee = 1; - ieee80211_sta_ps_send_null_frame(ieee, 0); + } else { + ieee->sta_sleep = 0; + ieee->polling = false; } } @@ -2067,23 +2200,30 @@ void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success) /* Null frame with PS bit set */ if(success){ ieee->sta_sleep = 1; + //printk("notify AP we will sleep and send null ok, so sleep now++++++++++ enter_sleep_state\n"); ieee->enter_sleep_state(ieee->dev,ieee->ps_th,ieee->ps_tl); } - /* if the card report not success we can't be sure the AP - * has not RXed so we can't assume the AP believe us awake - */ - } - /* 21112005 - tx again null without PS bit if lost */ - else { + } else {/* 21112005 - tx again null without PS bit if lost */ if((ieee->sta_sleep == 0) && !success){ spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2); - ieee80211_sta_ps_send_null_frame(ieee, 0); + //ieee80211_sta_ps_send_null_frame(ieee, 0); + if(ieee->pHTInfo->IOTAction & HT_IOT_ACT_NULL_DATA_POWER_SAVING) + { + //printk("notify AP we will sleep but send bull failed, so resend++++++++++ SendNullFunctionData\n"); + ieee80211_sta_ps_send_null_frame(ieee, 0); + } + else + { + //printk("notify AP we are awaked but send pspoll failed, so resend++++++++++ Send PS-Poll\n"); + ieee80211_sta_ps_send_pspoll_frame(ieee); + } spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2); } } spin_unlock_irqrestore(&ieee->lock, flags); } + void ieee80211_process_action(struct ieee80211_device* ieee, struct sk_buff* skb) { struct ieee80211_hdr* header = (struct ieee80211_hdr*)skb->data; @@ -2227,7 +2367,7 @@ ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb, { if (!ieee->GetNmodeSupportBySecCfg(ieee->dev)) { - // WEP or TKIP encryption + // WEP or TKIP encryption if(IsHTHalfNmodeAPs(ieee)) { bSupportNmode = true; @@ -2238,7 +2378,7 @@ ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb, bSupportNmode = false; bHalfSupportNmode = false; } - printk("==========>to link with AP using SEC(%d, %d)", bSupportNmode, bHalfSupportNmode); + printk("==========>to link with AP using SEC(%d, %d)\n", bSupportNmode, bHalfSupportNmode); } } /* Dummy wirless mode setting to avoid encryption issue */ @@ -2574,6 +2714,7 @@ void ieee80211_start_ibss_wq(struct ieee80211_device *ieee) ieee->ssid_set = 1; } + ieee->state = IEEE80211_NOLINK; /* check if we have this cell in our network list */ ieee80211_softmac_check_all_nets(ieee); @@ -2705,6 +2846,10 @@ void ieee80211_start_bss(struct ieee80211_device *ieee) spin_lock_irqsave(&ieee->lock, flags); if (ieee->state == IEEE80211_NOLINK){ +#ifdef ENABLE_IPS + if(ieee->ieee80211_ips_leave_wq != NULL) + ieee->ieee80211_ips_leave_wq(ieee->dev); +#endif ieee->actscanning = true; ieee80211_rtl_start_scan(ieee); } @@ -2823,21 +2968,23 @@ struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee) return skb; } -void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee) +void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee, u8 shutdown) { ieee->sync_scan_hurryup = 1; down(&ieee->wx_sem); - ieee80211_stop_protocol(ieee); + ieee80211_stop_protocol(ieee, shutdown); up(&ieee->wx_sem); } -void ieee80211_stop_protocol(struct ieee80211_device *ieee) +void ieee80211_stop_protocol(struct ieee80211_device *ieee, u8 shutdown) { if (!ieee->proto_started) return; - ieee->proto_started = 0; + if(shutdown) + ieee->proto_started = 0; + ieee->proto_stoppping = 1; ieee80211_stop_send_beacons(ieee); del_timer_sync(&ieee->associate_timer); @@ -2849,6 +2996,8 @@ void ieee80211_stop_protocol(struct ieee80211_device *ieee) ieee80211_disassociate(ieee); RemoveAllTS(ieee); //added as we disconnect from the previous BSS, Remove all TS + + ieee->proto_stoppping = 0; } void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee) @@ -2894,6 +3043,8 @@ void ieee80211_start_protocol(struct ieee80211_device *ieee) ieee->init_wmmparam_flag = 0;//reinitialize AC_xx_PARAM registers. + ieee->state = IEEE80211_NOLINK; + /* if the user set the MAC of the ad-hoc cell and then * switch to managed mode, shall we make sure that association @@ -3013,7 +3164,9 @@ void ieee80211_softmac_init(struct ieee80211_device *ieee) #endif sema_init(&ieee->wx_sem, 1); sema_init(&ieee->scan_sem, 1); - +#ifdef ENABLE_IPS + sema_init(&ieee->ips_sem,1); +#endif spin_lock_init(&ieee->mgmt_tx_lock); spin_lock_init(&ieee->beacon_lock); @@ -3537,5 +3690,6 @@ EXPORT_SYMBOL_NOVERS(ieee80211_stop_scan); EXPORT_SYMBOL_NOVERS(ieee80211_send_probe_requests); EXPORT_SYMBOL_NOVERS(ieee80211_softmac_scan_syncro); EXPORT_SYMBOL_NOVERS(ieee80211_start_scan_syncro); +EXPORT_SYMBOL_NOVERS(ieee80211_sta_ps_send_null_frame); +EXPORT_SYMBOL_NOVERS(ieee80211_sta_ps_send_pspoll_frame); #endif -//EXPORT_SYMBOL(ieee80211_sta_ps_send_null_frame); diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c index 7c21aaa..1bbd49f 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c @@ -160,7 +160,7 @@ int ieee80211_wx_set_wap(struct ieee80211_device *ieee, } if (ifup) - ieee80211_stop_protocol(ieee); + ieee80211_stop_protocol(ieee,true); /* just to avoid to give inconsistent infos in the * get wx method. not really needed otherwise @@ -302,7 +302,7 @@ int ieee80211_wx_set_mode(struct ieee80211_device *ieee, struct iw_request_info if (!ieee->proto_started){ ieee->iw_mode = wrqu->mode; }else{ - ieee80211_stop_protocol(ieee); + ieee80211_stop_protocol(ieee,true); ieee->iw_mode = wrqu->mode; ieee80211_start_protocol(ieee); } @@ -326,6 +326,17 @@ void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee) int b40M = 0; static int count = 0; chan = ieee->current_network.channel; + +#ifdef ENABLE_LPS + if (ieee->LeisurePSLeave) { + ieee->LeisurePSLeave(ieee->dev); + } + + /* notify AP to be in PS mode */ + ieee80211_sta_ps_send_null_frame(ieee, 1); + ieee80211_sta_ps_send_null_frame(ieee, 1); +#endif + netif_carrier_off(ieee->dev); if (ieee->data_hard_stop) @@ -360,6 +371,12 @@ void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee) ieee->InitialGainHandler(ieee->dev,IG_Restore); ieee->state = IEEE80211_LINKED; ieee->link_change(ieee->dev); + +#ifdef ENABLE_LPS + /* Notify AP that I wake up again */ + ieee80211_sta_ps_send_null_frame(ieee, 0); +#endif + // To prevent the immediately calling watch_dog after scan. if(ieee->LinkDetectInfo.NumRecvBcnInPeriod==0||ieee->LinkDetectInfo.NumRecvDataInPeriod==0 ) { @@ -429,8 +446,9 @@ int ieee80211_wx_set_essid(struct ieee80211_device *ieee, goto out; } - if(proto_started) - ieee80211_stop_protocol(ieee); + if(proto_started){ + ieee80211_stop_protocol(ieee,true); + } /* this is just to be sure that the GET wx callback diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c index 798fb41..a75f366 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c @@ -200,8 +200,8 @@ int ieee80211_encrypt_fragment( header = (struct ieee80211_hdr *) frag->data; if (net_ratelimit()) { printk(KERN_DEBUG "%s: TKIP countermeasures: dropped " - "TX packet to " MAC_FMT "\n", - ieee->dev->name, MAC_ARG(header->addr1)); + "TX packet to %pM\n", + ieee->dev->name, header->addr1); } return -1; } @@ -334,6 +334,13 @@ void ieee80211_tx_query_agg_cap(struct ieee80211_device* ieee, struct sk_buff* s if(!Adapter->HalFunc.GetNmodeSupportBySecCfgHandler(Adapter)) return; #endif + + if(tcb_desc->bdhcp)// || ieee->CntAfterLink<2) + { + return; + } + + #if 1 if(!ieee->GetNmodeSupportBySecCfg(ieee->dev)) { @@ -628,6 +635,7 @@ int ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev) int qos_actived = ieee->current_network.qos_data.active; struct ieee80211_crypt_data* crypt; + bool bdhcp =false; cb_desc *tcb_desc; @@ -672,6 +680,55 @@ int ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev) } #endif + // The following is for DHCP and ARP packet, we use cck1M to tx these packets and let LPS awake some time + // to prevent DHCP protocol fail + if (skb->len > 282){//MINIMUM_DHCP_PACKET_SIZE) { + if (ETH_P_IP == ether_type) {// IP header + const struct iphdr *ip = (struct iphdr *)((u8 *)skb->data+14); + if (IPPROTO_UDP == ip->protocol) {//FIXME windows is 11 but here UDP in linux kernel is 17. + struct udphdr *udp = (struct udphdr *)((u8 *)ip + (ip->ihl << 2)); + //if(((ntohs(udp->source) == 68) && (ntohs(udp->dest) == 67)) || + /// ((ntohs(udp->source) == 67) && (ntohs(udp->dest) == 68))) { + if(((((u8 *)udp)[1] == 68) && (((u8 *)udp)[3] == 67)) || + ((((u8 *)udp)[1] == 67) && (((u8 *)udp)[3] == 68))) { + // 68 : UDP BOOTP client + // 67 : UDP BOOTP server + printk("DHCP pkt src port:%d, dest port:%d!!\n", ((u8 *)udp)[1],((u8 *)udp)[3]); + // Use low rate to send DHCP packet. + //if(pMgntInfo->IOTAction & HT_IOT_ACT_WA_IOT_Broadcom) + //{ + // tcb_desc->DataRate = MgntQuery_TxRateExcludeCCKRates(ieee);//0xc;//ofdm 6m + // tcb_desc->bTxDisableRateFallBack = false; + //} + //else + //pTcb->DataRate = Adapter->MgntInfo.LowestBasicRate; + //RTPRINT(FDM, WA_IOT, ("DHCP TranslateHeader(), pTcb->DataRate = 0x%x\n", pTcb->DataRate)); + + bdhcp = true; +#ifdef _RTL8192_EXT_PATCH_ + ieee->LPSDelayCnt = 100;//pPSC->LPSAwakeIntvl*2; //AMY,090701 +#else + ieee->LPSDelayCnt = 100;//pPSC->LPSAwakeIntvl*2; +#endif + } + } + }else if(ETH_P_ARP == ether_type){// IP ARP packet + printk("=================>DHCP Protocol start tx ARP pkt!!\n"); + bdhcp = true; + ieee->LPSDelayCnt = ieee->current_network.tim.tim_count; + + //if(pMgntInfo->IOTAction & HT_IOT_ACT_WA_IOT_Broadcom) + //{ + // tcb_desc->DataRate = MgntQuery_TxRateExcludeCCKRates(Adapter->MgntInfo.mBrates);//0xc;//ofdm 6m + // tcb_desc->bTxDisableRateFallBack = FALSE; + //} + //else + // tcb_desc->DataRate = Adapter->MgntInfo.LowestBasicRate; + //RTPRINT(FDM, WA_IOT, ("ARP TranslateHeader(), pTcb->DataRate = 0x%x\n", pTcb->DataRate)); + + } + } + /* Save source and destination addresses */ memcpy(&dest, skb->data, ETH_ALEN); memcpy(&src, skb->data+ETH_ALEN, ETH_ALEN); @@ -895,6 +952,25 @@ int ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev) else //tcb_desc->data_rate = CURRENT_RATE(ieee->current_network.mode, ieee->rate, ieee->HTCurrentOperaRate); tcb_desc->data_rate = CURRENT_RATE(ieee->mode, ieee->rate, ieee->HTCurrentOperaRate); + + if(bdhcp == true){ + // Use low rate to send DHCP packet. + //if(ieee->pHTInfo->IOTAction & HT_IOT_ACT_WA_IOT_Broadcom) { + // tcb_desc->data_rate = MGN_1M;//MgntQuery_TxRateExcludeCCKRates(ieee);//0xc;//ofdm 6m + // tcb_desc->bTxDisableRateFallBack = false; + //} + //else + { + tcb_desc->data_rate = MGN_1M; + tcb_desc->bTxDisableRateFallBack = 1; + } + + tcb_desc->RATRIndex = 7; + tcb_desc->bTxUseDriverAssingedRate = 1; + tcb_desc->bdhcp = 1; + } + + ieee80211_qurey_ShortPreambleMode(ieee, tcb_desc); ieee80211_tx_query_agg_cap(ieee, txb->fragments[0], tcb_desc); ieee80211_query_HTCapShortGI(ieee, tcb_desc); diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c index 3441b72..a3302d5 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c @@ -386,10 +386,10 @@ int ieee80211_wx_get_scan(struct ieee80211_device *ieee, else IEEE80211_DEBUG_SCAN( "Not showing network '%s (" - MAC_FMT ")' due to age (%lums).\n", + "%pM)' due to age (%lums).\n", escape_essid(network->ssid, network->ssid_len), - MAC_ARG(network->bssid), + network->bssid, (jiffies - network->last_scanned) / (HZ / 100)); } @@ -933,7 +933,7 @@ int ieee80211_wx_set_auth(struct ieee80211_device *ieee, #if 1 case IW_AUTH_WPA_ENABLED: ieee->wpa_enabled = (data->value)?1:0; - //printk("enalbe wpa:%d\n", ieee->wpa_enabled); + //printk("enable wpa:%d\n", ieee->wpa_enabled); break; #endif diff --git a/drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c b/drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c index e41e8a0..ae0e5b9 100644 --- a/drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c +++ b/drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c @@ -113,7 +113,7 @@ static struct sk_buff* ieee80211_ADDBA(struct ieee80211_device* ieee, u8* Dst, P u16 tmp = 0; u16 len = ieee->tx_headroom + 9; //category(1) + action field(1) + Dialog Token(1) + BA Parameter Set(2) + BA Timeout Value(2) + BA Start SeqCtrl(2)(or StatusCode(2)) - IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), frame(%d) sentd to:"MAC_FMT", ieee->dev:%p\n", __FUNCTION__, type, MAC_ARG(Dst), ieee->dev); + IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), frame(%d) sentd to:%pM, ieee->dev:%p\n", __FUNCTION__, type, Dst, ieee->dev); if (pBA == NULL||ieee == NULL) { IEEE80211_DEBUG(IEEE80211_DL_ERR, "pBA(%p) is NULL or ieee(%p) is NULL\n", pBA, ieee); @@ -243,7 +243,7 @@ static struct sk_buff* ieee80211_DELBA( u16 len = 6 + ieee->tx_headroom; if (net_ratelimit()) - IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), ReasonCode(%d) sentd to:"MAC_FMT"\n", __FUNCTION__, ReasonCode, MAC_ARG(dst)); + IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), ReasonCode(%d) sentd to:%pM\n", __FUNCTION__, ReasonCode, dst); memset(&DelbaParamSet, 0, 2); @@ -397,7 +397,7 @@ int ieee80211_rx_ADDBAReq( struct ieee80211_device* ieee, struct sk_buff *skb) pBaTimeoutVal = (u16*)(tag + 5); pBaStartSeqCtrl = (PSEQUENCE_CONTROL)(req + 7); - printk("====================>rx ADDBAREQ from :"MAC_FMT"\n", MAC_ARG(dst)); + printk("====================>rx ADDBAREQ from :%pM\n", dst); //some other capability is not ready now. if( (ieee->current_network.qos_data.active == 0) || (ieee->pHTInfo->bCurrentHTSupport == false)) //|| diff --git a/drivers/staging/rtl8192e/ieee80211/rtl819x_HT.h b/drivers/staging/rtl8192e/ieee80211/rtl819x_HT.h index 992b718..f968817 100644 --- a/drivers/staging/rtl8192e/ieee80211/rtl819x_HT.h +++ b/drivers/staging/rtl8192e/ieee80211/rtl819x_HT.h @@ -458,7 +458,8 @@ typedef enum _HT_IOT_PEER HT_IOT_PEER_RALINK = 3, HT_IOT_PEER_ATHEROS = 4, HT_IOT_PEER_CISCO= 5, - HT_IOT_PEER_MAX = 6 + HT_IOT_PEER_MARVELL=6, + HT_IOT_PEER_MAX = 7 }HT_IOT_PEER_E, *PHTIOT_PEER_E; // @@ -475,6 +476,7 @@ typedef enum _HT_IOT_ACTION{ HT_IOT_ACT_CDD_FSYNC = 0x00000080, HT_IOT_ACT_PURE_N_MODE = 0x00000100, HT_IOT_ACT_FORCED_CTS2SELF = 0x00000200, + HT_IOT_ACT_NULL_DATA_POWER_SAVING = 0x00800000, }HT_IOT_ACTION_E, *PHT_IOT_ACTION_E; #endif //_RTL819XU_HTTYPE_H_ diff --git a/drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c b/drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c index 1e39214..4c4b1df 100644 --- a/drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c +++ b/drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c @@ -32,7 +32,7 @@ u16 MCS_DATA_RATE[2][2][77] = static u8 UNKNOWN_BORADCOM[3] = {0x00, 0x14, 0xbf}; static u8 LINKSYSWRT330_LINKSYSWRT300_BROADCOM[3] = {0x00, 0x1a, 0x70}; static u8 LINKSYSWRT350_LINKSYSWRT150_BROADCOM[3] = {0x00, 0x1d, 0x7e}; -static u8 NETGEAR834Bv2_BROADCOM[3] = {0x00, 0x1b, 0x2f}; +//static u8 NETGEAR834Bv2_BROADCOM[3] = {0x00, 0x1b, 0x2f}; static u8 BELKINF5D8233V1_RALINK[3] = {0x00, 0x17, 0x3f}; //cosa 03202008 static u8 BELKINF5D82334V3_RALINK[3] = {0x00, 0x1c, 0xdf}; static u8 PCI_RALINK[3] = {0x00, 0x90, 0xcc}; @@ -40,8 +40,9 @@ static u8 EDIMAX_RALINK[3] = {0x00, 0x0e, 0x2e}; static u8 AIRLINK_RALINK[3] = {0x00, 0x18, 0x02}; static u8 DLINK_ATHEROS[3] = {0x00, 0x1c, 0xf0}; static u8 CISCO_BROADCOM[3] = {0x00, 0x17, 0x94}; +static u8 LINKSYS_MARVELL_4400N[3] = {0x00, 0x14, 0xa4}; -// 2008/04/01 MH For Cisco G mode RX TP We need to change FW duration. Shoud we put the +// 2008/04/01 MH For Cisco G mode RX TP We need to change FW duration. Should we put the // code in other place?? //static u8 WIFI_CISCO_G_AP[3] = {0x00, 0x40, 0x96}; /******************************************************************************************************************** @@ -349,12 +350,12 @@ bool IsHTHalfNmodeAPs(struct ieee80211_device* ieee) bool retValue = false; struct ieee80211_network* net = &ieee->current_network; #if 0 - if(pMgntInfo->bHalfNMode == false) + if(ieee->bHalfNMode == false) retValue = false; else #endif if((memcmp(net->bssid, BELKINF5D8233V1_RALINK, 3)==0) || - (memcmp(net->bssid, BELKINF5D82334V3_RALINK, 3)==0) || + (memcmp(net->bssid, BELKINF5D82334V3_RALINK, 3)==0) || (memcmp(net->bssid, PCI_RALINK, 3)==0) || (memcmp(net->bssid, EDIMAX_RALINK, 3)==0) || (memcmp(net->bssid, AIRLINK_RALINK, 3)==0) || @@ -363,7 +364,7 @@ bool IsHTHalfNmodeAPs(struct ieee80211_device* ieee) else if((memcmp(net->bssid, UNKNOWN_BORADCOM, 3)==0) || (memcmp(net->bssid, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3)==0)|| (memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3)==0)|| - (memcmp(net->bssid, NETGEAR834Bv2_BROADCOM, 3)==0) || + //(memcmp(net->bssid, NETGEAR834Bv2_BROADCOM, 3)==0) || (net->broadcom_cap_exist)) retValue = true; else if(net->bssht.bdRT2RTAggregation) @@ -387,13 +388,15 @@ void HTIOTPeerDetermine(struct ieee80211_device* ieee) struct ieee80211_network* net = &ieee->current_network; if(net->bssht.bdRT2RTAggregation) pHTInfo->IOTPeer = HT_IOT_PEER_REALTEK; - else if(net->broadcom_cap_exist) + else if(net->broadcom_cap_exist){ pHTInfo->IOTPeer = HT_IOT_PEER_BROADCOM; + } else if((memcmp(net->bssid, UNKNOWN_BORADCOM, 3)==0) || (memcmp(net->bssid, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3)==0)|| - (memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3)==0)|| - (memcmp(net->bssid, NETGEAR834Bv2_BROADCOM, 3)==0) ) + (memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3)==0)){//|| + //(memcmp(net->bssid, NETGEAR834Bv2_BROADCOM, 3)==0) ){ pHTInfo->IOTPeer = HT_IOT_PEER_BROADCOM; + } else if((memcmp(net->bssid, BELKINF5D8233V1_RALINK, 3)==0) || (memcmp(net->bssid, BELKINF5D82334V3_RALINK, 3)==0) || (memcmp(net->bssid, PCI_RALINK, 3)==0) || @@ -405,6 +408,10 @@ void HTIOTPeerDetermine(struct ieee80211_device* ieee) pHTInfo->IOTPeer = HT_IOT_PEER_ATHEROS; else if(memcmp(net->bssid, CISCO_BROADCOM, 3)==0) pHTInfo->IOTPeer = HT_IOT_PEER_CISCO; + else if ((memcmp(net->bssid, LINKSYS_MARVELL_4400N, 3) == 0) || + net->marvell_cap_exist){ + pHTInfo->IOTPeer = HT_IOT_PEER_MARVELL; + } else pHTInfo->IOTPeer = HT_IOT_PEER_UNKNOWN; @@ -442,6 +449,18 @@ u8 HTIOTActIsDisableMCS14(struct ieee80211_device* ieee, u8* PeerMacAddr) return ret; } +u8 HTIOTActIsForcedCTS2Self(struct ieee80211_device *ieee, struct ieee80211_network *network) +{ + u8 retValue = 0; + //if(network->marvell_cap_exist) + if(ieee->pHTInfo->IOTPeer == HT_IOT_PEER_MARVELL) + { + retValue = 1; + } + + return retValue; +} + /** * Function: HTIOTActIsDisableMCS15 @@ -578,6 +597,23 @@ u8 HTIOTActIsCCDFsync(u8* PeerMacAddr) return retValue; } +// +// Send null data for to tell AP that we are awake. +// +bool +HTIOTActIsNullDataPowerSaving(struct ieee80211_device* ieee,struct ieee80211_network *network) +{ + bool retValue = false; + + PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; + { + if(pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM) // ||(pBssDesc->Vender == HT_IOT_PEER_ATHEROS && pBssDesc->SubTypeOfVender == HT_IOT_PEER_ATHEROS_DIR635)) + return true; + + } + return retValue; +} + void HTResetIOTSetting( PRT_HIGH_THROUGHPUT pHTInfo ) @@ -1071,6 +1107,13 @@ void HTOnAssocRsp(struct ieee80211_device *ieee) // Config and configure A-MSDU setting // pHTInfo->bCurrent_AMSDU_Support = pHTInfo->bAMSDU_Support; + if (ieee->rtllib_ap_sec_type && + (ieee->rtllib_ap_sec_type(ieee)&(SEC_ALG_WEP|SEC_ALG_TKIP))){ + if( (pHTInfo->IOTPeer== HT_IOT_PEER_ATHEROS) || + (pHTInfo->IOTPeer == HT_IOT_PEER_UNKNOWN) ) + pHTInfo->bCurrentAMPDUEnable = false; + } + nMaxAMSDUSize = (pPeerHTCap->MaxAMSDUSize==0)?3839:7935; @@ -1515,6 +1558,9 @@ void HTResetSelfAndSavePeerSetting(struct ieee80211_device* ieee, struct ieee80 bIOTAction = HTIOTActIsDisableMCS14(ieee, pNetwork->bssid); if(bIOTAction) pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_MCS14; + bIOTAction = HTIOTActIsForcedCTS2Self(ieee, pNetwork); + if(bIOTAction) + pHTInfo->IOTAction |= HT_IOT_ACT_FORCED_CTS2SELF; bIOTAction = HTIOTActIsDisableMCS15(ieee); if(bIOTAction) @@ -1537,6 +1583,9 @@ void HTResetSelfAndSavePeerSetting(struct ieee80211_device* ieee, struct ieee80 if(bIOTAction) pHTInfo->IOTAction |= HT_IOT_ACT_CDD_FSYNC; + bIOTAction = HTIOTActIsNullDataPowerSaving(ieee, pNetwork); + if(bIOTAction) + pHTInfo->IOTAction |= HT_IOT_ACT_NULL_DATA_POWER_SAVING; } else diff --git a/drivers/staging/rtl8192e/ieee80211/rtl819x_TSProc.c b/drivers/staging/rtl8192e/ieee80211/rtl819x_TSProc.c index 2816b60..e2cbfd3 100644 --- a/drivers/staging/rtl8192e/ieee80211/rtl819x_TSProc.c +++ b/drivers/staging/rtl8192e/ieee80211/rtl819x_TSProc.c @@ -304,7 +304,7 @@ PTS_COMMON_INFO SearchAdmitTRStream(struct ieee80211_device *ieee, u8* Addr, u8 if(search_dir[dir] ==false ) continue; list_for_each_entry(pRet, psearch_list, List){ - // IEEE80211_DEBUG(IEEE80211_DL_TS, "ADD:"MAC_FMT", TID:%d, dir:%d\n", MAC_ARG(pRet->Addr), pRet->TSpec.f.TSInfo.field.ucTSID, pRet->TSpec.f.TSInfo.field.ucDirection); + // IEEE80211_DEBUG(IEEE80211_DL_TS, "ADD:%pM, TID:%d, dir:%d\n", pRet->Addr, pRet->TSpec.f.TSInfo.field.ucTSID, pRet->TSpec.f.TSInfo.field.ucDirection); if (memcmp(pRet->Addr, Addr, 6) == 0) if (pRet->TSpec.f.TSInfo.field.ucTSID == TID) if(pRet->TSpec.f.TSInfo.field.ucDirection == dir) @@ -466,7 +466,7 @@ bool GetTs( ResetRxTsEntry(tmp); } - IEEE80211_DEBUG(IEEE80211_DL_TS, "to init current TS, UP:%d, Dir:%d, addr:"MAC_FMT"\n", UP, Dir, MAC_ARG(Addr)); + IEEE80211_DEBUG(IEEE80211_DL_TS, "to init current TS, UP:%d, Dir:%d, addr:%pM\n", UP, Dir, Addr); // Prepare TS Info releated field pTSInfo->field.ucTrafficType = 0; // Traffic type: WMM is reserved in this field pTSInfo->field.ucTSID = UP; // TSID @@ -552,7 +552,7 @@ void RemoveTsEntry( void RemovePeerTS(struct ieee80211_device* ieee, u8* Addr) { PTS_COMMON_INFO pTS, pTmpTS; - printk("===========>RemovePeerTS,"MAC_FMT"\n", MAC_ARG(Addr)); + printk("===========>RemovePeerTS,%pM\n", Addr); #if 1 list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, List) { diff --git a/drivers/staging/rtl8192e/r8180_93cx6.c b/drivers/staging/rtl8192e/r8180_93cx6.c index 79f7a0f..262ed5f 100644 --- a/drivers/staging/rtl8192e/r8180_93cx6.c +++ b/drivers/staging/rtl8192e/r8180_93cx6.c @@ -22,7 +22,7 @@ static void eprom_cs(struct net_device *dev, short bit) { - if(bit) + if (bit) write_nic_byte(dev, EPROM_CMD, (1<<EPROM_CS_SHIFT) | \ read_nic_byte(dev, EPROM_CMD)); //enable EPROM @@ -38,23 +38,23 @@ static void eprom_cs(struct net_device *dev, short bit) static void eprom_ck_cycle(struct net_device *dev) { write_nic_byte(dev, EPROM_CMD, - (1<<EPROM_CK_SHIFT) | read_nic_byte(dev,EPROM_CMD)); + (1<<EPROM_CK_SHIFT) | read_nic_byte(dev, EPROM_CMD)); force_pci_posting(dev); udelay(EPROM_DELAY); write_nic_byte(dev, EPROM_CMD, - read_nic_byte(dev, EPROM_CMD) &~ (1<<EPROM_CK_SHIFT)); + read_nic_byte(dev, EPROM_CMD) & ~(1<<EPROM_CK_SHIFT)); force_pci_posting(dev); udelay(EPROM_DELAY); } -static void eprom_w(struct net_device *dev,short bit) +static void eprom_w(struct net_device *dev, short bit) { - if(bit) + if (bit) write_nic_byte(dev, EPROM_CMD, (1<<EPROM_W_SHIFT) | \ - read_nic_byte(dev,EPROM_CMD)); + read_nic_byte(dev, EPROM_CMD)); else - write_nic_byte(dev, EPROM_CMD, read_nic_byte(dev,EPROM_CMD)\ + write_nic_byte(dev, EPROM_CMD, read_nic_byte(dev, EPROM_CMD)\ &~(1<<EPROM_W_SHIFT)); force_pci_posting(dev); @@ -66,10 +66,11 @@ static short eprom_r(struct net_device *dev) { short bit; - bit=(read_nic_byte(dev, EPROM_CMD) & (1<<EPROM_R_SHIFT) ); + bit = (read_nic_byte(dev, EPROM_CMD) & (1<<EPROM_R_SHIFT)); udelay(EPROM_DELAY); - if(bit) return 1; + if (bit) + return 1; return 0; } @@ -78,7 +79,7 @@ static void eprom_send_bits_string(struct net_device *dev, short b[], int len) { int i; - for(i=0; i<len; i++){ + for (i = 0; i < len; i++) { eprom_w(dev, b[i]); eprom_ck_cycle(dev); } @@ -88,37 +89,37 @@ static void eprom_send_bits_string(struct net_device *dev, short b[], int len) u32 eprom_read(struct net_device *dev, u32 addr) { struct r8192_priv *priv = ieee80211_priv(dev); - short read_cmd[]={1,1,0}; + short read_cmd[] = {1, 1, 0}; short addr_str[8]; int i; int addr_len; u32 ret; - ret=0; + ret = 0; //enable EPROM programming write_nic_byte(dev, EPROM_CMD, (EPROM_CMD_PROGRAM<<EPROM_CMD_OPERATING_MODE_SHIFT)); force_pci_posting(dev); udelay(EPROM_DELAY); - if (priv->epromtype==EPROM_93c56){ - addr_str[7]=addr & 1; - addr_str[6]=addr & (1<<1); - addr_str[5]=addr & (1<<2); - addr_str[4]=addr & (1<<3); - addr_str[3]=addr & (1<<4); - addr_str[2]=addr & (1<<5); - addr_str[1]=addr & (1<<6); - addr_str[0]=addr & (1<<7); - addr_len=8; - }else{ - addr_str[5]=addr & 1; - addr_str[4]=addr & (1<<1); - addr_str[3]=addr & (1<<2); - addr_str[2]=addr & (1<<3); - addr_str[1]=addr & (1<<4); - addr_str[0]=addr & (1<<5); - addr_len=6; + if (priv->epromtype == EPROM_93c56) { + addr_str[7] = addr & 1; + addr_str[6] = addr & (1<<1); + addr_str[5] = addr & (1<<2); + addr_str[4] = addr & (1<<3); + addr_str[3] = addr & (1<<4); + addr_str[2] = addr & (1<<5); + addr_str[1] = addr & (1<<6); + addr_str[0] = addr & (1<<7); + addr_len = 8; + } else { + addr_str[5] = addr & 1; + addr_str[4] = addr & (1<<1); + addr_str[3] = addr & (1<<2); + addr_str[2] = addr & (1<<3); + addr_str[1] = addr & (1<<4); + addr_str[0] = addr & (1<<5); + addr_len = 6; } eprom_cs(dev, 1); eprom_ck_cycle(dev); @@ -129,7 +130,7 @@ u32 eprom_read(struct net_device *dev, u32 addr) //I'm unsure if it is necessary, but anyway shouldn't hurt eprom_w(dev, 0); - for(i=0;i<16;i++){ + for (i = 0; i < 16; i++) { //eeprom needs a clk cycle between writing opcode&adr //and reading data. (eeprom outs a dummy 0) eprom_ck_cycle(dev); diff --git a/drivers/staging/rtl8192e/r8180_93cx6.h b/drivers/staging/rtl8192e/r8180_93cx6.h index 62e14c7..4c3f675 100644 --- a/drivers/staging/rtl8192e/r8180_93cx6.h +++ b/drivers/staging/rtl8192e/r8180_93cx6.h @@ -1,17 +1,18 @@ -/* - This is part of rtl8187 OpenSource driver - Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it> - Released under the terms of GPL (General Public Licence) - - Parts of this driver are based on the GPL part of the official realtek driver - Parts of this driver are based on the rtl8180 driver skeleton from Patric Schenke & Andres Salomon - Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver - - We want to tanks the Authors of such projects and the Ndiswrapper project Authors. -*/ - -/*This files contains card eeprom (93c46 or 93c56) programming routines*/ -/*memory is addressed by WORDS*/ +/* r8180_93cx6.h - 93c46 or 93c56 eeprom card programming routines + * + * This is part of rtl8187 OpenSource driver + * Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it> + * Released under the terms of GPL (General Public Licence) + * Parts of this driver are based on the GPL part of the official realtek driver + * + * Parts of this driver are based on the rtl8180 driver skeleton from + * Patric Schenke & Andres Salomon. + * + * Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver + * + * We want to thank the authors of the above mentioned projects and to + * the authors of the Ndiswrapper project. + */ #include "r8192E.h" #include "r8192E_hw.h" @@ -36,5 +37,5 @@ #define EPROM_TXPW2 0x1b #define EPROM_TXPW1 0x3d - -u32 eprom_read(struct net_device *dev,u32 addr); //reads a 16 bits word +/* Reads a 16 bits word. */ +u32 eprom_read(struct net_device *dev, u32 addr); diff --git a/drivers/staging/rtl8192e/r8190_rtl8256.c b/drivers/staging/rtl8192e/r8190_rtl8256.c index 3d67fbb..1bd054d 100644 --- a/drivers/staging/rtl8192e/r8190_rtl8256.c +++ b/drivers/staging/rtl8192e/r8190_rtl8256.c @@ -429,11 +429,12 @@ SetRFPowerState8190( bool bResult = true; //u8 eRFPath; u8 i = 0, QueueID = 0; - ptx_ring head=NULL,tail=NULL; + //ptx_ring head=NULL,tail=NULL; + struct rtl8192_tx_ring *ring = NULL; if(priv->SetRFPowerStateInProgress == true) return false; - RT_TRACE(COMP_POWER, "===========> SetRFPowerState8190()!\n"); + //RT_TRACE(COMP_PS, "===========> SetRFPowerState8190()!\n"); priv->SetRFPowerStateInProgress = true; switch(priv->rf_chip) @@ -442,11 +443,11 @@ SetRFPowerState8190( switch( eRFPowerState ) { case eRfOn: - RT_TRACE(COMP_POWER, "SetRFPowerState8190() eRfOn !\n"); + //RT_TRACE(COMP_PS, "SetRFPowerState8190() eRfOn !\n"); //RXTX enable control: On //for(eRFPath = 0; eRFPath <pHalData->NumTotalRFPath; eRFPath++) - // PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x2); - #ifdef RTL8190P + // PHY_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x2); +#ifdef RTL8190P if(priv->rf_type == RF_2T4R) { //enable RF-Chip A/B @@ -479,36 +480,92 @@ SetRFPowerState8190( //analog to digital part2 on rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x1800, 0x3); // 0x880[12:11] } - #else - write_nic_byte(dev, ANAPAR, 0x37);//160MHz - write_nic_byte(dev, MacBlkCtrl, 0x17); // 0x403 - mdelay(1); - //enable clock 80/88 MHz - - priv->bHwRfOffAction = 0; - //} - - // Baseband reset 2008.09.30 add - write_nic_byte(dev, BB_RESET, (read_nic_byte(dev, BB_RESET)|BIT0)); - - //2 AFE - // 2008.09.30 add - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter2, 0x20000000, 0x1); // 0x884 - //analog to digital part2 on - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60, 0x3); // 0x880[6:5] - //digital to analog on - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x98, 0x13); // 0x880[4:3] - //analog to digital on - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf03, 0xf03);// 0x88c[9:8] - //rx antenna on - //PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, 0x3, 0x3);// 0xc04[1:0] - //rx antenna on 2008.09.30 mark - //PHY_SetBBReg(Adapter, rOFDM1_TRxPathEnable, 0x3, 0x3);// 0xd04[1:0] - - //2 RF - //enable RF-Chip A/B + else if(priv->rf_type == RF_1T1R) //RF-C + { + //enable RF-Chip C/D + rtl8192_setBBreg(dev, rFPGA0_XC_RFInterfaceOE, BIT4, 0x1); // 0x868[4] + //analog to digital on + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0x400, 0x1);// 0x88c[10] + //digital to analog on + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x80, 0x1); // 0x880[7] + //rx antenna on + rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x4, 0x1);// 0xc04[2] + //rx antenna on + rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0x4, 0x1);// 0xd04[2] + //analog to digital part2 on + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x800, 0x1); // 0x880[11] + } + +#elif defined RTL8192E + // turn on RF + if((priv->ieee80211->eRFPowerState == eRfOff) && RT_IN_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC)) + { // The current RF state is OFF and the RF OFF level is halting the NIC, re-initialize the NIC. + bool rtstatus = true; + u32 InitilizeCount = 3; + do + { + InitilizeCount--; + priv->RegRfOff = false; + rtstatus = NicIFEnableNIC(dev); + }while( (rtstatus != true) &&(InitilizeCount >0) ); + + if(rtstatus != true) + { + RT_TRACE(COMP_ERR,"%s():Initialize Adapter fail,return\n",__FUNCTION__); + priv->SetRFPowerStateInProgress = false; + return false; + } + + RT_CLEAR_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC); + } else { + write_nic_byte(dev, ANAPAR, 0x37);//160MHz + //write_nic_byte(dev, MacBlkCtrl, 0x17); // 0x403 + mdelay(1); + //enable clock 80/88 MHz + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x4, 0x1); // 0x880[2] + priv->bHwRfOffAction = 0; + //} + + //RF-A, RF-B + //enable RF-Chip A/B rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x1); // 0x860[4] - rtl8192_setBBreg(dev, rFPGA0_XB_RFInterfaceOE, BIT4, 0x1); // 0x864[4] + //analog to digital on + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0x300, 0x3);// 0x88c[9:8] + //digital to analog on + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x18, 0x3); // 0x880[4:3] + //rx antenna on + rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x3, 0x3);// 0xc04[1:0] + //rx antenna on + rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0x3, 0x3);// 0xd04[1:0] + //analog to digital part2 on + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60, 0x3); // 0x880[6:5] + + // Baseband reset 2008.09.30 add + //write_nic_byte(dev, BB_RESET, (read_nic_byte(dev, BB_RESET)|BIT0)); + + //2 AFE + // 2008.09.30 add + //rtl8192_setBBreg(dev, rFPGA0_AnalogParameter2, 0x20000000, 0x1); // 0x884 + //analog to digital part2 on + //rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60, 0x3); // 0x880[6:5] + + + //digital to analog on + //rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x98, 0x13); // 0x880[4:3] + //analog to digital on + //rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf03, 0xf03);// 0x88c[9:8] + //rx antenna on + //PHY_SetBBReg(dev, rOFDM0_TRxPathEnable, 0x3, 0x3);// 0xc04[1:0] + //rx antenna on 2008.09.30 mark + //PHY_SetBBReg(dev, rOFDM1_TRxPathEnable, 0x3, 0x3);// 0xd04[1:0] + + //2 RF + //enable RF-Chip A/B + //rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x1); // 0x860[4] + //rtl8192_setBBreg(dev, rFPGA0_XB_RFInterfaceOE, BIT4, 0x1); // 0x864[4] + + } + #endif break; @@ -517,119 +574,137 @@ SetRFPowerState8190( // By Bruce, 2008-01-16. // case eRfSleep: - case eRfOff: - RT_TRACE(COMP_POWER, "SetRFPowerState8190() eRfOff/Sleep !\n"); - if (pPSC->bLeisurePs) + { + // HW setting had been configured with deeper mode. + if(priv->ieee80211->eRFPowerState == eRfOff) + break; + + // Update current RF state variable. + //priv->ieee80211->eRFPowerState = eRFPowerState; + + //if (pPSC->bLeisurePs) { for(QueueID = 0, i = 0; QueueID < MAX_TX_QUEUE; ) { - switch(QueueID) { - case MGNT_QUEUE: - tail=priv->txmapringtail; - head=priv->txmapringhead; + ring = &priv->tx_ring[QueueID]; + + if(skb_queue_len(&ring->queue) == 0) + { + QueueID++; + continue; + } + else + { + RT_TRACE((COMP_POWER|COMP_RF), "eRf Off/Sleep: %d times TcbBusyQueue[%d] !=0 before doze!\n", (i+1), QueueID); + udelay(10); + i++; + } + + if(i >= MAX_DOZE_WAITING_TIMES_9x) + { + RT_TRACE(COMP_POWER, "\n\n\n TimeOut!! SetRFPowerState8190(): eRfOff: %d times TcbBusyQueue[%d] != 0 !!!\n\n\n", MAX_DOZE_WAITING_TIMES_9x, QueueID); break; + } + } + } - case BK_QUEUE: - tail=priv->txbkpringtail; - head=priv->txbkpringhead; + //if(Adapter->HardwareType == HARDWARE_TYPE_RTL8190P) +#ifdef RTL8190P + { + PHY_SetRtl8190pRfOff(dev); + } + //else if(Adapter->HardwareType == HARDWARE_TYPE_RTL8192E) +#elif defined RTL8192E + { + PHY_SetRtl8192eRfOff(dev); + } +#endif + } break; - case BE_QUEUE: - tail=priv->txbepringtail; - head=priv->txbepringhead; - break; + case eRfOff: + //RT_TRACE(COMP_PS, "SetRFPowerState8190() eRfOff/Sleep !\n"); - case VI_QUEUE: - tail=priv->txvipringtail; - head=priv->txvipringhead; - break; + // Update current RF state variable. + //priv->ieee80211->eRFPowerState = eRFPowerState; - case VO_QUEUE: - tail=priv->txvopringtail; - head=priv->txvopringhead; - break; + // + // Disconnect with Any AP or STA. + // + for(QueueID = 0, i = 0; QueueID < MAX_TX_QUEUE; ) + { + ring = &priv->tx_ring[QueueID]; - default: - tail=head=NULL; - break; - } - if(tail == head) + if(skb_queue_len(&ring->queue) == 0) { - //DbgPrint("QueueID = %d", QueueID); QueueID++; continue; } else { - RT_TRACE(COMP_POWER, "eRf Off/Sleep: %d times BusyQueue[%d] !=0 before doze!\n", (i+1), QueueID); + RT_TRACE(COMP_POWER, + "eRf Off/Sleep: %d times TcbBusyQueue[%d] !=0 before doze!\n", (i+1), QueueID); udelay(10); i++; } if(i >= MAX_DOZE_WAITING_TIMES_9x) { - RT_TRACE(COMP_POWER, "\n\n\n TimeOut!! SetRFPowerState8190(): eRfOff: %d times BusyQueue[%d] != 0 !!!\n\n\n", MAX_DOZE_WAITING_TIMES_9x, QueueID); + RT_TRACE(COMP_POWER, "\n\n\n SetZebraRFPowerState8185B(): eRfOff: %d times TcbBusyQueue[%d] != 0 !!!\n\n\n", MAX_DOZE_WAITING_TIMES_9x, QueueID); break; } } + + //if(Adapter->HardwareType == HARDWARE_TYPE_RTL8190P) +#if defined RTL8190P + { + PHY_SetRtl8190pRfOff(dev); } - #ifdef RTL8190P - if(priv->rf_type == RF_2T4R) + //else if(Adapter->HardwareType == HARDWARE_TYPE_RTL8192E) +#elif defined RTL8192E { - //disable RF-Chip A/B - rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x0); // 0x860[4] + //if(pPSC->RegRfPsLevel & RT_RF_OFF_LEVL_HALT_NIC && !RT_IN_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC) && priv->ieee80211->RfOffReason > RF_CHANGE_BY_PS) + if (pPSC->RegRfPsLevel & RT_RF_OFF_LEVL_HALT_NIC && !RT_IN_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC)) + { // Disable all components. + // + // Note: + // NicIFSetLinkStatus is a big problem when we indicate the status to OS, + // the OS(XP) will reset. But now, we cnnot find why the NIC is hard to receive + // packets after RF ON. Just keep this function here and still work to find out the root couse. + // By Bruce, 2009-05-01. + // + //NicIFSetLinkStatus( Adapter, RT_MEDIA_DISCONNECT ); + //if HW radio of , need to indicate scan complete first for not be reset. + //if(MgntScanInProgress(pMgntInfo)) + // MgntResetScanProcess( Adapter ); + + // <1> Disable Interrupt + //rtl8192_irq_disable(dev); + // <2> Stop all timer + //MgntCancelAllTimer(Adapter); + // <3> Disable Adapter + //NicIFHaltAdapter(Adapter, false); + NicIFDisableNIC(dev); + RT_SET_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC); + } + else if (!(pPSC->RegRfPsLevel & RT_RF_OFF_LEVL_HALT_NIC)) + { // Normal case. + // IPS should go to this. + PHY_SetRtl8192eRfOff(dev); + } + } +#else + else + { + RT_TRACE(COMP_DBG,DBG_TRACE,("It is not 8190Pci and 8192PciE \n")); } - //disable RF-Chip C/D - rtl8192_setBBreg(dev, rFPGA0_XC_RFInterfaceOE, BIT4, 0x0); // 0x868[4] - //analog to digital off, for power save - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf00, 0x0);// 0x88c[11:8] - //digital to analog off, for power save - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x1e0, 0x0); // 0x880[8:5] - //rx antenna off - rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0xf, 0x0);// 0xc04[3:0] - //rx antenna off - rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0xf, 0x0);// 0xd04[3:0] - //analog to digital part2 off, for power save - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x1e00, 0x0); // 0x880[12:9] -#else //8192E - //2 RF - //disable RF-Chip A/B - rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x0); // 0x860[4] - rtl8192_setBBreg(dev, rFPGA0_XB_RFInterfaceOE, BIT4, 0x0); // 0x864[4] - //2 AFE - //analog to digital off, for power save - //PHY_SetBBReg(Adapter, rFPGA0_AnalogParameter4, 0xf00, 0x0);// 0x88c[11:8] - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf03, 0x0); // 2008.09.30 Modify - //digital to analog off, for power save - //PHY_SetBBReg(Adapter, rFPGA0_AnalogParameter1, 0x18, 0x0); // 0x880[4:3] - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x98, 0x0); // 0x880 2008.09.30 Modify - //rx antenna off 2008.09.30 mark - //PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, 0xf, 0x0);// 0xc04[3:0] - //rx antenna off 2008.09.30 mark - //PHY_SetBBReg(Adapter, rOFDM1_TRxPathEnable, 0xf, 0x0);// 0xd04[3:0] - //analog to digital part2 off, for power save - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60, 0x0); // 0x880[6:5] - // 2008.09.30 add - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter2, 0x20000000, 0x0); // 0x884 - - - //disable clock 80/88 MHz 2008.09.30 mark - //PHY_SetBBReg(Adapter, rFPGA0_AnalogParameter1, 0x4, 0x0); // 0x880[2] - //2 BB - // Baseband reset 2008.09.30 add - write_nic_byte(dev, BB_RESET, (read_nic_byte(dev, BB_RESET)|BIT0)); // 0x101 - //MAC: off - write_nic_byte(dev, MacBlkCtrl, 0x0); // 0x403 - //slow down cpu/lbus clock from 160MHz to Lower - write_nic_byte(dev, ANAPAR, 0x07); // 0x 17 40MHz - priv->bHwRfOffAction = 0; - //} #endif + break; default: bResult = false; - RT_TRACE(COMP_ERR, "SetRFPowerState8190(): unknown state to set: 0x%X!!!\n", eRFPowerState); + RT_TRACE(COMP_ERR, "SetRFPowerState8190(): unknow state to set: 0x%X!!!\n", eRFPowerState); break; } @@ -644,64 +719,11 @@ SetRFPowerState8190( { // Update current RF state variable. priv->ieee80211->eRFPowerState = eRFPowerState; - - switch(priv->rf_chip ) - { - case RF_8256: - switch(priv->ieee80211->eRFPowerState) - { - case eRfOff: - // - //If Rf off reason is from IPS, Led should blink with no link, by Maddest 071015 - // - if(priv->ieee80211->RfOffReason==RF_CHANGE_BY_IPS ) - { - #ifdef TO_DO - Adapter->HalFunc.LedControlHandler(Adapter,LED_CTL_NO_LINK); - #endif - } - else - { - // Turn off LED if RF is not ON. - #ifdef TO_DO - Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_POWER_OFF); - #endif - } - break; - - case eRfOn: - // Turn on RF we are still linked, which might happen when - // we quickly turn off and on HW RF. 2006.05.12, by rcnjko. - if( priv->ieee80211->state == IEEE80211_LINKED) - { - #ifdef TO_DO - Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_LINK); - #endif - } - else - { - // Turn off LED if RF is not ON. - #ifdef TO_DO - Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_NO_LINK); - #endif - } - break; - - default: - // do nothing. - break; - }// Switch RF state - - break; - - default: - RT_TRACE(COMP_ERR, "SetRFPowerState8190(): Unknown RF type\n"); - break; - }// Switch RFChipID } + //printk("%s()priv->ieee80211->eRFPowerState:%s\n" ,__func__,priv->ieee80211->eRFPowerState == eRfOn ? "On" : "Off"); priv->SetRFPowerStateInProgress = false; - RT_TRACE(COMP_POWER, "<=========== SetRFPowerState8190() bResult = %d!\n", bResult); + //RT_TRACE(COMP_PS, "<=========== SetRFPowerState8190() bResult = %d!\n", bResult); return bResult; } diff --git a/drivers/staging/rtl8192e/r8190_rtl8256.h b/drivers/staging/rtl8192e/r8190_rtl8256.h index 7d9095a..ce49c60 100644 --- a/drivers/staging/rtl8192e/r8190_rtl8256.h +++ b/drivers/staging/rtl8192e/r8190_rtl8256.h @@ -1,28 +1,33 @@ -/* - This is part of the rtl8180-sa2400 driver - released under the GPL (See file COPYING for details). - Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it> +/* r8190_rtl8256.h - rtl8256 radio frontend + * + * This is part of the rtl8180-sa2400 driver + * released under the GPL (See file COPYING for details). + * Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it> + * + * Many thanks to Realtek Corp. for their great support! + */ - This files contains programming code for the rtl8256 - radio frontend. - - *Many* thanks to Realtek Corp. for their great support! - -*/ - -#ifndef RTL8225H -#define RTL8225H +#ifndef RTL8225_H +#define RTL8225_H #ifdef RTL8190P -#define RTL819X_TOTAL_RF_PATH 4 +#define RTL819X_TOTAL_RF_PATH 4 #else -#define RTL819X_TOTAL_RF_PATH 2 //for 8192E +#define RTL819X_TOTAL_RF_PATH 2 /* for 8192E */ #endif -extern void PHY_SetRF8256Bandwidth(struct net_device* dev , HT_CHANNEL_WIDTH Bandwidth); -extern RT_STATUS PHY_RF8256_Config(struct net_device* dev); -extern RT_STATUS phy_RF8256_Config_ParaFile(struct net_device* dev); -extern void PHY_SetRF8256CCKTxPower(struct net_device* dev, u8 powerlevel); -extern void PHY_SetRF8256OFDMTxPower(struct net_device* dev, u8 powerlevel); -extern bool MgntActSet_RF_State(struct net_device* dev, RT_RF_POWER_STATE StateToSet, RT_RF_CHANGE_SOURCE ChangeSource); -#endif +extern void PHY_SetRF8256Bandwidth(struct net_device *dev, + HT_CHANNEL_WIDTH Bandwidth); + +extern RT_STATUS PHY_RF8256_Config(struct net_device *dev); + +extern RT_STATUS phy_RF8256_Config_ParaFile(struct net_device *dev); + +extern void PHY_SetRF8256CCKTxPower(struct net_device *dev, u8 powerlevel); +extern void PHY_SetRF8256OFDMTxPower(struct net_device *dev, u8 powerlevel); + +extern bool MgntActSet_RF_State(struct net_device *dev, + RT_RF_POWER_STATE StateToSet, + RT_RF_CHANGE_SOURCE ChangeSource); + +#endif /* RTL8225_H */ diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index 61b6f25..f4be9cc 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -39,7 +39,7 @@ #include <linux/random.h> #include <linux/version.h> #include <asm/io.h> -#include "ieee80211.h" +#include "ieee80211/ieee80211.h" @@ -1003,6 +1003,11 @@ typedef struct r8192_priv int irq; short irq_enabled; struct ieee80211_device *ieee80211; +#ifdef ENABLE_LPS + bool ps_force; + bool force_lps; + bool bdisable_nic; +#endif bool being_init_adapter; u8 Rf_Mode; short card_8192; /* O: rtl8192, 1:rtl8185 V B/C, 2:rtl8185 V D */ @@ -1477,7 +1482,7 @@ void write_nic_word(struct net_device *dev, int x,u16 y); void write_nic_dword(struct net_device *dev, int x,u32 y); void force_pci_posting(struct net_device *dev); -void rtl8192_rtx_disable(struct net_device *); +void rtl8192_halt_adapter(struct net_device *dev, bool reset); void rtl8192_rx_enable(struct net_device *); void rtl8192_tx_enable(struct net_device *); @@ -1512,5 +1517,19 @@ short rtl8192_is_tx_queue_empty(struct net_device *dev); #ifdef ENABLE_IPS void IPSEnter(struct net_device *dev); void IPSLeave(struct net_device *dev); +void InactivePsWorkItemCallback(struct net_device *dev); +void IPSLeave_wq(void *data); +void ieee80211_ips_leave_wq(struct net_device *dev); +void ieee80211_ips_leave(struct net_device *dev); +#endif +#ifdef ENABLE_LPS +void LeisurePSEnter(struct net_device *dev); +void LeisurePSLeave(struct net_device *dev); #endif + +bool NicIFEnableNIC(struct net_device* dev); +bool NicIFDisableNIC(struct net_device* dev); + +void rtl8192_irq_disable(struct net_device *dev); +void PHY_SetRtl8192eRfOff(struct net_device* dev); #endif diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 0ca5d8b..886105d 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -66,7 +66,7 @@ #endif #ifdef ENABLE_DOT11D -#include "dot11d.h" +#include "ieee80211/dot11d.h" #endif //set here to open your trace code. //WB @@ -75,7 +75,7 @@ u32 rt_global_debug_component = \ // COMP_EPROM | // COMP_PHY | // COMP_RF | - COMP_FIRMWARE | +// COMP_FIRMWARE | // COMP_TRACE | // COMP_DOWN | // COMP_SWBW | @@ -343,6 +343,141 @@ void write_nic_word(struct net_device *dev, int x,u16 y) #endif /* RTL_IO_MAP */ +u8 rtl8192e_ap_sec_type(struct ieee80211_device *ieee) +{ + //struct r8192_priv* priv = ieee80211_priv(dev); + //struct ieee80211_device *ieee = priv->ieee80211; + + static u8 ccmp_ie[4] = {0x00,0x50,0xf2,0x04}; + static u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04}; + int wpa_ie_len= ieee->wpa_ie_len; + struct ieee80211_crypt_data* crypt; + int encrypt; + + crypt = ieee->crypt[ieee->tx_keyidx]; + + encrypt = (ieee->current_network.capability & WLAN_CAPABILITY_PRIVACY) ||\ + (ieee->host_encrypt && crypt && crypt->ops && \ + (0 == strcmp(crypt->ops->name,"WEP"))); + + /* simply judge */ + if(encrypt && (wpa_ie_len == 0)) { + // wep encryption, no N mode setting */ + return SEC_ALG_WEP; + } else if((wpa_ie_len != 0)) { + // parse pairwise key type */ + if (((ieee->wpa_ie[0] == 0xdd) && (!memcmp(&(ieee->wpa_ie[14]),ccmp_ie,4))) || + ((ieee->wpa_ie[0] == 0x30) && (!memcmp(&ieee->wpa_ie[10],ccmp_rsn_ie, 4)))) + return SEC_ALG_CCMP; + else + return SEC_ALG_TKIP; + } else { + return SEC_ALG_NONE; + } +} + +void +rtl8192e_SetHwReg(struct net_device *dev,u8 variable,u8* val) +{ + struct r8192_priv* priv = ieee80211_priv(dev); + + switch(variable) + { + + case HW_VAR_BSSID: + write_nic_dword(dev, BSSIDR, ((u32*)(val))[0]); + write_nic_word(dev, BSSIDR+2, ((u16*)(val+2))[0]); + break; + + case HW_VAR_MEDIA_STATUS: + { + RT_OP_MODE OpMode = *((RT_OP_MODE *)(val)); + //LED_CTL_MODE LedAction = LED_CTL_NO_LINK; + u8 btMsr = read_nic_byte(dev, MSR); + + btMsr &= 0xfc; + + switch(OpMode) + { + case RT_OP_MODE_INFRASTRUCTURE: + btMsr |= MSR_INFRA; + //LedAction = LED_CTL_LINK; + break; + + case RT_OP_MODE_IBSS: + btMsr |= MSR_ADHOC; + // led link set seperate + break; + + case RT_OP_MODE_AP: + btMsr |= MSR_AP; + //LedAction = LED_CTL_LINK; + break; + + default: + btMsr |= MSR_NOLINK; + break; + } + + write_nic_byte(dev, MSR, btMsr); + + //priv->ieee80211->LedControlHandler(dev, LedAction); + } + break; + + case HW_VAR_CECHK_BSSID: + { + u32 RegRCR, Type; + + Type = ((u8*)(val))[0]; + //priv->ieee80211->GetHwRegHandler(dev, HW_VAR_RCR, (u8*)(&RegRCR)); + RegRCR = read_nic_dword(dev,RCR); + priv->ReceiveConfig = RegRCR; + + if (Type == true) + RegRCR |= (RCR_CBSSID); + else if (Type == false) + RegRCR &= (~RCR_CBSSID); + + //priv->ieee80211->SetHwRegHandler( dev, HW_VAR_RCR, (u8*)(&RegRCR) ); + write_nic_dword(dev, RCR,RegRCR); + priv->ReceiveConfig = RegRCR; + + } + break; + + case HW_VAR_SLOT_TIME: + { + //PSTA_QOS pStaQos = Adapter->MgntInfo.pStaQos; + //AC_CODING eACI; + + priv->slot_time = val[0]; + write_nic_byte(dev, SLOT_TIME, val[0]); + + } + break; + + case HW_VAR_ACK_PREAMBLE: + { + u32 regTmp = 0; + priv->short_preamble = (bool)(*(u8*)val ); + regTmp = priv->basic_rate; + if (priv->short_preamble) + regTmp |= BRSR_AckShortPmb; + write_nic_dword(dev, RRSR, regTmp); + } + break; + + case HW_VAR_CPU_RST: + write_nic_dword(dev, CPU_GEN, ((u32*)(val))[0]); + break; + + default: + break; + } + +} + /////////////////////////////////////////////////////////// @@ -365,11 +500,6 @@ void rtl8192_restart(struct work_struct *work); //void rtl8192_rq_tx_ack(struct work_struct *work); void watch_dog_timer_callback(unsigned long data); -#ifdef ENABLE_IPS -void IPSEnter(struct net_device *dev); -void IPSLeave(struct net_device *dev); -void InactivePsWorkItemCallback(struct net_device *dev); -#endif /**************************************************************************** -----------------------------PROCFS STUFF------------------------- *****************************************************************************/ @@ -707,7 +837,7 @@ static void rtl8192_irq_enable(struct net_device *dev) } -static void rtl8192_irq_disable(struct net_device *dev) +void rtl8192_irq_disable(struct net_device *dev) { struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); @@ -717,6 +847,7 @@ static void rtl8192_irq_disable(struct net_device *dev) } +#if 0 static void rtl8192_set_mode(struct net_device *dev,int mode) { u8 ecmd; @@ -727,7 +858,7 @@ static void rtl8192_set_mode(struct net_device *dev,int mode) ecmd=ecmd &~ (1<<EPROM_CK_SHIFT); write_nic_byte(dev, EPROM_CMD, ecmd); } - +#endif void rtl8192_update_msr(struct net_device *dev) { @@ -861,7 +992,7 @@ static void rtl8192_free_tx_ring(struct net_device *dev, unsigned int prio) ring->desc = NULL; } - +#if 0 static void rtl8192_beacon_disable(struct net_device *dev) { struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); @@ -873,38 +1004,116 @@ static void rtl8192_beacon_disable(struct net_device *dev) reg &= ~(IMR_BcnInt | IMR_BcnInt | IMR_TBDOK | IMR_TBDER); write_nic_dword(priv->ieee80211->dev, INTA_MASK, reg); } +#endif + +void PHY_SetRtl8192eRfOff(struct net_device* dev ) +{ + //struct r8192_priv *priv = ieee80211_priv(dev); + + //disable RF-Chip A/B + rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x0); + //analog to digital off, for power save + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0x300, 0x0); + //digital to analog off, for power save + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x18, 0x0); + //rx antenna off + rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0xf, 0x0); + //rx antenna off + rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0xf, 0x0); + //analog to digital part2 off, for power save + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60, 0x0); + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x4, 0x0); + // Analog parameter!!Change bias and Lbus control. + write_nic_byte(dev, ANAPAR_FOR_8192PciE, 0x07); + +} -void rtl8192_rtx_disable(struct net_device *dev) +void rtl8192_halt_adapter(struct net_device *dev, bool reset) { - u8 cmd; + //u8 cmd; struct r8192_priv *priv = ieee80211_priv(dev); - int i; + int i; + u8 OpMode; + u8 u1bTmp; + u32 ulRegRead; + + OpMode = RT_OP_MODE_NO_LINK; + priv->ieee80211->SetHwRegHandler(dev, HW_VAR_MEDIA_STATUS, &OpMode); +#if 1 + if(!priv->ieee80211->bSupportRemoteWakeUp) + { + u1bTmp = 0x0; // disable tx/rx. In 8185 we write 0x10 (Reset bit), but here we make reference to WMAC and wirte 0x0. 2006.11.21 Emily + //priv->ieee80211->SetHwRegHandler(dev, HW_VAR_COMMAND, &u1bTmp ); // Using HW_VAR_COMMAND instead of writing CMDR directly. Rewrited by Annie, 2006-04-07. + write_nic_byte(dev, CMDR, u1bTmp); + } +#else cmd=read_nic_byte(dev,CMDR); -// if(!priv->ieee80211->bSupportRemoteWakeUp) { - write_nic_byte(dev, CMDR, cmd &~ \ - (CR_TE|CR_RE)); -// } - force_pci_posting(dev); - mdelay(30); + write_nic_byte(dev, CMDR, cmd &~ (CR_TE|CR_RE)); +#endif - for(i = 0; i < MAX_QUEUE_SIZE; i++) { - skb_queue_purge(&priv->ieee80211->skb_waitQ [i]); - } - for(i = 0; i < MAX_QUEUE_SIZE; i++) { - skb_queue_purge(&priv->ieee80211->skb_aggQ [i]); - } + mdelay(20); + if(!reset) + { + //PlatformStallExecution(150000); + mdelay(150); + +#ifdef RTL8192E + priv->bHwRfOffAction = 2; +#endif + + // + // Call MgntActSet_RF_State instead to prevent RF config race condition. + // By Bruce, 2008-01-17. + // + if(!priv->ieee80211->bSupportRemoteWakeUp) + { + //MgntActSet_RF_State(Adapter, eRfOff, RF_CHANGE_BY_INIT); + //MgntActSet_RF_State(Adapter, eRfOff, Adapter->MgntInfo.RfOffReason); + //if(Adapter->HardwareType == HARDWARE_TYPE_RTL8190P) + + PHY_SetRtl8192eRfOff(dev); + + // 2006.11.30. System reset bit + //priv->ieee80211->GetHwRegHandler(dev, HW_VAR_CPU_RST, (u32*)(&ulRegRead) ); + ulRegRead = read_nic_dword(dev,CPU_GEN); + ulRegRead|=CPU_GEN_SYSTEM_RESET; + //priv->ieee80211->SetHwRegHandler(dev, HW_VAR_CPU_RST, &ulRegRead); + write_nic_dword(dev,CPU_GEN, ulRegRead); + } + else + { + //2008.06.03 for WOL + write_nic_dword(dev, WFCRC0, 0xffffffff); + write_nic_dword(dev, WFCRC1, 0xffffffff); + write_nic_dword(dev, WFCRC2, 0xffffffff); + + //Write PMR register + write_nic_byte(dev, PMR, 0x5); + //Disable tx, enanble rx + write_nic_byte(dev, MacBlkCtrl, 0xa); + } + } + + for(i = 0; i < MAX_QUEUE_SIZE; i++) { + skb_queue_purge(&priv->ieee80211->skb_waitQ [i]); + } + for(i = 0; i < MAX_QUEUE_SIZE; i++) { + skb_queue_purge(&priv->ieee80211->skb_aggQ [i]); + } skb_queue_purge(&priv->skb_queue); return; } +#if 0 static void rtl8192_reset(struct net_device *dev) { rtl8192_irq_disable(dev); printk("This is RTL819xP Reset procedure\n"); } +#endif static u16 rtl_rate[] = {10,20,55,110,60,90,120,180,240,360,480,540}; inline u16 rtl8192_rate2rate(short rate) @@ -954,6 +1163,12 @@ static void rtl8192_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, /* shall not be referred by command packet */ assert(queue_index != TXCMD_QUEUE); + if((priv->bHwRadioOff == true)||(!priv->up)) + { + kfree_skb(skb); + return; + } + //spin_lock_irqsave(&priv->tx_lock,flags); memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev)); @@ -996,6 +1211,13 @@ static int rtl8192_hard_start_xmit(struct sk_buff *skb,struct net_device *dev) cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); u8 queue_index = tcb_desc->queue_index; + if(queue_index != TXCMD_QUEUE){ + if((priv->bHwRadioOff == true)||(!priv->up)) + { + kfree_skb(skb); + return 0; + } + } //spin_lock_irqsave(&priv->tx_lock,flags); @@ -1379,6 +1601,15 @@ short rtl8192_tx(struct net_device *dev, struct sk_buff* skb) u8* pda_addr = NULL; int idx; + if(priv->bdisable_nic){ + RT_TRACE(COMP_ERR,"%s: ERR!! Nic is disabled! Can't tx packet len=%d qidx=%d!!!\n", __FUNCTION__, skb->len, tcb_desc->queue_index); + return skb->len; + } + +#ifdef ENABLE_LPS + priv->ieee80211->bAwakePktSent = true; +#endif + mapping = pci_map_single(priv->pdev, skb->data, skb->len, PCI_DMA_TODEVICE); /* collect the tx packets statitcs */ pda_addr = ((u8*)skb->data) + sizeof(TX_FWINFO_8190PCI); @@ -1481,6 +1712,7 @@ short rtl8192_tx(struct net_device *dev, struct sk_buff* skb) if((pdesc->OWN == 1) && (tcb_desc->queue_index != BEACON_QUEUE)) { RT_TRACE(COMP_ERR,"No more TX desc@%d, ring->idx = %d,idx = %d,%x", \ tcb_desc->queue_index,ring->idx, idx,skb->len); + spin_unlock_irqrestore(&priv->irq_th_lock,flags); return skb->len; } @@ -1575,7 +1807,7 @@ static short rtl8192_alloc_rx_desc_ring(struct net_device *dev) return 0; priv->rx_buf[i] = skb; mapping = (dma_addr_t *)skb->cb; - *mapping = pci_map_single(priv->pdev, skb->tail,//skb_tail_pointer(skb), + *mapping = pci_map_single(priv->pdev, skb_tail_pointer(skb), priv->rxbuffersize, PCI_DMA_FROMDEVICE); entry->BufferAddress = cpu_to_le32(*mapping); @@ -1779,7 +2011,7 @@ static void rtl8192_qos_activate(struct work_struct * work) (((u32)(qos_parameters->cw_max[i]))<< AC_PARAM_ECW_MAX_OFFSET)| (((u32)(qos_parameters->cw_min[i]))<< AC_PARAM_ECW_MIN_OFFSET)| ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET)); - printk("===>u4bAcParam:%x, ", u4bAcParam); + //printk("===>u4bAcParam:%x, ", u4bAcParam); write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam); //write_nic_dword(dev, WDCAPARA_ADD[i], 0x005e4332); } @@ -1964,11 +2196,24 @@ void rtl8192_update_ratr_table(struct net_device* dev) write_nic_byte(dev, UFWP, 1); } +#if 0 static u8 ccmp_ie[4] = {0x00,0x50,0xf2,0x04}; static u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04}; +#endif + static bool GetNmodeSupportBySecCfg8190Pci(struct net_device*dev) { #if 1 + + struct r8192_priv *priv = ieee80211_priv(dev); + struct ieee80211_device *ieee = priv->ieee80211; + if (ieee->rtllib_ap_sec_type && + (ieee->rtllib_ap_sec_type(ieee)&(SEC_ALG_WEP|SEC_ALG_TKIP))) { + return false; + } else { + return true; + } +#else struct r8192_priv* priv = ieee80211_priv(dev); struct ieee80211_device* ieee = priv->ieee80211; int wpa_ie_len= ieee->wpa_ie_len; @@ -1995,18 +2240,6 @@ static bool GetNmodeSupportBySecCfg8190Pci(struct net_device*dev) return true; } -#if 0 - //In here we discuss with SD4 David. He think we still can send TKIP in broadcast group key in MCS rate. - //We can't force in G mode if Pairwie key is AES and group key is TKIP - if((pSecInfo->GroupEncAlgorithm == WEP104_Encryption) || (pSecInfo->GroupEncAlgorithm == WEP40_Encryption) || - (pSecInfo->PairwiseEncAlgorithm == WEP104_Encryption) || - (pSecInfo->PairwiseEncAlgorithm == WEP40_Encryption) || (pSecInfo->PairwiseEncAlgorithm == TKIP_Encryption)) - { - return false; - } - else - return true; -#endif return true; #endif } @@ -2080,7 +2313,7 @@ static void rtl8192_SetWirelessMode(struct net_device* dev, u8 wireless_mode) wireless_mode = WIRELESS_MODE_B; } } -#ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we shoud wait for FPGA +#ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we should wait for FPGA ActUpdateChannelAccessSetting( pAdapter, pHalData->CurrentWirelessMode, &pAdapter->MgntInfo.Info8185.ChannelAccessSetting ); #endif priv->ieee80211->mode = wireless_mode; @@ -2127,7 +2360,19 @@ short rtl8192_is_tx_queue_empty(struct net_device *dev) } static void rtl8192_hw_sleep_down(struct net_device *dev) { - RT_TRACE(COMP_POWER, "%s()============>come to sleep down\n", __FUNCTION__); + struct r8192_priv *priv = ieee80211_priv(dev); + unsigned long flags = 0; + + spin_lock_irqsave(&priv->rf_ps_lock,flags); + if (priv->RFChangeInProgress) { + spin_unlock_irqrestore(&priv->rf_ps_lock,flags); + RT_TRACE(COMP_RF, "rtl8192_hw_sleep_down(): RF Change in progress! \n"); + printk("rtl8192_hw_sleep_down(): RF Change in progress!\n"); + return; + } + spin_unlock_irqrestore(&priv->rf_ps_lock,flags); + //RT_TRACE(COMP_PS, "%s()============>come to sleep down\n", __FUNCTION__); + MgntActSet_RF_State(dev, eRfSleep, RF_CHANGE_BY_PS); } static void rtl8192_hw_sleep_wq (struct work_struct *work) @@ -2138,21 +2383,29 @@ static void rtl8192_hw_sleep_wq (struct work_struct *work) struct delayed_work *dwork = container_of(work,struct delayed_work,work); struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_sleep_wq); struct net_device *dev = ieee->dev; - //printk("=========>%s()\n", __FUNCTION__); + rtl8192_hw_sleep_down(dev); } -// printk("dev is %d\n",dev); -// printk("&*&(^*(&(&=========>%s()\n", __FUNCTION__); + static void rtl8192_hw_wakeup(struct net_device* dev) { -// u32 flags = 0; + struct r8192_priv *priv = ieee80211_priv(dev); + unsigned long flags = 0; + + spin_lock_irqsave(&priv->rf_ps_lock,flags); + if (priv->RFChangeInProgress) { + spin_unlock_irqrestore(&priv->rf_ps_lock,flags); + RT_TRACE(COMP_RF, "rtl8192_hw_wakeup(): RF Change in progress! \n"); + printk("rtl8192_hw_wakeup(): RF Change in progress! schedule wake up task again\n"); + queue_delayed_work(priv->ieee80211->wq,&priv->ieee80211->hw_wakeup_wq,MSECS(10));//PowerSave is not supported if kernel version is below 2.6.20 + return; + } + spin_unlock_irqrestore(&priv->rf_ps_lock,flags); -// spin_lock_irqsave(&priv->ps_lock,flags); - RT_TRACE(COMP_POWER, "%s()============>come to wake up\n", __FUNCTION__); + //RT_TRACE(COMP_PS, "%s()============>come to wake up\n", __FUNCTION__); MgntActSet_RF_State(dev, eRfOn, RF_CHANGE_BY_PS); - //FIXME: will we send package stored while nic is sleep? -// spin_unlock_irqrestore(&priv->ps_lock,flags); } + void rtl8192_hw_wakeup_wq (struct work_struct *work) { // struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq); @@ -2169,7 +2422,6 @@ void rtl8192_hw_wakeup_wq (struct work_struct *work) #define MAX_SLEEP_TIME 10000 static void rtl8192_hw_to_sleep(struct net_device *dev, u32 th, u32 tl) { - struct r8192_priv *priv = ieee80211_priv(dev); u32 rb = jiffies; @@ -2177,58 +2429,55 @@ static void rtl8192_hw_to_sleep(struct net_device *dev, u32 th, u32 tl) spin_lock_irqsave(&priv->ps_lock,flags); - /* Writing HW register with 0 equals to disable - * the timer, that is not really what we want - */ - tl -= MSECS(4+16+7); - - //if(tl == 0) tl = 1; - - /* FIXME HACK FIXME HACK */ -// force_pci_posting(dev); - //mdelay(1); - -// rb = read_nic_dword(dev, TSFTR); + // Writing HW register with 0 equals to disable + // the timer, that is not really what we want + // + tl -= MSECS(8+16+7); - /* If the interval in witch we are requested to sleep is too - * short then give up and remain awake - */ + // If the interval in witch we are requested to sleep is too + // short then give up and remain awake + // when we sleep after send null frame, the timer will be too short to sleep. + // if(((tl>=rb)&& (tl-rb) <= MSECS(MIN_SLEEP_TIME)) - ||((rb>tl)&& (rb-tl) < MSECS(MIN_SLEEP_TIME))) { + ||((rb>tl)&& (rb-tl) < MSECS(MIN_SLEEP_TIME))) { spin_unlock_irqrestore(&priv->ps_lock,flags); - printk("too short to sleep\n"); + printk("too short to sleep::%x, %x, %lx\n",tl, rb, MSECS(MIN_SLEEP_TIME)); return; } -// write_nic_dword(dev, TimerInt, tl); -// rb = read_nic_dword(dev, TSFTR); - { - u32 tmp = (tl>rb)?(tl-rb):(rb-tl); - // if (tl<rb) - queue_delayed_work(priv->ieee80211->wq, &priv->ieee80211->hw_wakeup_wq, tmp); //as tl may be less than rb - } - /* if we suspect the TimerInt is gone beyond tl - * while setting it, then give up - */ -#if 1 if(((tl > rb) && ((tl-rb) > MSECS(MAX_SLEEP_TIME)))|| - ((tl < rb) && ((rb-tl) > MSECS(MAX_SLEEP_TIME)))) { + ((tl < rb) && (tl>MSECS(69)) && ((rb-tl) > MSECS(MAX_SLEEP_TIME)))|| + ((tl<rb)&&(tl<MSECS(69))&&((tl+0xffffffff-rb)>MSECS(MAX_SLEEP_TIME)))) { printk("========>too long to sleep:%x, %x, %lx\n", tl, rb, MSECS(MAX_SLEEP_TIME)); spin_unlock_irqrestore(&priv->ps_lock,flags); return; } -#endif -// if(priv->rf_sleep) -// priv->rf_sleep(dev); - - //printk("<=========%s()\n", __FUNCTION__); - queue_delayed_work(priv->ieee80211->wq, (void *)&priv->ieee80211->hw_sleep_wq,0); + { + u32 tmp = (tl>rb)?(tl-rb):(rb-tl); + queue_delayed_work(priv->ieee80211->wq, + &priv->ieee80211->hw_wakeup_wq,tmp); + //PowerSave not supported when kernel version less 2.6.20 + } + queue_delayed_work(priv->ieee80211->wq, + (void *)&priv->ieee80211->hw_sleep_wq,0); spin_unlock_irqrestore(&priv->ps_lock,flags); + } static void rtl8192_init_priv_variable(struct net_device* dev) { struct r8192_priv *priv = ieee80211_priv(dev); u8 i; + PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl)); + + // Default Halt the NIC if RF is OFF. + pPSC->RegRfPsLevel |= RT_RF_OFF_LEVL_HALT_NIC; + pPSC->RegRfPsLevel |= RT_RF_OFF_LEVL_CLK_REQ; + pPSC->RegRfPsLevel |= RT_RF_OFF_LEVL_ASPM; + pPSC->RegRfPsLevel |= RT_RF_LPS_LEVEL_ASPM; + pPSC->bLeisurePs = true; + pPSC->RegMaxLPSAwakeIntvl = 5; + priv->bHwRadioOff = false; + priv->being_init_adapter = false; priv->txbuffsize = 1600;//1024; priv->txfwbuffersize = 4096; @@ -2328,6 +2577,17 @@ static void rtl8192_init_priv_variable(struct net_device* dev) //added by amy priv->ieee80211->InitialGainHandler = InitialGain819xPci; +#ifdef ENABLE_IPS + priv->ieee80211->ieee80211_ips_leave_wq = ieee80211_ips_leave_wq; + priv->ieee80211->ieee80211_ips_leave = ieee80211_ips_leave; +#endif +#ifdef ENABLE_LPS + priv->ieee80211->LeisurePSLeave = LeisurePSLeave; +#endif//ENABL + + priv->ieee80211->SetHwRegHandler = rtl8192e_SetHwReg; + priv->ieee80211->rtllib_ap_sec_type = rtl8192e_ap_sec_type; + priv->card_type = USB; { priv->ShortRetryLimit = 0x30; @@ -2400,6 +2660,10 @@ static void rtl8192_init_priv_task(struct net_device* dev) priv->priv_wq = create_workqueue(DRV_NAME); #endif +#ifdef ENABLE_IPS + INIT_WORK(&priv->ieee80211->ips_leave_wq, (void*)IPSLeave_wq); +#endif + // INIT_WORK(&priv->reset_wq, (void(*)(void*)) rtl8192_restart); INIT_WORK(&priv->reset_wq, rtl8192_restart); // INIT_DELAYED_WORK(&priv->watch_dog_wq, hal_dm_watchdog); @@ -2550,10 +2814,7 @@ static void rtl8192_read_eeprom_info(struct net_device* dev) memcpy(dev->dev_addr, bMac_Tmp_Addr, 6); } - RT_TRACE(COMP_INIT, "Permanent Address = %02x-%02x-%02x-%02x-%02x-%02x\n", - dev->dev_addr[0], dev->dev_addr[1], - dev->dev_addr[2], dev->dev_addr[3], - dev->dev_addr[4], dev->dev_addr[5]); + RT_TRACE(COMP_INIT, "Permanent Address = %pM\n", dev->dev_addr); //2 TX Power Check EEPROM Fail or not if(priv->card_8192_version > VERSION_8190_BD) { @@ -2926,13 +3187,14 @@ static void rtl8192_read_eeprom_info(struct net_device* dev) #endif break; } -/* - //2008.06.03, for WOL + + if( priv->eeprom_vid == 0x1186 && priv->eeprom_did == 0x3304) - priv->ieee80211->bSupportRemoteWakeUp = TRUE; + priv->ieee80211->bSupportRemoteWakeUp = true; else - priv->ieee80211->bSupportRemoteWakeUp = FALSE; -*/ + priv->ieee80211->bSupportRemoteWakeUp = false; + + RT_TRACE(COMP_INIT, "RegChannelPlan(%d)\n", priv->RegChannelPlan); RT_TRACE(COMP_INIT, "ChannelPlan = %d \n", priv->ChannelPlan); RT_TRACE(COMP_INIT, "LedStrategy = %d \n", priv->LedStrategy); @@ -4006,12 +4268,19 @@ static void rtl819x_ifsilentreset(struct net_device *dev) struct ieee80211_device *ieee = priv->ieee80211; + return; + // 2007.07.20. If we need to check CCK stop, please uncomment this line. //bStuck = Adapter->HalFunc.CheckHWStopHandler(Adapter); if(priv->ResetProgress==RESET_TYPE_NORESET) { RESET_START: +#ifdef ENABLE_LPS + //LZM for PS-Poll AID issue. 090429 + if(priv->ieee80211->state == IEEE80211_LINKED) + LeisurePSLeave(dev); +#endif RT_TRACE(COMP_RESET,"=========>Reset progress!! \n"); @@ -4051,9 +4320,9 @@ RESET_START: } else{ printk("ieee->state is NOT LINKED\n"); - ieee80211_softmac_stop_protocol(priv->ieee80211); + ieee80211_softmac_stop_protocol(priv->ieee80211,true); } - rtl8192_rtx_disable(dev); + rtl8192_halt_adapter(dev, true); up(&priv->wx_sem); RT_TRACE(COMP_RESET,"%s():<==========down process is finished\n",__FUNCTION__); RT_TRACE(COMP_RESET,"%s():===========>start to up the driver\n",__FUNCTION__); @@ -4150,6 +4419,128 @@ void InactivePsWorkItemCallback(struct net_device *dev) RT_TRACE(COMP_POWER, "InactivePsWorkItemCallback() <--------- \n"); } +#ifdef ENABLE_LPS +// +// Change current and default preamble mode. +// 2005.01.06, by rcnjko. +// +bool MgntActSet_802_11_PowerSaveMode(struct net_device *dev, u8 rtPsMode) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + //PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl)); + //u8 RpwmVal, FwPwrMode; + + // Currently, we do not change power save mode on IBSS mode. + if(priv->ieee80211->iw_mode == IW_MODE_ADHOC) + { + return false; + } + + // + // <RJ_NOTE> If we make HW to fill up the PwrMgt bit for us, + // some AP will not response to our mgnt frames with PwrMgt bit set, + // e.g. cannot associate the AP. + // So I commented out it. 2005.02.16, by rcnjko. + // +// // Change device's power save mode. +// Adapter->HalFunc.SetPSModeHandler( Adapter, rtPsMode ); + + // Update power save mode configured. + //RT_TRACE(COMP_LPS,"%s(): set ieee->ps = %x\n",__FUNCTION__,rtPsMode); + if(!priv->ps_force) { + priv->ieee80211->ps = rtPsMode; + } + + // Awake immediately + if(priv->ieee80211->sta_sleep != 0 && rtPsMode == IEEE80211_PS_DISABLED) + { + unsigned long flags; + + //PlatformSetTimer(Adapter, &(pMgntInfo->AwakeTimer), 0); + // Notify the AP we awke. + rtl8192_hw_wakeup(dev); + priv->ieee80211->sta_sleep = 0; + + spin_lock_irqsave(&(priv->ieee80211->mgmt_tx_lock), flags); + printk("LPS leave: notify AP we are awaked ++++++++++ SendNullFunctionData\n"); + ieee80211_sta_ps_send_null_frame(priv->ieee80211, 0); + spin_unlock_irqrestore(&(priv->ieee80211->mgmt_tx_lock), flags); + } + + return true; +} + +//================================================================================ +// Leisure Power Save in linked state. +//================================================================================ + +// +// Description: +// Enter the leisure power save mode. +// +void LeisurePSEnter(struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl)); + + //RT_TRACE(COMP_PS, "LeisurePSEnter()...\n"); + //RT_TRACE(COMP_PS, "pPSC->bLeisurePs = %d, ieee->ps = %d,pPSC->LpsIdleCount is %d,RT_CHECK_FOR_HANG_PERIOD is %d\n", + // pPSC->bLeisurePs, priv->ieee80211->ps,pPSC->LpsIdleCount,RT_CHECK_FOR_HANG_PERIOD); + + if(!((priv->ieee80211->iw_mode == IW_MODE_INFRA) && + (priv->ieee80211->state == IEEE80211_LINKED)) || + (priv->ieee80211->iw_mode == IW_MODE_ADHOC) || + (priv->ieee80211->iw_mode == IW_MODE_MASTER)) + return; + + if (pPSC->bLeisurePs) + { + // Idle for a while if we connect to AP a while ago. + if(pPSC->LpsIdleCount >= RT_CHECK_FOR_HANG_PERIOD) // 4 Sec + { + + if(priv->ieee80211->ps == IEEE80211_PS_DISABLED) + { + + //RT_TRACE(COMP_LPS, "LeisurePSEnter(): Enter 802.11 power save mode...\n"); + MgntActSet_802_11_PowerSaveMode(dev, IEEE80211_PS_MBCAST|IEEE80211_PS_UNICAST); + + } + } + else + pPSC->LpsIdleCount++; + } +} + + +// +// Description: +// Leave the leisure power save mode. +// +void LeisurePSLeave(struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl)); + + + //RT_TRACE(COMP_PS, "LeisurePSLeave()...\n"); + //RT_TRACE(COMP_PS, "pPSC->bLeisurePs = %d, ieee->ps = %d\n", + // pPSC->bLeisurePs, priv->ieee80211->ps); + + if (pPSC->bLeisurePs) + { + if(priv->ieee80211->ps != IEEE80211_PS_DISABLED) + { + // move to lps_wakecomplete() + //RT_TRACE(COMP_LPS, "LeisurePSLeave(): Busy Traffic , Leave 802.11 power save..\n"); + MgntActSet_802_11_PowerSaveMode(dev, IEEE80211_PS_DISABLED); + + } + } +} +#endif + + // // Description: // Enter the inactive power save mode. RF will be off @@ -4178,6 +4569,7 @@ IPSEnter(struct net_device *dev) && (priv->ieee80211->state != IEEE80211_LINKED) ) { RT_TRACE(COMP_RF,"IPSEnter(): Turn off RF.\n"); + //printk("IPSEnter(): Turn off RF.\n"); pPSC->eInactivePowerState = eRfOff; // queue_work(priv->priv_wq,&(pPSC->InactivePsWorkItem)); InactivePsWorkItemCallback(dev); @@ -4203,12 +4595,53 @@ IPSLeave(struct net_device *dev) if (rtState != eRfOn && !pPSC->bSwRfProcessing && priv->ieee80211->RfOffReason <= RF_CHANGE_BY_IPS) { RT_TRACE(COMP_POWER, "IPSLeave(): Turn on RF.\n"); + //printk("IPSLeave(): Turn on RF.\n"); pPSC->eInactivePowerState = eRfOn; // queue_work(priv->priv_wq,&(pPSC->InactivePsWorkItem)); InactivePsWorkItemCallback(dev); } } } + +void IPSLeave_wq(void *data) +{ + struct ieee80211_device *ieee = container_of(data,struct ieee80211_device,ips_leave_wq); + struct net_device *dev = ieee->dev; + + struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); + down(&priv->ieee80211->ips_sem); + IPSLeave(dev); + up(&priv->ieee80211->ips_sem); +} + +void ieee80211_ips_leave_wq(struct net_device *dev) +{ + struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); + RT_RF_POWER_STATE rtState; + rtState = priv->ieee80211->eRFPowerState; + + if(priv->ieee80211->PowerSaveControl.bInactivePs){ + if(rtState == eRfOff){ + if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS) + { + RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__); + return; + } + else{ + printk("=========>%s(): IPSLeave\n",__FUNCTION__); + queue_work(priv->ieee80211->wq,&priv->ieee80211->ips_leave_wq); + } + } + } +} +//added by amy 090331 end +void ieee80211_ips_leave(struct net_device *dev) +{ + struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); + down(&priv->ieee80211->ips_sem); + IPSLeave(dev); + up(&priv->ieee80211->ips_sem); +} #endif static void rtl819x_update_rxcounts( @@ -4244,15 +4677,23 @@ void rtl819x_watchdog_wqcallback(struct work_struct *work) unsigned long flags; bool bBusyTraffic = false; static u8 last_time = 0; + bool bEnterPS = false; + + if((!priv->up) || (priv->bHwRadioOff == true)) + return; + if(!priv->up) return; hal_dm_watchdog(dev); #ifdef ENABLE_IPS // printk("watch_dog ENABLE_IPS\n"); if(ieee->actscanning == false){ - if((ieee->iw_mode != IW_MODE_ADHOC) && (ieee->state == IEEE80211_NOLINK) && (ieee->beinretry == false) && (ieee->eRFPowerState == eRfOn) && !ieee->is_set_key){ + //printk("%d,%d,%d,%d\n", ieee->eRFPowerState, ieee->is_set_key, ieee->proto_stoppping, ieee->wx_set_enc); + if((ieee->iw_mode == IW_MODE_INFRA) && (ieee->state == IEEE80211_NOLINK) &&\ + (ieee->eRFPowerState == eRfOn)&&!ieee->is_set_key &&\ + (!ieee->proto_stoppping) && !ieee->wx_set_enc){ if(ieee->PowerSaveControl.ReturnPoint == IPS_CALLBACK_NONE){ - printk("====================>haha:IPSEnter()\n"); + //printk("====================>haha:IPSEnter()\n"); IPSEnter(dev); //ieee80211_stop_scan(priv->ieee80211); } @@ -4262,14 +4703,49 @@ void rtl819x_watchdog_wqcallback(struct work_struct *work) {//to get busy traffic condition if(ieee->state == IEEE80211_LINKED) { - if( ieee->LinkDetectInfo.NumRxOkInPeriod> 666 || - ieee->LinkDetectInfo.NumTxOkInPeriod> 666 ) { + if( ieee->LinkDetectInfo.NumRxOkInPeriod> 100 || + ieee->LinkDetectInfo.NumTxOkInPeriod> 100 ) { bBusyTraffic = true; } +#ifdef ENABLE_LPS + //added by amy for Leisure PS + if( ((ieee->LinkDetectInfo.NumRxUnicastOkInPeriod + ieee->LinkDetectInfo.NumTxOkInPeriod) > 8 ) || + (ieee->LinkDetectInfo.NumRxUnicastOkInPeriod > 2) ) + { + //printk("ieee->LinkDetectInfo.NumRxUnicastOkInPeriod is %d,ieee->LinkDetectInfo.NumTxOkInPeriod is %d\n", + // ieee->LinkDetectInfo.NumRxUnicastOkInPeriod,ieee->LinkDetectInfo.NumTxOkInPeriod); + bEnterPS= false; + } + else + { + bEnterPS= true; + } + + //printk("***bEnterPS = %d\n", bEnterPS); + // LeisurePS only work in infra mode. + if(bEnterPS) + { + LeisurePSEnter(dev); + } + else + { + LeisurePSLeave(dev); + } +#endif + + } + else + { +#ifdef ENABLE_LPS + //RT_TRACE(COMP_LPS,"====>no link LPS leave\n"); + LeisurePSLeave(dev); +#endif } + ieee->LinkDetectInfo.NumRxOkInPeriod = 0; ieee->LinkDetectInfo.NumTxOkInPeriod = 0; + ieee->LinkDetectInfo.NumRxUnicastOkInPeriod = 0; ieee->LinkDetectInfo.bBusyTraffic = bBusyTraffic; } @@ -4288,14 +4764,14 @@ void rtl819x_watchdog_wqcallback(struct work_struct *work) if( ieee->eRFPowerState == eRfOff) RT_TRACE(COMP_ERR,"========>%s()\n",__FUNCTION__); printk("===>%s(): AP is power off,connect another one\n",__FUNCTION__); - // Dot11d_Reset(dev); + // Dot11d_Reset(dev); ieee->state = IEEE80211_ASSOCIATING; notify_wx_assoc_event(priv->ieee80211); - RemovePeerTS(priv->ieee80211,priv->ieee80211->current_network.bssid); + RemovePeerTS(priv->ieee80211,priv->ieee80211->current_network.bssid); ieee->is_roaming = true; ieee->is_set_key = false; - ieee->link_change(dev); - queue_work(ieee->wq, &ieee->associate_procedure_wq); + ieee->link_change(dev); + queue_work(ieee->wq, &ieee->associate_procedure_wq); } } ieee->LinkDetectInfo.NumRecvBcnInPeriod=0; @@ -4348,6 +4824,7 @@ int _rtl8192_up(struct net_device *dev) RT_STATUS init_status = RT_STATUS_SUCCESS; priv->up=1; priv->ieee80211->ieee_up=1; + priv->bdisable_nic = false; //YJ,add,091111 RT_TRACE(COMP_INIT, "Bringing up iface"); init_status = rtl8192_adapter_start(dev); @@ -4422,6 +4899,12 @@ int rtl8192_down(struct net_device *dev) #endif if (priv->up == 0) return -1; +#ifdef ENABLE_LPS + //LZM for PS-Poll AID issue. 090429 + if(priv->ieee80211->state == IEEE80211_LINKED) + LeisurePSLeave(dev); +#endif + priv->up=0; priv->ieee80211->ieee_up = 0; RT_TRACE(COMP_DOWN, "==========>%s()\n", __FUNCTION__); @@ -4459,11 +4942,9 @@ int rtl8192_down(struct net_device *dev) deinit_hal_dm(dev); del_timer_sync(&priv->watch_dog_timer); - ieee80211_softmac_stop_protocol(priv->ieee80211); -#ifdef ENABLE_IPS - MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_INIT); -#endif - rtl8192_rtx_disable(dev); + ieee80211_softmac_stop_protocol(priv->ieee80211,true); + + rtl8192_halt_adapter(dev,false); memset(&priv->ieee80211->current_network, 0 , offsetof(struct ieee80211_network, list)); RT_TRACE(COMP_DOWN, "<==========%s()\n", __FUNCTION__); @@ -4479,10 +4960,10 @@ void rtl8192_commit(struct net_device *dev) if (priv->up == 0) return ; - ieee80211_softmac_stop_protocol(priv->ieee80211); + ieee80211_softmac_stop_protocol(priv->ieee80211,true); rtl8192_irq_disable(dev); - rtl8192_rtx_disable(dev); + rtl8192_halt_adapter(dev,true); _rtl8192_up(dev); } @@ -5806,8 +6287,7 @@ static void rtl8192_rx(struct net_device *dev) skb = new_skb; priv->rx_buf[priv->rx_idx] = skb; - *((dma_addr_t *) skb->cb) = pci_map_single(priv->pdev, skb->tail, priv->rxbuffersize, PCI_DMA_FROMDEVICE); -// *((dma_addr_t *) skb->cb) = pci_map_single(priv->pdev, skb_tail_pointer(skb), priv->rxbuffersize, PCI_DMA_FROMDEVICE); + *((dma_addr_t *) skb->cb) = pci_map_single(priv->pdev, skb_tail_pointer(skb), priv->rxbuffersize, PCI_DMA_FROMDEVICE); } } @@ -6036,7 +6516,7 @@ void rtl8192_cancel_deferred_work(struct r8192_priv* priv) /* call cancel_work_sync instead of cancel_delayed_work if and only if Linux_version_code * is or is newer than 2.6.20 and work structure is defined to be struct work_struct. * Otherwise call cancel_delayed_work is enough. - * FIXME (2.6.20 shoud 2.6.22, work_struct shoud not cancel) + * FIXME (2.6.20 should 2.6.22, work_struct should not cancel) * */ cancel_delayed_work(&priv->watch_dog_wq); cancel_delayed_work(&priv->update_beacon_wq); @@ -6381,11 +6861,13 @@ void setKey( struct net_device *dev, if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS) { RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__); - up(&priv->wx_sem); + //up(&priv->wx_sem); return ; } else{ + down(&priv->ieee80211->ips_sem); IPSLeave(dev); + up(&priv->ieee80211->ips_sem); } } } @@ -6394,7 +6876,7 @@ void setKey( struct net_device *dev, if (EntryNo >= TOTAL_CAM_ENTRY) RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n"); - RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr"MAC_FMT"\n", dev,EntryNo, KeyIndex, KeyType, MAC_ARG(MacAddr)); + RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr%pM\n", dev,EntryNo, KeyIndex, KeyType, MacAddr); if (DefaultKey) usConfig |= BIT15 | (KeyType<<2); @@ -6455,6 +6937,65 @@ void CamPrintDbgReg(struct net_device* dev) RT_TRACE(COMP_SEC, "WPA_Config=%x \n",ucValue); } +bool NicIFEnableNIC(struct net_device* dev) +{ + RT_STATUS init_status = RT_STATUS_SUCCESS; + struct r8192_priv* priv = ieee80211_priv(dev); + PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl)); + + //YJ,add,091109 + if (priv->up == 0){ + RT_TRACE(COMP_ERR, "ERR!!! %s(): Driver is already down!\n",__FUNCTION__); + priv->bdisable_nic = false; //YJ,add,091111 + return false; + } + // <1> Reset memory: descriptor, buffer,.. + //NicIFResetMemory(Adapter); + + // <2> Enable Adapter + //printk("===========>%s()\n",__FUNCTION__); + //priv->bfirst_init = true; + init_status = rtl8192_adapter_start(dev); + if (init_status != RT_STATUS_SUCCESS) { + RT_TRACE(COMP_ERR,"ERR!!! %s(): initialization is failed!\n",__FUNCTION__); + priv->bdisable_nic = false; //YJ,add,091111 + return -1; + } + //printk("start adapter finished\n"); + RT_CLEAR_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC); + //priv->bfirst_init = false; + + // <3> Enable Interrupt + rtl8192_irq_enable(dev); + priv->bdisable_nic = false; + //RT_TRACE(COMP_PS,"<===========%s()\n",__FUNCTION__); + return (init_status == RT_STATUS_SUCCESS) ? true:false; +} +bool NicIFDisableNIC(struct net_device* dev) +{ + bool status = true; + struct r8192_priv* priv = ieee80211_priv(dev); + u8 tmp_state = 0; + // <1> Disable Interrupt + //RT_TRACE(COMP_PS, "=========>%s()\n",__FUNCTION__); + priv->bdisable_nic = true; //YJ,move,091109 + tmp_state = priv->ieee80211->state; + + ieee80211_softmac_stop_protocol(priv->ieee80211, false); + + priv->ieee80211->state = tmp_state; + rtl8192_cancel_deferred_work(priv); + rtl8192_irq_disable(dev); + // <2> Stop all timer + + // <3> Disable Adapter + rtl8192_halt_adapter(dev, false); +// priv->bdisable_nic = true; + //RT_TRACE(COMP_PS, "<=========%s()\n",__FUNCTION__); + + return status; +} + /*************************************************************************** ------------------- module init / exit stubs ---------------- diff --git a/drivers/staging/rtl8192e/r8192E_dm.c b/drivers/staging/rtl8192e/r8192E_dm.c index 5ffb4f7..a249f00 100644 --- a/drivers/staging/rtl8192e/r8192E_dm.c +++ b/drivers/staging/rtl8192e/r8192E_dm.c @@ -19,26 +19,28 @@ Major Change History: #include "r819xE_phy.h" #include "r819xE_phyreg.h" #include "r8190_rtl8256.h" + +#define DRV_NAME "rtl819xE" /*---------------------------Define Local Constant---------------------------*/ // // Indicate different AP vendor for IOT issue. // #ifdef RTL8190P static u32 edca_setting_DL[HT_IOT_PEER_MAX] = -{ 0x5e4322, 0x5e4322, 0x5e4322, 0x604322, 0xa44f, 0x5e4322}; +{ 0x5e4322, 0x5e4322, 0x5e4322, 0x604322, 0xa44f, 0x5e4322, 0x5e4322}; static u32 edca_setting_UL[HT_IOT_PEER_MAX] = -{ 0x5e4322, 0xa44f, 0x5e4322, 0x604322, 0x5e4322, 0x5e4322}; +{ 0x5e4322, 0xa44f, 0x5e4322, 0x604322, 0x5e4322, 0x5e4322, 0x5e4322}; #else #ifdef RTL8192E static u32 edca_setting_DL[HT_IOT_PEER_MAX] = -{ 0x5e4322, 0x5e4322, 0x5e4322, 0x604322, 0xa44f, 0x5e4322}; +{ 0x5e4322, 0x5e4322, 0x5e4322, 0x604322, 0xa44f, 0x5e4322, 0x5e4322}; static u32 edca_setting_UL[HT_IOT_PEER_MAX] = -{ 0x5e4322, 0xa44f, 0x5e4322, 0x604322, 0x5e4322, 0x5e4322}; +{ 0x5e4322, 0xa44f, 0x5e4322, 0x604322, 0x5e4322, 0x5e4322, 0x5e4322}; #else static u32 edca_setting_DL[HT_IOT_PEER_MAX] = -{ 0x5e4322, 0x5e4322, 0x5e4322, 0x604322, 0xa44f, 0x5ea44f}; +{ 0x5e4322, 0x5e4322, 0x5e4322, 0x604322, 0xa44f, 0x5ea44f, 0x5e4322}; static u32 edca_setting_UL[HT_IOT_PEER_MAX] = -{ 0x5e4322, 0xa44f, 0x5e4322, 0x604322, 0x5ea44f, 0x5ea44f}; +{ 0x5e4322, 0xa44f, 0x5e4322, 0x604322, 0x5ea44f, 0x5ea44f, 0x5e4322}; #endif #endif @@ -275,6 +277,30 @@ void dm_CheckRxAggregation(struct net_device *dev) { #endif +// call the script file to enable +void dm_check_ac_dc_power(struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + static char *ac_dc_check_script_path = "/etc/acpi/wireless-rtl-ac-dc-power.sh"; + char *argv[] = {ac_dc_check_script_path,DRV_NAME,NULL}; + static char *envp[] = {"HOME=/", + "TERM=linux", + "PATH=/usr/bin:/bin", + NULL}; + + if(priv->ResetProgress == RESET_TYPE_SILENT) + { + RT_TRACE((COMP_INIT | COMP_POWER | COMP_RF), "GPIOChangeRFWorkItemCallBack(): Silent Reseting!!!!!!!\n"); + return; + } + + if(priv->ieee80211->state != IEEE80211_LINKED) { + return; + } + call_usermodehelper(ac_dc_check_script_path,argv,envp,1); + + return; +}; void hal_dm_watchdog(struct net_device *dev) { @@ -282,6 +308,8 @@ void hal_dm_watchdog(struct net_device *dev) //static u8 previous_bssid[6] ={0}; + dm_check_ac_dc_power(dev); + /*Add by amy 2008/05/15 ,porting from windows code.*/ dm_check_rate_adaptive(dev); dm_dynamic_txpower(dev); diff --git a/drivers/staging/rtl8192e/r8192E_hw.h b/drivers/staging/rtl8192e/r8192E_hw.h index 388908f..346bfb1 100644 --- a/drivers/staging/rtl8192e/r8192E_hw.h +++ b/drivers/staging/rtl8192e/r8192E_hw.h @@ -808,4 +808,12 @@ enum _RTL8192Pci_HW { #define GPI 0x108 #define GPO 0x109 #define GPE 0x10a + +#define ANAPAR_FOR_8192PciE 0x17 // Analog parameter register + +#define MSR_NOLINK 0x00 +#define MSR_ADHOC 0x01 +#define MSR_INFRA 0x02 +#define MSR_AP 0x03 + #endif diff --git a/drivers/staging/rtl8192e/r8192E_wx.c b/drivers/staging/rtl8192e/r8192E_wx.c index d1eb892..0b0f39c 100644 --- a/drivers/staging/rtl8192e/r8192E_wx.c +++ b/drivers/staging/rtl8192e/r8192E_wx.c @@ -22,7 +22,7 @@ #include "r8192E_hw.h" #include "r8192E_wx.h" #ifdef ENABLE_DOT11D -#include "dot11d.h" +#include "ieee80211/dot11d.h" #endif #define RATE_COUNT 12 @@ -70,6 +70,9 @@ static int r8192_wx_set_rate(struct net_device *dev, int ret; struct r8192_priv *priv = ieee80211_priv(dev); + if(priv->bHwRadioOff == true) + return 0; + down(&priv->wx_sem); ret = ieee80211_wx_set_rate(priv->ieee80211,info,wrqu,extra); @@ -87,6 +90,9 @@ static int r8192_wx_set_rts(struct net_device *dev, int ret; struct r8192_priv *priv = ieee80211_priv(dev); + if(priv->bHwRadioOff == true) + return 0; + down(&priv->wx_sem); ret = ieee80211_wx_set_rts(priv->ieee80211,info,wrqu,extra); @@ -111,6 +117,9 @@ static int r8192_wx_set_power(struct net_device *dev, int ret; struct r8192_priv *priv = ieee80211_priv(dev); + if(priv->bHwRadioOff == true) + return 0; + down(&priv->wx_sem); ret = ieee80211_wx_set_power(priv->ieee80211,info,wrqu,extra); @@ -290,6 +299,9 @@ static int r8192_wx_set_rawtx(struct net_device *dev, struct r8192_priv *priv = ieee80211_priv(dev); int ret; + if(priv->bHwRadioOff == true) + return 0; + down(&priv->wx_sem); ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra); @@ -325,6 +337,9 @@ static int r8192_wx_set_crcmon(struct net_device *dev, int enable = (parms[0] > 0); short prev = priv->crcmon; + if(priv->bHwRadioOff == true) + return 0; + down(&priv->wx_sem); if(enable) @@ -352,6 +367,9 @@ static int r8192_wx_set_mode(struct net_device *dev, struct iw_request_info *a, RT_RF_POWER_STATE rtState; int ret; + if(priv->bHwRadioOff == true) + return 0; + rtState = priv->ieee80211->eRFPowerState; down(&priv->wx_sem); #ifdef ENABLE_IPS @@ -366,8 +384,10 @@ static int r8192_wx_set_mode(struct net_device *dev, struct iw_request_info *a, return -1; } else{ - printk("=========>%s(): IPSLeave\n",__FUNCTION__); + RT_TRACE(COMP_ERR, "%s(): IPSLeave\n",__FUNCTION__); + down(&priv->ieee80211->ips_sem); IPSLeave(dev); + up(&priv->ieee80211->ips_sem); } } } @@ -425,7 +445,7 @@ static int rtl8180_wx_get_range(struct net_device *dev, */ /* ~5 Mb/s real (802.11b) */ - range->throughput = 5 * 1000 * 1000; + range->throughput = 130 * 1000 * 1000; // TODO: Not used in 802.11b? // range->min_nwid; /* Minimal NWID we are able to set */ @@ -468,7 +488,7 @@ static int rtl8180_wx_get_range(struct net_device *dev, range->pmt_flags = IW_POWER_TIMEOUT; range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R; range->we_version_compiled = WIRELESS_EXT; - range->we_version_source = 16; + range->we_version_source = 18; // range->retry_capa; /* What retry options are supported */ // range->retry_flags; /* How to decode max/min retry limit */ @@ -517,7 +537,12 @@ static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a, struct ieee80211_device* ieee = priv->ieee80211; RT_RF_POWER_STATE rtState; int ret; + + if(priv->bHwRadioOff == true) + return 0; + rtState = priv->ieee80211->eRFPowerState; + if(!priv->up) return -ENETDOWN; if (priv->ieee80211->LinkDetectInfo.bBusyTraffic == true) return -EAGAIN; @@ -547,8 +572,10 @@ static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a, return -1; } else{ - printk("=========>%s(): IPSLeave\n",__FUNCTION__); + //RT_TRACE(COMP_PS, "%s(): IPSLeave\n",__FUNCTION__); + down(&priv->ieee80211->ips_sem); IPSLeave(dev); + up(&priv->ieee80211->ips_sem); } } } @@ -580,6 +607,9 @@ static int r8192_wx_get_scan(struct net_device *dev, struct iw_request_info *a, int ret; struct r8192_priv *priv = ieee80211_priv(dev); + if(priv->bHwRadioOff == true) + return 0; + if(!priv->up) return -ENETDOWN; down(&priv->wx_sem); @@ -599,23 +629,16 @@ static int r8192_wx_set_essid(struct net_device *dev, RT_RF_POWER_STATE rtState; int ret; + if(priv->bHwRadioOff == true) + return 0; + rtState = priv->ieee80211->eRFPowerState; down(&priv->wx_sem); + #ifdef ENABLE_IPS - if(priv->ieee80211->PowerSaveControl.bInactivePs){ - if(rtState == eRfOff){ - if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS) - { - RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__); - up(&priv->wx_sem); - return -1; - } - else{ - printk("=========>%s(): IPSLeave\n",__FUNCTION__); - IPSLeave(dev); - } - } - } + down(&priv->ieee80211->ips_sem); + IPSLeave(dev); + up(&priv->ieee80211->ips_sem); #endif ret = ieee80211_wx_set_essid(priv->ieee80211,a,wrqu,b); @@ -650,6 +673,9 @@ static int r8192_wx_set_freq(struct net_device *dev, struct iw_request_info *a, int ret; struct r8192_priv *priv = ieee80211_priv(dev); + if(priv->bHwRadioOff == true) + return 0; + down(&priv->wx_sem); ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b); @@ -673,6 +699,9 @@ static int r8192_wx_set_frag(struct net_device *dev, { struct r8192_priv *priv = ieee80211_priv(dev); + if(priv->bHwRadioOff == true) + return 0; + if (wrqu->frag.disabled) priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD; else { @@ -711,8 +740,16 @@ static int r8192_wx_set_wap(struct net_device *dev, struct r8192_priv *priv = ieee80211_priv(dev); // struct sockaddr *temp = (struct sockaddr *)awrq; + if(priv->bHwRadioOff == true) + return 0; + down(&priv->wx_sem); +#ifdef ENABLE_IPS + down(&priv->ieee80211->ips_sem); + IPSLeave(dev); + up(&priv->ieee80211->ips_sem); +#endif ret = ieee80211_wx_set_wap(priv->ieee80211,info,awrq,extra); up(&priv->wx_sem); @@ -753,14 +790,24 @@ static int r8192_wx_set_enc(struct net_device *dev, u32 hwkey[4]={0,0,0,0}; u8 mask=0xff; u32 key_idx=0; - u8 zero_addr[4][6] ={ {0x00,0x00,0x00,0x00,0x00,0x00}, + u8 zero_addr[4][6] ={{0x00,0x00,0x00,0x00,0x00,0x00}, {0x00,0x00,0x00,0x00,0x00,0x01}, {0x00,0x00,0x00,0x00,0x00,0x02}, {0x00,0x00,0x00,0x00,0x00,0x03} }; int i; + if(priv->bHwRadioOff == true) + return 0; + if(!priv->up) return -ENETDOWN; + priv->ieee80211->wx_set_enc = 1; +#ifdef ENABLE_IPS + down(&priv->ieee80211->ips_sem); + IPSLeave(dev); + up(&priv->ieee80211->ips_sem); +#endif + down(&priv->wx_sem); RT_TRACE(COMP_SEC, "Setting SW wep key"); @@ -768,7 +815,6 @@ static int r8192_wx_set_enc(struct net_device *dev, up(&priv->wx_sem); - //sometimes, the length is zero while we do not type key value if(wrqu->encoding.length!=0){ @@ -868,6 +914,8 @@ static int r8192_wx_set_enc(struct net_device *dev, } #endif + priv->ieee80211->wx_set_enc = 0; + return ret; } @@ -893,6 +941,9 @@ static int r8192_wx_set_retry(struct net_device *dev, struct r8192_priv *priv = ieee80211_priv(dev); int err = 0; + if(priv->bHwRadioOff == true) + return 0; + down(&priv->wx_sem); if (wrqu->retry.flags & IW_RETRY_LIFETIME || @@ -985,6 +1036,10 @@ static int r8192_wx_set_sens(struct net_device *dev, struct r8192_priv *priv = ieee80211_priv(dev); short err = 0; + + if(priv->bHwRadioOff == true) + return 0; + down(&priv->wx_sem); //DMESG("attempt to set sensivity to %ddb",wrqu->sens.value); if(priv->rf_set_sens == NULL) { @@ -1011,7 +1066,19 @@ static int r8192_wx_set_enc_ext(struct net_device *dev, struct r8192_priv *priv = ieee80211_priv(dev); struct ieee80211_device* ieee = priv->ieee80211; + if(priv->bHwRadioOff == true) + return 0; + down(&priv->wx_sem); + + priv->ieee80211->wx_set_enc = 1; + +#ifdef ENABLE_IPS + down(&priv->ieee80211->ips_sem); + IPSLeave(dev); + up(&priv->ieee80211->ips_sem); +#endif + ret = ieee80211_wx_set_encode_ext(ieee, info, wrqu, extra); { @@ -1091,6 +1158,7 @@ static int r8192_wx_set_enc_ext(struct net_device *dev, } end_hw_sec: + priv->ieee80211->wx_set_enc = 0; up(&priv->wx_sem); return ret; @@ -1102,6 +1170,10 @@ static int r8192_wx_set_auth(struct net_device *dev, int ret=0; //printk("====>%s()\n", __FUNCTION__); struct r8192_priv *priv = ieee80211_priv(dev); + + if(priv->bHwRadioOff == true) + return 0; + down(&priv->wx_sem); ret = ieee80211_wx_set_auth(priv->ieee80211, info, &(data->param), extra); up(&priv->wx_sem); @@ -1116,6 +1188,10 @@ static int r8192_wx_set_mlme(struct net_device *dev, int ret=0; struct r8192_priv *priv = ieee80211_priv(dev); + + if(priv->bHwRadioOff == true) + return 0; + down(&priv->wx_sem); ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra); up(&priv->wx_sem); @@ -1129,6 +1205,10 @@ static int r8192_wx_set_gen_ie(struct net_device *dev, //printk("====>%s(), len:%d\n", __FUNCTION__, data->length); int ret=0; struct r8192_priv *priv = ieee80211_priv(dev); + + if(priv->bHwRadioOff == true) + return 0; + down(&priv->wx_sem); ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->data.length); up(&priv->wx_sem); @@ -1142,6 +1222,42 @@ static int dummy(struct net_device *dev, struct iw_request_info *a, return -1; } +// check ac/dc status with the help of user space application */ +static int r8192_wx_adapter_power_status(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8192_priv *priv = ieee80211_priv(dev); +#ifdef ENABLE_LPS + PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl)); + struct ieee80211_device* ieee = priv->ieee80211; +#endif + down(&priv->wx_sem); + +#ifdef ENABLE_LPS + RT_TRACE(COMP_POWER, "%s(): %s\n",__FUNCTION__, (*extra == 6)?"DC power":"AC power"); + // ieee->ps shall not be set under DC mode, otherwise it conflict + // with Leisure power save mode setting. + // + if(*extra || priv->force_lps) { + priv->ps_force = false; + pPSC->bLeisurePs = true; + } else { + //LZM for PS-Poll AID issue. 090429 + if(priv->ieee80211->state == IEEE80211_LINKED) + LeisurePSLeave(dev); + + priv->ps_force = true; + pPSC->bLeisurePs = false; + ieee->ps = *extra; + } + +#endif + up(&priv->wx_sem); + return 0; + +} + static iw_handler r8192_wx_handlers[] = { @@ -1231,72 +1347,28 @@ static const struct iw_priv_args r8192_private_args[] = { SIOCIWFIRSTPRIV + 0x2, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx" } -#ifdef JOHN_IOCTL , { SIOCIWFIRSTPRIV + 0x3, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readRF" + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset" + } , { SIOCIWFIRSTPRIV + 0x4, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeRF" - } - , - { - SIOCIWFIRSTPRIV + 0x5, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readBB" - } - , - { - SIOCIWFIRSTPRIV + 0x6, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeBB" - } - , - { - SIOCIWFIRSTPRIV + 0x7, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readnicb" - } - , - { - SIOCIWFIRSTPRIV + 0x8, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writenicb" - } - , - { - SIOCIWFIRSTPRIV + 0x9, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo" - } - -#endif - , - { - SIOCIWFIRSTPRIV + 0x3, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset" - + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED|1, IW_PRIV_TYPE_NONE, + "set_power" } }; static iw_handler r8192_private_handler[] = { -// r8192_wx_set_monitor, /* SIOCIWFIRSTPRIV */ r8192_wx_set_crcmon, /*SIOCIWSECONDPRIV*/ -// r8192_wx_set_forceassociate, -// r8192_wx_set_beaconinterval, -// r8192_wx_set_monitor_type, r8192_wx_set_scan_type, r8192_wx_set_rawtx, -#ifdef JOHN_IOCTL - r8192_wx_read_regs, - r8192_wx_write_regs, - r8192_wx_read_bb, - r8192_wx_write_bb, - r8192_wx_read_nicb, - r8192_wx_write_nicb, - r8192_wx_get_ap_status -#endif r8192_wx_force_reset, + r8192_wx_adapter_power_status, }; //#if WIRELESS_EXT >= 17 diff --git a/drivers/staging/rtl8192e/r8192E_wx.h b/drivers/staging/rtl8192e/r8192E_wx.h index 79ebdb6..047030b 100644 --- a/drivers/staging/rtl8192e/r8192E_wx.h +++ b/drivers/staging/rtl8192e/r8192E_wx.h @@ -15,7 +15,6 @@ #ifndef R8180_WX_H #define R8180_WX_H //#include <linux/wireless.h> -//#include "ieee80211.h" extern struct iw_handler_def r8192_wx_handlers_def; /* Enable the rtl819x_core.c to share this function, david 2008.9.22 */ extern struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev); diff --git a/drivers/staging/rtl8192e/r819xE_cmdpkt.c b/drivers/staging/rtl8192e/r819xE_cmdpkt.c index 2aaa4e1..87c334f 100644 --- a/drivers/staging/rtl8192e/r819xE_cmdpkt.c +++ b/drivers/staging/rtl8192e/r819xE_cmdpkt.c @@ -135,7 +135,7 @@ RT_STATUS cmpk_message_handle_tx( * Transform from little endian to big endian * and pending zero */ - seg_ptr = skb->tail; + seg_ptr = skb_tail_pointer(skb); for(i=0 ; i < frag_length; i+=4) { *seg_ptr++ = ((i+0)<frag_length)?code_virtual_address[i+3]:0; *seg_ptr++ = ((i+1)<frag_length)?code_virtual_address[i+2]:0; diff --git a/drivers/staging/rtl8192e/r819xE_firmware.c b/drivers/staging/rtl8192e/r819xE_firmware.c index 1f9e413..793a175 100644 --- a/drivers/staging/rtl8192e/r819xE_firmware.c +++ b/drivers/staging/rtl8192e/r819xE_firmware.c @@ -1,5 +1,5 @@ /* - * Procedure: Init boot code/firmware code/data session + * Procedure: Init boot code/firmware code/data session * * Description: This routine will intialize firmware. If any error occurs * during the initialization process, the routine shall terminate @@ -7,19 +7,21 @@ * NdisOpenFile only from MiniportInitialize. * * Arguments: The pointer of the adapter - + * * Returns: * NDIS_STATUS_FAILURE - the following initialization process * should be terminated * NDIS_STATUS_SUCCESS - if firmware initialization process * success */ + #include "r8192E.h" #include "r8192E_hw.h" + #include <linux/firmware.h> /* It should be double word alignment */ -#define GET_COMMAND_PACKET_FRAG_THRESHOLD(v) (4 * (v / 4) - 8) +#define GET_COMMAND_PACKET_FRAG_THRESHOLD(v) (4 * (v / 4) - 8) enum firmware_init_step { FW_INIT_STEP0_BOOT = 0, @@ -47,17 +49,17 @@ void firmware_init_param(struct net_device *dev) static bool fw_download_code(struct net_device *dev, u8 *code_virtual_address, u32 buffer_len) { - struct r8192_priv *priv = ieee80211_priv(dev); - bool rt_status = true; - u16 frag_threshold; - u16 frag_length, frag_offset = 0; - int i; - - rt_firmware *pfirmware = priv->pFirmware; - struct sk_buff *skb; - unsigned char *seg_ptr; - cb_desc *tcb_desc; - u8 bLastIniPkt; + struct r8192_priv *priv = ieee80211_priv(dev); + bool rt_status = true; + u16 frag_threshold; + u16 frag_length, frag_offset = 0; + int i; + + rt_firmware *pfirmware = priv->pFirmware; + struct sk_buff *skb; + unsigned char *seg_ptr; + cb_desc *tcb_desc; + u8 bLastIniPkt; firmware_init_param(dev); @@ -89,10 +91,17 @@ static bool fw_download_code(struct net_device *dev, u8 *code_virtual_address, * Transform from little endian to big endian and pending zero */ for (i = 0; i < frag_length; i += 4) { - *seg_ptr++ = ((i+0) < frag_length) ? code_virtual_address[i+3] : 0; - *seg_ptr++ = ((i+1) < frag_length) ? code_virtual_address[i+2] : 0; - *seg_ptr++ = ((i+2) < frag_length) ? code_virtual_address[i+1] : 0; - *seg_ptr++ = ((i+3) < frag_length) ? code_virtual_address[i+0] : 0; + *seg_ptr++ = ((i+0) < frag_length) ? \ + code_virtual_address[i+3] : 0; + + *seg_ptr++ = ((i+1) < frag_length) ? \ + code_virtual_address[i+2] : 0; + + *seg_ptr++ = ((i+2) < frag_length) ? \ + code_virtual_address[i+1] : 0; + + *seg_ptr++ = ((i+3) < frag_length) ? \ + code_virtual_address[i+0] : 0; } tcb_desc->txbuf_size = (u16)i; skb_put(skb, i); @@ -204,16 +213,16 @@ CPUCheckFirmwareReady_Fail: bool init_firmware(struct net_device *dev) { - struct r8192_priv *priv = ieee80211_priv(dev); - bool rt_status = TRUE; - u32 file_length = 0; - u8 *mapped_file = NULL; - u32 init_step = 0; - enum opt_rst_type rst_opt = OPT_SYSTEM_RESET; + struct r8192_priv *priv = ieee80211_priv(dev); + bool rt_status = true; + u32 file_length = 0; + u8 *mapped_file = NULL; + u32 init_step = 0; + enum opt_rst_type rst_opt = OPT_SYSTEM_RESET; enum firmware_init_step starting_state = FW_INIT_STEP0_BOOT; - rt_firmware *pfirmware = priv->pFirmware; - const struct firmware *fw_entry; + rt_firmware *pfirmware = priv->pFirmware; + const struct firmware *fw_entry; const char *fw_name[3] = { "RTL8192E/boot.img", "RTL8192E/main.img", "RTL8192E/data.img"}; @@ -240,31 +249,37 @@ bool init_firmware(struct net_device *dev) * Download boot, main, and data image for System reset. * Download data image for firmware reseta */ - for (init_step = starting_state; init_step <= FW_INIT_STEP2_DATA; init_step++) { + for (init_step = starting_state; init_step <= FW_INIT_STEP2_DATA; \ + init_step++) { /* * Open Image file, and map file to contineous memory if open file success. * or read image file from array. Default load from IMG file */ if (rst_opt == OPT_SYSTEM_RESET) { if (pfirmware->firmware_buf_size[init_step] == 0) { - rc = request_firmware(&fw_entry, fw_name[init_step], &priv->pdev->dev); + rc = request_firmware(&fw_entry, + fw_name[init_step], &priv->pdev->dev); + if (rc < 0) { RT_TRACE(COMP_FIRMWARE, "request firmware fail!\n"); goto download_firmware_fail; } if (fw_entry->size > sizeof(pfirmware->firmware_buf[init_step])) { - RT_TRACE(COMP_FIRMWARE, "img file size exceed the container buffer fail!\n"); + RT_TRACE(COMP_FIRMWARE, \ + "img file size exceed the container buffer fail!\n"); goto download_firmware_fail; } if (init_step != FW_INIT_STEP1_MAIN) { - memcpy(pfirmware->firmware_buf[init_step], fw_entry->data, fw_entry->size); + memcpy(pfirmware->firmware_buf[init_step], + fw_entry->data, fw_entry->size); pfirmware->firmware_buf_size[init_step] = fw_entry->size; } else { memset(pfirmware->firmware_buf[init_step], 0, 128); - memcpy(&pfirmware->firmware_buf[init_step][128], fw_entry->data, fw_entry->size); + memcpy(&pfirmware->firmware_buf[init_step][128], fw_entry->data, + fw_entry->size); pfirmware->firmware_buf_size[init_step] = fw_entry->size+128; } @@ -273,6 +288,7 @@ bool init_firmware(struct net_device *dev) } mapped_file = pfirmware->firmware_buf[init_step]; file_length = pfirmware->firmware_buf_size[init_step]; + } else if (rst_opt == OPT_FIRMWARE_RESET) { /* we only need to download data.img here */ mapped_file = pfirmware->firmware_buf[init_step]; @@ -346,7 +362,10 @@ bool init_firmware(struct net_device *dev) download_firmware_fail: RT_TRACE(COMP_ERR, "ERR in %s()\n", __func__); - rt_status = FALSE; + rt_status = false; return rt_status; - } + +MODULE_FIRMWARE("RTL8192E/boot.img"); +MODULE_FIRMWARE("RTL8192E/main.img"); +MODULE_FIRMWARE("RTL8192E/data.img"); diff --git a/drivers/staging/rtl8192e/r819xE_phy.c b/drivers/staging/rtl8192e/r819xE_phy.c index c44059a..7bd4fae 100644 --- a/drivers/staging/rtl8192e/r819xE_phy.c +++ b/drivers/staging/rtl8192e/r819xE_phy.c @@ -5,7 +5,7 @@ #include "r819xE_phy.h" #include "r8192E_dm.h" #ifdef ENABLE_DOT11D -#include "dot11d.h" +#include "ieee80211/dot11d.h" #endif static u32 RF_CHANNEL_TABLE_ZEBRA[] = { 0, diff --git a/drivers/staging/rtl8192e/r819xE_phy.h b/drivers/staging/rtl8192e/r819xE_phy.h index fa77abe..41e0d77 100644 --- a/drivers/staging/rtl8192e/r819xE_phy.h +++ b/drivers/staging/rtl8192e/r819xE_phy.h @@ -1,43 +1,46 @@ #ifndef _R819XU_PHY_H #define _R819XU_PHY_H -/* Channel switch:The size of command tables for switch channel*/ + +/* Channel switch: the size of command tables for switch channel */ #define MAX_PRECMD_CNT 16 #define MAX_RFDEPENDCMD_CNT 16 #define MAX_POSTCMD_CNT 16 #ifdef RTL8190P #define MACPHY_Array_PGLength 21 -#define Rtl819XMACPHY_Array_PG Rtl8190PciMACPHY_Array_PG -#define Rtl819XMACPHY_Array Rtl8190PciMACPHY_Array +#define Rtl819XMACPHY_Array_PG Rtl8190PciMACPHY_Array_PG +#define Rtl819XMACPHY_Array Rtl8190PciMACPHY_Array #define RadioC_ArrayLength 246 #define RadioD_ArrayLength 78 -#define Rtl819XRadioA_Array Rtl8190PciRadioA_Array -#define Rtl819XRadioB_Array Rtl8190PciRadioB_Array -#define Rtl819XRadioC_Array Rtl8190PciRadioC_Array -#define Rtl819XRadioD_Array Rtl8190PciRadioD_Array -#define Rtl819XAGCTAB_Array Rtl8190PciAGCTAB_Array -#define PHY_REGArrayLength 280 -#define Rtl819XPHY_REGArray Rtl8190PciPHY_REGArray -#define PHY_REG_1T2RArrayLength 280 -#define Rtl819XPHY_REG_1T2RArray Rtl8190PciPHY_REG_1T2RArray +#define Rtl819XRadioA_Array Rtl8190PciRadioA_Array +#define Rtl819XRadioB_Array Rtl8190PciRadioB_Array +#define Rtl819XRadioC_Array Rtl8190PciRadioC_Array +#define Rtl819XRadioD_Array Rtl8190PciRadioD_Array +#define Rtl819XAGCTAB_Array Rtl8190PciAGCTAB_Array +#define PHY_REGArrayLength 280 +#define Rtl819XPHY_REGArray Rtl8190PciPHY_REGArray +#define PHY_REG_1T2RArrayLength 280 +#define Rtl819XPHY_REG_1T2RArray Rtl8190PciPHY_REG_1T2RArray +#endif + + +#ifdef RTL8192E +#define MACPHY_Array_PGLength 30 +#define Rtl819XMACPHY_Array_PG Rtl8192PciEMACPHY_Array_PG +#define Rtl819XMACPHY_Array Rtl8192PciEMACPHY_Array +#define RadioC_ArrayLength 1 +#define RadioD_ArrayLength 1 +#define Rtl819XRadioA_Array Rtl8192PciERadioA_Array +#define Rtl819XRadioB_Array Rtl8192PciERadioB_Array +#define Rtl819XRadioC_Array Rtl8192PciERadioC_Array +#define Rtl819XRadioD_Array Rtl8192PciERadioD_Array +#define Rtl819XAGCTAB_Array Rtl8192PciEAGCTAB_Array +#define PHY_REGArrayLength 1 +#define Rtl819XPHY_REGArray Rtl8192PciEPHY_REGArray +#define PHY_REG_1T2RArrayLength 296 +#define Rtl819XPHY_REG_1T2RArray Rtl8192PciEPHY_REG_1T2RArray #endif - #ifdef RTL8192E - #define MACPHY_Array_PGLength 30 - #define Rtl819XMACPHY_Array_PG Rtl8192PciEMACPHY_Array_PG - #define Rtl819XMACPHY_Array Rtl8192PciEMACPHY_Array - #define RadioC_ArrayLength 1 - #define RadioD_ArrayLength 1 - #define Rtl819XRadioA_Array Rtl8192PciERadioA_Array - #define Rtl819XRadioB_Array Rtl8192PciERadioB_Array - #define Rtl819XRadioC_Array Rtl8192PciERadioC_Array - #define Rtl819XRadioD_Array Rtl8192PciERadioD_Array - #define Rtl819XAGCTAB_Array Rtl8192PciEAGCTAB_Array - #define PHY_REGArrayLength 1 - #define Rtl819XPHY_REGArray Rtl8192PciEPHY_REGArray - #define PHY_REG_1T2RArrayLength 296 - #define Rtl819XPHY_REG_1T2RArray Rtl8192PciEPHY_REG_1T2RArray - #endif #define AGCTAB_ArrayLength 384 #define MACPHY_ArrayLength 18 @@ -45,7 +48,7 @@ #define RadioB_ArrayLength 78 -typedef enum _SwChnlCmdID{ +typedef enum _SwChnlCmdID { CmdID_End, CmdID_SetTxPowerLevel, CmdID_BBRegWrite10, @@ -53,16 +56,15 @@ typedef enum _SwChnlCmdID{ CmdID_WritePortUshort, CmdID_WritePortUchar, CmdID_RF_WriteReg, -}SwChnlCmdID; +} SwChnlCmdID; -/*--------------------------------Define structure--------------------------------*/ -/* 1. Switch channel related */ -typedef struct _SwChnlCmd{ - SwChnlCmdID CmdID; - u32 Para1; - u32 Para2; - u32 msDelay; -}__attribute__ ((packed)) SwChnlCmd; +/* switch channel data structure */ +typedef struct _SwChnlCmd { + SwChnlCmdID CmdID; + u32 Para1; + u32 Para2; + u32 msDelay; +} __attribute__ ((packed)) SwChnlCmd; extern u32 rtl819XMACPHY_Array_PG[]; extern u32 rtl819XPHY_REG_1T2RArray[]; @@ -72,54 +74,90 @@ extern u32 rtl819XRadioB_Array[]; extern u32 rtl819XRadioC_Array[]; extern u32 rtl819XRadioD_Array[]; -typedef enum _HW90_BLOCK{ +typedef enum _HW90_BLOCK { HW90_BLOCK_MAC = 0, HW90_BLOCK_PHY0 = 1, HW90_BLOCK_PHY1 = 2, HW90_BLOCK_RF = 3, - HW90_BLOCK_MAXIMUM = 4, // Never use this -}HW90_BLOCK_E, *PHW90_BLOCK_E; - -typedef enum _RF90_RADIO_PATH{ - RF90_PATH_A = 0, //Radio Path A - RF90_PATH_B = 1, //Radio Path B - RF90_PATH_C = 2, //Radio Path C - RF90_PATH_D = 3, //Radio Path D - RF90_PATH_MAX //Max RF number 92 support -}RF90_RADIO_PATH_E, *PRF90_RADIO_PATH_E; - -#define bMaskByte0 0xff -#define bMaskByte1 0xff00 -#define bMaskByte2 0xff0000 -#define bMaskByte3 0xff000000 -#define bMaskHWord 0xffff0000 -#define bMaskLWord 0x0000ffff -#define bMaskDWord 0xffffffff - -//extern u32 rtl8192_CalculateBitShift(u32 dwBitMask); -extern u8 rtl8192_phy_CheckIsLegalRFPath(struct net_device* dev, u32 eRFPath); -extern void rtl8192_setBBreg(struct net_device* dev, u32 dwRegAddr, u32 dwBitMask, u32 dwData); -extern u32 rtl8192_QueryBBReg(struct net_device* dev, u32 dwRegAddr, u32 dwBitMask); -//extern u32 rtl8192_phy_RFSerialRead(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 Offset); -//extern void rtl8192_phy_RFSerialWrite(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 Offset, u32 Data); -extern void rtl8192_phy_SetRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 RegAddr, u32 BitMask, u32 Data); -extern u32 rtl8192_phy_QueryRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 RegAddr, u32 BitMask); -extern void rtl8192_phy_configmac(struct net_device* dev); -extern void rtl8192_phyConfigBB(struct net_device* dev, u8 ConfigType); -//extern void rtl8192_InitBBRFRegDef(struct net_device* dev); -extern RT_STATUS rtl8192_phy_checkBBAndRF(struct net_device* dev, HW90_BLOCK_E CheckBlock, RF90_RADIO_PATH_E eRFPath); -//extern RT_STATUS rtl8192_BB_Config_ParaFile(struct net_device* dev); -extern RT_STATUS rtl8192_BBConfig(struct net_device* dev); -extern void rtl8192_phy_getTxPower(struct net_device* dev); -extern void rtl8192_phy_setTxPower(struct net_device* dev, u8 channel); + /* Don't ever use this. */ + HW90_BLOCK_MAXIMUM = 4, +} HW90_BLOCK_E, *PHW90_BLOCK_E; + +typedef enum _RF90_RADIO_PATH { + /* Radio paths */ + RF90_PATH_A = 0, + RF90_PATH_B = 1, + RF90_PATH_C = 2, + RF90_PATH_D = 3, + + /* Max RF number 92 support */ + RF90_PATH_MAX +} RF90_RADIO_PATH_E, *PRF90_RADIO_PATH_E; + +#define bMaskByte0 0xff +#define bMaskByte1 0xff00 +#define bMaskByte2 0xff0000 +#define bMaskByte3 0xff000000 +#define bMaskHWord 0xffff0000 +#define bMaskLWord 0x0000ffff +#define bMaskDWord 0xffffffff + +/*extern u32 rtl8192_CalculateBitShift(u32 dwBitMask); + +extern u32 rtl8192_phy_RFSerialRead(struct net_device *dev, + RF90_RADIO_PATH_E eRFPath, u32 Offset); + +extern void rtl8192_phy_RFSerialWrite(struct net_device *dev, + RF90_RADIO_PATH_E eRFPath, u32 Offset, u32 Data); + +extern void rtl8192_InitBBRFRegDef(struct net_device *dev); + +extern RT_STATUS rtl8192_BB_Config_ParaFile(struct net_device *dev); */ + +extern u8 rtl8192_phy_CheckIsLegalRFPath(struct net_device *dev, u32 eRFPath); + +extern void rtl8192_setBBreg(struct net_device *dev, u32 dwRegAddr, + u32 dwBitMask, u32 dwData); + +extern u32 rtl8192_QueryBBReg(struct net_device *dev, u32 dwRegAddr, + u32 dwBitMask); + +extern void rtl8192_phy_SetRFReg(struct net_device *dev, + RF90_RADIO_PATH_E eRFPath, u32 RegAddr, + u32 BitMask, u32 Data); + +extern u32 rtl8192_phy_QueryRFReg(struct net_device *dev, + RF90_RADIO_PATH_E eRFPath, u32 RegAddr, u32 BitMask); + +extern void rtl8192_phy_configmac(struct net_device *dev); + +extern void rtl8192_phyConfigBB(struct net_device *dev, u8 ConfigType); + +extern RT_STATUS rtl8192_phy_checkBBAndRF(struct net_device *dev, + HW90_BLOCK_E CheckBlock, RF90_RADIO_PATH_E eRFPath); + +extern RT_STATUS rtl8192_BBConfig(struct net_device *dev); + +extern void rtl8192_phy_getTxPower(struct net_device *dev); + +extern void rtl8192_phy_setTxPower(struct net_device *dev, u8 channel); + extern RT_STATUS rtl8192_phy_RFConfig(struct net_device* dev); + extern void rtl8192_phy_updateInitGain(struct net_device* dev); -extern u8 rtl8192_phy_ConfigRFWithHeaderFile(struct net_device* dev, RF90_RADIO_PATH_E eRFPath); -extern u8 rtl8192_phy_SwChnl(struct net_device* dev, u8 channel); -extern void rtl8192_SetBWMode(struct net_device *dev, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset); +extern u8 rtl8192_phy_ConfigRFWithHeaderFile(struct net_device *dev, + RF90_RADIO_PATH_E eRFPath); + +extern u8 rtl8192_phy_SwChnl(struct net_device *dev, u8 channel); + +extern void rtl8192_SetBWMode(struct net_device *dev, + HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset); + extern void rtl8192_SwChnl_WorkItem(struct net_device *dev); + extern void rtl8192_SetBWModeWorkItem(struct net_device *dev); + extern void InitialGain819xPci(struct net_device *dev, u8 Operation); -#endif +#endif /* _R819XU_PHY_H */ diff --git a/drivers/staging/rtl8192e/r819xE_phyreg.h b/drivers/staging/rtl8192e/r819xE_phyreg.h index 37f0fee..d5de279 100644 --- a/drivers/staging/rtl8192e/r819xE_phyreg.h +++ b/drivers/staging/rtl8192e/r819xE_phyreg.h @@ -38,6 +38,8 @@ #define MCS_TXAGC 0x340 // MCS AGC #define CCK_TXAGC 0x348 // CCK AGC +#define MacBlkCtrl 0x403 // Mac block on/off control register + //page8 #define rFPGA0_RFMOD 0x800 //RF mode & CCK TxSC #define rFPGA0_TxInfo 0x804 @@ -79,55 +81,70 @@ #define rFPGA0_XB_LSSIReadBack 0x8a4 #define rFPGA0_XC_LSSIReadBack 0x8a8 #define rFPGA0_XD_LSSIReadBack 0x8ac -#define rFPGA0_PSDReport 0x8b4 +#define rFPGA0_PSDReport 0x8b4 #define rFPGA0_XAB_RFInterfaceRB 0x8e0 #define rFPGA0_XCD_RFInterfaceRB 0x8e4 -//page 9 -#define rFPGA1_RFMOD 0x900 //RF mode & OFDM TxSC -#define rFPGA1_TxBlock 0x904 -#define rFPGA1_DebugSelect 0x908 -#define rFPGA1_TxInfo 0x90c - -//page a -#define rCCK0_System 0xa00 -#define rCCK0_AFESetting 0xa04 -#define rCCK0_CCA 0xa08 -#define rCCK0_RxAGC1 0xa0c //AGC default value, saturation level -#define rCCK0_RxAGC2 0xa10 //AGC & DAGC -#define rCCK0_RxHP 0xa14 -#define rCCK0_DSPParameter1 0xa18 //Timing recovery & Channel estimation threshold -#define rCCK0_DSPParameter2 0xa1c //SQ threshold -#define rCCK0_TxFilter1 0xa20 -#define rCCK0_TxFilter2 0xa24 -#define rCCK0_DebugPort 0xa28 //debug port and Tx filter3 -#define rCCK0_FalseAlarmReport 0xa2c //0xa2d -#define rCCK0_TRSSIReport 0xa50 -#define rCCK0_RxReport 0xa54 //0xa57 -#define rCCK0_FACounterLower 0xa5c //0xa5b -#define rCCK0_FACounterUpper 0xa58 //0xa5c - -//page c -#define rOFDM0_LSTF 0xc00 +/* Page 9 - RF mode & OFDM TxSC */ +#define rFPGA1_RFMOD 0x900 +#define rFPGA1_TxBlock 0x904 +#define rFPGA1_DebugSelect 0x908 +#define rFPGA1_TxInfo 0x90c + +/* Page a */ +#define rCCK0_System 0xa00 +#define rCCK0_AFESetting 0xa04 +#define rCCK0_CCA 0xa08 +/* AGC default value, saturation level */ +#define rCCK0_RxAGC1 0xa0c +/* AGC & DAGC */ +#define rCCK0_RxAGC2 0xa10 +#define rCCK0_RxHP 0xa14 +/* Timing recovery & channel estimation threshold */ +#define rCCK0_DSPParameter1 0xa18 +/* SQ threshold */ +#define rCCK0_DSPParameter2 0xa1c +#define rCCK0_TxFilter1 0xa20 +#define rCCK0_TxFilter2 0xa24 +/* Debug port and TX filter 3 */ +#define rCCK0_DebugPort 0xa28 +#define rCCK0_FalseAlarmReport 0xa2c +#define rCCK0_TRSSIReport 0xa50 +#define rCCK0_RxReport 0xa54 +#define rCCK0_FACounterLower 0xa5c +#define rCCK0_FACounterUpper 0xa58 + +/* Page c */ +#define rOFDM0_LSTF 0xc00 #define rOFDM0_TRxPathEnable 0xc04 -#define rOFDM0_TRMuxPar 0xc08 -#define rOFDM0_TRSWIsolation 0xc0c -#define rOFDM0_XARxAFE 0xc10 //RxIQ DC offset, Rx digital filter, DC notch filter -#define rOFDM0_XARxIQImbalance 0xc14 //RxIQ imblance matrix -#define rOFDM0_XBRxAFE 0xc18 +#define rOFDM0_TRMuxPar 0xc08 +#define rOFDM0_TRSWIsolation 0xc0c +/* RxIQ DC offset, Rx digital filter, DC notch filter */ +#define rOFDM0_XARxAFE 0xc10 +/* RxIQ imblance matrix */ +#define rOFDM0_XARxIQImbalance 0xc14 +#define rOFDM0_XBRxAFE 0xc18 #define rOFDM0_XBRxIQImbalance 0xc1c -#define rOFDM0_XCRxAFE 0xc20 +#define rOFDM0_XCRxAFE 0xc20 #define rOFDM0_XCRxIQImbalance 0xc24 -#define rOFDM0_XDRxAFE 0xc28 +#define rOFDM0_XDRxAFE 0xc28 #define rOFDM0_XDRxIQImbalance 0xc2c -#define rOFDM0_RxDetector1 0xc30 //PD,BW & SBD -#define rOFDM0_RxDetector2 0xc34 //SBD & Fame Sync. -#define rOFDM0_RxDetector3 0xc38 //Frame Sync. -#define rOFDM0_RxDetector4 0xc3c //PD, SBD, Frame Sync & Short-GI -#define rOFDM0_RxDSP 0xc40 //Rx Sync Path -#define rOFDM0_CFOandDAGC 0xc44 //CFO & DAGC -#define rOFDM0_CCADropThreshold 0xc48 //CCA Drop threshold -#define rOFDM0_ECCAThreshold 0xc4c // energy CCA +/* PD, BW & SBD */ +#define rOFDM0_RxDetector1 0xc30 +/* SBD */ +#define rOFDM0_RxDetector2 0xc34 +/* Frame Sync */ +#define rOFDM0_RxDetector3 0xc38 +/* PD, SBD, Frame Sync & Short-GI */ +#define rOFDM0_RxDetector4 0xc3c +/* Rx Sync Path */ +#define rOFDM0_RxDSP 0xc40 +/* CFO & DAGC */ +#define rOFDM0_CFOandDAGC 0xc44 +/* CCA Drop threshold */ +#define rOFDM0_CCADropThreshold 0xc48 +/* Energy CCA */ +#define rOFDM0_ECCAThreshold 0xc4c #define rOFDM0_XAAGCCore1 0xc50 #define rOFDM0_XAAGCCore2 0xc54 #define rOFDM0_XBAGCCore1 0xc58 @@ -139,501 +156,517 @@ #define rOFDM0_AGCParameter1 0xc70 #define rOFDM0_AGCParameter2 0xc74 #define rOFDM0_AGCRSSITable 0xc78 -#define rOFDM0_HTSTFAGC 0xc7c +#define rOFDM0_HTSTFAGC 0xc7c #define rOFDM0_XATxIQImbalance 0xc80 -#define rOFDM0_XATxAFE 0xc84 +#define rOFDM0_XATxAFE 0xc84 #define rOFDM0_XBTxIQImbalance 0xc88 -#define rOFDM0_XBTxAFE 0xc8c +#define rOFDM0_XBTxAFE 0xc8c #define rOFDM0_XCTxIQImbalance 0xc90 -#define rOFDM0_XCTxAFE 0xc94 +#define rOFDM0_XCTxAFE 0xc94 #define rOFDM0_XDTxIQImbalance 0xc98 -#define rOFDM0_XDTxAFE 0xc9c +#define rOFDM0_XDTxAFE 0xc9c #define rOFDM0_RxHPParameter 0xce0 #define rOFDM0_TxPseudoNoiseWgt 0xce4 -#define rOFDM0_FrameSync 0xcf0 -#define rOFDM0_DFSReport 0xcf4 -#define rOFDM0_TxCoeff1 0xca4 -#define rOFDM0_TxCoeff2 0xca8 -#define rOFDM0_TxCoeff3 0xcac -#define rOFDM0_TxCoeff4 0xcb0 -#define rOFDM0_TxCoeff5 0xcb4 -#define rOFDM0_TxCoeff6 0xcb8 - - -//page d -#define rOFDM1_LSTF 0xd00 +#define rOFDM0_FrameSync 0xcf0 +#define rOFDM0_DFSReport 0xcf4 +#define rOFDM0_TxCoeff1 0xca4 +#define rOFDM0_TxCoeff2 0xca8 +#define rOFDM0_TxCoeff3 0xcac +#define rOFDM0_TxCoeff4 0xcb0 +#define rOFDM0_TxCoeff5 0xcb4 +#define rOFDM0_TxCoeff6 0xcb8 + + +/* Page d */ +#define rOFDM1_LSTF 0xd00 #define rOFDM1_TRxPathEnable 0xd04 -#define rOFDM1_CFO 0xd08 -#define rOFDM1_CSI1 0xd10 -#define rOFDM1_SBD 0xd14 -#define rOFDM1_CSI2 0xd18 -#define rOFDM1_CFOTracking 0xd2c +#define rOFDM1_CFO 0xd08 +#define rOFDM1_CSI1 0xd10 +#define rOFDM1_SBD 0xd14 +#define rOFDM1_CSI2 0xd18 +#define rOFDM1_CFOTracking 0xd2c #define rOFDM1_TRxMesaure1 0xd34 -#define rOFDM1_IntfDet 0xd3c -#define rOFDM1_PseudoNoiseStateAB 0xd50 -#define rOFDM1_PseudoNoiseStateCD 0xd54 -#define rOFDM1_RxPseudoNoiseWgt 0xd58 -#define rOFDM_PHYCounter1 0xda0 //cca, parity fail -#define rOFDM_PHYCounter2 0xda4 //rate illegal, crc8 fail -#define rOFDM_PHYCounter3 0xda8 //MCS not support -#define rOFDM_ShortCFOAB 0xdac -#define rOFDM_ShortCFOCD 0xdb0 -#define rOFDM_LongCFOAB 0xdb4 -#define rOFDM_LongCFOCD 0xdb8 -#define rOFDM_TailCFOAB 0xdbc -#define rOFDM_TailCFOCD 0xdc0 +#define rOFDM1_IntfDet 0xd3c +#define rOFDM1_PseudoNoiseStateAB 0xd50 +#define rOFDM1_PseudoNoiseStateCD 0xd54 +#define rOFDM1_RxPseudoNoiseWgt 0xd58 +/* cca, parity fail */ +#define rOFDM_PHYCounter1 0xda0 +/* rate illegal, crc8 fail */ +#define rOFDM_PHYCounter2 0xda4 +/* MCS not supported */ +#define rOFDM_PHYCounter3 0xda8 +#define rOFDM_ShortCFOAB 0xdac +#define rOFDM_ShortCFOCD 0xdb0 +#define rOFDM_LongCFOAB 0xdb4 +#define rOFDM_LongCFOCD 0xdb8 +#define rOFDM_TailCFOAB 0xdbc +#define rOFDM_TailCFOCD 0xdc0 #define rOFDM_PWMeasure1 0xdc4 #define rOFDM_PWMeasure2 0xdc8 -#define rOFDM_BWReport 0xdcc -#define rOFDM_AGCReport 0xdd0 -#define rOFDM_RxSNR 0xdd4 -#define rOFDM_RxEVMCSI 0xdd8 -#define rOFDM_SIGReport 0xddc - -//page e -#define rTxAGC_Rate18_06 0xe00 -#define rTxAGC_Rate54_24 0xe04 -#define rTxAGC_CCK_Mcs32 0xe08 -#define rTxAGC_Mcs03_Mcs00 0xe10 -#define rTxAGC_Mcs07_Mcs04 0xe14 -#define rTxAGC_Mcs11_Mcs08 0xe18 -#define rTxAGC_Mcs15_Mcs12 0xe1c - - -//RF -//Zebra1 +#define rOFDM_BWReport 0xdcc +#define rOFDM_AGCReport 0xdd0 +#define rOFDM_RxSNR 0xdd4 +#define rOFDM_RxEVMCSI 0xdd8 +#define rOFDM_SIGReport 0xddc + +/* Page e */ +#define rTxAGC_Rate18_06 0xe00 +#define rTxAGC_Rate54_24 0xe04 +#define rTxAGC_CCK_Mcs32 0xe08 +#define rTxAGC_Mcs03_Mcs00 0xe10 +#define rTxAGC_Mcs07_Mcs04 0xe14 +#define rTxAGC_Mcs11_Mcs08 0xe18 +#define rTxAGC_Mcs15_Mcs12 0xe1c + + +/* RF Zebra 1 */ #define rZebra1_HSSIEnable 0x0 #define rZebra1_TRxEnable1 0x1 #define rZebra1_TRxEnable2 0x2 -#define rZebra1_AGC 0x4 +#define rZebra1_AGC 0x4 #define rZebra1_ChargePump 0x5 -#define rZebra1_Channel 0x7 -#define rZebra1_TxGain 0x8 -#define rZebra1_TxLPF 0x9 -#define rZebra1_RxLPF 0xb +#define rZebra1_Channel 0x7 +#define rZebra1_TxGain 0x8 +#define rZebra1_TxLPF 0x9 +#define rZebra1_RxLPF 0xb #define rZebra1_RxHPFCorner 0xc -//Zebra4 -#define rGlobalCtrl 0 -#define rRTL8256_TxLPF 19 -#define rRTL8256_RxLPF 11 +/* Zebra 4 */ +#define rGlobalCtrl 0 +#define rRTL8256_TxLPF 19 +#define rRTL8256_RxLPF 11 -//RTL8258 -#define rRTL8258_TxLPF 0x11 -#define rRTL8258_RxLPF 0x13 +/* RTL8258 */ +#define rRTL8258_TxLPF 0x11 +#define rRTL8258_RxLPF 0x13 #define rRTL8258_RSSILPF 0xa -//Bit Mask -//page-1 -#define bBBResetB 0x100 -#define bGlobalResetB 0x200 -#define bOFDMTxStart 0x4 -#define bCCKTxStart 0x8 -#define bCRC32Debug 0x100 -#define bPMACLoopback 0x10 -#define bTxLSIG 0xffffff -#define bOFDMTxRate 0xf -#define bOFDMTxReserved 0x10 -#define bOFDMTxLength 0x1ffe0 -#define bOFDMTxParity 0x20000 -#define bTxHTSIG1 0xffffff -#define bTxHTMCSRate 0x7f -#define bTxHTBW 0x80 -#define bTxHTLength 0xffff00 -#define bTxHTSIG2 0xffffff -#define bTxHTSmoothing 0x1 -#define bTxHTSounding 0x2 -#define bTxHTReserved 0x4 -#define bTxHTAggreation 0x8 -#define bTxHTSTBC 0x30 -#define bTxHTAdvanceCoding 0x40 -#define bTxHTShortGI 0x80 -#define bTxHTNumberHT_LTF 0x300 -#define bTxHTCRC8 0x3fc00 -#define bCounterReset 0x10000 -#define bNumOfOFDMTx 0xffff -#define bNumOfCCKTx 0xffff0000 -#define bTxIdleInterval 0xffff -#define bOFDMService 0xffff0000 -#define bTxMACHeader 0xffffffff -#define bTxDataInit 0xff -#define bTxHTMode 0x100 -#define bTxDataType 0x30000 -#define bTxRandomSeed 0xffffffff -#define bCCKTxPreamble 0x1 -#define bCCKTxSFD 0xffff0000 -#define bCCKTxSIG 0xff -#define bCCKTxService 0xff00 -#define bCCKLengthExt 0x8000 -#define bCCKTxLength 0xffff0000 -#define bCCKTxCRC16 0xffff -#define bCCKTxStatus 0x1 -#define bOFDMTxStatus 0x2 - -//page-8 -#define bRFMOD 0x1 -#define bJapanMode 0x2 -#define bCCKTxSC 0x30 -#define bCCKEn 0x1000000 -#define bOFDMEn 0x2000000 -#define bOFDMRxADCPhase 0x10000 -#define bOFDMTxDACPhase 0x40000 -#define bXATxAGC 0x3f -#define bXBTxAGC 0xf00 -#define bXCTxAGC 0xf000 -#define bXDTxAGC 0xf0000 -#define bPAStart 0xf0000000 -#define bTRStart 0x00f00000 -#define bRFStart 0x0000f000 -#define bBBStart 0x000000f0 -#define bBBCCKStart 0x0000000f -#define bPAEnd 0xf //Reg0x814 -#define bTREnd 0x0f000000 -#define bRFEnd 0x000f0000 -#define bCCAMask 0x000000f0 //T2R -#define bR2RCCAMask 0x00000f00 -#define bHSSI_R2TDelay 0xf8000000 -#define bHSSI_T2RDelay 0xf80000 -#define bContTxHSSI 0x400 //channel gain at continue Tx -#define bIGFromCCK 0x200 -#define bAGCAddress 0x3f -#define bRxHPTx 0x7000 -#define bRxHPT2R 0x38000 -#define bRxHPCCKIni 0xc0000 -#define bAGCTxCode 0xc00000 -#define bAGCRxCode 0x300000 -#define b3WireDataLength 0x800 -#define b3WireAddressLength 0x400 -#define b3WireRFPowerDown 0x1 -//#define bHWSISelect 0x8 -#define b5GPAPEPolarity 0x40000000 -#define b2GPAPEPolarity 0x80000000 -#define bRFSW_TxDefaultAnt 0x3 -#define bRFSW_TxOptionAnt 0x30 -#define bRFSW_RxDefaultAnt 0x300 -#define bRFSW_RxOptionAnt 0x3000 -#define bRFSI_3WireData 0x1 -#define bRFSI_3WireClock 0x2 -#define bRFSI_3WireLoad 0x4 -#define bRFSI_3WireRW 0x8 -#define bRFSI_3Wire 0xf //3-wire total control -#define bRFSI_RFENV 0x10 -#define bRFSI_TRSW 0x20 -#define bRFSI_TRSWB 0x40 -#define bRFSI_ANTSW 0x100 -#define bRFSI_ANTSWB 0x200 -#define bRFSI_PAPE 0x400 -#define bRFSI_PAPE5G 0x800 -#define bBandSelect 0x1 -#define bHTSIG2_GI 0x80 -#define bHTSIG2_Smoothing 0x01 -#define bHTSIG2_Sounding 0x02 -#define bHTSIG2_Aggreaton 0x08 -#define bHTSIG2_STBC 0x30 -#define bHTSIG2_AdvCoding 0x40 +/* Bit Mask */ +/* Page 1 */ +#define bBBResetB 0x100 +#define bGlobalResetB 0x200 +#define bOFDMTxStart 0x4 +#define bCCKTxStart 0x8 +#define bCRC32Debug 0x100 +#define bPMACLoopback 0x10 +#define bTxLSIG 0xffffff +#define bOFDMTxRate 0xf +#define bOFDMTxReserved 0x10 +#define bOFDMTxLength 0x1ffe0 +#define bOFDMTxParity 0x20000 +#define bTxHTSIG1 0xffffff +#define bTxHTMCSRate 0x7f +#define bTxHTBW 0x80 +#define bTxHTLength 0xffff00 +#define bTxHTSIG2 0xffffff +#define bTxHTSmoothing 0x1 +#define bTxHTSounding 0x2 +#define bTxHTReserved 0x4 +#define bTxHTAggreation 0x8 +#define bTxHTSTBC 0x30 +#define bTxHTAdvanceCoding 0x40 +#define bTxHTShortGI 0x80 +#define bTxHTNumberHT_LTF 0x300 +#define bTxHTCRC8 0x3fc00 +#define bCounterReset 0x10000 +#define bNumOfOFDMTx 0xffff +#define bNumOfCCKTx 0xffff0000 +#define bTxIdleInterval 0xffff +#define bOFDMService 0xffff0000 +#define bTxMACHeader 0xffffffff +#define bTxDataInit 0xff +#define bTxHTMode 0x100 +#define bTxDataType 0x30000 +#define bTxRandomSeed 0xffffffff +#define bCCKTxPreamble 0x1 +#define bCCKTxSFD 0xffff0000 +#define bCCKTxSIG 0xff +#define bCCKTxService 0xff00 +#define bCCKLengthExt 0x8000 +#define bCCKTxLength 0xffff0000 +#define bCCKTxCRC16 0xffff +#define bCCKTxStatus 0x1 +#define bOFDMTxStatus 0x2 + +/* Page 8 */ +#define bRFMOD 0x1 +#define bJapanMode 0x2 +#define bCCKTxSC 0x30 +#define bCCKEn 0x1000000 +#define bOFDMEn 0x2000000 +#define bOFDMRxADCPhase 0x10000 +#define bOFDMTxDACPhase 0x40000 +#define bXATxAGC 0x3f +#define bXBTxAGC 0xf00 +#define bXCTxAGC 0xf000 +#define bXDTxAGC 0xf0000 +#define bPAStart 0xf0000000 +#define bTRStart 0x00f00000 +#define bRFStart 0x0000f000 +#define bBBStart 0x000000f0 +#define bBBCCKStart 0x0000000f +/* Reg)x814 */ +#define bPAEnd 0xf +#define bTREnd 0x0f000000 +#define bRFEnd 0x000f0000 +/* T2R */ +#define bCCAMask 0x000000f0 +#define bR2RCCAMask 0x00000f00 +#define bHSSI_R2TDelay 0xf8000000 +#define bHSSI_T2RDelay 0xf80000 +/* Channel gain at continue TX. */ +#define bContTxHSSI 0x400 +#define bIGFromCCK 0x200 +#define bAGCAddress 0x3f +#define bRxHPTx 0x7000 +#define bRxHPT2R 0x38000 +#define bRxHPCCKIni 0xc0000 +#define bAGCTxCode 0xc00000 +#define bAGCRxCode 0x300000 +#define b3WireDataLength 0x800 +#define b3WireAddressLength 0x400 +#define b3WireRFPowerDown 0x1 +/*#define bHWSISelect 0x8 */ +#define b5GPAPEPolarity 0x40000000 +#define b2GPAPEPolarity 0x80000000 +#define bRFSW_TxDefaultAnt 0x3 +#define bRFSW_TxOptionAnt 0x30 +#define bRFSW_RxDefaultAnt 0x300 +#define bRFSW_RxOptionAnt 0x3000 +#define bRFSI_3WireData 0x1 +#define bRFSI_3WireClock 0x2 +#define bRFSI_3WireLoad 0x4 +#define bRFSI_3WireRW 0x8 +/* 3-wire total control */ +#define bRFSI_3Wire 0xf +#define bRFSI_RFENV 0x10 +#define bRFSI_TRSW 0x20 +#define bRFSI_TRSWB 0x40 +#define bRFSI_ANTSW 0x100 +#define bRFSI_ANTSWB 0x200 +#define bRFSI_PAPE 0x400 +#define bRFSI_PAPE5G 0x800 +#define bBandSelect 0x1 +#define bHTSIG2_GI 0x80 +#define bHTSIG2_Smoothing 0x01 +#define bHTSIG2_Sounding 0x02 +#define bHTSIG2_Aggreaton 0x08 +#define bHTSIG2_STBC 0x30 +#define bHTSIG2_AdvCoding 0x40 #define bHTSIG2_NumOfHTLTF 0x300 -#define bHTSIG2_CRC8 0x3fc -#define bHTSIG1_MCS 0x7f -#define bHTSIG1_BandWidth 0x80 -#define bHTSIG1_HTLength 0xffff -#define bLSIG_Rate 0xf -#define bLSIG_Reserved 0x10 -#define bLSIG_Length 0x1fffe -#define bLSIG_Parity 0x20 -#define bCCKRxPhase 0x4 -#define bLSSIReadAddress 0x3f000000 //LSSI "Read" Address -#define bLSSIReadEdge 0x80000000 //LSSI "Read" edge signal -#define bLSSIReadBackData 0xfff -#define bLSSIReadOKFlag 0x1000 -#define bCCKSampleRate 0x8 //0: 44MHz, 1:88MHz - -#define bRegulator0Standby 0x1 -#define bRegulatorPLLStandby 0x2 -#define bRegulator1Standby 0x4 -#define bPLLPowerUp 0x8 -#define bDPLLPowerUp 0x10 -#define bDA10PowerUp 0x20 -#define bAD7PowerUp 0x200 -#define bDA6PowerUp 0x2000 -#define bXtalPowerUp 0x4000 -#define b40MDClkPowerUP 0x8000 -#define bDA6DebugMode 0x20000 -#define bDA6Swing 0x380000 -#define bADClkPhase 0x4000000 -#define b80MClkDelay 0x18000000 -#define bAFEWatchDogEnable 0x20000000 -#define bXtalCap 0x0f000000 -#define bXtalCap01 0xc0000000 -#define bXtalCap23 0x3 -#define bXtalCap92x 0x0f000000 -#define bIntDifClkEnable 0x400 -#define bExtSigClkEnable 0x800 +#define bHTSIG2_CRC8 0x3fc +#define bHTSIG1_MCS 0x7f +#define bHTSIG1_BandWidth 0x80 +#define bHTSIG1_HTLength 0xffff +#define bLSIG_Rate 0xf +#define bLSIG_Reserved 0x10 +#define bLSIG_Length 0x1fffe +#define bLSIG_Parity 0x20 +#define bCCKRxPhase 0x4 +/* LSSI "read" address */ +#define bLSSIReadAddress 0x3f000000 +/* LSSI "read" edge signal */ +#define bLSSIReadEdge 0x80000000 +#define bLSSIReadBackData 0xfff +#define bLSSIReadOKFlag 0x1000 +/* 0: 44 MHz, 1: 88MHz */ +#define bCCKSampleRate 0x8 + +#define bRegulator0Standby 0x1 +#define bRegulatorPLLStandby 0x2 +#define bRegulator1Standby 0x4 +#define bPLLPowerUp 0x8 +#define bDPLLPowerUp 0x10 +#define bDA10PowerUp 0x20 +#define bAD7PowerUp 0x200 +#define bDA6PowerUp 0x2000 +#define bXtalPowerUp 0x4000 +#define b40MDClkPowerUP 0x8000 +#define bDA6DebugMode 0x20000 +#define bDA6Swing 0x380000 +#define bADClkPhase 0x4000000 +#define b80MClkDelay 0x18000000 +#define bAFEWatchDogEnable 0x20000000 +#define bXtalCap 0x0f000000 +#define bXtalCap01 0xc0000000 +#define bXtalCap23 0x3 +#define bXtalCap92x 0x0f000000 +#define bIntDifClkEnable 0x400 +#define bExtSigClkEnable 0x800 #define bBandgapMbiasPowerUp 0x10000 -#define bAD11SHGain 0xc0000 -#define bAD11InputRange 0x700000 -#define bAD11OPCurrent 0x3800000 -#define bIPathLoopback 0x4000000 -#define bQPathLoopback 0x8000000 -#define bAFELoopback 0x10000000 -#define bDA10Swing 0x7e0 -#define bDA10Reverse 0x800 -#define bDAClkSource 0x1000 -#define bAD7InputRange 0x6000 -#define bAD7Gain 0x38000 -#define bAD7OutputCMMode 0x40000 -#define bAD7InputCMMode 0x380000 -#define bAD7Current 0xc00000 -#define bRegulatorAdjust 0x7000000 -#define bAD11PowerUpAtTx 0x1 -#define bDA10PSAtTx 0x10 -#define bAD11PowerUpAtRx 0x100 -#define bDA10PSAtRx 0x1000 - -#define bCCKRxAGCFormat 0x200 - -#define bPSDFFTSamplepPoint 0xc000 -#define bPSDAverageNum 0x3000 -#define bIQPathControl 0xc00 -#define bPSDFreq 0x3ff -#define bPSDAntennaPath 0x30 -#define bPSDIQSwitch 0x40 -#define bPSDRxTrigger 0x400000 -#define bPSDTxTrigger 0x80000000 -#define bPSDSineToneScale 0x7f000000 -#define bPSDReport 0xffff - -//page-9 -#define bOFDMTxSC 0x30000000 -#define bCCKTxOn 0x1 -#define bOFDMTxOn 0x2 -#define bDebugPage 0xfff //reset debug page and also HWord, LWord -#define bDebugItem 0xff //reset debug page and LWord -#define bAntL 0x10 -#define bAntNonHT 0x100 -#define bAntHT1 0x1000 -#define bAntHT2 0x10000 -#define bAntHT1S1 0x100000 -#define bAntNonHTS1 0x1000000 - -//page-a -#define bCCKBBMode 0x3 -#define bCCKTxPowerSaving 0x80 -#define bCCKRxPowerSaving 0x40 -#define bCCKSideBand 0x10 -#define bCCKScramble 0x8 -#define bCCKAntDiversity 0x8000 +#define bAD11SHGain 0xc0000 +#define bAD11InputRange 0x700000 +#define bAD11OPCurrent 0x3800000 +#define bIPathLoopback 0x4000000 +#define bQPathLoopback 0x8000000 +#define bAFELoopback 0x10000000 +#define bDA10Swing 0x7e0 +#define bDA10Reverse 0x800 +#define bDAClkSource 0x1000 +#define bAD7InputRange 0x6000 +#define bAD7Gain 0x38000 +#define bAD7OutputCMMode 0x40000 +#define bAD7InputCMMode 0x380000 +#define bAD7Current 0xc00000 +#define bRegulatorAdjust 0x7000000 +#define bAD11PowerUpAtTx 0x1 +#define bDA10PSAtTx 0x10 +#define bAD11PowerUpAtRx 0x100 +#define bDA10PSAtRx 0x1000 + +#define bCCKRxAGCFormat 0x200 + +#define bPSDFFTSamplepPoint 0xc000 +#define bPSDAverageNum 0x3000 +#define bIQPathControl 0xc00 +#define bPSDFreq 0x3ff +#define bPSDAntennaPath 0x30 +#define bPSDIQSwitch 0x40 +#define bPSDRxTrigger 0x400000 +#define bPSDTxTrigger 0x80000000 +#define bPSDSineToneScale 0x7f000000 +#define bPSDReport 0xffff + +/* Page 8 */ +#define bOFDMTxSC 0x30000000 +#define bCCKTxOn 0x1 +#define bOFDMTxOn 0x2 +/* Reset debug page and also HWord, LWord */ +#define bDebugPage 0xfff +/* Reset debug page and LWord */ +#define bDebugItem 0xff +#define bAntL 0x10 +#define bAntNonHT 0x100 +#define bAntHT1 0x1000 +#define bAntHT2 0x10000 +#define bAntHT1S1 0x100000 +#define bAntNonHTS1 0x1000000 + +/* Page a */ +#define bCCKBBMode 0x3 +#define bCCKTxPowerSaving 0x80 +#define bCCKRxPowerSaving 0x40 +#define bCCKSideBand 0x10 +#define bCCKScramble 0x8 +#define bCCKAntDiversity 0x8000 #define bCCKCarrierRecovery 0x4000 -#define bCCKTxRate 0x3000 -#define bCCKDCCancel 0x0800 -#define bCCKISICancel 0x0400 -#define bCCKMatchFilter 0x0200 -#define bCCKEqualizer 0x0100 -#define bCCKPreambleDetect 0x800000 -#define bCCKFastFalseCCA 0x400000 -#define bCCKChEstStart 0x300000 -#define bCCKCCACount 0x080000 -#define bCCKcs_lim 0x070000 -#define bCCKBistMode 0x80000000 -#define bCCKCCAMask 0x40000000 +#define bCCKTxRate 0x3000 +#define bCCKDCCancel 0x0800 +#define bCCKISICancel 0x0400 +#define bCCKMatchFilter 0x0200 +#define bCCKEqualizer 0x0100 +#define bCCKPreambleDetect 0x800000 +#define bCCKFastFalseCCA 0x400000 +#define bCCKChEstStart 0x300000 +#define bCCKCCACount 0x080000 +#define bCCKcs_lim 0x070000 +#define bCCKBistMode 0x80000000 +#define bCCKCCAMask 0x40000000 #define bCCKTxDACPhase 0x4 -#define bCCKRxADCPhase 0x20000000 //r_rx_clk +/* r_rx_clk */ +#define bCCKRxADCPhase 0x20000000 #define bCCKr_cp_mode0 0x0100 -#define bCCKTxDCOffset 0xf0 -#define bCCKRxDCOffset 0xf -#define bCCKCCAMode 0xc000 -#define bCCKFalseCS_lim 0x3f00 -#define bCCKCS_ratio 0xc00000 -#define bCCKCorgBit_sel 0x300000 -#define bCCKPD_lim 0x0f0000 -#define bCCKNewCCA 0x80000000 -#define bCCKRxHPofIG 0x8000 -#define bCCKRxIG 0x7f00 -#define bCCKLNAPolarity 0x800000 -#define bCCKRx1stGain 0x7f0000 -#define bCCKRFExtend 0x20000000 //CCK Rx Iinital gain polarity -#define bCCKRxAGCSatLevel 0x1f000000 -#define bCCKRxAGCSatCount 0xe0 -#define bCCKRxRFSettle 0x1f //AGCsamp_dly -#define bCCKFixedRxAGC 0x8000 -//#define bCCKRxAGCFormat 0x4000 //remove to HSSI register 0x824 -#define bCCKAntennaPolarity 0x2000 -#define bCCKTxFilterType 0x0c00 +#define bCCKTxDCOffset 0xf0 +#define bCCKRxDCOffset 0xf +#define bCCKCCAMode 0xc000 +#define bCCKFalseCS_lim 0x3f00 +#define bCCKCS_ratio 0xc00000 +#define bCCKCorgBit_sel 0x300000 +#define bCCKPD_lim 0x0f0000 +#define bCCKNewCCA 0x80000000 +#define bCCKRxHPofIG 0x8000 +#define bCCKRxIG 0x7f00 +#define bCCKLNAPolarity 0x800000 +#define bCCKRx1stGain 0x7f0000 +/* CCK Rx Initial gain polarity */ +#define bCCKRFExtend 0x20000000 +#define bCCKRxAGCSatLevel 0x1f000000 +#define bCCKRxAGCSatCount 0xe0 +/* AGCSAmp_dly */ +#define bCCKRxRFSettle 0x1f +#define bCCKFixedRxAGC 0x8000 +/*#define bCCKRxAGCFormat 0x4000 remove to HSSI register 0x824 */ +#define bCCKAntennaPolarity 0x2000 +#define bCCKTxFilterType 0x0c00 #define bCCKRxAGCReportType 0x0300 -#define bCCKRxDAGCEn 0x80000000 -#define bCCKRxDAGCPeriod 0x20000000 +#define bCCKRxDAGCEn 0x80000000 +#define bCCKRxDAGCPeriod 0x20000000 #define bCCKRxDAGCSatLevel 0x1f000000 -#define bCCKTimingRecovery 0x800000 -#define bCCKTxC0 0x3f0000 -#define bCCKTxC1 0x3f000000 -#define bCCKTxC2 0x3f -#define bCCKTxC3 0x3f00 -#define bCCKTxC4 0x3f0000 -#define bCCKTxC5 0x3f000000 -#define bCCKTxC6 0x3f -#define bCCKTxC7 0x3f00 -#define bCCKDebugPort 0xff0000 -#define bCCKDACDebug 0x0f000000 -#define bCCKFalseAlarmEnable 0x8000 -#define bCCKFalseAlarmRead 0x4000 -#define bCCKTRSSI 0x7f -#define bCCKRxAGCReport 0xfe -#define bCCKRxReport_AntSel 0x80000000 -#define bCCKRxReport_MFOff 0x40000000 +#define bCCKTimingRecovery 0x800000 +#define bCCKTxC0 0x3f0000 +#define bCCKTxC1 0x3f000000 +#define bCCKTxC2 0x3f +#define bCCKTxC3 0x3f00 +#define bCCKTxC4 0x3f0000 +#define bCCKTxC5 0x3f000000 +#define bCCKTxC6 0x3f +#define bCCKTxC7 0x3f00 +#define bCCKDebugPort 0xff0000 +#define bCCKDACDebug 0x0f000000 +#define bCCKFalseAlarmEnable 0x8000 +#define bCCKFalseAlarmRead 0x4000 +#define bCCKTRSSI 0x7f +#define bCCKRxAGCReport 0xfe +#define bCCKRxReport_AntSel 0x80000000 +#define bCCKRxReport_MFOff 0x40000000 #define bCCKRxRxReport_SQLoss 0x20000000 -#define bCCKRxReport_Pktloss 0x10000000 +#define bCCKRxReport_Pktloss 0x10000000 #define bCCKRxReport_Lockedbit 0x08000000 #define bCCKRxReport_RateError 0x04000000 -#define bCCKRxReport_RxRate 0x03000000 +#define bCCKRxReport_RxRate 0x03000000 #define bCCKRxFACounterLower 0xff #define bCCKRxFACounterUpper 0xff000000 -#define bCCKRxHPAGCStart 0xe000 -#define bCCKRxHPAGCFinal 0x1c00 +#define bCCKRxHPAGCStart 0xe000 +#define bCCKRxHPAGCFinal 0x1c00 #define bCCKRxFalseAlarmEnable 0x8000 -#define bCCKFACounterFreeze 0x4000 - -#define bCCKTxPathSel 0x10000000 -#define bCCKDefaultRxPath 0xc000000 -#define bCCKOptionRxPath 0x3000000 - -//page c -#define bNumOfSTF 0x3 -#define bShift_L 0xc0 -#define bGI_TH 0xc -#define bRxPathA 0x1 -#define bRxPathB 0x2 -#define bRxPathC 0x4 -#define bRxPathD 0x8 -#define bTxPathA 0x1 -#define bTxPathB 0x2 -#define bTxPathC 0x4 -#define bTxPathD 0x8 -#define bTRSSIFreq 0x200 -#define bADCBackoff 0x3000 -#define bDFIRBackoff 0xc000 -#define bTRSSILatchPhase 0x10000 -#define bRxIDCOffset 0xff -#define bRxQDCOffset 0xff00 -#define bRxDFIRMode 0x1800000 -#define bRxDCNFType 0xe000000 -#define bRXIQImb_A 0x3ff -#define bRXIQImb_B 0xfc00 -#define bRXIQImb_C 0x3f0000 -#define bRXIQImb_D 0xffc00000 -#define bDC_dc_Notch 0x60000 -#define bRxNBINotch 0x1f000000 -#define bPD_TH 0xf -#define bPD_TH_Opt2 0xc000 -#define bPWED_TH 0x700 -#define bIfMF_Win_L 0x800 -#define bPD_Option 0x1000 -#define bMF_Win_L 0xe000 -#define bBW_Search_L 0x30000 -#define bwin_enh_L 0xc0000 -#define bBW_TH 0x700000 -#define bED_TH2 0x3800000 -#define bBW_option 0x4000000 -#define bRatio_TH 0x18000000 -#define bWindow_L 0xe0000000 -#define bSBD_Option 0x1 -#define bFrame_TH 0x1c -#define bFS_Option 0x60 -#define bDC_Slope_check 0x80 -#define bFGuard_Counter_DC_L 0xe00 -#define bFrame_Weight_Short 0x7000 -#define bSub_Tune 0xe00000 -#define bFrame_DC_Length 0xe000000 -#define bSBD_start_offset 0x30000000 -#define bFrame_TH_2 0x7 -#define bFrame_GI2_TH 0x38 -#define bGI2_Sync_en 0x40 -#define bSarch_Short_Early 0x300 -#define bSarch_Short_Late 0xc00 -#define bSarch_GI2_Late 0x70000 -#define bCFOAntSum 0x1 -#define bCFOAcc 0x2 -#define bCFOStartOffset 0xc -#define bCFOLookBack 0x70 -#define bCFOSumWeight 0x80 -#define bDAGCEnable 0x10000 -#define bTXIQImb_A 0x3ff -#define bTXIQImb_B 0xfc00 -#define bTXIQImb_C 0x3f0000 -#define bTXIQImb_D 0xffc00000 -#define bTxIDCOffset 0xff -#define bTxQDCOffset 0xff00 -#define bTxDFIRMode 0x10000 -#define bTxPesudoNoiseOn 0x4000000 -#define bTxPesudoNoise_A 0xff -#define bTxPesudoNoise_B 0xff00 -#define bTxPesudoNoise_C 0xff0000 -#define bTxPesudoNoise_D 0xff000000 -#define bCCADropOption 0x20000 -#define bCCADropThres 0xfff00000 -#define bEDCCA_H 0xf -#define bEDCCA_L 0xf0 -#define bLambda_ED 0x300 -#define bRxInitialGain 0x7f -#define bRxAntDivEn 0x80 -#define bRxAGCAddressForLNA 0x7f00 -#define bRxHighPowerFlow 0x8000 -#define bRxAGCFreezeThres 0xc0000 -#define bRxFreezeStep_AGC1 0x300000 -#define bRxFreezeStep_AGC2 0xc00000 -#define bRxFreezeStep_AGC3 0x3000000 -#define bRxFreezeStep_AGC0 0xc000000 -#define bRxRssi_Cmp_En 0x10000000 -#define bRxQuickAGCEn 0x20000000 -#define bRxAGCFreezeThresMode 0x40000000 -#define bRxOverFlowCheckType 0x80000000 -#define bRxAGCShift 0x7f -#define bTRSW_Tri_Only 0x80 -#define bPowerThres 0x300 -#define bRxAGCEn 0x1 -#define bRxAGCTogetherEn 0x2 -#define bRxAGCMin 0x4 -#define bRxHP_Ini 0x7 -#define bRxHP_TRLNA 0x70 -#define bRxHP_RSSI 0x700 -#define bRxHP_BBP1 0x7000 -#define bRxHP_BBP2 0x70000 -#define bRxHP_BBP3 0x700000 -#define bRSSI_H 0x7f0000 //the threshold for high power -#define bRSSI_Gen 0x7f000000 //the threshold for ant diversity -#define bRxSettle_TRSW 0x7 -#define bRxSettle_LNA 0x38 -#define bRxSettle_RSSI 0x1c0 -#define bRxSettle_BBP 0xe00 -#define bRxSettle_RxHP 0x7000 -#define bRxSettle_AntSW_RSSI 0x38000 -#define bRxSettle_AntSW 0xc0000 -#define bRxProcessTime_DAGC 0x300000 -#define bRxSettle_HSSI 0x400000 -#define bRxProcessTime_BBPPW 0x800000 -#define bRxAntennaPowerShift 0x3000000 -#define bRSSITableSelect 0xc000000 -#define bRxHP_Final 0x7000000 -#define bRxHTSettle_BBP 0x7 -#define bRxHTSettle_HSSI 0x8 -#define bRxHTSettle_RxHP 0x70 -#define bRxHTSettle_BBPPW 0x80 -#define bRxHTSettle_Idle 0x300 -#define bRxHTSettle_Reserved 0x1c00 -#define bRxHTRxHPEn 0x8000 -#define bRxHTAGCFreezeThres 0x30000 -#define bRxHTAGCTogetherEn 0x40000 -#define bRxHTAGCMin 0x80000 -#define bRxHTAGCEn 0x100000 -#define bRxHTDAGCEn 0x200000 -#define bRxHTRxHP_BBP 0x1c00000 -#define bRxHTRxHP_Final 0xe0000000 -#define bRxPWRatioTH 0x3 -#define bRxPWRatioEn 0x4 -#define bRxMFHold 0x3800 -#define bRxPD_Delay_TH1 0x38 -#define bRxPD_Delay_TH2 0x1c0 -#define bRxPD_DC_COUNT_MAX 0x600 -//#define bRxMF_Hold 0x3800 +#define bCCKFACounterFreeze 0x4000 + +#define bCCKTxPathSel 0x10000000 +#define bCCKDefaultRxPath 0xc000000 +#define bCCKOptionRxPath 0x3000000 + +/* Page c */ +#define bNumOfSTF 0x3 +#define bShift_L 0xc0 +#define bGI_TH 0xc +#define bRxPathA 0x1 +#define bRxPathB 0x2 +#define bRxPathC 0x4 +#define bRxPathD 0x8 +#define bTxPathA 0x1 +#define bTxPathB 0x2 +#define bTxPathC 0x4 +#define bTxPathD 0x8 +#define bTRSSIFreq 0x200 +#define bADCBackoff 0x3000 +#define bDFIRBackoff 0xc000 +#define bTRSSILatchPhase 0x10000 +#define bRxIDCOffset 0xff +#define bRxQDCOffset 0xff00 +#define bRxDFIRMode 0x1800000 +#define bRxDCNFType 0xe000000 +#define bRXIQImb_A 0x3ff +#define bRXIQImb_B 0xfc00 +#define bRXIQImb_C 0x3f0000 +#define bRXIQImb_D 0xffc00000 +#define bDC_dc_Notch 0x60000 +#define bRxNBINotch 0x1f000000 +#define bPD_TH 0xf +#define bPD_TH_Opt2 0xc000 +#define bPWED_TH 0x700 +#define bIfMF_Win_L 0x800 +#define bPD_Option 0x1000 +#define bMF_Win_L 0xe000 +#define bBW_Search_L 0x30000 +#define bwin_enh_L 0xc0000 +#define bBW_TH 0x700000 +#define bED_TH2 0x3800000 +#define bBW_option 0x4000000 +#define bRatio_TH 0x18000000 +#define bWindow_L 0xe0000000 +#define bSBD_Option 0x1 +#define bFrame_TH 0x1c +#define bFS_Option 0x60 +#define bDC_Slope_check 0x80 +#define bFGuard_Counter_DC_L 0xe00 +#define bFrame_Weight_Short 0x7000 +#define bSub_Tune 0xe00000 +#define bFrame_DC_Length 0xe000000 +#define bSBD_start_offset 0x30000000 +#define bFrame_TH_2 0x7 +#define bFrame_GI2_TH 0x38 +#define bGI2_Sync_en 0x40 +#define bSarch_Short_Early 0x300 +#define bSarch_Short_Late 0xc00 +#define bSarch_GI2_Late 0x70000 +#define bCFOAntSum 0x1 +#define bCFOAcc 0x2 +#define bCFOStartOffset 0xc +#define bCFOLookBack 0x70 +#define bCFOSumWeight 0x80 +#define bDAGCEnable 0x10000 +#define bTXIQImb_A 0x3ff +#define bTXIQImb_B 0xfc00 +#define bTXIQImb_C 0x3f0000 +#define bTXIQImb_D 0xffc00000 +#define bTxIDCOffset 0xff +#define bTxQDCOffset 0xff00 +#define bTxDFIRMode 0x10000 +#define bTxPesudoNoiseOn 0x4000000 +#define bTxPesudoNoise_A 0xff +#define bTxPesudoNoise_B 0xff00 +#define bTxPesudoNoise_C 0xff0000 +#define bTxPesudoNoise_D 0xff000000 +#define bCCADropOption 0x20000 +#define bCCADropThres 0xfff00000 +#define bEDCCA_H 0xf +#define bEDCCA_L 0xf0 +#define bLambda_ED 0x300 +#define bRxInitialGain 0x7f +#define bRxAntDivEn 0x80 +#define bRxAGCAddressForLNA 0x7f00 +#define bRxHighPowerFlow 0x8000 +#define bRxAGCFreezeThres 0xc0000 +#define bRxFreezeStep_AGC1 0x300000 +#define bRxFreezeStep_AGC2 0xc00000 +#define bRxFreezeStep_AGC3 0x3000000 +#define bRxFreezeStep_AGC0 0xc000000 +#define bRxRssi_Cmp_En 0x10000000 +#define bRxQuickAGCEn 0x20000000 +#define bRxAGCFreezeThresMode 0x40000000 +#define bRxOverFlowCheckType 0x80000000 +#define bRxAGCShift 0x7f +#define bTRSW_Tri_Only 0x80 +#define bPowerThres 0x300 +#define bRxAGCEn 0x1 +#define bRxAGCTogetherEn 0x2 +#define bRxAGCMin 0x4 +#define bRxHP_Ini 0x7 +#define bRxHP_TRLNA 0x70 +#define bRxHP_RSSI 0x700 +#define bRxHP_BBP1 0x7000 +#define bRxHP_BBP2 0x70000 +#define bRxHP_BBP3 0x700000 +/* The threshold for high power */ +#define bRSSI_H 0x7f0000 +/* The threshold for ant diversity */ +#define bRSSI_Gen 0x7f000000 +#define bRxSettle_TRSW 0x7 +#define bRxSettle_LNA 0x38 +#define bRxSettle_RSSI 0x1c0 +#define bRxSettle_BBP 0xe00 +#define bRxSettle_RxHP 0x7000 +#define bRxSettle_AntSW_RSSI 0x38000 +#define bRxSettle_AntSW 0xc0000 +#define bRxProcessTime_DAGC 0x300000 +#define bRxSettle_HSSI 0x400000 +#define bRxProcessTime_BBPPW 0x800000 +#define bRxAntennaPowerShift 0x3000000 +#define bRSSITableSelect 0xc000000 +#define bRxHP_Final 0x7000000 +#define bRxHTSettle_BBP 0x7 +#define bRxHTSettle_HSSI 0x8 +#define bRxHTSettle_RxHP 0x70 +#define bRxHTSettle_BBPPW 0x80 +#define bRxHTSettle_Idle 0x300 +#define bRxHTSettle_Reserved 0x1c00 +#define bRxHTRxHPEn 0x8000 +#define bRxHTAGCFreezeThres 0x30000 +#define bRxHTAGCTogetherEn 0x40000 +#define bRxHTAGCMin 0x80000 +#define bRxHTAGCEn 0x100000 +#define bRxHTDAGCEn 0x200000 +#define bRxHTRxHP_BBP 0x1c00000 +#define bRxHTRxHP_Final 0xe0000000 +#define bRxPWRatioTH 0x3 +#define bRxPWRatioEn 0x4 +#define bRxMFHold 0x3800 +#define bRxPD_Delay_TH1 0x38 +#define bRxPD_Delay_TH2 0x1c0 +#define bRxPD_DC_COUNT_MAX 0x600 +/*#define bRxMF_Hold 0x3800*/ #define bRxPD_Delay_TH 0x8000 #define bRxProcess_Delay 0xf0000 #define bRxSearchrange_GI2_Early 0x700000 @@ -659,7 +692,7 @@ #define bExtLNAGain 0x7c00 -//page d +/* Page d */ #define bSTBCEn 0x4 #define bAntennaMapping 0x10 #define bNss 0x20 @@ -669,12 +702,12 @@ #define bOFDMContinueTx 0x10000000 #define bOFDMSingleCarrier 0x20000000 #define bOFDMSingleTone 0x40000000 -//#define bRxPath1 0x01 -//#define bRxPath2 0x02 -//#define bRxPath3 0x04 -//#define bRxPath4 0x08 -//#define bTxPath1 0x10 -//#define bTxPath2 0x20 +/*#define bRxPath1 0x01 +#define bRxPath2 0x02 +#define bRxPath3 0x04 +#define bRxPath4 0x08 +#define bTxPath1 0x10 +#define bTxPath2 0x20*/ #define bHTDetect 0x100 #define bCFOEn 0x10000 #define bCFOValue 0xfff00000 @@ -687,8 +720,10 @@ #define bCounter_MCSNoSupport 0xffff #define bCounter_FastSync 0xffff #define bShortCFO 0xfff -#define bShortCFOTLength 12 //total -#define bShortCFOFLength 11 //fraction +/* total */ +#define bShortCFOTLength 12 +/* fraction */ +#define bShortCFOFLength 11 #define bLongCFO 0x7ff #define bLongCFOTLength 11 #define bLongCFOFLength 11 @@ -765,18 +800,18 @@ #define bUChCfg 0x7000000 #define bUpdEqz 0x8000000 -//page e -#define bTxAGCRate18_06 0x7f7f7f7f -#define bTxAGCRate54_24 0x7f7f7f7f +/* Page e */ +#define bTxAGCRate18_06 0x7f7f7f7f +#define bTxAGCRate54_24 0x7f7f7f7f #define bTxAGCRateMCS32 0x7f -#define bTxAGCRateCCK 0x7f00 +#define bTxAGCRateCCK 0x7f00 #define bTxAGCRateMCS3_MCS0 0x7f7f7f7f #define bTxAGCRateMCS7_MCS4 0x7f7f7f7f #define bTxAGCRateMCS11_MCS8 0x7f7f7f7f #define bTxAGCRateMCS15_MCS12 0x7f7f7f7f -//Rx Pseduo noise +/* Rx Pseduo noise */ #define bRxPesudoNoiseOn 0x20000000 #define bRxPesudoNoise_A 0xff #define bRxPesudoNoise_B 0xff00 @@ -787,8 +822,7 @@ #define bPesudoNoiseState_C 0xffff #define bPesudoNoiseState_D 0xffff0000 -//RF -//Zebra1 +/* RF Zebra 1 */ #define bZebra1_HSSIEnable 0x8 #define bZebra1_TRxControl 0xc00 #define bZebra1_TRxGainSetting 0x07f @@ -799,7 +833,7 @@ #define bZebra1_TxLPFBW 0x400 #define bZebra1_RxLPFBW 0x600 -//Zebra4 +/* Zebra4 */ #define bRTL8256RegModeCtrl1 0x100 #define bRTL8256RegModeCtrl0 0x40 #define bRTL8256_TxLPFBW 0x18 @@ -810,7 +844,7 @@ #define bRTL8258_RxLPFBW 0xc00 #define bRTL8258_RSSILPFBW 0xc0 -//byte endable for sb_write +/* byte endable for sb_write */ #define bByte0 0x1 #define bByte1 0x2 #define bByte2 0x4 @@ -819,7 +853,7 @@ #define bWord1 0xc #define bDWord 0xf -//for PutRegsetting & GetRegSetting BitMask +/* for PutRegsetting & GetRegSetting BitMask */ #define bMaskByte0 0xff #define bMaskByte1 0xff00 #define bMaskByte2 0xff0000 @@ -828,7 +862,7 @@ #define bMaskLWord 0x0000ffff #define bMaskDWord 0xffffffff -//for PutRFRegsetting & GetRFRegSetting BitMask +/* for PutRFRegsetting & GetRFRegSetting BitMask */ #define bMask12Bits 0xfff #define bEnable 0x1 @@ -837,14 +871,16 @@ #define LeftAntenna 0x0 #define RightAntenna 0x1 -#define tCheckTxStatus 500 //500ms -#define tUpdateRxCounter 100 //100ms +/* 500 ms */ +#define tCheckTxStatus 500 +/* 100 ms */ +#define tUpdateRxCounter 100 #define rateCCK 0 #define rateOFDM 1 #define rateHT 2 -//define Register-End +/* define Register-End */ #define bPMAC_End 0x1ff #define bFPGAPHY0_End 0x8ff #define bFPGAPHY1_End 0x9ff @@ -852,12 +888,12 @@ #define bOFDMPHY0_End 0xcff #define bOFDMPHY1_End 0xdff -//define max debug item in each debug page -//#define bMaxItem_FPGA_PHY0 0x9 -//#define bMaxItem_FPGA_PHY1 0x3 -//#define bMaxItem_PHY_11B 0x16 -//#define bMaxItem_OFDM_PHY0 0x29 -//#define bMaxItem_OFDM_PHY1 0x0 +/*#define max debug item in each debug page +#define bMaxItem_FPGA_PHY0 0x9 +#define bMaxItem_FPGA_PHY1 0x3 +#define bMaxItem_PHY_11B 0x16 +#define bMaxItem_OFDM_PHY0 0x29 +#define bMaxItem_OFDM_PHY1 0x0 */ #define bPMACControl 0x0 #define bWMACControl 0x1 @@ -868,11 +904,12 @@ #define PathC 0x2 #define PathD 0x3 -#define rRTL8256RxMixerPole 0xb -#define bZebraRxMixerPole 0x6 -#define rRTL8256TxBBOPBias 0x9 -#define bRTL8256TxBBOPBias 0x400 -#define rRTL8256TxBBBW 19 -#define bRTL8256TxBBBW 0x18 +#define rRTL8256RxMixerPole 0xb +#define bZebraRxMixerPole 0x6 +#define rRTL8256TxBBOPBias 0x9 +#define bRTL8256TxBBOPBias 0x400 +#define rRTL8256TxBBBW 19 +#define bRTL8256TxBBBW 0x18 + -#endif //__INC_HAL8190PCIPHYREG_H +#endif /* __INC_HAL8190PCIPHYREG_H */ diff --git a/drivers/staging/rtl8192su/Kconfig b/drivers/staging/rtl8192su/Kconfig index 123fa6d..b72a962 100644 --- a/drivers/staging/rtl8192su/Kconfig +++ b/drivers/staging/rtl8192su/Kconfig @@ -1,6 +1,7 @@ config RTL8192SU tristate "RealTek RTL8192SU Wireless LAN NIC driver" depends on PCI && WLAN && USB - depends on WIRELESS_EXT + select WIRELESS_EXT + select WEXT_PRIV default N ---help--- diff --git a/drivers/staging/rtl8192su/TODO b/drivers/staging/rtl8192su/TODO index f11eec7..3c8da15 100644 --- a/drivers/staging/rtl8192su/TODO +++ b/drivers/staging/rtl8192su/TODO @@ -4,7 +4,6 @@ TODO: - cleanup ieee80211.h - move rtl8192su's specific code out from ieee80211.h - abstract rtl819su's specific code - - use list_for_each_safe() in ieee80211_crypto_deinit - switch to use shared "librtl" instead of private ieee80211 stack - switch to use LIB80211 - switch to use MAC80211 diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211.h b/drivers/staging/rtl8192su/ieee80211/ieee80211.h index 2b8c855..32b261d 100644 --- a/drivers/staging/rtl8192su/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8192su/ieee80211/ieee80211.h @@ -30,6 +30,7 @@ #include <linux/jiffies.h> #include <linux/timer.h> #include <linux/sched.h> +#include <linux/semaphore.h> #include <linux/delay.h> #include <linux/wireless.h> @@ -195,10 +196,6 @@ extern u32 ieee80211_debug_level; #define IEEE80211_DEBUG_DATA(level, data, datalen) do {} while(0) #endif /* CONFIG_IEEE80211_DEBUG */ -#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x" -#define MAC_ARG(x) ((u8 *)(x))[0], ((u8 *)(x))[1], ((u8 *)(x))[2], \ - ((u8 *)(x))[3], ((u8 *)(x))[4], ((u8 *)(x))[5] - /* * To use the debug system; * diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt.c index 521e7b9..c4640e6 100644 --- a/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt.c +++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt.c @@ -226,19 +226,20 @@ out: void __exit ieee80211_crypto_deinit(void) { struct list_head *ptr, *n; + struct ieee80211_crypto_alg *alg = NULL; if (hcrypt == NULL) return; - for (ptr = hcrypt->algs.next, n = ptr->next; ptr != &hcrypt->algs; - ptr = n, n = ptr->next) { - struct ieee80211_crypto_alg *alg = - (struct ieee80211_crypto_alg *) ptr; - list_del(ptr); - printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm " - "'%s' (deinit)\n", alg->ops->name); - kfree(alg); + list_for_each_safe(ptr, n, &hcrypt->algs) { + alg = list_entry(ptr, struct ieee80211_crypto_alg, list); + if (alg) { + list_del(ptr); + printk(KERN_DEBUG + "ieee80211_crypt: unregistered algorithm '%s' (deinit)\n", + alg->ops->name); + kfree(alg); + } } - kfree(hcrypt); } diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_ccmp.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_ccmp.c index 7bc956e..8a93f7d 100644 --- a/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_ccmp.c +++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_ccmp.c @@ -288,7 +288,7 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) if (!(keyidx & (1 << 5))) { if (net_ratelimit()) { printk(KERN_DEBUG "CCMP: received packet without ExtIV" - " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2)); + " flag from %pM\n", hdr->addr2); } key->dot11RSNAStatsCCMPFormatErrors++; return -2; @@ -301,9 +301,9 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) } if (!key->key_set) { if (net_ratelimit()) { - printk(KERN_DEBUG "CCMP: received packet from " MAC_FMT + printk(KERN_DEBUG "CCMP: received packet from %pM" " with keyid=%d that does not have a configured" - " key\n", MAC_ARG(hdr->addr2), keyidx); + " key\n", hdr->addr2, keyidx); } return -3; } @@ -318,11 +318,9 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) { if (net_ratelimit()) { - printk(KERN_DEBUG "CCMP: replay detected: STA=" MAC_FMT - " previous PN %02x%02x%02x%02x%02x%02x " - "received PN %02x%02x%02x%02x%02x%02x\n", - MAC_ARG(hdr->addr2), MAC_ARG(key->rx_pn), - MAC_ARG(pn)); + printk(KERN_DEBUG "CCMP: replay detected: STA=%pM" + " previous PN %pm received PN %pm\n", + hdr->addr2, key->rx_pn, pn); } key->dot11RSNAStatsCCMPReplays++; return -4; @@ -359,7 +357,7 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) if (memcmp(mic, a, CCMP_MIC_LEN) != 0) { if (net_ratelimit()) { printk(KERN_DEBUG "CCMP: decrypt failed: STA=" - MAC_FMT "\n", MAC_ARG(hdr->addr2)); + "%pM\n", hdr->addr2); } key->dot11RSNAStatsCCMPDecryptErrors++; return -5; @@ -435,11 +433,10 @@ static char * ieee80211_ccmp_print_stats(char *p, void *priv) { struct ieee80211_ccmp_data *ccmp = priv; p += sprintf(p, "key[%d] alg=CCMP key_set=%d " - "tx_pn=%02x%02x%02x%02x%02x%02x " - "rx_pn=%02x%02x%02x%02x%02x%02x " + "tx_pn=%pm rx_pn=%pm " "format_errors=%d replays=%d decrypt_errors=%d\n", ccmp->key_idx, ccmp->key_set, - MAC_ARG(ccmp->tx_pn), MAC_ARG(ccmp->rx_pn), + ccmp->tx_pn, ccmp->rx_pn, ccmp->dot11RSNAStatsCCMPFormatErrors, ccmp->dot11RSNAStatsCCMPReplays, ccmp->dot11RSNAStatsCCMPDecryptErrors); diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_tkip.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_tkip.c index 9b9438f..7e48748 100644 --- a/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_tkip.c +++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_tkip.c @@ -410,7 +410,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) if (!(keyidx & (1 << 5))) { if (net_ratelimit()) { printk(KERN_DEBUG "TKIP: received packet without ExtIV" - " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2)); + " flag from %pM\n", hdr->addr2); } return -2; } @@ -422,9 +422,9 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) } if (!tkey->key_set) { if (net_ratelimit()) { - printk(KERN_DEBUG "TKIP: received packet from " MAC_FMT + printk(KERN_DEBUG "TKIP: received packet from %pM" " with keyid=%d that does not have a configured" - " key\n", MAC_ARG(hdr->addr2), keyidx); + " key\n", hdr->addr2, keyidx); } return -3; } @@ -437,9 +437,9 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) if (iv32 < tkey->rx_iv32 || (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) { if (net_ratelimit()) { - printk(KERN_DEBUG "TKIP: replay detected: STA=" MAC_FMT + printk(KERN_DEBUG "TKIP: replay detected: STA=%pM" " previous TSC %08x%04x received TSC " - "%08x%04x\n", MAC_ARG(hdr->addr2), + "%08x%04x\n", hdr->addr2, tkey->rx_iv32, tkey->rx_iv16, iv32, iv16); } tkey->dot11RSNAStatsTKIPReplays++; @@ -460,8 +460,8 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) { if (net_ratelimit()) { printk(KERN_DEBUG ": TKIP: failed to decrypt " - "received packet from " MAC_FMT "\n", - MAC_ARG(hdr->addr2)); + "received packet from %pM\n", + hdr->addr2); } return -7; } @@ -480,7 +480,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) } if (net_ratelimit()) { printk(KERN_DEBUG "TKIP: ICV error detected: STA=" - MAC_FMT "\n", MAC_ARG(hdr->addr2)); + "%pM\n", hdr->addr2); } tkey->dot11RSNAStatsTKIPICVErrors++; return -5; @@ -635,8 +635,8 @@ static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx, struct ieee80211_hdr_4addr *hdr; hdr = (struct ieee80211_hdr_4addr *) skb->data; printk(KERN_DEBUG "%s: Michael MIC verification failed for " - "MSDU from " MAC_FMT " keyidx=%d\n", - skb->dev ? skb->dev->name : "N/A", MAC_ARG(hdr->addr2), + "MSDU from %pM keyidx=%d\n", + skb->dev ? skb->dev->name : "N/A", hdr->addr2, keyidx); if (skb->dev) ieee80211_michael_mic_failure(skb->dev, hdr, keyidx); diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c index e8c67d5..c024fa6 100644 --- a/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c +++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c @@ -262,7 +262,7 @@ static int store_debug_level(struct file *file, const char *buffer, unsigned long count, void *data) { char buf[] = "0x00000000"; - unsigned long len = min(sizeof(buf) - 1, count); + unsigned long len = min_t(unsigned long, sizeof(buf) - 1, count); char *p = (char *)buf; unsigned long val; diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_rx.c index 095b8c6..cc80faf 100644 --- a/drivers/staging/rtl8192su/ieee80211/ieee80211_rx.c +++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_rx.c @@ -314,8 +314,8 @@ ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb, strcmp(crypt->ops->name, "TKIP") == 0) { if (net_ratelimit()) { printk(KERN_DEBUG "%s: TKIP countermeasures: dropped " - "received packet from " MAC_FMT "\n", - ieee->dev->name, MAC_ARG(hdr->addr2)); + "received packet from %pM\n", + ieee->dev->name, hdr->addr2); } return -1; } @@ -326,8 +326,8 @@ ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb, atomic_dec(&crypt->refcnt); if (res < 0) { IEEE80211_DEBUG_DROP( - "decryption failed (SA=" MAC_FMT - ") res=%d\n", MAC_ARG(hdr->addr2), res); + "decryption failed (SA=%pM" + ") res=%d\n", hdr->addr2, res); if (res == -2) IEEE80211_DEBUG_DROP("Decryption failed ICV " "mismatch (key %d)\n", @@ -364,8 +364,8 @@ ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device* ieee, struct sk_buff *s atomic_dec(&crypt->refcnt); if (res < 0) { printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed" - " (SA=" MAC_FMT " keyidx=%d)\n", - ieee->dev->name, MAC_ARG(hdr->addr2), keyidx); + " (SA=%pM keyidx=%d)\n", + ieee->dev->name, hdr->addr2, keyidx); return -1; } @@ -939,8 +939,8 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, * frames silently instead of filling system log with * these reports. */ IEEE80211_DEBUG_DROP("Decryption failed (not set)" - " (SA=" MAC_FMT ")\n", - MAC_ARG(hdr->addr2)); + " (SA=%pM)\n", + hdr->addr2); ieee->ieee_stats.rx_discards_undecryptable++; goto rx_dropped; } @@ -1143,8 +1143,8 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, } else { IEEE80211_DEBUG_DROP( "encryption configured, but RX " - "frame not encrypted (SA=" MAC_FMT ")\n", - MAC_ARG(hdr->addr2)); + "frame not encrypted (SA=%pM)\n", + hdr->addr2); goto rx_dropped; } } @@ -1163,9 +1163,9 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, !ieee80211_is_eapol_frame(ieee, skb, hdrlen)) { IEEE80211_DEBUG_DROP( "dropped unencrypted RX data " - "frame from " MAC_FMT + "frame from %pM" " (drop_unencrypted=1)\n", - MAC_ARG(hdr->addr2)); + hdr->addr2); goto rx_dropped; } /* @@ -2159,11 +2159,11 @@ static inline int ieee80211_network_init( } if (network->mode == 0) { - IEEE80211_DEBUG_SCAN("Filtered out '%s (" MAC_FMT ")' " + IEEE80211_DEBUG_SCAN("Filtered out '%s (%pM)' " "network.\n", escape_essid(network->ssid, network->ssid_len), - MAC_ARG(network->bssid)); + network->bssid); return 1; } @@ -2345,9 +2345,9 @@ static inline void ieee80211_process_probe_response( memset(&network, 0, sizeof(struct ieee80211_network)); IEEE80211_DEBUG_SCAN( - "'%s' (" MAC_FMT "): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n", + "'%s' (%pM): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n", escape_essid(info_element->data, info_element->len), - MAC_ARG(beacon->header.addr3), + beacon->header.addr3, (beacon->capability & (1<<0xf)) ? '1' : '0', (beacon->capability & (1<<0xe)) ? '1' : '0', (beacon->capability & (1<<0xd)) ? '1' : '0', @@ -2366,10 +2366,10 @@ static inline void ieee80211_process_probe_response( (beacon->capability & (1<<0x0)) ? '1' : '0'); if (ieee80211_network_init(ieee, beacon, &network, stats)) { - IEEE80211_DEBUG_SCAN("Dropped '%s' (" MAC_FMT ") via %s.\n", + IEEE80211_DEBUG_SCAN("Dropped '%s' (%pM) via %s.\n", escape_essid(info_element->data, info_element->len), - MAC_ARG(beacon->header.addr3), + beacon->header.addr3, WLAN_FC_GET_STYPE(beacon->header.frame_control) == IEEE80211_STYPE_PROBE_RESP ? "PROBE RESPONSE" : "BEACON"); @@ -2478,11 +2478,11 @@ static inline void ieee80211_process_probe_response( /* If there are no more slots, expire the oldest */ list_del(&oldest->list); target = oldest; - IEEE80211_DEBUG_SCAN("Expired '%s' (" MAC_FMT ") from " + IEEE80211_DEBUG_SCAN("Expired '%s' (%pM) from " "network list.\n", escape_essid(target->ssid, target->ssid_len), - MAC_ARG(target->bssid)); + target->bssid); } else { /* Otherwise just pull from the free list */ target = list_entry(ieee->network_free_list.next, @@ -2492,10 +2492,10 @@ static inline void ieee80211_process_probe_response( #ifdef CONFIG_IEEE80211_DEBUG - IEEE80211_DEBUG_SCAN("Adding '%s' (" MAC_FMT ") via %s.\n", + IEEE80211_DEBUG_SCAN("Adding '%s' (%pM) via %s.\n", escape_essid(network.ssid, network.ssid_len), - MAC_ARG(network.bssid), + network.bssid, WLAN_FC_GET_STYPE(beacon->header.frame_control) == IEEE80211_STYPE_PROBE_RESP ? "PROBE RESPONSE" : "BEACON"); @@ -2505,10 +2505,10 @@ static inline void ieee80211_process_probe_response( if(ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) ieee80211_softmac_new_net(ieee,&network); } else { - IEEE80211_DEBUG_SCAN("Updating '%s' (" MAC_FMT ") via %s.\n", + IEEE80211_DEBUG_SCAN("Updating '%s' (%pM) via %s.\n", escape_essid(target->ssid, target->ssid_len), - MAC_ARG(target->bssid), + target->bssid, WLAN_FC_GET_STYPE(beacon->header.frame_control) == IEEE80211_STYPE_PROBE_RESP ? "PROBE RESPONSE" : "BEACON"); diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c index 0ba2a01..9d8cb0e 100644 --- a/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c @@ -1709,7 +1709,7 @@ ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb) ieee80211_resp_to_assoc_rq(ieee, dest); } - printk(KERN_INFO"New client associated: "MAC_FMT"\n", MAC_ARG(dest)); + printk(KERN_INFO"New client associated: %pM\n", dest); //FIXME } @@ -2145,8 +2145,8 @@ void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device * ieee80211_sta_wakeup(ieee,0); /* update the tx status */ -// ieee->stats.tx_bytes += txb->payload_size; -// ieee->stats.tx_packets++; + ieee->stats.tx_bytes += txb->payload_size; + ieee->stats.tx_packets++; tcb_desc = (cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE); if(tcb_desc->bMulticast) { ieee->stats.multicast++; diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_tx.c index 4d54e1e..484c3ab 100644 --- a/drivers/staging/rtl8192su/ieee80211/ieee80211_tx.c +++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_tx.c @@ -199,8 +199,8 @@ int ieee80211_encrypt_fragment( header = (struct rtl_ieee80211_hdr *)frag->data; if (net_ratelimit()) { printk(KERN_DEBUG "%s: TKIP countermeasures: dropped " - "TX packet to " MAC_FMT "\n", - ieee->dev->name, MAC_ARG(header->addr1)); + "TX packet to %pM\n", + ieee->dev->name, header->addr1); } return -1; } diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c index 85c7e96..122f800 100644 --- a/drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c +++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c @@ -261,10 +261,10 @@ int ieee80211_wx_get_scan(struct ieee80211_device *ieee, else IEEE80211_DEBUG_SCAN( "Not showing network '%s (" - MAC_FMT ")' due to age (%lums).\n", + "%pM)' due to age (%lums).\n", escape_essid(network->ssid, network->ssid_len), - MAC_ARG(network->bssid), + network->bssid, (jiffies - network->last_scanned) / (HZ / 100)); } @@ -731,7 +731,7 @@ int ieee80211_wx_set_auth(struct ieee80211_device *ieee, #if 1 case IW_AUTH_WPA_ENABLED: ieee->wpa_enabled = (data->value)?1:0; - //printk("enalbe wpa:%d\n", ieee->wpa_enabled); + //printk("enable wpa:%d\n", ieee->wpa_enabled); break; #endif diff --git a/drivers/staging/rtl8192su/ieee80211/rtl819x_BAProc.c b/drivers/staging/rtl8192su/ieee80211/rtl819x_BAProc.c index c696245..8c37dd1 100644 --- a/drivers/staging/rtl8192su/ieee80211/rtl819x_BAProc.c +++ b/drivers/staging/rtl8192su/ieee80211/rtl819x_BAProc.c @@ -113,7 +113,7 @@ static struct sk_buff* ieee80211_ADDBA(struct ieee80211_device* ieee, u8* Dst, P u16 tmp = 0; u16 len = ieee->tx_headroom + 9; //category(1) + action field(1) + Dialog Token(1) + BA Parameter Set(2) + BA Timeout Value(2) + BA Start SeqCtrl(2)(or StatusCode(2)) - IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), frame(%d) sentd to:"MAC_FMT", ieee->dev:%p\n", __FUNCTION__, type, MAC_ARG(Dst), ieee->dev); + IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), frame(%d) sentd to:%pM, ieee->dev:%p\n", __FUNCTION__, type, Dst, ieee->dev); if (pBA == NULL||ieee == NULL) { IEEE80211_DEBUG(IEEE80211_DL_ERR, "pBA(%p) is NULL or ieee(%p) is NULL\n", pBA, ieee); @@ -200,7 +200,7 @@ static struct sk_buff* ieee80211_DELBA( u16 len = 6 + ieee->tx_headroom; if (net_ratelimit()) - IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), ReasonCode(%d) sentd to:"MAC_FMT"\n", __FUNCTION__, ReasonCode, MAC_ARG(dst)); + IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), ReasonCode(%d) sentd to:%pM\n", __FUNCTION__, ReasonCode, dst); memset(&DelbaParamSet, 0, 2); @@ -339,7 +339,10 @@ int ieee80211_rx_ADDBAReq( struct ieee80211_device* ieee, struct sk_buff *skb) if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 9) { - IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BAREQ(%d / %ld)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 9)); + IEEE80211_DEBUG(IEEE80211_DL_ERR, + " Invalid skb len in BAREQ(%d / %zd)\n", + skb->len, + sizeof(struct ieee80211_hdr_3addr) + 9); return -1; } @@ -354,7 +357,7 @@ int ieee80211_rx_ADDBAReq( struct ieee80211_device* ieee, struct sk_buff *skb) pBaTimeoutVal = (u16*)(tag + 5); pBaStartSeqCtrl = (PSEQUENCE_CONTROL)(req + 7); - printk("====================>rx ADDBAREQ from :"MAC_FMT"\n", MAC_ARG(dst)); + printk("====================>rx ADDBAREQ from :%pM\n", dst); //some other capability is not ready now. if( (ieee->current_network.qos_data.active == 0) || (ieee->pHTInfo->bCurrentHTSupport == false) || @@ -440,7 +443,10 @@ int ieee80211_rx_ADDBARsp( struct ieee80211_device* ieee, struct sk_buff *skb) if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 9) { - IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BARSP(%d / %ld)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 9)); + IEEE80211_DEBUG(IEEE80211_DL_ERR, + " Invalid skb len in BARSP(%d / %zd)\n", + skb->len, + sizeof(struct ieee80211_hdr_3addr) + 9); return -1; } rsp = ( struct ieee80211_hdr_3addr*)skb->data; @@ -570,7 +576,10 @@ int ieee80211_rx_DELBA(struct ieee80211_device* ieee,struct sk_buff *skb) if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 6) { - IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in DELBA(%d / %ld)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 6)); + IEEE80211_DEBUG(IEEE80211_DL_ERR, + " Invalid skb len in DELBA(%d / %zd)\n", + skb->len, + sizeof(struct ieee80211_hdr_3addr) + 6); return -1; } diff --git a/drivers/staging/rtl8192su/ieee80211/rtl819x_HTProc.c b/drivers/staging/rtl8192su/ieee80211/rtl819x_HTProc.c index 33c7fa7..01114c5 100644 --- a/drivers/staging/rtl8192su/ieee80211/rtl819x_HTProc.c +++ b/drivers/staging/rtl8192su/ieee80211/rtl819x_HTProc.c @@ -42,7 +42,7 @@ static u8 DLINK_ATHEROS_1[3] = {0x00, 0x1c, 0xf0}; static u8 DLINK_ATHEROS_2[3] = {0x00, 0x21, 0x91}; static u8 CISCO_BROADCOM[3] = {0x00, 0x17, 0x94}; static u8 LINKSYS_MARVELL_4400N[3] = {0x00, 0x14, 0xa4}; -// 2008/04/01 MH For Cisco G mode RX TP We need to change FW duration. Shoud we put the +// 2008/04/01 MH For Cisco G mode RX TP We need to change FW duration. Should we put the // code in other place?? //static u8 WIFI_CISCO_G_AP[3] = {0x00, 0x40, 0x96}; /******************************************************************************************************************** diff --git a/drivers/staging/rtl8192su/ieee80211/rtl819x_TSProc.c b/drivers/staging/rtl8192su/ieee80211/rtl819x_TSProc.c index ad3bf35..60cf1f8 100644 --- a/drivers/staging/rtl8192su/ieee80211/rtl819x_TSProc.c +++ b/drivers/staging/rtl8192su/ieee80211/rtl819x_TSProc.c @@ -291,7 +291,7 @@ PTS_COMMON_INFO SearchAdmitTRStream(struct ieee80211_device *ieee, u8* Addr, u8 if(search_dir[dir] ==false ) continue; list_for_each_entry(pRet, psearch_list, List){ - // IEEE80211_DEBUG(IEEE80211_DL_TS, "ADD:"MAC_FMT", TID:%d, dir:%d\n", MAC_ARG(pRet->Addr), pRet->TSpec.f.TSInfo.field.ucTSID, pRet->TSpec.f.TSInfo.field.ucDirection); + // IEEE80211_DEBUG(IEEE80211_DL_TS, "ADD:%pM, TID:%d, dir:%d\n", pRet->Addr, pRet->TSpec.f.TSInfo.field.ucTSID, pRet->TSpec.f.TSInfo.field.ucDirection); if (memcmp(pRet->Addr, Addr, 6) == 0) if (pRet->TSpec.f.TSInfo.field.ucTSID == TID) if(pRet->TSpec.f.TSInfo.field.ucDirection == dir) @@ -447,7 +447,7 @@ bool GetTs( ResetRxTsEntry(tmp); } - IEEE80211_DEBUG(IEEE80211_DL_TS, "to init current TS, UP:%d, Dir:%d, addr:"MAC_FMT"\n", UP, Dir, MAC_ARG(Addr)); + IEEE80211_DEBUG(IEEE80211_DL_TS, "to init current TS, UP:%d, Dir:%d, addr:%pM\n", UP, Dir, Addr); // Prepare TS Info releated field pTSInfo->field.ucTrafficType = 0; // Traffic type: WMM is reserved in this field pTSInfo->field.ucTSID = UP; // TSID @@ -533,7 +533,7 @@ void RemoveTsEntry( void RemovePeerTS(struct ieee80211_device* ieee, u8* Addr) { PTS_COMMON_INFO pTS, pTmpTS; - printk("===========>RemovePeerTS,"MAC_FMT"\n", MAC_ARG(Addr)); + printk("===========>RemovePeerTS,%pM\n", Addr); #if 1 list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, List) { diff --git a/drivers/staging/rtl8192su/r8192SU_HWImg.c b/drivers/staging/rtl8192su/r8192SU_HWImg.c index cbb6579..ba8e12c 100644 --- a/drivers/staging/rtl8192su/r8192SU_HWImg.c +++ b/drivers/staging/rtl8192su/r8192SU_HWImg.c @@ -2,4282 +2,6 @@ #include "r8192SU_HWImg.h" -u8 Rtl8192SUFwImgArray[ImgArrayLength] = { -0x92,0x81,0x2b,0x90,0x30,0x00,0x00,0x00,0x08,0x74,0x00,0x00,0x88,0x96,0x00,0x00, -0x30,0x00,0x00,0x00,0x00,0x95,0x00,0x00,0x00,0x00,0x2b,0x00,0x03,0x03,0x23,0x00, -0x92,0x81,0x02,0x01,0x00,0x00,0x12,0x04,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x01,0x01,0x01,0x00,0x00, -0x00,0x01,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x7f,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x1f,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x25,0xb0,0x1a,0x3c,0x80,0x03,0x5a,0x37,0x00,0x80,0x1b,0x3c,0x80,0x00,0x7b,0x37, -0x00,0x00,0x5b,0xaf,0x25,0xb0,0x1a,0x3c,0x18,0x03,0x5a,0x37,0x00,0x80,0x1b,0x3c, -0x80,0x00,0x7b,0x37,0x00,0x00,0x5b,0xaf,0x00,0x80,0x1a,0x3c,0x10,0x6d,0x5a,0x27, -0x08,0x00,0x40,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x04,0x00,0xa1,0xaf,0x08,0x00,0xa2,0xaf,0x0c,0x00,0xa3,0xaf,0x10,0x00,0xa4,0xaf, -0x14,0x00,0xa5,0xaf,0x18,0x00,0xa6,0xaf,0x1c,0x00,0xa7,0xaf,0x20,0x00,0xa8,0xaf, -0x24,0x00,0xa9,0xaf,0x28,0x00,0xaa,0xaf,0x2c,0x00,0xab,0xaf,0x30,0x00,0xac,0xaf, -0x34,0x00,0xad,0xaf,0x38,0x00,0xae,0xaf,0x3c,0x00,0xaf,0xaf,0x12,0x40,0x00,0x00, -0x10,0x48,0x00,0x00,0x00,0x70,0x0a,0x40,0x40,0x00,0xb0,0xaf,0x44,0x00,0xb1,0xaf, -0x48,0x00,0xb2,0xaf,0x4c,0x00,0xb3,0xaf,0x50,0x00,0xb4,0xaf,0x54,0x00,0xb5,0xaf, -0x58,0x00,0xb6,0xaf,0x5c,0x00,0xb7,0xaf,0x60,0x00,0xb8,0xaf,0x64,0x00,0xb9,0xaf, -0x68,0x00,0xbc,0xaf,0x6c,0x00,0xbd,0xaf,0x70,0x00,0xbe,0xaf,0x74,0x00,0xbf,0xaf, -0x78,0x00,0xa8,0xaf,0x7c,0x00,0xa9,0xaf,0x80,0x00,0xaa,0xaf,0xdf,0x1a,0x00,0x08, -0x21,0x20,0xa0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x25,0xb0,0x06,0x3c,0x00,0x80,0x02,0x3c,0xe8,0xff,0xbd,0x27,0x18,0x03,0xc3,0x34, -0x00,0x03,0x42,0x24,0x14,0x00,0xbf,0xaf,0x10,0x00,0xb0,0xaf,0x00,0x00,0x62,0xac, -0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,0x42,0xb0,0x03,0x3c, -0x03,0x00,0x63,0x34,0x00,0x00,0x62,0x90,0x02,0x80,0x0a,0x3c,0x02,0x80,0x10,0x3c, -0xff,0x00,0x42,0x30,0x00,0x46,0x02,0x00,0x10,0x00,0x42,0x30,0x13,0x00,0x40,0x10, -0x03,0x46,0x08,0x00,0xc4,0x7d,0x42,0x8d,0x68,0x15,0x05,0x26,0xd4,0x63,0xa4,0x94, -0x01,0x00,0x47,0x24,0x10,0x00,0x02,0x24,0xb0,0x03,0xc9,0x34,0x00,0x00,0x62,0xa0, -0x07,0x00,0x80,0x10,0x1c,0x03,0xc6,0x34,0xd8,0x63,0xa2,0x8c,0xd4,0x63,0xa0,0xa4, -0xd8,0x63,0xa0,0xac,0x00,0x00,0x04,0x24,0x00,0x00,0xc2,0xac,0x00,0x00,0x20,0xad, -0x01,0x00,0x82,0x24,0xc4,0x7d,0x47,0xad,0xd4,0x63,0xa2,0xa4,0x12,0x00,0x00,0x05, -0x42,0xb0,0x02,0x3c,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38, -0x00,0x60,0x81,0x40,0x68,0x15,0x04,0x26,0x0c,0x4b,0x83,0x94,0x08,0x4b,0x85,0x94, -0x14,0x00,0xbf,0x8f,0x10,0x00,0xb0,0x8f,0x80,0x00,0x63,0x30,0x41,0xb0,0x02,0x3c, -0x25,0x18,0x65,0x00,0x08,0x00,0x42,0x34,0x18,0x00,0xbd,0x27,0x00,0x00,0x43,0xa4, -0x08,0x00,0xe0,0x03,0x08,0x4b,0x83,0xa4,0x80,0xff,0x03,0x24,0x03,0x00,0x42,0x34, -0x00,0x00,0x43,0xa0,0xc8,0x0e,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x60,0x01,0x40, -0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x68,0x15,0x04,0x26, -0x0c,0x4b,0x83,0x94,0x08,0x4b,0x85,0x94,0x14,0x00,0xbf,0x8f,0x10,0x00,0xb0,0x8f, -0x80,0x00,0x63,0x30,0x41,0xb0,0x02,0x3c,0x25,0x18,0x65,0x00,0x08,0x00,0x42,0x34, -0x18,0x00,0xbd,0x27,0x00,0x00,0x43,0xa4,0x08,0x00,0xe0,0x03,0x08,0x4b,0x83,0xa4, -0xff,0x00,0x84,0x30,0x0b,0x00,0x82,0x2c,0xff,0xff,0xe7,0x30,0x10,0x00,0xa8,0x93, -0x19,0x00,0x40,0x10,0x21,0x18,0x00,0x00,0x02,0x80,0x03,0x3c,0x80,0x10,0x04,0x00, -0xc0,0x91,0x63,0x24,0x21,0x10,0x43,0x00,0x00,0x00,0x44,0x8c,0x00,0x00,0x00,0x00, -0x08,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x43,0xb0,0x02,0x3c,0x78,0x00,0x44,0x34, -0x07,0x00,0xe2,0x30,0x00,0x00,0x85,0xac,0x04,0x00,0x86,0xac,0x04,0x00,0x40,0x18, -0x00,0x00,0x00,0x00,0xf8,0xff,0xe2,0x30,0x08,0x00,0x42,0x24,0xff,0xff,0x47,0x30, -0x21,0x10,0xe8,0x00,0x00,0x80,0x03,0x3c,0x08,0x00,0x82,0xac,0x25,0x10,0x43,0x00, -0x08,0x00,0x82,0xac,0x01,0x00,0x03,0x24,0x08,0x00,0xe0,0x03,0x21,0x10,0x60,0x00, -0x43,0xb0,0x02,0x3c,0x20,0x01,0x00,0x08,0x6c,0x00,0x44,0x34,0x43,0xb0,0x02,0x3c, -0x20,0x01,0x00,0x08,0x60,0x00,0x44,0x34,0x43,0xb0,0x02,0x3c,0x20,0x01,0x00,0x08, -0x54,0x00,0x44,0x34,0x43,0xb0,0x02,0x3c,0x20,0x01,0x00,0x08,0x48,0x00,0x44,0x34, -0x43,0xb0,0x02,0x3c,0x20,0x01,0x00,0x08,0x3c,0x00,0x44,0x34,0x43,0xb0,0x02,0x3c, -0x20,0x01,0x00,0x08,0x30,0x00,0x44,0x34,0x43,0xb0,0x02,0x3c,0x20,0x01,0x00,0x08, -0x24,0x00,0x44,0x34,0x43,0xb0,0x02,0x3c,0x20,0x01,0x00,0x08,0x18,0x00,0x44,0x34, -0x43,0xb0,0x02,0x3c,0x20,0x01,0x00,0x08,0x0c,0x00,0x44,0x34,0x20,0x01,0x00,0x08, -0x43,0xb0,0x04,0x3c,0x01,0x00,0x02,0x24,0x25,0xb0,0x03,0x3c,0x04,0x20,0x82,0x00, -0x18,0x03,0x67,0x34,0x00,0x80,0x02,0x3c,0x43,0xb0,0x03,0x3c,0x34,0x05,0x46,0x24, -0x88,0x00,0x65,0x34,0x21,0x10,0x00,0x00,0x01,0x00,0x42,0x24,0xff,0xff,0x42,0x30, -0x05,0x00,0x43,0x2c,0xfd,0xff,0x60,0x14,0x01,0x00,0x42,0x24,0x00,0x00,0xe6,0xac, -0x00,0x00,0xa2,0x94,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0x30,0x24,0x10,0x44,0x00, -0xf4,0xff,0x40,0x1c,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00, -0x25,0xb0,0x08,0x3c,0x00,0x80,0x02,0x3c,0xc8,0xff,0xbd,0x27,0x18,0x03,0x03,0x35, -0x90,0x05,0x42,0x24,0x00,0x00,0x62,0xac,0x30,0x00,0xb6,0xaf,0x28,0x00,0xb4,0xaf, -0x24,0x00,0xb3,0xaf,0x1c,0x00,0xb1,0xaf,0x34,0x00,0xbf,0xaf,0x2c,0x00,0xb5,0xaf, -0x20,0x00,0xb2,0xaf,0x18,0x00,0xb0,0xaf,0x0c,0x00,0xf2,0x84,0x08,0x00,0xf5,0x8c, -0xff,0x00,0xc6,0x30,0x00,0x01,0x02,0x24,0x23,0x10,0x46,0x00,0xff,0xff,0x51,0x30, -0xd0,0x03,0x08,0x35,0xff,0x00,0x96,0x30,0x00,0x00,0x12,0xad,0x21,0xa0,0xa0,0x00, -0x21,0x30,0xc5,0x00,0x00,0x00,0x15,0xad,0x21,0x20,0xc0,0x02,0x21,0x28,0xa0,0x02, -0x21,0x38,0x20,0x02,0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,0x23,0x18,0x51,0x02, -0xff,0xff,0x82,0x32,0x00,0x94,0x03,0x00,0x03,0x94,0x12,0x00,0xa6,0x01,0x00,0x08, -0x02,0x9a,0x02,0x00,0x28,0xb0,0x03,0x3c,0xc0,0x10,0x13,0x00,0x21,0x10,0x43,0x00, -0x00,0x00,0x44,0x90,0x25,0xb0,0x10,0x3c,0x20,0x10,0x02,0x3c,0xff,0x00,0x93,0x30, -0x00,0x22,0x13,0x00,0xff,0xff,0x43,0x32,0x01,0x01,0x45,0x2a,0x21,0xa0,0x82,0x00, -0x21,0xa8,0xb1,0x02,0xd0,0x03,0x02,0x36,0x00,0x01,0x11,0x24,0x0b,0x88,0x65,0x00, -0x21,0x20,0xc0,0x02,0x00,0x00,0x53,0xac,0x4d,0x01,0x00,0x0c,0xb0,0x03,0x10,0x36, -0x21,0x30,0x80,0x02,0x21,0x20,0xc0,0x02,0x21,0x28,0xa0,0x02,0x21,0x38,0x20,0x02, -0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,0x23,0x18,0x51,0x02,0x00,0x94,0x03,0x00, -0x03,0x94,0x12,0x00,0x00,0x00,0x12,0xae,0xe2,0xff,0x40,0x1e,0x00,0x00,0x00,0x00, -0x34,0x00,0xbf,0x8f,0x30,0x00,0xb6,0x8f,0x2c,0x00,0xb5,0x8f,0x28,0x00,0xb4,0x8f, -0x24,0x00,0xb3,0x8f,0x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f, -0x08,0x00,0xe0,0x03,0x38,0x00,0xbd,0x27,0xc8,0xff,0xbd,0x27,0x02,0x80,0x02,0x3c, -0x25,0xb0,0x04,0x3c,0x20,0x00,0xb2,0xaf,0x68,0x15,0x52,0x24,0x00,0x80,0x02,0x3c, -0x18,0x03,0x83,0x34,0xc8,0x06,0x42,0x24,0x28,0x00,0xb4,0xaf,0x24,0x00,0xb3,0xaf, -0x30,0x00,0xbf,0xaf,0x2c,0x00,0xb5,0xaf,0x1c,0x00,0xb1,0xaf,0x18,0x00,0xb0,0xaf, -0x00,0x00,0x62,0xac,0xb0,0x03,0x93,0x34,0x21,0xa0,0x40,0x02,0x54,0x64,0x42,0x8e, -0xc0,0x64,0x50,0x8e,0x21,0x20,0x00,0x00,0x00,0x00,0x62,0xae,0x58,0x64,0x42,0xae, -0x00,0x00,0x70,0xae,0x4d,0x01,0x00,0x0c,0x00,0x00,0x00,0x00,0xc0,0x64,0x44,0x8e, -0xc4,0x64,0x43,0x8e,0x20,0x00,0x84,0x24,0x3f,0x00,0x62,0x24,0x2b,0x10,0x44,0x00, -0x0a,0x18,0x82,0x00,0xc0,0x64,0x43,0xae,0xc0,0x64,0x85,0x8e,0x00,0x00,0x00,0x00, -0x00,0x00,0x65,0xae,0x02,0x80,0x02,0x3c,0xff,0xff,0x10,0x32,0x25,0x80,0x02,0x02, -0x00,0x00,0x70,0xae,0x0c,0x00,0x02,0x92,0xff,0x00,0x15,0x24,0x21,0x20,0x00,0x00, -0x00,0x00,0x62,0xae,0x0c,0x00,0x11,0x92,0x20,0x10,0x02,0x3c,0x20,0x00,0x07,0x24, -0x00,0x1a,0x11,0x00,0x21,0x18,0x62,0x00,0x05,0x00,0x35,0x12,0x21,0x30,0x60,0x00, -0x08,0x64,0x91,0xa2,0x54,0x64,0x83,0xae,0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf, -0x04,0x00,0x04,0x8e,0x08,0x00,0x03,0x8e,0xff,0xe0,0x02,0x3c,0xff,0xff,0x42,0x34, -0x1f,0x00,0x84,0x30,0x24,0x18,0x62,0x00,0x00,0x26,0x04,0x00,0xff,0xdf,0x02,0x3c, -0x25,0x18,0x64,0x00,0xff,0xff,0x42,0x34,0x24,0x18,0x62,0x00,0x00,0x40,0x04,0x3c, -0x25,0x18,0x64,0x00,0xc0,0xff,0x02,0x24,0x24,0x18,0x62,0x00,0x08,0x00,0x03,0xae, -0xc9,0x64,0x84,0x92,0x2a,0xb0,0x02,0x3c,0x01,0x00,0x03,0x24,0x01,0x00,0x84,0x24, -0x01,0x00,0x42,0x34,0x00,0x00,0x43,0xa0,0xc4,0xff,0x35,0x16,0xc9,0x64,0x84,0xa2, -0xfc,0x4a,0x82,0x8e,0x41,0xb0,0x03,0x3c,0x30,0x00,0xbf,0x8f,0x00,0x38,0x42,0x34, -0x00,0x00,0x62,0xac,0x2c,0x00,0xb5,0x8f,0xfc,0x4a,0x82,0xae,0x24,0x00,0xb3,0x8f, -0x28,0x00,0xb4,0x8f,0x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f, -0x08,0x00,0xe0,0x03,0x38,0x00,0xbd,0x27,0x25,0xb0,0x04,0x3c,0x00,0x80,0x02,0x3c, -0xc8,0xff,0xbd,0x27,0x18,0x03,0x83,0x34,0x38,0x08,0x42,0x24,0x34,0x00,0xbf,0xaf, -0x30,0x00,0xb6,0xaf,0x2c,0x00,0xb5,0xaf,0x28,0x00,0xb4,0xaf,0x24,0x00,0xb3,0xaf, -0x20,0x00,0xb2,0xaf,0x1c,0x00,0xb1,0xaf,0x18,0x00,0xb0,0xaf,0x00,0x00,0x62,0xac, -0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,0x02,0x80,0x16,0x3c, -0x68,0x15,0xd2,0x26,0xb0,0x03,0x93,0x34,0x2d,0x02,0x00,0x08,0x21,0xa8,0x40,0x02, -0x2a,0xb0,0x02,0x3c,0x08,0x00,0x04,0xae,0x09,0x00,0x42,0x34,0x01,0x00,0x03,0x24, -0x02,0x00,0x04,0x24,0x00,0x00,0x43,0xa0,0x00,0x00,0x44,0xa0,0x42,0x00,0x34,0x12, -0x00,0x00,0x00,0x00,0x6c,0x64,0x42,0x8e,0xd8,0x64,0x50,0x8e,0x01,0x00,0x04,0x24, -0x00,0x00,0x62,0xae,0x70,0x64,0x42,0xae,0x00,0x00,0x70,0xae,0x4d,0x01,0x00,0x0c, -0x00,0x00,0x00,0x00,0xd8,0x64,0x44,0x8e,0xdc,0x64,0x43,0x8e,0x20,0x00,0x84,0x24, -0x3f,0x00,0x62,0x24,0x2b,0x10,0x44,0x00,0x0a,0x18,0x82,0x00,0xd8,0x64,0x43,0xae, -0xd8,0x64,0xa5,0x8e,0x00,0x00,0x00,0x00,0x00,0x00,0x65,0xae,0x02,0x80,0x02,0x3c, -0xff,0xff,0x10,0x32,0x25,0x80,0x02,0x02,0x00,0x00,0x70,0xae,0x0c,0x00,0x02,0x92, -0xff,0x00,0x14,0x24,0x01,0x00,0x04,0x24,0x00,0x00,0x62,0xae,0x0c,0x00,0x11,0x92, -0x20,0x10,0x02,0x3c,0x20,0x00,0x07,0x24,0x00,0x1a,0x11,0x00,0x21,0x18,0x62,0x00, -0x05,0x00,0x34,0x12,0x21,0x30,0x60,0x00,0x6c,0x64,0xa3,0xae,0x10,0x64,0xb1,0xa2, -0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,0x04,0x00,0x04,0x8e,0x08,0x00,0x03,0x8e, -0xff,0xe0,0x02,0x3c,0xff,0xff,0x42,0x34,0x1f,0x00,0x84,0x30,0x24,0x18,0x62,0x00, -0x00,0x26,0x04,0x00,0xff,0xdf,0x02,0x3c,0x25,0x18,0x64,0x00,0xff,0xff,0x42,0x34, -0x24,0x18,0x62,0x00,0x00,0x40,0x04,0x3c,0x25,0x18,0x64,0x00,0xc0,0xff,0x05,0x24, -0x82,0x11,0x03,0x00,0x24,0x20,0x65,0x00,0x01,0x00,0x42,0x30,0xc0,0xff,0x40,0x10, -0x04,0x00,0x84,0x34,0x2a,0xb0,0x02,0x3c,0x08,0x00,0x03,0xae,0x09,0x00,0x42,0x34, -0x01,0x00,0x03,0x24,0x02,0x00,0x04,0x24,0x00,0x00,0x43,0xa0,0x00,0x00,0x44,0xa0, -0xc0,0xff,0x34,0x16,0x00,0x00,0x00,0x00,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34, -0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x68,0x15,0xc2,0x26,0xfc,0x4a,0x43,0x8c, -0x34,0x00,0xbf,0x8f,0x30,0x00,0xb6,0x8f,0x2c,0x00,0xb5,0x8f,0x28,0x00,0xb4,0x8f, -0x24,0x00,0xb3,0x8f,0x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f, -0x00,0x38,0x63,0x34,0x41,0xb0,0x04,0x3c,0x38,0x00,0xbd,0x27,0x00,0x00,0x83,0xac, -0x08,0x00,0xe0,0x03,0xfc,0x4a,0x43,0xac,0x25,0xb0,0x04,0x3c,0x00,0x80,0x02,0x3c, -0xc0,0xff,0xbd,0x27,0x18,0x03,0x83,0x34,0x08,0x0a,0x42,0x24,0x38,0x00,0xbf,0xaf, -0x34,0x00,0xb7,0xaf,0x30,0x00,0xb6,0xaf,0x2c,0x00,0xb5,0xaf,0x28,0x00,0xb4,0xaf, -0x24,0x00,0xb3,0xaf,0x20,0x00,0xb2,0xaf,0x1c,0x00,0xb1,0xaf,0x18,0x00,0xb0,0xaf, -0x00,0x00,0x62,0xac,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40, -0x02,0x80,0x17,0x3c,0x68,0x15,0xf2,0x26,0xb0,0x03,0x93,0x34,0x02,0x80,0x14,0x3c, -0xab,0x02,0x00,0x08,0x21,0xb0,0x40,0x02,0x2a,0xb0,0x03,0x3c,0x08,0x00,0x04,0xae, -0x05,0x00,0x63,0x34,0x01,0x00,0x02,0x24,0x02,0x00,0x04,0x24,0x00,0x00,0x62,0xa0, -0x00,0x00,0x64,0xa0,0xca,0x7d,0x82,0x96,0x00,0x00,0x00,0x00,0x01,0x00,0x42,0x24, -0xca,0x7d,0x82,0xa6,0xca,0x7d,0x83,0x96,0x25,0xb0,0x02,0x3c,0x66,0x03,0x42,0x34, -0x00,0x00,0x43,0xa4,0x4a,0x00,0x35,0x12,0x00,0x00,0x00,0x00,0x60,0x64,0x42,0x8e, -0xcc,0x64,0x50,0x8e,0x01,0x00,0x04,0x24,0x00,0x00,0x62,0xae,0x64,0x64,0x42,0xae, -0x00,0x00,0x70,0xae,0x4d,0x01,0x00,0x0c,0x00,0x00,0x00,0x00,0xcc,0x64,0x44,0x8e, -0xd0,0x64,0x43,0x8e,0x20,0x00,0x84,0x24,0x3f,0x00,0x62,0x24,0x2b,0x10,0x44,0x00, -0x0a,0x18,0x82,0x00,0xcc,0x64,0x43,0xae,0xcc,0x64,0xc5,0x8e,0x00,0x00,0x00,0x00, -0x00,0x00,0x65,0xae,0x02,0x80,0x02,0x3c,0xff,0xff,0x10,0x32,0x25,0x80,0x02,0x02, -0x00,0x00,0x70,0xae,0x0c,0x00,0x02,0x92,0xff,0x00,0x15,0x24,0x01,0x00,0x04,0x24, -0x00,0x00,0x62,0xae,0x0c,0x00,0x11,0x92,0x20,0x10,0x02,0x3c,0x20,0x00,0x07,0x24, -0x00,0x1a,0x11,0x00,0x21,0x18,0x62,0x00,0x05,0x00,0x35,0x12,0x21,0x30,0x60,0x00, -0x60,0x64,0xc3,0xae,0x0c,0x64,0xd1,0xa2,0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf, -0x04,0x00,0x04,0x8e,0x08,0x00,0x03,0x8e,0xff,0xe0,0x02,0x3c,0xff,0xff,0x42,0x34, -0x1f,0x00,0x84,0x30,0x24,0x18,0x62,0x00,0x00,0x26,0x04,0x00,0xff,0xdf,0x02,0x3c, -0x25,0x18,0x64,0x00,0xff,0xff,0x42,0x34,0x24,0x18,0x62,0x00,0x00,0x40,0x04,0x3c, -0x25,0x18,0x64,0x00,0xc0,0xff,0x05,0x24,0x82,0x11,0x03,0x00,0x24,0x20,0x65,0x00, -0x01,0x00,0x42,0x30,0xb8,0xff,0x40,0x10,0x04,0x00,0x84,0x34,0x08,0x00,0x03,0xae, -0x2a,0xb0,0x03,0x3c,0x05,0x00,0x63,0x34,0x01,0x00,0x02,0x24,0x02,0x00,0x04,0x24, -0x00,0x00,0x62,0xa0,0x00,0x00,0x64,0xa0,0xca,0x7d,0x82,0x96,0x00,0x00,0x00,0x00, -0x01,0x00,0x42,0x24,0xca,0x7d,0x82,0xa6,0xca,0x7d,0x83,0x96,0x25,0xb0,0x02,0x3c, -0x66,0x03,0x42,0x34,0x00,0x00,0x43,0xa4,0xb8,0xff,0x35,0x16,0x00,0x00,0x00,0x00, -0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40, -0x68,0x15,0xe2,0x26,0xfc,0x4a,0x43,0x8c,0x38,0x00,0xbf,0x8f,0x34,0x00,0xb7,0x8f, -0x30,0x00,0xb6,0x8f,0x2c,0x00,0xb5,0x8f,0x28,0x00,0xb4,0x8f,0x24,0x00,0xb3,0x8f, -0x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f,0x00,0x38,0x63,0x34, -0x41,0xb0,0x04,0x3c,0x40,0x00,0xbd,0x27,0x00,0x00,0x83,0xac,0x08,0x00,0xe0,0x03, -0xfc,0x4a,0x43,0xac,0xc0,0xff,0xbd,0x27,0x2c,0x00,0xb5,0xaf,0x38,0x00,0xbf,0xaf, -0x34,0x00,0xb7,0xaf,0x30,0x00,0xb6,0xaf,0x28,0x00,0xb4,0xaf,0x24,0x00,0xb3,0xaf, -0x20,0x00,0xb2,0xaf,0x1c,0x00,0xb1,0xaf,0x18,0x00,0xb0,0xaf,0x02,0x80,0x06,0x3c, -0x7c,0x7e,0xc5,0x90,0x00,0x80,0x03,0x3c,0x25,0xb0,0x02,0x3c,0x18,0x03,0x42,0x34, -0x24,0x0c,0x63,0x24,0x40,0x00,0xa4,0x30,0x00,0x00,0x43,0xac,0x21,0xa8,0x00,0x00, -0x03,0x00,0x80,0x10,0x7f,0x00,0xa2,0x30,0xbf,0x00,0xa2,0x30,0x01,0x00,0x15,0x24, -0x7c,0x7e,0xc2,0xa0,0x7c,0x7e,0xc2,0x90,0x25,0xb0,0x04,0x3c,0x88,0x02,0x83,0x34, -0x00,0x00,0x62,0xac,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40, -0x02,0x80,0x16,0x3c,0x68,0x15,0xd2,0x26,0xb0,0x03,0x93,0x34,0x02,0x80,0x14,0x3c, -0x43,0x03,0x00,0x08,0x21,0xb8,0x40,0x02,0x24,0x10,0xa2,0x00,0x04,0x00,0x42,0x34, -0x2a,0xb0,0x07,0x3c,0x08,0x00,0x02,0xae,0x0d,0x00,0xe2,0x34,0x04,0x00,0x43,0x24, -0x0b,0x10,0x75,0x00,0x01,0x00,0x04,0x24,0x02,0x00,0x03,0x24,0x00,0x00,0x44,0xa0, -0x00,0x00,0x43,0xa0,0xca,0x7d,0x84,0x96,0x25,0xb0,0x06,0x3c,0x66,0x03,0xc5,0x34, -0x01,0x00,0x84,0x24,0xca,0x7d,0x84,0xa6,0xca,0x7d,0x82,0x96,0xff,0x00,0x03,0x24, -0x00,0x00,0xa2,0xa4,0x5a,0x00,0x23,0x12,0x00,0x00,0x00,0x00,0x24,0x64,0x42,0x8e, -0x90,0x64,0x50,0x8e,0x03,0x00,0x04,0x24,0x00,0x00,0x62,0xae,0x28,0x64,0x42,0xae, -0x00,0x00,0x70,0xae,0x4d,0x01,0x00,0x0c,0x00,0x00,0x00,0x00,0x90,0x64,0x44,0x8e, -0x94,0x64,0x43,0x8e,0x20,0x00,0x84,0x24,0x3f,0x00,0x62,0x24,0x2b,0x10,0x44,0x00, -0x0a,0x18,0x82,0x00,0x90,0x64,0x43,0xae,0x90,0x64,0xe2,0x8e,0x00,0x00,0x00,0x00, -0x00,0x00,0x62,0xae,0x02,0x80,0x02,0x3c,0xff,0xff,0x10,0x32,0x25,0x80,0x02,0x02, -0x00,0x00,0x70,0xae,0x0c,0x00,0x02,0x92,0x00,0x00,0x00,0x00,0x00,0x00,0x62,0xae, -0x0c,0x00,0x11,0x92,0xff,0x00,0x02,0x24,0x0d,0x00,0x22,0x12,0x00,0x12,0x11,0x00, -0x20,0x10,0x03,0x3c,0x21,0x10,0x43,0x00,0x5a,0x00,0xa0,0x12,0x24,0x64,0xe2,0xae, -0xec,0x63,0xf1,0xa2,0x68,0x15,0xc2,0x26,0x24,0x64,0x46,0x8c,0x90,0x64,0x45,0x8c, -0x03,0x00,0x04,0x24,0x20,0x00,0x07,0x24,0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf, -0x04,0x00,0x04,0x8e,0x14,0x00,0x03,0x8e,0x08,0x00,0x05,0x8e,0xff,0xe0,0x02,0x3c, -0x1f,0x00,0x84,0x30,0x42,0x1a,0x03,0x00,0xff,0xff,0x42,0x34,0x00,0x26,0x04,0x00, -0x24,0x28,0xa2,0x00,0x3f,0x00,0x63,0x30,0x25,0x28,0xa4,0x00,0x0c,0x00,0x63,0x28, -0x06,0x00,0x60,0x14,0x21,0x20,0xa0,0x00,0x00,0x00,0x02,0x96,0x00,0x00,0x00,0x00, -0xfd,0x0f,0x42,0x28,0x08,0x00,0x40,0x14,0x82,0x11,0x05,0x00,0xff,0xdf,0x02,0x3c, -0xff,0xff,0x42,0x34,0x24,0x28,0x82,0x00,0x00,0x40,0x03,0x3c,0x25,0x20,0xa3,0x00, -0x21,0x28,0x80,0x00,0x82,0x11,0x05,0x00,0x01,0x00,0x42,0x30,0xa6,0xff,0x40,0x10, -0xc0,0xff,0x02,0x24,0x2a,0xb0,0x07,0x3c,0x0d,0x00,0xe2,0x34,0x04,0x00,0x43,0x24, -0x08,0x00,0x04,0xae,0x0b,0x10,0x75,0x00,0x01,0x00,0x04,0x24,0x02,0x00,0x03,0x24, -0x00,0x00,0x44,0xa0,0x00,0x00,0x43,0xa0,0xca,0x7d,0x84,0x96,0x25,0xb0,0x06,0x3c, -0x66,0x03,0xc5,0x34,0x01,0x00,0x84,0x24,0xca,0x7d,0x84,0xa6,0xca,0x7d,0x82,0x96, -0xff,0x00,0x03,0x24,0x00,0x00,0xa2,0xa4,0xa8,0xff,0x23,0x16,0x00,0x00,0x00,0x00, -0x22,0x00,0xa0,0x12,0x68,0x15,0xc2,0x26,0xec,0x63,0x43,0x90,0x41,0x00,0xe4,0x34, -0xb0,0x03,0xc5,0x34,0x00,0x00,0x83,0xa0,0x00,0x00,0xa3,0xac,0x00,0x60,0x01,0x40, -0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34, -0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x68,0x15,0xc5,0x26,0xfc,0x4a,0xa4,0x8c, -0x01,0x00,0x02,0x3c,0x38,0x00,0xbf,0x8f,0x34,0x00,0xb7,0x8f,0x30,0x00,0xb6,0x8f, -0x2c,0x00,0xb5,0x8f,0x28,0x00,0xb4,0x8f,0x24,0x00,0xb3,0x8f,0x20,0x00,0xb2,0x8f, -0x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f,0x00,0x80,0x42,0x34,0x25,0x20,0x82,0x00, -0x41,0xb0,0x03,0x3c,0x40,0x00,0xbd,0x27,0x00,0x00,0x64,0xac,0x08,0x00,0xe0,0x03, -0xfc,0x4a,0xa4,0xac,0x65,0x03,0x00,0x08,0xe8,0x63,0xf1,0xa2,0xe8,0x63,0x43,0x90, -0x40,0x00,0xe4,0x34,0xb0,0x03,0xc5,0x34,0x00,0x00,0x83,0xa0,0x00,0x00,0xa3,0xac, -0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,0x00,0x60,0x01,0x40, -0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x68,0x15,0xc5,0x26, -0xfc,0x4a,0xa4,0x8c,0x01,0x00,0x02,0x3c,0x38,0x00,0xbf,0x8f,0x34,0x00,0xb7,0x8f, -0x30,0x00,0xb6,0x8f,0x2c,0x00,0xb5,0x8f,0x28,0x00,0xb4,0x8f,0x24,0x00,0xb3,0x8f, -0x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f,0x00,0x80,0x42,0x34, -0x25,0x20,0x82,0x00,0x41,0xb0,0x03,0x3c,0x40,0x00,0xbd,0x27,0x00,0x00,0x64,0xac, -0x08,0x00,0xe0,0x03,0xfc,0x4a,0xa4,0xac,0xc0,0xff,0xbd,0x27,0x2c,0x00,0xb5,0xaf, -0x38,0x00,0xbf,0xaf,0x34,0x00,0xb7,0xaf,0x30,0x00,0xb6,0xaf,0x28,0x00,0xb4,0xaf, -0x24,0x00,0xb3,0xaf,0x20,0x00,0xb2,0xaf,0x1c,0x00,0xb1,0xaf,0x18,0x00,0xb0,0xaf, -0x02,0x80,0x06,0x3c,0x7c,0x7e,0xc5,0x90,0x00,0x80,0x03,0x3c,0x25,0xb0,0x02,0x3c, -0x18,0x03,0x42,0x34,0x78,0x0f,0x63,0x24,0x10,0x00,0xa4,0x30,0x00,0x00,0x43,0xac, -0x21,0xa8,0x00,0x00,0x03,0x00,0x80,0x10,0xdf,0x00,0xa2,0x30,0xef,0x00,0xa2,0x30, -0x01,0x00,0x15,0x24,0x7c,0x7e,0xc2,0xa0,0x7c,0x7e,0xc3,0x90,0x25,0xb0,0x02,0x3c, -0xb0,0x03,0x42,0x34,0x00,0x00,0x43,0xac,0x00,0x00,0x43,0xac,0x00,0x60,0x01,0x40, -0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,0x02,0x80,0x16,0x3c,0x68,0x15,0xd2,0x26, -0x21,0x98,0x40,0x00,0x02,0x80,0x14,0x3c,0x19,0x04,0x00,0x08,0x21,0xb8,0x40,0x02, -0x24,0x10,0xa2,0x00,0x04,0x00,0x42,0x34,0x2a,0xb0,0x07,0x3c,0x08,0x00,0x02,0xae, -0x15,0x00,0xe2,0x34,0x04,0x00,0x43,0x24,0x0b,0x10,0x75,0x00,0x01,0x00,0x04,0x24, -0x02,0x00,0x03,0x24,0x00,0x00,0x44,0xa0,0x00,0x00,0x43,0xa0,0xca,0x7d,0x84,0x96, -0x25,0xb0,0x06,0x3c,0x66,0x03,0xc5,0x34,0x01,0x00,0x84,0x24,0xca,0x7d,0x84,0xa6, -0xca,0x7d,0x82,0x96,0xff,0x00,0x03,0x24,0x00,0x00,0xa2,0xa4,0x5a,0x00,0x23,0x12, -0x00,0x00,0x00,0x00,0x30,0x64,0x42,0x8e,0x9c,0x64,0x50,0x8e,0x04,0x00,0x04,0x24, -0x00,0x00,0x62,0xae,0x34,0x64,0x42,0xae,0x00,0x00,0x70,0xae,0x4d,0x01,0x00,0x0c, -0x00,0x00,0x00,0x00,0x9c,0x64,0x44,0x8e,0xa0,0x64,0x43,0x8e,0x20,0x00,0x84,0x24, -0x3f,0x00,0x62,0x24,0x2b,0x10,0x44,0x00,0x0a,0x18,0x82,0x00,0x9c,0x64,0x43,0xae, -0x9c,0x64,0xe2,0x8e,0x00,0x00,0x00,0x00,0x00,0x00,0x62,0xae,0x02,0x80,0x02,0x3c, -0xff,0xff,0x10,0x32,0x25,0x80,0x02,0x02,0x00,0x00,0x70,0xae,0x0c,0x00,0x02,0x92, -0x00,0x00,0x00,0x00,0x00,0x00,0x62,0xae,0x0c,0x00,0x11,0x92,0xff,0x00,0x02,0x24, -0x0d,0x00,0x22,0x12,0x00,0x12,0x11,0x00,0x20,0x10,0x03,0x3c,0x21,0x10,0x43,0x00, -0x59,0x00,0xa0,0x12,0x30,0x64,0xe2,0xae,0xf4,0x63,0xf1,0xa2,0x68,0x15,0xc2,0x26, -0x30,0x64,0x46,0x8c,0x9c,0x64,0x45,0x8c,0x04,0x00,0x04,0x24,0x20,0x00,0x07,0x24, -0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,0x04,0x00,0x04,0x8e,0x14,0x00,0x03,0x8e, -0x08,0x00,0x05,0x8e,0xff,0xe0,0x02,0x3c,0x1f,0x00,0x84,0x30,0x42,0x1a,0x03,0x00, -0xff,0xff,0x42,0x34,0x00,0x26,0x04,0x00,0x24,0x28,0xa2,0x00,0x3f,0x00,0x63,0x30, -0x25,0x28,0xa4,0x00,0x0c,0x00,0x63,0x28,0x06,0x00,0x60,0x14,0x21,0x20,0xa0,0x00, -0x00,0x00,0x02,0x96,0x00,0x00,0x00,0x00,0xfd,0x0f,0x42,0x28,0x08,0x00,0x40,0x14, -0x82,0x11,0x05,0x00,0xff,0xdf,0x02,0x3c,0xff,0xff,0x42,0x34,0x24,0x28,0x82,0x00, -0x00,0x40,0x03,0x3c,0x25,0x20,0xa3,0x00,0x21,0x28,0x80,0x00,0x82,0x11,0x05,0x00, -0x01,0x00,0x42,0x30,0xa6,0xff,0x40,0x10,0xc0,0xff,0x02,0x24,0x2a,0xb0,0x07,0x3c, -0x15,0x00,0xe2,0x34,0x04,0x00,0x43,0x24,0x08,0x00,0x04,0xae,0x0b,0x10,0x75,0x00, -0x01,0x00,0x04,0x24,0x02,0x00,0x03,0x24,0x00,0x00,0x44,0xa0,0x00,0x00,0x43,0xa0, -0xca,0x7d,0x84,0x96,0x25,0xb0,0x06,0x3c,0x66,0x03,0xc5,0x34,0x01,0x00,0x84,0x24, -0xca,0x7d,0x84,0xa6,0xca,0x7d,0x82,0x96,0xff,0x00,0x03,0x24,0x00,0x00,0xa2,0xa4, -0xa8,0xff,0x23,0x16,0x00,0x00,0x00,0x00,0x21,0x00,0xa0,0x12,0x68,0x15,0xc2,0x26, -0xf4,0x63,0x43,0x90,0x43,0x00,0xe4,0x34,0xb0,0x03,0xc5,0x34,0x00,0x00,0x83,0xa0, -0x00,0x00,0xa3,0xac,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40, -0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40, -0x68,0x15,0xc5,0x26,0xfc,0x4a,0xa2,0x8c,0x38,0x00,0xbf,0x8f,0x34,0x00,0xb7,0x8f, -0x30,0x00,0xb6,0x8f,0x2c,0x00,0xb5,0x8f,0x28,0x00,0xb4,0x8f,0x24,0x00,0xb3,0x8f, -0x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f,0x06,0x00,0x03,0x3c, -0x25,0x10,0x43,0x00,0x41,0xb0,0x04,0x3c,0x40,0x00,0xbd,0x27,0x00,0x00,0x82,0xac, -0x08,0x00,0xe0,0x03,0xfc,0x4a,0xa2,0xac,0x3b,0x04,0x00,0x08,0xf0,0x63,0xf1,0xa2, -0xf0,0x63,0x43,0x90,0x42,0x00,0xe4,0x34,0xb0,0x03,0xc5,0x34,0x00,0x00,0x83,0xa0, -0x00,0x00,0xa3,0xac,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40, -0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40, -0x68,0x15,0xc5,0x26,0xfc,0x4a,0xa2,0x8c,0x38,0x00,0xbf,0x8f,0x34,0x00,0xb7,0x8f, -0x30,0x00,0xb6,0x8f,0x2c,0x00,0xb5,0x8f,0x28,0x00,0xb4,0x8f,0x24,0x00,0xb3,0x8f, -0x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f,0x06,0x00,0x03,0x3c, -0x25,0x10,0x43,0x00,0x41,0xb0,0x04,0x3c,0x40,0x00,0xbd,0x27,0x00,0x00,0x82,0xac, -0x08,0x00,0xe0,0x03,0xfc,0x4a,0xa2,0xac,0xc0,0xff,0xbd,0x27,0x2c,0x00,0xb5,0xaf, -0x38,0x00,0xbf,0xaf,0x34,0x00,0xb7,0xaf,0x30,0x00,0xb6,0xaf,0x28,0x00,0xb4,0xaf, -0x24,0x00,0xb3,0xaf,0x20,0x00,0xb2,0xaf,0x1c,0x00,0xb1,0xaf,0x18,0x00,0xb0,0xaf, -0x02,0x80,0x06,0x3c,0x7c,0x7e,0xc5,0x90,0x00,0x80,0x03,0x3c,0x25,0xb0,0x02,0x3c, -0x18,0x03,0x42,0x34,0xc8,0x12,0x63,0x24,0x01,0x00,0xa4,0x30,0x00,0x00,0x43,0xac, -0x21,0xa8,0x00,0x00,0x03,0x00,0x80,0x10,0xf7,0x00,0xa2,0x30,0xfe,0x00,0xa2,0x30, -0x01,0x00,0x15,0x24,0x7c,0x7e,0xc2,0xa0,0x7c,0x7e,0xc3,0x90,0x25,0xb0,0x02,0x3c, -0xb0,0x03,0x42,0x34,0x00,0x00,0x43,0xac,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34, -0x00,0x60,0x81,0x40,0x02,0x80,0x16,0x3c,0x68,0x15,0xd2,0x26,0x21,0x98,0x40,0x00, -0x02,0x80,0x14,0x3c,0xf8,0x04,0x00,0x08,0x21,0xb8,0x40,0x02,0x00,0x00,0x02,0x96, -0x00,0x00,0x00,0x00,0xfd,0x0f,0x42,0x28,0x54,0x00,0x40,0x10,0xff,0xdf,0x02,0x3c, -0x00,0x20,0x02,0x3c,0x25,0x28,0xa2,0x00,0x82,0x11,0x05,0x00,0x01,0x00,0x42,0x30, -0x57,0x00,0x40,0x14,0x2a,0xb0,0x07,0x3c,0xc0,0xff,0x02,0x24,0x24,0x10,0xa2,0x00, -0x04,0x00,0x42,0x34,0x2a,0xb0,0x07,0x3c,0x08,0x00,0x02,0xae,0x1d,0x00,0xe2,0x34, -0x04,0x00,0x43,0x24,0x0b,0x10,0x75,0x00,0x01,0x00,0x04,0x24,0x02,0x00,0x03,0x24, -0x00,0x00,0x44,0xa0,0x00,0x00,0x43,0xa0,0xca,0x7d,0x84,0x96,0x25,0xb0,0x06,0x3c, -0x66,0x03,0xc5,0x34,0x01,0x00,0x84,0x24,0xca,0x7d,0x84,0xa6,0xca,0x7d,0x82,0x96, -0xff,0x00,0x03,0x24,0x00,0x00,0xa2,0xa4,0x53,0x00,0x23,0x12,0x00,0x00,0x00,0x00, -0x3c,0x64,0x42,0x8e,0xa8,0x64,0x50,0x8e,0x05,0x00,0x04,0x24,0x00,0x00,0x62,0xae, -0x40,0x64,0x42,0xae,0x00,0x00,0x70,0xae,0x4d,0x01,0x00,0x0c,0x00,0x00,0x00,0x00, -0xa8,0x64,0x44,0x8e,0xac,0x64,0x43,0x8e,0x20,0x00,0x84,0x24,0x3f,0x00,0x62,0x24, -0x2b,0x10,0x44,0x00,0x0a,0x18,0x82,0x00,0xa8,0x64,0x43,0xae,0xa8,0x64,0xe2,0x8e, -0x00,0x00,0x00,0x00,0x00,0x00,0x62,0xae,0x02,0x80,0x02,0x3c,0xff,0xff,0x10,0x32, -0x25,0x80,0x02,0x02,0x00,0x00,0x70,0xae,0x0c,0x00,0x02,0x92,0x00,0x00,0x00,0x00, -0x00,0x00,0x62,0xae,0x0c,0x00,0x11,0x92,0xff,0x00,0x02,0x24,0x0d,0x00,0x22,0x12, -0x00,0x12,0x11,0x00,0x20,0x10,0x03,0x3c,0x21,0x10,0x43,0x00,0x52,0x00,0xa0,0x12, -0x3c,0x64,0xe2,0xae,0x04,0x64,0xf1,0xa2,0x68,0x15,0xc2,0x26,0x3c,0x64,0x46,0x8c, -0xa8,0x64,0x45,0x8c,0x05,0x00,0x04,0x24,0x20,0x00,0x07,0x24,0x10,0x01,0x00,0x0c, -0x10,0x00,0xa0,0xaf,0x14,0x00,0x03,0x8e,0x04,0x00,0x04,0x8e,0x08,0x00,0x05,0x8e, -0x42,0x1a,0x03,0x00,0xff,0xe0,0x02,0x3c,0x1f,0x00,0x84,0x30,0x3f,0x00,0x63,0x30, -0xff,0xff,0x42,0x34,0x24,0x28,0xa2,0x00,0x00,0x26,0x04,0x00,0x0c,0x00,0x63,0x28, -0xaa,0xff,0x60,0x10,0x25,0x28,0xa4,0x00,0xff,0xdf,0x02,0x3c,0xff,0xff,0x42,0x34, -0x24,0x10,0xa2,0x00,0x00,0x40,0x03,0x3c,0x25,0x28,0x43,0x00,0x82,0x11,0x05,0x00, -0x01,0x00,0x42,0x30,0xad,0xff,0x40,0x10,0xc0,0xff,0x02,0x24,0x2a,0xb0,0x07,0x3c, -0x1d,0x00,0xe2,0x34,0x04,0x00,0x43,0x24,0x0b,0x10,0x75,0x00,0x01,0x00,0x04,0x24, -0x02,0x00,0x03,0x24,0x08,0x00,0x05,0xae,0x00,0x00,0x44,0xa0,0x00,0x00,0x43,0xa0, -0xca,0x7d,0x84,0x96,0x25,0xb0,0x06,0x3c,0x66,0x03,0xc5,0x34,0x01,0x00,0x84,0x24, -0xca,0x7d,0x84,0xa6,0xca,0x7d,0x82,0x96,0xff,0x00,0x03,0x24,0x00,0x00,0xa2,0xa4, -0xaf,0xff,0x23,0x16,0x00,0x00,0x00,0x00,0x21,0x00,0xa0,0x12,0x68,0x15,0xc2,0x26, -0x04,0x64,0x43,0x90,0x45,0x00,0xe4,0x34,0xb0,0x03,0xc5,0x34,0x00,0x00,0x83,0xa0, -0x00,0x00,0xa3,0xac,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40, -0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40, -0x68,0x15,0xc5,0x26,0xfc,0x4a,0xa2,0x8c,0x38,0x00,0xbf,0x8f,0x34,0x00,0xb7,0x8f, -0x30,0x00,0xb6,0x8f,0x2c,0x00,0xb5,0x8f,0x28,0x00,0xb4,0x8f,0x24,0x00,0xb3,0x8f, -0x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f,0x18,0x00,0x03,0x3c, -0x25,0x10,0x43,0x00,0x41,0xb0,0x04,0x3c,0x40,0x00,0xbd,0x27,0x00,0x00,0x82,0xac, -0x08,0x00,0xe0,0x03,0xfc,0x4a,0xa2,0xac,0x1a,0x05,0x00,0x08,0xf8,0x63,0xf1,0xa2, -0xf8,0x63,0x43,0x90,0x44,0x00,0xe4,0x34,0xb0,0x03,0xc5,0x34,0x00,0x00,0x83,0xa0, -0x00,0x00,0xa3,0xac,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40, -0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40, -0x68,0x15,0xc5,0x26,0xfc,0x4a,0xa2,0x8c,0x38,0x00,0xbf,0x8f,0x34,0x00,0xb7,0x8f, -0x30,0x00,0xb6,0x8f,0x2c,0x00,0xb5,0x8f,0x28,0x00,0xb4,0x8f,0x24,0x00,0xb3,0x8f, -0x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f,0x18,0x00,0x03,0x3c, -0x25,0x10,0x43,0x00,0x41,0xb0,0x04,0x3c,0x40,0x00,0xbd,0x27,0x00,0x00,0x82,0xac, -0x08,0x00,0xe0,0x03,0xfc,0x4a,0xa2,0xac,0xc0,0xff,0xbd,0x27,0x2c,0x00,0xb5,0xaf, -0x38,0x00,0xbf,0xaf,0x34,0x00,0xb7,0xaf,0x30,0x00,0xb6,0xaf,0x28,0x00,0xb4,0xaf, -0x24,0x00,0xb3,0xaf,0x20,0x00,0xb2,0xaf,0x1c,0x00,0xb1,0xaf,0x18,0x00,0xb0,0xaf, -0x02,0x80,0x06,0x3c,0x7c,0x7e,0xc5,0x90,0x00,0x80,0x03,0x3c,0x25,0xb0,0x02,0x3c, -0x18,0x03,0x42,0x34,0x28,0x16,0x63,0x24,0x02,0x00,0xa4,0x30,0x00,0x00,0x43,0xac, -0x21,0xa8,0x00,0x00,0x03,0x00,0x80,0x10,0xfb,0x00,0xa2,0x30,0xfd,0x00,0xa2,0x30, -0x01,0x00,0x15,0x24,0x7c,0x7e,0xc2,0xa0,0x7c,0x7e,0xc3,0x90,0x25,0xb0,0x02,0x3c, -0xb0,0x03,0x42,0x34,0x00,0x00,0x43,0xac,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34, -0x00,0x60,0x81,0x40,0x02,0x80,0x16,0x3c,0x68,0x15,0xd2,0x26,0x21,0x98,0x40,0x00, -0x02,0x80,0x14,0x3c,0xd0,0x05,0x00,0x08,0x21,0xb8,0x40,0x02,0x00,0x00,0x02,0x96, -0x00,0x00,0x00,0x00,0xfd,0x0f,0x42,0x28,0x54,0x00,0x40,0x10,0xff,0xdf,0x02,0x3c, -0x00,0x20,0x02,0x3c,0x25,0x28,0xa2,0x00,0x82,0x11,0x05,0x00,0x01,0x00,0x42,0x30, -0x57,0x00,0x40,0x14,0x2a,0xb0,0x07,0x3c,0xc0,0xff,0x02,0x24,0x24,0x10,0xa2,0x00, -0x04,0x00,0x42,0x34,0x2a,0xb0,0x07,0x3c,0x08,0x00,0x02,0xae,0x25,0x00,0xe2,0x34, -0x04,0x00,0x43,0x24,0x0b,0x10,0x75,0x00,0x01,0x00,0x04,0x24,0x02,0x00,0x03,0x24, -0x00,0x00,0x44,0xa0,0x00,0x00,0x43,0xa0,0xca,0x7d,0x84,0x96,0x25,0xb0,0x06,0x3c, -0x66,0x03,0xc5,0x34,0x01,0x00,0x84,0x24,0xca,0x7d,0x84,0xa6,0xca,0x7d,0x82,0x96, -0xff,0x00,0x03,0x24,0x00,0x00,0xa2,0xa4,0x53,0x00,0x23,0x12,0x00,0x00,0x00,0x00, -0x48,0x64,0x42,0x8e,0xb4,0x64,0x50,0x8e,0x06,0x00,0x04,0x24,0x00,0x00,0x62,0xae, -0x4c,0x64,0x42,0xae,0x00,0x00,0x70,0xae,0x4d,0x01,0x00,0x0c,0x00,0x00,0x00,0x00, -0xb4,0x64,0x44,0x8e,0xb8,0x64,0x43,0x8e,0x20,0x00,0x84,0x24,0x3f,0x00,0x62,0x24, -0x2b,0x10,0x44,0x00,0x0a,0x18,0x82,0x00,0xb4,0x64,0x43,0xae,0xb4,0x64,0xe2,0x8e, -0x00,0x00,0x00,0x00,0x00,0x00,0x62,0xae,0x02,0x80,0x02,0x3c,0xff,0xff,0x10,0x32, -0x25,0x80,0x02,0x02,0x00,0x00,0x70,0xae,0x0c,0x00,0x02,0x92,0x00,0x00,0x00,0x00, -0x00,0x00,0x62,0xae,0x0c,0x00,0x11,0x92,0xff,0x00,0x02,0x24,0x0d,0x00,0x22,0x12, -0x00,0x12,0x11,0x00,0x20,0x10,0x03,0x3c,0x21,0x10,0x43,0x00,0x52,0x00,0xa0,0x12, -0x48,0x64,0xe2,0xae,0x00,0x64,0xf1,0xa2,0x68,0x15,0xc2,0x26,0x48,0x64,0x46,0x8c, -0xb4,0x64,0x45,0x8c,0x06,0x00,0x04,0x24,0x20,0x00,0x07,0x24,0x10,0x01,0x00,0x0c, -0x10,0x00,0xa0,0xaf,0x14,0x00,0x03,0x8e,0x04,0x00,0x04,0x8e,0x08,0x00,0x05,0x8e, -0x42,0x1a,0x03,0x00,0xff,0xe0,0x02,0x3c,0x1f,0x00,0x84,0x30,0x3f,0x00,0x63,0x30, -0xff,0xff,0x42,0x34,0x24,0x28,0xa2,0x00,0x00,0x26,0x04,0x00,0x0c,0x00,0x63,0x28, -0xaa,0xff,0x60,0x10,0x25,0x28,0xa4,0x00,0xff,0xdf,0x02,0x3c,0xff,0xff,0x42,0x34, -0x24,0x10,0xa2,0x00,0x00,0x40,0x03,0x3c,0x25,0x28,0x43,0x00,0x82,0x11,0x05,0x00, -0x01,0x00,0x42,0x30,0xad,0xff,0x40,0x10,0xc0,0xff,0x02,0x24,0x2a,0xb0,0x07,0x3c, -0x25,0x00,0xe2,0x34,0x04,0x00,0x43,0x24,0x0b,0x10,0x75,0x00,0x01,0x00,0x04,0x24, -0x02,0x00,0x03,0x24,0x08,0x00,0x05,0xae,0x00,0x00,0x44,0xa0,0x00,0x00,0x43,0xa0, -0xca,0x7d,0x84,0x96,0x25,0xb0,0x06,0x3c,0x66,0x03,0xc5,0x34,0x01,0x00,0x84,0x24, -0xca,0x7d,0x84,0xa6,0xca,0x7d,0x82,0x96,0xff,0x00,0x03,0x24,0x00,0x00,0xa2,0xa4, -0xaf,0xff,0x23,0x16,0x00,0x00,0x00,0x00,0x21,0x00,0xa0,0x12,0x68,0x15,0xc2,0x26, -0x00,0x64,0x43,0x90,0x47,0x00,0xe4,0x34,0xb0,0x03,0xc5,0x34,0x00,0x00,0x83,0xa0, -0x00,0x00,0xa3,0xac,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40, -0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40, -0x68,0x15,0xc5,0x26,0xfc,0x4a,0xa2,0x8c,0x38,0x00,0xbf,0x8f,0x34,0x00,0xb7,0x8f, -0x30,0x00,0xb6,0x8f,0x2c,0x00,0xb5,0x8f,0x28,0x00,0xb4,0x8f,0x24,0x00,0xb3,0x8f, -0x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f,0x60,0x00,0x03,0x3c, -0x25,0x10,0x43,0x00,0x41,0xb0,0x04,0x3c,0x40,0x00,0xbd,0x27,0x00,0x00,0x82,0xac, -0x08,0x00,0xe0,0x03,0xfc,0x4a,0xa2,0xac,0xf2,0x05,0x00,0x08,0xfc,0x63,0xf1,0xa2, -0xfc,0x63,0x43,0x90,0x46,0x00,0xe4,0x34,0xb0,0x03,0xc5,0x34,0x00,0x00,0x83,0xa0, -0x00,0x00,0xa3,0xac,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40, -0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40, -0x68,0x15,0xc5,0x26,0xfc,0x4a,0xa2,0x8c,0x38,0x00,0xbf,0x8f,0x34,0x00,0xb7,0x8f, -0x30,0x00,0xb6,0x8f,0x2c,0x00,0xb5,0x8f,0x28,0x00,0xb4,0x8f,0x24,0x00,0xb3,0x8f, -0x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f,0x60,0x00,0x03,0x3c, -0x25,0x10,0x43,0x00,0x41,0xb0,0x04,0x3c,0x40,0x00,0xbd,0x27,0x00,0x00,0x82,0xac, -0x08,0x00,0xe0,0x03,0xfc,0x4a,0xa2,0xac,0x00,0x80,0x03,0x3c,0x25,0xb0,0x02,0x3c, -0x88,0x19,0x63,0x24,0x18,0x03,0x42,0x34,0x00,0x00,0x43,0xac,0x00,0x60,0x01,0x40, -0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34, -0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x02,0x80,0x05,0x3c,0x68,0x15,0xa5,0x24, -0x04,0x4b,0xa2,0x8c,0xfc,0x4a,0xa4,0x8c,0x00,0x08,0x03,0x3c,0x24,0x10,0x43,0x00, -0x25,0x20,0x82,0x00,0x41,0xb0,0x03,0x3c,0x00,0x00,0x64,0xac,0x08,0x00,0xe0,0x03, -0xfc,0x4a,0xa4,0xac,0x25,0xb0,0x04,0x3c,0x00,0x80,0x02,0x3c,0xc0,0xff,0xbd,0x27, -0x18,0x03,0x83,0x34,0xe4,0x19,0x42,0x24,0x3c,0x00,0xbf,0xaf,0x38,0x00,0xbe,0xaf, -0x34,0x00,0xb7,0xaf,0x30,0x00,0xb6,0xaf,0x2c,0x00,0xb5,0xaf,0x28,0x00,0xb4,0xaf, -0x24,0x00,0xb3,0xaf,0x20,0x00,0xb2,0xaf,0x1c,0x00,0xb1,0xaf,0x18,0x00,0xb0,0xaf, -0x00,0x00,0x62,0xac,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40, -0x02,0x80,0x02,0x3c,0x2a,0xb0,0x03,0x3c,0x68,0x15,0x51,0x24,0xb0,0x03,0x93,0x34, -0x2c,0x00,0x77,0x34,0x02,0x80,0x15,0x3c,0x02,0x80,0x16,0x3c,0x9c,0x06,0x00,0x08, -0x02,0x80,0x1e,0x3c,0x14,0x64,0x26,0x92,0xe4,0x64,0x25,0x8e,0x00,0x32,0x06,0x00, -0x21,0x30,0xc2,0x00,0x78,0x64,0x26,0xae,0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf, -0xe4,0x64,0x30,0x8e,0x0a,0x00,0x04,0x24,0x21,0x90,0x00,0x00,0x00,0x00,0x70,0xae, -0x4d,0x01,0x00,0x0c,0xff,0xff,0x10,0x32,0x02,0x80,0x02,0x3c,0x25,0x80,0x02,0x02, -0x0c,0x00,0x05,0x92,0x02,0x00,0x04,0x92,0xff,0x00,0x02,0x24,0xff,0x00,0xa3,0x30, -0x04,0x00,0x62,0x10,0x21,0x80,0x04,0x02,0x00,0x00,0x63,0xae,0x01,0x00,0x12,0x24, -0x14,0x64,0x25,0xa2,0x88,0x96,0xb0,0xae,0x21,0x28,0x00,0x02,0x02,0x00,0xa2,0x90, -0x08,0x00,0x10,0x26,0x21,0x20,0x00,0x02,0xff,0x00,0x42,0x30,0x00,0x00,0x62,0xae, -0x03,0x00,0xa3,0x90,0x00,0x00,0x00,0x00,0x7f,0x00,0x63,0x30,0x00,0x00,0x63,0xae, -0x00,0x00,0x72,0xae,0x03,0x00,0xa2,0x90,0x84,0x96,0xc3,0x92,0x02,0x00,0xa2,0x90, -0x00,0x00,0x00,0x00,0xff,0x00,0x42,0x30,0x2c,0x00,0x42,0x28,0x11,0x00,0x40,0x10, -0x08,0x00,0x02,0x24,0x03,0x00,0xa2,0x90,0x00,0x00,0x00,0x00,0x7f,0x00,0x42,0x30, -0x84,0x96,0xc2,0xa2,0x02,0x00,0xa3,0x90,0x02,0x80,0x02,0x3c,0x74,0x84,0x42,0x24, -0xff,0x00,0x63,0x30,0xc0,0x18,0x03,0x00,0x21,0x18,0x62,0x00,0x04,0x00,0x62,0x8c, -0x00,0x00,0x00,0x00,0x09,0xf8,0x40,0x00,0x80,0x96,0xc2,0xaf,0x21,0xa0,0x40,0x00, -0x08,0x00,0x02,0x24,0x0a,0x00,0x04,0x24,0x05,0x00,0x82,0x12,0x00,0x01,0x07,0x24, -0x01,0x00,0x02,0x24,0x02,0x00,0x03,0x24,0x01,0x00,0xe2,0xa2,0x01,0x00,0xe3,0xa2, -0xbc,0xff,0x40,0x16,0x20,0x10,0x02,0x3c,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34, -0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0xfc,0x4a,0x22,0x8e,0x00,0x04,0x03,0x3c, -0x41,0xb0,0x04,0x3c,0x25,0x10,0x43,0x00,0x00,0x00,0x82,0xac,0x3c,0x00,0xbf,0x8f, -0xfc,0x4a,0x22,0xae,0x38,0x00,0xbe,0x8f,0x34,0x00,0xb7,0x8f,0x30,0x00,0xb6,0x8f, -0x2c,0x00,0xb5,0x8f,0x28,0x00,0xb4,0x8f,0x24,0x00,0xb3,0x8f,0x20,0x00,0xb2,0x8f, -0x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x40,0x00,0xbd,0x27, -0xc8,0xff,0xbd,0x27,0xff,0xff,0xa8,0x30,0x02,0x80,0x02,0x3c,0x25,0x40,0x02,0x01, -0x30,0x00,0xb6,0xaf,0x20,0x00,0xb2,0xaf,0x34,0x00,0xbf,0xaf,0x2c,0x00,0xb5,0xaf, -0x28,0x00,0xb4,0xaf,0x24,0x00,0xb3,0xaf,0x1c,0x00,0xb1,0xaf,0x18,0x00,0xb0,0xaf, -0x00,0x00,0x03,0x8d,0xff,0xff,0xd2,0x30,0x21,0xb0,0xa0,0x00,0x00,0xc0,0x02,0x24, -0x08,0x00,0x45,0x26,0x04,0x00,0x06,0x8d,0x24,0x18,0x62,0x00,0xff,0x3f,0xa5,0x30, -0xf0,0xff,0x02,0x3c,0x25,0x18,0x65,0x00,0xff,0xff,0x42,0x34,0x24,0x18,0x62,0x00, -0x00,0x80,0x05,0x3c,0x25,0x18,0x65,0x00,0xff,0x01,0xc6,0x34,0x00,0x00,0x03,0xad, -0x04,0x00,0x06,0xad,0x21,0x48,0x80,0x00,0xff,0xff,0xe7,0x30,0x18,0x00,0x12,0xa5, -0x1a,0x00,0x07,0xa1,0x18,0x00,0x03,0x8d,0xff,0x7f,0x02,0x3c,0xff,0xff,0x42,0x34, -0x24,0x18,0x62,0x00,0x02,0x80,0x15,0x3c,0x18,0x00,0x03,0xad,0x68,0x15,0xa5,0x26, -0xd6,0x63,0xa3,0x90,0x00,0x00,0x00,0x00,0x01,0x00,0x62,0x24,0xd6,0x63,0xa2,0xa0, -0x18,0x00,0x04,0x8d,0xff,0x80,0x02,0x3c,0x20,0x00,0x45,0x26,0xff,0xff,0x42,0x34, -0x7f,0x00,0x63,0x30,0xff,0xff,0xb2,0x30,0x24,0x20,0x82,0x00,0x00,0x1e,0x03,0x00, -0x25,0xb0,0x02,0x3c,0xc0,0x00,0x42,0x34,0x25,0x20,0x83,0x00,0x07,0x00,0x45,0x32, -0x18,0x00,0x04,0xad,0x00,0x00,0x52,0xa4,0x03,0x00,0xa0,0x10,0xff,0xff,0x42,0x32, -0x08,0x00,0x42,0x26,0xff,0xff,0x42,0x30,0x68,0x15,0xb4,0x26,0x54,0x65,0x86,0x8e, -0x58,0x65,0x90,0x8e,0xf8,0xff,0x52,0x30,0x21,0x10,0xd2,0x00,0x2b,0x10,0x02,0x02, -0x31,0x00,0x40,0x10,0xff,0x00,0x33,0x31,0x23,0x80,0x06,0x02,0x21,0x28,0xc0,0x02, -0xff,0xff,0x07,0x32,0x01,0x00,0x11,0x24,0x21,0x20,0x60,0x02,0x10,0x01,0x00,0x0c, -0x10,0x00,0xb1,0xaf,0x23,0x18,0x50,0x02,0xff,0xff,0x72,0x30,0x22,0x10,0x02,0x3c, -0x21,0x10,0x42,0x02,0x21,0x20,0x60,0x02,0x4d,0x01,0x00,0x0c,0x54,0x65,0x82,0xae, -0x21,0x28,0xd0,0x02,0x21,0x38,0x40,0x02,0x21,0x20,0x60,0x02,0x10,0x00,0xb1,0xaf, -0x22,0x10,0x06,0x3c,0x10,0x01,0x00,0x0c,0x68,0x15,0xb1,0x26,0x54,0x65,0x23,0x8e, -0x25,0xb0,0x10,0x3c,0xb0,0x03,0x02,0x36,0x21,0x20,0x60,0x02,0x00,0x00,0x43,0xac, -0x4d,0x01,0x00,0x0c,0x00,0x00,0x00,0x00,0x54,0x65,0x25,0x8e,0xec,0x00,0x02,0x36, -0xbd,0x00,0x04,0x36,0x00,0x00,0x45,0xac,0x00,0x00,0x83,0x90,0xc2,0x00,0x10,0x36, -0x34,0x00,0xbf,0x8f,0x10,0x00,0x63,0x34,0x00,0x00,0x83,0xa0,0x30,0x00,0xb6,0x8f, -0x00,0x00,0x05,0xa6,0x2c,0x00,0xb5,0x8f,0x28,0x00,0xb4,0x8f,0x24,0x00,0xb3,0x8f, -0x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f,0x01,0x00,0x02,0x24, -0x08,0x00,0xe0,0x03,0x38,0x00,0xbd,0x27,0x21,0x28,0xc0,0x02,0x21,0x20,0x60,0x02, -0x21,0x38,0x40,0x02,0x01,0x00,0x02,0x24,0x10,0x01,0x00,0x0c,0x10,0x00,0xa2,0xaf, -0x54,0x65,0x83,0x8e,0x68,0x15,0xb1,0x26,0x25,0xb0,0x10,0x3c,0x21,0x18,0x72,0x00, -0x54,0x65,0x83,0xae,0x54,0x65,0x23,0x8e,0xb0,0x03,0x02,0x36,0x21,0x20,0x60,0x02, -0x00,0x00,0x43,0xac,0x4d,0x01,0x00,0x0c,0x00,0x00,0x00,0x00,0x54,0x65,0x25,0x8e, -0xec,0x00,0x02,0x36,0xbd,0x00,0x04,0x36,0x00,0x00,0x45,0xac,0x00,0x00,0x83,0x90, -0xc2,0x00,0x10,0x36,0x34,0x00,0xbf,0x8f,0x10,0x00,0x63,0x34,0x00,0x00,0x83,0xa0, -0x30,0x00,0xb6,0x8f,0x00,0x00,0x05,0xa6,0x2c,0x00,0xb5,0x8f,0x28,0x00,0xb4,0x8f, -0x24,0x00,0xb3,0x8f,0x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f, -0x01,0x00,0x02,0x24,0x08,0x00,0xe0,0x03,0x38,0x00,0xbd,0x27,0xe0,0xff,0xbd,0x27, -0x25,0xb0,0x02,0x3c,0x14,0x00,0xb1,0xaf,0x18,0x00,0xbf,0xaf,0x10,0x00,0xb0,0xaf, -0xbf,0x00,0x42,0x34,0x00,0x00,0x43,0x90,0x21,0x28,0x00,0x00,0x08,0x00,0x06,0x24, -0x04,0x00,0x63,0x2c,0x12,0x00,0x60,0x14,0x21,0x88,0x80,0x00,0x00,0x60,0x02,0x40, -0x01,0x00,0x41,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x02,0x80,0x03,0x3c, -0x00,0x7b,0x63,0x24,0x04,0x00,0x64,0x8c,0x00,0x00,0x23,0xae,0x04,0x00,0x71,0xac, -0x00,0x00,0x91,0xac,0x04,0x00,0x24,0xae,0x00,0x60,0x82,0x40,0x18,0x00,0xbf,0x8f, -0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x20,0x00,0xbd,0x27, -0x08,0x00,0x82,0x94,0x02,0x80,0x04,0x3c,0x97,0x45,0x00,0x0c,0x25,0x20,0x44,0x00, -0x00,0x60,0x10,0x40,0x01,0x00,0x01,0x36,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40, -0x08,0x00,0x25,0x8e,0x0c,0x00,0x26,0x96,0x14,0x00,0x27,0x96,0xf0,0x06,0x00,0x0c, -0x09,0x00,0x04,0x24,0x04,0x00,0x23,0x8e,0x00,0x00,0x22,0x8e,0x21,0x20,0x20,0x02, -0x00,0x00,0x62,0xac,0x04,0x00,0x43,0xac,0x00,0x00,0x31,0xae,0xbd,0x4e,0x00,0x0c, -0x04,0x00,0x31,0xae,0x00,0x60,0x90,0x40,0x18,0x00,0xbf,0x8f,0x14,0x00,0xb1,0x8f, -0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x20,0x00,0xbd,0x27,0x02,0x80,0x02,0x3c, -0x68,0x15,0x47,0x24,0x8c,0x64,0xe3,0x90,0xff,0xff,0xa5,0x30,0x09,0x00,0xa3,0x10, -0x21,0x20,0xc0,0x00,0xfc,0x64,0xe2,0x8c,0x00,0x00,0x00,0x00,0x08,0x00,0xc2,0xac, -0x06,0x65,0xe3,0x94,0x0e,0x00,0x02,0x24,0x14,0x00,0xc2,0xac,0x8b,0x07,0x00,0x08, -0x0c,0x00,0xc3,0xac,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x00,0x80,0x03,0x3c, -0x25,0xb0,0x02,0x3c,0xd0,0xff,0xbd,0x27,0x4c,0x1f,0x63,0x24,0x18,0x03,0x42,0x34, -0x28,0x00,0xbf,0xaf,0x24,0x00,0xb3,0xaf,0x20,0x00,0xb2,0xaf,0x1c,0x00,0xb1,0xaf, -0x18,0x00,0xb0,0xaf,0x00,0x00,0x43,0xac,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34, -0x00,0x60,0x81,0x40,0x2a,0xb0,0x02,0x3c,0x36,0x00,0x42,0x34,0x00,0x00,0x43,0x90, -0x02,0x80,0x13,0x3c,0x68,0x15,0x66,0x26,0xc0,0x18,0x03,0x00,0x5c,0x65,0xc5,0x8c, -0x23,0xb0,0x04,0x3c,0xf0,0x07,0x63,0x30,0xff,0x1f,0x02,0x3c,0x21,0x18,0x64,0x00, -0xff,0xff,0x42,0x34,0x24,0x20,0x62,0x00,0x23,0x88,0x85,0x00,0x2b,0x38,0x85,0x00, -0x00,0x04,0x22,0x26,0x00,0x65,0xc3,0x8c,0x0b,0x88,0x47,0x00,0x01,0x04,0x25,0x2e, -0xfc,0x64,0xc3,0xac,0x60,0x65,0xc4,0xac,0x06,0x65,0xc0,0xa4,0x11,0x00,0xa0,0x14, -0x05,0x65,0xc0,0xa0,0x00,0xfc,0x83,0x24,0x23,0x10,0x02,0x3c,0x0b,0x18,0x87,0x00, -0xff,0x03,0x42,0x34,0x2b,0x10,0x43,0x00,0x33,0x00,0x40,0x14,0x00,0x00,0x00,0x00, -0x23,0x88,0x83,0x00,0x2b,0x10,0x83,0x00,0x5c,0x65,0xc3,0xac,0x03,0x00,0x40,0x10, -0x01,0x04,0x25,0x2e,0x00,0x04,0x31,0x26,0x01,0x04,0x25,0x2e,0x0e,0x00,0xa0,0x10, -0x68,0x15,0x70,0x26,0x68,0x15,0x70,0x26,0x60,0x65,0x03,0x8e,0x5c,0x65,0x04,0x8e, -0x00,0x00,0x00,0x00,0x2b,0x10,0x83,0x00,0x25,0x00,0x40,0x14,0x2b,0x10,0x64,0x00, -0x51,0x00,0x40,0x14,0x25,0xb0,0x02,0x3c,0x80,0x00,0x03,0x24,0xd0,0x03,0x42,0x34, -0x00,0x00,0x43,0xac,0x68,0x15,0x70,0x26,0x5c,0x65,0x03,0x96,0x2a,0xb0,0x02,0x3c, -0x35,0x00,0x42,0x34,0xc2,0x88,0x03,0x00,0x00,0x00,0x51,0xa0,0x8f,0x10,0x00,0x0c, -0x00,0x00,0x00,0x00,0x06,0x65,0x03,0x96,0x25,0xb0,0x02,0x3c,0xb0,0x03,0x42,0x34, -0x00,0x00,0x43,0xac,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38, -0x00,0x60,0x81,0x40,0xfc,0x4a,0x02,0x8e,0x80,0x00,0x03,0x3c,0x41,0xb0,0x04,0x3c, -0x25,0x10,0x43,0x00,0x00,0x00,0x82,0xac,0x28,0x00,0xbf,0x8f,0xfc,0x4a,0x02,0xae, -0x24,0x00,0xb3,0x8f,0x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f, -0x08,0x00,0xe0,0x03,0x30,0x00,0xbd,0x27,0x00,0x08,0x00,0x08,0x00,0xfc,0x63,0x24, -0xfc,0x64,0x05,0x8e,0x21,0x30,0x80,0x00,0xff,0xff,0x27,0x32,0x09,0x00,0x04,0x24, -0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,0xfc,0x64,0x03,0x8e,0x06,0x65,0x05,0x96, -0x5c,0x65,0x02,0x8e,0x21,0x18,0x71,0x00,0x21,0x28,0x25,0x02,0x21,0x10,0x51,0x00, -0x09,0x00,0x04,0x24,0x5c,0x65,0x02,0xae,0xfc,0x64,0x03,0xae,0x4d,0x01,0x00,0x0c, -0x06,0x65,0x05,0xa6,0x68,0x15,0x70,0x26,0x5c,0x65,0x03,0x96,0x2a,0xb0,0x02,0x3c, -0x35,0x00,0x42,0x34,0xc2,0x88,0x03,0x00,0x00,0x00,0x51,0xa0,0x8f,0x10,0x00,0x0c, -0x00,0x00,0x00,0x00,0x06,0x65,0x03,0x96,0x25,0xb0,0x02,0x3c,0xb0,0x03,0x42,0x34, -0x00,0x00,0x43,0xac,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38, -0x00,0x60,0x81,0x40,0xfc,0x4a,0x02,0x8e,0x80,0x00,0x03,0x3c,0x41,0xb0,0x04,0x3c, -0x25,0x10,0x43,0x00,0x00,0x00,0x82,0xac,0x28,0x00,0xbf,0x8f,0xfc,0x4a,0x02,0xae, -0x24,0x00,0xb3,0x8f,0x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f, -0x08,0x00,0xe0,0x03,0x30,0x00,0xbd,0x27,0x64,0x65,0x02,0x8e,0xfc,0x64,0x05,0x8e, -0x21,0x30,0x80,0x00,0x23,0x88,0x44,0x00,0xff,0xff,0x27,0x32,0x09,0x00,0x04,0x24, -0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,0xfc,0x64,0x03,0x8e,0x06,0x65,0x02,0x96, -0x60,0x65,0x12,0x96,0x21,0x18,0x71,0x00,0x21,0x10,0x22,0x02,0x23,0x10,0x11,0x3c, -0xfc,0x64,0x03,0xae,0x06,0x65,0x02,0xa6,0x06,0x00,0x40,0x16,0x5c,0x65,0x11,0xae, -0x09,0x00,0x04,0x24,0x4d,0x01,0x00,0x0c,0x68,0x15,0x70,0x26,0x46,0x08,0x00,0x08, -0x00,0x00,0x00,0x00,0x4d,0x01,0x00,0x0c,0x09,0x00,0x04,0x24,0xfc,0x64,0x05,0x8e, -0x09,0x00,0x04,0x24,0x23,0x10,0x06,0x3c,0x21,0x38,0x40,0x02,0x10,0x01,0x00,0x0c, -0x10,0x00,0xa0,0xaf,0xfc,0x64,0x03,0x8e,0x06,0x65,0x02,0x96,0x21,0x20,0x51,0x02, -0x21,0x18,0x72,0x00,0x21,0x10,0x42,0x02,0x5c,0x65,0x04,0xae,0x09,0x00,0x04,0x24, -0xfc,0x64,0x03,0xae,0x75,0x08,0x00,0x08,0x06,0x65,0x02,0xa6,0x02,0x80,0x09,0x3c, -0x68,0x15,0x28,0x25,0xdc,0x63,0x06,0x8d,0xff,0xff,0x02,0x34,0x3f,0x00,0xc2,0x10, -0x21,0x38,0x80,0x00,0x2b,0x10,0xc7,0x00,0x30,0x00,0x40,0x10,0x02,0x19,0x06,0x00, -0x21,0x10,0xc7,0x00,0x23,0x10,0x43,0x00,0x10,0x00,0x46,0x24,0xdc,0x63,0x06,0xad, -0x68,0x15,0x26,0x25,0x04,0x40,0xc4,0x8c,0xe0,0x63,0x02,0xad,0xff,0xff,0x02,0x34, -0x2f,0x00,0x82,0x10,0x00,0x00,0x00,0x00,0x2b,0x10,0x87,0x00,0x1f,0x00,0x40,0x10, -0x02,0x19,0x04,0x00,0x21,0x10,0x87,0x00,0x23,0x10,0x43,0x00,0x10,0x00,0x44,0x24, -0x04,0x40,0xc4,0xac,0xe0,0x63,0xc2,0xac,0xc0,0x10,0x05,0x00,0x21,0x10,0x45,0x00, -0x80,0x10,0x02,0x00,0x21,0x10,0x45,0x00,0x68,0x15,0x23,0x25,0x80,0x10,0x02,0x00, -0x21,0x28,0x43,0x00,0x68,0x51,0xa6,0x8c,0x00,0x21,0x07,0x00,0xff,0xff,0xc2,0x38, -0x0a,0x30,0x82,0x00,0x2b,0x18,0xc7,0x00,0x07,0x00,0x60,0x10,0x21,0x10,0xc7,0x00, -0x02,0x19,0x06,0x00,0x23,0x10,0x43,0x00,0x10,0x00,0x46,0x24,0x68,0x51,0xa6,0xac, -0x08,0x00,0xe0,0x03,0x6c,0x51,0xa2,0xac,0x02,0x19,0x06,0x00,0x23,0x10,0x43,0x00, -0x68,0x51,0xa2,0xac,0x08,0x00,0xe0,0x03,0x6c,0x51,0xa2,0xac,0x21,0x10,0x87,0x00, -0x23,0x10,0x43,0x00,0xa5,0x08,0x00,0x08,0x04,0x40,0xc2,0xac,0x21,0x10,0xc7,0x00, -0x68,0x15,0x26,0x25,0x04,0x40,0xc4,0x8c,0x23,0x10,0x43,0x00,0xdc,0x63,0x02,0xad, -0xe0,0x63,0x02,0xad,0xff,0xff,0x02,0x34,0xd4,0xff,0x82,0x14,0x2b,0x10,0x87,0x00, -0x00,0x21,0x07,0x00,0x9e,0x08,0x00,0x08,0x04,0x40,0xc4,0xac,0x00,0x31,0x04,0x00, -0x91,0x08,0x00,0x08,0xdc,0x63,0x06,0xad,0x63,0x00,0x82,0x24,0x77,0x00,0x42,0x2c, -0x00,0x00,0x85,0x28,0x04,0x00,0x40,0x10,0x21,0x18,0x00,0x00,0x64,0x00,0x82,0x24, -0x64,0x00,0x03,0x24,0x0b,0x18,0x45,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x60,0x00, -0x0c,0x00,0x82,0x8c,0x00,0x00,0x00,0x00,0x3f,0x00,0x42,0x30,0x04,0x00,0x42,0x28, -0x17,0x00,0x40,0x10,0x25,0xb0,0x02,0x3c,0x24,0x08,0x42,0x34,0x00,0x00,0x43,0x8c, -0x00,0x00,0x00,0x00,0x00,0x02,0x63,0x30,0x16,0x00,0x60,0x14,0x01,0x00,0x02,0x24, -0x05,0x00,0xa3,0x90,0x00,0x00,0x00,0x00,0x82,0x21,0x03,0x00,0x28,0x00,0x82,0x10, -0xf5,0xff,0x02,0x24,0x02,0x00,0x82,0x28,0x39,0x00,0x40,0x14,0x02,0x00,0x02,0x24, -0x2e,0x00,0x82,0x10,0xe9,0xff,0x02,0x24,0x03,0x00,0x02,0x24,0x24,0x00,0x82,0x10, -0x3e,0x00,0x63,0x30,0x05,0x00,0xc4,0x24,0xd2,0x08,0x00,0x08,0x00,0x00,0x00,0x00, -0x04,0x00,0xa4,0x90,0x00,0x00,0x00,0x00,0x42,0x20,0x04,0x00,0xd2,0x08,0x00,0x08, -0x96,0xff,0x84,0x24,0x05,0x00,0xa3,0x90,0x00,0x00,0x00,0x00,0x60,0x00,0x64,0x30, -0x42,0x21,0x04,0x00,0x0e,0x00,0x82,0x10,0x1f,0x00,0x62,0x30,0x02,0x00,0x82,0x28, -0x1d,0x00,0x40,0x14,0x02,0x00,0x02,0x24,0x14,0x00,0x82,0x10,0x1f,0x00,0x62,0x30, -0x03,0x00,0x02,0x24,0xeb,0xff,0x82,0x14,0x1f,0x00,0x62,0x30,0x40,0x10,0x02,0x00, -0xdd,0xff,0x03,0x24,0x23,0x30,0x62,0x00,0xf6,0x08,0x00,0x08,0x05,0x00,0xc4,0x24, -0x40,0x10,0x02,0x00,0xf5,0xff,0x03,0x24,0x0e,0x09,0x00,0x08,0x23,0x30,0x62,0x00, -0x3e,0x00,0x63,0x30,0x23,0x30,0x43,0x00,0xf6,0x08,0x00,0x08,0x05,0x00,0xc4,0x24, -0xdd,0xff,0x02,0x24,0x16,0x09,0x00,0x08,0x23,0x30,0x43,0x00,0x40,0x10,0x02,0x00, -0xe9,0xff,0x03,0x24,0x0e,0x09,0x00,0x08,0x23,0x30,0x62,0x00,0x3e,0x00,0x63,0x30, -0x16,0x09,0x00,0x08,0x23,0x30,0x43,0x00,0xd2,0xff,0x80,0x14,0x1f,0x00,0x62,0x30, -0x40,0x10,0x02,0x00,0xf8,0xff,0x03,0x24,0x0e,0x09,0x00,0x08,0x23,0x30,0x62,0x00, -0xcc,0xff,0x80,0x14,0x3e,0x00,0x63,0x30,0xf8,0xff,0x02,0x24,0x16,0x09,0x00,0x08, -0x23,0x30,0x43,0x00,0xa0,0xff,0xbd,0x27,0x02,0x80,0x02,0x3c,0x4c,0x00,0xb5,0xaf, -0x5c,0x00,0xbf,0xaf,0x58,0x00,0xbe,0xaf,0x54,0x00,0xb7,0xaf,0x50,0x00,0xb6,0xaf, -0x48,0x00,0xb4,0xaf,0x44,0x00,0xb3,0xaf,0x40,0x00,0xb2,0xaf,0x3c,0x00,0xb1,0xaf, -0x38,0x00,0xb0,0xaf,0x68,0x15,0x55,0x24,0x25,0xb0,0x03,0x3c,0x04,0x01,0x62,0x34, -0x00,0x00,0x43,0x8c,0x44,0x65,0xa7,0x8e,0x00,0x00,0x00,0x00,0x33,0x00,0xe3,0x10, -0x48,0x65,0xa3,0xae,0x2b,0x10,0x67,0x00,0xa8,0x00,0x40,0x14,0x2b,0x10,0xe3,0x00, -0xd1,0x00,0x40,0x14,0x02,0x80,0x02,0x3c,0x68,0x15,0x44,0x24,0x18,0x65,0x83,0x94, -0x02,0x80,0x02,0x3c,0x21,0x88,0x00,0x00,0x19,0x00,0x40,0x1a,0x25,0x98,0x62,0x00, -0x21,0xb8,0x80,0x00,0x21,0xb0,0x80,0x00,0x01,0x00,0x14,0x24,0x21,0x20,0x00,0x00, -0x21,0x80,0x93,0x00,0x00,0x00,0x05,0x8e,0x00,0x00,0x00,0x00,0x07,0x00,0xa0,0x10, -0x01,0x00,0x22,0x26,0x04,0x00,0x02,0x8e,0x00,0xf0,0x03,0x3c,0x00,0x20,0x04,0x3c, -0x24,0x10,0x43,0x00,0x1e,0x00,0x44,0x10,0x06,0x00,0x22,0x26,0xff,0xff,0x51,0x30, -0x82,0x16,0x05,0x00,0x01,0x00,0x42,0x30,0x34,0x00,0x54,0x10,0x00,0x00,0x00,0x00, -0x80,0x20,0x11,0x00,0x2a,0x10,0x92,0x00,0xed,0xff,0x40,0x14,0x00,0x00,0x00,0x00, -0xbd,0x4e,0x00,0x0c,0x21,0x20,0xc0,0x03,0x02,0x80,0x02,0x3c,0x08,0x04,0x44,0x24, -0x21,0x28,0x00,0x00,0x21,0x30,0x00,0x00,0x31,0x1c,0x00,0x0c,0x21,0x38,0x00,0x00, -0x25,0xb0,0x03,0x3c,0x04,0x01,0x62,0x34,0x00,0x00,0x43,0x8c,0x44,0x65,0xa7,0x8e, -0x00,0x00,0x00,0x00,0xcf,0xff,0xe3,0x14,0x48,0x65,0xa3,0xae,0x25,0xb0,0x03,0x3c, -0x00,0x01,0x62,0x34,0x00,0x00,0x47,0xac,0x66,0x09,0x00,0x08,0x44,0x65,0xa7,0xae, -0xb0,0x4c,0xe2,0x8e,0x00,0x00,0x00,0x00,0x01,0x00,0x42,0x24,0xb0,0x4c,0xe2,0xae, -0x0c,0x00,0x04,0x8e,0x0c,0x00,0x02,0x24,0x3f,0x00,0x83,0x30,0x64,0x00,0x62,0x10, -0x21,0x28,0xe0,0x02,0x3f,0x00,0x83,0x30,0x0d,0x00,0x02,0x24,0x59,0x00,0x62,0x10, -0x00,0x00,0x00,0x00,0x3f,0x00,0x83,0x30,0x0e,0x00,0x02,0x24,0x04,0x00,0x62,0x10, -0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x8e,0x5b,0x09,0x00,0x08,0x06,0x00,0x22,0x26, -0xbc,0x4c,0xe2,0x8e,0x00,0x00,0x00,0x00,0x01,0x00,0x42,0x24,0xbc,0x4c,0xe2,0xae, -0x00,0x00,0x05,0x8e,0x5b,0x09,0x00,0x08,0x06,0x00,0x22,0x26,0x00,0x40,0xc2,0x8e, -0x00,0x00,0x00,0x00,0x02,0x12,0x02,0x00,0x0f,0x00,0x42,0x30,0x05,0x00,0x54,0x10, -0xc2,0x13,0x05,0x00,0x1e,0x00,0x42,0x30,0x21,0x10,0x51,0x00,0x60,0x09,0x00,0x08, -0xff,0xff,0x51,0x30,0x02,0x40,0xc2,0x92,0x00,0x00,0x00,0x00,0x1e,0x00,0x40,0x14, -0x02,0x80,0x03,0x3c,0x04,0x00,0x03,0x8e,0x00,0x00,0x00,0x00,0x02,0x14,0x03,0x00, -0x0f,0x00,0x42,0x30,0x17,0x00,0x40,0x14,0x02,0x17,0x03,0x00,0x03,0x00,0x44,0x30, -0x08,0x00,0x80,0x10,0x00,0xc0,0x02,0x3c,0x24,0x10,0x62,0x00,0x11,0x00,0x40,0x14, -0x03,0x00,0x02,0x24,0x10,0x00,0x82,0x10,0x02,0x80,0x03,0x3c,0x0f,0x00,0x80,0x10, -0x68,0x15,0x63,0x24,0x80,0x10,0x11,0x00,0x21,0x28,0x53,0x00,0xec,0xff,0xa3,0x8c, -0x25,0xb0,0x02,0x3c,0xd4,0x02,0x42,0x34,0x21,0x20,0x00,0x02,0x00,0x00,0x43,0xac, -0xdc,0x08,0x00,0x0c,0x00,0x00,0x00,0x00,0x21,0x20,0x40,0x00,0x8b,0x08,0x00,0x0c, -0x21,0x28,0x00,0x00,0x02,0x80,0x03,0x3c,0x68,0x15,0x63,0x24,0x02,0x40,0x62,0x90, -0x00,0x00,0x00,0x00,0x85,0x00,0x54,0x10,0x00,0x00,0x00,0x00,0x02,0x80,0x04,0x3c, -0x68,0x15,0x84,0x24,0x02,0x40,0x83,0x90,0x02,0x00,0x02,0x24,0x68,0x00,0x62,0x10, -0x00,0x00,0x00,0x00,0x25,0xb0,0x03,0x3c,0x4c,0x00,0x63,0x34,0x00,0x00,0x62,0x90, -0x00,0x00,0x00,0x00,0x03,0x00,0x42,0x30,0x08,0x00,0x54,0x10,0x02,0x80,0x04,0x3c, -0x00,0x00,0x05,0x8e,0x00,0x00,0x00,0x00,0xc2,0x13,0x05,0x00,0x1e,0x00,0x42,0x30, -0x21,0x10,0x51,0x00,0x60,0x09,0x00,0x08,0xff,0xff,0x51,0x30,0xd0,0x02,0x02,0x24, -0x68,0x15,0x84,0x24,0xdc,0x63,0x82,0xac,0x00,0x00,0x05,0x8e,0xd3,0x09,0x00,0x08, -0xc2,0x13,0x05,0x00,0xb8,0x4c,0xa2,0x8c,0x00,0x00,0x00,0x00,0x01,0x00,0x42,0x24, -0xb8,0x4c,0xa2,0xac,0x0c,0x00,0x04,0x8e,0x86,0x09,0x00,0x08,0x3f,0x00,0x83,0x30, -0xb4,0x4c,0xe2,0x8e,0x00,0x00,0x00,0x00,0x01,0x00,0x42,0x24,0xb4,0x4c,0xe2,0xae, -0x0c,0x00,0x04,0x8e,0x82,0x09,0x00,0x08,0x3f,0x00,0x83,0x30,0x4c,0x65,0xa2,0x8e, -0xff,0xff,0x71,0x30,0x23,0x10,0x47,0x00,0xff,0xff,0x50,0x30,0x21,0x18,0x11,0x02, -0xff,0xff,0x72,0x30,0xa1,0x4e,0x00,0x0c,0x21,0x20,0x40,0x02,0x76,0x00,0x40,0x10, -0x21,0xf0,0x40,0x00,0x08,0x00,0x42,0x8c,0x44,0x65,0xa6,0x8e,0x21,0x38,0x00,0x02, -0x21,0x18,0x52,0x00,0x21,0x28,0x40,0x00,0x08,0x00,0x04,0x24,0x14,0x65,0xa3,0xae, -0x18,0x65,0xa2,0xae,0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,0x4d,0x01,0x00,0x0c, -0x08,0x00,0x04,0x24,0x18,0x65,0xa5,0x8e,0x25,0xb0,0x03,0x3c,0x24,0x10,0x02,0x3c, -0x21,0x28,0xb0,0x00,0x00,0x01,0x70,0x34,0x00,0x00,0x02,0xae,0x21,0x38,0x20,0x02, -0x08,0x00,0x04,0x24,0x24,0x10,0x06,0x3c,0x44,0x65,0xa2,0xae,0x10,0x01,0x00,0x0c, -0x10,0x00,0xa0,0xaf,0x48,0x65,0xa3,0x8e,0x08,0x00,0x04,0x24,0x4d,0x01,0x00,0x0c, -0x44,0x65,0xa3,0xae,0x44,0x65,0xa2,0x8e,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0xae, -0x46,0x09,0x00,0x08,0x02,0x80,0x02,0x3c,0x23,0x10,0x67,0x00,0xff,0xff,0x52,0x30, -0xa1,0x4e,0x00,0x0c,0x21,0x20,0x40,0x02,0x56,0x00,0x40,0x10,0x21,0xf0,0x40,0x00, -0x08,0x00,0x42,0x8c,0x44,0x65,0xa6,0x8e,0x08,0x00,0x04,0x24,0x21,0x18,0x52,0x00, -0x21,0x28,0x40,0x00,0x21,0x38,0x40,0x02,0x14,0x65,0xa3,0xae,0x18,0x65,0xa2,0xae, -0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,0x48,0x65,0xa3,0x8e,0x08,0x00,0x04,0x24, -0x4d,0x01,0x00,0x0c,0x44,0x65,0xa3,0xae,0x44,0x65,0xa3,0x8e,0x25,0xb0,0x04,0x3c, -0x00,0x01,0x82,0x34,0x00,0x00,0x43,0xac,0x46,0x09,0x00,0x08,0x02,0x80,0x02,0x3c, -0x04,0x00,0x03,0x8e,0x00,0x00,0x00,0x00,0x02,0x14,0x03,0x00,0x0f,0x00,0x42,0x30, -0x08,0x00,0x42,0x28,0x93,0xff,0x40,0x10,0x02,0x17,0x03,0x00,0x03,0x00,0x42,0x30, -0x90,0xff,0x40,0x14,0x80,0x10,0x11,0x00,0x21,0x28,0x53,0x00,0xec,0xff,0xa3,0x8c, -0x25,0xb0,0x02,0x3c,0xd4,0x02,0x42,0x34,0x21,0x20,0x00,0x02,0x00,0x00,0x43,0xac, -0xdc,0x08,0x00,0x0c,0x00,0x00,0x00,0x00,0x21,0x20,0x40,0x00,0x8b,0x08,0x00,0x0c, -0x21,0x28,0x00,0x00,0xca,0x09,0x00,0x08,0x25,0xb0,0x03,0x3c,0x04,0x00,0x03,0x8e, -0x00,0x00,0x00,0x00,0x02,0x14,0x03,0x00,0x0f,0x00,0x42,0x30,0x08,0x00,0x42,0x28, -0x06,0x00,0x40,0x10,0x00,0xc0,0x02,0x3c,0x02,0x17,0x03,0x00,0x03,0x00,0x42,0x30, -0x0c,0x00,0x40,0x10,0x80,0x10,0x11,0x00,0x00,0xc0,0x02,0x3c,0x24,0x10,0x62,0x00, -0x6f,0xff,0x40,0x14,0x02,0x80,0x04,0x3c,0x02,0x17,0x03,0x00,0x03,0x00,0x42,0x30, -0x03,0x00,0x03,0x24,0x6b,0xff,0x43,0x10,0x68,0x15,0x84,0x24,0x67,0xff,0x40,0x10, -0x80,0x10,0x11,0x00,0x21,0x28,0x53,0x00,0xec,0xff,0xa3,0x8c,0x25,0xb0,0x02,0x3c, -0xd4,0x02,0x42,0x34,0x21,0x20,0x00,0x02,0x00,0x00,0x43,0xac,0xdc,0x08,0x00,0x0c, -0x00,0x00,0x00,0x00,0x21,0x20,0x40,0x00,0x8b,0x08,0x00,0x0c,0x21,0x28,0x00,0x00, -0xc4,0x09,0x00,0x08,0x02,0x80,0x04,0x3c,0x25,0xb0,0x04,0x3c,0x44,0x44,0x02,0x3c, -0xbc,0x02,0x83,0x34,0x44,0x44,0x42,0x34,0x00,0x00,0x62,0xac,0x67,0x09,0x00,0x08, -0x02,0x80,0x02,0x3c,0x48,0x65,0xa5,0x8e,0x25,0xb0,0x04,0x3c,0x66,0x66,0x02,0x3c, -0x00,0x01,0x83,0x34,0x66,0x66,0x42,0x34,0xbc,0x02,0x84,0x34,0x00,0x00,0x65,0xac, -0x00,0x00,0x82,0xac,0x66,0x09,0x00,0x08,0x44,0x65,0xa5,0xae,0x00,0x60,0x02,0x40, -0x01,0x00,0x41,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x02,0x80,0x03,0x3c, -0xd8,0x8c,0x64,0xac,0x00,0x60,0x82,0x40,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00, -0x02,0x80,0x02,0x3c,0xd8,0x8c,0x45,0x8c,0x00,0x80,0x03,0x3c,0x25,0xb0,0x02,0x3c, -0x18,0x03,0x42,0x34,0x10,0x2a,0x63,0x24,0x00,0x00,0x43,0xac,0x04,0x00,0x02,0x24, -0x1e,0x00,0xa2,0x10,0x05,0x00,0xa2,0x2c,0x10,0x00,0x40,0x10,0x05,0x00,0x02,0x24, -0x03,0x00,0x02,0x24,0x08,0x00,0xa2,0x10,0x00,0x19,0x04,0x00,0x80,0x10,0x04,0x00, -0x21,0x10,0x44,0x00,0xc0,0x10,0x02,0x00,0x23,0x10,0x44,0x00,0x00,0x11,0x02,0x00, -0x21,0x10,0x44,0x00,0x40,0x19,0x02,0x00,0xff,0xff,0x63,0x24,0xfe,0xff,0x60,0x14, -0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0xf3,0xff,0xa2,0x10, -0x06,0x00,0x02,0x24,0xf2,0xff,0xa2,0x14,0x80,0x10,0x04,0x00,0x40,0x11,0x04,0x00, -0x23,0x10,0x44,0x00,0x80,0x10,0x02,0x00,0x21,0x10,0x44,0x00,0x00,0x19,0x02,0x00, -0x23,0x18,0x62,0x00,0x9a,0x0a,0x00,0x08,0x00,0x19,0x03,0x00,0x80,0x10,0x04,0x00, -0x21,0x10,0x44,0x00,0xc0,0x10,0x02,0x00,0x23,0x10,0x44,0x00,0x00,0x11,0x02,0x00, -0x21,0x10,0x44,0x00,0x9a,0x0a,0x00,0x08,0x00,0x19,0x02,0x00,0x02,0x80,0x02,0x3c, -0xd8,0x8c,0x45,0x8c,0x00,0x80,0x03,0x3c,0x25,0xb0,0x02,0x3c,0x18,0x03,0x42,0x34, -0xcc,0x2a,0x63,0x24,0x00,0x00,0x43,0xac,0x05,0x00,0x02,0x24,0x10,0x00,0xa2,0x10, -0x06,0x00,0xa2,0x2c,0x09,0x00,0x40,0x14,0x04,0x00,0x02,0x24,0x06,0x00,0x02,0x24, -0x0f,0x00,0xa2,0x10,0x00,0x11,0x04,0x00,0xff,0xff,0x84,0x24,0xfe,0xff,0x80,0x14, -0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0xfa,0xff,0xa2,0x14, -0x80,0x10,0x04,0x00,0x21,0x10,0x44,0x00,0xc2,0x0a,0x00,0x08,0x40,0x20,0x02,0x00, -0x80,0x10,0x04,0x00,0x21,0x10,0x44,0x00,0xc2,0x0a,0x00,0x08,0x80,0x20,0x02,0x00, -0x23,0x10,0x44,0x00,0xc2,0x0a,0x00,0x08,0x40,0x20,0x02,0x00,0xff,0xff,0x85,0x30, -0x21,0x30,0x00,0x00,0x25,0xb0,0x03,0x3c,0x2a,0xb0,0x04,0x3c,0xb4,0x00,0x63,0x34, -0x01,0x00,0xa2,0x24,0x31,0x00,0x84,0x34,0x00,0x00,0x65,0xa0,0x00,0x00,0x85,0xa0, -0xff,0xff,0x45,0x30,0x12,0x00,0xa0,0x10,0x01,0x00,0x03,0x24,0x28,0xb0,0x07,0x3c, -0xe8,0x0a,0x00,0x08,0xff,0xff,0x08,0x24,0x00,0x00,0x83,0xa0,0x01,0x00,0x63,0x24, -0xff,0xff,0x63,0x30,0x2b,0x10,0xa3,0x00,0x09,0x00,0x40,0x14,0x08,0x00,0xc6,0x24, -0xf9,0xff,0x65,0x14,0x21,0x20,0xc7,0x00,0x01,0x00,0x63,0x24,0xff,0xff,0x63,0x30, -0x2b,0x10,0xa3,0x00,0x00,0x00,0x88,0xa0,0xf9,0xff,0x40,0x10,0x08,0x00,0xc6,0x24, -0x00,0x01,0xa2,0x2c,0x13,0x00,0x40,0x10,0x21,0x18,0xa0,0x00,0xff,0x00,0x08,0x24, -0x28,0xb0,0x07,0x3c,0xfc,0x0a,0x00,0x08,0xff,0xff,0x09,0x24,0xff,0xff,0x43,0x30, -0x00,0x00,0xa2,0xa0,0x00,0x01,0x62,0x2c,0x0a,0x00,0x40,0x10,0x08,0x00,0xc6,0x24, -0x01,0x00,0x62,0x24,0xf9,0xff,0x68,0x14,0x21,0x28,0xc7,0x00,0x00,0x01,0x02,0x24, -0xff,0xff,0x43,0x30,0x00,0x01,0x62,0x2c,0x00,0x00,0xa9,0xa0,0xf8,0xff,0x40,0x14, -0x08,0x00,0xc6,0x24,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0xd8,0xff,0xbd,0x27, -0x24,0x00,0xbf,0xaf,0x20,0x00,0xb4,0xaf,0x1c,0x00,0xb3,0xaf,0x18,0x00,0xb2,0xaf, -0x14,0x00,0xb1,0xaf,0x10,0x00,0xb0,0xaf,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34, -0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x25,0xb0,0x10,0x3c,0x42,0x00,0x14,0x36, -0xff,0xff,0x02,0x24,0x00,0x00,0x82,0xa2,0xd8,0x00,0x05,0x36,0x40,0x00,0x11,0x36, -0xa8,0x00,0x13,0x36,0xa0,0x00,0x12,0x36,0x00,0x10,0x03,0x24,0xa4,0x00,0x10,0x36, -0x00,0x80,0x02,0x3c,0x00,0x00,0x23,0xa6,0x00,0x00,0xa0,0xa0,0x00,0x00,0x40,0xae, -0x00,0x00,0x00,0xae,0x00,0x00,0x62,0xae,0x00,0x00,0xa3,0x90,0x80,0xff,0x02,0x24, -0xfd,0x00,0x04,0x24,0x25,0x18,0x62,0x00,0xfc,0x17,0x02,0x24,0x00,0x00,0xa3,0xa0, -0x00,0x00,0x22,0xa6,0xd3,0x0a,0x00,0x0c,0x00,0x00,0x00,0x00,0x02,0x80,0x02,0x3c, -0x68,0x15,0x42,0x24,0x68,0x4b,0x45,0x8c,0x60,0x4b,0x43,0x8c,0x64,0x4b,0x44,0x8c, -0xfc,0x37,0x02,0x24,0x00,0x00,0x43,0xae,0x00,0x00,0x04,0xae,0x00,0x00,0x65,0xae, -0x00,0x00,0x22,0xa6,0x00,0x00,0x80,0xa2,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34, -0x00,0x60,0x81,0x40,0x24,0x00,0xbf,0x8f,0x20,0x00,0xb4,0x8f,0x1c,0x00,0xb3,0x8f, -0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03, -0x28,0x00,0xbd,0x27,0xd0,0xff,0xbd,0x27,0x2c,0x00,0xbf,0xaf,0x28,0x00,0xb6,0xaf, -0x24,0x00,0xb5,0xaf,0x20,0x00,0xb4,0xaf,0x1c,0x00,0xb3,0xaf,0x18,0x00,0xb2,0xaf, -0x14,0x00,0xb1,0xaf,0x10,0x00,0xb0,0xaf,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34, -0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x25,0xb0,0x10,0x3c,0x40,0x00,0x05,0x36, -0x00,0x00,0xa2,0x94,0x24,0xfa,0x03,0x24,0xa8,0x00,0x13,0x36,0x24,0x10,0x43,0x00, -0x00,0x00,0xa2,0xa4,0xa0,0x00,0x12,0x36,0xa4,0x00,0x10,0x36,0x00,0x00,0x55,0x8e, -0x00,0x00,0x16,0x8e,0x00,0x00,0x71,0x8e,0x00,0x80,0x14,0x3c,0xfc,0x37,0x02,0x24, -0x00,0x00,0x40,0xae,0xfd,0x00,0x04,0x24,0x00,0x00,0x00,0xae,0x21,0x88,0x34,0x02, -0x00,0x00,0x74,0xae,0x00,0x00,0xa2,0xa4,0xd3,0x0a,0x00,0x0c,0x00,0x00,0x00,0x00, -0x00,0x00,0x55,0xae,0x00,0x00,0x16,0xae,0x00,0x00,0x71,0xae,0x00,0x60,0x01,0x40, -0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,0x2c,0x00,0xbf,0x8f,0x28,0x00,0xb6,0x8f, -0x24,0x00,0xb5,0x8f,0x20,0x00,0xb4,0x8f,0x1c,0x00,0xb3,0x8f,0x18,0x00,0xb2,0x8f, -0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x30,0x00,0xbd,0x27, -0xd0,0xff,0xbd,0x27,0x2c,0x00,0xbf,0xaf,0x28,0x00,0xb6,0xaf,0x24,0x00,0xb5,0xaf, -0x20,0x00,0xb4,0xaf,0x1c,0x00,0xb3,0xaf,0x18,0x00,0xb2,0xaf,0x14,0x00,0xb1,0xaf, -0x10,0x00,0xb0,0xaf,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38, -0x00,0x60,0x81,0x40,0x25,0xb0,0x10,0x3c,0x40,0x00,0x05,0x36,0x00,0x00,0xa2,0x94, -0xaf,0xff,0x03,0x24,0xa8,0x00,0x13,0x36,0x24,0x10,0x43,0x00,0x00,0x00,0xa2,0xa4, -0xa0,0x00,0x12,0x36,0xa4,0x00,0x10,0x36,0x00,0x00,0x55,0x8e,0x00,0x00,0x16,0x8e, -0x00,0x00,0x71,0x8e,0x00,0x80,0x14,0x3c,0xfc,0x37,0x02,0x24,0x00,0x00,0x40,0xae, -0xfd,0x00,0x04,0x24,0x00,0x00,0x00,0xae,0x21,0x88,0x34,0x02,0x00,0x00,0x74,0xae, -0x00,0x00,0xa2,0xa4,0xd3,0x0a,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x55,0xae, -0x00,0x00,0x16,0xae,0x00,0x00,0x71,0xae,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34, -0x00,0x60,0x81,0x40,0x2c,0x00,0xbf,0x8f,0x28,0x00,0xb6,0x8f,0x24,0x00,0xb5,0x8f, -0x20,0x00,0xb4,0x8f,0x1c,0x00,0xb3,0x8f,0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f, -0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x30,0x00,0xbd,0x27,0x00,0x60,0x01,0x40, -0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x25,0xb0,0x04,0x3c, -0x40,0x00,0x84,0x34,0x00,0x00,0x82,0x94,0xd8,0xfd,0x03,0x24,0x24,0x10,0x43,0x00, -0xfc,0x37,0x03,0x24,0x00,0x00,0x82,0xa4,0x00,0x00,0x83,0xa4,0x00,0x60,0x01,0x40, -0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00, -0x00,0x00,0x82,0x8c,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x30, -0x10,0x00,0x02,0x24,0x0c,0x00,0xc2,0x10,0x11,0x00,0xc3,0x28,0x06,0x00,0x60,0x10, -0x20,0x00,0x02,0x24,0x08,0x00,0x02,0x24,0x0d,0x00,0xc2,0x10,0x00,0x00,0x00,0x00, -0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x06,0x00,0xc2,0x10,0x00,0x00,0x00,0x00, -0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x85,0xa4,0x08,0x00,0xe0,0x03, -0x00,0x00,0x00,0x00,0x00,0x00,0x85,0xac,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00, -0x00,0x00,0x85,0xa0,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03, -0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x25,0xb0,0x02,0x3c, -0x0a,0x00,0x42,0x34,0x00,0x00,0x43,0x90,0xff,0xff,0xa5,0x24,0x00,0x2c,0x05,0x00, -0xfd,0x00,0x63,0x30,0x03,0x2c,0x05,0x00,0xff,0xff,0x87,0x30,0x00,0x00,0x43,0xa0, -0x1a,0x00,0xa0,0x04,0x00,0x00,0x00,0x00,0x21,0x30,0x40,0x00,0x07,0x10,0xa7,0x00, -0x01,0x00,0x42,0x30,0xfd,0x00,0x64,0x30,0x00,0x00,0x42,0x38,0x02,0x00,0x63,0x34, -0x0a,0x18,0x82,0x00,0x00,0x00,0xc3,0xa0,0x04,0x00,0x63,0x34,0x00,0x00,0xc3,0xa0, -0x09,0x00,0x02,0x24,0xff,0xff,0x42,0x24,0xff,0xff,0x41,0x04,0xff,0xff,0x42,0x24, -0xfb,0x00,0x63,0x30,0x00,0x00,0xc3,0xa0,0x04,0x00,0x02,0x24,0xff,0xff,0x42,0x24, -0xff,0xff,0x41,0x04,0xff,0xff,0x42,0x24,0xff,0xff,0xa2,0x24,0x00,0x2c,0x02,0x00, -0x03,0x2c,0x05,0x00,0xea,0xff,0xa1,0x04,0x07,0x10,0xa7,0x00,0x08,0x00,0xe0,0x03, -0x00,0x00,0x00,0x00,0x25,0xb0,0x02,0x3c,0x0a,0x00,0x42,0x34,0x00,0x00,0x43,0x90, -0xff,0xff,0x84,0x24,0x00,0x24,0x04,0x00,0x03,0x24,0x04,0x00,0xff,0x00,0x65,0x30, -0x1d,0x00,0x80,0x04,0x21,0x38,0x00,0x00,0x21,0x30,0x40,0x00,0x01,0x00,0x08,0x24, -0x04,0x00,0xa5,0x34,0x00,0x00,0xc5,0xa0,0x00,0x00,0xc2,0x90,0x00,0x00,0x00,0x00, -0xff,0x00,0x45,0x30,0x01,0x00,0xa3,0x30,0x05,0x00,0x60,0x10,0x04,0x00,0x02,0x24, -0x04,0x10,0x88,0x00,0x25,0x10,0x47,0x00,0xff,0xff,0x47,0x30,0x04,0x00,0x02,0x24, -0xff,0xff,0x42,0x24,0xff,0xff,0x41,0x04,0xff,0xff,0x42,0x24,0xfb,0x00,0xa5,0x30, -0x00,0x00,0xc5,0xa0,0x09,0x00,0x02,0x24,0xff,0xff,0x42,0x24,0xff,0xff,0x41,0x04, -0xff,0xff,0x42,0x24,0xff,0xff,0x82,0x24,0x00,0x24,0x02,0x00,0x03,0x24,0x04,0x00, -0xe7,0xff,0x81,0x04,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0xe0,0x00, -0xe0,0xff,0xbd,0x27,0x10,0x00,0xb0,0xaf,0x25,0xb0,0x10,0x3c,0x0a,0x00,0x10,0x36, -0x18,0x00,0xbf,0xaf,0x14,0x00,0xb1,0xaf,0x00,0x00,0x02,0x92,0xff,0xff,0x91,0x30, -0x03,0x00,0x05,0x24,0xc0,0x00,0x42,0x30,0x80,0x00,0x43,0x34,0x00,0x00,0x03,0xa2, -0x04,0x00,0x63,0x34,0x00,0x00,0x03,0xa2,0xfb,0x00,0x63,0x30,0x00,0x00,0x03,0xa2, -0x08,0x00,0x63,0x34,0x00,0x00,0x03,0xa2,0x04,0x00,0x63,0x34,0x00,0x00,0x03,0xa2, -0xfb,0x00,0x63,0x30,0x00,0x00,0x03,0xa2,0xd7,0x0b,0x00,0x0c,0x06,0x00,0x04,0x24, -0x42,0x20,0x11,0x00,0xd7,0x0b,0x00,0x0c,0x06,0x00,0x05,0x24,0xfd,0x0b,0x00,0x0c, -0x10,0x00,0x04,0x24,0x00,0x00,0x03,0x92,0x18,0x00,0xbf,0x8f,0x14,0x00,0xb1,0x8f, -0xc0,0x00,0x63,0x30,0x00,0x00,0x03,0xa2,0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03, -0x20,0x00,0xbd,0x27,0xe0,0xff,0xbd,0x27,0x14,0x00,0xb1,0xaf,0xff,0xff,0xb1,0x30, -0x18,0x00,0xb2,0xaf,0x10,0x00,0xb0,0xaf,0x1c,0x00,0xbf,0xaf,0x21,0x90,0xc0,0x00, -0x0a,0x00,0x20,0x12,0xff,0xff,0x90,0x30,0x24,0x0c,0x00,0x0c,0x21,0x20,0x00,0x02, -0xfe,0xff,0x23,0x26,0x02,0x00,0x04,0x26,0x00,0x00,0x42,0xa6,0xff,0xff,0x71,0x30, -0xff,0xff,0x90,0x30,0xf8,0xff,0x20,0x16,0x02,0x00,0x52,0x26,0x1c,0x00,0xbf,0x8f, -0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03, -0x20,0x00,0xbd,0x27,0x25,0xb0,0x03,0x3c,0x0a,0x00,0x68,0x34,0x00,0x00,0x02,0x91, -0xff,0xff,0xa5,0x30,0xff,0x00,0x84,0x30,0x1f,0x00,0xa0,0x10,0xff,0x00,0x47,0x30, -0x21,0x48,0x00,0x01,0x0c,0x00,0x6c,0x34,0x0b,0x00,0x6b,0x34,0xc0,0xff,0x0a,0x24, -0x21,0x68,0x00,0x01,0x25,0x10,0xea,0x00,0xff,0x00,0x47,0x30,0x00,0x00,0x64,0xa1, -0x00,0x00,0x27,0xa1,0x00,0x00,0x22,0x91,0x00,0x00,0x00,0x00,0xff,0x00,0x47,0x30, -0xc0,0x00,0xe3,0x30,0x08,0x00,0x60,0x10,0x00,0x00,0x00,0x00,0x21,0x40,0xa0,0x01, -0x00,0x00,0x02,0x91,0x00,0x00,0x00,0x00,0xff,0x00,0x47,0x30,0xc0,0x00,0xe3,0x30, -0xfb,0xff,0x60,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x82,0x8d,0xfc,0xff,0xa3,0x24, -0x04,0x00,0x84,0x24,0xff,0xff,0x65,0x30,0x00,0x00,0xc2,0xac,0xff,0x00,0x84,0x30, -0xe8,0xff,0xa0,0x14,0x04,0x00,0xc6,0x24,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00, -0xff,0x00,0x84,0x30,0x21,0x68,0xe0,0x00,0xff,0xff,0xa5,0x30,0xc0,0x50,0x04,0x00, -0x00,0x60,0x0c,0x40,0x01,0x00,0x81,0x35,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40, -0x00,0x00,0xc2,0x90,0x01,0x00,0xc3,0x90,0x25,0xb0,0x07,0x3c,0x00,0x14,0x02,0x00, -0x25,0x28,0xa2,0x00,0x00,0x1e,0x03,0x00,0x01,0x80,0x08,0x3c,0x25,0x20,0xa3,0x00, -0x40,0x02,0xe9,0x34,0x25,0x18,0x48,0x01,0x44,0x02,0xe7,0x34,0x00,0x00,0xe4,0xac, -0x00,0x00,0x23,0xad,0x03,0x00,0xc2,0x90,0x02,0x00,0xc4,0x90,0x04,0x00,0xc3,0x90, -0x05,0x00,0xc5,0x90,0x00,0x12,0x02,0x00,0x25,0x20,0x82,0x00,0x00,0x1c,0x03,0x00, -0x01,0x00,0x4a,0x25,0x25,0x20,0x83,0x00,0x00,0x2e,0x05,0x00,0x25,0x40,0x48,0x01, -0x25,0x20,0x85,0x00,0x00,0x00,0xe4,0xac,0x01,0x00,0x4a,0x25,0x00,0x00,0x28,0xad, -0x01,0x80,0x0b,0x3c,0x21,0x40,0x00,0x00,0x21,0x10,0xa8,0x01,0x01,0x00,0x43,0x90, -0x00,0x00,0x45,0x90,0x02,0x00,0x44,0x90,0x03,0x00,0x46,0x90,0x00,0x1a,0x03,0x00, -0x25,0x28,0xa3,0x00,0x00,0x24,0x04,0x00,0x25,0x28,0xa4,0x00,0x00,0x36,0x06,0x00, -0x04,0x00,0x08,0x25,0x25,0x10,0x4b,0x01,0x25,0x20,0xa6,0x00,0x10,0x00,0x03,0x2d, -0x00,0x00,0xe4,0xac,0x01,0x00,0x4a,0x25,0x00,0x00,0x22,0xad,0xee,0xff,0x60,0x14, -0x00,0x00,0x00,0x00,0x00,0x60,0x8c,0x40,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00, -0xff,0xff,0x84,0x30,0x42,0xb0,0x08,0x3c,0x80,0x10,0x04,0x00,0x21,0x10,0x48,0x00, -0x04,0x00,0x46,0xac,0x00,0x00,0x07,0x91,0x40,0x18,0x04,0x00,0x03,0x00,0x06,0x24, -0xff,0x00,0xe7,0x30,0x04,0x30,0x66,0x00,0x01,0x00,0x02,0x24,0x04,0x10,0x62,0x00, -0x25,0x30,0xc7,0x00,0xff,0xff,0xa5,0x30,0x25,0x10,0x47,0x00,0x02,0x00,0xa0,0x14, -0xff,0x00,0xc7,0x30,0xff,0x00,0x47,0x30,0x42,0xb0,0x02,0x3c,0x00,0x00,0x47,0xa0, -0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x42,0xb0,0x02,0x3c,0x03,0x00,0x47,0x34, -0x00,0x00,0xe3,0x90,0xff,0x00,0x84,0x30,0x04,0x00,0x84,0x24,0xff,0x00,0x65,0x30, -0x01,0x00,0x02,0x24,0x04,0x30,0x82,0x00,0x07,0x18,0x85,0x00,0x25,0xb0,0x02,0x3c, -0xe8,0x03,0x42,0x34,0x01,0x00,0x63,0x30,0x21,0x20,0xc0,0x00,0x00,0x00,0x45,0xa0, -0x02,0x00,0x60,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0xe6,0xa0,0x08,0x00,0xe0,0x03, -0x24,0x10,0x85,0x00,0x00,0x60,0x03,0x40,0x01,0x00,0x61,0x34,0x01,0x00,0x21,0x38, -0x00,0x60,0x81,0x40,0x02,0x80,0x02,0x3c,0xdc,0x8c,0x42,0x24,0x04,0x00,0x45,0x8c, -0x00,0x00,0x82,0xac,0x04,0x00,0x44,0xac,0x00,0x00,0xa4,0xac,0x04,0x00,0x85,0xac, -0x00,0x60,0x83,0x40,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x14,0x00,0x83,0x90, -0x01,0x00,0x02,0x24,0x08,0x00,0x86,0xac,0x18,0x00,0x85,0xac,0x00,0x00,0x84,0xac, -0x03,0x00,0x62,0x10,0x04,0x00,0x84,0xac,0xed,0x0c,0x00,0x08,0x0c,0x00,0x80,0xac, -0x0c,0x00,0x82,0x8c,0xed,0x0c,0x00,0x08,0x10,0x00,0x82,0xac,0x00,0x60,0x03,0x40, -0x01,0x00,0x61,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x04,0x00,0x85,0x8c, -0x00,0x00,0x82,0x8c,0x00,0x00,0x00,0x00,0x00,0x00,0xa2,0xac,0x04,0x00,0x45,0xac, -0x00,0x00,0x84,0xac,0x04,0x00,0x84,0xac,0x00,0x60,0x83,0x40,0x08,0x00,0xe0,0x03, -0x00,0x00,0x00,0x00,0xd0,0xff,0xbd,0x27,0x28,0x00,0xb6,0xaf,0x24,0x00,0xb5,0xaf, -0x20,0x00,0xb4,0xaf,0x14,0x00,0xb1,0xaf,0x2c,0x00,0xbf,0xaf,0x1c,0x00,0xb3,0xaf, -0x18,0x00,0xb2,0xaf,0x10,0x00,0xb0,0xaf,0x00,0x80,0x16,0x3c,0x02,0x80,0x14,0x3c, -0x02,0x80,0x11,0x3c,0x02,0x80,0x15,0x3c,0xc4,0x7d,0x24,0x8e,0x25,0xb0,0x02,0x3c, -0x54,0x34,0xc3,0x26,0x18,0x03,0x42,0x34,0x00,0x00,0x43,0xac,0xdc,0x8c,0x90,0x8e, -0x18,0x00,0x80,0x10,0xdc,0x8c,0x82,0x26,0x15,0x00,0x02,0x12,0x00,0x00,0x00,0x00, -0x21,0x98,0x40,0x00,0x01,0x00,0x12,0x24,0x14,0x00,0x02,0x92,0x00,0x00,0x00,0x00, -0x1d,0x00,0x52,0x10,0x00,0x00,0x00,0x00,0x09,0x00,0x40,0x14,0x00,0x00,0x00,0x00, -0x0c,0x00,0x03,0x8e,0xc4,0x7d,0x22,0x8e,0x00,0x00,0x00,0x00,0x23,0x20,0x62,0x00, -0x2b,0x10,0x43,0x00,0x0e,0x00,0x40,0x10,0x00,0x00,0x00,0x00,0x0c,0x00,0x04,0xae, -0x00,0x00,0x10,0x8e,0x00,0x00,0x00,0x00,0xef,0xff,0x13,0x16,0x00,0x00,0x00,0x00, -0xc4,0x7d,0x20,0xae,0x08,0x0c,0xa4,0x26,0x21,0x28,0x00,0x00,0x21,0x30,0x00,0x00, -0x31,0x1c,0x00,0x0c,0x21,0x38,0x00,0x00,0x22,0x0d,0x00,0x08,0x00,0x00,0x00,0x00, -0x08,0x00,0x02,0x8e,0x18,0x00,0x04,0x8e,0x09,0xf8,0x40,0x00,0x00,0x00,0x00,0x00, -0x3c,0x0d,0x00,0x08,0x0c,0x00,0x02,0xae,0x0c,0x00,0x03,0x8e,0xc4,0x7d,0x22,0x8e, -0x00,0x00,0x00,0x00,0x23,0x20,0x62,0x00,0x2b,0x10,0x43,0x00,0xe7,0xff,0x40,0x14, -0x00,0x00,0x00,0x00,0x08,0x00,0x02,0x8e,0x18,0x00,0x04,0x8e,0x09,0xf8,0x40,0x00, -0x00,0x00,0x00,0x00,0x10,0x00,0x03,0x8e,0x3c,0x0d,0x00,0x08,0x0c,0x00,0x03,0xae, -0xff,0x00,0xa5,0x30,0x25,0xb0,0x02,0x3c,0x21,0x28,0xa2,0x00,0xff,0x00,0x84,0x30, -0x60,0x01,0xa4,0xa0,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0xff,0x00,0x84,0x30, -0x01,0x00,0x03,0x24,0x10,0x00,0x02,0x3c,0x04,0x18,0x83,0x00,0xf0,0x70,0x42,0x34, -0x15,0x00,0x84,0x2c,0x06,0x00,0x80,0x10,0x24,0x28,0x62,0x00,0x0f,0x00,0x63,0x30, -0x04,0x00,0xa0,0x14,0x01,0x00,0x02,0x24,0x02,0x00,0x60,0x14,0x02,0x00,0x02,0x24, -0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0xff,0x00,0xa5,0x30, -0x04,0x00,0xa2,0x2c,0x14,0x00,0x40,0x10,0xff,0x00,0x84,0x30,0x02,0x80,0x03,0x3c, -0x8e,0x7d,0x62,0x90,0x00,0x00,0x00,0x00,0xef,0xff,0x42,0x24,0xff,0x00,0x42,0x30, -0x02,0x00,0x42,0x2c,0x0e,0x00,0x40,0x10,0x02,0x00,0x03,0x24,0x24,0x00,0x83,0x10, -0x0f,0x10,0x02,0x3c,0x03,0x00,0x82,0x28,0x14,0x00,0x40,0x10,0x03,0x00,0x02,0x24, -0x01,0x00,0x02,0x24,0x2f,0x00,0x82,0x10,0x00,0x00,0x00,0x00,0xff,0x1f,0x02,0x3c, -0x08,0x00,0xe0,0x03,0xff,0xff,0x42,0x34,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00, -0x35,0x00,0x83,0x10,0x0f,0x1f,0x02,0x3c,0x03,0x00,0x82,0x28,0x16,0x00,0x40,0x10, -0x03,0x00,0x02,0x24,0x01,0x00,0x02,0x24,0xf4,0xff,0x82,0x14,0x00,0x00,0x00,0x00, -0x0f,0x1f,0x02,0x3c,0x08,0x00,0xe0,0x03,0x00,0x80,0x42,0x34,0xf0,0xff,0x82,0x14, -0xff,0x1f,0x02,0x3c,0x01,0x00,0x02,0x24,0x29,0x00,0xa2,0x10,0x0f,0x10,0x02,0x3c, -0x02,0x00,0xa2,0x28,0x1f,0x00,0x40,0x14,0x00,0x00,0x00,0x00,0x28,0x00,0xa3,0x10, -0x00,0x00,0x00,0x00,0xe5,0xff,0xa4,0x14,0x00,0x00,0x00,0x00,0x0f,0x10,0x02,0x3c, -0x08,0x00,0xe0,0x03,0x00,0xf0,0x42,0x34,0xe1,0xff,0x82,0x14,0xff,0x1f,0x02,0x3c, -0x01,0x00,0x02,0x24,0x1c,0x00,0xa2,0x10,0x0f,0x00,0x02,0x3c,0x02,0x00,0xa2,0x28, -0x0b,0x00,0x40,0x14,0x00,0x00,0x00,0x00,0x1c,0x00,0xa3,0x10,0x00,0x00,0x00,0x00, -0xd6,0xff,0xa4,0x14,0x00,0x00,0x00,0x00,0x0f,0x00,0x02,0x3c,0x08,0x00,0xe0,0x03, -0x00,0xf0,0x42,0x34,0x0f,0x10,0x02,0x3c,0x08,0x00,0xe0,0x03,0x00,0x80,0x42,0x34, -0xce,0xff,0xa0,0x14,0x00,0x00,0x00,0x00,0x0f,0x00,0x02,0x3c,0x08,0x00,0xe0,0x03, -0x15,0xf0,0x42,0x34,0xc9,0xff,0xa0,0x14,0x00,0x00,0x00,0x00,0x0f,0x10,0x02,0x3c, -0x08,0x00,0xe0,0x03,0x15,0xf0,0x42,0x34,0x08,0x00,0xe0,0x03,0x00,0xf0,0x42,0x34, -0x08,0x00,0xe0,0x03,0x10,0xf0,0x42,0x34,0x08,0x00,0xe0,0x03,0x10,0xf0,0x42,0x34, -0x0f,0x10,0x02,0x3c,0x08,0x00,0xe0,0x03,0x05,0xf0,0x42,0x34,0x0f,0x00,0x02,0x3c, -0x08,0x00,0xe0,0x03,0x05,0xf0,0x42,0x34,0xc0,0x40,0x04,0x00,0x21,0x18,0x04,0x01, -0x80,0x18,0x03,0x00,0x21,0x18,0x64,0x00,0x02,0x80,0x02,0x3c,0x80,0x18,0x03,0x00, -0x68,0x15,0x42,0x24,0x21,0x18,0x62,0x00,0x74,0x51,0x66,0x8c,0x21,0x38,0x60,0x00, -0x7a,0x51,0x60,0xa0,0x7b,0x51,0x60,0xa0,0x1c,0x00,0x05,0x24,0xdf,0x0d,0x00,0x08, -0x01,0x00,0x03,0x24,0x08,0x00,0xa0,0x04,0x21,0x10,0x04,0x01,0x04,0x10,0xa3,0x00, -0x24,0x10,0xc2,0x00,0xfb,0xff,0x40,0x10,0xff,0xff,0xa5,0x24,0x01,0x00,0xa5,0x24, -0x7a,0x51,0xe5,0xa0,0x21,0x10,0x04,0x01,0x80,0x10,0x02,0x00,0x21,0x10,0x44,0x00, -0x02,0x80,0x03,0x3c,0x80,0x10,0x02,0x00,0x68,0x15,0x63,0x24,0x21,0x18,0x43,0x00, -0x74,0x51,0x66,0x8c,0x21,0x28,0x00,0x00,0xf3,0x0d,0x00,0x08,0x01,0x00,0x07,0x24, -0x1d,0x00,0xa2,0x28,0x08,0x00,0x40,0x10,0x00,0x00,0x00,0x00,0x04,0x10,0xa7,0x00, -0x24,0x10,0xc2,0x00,0xfa,0xff,0x40,0x10,0x01,0x00,0xa5,0x24,0xff,0xff,0xa5,0x24, -0x08,0x00,0xe0,0x03,0x7b,0x51,0x65,0xa0,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00, -0xc8,0xff,0xbd,0x27,0x28,0x00,0xb6,0xaf,0x02,0x80,0x16,0x3c,0x30,0x00,0xbe,0xaf, -0x2c,0x00,0xb7,0xaf,0x24,0x00,0xb5,0xaf,0x20,0x00,0xb4,0xaf,0x18,0x00,0xb2,0xaf, -0x14,0x00,0xb1,0xaf,0x01,0x00,0x15,0x24,0x21,0x88,0x00,0x00,0x68,0x15,0xde,0x26, -0x21,0xa0,0x00,0x00,0x21,0x90,0x00,0x00,0x25,0xb0,0x17,0x3c,0x34,0x00,0xbf,0xaf, -0x1c,0x00,0xb3,0xaf,0x14,0x0e,0x00,0x08,0x10,0x00,0xb0,0xaf,0x01,0x00,0x31,0x26, -0x20,0x00,0x22,0x2e,0x94,0x00,0x52,0x26,0x2e,0x00,0x40,0x10,0x94,0x00,0x94,0x26, -0x68,0x15,0xc2,0x26,0x21,0x30,0x42,0x02,0x78,0x51,0xc5,0x8c,0x00,0x00,0x00,0x00, -0x02,0x13,0x05,0x00,0x01,0x00,0x42,0x30,0xf4,0xff,0x55,0x14,0x42,0x1a,0x05,0x00, -0x68,0x51,0xc2,0x8c,0x07,0x00,0x64,0x30,0x02,0x11,0x02,0x00,0x7f,0x00,0x43,0x30, -0x2d,0x00,0x95,0x10,0x07,0x00,0xb3,0x30,0x02,0x00,0x82,0x28,0x3a,0x00,0x40,0x14, -0x02,0x00,0x02,0x24,0x30,0x00,0x82,0x10,0x03,0x00,0x02,0x24,0x3c,0x00,0x82,0x10, -0x1a,0x00,0x62,0x2c,0x21,0x80,0x9e,0x02,0x78,0x51,0x02,0x8e,0x04,0x00,0x63,0x2e, -0x42,0x12,0x02,0x00,0x0a,0x00,0x60,0x10,0x07,0x00,0x44,0x30,0x73,0x0d,0x00,0x0c, -0x21,0x28,0x60,0x02,0x80,0x20,0x13,0x00,0x70,0x51,0x02,0xae,0x21,0x20,0x97,0x00, -0x84,0x01,0x83,0x8c,0x00,0x00,0x00,0x00,0x24,0x18,0x62,0x00,0x74,0x51,0x03,0xae, -0xce,0x0d,0x00,0x0c,0x21,0x20,0x20,0x02,0x21,0x10,0x37,0x02,0x01,0x00,0x31,0x26, -0x60,0x01,0x43,0x90,0x20,0x00,0x22,0x2e,0x94,0x00,0x52,0x26,0xd4,0xff,0x40,0x14, -0x94,0x00,0x94,0x26,0x34,0x00,0xbf,0x8f,0x30,0x00,0xbe,0x8f,0x2c,0x00,0xb7,0x8f, -0x28,0x00,0xb6,0x8f,0x24,0x00,0xb5,0x8f,0x20,0x00,0xb4,0x8f,0x1c,0x00,0xb3,0x8f, -0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x21,0x10,0x00,0x00, -0x08,0x00,0xe0,0x03,0x38,0x00,0xbd,0x27,0x32,0x00,0x62,0x2c,0xda,0xff,0x40,0x10, -0x21,0x80,0x9e,0x02,0xff,0xf1,0x03,0x24,0x24,0x10,0xa3,0x00,0x00,0x04,0x42,0x34, -0x29,0x0e,0x00,0x08,0x78,0x51,0xc2,0xac,0x38,0x00,0x62,0x2c,0x12,0x00,0x40,0x14, -0x14,0x00,0x62,0x2c,0xff,0xf1,0x03,0x24,0x24,0x10,0xa3,0x00,0x00,0x02,0x42,0x34, -0x29,0x0e,0x00,0x08,0x78,0x51,0xc2,0xac,0xcb,0xff,0x80,0x14,0x21,0x80,0x9e,0x02, -0xff,0xf1,0x03,0x24,0x24,0x10,0xa3,0x00,0x2a,0x0e,0x00,0x08,0x78,0x51,0xc2,0xac, -0xc5,0xff,0x40,0x14,0x21,0x80,0x9e,0x02,0xff,0xf1,0x03,0x24,0x24,0x10,0xa3,0x00, -0x54,0x0e,0x00,0x08,0x00,0x04,0x42,0x34,0xbf,0xff,0x40,0x10,0x21,0x80,0x9e,0x02, -0xff,0xf1,0x03,0x24,0x24,0x10,0xa3,0x00,0x00,0x06,0x42,0x34,0x2a,0x0e,0x00,0x08, -0x78,0x51,0xc2,0xac,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0xd8,0xff,0xbd,0x27, -0x10,0x00,0xb0,0xaf,0xc0,0x80,0x04,0x00,0x21,0x80,0x04,0x02,0x80,0x80,0x10,0x00, -0x21,0x80,0x04,0x02,0x02,0x80,0x02,0x3c,0x68,0x15,0x42,0x24,0x80,0x80,0x10,0x00, -0x20,0x00,0xbf,0xaf,0x1c,0x00,0xb3,0xaf,0x18,0x00,0xb2,0xaf,0x21,0x80,0x02,0x02, -0x14,0x00,0xb1,0xaf,0x78,0x51,0x03,0x8e,0x25,0xb0,0x02,0x3c,0x80,0x01,0x53,0x34, -0x07,0x00,0x63,0x30,0x80,0x18,0x03,0x00,0x21,0x18,0x62,0x00,0x00,0x00,0x71,0x92, -0x70,0x51,0x05,0x8e,0x84,0x01,0x62,0x8c,0x21,0x90,0x80,0x00,0xff,0x00,0x31,0x32, -0x24,0x10,0x45,0x00,0xce,0x0d,0x00,0x0c,0x74,0x51,0x02,0xae,0x7a,0x51,0x04,0x92, -0x5c,0x0d,0x00,0x0c,0xff,0x00,0x45,0x32,0x7a,0x51,0x04,0x92,0x63,0x0d,0x00,0x0c, -0x00,0x00,0x00,0x00,0x01,0x00,0x42,0x38,0x04,0x00,0x03,0x24,0x0a,0x88,0x62,0x00, -0x00,0x00,0x71,0xa2,0x20,0x00,0xbf,0x8f,0x1c,0x00,0xb3,0x8f,0x18,0x00,0xb2,0x8f, -0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x28,0x00,0xbd,0x27, -0xff,0xff,0x84,0x30,0x00,0x02,0x82,0x30,0x07,0x00,0x03,0x24,0x0d,0x00,0x40,0x14, -0x0b,0x00,0x84,0x30,0x0c,0x00,0x82,0x2c,0x0a,0x00,0x40,0x10,0x00,0x00,0x00,0x00, -0x02,0x80,0x03,0x3c,0x80,0x10,0x04,0x00,0xf0,0x91,0x63,0x24,0x21,0x10,0x43,0x00, -0x00,0x00,0x44,0x8c,0x00,0x00,0x00,0x00,0x08,0x00,0x80,0x00,0x00,0x00,0x00,0x00, -0x07,0x00,0x03,0x24,0x08,0x00,0xe0,0x03,0x21,0x10,0x60,0x00,0x06,0x00,0x03,0x24, -0x08,0x00,0xe0,0x03,0x21,0x10,0x60,0x00,0x05,0x00,0x03,0x24,0x08,0x00,0xe0,0x03, -0x21,0x10,0x60,0x00,0x04,0x00,0x03,0x24,0x08,0x00,0xe0,0x03,0x21,0x10,0x60,0x00, -0x03,0x00,0x03,0x24,0x08,0x00,0xe0,0x03,0x21,0x10,0x60,0x00,0x02,0x00,0x03,0x24, -0x08,0x00,0xe0,0x03,0x21,0x10,0x60,0x00,0x01,0x00,0x03,0x24,0x08,0x00,0xe0,0x03, -0x21,0x10,0x60,0x00,0x21,0x18,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x60,0x00, -0xa0,0xff,0xbd,0x27,0x02,0x80,0x02,0x3c,0x58,0x00,0xbe,0xaf,0x54,0x00,0xb7,0xaf, -0x50,0x00,0xb6,0xaf,0x4c,0x00,0xb5,0xaf,0x48,0x00,0xb4,0xaf,0x40,0x00,0xb2,0xaf, -0x3c,0x00,0xb1,0xaf,0x5c,0x00,0xbf,0xaf,0x44,0x00,0xb3,0xaf,0x38,0x00,0xb0,0xaf, -0x20,0x92,0x42,0x24,0x00,0x00,0x53,0x8c,0x08,0x00,0x03,0x24,0x02,0x80,0x0b,0x3c, -0x21,0x90,0x00,0x00,0x21,0xa0,0x00,0x00,0x21,0xb8,0x00,0x00,0x21,0xf0,0x00,0x00, -0x21,0xa8,0x00,0x00,0x21,0xb0,0x00,0x00,0x21,0x88,0x60,0x02,0x10,0x00,0xa3,0xaf, -0x14,0x00,0xa0,0xaf,0x18,0x00,0xa0,0xaf,0x1c,0x00,0xa0,0xaf,0x20,0x00,0xa0,0xaf, -0x24,0x00,0xa0,0xaf,0x28,0x00,0xa0,0xaf,0x7a,0x0f,0x00,0x08,0x2c,0x00,0xa0,0xaf, -0x44,0x51,0x22,0xae,0x60,0x51,0x24,0x8e,0x5c,0x51,0x27,0x8e,0x48,0x51,0x28,0x8e, -0x4c,0x51,0x25,0x8e,0x54,0x51,0x26,0x8e,0x58,0x51,0x23,0x8e,0x21,0x38,0xe4,0x00, -0x02,0x80,0x04,0x3c,0x68,0x15,0x84,0x24,0x21,0x10,0x04,0x02,0x21,0x40,0x05,0x01, -0x21,0x30,0xc3,0x00,0xca,0x44,0x42,0x90,0x44,0x51,0x2a,0x8e,0x0c,0x00,0xe0,0x10, -0x21,0x48,0x00,0x00,0x2b,0x48,0x47,0x00,0x0b,0x00,0x20,0x15,0x02,0x80,0x02,0x3c, -0x07,0x00,0x02,0x2e,0x59,0x01,0x40,0x14,0xc0,0x10,0x07,0x00,0x0c,0x00,0x02,0x24, -0x55,0x01,0x02,0x12,0x0d,0x00,0x02,0x24,0x54,0x01,0x02,0x12,0xc0,0x10,0x07,0x00, -0x92,0x00,0x20,0x11,0x02,0x80,0x02,0x3c,0x68,0x15,0x42,0x24,0x80,0x18,0x10,0x00, -0x21,0x18,0x62,0x00,0x21,0x20,0x30,0x02,0xb6,0x51,0x85,0x90,0xec,0x44,0x62,0x8c, -0x00,0x00,0x00,0x00,0x04,0x10,0xa2,0x00,0x2b,0x10,0x4a,0x00,0x87,0x00,0x40,0x10, -0x00,0x00,0x00,0x00,0xd4,0x51,0x22,0x8e,0x01,0x00,0x07,0x24,0x04,0x18,0x07,0x02, -0x24,0x10,0x43,0x00,0xf0,0x00,0x40,0x10,0x1c,0x00,0x02,0x2e,0x21,0x28,0x30,0x02, -0x7c,0x51,0xa6,0x90,0xb6,0x51,0xa2,0x90,0x0a,0x00,0x04,0x24,0xff,0x00,0xc3,0x30, -0x04,0x20,0x44,0x00,0x2a,0x18,0x64,0x00,0xe7,0x00,0x60,0x10,0x1c,0x00,0x02,0x2e, -0x01,0x00,0xc2,0x24,0xff,0x00,0x43,0x30,0x56,0x01,0x64,0x10,0x7c,0x51,0xa2,0xa0, -0x68,0x15,0x65,0x25,0x80,0x10,0x10,0x00,0x21,0x10,0x45,0x00,0x60,0x45,0x44,0x8c, -0xec,0x44,0x43,0x8c,0x21,0x30,0xc5,0x02,0x40,0x10,0x04,0x00,0x21,0x10,0x44,0x00, -0x21,0x18,0x62,0x00,0x82,0x50,0x03,0x00,0x44,0x51,0xca,0xac,0x8c,0x65,0xa3,0x8c, -0xff,0xff,0x02,0x34,0x07,0x00,0x62,0x10,0x21,0x20,0x00,0x02,0x21,0x20,0x00,0x02, -0xff,0x00,0x45,0x32,0x5c,0x0d,0x00,0x0c,0x30,0x00,0xab,0xaf,0x30,0x00,0xab,0x8f, -0x21,0x20,0x00,0x02,0x63,0x0d,0x00,0x0c,0x30,0x00,0xab,0xaf,0x10,0x00,0xa4,0x8f, -0x01,0x00,0x42,0x38,0x04,0x00,0x03,0x24,0x0a,0x20,0x62,0x00,0x10,0x00,0xa4,0xaf, -0x30,0x00,0xab,0x8f,0x11,0x00,0x40,0x16,0x68,0x15,0x62,0x25,0x58,0x51,0x47,0x8c, -0x54,0x51,0x43,0x8c,0x4c,0x51,0x44,0x94,0x48,0x51,0x45,0x94,0x50,0x51,0x46,0x94, -0x21,0x18,0x67,0x00,0x00,0x24,0x04,0x00,0x25,0xb0,0x02,0x3c,0x00,0x1c,0x03,0x00, -0x21,0x28,0xa4,0x00,0x21,0x30,0xc3,0x00,0x6c,0x0c,0x44,0x34,0x68,0x0c,0x42,0x34, -0x00,0x00,0x45,0xac,0x00,0x00,0x86,0xac,0x68,0x15,0x62,0x25,0x21,0x10,0x82,0x02, -0x58,0x51,0x40,0xac,0x5c,0x51,0x40,0xac,0x60,0x51,0x40,0xac,0x48,0x51,0x40,0xac, -0x4c,0x51,0x40,0xac,0x50,0x51,0x40,0xac,0x54,0x51,0x40,0xac,0x2c,0x00,0xa2,0x8f, -0x28,0x00,0xa4,0x8f,0x01,0x00,0x52,0x26,0x94,0x00,0x42,0x24,0x2c,0x00,0xa2,0xaf, -0x24,0x00,0xa2,0x8f,0x94,0x00,0x84,0x24,0x28,0x00,0xa4,0xaf,0x94,0x00,0x42,0x24, -0x20,0x00,0xa4,0x8f,0x24,0x00,0xa2,0xaf,0x1c,0x00,0xa2,0x8f,0x94,0x00,0x84,0x24, -0x20,0x00,0xa4,0xaf,0x94,0x00,0x42,0x24,0x18,0x00,0xa4,0x8f,0x1c,0x00,0xa2,0xaf, -0x14,0x00,0xa2,0x8f,0x94,0x00,0x84,0x24,0x20,0x00,0x43,0x2a,0x94,0x00,0x42,0x24, -0x94,0x00,0x31,0x26,0x94,0x00,0xd6,0x26,0x94,0x00,0xb5,0x26,0x18,0x00,0xa4,0xaf, -0x14,0x00,0xa2,0xaf,0x94,0x00,0xde,0x27,0x94,0x00,0x73,0x26,0x94,0x00,0xf7,0x26, -0xe5,0x00,0x60,0x10,0x94,0x00,0x94,0x26,0x78,0x51,0x22,0x8e,0x00,0x00,0x00,0x00, -0x02,0x13,0x02,0x00,0x01,0x00,0x42,0x30,0xd3,0xff,0x40,0x10,0x25,0xb0,0x02,0x3c, -0x21,0x10,0x42,0x02,0x60,0x01,0x44,0x90,0x60,0x51,0x23,0x8e,0x5c,0x51,0x26,0x8e, -0xff,0x00,0x90,0x30,0x02,0x80,0x04,0x3c,0x68,0x15,0x84,0x24,0x21,0x10,0x04,0x02, -0x73,0x44,0x44,0x90,0x56,0x44,0x45,0x90,0x44,0x51,0x27,0x8e,0x18,0x00,0x64,0x00, -0x12,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0xc5,0x00, -0x12,0x30,0x00,0x00,0x21,0x30,0xc3,0x00,0x2b,0x10,0xe6,0x00,0x54,0xff,0x40,0x10, -0x23,0x10,0xe6,0x00,0xe9,0x0e,0x00,0x08,0x44,0x51,0x20,0xae,0x62,0x00,0xe0,0x10, -0x00,0x00,0x00,0x00,0x63,0x00,0x20,0x15,0x68,0x15,0x62,0x25,0x40,0x10,0x07,0x00, -0x21,0x10,0x47,0x00,0x82,0x10,0x02,0x00,0x2b,0x10,0x46,0x00,0x99,0xff,0x40,0x10, -0x21,0x20,0x00,0x02,0x68,0x15,0x68,0x25,0x21,0x20,0xa8,0x02,0x21,0x30,0x90,0x00, -0xd4,0x51,0x83,0x8c,0x01,0x00,0x05,0x24,0x04,0x10,0x05,0x02,0x99,0x51,0xc7,0x90, -0x27,0x10,0x02,0x00,0x24,0x18,0x62,0x00,0xd4,0x51,0x83,0xac,0x09,0x00,0xe5,0x10, -0x7c,0x51,0xc0,0xa0,0x18,0x00,0xa2,0x8f,0x21,0x38,0x00,0x00,0x21,0x20,0x48,0x00, -0x21,0x18,0x87,0x00,0x01,0x00,0xe7,0x24,0x1d,0x00,0xe2,0x28,0xfc,0xff,0x40,0x14, -0xb6,0x51,0x60,0xa0,0x14,0x00,0xa4,0x8f,0x68,0x15,0x63,0x25,0x21,0x50,0x60,0x00, -0x21,0x10,0x83,0x00,0x21,0x10,0x50,0x00,0x99,0x51,0x40,0xa0,0x02,0x80,0x03,0x3c, -0x02,0x80,0x02,0x3c,0x4c,0x91,0x49,0x24,0xd8,0x90,0x68,0x24,0x21,0x38,0x00,0x00, -0x80,0x18,0x07,0x00,0x21,0x10,0x69,0x00,0x21,0x20,0x68,0x00,0x00,0x00,0x46,0x8c, -0x00,0x00,0x85,0x8c,0x01,0x00,0xe7,0x24,0x21,0x18,0x6a,0x00,0x1d,0x00,0xe2,0x28, -0xec,0x44,0x65,0xac,0xf6,0xff,0x40,0x14,0x60,0x45,0x66,0xac,0x14,0x00,0x00,0x12, -0x68,0x15,0x63,0x25,0x7b,0x51,0x62,0x92,0xff,0xff,0x07,0x26,0x2a,0x10,0xe2,0x00, -0x0e,0x00,0x40,0x14,0x02,0x80,0x0b,0x3c,0x68,0x15,0x62,0x25,0x21,0x10,0xc2,0x03, -0x7b,0x51,0x45,0x90,0x74,0x51,0x44,0x8c,0x01,0x00,0x06,0x24,0x04,0x18,0xe6,0x00, -0x24,0x10,0x83,0x00,0xb3,0x00,0x43,0x10,0x00,0x00,0x00,0x00,0xff,0xff,0xe7,0x24, -0x2a,0x10,0xe5,0x00,0xfa,0xff,0x40,0x10,0x04,0x18,0xe6,0x00,0x68,0x15,0x63,0x25, -0x80,0x10,0x10,0x00,0x21,0x10,0x43,0x00,0x60,0x45,0x45,0x8c,0xec,0x44,0x44,0x8c, -0x02,0x80,0x03,0x3c,0x40,0x10,0x05,0x00,0x8e,0x7d,0x66,0x90,0x21,0x10,0x45,0x00, -0x21,0x20,0x82,0x00,0x22,0x00,0x02,0x24,0x98,0x00,0xc2,0x10,0x82,0x50,0x04,0x00, -0xd4,0x51,0x63,0x8e,0x01,0x00,0x02,0x24,0x04,0x10,0x02,0x02,0x25,0x18,0x62,0x00, -0xd4,0x51,0x63,0xae,0x68,0x15,0x63,0x25,0x21,0x10,0xe3,0x02,0x44,0x51,0x4a,0xac, -0x8c,0x65,0x64,0x8c,0xff,0xff,0x02,0x34,0x3c,0xff,0x82,0x14,0x21,0x20,0x00,0x02, -0x39,0x0f,0x00,0x08,0x00,0x00,0x00,0x00,0x3e,0xff,0x20,0x11,0x21,0x20,0x00,0x02, -0x68,0x15,0x62,0x25,0x80,0x18,0x10,0x00,0x21,0x18,0x62,0x00,0x60,0x45,0x64,0x8c, -0x00,0x00,0x00,0x00,0x2b,0x20,0x44,0x01,0x36,0xff,0x80,0x10,0x21,0x20,0x00,0x02, -0xa2,0x0f,0x00,0x08,0x68,0x15,0x68,0x25,0x1e,0xff,0x40,0x10,0x68,0x15,0x65,0x25, -0x21,0x20,0x30,0x02,0x99,0x51,0x83,0x90,0x01,0x00,0x02,0x24,0x63,0x00,0x62,0x10, -0x02,0x80,0x02,0x3c,0x2c,0x00,0xa3,0x8f,0x68,0x15,0x42,0x24,0x21,0x38,0x00,0x00, -0x21,0x20,0x62,0x00,0x21,0x18,0x87,0x00,0x01,0x00,0xe7,0x24,0x1d,0x00,0xe2,0x28, -0xfc,0xff,0x40,0x14,0xb6,0x51,0x60,0xa0,0x28,0x00,0xa3,0x8f,0x02,0x80,0x0b,0x3c, -0x68,0x15,0x65,0x25,0x21,0x30,0x65,0x00,0xd4,0x51,0xc2,0x8c,0x01,0x00,0x03,0x24, -0x04,0x18,0x03,0x02,0x27,0x18,0x03,0x00,0x21,0x20,0xd0,0x00,0x24,0x10,0x43,0x00, -0x99,0x51,0x80,0xa0,0xd4,0x51,0xc2,0xac,0x12,0x00,0x00,0x16,0x7c,0x51,0x80,0xa0, -0x7a,0x51,0xc2,0x90,0x00,0x00,0x00,0x00,0x0e,0x00,0x40,0x10,0x01,0x00,0x07,0x24, -0x24,0x00,0xa4,0x8f,0x01,0x00,0x06,0x24,0x21,0x10,0x85,0x00,0x7a,0x51,0x44,0x90, -0x74,0x51,0x45,0x8c,0x04,0x18,0xe6,0x00,0x24,0x10,0xa3,0x00,0x5b,0x00,0x43,0x10, -0x00,0x00,0x00,0x00,0x01,0x00,0xe7,0x24,0x2a,0x10,0x87,0x00,0xfa,0xff,0x40,0x10, -0x04,0x18,0xe6,0x00,0x20,0x00,0xa2,0x8f,0x02,0x80,0x0b,0x3c,0x68,0x15,0x64,0x25, -0x21,0x18,0x44,0x00,0x7a,0x51,0x62,0x90,0x01,0x00,0x07,0x26,0x2a,0x10,0x47,0x00, -0x0e,0x00,0x40,0x14,0x01,0x00,0x06,0x24,0x1c,0x00,0xa3,0x8f,0x00,0x00,0x00,0x00, -0x21,0x10,0x64,0x00,0x7a,0x51,0x45,0x90,0x74,0x51,0x44,0x8c,0x04,0x18,0xe6,0x00, -0x24,0x10,0x83,0x00,0x42,0x00,0x43,0x10,0x00,0x00,0x00,0x00,0x01,0x00,0xe7,0x24, -0x2a,0x10,0xa7,0x00,0xfa,0xff,0x40,0x10,0x04,0x18,0xe6,0x00,0x02,0x80,0x02,0x3c, -0x8e,0x7d,0x44,0x90,0x22,0x00,0x03,0x24,0xd6,0xfe,0x83,0x14,0x68,0x15,0x65,0x25, -0xee,0xff,0x02,0x26,0xff,0x00,0x42,0x30,0x02,0x00,0x42,0x2c,0x18,0x00,0x03,0x24, -0x25,0x0f,0x00,0x08,0x0b,0x80,0x62,0x00,0xc0,0x10,0x07,0x00,0x23,0x10,0x47,0x00, -0xc2,0x10,0x02,0x00,0x2b,0x10,0x48,0x00,0xb6,0xfe,0x40,0x14,0x00,0x00,0x00,0x00, -0x04,0x0f,0x00,0x08,0x00,0x00,0x00,0x00,0x10,0x00,0xa3,0x8f,0x5c,0x00,0xbf,0x8f, -0x58,0x00,0xbe,0x8f,0x54,0x00,0xb7,0x8f,0x50,0x00,0xb6,0x8f,0x4c,0x00,0xb5,0x8f, -0x48,0x00,0xb4,0x8f,0x44,0x00,0xb3,0x8f,0x40,0x00,0xb2,0x8f,0x3c,0x00,0xb1,0x8f, -0x38,0x00,0xb0,0x8f,0x25,0xb0,0x02,0x3c,0x80,0x01,0x42,0x34,0x60,0x00,0xbd,0x27, -0x00,0x00,0x43,0xa0,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x18,0x00,0x02,0x2e, -0x0a,0x00,0x40,0x14,0x05,0x00,0x02,0x2e,0xb6,0x51,0x83,0x90,0x00,0x00,0x00,0x00, -0x05,0x00,0x62,0x2c,0xa0,0xff,0x40,0x10,0x01,0x00,0x62,0x24,0x16,0x10,0x00,0x08, -0xb6,0x51,0x82,0xa0,0x24,0x0f,0x00,0x08,0x99,0x51,0xa7,0xa0,0x04,0x00,0x40,0x10, -0x00,0x00,0x00,0x00,0xb6,0x51,0x83,0x90,0x75,0x10,0x00,0x08,0x03,0x00,0x62,0x2c, -0xb6,0x51,0x83,0x90,0x75,0x10,0x00,0x08,0x04,0x00,0x62,0x2c,0x13,0x00,0x02,0x24, -0x67,0xff,0x02,0x16,0x68,0x15,0x63,0x25,0xf3,0x0f,0x00,0x08,0x21,0x10,0xe3,0x02, -0xff,0x00,0xf0,0x30,0x4c,0x10,0x00,0x08,0x02,0x80,0x02,0x3c,0x35,0x10,0x00,0x08, -0xff,0x00,0xf0,0x30,0xdf,0x0f,0x00,0x08,0xff,0x00,0xf0,0x30,0xd8,0xff,0xbd,0x27, -0x02,0x80,0x02,0x3c,0x14,0x00,0xb1,0xaf,0x24,0x00,0xbf,0xaf,0x20,0x00,0xb4,0xaf, -0x1c,0x00,0xb3,0xaf,0x18,0x00,0xb2,0xaf,0x10,0x00,0xb0,0xaf,0x68,0x15,0x45,0x24, -0x05,0x65,0xa4,0x90,0x00,0x65,0xa3,0x8c,0xfc,0x64,0xa2,0x8c,0x21,0x88,0x64,0x00, -0x2b,0x10,0x22,0x02,0x60,0x00,0x40,0x10,0x21,0x80,0xa0,0x00,0x02,0x80,0x14,0x3c, -0x21,0x98,0xa0,0x00,0xa8,0x10,0x00,0x08,0x21,0x90,0xa0,0x00,0xfc,0x64,0x42,0x8e, -0x10,0x00,0x31,0x26,0x2b,0x10,0x22,0x02,0x57,0x00,0x40,0x10,0x21,0x80,0x40,0x02, -0x05,0x65,0x02,0x92,0xff,0xff,0x23,0x32,0x02,0x80,0x05,0x3c,0x10,0x00,0x42,0x24, -0x25,0x28,0x65,0x00,0x2c,0x79,0x84,0x26,0x10,0x00,0x06,0x24,0x9f,0x45,0x00,0x0c, -0x05,0x65,0x02,0xa2,0xc8,0x63,0x06,0x8e,0x00,0x00,0x00,0x00,0x42,0x24,0x06,0x00, -0x1f,0x00,0x84,0x30,0xc0,0x10,0x04,0x00,0x21,0x10,0x44,0x00,0x80,0x10,0x02,0x00, -0x21,0x10,0x44,0x00,0x80,0x10,0x02,0x00,0x21,0x38,0x50,0x00,0x78,0x51,0xe3,0x8c, -0x00,0x00,0x00,0x00,0x02,0x1b,0x03,0x00,0x01,0x00,0x63,0x30,0xe3,0xff,0x60,0x10, -0x25,0xb0,0x02,0x3c,0xc4,0x63,0x05,0x8e,0x21,0x10,0x82,0x00,0x60,0x01,0x44,0x90, -0x82,0x1d,0x05,0x00,0x3f,0x00,0x63,0x30,0x04,0x00,0x0a,0x24,0x05,0x00,0x62,0x28, -0x21,0x40,0x40,0x01,0x0b,0x40,0x62,0x00,0x07,0x00,0xa0,0x04,0xff,0x00,0x89,0x30, -0x64,0x51,0xe2,0x8c,0x04,0x00,0x08,0x24,0x01,0x00,0x42,0x24,0x64,0x51,0xe2,0xac, -0xc8,0x63,0x66,0x8e,0x00,0x00,0x00,0x00,0x02,0x13,0x06,0x00,0x1f,0x00,0x42,0x30, -0x08,0x00,0x42,0x28,0xcd,0xff,0x40,0x10,0x00,0x00,0x00,0x00,0xc4,0x63,0x62,0x8e, -0x00,0x00,0x00,0x00,0x3f,0x00,0x42,0x30,0xc8,0xff,0x49,0x14,0x00,0x00,0x00,0x00, -0x29,0x00,0x00,0x11,0x01,0x00,0x02,0x24,0x2e,0x00,0x02,0x11,0x02,0x00,0x02,0x24, -0x33,0x00,0x02,0x11,0x03,0x00,0x02,0x24,0x38,0x00,0x02,0x11,0x00,0x00,0x00,0x00, -0x3b,0x00,0x0a,0x11,0x00,0x00,0x00,0x00,0x68,0x51,0xe2,0x8c,0x21,0x18,0x33,0x01, -0x90,0x44,0x64,0x90,0x02,0x11,0x02,0x00,0x2b,0x10,0x44,0x00,0x3e,0x00,0x40,0x14, -0x00,0x00,0x00,0x00,0x5c,0x51,0xe3,0x8c,0x80,0x10,0x09,0x00,0x21,0x10,0x49,0x00, -0x01,0x00,0x63,0x24,0x21,0x10,0x53,0x00,0x5c,0x51,0xe3,0xac,0x21,0x10,0x48,0x00, -0x34,0x43,0x44,0x90,0x44,0x51,0xe3,0x8c,0x00,0x00,0x00,0x00,0x21,0x18,0x64,0x00, -0x44,0x51,0xe3,0xac,0xfc,0x64,0x42,0x8e,0x10,0x00,0x31,0x26,0x2b,0x10,0x22,0x02, -0xab,0xff,0x40,0x14,0x21,0x80,0x40,0x02,0x24,0x00,0xbf,0x8f,0x20,0x00,0xb4,0x8f, -0x1c,0x00,0xb3,0x8f,0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f, -0x08,0x00,0xe0,0x03,0x28,0x00,0xbd,0x27,0x48,0x51,0xe2,0x8c,0x00,0x00,0x00,0x00, -0x01,0x00,0x42,0x24,0x48,0x51,0xe2,0xac,0x01,0x00,0x02,0x24,0xd4,0xff,0x02,0x15, -0x02,0x00,0x02,0x24,0x4c,0x51,0xe2,0x8c,0x00,0x00,0x00,0x00,0x01,0x00,0x42,0x24, -0x4c,0x51,0xe2,0xac,0x02,0x00,0x02,0x24,0xcf,0xff,0x02,0x15,0x03,0x00,0x02,0x24, -0x50,0x51,0xe2,0x8c,0x00,0x00,0x00,0x00,0x01,0x00,0x42,0x24,0x50,0x51,0xe2,0xac, -0x03,0x00,0x02,0x24,0xca,0xff,0x02,0x15,0x00,0x00,0x00,0x00,0x54,0x51,0xe2,0x8c, -0x00,0x00,0x00,0x00,0x01,0x00,0x42,0x24,0xc7,0xff,0x0a,0x15,0x54,0x51,0xe2,0xac, -0x58,0x51,0xe2,0x8c,0x21,0x18,0x33,0x01,0x01,0x00,0x42,0x24,0x58,0x51,0xe2,0xac, -0x68,0x51,0xe2,0x8c,0x90,0x44,0x64,0x90,0x02,0x11,0x02,0x00,0x2b,0x10,0x44,0x00, -0xc4,0xff,0x40,0x10,0x00,0x00,0x00,0x00,0x60,0x51,0xe3,0x8c,0x80,0x10,0x09,0x00, -0x21,0x10,0x49,0x00,0x01,0x00,0x63,0x24,0x21,0x10,0x53,0x00,0x60,0x51,0xe3,0xac, -0x21,0x10,0x48,0x00,0xc5,0x43,0x44,0x90,0x44,0x51,0xe3,0x8c,0x00,0x00,0x00,0x00, -0x21,0x18,0x64,0x00,0xf9,0x10,0x00,0x08,0x44,0x51,0xe3,0xac,0x25,0xb0,0x02,0x3c, -0x25,0xb0,0x05,0x3c,0x02,0x80,0x03,0x3c,0x58,0x00,0x4a,0x34,0x5c,0x00,0x4b,0x34, -0x4c,0x00,0xa2,0x34,0x00,0x00,0x44,0x90,0x68,0x15,0x66,0x24,0xed,0x4a,0xc2,0x90, -0x29,0xb0,0x07,0x3c,0x03,0x00,0x84,0x30,0x21,0x18,0xc0,0x00,0x0f,0x00,0x44,0x10, -0x04,0x00,0xe8,0x34,0x07,0x00,0x80,0x14,0x58,0x0c,0xa9,0x34,0xe6,0x42,0xc2,0x90, -0x1c,0x00,0x06,0x24,0x03,0x00,0x40,0x14,0x50,0x0c,0xa5,0x34,0x00,0x00,0xa6,0xa0, -0x00,0x00,0x26,0xa1,0x00,0x00,0x42,0x8d,0xed,0x4a,0x64,0xa0,0x00,0x00,0xe2,0xac, -0x00,0x00,0x62,0x8d,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0xad,0x08,0x00,0xe0,0x03, -0x21,0x10,0x00,0x00,0x25,0xb0,0x0d,0x3c,0xe8,0xff,0xbd,0x27,0x10,0x00,0xbf,0xaf, -0x2d,0x0a,0xa7,0x35,0xa2,0x0d,0xa2,0x35,0xa4,0x0d,0xa3,0x35,0xa6,0x0d,0xa4,0x35, -0xa8,0x0d,0xa5,0x35,0x00,0x00,0x48,0x94,0x00,0x00,0x69,0x94,0x00,0x00,0x8a,0x94, -0x00,0x00,0xab,0x94,0x00,0x00,0xe3,0x90,0x5b,0x0a,0xa4,0x35,0x5c,0x0a,0xa6,0x35, -0x00,0x2e,0x03,0x00,0x03,0x2e,0x05,0x00,0x40,0x00,0xa2,0x34,0x00,0x00,0xe2,0xa0, -0x00,0x00,0x85,0x90,0x00,0x00,0xc3,0x90,0x02,0x80,0x0e,0x3c,0x68,0x15,0xcc,0x25, -0xff,0xff,0x22,0x31,0xff,0x00,0xa5,0x30,0xff,0xff,0x04,0x31,0x21,0x20,0x82,0x00, -0xff,0x00,0x63,0x30,0x00,0x40,0x87,0x8d,0x00,0x2a,0x05,0x00,0xff,0xff,0x46,0x31, -0x21,0x28,0xa3,0x00,0xff,0xff,0x62,0x31,0x21,0x20,0x86,0x00,0x21,0x20,0x82,0x00, -0xff,0xff,0xa3,0x30,0x64,0x0c,0xa2,0x35,0x00,0x00,0x45,0xa4,0x21,0x20,0x83,0x00, -0x0f,0x00,0xe7,0x30,0x01,0x00,0x02,0x24,0xe0,0x42,0x84,0xad,0xd8,0x42,0x88,0xa5, -0xda,0x42,0x89,0xa5,0xdc,0x42,0x8a,0xa5,0xde,0x42,0x8b,0xa5,0x07,0x00,0xe2,0x10, -0xe4,0x42,0x85,0xa5,0xa8,0x56,0x00,0x0c,0x00,0x00,0x00,0x00,0x10,0x00,0xbf,0x8f, -0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x18,0x00,0xbd,0x27,0x4c,0x00,0xa3,0x35, -0x00,0x00,0x62,0x90,0x00,0x00,0x00,0x00,0x03,0x00,0x42,0x30,0x67,0x00,0x47,0x10, -0x68,0x15,0xc4,0x25,0xe6,0x42,0x82,0x90,0x00,0x00,0x00,0x00,0x2d,0x00,0x40,0x10, -0x01,0x00,0x03,0x24,0x68,0x15,0xc5,0x25,0xe6,0x42,0xa3,0x90,0xff,0x00,0x02,0x24, -0xec,0xff,0x62,0x14,0x25,0xb0,0x03,0x3c,0xc8,0x42,0xa2,0x94,0xe0,0x42,0xa6,0x8c, -0x50,0x0c,0x63,0x34,0x00,0x00,0x64,0x90,0x2b,0x10,0xc2,0x00,0x5e,0x00,0x40,0x14, -0x7f,0x00,0x84,0x30,0xca,0x42,0xa2,0x94,0x00,0x00,0x00,0x00,0x2b,0x10,0xc2,0x00, -0x09,0x00,0x40,0x14,0x00,0x00,0x00,0x00,0xcc,0x42,0xa2,0x94,0x00,0x00,0x00,0x00, -0x2b,0x10,0xc2,0x00,0x02,0x00,0x40,0x10,0x02,0x00,0x82,0x24,0x01,0x00,0x82,0x24, -0xff,0x00,0x44,0x30,0x68,0x15,0xc5,0x25,0xd0,0x42,0xa3,0x90,0x00,0x00,0x00,0x00, -0x2b,0x10,0x64,0x00,0x4e,0x00,0x40,0x10,0x00,0x00,0x00,0x00,0x21,0x20,0x60,0x00, -0x68,0x15,0xc3,0x25,0xe0,0x42,0x62,0x8c,0x00,0x00,0x00,0x00,0xe9,0x03,0x42,0x2c, -0x02,0x00,0x40,0x14,0x25,0xb0,0x02,0x3c,0xd0,0x42,0x64,0x90,0x58,0x0c,0x43,0x34, -0x50,0x0c,0x42,0x34,0x00,0x00,0x44,0xa0,0x00,0x00,0x64,0xa0,0x85,0x11,0x00,0x08, -0x00,0x00,0x00,0x00,0x00,0x40,0x82,0x8c,0x00,0x00,0x00,0x00,0x02,0x12,0x02,0x00, -0x0f,0x00,0x42,0x30,0xd0,0xff,0x43,0x14,0x68,0x15,0xc5,0x25,0x25,0xb0,0x02,0x3c, -0x4c,0x00,0x42,0x34,0x00,0x00,0x43,0x90,0x00,0x00,0x00,0x00,0x03,0x00,0x63,0x30, -0xb8,0xff,0x60,0x10,0xff,0xff,0x02,0x34,0xdc,0x63,0x83,0x8c,0x00,0x00,0x00,0x00, -0xb4,0xff,0x62,0x10,0x00,0x00,0x00,0x00,0xe0,0x42,0x83,0x8c,0x00,0x00,0x00,0x00, -0x65,0x00,0x62,0x2c,0x3b,0x00,0x40,0x14,0x28,0x00,0x62,0x2c,0xd2,0x42,0x83,0x90, -0x00,0x00,0x00,0x00,0x00,0x16,0x03,0x00,0x03,0x16,0x02,0x00,0xfe,0xff,0x42,0x24, -0xfc,0xff,0x42,0x28,0x02,0x00,0x40,0x10,0xfe,0xff,0x62,0x24,0xfc,0xff,0x02,0x24, -0xd2,0x42,0x82,0xa0,0x68,0x15,0xc4,0x25,0xdc,0x63,0x82,0x8c,0xd2,0x42,0x83,0x90, -0xce,0x42,0x86,0x90,0x02,0x11,0x02,0x00,0x7f,0x00,0x42,0x30,0x0a,0x00,0x45,0x24, -0x23,0x18,0xa3,0x00,0x00,0x2e,0x03,0x00,0x03,0x2e,0x05,0x00,0xff,0x00,0xc2,0x30, -0x2a,0x10,0x45,0x00,0x17,0x00,0x40,0x10,0x25,0xb0,0x02,0x3c,0x00,0x2e,0x06,0x00, -0x03,0x2e,0x05,0x00,0x58,0x0c,0x43,0x34,0x50,0x0c,0x42,0x34,0x00,0x00,0x45,0xa0, -0x00,0x00,0x65,0xa0,0x85,0x11,0x00,0x08,0x00,0x00,0x00,0x00,0xe6,0x42,0x82,0x91, -0x00,0x00,0x00,0x00,0x97,0xff,0x40,0x14,0x00,0x00,0x00,0x00,0xff,0xff,0x02,0x24, -0x91,0x11,0x00,0x08,0xe6,0x42,0x82,0xa1,0xac,0x11,0x00,0x08,0xff,0xff,0x82,0x24, -0xd1,0x42,0xa3,0x90,0x00,0x00,0x00,0x00,0x2b,0x10,0x83,0x00,0xb4,0x11,0x00,0x08, -0x0b,0x20,0x62,0x00,0xcf,0x42,0x83,0x80,0x00,0x00,0x00,0x00,0xff,0x00,0x62,0x30, -0x2a,0x10,0xa2,0x00,0x0b,0x28,0x62,0x00,0x25,0xb0,0x02,0x3c,0x58,0x0c,0x43,0x34, -0x50,0x0c,0x42,0x34,0x00,0x00,0x45,0xa0,0x00,0x00,0x65,0xa0,0x85,0x11,0x00,0x08, -0x00,0x00,0x00,0x00,0xcf,0xff,0x40,0x10,0x00,0x00,0x00,0x00,0xd2,0x42,0x83,0x90, -0x00,0x00,0x00,0x00,0x00,0x16,0x03,0x00,0x03,0x16,0x02,0x00,0x02,0x00,0x42,0x24, -0x0d,0x00,0x42,0x28,0x03,0x00,0x40,0x14,0x00,0x00,0x00,0x00,0xe0,0x11,0x00,0x08, -0x0c,0x00,0x02,0x24,0xe0,0x11,0x00,0x08,0x02,0x00,0x62,0x24,0xc0,0xff,0xbd,0x27, -0x18,0x00,0xb0,0xaf,0x25,0xb0,0x10,0x3c,0x28,0x00,0xb4,0xaf,0x24,0x00,0xb3,0xaf, -0x1c,0x00,0xb1,0xaf,0x3c,0x00,0xbf,0xaf,0x38,0x00,0xbe,0xaf,0x34,0x00,0xb7,0xaf, -0x30,0x00,0xb6,0xaf,0x2c,0x00,0xb5,0xaf,0x20,0x00,0xb2,0xaf,0xd8,0x00,0x06,0x36, -0x00,0x00,0xc3,0x90,0x02,0x80,0x02,0x3c,0x68,0x15,0x54,0x24,0x2a,0xb0,0x11,0x3c, -0xa0,0xff,0x02,0x24,0x25,0x18,0x62,0x00,0x34,0x00,0x25,0x36,0xfe,0xff,0x02,0x24, -0xbc,0x42,0x92,0x92,0x40,0x00,0x04,0x24,0x00,0x00,0xc3,0xa0,0x00,0x00,0xa2,0xa0, -0xa1,0x4e,0x00,0x0c,0x00,0x96,0x12,0x00,0x21,0x98,0x40,0x00,0x6b,0x00,0x60,0x12, -0x00,0x40,0x02,0x3c,0x08,0x00,0x63,0x8e,0xb0,0x03,0x02,0x36,0x21,0x20,0x60,0x02, -0x00,0x00,0x43,0xac,0x3a,0x45,0x00,0x0c,0x21,0xb8,0x80,0x02,0x01,0x00,0x1e,0x24, -0x42,0x00,0x16,0x36,0x03,0x0c,0x11,0x36,0x17,0x0e,0x15,0x36,0x04,0x00,0x14,0x24, -0x2a,0xb0,0x03,0x3c,0x06,0x00,0x63,0x34,0x00,0x00,0x62,0x94,0x00,0x00,0x00,0x00, -0x00,0xff,0x42,0x30,0x0a,0x00,0x40,0x18,0x00,0x00,0x00,0x00,0x02,0x80,0x04,0x3c, -0xc8,0x94,0x84,0x24,0x00,0x00,0x83,0x8c,0x00,0x00,0x00,0x00,0x00,0x00,0x62,0x94, -0x00,0x00,0x00,0x00,0x00,0xff,0x42,0x30,0xfc,0xff,0x40,0x1c,0x00,0x00,0x00,0x00, -0x08,0x00,0x65,0x8e,0x20,0x10,0x06,0x3c,0x00,0xfe,0xc6,0x34,0x40,0x00,0x07,0x24, -0x01,0x00,0x04,0x24,0x10,0x01,0x00,0x0c,0x10,0x00,0xbe,0xaf,0x4d,0x01,0x00,0x0c, -0x01,0x00,0x04,0x24,0x2a,0xb0,0x02,0x3c,0x05,0x00,0x42,0x34,0xff,0xff,0x03,0x24, -0x00,0x00,0x5e,0xa0,0x00,0x00,0xc3,0xa2,0x00,0x00,0x22,0x92,0xc1,0x42,0xe5,0x92, -0x2a,0xb0,0x04,0x3c,0x02,0x00,0x03,0x24,0x40,0x00,0x42,0x34,0x05,0x00,0x84,0x34, -0x00,0x00,0x22,0xa2,0x00,0x00,0x83,0xa0,0xef,0xff,0x02,0x24,0x00,0x00,0xb0,0x92, -0x64,0x00,0x04,0x24,0x00,0x00,0xa5,0xa2,0x00,0x00,0xc2,0xa2,0xb3,0x0a,0x00,0x0c, -0x00,0x00,0x00,0x00,0x00,0x00,0x22,0x92,0xbf,0xff,0x03,0x24,0x84,0x03,0x04,0x24, -0x24,0x10,0x43,0x00,0x00,0x00,0x22,0xa2,0xb3,0x0a,0x00,0x0c,0xff,0x00,0x10,0x32, -0x25,0xb0,0x02,0x3c,0xf4,0x08,0x42,0x34,0x00,0x00,0x44,0x8c,0x00,0x00,0xb0,0xa2, -0x00,0x00,0xc0,0xa2,0x00,0x00,0x22,0x92,0xbe,0x42,0xe3,0x92,0x1f,0x00,0x85,0x30, -0x40,0x00,0x42,0x34,0x00,0x00,0x22,0xa2,0x00,0x80,0x02,0x3c,0xdf,0x07,0x42,0x34, -0x2b,0x18,0xa3,0x00,0x09,0x00,0x60,0x10,0x24,0x20,0x82,0x00,0xbf,0x42,0xe2,0x92, -0x00,0x00,0x00,0x00,0x2b,0x10,0x45,0x00,0x05,0x00,0x40,0x10,0x02,0x80,0x02,0x3c, -0x01,0x00,0x02,0x3c,0x25,0x10,0xa2,0x00,0x21,0x90,0x42,0x02,0x02,0x80,0x02,0x3c, -0x8e,0x7d,0x43,0x90,0x22,0x00,0x02,0x24,0x1c,0x00,0x62,0x10,0x92,0x00,0x02,0x24, -0x1b,0x00,0x62,0x10,0x02,0x80,0x03,0x3c,0xff,0xff,0x94,0x26,0xb3,0x0a,0x00,0x0c, -0xf4,0x01,0x04,0x24,0xab,0xff,0x81,0x06,0x2a,0xb0,0x03,0x3c,0x04,0x00,0x60,0x12, -0x25,0xb0,0x02,0x3c,0xbd,0x4e,0x00,0x0c,0x21,0x20,0x60,0x02,0x25,0xb0,0x02,0x3c, -0xd8,0x02,0x42,0x34,0x00,0x00,0x52,0xac,0x21,0x10,0x40,0x02,0x3c,0x00,0xbf,0x8f, -0x38,0x00,0xbe,0x8f,0x34,0x00,0xb7,0x8f,0x30,0x00,0xb6,0x8f,0x2c,0x00,0xb5,0x8f, -0x28,0x00,0xb4,0x8f,0x24,0x00,0xb3,0x8f,0x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f, -0x18,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x40,0x00,0xbd,0x27,0x02,0x80,0x03,0x3c, -0x68,0x15,0x63,0x24,0xbe,0x42,0x62,0x90,0xc0,0x07,0x83,0x30,0x82,0x19,0x03,0x00, -0x2b,0x10,0x62,0x00,0xe0,0xff,0x40,0x10,0x02,0x80,0x04,0x3c,0x68,0x15,0x84,0x24, -0xbf,0x42,0x82,0x90,0x00,0x00,0x00,0x00,0x2b,0x10,0x43,0x00,0xda,0xff,0x40,0x10, -0x00,0x12,0x03,0x00,0x10,0x00,0x03,0x3c,0x25,0x10,0x43,0x00,0x9a,0x12,0x00,0x08, -0x21,0x90,0x42,0x02,0xe8,0xff,0xbd,0x27,0x10,0x00,0xb0,0xaf,0x0f,0x00,0x10,0x3c, -0xff,0xff,0x05,0x36,0xf0,0xf8,0x06,0x34,0x14,0x00,0xbf,0xaf,0xba,0x44,0x00,0x0c, -0x15,0x00,0x04,0x24,0xb3,0x0a,0x00,0x0c,0x64,0x00,0x04,0x24,0xff,0xff,0x05,0x36, -0x56,0x30,0x06,0x24,0xba,0x44,0x00,0x0c,0x1a,0x00,0x04,0x24,0xb3,0x0a,0x00,0x0c, -0x64,0x00,0x04,0x24,0x02,0x80,0x0b,0x3c,0x68,0x15,0x64,0x25,0x04,0x43,0x83,0x90, -0x04,0x00,0x02,0x24,0x19,0x00,0x62,0x10,0x25,0xb0,0x02,0x3c,0x14,0x43,0x8a,0x8c, -0x18,0x43,0x88,0x8c,0x25,0xb0,0x02,0x3c,0x1c,0x0e,0x49,0x34,0x00,0x0e,0x43,0x34, -0x04,0x0e,0x44,0x34,0x08,0x0e,0x45,0x34,0x10,0x0e,0x46,0x34,0x14,0x0e,0x47,0x34, -0x18,0x0e,0x42,0x34,0x00,0x00,0x6a,0xac,0x00,0x00,0x8a,0xac,0x00,0x00,0xa8,0xac, -0x00,0x00,0xca,0xac,0x00,0x00,0xea,0xac,0x00,0x00,0x4a,0xac,0x00,0x00,0x2a,0xad, -0x14,0x00,0xbf,0x8f,0x10,0x00,0xb0,0x8f,0x68,0x15,0x63,0x25,0x04,0x00,0x02,0x24, -0x18,0x00,0xbd,0x27,0x08,0x00,0xe0,0x03,0x04,0x43,0x62,0xa0,0x00,0x0e,0x42,0x34, -0x00,0x00,0x43,0x8c,0x14,0x43,0x8a,0x8c,0x00,0x00,0x00,0x00,0xe4,0xff,0x6a,0x14, -0x00,0x00,0x00,0x00,0xec,0x12,0x00,0x08,0x00,0x00,0x00,0x00,0xe8,0xff,0xbd,0x27, -0x10,0x00,0xb0,0xaf,0x0f,0x00,0x10,0x3c,0xff,0xff,0x05,0x36,0xf0,0xf8,0x06,0x34, -0x14,0x00,0xbf,0xaf,0xba,0x44,0x00,0x0c,0x15,0x00,0x04,0x24,0xb3,0x0a,0x00,0x0c, -0x64,0x00,0x04,0x24,0xff,0xff,0x05,0x36,0x56,0x30,0x06,0x24,0xba,0x44,0x00,0x0c, -0x1a,0x00,0x04,0x24,0xb3,0x0a,0x00,0x0c,0x64,0x00,0x04,0x24,0x02,0x80,0x04,0x3c, -0x68,0x15,0x83,0x24,0x04,0x43,0x65,0x90,0x21,0x70,0x60,0x00,0x10,0x10,0x03,0x3c, -0x25,0xb0,0x02,0x3c,0x10,0x10,0x66,0x34,0x01,0x00,0x03,0x24,0x1c,0x0e,0x4d,0x34, -0x00,0x0e,0x4a,0x34,0x04,0x0e,0x4b,0x34,0x08,0x0e,0x4c,0x34,0x10,0x0e,0x47,0x34, -0x14,0x0e,0x48,0x34,0x0f,0x00,0xa3,0x10,0x18,0x0e,0x49,0x34,0x10,0x10,0x02,0x24, -0x00,0x00,0x46,0xad,0x00,0x00,0x66,0xad,0x00,0x00,0x82,0xad,0x00,0x00,0xe6,0xac, -0x00,0x00,0x06,0xad,0x00,0x00,0x26,0xad,0x00,0x00,0xa6,0xad,0x14,0x00,0xbf,0x8f, -0x10,0x00,0xb0,0x8f,0x01,0x00,0x02,0x24,0x18,0x00,0xbd,0x27,0x08,0x00,0xe0,0x03, -0x04,0x43,0xc2,0xa1,0x00,0x00,0x44,0x8d,0x00,0x00,0x00,0x00,0xf0,0xff,0x86,0x14, -0x10,0x10,0x02,0x24,0x23,0x13,0x00,0x08,0x00,0x00,0x00,0x00,0xe0,0xff,0xbd,0x27, -0x14,0x00,0xb1,0xaf,0x10,0x00,0xb0,0xaf,0x01,0x00,0x11,0x3c,0x0f,0x00,0x10,0x3c, -0xff,0xff,0x05,0x36,0xf4,0x98,0x26,0x36,0x18,0x00,0xbf,0xaf,0xba,0x44,0x00,0x0c, -0x15,0x00,0x04,0x24,0xb3,0x0a,0x00,0x0c,0x64,0x00,0x04,0x24,0xff,0xff,0x05,0x36, -0x56,0x30,0x26,0x36,0xba,0x44,0x00,0x0c,0x1a,0x00,0x04,0x24,0x02,0x80,0x10,0x3c, -0xb3,0x0a,0x00,0x0c,0x64,0x00,0x04,0x24,0x68,0x15,0x04,0x26,0x04,0x43,0x82,0x90, -0x00,0x00,0x00,0x00,0x0d,0x00,0x40,0x14,0x25,0xb0,0x02,0x3c,0x00,0x0e,0x42,0x34, -0x00,0x00,0x43,0x8c,0xec,0x42,0x8f,0x8c,0x00,0x00,0x00,0x00,0x08,0x00,0x6f,0x14, -0x68,0x15,0x02,0x26,0x18,0x00,0xbf,0x8f,0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f, -0x20,0x00,0xbd,0x27,0x08,0x00,0xe0,0x03,0x04,0x43,0x40,0xa0,0xec,0x42,0x8f,0x8c, -0xe8,0x42,0x88,0x8c,0xf0,0x42,0x8a,0x8c,0xf4,0x42,0x8b,0x8c,0xf8,0x42,0x8c,0x8c, -0xfc,0x42,0x8d,0x8c,0x25,0xb0,0x02,0x3c,0x00,0x43,0x8e,0x8c,0x1c,0x0e,0x49,0x34, -0x08,0x0e,0x43,0x34,0x00,0x0e,0x44,0x34,0x04,0x0e,0x45,0x34,0x10,0x0e,0x46,0x34, -0x14,0x0e,0x47,0x34,0x18,0x0e,0x42,0x34,0x00,0x00,0x68,0xac,0x18,0x00,0xbf,0x8f, -0x00,0x00,0x8f,0xac,0x14,0x00,0xb1,0x8f,0x00,0x00,0xaa,0xac,0x00,0x00,0xcb,0xac, -0x00,0x00,0xec,0xac,0x00,0x00,0x4d,0xac,0x68,0x15,0x02,0x26,0x10,0x00,0xb0,0x8f, -0x20,0x00,0xbd,0x27,0x00,0x00,0x2e,0xad,0x08,0x00,0xe0,0x03,0x04,0x43,0x40,0xa0, -0xe0,0xff,0xbd,0x27,0x14,0x00,0xb1,0xaf,0x10,0x00,0xb0,0xaf,0x01,0x00,0x11,0x3c, -0x0f,0x00,0x10,0x3c,0xff,0xff,0x05,0x36,0xf4,0x98,0x26,0x36,0x18,0x00,0xbf,0xaf, -0xba,0x44,0x00,0x0c,0x15,0x00,0x04,0x24,0xb3,0x0a,0x00,0x0c,0x64,0x00,0x04,0x24, -0xff,0xff,0x05,0x36,0x56,0x30,0x26,0x36,0xba,0x44,0x00,0x0c,0x1a,0x00,0x04,0x24, -0xb3,0x0a,0x00,0x0c,0x64,0x00,0x04,0x24,0x02,0x80,0x18,0x3c,0x68,0x15,0x05,0x27, -0x04,0x43,0xa3,0x90,0x03,0x00,0x02,0x24,0x2a,0x00,0x62,0x10,0x25,0xb0,0x02,0x3c, -0xec,0x42,0xaf,0x8c,0x08,0x43,0xa3,0x8c,0xe8,0x42,0xa2,0x8c,0xf0,0x42,0xac,0x8c, -0xf4,0x42,0xad,0x8c,0xf8,0x42,0xa9,0x8c,0xfc,0x42,0xaa,0x8c,0x00,0x43,0xab,0x8c, -0x21,0x70,0x43,0x00,0xff,0xff,0x02,0x3c,0x25,0xb0,0x03,0x3c,0xff,0x00,0x42,0x34, -0x00,0xff,0xc4,0x31,0x04,0x0e,0x65,0x34,0x10,0x0e,0x66,0x34,0x14,0x0e,0x67,0x34, -0x18,0x0e,0x68,0x34,0x24,0x80,0xc2,0x01,0x08,0x0e,0x71,0x34,0x00,0x0e,0x62,0x34, -0x01,0x3f,0x84,0x2c,0x1c,0x0e,0x63,0x34,0x00,0x00,0x4f,0xac,0x00,0x00,0xac,0xac, -0x00,0x00,0xcd,0xac,0x00,0x00,0xe9,0xac,0x00,0x00,0x0a,0xad,0x00,0x00,0x6b,0xac, -0x0a,0x00,0x80,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x2e,0xae,0x18,0x00,0xbf,0x8f, -0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x68,0x15,0x03,0x27,0x03,0x00,0x02,0x24, -0x20,0x00,0xbd,0x27,0x08,0x00,0xe0,0x03,0x04,0x43,0x62,0xa0,0xa6,0x13,0x00,0x08, -0x00,0x3f,0x0e,0x36,0x00,0x0e,0x42,0x34,0x00,0x00,0x43,0x8c,0xec,0x42,0xaf,0x8c, -0x00,0x00,0x00,0x00,0xd3,0xff,0x6f,0x14,0x00,0x00,0x00,0x00,0xa7,0x13,0x00,0x08, -0x00,0x00,0x00,0x00,0xd0,0xff,0xbd,0x27,0x18,0x00,0xb2,0xaf,0x02,0x80,0x12,0x3c, -0x24,0x00,0xb5,0xaf,0x20,0x00,0xb4,0xaf,0x28,0x00,0xbf,0xaf,0x1c,0x00,0xb3,0xaf, -0x14,0x00,0xb1,0xaf,0x10,0x00,0xb0,0xaf,0x68,0x15,0x44,0x26,0x02,0x80,0x14,0x3c, -0x00,0x40,0x85,0x8c,0xdc,0x63,0x83,0x8c,0x8e,0x7d,0x86,0x92,0x25,0xb0,0x02,0x3c, -0x0f,0x0c,0x42,0x34,0x00,0x00,0x46,0xa0,0x02,0x19,0x03,0x00,0xf0,0xf0,0xa5,0x30, -0x00,0x10,0x02,0x24,0x04,0x43,0x93,0x90,0x71,0x00,0xa2,0x10,0x7f,0x00,0x75,0x30, -0x25,0xb0,0x09,0x3c,0x4c,0x00,0x23,0x35,0x00,0x00,0x62,0x90,0x00,0x00,0x00,0x00, -0x03,0x00,0x42,0x30,0x09,0x00,0x40,0x10,0x68,0x15,0x45,0x26,0x68,0x15,0x4a,0x26, -0x00,0x40,0x42,0x8d,0x00,0x00,0x00,0x00,0x02,0x13,0x02,0x00,0x0f,0x00,0x42,0x30, -0x33,0x00,0x40,0x10,0x00,0x0e,0x25,0x35,0x68,0x15,0x45,0x26,0x04,0x43,0xa2,0x8c, -0x00,0x00,0x00,0x00,0x02,0x12,0x02,0x00,0x0f,0x00,0x40,0x14,0x68,0x15,0x4a,0x26, -0x25,0xb0,0x02,0x3c,0x84,0x01,0x42,0x34,0x00,0x00,0x44,0x8c,0x0d,0x00,0x03,0x24, -0x7e,0x00,0x83,0x10,0x3e,0x00,0x02,0x24,0x4a,0x00,0x03,0x24,0x1f,0x43,0xa2,0xa0, -0x1c,0x43,0xa3,0xa0,0x45,0x00,0x02,0x24,0x43,0x00,0x03,0x24,0x1d,0x43,0xa2,0xa0, -0x1e,0x43,0xa3,0xa0,0x68,0x15,0x4a,0x26,0xdc,0x63,0x4c,0x8d,0x04,0x40,0x42,0x8d, -0x00,0x40,0x4b,0x8d,0x1e,0x43,0x4d,0x91,0x1c,0x43,0x4e,0x91,0x25,0xb0,0x09,0x3c, -0x02,0x11,0x02,0x00,0x60,0x0c,0x27,0x35,0x02,0x19,0x0c,0x00,0x98,0x0c,0x24,0x35, -0x00,0x00,0xe3,0xa0,0x66,0x0c,0x25,0x35,0x00,0x00,0x82,0xa0,0x67,0x0c,0x26,0x35, -0xf0,0xf0,0x68,0x31,0x10,0x10,0x02,0x24,0x00,0x00,0xad,0xa0,0x00,0x00,0xce,0xa0, -0x43,0x00,0x02,0x11,0xff,0xff,0x02,0x34,0x28,0x00,0xbf,0x8f,0x24,0x00,0xb5,0x8f, -0x20,0x00,0xb4,0x8f,0x1c,0x00,0xb3,0x8f,0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f, -0x10,0x00,0xb0,0x8f,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x30,0x00,0xbd,0x27, -0x00,0x00,0xa2,0x8c,0x00,0x00,0x00,0x00,0x5d,0x00,0x40,0x10,0x10,0x0e,0x28,0x35, -0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40, -0x08,0x0e,0x22,0x35,0x04,0x0e,0x24,0x35,0x00,0x00,0x43,0x8c,0x00,0x00,0xa5,0x8c, -0x00,0x00,0x82,0x8c,0xe8,0x42,0x43,0xad,0xec,0x42,0x45,0xad,0xf0,0x42,0x42,0xad, -0x14,0x0e,0x24,0x35,0x18,0x0e,0x22,0x35,0x1c,0x0e,0x25,0x35,0x00,0x00,0x08,0x8d, -0x8e,0x7d,0x8b,0x92,0x00,0x00,0x86,0x8c,0x00,0xff,0x63,0x30,0x00,0x00,0x47,0x8c, -0x00,0x00,0xa4,0x8c,0x9a,0x0c,0x22,0x35,0x02,0x1a,0x03,0x00,0x00,0x00,0x43,0xa0, -0x22,0x00,0x02,0x24,0xf4,0x42,0x48,0xad,0xf8,0x42,0x46,0xad,0xfc,0x42,0x47,0xad, -0x58,0x00,0x62,0x11,0x00,0x43,0x44,0xad,0x92,0x00,0x02,0x24,0x56,0x00,0x62,0x11, -0x0d,0x08,0x22,0x35,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40, -0x68,0x15,0x44,0x26,0x00,0x40,0x83,0x8c,0xff,0xff,0x02,0x3c,0xff,0x0f,0x42,0x34, -0x24,0x18,0x62,0x00,0x00,0x10,0x63,0x34,0xde,0x13,0x00,0x08,0x00,0x40,0x83,0xac, -0x01,0x00,0x02,0x24,0x35,0x00,0x62,0x12,0x04,0x00,0x02,0x24,0x33,0x00,0x62,0x12, -0x68,0x15,0x43,0x26,0xff,0xff,0x02,0x24,0xd0,0x13,0x00,0x08,0x04,0x43,0x62,0xa0, -0xbd,0xff,0x82,0x11,0x02,0x12,0x0b,0x00,0x0f,0x00,0x48,0x30,0x01,0x00,0x03,0x24, -0xb9,0xff,0x03,0x15,0x4c,0x00,0x23,0x35,0x00,0x00,0x62,0x90,0x00,0x00,0x00,0x00, -0x03,0x00,0x42,0x30,0xb4,0xff,0x40,0x10,0x03,0x00,0x02,0x24,0x5f,0x00,0x62,0x12, -0x04,0x00,0x62,0x2a,0x45,0x00,0x40,0x10,0x00,0x00,0x00,0x00,0x64,0x00,0x60,0x12, -0xff,0x00,0xa2,0x31,0xac,0xff,0x68,0x16,0xff,0x00,0xc2,0x31,0x2b,0x10,0xa2,0x02, -0x52,0x00,0x40,0x10,0x00,0x00,0x00,0x00,0x1f,0x43,0x42,0x91,0x00,0x00,0x00,0x00, -0x2b,0x10,0x55,0x00,0x44,0x00,0x40,0x14,0x00,0x00,0x00,0x00,0x2f,0x13,0x00,0x0c, -0x00,0x00,0x00,0x00,0x06,0x14,0x00,0x08,0x00,0x00,0x00,0x00,0x3b,0x00,0x02,0x24, -0x46,0x00,0x03,0x24,0x1f,0x43,0xa2,0xa0,0x1c,0x43,0xa3,0xa0,0x41,0x00,0x02,0x24, -0x40,0x00,0x03,0x24,0x1d,0x43,0xa2,0xa0,0xf1,0x13,0x00,0x08,0x1e,0x43,0xa3,0xa0, -0x00,0x00,0x03,0x8d,0x3f,0x3f,0x02,0x3c,0x3f,0x3f,0x42,0x34,0xa0,0xff,0x62,0x14, -0x00,0x00,0x00,0x00,0xdf,0x13,0x00,0x08,0x68,0x15,0x45,0x26,0x0f,0x00,0x10,0x3c, -0x01,0x00,0x11,0x3c,0xff,0xff,0x05,0x36,0xf4,0x98,0x26,0x36,0xba,0x44,0x00,0x0c, -0x15,0x00,0x04,0x24,0xb3,0x0a,0x00,0x0c,0x64,0x00,0x04,0x24,0xff,0xff,0x05,0x36, -0x56,0x30,0x26,0x36,0xba,0x44,0x00,0x0c,0x1a,0x00,0x04,0x24,0xb3,0x0a,0x00,0x0c, -0x64,0x00,0x04,0x24,0x68,0x15,0x43,0x26,0xff,0xff,0x02,0x24,0xd0,0x13,0x00,0x08, -0x04,0x43,0x62,0xa0,0x0d,0x08,0x22,0x35,0x00,0x00,0x43,0x90,0x00,0x00,0x00,0x00, -0x0f,0x00,0x63,0x30,0x08,0x00,0x62,0x2c,0x0f,0x00,0x63,0x38,0xa5,0xff,0x40,0x14, -0x01,0x00,0x65,0x24,0x00,0x16,0x05,0x00,0x00,0x24,0x05,0x00,0x00,0x1a,0x05,0x00, -0x25,0x10,0x44,0x00,0x25,0x10,0x43,0x00,0x25,0x10,0x45,0x00,0x25,0x18,0x65,0x00, -0x18,0x43,0x43,0xad,0x35,0x14,0x00,0x08,0x14,0x43,0x42,0xad,0x04,0x00,0x02,0x24, -0x0d,0x00,0x62,0x12,0xff,0x00,0x02,0x24,0x67,0xff,0x62,0x16,0xff,0x00,0xa2,0x31, -0x2b,0x10,0xa2,0x02,0x1d,0x00,0x40,0x14,0xff,0x00,0xc2,0x31,0x2b,0x10,0xa2,0x02, -0x0a,0x00,0x40,0x10,0x00,0x00,0x00,0x00,0xfb,0x12,0x00,0x0c,0x00,0x00,0x00,0x00, -0x06,0x14,0x00,0x08,0x00,0x00,0x00,0x00,0x1d,0x43,0x42,0x91,0x00,0x00,0x00,0x00, -0x2b,0x10,0x55,0x00,0xf8,0xff,0x40,0x10,0x00,0x00,0x00,0x00,0xc5,0x12,0x00,0x0c, -0x00,0x00,0x00,0x00,0x06,0x14,0x00,0x08,0x00,0x00,0x00,0x00,0x20,0x43,0x42,0x91, -0x00,0x00,0x00,0x00,0x2b,0x10,0xa2,0x02,0xac,0xff,0x40,0x10,0x00,0x00,0x00,0x00, -0x70,0x13,0x00,0x0c,0x00,0x00,0x00,0x00,0x06,0x14,0x00,0x08,0x00,0x00,0x00,0x00, -0x2b,0x10,0xa2,0x02,0xe8,0xff,0x40,0x10,0x00,0x00,0x00,0x00,0x21,0x43,0x42,0x91, -0x00,0x00,0x00,0x00,0x2b,0x10,0x55,0x00,0xa0,0xff,0x40,0x14,0x00,0x00,0x00,0x00, -0x70,0x13,0x00,0x0c,0x00,0x00,0x00,0x00,0x06,0x14,0x00,0x08,0x00,0x00,0x00,0x00, -0x02,0x80,0x08,0x3c,0x68,0x15,0x05,0x25,0xdc,0x63,0xa4,0x8c,0xe6,0x42,0xa3,0x90, -0x02,0x11,0x04,0x00,0x1f,0x00,0x60,0x14,0x7f,0x00,0x46,0x30,0x25,0xb0,0x07,0x3c, -0x4c,0x00,0xe2,0x34,0x00,0x00,0x43,0x90,0x00,0x00,0x00,0x00,0x19,0x00,0x60,0x10, -0x00,0x00,0x00,0x00,0xff,0xff,0x02,0x34,0x16,0x00,0x82,0x10,0x00,0x00,0x00,0x00, -0x00,0x08,0xe3,0x34,0x00,0x00,0x62,0x90,0x00,0x00,0x00,0x00,0x01,0x00,0x42,0x30, -0x12,0x00,0x40,0x10,0x4b,0x00,0xc2,0x2c,0x29,0x00,0x40,0x10,0x01,0x00,0x04,0x24, -0xd8,0xff,0xc2,0x24,0x1e,0x00,0x42,0x2c,0x2f,0x00,0x40,0x10,0x23,0x00,0xc2,0x2c, -0x68,0x15,0x04,0x25,0xd3,0x42,0x82,0x90,0x00,0x00,0x00,0x00,0x29,0x00,0x40,0x10, -0x25,0xb0,0x02,0x3c,0x20,0x00,0x03,0x24,0x87,0x0c,0x42,0x34,0x00,0x00,0x43,0xa0, -0xd3,0x42,0x80,0xa0,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x0f,0x00,0x40,0x10, -0x01,0x00,0x04,0x24,0xd8,0xff,0xc2,0x24,0x1e,0x00,0x42,0x2c,0x2c,0x00,0x40,0x10, -0x23,0x00,0xc2,0x2c,0x68,0x15,0x04,0x25,0xd3,0x42,0x82,0x90,0x00,0x00,0x00,0x00, -0x26,0x00,0x40,0x10,0x25,0xb0,0x02,0x3c,0x44,0x00,0x03,0x24,0x30,0x0c,0x42,0x34, -0x00,0x00,0x43,0xa0,0xed,0x14,0x00,0x08,0xd3,0x42,0x80,0xa0,0xd3,0x42,0xa2,0x90, -0x00,0x00,0x00,0x00,0xef,0xff,0x44,0x10,0x30,0x0c,0xe3,0x34,0x43,0x00,0x02,0x24, -0xd3,0x42,0xa4,0xa0,0x00,0x00,0x62,0xa0,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00, -0xd3,0x42,0xa2,0x90,0x00,0x00,0x00,0x00,0xd5,0xff,0x44,0x10,0x87,0x0c,0xe3,0x34, -0x10,0x00,0x02,0x24,0xd3,0x42,0xa4,0xa0,0x00,0x00,0x62,0xa0,0x06,0x15,0x00,0x08, -0x00,0x00,0x00,0x00,0x23,0x00,0xc2,0x2c,0xda,0xff,0x40,0x10,0x00,0x00,0x00,0x00, -0x68,0x15,0x04,0x25,0xd3,0x42,0x82,0x90,0x02,0x00,0x03,0x24,0xd5,0xff,0x43,0x10, -0x00,0x00,0x00,0x00,0x25,0xb0,0x02,0x3c,0x87,0x0c,0x42,0x34,0xd3,0x42,0x83,0xa0, -0x00,0x00,0x40,0xa0,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x23,0x00,0xc2,0x2c, -0xcc,0xff,0x40,0x10,0x00,0x00,0x00,0x00,0x68,0x15,0x04,0x25,0xd3,0x42,0x82,0x90, -0x02,0x00,0x03,0x24,0xc7,0xff,0x43,0x10,0x00,0x00,0x00,0x00,0x25,0xb0,0x02,0x3c, -0xd3,0x42,0x83,0xa0,0x30,0x0c,0x42,0x34,0x42,0x00,0x03,0x24,0x00,0x00,0x43,0xa0, -0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x02,0x80,0x02,0x3c,0x68,0x15,0x45,0x24, -0xd5,0x42,0xa3,0x90,0x02,0x00,0x02,0x24,0x03,0x00,0x62,0x10,0x00,0x00,0x00,0x00, -0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0xdc,0x63,0xa2,0x8c,0x25,0xb0,0x03,0x3c, -0x0a,0x0a,0x68,0x34,0x02,0x11,0x02,0x00,0x7f,0x00,0x42,0x30,0x1a,0x00,0x44,0x2c, -0x14,0x00,0x42,0x2c,0x01,0x0a,0x66,0x34,0x0b,0x00,0x40,0x14,0x2e,0x0a,0x67,0x34, -0xf3,0xff,0x80,0x14,0x00,0x00,0x00,0x00,0xd4,0x42,0xa4,0x90,0x01,0x00,0x02,0x24, -0x01,0x0a,0x67,0x34,0x0f,0x00,0x82,0x10,0x2e,0x0a,0x66,0x34,0xd4,0x42,0xa0,0xa0, -0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x40,0x00,0x02,0x24,0x00,0x00,0xc2,0xa0, -0x01,0x00,0x03,0x24,0xdf,0xff,0x02,0x24,0xd4,0x42,0xa3,0xa0,0x00,0x00,0xe2,0xa0, -0x03,0x00,0x03,0x24,0x21,0x10,0x00,0x00,0x00,0x00,0x03,0xa1,0x08,0x00,0xe0,0x03, -0x00,0x00,0x00,0x00,0x47,0x00,0x02,0x24,0x00,0x00,0xe2,0xa0,0xd3,0xff,0x03,0x24, -0x83,0xff,0x02,0x24,0x00,0x00,0xc3,0xa0,0x00,0x00,0x02,0xa1,0x48,0x15,0x00,0x08, -0xd4,0x42,0xa0,0xa0,0xd0,0xff,0xbd,0x27,0x1c,0x00,0xb1,0xaf,0x28,0x00,0xbf,0xaf, -0x24,0x00,0xb3,0xaf,0x20,0x00,0xb2,0xaf,0x18,0x00,0xb0,0xaf,0xff,0xff,0x11,0x24, -0x02,0x80,0x13,0x3c,0x41,0xb0,0x02,0x3c,0x68,0x15,0x66,0x26,0x04,0x00,0x42,0x34, -0x00,0x00,0x47,0x8c,0x00,0x4b,0xc5,0x8c,0x02,0x80,0x03,0x3c,0x96,0x7d,0x64,0x90, -0xfc,0x4a,0xc8,0x8c,0x02,0x80,0x02,0x3c,0xb8,0x7d,0x49,0x90,0x25,0xb0,0x0a,0x3c, -0x25,0x90,0xa7,0x00,0xb0,0x03,0x42,0x35,0x00,0x00,0x52,0xac,0x00,0x24,0x04,0x00, -0x00,0x00,0x48,0xac,0x84,0x02,0x43,0x35,0x8c,0x02,0x45,0x35,0x01,0x00,0x02,0x24, -0x00,0x00,0x72,0xac,0x00,0x00,0xa4,0xac,0xb9,0x04,0x22,0x11,0x00,0x4b,0xd2,0xac, -0x68,0x15,0x66,0x26,0xfc,0x4a,0xc2,0x8c,0x00,0x00,0x00,0x00,0x24,0x28,0x52,0x00, -0x01,0x00,0xa3,0x30,0x09,0x00,0x60,0x10,0x04,0x00,0xa2,0x30,0x00,0x4b,0xc2,0x8c, -0x25,0xb0,0x03,0x3c,0x01,0x00,0x04,0x24,0x01,0x00,0x42,0x38,0xb0,0x03,0x63,0x34, -0x00,0x00,0x64,0xac,0x00,0x4b,0xc2,0xac,0x04,0x00,0xa2,0x30,0x09,0x00,0x40,0x10, -0x08,0x00,0xa2,0x30,0x00,0x4b,0xc2,0x8c,0x25,0xb0,0x03,0x3c,0x04,0x00,0x04,0x24, -0x04,0x00,0x42,0x38,0xb0,0x03,0x63,0x34,0x00,0x00,0x64,0xac,0x00,0x4b,0xc2,0xac, -0x08,0x00,0xa2,0x30,0x0e,0x00,0x40,0x10,0x68,0x15,0x64,0x26,0xc9,0x64,0xc2,0x90, -0x00,0x00,0x00,0x00,0x05,0x00,0x40,0x18,0x2a,0xb0,0x02,0x3c,0x02,0x00,0x03,0x24, -0x01,0x00,0x42,0x34,0x00,0x00,0x43,0xa0,0xc9,0x64,0xc0,0xa0,0x00,0x4b,0xc2,0x8c, -0x00,0x00,0x00,0x00,0x08,0x00,0x42,0x38,0x00,0x4b,0xc2,0xac,0x68,0x15,0x64,0x26, -0xfc,0x4a,0x82,0x8c,0x00,0x00,0x00,0x00,0x24,0x10,0x52,0x00,0x10,0x00,0x42,0x30, -0x0d,0x00,0x40,0x10,0x00,0x00,0x00,0x00,0xc9,0x64,0x82,0x90,0x00,0x00,0x00,0x00, -0x05,0x00,0x40,0x18,0x2a,0xb0,0x02,0x3c,0x02,0x00,0x03,0x24,0x01,0x00,0x42,0x34, -0x00,0x00,0x43,0xa0,0xc9,0x64,0x80,0xa0,0x00,0x4b,0x82,0x8c,0x00,0x00,0x00,0x00, -0x10,0x00,0x42,0x38,0x00,0x4b,0x82,0xac,0x68,0x15,0x64,0x26,0xfc,0x4a,0x82,0x8c, -0x00,0x00,0x00,0x00,0x24,0x10,0x52,0x00,0x20,0x00,0x42,0x30,0x0e,0x00,0x40,0x10, -0x00,0x00,0x00,0x00,0xc9,0x64,0x82,0x90,0x00,0x00,0x00,0x00,0x05,0x00,0x40,0x18, -0x2a,0xb0,0x02,0x3c,0x02,0x00,0x03,0x24,0x01,0x00,0x42,0x34,0x00,0x00,0x43,0xa0, -0xc9,0x64,0x80,0xa0,0x00,0x4b,0x82,0x8c,0x00,0x00,0x00,0x00,0x20,0x00,0x42,0x38, -0x00,0x4b,0x82,0xac,0x68,0x15,0x64,0x26,0xfc,0x4a,0x82,0x8c,0x00,0x00,0x00,0x00, -0x24,0x10,0x52,0x00,0x40,0x00,0x42,0x30,0x0d,0x00,0x40,0x10,0x00,0x00,0x00,0x00, -0xc9,0x64,0x82,0x90,0x00,0x00,0x00,0x00,0x05,0x00,0x40,0x18,0x2a,0xb0,0x02,0x3c, -0x02,0x00,0x03,0x24,0x01,0x00,0x42,0x34,0x00,0x00,0x43,0xa0,0xc9,0x64,0x80,0xa0, -0x00,0x4b,0x82,0x8c,0x00,0x00,0x00,0x00,0x40,0x00,0x42,0x38,0x00,0x4b,0x82,0xac, -0x68,0x15,0x64,0x26,0xfc,0x4a,0x82,0x8c,0x00,0x00,0x00,0x00,0x24,0x10,0x52,0x00, -0x80,0x00,0x42,0x30,0x0e,0x00,0x40,0x10,0x00,0x00,0x00,0x00,0xc9,0x64,0x82,0x90, -0x00,0x00,0x00,0x00,0x05,0x00,0x40,0x18,0x2a,0xb0,0x02,0x3c,0x02,0x00,0x03,0x24, -0x01,0x00,0x42,0x34,0x00,0x00,0x43,0xa0,0xc9,0x64,0x80,0xa0,0x00,0x4b,0x82,0x8c, -0x00,0x00,0x00,0x00,0x80,0x00,0x42,0x38,0x00,0x4b,0x82,0xac,0x68,0x15,0x64,0x26, -0xfc,0x4a,0x82,0x8c,0x00,0x00,0x00,0x00,0x24,0x10,0x52,0x00,0x00,0x01,0x42,0x30, -0x0d,0x00,0x40,0x10,0x00,0x00,0x00,0x00,0xc9,0x64,0x82,0x90,0x00,0x00,0x00,0x00, -0x05,0x00,0x40,0x18,0x2a,0xb0,0x02,0x3c,0x02,0x00,0x03,0x24,0x01,0x00,0x42,0x34, -0x00,0x00,0x43,0xa0,0xc9,0x64,0x80,0xa0,0x00,0x4b,0x82,0x8c,0x00,0x00,0x00,0x00, -0x00,0x01,0x42,0x38,0x00,0x4b,0x82,0xac,0x68,0x15,0x64,0x26,0xfc,0x4a,0x82,0x8c, -0x00,0x00,0x00,0x00,0x24,0x10,0x52,0x00,0x00,0x02,0x42,0x30,0x0e,0x00,0x40,0x10, -0x00,0x00,0x00,0x00,0xc9,0x64,0x82,0x90,0x00,0x00,0x00,0x00,0x05,0x00,0x40,0x18, -0x2a,0xb0,0x02,0x3c,0x02,0x00,0x03,0x24,0x01,0x00,0x42,0x34,0x00,0x00,0x43,0xa0, -0xc9,0x64,0x80,0xa0,0x00,0x4b,0x82,0x8c,0x00,0x00,0x00,0x00,0x00,0x02,0x42,0x38, -0x00,0x4b,0x82,0xac,0x68,0x15,0x64,0x26,0xfc,0x4a,0x82,0x8c,0x00,0x00,0x00,0x00, -0x24,0x10,0x52,0x00,0x00,0x04,0x42,0x30,0x0d,0x00,0x40,0x10,0x00,0x00,0x00,0x00, -0xc9,0x64,0x82,0x90,0x00,0x00,0x00,0x00,0x05,0x00,0x40,0x18,0x2a,0xb0,0x02,0x3c, -0x02,0x00,0x03,0x24,0x01,0x00,0x42,0x34,0x00,0x00,0x43,0xa0,0xc9,0x64,0x80,0xa0, -0x00,0x4b,0x82,0x8c,0x00,0x00,0x00,0x00,0x00,0x04,0x42,0x38,0x00,0x4b,0x82,0xac, -0x68,0x15,0x63,0x26,0xfc,0x4a,0x62,0x8c,0x00,0x00,0x00,0x00,0x24,0x10,0x52,0x00, -0x00,0x08,0x42,0x30,0x3a,0x00,0x40,0x10,0x2a,0xb0,0x05,0x3c,0x00,0x00,0xa8,0x8c, -0xff,0x00,0x02,0x24,0xff,0x00,0x04,0x31,0x31,0x00,0x82,0x10,0x00,0x80,0x02,0x31, -0x08,0x04,0x40,0x14,0x00,0x80,0x02,0x3c,0x00,0xff,0x02,0x3c,0x24,0x10,0x02,0x01, -0x05,0x00,0x40,0x14,0x00,0x00,0x00,0x00,0xc9,0x64,0x62,0x90,0x00,0x00,0x00,0x00, -0x0b,0x00,0x40,0x18,0xff,0x00,0x02,0x24,0x08,0x64,0x62,0x90,0x20,0xb0,0x03,0x3c, -0x00,0x12,0x02,0x00,0x21,0x10,0x43,0x00,0x0c,0x00,0x48,0x8c,0x25,0xb0,0x03,0x3c, -0xb0,0x03,0x63,0x34,0x00,0x00,0x68,0xac,0xff,0x00,0x04,0x31,0xff,0x00,0x02,0x24, -0x1a,0x00,0x82,0x10,0x68,0x15,0x70,0x26,0xff,0x00,0x03,0x31,0xc0,0x64,0x05,0x8e, -0x20,0x10,0x02,0x3c,0x00,0x1a,0x03,0x00,0x21,0x18,0x62,0x00,0x21,0x30,0x60,0x00, -0x54,0x64,0x03,0xae,0x21,0x20,0x00,0x00,0x08,0x64,0x08,0xa2,0x20,0x00,0x07,0x24, -0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,0xfc,0x4a,0x05,0x8e,0x02,0x80,0x06,0x3c, -0x6c,0x7e,0xc4,0x8c,0xff,0xc7,0x02,0x24,0x24,0x28,0xa2,0x00,0x25,0xb0,0x02,0x3c, -0x04,0x00,0x84,0x34,0x80,0x03,0x42,0x34,0x41,0xb0,0x03,0x3c,0x00,0x00,0x44,0xac, -0x00,0x00,0x65,0xac,0x6c,0x7e,0xc4,0xac,0xfc,0x4a,0x05,0xae,0x68,0x15,0x63,0x26, -0x00,0x4b,0x62,0x8c,0x00,0x00,0x00,0x00,0x00,0x08,0x42,0x38,0x00,0x4b,0x62,0xac, -0x68,0x15,0x65,0x26,0xfc,0x4a,0xa2,0x8c,0x00,0x00,0x00,0x00,0x24,0x10,0x52,0x00, -0x00,0x10,0x42,0x30,0x38,0x00,0x40,0x10,0x2a,0xb0,0x02,0x3c,0x08,0x00,0x43,0x34, -0x00,0x00,0x68,0x8c,0xff,0x00,0x02,0x24,0xff,0x00,0x04,0x31,0x2c,0x00,0x82,0x10, -0x00,0x80,0x02,0x31,0xca,0x03,0x40,0x14,0x00,0x80,0x02,0x3c,0x00,0xff,0x02,0x3c, -0x24,0x10,0x02,0x01,0x0b,0x00,0x40,0x10,0xff,0x00,0x02,0x24,0x10,0x64,0xa2,0x90, -0x20,0xb0,0x03,0x3c,0x00,0x12,0x02,0x00,0x21,0x10,0x43,0x00,0x0c,0x00,0x48,0x8c, -0x25,0xb0,0x03,0x3c,0xb0,0x03,0x63,0x34,0x00,0x00,0x68,0xac,0xff,0x00,0x04,0x31, -0xff,0x00,0x02,0x24,0x1a,0x00,0x82,0x10,0x68,0x15,0x70,0x26,0xff,0x00,0x03,0x31, -0xd8,0x64,0x05,0x8e,0x20,0x10,0x02,0x3c,0x00,0x1a,0x03,0x00,0x21,0x18,0x62,0x00, -0x21,0x30,0x60,0x00,0x6c,0x64,0x03,0xae,0x01,0x00,0x04,0x24,0x10,0x64,0x08,0xa2, -0x20,0x00,0x07,0x24,0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,0xfc,0x4a,0x05,0x8e, -0x02,0x80,0x06,0x3c,0x6c,0x7e,0xc4,0x8c,0xff,0xc7,0x02,0x24,0x24,0x28,0xa2,0x00, -0x25,0xb0,0x02,0x3c,0x10,0x00,0x84,0x34,0x80,0x03,0x42,0x34,0x41,0xb0,0x03,0x3c, -0x00,0x00,0x44,0xac,0x00,0x00,0x65,0xac,0x6c,0x7e,0xc4,0xac,0xfc,0x4a,0x05,0xae, -0x68,0x15,0x63,0x26,0x00,0x4b,0x62,0x8c,0x00,0x00,0x00,0x00,0x00,0x10,0x42,0x38, -0x00,0x4b,0x62,0xac,0x68,0x15,0x65,0x26,0xfc,0x4a,0xa2,0x8c,0x00,0x00,0x00,0x00, -0x24,0x10,0x52,0x00,0x00,0x20,0x42,0x30,0x37,0x00,0x40,0x10,0x2a,0xb0,0x02,0x3c, -0x04,0x00,0x43,0x34,0x00,0x00,0x68,0x8c,0xff,0x00,0x02,0x24,0xff,0x00,0x04,0x31, -0xab,0x03,0x82,0x10,0x00,0x80,0x02,0x31,0x90,0x03,0x40,0x14,0x00,0x80,0x02,0x3c, -0x00,0xff,0x02,0x3c,0x24,0x10,0x02,0x01,0x0b,0x00,0x40,0x10,0xff,0x00,0x02,0x24, -0x0c,0x64,0xa2,0x90,0x20,0xb0,0x03,0x3c,0x00,0x12,0x02,0x00,0x21,0x10,0x43,0x00, -0x0c,0x00,0x48,0x8c,0x25,0xb0,0x03,0x3c,0xb0,0x03,0x63,0x34,0x00,0x00,0x68,0xac, -0xff,0x00,0x04,0x31,0xff,0x00,0x02,0x24,0x1a,0x00,0x82,0x10,0xff,0x00,0x03,0x31, -0x68,0x15,0x70,0x26,0xcc,0x64,0x05,0x8e,0x20,0x10,0x02,0x3c,0x00,0x1a,0x03,0x00, -0x21,0x18,0x62,0x00,0x21,0x30,0x60,0x00,0x60,0x64,0x03,0xae,0x01,0x00,0x04,0x24, -0x0c,0x64,0x08,0xa2,0x20,0x00,0x07,0x24,0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf, -0xfc,0x4a,0x05,0x8e,0x02,0x80,0x06,0x3c,0x6c,0x7e,0xc4,0x8c,0xff,0xc7,0x02,0x24, -0x24,0x28,0xa2,0x00,0x25,0xb0,0x02,0x3c,0x20,0x00,0x84,0x34,0x80,0x03,0x42,0x34, -0x41,0xb0,0x03,0x3c,0x00,0x00,0x44,0xac,0x00,0x00,0x65,0xac,0x6c,0x7e,0xc4,0xac, -0xfc,0x4a,0x05,0xae,0x68,0x15,0x63,0x26,0x00,0x4b,0x62,0x8c,0x00,0x00,0x00,0x00, -0x00,0x20,0x42,0x38,0x00,0x4b,0x62,0xac,0x68,0x15,0x65,0x26,0xfc,0x4a,0xa2,0x8c, -0x00,0x00,0x00,0x00,0x24,0x10,0x52,0x00,0x00,0x80,0x42,0x30,0x59,0x00,0x40,0x10, -0x2a,0xb0,0x06,0x3c,0x0c,0x00,0xc3,0x34,0x00,0x00,0x68,0x8c,0xff,0x00,0x07,0x24, -0xff,0x00,0x04,0x31,0x78,0x03,0x87,0x10,0x00,0x80,0x02,0x31,0x24,0x00,0x40,0x14, -0x00,0x80,0x02,0x3c,0x00,0xff,0x02,0x3c,0x24,0x10,0x02,0x01,0x22,0x00,0x40,0x10, -0xff,0x00,0x02,0x24,0x40,0x00,0xc6,0x34,0x00,0x00,0xc2,0x90,0x00,0x00,0x00,0x00, -0xff,0x00,0x44,0x30,0x0f,0x00,0x87,0x10,0x68,0x15,0x62,0x26,0xe8,0x63,0xa4,0xa0, -0x00,0x00,0xc2,0x90,0xff,0x00,0x83,0x30,0xff,0x00,0x44,0x30,0x09,0x00,0x83,0x10, -0x68,0x15,0x62,0x26,0x21,0x38,0xa0,0x00,0x21,0x28,0xc0,0x00,0x00,0x00,0xa2,0x90, -0x21,0x18,0x80,0x00,0xfd,0xff,0x62,0x14,0xff,0x00,0x44,0x30,0xe8,0x63,0xe3,0xa0, -0x68,0x15,0x62,0x26,0xe8,0x63,0x43,0x90,0x20,0xb0,0x02,0x3c,0x00,0x1a,0x03,0x00, -0x21,0x18,0x62,0x00,0x0c,0x00,0x68,0x8c,0x25,0xb0,0x02,0x3c,0xb0,0x03,0x42,0x34, -0xff,0x00,0x04,0x31,0x00,0x00,0x48,0xac,0x16,0x17,0x00,0x08,0xff,0x00,0x02,0x24, -0x00,0x00,0x62,0xac,0xff,0x00,0x02,0x24,0x24,0x00,0x82,0x10,0x68,0x15,0x70,0x26, -0xff,0x00,0x03,0x31,0x90,0x64,0x05,0x8e,0x20,0x10,0x02,0x3c,0x00,0x1a,0x03,0x00, -0x21,0x18,0x62,0x00,0x21,0x30,0x60,0x00,0xe8,0x63,0x08,0xa2,0x24,0x64,0x03,0xae, -0x03,0x00,0x04,0x24,0x20,0x00,0x07,0x24,0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf, -0x02,0x80,0x0a,0x3c,0x7c,0x7e,0x47,0x91,0x02,0x80,0x09,0x3c,0x6c,0x7e,0x25,0x8d, -0xfc,0x4a,0x06,0x8e,0x01,0x00,0x08,0x3c,0x80,0xff,0x02,0x24,0x25,0x38,0xe2,0x00, -0x00,0x80,0x03,0x35,0x80,0x00,0xa5,0x34,0x27,0x18,0x03,0x00,0x00,0x26,0x07,0x00, -0x25,0xb0,0x02,0x3c,0x24,0x30,0xc3,0x00,0x25,0x20,0x85,0x00,0x80,0x03,0x42,0x34, -0x41,0xb0,0x03,0x3c,0x00,0x00,0x44,0xac,0x27,0x88,0x08,0x00,0x00,0x00,0x66,0xac, -0x6c,0x7e,0x25,0xad,0x7c,0x7e,0x47,0xa1,0xfc,0x4a,0x06,0xae,0x68,0x15,0x63,0x26, -0x00,0x4b,0x62,0x8c,0x00,0x00,0x00,0x00,0x00,0x80,0x42,0x38,0x00,0x4b,0x62,0xac, -0x68,0x15,0x65,0x26,0xfc,0x4a,0xa2,0x8c,0x01,0x00,0x03,0x3c,0x24,0x10,0x52,0x00, -0x24,0x10,0x51,0x00,0x24,0x10,0x43,0x00,0x56,0x00,0x40,0x10,0x2a,0xb0,0x06,0x3c, -0x10,0x00,0xc3,0x34,0x00,0x00,0x68,0x8c,0xff,0x00,0x07,0x24,0xff,0x00,0x04,0x31, -0x23,0x03,0x87,0x10,0x25,0xb0,0x02,0x3c,0x00,0x80,0x02,0x31,0x23,0x00,0x40,0x14, -0x00,0x80,0x02,0x3c,0x00,0xff,0x02,0x3c,0x24,0x10,0x02,0x01,0x21,0x00,0x40,0x10, -0xff,0x00,0x02,0x24,0x41,0x00,0xc6,0x34,0x00,0x00,0xc2,0x90,0x00,0x00,0x00,0x00, -0xff,0x00,0x44,0x30,0x0e,0x00,0x87,0x10,0x68,0x15,0x62,0x26,0xec,0x63,0xa4,0xa0, -0x00,0x00,0xc2,0x90,0xff,0x00,0x83,0x30,0xff,0x00,0x44,0x30,0x07,0x00,0x83,0x10, -0x21,0x38,0xa0,0x00,0x21,0x28,0xc0,0x00,0x00,0x00,0xa2,0x90,0x21,0x18,0x80,0x00, -0xfd,0xff,0x62,0x14,0xff,0x00,0x44,0x30,0xec,0x63,0xe3,0xa0,0x68,0x15,0x62,0x26, -0xec,0x63,0x43,0x90,0x20,0xb0,0x02,0x3c,0x00,0x1a,0x03,0x00,0x21,0x18,0x62,0x00, -0x0c,0x00,0x68,0x8c,0x25,0xb0,0x02,0x3c,0xb0,0x03,0x42,0x34,0xff,0x00,0x04,0x31, -0x00,0x00,0x48,0xac,0x75,0x17,0x00,0x08,0xff,0x00,0x02,0x24,0x00,0x00,0x62,0xac, -0xff,0x00,0x02,0x24,0x22,0x00,0x82,0x10,0x68,0x15,0x70,0x26,0xff,0x00,0x03,0x31, -0x90,0x64,0x05,0x8e,0x20,0x10,0x02,0x3c,0x00,0x1a,0x03,0x00,0x21,0x18,0x62,0x00, -0x21,0x30,0x60,0x00,0xec,0x63,0x08,0xa2,0x24,0x64,0x03,0xae,0x03,0x00,0x04,0x24, -0x20,0x00,0x07,0x24,0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,0x02,0x80,0x09,0x3c, -0x7c,0x7e,0x27,0x91,0x02,0x80,0x08,0x3c,0x6c,0x7e,0x05,0x8d,0xfc,0x4a,0x06,0x8e, -0x01,0x00,0x02,0x3c,0x00,0x80,0x42,0x34,0x40,0x00,0xe7,0x34,0x27,0x10,0x02,0x00, -0x24,0x30,0xc2,0x00,0x80,0x00,0xa5,0x34,0x00,0x26,0x07,0x00,0x25,0xb0,0x02,0x3c, -0x25,0x20,0x85,0x00,0x80,0x03,0x42,0x34,0x41,0xb0,0x03,0x3c,0x00,0x00,0x44,0xac, -0x00,0x00,0x66,0xac,0x6c,0x7e,0x05,0xad,0x7c,0x7e,0x27,0xa1,0xfc,0x4a,0x06,0xae, -0x68,0x15,0x62,0x26,0x00,0x4b,0x43,0x8c,0x01,0x00,0x04,0x3c,0x26,0x18,0x64,0x00, -0x00,0x4b,0x43,0xac,0x68,0x15,0x65,0x26,0xfc,0x4a,0xa2,0x8c,0x02,0x00,0x03,0x3c, -0x24,0x10,0x52,0x00,0x24,0x10,0x43,0x00,0x5a,0x00,0x40,0x10,0x2a,0xb0,0x06,0x3c, -0x14,0x00,0xc3,0x34,0x00,0x00,0x68,0x8c,0xff,0x00,0x07,0x24,0xff,0x00,0x04,0x31, -0xcc,0x02,0x87,0x10,0x25,0xb0,0x02,0x3c,0x00,0x80,0x02,0x31,0x23,0x00,0x40,0x14, -0x00,0x80,0x02,0x3c,0x00,0xff,0x02,0x3c,0x24,0x10,0x02,0x01,0x21,0x00,0x40,0x10, -0xff,0x00,0x02,0x24,0x42,0x00,0xc6,0x34,0x00,0x00,0xc2,0x90,0x00,0x00,0x00,0x00, -0xff,0x00,0x44,0x30,0x0e,0x00,0x87,0x10,0x68,0x15,0x62,0x26,0xf0,0x63,0xa4,0xa0, -0x00,0x00,0xc2,0x90,0xff,0x00,0x83,0x30,0xff,0x00,0x44,0x30,0x07,0x00,0x83,0x10, -0x21,0x38,0xa0,0x00,0x21,0x28,0xc0,0x00,0x00,0x00,0xa2,0x90,0x21,0x18,0x80,0x00, -0xfd,0xff,0x62,0x14,0xff,0x00,0x44,0x30,0xf0,0x63,0xe3,0xa0,0x68,0x15,0x62,0x26, -0xf0,0x63,0x43,0x90,0x20,0xb0,0x02,0x3c,0x00,0x1a,0x03,0x00,0x21,0x18,0x62,0x00, -0x0c,0x00,0x68,0x8c,0x25,0xb0,0x02,0x3c,0xb0,0x03,0x42,0x34,0xff,0x00,0x04,0x31, -0x00,0x00,0x48,0xac,0xd1,0x17,0x00,0x08,0xff,0x00,0x02,0x24,0x00,0x00,0x62,0xac, -0xff,0x00,0x02,0x24,0x25,0x00,0x82,0x10,0x68,0x15,0x70,0x26,0xff,0x00,0x03,0x31, -0x9c,0x64,0x05,0x8e,0x20,0x10,0x02,0x3c,0x00,0x1a,0x03,0x00,0x21,0x18,0x62,0x00, -0x21,0x30,0x60,0x00,0xf0,0x63,0x08,0xa2,0x30,0x64,0x03,0xae,0x04,0x00,0x04,0x24, -0x20,0x00,0x07,0x24,0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,0x02,0x80,0x0a,0x3c, -0x7c,0x7e,0x47,0x91,0x02,0x80,0x09,0x3c,0x6c,0x7e,0x25,0x8d,0xfc,0x4a,0x06,0x8e, -0x06,0x00,0x02,0x3c,0x20,0x00,0xe7,0x34,0x27,0x10,0x02,0x00,0x24,0x30,0xc2,0x00, -0x00,0x01,0xa5,0x34,0x25,0xb0,0x03,0x3c,0x04,0x00,0x02,0x3c,0x00,0x26,0x07,0x00, -0x26,0x88,0x22,0x02,0xb0,0x03,0x68,0x34,0x25,0x20,0x85,0x00,0x80,0x03,0x63,0x34, -0x41,0xb0,0x02,0x3c,0x00,0x00,0x64,0xac,0x00,0x00,0x46,0xac,0x6c,0x7e,0x25,0xad, -0x7c,0x7e,0x47,0xa1,0xfc,0x4a,0x06,0xae,0x00,0x00,0x11,0xad,0x68,0x15,0x62,0x26, -0x00,0x4b,0x43,0x8c,0x02,0x00,0x04,0x3c,0x26,0x18,0x64,0x00,0x00,0x4b,0x43,0xac, -0x68,0x15,0x65,0x26,0xfc,0x4a,0xa2,0x8c,0x04,0x00,0x03,0x3c,0x24,0x10,0x52,0x00, -0x24,0x10,0x51,0x00,0x24,0x10,0x43,0x00,0x58,0x00,0x40,0x10,0x25,0xb0,0x03,0x3c, -0xb0,0x03,0x62,0x34,0x2a,0xb0,0x09,0x3c,0x00,0x00,0x51,0xac,0x18,0x00,0x26,0x35, -0x00,0x00,0xc8,0x8c,0xff,0x00,0x07,0x24,0xff,0x00,0x04,0x31,0x3a,0x02,0x87,0x10, -0x04,0x00,0x02,0x24,0x00,0x80,0x02,0x31,0x23,0x00,0x40,0x14,0x00,0x80,0x02,0x3c, -0x00,0xff,0x02,0x3c,0x24,0x10,0x02,0x01,0x21,0x00,0x40,0x10,0xff,0x00,0x02,0x24, -0x43,0x00,0x26,0x35,0x00,0x00,0xc2,0x90,0x00,0x00,0x00,0x00,0xff,0x00,0x44,0x30, -0x0e,0x00,0x87,0x10,0x68,0x15,0x62,0x26,0xf4,0x63,0xa4,0xa0,0x00,0x00,0xc2,0x90, -0xff,0x00,0x83,0x30,0xff,0x00,0x44,0x30,0x07,0x00,0x83,0x10,0x21,0x38,0xa0,0x00, -0x21,0x28,0xc0,0x00,0x00,0x00,0xa2,0x90,0x21,0x18,0x80,0x00,0xfd,0xff,0x62,0x14, -0xff,0x00,0x44,0x30,0xf4,0x63,0xe3,0xa0,0x68,0x15,0x62,0x26,0xf4,0x63,0x43,0x90, -0x20,0xb0,0x02,0x3c,0x00,0x1a,0x03,0x00,0x21,0x18,0x62,0x00,0x0c,0x00,0x68,0x8c, -0x25,0xb0,0x02,0x3c,0xb0,0x03,0x42,0x34,0xff,0x00,0x04,0x31,0x00,0x00,0x48,0xac, -0x34,0x18,0x00,0x08,0xff,0x00,0x02,0x24,0x00,0x00,0xc2,0xac,0xff,0x00,0x02,0x24, -0x21,0x00,0x82,0x10,0x68,0x15,0x70,0x26,0xff,0x00,0x03,0x31,0x9c,0x64,0x05,0x8e, -0x20,0x10,0x02,0x3c,0x00,0x1a,0x03,0x00,0x21,0x18,0x62,0x00,0x21,0x30,0x60,0x00, -0xf4,0x63,0x08,0xa2,0x30,0x64,0x03,0xae,0x04,0x00,0x04,0x24,0x20,0x00,0x07,0x24, -0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,0x02,0x80,0x09,0x3c,0x7c,0x7e,0x27,0x91, -0x02,0x80,0x08,0x3c,0x6c,0x7e,0x05,0x8d,0xfc,0x4a,0x06,0x8e,0x06,0x00,0x02,0x3c, -0x10,0x00,0xe7,0x34,0x27,0x10,0x02,0x00,0x24,0x30,0xc2,0x00,0x00,0x01,0xa5,0x34, -0x00,0x26,0x07,0x00,0x25,0xb0,0x02,0x3c,0x25,0x20,0x85,0x00,0x80,0x03,0x42,0x34, -0x41,0xb0,0x03,0x3c,0x00,0x00,0x44,0xac,0x00,0x00,0x66,0xac,0x6c,0x7e,0x05,0xad, -0x7c,0x7e,0x27,0xa1,0xfc,0x4a,0x06,0xae,0x68,0x15,0x62,0x26,0x00,0x4b,0x43,0x8c, -0x04,0x00,0x04,0x3c,0x26,0x18,0x64,0x00,0x00,0x4b,0x43,0xac,0x68,0x15,0x65,0x26, -0xfc,0x4a,0xa2,0x8c,0x08,0x00,0x03,0x3c,0x24,0x10,0x52,0x00,0x24,0x10,0x43,0x00, -0x5a,0x00,0x40,0x10,0x2a,0xb0,0x06,0x3c,0x1c,0x00,0xc3,0x34,0x00,0x00,0x68,0x8c, -0xff,0x00,0x07,0x24,0xff,0x00,0x04,0x31,0x13,0x02,0x87,0x10,0x25,0xb0,0x02,0x3c, -0x00,0x80,0x02,0x31,0x23,0x00,0x40,0x14,0x00,0x80,0x02,0x3c,0x00,0xff,0x02,0x3c, -0x24,0x10,0x02,0x01,0x21,0x00,0x40,0x10,0xff,0x00,0x02,0x24,0x44,0x00,0xc6,0x34, -0x00,0x00,0xc2,0x90,0x00,0x00,0x00,0x00,0xff,0x00,0x44,0x30,0x0e,0x00,0x87,0x10, -0x68,0x15,0x62,0x26,0xf8,0x63,0xa4,0xa0,0x00,0x00,0xc2,0x90,0xff,0x00,0x83,0x30, -0xff,0x00,0x44,0x30,0x07,0x00,0x83,0x10,0x21,0x38,0xa0,0x00,0x21,0x28,0xc0,0x00, -0x00,0x00,0xa2,0x90,0x21,0x18,0x80,0x00,0xfd,0xff,0x62,0x14,0xff,0x00,0x44,0x30, -0xf8,0x63,0xe3,0xa0,0x68,0x15,0x62,0x26,0xf8,0x63,0x43,0x90,0x20,0xb0,0x02,0x3c, -0x00,0x1a,0x03,0x00,0x21,0x18,0x62,0x00,0x0c,0x00,0x68,0x8c,0x25,0xb0,0x02,0x3c, -0xb0,0x03,0x42,0x34,0xff,0x00,0x04,0x31,0x00,0x00,0x48,0xac,0x8f,0x18,0x00,0x08, -0xff,0x00,0x02,0x24,0x00,0x00,0x62,0xac,0xff,0x00,0x02,0x24,0x25,0x00,0x82,0x10, -0x68,0x15,0x70,0x26,0xff,0x00,0x03,0x31,0xa8,0x64,0x05,0x8e,0x20,0x10,0x02,0x3c, -0x00,0x1a,0x03,0x00,0x21,0x18,0x62,0x00,0x21,0x30,0x60,0x00,0xf8,0x63,0x08,0xa2, -0x3c,0x64,0x03,0xae,0x05,0x00,0x04,0x24,0x20,0x00,0x07,0x24,0x10,0x01,0x00,0x0c, -0x10,0x00,0xa0,0xaf,0x02,0x80,0x0a,0x3c,0x7c,0x7e,0x47,0x91,0x02,0x80,0x09,0x3c, -0x6c,0x7e,0x25,0x8d,0xfc,0x4a,0x06,0x8e,0x18,0x00,0x02,0x3c,0x08,0x00,0xe7,0x34, -0x27,0x10,0x02,0x00,0x24,0x30,0xc2,0x00,0x00,0x02,0xa5,0x34,0x25,0xb0,0x03,0x3c, -0x10,0x00,0x02,0x3c,0x00,0x26,0x07,0x00,0x26,0x88,0x22,0x02,0xb0,0x03,0x68,0x34, -0x25,0x20,0x85,0x00,0x80,0x03,0x63,0x34,0x41,0xb0,0x02,0x3c,0x00,0x00,0x64,0xac, -0x00,0x00,0x46,0xac,0x6c,0x7e,0x25,0xad,0x7c,0x7e,0x47,0xa1,0xfc,0x4a,0x06,0xae, -0x00,0x00,0x11,0xad,0x68,0x15,0x62,0x26,0x00,0x4b,0x43,0x8c,0x08,0x00,0x04,0x3c, -0x26,0x18,0x64,0x00,0x00,0x4b,0x43,0xac,0x68,0x15,0x65,0x26,0xfc,0x4a,0xa2,0x8c, -0x10,0x00,0x03,0x3c,0x24,0x10,0x52,0x00,0x24,0x10,0x51,0x00,0x24,0x10,0x43,0x00, -0x58,0x00,0x40,0x10,0x25,0xb0,0x06,0x3c,0xb0,0x03,0xc2,0x34,0x2a,0xb0,0x09,0x3c, -0x00,0x00,0x51,0xac,0x20,0x00,0x23,0x35,0x00,0x00,0x68,0x8c,0xff,0x00,0x07,0x24, -0xff,0x00,0x04,0x31,0x80,0x01,0x87,0x10,0x90,0x03,0xc2,0x34,0x00,0x80,0x02,0x31, -0x23,0x00,0x40,0x14,0x00,0x80,0x02,0x3c,0x00,0xff,0x02,0x3c,0x24,0x10,0x02,0x01, -0x21,0x00,0x40,0x10,0xff,0x00,0x02,0x24,0x45,0x00,0x26,0x35,0x00,0x00,0xc2,0x90, -0x00,0x00,0x00,0x00,0xff,0x00,0x44,0x30,0x0e,0x00,0x87,0x10,0x68,0x15,0x62,0x26, -0x04,0x64,0xa4,0xa0,0x00,0x00,0xc2,0x90,0xff,0x00,0x83,0x30,0xff,0x00,0x44,0x30, -0x07,0x00,0x83,0x10,0x21,0x38,0xa0,0x00,0x21,0x28,0xc0,0x00,0x00,0x00,0xa2,0x90, -0x21,0x18,0x80,0x00,0xfd,0xff,0x62,0x14,0xff,0x00,0x44,0x30,0x04,0x64,0xe3,0xa0, -0x68,0x15,0x62,0x26,0x04,0x64,0x43,0x90,0x20,0xb0,0x02,0x3c,0x00,0x1a,0x03,0x00, -0x21,0x18,0x62,0x00,0x0c,0x00,0x68,0x8c,0x25,0xb0,0x02,0x3c,0xb0,0x03,0x42,0x34, -0xff,0x00,0x04,0x31,0x00,0x00,0x48,0xac,0xf2,0x18,0x00,0x08,0xff,0x00,0x02,0x24, -0x00,0x00,0x62,0xac,0xff,0x00,0x02,0x24,0x21,0x00,0x82,0x10,0x68,0x15,0x70,0x26, -0xff,0x00,0x03,0x31,0xa8,0x64,0x05,0x8e,0x20,0x10,0x02,0x3c,0x00,0x1a,0x03,0x00, -0x21,0x18,0x62,0x00,0x21,0x30,0x60,0x00,0x04,0x64,0x08,0xa2,0x3c,0x64,0x03,0xae, -0x05,0x00,0x04,0x24,0x20,0x00,0x07,0x24,0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf, -0x02,0x80,0x09,0x3c,0x7c,0x7e,0x27,0x91,0x02,0x80,0x08,0x3c,0x6c,0x7e,0x05,0x8d, -0xfc,0x4a,0x06,0x8e,0x18,0x00,0x02,0x3c,0x01,0x00,0xe7,0x34,0x27,0x10,0x02,0x00, -0x24,0x30,0xc2,0x00,0x00,0x02,0xa5,0x34,0x00,0x26,0x07,0x00,0x25,0xb0,0x02,0x3c, -0x25,0x20,0x85,0x00,0x80,0x03,0x42,0x34,0x41,0xb0,0x03,0x3c,0x00,0x00,0x44,0xac, -0x00,0x00,0x66,0xac,0x6c,0x7e,0x05,0xad,0x7c,0x7e,0x27,0xa1,0xfc,0x4a,0x06,0xae, -0x68,0x15,0x62,0x26,0x00,0x4b,0x43,0x8c,0x10,0x00,0x04,0x3c,0x26,0x18,0x64,0x00, -0x00,0x4b,0x43,0xac,0x68,0x15,0x65,0x26,0xfc,0x4a,0xa2,0x8c,0x20,0x00,0x03,0x3c, -0x24,0x10,0x52,0x00,0x24,0x10,0x43,0x00,0x5a,0x00,0x40,0x10,0x2a,0xb0,0x06,0x3c, -0x24,0x00,0xc3,0x34,0x00,0x00,0x68,0x8c,0xff,0x00,0x07,0x24,0xff,0x00,0x04,0x31, -0x28,0x01,0x87,0x10,0x25,0xb0,0x02,0x3c,0x00,0x80,0x02,0x31,0x23,0x00,0x40,0x14, -0x00,0x80,0x02,0x3c,0x00,0xff,0x02,0x3c,0x24,0x10,0x02,0x01,0x21,0x00,0x40,0x10, -0xff,0x00,0x02,0x24,0x46,0x00,0xc6,0x34,0x00,0x00,0xc2,0x90,0x00,0x00,0x00,0x00, -0xff,0x00,0x44,0x30,0x0e,0x00,0x87,0x10,0x68,0x15,0x62,0x26,0xfc,0x63,0xa4,0xa0, -0x00,0x00,0xc2,0x90,0xff,0x00,0x83,0x30,0xff,0x00,0x44,0x30,0x07,0x00,0x83,0x10, -0x21,0x38,0xa0,0x00,0x21,0x28,0xc0,0x00,0x00,0x00,0xa2,0x90,0x21,0x18,0x80,0x00, -0xfd,0xff,0x62,0x14,0xff,0x00,0x44,0x30,0xfc,0x63,0xe3,0xa0,0x68,0x15,0x62,0x26, -0xfc,0x63,0x43,0x90,0x20,0xb0,0x02,0x3c,0x00,0x1a,0x03,0x00,0x21,0x18,0x62,0x00, -0x0c,0x00,0x68,0x8c,0x25,0xb0,0x02,0x3c,0xb0,0x03,0x42,0x34,0xff,0x00,0x04,0x31, -0x00,0x00,0x48,0xac,0x4d,0x19,0x00,0x08,0xff,0x00,0x02,0x24,0x00,0x00,0x62,0xac, -0xff,0x00,0x02,0x24,0x25,0x00,0x82,0x10,0x68,0x15,0x70,0x26,0xff,0x00,0x03,0x31, -0xb4,0x64,0x05,0x8e,0x20,0x10,0x02,0x3c,0x00,0x1a,0x03,0x00,0x21,0x18,0x62,0x00, -0x21,0x30,0x60,0x00,0xfc,0x63,0x08,0xa2,0x48,0x64,0x03,0xae,0x06,0x00,0x04,0x24, -0x20,0x00,0x07,0x24,0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,0x02,0x80,0x0a,0x3c, -0x7c,0x7e,0x47,0x91,0x02,0x80,0x09,0x3c,0x6c,0x7e,0x25,0x8d,0xfc,0x4a,0x06,0x8e, -0x60,0x00,0x02,0x3c,0x04,0x00,0xe7,0x34,0x27,0x10,0x02,0x00,0x24,0x30,0xc2,0x00, -0x00,0x04,0xa5,0x34,0x25,0xb0,0x03,0x3c,0x40,0x00,0x02,0x3c,0x00,0x26,0x07,0x00, -0x26,0x88,0x22,0x02,0xb0,0x03,0x68,0x34,0x25,0x20,0x85,0x00,0x80,0x03,0x63,0x34, -0x41,0xb0,0x02,0x3c,0x00,0x00,0x64,0xac,0x00,0x00,0x46,0xac,0x6c,0x7e,0x25,0xad, -0x7c,0x7e,0x47,0xa1,0xfc,0x4a,0x06,0xae,0x00,0x00,0x11,0xad,0x68,0x15,0x62,0x26, -0x00,0x4b,0x43,0x8c,0x20,0x00,0x04,0x3c,0x26,0x18,0x64,0x00,0x00,0x4b,0x43,0xac, -0x68,0x15,0x65,0x26,0xfc,0x4a,0xa2,0x8c,0x40,0x00,0x03,0x3c,0x24,0x10,0x52,0x00, -0x24,0x10,0x51,0x00,0x24,0x10,0x43,0x00,0x5a,0x00,0x40,0x10,0x68,0x15,0x70,0x26, -0x25,0xb0,0x02,0x3c,0x2a,0xb0,0x07,0x3c,0xb0,0x03,0x42,0x34,0x00,0x00,0x51,0xac, -0x28,0x00,0xe3,0x34,0x00,0x00,0x68,0x8c,0xff,0x00,0x06,0x24,0xff,0x00,0x04,0x31, -0xc9,0x00,0x86,0x10,0x25,0xbd,0x02,0x3c,0x00,0x80,0x02,0x31,0x23,0x00,0x40,0x14, -0x00,0x80,0x02,0x3c,0x00,0xff,0x02,0x3c,0x24,0x10,0x02,0x01,0x21,0x00,0x40,0x10, -0xff,0x00,0x02,0x24,0x47,0x00,0xe7,0x34,0x00,0x00,0xe2,0x90,0x00,0x00,0x00,0x00, -0xff,0x00,0x44,0x30,0x0e,0x00,0x86,0x10,0x68,0x15,0x62,0x26,0x00,0x64,0xa4,0xa0, -0x00,0x00,0xe2,0x90,0xff,0x00,0x83,0x30,0xff,0x00,0x44,0x30,0x07,0x00,0x83,0x10, -0x21,0x30,0xa0,0x00,0x21,0x28,0xe0,0x00,0x00,0x00,0xa2,0x90,0x21,0x18,0x80,0x00, -0xfd,0xff,0x62,0x14,0xff,0x00,0x44,0x30,0x00,0x64,0xc3,0xa0,0x68,0x15,0x62,0x26, -0x00,0x64,0x43,0x90,0x20,0xb0,0x02,0x3c,0x00,0x1a,0x03,0x00,0x21,0x18,0x62,0x00, -0x0c,0x00,0x68,0x8c,0x25,0xb0,0x02,0x3c,0xb0,0x03,0x42,0x34,0xff,0x00,0x04,0x31, -0x00,0x00,0x48,0xac,0xb1,0x19,0x00,0x08,0xff,0x00,0x02,0x24,0x00,0x00,0x62,0xac, -0xff,0x00,0x02,0x24,0x21,0x00,0x82,0x10,0x68,0x15,0x70,0x26,0xff,0x00,0x03,0x31, -0xb4,0x64,0x05,0x8e,0x20,0x10,0x02,0x3c,0x00,0x1a,0x03,0x00,0x21,0x18,0x62,0x00, -0x21,0x30,0x60,0x00,0x00,0x64,0x08,0xa2,0x48,0x64,0x03,0xae,0x06,0x00,0x04,0x24, -0x20,0x00,0x07,0x24,0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,0x02,0x80,0x09,0x3c, -0x7c,0x7e,0x27,0x91,0x02,0x80,0x08,0x3c,0x6c,0x7e,0x05,0x8d,0xfc,0x4a,0x06,0x8e, -0x60,0x00,0x02,0x3c,0x02,0x00,0xe7,0x34,0x27,0x10,0x02,0x00,0x24,0x30,0xc2,0x00, -0x00,0x04,0xa5,0x34,0x00,0x26,0x07,0x00,0x25,0xb0,0x02,0x3c,0x25,0x20,0x85,0x00, -0x80,0x03,0x42,0x34,0x41,0xb0,0x03,0x3c,0x00,0x00,0x44,0xac,0x00,0x00,0x66,0xac, -0x6c,0x7e,0x05,0xad,0x7c,0x7e,0x27,0xa1,0xfc,0x4a,0x06,0xae,0x68,0x15,0x62,0x26, -0x00,0x4b,0x43,0x8c,0x40,0x00,0x04,0x3c,0x26,0x18,0x64,0x00,0x00,0x4b,0x43,0xac, -0x68,0x15,0x70,0x26,0xfc,0x4a,0x06,0x8e,0x00,0x04,0x11,0x3c,0x24,0x10,0xd2,0x00, -0x24,0x10,0x51,0x00,0x4c,0x00,0x40,0x14,0x00,0x00,0x00,0x00,0x24,0x28,0xd2,0x00, -0x00,0x08,0x04,0x3c,0x24,0x10,0xa4,0x00,0x08,0x00,0x40,0x10,0x80,0x00,0x07,0x3c, -0x00,0x4b,0x03,0x8e,0x25,0xb0,0x02,0x3c,0xb0,0x03,0x42,0x34,0x26,0x18,0x64,0x00, -0x00,0x00,0x44,0xac,0x00,0x4b,0x03,0xae,0x80,0x00,0x07,0x3c,0x24,0x10,0xa7,0x00, -0x21,0x00,0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x4b,0x03,0x8e,0x25,0xb0,0x08,0x3c, -0xb0,0x03,0x09,0x35,0x2a,0xb0,0x02,0x3c,0x00,0x00,0x23,0xad,0x36,0x00,0x42,0x34, -0x00,0x00,0x43,0x90,0x23,0xb0,0x04,0x3c,0xff,0x1f,0x02,0x3c,0xc0,0x18,0x03,0x00, -0xf0,0x07,0x63,0x30,0x5c,0x65,0x05,0x8e,0x21,0x18,0x64,0x00,0xff,0xff,0x42,0x34, -0x24,0x18,0x62,0x00,0x59,0x00,0x65,0x10,0x60,0x65,0x03,0xae,0x02,0x80,0x05,0x3c, -0x6c,0x7e,0xa3,0x8c,0x27,0x20,0x07,0x00,0x24,0x20,0xc4,0x00,0x00,0x08,0x63,0x34, -0x41,0xb0,0x02,0x3c,0x00,0x00,0x23,0xad,0x00,0x00,0x44,0xac,0x6c,0x7e,0xa3,0xac, -0xfc,0x4a,0x04,0xae,0x68,0x15,0x62,0x26,0x00,0x4b,0x43,0x8c,0x80,0x00,0x04,0x3c, -0x26,0x18,0x64,0x00,0x00,0x4b,0x43,0xac,0x68,0x15,0x66,0x26,0xfc,0x4a,0xc3,0x8c, -0x00,0x01,0x04,0x3c,0x24,0x28,0x72,0x00,0x24,0x10,0xa4,0x00,0x06,0x00,0x40,0x10, -0x25,0xb0,0x02,0x3c,0x00,0x4b,0xc3,0x8c,0xb0,0x03,0x42,0x34,0x26,0x18,0x64,0x00, -0x00,0x00,0x44,0xac,0x00,0x4b,0xc3,0xac,0x00,0x02,0x04,0x3c,0x24,0x10,0xa4,0x00, -0x06,0x00,0x40,0x10,0x25,0xb0,0x03,0x3c,0x00,0x4b,0xc2,0x8c,0xb0,0x03,0x63,0x34, -0x26,0x10,0x44,0x00,0x00,0x4b,0xc2,0xac,0x00,0x00,0x64,0xac,0x28,0x00,0xbf,0x8f, -0x24,0x00,0xb3,0x8f,0x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f, -0x08,0x00,0xe0,0x03,0x30,0x00,0xbd,0x27,0x5b,0x4e,0x00,0x0c,0x07,0x00,0x04,0x24, -0x00,0x4b,0x03,0x8e,0xfc,0x4a,0x06,0x8e,0x25,0xb0,0x02,0x3c,0x26,0x18,0x71,0x00, -0xb0,0x03,0x42,0x34,0x00,0x00,0x43,0xac,0xdf,0x19,0x00,0x08,0x00,0x4b,0x03,0xae, -0x56,0x01,0x42,0x35,0x00,0x00,0x43,0x94,0x00,0x00,0x00,0x00,0x44,0xfb,0x60,0x10, -0x00,0x00,0x00,0x00,0x5b,0x4e,0x00,0x0c,0x07,0x00,0x04,0x24,0x7d,0x15,0x00,0x08, -0x68,0x15,0x66,0x26,0x00,0x00,0xa2,0xac,0x48,0x16,0x00,0x08,0xff,0x00,0x02,0x24, -0x00,0x00,0x62,0xac,0x85,0x16,0x00,0x08,0xff,0x00,0x02,0x24,0x00,0x00,0x62,0xac, -0xc2,0x16,0x00,0x08,0xff,0x00,0x02,0x24,0x90,0x03,0x63,0x34,0x00,0x00,0x62,0xac, -0x57,0x18,0x00,0x08,0x68,0x15,0x62,0x26,0x00,0x00,0x40,0xac,0x15,0x19,0x00,0x08, -0x68,0x15,0x62,0x26,0x02,0x00,0x03,0x24,0x90,0x03,0x42,0x34,0x00,0x00,0x43,0xac, -0x74,0x19,0x00,0x08,0x68,0x15,0x62,0x26,0x01,0x00,0x03,0x24,0x90,0x03,0x42,0x34, -0x00,0x00,0x43,0xac,0xd4,0x19,0x00,0x08,0x68,0x15,0x62,0x26,0xd0,0x03,0x03,0x35, -0x80,0x00,0x02,0x24,0x00,0x00,0x62,0xac,0x0a,0x1a,0x00,0x08,0x68,0x15,0x62,0x26, -0x25,0xb0,0x02,0x3c,0x07,0x00,0x03,0x24,0x90,0x03,0x42,0x34,0x00,0x00,0x43,0xac, -0x68,0x15,0x63,0x26,0x00,0x4b,0x62,0x8c,0x00,0x00,0x00,0x00,0x00,0x20,0x42,0x38, -0xe2,0x16,0x00,0x08,0x00,0x4b,0x62,0xac,0x25,0xb0,0x02,0x3c,0x07,0x00,0x03,0x24, -0x90,0x03,0x42,0x34,0x00,0x00,0x43,0xac,0x68,0x15,0x63,0x26,0x00,0x4b,0x62,0x8c, -0x00,0x00,0x00,0x00,0x00,0x80,0x42,0x38,0x40,0x17,0x00,0x08,0x00,0x4b,0x62,0xac, -0x06,0x00,0x03,0x24,0x90,0x03,0x42,0x34,0x00,0x00,0x43,0xac,0x99,0x17,0x00,0x08, -0x68,0x15,0x62,0x26,0x05,0x00,0x03,0x24,0x90,0x03,0x42,0x34,0x00,0x00,0x43,0xac, -0xf8,0x17,0x00,0x08,0x68,0x15,0x62,0x26,0x03,0x00,0x03,0x24,0x90,0x03,0x42,0x34, -0x00,0x00,0x43,0xac,0xb6,0x18,0x00,0x08,0x68,0x15,0x62,0x26,0x25,0xb0,0x0d,0x3c, -0x00,0x80,0x02,0x3c,0x18,0x03,0xa4,0x35,0xfc,0x69,0x42,0x24,0x02,0x80,0x03,0x3c, -0x41,0xb0,0x08,0x3c,0x00,0x00,0x82,0xac,0x68,0x15,0x6a,0x24,0x0a,0x00,0x02,0x35, -0x00,0x00,0x44,0x94,0x0a,0x4b,0x43,0x95,0x08,0x4b,0x4b,0x95,0x25,0x18,0x64,0x00, -0xff,0xff,0x6c,0x30,0x24,0x10,0x8b,0x01,0x02,0x00,0x42,0x30,0x4d,0x00,0x40,0x10, -0x02,0x00,0x64,0x38,0x02,0x00,0x02,0x24,0xc0,0x03,0xa3,0x35,0x00,0x00,0x62,0xac, -0x0a,0x4b,0x44,0xa5,0x24,0x38,0x8b,0x01,0x04,0x00,0xe2,0x30,0x0a,0x00,0x40,0x10, -0x08,0x00,0xe2,0x30,0x0a,0x4b,0x43,0x95,0x0c,0x00,0x04,0x35,0xc0,0x03,0xa5,0x35, -0x04,0x00,0x63,0x38,0x04,0x00,0x02,0x24,0x00,0x00,0x86,0x8c,0x00,0x00,0xa2,0xac, -0x0a,0x4b,0x43,0xa5,0x08,0x00,0xe2,0x30,0x08,0x00,0x40,0x10,0x10,0x00,0xe2,0x30, -0x0a,0x4b,0x42,0x95,0xc0,0x03,0xa4,0x35,0x08,0x00,0x03,0x24,0x08,0x00,0x42,0x38, -0x00,0x00,0x83,0xac,0x0a,0x4b,0x42,0xa5,0x10,0x00,0xe2,0x30,0x08,0x00,0x40,0x10, -0x20,0x00,0xe2,0x30,0x0a,0x4b,0x42,0x95,0xc0,0x03,0xa4,0x35,0x10,0x00,0x03,0x24, -0x10,0x00,0x42,0x38,0x00,0x00,0x83,0xac,0x0a,0x4b,0x42,0xa5,0x20,0x00,0xe2,0x30, -0x08,0x00,0x40,0x10,0x80,0x00,0xe2,0x30,0x0a,0x4b,0x42,0x95,0xc0,0x03,0xa4,0x35, -0x20,0x00,0x03,0x24,0x20,0x00,0x42,0x38,0x00,0x00,0x83,0xac,0x0a,0x4b,0x42,0xa5, -0x80,0x00,0xe2,0x30,0x15,0x00,0x40,0x10,0x24,0x10,0x8b,0x01,0x02,0x80,0x09,0x3c, -0x0a,0x4b,0x46,0x95,0x6c,0x7e,0x25,0x8d,0x08,0x00,0x02,0x3c,0x7f,0xff,0x04,0x24, -0x24,0x20,0x64,0x01,0x25,0x28,0xa2,0x00,0x80,0x00,0xc6,0x38,0xb0,0x03,0xa7,0x35, -0x08,0x00,0x08,0x35,0xc0,0x03,0xa3,0x35,0x80,0x00,0x02,0x24,0x00,0x00,0x62,0xac, -0x21,0x58,0x80,0x00,0x00,0x00,0xe5,0xac,0x0a,0x4b,0x46,0xa5,0x6c,0x7e,0x25,0xad, -0x00,0x00,0x04,0xa5,0x08,0x4b,0x44,0xa5,0x24,0x10,0x8b,0x01,0x00,0x30,0x42,0x30, -0x06,0x00,0x40,0x10,0x00,0x00,0x00,0x00,0x0a,0x4b,0x42,0x95,0x00,0x00,0x00,0x00, -0x00,0x10,0x42,0x38,0x00,0x20,0x42,0x34,0x0a,0x4b,0x42,0xa5,0x08,0x00,0xe0,0x03, -0x00,0x00,0x00,0x00,0x95,0x1a,0x00,0x08,0x0a,0x4b,0x43,0xa5,0xf8,0xff,0xbd,0x27, -0x04,0x00,0xb1,0xaf,0x00,0x00,0xb0,0xaf,0x00,0x40,0x02,0x40,0x00,0x68,0x08,0x40, -0x00,0x70,0x02,0x40,0x00,0x60,0x09,0x40,0x25,0xb0,0x05,0x3c,0x00,0x80,0x02,0x3c, -0x18,0x03,0xa3,0x34,0x7c,0x6b,0x42,0x24,0x00,0x00,0x62,0xac,0x80,0x00,0x87,0x8c, -0x7c,0x02,0xa2,0x34,0x84,0x02,0xa3,0x34,0x88,0x02,0xa6,0x34,0x00,0x00,0x47,0xac, -0x00,0x00,0x68,0xac,0x00,0x00,0xc9,0xac,0x74,0x00,0x83,0x8c,0x8c,0x02,0xa2,0x34, -0x90,0x02,0xa7,0x34,0x00,0x00,0x43,0xac,0x08,0x00,0x86,0x8c,0x94,0x02,0xa8,0x34, -0x98,0x02,0xa9,0x34,0x00,0x00,0xe6,0xac,0x0c,0x00,0x82,0x8c,0x9c,0x02,0xa6,0x34, -0xa0,0x02,0xa7,0x34,0x00,0x00,0x02,0xad,0x10,0x00,0x83,0x8c,0xa4,0x02,0xa8,0x34, -0xa8,0x02,0xaa,0x34,0x00,0x00,0x23,0xad,0x14,0x00,0x82,0x8c,0xac,0x02,0xa9,0x34, -0xb0,0x02,0xab,0x34,0x00,0x00,0xc2,0xac,0x18,0x00,0x83,0x8c,0xb4,0x02,0xa6,0x34, -0xb8,0x02,0xac,0x34,0x00,0x00,0xe3,0xac,0x1c,0x00,0x82,0x8c,0xbc,0x02,0xa7,0x34, -0xc0,0x02,0xad,0x34,0x00,0x00,0x02,0xad,0x20,0x00,0x83,0x8c,0xc4,0x02,0xa8,0x34, -0xc8,0x02,0xae,0x34,0x00,0x00,0x43,0xad,0x24,0x00,0x82,0x8c,0xcc,0x02,0xaa,0x34, -0xd0,0x02,0xaf,0x34,0x00,0x00,0x22,0xad,0x28,0x00,0x83,0x8c,0xd4,0x02,0xa9,0x34, -0xd8,0x02,0xb0,0x34,0x00,0x00,0x63,0xad,0x2c,0x00,0x82,0x8c,0x70,0x02,0xab,0x34, -0x74,0x02,0xb1,0x34,0x00,0x00,0xc2,0xac,0x30,0x00,0x83,0x8c,0x78,0x02,0xa5,0x34, -0x00,0x00,0x83,0xad,0x34,0x00,0x82,0x8c,0x00,0x00,0x00,0x00,0x00,0x00,0xe2,0xac, -0x38,0x00,0x83,0x8c,0x00,0x00,0x00,0x00,0x00,0x00,0xa3,0xad,0x3c,0x00,0x82,0x8c, -0x00,0x00,0x00,0x00,0x00,0x00,0x02,0xad,0x40,0x00,0x83,0x8c,0x00,0x00,0x00,0x00, -0x00,0x00,0xc3,0xad,0x44,0x00,0x82,0x8c,0x00,0x00,0x00,0x00,0x00,0x00,0x42,0xad, -0x48,0x00,0x83,0x8c,0x00,0x00,0x00,0x00,0x00,0x00,0xe3,0xad,0x4c,0x00,0x82,0x8c, -0x00,0x00,0x00,0x00,0x00,0x00,0x22,0xad,0x50,0x00,0x83,0x8c,0x00,0x00,0x00,0x00, -0x00,0x00,0x03,0xae,0x54,0x00,0x82,0x8c,0x00,0x00,0x00,0x00,0x00,0x00,0x62,0xad, -0x58,0x00,0x83,0x8c,0x00,0x00,0x00,0x00,0x00,0x00,0x23,0xae,0x5c,0x00,0x82,0x8c, -0x00,0x00,0x00,0x00,0x00,0x00,0xa2,0xac,0x42,0x1b,0x00,0x08,0x00,0x00,0x00,0x00, -0x00,0x80,0x1b,0x3c,0x10,0x6d,0x7b,0x27,0x25,0xb0,0x1a,0x3c,0x18,0x03,0x5a,0x27, -0x00,0x00,0x5b,0xaf,0x21,0xd8,0xa0,0x03,0x82,0xda,0x1b,0x00,0x80,0xda,0x1b,0x00, -0x08,0x00,0x7b,0x27,0x04,0x00,0x61,0xaf,0x08,0x00,0x62,0xaf,0x0c,0x00,0x63,0xaf, -0x10,0x00,0x64,0xaf,0x14,0x00,0x65,0xaf,0x18,0x00,0x66,0xaf,0x1c,0x00,0x67,0xaf, -0x20,0x00,0x68,0xaf,0x24,0x00,0x69,0xaf,0x28,0x00,0x6a,0xaf,0x2c,0x00,0x6b,0xaf, -0x30,0x00,0x6c,0xaf,0x34,0x00,0x6d,0xaf,0x38,0x00,0x6e,0xaf,0x3c,0x00,0x6f,0xaf, -0x12,0x40,0x00,0x00,0x10,0x48,0x00,0x00,0x00,0x70,0x0a,0x40,0x40,0x00,0x70,0xaf, -0x44,0x00,0x71,0xaf,0x48,0x00,0x72,0xaf,0x4c,0x00,0x73,0xaf,0x50,0x00,0x74,0xaf, -0x54,0x00,0x75,0xaf,0x58,0x00,0x76,0xaf,0x5c,0x00,0x77,0xaf,0x60,0x00,0x78,0xaf, -0x64,0x00,0x79,0xaf,0x68,0x00,0x7c,0xaf,0x6c,0x00,0x7d,0xaf,0x70,0x00,0x7e,0xaf, -0x74,0x00,0x7f,0xaf,0x78,0x00,0x68,0xaf,0x7c,0x00,0x69,0xaf,0x80,0x00,0x6a,0xaf, -0x00,0x68,0x1a,0x40,0x25,0xb0,0x1b,0x3c,0x1c,0x03,0x7b,0x37,0x00,0x00,0x00,0x00, -0x00,0x00,0x7a,0xaf,0x7f,0x00,0x5b,0x33,0x30,0x00,0x60,0x13,0x00,0x00,0x00,0x00, -0x25,0xb0,0x1b,0x3c,0x30,0x03,0x7b,0x37,0x00,0x00,0x00,0x00,0x00,0x00,0x7a,0xaf, -0x00,0x00,0x00,0x00,0x21,0xd8,0xa0,0x03,0x82,0xda,0x1b,0x00,0x80,0xda,0x1b,0x00, -0x08,0x00,0x7b,0x27,0x04,0x00,0x61,0xaf,0x08,0x00,0x62,0xaf,0x0c,0x00,0x63,0xaf, -0x10,0x00,0x64,0xaf,0x14,0x00,0x65,0xaf,0x18,0x00,0x66,0xaf,0x1c,0x00,0x67,0xaf, -0x20,0x00,0x68,0xaf,0x24,0x00,0x69,0xaf,0x28,0x00,0x6a,0xaf,0x2c,0x00,0x6b,0xaf, -0x30,0x00,0x6c,0xaf,0x34,0x00,0x6d,0xaf,0x38,0x00,0x6e,0xaf,0x3c,0x00,0x6f,0xaf, -0x12,0x40,0x00,0x00,0x10,0x48,0x00,0x00,0x00,0x70,0x0a,0x40,0x40,0x00,0x70,0xaf, -0x44,0x00,0x71,0xaf,0x48,0x00,0x72,0xaf,0x4c,0x00,0x73,0xaf,0x50,0x00,0x74,0xaf, -0x54,0x00,0x75,0xaf,0x58,0x00,0x76,0xaf,0x5c,0x00,0x77,0xaf,0x60,0x00,0x78,0xaf, -0x64,0x00,0x79,0xaf,0x68,0x00,0x7c,0xaf,0x6c,0x00,0x7d,0xaf,0x70,0x00,0x7e,0xaf, -0x74,0x00,0x7f,0xaf,0x78,0x00,0x68,0xaf,0x7c,0x00,0x69,0xaf,0x80,0x00,0x6a,0xaf, -0xdf,0x1a,0x00,0x08,0x21,0x20,0x60,0x03,0x00,0x00,0x00,0x00,0x25,0xb0,0x08,0x3c, -0x20,0x03,0x08,0x35,0x00,0x00,0x00,0x00,0x00,0x00,0x1a,0xad,0x00,0x04,0x5b,0x33, -0x0a,0x00,0x60,0x13,0x00,0x00,0x00,0x00,0x00,0x80,0x08,0x3c,0x74,0x55,0x08,0x25, -0x00,0x00,0x00,0x00,0x25,0xb0,0x1b,0x3c,0x24,0x03,0x7b,0x37,0x00,0x00,0x00,0x00, -0x00,0x00,0x68,0xaf,0x09,0xf8,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x08,0x5b,0x33, -0x25,0xb0,0x08,0x3c,0x28,0x03,0x08,0x35,0x00,0x00,0x00,0x00,0x00,0x00,0x1b,0xad, -0x06,0x00,0x60,0x13,0x00,0x00,0x00,0x00,0x00,0x80,0x08,0x3c,0xfc,0x69,0x08,0x25, -0x00,0x00,0x00,0x00,0x09,0xf8,0x00,0x01,0x00,0x00,0x00,0x00,0x02,0x80,0x1a,0x3c, -0x6c,0x7e,0x5a,0x27,0x04,0x00,0x5b,0x97,0x25,0xb0,0x08,0x3c,0x30,0x03,0x08,0x35, -0x00,0x00,0x00,0x00,0x00,0x00,0x1b,0xad,0x18,0x00,0x60,0x13,0x00,0x00,0x00,0x00, -0x08,0xec,0x9b,0x27,0x00,0x00,0x00,0x00,0x04,0x00,0x61,0x8f,0xfc,0x03,0x70,0x7b, -0x7c,0x00,0x62,0x7b,0xbc,0x00,0x64,0x7b,0xfc,0x00,0x66,0x7b,0x3c,0x01,0x68,0x7b, -0x13,0x00,0x00,0x02,0x11,0x00,0x20,0x02,0x7c,0x01,0x6a,0x7b,0xbc,0x01,0x6c,0x7b, -0xfc,0x01,0x6e,0x7b,0x3c,0x02,0x70,0x7b,0x7c,0x02,0x72,0x7b,0xbc,0x02,0x74,0x7b, -0xfc,0x02,0x76,0x7b,0x3c,0x03,0x78,0x7b,0x7c,0x03,0x7c,0x7b,0xbc,0x03,0x7e,0x7b, -0x80,0x00,0x7b,0x8f,0x2f,0x1c,0x00,0x08,0x00,0x00,0x00,0x00,0x21,0xd8,0xa0,0x03, -0x82,0xda,0x1b,0x00,0x80,0xda,0x1b,0x00,0x08,0x00,0x7b,0x27,0x08,0x00,0x5b,0xaf, -0xfc,0xef,0x9d,0x27,0x00,0x00,0x4a,0x8f,0x00,0x00,0x00,0x00,0x21,0x00,0x40,0x11, -0x00,0x00,0x00,0x00,0x02,0x80,0x08,0x3c,0xcc,0x7d,0x08,0x25,0x21,0x48,0x00,0x00, -0x21,0x58,0x00,0x00,0x01,0x00,0x6b,0x25,0x1a,0x00,0x40,0x11,0x24,0x70,0x4b,0x01, -0x14,0x00,0xc0,0x11,0x01,0x00,0x04,0x24,0x00,0x00,0x00,0x00,0x04,0x00,0x44,0xa3, -0x26,0x50,0x4b,0x01,0x00,0x00,0x4a,0xaf,0x80,0x80,0x09,0x00,0x21,0x80,0x08,0x02, -0x00,0x00,0x10,0x8e,0x00,0x00,0x00,0x00,0x09,0xf8,0x00,0x02,0x00,0x00,0x00,0x00, -0x00,0x80,0x1b,0x3c,0xe8,0x6f,0x7b,0x27,0x25,0xb0,0x1a,0x3c,0x18,0x03,0x5a,0x27, -0x00,0x00,0x5b,0xaf,0x02,0x80,0x1a,0x3c,0x6c,0x7e,0x5a,0x27,0xe1,0xff,0x00,0x10, -0x00,0x00,0x00,0x00,0x01,0x00,0x29,0x25,0x40,0x58,0x0b,0x00,0xf2,0x1b,0x00,0x08, -0x00,0x00,0x00,0x00,0x02,0x80,0x1b,0x3c,0x6c,0x7e,0x7b,0x27,0x21,0x60,0x00,0x00, -0x04,0x00,0x6c,0xa7,0x08,0x00,0x7a,0x8f,0x00,0x00,0x00,0x00,0xf8,0xff,0x5a,0x27, -0x00,0x00,0x5a,0x8f,0x00,0x00,0x00,0x00,0x08,0x00,0x5a,0x27,0x84,0x00,0x44,0x8f, -0x00,0x00,0x00,0x00,0xf9,0xff,0x80,0x10,0x00,0x00,0x00,0x00,0x04,0x00,0x41,0x8f, -0xfc,0x03,0x50,0x7b,0x7c,0x00,0x42,0x7b,0xbc,0x00,0x44,0x7b,0xfc,0x00,0x46,0x7b, -0x3c,0x01,0x48,0x7b,0x13,0x00,0x00,0x02,0x11,0x00,0x20,0x02,0x7c,0x01,0x4a,0x7b, -0xbc,0x01,0x4c,0x7b,0xfc,0x01,0x4e,0x7b,0x3c,0x02,0x50,0x7b,0x7c,0x02,0x52,0x7b, -0xbc,0x02,0x54,0x7b,0xfc,0x02,0x56,0x7b,0x3c,0x03,0x58,0x7b,0x7c,0x03,0x5c,0x7b, -0xbc,0x03,0x5e,0x7b,0x80,0x00,0x5b,0x8f,0x00,0x00,0x00,0x00,0x08,0x00,0x60,0x03, -0x10,0x00,0x00,0x42,0x00,0x60,0x05,0x40,0x42,0x28,0x05,0x00,0x40,0x28,0x05,0x00, -0x00,0x60,0x85,0x40,0x04,0x00,0x81,0xac,0x08,0x00,0x82,0xac,0x0c,0x00,0x83,0xac, -0x20,0x00,0x88,0xac,0x24,0x00,0x89,0xac,0x28,0x00,0x8a,0xac,0x2c,0x00,0x8b,0xac, -0x30,0x00,0x8c,0xac,0x34,0x00,0x8d,0xac,0x38,0x00,0x8e,0xac,0x3c,0x00,0x8f,0xac, -0x12,0x40,0x00,0x00,0x10,0x48,0x00,0x00,0x40,0x00,0x90,0xac,0x44,0x00,0x91,0xac, -0x48,0x00,0x92,0xac,0x4c,0x00,0x93,0xac,0x50,0x00,0x94,0xac,0x54,0x00,0x95,0xac, -0x58,0x00,0x96,0xac,0x5c,0x00,0x97,0xac,0x60,0x00,0x98,0xac,0x64,0x00,0x99,0xac, -0x68,0x00,0x9c,0xac,0x6c,0x00,0x9d,0xac,0x70,0x00,0x9e,0xac,0x74,0x00,0x9f,0xac, -0x78,0x00,0x88,0xac,0x7c,0x00,0x89,0xac,0x80,0x00,0x9f,0xac,0xf8,0xff,0x84,0x24, -0x00,0x00,0x84,0x8c,0x00,0x00,0x00,0x00,0x08,0x00,0x84,0x24,0x84,0x00,0x86,0x8c, -0x00,0x00,0x00,0x00,0xf9,0xff,0xc0,0x10,0x00,0x00,0x00,0x00,0x21,0xd8,0x80,0x00, -0x01,0x00,0xba,0x24,0x04,0x00,0x61,0x8f,0xfc,0x03,0x70,0x7b,0x7c,0x00,0x62,0x7b, -0xbc,0x00,0x64,0x7b,0xfc,0x00,0x66,0x7b,0x3c,0x01,0x68,0x7b,0x13,0x00,0x00,0x02, -0x11,0x00,0x20,0x02,0x7c,0x01,0x6a,0x7b,0xbc,0x01,0x6c,0x7b,0xfc,0x01,0x6e,0x7b, -0x3c,0x02,0x70,0x7b,0x7c,0x02,0x72,0x7b,0xbc,0x02,0x74,0x7b,0xfc,0x02,0x76,0x7b, -0x3c,0x03,0x78,0x7b,0x7c,0x03,0x7c,0x7b,0xbc,0x03,0x7e,0x7b,0x80,0x00,0x7b,0x8f, -0x00,0x00,0x00,0x00,0x08,0x00,0x60,0x03,0x00,0x60,0x9a,0x40,0x00,0x60,0x05,0x40, -0x42,0x28,0x05,0x00,0x40,0x28,0x05,0x00,0x00,0x60,0x85,0x40,0x04,0x00,0x81,0xac, -0x08,0x00,0x82,0xac,0x0c,0x00,0x83,0xac,0x20,0x00,0x88,0xac,0x24,0x00,0x89,0xac, -0x28,0x00,0x8a,0xac,0x2c,0x00,0x8b,0xac,0x30,0x00,0x8c,0xac,0x34,0x00,0x8d,0xac, -0x38,0x00,0x8e,0xac,0x3c,0x00,0x8f,0xac,0x12,0x40,0x00,0x00,0x10,0x48,0x00,0x00, -0x40,0x00,0x90,0xac,0x44,0x00,0x91,0xac,0x48,0x00,0x92,0xac,0x4c,0x00,0x93,0xac, -0x50,0x00,0x94,0xac,0x54,0x00,0x94,0xac,0x58,0x00,0x96,0xac,0x5c,0x00,0x96,0xac, -0x60,0x00,0x98,0xac,0x64,0x00,0x99,0xac,0x68,0x00,0x9c,0xac,0x6c,0x00,0x9d,0xac, -0x70,0x00,0x9e,0xac,0x78,0x00,0x88,0xac,0x7c,0x00,0x89,0xac,0x80,0x00,0x9f,0xac, -0x84,0x00,0x80,0xac,0xf8,0xff,0x84,0x24,0x00,0x00,0x84,0x8c,0x00,0x00,0x00,0x00, -0x08,0x00,0x84,0x24,0x84,0x00,0x86,0x8c,0xfa,0xff,0xc0,0x10,0x00,0x00,0x00,0x00, -0x21,0xd8,0x80,0x00,0x01,0x00,0xba,0x24,0x04,0x00,0x61,0x8f,0xfc,0x03,0x70,0x7b, -0x7c,0x00,0x62,0x7b,0xbc,0x00,0x64,0x7b,0xfc,0x00,0x66,0x7b,0x3c,0x01,0x68,0x7b, -0x13,0x00,0x00,0x02,0x11,0x00,0x20,0x02,0x7c,0x01,0x6a,0x7b,0xbc,0x01,0x6c,0x7b, -0xfc,0x01,0x6e,0x7b,0x3c,0x02,0x70,0x7b,0x7c,0x02,0x72,0x7b,0xbc,0x02,0x74,0x7b, -0xfc,0x02,0x76,0x7b,0x3c,0x03,0x78,0x7b,0x7c,0x03,0x7c,0x7b,0xbc,0x03,0x7e,0x7b, -0x80,0x00,0x7b,0x8f,0x08,0x00,0x60,0x03,0x00,0x60,0x9a,0x40,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0xc6,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x1b,0x3c,0x00,0x00,0x7b,0x27, -0x25,0xb0,0x1a,0x3c,0x18,0x03,0x5a,0x27,0x00,0x00,0x5b,0xaf,0x00,0x00,0x05,0x24, -0x03,0x00,0xa4,0x24,0x00,0xa0,0x80,0x40,0x00,0xa0,0x84,0x40,0x01,0x80,0x04,0x3c, -0x98,0x03,0x84,0x24,0x08,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x01,0x80,0x1b,0x3c,0x98,0x03,0x7b,0x27,0x25,0xb0,0x1a,0x3c,0x18,0x03,0x5a,0x27, -0x00,0x00,0x5b,0xaf,0x02,0x80,0x1a,0x3c,0x00,0x00,0x5a,0x27,0xfc,0x03,0x5d,0x27, -0x02,0x80,0x1c,0x3c,0x00,0x14,0x9c,0x27,0x00,0xf0,0x08,0x3c,0x00,0x0c,0x08,0x35, -0x00,0x60,0x88,0x40,0x02,0x80,0x04,0x3c,0x00,0x00,0x84,0x24,0xff,0x7f,0x05,0x3c, -0xff,0xff,0xa5,0x34,0x24,0x20,0x85,0x00,0x00,0x20,0x84,0x4c,0xff,0xff,0x05,0x34, -0x21,0x28,0xa4,0x00,0x00,0x28,0x85,0x4c,0x00,0x80,0x04,0x3c,0x00,0x00,0x84,0x24, -0xff,0x7f,0x05,0x3c,0xff,0xff,0xa5,0x34,0x24,0x20,0x85,0x00,0x00,0x00,0x84,0x4c, -0xff,0x7f,0x06,0x24,0x21,0x30,0xc4,0x00,0x24,0x30,0xc5,0x00,0x00,0x08,0x86,0x4c, -0x00,0xa0,0x04,0x40,0x10,0x00,0x84,0x34,0x00,0xa0,0x84,0x40,0x01,0x80,0x1b,0x3c, -0x24,0x04,0x7b,0x27,0x25,0xb0,0x1a,0x3c,0x18,0x03,0x5a,0x27,0x00,0x00,0x5b,0xaf, -0x00,0x00,0x00,0x00,0x25,0xb0,0x04,0x3c,0x44,0x00,0x84,0x34,0x00,0x00,0x85,0x84, -0x20,0x00,0x06,0x24,0x25,0x28,0xa6,0x00,0x00,0x00,0x85,0xa4,0x01,0x80,0x1b,0x3c, -0x54,0x04,0x7b,0x27,0x25,0xb0,0x1a,0x3c,0x18,0x03,0x5a,0x27,0x00,0x00,0x5b,0xaf, -0x25,0xb0,0x04,0x3c,0x44,0x00,0x84,0x34,0x00,0x00,0x85,0x8c,0x00,0x00,0x00,0x00, -0x10,0x00,0xa5,0x30,0xfc,0xff,0xa0,0x10,0x00,0x00,0x00,0x00,0xff,0x1f,0x07,0x3c, -0xff,0xff,0xe7,0x34,0x02,0x80,0x05,0x3c,0x88,0x7d,0xa5,0x24,0xff,0xff,0xa5,0x30, -0x40,0xb0,0x04,0x3c,0x25,0x28,0xa4,0x00,0x24,0x28,0xa7,0x00,0x21,0x30,0x00,0x00, -0x43,0xb0,0x02,0x3c,0x00,0x80,0x04,0x3c,0x40,0x00,0x84,0x34,0x00,0x00,0x45,0xac, -0x04,0x00,0x46,0xac,0x08,0x00,0x44,0xac,0x4e,0x58,0x00,0x08,0x00,0x00,0x00,0x00, -0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x09,0x00,0x02,0x24,0xff,0xff,0x42,0x24, -0xff,0xff,0x41,0x04,0xff,0xff,0x42,0x24,0x08,0x00,0xe0,0x03,0x01,0x00,0x42,0x24, -0x00,0x60,0x02,0x40,0x01,0x00,0x41,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40, -0x08,0x00,0xe0,0x03,0x00,0x00,0x82,0xac,0x00,0x00,0x82,0x8c,0x00,0x00,0x00,0x00, -0x21,0x18,0x40,0x00,0x00,0x60,0x83,0x40,0x08,0x00,0xe0,0x03,0x00,0x00,0x82,0xac, -0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,0x08,0x00,0xe0,0x03, -0x00,0x00,0x00,0x00,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38, -0x00,0x60,0x81,0x40,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x01,0x80,0x03,0x3c, -0x25,0xb0,0x02,0x3c,0x44,0x05,0x63,0x24,0x18,0x03,0x42,0x34,0x00,0x00,0x43,0xac, -0x04,0x00,0x85,0x8c,0x00,0x80,0x03,0x3c,0x01,0x00,0x02,0x24,0x25,0x28,0xa3,0x00, -0x00,0x00,0xa4,0x8c,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x01,0x80,0x03,0x3c, -0x25,0xb0,0x02,0x3c,0x74,0x05,0x63,0x24,0x18,0x03,0x42,0x34,0x00,0x00,0x43,0xac, -0x04,0x00,0x82,0x8c,0x02,0x00,0x83,0x94,0x00,0x80,0x07,0x3c,0x25,0x28,0x47,0x00, -0x00,0x00,0xa2,0x8c,0x10,0x00,0x02,0x24,0x13,0x00,0x62,0x10,0x11,0x00,0x66,0x28, -0x06,0x00,0xc0,0x10,0x20,0x00,0x02,0x24,0x08,0x00,0x02,0x24,0x17,0x00,0x62,0x10, -0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x01,0x00,0x02,0x24,0xfd,0xff,0x62,0x14, -0x00,0x00,0x00,0x00,0x08,0x00,0x83,0x8c,0x00,0x00,0x00,0x00,0x00,0x00,0xa3,0xac, -0x04,0x00,0x82,0x8c,0x00,0x00,0x00,0x00,0x25,0x10,0x47,0x00,0x00,0x00,0x42,0x8c, -0x08,0x00,0xe0,0x03,0x01,0x00,0x02,0x24,0x08,0x00,0x82,0x8c,0x00,0x00,0x00,0x00, -0x00,0x00,0xa2,0xa4,0x04,0x00,0x83,0x8c,0x00,0x00,0x00,0x00,0x25,0x18,0x67,0x00, -0x00,0x00,0x62,0x94,0x08,0x00,0xe0,0x03,0x01,0x00,0x02,0x24,0x08,0x00,0x82,0x8c, -0x00,0x00,0x00,0x00,0x00,0x00,0xa2,0xa0,0x04,0x00,0x83,0x8c,0x00,0x00,0x00,0x00, -0x25,0x18,0x67,0x00,0x00,0x00,0x62,0x90,0x08,0x00,0xe0,0x03,0x01,0x00,0x02,0x24, -0xe0,0xff,0xbd,0x27,0x14,0x00,0xb1,0xaf,0x02,0x80,0x11,0x3c,0x1c,0x00,0xbf,0xaf, -0x18,0x00,0xb2,0xaf,0x10,0x00,0xb0,0xaf,0x68,0x15,0x31,0x26,0xe4,0x64,0x30,0x96, -0x02,0x80,0x02,0x3c,0x01,0x80,0x03,0x3c,0x25,0x80,0x02,0x02,0x25,0xb0,0x02,0x3c, -0x38,0x06,0x63,0x24,0x18,0x03,0x42,0x34,0x60,0x00,0x04,0x26,0x80,0x00,0x05,0x26, -0x00,0x00,0x43,0xac,0xab,0x45,0x00,0x0c,0x03,0x00,0x06,0x24,0x21,0x20,0x00,0x02, -0x21,0x28,0x00,0x00,0x97,0x45,0x00,0x0c,0x08,0x00,0x06,0x24,0xe4,0x64,0x22,0x8e, -0x0c,0x00,0x03,0x24,0x0c,0x00,0x43,0xae,0x08,0x00,0x42,0xae,0x12,0x00,0x02,0x24, -0x14,0x00,0x42,0xae,0x21,0x20,0x40,0x02,0x1c,0x00,0xbf,0x8f,0x18,0x00,0xb2,0x8f, -0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x8b,0x07,0x00,0x08,0x20,0x00,0xbd,0x27, -0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00, -0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00, -0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00, -0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00, -0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00, -0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00, -0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00, -0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00, -0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00, -0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x01,0x00,0x02,0x24, -0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x01,0x00,0x02,0x24, -0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00, -0x08,0x00,0xe0,0x03,0x01,0x00,0x02,0x24,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00, -0x08,0x00,0xe0,0x03,0x01,0x00,0x02,0x24,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00, -0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x01,0x00,0x02,0x24, -0x08,0x00,0xe0,0x03,0x01,0x00,0x02,0x24,0x02,0x80,0x02,0x3c,0x21,0x48,0x80,0x00, -0x68,0x15,0x48,0x24,0x21,0x38,0x00,0x00,0x21,0x28,0x27,0x01,0x00,0x00,0xa2,0x90, -0x21,0x20,0xe8,0x00,0x01,0x00,0xe7,0x24,0x38,0x4c,0x82,0xa0,0x1e,0x00,0xa3,0x90, -0x1e,0x00,0xe6,0x28,0x56,0x4c,0x83,0xa0,0x3c,0x00,0xa2,0x90,0x00,0x00,0x00,0x00, -0x74,0x4c,0x82,0xa0,0x5a,0x00,0xa3,0x90,0xf3,0xff,0xc0,0x14,0x92,0x4c,0x83,0xa0, -0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x01,0x00,0x02,0x24, -0x20,0xbd,0x03,0x3c,0x58,0x00,0x63,0x34,0x00,0x00,0x62,0x90,0x0f,0x27,0x07,0x24, -0x20,0x00,0x42,0x34,0x00,0x00,0x62,0xa0,0xff,0xff,0xe7,0x24,0xff,0xff,0xe1,0x04, -0xff,0xff,0xe7,0x24,0x62,0xbd,0x04,0x3c,0x24,0x10,0x82,0x34,0x00,0x00,0x40,0xa0, -0x28,0x10,0x83,0x34,0x0c,0x11,0x86,0x34,0x0e,0x00,0x02,0x24,0x00,0x00,0x60,0xa0, -0x00,0x11,0x85,0x34,0x00,0x00,0xc2,0xa0,0x00,0x00,0xa7,0x8c,0xdf,0xff,0x02,0x24, -0x10,0x00,0x86,0x34,0x24,0x38,0xe2,0x00,0x49,0x0c,0x03,0x24,0xcf,0xff,0x02,0x24, -0x00,0x00,0xc3,0xac,0x04,0x00,0x84,0x34,0x00,0x00,0xa7,0xac,0x24,0x38,0xe2,0x00, -0x41,0x0c,0x02,0x24,0x00,0x00,0xa7,0xac,0x00,0x00,0x80,0xac,0x00,0x00,0xc2,0xac, -0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0xd0,0xff,0xbd,0x27,0x25,0xb0,0x03,0x3c, -0x01,0x80,0x02,0x3c,0xb0,0x03,0x68,0x34,0x1c,0x00,0xb1,0xaf,0x18,0x03,0x63,0x34, -0xd8,0xff,0x91,0x24,0xa0,0x08,0x42,0x24,0x00,0x00,0x62,0xac,0x28,0x00,0xbf,0xaf, -0x00,0x00,0x11,0xad,0x24,0x00,0xb3,0xaf,0x20,0x00,0xb2,0xaf,0x18,0x00,0xb0,0xaf, -0x02,0x80,0x13,0x3c,0x00,0x00,0x23,0x96,0x68,0x15,0x73,0x26,0xff,0xff,0x32,0x32, -0x40,0x10,0x02,0x3c,0x78,0x64,0x65,0x8e,0x25,0x90,0x42,0x02,0x02,0x80,0x10,0x3c, -0x8c,0x96,0x10,0x26,0x20,0x00,0x42,0x26,0x00,0x00,0x03,0xad,0x20,0x00,0x06,0x24, -0x00,0x00,0x02,0xad,0x21,0x38,0x00,0x02,0x0c,0x00,0x03,0xae,0x0a,0x00,0x04,0x24, -0x64,0x01,0x00,0x0c,0x08,0x00,0x02,0xae,0x04,0x00,0x23,0x8e,0xff,0xe0,0x02,0x24, -0x28,0x00,0x04,0x24,0x24,0x18,0x62,0x00,0x00,0x10,0x63,0x34,0x02,0x00,0x24,0xa2, -0x04,0x00,0x23,0xae,0x0c,0x00,0x02,0x8e,0x0a,0x00,0x04,0x24,0xf8,0xff,0x42,0x24, -0x4d,0x01,0x00,0x0c,0x00,0x00,0x22,0xa6,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34, -0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x0c,0x00,0x07,0x8e,0x20,0x10,0x06,0x3c, -0x21,0x28,0x40,0x02,0x20,0x00,0xe7,0x24,0x00,0xfe,0xc6,0x34,0xff,0xff,0xe7,0x30, -0x01,0x00,0x11,0x24,0x0a,0x00,0x04,0x24,0x10,0x01,0x00,0x0c,0x10,0x00,0xb1,0xaf, -0xd5,0x4a,0x63,0x92,0x2a,0xb0,0x10,0x3c,0x32,0x00,0x02,0x36,0x01,0x00,0x63,0x24, -0x00,0x00,0x43,0xa0,0x4d,0x01,0x00,0x0c,0x0a,0x00,0x04,0x24,0xc9,0x64,0x62,0x92, -0x00,0x00,0x00,0x00,0x01,0x00,0x42,0x24,0xc9,0x64,0x62,0xa2,0x00,0x60,0x01,0x40, -0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,0x01,0x00,0x10,0x36,0x00,0x00,0x11,0xa2, -0x28,0x00,0xbf,0x8f,0x24,0x00,0xb3,0x8f,0x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f, -0x18,0x00,0xb0,0x8f,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x30,0x00,0xbd,0x27, -0x25,0xb0,0x05,0x3c,0x01,0x80,0x03,0x3c,0x21,0x38,0x80,0x00,0x18,0x03,0xa2,0x34, -0xe8,0x09,0x63,0x24,0x01,0x00,0x04,0x24,0x00,0x00,0x43,0xac,0x35,0x00,0xe4,0x10, -0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x10,0x20,0x08,0xa2,0x34,0x02,0x00,0x02,0x24, -0x83,0x00,0xe2,0x10,0x03,0x00,0x02,0x24,0x5a,0x00,0xe2,0x10,0x00,0x00,0x00,0x00, -0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x02,0x80,0x03,0x3c,0x00,0x00,0x44,0x8c, -0x68,0x15,0x66,0x24,0x70,0x08,0x02,0x24,0xe0,0x08,0x03,0x24,0x74,0x4b,0xc2,0xac, -0x40,0x08,0x02,0x24,0x78,0x4b,0xc3,0xac,0x84,0x4b,0xc2,0xac,0x78,0x08,0x03,0x24, -0x0c,0x08,0x02,0x24,0x88,0x4b,0xc3,0xac,0x8c,0x4b,0xc2,0xac,0x10,0x08,0x03,0x24, -0x20,0x08,0x02,0x24,0x90,0x4b,0xc3,0xac,0x94,0x4b,0xc2,0xac,0x24,0x08,0x03,0x24, -0x58,0x08,0x02,0x24,0x98,0x4b,0xc3,0xac,0x9c,0x4b,0xc2,0xac,0x50,0x0c,0x03,0x24, -0x54,0x0c,0x02,0x24,0xa0,0x4b,0xc3,0xac,0xa4,0x4b,0xc2,0xac,0x14,0x0c,0x03,0x24, -0x10,0x0c,0x02,0x24,0x60,0x08,0x05,0x24,0xa8,0x4b,0xc3,0xac,0xac,0x4b,0xc2,0xac, -0x80,0x0c,0x03,0x24,0x84,0x0c,0x02,0x24,0x00,0x01,0x84,0x30,0xb4,0x4b,0xc2,0xac, -0x80,0x4b,0xc5,0xac,0xb0,0x4b,0xc3,0xac,0x71,0x4b,0xc0,0xa0,0x7c,0x4b,0xc5,0xac, -0x02,0x00,0x80,0x10,0xa0,0x08,0x02,0x24,0xb8,0x08,0x02,0x24,0x08,0x00,0xe0,0x03, -0xb8,0x4b,0xc2,0xac,0x28,0x08,0xa2,0x34,0x02,0x80,0x03,0x3c,0x00,0x00,0x44,0x8c, -0x68,0x15,0x66,0x24,0x70,0x08,0x02,0x24,0xe0,0x08,0x03,0x24,0x74,0x4b,0xc2,0xac, -0x44,0x08,0x02,0x24,0x78,0x4b,0xc3,0xac,0x84,0x4b,0xc2,0xac,0x78,0x08,0x03,0x24, -0x0c,0x08,0x02,0x24,0x88,0x4b,0xc3,0xac,0x8c,0x4b,0xc2,0xac,0x14,0x08,0x03,0x24, -0x28,0x08,0x02,0x24,0x90,0x4b,0xc3,0xac,0x94,0x4b,0xc2,0xac,0x2c,0x08,0x03,0x24, -0x58,0x08,0x02,0x24,0x98,0x4b,0xc3,0xac,0x9c,0x4b,0xc2,0xac,0x58,0x0c,0x03,0x24, -0x5c,0x0c,0x02,0x24,0xa0,0x4b,0xc3,0xac,0xa4,0x4b,0xc2,0xac,0x1c,0x0c,0x03,0x24, -0x18,0x0c,0x02,0x24,0x64,0x08,0x05,0x24,0xa8,0x4b,0xc3,0xac,0xac,0x4b,0xc2,0xac, -0x88,0x0c,0x03,0x24,0x8c,0x0c,0x02,0x24,0x00,0x01,0x84,0x30,0xb4,0x4b,0xc2,0xac, -0x71,0x4b,0xc7,0xa0,0x80,0x4b,0xc5,0xac,0xb0,0x4b,0xc3,0xac,0x7c,0x4b,0xc5,0xac, -0xd6,0xff,0x80,0x10,0xa4,0x08,0x02,0x24,0xbc,0x08,0x02,0x24,0x08,0x00,0xe0,0x03, -0xb8,0x4b,0xc2,0xac,0x02,0x80,0x02,0x3c,0x68,0x15,0x42,0x24,0xac,0x08,0x03,0x24, -0xb8,0x4b,0x43,0xac,0x74,0x08,0x03,0x24,0xe4,0x08,0x04,0x24,0x74,0x4b,0x43,0xac, -0x4c,0x08,0x03,0x24,0x78,0x4b,0x44,0xac,0x84,0x4b,0x43,0xac,0x7c,0x08,0x04,0x24, -0x0c,0x08,0x03,0x24,0x88,0x4b,0x44,0xac,0x8c,0x4b,0x43,0xac,0x1c,0x08,0x04,0x24, -0x38,0x08,0x03,0x24,0x90,0x4b,0x44,0xac,0x94,0x4b,0x43,0xac,0x3c,0x08,0x04,0x24, -0x5c,0x08,0x03,0x24,0x98,0x4b,0x44,0xac,0x9c,0x4b,0x43,0xac,0x68,0x0c,0x04,0x24, -0x6c,0x0c,0x03,0x24,0xa0,0x4b,0x44,0xac,0xa4,0x4b,0x43,0xac,0x2c,0x0c,0x04,0x24, -0x28,0x0c,0x03,0x24,0x6c,0x08,0x05,0x24,0xa8,0x4b,0x44,0xac,0xac,0x4b,0x43,0xac, -0x98,0x0c,0x04,0x24,0x9c,0x0c,0x03,0x24,0x71,0x4b,0x47,0xa0,0x80,0x4b,0x45,0xac, -0xb0,0x4b,0x44,0xac,0xb4,0x4b,0x43,0xac,0x08,0x00,0xe0,0x03,0x7c,0x4b,0x45,0xac, -0x02,0x80,0x02,0x3c,0x68,0x15,0x42,0x24,0xa8,0x08,0x03,0x24,0xb8,0x4b,0x43,0xac, -0x74,0x08,0x03,0x24,0xe4,0x08,0x04,0x24,0x74,0x4b,0x43,0xac,0x48,0x08,0x03,0x24, -0x78,0x4b,0x44,0xac,0x84,0x4b,0x43,0xac,0x7c,0x08,0x04,0x24,0x0c,0x08,0x03,0x24, -0x88,0x4b,0x44,0xac,0x8c,0x4b,0x43,0xac,0x18,0x08,0x04,0x24,0x30,0x08,0x03,0x24, -0x90,0x4b,0x44,0xac,0x94,0x4b,0x43,0xac,0x34,0x08,0x04,0x24,0x5c,0x08,0x03,0x24, -0x98,0x4b,0x44,0xac,0x9c,0x4b,0x43,0xac,0x60,0x0c,0x04,0x24,0x64,0x0c,0x03,0x24, -0xa0,0x4b,0x44,0xac,0xa4,0x4b,0x43,0xac,0x24,0x0c,0x04,0x24,0x20,0x0c,0x03,0x24, -0x68,0x08,0x05,0x24,0xa8,0x4b,0x44,0xac,0xac,0x4b,0x43,0xac,0x90,0x0c,0x04,0x24, -0x94,0x0c,0x03,0x24,0x71,0x4b,0x47,0xa0,0x80,0x4b,0x45,0xac,0xb0,0x4b,0x44,0xac, -0xb4,0x4b,0x43,0xac,0x08,0x00,0xe0,0x03,0x7c,0x4b,0x45,0xac,0x36,0x43,0x00,0x08, -0x21,0x18,0x00,0x00,0x20,0x00,0x62,0x2c,0x06,0x00,0x40,0x10,0x00,0x00,0x00,0x00, -0x06,0x10,0x64,0x00,0x01,0x00,0x42,0x30,0xfa,0xff,0x40,0x10,0x01,0x00,0x63,0x24, -0xff,0xff,0x63,0x24,0x08,0x00,0xe0,0x03,0x21,0x10,0x60,0x00,0xd8,0xff,0xbd,0x27, -0x25,0xb0,0x02,0x3c,0x18,0x00,0xb2,0xaf,0x21,0x90,0x82,0x00,0xff,0xff,0x02,0x24, -0x1c,0x00,0xb3,0xaf,0x14,0x00,0xb1,0xaf,0x20,0x00,0xbf,0xaf,0x10,0x00,0xb0,0xaf, -0x21,0x88,0xa0,0x00,0x21,0x20,0xa0,0x00,0x21,0x18,0x40,0x02,0x10,0x00,0xa2,0x10, -0x21,0x98,0xc0,0x00,0x00,0x00,0x50,0x8e,0x31,0x43,0x00,0x0c,0x00,0x00,0x00,0x00, -0x04,0x10,0x53,0x00,0x27,0x18,0x11,0x00,0x25,0x18,0x62,0x00,0x24,0x18,0x70,0x00, -0x00,0x00,0x43,0xae,0x20,0x00,0xbf,0x8f,0x1c,0x00,0xb3,0x8f,0x18,0x00,0xb2,0x8f, -0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x28,0x00,0xbd,0x27, -0x20,0x00,0xbf,0x8f,0x1c,0x00,0xb3,0x8f,0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f, -0x10,0x00,0xb0,0x8f,0x28,0x00,0xbd,0x27,0x00,0x00,0x66,0xac,0x08,0x00,0xe0,0x03, -0x00,0x00,0x00,0x00,0x02,0x80,0x02,0x3c,0x21,0x30,0x80,0x00,0xec,0x60,0x44,0x8c, -0x3d,0x43,0x00,0x08,0xff,0xff,0x05,0x24,0xe0,0xff,0xbd,0x27,0x25,0xb0,0x02,0x3c, -0x18,0x00,0xbf,0xaf,0x14,0x00,0xb1,0xaf,0x10,0x00,0xb0,0xaf,0x21,0x20,0x82,0x00, -0x00,0x00,0x90,0x8c,0x21,0x88,0xa0,0x00,0x31,0x43,0x00,0x0c,0x21,0x20,0xa0,0x00, -0x24,0x80,0x11,0x02,0x06,0x10,0x50,0x00,0x18,0x00,0xbf,0x8f,0x14,0x00,0xb1,0x8f, -0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x20,0x00,0xbd,0x27,0xd0,0xff,0xbd,0x27, -0x14,0x00,0xb1,0xaf,0x02,0x80,0x11,0x3c,0x28,0x00,0xbf,0xaf,0x20,0x00,0xb4,0xaf, -0x1c,0x00,0xb3,0xaf,0x18,0x00,0xb2,0xaf,0x24,0x00,0xb5,0xaf,0x10,0x00,0xb0,0xaf, -0x68,0x15,0x31,0x26,0x98,0x4b,0x22,0x8e,0x25,0xb0,0x12,0x3c,0x24,0x08,0x53,0x36, -0x21,0x10,0x52,0x00,0x00,0x00,0x70,0x8e,0x00,0x00,0x55,0x8c,0x7f,0x80,0x03,0x3c, -0xff,0x7f,0x02,0x3c,0xff,0xff,0x63,0x34,0xff,0xff,0x42,0x34,0x24,0x10,0x02,0x02, -0x24,0x18,0xa3,0x02,0xc0,0x25,0x04,0x00,0x25,0x18,0x64,0x00,0x00,0x80,0x14,0x3c, -0x00,0x00,0x62,0xae,0x01,0x00,0x04,0x24,0x84,0x0a,0x00,0x0c,0x25,0xa8,0x74,0x00, -0x98,0x4b,0x22,0x8e,0x25,0x80,0x14,0x02,0x01,0x00,0x04,0x24,0x21,0x10,0x52,0x00, -0x00,0x00,0x55,0xac,0x84,0x0a,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0xae, -0x84,0x0a,0x00,0x0c,0x01,0x00,0x04,0x24,0xb8,0x4b,0x24,0x8e,0x0f,0x00,0x05,0x3c, -0x28,0x00,0xbf,0x8f,0x24,0x00,0xb5,0x8f,0x20,0x00,0xb4,0x8f,0x1c,0x00,0xb3,0x8f, -0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0xff,0xff,0xa5,0x34, -0x68,0x43,0x00,0x08,0x30,0x00,0xbd,0x27,0xe0,0xff,0xbd,0x27,0x14,0x00,0xb1,0xaf, -0x02,0x80,0x11,0x3c,0x10,0x00,0xb0,0xaf,0x18,0x00,0xbf,0xaf,0x68,0x15,0x27,0x26, -0x73,0x4b,0xe5,0x90,0x01,0x80,0x03,0x3c,0x25,0xb0,0x02,0x3c,0xb0,0x0e,0x63,0x24, -0x18,0x03,0x42,0x34,0x02,0x00,0x06,0x24,0x00,0x00,0x43,0xac,0x34,0x00,0xa6,0x10, -0x21,0x80,0x80,0x00,0x03,0x00,0x03,0x24,0x3a,0x00,0xa3,0x10,0x2e,0x00,0x02,0x2e, -0x10,0x00,0x02,0x2e,0x07,0x00,0x40,0x10,0x00,0x00,0x00,0x00,0xff,0x00,0x04,0x32, -0x18,0x00,0xbf,0x8f,0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x79,0x43,0x00,0x08, -0x20,0x00,0xbd,0x27,0xfa,0xff,0xa6,0x14,0xff,0x00,0x04,0x32,0x71,0x4b,0xe4,0x90, -0x01,0x00,0x02,0x24,0x33,0x00,0x82,0x10,0x02,0x00,0x82,0x28,0x38,0x00,0x40,0x14, -0x00,0x00,0x00,0x00,0x38,0x00,0x85,0x10,0x68,0x15,0x22,0x26,0x2e,0x00,0x83,0x10, -0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x24,0x68,0x43,0x00,0x0c,0xff,0xff,0x05,0x24, -0xff,0xfc,0x06,0x3c,0xff,0xff,0xc6,0x34,0x24,0x30,0x46,0x00,0x00,0x08,0x04,0x24, -0x3d,0x43,0x00,0x0c,0xff,0xff,0x05,0x24,0x68,0x15,0x22,0x26,0x71,0x4b,0x44,0x90, -0x01,0x00,0x03,0x24,0x07,0x00,0x83,0x10,0x02,0x00,0x82,0x28,0x2c,0x00,0x40,0x14, -0x02,0x00,0x02,0x24,0x2c,0x00,0x82,0x10,0x03,0x00,0x02,0x24,0xdb,0xff,0x82,0x14, -0x00,0x00,0x00,0x00,0x68,0x15,0x22,0x26,0x74,0x4b,0x44,0x8c,0x0f,0x00,0x05,0x3c, -0x3d,0x43,0x00,0x0c,0x21,0x30,0x00,0x00,0xc2,0x43,0x00,0x08,0xff,0x00,0x04,0x32, -0x25,0x00,0x82,0x2c,0xcc,0xff,0x40,0x14,0x03,0x00,0x03,0x24,0x18,0x00,0xbf,0x8f, -0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03, -0x20,0x00,0xbd,0x27,0xc7,0xff,0x40,0x14,0x10,0x00,0x02,0x2e,0x18,0x00,0xbf,0x8f, -0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03, -0x20,0x00,0xbd,0x27,0x68,0x15,0x22,0x26,0x74,0x4b,0x44,0x8c,0x0f,0x00,0x05,0x3c, -0x3d,0x43,0x00,0x0c,0x0f,0x00,0x06,0x24,0xd4,0x43,0x00,0x08,0x00,0x08,0x04,0x24, -0xcc,0xff,0x80,0x14,0x68,0x15,0x22,0x26,0x74,0x4b,0x44,0x8c,0x0f,0x00,0x05,0x24, -0x3d,0x43,0x00,0x0c,0x0f,0x00,0x06,0x24,0xd4,0x43,0x00,0x08,0x00,0x08,0x04,0x24, -0xb2,0xff,0x80,0x14,0x00,0x00,0x00,0x00,0x68,0x15,0x22,0x26,0x74,0x4b,0x44,0x8c, -0x0f,0x00,0x05,0x24,0x3d,0x43,0x00,0x0c,0x21,0x30,0x00,0x00,0xc2,0x43,0x00,0x08, -0xff,0x00,0x04,0x32,0xe0,0xff,0xbd,0x27,0x14,0x00,0xb1,0xaf,0x02,0x80,0x11,0x3c, -0x68,0x15,0x28,0x26,0x73,0x4b,0x06,0x91,0x01,0x80,0x03,0x3c,0x25,0xb0,0x02,0x3c, -0x5c,0x10,0x63,0x24,0x18,0x03,0x42,0x34,0x02,0x00,0x07,0x24,0x18,0x00,0xb2,0xaf, -0x10,0x00,0xb0,0xaf,0x1c,0x00,0xbf,0xaf,0x00,0x00,0x43,0xac,0x21,0x90,0xa0,0x00, -0x39,0x00,0xc7,0x10,0xff,0x00,0x90,0x30,0x03,0x00,0x03,0x24,0x3f,0x00,0xc3,0x10, -0x2e,0x00,0x02,0x2e,0x10,0x00,0x02,0x2e,0x0c,0x00,0x40,0x10,0x00,0x00,0x00,0x00, -0x0f,0x00,0x04,0x3c,0xff,0xff,0x84,0x34,0x24,0x20,0x44,0x02,0x00,0x15,0x10,0x00, -0x1c,0x00,0xbf,0x8f,0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f, -0x25,0x20,0x44,0x00,0x63,0x43,0x00,0x08,0x20,0x00,0xbd,0x27,0xf5,0xff,0xc7,0x14, -0x0f,0x00,0x04,0x3c,0x71,0x4b,0x04,0x91,0x01,0x00,0x02,0x24,0x33,0x00,0x82,0x10, -0x02,0x00,0x82,0x28,0x38,0x00,0x40,0x14,0x00,0x00,0x00,0x00,0x38,0x00,0x86,0x10, -0x68,0x15,0x22,0x26,0x2e,0x00,0x83,0x10,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x24, -0x68,0x43,0x00,0x0c,0xff,0xff,0x05,0x24,0xff,0xfc,0x06,0x3c,0xff,0xff,0xc6,0x34, -0x24,0x30,0x46,0x00,0x00,0x08,0x04,0x24,0x3d,0x43,0x00,0x0c,0xff,0xff,0x05,0x24, -0x68,0x15,0x22,0x26,0x71,0x4b,0x44,0x90,0x01,0x00,0x03,0x24,0x07,0x00,0x83,0x10, -0x02,0x00,0x82,0x28,0x2c,0x00,0x40,0x14,0x02,0x00,0x02,0x24,0x2c,0x00,0x82,0x10, -0x03,0x00,0x02,0x24,0xd6,0xff,0x82,0x14,0x00,0x00,0x00,0x00,0x68,0x15,0x22,0x26, -0x74,0x4b,0x44,0x8c,0x0f,0x00,0x05,0x3c,0x3d,0x43,0x00,0x0c,0x21,0x30,0x00,0x00, -0x2f,0x44,0x00,0x08,0x0f,0x00,0x04,0x3c,0x25,0x00,0x02,0x2e,0xc7,0xff,0x40,0x14, -0x03,0x00,0x03,0x24,0x1c,0x00,0xbf,0x8f,0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f, -0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x20,0x00,0xbd,0x27,0xc1,0xff,0x40,0x14, -0x00,0x00,0x00,0x00,0x1c,0x00,0xbf,0x8f,0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f, -0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x20,0x00,0xbd,0x27,0x68,0x15,0x22,0x26, -0x74,0x4b,0x44,0x8c,0x0f,0x00,0x05,0x3c,0x3d,0x43,0x00,0x0c,0x0f,0x00,0x06,0x24, -0x46,0x44,0x00,0x08,0x00,0x08,0x04,0x24,0xcc,0xff,0x80,0x14,0x68,0x15,0x22,0x26, -0x74,0x4b,0x44,0x8c,0x0f,0x00,0x05,0x24,0x3d,0x43,0x00,0x0c,0x0f,0x00,0x06,0x24, -0x46,0x44,0x00,0x08,0x00,0x08,0x04,0x24,0xad,0xff,0x80,0x14,0x00,0x00,0x00,0x00, -0x68,0x15,0x22,0x26,0x74,0x4b,0x44,0x8c,0x0f,0x00,0x05,0x24,0x3d,0x43,0x00,0x0c, -0x21,0x30,0x00,0x00,0x2f,0x44,0x00,0x08,0x0f,0x00,0x04,0x3c,0xe8,0xff,0xbd,0x27, -0x10,0x00,0xb0,0xaf,0x21,0x80,0x80,0x00,0x14,0x00,0xbf,0xaf,0x79,0x43,0x00,0x0c, -0x21,0x20,0x00,0x00,0x40,0x01,0x44,0x34,0x21,0x18,0x40,0x00,0x1f,0x00,0x02,0x2e, -0x00,0x23,0x04,0x00,0x10,0x00,0x40,0x10,0x10,0x00,0x05,0x2e,0x00,0x01,0x64,0x34, -0x06,0x00,0xa0,0x10,0x00,0x23,0x04,0x00,0x21,0x10,0x00,0x02,0x14,0x00,0xbf,0x8f, -0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x18,0x00,0xbd,0x27,0x63,0x43,0x00,0x0c, -0xf1,0xff,0x10,0x26,0x21,0x10,0x00,0x02,0x14,0x00,0xbf,0x8f,0x10,0x00,0xb0,0x8f, -0x08,0x00,0xe0,0x03,0x18,0x00,0xbd,0x27,0x63,0x43,0x00,0x0c,0xe2,0xff,0x10,0x26, -0x21,0x10,0x00,0x02,0x14,0x00,0xbf,0x8f,0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03, -0x18,0x00,0xbd,0x27,0x25,0xb0,0x02,0x3c,0x27,0x38,0x05,0x00,0x21,0x40,0x82,0x00, -0xff,0xff,0x02,0x24,0x07,0x00,0xa2,0x10,0x25,0x38,0xe6,0x00,0x00,0x00,0x02,0x8d, -0x00,0x00,0x00,0x00,0x24,0x10,0xe2,0x00,0x00,0x00,0x02,0xad,0x08,0x00,0xe0,0x03, -0x00,0x00,0x00,0x00,0x00,0x00,0x06,0xad,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00, -0x01,0x80,0x02,0x3c,0x25,0xb0,0x03,0x3c,0xe8,0x12,0x42,0x24,0x18,0x03,0x63,0x34, -0xd8,0xff,0xbd,0x27,0x00,0x00,0x62,0xac,0x0f,0x00,0x02,0x3c,0x14,0x00,0xb1,0xaf, -0xff,0xff,0x42,0x34,0x21,0x88,0xa0,0x00,0x1c,0x00,0xb3,0xaf,0x18,0x00,0xb2,0xaf, -0x20,0x00,0xbf,0xaf,0x10,0x00,0xb0,0xaf,0x21,0x90,0xc0,0x00,0x21,0x28,0xc0,0x00, -0x0a,0x00,0x22,0x12,0x21,0x98,0x80,0x00,0xac,0x43,0x00,0x0c,0x00,0x00,0x00,0x00, -0x21,0x20,0x20,0x02,0x31,0x43,0x00,0x0c,0x21,0x80,0x40,0x00,0x04,0x10,0x52,0x00, -0x27,0x28,0x11,0x00,0x25,0x28,0xa2,0x00,0x24,0x28,0xb0,0x00,0xff,0x00,0x64,0x32, -0x20,0x00,0xbf,0x8f,0x1c,0x00,0xb3,0x8f,0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f, -0x10,0x00,0xb0,0x8f,0x17,0x44,0x00,0x08,0x28,0x00,0xbd,0x27,0x01,0x80,0x03,0x3c, -0x25,0xb0,0x02,0x3c,0x74,0x13,0x63,0x24,0x18,0x03,0x42,0x34,0xe0,0xff,0xbd,0x27, -0x00,0x00,0x43,0xac,0x18,0x00,0xbf,0xaf,0x14,0x00,0xb1,0xaf,0x10,0x00,0xb0,0xaf, -0xac,0x43,0x00,0x0c,0x21,0x88,0xa0,0x00,0x21,0x80,0x40,0x00,0x31,0x43,0x00,0x0c, -0x21,0x20,0x20,0x02,0x24,0x80,0x11,0x02,0x06,0x10,0x50,0x00,0x18,0x00,0xbf,0x8f, -0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x20,0x00,0xbd,0x27, -0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00, -0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00, -0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00, -0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00, -0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00, -0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00, -0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00, -0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00, -0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00, -0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00, -0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00, -0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x01,0x00,0x02,0x24, -0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00, -0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00, -0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00, -0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00, -0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00, -0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00, -0xc8,0xff,0xbd,0x27,0x2c,0x00,0xb1,0xaf,0xff,0xff,0x05,0x24,0x21,0x88,0x80,0x00, -0x02,0x00,0x06,0x24,0x10,0x00,0xa4,0x27,0x34,0x00,0xbf,0xaf,0x30,0x00,0xb2,0xaf, -0x97,0x45,0x00,0x0c,0x28,0x00,0xb0,0xaf,0x08,0x00,0x30,0x96,0x02,0x80,0x02,0x3c, -0x21,0x28,0x00,0x00,0x25,0x80,0x02,0x02,0x21,0x20,0x00,0x02,0x97,0x45,0x00,0x0c, -0x10,0x00,0x06,0x24,0x20,0x00,0x02,0x96,0x24,0x00,0x04,0x26,0x10,0x00,0xa5,0x27, -0x03,0xff,0x42,0x30,0xc8,0x00,0x42,0x34,0x20,0x00,0x02,0xa6,0x9f,0x45,0x00,0x0c, -0x06,0x00,0x06,0x24,0x25,0xb0,0x03,0x3c,0x50,0x00,0x62,0x34,0x00,0x00,0x44,0x8c, -0x54,0x00,0x65,0x34,0x58,0x00,0x66,0x34,0x18,0x00,0xa4,0xaf,0x00,0x00,0xa2,0x8c, -0x5c,0x00,0x63,0x34,0x2a,0x00,0x04,0x26,0x1c,0x00,0xa2,0xaf,0x00,0x00,0xc7,0x8c, -0x18,0x00,0xa5,0x27,0x06,0x00,0x06,0x24,0x20,0x00,0xa7,0xaf,0x00,0x00,0x62,0x8c, -0x1a,0x00,0x12,0x24,0x9f,0x45,0x00,0x0c,0x24,0x00,0xa2,0xaf,0x30,0x00,0x04,0x26, -0x20,0x00,0xa5,0x27,0x9f,0x45,0x00,0x0c,0x06,0x00,0x06,0x24,0x13,0x00,0x03,0x24, -0x14,0x00,0x23,0xae,0x0c,0x00,0x32,0xae,0x08,0x00,0x05,0x8e,0x04,0x00,0x04,0x8e, -0xff,0xdf,0x02,0x3c,0x14,0x00,0x06,0x8e,0xff,0xff,0x42,0x34,0x10,0x00,0x07,0x8e, -0xff,0xe0,0x03,0x24,0x24,0x28,0xa2,0x00,0x00,0x40,0x02,0x3c,0x24,0x20,0x83,0x00, -0x25,0x28,0xa2,0x00,0xff,0x81,0x03,0x24,0xfe,0xff,0x02,0x3c,0x24,0x30,0xc3,0x00, -0xff,0xff,0x42,0x34,0x00,0x12,0x84,0x34,0x00,0x80,0x03,0x3c,0x24,0x20,0x82,0x00, -0x25,0x38,0xe3,0x00,0x00,0x26,0xc6,0x34,0x80,0x00,0xa5,0x34,0x20,0x00,0x02,0x24, -0x00,0x00,0x12,0xa6,0x10,0x00,0x07,0xae,0x02,0x00,0x02,0xa2,0x14,0x00,0x06,0xae, -0x04,0x00,0x04,0xae,0x08,0x00,0x05,0xae,0x34,0x00,0xbf,0x8f,0x30,0x00,0xb2,0x8f, -0x2c,0x00,0xb1,0x8f,0x28,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x38,0x00,0xbd,0x27, -0x93,0x45,0x00,0x08,0xff,0x00,0xa5,0x30,0x00,0x00,0x85,0xa0,0xff,0xff,0xc6,0x24, -0x01,0x00,0x84,0x24,0xfc,0xff,0xc0,0x14,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03, -0x00,0x00,0x00,0x00,0x05,0x00,0xc0,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x85,0xac, -0xff,0xff,0xc6,0x24,0xfd,0xff,0xc0,0x14,0x04,0x00,0x84,0x24,0x08,0x00,0xe0,0x03, -0x00,0x00,0x00,0x00,0x21,0x38,0x80,0x00,0x08,0x00,0xc0,0x10,0xff,0xff,0xc3,0x24, -0xff,0xff,0x06,0x24,0x00,0x00,0xa2,0x90,0xff,0xff,0x63,0x24,0x01,0x00,0xa5,0x24, -0x00,0x00,0xe2,0xa0,0xfb,0xff,0x66,0x14,0x01,0x00,0xe7,0x24,0x08,0x00,0xe0,0x03, -0x21,0x10,0x80,0x00,0x21,0x38,0x80,0x00,0x08,0x00,0xc0,0x10,0xff,0xff,0xc3,0x24, -0xff,0xff,0x06,0x24,0x00,0x00,0xa2,0x8c,0xff,0xff,0x63,0x24,0x04,0x00,0xa5,0x24, -0x00,0x00,0xe2,0xac,0xfb,0xff,0x66,0x14,0x04,0x00,0xe7,0x24,0x08,0x00,0xe0,0x03, -0x21,0x10,0x80,0x00,0x2b,0x10,0xa4,0x00,0x0d,0x00,0x40,0x14,0xff,0xff,0x02,0x24, -0xff,0xff,0xc6,0x24,0x08,0x00,0xc2,0x10,0x21,0x18,0x80,0x00,0xff,0xff,0x07,0x24, -0x00,0x00,0xa2,0x90,0xff,0xff,0xc6,0x24,0x01,0x00,0xa5,0x24,0x00,0x00,0x62,0xa0, -0xfb,0xff,0xc7,0x14,0x01,0x00,0x63,0x24,0x08,0x00,0xe0,0x03,0x21,0x10,0x80,0x00, -0x21,0x28,0xa6,0x00,0x21,0x18,0x86,0x00,0xff,0xff,0xc6,0x24,0xfa,0xff,0xc2,0x10, -0x00,0x00,0x00,0x00,0xff,0xff,0x07,0x24,0xff,0xff,0xa5,0x24,0x00,0x00,0xa2,0x90, -0xff,0xff,0x63,0x24,0xff,0xff,0xc6,0x24,0xfb,0xff,0xc7,0x14,0x00,0x00,0x62,0xa0, -0x08,0x00,0xe0,0x03,0x21,0x10,0x80,0x00,0x0c,0x00,0xc0,0x10,0x00,0x00,0x00,0x00, -0x00,0x00,0x82,0x90,0x00,0x00,0xa3,0x90,0x01,0x00,0x84,0x24,0x23,0x10,0x43,0x00, -0x00,0x16,0x02,0x00,0x03,0x16,0x02,0x00,0x04,0x00,0x40,0x14,0x01,0x00,0xa5,0x24, -0xff,0xff,0xc6,0x24,0xf6,0xff,0xc0,0x14,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03, -0x21,0x10,0xc0,0x00,0xea,0x45,0x00,0x08,0x21,0x18,0x86,0x00,0x00,0x00,0x82,0x90, -0x00,0x00,0x00,0x00,0x04,0x00,0x45,0x10,0x00,0x00,0x00,0x00,0x01,0x00,0x84,0x24, -0xfa,0xff,0x83,0x14,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x80,0x00, -0x09,0x00,0xc0,0x10,0xff,0xff,0xc3,0x24,0xff,0x00,0xa5,0x30,0xff,0xff,0x06,0x24, -0x00,0x00,0x82,0x90,0xff,0xff,0x63,0x24,0x05,0x00,0x45,0x10,0x01,0x00,0x84,0x24, -0xfb,0xff,0x66,0x14,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00, -0x08,0x00,0xe0,0x03,0xff,0xff,0x82,0x24,0x21,0x38,0x00,0x00,0x1f,0x00,0xc0,0x10, -0x21,0x18,0x00,0x00,0x02,0x80,0x02,0x3c,0x80,0x95,0x4b,0x24,0x00,0x00,0x87,0x90, -0x00,0x00,0xa3,0x90,0xff,0xff,0xc6,0x24,0x01,0x00,0x84,0x24,0x21,0x10,0xeb,0x00, -0x16,0x00,0xe0,0x10,0x01,0x00,0xa5,0x24,0x14,0x00,0x60,0x10,0x21,0x48,0x6b,0x00, -0x10,0x00,0xe3,0x10,0x20,0x00,0xe8,0x24,0x00,0x00,0x42,0x90,0x00,0x00,0x00,0x00, -0x01,0x00,0x42,0x30,0x02,0x00,0x40,0x10,0x20,0x00,0x6a,0x24,0xff,0x00,0x07,0x31, -0x00,0x00,0x22,0x91,0x00,0x00,0x00,0x00,0x01,0x00,0x42,0x30,0x02,0x00,0x40,0x10, -0xff,0x00,0xe7,0x30,0xff,0x00,0x43,0x31,0xff,0x00,0x63,0x30,0x03,0x00,0xe3,0x14, -0x00,0x00,0x00,0x00,0xe5,0xff,0xc0,0x14,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03, -0x23,0x10,0xe3,0x00,0x21,0x18,0x80,0x00,0x00,0x00,0xa2,0x90,0x01,0x00,0xa5,0x24, -0x00,0x00,0x82,0xa0,0xfc,0xff,0x40,0x14,0x01,0x00,0x84,0x24,0x08,0x00,0xe0,0x03, -0x21,0x10,0x60,0x00,0x21,0x38,0x80,0x00,0xff,0xff,0x03,0x24,0xff,0xff,0xc6,0x24, -0x06,0x00,0xc3,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0xa2,0x90,0x01,0x00,0xa5,0x24, -0x00,0x00,0x82,0xa0,0xf9,0xff,0x40,0x14,0x01,0x00,0x84,0x24,0x08,0x00,0xe0,0x03, -0x21,0x10,0xe0,0x00,0x00,0x00,0x82,0x80,0x39,0x46,0x00,0x08,0x21,0x18,0x80,0x00, -0x01,0x00,0x84,0x24,0x00,0x00,0x82,0x80,0x00,0x00,0x00,0x00,0xfc,0xff,0x40,0x14, -0x00,0x00,0x00,0x00,0x00,0x00,0xa2,0x90,0x01,0x00,0xa5,0x24,0x00,0x00,0x82,0xa0, -0xfc,0xff,0x40,0x14,0x01,0x00,0x84,0x24,0x08,0x00,0xe0,0x03,0x21,0x10,0x60,0x00, -0x12,0x00,0xc0,0x10,0x21,0x18,0x80,0x00,0x00,0x00,0x82,0x80,0x4a,0x46,0x00,0x08, -0x00,0x00,0x00,0x00,0x01,0x00,0x84,0x24,0x00,0x00,0x82,0x80,0x00,0x00,0x00,0x00, -0xfc,0xff,0x40,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0xa2,0x90,0x01,0x00,0xa5,0x24, -0x00,0x00,0x82,0xa0,0x05,0x00,0x40,0x10,0x01,0x00,0x84,0x24,0xff,0xff,0xc6,0x24, -0xf9,0xff,0xc0,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xa0,0x08,0x00,0xe0,0x03, -0x21,0x10,0x60,0x00,0x00,0x00,0x83,0x90,0x00,0x00,0xa2,0x90,0x01,0x00,0x84,0x24, -0x23,0x10,0x62,0x00,0x00,0x16,0x02,0x00,0x03,0x16,0x02,0x00,0x03,0x00,0x40,0x14, -0x01,0x00,0xa5,0x24,0xf7,0xff,0x60,0x14,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03, -0x00,0x00,0x00,0x00,0x21,0x10,0x00,0x00,0x0b,0x00,0xc0,0x10,0x00,0x00,0x00,0x00, -0x00,0x00,0xa2,0x90,0x00,0x00,0x83,0x90,0xff,0xff,0xc6,0x24,0x23,0x10,0x62,0x00, -0x00,0x16,0x02,0x00,0x03,0x16,0x02,0x00,0x03,0x00,0x40,0x14,0x01,0x00,0xa5,0x24, -0xf5,0xff,0x60,0x14,0x01,0x00,0x84,0x24,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00, -0x00,0x00,0x83,0x80,0x00,0x2e,0x05,0x00,0x21,0x10,0x80,0x00,0x7b,0x46,0x00,0x08, -0x03,0x2e,0x05,0x00,0x07,0x00,0x60,0x10,0x01,0x00,0x42,0x24,0x00,0x00,0x43,0x80, -0x00,0x00,0x00,0x00,0xfb,0xff,0x65,0x14,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03, -0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x00,0x00,0x82,0x80, -0x87,0x46,0x00,0x08,0x21,0x18,0x80,0x00,0x01,0x00,0x63,0x24,0x00,0x00,0x62,0x80, -0x00,0x00,0x00,0x00,0xfc,0xff,0x40,0x14,0x23,0x10,0x64,0x00,0x08,0x00,0xe0,0x03, -0x00,0x00,0x00,0x00,0xe0,0xff,0xbd,0x27,0x10,0x00,0xb0,0xaf,0x21,0x80,0xa0,0x00, -0x14,0x00,0xb1,0xaf,0x18,0x00,0xbf,0xaf,0x21,0x88,0x80,0x00,0x81,0x46,0x00,0x0c, -0x00,0x86,0x10,0x00,0x21,0x18,0x51,0x00,0x03,0x86,0x10,0x00,0x00,0x00,0x62,0x80, -0x00,0x00,0x00,0x00,0x0a,0x00,0x50,0x10,0x21,0x10,0x60,0x00,0xff,0xff,0x63,0x24, -0x2b,0x10,0x71,0x00,0xf9,0xff,0x40,0x10,0x21,0x10,0x00,0x00,0x18,0x00,0xbf,0x8f, -0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x20,0x00,0xbd,0x27, -0x18,0x00,0xbf,0x8f,0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03, -0x20,0x00,0xbd,0x27,0x21,0x30,0x80,0x00,0x0d,0x00,0xa0,0x10,0xff,0xff,0xa3,0x24, -0x00,0x00,0x82,0x80,0x00,0x00,0x00,0x00,0x09,0x00,0x40,0x10,0x00,0x00,0x00,0x00, -0xff,0xff,0x05,0x24,0xff,0xff,0x63,0x24,0x05,0x00,0x65,0x10,0x01,0x00,0xc6,0x24, -0x00,0x00,0xc2,0x80,0x00,0x00,0x00,0x00,0xfa,0xff,0x40,0x14,0x00,0x00,0x00,0x00, -0x08,0x00,0xe0,0x03,0x23,0x10,0xc4,0x00,0x00,0x00,0x82,0x90,0x00,0x00,0x00,0x00, -0x19,0x00,0x40,0x10,0x21,0x40,0x00,0x00,0x00,0x00,0xa9,0x80,0x00,0x00,0x00,0x00, -0x17,0x00,0x20,0x11,0x21,0x30,0xa0,0x00,0x00,0x3e,0x02,0x00,0x03,0x3e,0x07,0x00, -0x21,0x18,0x20,0x01,0x15,0x00,0xe3,0x10,0x00,0x00,0x00,0x00,0x01,0x00,0xc6,0x24, -0x00,0x00,0xc2,0x90,0x00,0x00,0x00,0x00,0x00,0x1e,0x02,0x00,0x03,0x1e,0x03,0x00, -0xf8,0xff,0x60,0x14,0x00,0x16,0x02,0x00,0x03,0x16,0x02,0x00,0x06,0x00,0x40,0x10, -0x00,0x00,0x00,0x00,0x01,0x00,0x84,0x24,0x00,0x00,0x82,0x90,0x00,0x00,0x00,0x00, -0xeb,0xff,0x40,0x14,0x01,0x00,0x08,0x25,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x01, -0x00,0x00,0xa2,0x90,0xcc,0x46,0x00,0x08,0x00,0x16,0x02,0x00,0x00,0x00,0xc2,0x90, -0xcc,0x46,0x00,0x08,0x00,0x16,0x02,0x00,0x00,0x00,0x87,0x90,0x00,0x00,0x00,0x00, -0x14,0x00,0xe0,0x10,0x21,0x10,0x80,0x00,0x00,0x00,0xa4,0x90,0x00,0x00,0x00,0x00, -0x00,0x1e,0x04,0x00,0x03,0x1e,0x03,0x00,0x09,0x00,0x60,0x10,0x21,0x30,0xa0,0x00, -0x00,0x3e,0x07,0x00,0x03,0x3e,0x07,0x00,0x0b,0x00,0xe3,0x10,0x01,0x00,0xc6,0x24, -0x00,0x00,0xc3,0x80,0x00,0x00,0x00,0x00,0xfb,0xff,0x60,0x14,0x00,0x00,0x00,0x00, -0x01,0x00,0x42,0x24,0x00,0x00,0x47,0x90,0x00,0x00,0x00,0x00,0xf0,0xff,0xe0,0x14, -0x00,0x00,0x00,0x00,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00, -0xe0,0xff,0xbd,0x27,0x14,0x00,0xb1,0xaf,0x10,0x00,0xb0,0xaf,0x18,0x00,0xbf,0xaf, -0x21,0x80,0x80,0x00,0x1d,0x00,0x80,0x10,0x21,0x88,0xa0,0x00,0xb8,0x46,0x00,0x0c, -0x21,0x20,0x00,0x02,0x21,0x80,0x02,0x02,0x00,0x00,0x02,0x82,0x21,0x28,0x20,0x02, -0x21,0x20,0x00,0x02,0x22,0x00,0x40,0x10,0x21,0x18,0x00,0x00,0xdc,0x46,0x00,0x0c, -0x00,0x00,0x00,0x00,0x05,0x00,0x40,0x10,0x21,0x18,0x40,0x00,0x00,0x00,0x42,0x80, -0x00,0x00,0x00,0x00,0x0a,0x00,0x40,0x14,0x00,0x00,0x00,0x00,0x02,0x80,0x02,0x3c, -0xa8,0x96,0x43,0xac,0x21,0x18,0x00,0x02,0x18,0x00,0xbf,0x8f,0x14,0x00,0xb1,0x8f, -0x10,0x00,0xb0,0x8f,0x21,0x10,0x60,0x00,0x08,0x00,0xe0,0x03,0x20,0x00,0xbd,0x27, -0x00,0x00,0x60,0xa0,0x0d,0x47,0x00,0x08,0x01,0x00,0x63,0x24,0x02,0x80,0x02,0x3c, -0xa8,0x96,0x50,0x8c,0x00,0x00,0x00,0x00,0xf3,0xff,0x00,0x12,0x21,0x18,0x00,0x00, -0xb8,0x46,0x00,0x0c,0x21,0x20,0x00,0x02,0x21,0x80,0x02,0x02,0x00,0x00,0x02,0x82, -0x21,0x28,0x20,0x02,0x21,0x20,0x00,0x02,0xe0,0xff,0x40,0x14,0x21,0x18,0x00,0x00, -0x18,0x00,0xbf,0x8f,0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x02,0x80,0x02,0x3c, -0xa8,0x96,0x40,0xac,0x20,0x00,0xbd,0x27,0x08,0x00,0xe0,0x03,0x21,0x10,0x60,0x00, -0xe0,0xff,0xbd,0x27,0x18,0x00,0xb2,0xaf,0x14,0x00,0xb1,0xaf,0x1c,0x00,0xbf,0xaf, -0x10,0x00,0xb0,0xaf,0x00,0x00,0x90,0x8c,0x21,0x90,0x80,0x00,0x21,0x88,0xa0,0x00, -0x21,0x18,0x00,0x00,0x0f,0x00,0x00,0x12,0x21,0x20,0x00,0x02,0xb8,0x46,0x00,0x0c, -0x00,0x00,0x00,0x00,0x21,0x80,0x02,0x02,0x00,0x00,0x02,0x82,0x21,0x28,0x20,0x02, -0x21,0x20,0x00,0x02,0x07,0x00,0x40,0x10,0x21,0x18,0x00,0x00,0xdc,0x46,0x00,0x0c, -0x00,0x00,0x00,0x00,0x21,0x18,0x40,0x00,0x09,0x00,0x40,0x14,0x00,0x00,0x42,0xae, -0x21,0x18,0x00,0x02,0x1c,0x00,0xbf,0x8f,0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f, -0x10,0x00,0xb0,0x8f,0x21,0x10,0x60,0x00,0x08,0x00,0xe0,0x03,0x20,0x00,0xbd,0x27, -0x00,0x00,0x42,0x80,0x00,0x00,0x00,0x00,0xf5,0xff,0x40,0x10,0x01,0x00,0x64,0x24, -0x00,0x00,0x60,0xa0,0x46,0x47,0x00,0x08,0x00,0x00,0x44,0xae,0xd8,0xff,0xbd,0x27, -0x14,0x00,0xb1,0xaf,0x21,0x88,0x80,0x00,0x21,0x20,0xa0,0x00,0x1c,0x00,0xb3,0xaf, -0x18,0x00,0xb2,0xaf,0x20,0x00,0xbf,0xaf,0x10,0x00,0xb0,0xaf,0x81,0x46,0x00,0x0c, -0x21,0x98,0xa0,0x00,0x21,0x90,0x40,0x00,0x08,0x00,0x40,0x16,0x21,0x10,0x20,0x02, -0x20,0x00,0xbf,0x8f,0x1c,0x00,0xb3,0x8f,0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f, -0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x28,0x00,0xbd,0x27,0x81,0x46,0x00,0x0c, -0x21,0x20,0x20,0x02,0x21,0x80,0x40,0x00,0x2a,0x10,0x52,0x00,0x0a,0x00,0x40,0x14, -0x00,0x00,0x00,0x00,0x21,0x20,0x20,0x02,0x21,0x28,0x60,0x02,0x21,0x30,0x40,0x02, -0xd4,0x45,0x00,0x0c,0xff,0xff,0x10,0x26,0x0b,0x00,0x40,0x10,0x2a,0x18,0x12,0x02, -0xf8,0xff,0x60,0x10,0x01,0x00,0x31,0x26,0x20,0x00,0xbf,0x8f,0x1c,0x00,0xb3,0x8f, -0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x21,0x10,0x00,0x00, -0x08,0x00,0xe0,0x03,0x28,0x00,0xbd,0x27,0x62,0x47,0x00,0x08,0x21,0x10,0x20,0x02, -0x01,0x80,0x02,0x3c,0xc0,0xff,0xbd,0x27,0x08,0x1e,0x44,0x24,0x25,0xb0,0x02,0x3c, -0x28,0x00,0xb4,0xaf,0x02,0x80,0x03,0x3c,0x25,0xb0,0x14,0x3c,0x18,0x03,0x42,0x34, -0x38,0x00,0xbe,0xaf,0x34,0x00,0xb7,0xaf,0x30,0x00,0xb6,0xaf,0x2c,0x00,0xb5,0xaf, -0x24,0x00,0xb3,0xaf,0x3c,0x00,0xbf,0xaf,0x20,0x00,0xb2,0xaf,0x1c,0x00,0xb1,0xaf, -0x18,0x00,0xb0,0xaf,0x68,0x15,0x73,0x24,0x00,0x00,0x44,0xac,0x02,0x80,0x16,0x3c, -0x02,0x80,0x15,0x3c,0xc4,0x02,0x9e,0x36,0x64,0x03,0x97,0x36,0x01,0x80,0x04,0x3c, -0x08,0x1e,0x82,0x24,0x18,0x03,0x83,0x36,0x00,0x00,0x62,0xac,0xa0,0x02,0x87,0x36, -0x00,0x00,0xe4,0x8c,0xd8,0x63,0x63,0x8e,0xff,0x0f,0x02,0x3c,0xff,0xff,0x46,0x34, -0x24,0x80,0x86,0x00,0x01,0x00,0x05,0x3c,0x01,0x00,0x63,0x24,0x2b,0x10,0xb0,0x00, -0x07,0x00,0x40,0x10,0xd8,0x63,0x63,0xae,0xa4,0x02,0x82,0x36,0x00,0x00,0x51,0x8c, -0x00,0xb0,0x03,0x3c,0x25,0x80,0x03,0x02,0x00,0x00,0x11,0xae,0x00,0x00,0xe0,0xac, -0xb0,0x02,0x84,0x36,0x00,0x00,0x82,0x8c,0x00,0x00,0x00,0x00,0x24,0x80,0x46,0x00, -0x2b,0x18,0xb0,0x00,0x08,0x00,0x60,0x10,0xc0,0x02,0x82,0x36,0x00,0xb0,0x02,0x3c, -0x25,0x80,0x02,0x02,0x00,0x00,0x11,0x8e,0xb4,0x02,0x82,0x36,0x00,0x00,0x51,0xac, -0x00,0x00,0x80,0xac,0xc0,0x02,0x82,0x36,0x00,0x00,0x50,0x8c,0xff,0x00,0x08,0x3c, -0xff,0xff,0x02,0x35,0x2b,0x10,0x50,0x00,0x47,0x00,0x40,0x10,0x00,0x00,0x00,0x00, -0x00,0x00,0x82,0x8e,0x00,0xff,0x06,0x3c,0xac,0x02,0x84,0x36,0x01,0x00,0x45,0x24, -0xbc,0x02,0x83,0x36,0xff,0x00,0xc2,0x34,0x00,0xfd,0x07,0x3c,0x00,0x00,0x85,0xac, -0x00,0x00,0x70,0xac,0x24,0x18,0x02,0x02,0x07,0x00,0xe2,0x34,0x00,0x00,0x85,0x8c, -0x52,0x03,0x62,0x10,0x25,0xb0,0x12,0x3c,0x2b,0x10,0x43,0x00,0xa2,0x00,0x40,0x14, -0xa4,0x00,0xe2,0x34,0x00,0xf8,0x04,0x3c,0x15,0x00,0x82,0x34,0x57,0x03,0x62,0x10, -0x2b,0x10,0x43,0x00,0xc8,0x00,0x40,0x14,0x00,0xf9,0x05,0x3c,0x00,0xf0,0x05,0x3c, -0x20,0x00,0xa2,0x34,0x67,0x03,0x62,0x10,0x2b,0x10,0x43,0x00,0x20,0x01,0x40,0x14, -0x10,0x00,0x82,0x34,0x70,0x03,0x65,0x10,0x2b,0x10,0xa3,0x00,0xc8,0x01,0x40,0x14, -0x02,0x00,0xa2,0x34,0x00,0xd0,0x02,0x3c,0x2a,0x02,0x62,0x10,0x2b,0x10,0x43,0x00, -0xaf,0x02,0x40,0x14,0x00,0xe0,0x02,0x3c,0x00,0xc0,0x02,0x3c,0xbb,0x03,0x62,0x10, -0xff,0x00,0x03,0x3c,0x00,0xf0,0x02,0x3c,0x24,0x30,0x02,0x02,0x18,0x00,0xc2,0x10, -0x02,0x1d,0x10,0x00,0x00,0x70,0x05,0x3c,0x24,0x10,0x05,0x02,0x02,0x4f,0x02,0x00, -0x0f,0x00,0x02,0x3c,0xff,0xff,0x42,0x34,0x00,0x50,0x07,0x3c,0xff,0x00,0x68,0x30, -0xff,0x00,0x04,0x32,0x96,0x01,0xc7,0x10,0x24,0x18,0x02,0x02,0x2b,0x10,0xe6,0x00, -0x8a,0x01,0x40,0x14,0x00,0x80,0x02,0x3c,0x00,0x20,0x02,0x3c,0x1a,0x03,0xc2,0x10, -0x2b,0x10,0x46,0x00,0x82,0x02,0x40,0x14,0x00,0x30,0x02,0x3c,0x17,0x03,0xc0,0x10, -0x80,0x10,0x08,0x00,0x00,0x10,0x02,0x3c,0x14,0x03,0xc2,0x10,0x80,0x10,0x08,0x00, -0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34, -0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x00,0x00,0xe2,0x92,0x25,0xb0,0x07,0x3c, -0xc8,0x7d,0xc2,0xa2,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40, -0xc8,0x7d,0xc2,0x92,0x00,0x00,0x00,0x00,0x01,0x00,0x42,0x30,0x4e,0x00,0x40,0x10, -0x02,0x80,0x03,0x3c,0x00,0x40,0x62,0x8e,0xf0,0xff,0x03,0x24,0xd7,0x42,0x60,0xa2, -0x24,0x10,0x43,0x00,0x01,0x00,0x42,0x34,0x00,0x40,0x62,0xae,0xc8,0x7d,0xc2,0x92, -0x00,0x00,0x00,0x00,0x02,0x00,0x42,0x30,0x3d,0x00,0x40,0x10,0x0f,0xff,0x03,0x24, -0x00,0x40,0x62,0x8e,0x00,0x00,0x00,0x00,0x24,0x10,0x43,0x00,0x10,0x00,0x42,0x34, -0x00,0x40,0x62,0xae,0xc8,0x7d,0xc2,0x92,0x00,0x00,0x00,0x00,0x04,0x00,0x42,0x30, -0x30,0x00,0x40,0x10,0xff,0xf0,0x03,0x24,0x00,0x40,0x62,0x8e,0x00,0x00,0x00,0x00, -0x24,0x10,0x43,0x00,0x00,0x01,0x42,0x34,0x25,0xb0,0x05,0x3c,0x00,0x40,0x62,0xae, -0x4c,0x00,0xa3,0x34,0x00,0x00,0x62,0x90,0x00,0x00,0x00,0x00,0x03,0x00,0x42,0x30, -0x05,0x00,0x40,0x14,0xff,0xff,0x02,0x3c,0x00,0x40,0x63,0x8e,0xff,0x0f,0x42,0x34, -0x24,0x18,0x62,0x00,0x00,0x40,0x63,0xae,0x00,0x7b,0xa4,0x8e,0x01,0x80,0x06,0x3c, -0x08,0x1f,0xc2,0x24,0x18,0x03,0xa3,0x34,0x00,0x7b,0xa6,0x26,0x00,0x00,0x62,0xac, -0x10,0x00,0x86,0x10,0x02,0x80,0x02,0x3c,0xbf,0x00,0xb2,0x34,0x68,0x15,0x51,0x24, -0x21,0x80,0xc0,0x00,0x00,0x00,0x42,0x92,0x00,0x00,0x00,0x00,0x04,0x00,0x42,0x2c, -0x09,0x00,0x40,0x10,0x02,0x80,0x07,0x3c,0x98,0x65,0x24,0x8e,0x8b,0x07,0x00,0x0c, -0x00,0x00,0x00,0x00,0x00,0x7b,0xa2,0x8e,0x00,0x00,0x00,0x00,0xf5,0xff,0x50,0x14, -0x00,0x00,0x00,0x00,0x02,0x80,0x07,0x3c,0x08,0x08,0xe4,0x24,0x21,0x28,0x00,0x00, -0x21,0x30,0x00,0x00,0x31,0x1c,0x00,0x0c,0x21,0x38,0x00,0x00,0x9a,0x47,0x00,0x08, -0x01,0x80,0x04,0x3c,0x00,0x40,0x62,0x8e,0x30,0x48,0x00,0x08,0x24,0x10,0x43,0x00, -0x00,0x40,0x62,0x8e,0x04,0x43,0x64,0x92,0x24,0x10,0x43,0x00,0x00,0x40,0x62,0xae, -0x27,0x48,0x00,0x08,0x04,0x43,0x64,0xae,0x68,0x15,0x66,0x24,0x00,0x40,0xc2,0x8c, -0xd7,0x42,0xc4,0x90,0xf0,0xff,0x03,0x24,0x24,0x10,0x43,0x00,0xb3,0xff,0x80,0x14, -0x00,0x40,0xc2,0xac,0x1c,0x00,0x04,0x24,0x58,0x0c,0xe5,0x34,0x50,0x0c,0xe3,0x34, -0x01,0x00,0x02,0x24,0xd7,0x42,0xc2,0xa0,0x00,0x00,0x64,0xa0,0x00,0x00,0xa4,0xa0, -0x1d,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xb2,0x02,0x62,0x10,0x2b,0x10,0x43,0x00, -0x3f,0x00,0x40,0x14,0xaf,0x00,0xe2,0x34,0x20,0x00,0xe2,0x34,0xc0,0x02,0x62,0x10, -0x2b,0x10,0x43,0x00,0xe3,0x00,0x40,0x14,0x29,0x00,0xe2,0x34,0x15,0x00,0xe2,0x34, -0x0c,0x03,0x62,0x10,0x2b,0x10,0x43,0x00,0x9d,0x01,0x40,0x14,0x17,0x00,0xe2,0x34, -0x09,0x00,0xe2,0x34,0xd8,0x03,0x62,0x10,0x2b,0x10,0x62,0x00,0x81,0x02,0x40,0x14, -0x14,0x00,0xe2,0x34,0x64,0xff,0x62,0x14,0x00,0xf0,0x02,0x3c,0xff,0x00,0x07,0x3c, -0x00,0xff,0xe7,0x34,0x24,0x10,0x07,0x02,0x7a,0xff,0x40,0x10,0xc0,0x02,0x82,0x36, -0x04,0x43,0x64,0x92,0xff,0x00,0x02,0x3c,0x24,0x10,0x02,0x02,0x00,0xff,0x03,0x32, -0x02,0x14,0x02,0x00,0x02,0x1a,0x03,0x00,0xfb,0xff,0x45,0x24,0x1c,0x43,0x62,0xa2, -0x00,0x01,0x84,0x34,0xfb,0xff,0x66,0x24,0xc0,0x02,0x82,0x36,0x04,0x43,0x64,0xae, -0x1d,0x43,0x65,0xa2,0x1f,0x43,0x66,0xa2,0x1e,0x43,0x63,0xa2,0x00,0x00,0x40,0xac, -0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x05,0x00,0xa2,0x34,0x91,0x02,0x62,0x10, -0x2b,0x10,0x43,0x00,0x8e,0x00,0x40,0x14,0x00,0x00,0x00,0x00,0xde,0x02,0x65,0x10, -0x2b,0x10,0xa3,0x00,0x32,0x01,0x40,0x14,0x02,0x00,0xa2,0x34,0x17,0x00,0x82,0x34, -0x61,0x04,0x62,0x10,0x2b,0x10,0x62,0x00,0xa9,0x03,0x40,0x14,0x18,0x00,0x82,0x34, -0x3d,0xff,0x62,0x14,0x00,0xf0,0x02,0x3c,0x74,0x0b,0x00,0x0c,0x00,0x00,0x00,0x00, -0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00, -0xa8,0x02,0x62,0x10,0x2b,0x10,0x43,0x00,0x95,0x00,0x40,0x14,0x0c,0x00,0xc2,0x34, -0xaa,0x00,0xe2,0x34,0xdc,0x02,0x62,0x10,0x2b,0x10,0x43,0x00,0xd9,0x00,0x40,0x14, -0xac,0x00,0xe2,0x34,0xa6,0x00,0xe2,0x34,0x1c,0x04,0x62,0x10,0x2b,0x10,0x62,0x00, -0x69,0x03,0x40,0x14,0xa7,0x00,0xe2,0x34,0x27,0xff,0x62,0x14,0x00,0xf0,0x02,0x3c, -0x00,0xff,0x02,0x32,0xff,0x00,0x04,0x3c,0x02,0x8a,0x02,0x00,0x24,0x18,0x04,0x02, -0x01,0x00,0x02,0x24,0xa6,0x04,0x22,0x12,0x02,0x1c,0x03,0x00,0x02,0x00,0x02,0x24, -0xc9,0x04,0x22,0x12,0x03,0x00,0x02,0x24,0xdf,0x04,0x22,0x12,0x04,0x00,0x02,0x24, -0xd1,0x04,0x22,0x12,0x08,0x00,0x02,0x24,0x2e,0x05,0x22,0x12,0x09,0x00,0x02,0x24, -0x1e,0x05,0x22,0x12,0x0a,0x00,0x02,0x24,0x0e,0x05,0x22,0x12,0x0b,0x00,0x02,0x24, -0xfe,0x04,0x22,0x12,0x0c,0x00,0x02,0x24,0x5e,0x05,0x22,0x12,0x0d,0x00,0x02,0x24, -0x4e,0x05,0x22,0x12,0x0e,0x00,0x02,0x24,0x3e,0x05,0x22,0x12,0x0f,0x00,0x02,0x24, -0x2e,0x05,0x22,0x12,0x10,0x00,0x02,0x24,0x22,0xff,0x22,0x16,0xc0,0x02,0x82,0x36, -0xc0,0x10,0x03,0x00,0x21,0x10,0x43,0x00,0x80,0x10,0x02,0x00,0x21,0x10,0x43,0x00, -0x80,0x10,0x02,0x00,0x21,0x10,0x53,0x00,0x4c,0x51,0x43,0x94,0x48,0x51,0x44,0x94, -0x25,0xb0,0x06,0x3c,0x00,0x1c,0x03,0x00,0x21,0x20,0x83,0x00,0x00,0x00,0xc4,0xaf, -0x58,0x51,0x45,0x8c,0x54,0x51,0x43,0x8c,0x50,0x51,0x44,0x94,0xc8,0x02,0xc6,0x34, -0x21,0x18,0x65,0x00,0x00,0x1c,0x03,0x00,0x21,0x20,0x83,0x00,0xc0,0x02,0x82,0x36, -0x00,0x00,0xc4,0xac,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00, -0x66,0x02,0x62,0x10,0x2b,0x10,0x43,0x00,0xbf,0x00,0x40,0x14,0x12,0x00,0x82,0x34, -0x00,0xf1,0x04,0x3c,0x01,0x00,0x82,0x34,0xc1,0x02,0x62,0x10,0x2b,0x10,0x43,0x00, -0xb7,0x01,0x40,0x14,0x02,0x00,0x82,0x34,0xe3,0xfe,0x64,0x14,0x00,0xf0,0x02,0x3c, -0xff,0x00,0x04,0x3c,0x00,0xff,0x84,0x34,0x24,0x10,0x04,0x02,0x02,0x8a,0x02,0x00, -0x80,0x1a,0x11,0x00,0x00,0xf4,0x63,0x24,0x94,0x00,0x82,0x36,0x00,0x00,0x51,0xa4, -0x26,0xb0,0x04,0x3c,0x42,0x89,0x03,0x00,0x98,0x00,0x86,0x36,0xff,0x01,0x02,0x24, -0x10,0x00,0x03,0x24,0x9a,0x00,0x85,0x36,0x00,0x00,0xa2,0xa4,0x7c,0x00,0x89,0x34, -0x00,0x00,0xc3,0xa4,0x01,0x00,0x02,0x24,0x04,0x00,0x03,0x24,0x96,0x00,0x87,0x36, -0x7a,0x00,0x84,0x34,0xb0,0x03,0x88,0x36,0x25,0xb0,0x06,0x3c,0x00,0x00,0xe2,0xa4, -0x44,0x00,0xc6,0x34,0x00,0x00,0x83,0xa0,0x00,0x00,0x11,0xad,0x00,0x00,0x31,0xa5, -0x00,0x00,0xc3,0x94,0xff,0xfd,0x02,0x24,0x24,0x18,0x62,0x00,0x00,0x00,0xc3,0xa4, -0x00,0x00,0xc2,0x94,0x00,0x00,0x00,0x00,0x00,0x02,0x42,0x34,0x00,0x00,0xc2,0xa4, -0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00, -0x65,0x01,0x67,0x10,0x2b,0x10,0xe3,0x00,0xc5,0x00,0x40,0x14,0x02,0x00,0xe2,0x34, -0x07,0x00,0xa2,0x34,0xfc,0x02,0x62,0x10,0x2b,0x10,0x62,0x00,0xa9,0x01,0x40,0x14, -0x20,0x00,0xa2,0x34,0xb0,0xfe,0x62,0x14,0x00,0xf0,0x02,0x3c,0xff,0x00,0x03,0x3c, -0x00,0xff,0x63,0x34,0x24,0x10,0x03,0x02,0x02,0x3a,0x02,0x00,0x80,0x04,0xe0,0x10, -0x02,0x80,0x04,0x3c,0x05,0x00,0x02,0x24,0xc2,0xfe,0xe2,0x14,0xc0,0x02,0x82,0x36, -0x02,0x80,0x06,0x3c,0x8f,0x7d,0xc2,0x90,0x00,0x00,0x00,0x00,0x00,0x00,0xc2,0xaf, -0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00, -0x2e,0x02,0x62,0x10,0x2b,0x10,0x43,0x00,0x98,0x00,0x40,0x14,0x0e,0x00,0xc2,0x34, -0x01,0x00,0xc2,0x34,0xab,0x03,0x62,0x10,0x2b,0x10,0x43,0x00,0x48,0x01,0x40,0x14, -0x00,0xff,0x02,0x3c,0x94,0xfe,0x66,0x14,0x00,0xf0,0x02,0x3c,0x5b,0x4e,0x00,0x0c, -0x21,0x20,0x00,0x00,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08, -0x00,0x00,0x00,0x00,0x4c,0x02,0x62,0x10,0x2b,0x10,0x43,0x00,0xa6,0x00,0x40,0x14, -0xa1,0x00,0xe2,0x34,0x22,0x00,0xe2,0x34,0xbd,0x02,0x62,0x10,0x2b,0x10,0x62,0x00, -0x88,0x01,0x40,0x14,0x00,0x20,0x02,0x3c,0x28,0x00,0xe2,0x34,0x82,0xfe,0x62,0x14, -0x00,0xf0,0x02,0x3c,0x0f,0x00,0x04,0x3c,0xff,0xff,0x85,0x34,0x60,0x00,0x06,0x24, -0xba,0x44,0x00,0x0c,0x24,0x00,0x04,0x24,0x84,0x0a,0x00,0x0c,0xe8,0x03,0x04,0x24, -0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40, -0x0f,0x00,0x06,0x3c,0x24,0x00,0x04,0x24,0xdd,0x44,0x00,0x0c,0xff,0xff,0xc5,0x34, -0x1f,0x00,0x51,0x30,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40, -0xb3,0x0a,0x00,0x0c,0x64,0x00,0x04,0x24,0xc0,0x02,0x82,0x36,0x00,0x00,0xd1,0xa3, -0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x18,0x02,0xc2,0x10, -0x2b,0x10,0x46,0x00,0x01,0x01,0x40,0x14,0x00,0xa0,0x02,0x3c,0x00,0x60,0x02,0x3c, -0x04,0x00,0xc2,0x10,0x80,0x10,0x08,0x00,0x7a,0xfe,0xc5,0x14,0xc0,0x02,0x82,0x36, -0x80,0x10,0x08,0x00,0x21,0x10,0x48,0x00,0x21,0x10,0x53,0x00,0x21,0x10,0x49,0x00, -0xc1,0x43,0x44,0xa0,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08, -0x00,0x00,0x00,0x00,0x3f,0x03,0x62,0x10,0x2b,0x10,0x62,0x00,0xb6,0x02,0x40,0x14, -0xad,0x00,0xe2,0x34,0xc7,0x03,0x62,0x10,0xae,0x00,0xe2,0x34,0x4e,0xfe,0x62,0x14, -0x00,0xf0,0x02,0x3c,0xff,0x00,0x02,0x3c,0x24,0x20,0x02,0x02,0x00,0xff,0x05,0x32, -0x02,0x24,0x04,0x00,0x69,0x4f,0x00,0x0c,0x02,0x2a,0x05,0x00,0x00,0x00,0xc2,0xa3, -0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00, -0x4b,0x02,0x62,0x10,0x2b,0x10,0x62,0x00,0x17,0x01,0x40,0x14,0x03,0x00,0xa2,0x34, -0x82,0x03,0x62,0x10,0x08,0x00,0xa2,0x34,0x3b,0xfe,0x62,0x14,0x00,0xf0,0x02,0x3c, -0x00,0xff,0x02,0x32,0x02,0x82,0x02,0x00,0xcc,0x02,0x83,0x36,0x00,0x00,0x70,0xac, -0x12,0x04,0x00,0x12,0x01,0x00,0x02,0x24,0x9c,0x04,0x02,0x12,0x00,0x00,0x00,0x00, -0x7a,0x42,0x00,0x0c,0x21,0x20,0x00,0x00,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac, -0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x4e,0x02,0x62,0x10,0x2b,0x10,0x62,0x00, -0xe4,0x00,0x40,0x14,0x00,0xff,0x02,0x32,0x13,0x00,0x82,0x34,0x4c,0x03,0x62,0x10, -0x14,0x00,0x82,0x34,0x24,0xfe,0x62,0x14,0x00,0xf0,0x02,0x3c,0xd3,0x0a,0x00,0x0c, -0xfd,0x00,0x04,0x24,0x10,0x10,0x03,0x3c,0xa0,0x00,0x82,0x36,0x10,0x10,0x63,0x34, -0x00,0xc0,0x07,0x3c,0x25,0xb0,0x06,0x3c,0x00,0x00,0x43,0xac,0xa4,0x00,0x84,0x36, -0x00,0xa1,0xe7,0x34,0xa8,0x00,0xc6,0x34,0xc0,0x02,0x82,0x36,0x00,0x00,0x80,0xac, -0x00,0x00,0xc7,0xac,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00, -0x60,0x02,0x62,0x10,0x2b,0x10,0x62,0x00,0xf6,0x00,0x40,0x14,0x03,0x00,0xa2,0x34, -0x4b,0x03,0x62,0x10,0x04,0x00,0xa2,0x34,0x0b,0xfe,0x62,0x14,0x00,0xf0,0x02,0x3c, -0xf4,0x63,0x62,0x92,0x00,0x00,0x00,0x00,0x00,0x00,0xc2,0xaf,0xc0,0x02,0x82,0x36, -0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x61,0x02,0x62,0x10, -0x2b,0x10,0x62,0x00,0xfe,0x00,0x40,0x14,0x01,0x00,0x02,0x24,0x0f,0x00,0xc2,0x34, -0x63,0x03,0x62,0x10,0x10,0x00,0xc2,0x34,0xfb,0xfd,0x62,0x14,0x00,0xf0,0x02,0x3c, -0x00,0xff,0x03,0x32,0x00,0xff,0x02,0x34,0x9d,0x03,0x62,0x10,0xc0,0x02,0x82,0x36, -0x8c,0x65,0x60,0xae,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00, -0x47,0x02,0x62,0x10,0x2b,0x10,0x62,0x00,0x02,0x01,0x40,0x14,0x03,0x00,0xe2,0x34, -0x8d,0x03,0x62,0x10,0x04,0x00,0xe2,0x34,0xeb,0xfd,0x62,0x14,0x00,0xf0,0x02,0x3c, -0x1e,0x57,0x00,0x0c,0x00,0x00,0x00,0x00,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac, -0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x9b,0x01,0x62,0x10,0x2b,0x10,0x43,0x00, -0xcf,0x00,0x40,0x14,0xa2,0x00,0xe2,0x34,0xa0,0x00,0xe2,0x34,0xde,0xfd,0x62,0x14, -0x00,0xf0,0x02,0x3c,0x00,0x0f,0x02,0x32,0x02,0x22,0x02,0x00,0x01,0x00,0x03,0x24, -0x3c,0x04,0x83,0x10,0x02,0x00,0x02,0x24,0x34,0x04,0x82,0x10,0x03,0x00,0x02,0x24, -0x46,0x03,0x82,0x10,0x00,0x00,0x00,0x00,0xde,0x4f,0x00,0x0c,0x21,0x20,0x00,0x00, -0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00, -0x46,0x02,0x62,0x10,0x2b,0x10,0x62,0x00,0xe6,0xfd,0x40,0x14,0xc0,0x02,0x82,0x36, -0x18,0x00,0xe2,0x34,0x45,0x03,0x62,0x10,0x19,0x00,0xe2,0x34,0xc6,0xfd,0x62,0x14, -0x00,0xf0,0x02,0x3c,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x94,0x0e,0x83,0x36, -0x9c,0x0e,0x82,0x36,0xa4,0x0e,0x84,0x36,0xac,0x0e,0x87,0x36,0x00,0x00,0x65,0x8c, -0x00,0x00,0x48,0x8c,0x00,0x00,0x8a,0x8c,0x00,0x00,0xe6,0x8c,0x02,0x80,0x07,0x3c, -0x68,0x15,0xed,0x24,0xb4,0x0e,0x82,0x36,0x00,0x00,0x47,0x8c,0x0c,0x40,0xa3,0x8d, -0xff,0x03,0x02,0x3c,0x10,0x40,0xa4,0x8d,0x24,0x28,0xa2,0x00,0x24,0x30,0xc2,0x00, -0xbc,0x0e,0x82,0x36,0x00,0x00,0x4b,0x8c,0x00,0xfc,0x02,0x24,0x02,0x2c,0x05,0x00, -0x24,0x18,0x62,0x00,0x02,0x34,0x06,0x00,0x24,0x20,0x82,0x00,0xc4,0x0e,0x82,0x36, -0x25,0x18,0x65,0x00,0x25,0x20,0x86,0x00,0x00,0x00,0x45,0x8c,0xff,0x03,0x06,0x3c, -0xf0,0xff,0x02,0x3c,0xff,0x03,0x42,0x34,0x24,0x38,0xe6,0x00,0x82,0x39,0x07,0x00, -0x24,0x20,0x82,0x00,0x24,0x40,0x06,0x01,0x08,0x40,0xa9,0x8d,0x25,0x20,0x87,0x00, -0xcc,0x0e,0x8c,0x36,0xff,0x03,0x07,0x3c,0x00,0x00,0x86,0x8d,0x24,0x18,0x62,0x00, -0x24,0x50,0x47,0x01,0x24,0x58,0x67,0x01,0x82,0x41,0x08,0x00,0xff,0x9f,0x02,0x3c, -0x0f,0xc0,0x07,0x3c,0xff,0xff,0xe7,0x34,0xff,0xff,0x42,0x34,0x25,0x18,0x68,0x00, -0x24,0x48,0x22,0x01,0x24,0x18,0x67,0x00,0xff,0x03,0x02,0x3c,0x24,0x20,0x87,0x00, -0xff,0x00,0x07,0x3c,0x24,0x28,0xa2,0x00,0x24,0x30,0xc2,0x00,0x00,0x51,0x0a,0x00, -0x00,0x20,0x02,0x3c,0x00,0x59,0x0b,0x00,0x00,0xff,0xe7,0x34,0x25,0x48,0x22,0x01, -0x25,0x18,0x6a,0x00,0x25,0x20,0x8b,0x00,0x02,0x2c,0x05,0x00,0x02,0x34,0x06,0x00, -0x24,0x10,0x07,0x02,0x08,0x40,0xa9,0xad,0x0c,0x40,0xa3,0xad,0x10,0x40,0xa4,0xad, -0x14,0x40,0xa5,0xa5,0x4e,0x03,0x40,0x10,0x16,0x40,0xa6,0xa5,0xff,0x00,0x02,0x3c, -0x24,0x10,0x02,0x02,0x02,0x14,0x02,0x00,0x02,0x1a,0x10,0x00,0xc7,0x42,0xa2,0xa1, -0xc3,0x42,0xa3,0xa1,0xc3,0x42,0x62,0x92,0x25,0xb0,0x03,0x3c,0x61,0x0c,0x63,0x34, -0x10,0x00,0xa4,0x27,0x00,0x00,0x62,0xa0,0x7a,0x54,0x00,0x0c,0x00,0x00,0x00,0x00, -0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00, -0x95,0x00,0xc2,0x10,0x00,0x40,0x02,0x3c,0x09,0xff,0xc2,0x10,0xc0,0x02,0x82,0x36, -0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x7b,0x02,0xc2,0x10, -0x2b,0x10,0x46,0x00,0x83,0x00,0x40,0x14,0x00,0xb0,0x02,0x3c,0x00,0x90,0x02,0x3c, -0x78,0xfd,0xc2,0x14,0xc0,0x02,0x82,0x36,0x21,0x10,0x13,0x01,0x73,0x44,0x44,0xa0, -0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00, -0x55,0xfd,0x62,0x14,0x00,0xf0,0x02,0x3c,0x6a,0x56,0x00,0x0c,0x21,0x20,0x00,0x02, -0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00, -0x07,0x00,0x42,0x34,0x4c,0xfd,0x62,0x14,0x00,0xf0,0x02,0x3c,0x5b,0x4e,0x00,0x0c, -0x07,0x00,0x04,0x24,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08, -0x00,0x00,0x00,0x00,0x02,0x1a,0x02,0x00,0x21,0x88,0x00,0x00,0xaf,0x4a,0x00,0x08, -0x27,0xb0,0x06,0x3c,0x01,0x00,0x31,0x26,0x00,0x01,0x22,0x2e,0x08,0x00,0x40,0x10, -0xff,0x00,0x22,0x2e,0x00,0x00,0xc2,0x94,0x00,0x00,0x00,0x00,0xff,0x00,0x42,0x30, -0xf8,0xff,0x43,0x14,0x08,0x00,0xc6,0x24,0x00,0x00,0xd1,0xa7,0xff,0x00,0x22,0x2e, -0x50,0xfd,0x40,0x14,0xc0,0x02,0x82,0x36,0x12,0x87,0x02,0x3c,0x00,0x00,0xc2,0xaf, -0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00, -0x2d,0xfd,0x62,0x14,0x00,0xf0,0x02,0x3c,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac, -0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xff,0x00,0x03,0x3c,0x00,0xff,0x63,0x34, -0x24,0x10,0x03,0x02,0x02,0x82,0x02,0x00,0xcc,0x02,0x83,0x36,0x00,0x00,0x70,0xac, -0x00,0x00,0xd1,0x8f,0x21,0x10,0x14,0x02,0x00,0x00,0x51,0xac,0x00,0x00,0x51,0x8c, -0xc0,0x02,0x82,0x36,0x00,0x00,0xd1,0xaf,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08, -0x00,0x00,0x00,0x00,0x00,0x64,0x62,0x92,0x00,0x00,0x00,0x00,0x00,0x00,0xc2,0xaf, -0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00, -0xf4,0x02,0x62,0x10,0xa3,0x00,0xe2,0x34,0x0f,0xfd,0x62,0x14,0x00,0xf0,0x02,0x3c, -0xc0,0x02,0x82,0x36,0x8c,0x65,0x60,0xae,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08, -0x00,0x00,0x00,0x00,0xec,0x63,0x62,0x92,0x00,0x00,0x00,0x00,0x00,0x00,0xc2,0xaf, -0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00, -0xe6,0x63,0x62,0xa6,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08, -0x00,0x00,0x00,0x00,0x08,0x40,0x63,0x8e,0xff,0x9f,0x07,0x3c,0xff,0xff,0xe7,0x34, -0x02,0x2c,0x10,0x00,0x00,0x1f,0x04,0x32,0x24,0x18,0x67,0x00,0x25,0x18,0x62,0x00, -0x02,0x8a,0x04,0x00,0x3f,0x00,0xa5,0x30,0xc0,0x02,0x82,0x36,0x08,0x40,0x63,0xae, -0xbc,0x42,0x71,0xa2,0xc1,0x42,0x65,0xa2,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08, -0x00,0x00,0x00,0x00,0x00,0x00,0xe2,0x92,0x00,0x00,0x00,0x00,0xfa,0x00,0x42,0x30, -0x00,0x00,0xe2,0xa2,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08, -0x00,0x00,0x00,0x00,0x00,0x00,0xe2,0x92,0x00,0x00,0x00,0x00,0xfd,0x00,0x42,0x30, -0x00,0x00,0xe2,0xa2,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08, -0x00,0x00,0x00,0x00,0xf7,0xfc,0xc2,0x14,0xc0,0x02,0x82,0x36,0x80,0x10,0x08,0x00, -0x21,0x10,0x53,0x00,0x60,0x45,0x43,0xac,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac, -0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x80,0x10,0x08,0x00,0x21,0x10,0x48,0x00, -0x21,0x10,0x53,0x00,0x21,0x10,0x49,0x00,0x34,0x43,0x44,0xa0,0xc0,0x02,0x82,0x36, -0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x77,0x56,0x00,0x0c, -0x21,0x20,0x00,0x02,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08, -0x00,0x00,0x00,0x00,0xff,0xff,0x02,0x34,0x8c,0x65,0x62,0xae,0xc0,0x02,0x82,0x36, -0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x07,0x0b,0x00,0x0c, -0x00,0x00,0x00,0x00,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08, -0x00,0x00,0x00,0x00,0xf0,0x63,0x62,0x92,0x00,0x00,0x00,0x00,0x00,0x00,0xc2,0xaf, -0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00, -0x08,0x40,0x62,0x8e,0xff,0x9f,0x03,0x3c,0xff,0xff,0x63,0x34,0x24,0x10,0x43,0x00, -0x08,0x40,0x62,0xae,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08, -0x00,0x00,0x00,0x00,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38, -0x00,0x60,0x81,0x40,0x22,0x51,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x60,0x01,0x40, -0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac, -0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xff,0x00,0x07,0x3c,0x00,0xff,0xe7,0x34, -0x24,0x10,0x07,0x02,0x02,0x82,0x02,0x00,0xcc,0x02,0x43,0x36,0x00,0x00,0x70,0xac, -0x21,0x10,0x12,0x02,0x00,0x00,0x51,0x8c,0x00,0x00,0x00,0x00,0x00,0x00,0xd1,0xaf, -0x00,0x00,0x51,0x8c,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08, -0x00,0x00,0x00,0x00,0xb7,0x4f,0x00,0x0c,0x00,0x00,0x00,0x00,0xc0,0x02,0x82,0x36, -0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x21,0x88,0x00,0x00, -0x6c,0x4b,0x00,0x08,0x27,0xb0,0x04,0x3c,0x01,0x00,0x31,0x26,0x00,0x01,0x22,0x2e, -0x0a,0x00,0x40,0x10,0xff,0x00,0x22,0x2e,0x00,0x00,0x83,0x94,0x00,0x00,0x00,0x00, -0xff,0xff,0x67,0x30,0xff,0x00,0xe2,0x30,0xf0,0x00,0x42,0x28,0xf6,0xff,0x40,0x14, -0x08,0x00,0x84,0x24,0x00,0x00,0xc7,0xa7,0xff,0x00,0x22,0x2e,0x91,0xfc,0x40,0x14, -0xc0,0x02,0x82,0x36,0x12,0x87,0x02,0x3c,0x00,0x00,0xc2,0xaf,0xc0,0x02,0x82,0x36, -0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xe4,0x63,0x62,0x96, -0x00,0x00,0x00,0x00,0x00,0x00,0xc2,0xa7,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac, -0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x04,0x64,0x62,0x92,0x00,0x00,0x00,0x00, -0x00,0x00,0xc2,0xaf,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08, -0x00,0x00,0x00,0x00,0x00,0xff,0x02,0x32,0x02,0x12,0x02,0x00,0x03,0x00,0x43,0x2c, -0x02,0x00,0x60,0x10,0x00,0x00,0x00,0x00,0x02,0x40,0x62,0xa2,0x02,0x40,0x63,0x92, -0x90,0x0c,0x42,0x36,0x00,0x00,0x43,0xa0,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac, -0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xd7,0x56,0x00,0x0c,0x00,0x00,0x00,0x00, -0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00, -0x21,0x10,0x13,0x01,0x56,0x44,0x44,0xa0,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac, -0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xff,0x00,0x03,0x3c,0x24,0x20,0x03,0x02, -0x73,0x0e,0x00,0x0c,0x02,0x24,0x04,0x00,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac, -0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x02,0x1c,0x10,0x00,0x00,0x1f,0x02,0x32, -0x02,0x8a,0x02,0x00,0x3f,0x00,0x65,0x30,0xc1,0x42,0x65,0xa2,0xbc,0x42,0x71,0xa2, -0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40, -0x1f,0x12,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0xc2,0xaf,0x00,0x60,0x01,0x40, -0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,0x03,0x40,0x62,0x92,0x0e,0x0c,0x44,0x36, -0x01,0x00,0x42,0x24,0xff,0x00,0x43,0x30,0x00,0x00,0x83,0xa0,0x03,0x40,0x62,0xa2, -0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00, -0x00,0xff,0x02,0x32,0x02,0x3a,0x02,0x00,0x1a,0x01,0xe0,0x10,0x4f,0x00,0x82,0x36, -0x94,0x00,0x42,0x36,0x00,0x00,0x43,0x94,0xff,0xff,0xe2,0x24,0xb0,0x03,0x45,0x36, -0xff,0xff,0x71,0x30,0x1b,0x00,0x27,0x02,0x02,0x00,0xe0,0x14,0x00,0x00,0x00,0x00, -0x0d,0x00,0x07,0x00,0xff,0xff,0x47,0x30,0x00,0x00,0xb1,0xac,0x80,0xff,0x02,0x24, -0x00,0x19,0x07,0x00,0x25,0x18,0x62,0x00,0x4f,0x00,0x44,0x36,0x9e,0x00,0x46,0x36, -0x00,0x00,0xa7,0xac,0x00,0x00,0x83,0xa0,0x25,0xb0,0x04,0x3c,0x44,0x00,0x84,0x34, -0x12,0x88,0x00,0x00,0x80,0x12,0x11,0x00,0x00,0xfc,0x42,0x24,0x00,0x00,0xb1,0xac, -0x00,0x00,0xd1,0xa4,0x42,0x89,0x02,0x00,0x26,0xb0,0x02,0x3c,0x7c,0x00,0x42,0x34, -0x00,0x00,0xb1,0xac,0x00,0x00,0x51,0xa4,0x25,0xb0,0x02,0x3c,0x44,0x00,0x42,0x34, -0x00,0x00,0x43,0x94,0xff,0xfd,0x02,0x24,0x24,0x18,0x62,0x00,0x00,0x00,0x83,0xa4, -0x00,0x00,0x82,0x94,0x00,0x00,0x00,0x00,0x00,0x02,0x42,0x34,0x00,0x00,0x82,0xa4, -0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00, -0x24,0x10,0x08,0x02,0xcc,0x02,0x43,0x36,0x00,0xff,0x04,0x32,0x02,0x3c,0x02,0x00, -0x00,0x00,0x70,0xac,0x04,0x00,0xe0,0x10,0x02,0x82,0x04,0x00,0x01,0x00,0x02,0x24, -0x02,0x00,0xe2,0x10,0x01,0x00,0x04,0x24,0x21,0x20,0x00,0x00,0x7a,0x42,0x00,0x0c, -0x00,0x00,0x00,0x00,0x0f,0x00,0x06,0x3c,0x21,0x20,0x00,0x02,0xdd,0x44,0x00,0x0c, -0xff,0xff,0xc5,0x34,0x0f,0x00,0x07,0x3c,0xff,0xff,0xe7,0x34,0x24,0x88,0x47,0x00, -0xc0,0x02,0x82,0x36,0x00,0x00,0xd1,0xaf,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08, -0x00,0x00,0x00,0x00,0x28,0xb0,0x02,0x3c,0x00,0x00,0x43,0x90,0xff,0x00,0x02,0x24, -0xff,0x00,0x70,0x30,0xf3,0xfb,0x02,0x12,0xc0,0x02,0x82,0x36,0x28,0xb0,0x05,0x3c, -0xff,0x00,0x04,0x24,0xc0,0x10,0x10,0x00,0x21,0x10,0x45,0x00,0x00,0x00,0x43,0x90, -0x00,0x00,0x00,0x00,0xff,0x00,0x70,0x30,0xfb,0xff,0x04,0x16,0xc0,0x10,0x10,0x00, -0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00, -0x00,0x1f,0x02,0x32,0x02,0x1c,0x10,0x00,0x02,0x8a,0x02,0x00,0x3f,0x00,0x65,0x30, -0xc0,0x02,0x82,0x36,0xbc,0x42,0x71,0xa2,0xc1,0x42,0x65,0xa2,0x00,0x00,0x40,0xac, -0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xff,0x00,0x07,0x3c,0x24,0x20,0x07,0x02, -0x15,0x51,0x00,0x0c,0x02,0x24,0x04,0x00,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac, -0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xe8,0x63,0x62,0x92,0x00,0x00,0x00,0x00, -0x00,0x00,0xc2,0xaf,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08, -0x00,0x00,0x00,0x00,0xfc,0x63,0x62,0x92,0x00,0x00,0x00,0x00,0x00,0x00,0xc2,0xaf, -0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00, -0x00,0x00,0xe2,0x92,0x00,0x00,0x00,0x00,0xff,0x00,0x51,0x30,0x05,0x00,0x23,0x36, -0xc0,0x02,0x82,0x36,0x00,0x00,0xe3,0xa2,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08, -0x00,0x00,0x00,0x00,0xc0,0x02,0x82,0x36,0xe6,0x63,0x60,0xa6,0x00,0x00,0x40,0xac, -0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xbd,0x56,0x00,0x0c,0x21,0x20,0x00,0x02, -0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00, -0x41,0x0b,0x00,0x0c,0x00,0x00,0x00,0x00,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac, -0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0xe2,0x92,0x00,0x00,0x00,0x00, -0xff,0x00,0x51,0x30,0x02,0x00,0x23,0x36,0xc0,0x02,0x82,0x36,0x00,0x00,0xe3,0xa2, -0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x02,0x80,0x02,0x3c, -0xec,0x91,0x42,0x24,0x00,0x00,0x47,0x8c,0xc0,0x02,0x43,0x36,0x25,0xb0,0x0c,0x3c, -0x08,0x40,0xe4,0x8c,0x00,0x00,0x60,0xac,0x42,0x17,0x04,0x00,0x03,0x00,0x42,0x30, -0x60,0x00,0x40,0x14,0x03,0x0d,0x42,0x36,0x00,0x00,0x45,0x90,0x10,0x40,0xe6,0x8c, -0xff,0x9f,0x03,0x3c,0xff,0xff,0x63,0x34,0xff,0x3f,0x02,0x3c,0x24,0x20,0x83,0x00, -0xff,0xff,0x42,0x34,0x00,0x20,0x03,0x3c,0x24,0x58,0xc2,0x00,0x25,0x20,0x83,0x00, -0x00,0x40,0x02,0x3c,0x70,0x00,0xa5,0x30,0x25,0x58,0x62,0x01,0x08,0x01,0xa0,0x10, -0x08,0x40,0xe4,0xac,0x94,0x0e,0x82,0x35,0x9c,0x0e,0x83,0x35,0xa4,0x0e,0x86,0x35, -0x00,0x00,0x45,0x8c,0xac,0x0e,0x87,0x35,0x00,0x00,0x68,0x8c,0x00,0x00,0xca,0x8c, -0x02,0x80,0x06,0x3c,0x00,0x00,0xe4,0x8c,0x68,0x15,0xc6,0x24,0x0c,0x40,0xc3,0x8c, -0xb4,0x0e,0x82,0x35,0x00,0x00,0x47,0x8c,0xff,0x03,0x02,0x3c,0x00,0xfc,0x06,0x24, -0x24,0x28,0xa2,0x00,0x24,0x20,0x82,0x00,0xbc,0x0e,0x82,0x35,0x00,0x00,0x49,0x8c, -0x02,0x2c,0x05,0x00,0x24,0x10,0x66,0x01,0x24,0x18,0x66,0x00,0x02,0x24,0x04,0x00, -0xc4,0x0e,0x86,0x35,0x25,0x18,0x65,0x00,0x25,0x10,0x44,0x00,0x00,0x00,0xc5,0x8c, -0xff,0x03,0x04,0x3c,0xf0,0xff,0x06,0x3c,0xff,0x03,0xc6,0x34,0x24,0x38,0xe4,0x00, -0xcc,0x0e,0x8b,0x35,0x24,0x40,0x04,0x01,0x82,0x39,0x07,0x00,0x00,0x00,0x64,0x8d, -0x24,0x10,0x46,0x00,0x24,0x18,0x66,0x00,0x25,0x10,0x47,0x00,0x82,0x41,0x08,0x00, -0xff,0x03,0x07,0x3c,0x0f,0xc0,0x06,0x3c,0x24,0x50,0x47,0x01,0x24,0x48,0x27,0x01, -0xff,0xff,0xc6,0x34,0x25,0x18,0x68,0x00,0x24,0x28,0xa7,0x00,0x24,0x20,0x87,0x00, -0x00,0x51,0x0a,0x00,0x24,0x18,0x66,0x00,0x00,0x49,0x09,0x00,0x24,0x10,0x46,0x00, -0x02,0x80,0x07,0x3c,0x68,0x15,0xe7,0x24,0x25,0x18,0x6a,0x00,0x25,0x10,0x49,0x00, -0x02,0x2c,0x05,0x00,0x02,0x24,0x04,0x00,0x0c,0x40,0xe3,0xac,0x10,0x40,0xe2,0xac, -0x14,0x40,0xe5,0xa4,0x16,0x40,0xe4,0xa4,0x02,0x80,0x02,0x3c,0x68,0x15,0x43,0x24, -0x0c,0x40,0x62,0x8c,0x00,0x00,0x00,0x00,0xbd,0x00,0x40,0x04,0x00,0x00,0x00,0x00, -0x00,0xff,0x02,0x32,0xc6,0x00,0x40,0x10,0x00,0x00,0x00,0x00,0x02,0x12,0x02,0x00, -0xc3,0x42,0x62,0xa0,0x7a,0x54,0x00,0x0c,0x10,0x00,0xa4,0x27,0xc2,0x53,0x00,0x0c, -0x00,0x00,0x00,0x00,0x0c,0x40,0x62,0x8e,0x00,0x80,0x03,0x3c,0x25,0x10,0x43,0x00, -0x0c,0x40,0x62,0xae,0xc3,0x42,0x62,0x92,0x25,0xb0,0x03,0x3c,0x61,0x0c,0x63,0x34, -0x00,0x00,0x62,0xa0,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08, -0x00,0x00,0x00,0x00,0xcf,0x4e,0x00,0x0c,0x21,0x20,0x00,0x02,0xc0,0x02,0x82,0x36, -0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x17,0x51,0x00,0x0c, -0x00,0x00,0x00,0x00,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08, -0x00,0x00,0x00,0x00,0x9e,0x00,0x83,0x36,0x00,0x00,0x40,0xa0,0x00,0x00,0x60,0xa4, -0x94,0x00,0x82,0x36,0x00,0x00,0x43,0x94,0x25,0xb0,0x06,0x3c,0x44,0x00,0xc6,0x34, -0xff,0xff,0x71,0x30,0x80,0x12,0x11,0x00,0x00,0xf8,0x42,0x24,0x42,0x89,0x02,0x00, -0x26,0xb0,0x02,0x3c,0xb0,0x03,0x83,0x36,0x7c,0x00,0x42,0x34,0x00,0x00,0x71,0xac, -0x00,0x00,0x51,0xa4,0x00,0x00,0xc3,0x94,0xff,0xfd,0x02,0x24,0x24,0x18,0x62,0x00, -0x00,0x00,0xc3,0xa4,0x00,0x00,0xc2,0x94,0x00,0x00,0x00,0x00,0x00,0x02,0x42,0x34, -0x00,0x00,0xc2,0xa4,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08, -0x00,0x00,0x00,0x00,0x5b,0x4e,0x00,0x0c,0x01,0x00,0x04,0x24,0xc0,0x02,0x82,0x36, -0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x80,0x10,0x08,0x00, -0x21,0x10,0x53,0x00,0xec,0x44,0x43,0xac,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac, -0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xa7,0x0b,0x00,0x0c,0x00,0x00,0x00,0x00, -0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00, -0x28,0xb0,0x11,0x3c,0x00,0x00,0x22,0x96,0xff,0x00,0x04,0x3c,0x24,0x18,0x04,0x02, -0x02,0x24,0x03,0x00,0xff,0x00,0x42,0x30,0x0a,0x00,0x82,0x10,0xff,0x7f,0x02,0x3c, -0x08,0x00,0x31,0x26,0x00,0x00,0x22,0x96,0xff,0xff,0x23,0x32,0xff,0x00,0x42,0x30, -0x03,0x00,0x82,0x10,0x00,0x08,0x63,0x2c,0xf9,0xff,0x60,0x14,0x00,0x00,0x00,0x00, -0xff,0x7f,0x02,0x3c,0xff,0xff,0x42,0x34,0x24,0x10,0x22,0x02,0x00,0x00,0xc2,0xaf, -0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00, -0xf8,0x63,0x62,0x92,0x00,0x00,0x00,0x00,0x00,0x00,0xc2,0xaf,0xc0,0x02,0x82,0x36, -0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xff,0x00,0x03,0x3c, -0x24,0x10,0x03,0x02,0x00,0xff,0x04,0x32,0xcc,0x02,0x83,0x36,0x02,0x3c,0x02,0x00, -0x00,0x00,0x70,0xac,0x04,0x00,0xe0,0x10,0x02,0x82,0x04,0x00,0x01,0x00,0x02,0x24, -0x02,0x00,0xe2,0x10,0x01,0x00,0x04,0x24,0x21,0x20,0x00,0x00,0x7a,0x42,0x00,0x0c, -0x00,0x00,0x00,0x00,0x00,0x00,0xd1,0x8f,0x0f,0x00,0x06,0x3c,0xff,0xff,0xc5,0x34, -0x21,0x20,0x00,0x02,0xba,0x44,0x00,0x0c,0x21,0x30,0x20,0x02,0x0f,0x00,0x07,0x3c, -0x21,0x20,0x00,0x02,0xdd,0x44,0x00,0x0c,0xff,0xff,0xe5,0x34,0x00,0x00,0xc2,0xaf, -0x21,0x88,0x40,0x00,0x25,0xb0,0x02,0x3c,0xc8,0x02,0x42,0x34,0x00,0x00,0x51,0xac, -0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00, -0x25,0xb0,0x06,0x3c,0xff,0x00,0x02,0x24,0x56,0x01,0xc6,0x34,0x00,0x00,0xc2,0xa4, -0x01,0x00,0x03,0x24,0x02,0x80,0x07,0x3c,0xc0,0x02,0x82,0x36,0xb8,0x7d,0xe3,0xa0, -0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xde,0x4f,0x00,0x0c, -0x03,0x00,0x04,0x24,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08, -0x00,0x00,0x00,0x00,0xde,0x4e,0x00,0x0c,0x21,0x20,0x00,0x02,0xc0,0x02,0x82,0x36, -0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x08,0x40,0x62,0x8e, -0xff,0x9f,0x04,0x3c,0xff,0xff,0x84,0x34,0x24,0x10,0x44,0x00,0x08,0x40,0x62,0xae, -0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00, -0xc0,0x10,0x03,0x00,0x21,0x10,0x43,0x00,0x80,0x10,0x02,0x00,0x21,0x10,0x43,0x00, -0x80,0x10,0x02,0x00,0x21,0x10,0x53,0x00,0x70,0x51,0x43,0x8c,0xc0,0x02,0x82,0x36, -0x00,0x00,0xc3,0xaf,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00, -0x7a,0x54,0x00,0x0c,0x10,0x00,0xa4,0x27,0xc3,0x42,0x62,0x92,0x25,0xb0,0x03,0x3c, -0x61,0x0c,0x63,0x34,0x00,0x00,0x62,0xa0,0xd4,0x4c,0x00,0x08,0xc0,0x02,0x82,0x36, -0x22,0x51,0x00,0x0c,0x10,0x40,0xeb,0xac,0xbd,0x4c,0x00,0x08,0x02,0x80,0x02,0x3c, -0xc6,0x4c,0x00,0x08,0x12,0x00,0x02,0x24,0x1a,0x57,0x00,0x0c,0x00,0x00,0x00,0x00, -0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00, -0xff,0xff,0x02,0x34,0x8c,0x65,0x62,0xae,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac, -0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xc0,0x10,0x03,0x00,0x21,0x10,0x43,0x00, -0x80,0x10,0x02,0x00,0x21,0x10,0x43,0x00,0x80,0x10,0x02,0x00,0x21,0x10,0x53,0x00, -0x74,0x51,0x43,0x8c,0xc0,0x02,0x82,0x36,0x00,0x00,0xc3,0xaf,0x00,0x00,0x40,0xac, -0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xc0,0x10,0x03,0x00,0x21,0x10,0x43,0x00, -0x80,0x10,0x02,0x00,0x21,0x10,0x43,0x00,0x80,0x10,0x02,0x00,0x21,0x10,0x53,0x00, -0xd4,0x51,0x43,0x8c,0xc0,0x02,0x82,0x36,0x00,0x00,0xc3,0xaf,0x00,0x00,0x40,0xac, -0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xc0,0x10,0x03,0x00,0x21,0x10,0x43,0x00, -0x80,0x10,0x02,0x00,0x21,0x10,0x43,0x00,0x02,0x80,0x06,0x3c,0x80,0x10,0x02,0x00, -0xe0,0x66,0xc3,0x24,0x21,0x10,0x43,0x00,0x00,0x00,0x44,0x8c,0xc0,0x02,0x82,0x36, -0x00,0x00,0xc4,0xaf,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00, -0x12,0x00,0x02,0x24,0xc7,0x42,0xa2,0xa1,0x77,0x4a,0x00,0x08,0xc3,0x42,0xa2,0xa1, -0x88,0x7d,0x82,0x94,0x00,0x00,0x00,0x00,0x00,0x00,0xc2,0xaf,0xc0,0x02,0x82,0x36, -0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x7a,0x42,0x00,0x0c, -0x21,0x20,0x00,0x00,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08, -0x00,0x00,0x00,0x00,0xff,0x00,0x06,0x3c,0x00,0xff,0xc6,0x34,0x00,0x00,0xc5,0x8f, -0x24,0x20,0x06,0x02,0xe1,0x50,0x00,0x0c,0x02,0x22,0x04,0x00,0xc0,0x02,0x82,0x36, -0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xc0,0x10,0x03,0x00, -0x21,0x10,0x43,0x00,0x80,0x10,0x02,0x00,0x21,0x10,0x43,0x00,0x02,0x80,0x07,0x3c, -0x80,0x10,0x02,0x00,0xf0,0x66,0xe3,0x24,0x21,0x10,0x43,0x00,0x00,0x00,0x44,0x8c, -0xc0,0x02,0x82,0x36,0x00,0x00,0xc4,0xaf,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08, -0x00,0x00,0x00,0x00,0xc0,0x10,0x03,0x00,0x21,0x10,0x43,0x00,0x80,0x10,0x02,0x00, -0x21,0x10,0x43,0x00,0x02,0x80,0x06,0x3c,0x80,0x10,0x02,0x00,0xec,0x66,0xc3,0x24, -0x21,0x10,0x43,0x00,0x00,0x00,0x44,0x8c,0xc0,0x02,0x82,0x36,0x00,0x00,0xc4,0xaf, -0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xc0,0x10,0x03,0x00, -0x21,0x10,0x43,0x00,0x80,0x10,0x02,0x00,0x21,0x10,0x43,0x00,0x02,0x80,0x04,0x3c, -0xe8,0x66,0x83,0x24,0x80,0x10,0x02,0x00,0x21,0x10,0x43,0x00,0x00,0x00,0x44,0x8c, -0xc0,0x02,0x82,0x36,0x00,0x00,0xc4,0xaf,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08, -0x00,0x00,0x00,0x00,0xc0,0x10,0x03,0x00,0x21,0x10,0x43,0x00,0x80,0x10,0x02,0x00, -0x21,0x10,0x43,0x00,0x02,0x80,0x07,0x3c,0x80,0x10,0x02,0x00,0xe4,0x66,0xe3,0x24, -0x21,0x10,0x43,0x00,0x00,0x00,0x44,0x8c,0xc0,0x02,0x82,0x36,0x00,0x00,0xc4,0xaf, -0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xc0,0x10,0x03,0x00, -0x21,0x10,0x43,0x00,0x80,0x10,0x02,0x00,0x21,0x10,0x43,0x00,0x02,0x80,0x04,0x3c, -0x00,0x67,0x83,0x24,0x80,0x10,0x02,0x00,0x21,0x10,0x43,0x00,0x00,0x00,0x44,0x8c, -0xc0,0x02,0x82,0x36,0x00,0x00,0xc4,0xaf,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08, -0x00,0x00,0x00,0x00,0xc0,0x10,0x03,0x00,0x21,0x10,0x43,0x00,0x80,0x10,0x02,0x00, -0x21,0x10,0x43,0x00,0x02,0x80,0x07,0x3c,0x80,0x10,0x02,0x00,0xfc,0x66,0xe3,0x24, -0x21,0x10,0x43,0x00,0x00,0x00,0x44,0x8c,0xc0,0x02,0x82,0x36,0x00,0x00,0xc4,0xaf, -0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xc0,0x10,0x03,0x00, -0x21,0x10,0x43,0x00,0x80,0x10,0x02,0x00,0x21,0x10,0x43,0x00,0x02,0x80,0x06,0x3c, -0x80,0x10,0x02,0x00,0xf8,0x66,0xc3,0x24,0x21,0x10,0x43,0x00,0x00,0x00,0x44,0x8c, -0xc0,0x02,0x82,0x36,0x00,0x00,0xc4,0xaf,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08, -0x00,0x00,0x00,0x00,0xc0,0x10,0x03,0x00,0x21,0x10,0x43,0x00,0x80,0x10,0x02,0x00, -0x21,0x10,0x43,0x00,0x02,0x80,0x04,0x3c,0xf4,0x66,0x83,0x24,0x80,0x10,0x02,0x00, -0x21,0x10,0x43,0x00,0x00,0x00,0x44,0x8c,0xc0,0x02,0x82,0x36,0x00,0x00,0xc4,0xaf, -0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xde,0x4f,0x00,0x0c, -0x02,0x00,0x04,0x24,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08, -0x00,0x00,0x00,0x00,0xde,0x4f,0x00,0x0c,0x01,0x00,0x04,0x24,0xc0,0x02,0x82,0x36, -0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x7a,0x42,0x00,0x0c, -0x01,0x00,0x04,0x24,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08, -0x00,0x00,0x00,0x00,0x25,0xb0,0x05,0x3c,0x01,0x00,0x06,0x24,0x01,0x80,0x02,0x3c, -0x04,0x30,0x86,0x00,0xf1,0x02,0xa7,0x34,0xed,0x02,0xa4,0x34,0x6c,0x39,0x42,0x24, -0x18,0x03,0xa5,0x34,0x08,0x00,0x03,0x24,0x00,0x00,0xa2,0xac,0x00,0x00,0xe3,0xa0, -0x00,0x00,0x80,0xa0,0x00,0x00,0x86,0xa0,0x00,0x00,0x80,0xa0,0x00,0x00,0x86,0xa0, -0x00,0x00,0x80,0xa0,0x00,0x00,0x86,0xa0,0x00,0x00,0x80,0xa0,0x00,0x00,0x86,0xa0, -0x00,0x00,0x80,0xa0,0x00,0x00,0xe0,0xa0,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00, -0x01,0x80,0x02,0x3c,0x25,0xb0,0x03,0x3c,0xc8,0x39,0x42,0x24,0x18,0x03,0x63,0x34, -0x00,0x00,0x62,0xac,0x00,0x00,0x83,0x90,0x30,0x00,0x02,0x24,0x05,0x00,0x62,0x10, -0x21,0x20,0x00,0x00,0x31,0x00,0x02,0x24,0x02,0x00,0x62,0x10,0x01,0x00,0x04,0x24, -0x07,0x00,0x04,0x24,0x5b,0x4e,0x00,0x08,0x00,0x00,0x00,0x00,0x01,0x80,0x02,0x3c, -0x25,0xb0,0x03,0x3c,0x04,0x3a,0x42,0x24,0x18,0x03,0x63,0x34,0x02,0x80,0x04,0x3c, -0x00,0x00,0x62,0xac,0x08,0x00,0xe0,0x03,0xc4,0x7d,0x80,0xac,0x02,0x80,0x02,0x3c, -0x08,0x7b,0x42,0x24,0xc0,0x20,0x04,0x00,0x21,0x20,0x82,0x00,0x21,0x28,0x00,0x00, -0x00,0x60,0x06,0x40,0x01,0x00,0xc1,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40, -0x00,0x00,0x82,0x8c,0x00,0x00,0x00,0x00,0x09,0x00,0x44,0x10,0x00,0x00,0x00,0x00, -0x04,0x00,0x43,0x8c,0x21,0x28,0x40,0x00,0x00,0x00,0x42,0x8c,0x00,0x00,0x00,0x00, -0x00,0x00,0x62,0xac,0x04,0x00,0x43,0xac,0x00,0x00,0xa5,0xac,0x04,0x00,0xa5,0xac, -0x00,0x60,0x86,0x40,0x08,0x00,0xe0,0x03,0x21,0x10,0xa0,0x00,0x21,0x18,0x80,0x00, -0xe8,0xff,0xbd,0x27,0x01,0x01,0x62,0x2c,0x10,0x00,0xbf,0xaf,0x01,0x00,0x04,0x24, -0x01,0x02,0x65,0x2c,0x0a,0x00,0x40,0x14,0x21,0x30,0x00,0x00,0x02,0x00,0x04,0x24, -0x07,0x00,0xa0,0x14,0x01,0x08,0x62,0x2c,0x05,0x00,0x40,0x14,0x03,0x00,0x04,0x24, -0x10,0x00,0xbf,0x8f,0x21,0x10,0xc0,0x00,0x08,0x00,0xe0,0x03,0x18,0x00,0xbd,0x27, -0x89,0x4e,0x00,0x0c,0x00,0x00,0x00,0x00,0x10,0x00,0xbf,0x8f,0x21,0x30,0x40,0x00, -0x21,0x10,0xc0,0x00,0x08,0x00,0xe0,0x03,0x18,0x00,0xbd,0x27,0x02,0x80,0x03,0x3c, -0x20,0x7b,0x62,0x8c,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x00,0x60,0x06,0x40, -0x01,0x00,0xc1,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x10,0x00,0x83,0x8c, -0x02,0x80,0x02,0x3c,0x08,0x7b,0x42,0x24,0xc0,0x18,0x03,0x00,0x21,0x18,0x62,0x00, -0x00,0x00,0x65,0x8c,0x00,0x00,0x00,0x00,0x00,0x00,0x85,0xac,0x04,0x00,0xa4,0xac, -0x00,0x00,0x64,0xac,0x04,0x00,0x83,0xac,0x00,0x60,0x86,0x40,0x08,0x00,0xe0,0x03, -0x00,0x00,0x00,0x00,0x02,0x24,0x04,0x00,0xff,0x00,0x84,0x30,0xc0,0x18,0x04,0x00, -0x21,0x18,0x64,0x00,0x80,0x18,0x03,0x00,0x21,0x18,0x64,0x00,0x02,0x80,0x02,0x3c, -0x68,0x15,0x42,0x24,0x80,0x18,0x03,0x00,0x21,0x18,0x62,0x00,0x78,0x51,0x64,0x8c, -0xff,0xf1,0x02,0x24,0x24,0x20,0x82,0x00,0x08,0x00,0xe0,0x03,0x78,0x51,0x64,0xac, -0x02,0x24,0x04,0x00,0xff,0x00,0x84,0x30,0xc0,0x18,0x04,0x00,0x21,0x18,0x64,0x00, -0x80,0x18,0x03,0x00,0x21,0x18,0x64,0x00,0x02,0x80,0x02,0x3c,0x68,0x15,0x42,0x24, -0x80,0x18,0x03,0x00,0x21,0x18,0x62,0x00,0x78,0x51,0x64,0x8c,0xff,0xf1,0x02,0x24, -0x24,0x20,0x82,0x00,0x00,0x02,0x84,0x34,0x08,0x00,0xe0,0x03,0x78,0x51,0x64,0xac, -0xe0,0xff,0xbd,0x27,0x10,0x00,0xb0,0xaf,0xc0,0x80,0x04,0x00,0x21,0x80,0x04,0x02, -0x80,0x80,0x10,0x00,0x21,0x80,0x04,0x02,0x02,0x80,0x02,0x3c,0x68,0x15,0x42,0x24, -0x80,0x80,0x10,0x00,0x21,0x80,0x02,0x02,0x1c,0x00,0xbf,0xaf,0x18,0x00,0xb2,0xaf, -0x14,0x00,0xb1,0xaf,0x78,0x51,0x05,0x8e,0xff,0x1f,0x02,0x3c,0x25,0xb0,0x12,0x3c, -0xff,0xff,0x42,0x34,0x70,0x51,0x02,0xae,0x84,0x01,0x43,0x36,0xf8,0xff,0x02,0x24, -0x00,0x00,0x66,0x8c,0x24,0x28,0xa2,0x00,0xff,0xfe,0x02,0x24,0x24,0x28,0xa2,0x00, -0xff,0xef,0x03,0x24,0x24,0x28,0xa3,0x00,0x74,0x51,0x06,0xae,0x78,0x51,0x05,0xae, -0xce,0x0d,0x00,0x0c,0x21,0x88,0x80,0x00,0x7a,0x51,0x02,0x92,0x21,0x88,0x32,0x02, -0x1c,0x00,0xbf,0x8f,0x60,0x01,0x22,0xa2,0x18,0x00,0xb2,0x8f,0x64,0x51,0x00,0xae, -0x48,0x51,0x00,0xae,0x4c,0x51,0x00,0xae,0x50,0x51,0x00,0xae,0x54,0x51,0x00,0xae, -0x58,0x51,0x00,0xae,0x5c,0x51,0x00,0xae,0x60,0x51,0x00,0xae,0x14,0x00,0xb1,0x8f, -0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x20,0x00,0xbd,0x27,0xff,0x00,0xa5,0x30, -0xc0,0x10,0x05,0x00,0x21,0x10,0x45,0x00,0x80,0x10,0x02,0x00,0x21,0x10,0x45,0x00, -0x02,0x80,0x03,0x3c,0x68,0x15,0x63,0x24,0x80,0x10,0x02,0x00,0x21,0x10,0x43,0x00, -0x78,0x51,0x43,0x8c,0x25,0xb0,0x05,0x3c,0xff,0x00,0xc6,0x30,0x21,0x30,0xc5,0x00, -0xaf,0x01,0xc2,0x90,0x07,0x00,0x63,0x30,0x80,0x18,0x03,0x00,0x21,0x18,0x65,0x00, -0xff,0x00,0x88,0x30,0xff,0x00,0x49,0x30,0x84,0x01,0x66,0x8c,0x21,0x50,0x00,0x00, -0x21,0x58,0x00,0x00,0x2b,0x00,0x20,0x11,0x21,0x20,0x00,0x01,0x2b,0x00,0xc0,0x10, -0x2b,0x10,0x09,0x01,0x21,0x28,0x00,0x00,0x3e,0x4f,0x00,0x08,0x01,0x00,0x07,0x24, -0xff,0x00,0x65,0x30,0x1d,0x00,0xa2,0x2c,0x07,0x00,0x40,0x10,0xff,0xff,0x02,0x25, -0x04,0x10,0xa7,0x00,0x24,0x10,0x46,0x00,0xf9,0xff,0x40,0x10,0x01,0x00,0xa3,0x24, -0x21,0x58,0xa0,0x00,0xff,0xff,0x02,0x25,0xff,0x00,0x45,0x30,0x2b,0x18,0xab,0x00, -0x0f,0x00,0x60,0x14,0x2b,0x10,0x49,0x01,0x01,0x00,0x04,0x24,0x04,0x10,0xa4,0x00, -0x24,0x10,0x46,0x00,0xff,0xff,0xa7,0x24,0x04,0x00,0x40,0x10,0x01,0x00,0x43,0x25, -0x17,0x00,0x49,0x11,0xff,0x00,0x6a,0x30,0x21,0x40,0xa0,0x00,0xff,0x00,0xe5,0x30, -0x2b,0x10,0xab,0x00,0xf6,0xff,0x40,0x10,0x04,0x10,0xa4,0x00,0x2b,0x10,0x49,0x01, -0x08,0x00,0x40,0x10,0x21,0x20,0x00,0x01,0x23,0x10,0x2a,0x01,0x2a,0x10,0x62,0x01, -0x04,0x00,0x40,0x14,0x21,0x20,0x00,0x00,0x23,0x10,0x69,0x01,0x21,0x10,0x4a,0x00, -0xff,0x00,0x44,0x30,0x08,0x00,0xe0,0x03,0x21,0x10,0x80,0x00,0xfd,0xff,0x40,0x14, -0x21,0x20,0x00,0x00,0x23,0x10,0x09,0x01,0x5f,0x4f,0x00,0x08,0xff,0x00,0x44,0x30, -0x21,0x20,0x00,0x01,0x08,0x00,0xe0,0x03,0x21,0x10,0x80,0x00,0xff,0x00,0x84,0x30, -0xc0,0x10,0x04,0x00,0x21,0x10,0x44,0x00,0x80,0x10,0x02,0x00,0x21,0x10,0x44,0x00, -0x02,0x80,0x03,0x3c,0x68,0x15,0x63,0x24,0x80,0x10,0x02,0x00,0x21,0x10,0x43,0x00, -0x25,0xb0,0x06,0x3c,0x78,0x51,0x43,0x8c,0xff,0x00,0xa5,0x30,0x21,0x20,0x86,0x00, -0x21,0x28,0xa6,0x00,0x60,0x01,0x82,0x90,0xaf,0x01,0xa4,0x90,0x07,0x00,0x63,0x30, -0x80,0x18,0x03,0x00,0x21,0x18,0x66,0x00,0xff,0x00,0x48,0x30,0xff,0x00,0x89,0x30, -0x84,0x01,0x66,0x8c,0x21,0x50,0x00,0x00,0x21,0x58,0x00,0x00,0x2b,0x00,0x20,0x11, -0x21,0x20,0x00,0x01,0x2b,0x00,0xc0,0x10,0x2b,0x10,0x09,0x01,0x21,0x28,0x00,0x00, -0x8c,0x4f,0x00,0x08,0x01,0x00,0x07,0x24,0xff,0x00,0x65,0x30,0x1d,0x00,0xa2,0x2c, -0x07,0x00,0x40,0x10,0xff,0xff,0x02,0x25,0x04,0x10,0xa7,0x00,0x24,0x10,0x46,0x00, -0xf9,0xff,0x40,0x10,0x01,0x00,0xa3,0x24,0x21,0x58,0xa0,0x00,0xff,0xff,0x02,0x25, -0xff,0x00,0x45,0x30,0x2b,0x18,0xab,0x00,0x0f,0x00,0x60,0x14,0x2b,0x10,0x49,0x01, -0x01,0x00,0x04,0x24,0x04,0x10,0xa4,0x00,0x24,0x10,0x46,0x00,0xff,0xff,0xa7,0x24, -0x04,0x00,0x40,0x10,0x01,0x00,0x43,0x25,0x17,0x00,0x49,0x11,0xff,0x00,0x6a,0x30, -0x21,0x40,0xa0,0x00,0xff,0x00,0xe5,0x30,0x2b,0x10,0xab,0x00,0xf6,0xff,0x40,0x10, -0x04,0x10,0xa4,0x00,0x2b,0x10,0x49,0x01,0x08,0x00,0x40,0x10,0x21,0x20,0x00,0x01, -0x23,0x10,0x2a,0x01,0x2a,0x10,0x62,0x01,0x04,0x00,0x40,0x14,0x21,0x20,0x00,0x00, -0x23,0x10,0x69,0x01,0x21,0x10,0x4a,0x00,0xff,0x00,0x44,0x30,0x08,0x00,0xe0,0x03, -0x21,0x10,0x80,0x00,0xfd,0xff,0x40,0x14,0x21,0x20,0x00,0x00,0x23,0x10,0x09,0x01, -0xad,0x4f,0x00,0x08,0xff,0x00,0x44,0x30,0x21,0x20,0x00,0x01,0x08,0x00,0xe0,0x03, -0x21,0x10,0x80,0x00,0xe0,0xff,0xbd,0x27,0x02,0x80,0x02,0x3c,0x10,0x00,0xb0,0xaf, -0x68,0x15,0x50,0x24,0x18,0x00,0xb2,0xaf,0x14,0x00,0xb1,0xaf,0x1c,0x00,0xbf,0xaf, -0x21,0x88,0x00,0x00,0x21,0x90,0x00,0x02,0xee,0x4e,0x00,0x0c,0x21,0x20,0x20,0x02, -0x7a,0x51,0x02,0x92,0x21,0x28,0x00,0x00,0x80,0x10,0x02,0x00,0x21,0x10,0x52,0x00, -0xec,0x44,0x44,0x8c,0x60,0x45,0x43,0x8c,0x00,0x00,0x00,0x00,0x21,0x18,0x64,0x00, -0x42,0x18,0x03,0x00,0x44,0x51,0x03,0xae,0x21,0x10,0x05,0x02,0x01,0x00,0xa5,0x24, -0x1d,0x00,0xa3,0x28,0xb6,0x51,0x40,0xa0,0x7c,0x51,0x40,0xa0,0xfa,0xff,0x60,0x14, -0x99,0x51,0x40,0xa0,0x01,0x00,0x31,0x26,0x20,0x00,0x22,0x2a,0xd4,0x51,0x00,0xae, -0xe9,0xff,0x40,0x14,0x94,0x00,0x10,0x26,0x1c,0x00,0xbf,0x8f,0x18,0x00,0xb2,0x8f, -0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x20,0x00,0xbd,0x27, -0xc8,0xff,0xbd,0x27,0x02,0x80,0x02,0x3c,0x30,0x00,0xbe,0xaf,0x28,0x00,0xb6,0xaf, -0x68,0x15,0x46,0x24,0x34,0x00,0xbf,0xaf,0x2c,0x00,0xb7,0xaf,0x24,0x00,0xb5,0xaf, -0x20,0x00,0xb4,0xaf,0x1c,0x00,0xb3,0xaf,0x18,0x00,0xb2,0xaf,0x14,0x00,0xb1,0xaf, -0x10,0x00,0xb0,0xaf,0x8c,0x65,0xc2,0x8c,0xff,0x00,0x8d,0x30,0xff,0x00,0x03,0x24, -0xff,0xff,0x42,0x38,0x21,0xf0,0x00,0x00,0xff,0xff,0x04,0x34,0x0a,0xf0,0x62,0x00, -0x8c,0x65,0xc4,0xac,0xb0,0x00,0xa0,0x11,0x08,0x00,0x16,0x24,0x02,0x80,0x02,0x3c, -0xb8,0x90,0x45,0x24,0x90,0x44,0xc4,0x24,0xff,0x4f,0x00,0x08,0x21,0x88,0x00,0x00, -0x01,0x00,0x31,0x26,0x00,0x00,0x82,0xa0,0x1d,0x00,0x22,0x2a,0x0b,0x00,0x40,0x10, -0x01,0x00,0x84,0x24,0x21,0x10,0x25,0x02,0x00,0x00,0x42,0x90,0x00,0x00,0x00,0x00, -0xf7,0xff,0x40,0x10,0xfd,0xff,0x43,0x24,0x01,0x00,0x31,0x26,0x1d,0x00,0x22,0x2a, -0x00,0x00,0x83,0xa0,0xf7,0xff,0x40,0x14,0x01,0x00,0x84,0x24,0x02,0x80,0x02,0x3c, -0x68,0x15,0x4a,0x24,0x02,0x80,0x03,0x3c,0x02,0x80,0x02,0x3c,0x50,0x8e,0x6c,0x24, -0xd8,0x8d,0x4b,0x24,0x21,0x88,0x00,0x00,0x21,0x48,0x00,0x00,0x21,0x30,0x00,0x00, -0x21,0x40,0x2a,0x01,0x21,0x38,0x2c,0x01,0x21,0x10,0xe6,0x00,0x91,0x00,0x44,0x90, -0x00,0x00,0x45,0x90,0x21,0x18,0x06,0x01,0x01,0x00,0xc6,0x24,0x05,0x00,0xc2,0x28, -0xc5,0x43,0x64,0xa0,0xf8,0xff,0x40,0x14,0x34,0x43,0x65,0xa0,0x21,0x10,0x2b,0x02, -0x1d,0x00,0x44,0x90,0x00,0x00,0x45,0x90,0x21,0x18,0x2a,0x02,0x01,0x00,0x31,0x26, -0x1d,0x00,0x22,0x2a,0x73,0x44,0x64,0xa0,0x56,0x44,0x65,0xa0,0xeb,0xff,0x40,0x14, -0x05,0x00,0x29,0x25,0xa6,0x00,0xa0,0x11,0x02,0x80,0x02,0x3c,0x68,0x15,0x48,0x24, -0x02,0x80,0x03,0x3c,0x02,0x80,0x02,0x3c,0x4c,0x91,0x69,0x24,0xd8,0x90,0x47,0x24, -0x21,0x88,0x00,0x00,0x80,0x18,0x11,0x00,0x21,0x10,0x69,0x00,0x21,0x20,0x67,0x00, -0x00,0x00,0x46,0x8c,0x00,0x00,0x85,0x8c,0x01,0x00,0x31,0x26,0x21,0x18,0x68,0x00, -0x04,0x00,0x22,0x2a,0xec,0x44,0x65,0xac,0xf6,0xff,0x40,0x14,0x60,0x45,0x66,0xac, -0x02,0x80,0x02,0x3c,0x68,0x15,0x49,0x24,0x02,0x80,0x03,0x3c,0x02,0x80,0x02,0x3c, -0x4c,0x91,0x68,0x24,0xd8,0x90,0x47,0x24,0x04,0x00,0x11,0x24,0x80,0x20,0x11,0x00, -0x21,0x10,0x88,0x00,0x21,0x30,0x87,0x00,0x00,0x00,0x45,0x8c,0x00,0x00,0xc3,0x8c, -0x01,0x00,0x31,0x26,0x21,0x20,0x89,0x00,0x82,0x28,0x05,0x00,0x82,0x18,0x03,0x00, -0x1d,0x00,0x22,0x2a,0xec,0x44,0x83,0xac,0xf4,0xff,0x40,0x14,0x60,0x45,0x85,0xac, -0x02,0x80,0x02,0x3c,0x68,0x15,0x55,0x24,0x21,0x88,0x00,0x00,0x21,0xb8,0xa0,0x02, -0x21,0xa0,0x00,0x00,0x5a,0x50,0x00,0x08,0x21,0x90,0xa0,0x02,0x01,0x00,0x31,0x26, -0x20,0x00,0x22,0x2a,0x94,0x00,0x52,0x26,0x38,0x00,0x40,0x10,0x94,0x00,0x94,0x26, -0x78,0x51,0x44,0x8e,0x01,0x00,0x03,0x24,0x02,0x13,0x04,0x00,0x01,0x00,0x53,0x30, -0xf6,0xff,0x63,0x16,0x07,0x00,0x82,0x30,0x25,0xb0,0x03,0x3c,0x80,0x10,0x02,0x00, -0x21,0x10,0x43,0x00,0x84,0x01,0x45,0x8c,0x70,0x51,0x43,0x8e,0x21,0x20,0x20,0x02, -0x24,0x28,0xa3,0x00,0xce,0x0d,0x00,0x0c,0x74,0x51,0x45,0xae,0x7a,0x51,0x44,0x92, -0x5c,0x0d,0x00,0x0c,0xff,0x00,0x25,0x32,0x7a,0x51,0x50,0x92,0x00,0x00,0x00,0x00, -0x21,0x20,0x00,0x02,0x63,0x0d,0x00,0x0c,0x80,0x80,0x10,0x00,0x21,0x80,0x17,0x02, -0x48,0x51,0x40,0xae,0x4c,0x51,0x40,0xae,0x50,0x51,0x40,0xae,0x54,0x51,0x40,0xae, -0x58,0x51,0x40,0xae,0x5c,0x51,0x40,0xae,0x60,0x51,0x40,0xae,0x64,0x51,0x40,0xae, -0xec,0x44,0x04,0x8e,0x60,0x45,0x03,0x8e,0x26,0x10,0x53,0x00,0x21,0x30,0x00,0x00, -0x21,0x18,0x64,0x00,0x42,0x18,0x03,0x00,0x04,0x00,0x04,0x24,0x0a,0xb0,0x82,0x00, -0x44,0x51,0x43,0xae,0x21,0x20,0x95,0x02,0x21,0x10,0x86,0x00,0x01,0x00,0xc6,0x24, -0x1d,0x00,0xc3,0x28,0xb6,0x51,0x40,0xa0,0x7c,0x51,0x40,0xa0,0xfa,0xff,0x60,0x14, -0x99,0x51,0x40,0xa0,0x01,0x00,0x31,0x26,0x20,0x00,0x22,0x2a,0xd4,0x51,0x80,0xac, -0x94,0x00,0x52,0x26,0xca,0xff,0x40,0x14,0x94,0x00,0x94,0x26,0x25,0xb0,0x02,0x3c, -0x80,0x01,0x42,0x34,0x00,0x00,0x56,0xa0,0x03,0x00,0xc0,0x17,0x02,0x80,0x03,0x3c, -0x68,0x15,0x62,0x24,0x8c,0x65,0x40,0xac,0x34,0x00,0xbf,0x8f,0x30,0x00,0xbe,0x8f, -0x2c,0x00,0xb7,0x8f,0x28,0x00,0xb6,0x8f,0x24,0x00,0xb5,0x8f,0x20,0x00,0xb4,0x8f, -0x1c,0x00,0xb3,0x8f,0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f, -0x08,0x00,0xe0,0x03,0x38,0x00,0xbd,0x27,0x02,0x80,0x02,0x3c,0xb8,0x90,0x45,0x24, -0x90,0x44,0xc4,0x24,0x21,0x88,0x00,0x00,0x21,0x10,0x25,0x02,0x00,0x00,0x43,0x90, -0x01,0x00,0x31,0x26,0x1d,0x00,0x22,0x2a,0x00,0x00,0x83,0xa0,0xfa,0xff,0x40,0x14, -0x01,0x00,0x84,0x24,0x02,0x80,0x02,0x3c,0x68,0x15,0x4a,0x24,0x02,0x80,0x03,0x3c, -0x02,0x80,0x02,0x3c,0x74,0x8f,0x6c,0x24,0x14,0x8e,0x4b,0x24,0x21,0x88,0x00,0x00, -0x21,0x48,0x00,0x00,0x21,0x30,0x00,0x00,0x21,0x40,0x2a,0x01,0x21,0x38,0x2c,0x01, -0x21,0x10,0xe6,0x00,0x91,0x00,0x44,0x90,0x00,0x00,0x45,0x90,0x21,0x18,0x06,0x01, -0x01,0x00,0xc6,0x24,0x05,0x00,0xc2,0x28,0xc5,0x43,0x64,0xa0,0xf8,0xff,0x40,0x14, -0x34,0x43,0x65,0xa0,0x21,0x10,0x2b,0x02,0x1d,0x00,0x44,0x90,0x00,0x00,0x45,0x90, -0x21,0x18,0x2a,0x02,0x01,0x00,0x31,0x26,0x1d,0x00,0x22,0x2a,0x73,0x44,0x64,0xa0, -0x56,0x44,0x65,0xa0,0xeb,0xff,0x40,0x14,0x05,0x00,0x29,0x25,0x02,0x80,0x02,0x3c, -0x68,0x15,0x49,0x24,0x02,0x80,0x03,0x3c,0x02,0x80,0x02,0x3c,0x4c,0x91,0x68,0x24, -0xd8,0x90,0x47,0x24,0x21,0x88,0x00,0x00,0x80,0x18,0x11,0x00,0x21,0x10,0x68,0x00, -0x21,0x20,0x67,0x00,0x00,0x00,0x46,0x8c,0x00,0x00,0x85,0x8c,0x01,0x00,0x31,0x26, -0x21,0x18,0x69,0x00,0x1d,0x00,0x22,0x2a,0xec,0x44,0x65,0xac,0xf6,0xff,0x40,0x14, -0x60,0x45,0x66,0xac,0x4f,0x50,0x00,0x08,0x02,0x80,0x02,0x3c,0xd8,0xff,0xbd,0x27, -0xff,0xff,0x84,0x30,0x18,0x00,0xb2,0xaf,0xf0,0x01,0x92,0x30,0x02,0x91,0x12,0x00, -0x14,0x00,0xb1,0xaf,0xc0,0x88,0x12,0x00,0x21,0x88,0x32,0x02,0x80,0x88,0x11,0x00, -0x21,0x88,0x32,0x02,0x02,0x80,0x02,0x3c,0x68,0x15,0x42,0x24,0x80,0x88,0x11,0x00, -0x21,0x88,0x22,0x02,0x20,0x00,0xbf,0xaf,0x1c,0x00,0xb3,0xaf,0x10,0x00,0xb0,0xaf, -0x78,0x51,0x30,0x8e,0x00,0x02,0x82,0x30,0xff,0xfe,0x03,0x24,0x2b,0x10,0x02,0x00, -0x00,0x10,0x10,0x36,0x24,0x80,0x03,0x02,0x00,0x12,0x02,0x00,0x25,0x80,0x02,0x02, -0x70,0x51,0x25,0xae,0x78,0x51,0x30,0xae,0xa0,0x0e,0x00,0x0c,0x21,0x98,0xa0,0x00, -0xf8,0xff,0x03,0x24,0x24,0x80,0x03,0x02,0x07,0x00,0x42,0x30,0x25,0x80,0x02,0x02, -0x07,0x00,0x03,0x32,0x25,0xb0,0x02,0x3c,0x80,0x18,0x03,0x00,0x78,0x51,0x30,0xae, -0x21,0x18,0x62,0x00,0x84,0x01,0x62,0x8c,0x21,0x20,0x40,0x02,0x24,0x10,0x53,0x00, -0xce,0x0d,0x00,0x0c,0x74,0x51,0x22,0xae,0x7a,0x51,0x24,0x92,0x21,0x28,0x40,0x02, -0x20,0x00,0xbf,0x8f,0x1c,0x00,0xb3,0x8f,0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f, -0x10,0x00,0xb0,0x8f,0x5c,0x0d,0x00,0x08,0x28,0x00,0xbd,0x27,0xee,0x4e,0x00,0x08, -0xff,0x00,0x84,0x30,0x02,0x80,0x02,0x3c,0x68,0x15,0x43,0x24,0x1f,0x00,0x04,0x24, -0x78,0x51,0x62,0x8c,0xff,0xff,0x84,0x24,0x00,0x10,0x42,0x34,0x78,0x51,0x62,0xac, -0xfb,0xff,0x81,0x04,0x94,0x00,0x63,0x24,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00, -0x78,0xff,0xbd,0x27,0x60,0x00,0xb0,0xaf,0x25,0xb0,0x10,0x3c,0x70,0x00,0xb4,0xaf, -0xc4,0x02,0x14,0x36,0x00,0x00,0x80,0xae,0x74,0x00,0xb5,0xaf,0x6c,0x00,0xb3,0xaf, -0x68,0x00,0xb2,0xaf,0x64,0x00,0xb1,0xaf,0x84,0x00,0xbf,0xaf,0x80,0x00,0xbe,0xaf, -0x7c,0x00,0xb7,0xaf,0x78,0x00,0xb6,0xaf,0x04,0x00,0x02,0x36,0x04,0x0c,0x13,0x36, -0x00,0x00,0x43,0x8c,0x00,0x00,0x62,0x8e,0x0f,0x00,0x11,0x3c,0x24,0x18,0x71,0x00, -0x08,0x0c,0x12,0x36,0x4c,0x00,0xa2,0xaf,0x02,0xac,0x03,0x00,0x00,0x00,0x43,0x8e, -0x00,0x00,0x00,0x00,0x50,0x00,0xa3,0xaf,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34, -0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x21,0x20,0x00,0x00,0xdd,0x44,0x00,0x0c, -0xff,0xff,0x25,0x36,0x10,0x00,0xa2,0xaf,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34, -0x00,0x60,0x81,0x40,0xb3,0x0a,0x00,0x0c,0x64,0x00,0x04,0x24,0x7a,0x42,0x00,0x0c, -0x01,0x00,0x04,0x24,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38, -0x00,0x60,0x81,0x40,0x21,0x20,0x00,0x00,0xdd,0x44,0x00,0x0c,0xff,0xff,0x25,0x36, -0x14,0x00,0xa2,0xaf,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40, -0xb3,0x0a,0x00,0x0c,0x64,0x00,0x04,0x24,0x7a,0x42,0x00,0x0c,0x21,0x20,0x00,0x00, -0xe0,0x0e,0x05,0x36,0x00,0x00,0xad,0x8c,0xdc,0x0e,0x06,0x36,0x70,0x0e,0x07,0x36, -0x18,0x00,0xad,0xaf,0x00,0x00,0xc2,0x8c,0x74,0x0e,0x08,0x36,0x78,0x0e,0x09,0x36, -0x1c,0x00,0xa2,0xaf,0x00,0x00,0xe3,0x8c,0x7c,0x0e,0x0a,0x36,0x80,0x0e,0x0b,0x36, -0x20,0x00,0xa3,0xaf,0x00,0x00,0x0d,0x8d,0x84,0x0e,0x0c,0x36,0x88,0x0e,0x17,0x36, -0x24,0x00,0xad,0xaf,0x00,0x00,0x22,0x8d,0x8c,0x0e,0x0e,0x36,0xd0,0x0e,0x18,0x36, -0x28,0x00,0xa2,0xaf,0x00,0x00,0x43,0x8d,0xd8,0x0e,0x11,0x36,0xd4,0x0e,0x10,0x36, -0x2c,0x00,0xa3,0xaf,0x00,0x00,0x6d,0x8d,0xed,0x3f,0x04,0x3c,0xfb,0x92,0x84,0x34, -0x30,0x00,0xad,0xaf,0x00,0x00,0x82,0x8d,0x25,0xb0,0x1e,0x3c,0x21,0xb0,0x00,0x00, -0x34,0x00,0xa2,0xaf,0x00,0x00,0xe3,0x8e,0xff,0x03,0x0f,0x3c,0x38,0x00,0xa3,0xaf, -0x00,0x00,0xcd,0x8d,0x00,0x00,0x00,0x00,0x3c,0x00,0xad,0xaf,0x00,0x00,0x02,0x8f, -0x00,0x00,0x00,0x00,0x40,0x00,0xa2,0xaf,0x00,0x00,0x03,0x8e,0x00,0x00,0x00,0x00, -0x44,0x00,0xa3,0xaf,0x00,0x00,0x2d,0x8e,0x00,0x00,0x00,0x00,0x48,0x00,0xad,0xaf, -0x00,0x00,0xa4,0xac,0x00,0x00,0xc4,0xac,0x00,0x00,0xe4,0xac,0x00,0x00,0x04,0xad, -0x00,0x00,0x24,0xad,0x00,0x00,0x44,0xad,0x00,0x00,0x64,0xad,0x00,0x00,0x84,0xad, -0x00,0x00,0xe4,0xae,0x00,0x00,0xc4,0xad,0x00,0x00,0x04,0xaf,0x00,0x00,0x04,0xae, -0x00,0x00,0x24,0xae,0xd0,0x51,0x00,0x08,0x00,0x00,0x00,0x00,0x7a,0x00,0xa2,0x12, -0x00,0x10,0x03,0x3c,0xac,0x0e,0xc2,0x37,0x94,0x0e,0xc3,0x37,0x25,0xb0,0x09,0x3c, -0x00,0x00,0x4a,0x8c,0xbc,0x0e,0x29,0x35,0x00,0x00,0x64,0x8c,0xb4,0x0e,0xc2,0x37, -0x9c,0x0e,0xc3,0x37,0x00,0x00,0x45,0x8c,0x00,0x00,0x66,0x8c,0x00,0x00,0x27,0x8d, -0x24,0x20,0x8f,0x00,0x00,0xd8,0x02,0x3c,0x24,0x10,0x42,0x01,0x24,0x28,0xaf,0x00, -0x24,0x30,0xcf,0x00,0x24,0x38,0xef,0x00,0x02,0x24,0x04,0x00,0x20,0x01,0x03,0x24, -0x01,0x00,0x42,0x2c,0x02,0x2c,0x05,0x00,0x02,0x34,0x06,0x00,0xf2,0x00,0x83,0x10, -0x02,0x3c,0x07,0x00,0xf0,0x00,0xa3,0x10,0x20,0x00,0x03,0x24,0xee,0x00,0xc3,0x10, -0x00,0x00,0x00,0x00,0xec,0x00,0xe3,0x10,0x01,0x00,0x08,0x24,0x80,0x00,0x03,0x24, -0x08,0x00,0x83,0x10,0x21,0x20,0x00,0x00,0x06,0x00,0xa3,0x10,0x21,0x20,0x00,0x00, -0xe0,0x03,0x03,0x24,0x03,0x00,0xc3,0x10,0x00,0x00,0x00,0x00,0xe5,0x00,0xe3,0x10, -0x01,0x00,0x04,0x24,0x06,0x00,0x40,0x10,0x09,0x00,0x02,0x24,0x04,0x00,0x00,0x11, -0x00,0x00,0x00,0x00,0x6d,0x01,0x80,0x14,0x25,0xb0,0x12,0x3c,0x09,0x00,0x02,0x24, -0xde,0x00,0xc2,0x12,0x25,0xb0,0x04,0x3c,0x01,0x00,0xd6,0x26,0x0a,0x00,0xc2,0x2e, -0x1d,0x01,0x40,0x10,0x00,0x00,0x00,0x00,0xc8,0xff,0xa0,0x16,0x01,0x00,0x02,0x24, -0xa0,0x00,0x03,0x3c,0x25,0xb0,0x09,0x3c,0x30,0x54,0x62,0x34,0x04,0x0c,0x29,0x35, -0x00,0x00,0x22,0xad,0x25,0xb0,0x0d,0x3c,0x08,0x00,0x02,0x3c,0xe4,0x00,0x42,0x34, -0x08,0x0c,0xad,0x35,0x25,0xb0,0x09,0x3c,0x00,0x00,0xa2,0xad,0x28,0x0e,0x29,0x35, -0x80,0x80,0x02,0x3c,0x00,0x00,0x22,0xad,0x14,0x02,0x04,0x3c,0x16,0x68,0x02,0x3c, -0x48,0x01,0x83,0x34,0x40,0x0e,0xc5,0x37,0x44,0x0e,0xc6,0x37,0xa2,0x04,0x42,0x34, -0x25,0xb0,0x0d,0x3c,0x00,0x00,0xa3,0xac,0x4c,0x0e,0xad,0x35,0x00,0x00,0xc2,0xac, -0xd1,0x28,0x02,0x24,0x00,0x00,0xa2,0xad,0x14,0x02,0x03,0x3c,0x16,0x28,0x02,0x3c, -0x4d,0x01,0x63,0x34,0x60,0x0e,0xc7,0x37,0x64,0x0e,0xc8,0x37,0xba,0x08,0x42,0x34, -0x00,0x00,0xe3,0xac,0x25,0xb0,0x06,0x3c,0x00,0x00,0x02,0xad,0x00,0xfb,0x0d,0x3c, -0x25,0xb0,0x09,0x3c,0x00,0xf8,0x02,0x3c,0xd1,0x28,0x07,0x24,0x6c,0x0e,0xc6,0x34, -0x48,0x0e,0x29,0x35,0x01,0x00,0x42,0x34,0x01,0x00,0xad,0x35,0x00,0x00,0xc7,0xac, -0x03,0x00,0x04,0x24,0x00,0x00,0x2d,0xad,0x00,0x00,0x22,0xad,0x84,0x0a,0x00,0x0c, -0x58,0x00,0xaf,0xaf,0xa0,0x00,0x04,0x3c,0x25,0xb0,0x03,0x3c,0x25,0xb0,0x06,0x3c, -0x25,0xb0,0x07,0x3c,0xe4,0x00,0x02,0x24,0x33,0x54,0x84,0x34,0x04,0x0c,0x63,0x34, -0x08,0x0c,0xc6,0x34,0x28,0x0e,0xe7,0x34,0x00,0x00,0x64,0xac,0x00,0x00,0xc2,0xac, -0x00,0x00,0xe0,0xac,0x01,0x00,0x02,0x24,0x58,0x00,0xaf,0x8f,0x8a,0xff,0xa2,0x16, -0xac,0x0e,0xc2,0x37,0x00,0x10,0x03,0x3c,0x1f,0xdc,0x79,0x34,0x1f,0x8c,0x7f,0x34, -0x23,0x8c,0x6d,0x34,0xa0,0x00,0x03,0x3c,0x30,0x54,0x65,0x34,0x00,0x01,0x17,0x3c, -0x25,0xb0,0x09,0x3c,0x25,0xb0,0x03,0x3c,0x00,0x01,0xe2,0x36,0x20,0x08,0x29,0x35, -0x20,0x08,0x63,0x34,0x00,0x00,0x30,0x8d,0x00,0x00,0x62,0xac,0x25,0xb0,0x03,0x3c, -0x28,0x08,0x63,0x34,0x00,0x00,0x62,0xac,0x25,0xb0,0x02,0x3c,0x04,0x0c,0x42,0x34, -0x00,0x00,0x45,0xac,0x25,0xb0,0x03,0x3c,0x08,0x00,0x02,0x3c,0xe4,0x00,0x42,0x34, -0x08,0x0c,0x63,0x34,0x00,0x00,0x62,0xac,0x25,0xb0,0x03,0x3c,0x00,0x7c,0xf3,0x36, -0x00,0x48,0xf4,0x36,0x30,0x0e,0xc6,0x37,0x34,0x0e,0xc7,0x37,0x80,0x80,0x02,0x3c, -0x28,0x0e,0x63,0x34,0x00,0x00,0x62,0xac,0x00,0x00,0xd3,0xac,0x00,0x00,0xf4,0xac, -0x14,0x02,0x06,0x3c,0x16,0x68,0x07,0x3c,0x38,0x0e,0xc8,0x37,0x40,0x0e,0xca,0x37, -0x44,0x0e,0xcb,0x37,0x3c,0x0e,0xc9,0x37,0x02,0x01,0xc6,0x34,0xc7,0x04,0xe7,0x34, -0x00,0x00,0x19,0xad,0x25,0xb0,0x03,0x3c,0x00,0x00,0x3f,0xad,0x00,0x00,0x46,0xad, -0x25,0xb0,0x09,0x3c,0x00,0x00,0x67,0xad,0x25,0xb0,0x06,0x3c,0x00,0x10,0x07,0x3c, -0x50,0x0e,0xcc,0x37,0x58,0x0e,0xce,0x37,0x5c,0x0e,0xd8,0x37,0xd1,0x28,0x02,0x24, -0x23,0xdc,0xe7,0x34,0x4c,0x0e,0x29,0x35,0x6c,0x0e,0x63,0x34,0x54,0x0e,0xc6,0x34, -0x00,0x00,0x22,0xad,0x00,0x00,0x62,0xac,0x14,0x02,0x09,0x3c,0x00,0x00,0x93,0xad, -0x25,0xb0,0x02,0x3c,0x00,0x00,0xd4,0xac,0x00,0x00,0xc7,0xad,0x00,0x00,0x0d,0xaf, -0x16,0x28,0x0d,0x3c,0x48,0x0e,0x42,0x34,0x00,0xf8,0x06,0x3c,0x02,0x01,0x29,0x35, -0x07,0x0d,0xad,0x35,0x00,0xfb,0x03,0x3c,0x60,0x0e,0xd1,0x37,0x64,0x0e,0xd2,0x37, -0x00,0x00,0x29,0xae,0x03,0x00,0x04,0x24,0x00,0x00,0x4d,0xae,0x00,0x00,0x43,0xac, -0x00,0x00,0x46,0xac,0x84,0x0a,0x00,0x0c,0x58,0x00,0xaf,0xaf,0x00,0x02,0x02,0x3c, -0x25,0xb0,0x07,0x3c,0x25,0xb0,0x09,0x3c,0xd1,0x28,0x42,0x34,0x4c,0x0e,0xe7,0x34, -0x6c,0x0e,0x29,0x35,0x25,0xb0,0x0d,0x3c,0x00,0x00,0xe2,0xac,0x48,0x0e,0xad,0x35, -0x00,0x00,0x22,0xad,0x00,0xf8,0x03,0x3c,0x00,0xfb,0x02,0x3c,0x00,0x00,0xa2,0xad, -0x03,0x00,0x04,0x24,0x00,0x00,0xa3,0xad,0x84,0x0a,0x00,0x0c,0x00,0x00,0x00,0x00, -0x4c,0x00,0xa6,0x8f,0x25,0xb0,0x04,0x3c,0x04,0x0c,0x84,0x34,0x00,0x00,0x86,0xac, -0x50,0x00,0xa9,0x8f,0x25,0xb0,0x07,0x3c,0x25,0xb0,0x0d,0x3c,0x00,0x01,0x10,0x32, -0x08,0x0c,0xe7,0x34,0x28,0x0e,0xad,0x35,0x00,0x00,0xe9,0xac,0x2b,0x80,0x10,0x00, -0x00,0x00,0xa0,0xad,0x58,0x00,0xaf,0x8f,0x17,0xff,0x00,0x16,0xac,0x0e,0xc2,0x37, -0x25,0xb0,0x02,0x3c,0x25,0xb0,0x03,0x3c,0x20,0x08,0x42,0x34,0x28,0x08,0x63,0x34, -0x00,0x00,0x57,0xac,0x25,0xb0,0x09,0x3c,0x00,0x00,0x77,0xac,0xac,0x0e,0xc2,0x37, -0x94,0x0e,0xc3,0x37,0x00,0x00,0x4a,0x8c,0xbc,0x0e,0x29,0x35,0x00,0x00,0x64,0x8c, -0xb4,0x0e,0xc2,0x37,0x9c,0x0e,0xc3,0x37,0x00,0x00,0x45,0x8c,0x00,0x00,0x66,0x8c, -0x00,0x00,0x27,0x8d,0x24,0x20,0x8f,0x00,0x00,0xd8,0x02,0x3c,0x24,0x10,0x42,0x01, -0x24,0x28,0xaf,0x00,0x24,0x30,0xcf,0x00,0x24,0x38,0xef,0x00,0x02,0x24,0x04,0x00, -0x20,0x01,0x03,0x24,0x01,0x00,0x42,0x2c,0x02,0x2c,0x05,0x00,0x02,0x34,0x06,0x00, -0x10,0xff,0x83,0x14,0x02,0x3c,0x07,0x00,0x80,0x00,0x03,0x24,0x16,0xff,0x83,0x14, -0x21,0x40,0x00,0x00,0xc3,0x51,0x00,0x08,0x21,0x20,0x00,0x00,0xff,0xff,0x02,0x34, -0xc4,0x02,0x84,0x34,0x00,0x00,0x82,0xac,0x94,0x0e,0xc3,0x37,0x9c,0x0e,0xc2,0x37, -0xa4,0x0e,0xc4,0x37,0xac,0x0e,0xc7,0x37,0x00,0x00,0x66,0x8c,0x00,0x00,0x49,0x8c, -0x00,0x00,0x8b,0x8c,0x00,0x00,0xe5,0x8c,0x02,0x80,0x07,0x3c,0x68,0x15,0xe7,0x24, -0x0c,0x40,0xe3,0x8c,0x10,0x40,0xe4,0x8c,0xb4,0x0e,0xc2,0x37,0x00,0x00,0x47,0x8c, -0x25,0xb0,0x0d,0x3c,0x00,0xfc,0x02,0x24,0x24,0x30,0xcf,0x00,0x24,0x28,0xaf,0x00, -0xbc,0x0e,0xad,0x35,0x00,0x00,0xa8,0x8d,0x24,0x20,0x82,0x00,0x02,0x34,0x06,0x00, -0x24,0x18,0x62,0x00,0x02,0x2c,0x05,0x00,0xc4,0x0e,0xca,0x37,0xcc,0x0e,0xcc,0x37, -0xf0,0xff,0x02,0x3c,0xff,0x03,0x42,0x34,0x25,0x18,0x66,0x00,0x25,0x20,0x85,0x00, -0x00,0x00,0x46,0x8d,0x24,0x48,0x2f,0x01,0x00,0x00,0x85,0x8d,0x24,0x38,0xef,0x00, -0x24,0x20,0x82,0x00,0x24,0x18,0x62,0x00,0x82,0x49,0x09,0x00,0x82,0x39,0x07,0x00, -0x0f,0xc0,0x02,0x3c,0xff,0xff,0x42,0x34,0x25,0x18,0x69,0x00,0x25,0x20,0x87,0x00, -0x24,0x58,0x6f,0x01,0x24,0x40,0x0f,0x01,0x24,0x20,0x82,0x00,0x24,0x18,0x62,0x00, -0x00,0x59,0x0b,0x00,0x00,0x41,0x08,0x00,0x24,0x30,0xcf,0x00,0x24,0x28,0xaf,0x00, -0x02,0x80,0x02,0x3c,0x68,0x15,0x42,0x24,0x25,0x18,0x6b,0x00,0x25,0x20,0x88,0x00, -0x02,0x34,0x06,0x00,0x02,0x2c,0x05,0x00,0x01,0x00,0xd6,0x26,0x0c,0x40,0x43,0xac, -0x10,0x40,0x44,0xac,0x14,0x40,0x46,0xa4,0x16,0x40,0x45,0xa4,0x0a,0x00,0xc2,0x2e, -0xe5,0xfe,0x40,0x14,0x00,0x00,0x00,0x00,0x18,0x00,0xad,0x8f,0x25,0xb0,0x02,0x3c, -0xe0,0x0e,0x43,0x34,0x10,0x00,0xa6,0x8f,0x00,0x00,0x6d,0xac,0x1c,0x00,0xa3,0x8f, -0xdc,0x0e,0x47,0x34,0x70,0x0e,0x48,0x34,0x00,0x00,0xe3,0xac,0x20,0x00,0xa7,0x8f, -0x74,0x0e,0x49,0x34,0x78,0x0e,0x4a,0x34,0x00,0x00,0x07,0xad,0x24,0x00,0xad,0x8f, -0x7c,0x0e,0x4b,0x34,0x80,0x0e,0x4c,0x34,0x00,0x00,0x2d,0xad,0x28,0x00,0xa3,0x8f, -0x25,0xb0,0x0d,0x3c,0x84,0x0e,0xad,0x35,0x00,0x00,0x43,0xad,0x2c,0x00,0xa7,0x8f, -0x88,0x0e,0x52,0x34,0x8c,0x0e,0x4e,0x34,0x00,0x00,0x67,0xad,0x30,0x00,0xa9,0x8f, -0xd4,0x0e,0x51,0x34,0xd0,0x0e,0x42,0x34,0x00,0x00,0x89,0xad,0x34,0x00,0xa3,0x8f, -0x0f,0x00,0x10,0x3c,0xff,0xff,0x05,0x36,0x00,0x00,0xa3,0xad,0x38,0x00,0xa7,0x8f, -0x21,0x20,0x00,0x00,0x00,0x00,0x47,0xae,0x3c,0x00,0xa9,0x8f,0x00,0x00,0x00,0x00, -0x00,0x00,0xc9,0xad,0x40,0x00,0xad,0x8f,0x00,0x00,0x00,0x00,0x00,0x00,0x4d,0xac, -0x44,0x00,0xa2,0x8f,0x00,0x00,0x00,0x00,0x00,0x00,0x22,0xae,0x48,0x00,0xa3,0x8f, -0x00,0x00,0x00,0x00,0x00,0x00,0x43,0xae,0xba,0x44,0x00,0x0c,0x00,0x00,0x00,0x00, -0xb3,0x0a,0x00,0x0c,0x64,0x00,0x04,0x24,0x7a,0x42,0x00,0x0c,0x01,0x00,0x04,0x24, -0x14,0x00,0xa6,0x8f,0xff,0xff,0x05,0x36,0xba,0x44,0x00,0x0c,0x21,0x20,0x00,0x00, -0xb3,0x0a,0x00,0x0c,0x64,0x00,0x04,0x24,0x84,0x00,0xbf,0x8f,0x80,0x00,0xbe,0x8f, -0x7c,0x00,0xb7,0x8f,0x78,0x00,0xb6,0x8f,0x74,0x00,0xb5,0x8f,0x70,0x00,0xb4,0x8f, -0x6c,0x00,0xb3,0x8f,0x68,0x00,0xb2,0x8f,0x64,0x00,0xb1,0x8f,0x60,0x00,0xb0,0x8f, -0x21,0x20,0x00,0x00,0x7a,0x42,0x00,0x08,0x88,0x00,0xbd,0x27,0x94,0x0e,0x42,0x36, -0x9c,0x0e,0x43,0x36,0xa4,0x0e,0x44,0x36,0xac,0x0e,0x45,0x36,0x02,0x80,0x0d,0x3c, -0x00,0x00,0x47,0x8c,0x68,0x15,0xad,0x25,0x00,0x00,0x6a,0x8c,0x00,0x00,0x8c,0x8c, -0x00,0x00,0xa3,0x8c,0x10,0x40,0xa4,0x8d,0xb4,0x0e,0x42,0x36,0x00,0x00,0x48,0x8c, -0x0c,0x40,0xa5,0x8d,0x25,0xb0,0x02,0x3c,0x00,0xfc,0x13,0x24,0xbc,0x0e,0x42,0x34, -0x24,0x18,0x6f,0x00,0x00,0x00,0x49,0x8c,0x02,0x1c,0x03,0x00,0x24,0x38,0xef,0x00, -0x24,0x20,0x93,0x00,0xf0,0xff,0x06,0x3c,0x25,0x20,0x83,0x00,0xff,0x03,0xc6,0x34, -0x02,0x3c,0x07,0x00,0xc4,0x0e,0x42,0x36,0x24,0x28,0xb3,0x00,0x24,0x40,0x0f,0x01, -0xcc,0x0e,0x4b,0x36,0x25,0x28,0xa7,0x00,0x24,0x20,0x86,0x00,0x00,0x00,0x47,0x8c, -0x24,0x50,0x4f,0x01,0x00,0x00,0x63,0x8d,0x82,0x41,0x08,0x00,0x0f,0xc0,0x02,0x3c, -0xff,0xff,0x42,0x34,0x25,0x20,0x88,0x00,0x82,0x51,0x0a,0x00,0x24,0x28,0xa6,0x00, -0x24,0x48,0x2f,0x01,0x24,0x88,0x82,0x00,0x25,0x28,0xaa,0x00,0x24,0x60,0x8f,0x01, -0x00,0x49,0x09,0x00,0x25,0x88,0x29,0x02,0x24,0x28,0xa2,0x00,0x24,0x18,0x6f,0x00, -0x00,0x61,0x0c,0x00,0x24,0x38,0xef,0x00,0x25,0x28,0xac,0x00,0x02,0x3c,0x07,0x00, -0x02,0x1c,0x03,0x00,0x82,0x27,0x11,0x00,0x01,0x00,0x02,0x24,0x16,0x40,0xa3,0xa5, -0x14,0x40,0xa7,0xa5,0x0c,0x40,0xa5,0xad,0x4a,0x00,0x82,0x10,0x10,0x40,0xb1,0xad, -0x80,0x0c,0x4c,0x36,0x00,0x00,0x8a,0x8d,0x82,0x72,0x05,0x00,0xff,0x03,0xce,0x31, -0x00,0x02,0xc3,0x31,0x25,0x10,0xd3,0x01,0x0b,0x70,0x43,0x00,0x82,0x85,0x0a,0x00, -0x18,0x00,0xd0,0x01,0xff,0x03,0xaf,0x30,0x00,0x02,0xa3,0x30,0x25,0x10,0xf3,0x01, -0x0b,0x78,0x43,0x00,0x02,0x75,0x11,0x00,0xff,0x03,0xce,0x31,0xc0,0xff,0x08,0x3c, -0x25,0x18,0xd3,0x01,0x00,0x02,0xc2,0x31,0x00,0xfc,0x06,0x35,0x0b,0x70,0x62,0x00, -0x24,0x38,0x46,0x01,0x94,0x0c,0x4a,0x36,0xff,0x0f,0x09,0x3c,0xff,0xff,0x29,0x35, -0x88,0x0c,0x54,0x36,0x12,0x20,0x00,0x00,0x02,0x22,0x04,0x00,0x3f,0x00,0x82,0x30, -0x18,0x00,0xf0,0x01,0x82,0x7a,0x11,0x00,0xff,0x03,0xef,0x31,0x00,0x14,0x02,0x00, -0x25,0x38,0xe2,0x00,0x00,0x02,0xe3,0x31,0x25,0x10,0xf3,0x01,0x0b,0x78,0x43,0x00, -0xc0,0x03,0x84,0x30,0x80,0x25,0x04,0x00,0x9c,0x0c,0x4b,0x36,0x12,0x28,0x00,0x00, -0x02,0x2a,0x05,0x00,0xff,0x03,0xa2,0x30,0x25,0x10,0xe2,0x00,0x00,0x00,0x82,0xad, -0x00,0x00,0x42,0x8d,0x00,0x00,0x00,0x00,0x24,0x10,0x49,0x00,0x25,0x10,0x44,0x00, -0x00,0x00,0x42,0xad,0x00,0x00,0x8a,0x8e,0x00,0x00,0x00,0x00,0x24,0x40,0x48,0x01, -0x82,0x85,0x08,0x00,0x18,0x00,0xd0,0x01,0x24,0x30,0x46,0x01,0x12,0x18,0x00,0x00, -0x02,0x1a,0x03,0x00,0x3f,0x00,0x62,0x30,0x18,0x00,0xf0,0x01,0x00,0x14,0x02,0x00, -0x25,0x30,0xc2,0x00,0xc0,0x03,0x63,0x30,0x80,0x1d,0x03,0x00,0x12,0x20,0x00,0x00, -0x02,0x22,0x04,0x00,0xff,0x03,0x82,0x30,0x25,0x10,0xc2,0x00,0x00,0x00,0x82,0xae, -0x00,0x00,0x62,0x8d,0x00,0x00,0x00,0x00,0x24,0x10,0x49,0x00,0x25,0x10,0x43,0x00, -0x00,0x00,0x62,0xad,0x00,0x17,0x16,0x00,0x25,0xb0,0x03,0x3c,0xdd,0xdd,0x42,0x34, -0xc4,0x02,0x63,0x34,0x00,0x00,0x62,0xac,0xec,0x52,0x00,0x08,0x00,0x00,0x00,0x00, -0xe0,0xff,0xbd,0x27,0x44,0x00,0x02,0x24,0x10,0x00,0xa2,0xa3,0x49,0x00,0x03,0x24, -0x47,0x00,0x02,0x24,0x02,0x80,0x07,0x3c,0x8c,0x97,0xe7,0x24,0x11,0x00,0xa3,0xa3, -0x12,0x00,0xa2,0xa3,0x10,0x27,0x03,0x24,0x01,0x00,0x02,0x24,0x01,0x80,0x06,0x3c, -0x10,0x00,0xa5,0x27,0x21,0x20,0xe0,0x00,0xe8,0x51,0xc6,0x24,0x0c,0x00,0xe3,0xac, -0x14,0x00,0xe2,0xa0,0x18,0x00,0xbf,0xaf,0xfb,0x0c,0x00,0x0c,0x13,0x00,0xa0,0xa3, -0x18,0x00,0xbf,0x8f,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x20,0x00,0xbd,0x27, -0xd0,0xff,0xbd,0x27,0x25,0xb0,0x02,0x3c,0x20,0x00,0xb4,0xaf,0x1c,0x00,0xb3,0xaf, -0x03,0x0d,0x44,0x34,0x2c,0x00,0xbf,0xaf,0x28,0x00,0xb6,0xaf,0x24,0x00,0xb5,0xaf, -0x18,0x00,0xb2,0xaf,0x14,0x00,0xb1,0xaf,0x10,0x00,0xb0,0xaf,0x00,0x00,0x83,0x90, -0x42,0x00,0x45,0x34,0xff,0x00,0x73,0x30,0x70,0x00,0x74,0x32,0x29,0x00,0x80,0x16, -0x8f,0x00,0x62,0x32,0xff,0xff,0x02,0x24,0x00,0x00,0xa2,0xa0,0x00,0x60,0x01,0x40, -0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x0f,0x00,0x11,0x3c, -0x18,0x00,0x04,0x24,0xdd,0x44,0x00,0x0c,0xff,0xff,0x25,0x36,0x21,0x80,0x40,0x00, -0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,0xb3,0x0a,0x00,0x0c, -0x64,0x00,0x04,0x24,0x00,0x80,0x06,0x36,0xff,0xff,0x25,0x36,0xba,0x44,0x00,0x0c, -0x18,0x00,0x04,0x24,0x84,0x0a,0x00,0x0c,0x03,0x00,0x04,0x24,0x21,0x30,0xa0,0x02, -0xff,0xff,0x25,0x36,0x5c,0x00,0x80,0x16,0x21,0x20,0x00,0x00,0x2c,0x00,0xbf,0x8f, -0x28,0x00,0xb6,0x8f,0x24,0x00,0xb5,0x8f,0x20,0x00,0xb4,0x8f,0x1c,0x00,0xb3,0x8f, -0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x25,0xb0,0x02,0x3c, -0x42,0x00,0x42,0x34,0x30,0x00,0xbd,0x27,0x00,0x00,0x40,0xa0,0x08,0x00,0xe0,0x03, -0x00,0x00,0x00,0x00,0x00,0x00,0x82,0xa0,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34, -0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x0f,0x00,0x11,0x3c,0x21,0x20,0x00,0x00, -0xdd,0x44,0x00,0x0c,0xff,0xff,0x25,0x36,0x21,0xa8,0x40,0x00,0x00,0x60,0x01,0x40, -0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,0xb3,0x0a,0x00,0x0c,0x64,0x00,0x04,0x24, -0x7a,0x42,0x00,0x0c,0x01,0x00,0x04,0x24,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34, -0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x21,0x20,0x00,0x00,0xdd,0x44,0x00,0x0c, -0xff,0xff,0x25,0x36,0x21,0xb0,0x40,0x00,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34, -0x00,0x60,0x81,0x40,0x64,0x00,0x04,0x24,0xb3,0x0a,0x00,0x0c,0x08,0x00,0x10,0x3c, -0xff,0xff,0x10,0x36,0x7a,0x42,0x00,0x0c,0x21,0x20,0x00,0x00,0x01,0x00,0x12,0x3c, -0x24,0x30,0xb0,0x02,0x25,0x30,0xd2,0x00,0xff,0xff,0x25,0x36,0xba,0x44,0x00,0x0c, -0x21,0x20,0x00,0x00,0xb3,0x0a,0x00,0x0c,0x64,0x00,0x04,0x24,0x24,0x80,0xd0,0x02, -0x7a,0x42,0x00,0x0c,0x01,0x00,0x04,0x24,0x25,0x30,0x12,0x02,0xff,0xff,0x25,0x36, -0xba,0x44,0x00,0x0c,0x21,0x20,0x00,0x00,0xb3,0x0a,0x00,0x0c,0x64,0x00,0x04,0x24, -0x7a,0x42,0x00,0x0c,0x21,0x20,0x00,0x00,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34, -0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x0f,0x00,0x11,0x3c,0x18,0x00,0x04,0x24, -0xdd,0x44,0x00,0x0c,0xff,0xff,0x25,0x36,0x21,0x80,0x40,0x00,0x00,0x60,0x01,0x40, -0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,0xb3,0x0a,0x00,0x0c,0x64,0x00,0x04,0x24, -0x00,0x80,0x06,0x36,0xff,0xff,0x25,0x36,0xba,0x44,0x00,0x0c,0x18,0x00,0x04,0x24, -0x84,0x0a,0x00,0x0c,0x03,0x00,0x04,0x24,0x21,0x30,0xa0,0x02,0xff,0xff,0x25,0x36, -0xa6,0xff,0x80,0x12,0x21,0x20,0x00,0x00,0x25,0xb0,0x02,0x3c,0x03,0x0d,0x42,0x34, -0x00,0x00,0x53,0xa0,0xba,0x44,0x00,0x0c,0x00,0x00,0x00,0x00,0xb3,0x0a,0x00,0x0c, -0x64,0x00,0x04,0x24,0x7a,0x42,0x00,0x0c,0x01,0x00,0x04,0x24,0xff,0xff,0x25,0x36, -0x21,0x30,0xc0,0x02,0xba,0x44,0x00,0x0c,0x21,0x20,0x00,0x00,0xb3,0x0a,0x00,0x0c, -0x64,0x00,0x04,0x24,0x2c,0x00,0xbf,0x8f,0x28,0x00,0xb6,0x8f,0x24,0x00,0xb5,0x8f, -0x20,0x00,0xb4,0x8f,0x1c,0x00,0xb3,0x8f,0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f, -0x10,0x00,0xb0,0x8f,0x21,0x20,0x00,0x00,0x7a,0x42,0x00,0x08,0x30,0x00,0xbd,0x27, -0xd0,0xff,0xbd,0x27,0x28,0x00,0xb4,0xaf,0x02,0x80,0x14,0x3c,0x2c,0x00,0xbf,0xaf, -0x24,0x00,0xb3,0xaf,0x20,0x00,0xb2,0xaf,0x1c,0x00,0xb1,0xaf,0x18,0x00,0xb0,0xaf, -0x68,0x15,0x86,0x26,0x0c,0x40,0xc2,0x8c,0x00,0x00,0x00,0x00,0x82,0x17,0x02,0x00, -0x01,0x00,0x42,0x30,0x07,0x00,0x40,0x14,0x68,0x15,0x85,0x26,0x08,0x40,0xc2,0x8c, -0x01,0x00,0x03,0x24,0x42,0x17,0x02,0x00,0x03,0x00,0x42,0x30,0xf0,0x00,0x43,0x10, -0x25,0xb0,0x02,0x3c,0x0c,0x40,0xa2,0x8c,0x01,0x00,0x03,0x24,0x82,0x17,0x02,0x00, -0x01,0x00,0x44,0x30,0x0a,0x00,0x83,0x10,0x00,0x00,0x00,0x00,0x2c,0x00,0xbf,0x8f, -0x28,0x00,0xb4,0x8f,0x24,0x00,0xb3,0x8f,0x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f, -0x18,0x00,0xb0,0x8f,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x30,0x00,0xbd,0x27, -0x08,0x40,0xa2,0x8c,0x00,0x00,0x00,0x00,0x42,0x17,0x02,0x00,0x03,0x00,0x42,0x30, -0xf2,0xff,0x44,0x14,0x25,0xb0,0x02,0x3c,0x0e,0x0c,0x44,0x34,0x00,0x00,0x83,0x90, -0x00,0x01,0x02,0x24,0xff,0x00,0x63,0x30,0x01,0x00,0x63,0x24,0x8b,0x01,0x62,0x10, -0x00,0x00,0x00,0x00,0x00,0x00,0x83,0xa0,0x68,0x15,0x84,0x26,0x10,0x40,0x82,0x8c, -0x01,0x00,0x03,0x24,0x82,0x17,0x02,0x00,0xa4,0x01,0x43,0x10,0x0f,0x00,0x10,0x3c, -0xc7,0x42,0x92,0x90,0x68,0x15,0x90,0x26,0xc6,0x42,0x03,0x92,0x25,0xb0,0x11,0x3c, -0x62,0x0c,0x22,0x36,0x00,0x00,0x52,0xa0,0x17,0x01,0x60,0x10,0x01,0x00,0x02,0x24, -0x03,0x0d,0x23,0x36,0x00,0x00,0x62,0x90,0x00,0x00,0x00,0x00,0x70,0x00,0x42,0x30, -0x3e,0x01,0x40,0x14,0x63,0x0c,0x23,0x36,0xc4,0x42,0x02,0x96,0x00,0x00,0x00,0x00, -0x23,0x20,0x52,0x00,0x2b,0x18,0x52,0x00,0x23,0x10,0x42,0x02,0x0a,0x10,0x83,0x00, -0x03,0x00,0x42,0x2c,0x0b,0x01,0x40,0x10,0x00,0x00,0x00,0x00,0xc4,0x42,0x03,0x96, -0x63,0x0c,0x22,0x36,0x00,0x00,0x43,0xa0,0x68,0x15,0x83,0x26,0xc3,0x42,0x62,0x90, -0x08,0x40,0x66,0x8c,0xc2,0x42,0x72,0xa0,0x23,0x20,0x52,0x00,0x2b,0x38,0x42,0x02, -0x23,0x50,0x42,0x02,0x02,0x2c,0x06,0x00,0x0b,0x50,0x87,0x00,0x3f,0x00,0xa5,0x30, -0x3f,0x00,0xc4,0x30,0x24,0x00,0x02,0x24,0x20,0x00,0x03,0x24,0x23,0x10,0x44,0x00, -0x2d,0x01,0x40,0x15,0x23,0x18,0x65,0x00,0x21,0x30,0x80,0x00,0x21,0x48,0xa0,0x00, -0x02,0x80,0x0b,0x3c,0x68,0x15,0x83,0x26,0x80,0x10,0x06,0x00,0x21,0x10,0x43,0x00, -0x0c,0x40,0x63,0x8c,0x18,0x40,0x44,0x8c,0xff,0x03,0x67,0x30,0x1b,0x01,0xe0,0x10, -0x82,0x2d,0x04,0x00,0x00,0x02,0x62,0x30,0x04,0x00,0x40,0x10,0x18,0x00,0xe5,0x00, -0x00,0xfc,0x02,0x24,0x25,0x38,0xe2,0x00,0x18,0x00,0xe5,0x00,0x82,0x22,0x03,0x00, -0xff,0x03,0x84,0x30,0x00,0x02,0x83,0x30,0x12,0x10,0x00,0x00,0x02,0x12,0x02,0x00, -0x03,0x00,0x60,0x10,0xff,0x03,0x48,0x30,0x00,0xfc,0x02,0x24,0x25,0x20,0x82,0x00, -0x18,0x00,0x85,0x00,0x80,0x2d,0x05,0x00,0x25,0xb0,0x06,0x3c,0x80,0x0c,0xc7,0x34, -0x94,0x0c,0xc6,0x34,0x12,0x20,0x00,0x00,0x02,0x22,0x04,0x00,0x3f,0x00,0x82,0x30, -0x00,0x14,0x02,0x00,0x25,0x28,0xa2,0x00,0x25,0x28,0xa8,0x00,0x10,0x00,0xa5,0xaf, -0x00,0x00,0xe5,0xac,0x00,0x00,0xc3,0x8c,0xff,0x0f,0x02,0x3c,0xc0,0x03,0x84,0x30, -0xff,0xff,0x42,0x34,0x80,0x25,0x04,0x00,0x24,0x18,0x62,0x00,0x25,0x18,0x64,0x00, -0x10,0x00,0xa3,0xaf,0x00,0x00,0xc3,0xac,0x68,0x15,0x83,0x26,0x08,0x40,0x62,0x8c, -0x00,0x00,0x00,0x00,0x08,0x01,0x40,0x04,0xc0,0x28,0x09,0x00,0x21,0x28,0xa3,0x00, -0xac,0x40,0xa3,0x90,0x25,0xb0,0x04,0x3c,0x22,0x0a,0x82,0x34,0x00,0x00,0x43,0xa0, -0xad,0x40,0xa6,0x90,0x23,0x0a,0x82,0x34,0x24,0x0a,0x87,0x34,0x00,0x00,0x46,0xa0, -0xae,0x40,0xa3,0x90,0x25,0x0a,0x86,0x34,0x26,0x0a,0x88,0x34,0x00,0x00,0xe3,0xa0, -0xaf,0x40,0xa2,0x90,0x27,0x0a,0x87,0x34,0x28,0x0a,0x89,0x34,0x00,0x00,0xc2,0xa0, -0xb0,0x40,0xa3,0x90,0x29,0x0a,0x84,0x34,0x00,0x00,0x03,0xa1,0xb1,0x40,0xa2,0x90, -0x00,0x00,0x00,0x00,0x00,0x00,0xe2,0xa0,0xb2,0x40,0xa3,0x90,0x00,0x00,0x00,0x00, -0x00,0x00,0x23,0xa1,0xb3,0x40,0xa2,0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x82,0xa0, -0x8e,0x7d,0x63,0x91,0x22,0x00,0x02,0x24,0x03,0x00,0x62,0x10,0x92,0x00,0x02,0x24, -0x62,0xff,0x62,0x14,0x00,0x00,0x00,0x00,0x68,0x15,0x82,0x26,0x08,0x40,0x43,0x8c, -0x01,0x00,0x44,0x39,0x24,0x00,0x02,0x24,0x02,0x1a,0x03,0x00,0x3f,0x00,0x63,0x30, -0x01,0x00,0x84,0x30,0x04,0x01,0x80,0x10,0x23,0x28,0x43,0x00,0x42,0x18,0x0a,0x00, -0x40,0x10,0x03,0x00,0x21,0x50,0x43,0x00,0x68,0x15,0x83,0x26,0xc3,0x42,0x62,0x90, -0x00,0x00,0x00,0x00,0x2b,0x10,0x42,0x02,0x08,0x01,0x40,0x10,0x21,0x20,0x00,0x00, -0x2b,0x10,0x45,0x01,0x07,0x00,0x40,0x10,0x24,0x00,0x04,0x24,0x08,0x40,0x62,0x8c, -0x00,0x00,0x00,0x00,0x02,0x12,0x02,0x00,0x3f,0x00,0x42,0x30,0x21,0x20,0x4a,0x00, -0x68,0x15,0x83,0x26,0x80,0x10,0x04,0x00,0x10,0x40,0x66,0x8c,0x21,0x10,0x43,0x00, -0x18,0x40,0x44,0x8c,0x82,0x3a,0x06,0x00,0xff,0x03,0xe7,0x30,0xf0,0x00,0xe0,0x10, -0x82,0x2d,0x04,0x00,0x00,0x02,0xe2,0x30,0x04,0x00,0x40,0x10,0x18,0x00,0xe5,0x00, -0x00,0xfc,0x02,0x24,0x25,0x38,0xe2,0x00,0x18,0x00,0xe5,0x00,0x02,0x25,0x06,0x00, -0xff,0x03,0x84,0x30,0x00,0x02,0x83,0x30,0x12,0x10,0x00,0x00,0x02,0x12,0x02,0x00, -0x03,0x00,0x60,0x10,0xff,0x03,0x48,0x30,0x00,0xfc,0x02,0x24,0x25,0x20,0x82,0x00, -0x18,0x00,0x85,0x00,0x80,0x2d,0x05,0x00,0x25,0xb0,0x06,0x3c,0x88,0x0c,0xc7,0x34, -0x9c,0x0c,0xc6,0x34,0x12,0x20,0x00,0x00,0x02,0x22,0x04,0x00,0x3f,0x00,0x82,0x30, -0x00,0x14,0x02,0x00,0x25,0x28,0xa2,0x00,0x25,0x28,0xa8,0x00,0x10,0x00,0xa5,0xaf, -0x00,0x00,0xe5,0xac,0x00,0x00,0xc3,0x8c,0xff,0x0f,0x02,0x3c,0xc0,0x03,0x84,0x30, -0xff,0xff,0x42,0x34,0x80,0x25,0x04,0x00,0x24,0x18,0x62,0x00,0x25,0x18,0x64,0x00, -0x10,0x00,0xa3,0xaf,0x00,0x00,0xc3,0xac,0x95,0x54,0x00,0x08,0x00,0x00,0x00,0x00, -0x80,0x0c,0x42,0x34,0x00,0x00,0x43,0x8c,0xc0,0xff,0x02,0x3c,0x21,0x88,0x00,0x00, -0x24,0x28,0x62,0x00,0xc0,0xff,0x04,0x3c,0x8a,0x55,0x00,0x08,0x18,0x40,0xc3,0x24, -0x01,0x00,0x31,0x26,0x25,0x00,0x22,0x2e,0x0d,0x00,0x40,0x10,0x02,0x80,0x0b,0x3c, -0x00,0x00,0x62,0x8c,0x00,0x00,0x00,0x00,0x24,0x10,0x44,0x00,0xf8,0xff,0x45,0x14, -0x04,0x00,0x63,0x24,0x08,0x40,0xc2,0x8c,0xc0,0xff,0x03,0x24,0x3f,0x00,0x24,0x32, -0x24,0x10,0x43,0x00,0x25,0x10,0x44,0x00,0x08,0x40,0xc2,0xac,0x02,0x80,0x0b,0x3c, -0x8e,0x7d,0x63,0x91,0x22,0x00,0x02,0x24,0x3e,0x00,0x62,0x10,0x92,0x00,0x02,0x24, -0x3d,0x00,0x62,0x10,0x25,0xb0,0x02,0x3c,0x25,0xb0,0x02,0x3c,0x24,0x0a,0x42,0x34, -0x00,0x00,0x44,0x8c,0x3f,0x3f,0x03,0x3c,0x3f,0x3f,0x63,0x34,0x24,0x20,0x83,0x00, -0x02,0x80,0x02,0x3c,0x02,0x80,0x03,0x3c,0x16,0x56,0x53,0x24,0x1e,0x57,0x72,0x24, -0x21,0x88,0x00,0x00,0xb1,0x55,0x00,0x08,0x10,0x00,0xa4,0xaf,0xd4,0x45,0x00,0x0c, -0x00,0x00,0x00,0x00,0x47,0x00,0x40,0x10,0x68,0x15,0x85,0x26,0x01,0x00,0x31,0x26, -0x21,0x00,0x22,0x2e,0x17,0x00,0x40,0x10,0x68,0x15,0x84,0x26,0xc0,0x80,0x11,0x00, -0x10,0x00,0xa4,0x27,0x21,0x28,0x13,0x02,0xd4,0x45,0x00,0x0c,0x04,0x00,0x06,0x24, -0x21,0x28,0x12,0x02,0x10,0x00,0xa4,0x27,0xf0,0xff,0x40,0x14,0x04,0x00,0x06,0x24, -0x68,0x15,0x85,0x26,0x08,0x40,0xa3,0x8c,0xc0,0xff,0x02,0x3c,0xff,0xff,0x42,0x34, -0x3f,0x00,0x24,0x32,0x24,0x18,0x62,0x00,0x00,0x24,0x04,0x00,0xff,0x7f,0x02,0x3c, -0x25,0x18,0x64,0x00,0xff,0xff,0x42,0x34,0x24,0x18,0x62,0x00,0x08,0x40,0xa3,0xac, -0x68,0x15,0x84,0x26,0x0c,0x40,0x83,0x8c,0x00,0x40,0x02,0x3c,0x25,0x18,0x62,0x00, -0x25,0xb0,0x02,0x3c,0x0e,0x0c,0x42,0x34,0x0c,0x40,0x83,0xac,0x00,0x00,0x40,0xa0, -0x8f,0x54,0x00,0x08,0x68,0x15,0x85,0x26,0xc6,0x42,0x02,0xa2,0xba,0x54,0x00,0x08, -0xc4,0x42,0x12,0xa6,0xda,0x53,0x00,0x0c,0x00,0x00,0x00,0x00,0xc9,0x54,0x00,0x08, -0xc4,0x42,0x12,0xa6,0x25,0xb0,0x02,0x3c,0x88,0x0c,0x42,0x34,0x00,0x00,0x44,0x8c, -0x02,0x80,0x03,0x3c,0x68,0x15,0x66,0x24,0xc0,0xff,0x02,0x3c,0x24,0x28,0x82,0x00, -0x21,0x88,0x00,0x00,0xc0,0xff,0x04,0x3c,0xe6,0x55,0x00,0x08,0x18,0x40,0xc3,0x24, -0x01,0x00,0x31,0x26,0x25,0x00,0x22,0x2e,0xb8,0xff,0x40,0x10,0x25,0xb0,0x02,0x3c, -0x00,0x00,0x62,0x8c,0x00,0x00,0x00,0x00,0x24,0x10,0x44,0x00,0xf8,0xff,0x45,0x14, -0x04,0x00,0x63,0x24,0x08,0x40,0xc2,0x8c,0x3f,0x00,0x23,0x32,0xff,0xc0,0x04,0x24, -0x24,0x10,0x44,0x00,0x00,0x1a,0x03,0x00,0x25,0x10,0x43,0x00,0x9c,0x55,0x00,0x08, -0x08,0x40,0xc2,0xac,0x08,0x40,0xa3,0x8c,0xc0,0xff,0x02,0x3c,0xff,0xff,0x42,0x34, -0x3f,0x00,0x24,0x32,0x24,0x18,0x62,0x00,0x00,0x24,0x04,0x00,0x25,0x18,0x64,0x00, -0x00,0x80,0x02,0x3c,0xc5,0x55,0x00,0x08,0x25,0x18,0x62,0x00,0xcc,0xff,0x02,0x24, -0x00,0x00,0x62,0xa0,0xcd,0x54,0x00,0x08,0x68,0x15,0x83,0x26,0x25,0xb0,0x02,0x3c, -0x94,0x0c,0x43,0x34,0x80,0x0c,0x42,0x34,0x00,0x00,0x44,0xac,0x00,0x00,0x60,0xac, -0x0d,0x55,0x00,0x08,0x68,0x15,0x83,0x26,0x2f,0x00,0xe0,0x10,0x21,0x30,0x00,0x00, -0x2b,0x10,0x42,0x01,0x21,0x20,0x8a,0x00,0x00,0x00,0x42,0x38,0x24,0x00,0x06,0x24, -0x2b,0x18,0x43,0x01,0x0b,0x30,0x82,0x00,0xcd,0xfe,0x60,0x10,0x20,0x00,0x09,0x24, -0x68,0x15,0x83,0x26,0x0a,0x40,0x62,0x94,0x02,0x80,0x0b,0x3c,0x3f,0x00,0x42,0x30, -0xe0,0x54,0x00,0x08,0x21,0x48,0x4a,0x00,0x21,0x28,0xa3,0x00,0xb4,0x41,0xa3,0x90, -0x25,0xb0,0x04,0x3c,0x22,0x0a,0x82,0x34,0x00,0x00,0x43,0xa0,0xb5,0x41,0xa6,0x90, -0x23,0x0a,0x82,0x34,0x24,0x0a,0x87,0x34,0x00,0x00,0x46,0xa0,0xb6,0x41,0xa3,0x90, -0x25,0x0a,0x86,0x34,0x26,0x0a,0x88,0x34,0x00,0x00,0xe3,0xa0,0xb7,0x41,0xa2,0x90, -0x27,0x0a,0x87,0x34,0x28,0x0a,0x89,0x34,0x00,0x00,0xc2,0xa0,0xb8,0x41,0xa3,0x90, -0x29,0x0a,0x84,0x34,0x00,0x00,0x03,0xa1,0xb9,0x41,0xa2,0x90,0x00,0x00,0x00,0x00, -0x00,0x00,0xe2,0xa0,0xba,0x41,0xa3,0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x23,0xa1, -0xbb,0x41,0xa2,0x90,0x2d,0x55,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xa0, -0xad,0x54,0x00,0x08,0x68,0x15,0x84,0x26,0x23,0x10,0x8a,0x00,0x2b,0x18,0x44,0x01, -0x2b,0x20,0x45,0x01,0x0b,0x30,0x43,0x00,0xa1,0xfe,0x80,0x14,0x23,0x48,0xaa,0x00, -0xde,0x54,0x00,0x08,0x21,0x48,0x00,0x00,0xff,0xff,0x43,0x25,0x42,0x18,0x03,0x00, -0x40,0x10,0x03,0x00,0x21,0x10,0x43,0x00,0x40,0x55,0x00,0x08,0x01,0x00,0x4a,0x24, -0x25,0xb0,0x02,0x3c,0x9c,0x0c,0x43,0x34,0x88,0x0c,0x42,0x34,0x00,0x00,0x44,0xac, -0x00,0x00,0x60,0xac,0x95,0x54,0x00,0x08,0x00,0x00,0x00,0x00,0x08,0x40,0x62,0x8c, -0x00,0x00,0x00,0x00,0x02,0x12,0x02,0x00,0x3f,0x00,0x42,0x30,0x23,0x18,0x4a,0x00, -0x2b,0x10,0x42,0x01,0x4e,0x55,0x00,0x08,0x0b,0x20,0x62,0x00,0xff,0xff,0x05,0x36, -0x60,0x00,0x06,0x24,0xba,0x44,0x00,0x0c,0x24,0x00,0x04,0x24,0x84,0x0a,0x00,0x0c, -0xe8,0x03,0x04,0x24,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38, -0x00,0x60,0x81,0x40,0x24,0x00,0x04,0x24,0xdd,0x44,0x00,0x0c,0xff,0xff,0x05,0x36, -0x1f,0x00,0x52,0x30,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40, -0xb3,0x0a,0x00,0x0c,0x64,0x00,0x04,0x24,0xb4,0x54,0x00,0x08,0x68,0x15,0x90,0x26, -0x00,0xff,0x84,0x30,0x02,0x22,0x04,0x00,0x08,0x00,0x80,0x10,0x02,0x80,0x02,0x3c, -0xff,0x00,0x02,0x24,0x04,0x00,0x82,0x10,0xcc,0xff,0x03,0x24,0x02,0x80,0x02,0x3c, -0x08,0x00,0xe0,0x03,0x4e,0x58,0x43,0xa0,0x02,0x80,0x02,0x3c,0x08,0x00,0xe0,0x03, -0x4e,0x58,0x44,0xa0,0x02,0x24,0x04,0x00,0xff,0x00,0x84,0x30,0xc0,0x10,0x04,0x00, -0x21,0x10,0x44,0x00,0x80,0x10,0x02,0x00,0x21,0x10,0x44,0x00,0x02,0x80,0x03,0x3c, -0x80,0x10,0x02,0x00,0x68,0x15,0x63,0x24,0x20,0x00,0x84,0x2c,0x09,0x00,0x80,0x10, -0x21,0x10,0x43,0x00,0x68,0x51,0x43,0x8c,0x25,0xb0,0x02,0x3c,0xc4,0x02,0x42,0x34, -0x02,0x19,0x03,0x00,0x7f,0x00,0x63,0x30,0x00,0x00,0x43,0xac,0x08,0x00,0xe0,0x03, -0x00,0x00,0x00,0x00,0x02,0x80,0x02,0x3c,0x44,0x79,0x43,0x8c,0x25,0xb0,0x02,0x3c, -0xc4,0x02,0x42,0x34,0x02,0x19,0x03,0x00,0x7f,0x00,0x63,0x30,0x00,0x00,0x43,0xac, -0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0xff,0x00,0x85,0x30,0xd2,0xff,0xa3,0x24, -0xfe,0xff,0xa2,0x24,0xda,0xff,0xa4,0x24,0x04,0x00,0x63,0x2c,0x08,0x00,0x84,0x2c, -0x06,0x00,0x60,0x14,0xff,0x00,0x42,0x30,0xf0,0xff,0xa2,0x24,0xfc,0xff,0xa3,0x24, -0x16,0x00,0x46,0x2c,0x03,0x00,0x80,0x10,0xff,0x00,0x62,0x30,0x08,0x00,0xe0,0x03, -0x00,0x00,0x00,0x00,0xfa,0xff,0xa3,0x24,0xfc,0xff,0xc0,0x10,0x21,0x10,0xa0,0x00, -0x08,0x00,0xe0,0x03,0xff,0x00,0x62,0x30,0x25,0xb0,0x04,0x3c,0x03,0x0d,0x85,0x34, -0x00,0x00,0xa3,0x90,0x2d,0x0a,0x84,0x34,0xff,0x00,0x63,0x30,0x08,0x00,0x63,0x34, -0x00,0x00,0xa3,0xa0,0x00,0x00,0xa2,0x90,0x00,0x00,0x00,0x00,0xf7,0x00,0x42,0x30, -0x00,0x00,0xa2,0xa0,0x00,0x00,0x83,0x90,0x00,0x00,0x00,0x00,0x3f,0x00,0x63,0x30, -0x00,0x00,0x83,0xa0,0x00,0x00,0x82,0x90,0x80,0xff,0x03,0x24,0x25,0x10,0x43,0x00, -0x00,0x00,0x82,0xa0,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x25,0xb0,0x02,0x3c, -0xff,0x00,0x03,0x3c,0x82,0x01,0x49,0x34,0x81,0x01,0x48,0x34,0x24,0x10,0x83,0x00, -0x02,0x3c,0x02,0x00,0x00,0xff,0x63,0x34,0x02,0x80,0x02,0x3c,0x68,0x15,0x45,0x24, -0x02,0x32,0x04,0x00,0x01,0x00,0x02,0x24,0x24,0x20,0x83,0x00,0xc2,0x4c,0xa2,0xa0, -0xb0,0x4c,0xa0,0xac,0xb4,0x4c,0xa0,0xac,0xb8,0x4c,0xa0,0xac,0x06,0x00,0x80,0x14, -0xbc,0x4c,0xa0,0xac,0x00,0x00,0x02,0x91,0x00,0x00,0x23,0x91,0xc0,0x4c,0xa2,0xa0, -0x08,0x00,0xe0,0x03,0xc1,0x4c,0xa3,0xa0,0xc1,0x4c,0xa7,0xa0,0x08,0x00,0xe0,0x03, -0xc0,0x4c,0xa6,0xa0,0x02,0x80,0x03,0x3c,0x68,0x15,0x63,0x24,0xc1,0x4c,0x66,0x90, -0xc0,0x4c,0x65,0x90,0x25,0xb0,0x02,0x3c,0x82,0x01,0x44,0x34,0x81,0x01,0x42,0x34, -0x00,0x00,0x45,0xa0,0x00,0x00,0x86,0xa0,0x08,0x00,0xe0,0x03,0xc2,0x4c,0x60,0xa0, -0x02,0x80,0x08,0x3c,0x68,0x15,0x04,0x25,0xc2,0x4c,0x82,0x90,0x00,0x00,0x00,0x00, -0x15,0x00,0x40,0x10,0x21,0x18,0x00,0x00,0xb4,0x4c,0x82,0x8c,0xb0,0x4c,0x85,0x8c, -0x25,0xb0,0x03,0x3c,0x40,0x11,0x02,0x00,0x2b,0x10,0xa2,0x00,0x82,0x01,0x67,0x34, -0x0f,0x00,0x40,0x10,0x81,0x01,0x66,0x34,0xc1,0x4c,0x83,0x90,0xc0,0x4c,0x82,0x90, -0xf0,0x00,0x63,0x30,0x1f,0x00,0x42,0x30,0x00,0x00,0xc2,0xa0,0x00,0x00,0xe3,0xa0, -0x68,0x15,0x02,0x25,0x01,0x00,0x03,0x24,0xbc,0x4c,0x40,0xac,0xb0,0x4c,0x40,0xac, -0xb4,0x4c,0x40,0xac,0xb8,0x4c,0x40,0xac,0x08,0x00,0xe0,0x03,0x21,0x10,0x60,0x00, -0xb8,0x4c,0x82,0x8c,0x25,0xb0,0x03,0x3c,0x82,0x01,0x69,0x34,0x40,0x11,0x02,0x00, -0x2b,0x10,0xa2,0x00,0x0e,0x00,0x40,0x14,0x81,0x01,0x66,0x34,0xbc,0x4c,0x82,0x8c, -0x00,0x00,0x00,0x00,0x40,0x11,0x02,0x00,0x2b,0x10,0xa2,0x00,0x08,0x00,0x40,0x14, -0x00,0x00,0x00,0x00,0xc1,0x4c,0x83,0x90,0xc0,0x4c,0x82,0x90,0x00,0x00,0x00,0x00, -0x00,0x00,0xc2,0xa0,0x00,0x00,0x23,0xa1,0xf7,0x56,0x00,0x08,0x68,0x15,0x02,0x25, -0xc1,0x4c,0x83,0x90,0xc0,0x4c,0x82,0x90,0xf0,0x00,0x63,0x30,0x7f,0x00,0x42,0x30, -0x00,0x00,0xc2,0xa0,0x00,0x00,0x23,0xa1,0xf7,0x56,0x00,0x08,0x68,0x15,0x02,0x25, -0x02,0x00,0x03,0x24,0x02,0x80,0x02,0x3c,0x08,0x00,0xe0,0x03,0x3d,0x58,0x43,0xa0, -0xcc,0xff,0x03,0x24,0x02,0x80,0x02,0x3c,0x08,0x00,0xe0,0x03,0x3d,0x58,0x43,0xa0, -0x25,0xb0,0x03,0x3c,0x33,0x02,0x65,0x34,0x00,0x11,0x04,0x00,0x00,0x00,0xa2,0xa0, -0x30,0x02,0x63,0x34,0x00,0x00,0x65,0x8c,0x0f,0x00,0x02,0x3c,0xff,0xff,0x42,0x34, -0x24,0x28,0xa2,0x00,0x01,0x00,0x03,0x24,0x04,0x18,0x83,0x00,0x02,0x00,0xa0,0x10, -0x21,0x10,0x00,0x00,0xff,0xff,0x62,0x30,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00, -0xe0,0xff,0xbd,0x27,0x14,0x00,0xb1,0xaf,0x25,0xb0,0x11,0x3c,0x18,0x00,0xb2,0xaf, -0x4c,0x00,0x22,0x36,0x1c,0x00,0xbf,0xaf,0x10,0x00,0xb0,0xaf,0x00,0x00,0x44,0x90, -0x02,0x80,0x03,0x3c,0x02,0x00,0x02,0x24,0xff,0x00,0x84,0x30,0x07,0x00,0x82,0x10, -0x68,0x15,0x72,0x24,0x1c,0x00,0xbf,0x8f,0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f, -0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x20,0x00,0xbd,0x27,0xe6,0x63,0x43,0x96, -0x01,0x00,0x02,0x24,0xf7,0xff,0x62,0x14,0x21,0x20,0x00,0x00,0x22,0x57,0x00,0x0c, -0x00,0x00,0x00,0x00,0x04,0x00,0x04,0x24,0x22,0x57,0x00,0x0c,0x21,0x80,0x40,0x00, -0x25,0x80,0x02,0x02,0x33,0x02,0x23,0x36,0x08,0x00,0x02,0x24,0xff,0xff,0x10,0x32, -0x40,0x00,0x25,0x36,0x00,0x00,0x62,0xa0,0xea,0xff,0x00,0x16,0x00,0x00,0x00,0x00, -0x00,0x00,0xa2,0x94,0xe4,0x63,0x43,0x96,0xff,0xdf,0x42,0x30,0x00,0x20,0x44,0x34, -0x01,0x00,0x63,0x24,0xe4,0x63,0x43,0xa6,0x00,0x00,0xa2,0xa4,0x00,0x00,0xa4,0xa4, -0x3f,0x57,0x00,0x08,0x00,0x00,0x00,0x00,0x01,0x80,0x03,0x3c,0x25,0xb0,0x02,0x3c, -0x18,0x03,0x42,0x34,0x80,0x5d,0x63,0x24,0x00,0x00,0x43,0xac,0x63,0x00,0x02,0x24, -0xff,0xff,0x42,0x24,0xff,0xff,0x41,0x04,0xff,0xff,0x42,0x24,0x02,0x80,0x02,0x3c, -0x88,0x7d,0x45,0x94,0x02,0x80,0x03,0x3c,0x02,0x80,0x02,0x3c,0x8b,0x7d,0x66,0x90, -0x98,0x7d,0x47,0x90,0x02,0x80,0x03,0x3c,0x02,0x80,0x02,0x3c,0xa3,0x7d,0x69,0x90, -0xa5,0x7d,0x4a,0x90,0x02,0x80,0x03,0x3c,0x02,0x80,0x02,0x3c,0xa8,0x7d,0x6b,0x90, -0xaa,0x7d,0x4c,0x90,0x07,0x00,0x03,0x24,0x02,0x80,0x02,0x3c,0x25,0xb0,0x04,0x3c, -0x95,0x7d,0x43,0xa0,0xb0,0x03,0x84,0x34,0x02,0x80,0x02,0x3c,0x02,0x80,0x18,0x3c, -0x8a,0x7d,0x08,0x93,0x00,0x00,0x85,0xac,0x96,0x7d,0x40,0xa0,0x02,0x80,0x02,0x3c, -0x00,0x00,0x86,0xac,0x02,0x80,0x0f,0x3c,0x97,0x7d,0x40,0xa0,0x02,0x80,0x02,0x3c, -0x00,0x00,0x87,0xac,0x68,0x15,0xee,0x25,0xb8,0x7d,0x40,0xa0,0xfd,0xff,0x02,0x24, -0xd5,0x4a,0xc2,0xa1,0x01,0x00,0x03,0x24,0x00,0x78,0x02,0x24,0xd4,0x4a,0xc3,0xa1, -0xd8,0x4a,0xc2,0xa5,0xff,0x07,0x03,0x24,0x0f,0x00,0x0d,0x31,0x02,0x00,0x02,0x24, -0xda,0x4a,0xc3,0xa5,0x00,0x00,0x88,0xac,0x00,0x00,0x89,0xac,0x00,0x00,0x8a,0xac, -0x00,0x00,0x8b,0xac,0x00,0x00,0x8c,0xac,0x17,0x00,0xa2,0x11,0x02,0x80,0x02,0x3c, -0x8a,0x7d,0x02,0x93,0x01,0x00,0x03,0x24,0x0f,0x00,0x42,0x30,0x05,0x00,0x43,0x10, -0x00,0x00,0x00,0x00,0x02,0x80,0x02,0x3c,0xca,0x7d,0x40,0xa4,0x08,0x00,0xe0,0x03, -0x00,0x00,0x00,0x00,0x00,0x80,0x02,0x3c,0x68,0x15,0xe4,0x25,0x02,0xbc,0x42,0x34, -0x68,0x4b,0x82,0xac,0x15,0x15,0x03,0x3c,0x02,0x02,0x02,0x3c,0x07,0x07,0x63,0x34, -0x64,0x4b,0x82,0xac,0x02,0x80,0x02,0x3c,0x60,0x4b,0x83,0xac,0xca,0x7d,0x40,0xa4, -0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x8f,0x7d,0x44,0x90,0x06,0x00,0x03,0x24, -0x15,0x00,0x83,0x10,0x0b,0x00,0x02,0x24,0x0a,0x00,0x82,0x10,0x00,0xe0,0x02,0x3c, -0x68,0x15,0xe4,0x25,0x00,0xb2,0x42,0x34,0x00,0x1c,0x03,0x3c,0x68,0x4b,0x82,0xac, -0x00,0x1c,0x63,0x34,0x00,0x04,0x02,0x24,0x60,0x4b,0x83,0xac,0x9a,0x57,0x00,0x08, -0x64,0x4b,0x82,0xac,0x00,0x80,0x02,0x3c,0x00,0xbc,0x42,0x34,0x15,0x15,0x03,0x3c, -0x68,0x4b,0xc2,0xad,0x07,0x07,0x63,0x34,0x03,0x03,0x02,0x3c,0x60,0x4b,0xc3,0xad, -0x9a,0x57,0x00,0x08,0x64,0x4b,0xc2,0xad,0x00,0xc0,0x02,0x3c,0x00,0xb2,0x42,0x34, -0x1c,0x1c,0x03,0x3c,0x68,0x4b,0xc2,0xad,0x07,0x07,0x63,0x34,0x00,0x04,0x02,0x24, -0x60,0x4b,0xc3,0xad,0x9a,0x57,0x00,0x08,0x64,0x4b,0xc2,0xad,0x25,0xb0,0x02,0x3c, -0x4d,0x00,0x44,0x34,0xff,0x00,0x03,0x3c,0xec,0x02,0x42,0x34,0x00,0x00,0x43,0xac, -0x00,0x00,0x80,0xa0,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x01,0x80,0x03,0x3c, -0x25,0xb0,0x02,0x3c,0x64,0x5f,0x63,0x24,0x18,0x03,0x42,0x34,0x00,0x00,0x43,0xac, -0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x7f,0x00,0x02,0x3c,0xfd,0xbf,0x45,0x34, -0x80,0x04,0x03,0x3c,0x25,0x28,0xa3,0x00,0x00,0x08,0x04,0x3c,0x02,0x80,0x02,0x3c, -0x68,0x15,0x42,0x24,0x25,0x28,0xa4,0x00,0x41,0xb0,0x03,0x3c,0x00,0x00,0x65,0xac, -0x04,0x4b,0x45,0xac,0xfc,0x4a,0x45,0xac,0x08,0x00,0x63,0x34,0x86,0x00,0x05,0x24, -0x00,0x00,0x65,0xa4,0x08,0x4b,0x45,0xa4,0x00,0x4b,0x40,0xac,0x0a,0x4b,0x40,0xa4, -0x0c,0x4b,0x45,0xa4,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40, -0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0xf8,0x57,0x00,0x08,0x00,0x00,0x00,0x00, -0x42,0xb0,0x02,0x3c,0xa0,0xff,0x03,0x24,0x01,0x00,0x42,0x34,0xe8,0xff,0xbd,0x27, -0x21,0x20,0x00,0x00,0x01,0x00,0x05,0x24,0x00,0x01,0x06,0x24,0x00,0x00,0x43,0xa0, -0x10,0x00,0xbf,0xaf,0xc4,0x0c,0x00,0x0c,0x00,0x00,0x00,0x00,0x10,0x00,0xbf,0x8f, -0x03,0x00,0x04,0x24,0x01,0x00,0x05,0x24,0x40,0x1f,0x06,0x24,0xc4,0x0c,0x00,0x08, -0x18,0x00,0xbd,0x27,0xe8,0xff,0xbd,0x27,0x10,0x00,0xb0,0xaf,0x14,0x00,0xbf,0xaf, -0x21,0x5b,0x00,0x0c,0x00,0x00,0x00,0x00,0x02,0x80,0x02,0x3c,0x68,0x15,0x42,0x24, -0x48,0x01,0x03,0x24,0xe0,0x63,0x43,0xac,0xdc,0x63,0x43,0xac,0x21,0x80,0x40,0x00, -0x1f,0x00,0x03,0x24,0xff,0xff,0x63,0x24,0xc4,0x4c,0x40,0xa4,0xc6,0x4c,0x40,0xa4, -0xc8,0x4c,0x40,0xa4,0xca,0x4c,0x40,0xa4,0xcc,0x4c,0x40,0xa4,0xce,0x4c,0x40,0xa4, -0xd0,0x4c,0x40,0xa4,0xd2,0x4c,0x40,0xa4,0xd4,0x4c,0x40,0xa4,0xf5,0xff,0x61,0x04, -0x24,0x00,0x42,0x24,0x25,0xb0,0x02,0x3c,0x10,0x00,0x03,0x24,0xb0,0x03,0x42,0x34, -0x02,0x80,0x04,0x3c,0x8c,0x58,0x84,0x24,0x00,0x00,0x43,0xac,0x21,0x28,0x00,0x00, -0x97,0x45,0x00,0x0c,0x04,0x00,0x06,0x24,0xef,0x5b,0x00,0x0c,0x00,0x00,0x00,0x00, -0x71,0x5c,0x00,0x0c,0x8c,0x65,0x00,0xae,0xa7,0x5d,0x00,0x0c,0x00,0x00,0x00,0x00, -0x4b,0x5e,0x00,0x0c,0x00,0x00,0x00,0x00,0x02,0x80,0x03,0x3c,0x8e,0x7d,0x64,0x90, -0x92,0x00,0x02,0x24,0x03,0x00,0x82,0x10,0x00,0x00,0x00,0x00,0xf7,0x5d,0x00,0x0c, -0x00,0x00,0x00,0x00,0xdd,0x5d,0x00,0x0c,0x00,0x00,0x00,0x00,0x8b,0x5c,0x00,0x0c, -0x00,0x00,0x00,0x00,0xe4,0x63,0x00,0xa6,0x67,0x5e,0x00,0x0c,0xe6,0x63,0x00,0xa6, -0x14,0x00,0xbf,0x8f,0x10,0x00,0xb0,0x8f,0x02,0x80,0x04,0x3c,0x02,0x80,0x05,0x3c, -0xf8,0x7a,0x82,0x24,0x00,0x7b,0xa3,0x24,0x18,0x00,0xbd,0x27,0x04,0x00,0x42,0xac, -0xf8,0x7a,0x82,0xac,0x00,0x7b,0xa3,0xac,0x08,0x00,0xe0,0x03,0x04,0x00,0x63,0xac, -0xe8,0xff,0xbd,0x27,0x10,0x00,0xb0,0xaf,0x01,0x80,0x02,0x3c,0x25,0xb0,0x10,0x3c, -0x18,0x03,0x03,0x36,0x38,0x61,0x42,0x24,0x00,0x00,0x62,0xac,0x14,0x00,0xbf,0xaf, -0x60,0x57,0x00,0x0c,0x00,0x00,0x00,0x00,0xd5,0x58,0x00,0x0c,0x00,0x00,0x00,0x00, -0x01,0x00,0x03,0x24,0x02,0x80,0x02,0x3c,0xfd,0x5a,0x00,0x0c,0xdb,0x60,0x43,0xa0, -0xd1,0x57,0x00,0x0c,0x00,0x00,0x00,0x00,0x32,0x41,0x00,0x0c,0x00,0x00,0x00,0x00, -0x0b,0x58,0x00,0x0c,0x00,0x00,0x00,0x00,0x44,0x00,0x03,0x36,0x00,0x00,0x62,0x94, -0x00,0x00,0x00,0x00,0x40,0x00,0x42,0x34,0x00,0x00,0x62,0xa4,0xd9,0x57,0x00,0x0c, -0x00,0x00,0x00,0x00,0xfa,0x57,0x00,0x0c,0x00,0x00,0x00,0x00,0xc9,0x5a,0x00,0x0c, -0x00,0x00,0x00,0x00,0x8e,0x5a,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x3c, -0xb4,0x24,0x84,0x24,0xe6,0x5a,0x00,0x0c,0x01,0x00,0x05,0x24,0x01,0x80,0x04,0x3c, -0x08,0x1e,0x84,0x24,0xe6,0x5a,0x00,0x0c,0x02,0x00,0x05,0x24,0x81,0x4e,0x00,0x0c, -0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x3c,0x54,0x34,0x84,0x24,0xe6,0x5a,0x00,0x0c, -0x03,0x00,0x05,0x24,0x02,0x80,0x02,0x3c,0x98,0x7d,0x43,0x90,0x43,0x00,0x04,0x36, -0x29,0x00,0x60,0x10,0xd8,0x00,0x10,0x36,0x07,0x00,0x02,0x24,0x2b,0x00,0x62,0x10, -0x25,0xb0,0x04,0x3c,0x10,0x02,0x86,0x34,0x43,0x00,0x85,0x34,0x03,0x00,0x02,0x24, -0x10,0x00,0x03,0x24,0x00,0x00,0xa2,0xa0,0xd8,0x00,0x84,0x34,0x00,0x00,0xc3,0xa0, -0x00,0x00,0x82,0x90,0x80,0xff,0x03,0x24,0x42,0xb0,0x05,0x3c,0x25,0x10,0x43,0x00, -0x00,0x00,0x82,0xa0,0x25,0xb0,0x04,0x3c,0x44,0x00,0x84,0x34,0x00,0x00,0x82,0x94, -0x00,0x00,0x00,0x00,0xc0,0x00,0x42,0x34,0x00,0x00,0x82,0xa4,0x00,0x00,0xa3,0x90, -0x00,0x00,0x00,0x00,0x01,0x00,0x63,0x34,0x00,0x00,0xa3,0xa0,0xe0,0x57,0x00,0x0c, -0x00,0x00,0x00,0x00,0x02,0x80,0x04,0x3c,0x08,0x00,0x84,0x24,0x21,0x28,0x00,0x00, -0x21,0x30,0x00,0x00,0x31,0x1c,0x00,0x0c,0x21,0x38,0x00,0x00,0xf8,0x57,0x00,0x0c, -0x00,0x00,0x00,0x00,0x14,0x00,0xbf,0x8f,0x10,0x00,0xb0,0x8f,0x01,0x00,0x02,0x24, -0x08,0x00,0xe0,0x03,0x18,0x00,0xbd,0x27,0x00,0x00,0x80,0xa0,0x00,0x00,0x03,0x92, -0x80,0xff,0x02,0x24,0x25,0x18,0x62,0x00,0x00,0x00,0x03,0xa2,0x25,0xb0,0x04,0x3c, -0x44,0x00,0x84,0x34,0x00,0x00,0x82,0x94,0x42,0xb0,0x05,0x3c,0xc0,0x00,0x42,0x34, -0x00,0x00,0x82,0xa4,0x00,0x00,0xa3,0x90,0x00,0x00,0x00,0x00,0x01,0x00,0x63,0x34, -0x00,0x00,0xa3,0xa0,0xe0,0x57,0x00,0x0c,0x00,0x00,0x00,0x00,0x02,0x80,0x04,0x3c, -0x08,0x00,0x84,0x24,0x21,0x28,0x00,0x00,0x21,0x30,0x00,0x00,0x31,0x1c,0x00,0x0c, -0x21,0x38,0x00,0x00,0xf8,0x57,0x00,0x0c,0x00,0x00,0x00,0x00,0x14,0x00,0xbf,0x8f, -0x10,0x00,0xb0,0x8f,0x01,0x00,0x02,0x24,0x08,0x00,0xe0,0x03,0x18,0x00,0xbd,0x27, -0x21,0x20,0x00,0x00,0x20,0xb0,0x06,0x3c,0xff,0xff,0x05,0x34,0x21,0x18,0x86,0x00, -0x04,0x00,0x84,0x24,0x2a,0x10,0xa4,0x00,0x00,0x00,0x60,0xac,0xfb,0xff,0x40,0x10, -0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0xb8,0xff,0xbd,0x27, -0x25,0xb0,0x04,0x3c,0x44,0x00,0xbf,0xaf,0x40,0x00,0xbe,0xaf,0x3c,0x00,0xb7,0xaf, -0x38,0x00,0xb6,0xaf,0x34,0x00,0xb5,0xaf,0x30,0x00,0xb4,0xaf,0x2c,0x00,0xb3,0xaf, -0x28,0x00,0xb2,0xaf,0x24,0x00,0xb1,0xaf,0x20,0x00,0xb0,0xaf,0x0a,0x00,0x83,0x34, -0x00,0x00,0x62,0x90,0x00,0x00,0x00,0x00,0x20,0x00,0x42,0x30,0x0c,0x00,0x40,0x10, -0x4c,0x87,0x02,0x3c,0x00,0x00,0x62,0x90,0x00,0x00,0x00,0x00,0x10,0x00,0x42,0x30, -0x66,0x01,0x40,0x10,0x4c,0x87,0x02,0x3c,0x54,0x00,0x83,0x34,0x50,0x00,0x82,0x34, -0x00,0x00,0x45,0xac,0x00,0x00,0x65,0xa4,0xf9,0x58,0x00,0x08,0x02,0x80,0x03,0x3c, -0x54,0x00,0x85,0x34,0x00,0xe0,0x42,0x34,0x50,0x00,0x84,0x34,0x12,0x01,0x03,0x24, -0x00,0x00,0x82,0xac,0x00,0x00,0xa3,0xac,0x02,0x80,0x03,0x3c,0x68,0x15,0x62,0x24, -0xd5,0x4a,0x43,0x90,0xda,0x4a,0x45,0x94,0x25,0xb0,0x1e,0x3c,0x1c,0x00,0xa3,0xa3, -0x60,0x4b,0x43,0x8c,0x58,0x00,0xc6,0x37,0xff,0xff,0x04,0x24,0x10,0x00,0xa3,0xaf, -0x64,0x4b,0x43,0x8c,0x5c,0x00,0xc7,0x37,0x60,0x00,0xc8,0x37,0x14,0x00,0xa3,0xaf, -0x68,0x4b,0x42,0x8c,0x64,0x00,0xc9,0x37,0x8a,0x00,0xca,0x37,0x18,0x00,0xa2,0xaf, -0x24,0x10,0x02,0x3c,0x21,0x28,0xa2,0x00,0x4c,0x81,0x02,0x3c,0x00,0xe0,0x42,0x34, -0x00,0x00,0xc2,0xac,0x96,0x01,0x03,0x24,0x28,0x28,0x02,0x24,0x00,0x00,0xe3,0xac, -0x89,0x00,0xcb,0x37,0x00,0x00,0x04,0xad,0x8c,0x00,0xcc,0x37,0x00,0x00,0x24,0xad, -0x09,0x00,0x03,0x24,0x00,0x00,0x42,0xa5,0x10,0x10,0x02,0x24,0x00,0x00,0x63,0xa1, -0x8e,0x00,0xcd,0x37,0x00,0x00,0x82,0xa5,0x0a,0x0a,0x03,0x24,0x13,0x00,0x02,0x24, -0x90,0x00,0xce,0x37,0x00,0x00,0xa3,0xa5,0x00,0x00,0xc2,0xa1,0x25,0xb0,0x02,0x3c, -0x40,0x00,0x03,0x24,0x91,0x00,0x42,0x34,0x00,0x00,0x43,0xa0,0x25,0xb0,0x03,0x3c, -0x3a,0x01,0x02,0x24,0x92,0x00,0x63,0x34,0x00,0x00,0x62,0xa4,0xb5,0x00,0xd1,0x37, -0x21,0x00,0x03,0x24,0x00,0x00,0x23,0xa2,0x10,0x00,0xa2,0x8f,0xa0,0x00,0xd2,0x37, -0xa4,0x00,0xd3,0x37,0x00,0x00,0x42,0xae,0x14,0x00,0xa3,0x8f,0xa8,0x00,0xd4,0x37, -0xac,0x00,0xd5,0x37,0x00,0x00,0x63,0xae,0x18,0x00,0xa2,0x8f,0x25,0xb0,0x03,0x3c, -0xb0,0x00,0x63,0x34,0x00,0x00,0x82,0xae,0x21,0x10,0x02,0x3c,0xff,0x77,0x42,0x34, -0x00,0x00,0xa2,0xae,0x25,0xb0,0x02,0x3c,0xd8,0x00,0x42,0x34,0x00,0x00,0x65,0xac, -0x00,0x00,0x40,0xa0,0x1c,0x00,0xa2,0x93,0x25,0xb0,0x03,0x3c,0xb4,0x00,0x63,0x34, -0x00,0x00,0x62,0xa0,0x25,0xb0,0x03,0x3c,0x04,0x00,0x02,0x24,0xb6,0x00,0x63,0x34, -0x00,0x00,0x62,0xa0,0x25,0xb0,0x03,0x3c,0x0f,0x00,0x02,0x24,0xba,0x00,0x63,0x34, -0xb9,0x00,0xdf,0x37,0x00,0x00,0xe4,0xa3,0x00,0x00,0x62,0xa4,0x25,0xb0,0x02,0x3c, -0x1a,0x01,0x42,0x34,0x16,0x01,0xd0,0x37,0x18,0x01,0xcf,0x37,0x00,0x00,0x00,0xa6, -0x25,0xb0,0x03,0x3c,0x00,0x00,0xe0,0xa5,0x00,0x00,0x40,0xa4,0xff,0xff,0x02,0x3c, -0xff,0x0f,0x42,0x34,0xdc,0x00,0x63,0x34,0x00,0x00,0x62,0xac,0x2f,0x00,0x03,0x3c, -0x25,0xb0,0x02,0x3c,0x32,0x32,0x63,0x34,0xd0,0x01,0x42,0x34,0x00,0x00,0x43,0xac, -0x5e,0x00,0x02,0x3c,0x25,0xb0,0x03,0x3c,0x32,0x43,0x42,0x34,0xd4,0x01,0x63,0x34, -0x00,0x00,0x62,0xac,0x08,0x00,0x03,0x3c,0x25,0xb0,0x02,0x3c,0x30,0xa5,0x63,0x34, -0xd8,0x01,0x42,0x34,0x00,0x00,0x43,0xac,0xdc,0x01,0xc4,0x37,0x02,0x80,0x03,0x3c, -0x49,0xa5,0x02,0x34,0x8e,0x7d,0x6d,0x90,0x00,0x00,0x82,0xac,0xc2,0x00,0x02,0x3c, -0x1a,0x06,0x03,0x24,0x51,0x10,0x42,0x34,0xe0,0x01,0xc5,0x37,0xf4,0x01,0xc6,0x37, -0xf8,0x01,0xc7,0x37,0x07,0x07,0x04,0x24,0x00,0x00,0xa3,0xa4,0x00,0x02,0xc8,0x37, -0x00,0x00,0xc4,0xa4,0x26,0x00,0x03,0x24,0x00,0x00,0xe2,0xac,0x03,0x02,0xc9,0x37, -0x04,0x00,0x02,0x24,0x00,0x00,0x03,0xa5,0x36,0x02,0xca,0x37,0x00,0x00,0x22,0xa1, -0xc0,0x01,0x03,0x24,0x0c,0x00,0x02,0x24,0x34,0x02,0xcb,0x37,0x00,0x00,0x42,0xa1, -0x37,0x02,0xcc,0x37,0x00,0x00,0x63,0xa5,0x03,0x00,0x02,0x24,0x22,0x00,0x03,0x24, -0x00,0x00,0x82,0xa1,0xd6,0x00,0xa3,0x11,0x1b,0x1b,0x02,0x3c,0x13,0x13,0x02,0x3c, -0x13,0x13,0x42,0x34,0x60,0x01,0xc3,0x37,0x64,0x01,0xc4,0x37,0x68,0x01,0xc5,0x37, -0x7c,0x01,0xca,0x37,0x6c,0x01,0xc6,0x37,0x70,0x01,0xc7,0x37,0x74,0x01,0xc8,0x37, -0x78,0x01,0xc9,0x37,0x00,0x00,0x62,0xac,0x00,0x00,0x82,0xac,0x02,0x80,0x03,0x3c, -0x00,0x00,0xa2,0xac,0x00,0x00,0xc2,0xac,0x00,0x00,0xe2,0xac,0x00,0x00,0x02,0xad, -0x00,0x00,0x22,0xad,0x00,0x00,0x42,0xad,0x8e,0x7d,0x65,0x90,0x25,0xb0,0x0c,0x3c, -0x01,0x70,0x03,0x3c,0x80,0x01,0x82,0x35,0x08,0x5f,0x63,0x34,0x22,0x00,0x04,0x24, -0x00,0x00,0x43,0xac,0xb5,0x00,0xa4,0x10,0x0f,0x1f,0x02,0x3c,0x92,0x00,0x02,0x24, -0xb2,0x00,0xa2,0x10,0x0f,0x1f,0x02,0x3c,0x0f,0x10,0x02,0x3c,0x00,0xf0,0x51,0x34, -0xf7,0x01,0x92,0x35,0x15,0xf0,0x4d,0x34,0x77,0x00,0x0e,0x24,0x84,0x01,0x87,0x35, -0x88,0x01,0x88,0x35,0x10,0xf0,0x44,0x34,0x8c,0x01,0x85,0x35,0x05,0xf0,0x42,0x34, -0x00,0x00,0xed,0xac,0x90,0x01,0x83,0x35,0x00,0x00,0x04,0xad,0x94,0x01,0x86,0x35, -0x00,0x00,0xa2,0xac,0xf5,0x0f,0x02,0x24,0x00,0x00,0x71,0xac,0x25,0xb0,0x05,0x3c, -0x00,0x00,0xc2,0xac,0x98,0x01,0x89,0x35,0x9c,0x01,0x8a,0x35,0xf0,0x0f,0x03,0x24, -0x0d,0x00,0x02,0x24,0x00,0x00,0x23,0xad,0xa0,0x01,0x8b,0x35,0x00,0x00,0x42,0xad, -0xa7,0x01,0xb7,0x34,0xf6,0x01,0x8c,0x35,0xff,0xff,0x02,0x24,0x00,0x00,0x6d,0xad, -0x00,0x00,0x8e,0xa1,0x00,0x00,0x4e,0xa2,0x00,0x00,0xe2,0xa2,0x25,0xb0,0x02,0x3c, -0xa8,0x01,0xb6,0x34,0xff,0xff,0x09,0x24,0xac,0x01,0x42,0x34,0x00,0x00,0xc9,0xae, -0x03,0x04,0x04,0x3c,0x00,0x00,0x49,0xac,0x07,0x08,0x03,0x3c,0x25,0xb0,0x02,0x3c, -0x01,0x02,0x84,0x34,0x05,0x06,0x63,0x34,0xb4,0x01,0xb1,0x34,0xb8,0x01,0xb2,0x34, -0xbc,0x01,0xb3,0x34,0xb0,0x01,0x42,0x34,0x00,0x00,0x44,0xac,0x00,0x00,0x23,0xae, -0x25,0xb0,0x02,0x3c,0x00,0x00,0x44,0xae,0x00,0x00,0x63,0xae,0x25,0xb0,0x03,0x3c, -0x0c,0x00,0x06,0x24,0xc0,0x01,0xb4,0x34,0xc1,0x01,0xb5,0x34,0x0d,0x00,0x08,0x24, -0xc2,0x01,0x63,0x34,0xc3,0x01,0x42,0x34,0x00,0x00,0x86,0xa2,0xc4,0x01,0xab,0x34, -0x00,0x00,0xa6,0xa2,0xc5,0x01,0xac,0x34,0x00,0x00,0x66,0xa0,0x0e,0x00,0x07,0x24, -0x00,0x00,0x48,0xa0,0xc6,0x01,0xaa,0x34,0xc7,0x01,0xad,0x34,0x0f,0x00,0x02,0x24, -0x00,0x00,0x68,0xa1,0x00,0x00,0x87,0xa1,0x00,0x00,0x47,0xa1,0x00,0x00,0xa2,0xa1, -0x57,0x01,0x02,0x3c,0x48,0x00,0xbf,0x34,0x46,0x00,0xae,0x34,0x0e,0xe2,0x42,0x34, -0x00,0x00,0xc0,0xa5,0x4c,0x00,0xbe,0x34,0x00,0x00,0xe2,0xaf,0x4d,0x00,0xb9,0x34, -0x80,0xff,0x02,0x24,0x00,0x00,0xc0,0xa3,0x00,0x00,0x22,0xa3,0x25,0xb0,0x02,0x3c, -0xbc,0x00,0x03,0x24,0x40,0x00,0x42,0x34,0x00,0x00,0x43,0xa4,0x25,0xb0,0x03,0x3c, -0x64,0x03,0xb8,0x34,0xfc,0x37,0x02,0x24,0x40,0x00,0x63,0x34,0x00,0x00,0x00,0xa3, -0xd8,0x00,0xa7,0x34,0x00,0x00,0x62,0xa4,0x00,0x00,0xe3,0x90,0x2a,0xb0,0x04,0x3c, -0x80,0xff,0x02,0x24,0x26,0xb0,0x06,0x3c,0x25,0x18,0x62,0x00,0x30,0x00,0x89,0x34, -0x20,0x20,0x02,0x24,0x38,0x00,0x84,0x34,0x00,0x00,0xe3,0xa0,0x79,0x00,0xc8,0x34, -0x00,0x00,0x82,0xa4,0x40,0x00,0x03,0x24,0x16,0x00,0x02,0x24,0x00,0x00,0x23,0xa1, -0x94,0x00,0xaa,0x34,0x00,0x00,0x02,0xa1,0x98,0x00,0xab,0x34,0x64,0x00,0x03,0x24, -0x22,0x00,0x02,0x24,0x00,0x00,0x43,0xa5,0x7c,0x00,0xd1,0x34,0x00,0x00,0x62,0xa5, -0x04,0x00,0x12,0x24,0x9c,0x00,0xac,0x34,0x7a,0x00,0xc6,0x34,0x20,0x0c,0x02,0x24, -0x0a,0x00,0x03,0x24,0x00,0x00,0xd2,0xa0,0x9a,0x00,0xad,0x34,0x00,0x00,0x22,0xa6, -0x96,0x00,0xae,0x34,0x00,0x00,0x83,0xa1,0xff,0x03,0x02,0x24,0x02,0x00,0x03,0x24, -0x00,0x00,0xa2,0xa5,0x00,0x00,0xc3,0xa5,0x25,0xb0,0x03,0x3c,0x20,0x00,0x02,0x24, -0xb7,0x00,0x63,0x34,0x00,0x00,0x62,0xa0,0x25,0xb0,0x02,0x3c,0x09,0x00,0x03,0x24, -0x89,0x00,0x42,0x34,0x00,0x00,0x43,0xa0,0x44,0x00,0xa5,0x34,0x00,0x00,0xa2,0x94, -0x02,0x80,0x03,0x3c,0x68,0x15,0x66,0x24,0xff,0xfd,0x03,0x24,0x24,0x10,0x43,0x00, -0x00,0x00,0xa2,0xa4,0x00,0x00,0xa3,0x94,0xd5,0x4a,0xc4,0x90,0x29,0xb0,0x02,0x3c, -0x40,0x00,0x42,0x34,0x00,0x02,0x63,0x34,0x00,0x00,0xa3,0xa4,0x00,0x00,0x52,0xa0, -0xd3,0x0a,0x00,0x0c,0x00,0x00,0x00,0x00,0x44,0x00,0xbf,0x8f,0x40,0x00,0xbe,0x8f, -0x3c,0x00,0xb7,0x8f,0x38,0x00,0xb6,0x8f,0x34,0x00,0xb5,0x8f,0x30,0x00,0xb4,0x8f, -0x2c,0x00,0xb3,0x8f,0x28,0x00,0xb2,0x8f,0x24,0x00,0xb1,0x8f,0x20,0x00,0xb0,0x8f, -0x01,0x00,0x02,0x24,0x08,0x00,0xe0,0x03,0x48,0x00,0xbd,0x27,0x54,0x00,0x85,0x34, -0x00,0xe0,0x42,0x34,0x50,0x00,0x84,0x34,0x12,0x01,0x03,0x24,0x00,0x00,0x82,0xac, -0x00,0x00,0xa3,0xa4,0xf9,0x58,0x00,0x08,0x02,0x80,0x03,0x3c,0x00,0xf0,0x51,0x34, -0xf7,0x01,0x92,0x35,0x15,0xf0,0x4d,0x34,0xad,0x59,0x00,0x08,0xff,0xff,0x0e,0x24, -0x8b,0x59,0x00,0x08,0x1b,0x1b,0x42,0x34,0x25,0xb0,0x03,0x3c,0x25,0xb0,0x08,0x3c, -0xfc,0x37,0x02,0x24,0x40,0x00,0x63,0x34,0x02,0x80,0x04,0x3c,0x00,0x00,0x62,0xa4, -0x14,0x80,0x84,0x24,0xff,0x00,0x07,0x24,0xb0,0x03,0x06,0x35,0x00,0x00,0x83,0x94, -0x00,0x00,0x00,0x00,0xff,0x00,0x62,0x30,0x21,0x18,0x68,0x00,0x0a,0x00,0x47,0x10, -0xff,0x00,0x65,0x30,0x04,0x00,0x82,0x8c,0x00,0x00,0x00,0x00,0x00,0x00,0x62,0xac, -0x00,0x00,0xc3,0xac,0x04,0x00,0x82,0x8c,0x08,0x00,0x84,0x24,0x00,0x00,0xc2,0xac, -0xf2,0xff,0xa7,0x14,0x00,0x00,0x00,0x00,0x25,0xb0,0x08,0x3c,0x01,0x80,0x02,0x3c, -0x0c,0x7a,0x44,0x24,0xff,0x00,0x07,0x24,0xb0,0x03,0x06,0x35,0x00,0x00,0x83,0x94, -0x00,0x00,0x00,0x00,0xff,0x00,0x62,0x30,0x21,0x18,0x68,0x00,0x0a,0x00,0x47,0x10, -0xff,0x00,0x65,0x30,0x04,0x00,0x82,0x8c,0x00,0x00,0x00,0x00,0x00,0x00,0x62,0xac, -0x00,0x00,0xc3,0xac,0x04,0x00,0x82,0x8c,0x08,0x00,0x84,0x24,0x00,0x00,0xc2,0xac, -0xf2,0xff,0xa7,0x14,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00, -0x01,0x80,0x02,0x3c,0x02,0x80,0x05,0x3c,0x10,0x6b,0x42,0x24,0x02,0x80,0x03,0x3c, -0xcc,0x7d,0xa2,0xac,0x00,0x80,0x02,0x3c,0x6c,0x7e,0x60,0xac,0xcc,0x7d,0xa4,0x24, -0x02,0x80,0x03,0x3c,0xc8,0x06,0x42,0x24,0x70,0x7e,0x60,0xa4,0x08,0x00,0x82,0xac, -0x02,0x80,0x03,0x3c,0x00,0x80,0x02,0x3c,0x72,0x7e,0x60,0xa4,0x02,0x80,0x06,0x3c, -0x08,0x0a,0x42,0x24,0x00,0x80,0x03,0x3c,0x74,0x7e,0xc7,0x24,0x14,0x00,0x82,0xac, -0x38,0x08,0x63,0x24,0x02,0x80,0x02,0x3c,0x74,0x7e,0xc0,0xac,0x10,0x00,0x83,0xac, -0x04,0x00,0xe0,0xac,0x7c,0x7e,0x40,0xa0,0x00,0x80,0x02,0x3c,0x88,0x19,0x42,0x24, -0x3c,0x00,0x82,0xac,0x00,0x80,0x03,0x3c,0x00,0x80,0x02,0x3c,0x24,0x0c,0x63,0x24, -0x78,0x0f,0x42,0x24,0x1c,0x00,0x83,0xac,0x20,0x00,0x82,0xac,0x00,0x80,0x03,0x3c, -0x00,0x80,0x02,0x3c,0xc8,0x12,0x63,0x24,0x28,0x16,0x42,0x24,0x24,0x00,0x83,0xac, -0x28,0x00,0x82,0xac,0x00,0x80,0x03,0x3c,0x01,0x80,0x02,0x3c,0x4c,0x1f,0x63,0x24, -0xd0,0x04,0x42,0x24,0x2c,0x00,0x83,0xac,0x30,0x00,0x82,0xac,0x00,0x80,0x03,0x3c, -0x00,0x80,0x02,0x3c,0xe4,0x19,0x63,0x24,0x00,0x03,0x42,0x24,0x38,0x00,0x83,0xac, -0x08,0x00,0xe0,0x03,0x4c,0x00,0x82,0xac,0x25,0xb0,0x02,0x3c,0x08,0x00,0x42,0x34, -0x00,0x00,0x43,0x8c,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x02,0x80,0x0e,0x3c, -0x02,0x80,0x08,0x3c,0x02,0x80,0x02,0x3c,0x02,0x80,0x03,0x3c,0xf8,0x03,0x4d,0x24, -0x00,0x14,0x6c,0x24,0x01,0x00,0x07,0x24,0x00,0x00,0xcb,0x25,0xff,0xff,0x0a,0x24, -0x00,0x04,0x09,0x25,0x80,0x1a,0x07,0x00,0x21,0x10,0x6b,0x00,0x00,0x00,0x42,0xac, -0x90,0x00,0x4a,0xac,0x00,0x04,0x04,0x8d,0x01,0x00,0xe7,0x24,0x08,0x00,0x45,0x24, -0x21,0x18,0x6d,0x00,0x05,0x00,0xe6,0x28,0x04,0x00,0x82,0xac,0x00,0x00,0x44,0xac, -0x04,0x00,0x49,0xac,0x00,0x04,0x02,0xad,0x8c,0x00,0x40,0xac,0x6c,0x00,0xa3,0xac, -0xf0,0xff,0xc0,0x14,0x68,0x00,0xac,0xac,0x08,0x00,0xe0,0x03,0x00,0x00,0xc9,0xad, -0x05,0x00,0xa2,0x2c,0x13,0x00,0x40,0x10,0xff,0xff,0x07,0x24,0x02,0x80,0x02,0x3c, -0x80,0x1a,0x05,0x00,0x00,0x00,0x42,0x24,0x0e,0x00,0xa0,0x10,0x21,0x30,0x62,0x00, -0x90,0x00,0xc3,0x8c,0xff,0xff,0x02,0x24,0x0a,0x00,0x62,0x14,0x00,0x00,0x00,0x00, -0x8c,0x00,0xc2,0x8c,0x00,0x00,0x00,0x00,0x06,0x00,0x40,0x14,0x00,0x00,0x00,0x00, -0x01,0x00,0x02,0x24,0x88,0x00,0xc4,0xac,0x8c,0x00,0xc2,0xac,0x90,0x00,0xc5,0xac, -0x21,0x38,0xa0,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0xe0,0x00,0x25,0xb0,0x04,0x3c, -0x01,0x80,0x02,0x3c,0x18,0x03,0x85,0x34,0xf4,0x6b,0x42,0x24,0xe0,0xff,0xbd,0x27, -0x00,0x00,0xa2,0xac,0x1b,0x00,0x86,0x34,0xdb,0xff,0x03,0x24,0x27,0x00,0x84,0x34, -0x07,0x00,0x02,0x24,0x14,0x00,0xb1,0xaf,0x10,0x00,0xb0,0xaf,0x00,0x00,0x83,0xa0, -0x18,0x00,0xbf,0xaf,0x00,0x00,0xc2,0xa0,0x01,0x00,0x11,0x24,0x21,0x80,0x00,0x00, -0x7a,0x42,0x00,0x0c,0x21,0x20,0x00,0x02,0x01,0x00,0x02,0x26,0xff,0x00,0x50,0x30, -0x2b,0x18,0x30,0x02,0xfa,0xff,0x60,0x10,0x00,0x00,0x00,0x00,0x7a,0x42,0x00,0x0c, -0x21,0x20,0x00,0x00,0x18,0x00,0xbf,0x8f,0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f, -0x01,0x00,0x02,0x24,0x08,0x00,0xe0,0x03,0x20,0x00,0xbd,0x27,0x08,0x00,0xe0,0x03, -0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x02,0x80,0x02,0x3c, -0x68,0x15,0x42,0x24,0x40,0x10,0x03,0x3c,0xff,0xff,0x44,0x30,0x25,0xc0,0x83,0x00, -0x94,0x64,0x58,0xac,0x40,0x00,0x18,0x27,0xa0,0x64,0x58,0xac,0x40,0x00,0x18,0x27, -0xac,0x64,0x58,0xac,0x40,0x00,0x18,0x27,0xb8,0x64,0x58,0xac,0x40,0x00,0x18,0x27, -0xe0,0xff,0xbd,0x27,0xc4,0x64,0x58,0xac,0x40,0x00,0x18,0x27,0x1c,0x00,0xb7,0xaf, -0x18,0x00,0xb6,0xaf,0x14,0x00,0xb5,0xaf,0x10,0x00,0xb4,0xaf,0x0c,0x00,0xb3,0xaf, -0x08,0x00,0xb2,0xaf,0x04,0x00,0xb1,0xaf,0x00,0x00,0xb0,0xaf,0xd0,0x64,0x58,0xac, -0xa0,0x64,0x45,0x8c,0xac,0x64,0x46,0x8c,0xb8,0x64,0x47,0x8c,0xc4,0x64,0x48,0x8c, -0xd0,0x64,0x49,0x8c,0x40,0x00,0x18,0x27,0xdc,0x64,0x58,0xac,0x21,0x50,0x00,0x03, -0x25,0x20,0x83,0x00,0x40,0x00,0x18,0x27,0x20,0x10,0x03,0x3c,0x90,0x64,0x44,0xac, -0x9c,0x64,0x45,0xac,0xa8,0x64,0x46,0xac,0xb4,0x64,0x47,0xac,0xc0,0x64,0x48,0xac, -0xcc,0x64,0x49,0xac,0x25,0xb0,0x06,0x3c,0x28,0x64,0x43,0xac,0x24,0x64,0x43,0xac, -0x34,0x64,0x43,0xac,0x30,0x64,0x43,0xac,0x40,0x64,0x43,0xac,0x3c,0x64,0x43,0xac, -0x4c,0x64,0x43,0xac,0x48,0x64,0x43,0xac,0xe8,0x64,0x58,0xac,0x00,0x02,0x18,0x27, -0xd8,0x64,0x4a,0xac,0x00,0x65,0x58,0xac,0x58,0x64,0x43,0xac,0x54,0x64,0x43,0xac, -0x64,0x64,0x43,0xac,0x60,0x64,0x43,0xac,0x70,0x64,0x43,0xac,0x6c,0x64,0x43,0xac, -0xac,0x00,0xc4,0x34,0xb0,0x00,0xc5,0x34,0x00,0x00,0x92,0x8c,0xe8,0x64,0x50,0x8c, -0x00,0x00,0xb3,0x8c,0x21,0x10,0x04,0x3c,0x23,0x10,0x09,0x3c,0x22,0x10,0x0c,0x3c, -0x02,0x80,0x14,0x3c,0x02,0x80,0x15,0x3c,0x02,0x80,0x16,0x3c,0x02,0x80,0x17,0x3c, -0x24,0x10,0x05,0x3c,0x21,0x88,0x00,0x03,0x08,0x7b,0x87,0x26,0x00,0x04,0x18,0x27, -0x10,0x7b,0xa8,0x26,0x18,0x7b,0xca,0x26,0x20,0x7b,0xeb,0x26,0x00,0x04,0x2d,0x35, -0x00,0x40,0x8e,0x34,0x00,0x80,0x8f,0x35,0x00,0x01,0xc6,0x34,0xe4,0x64,0x50,0xac, -0xfc,0x64,0x51,0xac,0x64,0x65,0x4d,0xac,0x28,0x65,0x52,0xac,0x34,0x65,0x4e,0xac, -0x58,0x65,0x4f,0xac,0x4c,0x65,0x53,0xac,0x00,0x00,0xc5,0xac,0x48,0x65,0x45,0xac, -0x68,0x65,0x43,0xac,0x74,0x65,0x58,0xac,0x7c,0x64,0x43,0xac,0x78,0x64,0x43,0xac, -0x06,0x65,0x40,0xa4,0x05,0x65,0x40,0xa0,0x04,0x65,0x40,0xa0,0x5c,0x65,0x49,0xac, -0x60,0x65,0x49,0xac,0x20,0x65,0x44,0xac,0x24,0x65,0x44,0xac,0x2c,0x65,0x44,0xac, -0x30,0x65,0x44,0xac,0x50,0x65,0x4c,0xac,0x54,0x65,0x4c,0xac,0x44,0x65,0x45,0xac, -0x6c,0x65,0x43,0xac,0x78,0x65,0x58,0xac,0x04,0x00,0x08,0xad,0x08,0x7b,0x87,0xae, -0x04,0x00,0x4a,0xad,0x10,0x7b,0xa8,0xae,0x04,0x00,0x6b,0xad,0x18,0x7b,0xca,0xae, -0x20,0x7b,0xeb,0xae,0x04,0x00,0xe7,0xac,0x02,0x80,0x02,0x3c,0x00,0x14,0x43,0x24, -0x21,0x20,0xe0,0x00,0x03,0x00,0x06,0x24,0x21,0x10,0x80,0x00,0xff,0xff,0xc6,0x24, -0x08,0x00,0x78,0xac,0x00,0x00,0x63,0xac,0x10,0x00,0x60,0xac,0x00,0x00,0x67,0xac, -0x21,0x20,0x60,0x00,0x04,0x00,0x62,0xac,0x00,0x00,0x43,0xac,0x00,0x01,0x18,0x27, -0xf5,0xff,0xc1,0x04,0x18,0x00,0x63,0x24,0x02,0x80,0x02,0x3c,0x10,0x7b,0x49,0x24, -0x02,0x80,0x03,0x3c,0x02,0x80,0x02,0x3c,0x04,0x00,0x28,0x8d,0x60,0x14,0x4b,0x24, -0x04,0x00,0xe4,0xac,0x00,0x14,0x6a,0x24,0x01,0x00,0x07,0x24,0x21,0x28,0x00,0x00, -0x07,0x00,0x06,0x24,0x21,0x20,0xab,0x00,0x21,0x10,0xaa,0x00,0xff,0xff,0xc6,0x24, -0x68,0x00,0x58,0xac,0x70,0x00,0x47,0xac,0x18,0x00,0xa5,0x24,0x00,0x00,0x89,0xac, -0x04,0x00,0x88,0xac,0x00,0x00,0x04,0xad,0x00,0x01,0x18,0x27,0xf5,0xff,0xc1,0x04, -0x21,0x40,0x80,0x00,0x02,0x80,0x02,0x3c,0x18,0x7b,0x4a,0x24,0x02,0x80,0x03,0x3c, -0x02,0x80,0x02,0x3c,0x04,0x00,0x45,0x8d,0x20,0x15,0x4b,0x24,0x04,0x00,0x24,0xad, -0x02,0x00,0x07,0x24,0x00,0x14,0x69,0x24,0x21,0x20,0x00,0x00,0x01,0x00,0x06,0x24, -0x21,0x40,0x8b,0x00,0x21,0x10,0x89,0x00,0xff,0xff,0xc6,0x24,0x28,0x01,0x58,0xac, -0x30,0x01,0x47,0xac,0x18,0x00,0x84,0x24,0x00,0x00,0x0a,0xad,0x04,0x00,0x05,0xad, -0x00,0x00,0xa8,0xac,0x00,0x02,0x18,0x27,0xf5,0xff,0xc1,0x04,0x21,0x28,0x00,0x01, -0x02,0x80,0x05,0x3c,0x20,0x7b,0xa5,0x24,0x04,0x00,0xa6,0x8c,0x1c,0x00,0xb7,0x8f, -0x18,0x00,0xb6,0x8f,0x14,0x00,0xb5,0x8f,0x10,0x00,0xb4,0x8f,0x0c,0x00,0xb3,0x8f, -0x08,0x00,0xb2,0x8f,0x04,0x00,0xb1,0x8f,0x00,0x00,0xb0,0x8f,0x02,0x80,0x07,0x3c, -0x02,0x80,0x03,0x3c,0x50,0x15,0xe4,0x24,0x00,0x14,0x63,0x24,0x03,0x00,0x02,0x24, -0x20,0x00,0xbd,0x27,0x58,0x01,0x78,0xac,0x04,0x00,0x48,0xad,0x04,0x00,0xa4,0xac, -0x60,0x01,0x62,0xac,0x50,0x15,0xe5,0xac,0x04,0x00,0x86,0xac,0x08,0x00,0xe0,0x03, -0x00,0x00,0xc4,0xac,0xd0,0xff,0xbd,0x27,0x02,0x80,0x02,0x3c,0x20,0x00,0xb2,0xaf, -0x02,0x80,0x03,0x3c,0x4c,0x91,0x52,0x24,0x02,0x80,0x02,0x3c,0x28,0x00,0xb4,0xaf, -0x24,0x00,0xb3,0xaf,0x1c,0x00,0xb1,0xaf,0x18,0x00,0xb0,0xaf,0x2c,0x00,0xbf,0xaf, -0xd8,0x90,0x73,0x24,0x68,0x15,0x50,0x24,0x21,0x88,0x00,0x00,0x02,0x80,0x14,0x3c, -0xee,0x4e,0x00,0x0c,0x21,0x20,0x20,0x02,0x78,0x51,0x05,0x8e,0x6c,0x00,0x66,0x8e, -0xb8,0x90,0x82,0x26,0x6c,0x00,0x43,0x8e,0x1b,0x00,0x44,0x90,0xff,0xf1,0x02,0x24, -0x21,0x18,0x66,0x00,0x24,0x28,0xa2,0x00,0x00,0x21,0x04,0x00,0x42,0x18,0x03,0x00, -0x00,0x02,0xa5,0x34,0x44,0x51,0x03,0xae,0x68,0x51,0x04,0xae,0x78,0x51,0x05,0xae, -0x6c,0x51,0x04,0xae,0x21,0x30,0x00,0x00,0x21,0x10,0x06,0x02,0x01,0x00,0xc6,0x24, -0x1d,0x00,0xc3,0x28,0x99,0x51,0x40,0xa0,0x7c,0x51,0x40,0xa0,0xfa,0xff,0x60,0x14, -0xb6,0x51,0x40,0xa0,0x01,0x00,0x31,0x26,0x20,0x00,0x22,0x2a,0xd4,0x51,0x00,0xae, -0xe3,0xff,0x40,0x14,0x94,0x00,0x10,0x26,0x02,0x80,0x02,0x3c,0x02,0x80,0x03,0x3c, -0x68,0x15,0x4b,0x24,0x02,0x80,0x02,0x3c,0x4c,0x91,0x6f,0x24,0xd8,0x90,0x4d,0x24, -0x02,0x80,0x03,0x3c,0x02,0x80,0x02,0x3c,0xb8,0x90,0x6e,0x24,0x98,0x90,0x4c,0x24, -0x21,0x88,0x00,0x00,0x80,0x18,0x11,0x00,0x21,0x20,0x6d,0x00,0x21,0x10,0x6f,0x00, -0x21,0x28,0x2e,0x02,0x21,0x30,0x2c,0x02,0x00,0x00,0x88,0x8c,0x00,0x00,0xa9,0x90, -0x00,0x00,0xc7,0x90,0x00,0x00,0x4a,0x8c,0x21,0x10,0x2b,0x02,0x01,0x00,0x31,0x26, -0x21,0x18,0x6b,0x00,0x1d,0x00,0x24,0x2a,0xec,0x44,0x68,0xac,0xca,0x44,0x47,0xa0, -0x60,0x45,0x6a,0xac,0xef,0xff,0x80,0x14,0x90,0x44,0x49,0xa0,0x02,0x80,0x02,0x3c, -0x68,0x15,0x4a,0x24,0x02,0x80,0x03,0x3c,0x02,0x80,0x02,0x3c,0x74,0x8f,0x6b,0x24, -0x14,0x8e,0x4c,0x24,0x21,0x88,0x00,0x00,0x21,0x48,0x00,0x00,0x21,0x30,0x00,0x00, -0x21,0x40,0x2a,0x01,0x21,0x38,0x2b,0x01,0x21,0x10,0xe6,0x00,0x91,0x00,0x44,0x90, -0x00,0x00,0x45,0x90,0x21,0x18,0x06,0x01,0x01,0x00,0xc6,0x24,0x05,0x00,0xc2,0x28, -0xc5,0x43,0x64,0xa0,0xf8,0xff,0x40,0x14,0x34,0x43,0x65,0xa0,0x21,0x10,0x2c,0x02, -0x1d,0x00,0x44,0x90,0x00,0x00,0x45,0x90,0x21,0x18,0x2a,0x02,0x01,0x00,0x31,0x26, -0x1d,0x00,0x22,0x2a,0x73,0x44,0x64,0xa0,0x56,0x44,0x65,0xa0,0xeb,0xff,0x40,0x14, -0x05,0x00,0x29,0x25,0x52,0x00,0x02,0x24,0x10,0x00,0xa2,0xa3,0x41,0x00,0x03,0x24, -0x4d,0x00,0x02,0x24,0x02,0x80,0x07,0x3c,0x1c,0x97,0xe7,0x24,0x11,0x00,0xa3,0xa3, -0x12,0x00,0xa2,0xa3,0xe8,0x03,0x03,0x24,0x01,0x00,0x02,0x24,0x00,0x80,0x06,0x3c, -0x10,0x00,0xa5,0x27,0x21,0x20,0xe0,0x00,0xf0,0x37,0xc6,0x24,0x0c,0x00,0xe3,0xac, -0x14,0x00,0xe2,0xa0,0xfb,0x0c,0x00,0x0c,0x13,0x00,0xa0,0xa3,0x2c,0x00,0xbf,0x8f, -0x28,0x00,0xb4,0x8f,0x24,0x00,0xb3,0x8f,0x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f, -0x18,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x30,0x00,0xbd,0x27,0xe0,0xff,0xbd,0x27, -0x02,0x80,0x02,0x3c,0x42,0x00,0x03,0x24,0x10,0x00,0xa3,0xa3,0x55,0x60,0x40,0xa0, -0x4e,0x00,0x03,0x24,0x43,0x00,0x02,0x24,0x02,0x80,0x07,0x3c,0x54,0x97,0xe7,0x24, -0x11,0x00,0xa2,0xa3,0x12,0x00,0xa3,0xa3,0xd0,0x07,0x02,0x24,0x01,0x00,0x03,0x24, -0x00,0x80,0x06,0x3c,0x10,0x00,0xa5,0x27,0x21,0x20,0xe0,0x00,0xdc,0x44,0xc6,0x24, -0x0c,0x00,0xe2,0xac,0x14,0x00,0xe3,0xa0,0x18,0x00,0xbf,0xaf,0xfb,0x0c,0x00,0x0c, -0x13,0x00,0xa0,0xa3,0x18,0x00,0xbf,0x8f,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03, -0x20,0x00,0xbd,0x27,0x48,0xfd,0xbd,0x27,0xb4,0x02,0xb3,0xaf,0x02,0x80,0x02,0x3c, -0x02,0x80,0x13,0x3c,0x24,0x92,0x46,0x24,0x68,0x15,0x63,0x26,0xb0,0x02,0xb2,0xaf, -0xac,0x02,0xb1,0xaf,0xa8,0x02,0xb0,0xaf,0x03,0x40,0x60,0xa0,0x21,0x38,0xa0,0x03, -0x90,0x00,0xc8,0x24,0x00,0x00,0xc2,0x8c,0x04,0x00,0xc3,0x8c,0x08,0x00,0xc4,0x8c, -0x0c,0x00,0xc5,0x8c,0x10,0x00,0xc6,0x24,0x00,0x00,0xe2,0xac,0x04,0x00,0xe3,0xac, -0x08,0x00,0xe4,0xac,0x0c,0x00,0xe5,0xac,0xf6,0xff,0xc8,0x14,0x10,0x00,0xe7,0x24, -0x00,0x00,0xc3,0x8c,0x02,0x80,0x02,0x3c,0xb8,0x92,0x58,0x24,0x00,0x00,0xe3,0xac, -0x98,0x00,0xb9,0x27,0x00,0x01,0x12,0x27,0x01,0x00,0x02,0x93,0x05,0x00,0x03,0x93, -0x09,0x00,0x04,0x93,0x0d,0x00,0x05,0x93,0x00,0x00,0x11,0x93,0x02,0x00,0x0d,0x93, -0x04,0x00,0x10,0x93,0x06,0x00,0x0c,0x93,0x08,0x00,0x0f,0x93,0x0a,0x00,0x07,0x93, -0x0c,0x00,0x0e,0x93,0x0e,0x00,0x06,0x93,0x03,0x00,0x08,0x93,0x07,0x00,0x09,0x93, -0x0b,0x00,0x0a,0x93,0x0f,0x00,0x0b,0x93,0x00,0x12,0x02,0x00,0x00,0x1a,0x03,0x00, -0x00,0x22,0x04,0x00,0x00,0x2a,0x05,0x00,0x25,0x10,0x51,0x00,0x25,0x18,0x70,0x00, -0x25,0x20,0x8f,0x00,0x25,0x28,0xae,0x00,0x00,0x6c,0x0d,0x00,0x00,0x64,0x0c,0x00, -0x00,0x3c,0x07,0x00,0x00,0x34,0x06,0x00,0x25,0x68,0xa2,0x01,0x25,0x60,0x83,0x01, -0x25,0x38,0xe4,0x00,0x25,0x30,0xc5,0x00,0x00,0x46,0x08,0x00,0x00,0x4e,0x09,0x00, -0x00,0x56,0x0a,0x00,0x00,0x5e,0x0b,0x00,0x25,0x40,0x0d,0x01,0x25,0x48,0x2c,0x01, -0x25,0x50,0x47,0x01,0x25,0x58,0x66,0x01,0x10,0x00,0x18,0x27,0x00,0x00,0x28,0xaf, -0x04,0x00,0x29,0xaf,0x08,0x00,0x2a,0xaf,0x0c,0x00,0x2b,0xaf,0xd2,0xff,0x12,0x17, -0x10,0x00,0x39,0x27,0x01,0x00,0x02,0x93,0x05,0x00,0x03,0x93,0x00,0x00,0x09,0x93, -0x02,0x00,0x04,0x93,0x04,0x00,0x08,0x93,0x06,0x00,0x05,0x93,0x07,0x00,0x06,0x93, -0x03,0x00,0x07,0x93,0x00,0x12,0x02,0x00,0x00,0x1a,0x03,0x00,0x25,0x10,0x49,0x00, -0x25,0x18,0x68,0x00,0x00,0x24,0x04,0x00,0x00,0x2c,0x05,0x00,0x25,0x20,0x82,0x00, -0x25,0x28,0xa3,0x00,0x00,0x3e,0x07,0x00,0x00,0x36,0x06,0x00,0x02,0x80,0x02,0x3c, -0x25,0x38,0xe4,0x00,0x25,0x30,0xc5,0x00,0xc0,0x93,0x58,0x24,0x04,0x00,0x26,0xaf, -0x00,0x00,0x27,0xaf,0x00,0x01,0x12,0x27,0xa0,0x01,0xb9,0x27,0x01,0x00,0x02,0x93, -0x05,0x00,0x03,0x93,0x09,0x00,0x04,0x93,0x0d,0x00,0x05,0x93,0x00,0x00,0x11,0x93, -0x02,0x00,0x0d,0x93,0x04,0x00,0x10,0x93,0x06,0x00,0x0c,0x93,0x08,0x00,0x0f,0x93, -0x0a,0x00,0x07,0x93,0x0c,0x00,0x0e,0x93,0x0e,0x00,0x06,0x93,0x03,0x00,0x08,0x93, -0x07,0x00,0x09,0x93,0x0b,0x00,0x0a,0x93,0x0f,0x00,0x0b,0x93,0x00,0x12,0x02,0x00, -0x00,0x1a,0x03,0x00,0x00,0x22,0x04,0x00,0x00,0x2a,0x05,0x00,0x25,0x10,0x51,0x00, -0x25,0x18,0x70,0x00,0x25,0x20,0x8f,0x00,0x25,0x28,0xae,0x00,0x00,0x6c,0x0d,0x00, -0x00,0x64,0x0c,0x00,0x00,0x3c,0x07,0x00,0x00,0x34,0x06,0x00,0x25,0x68,0xa2,0x01, -0x25,0x60,0x83,0x01,0x25,0x38,0xe4,0x00,0x25,0x30,0xc5,0x00,0x00,0x46,0x08,0x00, -0x00,0x4e,0x09,0x00,0x00,0x56,0x0a,0x00,0x00,0x5e,0x0b,0x00,0x25,0x40,0x0d,0x01, -0x25,0x48,0x2c,0x01,0x25,0x50,0x47,0x01,0x25,0x58,0x66,0x01,0x10,0x00,0x18,0x27, -0x00,0x00,0x28,0xaf,0x04,0x00,0x29,0xaf,0x08,0x00,0x2a,0xaf,0x0c,0x00,0x2b,0xaf, -0xd2,0xff,0x12,0x17,0x10,0x00,0x39,0x27,0x01,0x00,0x02,0x93,0x05,0x00,0x03,0x93, -0x00,0x00,0x09,0x93,0x02,0x00,0x04,0x93,0x04,0x00,0x08,0x93,0x06,0x00,0x05,0x93, -0x07,0x00,0x06,0x93,0x03,0x00,0x07,0x93,0x00,0x12,0x02,0x00,0x00,0x1a,0x03,0x00, -0x25,0x10,0x49,0x00,0x25,0x18,0x68,0x00,0x00,0x24,0x04,0x00,0x00,0x2c,0x05,0x00, -0x25,0x20,0x82,0x00,0x25,0x28,0xa3,0x00,0x00,0x3e,0x07,0x00,0x00,0x36,0x06,0x00, -0x25,0x30,0xc5,0x00,0x25,0x38,0xe4,0x00,0x02,0x80,0x02,0x3c,0x04,0x00,0x26,0xaf, -0x00,0x00,0x27,0xaf,0x68,0x15,0x46,0x24,0x21,0x50,0x00,0x00,0x80,0x20,0x0a,0x00, -0x21,0x10,0x9d,0x00,0x00,0x00,0x45,0x8c,0x01,0x00,0x43,0x25,0xff,0x00,0x6a,0x30, -0x21,0x20,0x86,0x00,0x25,0x00,0x42,0x2d,0xf8,0xff,0x40,0x14,0x18,0x40,0x85,0xac, -0x02,0x80,0x02,0x3c,0x68,0x15,0x4b,0x24,0x21,0x50,0x00,0x00,0xc0,0x10,0x0a,0x00, -0x21,0x48,0x5d,0x00,0x21,0x38,0x00,0x00,0x21,0x40,0x4b,0x00,0x21,0x10,0x27,0x01, -0xa0,0x01,0x46,0x90,0x98,0x00,0x45,0x90,0x01,0x00,0xe4,0x24,0x21,0x18,0x07,0x01, -0xff,0x00,0x87,0x30,0x08,0x00,0xe2,0x2c,0xb4,0x41,0x66,0xa0,0xf7,0xff,0x40,0x14, -0xac,0x40,0x65,0xa0,0x01,0x00,0x42,0x25,0xff,0x00,0x4a,0x30,0x21,0x00,0x43,0x2d, -0xef,0xff,0x60,0x14,0xc0,0x10,0x0a,0x00,0x25,0xb0,0x02,0x3c,0x0a,0x00,0x42,0x34, -0x00,0x00,0x43,0x90,0x00,0x00,0x00,0x00,0x20,0x00,0x63,0x30,0x42,0x00,0x60,0x10, -0x68,0x15,0x64,0x26,0x33,0x00,0x02,0x24,0xc1,0x42,0x62,0xa1,0x1c,0x00,0x03,0x24, -0x0f,0x00,0x02,0x24,0xbc,0x42,0x63,0xa1,0xbd,0x42,0x62,0xa1,0x68,0x15,0x65,0x26, -0x08,0x40,0xa4,0x8c,0xff,0x7f,0x08,0x3c,0xff,0xff,0x08,0x35,0xc0,0xff,0x02,0x24, -0x24,0x20,0x88,0x00,0x24,0x20,0x82,0x00,0x0c,0x00,0x84,0x34,0xff,0xc0,0x02,0x24, -0x24,0x20,0x82,0x00,0xc0,0xff,0x02,0x3c,0xff,0xff,0x42,0x34,0x00,0x18,0x84,0x34, -0xbf,0xff,0x03,0x3c,0x24,0x20,0x82,0x00,0xff,0xff,0x63,0x34,0x7f,0xff,0x02,0x3c, -0x24,0x20,0x83,0x00,0xff,0xff,0x42,0x34,0x24,0x20,0x82,0x00,0x0c,0x40,0xa6,0x8c, -0x7f,0xff,0x03,0x24,0x40,0x40,0x84,0x34,0xff,0xff,0x02,0x3c,0x24,0x20,0x83,0x00, -0xff,0x7f,0x42,0x34,0xff,0xbf,0x03,0x3c,0x10,0x40,0xa7,0x8c,0x24,0x20,0x82,0x00, -0xff,0xff,0x63,0x34,0xff,0x9f,0x02,0x3c,0x24,0x30,0xc3,0x00,0xff,0xff,0x42,0x34, -0xff,0x3f,0x03,0x3c,0x24,0x20,0x82,0x00,0xff,0xff,0x63,0x34,0x12,0x00,0x02,0x24, -0xb4,0x02,0xb3,0x8f,0xb0,0x02,0xb2,0x8f,0xac,0x02,0xb1,0x8f,0xa8,0x02,0xb0,0x8f, -0x24,0x38,0xe3,0x00,0xc7,0x42,0xa2,0xa0,0x1f,0x00,0x03,0x24,0x01,0x00,0x02,0x24, -0x24,0x30,0xc8,0x00,0xbe,0x42,0xa3,0xa0,0xc0,0x42,0xa2,0xa0,0xff,0x00,0x03,0x24, -0xff,0xff,0x02,0x24,0xb8,0x02,0xbd,0x27,0x08,0x40,0xa4,0xac,0x10,0x40,0xa7,0xac, -0x0c,0x40,0xa6,0xac,0xc2,0x42,0xa2,0xa0,0xc4,0x42,0xa3,0xa4,0xbf,0x42,0xa0,0xa0, -0x08,0x00,0xe0,0x03,0xc6,0x42,0xa0,0xa0,0x33,0x00,0x02,0x24,0xc1,0x42,0x82,0xa0, -0x0d,0x00,0x03,0x24,0x03,0x00,0x02,0x24,0xbc,0x42,0x83,0xa0,0x65,0x5d,0x00,0x08, -0xbd,0x42,0x82,0xa0,0xe0,0xff,0xbd,0x27,0x02,0x80,0x07,0x3c,0x68,0x15,0xe7,0x24, -0x18,0x00,0xbf,0xaf,0x00,0x40,0xe3,0x8c,0xf0,0xff,0x02,0x24,0x02,0x80,0x08,0x3c, -0x24,0x18,0x62,0x00,0xff,0xf0,0x02,0x24,0x24,0x18,0x62,0x00,0x00,0x40,0xe3,0xac, -0x1c,0x00,0x03,0x24,0x36,0x00,0x02,0x24,0xcf,0x42,0xe3,0xa0,0x20,0x00,0x03,0x24, -0xce,0x42,0xe2,0xa0,0xd1,0x42,0xe3,0xa0,0x32,0x00,0x02,0x24,0x20,0x00,0x03,0x24, -0xd0,0x42,0xe2,0xa0,0xc8,0x42,0xe3,0xa4,0x0a,0x00,0x02,0x24,0x00,0x02,0x03,0x24, -0xd2,0x42,0xe2,0xa0,0xcc,0x42,0xe3,0xa4,0x00,0x01,0x02,0x24,0x49,0x00,0x03,0x24, -0x38,0x97,0x08,0x25,0xff,0xff,0x0a,0x34,0x01,0x00,0x09,0x24,0x11,0x00,0xa3,0xa3, -0xca,0x42,0xe2,0xa4,0xd0,0x07,0x03,0x24,0x44,0x00,0x02,0x24,0x00,0x80,0x06,0x3c, -0x10,0x00,0xa2,0xa3,0x10,0x00,0xa5,0x27,0x47,0x00,0x02,0x24,0x21,0x20,0x00,0x01, -0x54,0x45,0xc6,0x24,0x04,0x40,0xea,0xac,0x02,0x40,0xe9,0xa0,0x0c,0x00,0x03,0xad, -0x14,0x00,0x09,0xa1,0xe6,0x42,0xe0,0xa0,0xdc,0x63,0xea,0xac,0xd7,0x42,0xe0,0xa0, -0x12,0x00,0xa2,0xa3,0xfb,0x0c,0x00,0x0c,0x13,0x00,0xa0,0xa3,0x18,0x00,0xbf,0x8f, -0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x20,0x00,0xbd,0x27,0xe0,0xff,0xbd,0x27, -0x02,0x80,0x02,0x3c,0x50,0x00,0x03,0x24,0x10,0x00,0xa3,0xa3,0x2a,0x62,0x40,0xa0, -0x41,0x00,0x03,0x24,0x52,0x00,0x02,0x24,0x02,0x80,0x07,0x3c,0xc4,0x97,0xe7,0x24, -0x11,0x00,0xa2,0xa3,0x12,0x00,0xa3,0xa3,0xd0,0x07,0x02,0x24,0x01,0x00,0x03,0x24, -0x01,0x80,0x06,0x3c,0x10,0x00,0xa5,0x27,0x21,0x20,0xe0,0x00,0x88,0x5b,0xc6,0x24, -0x0c,0x00,0xe2,0xac,0x14,0x00,0xe3,0xa0,0x18,0x00,0xbf,0xaf,0xfb,0x0c,0x00,0x0c, -0x13,0x00,0xa0,0xa3,0x18,0x00,0xbf,0x8f,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03, -0x20,0x00,0xbd,0x27,0xd8,0xff,0xbd,0x27,0x18,0x00,0xb0,0xaf,0x02,0x80,0x10,0x3c, -0x68,0x15,0x10,0x26,0x20,0x00,0xbf,0xaf,0x1c,0x00,0xb1,0xaf,0x00,0x40,0x09,0x8e, -0xff,0xff,0x02,0x24,0xff,0x00,0x4b,0x30,0x0f,0xff,0x02,0x24,0x24,0x48,0x22,0x01, -0xff,0xff,0x02,0x3c,0xff,0x0f,0x42,0x34,0x24,0x48,0x22,0x01,0x01,0x00,0x07,0x3c, -0x47,0x00,0x02,0x24,0x3b,0x00,0x03,0x24,0x02,0x80,0x08,0x3c,0x10,0x00,0xa2,0xa3, -0x11,0x00,0xa3,0xa3,0xe0,0x97,0x08,0x25,0x56,0x30,0xea,0x34,0xd0,0x07,0x02,0x24, -0x01,0x00,0x03,0x24,0xf4,0x98,0xe7,0x34,0x00,0x80,0x06,0x3c,0x04,0x43,0x0b,0xae, -0x00,0x40,0x09,0xae,0x43,0x00,0x11,0x24,0x10,0x00,0xa5,0x27,0x0c,0x43,0x07,0xae, -0x10,0x43,0x0a,0xae,0x0c,0x00,0x02,0xad,0x14,0x00,0x03,0xa1,0x08,0x43,0x00,0xae, -0x14,0x43,0x00,0xae,0x18,0x43,0x00,0xae,0x21,0x20,0x00,0x01,0xe4,0x4e,0xc6,0x24, -0x12,0x00,0xb1,0xa3,0xfb,0x0c,0x00,0x0c,0x13,0x00,0xa0,0xa3,0x1e,0x00,0x02,0x24, -0x21,0x43,0x02,0xa2,0x4a,0x00,0x03,0x24,0x45,0x00,0x02,0x24,0x1c,0x43,0x03,0xa2, -0x1d,0x43,0x02,0xa2,0x23,0x00,0x03,0x24,0x3e,0x00,0x02,0x24,0x1e,0x43,0x11,0xa2, -0x1f,0x43,0x02,0xa2,0x20,0x43,0x03,0xa2,0x20,0x00,0xbf,0x8f,0x1c,0x00,0xb1,0x8f, -0x18,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x28,0x00,0xbd,0x27,0xe0,0xff,0xbd,0x27, -0x3b,0x00,0x02,0x24,0x43,0x00,0x03,0x24,0x10,0x00,0xa2,0xa3,0x11,0x00,0xa3,0xa3, -0x36,0x00,0x02,0x24,0x02,0x80,0x03,0x3c,0x02,0x80,0x07,0x3c,0xfc,0x97,0xe7,0x24, -0x12,0x00,0xa2,0xa3,0x3b,0x58,0x60,0xa0,0xd0,0x07,0x02,0x24,0x01,0x00,0x03,0x24, -0x00,0x80,0x06,0x3c,0x10,0x00,0xa5,0x27,0x21,0x20,0xe0,0x00,0x20,0x53,0xc6,0x24, -0x0c,0x00,0xe2,0xac,0x14,0x00,0xe3,0xa0,0x18,0x00,0xbf,0xaf,0xfb,0x0c,0x00,0x0c, -0x13,0x00,0xa0,0xa3,0x18,0x00,0xbf,0x8f,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03, -0x20,0x00,0xbd,0x27,0xff,0xff,0x07,0x24,0x02,0x80,0x02,0x3c,0xe0,0xff,0xbd,0x27, -0x3d,0x58,0x47,0xa0,0x3b,0x00,0x03,0x24,0x43,0x00,0x02,0x24,0x10,0x00,0xa3,0xa3, -0x11,0x00,0xa2,0xa3,0x36,0x00,0x03,0x24,0x16,0x00,0x02,0x24,0x02,0x80,0x08,0x3c, -0x18,0x98,0x08,0x25,0x12,0x00,0xa3,0xa3,0x13,0x00,0xa2,0xa3,0xd0,0x07,0x03,0x24, -0x01,0x00,0x02,0x24,0x00,0x80,0x06,0x3c,0x10,0x00,0xa5,0x27,0x21,0x20,0x00,0x01, -0x0c,0x00,0x03,0xad,0x14,0x00,0x02,0xa1,0x18,0x00,0xbf,0xaf,0xfb,0x0c,0x00,0x0c, -0xb8,0x54,0xc6,0x24,0x18,0x00,0xbf,0x8f,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03, -0x20,0x00,0xbd,0x27,0xe0,0xff,0xbd,0x27,0x02,0x80,0x02,0x3c,0x52,0x00,0x03,0x24, -0x10,0x00,0xa3,0xa3,0x4c,0x79,0x40,0xa4,0x54,0x00,0x03,0x24,0x53,0x00,0x02,0x24, -0x02,0x80,0x07,0x3c,0x34,0x98,0xe7,0x24,0x11,0x00,0xa2,0xa3,0x12,0x00,0xa3,0xa3, -0xf4,0x01,0x02,0x24,0x01,0x00,0x03,0x24,0x01,0x80,0x06,0x3c,0x10,0x00,0xa5,0x27, -0x21,0x20,0xe0,0x00,0xc8,0x5c,0xc6,0x24,0x0c,0x00,0xe2,0xac,0x14,0x00,0xe3,0xa0, -0x18,0x00,0xbf,0xaf,0xfb,0x0c,0x00,0x0c,0x13,0x00,0xa0,0xa3,0x18,0x00,0xbf,0x8f, -0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x20,0x00,0xbd,0x27,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x78,0x0c,0x00,0x00,0x01,0x00,0x00,0x5e,0x78,0x0c,0x00,0x00, -0x01,0x00,0x01,0x5e,0x78,0x0c,0x00,0x00,0x01,0x00,0x02,0x5e,0x78,0x0c,0x00,0x00, -0x01,0x00,0x03,0x5e,0x78,0x0c,0x00,0x00,0x01,0x00,0x04,0x5d,0x78,0x0c,0x00,0x00, -0x01,0x00,0x05,0x5b,0x78,0x0c,0x00,0x00,0x01,0x00,0x06,0x59,0x78,0x0c,0x00,0x00, -0x01,0x00,0x07,0x57,0x78,0x0c,0x00,0x00,0x01,0x00,0x08,0x55,0x78,0x0c,0x00,0x00, -0x01,0x00,0x09,0x53,0x78,0x0c,0x00,0x00,0x01,0x00,0x0a,0x51,0x78,0x0c,0x00,0x00, -0x01,0x00,0x0b,0x4f,0x78,0x0c,0x00,0x00,0x01,0x00,0x0c,0x4d,0x78,0x0c,0x00,0x00, -0x01,0x00,0x0d,0x4b,0x78,0x0c,0x00,0x00,0x01,0x00,0x0e,0x49,0x78,0x0c,0x00,0x00, -0x01,0x00,0x0f,0x47,0x78,0x0c,0x00,0x00,0x01,0x00,0x10,0x45,0x78,0x0c,0x00,0x00, -0x01,0x00,0x11,0x43,0x78,0x0c,0x00,0x00,0x01,0x00,0x12,0x41,0x78,0x0c,0x00,0x00, -0x01,0x00,0x13,0x3f,0x78,0x0c,0x00,0x00,0x01,0x00,0x14,0x3d,0x78,0x0c,0x00,0x00, -0x01,0x00,0x15,0x3b,0x78,0x0c,0x00,0x00,0x01,0x00,0x16,0x39,0x78,0x0c,0x00,0x00, -0x01,0x00,0x17,0x37,0x78,0x0c,0x00,0x00,0x01,0x00,0x18,0x35,0x78,0x0c,0x00,0x00, -0x01,0x00,0x19,0x33,0x78,0x0c,0x00,0x00,0x01,0x00,0x1a,0x31,0x78,0x0c,0x00,0x00, -0x01,0x00,0x1b,0x2f,0x78,0x0c,0x00,0x00,0x01,0x00,0x1c,0x2d,0x78,0x0c,0x00,0x00, -0x01,0x00,0x1d,0x2b,0x78,0x0c,0x00,0x00,0x01,0x00,0x1e,0x29,0x78,0x0c,0x00,0x00, -0x01,0x00,0x1f,0x27,0x78,0x0c,0x00,0x00,0x01,0x00,0x20,0x25,0x78,0x0c,0x00,0x00, -0x01,0x00,0x21,0x23,0x78,0x0c,0x00,0x00,0x01,0x00,0x22,0x21,0x78,0x0c,0x00,0x00, -0x01,0x00,0x23,0x1f,0x78,0x0c,0x00,0x00,0x01,0x00,0x24,0x1d,0x78,0x0c,0x00,0x00, -0x01,0x00,0x25,0x1b,0x78,0x0c,0x00,0x00,0x01,0x00,0x26,0x19,0x78,0x0c,0x00,0x00, -0x01,0x00,0x27,0x17,0x78,0x0c,0x00,0x00,0x01,0x00,0x28,0x15,0x78,0x0c,0x00,0x00, -0x01,0x00,0x29,0x13,0x78,0x0c,0x00,0x00,0x01,0x00,0x2a,0x11,0x78,0x0c,0x00,0x00, -0x01,0x00,0x2b,0x0f,0x78,0x0c,0x00,0x00,0x01,0x00,0x2c,0x0d,0x78,0x0c,0x00,0x00, -0x01,0x00,0x2d,0x0b,0x78,0x0c,0x00,0x00,0x01,0x00,0x2e,0x09,0x78,0x0c,0x00,0x00, -0x01,0x00,0x2f,0x07,0x78,0x0c,0x00,0x00,0x01,0x00,0x30,0x05,0x78,0x0c,0x00,0x00, -0x01,0x00,0x31,0x03,0x78,0x0c,0x00,0x00,0x01,0x00,0x32,0x01,0x78,0x0c,0x00,0x00, -0x01,0x00,0x33,0x01,0x78,0x0c,0x00,0x00,0x01,0x00,0x34,0x01,0x78,0x0c,0x00,0x00, -0x01,0x00,0x35,0x01,0x78,0x0c,0x00,0x00,0x01,0x00,0x36,0x01,0x78,0x0c,0x00,0x00, -0x01,0x00,0x37,0x01,0x78,0x0c,0x00,0x00,0x01,0x00,0x38,0x01,0x78,0x0c,0x00,0x00, -0x01,0x00,0x39,0x01,0x78,0x0c,0x00,0x00,0x01,0x00,0x3a,0x01,0x78,0x0c,0x00,0x00, -0x01,0x00,0x3b,0x01,0x78,0x0c,0x00,0x00,0x01,0x00,0x3c,0x01,0x78,0x0c,0x00,0x00, -0x01,0x00,0x3d,0x01,0x78,0x0c,0x00,0x00,0x01,0x00,0x3e,0x01,0x78,0x0c,0x00,0x00, -0x01,0x00,0x3f,0x01,0x78,0x0c,0x00,0x00,0x01,0x00,0x40,0x5e,0x78,0x0c,0x00,0x00, -0x01,0x00,0x41,0x5e,0x78,0x0c,0x00,0x00,0x01,0x00,0x42,0x5e,0x78,0x0c,0x00,0x00, -0x01,0x00,0x43,0x5e,0x78,0x0c,0x00,0x00,0x01,0x00,0x44,0x5d,0x78,0x0c,0x00,0x00, -0x01,0x00,0x45,0x5b,0x78,0x0c,0x00,0x00,0x01,0x00,0x46,0x59,0x78,0x0c,0x00,0x00, -0x01,0x00,0x47,0x57,0x78,0x0c,0x00,0x00,0x01,0x00,0x48,0x55,0x78,0x0c,0x00,0x00, -0x01,0x00,0x49,0x53,0x78,0x0c,0x00,0x00,0x01,0x00,0x4a,0x51,0x78,0x0c,0x00,0x00, -0x01,0x00,0x4b,0x4f,0x78,0x0c,0x00,0x00,0x01,0x00,0x4c,0x4d,0x78,0x0c,0x00,0x00, -0x01,0x00,0x4d,0x4b,0x78,0x0c,0x00,0x00,0x01,0x00,0x4e,0x49,0x78,0x0c,0x00,0x00, -0x01,0x00,0x4f,0x47,0x78,0x0c,0x00,0x00,0x01,0x00,0x50,0x45,0x78,0x0c,0x00,0x00, -0x01,0x00,0x51,0x43,0x78,0x0c,0x00,0x00,0x01,0x00,0x52,0x41,0x78,0x0c,0x00,0x00, -0x01,0x00,0x53,0x3f,0x78,0x0c,0x00,0x00,0x01,0x00,0x54,0x3d,0x78,0x0c,0x00,0x00, -0x01,0x00,0x55,0x3b,0x78,0x0c,0x00,0x00,0x01,0x00,0x56,0x39,0x78,0x0c,0x00,0x00, -0x01,0x00,0x57,0x37,0x78,0x0c,0x00,0x00,0x01,0x00,0x58,0x35,0x78,0x0c,0x00,0x00, -0x01,0x00,0x59,0x33,0x78,0x0c,0x00,0x00,0x01,0x00,0x5a,0x31,0x78,0x0c,0x00,0x00, -0x01,0x00,0x5b,0x2f,0x78,0x0c,0x00,0x00,0x01,0x00,0x5c,0x2d,0x78,0x0c,0x00,0x00, -0x01,0x00,0x5d,0x2b,0x78,0x0c,0x00,0x00,0x01,0x00,0x5e,0x29,0x78,0x0c,0x00,0x00, -0x01,0x00,0x5f,0x27,0x78,0x0c,0x00,0x00,0x01,0x00,0x60,0x25,0x78,0x0c,0x00,0x00, -0x01,0x00,0x61,0x23,0x78,0x0c,0x00,0x00,0x01,0x00,0x62,0x21,0x78,0x0c,0x00,0x00, -0x01,0x00,0x63,0x1f,0x78,0x0c,0x00,0x00,0x01,0x00,0x64,0x1d,0x78,0x0c,0x00,0x00, -0x01,0x00,0x65,0x1b,0x78,0x0c,0x00,0x00,0x01,0x00,0x66,0x19,0x78,0x0c,0x00,0x00, -0x01,0x00,0x67,0x17,0x78,0x0c,0x00,0x00,0x01,0x00,0x68,0x15,0x78,0x0c,0x00,0x00, -0x01,0x00,0x69,0x13,0x78,0x0c,0x00,0x00,0x01,0x00,0x6a,0x11,0x78,0x0c,0x00,0x00, -0x01,0x00,0x6b,0x0f,0x78,0x0c,0x00,0x00,0x01,0x00,0x6c,0x0d,0x78,0x0c,0x00,0x00, -0x01,0x00,0x6d,0x0b,0x78,0x0c,0x00,0x00,0x01,0x00,0x6e,0x09,0x78,0x0c,0x00,0x00, -0x01,0x00,0x6f,0x07,0x78,0x0c,0x00,0x00,0x01,0x00,0x70,0x05,0x78,0x0c,0x00,0x00, -0x01,0x00,0x71,0x03,0x78,0x0c,0x00,0x00,0x01,0x00,0x72,0x01,0x78,0x0c,0x00,0x00, -0x01,0x00,0x73,0x01,0x78,0x0c,0x00,0x00,0x01,0x00,0x74,0x01,0x78,0x0c,0x00,0x00, -0x01,0x00,0x75,0x01,0x78,0x0c,0x00,0x00,0x01,0x00,0x76,0x01,0x78,0x0c,0x00,0x00, -0x01,0x00,0x77,0x01,0x78,0x0c,0x00,0x00,0x01,0x00,0x78,0x01,0x78,0x0c,0x00,0x00, -0x01,0x00,0x79,0x01,0x78,0x0c,0x00,0x00,0x01,0x00,0x7a,0x01,0x78,0x0c,0x00,0x00, -0x01,0x00,0x7b,0x01,0x78,0x0c,0x00,0x00,0x01,0x00,0x7c,0x01,0x78,0x0c,0x00,0x00, -0x01,0x00,0x7d,0x01,0x78,0x0c,0x00,0x00,0x01,0x00,0x7e,0x01,0x78,0x0c,0x00,0x00, -0x01,0x00,0x7f,0x01,0x78,0x0c,0x00,0x00,0x1e,0x00,0x00,0x30,0x78,0x0c,0x00,0x00, -0x1e,0x00,0x01,0x30,0x78,0x0c,0x00,0x00,0x1e,0x00,0x02,0x30,0x78,0x0c,0x00,0x00, -0x1e,0x00,0x03,0x30,0x78,0x0c,0x00,0x00,0x1e,0x00,0x04,0x30,0x78,0x0c,0x00,0x00, -0x1e,0x00,0x05,0x30,0x78,0x0c,0x00,0x00,0x1e,0x00,0x06,0x30,0x78,0x0c,0x00,0x00, -0x1e,0x00,0x07,0x30,0x78,0x0c,0x00,0x00,0x1e,0x00,0x08,0x3e,0x78,0x0c,0x00,0x00, -0x1e,0x00,0x09,0x40,0x78,0x0c,0x00,0x00,0x1e,0x00,0x0a,0x42,0x78,0x0c,0x00,0x00, -0x1e,0x00,0x0b,0x44,0x78,0x0c,0x00,0x00,0x1e,0x00,0x0c,0x46,0x78,0x0c,0x00,0x00, -0x1e,0x00,0x0d,0x48,0x78,0x0c,0x00,0x00,0x1e,0x00,0x0e,0x48,0x78,0x0c,0x00,0x00, -0x1e,0x00,0x0f,0x4a,0x78,0x0c,0x00,0x00,0x1e,0x00,0x10,0x4a,0x78,0x0c,0x00,0x00, -0x1e,0x00,0x11,0x4c,0x78,0x0c,0x00,0x00,0x1e,0x00,0x12,0x4c,0x78,0x0c,0x00,0x00, -0x1e,0x00,0x13,0x4e,0x78,0x0c,0x00,0x00,0x1e,0x00,0x14,0x50,0x78,0x0c,0x00,0x00, -0x1e,0x00,0x15,0x50,0x78,0x0c,0x00,0x00,0x1e,0x00,0x16,0x50,0x78,0x0c,0x00,0x00, -0x1e,0x00,0x17,0x52,0x78,0x0c,0x00,0x00,0x1e,0x00,0x18,0x52,0x78,0x0c,0x00,0x00, -0x1e,0x00,0x19,0x52,0x78,0x0c,0x00,0x00,0x1e,0x00,0x1a,0x54,0x78,0x0c,0x00,0x00, -0x1e,0x00,0x1b,0x54,0x78,0x0c,0x00,0x00,0x1e,0x00,0x1c,0x54,0x78,0x0c,0x00,0x00, -0x1e,0x00,0x1d,0x56,0x78,0x0c,0x00,0x00,0x1e,0x00,0x1e,0x56,0x78,0x0c,0x00,0x00, -0x1e,0x00,0x1f,0x56,0x78,0x0c,0x00,0x00,0x1e,0x00,0x20,0x56,0x78,0x0c,0x00,0x00, -0x1e,0x00,0x21,0x58,0x78,0x0c,0x00,0x00,0x1e,0x00,0x22,0x58,0x78,0x0c,0x00,0x00, -0x1e,0x00,0x23,0x58,0x78,0x0c,0x00,0x00,0x1e,0x00,0x24,0x58,0x78,0x0c,0x00,0x00, -0x1e,0x00,0x25,0x5a,0x78,0x0c,0x00,0x00,0x1e,0x00,0x26,0x5a,0x78,0x0c,0x00,0x00, -0x1e,0x00,0x27,0x5a,0x78,0x0c,0x00,0x00,0x1e,0x00,0x28,0x5c,0x78,0x0c,0x00,0x00, -0x1e,0x00,0x29,0x5c,0x78,0x0c,0x00,0x00,0x1e,0x00,0x2a,0x5e,0x78,0x0c,0x00,0x00, -0x1e,0x00,0x2b,0x5e,0x78,0x0c,0x00,0x00,0x1e,0x00,0x2c,0x5e,0x78,0x0c,0x00,0x00, -0x1e,0x00,0x2d,0x5e,0x78,0x0c,0x00,0x00,0x1e,0x00,0x2e,0x5e,0x78,0x0c,0x00,0x00, -0x1e,0x00,0x2f,0x5e,0x78,0x0c,0x00,0x00,0x1e,0x00,0x30,0x5e,0x78,0x0c,0x00,0x00, -0x1e,0x00,0x31,0x5e,0x78,0x0c,0x00,0x00,0x1e,0x00,0x32,0x5e,0x78,0x0c,0x00,0x00, -0x1e,0x00,0x33,0x5e,0x78,0x0c,0x00,0x00,0x1e,0x00,0x34,0x5e,0x78,0x0c,0x00,0x00, -0x1e,0x00,0x35,0x5e,0x78,0x0c,0x00,0x00,0x1e,0x00,0x36,0x5e,0x78,0x0c,0x00,0x00, -0x1e,0x00,0x37,0x5e,0x78,0x0c,0x00,0x00,0x1e,0x00,0x38,0x5e,0x78,0x0c,0x00,0x00, -0x1e,0x00,0x39,0x5e,0x78,0x0c,0x00,0x00,0x1e,0x00,0x3a,0x5e,0x78,0x0c,0x00,0x00, -0x1e,0x00,0x3b,0x5e,0x78,0x0c,0x00,0x00,0x1e,0x00,0x3c,0x5e,0x78,0x0c,0x00,0x00, -0x1e,0x00,0x3d,0x5e,0x78,0x0c,0x00,0x00,0x1e,0x00,0x3e,0x5e,0x78,0x0c,0x00,0x00, -0x1e,0x00,0x3f,0x5e,0xff,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x08,0x00,0x00, -0x00,0x00,0x04,0x03,0x04,0x08,0x00,0x00,0x03,0x00,0x00,0x00,0x08,0x08,0x00,0x00, -0x00,0xfc,0x00,0x00,0x0c,0x08,0x00,0x00,0x0a,0x00,0x00,0x04,0x10,0x08,0x00,0x00, -0xff,0x10,0x10,0x80,0x14,0x08,0x00,0x00,0x10,0x3d,0x0c,0x02,0x18,0x08,0x00,0x00, -0xc5,0x03,0x00,0x00,0x1c,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x08,0x00,0x00, -0x04,0x00,0x00,0x00,0x24,0x08,0x00,0x00,0x00,0x02,0x69,0x00,0x28,0x08,0x00,0x00, -0x04,0x00,0x00,0x00,0x2c,0x08,0x00,0x00,0x00,0x02,0x69,0x00,0x30,0x08,0x00,0x00, -0x04,0x00,0x00,0x00,0x34,0x08,0x00,0x00,0x00,0x02,0x69,0x00,0x38,0x08,0x00,0x00, -0x04,0x00,0x00,0x00,0x3c,0x08,0x00,0x00,0x00,0x02,0x69,0x00,0x40,0x08,0x00,0x00, -0x00,0x00,0x00,0x00,0x44,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x00,0x00, -0x00,0x00,0x00,0x00,0x4c,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x08,0x00,0x00, -0x00,0x00,0x00,0x00,0x54,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x08,0x00,0x00, -0x65,0xa9,0x65,0xa9,0x5c,0x08,0x00,0x00,0x65,0xa9,0x65,0xa9,0x60,0x08,0x00,0x00, -0x30,0x01,0x7f,0x0f,0x64,0x08,0x00,0x00,0x30,0x01,0x7f,0x0f,0x68,0x08,0x00,0x00, -0x30,0x01,0x7f,0x0f,0x6c,0x08,0x00,0x00,0x30,0x01,0x7f,0x0f,0x70,0x08,0x00,0x00, -0x00,0x03,0x00,0x03,0x74,0x08,0x00,0x00,0x00,0x03,0x00,0x03,0x78,0x08,0x00,0x00, -0x00,0x00,0x00,0x00,0x7c,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x08,0x00,0x00, -0x00,0x00,0x00,0x00,0x94,0x08,0x00,0x00,0xfe,0xff,0xff,0xff,0x98,0x08,0x00,0x00, -0x10,0x20,0x30,0x40,0x9c,0x08,0x00,0x00,0x50,0x60,0x70,0x00,0xb0,0x08,0x00,0x00, -0x00,0x00,0x00,0x00,0xe0,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0xe4,0x08,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x0e,0x00,0x00,0x03,0x03,0x03,0x03,0x04,0x0e,0x00,0x00, -0x03,0x03,0x03,0x03,0x08,0x0e,0x00,0x00,0x03,0x03,0x00,0x00,0x0c,0x0e,0x00,0x00, -0x00,0x00,0x00,0x00,0x10,0x0e,0x00,0x00,0x03,0x03,0x03,0x03,0x14,0x0e,0x00,0x00, -0x03,0x03,0x03,0x03,0x18,0x0e,0x00,0x00,0x03,0x03,0x03,0x03,0x1c,0x0e,0x00,0x00, -0x03,0x03,0x03,0x03,0x00,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x09,0x00,0x00, -0x23,0x00,0x00,0x00,0x08,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x09,0x00,0x00, -0x33,0x13,0x32,0x03,0x08,0x0a,0x00,0x00,0x00,0x86,0x88,0x8f,0x2c,0x0a,0x00,0x00, -0x00,0x00,0x92,0x00,0x00,0x0c,0x00,0x00,0x80,0x00,0x00,0x00,0x04,0x0c,0x00,0x00, -0x33,0x54,0x00,0x00,0x08,0x0c,0x00,0x00,0xe4,0x00,0x00,0x00,0x0c,0x0c,0x00,0x00, -0x6c,0x6c,0x6c,0x6c,0x10,0x0c,0x00,0x00,0x00,0x00,0x00,0x08,0x14,0x0c,0x00,0x00, -0x00,0x01,0x00,0x40,0x18,0x0c,0x00,0x00,0x00,0x00,0x00,0x08,0x1c,0x0c,0x00,0x00, -0x00,0x01,0x00,0x40,0x20,0x0c,0x00,0x00,0x00,0x00,0x00,0x08,0x24,0x0c,0x00,0x00, -0x00,0x01,0x00,0x40,0x28,0x0c,0x00,0x00,0x00,0x00,0x00,0x08,0x2c,0x0c,0x00,0x00, -0x00,0x01,0x00,0x40,0x30,0x0c,0x00,0x00,0x44,0x6a,0xe9,0x8d,0x34,0x0c,0x00,0x00, -0xcd,0x52,0x96,0x46,0x38,0x0c,0x00,0x00,0x90,0x5a,0x01,0x48,0x3c,0x0c,0x00,0x00, -0x64,0x97,0x97,0x1a,0x40,0x0c,0x00,0x00,0x3f,0x42,0x7c,0x1f,0x44,0x0c,0x00,0x00, -0xb7,0x00,0x01,0x00,0x48,0x0c,0x00,0x00,0x00,0x00,0x02,0xec,0x4c,0x0c,0x00,0x00, -0x03,0x03,0xfc,0x00,0x50,0x0c,0x00,0x00,0x1c,0x34,0x54,0x69,0x54,0x0c,0x00,0x00, -0x94,0x00,0x3c,0x43,0x58,0x0c,0x00,0x00,0x1c,0x34,0x54,0x69,0x5c,0x0c,0x00,0x00, -0x94,0x00,0x3c,0x43,0x60,0x0c,0x00,0x00,0x1c,0x34,0x54,0x69,0x64,0x0c,0x00,0x00, -0x94,0x00,0x3c,0x43,0x68,0x0c,0x00,0x00,0x1c,0x34,0x54,0x69,0x6c,0x0c,0x00,0x00, -0x94,0x00,0x3c,0x43,0x70,0x0c,0x00,0x00,0x0d,0x00,0x5a,0x2c,0x74,0x0c,0x00,0x00, -0x1b,0x15,0x86,0x01,0x78,0x0c,0x00,0x00,0x1f,0x00,0x00,0x00,0x7c,0x0c,0x00,0x00, -0x12,0x16,0xb9,0x00,0x80,0x0c,0x00,0x00,0x80,0x00,0x00,0x20,0x84,0x0c,0x00,0x00, -0x00,0x00,0x00,0x00,0x88,0x0c,0x00,0x00,0x80,0x00,0x00,0x20,0x8c,0x0c,0x00,0x00, -0x00,0x00,0x20,0x08,0x90,0x0c,0x00,0x00,0x00,0x01,0x00,0x40,0x94,0x0c,0x00,0x00, -0x00,0x00,0x00,0x00,0x98,0x0c,0x00,0x00,0x00,0x01,0x00,0x40,0x9c,0x0c,0x00,0x00, -0x00,0x00,0x00,0x00,0xa0,0x0c,0x00,0x00,0x92,0x24,0x49,0x00,0xa4,0x0c,0x00,0x00, -0x00,0x00,0x00,0x00,0xa8,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0xac,0x0c,0x00,0x00, -0x00,0x00,0x00,0x00,0xb0,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0xb4,0x0c,0x00,0x00, -0x00,0x00,0x00,0x00,0xb8,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0xbc,0x0c,0x00,0x00, -0x92,0x24,0x49,0x00,0xc0,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0xc4,0x0c,0x00,0x00, -0x00,0x00,0x00,0x00,0xc8,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0xcc,0x0c,0x00,0x00, -0x00,0x00,0x00,0x00,0xd0,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0xd4,0x0c,0x00,0x00, -0x00,0x00,0x00,0x00,0xd8,0x0c,0x00,0x00,0x27,0x24,0xb2,0x64,0xdc,0x0c,0x00,0x00, -0x32,0x69,0x76,0x00,0xe0,0x0c,0x00,0x00,0x22,0x22,0x22,0x00,0xe4,0x0c,0x00,0x00, -0x00,0x00,0x00,0x00,0xe8,0x0c,0x00,0x00,0x02,0x43,0x64,0x07,0x00,0x0d,0x00,0x00, -0x80,0x07,0x00,0x00,0x04,0x0d,0x00,0x00,0x03,0x04,0x00,0x00,0x08,0x0d,0x00,0x00, -0x7f,0x90,0x00,0x00,0x0c,0x0d,0x00,0x00,0x01,0x00,0x00,0x00,0x10,0x0d,0x00,0x00, -0x99,0x99,0x69,0xa0,0x14,0x0d,0x00,0x00,0x67,0x3c,0x99,0x99,0x18,0x0d,0x00,0x00, -0x6b,0x5b,0x8f,0x6a,0x1c,0x0d,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x0d,0x00,0x00, -0x00,0x00,0x00,0x00,0x24,0x0d,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x0d,0x00,0x00, -0x00,0x00,0x00,0x00,0x2c,0x0d,0x00,0x00,0x75,0x19,0x97,0xcc,0x30,0x0d,0x00,0x00, -0x00,0x00,0x00,0x00,0x34,0x0d,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x0d,0x00,0x00, -0x00,0x00,0x00,0x00,0x3c,0x0d,0x00,0x00,0x93,0x72,0x02,0x00,0x40,0x0d,0x00,0x00, -0x00,0x00,0x00,0x00,0x44,0x0d,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x0d,0x00,0x00, -0x00,0x00,0x00,0x00,0x50,0x0d,0x00,0x00,0x0a,0x14,0x37,0x64,0x54,0x0d,0x00,0x00, -0x02,0xbd,0x4d,0x02,0x58,0x0d,0x00,0x00,0x00,0x00,0x00,0x00,0x5c,0x0d,0x00,0x00, -0x64,0x20,0x03,0x30,0x60,0x0d,0x00,0x00,0x68,0xde,0x53,0x46,0x64,0x0d,0x00,0x00, -0x3c,0x8a,0x51,0x00,0x68,0x0d,0x00,0x00,0x06,0x01,0x00,0x00,0xff,0x00,0x00,0x00, -0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00, -0x44,0x05,0x01,0x80,0x10,0x00,0x00,0x00,0x74,0x05,0x01,0x80,0x10,0x00,0x00,0x00, -0xe0,0x2e,0x00,0x80,0x10,0x00,0x00,0x00,0xec,0x2e,0x00,0x80,0x10,0x00,0x00,0x00, -0xa0,0x08,0x01,0x80,0x08,0x00,0x00,0x00,0x38,0x06,0x01,0x80,0x00,0xb7,0x00,0x00, -0x01,0xe0,0x0e,0x00,0x02,0x4d,0x04,0x00,0x03,0x41,0x04,0x00,0x04,0xc3,0x08,0x00, -0x05,0x72,0x0c,0x00,0x06,0xe6,0x00,0x00,0x07,0x2a,0x08,0x00,0x08,0x3f,0x00,0x00, -0x09,0x35,0x03,0x00,0x0a,0xd4,0x09,0x00,0x0b,0xbb,0x07,0x00,0x0c,0x50,0x08,0x00, -0x0d,0xdf,0x0c,0x00,0x0e,0x2b,0x00,0x00,0x0f,0x14,0x01,0x00,0x00,0xb7,0x01,0x00, -0x01,0x01,0x00,0x00,0x02,0x00,0x04,0x00,0x01,0x02,0x00,0x00,0x02,0x01,0x04,0x00, -0x01,0x03,0x00,0x00,0x02,0x02,0x04,0x00,0x01,0x04,0x00,0x00,0x02,0x03,0x04,0x00, -0x01,0x05,0x00,0x00,0x02,0x04,0x04,0x00,0x01,0x06,0x00,0x00,0x02,0x05,0x04,0x00, -0x01,0x07,0x00,0x00,0x02,0x08,0x04,0x00,0x01,0x08,0x00,0x00,0x02,0x09,0x04,0x00, -0x01,0x09,0x00,0x00,0x02,0x0a,0x04,0x00,0x01,0x0a,0x00,0x00,0x02,0x0b,0x04,0x00, -0x01,0x0b,0x00,0x00,0x02,0x02,0x05,0x00,0x01,0x0c,0x00,0x00,0x02,0x03,0x05,0x00, -0x01,0x0d,0x00,0x00,0x02,0x04,0x05,0x00,0x01,0x0e,0x00,0x00,0x02,0x05,0x05,0x00, -0x01,0x0f,0x00,0x00,0x02,0x40,0x05,0x00,0x01,0x10,0x00,0x00,0x02,0x41,0x05,0x00, -0x01,0x11,0x00,0x00,0x02,0x42,0x05,0x00,0x01,0x12,0x00,0x00,0x02,0x43,0x05,0x00, -0x01,0x13,0x00,0x00,0x02,0x44,0x05,0x00,0x01,0x14,0x00,0x00,0x02,0x45,0x05,0x00, -0x01,0x15,0x00,0x00,0x02,0x80,0x05,0x00,0x01,0x16,0x00,0x00,0x02,0x81,0x05,0x00, -0x01,0x17,0x00,0x00,0x02,0x82,0x05,0x00,0x01,0x18,0x00,0x00,0x02,0x83,0x05,0x00, -0x01,0x19,0x00,0x00,0x02,0x84,0x05,0x00,0x01,0x1a,0x00,0x00,0x02,0x85,0x05,0x00, -0x01,0x1b,0x00,0x00,0x02,0x88,0x05,0x00,0x01,0x1c,0x00,0x00,0x02,0x89,0x05,0x00, -0x01,0x1d,0x00,0x00,0x02,0x8a,0x05,0x00,0x01,0x1e,0x00,0x00,0x02,0x8b,0x05,0x00, -0x01,0x1f,0x00,0x00,0x02,0x43,0x06,0x00,0x01,0x20,0x00,0x00,0x02,0x44,0x06,0x00, -0x01,0x21,0x00,0x00,0x02,0x45,0x06,0x00,0x01,0x22,0x00,0x00,0x02,0x80,0x06,0x00, -0x01,0x23,0x00,0x00,0x02,0x81,0x06,0x00,0x01,0x24,0x00,0x00,0x02,0x82,0x06,0x00, -0x01,0x25,0x00,0x00,0x02,0x83,0x06,0x00,0x01,0x26,0x00,0x00,0x02,0x84,0x06,0x00, -0x01,0x27,0x00,0x00,0x02,0x85,0x06,0x00,0x01,0x28,0x00,0x00,0x02,0x88,0x06,0x00, -0x01,0x29,0x00,0x00,0x02,0x89,0x06,0x00,0x01,0x2a,0x00,0x00,0x02,0x8a,0x06,0x00, -0x01,0x2b,0x00,0x00,0x02,0x8b,0x06,0x00,0x01,0x2c,0x00,0x00,0x02,0x8c,0x06,0x00, -0x01,0x2d,0x00,0x00,0x02,0x42,0x07,0x00,0x01,0x2e,0x00,0x00,0x02,0x43,0x07,0x00, -0x01,0x2f,0x00,0x00,0x02,0x44,0x07,0x00,0x01,0x30,0x00,0x00,0x02,0x45,0x07,0x00, -0x01,0x31,0x00,0x00,0x02,0x80,0x07,0x00,0x01,0x32,0x00,0x00,0x02,0x81,0x07,0x00, -0x01,0x33,0x00,0x00,0x02,0x82,0x07,0x00,0x01,0x34,0x00,0x00,0x02,0x83,0x07,0x00, -0x01,0x35,0x00,0x00,0x02,0x84,0x07,0x00,0x01,0x36,0x00,0x00,0x02,0x85,0x07,0x00, -0x01,0x37,0x00,0x00,0x02,0x88,0x07,0x00,0x01,0x38,0x00,0x00,0x02,0x89,0x07,0x00, -0x01,0x39,0x00,0x00,0x02,0x8a,0x07,0x00,0x01,0x3a,0x00,0x00,0x02,0x8b,0x07,0x00, -0x01,0x3b,0x00,0x00,0x02,0x8c,0x07,0x00,0x01,0x3c,0x00,0x00,0x02,0x8d,0x07,0x00, -0x01,0x3d,0x00,0x00,0x02,0x90,0x07,0x00,0x01,0x3e,0x00,0x00,0x02,0x91,0x07,0x00, -0x01,0x3f,0x00,0x00,0x02,0x92,0x07,0x00,0x01,0x40,0x00,0x00,0x02,0x93,0x07,0x00, -0x01,0x41,0x00,0x00,0x02,0x94,0x07,0x00,0x01,0x42,0x00,0x00,0x02,0x95,0x07,0x00, -0x01,0x43,0x00,0x00,0x02,0x98,0x07,0x00,0x01,0x44,0x00,0x00,0x02,0x99,0x07,0x00, -0x01,0x45,0x00,0x00,0x02,0x9a,0x07,0x00,0x01,0x46,0x00,0x00,0x02,0x9b,0x07,0x00, -0x01,0x47,0x00,0x00,0x02,0x9c,0x07,0x00,0x01,0x48,0x00,0x00,0x02,0x9d,0x07,0x00, -0x01,0x49,0x00,0x00,0x02,0xa0,0x07,0x00,0x01,0x4a,0x00,0x00,0x02,0xa1,0x07,0x00, -0x01,0x4b,0x00,0x00,0x02,0xa2,0x07,0x00,0x01,0x4c,0x00,0x00,0x02,0xa3,0x07,0x00, -0x01,0x4d,0x00,0x00,0x02,0xa4,0x07,0x00,0x01,0x4e,0x00,0x00,0x02,0xa5,0x07,0x00, -0x01,0x4f,0x00,0x00,0x02,0xa8,0x07,0x00,0x01,0x50,0x00,0x00,0x02,0xa9,0x07,0x00, -0x01,0x51,0x00,0x00,0x02,0xaa,0x03,0x00,0x01,0x52,0x00,0x00,0x02,0xab,0x03,0x00, -0x01,0x53,0x00,0x00,0x02,0xac,0x03,0x00,0x01,0x54,0x00,0x00,0x02,0xad,0x03,0x00, -0x01,0x55,0x00,0x00,0x02,0xb0,0x03,0x00,0x01,0x56,0x00,0x00,0x02,0xb1,0x03,0x00, -0x01,0x57,0x00,0x00,0x02,0xb2,0x03,0x00,0x01,0x58,0x00,0x00,0x02,0xb3,0x03,0x00, -0x01,0x59,0x00,0x00,0x02,0xb4,0x03,0x00,0x01,0x5a,0x00,0x00,0x02,0xb5,0x03,0x00, -0x01,0x5b,0x00,0x00,0x02,0xb8,0x03,0x00,0x01,0x5c,0x00,0x00,0x02,0xb9,0x03,0x00, -0x01,0x5d,0x00,0x00,0x02,0xba,0x03,0x00,0x01,0x5e,0x00,0x00,0x02,0xbb,0x03,0x00, -0x01,0x5f,0x00,0x00,0x02,0xbb,0x03,0x00,0x03,0x80,0x00,0x00,0x05,0x04,0x00,0x00, -0x00,0xb7,0x00,0x00,0xfe,0x00,0x00,0x00,0xfe,0x00,0x00,0x00,0xfe,0x00,0x00,0x00, -0x02,0x4d,0x0c,0x00,0xfe,0x00,0x00,0x00,0xfe,0x00,0x00,0x00,0x02,0x4d,0x04,0x00, -0x00,0xbf,0x02,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0xb7,0x00,0x00, -0x01,0xe0,0x0e,0x00,0x02,0x4d,0x04,0x00,0x03,0x41,0x04,0x00,0x04,0xc3,0x08,0x00, -0x05,0x72,0x0c,0x00,0x06,0xe6,0x00,0x00,0x07,0x2a,0x08,0x00,0x08,0x3f,0x00,0x00, -0x09,0x35,0x03,0x00,0x0a,0xd4,0x09,0x00,0x0b,0xbb,0x07,0x00,0x0c,0x50,0x08,0x00, -0x0d,0xdf,0x0c,0x00,0x0e,0x2b,0x00,0x00,0x0f,0x14,0x01,0x00,0x00,0xb7,0x01,0x00, -0x01,0x01,0x00,0x00,0x02,0x00,0x04,0x00,0x01,0x02,0x00,0x00,0x02,0x01,0x04,0x00, -0x01,0x03,0x00,0x00,0x02,0x02,0x04,0x00,0x01,0x04,0x00,0x00,0x02,0x03,0x04,0x00, -0x01,0x05,0x00,0x00,0x02,0x04,0x04,0x00,0x01,0x06,0x00,0x00,0x02,0x05,0x04,0x00, -0x01,0x07,0x00,0x00,0x02,0x08,0x04,0x00,0x01,0x08,0x00,0x00,0x02,0x09,0x04,0x00, -0x01,0x09,0x00,0x00,0x02,0x0a,0x04,0x00,0x01,0x0a,0x00,0x00,0x02,0x0b,0x04,0x00, -0x01,0x0b,0x00,0x00,0x02,0x02,0x05,0x00,0x01,0x0c,0x00,0x00,0x02,0x03,0x05,0x00, -0x01,0x0d,0x00,0x00,0x02,0x04,0x05,0x00,0x01,0x0e,0x00,0x00,0x02,0x05,0x05,0x00, -0x01,0x0f,0x00,0x00,0x02,0x40,0x05,0x00,0x01,0x10,0x00,0x00,0x02,0x41,0x05,0x00, -0x01,0x11,0x00,0x00,0x02,0x42,0x05,0x00,0x01,0x12,0x00,0x00,0x02,0x43,0x05,0x00, -0x01,0x13,0x00,0x00,0x02,0x44,0x05,0x00,0x01,0x14,0x00,0x00,0x02,0x45,0x05,0x00, -0x01,0x15,0x00,0x00,0x02,0x80,0x05,0x00,0x01,0x16,0x00,0x00,0x02,0x81,0x05,0x00, -0x01,0x17,0x00,0x00,0x02,0x82,0x05,0x00,0x01,0x18,0x00,0x00,0x02,0x83,0x05,0x00, -0x01,0x19,0x00,0x00,0x02,0x84,0x05,0x00,0x01,0x1a,0x00,0x00,0x02,0x85,0x05,0x00, -0x01,0x1b,0x00,0x00,0x02,0x88,0x05,0x00,0x01,0x1c,0x00,0x00,0x02,0x89,0x05,0x00, -0x01,0x1d,0x00,0x00,0x02,0x8a,0x05,0x00,0x01,0x1e,0x00,0x00,0x02,0x8b,0x05,0x00, -0x01,0x1f,0x00,0x00,0x02,0x43,0x06,0x00,0x01,0x20,0x00,0x00,0x02,0x44,0x06,0x00, -0x01,0x21,0x00,0x00,0x02,0x45,0x06,0x00,0x01,0x22,0x00,0x00,0x02,0x80,0x06,0x00, -0x01,0x23,0x00,0x00,0x02,0x81,0x06,0x00,0x01,0x24,0x00,0x00,0x02,0x82,0x06,0x00, -0x01,0x25,0x00,0x00,0x02,0x83,0x06,0x00,0x01,0x26,0x00,0x00,0x02,0x84,0x06,0x00, -0x01,0x27,0x00,0x00,0x02,0x85,0x06,0x00,0x01,0x28,0x00,0x00,0x02,0x88,0x06,0x00, -0x01,0x29,0x00,0x00,0x02,0x89,0x06,0x00,0x01,0x2a,0x00,0x00,0x02,0x8a,0x06,0x00, -0x01,0x2b,0x00,0x00,0x02,0x8b,0x06,0x00,0x01,0x2c,0x00,0x00,0x02,0x8c,0x06,0x00, -0x01,0x2d,0x00,0x00,0x02,0x42,0x07,0x00,0x01,0x2e,0x00,0x00,0x02,0x43,0x07,0x00, -0x01,0x2f,0x00,0x00,0x02,0x44,0x07,0x00,0x01,0x30,0x00,0x00,0x02,0x45,0x07,0x00, -0x01,0x31,0x00,0x00,0x02,0x80,0x07,0x00,0x01,0x32,0x00,0x00,0x02,0x81,0x07,0x00, -0x01,0x33,0x00,0x00,0x02,0x82,0x07,0x00,0x01,0x34,0x00,0x00,0x02,0x83,0x07,0x00, -0x01,0x35,0x00,0x00,0x02,0x84,0x07,0x00,0x01,0x36,0x00,0x00,0x02,0x85,0x07,0x00, -0x01,0x37,0x00,0x00,0x02,0x88,0x07,0x00,0x01,0x38,0x00,0x00,0x02,0x89,0x07,0x00, -0x01,0x39,0x00,0x00,0x02,0x8a,0x07,0x00,0x01,0x3a,0x00,0x00,0x02,0x8b,0x07,0x00, -0x01,0x3b,0x00,0x00,0x02,0x8c,0x07,0x00,0x01,0x3c,0x00,0x00,0x02,0x8d,0x07,0x00, -0x01,0x3d,0x00,0x00,0x02,0x90,0x07,0x00,0x01,0x3e,0x00,0x00,0x02,0x91,0x07,0x00, -0x01,0x3f,0x00,0x00,0x02,0x92,0x07,0x00,0x01,0x40,0x00,0x00,0x02,0x93,0x07,0x00, -0x01,0x41,0x00,0x00,0x02,0x94,0x07,0x00,0x01,0x42,0x00,0x00,0x02,0x95,0x07,0x00, -0x01,0x43,0x00,0x00,0x02,0x98,0x07,0x00,0x01,0x44,0x00,0x00,0x02,0x99,0x07,0x00, -0x01,0x45,0x00,0x00,0x02,0x9a,0x07,0x00,0x01,0x46,0x00,0x00,0x02,0x9b,0x07,0x00, -0x01,0x47,0x00,0x00,0x02,0x9c,0x07,0x00,0x01,0x48,0x00,0x00,0x02,0x9d,0x07,0x00, -0x01,0x49,0x00,0x00,0x02,0xa0,0x07,0x00,0x01,0x4a,0x00,0x00,0x02,0xa1,0x07,0x00, -0x01,0x4b,0x00,0x00,0x02,0xa2,0x07,0x00,0x01,0x4c,0x00,0x00,0x02,0xa3,0x07,0x00, -0x01,0x4d,0x00,0x00,0x02,0xa4,0x07,0x00,0x01,0x4e,0x00,0x00,0x02,0xa5,0x07,0x00, -0x01,0x4f,0x00,0x00,0x02,0xa8,0x07,0x00,0x01,0x50,0x00,0x00,0x02,0xa9,0x07,0x00, -0x01,0x51,0x00,0x00,0x02,0xaa,0x03,0x00,0x01,0x52,0x00,0x00,0x02,0xab,0x03,0x00, -0x01,0x53,0x00,0x00,0x02,0xac,0x03,0x00,0x01,0x54,0x00,0x00,0x02,0xad,0x03,0x00, -0x01,0x55,0x00,0x00,0x02,0xb0,0x03,0x00,0x01,0x56,0x00,0x00,0x02,0xb1,0x03,0x00, -0x01,0x57,0x00,0x00,0x02,0xb2,0x03,0x00,0x01,0x58,0x00,0x00,0x02,0xb3,0x03,0x00, -0x01,0x59,0x00,0x00,0x02,0xb4,0x03,0x00,0x01,0x5a,0x00,0x00,0x02,0xb5,0x03,0x00, -0x01,0x5b,0x00,0x00,0x02,0xb8,0x03,0x00,0x01,0x5c,0x00,0x00,0x02,0xb9,0x03,0x00, -0x01,0x5d,0x00,0x00,0x02,0xba,0x03,0x00,0x01,0x5e,0x00,0x00,0x02,0xbb,0x03,0x00, -0x01,0x5f,0x00,0x00,0x02,0xbb,0x03,0x00,0x03,0x80,0x00,0x00,0x05,0x04,0x00,0x00, -0x00,0xb7,0x00,0x00,0xfe,0x00,0x00,0x00,0xfe,0x00,0x00,0x00,0xfe,0x00,0x00,0x00, -0x02,0x4d,0x0c,0x00,0xfe,0x00,0x00,0x00,0xfe,0x00,0x00,0x00,0x02,0x4d,0x04,0x00, -0x00,0xbf,0x02,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x0a,0x00,0x00,0x00, -0x4f,0x6e,0x41,0x73,0x73,0x6f,0x63,0x52,0x65,0x71,0x00,0x00,0x4f,0x6e,0x41,0x73, -0x73,0x6f,0x63,0x52,0x73,0x70,0x00,0x00,0x4f,0x6e,0x52,0x65,0x41,0x73,0x73,0x6f, -0x63,0x52,0x65,0x71,0x00,0x00,0x00,0x00,0x4f,0x6e,0x52,0x65,0x41,0x73,0x73,0x6f, -0x63,0x52,0x73,0x70,0x00,0x00,0x00,0x00,0x4f,0x6e,0x50,0x72,0x6f,0x62,0x65,0x52, -0x65,0x71,0x00,0x00,0x4f,0x6e,0x50,0x72,0x6f,0x62,0x65,0x52,0x73,0x70,0x00,0x00, -0x44,0x6f,0x52,0x65,0x73,0x65,0x72,0x76,0x65,0x64,0x00,0x00,0x44,0x6f,0x52,0x65, -0x73,0x65,0x72,0x76,0x65,0x64,0x00,0x00,0x4f,0x6e,0x42,0x65,0x61,0x63,0x6f,0x6e, -0x00,0x00,0x00,0x00,0x4f,0x6e,0x41,0x54,0x49,0x4d,0x00,0x00,0x4f,0x6e,0x44,0x69, -0x73,0x61,0x73,0x73,0x6f,0x63,0x00,0x00,0x4f,0x6e,0x41,0x75,0x74,0x68,0x00,0x00, -0x4f,0x6e,0x44,0x65,0x41,0x75,0x74,0x68,0x00,0x00,0x00,0x00,0x4f,0x6e,0x41,0x63, -0x74,0x69,0x6f,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x8b,0x01,0x80, -0x28,0x14,0x01,0x80,0x10,0x00,0x00,0x00,0x94,0x8b,0x01,0x80,0x30,0x14,0x01,0x80, -0x20,0x00,0x00,0x00,0xa0,0x8b,0x01,0x80,0x28,0x14,0x01,0x80,0x30,0x00,0x00,0x00, -0xb0,0x8b,0x01,0x80,0x30,0x14,0x01,0x80,0x40,0x00,0x00,0x00,0xc0,0x8b,0x01,0x80, -0x38,0x14,0x01,0x80,0x50,0x00,0x00,0x00,0xcc,0x8b,0x01,0x80,0x40,0x14,0x01,0x80, -0x00,0x00,0x00,0x00,0xd8,0x8b,0x01,0x80,0xa8,0x14,0x01,0x80,0x00,0x00,0x00,0x00, -0xe4,0x8b,0x01,0x80,0xa8,0x14,0x01,0x80,0x80,0x00,0x00,0x00,0xf0,0x8b,0x01,0x80, -0x48,0x14,0x01,0x80,0x90,0x00,0x00,0x00,0xfc,0x8b,0x01,0x80,0x50,0x14,0x01,0x80, -0xa0,0x00,0x00,0x00,0x04,0x8c,0x01,0x80,0x58,0x14,0x01,0x80,0xb0,0x00,0x00,0x00, -0x10,0x8c,0x01,0x80,0x90,0x14,0x01,0x80,0xc0,0x00,0x00,0x00,0x18,0x8c,0x01,0x80, -0x98,0x14,0x01,0x80,0xd0,0x00,0x00,0x00,0x24,0x8c,0x01,0x80,0xa0,0x14,0x01,0x80, -0x00,0x00,0x00,0x00,0xdc,0x8c,0x01,0x80,0xdc,0x8c,0x01,0x80,0x31,0x10,0x10,0x00, -0x00,0x30,0x00,0x00,0x31,0x20,0x10,0x00,0x00,0x30,0x00,0x00,0x31,0x28,0x10,0x00, -0x00,0x30,0x00,0x00,0x31,0x2c,0x10,0x10,0x00,0x30,0x00,0x00,0x31,0x2f,0x10,0x10, -0x00,0x30,0x00,0x00,0x31,0x30,0x18,0x00,0x00,0x30,0x00,0x00,0x31,0x30,0x20,0x10, -0x00,0x30,0x00,0x00,0x22,0x20,0x18,0x08,0x00,0x20,0x00,0x00,0x22,0x21,0x14,0x08, -0x00,0x20,0x00,0x00,0x22,0x21,0x1c,0x08,0x00,0x20,0x00,0x00,0x22,0x21,0x20,0x08, -0x00,0x20,0x00,0x00,0x22,0x21,0x20,0x10,0x00,0x20,0x00,0x00,0x22,0x21,0x20,0x18, -0x00,0x20,0x00,0x00,0x1a,0x19,0x18,0x10,0x00,0x18,0x00,0x00,0x12,0x11,0x10,0x08, -0x00,0x10,0x00,0x00,0x0a,0x09,0x08,0x00,0x00,0x08,0x00,0x00,0x0a,0x09,0x08,0x02, -0x00,0x08,0x00,0x00,0x0a,0x09,0x08,0x04,0x00,0x08,0x00,0x00,0x0a,0x09,0x08,0x06, -0x00,0x08,0x00,0x00,0x08,0x07,0x06,0x04,0x00,0x06,0x00,0x00,0x06,0x05,0x04,0x02, -0x00,0x04,0x00,0x00,0x06,0x05,0x04,0x03,0x00,0x04,0x00,0x00,0x05,0x04,0x03,0x02, -0x00,0x03,0x00,0x00,0x09,0x08,0x07,0x06,0x07,0x06,0x06,0x05,0x05,0x04,0x04,0x03, -0x06,0x05,0x05,0x04,0x04,0x03,0x03,0x03,0x05,0x04,0x04,0x03,0x03,0x02,0x02,0x02, -0x00,0x09,0x08,0x07,0x06,0x07,0x06,0x06,0x05,0x05,0x04,0x04,0x03,0x05,0x04,0x04, -0x03,0x03,0x02,0x02,0x02,0x04,0x03,0x03,0x02,0x02,0x01,0x01,0x01,0x00,0x00,0x00, -0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x10,0x10,0x20,0x08,0x08,0x08,0x08, -0x20,0x20,0x20,0x20,0x08,0x08,0x08,0x08,0x08,0x20,0x20,0x20,0x30,0x08,0x08,0x08, -0x08,0x18,0x18,0x18,0x18,0x18,0x20,0x30,0x30,0x10,0x20,0x20,0x20,0x20,0x20,0x30, -0x30,0x08,0x10,0x20,0x30,0x30,0x30,0x30,0x30,0x30,0x00,0x00,0x08,0x08,0x08,0x08, -0x08,0x08,0x08,0x08,0x08,0x10,0x10,0x20,0x08,0x08,0x08,0x08,0x08,0x20,0x20,0x20, -0x08,0x08,0x08,0x08,0x08,0x20,0x20,0x20,0x20,0x08,0x08,0x08,0x08,0x18,0x18,0x18, -0x18,0x18,0x20,0x30,0x30,0x10,0x20,0x20,0x20,0x20,0x20,0x30,0x30,0x08,0x10,0x20, -0x30,0x30,0x30,0x30,0x30,0x30,0x00,0x00,0x0a,0x09,0x08,0x04,0x00,0x0a,0x09,0x08, -0x04,0x00,0x0a,0x09,0x08,0x04,0x00,0x0a,0x09,0x08,0x04,0x00,0x0a,0x09,0x08,0x00, -0x00,0x0a,0x09,0x08,0x00,0x00,0x0a,0x09,0x08,0x00,0x00,0x0a,0x09,0x08,0x00,0x00, -0x0a,0x09,0x08,0x00,0x00,0x12,0x11,0x10,0x08,0x00,0x12,0x11,0x10,0x08,0x00,0x22, -0x21,0x20,0x18,0x00,0x0a,0x09,0x08,0x00,0x00,0x0a,0x09,0x08,0x00,0x00,0x0a,0x09, -0x08,0x00,0x00,0x0a,0x09,0x08,0x00,0x00,0x22,0x21,0x20,0x18,0x00,0x22,0x21,0x20, -0x18,0x00,0x22,0x21,0x1c,0x08,0x00,0x22,0x20,0x18,0x08,0x00,0x0a,0x09,0x08,0x02, -0x00,0x0a,0x09,0x08,0x02,0x00,0x0a,0x09,0x08,0x02,0x00,0x0a,0x09,0x08,0x02,0x00, -0x0a,0x09,0x08,0x00,0x00,0x22,0x21,0x20,0x10,0x00,0x22,0x21,0x20,0x08,0x00,0x22, -0x21,0x1c,0x08,0x00,0x31,0x30,0x18,0x00,0x00,0x0a,0x09,0x08,0x04,0x00,0x0a,0x09, -0x08,0x04,0x00,0x0a,0x09,0x08,0x04,0x00,0x0a,0x09,0x08,0x04,0x00,0x1a,0x19,0x18, -0x10,0x00,0x1a,0x19,0x18,0x10,0x00,0x1a,0x19,0x18,0x10,0x00,0x1a,0x19,0x18,0x10, -0x00,0x1a,0x19,0x18,0x10,0x00,0x22,0x21,0x20,0x08,0x00,0x31,0x2c,0x10,0x10,0x00, -0x31,0x28,0x10,0x00,0x00,0x12,0x11,0x10,0x08,0x00,0x22,0x21,0x20,0x18,0x00,0x22, -0x21,0x20,0x18,0x00,0x22,0x21,0x20,0x08,0x00,0x22,0x21,0x14,0x08,0x00,0x22,0x20, -0x18,0x08,0x00,0x31,0x30,0x20,0x10,0x00,0x31,0x2c,0x10,0x10,0x00,0x0a,0x09,0x08, -0x00,0x00,0x12,0x11,0x10,0x08,0x00,0x22,0x21,0x20,0x18,0x00,0x22,0x21,0x20,0x18, -0x00,0x31,0x30,0x20,0x10,0x00,0x31,0x2f,0x10,0x10,0x00,0x31,0x2f,0x10,0x10,0x00, -0x31,0x10,0x10,0x00,0x00,0x31,0x2c,0x10,0x10,0x00,0x00,0x00,0x0a,0x09,0x08,0x04, -0x00,0x0a,0x09,0x08,0x04,0x00,0x0a,0x09,0x08,0x04,0x00,0x0a,0x09,0x08,0x04,0x00, -0x0a,0x09,0x08,0x00,0x00,0x0a,0x09,0x08,0x00,0x00,0x0a,0x09,0x08,0x00,0x00,0x0a, -0x09,0x08,0x00,0x00,0x0a,0x09,0x08,0x00,0x00,0x12,0x11,0x10,0x08,0x00,0x12,0x11, -0x10,0x08,0x00,0x22,0x21,0x20,0x18,0x00,0x0a,0x09,0x08,0x04,0x00,0x0a,0x09,0x08, -0x04,0x00,0x0a,0x09,0x08,0x02,0x00,0x0a,0x09,0x08,0x00,0x00,0x0a,0x09,0x08,0x00, -0x00,0x22,0x21,0x20,0x18,0x00,0x22,0x21,0x1c,0x08,0x00,0x22,0x21,0x14,0x08,0x00, -0x0a,0x09,0x08,0x02,0x00,0x0a,0x09,0x08,0x02,0x00,0x0a,0x09,0x08,0x02,0x00,0x0a, -0x09,0x08,0x02,0x00,0x0a,0x09,0x08,0x00,0x00,0x22,0x21,0x20,0x10,0x00,0x22,0x21, -0x20,0x08,0x00,0x22,0x21,0x14,0x08,0x00,0x22,0x21,0x14,0x08,0x00,0x0a,0x09,0x08, -0x04,0x00,0x0a,0x09,0x08,0x04,0x00,0x0a,0x09,0x08,0x04,0x00,0x0a,0x09,0x08,0x04, -0x00,0x1a,0x19,0x18,0x10,0x00,0x1a,0x19,0x18,0x10,0x00,0x1a,0x19,0x18,0x10,0x00, -0x1a,0x19,0x18,0x10,0x00,0x1a,0x19,0x18,0x10,0x00,0x22,0x21,0x20,0x08,0x00,0x31, -0x2c,0x10,0x10,0x00,0x31,0x28,0x10,0x00,0x00,0x12,0x11,0x10,0x08,0x00,0x22,0x21, -0x20,0x18,0x00,0x22,0x21,0x20,0x18,0x00,0x22,0x21,0x20,0x08,0x00,0x22,0x21,0x14, -0x08,0x00,0x22,0x20,0x18,0x08,0x00,0x31,0x30,0x20,0x10,0x00,0x31,0x2c,0x10,0x10, -0x00,0x0a,0x09,0x08,0x00,0x00,0x12,0x11,0x10,0x08,0x00,0x22,0x21,0x20,0x18,0x00, -0x22,0x21,0x20,0x18,0x00,0x31,0x30,0x20,0x10,0x00,0x31,0x2f,0x10,0x10,0x00,0x31, -0x2f,0x10,0x10,0x00,0x31,0x10,0x10,0x00,0x00,0x31,0x2c,0x10,0x10,0x00,0x00,0x00, -0x01,0x02,0x04,0x08,0x02,0x04,0x08,0x0c,0x10,0x18,0x20,0x30,0x02,0x04,0x08,0x0c, -0x10,0x18,0x20,0x30,0x06,0x0c,0x10,0x18,0x24,0x30,0x3c,0x48,0x48,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x25,0x27,0x2c,0x19,0x1b,0x1e,0x20, -0x23,0x29,0x2a,0x2b,0x00,0x00,0x00,0x00,0x25,0x29,0x2b,0x2e,0x2e,0x00,0x00,0x00, -0x04,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x10,0x00,0x00,0x00, -0x18,0x00,0x00,0x00,0x24,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x48,0x00,0x00,0x00, -0x60,0x00,0x00,0x00,0x90,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0xd8,0x00,0x00,0x00, -0x50,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0xa0,0x00,0x00,0x00,0xc8,0x00,0x00,0x00, -0x40,0x01,0x00,0x00,0x90,0x01,0x00,0x00,0xe0,0x01,0x00,0x00,0x30,0x02,0x00,0x00, -0x2c,0x01,0x00,0x00,0x40,0x01,0x00,0x00,0xe0,0x01,0x00,0x00,0xd0,0x02,0x00,0x00, -0x80,0x0c,0x00,0x00,0x80,0x0c,0x00,0x00,0x80,0x0c,0x00,0x00,0xa0,0x0f,0x00,0x00, -0xa0,0x0f,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x04,0x00,0x00,0x00, -0x08,0x00,0x00,0x00,0x0c,0x00,0x00,0x00,0x12,0x00,0x00,0x00,0x18,0x00,0x00,0x00, -0x24,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x60,0x00,0x00,0x00, -0x6c,0x00,0x00,0x00,0x28,0x00,0x00,0x00,0x3c,0x00,0x00,0x00,0x50,0x00,0x00,0x00, -0x64,0x00,0x00,0x00,0xa0,0x00,0x00,0x00,0xc8,0x00,0x00,0x00,0xf0,0x00,0x00,0x00, -0x18,0x01,0x00,0x00,0x64,0x00,0x00,0x00,0xa0,0x00,0x00,0x00,0xf0,0x00,0x00,0x00, -0x68,0x01,0x00,0x00,0x40,0x06,0x00,0x00,0x40,0x06,0x00,0x00,0x40,0x06,0x00,0x00, -0xd0,0x07,0x00,0x00,0xd0,0x07,0x00,0x00,0x2c,0x05,0x00,0x80,0x20,0x05,0x00,0x80, -0x14,0x05,0x00,0x80,0x08,0x05,0x00,0x80,0xfc,0x04,0x00,0x80,0xf0,0x04,0x00,0x80, -0xe4,0x04,0x00,0x80,0xd8,0x04,0x00,0x80,0xcc,0x04,0x00,0x80,0xc0,0x04,0x00,0x80, -0x78,0x04,0x00,0x80,0x68,0x15,0x02,0x80,0xc0,0x3a,0x00,0x80,0xcc,0x3a,0x00,0x80, -0xd8,0x3a,0x00,0x80,0xe4,0x3a,0x00,0x80,0xc0,0x3a,0x00,0x80,0xc0,0x3a,0x00,0x80, -0xc0,0x3a,0x00,0x80,0xc0,0x3a,0x00,0x80,0xf0,0x3a,0x00,0x80,0xfc,0x3a,0x00,0x80, -0x08,0x3b,0x00,0x80,0x14,0x3b,0x00,0x80,0x68,0x15,0x02,0x80,0xfe,0x01,0x80,0x7f, -0xe2,0x01,0x80,0x78,0xc7,0x01,0xc0,0x71,0xae,0x01,0x80,0x6b,0x95,0x01,0x40,0x65, -0x7f,0x01,0xc0,0x5f,0x69,0x01,0x40,0x5a,0x55,0x01,0x40,0x55,0x42,0x01,0x80,0x50, -0x30,0x01,0x00,0x4c,0x1f,0x01,0xc0,0x47,0x0f,0x01,0xc0,0x43,0x00,0x01,0x00,0x40, -0xf2,0x00,0x80,0x3c,0xe4,0x00,0x00,0x39,0xd7,0x00,0xc0,0x35,0xcb,0x00,0xc0,0x32, -0xc0,0x00,0x00,0x30,0xb5,0x00,0x40,0x2d,0xab,0x00,0xc0,0x2a,0xa2,0x00,0x80,0x28, -0x98,0x00,0x00,0x26,0x90,0x00,0x00,0x24,0x88,0x00,0x00,0x22,0x80,0x00,0x00,0x20, -0x79,0x00,0x40,0x1e,0x72,0x00,0x80,0x1c,0x6c,0x00,0x00,0x1b,0x66,0x00,0x80,0x19, -0x60,0x00,0x00,0x18,0x5b,0x00,0xc0,0x16,0x56,0x00,0x80,0x15,0x51,0x00,0x40,0x14, -0x4c,0x00,0x00,0x13,0x48,0x00,0x00,0x12,0x44,0x00,0x00,0x11,0x40,0x00,0x00,0x10, -0x36,0x35,0x2e,0x25,0x1c,0x12,0x09,0x04,0x33,0x32,0x2b,0x23,0x1a,0x11,0x08,0x04, -0x30,0x2f,0x29,0x21,0x19,0x10,0x08,0x03,0x2d,0x2d,0x27,0x1f,0x18,0x0f,0x08,0x03, -0x2b,0x2a,0x25,0x1e,0x16,0x0e,0x07,0x03,0x28,0x28,0x22,0x1c,0x15,0x0d,0x07,0x03, -0x26,0x25,0x21,0x1b,0x14,0x0d,0x06,0x03,0x24,0x23,0x1f,0x19,0x13,0x0c,0x06,0x03, -0x22,0x21,0x1d,0x18,0x11,0x0b,0x06,0x02,0x20,0x20,0x1b,0x16,0x11,0x08,0x05,0x02, -0x1f,0x1e,0x1a,0x15,0x10,0x0a,0x05,0x02,0x1d,0x1c,0x18,0x14,0x0f,0x0a,0x05,0x02, -0x1b,0x1a,0x17,0x13,0x0e,0x09,0x04,0x02,0x1a,0x19,0x16,0x12,0x0d,0x09,0x04,0x02, -0x18,0x17,0x15,0x11,0x0c,0x08,0x04,0x02,0x17,0x16,0x13,0x10,0x0c,0x08,0x04,0x02, -0x16,0x15,0x12,0x0f,0x0b,0x07,0x04,0x01,0x14,0x14,0x11,0x0e,0x0b,0x07,0x03,0x02, -0x13,0x13,0x10,0x0d,0x0a,0x06,0x03,0x01,0x12,0x12,0x0f,0x0c,0x09,0x06,0x03,0x01, -0x11,0x11,0x0f,0x0c,0x09,0x06,0x03,0x01,0x10,0x10,0x0e,0x0b,0x08,0x05,0x03,0x01, -0x0f,0x0f,0x0d,0x0b,0x08,0x05,0x03,0x01,0x0e,0x0e,0x0c,0x0a,0x08,0x05,0x02,0x01, -0x0d,0x0d,0x0c,0x0a,0x07,0x05,0x02,0x01,0x0d,0x0c,0x0b,0x09,0x07,0x04,0x02,0x01, -0x0c,0x0c,0x0a,0x09,0x06,0x04,0x02,0x01,0x0b,0x0b,0x0a,0x08,0x06,0x04,0x02,0x01, -0x0b,0x0a,0x09,0x08,0x06,0x04,0x02,0x01,0x0a,0x0a,0x09,0x07,0x05,0x03,0x02,0x01, -0x0a,0x09,0x08,0x07,0x05,0x03,0x02,0x01,0x09,0x09,0x08,0x06,0x05,0x03,0x01,0x01, -0x09,0x08,0x07,0x06,0x04,0x03,0x01,0x01,0x36,0x35,0x2e,0x1b,0x00,0x00,0x00,0x00, -0x33,0x32,0x2b,0x19,0x00,0x00,0x00,0x00,0x30,0x2f,0x29,0x18,0x00,0x00,0x00,0x00, -0x2d,0x2d,0x17,0x17,0x00,0x00,0x00,0x00,0x2b,0x2a,0x25,0x15,0x00,0x00,0x00,0x00, -0x28,0x28,0x24,0x14,0x00,0x00,0x00,0x00,0x26,0x25,0x21,0x13,0x00,0x00,0x00,0x00, -0x24,0x23,0x1f,0x12,0x00,0x00,0x00,0x00,0x22,0x21,0x1d,0x11,0x00,0x00,0x00,0x00, -0x20,0x20,0x1b,0x10,0x00,0x00,0x00,0x00,0x1f,0x1e,0x1a,0x0f,0x00,0x00,0x00,0x00, -0x1d,0x1c,0x18,0x0e,0x00,0x00,0x00,0x00,0x1b,0x1a,0x17,0x0e,0x00,0x00,0x00,0x00, -0x1a,0x19,0x16,0x0d,0x00,0x00,0x00,0x00,0x18,0x17,0x15,0x0c,0x00,0x00,0x00,0x00, -0x17,0x16,0x13,0x0b,0x00,0x00,0x00,0x00,0x16,0x15,0x12,0x0b,0x00,0x00,0x00,0x00, -0x14,0x14,0x11,0x0a,0x00,0x00,0x00,0x00,0x13,0x13,0x10,0x0a,0x00,0x00,0x00,0x00, -0x12,0x12,0x0f,0x09,0x00,0x00,0x00,0x00,0x11,0x11,0x0f,0x09,0x00,0x00,0x00,0x00, -0x10,0x10,0x0e,0x08,0x00,0x00,0x00,0x00,0x0f,0x0f,0x0d,0x08,0x00,0x00,0x00,0x00, -0x0e,0x0e,0x0c,0x07,0x00,0x00,0x00,0x00,0x0d,0x0d,0x0c,0x07,0x00,0x00,0x00,0x00, -0x0d,0x0c,0x0b,0x06,0x00,0x00,0x00,0x00,0x0c,0x0c,0x0a,0x06,0x00,0x00,0x00,0x00, -0x0b,0x0b,0x0a,0x06,0x00,0x00,0x00,0x00,0x0b,0x0a,0x09,0x05,0x00,0x00,0x00,0x00, -0x0a,0x0a,0x09,0x05,0x00,0x00,0x00,0x00,0x0a,0x09,0x08,0x05,0x00,0x00,0x00,0x00, -0x09,0x09,0x08,0x05,0x00,0x00,0x00,0x00,0x09,0x08,0x07,0x04,0x00,0x00,0x00,0x00, -0x06,0x00,0x2a,0xb0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08, -0x08,0x28,0x28,0x28,0x28,0x28,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08, -0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0xa0,0x10,0x10,0x10,0x10,0x10,0x10,0x10, -0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, -0x04,0x04,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x41,0x41,0x41,0x41,0x41,0x41,0x01, -0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, -0x01,0x01,0x01,0x10,0x10,0x10,0x10,0x10,0x10,0x42,0x42,0x42,0x42,0x42,0x42,0x02, -0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02, -0x02,0x02,0x02,0x10,0x10,0x10,0x10,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x10,0x10,0x10,0x10,0x10,0x10,0x10, -0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10, -0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, -0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x10, -0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02, -0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x10, -0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x00,0x19,0x77,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x26,0x72,0xb0,0x00,0x26,0x72,0xb0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x26,0x65,0x60,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x02, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xf2,0x30,0xb8,0xff,0xff,0xff,0xff, -}; - u8 Rtl8192SUFwMainArray[MainArrayLength] = { 0x0, }; diff --git a/drivers/staging/rtl8192su/r8192SU_HWImg.h b/drivers/staging/rtl8192su/r8192SU_HWImg.h index 96b1525..36e84af 100644 --- a/drivers/staging/rtl8192su/r8192SU_HWImg.h +++ b/drivers/staging/rtl8192su/r8192SU_HWImg.h @@ -5,8 +5,6 @@ /*Created on 2009/ 3/ 6, 5:29*/ -#define ImgArrayLength 68368 -extern u8 Rtl8192SUFwImgArray[ImgArrayLength]; #define MainArrayLength 1 extern u8 Rtl8192SUFwMainArray[MainArrayLength]; #define DataArrayLength 1 diff --git a/drivers/staging/rtl8192su/r8192S_firmware.c b/drivers/staging/rtl8192su/r8192S_firmware.c index 3561adf..752a3f1 100644 --- a/drivers/staging/rtl8192su/r8192S_firmware.c +++ b/drivers/staging/rtl8192su/r8192S_firmware.c @@ -360,117 +360,58 @@ bool FirmwareDownload92S(struct net_device *dev) RT_TRACE(COMP_FIRMWARE, " --->FirmwareDownload92S()\n"); - //3// - //3 //<1> Open Image file, and map file to contineous memory if open file success. - //3 // or read image file from array. Default load from BIN file - //3// - priv->firmware_source = FW_SOURCE_IMG_FILE;// We should decided by Reg. - - switch( priv->firmware_source ) +/* +* Load the firmware from RTL8192SU/rtl8192sfw.bin +*/ + if(pFirmware->szFwTmpBufferLen == 0) { - case FW_SOURCE_IMG_FILE: - if(pFirmware->szFwTmpBufferLen == 0) - { - - rc = request_firmware(&fw_entry, pFwImageFileName[ulInitStep],&priv->udev->dev);//===>1 - if(rc < 0 ) { - RT_TRACE(COMP_ERR, "request firmware fail!\n"); - goto DownloadFirmware_Fail; - } - - if(fw_entry->size > sizeof(pFirmware->szFwTmpBuffer)) - { - RT_TRACE(COMP_ERR, "img file size exceed the container buffer fail!\n"); - release_firmware(fw_entry); - goto DownloadFirmware_Fail; - } + rc = request_firmware(&fw_entry, pFwImageFileName[ulInitStep],&priv->udev->dev); + if(rc < 0 ) { + RT_TRACE(COMP_ERR, "request firmware fail!\n"); + goto DownloadFirmware_Fail; + } - memcpy(pFirmware->szFwTmpBuffer,fw_entry->data,fw_entry->size); - pFirmware->szFwTmpBufferLen = fw_entry->size; + if(fw_entry->size > sizeof(pFirmware->szFwTmpBuffer)) { + RT_TRACE(COMP_ERR, "img file size exceed the container buffer fail!\n"); release_firmware(fw_entry); - - pucMappedFile = pFirmware->szFwTmpBuffer; - file_length = pFirmware->szFwTmpBufferLen; - - //Retrieve FW header. - pFirmware->pFwHeader = (PRT_8192S_FIRMWARE_HDR) pucMappedFile; - pFwHdr = pFirmware->pFwHeader; - RT_TRACE(COMP_FIRMWARE,"signature:%x, version:%x, size:%x, imemsize:%x, sram size:%x\n", \ - pFwHdr->Signature, pFwHdr->Version, pFwHdr->DMEMSize, \ - pFwHdr->IMG_IMEM_SIZE, pFwHdr->IMG_SRAM_SIZE); - pFirmware->FirmwareVersion = byte(pFwHdr->Version ,0); - if ((pFwHdr->IMG_IMEM_SIZE==0) || (pFwHdr->IMG_IMEM_SIZE > sizeof(pFirmware->FwIMEM))) - { - RT_TRACE(COMP_ERR, "%s: memory for data image is less than IMEM required\n",\ - __FUNCTION__); - goto DownloadFirmware_Fail; - } else { - pucMappedFile+=FwHdrSize; - - //Retrieve IMEM image. - memcpy(pFirmware->FwIMEM, pucMappedFile, pFwHdr->IMG_IMEM_SIZE); - pFirmware->FwIMEMLen = pFwHdr->IMG_IMEM_SIZE; - } - - if (pFwHdr->IMG_SRAM_SIZE > sizeof(pFirmware->FwEMEM)) - { - RT_TRACE(COMP_ERR, "%s: memory for data image is less than EMEM required\n",\ - __FUNCTION__); - goto DownloadFirmware_Fail; - } else { - pucMappedFile += pFirmware->FwIMEMLen; - - /* Retriecve EMEM image */ - memcpy(pFirmware->FwEMEM, pucMappedFile, pFwHdr->IMG_SRAM_SIZE);//===>6 - pFirmware->FwEMEMLen = pFwHdr->IMG_SRAM_SIZE; - } - - + goto DownloadFirmware_Fail; } - break; - case FW_SOURCE_HEADER_FILE: -#if 1 -#define Rtl819XFwImageArray Rtl8192SUFwImgArray - //2008.11.10 Add by tynli. - pucMappedFile = Rtl819XFwImageArray; - ulFileLength = ImgArrayLength; + memcpy(pFirmware->szFwTmpBuffer,fw_entry->data,fw_entry->size); + pFirmware->szFwTmpBufferLen = fw_entry->size; + release_firmware(fw_entry); + + pucMappedFile = pFirmware->szFwTmpBuffer; + file_length = pFirmware->szFwTmpBufferLen; - RT_TRACE(COMP_INIT,"Fw download from header.\n"); - /* Retrieve FW header*/ + /* Retrieve FW header. */ pFirmware->pFwHeader = (PRT_8192S_FIRMWARE_HDR) pucMappedFile; pFwHdr = pFirmware->pFwHeader; RT_TRACE(COMP_FIRMWARE,"signature:%x, version:%x, size:%x, imemsize:%x, sram size:%x\n", \ pFwHdr->Signature, pFwHdr->Version, pFwHdr->DMEMSize, \ pFwHdr->IMG_IMEM_SIZE, pFwHdr->IMG_SRAM_SIZE); pFirmware->FirmwareVersion = byte(pFwHdr->Version ,0); - - if ((pFwHdr->IMG_IMEM_SIZE==0) || (pFwHdr->IMG_IMEM_SIZE > sizeof(pFirmware->FwIMEM))) - { - printk("FirmwareDownload92S(): memory for data image is less than IMEM required\n"); + if ((pFwHdr->IMG_IMEM_SIZE==0) || (pFwHdr->IMG_IMEM_SIZE > sizeof(pFirmware->FwIMEM))) { + RT_TRACE(COMP_ERR, "%s: memory for data image is less than IMEM required\n",\ + __FUNCTION__); goto DownloadFirmware_Fail; } else { pucMappedFile+=FwHdrSize; - //Retrieve IMEM image. + /* Retrieve IMEM image. */ memcpy(pFirmware->FwIMEM, pucMappedFile, pFwHdr->IMG_IMEM_SIZE); pFirmware->FwIMEMLen = pFwHdr->IMG_IMEM_SIZE; } - if (pFwHdr->IMG_SRAM_SIZE > sizeof(pFirmware->FwEMEM)) - { - printk(" FirmwareDownload92S(): memory for data image is less than EMEM required\n"); - goto DownloadFirmware_Fail; - } else { - pucMappedFile+= pFirmware->FwIMEMLen; - - //Retriecve EMEM image. - memcpy(pFirmware->FwEMEM, pucMappedFile, pFwHdr->IMG_SRAM_SIZE); - pFirmware->FwEMEMLen = pFwHdr->IMG_SRAM_SIZE; - } -#endif - break; - default: - break; + if (pFwHdr->IMG_SRAM_SIZE > sizeof(pFirmware->FwEMEM)) { + RT_TRACE(COMP_ERR, "%s: memory for data image is less than EMEM required\n",\ + __FUNCTION__); + goto DownloadFirmware_Fail; + } else { + pucMappedFile += pFirmware->FwIMEMLen; + /* Retriecve EMEM image */ + memcpy(pFirmware->FwEMEM, pucMappedFile, pFwHdr->IMG_SRAM_SIZE);//===>6 + pFirmware->FwEMEMLen = pFwHdr->IMG_SRAM_SIZE; + } } FwStatus = FirmwareGetNextStatus(pFirmware->FWStatus); @@ -538,3 +479,4 @@ bool FirmwareDownload92S(struct net_device *dev) return rtStatus; } +MODULE_FIRMWARE("RTL8192SU/rtl8192sfw.bin"); diff --git a/drivers/staging/rtl8192su/r8192S_firmware.h b/drivers/staging/rtl8192su/r8192S_firmware.h index c525380..2c2cf80 100644 --- a/drivers/staging/rtl8192su/r8192S_firmware.h +++ b/drivers/staging/rtl8192su/r8192S_firmware.h @@ -59,12 +59,6 @@ typedef enum _desc_packet_type_e{ DESC_PACKET_TYPE_NORMAL = 1, }desc_packet_type_e; -typedef enum _firmware_source{ - FW_SOURCE_IMG_FILE = 0, - FW_SOURCE_HEADER_FILE = 1, -}firmware_source_e, *pfirmware_source_e; - - typedef enum _opt_rst_type{ OPT_SYSTEM_RESET = 0, OPT_FIRMWARE_RESET = 1, @@ -185,7 +179,6 @@ typedef enum _FIRMWARE_8192S_STATUS{ #define RTL8190_MAX_FIRMWARE_CODE_SIZE 64000 //64k typedef struct _rt_firmware{ - firmware_source_e eFWSource; PRT_8192S_FIRMWARE_HDR pFwHeader; FIRMWARE_8192S_STATUS FWStatus; u16 FirmwareVersion; diff --git a/drivers/staging/rtl8192su/r8192S_phy.c b/drivers/staging/rtl8192su/r8192S_phy.c index 77ab026..63d4e5f 100644 --- a/drivers/staging/rtl8192su/r8192S_phy.c +++ b/drivers/staging/rtl8192su/r8192S_phy.c @@ -2407,8 +2407,8 @@ void PHY_SetBWModeCallback8192S(struct net_device *dev) break; default: - RT_TRACE(COMP_DBG, "SetBWModeCallback8190Pci():\ - unknown Bandwidth: %#X\n",priv->CurrentChannelBW); + RT_TRACE(COMP_DBG, "SetBWModeCallback8190Pci(): unknown Bandwidth: %#X\n", + priv->CurrentChannelBW); break; } @@ -3398,8 +3398,8 @@ void SwChnlCallback8192SUsb(struct net_device *dev) u32 delay; // bool ret; - RT_TRACE(COMP_SCAN, "==>SwChnlCallback8190Pci(), switch to channel\ - %d\n", priv->chan); + RT_TRACE(COMP_SCAN, "==>SwChnlCallback8190Pci(), switch to channel %d\n", + priv->chan); if(!priv->up) @@ -3525,8 +3525,8 @@ void SetBWModeCallback8192SUsb(struct net_device *dev) break; default: - RT_TRACE(COMP_DBG, "SetChannelBandwidth8190Pci():\ - unknown Bandwidth: %#X\n",priv->CurrentChannelBW); + RT_TRACE(COMP_DBG, "SetChannelBandwidth8190Pci(): unknown Bandwidth: %#X\n", + priv->CurrentChannelBW); break; } @@ -3660,8 +3660,8 @@ void SetBWModeCallback8192SUsbWorkItem(struct net_device *dev) break; default: - RT_TRACE(COMP_DBG, "SetBWModeCallback8192SUsbWorkItem():\ - unknown Bandwidth: %#X\n",priv->CurrentChannelBW); + RT_TRACE(COMP_DBG, "SetBWModeCallback8192SUsbWorkItem(): unknown Bandwidth: %#X\n", + priv->CurrentChannelBW); break; } diff --git a/drivers/staging/rtl8192su/r8192U.h b/drivers/staging/rtl8192su/r8192U.h index 2a11e01..ba87623 100644 --- a/drivers/staging/rtl8192su/r8192U.h +++ b/drivers/staging/rtl8192su/r8192U.h @@ -1258,7 +1258,6 @@ typedef struct r8192_priv u8 Rf_Mode; //add for Firmware RF -R/W switch prt_firmware pFirmware; rtl819xUsb_loopback_e LoopbackMode; - firmware_source_e firmware_source; bool usb_error; u16 EEPROMTxPowerDiff; diff --git a/drivers/staging/rtl8192su/r8192U_core.c b/drivers/staging/rtl8192su/r8192U_core.c index 6f424fe..7d0305c 100644 --- a/drivers/staging/rtl8192su/r8192U_core.c +++ b/drivers/staging/rtl8192su/r8192U_core.c @@ -110,7 +110,7 @@ u32 rt_global_debug_component = \ #define TOTAL_CAM_ENTRY 32 #define CAM_CONTENT_COUNT 8 -static struct usb_device_id rtl8192_usb_id_tbl[] = { +static const struct usb_device_id rtl8192_usb_id_tbl[] = { /* Realtek */ {USB_DEVICE(0x0bda, 0x8192)}, {USB_DEVICE(0x0bda, 0x8709)}, @@ -2340,25 +2340,24 @@ short rtl8192SU_tx(struct net_device *dev, struct sk_buff* skb) skb->len, rtl8192_tx_isr, skb); status = usb_submit_urb(tx_urb, GFP_ATOMIC); - if (!status){ -//we need to send 0 byte packet whenever 512N bytes/64N(HIGN SPEED/NORMAL SPEED) bytes packet has been transmitted. Otherwise, it will be halt to wait for another packet. WB. 2008.08.27 + if (!status) { + /* + * we need to send 0 byte packet whenever 512N bytes/64N(HIGN SPEED/NORMAL SPEED) bytes packet has been transmitted. + * Otherwise, it will be halt to wait for another packet. WB. 2008.08.27 + */ bool bSend0Byte = false; u8 zero = 0; - if(udev->speed == USB_SPEED_HIGH) - { + if(udev->speed == USB_SPEED_HIGH) { if (skb->len > 0 && skb->len % 512 == 0) bSend0Byte = true; } - else - { + else { if (skb->len > 0 && skb->len % 64 == 0) bSend0Byte = true; } - if (bSend0Byte) - { -#if 1 + if (bSend0Byte) { tx_urb_zero = usb_alloc_urb(0,GFP_ATOMIC); - if(!tx_urb_zero){ + if(!tx_urb_zero) { RT_TRACE(COMP_ERR, "can't alloc urb for zero byte\n"); return -ENOMEM; } @@ -2366,16 +2365,23 @@ short rtl8192SU_tx(struct net_device *dev, struct sk_buff* skb) usb_sndbulkpipe(udev,idx_pipe), &zero, 0, tx_zero_isr, dev); status = usb_submit_urb(tx_urb_zero, GFP_ATOMIC); - if (status){ - RT_TRACE(COMP_ERR, "Error TX URB for zero byte %d, error %d", atomic_read(&priv->tx_pending[tcb_desc->queue_index]), status); - return -1; + switch (status) { + case 0: + break; + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: + break; + default: + RT_TRACE(COMP_ERR, "Error TX URB for zero byte %d, error %d", + atomic_read(&priv->tx_pending[tcb_desc->queue_index]), status); + return -1; } -#endif } dev->trans_start = jiffies; atomic_inc(&priv->tx_pending[tcb_desc->queue_index]); return 0; - }else{ + } else { RT_TRACE(COMP_ERR, "Error TX URB %d, error %d", atomic_read(&priv->tx_pending[tcb_desc->queue_index]), status); return -1; @@ -2952,7 +2958,7 @@ void rtl8192_SetWirelessMode(struct net_device* dev, u8 wireless_mode) wireless_mode = WIRELESS_MODE_B; } } -#ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we shoud wait for FPGA +#ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we should wait for FPGA ActUpdateChannelAccessSetting( pAdapter, pHalData->CurrentWirelessMode, &pAdapter->MgntInfo.Info8185.ChannelAccessSetting ); #endif //LZM 090306 usb crash here, mark it temp @@ -3359,6 +3365,46 @@ u8 rtl8192SU_BoardTypeToRFtype(struct net_device* dev, u8 Boardtype) return RFtype; } +void update_hal_variables(struct r8192_priv *priv) +{ + int rf_path; + int i; + u8 index; + + for (rf_path = 0; rf_path < 2; rf_path++) { + for (i = 0; i < 3; i++) { + RT_TRACE((COMP_INIT), "CCK RF-%d CHan_Area-%d = 0x%x\n", rf_path, i, priv->RfCckChnlAreaTxPwr[rf_path][i]); + RT_TRACE((COMP_INIT), "OFDM-1T RF-%d CHan_Area-%d = 0x%x\n", rf_path, i, priv->RfOfdmChnlAreaTxPwr1T[rf_path][i]); + RT_TRACE((COMP_INIT), "OFDM-2T RF-%d CHan_Area-%d = 0x%x\n", rf_path, i, priv->RfOfdmChnlAreaTxPwr2T[rf_path][i]); + } + /* Assign dedicated channel tx power */ + for(i = 0; i < 14; i++) { + /* channel 1-3 use the same Tx Power Level. */ + if (i < 3) /* Channel 1-3 */ + index = 0; + else if (i < 9) /* Channel 4-9 */ + index = 1; + else /* Channel 10-14 */ + index = 2; + /* Record A & B CCK /OFDM - 1T/2T Channel area tx power */ + priv->RfTxPwrLevelCck[rf_path][i] = priv->RfCckChnlAreaTxPwr[rf_path][index]; + priv->RfTxPwrLevelOfdm1T[rf_path][i] = priv->RfOfdmChnlAreaTxPwr1T[rf_path][index]; + priv->RfTxPwrLevelOfdm2T[rf_path][i] = priv->RfOfdmChnlAreaTxPwr2T[rf_path][index]; + if (rf_path == 0) { + priv->TxPowerLevelOFDM24G[i] = priv->RfTxPwrLevelOfdm1T[rf_path][i] ; + priv->TxPowerLevelCCK[i] = priv->RfTxPwrLevelCck[rf_path][i]; + } + } + for(i = 0; i < 14; i++) { + RT_TRACE((COMP_INIT), + "Rf-%d TxPwr CH-%d CCK OFDM_1T OFDM_2T= 0x%x/0x%x/0x%x\n", + rf_path, i, priv->RfTxPwrLevelCck[rf_path][i], + priv->RfTxPwrLevelOfdm1T[rf_path][i] , + priv->RfTxPwrLevelOfdm2T[rf_path][i] ); + } + } +} + // // Description: // Config HW adapter information into initial value. @@ -3374,7 +3420,7 @@ rtl8192SU_ConfigAdapterInfo8192SForAutoLoadFail(struct net_device* dev) struct r8192_priv *priv = ieee80211_priv(dev); //u16 i,usValue; //u8 sMacAddr[6] = {0x00, 0xE0, 0x4C, 0x81, 0x92, 0x00}; - u8 rf_path, index; // For EEPROM/EFUSE After V0.6_1117 + u8 rf_path; // For EEPROM/EFUSE After V0.6_1117 int i; RT_TRACE(COMP_INIT, "====> ConfigAdapterInfo8192SForAutoLoadFail\n"); @@ -3426,10 +3472,9 @@ rtl8192SU_ConfigAdapterInfo8192SForAutoLoadFail(struct net_device* dev) write_nic_dword(dev, IDR0, ((u32*)dev->dev_addr)[0]); write_nic_word(dev, IDR4, ((u16*)(dev->dev_addr + 4))[0]); - RT_TRACE(COMP_INIT, "ReadAdapterInfo8192SEFuse(), Permanent Address = %02x-%02x-%02x-%02x-%02x-%02x\n", - dev->dev_addr[0], dev->dev_addr[1], - dev->dev_addr[2], dev->dev_addr[3], - dev->dev_addr[4], dev->dev_addr[5]); + RT_TRACE(COMP_INIT, + "ReadAdapterInfo8192SEFuse(), Permanent Address = %pM\n", + dev->dev_addr); priv->EEPROMBoardType = EEPROM_Default_BoardType; priv->rf_type = RF_1T2R; //RF_2T2R @@ -3455,42 +3500,7 @@ rtl8192SU_ConfigAdapterInfo8192SForAutoLoadFail(struct net_device* dev) } } - for (i = 0; i < 3; i++) - { - //RT_TRACE((COMP_EFUSE), "CCK RF-%d CHan_Area-%d = 0x%x\n", rf_path, i, - //priv->RfCckChnlAreaTxPwr[rf_path][i]); - //RT_TRACE((COMP_EFUSE), "OFDM-1T RF-%d CHan_Area-%d = 0x%x\n", rf_path, i, - //priv->RfOfdmChnlAreaTxPwr1T[rf_path][i]); - //RT_TRACE((COMP_EFUSE), "OFDM-2T RF-%d CHan_Area-%d = 0x%x\n", rf_path, i, - //priv->RfOfdmChnlAreaTxPwr2T[rf_path][i]); - } - - // Assign dedicated channel tx power - for(i=0; i<14; i++) // channel 1~3 use the same Tx Power Level. - { - if (i < 3) // Cjanel 1-3 - index = 0; - else if (i < 9) // Channel 4-9 - index = 1; - else // Channel 10-14 - index = 2; - - // Record A & B CCK /OFDM - 1T/2T Channel area tx power - priv->RfTxPwrLevelCck[rf_path][i] = - priv->RfCckChnlAreaTxPwr[rf_path][index]; - priv->RfTxPwrLevelOfdm1T[rf_path][i] = - priv->RfOfdmChnlAreaTxPwr1T[rf_path][index]; - priv->RfTxPwrLevelOfdm2T[rf_path][i] = - priv->RfOfdmChnlAreaTxPwr2T[rf_path][index]; - } - - for(i=0; i<14; i++) - { - //RT_TRACE((COMP_EFUSE), "Rf-%d TxPwr CH-%d CCK OFDM_1T OFDM_2T= 0x%x/0x%x/0x%x\n", - //rf_path, i, priv->RfTxPwrLevelCck[0][i], - //priv->RfTxPwrLevelOfdm1T[0][i] , - //priv->RfTxPwrLevelOfdm2T[0][i] ); - } + update_hal_variables(priv); // // Update remained HAL variables. @@ -3767,10 +3777,9 @@ rtl8192SU_ReadAdapterInfo8192SUsb(struct net_device* dev) write_nic_dword(dev, IDR0, ((u32*)dev->dev_addr)[0]); write_nic_word(dev, IDR4, ((u16*)(dev->dev_addr + 4))[0]); - RT_TRACE(COMP_INIT, "ReadAdapterInfo8192SEFuse(), Permanent Address = %02x-%02x-%02x-%02x-%02x-%02x\n", - dev->dev_addr[0], dev->dev_addr[1], - dev->dev_addr[2], dev->dev_addr[3], - dev->dev_addr[4], dev->dev_addr[5]); + RT_TRACE(COMP_INIT, + "ReadAdapterInfo8192SEFuse(), Permanent Address = %pM\n", + dev->dev_addr); // // Get CustomerID(Boad Type) @@ -3901,53 +3910,7 @@ rtl8192SU_ReadAdapterInfo8192SUsb(struct net_device* dev) } } -// - // Update Tx Power HAL variables. -// - for (rf_path = 0; rf_path < 2; rf_path++) - { - for (i = 0; i < 3; i++) - { - RT_TRACE((COMP_INIT), "CCK RF-%d CHan_Area-%d = 0x%x\n", rf_path, i, - priv->RfCckChnlAreaTxPwr[rf_path][i]); - RT_TRACE((COMP_INIT), "OFDM-1T RF-%d CHan_Area-%d = 0x%x\n", rf_path, i, - priv->RfOfdmChnlAreaTxPwr1T[rf_path][i]); - RT_TRACE((COMP_INIT), "OFDM-2T RF-%d CHan_Area-%d = 0x%x\n", rf_path, i, priv->RfOfdmChnlAreaTxPwr2T[rf_path][i]); - } - - // Assign dedicated channel tx power - for(i=0; i<14; i++) // channel 1~3 use the same Tx Power Level. - { - if (i < 3) // Cjanel 1-3 - index = 0; - else if (i < 9) // Channel 4-9 - index = 1; - else // Channel 10-14 - index = 2; - - // Record A & B CCK /OFDM - 1T/2T Channel area tx power - priv->RfTxPwrLevelCck[rf_path][i] = - priv->RfCckChnlAreaTxPwr[rf_path][index]; - priv->RfTxPwrLevelOfdm1T[rf_path][i] = - priv->RfOfdmChnlAreaTxPwr1T[rf_path][index]; - priv->RfTxPwrLevelOfdm2T[rf_path][i] = - priv->RfOfdmChnlAreaTxPwr2T[rf_path][index]; - if (rf_path == 0) - { - priv->TxPowerLevelOFDM24G[i] = priv->RfTxPwrLevelOfdm1T[rf_path][i] ; - priv->TxPowerLevelCCK[i] = priv->RfTxPwrLevelCck[rf_path][i]; - } - } - - for(i=0; i<14; i++) - { - RT_TRACE((COMP_INIT), - "Rf-%d TxPwr CH-%d CCK OFDM_1T OFDM_2T= 0x%x/0x%x/0x%x\n", - rf_path, i, priv->RfTxPwrLevelCck[rf_path][i], - priv->RfTxPwrLevelOfdm1T[rf_path][i] , - priv->RfTxPwrLevelOfdm2T[rf_path][i] ); - } - } + update_hal_variables(priv); } // @@ -7677,7 +7640,7 @@ void setKey( struct net_device *dev, if (EntryNo >= TOTAL_CAM_ENTRY) RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n"); - RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr"MAC_FMT"\n", dev,EntryNo, KeyIndex, KeyType, MAC_ARG(MacAddr)); + RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr%pM\n", dev,EntryNo, KeyIndex, KeyType, MacAddr); if (DefaultKey) usConfig |= BIT15 | (KeyType<<2); diff --git a/drivers/staging/rtl8192su/r8192U_dm.c b/drivers/staging/rtl8192su/r8192U_dm.c index 7891e96..fa5e244 100644 --- a/drivers/staging/rtl8192su/r8192U_dm.c +++ b/drivers/staging/rtl8192su/r8192U_dm.c @@ -2697,7 +2697,7 @@ static void dm_check_edca_turbo( u8* peername[11] = {"unknown", "realtek", "realtek_92se", "broadcom", "ralink", "atheros", "cisco", "marvell", "92u_softap", "self_softap"}; static int wb_tmp = 0; if (wb_tmp == 0){ - printk("%s():iot peer is %#x:%s, bssid:"MAC_FMT"\n",__FUNCTION__,pHTInfo->IOTPeer,peername[pHTInfo->IOTPeer], MAC_ARG(priv->ieee80211->current_network.bssid)); + printk("%s():iot peer is %#x:%s, bssid:%pM\n",__FUNCTION__,pHTInfo->IOTPeer,peername[pHTInfo->IOTPeer], priv->ieee80211->current_network.bssid); wb_tmp = 1; } } diff --git a/drivers/staging/rtl8192u/Kconfig b/drivers/staging/rtl8192u/Kconfig index 9913ab8..0439c90 100644 --- a/drivers/staging/rtl8192u/Kconfig +++ b/drivers/staging/rtl8192u/Kconfig @@ -1,6 +1,7 @@ config RTL8192U tristate "RealTek RTL8192U Wireless LAN NIC driver" depends on PCI && WLAN && USB - depends on WIRELESS_EXT + select WIRELESS_EXT + select WEXT_PRIV default N ---help--- diff --git a/drivers/staging/rtl8192u/Makefile b/drivers/staging/rtl8192u/Makefile index 2d59c4e..738f4a8 100644 --- a/drivers/staging/rtl8192u/Makefile +++ b/drivers/staging/rtl8192u/Makefile @@ -3,7 +3,7 @@ NIC_SELECT = RTL8192U EXTRA_CFLAGS += -std=gnu89 EXTRA_CFLAGS += -O2 -EXTRA_CFLAGS += -mhard-float -DCONFIG_FORCE_HARD_FLOAT=y +EXTRA_CFLAGS += -DCONFIG_FORCE_HARD_FLOAT=y EXTRA_CFLAGS += -DJACKSON_NEW_8187 -DJACKSON_NEW_RX EXTRA_CFLAGS += -DTHOMAS_BEACON -DTHOMAS_TASKLET -DTHOMAS_SKB -DTHOMAS_TURBO #EXTRA_CFLAGS += -DUSB_TX_DRIVER_AGGREGATION_ENABLE diff --git a/drivers/staging/rtl8192u/ieee80211.h b/drivers/staging/rtl8192u/ieee80211.h index 3a47f12..9d05ed6 100644 --- a/drivers/staging/rtl8192u/ieee80211.h +++ b/drivers/staging/rtl8192u/ieee80211.h @@ -551,9 +551,6 @@ do { if (ieee80211_debug_level & (level)) \ /* debug macros not dependent on CONFIG_IEEE80211_DEBUG */ -#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x" -#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5] - /* * To use the debug system; * diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211.h b/drivers/staging/rtl8192u/ieee80211/ieee80211.h index 10908e123..39847c8 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211.h @@ -30,6 +30,7 @@ #include <linux/jiffies.h> #include <linux/timer.h> #include <linux/sched.h> +#include <linux/semaphore.h> #include <linux/delay.h> #include <linux/wireless.h> @@ -551,9 +552,6 @@ do { if (ieee80211_debug_level & (level)) \ /* debug macros not dependent on CONFIG_IEEE80211_DEBUG */ -#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x" -#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5] - /* * To use the debug system; * diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c index 0b33bf4..0b57632 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c @@ -288,7 +288,7 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) if (!(keyidx & (1 << 5))) { if (net_ratelimit()) { printk(KERN_DEBUG "CCMP: received packet without ExtIV" - " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2)); + " flag from %pM\n", hdr->addr2); } key->dot11RSNAStatsCCMPFormatErrors++; return -2; @@ -301,9 +301,9 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) } if (!key->key_set) { if (net_ratelimit()) { - printk(KERN_DEBUG "CCMP: received packet from " MAC_FMT + printk(KERN_DEBUG "CCMP: received packet from %pM" " with keyid=%d that does not have a configured" - " key\n", MAC_ARG(hdr->addr2), keyidx); + " key\n", hdr->addr2, keyidx); } return -3; } @@ -318,11 +318,9 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) { if (net_ratelimit()) { - printk(KERN_DEBUG "CCMP: replay detected: STA=" MAC_FMT - " previous PN %02x%02x%02x%02x%02x%02x " - "received PN %02x%02x%02x%02x%02x%02x\n", - MAC_ARG(hdr->addr2), MAC_ARG(key->rx_pn), - MAC_ARG(pn)); + printk(KERN_DEBUG "CCMP: replay detected: STA=%pM" + " previous PN %pm received PN %pm\n", + hdr->addr2, key->rx_pn, pn); } key->dot11RSNAStatsCCMPReplays++; return -4; @@ -359,7 +357,7 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) if (memcmp(mic, a, CCMP_MIC_LEN) != 0) { if (net_ratelimit()) { printk(KERN_DEBUG "CCMP: decrypt failed: STA=" - MAC_FMT "\n", MAC_ARG(hdr->addr2)); + "%pM\n", hdr->addr2); } key->dot11RSNAStatsCCMPDecryptErrors++; return -5; @@ -435,11 +433,10 @@ static char * ieee80211_ccmp_print_stats(char *p, void *priv) { struct ieee80211_ccmp_data *ccmp = priv; p += sprintf(p, "key[%d] alg=CCMP key_set=%d " - "tx_pn=%02x%02x%02x%02x%02x%02x " - "rx_pn=%02x%02x%02x%02x%02x%02x " + "tx_pn=%pm rx_pn=%pm " "format_errors=%d replays=%d decrypt_errors=%d\n", ccmp->key_idx, ccmp->key_set, - MAC_ARG(ccmp->tx_pn), MAC_ARG(ccmp->rx_pn), + ccmp->tx_pn, ccmp->rx_pn, ccmp->dot11RSNAStatsCCMPFormatErrors, ccmp->dot11RSNAStatsCCMPReplays, ccmp->dot11RSNAStatsCCMPDecryptErrors); diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c index 841b999..9510507 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c @@ -410,7 +410,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) if (!(keyidx & (1 << 5))) { if (net_ratelimit()) { printk(KERN_DEBUG "TKIP: received packet without ExtIV" - " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2)); + " flag from %pM\n", hdr->addr2); } return -2; } @@ -422,9 +422,9 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) } if (!tkey->key_set) { if (net_ratelimit()) { - printk(KERN_DEBUG "TKIP: received packet from " MAC_FMT + printk(KERN_DEBUG "TKIP: received packet from %pM" " with keyid=%d that does not have a configured" - " key\n", MAC_ARG(hdr->addr2), keyidx); + " key\n", hdr->addr2, keyidx); } return -3; } @@ -437,9 +437,9 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) if (iv32 < tkey->rx_iv32 || (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) { if (net_ratelimit()) { - printk(KERN_DEBUG "TKIP: replay detected: STA=" MAC_FMT + printk(KERN_DEBUG "TKIP: replay detected: STA=%pM" " previous TSC %08x%04x received TSC " - "%08x%04x\n", MAC_ARG(hdr->addr2), + "%08x%04x\n", hdr->addr2, tkey->rx_iv32, tkey->rx_iv16, iv32, iv16); } tkey->dot11RSNAStatsTKIPReplays++; @@ -460,8 +460,8 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) { if (net_ratelimit()) { printk(KERN_DEBUG ": TKIP: failed to decrypt " - "received packet from " MAC_FMT "\n", - MAC_ARG(hdr->addr2)); + "received packet from %pM\n", + hdr->addr2); } return -7; } @@ -480,7 +480,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) } if (net_ratelimit()) { printk(KERN_DEBUG "TKIP: ICV error detected: STA=" - MAC_FMT "\n", MAC_ARG(hdr->addr2)); + "%pM\n", hdr->addr2); } tkey->dot11RSNAStatsTKIPICVErrors++; return -5; @@ -635,8 +635,8 @@ static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx, struct ieee80211_hdr_4addr *hdr; hdr = (struct ieee80211_hdr_4addr *) skb->data; printk(KERN_DEBUG "%s: Michael MIC verification failed for " - "MSDU from " MAC_FMT " keyidx=%d\n", - skb->dev ? skb->dev->name : "N/A", MAC_ARG(hdr->addr2), + "MSDU from %pM keyidx=%d\n", + skb->dev ? skb->dev->name : "N/A", hdr->addr2, keyidx); if (skb->dev) ieee80211_michael_mic_failure(skb->dev, hdr, keyidx); diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c index 7a8690f..b752017 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c @@ -260,7 +260,7 @@ static int store_debug_level(struct file *file, const char *buffer, unsigned long count, void *data) { char buf[] = "0x00000000"; - unsigned long len = min(sizeof(buf) - 1, count); + unsigned long len = min_t(unsigned long, sizeof(buf) - 1, count); char *p = (char *)buf; unsigned long val; diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c index 0e003c5..7e9b367 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c @@ -360,8 +360,8 @@ ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb, strcmp(crypt->ops->name, "TKIP") == 0) { if (net_ratelimit()) { printk(KERN_DEBUG "%s: TKIP countermeasures: dropped " - "received packet from " MAC_FMT "\n", - ieee->dev->name, MAC_ARG(hdr->addr2)); + "received packet from %pM\n", + ieee->dev->name, hdr->addr2); } return -1; } @@ -372,8 +372,8 @@ ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb, atomic_dec(&crypt->refcnt); if (res < 0) { IEEE80211_DEBUG_DROP( - "decryption failed (SA=" MAC_FMT - ") res=%d\n", MAC_ARG(hdr->addr2), res); + "decryption failed (SA=%pM" + ") res=%d\n", hdr->addr2, res); if (res == -2) IEEE80211_DEBUG_DROP("Decryption failed ICV " "mismatch (key %d)\n", @@ -410,8 +410,8 @@ ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device* ieee, struct sk_buff *s atomic_dec(&crypt->refcnt); if (res < 0) { printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed" - " (SA=" MAC_FMT " keyidx=%d)\n", - ieee->dev->name, MAC_ARG(hdr->addr2), keyidx); + " (SA=%pM keyidx=%d)\n", + ieee->dev->name, hdr->addr2, keyidx); return -1; } @@ -1016,8 +1016,8 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, * frames silently instead of filling system log with * these reports. */ IEEE80211_DEBUG_DROP("Decryption failed (not set)" - " (SA=" MAC_FMT ")\n", - MAC_ARG(hdr->addr2)); + " (SA=%pM)\n", + hdr->addr2); ieee->ieee_stats.rx_discards_undecryptable++; goto rx_dropped; } @@ -1256,8 +1256,8 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, } else { IEEE80211_DEBUG_DROP( "encryption configured, but RX " - "frame not encrypted (SA=" MAC_FMT ")\n", - MAC_ARG(hdr->addr2)); + "frame not encrypted (SA=%pM)\n", + hdr->addr2); goto rx_dropped; } } @@ -1276,9 +1276,9 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, !ieee80211_is_eapol_frame(ieee, skb, hdrlen)) { IEEE80211_DEBUG_DROP( "dropped unencrypted RX data " - "frame from " MAC_FMT + "frame from %pM" " (drop_unencrypted=1)\n", - MAC_ARG(hdr->addr2)); + hdr->addr2); goto rx_dropped; } /* @@ -2260,11 +2260,11 @@ static inline int ieee80211_network_init( } if (network->mode == 0) { - IEEE80211_DEBUG_SCAN("Filtered out '%s (" MAC_FMT ")' " + IEEE80211_DEBUG_SCAN("Filtered out '%s (%pM)' " "network.\n", escape_essid(network->ssid, network->ssid_len), - MAC_ARG(network->bssid)); + network->bssid); return 1; } @@ -2439,9 +2439,9 @@ static inline void ieee80211_process_probe_response( memset(&network, 0, sizeof(struct ieee80211_network)); IEEE80211_DEBUG_SCAN( - "'%s' (" MAC_FMT "): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n", + "'%s' (%pM): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n", escape_essid(info_element->data, info_element->len), - MAC_ARG(beacon->header.addr3), + beacon->header.addr3, (beacon->capability & (1<<0xf)) ? '1' : '0', (beacon->capability & (1<<0xe)) ? '1' : '0', (beacon->capability & (1<<0xd)) ? '1' : '0', @@ -2460,10 +2460,10 @@ static inline void ieee80211_process_probe_response( (beacon->capability & (1<<0x0)) ? '1' : '0'); if (ieee80211_network_init(ieee, beacon, &network, stats)) { - IEEE80211_DEBUG_SCAN("Dropped '%s' (" MAC_FMT ") via %s.\n", + IEEE80211_DEBUG_SCAN("Dropped '%s' (%pM) via %s.\n", escape_essid(info_element->data, info_element->len), - MAC_ARG(beacon->header.addr3), + beacon->header.addr3, WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_PROBE_RESP ? "PROBE RESPONSE" : "BEACON"); @@ -2574,11 +2574,11 @@ static inline void ieee80211_process_probe_response( /* If there are no more slots, expire the oldest */ list_del(&oldest->list); target = oldest; - IEEE80211_DEBUG_SCAN("Expired '%s' (" MAC_FMT ") from " + IEEE80211_DEBUG_SCAN("Expired '%s' (%pM) from " "network list.\n", escape_essid(target->ssid, target->ssid_len), - MAC_ARG(target->bssid)); + target->bssid); } else { /* Otherwise just pull from the free list */ target = list_entry(ieee->network_free_list.next, @@ -2588,10 +2588,10 @@ static inline void ieee80211_process_probe_response( #ifdef CONFIG_IEEE80211_DEBUG - IEEE80211_DEBUG_SCAN("Adding '%s' (" MAC_FMT ") via %s.\n", + IEEE80211_DEBUG_SCAN("Adding '%s' (%pM) via %s.\n", escape_essid(network.ssid, network.ssid_len), - MAC_ARG(network.bssid), + network.bssid, WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_PROBE_RESP ? "PROBE RESPONSE" : "BEACON"); @@ -2601,10 +2601,10 @@ static inline void ieee80211_process_probe_response( if(ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) ieee80211_softmac_new_net(ieee,&network); } else { - IEEE80211_DEBUG_SCAN("Updating '%s' (" MAC_FMT ") via %s.\n", + IEEE80211_DEBUG_SCAN("Updating '%s' (%pM) via %s.\n", escape_essid(target->ssid, target->ssid_len), - MAC_ARG(target->bssid), + target->bssid, WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_PROBE_RESP ? "PROBE RESPONSE" : "BEACON"); diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c index 8a86e93..27d9257 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c @@ -1731,7 +1731,7 @@ ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb) ieee80211_resp_to_assoc_rq(ieee, dest); } - printk(KERN_INFO"New client associated: "MAC_FMT"\n", MAC_ARG(dest)); + printk(KERN_INFO"New client associated: %pM\n", dest); //FIXME } diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c index b29c36b..48537d9 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c @@ -200,8 +200,8 @@ int ieee80211_encrypt_fragment( header = (struct ieee80211_hdr *) frag->data; if (net_ratelimit()) { printk(KERN_DEBUG "%s: TKIP countermeasures: dropped " - "TX packet to " MAC_FMT "\n", - ieee->dev->name, MAC_ARG(header->addr1)); + "TX packet to %pM\n", + ieee->dev->name, header->addr1); } return -1; } diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c index 5f12d62..c0b2c02 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c @@ -289,10 +289,10 @@ int ieee80211_wx_get_scan(struct ieee80211_device *ieee, else IEEE80211_DEBUG_SCAN( "Not showing network '%s (" - MAC_FMT ")' due to age (%lums).\n", + "%pM)' due to age (%lums).\n", escape_essid(network->ssid, network->ssid_len), - MAC_ARG(network->bssid), + network->bssid, (jiffies - network->last_scanned) / (HZ / 100)); } @@ -718,7 +718,7 @@ int ieee80211_wx_get_encode_ext(struct ieee80211_device *ieee, } else idx = ieee->tx_keyidx; - if (!ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY && + if (!(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) && ext->alg != IW_ENCODE_ALG_WEP) if (idx != 0 || ieee->iw_mode != IW_MODE_INFRA) return -EINVAL; diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c b/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c index 512a57a..27d083a 100644 --- a/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c +++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c @@ -113,7 +113,7 @@ static struct sk_buff* ieee80211_ADDBA(struct ieee80211_device* ieee, u8* Dst, P u16 tmp = 0; u16 len = ieee->tx_headroom + 9; //category(1) + action field(1) + Dialog Token(1) + BA Parameter Set(2) + BA Timeout Value(2) + BA Start SeqCtrl(2)(or StatusCode(2)) - IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), frame(%d) sentd to:"MAC_FMT", ieee->dev:%p\n", __FUNCTION__, type, MAC_ARG(Dst), ieee->dev); + IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), frame(%d) sentd to:%pM, ieee->dev:%p\n", __FUNCTION__, type, Dst, ieee->dev); if (pBA == NULL||ieee == NULL) { IEEE80211_DEBUG(IEEE80211_DL_ERR, "pBA(%p) is NULL or ieee(%p) is NULL\n", pBA, ieee); @@ -201,7 +201,7 @@ static struct sk_buff* ieee80211_DELBA( u16 len = 6 + ieee->tx_headroom; if (net_ratelimit()) - IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), ReasonCode(%d) sentd to:"MAC_FMT"\n", __FUNCTION__, ReasonCode, MAC_ARG(dst)); + IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), ReasonCode(%d) sentd to:%pM\n", __FUNCTION__, ReasonCode, dst); memset(&DelbaParamSet, 0, 2); @@ -355,7 +355,7 @@ int ieee80211_rx_ADDBAReq( struct ieee80211_device* ieee, struct sk_buff *skb) pBaTimeoutVal = (u16*)(tag + 5); pBaStartSeqCtrl = (PSEQUENCE_CONTROL)(req + 7); - printk("====================>rx ADDBAREQ from :"MAC_FMT"\n", MAC_ARG(dst)); + printk("====================>rx ADDBAREQ from :%pM\n", dst); //some other capability is not ready now. if( (ieee->current_network.qos_data.active == 0) || (ieee->pHTInfo->bCurrentHTSupport == false)) //|| diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c b/drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c index 2c4eb38..50f4f59 100644 --- a/drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c +++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c @@ -41,7 +41,7 @@ static u8 AIRLINK_RALINK[3] = {0x00, 0x18, 0x02}; //static u8 DLINK_ATHEROS[3] = {0x00, 0x1c, 0xf0}; static u8 CISCO_BROADCOM[3] = {0x00, 0x17, 0x94}; -// 2008/04/01 MH For Cisco G mode RX TP We need to change FW duration. Shoud we put the +// 2008/04/01 MH For Cisco G mode RX TP We need to change FW duration. Should we put the // code in other place?? //static u8 WIFI_CISCO_G_AP[3] = {0x00, 0x40, 0x96}; /******************************************************************************************************************** @@ -1342,7 +1342,7 @@ void HTUseDefaultSetting(struct ieee80211_device* ieee) pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor; - pHTInfo->CurrentMPDUDensity = pHTInfo->CurrentMPDUDensity; + pHTInfo->CurrentMPDUDensity = pHTInfo->MPDU_Density; // Set BWOpMode register diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c b/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c index 5373d56..d1275e8 100644 --- a/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c +++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c @@ -290,7 +290,7 @@ PTS_COMMON_INFO SearchAdmitTRStream(struct ieee80211_device *ieee, u8* Addr, u8 if(search_dir[dir] ==false ) continue; list_for_each_entry(pRet, psearch_list, List){ - // IEEE80211_DEBUG(IEEE80211_DL_TS, "ADD:"MAC_FMT", TID:%d, dir:%d\n", MAC_ARG(pRet->Addr), pRet->TSpec.f.TSInfo.field.ucTSID, pRet->TSpec.f.TSInfo.field.ucDirection); + // IEEE80211_DEBUG(IEEE80211_DL_TS, "ADD:%pM, TID:%d, dir:%d\n", pRet->Addr, pRet->TSpec.f.TSInfo.field.ucTSID, pRet->TSpec.f.TSInfo.field.ucDirection); if (memcmp(pRet->Addr, Addr, 6) == 0) if (pRet->TSpec.f.TSInfo.field.ucTSID == TID) if(pRet->TSpec.f.TSInfo.field.ucDirection == dir) @@ -445,7 +445,7 @@ bool GetTs( ResetRxTsEntry(tmp); } - IEEE80211_DEBUG(IEEE80211_DL_TS, "to init current TS, UP:%d, Dir:%d, addr:"MAC_FMT"\n", UP, Dir, MAC_ARG(Addr)); + IEEE80211_DEBUG(IEEE80211_DL_TS, "to init current TS, UP:%d, Dir:%d, addr:%pM\n", UP, Dir, Addr); // Prepare TS Info releated field pTSInfo->field.ucTrafficType = 0; // Traffic type: WMM is reserved in this field pTSInfo->field.ucTSID = UP; // TSID @@ -531,7 +531,7 @@ void RemoveTsEntry( void RemovePeerTS(struct ieee80211_device* ieee, u8* Addr) { PTS_COMMON_INFO pTS, pTmpTS; - printk("===========>RemovePeerTS,"MAC_FMT"\n", MAC_ARG(Addr)); + printk("===========>RemovePeerTS,%pM\n", Addr); list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, List) { if (memcmp(pTS->Addr, Addr, 6) == 0) diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c index adade13..f1e085b 100644 --- a/drivers/staging/rtl8192u/r8192U_core.c +++ b/drivers/staging/rtl8192u/r8192U_core.c @@ -104,7 +104,7 @@ u32 rt_global_debug_component = \ #define TOTAL_CAM_ENTRY 32 #define CAM_CONTENT_COUNT 8 -static struct usb_device_id rtl8192_usb_id_tbl[] = { +static const struct usb_device_id rtl8192_usb_id_tbl[] = { /* Realtek */ {USB_DEVICE(0x0bda, 0x8192)}, {USB_DEVICE(0x0bda, 0x8709)}, @@ -2719,7 +2719,7 @@ void rtl8192_SetWirelessMode(struct net_device* dev, u8 wireless_mode) wireless_mode = WIRELESS_MODE_B; } } -#ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we shoud wait for FPGA +#ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we should wait for FPGA ActUpdateChannelAccessSetting( pAdapter, pHalData->CurrentWirelessMode, &pAdapter->MgntInfo.Info8185.ChannelAccessSetting ); #endif priv->ieee80211->mode = wireless_mode; @@ -2976,7 +2976,7 @@ static void rtl8192_read_eeprom_info(struct net_device* dev) memcpy(dev->dev_addr, bMac_Tmp_Addr, 6); //should I set IDR0 here? } - RT_TRACE(COMP_EPROM, "MAC addr:"MAC_FMT"\n", MAC_ARG(dev->dev_addr)); + RT_TRACE(COMP_EPROM, "MAC addr:%pM\n", dev->dev_addr); priv->rf_type = RTL819X_DEFAULT_RF_TYPE; //default 1T2R priv->rf_chip = RF_8256; @@ -6037,7 +6037,7 @@ void setKey( struct net_device *dev, if (EntryNo >= TOTAL_CAM_ENTRY) RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n"); - RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr"MAC_FMT"\n", dev,EntryNo, KeyIndex, KeyType, MAC_ARG(MacAddr)); + RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr%pM\n", dev,EntryNo, KeyIndex, KeyType, MacAddr); if (DefaultKey) usConfig |= BIT15 | (KeyType<<2); diff --git a/drivers/staging/samsung-laptop/samsung-laptop.c b/drivers/staging/samsung-laptop/samsung-laptop.c index 4877138..dd7ea4c0 100644 --- a/drivers/staging/samsung-laptop/samsung-laptop.c +++ b/drivers/staging/samsung-laptop/samsung-laptop.c @@ -99,7 +99,8 @@ static struct rfkill *rfk; static int force; module_param(force, bool, 0); -MODULE_PARM_DESC(force, "Disable the DMI check and forces the driver to be loaded"); +MODULE_PARM_DESC(force, + "Disable the DMI check and forces the driver to be loaded"); static int debug; module_param(debug, bool, S_IRUGO | S_IWUSR); @@ -370,7 +371,8 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = { { .ident = "N128", .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), + DMI_MATCH(DMI_SYS_VENDOR, + "SAMSUNG ELECTRONICS CO., LTD."), DMI_MATCH(DMI_PRODUCT_NAME, "N128"), DMI_MATCH(DMI_BOARD_NAME, "N128"), }, @@ -379,7 +381,8 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = { { .ident = "N130", .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), + DMI_MATCH(DMI_SYS_VENDOR, + "SAMSUNG ELECTRONICS CO., LTD."), DMI_MATCH(DMI_PRODUCT_NAME, "N130"), DMI_MATCH(DMI_BOARD_NAME, "N130"), }, diff --git a/drivers/staging/sep/sep_driver.c b/drivers/staging/sep/sep_driver.c index e7bc9ec..265de79 100644 --- a/drivers/staging/sep/sep_driver.c +++ b/drivers/staging/sep/sep_driver.c @@ -35,6 +35,7 @@ #include <linux/cdev.h> #include <linux/kdev_t.h> #include <linux/mutex.h> +#include <linux/sched.h> #include <linux/mm.h> #include <linux/poll.h> #include <linux/wait.h> @@ -182,8 +183,8 @@ static DECLARE_WAIT_QUEUE_HEAD(sep_event); static int sep_load_firmware(struct sep_device *sep) { const struct firmware *fw; - char *cache_name = "cache.image.bin"; - char *res_name = "resident.image.bin"; + char *cache_name = "sep/cache.image.bin"; + char *res_name = "sep/resident.image.bin"; int error; edbg("SEP Driver:rar_virtual is %p\n", sep->rar_addr); @@ -222,6 +223,9 @@ static int sep_load_firmware(struct sep_device *sep) return 0; } +MODULE_FIRMWARE("sep/cache.image.bin"); +MODULE_FIRMWARE("sep/resident.image.bin"); + /** * sep_map_and_alloc_shared_area - allocate shared block * @sep: security processor @@ -273,8 +277,8 @@ static dma_addr_t sep_shared_virt_to_bus(struct sep_device *sep, void *virt_address) { dma_addr_t pa = sep->shared_bus + (virt_address - sep->shared_addr); - edbg("sep: virt to bus b %08llx v %p\n", - (unsigned long long)pa, virt_address); + edbg("sep: virt to bus b %08llx v %p\n", (unsigned long long) pa, + virt_address); return pa; } @@ -380,8 +384,7 @@ static int sep_mmap(struct file *filp, struct vm_area_struct *vma) shared area */ if ((vma->vm_end - vma->vm_start) > SEP_DRIVER_MMMAP_AREA_SIZE) { edbg("SEP Driver mmap requested size is more than allowed\n"); - printk(KERN_WARNING "SEP Driver mmap requested size is more \ - than allowed\n"); + printk(KERN_WARNING "SEP Driver mmap requested size is more than allowed\n"); printk(KERN_WARNING "SEP Driver vma->vm_end is %08lx\n", vma->vm_end); printk(KERN_WARNING "SEP Driver vma->vm_end is %08lx\n", vma->vm_start); return -EAGAIN; @@ -941,8 +944,9 @@ static int sep_lock_user_pages(struct sep_device *sep, dbg("data_size is %lu\n", data_size); while (1); } - edbg("lli_array[%lu].physical_address is %08lx, \ - lli_array[%lu].block_size is %lu\n", count, lli_array[count].physical_address, count, lli_array[count].block_size); + edbg("lli_array[%lu].physical_address is %08lx, lli_array[%lu].block_size is %lu\n", + count, lli_array[count].physical_address, + count, lli_array[count].block_size); } /* set output params */ @@ -1771,7 +1775,7 @@ static struct sep_flow_context_t *sep_find_flow_context(struct sep_device *sep, static int sep_create_flow_dma_tables_handler(struct sep_device *sep, unsigned long arg) { - int error; + int error = -ENOENT; struct sep_driver_build_flow_table_t command_args; /* first table - output */ struct sep_lli_entry_t first_table_data; @@ -2232,7 +2236,7 @@ static int sep_set_flow_id_handler(struct sep_device *sep, return error; } -static int sep_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) +static long sep_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { int error = 0; struct sep_device *sep = filp->private_data; @@ -2586,7 +2590,7 @@ end_function: return error; } -static struct pci_device_id sep_pci_id_tbl[] = { +static const struct pci_device_id sep_pci_id_tbl[] = { {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080c)}, {0} }; @@ -2607,7 +2611,7 @@ static dev_t sep_devno; /* the files operations structure of the driver */ static struct file_operations sep_file_operations = { .owner = THIS_MODULE, - .ioctl = sep_ioctl, + .unlocked_ioctl = sep_ioctl, .poll = sep_poll, .open = sep_open, .release = sep_release, diff --git a/drivers/staging/serqt_usb2/serqt_usb2.c b/drivers/staging/serqt_usb2/serqt_usb2.c index 060e9de..44f2d4e 100644 --- a/drivers/staging/serqt_usb2/serqt_usb2.c +++ b/drivers/staging/serqt_usb2/serqt_usb2.c @@ -126,7 +126,7 @@ static int debug; #define MODEM_CTRL 0x40 #define RS232_MODE 0x00 -static struct usb_device_id serqt_id_table[] = { +static const struct usb_device_id serqt_id_table[] = { {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_SSU100)}, {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_SSU200)}, {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_DSU100)}, @@ -1277,7 +1277,7 @@ static void qt_set_termios(struct tty_struct *tty, if (cflag & CSTOPB) new_LCR |= SERIAL_TWO_STOPB; else - new_LCR |= SERIAL_TWO_STOPB; + new_LCR |= SERIAL_ONE_STOPB; dbg("%s - 4\n", __func__); diff --git a/drivers/staging/slicoss/slic.h b/drivers/staging/slicoss/slic.h index ccf7625..eb3a619 100644 --- a/drivers/staging/slicoss/slic.h +++ b/drivers/staging/slicoss/slic.h @@ -527,15 +527,6 @@ struct adapter { (largestat) += ((newstat) - (oldstat)); \ } -#define ETHER_EQ_ADDR(_AddrA, _AddrB, _Result) \ -{ \ - _Result = true; \ - if (*(u32 *)(_AddrA) != *(u32 *)(_AddrB)) \ - _Result = false; \ - if (*(u16 *)(&((_AddrA)[4])) != *(u16 *)(&((_AddrB)[4]))) \ - _Result = false; \ -} - #if defined(CONFIG_X86_64) || defined(CONFIG_IA64) #define SLIC_GET_ADDR_LOW(_addr) (u32)((u64)(_addr) & \ 0x00000000FFFFFFFF) diff --git a/drivers/staging/slicoss/slicoss.c b/drivers/staging/slicoss/slicoss.c index f5cc01b..7daeced 100644 --- a/drivers/staging/slicoss/slicoss.c +++ b/drivers/staging/slicoss/slicoss.c @@ -101,7 +101,7 @@ static struct net_device_stats *slic_get_stats(struct net_device *dev); static int slic_entry_open(struct net_device *dev); static int slic_entry_halt(struct net_device *dev); static int slic_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); -static int slic_xmit_start(struct sk_buff *skb, struct net_device *dev); +static netdev_tx_t slic_xmit_start(struct sk_buff *skb, struct net_device *dev); static void slic_xmit_fail(struct adapter *adapter, struct sk_buff *skb, void *cmd, u32 skbtype, u32 status); static void slic_config_pci(struct pci_dev *pcidev); @@ -194,14 +194,10 @@ MODULE_PARM_DESC(dynamic_intagg, "Dynamic Interrupt Aggregation Setting"); module_param(intagg_delay, int, 0); MODULE_PARM_DESC(intagg_delay, "uSec Interrupt Aggregation Delay"); -static struct pci_device_id slic_pci_tbl[] __devinitdata = { - {PCI_VENDOR_ID_ALACRITECH, - SLIC_1GB_DEVICE_ID, - PCI_ANY_ID, PCI_ANY_ID,}, - {PCI_VENDOR_ID_ALACRITECH, - SLIC_2GB_DEVICE_ID, - PCI_ANY_ID, PCI_ANY_ID,}, - {0,} +static DEFINE_PCI_DEVICE_TABLE(slic_pci_tbl) = { + { PCI_DEVICE(PCI_VENDOR_ID_ALACRITECH, SLIC_1GB_DEVICE_ID) }, + { PCI_DEVICE(PCI_VENDOR_ID_ALACRITECH, SLIC_2GB_DEVICE_ID) }, + { 0 } }; MODULE_DEVICE_TABLE(pci, slic_pci_tbl); @@ -292,7 +288,7 @@ static void slic_init_adapter(struct net_device *netdev, { ushort index; struct slic_handle *pslic_handle; - struct adapter *adapter = (struct adapter *)netdev_priv(netdev); + struct adapter *adapter = netdev_priv(netdev); /* adapter->pcidev = pcidev;*/ adapter->vendid = pci_tbl_entry->vendor; @@ -370,6 +366,7 @@ static int __devinit slic_entry_probe(struct pci_dev *pcidev, ulong mmio_start = 0; ulong mmio_len = 0; struct sliccard *card = NULL; + int pci_using_dac = 0; slic_global.dynamic_intagg = dynamic_intagg; @@ -383,16 +380,26 @@ static int __devinit slic_entry_probe(struct pci_dev *pcidev, printk(KERN_DEBUG "%s\n", slic_proc_version); } - err = pci_set_dma_mask(pcidev, DMA_BIT_MASK(64)); - if (err) { - err = pci_set_dma_mask(pcidev, DMA_BIT_MASK(32)); - if (err) + if (!pci_set_dma_mask(pcidev, DMA_BIT_MASK(64))) { + pci_using_dac = 1; + if (pci_set_consistent_dma_mask(pcidev, DMA_BIT_MASK(64))) { + dev_err(&pcidev->dev, "unable to obtain 64-bit DMA for " + "consistent allocations\n"); goto err_out_disable_pci; + } + } else if (pci_set_dma_mask(pcidev, DMA_BIT_MASK(32))) { + pci_using_dac = 0; + pci_set_consistent_dma_mask(pcidev, DMA_BIT_MASK(32)); + } else { + dev_err(&pcidev->dev, "no usable DMA configuration\n"); + goto err_out_disable_pci; } err = pci_request_regions(pcidev, DRV_NAME); - if (err) + if (err) { + dev_err(&pcidev->dev, "can't obtain PCI resources\n"); goto err_out_disable_pci; + } pci_set_master(pcidev); @@ -408,6 +415,8 @@ static int __devinit slic_entry_probe(struct pci_dev *pcidev, adapter = netdev_priv(netdev); adapter->netdev = netdev; adapter->pcidev = pcidev; + if (pci_using_dac) + netdev->features |= NETIF_F_HIGHDMA; mmio_start = pci_resource_start(pcidev, 0); mmio_len = pci_resource_len(pcidev, 0); @@ -484,7 +493,7 @@ err_out_disable_pci: static int slic_entry_open(struct net_device *dev) { - struct adapter *adapter = (struct adapter *) netdev_priv(dev); + struct adapter *adapter = netdev_priv(dev); struct sliccard *card = adapter->card; u32 locked = 0; int status; @@ -534,7 +543,7 @@ static void __devexit slic_entry_remove(struct pci_dev *pcidev) struct net_device *dev = pci_get_drvdata(pcidev); u32 mmio_start = 0; uint mmio_len = 0; - struct adapter *adapter = (struct adapter *) netdev_priv(dev); + struct adapter *adapter = netdev_priv(dev); struct sliccard *card; struct mcast_address *mcaddr, *mlist; @@ -581,7 +590,7 @@ static void __devexit slic_entry_remove(struct pci_dev *pcidev) static int slic_entry_halt(struct net_device *dev) { - struct adapter *adapter = (struct adapter *)netdev_priv(dev); + struct adapter *adapter = netdev_priv(dev); struct sliccard *card = adapter->card; __iomem struct slic_regs *slic_regs = adapter->slic_regs; @@ -624,7 +633,7 @@ static int slic_entry_halt(struct net_device *dev) static int slic_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { - struct adapter *adapter = (struct adapter *)netdev_priv(dev); + struct adapter *adapter = netdev_priv(dev); struct ethtool_cmd edata; struct ethtool_cmd ecmd; u32 data[7]; @@ -649,8 +658,7 @@ static int slic_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) if (copy_from_user(data, rq->ifr_data, 28)) { PRINT_ERROR - ("slic: copy_from_user FAILED getting \ - initial simba param\n"); + ("slic: copy_from_user FAILED getting initial simba param\n"); return -EFAULT; } @@ -665,8 +673,7 @@ static int slic_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) (tracemon_request == SLIC_DUMP_IN_PROGRESS)) { PRINT_ERROR - ("ATK Diagnostic Trace Dump Requested but \ - already in progress... ignore\n"); + ("ATK Diagnostic Trace Dump Requested but already in progress... ignore\n"); } else { PRINT_ERROR ("ATK Diagnostic Trace Dump Requested\n"); @@ -784,10 +791,10 @@ static void slic_xmit_build_request(struct adapter *adapter, #define NORMAL_ETHFRAME 0 -static int slic_xmit_start(struct sk_buff *skb, struct net_device *dev) +static netdev_tx_t slic_xmit_start(struct sk_buff *skb, struct net_device *dev) { struct sliccard *card; - struct adapter *adapter = (struct adapter *)netdev_priv(dev); + struct adapter *adapter = netdev_priv(dev); struct slic_hostcmd *hcmd = NULL; u32 status = 0; u32 skbtype = NORMAL_ETHFRAME; @@ -1071,7 +1078,7 @@ static void slic_xmit_complete(struct adapter *adapter) static irqreturn_t slic_interrupt(int irq, void *dev_id) { struct net_device *dev = (struct net_device *)dev_id; - struct adapter *adapter = (struct adapter *)netdev_priv(dev); + struct adapter *adapter = netdev_priv(dev); u32 isr; if ((adapter->pshmem) && (adapter->pshmem->isr)) { @@ -1229,22 +1236,21 @@ static void slic_init_cleanup(struct adapter *adapter) static struct net_device_stats *slic_get_stats(struct net_device *dev) { - struct adapter *adapter = (struct adapter *)netdev_priv(dev); - struct net_device_stats *stats; + struct adapter *adapter = netdev_priv(dev); ASSERT(adapter); - stats = &adapter->stats; - stats->collisions = adapter->slic_stats.iface.xmit_collisions; - stats->rx_errors = adapter->slic_stats.iface.rcv_errors; - stats->tx_errors = adapter->slic_stats.iface.xmt_errors; - stats->rx_missed_errors = adapter->slic_stats.iface.rcv_discards; - stats->tx_heartbeat_errors = 0; - stats->tx_aborted_errors = 0; - stats->tx_window_errors = 0; - stats->tx_fifo_errors = 0; - stats->rx_frame_errors = 0; - stats->rx_length_errors = 0; - return &adapter->stats; + dev->stats.collisions = adapter->slic_stats.iface.xmit_collisions; + dev->stats.rx_errors = adapter->slic_stats.iface.rcv_errors; + dev->stats.tx_errors = adapter->slic_stats.iface.xmt_errors; + dev->stats.rx_missed_errors = adapter->slic_stats.iface.rcv_discards; + dev->stats.tx_heartbeat_errors = 0; + dev->stats.tx_aborted_errors = 0; + dev->stats.tx_window_errors = 0; + dev->stats.tx_fifo_errors = 0; + dev->stats.rx_frame_errors = 0; + dev->stats.rx_length_errors = 0; + + return &dev->stats; } /* @@ -1254,13 +1260,11 @@ static struct net_device_stats *slic_get_stats(struct net_device *dev) static int slic_mcast_add_list(struct adapter *adapter, char *address) { struct mcast_address *mcaddr, *mlist; - bool equaladdr; /* Check to see if it already exists */ mlist = adapter->mcastaddrs; while (mlist) { - ETHER_EQ_ADDR(mlist->address, address, equaladdr); - if (equaladdr) + if (!compare_ether_addr(mlist->address, address)) return STATUS_SUCCESS; mlist = mlist->next; } @@ -1360,7 +1364,7 @@ static void slic_mcast_set_bit(struct adapter *adapter, char *address) static void slic_mcast_set_list(struct net_device *dev) { - struct adapter *adapter = (struct adapter *)netdev_priv(dev); + struct adapter *adapter = netdev_priv(dev); int status = STATUS_SUCCESS; char *addresses; struct dev_mc_list *mc_list; @@ -1852,6 +1856,9 @@ static int slic_card_download_gbrcv(struct adapter *adapter) return 0; } +MODULE_FIRMWARE("slicoss/oasisrcvucode.sys"); +MODULE_FIRMWARE("slicoss/gbrcvucode.sys"); + static int slic_card_download(struct adapter *adapter) { const struct firmware *fw; @@ -1963,6 +1970,9 @@ static int slic_card_download(struct adapter *adapter) return STATUS_SUCCESS; } +MODULE_FIRMWARE("slicoss/oasisdownload.sys"); +MODULE_FIRMWARE("slicoss/gbdownload.sys"); + static void slic_adapter_set_hwaddr(struct adapter *adapter) { struct sliccard *card = adapter->card; @@ -2466,7 +2476,6 @@ static bool slic_mac_filter(struct adapter *adapter, u32 opts = adapter->macopts; u32 *dhost4 = (u32 *)ðer_frame->ether_dhost[0]; u16 *dhost2 = (u16 *)ðer_frame->ether_dhost[4]; - bool equaladdr; if (opts & MAC_PROMISC) return true; @@ -2490,10 +2499,8 @@ static bool slic_mac_filter(struct adapter *adapter, struct mcast_address *mcaddr = adapter->mcastaddrs; while (mcaddr) { - ETHER_EQ_ADDR(mcaddr->address, - ether_frame->ether_dhost, - equaladdr); - if (equaladdr) { + if (!compare_ether_addr(mcaddr->address, + ether_frame->ether_dhost)) { adapter->rcv_multicasts++; adapter->stats.multicast++; return true; @@ -2515,7 +2522,7 @@ static bool slic_mac_filter(struct adapter *adapter, static int slic_mac_set_address(struct net_device *dev, void *ptr) { - struct adapter *adapter = (struct adapter *)netdev_priv(dev); + struct adapter *adapter = netdev_priv(dev); struct sockaddr *addr = ptr; if (netif_running(dev)) @@ -2523,6 +2530,9 @@ static int slic_mac_set_address(struct net_device *dev, void *ptr) if (!adapter) return -EBUSY; + if (!is_valid_ether_addr(addr->sa_data)) + return -EINVAL; + memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); memcpy(adapter->currmacaddr, addr->sa_data, dev->addr_len); @@ -3960,10 +3970,8 @@ static void slic_debug_adapter_create(struct adapter *adapter) static void slic_debug_adapter_destroy(struct adapter *adapter) { - if (adapter->debugfs_entry) { - debugfs_remove(adapter->debugfs_entry); - adapter->debugfs_entry = NULL; - } + debugfs_remove(adapter->debugfs_entry); + adapter->debugfs_entry = NULL; } static void slic_debug_card_create(struct sliccard *card) diff --git a/drivers/staging/sm7xx/Kconfig b/drivers/staging/sm7xx/Kconfig index 204dbfc..315102c 100644 --- a/drivers/staging/sm7xx/Kconfig +++ b/drivers/staging/sm7xx/Kconfig @@ -6,10 +6,3 @@ config FB_SM7XX select FB_CFB_IMAGEBLIT help Frame Buffer driver for the Silicon Motion SM7XX serial graphic card. - -config FB_SM7XX_ACCEL - bool "Siliconmotion Acceleration functions (EXPERIMENTAL)" - depends on FB_SM7XX && EXPERIMENTAL - help - This will compile the Trident frame buffer device with - acceleration functions. diff --git a/drivers/staging/sm7xx/TODO b/drivers/staging/sm7xx/TODO index 1f61f5e..a66d9e4 100644 --- a/drivers/staging/sm7xx/TODO +++ b/drivers/staging/sm7xx/TODO @@ -1,5 +1,6 @@ TODO: - Dual head support +- 2D acceleration support - use kernel coding style - checkpatch.pl clean - refine the code and remove unused code diff --git a/drivers/staging/sm7xx/smtc2d.c b/drivers/staging/sm7xx/smtc2d.c deleted file mode 100644 index 2fff0a0..0000000 --- a/drivers/staging/sm7xx/smtc2d.c +++ /dev/null @@ -1,979 +0,0 @@ -/* - * Silicon Motion SM7XX 2D drawing engine functions. - * - * Copyright (C) 2006 Silicon Motion Technology Corp. - * Author: Boyod boyod.yang@siliconmotion.com.cn - * - * Copyright (C) 2009 Lemote, Inc. - * Author: Wu Zhangjin, wuzhangjin@gmail.com - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive for - * more details. - * - * Version 0.10.26192.21.01 - * - Add PowerPC support - * - Add 2D support for Lynx - - * Verified on 2.6.19.2 - * Boyod.yang <boyod.yang@siliconmotion.com.cn> - */ - -unsigned char smtc_de_busy; - -void SMTC_write2Dreg(unsigned long nOffset, unsigned long nData) -{ - writel(nData, smtc_2DBaseAddress + nOffset); -} - -unsigned long SMTC_read2Dreg(unsigned long nOffset) -{ - return readl(smtc_2DBaseAddress + nOffset); -} - -void SMTC_write2Ddataport(unsigned long nOffset, unsigned long nData) -{ - writel(nData, smtc_2Ddataport + nOffset); -} - -/********************************************************************** - * - * deInit - * - * Purpose - * Drawing engine initialization. - * - **********************************************************************/ - -void deInit(unsigned int nModeWidth, unsigned int nModeHeight, - unsigned int bpp) -{ - /* Get current power configuration. */ - unsigned char clock; - clock = smtc_seqr(0x21); - - /* initialize global 'mutex lock' variable */ - smtc_de_busy = 0; - - /* Enable 2D Drawing Engine */ - smtc_seqw(0x21, clock & 0xF8); - - SMTC_write2Dreg(DE_CLIP_TL, - FIELD_VALUE(0, DE_CLIP_TL, TOP, 0) | - FIELD_SET(0, DE_CLIP_TL, STATUS, DISABLE) | - FIELD_SET(0, DE_CLIP_TL, INHIBIT, OUTSIDE) | - FIELD_VALUE(0, DE_CLIP_TL, LEFT, 0)); - - if (bpp >= 24) { - SMTC_write2Dreg(DE_PITCH, - FIELD_VALUE(0, DE_PITCH, DESTINATION, - nModeWidth * 3) | FIELD_VALUE(0, - DE_PITCH, - SOURCE, - nModeWidth - * 3)); - } else { - SMTC_write2Dreg(DE_PITCH, - FIELD_VALUE(0, DE_PITCH, DESTINATION, - nModeWidth) | FIELD_VALUE(0, - DE_PITCH, - SOURCE, - nModeWidth)); - } - - SMTC_write2Dreg(DE_WINDOW_WIDTH, - FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, - nModeWidth) | FIELD_VALUE(0, - DE_WINDOW_WIDTH, - SOURCE, - nModeWidth)); - - switch (bpp) { - case 8: - SMTC_write2Dreg(DE_STRETCH_FORMAT, - FIELD_SET(0, DE_STRETCH_FORMAT, PATTERN_XY, - NORMAL) | FIELD_VALUE(0, - DE_STRETCH_FORMAT, - PATTERN_Y, - 0) | - FIELD_VALUE(0, DE_STRETCH_FORMAT, PATTERN_X, - 0) | FIELD_SET(0, DE_STRETCH_FORMAT, - PIXEL_FORMAT, - 8) | FIELD_SET(0, - DE_STRETCH_FORMAT, - ADDRESSING, - XY) | - FIELD_VALUE(0, DE_STRETCH_FORMAT, - SOURCE_HEIGHT, 3)); - break; - case 24: - SMTC_write2Dreg(DE_STRETCH_FORMAT, - FIELD_SET(0, DE_STRETCH_FORMAT, PATTERN_XY, - NORMAL) | FIELD_VALUE(0, - DE_STRETCH_FORMAT, - PATTERN_Y, - 0) | - FIELD_VALUE(0, DE_STRETCH_FORMAT, PATTERN_X, - 0) | FIELD_SET(0, DE_STRETCH_FORMAT, - PIXEL_FORMAT, - 24) | FIELD_SET(0, - DE_STRETCH_FORMAT, - ADDRESSING, - XY) | - FIELD_VALUE(0, DE_STRETCH_FORMAT, - SOURCE_HEIGHT, 3)); - break; - case 16: - default: - SMTC_write2Dreg(DE_STRETCH_FORMAT, - FIELD_SET(0, DE_STRETCH_FORMAT, PATTERN_XY, - NORMAL) | FIELD_VALUE(0, - DE_STRETCH_FORMAT, - PATTERN_Y, - 0) | - FIELD_VALUE(0, DE_STRETCH_FORMAT, PATTERN_X, - 0) | FIELD_SET(0, DE_STRETCH_FORMAT, - PIXEL_FORMAT, - 16) | FIELD_SET(0, - DE_STRETCH_FORMAT, - ADDRESSING, - XY) | - FIELD_VALUE(0, DE_STRETCH_FORMAT, - SOURCE_HEIGHT, 3)); - break; - } - - SMTC_write2Dreg(DE_MASKS, - FIELD_VALUE(0, DE_MASKS, BYTE_MASK, 0xFFFF) | - FIELD_VALUE(0, DE_MASKS, BIT_MASK, 0xFFFF)); - SMTC_write2Dreg(DE_COLOR_COMPARE_MASK, - FIELD_VALUE(0, DE_COLOR_COMPARE_MASK, MASKS, \ - 0xFFFFFF)); - SMTC_write2Dreg(DE_COLOR_COMPARE, - FIELD_VALUE(0, DE_COLOR_COMPARE, COLOR, 0xFFFFFF)); -} - -void deVerticalLine(unsigned long dst_base, - unsigned long dst_pitch, - unsigned long nX, - unsigned long nY, - unsigned long dst_height, unsigned long nColor) -{ - deWaitForNotBusy(); - - SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, - FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS, - dst_base)); - - SMTC_write2Dreg(DE_PITCH, - FIELD_VALUE(0, DE_PITCH, DESTINATION, dst_pitch) | - FIELD_VALUE(0, DE_PITCH, SOURCE, dst_pitch)); - - SMTC_write2Dreg(DE_WINDOW_WIDTH, - FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, - dst_pitch) | FIELD_VALUE(0, DE_WINDOW_WIDTH, - SOURCE, - dst_pitch)); - - SMTC_write2Dreg(DE_FOREGROUND, - FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor)); - - SMTC_write2Dreg(DE_DESTINATION, - FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) | - FIELD_VALUE(0, DE_DESTINATION, X, nX) | - FIELD_VALUE(0, DE_DESTINATION, Y, nY)); - - SMTC_write2Dreg(DE_DIMENSION, - FIELD_VALUE(0, DE_DIMENSION, X, 1) | - FIELD_VALUE(0, DE_DIMENSION, Y_ET, dst_height)); - - SMTC_write2Dreg(DE_CONTROL, - FIELD_SET(0, DE_CONTROL, STATUS, START) | - FIELD_SET(0, DE_CONTROL, DIRECTION, LEFT_TO_RIGHT) | - FIELD_SET(0, DE_CONTROL, MAJOR, Y) | - FIELD_SET(0, DE_CONTROL, STEP_X, NEGATIVE) | - FIELD_SET(0, DE_CONTROL, STEP_Y, POSITIVE) | - FIELD_SET(0, DE_CONTROL, LAST_PIXEL, OFF) | - FIELD_SET(0, DE_CONTROL, COMMAND, SHORT_STROKE) | - FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) | - FIELD_VALUE(0, DE_CONTROL, ROP, 0x0C)); - - smtc_de_busy = 1; -} - -void deHorizontalLine(unsigned long dst_base, - unsigned long dst_pitch, - unsigned long nX, - unsigned long nY, - unsigned long dst_width, unsigned long nColor) -{ - deWaitForNotBusy(); - - SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, - FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS, - dst_base)); - - SMTC_write2Dreg(DE_PITCH, - FIELD_VALUE(0, DE_PITCH, DESTINATION, dst_pitch) | - FIELD_VALUE(0, DE_PITCH, SOURCE, dst_pitch)); - - SMTC_write2Dreg(DE_WINDOW_WIDTH, - FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, - dst_pitch) | FIELD_VALUE(0, DE_WINDOW_WIDTH, - SOURCE, - dst_pitch)); - SMTC_write2Dreg(DE_FOREGROUND, - FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor)); - SMTC_write2Dreg(DE_DESTINATION, - FIELD_SET(0, DE_DESTINATION, WRAP, - DISABLE) | FIELD_VALUE(0, DE_DESTINATION, X, - nX) | FIELD_VALUE(0, - DE_DESTINATION, - Y, - nY)); - SMTC_write2Dreg(DE_DIMENSION, - FIELD_VALUE(0, DE_DIMENSION, X, - dst_width) | FIELD_VALUE(0, DE_DIMENSION, - Y_ET, 1)); - SMTC_write2Dreg(DE_CONTROL, - FIELD_SET(0, DE_CONTROL, STATUS, START) | FIELD_SET(0, - DE_CONTROL, - DIRECTION, - RIGHT_TO_LEFT) - | FIELD_SET(0, DE_CONTROL, MAJOR, X) | FIELD_SET(0, - DE_CONTROL, - STEP_X, - POSITIVE) - | FIELD_SET(0, DE_CONTROL, STEP_Y, - NEGATIVE) | FIELD_SET(0, DE_CONTROL, - LAST_PIXEL, - OFF) | FIELD_SET(0, - DE_CONTROL, - COMMAND, - SHORT_STROKE) - | FIELD_SET(0, DE_CONTROL, ROP_SELECT, - ROP2) | FIELD_VALUE(0, DE_CONTROL, ROP, - 0x0C)); - - smtc_de_busy = 1; -} - -void deLine(unsigned long dst_base, - unsigned long dst_pitch, - unsigned long nX1, - unsigned long nY1, - unsigned long nX2, unsigned long nY2, unsigned long nColor) -{ - unsigned long nCommand = - FIELD_SET(0, DE_CONTROL, STATUS, START) | - FIELD_SET(0, DE_CONTROL, DIRECTION, LEFT_TO_RIGHT) | - FIELD_SET(0, DE_CONTROL, MAJOR, X) | - FIELD_SET(0, DE_CONTROL, STEP_X, POSITIVE) | - FIELD_SET(0, DE_CONTROL, STEP_Y, POSITIVE) | - FIELD_SET(0, DE_CONTROL, LAST_PIXEL, OFF) | - FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) | - FIELD_VALUE(0, DE_CONTROL, ROP, 0x0C); - unsigned long DeltaX; - unsigned long DeltaY; - - /* Calculate delta X */ - if (nX1 <= nX2) - DeltaX = nX2 - nX1; - else { - DeltaX = nX1 - nX2; - nCommand = FIELD_SET(nCommand, DE_CONTROL, STEP_X, NEGATIVE); - } - - /* Calculate delta Y */ - if (nY1 <= nY2) - DeltaY = nY2 - nY1; - else { - DeltaY = nY1 - nY2; - nCommand = FIELD_SET(nCommand, DE_CONTROL, STEP_Y, NEGATIVE); - } - - /* Determine the major axis */ - if (DeltaX < DeltaY) - nCommand = FIELD_SET(nCommand, DE_CONTROL, MAJOR, Y); - - /* Vertical line? */ - if (nX1 == nX2) - deVerticalLine(dst_base, dst_pitch, nX1, nY1, DeltaY, nColor); - - /* Horizontal line? */ - else if (nY1 == nY2) - deHorizontalLine(dst_base, dst_pitch, nX1, nY1, \ - DeltaX, nColor); - - /* Diagonal line? */ - else if (DeltaX == DeltaY) { - deWaitForNotBusy(); - - SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, - FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, - ADDRESS, dst_base)); - - SMTC_write2Dreg(DE_PITCH, - FIELD_VALUE(0, DE_PITCH, DESTINATION, - dst_pitch) | FIELD_VALUE(0, - DE_PITCH, - SOURCE, - dst_pitch)); - - SMTC_write2Dreg(DE_WINDOW_WIDTH, - FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, - dst_pitch) | FIELD_VALUE(0, - DE_WINDOW_WIDTH, - SOURCE, - dst_pitch)); - - SMTC_write2Dreg(DE_FOREGROUND, - FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor)); - - SMTC_write2Dreg(DE_DESTINATION, - FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) | - FIELD_VALUE(0, DE_DESTINATION, X, 1) | - FIELD_VALUE(0, DE_DESTINATION, Y, nY1)); - - SMTC_write2Dreg(DE_DIMENSION, - FIELD_VALUE(0, DE_DIMENSION, X, 1) | - FIELD_VALUE(0, DE_DIMENSION, Y_ET, DeltaX)); - - SMTC_write2Dreg(DE_CONTROL, - FIELD_SET(nCommand, DE_CONTROL, COMMAND, - SHORT_STROKE)); - } - - /* Generic line */ - else { - unsigned int k1, k2, et, w; - if (DeltaX < DeltaY) { - k1 = 2 * DeltaX; - et = k1 - DeltaY; - k2 = et - DeltaY; - w = DeltaY + 1; - } else { - k1 = 2 * DeltaY; - et = k1 - DeltaX; - k2 = et - DeltaX; - w = DeltaX + 1; - } - - deWaitForNotBusy(); - - SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, - FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, - ADDRESS, dst_base)); - - SMTC_write2Dreg(DE_PITCH, - FIELD_VALUE(0, DE_PITCH, DESTINATION, - dst_pitch) | FIELD_VALUE(0, - DE_PITCH, - SOURCE, - dst_pitch)); - - SMTC_write2Dreg(DE_WINDOW_WIDTH, - FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, - dst_pitch) | FIELD_VALUE(0, - DE_WINDOW_WIDTH, - SOURCE, - dst_pitch)); - - SMTC_write2Dreg(DE_FOREGROUND, - FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor)); - - SMTC_write2Dreg(DE_SOURCE, - FIELD_SET(0, DE_SOURCE, WRAP, DISABLE) | - FIELD_VALUE(0, DE_SOURCE, X_K1, k1) | - FIELD_VALUE(0, DE_SOURCE, Y_K2, k2)); - - SMTC_write2Dreg(DE_DESTINATION, - FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) | - FIELD_VALUE(0, DE_DESTINATION, X, nX1) | - FIELD_VALUE(0, DE_DESTINATION, Y, nY1)); - - SMTC_write2Dreg(DE_DIMENSION, - FIELD_VALUE(0, DE_DIMENSION, X, w) | - FIELD_VALUE(0, DE_DIMENSION, Y_ET, et)); - - SMTC_write2Dreg(DE_CONTROL, - FIELD_SET(nCommand, DE_CONTROL, COMMAND, - LINE_DRAW)); - } - - smtc_de_busy = 1; -} - -void deFillRect(unsigned long dst_base, - unsigned long dst_pitch, - unsigned long dst_X, - unsigned long dst_Y, - unsigned long dst_width, - unsigned long dst_height, unsigned long nColor) -{ - deWaitForNotBusy(); - - SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, - FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS, - dst_base)); - - if (dst_pitch) { - SMTC_write2Dreg(DE_PITCH, - FIELD_VALUE(0, DE_PITCH, DESTINATION, - dst_pitch) | FIELD_VALUE(0, - DE_PITCH, - SOURCE, - dst_pitch)); - - SMTC_write2Dreg(DE_WINDOW_WIDTH, - FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, - dst_pitch) | FIELD_VALUE(0, - DE_WINDOW_WIDTH, - SOURCE, - dst_pitch)); - } - - SMTC_write2Dreg(DE_FOREGROUND, - FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor)); - - SMTC_write2Dreg(DE_DESTINATION, - FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) | - FIELD_VALUE(0, DE_DESTINATION, X, dst_X) | - FIELD_VALUE(0, DE_DESTINATION, Y, dst_Y)); - - SMTC_write2Dreg(DE_DIMENSION, - FIELD_VALUE(0, DE_DIMENSION, X, dst_width) | - FIELD_VALUE(0, DE_DIMENSION, Y_ET, dst_height)); - - SMTC_write2Dreg(DE_CONTROL, - FIELD_SET(0, DE_CONTROL, STATUS, START) | - FIELD_SET(0, DE_CONTROL, DIRECTION, LEFT_TO_RIGHT) | - FIELD_SET(0, DE_CONTROL, LAST_PIXEL, OFF) | - FIELD_SET(0, DE_CONTROL, COMMAND, RECTANGLE_FILL) | - FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) | - FIELD_VALUE(0, DE_CONTROL, ROP, 0x0C)); - - smtc_de_busy = 1; -} - -/********************************************************************** - * - * deRotatePattern - * - * Purpose - * Rotate the given pattern if necessary - * - * Parameters - * [in] - * pPattern - Pointer to DE_SURFACE structure containing - * pattern attributes - * patternX - X position (0-7) of pattern origin - * patternY - Y position (0-7) of pattern origin - * - * [out] - * pattern_dstaddr - Pointer to pre-allocated buffer containing - * rotated pattern - * - **********************************************************************/ -void deRotatePattern(unsigned char *pattern_dstaddr, - unsigned long pattern_src_addr, - unsigned long pattern_BPP, - unsigned long pattern_stride, int patternX, int patternY) -{ - unsigned int i; - unsigned long pattern[PATTERN_WIDTH * PATTERN_HEIGHT]; - unsigned int x, y; - unsigned char *pjPatByte; - - if (pattern_dstaddr != NULL) { - deWaitForNotBusy(); - - if (patternX || patternY) { - /* Rotate pattern */ - pjPatByte = (unsigned char *)pattern; - - switch (pattern_BPP) { - case 8: - { - for (y = 0; y < 8; y++) { - unsigned char *pjBuffer = - pattern_dstaddr + - ((patternY + y) & 7) * 8; - for (x = 0; x < 8; x++) { - pjBuffer[(patternX + - x) & 7] = - pjPatByte[x]; - } - pjPatByte += pattern_stride; - } - break; - } - - case 16: - { - for (y = 0; y < 8; y++) { - unsigned short *pjBuffer = - (unsigned short *) - pattern_dstaddr + - ((patternY + y) & 7) * 8; - for (x = 0; x < 8; x++) { - pjBuffer[(patternX + - x) & 7] = - ((unsigned short *) - pjPatByte)[x]; - } - pjPatByte += pattern_stride; - } - break; - } - - case 32: - { - for (y = 0; y < 8; y++) { - unsigned long *pjBuffer = - (unsigned long *) - pattern_dstaddr + - ((patternY + y) & 7) * 8; - for (x = 0; x < 8; x++) { - pjBuffer[(patternX + - x) & 7] = - ((unsigned long *) - pjPatByte)[x]; - } - pjPatByte += pattern_stride; - } - break; - } - } - } else { - /*Don't rotate,just copy pattern into pattern_dstaddr*/ - for (i = 0; i < (pattern_BPP * 2); i++) { - ((unsigned long *)pattern_dstaddr)[i] = - pattern[i]; - } - } - - } -} - -/********************************************************************** - * - * deCopy - * - * Purpose - * Copy a rectangular area of the source surface to a destination surface - * - * Remarks - * Source bitmap must have the same color depth (BPP) as the destination - * bitmap. - * -**********************************************************************/ -void deCopy(unsigned long dst_base, - unsigned long dst_pitch, - unsigned long dst_BPP, - unsigned long dst_X, - unsigned long dst_Y, - unsigned long dst_width, - unsigned long dst_height, - unsigned long src_base, - unsigned long src_pitch, - unsigned long src_X, - unsigned long src_Y, pTransparent pTransp, unsigned char nROP2) -{ - unsigned long nDirection = 0; - unsigned long nTransparent = 0; - /* Direction of ROP2 operation: - * 1 = Left to Right, - * (-1) = Right to Left - */ - unsigned long opSign = 1; - /* xWidth is in pixels */ - unsigned long xWidth = 192 / (dst_BPP / 8); - unsigned long de_ctrl = 0; - - deWaitForNotBusy(); - - SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, - FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS, - dst_base)); - - SMTC_write2Dreg(DE_WINDOW_SOURCE_BASE, - FIELD_VALUE(0, DE_WINDOW_SOURCE_BASE, ADDRESS, - src_base)); - - if (dst_pitch && src_pitch) { - SMTC_write2Dreg(DE_PITCH, - FIELD_VALUE(0, DE_PITCH, DESTINATION, - dst_pitch) | FIELD_VALUE(0, - DE_PITCH, - SOURCE, - src_pitch)); - - SMTC_write2Dreg(DE_WINDOW_WIDTH, - FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, - dst_pitch) | FIELD_VALUE(0, - DE_WINDOW_WIDTH, - SOURCE, - src_pitch)); - } - - /* Set transparent bits if necessary */ - if (pTransp != NULL) { - nTransparent = - pTransp->match | pTransp->select | pTransp->control; - - /* Set color compare register */ - SMTC_write2Dreg(DE_COLOR_COMPARE, - FIELD_VALUE(0, DE_COLOR_COMPARE, COLOR, - pTransp->color)); - } - - /* Determine direction of operation */ - if (src_Y < dst_Y) { - /* +----------+ - |S | - | +----------+ - | | | | - | | | | - +---|------+ | - | D | - +----------+ */ - - nDirection = BOTTOM_TO_TOP; - } else if (src_Y > dst_Y) { - /* +----------+ - |D | - | +----------+ - | | | | - | | | | - +---|------+ | - | S | - +----------+ */ - - nDirection = TOP_TO_BOTTOM; - } else { - /* src_Y == dst_Y */ - - if (src_X <= dst_X) { - /* +------+---+------+ - |S | | D| - | | | | - | | | | - | | | | - +------+---+------+ */ - - nDirection = RIGHT_TO_LEFT; - } else { - /* src_X > dst_X */ - - /* +------+---+------+ - |D | | S| - | | | | - | | | | - | | | | - +------+---+------+ */ - - nDirection = LEFT_TO_RIGHT; - } - } - - if ((nDirection == BOTTOM_TO_TOP) || (nDirection == RIGHT_TO_LEFT)) { - src_X += dst_width - 1; - src_Y += dst_height - 1; - dst_X += dst_width - 1; - dst_Y += dst_height - 1; - opSign = (-1); - } - - if (dst_BPP >= 24) { - src_X *= 3; - src_Y *= 3; - dst_X *= 3; - dst_Y *= 3; - dst_width *= 3; - if ((nDirection == BOTTOM_TO_TOP) - || (nDirection == RIGHT_TO_LEFT)) { - src_X += 2; - dst_X += 2; - } - } - - /* Workaround for 192 byte hw bug */ - if ((nROP2 != 0x0C) && ((dst_width * (dst_BPP / 8)) >= 192)) { - /* - * Perform the ROP2 operation in chunks of (xWidth * - * dst_height) - */ - while (1) { - deWaitForNotBusy(); - - SMTC_write2Dreg(DE_SOURCE, - FIELD_SET(0, DE_SOURCE, WRAP, DISABLE) | - FIELD_VALUE(0, DE_SOURCE, X_K1, src_X) | - FIELD_VALUE(0, DE_SOURCE, Y_K2, src_Y)); - - SMTC_write2Dreg(DE_DESTINATION, - FIELD_SET(0, DE_DESTINATION, WRAP, - DISABLE) | FIELD_VALUE(0, - DE_DESTINATION, - X, - dst_X) - | FIELD_VALUE(0, DE_DESTINATION, Y, - dst_Y)); - - SMTC_write2Dreg(DE_DIMENSION, - FIELD_VALUE(0, DE_DIMENSION, X, - xWidth) | FIELD_VALUE(0, - DE_DIMENSION, - Y_ET, - dst_height)); - - de_ctrl = - FIELD_VALUE(0, DE_CONTROL, ROP, - nROP2) | nTransparent | FIELD_SET(0, - DE_CONTROL, - ROP_SELECT, - ROP2) - | FIELD_SET(0, DE_CONTROL, COMMAND, - BITBLT) | ((nDirection == - 1) ? FIELD_SET(0, - DE_CONTROL, - DIRECTION, - RIGHT_TO_LEFT) - : FIELD_SET(0, DE_CONTROL, - DIRECTION, - LEFT_TO_RIGHT)) | - FIELD_SET(0, DE_CONTROL, STATUS, START); - - SMTC_write2Dreg(DE_CONTROL, de_ctrl); - - src_X += (opSign * xWidth); - dst_X += (opSign * xWidth); - dst_width -= xWidth; - - if (dst_width <= 0) { - /* ROP2 operation is complete */ - break; - } - - if (xWidth > dst_width) - xWidth = dst_width; - } - } else { - deWaitForNotBusy(); - SMTC_write2Dreg(DE_SOURCE, - FIELD_SET(0, DE_SOURCE, WRAP, DISABLE) | - FIELD_VALUE(0, DE_SOURCE, X_K1, src_X) | - FIELD_VALUE(0, DE_SOURCE, Y_K2, src_Y)); - - SMTC_write2Dreg(DE_DESTINATION, - FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) | - FIELD_VALUE(0, DE_DESTINATION, X, dst_X) | - FIELD_VALUE(0, DE_DESTINATION, Y, dst_Y)); - - SMTC_write2Dreg(DE_DIMENSION, - FIELD_VALUE(0, DE_DIMENSION, X, dst_width) | - FIELD_VALUE(0, DE_DIMENSION, Y_ET, dst_height)); - - de_ctrl = FIELD_VALUE(0, DE_CONTROL, ROP, nROP2) | - nTransparent | - FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) | - FIELD_SET(0, DE_CONTROL, COMMAND, BITBLT) | - ((nDirection == 1) ? FIELD_SET(0, DE_CONTROL, DIRECTION, - RIGHT_TO_LEFT) - : FIELD_SET(0, DE_CONTROL, DIRECTION, - LEFT_TO_RIGHT)) | FIELD_SET(0, DE_CONTROL, - STATUS, START); - SMTC_write2Dreg(DE_CONTROL, de_ctrl); - } - - smtc_de_busy = 1; -} - -/* - * This function sets the pixel format that will apply to the 2D Engine. - */ -void deSetPixelFormat(unsigned long bpp) -{ - unsigned long de_format; - - de_format = SMTC_read2Dreg(DE_STRETCH_FORMAT); - - switch (bpp) { - case 8: - de_format = - FIELD_SET(de_format, DE_STRETCH_FORMAT, PIXEL_FORMAT, 8); - break; - default: - case 16: - de_format = - FIELD_SET(de_format, DE_STRETCH_FORMAT, PIXEL_FORMAT, 16); - break; - case 32: - de_format = - FIELD_SET(de_format, DE_STRETCH_FORMAT, PIXEL_FORMAT, 32); - break; - } - - SMTC_write2Dreg(DE_STRETCH_FORMAT, de_format); -} - -/* - * System memory to Video memory monochrome expansion. - * - * Source is monochrome image in system memory. This function expands the - * monochrome data to color image in video memory. - */ - -long deSystemMem2VideoMemMonoBlt(const char *pSrcbuf, - long srcDelta, - unsigned long startBit, - unsigned long dBase, - unsigned long dPitch, - unsigned long bpp, - unsigned long dx, unsigned long dy, - unsigned long width, unsigned long height, - unsigned long fColor, - unsigned long bColor, - unsigned long rop2) { - unsigned long bytePerPixel; - unsigned long ulBytesPerScan; - unsigned long ul4BytesPerScan; - unsigned long ulBytesRemain; - unsigned long de_ctrl = 0; - unsigned char ajRemain[4]; - long i, j; - - bytePerPixel = bpp / 8; - - /* Just make sure the start bit is within legal range */ - startBit &= 7; - - ulBytesPerScan = (width + startBit + 7) / 8; - ul4BytesPerScan = ulBytesPerScan & ~3; - ulBytesRemain = ulBytesPerScan & 3; - - if (smtc_de_busy) - deWaitForNotBusy(); - - /* - * 2D Source Base. Use 0 for HOST Blt. - */ - - SMTC_write2Dreg(DE_WINDOW_SOURCE_BASE, 0); - - /* - * 2D Destination Base. - * - * It is an address offset (128 bit aligned) from the beginning of - * frame buffer. - */ - - SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, dBase); - - if (dPitch) { - - /* - * Program pitch (distance between the 1st points of two - * adjacent lines). - * - * Note that input pitch is BYTE value, but the 2D Pitch - * register uses pixel values. Need Byte to pixel convertion. - */ - - SMTC_write2Dreg(DE_PITCH, - FIELD_VALUE(0, DE_PITCH, DESTINATION, - dPitch / - bytePerPixel) | FIELD_VALUE(0, - DE_PITCH, - SOURCE, - dPitch / - bytePerPixel)); - - /* Screen Window width in Pixels. - * - * 2D engine uses this value to calculate the linear address in - * frame buffer for a given point. - */ - - SMTC_write2Dreg(DE_WINDOW_WIDTH, - FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, - (dPitch / - bytePerPixel)) | FIELD_VALUE(0, - DE_WINDOW_WIDTH, - SOURCE, - (dPitch - / - bytePerPixel))); - } - /* Note: For 2D Source in Host Write, only X_K1 field is needed, and - * Y_K2 field is not used. For mono bitmap, use startBit for X_K1. - */ - - SMTC_write2Dreg(DE_SOURCE, - FIELD_SET(0, DE_SOURCE, WRAP, DISABLE) | - FIELD_VALUE(0, DE_SOURCE, X_K1, startBit) | - FIELD_VALUE(0, DE_SOURCE, Y_K2, 0)); - - SMTC_write2Dreg(DE_DESTINATION, - FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) | - FIELD_VALUE(0, DE_DESTINATION, X, dx) | - FIELD_VALUE(0, DE_DESTINATION, Y, dy)); - - SMTC_write2Dreg(DE_DIMENSION, - FIELD_VALUE(0, DE_DIMENSION, X, width) | - FIELD_VALUE(0, DE_DIMENSION, Y_ET, height)); - - SMTC_write2Dreg(DE_FOREGROUND, fColor); - SMTC_write2Dreg(DE_BACKGROUND, bColor); - - if (bpp) - deSetPixelFormat(bpp); - /* Set the pixel format of the destination */ - - de_ctrl = FIELD_VALUE(0, DE_CONTROL, ROP, rop2) | - FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) | - FIELD_SET(0, DE_CONTROL, COMMAND, HOST_WRITE) | - FIELD_SET(0, DE_CONTROL, HOST, MONO) | - FIELD_SET(0, DE_CONTROL, STATUS, START); - - SMTC_write2Dreg(DE_CONTROL, de_ctrl | deGetTransparency()); - - /* Write MONO data (line by line) to 2D Engine data port */ - for (i = 0; i < height; i++) { - /* For each line, send the data in chunks of 4 bytes */ - for (j = 0; j < (ul4BytesPerScan / 4); j++) - SMTC_write2Ddataport(0, - *(unsigned long *)(pSrcbuf + - (j * 4))); - - if (ulBytesRemain) { - memcpy(ajRemain, pSrcbuf + ul4BytesPerScan, - ulBytesRemain); - SMTC_write2Ddataport(0, *(unsigned long *)ajRemain); - } - - pSrcbuf += srcDelta; - } - smtc_de_busy = 1; - - return 0; -} - -/* - * This function gets the transparency status from DE_CONTROL register. - * It returns a double word with the transparent fields properly set, - * while other fields are 0. - */ -unsigned long deGetTransparency(void) -{ - unsigned long de_ctrl; - - de_ctrl = SMTC_read2Dreg(DE_CONTROL); - - de_ctrl &= - FIELD_MASK(DE_CONTROL_TRANSPARENCY_MATCH) | - FIELD_MASK(DE_CONTROL_TRANSPARENCY_SELECT) | - FIELD_MASK(DE_CONTROL_TRANSPARENCY); - - return de_ctrl; -} diff --git a/drivers/staging/sm7xx/smtc2d.h b/drivers/staging/sm7xx/smtc2d.h deleted file mode 100644 index 02b4fa2..0000000 --- a/drivers/staging/sm7xx/smtc2d.h +++ /dev/null @@ -1,530 +0,0 @@ -/* - * Silicon Motion SM712 2D drawing engine functions. - * - * Copyright (C) 2006 Silicon Motion Technology Corp. - * Author: Ge Wang, gewang@siliconmotion.com - * - * Copyright (C) 2009 Lemote, Inc. - * Author: Wu Zhangjin, wuzhangjin@gmail.com - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive for - * more details. - */ - -#ifndef NULL -#define NULL 0 -#endif - -/* Internal macros */ - -#define _F_START(f) (0 ? f) -#define _F_END(f) (1 ? f) -#define _F_SIZE(f) (1 + _F_END(f) - _F_START(f)) -#define _F_MASK(f) (((1ULL << _F_SIZE(f)) - 1) << _F_START(f)) -#define _F_NORMALIZE(v, f) (((v) & _F_MASK(f)) >> _F_START(f)) -#define _F_DENORMALIZE(v, f) (((v) << _F_START(f)) & _F_MASK(f)) - -/* Global macros */ - -#define FIELD_GET(x, reg, field) \ -( \ - _F_NORMALIZE((x), reg ## _ ## field) \ -) - -#define FIELD_SET(x, reg, field, value) \ -( \ - (x & ~_F_MASK(reg ## _ ## field)) \ - | _F_DENORMALIZE(reg ## _ ## field ## _ ## value, reg ## _ ## field) \ -) - -#define FIELD_VALUE(x, reg, field, value) \ -( \ - (x & ~_F_MASK(reg ## _ ## field)) \ - | _F_DENORMALIZE(value, reg ## _ ## field) \ -) - -#define FIELD_CLEAR(reg, field) \ -( \ - ~_F_MASK(reg ## _ ## field) \ -) - -/* Field Macros */ - -#define FIELD_START(field) (0 ? field) -#define FIELD_END(field) (1 ? field) -#define FIELD_SIZE(field) \ - (1 + FIELD_END(field) - FIELD_START(field)) - -#define FIELD_MASK(field) \ - (((1 << (FIELD_SIZE(field)-1)) \ - | ((1 << (FIELD_SIZE(field)-1)) - 1)) \ - << FIELD_START(field)) - -#define FIELD_NORMALIZE(reg, field) \ - (((reg) & FIELD_MASK(field)) >> FIELD_START(field)) - -#define FIELD_DENORMALIZE(field, value) \ - (((value) << FIELD_START(field)) & FIELD_MASK(field)) - -#define FIELD_INIT(reg, field, value) \ - FIELD_DENORMALIZE(reg ## _ ## field, \ - reg ## _ ## field ## _ ## value) - -#define FIELD_INIT_VAL(reg, field, value) \ - (FIELD_DENORMALIZE(reg ## _ ## field, value)) - -#define FIELD_VAL_SET(x, r, f, v) ({ \ - x = (x & ~FIELD_MASK(r ## _ ## f)) \ - | FIELD_DENORMALIZE(r ## _ ## f, r ## _ ## f ## _ ## v) \ -}) - -#define RGB(r, g, b) ((unsigned long)(((r) << 16) | ((g) << 8) | (b))) - -/* Transparent info definition */ -typedef struct { - unsigned long match; /* Matching pixel is OPAQUE/TRANSPARENT */ - unsigned long select; /* Transparency controlled by SRC/DST */ - unsigned long control; /* ENABLE/DISABLE transparency */ - unsigned long color; /* Transparent color */ -} Transparent, *pTransparent; - -#define PIXEL_DEPTH_1_BP 0 /* 1 bit per pixel */ -#define PIXEL_DEPTH_8_BPP 1 /* 8 bits per pixel */ -#define PIXEL_DEPTH_16_BPP 2 /* 16 bits per pixel */ -#define PIXEL_DEPTH_32_BPP 3 /* 32 bits per pixel */ -#define PIXEL_DEPTH_YUV422 8 /* 16 bits per pixel YUV422 */ -#define PIXEL_DEPTH_YUV420 9 /* 16 bits per pixel YUV420 */ - -#define PATTERN_WIDTH 8 -#define PATTERN_HEIGHT 8 - -#define TOP_TO_BOTTOM 0 -#define BOTTOM_TO_TOP 1 -#define RIGHT_TO_LEFT BOTTOM_TO_TOP -#define LEFT_TO_RIGHT TOP_TO_BOTTOM - -/* Constants used in Transparent structure */ -#define MATCH_OPAQUE 0x00000000 -#define MATCH_TRANSPARENT 0x00000400 -#define SOURCE 0x00000000 -#define DESTINATION 0x00000200 - -/* 2D registers. */ - -#define DE_SOURCE 0x000000 -#define DE_SOURCE_WRAP 31 : 31 -#define DE_SOURCE_WRAP_DISABLE 0 -#define DE_SOURCE_WRAP_ENABLE 1 -#define DE_SOURCE_X_K1 29 : 16 -#define DE_SOURCE_Y_K2 15 : 0 - -#define DE_DESTINATION 0x000004 -#define DE_DESTINATION_WRAP 31 : 31 -#define DE_DESTINATION_WRAP_DISABLE 0 -#define DE_DESTINATION_WRAP_ENABLE 1 -#define DE_DESTINATION_X 28 : 16 -#define DE_DESTINATION_Y 15 : 0 - -#define DE_DIMENSION 0x000008 -#define DE_DIMENSION_X 28 : 16 -#define DE_DIMENSION_Y_ET 15 : 0 - -#define DE_CONTROL 0x00000C -#define DE_CONTROL_STATUS 31 : 31 -#define DE_CONTROL_STATUS_STOP 0 -#define DE_CONTROL_STATUS_START 1 -#define DE_CONTROL_PATTERN 30 : 30 -#define DE_CONTROL_PATTERN_MONO 0 -#define DE_CONTROL_PATTERN_COLOR 1 -#define DE_CONTROL_UPDATE_DESTINATION_X 29 : 29 -#define DE_CONTROL_UPDATE_DESTINATION_X_DISABLE 0 -#define DE_CONTROL_UPDATE_DESTINATION_X_ENABLE 1 -#define DE_CONTROL_QUICK_START 28 : 28 -#define DE_CONTROL_QUICK_START_DISABLE 0 -#define DE_CONTROL_QUICK_START_ENABLE 1 -#define DE_CONTROL_DIRECTION 27 : 27 -#define DE_CONTROL_DIRECTION_LEFT_TO_RIGHT 0 -#define DE_CONTROL_DIRECTION_RIGHT_TO_LEFT 1 -#define DE_CONTROL_MAJOR 26 : 26 -#define DE_CONTROL_MAJOR_X 0 -#define DE_CONTROL_MAJOR_Y 1 -#define DE_CONTROL_STEP_X 25 : 25 -#define DE_CONTROL_STEP_X_POSITIVE 1 -#define DE_CONTROL_STEP_X_NEGATIVE 0 -#define DE_CONTROL_STEP_Y 24 : 24 -#define DE_CONTROL_STEP_Y_POSITIVE 1 -#define DE_CONTROL_STEP_Y_NEGATIVE 0 -#define DE_CONTROL_STRETCH 23 : 23 -#define DE_CONTROL_STRETCH_DISABLE 0 -#define DE_CONTROL_STRETCH_ENABLE 1 -#define DE_CONTROL_HOST 22 : 22 -#define DE_CONTROL_HOST_COLOR 0 -#define DE_CONTROL_HOST_MONO 1 -#define DE_CONTROL_LAST_PIXEL 21 : 21 -#define DE_CONTROL_LAST_PIXEL_OFF 0 -#define DE_CONTROL_LAST_PIXEL_ON 1 -#define DE_CONTROL_COMMAND 20 : 16 -#define DE_CONTROL_COMMAND_BITBLT 0 -#define DE_CONTROL_COMMAND_RECTANGLE_FILL 1 -#define DE_CONTROL_COMMAND_DE_TILE 2 -#define DE_CONTROL_COMMAND_TRAPEZOID_FILL 3 -#define DE_CONTROL_COMMAND_ALPHA_BLEND 4 -#define DE_CONTROL_COMMAND_RLE_STRIP 5 -#define DE_CONTROL_COMMAND_SHORT_STROKE 6 -#define DE_CONTROL_COMMAND_LINE_DRAW 7 -#define DE_CONTROL_COMMAND_HOST_WRITE 8 -#define DE_CONTROL_COMMAND_HOST_READ 9 -#define DE_CONTROL_COMMAND_HOST_WRITE_BOTTOM_UP 10 -#define DE_CONTROL_COMMAND_ROTATE 11 -#define DE_CONTROL_COMMAND_FONT 12 -#define DE_CONTROL_COMMAND_TEXTURE_LOAD 15 -#define DE_CONTROL_ROP_SELECT 15 : 15 -#define DE_CONTROL_ROP_SELECT_ROP3 0 -#define DE_CONTROL_ROP_SELECT_ROP2 1 -#define DE_CONTROL_ROP2_SOURCE 14 : 14 -#define DE_CONTROL_ROP2_SOURCE_BITMAP 0 -#define DE_CONTROL_ROP2_SOURCE_PATTERN 1 -#define DE_CONTROL_MONO_DATA 13 : 12 -#define DE_CONTROL_MONO_DATA_NOT_PACKED 0 -#define DE_CONTROL_MONO_DATA_8_PACKED 1 -#define DE_CONTROL_MONO_DATA_16_PACKED 2 -#define DE_CONTROL_MONO_DATA_32_PACKED 3 -#define DE_CONTROL_REPEAT_ROTATE 11 : 11 -#define DE_CONTROL_REPEAT_ROTATE_DISABLE 0 -#define DE_CONTROL_REPEAT_ROTATE_ENABLE 1 -#define DE_CONTROL_TRANSPARENCY_MATCH 10 : 10 -#define DE_CONTROL_TRANSPARENCY_MATCH_OPAQUE 0 -#define DE_CONTROL_TRANSPARENCY_MATCH_TRANSPARENT 1 -#define DE_CONTROL_TRANSPARENCY_SELECT 9 : 9 -#define DE_CONTROL_TRANSPARENCY_SELECT_SOURCE 0 -#define DE_CONTROL_TRANSPARENCY_SELECT_DESTINATION 1 -#define DE_CONTROL_TRANSPARENCY 8 : 8 -#define DE_CONTROL_TRANSPARENCY_DISABLE 0 -#define DE_CONTROL_TRANSPARENCY_ENABLE 1 -#define DE_CONTROL_ROP 7 : 0 - -/* Pseudo fields. */ - -#define DE_CONTROL_SHORT_STROKE_DIR 27 : 24 -#define DE_CONTROL_SHORT_STROKE_DIR_225 0 -#define DE_CONTROL_SHORT_STROKE_DIR_135 1 -#define DE_CONTROL_SHORT_STROKE_DIR_315 2 -#define DE_CONTROL_SHORT_STROKE_DIR_45 3 -#define DE_CONTROL_SHORT_STROKE_DIR_270 4 -#define DE_CONTROL_SHORT_STROKE_DIR_90 5 -#define DE_CONTROL_SHORT_STROKE_DIR_180 8 -#define DE_CONTROL_SHORT_STROKE_DIR_0 10 -#define DE_CONTROL_ROTATION 25 : 24 -#define DE_CONTROL_ROTATION_0 0 -#define DE_CONTROL_ROTATION_270 1 -#define DE_CONTROL_ROTATION_90 2 -#define DE_CONTROL_ROTATION_180 3 - -#define DE_PITCH 0x000010 -#define DE_PITCH_DESTINATION 28 : 16 -#define DE_PITCH_SOURCE 12 : 0 - -#define DE_FOREGROUND 0x000014 -#define DE_FOREGROUND_COLOR 31 : 0 - -#define DE_BACKGROUND 0x000018 -#define DE_BACKGROUND_COLOR 31 : 0 - -#define DE_STRETCH_FORMAT 0x00001C -#define DE_STRETCH_FORMAT_PATTERN_XY 30 : 30 -#define DE_STRETCH_FORMAT_PATTERN_XY_NORMAL 0 -#define DE_STRETCH_FORMAT_PATTERN_XY_OVERWRITE 1 -#define DE_STRETCH_FORMAT_PATTERN_Y 29 : 27 -#define DE_STRETCH_FORMAT_PATTERN_X 25 : 23 -#define DE_STRETCH_FORMAT_PIXEL_FORMAT 21 : 20 -#define DE_STRETCH_FORMAT_PIXEL_FORMAT_8 0 -#define DE_STRETCH_FORMAT_PIXEL_FORMAT_16 1 -#define DE_STRETCH_FORMAT_PIXEL_FORMAT_24 3 -#define DE_STRETCH_FORMAT_PIXEL_FORMAT_32 2 -#define DE_STRETCH_FORMAT_ADDRESSING 19 : 16 -#define DE_STRETCH_FORMAT_ADDRESSING_XY 0 -#define DE_STRETCH_FORMAT_ADDRESSING_LINEAR 15 -#define DE_STRETCH_FORMAT_SOURCE_HEIGHT 11 : 0 - -#define DE_COLOR_COMPARE 0x000020 -#define DE_COLOR_COMPARE_COLOR 23 : 0 - -#define DE_COLOR_COMPARE_MASK 0x000024 -#define DE_COLOR_COMPARE_MASK_MASKS 23 : 0 - -#define DE_MASKS 0x000028 -#define DE_MASKS_BYTE_MASK 31 : 16 -#define DE_MASKS_BIT_MASK 15 : 0 - -#define DE_CLIP_TL 0x00002C -#define DE_CLIP_TL_TOP 31 : 16 -#define DE_CLIP_TL_STATUS 13 : 13 -#define DE_CLIP_TL_STATUS_DISABLE 0 -#define DE_CLIP_TL_STATUS_ENABLE 1 -#define DE_CLIP_TL_INHIBIT 12 : 12 -#define DE_CLIP_TL_INHIBIT_OUTSIDE 0 -#define DE_CLIP_TL_INHIBIT_INSIDE 1 -#define DE_CLIP_TL_LEFT 11 : 0 - -#define DE_CLIP_BR 0x000030 -#define DE_CLIP_BR_BOTTOM 31 : 16 -#define DE_CLIP_BR_RIGHT 12 : 0 - -#define DE_MONO_PATTERN_LOW 0x000034 -#define DE_MONO_PATTERN_LOW_PATTERN 31 : 0 - -#define DE_MONO_PATTERN_HIGH 0x000038 -#define DE_MONO_PATTERN_HIGH_PATTERN 31 : 0 - -#define DE_WINDOW_WIDTH 0x00003C -#define DE_WINDOW_WIDTH_DESTINATION 28 : 16 -#define DE_WINDOW_WIDTH_SOURCE 12 : 0 - -#define DE_WINDOW_SOURCE_BASE 0x000040 -#define DE_WINDOW_SOURCE_BASE_EXT 27 : 27 -#define DE_WINDOW_SOURCE_BASE_EXT_LOCAL 0 -#define DE_WINDOW_SOURCE_BASE_EXT_EXTERNAL 1 -#define DE_WINDOW_SOURCE_BASE_CS 26 : 26 -#define DE_WINDOW_SOURCE_BASE_CS_0 0 -#define DE_WINDOW_SOURCE_BASE_CS_1 1 -#define DE_WINDOW_SOURCE_BASE_ADDRESS 25 : 0 - -#define DE_WINDOW_DESTINATION_BASE 0x000044 -#define DE_WINDOW_DESTINATION_BASE_EXT 27 : 27 -#define DE_WINDOW_DESTINATION_BASE_EXT_LOCAL 0 -#define DE_WINDOW_DESTINATION_BASE_EXT_EXTERNAL 1 -#define DE_WINDOW_DESTINATION_BASE_CS 26 : 26 -#define DE_WINDOW_DESTINATION_BASE_CS_0 0 -#define DE_WINDOW_DESTINATION_BASE_CS_1 1 -#define DE_WINDOW_DESTINATION_BASE_ADDRESS 25 : 0 - -#define DE_ALPHA 0x000048 -#define DE_ALPHA_VALUE 7 : 0 - -#define DE_WRAP 0x00004C -#define DE_WRAP_X 31 : 16 -#define DE_WRAP_Y 15 : 0 - -#define DE_STATUS 0x000050 -#define DE_STATUS_CSC 1 : 1 -#define DE_STATUS_CSC_CLEAR 0 -#define DE_STATUS_CSC_NOT_ACTIVE 0 -#define DE_STATUS_CSC_ACTIVE 1 -#define DE_STATUS_2D 0 : 0 -#define DE_STATUS_2D_CLEAR 0 -#define DE_STATUS_2D_NOT_ACTIVE 0 -#define DE_STATUS_2D_ACTIVE 1 - -/* Color Space Conversion registers. */ - -#define CSC_Y_SOURCE_BASE 0x0000C8 -#define CSC_Y_SOURCE_BASE_EXT 27 : 27 -#define CSC_Y_SOURCE_BASE_EXT_LOCAL 0 -#define CSC_Y_SOURCE_BASE_EXT_EXTERNAL 1 -#define CSC_Y_SOURCE_BASE_CS 26 : 26 -#define CSC_Y_SOURCE_BASE_CS_0 0 -#define CSC_Y_SOURCE_BASE_CS_1 1 -#define CSC_Y_SOURCE_BASE_ADDRESS 25 : 0 - -#define CSC_CONSTANTS 0x0000CC -#define CSC_CONSTANTS_Y 31 : 24 -#define CSC_CONSTANTS_R 23 : 16 -#define CSC_CONSTANTS_G 15 : 8 -#define CSC_CONSTANTS_B 7 : 0 - -#define CSC_Y_SOURCE_X 0x0000D0 -#define CSC_Y_SOURCE_X_INTEGER 26 : 16 -#define CSC_Y_SOURCE_X_FRACTION 15 : 3 - -#define CSC_Y_SOURCE_Y 0x0000D4 -#define CSC_Y_SOURCE_Y_INTEGER 27 : 16 -#define CSC_Y_SOURCE_Y_FRACTION 15 : 3 - -#define CSC_U_SOURCE_BASE 0x0000D8 -#define CSC_U_SOURCE_BASE_EXT 27 : 27 -#define CSC_U_SOURCE_BASE_EXT_LOCAL 0 -#define CSC_U_SOURCE_BASE_EXT_EXTERNAL 1 -#define CSC_U_SOURCE_BASE_CS 26 : 26 -#define CSC_U_SOURCE_BASE_CS_0 0 -#define CSC_U_SOURCE_BASE_CS_1 1 -#define CSC_U_SOURCE_BASE_ADDRESS 25 : 0 - -#define CSC_V_SOURCE_BASE 0x0000DC -#define CSC_V_SOURCE_BASE_EXT 27 : 27 -#define CSC_V_SOURCE_BASE_EXT_LOCAL 0 -#define CSC_V_SOURCE_BASE_EXT_EXTERNAL 1 -#define CSC_V_SOURCE_BASE_CS 26 : 26 -#define CSC_V_SOURCE_BASE_CS_0 0 -#define CSC_V_SOURCE_BASE_CS_1 1 -#define CSC_V_SOURCE_BASE_ADDRESS 25 : 0 - -#define CSC_SOURCE_DIMENSION 0x0000E0 -#define CSC_SOURCE_DIMENSION_X 31 : 16 -#define CSC_SOURCE_DIMENSION_Y 15 : 0 - -#define CSC_SOURCE_PITCH 0x0000E4 -#define CSC_SOURCE_PITCH_Y 31 : 16 -#define CSC_SOURCE_PITCH_UV 15 : 0 - -#define CSC_DESTINATION 0x0000E8 -#define CSC_DESTINATION_WRAP 31 : 31 -#define CSC_DESTINATION_WRAP_DISABLE 0 -#define CSC_DESTINATION_WRAP_ENABLE 1 -#define CSC_DESTINATION_X 27 : 16 -#define CSC_DESTINATION_Y 11 : 0 - -#define CSC_DESTINATION_DIMENSION 0x0000EC -#define CSC_DESTINATION_DIMENSION_X 31 : 16 -#define CSC_DESTINATION_DIMENSION_Y 15 : 0 - -#define CSC_DESTINATION_PITCH 0x0000F0 -#define CSC_DESTINATION_PITCH_X 31 : 16 -#define CSC_DESTINATION_PITCH_Y 15 : 0 - -#define CSC_SCALE_FACTOR 0x0000F4 -#define CSC_SCALE_FACTOR_HORIZONTAL 31 : 16 -#define CSC_SCALE_FACTOR_VERTICAL 15 : 0 - -#define CSC_DESTINATION_BASE 0x0000F8 -#define CSC_DESTINATION_BASE_EXT 27 : 27 -#define CSC_DESTINATION_BASE_EXT_LOCAL 0 -#define CSC_DESTINATION_BASE_EXT_EXTERNAL 1 -#define CSC_DESTINATION_BASE_CS 26 : 26 -#define CSC_DESTINATION_BASE_CS_0 0 -#define CSC_DESTINATION_BASE_CS_1 1 -#define CSC_DESTINATION_BASE_ADDRESS 25 : 0 - -#define CSC_CONTROL 0x0000FC -#define CSC_CONTROL_STATUS 31 : 31 -#define CSC_CONTROL_STATUS_STOP 0 -#define CSC_CONTROL_STATUS_START 1 -#define CSC_CONTROL_SOURCE_FORMAT 30 : 28 -#define CSC_CONTROL_SOURCE_FORMAT_YUV422 0 -#define CSC_CONTROL_SOURCE_FORMAT_YUV420I 1 -#define CSC_CONTROL_SOURCE_FORMAT_YUV420 2 -#define CSC_CONTROL_SOURCE_FORMAT_YVU9 3 -#define CSC_CONTROL_SOURCE_FORMAT_IYU1 4 -#define CSC_CONTROL_SOURCE_FORMAT_IYU2 5 -#define CSC_CONTROL_SOURCE_FORMAT_RGB565 6 -#define CSC_CONTROL_SOURCE_FORMAT_RGB8888 7 -#define CSC_CONTROL_DESTINATION_FORMAT 27 : 26 -#define CSC_CONTROL_DESTINATION_FORMAT_RGB565 0 -#define CSC_CONTROL_DESTINATION_FORMAT_RGB8888 1 -#define CSC_CONTROL_HORIZONTAL_FILTER 25 : 25 -#define CSC_CONTROL_HORIZONTAL_FILTER_DISABLE 0 -#define CSC_CONTROL_HORIZONTAL_FILTER_ENABLE 1 -#define CSC_CONTROL_VERTICAL_FILTER 24 : 24 -#define CSC_CONTROL_VERTICAL_FILTER_DISABLE 0 -#define CSC_CONTROL_VERTICAL_FILTER_ENABLE 1 -#define CSC_CONTROL_BYTE_ORDER 23 : 23 -#define CSC_CONTROL_BYTE_ORDER_YUYV 0 -#define CSC_CONTROL_BYTE_ORDER_UYVY 1 - -#define DE_DATA_PORT_501 0x110000 -#define DE_DATA_PORT_712 0x400000 -#define DE_DATA_PORT_722 0x6000 - -/* point to virtual Memory Map IO starting address */ -extern char *smtc_RegBaseAddress; -/* point to virtual video memory starting address */ -extern char *smtc_VRAMBaseAddress; -extern unsigned char smtc_de_busy; - -extern unsigned long memRead32(unsigned long nOffset); -extern void memWrite32(unsigned long nOffset, unsigned long nData); -extern unsigned long SMTC_read2Dreg(unsigned long nOffset); - -/* 2D functions */ -extern void deInit(unsigned int nModeWidth, unsigned int nModeHeight, - unsigned int bpp); - -extern void deWaitForNotBusy(void); - -extern void deVerticalLine(unsigned long dst_base, - unsigned long dst_pitch, - unsigned long nX, - unsigned long nY, - unsigned long dst_height, - unsigned long nColor); - -extern void deHorizontalLine(unsigned long dst_base, - unsigned long dst_pitch, - unsigned long nX, - unsigned long nY, - unsigned long dst_width, - unsigned long nColor); - -extern void deLine(unsigned long dst_base, - unsigned long dst_pitch, - unsigned long nX1, - unsigned long nY1, - unsigned long nX2, - unsigned long nY2, - unsigned long nColor); - -extern void deFillRect(unsigned long dst_base, - unsigned long dst_pitch, - unsigned long dst_X, - unsigned long dst_Y, - unsigned long dst_width, - unsigned long dst_height, - unsigned long nColor); - -extern void deRotatePattern(unsigned char *pattern_dstaddr, - unsigned long pattern_src_addr, - unsigned long pattern_BPP, - unsigned long pattern_stride, - int patternX, - int patternY); - -extern void deCopy(unsigned long dst_base, - unsigned long dst_pitch, - unsigned long dst_BPP, - unsigned long dst_X, - unsigned long dst_Y, - unsigned long dst_width, - unsigned long dst_height, - unsigned long src_base, - unsigned long src_pitch, - unsigned long src_X, - unsigned long src_Y, - pTransparent pTransp, - unsigned char nROP2); - -/* - * System memory to Video memory monochrome expansion. - * - * Source is monochrome image in system memory. This function expands the - * monochrome data to color image in video memory. - * - * @pSrcbuf: pointer to start of source buffer in system memory - * @srcDelta: Pitch value (in bytes) of the source buffer, +ive means top - * down and -ive mean button up - * @startBit: Mono data can start at any bit in a byte, this value should - * be 0 to 7 - * @dBase: Address of destination : offset in frame buffer - * @dPitch: Pitch value of destination surface in BYTE - * @bpp: Color depth of destination surface - * @dx, dy: Starting coordinate of destination surface - * @width, height: width and height of rectange in pixel value - * @fColor,bColor: Foreground, Background color (corresponding to a 1, 0 in - * the monochrome data) - * @rop2: ROP value - */ - -extern long deSystemMem2VideoMemMonoBlt( - const char *pSrcbuf, - long srcDelta, - unsigned long startBit, - unsigned long dBase, - unsigned long dPitch, - unsigned long bpp, - unsigned long dx, unsigned long dy, - unsigned long width, unsigned long height, - unsigned long fColor, - unsigned long bColor, - unsigned long rop2); - -extern unsigned long deGetTransparency(void); -extern void deSetPixelFormat(unsigned long bpp); diff --git a/drivers/staging/sm7xx/smtcfb.c b/drivers/staging/sm7xx/smtcfb.c index a4f6f49..9c82a1a 100644 --- a/drivers/staging/sm7xx/smtcfb.c +++ b/drivers/staging/sm7xx/smtcfb.c @@ -45,7 +45,6 @@ struct screen_info smtc_screen_info; #include "smtcfb.h" -#include "smtc2d.h" #ifdef DEBUG #define smdbg(format, arg...) printk(KERN_DEBUG format , ## arg) @@ -120,10 +119,6 @@ static struct vesa_mode_table vesa_mode[] = { char __iomem *smtc_RegBaseAddress; /* Memory Map IO starting address */ char __iomem *smtc_VRAMBaseAddress; /* video memory starting address */ -char *smtc_2DBaseAddress; /* 2D engine starting address */ -char *smtc_2Ddataport; /* 2D data port offset */ -short smtc_2Dacceleration; - static u32 colreg[17]; static struct par_info hw; /* hardware information */ @@ -135,16 +130,6 @@ u16 smtc_ChipIDs[] = { #define numSMTCchipIDs (sizeof(smtc_ChipIDs) / sizeof(u16)) -void deWaitForNotBusy(void) -{ - unsigned long i = 0x1000000; - while (i--) { - if ((smtc_seqr(0x16) & 0x18) == 0x10) - break; - } - smtc_de_busy = 0; -} - static void sm712_set_timing(struct smtcfb_info *sfb, struct par_info *ppar_info) { @@ -324,7 +309,7 @@ static inline unsigned int chan_to_field(unsigned int chan, return chan << bf->offset; } -static int smtcfb_blank(int blank_mode, struct fb_info *info) +static int cfb_blank(int blank_mode, struct fb_info *info) { /* clear DPMS setting */ switch (blank_mode) { @@ -622,93 +607,13 @@ smtcfb_write(struct fb_info *info, const char __user *buf, size_t count, } #endif /* ! __BIG_ENDIAN */ -#include "smtc2d.c" - -void smtcfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) -{ - struct par_info *p = (struct par_info *)info->par; - - if (smtc_2Dacceleration) { - if (!area->width || !area->height) - return; - - deCopy(p->BaseAddressInVRAM, 0, info->var.bits_per_pixel, - area->dx, area->dy, area->width, area->height, - p->BaseAddressInVRAM, 0, area->sx, area->sy, 0, 0xC); - - } else - cfb_copyarea(info, area); -} - -void smtcfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) -{ - struct par_info *p = (struct par_info *)info->par; - - if (smtc_2Dacceleration) { - if (!rect->width || !rect->height) - return; - if (info->var.bits_per_pixel >= 24) - deFillRect(p->BaseAddressInVRAM, 0, rect->dx * 3, - rect->dy * 3, rect->width * 3, rect->height, - rect->color); - else - deFillRect(p->BaseAddressInVRAM, 0, rect->dx, rect->dy, - rect->width, rect->height, rect->color); - } else - cfb_fillrect(info, rect); -} - -void smtcfb_imageblit(struct fb_info *info, const struct fb_image *image) -{ - struct par_info *p = (struct par_info *)info->par; - u32 bg_col = 0, fg_col = 0; - - if ((smtc_2Dacceleration) && (image->depth == 1)) { - if (smtc_de_busy) - deWaitForNotBusy(); - - switch (info->var.bits_per_pixel) { - case 8: - bg_col = image->bg_color; - fg_col = image->fg_color; - break; - case 16: - bg_col = - ((u32 *) (info->pseudo_palette))[image->bg_color]; - fg_col = - ((u32 *) (info->pseudo_palette))[image->fg_color]; - break; - case 32: - bg_col = - ((u32 *) (info->pseudo_palette))[image->bg_color]; - fg_col = - ((u32 *) (info->pseudo_palette))[image->fg_color]; - break; - } - - deSystemMem2VideoMemMonoBlt( - image->data, - image->width / 8, - 0, - p->BaseAddressInVRAM, - 0, - 0, - image->dx, image->dy, - image->width, image->height, - fg_col, bg_col, - 0x0C); - - } else - cfb_imageblit(info, image); -} - static struct fb_ops smtcfb_ops = { .owner = THIS_MODULE, .fb_setcolreg = smtc_setcolreg, - .fb_blank = smtcfb_blank, - .fb_fillrect = smtcfb_fillrect, - .fb_imageblit = smtcfb_imageblit, - .fb_copyarea = smtcfb_copyarea, + .fb_blank = cfb_blank, + .fb_fillrect = cfb_fillrect, + .fb_imageblit = cfb_imageblit, + .fb_copyarea = cfb_copyarea, #ifdef __BIG_ENDIAN .fb_read = smtcfb_read, .fb_write = smtcfb_write, @@ -772,12 +677,6 @@ void smtcfb_setmode(struct smtcfb_info *sfb) hw.height = sfb->fb.var.yres; hw.hz = 60; smtc_set_timing(sfb, &hw); - if (smtc_2Dacceleration) { - printk("2D acceleration enabled!\n"); - /* Init smtc drawing engine */ - deInit(sfb->fb.var.xres, sfb->fb.var.yres, - sfb->fb.var.bits_per_pixel); - } } /* @@ -1004,9 +903,7 @@ static int __init smtcfb_pci_probe(struct pci_dev *pdev, #endif hw.m_pMMIO = (smtc_RegBaseAddress = smtc_VRAMBaseAddress + 0x00700000); - smtc_2DBaseAddress = (hw.m_pDPR = - smtc_VRAMBaseAddress + 0x00408000); - smtc_2Ddataport = smtc_VRAMBaseAddress + DE_DATA_PORT_712; + hw.m_pDPR = smtc_VRAMBaseAddress + 0x00408000; hw.m_pVPR = hw.m_pLFB + 0x0040c000; #ifdef __BIG_ENDIAN if (sfb->fb.var.bits_per_pixel == 32) { @@ -1035,27 +932,21 @@ static int __init smtcfb_pci_probe(struct pci_dev *pdev, if (sfb->fb.var.bits_per_pixel == 32) smtc_seqw(0x17, 0x30); #endif -#ifdef CONFIG_FB_SM7XX_ACCEL - smtc_2Dacceleration = 1; -#endif break; case 0x720: sfb->fb.fix.mmio_start = pFramebufferPhysical; sfb->fb.fix.mmio_len = 0x00200000; smem_size = SM722_VIDEOMEMORYSIZE; - smtc_2DBaseAddress = (hw.m_pDPR = - ioremap(pFramebufferPhysical, 0x00a00000)); + hw.m_pDPR = ioremap(pFramebufferPhysical, 0x00a00000); hw.m_pLFB = (smtc_VRAMBaseAddress = - smtc_2DBaseAddress + 0x00200000); + hw.m_pDPR + 0x00200000); hw.m_pMMIO = (smtc_RegBaseAddress = - smtc_2DBaseAddress + 0x000c0000); - smtc_2Ddataport = smtc_2DBaseAddress + DE_DATA_PORT_722; - hw.m_pVPR = smtc_2DBaseAddress + 0x800; + hw.m_pDPR + 0x000c0000); + hw.m_pVPR = hw.m_pDPR + 0x800; smtc_seqw(0x62, 0xff); smtc_seqw(0x6a, 0x0d); smtc_seqw(0x6b, 0x02); - smtc_2Dacceleration = 0; break; default: printk(KERN_INFO @@ -1103,7 +994,7 @@ static int __init smtcfb_pci_probe(struct pci_dev *pdev, /* Jason (08/11/2009) PCI_DRV wrapper essential structs */ -static struct pci_device_id smtcfb_pci_table[] = { +static const struct pci_device_id smtcfb_pci_table[] = { {0x126f, 0x710, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {0x126f, 0x712, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {0x126f, 0x720, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, diff --git a/drivers/staging/udlfb/Kconfig b/drivers/staging/udlfb/Kconfig index 641692d..65bd5db 100644 --- a/drivers/staging/udlfb/Kconfig +++ b/drivers/staging/udlfb/Kconfig @@ -1,8 +1,14 @@ config FB_UDL tristate "Displaylink USB Framebuffer support" depends on FB && USB + select FB_MODE_HELPERS + select FB_SYS_FILLRECT + select FB_SYS_COPYAREA + select FB_SYS_IMAGEBLIT + select FB_SYS_FOPS + select FB_DEFERRED_IO ---help--- - This is an experimental driver for DisplayLink USB devices - that provides a framebuffer device. A normal framebuffer can - be used with this driver, or xorg can be run on the device - using it. + This is a kernel framebuffer driver for DisplayLink USB devices. + Supports fbdev clients like xf86-video-fbdev, kdrive, fbi, and + mplayer -vo fbdev. Supports all USB 2.0 era DisplayLink devices. + To compile as a module, choose M here: the module name is udlfb. diff --git a/drivers/staging/udlfb/udlfb.c b/drivers/staging/udlfb/udlfb.c index f5416af..8f6223c 100644 --- a/drivers/staging/udlfb/udlfb.c +++ b/drivers/staging/udlfb/udlfb.c @@ -1,17 +1,20 @@ -/***************************************************************************** - * DLFB Kernel Driver * - * Version 0.2 (udlfb) * - * (C) 2009 Roberto De Ioris <roberto@unbit.it> * - * * - * This file is licensed under the GPLv2. See COPYING in the package. * - * Based on the amazing work of Florian Echtler and libdlo 0.1 * - * * - * * - * 10.06.09 release 0.2.3 (edid ioctl, fallback for unsupported modes) * - * 05.06.09 release 0.2.2 (real screen blanking, rle compression, double buffer) * - * 31.05.09 release 0.2 * - * 22.05.09 First public (ugly) release * - *****************************************************************************/ +/* + * udlfb.c -- Framebuffer driver for DisplayLink USB controller + * + * Copyright (C) 2009 Roberto De Ioris <roberto@unbit.it> + * Copyright (C) 2009 Jaya Kumar <jayakumar.lkml@gmail.com> + * Copyright (C) 2009 Bernie Thompson <bernie@plugable.com> + * + * This file is subject to the terms and conditions of the GNU General Public + * License v2. See the file COPYING in the main directory of this archive for + * more details. + * + * Layout is based on skeletonfb by James Simmons and Geert Uytterhoeven, + * usb-skeleton by GregKH. + * + * Device-specific portions based on information from Displaylink, with work + * from Florian Echtler, Henrik Bjerregaard Pedersen, and others. + */ #include <linux/module.h> #include <linux/kernel.h> @@ -20,606 +23,672 @@ #include <linux/uaccess.h> #include <linux/mm.h> #include <linux/fb.h> -#include <linux/mutex.h> #include <linux/vmalloc.h> #include "udlfb.h" -#define DRIVER_VERSION "DLFB 0.2" +static struct fb_fix_screeninfo dlfb_fix = { + .id = "udlfb", + .type = FB_TYPE_PACKED_PIXELS, + .visual = FB_VISUAL_TRUECOLOR, + .xpanstep = 0, + .ypanstep = 0, + .ywrapstep = 0, + .accel = FB_ACCEL_NONE, +}; -/* memory functions taken from vfb */ +static const u32 udlfb_info_flags = FBINFO_DEFAULT | FBINFO_READS_FAST | +#ifdef FBINFO_VIRTFB + FBINFO_VIRTFB | +#endif + FBINFO_HWACCEL_IMAGEBLIT | FBINFO_HWACCEL_FILLRECT | + FBINFO_HWACCEL_COPYAREA | FBINFO_MISC_ALWAYS_SETPAR; -static void *rvmalloc(unsigned long size) -{ - void *mem; - unsigned long adr; +/* + * There are many DisplayLink-based products, all with unique PIDs. We are able + * to support all volume ones (circa 2009) with a single driver, so we match + * globally on VID. TODO: Probe() needs to detect when we might be running + * "future" chips, and bail on those, so a compatible driver can match. + */ +static struct usb_device_id id_table[] = { + {.idVendor = 0x17e9, .match_flags = USB_DEVICE_ID_MATCH_VENDOR,}, + {}, +}; +MODULE_DEVICE_TABLE(usb, id_table); - size = PAGE_ALIGN(size); - mem = vmalloc_32(size); - if (!mem) - return NULL; +#ifndef CONFIG_FB_DEFERRED_IO +#warning message "kernel FB_DEFFERRED_IO option to support generic fbdev apps" +#endif - memset(mem, 0, size); /* Clear the ram out, no junk to the user */ - adr = (unsigned long)mem; - while (size > 0) { - SetPageReserved(vmalloc_to_page((void *)adr)); - adr += PAGE_SIZE; - size -= PAGE_SIZE; - } +#ifndef CONFIG_FB_SYS_IMAGEBLIT +#ifndef CONFIG_FB_SYS_IMAGEBLIT_MODULE +#warning message "FB_SYS_* in kernel or module option to support fb console" +#endif +#endif - return mem; -} +#ifndef CONFIG_FB_MODE_HELPERS +#warning message "kernel FB_MODE_HELPERS required. Expect build break" +#endif -static void rvfree(void *mem, unsigned long size) -{ - unsigned long adr; +/* dlfb keeps a list of urbs for efficient bulk transfers */ +static void dlfb_urb_completion(struct urb *urb); +static struct urb *dlfb_get_urb(struct dlfb_data *dev); +static int dlfb_submit_urb(struct dlfb_data *dev, struct urb * urb, size_t len); +static int dlfb_alloc_urb_list(struct dlfb_data *dev, int count, size_t size); +static void dlfb_free_urb_list(struct dlfb_data *dev); - if (!mem) - return; +/* other symbols with dependents */ +#ifdef CONFIG_FB_DEFERRED_IO +static struct fb_deferred_io dlfb_defio; +#endif - adr = (unsigned long)mem; - while ((long)size > 0) { - ClearPageReserved(vmalloc_to_page((void *)adr)); - adr += PAGE_SIZE; - size -= PAGE_SIZE; - } - vfree(mem); +/* + * All DisplayLink bulk operations start with 0xAF, followed by specific code + * All operations are written to buffers which then later get sent to device + */ +static char *dlfb_set_register(char *buf, u8 reg, u8 val) +{ + *buf++ = 0xAF; + *buf++ = 0x20; + *buf++ = reg; + *buf++ = val; + return buf; } -static int dlfb_mmap(struct fb_info *info, struct vm_area_struct *vma) +static char *dlfb_vidreg_lock(char *buf) { - unsigned long start = vma->vm_start; - unsigned long size = vma->vm_end - vma->vm_start; - unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; - unsigned long page, pos; - - printk("MMAP: %lu %u\n", offset + size, info->fix.smem_len); - - if (offset + size > info->fix.smem_len) - return -EINVAL; - - pos = (unsigned long)info->fix.smem_start + offset; - - while (size > 0) { - page = vmalloc_to_pfn((void *)pos); - if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) - return -EAGAIN; - - start += PAGE_SIZE; - pos += PAGE_SIZE; - if (size > PAGE_SIZE) - size -= PAGE_SIZE; - else - size = 0; - } - - vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */ - return 0; - + return dlfb_set_register(buf, 0xFF, 0x00); } -/* ioctl structure */ -struct dloarea { - int x, y; - int w, h; - int x2, y2; -}; +static char *dlfb_vidreg_unlock(char *buf) +{ + return dlfb_set_register(buf, 0xFF, 0xFF); +} /* -static struct usb_device_id id_table [] = { - { USB_DEVICE(0x17e9, 0x023d) }, - { } -}; -*/ + * On/Off for driving the DisplayLink framebuffer to the display + */ +static char *dlfb_enable_hvsync(char *buf, bool enable) +{ + if (enable) + return dlfb_set_register(buf, 0x1F, 0x00); + else + return dlfb_set_register(buf, 0x1F, 0x01); +} -static struct usb_device_id id_table[] = { - {.idVendor = 0x17e9, .match_flags = USB_DEVICE_ID_MATCH_VENDOR,}, - {}, -}; -MODULE_DEVICE_TABLE(usb, id_table); +static char *dlfb_set_color_depth(char *buf, u8 selection) +{ + return dlfb_set_register(buf, 0x00, selection); +} -static struct usb_driver dlfb_driver; +static char *dlfb_set_base16bpp(char *wrptr, u32 base) +{ + /* the base pointer is 16 bits wide, 0x20 is hi byte. */ + wrptr = dlfb_set_register(wrptr, 0x20, base >> 16); + wrptr = dlfb_set_register(wrptr, 0x21, base >> 8); + return dlfb_set_register(wrptr, 0x22, base); +} -// thanks to Henrik Bjerregaard Pedersen for this function -static char *rle_compress16(uint16_t * src, char *dst, int rem) +/* + * DisplayLink HW has separate 16bpp and 8bpp framebuffers. + * In 24bpp modes, the low 323 RGB bits go in the 8bpp framebuffer + */ +static char *dlfb_set_base8bpp(char *wrptr, u32 base) { + wrptr = dlfb_set_register(wrptr, 0x26, base >> 16); + wrptr = dlfb_set_register(wrptr, 0x27, base >> 8); + return dlfb_set_register(wrptr, 0x28, base); +} - int rl; - uint16_t pix0; - char *end_if_raw = dst + 6 + 2 * rem; +static char *dlfb_set_register_16(char *wrptr, u8 reg, u16 value) +{ + wrptr = dlfb_set_register(wrptr, reg, value >> 8); + return dlfb_set_register(wrptr, reg+1, value); +} - dst += 6; // header will be filled in if RLE is worth it +/* + * This is kind of weird because the controller takes some + * register values in a different byte order than other registers. + */ +static char *dlfb_set_register_16be(char *wrptr, u8 reg, u16 value) +{ + wrptr = dlfb_set_register(wrptr, reg, value); + return dlfb_set_register(wrptr, reg+1, value >> 8); +} - while (rem && dst < end_if_raw) { - char *start = (char *)src; +/* + * LFSR is linear feedback shift register. The reason we have this is + * because the display controller needs to minimize the clock depth of + * various counters used in the display path. So this code reverses the + * provided value into the lfsr16 value by counting backwards to get + * the value that needs to be set in the hardware comparator to get the + * same actual count. This makes sense once you read above a couple of + * times and think about it from a hardware perspective. + */ +static u16 dlfb_lfsr16(u16 actual_count) +{ + u32 lv = 0xFFFF; /* This is the lfsr value that the hw starts with */ - pix0 = *src++; - rl = 1; - rem--; - while (rem && *src == pix0) - rem--, rl++, src++; - *dst++ = rl; - *dst++ = start[1]; - *dst++ = start[0]; + while (actual_count--) { + lv = ((lv << 1) | + (((lv >> 15) ^ (lv >> 4) ^ (lv >> 2) ^ (lv >> 1)) & 1)) + & 0xFFFF; } - return dst; + return (u16) lv; } /* -Thanks to Henrik Bjerregaard Pedersen for rle implementation and code refactoring. -Next step is huffman compression. -*/ - -static int -image_blit(struct dlfb_data *dev_info, int x, int y, int width, int height, - char *data) + * This does LFSR conversion on the value that is to be written. + * See LFSR explanation above for more detail. + */ +static char *dlfb_set_register_lfsr16(char *wrptr, u8 reg, u16 value) { + return dlfb_set_register_16(wrptr, reg, dlfb_lfsr16(value)); +} - int i, j, base; - int rem = width; - int ret; - - int firstdiff, thistime; - - char *bufptr; - - if (x + width > dev_info->info->var.xres) - return -EINVAL; - - if (y + height > dev_info->info->var.yres) - return -EINVAL; +/* + * This takes a standard fbdev screeninfo struct and all of its monitor mode + * details and converts them into the DisplayLink equivalent register commands. + */ +static char *dlfb_set_vid_cmds(char *wrptr, struct fb_var_screeninfo *var) +{ + u16 xds, yds; + u16 xde, yde; + u16 yec; - mutex_lock(&dev_info->bulk_mutex); + /* x display start */ + xds = var->left_margin + var->hsync_len; + wrptr = dlfb_set_register_lfsr16(wrptr, 0x01, xds); + /* x display end */ + xde = xds + var->xres; + wrptr = dlfb_set_register_lfsr16(wrptr, 0x03, xde); - base = - dev_info->base16 + ((dev_info->info->var.xres * 2 * y) + (x * 2)); + /* y display start */ + yds = var->upper_margin + var->vsync_len; + wrptr = dlfb_set_register_lfsr16(wrptr, 0x05, yds); + /* y display end */ + yde = yds + var->yres; + wrptr = dlfb_set_register_lfsr16(wrptr, 0x07, yde); - data += (dev_info->info->var.xres * 2 * y) + (x * 2); + /* x end count is active + blanking - 1 */ + wrptr = dlfb_set_register_lfsr16(wrptr, 0x09, + xde + var->right_margin - 1); - /* printk("IMAGE_BLIT\n"); */ + /* libdlo hardcodes hsync start to 1 */ + wrptr = dlfb_set_register_lfsr16(wrptr, 0x0B, 1); - bufptr = dev_info->buf; + /* hsync end is width of sync pulse + 1 */ + wrptr = dlfb_set_register_lfsr16(wrptr, 0x0D, var->hsync_len + 1); - for (i = y; i < y + height; i++) { + /* hpixels is active pixels */ + wrptr = dlfb_set_register_16(wrptr, 0x0F, var->xres); - if (dev_info->bufend - bufptr < BUF_HIGH_WATER_MARK) { - ret = dlfb_bulk_msg(dev_info, bufptr - dev_info->buf); - bufptr = dev_info->buf; - } + /* yendcount is vertical active + vertical blanking */ + yec = var->yres + var->upper_margin + var->lower_margin + + var->vsync_len; + wrptr = dlfb_set_register_lfsr16(wrptr, 0x11, yec); - rem = width; + /* libdlo hardcodes vsync start to 0 */ + wrptr = dlfb_set_register_lfsr16(wrptr, 0x13, 0); - /* printk("WRITING LINE %d\n", i); */ + /* vsync end is width of vsync pulse */ + wrptr = dlfb_set_register_lfsr16(wrptr, 0x15, var->vsync_len); - while (rem) { + /* vpixels is active pixels */ + wrptr = dlfb_set_register_16(wrptr, 0x17, var->yres); - if (dev_info->bufend - bufptr < BUF_HIGH_WATER_MARK) { - ret = - dlfb_bulk_msg(dev_info, - bufptr - dev_info->buf); - bufptr = dev_info->buf; - } - // number of pixels to consider this time - thistime = rem; - if (thistime > 255) - thistime = 255; - - // find position of first pixel that has changed - firstdiff = -1; - for (j = 0; j < thistime * 2; j++) { - if (dev_info->backing_buffer - [base - dev_info->base16 + j] != data[j]) { - firstdiff = j / 2; - break; - } - } + /* convert picoseconds to 5kHz multiple for pclk5k = x * 1E12/5k */ + wrptr = dlfb_set_register_16be(wrptr, 0x1B, + 200*1000*1000/var->pixclock); - if (firstdiff >= 0) { - char *end_of_rle; - - end_of_rle = - rle_compress16((uint16_t *) (data + - firstdiff * 2), - bufptr, - thistime - firstdiff); - - if (end_of_rle < - bufptr + 6 + 2 * (thistime - firstdiff)) { - bufptr[0] = 0xAF; - bufptr[1] = 0x69; - - bufptr[2] = - (char)((base + - firstdiff * 2) >> 16); - bufptr[3] = - (char)((base + firstdiff * 2) >> 8); - bufptr[4] = - (char)(base + firstdiff * 2); - bufptr[5] = thistime - firstdiff; - - bufptr = end_of_rle; - - } else { - // fallback to raw (or some other encoding?) - *bufptr++ = 0xAF; - *bufptr++ = 0x68; - - *bufptr++ = - (char)((base + - firstdiff * 2) >> 16); - *bufptr++ = - (char)((base + firstdiff * 2) >> 8); - *bufptr++ = - (char)(base + firstdiff * 2); - *bufptr++ = thistime - firstdiff; - // PUT COMPRESSION HERE - for (j = firstdiff * 2; - j < thistime * 2; j += 2) { - *bufptr++ = data[j + 1]; - *bufptr++ = data[j]; - } - } - } + return wrptr; +} - base += thistime * 2; - data += thistime * 2; - rem -= thistime; - } +/* + * This takes a standard fbdev screeninfo struct that was fetched or prepared + * and then generates the appropriate command sequence that then drives the + * display controller. + */ +static int dlfb_set_video_mode(struct dlfb_data *dev, + struct fb_var_screeninfo *var) +{ + char *buf; + char *wrptr; + int retval = 0; + int writesize; + struct urb *urb; - memcpy(dev_info->backing_buffer + (base - dev_info->base16) - - (width * 2), data - (width * 2), width * 2); + if (!atomic_read(&dev->usb_active)) + return -EPERM; - base += (dev_info->info->var.xres * 2) - (width * 2); - data += (dev_info->info->var.xres * 2) - (width * 2); + urb = dlfb_get_urb(dev); + if (!urb) + return -ENOMEM; + buf = (char *) urb->transfer_buffer; - } + /* + * This first section has to do with setting the base address on the + * controller * associated with the display. There are 2 base + * pointers, currently, we only * use the 16 bpp segment. + */ + wrptr = dlfb_vidreg_lock(buf); + wrptr = dlfb_set_color_depth(wrptr, 0x00); + /* set base for 16bpp segment to 0 */ + wrptr = dlfb_set_base16bpp(wrptr, 0); + /* set base for 8bpp segment to end of fb */ + wrptr = dlfb_set_base8bpp(wrptr, dev->info->fix.smem_len); - if (bufptr > dev_info->buf) { - ret = dlfb_bulk_msg(dev_info, bufptr - dev_info->buf); - } + wrptr = dlfb_set_vid_cmds(wrptr, var); + wrptr = dlfb_enable_hvsync(wrptr, true); + wrptr = dlfb_vidreg_unlock(wrptr); - mutex_unlock(&dev_info->bulk_mutex); + writesize = wrptr - buf; - return base; + retval = dlfb_submit_urb(dev, urb, writesize); + return retval; } -static int -draw_rect(struct dlfb_data *dev_info, int x, int y, int width, int height, - unsigned char red, unsigned char green, unsigned char blue) +static int dlfb_ops_mmap(struct fb_info *info, struct vm_area_struct *vma) { + unsigned long start = vma->vm_start; + unsigned long size = vma->vm_end - vma->vm_start; + unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; + unsigned long page, pos; + struct dlfb_data *dev = info->par; - int i, j, base; - int ret; - unsigned short col = - (((((red) & 0xF8) | ((green) >> 5)) & 0xFF) << 8) + - (((((green) & 0x1C) << 3) | ((blue) >> 3)) & 0xFF); - int rem = width; - - char *bufptr; + dl_notice("MMAP: %lu %u\n", offset + size, info->fix.smem_len); - if (x + width > dev_info->info->var.xres) + if (offset + size > info->fix.smem_len) return -EINVAL; - if (y + height > dev_info->info->var.yres) - return -EINVAL; + pos = (unsigned long)info->fix.smem_start + offset; - mutex_lock(&dev_info->bulk_mutex); + while (size > 0) { + page = vmalloc_to_pfn((void *)pos); + if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) + return -EAGAIN; - base = dev_info->base16 + (dev_info->info->var.xres * 2 * y) + (x * 2); + start += PAGE_SIZE; + pos += PAGE_SIZE; + if (size > PAGE_SIZE) + size -= PAGE_SIZE; + else + size = 0; + } - bufptr = dev_info->buf; + vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */ + return 0; - for (i = y; i < y + height; i++) { +} - for (j = 0; j < width * 2; j += 2) { - dev_info->backing_buffer[base - dev_info->base16 + j] = - (char)(col >> 8); - dev_info->backing_buffer[base - dev_info->base16 + j + - 1] = (char)(col); - } - if (dev_info->bufend - bufptr < BUF_HIGH_WATER_MARK) { - ret = dlfb_bulk_msg(dev_info, bufptr - dev_info->buf); - bufptr = dev_info->buf; +/* + * Trims identical data from front and back of line + * Sets new front buffer address and width + * And returns byte count of identical pixels + * Assumes CPU natural alignment (unsigned long) + * for back and front buffer ptrs and width + */ +static int dlfb_trim_hline(const u8 *bback, const u8 **bfront, int *width_bytes) +{ + int j, k; + const unsigned long *back = (const unsigned long *) bback; + const unsigned long *front = (const unsigned long *) *bfront; + const int width = *width_bytes / sizeof(unsigned long); + int identical = width; + int start = width; + int end = width; + + prefetch((void *) front); + prefetch((void *) back); + + for (j = 0; j < width; j++) { + if (back[j] != front[j]) { + start = j; + break; } + } - rem = width; - - while (rem) { - - if (dev_info->bufend - bufptr < BUF_HIGH_WATER_MARK) { - ret = - dlfb_bulk_msg(dev_info, - bufptr - dev_info->buf); - bufptr = dev_info->buf; - } - - *bufptr++ = 0xAF; - *bufptr++ = 0x69; - - *bufptr++ = (char)(base >> 16); - *bufptr++ = (char)(base >> 8); - *bufptr++ = (char)(base); - - if (rem > 255) { - *bufptr++ = 255; - *bufptr++ = 255; - rem -= 255; - base += 255 * 2; - } else { - *bufptr++ = rem; - *bufptr++ = rem; - base += rem * 2; - rem = 0; - } - - *bufptr++ = (char)(col >> 8); - *bufptr++ = (char)(col); - + for (k = width - 1; k > j; k--) { + if (back[k] != front[k]) { + end = k+1; + break; } - - base += (dev_info->info->var.xres * 2) - (width * 2); - } - if (bufptr > dev_info->buf) - ret = dlfb_bulk_msg(dev_info, bufptr - dev_info->buf); + identical = start + (width - end); + *bfront = (u8 *) &front[start]; + *width_bytes = (end - start) * sizeof(unsigned long); - mutex_unlock(&dev_info->bulk_mutex); - - return 1; + return identical * sizeof(unsigned long); } -static void swapfb(struct dlfb_data *dev_info) +/* +Render a command stream for an encoded horizontal line segment of pixels. + +A command buffer holds several commands. +It always begins with a fresh command header +(the protocol doesn't require this, but we enforce it to allow +multiple buffers to be potentially encoded and sent in parallel). +A single command encodes one contiguous horizontal line of pixels + +The function relies on the client to do all allocation, so that +rendering can be done directly to output buffers (e.g. USB URBs). +The function fills the supplied command buffer, providing information +on where it left off, so the client may call in again with additional +buffers if the line will take several buffers to complete. + +A single command can transmit a maximum of 256 pixels, +regardless of the compression ratio (protocol design limit). +To the hardware, 0 for a size byte means 256 + +Rather than 256 pixel commands which are either rl or raw encoded, +the rlx command simply assumes alternating raw and rl spans within one cmd. +This has a slightly larger header overhead, but produces more even results. +It also processes all data (read and write) in a single pass. +Performance benchmarks of common cases show it having just slightly better +compression than 256 pixel raw -or- rle commands, with similar CPU consumpion. +But for very rl friendly data, will compress not quite as well. +*/ +static void dlfb_compress_hline( + const uint16_t **pixel_start_ptr, + const uint16_t *const pixel_end, + uint32_t *device_address_ptr, + uint8_t **command_buffer_ptr, + const uint8_t *const cmd_buffer_end) { + const uint16_t *pixel = *pixel_start_ptr; + uint32_t dev_addr = *device_address_ptr; + uint8_t *cmd = *command_buffer_ptr; + const int bpp = 2; + + while ((pixel_end > pixel) && + (cmd_buffer_end - MIN_RLX_CMD_BYTES > cmd)) { + uint8_t *raw_pixels_count_byte = 0; + uint8_t *cmd_pixels_count_byte = 0; + const uint16_t *raw_pixel_start = 0; + const uint16_t *cmd_pixel_start, *cmd_pixel_end = 0; + const uint32_t be_dev_addr = cpu_to_be32(dev_addr); + + prefetchw((void *) cmd); /* pull in one cache line at least */ + + *cmd++ = 0xAF; + *cmd++ = 0x6B; + *cmd++ = (uint8_t) ((be_dev_addr >> 8) & 0xFF); + *cmd++ = (uint8_t) ((be_dev_addr >> 16) & 0xFF); + *cmd++ = (uint8_t) ((be_dev_addr >> 24) & 0xFF); + + cmd_pixels_count_byte = cmd++; /* we'll know this later */ + cmd_pixel_start = pixel; + + raw_pixels_count_byte = cmd++; /* we'll know this later */ + raw_pixel_start = pixel; + + cmd_pixel_end = pixel + min(MAX_CMD_PIXELS + 1, + min((int)(pixel_end - pixel), + (int)(cmd_buffer_end - cmd) / bpp)); + + prefetch_range((void *) pixel, (cmd_pixel_end - pixel) * bpp); + + while (pixel < cmd_pixel_end) { + const uint16_t * const repeating_pixel = pixel; + + *(uint16_t *)cmd = cpu_to_be16p(pixel); + cmd += 2; + pixel++; + + if (unlikely((pixel < cmd_pixel_end) && + (*pixel == *repeating_pixel))) { + /* go back and fill in raw pixel count */ + *raw_pixels_count_byte = ((repeating_pixel - + raw_pixel_start) + 1) & 0xFF; + + while ((pixel < cmd_pixel_end) + && (*pixel == *repeating_pixel)) { + pixel++; + } - int tmpbase; - char *bufptr; - - mutex_lock(&dev_info->bulk_mutex); - - tmpbase = dev_info->base16; - - dev_info->base16 = dev_info->base16d; - dev_info->base16d = tmpbase; + /* immediately after raw data is repeat byte */ + *cmd++ = ((pixel - repeating_pixel) - 1) & 0xFF; - bufptr = dev_info->buf; + /* Then start another raw pixel span */ + raw_pixel_start = pixel; + raw_pixels_count_byte = cmd++; + } + } - bufptr = dlfb_set_register(bufptr, 0xFF, 0x00); + if (pixel > raw_pixel_start) { + /* finalize last RAW span */ + *raw_pixels_count_byte = (pixel-raw_pixel_start) & 0xFF; + } - // set addresses - bufptr = - dlfb_set_register(bufptr, 0x20, (char)(dev_info->base16 >> 16)); - bufptr = dlfb_set_register(bufptr, 0x21, (char)(dev_info->base16 >> 8)); - bufptr = dlfb_set_register(bufptr, 0x22, (char)(dev_info->base16)); + *cmd_pixels_count_byte = (pixel - cmd_pixel_start) & 0xFF; + dev_addr += (pixel - cmd_pixel_start) * bpp; + } - bufptr = dlfb_set_register(bufptr, 0xFF, 0x00); + if (cmd_buffer_end <= MIN_RLX_CMD_BYTES + cmd) { + /* Fill leftover bytes with no-ops */ + if (cmd_buffer_end > cmd) + memset(cmd, 0xAF, cmd_buffer_end - cmd); + cmd = (uint8_t *) cmd_buffer_end; + } - dlfb_bulk_msg(dev_info, bufptr - dev_info->buf); + *command_buffer_ptr = cmd; + *pixel_start_ptr = pixel; + *device_address_ptr = dev_addr; - mutex_unlock(&dev_info->bulk_mutex); + return; } -static int copyfb(struct dlfb_data *dev_info) +/* + * There are 3 copies of every pixel: The front buffer that the fbdev + * client renders to, the actual framebuffer across the USB bus in hardware + * (that we can only write to, slowly, and can never read), and (optionally) + * our shadow copy that tracks what's been sent to that hardware buffer. + */ +static void dlfb_render_hline(struct dlfb_data *dev, struct urb **urb_ptr, + const char *front, char **urb_buf_ptr, + u32 byte_offset, u32 byte_width, + int *ident_ptr, int *sent_ptr) { - int base; - int source; - int rem; - int i, ret; - - char *bufptr; - - base = dev_info->base16d; - - mutex_lock(&dev_info->bulk_mutex); - - source = dev_info->base16; - - bufptr = dev_info->buf; - - for (i = 0; i < dev_info->info->var.yres; i++) { - - if (dev_info->bufend - bufptr < BUF_HIGH_WATER_MARK) { - ret = dlfb_bulk_msg(dev_info, bufptr - dev_info->buf); - bufptr = dev_info->buf; - } - - rem = dev_info->info->var.xres; - - while (rem) { - - if (dev_info->bufend - bufptr < BUF_HIGH_WATER_MARK) { - ret = - dlfb_bulk_msg(dev_info, - bufptr - dev_info->buf); - bufptr = dev_info->buf; - - } - - *bufptr++ = 0xAF; - *bufptr++ = 0x6A; - - *bufptr++ = (char)(base >> 16); - *bufptr++ = (char)(base >> 8); - *bufptr++ = (char)(base); - - if (rem > 255) { - *bufptr++ = 255; - *bufptr++ = (char)(source >> 16); - *bufptr++ = (char)(source >> 8); - *bufptr++ = (char)(source); - - rem -= 255; - base += 255 * 2; - source += 255 * 2; - - } else { - *bufptr++ = rem; - *bufptr++ = (char)(source >> 16); - *bufptr++ = (char)(source >> 8); - *bufptr++ = (char)(source); + const u8 *line_start, *line_end, *next_pixel; + u32 dev_addr = dev->base16 + byte_offset; + struct urb *urb = *urb_ptr; + u8 *cmd = *urb_buf_ptr; + u8 *cmd_end = (u8 *) urb->transfer_buffer + urb->transfer_buffer_length; + + line_start = (u8 *) (front + byte_offset); + next_pixel = line_start; + line_end = next_pixel + byte_width; + + if (dev->backing_buffer) { + int offset; + const u8 *back_start = (u8 *) (dev->backing_buffer + + byte_offset); + + *ident_ptr += dlfb_trim_hline(back_start, &next_pixel, + &byte_width); + + offset = next_pixel - line_start; + line_end = next_pixel + byte_width; + dev_addr += offset; + back_start += offset; + line_start += offset; + + memcpy((char *)back_start, (char *) line_start, + byte_width); + } - base += rem * 2; - source += rem * 2; - rem = 0; - } + while (next_pixel < line_end) { + + dlfb_compress_hline((const uint16_t **) &next_pixel, + (const uint16_t *) line_end, &dev_addr, + (u8 **) &cmd, (u8 *) cmd_end); + + if (cmd >= cmd_end) { + int len = cmd - (u8 *) urb->transfer_buffer; + if (dlfb_submit_urb(dev, urb, len)) + return; /* lost pixels is set */ + *sent_ptr += len; + urb = dlfb_get_urb(dev); + if (!urb) + return; /* lost_pixels is set */ + *urb_ptr = urb; + cmd = urb->transfer_buffer; + cmd_end = &cmd[urb->transfer_buffer_length]; } } - if (bufptr > dev_info->buf) - ret = dlfb_bulk_msg(dev_info, bufptr - dev_info->buf); - - mutex_unlock(&dev_info->bulk_mutex); - - return 1; - + *urb_buf_ptr = cmd; } -static int -copyarea(struct dlfb_data *dev_info, int dx, int dy, int sx, int sy, - int width, int height) +int dlfb_handle_damage(struct dlfb_data *dev, int x, int y, + int width, int height, char *data) { - int base; - int source; - int rem; int i, ret; - - char *bufptr; - - if (dx + width > dev_info->info->var.xres) + char *cmd; + cycles_t start_cycles, end_cycles; + int bytes_sent = 0; + int bytes_identical = 0; + struct urb *urb; + int aligned_x; + + start_cycles = get_cycles(); + + aligned_x = DL_ALIGN_DOWN(x, sizeof(unsigned long)); + width = DL_ALIGN_UP(width + (x-aligned_x), sizeof(unsigned long)); + x = aligned_x; + + if ((width <= 0) || + (x + width > dev->info->var.xres) || + (y + height > dev->info->var.yres)) return -EINVAL; - if (dy + height > dev_info->info->var.yres) - return -EINVAL; - - mutex_lock(&dev_info->bulk_mutex); + if (!atomic_read(&dev->usb_active)) + return 0; - base = - dev_info->base16 + (dev_info->info->var.xres * 2 * dy) + (dx * 2); - source = (dev_info->info->var.xres * 2 * sy) + (sx * 2); + urb = dlfb_get_urb(dev); + if (!urb) + return 0; + cmd = urb->transfer_buffer; - bufptr = dev_info->buf; + for (i = y; i < y + height ; i++) { + const int line_offset = dev->info->fix.line_length * i; + const int byte_offset = line_offset + (x * BPP); - for (i = sy; i < sy + height; i++) { + dlfb_render_hline(dev, &urb, (char *) dev->info->fix.smem_start, + &cmd, byte_offset, width * BPP, + &bytes_identical, &bytes_sent); + } - memcpy(dev_info->backing_buffer + base - dev_info->base16, - dev_info->backing_buffer + source, width * 2); + if (cmd > (char *) urb->transfer_buffer) { + /* Send partial buffer remaining before exiting */ + int len = cmd - (char *) urb->transfer_buffer; + ret = dlfb_submit_urb(dev, urb, len); + bytes_sent += len; + } else + dlfb_urb_completion(urb); + + atomic_add(bytes_sent, &dev->bytes_sent); + atomic_add(bytes_identical, &dev->bytes_identical); + atomic_add(width*height*2, &dev->bytes_rendered); + end_cycles = get_cycles(); + atomic_add(((unsigned int) ((end_cycles - start_cycles) + >> 10)), /* Kcycles */ + &dev->cpu_kcycles_used); - if (dev_info->bufend - bufptr < BUF_HIGH_WATER_MARK) { - ret = dlfb_bulk_msg(dev_info, bufptr - dev_info->buf); - bufptr = dev_info->buf; - } - - rem = width; + return 0; +} - while (rem) { +/* hardware has native COPY command (see libdlo), but not worth it for fbcon */ +static void dlfb_ops_copyarea(struct fb_info *info, + const struct fb_copyarea *area) +{ - if (dev_info->bufend - bufptr < BUF_HIGH_WATER_MARK) { - ret = - dlfb_bulk_msg(dev_info, - bufptr - dev_info->buf); - bufptr = dev_info->buf; - } + struct dlfb_data *dev = info->par; - *bufptr++ = 0xAF; - *bufptr++ = 0x6A; +#if defined CONFIG_FB_SYS_COPYAREA || defined CONFIG_FB_SYS_COPYAREA_MODULE - *bufptr++ = (char)(base >> 16); - *bufptr++ = (char)(base >> 8); - *bufptr++ = (char)(base); + sys_copyarea(info, area); - if (rem > 255) { - *bufptr++ = 255; - *bufptr++ = (char)(source >> 16); - *bufptr++ = (char)(source >> 8); - *bufptr++ = (char)(source); + dlfb_handle_damage(dev, area->dx, area->dy, + area->width, area->height, info->screen_base); +#endif + atomic_inc(&dev->copy_count); - rem -= 255; - base += 255 * 2; - source += 255 * 2; +} - } else { - *bufptr++ = rem; - *bufptr++ = (char)(source >> 16); - *bufptr++ = (char)(source >> 8); - *bufptr++ = (char)(source); +static void dlfb_ops_imageblit(struct fb_info *info, + const struct fb_image *image) +{ + struct dlfb_data *dev = info->par; - base += rem * 2; - source += rem * 2; - rem = 0; - } - } +#if defined CONFIG_FB_SYS_IMAGEBLIT || defined CONFIG_FB_SYS_IMAGEBLIT_MODULE - base += (dev_info->info->var.xres * 2) - (width * 2); - source += (dev_info->info->var.xres * 2) - (width * 2); - } + sys_imageblit(info, image); - if (bufptr > dev_info->buf) - ret = dlfb_bulk_msg(dev_info, bufptr - dev_info->buf); + dlfb_handle_damage(dev, image->dx, image->dy, + image->width, image->height, info->screen_base); - mutex_unlock(&dev_info->bulk_mutex); +#endif - return 1; + atomic_inc(&dev->blit_count); } -static void dlfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) +static void dlfb_ops_fillrect(struct fb_info *info, + const struct fb_fillrect *rect) { - struct dlfb_data *dev = info->par; - copyarea(dev, area->dx, area->dy, area->sx, area->sy, area->width, - area->height); +#if defined CONFIG_FB_SYS_FILLRECT || defined CONFIG_FB_SYS_FILLRECT_MODULE - /* printk("COPY AREA %d %d %d %d %d %d !!!\n", area->dx, area->dy, area->sx, area->sy, area->width, area->height); */ + sys_fillrect(info, rect); -} + dlfb_handle_damage(dev, rect->dx, rect->dy, rect->width, + rect->height, info->screen_base); +#endif -static void dlfb_imageblit(struct fb_info *info, const struct fb_image *image) -{ + atomic_inc(&dev->fill_count); - int ret; - struct dlfb_data *dev = info->par; - /* printk("IMAGE BLIT (1) %d %d %d %d DEPTH %d {%p}!!!\n", image->dx, image->dy, image->width, image->height, image->depth, dev->udev); */ - cfb_imageblit(info, image); - ret = - image_blit(dev, image->dx, image->dy, image->width, image->height, - info->screen_base); - /* printk("IMAGE BLIT (2) %d %d %d %d DEPTH %d {%p} %d!!!\n", image->dx, image->dy, image->width, image->height, image->depth, dev->udev, ret); */ } -static void dlfb_fillrect(struct fb_info *info, - const struct fb_fillrect *region) +static void dlfb_get_edid(struct dlfb_data *dev) { - - unsigned char red, green, blue; - struct dlfb_data *dev = info->par; - - memcpy(&red, ®ion->color, 1); - memcpy(&green, ®ion->color + 1, 1); - memcpy(&blue, ®ion->color + 2, 1); - draw_rect(dev, region->dx, region->dy, region->width, region->height, - red, green, blue); - /* printk("FILL RECT %d %d !!!\n", region->dx, region->dy); */ - + int i; + int ret; + char rbuf[2]; + + for (i = 0; i < sizeof(dev->edid); i++) { + ret = usb_control_msg(dev->udev, + usb_rcvctrlpipe(dev->udev, 0), (0x02), + (0x80 | (0x02 << 5)), i << 8, 0xA1, rbuf, 2, + 0); + dev->edid[i] = rbuf[1]; + } } -static int dlfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) +static int dlfb_ops_ioctl(struct fb_info *info, unsigned int cmd, + unsigned long arg) { - struct dlfb_data *dev_info = info->par; + struct dlfb_data *dev = info->par; struct dloarea *area = NULL; - if (cmd == 0xAD) { + if (!atomic_read(&dev->usb_active)) + return 0; + + /* TODO: Update X server to get this from sysfs instead */ + if (cmd == DLFB_IOCTL_RETURN_EDID) { char *edid = (char *)arg; - dlfb_edid(dev_info); - if (copy_to_user(edid, dev_info->edid, 128)) { + dlfb_get_edid(dev); + if (copy_to_user(edid, dev->edid, sizeof(dev->edid))) return -EFAULT; - } return 0; } - if (cmd == 0xAA || cmd == 0xAB || cmd == 0xAC) { + /* TODO: Help propose a standard fb.h ioctl to report mmap damage */ + if (cmd == DLFB_IOCTL_REPORT_DAMAGE) { area = (struct dloarea *)arg; @@ -634,36 +703,20 @@ static int dlfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) if (area->y > info->var.yres) area->y = info->var.yres; - } - if (cmd == 0xAA) { - image_blit(dev_info, area->x, area->y, area->w, area->h, + atomic_set(&dev->use_defio, 0); + + dlfb_handle_damage(dev, area->x, area->y, area->w, area->h, info->screen_base); + atomic_inc(&dev->damage_count); } - if (cmd == 0xAC) { - copyfb(dev_info); - image_blit(dev_info, area->x, area->y, area->w, area->h, - info->screen_base); - swapfb(dev_info); - } else if (cmd == 0xAB) { - - if (area->x2 < 0) - area->x2 = 0; - - if (area->y2 < 0) - area->y2 = 0; - copyarea(dev_info, - area->x2, area->y2, area->x, area->y, area->w, - area->h); - } return 0; } /* taken from vesafb */ - static int -dlfb_setcolreg(unsigned regno, unsigned red, unsigned green, +dlfb_ops_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *info) { int err = 0; @@ -688,234 +741,698 @@ dlfb_setcolreg(unsigned regno, unsigned red, unsigned green, return err; } -static int dlfb_release(struct fb_info *info, int user) +/* + * It's common for several clients to have framebuffer open simultaneously. + * e.g. both fbcon and X. Makes things interesting. + */ +static int dlfb_ops_open(struct fb_info *info, int user) +{ + struct dlfb_data *dev = info->par; + +/* if (user == 0) + * We could special case kernel mode clients (fbcon) here + */ + + mutex_lock(&dev->fb_open_lock); + + dev->fb_count++; + +#ifdef CONFIG_FB_DEFERRED_IO + if ((atomic_read(&dev->use_defio)) && (info->fbdefio == NULL)) { + /* enable defio */ + info->fbdefio = &dlfb_defio; + fb_deferred_io_init(info); + } +#endif + + dl_notice("open /dev/fb%d user=%d fb_info=%p count=%d\n", + info->node, user, info, dev->fb_count); + + mutex_unlock(&dev->fb_open_lock); + + return 0; +} + +static int dlfb_ops_release(struct fb_info *info, int user) +{ + struct dlfb_data *dev = info->par; + + mutex_lock(&dev->fb_open_lock); + + dev->fb_count--; + +#ifdef CONFIG_FB_DEFERRED_IO + if ((dev->fb_count == 0) && (info->fbdefio)) { + fb_deferred_io_cleanup(info); + info->fbdefio = NULL; + info->fbops->fb_mmap = dlfb_ops_mmap; + } +#endif + + dl_notice("release /dev/fb%d user=%d count=%d\n", + info->node, user, dev->fb_count); + + mutex_unlock(&dev->fb_open_lock); + + return 0; +} + +/* + * Called when all client interfaces to start transactions have been disabled, + * and all references to our device instance (dlfb_data) are released. + * Every transaction must have a reference, so we know are fully spun down + */ +static void dlfb_delete(struct kref *kref) +{ + struct dlfb_data *dev = container_of(kref, struct dlfb_data, kref); + + if (dev->backing_buffer) + vfree(dev->backing_buffer); + + mutex_destroy(&dev->fb_open_lock); + + kfree(dev); +} + +/* + * Called by fbdev as last part of unregister_framebuffer() process + * No new clients can open connections. Deallocate everything fb_info. + */ +static void dlfb_ops_destroy(struct fb_info *info) +{ + struct dlfb_data *dev = info->par; + + if (info->cmap.len != 0) + fb_dealloc_cmap(&info->cmap); + if (info->monspecs.modedb) + fb_destroy_modedb(info->monspecs.modedb); + if (info->screen_base) + vfree(info->screen_base); + + fb_destroy_modelist(&info->modelist); + + framebuffer_release(info); + + /* ref taken before register_framebuffer() for dlfb_data clients */ + kref_put(&dev->kref, dlfb_delete); +} + +/* + * Check whether a video mode is supported by the DisplayLink chip + * We start from monitor's modes, so don't need to filter that here + */ +static int dlfb_is_valid_mode(struct fb_videomode *mode, + struct fb_info *info) +{ + struct dlfb_data *dev = info->par; + + if (mode->xres * mode->yres > dev->sku_pixel_limit) + return 0; + + return 1; +} + +static void dlfb_var_color_format(struct fb_var_screeninfo *var) +{ + const struct fb_bitfield red = { 11, 5, 0 }; + const struct fb_bitfield green = { 5, 6, 0 }; + const struct fb_bitfield blue = { 0, 5, 0 }; + + var->bits_per_pixel = 16; + var->red = red; + var->green = green; + var->blue = blue; +} + +static int dlfb_ops_check_var(struct fb_var_screeninfo *var, + struct fb_info *info) { - struct dlfb_data *dev_info = info->par; - image_blit(dev_info, 0, 0, info->var.xres, info->var.yres, - info->screen_base); + struct fb_videomode mode; + + /* TODO: support dynamically changing framebuffer size */ + if ((var->xres * var->yres * 2) > info->fix.smem_len) + return -EINVAL; + + /* set device-specific elements of var unrelated to mode */ + dlfb_var_color_format(var); + + fb_var_to_videomode(&mode, var); + + if (!dlfb_is_valid_mode(&mode, info)) + return -EINVAL; + return 0; } -static int dlfb_blank(int blank_mode, struct fb_info *info) +static int dlfb_ops_set_par(struct fb_info *info) { - struct dlfb_data *dev_info = info->par; - char *bufptr = dev_info->buf; + struct dlfb_data *dev = info->par; + + dl_notice("set_par mode %dx%d\n", info->var.xres, info->var.yres); - bufptr = dlfb_set_register(bufptr, 0xFF, 0x00); + return dlfb_set_video_mode(dev, &info->var); +} + +static int dlfb_ops_blank(int blank_mode, struct fb_info *info) +{ + struct dlfb_data *dev = info->par; + char *bufptr; + struct urb *urb; + + urb = dlfb_get_urb(dev); + if (!urb) + return 0; + bufptr = (char *) urb->transfer_buffer; + + /* overloading usb_active. UNBLANK can conflict with teardown */ + + bufptr = dlfb_vidreg_lock(bufptr); if (blank_mode != FB_BLANK_UNBLANK) { - bufptr = dlfb_set_register(bufptr, 0x1F, 0x01); + atomic_set(&dev->usb_active, 0); + bufptr = dlfb_enable_hvsync(bufptr, false); } else { - bufptr = dlfb_set_register(bufptr, 0x1F, 0x00); + atomic_set(&dev->usb_active, 1); + bufptr = dlfb_enable_hvsync(bufptr, true); } - bufptr = dlfb_set_register(bufptr, 0xFF, 0xFF); + bufptr = dlfb_vidreg_unlock(bufptr); - dlfb_bulk_msg(dev_info, bufptr - dev_info->buf); + dlfb_submit_urb(dev, urb, bufptr - (char *) urb->transfer_buffer); return 0; } static struct fb_ops dlfb_ops = { - .fb_setcolreg = dlfb_setcolreg, - .fb_fillrect = dlfb_fillrect, - .fb_copyarea = dlfb_copyarea, - .fb_imageblit = dlfb_imageblit, - .fb_mmap = dlfb_mmap, - .fb_ioctl = dlfb_ioctl, - .fb_release = dlfb_release, - .fb_blank = dlfb_blank, + .owner = THIS_MODULE, + .fb_setcolreg = dlfb_ops_setcolreg, + .fb_fillrect = dlfb_ops_fillrect, + .fb_copyarea = dlfb_ops_copyarea, + .fb_imageblit = dlfb_ops_imageblit, + .fb_mmap = dlfb_ops_mmap, + .fb_ioctl = dlfb_ops_ioctl, + .fb_open = dlfb_ops_open, + .fb_release = dlfb_ops_release, + .fb_blank = dlfb_ops_blank, + .fb_check_var = dlfb_ops_check_var, + .fb_set_par = dlfb_ops_set_par, }; -static int -dlfb_probe(struct usb_interface *interface, const struct usb_device_id *id) +/* + * Calls dlfb_get_edid() to query the EDID of attached monitor via usb cmds + * Then parses EDID into three places used by various parts of fbdev: + * fb_var_screeninfo contains the timing of the monitor's preferred mode + * fb_info.monspecs is full parsed EDID info, including monspecs.modedb + * fb_info.modelist is a linked list of all monitor & VESA modes which work + * + * If EDID is not readable/valid, then modelist is all VESA modes, + * monspecs is NULL, and fb_var_screeninfo is set to safe VESA mode + * Returns 0 if EDID parses successfully + */ +static int dlfb_parse_edid(struct dlfb_data *dev, + struct fb_var_screeninfo *var, + struct fb_info *info) { - struct dlfb_data *dev_info; - struct fb_info *info; + int i; + const struct fb_videomode *default_vmode = NULL; + int result = 0; - int ret; - char rbuf[4]; + fb_destroy_modelist(&info->modelist); + memset(&info->monspecs, 0, sizeof(info->monspecs)); - dev_info = kzalloc(sizeof(*dev_info), GFP_KERNEL); - if (dev_info == NULL) { - printk("cannot allocate dev_info structure.\n"); - return -ENOMEM; + dlfb_get_edid(dev); + fb_edid_to_monspecs(dev->edid, &info->monspecs); + + if (info->monspecs.modedb_len > 0) { + + for (i = 0; i < info->monspecs.modedb_len; i++) { + if (dlfb_is_valid_mode(&info->monspecs.modedb[i], info)) + fb_add_videomode(&info->monspecs.modedb[i], + &info->modelist); + } + + default_vmode = fb_find_best_display(&info->monspecs, + &info->modelist); + } else { + struct fb_videomode fb_vmode = {0}; + + dl_err("Unable to get valid EDID from device/display\n"); + result = 1; + + /* + * Add the standard VESA modes to our modelist + * Since we don't have EDID, there may be modes that + * overspec monitor and/or are incorrect aspect ratio, etc. + * But at least the user has a chance to choose + */ + for (i = 0; i < VESA_MODEDB_SIZE; i++) { + if (dlfb_is_valid_mode((struct fb_videomode *) + &vesa_modes[i], info)) + fb_add_videomode(&vesa_modes[i], + &info->modelist); + } + + /* + * default to resolution safe for projectors + * (since they are most common case without EDID) + */ + fb_vmode.xres = 800; + fb_vmode.yres = 600; + fb_vmode.refresh = 60; + default_vmode = fb_find_nearest_mode(&fb_vmode, + &info->modelist); } - mutex_init(&dev_info->bulk_mutex); + fb_videomode_to_var(var, default_vmode); + dlfb_var_color_format(var); - dev_info->udev = usb_get_dev(interface_to_usbdev(interface)); - dev_info->interface = interface; + return result; +} - printk("DisplayLink device attached\n"); +static ssize_t metrics_bytes_rendered_show(struct device *fbdev, + struct device_attribute *a, char *buf) { + struct fb_info *fb_info = dev_get_drvdata(fbdev); + struct dlfb_data *dev = fb_info->par; + return snprintf(buf, PAGE_SIZE, "%u\n", + atomic_read(&dev->bytes_rendered)); +} - /* add framebuffer info to usb interface */ - usb_set_intfdata(interface, dev_info); +static ssize_t metrics_bytes_identical_show(struct device *fbdev, + struct device_attribute *a, char *buf) { + struct fb_info *fb_info = dev_get_drvdata(fbdev); + struct dlfb_data *dev = fb_info->par; + return snprintf(buf, PAGE_SIZE, "%u\n", + atomic_read(&dev->bytes_identical)); +} - dev_info->buf = kmalloc(BUF_SIZE, GFP_KERNEL); - /* usb_buffer_alloc(dev_info->udev, BUF_SIZE , GFP_KERNEL, &dev_info->tx_urb->transfer_dma); */ +static ssize_t metrics_bytes_sent_show(struct device *fbdev, + struct device_attribute *a, char *buf) { + struct fb_info *fb_info = dev_get_drvdata(fbdev); + struct dlfb_data *dev = fb_info->par; + return snprintf(buf, PAGE_SIZE, "%u\n", + atomic_read(&dev->bytes_sent)); +} - if (dev_info->buf == NULL) { - printk("unable to allocate memory for dlfb commands\n"); - goto out; - } - dev_info->bufend = dev_info->buf + BUF_SIZE; +static ssize_t metrics_cpu_kcycles_used_show(struct device *fbdev, + struct device_attribute *a, char *buf) { + struct fb_info *fb_info = dev_get_drvdata(fbdev); + struct dlfb_data *dev = fb_info->par; + return snprintf(buf, PAGE_SIZE, "%u\n", + atomic_read(&dev->cpu_kcycles_used)); +} - dev_info->tx_urb = usb_alloc_urb(0, GFP_KERNEL); - usb_fill_bulk_urb(dev_info->tx_urb, dev_info->udev, - usb_sndbulkpipe(dev_info->udev, 1), dev_info->buf, 0, - dlfb_bulk_callback, dev_info); +static ssize_t metrics_misc_show(struct device *fbdev, + struct device_attribute *a, char *buf) { + struct fb_info *fb_info = dev_get_drvdata(fbdev); + struct dlfb_data *dev = fb_info->par; + return snprintf(buf, PAGE_SIZE, + "Calls to\ndamage: %u\nblit: %u\n" + "defio faults: %u\ncopy: %u\n" + "fill: %u\n\n" + "active framebuffer clients: %d\n" + "urbs available %d(%d)\n" + "Shadow framebuffer in use? %s\n" + "Any lost pixels? %s\n", + atomic_read(&dev->damage_count), + atomic_read(&dev->blit_count), + atomic_read(&dev->defio_fault_count), + atomic_read(&dev->copy_count), + atomic_read(&dev->fill_count), + dev->fb_count, + dev->urbs.available, dev->urbs.limit_sem.count, + (dev->backing_buffer) ? "yes" : "no", + atomic_read(&dev->lost_pixels) ? "yes" : "no"); +} - ret = - usb_control_msg(dev_info->udev, usb_rcvctrlpipe(dev_info->udev, 0), - (0x06), (0x80 | (0x02 << 5)), 0, 0, rbuf, 4, 0); - printk("ret control msg 0: %d %x%x%x%x\n", ret, rbuf[0], rbuf[1], - rbuf[2], rbuf[3]); +static ssize_t edid_show(struct kobject *kobj, struct bin_attribute *a, + char *buf, loff_t off, size_t count) { + struct device *fbdev = container_of(kobj, struct device, kobj); + struct fb_info *fb_info = dev_get_drvdata(fbdev); + struct dlfb_data *dev = fb_info->par; + char *edid = &dev->edid[0]; + const size_t size = sizeof(dev->edid); - dlfb_edid(dev_info); + if (dlfb_parse_edid(dev, &fb_info->var, fb_info)) + return 0; - info = framebuffer_alloc(sizeof(u32) * 256, &dev_info->udev->dev); + if (off >= size) + return 0; - if (!info) { - printk("non posso allocare il framebuffer displaylink"); - goto out; - } + if (off + count > size) + count = size - off; + memcpy(buf, edid + off, count); - fb_parse_edid(dev_info->edid, &info->var); + return count; +} - printk("EDID XRES %d YRES %d\n", info->var.xres, info->var.yres); - if (dlfb_set_video_mode(dev_info, info->var.xres, info->var.yres) != 0) { - info->var.xres = 1280; - info->var.yres = 1024; - if (dlfb_set_video_mode - (dev_info, info->var.xres, info->var.yres) != 0) { - goto out; - } +static ssize_t metrics_reset_store(struct device *fbdev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct fb_info *fb_info = dev_get_drvdata(fbdev); + struct dlfb_data *dev = fb_info->par; + + atomic_set(&dev->bytes_rendered, 0); + atomic_set(&dev->bytes_identical, 0); + atomic_set(&dev->bytes_sent, 0); + atomic_set(&dev->cpu_kcycles_used, 0); + atomic_set(&dev->blit_count, 0); + atomic_set(&dev->copy_count, 0); + atomic_set(&dev->fill_count, 0); + atomic_set(&dev->defio_fault_count, 0); + atomic_set(&dev->damage_count, 0); + + return count; +} + +static ssize_t use_defio_show(struct device *fbdev, + struct device_attribute *a, char *buf) { + struct fb_info *fb_info = dev_get_drvdata(fbdev); + struct dlfb_data *dev = fb_info->par; + return snprintf(buf, PAGE_SIZE, "%d\n", + atomic_read(&dev->use_defio)); +} + +static ssize_t use_defio_store(struct device *fbdev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct fb_info *fb_info = dev_get_drvdata(fbdev); + struct dlfb_data *dev = fb_info->par; + + if (count > 0) { + if (buf[0] == '0') + atomic_set(&dev->use_defio, 0); + if (buf[0] == '1') + atomic_set(&dev->use_defio, 1); } + return count; +} - printk("found valid mode...%d\n", info->var.pixclock); +static struct bin_attribute edid_attr = { + .attr.name = "edid", + .attr.mode = 0444, + .size = 128, + .read = edid_show, +}; - info->pseudo_palette = info->par; - info->par = dev_info; +static struct device_attribute fb_device_attrs[] = { + __ATTR_RO(metrics_bytes_rendered), + __ATTR_RO(metrics_bytes_identical), + __ATTR_RO(metrics_bytes_sent), + __ATTR_RO(metrics_cpu_kcycles_used), + __ATTR_RO(metrics_misc), + __ATTR(metrics_reset, S_IWUGO, NULL, metrics_reset_store), + __ATTR_RW(use_defio), +}; - dev_info->info = info; +#ifdef CONFIG_FB_DEFERRED_IO +static void dlfb_dpy_deferred_io(struct fb_info *info, + struct list_head *pagelist) +{ + struct page *cur; + struct fb_deferred_io *fbdefio = info->fbdefio; + struct dlfb_data *dev = info->par; + struct urb *urb; + char *cmd; + cycles_t start_cycles, end_cycles; + int bytes_sent = 0; + int bytes_identical = 0; + int bytes_rendered = 0; + int fault_count = 0; + + if (!atomic_read(&dev->use_defio)) + return; - info->flags = - FBINFO_DEFAULT | FBINFO_READS_FAST | FBINFO_HWACCEL_IMAGEBLIT | - FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT; - info->fbops = &dlfb_ops; - info->screen_base = rvmalloc(dev_info->screen_size); + if (!atomic_read(&dev->usb_active)) + return; + + start_cycles = get_cycles(); - if (info->screen_base == NULL) { - printk - ("cannot allocate framebuffer virtual memory of %d bytes\n", - dev_info->screen_size); - goto out0; + urb = dlfb_get_urb(dev); + if (!urb) + return; + cmd = urb->transfer_buffer; + + /* walk the written page list and render each to device */ + list_for_each_entry(cur, &fbdefio->pagelist, lru) { + dlfb_render_hline(dev, &urb, (char *) info->fix.smem_start, + &cmd, cur->index << PAGE_SHIFT, + PAGE_SIZE, &bytes_identical, &bytes_sent); + bytes_rendered += PAGE_SIZE; + fault_count++; } - printk("screen base allocated !!!\n"); + if (cmd > (char *) urb->transfer_buffer) { + /* Send partial buffer remaining before exiting */ + int len = cmd - (char *) urb->transfer_buffer; + dlfb_submit_urb(dev, urb, len); + bytes_sent += len; + } else + dlfb_urb_completion(urb); + + atomic_add(fault_count, &dev->defio_fault_count); + atomic_add(bytes_sent, &dev->bytes_sent); + atomic_add(bytes_identical, &dev->bytes_identical); + atomic_add(bytes_rendered, &dev->bytes_rendered); + end_cycles = get_cycles(); + atomic_add(((unsigned int) ((end_cycles - start_cycles) + >> 10)), /* Kcycles */ + &dev->cpu_kcycles_used); +} - dev_info->backing_buffer = kzalloc(dev_info->screen_size, GFP_KERNEL); +static struct fb_deferred_io dlfb_defio = { + .delay = 5, + .deferred_io = dlfb_dpy_deferred_io, +}; - if (!dev_info->backing_buffer) - printk("non posso allocare il backing buffer\n"); +#endif - /* info->var = dev_info->si; */ +/* + * This is necessary before we can communicate with the display controller. + */ +static int dlfb_select_std_channel(struct dlfb_data *dev) +{ + int ret; + u8 set_def_chn[] = { 0x57, 0xCD, 0xDC, 0xA7, + 0x1C, 0x88, 0x5E, 0x15, + 0x60, 0xFE, 0xC6, 0x97, + 0x16, 0x3D, 0x47, 0xF2 }; + + ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), + NR_USB_REQUEST_CHANNEL, + (USB_DIR_OUT | USB_TYPE_VENDOR), 0, 0, + set_def_chn, sizeof(set_def_chn), USB_CTRL_SET_TIMEOUT); + return ret; +} - info->var.bits_per_pixel = 16; - info->var.activate = FB_ACTIVATE_TEST; - info->var.vmode = FB_VMODE_NONINTERLACED; - info->var.red.offset = 11; - info->var.red.length = 5; - info->var.red.msb_right = 0; +static int dlfb_usb_probe(struct usb_interface *interface, + const struct usb_device_id *id) +{ + struct usb_device *usbdev; + struct dlfb_data *dev; + struct fb_info *info; + int videomemorysize; + int i; + unsigned char *videomemory; + int retval = -ENOMEM; + struct fb_var_screeninfo *var; + int registered = 0; + u16 *pix_framebuffer; + + /* usb initialization */ + + usbdev = interface_to_usbdev(interface); + + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (dev == NULL) { + err("dlfb_usb_probe: failed alloc of dev struct\n"); + goto error; + } - info->var.green.offset = 5; - info->var.green.length = 6; - info->var.green.msb_right = 0; + /* we need to wait for both usb and fbdev to spin down on disconnect */ + kref_init(&dev->kref); /* matching kref_put in usb .disconnect fn */ + kref_get(&dev->kref); /* matching kref_put in .fb_destroy function*/ - info->var.blue.offset = 0; - info->var.blue.length = 5; - info->var.blue.msb_right = 0; + dev->udev = usbdev; + dev->gdev = &usbdev->dev; /* our generic struct device * */ + usb_set_intfdata(interface, dev); - /* info->var.pixclock = (10000000 / FB_W * 1000 / FB_H)/2 ; */ + if (!dlfb_alloc_urb_list(dev, WRITES_IN_FLIGHT, MAX_TRANSFER)) { + retval = -ENOMEM; + dl_err("dlfb_alloc_urb_list failed\n"); + goto error; + } - info->fix.smem_start = (unsigned long)info->screen_base; - info->fix.smem_len = PAGE_ALIGN(dev_info->screen_size); - if (strlen(dev_info->udev->product) > 15) { - memcpy(info->fix.id, dev_info->udev->product, 15); - } else { - memcpy(info->fix.id, dev_info->udev->product, - strlen(dev_info->udev->product)); + mutex_init(&dev->fb_open_lock); + + /* We don't register a new USB class. Our client interface is fbdev */ + + /* allocates framebuffer driver structure, not framebuffer memory */ + info = framebuffer_alloc(0, &usbdev->dev); + if (!info) { + retval = -ENOMEM; + dl_err("framebuffer_alloc failed\n"); + goto error; + } + dev->info = info; + info->par = dev; + info->pseudo_palette = dev->pseudo_palette; + info->fbops = &dlfb_ops; + + var = &info->var; + + /* TODO set limit based on actual SKU detection */ + dev->sku_pixel_limit = 2048 * 1152; + + INIT_LIST_HEAD(&info->modelist); + dlfb_parse_edid(dev, var, info); + + /* + * ok, now that we've got the size info, we can alloc our framebuffer. + */ + info->fix = dlfb_fix; + info->fix.line_length = var->xres * (var->bits_per_pixel / 8); + videomemorysize = info->fix.line_length * var->yres; + + /* + * The big chunk of system memory we use as a virtual framebuffer. + * TODO: Handle fbcon cursor code calling blit in interrupt context + */ + videomemory = vmalloc(videomemorysize); + if (!videomemory) { + retval = -ENOMEM; + dl_err("Virtual framebuffer alloc failed\n"); + goto error; } - info->fix.type = FB_TYPE_PACKED_PIXELS; - info->fix.visual = FB_VISUAL_TRUECOLOR; - info->fix.accel = info->flags; - info->fix.line_length = dev_info->line_length; - if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) - goto out1; + info->screen_base = videomemory; + info->fix.smem_len = PAGE_ALIGN(videomemorysize); + info->fix.smem_start = (unsigned long) videomemory; + info->flags = udlfb_info_flags; + + + /* + * Second framebuffer copy, mirroring the state of the framebuffer + * on the physical USB device. We can function without this. + * But with imperfect damage info we may end up sending pixels over USB + * that were, in fact, unchanged -- wasting limited USB bandwidth + */ + dev->backing_buffer = vmalloc(videomemorysize); + if (!dev->backing_buffer) + dl_warn("No shadow/backing buffer allcoated\n"); + else + memset(dev->backing_buffer, 0, videomemorysize); + + retval = fb_alloc_cmap(&info->cmap, 256, 0); + if (retval < 0) { + dl_err("fb_alloc_cmap failed %x\n", retval); + goto error; + } + + /* ready to begin using device */ + +#ifdef CONFIG_FB_DEFERRED_IO + atomic_set(&dev->use_defio, 1); +#endif + atomic_set(&dev->usb_active, 1); + dlfb_select_std_channel(dev); + + dlfb_ops_check_var(var, info); + dlfb_ops_set_par(info); + + /* paint greenscreen */ + pix_framebuffer = (u16 *) videomemory; + for (i = 0; i < videomemorysize / 2; i++) + pix_framebuffer[i] = 0x37e6; + + dlfb_handle_damage(dev, 0, 0, info->var.xres, info->var.yres, + videomemory); - printk("colormap allocated\n"); - if (register_framebuffer(info) < 0) - goto out2; + retval = register_framebuffer(info); + if (retval < 0) { + dl_err("register_framebuffer failed %d\n", retval); + goto error; + } + registered = 1; + + for (i = 0; i < ARRAY_SIZE(fb_device_attrs); i++) + device_create_file(info->dev, &fb_device_attrs[i]); - draw_rect(dev_info, 0, 0, dev_info->info->var.xres, - dev_info->info->var.yres, 0x30, 0xff, 0x30); + device_create_bin_file(info->dev, &edid_attr); + dl_err("DisplayLink USB device /dev/fb%d attached. %dx%d resolution." + " Using %dK framebuffer memory\n", info->node, + var->xres, var->yres, + ((dev->backing_buffer) ? + videomemorysize * 2 : videomemorysize) >> 10); return 0; -out2: - fb_dealloc_cmap(&info->cmap); -out1: - rvfree(info->screen_base, dev_info->screen_size); -out0: - framebuffer_release(info); -out: - usb_set_intfdata(interface, NULL); - usb_put_dev(dev_info->udev); - kfree(dev_info); - return -ENOMEM; +error: + if (dev) { + if (registered) { + unregister_framebuffer(info); + dlfb_ops_destroy(info); + } else + kref_put(&dev->kref, dlfb_delete); + + if (dev->urbs.count > 0) + dlfb_free_urb_list(dev); + kref_put(&dev->kref, dlfb_delete); /* last ref from kref_init */ + + /* dev has been deallocated. Do not dereference */ + } + return retval; } -static void dlfb_disconnect(struct usb_interface *interface) +static void dlfb_usb_disconnect(struct usb_interface *interface) { - struct dlfb_data *dev_info = usb_get_intfdata(interface); + struct dlfb_data *dev; + struct fb_info *info; + int i; + + dev = usb_get_intfdata(interface); + info = dev->info; - mutex_unlock(&dev_info->bulk_mutex); + /* when non-active we'll update virtual framebuffer, but no new urbs */ + atomic_set(&dev->usb_active, 0); - usb_kill_urb(dev_info->tx_urb); - usb_free_urb(dev_info->tx_urb); usb_set_intfdata(interface, NULL); - usb_put_dev(dev_info->udev); - if (dev_info->info) { - unregister_framebuffer(dev_info->info); - fb_dealloc_cmap(&dev_info->info->cmap); - rvfree(dev_info->info->screen_base, dev_info->screen_size); - kfree(dev_info->backing_buffer); - framebuffer_release(dev_info->info); + for (i = 0; i < ARRAY_SIZE(fb_device_attrs); i++) + device_remove_file(info->dev, &fb_device_attrs[i]); + + device_remove_bin_file(info->dev, &edid_attr); + /* this function will wait for all in-flight urbs to complete */ + dlfb_free_urb_list(dev); + + if (info) { + dl_notice("Detaching /dev/fb%d\n", info->node); + unregister_framebuffer(info); + dlfb_ops_destroy(info); } - kfree(dev_info); + /* release reference taken by kref_init in probe() */ + kref_put(&dev->kref, dlfb_delete); + + /* consider dlfb_data freed */ - printk("DisplayLink device disconnected\n"); + return; } static struct usb_driver dlfb_driver = { .name = "udlfb", - .probe = dlfb_probe, - .disconnect = dlfb_disconnect, + .probe = dlfb_usb_probe, + .disconnect = dlfb_usb_disconnect, .id_table = id_table, }; -static int __init dlfb_init(void) +static int __init dlfb_module_init(void) { int res; - dlfb_init_modes(); - res = usb_register(&dlfb_driver); if (res) err("usb_register failed. Error number %d", res); @@ -925,14 +1442,186 @@ static int __init dlfb_init(void) return res; } -static void __exit dlfb_exit(void) +static void __exit dlfb_module_exit(void) { usb_deregister(&dlfb_driver); } -module_init(dlfb_init); -module_exit(dlfb_exit); +module_init(dlfb_module_init); +module_exit(dlfb_module_exit); -MODULE_AUTHOR("Roberto De Ioris <roberto@unbit.it>"); -MODULE_DESCRIPTION(DRIVER_VERSION); +static void dlfb_urb_completion(struct urb *urb) +{ + struct urb_node *unode = urb->context; + struct dlfb_data *dev = unode->dev; + unsigned long flags; + + /* sync/async unlink faults aren't errors */ + if (urb->status) { + if (!(urb->status == -ENOENT || + urb->status == -ECONNRESET || + urb->status == -ESHUTDOWN)) { + dl_err("%s - nonzero write bulk status received: %d\n", + __func__, urb->status); + atomic_set(&dev->lost_pixels, 1); + } + } + + urb->transfer_buffer_length = dev->urbs.size; /* reset to actual */ + + spin_lock_irqsave(&dev->urbs.lock, flags); + list_add_tail(&unode->entry, &dev->urbs.list); + dev->urbs.available++; + spin_unlock_irqrestore(&dev->urbs.lock, flags); + + up(&dev->urbs.limit_sem); +} + +static void dlfb_free_urb_list(struct dlfb_data *dev) +{ + int count = dev->urbs.count; + struct list_head *node; + struct urb_node *unode; + struct urb *urb; + int ret; + unsigned long flags; + + dl_notice("Waiting for completes and freeing all render urbs\n"); + + /* keep waiting and freeing, until we've got 'em all */ + while (count--) { + /* Timeout means a memory leak and/or fault */ + ret = down_timeout(&dev->urbs.limit_sem, FREE_URB_TIMEOUT); + if (ret) { + BUG_ON(ret); + break; + } + spin_lock_irqsave(&dev->urbs.lock, flags); + + node = dev->urbs.list.next; /* have reserved one with sem */ + list_del_init(node); + + spin_unlock_irqrestore(&dev->urbs.lock, flags); + + unode = list_entry(node, struct urb_node, entry); + urb = unode->urb; + + /* Free each separately allocated piece */ + usb_buffer_free(urb->dev, dev->urbs.size, + urb->transfer_buffer, urb->transfer_dma); + usb_free_urb(urb); + kfree(node); + } + + kref_put(&dev->kref, dlfb_delete); + +} + +static int dlfb_alloc_urb_list(struct dlfb_data *dev, int count, size_t size) +{ + int i = 0; + struct urb *urb; + struct urb_node *unode; + char *buf; + + spin_lock_init(&dev->urbs.lock); + + dev->urbs.size = size; + INIT_LIST_HEAD(&dev->urbs.list); + + while (i < count) { + unode = kzalloc(sizeof(struct urb_node), GFP_KERNEL); + if (!unode) + break; + unode->dev = dev; + + urb = usb_alloc_urb(0, GFP_KERNEL); + if (!urb) { + kfree(unode); + break; + } + unode->urb = urb; + + buf = usb_buffer_alloc(dev->udev, MAX_TRANSFER, GFP_KERNEL, + &urb->transfer_dma); + if (!buf) { + kfree(unode); + usb_free_urb(urb); + break; + } + + /* urb->transfer_buffer_length set to actual before submit */ + usb_fill_bulk_urb(urb, dev->udev, usb_sndbulkpipe(dev->udev, 1), + buf, size, dlfb_urb_completion, unode); + urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + + list_add_tail(&unode->entry, &dev->urbs.list); + + i++; + } + + sema_init(&dev->urbs.limit_sem, i); + dev->urbs.count = i; + dev->urbs.available = i; + + kref_get(&dev->kref); /* released in free_render_urbs() */ + + dl_notice("allocated %d %d byte urbs \n", i, (int) size); + + return i; +} + +static struct urb *dlfb_get_urb(struct dlfb_data *dev) +{ + int ret = 0; + struct list_head *entry; + struct urb_node *unode; + struct urb *urb = NULL; + unsigned long flags; + + /* Wait for an in-flight buffer to complete and get re-queued */ + ret = down_timeout(&dev->urbs.limit_sem, GET_URB_TIMEOUT); + if (ret) { + atomic_set(&dev->lost_pixels, 1); + dl_err("wait for urb interrupted: %x\n", ret); + goto error; + } + + spin_lock_irqsave(&dev->urbs.lock, flags); + + BUG_ON(list_empty(&dev->urbs.list)); /* reserved one with limit_sem */ + entry = dev->urbs.list.next; + list_del_init(entry); + dev->urbs.available--; + + spin_unlock_irqrestore(&dev->urbs.lock, flags); + + unode = list_entry(entry, struct urb_node, entry); + urb = unode->urb; + +error: + return urb; +} + +static int dlfb_submit_urb(struct dlfb_data *dev, struct urb *urb, size_t len) +{ + int ret; + + BUG_ON(len > dev->urbs.size); + + urb->transfer_buffer_length = len; /* set to actual payload len */ + ret = usb_submit_urb(urb, GFP_KERNEL); + if (ret) { + dlfb_urb_completion(urb); /* because no one else will */ + atomic_set(&dev->lost_pixels, 1); + dl_err("usb_submit_urb error %x\n", ret); + } + return ret; +} + +MODULE_AUTHOR("Roberto De Ioris <roberto@unbit.it>, " + "Jaya Kumar <jayakumar.lkml@gmail.com>, " + "Bernie Thompson <bernie@plugable.com>"); +MODULE_DESCRIPTION("DisplayLink kernel framebuffer driver"); MODULE_LICENSE("GPL"); + diff --git a/drivers/staging/udlfb/udlfb.h b/drivers/staging/udlfb/udlfb.h index 40ad85e..b07a693 100644 --- a/drivers/staging/udlfb/udlfb.h +++ b/drivers/staging/udlfb/udlfb.h @@ -1,225 +1,106 @@ #ifndef UDLFB_H #define UDLFB_H -#define MAX_VMODES 4 -#define FB_BPP 16 +/* + * TODO: Propose standard fb.h ioctl for reporting damage, + * using _IOWR() and one of the existing area structs from fb.h + * Consider these ioctls deprecated, but they're still used by the + * DisplayLink X server as yet - need both to be modified in tandem + * when new ioctl(s) are ready. + */ +#define DLFB_IOCTL_RETURN_EDID 0xAD +#define DLFB_IOCTL_REPORT_DAMAGE 0xAA +struct dloarea { + int x, y; + int w, h; + int x2, y2; +}; -#define STD_CHANNEL "\x57\xCD\xDC\xA7\x1C\x88\x5E\x15" \ - "\x60\xFE\xC6\x97\x16\x3D\x47\xF2" +struct urb_node { + struct list_head entry; + struct dlfb_data *dev; + struct urb *urb; +}; -/* as libdlo */ -#define BUF_HIGH_WATER_MARK 1024 -#define BUF_SIZE (64*1024) +struct urb_list { + struct list_head list; + spinlock_t lock; + struct semaphore limit_sem; + int available; + int count; + size_t size; +}; struct dlfb_data { struct usb_device *udev; - struct usb_interface *interface; - struct urb *tx_urb, *ctrl_urb; - struct usb_ctrlrequest dr; + struct device *gdev; /* &udev->dev */ struct fb_info *info; - char *buf; - char *bufend; + struct urb_list urbs; + struct kref kref; char *backing_buffer; - struct mutex bulk_mutex; + struct delayed_work deferred_work; + struct mutex fb_open_lock; + int fb_count; + atomic_t usb_active; /* 0 = update virtual buffer, but no usb traffic */ + atomic_t lost_pixels; /* 1 = a render op failed. Need screen refresh */ + atomic_t use_defio; /* 0 = rely on ioctls and blit/copy/fill rects */ char edid[128]; - int screen_size; - int line_length; - struct completion done; + int sku_pixel_limit; int base16; - int base16d; int base8; - int base8d; + u32 pseudo_palette[256]; + /* blit-only rendering path metrics, exposed through sysfs */ + atomic_t bytes_rendered; /* raw pixel-bytes driver asked to render */ + atomic_t bytes_identical; /* saved effort with backbuffer comparison */ + atomic_t bytes_sent; /* to usb, after compression including overhead */ + atomic_t cpu_kcycles_used; /* transpired during pixel processing */ + /* interface usage metrics. Clients can call driver via several */ + atomic_t blit_count; + atomic_t copy_count; + atomic_t fill_count; + atomic_t damage_count; + atomic_t defio_fault_count; }; -struct dlfb_video_mode { - uint8_t col; - uint32_t hclock; - uint32_t vclock; - uint8_t unknown1[6]; - uint16_t xres; - uint8_t unknown2[6]; - uint16_t yres; - uint8_t unknown3[4]; -} __attribute__ ((__packed__)); - -static struct dlfb_video_mode dlfb_video_modes[MAX_VMODES]; - -static void dlfb_bulk_callback(struct urb *urb) -{ - struct dlfb_data *dev_info = urb->context; - complete(&dev_info->done); -} - -static void dlfb_edid(struct dlfb_data *dev_info) -{ - int i; - int ret; - char rbuf[2]; - - for (i = 0; i < 128; i++) { - ret = - usb_control_msg(dev_info->udev, - usb_rcvctrlpipe(dev_info->udev, 0), (0x02), - (0x80 | (0x02 << 5)), i << 8, 0xA1, rbuf, 2, - 0); - /*printk("ret control msg edid %d: %d [%d]\n",i, ret, rbuf[1]); */ - dev_info->edid[i] = rbuf[1]; - } - -} - -static int dlfb_bulk_msg(struct dlfb_data *dev_info, int len) -{ - int ret; - - init_completion(&dev_info->done); - - dev_info->tx_urb->actual_length = 0; - dev_info->tx_urb->transfer_buffer_length = len; - - ret = usb_submit_urb(dev_info->tx_urb, GFP_KERNEL); - if (!wait_for_completion_timeout(&dev_info->done, 1000)) { - usb_kill_urb(dev_info->tx_urb); - printk("usb timeout !!!\n"); - } - - return dev_info->tx_urb->actual_length; -} - -static void dlfb_init_modes(void) -{ - dlfb_video_modes[0].col = 0; - memcpy(&dlfb_video_modes[0].hclock, "\x20\x3C\x7A\xC9", 4); - memcpy(&dlfb_video_modes[0].vclock, "\xF2\x6C\x48\xF9", 4); - memcpy(&dlfb_video_modes[0].unknown1, "\x70\x53\xFF\xFF\x21\x27", 6); - dlfb_video_modes[0].xres = 800; - memcpy(&dlfb_video_modes[0].unknown2, "\x91\xF3\xFF\xFF\xFF\xF9", 6); - dlfb_video_modes[0].yres = 480; - memcpy(&dlfb_video_modes[0].unknown3, "\x01\x02\xC8\x19", 4); - - dlfb_video_modes[1].col = 0; - memcpy(&dlfb_video_modes[1].hclock, "\x36\x18\xD5\x10", 4); - memcpy(&dlfb_video_modes[1].vclock, "\x60\xA9\x7B\x33", 4); - memcpy(&dlfb_video_modes[1].unknown1, "\xA1\x2B\x27\x32\xFF\xFF", 6); - dlfb_video_modes[1].xres = 1024; - memcpy(&dlfb_video_modes[1].unknown2, "\xD9\x9A\xFF\xCA\xFF\xFF", 6); - dlfb_video_modes[1].yres = 768; - memcpy(&dlfb_video_modes[1].unknown3, "\x04\x03\xC8\x32", 4); - - dlfb_video_modes[2].col = 0; - memcpy(&dlfb_video_modes[2].hclock, "\x98\xF8\x0D\x57", 4); - memcpy(&dlfb_video_modes[2].vclock, "\x2A\x55\x4D\x54", 4); - memcpy(&dlfb_video_modes[2].unknown1, "\xCA\x0D\xFF\xFF\x94\x43", 6); - dlfb_video_modes[2].xres = 1280; - memcpy(&dlfb_video_modes[2].unknown2, "\x9A\xA8\xFF\xFF\xFF\xF9", 6); - dlfb_video_modes[2].yres = 1024; - memcpy(&dlfb_video_modes[2].unknown3, "\x04\x02\x60\x54", 4); - - dlfb_video_modes[3].col = 0; - memcpy(&dlfb_video_modes[3].hclock, "\x42\x24\x38\x36", 4); - memcpy(&dlfb_video_modes[3].vclock, "\xC1\x52\xD9\x29", 4); - memcpy(&dlfb_video_modes[3].unknown1, "\xEA\xB8\x32\x60\xFF\xFF", 6); - dlfb_video_modes[3].xres = 1400; - memcpy(&dlfb_video_modes[3].unknown2, "\xC9\x4E\xFF\xFF\xFF\xF2", 6); - dlfb_video_modes[3].yres = 1050; - memcpy(&dlfb_video_modes[3].unknown3, "\x04\x02\x1E\x5F", 4); -} - -static char *dlfb_set_register(char *bufptr, uint8_t reg, uint8_t val) -{ - *bufptr++ = 0xAF; - *bufptr++ = 0x20; - *bufptr++ = reg; - *bufptr++ = val; - - return bufptr; -} - -static int dlfb_set_video_mode(struct dlfb_data *dev_info, int width, int height) -{ - int i, ret; - unsigned char j; - char *bufptr = dev_info->buf; - uint8_t *vdata; - - for (i = 0; i < MAX_VMODES; i++) { - printk("INIT VIDEO %d %d %d\n", i, dlfb_video_modes[i].xres, - dlfb_video_modes[i].yres); - if (dlfb_video_modes[i].xres == width - && dlfb_video_modes[i].yres == height) { - - dev_info->base16 = 0; - dev_info->base16d = width * height * (FB_BPP / 8); - - //dev_info->base8 = width * height * (FB_BPP / 8); - - dev_info->base8 = dev_info->base16; - dev_info->base8d = dev_info->base16d; - - /* set encryption key (null) */ - memcpy(dev_info->buf, STD_CHANNEL, 16); - ret = - usb_control_msg(dev_info->udev, - usb_sndctrlpipe(dev_info->udev, 0), - 0x12, (0x02 << 5), 0, 0, - dev_info->buf, 16, 0); - printk("ret control msg 1 (STD_CHANNEL): %d\n", ret); - - /* set registers */ - bufptr = dlfb_set_register(bufptr, 0xFF, 0x00); - - /* set color depth */ - bufptr = dlfb_set_register(bufptr, 0x00, 0x00); - - /* set addresses */ - bufptr = - dlfb_set_register(bufptr, 0x20, - (char)(dev_info->base16 >> 16)); - bufptr = - dlfb_set_register(bufptr, 0x21, - (char)(dev_info->base16 >> 8)); - bufptr = - dlfb_set_register(bufptr, 0x22, - (char)(dev_info->base16)); - - bufptr = - dlfb_set_register(bufptr, 0x26, - (char)(dev_info->base8 >> 16)); - bufptr = - dlfb_set_register(bufptr, 0x27, - (char)(dev_info->base8 >> 8)); - bufptr = - dlfb_set_register(bufptr, 0x28, - (char)(dev_info->base8)); +#define NR_USB_REQUEST_I2C_SUB_IO 0x02 +#define NR_USB_REQUEST_CHANNEL 0x12 - /* set video mode */ - vdata = (uint8_t *)&dlfb_video_modes[i]; - for (j = 0; j < 29; j++) - bufptr = dlfb_set_register(bufptr, j, vdata[j]); +/* -BULK_SIZE as per usb-skeleton. Can we get full page and avoid overhead? */ +#define BULK_SIZE 512 +#define MAX_TRANSFER (PAGE_SIZE*16 - BULK_SIZE) +#define WRITES_IN_FLIGHT (4) - /* blank */ - bufptr = dlfb_set_register(bufptr, 0x1F, 0x00); +#define GET_URB_TIMEOUT HZ +#define FREE_URB_TIMEOUT (HZ*2) - /* end registers */ - bufptr = dlfb_set_register(bufptr, 0xFF, 0xFF); +#define BPP 2 +#define MAX_CMD_PIXELS 255 - /* send */ - ret = dlfb_bulk_msg(dev_info, bufptr - dev_info->buf); - printk("ret bulk 2: %d %td\n", ret, - bufptr - dev_info->buf); +#define RLX_HEADER_BYTES 7 +#define MIN_RLX_PIX_BYTES 4 +#define MIN_RLX_CMD_BYTES (RLX_HEADER_BYTES + MIN_RLX_PIX_BYTES) - /* flush */ - ret = dlfb_bulk_msg(dev_info, 0); - printk("ret bulk 3: %d\n", ret); +#define RLE_HEADER_BYTES 6 +#define MIN_RLE_PIX_BYTES 3 +#define MIN_RLE_CMD_BYTES (RLE_HEADER_BYTES + MIN_RLE_PIX_BYTES) - dev_info->screen_size = width * height * (FB_BPP / 8); - dev_info->line_length = width * (FB_BPP / 8); +#define RAW_HEADER_BYTES 6 +#define MIN_RAW_PIX_BYTES 2 +#define MIN_RAW_CMD_BYTES (RAW_HEADER_BYTES + MIN_RAW_PIX_BYTES) - return 0; - } - } +/* remove these once align.h patch is taken into kernel */ +#define DL_ALIGN_UP(x, a) ALIGN(x, a) +#define DL_ALIGN_DOWN(x, a) ALIGN(x-(a-1), a) - return -1; -} +/* remove once this gets added to sysfs.h */ +#define __ATTR_RW(attr) __ATTR(attr, 0644, attr##_show, attr##_store) +#define dl_err(format, arg...) \ + dev_err(dev->gdev, "dlfb: " format, ## arg) +#define dl_warn(format, arg...) \ + dev_warn(dev->gdev, "dlfb: " format, ## arg) +#define dl_notice(format, arg...) \ + dev_notice(dev->gdev, "dlfb: " format, ## arg) +#define dl_info(format, arg...) \ + dev_info(dev->gdev, "dlfb: " format, ## arg) #endif diff --git a/drivers/staging/usbip/Kconfig b/drivers/staging/usbip/Kconfig index 350d5d6..2c1d10a 100644 --- a/drivers/staging/usbip/Kconfig +++ b/drivers/staging/usbip/Kconfig @@ -34,3 +34,10 @@ config USB_IP_HOST To compile this driver as a module, choose M here: the module will be called usbip. + +config USB_IP_DEBUG_ENABLE + bool "USB-IP Debug Enable" + depends on USB_IP_COMMON + default N + ---help--- + This enables the debug messages from the USB-IP drivers. diff --git a/drivers/staging/usbip/Makefile b/drivers/staging/usbip/Makefile index 179f421..6f2916b 100644 --- a/drivers/staging/usbip/Makefile +++ b/drivers/staging/usbip/Makefile @@ -7,6 +7,6 @@ vhci-hcd-objs := vhci_sysfs.o vhci_tx.o vhci_rx.o vhci_hcd.o obj-$(CONFIG_USB_IP_HOST) += usbip.o usbip-objs := stub_dev.o stub_main.o stub_rx.o stub_tx.o -ifeq ($(CONFIG_USB_DEBUG),y) +ifeq ($(CONFIG_USB_IP_DEBUG_ENABLE),y) EXTRA_CFLAGS += -DDEBUG endif diff --git a/drivers/staging/usbip/usbip_common.c b/drivers/staging/usbip/usbip_common.c index ddb6f5f..7a45da8 100644 --- a/drivers/staging/usbip/usbip_common.c +++ b/drivers/staging/usbip/usbip_common.c @@ -33,7 +33,7 @@ /*-------------------------------------------------------------------------*/ /* debug routines */ -#ifdef CONFIG_USB_DEBUG +#ifdef CONFIG_USB_IP_DEBUG_ENABLE unsigned long usbip_debug_flag = 0xffffffff; #else unsigned long usbip_debug_flag; @@ -55,10 +55,7 @@ static ssize_t show_flag(struct device *dev, struct device_attribute *attr, static ssize_t store_flag(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - unsigned long flag; - - sscanf(buf, "%lx", &flag); - usbip_debug_flag = flag; + sscanf(buf, "%lx", &usbip_debug_flag); return count; } @@ -66,33 +63,8 @@ DEVICE_ATTR(usbip_debug, (S_IRUGO | S_IWUSR), show_flag, store_flag); static void usbip_dump_buffer(char *buff, int bufflen) { - int i; - - if (bufflen > 128) { - for (i = 0; i < 128; i++) { - if (i%24 == 0) - printk(KERN_DEBUG " "); - printk(KERN_DEBUG "%02x ", (unsigned char) buff[i]); - if (i%4 == 3) - printk(KERN_DEBUG "| "); - if (i%24 == 23) - printk(KERN_DEBUG "\n"); - } - printk(KERN_DEBUG "... (%d byte)\n", bufflen); - return; - } - - for (i = 0; i < bufflen; i++) { - if (i%24 == 0) - printk(KERN_DEBUG " "); - printk(KERN_DEBUG "%02x ", (unsigned char) buff[i]); - if (i%4 == 3) - printk(KERN_DEBUG "| "); - if (i%24 == 23) - printk(KERN_DEBUG "\n"); - } - printk(KERN_DEBUG "\n"); - + print_hex_dump(KERN_DEBUG, "usb-ip", DUMP_PREFIX_OFFSET, 16, 4, + buff, bufflen, false); } static void usbip_dump_pipe(unsigned int p) @@ -558,60 +530,6 @@ err: } EXPORT_SYMBOL_GPL(usbip_xmit); - -/* now a usrland utility should set options. */ -#if 0 -int setquickack(struct socket *socket) -{ - mm_segment_t oldfs; - int val = 1; - int ret; - - oldfs = get_fs(); - set_fs(get_ds()); - ret = socket->ops->setsockopt(socket, SOL_TCP, TCP_QUICKACK, - (char __user *) &val, sizeof(ret)); - set_fs(oldfs); - - return ret; -} - -int setnodelay(struct socket *socket) -{ - mm_segment_t oldfs; - int val = 1; - int ret; - - oldfs = get_fs(); - set_fs(get_ds()); - ret = socket->ops->setsockopt(socket, SOL_TCP, TCP_NODELAY, - (char __user *) &val, sizeof(ret)); - set_fs(oldfs); - - return ret; -} - -int setkeepalive(struct socket *socket) -{ - mm_segment_t oldfs; - int val = 1; - int ret; - - oldfs = get_fs(); - set_fs(get_ds()); - ret = socket->ops->setsockopt(socket, SOL_SOCKET, SO_KEEPALIVE, - (char __user *) &val, sizeof(ret)); - set_fs(oldfs); - - return ret; -} - -void setreuse(struct socket *socket) -{ - socket->sk->sk_reuse = 1; -} -#endif - struct socket *sockfd_to_socket(unsigned int sockfd) { struct socket *socket; diff --git a/drivers/staging/usbip/usbip_common.h b/drivers/staging/usbip/usbip_common.h index 1ca3eab..6f1dcb1 100644 --- a/drivers/staging/usbip/usbip_common.h +++ b/drivers/staging/usbip/usbip_common.h @@ -33,12 +33,12 @@ */ /** - * usbip_udbg - print debug messages if CONFIG_USB_DEBUG is defined + * usbip_udbg - print debug messages if CONFIG_USB_IP_DEBUG_ENABLE is defined * @fmt: * @args: */ -#ifdef CONFIG_USB_DEBUG +#ifdef CONFIG_USB_IP_DEBUG_ENABLE #define usbip_udbg(fmt, args...) \ do { \ @@ -47,11 +47,11 @@ __FILE__, __LINE__, __func__, ##args); \ } while (0) -#else /* CONFIG_USB_DEBUG */ +#else /* CONFIG_USB_IP_DEBUG_ENABLE */ #define usbip_udbg(fmt, args...) do { } while (0) -#endif /* CONFIG_USB_DEBUG */ +#endif /* CONFIG_USB_IP_DEBUG_ENABLE */ enum { diff --git a/drivers/staging/vme/Kconfig b/drivers/staging/vme/Kconfig index ae628a5..6411ae5 100644 --- a/drivers/staging/vme/Kconfig +++ b/drivers/staging/vme/Kconfig @@ -14,4 +14,6 @@ source "drivers/staging/vme/bridges/Kconfig" source "drivers/staging/vme/devices/Kconfig" +source "drivers/staging/vme/boards/Kconfig" + endif # VME diff --git a/drivers/staging/vme/Makefile b/drivers/staging/vme/Makefile index 8c3b90e..b4ea3f8 100644 --- a/drivers/staging/vme/Makefile +++ b/drivers/staging/vme/Makefile @@ -5,3 +5,4 @@ obj-$(CONFIG_VME_BUS) += vme.o obj-y += bridges/ obj-y += devices/ +obj-y += boards/ diff --git a/drivers/staging/vme/TODO b/drivers/staging/vme/TODO index 2201ff6..82c222b 100644 --- a/drivers/staging/vme/TODO +++ b/drivers/staging/vme/TODO @@ -4,28 +4,6 @@ API === -DMA Resource Allocation incomplete ----------------------------------- - -The current DMA resource Allocation provides no means of selecting the -suitability of a DMA controller based on it's supported modes of operation, as -opposed to the resource allocation mechanisms for master and slave windows: - - struct vme_resource *vme_dma_request(struct device *dev); - -As opposed to: - - struct vme_resource * vme_master_request(struct device *dev, - vme_address_t aspace, vme_cycle_t cycle, vme_width_t width); - -The TSI148 can perform, VME-to-PCI, PCI-to-VME, PATTERN-to-VME, PATTERN-to-PCI, -VME-to-VME and PCI-to-PCI transfers. The CA91C142 can only provide VME-to-PCI -and PCI-to-VME. - -Add a mechanism to select a VME controller based on source/target type, -required aspace, cycle and width requirements. - - Master window broadcast select mask ----------------------------------- @@ -59,7 +37,6 @@ chips. They are currently not supported at all by the API. Core ==== -- Rename vme_master_resource's "pci_resource" to be bus agnostic. - Improve generic sanity checks (Such as does an offset and size fit within a window and parameter checking). @@ -69,7 +46,6 @@ Bridge Support Tempe (tsi148) -------------- -- Driver can currently only support a single bridge. - 2eSST Broadcast mode. - Mailboxes unsupported. - Improve error detection. @@ -80,10 +56,6 @@ Tempe (tsi148) Universe II (ca91c142) ---------------------- -- Driver can currently only support a single bridge. -- DMA unsupported. -- RMW transactions unsupported. -- Location Monitors unsupported. - Mailboxes unsupported. - Error Detection. - Control of prefetch size, threshold. diff --git a/drivers/staging/vme/boards/Kconfig b/drivers/staging/vme/boards/Kconfig new file mode 100644 index 0000000..7616313 --- /dev/null +++ b/drivers/staging/vme/boards/Kconfig @@ -0,0 +1,9 @@ +comment "VME Board Drivers" + +config VMIVME_7805 + tristate "VMIVME-7805" + help + If you say Y here you get support for the VMIVME-7805 board. + This board has an additional control interface to the Universe II + chip. This driver has to be included if you want to access VME bus + with VMIVME-7805 board. diff --git a/drivers/staging/vme/boards/Makefile b/drivers/staging/vme/boards/Makefile new file mode 100644 index 0000000..4365834 --- /dev/null +++ b/drivers/staging/vme/boards/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for the VME board drivers. +# + +obj-$(CONFIG_VMIVME_7805) += vme_vmivme7805.o diff --git a/drivers/staging/vme/boards/vme_vmivme7805.c b/drivers/staging/vme/boards/vme_vmivme7805.c new file mode 100644 index 0000000..843c9ed --- /dev/null +++ b/drivers/staging/vme/boards/vme_vmivme7805.c @@ -0,0 +1,124 @@ +/* + * Support for the VMIVME-7805 board access to the Universe II bridge. + * + * Author: Arthur Benilov <arthur.benilov@iba-group.com> + * Copyright 2010 Ion Beam Application, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/version.h> +#include <linux/module.h> +#include <linux/types.h> +#include <linux/errno.h> +#include <linux/pci.h> +#include <linux/poll.h> +#include <linux/io.h> + +#include "vme_vmivme7805.h" + +static int __init vmic_init(void); +static int vmic_probe(struct pci_dev *, const struct pci_device_id *); +static void vmic_remove(struct pci_dev *); +static void __exit vmic_exit(void); + +/** Base address to access FPGA register */ +static void *vmic_base; + +static char driver_name[] = "vmivme_7805"; + +static struct pci_device_id vmic_ids[] = { + { PCI_DEVICE(PCI_VENDOR_ID_VMIC, PCI_DEVICE_ID_VTIMR) }, + { }, +}; + +static struct pci_driver vmic_driver = { + .name = driver_name, + .id_table = vmic_ids, + .probe = vmic_probe, + .remove = vmic_remove, +}; + +static int __init vmic_init(void) +{ + return pci_register_driver(&vmic_driver); +} + +static int vmic_probe(struct pci_dev *pdev, const struct pci_device_id *id) +{ + int retval; + u32 data; + + /* Enable the device */ + retval = pci_enable_device(pdev); + if (retval) { + dev_err(&pdev->dev, "Unable to enable device\n"); + goto err; + } + + /* Map Registers */ + retval = pci_request_regions(pdev, driver_name); + if (retval) { + dev_err(&pdev->dev, "Unable to reserve resources\n"); + goto err_resource; + } + + /* Map registers in BAR 0 */ + vmic_base = ioremap_nocache(pci_resource_start(pdev, 0), 16); + if (!vmic_base) { + dev_err(&pdev->dev, "Unable to remap CRG region\n"); + retval = -EIO; + goto err_remap; + } + + /* Clear the FPGA VME IF contents */ + iowrite32(0, vmic_base + VME_CONTROL); + + /* Clear any initial BERR */ + data = ioread32(vmic_base + VME_CONTROL) & 0x00000FFF; + data |= BM_VME_CONTROL_BERRST; + iowrite32(data, vmic_base + VME_CONTROL); + + /* Enable the vme interface and byte swapping */ + data = ioread32(vmic_base + VME_CONTROL) & 0x00000FFF; + data = data | BM_VME_CONTROL_MASTER_ENDIAN | + BM_VME_CONTROL_SLAVE_ENDIAN | + BM_VME_CONTROL_ABLE | + BM_VME_CONTROL_BERRI | + BM_VME_CONTROL_BPENA | + BM_VME_CONTROL_VBENA; + iowrite32(data, vmic_base + VME_CONTROL); + + return 0; + +err_remap: + pci_release_regions(pdev); +err_resource: + pci_disable_device(pdev); +err: + return retval; +} + +static void vmic_remove(struct pci_dev *pdev) +{ + iounmap(vmic_base); + pci_release_regions(pdev); + pci_disable_device(pdev); + +} + +static void __exit vmic_exit(void) +{ + pci_unregister_driver(&vmic_driver); +} + +MODULE_DESCRIPTION("VMIVME-7805 board support driver"); +MODULE_AUTHOR("Arthur Benilov <arthur.benilov@iba-group.com>"); +MODULE_LICENSE("GPL"); + +module_init(vmic_init); +module_exit(vmic_exit); + diff --git a/drivers/staging/vme/boards/vme_vmivme7805.h b/drivers/staging/vme/boards/vme_vmivme7805.h new file mode 100644 index 0000000..44c2c44 --- /dev/null +++ b/drivers/staging/vme/boards/vme_vmivme7805.h @@ -0,0 +1,37 @@ +/* + * vmivme_7805.h + * + * Support for the VMIVME-7805 board access to the Universe II bridge. + * + * Author: Arthur Benilov <arthur.benilov@iba-group.com> + * Copyright 2010 Ion Beam Application, Inc. + * + * 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 _VMIVME_7805_H +#define _VMIVME_7805_H + +#ifndef PCI_VENDOR_ID_VMIC +#define PCI_VENDOR_ID_VMIC 0x114A +#endif + +#ifndef PCI_DEVICE_ID_VTIMR +#define PCI_DEVICE_ID_VTIMR 0x0004 +#endif + +#define VME_CONTROL 0x0000 +#define BM_VME_CONTROL_MASTER_ENDIAN 0x0001 +#define BM_VME_CONTROL_SLAVE_ENDIAN 0x0002 +#define BM_VME_CONTROL_ABLE 0x0004 +#define BM_VME_CONTROL_BERRI 0x0040 +#define BM_VME_CONTROL_BERRST 0x0080 +#define BM_VME_CONTROL_BPENA 0x0400 +#define BM_VME_CONTROL_VBENA 0x0800 + +#endif /* _VMIVME_7805_H */ + diff --git a/drivers/staging/vme/bridges/Kconfig b/drivers/staging/vme/bridges/Kconfig index 023cceb..9331064 100644 --- a/drivers/staging/vme/bridges/Kconfig +++ b/drivers/staging/vme/bridges/Kconfig @@ -2,12 +2,14 @@ comment "VME Bridge Drivers" config VME_CA91CX42 tristate "Universe II" + depends on VIRT_TO_BUS help If you say Y here you get support for the Tundra CA91C142 (Universe II) VME bridge chip. config VME_TSI148 tristate "Tempe" + depends on VIRT_TO_BUS help If you say Y here you get support for the Tundra TSI148 VME bridge chip. diff --git a/drivers/staging/vme/bridges/vme_ca91cx42.c b/drivers/staging/vme/bridges/vme_ca91cx42.c index 1cf3e91..2795ff2 100644 --- a/drivers/staging/vme/bridges/vme_ca91cx42.c +++ b/drivers/staging/vme/bridges/vme_ca91cx42.c @@ -1,8 +1,8 @@ /* * Support for the Tundra Universe I/II VME-PCI Bridge Chips * - * Author: Martyn Welch <martyn.welch@gefanuc.com> - * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc. + * Author: Martyn Welch <martyn.welch@ge.com> + * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc. * * Based on work by Tom Armistead and Ajit Prem * Copyright 2004 Motorola Inc. @@ -38,25 +38,12 @@ static int ca91cx42_probe(struct pci_dev *, const struct pci_device_id *); static void ca91cx42_remove(struct pci_dev *); static void __exit ca91cx42_exit(void); -struct vme_bridge *ca91cx42_bridge; -wait_queue_head_t dma_queue; -wait_queue_head_t iack_queue; -wait_queue_head_t lm_queue; -wait_queue_head_t mbox_queue; - -void (*lm_callback[4])(int); /* Called in interrupt handler, be careful! */ -void *crcsr_kernel; -dma_addr_t crcsr_bus; - -struct mutex vme_rmw; /* Only one RMW cycle at a time */ -struct mutex vme_int; /* - * Only one VME interrupt can be - * generated at a time, provide locking - */ +/* Module parameters */ +static int geoid; static char driver_name[] = "vme_ca91cx42"; -static struct pci_device_id ca91cx42_ids[] = { +static const struct pci_device_id ca91cx42_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_TUNDRA, PCI_DEVICE_ID_TUNDRA_CA91C142) }, { }, }; @@ -68,14 +55,14 @@ static struct pci_driver ca91cx42_driver = { .remove = ca91cx42_remove, }; -static u32 ca91cx42_DMA_irqhandler(void) +static u32 ca91cx42_DMA_irqhandler(struct ca91cx42_driver *bridge) { - wake_up(&dma_queue); + wake_up(&(bridge->dma_queue)); return CA91CX42_LINT_DMA; } -static u32 ca91cx42_LM_irqhandler(u32 stat) +static u32 ca91cx42_LM_irqhandler(struct ca91cx42_driver *bridge, u32 stat) { int i; u32 serviced = 0; @@ -83,7 +70,7 @@ static u32 ca91cx42_LM_irqhandler(u32 stat) for (i = 0; i < 4; i++) { if (stat & CA91CX42_LINT_LM[i]) { /* We only enable interrupts if the callback is set */ - lm_callback[i](i); + bridge->lm_callback[i](i); serviced |= CA91CX42_LINT_LM[i]; } } @@ -92,40 +79,25 @@ static u32 ca91cx42_LM_irqhandler(u32 stat) } /* XXX This needs to be split into 4 queues */ -static u32 ca91cx42_MB_irqhandler(int mbox_mask) +static u32 ca91cx42_MB_irqhandler(struct ca91cx42_driver *bridge, int mbox_mask) { - wake_up(&mbox_queue); + wake_up(&(bridge->mbox_queue)); return CA91CX42_LINT_MBOX; } -static u32 ca91cx42_IACK_irqhandler(void) +static u32 ca91cx42_IACK_irqhandler(struct ca91cx42_driver *bridge) { - wake_up(&iack_queue); + wake_up(&(bridge->iack_queue)); return CA91CX42_LINT_SW_IACK; } -#if 0 -int ca91cx42_bus_error_chk(int clrflag) -{ - int tmp; - tmp = ioread32(ca91cx42_bridge->base + PCI_COMMAND); - if (tmp & 0x08000000) { /* S_TA is Set */ - if (clrflag) - iowrite32(tmp | 0x08000000, - ca91cx42_bridge->base + PCI_COMMAND); - return 1; - } - return 0; -} -#endif - -static u32 ca91cx42_VERR_irqhandler(void) +static u32 ca91cx42_VERR_irqhandler(struct ca91cx42_driver *bridge) { int val; - val = ioread32(ca91cx42_bridge->base + DGCS); + val = ioread32(bridge->base + DGCS); if (!(val & 0x00000800)) { printk(KERN_ERR "ca91c042: ca91cx42_VERR_irqhandler DMA Read " @@ -135,11 +107,11 @@ static u32 ca91cx42_VERR_irqhandler(void) return CA91CX42_LINT_VERR; } -static u32 ca91cx42_LERR_irqhandler(void) +static u32 ca91cx42_LERR_irqhandler(struct ca91cx42_driver *bridge) { int val; - val = ioread32(ca91cx42_bridge->base + DGCS); + val = ioread32(bridge->base + DGCS); if (!(val & 0x00000800)) { printk(KERN_ERR "ca91c042: ca91cx42_LERR_irqhandler DMA Read " @@ -151,13 +123,18 @@ static u32 ca91cx42_LERR_irqhandler(void) } -static u32 ca91cx42_VIRQ_irqhandler(int stat) +static u32 ca91cx42_VIRQ_irqhandler(struct vme_bridge *ca91cx42_bridge, + int stat) { int vec, i, serviced = 0; + struct ca91cx42_driver *bridge; + + bridge = ca91cx42_bridge->driver_priv; + for (i = 7; i > 0; i--) { if (stat & (1 << i)) { - vec = ioread32(ca91cx42_bridge->base + + vec = ioread32(bridge->base + CA91CX42_V_STATID[i]) & 0xff; vme_irq_handler(ca91cx42_bridge, i, vec); @@ -169,15 +146,18 @@ static u32 ca91cx42_VIRQ_irqhandler(int stat) return serviced; } -static irqreturn_t ca91cx42_irqhandler(int irq, void *dev_id) +static irqreturn_t ca91cx42_irqhandler(int irq, void *ptr) { u32 stat, enable, serviced = 0; + struct vme_bridge *ca91cx42_bridge; + struct ca91cx42_driver *bridge; - if (dev_id != ca91cx42_bridge->base) - return IRQ_NONE; + ca91cx42_bridge = ptr; - enable = ioread32(ca91cx42_bridge->base + LINT_EN); - stat = ioread32(ca91cx42_bridge->base + LINT_STAT); + bridge = ca91cx42_bridge->driver_priv; + + enable = ioread32(bridge->base + LINT_EN); + stat = ioread32(bridge->base + LINT_STAT); /* Only look at unmasked interrupts */ stat &= enable; @@ -186,42 +166,45 @@ static irqreturn_t ca91cx42_irqhandler(int irq, void *dev_id) return IRQ_NONE; if (stat & CA91CX42_LINT_DMA) - serviced |= ca91cx42_DMA_irqhandler(); + serviced |= ca91cx42_DMA_irqhandler(bridge); if (stat & (CA91CX42_LINT_LM0 | CA91CX42_LINT_LM1 | CA91CX42_LINT_LM2 | CA91CX42_LINT_LM3)) - serviced |= ca91cx42_LM_irqhandler(stat); + serviced |= ca91cx42_LM_irqhandler(bridge, stat); if (stat & CA91CX42_LINT_MBOX) - serviced |= ca91cx42_MB_irqhandler(stat); + serviced |= ca91cx42_MB_irqhandler(bridge, stat); if (stat & CA91CX42_LINT_SW_IACK) - serviced |= ca91cx42_IACK_irqhandler(); + serviced |= ca91cx42_IACK_irqhandler(bridge); if (stat & CA91CX42_LINT_VERR) - serviced |= ca91cx42_VERR_irqhandler(); + serviced |= ca91cx42_VERR_irqhandler(bridge); if (stat & CA91CX42_LINT_LERR) - serviced |= ca91cx42_LERR_irqhandler(); + serviced |= ca91cx42_LERR_irqhandler(bridge); if (stat & (CA91CX42_LINT_VIRQ1 | CA91CX42_LINT_VIRQ2 | CA91CX42_LINT_VIRQ3 | CA91CX42_LINT_VIRQ4 | CA91CX42_LINT_VIRQ5 | CA91CX42_LINT_VIRQ6 | CA91CX42_LINT_VIRQ7)) - serviced |= ca91cx42_VIRQ_irqhandler(stat); + serviced |= ca91cx42_VIRQ_irqhandler(ca91cx42_bridge, stat); /* Clear serviced interrupts */ - iowrite32(stat, ca91cx42_bridge->base + LINT_STAT); + iowrite32(stat, bridge->base + LINT_STAT); return IRQ_HANDLED; } -static int ca91cx42_irq_init(struct vme_bridge *bridge) +static int ca91cx42_irq_init(struct vme_bridge *ca91cx42_bridge) { int result, tmp; struct pci_dev *pdev; + struct ca91cx42_driver *bridge; + + bridge = ca91cx42_bridge->driver_priv; /* Need pdev */ - pdev = container_of(bridge->parent, struct pci_dev, dev); + pdev = container_of(ca91cx42_bridge->parent, struct pci_dev, dev); /* Initialise list for VME bus errors */ - INIT_LIST_HEAD(&(bridge->vme_errors)); + INIT_LIST_HEAD(&(ca91cx42_bridge->vme_errors)); - mutex_init(&(bridge->irq_mtx)); + mutex_init(&(ca91cx42_bridge->irq_mtx)); /* Disable interrupts from PCI to VME */ iowrite32(0, bridge->base + VINT_EN); @@ -232,7 +215,7 @@ static int ca91cx42_irq_init(struct vme_bridge *bridge) iowrite32(0x00FFFFFF, bridge->base + LINT_STAT); result = request_irq(pdev->irq, ca91cx42_irqhandler, IRQF_SHARED, - driver_name, pdev); + driver_name, ca91cx42_bridge); if (result) { dev_err(&pdev->dev, "Can't get assigned pci irq vector %02X\n", pdev->irq); @@ -254,15 +237,16 @@ static int ca91cx42_irq_init(struct vme_bridge *bridge) return 0; } -static void ca91cx42_irq_exit(struct pci_dev *pdev) +static void ca91cx42_irq_exit(struct ca91cx42_driver *bridge, + struct pci_dev *pdev) { /* Disable interrupts from PCI to VME */ - iowrite32(0, ca91cx42_bridge->base + VINT_EN); + iowrite32(0, bridge->base + VINT_EN); /* Disable PCI interrupts */ - iowrite32(0, ca91cx42_bridge->base + LINT_EN); + iowrite32(0, bridge->base + LINT_EN); /* Clear Any Pending PCI Interrupts */ - iowrite32(0x00FFFFFF, ca91cx42_bridge->base + LINT_STAT); + iowrite32(0x00FFFFFF, bridge->base + LINT_STAT); free_irq(pdev->irq, pdev); } @@ -270,21 +254,25 @@ static void ca91cx42_irq_exit(struct pci_dev *pdev) /* * Set up an VME interrupt */ -void ca91cx42_irq_set(int level, int state, int sync) +void ca91cx42_irq_set(struct vme_bridge *ca91cx42_bridge, int level, int state, + int sync) { struct pci_dev *pdev; u32 tmp; + struct ca91cx42_driver *bridge; + + bridge = ca91cx42_bridge->driver_priv; /* Enable IRQ level */ - tmp = ioread32(ca91cx42_bridge->base + LINT_EN); + tmp = ioread32(bridge->base + LINT_EN); if (state == 0) tmp &= ~CA91CX42_LINT_VIRQ[level]; else tmp |= CA91CX42_LINT_VIRQ[level]; - iowrite32(tmp, ca91cx42_bridge->base + LINT_EN); + iowrite32(tmp, bridge->base + LINT_EN); if ((state == 0) && (sync != 0)) { pdev = container_of(ca91cx42_bridge->parent, struct pci_dev, @@ -294,34 +282,38 @@ void ca91cx42_irq_set(int level, int state, int sync) } } -int ca91cx42_irq_generate(int level, int statid) +int ca91cx42_irq_generate(struct vme_bridge *ca91cx42_bridge, int level, + int statid) { u32 tmp; + struct ca91cx42_driver *bridge; + + bridge = ca91cx42_bridge->driver_priv; /* Universe can only generate even vectors */ if (statid & 1) return -EINVAL; - mutex_lock(&(vme_int)); + mutex_lock(&(bridge->vme_int)); - tmp = ioread32(ca91cx42_bridge->base + VINT_EN); + tmp = ioread32(bridge->base + VINT_EN); /* Set Status/ID */ - iowrite32(statid << 24, ca91cx42_bridge->base + STATID); + iowrite32(statid << 24, bridge->base + STATID); /* Assert VMEbus IRQ */ tmp = tmp | (1 << (level + 24)); - iowrite32(tmp, ca91cx42_bridge->base + VINT_EN); + iowrite32(tmp, bridge->base + VINT_EN); /* Wait for IACK */ - wait_event_interruptible(iack_queue, 0); + wait_event_interruptible(bridge->iack_queue, 0); /* Return interrupt to low state */ - tmp = ioread32(ca91cx42_bridge->base + VINT_EN); + tmp = ioread32(bridge->base + VINT_EN); tmp = tmp & ~(1 << (level + 24)); - iowrite32(tmp, ca91cx42_bridge->base + VINT_EN); + iowrite32(tmp, bridge->base + VINT_EN); - mutex_unlock(&(vme_int)); + mutex_unlock(&(bridge->vme_int)); return 0; } @@ -330,9 +322,12 @@ int ca91cx42_slave_set(struct vme_slave_resource *image, int enabled, unsigned long long vme_base, unsigned long long size, dma_addr_t pci_base, vme_address_t aspace, vme_cycle_t cycle) { - unsigned int i, addr = 0, granularity = 0; + unsigned int i, addr = 0, granularity; unsigned int temp_ctl = 0; unsigned int vme_bound, pci_offset; + struct ca91cx42_driver *bridge; + + bridge = image->parent->driver_priv; i = image->number; @@ -366,13 +361,9 @@ int ca91cx42_slave_set(struct vme_slave_resource *image, int enabled, * Bound address is a valid address for the window, adjust * accordingly */ - vme_bound = vme_base + size - granularity; + vme_bound = vme_base + size; pci_offset = pci_base - vme_base; - /* XXX Need to check that vme_base, vme_bound and pci_offset aren't - * too big for registers - */ - if ((i == 0) || (i == 4)) granularity = 0x1000; else @@ -392,26 +383,14 @@ int ca91cx42_slave_set(struct vme_slave_resource *image, int enabled, } /* Disable while we are mucking around */ - temp_ctl = ioread32(ca91cx42_bridge->base + CA91CX42_VSI_CTL[i]); + temp_ctl = ioread32(bridge->base + CA91CX42_VSI_CTL[i]); temp_ctl &= ~CA91CX42_VSI_CTL_EN; - iowrite32(temp_ctl, ca91cx42_bridge->base + CA91CX42_VSI_CTL[i]); + iowrite32(temp_ctl, bridge->base + CA91CX42_VSI_CTL[i]); /* Setup mapping */ - iowrite32(vme_base, ca91cx42_bridge->base + CA91CX42_VSI_BS[i]); - iowrite32(vme_bound, ca91cx42_bridge->base + CA91CX42_VSI_BD[i]); - iowrite32(pci_offset, ca91cx42_bridge->base + CA91CX42_VSI_TO[i]); - -/* XXX Prefetch stuff currently unsupported */ -#if 0 - if (vmeIn->wrPostEnable) - temp_ctl |= CA91CX42_VSI_CTL_PWEN; - if (vmeIn->prefetchEnable) - temp_ctl |= CA91CX42_VSI_CTL_PREN; - if (vmeIn->rmwLock) - temp_ctl |= CA91CX42_VSI_CTL_LLRMW; - if (vmeIn->data64BitCapable) - temp_ctl |= CA91CX42_VSI_CTL_LD64EN; -#endif + iowrite32(vme_base, bridge->base + CA91CX42_VSI_BS[i]); + iowrite32(vme_bound, bridge->base + CA91CX42_VSI_BD[i]); + iowrite32(pci_offset, bridge->base + CA91CX42_VSI_TO[i]); /* Setup address space */ temp_ctl &= ~CA91CX42_VSI_CTL_VAS_M; @@ -429,12 +408,12 @@ int ca91cx42_slave_set(struct vme_slave_resource *image, int enabled, temp_ctl |= CA91CX42_VSI_CTL_PGM_DATA; /* Write ctl reg without enable */ - iowrite32(temp_ctl, ca91cx42_bridge->base + CA91CX42_VSI_CTL[i]); + iowrite32(temp_ctl, bridge->base + CA91CX42_VSI_CTL[i]); if (enabled) temp_ctl |= CA91CX42_VSI_CTL_EN; - iowrite32(temp_ctl, ca91cx42_bridge->base + CA91CX42_VSI_CTL[i]); + iowrite32(temp_ctl, bridge->base + CA91CX42_VSI_CTL[i]); return 0; } @@ -445,6 +424,9 @@ int ca91cx42_slave_get(struct vme_slave_resource *image, int *enabled, { unsigned int i, granularity = 0, ctl = 0; unsigned long long vme_bound, pci_offset; + struct ca91cx42_driver *bridge; + + bridge = image->parent->driver_priv; i = image->number; @@ -454,11 +436,11 @@ int ca91cx42_slave_get(struct vme_slave_resource *image, int *enabled, granularity = 0x10000; /* Read Registers */ - ctl = ioread32(ca91cx42_bridge->base + CA91CX42_VSI_CTL[i]); + ctl = ioread32(bridge->base + CA91CX42_VSI_CTL[i]); - *vme_base = ioread32(ca91cx42_bridge->base + CA91CX42_VSI_BS[i]); - vme_bound = ioread32(ca91cx42_bridge->base + CA91CX42_VSI_BD[i]); - pci_offset = ioread32(ca91cx42_bridge->base + CA91CX42_VSI_TO[i]); + *vme_base = ioread32(bridge->base + CA91CX42_VSI_BS[i]); + vme_bound = ioread32(bridge->base + CA91CX42_VSI_BD[i]); + pci_offset = ioread32(bridge->base + CA91CX42_VSI_TO[i]); *pci_base = (dma_addr_t)vme_base + pci_offset; *size = (unsigned long long)((vme_bound - *vme_base) + granularity); @@ -502,6 +484,9 @@ static int ca91cx42_alloc_resource(struct vme_master_resource *image, unsigned long long existing_size; int retval = 0; struct pci_dev *pdev; + struct vme_bridge *ca91cx42_bridge; + + ca91cx42_bridge = image->parent; /* Find pci_dev container of dev */ if (ca91cx42_bridge->parent == NULL) { @@ -510,8 +495,8 @@ static int ca91cx42_alloc_resource(struct vme_master_resource *image, } pdev = container_of(ca91cx42_bridge->parent, struct pci_dev, dev); - existing_size = (unsigned long long)(image->pci_resource.end - - image->pci_resource.start); + existing_size = (unsigned long long)(image->bus_resource.end - + image->bus_resource.start); /* If the existing size is OK, return */ if (existing_size == (size - 1)) @@ -520,15 +505,15 @@ static int ca91cx42_alloc_resource(struct vme_master_resource *image, if (existing_size != 0) { iounmap(image->kern_base); image->kern_base = NULL; - if (image->pci_resource.name != NULL) - kfree(image->pci_resource.name); - release_resource(&(image->pci_resource)); - memset(&(image->pci_resource), 0, sizeof(struct resource)); + if (image->bus_resource.name != NULL) + kfree(image->bus_resource.name); + release_resource(&(image->bus_resource)); + memset(&(image->bus_resource), 0, sizeof(struct resource)); } - if (image->pci_resource.name == NULL) { - image->pci_resource.name = kmalloc(VMENAMSIZ+3, GFP_KERNEL); - if (image->pci_resource.name == NULL) { + if (image->bus_resource.name == NULL) { + image->bus_resource.name = kmalloc(VMENAMSIZ+3, GFP_KERNEL); + if (image->bus_resource.name == NULL) { printk(KERN_ERR "Unable to allocate memory for resource" " name\n"); retval = -ENOMEM; @@ -536,26 +521,26 @@ static int ca91cx42_alloc_resource(struct vme_master_resource *image, } } - sprintf((char *)image->pci_resource.name, "%s.%d", + sprintf((char *)image->bus_resource.name, "%s.%d", ca91cx42_bridge->name, image->number); - image->pci_resource.start = 0; - image->pci_resource.end = (unsigned long)size; - image->pci_resource.flags = IORESOURCE_MEM; + image->bus_resource.start = 0; + image->bus_resource.end = (unsigned long)size; + image->bus_resource.flags = IORESOURCE_MEM; retval = pci_bus_alloc_resource(pdev->bus, - &(image->pci_resource), size, size, PCIBIOS_MIN_MEM, + &(image->bus_resource), size, size, PCIBIOS_MIN_MEM, 0, NULL, NULL); if (retval) { printk(KERN_ERR "Failed to allocate mem resource for " "window %d size 0x%lx start 0x%lx\n", image->number, (unsigned long)size, - (unsigned long)image->pci_resource.start); + (unsigned long)image->bus_resource.start); goto err_resource; } image->kern_base = ioremap_nocache( - image->pci_resource.start, size); + image->bus_resource.start, size); if (image->kern_base == NULL) { printk(KERN_ERR "Failed to remap resource\n"); retval = -ENOMEM; @@ -567,24 +552,24 @@ static int ca91cx42_alloc_resource(struct vme_master_resource *image, iounmap(image->kern_base); image->kern_base = NULL; err_remap: - release_resource(&(image->pci_resource)); + release_resource(&(image->bus_resource)); err_resource: - kfree(image->pci_resource.name); - memset(&(image->pci_resource), 0, sizeof(struct resource)); + kfree(image->bus_resource.name); + memset(&(image->bus_resource), 0, sizeof(struct resource)); err_name: return retval; } /* - * * Free and unmap PCI Resource - * */ + * Free and unmap PCI Resource + */ static void ca91cx42_free_resource(struct vme_master_resource *image) { iounmap(image->kern_base); image->kern_base = NULL; - release_resource(&(image->pci_resource)); - kfree(image->pci_resource.name); - memset(&(image->pci_resource), 0, sizeof(struct resource)); + release_resource(&(image->bus_resource)); + kfree(image->bus_resource.name); + memset(&(image->bus_resource), 0, sizeof(struct resource)); } @@ -593,17 +578,27 @@ int ca91cx42_master_set(struct vme_master_resource *image, int enabled, vme_address_t aspace, vme_cycle_t cycle, vme_width_t dwidth) { int retval = 0; - unsigned int i; + unsigned int i, granularity = 0; unsigned int temp_ctl = 0; unsigned long long pci_bound, vme_offset, pci_base; + struct ca91cx42_driver *bridge; + + bridge = image->parent->driver_priv; + + i = image->number; + + if ((i == 0) || (i == 4)) + granularity = 0x1000; + else + granularity = 0x10000; /* Verify input data */ - if (vme_base & 0xFFF) { + if (vme_base & (granularity - 1)) { printk(KERN_ERR "Invalid VME Window alignment\n"); retval = -EINVAL; goto err_window; } - if (size & 0xFFF) { + if (size & (granularity - 1)) { printk(KERN_ERR "Invalid VME Window alignment\n"); retval = -EINVAL; goto err_window; @@ -611,9 +606,6 @@ int ca91cx42_master_set(struct vme_master_resource *image, int enabled, spin_lock(&(image->lock)); - /* XXX We should do this much later, so that we can exit without - * needing to redo the mapping... - */ /* * Let's allocate the resource here rather than further up the stack as * it avoids pushing loads of bus dependant stuff up the stack @@ -627,27 +619,19 @@ int ca91cx42_master_set(struct vme_master_resource *image, int enabled, goto err_res; } - pci_base = (unsigned long long)image->pci_resource.start; + pci_base = (unsigned long long)image->bus_resource.start; /* * Bound address is a valid address for the window, adjust * according to window granularity. */ - pci_bound = pci_base + (size - 0x1000); + pci_bound = pci_base + size; vme_offset = vme_base - pci_base; - i = image->number; - /* Disable while we are mucking around */ - temp_ctl = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_CTL[i]); + temp_ctl = ioread32(bridge->base + CA91CX42_LSI_CTL[i]); temp_ctl &= ~CA91CX42_LSI_CTL_EN; - iowrite32(temp_ctl, ca91cx42_bridge->base + CA91CX42_LSI_CTL[i]); - -/* XXX Prefetch stuff currently unsupported */ -#if 0 - if (vmeOut->wrPostEnable) - temp_ctl |= 0x40000000; -#endif + iowrite32(temp_ctl, bridge->base + CA91CX42_LSI_CTL[i]); /* Setup cycle types */ temp_ctl &= ~CA91CX42_LSI_CTL_VCT_M; @@ -718,17 +702,17 @@ int ca91cx42_master_set(struct vme_master_resource *image, int enabled, temp_ctl |= CA91CX42_LSI_CTL_PGM_PGM; /* Setup mapping */ - iowrite32(pci_base, ca91cx42_bridge->base + CA91CX42_LSI_BS[i]); - iowrite32(pci_bound, ca91cx42_bridge->base + CA91CX42_LSI_BD[i]); - iowrite32(vme_offset, ca91cx42_bridge->base + CA91CX42_LSI_TO[i]); + iowrite32(pci_base, bridge->base + CA91CX42_LSI_BS[i]); + iowrite32(pci_bound, bridge->base + CA91CX42_LSI_BD[i]); + iowrite32(vme_offset, bridge->base + CA91CX42_LSI_TO[i]); /* Write ctl reg without enable */ - iowrite32(temp_ctl, ca91cx42_bridge->base + CA91CX42_LSI_CTL[i]); + iowrite32(temp_ctl, bridge->base + CA91CX42_LSI_CTL[i]); if (enabled) temp_ctl |= CA91CX42_LSI_CTL_EN; - iowrite32(temp_ctl, ca91cx42_bridge->base + CA91CX42_LSI_CTL[i]); + iowrite32(temp_ctl, bridge->base + CA91CX42_LSI_CTL[i]); spin_unlock(&(image->lock)); return 0; @@ -747,17 +731,20 @@ int __ca91cx42_master_get(struct vme_master_resource *image, int *enabled, { unsigned int i, ctl; unsigned long long pci_base, pci_bound, vme_offset; + struct ca91cx42_driver *bridge; + + bridge = image->parent->driver_priv; i = image->number; - ctl = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_CTL[i]); + ctl = ioread32(bridge->base + CA91CX42_LSI_CTL[i]); - pci_base = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_BS[i]); - vme_offset = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_TO[i]); - pci_bound = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_BD[i]); + pci_base = ioread32(bridge->base + CA91CX42_LSI_BS[i]); + vme_offset = ioread32(bridge->base + CA91CX42_LSI_TO[i]); + pci_bound = ioread32(bridge->base + CA91CX42_LSI_BD[i]); *vme_base = pci_base + vme_offset; - *size = (pci_bound - pci_base) + 0x1000; + *size = (unsigned long long)(pci_bound - pci_base); *enabled = 0; *aspace = 0; @@ -822,12 +809,6 @@ int __ca91cx42_master_get(struct vme_master_resource *image, int *enabled, break; } -/* XXX Prefetch stuff currently unsupported */ -#if 0 - if (ctl & 0x40000000) - vmeOut->wrPostEnable = 1; -#endif - return 0; } @@ -850,7 +831,7 @@ int ca91cx42_master_get(struct vme_master_resource *image, int *enabled, ssize_t ca91cx42_master_read(struct vme_master_resource *image, void *buf, size_t count, loff_t offset) { - int retval; + ssize_t retval; spin_lock(&(image->lock)); @@ -877,12 +858,528 @@ ssize_t ca91cx42_master_write(struct vme_master_resource *image, void *buf, return retval; } -int ca91cx42_slot_get(void) +unsigned int ca91cx42_master_rmw(struct vme_master_resource *image, + unsigned int mask, unsigned int compare, unsigned int swap, + loff_t offset) +{ + u32 pci_addr, result; + int i; + struct ca91cx42_driver *bridge; + struct device *dev; + + bridge = image->parent->driver_priv; + dev = image->parent->parent; + + /* Find the PCI address that maps to the desired VME address */ + i = image->number; + + /* Locking as we can only do one of these at a time */ + mutex_lock(&(bridge->vme_rmw)); + + /* Lock image */ + spin_lock(&(image->lock)); + + pci_addr = (u32)image->kern_base + offset; + + /* Address must be 4-byte aligned */ + if (pci_addr & 0x3) { + dev_err(dev, "RMW Address not 4-byte aligned\n"); + return -EINVAL; + } + + /* Ensure RMW Disabled whilst configuring */ + iowrite32(0, bridge->base + SCYC_CTL); + + /* Configure registers */ + iowrite32(mask, bridge->base + SCYC_EN); + iowrite32(compare, bridge->base + SCYC_CMP); + iowrite32(swap, bridge->base + SCYC_SWP); + iowrite32(pci_addr, bridge->base + SCYC_ADDR); + + /* Enable RMW */ + iowrite32(CA91CX42_SCYC_CTL_CYC_RMW, bridge->base + SCYC_CTL); + + /* Kick process off with a read to the required address. */ + result = ioread32(image->kern_base + offset); + + /* Disable RMW */ + iowrite32(0, bridge->base + SCYC_CTL); + + spin_unlock(&(image->lock)); + + mutex_unlock(&(bridge->vme_rmw)); + + return result; +} + +int ca91cx42_dma_list_add(struct vme_dma_list *list, struct vme_dma_attr *src, + struct vme_dma_attr *dest, size_t count) +{ + struct ca91cx42_dma_entry *entry, *prev; + struct vme_dma_pci *pci_attr; + struct vme_dma_vme *vme_attr; + dma_addr_t desc_ptr; + int retval = 0; + + /* XXX descriptor must be aligned on 64-bit boundaries */ + entry = (struct ca91cx42_dma_entry *) + kmalloc(sizeof(struct ca91cx42_dma_entry), GFP_KERNEL); + if (entry == NULL) { + printk(KERN_ERR "Failed to allocate memory for dma resource " + "structure\n"); + retval = -ENOMEM; + goto err_mem; + } + + /* Test descriptor alignment */ + if ((unsigned long)&(entry->descriptor) & CA91CX42_DCPP_M) { + printk("Descriptor not aligned to 16 byte boundary as " + "required: %p\n", &(entry->descriptor)); + retval = -EINVAL; + goto err_align; + } + + memset(&(entry->descriptor), 0, sizeof(struct ca91cx42_dma_descriptor)); + + if (dest->type == VME_DMA_VME) { + entry->descriptor.dctl |= CA91CX42_DCTL_L2V; + vme_attr = (struct vme_dma_vme *)dest->private; + pci_attr = (struct vme_dma_pci *)src->private; + } else { + vme_attr = (struct vme_dma_vme *)src->private; + pci_attr = (struct vme_dma_pci *)dest->private; + } + + /* Check we can do fullfill required attributes */ + if ((vme_attr->aspace & ~(VME_A16 | VME_A24 | VME_A32 | VME_USER1 | + VME_USER2)) != 0) { + + printk(KERN_ERR "Unsupported cycle type\n"); + retval = -EINVAL; + goto err_aspace; + } + + if ((vme_attr->cycle & ~(VME_SCT | VME_BLT | VME_SUPER | VME_USER | + VME_PROG | VME_DATA)) != 0) { + + printk(KERN_ERR "Unsupported cycle type\n"); + retval = -EINVAL; + goto err_cycle; + } + + /* Check to see if we can fullfill source and destination */ + if (!(((src->type == VME_DMA_PCI) && (dest->type == VME_DMA_VME)) || + ((src->type == VME_DMA_VME) && (dest->type == VME_DMA_PCI)))) { + + printk(KERN_ERR "Cannot perform transfer with this " + "source-destination combination\n"); + retval = -EINVAL; + goto err_direct; + } + + /* Setup cycle types */ + if (vme_attr->cycle & VME_BLT) + entry->descriptor.dctl |= CA91CX42_DCTL_VCT_BLT; + + /* Setup data width */ + switch (vme_attr->dwidth) { + case VME_D8: + entry->descriptor.dctl |= CA91CX42_DCTL_VDW_D8; + break; + case VME_D16: + entry->descriptor.dctl |= CA91CX42_DCTL_VDW_D16; + break; + case VME_D32: + entry->descriptor.dctl |= CA91CX42_DCTL_VDW_D32; + break; + case VME_D64: + entry->descriptor.dctl |= CA91CX42_DCTL_VDW_D64; + break; + default: + printk(KERN_ERR "Invalid data width\n"); + return -EINVAL; + } + + /* Setup address space */ + switch (vme_attr->aspace) { + case VME_A16: + entry->descriptor.dctl |= CA91CX42_DCTL_VAS_A16; + break; + case VME_A24: + entry->descriptor.dctl |= CA91CX42_DCTL_VAS_A24; + break; + case VME_A32: + entry->descriptor.dctl |= CA91CX42_DCTL_VAS_A32; + break; + case VME_USER1: + entry->descriptor.dctl |= CA91CX42_DCTL_VAS_USER1; + break; + case VME_USER2: + entry->descriptor.dctl |= CA91CX42_DCTL_VAS_USER2; + break; + default: + printk(KERN_ERR "Invalid address space\n"); + return -EINVAL; + break; + } + + if (vme_attr->cycle & VME_SUPER) + entry->descriptor.dctl |= CA91CX42_DCTL_SUPER_SUPR; + if (vme_attr->cycle & VME_PROG) + entry->descriptor.dctl |= CA91CX42_DCTL_PGM_PGM; + + entry->descriptor.dtbc = count; + entry->descriptor.dla = pci_attr->address; + entry->descriptor.dva = vme_attr->address; + entry->descriptor.dcpp = CA91CX42_DCPP_NULL; + + /* Add to list */ + list_add_tail(&(entry->list), &(list->entries)); + + /* Fill out previous descriptors "Next Address" */ + if (entry->list.prev != &(list->entries)) { + prev = list_entry(entry->list.prev, struct ca91cx42_dma_entry, + list); + /* We need the bus address for the pointer */ + desc_ptr = virt_to_bus(&(entry->descriptor)); + prev->descriptor.dcpp = desc_ptr & ~CA91CX42_DCPP_M; + } + + return 0; + +err_cycle: +err_aspace: +err_direct: +err_align: + kfree(entry); +err_mem: + return retval; +} + +static int ca91cx42_dma_busy(struct vme_bridge *ca91cx42_bridge) +{ + u32 tmp; + struct ca91cx42_driver *bridge; + + bridge = ca91cx42_bridge->driver_priv; + + tmp = ioread32(bridge->base + DGCS); + + if (tmp & CA91CX42_DGCS_ACT) + return 0; + else + return 1; +} + +int ca91cx42_dma_list_exec(struct vme_dma_list *list) +{ + struct vme_dma_resource *ctrlr; + struct ca91cx42_dma_entry *entry; + int retval = 0; + dma_addr_t bus_addr; + u32 val; + + struct ca91cx42_driver *bridge; + + ctrlr = list->parent; + + bridge = ctrlr->parent->driver_priv; + + mutex_lock(&(ctrlr->mtx)); + + if (!(list_empty(&(ctrlr->running)))) { + /* + * XXX We have an active DMA transfer and currently haven't + * sorted out the mechanism for "pending" DMA transfers. + * Return busy. + */ + /* Need to add to pending here */ + mutex_unlock(&(ctrlr->mtx)); + return -EBUSY; + } else { + list_add(&(list->list), &(ctrlr->running)); + } + + /* Get first bus address and write into registers */ + entry = list_first_entry(&(list->entries), struct ca91cx42_dma_entry, + list); + + bus_addr = virt_to_bus(&(entry->descriptor)); + + mutex_unlock(&(ctrlr->mtx)); + + iowrite32(0, bridge->base + DTBC); + iowrite32(bus_addr & ~CA91CX42_DCPP_M, bridge->base + DCPP); + + /* Start the operation */ + val = ioread32(bridge->base + DGCS); + + /* XXX Could set VMEbus On and Off Counters here */ + val &= (CA91CX42_DGCS_VON_M | CA91CX42_DGCS_VOFF_M); + + val |= (CA91CX42_DGCS_CHAIN | CA91CX42_DGCS_STOP | CA91CX42_DGCS_HALT | + CA91CX42_DGCS_DONE | CA91CX42_DGCS_LERR | CA91CX42_DGCS_VERR | + CA91CX42_DGCS_PERR); + + iowrite32(val, bridge->base + DGCS); + + val |= CA91CX42_DGCS_GO; + + iowrite32(val, bridge->base + DGCS); + + wait_event_interruptible(bridge->dma_queue, + ca91cx42_dma_busy(ctrlr->parent)); + + /* + * Read status register, this register is valid until we kick off a + * new transfer. + */ + val = ioread32(bridge->base + DGCS); + + if (val & (CA91CX42_DGCS_LERR | CA91CX42_DGCS_VERR | + CA91CX42_DGCS_PERR)) { + + printk(KERN_ERR "ca91c042: DMA Error. DGCS=%08X\n", val); + val = ioread32(bridge->base + DCTL); + } + + /* Remove list from running list */ + mutex_lock(&(ctrlr->mtx)); + list_del(&(list->list)); + mutex_unlock(&(ctrlr->mtx)); + + return retval; + +} + +int ca91cx42_dma_list_empty(struct vme_dma_list *list) +{ + struct list_head *pos, *temp; + struct ca91cx42_dma_entry *entry; + + /* detach and free each entry */ + list_for_each_safe(pos, temp, &(list->entries)) { + list_del(pos); + entry = list_entry(pos, struct ca91cx42_dma_entry, list); + kfree(entry); + } + + return 0; +} + +/* + * All 4 location monitors reside at the same base - this is therefore a + * system wide configuration. + * + * This does not enable the LM monitor - that should be done when the first + * callback is attached and disabled when the last callback is removed. + */ +int ca91cx42_lm_set(struct vme_lm_resource *lm, unsigned long long lm_base, + vme_address_t aspace, vme_cycle_t cycle) +{ + u32 temp_base, lm_ctl = 0; + int i; + struct ca91cx42_driver *bridge; + struct device *dev; + + bridge = lm->parent->driver_priv; + dev = lm->parent->parent; + + /* Check the alignment of the location monitor */ + temp_base = (u32)lm_base; + if (temp_base & 0xffff) { + dev_err(dev, "Location monitor must be aligned to 64KB " + "boundary"); + return -EINVAL; + } + + mutex_lock(&(lm->mtx)); + + /* If we already have a callback attached, we can't move it! */ + for (i = 0; i < lm->monitors; i++) { + if (bridge->lm_callback[i] != NULL) { + mutex_unlock(&(lm->mtx)); + dev_err(dev, "Location monitor callback attached, " + "can't reset\n"); + return -EBUSY; + } + } + + switch (aspace) { + case VME_A16: + lm_ctl |= CA91CX42_LM_CTL_AS_A16; + break; + case VME_A24: + lm_ctl |= CA91CX42_LM_CTL_AS_A24; + break; + case VME_A32: + lm_ctl |= CA91CX42_LM_CTL_AS_A32; + break; + default: + mutex_unlock(&(lm->mtx)); + dev_err(dev, "Invalid address space\n"); + return -EINVAL; + break; + } + + if (cycle & VME_SUPER) + lm_ctl |= CA91CX42_LM_CTL_SUPR; + if (cycle & VME_USER) + lm_ctl |= CA91CX42_LM_CTL_NPRIV; + if (cycle & VME_PROG) + lm_ctl |= CA91CX42_LM_CTL_PGM; + if (cycle & VME_DATA) + lm_ctl |= CA91CX42_LM_CTL_DATA; + + iowrite32(lm_base, bridge->base + LM_BS); + iowrite32(lm_ctl, bridge->base + LM_CTL); + + mutex_unlock(&(lm->mtx)); + + return 0; +} + +/* Get configuration of the callback monitor and return whether it is enabled + * or disabled. + */ +int ca91cx42_lm_get(struct vme_lm_resource *lm, unsigned long long *lm_base, + vme_address_t *aspace, vme_cycle_t *cycle) +{ + u32 lm_ctl, enabled = 0; + struct ca91cx42_driver *bridge; + + bridge = lm->parent->driver_priv; + + mutex_lock(&(lm->mtx)); + + *lm_base = (unsigned long long)ioread32(bridge->base + LM_BS); + lm_ctl = ioread32(bridge->base + LM_CTL); + + if (lm_ctl & CA91CX42_LM_CTL_EN) + enabled = 1; + + if ((lm_ctl & CA91CX42_LM_CTL_AS_M) == CA91CX42_LM_CTL_AS_A16) + *aspace = VME_A16; + if ((lm_ctl & CA91CX42_LM_CTL_AS_M) == CA91CX42_LM_CTL_AS_A24) + *aspace = VME_A24; + if ((lm_ctl & CA91CX42_LM_CTL_AS_M) == CA91CX42_LM_CTL_AS_A32) + *aspace = VME_A32; + + *cycle = 0; + if (lm_ctl & CA91CX42_LM_CTL_SUPR) + *cycle |= VME_SUPER; + if (lm_ctl & CA91CX42_LM_CTL_NPRIV) + *cycle |= VME_USER; + if (lm_ctl & CA91CX42_LM_CTL_PGM) + *cycle |= VME_PROG; + if (lm_ctl & CA91CX42_LM_CTL_DATA) + *cycle |= VME_DATA; + + mutex_unlock(&(lm->mtx)); + + return enabled; +} + +/* + * Attach a callback to a specific location monitor. + * + * Callback will be passed the monitor triggered. + */ +int ca91cx42_lm_attach(struct vme_lm_resource *lm, int monitor, + void (*callback)(int)) +{ + u32 lm_ctl, tmp; + struct ca91cx42_driver *bridge; + struct device *dev; + + bridge = lm->parent->driver_priv; + dev = lm->parent->parent; + + mutex_lock(&(lm->mtx)); + + /* Ensure that the location monitor is configured - need PGM or DATA */ + lm_ctl = ioread32(bridge->base + LM_CTL); + if ((lm_ctl & (CA91CX42_LM_CTL_PGM | CA91CX42_LM_CTL_DATA)) == 0) { + mutex_unlock(&(lm->mtx)); + dev_err(dev, "Location monitor not properly configured\n"); + return -EINVAL; + } + + /* Check that a callback isn't already attached */ + if (bridge->lm_callback[monitor] != NULL) { + mutex_unlock(&(lm->mtx)); + dev_err(dev, "Existing callback attached\n"); + return -EBUSY; + } + + /* Attach callback */ + bridge->lm_callback[monitor] = callback; + + /* Enable Location Monitor interrupt */ + tmp = ioread32(bridge->base + LINT_EN); + tmp |= CA91CX42_LINT_LM[monitor]; + iowrite32(tmp, bridge->base + LINT_EN); + + /* Ensure that global Location Monitor Enable set */ + if ((lm_ctl & CA91CX42_LM_CTL_EN) == 0) { + lm_ctl |= CA91CX42_LM_CTL_EN; + iowrite32(lm_ctl, bridge->base + LM_CTL); + } + + mutex_unlock(&(lm->mtx)); + + return 0; +} + +/* + * Detach a callback function forn a specific location monitor. + */ +int ca91cx42_lm_detach(struct vme_lm_resource *lm, int monitor) +{ + u32 tmp; + struct ca91cx42_driver *bridge; + + bridge = lm->parent->driver_priv; + + mutex_lock(&(lm->mtx)); + + /* Disable Location Monitor and ensure previous interrupts are clear */ + tmp = ioread32(bridge->base + LINT_EN); + tmp &= ~CA91CX42_LINT_LM[monitor]; + iowrite32(tmp, bridge->base + LINT_EN); + + iowrite32(CA91CX42_LINT_LM[monitor], + bridge->base + LINT_STAT); + + /* Detach callback */ + bridge->lm_callback[monitor] = NULL; + + /* If all location monitors disabled, disable global Location Monitor */ + if ((tmp & (CA91CX42_LINT_LM0 | CA91CX42_LINT_LM1 | CA91CX42_LINT_LM2 | + CA91CX42_LINT_LM3)) == 0) { + tmp = ioread32(bridge->base + LM_CTL); + tmp &= ~CA91CX42_LM_CTL_EN; + iowrite32(tmp, bridge->base + LM_CTL); + } + + mutex_unlock(&(lm->mtx)); + + return 0; +} + +int ca91cx42_slot_get(struct vme_bridge *ca91cx42_bridge) { u32 slot = 0; + struct ca91cx42_driver *bridge; + + bridge = ca91cx42_bridge->driver_priv; + + if (!geoid) { + slot = ioread32(bridge->base + VCSR_BS); + slot = ((slot & CA91CX42_VCSR_BS_SLOT_M) >> 27); + } else + slot = geoid; - slot = ioread32(ca91cx42_bridge->base + VCSR_BS); - slot = ((slot & CA91CX42_VCSR_BS_SLOT_M) >> 27); return (int)slot; } @@ -900,19 +1397,21 @@ static int __init ca91cx42_init(void) * Auto-ID or Geographic address. This function ensures that the window is * enabled at an offset consistent with the boards geopgraphic address. */ -static int ca91cx42_crcsr_init(struct pci_dev *pdev) +static int ca91cx42_crcsr_init(struct vme_bridge *ca91cx42_bridge, + struct pci_dev *pdev) { unsigned int crcsr_addr; int tmp, slot; + struct ca91cx42_driver *bridge; + + bridge = ca91cx42_bridge->driver_priv; + + slot = ca91cx42_slot_get(ca91cx42_bridge); + + /* Write CSR Base Address if slot ID is supplied as a module param */ + if (geoid) + iowrite32(geoid << 27, bridge->base + VCSR_BS); -/* XXX We may need to set this somehow as the Universe II does not support - * geographical addressing. - */ -#if 0 - if (vme_slotnum != -1) - iowrite32(vme_slotnum << 27, ca91cx42_bridge->base + VCSR_BS); -#endif - slot = ca91cx42_slot_get(); dev_info(&pdev->dev, "CR/CSR Offset: %d\n", slot); if (slot == 0) { dev_err(&pdev->dev, "Slot number is unset, not configuring " @@ -921,39 +1420,44 @@ static int ca91cx42_crcsr_init(struct pci_dev *pdev) } /* Allocate mem for CR/CSR image */ - crcsr_kernel = pci_alloc_consistent(pdev, VME_CRCSR_BUF_SIZE, - &crcsr_bus); - if (crcsr_kernel == NULL) { + bridge->crcsr_kernel = pci_alloc_consistent(pdev, VME_CRCSR_BUF_SIZE, + &(bridge->crcsr_bus)); + if (bridge->crcsr_kernel == NULL) { dev_err(&pdev->dev, "Failed to allocate memory for CR/CSR " "image\n"); return -ENOMEM; } - memset(crcsr_kernel, 0, VME_CRCSR_BUF_SIZE); + memset(bridge->crcsr_kernel, 0, VME_CRCSR_BUF_SIZE); crcsr_addr = slot * (512 * 1024); - iowrite32(crcsr_bus - crcsr_addr, ca91cx42_bridge->base + VCSR_TO); + iowrite32(bridge->crcsr_bus - crcsr_addr, bridge->base + VCSR_TO); - tmp = ioread32(ca91cx42_bridge->base + VCSR_CTL); + tmp = ioread32(bridge->base + VCSR_CTL); tmp |= CA91CX42_VCSR_CTL_EN; - iowrite32(tmp, ca91cx42_bridge->base + VCSR_CTL); + iowrite32(tmp, bridge->base + VCSR_CTL); return 0; } -static void ca91cx42_crcsr_exit(struct pci_dev *pdev) +static void ca91cx42_crcsr_exit(struct vme_bridge *ca91cx42_bridge, + struct pci_dev *pdev) { u32 tmp; + struct ca91cx42_driver *bridge; + + bridge = ca91cx42_bridge->driver_priv; /* Turn off CR/CSR space */ - tmp = ioread32(ca91cx42_bridge->base + VCSR_CTL); + tmp = ioread32(bridge->base + VCSR_CTL); tmp &= ~CA91CX42_VCSR_CTL_EN; - iowrite32(tmp, ca91cx42_bridge->base + VCSR_CTL); + iowrite32(tmp, bridge->base + VCSR_CTL); /* Free image */ - iowrite32(0, ca91cx42_bridge->base + VCSR_TO); + iowrite32(0, bridge->base + VCSR_TO); - pci_free_consistent(pdev, VME_CRCSR_BUF_SIZE, crcsr_kernel, crcsr_bus); + pci_free_consistent(pdev, VME_CRCSR_BUF_SIZE, bridge->crcsr_kernel, + bridge->crcsr_bus); } static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id) @@ -961,11 +1465,11 @@ static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id) int retval, i; u32 data; struct list_head *pos = NULL; + struct vme_bridge *ca91cx42_bridge; + struct ca91cx42_driver *ca91cx42_device; struct vme_master_resource *master_image; struct vme_slave_resource *slave_image; -#if 0 struct vme_dma_resource *dma_ctrlr; -#endif struct vme_lm_resource *lm; /* We want to support more than one of each bridge so we need to @@ -982,6 +1486,19 @@ static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id) memset(ca91cx42_bridge, 0, sizeof(struct vme_bridge)); + ca91cx42_device = kmalloc(sizeof(struct ca91cx42_driver), GFP_KERNEL); + + if (ca91cx42_device == NULL) { + dev_err(&pdev->dev, "Failed to allocate memory for device " + "structure\n"); + retval = -ENOMEM; + goto err_driver; + } + + memset(ca91cx42_device, 0, sizeof(struct ca91cx42_driver)); + + ca91cx42_bridge->driver_priv = ca91cx42_device; + /* Enable the device */ retval = pci_enable_device(pdev); if (retval) { @@ -997,16 +1514,16 @@ static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id) } /* map registers in BAR 0 */ - ca91cx42_bridge->base = ioremap_nocache(pci_resource_start(pdev, 0), + ca91cx42_device->base = ioremap_nocache(pci_resource_start(pdev, 0), 4096); - if (!ca91cx42_bridge->base) { + if (!ca91cx42_device->base) { dev_err(&pdev->dev, "Unable to remap CRG region\n"); retval = -EIO; goto err_remap; } /* Check to see if the mapping worked out */ - data = ioread32(ca91cx42_bridge->base + CA91CX42_PCI_ID) & 0x0000FFFF; + data = ioread32(ca91cx42_device->base + CA91CX42_PCI_ID) & 0x0000FFFF; if (data != PCI_VENDOR_ID_TUNDRA) { dev_err(&pdev->dev, "PCI_ID check failed\n"); retval = -EIO; @@ -1014,11 +1531,10 @@ static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id) } /* Initialize wait queues & mutual exclusion flags */ - /* XXX These need to be moved to the vme_bridge structure */ - init_waitqueue_head(&dma_queue); - init_waitqueue_head(&iack_queue); - mutex_init(&(vme_int)); - mutex_init(&(vme_rmw)); + init_waitqueue_head(&(ca91cx42_device->dma_queue)); + init_waitqueue_head(&(ca91cx42_device->iack_queue)); + mutex_init(&(ca91cx42_device->vme_int)); + mutex_init(&(ca91cx42_device->vme_rmw)); ca91cx42_bridge->parent = &(pdev->dev); strcpy(ca91cx42_bridge->name, driver_name); @@ -1050,7 +1566,7 @@ static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id) master_image->cycle_attr = VME_SCT | VME_BLT | VME_MBLT | VME_SUPER | VME_USER | VME_PROG | VME_DATA; master_image->width_attr = VME_D8 | VME_D16 | VME_D32 | VME_D64; - memset(&(master_image->pci_resource), 0, + memset(&(master_image->bus_resource), 0, sizeof(struct resource)); master_image->kern_base = NULL; list_add_tail(&(master_image->list), @@ -1084,7 +1600,7 @@ static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id) list_add_tail(&(slave_image->list), &(ca91cx42_bridge->slave_resources)); } -#if 0 + /* Add dma engines to list */ INIT_LIST_HEAD(&(ca91cx42_bridge->dma_resources)); for (i = 0; i < CA91C142_MAX_DMA; i++) { @@ -1100,12 +1616,14 @@ static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id) mutex_init(&(dma_ctrlr->mtx)); dma_ctrlr->locked = 0; dma_ctrlr->number = i; + dma_ctrlr->route_attr = VME_DMA_VME_TO_MEM | + VME_DMA_MEM_TO_VME; INIT_LIST_HEAD(&(dma_ctrlr->pending)); INIT_LIST_HEAD(&(dma_ctrlr->running)); list_add_tail(&(dma_ctrlr->list), &(ca91cx42_bridge->dma_resources)); } -#endif + /* Add location monitor to list */ INIT_LIST_HEAD(&(ca91cx42_bridge->lm_resources)); lm = kmalloc(sizeof(struct vme_lm_resource), GFP_KERNEL); @@ -1128,33 +1646,26 @@ static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id) ca91cx42_bridge->master_set = ca91cx42_master_set; ca91cx42_bridge->master_read = ca91cx42_master_read; ca91cx42_bridge->master_write = ca91cx42_master_write; -#if 0 ca91cx42_bridge->master_rmw = ca91cx42_master_rmw; ca91cx42_bridge->dma_list_add = ca91cx42_dma_list_add; ca91cx42_bridge->dma_list_exec = ca91cx42_dma_list_exec; ca91cx42_bridge->dma_list_empty = ca91cx42_dma_list_empty; -#endif ca91cx42_bridge->irq_set = ca91cx42_irq_set; ca91cx42_bridge->irq_generate = ca91cx42_irq_generate; -#if 0 ca91cx42_bridge->lm_set = ca91cx42_lm_set; ca91cx42_bridge->lm_get = ca91cx42_lm_get; ca91cx42_bridge->lm_attach = ca91cx42_lm_attach; ca91cx42_bridge->lm_detach = ca91cx42_lm_detach; -#endif ca91cx42_bridge->slot_get = ca91cx42_slot_get; - data = ioread32(ca91cx42_bridge->base + MISC_CTL); + data = ioread32(ca91cx42_device->base + MISC_CTL); dev_info(&pdev->dev, "Board is%s the VME system controller\n", (data & CA91CX42_MISC_CTL_SYSCON) ? "" : " not"); - dev_info(&pdev->dev, "Slot ID is %d\n", ca91cx42_slot_get()); + dev_info(&pdev->dev, "Slot ID is %d\n", + ca91cx42_slot_get(ca91cx42_bridge)); - if (ca91cx42_crcsr_init(pdev)) { + if (ca91cx42_crcsr_init(ca91cx42_bridge, pdev)) { dev_err(&pdev->dev, "CR/CSR configuration failed.\n"); - retval = -EINVAL; -#if 0 - goto err_crcsr; -#endif } /* Need to save ca91cx42_bridge pointer locally in link list for use in @@ -1166,14 +1677,13 @@ static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id) goto err_reg; } + pci_set_drvdata(pdev, ca91cx42_bridge); + return 0; vme_unregister_bridge(ca91cx42_bridge); err_reg: - ca91cx42_crcsr_exit(pdev); -#if 0 -err_crcsr: -#endif + ca91cx42_crcsr_exit(ca91cx42_bridge, pdev); err_lm: /* resources are stored in link list */ list_for_each(pos, &(ca91cx42_bridge->lm_resources)) { @@ -1181,7 +1691,6 @@ err_lm: list_del(pos); kfree(lm); } -#if 0 err_dma: /* resources are stored in link list */ list_for_each(pos, &(ca91cx42_bridge->dma_resources)) { @@ -1189,7 +1698,6 @@ err_dma: list_del(pos); kfree(dma_ctrlr); } -#endif err_slave: /* resources are stored in link list */ list_for_each(pos, &(ca91cx42_bridge->slave_resources)) { @@ -1206,15 +1714,17 @@ err_master: kfree(master_image); } - ca91cx42_irq_exit(pdev); + ca91cx42_irq_exit(ca91cx42_device, pdev); err_irq: err_test: - iounmap(ca91cx42_bridge->base); + iounmap(ca91cx42_device->base); err_remap: pci_release_regions(pdev); err_resource: pci_disable_device(pdev); err_enable: + kfree(ca91cx42_device); +err_driver: kfree(ca91cx42_bridge); err_struct: return retval; @@ -1228,32 +1738,37 @@ void ca91cx42_remove(struct pci_dev *pdev) struct vme_slave_resource *slave_image; struct vme_dma_resource *dma_ctrlr; struct vme_lm_resource *lm; + struct ca91cx42_driver *bridge; + struct vme_bridge *ca91cx42_bridge = pci_get_drvdata(pdev); + + bridge = ca91cx42_bridge->driver_priv; + /* Turn off Ints */ - iowrite32(0, ca91cx42_bridge->base + LINT_EN); + iowrite32(0, bridge->base + LINT_EN); /* Turn off the windows */ - iowrite32(0x00800000, ca91cx42_bridge->base + LSI0_CTL); - iowrite32(0x00800000, ca91cx42_bridge->base + LSI1_CTL); - iowrite32(0x00800000, ca91cx42_bridge->base + LSI2_CTL); - iowrite32(0x00800000, ca91cx42_bridge->base + LSI3_CTL); - iowrite32(0x00800000, ca91cx42_bridge->base + LSI4_CTL); - iowrite32(0x00800000, ca91cx42_bridge->base + LSI5_CTL); - iowrite32(0x00800000, ca91cx42_bridge->base + LSI6_CTL); - iowrite32(0x00800000, ca91cx42_bridge->base + LSI7_CTL); - iowrite32(0x00F00000, ca91cx42_bridge->base + VSI0_CTL); - iowrite32(0x00F00000, ca91cx42_bridge->base + VSI1_CTL); - iowrite32(0x00F00000, ca91cx42_bridge->base + VSI2_CTL); - iowrite32(0x00F00000, ca91cx42_bridge->base + VSI3_CTL); - iowrite32(0x00F00000, ca91cx42_bridge->base + VSI4_CTL); - iowrite32(0x00F00000, ca91cx42_bridge->base + VSI5_CTL); - iowrite32(0x00F00000, ca91cx42_bridge->base + VSI6_CTL); - iowrite32(0x00F00000, ca91cx42_bridge->base + VSI7_CTL); + iowrite32(0x00800000, bridge->base + LSI0_CTL); + iowrite32(0x00800000, bridge->base + LSI1_CTL); + iowrite32(0x00800000, bridge->base + LSI2_CTL); + iowrite32(0x00800000, bridge->base + LSI3_CTL); + iowrite32(0x00800000, bridge->base + LSI4_CTL); + iowrite32(0x00800000, bridge->base + LSI5_CTL); + iowrite32(0x00800000, bridge->base + LSI6_CTL); + iowrite32(0x00800000, bridge->base + LSI7_CTL); + iowrite32(0x00F00000, bridge->base + VSI0_CTL); + iowrite32(0x00F00000, bridge->base + VSI1_CTL); + iowrite32(0x00F00000, bridge->base + VSI2_CTL); + iowrite32(0x00F00000, bridge->base + VSI3_CTL); + iowrite32(0x00F00000, bridge->base + VSI4_CTL); + iowrite32(0x00F00000, bridge->base + VSI5_CTL); + iowrite32(0x00F00000, bridge->base + VSI6_CTL); + iowrite32(0x00F00000, bridge->base + VSI7_CTL); vme_unregister_bridge(ca91cx42_bridge); -#if 0 - ca91cx42_crcsr_exit(pdev); -#endif + + ca91cx42_crcsr_exit(ca91cx42_bridge, pdev); + /* resources are stored in link list */ list_for_each(pos, &(ca91cx42_bridge->lm_resources)) { lm = list_entry(pos, struct vme_lm_resource, list); @@ -1283,9 +1798,9 @@ void ca91cx42_remove(struct pci_dev *pdev) kfree(master_image); } - ca91cx42_irq_exit(pdev); + ca91cx42_irq_exit(bridge, pdev); - iounmap(ca91cx42_bridge->base); + iounmap(bridge->base); pci_release_regions(pdev); @@ -1299,588 +1814,11 @@ static void __exit ca91cx42_exit(void) pci_unregister_driver(&ca91cx42_driver); } +MODULE_PARM_DESC(geoid, "Override geographical addressing"); +module_param(geoid, int, 0); + MODULE_DESCRIPTION("VME driver for the Tundra Universe II VME bridge"); MODULE_LICENSE("GPL"); module_init(ca91cx42_init); module_exit(ca91cx42_exit); - -/*---------------------------------------------------------------------------- - * STAGING - *--------------------------------------------------------------------------*/ - -#if 0 -#define SWIZZLE(X) ( ((X & 0xFF000000) >> 24) | ((X & 0x00FF0000) >> 8) | ((X & 0x0000FF00) << 8) | ((X & 0x000000FF) << 24)) - -int ca91cx42_master_rmw(vmeRmwCfg_t *vmeRmw) -{ - int temp_ctl = 0; - int tempBS = 0; - int tempBD = 0; - int tempTO = 0; - int vmeBS = 0; - int vmeBD = 0; - int *rmw_pci_data_ptr = NULL; - int *vaDataPtr = NULL; - int i; - vmeOutWindowCfg_t vmeOut; - if (vmeRmw->maxAttempts < 1) { - return -EINVAL; - } - if (vmeRmw->targetAddrU) { - return -EINVAL; - } - /* Find the PCI address that maps to the desired VME address */ - for (i = 0; i < 8; i++) { - temp_ctl = ioread32(ca91cx42_bridge->base + - CA91CX42_LSI_CTL[i]); - if ((temp_ctl & 0x80000000) == 0) { - continue; - } - memset(&vmeOut, 0, sizeof(vmeOut)); - vmeOut.windowNbr = i; - ca91cx42_get_out_bound(&vmeOut); - if (vmeOut.addrSpace != vmeRmw->addrSpace) { - continue; - } - tempBS = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_BS[i]); - tempBD = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_BD[i]); - tempTO = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_TO[i]); - vmeBS = tempBS + tempTO; - vmeBD = tempBD + tempTO; - if ((vmeRmw->targetAddr >= vmeBS) && - (vmeRmw->targetAddr < vmeBD)) { - rmw_pci_data_ptr = - (int *)(tempBS + (vmeRmw->targetAddr - vmeBS)); - vaDataPtr = - (int *)(out_image_va[i] + - (vmeRmw->targetAddr - vmeBS)); - break; - } - } - - /* If no window - fail. */ - if (rmw_pci_data_ptr == NULL) { - return -EINVAL; - } - /* Setup the RMW registers. */ - iowrite32(0, ca91cx42_bridge->base + SCYC_CTL); - iowrite32(SWIZZLE(vmeRmw->enableMask), ca91cx42_bridge->base + SCYC_EN); - iowrite32(SWIZZLE(vmeRmw->compareData), ca91cx42_bridge->base + - SCYC_CMP); - iowrite32(SWIZZLE(vmeRmw->swapData), ca91cx42_bridge->base + SCYC_SWP); - iowrite32((int)rmw_pci_data_ptr, ca91cx42_bridge->base + SCYC_ADDR); - iowrite32(1, ca91cx42_bridge->base + SCYC_CTL); - - /* Run the RMW cycle until either success or max attempts. */ - vmeRmw->numAttempts = 1; - while (vmeRmw->numAttempts <= vmeRmw->maxAttempts) { - - if ((ioread32(vaDataPtr) & vmeRmw->enableMask) == - (vmeRmw->swapData & vmeRmw->enableMask)) { - - iowrite32(0, ca91cx42_bridge->base + SCYC_CTL); - break; - - } - vmeRmw->numAttempts++; - } - - /* If no success, set num Attempts to be greater than max attempts */ - if (vmeRmw->numAttempts > vmeRmw->maxAttempts) { - vmeRmw->numAttempts = vmeRmw->maxAttempts + 1; - } - - return 0; -} - -int uniSetupDctlReg(vmeDmaPacket_t * vmeDma, int *dctlregreturn) -{ - unsigned int dctlreg = 0x80; - struct vmeAttr *vmeAttr; - - if (vmeDma->srcBus == VME_DMA_VME) { - dctlreg = 0; - vmeAttr = &vmeDma->srcVmeAttr; - } else { - dctlreg = 0x80000000; - vmeAttr = &vmeDma->dstVmeAttr; - } - - switch (vmeAttr->maxDataWidth) { - case VME_D8: - break; - case VME_D16: - dctlreg |= 0x00400000; - break; - case VME_D32: - dctlreg |= 0x00800000; - break; - case VME_D64: - dctlreg |= 0x00C00000; - break; - } - - switch (vmeAttr->addrSpace) { - case VME_A16: - break; - case VME_A24: - dctlreg |= 0x00010000; - break; - case VME_A32: - dctlreg |= 0x00020000; - break; - case VME_USER1: - dctlreg |= 0x00060000; - break; - case VME_USER2: - dctlreg |= 0x00070000; - break; - - case VME_A64: /* not supported in Universe DMA */ - case VME_CRCSR: - case VME_USER3: - case VME_USER4: - return -EINVAL; - break; - } - if (vmeAttr->userAccessType == VME_PROG) { - dctlreg |= 0x00004000; - } - if (vmeAttr->dataAccessType == VME_SUPER) { - dctlreg |= 0x00001000; - } - if (vmeAttr->xferProtocol != VME_SCT) { - dctlreg |= 0x00000100; - } - *dctlregreturn = dctlreg; - return 0; -} - -unsigned int -ca91cx42_start_dma(int channel, unsigned int dgcsreg, TDMA_Cmd_Packet *vmeLL) -{ - unsigned int val; - - /* Setup registers as needed for direct or chained. */ - if (dgcsreg & 0x8000000) { - iowrite32(0, ca91cx42_bridge->base + DTBC); - iowrite32((unsigned int)vmeLL, ca91cx42_bridge->base + DCPP); - } else { -#if 0 - printk(KERN_ERR "Starting: DGCS = %08x\n", dgcsreg); - printk(KERN_ERR "Starting: DVA = %08x\n", - ioread32(&vmeLL->dva)); - printk(KERN_ERR "Starting: DLV = %08x\n", - ioread32(&vmeLL->dlv)); - printk(KERN_ERR "Starting: DTBC = %08x\n", - ioread32(&vmeLL->dtbc)); - printk(KERN_ERR "Starting: DCTL = %08x\n", - ioread32(&vmeLL->dctl)); -#endif - /* Write registers */ - iowrite32(ioread32(&vmeLL->dva), ca91cx42_bridge->base + DVA); - iowrite32(ioread32(&vmeLL->dlv), ca91cx42_bridge->base + DLA); - iowrite32(ioread32(&vmeLL->dtbc), ca91cx42_bridge->base + DTBC); - iowrite32(ioread32(&vmeLL->dctl), ca91cx42_bridge->base + DCTL); - iowrite32(0, ca91cx42_bridge->base + DCPP); - } - - /* Start the operation */ - iowrite32(dgcsreg, ca91cx42_bridge->base + DGCS); - val = get_tbl(); - iowrite32(dgcsreg | 0x8000000F, ca91cx42_bridge->base + DGCS); - return val; -} - -TDMA_Cmd_Packet *ca91cx42_setup_dma(vmeDmaPacket_t * vmeDma) -{ - vmeDmaPacket_t *vmeCur; - int maxPerPage; - int currentLLcount; - TDMA_Cmd_Packet *startLL; - TDMA_Cmd_Packet *currentLL; - TDMA_Cmd_Packet *nextLL; - unsigned int dctlreg = 0; - - maxPerPage = PAGESIZE / sizeof(TDMA_Cmd_Packet) - 1; - startLL = (TDMA_Cmd_Packet *) __get_free_pages(GFP_KERNEL, 0); - if (startLL == 0) { - return startLL; - } - /* First allocate pages for descriptors and create linked list */ - vmeCur = vmeDma; - currentLL = startLL; - currentLLcount = 0; - while (vmeCur != 0) { - if (vmeCur->pNextPacket != 0) { - currentLL->dcpp = (unsigned int)(currentLL + 1); - currentLLcount++; - if (currentLLcount >= maxPerPage) { - currentLL->dcpp = - __get_free_pages(GFP_KERNEL, 0); - currentLLcount = 0; - } - currentLL = (TDMA_Cmd_Packet *) currentLL->dcpp; - } else { - currentLL->dcpp = (unsigned int)0; - } - vmeCur = vmeCur->pNextPacket; - } - - /* Next fill in information for each descriptor */ - vmeCur = vmeDma; - currentLL = startLL; - while (vmeCur != 0) { - if (vmeCur->srcBus == VME_DMA_VME) { - iowrite32(vmeCur->srcAddr, ¤tLL->dva); - iowrite32(vmeCur->dstAddr, ¤tLL->dlv); - } else { - iowrite32(vmeCur->srcAddr, ¤tLL->dlv); - iowrite32(vmeCur->dstAddr, ¤tLL->dva); - } - uniSetupDctlReg(vmeCur, &dctlreg); - iowrite32(dctlreg, ¤tLL->dctl); - iowrite32(vmeCur->byteCount, ¤tLL->dtbc); - - currentLL = (TDMA_Cmd_Packet *) currentLL->dcpp; - vmeCur = vmeCur->pNextPacket; - } - - /* Convert Links to PCI addresses. */ - currentLL = startLL; - while (currentLL != 0) { - nextLL = (TDMA_Cmd_Packet *) currentLL->dcpp; - if (nextLL == 0) { - iowrite32(1, ¤tLL->dcpp); - } else { - iowrite32((unsigned int)virt_to_bus(nextLL), - ¤tLL->dcpp); - } - currentLL = nextLL; - } - - /* Return pointer to descriptors list */ - return startLL; -} - -int ca91cx42_free_dma(TDMA_Cmd_Packet *startLL) -{ - TDMA_Cmd_Packet *currentLL; - TDMA_Cmd_Packet *prevLL; - TDMA_Cmd_Packet *nextLL; - unsigned int dcppreg; - - /* Convert Links to virtual addresses. */ - currentLL = startLL; - while (currentLL != 0) { - dcppreg = ioread32(¤tLL->dcpp); - dcppreg &= ~6; - if (dcppreg & 1) { - currentLL->dcpp = 0; - } else { - currentLL->dcpp = (unsigned int)bus_to_virt(dcppreg); - } - currentLL = (TDMA_Cmd_Packet *) currentLL->dcpp; - } - - /* Free all pages associated with the descriptors. */ - currentLL = startLL; - prevLL = currentLL; - while (currentLL != 0) { - nextLL = (TDMA_Cmd_Packet *) currentLL->dcpp; - if (currentLL + 1 != nextLL) { - free_pages((int)prevLL, 0); - prevLL = nextLL; - } - currentLL = nextLL; - } - - /* Return pointer to descriptors list */ - return 0; -} - -int ca91cx42_do_dma(vmeDmaPacket_t *vmeDma) -{ - unsigned int dgcsreg = 0; - unsigned int dctlreg = 0; - int val; - int channel, x; - vmeDmaPacket_t *curDma; - TDMA_Cmd_Packet *dmaLL; - - /* Sanity check the VME chain. */ - channel = vmeDma->channel_number; - if (channel > 0) { - return -EINVAL; - } - curDma = vmeDma; - while (curDma != 0) { - if (curDma->byteCount == 0) { - return -EINVAL; - } - if (curDma->byteCount >= 0x1000000) { - return -EINVAL; - } - if ((curDma->srcAddr & 7) != (curDma->dstAddr & 7)) { - return -EINVAL; - } - switch (curDma->srcBus) { - case VME_DMA_PCI: - if (curDma->dstBus != VME_DMA_VME) { - return -EINVAL; - } - break; - case VME_DMA_VME: - if (curDma->dstBus != VME_DMA_PCI) { - return -EINVAL; - } - break; - default: - return -EINVAL; - break; - } - if (uniSetupDctlReg(curDma, &dctlreg) < 0) { - return -EINVAL; - } - - curDma = curDma->pNextPacket; - if (curDma == vmeDma) { /* Endless Loop! */ - return -EINVAL; - } - } - - /* calculate control register */ - if (vmeDma->pNextPacket != 0) { - dgcsreg = 0x8000000; - } else { - dgcsreg = 0; - } - - for (x = 0; x < 8; x++) { /* vme block size */ - if ((256 << x) >= vmeDma->maxVmeBlockSize) { - break; - } - } - if (x == 8) - x = 7; - dgcsreg |= (x << 20); - - if (vmeDma->vmeBackOffTimer) { - for (x = 1; x < 8; x++) { /* vme timer */ - if ((16 << (x - 1)) >= vmeDma->vmeBackOffTimer) { - break; - } - } - if (x == 8) - x = 7; - dgcsreg |= (x << 16); - } - /*` Setup the dma chain */ - dmaLL = ca91cx42_setup_dma(vmeDma); - - /* Start the DMA */ - if (dgcsreg & 0x8000000) { - vmeDma->vmeDmaStartTick = - ca91cx42_start_dma(channel, dgcsreg, - (TDMA_Cmd_Packet *) virt_to_phys(dmaLL)); - } else { - vmeDma->vmeDmaStartTick = - ca91cx42_start_dma(channel, dgcsreg, dmaLL); - } - - wait_event_interruptible(dma_queue, - ioread32(ca91cx42_bridge->base + DGCS) & 0x800); - - val = ioread32(ca91cx42_bridge->base + DGCS); - iowrite32(val | 0xF00, ca91cx42_bridge->base + DGCS); - - vmeDma->vmeDmaStatus = 0; - - if (!(val & 0x00000800)) { - vmeDma->vmeDmaStatus = val & 0x700; - printk(KERN_ERR "ca91c042: DMA Error in ca91cx42_DMA_irqhandler" - " DGCS=%08X\n", val); - val = ioread32(ca91cx42_bridge->base + DCPP); - printk(KERN_ERR "ca91c042: DCPP=%08X\n", val); - val = ioread32(ca91cx42_bridge->base + DCTL); - printk(KERN_ERR "ca91c042: DCTL=%08X\n", val); - val = ioread32(ca91cx42_bridge->base + DTBC); - printk(KERN_ERR "ca91c042: DTBC=%08X\n", val); - val = ioread32(ca91cx42_bridge->base + DLA); - printk(KERN_ERR "ca91c042: DLA=%08X\n", val); - val = ioread32(ca91cx42_bridge->base + DVA); - printk(KERN_ERR "ca91c042: DVA=%08X\n", val); - - } - /* Free the dma chain */ - ca91cx42_free_dma(dmaLL); - - return 0; -} - -int ca91cx42_lm_set(vmeLmCfg_t *vmeLm) -{ - int temp_ctl = 0; - - if (vmeLm->addrU) - return -EINVAL; - - switch (vmeLm->addrSpace) { - case VME_A64: - case VME_USER3: - case VME_USER4: - return -EINVAL; - case VME_A16: - temp_ctl |= 0x00000; - break; - case VME_A24: - temp_ctl |= 0x10000; - break; - case VME_A32: - temp_ctl |= 0x20000; - break; - case VME_CRCSR: - temp_ctl |= 0x50000; - break; - case VME_USER1: - temp_ctl |= 0x60000; - break; - case VME_USER2: - temp_ctl |= 0x70000; - break; - } - - /* Disable while we are mucking around */ - iowrite32(0x00000000, ca91cx42_bridge->base + LM_CTL); - - iowrite32(vmeLm->addr, ca91cx42_bridge->base + LM_BS); - - /* Setup CTL register. */ - if (vmeLm->userAccessType & VME_SUPER) - temp_ctl |= 0x00200000; - if (vmeLm->userAccessType & VME_USER) - temp_ctl |= 0x00100000; - if (vmeLm->dataAccessType & VME_PROG) - temp_ctl |= 0x00800000; - if (vmeLm->dataAccessType & VME_DATA) - temp_ctl |= 0x00400000; - - - /* Write ctl reg and enable */ - iowrite32(0x80000000 | temp_ctl, ca91cx42_bridge->base + LM_CTL); - temp_ctl = ioread32(ca91cx42_bridge->base + LM_CTL); - - return 0; -} - -int ca91cx42_wait_lm(vmeLmCfg_t *vmeLm) -{ - unsigned long flags; - unsigned int tmp; - - spin_lock_irqsave(&lm_lock, flags); - spin_unlock_irqrestore(&lm_lock, flags); - if (tmp == 0) { - if (vmeLm->lmWait < 10) - vmeLm->lmWait = 10; - interruptible_sleep_on_timeout(&lm_queue, vmeLm->lmWait); - } - iowrite32(0x00000000, ca91cx42_bridge->base + LM_CTL); - - return 0; -} - - - -int ca91cx42_set_arbiter(vmeArbiterCfg_t *vmeArb) -{ - int temp_ctl = 0; - int vbto = 0; - - temp_ctl = ioread32(ca91cx42_bridge->base + MISC_CTL); - temp_ctl &= 0x00FFFFFF; - - if (vmeArb->globalTimeoutTimer == 0xFFFFFFFF) { - vbto = 7; - } else if (vmeArb->globalTimeoutTimer > 1024) { - return -EINVAL; - } else if (vmeArb->globalTimeoutTimer == 0) { - vbto = 0; - } else { - vbto = 1; - while ((16 * (1 << (vbto - 1))) < vmeArb->globalTimeoutTimer) - vbto += 1; - } - temp_ctl |= (vbto << 28); - - if (vmeArb->arbiterMode == VME_PRIORITY_MODE) - temp_ctl |= 1 << 26; - - if (vmeArb->arbiterTimeoutFlag) - temp_ctl |= 2 << 24; - - iowrite32(temp_ctl, ca91cx42_bridge->base + MISC_CTL); - return 0; -} - -int ca91cx42_get_arbiter(vmeArbiterCfg_t *vmeArb) -{ - int temp_ctl = 0; - int vbto = 0; - - temp_ctl = ioread32(ca91cx42_bridge->base + MISC_CTL); - - vbto = (temp_ctl >> 28) & 0xF; - if (vbto != 0) - vmeArb->globalTimeoutTimer = (16 * (1 << (vbto - 1))); - - if (temp_ctl & (1 << 26)) - vmeArb->arbiterMode = VME_PRIORITY_MODE; - else - vmeArb->arbiterMode = VME_R_ROBIN_MODE; - - if (temp_ctl & (3 << 24)) - vmeArb->arbiterTimeoutFlag = 1; - - return 0; -} - -int ca91cx42_set_requestor(vmeRequesterCfg_t *vmeReq) -{ - int temp_ctl = 0; - - temp_ctl = ioread32(ca91cx42_bridge->base + MAST_CTL); - temp_ctl &= 0xFF0FFFFF; - - if (vmeReq->releaseMode == 1) - temp_ctl |= (1 << 20); - - if (vmeReq->fairMode == 1) - temp_ctl |= (1 << 21); - - temp_ctl |= (vmeReq->requestLevel << 22); - - iowrite32(temp_ctl, ca91cx42_bridge->base + MAST_CTL); - return 0; -} - -int ca91cx42_get_requestor(vmeRequesterCfg_t *vmeReq) -{ - int temp_ctl = 0; - - temp_ctl = ioread32(ca91cx42_bridge->base + MAST_CTL); - - if (temp_ctl & (1 << 20)) - vmeReq->releaseMode = 1; - - if (temp_ctl & (1 << 21)) - vmeReq->fairMode = 1; - - vmeReq->requestLevel = (temp_ctl & 0xC00000) >> 22; - - return 0; -} - - -#endif diff --git a/drivers/staging/vme/bridges/vme_ca91cx42.h b/drivers/staging/vme/bridges/vme_ca91cx42.h index 95a42c2..e72c65b 100644 --- a/drivers/staging/vme/bridges/vme_ca91cx42.h +++ b/drivers/staging/vme/bridges/vme_ca91cx42.h @@ -7,8 +7,8 @@ * Updated by Ajit Prem * Copyright 2004 Motorola Inc. * - * Further updated by Martyn Welch <martyn.welch@gefanuc.com> - * Copyright 2009 GE Fanuc Intelligent Platforms Embedded Systems, Inc. + * Further updated by Martyn Welch <martyn.welch@ge.com> + * Copyright 2009 GE Intelligent Platforms Embedded Systems, Inc. * * Derived from ca91c042.h by Michael Wyrick * @@ -37,11 +37,27 @@ #define CA91C142_MAX_DMA 1 /* Max DMA Controllers */ #define CA91C142_MAX_MAILBOX 4 /* Max Mail Box registers */ +/* Structure used to hold driver specific information */ +struct ca91cx42_driver { + void *base; /* Base Address of device registers */ + wait_queue_head_t dma_queue; + wait_queue_head_t iack_queue; + wait_queue_head_t mbox_queue; + void (*lm_callback[4])(int); /* Called in interrupt handler */ + void *crcsr_kernel; + dma_addr_t crcsr_bus; + struct mutex vme_rmw; /* Only one RMW cycle at a time */ + struct mutex vme_int; /* + * Only one VME interrupt can be + * generated at a time, provide locking + */ +}; + /* See Page 2-77 in the Universe User Manual */ struct ca91cx42_dma_descriptor { unsigned int dctl; /* DMA Control */ unsigned int dtbc; /* Transfer Byte Count */ - unsigned int dlv; /* PCI Address */ + unsigned int dla; /* PCI Address */ unsigned int res1; /* Reserved */ unsigned int dva; /* Vme Address */ unsigned int res2; /* Reserved */ @@ -237,32 +253,6 @@ static const int CA91CX42_VSI_TO[] = { VSI0_TO, VSI1_TO, VSI2_TO, VSI3_TO, #define VCSR_SET 0x0FF8 #define VCSR_BS 0x0FFC -// DMA General Control/Status Register DGCS (0x220) -// 32-24 || GO | STOPR | HALTR | 0 || CHAIN | 0 | 0 | 0 || -// 23-16 || VON || VOFF || -// 15-08 || ACT | STOP | HALT | 0 || DONE | LERR | VERR | P_ERR || -// 07-00 || 0 | INT_S | INT_H | 0 || I_DNE | I_LER | I_VER | I_PER || - -// VON - Length Per DMA VMEBus Transfer -// 0000 = None -// 0001 = 256 Bytes -// 0010 = 512 -// 0011 = 1024 -// 0100 = 2048 -// 0101 = 4096 -// 0110 = 8192 -// 0111 = 16384 - -// VOFF - wait between DMA tenures -// 0000 = 0 us -// 0001 = 16 -// 0010 = 32 -// 0011 = 64 -// 0100 = 128 -// 0101 = 256 -// 0110 = 512 -// 0111 = 1024 - /* * PCI Class Register * offset 008 @@ -326,6 +316,16 @@ static const int CA91CX42_VSI_TO[] = { VSI0_TO, VSI1_TO, VSI2_TO, VSI3_TO, #define CA91CX42_LSI_CTL_VCT_MBLT (1<<8) #define CA91CX42_LSI_CTL_LAS (1<<0) +/* + * SCYC_CTL Register + * offset 178 + */ +#define CA91CX42_SCYC_CTL_LAS_PCIMEM 0 +#define CA91CX42_SCYC_CTL_LAS_PCIIO (1<<2) + +#define CA91CX42_SCYC_CTL_CYC_M (3<<0) +#define CA91CX42_SCYC_CTL_CYC_RMW (1<<0) +#define CA91CX42_SCYC_CTL_CYC_ADOH (1<<1) /* * LMISC Register @@ -355,6 +355,71 @@ static const int CA91CX42_VSI_TO[] = { VSI0_TO, VSI1_TO, VSI2_TO, VSI3_TO, #define CA91CX42_BM_SLSI_RESERVED 0x3F0F0000 /* + * DCTL Register + * offset 200 + */ +#define CA91CX42_DCTL_L2V (1<<31) +#define CA91CX42_DCTL_VDW_M (3<<22) +#define CA91CX42_DCTL_VDW_M (3<<22) +#define CA91CX42_DCTL_VDW_D8 0 +#define CA91CX42_DCTL_VDW_D16 (1<<22) +#define CA91CX42_DCTL_VDW_D32 (1<<23) +#define CA91CX42_DCTL_VDW_D64 (3<<22) + +#define CA91CX42_DCTL_VAS_M (7<<16) +#define CA91CX42_DCTL_VAS_A16 0 +#define CA91CX42_DCTL_VAS_A24 (1<<16) +#define CA91CX42_DCTL_VAS_A32 (1<<17) +#define CA91CX42_DCTL_VAS_USER1 (3<<17) +#define CA91CX42_DCTL_VAS_USER2 (7<<16) + +#define CA91CX42_DCTL_PGM_M (1<<14) +#define CA91CX42_DCTL_PGM_DATA 0 +#define CA91CX42_DCTL_PGM_PGM (1<<14) + +#define CA91CX42_DCTL_SUPER_M (1<<12) +#define CA91CX42_DCTL_SUPER_NPRIV 0 +#define CA91CX42_DCTL_SUPER_SUPR (1<<12) + +#define CA91CX42_DCTL_VCT_M (1<<8) +#define CA91CX42_DCTL_VCT_BLT (1<<8) +#define CA91CX42_DCTL_LD64EN (1<<7) + +/* + * DCPP Register + * offset 218 + */ +#define CA91CX42_DCPP_M 0xf +#define CA91CX42_DCPP_NULL (1<<0) + +/* + * DMA General Control/Status Register (DGCS) + * offset 220 + */ +#define CA91CX42_DGCS_GO (1<<31) +#define CA91CX42_DGCS_STOP_REQ (1<<30) +#define CA91CX42_DGCS_HALT_REQ (1<<29) +#define CA91CX42_DGCS_CHAIN (1<<27) + +#define CA91CX42_DGCS_VON_M (7<<20) + +#define CA91CX42_DGCS_VOFF_M (0xf<<16) + +#define CA91CX42_DGCS_ACT (1<<15) +#define CA91CX42_DGCS_STOP (1<<14) +#define CA91CX42_DGCS_HALT (1<<13) +#define CA91CX42_DGCS_DONE (1<<11) +#define CA91CX42_DGCS_LERR (1<<10) +#define CA91CX42_DGCS_VERR (1<<9) +#define CA91CX42_DGCS_PERR (1<<8) +#define CA91CX42_DGCS_INT_STOP (1<<6) +#define CA91CX42_DGCS_INT_HALT (1<<5) +#define CA91CX42_DGCS_INT_DONE (1<<3) +#define CA91CX42_DGCS_INT_LERR (1<<2) +#define CA91CX42_DGCS_INT_VERR (1<<1) +#define CA91CX42_DGCS_INT_PERR (1<<0) + +/* * PCI Interrupt Enable Register * offset 300 */ @@ -475,6 +540,19 @@ static const int CA91CX42_LINT_LM[] = { CA91CX42_LINT_LM0, CA91CX42_LINT_LM1, #define CA91CX42_VSI_CTL_LAS_PCI_IO (1<<0) #define CA91CX42_VSI_CTL_LAS_PCI_CONF (1<<1) +/* LM_CTL Register + * offset F64 + */ +#define CA91CX42_LM_CTL_EN (1<<31) +#define CA91CX42_LM_CTL_PGM (1<<23) +#define CA91CX42_LM_CTL_DATA (1<<22) +#define CA91CX42_LM_CTL_SUPR (1<<21) +#define CA91CX42_LM_CTL_NPRIV (1<<20) +#define CA91CX42_LM_CTL_AS_M (5<<16) +#define CA91CX42_LM_CTL_AS_A16 0 +#define CA91CX42_LM_CTL_AS_A24 (1<<16) +#define CA91CX42_LM_CTL_AS_A32 (1<<17) + /* * VRAI_CTL Register * offset F70 diff --git a/drivers/staging/vme/bridges/vme_tsi148.c b/drivers/staging/vme/bridges/vme_tsi148.c index 89a7dcc..faf652e 100644 --- a/drivers/staging/vme/bridges/vme_tsi148.c +++ b/drivers/staging/vme/bridges/vme_tsi148.c @@ -1,8 +1,8 @@ /* * Support for the Tundra TSI148 VME-PCI Bridge Chip * - * Author: Martyn Welch <martyn.welch@gefanuc.com> - * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc. + * Author: Martyn Welch <martyn.welch@ge.com> + * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc. * * Based on work by Tom Armistead and Ajit Prem * Copyright 2004 Motorola Inc. @@ -59,28 +59,14 @@ int tsi148_dma_list_add (struct vme_dma_list *, struct vme_dma_attr *, int tsi148_dma_list_exec(struct vme_dma_list *); int tsi148_dma_list_empty(struct vme_dma_list *); int tsi148_generate_irq(int, int); -int tsi148_slot_get(void); - -/* Modue parameter */ -int err_chk = 0; - -/* XXX These should all be in a per device structure */ -struct vme_bridge *tsi148_bridge; -wait_queue_head_t dma_queue[2]; -wait_queue_head_t iack_queue; -void (*lm_callback[4])(int); /* Called in interrupt handler, be careful! */ -void *crcsr_kernel; -dma_addr_t crcsr_bus; -struct vme_master_resource *flush_image; -struct mutex vme_rmw; /* Only one RMW cycle at a time */ -struct mutex vme_int; /* - * Only one VME interrupt can be - * generated at a time, provide locking - */ + +/* Module parameter */ +static int err_chk; +static int geoid; static char driver_name[] = "vme_tsi148"; -static struct pci_device_id tsi148_ids[] = { +static const struct pci_device_id tsi148_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_TUNDRA, PCI_DEVICE_ID_TUNDRA_TSI148) }, { }, }; @@ -109,16 +95,17 @@ static void reg_split(unsigned long long variable, unsigned int *high, /* * Wakes up DMA queue. */ -static u32 tsi148_DMA_irqhandler(int channel_mask) +static u32 tsi148_DMA_irqhandler(struct tsi148_driver *bridge, + int channel_mask) { u32 serviced = 0; if (channel_mask & TSI148_LCSR_INTS_DMA0S) { - wake_up(&dma_queue[0]); + wake_up(&(bridge->dma_queue[0])); serviced |= TSI148_LCSR_INTC_DMA0C; } if (channel_mask & TSI148_LCSR_INTS_DMA1S) { - wake_up(&dma_queue[1]); + wake_up(&(bridge->dma_queue[1])); serviced |= TSI148_LCSR_INTC_DMA1C; } @@ -128,7 +115,7 @@ static u32 tsi148_DMA_irqhandler(int channel_mask) /* * Wake up location monitor queue */ -static u32 tsi148_LM_irqhandler(u32 stat) +static u32 tsi148_LM_irqhandler(struct tsi148_driver *bridge, u32 stat) { int i; u32 serviced = 0; @@ -136,7 +123,7 @@ static u32 tsi148_LM_irqhandler(u32 stat) for (i = 0; i < 4; i++) { if(stat & TSI148_LCSR_INTS_LMS[i]) { /* We only enable interrupts if the callback is set */ - lm_callback[i](i); + bridge->lm_callback[i](i); serviced |= TSI148_LCSR_INTC_LMC[i]; } } @@ -149,7 +136,7 @@ static u32 tsi148_LM_irqhandler(u32 stat) * * XXX This functionality is not exposed up though API. */ -static u32 tsi148_MB_irqhandler(u32 stat) +static u32 tsi148_MB_irqhandler(struct tsi148_driver *bridge, u32 stat) { int i; u32 val; @@ -157,8 +144,7 @@ static u32 tsi148_MB_irqhandler(u32 stat) for (i = 0; i < 4; i++) { if(stat & TSI148_LCSR_INTS_MBS[i]) { - val = ioread32be(tsi148_bridge->base + - TSI148_GCSR_MBOX[i]); + val = ioread32be(bridge->base + TSI148_GCSR_MBOX[i]); printk("VME Mailbox %d received: 0x%x\n", i, val); serviced |= TSI148_LCSR_INTC_MBC[i]; } @@ -170,22 +156,21 @@ static u32 tsi148_MB_irqhandler(u32 stat) /* * Display error & status message when PERR (PCI) exception interrupt occurs. */ -static u32 tsi148_PERR_irqhandler(void) +static u32 tsi148_PERR_irqhandler(struct tsi148_driver *bridge) { printk(KERN_ERR "PCI Exception at address: 0x%08x:%08x, attributes: %08x\n", - ioread32be(tsi148_bridge->base + TSI148_LCSR_EDPAU), - ioread32be(tsi148_bridge->base + TSI148_LCSR_EDPAL), - ioread32be(tsi148_bridge->base + TSI148_LCSR_EDPAT) + ioread32be(bridge->base + TSI148_LCSR_EDPAU), + ioread32be(bridge->base + TSI148_LCSR_EDPAL), + ioread32be(bridge->base + TSI148_LCSR_EDPAT) ); printk(KERN_ERR "PCI-X attribute reg: %08x, PCI-X split completion reg: %08x\n", - ioread32be(tsi148_bridge->base + TSI148_LCSR_EDPXA), - ioread32be(tsi148_bridge->base + TSI148_LCSR_EDPXS) + ioread32be(bridge->base + TSI148_LCSR_EDPXA), + ioread32be(bridge->base + TSI148_LCSR_EDPXS) ); - iowrite32be(TSI148_LCSR_EDPAT_EDPCL, - tsi148_bridge->base + TSI148_LCSR_EDPAT); + iowrite32be(TSI148_LCSR_EDPAT_EDPCL, bridge->base + TSI148_LCSR_EDPAT); return TSI148_LCSR_INTC_PERRC; } @@ -193,16 +178,19 @@ static u32 tsi148_PERR_irqhandler(void) /* * Save address and status when VME error interrupt occurs. */ -static u32 tsi148_VERR_irqhandler(void) +static u32 tsi148_VERR_irqhandler(struct vme_bridge *tsi148_bridge) { unsigned int error_addr_high, error_addr_low; unsigned long long error_addr; u32 error_attrib; struct vme_bus_error *error; + struct tsi148_driver *bridge; + + bridge = tsi148_bridge->driver_priv; - error_addr_high = ioread32be(tsi148_bridge->base + TSI148_LCSR_VEAU); - error_addr_low = ioread32be(tsi148_bridge->base + TSI148_LCSR_VEAL); - error_attrib = ioread32be(tsi148_bridge->base + TSI148_LCSR_VEAT); + error_addr_high = ioread32be(bridge->base + TSI148_LCSR_VEAU); + error_addr_low = ioread32be(bridge->base + TSI148_LCSR_VEAL); + error_attrib = ioread32be(bridge->base + TSI148_LCSR_VEAT); reg_join(error_addr_high, error_addr_low, &error_addr); @@ -226,8 +214,7 @@ static u32 tsi148_VERR_irqhandler(void) } /* Clear Status */ - iowrite32be(TSI148_LCSR_VEAT_VESCL, - tsi148_bridge->base + TSI148_LCSR_VEAT); + iowrite32be(TSI148_LCSR_VEAT_VESCL, bridge->base + TSI148_LCSR_VEAT); return TSI148_LCSR_INTC_VERRC; } @@ -235,9 +222,9 @@ static u32 tsi148_VERR_irqhandler(void) /* * Wake up IACK queue. */ -static u32 tsi148_IACK_irqhandler(void) +static u32 tsi148_IACK_irqhandler(struct tsi148_driver *bridge) { - wake_up(&iack_queue); + wake_up(&(bridge->iack_queue)); return TSI148_LCSR_INTC_IACKC; } @@ -245,9 +232,13 @@ static u32 tsi148_IACK_irqhandler(void) /* * Calling VME bus interrupt callback if provided. */ -static u32 tsi148_VIRQ_irqhandler(u32 stat) +static u32 tsi148_VIRQ_irqhandler(struct vme_bridge *tsi148_bridge, + u32 stat) { int vec, i, serviced = 0; + struct tsi148_driver *bridge; + + bridge = tsi148_bridge->driver_priv; for (i = 7; i > 0; i--) { if (stat & (1 << i)) { @@ -257,8 +248,7 @@ static u32 tsi148_VIRQ_irqhandler(u32 stat) * 8-bit IACK cycles on the bus, read from offset * 3. */ - vec = ioread8(tsi148_bridge->base + - TSI148_LCSR_VIACK[i] + 3); + vec = ioread8(bridge->base + TSI148_LCSR_VIACK[i] + 3); vme_irq_handler(tsi148_bridge, i, vec); @@ -273,13 +263,19 @@ static u32 tsi148_VIRQ_irqhandler(u32 stat) * Top level interrupt handler. Clears appropriate interrupt status bits and * then calls appropriate sub handler(s). */ -static irqreturn_t tsi148_irqhandler(int irq, void *dev_id) +static irqreturn_t tsi148_irqhandler(int irq, void *ptr) { u32 stat, enable, serviced = 0; + struct vme_bridge *tsi148_bridge; + struct tsi148_driver *bridge; + + tsi148_bridge = ptr; + + bridge = tsi148_bridge->driver_priv; /* Determine which interrupts are unmasked and set */ - enable = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEO); - stat = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTS); + enable = ioread32be(bridge->base + TSI148_LCSR_INTEO); + stat = ioread32be(bridge->base + TSI148_LCSR_INTS); /* Only look at unmasked interrupts */ stat &= enable; @@ -291,61 +287,63 @@ static irqreturn_t tsi148_irqhandler(int irq, void *dev_id) /* Call subhandlers as appropriate */ /* DMA irqs */ if (stat & (TSI148_LCSR_INTS_DMA1S | TSI148_LCSR_INTS_DMA0S)) - serviced |= tsi148_DMA_irqhandler(stat); + serviced |= tsi148_DMA_irqhandler(bridge, stat); /* Location monitor irqs */ if (stat & (TSI148_LCSR_INTS_LM3S | TSI148_LCSR_INTS_LM2S | TSI148_LCSR_INTS_LM1S | TSI148_LCSR_INTS_LM0S)) - serviced |= tsi148_LM_irqhandler(stat); + serviced |= tsi148_LM_irqhandler(bridge, stat); /* Mail box irqs */ if (stat & (TSI148_LCSR_INTS_MB3S | TSI148_LCSR_INTS_MB2S | TSI148_LCSR_INTS_MB1S | TSI148_LCSR_INTS_MB0S)) - serviced |= tsi148_MB_irqhandler(stat); + serviced |= tsi148_MB_irqhandler(bridge, stat); /* PCI bus error */ if (stat & TSI148_LCSR_INTS_PERRS) - serviced |= tsi148_PERR_irqhandler(); + serviced |= tsi148_PERR_irqhandler(bridge); /* VME bus error */ if (stat & TSI148_LCSR_INTS_VERRS) - serviced |= tsi148_VERR_irqhandler(); + serviced |= tsi148_VERR_irqhandler(tsi148_bridge); /* IACK irq */ if (stat & TSI148_LCSR_INTS_IACKS) - serviced |= tsi148_IACK_irqhandler(); + serviced |= tsi148_IACK_irqhandler(bridge); /* VME bus irqs */ if (stat & (TSI148_LCSR_INTS_IRQ7S | TSI148_LCSR_INTS_IRQ6S | TSI148_LCSR_INTS_IRQ5S | TSI148_LCSR_INTS_IRQ4S | TSI148_LCSR_INTS_IRQ3S | TSI148_LCSR_INTS_IRQ2S | TSI148_LCSR_INTS_IRQ1S)) - serviced |= tsi148_VIRQ_irqhandler(stat); + serviced |= tsi148_VIRQ_irqhandler(tsi148_bridge, stat); /* Clear serviced interrupts */ - iowrite32be(serviced, tsi148_bridge->base + TSI148_LCSR_INTC); + iowrite32be(serviced, bridge->base + TSI148_LCSR_INTC); return IRQ_HANDLED; } -static int tsi148_irq_init(struct vme_bridge *bridge) +static int tsi148_irq_init(struct vme_bridge *tsi148_bridge) { int result; unsigned int tmp; struct pci_dev *pdev; + struct tsi148_driver *bridge; + + pdev = container_of(tsi148_bridge->parent, struct pci_dev, dev); - /* Need pdev */ - pdev = container_of(bridge->parent, struct pci_dev, dev); + bridge = tsi148_bridge->driver_priv; /* Initialise list for VME bus errors */ - INIT_LIST_HEAD(&(bridge->vme_errors)); + INIT_LIST_HEAD(&(tsi148_bridge->vme_errors)); - mutex_init(&(bridge->irq_mtx)); + mutex_init(&(tsi148_bridge->irq_mtx)); result = request_irq(pdev->irq, tsi148_irqhandler, IRQF_SHARED, - driver_name, pdev); + driver_name, tsi148_bridge); if (result) { dev_err(&pdev->dev, "Can't get assigned pci irq vector %02X\n", pdev->irq); @@ -359,7 +357,7 @@ static int tsi148_irq_init(struct vme_bridge *bridge) TSI148_LCSR_INTEO_PERREO | TSI148_LCSR_INTEO_VERREO | TSI148_LCSR_INTEO_IACKEO; - /* XXX This leaves the following interrupts masked. + /* This leaves the following interrupts masked. * TSI148_LCSR_INTEO_VIEEO * TSI148_LCSR_INTEO_SYSFLEO * TSI148_LCSR_INTEO_ACFLEO @@ -392,14 +390,14 @@ static int tsi148_irq_init(struct vme_bridge *bridge) return 0; } -static void tsi148_irq_exit(struct pci_dev *pdev) +static void tsi148_irq_exit(struct tsi148_driver *bridge, struct pci_dev *pdev) { /* Turn off interrupts */ - iowrite32be(0x0, tsi148_bridge->base + TSI148_LCSR_INTEO); - iowrite32be(0x0, tsi148_bridge->base + TSI148_LCSR_INTEN); + iowrite32be(0x0, bridge->base + TSI148_LCSR_INTEO); + iowrite32be(0x0, bridge->base + TSI148_LCSR_INTEN); /* Clear all interrupts */ - iowrite32be(0xFFFFFFFF, tsi148_bridge->base + TSI148_LCSR_INTC); + iowrite32be(0xFFFFFFFF, bridge->base + TSI148_LCSR_INTC); /* Detach interrupt handler */ free_irq(pdev->irq, pdev); @@ -408,11 +406,11 @@ static void tsi148_irq_exit(struct pci_dev *pdev) /* * Check to see if an IACk has been received, return true (1) or false (0). */ -int tsi148_iack_received(void) +int tsi148_iack_received(struct tsi148_driver *bridge) { u32 tmp; - tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_VICR); + tmp = ioread32be(bridge->base + TSI148_LCSR_VICR); if (tmp & TSI148_LCSR_VICR_IRQS) return 0; @@ -423,20 +421,24 @@ int tsi148_iack_received(void) /* * Configure VME interrupt */ -void tsi148_irq_set(int level, int state, int sync) +void tsi148_irq_set(struct vme_bridge *tsi148_bridge, int level, + int state, int sync) { struct pci_dev *pdev; u32 tmp; + struct tsi148_driver *bridge; + + bridge = tsi148_bridge->driver_priv; /* We need to do the ordering differently for enabling and disabling */ if (state == 0) { - tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEN); + tmp = ioread32be(bridge->base + TSI148_LCSR_INTEN); tmp &= ~TSI148_LCSR_INTEN_IRQEN[level - 1]; - iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_INTEN); + iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEN); - tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEO); + tmp = ioread32be(bridge->base + TSI148_LCSR_INTEO); tmp &= ~TSI148_LCSR_INTEO_IRQEO[level - 1]; - iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_INTEO); + iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEO); if (sync != 0) { pdev = container_of(tsi148_bridge->parent, @@ -445,13 +447,13 @@ void tsi148_irq_set(int level, int state, int sync) synchronize_irq(pdev->irq); } } else { - tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEO); + tmp = ioread32be(bridge->base + TSI148_LCSR_INTEO); tmp |= TSI148_LCSR_INTEO_IRQEO[level - 1]; - iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_INTEO); + iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEO); - tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEN); + tmp = ioread32be(bridge->base + TSI148_LCSR_INTEN); tmp |= TSI148_LCSR_INTEN_IRQEN[level - 1]; - iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_INTEN); + iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEN); } } @@ -459,28 +461,32 @@ void tsi148_irq_set(int level, int state, int sync) * Generate a VME bus interrupt at the requested level & vector. Wait for * interrupt to be acked. */ -int tsi148_irq_generate(int level, int statid) +int tsi148_irq_generate(struct vme_bridge *tsi148_bridge, int level, int statid) { u32 tmp; + struct tsi148_driver *bridge; + + bridge = tsi148_bridge->driver_priv; - mutex_lock(&(vme_int)); + mutex_lock(&(bridge->vme_int)); /* Read VICR register */ - tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_VICR); + tmp = ioread32be(bridge->base + TSI148_LCSR_VICR); /* Set Status/ID */ tmp = (tmp & ~TSI148_LCSR_VICR_STID_M) | (statid & TSI148_LCSR_VICR_STID_M); - iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_VICR); + iowrite32be(tmp, bridge->base + TSI148_LCSR_VICR); /* Assert VMEbus IRQ */ tmp = tmp | TSI148_LCSR_VICR_IRQL[level]; - iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_VICR); + iowrite32be(tmp, bridge->base + TSI148_LCSR_VICR); /* XXX Consider implementing a timeout? */ - wait_event_interruptible(iack_queue, tsi148_iack_received()); + wait_event_interruptible(bridge->iack_queue, + tsi148_iack_received(bridge)); - mutex_unlock(&(vme_int)); + mutex_unlock(&(bridge->vme_int)); return 0; } @@ -488,8 +494,8 @@ int tsi148_irq_generate(int level, int statid) /* * Find the first error in this address range */ -static struct vme_bus_error *tsi148_find_error(vme_address_t aspace, - unsigned long long address, size_t count) +static struct vme_bus_error *tsi148_find_error(struct vme_bridge *tsi148_bridge, + vme_address_t aspace, unsigned long long address, size_t count) { struct list_head *err_pos; struct vme_bus_error *vme_err, *valid = NULL; @@ -520,8 +526,8 @@ static struct vme_bus_error *tsi148_find_error(vme_address_t aspace, /* * Clear errors in the provided address range. */ -static void tsi148_clear_errors(vme_address_t aspace, - unsigned long long address, size_t count) +static void tsi148_clear_errors(struct vme_bridge *tsi148_bridge, + vme_address_t aspace, unsigned long long address, size_t count) { struct list_head *err_pos, *temp; struct vme_bus_error *vme_err; @@ -561,16 +567,9 @@ int tsi148_slave_set(struct vme_slave_resource *image, int enabled, unsigned int vme_bound_low, vme_bound_high; unsigned int pci_offset_low, pci_offset_high; unsigned long long vme_bound, pci_offset; + struct tsi148_driver *bridge; -#if 0 - printk("Set slave image %d to:\n", image->number); - printk("\tEnabled: %s\n", (enabled == 1)? "yes" : "no"); - printk("\tVME Base:0x%llx\n", vme_base); - printk("\tWindow Size:0x%llx\n", size); - printk("\tPCI Base:0x%lx\n", (unsigned long)pci_base); - printk("\tAddress Space:0x%x\n", aspace); - printk("\tTransfer Cycle Properties:0x%x\n", cycle); -#endif + bridge = image->parent->driver_priv; i = image->number; @@ -627,49 +626,27 @@ int tsi148_slave_set(struct vme_slave_resource *image, int enabled, return -EINVAL; } -#if 0 - printk("\tVME Bound:0x%llx\n", vme_bound); - printk("\tPCI Offset:0x%llx\n", pci_offset); -#endif - /* Disable while we are mucking around */ - temp_ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_IT[i] + + temp_ctl = ioread32be(bridge->base + TSI148_LCSR_IT[i] + TSI148_LCSR_OFFSET_ITAT); temp_ctl &= ~TSI148_LCSR_ITAT_EN; - iowrite32be(temp_ctl, tsi148_bridge->base + TSI148_LCSR_IT[i] + + iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_IT[i] + TSI148_LCSR_OFFSET_ITAT); /* Setup mapping */ - iowrite32be(vme_base_high, tsi148_bridge->base + TSI148_LCSR_IT[i] + + iowrite32be(vme_base_high, bridge->base + TSI148_LCSR_IT[i] + TSI148_LCSR_OFFSET_ITSAU); - iowrite32be(vme_base_low, tsi148_bridge->base + TSI148_LCSR_IT[i] + + iowrite32be(vme_base_low, bridge->base + TSI148_LCSR_IT[i] + TSI148_LCSR_OFFSET_ITSAL); - iowrite32be(vme_bound_high, tsi148_bridge->base + TSI148_LCSR_IT[i] + + iowrite32be(vme_bound_high, bridge->base + TSI148_LCSR_IT[i] + TSI148_LCSR_OFFSET_ITEAU); - iowrite32be(vme_bound_low, tsi148_bridge->base + TSI148_LCSR_IT[i] + + iowrite32be(vme_bound_low, bridge->base + TSI148_LCSR_IT[i] + TSI148_LCSR_OFFSET_ITEAL); - iowrite32be(pci_offset_high, tsi148_bridge->base + TSI148_LCSR_IT[i] + + iowrite32be(pci_offset_high, bridge->base + TSI148_LCSR_IT[i] + TSI148_LCSR_OFFSET_ITOFU); - iowrite32be(pci_offset_low, tsi148_bridge->base + TSI148_LCSR_IT[i] + + iowrite32be(pci_offset_low, bridge->base + TSI148_LCSR_IT[i] + TSI148_LCSR_OFFSET_ITOFL); -/* XXX Prefetch stuff currently unsupported */ -#if 0 - - for (x = 0; x < 4; x++) { - if ((64 << x) >= vmeIn->prefetchSize) { - break; - } - } - if (x == 4) - x--; - temp_ctl |= (x << 16); - - if (vmeIn->prefetchThreshold) - if (vmeIn->prefetchThreshold) - temp_ctl |= 0x40000; -#endif - /* Setup 2eSST speeds */ temp_ctl &= ~TSI148_LCSR_ITAT_2eSSTM_M; switch (cycle & (VME_2eSST160 | VME_2eSST267 | VME_2eSST320)) { @@ -712,13 +689,13 @@ int tsi148_slave_set(struct vme_slave_resource *image, int enabled, temp_ctl |= TSI148_LCSR_ITAT_DATA; /* Write ctl reg without enable */ - iowrite32be(temp_ctl, tsi148_bridge->base + TSI148_LCSR_IT[i] + + iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_IT[i] + TSI148_LCSR_OFFSET_ITAT); if (enabled) temp_ctl |= TSI148_LCSR_ITAT_EN; - iowrite32be(temp_ctl, tsi148_bridge->base + TSI148_LCSR_IT[i] + + iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_IT[i] + TSI148_LCSR_OFFSET_ITAT); return 0; @@ -726,8 +703,6 @@ int tsi148_slave_set(struct vme_slave_resource *image, int enabled, /* * Get slave window configuration. - * - * XXX Prefetch currently unsupported. */ int tsi148_slave_get(struct vme_slave_resource *image, int *enabled, unsigned long long *vme_base, unsigned long long *size, @@ -738,25 +713,27 @@ int tsi148_slave_get(struct vme_slave_resource *image, int *enabled, unsigned int vme_bound_low, vme_bound_high; unsigned int pci_offset_low, pci_offset_high; unsigned long long vme_bound, pci_offset; + struct tsi148_driver *bridge; + bridge = image->parent->driver_priv; i = image->number; /* Read registers */ - ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_IT[i] + + ctl = ioread32be(bridge->base + TSI148_LCSR_IT[i] + TSI148_LCSR_OFFSET_ITAT); - vme_base_high = ioread32be(tsi148_bridge->base + TSI148_LCSR_IT[i] + + vme_base_high = ioread32be(bridge->base + TSI148_LCSR_IT[i] + TSI148_LCSR_OFFSET_ITSAU); - vme_base_low = ioread32be(tsi148_bridge->base + TSI148_LCSR_IT[i] + + vme_base_low = ioread32be(bridge->base + TSI148_LCSR_IT[i] + TSI148_LCSR_OFFSET_ITSAL); - vme_bound_high = ioread32be(tsi148_bridge->base + TSI148_LCSR_IT[i] + + vme_bound_high = ioread32be(bridge->base + TSI148_LCSR_IT[i] + TSI148_LCSR_OFFSET_ITEAU); - vme_bound_low = ioread32be(tsi148_bridge->base + TSI148_LCSR_IT[i] + + vme_bound_low = ioread32be(bridge->base + TSI148_LCSR_IT[i] + TSI148_LCSR_OFFSET_ITEAL); - pci_offset_high = ioread32be(tsi148_bridge->base + TSI148_LCSR_IT[i] + + pci_offset_high = ioread32be(bridge->base + TSI148_LCSR_IT[i] + TSI148_LCSR_OFFSET_ITOFU); - pci_offset_low = ioread32be(tsi148_bridge->base + TSI148_LCSR_IT[i] + + pci_offset_low = ioread32be(bridge->base + TSI148_LCSR_IT[i] + TSI148_LCSR_OFFSET_ITOFL); /* Convert 64-bit variables to 2x 32-bit variables */ @@ -833,6 +810,9 @@ static int tsi148_alloc_resource(struct vme_master_resource *image, unsigned long long existing_size; int retval = 0; struct pci_dev *pdev; + struct vme_bridge *tsi148_bridge; + + tsi148_bridge = image->parent; /* Find pci_dev container of dev */ if (tsi148_bridge->parent == NULL) { @@ -841,8 +821,8 @@ static int tsi148_alloc_resource(struct vme_master_resource *image, } pdev = container_of(tsi148_bridge->parent, struct pci_dev, dev); - existing_size = (unsigned long long)(image->pci_resource.end - - image->pci_resource.start); + existing_size = (unsigned long long)(image->bus_resource.end - + image->bus_resource.start); /* If the existing size is OK, return */ if ((size != 0) && (existing_size == (size - 1))) @@ -851,10 +831,10 @@ static int tsi148_alloc_resource(struct vme_master_resource *image, if (existing_size != 0) { iounmap(image->kern_base); image->kern_base = NULL; - if (image->pci_resource.name != NULL) - kfree(image->pci_resource.name); - release_resource(&(image->pci_resource)); - memset(&(image->pci_resource), 0, sizeof(struct resource)); + if (image->bus_resource.name != NULL) + kfree(image->bus_resource.name); + release_resource(&(image->bus_resource)); + memset(&(image->bus_resource), 0, sizeof(struct resource)); } /* Exit here if size is zero */ @@ -862,9 +842,9 @@ static int tsi148_alloc_resource(struct vme_master_resource *image, return 0; } - if (image->pci_resource.name == NULL) { - image->pci_resource.name = kmalloc(VMENAMSIZ+3, GFP_KERNEL); - if (image->pci_resource.name == NULL) { + if (image->bus_resource.name == NULL) { + image->bus_resource.name = kmalloc(VMENAMSIZ+3, GFP_KERNEL); + if (image->bus_resource.name == NULL) { printk(KERN_ERR "Unable to allocate memory for resource" " name\n"); retval = -ENOMEM; @@ -872,26 +852,26 @@ static int tsi148_alloc_resource(struct vme_master_resource *image, } } - sprintf((char *)image->pci_resource.name, "%s.%d", tsi148_bridge->name, + sprintf((char *)image->bus_resource.name, "%s.%d", tsi148_bridge->name, image->number); - image->pci_resource.start = 0; - image->pci_resource.end = (unsigned long)size; - image->pci_resource.flags = IORESOURCE_MEM; + image->bus_resource.start = 0; + image->bus_resource.end = (unsigned long)size; + image->bus_resource.flags = IORESOURCE_MEM; retval = pci_bus_alloc_resource(pdev->bus, - &(image->pci_resource), size, size, PCIBIOS_MIN_MEM, + &(image->bus_resource), size, size, PCIBIOS_MIN_MEM, 0, NULL, NULL); if (retval) { printk(KERN_ERR "Failed to allocate mem resource for " "window %d size 0x%lx start 0x%lx\n", image->number, (unsigned long)size, - (unsigned long)image->pci_resource.start); + (unsigned long)image->bus_resource.start); goto err_resource; } image->kern_base = ioremap_nocache( - image->pci_resource.start, size); + image->bus_resource.start, size); if (image->kern_base == NULL) { printk(KERN_ERR "Failed to remap resource\n"); retval = -ENOMEM; @@ -903,10 +883,10 @@ static int tsi148_alloc_resource(struct vme_master_resource *image, iounmap(image->kern_base); image->kern_base = NULL; err_remap: - release_resource(&(image->pci_resource)); + release_resource(&(image->bus_resource)); err_resource: - kfree(image->pci_resource.name); - memset(&(image->pci_resource), 0, sizeof(struct resource)); + kfree(image->bus_resource.name); + memset(&(image->bus_resource), 0, sizeof(struct resource)); err_name: return retval; } @@ -918,9 +898,9 @@ static void tsi148_free_resource(struct vme_master_resource *image) { iounmap(image->kern_base); image->kern_base = NULL; - release_resource(&(image->pci_resource)); - kfree(image->pci_resource.name); - memset(&(image->pci_resource), 0, sizeof(struct resource)); + release_resource(&(image->bus_resource)); + kfree(image->bus_resource.name); + memset(&(image->bus_resource), 0, sizeof(struct resource)); } /* @@ -937,6 +917,9 @@ int tsi148_master_set( struct vme_master_resource *image, int enabled, unsigned int pci_bound_low, pci_bound_high; unsigned int vme_offset_low, vme_offset_high; unsigned long long pci_bound, vme_offset, pci_base; + struct tsi148_driver *bridge; + + bridge = image->parent->driver_priv; /* Verify input data */ if (vme_base & 0xFFFF) { @@ -970,7 +953,7 @@ int tsi148_master_set( struct vme_master_resource *image, int enabled, pci_bound = 0; vme_offset = 0; } else { - pci_base = (unsigned long long)image->pci_resource.start; + pci_base = (unsigned long long)image->bus_resource.start; /* * Bound address is a valid address for the window, adjust @@ -1007,26 +990,12 @@ int tsi148_master_set( struct vme_master_resource *image, int enabled, i = image->number; /* Disable while we are mucking around */ - temp_ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_OT[i] + + temp_ctl = ioread32be(bridge->base + TSI148_LCSR_OT[i] + TSI148_LCSR_OFFSET_OTAT); temp_ctl &= ~TSI148_LCSR_OTAT_EN; - iowrite32be(temp_ctl, tsi148_bridge->base + TSI148_LCSR_OT[i] + + iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_OT[i] + TSI148_LCSR_OFFSET_OTAT); -/* XXX Prefetch stuff currently unsupported */ -#if 0 - if (vmeOut->prefetchEnable) { - temp_ctl |= 0x40000; - for (x = 0; x < 4; x++) { - if ((2 << x) >= vmeOut->prefetchSize) - break; - } - if (x == 4) - x = 3; - temp_ctl |= (x << 16); - } -#endif - /* Setup 2eSST speeds */ temp_ctl &= ~TSI148_LCSR_OTAT_2eSSTM_M; switch (cycle & (VME_2eSST160 | VME_2eSST267 | VME_2eSST320)) { @@ -1126,33 +1095,27 @@ int tsi148_master_set( struct vme_master_resource *image, int enabled, temp_ctl |= TSI148_LCSR_OTAT_PGM; /* Setup mapping */ - iowrite32be(pci_base_high, tsi148_bridge->base + TSI148_LCSR_OT[i] + + iowrite32be(pci_base_high, bridge->base + TSI148_LCSR_OT[i] + TSI148_LCSR_OFFSET_OTSAU); - iowrite32be(pci_base_low, tsi148_bridge->base + TSI148_LCSR_OT[i] + + iowrite32be(pci_base_low, bridge->base + TSI148_LCSR_OT[i] + TSI148_LCSR_OFFSET_OTSAL); - iowrite32be(pci_bound_high, tsi148_bridge->base + TSI148_LCSR_OT[i] + + iowrite32be(pci_bound_high, bridge->base + TSI148_LCSR_OT[i] + TSI148_LCSR_OFFSET_OTEAU); - iowrite32be(pci_bound_low, tsi148_bridge->base + TSI148_LCSR_OT[i] + + iowrite32be(pci_bound_low, bridge->base + TSI148_LCSR_OT[i] + TSI148_LCSR_OFFSET_OTEAL); - iowrite32be(vme_offset_high, tsi148_bridge->base + TSI148_LCSR_OT[i] + + iowrite32be(vme_offset_high, bridge->base + TSI148_LCSR_OT[i] + TSI148_LCSR_OFFSET_OTOFU); - iowrite32be(vme_offset_low, tsi148_bridge->base + TSI148_LCSR_OT[i] + + iowrite32be(vme_offset_low, bridge->base + TSI148_LCSR_OT[i] + TSI148_LCSR_OFFSET_OTOFL); -/* XXX We need to deal with OTBS */ -#if 0 - iowrite32be(vmeOut->bcastSelect2esst, tsi148_bridge->base + - TSI148_LCSR_OT[i] + TSI148_LCSR_OFFSET_OTBS); -#endif - /* Write ctl reg without enable */ - iowrite32be(temp_ctl, tsi148_bridge->base + TSI148_LCSR_OT[i] + + iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_OT[i] + TSI148_LCSR_OFFSET_OTAT); if (enabled) temp_ctl |= TSI148_LCSR_OTAT_EN; - iowrite32be(temp_ctl, tsi148_bridge->base + TSI148_LCSR_OT[i] + + iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_OT[i] + TSI148_LCSR_OFFSET_OTAT); spin_unlock(&(image->lock)); @@ -1183,23 +1146,26 @@ int __tsi148_master_get( struct vme_master_resource *image, int *enabled, unsigned int vme_offset_low, vme_offset_high; unsigned long long pci_base, pci_bound, vme_offset; + struct tsi148_driver *bridge; + + bridge = image->parent->driver_priv; i = image->number; - ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_OT[i] + + ctl = ioread32be(bridge->base + TSI148_LCSR_OT[i] + TSI148_LCSR_OFFSET_OTAT); - pci_base_high = ioread32be(tsi148_bridge->base + TSI148_LCSR_OT[i] + + pci_base_high = ioread32be(bridge->base + TSI148_LCSR_OT[i] + TSI148_LCSR_OFFSET_OTSAU); - pci_base_low = ioread32be(tsi148_bridge->base + TSI148_LCSR_OT[i] + + pci_base_low = ioread32be(bridge->base + TSI148_LCSR_OT[i] + TSI148_LCSR_OFFSET_OTSAL); - pci_bound_high = ioread32be(tsi148_bridge->base + TSI148_LCSR_OT[i] + + pci_bound_high = ioread32be(bridge->base + TSI148_LCSR_OT[i] + TSI148_LCSR_OFFSET_OTEAU); - pci_bound_low = ioread32be(tsi148_bridge->base + TSI148_LCSR_OT[i] + + pci_bound_low = ioread32be(bridge->base + TSI148_LCSR_OT[i] + TSI148_LCSR_OFFSET_OTEAL); - vme_offset_high = ioread32be(tsi148_bridge->base + TSI148_LCSR_OT[i] + + vme_offset_high = ioread32be(bridge->base + TSI148_LCSR_OT[i] + TSI148_LCSR_OFFSET_OTOFU); - vme_offset_low = ioread32be(tsi148_bridge->base + TSI148_LCSR_OT[i] + + vme_offset_low = ioread32be(bridge->base + TSI148_LCSR_OT[i] + TSI148_LCSR_OFFSET_OTOFL); /* Convert 64-bit variables to 2x 32-bit variables */ @@ -1305,6 +1271,9 @@ ssize_t tsi148_master_read(struct vme_master_resource *image, void *buf, vme_cycle_t cycle; vme_width_t dwidth; struct vme_bus_error *vme_err = NULL; + struct vme_bridge *tsi148_bridge; + + tsi148_bridge = image->parent; spin_lock(&(image->lock)); @@ -1317,13 +1286,15 @@ ssize_t tsi148_master_read(struct vme_master_resource *image, void *buf, __tsi148_master_get(image, &enabled, &vme_base, &size, &aspace, &cycle, &dwidth); - vme_err = tsi148_find_error(aspace, vme_base + offset, count); + vme_err = tsi148_find_error(tsi148_bridge, aspace, vme_base + offset, + count); if(vme_err != NULL) { dev_err(image->parent->parent, "First VME read error detected " "an at address 0x%llx\n", vme_err->address); retval = vme_err->address - (vme_base + offset); /* Clear down save errors in this address range */ - tsi148_clear_errors(aspace, vme_base + offset, count); + tsi148_clear_errors(tsi148_bridge, aspace, vme_base + offset, + count); } skip_chk: @@ -1333,9 +1304,6 @@ skip_chk: } -/* XXX We need to change vme_master_resource->mtx to a spinlock so that read - * and write functions can be used in an interrupt context - */ ssize_t tsi148_master_write(struct vme_master_resource *image, void *buf, size_t count, loff_t offset) { @@ -1346,6 +1314,12 @@ ssize_t tsi148_master_write(struct vme_master_resource *image, void *buf, vme_width_t dwidth; struct vme_bus_error *vme_err = NULL; + struct vme_bridge *tsi148_bridge; + struct tsi148_driver *bridge; + + tsi148_bridge = image->parent; + + bridge = tsi148_bridge->driver_priv; spin_lock(&(image->lock)); @@ -1373,15 +1347,17 @@ ssize_t tsi148_master_write(struct vme_master_resource *image, void *buf, __tsi148_master_get(image, &enabled, &vme_base, &size, &aspace, &cycle, &dwidth); - ioread16(flush_image->kern_base + 0x7F000); + ioread16(bridge->flush_image->kern_base + 0x7F000); - vme_err = tsi148_find_error(aspace, vme_base + offset, count); + vme_err = tsi148_find_error(tsi148_bridge, aspace, vme_base + offset, + count); if(vme_err != NULL) { printk("First VME write error detected an at address 0x%llx\n", vme_err->address); retval = vme_err->address - (vme_base + offset); /* Clear down save errors in this address range */ - tsi148_clear_errors(aspace, vme_base + offset, count); + tsi148_clear_errors(tsi148_bridge, aspace, vme_base + offset, + count); } skip_chk: @@ -1403,48 +1379,50 @@ unsigned int tsi148_master_rmw(struct vme_master_resource *image, unsigned int pci_addr_high, pci_addr_low; u32 tmp, result; int i; + struct tsi148_driver *bridge; + bridge = image->parent->driver_priv; /* Find the PCI address that maps to the desired VME address */ i = image->number; /* Locking as we can only do one of these at a time */ - mutex_lock(&(vme_rmw)); + mutex_lock(&(bridge->vme_rmw)); /* Lock image */ spin_lock(&(image->lock)); - pci_addr_high = ioread32be(tsi148_bridge->base + TSI148_LCSR_OT[i] + + pci_addr_high = ioread32be(bridge->base + TSI148_LCSR_OT[i] + TSI148_LCSR_OFFSET_OTSAU); - pci_addr_low = ioread32be(tsi148_bridge->base + TSI148_LCSR_OT[i] + + pci_addr_low = ioread32be(bridge->base + TSI148_LCSR_OT[i] + TSI148_LCSR_OFFSET_OTSAL); reg_join(pci_addr_high, pci_addr_low, &pci_addr); reg_split(pci_addr + offset, &pci_addr_high, &pci_addr_low); /* Configure registers */ - iowrite32be(mask, tsi148_bridge->base + TSI148_LCSR_RMWEN); - iowrite32be(compare, tsi148_bridge->base + TSI148_LCSR_RMWC); - iowrite32be(swap, tsi148_bridge->base + TSI148_LCSR_RMWS); - iowrite32be(pci_addr_high, tsi148_bridge->base + TSI148_LCSR_RMWAU); - iowrite32be(pci_addr_low, tsi148_bridge->base + TSI148_LCSR_RMWAL); + iowrite32be(mask, bridge->base + TSI148_LCSR_RMWEN); + iowrite32be(compare, bridge->base + TSI148_LCSR_RMWC); + iowrite32be(swap, bridge->base + TSI148_LCSR_RMWS); + iowrite32be(pci_addr_high, bridge->base + TSI148_LCSR_RMWAU); + iowrite32be(pci_addr_low, bridge->base + TSI148_LCSR_RMWAL); /* Enable RMW */ - tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_VMCTRL); + tmp = ioread32be(bridge->base + TSI148_LCSR_VMCTRL); tmp |= TSI148_LCSR_VMCTRL_RMWEN; - iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_VMCTRL); + iowrite32be(tmp, bridge->base + TSI148_LCSR_VMCTRL); /* Kick process off with a read to the required address. */ result = ioread32be(image->kern_base + offset); /* Disable RMW */ - tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_VMCTRL); + tmp = ioread32be(bridge->base + TSI148_LCSR_VMCTRL); tmp &= ~TSI148_LCSR_VMCTRL_RMWEN; - iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_VMCTRL); + iowrite32be(tmp, bridge->base + TSI148_LCSR_VMCTRL); spin_unlock(&(image->lock)); - mutex_unlock(&(vme_rmw)); + mutex_unlock(&(bridge->vme_rmw)); return result; } @@ -1637,8 +1615,6 @@ static int tsi148_dma_set_vme_dest_attributes(u32 *attr, vme_address_t aspace, /* * Add a link list descriptor to the list - * - * XXX Need to handle 2eSST Broadcast select bits */ int tsi148_dma_list_add (struct vme_dma_list *list, struct vme_dma_attr *src, struct vme_dma_attr *dest, size_t count) @@ -1651,7 +1627,7 @@ int tsi148_dma_list_add (struct vme_dma_list *list, struct vme_dma_attr *src, dma_addr_t desc_ptr; int retval = 0; - /* XXX descriptor must be aligned on 64-bit boundaries */ + /* Descriptor must be aligned on 64-bit boundaries */ entry = (struct tsi148_dma_entry *)kmalloc( sizeof(struct tsi148_dma_entry), GFP_KERNEL); if (entry == NULL) { @@ -1788,11 +1764,14 @@ err_mem: /* * Check to see if the provided DMA channel is busy. */ -static int tsi148_dma_busy(int channel) +static int tsi148_dma_busy(struct vme_bridge *tsi148_bridge, int channel) { u32 tmp; + struct tsi148_driver *bridge; + + bridge = tsi148_bridge->driver_priv; - tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_DMA[channel] + + tmp = ioread32be(bridge->base + TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DSTA); if (tmp & TSI148_LCSR_DSTA_BSY) @@ -1815,12 +1794,12 @@ int tsi148_dma_list_exec(struct vme_dma_list *list) dma_addr_t bus_addr; u32 bus_addr_high, bus_addr_low; u32 val, dctlreg = 0; -#if 0 - int x; -#endif + struct tsi148_driver *bridge; ctrlr = list->parent; + bridge = ctrlr->parent->driver_priv; + mutex_lock(&(ctrlr->mtx)); channel = ctrlr->number; @@ -1837,48 +1816,6 @@ int tsi148_dma_list_exec(struct vme_dma_list *list) } else { list_add(&(list->list), &(ctrlr->running)); } -#if 0 - /* XXX Still todo */ - for (x = 0; x < 8; x++) { /* vme block size */ - if ((32 << x) >= vmeDma->maxVmeBlockSize) { - break; - } - } - if (x == 8) - x = 7; - dctlreg |= (x << 12); - - for (x = 0; x < 8; x++) { /* pci block size */ - if ((32 << x) >= vmeDma->maxPciBlockSize) { - break; - } - } - if (x == 8) - x = 7; - dctlreg |= (x << 4); - - if (vmeDma->vmeBackOffTimer) { - for (x = 1; x < 8; x++) { /* vme timer */ - if ((1 << (x - 1)) >= vmeDma->vmeBackOffTimer) { - break; - } - } - if (x == 8) - x = 7; - dctlreg |= (x << 8); - } - - if (vmeDma->pciBackOffTimer) { - for (x = 1; x < 8; x++) { /* pci timer */ - if ((1 << (x - 1)) >= vmeDma->pciBackOffTimer) { - break; - } - } - if (x == 8) - x = 7; - dctlreg |= (x << 0); - } -#endif /* Get first bus address and write into registers */ entry = list_first_entry(&(list->entries), struct tsi148_dma_entry, @@ -1890,21 +1827,22 @@ int tsi148_dma_list_exec(struct vme_dma_list *list) reg_split(bus_addr, &bus_addr_high, &bus_addr_low); - iowrite32be(bus_addr_high, tsi148_bridge->base + + iowrite32be(bus_addr_high, bridge->base + TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DNLAU); - iowrite32be(bus_addr_low, tsi148_bridge->base + + iowrite32be(bus_addr_low, bridge->base + TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DNLAL); /* Start the operation */ - iowrite32be(dctlreg | TSI148_LCSR_DCTL_DGO, tsi148_bridge->base + + iowrite32be(dctlreg | TSI148_LCSR_DCTL_DGO, bridge->base + TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DCTL); - wait_event_interruptible(dma_queue[channel], tsi148_dma_busy(channel)); + wait_event_interruptible(bridge->dma_queue[channel], + tsi148_dma_busy(ctrlr->parent, channel)); /* * Read status register, this register is valid until we kick off a * new transfer. */ - val = ioread32be(tsi148_bridge->base + TSI148_LCSR_DMA[channel] + + val = ioread32be(bridge->base + TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DSTA); if (val & TSI148_LCSR_DSTA_VBE) { @@ -1952,12 +1890,15 @@ int tsi148_lm_set(struct vme_lm_resource *lm, unsigned long long lm_base, { u32 lm_base_high, lm_base_low, lm_ctl = 0; int i; + struct tsi148_driver *bridge; + + bridge = lm->parent->driver_priv; mutex_lock(&(lm->mtx)); /* If we already have a callback attached, we can't move it! */ for (i = 0; i < lm->monitors; i++) { - if(lm_callback[i] != NULL) { + if (bridge->lm_callback[i] != NULL) { mutex_unlock(&(lm->mtx)); printk("Location monitor callback attached, can't " "reset\n"); @@ -1996,9 +1937,9 @@ int tsi148_lm_set(struct vme_lm_resource *lm, unsigned long long lm_base, reg_split(lm_base, &lm_base_high, &lm_base_low); - iowrite32be(lm_base_high, tsi148_bridge->base + TSI148_LCSR_LMBAU); - iowrite32be(lm_base_low, tsi148_bridge->base + TSI148_LCSR_LMBAL); - iowrite32be(lm_ctl, tsi148_bridge->base + TSI148_LCSR_LMAT); + iowrite32be(lm_base_high, bridge->base + TSI148_LCSR_LMBAU); + iowrite32be(lm_base_low, bridge->base + TSI148_LCSR_LMBAL); + iowrite32be(lm_ctl, bridge->base + TSI148_LCSR_LMAT); mutex_unlock(&(lm->mtx)); @@ -2012,12 +1953,15 @@ int tsi148_lm_get(struct vme_lm_resource *lm, unsigned long long *lm_base, vme_address_t *aspace, vme_cycle_t *cycle) { u32 lm_base_high, lm_base_low, lm_ctl, enabled = 0; + struct tsi148_driver *bridge; + + bridge = lm->parent->driver_priv; mutex_lock(&(lm->mtx)); - lm_base_high = ioread32be(tsi148_bridge->base + TSI148_LCSR_LMBAU); - lm_base_low = ioread32be(tsi148_bridge->base + TSI148_LCSR_LMBAL); - lm_ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_LMAT); + lm_base_high = ioread32be(bridge->base + TSI148_LCSR_LMBAU); + lm_base_low = ioread32be(bridge->base + TSI148_LCSR_LMBAL); + lm_ctl = ioread32be(bridge->base + TSI148_LCSR_LMAT); reg_join(lm_base_high, lm_base_low, lm_base); @@ -2060,11 +2004,14 @@ int tsi148_lm_attach(struct vme_lm_resource *lm, int monitor, void (*callback)(int)) { u32 lm_ctl, tmp; + struct tsi148_driver *bridge; + + bridge = lm->parent->driver_priv; mutex_lock(&(lm->mtx)); /* Ensure that the location monitor is configured - need PGM or DATA */ - lm_ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_LMAT); + lm_ctl = ioread32be(bridge->base + TSI148_LCSR_LMAT); if ((lm_ctl & (TSI148_LCSR_LMAT_PGM | TSI148_LCSR_LMAT_DATA)) == 0) { mutex_unlock(&(lm->mtx)); printk("Location monitor not properly configured\n"); @@ -2072,28 +2019,28 @@ int tsi148_lm_attach(struct vme_lm_resource *lm, int monitor, } /* Check that a callback isn't already attached */ - if (lm_callback[monitor] != NULL) { + if (bridge->lm_callback[monitor] != NULL) { mutex_unlock(&(lm->mtx)); printk("Existing callback attached\n"); return -EBUSY; } /* Attach callback */ - lm_callback[monitor] = callback; + bridge->lm_callback[monitor] = callback; /* Enable Location Monitor interrupt */ - tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEN); + tmp = ioread32be(bridge->base + TSI148_LCSR_INTEN); tmp |= TSI148_LCSR_INTEN_LMEN[monitor]; - iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_INTEN); + iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEN); - tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEO); + tmp = ioread32be(bridge->base + TSI148_LCSR_INTEO); tmp |= TSI148_LCSR_INTEO_LMEO[monitor]; - iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_INTEO); + iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEO); /* Ensure that global Location Monitor Enable set */ if ((lm_ctl & TSI148_LCSR_LMAT_EN) == 0) { lm_ctl |= TSI148_LCSR_LMAT_EN; - iowrite32be(lm_ctl, tsi148_bridge->base + TSI148_LCSR_LMAT); + iowrite32be(lm_ctl, bridge->base + TSI148_LCSR_LMAT); } mutex_unlock(&(lm->mtx)); @@ -2107,30 +2054,33 @@ int tsi148_lm_attach(struct vme_lm_resource *lm, int monitor, int tsi148_lm_detach(struct vme_lm_resource *lm, int monitor) { u32 lm_en, tmp; + struct tsi148_driver *bridge; + + bridge = lm->parent->driver_priv; mutex_lock(&(lm->mtx)); /* Disable Location Monitor and ensure previous interrupts are clear */ - lm_en = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEN); + lm_en = ioread32be(bridge->base + TSI148_LCSR_INTEN); lm_en &= ~TSI148_LCSR_INTEN_LMEN[monitor]; - iowrite32be(lm_en, tsi148_bridge->base + TSI148_LCSR_INTEN); + iowrite32be(lm_en, bridge->base + TSI148_LCSR_INTEN); - tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEO); + tmp = ioread32be(bridge->base + TSI148_LCSR_INTEO); tmp &= ~TSI148_LCSR_INTEO_LMEO[monitor]; - iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_INTEO); + iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEO); iowrite32be(TSI148_LCSR_INTC_LMC[monitor], - tsi148_bridge->base + TSI148_LCSR_INTC); + bridge->base + TSI148_LCSR_INTC); /* Detach callback */ - lm_callback[monitor] = NULL; + bridge->lm_callback[monitor] = NULL; /* If all location monitors disabled, disable global Location Monitor */ if ((lm_en & (TSI148_LCSR_INTS_LM0S | TSI148_LCSR_INTS_LM1S | TSI148_LCSR_INTS_LM2S | TSI148_LCSR_INTS_LM3S)) == 0) { - tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_LMAT); + tmp = ioread32be(bridge->base + TSI148_LCSR_LMAT); tmp &= ~TSI148_LCSR_LMAT_EN; - iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_LMAT); + iowrite32be(tmp, bridge->base + TSI148_LCSR_LMAT); } mutex_unlock(&(lm->mtx)); @@ -2141,12 +2091,19 @@ int tsi148_lm_detach(struct vme_lm_resource *lm, int monitor) /* * Determine Geographical Addressing */ -int tsi148_slot_get(void) +int tsi148_slot_get(struct vme_bridge *tsi148_bridge) { u32 slot = 0; + struct tsi148_driver *bridge; + + bridge = tsi148_bridge->driver_priv; + + if (!geoid) { + slot = ioread32be(bridge->base + TSI148_LCSR_VSTAT); + slot = slot & TSI148_LCSR_VSTAT_GA_M; + } else + slot = geoid; - slot = ioread32be(tsi148_bridge->base + TSI148_LCSR_VSTAT); - slot = slot & TSI148_LCSR_VSTAT_GA_M; return (int)slot; } @@ -2167,45 +2124,50 @@ static int __init tsi148_init(void) * boards registers, this means there is a fix length 508kB window which must * be mapped onto PCI memory. */ -static int tsi148_crcsr_init(struct pci_dev *pdev) +static int tsi148_crcsr_init(struct vme_bridge *tsi148_bridge, + struct pci_dev *pdev) { u32 cbar, crat, vstat; u32 crcsr_bus_high, crcsr_bus_low; int retval; + struct tsi148_driver *bridge; + + bridge = tsi148_bridge->driver_priv; /* Allocate mem for CR/CSR image */ - crcsr_kernel = pci_alloc_consistent(pdev, VME_CRCSR_BUF_SIZE, - &crcsr_bus); - if (crcsr_kernel == NULL) { + bridge->crcsr_kernel = pci_alloc_consistent(pdev, VME_CRCSR_BUF_SIZE, + &(bridge->crcsr_bus)); + if (bridge->crcsr_kernel == NULL) { dev_err(&pdev->dev, "Failed to allocate memory for CR/CSR " "image\n"); return -ENOMEM; } - memset(crcsr_kernel, 0, VME_CRCSR_BUF_SIZE); + memset(bridge->crcsr_kernel, 0, VME_CRCSR_BUF_SIZE); - reg_split(crcsr_bus, &crcsr_bus_high, &crcsr_bus_low); + reg_split(bridge->crcsr_bus, &crcsr_bus_high, &crcsr_bus_low); - iowrite32be(crcsr_bus_high, tsi148_bridge->base + TSI148_LCSR_CROU); - iowrite32be(crcsr_bus_low, tsi148_bridge->base + TSI148_LCSR_CROL); + iowrite32be(crcsr_bus_high, bridge->base + TSI148_LCSR_CROU); + iowrite32be(crcsr_bus_low, bridge->base + TSI148_LCSR_CROL); /* Ensure that the CR/CSR is configured at the correct offset */ - cbar = ioread32be(tsi148_bridge->base + TSI148_CBAR); + cbar = ioread32be(bridge->base + TSI148_CBAR); cbar = (cbar & TSI148_CRCSR_CBAR_M)>>3; - vstat = tsi148_slot_get(); + vstat = tsi148_slot_get(tsi148_bridge); if (cbar != vstat) { + cbar = vstat; dev_info(&pdev->dev, "Setting CR/CSR offset\n"); - iowrite32be(cbar<<3, tsi148_bridge->base + TSI148_CBAR); + iowrite32be(cbar<<3, bridge->base + TSI148_CBAR); } dev_info(&pdev->dev, "CR/CSR Offset: %d\n", cbar); - crat = ioread32be(tsi148_bridge->base + TSI148_LCSR_CRAT); + crat = ioread32be(bridge->base + TSI148_LCSR_CRAT); if (crat & TSI148_LCSR_CRAT_EN) { dev_info(&pdev->dev, "Enabling CR/CSR space\n"); iowrite32be(crat | TSI148_LCSR_CRAT_EN, - tsi148_bridge->base + TSI148_LCSR_CRAT); + bridge->base + TSI148_LCSR_CRAT); } else dev_info(&pdev->dev, "CR/CSR already enabled\n"); @@ -2214,8 +2176,9 @@ static int tsi148_crcsr_init(struct pci_dev *pdev) * through VME writes. */ if(err_chk) { - retval = tsi148_master_set(flush_image, 1, (vstat * 0x80000), - 0x80000, VME_CRCSR, VME_SCT, VME_D16); + retval = tsi148_master_set(bridge->flush_image, 1, + (vstat * 0x80000), 0x80000, VME_CRCSR, VME_SCT, + VME_D16); if (retval) dev_err(&pdev->dev, "Configuring flush image failed\n"); } @@ -2224,20 +2187,25 @@ static int tsi148_crcsr_init(struct pci_dev *pdev) } -static void tsi148_crcsr_exit(struct pci_dev *pdev) +static void tsi148_crcsr_exit(struct vme_bridge *tsi148_bridge, + struct pci_dev *pdev) { u32 crat; + struct tsi148_driver *bridge; + + bridge = tsi148_bridge->driver_priv; /* Turn off CR/CSR space */ - crat = ioread32be(tsi148_bridge->base + TSI148_LCSR_CRAT); + crat = ioread32be(bridge->base + TSI148_LCSR_CRAT); iowrite32be(crat & ~TSI148_LCSR_CRAT_EN, - tsi148_bridge->base + TSI148_LCSR_CRAT); + bridge->base + TSI148_LCSR_CRAT); /* Free image */ - iowrite32be(0, tsi148_bridge->base + TSI148_LCSR_CROU); - iowrite32be(0, tsi148_bridge->base + TSI148_LCSR_CROL); + iowrite32be(0, bridge->base + TSI148_LCSR_CROU); + iowrite32be(0, bridge->base + TSI148_LCSR_CROL); - pci_free_consistent(pdev, VME_CRCSR_BUF_SIZE, crcsr_kernel, crcsr_bus); + pci_free_consistent(pdev, VME_CRCSR_BUF_SIZE, bridge->crcsr_kernel, + bridge->crcsr_bus); } static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id) @@ -2245,6 +2213,8 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id) int retval, i, master_num; u32 data; struct list_head *pos = NULL; + struct vme_bridge *tsi148_bridge; + struct tsi148_driver *tsi148_device; struct vme_master_resource *master_image; struct vme_slave_resource *slave_image; struct vme_dma_resource *dma_ctrlr; @@ -2264,6 +2234,18 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id) memset(tsi148_bridge, 0, sizeof(struct vme_bridge)); + tsi148_device = kmalloc(sizeof(struct tsi148_driver), GFP_KERNEL); + if (tsi148_device == NULL) { + dev_err(&pdev->dev, "Failed to allocate memory for device " + "structure\n"); + retval = -ENOMEM; + goto err_driver; + } + + memset(tsi148_device, 0, sizeof(struct tsi148_driver)); + + tsi148_bridge->driver_priv = tsi148_device; + /* Enable the device */ retval = pci_enable_device(pdev); if (retval) { @@ -2279,15 +2261,16 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id) } /* map registers in BAR 0 */ - tsi148_bridge->base = ioremap_nocache(pci_resource_start(pdev, 0), 4096); - if (!tsi148_bridge->base) { + tsi148_device->base = ioremap_nocache(pci_resource_start(pdev, 0), + 4096); + if (!tsi148_device->base) { dev_err(&pdev->dev, "Unable to remap CRG region\n"); retval = -EIO; goto err_remap; } /* Check to see if the mapping worked out */ - data = ioread32(tsi148_bridge->base + TSI148_PCFS_ID) & 0x0000FFFF; + data = ioread32(tsi148_device->base + TSI148_PCFS_ID) & 0x0000FFFF; if (data != PCI_VENDOR_ID_TUNDRA) { dev_err(&pdev->dev, "CRG region check failed\n"); retval = -EIO; @@ -2295,12 +2278,11 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id) } /* Initialize wait queues & mutual exclusion flags */ - /* XXX These need to be moved to the vme_bridge structure */ - init_waitqueue_head(&dma_queue[0]); - init_waitqueue_head(&dma_queue[1]); - init_waitqueue_head(&iack_queue); - mutex_init(&(vme_int)); - mutex_init(&(vme_rmw)); + init_waitqueue_head(&(tsi148_device->dma_queue[0])); + init_waitqueue_head(&(tsi148_device->dma_queue[1])); + init_waitqueue_head(&(tsi148_device->iack_queue)); + mutex_init(&(tsi148_device->vme_int)); + mutex_init(&(tsi148_device->vme_rmw)); tsi148_bridge->parent = &(pdev->dev); strcpy(tsi148_bridge->name, driver_name); @@ -2320,29 +2302,29 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id) master_num = TSI148_MAX_MASTER; if(err_chk){ master_num--; - /* XXX */ - flush_image = (struct vme_master_resource *)kmalloc( - sizeof(struct vme_master_resource), GFP_KERNEL); - if (flush_image == NULL) { + + tsi148_device->flush_image = (struct vme_master_resource *) + kmalloc(sizeof(struct vme_master_resource), GFP_KERNEL); + if (tsi148_device->flush_image == NULL) { dev_err(&pdev->dev, "Failed to allocate memory for " "flush resource structure\n"); retval = -ENOMEM; goto err_master; } - flush_image->parent = tsi148_bridge; - spin_lock_init(&(flush_image->lock)); - flush_image->locked = 1; - flush_image->number = master_num; - flush_image->address_attr = VME_A16 | VME_A24 | VME_A32 | - VME_A64; - flush_image->cycle_attr = VME_SCT | VME_BLT | VME_MBLT | - VME_2eVME | VME_2eSST | VME_2eSSTB | VME_2eSST160 | - VME_2eSST267 | VME_2eSST320 | VME_SUPER | VME_USER | - VME_PROG | VME_DATA; - flush_image->width_attr = VME_D16 | VME_D32; - memset(&(flush_image->pci_resource), 0, + tsi148_device->flush_image->parent = tsi148_bridge; + spin_lock_init(&(tsi148_device->flush_image->lock)); + tsi148_device->flush_image->locked = 1; + tsi148_device->flush_image->number = master_num; + tsi148_device->flush_image->address_attr = VME_A16 | VME_A24 | + VME_A32 | VME_A64; + tsi148_device->flush_image->cycle_attr = VME_SCT | VME_BLT | + VME_MBLT | VME_2eVME | VME_2eSST | VME_2eSSTB | + VME_2eSST160 | VME_2eSST267 | VME_2eSST320 | VME_SUPER | + VME_USER | VME_PROG | VME_DATA; + tsi148_device->flush_image->width_attr = VME_D16 | VME_D32; + memset(&(tsi148_device->flush_image->bus_resource), 0, sizeof(struct resource)); - flush_image->kern_base = NULL; + tsi148_device->flush_image->kern_base = NULL; } /* Add master windows to list */ @@ -2367,7 +2349,7 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id) VME_2eSST267 | VME_2eSST320 | VME_SUPER | VME_USER | VME_PROG | VME_DATA; master_image->width_attr = VME_D16 | VME_D32; - memset(&(master_image->pci_resource), 0, + memset(&(master_image->bus_resource), 0, sizeof(struct resource)); master_image->kern_base = NULL; list_add_tail(&(master_image->list), @@ -2415,6 +2397,10 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id) mutex_init(&(dma_ctrlr->mtx)); dma_ctrlr->locked = 0; dma_ctrlr->number = i; + dma_ctrlr->route_attr = VME_DMA_VME_TO_MEM | + VME_DMA_MEM_TO_VME | VME_DMA_VME_TO_VME | + VME_DMA_MEM_TO_MEM | VME_DMA_PATTERN_TO_VME | + VME_DMA_PATTERN_TO_MEM; INIT_LIST_HEAD(&(dma_ctrlr->pending)); INIT_LIST_HEAD(&(dma_ctrlr->running)); list_add_tail(&(dma_ctrlr->list), @@ -2455,40 +2441,42 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id) tsi148_bridge->lm_detach = tsi148_lm_detach; tsi148_bridge->slot_get = tsi148_slot_get; - data = ioread32be(tsi148_bridge->base + TSI148_LCSR_VSTAT); + data = ioread32be(tsi148_device->base + TSI148_LCSR_VSTAT); dev_info(&pdev->dev, "Board is%s the VME system controller\n", (data & TSI148_LCSR_VSTAT_SCONS)? "" : " not"); - dev_info(&pdev->dev, "VME geographical address is %d\n", - data & TSI148_LCSR_VSTAT_GA_M); + if (!geoid) + dev_info(&pdev->dev, "VME geographical address is %d\n", + data & TSI148_LCSR_VSTAT_GA_M); + else + dev_info(&pdev->dev, "VME geographical address is set to %d\n", + geoid); + dev_info(&pdev->dev, "VME Write and flush and error check is %s\n", err_chk ? "enabled" : "disabled"); - if(tsi148_crcsr_init(pdev)) { + if (tsi148_crcsr_init(tsi148_bridge, pdev)) dev_err(&pdev->dev, "CR/CSR configuration failed.\n"); goto err_crcsr; - } - - /* Need to save tsi148_bridge pointer locally in link list for use in - * tsi148_remove() - */ retval = vme_register_bridge(tsi148_bridge); if (retval != 0) { dev_err(&pdev->dev, "Chip Registration failed.\n"); goto err_reg; } + pci_set_drvdata(pdev, tsi148_bridge); + /* Clear VME bus "board fail", and "power-up reset" lines */ - data = ioread32be(tsi148_bridge->base + TSI148_LCSR_VSTAT); + data = ioread32be(tsi148_device->base + TSI148_LCSR_VSTAT); data &= ~TSI148_LCSR_VSTAT_BRDFL; data |= TSI148_LCSR_VSTAT_CPURST; - iowrite32be(data, tsi148_bridge->base + TSI148_LCSR_VSTAT); + iowrite32be(data, tsi148_device->base + TSI148_LCSR_VSTAT); return 0; vme_unregister_bridge(tsi148_bridge); err_reg: - tsi148_crcsr_exit(pdev); + tsi148_crcsr_exit(tsi148_bridge, pdev); err_crcsr: err_lm: /* resources are stored in link list */ @@ -2519,15 +2507,17 @@ err_master: kfree(master_image); } - tsi148_irq_exit(pdev); + tsi148_irq_exit(tsi148_device, pdev); err_irq: err_test: - iounmap(tsi148_bridge->base); + iounmap(tsi148_device->base); err_remap: pci_release_regions(pdev); err_resource: pci_disable_device(pdev); err_enable: + kfree(tsi148_device); +err_driver: kfree(tsi148_bridge); err_struct: return retval; @@ -2541,56 +2531,58 @@ static void tsi148_remove(struct pci_dev *pdev) struct vme_slave_resource *slave_image; struct vme_dma_resource *dma_ctrlr; int i; + struct tsi148_driver *bridge; + struct vme_bridge *tsi148_bridge = pci_get_drvdata(pdev); - dev_dbg(&pdev->dev, "Driver is being unloaded.\n"); + bridge = tsi148_bridge->driver_priv; - /* XXX We need to find the pdev->dev in the list of vme_bridge->dev's */ + + dev_dbg(&pdev->dev, "Driver is being unloaded.\n"); /* * Shutdown all inbound and outbound windows. */ for (i = 0; i < 8; i++) { - iowrite32be(0, tsi148_bridge->base + TSI148_LCSR_IT[i] + + iowrite32be(0, bridge->base + TSI148_LCSR_IT[i] + TSI148_LCSR_OFFSET_ITAT); - iowrite32be(0, tsi148_bridge->base + TSI148_LCSR_OT[i] + + iowrite32be(0, bridge->base + TSI148_LCSR_OT[i] + TSI148_LCSR_OFFSET_OTAT); } /* * Shutdown Location monitor. */ - iowrite32be(0, tsi148_bridge->base + TSI148_LCSR_LMAT); + iowrite32be(0, bridge->base + TSI148_LCSR_LMAT); /* * Shutdown CRG map. */ - iowrite32be(0, tsi148_bridge->base + TSI148_LCSR_CSRAT); + iowrite32be(0, bridge->base + TSI148_LCSR_CSRAT); /* * Clear error status. */ - iowrite32be(0xFFFFFFFF, tsi148_bridge->base + TSI148_LCSR_EDPAT); - iowrite32be(0xFFFFFFFF, tsi148_bridge->base + TSI148_LCSR_VEAT); - iowrite32be(0x07000700, tsi148_bridge->base + TSI148_LCSR_PSTAT); + iowrite32be(0xFFFFFFFF, bridge->base + TSI148_LCSR_EDPAT); + iowrite32be(0xFFFFFFFF, bridge->base + TSI148_LCSR_VEAT); + iowrite32be(0x07000700, bridge->base + TSI148_LCSR_PSTAT); /* * Remove VIRQ interrupt (if any) */ - if (ioread32be(tsi148_bridge->base + TSI148_LCSR_VICR) & 0x800) { - iowrite32be(0x8000, tsi148_bridge->base + TSI148_LCSR_VICR); - } + if (ioread32be(bridge->base + TSI148_LCSR_VICR) & 0x800) + iowrite32be(0x8000, bridge->base + TSI148_LCSR_VICR); /* * Map all Interrupts to PCI INTA */ - iowrite32be(0x0, tsi148_bridge->base + TSI148_LCSR_INTM1); - iowrite32be(0x0, tsi148_bridge->base + TSI148_LCSR_INTM2); + iowrite32be(0x0, bridge->base + TSI148_LCSR_INTM1); + iowrite32be(0x0, bridge->base + TSI148_LCSR_INTM2); - tsi148_irq_exit(pdev); + tsi148_irq_exit(bridge, pdev); vme_unregister_bridge(tsi148_bridge); - tsi148_crcsr_exit(pdev); + tsi148_crcsr_exit(tsi148_bridge, pdev); /* resources are stored in link list */ list_for_each(pos, &(tsi148_bridge->dma_resources)) { @@ -2608,19 +2600,22 @@ static void tsi148_remove(struct pci_dev *pdev) /* resources are stored in link list */ list_for_each(pos, &(tsi148_bridge->master_resources)) { - master_image = list_entry(pos, struct vme_master_resource, list); + master_image = list_entry(pos, struct vme_master_resource, + list); list_del(pos); kfree(master_image); } - tsi148_irq_exit(pdev); + tsi148_irq_exit(bridge, pdev); - iounmap(tsi148_bridge->base); + iounmap(bridge->base); pci_release_regions(pdev); pci_disable_device(pdev); + kfree(tsi148_bridge->driver_priv); + kfree(tsi148_bridge); } @@ -2634,250 +2629,11 @@ static void __exit tsi148_exit(void) MODULE_PARM_DESC(err_chk, "Check for VME errors on reads and writes"); module_param(err_chk, bool, 0); +MODULE_PARM_DESC(geoid, "Override geographical addressing"); +module_param(geoid, int, 0); + MODULE_DESCRIPTION("VME driver for the Tundra Tempe VME bridge"); MODULE_LICENSE("GPL"); module_init(tsi148_init); module_exit(tsi148_exit); - -/*---------------------------------------------------------------------------- - * STAGING - *--------------------------------------------------------------------------*/ - -#if 0 -/* - * Direct Mode DMA transfer - * - * XXX Not looking at direct mode for now, we can always use link list mode - * with a single entry. - */ -int tsi148_dma_run(struct vme_dma_resource *resource, struct vme_dma_attr src, - struct vme_dma_attr dest, size_t count) -{ - u32 dctlreg = 0; - unsigned int tmp; - int val; - int channel, x; - struct vmeDmaPacket *cur_dma; - struct tsi148_dma_descriptor *dmaLL; - - /* direct mode */ - dctlreg = 0x800000; - - for (x = 0; x < 8; x++) { /* vme block size */ - if ((32 << x) >= vmeDma->maxVmeBlockSize) { - break; - } - } - if (x == 8) - x = 7; - dctlreg |= (x << 12); - - for (x = 0; x < 8; x++) { /* pci block size */ - if ((32 << x) >= vmeDma->maxPciBlockSize) { - break; - } - } - if (x == 8) - x = 7; - dctlreg |= (x << 4); - - if (vmeDma->vmeBackOffTimer) { - for (x = 1; x < 8; x++) { /* vme timer */ - if ((1 << (x - 1)) >= vmeDma->vmeBackOffTimer) { - break; - } - } - if (x == 8) - x = 7; - dctlreg |= (x << 8); - } - - if (vmeDma->pciBackOffTimer) { - for (x = 1; x < 8; x++) { /* pci timer */ - if ((1 << (x - 1)) >= vmeDma->pciBackOffTimer) { - break; - } - } - if (x == 8) - x = 7; - dctlreg |= (x << 0); - } - - /* Program registers for DMA transfer */ - iowrite32be(dmaLL->dsau, tsi148_bridge->base + - TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DSAU); - iowrite32be(dmaLL->dsal, tsi148_bridge->base + - TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DSAL); - iowrite32be(dmaLL->ddau, tsi148_bridge->base + - TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DDAU); - iowrite32be(dmaLL->ddal, tsi148_bridge->base + - TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DDAL); - iowrite32be(dmaLL->dsat, tsi148_bridge->base + - TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DSAT); - iowrite32be(dmaLL->ddat, tsi148_bridge->base + - TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DDAT); - iowrite32be(dmaLL->dcnt, tsi148_bridge->base + - TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DCNT); - iowrite32be(dmaLL->ddbs, tsi148_bridge->base + - TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DDBS); - - /* Start the operation */ - iowrite32be(dctlreg | 0x2000000, tsi148_bridge->base + - TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DCTL); - - tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_DMA[channel] + - TSI148_LCSR_OFFSET_DSTA); - wait_event_interruptible(dma_queue[channel], (tmp & 0x1000000) == 0); - - /* - * Read status register, we should probably do this in some error - * handler rather than here so that we can be sure we haven't kicked off - * another DMA transfer. - */ - val = ioread32be(tsi148_bridge->base + TSI148_LCSR_DMA[channel] + - TSI148_LCSR_OFFSET_DSTA); - - vmeDma->vmeDmaStatus = 0; - if (val & 0x10000000) { - printk(KERN_ERR - "DMA Error in DMA_tempe_irqhandler DSTA=%08X\n", - val); - vmeDma->vmeDmaStatus = val; - - } - return (0); -} -#endif - -#if 0 - -/* Global VME controller information */ -struct pci_dev *vme_pci_dev; - -/* - * Set the VME bus arbiter with the requested attributes - */ -int tempe_set_arbiter(vmeArbiterCfg_t * vmeArb) -{ - int temp_ctl = 0; - int gto = 0; - - temp_ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_VCTRL); - temp_ctl &= 0xFFEFFF00; - - if (vmeArb->globalTimeoutTimer == 0xFFFFFFFF) { - gto = 8; - } else if (vmeArb->globalTimeoutTimer > 2048) { - return (-EINVAL); - } else if (vmeArb->globalTimeoutTimer == 0) { - gto = 0; - } else { - gto = 1; - while ((16 * (1 << (gto - 1))) < vmeArb->globalTimeoutTimer) { - gto += 1; - } - } - temp_ctl |= gto; - - if (vmeArb->arbiterMode != VME_PRIORITY_MODE) { - temp_ctl |= 1 << 6; - } - - if (vmeArb->arbiterTimeoutFlag) { - temp_ctl |= 1 << 7; - } - - if (vmeArb->noEarlyReleaseFlag) { - temp_ctl |= 1 << 20; - } - iowrite32be(temp_ctl, tsi148_bridge->base + TSI148_LCSR_VCTRL); - - return (0); -} - -/* - * Return the attributes of the VME bus arbiter. - */ -int tempe_get_arbiter(vmeArbiterCfg_t * vmeArb) -{ - int temp_ctl = 0; - int gto = 0; - - - temp_ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_VCTRL); - - gto = temp_ctl & 0xF; - if (gto != 0) { - vmeArb->globalTimeoutTimer = (16 * (1 << (gto - 1))); - } - - if (temp_ctl & (1 << 6)) { - vmeArb->arbiterMode = VME_R_ROBIN_MODE; - } else { - vmeArb->arbiterMode = VME_PRIORITY_MODE; - } - - if (temp_ctl & (1 << 7)) { - vmeArb->arbiterTimeoutFlag = 1; - } - - if (temp_ctl & (1 << 20)) { - vmeArb->noEarlyReleaseFlag = 1; - } - - return (0); -} - -/* - * Set the VME bus requestor with the requested attributes - */ -int tempe_set_requestor(vmeRequesterCfg_t * vmeReq) -{ - int temp_ctl = 0; - - temp_ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_VMCTRL); - temp_ctl &= 0xFFFF0000; - - if (vmeReq->releaseMode == 1) { - temp_ctl |= (1 << 3); - } - - if (vmeReq->fairMode == 1) { - temp_ctl |= (1 << 2); - } - - temp_ctl |= (vmeReq->timeonTimeoutTimer & 7) << 8; - temp_ctl |= (vmeReq->timeoffTimeoutTimer & 7) << 12; - temp_ctl |= vmeReq->requestLevel; - - iowrite32be(temp_ctl, tsi148_bridge->base + TSI148_LCSR_VMCTRL); - return (0); -} - -/* - * Return the attributes of the VME bus requestor - */ -int tempe_get_requestor(vmeRequesterCfg_t * vmeReq) -{ - int temp_ctl = 0; - - temp_ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_VMCTRL); - - if (temp_ctl & 0x18) { - vmeReq->releaseMode = 1; - } - - if (temp_ctl & (1 << 2)) { - vmeReq->fairMode = 1; - } - - vmeReq->requestLevel = temp_ctl & 3; - vmeReq->timeonTimeoutTimer = (temp_ctl >> 8) & 7; - vmeReq->timeoffTimeoutTimer = (temp_ctl >> 12) & 7; - - return (0); -} - - -#endif diff --git a/drivers/staging/vme/bridges/vme_tsi148.h b/drivers/staging/vme/bridges/vme_tsi148.h index 6f0f705..9e5f7fa 100644 --- a/drivers/staging/vme/bridges/vme_tsi148.h +++ b/drivers/staging/vme/bridges/vme_tsi148.h @@ -33,6 +33,22 @@ #define TSI148_MAX_MAILBOX 4 /* Max Mail Box registers */ #define TSI148_MAX_SEMAPHORE 8 /* Max Semaphores */ +/* Structure used to hold driver specific information */ +struct tsi148_driver { + void *base; /* Base Address of device registers */ + wait_queue_head_t dma_queue[2]; + wait_queue_head_t iack_queue; + void (*lm_callback[4])(int); /* Called in interrupt handler */ + void *crcsr_kernel; + dma_addr_t crcsr_bus; + struct vme_master_resource *flush_image; + struct mutex vme_rmw; /* Only one RMW cycle at a time */ + struct mutex vme_int; /* + * Only one VME interrupt can be + * generated at a time, provide locking + */ +}; + /* * Layout of a DMAC Linked-List Descriptor * diff --git a/drivers/staging/vme/devices/vme_user.c b/drivers/staging/vme/devices/vme_user.c index e228942..c60c80f 100644 --- a/drivers/staging/vme/devices/vme_user.c +++ b/drivers/staging/vme/devices/vme_user.c @@ -1,8 +1,8 @@ /* * VMEbus User access driver * - * Author: Martyn Welch <martyn.welch@gefanuc.com> - * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc. + * Author: Martyn Welch <martyn.welch@ge.com> + * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc. * * Based on work by: * Tom Armistead and Ajit Prem @@ -400,8 +400,39 @@ static ssize_t vme_user_write(struct file *file, const char *buf, size_t count, static loff_t vme_user_llseek(struct file *file, loff_t off, int whence) { - printk(KERN_ERR "Llseek currently incomplete\n"); - return -EINVAL; + loff_t absolute = -1; + unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev); + size_t image_size; + + down(&image[minor].sem); + image_size = vme_get_size(image[minor].resource); + + switch (whence) { + case SEEK_SET: + absolute = off; + break; + case SEEK_CUR: + absolute = file->f_pos + off; + break; + case SEEK_END: + absolute = image_size + off; + break; + default: + up(&image[minor].sem); + return -EINVAL; + break; + } + + if ((absolute < 0) || (absolute >= image_size)) { + up(&image[minor].sem); + return -EINVAL; + } + + file->f_pos = absolute; + + up(&image[minor].sem); + + return absolute; } /* @@ -574,8 +605,8 @@ static int __init vme_user_init(void) * in future revisions if that ever becomes necessary. */ if (bus_num > USER_BUS_MAX) { - printk(KERN_ERR "%s: Driver only able to handle %d PIO2 " - "Cards\n", driver_name, USER_BUS_MAX); + printk(KERN_ERR "%s: Driver only able to handle %d buses\n", + driver_name, USER_BUS_MAX); bus_num = USER_BUS_MAX; } @@ -670,8 +701,12 @@ static int __init vme_user_probe(struct device *dev, int cur_bus, int cur_slot) /* Request slave resources and allocate buffers (128kB wide) */ for (i = SLAVE_MINOR; i < (SLAVE_MAX + 1); i++) { /* XXX Need to properly request attributes */ + /* For ca91cx42 bridge there are only two slave windows + * supporting A16 addressing, so we request A24 supported + * by all windows. + */ image[i].resource = vme_slave_request(vme_user_bridge, - VME_A16, VME_SCT); + VME_A24, VME_SCT); if (image[i].resource == NULL) { printk(KERN_WARNING "Unable to allocate slave " "resource\n"); @@ -703,6 +738,14 @@ static int __init vme_user_probe(struct device *dev, int cur_bus, int cur_slot) "resource\n"); goto err_master; } + image[i].size_buf = PCI_BUF_SIZE; + image[i].kern_buf = kmalloc(image[i].size_buf, GFP_KERNEL); + if (image[i].kern_buf == NULL) { + printk(KERN_WARNING "Unable to allocate memory for " + "master window buffers\n"); + err = -ENOMEM; + goto err_master_buf; + } } /* Create sysfs entries - on udev systems this creates the dev files */ @@ -756,6 +799,9 @@ err_sysfs: /* Ensure counter set correcty to unalloc all master windows */ i = MASTER_MAX + 1; +err_master_buf: + for (i = MASTER_MINOR; i < (MASTER_MAX + 1); i++) + kfree(image[i].kern_buf); err_master: while (i > MASTER_MINOR) { i--; @@ -791,6 +837,9 @@ static int __exit vme_user_remove(struct device *dev, int cur_bus, int cur_slot) } class_destroy(vme_user_sysfs_class); + for (i = MASTER_MINOR; i < (MASTER_MAX + 1); i++) + kfree(image[i].kern_buf); + for (i = SLAVE_MINOR; i < (SLAVE_MAX + 1); i++) { vme_slave_set(image[i].resource, 0, 0, 0, 0, VME_A32, 0); vme_slave_free(image[i].resource); @@ -818,7 +867,7 @@ MODULE_PARM_DESC(bus, "Enumeration of VMEbus to which the driver is connected"); module_param_array(bus, int, &bus_num, 0); MODULE_DESCRIPTION("VME User Space Access Driver"); -MODULE_AUTHOR("Martyn Welch <martyn.welch@gefanuc.com"); +MODULE_AUTHOR("Martyn Welch <martyn.welch@ge.com"); MODULE_LICENSE("GPL"); module_init(vme_user_init); diff --git a/drivers/staging/vme/vme.c b/drivers/staging/vme/vme.c index 994fdb9..d6d84eb 100644 --- a/drivers/staging/vme/vme.c +++ b/drivers/staging/vme/vme.c @@ -1,8 +1,8 @@ /* * VME Bridge Framework * - * Author: Martyn Welch <martyn.welch@gefanuc.com> - * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc. + * Author: Martyn Welch <martyn.welch@ge.com> + * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc. * * Based on work by Tom Armistead and Ajit Prem * Copyright 2004 Motorola Inc. @@ -37,8 +37,8 @@ static unsigned int vme_bus_numbers; DEFINE_MUTEX(vme_bus_num_mtx); -static void __exit vme_exit (void); -static int __init vme_init (void); +static void __exit vme_exit(void); +static int __init vme_init(void); /* @@ -86,26 +86,26 @@ static struct vme_bridge *find_bridge(struct vme_resource *resource) * XXX VME bridges could be available on buses other than PCI. At the momment * this framework only supports PCI devices. */ -void * vme_alloc_consistent(struct vme_resource *resource, size_t size, +void *vme_alloc_consistent(struct vme_resource *resource, size_t size, dma_addr_t *dma) { struct vme_bridge *bridge; struct pci_dev *pdev; - if(resource == NULL) { - printk("No resource\n"); + if (resource == NULL) { + printk(KERN_ERR "No resource\n"); return NULL; } bridge = find_bridge(resource); - if(bridge == NULL) { - printk("Can't find bridge\n"); + if (bridge == NULL) { + printk(KERN_ERR "Can't find bridge\n"); return NULL; } /* Find pci_dev container of dev */ if (bridge->parent == NULL) { - printk("Dev entry NULL\n"); + printk(KERN_ERR "Dev entry NULL\n"); return NULL; } pdev = container_of(bridge->parent, struct pci_dev, dev); @@ -126,14 +126,14 @@ void vme_free_consistent(struct vme_resource *resource, size_t size, struct vme_bridge *bridge; struct pci_dev *pdev; - if(resource == NULL) { - printk("No resource\n"); + if (resource == NULL) { + printk(KERN_ERR "No resource\n"); return; } bridge = find_bridge(resource); - if(bridge == NULL) { - printk("Can't find bridge\n"); + if (bridge == NULL) { + printk(KERN_ERR "Can't find bridge\n"); return; } @@ -216,7 +216,7 @@ static int vme_check_window(vme_address_t aspace, unsigned long long vme_base, /* User Defined */ break; default: - printk("Invalid address space\n"); + printk(KERN_ERR "Invalid address space\n"); retval = -EINVAL; break; } @@ -228,7 +228,7 @@ static int vme_check_window(vme_address_t aspace, unsigned long long vme_base, * Request a slave image with specific attributes, return some unique * identifier. */ -struct vme_resource * vme_slave_request(struct device *dev, +struct vme_resource *vme_slave_request(struct device *dev, vme_address_t address, vme_cycle_t cycle) { struct vme_bridge *bridge; @@ -249,13 +249,13 @@ struct vme_resource * vme_slave_request(struct device *dev, struct vme_slave_resource, list); if (slave_image == NULL) { - printk("Registered NULL Slave resource\n"); + printk(KERN_ERR "Registered NULL Slave resource\n"); continue; } /* Find an unlocked and compatible image */ mutex_lock(&(slave_image->mtx)); - if(((slave_image->address_attr & address) == address) && + if (((slave_image->address_attr & address) == address) && ((slave_image->cycle_attr & cycle) == cycle) && (slave_image->locked == 0)) { @@ -292,7 +292,7 @@ err_bus: } EXPORT_SYMBOL(vme_slave_request); -int vme_slave_set (struct vme_resource *resource, int enabled, +int vme_slave_set(struct vme_resource *resource, int enabled, unsigned long long vme_base, unsigned long long size, dma_addr_t buf_base, vme_address_t aspace, vme_cycle_t cycle) { @@ -301,25 +301,25 @@ int vme_slave_set (struct vme_resource *resource, int enabled, int retval; if (resource->type != VME_SLAVE) { - printk("Not a slave resource\n"); + printk(KERN_ERR "Not a slave resource\n"); return -EINVAL; } image = list_entry(resource->entry, struct vme_slave_resource, list); if (bridge->slave_set == NULL) { - printk("Function not supported\n"); + printk(KERN_ERR "Function not supported\n"); return -ENOSYS; } - if(!(((image->address_attr & aspace) == aspace) && + if (!(((image->address_attr & aspace) == aspace) && ((image->cycle_attr & cycle) == cycle))) { - printk("Invalid attributes\n"); + printk(KERN_ERR "Invalid attributes\n"); return -EINVAL; } retval = vme_check_window(aspace, vme_base, size); - if(retval) + if (retval) return retval; return bridge->slave_set(image, enabled, vme_base, size, buf_base, @@ -327,7 +327,7 @@ int vme_slave_set (struct vme_resource *resource, int enabled, } EXPORT_SYMBOL(vme_slave_set); -int vme_slave_get (struct vme_resource *resource, int *enabled, +int vme_slave_get(struct vme_resource *resource, int *enabled, unsigned long long *vme_base, unsigned long long *size, dma_addr_t *buf_base, vme_address_t *aspace, vme_cycle_t *cycle) { @@ -335,14 +335,14 @@ int vme_slave_get (struct vme_resource *resource, int *enabled, struct vme_slave_resource *image; if (resource->type != VME_SLAVE) { - printk("Not a slave resource\n"); + printk(KERN_ERR "Not a slave resource\n"); return -EINVAL; } image = list_entry(resource->entry, struct vme_slave_resource, list); if (bridge->slave_get == NULL) { - printk("vme_slave_get not supported\n"); + printk(KERN_ERR "vme_slave_get not supported\n"); return -EINVAL; } @@ -356,14 +356,14 @@ void vme_slave_free(struct vme_resource *resource) struct vme_slave_resource *slave_image; if (resource->type != VME_SLAVE) { - printk("Not a slave resource\n"); + printk(KERN_ERR "Not a slave resource\n"); return; } slave_image = list_entry(resource->entry, struct vme_slave_resource, list); if (slave_image == NULL) { - printk("Can't find slave resource\n"); + printk(KERN_ERR "Can't find slave resource\n"); return; } @@ -384,7 +384,7 @@ EXPORT_SYMBOL(vme_slave_free); * Request a master image with specific attributes, return some unique * identifier. */ -struct vme_resource * vme_master_request(struct device *dev, +struct vme_resource *vme_master_request(struct device *dev, vme_address_t address, vme_cycle_t cycle, vme_width_t dwidth) { struct vme_bridge *bridge; @@ -411,7 +411,7 @@ struct vme_resource * vme_master_request(struct device *dev, /* Find an unlocked and compatible image */ spin_lock(&(master_image->lock)); - if(((master_image->address_attr & address) == address) && + if (((master_image->address_attr & address) == address) && ((master_image->cycle_attr & cycle) == cycle) && ((master_image->width_attr & dwidth) == dwidth) && (master_image->locked == 0)) { @@ -452,7 +452,7 @@ err_bus: } EXPORT_SYMBOL(vme_master_request); -int vme_master_set (struct vme_resource *resource, int enabled, +int vme_master_set(struct vme_resource *resource, int enabled, unsigned long long vme_base, unsigned long long size, vme_address_t aspace, vme_cycle_t cycle, vme_width_t dwidth) { @@ -461,26 +461,26 @@ int vme_master_set (struct vme_resource *resource, int enabled, int retval; if (resource->type != VME_MASTER) { - printk("Not a master resource\n"); + printk(KERN_ERR "Not a master resource\n"); return -EINVAL; } image = list_entry(resource->entry, struct vme_master_resource, list); if (bridge->master_set == NULL) { - printk("vme_master_set not supported\n"); + printk(KERN_WARNING "vme_master_set not supported\n"); return -EINVAL; } - if(!(((image->address_attr & aspace) == aspace) && + if (!(((image->address_attr & aspace) == aspace) && ((image->cycle_attr & cycle) == cycle) && ((image->width_attr & dwidth) == dwidth))) { - printk("Invalid attributes\n"); + printk(KERN_WARNING "Invalid attributes\n"); return -EINVAL; } retval = vme_check_window(aspace, vme_base, size); - if(retval) + if (retval) return retval; return bridge->master_set(image, enabled, vme_base, size, aspace, @@ -488,7 +488,7 @@ int vme_master_set (struct vme_resource *resource, int enabled, } EXPORT_SYMBOL(vme_master_set); -int vme_master_get (struct vme_resource *resource, int *enabled, +int vme_master_get(struct vme_resource *resource, int *enabled, unsigned long long *vme_base, unsigned long long *size, vme_address_t *aspace, vme_cycle_t *cycle, vme_width_t *dwidth) { @@ -496,14 +496,14 @@ int vme_master_get (struct vme_resource *resource, int *enabled, struct vme_master_resource *image; if (resource->type != VME_MASTER) { - printk("Not a master resource\n"); + printk(KERN_ERR "Not a master resource\n"); return -EINVAL; } image = list_entry(resource->entry, struct vme_master_resource, list); if (bridge->master_get == NULL) { - printk("vme_master_set not supported\n"); + printk(KERN_WARNING "vme_master_set not supported\n"); return -EINVAL; } @@ -515,7 +515,7 @@ EXPORT_SYMBOL(vme_master_get); /* * Read data out of VME space into a buffer. */ -ssize_t vme_master_read (struct vme_resource *resource, void *buf, size_t count, +ssize_t vme_master_read(struct vme_resource *resource, void *buf, size_t count, loff_t offset) { struct vme_bridge *bridge = find_bridge(resource); @@ -523,12 +523,12 @@ ssize_t vme_master_read (struct vme_resource *resource, void *buf, size_t count, size_t length; if (bridge->master_read == NULL) { - printk("Reading from resource not supported\n"); + printk(KERN_WARNING "Reading from resource not supported\n"); return -EINVAL; } if (resource->type != VME_MASTER) { - printk("Not a master resource\n"); + printk(KERN_ERR "Not a master resource\n"); return -EINVAL; } @@ -537,7 +537,7 @@ ssize_t vme_master_read (struct vme_resource *resource, void *buf, size_t count, length = vme_get_size(resource); if (offset > length) { - printk("Invalid Offset\n"); + printk(KERN_WARNING "Invalid Offset\n"); return -EFAULT; } @@ -552,7 +552,7 @@ EXPORT_SYMBOL(vme_master_read); /* * Write data out to VME space from a buffer. */ -ssize_t vme_master_write (struct vme_resource *resource, void *buf, +ssize_t vme_master_write(struct vme_resource *resource, void *buf, size_t count, loff_t offset) { struct vme_bridge *bridge = find_bridge(resource); @@ -560,12 +560,12 @@ ssize_t vme_master_write (struct vme_resource *resource, void *buf, size_t length; if (bridge->master_write == NULL) { - printk("Writing to resource not supported\n"); + printk(KERN_WARNING "Writing to resource not supported\n"); return -EINVAL; } if (resource->type != VME_MASTER) { - printk("Not a master resource\n"); + printk(KERN_ERR "Not a master resource\n"); return -EINVAL; } @@ -574,7 +574,7 @@ ssize_t vme_master_write (struct vme_resource *resource, void *buf, length = vme_get_size(resource); if (offset > length) { - printk("Invalid Offset\n"); + printk(KERN_WARNING "Invalid Offset\n"); return -EFAULT; } @@ -588,19 +588,19 @@ EXPORT_SYMBOL(vme_master_write); /* * Perform RMW cycle to provided location. */ -unsigned int vme_master_rmw (struct vme_resource *resource, unsigned int mask, +unsigned int vme_master_rmw(struct vme_resource *resource, unsigned int mask, unsigned int compare, unsigned int swap, loff_t offset) { struct vme_bridge *bridge = find_bridge(resource); struct vme_master_resource *image; if (bridge->master_rmw == NULL) { - printk("Writing to resource not supported\n"); + printk(KERN_WARNING "Writing to resource not supported\n"); return -EINVAL; } if (resource->type != VME_MASTER) { - printk("Not a master resource\n"); + printk(KERN_ERR "Not a master resource\n"); return -EINVAL; } @@ -615,14 +615,14 @@ void vme_master_free(struct vme_resource *resource) struct vme_master_resource *master_image; if (resource->type != VME_MASTER) { - printk("Not a master resource\n"); + printk(KERN_ERR "Not a master resource\n"); return; } master_image = list_entry(resource->entry, struct vme_master_resource, list); if (master_image == NULL) { - printk("Can't find master resource\n"); + printk(KERN_ERR "Can't find master resource\n"); return; } @@ -643,7 +643,7 @@ EXPORT_SYMBOL(vme_master_free); * Request a DMA controller with specific attributes, return some unique * identifier. */ -struct vme_resource *vme_dma_request(struct device *dev) +struct vme_resource *vme_dma_request(struct device *dev, vme_dma_route_t route) { struct vme_bridge *bridge; struct list_head *dma_pos = NULL; @@ -666,13 +666,15 @@ struct vme_resource *vme_dma_request(struct device *dev) struct vme_dma_resource, list); if (dma_ctrlr == NULL) { - printk("Registered NULL DMA resource\n"); + printk(KERN_ERR "Registered NULL DMA resource\n"); continue; } - /* Find an unlocked controller */ + /* Find an unlocked and compatible controller */ mutex_lock(&(dma_ctrlr->mtx)); - if(dma_ctrlr->locked == 0) { + if (((dma_ctrlr->route_attr & route) == route) && + (dma_ctrlr->locked == 0)) { + dma_ctrlr->locked = 1; mutex_unlock(&(dma_ctrlr->mtx)); allocated_ctrlr = dma_ctrlr; @@ -715,16 +717,15 @@ struct vme_dma_list *vme_new_dma_list(struct vme_resource *resource) struct vme_dma_list *dma_list; if (resource->type != VME_DMA) { - printk("Not a DMA resource\n"); + printk(KERN_ERR "Not a DMA resource\n"); return NULL; } ctrlr = list_entry(resource->entry, struct vme_dma_resource, list); - dma_list = (struct vme_dma_list *)kmalloc( - sizeof(struct vme_dma_list), GFP_KERNEL); - if(dma_list == NULL) { - printk("Unable to allocate memory for new dma list\n"); + dma_list = kmalloc(sizeof(struct vme_dma_list), GFP_KERNEL); + if (dma_list == NULL) { + printk(KERN_ERR "Unable to allocate memory for new dma list\n"); return NULL; } INIT_LIST_HEAD(&(dma_list->entries)); @@ -744,17 +745,17 @@ struct vme_dma_attr *vme_dma_pattern_attribute(u32 pattern, struct vme_dma_attr *attributes; struct vme_dma_pattern *pattern_attr; - attributes = (struct vme_dma_attr *)kmalloc( - sizeof(struct vme_dma_attr), GFP_KERNEL); - if(attributes == NULL) { - printk("Unable to allocate memory for attributes structure\n"); + attributes = kmalloc(sizeof(struct vme_dma_attr), GFP_KERNEL); + if (attributes == NULL) { + printk(KERN_ERR "Unable to allocate memory for attributes " + "structure\n"); goto err_attr; } - pattern_attr = (struct vme_dma_pattern *)kmalloc( - sizeof(struct vme_dma_pattern), GFP_KERNEL); - if(pattern_attr == NULL) { - printk("Unable to allocate memory for pattern attributes\n"); + pattern_attr = kmalloc(sizeof(struct vme_dma_pattern), GFP_KERNEL); + if (pattern_attr == NULL) { + printk(KERN_ERR "Unable to allocate memory for pattern " + "attributes\n"); goto err_pat; } @@ -784,17 +785,17 @@ struct vme_dma_attr *vme_dma_pci_attribute(dma_addr_t address) /* XXX Run some sanity checks here */ - attributes = (struct vme_dma_attr *)kmalloc( - sizeof(struct vme_dma_attr), GFP_KERNEL); - if(attributes == NULL) { - printk("Unable to allocate memory for attributes structure\n"); + attributes = kmalloc(sizeof(struct vme_dma_attr), GFP_KERNEL); + if (attributes == NULL) { + printk(KERN_ERR "Unable to allocate memory for attributes " + "structure\n"); goto err_attr; } - pci_attr = (struct vme_dma_pci *)kmalloc(sizeof(struct vme_dma_pci), - GFP_KERNEL); - if(pci_attr == NULL) { - printk("Unable to allocate memory for pci attributes\n"); + pci_attr = kmalloc(sizeof(struct vme_dma_pci), GFP_KERNEL); + if (pci_attr == NULL) { + printk(KERN_ERR "Unable to allocate memory for pci " + "attributes\n"); goto err_pci; } @@ -824,19 +825,18 @@ struct vme_dma_attr *vme_dma_vme_attribute(unsigned long long address, struct vme_dma_attr *attributes; struct vme_dma_vme *vme_attr; - /* XXX Run some sanity checks here */ - - attributes = (struct vme_dma_attr *)kmalloc( + attributes = kmalloc( sizeof(struct vme_dma_attr), GFP_KERNEL); - if(attributes == NULL) { - printk("Unable to allocate memory for attributes structure\n"); + if (attributes == NULL) { + printk(KERN_ERR "Unable to allocate memory for attributes " + "structure\n"); goto err_attr; } - vme_attr = (struct vme_dma_vme *)kmalloc(sizeof(struct vme_dma_vme), - GFP_KERNEL); - if(vme_attr == NULL) { - printk("Unable to allocate memory for vme attributes\n"); + vme_attr = kmalloc(sizeof(struct vme_dma_vme), GFP_KERNEL); + if (vme_attr == NULL) { + printk(KERN_ERR "Unable to allocate memory for vme " + "attributes\n"); goto err_vme; } @@ -875,12 +875,12 @@ int vme_dma_list_add(struct vme_dma_list *list, struct vme_dma_attr *src, int retval; if (bridge->dma_list_add == NULL) { - printk("Link List DMA generation not supported\n"); + printk(KERN_WARNING "Link List DMA generation not supported\n"); return -EINVAL; } if (!mutex_trylock(&(list->mtx))) { - printk("Link List already submitted\n"); + printk(KERN_ERR "Link List already submitted\n"); return -EINVAL; } @@ -898,7 +898,7 @@ int vme_dma_list_exec(struct vme_dma_list *list) int retval; if (bridge->dma_list_exec == NULL) { - printk("Link List DMA execution not supported\n"); + printk(KERN_ERR "Link List DMA execution not supported\n"); return -EINVAL; } @@ -918,12 +918,12 @@ int vme_dma_list_free(struct vme_dma_list *list) int retval; if (bridge->dma_list_empty == NULL) { - printk("Emptying of Link Lists not supported\n"); + printk(KERN_WARNING "Emptying of Link Lists not supported\n"); return -EINVAL; } if (!mutex_trylock(&(list->mtx))) { - printk("Link List in use\n"); + printk(KERN_ERR "Link List in use\n"); return -EINVAL; } @@ -933,7 +933,7 @@ int vme_dma_list_free(struct vme_dma_list *list) */ retval = bridge->dma_list_empty(list); if (retval) { - printk("Unable to empty link-list entries\n"); + printk(KERN_ERR "Unable to empty link-list entries\n"); mutex_unlock(&(list->mtx)); return retval; } @@ -949,19 +949,19 @@ int vme_dma_free(struct vme_resource *resource) struct vme_dma_resource *ctrlr; if (resource->type != VME_DMA) { - printk("Not a DMA resource\n"); + printk(KERN_ERR "Not a DMA resource\n"); return -EINVAL; } ctrlr = list_entry(resource->entry, struct vme_dma_resource, list); if (!mutex_trylock(&(ctrlr->mtx))) { - printk("Resource busy, can't free\n"); + printk(KERN_ERR "Resource busy, can't free\n"); return -EBUSY; } if (!(list_empty(&(ctrlr->pending)) && list_empty(&(ctrlr->running)))) { - printk("Resource still processing transfers\n"); + printk(KERN_WARNING "Resource still processing transfers\n"); mutex_unlock(&(ctrlr->mtx)); return -EBUSY; } @@ -991,7 +991,7 @@ void vme_irq_handler(struct vme_bridge *bridge, int level, int statid) EXPORT_SYMBOL(vme_irq_handler); int vme_irq_request(struct device *dev, int level, int statid, - void (*callback)(int level, int vector, void *priv_data), + void (*callback)(int, int, void *), void *priv_data) { struct vme_bridge *bridge; @@ -1002,7 +1002,7 @@ int vme_irq_request(struct device *dev, int level, int statid, return -EINVAL; } - if((level < 1) || (level > 7)) { + if ((level < 1) || (level > 7)) { printk(KERN_ERR "Invalid interrupt level\n"); return -EINVAL; } @@ -1025,7 +1025,7 @@ int vme_irq_request(struct device *dev, int level, int statid, bridge->irq[level - 1].callback[statid].func = callback; /* Enable IRQ level */ - bridge->irq_set(level, 1, 1); + bridge->irq_set(bridge, level, 1, 1); mutex_unlock(&(bridge->irq_mtx)); @@ -1043,7 +1043,7 @@ void vme_irq_free(struct device *dev, int level, int statid) return; } - if((level < 1) || (level > 7)) { + if ((level < 1) || (level > 7)) { printk(KERN_ERR "Invalid interrupt level\n"); return; } @@ -1059,7 +1059,7 @@ void vme_irq_free(struct device *dev, int level, int statid) /* Disable IRQ level if no more interrupts attached at this level*/ if (bridge->irq[level - 1].count == 0) - bridge->irq_set(level, 0, 1); + bridge->irq_set(bridge, level, 0, 1); bridge->irq[level - 1].callback[statid].func = NULL; bridge->irq[level - 1].callback[statid].priv_data = NULL; @@ -1078,17 +1078,17 @@ int vme_irq_generate(struct device *dev, int level, int statid) return -EINVAL; } - if((level < 1) || (level > 7)) { + if ((level < 1) || (level > 7)) { printk(KERN_WARNING "Invalid interrupt level\n"); return -EINVAL; } if (bridge->irq_generate == NULL) { - printk("Interrupt generation not supported\n"); + printk(KERN_WARNING "Interrupt generation not supported\n"); return -EINVAL; } - return bridge->irq_generate(level, statid); + return bridge->irq_generate(bridge, level, statid); } EXPORT_SYMBOL(vme_irq_generate); @@ -1189,8 +1189,6 @@ int vme_lm_set(struct vme_resource *resource, unsigned long long lm_base, return -EINVAL; } - /* XXX Check parameters */ - return bridge->lm_set(lm, lm_base, aspace, cycle); } EXPORT_SYMBOL(vme_lm_set); @@ -1297,11 +1295,11 @@ int vme_slot_get(struct device *bus) } if (bridge->slot_get == NULL) { - printk("vme_slot_get not supported\n"); + printk(KERN_WARNING "vme_slot_get not supported\n"); return -EINVAL; } - return bridge->slot_get(); + return bridge->slot_get(bridge); } EXPORT_SYMBOL(vme_slot_get); @@ -1331,7 +1329,7 @@ static void vme_free_bus_num(int bus) mutex_unlock(&vme_bus_num_mtx); } -int vme_register_bridge (struct vme_bridge *bridge) +int vme_register_bridge(struct vme_bridge *bridge) { struct device *dev; int retval; @@ -1358,7 +1356,7 @@ int vme_register_bridge (struct vme_bridge *bridge) dev_set_name(dev, "vme-%x.%x", bridge->num, i + 1); retval = device_register(dev); - if(retval) + if (retval) goto err_reg; } @@ -1375,7 +1373,7 @@ err_reg: } EXPORT_SYMBOL(vme_register_bridge); -void vme_unregister_bridge (struct vme_bridge *bridge) +void vme_unregister_bridge(struct vme_bridge *bridge) { int i; struct device *dev; @@ -1392,7 +1390,7 @@ EXPORT_SYMBOL(vme_unregister_bridge); /* - Driver Registration --------------------------------------------------- */ -int vme_register_driver (struct vme_driver *drv) +int vme_register_driver(struct vme_driver *drv) { drv->driver.name = drv->name; drv->driver.bus = &vme_bus_type; @@ -1401,7 +1399,7 @@ int vme_register_driver (struct vme_driver *drv) } EXPORT_SYMBOL(vme_register_driver); -void vme_unregister_driver (struct vme_driver *drv) +void vme_unregister_driver(struct vme_driver *drv) { driver_unregister(&drv->driver); } @@ -1418,10 +1416,10 @@ int vme_calc_slot(struct device *dev) /* Determine slot number */ num = 0; - while(num < VME_SLOTS_MAX) { - if(&(bridge->dev[num]) == dev) { + while (num < VME_SLOTS_MAX) { + if (&(bridge->dev[num]) == dev) break; - } + num++; } if (num == VME_SLOTS_MAX) { @@ -1437,8 +1435,8 @@ err_dev: static struct vme_driver *dev_to_vme_driver(struct device *dev) { - if(dev->driver == NULL) - printk("Bugger dev->driver is NULL\n"); + if (dev->driver == NULL) + printk(KERN_ERR "Bugger dev->driver is NULL\n"); return container_of(dev->driver, struct vme_driver, driver); } @@ -1462,7 +1460,7 @@ static int vme_bus_match(struct device *dev, struct device_driver *drv) } i = 0; - while((driver->bind_table[i].bus != 0) || + while ((driver->bind_table[i].bus != 0) || (driver->bind_table[i].slot != 0)) { if (bridge->num == driver->bind_table[i].bus) { @@ -1493,9 +1491,8 @@ static int vme_bus_probe(struct device *dev) driver = dev_to_vme_driver(dev); bridge = dev_to_bridge(dev); - if(driver->probe != NULL) { + if (driver->probe != NULL) retval = driver->probe(dev, bridge->num, vme_calc_slot(dev)); - } return retval; } @@ -1509,9 +1506,8 @@ static int vme_bus_remove(struct device *dev) driver = dev_to_vme_driver(dev); bridge = dev_to_bridge(dev); - if(driver->remove != NULL) { + if (driver->remove != NULL) retval = driver->remove(dev, bridge->num, vme_calc_slot(dev)); - } return retval; } @@ -1524,18 +1520,18 @@ struct bus_type vme_bus_type = { }; EXPORT_SYMBOL(vme_bus_type); -static int __init vme_init (void) +static int __init vme_init(void) { return bus_register(&vme_bus_type); } -static void __exit vme_exit (void) +static void __exit vme_exit(void) { bus_unregister(&vme_bus_type); } MODULE_DESCRIPTION("VME bridge driver framework"); -MODULE_AUTHOR("Martyn Welch <martyn.welch@gefanuc.com"); +MODULE_AUTHOR("Martyn Welch <martyn.welch@ge.com"); MODULE_LICENSE("GPL"); module_init(vme_init); diff --git a/drivers/staging/vme/vme.h b/drivers/staging/vme/vme.h index 97dc22e..48768ca 100644 --- a/drivers/staging/vme/vme.h +++ b/drivers/staging/vme/vme.h @@ -68,6 +68,14 @@ typedef u32 vme_pattern_t; #define VME_DMA_PATTERN_WORD (1<<1) #define VME_DMA_PATTERN_INCREMENT (1<<2) +typedef u32 vme_dma_route_t; +#define VME_DMA_VME_TO_MEM (1<<0) +#define VME_DMA_MEM_TO_VME (1<<1) +#define VME_DMA_VME_TO_VME (1<<2) +#define VME_DMA_MEM_TO_MEM (1<<3) +#define VME_DMA_PATTERN_TO_VME (1<<4) +#define VME_DMA_PATTERN_TO_MEM (1<<5) + struct vme_dma_attr { vme_dma_t type; void *private; @@ -98,32 +106,33 @@ struct vme_driver { struct device_driver driver; }; -void * vme_alloc_consistent(struct vme_resource *, size_t, dma_addr_t *); +void *vme_alloc_consistent(struct vme_resource *, size_t, dma_addr_t *); void vme_free_consistent(struct vme_resource *, size_t, void *, dma_addr_t); size_t vme_get_size(struct vme_resource *); -struct vme_resource * vme_slave_request(struct device *, vme_address_t, vme_cycle_t); -int vme_slave_set (struct vme_resource *, int, unsigned long long, +struct vme_resource *vme_slave_request(struct device *, vme_address_t, + vme_cycle_t); +int vme_slave_set(struct vme_resource *, int, unsigned long long, unsigned long long, dma_addr_t, vme_address_t, vme_cycle_t); -int vme_slave_get (struct vme_resource *, int *, unsigned long long *, +int vme_slave_get(struct vme_resource *, int *, unsigned long long *, unsigned long long *, dma_addr_t *, vme_address_t *, vme_cycle_t *); void vme_slave_free(struct vme_resource *); -struct vme_resource * vme_master_request(struct device *, vme_address_t, vme_cycle_t, - vme_width_t); -int vme_master_set (struct vme_resource *, int, unsigned long long, +struct vme_resource *vme_master_request(struct device *, vme_address_t, + vme_cycle_t, vme_width_t); +int vme_master_set(struct vme_resource *, int, unsigned long long, unsigned long long, vme_address_t, vme_cycle_t, vme_width_t); -int vme_master_get (struct vme_resource *, int *, unsigned long long *, +int vme_master_get(struct vme_resource *, int *, unsigned long long *, unsigned long long *, vme_address_t *, vme_cycle_t *, vme_width_t *); ssize_t vme_master_read(struct vme_resource *, void *, size_t, loff_t); ssize_t vme_master_write(struct vme_resource *, void *, size_t, loff_t); -unsigned int vme_master_rmw (struct vme_resource *, unsigned int, unsigned int, +unsigned int vme_master_rmw(struct vme_resource *, unsigned int, unsigned int, unsigned int, loff_t); void vme_master_free(struct vme_resource *); -struct vme_resource *vme_dma_request(struct device *); +struct vme_resource *vme_dma_request(struct device *, vme_dma_route_t); struct vme_dma_list *vme_new_dma_list(struct vme_resource *); struct vme_dma_attr *vme_dma_pattern_attribute(u32, vme_pattern_t); struct vme_dma_attr *vme_dma_pci_attribute(dma_addr_t); @@ -153,8 +162,8 @@ void vme_lm_free(struct vme_resource *); int vme_slot_get(struct device *); -int vme_register_driver (struct vme_driver *); -void vme_unregister_driver (struct vme_driver *); +int vme_register_driver(struct vme_driver *); +void vme_unregister_driver(struct vme_driver *); #endif /* _VME_H_ */ diff --git a/drivers/staging/vme/vme_api.txt b/drivers/staging/vme/vme_api.txt index a5c1b1c..a910a0c 100644 --- a/drivers/staging/vme/vme_api.txt +++ b/drivers/staging/vme/vme_api.txt @@ -77,16 +77,21 @@ driver in question: struct vme_resource * vme_slave_request(struct device *dev, vme_address_t aspace, vme_cycle_t cycle); - struct vme_resource *vme_dma_request(struct device *dev); + struct vme_resource *vme_dma_request(struct device *dev, + vme_dma_route_t route); For slave windows these attributes are split into those of type 'vme_address_t' -and 'vme_cycle_t'. Master windows add a further set of attributes 'vme_cycle_t'. -These attributes are defined as bitmasks and as such any combination of the -attributes can be requested for a single window, the core will assign a window -that meets the requirements, returning a pointer of type vme_resource that -should be used to identify the allocated resource when it is used. If an -unallocated window fitting the requirements can not be found a NULL pointer will -be returned. +and 'vme_cycle_t'. Master windows add a further set of attributes +'vme_cycle_t'. These attributes are defined as bitmasks and as such any +combination of the attributes can be requested for a single window, the core +will assign a window that meets the requirements, returning a pointer of type +vme_resource that should be used to identify the allocated resource when it is +used. For DMA controllers, the request function requires the potential +direction of any transfers to be provided in the route attributes. This is +typically VME-to-MEM and/or MEM-to-VME, though some hardware can support +VME-to-VME and MEM-to-MEM transfers as well as test pattern generation. If an +unallocated window fitting the requirements can not be found a NULL pointer +will be returned. Functions are also provided to free window allocations once they are no longer required. These functions should be passed the pointer to the resource provided @@ -237,6 +242,12 @@ covered under "Transfer Attributes"): struct vme_dma_attr *src, struct vme_dma_attr *dest, size_t count); +NOTE: The detailed attributes of the transfers source and destination + are not checked until an entry is added to a DMA list, the request + for a DMA channel purely checks the directions in which the + controller is expected to transfer data. As a result it is + possible for this call to return an error, for example if the + source or destination is in an unsupported VME address space. Transfer Attributes ------------------- diff --git a/drivers/staging/vme/vme_bridge.h b/drivers/staging/vme/vme_bridge.h index 851fa92..b653ec0 100644 --- a/drivers/staging/vme/vme_bridge.h +++ b/drivers/staging/vme/vme_bridge.h @@ -19,7 +19,7 @@ struct vme_master_resource { vme_address_t address_attr; vme_cycle_t cycle_attr; vme_width_t width_attr; - struct resource pci_resource; /* XXX Rename to be bus agnostic */ + struct resource bus_resource; void *kern_base; }; @@ -64,6 +64,7 @@ struct vme_dma_resource { int number; struct list_head pending; struct list_head running; + vme_dma_route_t route_attr; }; struct vme_lm_resource { @@ -101,7 +102,7 @@ struct vme_irq { * Currently we assume that all chips are PCI-based */ struct vme_bridge { - char name[VMENAMSIZ]; + char name[VMENAMSIZ]; int num; struct list_head master_resources; struct list_head slave_resources; @@ -112,7 +113,7 @@ struct vme_bridge { /* Bridge Info - XXX Move to private structure? */ struct device *parent; /* Generic device struct (pdev->dev for PCI) */ - void * base; /* Base Address of device registers */ + void *driver_priv; /* Private pointer for the bridge driver */ struct device dev[VME_SLOTS_MAX]; /* Device registered with * device model on VME bus @@ -151,8 +152,8 @@ struct vme_bridge { int (*dma_list_empty) (struct vme_dma_list *); /* Interrupt Functions */ - void (*irq_set) (int, int, int); - int (*irq_generate) (int, int); + void (*irq_set) (struct vme_bridge *, int, int, int); + int (*irq_generate) (struct vme_bridge *, int, int); /* Location monitor functions */ int (*lm_set) (struct vme_lm_resource *, unsigned long long, @@ -163,102 +164,12 @@ struct vme_bridge { int (*lm_detach) (struct vme_lm_resource *, int); /* CR/CSR space functions */ - int (*slot_get) (void); - /* Use standard master read and write functions to access CR/CSR */ - -#if 0 - int (*set_prefetch) (void); - int (*get_prefetch) (void); - int (*set_arbiter) (void); - int (*get_arbiter) (void); - int (*set_requestor) (void); - int (*get_requestor) (void); -#endif + int (*slot_get) (struct vme_bridge *); }; void vme_irq_handler(struct vme_bridge *, int, int); -int vme_register_bridge (struct vme_bridge *); -void vme_unregister_bridge (struct vme_bridge *); +int vme_register_bridge(struct vme_bridge *); +void vme_unregister_bridge(struct vme_bridge *); #endif /* _VME_BRIDGE_H_ */ - -#if 0 -/* - * VMEbus GET INFO Arg Structure - */ -struct vmeInfoCfg { - int vmeSlotNum; /* VME slot number of interest */ - int boardResponded; /* Board responded */ - char sysConFlag; /* System controller flag */ - int vmeControllerID; /* Vendor/device ID of VME bridge */ - int vmeControllerRev; /* Revision of VME bridge */ - char osName[8]; /* Name of OS e.g. "Linux" */ - int vmeSharedDataValid; /* Validity of data struct */ - int vmeDriverRev; /* Revision of VME driver */ - unsigned int vmeAddrHi[8]; /* Address on VME bus */ - unsigned int vmeAddrLo[8]; /* Address on VME bus */ - unsigned int vmeSize[8]; /* Size on VME bus */ - unsigned int vmeAm[8]; /* Address modifier on VME bus */ - int reserved; /* For future use */ -}; -typedef struct vmeInfoCfg vmeInfoCfg_t; - -/* - * VMEbus Requester Arg Structure - */ -struct vmeRequesterCfg { - int requestLevel; /* Requester Bus Request Level */ - char fairMode; /* Requester Fairness Mode Indicator */ - int releaseMode; /* Requester Bus Release Mode */ - int timeonTimeoutTimer; /* Master Time-on Time-out Timer */ - int timeoffTimeoutTimer; /* Master Time-off Time-out Timer */ - int reserved; /* For future use */ -}; -typedef struct vmeRequesterCfg vmeRequesterCfg_t; - -/* - * VMEbus Arbiter Arg Structure - */ -struct vmeArbiterCfg { - vme_arbitration_t arbiterMode; /* Arbitration Scheduling Algorithm */ - char arbiterTimeoutFlag; /* Arbiter Time-out Timer Indicator */ - int globalTimeoutTimer; /* VMEbus Global Time-out Timer */ - char noEarlyReleaseFlag; /* No Early Release on BBUSY */ - int reserved; /* For future use */ -}; -typedef struct vmeArbiterCfg vmeArbiterCfg_t; - - -/* - * VMEbus RMW Configuration Data - */ -struct vmeRmwCfg { - unsigned int targetAddrU; /* VME Address (Upper) to trigger RMW cycle */ - unsigned int targetAddr; /* VME Address (Lower) to trigger RMW cycle */ - vme_address_t addrSpace; /* VME Address Space */ - int enableMask; /* Bit mask defining the bits of interest */ - int compareData; /* Data to be compared with the data read */ - int swapData; /* Data written to the VMEbus on success */ - int maxAttempts; /* Maximum times to try */ - int numAttempts; /* Number of attempts before success */ - int reserved; /* For future use */ - -}; -typedef struct vmeRmwCfg vmeRmwCfg_t; - -/* - * VMEbus Location Monitor Arg Structure - */ -struct vmeLmCfg { - unsigned int addrU; /* Location Monitor Address upper */ - unsigned int addr; /* Location Monitor Address lower */ - vme_address_t addrSpace; /* Address Space */ - int userAccessType; /* User/Supervisor Access Type */ - int dataAccessType; /* Data/Program Access Type */ - int lmWait; /* Time to wait for access */ - int lmEvents; /* Lm event mask */ - int reserved; /* For future use */ -}; -typedef struct vmeLmCfg vmeLmCfg_t; -#endif diff --git a/drivers/staging/vt6655/card.c b/drivers/staging/vt6655/card.c index db78614..bf4fd49 100644 --- a/drivers/staging/vt6655/card.c +++ b/drivers/staging/vt6655/card.c @@ -2788,16 +2788,18 @@ void CARDvUpdateBasicTopRate (PVOID pDeviceHandler) //Determines the highest basic rate. for (ii = RATE_54M; ii >= RATE_6M; ii --) { - if ( (pDevice->wBasicRate) & ((WORD)(1<<ii)) ) + if ( (pDevice->wBasicRate) & ((WORD)(1<<ii)) ) { byTopOFDM = ii; break; + } } pDevice->byTopOFDMBasicRate = byTopOFDM; for (ii = RATE_11M;; ii --) { - if ( (pDevice->wBasicRate) & ((WORD)(1<<ii)) ) + if ( (pDevice->wBasicRate) & ((WORD)(1<<ii)) ) { byTopCCK = ii; break; + } if (ii == RATE_1M) break; } diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 0dadb76..1d64365 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -1105,10 +1105,7 @@ static void device_print_info(PSDevice pDevice) struct net_device* dev=pDevice->dev; DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "%s: %s\n",dev->name, get_chip_name(pDevice->chip_id)); - DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "%s: MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X", - dev->name, - dev->dev_addr[0],dev->dev_addr[1],dev->dev_addr[2], - dev->dev_addr[3],dev->dev_addr[4],dev->dev_addr[5]); + DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "%s: MAC=%pM", dev->name, dev->dev_addr); #ifdef IO_MAP DBG_PRT(MSG_LEVEL_INFO, KERN_INFO" IO=0x%lx ",(ULONG) pDevice->ioaddr); DBG_PRT(MSG_LEVEL_INFO, KERN_INFO" IRQ=%d \n", pDevice->dev->irq); diff --git a/drivers/staging/vt6655/iwctl.c b/drivers/staging/vt6655/iwctl.c index 108830f..78b4983 100644 --- a/drivers/staging/vt6655/iwctl.c +++ b/drivers/staging/vt6655/iwctl.c @@ -1472,7 +1472,7 @@ if((wrq->flags & IW_ENCODE_DISABLED)==0){ if ( index < 4 ) { pDevice->byKeyIndex = index; } - else if(!wrq->flags & IW_ENCODE_MODE) { + else if(!(wrq->flags & IW_ENCODE_MODE)) { rc = -EINVAL; return rc; } diff --git a/drivers/staging/winbond/core.h b/drivers/staging/winbond/core.h index 7d4bd5e..0a2060b 100644 --- a/drivers/staging/winbond/core.h +++ b/drivers/staging/winbond/core.h @@ -14,7 +14,7 @@ struct wbsoft_priv { u32 adapterIndex; // 20060703.4 Add for using padapterContext global adapter point - WB_LOCALDESCRIPT sLocalPara; // Myself connected parameters + struct wb_local_para sLocalPara; // Myself connected parameters MLME_FRAME sMlmeFrame; // connect to peerSTA parameters diff --git a/drivers/staging/winbond/localpara.h b/drivers/staging/winbond/localpara.h index 5626a76..fcf6a04 100644 --- a/drivers/staging/winbond/localpara.h +++ b/drivers/staging/winbond/localpara.h @@ -110,33 +110,20 @@ // 20061108 WPS IE buffer #define MAX_IE_APPEND_SIZE 256 + 4 // Due to [E id][Length][OUI][Data] may 257 bytes -typedef struct _EVENTLOG -{ - u16 Count; //Total count from start - u16 index; //Buffer index, 0 ~ 63 - u32 EventValue[64]; //BYTE 3~2 : count, BYTE 1 : Event, BYTE 0 : reason -} Event_Log, *pEvent_Log; - -typedef struct _ChanInfo +struct chan_info { u8 band; u8 ChanNo; -} ChanInfo, *pChanInfo; +}; -typedef struct _CHAN_LIST -{ - u16 Count; - ChanInfo Channel[50]; // 100B -} CHAN_LIST, *psCHAN_LIST; - -typedef struct _RadioOff +struct radio_off { u8 boHwRadioOff; u8 boSwRadioOff; -} RadioOff, *psRadioOff; +}; //=========================================================================== -typedef struct LOCAL_PARA +struct wb_local_para { u8 PermanentAddress[ MAC_ADDR_LENGTH + 2 ]; // read from EPROM, manufacture set for each NetCard u8 ThisMacAddress[ MAC_ADDR_LENGTH + 2 ]; // the driver will use actually. @@ -186,7 +173,7 @@ typedef struct LOCAL_PARA u16 ListenInterval; // The listen interval when SME invoking MLME_ // (Re)Associate_Request(). - RadioOff RadioOffStatus; + struct radio_off RadioOffStatus; u8 Reserved0[2]; u8 boMsRadioOff; // Ndis demands to be true when set Disassoc. OID and be false when set SSID OID. @@ -196,7 +183,7 @@ typedef struct LOCAL_PARA u8 RoamStatus; u8 reserved7[3]; - ChanInfo CurrentChan; //Current channel no. and channel band. It may be changed by scanning. + struct chan_info CurrentChan; //Current channel no. and channel band. It may be changed by scanning. u8 boHandover; // Roaming, Hnadover to other AP. u8 boCCAbusy; @@ -253,19 +240,16 @@ typedef struct LOCAL_PARA u32 _dot11WEPUndecryptableCount; u32 _dot11FrameDuplicateCount; - ChanInfo IbssChanSetting; // 2B. Start IBSS Channel setting by registry or WWU. + struct chan_info IbssChanSetting; // 2B. Start IBSS Channel setting by registry or WWU. u8 reserved_5[2]; //It may not be used after considering RF type, //region and modulation type. - CHAN_LIST sSupportChanList; // 86B. It will be obtained according to RF type and region u8 reserved_6[2]; //two variables are for wep key error detection added by ws 02/02/04 u32 bWepKeyError; u32 bToSelfPacketReceived; u32 WepKeyDetectTimerCount; - Event_Log EventLog; - u16 SignalLostTh; u16 SignalRoamTh; @@ -274,6 +258,6 @@ typedef struct LOCAL_PARA u16 IE_Append_size; u16 reserved_7; -} WB_LOCALDESCRIPT, *PWB_LOCALDESCRIPT; +}; #endif diff --git a/drivers/staging/winbond/mds_f.h b/drivers/staging/winbond/mds_f.h index ab1ea53..e09dd4b 100644 --- a/drivers/staging/winbond/mds_f.h +++ b/drivers/staging/winbond/mds_f.h @@ -11,9 +11,6 @@ void Mds_SendComplete( struct wbsoft_priv *adapter, PT02_DESCRIPTOR pT02 ); void Mds_MpduProcess( struct wbsoft_priv *adapter, struct wb35_descriptor *pRxDes ); extern void DataDmp(u8 *pdata, u32 len, u32 offset); -// For Asynchronous indicating. The routine collocates with USB. -void Mds_MsduProcess( struct wbsoft_priv *adapter, PRXLAYER1 pRxLayer1, u8 SlotIndex); - // For data frame sending 20060802 u16 MDS_GetPacketSize( struct wbsoft_priv *adapter ); void MDS_GetNextPacket( struct wbsoft_priv *adapter, struct wb35_descriptor *pDes ); diff --git a/drivers/staging/winbond/mds_s.h b/drivers/staging/winbond/mds_s.h index e8e13bd..217ff08 100644 --- a/drivers/staging/winbond/mds_s.h +++ b/drivers/staging/winbond/mds_s.h @@ -133,32 +133,4 @@ struct wb35_mds { }; -// -// Reveive Layer 1 Format. -//---------------------------- -typedef struct _RXLAYER1 -{ - u16 SequenceNumber; // The sequence number of the last received packet. - u16 BufferTotalSize; - - u32 InUsed; - u32 DecryptionMethod; // The desired defragment number of the next incoming packet. - - u8 DeFragmentNumber; - u8 FrameType; - u8 TypeEncapsulated; - u8 BufferNumber; - - u32 FirstFrameArrivedTime; - - u8 LastFrameType; // 20061004 for fix intel 3945 's bug - u8 RESERVED[3]; //@@ anson - - ///////////////////////////////////////////////////////////////////////////////////////////// - // For brand-new Rx system - u8 ReservedBuffer[ 2400 ];//If Buffer ID is reserved one, it must copy the data into this area - u8 *ReservedBufferPoint;// Point to the next availabe address of reserved buffer - -}RXLAYER1, * PRXLAYER1; - #endif diff --git a/drivers/staging/winbond/mlme_s.h b/drivers/staging/winbond/mlme_s.h index ea12684..1217a1c 100644 --- a/drivers/staging/winbond/mlme_s.h +++ b/drivers/staging/winbond/mlme_s.h @@ -165,14 +165,6 @@ typedef struct _AUTHREQ { } MLME_AUTHREQ_PARA, *psMLME_AUTHREQ_PARA; -struct _Reason_Code { - - u8 peerMACaddr[MAC_ADDR_LENGTH]; - u16 wReasonCode; -}; -typedef struct _Reason_Code MLME_DEAUTHREQ_PARA, *psMLME_DEAUTHREQ_PARA; -typedef struct _Reason_Code MLME_DISASSOCREQ_PARA, *psMLME_DISASSOCREQ_PARA; - typedef struct _ASSOCREQ { u8 PeerSTAAddr[MAC_ADDR_LENGTH]; u16 CapabilityInfo; diff --git a/drivers/staging/winbond/mto.h b/drivers/staging/winbond/mto.h index 4fe24b0..fb4781d 100644 --- a/drivers/staging/winbond/mto.h +++ b/drivers/staging/winbond/mto.h @@ -141,11 +141,6 @@ extern u16 MTO_Frag_Th_Tbl[]; #define MTO_DATA_RATE() MTO_Data_Rate_Tbl[MTO_RATE_LEVEL()] #define MTO_FRAG_TH() MTO_Frag_Th_Tbl[MTO_FRAG_TH_LEVEL()] -typedef struct { - u8 tx_rate; - u8 tx_retry_rate; -} TXRETRY_REC; - extern void MTO_Init(struct wbsoft_priv *); extern void MTO_PeriodicTimerExpired(struct wbsoft_priv *); extern void MTO_SetDTORateRange(struct wbsoft_priv *, u8 *, u8); diff --git a/drivers/staging/winbond/reg.c b/drivers/staging/winbond/reg.c index d915cbd..5f5048a 100644 --- a/drivers/staging/winbond/reg.c +++ b/drivers/staging/winbond/reg.c @@ -1823,12 +1823,12 @@ BBProcessor_initial( struct hw_data * pHwData ) reg->SQ3_filter[i] = 0x2f; // half of Bit 0 ~ 6 } -void set_tx_power_per_channel_max2829( struct hw_data * pHwData, ChanInfo Channel) +void set_tx_power_per_channel_max2829( struct hw_data * pHwData, struct chan_info Channel) { RFSynthesizer_SetPowerIndex( pHwData, 100 ); // 20060620.1 Modify } -void set_tx_power_per_channel_al2230( struct hw_data * pHwData, ChanInfo Channel ) +void set_tx_power_per_channel_al2230( struct hw_data * pHwData, struct chan_info Channel ) { u8 index = 100; @@ -1838,7 +1838,7 @@ void set_tx_power_per_channel_al2230( struct hw_data * pHwData, ChanInfo Chann RFSynthesizer_SetPowerIndex( pHwData, index ); } -void set_tx_power_per_channel_al7230( struct hw_data * pHwData, ChanInfo Channel) +void set_tx_power_per_channel_al7230( struct hw_data * pHwData, struct chan_info Channel) { u8 i, index = 100; @@ -1868,7 +1868,7 @@ void set_tx_power_per_channel_al7230( struct hw_data * pHwData, ChanInfo Chann RFSynthesizer_SetPowerIndex( pHwData, index ); } -void set_tx_power_per_channel_wb242( struct hw_data * pHwData, ChanInfo Channel) +void set_tx_power_per_channel_wb242( struct hw_data * pHwData, struct chan_info Channel) { u8 index = 100; @@ -1901,7 +1901,7 @@ void set_tx_power_per_channel_wb242( struct hw_data * pHwData, ChanInfo Channe // None. //============================================================================================================= void -RFSynthesizer_SwitchingChannel( struct hw_data * pHwData, ChanInfo Channel ) +RFSynthesizer_SwitchingChannel( struct hw_data * pHwData, struct chan_info Channel ) { struct wb35_reg *reg = &pHwData->reg; u32 pltmp[16]; // The 16 is the maximum capability of hardware diff --git a/drivers/staging/winbond/scan_s.h b/drivers/staging/winbond/scan_s.h index 775bb81..209717f5 100644 --- a/drivers/staging/winbond/scan_s.h +++ b/drivers/staging/winbond/scan_s.h @@ -35,7 +35,6 @@ typedef struct _SCAN_REQ_PARA //mandatory parameters for SCAN request { u32 ScanType; //passive/active scan - CHAN_LIST sChannelList; // 86B u8 reserved_1[2]; struct SSID_Element sSSID; // 34B. scan only for this SSID diff --git a/drivers/staging/winbond/sme_api.h b/drivers/staging/winbond/sme_api.h index 5498783..b589829 100644 --- a/drivers/staging/winbond/sme_api.h +++ b/drivers/staging/winbond/sme_api.h @@ -193,8 +193,6 @@ s8 sme_get_cwmin_value(void *pcore_data, u8 *cwmin); s8 sme_get_cwmax_value(void *pcore_data, u16 *cwmax); s8 sme_get_ms_radio_mode(void *pcore_data, u8 * pMsRadioOff); s8 sme_set_ms_radio_mode(void *pcore_data, u8 boMsRadioOff); -s8 sme_get_radio_mode(void *pcore_data, psRadioOff pRadioOffData); -s8 sme_set_radio_mode(void *pcore_data, RadioOff RadioOffData); void sme_get_tx_power_level(void *pcore_data, u32 *TxPower); u8 sme_set_tx_power_level(void *pcore_data, u32 TxPower); @@ -203,7 +201,7 @@ void sme_get_rx_antenna(void *pcore_data, u32 *RxAntenna); u8 sme_set_rx_antenna(void *pcore_data, u32 RxAntenna); void sme_get_tx_antenna(void *pcore_data, u32 *TxAntenna); s8 sme_set_tx_antenna(void *pcore_data, u32 TxAntenna); -s8 sme_set_IBSS_chan(void *pcore_data, ChanInfo chan); +s8 sme_set_IBSS_chan(void *pcore_data, struct chan_info chan); //20061108 WPS s8 sme_set_IE_append(void *pcore_data, u8 *buffer, u16 buf_len); diff --git a/drivers/staging/winbond/wb35reg_f.h b/drivers/staging/winbond/wb35reg_f.h index 30f5b5a..d352bce 100644 --- a/drivers/staging/winbond/wb35reg_f.h +++ b/drivers/staging/winbond/wb35reg_f.h @@ -14,7 +14,7 @@ void Dxx_initial( struct hw_data * pHwData ); void Mxx_initial( struct hw_data * pHwData ); void RFSynthesizer_initial( struct hw_data * pHwData ); //void RFSynthesizer_SwitchingChannel( struct hw_data * pHwData, s8 Channel ); -void RFSynthesizer_SwitchingChannel( struct hw_data * pHwData, ChanInfo Channel ); +void RFSynthesizer_SwitchingChannel( struct hw_data * pHwData, struct chan_info Channel ); void BBProcessor_initial( struct hw_data * pHwData ); void BBProcessor_RateChanging( struct hw_data * pHwData, u8 rate ); // 20060613.1 //void RF_RateChanging( struct hw_data * pHwData, u8 rate ); // 20060626.5.c Add diff --git a/drivers/staging/winbond/wbusb.c b/drivers/staging/winbond/wbusb.c index 067082a..3482eec 100644 --- a/drivers/staging/winbond/wbusb.c +++ b/drivers/staging/winbond/wbusb.c @@ -23,7 +23,7 @@ MODULE_DESCRIPTION("IS89C35 802.11bg WLAN USB Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION("0.1"); -static struct usb_device_id wb35_table[] __devinitdata = { +static const struct usb_device_id wb35_table[] __devinitconst = { { USB_DEVICE(0x0416, 0x0035) }, { USB_DEVICE(0x18E8, 0x6201) }, { USB_DEVICE(0x18E8, 0x6206) }, @@ -65,17 +65,17 @@ static void hal_set_beacon_period(struct hw_data *pHwData, u16 beacon_period) } static int wbsoft_add_interface(struct ieee80211_hw *dev, - struct ieee80211_if_init_conf *conf) + struct ieee80211_vif *vif) { struct wbsoft_priv *priv = dev->priv; - hal_set_beacon_period(&priv->sHwData, conf->vif->bss_conf.beacon_int); + hal_set_beacon_period(&priv->sHwData, vif->bss_conf.beacon_int); return 0; } static void wbsoft_remove_interface(struct ieee80211_hw *dev, - struct ieee80211_if_init_conf *conf) + struct ieee80211_vif *vif) { printk("wbsoft_remove interface called\n"); } @@ -92,13 +92,6 @@ static int wbsoft_get_stats(struct ieee80211_hw *hw, return 0; } -static int wbsoft_get_tx_stats(struct ieee80211_hw *hw, - struct ieee80211_tx_queue_stats *stats) -{ - printk(KERN_INFO "%s called\n", __func__); - return 0; -} - static u64 wbsoft_prepare_multicast(struct ieee80211_hw *hw, int mc_count, struct dev_addr_list *mc_list) { @@ -161,7 +154,7 @@ static void hal_set_radio_mode(struct hw_data *pHwData, unsigned char radio_off) } static void -hal_set_current_channel_ex(struct hw_data *pHwData, ChanInfo channel) +hal_set_current_channel_ex(struct hw_data *pHwData, struct chan_info channel) { struct wb35_reg *reg = &pHwData->reg; @@ -180,10 +173,10 @@ hal_set_current_channel_ex(struct hw_data *pHwData, ChanInfo channel) reg->M28_MacControl &= ~0xff; // Clean channel information field reg->M28_MacControl |= channel.ChanNo; Wb35Reg_WriteWithCallbackValue(pHwData, 0x0828, reg->M28_MacControl, - (s8 *) & channel, sizeof(ChanInfo)); + (s8 *) & channel, sizeof(struct chan_info)); } -static void hal_set_current_channel(struct hw_data *pHwData, ChanInfo channel) +static void hal_set_current_channel(struct hw_data *pHwData, struct chan_info channel) { hal_set_current_channel_ex(pHwData, channel); } @@ -253,7 +246,7 @@ static void hal_set_accept_beacon(struct hw_data *pHwData, u8 enable) static int wbsoft_config(struct ieee80211_hw *dev, u32 changed) { struct wbsoft_priv *priv = dev->priv; - ChanInfo ch; + struct chan_info ch; printk("wbsoft_config called\n"); @@ -287,7 +280,6 @@ static const struct ieee80211_ops wbsoft_ops = { .prepare_multicast = wbsoft_prepare_multicast, .configure_filter = wbsoft_configure_filter, .get_stats = wbsoft_get_stats, - .get_tx_stats = wbsoft_get_tx_stats, .get_tsf = wbsoft_get_tsf, }; diff --git a/drivers/staging/wlags49_h2/wl_main.c b/drivers/staging/wlags49_h2/wl_main.c index 16764a0..cf0c384 100644 --- a/drivers/staging/wlags49_h2/wl_main.c +++ b/drivers/staging/wlags49_h2/wl_main.c @@ -3792,7 +3792,7 @@ static int write_int(struct file *file, const char *buffer, unsigned long count, } if (count > 0 ) { proc_number[count] = 0; - nr = wl_atoi( proc_number ); + nr = simple_strtoul(proc_number , NULL, 0); *(unsigned int *)data = nr; if ( nr & 0x8000 ) { //;?kludgy but it is unclear to me were else to place this #if DBG diff --git a/drivers/staging/wlags49_h2/wl_netdev.c b/drivers/staging/wlags49_h2/wl_netdev.c index c33e225..fa082d9 100644 --- a/drivers/staging/wlags49_h2/wl_netdev.c +++ b/drivers/staging/wlags49_h2/wl_netdev.c @@ -360,7 +360,7 @@ int wl_open(struct net_device *dev) wl_lock( lp, &flags ); if( status != HCF_SUCCESS ) { - // Unsuccesfull, try reset of the card to recover + // Unsuccessful, try reset of the card to recover status = wl_reset( dev ); } diff --git a/drivers/staging/wlags49_h2/wl_pci.c b/drivers/staging/wlags49_h2/wl_pci.c index a3db111..01e4bec 100644 --- a/drivers/staging/wlags49_h2/wl_pci.c +++ b/drivers/staging/wlags49_h2/wl_pci.c @@ -81,7 +81,6 @@ #include <asm/system.h> #include <asm/io.h> #include <asm/irq.h> -#include <asm/system.h> #include <asm/bitops.h> #include <asm/uaccess.h> diff --git a/drivers/staging/wlags49_h2/wl_profile.c b/drivers/staging/wlags49_h2/wl_profile.c index 715f027..1e0c75f 100644 --- a/drivers/staging/wlags49_h2/wl_profile.c +++ b/drivers/staging/wlags49_h2/wl_profile.c @@ -383,15 +383,15 @@ void translate_option( char *buffer, struct wl_private *lp ) DbgInfo->DebugFlag |= DBG_DEFAULTS; } } else { - DbgInfo->DebugFlag = wl_atoi( value ); //;?DebugFlag; + DbgInfo->DebugFlag = simple_strtoul(value, NULL, 0); //;?DebugFlag; } - DbgInfo->DebugFlag = wl_atoi( value ); //;?Delete ASAP + DbgInfo->DebugFlag = simple_strtoul(value, NULL, 0); //;?Delete ASAP } #endif /* DBG */ if ( strcmp( key, PARM_NAME_AUTH_KEY_MGMT_SUITE ) == 0 ) { DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_AUTH_KEY_MGMT_SUITE, value ); - value_convert = wl_atoi( value ); + value_convert = simple_strtoul(value, NULL, 0); if (( value_convert >= PARM_MIN_AUTH_KEY_MGMT_SUITE ) || ( value_convert <= PARM_MAX_AUTH_KEY_MGMT_SUITE )) { lp->AuthKeyMgmtSuite = value_convert; } else { @@ -401,7 +401,7 @@ void translate_option( char *buffer, struct wl_private *lp ) else if ( strcmp( key, PARM_NAME_BRSC_2GHZ ) == 0 ) { DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_BRSC_2GHZ, value ); - value_convert = wl_atoi( value ); + value_convert = simple_strtoul(value, NULL, 0); if (( value_convert >= PARM_MIN_BRSC ) || ( value_convert <= PARM_MAX_BRSC )) { lp->brsc[0] = value_convert; } else { @@ -411,7 +411,7 @@ void translate_option( char *buffer, struct wl_private *lp ) else if ( strcmp( key, PARM_NAME_BRSC_5GHZ ) == 0 ) { DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_BRSC_5GHZ, value ); - value_convert = wl_atoi( value ); + value_convert = simple_strtoul(value, NULL, 0); if (( value_convert >= PARM_MIN_BRSC ) || ( value_convert <= PARM_MAX_BRSC )) { lp->brsc[1] = value_convert; } else { @@ -448,7 +448,7 @@ void translate_option( char *buffer, struct wl_private *lp ) else if ( strcmp( key, PARM_NAME_ENABLE_ENCRYPTION ) == 0 ) { DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_ENABLE_ENCRYPTION, value ); - value_convert = wl_atoi( value ); + value_convert = simple_strtoul(value, NULL, 0); if (( value_convert >= PARM_MIN_ENABLE_ENCRYPTION ) && ( value_convert <= PARM_MAX_ENABLE_ENCRYPTION )) { lp->EnableEncryption = value_convert; } else { @@ -529,7 +529,7 @@ void translate_option( char *buffer, struct wl_private *lp ) else if ( strcmp( key, PARM_NAME_MULTICAST_RATE ) == 0 ) { DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_MULTICAST_RATE, value ); - value_convert = wl_atoi( value ); + value_convert = simple_strtoul(value, NULL, 0); if (( value_convert >= PARM_MIN_MULTICAST_RATE ) && ( value_convert <= PARM_MAX_MULTICAST_RATE )) { lp->MulticastRate[0] = value_convert; @@ -540,7 +540,7 @@ void translate_option( char *buffer, struct wl_private *lp ) else if ( strcmp( key, PARM_NAME_OWN_CHANNEL ) == 0 ) { DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_CHANNEL, value ); - value_convert = wl_atoi( value ); + value_convert = simple_strtoul(value, NULL, 0); if ( wl_is_a_valid_chan( value_convert )) { if ( value_convert > 14 ) { value_convert = value_convert | 0x100; @@ -567,7 +567,7 @@ void translate_option( char *buffer, struct wl_private *lp ) else if ( strcmp( key, PARM_NAME_RTS_THRESHOLD ) == 0 ) { DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD, value ); - value_convert = wl_atoi( value ); + value_convert = simple_strtoul(value, NULL, 0); if (( value_convert >= PARM_MIN_RTS_THRESHOLD ) && ( value_convert <= PARM_MAX_RTS_THRESHOLD )) { lp->RTSThreshold = value_convert; } else { @@ -577,7 +577,7 @@ void translate_option( char *buffer, struct wl_private *lp ) else if ( strcmp( key, PARM_NAME_SRSC_2GHZ ) == 0 ) { DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_SRSC_2GHZ, value ); - value_convert = wl_atoi( value ); + value_convert = simple_strtoul(value, NULL, 0); if (( value_convert >= PARM_MIN_SRSC ) || ( value_convert <= PARM_MAX_SRSC )) { lp->srsc[0] = value_convert; } else { @@ -587,7 +587,7 @@ void translate_option( char *buffer, struct wl_private *lp ) else if ( strcmp( key, PARM_NAME_SRSC_5GHZ ) == 0 ) { DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_SRSC_5GHZ, value ); - value_convert = wl_atoi( value ); + value_convert = simple_strtoul(value, NULL, 0); if (( value_convert >= PARM_MIN_SRSC ) || ( value_convert <= PARM_MAX_SRSC )) { lp->srsc[1] = value_convert; } else { @@ -597,7 +597,7 @@ void translate_option( char *buffer, struct wl_private *lp ) else if ( strcmp( key, PARM_NAME_SYSTEM_SCALE ) == 0 ) { DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_SYSTEM_SCALE, value ); - value_convert = wl_atoi( value ); + value_convert = simple_strtoul(value, NULL, 0); if (( value_convert >= PARM_MIN_SYSTEM_SCALE ) && ( value_convert <= PARM_MAX_SYSTEM_SCALE )) { lp->DistanceBetweenAPs = value_convert; } else { @@ -607,9 +607,9 @@ void translate_option( char *buffer, struct wl_private *lp ) else if ( strcmp( key, PARM_NAME_TX_KEY ) == 0 ) { DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_KEY, value ); - value_convert = wl_atoi( value ); + value_convert = simple_strtoul(value, NULL, 0); if (( value_convert >= PARM_MIN_TX_KEY ) && ( value_convert <= PARM_MAX_TX_KEY )) { - lp->TransmitKeyID = wl_atoi( value ); + lp->TransmitKeyID = simple_strtoul(value, NULL, 0); } else { DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_KEY ); } @@ -617,7 +617,7 @@ void translate_option( char *buffer, struct wl_private *lp ) else if ( strcmp( key, PARM_NAME_TX_RATE ) == 0 ) { DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE, value ); - value_convert = wl_atoi( value ); + value_convert = simple_strtoul(value, NULL, 0); if (( value_convert >= PARM_MIN_TX_RATE ) && ( value_convert <= PARM_MAX_TX_RATE )) { lp->TxRateControl[0] = value_convert; } else { @@ -627,7 +627,7 @@ void translate_option( char *buffer, struct wl_private *lp ) else if ( strcmp( key, PARM_NAME_TX_POW_LEVEL ) == 0 ) { DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_POW_LEVEL, value ); - value_convert = wl_atoi( value ); + value_convert = simple_strtoul(value, NULL, 0); if (( value_convert >= PARM_MIN_TX_POW_LEVEL ) || ( value_convert <= PARM_MAX_TX_POW_LEVEL )) { lp->txPowLevel = value_convert; } else { @@ -645,7 +645,7 @@ void translate_option( char *buffer, struct wl_private *lp ) if ( strcmp( key, PARM_NAME_PORT_TYPE ) == 0 ) { DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_PORT_TYPE, value ); - value_convert = wl_atoi( value ); + value_convert = simple_strtoul(value, NULL, 0); if (( value_convert == PARM_MIN_PORT_TYPE ) || ( value_convert == PARM_MAX_PORT_TYPE )) { lp->PortType = value_convert; } else { @@ -654,7 +654,7 @@ void translate_option( char *buffer, struct wl_private *lp ) } else if ( strcmp( key, PARM_NAME_PM_ENABLED ) == 0 ) { DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_PM_ENABLED, value ); - value_convert = wl_atoi( value ); + value_convert = simple_strtoul(value, NULL, 0); /* ;? how about wl_main.c containing * VALID_PARAM( PARM_PM_ENABLED <= WVLAN_PM_STATE_STANDARD || * ( PARM_PM_ENABLED & 0x7FFF ) <= WVLAN_PM_STATE_STANDARD ); @@ -677,7 +677,7 @@ void translate_option( char *buffer, struct wl_private *lp ) else if ( strcmp( key, PARM_NAME_MAX_SLEEP ) == 0 ) { DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_MAX_SLEEP, value ); - value_convert = wl_atoi( value ); + value_convert = simple_strtoul(value, NULL, 0); if (( value_convert >= 0 ) && ( value_convert <= 65535 )) { lp->MaxSleepDuration = value_convert; } else { @@ -696,7 +696,7 @@ void translate_option( char *buffer, struct wl_private *lp ) else if ( strcmp( key, PARM_NAME_AUTHENTICATION ) == 0 ) { DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_AUTHENTICATION, value ); - value_convert = wl_atoi( value ); + value_convert = simple_strtoul(value, NULL, 0); if (( value_convert >= PARM_MIN_AUTHENTICATION ) && ( value_convert <= PARM_MAX_AUTHENTICATION )) { lp->authentication = value_convert; } else { @@ -706,7 +706,7 @@ void translate_option( char *buffer, struct wl_private *lp ) else if ( strcmp( key, PARM_NAME_OWN_ATIM_WINDOW ) == 0 ) { DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_ATIM_WINDOW, value ); - value_convert = wl_atoi( value ); + value_convert = simple_strtoul(value, NULL, 0); if (( value_convert >= PARM_MIN_OWN_ATIM_WINDOW ) && ( value_convert <= PARM_MAX_OWN_ATIM_WINDOW )) { lp->atimWindow = value_convert; } else { @@ -716,7 +716,7 @@ void translate_option( char *buffer, struct wl_private *lp ) else if ( strcmp( key, PARM_NAME_PM_HOLDOVER_DURATION ) == 0 ) { DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_PM_HOLDOVER_DURATION, value ); - value_convert = wl_atoi( value ); + value_convert = simple_strtoul(value, NULL, 0); if (( value_convert >= PARM_MIN_PM_HOLDOVER_DURATION ) && ( value_convert <= PARM_MAX_PM_HOLDOVER_DURATION )) { lp->holdoverDuration = value_convert; } else { @@ -730,7 +730,7 @@ void translate_option( char *buffer, struct wl_private *lp ) else if ( strcmp( key, PARM_NAME_CONNECTION_CONTROL ) == 0 ) { DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_CONNECTION_CONTROL, value ); - value_convert = wl_atoi( value ); + value_convert = simple_strtoul(value, NULL, 0); if (( value_convert >= PARM_MIN_CONNECTION_CONTROL ) && ( value_convert <= PARM_MAX_CONNECTION_CONTROL )) { lp->connectionControl = value_convert; } else { @@ -749,7 +749,7 @@ void translate_option( char *buffer, struct wl_private *lp ) if ( strcmp( key, PARM_NAME_OWN_DTIM_PERIOD ) == 0 ) { DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_DTIM_PERIOD, value ); - value_convert = wl_atoi( value ); + value_convert = simple_strtoul(value, NULL, 0); if ( value_convert >= PARM_MIN_OWN_DTIM_PERIOD ) { lp->DTIMPeriod = value_convert; } else { @@ -775,7 +775,7 @@ void translate_option( char *buffer, struct wl_private *lp ) else if ( strcmp( key, PARM_NAME_OWN_BEACON_INTERVAL ) == 0 ) { DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_BEACON_INTERVAL, value ); - value_convert = wl_atoi( value ); + value_convert = simple_strtoul(value, NULL, 0); if ( value_convert >= PARM_MIN_OWN_BEACON_INTERVAL ) { lp->ownBeaconInterval = value_convert; } else { @@ -785,7 +785,7 @@ void translate_option( char *buffer, struct wl_private *lp ) else if ( strcmp( key, PARM_NAME_COEXISTENCE ) == 0 ) { DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_COEXISTENCE, value ); - value_convert = wl_atoi( value ); + value_convert = simple_strtoul(value, NULL, 0); if ( value_convert >= PARM_MIN_COEXISTENCE ) { lp->coexistence = value_convert; } else { @@ -797,7 +797,7 @@ void translate_option( char *buffer, struct wl_private *lp ) else if ( strcmp( key, PARM_NAME_RTS_THRESHOLD1 ) == 0 ) { DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD1, value ); - value_convert = wl_atoi( value ); + value_convert = simple_strtoul(value, NULL, 0); if (( value_convert >= PARM_MIN_RTS_THRESHOLD ) && ( value_convert <= PARM_MAX_RTS_THRESHOLD )) { lp->wds_port[0].rtsThreshold = value_convert; } else { @@ -807,7 +807,7 @@ void translate_option( char *buffer, struct wl_private *lp ) else if ( strcmp( key, PARM_NAME_RTS_THRESHOLD2 ) == 0 ) { DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD2, value ); - value_convert = wl_atoi( value ); + value_convert = simple_strtoul(value, NULL, 0); if (( value_convert >= PARM_MIN_RTS_THRESHOLD ) && ( value_convert <= PARM_MAX_RTS_THRESHOLD )) { lp->wds_port[1].rtsThreshold = value_convert; } else { @@ -817,7 +817,7 @@ void translate_option( char *buffer, struct wl_private *lp ) else if ( strcmp( key, PARM_NAME_RTS_THRESHOLD3 ) == 0 ) { DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD3, value ); - value_convert = wl_atoi( value ); + value_convert = simple_strtoul(value, NULL, 0); if (( value_convert >= PARM_MIN_RTS_THRESHOLD ) && ( value_convert <= PARM_MAX_RTS_THRESHOLD )) { lp->wds_port[2].rtsThreshold = value_convert; } else { @@ -827,7 +827,7 @@ void translate_option( char *buffer, struct wl_private *lp ) else if ( strcmp( key, PARM_NAME_RTS_THRESHOLD4 ) == 0 ) { DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD4, value ); - value_convert = wl_atoi( value ); + value_convert = simple_strtoul(value, NULL, 0); if (( value_convert >= PARM_MIN_RTS_THRESHOLD ) && ( value_convert <= PARM_MAX_RTS_THRESHOLD )) { lp->wds_port[3].rtsThreshold = value_convert; } else { @@ -837,7 +837,7 @@ void translate_option( char *buffer, struct wl_private *lp ) else if ( strcmp( key, PARM_NAME_RTS_THRESHOLD5 ) == 0 ) { DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD5, value ); - value_convert = wl_atoi( value ); + value_convert = simple_strtoul(value, NULL, 0); if (( value_convert >= PARM_MIN_RTS_THRESHOLD ) && ( value_convert <= PARM_MAX_RTS_THRESHOLD )) { lp->wds_port[4].rtsThreshold = value_convert; } else { @@ -847,7 +847,7 @@ void translate_option( char *buffer, struct wl_private *lp ) else if ( strcmp( key, PARM_NAME_RTS_THRESHOLD6 ) == 0 ) { DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD6, value ); - value_convert = wl_atoi( value ); + value_convert = simple_strtoul(value, NULL, 0); if (( value_convert >= PARM_MIN_RTS_THRESHOLD ) && ( value_convert <= PARM_MAX_RTS_THRESHOLD )) { lp->wds_port[5].rtsThreshold = value_convert; } else { @@ -857,7 +857,7 @@ void translate_option( char *buffer, struct wl_private *lp ) else if ( strcmp( key, PARM_NAME_TX_RATE1 ) == 0 ) { DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE1, value ); - value_convert = wl_atoi( value ); + value_convert = simple_strtoul(value, NULL, 0); if (( value_convert >= PARM_MIN_TX_RATE ) && ( value_convert <= PARM_MAX_TX_RATE )) { lp->wds_port[0].txRateCntl = value_convert; } else { @@ -867,7 +867,7 @@ void translate_option( char *buffer, struct wl_private *lp ) else if ( strcmp( key, PARM_NAME_TX_RATE2 ) == 0 ) { DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE2, value ); - value_convert = wl_atoi( value ); + value_convert = simple_strtoul(value, NULL, 0); if (( value_convert >= PARM_MIN_TX_RATE ) && ( value_convert <= PARM_MAX_TX_RATE )) { lp->wds_port[1].txRateCntl = value_convert; } else { @@ -877,7 +877,7 @@ void translate_option( char *buffer, struct wl_private *lp ) else if ( strcmp( key, PARM_NAME_TX_RATE3 ) == 0 ) { DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE3, value ); - value_convert = wl_atoi( value ); + value_convert = simple_strtoul(value, NULL, 0); if (( value_convert >= PARM_MIN_TX_RATE ) && ( value_convert <= PARM_MAX_TX_RATE )) { lp->wds_port[2].txRateCntl = value_convert; } else { @@ -887,7 +887,7 @@ void translate_option( char *buffer, struct wl_private *lp ) else if ( strcmp( key, PARM_NAME_TX_RATE4 ) == 0 ) { DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE4, value ); - value_convert = wl_atoi( value ); + value_convert = simple_strtoul(value, NULL, 0); if (( value_convert >= PARM_MIN_TX_RATE ) && ( value_convert <= PARM_MAX_TX_RATE )) { lp->wds_port[3].txRateCntl = value_convert; } else { @@ -897,7 +897,7 @@ void translate_option( char *buffer, struct wl_private *lp ) else if ( strcmp( key, PARM_NAME_TX_RATE5 ) == 0 ) { DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE5, value ); - value_convert = wl_atoi( value ); + value_convert = simple_strtoul(value, NULL, 0); if (( value_convert >= PARM_MIN_TX_RATE ) && ( value_convert <= PARM_MAX_TX_RATE )) { lp->wds_port[4].txRateCntl = value_convert; } else { @@ -907,7 +907,7 @@ void translate_option( char *buffer, struct wl_private *lp ) else if ( strcmp( key, PARM_NAME_TX_RATE6 ) == 0 ) { DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE6, value ); - value_convert = wl_atoi( value ); + value_convert = simple_strtoul(value, NULL, 0); if (( value_convert >= PARM_MIN_TX_RATE ) && ( value_convert <= PARM_MAX_TX_RATE )) { lp->wds_port[5].txRateCntl = value_convert; } else { diff --git a/drivers/staging/wlags49_h2/wl_util.c b/drivers/staging/wlags49_h2/wl_util.c index ac1e7f3..bbdb997 100644 --- a/drivers/staging/wlags49_h2/wl_util.c +++ b/drivers/staging/wlags49_h2/wl_util.c @@ -1536,52 +1536,3 @@ int wl_get_tallies(struct wl_private *lp, return ret; } -/******************************************************************************* - * wl_atoi() - ******************************************************************************* - * - * DESCRIPTION: - * - * Believe it or not, we need our own implementation of atoi in the kernel. - * - * PARAMETERS: - * - * string - the ASCII string to convert to an integer - * - * RETURNS: - * - * unsigned integer - * - ******************************************************************************/ -unsigned int wl_atoi( char *string ) -{ -unsigned int base = 10; //default to decimal -unsigned int value = 0; -unsigned int c; -int i = strlen( string ); - - if ( i > 2 && string[0] == '0' && ( string[1] | ('X'^'x') ) == 'x' ) { - base = 16; - string +=2; - } - while ( ( c = *string++ ) != '\0' ) { - if ( value > UINT_MAX / base ) { //test for overrun - DBG_FUNC( "wl_atoi" ); //don't overload the log file with good messages - DBG_ENTER( DbgInfo ); - DBG_ERROR( DbgInfo, "string \"%s\", lenght exceeds expectations\n", string ); - printk( "<1>string \"%s\", lenght exceeds expectations\n", string ); - DBG_LEAVE( DbgInfo ); - break; - } - c -= '0'; - if ( 0 <= c && c <= 9 ) value = base * value + c; - else if ( base == 16 ) { - c += '0'; - c |= 'A'^'a'; - c = c - 'a'+ 10; - if ( 10 <= c && c <= 15 ) value = base * value + c; - } - } - return value; -} // wl_atoi - diff --git a/drivers/staging/wlags49_h2/wl_util.h b/drivers/staging/wlags49_h2/wl_util.h index 16cd6c5..561e85b 100644 --- a/drivers/staging/wlags49_h2/wl_util.h +++ b/drivers/staging/wlags49_h2/wl_util.h @@ -100,6 +100,4 @@ void wl_process_updated_record( struct wl_private *lp ); void wl_process_assoc_status( struct wl_private *lp ); void wl_process_security_status( struct wl_private *lp ); -unsigned int wl_atoi( char *string ); - #endif // __WL_UTIL_H__ diff --git a/drivers/staging/wlan-ng/Kconfig b/drivers/staging/wlan-ng/Kconfig index f44294b..82fcc16 100644 --- a/drivers/staging/wlan-ng/Kconfig +++ b/drivers/staging/wlan-ng/Kconfig @@ -1,6 +1,8 @@ config PRISM2_USB tristate "Prism2.5/3 USB driver" - depends on WLAN && USB && WIRELESS_EXT + depends on WLAN && USB + select WIRELESS_EXT + select WEXT_PRIV default n ---help--- This is the wlan-ng prism 2.5/3 USB driver for a wide range of diff --git a/drivers/staging/wlan-ng/hfa384x.h b/drivers/staging/wlan-ng/hfa384x.h index 46cce81..1fa42e0 100644 --- a/drivers/staging/wlan-ng/hfa384x.h +++ b/drivers/staging/wlan-ng/hfa384x.h @@ -61,17 +61,17 @@ #include <linux/if_ether.h> /*--- Mins & Maxs -----------------------------------*/ -#define HFA384x_PORTID_MAX ((u16)7) -#define HFA384x_NUMPORTS_MAX ((u16)(HFA384x_PORTID_MAX+1)) -#define HFA384x_PDR_LEN_MAX ((u16)512) /* in bytes, from EK */ -#define HFA384x_PDA_RECS_MAX ((u16)200) /* a guess */ -#define HFA384x_PDA_LEN_MAX ((u16)1024) /* in bytes, from EK */ -#define HFA384x_SCANRESULT_MAX ((u16)31) -#define HFA384x_HSCANRESULT_MAX ((u16)31) -#define HFA384x_CHINFORESULT_MAX ((u16)16) -#define HFA384x_RID_GUESSING_MAXLEN 2048 /* I'm not really sure */ -#define HFA384x_RIDDATA_MAXLEN HFA384x_RID_GUESSING_MAXLEN -#define HFA384x_USB_RWMEM_MAXLEN 2048 +#define HFA384x_PORTID_MAX ((u16)7) +#define HFA384x_NUMPORTS_MAX ((u16)(HFA384x_PORTID_MAX+1)) +#define HFA384x_PDR_LEN_MAX ((u16)512) /* in bytes, from EK */ +#define HFA384x_PDA_RECS_MAX ((u16)200) /* a guess */ +#define HFA384x_PDA_LEN_MAX ((u16)1024) /* in bytes, from EK*/ +#define HFA384x_SCANRESULT_MAX ((u16)31) +#define HFA384x_HSCANRESULT_MAX ((u16)31) +#define HFA384x_CHINFORESULT_MAX ((u16)16) +#define HFA384x_RID_GUESSING_MAXLEN 2048 /* I'm not really sure */ +#define HFA384x_RIDDATA_MAXLEN HFA384x_RID_GUESSING_MAXLEN +#define HFA384x_USB_RWMEM_MAXLEN 2048 /*--- Support Constants -----------------------------*/ #define HFA384x_PORTTYPE_IBSS ((u16)0) @@ -115,8 +115,8 @@ /* Make a 32-bit flat address from AUX format 16-bit page and offset */ #define HFA384x_ADDR_AUX_MKFLAT(p, o) \ - (((u32)(((u16)(p))&HFA384x_ADDR_AUX_PAGE_MASK)) << 7) | \ - ((u32)(((u16)(o))&HFA384x_ADDR_AUX_OFF_MASK)) + ((((u32)(((u16)(p))&HFA384x_ADDR_AUX_PAGE_MASK)) << 7) | \ + ((u32)(((u16)(o))&HFA384x_ADDR_AUX_OFF_MASK))) /* Make CMD format offset and page from a 32-bit flat address */ #define HFA384x_ADDR_CMD_MKPAGE(f) \ @@ -135,12 +135,21 @@ #define HFA384x_DLSTATE_FLASHENABLED 2 /*--- Register Field Masks --------------------------*/ -#define HFA384x_CMD_AINFO ((u16)(BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10) | BIT(9) | BIT(8))) -#define HFA384x_CMD_MACPORT ((u16)(BIT(10) | BIT(9) | BIT(8))) +#define HFA384x_CMD_AINFO ((u16)(BIT(14) | BIT(13) \ + | BIT(12) | BIT(11) \ + | BIT(10) | BIT(9) \ + | BIT(8))) +#define HFA384x_CMD_MACPORT ((u16)(BIT(10) | BIT(9) | \ + BIT(8))) #define HFA384x_CMD_PROGMODE ((u16)(BIT(9) | BIT(8))) -#define HFA384x_CMD_CMDCODE ((u16)(BIT(5) | BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0))) +#define HFA384x_CMD_CMDCODE ((u16)(BIT(5) | BIT(4) | \ + BIT(3) | BIT(2) | \ + BIT(1) | BIT(0))) -#define HFA384x_STATUS_RESULT ((u16)(BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10) | BIT(9) | BIT(8))) +#define HFA384x_STATUS_RESULT ((u16)(BIT(14) | BIT(13) \ + | BIT(12) | BIT(11) \ + | BIT(10) | BIT(9) \ + | BIT(8))) /*--- Command Code Constants --------------------------*/ /*--- Controller Commands --------------------------*/ @@ -244,8 +253,10 @@ Information RID Lengths: MAC Information This is the length of JUST the DATA part of the RID (does not include the len or code fields) --------------------------------------------------------------------*/ -#define HFA384x_RID_DBMCOMMSQUALITY_LEN ((u16)sizeof(hfa384x_dbmcommsquality_t)) -#define HFA384x_RID_JOINREQUEST_LEN ((u16)sizeof(hfa384x_JoinRequest_data_t)) +#define HFA384x_RID_DBMCOMMSQUALITY_LEN \ + ((u16) sizeof(hfa384x_dbmcommsquality_t)) +#define HFA384x_RID_JOINREQUEST_LEN \ + ((u16)sizeof(hfa384x_JoinRequest_data_t)) /*-------------------------------------------------------------------- Information RIDs: Modem Information @@ -322,9 +333,11 @@ PD Record codes /*--- Register Test/Get/Set Field macros ------------------------*/ -#define HFA384x_CMD_AINFO_SET(value) ((u16)((u16)(value) << 8)) -#define HFA384x_CMD_MACPORT_SET(value) ((u16)HFA384x_CMD_AINFO_SET(value)) -#define HFA384x_CMD_PROGMODE_SET(value) ((u16)HFA384x_CMD_AINFO_SET((u16)value)) +#define HFA384x_CMD_AINFO_SET(value) ((u16)((u16)(value) << 8)) +#define HFA384x_CMD_MACPORT_SET(value) \ + ((u16)HFA384x_CMD_AINFO_SET(value)) +#define HFA384x_CMD_PROGMODE_SET(value) \ + ((u16)HFA384x_CMD_AINFO_SET((u16)value)) #define HFA384x_CMD_CMDCODE_SET(value) ((u16)(value)) #define HFA384x_STATUS_RESULT_SET(value) (((u16)(value)) << 8) @@ -402,7 +415,7 @@ typedef struct hfa384x_authenticateStation_data { /*-- Configuration Record: WPAData (data portion only) --*/ typedef struct hfa384x_WPAData { u16 datalen; - u8 data[0]; // max 80 + u8 data[0]; /* max 80 */ } __attribute__ ((packed)) hfa384x_WPAData_t; /*-------------------------------------------------------------------- @@ -479,7 +492,8 @@ Communication Frames: Field Masks for Transmit Frames #define HFA384x_TXSTATUS_AGEDERR ((u16)BIT(1)) #define HFA384x_TXSTATUS_RETRYERR ((u16)BIT(0)) /*-- Transmit Control Field --*/ -#define HFA384x_TX_MACPORT ((u16)(BIT(10) | BIT(9) | BIT(8))) +#define HFA384x_TX_MACPORT ((u16)(BIT(10) | \ + BIT(9) | BIT(8))) #define HFA384x_TX_STRUCTYPE ((u16)(BIT(4) | BIT(3))) #define HFA384x_TX_TXEX ((u16)BIT(2)) #define HFA384x_TX_TXOK ((u16)BIT(1)) @@ -496,7 +510,8 @@ Communication Frames: Test/Get/Set Field Values for Transmit Frames #define HFA384x_TX_SET(v, m, s) ((((u16)(v))<<((u16)(s)))&((u16)(m))) #define HFA384x_TX_MACPORT_SET(v) HFA384x_TX_SET(v, HFA384x_TX_MACPORT, 8) -#define HFA384x_TX_STRUCTYPE_SET(v) HFA384x_TX_SET(v, HFA384x_TX_STRUCTYPE, 3) +#define HFA384x_TX_STRUCTYPE_SET(v) HFA384x_TX_SET(v, \ + HFA384x_TX_STRUCTYPE, 3) #define HFA384x_TX_TXEX_SET(v) HFA384x_TX_SET(v, HFA384x_TX_TXEX, 2) #define HFA384x_TX_TXOK_SET(v) HFA384x_TX_SET(v, HFA384x_TX_TXOK, 1) /*-------------------------------------------------------------------- @@ -534,13 +549,17 @@ Communication Frames: Field Masks for Receive Frames --------------------------------------------------------------------*/ /*-- Status Fields --*/ -#define HFA384x_RXSTATUS_MACPORT ((u16)(BIT(10) | BIT(9) | BIT(8))) +#define HFA384x_RXSTATUS_MACPORT ((u16)(BIT(10) | \ + BIT(9) | \ + BIT(8))) #define HFA384x_RXSTATUS_FCSERR ((u16)BIT(0)) /*-------------------------------------------------------------------- Communication Frames: Test/Get/Set Field Values for Receive Frames --------------------------------------------------------------------*/ -#define HFA384x_RXSTATUS_MACPORT_GET(value) ((u16)((((u16)(value)) & HFA384x_RXSTATUS_MACPORT) >> 8)) -#define HFA384x_RXSTATUS_ISFCSERR(value) ((u16)(((u16)(value)) & HFA384x_RXSTATUS_FCSERR)) +#define HFA384x_RXSTATUS_MACPORT_GET(value) ((u16)((((u16)(value)) \ + & HFA384x_RXSTATUS_MACPORT) >> 8)) +#define HFA384x_RXSTATUS_ISFCSERR(value) ((u16)(((u16)(value)) \ + & HFA384x_RXSTATUS_FCSERR)) /*-------------------------------------------------------------------- FRAME STRUCTURES: Information Types and Information Frame Structures ---------------------------------------------------------------------- @@ -1133,7 +1152,7 @@ struct hfa384x; typedef void (*ctlx_cmdcb_t) (struct hfa384x *, const struct hfa384x_usbctlx *); -typedef void (*ctlx_usercb_t) (struct hfa384x * hw, +typedef void (*ctlx_usercb_t) (struct hfa384x *hw, void *ctlxresult, void *usercb_data); typedef struct hfa384x_usbctlx { @@ -1174,14 +1193,14 @@ typedef struct hfa484x_metacmd { } hfa384x_metacmd_t; #define MAX_GRP_ADDR 32 -#define WLAN_COMMENT_MAX 80 /* Max. length of user comment string. */ +#define WLAN_COMMENT_MAX 80 /* Max. length of user comment string. */ -#define WLAN_AUTH_MAX 60 /* Max. # of authenticated stations. */ -#define WLAN_ACCESS_MAX 60 /* Max. # of stations in an access list. */ -#define WLAN_ACCESS_NONE 0 /* No stations may be authenticated. */ -#define WLAN_ACCESS_ALL 1 /* All stations may be authenticated. */ -#define WLAN_ACCESS_ALLOW 2 /* Authenticate only "allowed" stations. */ -#define WLAN_ACCESS_DENY 3 /* Do not authenticate "denied" stations. */ +#define WLAN_AUTH_MAX 60 /* Max. # of authenticated stations. */ +#define WLAN_ACCESS_MAX 60 /* Max. # of stations in an access list. */ +#define WLAN_ACCESS_NONE 0 /* No stations may be authenticated. */ +#define WLAN_ACCESS_ALL 1 /* All stations may be authenticated. */ +#define WLAN_ACCESS_ALLOW 2 /* Authenticate only "allowed" stations. */ +#define WLAN_ACCESS_DENY 3 /* Do not authenticate "denied" stations. */ /* XXX These are going away ASAP */ typedef struct prism2sta_authlist { @@ -1294,10 +1313,23 @@ typedef struct hfa384x { hfa384x_caplevel_t cap_sup_ap; /* Actor compatibility ranges */ - hfa384x_caplevel_t cap_act_pri_cfi; /* pri f/w to controller interface */ - hfa384x_caplevel_t cap_act_sta_cfi; /* sta f/w to controller interface */ + hfa384x_caplevel_t cap_act_pri_cfi; /* + * pri f/w to controller + * interface + */ + + hfa384x_caplevel_t cap_act_sta_cfi; /* + * sta f/w to controller + * interface + */ + hfa384x_caplevel_t cap_act_sta_mfi; /* sta f/w to modem interface */ - hfa384x_caplevel_t cap_act_ap_cfi; /* ap f/w to controller interface */ + + hfa384x_caplevel_t cap_act_ap_cfi; /* + * ap f/w to controller + * interface + */ + hfa384x_caplevel_t cap_act_ap_mfi; /* ap f/w to modem interface */ u32 psusercount; /* Power save user count. */ @@ -1320,25 +1352,25 @@ typedef struct hfa384x { } hfa384x_t; -void hfa384x_create(hfa384x_t * hw, struct usb_device *usb); -void hfa384x_destroy(hfa384x_t * hw); +void hfa384x_create(hfa384x_t *hw, struct usb_device *usb); +void hfa384x_destroy(hfa384x_t *hw); int -hfa384x_corereset(hfa384x_t * hw, int holdtime, int settletime, int genesis); -int hfa384x_drvr_commtallies(hfa384x_t * hw); -int hfa384x_drvr_disable(hfa384x_t * hw, u16 macport); -int hfa384x_drvr_enable(hfa384x_t * hw, u16 macport); -int hfa384x_drvr_flashdl_enable(hfa384x_t * hw); -int hfa384x_drvr_flashdl_disable(hfa384x_t * hw); -int hfa384x_drvr_flashdl_write(hfa384x_t * hw, u32 daddr, void *buf, u32 len); -int hfa384x_drvr_getconfig(hfa384x_t * hw, u16 rid, void *buf, u16 len); -int hfa384x_drvr_ramdl_enable(hfa384x_t * hw, u32 exeaddr); -int hfa384x_drvr_ramdl_disable(hfa384x_t * hw); -int hfa384x_drvr_ramdl_write(hfa384x_t * hw, u32 daddr, void *buf, u32 len); -int hfa384x_drvr_readpda(hfa384x_t * hw, void *buf, unsigned int len); -int hfa384x_drvr_setconfig(hfa384x_t * hw, u16 rid, void *buf, u16 len); - -static inline int hfa384x_drvr_getconfig16(hfa384x_t * hw, u16 rid, void *val) +hfa384x_corereset(hfa384x_t *hw, int holdtime, int settletime, int genesis); +int hfa384x_drvr_commtallies(hfa384x_t *hw); +int hfa384x_drvr_disable(hfa384x_t *hw, u16 macport); +int hfa384x_drvr_enable(hfa384x_t *hw, u16 macport); +int hfa384x_drvr_flashdl_enable(hfa384x_t *hw); +int hfa384x_drvr_flashdl_disable(hfa384x_t *hw); +int hfa384x_drvr_flashdl_write(hfa384x_t *hw, u32 daddr, void *buf, u32 len); +int hfa384x_drvr_getconfig(hfa384x_t *hw, u16 rid, void *buf, u16 len); +int hfa384x_drvr_ramdl_enable(hfa384x_t *hw, u32 exeaddr); +int hfa384x_drvr_ramdl_disable(hfa384x_t *hw); +int hfa384x_drvr_ramdl_write(hfa384x_t *hw, u32 daddr, void *buf, u32 len); +int hfa384x_drvr_readpda(hfa384x_t *hw, void *buf, unsigned int len); +int hfa384x_drvr_setconfig(hfa384x_t *hw, u16 rid, void *buf, u16 len); + +static inline int hfa384x_drvr_getconfig16(hfa384x_t *hw, u16 rid, void *val) { int result = 0; result = hfa384x_drvr_getconfig(hw, rid, val, sizeof(u16)); @@ -1347,46 +1379,46 @@ static inline int hfa384x_drvr_getconfig16(hfa384x_t * hw, u16 rid, void *val) return result; } -static inline int hfa384x_drvr_setconfig16(hfa384x_t * hw, u16 rid, u16 val) +static inline int hfa384x_drvr_setconfig16(hfa384x_t *hw, u16 rid, u16 val) { u16 value = cpu_to_le16(val); return hfa384x_drvr_setconfig(hw, rid, &value, sizeof(value)); } int -hfa384x_drvr_getconfig_async(hfa384x_t * hw, +hfa384x_drvr_getconfig_async(hfa384x_t *hw, u16 rid, ctlx_usercb_t usercb, void *usercb_data); int -hfa384x_drvr_setconfig_async(hfa384x_t * hw, +hfa384x_drvr_setconfig_async(hfa384x_t *hw, u16 rid, void *buf, u16 len, ctlx_usercb_t usercb, void *usercb_data); static inline int -hfa384x_drvr_setconfig16_async(hfa384x_t * hw, u16 rid, u16 val) +hfa384x_drvr_setconfig16_async(hfa384x_t *hw, u16 rid, u16 val) { u16 value = cpu_to_le16(val); return hfa384x_drvr_setconfig_async(hw, rid, &value, sizeof(value), NULL, NULL); } -int hfa384x_drvr_start(hfa384x_t * hw); -int hfa384x_drvr_stop(hfa384x_t * hw); +int hfa384x_drvr_start(hfa384x_t *hw); +int hfa384x_drvr_stop(hfa384x_t *hw); int -hfa384x_drvr_txframe(hfa384x_t * hw, struct sk_buff *skb, - p80211_hdr_t * p80211_hdr, p80211_metawep_t * p80211_wep); -void hfa384x_tx_timeout(wlandevice_t * wlandev); - -int hfa384x_cmd_initialize(hfa384x_t * hw); -int hfa384x_cmd_enable(hfa384x_t * hw, u16 macport); -int hfa384x_cmd_disable(hfa384x_t * hw, u16 macport); -int hfa384x_cmd_allocate(hfa384x_t * hw, u16 len); -int hfa384x_cmd_monitor(hfa384x_t * hw, u16 enable); +hfa384x_drvr_txframe(hfa384x_t *hw, struct sk_buff *skb, + p80211_hdr_t *p80211_hdr, p80211_metawep_t *p80211_wep); +void hfa384x_tx_timeout(wlandevice_t *wlandev); + +int hfa384x_cmd_initialize(hfa384x_t *hw); +int hfa384x_cmd_enable(hfa384x_t *hw, u16 macport); +int hfa384x_cmd_disable(hfa384x_t *hw, u16 macport); +int hfa384x_cmd_allocate(hfa384x_t *hw, u16 len); +int hfa384x_cmd_monitor(hfa384x_t *hw, u16 enable); int -hfa384x_cmd_download(hfa384x_t * hw, +hfa384x_cmd_download(hfa384x_t *hw, u16 mode, u16 lowaddr, u16 highaddr, u16 codelen); -#endif /* __KERNEL__ */ +#endif /*__KERNEL__ */ -#endif /* _HFA384x_H */ +#endif /*_HFA384x_H */ diff --git a/drivers/staging/wlan-ng/hfa384x_usb.c b/drivers/staging/wlan-ng/hfa384x_usb.c index 925678b..5df56f0 100644 --- a/drivers/staging/wlan-ng/hfa384x_usb.c +++ b/drivers/staging/wlan-ng/hfa384x_usb.c @@ -52,7 +52,7 @@ * around the register accesses. The next higher level represents C-callable * prism2 API functions that match the Intersil documentation as closely * as is reasonable. The next higher layer implements common sequences -* of invokations of the API layer (e.g. write to bap, followed by cmd). +* of invocations of the API layer (e.g. write to bap, followed by cmd). * * Common sequences: * hfa384x_drvr_xxx Highest level abstractions provided by the @@ -118,15 +118,15 @@ #include <linux/wireless.h> #include <linux/netdevice.h> #include <linux/timer.h> -#include <asm/io.h> +#include <linux/io.h> #include <linux/delay.h> #include <asm/byteorder.h> -#include <asm/bitops.h> +#include <linux/bitops.h> #include <linux/list.h> #include <linux/usb.h> #include <linux/byteorder/generic.h> -#define SUBMIT_URB(u,f) usb_submit_urb(u,f) +#define SUBMIT_URB(u, f) usb_submit_urb(u, f) #include "p80211types.h" #include "p80211hdr.h" @@ -627,7 +627,7 @@ static hfa384x_usbctlx_t *usbctlx_alloc(void) { hfa384x_usbctlx_t *ctlx; - ctlx = kmalloc(sizeof(*ctlx), in_interrupt()? GFP_ATOMIC : GFP_KERNEL); + ctlx = kmalloc(sizeof(*ctlx), in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); if (ctlx != NULL) { memset(ctlx, 0, sizeof(*ctlx)); init_completion(&ctlx->done); @@ -675,7 +675,7 @@ struct usbctlx_cmd_completor { }; typedef struct usbctlx_cmd_completor usbctlx_cmd_completor_t; -static int usbctlx_cmd_completor_fn(usbctlx_completor_t * head) +static int usbctlx_cmd_completor_fn(usbctlx_completor_t *head) { usbctlx_cmd_completor_t *complete = (usbctlx_cmd_completor_t *) head; return usbctlx_get_status(complete->cmdresp, complete->result); @@ -1909,18 +1909,19 @@ int hfa384x_drvr_flashdl_enable(hfa384x_t *hw) return -EINVAL; /* Retrieve the buffer loc&size and timeout */ - if ((result = hfa384x_drvr_getconfig(hw, HFA384x_RID_DOWNLOADBUFFER, - &(hw->bufinfo), - sizeof(hw->bufinfo)))) { + result = hfa384x_drvr_getconfig(hw, HFA384x_RID_DOWNLOADBUFFER, + &(hw->bufinfo), sizeof(hw->bufinfo)); + if (result) return result; - } + hw->bufinfo.page = le16_to_cpu(hw->bufinfo.page); hw->bufinfo.offset = le16_to_cpu(hw->bufinfo.offset); hw->bufinfo.len = le16_to_cpu(hw->bufinfo.len); - if ((result = hfa384x_drvr_getconfig16(hw, HFA384x_RID_MAXLOADTIME, - &(hw->dltimeout)))) { + result = hfa384x_drvr_getconfig16(hw, HFA384x_RID_MAXLOADTIME, + &(hw->dltimeout)); + if (result) return result; - } + hw->dltimeout = le16_to_cpu(hw->dltimeout); pr_debug("flashdl_enable\n"); @@ -3071,9 +3072,9 @@ static void hfa384x_usbctlxq_run(hfa384x_t *hw) hfa384x_ctlxout_callback, hw); hw->ctlx_urb.transfer_flags |= USB_QUEUE_BULK; - /* Now submit the URB and update the CTLX's state - */ - if ((result = SUBMIT_URB(&hw->ctlx_urb, GFP_ATOMIC)) == 0) { + /* Now submit the URB and update the CTLX's state */ + result = SUBMIT_URB(&hw->ctlx_urb, GFP_ATOMIC); + if (result == 0) { /* This CTLX is now running on the active queue */ head->state = CTLX_REQ_SUBMITTED; @@ -3599,7 +3600,8 @@ static void hfa384x_int_rxmonitor(wlandevice_t *wlandev, skblen - sizeof(p80211_caphdr_t)); } - if ((skb = dev_alloc_skb(skblen)) == NULL) { + skb = dev_alloc_skb(skblen); + if (skb == NULL) { printk(KERN_ERR "alloc_skb failed trying to allocate %d bytes\n", skblen); @@ -3642,7 +3644,7 @@ static void hfa384x_int_rxmonitor(wlandevice_t *wlandev, /* check for unencrypted stuff if WEP bit set. */ if (*(datap - hdrlen + 1) & 0x40) /* wep set */ if ((*(datap) == 0xaa) && (*(datap + 1) == 0xaa)) - *(datap - hdrlen + 1) &= 0xbf; // clear wep; it's the 802.2 header! + *(datap - hdrlen + 1) &= 0xbf; /* clear wep; it's the 802.2 header! */ } if (hw->sniff_fcs) { @@ -3870,9 +3872,9 @@ retry: delresp: if (delete_resptimer) { - if ((timer_ok = del_timer(&hw->resptimer)) != 0) { + timer_ok = del_timer(&hw->resptimer); + if (timer_ok != 0) hw->resp_timer_done = 1; - } } spin_unlock_irqrestore(&hw->ctlxq.lock, flags); diff --git a/drivers/staging/wlan-ng/p80211conv.c b/drivers/staging/wlan-ng/p80211conv.c index 5952c67..a1605fb 100644 --- a/drivers/staging/wlan-ng/p80211conv.c +++ b/drivers/staging/wlan-ng/p80211conv.c @@ -206,12 +206,11 @@ int skb_ether_to_p80211(wlandevice_t *wlandev, u32 ethconv, /* XXXX need to pick keynum other than default? */ p80211_wep->data = kmalloc(skb->len, GFP_ATOMIC); - - if ((foo = wep_encrypt(wlandev, skb->data, p80211_wep->data, - skb->len, - (wlandev->hostwep & - HOSTWEP_DEFAULTKEY_MASK), - p80211_wep->iv, p80211_wep->icv))) { + foo = wep_encrypt(wlandev, skb->data, p80211_wep->data, + skb->len, + (wlandev->hostwep &HOSTWEP_DEFAULTKEY_MASK), + p80211_wep->iv, p80211_wep->icv); + if (foo) { printk(KERN_WARNING "Host en-WEP failed, dropping frame (%d).\n", foo); @@ -323,11 +322,12 @@ int skb_p80211_to_ether(wlandevice_t *wlandev, u32 ethconv, skb->len); return 1; } - if ((foo = wep_decrypt(wlandev, skb->data + payload_offset + 4, + foo = wep_decrypt(wlandev, skb->data + payload_offset + 4, payload_length - 8, -1, skb->data + payload_offset, skb->data + payload_offset + - payload_length - 4))) { + payload_length - 4); + if (foo) { /* de-wep failed, drop skb. */ pr_debug("Host de-WEP failed, dropping frame (%d).\n", foo); diff --git a/drivers/staging/wlan-ng/p80211conv.h b/drivers/staging/wlan-ng/p80211conv.h index 0c62df1..6fe163b 100644 --- a/drivers/staging/wlan-ng/p80211conv.h +++ b/drivers/staging/wlan-ng/p80211conv.h @@ -153,8 +153,8 @@ struct wlandevice; int skb_p80211_to_ether(struct wlandevice *wlandev, u32 ethconv, struct sk_buff *skb); int skb_ether_to_p80211(struct wlandevice *wlandev, u32 ethconv, - struct sk_buff *skb, p80211_hdr_t * p80211_hdr, - p80211_metawep_t * p80211_wep); + struct sk_buff *skb, p80211_hdr_t *p80211_hdr, + p80211_metawep_t *p80211_wep); int p80211_stt_findproto(u16 proto); diff --git a/drivers/staging/wlan-ng/p80211metadef.h b/drivers/staging/wlan-ng/p80211metadef.h index da8b6f5..0ccfba1 100644 --- a/drivers/staging/wlan-ng/p80211metadef.h +++ b/drivers/staging/wlan-ng/p80211metadef.h @@ -190,9 +190,9 @@ (P80211DID_MKSECTION(2) | \ P80211DID_MKGROUP(1)) #define DIDmib_dot11mac_dot11OperationTable_dot11MACAddress \ - (P80211DID_MKSECTION(2) | \ - P80211DID_MKGROUP(1) | \ - P80211DID_MKITEM(1) | 0x18000000) + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(1) | 0x18000000) #define DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold \ (P80211DID_MKSECTION(2) | \ P80211DID_MKGROUP(1) | \ @@ -210,18 +210,18 @@ P80211DID_MKGROUP(1) | \ P80211DID_MKITEM(5) | 0x18000000) #define DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime \ - (P80211DID_MKSECTION(2) | \ - P80211DID_MKGROUP(1) | \ - P80211DID_MKITEM(6) | 0x10000000) + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(6) | 0x10000000) #define DIDmib_cat_dot11phy \ P80211DID_MKSECTION(3) #define DIDmib_dot11phy_dot11PhyOperationTable \ (P80211DID_MKSECTION(3) | \ P80211DID_MKGROUP(1)) #define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel \ - (P80211DID_MKSECTION(3) | \ - P80211DID_MKGROUP(3) | \ - P80211DID_MKITEM(10) | 0x18000000) + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(10) | 0x18000000) #define DIDmib_dot11phy_dot11PhyDSSSTable \ (P80211DID_MKSECTION(3) | \ P80211DID_MKGROUP(5)) diff --git a/drivers/staging/wlan-ng/p80211mgmt.h b/drivers/staging/wlan-ng/p80211mgmt.h index 14cdc86..deb52f5 100644 --- a/drivers/staging/wlan-ng/p80211mgmt.h +++ b/drivers/staging/wlan-ng/p80211mgmt.h @@ -100,7 +100,7 @@ #ifndef _P80211MGMT_H #define _P80211MGMT_H -#ifndef _P80211HDR_H +#ifndef _P80211HDR_H #include "p80211hdr.h" #endif @@ -496,25 +496,25 @@ typedef struct wlan_fr_deauthen { } wlan_fr_deauthen_t; -void wlan_mgmt_encode_beacon(wlan_fr_beacon_t * f); -void wlan_mgmt_decode_beacon(wlan_fr_beacon_t * f); -void wlan_mgmt_encode_disassoc(wlan_fr_disassoc_t * f); -void wlan_mgmt_decode_disassoc(wlan_fr_disassoc_t * f); -void wlan_mgmt_encode_assocreq(wlan_fr_assocreq_t * f); -void wlan_mgmt_decode_assocreq(wlan_fr_assocreq_t * f); -void wlan_mgmt_encode_assocresp(wlan_fr_assocresp_t * f); -void wlan_mgmt_decode_assocresp(wlan_fr_assocresp_t * f); -void wlan_mgmt_encode_reassocreq(wlan_fr_reassocreq_t * f); -void wlan_mgmt_decode_reassocreq(wlan_fr_reassocreq_t * f); -void wlan_mgmt_encode_reassocresp(wlan_fr_reassocresp_t * f); -void wlan_mgmt_decode_reassocresp(wlan_fr_reassocresp_t * f); -void wlan_mgmt_encode_probereq(wlan_fr_probereq_t * f); -void wlan_mgmt_decode_probereq(wlan_fr_probereq_t * f); -void wlan_mgmt_encode_proberesp(wlan_fr_proberesp_t * f); -void wlan_mgmt_decode_proberesp(wlan_fr_proberesp_t * f); -void wlan_mgmt_encode_authen(wlan_fr_authen_t * f); -void wlan_mgmt_decode_authen(wlan_fr_authen_t * f); -void wlan_mgmt_encode_deauthen(wlan_fr_deauthen_t * f); -void wlan_mgmt_decode_deauthen(wlan_fr_deauthen_t * f); +void wlan_mgmt_encode_beacon(wlan_fr_beacon_t *f); +void wlan_mgmt_decode_beacon(wlan_fr_beacon_t *f); +void wlan_mgmt_encode_disassoc(wlan_fr_disassoc_t *f); +void wlan_mgmt_decode_disassoc(wlan_fr_disassoc_t *f); +void wlan_mgmt_encode_assocreq(wlan_fr_assocreq_t *f); +void wlan_mgmt_decode_assocreq(wlan_fr_assocreq_t *f); +void wlan_mgmt_encode_assocresp(wlan_fr_assocresp_t *f); +void wlan_mgmt_decode_assocresp(wlan_fr_assocresp_t *f); +void wlan_mgmt_encode_reassocreq(wlan_fr_reassocreq_t *f); +void wlan_mgmt_decode_reassocreq(wlan_fr_reassocreq_t *f); +void wlan_mgmt_encode_reassocresp(wlan_fr_reassocresp_t *f); +void wlan_mgmt_decode_reassocresp(wlan_fr_reassocresp_t *f); +void wlan_mgmt_encode_probereq(wlan_fr_probereq_t *f); +void wlan_mgmt_decode_probereq(wlan_fr_probereq_t *f); +void wlan_mgmt_encode_proberesp(wlan_fr_proberesp_t *f); +void wlan_mgmt_decode_proberesp(wlan_fr_proberesp_t *f); +void wlan_mgmt_encode_authen(wlan_fr_authen_t *f); +void wlan_mgmt_decode_authen(wlan_fr_authen_t *f); +void wlan_mgmt_encode_deauthen(wlan_fr_deauthen_t *f); +void wlan_mgmt_decode_deauthen(wlan_fr_deauthen_t *f); #endif /* _P80211MGMT_H */ diff --git a/drivers/staging/wlan-ng/p80211netdev.c b/drivers/staging/wlan-ng/p80211netdev.c index 22424c8..763ab11 100644 --- a/drivers/staging/wlan-ng/p80211netdev.c +++ b/drivers/staging/wlan-ng/p80211netdev.c @@ -586,7 +586,8 @@ static int p80211knetdev_do_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd) } /* Allocate a buf of size req->len */ - if ((msgbuf = kmalloc(req->len, GFP_KERNEL))) { + msgbuf = kmalloc(req->len, GFP_KERNEL); + if (msgbuf) { if (copy_from_user(msgbuf, (void __user *)req->data, req->len)) result = -EFAULT; else @@ -646,7 +647,7 @@ static int p80211knetdev_set_mac_address(netdevice_t *dev, void *addr) /* Set up some convenience pointers. */ mibattr = &dot11req.mibattribute; - macaddr = (p80211item_pstr6_t *) & mibattr->data; + macaddr = (p80211item_pstr6_t *) &mibattr->data; resultcode = &dot11req.resultcode; /* Set up a dot11req_mibset */ @@ -674,7 +675,7 @@ static int p80211knetdev_set_mac_address(netdevice_t *dev, void *addr) resultcode->data = 0; /* now fire the request */ - result = p80211req_dorequest(dev->ml_priv, (u8 *) & dot11req); + result = p80211req_dorequest(dev->ml_priv, (u8 *) &dot11req); /* If the request wasn't successful, report an error and don't * change the netdev address diff --git a/drivers/staging/wlan-ng/p80211netdev.h b/drivers/staging/wlan-ng/p80211netdev.h index 8bd9dfb..3c8c648 100644 --- a/drivers/staging/wlan-ng/p80211netdev.h +++ b/drivers/staging/wlan-ng/p80211netdev.h @@ -179,16 +179,16 @@ typedef struct wlandevice { unsigned int ethconv; /* device methods (init by MSD, used by p80211 */ - int (*open) (struct wlandevice * wlandev); - int (*close) (struct wlandevice * wlandev); - void (*reset) (struct wlandevice * wlandev); - int (*txframe) (struct wlandevice * wlandev, struct sk_buff * skb, - p80211_hdr_t * p80211_hdr, - p80211_metawep_t * p80211_wep); - int (*mlmerequest) (struct wlandevice * wlandev, p80211msg_t * msg); - int (*set_multicast_list) (struct wlandevice * wlandev, - netdevice_t * dev); - void (*tx_timeout) (struct wlandevice * wlandev); + int (*open) (struct wlandevice *wlandev); + int (*close) (struct wlandevice *wlandev); + void (*reset) (struct wlandevice *wlandev); + int (*txframe) (struct wlandevice *wlandev, struct sk_buff *skb, + p80211_hdr_t *p80211_hdr, + p80211_metawep_t *p80211_wep); + int (*mlmerequest) (struct wlandevice *wlandev, p80211msg_t *msg); + int (*set_multicast_list) (struct wlandevice *wlandev, + netdevice_t *dev); + void (*tx_timeout) (struct wlandevice *wlandev); /* 802.11 State */ u8 bssid[WLAN_BSSID_LEN]; @@ -227,16 +227,16 @@ typedef struct wlandevice { } wlandevice_t; /* WEP stuff */ -int wep_change_key(wlandevice_t * wlandev, int keynum, u8 * key, int keylen); -int wep_decrypt(wlandevice_t * wlandev, u8 * buf, u32 len, int key_override, - u8 * iv, u8 * icv); -int wep_encrypt(wlandevice_t * wlandev, u8 * buf, u8 * dst, u32 len, int keynum, - u8 * iv, u8 * icv); - -int wlan_setup(wlandevice_t * wlandev); -int wlan_unsetup(wlandevice_t * wlandev); -int register_wlandev(wlandevice_t * wlandev); -int unregister_wlandev(wlandevice_t * wlandev); -void p80211netdev_rx(wlandevice_t * wlandev, struct sk_buff *skb); -void p80211netdev_hwremoved(wlandevice_t * wlandev); +int wep_change_key(wlandevice_t *wlandev, int keynum, u8 *key, int keylen); +int wep_decrypt(wlandevice_t *wlandev, u8 *buf, u32 len, int key_override, + u8 *iv, u8 *icv); +int wep_encrypt(wlandevice_t *wlandev, u8 *buf, u8 *dst, u32 len, int keynum, + u8 *iv, u8 *icv); + +int wlan_setup(wlandevice_t *wlandev); +int wlan_unsetup(wlandevice_t *wlandev); +int register_wlandev(wlandevice_t *wlandev); +int unregister_wlandev(wlandevice_t *wlandev); +void p80211netdev_rx(wlandevice_t *wlandev, struct sk_buff *skb); +void p80211netdev_hwremoved(wlandevice_t *wlandev); #endif diff --git a/drivers/staging/wlan-ng/p80211req.c b/drivers/staging/wlan-ng/p80211req.c index c88156c..c2e95f1 100644 --- a/drivers/staging/wlan-ng/p80211req.c +++ b/drivers/staging/wlan-ng/p80211req.c @@ -94,7 +94,7 @@ static int p80211req_mibset_mibget(wlandevice_t *wlandev, * Potentially blocks the caller, so it's a good idea to * not call this function from an interrupt context. ----------------------------------------------------------------*/ -int p80211req_dorequest(wlandevice_t * wlandev, u8 * msgbuf) +int p80211req_dorequest(wlandevice_t *wlandev, u8 *msgbuf) { int result = 0; p80211msg_t *msg = (p80211msg_t *) msgbuf; diff --git a/drivers/staging/wlan-ng/p80211req.h b/drivers/staging/wlan-ng/p80211req.h index 5d91767..a95a45a 100644 --- a/drivers/staging/wlan-ng/p80211req.h +++ b/drivers/staging/wlan-ng/p80211req.h @@ -48,6 +48,6 @@ #ifndef _LINUX_P80211REQ_H #define _LINUX_P80211REQ_H -int p80211req_dorequest(wlandevice_t * wlandev, u8 * msgbuf); +int p80211req_dorequest(wlandevice_t *wlandev, u8 *msgbuf); #endif diff --git a/drivers/staging/wlan-ng/p80211types.h b/drivers/staging/wlan-ng/p80211types.h index 2b83ab0..41a99c5 100644 --- a/drivers/staging/wlan-ng/p80211types.h +++ b/drivers/staging/wlan-ng/p80211types.h @@ -168,12 +168,12 @@ P80211DID_MASK_ISTABLE, \ P80211DID_LSB_ISTABLE) -#define P80211DID_MKID(s,g,i,n,t,a) (P80211DID_MKSECTION(s) | \ - P80211DID_MKGROUP(g) | \ - P80211DID_MKITEM(i) | \ - P80211DID_MKINDEX(n) | \ - P80211DID_MKISTABLE(t) | \ - (a)) +#define P80211DID_MKID(s, g, i, n, t, a) (P80211DID_MKSECTION(s) | \ + P80211DID_MKGROUP(g) | \ + P80211DID_MKITEM(i) | \ + P80211DID_MKINDEX(n) | \ + P80211DID_MKISTABLE(t) | \ + (a)) #define P80211DID_GET(a, m, l) ((((u32)(a)) >> (l)) & (m)) @@ -340,11 +340,11 @@ struct catlistitem; /* metadata items. Some components may choose to use more, */ /* less or different metadata items. */ -typedef void (*p80211_totext_t) (struct catlistitem *, u32 did, u8 * itembuf, +typedef void (*p80211_totext_t) (struct catlistitem *, u32 did, u8 *itembuf, char *textbuf); -typedef void (*p80211_fromtext_t) (struct catlistitem *, u32 did, u8 * itembuf, +typedef void (*p80211_fromtext_t) (struct catlistitem *, u32 did, u8 *itembuf, char *textbuf); -typedef u32(*p80211_valid_t) (struct catlistitem *, u32 did, u8 * itembuf); +typedef u32(*p80211_valid_t) (struct catlistitem *, u32 did, u8 *itembuf); /*----------------------------------------------------------------*/ /* Enumeration Lists */ diff --git a/drivers/staging/wlan-ng/p80211wext.c b/drivers/staging/wlan-ng/p80211wext.c index 74d8022..2fa1dfa 100644 --- a/drivers/staging/wlan-ng/p80211wext.c +++ b/drivers/staging/wlan-ng/p80211wext.c @@ -46,8 +46,8 @@ #include <linux/wireless.h> #include <net/iw_handler.h> #include <linux/if_arp.h> -#include <asm/bitops.h> -#include <asm/uaccess.h> +#include <linux/bitops.h> +#include <linux/uaccess.h> #include <asm/byteorder.h> #include <linux/if_ether.h> #include <linux/bitops.h> @@ -134,10 +134,11 @@ static int p80211wext_dorequest(wlandevice_t *wlandev, u32 did, u32 data) int result; msg.msgcode = DIDmsg_dot11req_mibset; + memset(&mibitem, 0, sizeof(mibitem)); mibitem.did = did; mibitem.data = data; memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); - result = p80211req_dorequest(wlandev, (u8 *) & msg); + result = p80211req_dorequest(wlandev, (u8 *) &msg); return result; } @@ -174,7 +175,7 @@ static int p80211wext_autojoin(wlandevice_t *wlandev) memcpy(msg.ssid.data.data, ssid, data.length); msg.ssid.data.len = data.length; - result = p80211req_dorequest(wlandev, (u8 *) & msg); + result = p80211req_dorequest(wlandev, (u8 *) &msg); if (result) { err = -EFAULT; @@ -211,7 +212,7 @@ struct iw_statistics *p80211wext_get_wireless_stats(netdevice_t *dev) if (wlandev->mlmerequest == NULL) return NULL; - retval = wlandev->mlmerequest(wlandev, (p80211msg_t *) & quality); + retval = wlandev->mlmerequest(wlandev, (p80211msg_t *) &quality); wstats->qual.qual = qual_as_percent(quality.link.data); /* overall link quality */ wstats->qual.level = quality.level.data; /* instant signal level */ @@ -269,9 +270,10 @@ static int p80211wext_giwfreq(netdevice_t *dev, int err = 0; msg.msgcode = DIDmsg_dot11req_mibget; + memset(&mibitem, 0, sizeof(mibitem)); mibitem.did = DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel; memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); - result = p80211req_dorequest(wlandev, (u8 *) & msg); + result = p80211req_dorequest(wlandev, (u8 *) &msg); if (result) { err = -EFAULT; @@ -309,6 +311,7 @@ static int p80211wext_siwfreq(netdevice_t *dev, } msg.msgcode = DIDmsg_dot11req_mibset; + memset(&mibitem, 0, sizeof(mibitem)); mibitem.did = DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel; mibitem.status = P80211ENUM_msgitem_status_data_ok; @@ -318,7 +321,7 @@ static int p80211wext_siwfreq(netdevice_t *dev, mibitem.data = p80211_mhz_to_channel(freq->m); memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); - result = p80211req_dorequest(wlandev, (u8 *) & msg); + result = p80211req_dorequest(wlandev, (u8 *) &msg); if (result) { err = -EFAULT; @@ -396,10 +399,11 @@ static int p80211wext_siwmode(netdevice_t *dev, /* Set Operation mode to the PORT TYPE RID */ msg.msgcode = DIDmsg_dot11req_mibset; + memset(&mibitem, 0, sizeof(mibitem)); mibitem.did = DIDmib_p2_p2Static_p2CnfPortType; mibitem.data = (*mode == IW_MODE_ADHOC) ? 0 : 1; memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); - result = p80211req_dorequest(wlandev, (u8 *) & msg); + result = p80211req_dorequest(wlandev, (u8 *) &msg); if (result) err = -EFAULT; @@ -549,14 +553,14 @@ static int p80211wext_siwencode(netdevice_t *dev, } /* Check the Key index first. */ - if ((i = (erq->flags & IW_ENCODE_INDEX))) { - + i = (erq->flags & IW_ENCODE_INDEX); + if (i) { if ((i < 1) || (i > NUM_WEPKEYS)) { err = -EINVAL; goto exit; - } else + } else { i--; - + } /* Set current key number only if no keys are given */ if (erq->flags & IW_ENCODE_NOKEY) { result = @@ -621,7 +625,7 @@ static int p80211wext_siwencode(netdevice_t *dev, msg.msgcode = DIDmsg_dot11req_mibset; memcpy(&msg.mibattribute.data, &pstr, sizeof(pstr)); - result = p80211req_dorequest(wlandev, (u8 *) & msg); + result = p80211req_dorequest(wlandev, (u8 *) &msg); if (result) { err = -EFAULT; @@ -729,7 +733,7 @@ static int p80211wext_siwessid(netdevice_t *dev, msg.ssid.data.len = length; pr_debug("autojoin_ssid for %s \n", essid); - result = p80211req_dorequest(wlandev, (u8 *) & msg); + result = p80211req_dorequest(wlandev, (u8 *) &msg); pr_debug("autojoin_ssid %d\n", result); if (result) { @@ -771,9 +775,10 @@ static int p80211wext_giwrate(netdevice_t *dev, int err = 0; msg.msgcode = DIDmsg_dot11req_mibget; + memset(&mibitem, 0, sizeof(mibitem)); mibitem.did = DIDmib_p2_p2MAC_p2CurrentTxRate; memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); - result = p80211req_dorequest(wlandev, (u8 *) & msg); + result = p80211req_dorequest(wlandev, (u8 *) &msg); if (result) { err = -EFAULT; @@ -822,9 +827,10 @@ static int p80211wext_giwrts(netdevice_t *dev, int err = 0; msg.msgcode = DIDmsg_dot11req_mibget; + memset(&mibitem, 0, sizeof(mibitem)); mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold; memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); - result = p80211req_dorequest(wlandev, (u8 *) & msg); + result = p80211req_dorequest(wlandev, (u8 *) &msg); if (result) { err = -EFAULT; @@ -857,6 +863,7 @@ static int p80211wext_siwrts(netdevice_t *dev, } msg.msgcode = DIDmsg_dot11req_mibget; + memset(&mibitem, 0, sizeof(mibitem)); mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold; if (rts->disabled) mibitem.data = 2347; @@ -864,7 +871,7 @@ static int p80211wext_siwrts(netdevice_t *dev, mibitem.data = rts->value; memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); - result = p80211req_dorequest(wlandev, (u8 *) & msg); + result = p80211req_dorequest(wlandev, (u8 *) &msg); if (result) { err = -EFAULT; @@ -886,10 +893,11 @@ static int p80211wext_giwfrag(netdevice_t *dev, int err = 0; msg.msgcode = DIDmsg_dot11req_mibget; + memset(&mibitem, 0, sizeof(mibitem)); mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold; memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); - result = p80211req_dorequest(wlandev, (u8 *) & msg); + result = p80211req_dorequest(wlandev, (u8 *) &msg); if (result) { err = -EFAULT; @@ -922,6 +930,7 @@ static int p80211wext_siwfrag(netdevice_t *dev, } msg.msgcode = DIDmsg_dot11req_mibset; + memset(&mibitem, 0, sizeof(mibitem)); mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold; @@ -931,7 +940,7 @@ static int p80211wext_siwfrag(netdevice_t *dev, mibitem.data = frag->value; memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); - result = p80211req_dorequest(wlandev, (u8 *) & msg); + result = p80211req_dorequest(wlandev, (u8 *) &msg); if (result) { err = -EFAULT; @@ -962,10 +971,11 @@ static int p80211wext_giwretry(netdevice_t *dev, u16 shortretry, longretry, lifetime; msg.msgcode = DIDmsg_dot11req_mibget; + memset(&mibitem, 0, sizeof(mibitem)); mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11ShortRetryLimit; memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); - result = p80211req_dorequest(wlandev, (u8 *) & msg); + result = p80211req_dorequest(wlandev, (u8 *) &msg); if (result) { err = -EFAULT; @@ -979,7 +989,7 @@ static int p80211wext_giwretry(netdevice_t *dev, mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit; memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); - result = p80211req_dorequest(wlandev, (u8 *) & msg); + result = p80211req_dorequest(wlandev, (u8 *) &msg); if (result) { err = -EFAULT; @@ -994,7 +1004,7 @@ static int p80211wext_giwretry(netdevice_t *dev, DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime; memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); - result = p80211req_dorequest(wlandev, (u8 *) & msg); + result = p80211req_dorequest(wlandev, (u8 *) &msg); if (result) { err = -EFAULT; @@ -1037,6 +1047,8 @@ static int p80211wext_siwretry(netdevice_t *dev, int result; int err = 0; + memset(&mibitem, 0, sizeof(mibitem)); + if (!wlan_wext_write) { err = (-EOPNOTSUPP); goto exit; @@ -1055,7 +1067,7 @@ static int p80211wext_siwretry(netdevice_t *dev, mibitem.data = rrq->value /= 1024; memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); - result = p80211req_dorequest(wlandev, (u8 *) & msg); + result = p80211req_dorequest(wlandev, (u8 *) &msg); if (result) { err = -EFAULT; @@ -1069,7 +1081,7 @@ static int p80211wext_siwretry(netdevice_t *dev, memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); - result = p80211req_dorequest(wlandev, (u8 *) & msg); + result = p80211req_dorequest(wlandev, (u8 *) &msg); if (result) { err = -EFAULT; @@ -1084,7 +1096,7 @@ static int p80211wext_siwretry(netdevice_t *dev, memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); - result = p80211req_dorequest(wlandev, (u8 *) & msg); + result = p80211req_dorequest(wlandev, (u8 *) &msg); if (result) { err = -EFAULT; @@ -1114,6 +1126,7 @@ static int p80211wext_siwtxpow(netdevice_t *dev, } msg.msgcode = DIDmsg_dot11req_mibset; + memset(&mibitem, 0, sizeof(mibitem)); mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel; if (rrq->fixed == 0) @@ -1121,7 +1134,7 @@ static int p80211wext_siwtxpow(netdevice_t *dev, else mibitem.data = rrq->value; memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); - result = p80211req_dorequest(wlandev, (u8 *) & msg); + result = p80211req_dorequest(wlandev, (u8 *) &msg); if (result) { err = -EFAULT; @@ -1143,11 +1156,13 @@ static int p80211wext_giwtxpow(netdevice_t *dev, int err = 0; msg.msgcode = DIDmsg_dot11req_mibget; + + memset(&mibitem, 0, sizeof(mibitem)); mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel; memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); - result = p80211req_dorequest(wlandev, (u8 *) & msg); + result = p80211req_dorequest(wlandev, (u8 *) &msg); if (result) { err = -EFAULT; @@ -1295,7 +1310,7 @@ static int p80211wext_siwscan(netdevice_t *dev, msg.maxchanneltime.data = 250; msg.minchanneltime.data = 200; - result = p80211req_dorequest(wlandev, (u8 *) & msg); + result = p80211req_dorequest(wlandev, (u8 *) &msg); if (result) err = prism2_result2err(msg.resultcode.data); @@ -1414,7 +1429,7 @@ static int p80211wext_giwscan(netdevice_t *dev, msg.msgcode = DIDmsg_dot11req_scan_results; msg.bssindex.data = i; - result = p80211req_dorequest(wlandev, (u8 *) & msg); + result = p80211req_dorequest(wlandev, (u8 *) &msg); if ((result != 0) || (msg.resultcode.data != P80211ENUM_resultcode_success)) { break; @@ -1489,7 +1504,7 @@ static int p80211wext_set_encodeext(struct net_device *dev, memcpy(wlandev->wep_keys[idx], ext->key, ext->key_len); memset(&msg, 0, sizeof(msg)); - pstr = (p80211item_pstr32_t *) & msg.mibattribute.data; + pstr = (p80211item_pstr32_t *) &msg.mibattribute.data; memcpy(pstr->data.data, ext->key, ext->key_len); pstr->data.len = ext->key_len; switch (idx) { @@ -1513,7 +1528,7 @@ static int p80211wext_set_encodeext(struct net_device *dev, break; } msg.msgcode = DIDmsg_dot11req_mibset; - result = p80211req_dorequest(wlandev, (u8 *) & msg); + result = p80211req_dorequest(wlandev, (u8 *) &msg); pr_debug("result (%d)\n", result); } return result; @@ -1729,15 +1744,11 @@ static iw_handler p80211wext_handlers[] = { struct iw_handler_def p80211wext_handler_def = { .num_standard = ARRAY_SIZE(p80211wext_handlers), - .num_private = 0, - .num_private_args = 0, .standard = p80211wext_handlers, - .private = NULL, - .private_args = NULL, .get_wireless_stats = p80211wext_get_wireless_stats }; -int p80211wext_event_associated(wlandevice_t * wlandev, int assoc) +int p80211wext_event_associated(wlandevice_t *wlandev, int assoc) { union iwreq_data data; diff --git a/drivers/staging/wlan-ng/prism2fw.c b/drivers/staging/wlan-ng/prism2fw.c index aaa70ed..4be54ce 100644 --- a/drivers/staging/wlan-ng/prism2fw.c +++ b/drivers/staging/wlan-ng/prism2fw.c @@ -53,6 +53,7 @@ /* Local Constants */ #define PRISM2_USB_FWFILE "prism2_ru.fw" +MODULE_FIRMWARE(PRISM2_USB_FWFILE); #define S3DATA_MAX 5000 #define S3PLUG_MAX 200 @@ -108,9 +109,9 @@ typedef struct pda { } pda_t; typedef struct imgchunk { - u32 addr; /* start address */ - u32 len; /* in bytes */ - u16 crc; /* CRC value (if it falls at a chunk boundary) */ + u32 addr; /* start address */ + u32 len; /* in bytes */ + u16 crc; /* CRC value (if it falls at a chunk boundary) */ u8 *data; } imgchunk_t; @@ -204,7 +205,7 @@ int prism2_fwtry(struct usb_device *udev, wlandevice_t *wlandev) return 1; } - printk(KERN_INFO "prism2_usb: %s will be processed, size %d\n", + printk(KERN_INFO "prism2_usb: %s will be processed, size %zu\n", PRISM2_USB_FWFILE, fw_entry->size); prism2_fwapply((const struct ihex_binrec *)fw_entry->data, wlandev); @@ -264,7 +265,7 @@ int prism2_fwapply(const struct ihex_binrec *rfptr, wlandevice_t *wlandev) /* Build the PDA we're going to use. */ if (read_cardpda(&pda, wlandev)) { printk(KERN_ERR "load_cardpda failed, exiting.\n"); - return (1); + return 1; } /* read the card's PRI-SUP */ @@ -286,9 +287,8 @@ int prism2_fwapply(const struct ihex_binrec *rfptr, wlandevice_t *wlandev) /* DIDmsg_dot11req_mibget */ prism2mgmt_mibset_mibget(wlandev, &getmsg); - if (getmsg.resultcode.data != P80211ENUM_resultcode_success) { + if (getmsg.resultcode.data != P80211ENUM_resultcode_success) printk(KERN_ERR "Couldn't fetch PRI-SUP info\n"); - } /* Already in host order */ priid.role = *data++; @@ -301,19 +301,19 @@ int prism2_fwapply(const struct ihex_binrec *rfptr, wlandevice_t *wlandev) result = read_fwfile(rfptr); if (result) { printk(KERN_ERR "Failed to read the data exiting.\n"); - return (1); + return 1; } result = validate_identity(); if (result) { printk(KERN_ERR "Incompatible firmware image.\n"); - return (1); + return 1; } if (startaddr == 0x00000000) { printk(KERN_ERR "Can't RAM download a Flash image!\n"); - return (1); + return 1; } /* Make the image chunks */ @@ -323,20 +323,20 @@ int prism2_fwapply(const struct ihex_binrec *rfptr, wlandevice_t *wlandev) result = plugimage(fchunk, nfchunks, s3plug, ns3plug, &pda); if (result) { printk(KERN_ERR "Failed to plug data.\n"); - return (1); + return 1; } /* Insert any CRCs */ if (crcimage(fchunk, nfchunks, s3crc, ns3crc)) { printk(KERN_ERR "Failed to insert all CRCs\n"); - return (1); + return 1; } /* Write the image */ result = writeimage(wlandev, fchunk, nfchunks); if (result) { printk(KERN_ERR "Failed to ramwrite image data.\n"); - return (1); + return 1; } /* clear any allocated memory */ @@ -434,9 +434,8 @@ void free_chunks(imgchunk_t *fchunk, unsigned int *nfchunks) { int i; for (i = 0; i < *nfchunks; i++) { - if (fchunk[i].data != NULL) { + if (fchunk[i].data != NULL) kfree(fchunk[i].data); - } } *nfchunks = 0; memset(fchunk, 0, sizeof(*fchunk)); @@ -531,7 +530,7 @@ int mkimage(imgchunk_t *clist, unsigned int *ccnt) if (clist[i].data == NULL) { printk(KERN_ERR "failed to allocate image space, exitting.\n"); - return (1); + return 1; } memset(clist[i].data, 0, clist[i].len); pr_debug("chunk[%d]: addr=0x%06x len=%d\n", @@ -545,15 +544,14 @@ int mkimage(imgchunk_t *clist, unsigned int *ccnt) for (j = 0; j < *ccnt; j++) { cstart = clist[j].addr; cend = cstart + clist[j].len - 1; - if (s3start >= cstart && s3end <= cend) { + if (s3start >= cstart && s3end <= cend) break; - } } if (((unsigned int)j) >= (*ccnt)) { printk(KERN_ERR "s3rec(a=0x%06x,l=%d), no chunk match, exiting.\n", s3start, s3data[i].len); - return (1); + return 1; } coffset = s3start - cstart; memcpy(clist[j].data + coffset, s3data[i].data, s3data[i].len); @@ -586,7 +584,7 @@ int mkpdrlist(pda_t *pda) curroff = 0; while (curroff < (HFA384x_PDA_LEN_MAX / 2) && le16_to_cpu(pda16[curroff + 1]) != HFA384x_PDR_END_OF_PDA) { - pda->rec[pda->nrec] = (hfa384x_pdrec_t *) & (pda16[curroff]); + pda->rec[pda->nrec] = (hfa384x_pdrec_t *) &(pda16[curroff]); if (le16_to_cpu(pda->rec[pda->nrec]->code) == HFA384x_PDR_NICID) { memcpy(&nicid, &pda->rec[pda->nrec]->data.nicid, @@ -623,10 +621,10 @@ int mkpdrlist(pda_t *pda) printk(KERN_ERR "no end record found or invalid lengths in " "PDR data, exiting. %x %d\n", curroff, pda->nrec); - return (1); + return 1; } if (le16_to_cpu(pda16[curroff + 1]) == HFA384x_PDR_END_OF_PDA) { - pda->rec[pda->nrec] = (hfa384x_pdrec_t *) & (pda16[curroff]); + pda->rec[pda->nrec] = (hfa384x_pdrec_t *) &(pda16[curroff]); (pda->nrec)++; } return result; @@ -869,7 +867,7 @@ int read_fwfile(const struct ihex_binrec *record) ptr16 = (u16 *) record->data; /* parse what was an S3 srec and put it in the right array */ - switch(addr) { + switch (addr) { case S3ADDR_START: startaddr = *ptr32; pr_debug(" S7 start addr, record=%d " @@ -890,7 +888,7 @@ int read_fwfile(const struct ihex_binrec *record) s3plug[ns3plug].len); ns3plug++; - if ( ns3plug == S3PLUG_MAX ) { + if (ns3plug == S3PLUG_MAX) { printk(KERN_ERR "S3 plugrec limit reached - aborting\n"); return 1; } @@ -907,7 +905,7 @@ int read_fwfile(const struct ihex_binrec *record) s3crc[ns3crc].len, s3crc[ns3crc].dowrite); ns3crc++; - if ( ns3crc == S3CRC_MAX ) { + if (ns3crc == S3CRC_MAX) { printk(KERN_ERR "S3 crcrec limit reached - aborting\n"); return 1; } @@ -921,12 +919,12 @@ int read_fwfile(const struct ihex_binrec *record) rcnt, s3info[ns3info].len, s3info[ns3info].type); - if ( ((s3info[ns3info].len - 1) * sizeof(u16)) > sizeof(s3info[ns3info].info) ) { + if (((s3info[ns3info].len - 1) * sizeof(u16)) > sizeof(s3info[ns3info].info)) { printk(KERN_ERR " S3 inforec length too long - aborting\n"); return 1; } - tmpinfo = (u16*)&(s3info[ns3info].info.version); + tmpinfo = (u16 *)&(s3info[ns3info].info.version); pr_debug(" info="); for (i = 0; i < s3info[ns3info].len - 1; i++) { tmpinfo[i] = *(ptr16 + 2 + i); @@ -935,7 +933,7 @@ int read_fwfile(const struct ihex_binrec *record) pr_debug("\n"); ns3info++; - if ( ns3info == S3INFO_MAX ) { + if (ns3info == S3INFO_MAX) { printk(KERN_ERR "S3 inforec limit reached - aborting\n"); return 1; } @@ -945,7 +943,7 @@ int read_fwfile(const struct ihex_binrec *record) s3data[ns3data].len = len; s3data[ns3data].data = (uint8_t *) record->data; ns3data++; - if ( ns3data == S3DATA_MAX ) { + if (ns3data == S3DATA_MAX) { printk(KERN_ERR "S3 datarec limit reached - aborting\n"); return 1; } @@ -1023,7 +1021,7 @@ int writeimage(wlandevice_t *wlandev, imgchunk_t *fchunk, rstatemsg.enable.data = P80211ENUM_truth_true; rstatemsg.exeaddr.data = startaddr; - msgp = (p80211msg_t *) & rstatemsg; + msgp = (p80211msg_t *) &rstatemsg; result = prism2mgmt_ramdl_state(wlandev, msgp); if (result) { printk(KERN_ERR @@ -1063,7 +1061,7 @@ int writeimage(wlandevice_t *wlandev, imgchunk_t *fchunk, ("Sending xxxdl_write message addr=%06x len=%d.\n", currdaddr, currlen); - msgp = (p80211msg_t *) & rwritemsg; + msgp = (p80211msg_t *) &rwritemsg; result = prism2mgmt_ramdl_write(wlandev, msgp); /* Check the results */ @@ -1090,7 +1088,7 @@ int writeimage(wlandevice_t *wlandev, imgchunk_t *fchunk, rstatemsg.enable.data = P80211ENUM_truth_false; rstatemsg.exeaddr.data = 0; - msgp = (p80211msg_t *) & rstatemsg; + msgp = (p80211msg_t *) &rstatemsg; result = prism2mgmt_ramdl_state(wlandev, msgp); if (result) { printk(KERN_ERR @@ -1161,7 +1159,7 @@ int validate_identity(void) /* SEC compat range */ if ((s3info[i].info.compat.role == 1) && (s3info[i].info.compat.id == 4)) { - + /* FIXME: isn't something missing here? */ } break; @@ -1196,8 +1194,9 @@ int validate_identity(void) pr_debug("Unknown inforec type %d\n", s3info[i].type); } } - // walk through + /* walk through */ - if (trump && (result != 2)) result = 0; + if (trump && (result != 2)) + result = 0; return result; } diff --git a/drivers/staging/wlan-ng/prism2mgmt.c b/drivers/staging/wlan-ng/prism2mgmt.c index 9f7d96c..ad163da 100644 --- a/drivers/staging/wlan-ng/prism2mgmt.c +++ b/drivers/staging/wlan-ng/prism2mgmt.c @@ -67,7 +67,7 @@ #include <linux/wireless.h> #include <linux/netdevice.h> #include <linux/delay.h> -#include <asm/io.h> +#include <linux/io.h> #include <asm/byteorder.h> #include <linux/random.h> #include <linux/usb.h> @@ -541,7 +541,7 @@ int prism2mgmt_start(wlandevice_t *wlandev, void *msgp) /*** STATION ***/ /* Set the REQUIRED config items */ /* SSID */ - pstr = (p80211pstrd_t *) & (msg->ssid.data); + pstr = (p80211pstrd_t *) &(msg->ssid.data); prism2mgmt_pstr2bytestr(p2bytestr, pstr); result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFOWNSSID, bytebuf, HFA384x_RID_CNFOWNSSID_LEN); @@ -1034,7 +1034,7 @@ int prism2mgmt_autojoin(wlandevice_t *wlandev, void *msgp) /* Set the ssid */ memset(bytebuf, 0, 256); - pstr = (p80211pstrd_t *) & (msg->ssid.data); + pstr = (p80211pstrd_t *) &(msg->ssid.data); prism2mgmt_pstr2bytestr(p2bytestr, pstr); result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFDESIREDSSID, bytebuf, @@ -1123,8 +1123,8 @@ int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp) if (hw->presniff_port_type != 0) { word = hw->presniff_port_type; result = hfa384x_drvr_setconfig16(hw, - HFA384x_RID_CNFPORTTYPE, - word); + HFA384x_RID_CNFPORTTYPE, + word); if (result) { pr_debug ("failed to restore porttype, result=%d\n", @@ -1156,10 +1156,8 @@ int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp) if (wlandev->netdev->type == ARPHRD_ETHER) { /* Save macport 0 state */ result = hfa384x_drvr_getconfig16(hw, - HFA384x_RID_CNFPORTTYPE, - & - (hw-> - presniff_port_type)); + HFA384x_RID_CNFPORTTYPE, + &(hw->presniff_port_type)); if (result) { pr_debug ("failed to read porttype, result=%d\n", @@ -1168,10 +1166,8 @@ int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp) } /* Save the wepflags state */ result = hfa384x_drvr_getconfig16(hw, - HFA384x_RID_CNFWEPFLAGS, - & - (hw-> - presniff_wepflags)); + HFA384x_RID_CNFWEPFLAGS, + &(hw->presniff_wepflags)); if (result) { pr_debug ("failed to read wepflags, result=%d\n", @@ -1218,8 +1214,8 @@ int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp) /* Set the port type to pIbss */ word = HFA384x_PORTTYPE_PSUEDOIBSS; result = hfa384x_drvr_setconfig16(hw, - HFA384x_RID_CNFPORTTYPE, - word); + HFA384x_RID_CNFPORTTYPE, + word); if (result) { pr_debug ("failed to set porttype %d, result=%d\n", @@ -1235,8 +1231,8 @@ int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp) HFA384x_WEPFLAGS_DISABLE_RXCRYPT; result = hfa384x_drvr_setconfig16(hw, - HFA384x_RID_CNFWEPFLAGS, - word); + HFA384x_RID_CNFWEPFLAGS, + word); } if (result) { diff --git a/drivers/staging/wlan-ng/prism2mgmt.h b/drivers/staging/wlan-ng/prism2mgmt.h index bdf2b3e..07eeceb 100644 --- a/drivers/staging/wlan-ng/prism2mgmt.h +++ b/drivers/staging/wlan-ng/prism2mgmt.h @@ -63,43 +63,43 @@ extern int prism2_reset_holdtime; extern int prism2_reset_settletime; -u32 prism2sta_ifstate(wlandevice_t * wlandev, u32 ifstate); +u32 prism2sta_ifstate(wlandevice_t *wlandev, u32 ifstate); -void prism2sta_ev_info(wlandevice_t * wlandev, hfa384x_InfFrame_t * inf); -void prism2sta_ev_txexc(wlandevice_t * wlandev, u16 status); -void prism2sta_ev_tx(wlandevice_t * wlandev, u16 status); -void prism2sta_ev_rx(wlandevice_t * wlandev, struct sk_buff *skb); -void prism2sta_ev_alloc(wlandevice_t * wlandev); +void prism2sta_ev_info(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf); +void prism2sta_ev_txexc(wlandevice_t *wlandev, u16 status); +void prism2sta_ev_tx(wlandevice_t *wlandev, u16 status); +void prism2sta_ev_rx(wlandevice_t *wlandev, struct sk_buff *skb); +void prism2sta_ev_alloc(wlandevice_t *wlandev); -int prism2mgmt_mibset_mibget(wlandevice_t * wlandev, void *msgp); -int prism2mgmt_scan(wlandevice_t * wlandev, void *msgp); -int prism2mgmt_scan_results(wlandevice_t * wlandev, void *msgp); -int prism2mgmt_start(wlandevice_t * wlandev, void *msgp); -int prism2mgmt_wlansniff(wlandevice_t * wlandev, void *msgp); -int prism2mgmt_readpda(wlandevice_t * wlandev, void *msgp); -int prism2mgmt_ramdl_state(wlandevice_t * wlandev, void *msgp); -int prism2mgmt_ramdl_write(wlandevice_t * wlandev, void *msgp); -int prism2mgmt_flashdl_state(wlandevice_t * wlandev, void *msgp); -int prism2mgmt_flashdl_write(wlandevice_t * wlandev, void *msgp); -int prism2mgmt_autojoin(wlandevice_t * wlandev, void *msgp); +int prism2mgmt_mibset_mibget(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_scan(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_scan_results(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_start(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_readpda(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_ramdl_state(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_ramdl_write(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_flashdl_state(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_flashdl_write(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_autojoin(wlandevice_t *wlandev, void *msgp); /*--------------------------------------------------------------- * conversion functions going between wlan message data types and * Prism2 data types ---------------------------------------------------------------*/ /* byte area conversion functions*/ -void prism2mgmt_pstr2bytearea(u8 * bytearea, p80211pstrd_t * pstr); -void prism2mgmt_bytearea2pstr(u8 * bytearea, p80211pstrd_t * pstr, int len); +void prism2mgmt_pstr2bytearea(u8 *bytearea, p80211pstrd_t *pstr); +void prism2mgmt_bytearea2pstr(u8 *bytearea, p80211pstrd_t *pstr, int len); /* byte string conversion functions*/ -void prism2mgmt_pstr2bytestr(hfa384x_bytestr_t * bytestr, p80211pstrd_t * pstr); -void prism2mgmt_bytestr2pstr(hfa384x_bytestr_t * bytestr, p80211pstrd_t * pstr); +void prism2mgmt_pstr2bytestr(hfa384x_bytestr_t *bytestr, p80211pstrd_t *pstr); +void prism2mgmt_bytestr2pstr(hfa384x_bytestr_t *bytestr, p80211pstrd_t *pstr); /* functions to convert Group Addresses */ -void prism2mgmt_get_grpaddr(u32 did, p80211pstrd_t * pstr, hfa384x_t * priv); +void prism2mgmt_get_grpaddr(u32 did, p80211pstrd_t *pstr, hfa384x_t *priv); int prism2mgmt_set_grpaddr(u32 did, - u8 * prism2buf, p80211pstrd_t * pstr, - hfa384x_t * priv); + u8 *prism2buf, p80211pstrd_t *pstr, + hfa384x_t *priv); int prism2mgmt_get_grpaddr_index(u32 did); void prism2sta_processing_defer(struct work_struct *data); diff --git a/drivers/staging/wlan-ng/prism2mib.c b/drivers/staging/wlan-ng/prism2mib.c index 2fff0a1..98a5d58 100644 --- a/drivers/staging/wlan-ng/prism2mib.c +++ b/drivers/staging/wlan-ng/prism2mib.c @@ -114,7 +114,7 @@ static int prism2mib_flag(mibrec_t *mib, static int prism2mib_wepdefaultkey(mibrec_t *mib, int isget, - wlandevice_t * wlandev, + wlandevice_t *wlandev, hfa384x_t *hw, p80211msg_dot11req_mibset_t *msg, void *data); @@ -726,7 +726,7 @@ static int prism2mib_priv(mibrec_t *mib, if (isget) { hfa384x_drvr_getconfig(hw, HFA384x_RID_CNFWPADATA, - (u8 *) & wpa, + (u8 *) &wpa, sizeof(wpa)); pstr->len = le16_to_cpu(wpa.datalen); memcpy(pstr->data, wpa.data, pstr->len); @@ -736,9 +736,9 @@ static int prism2mib_priv(mibrec_t *mib, result = hfa384x_drvr_setconfig(hw, - HFA384x_RID_CNFWPADATA, - (u8 *) & wpa, - sizeof(wpa)); + HFA384x_RID_CNFWPADATA, + (u8 *) &wpa, + sizeof(wpa)); } break; } diff --git a/drivers/staging/wlan-ng/prism2sta.c b/drivers/staging/wlan-ng/prism2sta.c index 50f301d..31ac8da 100644 --- a/drivers/staging/wlan-ng/prism2sta.c +++ b/drivers/staging/wlan-ng/prism2sta.c @@ -64,7 +64,7 @@ #include <linux/byteorder/generic.h> #include <linux/ctype.h> -#include <asm/io.h> +#include <linux/io.h> #include <linux/delay.h> #include <asm/byteorder.h> #include <linux/if_arp.h> @@ -1023,13 +1023,13 @@ static void prism2sta_inf_tallies(wlandevice_t *wlandev, cnt = sizeof(hfa384x_CommTallies32_t) / sizeof(u32); if (inf->framelen > 22) { - dst = (u32 *) & hw->tallies; - src32 = (u32 *) & inf->info.commtallies32; + dst = (u32 *) &hw->tallies; + src32 = (u32 *) &inf->info.commtallies32; for (i = 0; i < cnt; i++, dst++, src32++) *dst += le32_to_cpu(*src32); } else { - dst = (u32 *) & hw->tallies; - src16 = (u16 *) & inf->info.commtallies16; + dst = (u32 *) &hw->tallies; + src16 = (u16 *) &inf->info.commtallies16; for (i = 0; i < cnt; i++, dst++, src16++) *dst += le16_to_cpu(*src16); } @@ -1280,7 +1280,7 @@ void prism2sta_processing_defer(struct work_struct *data) HFA384x_RID_CURRENTSSID, result); goto failed; } - prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *) & ssid, + prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *) &ssid, (p80211pstrd_t *) & wlandev->ssid); @@ -1368,8 +1368,8 @@ void prism2sta_processing_defer(struct work_struct *data) HFA384x_RID_CURRENTSSID, result); goto failed; } - prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *) & ssid, - (p80211pstrd_t *) & wlandev->ssid); + prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *) &ssid, + (p80211pstrd_t *) &wlandev->ssid); hw->link_status = HFA384x_LINK_CONNECTED; netif_carrier_on(wlandev->netdev); @@ -2028,8 +2028,8 @@ void prism2sta_commsqual_defer(struct work_struct *data) HFA384x_RID_CURRENTSSID, result); goto done; } - prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *) & ssid, - (p80211pstrd_t *) & wlandev->ssid); + prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *) &ssid, + (p80211pstrd_t *) &wlandev->ssid); /* Reschedule timer */ mod_timer(&hw->commsqual_timer, jiffies + HZ); diff --git a/drivers/staging/wlan-ng/prism2usb.c b/drivers/staging/wlan-ng/prism2usb.c index 9dde68b..501d27f 100644 --- a/drivers/staging/wlan-ng/prism2usb.c +++ b/drivers/staging/wlan-ng/prism2usb.c @@ -24,8 +24,9 @@ static struct usb_device_id usb_prism_tbl[] = { (0x066b, 0x2213, "Linksys WUSB12v1.1 11Mbps WLAN USB Adapter")}, {PRISM_USB_DEVICE (0x067c, 0x1022, "Siemens SpeedStream 1022 11Mbps WLAN USB Adapter")}, - {PRISM_USB_DEVICE(0x049f, 0x0033, - "Compaq/Intel W100 PRO/Wireless 11Mbps multiport WLAN Adapter")}, + {PRISM_USB_DEVICE + (0x049f, 0x0033, + "Compaq/Intel W100 PRO/Wireless 11Mbps multiport WLAN Adapter")}, {PRISM_USB_DEVICE (0x0411, 0x0016, "Melco WLI-USB-S11 11Mbps WLAN Adapter")}, {PRISM_USB_DEVICE @@ -55,7 +56,6 @@ static struct usb_device_id usb_prism_tbl[] = { (0x04f1, 0x3009, "JVC MP-XP7250 Builtin USB WLAN Adapter")}, {PRISM_USB_DEVICE(0x0846, 0x4110, "NetGear MA111")}, {PRISM_USB_DEVICE(0x03f3, 0x0020, "Adaptec AWN-8020 USB WLAN Adapter")}, -/* {PRISM_USB_DEVICE(0x0ace, 0x1201, "ZyDAS ZD1201 Wireless USB Adapter")}, */ {PRISM_USB_DEVICE(0x2821, 0x3300, "ASUS-WL140 Wireless USB Adapter")}, {PRISM_USB_DEVICE(0x2001, 0x3700, "DWL-122 Wireless USB Adapter")}, {PRISM_USB_DEVICE diff --git a/drivers/video/backlight/88pm860x_bl.c b/drivers/video/backlight/88pm860x_bl.c new file mode 100644 index 0000000..b8f705c --- /dev/null +++ b/drivers/video/backlight/88pm860x_bl.c @@ -0,0 +1,304 @@ +/* + * Backlight driver for Marvell Semiconductor 88PM8606 + * + * Copyright (C) 2009 Marvell International Ltd. + * Haojian Zhuang <haojian.zhuang@marvell.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/platform_device.h> +#include <linux/fb.h> +#include <linux/i2c.h> +#include <linux/backlight.h> +#include <linux/mfd/88pm860x.h> + +#define MAX_BRIGHTNESS (0xFF) +#define MIN_BRIGHTNESS (0) + +#define CURRENT_MASK (0x1F << 1) + +struct pm860x_backlight_data { + struct pm860x_chip *chip; + struct i2c_client *i2c; + int current_brightness; + int port; + int pwm; + int iset; +}; + +static inline int wled_a(int port) +{ + int ret; + + ret = ((port - PM8606_BACKLIGHT1) << 1) + 2; + return ret; +} + +static inline int wled_b(int port) +{ + int ret; + + ret = ((port - PM8606_BACKLIGHT1) << 1) + 3; + return ret; +} + +/* WLED2 & WLED3 share the same IDC */ +static inline int wled_idc(int port) +{ + int ret; + + switch (port) { + case PM8606_BACKLIGHT1: + case PM8606_BACKLIGHT2: + ret = ((port - PM8606_BACKLIGHT1) << 1) + 3; + break; + case PM8606_BACKLIGHT3: + default: + ret = ((port - PM8606_BACKLIGHT2) << 1) + 3; + break; + } + return ret; +} + +static int pm860x_backlight_set(struct backlight_device *bl, int brightness) +{ + struct pm860x_backlight_data *data = bl_get_data(bl); + struct pm860x_chip *chip = data->chip; + unsigned char value; + int ret; + + if (brightness > MAX_BRIGHTNESS) + value = MAX_BRIGHTNESS; + else + value = brightness; + + ret = pm860x_reg_write(data->i2c, wled_a(data->port), value); + if (ret < 0) + goto out; + + if ((data->current_brightness == 0) && brightness) { + if (data->iset) { + ret = pm860x_set_bits(data->i2c, wled_idc(data->port), + CURRENT_MASK, data->iset); + if (ret < 0) + goto out; + } + if (data->pwm) { + ret = pm860x_set_bits(data->i2c, PM8606_PWM, + PM8606_PWM_FREQ_MASK, data->pwm); + if (ret < 0) + goto out; + } + if (brightness == MAX_BRIGHTNESS) { + /* set WLED_ON bit as 100% */ + ret = pm860x_set_bits(data->i2c, wled_b(data->port), + PM8606_WLED_ON, PM8606_WLED_ON); + } + } else { + if (brightness == MAX_BRIGHTNESS) { + /* set WLED_ON bit as 100% */ + ret = pm860x_set_bits(data->i2c, wled_b(data->port), + PM8606_WLED_ON, PM8606_WLED_ON); + } else { + /* clear WLED_ON bit since it's not 100% */ + ret = pm860x_set_bits(data->i2c, wled_b(data->port), + PM8606_WLED_ON, 0); + } + } + if (ret < 0) + goto out; + + dev_dbg(chip->dev, "set brightness %d\n", value); + data->current_brightness = value; + return 0; +out: + dev_dbg(chip->dev, "set brightness %d failure with return " + "value:%d\n", value, ret); + return ret; +} + +static int pm860x_backlight_update_status(struct backlight_device *bl) +{ + int brightness = bl->props.brightness; + + if (bl->props.power != FB_BLANK_UNBLANK) + brightness = 0; + + if (bl->props.fb_blank != FB_BLANK_UNBLANK) + brightness = 0; + + if (bl->props.state & BL_CORE_SUSPENDED) + brightness = 0; + + return pm860x_backlight_set(bl, brightness); +} + +static int pm860x_backlight_get_brightness(struct backlight_device *bl) +{ + struct pm860x_backlight_data *data = bl_get_data(bl); + struct pm860x_chip *chip = data->chip; + int ret; + + ret = pm860x_reg_read(data->i2c, wled_a(data->port)); + if (ret < 0) + goto out; + data->current_brightness = ret; + dev_dbg(chip->dev, "get brightness %d\n", data->current_brightness); + return data->current_brightness; +out: + return -EINVAL; +} + +static struct backlight_ops pm860x_backlight_ops = { + .options = BL_CORE_SUSPENDRESUME, + .update_status = pm860x_backlight_update_status, + .get_brightness = pm860x_backlight_get_brightness, +}; + +static int __check_device(struct pm860x_backlight_pdata *pdata, char *name) +{ + struct pm860x_backlight_pdata *p = pdata; + int ret = -EINVAL; + + while (p && p->id) { + if ((p->id != PM8606_ID_BACKLIGHT) || (p->flags < 0)) + break; + + if (!strncmp(name, pm860x_backlight_name[p->flags], + MFD_NAME_SIZE)) { + ret = (int)p->flags; + break; + } + p++; + } + return ret; +} + +static int pm860x_backlight_probe(struct platform_device *pdev) +{ + struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); + struct pm860x_platform_data *pm860x_pdata; + struct pm860x_backlight_pdata *pdata = NULL; + struct pm860x_backlight_data *data; + struct backlight_device *bl; + struct resource *res; + unsigned char value; + char name[MFD_NAME_SIZE]; + int ret; + + res = platform_get_resource(pdev, IORESOURCE_IO, 0); + if (res == NULL) { + dev_err(&pdev->dev, "No I/O resource!\n"); + return -EINVAL; + } + + if (pdev->dev.parent->platform_data) { + pm860x_pdata = pdev->dev.parent->platform_data; + pdata = pm860x_pdata->backlight; + } + if (pdata == NULL) { + dev_err(&pdev->dev, "platform data isn't assigned to " + "backlight\n"); + return -EINVAL; + } + + data = kzalloc(sizeof(struct pm860x_backlight_data), GFP_KERNEL); + if (data == NULL) + return -ENOMEM; + strncpy(name, res->name, MFD_NAME_SIZE); + data->chip = chip; + data->i2c = (chip->id == CHIP_PM8606) ? chip->client \ + : chip->companion; + data->current_brightness = MAX_BRIGHTNESS; + data->pwm = pdata->pwm; + data->iset = pdata->iset; + data->port = __check_device(pdata, name); + if (data->port < 0) { + dev_err(&pdev->dev, "wrong platform data is assigned"); + return -EINVAL; + } + + bl = backlight_device_register(name, &pdev->dev, data, + &pm860x_backlight_ops); + if (IS_ERR(bl)) { + dev_err(&pdev->dev, "failed to register backlight\n"); + kfree(data); + return PTR_ERR(bl); + } + bl->props.max_brightness = MAX_BRIGHTNESS; + bl->props.brightness = MAX_BRIGHTNESS; + + platform_set_drvdata(pdev, bl); + + /* Enable reference VSYS */ + ret = pm860x_reg_read(data->i2c, PM8606_VSYS); + if (ret < 0) + goto out; + if ((ret & PM8606_VSYS_EN) == 0) { + value = ret | PM8606_VSYS_EN; + ret = pm860x_reg_write(data->i2c, PM8606_VSYS, value); + if (ret < 0) + goto out; + } + /* Enable reference OSC */ + ret = pm860x_reg_read(data->i2c, PM8606_MISC); + if (ret < 0) + goto out; + if ((ret & PM8606_MISC_OSC_EN) == 0) { + value = ret | PM8606_MISC_OSC_EN; + ret = pm860x_reg_write(data->i2c, PM8606_MISC, value); + if (ret < 0) + goto out; + } + /* read current backlight */ + ret = pm860x_backlight_get_brightness(bl); + if (ret < 0) + goto out; + + backlight_update_status(bl); + return 0; +out: + kfree(data); + return ret; +} + +static int pm860x_backlight_remove(struct platform_device *pdev) +{ + struct backlight_device *bl = platform_get_drvdata(pdev); + struct pm860x_backlight_data *data = bl_get_data(bl); + + backlight_device_unregister(bl); + kfree(data); + return 0; +} + +static struct platform_driver pm860x_backlight_driver = { + .driver = { + .name = "88pm860x-backlight", + .owner = THIS_MODULE, + }, + .probe = pm860x_backlight_probe, + .remove = pm860x_backlight_remove, +}; + +static int __init pm860x_backlight_init(void) +{ + return platform_driver_register(&pm860x_backlight_driver); +} +module_init(pm860x_backlight_init); + +static void __exit pm860x_backlight_exit(void) +{ + platform_driver_unregister(&pm860x_backlight_driver); +} +module_exit(pm860x_backlight_exit); + +MODULE_DESCRIPTION("Backlight Driver for Marvell Semiconductor 88PM8606"); +MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:88pm860x-backlight"); diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index 09bfa96..0c77fc6 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig @@ -212,6 +212,13 @@ config BACKLIGHT_DA903X If you have a LCD backlight connected to the WLED output of DA9030 or DA9034 WLED output, say Y here to enable this driver. +config BACKLIGHT_MAX8925 + tristate "Backlight driver for MAX8925" + depends on BACKLIGHT_CLASS_DEVICE && MFD_MAX8925 + help + If you have a LCD backlight connected to the WLED output of MAX8925 + WLED output, say Y here to enable this driver. + config BACKLIGHT_MBP_NVIDIA tristate "MacBook Pro Nvidia Backlight Driver" depends on BACKLIGHT_CLASS_DEVICE && X86 @@ -262,3 +269,9 @@ config BACKLIGHT_ADP5520 To compile this driver as a module, choose M here: the module will be called adp5520_bl. +config BACKLIGHT_88PM860X + tristate "Backlight Driver for 88PM8606 using WLED" + depends on BACKLIGHT_CLASS_DEVICE && MFD_88PM860X + help + Say Y to enable the backlight driver for Marvell 88PM8606. + diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile index 9a40554..6c704d4 100644 --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile @@ -22,10 +22,12 @@ obj-$(CONFIG_BACKLIGHT_PROGEAR) += progear_bl.o obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o obj-$(CONFIG_BACKLIGHT_PWM) += pwm_bl.o obj-$(CONFIG_BACKLIGHT_DA903X) += da903x_bl.o +obj-$(CONFIG_BACKLIGHT_MAX8925) += max8925_bl.o obj-$(CONFIG_BACKLIGHT_MBP_NVIDIA) += mbp_nvidia_bl.o obj-$(CONFIG_BACKLIGHT_TOSA) += tosa_bl.o obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o obj-$(CONFIG_BACKLIGHT_WM831X) += wm831x_bl.o obj-$(CONFIG_BACKLIGHT_ADX) += adx_bl.o obj-$(CONFIG_BACKLIGHT_ADP5520) += adp5520_bl.o +obj-$(CONFIG_BACKLIGHT_88PM860X) += 88pm860x_bl.o diff --git a/drivers/video/backlight/max8925_bl.c b/drivers/video/backlight/max8925_bl.c new file mode 100644 index 0000000..c267069 --- /dev/null +++ b/drivers/video/backlight/max8925_bl.c @@ -0,0 +1,200 @@ +/* + * Backlight driver for Maxim MAX8925 + * + * Copyright (C) 2009 Marvell International Ltd. + * Haojian Zhuang <haojian.zhuang@marvell.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/platform_device.h> +#include <linux/fb.h> +#include <linux/i2c.h> +#include <linux/backlight.h> +#include <linux/mfd/max8925.h> + +#define MAX_BRIGHTNESS (0xff) +#define MIN_BRIGHTNESS (0) + +#define LWX_FREQ(x) (((x - 601) / 100) & 0x7) + +struct max8925_backlight_data { + struct max8925_chip *chip; + + int current_brightness; +}; + +static int max8925_backlight_set(struct backlight_device *bl, int brightness) +{ + struct max8925_backlight_data *data = bl_get_data(bl); + struct max8925_chip *chip = data->chip; + unsigned char value; + int ret; + + if (brightness > MAX_BRIGHTNESS) + value = MAX_BRIGHTNESS; + else + value = brightness; + + ret = max8925_reg_write(chip->i2c, MAX8925_WLED_CNTL, value); + if (ret < 0) + goto out; + + if (!data->current_brightness && brightness) + /* enable WLED output */ + ret = max8925_set_bits(chip->i2c, MAX8925_WLED_MODE_CNTL, 1, 1); + else if (!brightness) + /* disable WLED output */ + ret = max8925_set_bits(chip->i2c, MAX8925_WLED_MODE_CNTL, 1, 0); + if (ret < 0) + goto out; + dev_dbg(chip->dev, "set brightness %d\n", value); + data->current_brightness = value; + return 0; +out: + dev_dbg(chip->dev, "set brightness %d failure with return value:%d\n", + value, ret); + return ret; +} + +static int max8925_backlight_update_status(struct backlight_device *bl) +{ + int brightness = bl->props.brightness; + + if (bl->props.power != FB_BLANK_UNBLANK) + brightness = 0; + + if (bl->props.fb_blank != FB_BLANK_UNBLANK) + brightness = 0; + + if (bl->props.state & BL_CORE_SUSPENDED) + brightness = 0; + + return max8925_backlight_set(bl, brightness); +} + +static int max8925_backlight_get_brightness(struct backlight_device *bl) +{ + struct max8925_backlight_data *data = bl_get_data(bl); + struct max8925_chip *chip = data->chip; + int ret; + + ret = max8925_reg_read(chip->i2c, MAX8925_WLED_CNTL); + if (ret < 0) + return -EINVAL; + data->current_brightness = ret; + dev_dbg(chip->dev, "get brightness %d\n", data->current_brightness); + return ret; +} + +static struct backlight_ops max8925_backlight_ops = { + .options = BL_CORE_SUSPENDRESUME, + .update_status = max8925_backlight_update_status, + .get_brightness = max8925_backlight_get_brightness, +}; + +static int __devinit max8925_backlight_probe(struct platform_device *pdev) +{ + struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent); + struct max8925_platform_data *max8925_pdata; + struct max8925_backlight_pdata *pdata = NULL; + struct max8925_backlight_data *data; + struct backlight_device *bl; + struct resource *res; + char name[MAX8925_NAME_SIZE]; + unsigned char value; + int ret; + + res = platform_get_resource(pdev, IORESOURCE_IO, 0); + if (res == NULL) { + dev_err(&pdev->dev, "No I/O resource!\n"); + return -EINVAL; + } + + if (pdev->dev.parent->platform_data) { + max8925_pdata = pdev->dev.parent->platform_data; + pdata = max8925_pdata->backlight; + } + + if (!pdata) { + dev_err(&pdev->dev, "platform data isn't assigned to " + "backlight\n"); + return -EINVAL; + } + + data = kzalloc(sizeof(struct max8925_backlight_data), GFP_KERNEL); + if (data == NULL) + return -ENOMEM; + strncpy(name, res->name, MAX8925_NAME_SIZE); + data->chip = chip; + data->current_brightness = 0; + + bl = backlight_device_register(name, &pdev->dev, data, + &max8925_backlight_ops); + if (IS_ERR(bl)) { + dev_err(&pdev->dev, "failed to register backlight\n"); + kfree(data); + return PTR_ERR(bl); + } + bl->props.max_brightness = MAX_BRIGHTNESS; + bl->props.brightness = MAX_BRIGHTNESS; + + platform_set_drvdata(pdev, bl); + + value = 0; + if (pdata->lxw_scl) + value |= (1 << 7); + if (pdata->lxw_freq) + value |= (LWX_FREQ(pdata->lxw_freq) << 4); + if (pdata->dual_string) + value |= (1 << 1); + ret = max8925_set_bits(chip->i2c, MAX8925_WLED_MODE_CNTL, 0xfe, value); + if (ret < 0) + goto out; + + backlight_update_status(bl); + return 0; +out: + kfree(data); + return ret; +} + +static int __devexit max8925_backlight_remove(struct platform_device *pdev) +{ + struct backlight_device *bl = platform_get_drvdata(pdev); + struct max8925_backlight_data *data = bl_get_data(bl); + + backlight_device_unregister(bl); + kfree(data); + return 0; +} + +static struct platform_driver max8925_backlight_driver = { + .driver = { + .name = "max8925-backlight", + .owner = THIS_MODULE, + }, + .probe = max8925_backlight_probe, + .remove = __devexit_p(max8925_backlight_remove), +}; + +static int __init max8925_backlight_init(void) +{ + return platform_driver_register(&max8925_backlight_driver); +} +module_init(max8925_backlight_init); + +static void __exit max8925_backlight_exit(void) +{ + platform_driver_unregister(&max8925_backlight_driver); +}; +module_exit(max8925_backlight_exit); + +MODULE_DESCRIPTION("Backlight Driver for Maxim MAX8925"); +MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:max8925-backlight"); diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c index 1b65732..625447f 100644 --- a/drivers/virtio/virtio_pci.c +++ b/drivers/virtio/virtio_pci.c @@ -649,6 +649,7 @@ static int __devinit virtio_pci_probe(struct pci_dev *pci_dev, goto out_req_regions; pci_set_drvdata(pci_dev, vp_dev); + pci_set_master(pci_dev); /* we use the subsystem vendor/device id as the virtio vendor/device * id. this allows us to use the same PCI vendor/device id for all diff --git a/fs/seq_file.c b/fs/seq_file.c index 5afd554..e1f437b 100644 --- a/fs/seq_file.c +++ b/fs/seq_file.c @@ -734,7 +734,7 @@ EXPORT_SYMBOL(seq_hlist_start_head); * seq_hlist_next - move to the next position of the hlist * @v: the current iterator * @head: the head of the hlist - * @pos: the current posision + * @ppos: the current position * * Called at seq_file->op->next(). */ @@ -800,7 +800,7 @@ EXPORT_SYMBOL(seq_hlist_start_head_rcu); * seq_hlist_next_rcu - move to the next position of the hlist protected by RCU * @v: the current iterator * @head: the head of the hlist - * @pos: the current posision + * @ppos: the current position * * Called at seq_file->op->next(). * diff --git a/include/linux/htcpld.h b/include/linux/htcpld.h new file mode 100644 index 0000000..ab3f6cb4 --- /dev/null +++ b/include/linux/htcpld.h @@ -0,0 +1,24 @@ +#ifndef __LINUX_HTCPLD_H +#define __LINUX_HTCPLD_H + +struct htcpld_chip_platform_data { + unsigned int addr; + unsigned int reset; + unsigned int num_gpios; + unsigned int gpio_out_base; + unsigned int gpio_in_base; + unsigned int irq_base; + unsigned int num_irqs; +}; + +struct htcpld_core_platform_data { + unsigned int int_reset_gpio_hi; + unsigned int int_reset_gpio_lo; + unsigned int i2c_adapter_id; + + struct htcpld_chip_platform_data *chip; + unsigned int num_chip; +}; + +#endif /* __LINUX_HTCPLD_H */ + diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h index 7897f30..fb6784e 100644 --- a/include/linux/i2c/twl.h +++ b/include/linux/i2c/twl.h @@ -80,6 +80,11 @@ #define TWL_MODULE_PM_MASTER TWL4030_MODULE_PM_MASTER #define TWL_MODULE_PM_RECEIVER TWL4030_MODULE_PM_RECEIVER #define TWL_MODULE_RTC TWL4030_MODULE_RTC +#define TWL_MODULE_PWM TWL4030_MODULE_PWM0 + +#define TWL6030_MODULE_ID0 0x0D +#define TWL6030_MODULE_ID1 0x0E +#define TWL6030_MODULE_ID2 0x0F #define GPIO_INTR_OFFSET 0 #define KEYPAD_INTR_OFFSET 1 @@ -239,6 +244,21 @@ int twl6030_interrupt_mask(u8 bit_mask, u8 offset); /*----------------------------------------------------------------------*/ +/*Interface Bit Register (INTBR) offsets + *(Use TWL_4030_MODULE_INTBR) + */ + +#define REG_GPPUPDCTR1 0x0F + +/*I2C1 and I2C4(SR) SDA/SCL pull-up control bits */ + +#define I2C_SCL_CTRL_PU BIT(0) +#define I2C_SDA_CTRL_PU BIT(2) +#define SR_I2C_SCL_CTRL_PU BIT(4) +#define SR_I2C_SDA_CTRL_PU BIT(6) + +/*----------------------------------------------------------------------*/ + /* * Keypad register offsets (use TWL4030_MODULE_KEYPAD) * ... SIH/interrupt only @@ -530,6 +550,7 @@ struct twl4030_power_data { }; extern void twl4030_power_init(struct twl4030_power_data *triton2_scripts); +extern int twl4030_remove_script(u8 flags); struct twl4030_codec_audio_data { unsigned int audio_mclk; @@ -605,12 +626,7 @@ int twl4030_sih_setup(int module); #define TWL4030_VAUX3_DEV_GRP 0x1F #define TWL4030_VAUX3_DEDICATED 0x22 -#if defined(CONFIG_TWL4030_BCI_BATTERY) || \ - defined(CONFIG_TWL4030_BCI_BATTERY_MODULE) - extern int twl4030charger_usb_en(int enable); -#else - static inline int twl4030charger_usb_en(int enable) { return 0; } -#endif +static inline int twl4030charger_usb_en(int enable) { return 0; } /*----------------------------------------------------------------------*/ diff --git a/include/linux/mfd/88pm8607.h b/include/linux/mfd/88pm8607.h deleted file mode 100644 index f41b428..0000000 --- a/include/linux/mfd/88pm8607.h +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Marvell 88PM8607 Interface - * - * Copyright (C) 2009 Marvell International Ltd. - * Haojian Zhuang <haojian.zhuang@marvell.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef __LINUX_MFD_88PM8607_H -#define __LINUX_MFD_88PM8607_H - -enum { - PM8607_ID_BUCK1 = 0, - PM8607_ID_BUCK2, - PM8607_ID_BUCK3, - - PM8607_ID_LDO1, - PM8607_ID_LDO2, - PM8607_ID_LDO3, - PM8607_ID_LDO4, - PM8607_ID_LDO5, - PM8607_ID_LDO6, - PM8607_ID_LDO7, - PM8607_ID_LDO8, - PM8607_ID_LDO9, - PM8607_ID_LDO10, - PM8607_ID_LDO12, - PM8607_ID_LDO14, - - PM8607_ID_RG_MAX, -}; - -#define CHIP_ID (0x40) -#define CHIP_ID_MASK (0xF8) - -/* Interrupt Registers */ -#define PM8607_STATUS_1 (0x01) -#define PM8607_STATUS_2 (0x02) -#define PM8607_INT_STATUS1 (0x03) -#define PM8607_INT_STATUS2 (0x04) -#define PM8607_INT_STATUS3 (0x05) -#define PM8607_INT_MASK_1 (0x06) -#define PM8607_INT_MASK_2 (0x07) -#define PM8607_INT_MASK_3 (0x08) - -/* Regulator Control Registers */ -#define PM8607_LDO1 (0x10) -#define PM8607_LDO2 (0x11) -#define PM8607_LDO3 (0x12) -#define PM8607_LDO4 (0x13) -#define PM8607_LDO5 (0x14) -#define PM8607_LDO6 (0x15) -#define PM8607_LDO7 (0x16) -#define PM8607_LDO8 (0x17) -#define PM8607_LDO9 (0x18) -#define PM8607_LDO10 (0x19) -#define PM8607_LDO12 (0x1A) -#define PM8607_LDO14 (0x1B) -#define PM8607_SLEEP_MODE1 (0x1C) -#define PM8607_SLEEP_MODE2 (0x1D) -#define PM8607_SLEEP_MODE3 (0x1E) -#define PM8607_SLEEP_MODE4 (0x1F) -#define PM8607_GO (0x20) -#define PM8607_SLEEP_BUCK1 (0x21) -#define PM8607_SLEEP_BUCK2 (0x22) -#define PM8607_SLEEP_BUCK3 (0x23) -#define PM8607_BUCK1 (0x24) -#define PM8607_BUCK2 (0x25) -#define PM8607_BUCK3 (0x26) -#define PM8607_BUCK_CONTROLS (0x27) -#define PM8607_SUPPLIES_EN11 (0x2B) -#define PM8607_SUPPLIES_EN12 (0x2C) -#define PM8607_GROUP1 (0x2D) -#define PM8607_GROUP2 (0x2E) -#define PM8607_GROUP3 (0x2F) -#define PM8607_GROUP4 (0x30) -#define PM8607_GROUP5 (0x31) -#define PM8607_GROUP6 (0x32) -#define PM8607_SUPPLIES_EN21 (0x33) -#define PM8607_SUPPLIES_EN22 (0x34) - -/* RTC Control Registers */ -#define PM8607_RTC1 (0xA0) -#define PM8607_RTC_COUNTER1 (0xA1) -#define PM8607_RTC_COUNTER2 (0xA2) -#define PM8607_RTC_COUNTER3 (0xA3) -#define PM8607_RTC_COUNTER4 (0xA4) -#define PM8607_RTC_EXPIRE1 (0xA5) -#define PM8607_RTC_EXPIRE2 (0xA6) -#define PM8607_RTC_EXPIRE3 (0xA7) -#define PM8607_RTC_EXPIRE4 (0xA8) -#define PM8607_RTC_TRIM1 (0xA9) -#define PM8607_RTC_TRIM2 (0xAA) -#define PM8607_RTC_TRIM3 (0xAB) -#define PM8607_RTC_TRIM4 (0xAC) -#define PM8607_RTC_MISC1 (0xAD) -#define PM8607_RTC_MISC2 (0xAE) -#define PM8607_RTC_MISC3 (0xAF) - -/* Misc Registers */ -#define PM8607_CHIP_ID (0x00) -#define PM8607_LDO1 (0x10) -#define PM8607_DVC3 (0x26) -#define PM8607_MISC1 (0x40) - -/* bit definitions for PM8607 events */ -#define PM8607_EVENT_ONKEY (1 << 0) -#define PM8607_EVENT_EXTON (1 << 1) -#define PM8607_EVENT_CHG (1 << 2) -#define PM8607_EVENT_BAT (1 << 3) -#define PM8607_EVENT_RTC (1 << 4) -#define PM8607_EVENT_CC (1 << 5) -#define PM8607_EVENT_VBAT (1 << 8) -#define PM8607_EVENT_VCHG (1 << 9) -#define PM8607_EVENT_VSYS (1 << 10) -#define PM8607_EVENT_TINT (1 << 11) -#define PM8607_EVENT_GPADC0 (1 << 12) -#define PM8607_EVENT_GPADC1 (1 << 13) -#define PM8607_EVENT_GPADC2 (1 << 14) -#define PM8607_EVENT_GPADC3 (1 << 15) -#define PM8607_EVENT_AUDIO_SHORT (1 << 16) -#define PM8607_EVENT_PEN (1 << 17) -#define PM8607_EVENT_HEADSET (1 << 18) -#define PM8607_EVENT_HOOK (1 << 19) -#define PM8607_EVENT_MICIN (1 << 20) -#define PM8607_EVENT_CHG_TIMEOUT (1 << 21) -#define PM8607_EVENT_CHG_DONE (1 << 22) -#define PM8607_EVENT_CHG_FAULT (1 << 23) - -/* bit definitions of Status Query Interface */ -#define PM8607_STATUS_CC (1 << 3) -#define PM8607_STATUS_PEN (1 << 4) -#define PM8607_STATUS_HEADSET (1 << 5) -#define PM8607_STATUS_HOOK (1 << 6) -#define PM8607_STATUS_MICIN (1 << 7) -#define PM8607_STATUS_ONKEY (1 << 8) -#define PM8607_STATUS_EXTON (1 << 9) -#define PM8607_STATUS_CHG (1 << 10) -#define PM8607_STATUS_BAT (1 << 11) -#define PM8607_STATUS_VBUS (1 << 12) -#define PM8607_STATUS_OV (1 << 13) - -/* bit definitions of BUCK3 */ -#define PM8607_BUCK3_DOUBLE (1 << 6) - -/* bit definitions of Misc1 */ -#define PM8607_MISC1_PI2C (1 << 0) - -/* Interrupt Number in 88PM8607 */ -enum { - PM8607_IRQ_ONKEY = 0, - PM8607_IRQ_EXTON, - PM8607_IRQ_CHG, - PM8607_IRQ_BAT, - PM8607_IRQ_RTC, - PM8607_IRQ_VBAT = 8, - PM8607_IRQ_VCHG, - PM8607_IRQ_VSYS, - PM8607_IRQ_TINT, - PM8607_IRQ_GPADC0, - PM8607_IRQ_GPADC1, - PM8607_IRQ_GPADC2, - PM8607_IRQ_GPADC3, - PM8607_IRQ_AUDIO_SHORT = 16, - PM8607_IRQ_PEN, - PM8607_IRQ_HEADSET, - PM8607_IRQ_HOOK, - PM8607_IRQ_MICIN, - PM8607_IRQ_CHG_FAIL, - PM8607_IRQ_CHG_DONE, - PM8607_IRQ_CHG_FAULT, -}; - -enum { - PM8607_CHIP_A0 = 0x40, - PM8607_CHIP_A1 = 0x41, - PM8607_CHIP_B0 = 0x48, -}; - - -struct pm8607_chip { - struct device *dev; - struct mutex io_lock; - struct i2c_client *client; - - int (*read)(struct pm8607_chip *chip, int reg, int bytes, void *dest); - int (*write)(struct pm8607_chip *chip, int reg, int bytes, void *src); - - int buck3_double; /* DVC ramp slope double */ - unsigned char chip_id; - -}; - -#define PM8607_MAX_REGULATOR 15 /* 3 Bucks, 12 LDOs */ - -enum { - GI2C_PORT = 0, - PI2C_PORT, -}; - -struct pm8607_platform_data { - int i2c_port; /* Controlled by GI2C or PI2C */ - struct regulator_init_data *regulator[PM8607_MAX_REGULATOR]; -}; - -extern int pm8607_reg_read(struct pm8607_chip *, int); -extern int pm8607_reg_write(struct pm8607_chip *, int, unsigned char); -extern int pm8607_bulk_read(struct pm8607_chip *, int, int, - unsigned char *); -extern int pm8607_bulk_write(struct pm8607_chip *, int, int, - unsigned char *); -extern int pm8607_set_bits(struct pm8607_chip *, int, unsigned char, - unsigned char); -#endif /* __LINUX_MFD_88PM8607_H */ diff --git a/include/linux/mfd/88pm860x.h b/include/linux/mfd/88pm860x.h new file mode 100644 index 0000000..73f92c5 --- /dev/null +++ b/include/linux/mfd/88pm860x.h @@ -0,0 +1,375 @@ +/* + * Marvell 88PM860x Interface + * + * Copyright (C) 2009 Marvell International Ltd. + * Haojian Zhuang <haojian.zhuang@marvell.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __LINUX_MFD_88PM860X_H +#define __LINUX_MFD_88PM860X_H + +#include <linux/interrupt.h> + +#define MFD_NAME_SIZE (40) + +enum { + CHIP_INVALID = 0, + CHIP_PM8606, + CHIP_PM8607, + CHIP_MAX, +}; + +enum { + PM8606_ID_INVALID, + PM8606_ID_BACKLIGHT, + PM8606_ID_LED, + PM8606_ID_VIBRATOR, + PM8606_ID_TOUCH, + PM8606_ID_SOUND, + PM8606_ID_CHARGER, + PM8606_ID_MAX, +}; + +enum { + PM8606_BACKLIGHT1 = 0, + PM8606_BACKLIGHT2, + PM8606_BACKLIGHT3, +}; + +enum { + PM8606_LED1_RED = 0, + PM8606_LED1_GREEN, + PM8606_LED1_BLUE, + PM8606_LED2_RED, + PM8606_LED2_GREEN, + PM8606_LED2_BLUE, + PM8607_LED_VIBRATOR, +}; + + +/* 8606 Registers */ +#define PM8606_DCM_BOOST (0x00) +#define PM8606_PWM (0x01) + +/* Backlight Registers */ +#define PM8606_WLED1A (0x02) +#define PM8606_WLED1B (0x03) +#define PM8606_WLED2A (0x04) +#define PM8606_WLED2B (0x05) +#define PM8606_WLED3A (0x06) +#define PM8606_WLED3B (0x07) + +/* LED Registers */ +#define PM8606_RGB2A (0x08) +#define PM8606_RGB2B (0x09) +#define PM8606_RGB2C (0x0A) +#define PM8606_RGB2D (0x0B) +#define PM8606_RGB1A (0x0C) +#define PM8606_RGB1B (0x0D) +#define PM8606_RGB1C (0x0E) +#define PM8606_RGB1D (0x0F) + +#define PM8606_PREREGULATORA (0x10) +#define PM8606_PREREGULATORB (0x11) +#define PM8606_VIBRATORA (0x12) +#define PM8606_VIBRATORB (0x13) +#define PM8606_VCHG (0x14) +#define PM8606_VSYS (0x15) +#define PM8606_MISC (0x16) +#define PM8606_CHIP_ID (0x17) +#define PM8606_STATUS (0x18) +#define PM8606_FLAGS (0x19) +#define PM8606_PROTECTA (0x1A) +#define PM8606_PROTECTB (0x1B) +#define PM8606_PROTECTC (0x1C) + +/* Bit definitions of PM8606 registers */ +#define PM8606_DCM_500MA (0x0) /* current limit */ +#define PM8606_DCM_750MA (0x1) +#define PM8606_DCM_1000MA (0x2) +#define PM8606_DCM_1250MA (0x3) +#define PM8606_DCM_250MV (0x0 << 2) +#define PM8606_DCM_300MV (0x1 << 2) +#define PM8606_DCM_350MV (0x2 << 2) +#define PM8606_DCM_400MV (0x3 << 2) + +#define PM8606_PWM_31200HZ (0x0) +#define PM8606_PWM_15600HZ (0x1) +#define PM8606_PWM_7800HZ (0x2) +#define PM8606_PWM_3900HZ (0x3) +#define PM8606_PWM_1950HZ (0x4) +#define PM8606_PWM_976HZ (0x5) +#define PM8606_PWM_488HZ (0x6) +#define PM8606_PWM_244HZ (0x7) +#define PM8606_PWM_FREQ_MASK (0x7) + +#define PM8606_WLED_ON (1 << 0) +#define PM8606_WLED_CURRENT(x) ((x & 0x1F) << 1) + +#define PM8606_LED_CURRENT(x) (((x >> 2) & 0x07) << 5) + +#define PM8606_VSYS_EN (1 << 1) + +#define PM8606_MISC_OSC_EN (1 << 4) + +enum { + PM8607_ID_BUCK1 = 0, + PM8607_ID_BUCK2, + PM8607_ID_BUCK3, + + PM8607_ID_LDO1, + PM8607_ID_LDO2, + PM8607_ID_LDO3, + PM8607_ID_LDO4, + PM8607_ID_LDO5, + PM8607_ID_LDO6, + PM8607_ID_LDO7, + PM8607_ID_LDO8, + PM8607_ID_LDO9, + PM8607_ID_LDO10, + PM8607_ID_LDO12, + PM8607_ID_LDO14, + + PM8607_ID_RG_MAX, +}; + +#define PM8607_VERSION (0x40) /* 8607 chip ID */ +#define PM8607_VERSION_MASK (0xF0) /* 8607 chip ID mask */ + +/* Interrupt Registers */ +#define PM8607_STATUS_1 (0x01) +#define PM8607_STATUS_2 (0x02) +#define PM8607_INT_STATUS1 (0x03) +#define PM8607_INT_STATUS2 (0x04) +#define PM8607_INT_STATUS3 (0x05) +#define PM8607_INT_MASK_1 (0x06) +#define PM8607_INT_MASK_2 (0x07) +#define PM8607_INT_MASK_3 (0x08) + +/* Regulator Control Registers */ +#define PM8607_LDO1 (0x10) +#define PM8607_LDO2 (0x11) +#define PM8607_LDO3 (0x12) +#define PM8607_LDO4 (0x13) +#define PM8607_LDO5 (0x14) +#define PM8607_LDO6 (0x15) +#define PM8607_LDO7 (0x16) +#define PM8607_LDO8 (0x17) +#define PM8607_LDO9 (0x18) +#define PM8607_LDO10 (0x19) +#define PM8607_LDO12 (0x1A) +#define PM8607_LDO14 (0x1B) +#define PM8607_SLEEP_MODE1 (0x1C) +#define PM8607_SLEEP_MODE2 (0x1D) +#define PM8607_SLEEP_MODE3 (0x1E) +#define PM8607_SLEEP_MODE4 (0x1F) +#define PM8607_GO (0x20) +#define PM8607_SLEEP_BUCK1 (0x21) +#define PM8607_SLEEP_BUCK2 (0x22) +#define PM8607_SLEEP_BUCK3 (0x23) +#define PM8607_BUCK1 (0x24) +#define PM8607_BUCK2 (0x25) +#define PM8607_BUCK3 (0x26) +#define PM8607_BUCK_CONTROLS (0x27) +#define PM8607_SUPPLIES_EN11 (0x2B) +#define PM8607_SUPPLIES_EN12 (0x2C) +#define PM8607_GROUP1 (0x2D) +#define PM8607_GROUP2 (0x2E) +#define PM8607_GROUP3 (0x2F) +#define PM8607_GROUP4 (0x30) +#define PM8607_GROUP5 (0x31) +#define PM8607_GROUP6 (0x32) +#define PM8607_SUPPLIES_EN21 (0x33) +#define PM8607_SUPPLIES_EN22 (0x34) + +/* Vibrator Control Registers */ +#define PM8607_VIBRATOR_SET (0x28) +#define PM8607_VIBRATOR_PWM (0x29) + +/* GPADC Registers */ +#define PM8607_GP_BIAS1 (0x4F) +#define PM8607_MEAS_EN1 (0x50) +#define PM8607_MEAS_EN2 (0x51) +#define PM8607_MEAS_EN3 (0x52) +#define PM8607_MEAS_OFF_TIME1 (0x53) +#define PM8607_MEAS_OFF_TIME2 (0x54) +#define PM8607_TSI_PREBIAS (0x55) /* prebias time */ +#define PM8607_PD_PREBIAS (0x56) /* prebias time */ +#define PM8607_GPADC_MISC1 (0x57) + +/* RTC Control Registers */ +#define PM8607_RTC1 (0xA0) +#define PM8607_RTC_COUNTER1 (0xA1) +#define PM8607_RTC_COUNTER2 (0xA2) +#define PM8607_RTC_COUNTER3 (0xA3) +#define PM8607_RTC_COUNTER4 (0xA4) +#define PM8607_RTC_EXPIRE1 (0xA5) +#define PM8607_RTC_EXPIRE2 (0xA6) +#define PM8607_RTC_EXPIRE3 (0xA7) +#define PM8607_RTC_EXPIRE4 (0xA8) +#define PM8607_RTC_TRIM1 (0xA9) +#define PM8607_RTC_TRIM2 (0xAA) +#define PM8607_RTC_TRIM3 (0xAB) +#define PM8607_RTC_TRIM4 (0xAC) +#define PM8607_RTC_MISC1 (0xAD) +#define PM8607_RTC_MISC2 (0xAE) +#define PM8607_RTC_MISC3 (0xAF) + +/* Misc Registers */ +#define PM8607_CHIP_ID (0x00) +#define PM8607_B0_MISC1 (0x0C) +#define PM8607_LDO1 (0x10) +#define PM8607_DVC3 (0x26) +#define PM8607_A1_MISC1 (0x40) + +/* bit definitions of Status Query Interface */ +#define PM8607_STATUS_CC (1 << 3) +#define PM8607_STATUS_PEN (1 << 4) +#define PM8607_STATUS_HEADSET (1 << 5) +#define PM8607_STATUS_HOOK (1 << 6) +#define PM8607_STATUS_MICIN (1 << 7) +#define PM8607_STATUS_ONKEY (1 << 8) +#define PM8607_STATUS_EXTON (1 << 9) +#define PM8607_STATUS_CHG (1 << 10) +#define PM8607_STATUS_BAT (1 << 11) +#define PM8607_STATUS_VBUS (1 << 12) +#define PM8607_STATUS_OV (1 << 13) + +/* bit definitions of BUCK3 */ +#define PM8607_BUCK3_DOUBLE (1 << 6) + +/* bit definitions of Misc1 */ +#define PM8607_A1_MISC1_PI2C (1 << 0) +#define PM8607_B0_MISC1_INV_INT (1 << 0) +#define PM8607_B0_MISC1_INT_CLEAR (1 << 1) +#define PM8607_B0_MISC1_INT_MASK (1 << 2) +#define PM8607_B0_MISC1_PI2C (1 << 3) +#define PM8607_B0_MISC1_RESET (1 << 6) + +/* bits definitions of GPADC */ +#define PM8607_GPADC_EN (1 << 0) +#define PM8607_GPADC_PREBIAS_MASK (3 << 1) +#define PM8607_GPADC_SLOT_CYCLE_MASK (3 << 3) /* slow mode */ +#define PM8607_GPADC_OFF_SCALE_MASK (3 << 5) /* GP sleep mode */ +#define PM8607_GPADC_SW_CAL_MASK (1 << 7) + +#define PM8607_PD_PREBIAS_MASK (0x1F << 0) +#define PM8607_PD_PRECHG_MASK (7 << 5) + +/* Interrupt Number in 88PM8607 */ +enum { + PM8607_IRQ_ONKEY, + PM8607_IRQ_EXTON, + PM8607_IRQ_CHG, + PM8607_IRQ_BAT, + PM8607_IRQ_RTC, + PM8607_IRQ_CC, + PM8607_IRQ_VBAT, + PM8607_IRQ_VCHG, + PM8607_IRQ_VSYS, + PM8607_IRQ_TINT, + PM8607_IRQ_GPADC0, + PM8607_IRQ_GPADC1, + PM8607_IRQ_GPADC2, + PM8607_IRQ_GPADC3, + PM8607_IRQ_AUDIO_SHORT, + PM8607_IRQ_PEN, + PM8607_IRQ_HEADSET, + PM8607_IRQ_HOOK, + PM8607_IRQ_MICIN, + PM8607_IRQ_CHG_FAIL, + PM8607_IRQ_CHG_DONE, + PM8607_IRQ_CHG_FAULT, +}; + +enum { + PM8607_CHIP_A0 = 0x40, + PM8607_CHIP_A1 = 0x41, + PM8607_CHIP_B0 = 0x48, +}; + +struct pm860x_chip { + struct device *dev; + struct mutex io_lock; + struct mutex irq_lock; + struct i2c_client *client; + struct i2c_client *companion; /* companion chip client */ + + int buck3_double; /* DVC ramp slope double */ + unsigned short companion_addr; + int id; + int irq_mode; + int irq_base; + int core_irq; + unsigned char chip_version; + +}; + +#define PM8607_MAX_REGULATOR 15 /* 3 Bucks, 12 LDOs */ + +enum { + GI2C_PORT = 0, + PI2C_PORT, +}; + +struct pm860x_backlight_pdata { + int id; + int pwm; + int iset; + unsigned long flags; +}; + +struct pm860x_led_pdata { + int id; + int iset; + unsigned long flags; +}; + +struct pm860x_touch_pdata { + int gpadc_prebias; + int slot_cycle; + int off_scale; + int sw_cal; + int tsi_prebias; /* time, slot */ + int pen_prebias; /* time, slot */ + int pen_prechg; /* time, slot */ + int res_x; /* resistor of Xplate */ + unsigned long flags; +}; + +struct pm860x_power_pdata { + unsigned fast_charge; /* charge current */ +}; + +struct pm860x_platform_data { + struct pm860x_backlight_pdata *backlight; + struct pm860x_led_pdata *led; + struct pm860x_touch_pdata *touch; + struct pm860x_power_pdata *power; + + unsigned short companion_addr; /* I2C address of companion chip */ + int i2c_port; /* Controlled by GI2C or PI2C */ + int irq_mode; /* Clear interrupt by read/write(0/1) */ + int irq_base; /* IRQ base number of 88pm860x */ + struct regulator_init_data *regulator[PM8607_MAX_REGULATOR]; +}; + +extern char pm860x_backlight_name[][MFD_NAME_SIZE]; +extern char pm860x_led_name[][MFD_NAME_SIZE]; + +extern int pm860x_reg_read(struct i2c_client *, int); +extern int pm860x_reg_write(struct i2c_client *, int, unsigned char); +extern int pm860x_bulk_read(struct i2c_client *, int, int, unsigned char *); +extern int pm860x_bulk_write(struct i2c_client *, int, int, unsigned char *); +extern int pm860x_set_bits(struct i2c_client *, int, unsigned char, + unsigned char); + +extern int pm860x_device_init(struct pm860x_chip *chip, + struct pm860x_platform_data *pdata); +extern void pm860x_device_exit(struct pm860x_chip *chip); + +#endif /* __LINUX_MFD_88PM860X_H */ diff --git a/include/linux/mfd/ab3100.h b/include/linux/mfd/ab3100.h index e9aa4c9..9a881c3 100644 --- a/include/linux/mfd/ab3100.h +++ b/include/linux/mfd/ab3100.h @@ -6,7 +6,6 @@ */ #include <linux/device.h> -#include <linux/workqueue.h> #include <linux/regulator/machine.h> #ifndef MFD_AB3100_H @@ -74,7 +73,6 @@ * @testreg_client: secondary client for test registers * @chip_name: name of this chip variant * @chip_id: 8 bit chip ID for this chip variant - * @work: an event handling worker * @event_subscribers: event subscribers are listed here * @startup_events: a copy of the first reading of the event registers * @startup_events_read: whether the first events have been read @@ -90,7 +88,6 @@ struct ab3100 { struct i2c_client *testreg_client; char chip_name[32]; u8 chip_id; - struct work_struct work; struct blocking_notifier_head event_subscribers; u32 startup_events; bool startup_events_read; diff --git a/include/linux/mfd/max8925.h b/include/linux/mfd/max8925.h new file mode 100644 index 0000000..5259dfe --- /dev/null +++ b/include/linux/mfd/max8925.h @@ -0,0 +1,253 @@ +/* + * Maxim8925 Interface + * + * Copyright (C) 2009 Marvell International Ltd. + * Haojian Zhuang <haojian.zhuang@marvell.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __LINUX_MFD_MAX8925_H +#define __LINUX_MFD_MAX8925_H + +#include <linux/mutex.h> +#include <linux/interrupt.h> + +/* Unified sub device IDs for MAX8925 */ +enum { + MAX8925_ID_SD1, + MAX8925_ID_SD2, + MAX8925_ID_SD3, + MAX8925_ID_LDO1, + MAX8925_ID_LDO2, + MAX8925_ID_LDO3, + MAX8925_ID_LDO4, + MAX8925_ID_LDO5, + MAX8925_ID_LDO6, + MAX8925_ID_LDO7, + MAX8925_ID_LDO8, + MAX8925_ID_LDO9, + MAX8925_ID_LDO10, + MAX8925_ID_LDO11, + MAX8925_ID_LDO12, + MAX8925_ID_LDO13, + MAX8925_ID_LDO14, + MAX8925_ID_LDO15, + MAX8925_ID_LDO16, + MAX8925_ID_LDO17, + MAX8925_ID_LDO18, + MAX8925_ID_LDO19, + MAX8925_ID_LDO20, + MAX8925_ID_MAX, +}; + +enum { + /* + * Charging current threshold trigger going from fast charge + * to TOPOFF charge. From 5% to 20% of fasting charging current. + */ + MAX8925_TOPOFF_THR_5PER, + MAX8925_TOPOFF_THR_10PER, + MAX8925_TOPOFF_THR_15PER, + MAX8925_TOPOFF_THR_20PER, +}; + +enum { + /* Fast charging current */ + MAX8925_FCHG_85MA, + MAX8925_FCHG_300MA, + MAX8925_FCHG_460MA, + MAX8925_FCHG_600MA, + MAX8925_FCHG_700MA, + MAX8925_FCHG_800MA, + MAX8925_FCHG_900MA, + MAX8925_FCHG_1000MA, +}; + +/* Charger registers */ +#define MAX8925_CHG_IRQ1 (0x7e) +#define MAX8925_CHG_IRQ2 (0x7f) +#define MAX8925_CHG_IRQ1_MASK (0x80) +#define MAX8925_CHG_IRQ2_MASK (0x81) +#define MAX8925_CHG_STATUS (0x82) + +/* GPM registers */ +#define MAX8925_SYSENSEL (0x00) +#define MAX8925_ON_OFF_IRQ1 (0x01) +#define MAX8925_ON_OFF_IRQ1_MASK (0x02) +#define MAX8925_ON_OFF_STATUS (0x03) +#define MAX8925_ON_OFF_IRQ2 (0x0d) +#define MAX8925_ON_OFF_IRQ2_MASK (0x0e) +#define MAX8925_RESET_CNFG (0x0f) + +/* Touch registers */ +#define MAX8925_TSC_IRQ (0x00) +#define MAX8925_TSC_IRQ_MASK (0x01) +#define MAX8925_TSC_CNFG1 (0x02) +#define MAX8925_ADC_SCHED (0x10) +#define MAX8925_ADC_RES_END (0x6f) + +#define MAX8925_NREF_OK (1 << 4) + +/* RTC registers */ +#define MAX8925_ALARM0_CNTL (0x18) +#define MAX8925_ALARM1_CNTL (0x19) +#define MAX8925_RTC_IRQ (0x1c) +#define MAX8925_RTC_IRQ_MASK (0x1d) +#define MAX8925_MPL_CNTL (0x1e) + +/* WLED registers */ +#define MAX8925_WLED_MODE_CNTL (0x84) +#define MAX8925_WLED_CNTL (0x85) + +/* MAX8925 Registers */ +#define MAX8925_SDCTL1 (0x04) +#define MAX8925_SDCTL2 (0x07) +#define MAX8925_SDCTL3 (0x0A) +#define MAX8925_SDV1 (0x06) +#define MAX8925_SDV2 (0x09) +#define MAX8925_SDV3 (0x0C) +#define MAX8925_LDOCTL1 (0x18) +#define MAX8925_LDOCTL2 (0x1C) +#define MAX8925_LDOCTL3 (0x20) +#define MAX8925_LDOCTL4 (0x24) +#define MAX8925_LDOCTL5 (0x28) +#define MAX8925_LDOCTL6 (0x2C) +#define MAX8925_LDOCTL7 (0x30) +#define MAX8925_LDOCTL8 (0x34) +#define MAX8925_LDOCTL9 (0x38) +#define MAX8925_LDOCTL10 (0x3C) +#define MAX8925_LDOCTL11 (0x40) +#define MAX8925_LDOCTL12 (0x44) +#define MAX8925_LDOCTL13 (0x48) +#define MAX8925_LDOCTL14 (0x4C) +#define MAX8925_LDOCTL15 (0x50) +#define MAX8925_LDOCTL16 (0x10) +#define MAX8925_LDOCTL17 (0x14) +#define MAX8925_LDOCTL18 (0x72) +#define MAX8925_LDOCTL19 (0x5C) +#define MAX8925_LDOCTL20 (0x9C) +#define MAX8925_LDOVOUT1 (0x1A) +#define MAX8925_LDOVOUT2 (0x1E) +#define MAX8925_LDOVOUT3 (0x22) +#define MAX8925_LDOVOUT4 (0x26) +#define MAX8925_LDOVOUT5 (0x2A) +#define MAX8925_LDOVOUT6 (0x2E) +#define MAX8925_LDOVOUT7 (0x32) +#define MAX8925_LDOVOUT8 (0x36) +#define MAX8925_LDOVOUT9 (0x3A) +#define MAX8925_LDOVOUT10 (0x3E) +#define MAX8925_LDOVOUT11 (0x42) +#define MAX8925_LDOVOUT12 (0x46) +#define MAX8925_LDOVOUT13 (0x4A) +#define MAX8925_LDOVOUT14 (0x4E) +#define MAX8925_LDOVOUT15 (0x52) +#define MAX8925_LDOVOUT16 (0x12) +#define MAX8925_LDOVOUT17 (0x16) +#define MAX8925_LDOVOUT18 (0x74) +#define MAX8925_LDOVOUT19 (0x5E) +#define MAX8925_LDOVOUT20 (0x9E) + +/* bit definitions */ +#define CHG_IRQ1_MASK (0x07) +#define CHG_IRQ2_MASK (0xff) +#define ON_OFF_IRQ1_MASK (0xff) +#define ON_OFF_IRQ2_MASK (0x03) +#define TSC_IRQ_MASK (0x03) +#define RTC_IRQ_MASK (0x0c) + +#define MAX8925_MAX_REGULATOR (23) + +#define MAX8925_NAME_SIZE (32) + +/* IRQ definitions */ +enum { + MAX8925_IRQ_VCHG_DC_OVP, + MAX8925_IRQ_VCHG_DC_F, + MAX8925_IRQ_VCHG_DC_R, + MAX8925_IRQ_VCHG_USB_OVP, + MAX8925_IRQ_VCHG_USB_F, + MAX8925_IRQ_VCHG_USB_R, + MAX8925_IRQ_VCHG_THM_OK_R, + MAX8925_IRQ_VCHG_THM_OK_F, + MAX8925_IRQ_VCHG_SYSLOW_F, + MAX8925_IRQ_VCHG_SYSLOW_R, + MAX8925_IRQ_VCHG_RST, + MAX8925_IRQ_VCHG_DONE, + MAX8925_IRQ_VCHG_TOPOFF, + MAX8925_IRQ_VCHG_TMR_FAULT, + MAX8925_IRQ_GPM_RSTIN, + MAX8925_IRQ_GPM_MPL, + MAX8925_IRQ_GPM_SW_3SEC, + MAX8925_IRQ_GPM_EXTON_F, + MAX8925_IRQ_GPM_EXTON_R, + MAX8925_IRQ_GPM_SW_1SEC, + MAX8925_IRQ_GPM_SW_F, + MAX8925_IRQ_GPM_SW_R, + MAX8925_IRQ_GPM_SYSCKEN_F, + MAX8925_IRQ_GPM_SYSCKEN_R, + MAX8925_IRQ_RTC_ALARM1, + MAX8925_IRQ_RTC_ALARM0, + MAX8925_IRQ_TSC_STICK, + MAX8925_IRQ_TSC_NSTICK, + MAX8925_NR_IRQS, +}; + +struct max8925_chip { + struct device *dev; + struct i2c_client *i2c; + struct i2c_client *adc; + struct i2c_client *rtc; + struct mutex io_lock; + struct mutex irq_lock; + + int irq_base; + int core_irq; + int tsc_irq; +}; + +struct max8925_backlight_pdata { + int lxw_scl; /* 0/1 -- 0.8Ohm/0.4Ohm */ + int lxw_freq; /* 700KHz ~ 1400KHz */ + int dual_string; /* 0/1 -- single/dual string */ +}; + +struct max8925_touch_pdata { + unsigned int flags; +}; + +struct max8925_power_pdata { + int (*set_charger)(int); + unsigned batt_detect:1; + unsigned topoff_threshold:2; + unsigned fast_charge:3; /* charge current */ +}; + +/* + * irq_base: stores IRQ base number of MAX8925 in platform + * tsc_irq: stores IRQ number of MAX8925 TSC + */ +struct max8925_platform_data { + struct max8925_backlight_pdata *backlight; + struct max8925_touch_pdata *touch; + struct max8925_power_pdata *power; + struct regulator_init_data *regulator[MAX8925_MAX_REGULATOR]; + + int irq_base; + int tsc_irq; +}; + +extern int max8925_reg_read(struct i2c_client *, int); +extern int max8925_reg_write(struct i2c_client *, int, unsigned char); +extern int max8925_bulk_read(struct i2c_client *, int, int, unsigned char *); +extern int max8925_bulk_write(struct i2c_client *, int, int, unsigned char *); +extern int max8925_set_bits(struct i2c_client *, int, unsigned char, + unsigned char); + +extern int max8925_device_init(struct max8925_chip *, + struct max8925_platform_data *); +extern void max8925_device_exit(struct max8925_chip *); +#endif /* __LINUX_MFD_MAX8925_H */ + diff --git a/include/linux/mfd/tmio.h b/include/linux/mfd/tmio.h index 9cb1834..c3f7dff 100644 --- a/include/linux/mfd/tmio.h +++ b/include/linux/mfd/tmio.h @@ -59,7 +59,8 @@ void tmio_core_mmc_clk_div(void __iomem *cnf, int shift, int state); * data for the MMC controller */ struct tmio_mmc_data { - const unsigned int hclk; + unsigned int hclk; + unsigned long capabilities; void (*set_pwr)(struct platform_device *host, int state); void (*set_clk_div)(struct platform_device *host, int state); }; diff --git a/include/linux/mfd/ucb1x00.h b/include/linux/mfd/ucb1x00.h index aa9c378..4321f04 100644 --- a/include/linux/mfd/ucb1x00.h +++ b/include/linux/mfd/ucb1x00.h @@ -12,6 +12,7 @@ #include <linux/mfd/mcp.h> #include <linux/gpio.h> +#include <linux/semaphore.h> #define UCB_IO_DATA 0x00 #define UCB_IO_DIR 0x01 diff --git a/include/linux/mfd/wm831x/core.h b/include/linux/mfd/wm831x/core.h index 5184b79..5915f6e 100644 --- a/include/linux/mfd/wm831x/core.h +++ b/include/linux/mfd/wm831x/core.h @@ -15,6 +15,7 @@ #ifndef __MFD_WM831X_CORE_H__ #define __MFD_WM831X_CORE_H__ +#include <linux/completion.h> #include <linux/interrupt.h> /* @@ -254,9 +255,14 @@ struct wm831x { int irq_masks_cur[WM831X_NUM_IRQ_REGS]; /* Currently active value */ int irq_masks_cache[WM831X_NUM_IRQ_REGS]; /* Cached hardware value */ + /* Chip revision based flags */ + unsigned has_gpio_ena:1; /* Has GPIO enable bit */ + unsigned has_cs_sts:1; /* Has current sink status bit */ + int num_gpio; struct mutex auxadc_lock; + struct completion auxadc_done; /* The WM831x has a security key blocking access to certain * registers. The mutex is taken by the accessors for locking diff --git a/include/linux/mfd/wm831x/gpio.h b/include/linux/mfd/wm831x/gpio.h index 2835614..9b163c5 100644 --- a/include/linux/mfd/wm831x/gpio.h +++ b/include/linux/mfd/wm831x/gpio.h @@ -41,6 +41,10 @@ #define WM831X_GPN_OD_MASK 0x0200 /* GPN_OD */ #define WM831X_GPN_OD_SHIFT 9 /* GPN_OD */ #define WM831X_GPN_OD_WIDTH 1 /* GPN_OD */ +#define WM831X_GPN_ENA 0x0080 /* GPN_ENA */ +#define WM831X_GPN_ENA_MASK 0x0080 /* GPN_ENA */ +#define WM831X_GPN_ENA_SHIFT 7 /* GPN_ENA */ +#define WM831X_GPN_ENA_WIDTH 1 /* GPN_ENA */ #define WM831X_GPN_TRI 0x0080 /* GPN_TRI */ #define WM831X_GPN_TRI_MASK 0x0080 /* GPN_TRI */ #define WM831X_GPN_TRI_SHIFT 7 /* GPN_TRI */ diff --git a/include/linux/mfd/wm8350/core.h b/include/linux/mfd/wm8350/core.h index 4386889..98fcc97 100644 --- a/include/linux/mfd/wm8350/core.h +++ b/include/linux/mfd/wm8350/core.h @@ -16,6 +16,7 @@ #include <linux/kernel.h> #include <linux/mutex.h> #include <linux/interrupt.h> +#include <linux/completion.h> #include <linux/mfd/wm8350/audio.h> #include <linux/mfd/wm8350/gpio.h> @@ -579,6 +580,8 @@ #define WM8350_NUM_IRQ 63 +#define WM8350_NUM_IRQ_REGS 7 + struct wm8350_reg_access { u16 readable; /* Mask of readable bits */ u16 writable; /* Mask of writable bits */ @@ -600,11 +603,6 @@ extern const u16 wm8352_mode3_defaults[]; struct wm8350; -struct wm8350_irq { - irq_handler_t handler; - void *data; -}; - struct wm8350_hwmon { struct platform_device *pdev; struct device *classdev; @@ -624,11 +622,13 @@ struct wm8350 { u16 *reg_cache; struct mutex auxadc_mutex; + struct completion auxadc_done; /* Interrupt handling */ - struct mutex irq_mutex; /* IRQ table mutex */ - struct wm8350_irq irq[WM8350_NUM_IRQ]; + struct mutex irq_lock; int chip_irq; + int irq_base; + u16 irq_masks[WM8350_NUM_IRQ_REGS]; /* Client devices */ struct wm8350_codec codec; @@ -647,11 +647,13 @@ struct wm8350 { * used by the platform to configure GPIO functions and similar. * @irq_high: Set if WM8350 IRQ is active high. * @irq_base: Base IRQ for genirq (not currently used). + * @gpio_base: Base for gpiolib. */ struct wm8350_platform_data { int (*init)(struct wm8350 *wm8350); int irq_high; int irq_base; + int gpio_base; }; @@ -677,12 +679,33 @@ int wm8350_block_write(struct wm8350 *wm8350, int reg, int size, u16 *src); /* * WM8350 internal interrupts */ -int wm8350_register_irq(struct wm8350 *wm8350, int irq, - irq_handler_t handler, unsigned long flags, - const char *name, void *data); -int wm8350_free_irq(struct wm8350 *wm8350, int irq); -int wm8350_mask_irq(struct wm8350 *wm8350, int irq); -int wm8350_unmask_irq(struct wm8350 *wm8350, int irq); +static inline int wm8350_register_irq(struct wm8350 *wm8350, int irq, + irq_handler_t handler, + unsigned long flags, + const char *name, void *data) +{ + if (!wm8350->irq_base) + return -ENODEV; + + return request_threaded_irq(irq + wm8350->irq_base, NULL, + handler, flags, name, data); +} + +static inline void wm8350_free_irq(struct wm8350 *wm8350, int irq, void *data) +{ + free_irq(irq + wm8350->irq_base, data); +} + +static inline void wm8350_mask_irq(struct wm8350 *wm8350, int irq) +{ + disable_irq(irq + wm8350->irq_base); +} + +static inline void wm8350_unmask_irq(struct wm8350 *wm8350, int irq) +{ + enable_irq(irq + wm8350->irq_base); +} + int wm8350_irq_init(struct wm8350 *wm8350, int irq, struct wm8350_platform_data *pdata); int wm8350_irq_exit(struct wm8350 *wm8350); diff --git a/include/linux/mfd/wm8350/gpio.h b/include/linux/mfd/wm8350/gpio.h index 71af3d6..d657bcd 100644 --- a/include/linux/mfd/wm8350/gpio.h +++ b/include/linux/mfd/wm8350/gpio.h @@ -29,6 +29,7 @@ #define WM8350_GPIO_FUNCTION_SELECT_2 0x8D #define WM8350_GPIO_FUNCTION_SELECT_3 0x8E #define WM8350_GPIO_FUNCTION_SELECT_4 0x8F +#define WM8350_GPIO_LEVEL 0xE6 /* * GPIO Functions diff --git a/include/linux/mfd/wm8350/rtc.h b/include/linux/mfd/wm8350/rtc.h index 24add2b..ebd72ff 100644 --- a/include/linux/mfd/wm8350/rtc.h +++ b/include/linux/mfd/wm8350/rtc.h @@ -263,6 +263,7 @@ struct wm8350_rtc { struct platform_device *pdev; struct rtc_device *rtc; int alarm_enabled; /* used over suspend/resume */ + int update_enabled; }; #endif diff --git a/include/linux/mfd/wm8994/core.h b/include/linux/mfd/wm8994/core.h new file mode 100644 index 0000000..b06ff28 --- /dev/null +++ b/include/linux/mfd/wm8994/core.h @@ -0,0 +1,54 @@ +/* + * include/linux/mfd/wm8994/core.h -- Core interface for WM8994 + * + * Copyright 2009 Wolfson Microelectronics PLC. + * + * Author: Mark Brown <broonie@opensource.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 __MFD_WM8994_CORE_H__ +#define __MFD_WM8994_CORE_H__ + +struct regulator_dev; +struct regulator_bulk_data; + +#define WM8994_NUM_GPIO_REGS 11 +#define WM8994_NUM_LDO_REGS 2 + +struct wm8994 { + struct mutex io_lock; + + struct device *dev; + int (*read_dev)(struct wm8994 *wm8994, unsigned short reg, + int bytes, void *dest); + int (*write_dev)(struct wm8994 *wm8994, unsigned short reg, + int bytes, void *src); + + void *control_data; + + int gpio_base; + + /* Used over suspend/resume */ + u16 ldo_regs[WM8994_NUM_LDO_REGS]; + u16 gpio_regs[WM8994_NUM_GPIO_REGS]; + + struct regulator_dev *dbvdd; + struct regulator_bulk_data *supplies; +}; + +/* Device I/O API */ +int wm8994_reg_read(struct wm8994 *wm8994, unsigned short reg); +int wm8994_reg_write(struct wm8994 *wm8994, unsigned short reg, + unsigned short val); +int wm8994_set_bits(struct wm8994 *wm8994, unsigned short reg, + unsigned short mask, unsigned short val); +int wm8994_bulk_read(struct wm8994 *wm8994, unsigned short reg, + int count, u16 *buf); + +#endif diff --git a/include/linux/mfd/wm8994/gpio.h b/include/linux/mfd/wm8994/gpio.h new file mode 100644 index 0000000..b4d4c22 --- /dev/null +++ b/include/linux/mfd/wm8994/gpio.h @@ -0,0 +1,72 @@ +/* + * include/linux/mfd/wm8994/gpio.h - GPIO configuration for WM8994 + * + * Copyright 2009 Wolfson Microelectronics PLC. + * + * Author: Mark Brown <broonie@opensource.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 __MFD_WM8994_GPIO_H__ +#define __MFD_WM8994_GPIO_H__ + +#define WM8994_GPIO_MAX 11 + +#define WM8994_GP_FN_PIN_SPECIFIC 0 +#define WM8994_GP_FN_GPIO 1 +#define WM8994_GP_FN_SDOUT 2 +#define WM8994_GP_FN_IRQ 3 +#define WM8994_GP_FN_TEMPERATURE 4 +#define WM8994_GP_FN_MICBIAS1_DET 5 +#define WM8994_GP_FN_MICBIAS1_SHORT 6 +#define WM8994_GP_FN_MICBIAS2_DET 7 +#define WM8994_GP_FN_MICBIAS2_SHORT 8 +#define WM8994_GP_FN_FLL1_LOCK 9 +#define WM8994_GP_FN_FLL2_LOCK 10 +#define WM8994_GP_FN_SRC1_LOCK 11 +#define WM8994_GP_FN_SRC2_LOCK 12 +#define WM8994_GP_FN_DRC1_ACT 13 +#define WM8994_GP_FN_DRC2_ACT 14 +#define WM8994_GP_FN_DRC3_ACT 15 +#define WM8994_GP_FN_WSEQ_STATUS 16 +#define WM8994_GP_FN_FIFO_ERROR 17 +#define WM8994_GP_FN_OPCLK 18 + +#define WM8994_GPN_DIR 0x8000 /* GPN_DIR */ +#define WM8994_GPN_DIR_MASK 0x8000 /* GPN_DIR */ +#define WM8994_GPN_DIR_SHIFT 15 /* GPN_DIR */ +#define WM8994_GPN_DIR_WIDTH 1 /* GPN_DIR */ +#define WM8994_GPN_PU 0x4000 /* GPN_PU */ +#define WM8994_GPN_PU_MASK 0x4000 /* GPN_PU */ +#define WM8994_GPN_PU_SHIFT 14 /* GPN_PU */ +#define WM8994_GPN_PU_WIDTH 1 /* GPN_PU */ +#define WM8994_GPN_PD 0x2000 /* GPN_PD */ +#define WM8994_GPN_PD_MASK 0x2000 /* GPN_PD */ +#define WM8994_GPN_PD_SHIFT 13 /* GPN_PD */ +#define WM8994_GPN_PD_WIDTH 1 /* GPN_PD */ +#define WM8994_GPN_POL 0x0400 /* GPN_POL */ +#define WM8994_GPN_POL_MASK 0x0400 /* GPN_POL */ +#define WM8994_GPN_POL_SHIFT 10 /* GPN_POL */ +#define WM8994_GPN_POL_WIDTH 1 /* GPN_POL */ +#define WM8994_GPN_OP_CFG 0x0200 /* GPN_OP_CFG */ +#define WM8994_GPN_OP_CFG_MASK 0x0200 /* GPN_OP_CFG */ +#define WM8994_GPN_OP_CFG_SHIFT 9 /* GPN_OP_CFG */ +#define WM8994_GPN_OP_CFG_WIDTH 1 /* GPN_OP_CFG */ +#define WM8994_GPN_DB 0x0100 /* GPN_DB */ +#define WM8994_GPN_DB_MASK 0x0100 /* GPN_DB */ +#define WM8994_GPN_DB_SHIFT 8 /* GPN_DB */ +#define WM8994_GPN_DB_WIDTH 1 /* GPN_DB */ +#define WM8994_GPN_LVL 0x0040 /* GPN_LVL */ +#define WM8994_GPN_LVL_MASK 0x0040 /* GPN_LVL */ +#define WM8994_GPN_LVL_SHIFT 6 /* GPN_LVL */ +#define WM8994_GPN_LVL_WIDTH 1 /* GPN_LVL */ +#define WM8994_GPN_FN_MASK 0x001F /* GPN_FN - [4:0] */ +#define WM8994_GPN_FN_SHIFT 0 /* GPN_FN - [4:0] */ +#define WM8994_GPN_FN_WIDTH 5 /* GPN_FN - [4:0] */ + +#endif diff --git a/include/linux/mfd/wm8994/pdata.h b/include/linux/mfd/wm8994/pdata.h new file mode 100644 index 0000000..70d6a86 --- /dev/null +++ b/include/linux/mfd/wm8994/pdata.h @@ -0,0 +1,97 @@ +/* + * include/linux/mfd/wm8994/pdata.h -- Platform data for WM8994 + * + * Copyright 2009 Wolfson Microelectronics PLC. + * + * Author: Mark Brown <broonie@opensource.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 __MFD_WM8994_PDATA_H__ +#define __MFD_WM8994_PDATA_H__ + +#define WM8994_NUM_LDO 2 +#define WM8994_NUM_GPIO 11 + +struct wm8994_ldo_pdata { + /** GPIOs to enable regulator, 0 or less if not available */ + int enable; + + const char *supply; + struct regulator_init_data *init_data; +}; + +#define WM8994_CONFIGURE_GPIO 0x8000 + +#define WM8994_DRC_REGS 5 +#define WM8994_EQ_REGS 19 + +/** + * DRC configurations are specified with a label and a set of register + * values to write (the enable bits will be ignored). At runtime an + * enumerated control will be presented for each DRC block allowing + * the user to choose the configration to use. + * + * Configurations may be generated by hand or by using the DRC control + * panel provided by the WISCE - see http://www.wolfsonmicro.com/wisce/ + * for details. + */ +struct wm8994_drc_cfg { + const char *name; + u16 regs[WM8994_DRC_REGS]; +}; + +/** + * ReTune Mobile configurations are specified with a label, sample + * rate and set of values to write (the enable bits will be ignored). + * + * Configurations are expected to be generated using the ReTune Mobile + * control panel in WISCE - see http://www.wolfsonmicro.com/wisce/ + */ +struct wm8994_retune_mobile_cfg { + const char *name; + unsigned int rate; + u16 regs[WM8994_EQ_REGS]; +}; + +struct wm8994_pdata { + int gpio_base; + + /** + * Default values for GPIOs if non-zero, WM8994_CONFIGURE_GPIO + * can be used for all zero values. + */ + int gpio_defaults[WM8994_NUM_GPIO]; + + struct wm8994_ldo_pdata ldo[WM8994_NUM_LDO]; + + + int num_drc_cfgs; + struct wm8994_drc_cfg *drc_cfgs; + + int num_retune_mobile_cfgs; + struct wm8994_retune_mobile_cfg *retune_mobile_cfgs; + + /* LINEOUT can be differential or single ended */ + unsigned int lineout1_diff:1; + unsigned int lineout2_diff:1; + + /* Common mode feedback */ + unsigned int lineout1fb:1; + unsigned int lineout2fb:1; + + /* Microphone biases: 0=0.9*AVDD1 1=0.65*AVVD1 */ + unsigned int micbias1_lvl:1; + unsigned int micbias2_lvl:1; + + /* Jack detect threashold levels, see datasheet for values */ + unsigned int jd_scthr:2; + unsigned int jd_thr:2; +}; + +#endif diff --git a/include/linux/mfd/wm8994/registers.h b/include/linux/mfd/wm8994/registers.h new file mode 100644 index 0000000..967f62f --- /dev/null +++ b/include/linux/mfd/wm8994/registers.h @@ -0,0 +1,4292 @@ +/* + * include/linux/mfd/wm8994/registers.h -- Register definitions for WM8994 + * + * Copyright 2009 Wolfson Microelectronics PLC. + * + * Author: Mark Brown <broonie@opensource.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 __MFD_WM8994_REGISTERS_H__ +#define __MFD_WM8994_REGISTERS_H__ + +/* + * Register values. + */ +#define WM8994_SOFTWARE_RESET 0x00 +#define WM8994_POWER_MANAGEMENT_1 0x01 +#define WM8994_POWER_MANAGEMENT_2 0x02 +#define WM8994_POWER_MANAGEMENT_3 0x03 +#define WM8994_POWER_MANAGEMENT_4 0x04 +#define WM8994_POWER_MANAGEMENT_5 0x05 +#define WM8994_POWER_MANAGEMENT_6 0x06 +#define WM8994_INPUT_MIXER_1 0x15 +#define WM8994_LEFT_LINE_INPUT_1_2_VOLUME 0x18 +#define WM8994_LEFT_LINE_INPUT_3_4_VOLUME 0x19 +#define WM8994_RIGHT_LINE_INPUT_1_2_VOLUME 0x1A +#define WM8994_RIGHT_LINE_INPUT_3_4_VOLUME 0x1B +#define WM8994_LEFT_OUTPUT_VOLUME 0x1C +#define WM8994_RIGHT_OUTPUT_VOLUME 0x1D +#define WM8994_LINE_OUTPUTS_VOLUME 0x1E +#define WM8994_HPOUT2_VOLUME 0x1F +#define WM8994_LEFT_OPGA_VOLUME 0x20 +#define WM8994_RIGHT_OPGA_VOLUME 0x21 +#define WM8994_SPKMIXL_ATTENUATION 0x22 +#define WM8994_SPKMIXR_ATTENUATION 0x23 +#define WM8994_SPKOUT_MIXERS 0x24 +#define WM8994_CLASSD 0x25 +#define WM8994_SPEAKER_VOLUME_LEFT 0x26 +#define WM8994_SPEAKER_VOLUME_RIGHT 0x27 +#define WM8994_INPUT_MIXER_2 0x28 +#define WM8994_INPUT_MIXER_3 0x29 +#define WM8994_INPUT_MIXER_4 0x2A +#define WM8994_INPUT_MIXER_5 0x2B +#define WM8994_INPUT_MIXER_6 0x2C +#define WM8994_OUTPUT_MIXER_1 0x2D +#define WM8994_OUTPUT_MIXER_2 0x2E +#define WM8994_OUTPUT_MIXER_3 0x2F +#define WM8994_OUTPUT_MIXER_4 0x30 +#define WM8994_OUTPUT_MIXER_5 0x31 +#define WM8994_OUTPUT_MIXER_6 0x32 +#define WM8994_HPOUT2_MIXER 0x33 +#define WM8994_LINE_MIXER_1 0x34 +#define WM8994_LINE_MIXER_2 0x35 +#define WM8994_SPEAKER_MIXER 0x36 +#define WM8994_ADDITIONAL_CONTROL 0x37 +#define WM8994_ANTIPOP_1 0x38 +#define WM8994_ANTIPOP_2 0x39 +#define WM8994_MICBIAS 0x3A +#define WM8994_LDO_1 0x3B +#define WM8994_LDO_2 0x3C +#define WM8994_CHARGE_PUMP_1 0x4C +#define WM8994_CLASS_W_1 0x51 +#define WM8994_DC_SERVO_1 0x54 +#define WM8994_DC_SERVO_2 0x55 +#define WM8994_DC_SERVO_4 0x57 +#define WM8994_DC_SERVO_READBACK 0x58 +#define WM8994_ANALOGUE_HP_1 0x60 +#define WM8994_CHIP_REVISION 0x100 +#define WM8994_CONTROL_INTERFACE 0x101 +#define WM8994_WRITE_SEQUENCER_CTRL_1 0x110 +#define WM8994_WRITE_SEQUENCER_CTRL_2 0x111 +#define WM8994_AIF1_CLOCKING_1 0x200 +#define WM8994_AIF1_CLOCKING_2 0x201 +#define WM8994_AIF2_CLOCKING_1 0x204 +#define WM8994_AIF2_CLOCKING_2 0x205 +#define WM8994_CLOCKING_1 0x208 +#define WM8994_CLOCKING_2 0x209 +#define WM8994_AIF1_RATE 0x210 +#define WM8994_AIF2_RATE 0x211 +#define WM8994_RATE_STATUS 0x212 +#define WM8994_FLL1_CONTROL_1 0x220 +#define WM8994_FLL1_CONTROL_2 0x221 +#define WM8994_FLL1_CONTROL_3 0x222 +#define WM8994_FLL1_CONTROL_4 0x223 +#define WM8994_FLL1_CONTROL_5 0x224 +#define WM8994_FLL2_CONTROL_1 0x240 +#define WM8994_FLL2_CONTROL_2 0x241 +#define WM8994_FLL2_CONTROL_3 0x242 +#define WM8994_FLL2_CONTROL_4 0x243 +#define WM8994_FLL2_CONTROL_5 0x244 +#define WM8994_AIF1_CONTROL_1 0x300 +#define WM8994_AIF1_CONTROL_2 0x301 +#define WM8994_AIF1_MASTER_SLAVE 0x302 +#define WM8994_AIF1_BCLK 0x303 +#define WM8994_AIF1ADC_LRCLK 0x304 +#define WM8994_AIF1DAC_LRCLK 0x305 +#define WM8994_AIF1DAC_DATA 0x306 +#define WM8994_AIF1ADC_DATA 0x307 +#define WM8994_AIF2_CONTROL_1 0x310 +#define WM8994_AIF2_CONTROL_2 0x311 +#define WM8994_AIF2_MASTER_SLAVE 0x312 +#define WM8994_AIF2_BCLK 0x313 +#define WM8994_AIF2ADC_LRCLK 0x314 +#define WM8994_AIF2DAC_LRCLK 0x315 +#define WM8994_AIF2DAC_DATA 0x316 +#define WM8994_AIF2ADC_DATA 0x317 +#define WM8994_AIF1_ADC1_LEFT_VOLUME 0x400 +#define WM8994_AIF1_ADC1_RIGHT_VOLUME 0x401 +#define WM8994_AIF1_DAC1_LEFT_VOLUME 0x402 +#define WM8994_AIF1_DAC1_RIGHT_VOLUME 0x403 +#define WM8994_AIF1_ADC2_LEFT_VOLUME 0x404 +#define WM8994_AIF1_ADC2_RIGHT_VOLUME 0x405 +#define WM8994_AIF1_DAC2_LEFT_VOLUME 0x406 +#define WM8994_AIF1_DAC2_RIGHT_VOLUME 0x407 +#define WM8994_AIF1_ADC1_FILTERS 0x410 +#define WM8994_AIF1_ADC2_FILTERS 0x411 +#define WM8994_AIF1_DAC1_FILTERS_1 0x420 +#define WM8994_AIF1_DAC1_FILTERS_2 0x421 +#define WM8994_AIF1_DAC2_FILTERS_1 0x422 +#define WM8994_AIF1_DAC2_FILTERS_2 0x423 +#define WM8994_AIF1_DRC1_1 0x440 +#define WM8994_AIF1_DRC1_2 0x441 +#define WM8994_AIF1_DRC1_3 0x442 +#define WM8994_AIF1_DRC1_4 0x443 +#define WM8994_AIF1_DRC1_5 0x444 +#define WM8994_AIF1_DRC2_1 0x450 +#define WM8994_AIF1_DRC2_2 0x451 +#define WM8994_AIF1_DRC2_3 0x452 +#define WM8994_AIF1_DRC2_4 0x453 +#define WM8994_AIF1_DRC2_5 0x454 +#define WM8994_AIF1_DAC1_EQ_GAINS_1 0x480 +#define WM8994_AIF1_DAC1_EQ_GAINS_2 0x481 +#define WM8994_AIF1_DAC1_EQ_BAND_1_A 0x482 +#define WM8994_AIF1_DAC1_EQ_BAND_1_B 0x483 +#define WM8994_AIF1_DAC1_EQ_BAND_1_PG 0x484 +#define WM8994_AIF1_DAC1_EQ_BAND_2_A 0x485 +#define WM8994_AIF1_DAC1_EQ_BAND_2_B 0x486 +#define WM8994_AIF1_DAC1_EQ_BAND_2_C 0x487 +#define WM8994_AIF1_DAC1_EQ_BAND_2_PG 0x488 +#define WM8994_AIF1_DAC1_EQ_BAND_3_A 0x489 +#define WM8994_AIF1_DAC1_EQ_BAND_3_B 0x48A +#define WM8994_AIF1_DAC1_EQ_BAND_3_C 0x48B +#define WM8994_AIF1_DAC1_EQ_BAND_3_PG 0x48C +#define WM8994_AIF1_DAC1_EQ_BAND_4_A 0x48D +#define WM8994_AIF1_DAC1_EQ_BAND_4_B 0x48E +#define WM8994_AIF1_DAC1_EQ_BAND_4_C 0x48F +#define WM8994_AIF1_DAC1_EQ_BAND_4_PG 0x490 +#define WM8994_AIF1_DAC1_EQ_BAND_5_A 0x491 +#define WM8994_AIF1_DAC1_EQ_BAND_5_B 0x492 +#define WM8994_AIF1_DAC1_EQ_BAND_5_PG 0x493 +#define WM8994_AIF1_DAC2_EQ_GAINS_1 0x4A0 +#define WM8994_AIF1_DAC2_EQ_GAINS_2 0x4A1 +#define WM8994_AIF1_DAC2_EQ_BAND_1_A 0x4A2 +#define WM8994_AIF1_DAC2_EQ_BAND_1_B 0x4A3 +#define WM8994_AIF1_DAC2_EQ_BAND_1_PG 0x4A4 +#define WM8994_AIF1_DAC2_EQ_BAND_2_A 0x4A5 +#define WM8994_AIF1_DAC2_EQ_BAND_2_B 0x4A6 +#define WM8994_AIF1_DAC2_EQ_BAND_2_C 0x4A7 +#define WM8994_AIF1_DAC2_EQ_BAND_2_PG 0x4A8 +#define WM8994_AIF1_DAC2_EQ_BAND_3_A 0x4A9 +#define WM8994_AIF1_DAC2_EQ_BAND_3_B 0x4AA +#define WM8994_AIF1_DAC2_EQ_BAND_3_C 0x4AB +#define WM8994_AIF1_DAC2_EQ_BAND_3_PG 0x4AC +#define WM8994_AIF1_DAC2_EQ_BAND_4_A 0x4AD +#define WM8994_AIF1_DAC2_EQ_BAND_4_B 0x4AE +#define WM8994_AIF1_DAC2_EQ_BAND_4_C 0x4AF +#define WM8994_AIF1_DAC2_EQ_BAND_4_PG 0x4B0 +#define WM8994_AIF1_DAC2_EQ_BAND_5_A 0x4B1 +#define WM8994_AIF1_DAC2_EQ_BAND_5_B 0x4B2 +#define WM8994_AIF1_DAC2_EQ_BAND_5_PG 0x4B3 +#define WM8994_AIF2_ADC_LEFT_VOLUME 0x500 +#define WM8994_AIF2_ADC_RIGHT_VOLUME 0x501 +#define WM8994_AIF2_DAC_LEFT_VOLUME 0x502 +#define WM8994_AIF2_DAC_RIGHT_VOLUME 0x503 +#define WM8994_AIF2_ADC_FILTERS 0x510 +#define WM8994_AIF2_DAC_FILTERS_1 0x520 +#define WM8994_AIF2_DAC_FILTERS_2 0x521 +#define WM8994_AIF2_DRC_1 0x540 +#define WM8994_AIF2_DRC_2 0x541 +#define WM8994_AIF2_DRC_3 0x542 +#define WM8994_AIF2_DRC_4 0x543 +#define WM8994_AIF2_DRC_5 0x544 +#define WM8994_AIF2_EQ_GAINS_1 0x580 +#define WM8994_AIF2_EQ_GAINS_2 0x581 +#define WM8994_AIF2_EQ_BAND_1_A 0x582 +#define WM8994_AIF2_EQ_BAND_1_B 0x583 +#define WM8994_AIF2_EQ_BAND_1_PG 0x584 +#define WM8994_AIF2_EQ_BAND_2_A 0x585 +#define WM8994_AIF2_EQ_BAND_2_B 0x586 +#define WM8994_AIF2_EQ_BAND_2_C 0x587 +#define WM8994_AIF2_EQ_BAND_2_PG 0x588 +#define WM8994_AIF2_EQ_BAND_3_A 0x589 +#define WM8994_AIF2_EQ_BAND_3_B 0x58A +#define WM8994_AIF2_EQ_BAND_3_C 0x58B +#define WM8994_AIF2_EQ_BAND_3_PG 0x58C +#define WM8994_AIF2_EQ_BAND_4_A 0x58D +#define WM8994_AIF2_EQ_BAND_4_B 0x58E +#define WM8994_AIF2_EQ_BAND_4_C 0x58F +#define WM8994_AIF2_EQ_BAND_4_PG 0x590 +#define WM8994_AIF2_EQ_BAND_5_A 0x591 +#define WM8994_AIF2_EQ_BAND_5_B 0x592 +#define WM8994_AIF2_EQ_BAND_5_PG 0x593 +#define WM8994_DAC1_MIXER_VOLUMES 0x600 +#define WM8994_DAC1_LEFT_MIXER_ROUTING 0x601 +#define WM8994_DAC1_RIGHT_MIXER_ROUTING 0x602 +#define WM8994_DAC2_MIXER_VOLUMES 0x603 +#define WM8994_DAC2_LEFT_MIXER_ROUTING 0x604 +#define WM8994_DAC2_RIGHT_MIXER_ROUTING 0x605 +#define WM8994_AIF1_ADC1_LEFT_MIXER_ROUTING 0x606 +#define WM8994_AIF1_ADC1_RIGHT_MIXER_ROUTING 0x607 +#define WM8994_AIF1_ADC2_LEFT_MIXER_ROUTING 0x608 +#define WM8994_AIF1_ADC2_RIGHT_MIXER_ROUTING 0x609 +#define WM8994_DAC1_LEFT_VOLUME 0x610 +#define WM8994_DAC1_RIGHT_VOLUME 0x611 +#define WM8994_DAC2_LEFT_VOLUME 0x612 +#define WM8994_DAC2_RIGHT_VOLUME 0x613 +#define WM8994_DAC_SOFTMUTE 0x614 +#define WM8994_OVERSAMPLING 0x620 +#define WM8994_SIDETONE 0x621 +#define WM8994_GPIO_1 0x700 +#define WM8994_GPIO_2 0x701 +#define WM8994_GPIO_3 0x702 +#define WM8994_GPIO_4 0x703 +#define WM8994_GPIO_5 0x704 +#define WM8994_GPIO_6 0x705 +#define WM8994_GPIO_7 0x706 +#define WM8994_GPIO_8 0x707 +#define WM8994_GPIO_9 0x708 +#define WM8994_GPIO_10 0x709 +#define WM8994_GPIO_11 0x70A +#define WM8994_PULL_CONTROL_1 0x720 +#define WM8994_PULL_CONTROL_2 0x721 +#define WM8994_INTERRUPT_STATUS_1 0x730 +#define WM8994_INTERRUPT_STATUS_2 0x731 +#define WM8994_INTERRUPT_RAW_STATUS_2 0x732 +#define WM8994_INTERRUPT_STATUS_1_MASK 0x738 +#define WM8994_INTERRUPT_STATUS_2_MASK 0x739 +#define WM8994_INTERRUPT_CONTROL 0x740 +#define WM8994_IRQ_DEBOUNCE 0x748 +#define WM8994_WRITE_SEQUENCER_0 0x3000 +#define WM8994_WRITE_SEQUENCER_1 0x3001 +#define WM8994_WRITE_SEQUENCER_2 0x3002 +#define WM8994_WRITE_SEQUENCER_3 0x3003 +#define WM8994_WRITE_SEQUENCER_4 0x3004 +#define WM8994_WRITE_SEQUENCER_5 0x3005 +#define WM8994_WRITE_SEQUENCER_6 0x3006 +#define WM8994_WRITE_SEQUENCER_7 0x3007 +#define WM8994_WRITE_SEQUENCER_8 0x3008 +#define WM8994_WRITE_SEQUENCER_9 0x3009 +#define WM8994_WRITE_SEQUENCER_10 0x300A +#define WM8994_WRITE_SEQUENCER_11 0x300B +#define WM8994_WRITE_SEQUENCER_12 0x300C +#define WM8994_WRITE_SEQUENCER_13 0x300D +#define WM8994_WRITE_SEQUENCER_14 0x300E +#define WM8994_WRITE_SEQUENCER_15 0x300F +#define WM8994_WRITE_SEQUENCER_16 0x3010 +#define WM8994_WRITE_SEQUENCER_17 0x3011 +#define WM8994_WRITE_SEQUENCER_18 0x3012 +#define WM8994_WRITE_SEQUENCER_19 0x3013 +#define WM8994_WRITE_SEQUENCER_20 0x3014 +#define WM8994_WRITE_SEQUENCER_21 0x3015 +#define WM8994_WRITE_SEQUENCER_22 0x3016 +#define WM8994_WRITE_SEQUENCER_23 0x3017 +#define WM8994_WRITE_SEQUENCER_24 0x3018 +#define WM8994_WRITE_SEQUENCER_25 0x3019 +#define WM8994_WRITE_SEQUENCER_26 0x301A +#define WM8994_WRITE_SEQUENCER_27 0x301B +#define WM8994_WRITE_SEQUENCER_28 0x301C +#define WM8994_WRITE_SEQUENCER_29 0x301D +#define WM8994_WRITE_SEQUENCER_30 0x301E +#define WM8994_WRITE_SEQUENCER_31 0x301F +#define WM8994_WRITE_SEQUENCER_32 0x3020 +#define WM8994_WRITE_SEQUENCER_33 0x3021 +#define WM8994_WRITE_SEQUENCER_34 0x3022 +#define WM8994_WRITE_SEQUENCER_35 0x3023 +#define WM8994_WRITE_SEQUENCER_36 0x3024 +#define WM8994_WRITE_SEQUENCER_37 0x3025 +#define WM8994_WRITE_SEQUENCER_38 0x3026 +#define WM8994_WRITE_SEQUENCER_39 0x3027 +#define WM8994_WRITE_SEQUENCER_40 0x3028 +#define WM8994_WRITE_SEQUENCER_41 0x3029 +#define WM8994_WRITE_SEQUENCER_42 0x302A +#define WM8994_WRITE_SEQUENCER_43 0x302B +#define WM8994_WRITE_SEQUENCER_44 0x302C +#define WM8994_WRITE_SEQUENCER_45 0x302D +#define WM8994_WRITE_SEQUENCER_46 0x302E +#define WM8994_WRITE_SEQUENCER_47 0x302F +#define WM8994_WRITE_SEQUENCER_48 0x3030 +#define WM8994_WRITE_SEQUENCER_49 0x3031 +#define WM8994_WRITE_SEQUENCER_50 0x3032 +#define WM8994_WRITE_SEQUENCER_51 0x3033 +#define WM8994_WRITE_SEQUENCER_52 0x3034 +#define WM8994_WRITE_SEQUENCER_53 0x3035 +#define WM8994_WRITE_SEQUENCER_54 0x3036 +#define WM8994_WRITE_SEQUENCER_55 0x3037 +#define WM8994_WRITE_SEQUENCER_56 0x3038 +#define WM8994_WRITE_SEQUENCER_57 0x3039 +#define WM8994_WRITE_SEQUENCER_58 0x303A +#define WM8994_WRITE_SEQUENCER_59 0x303B +#define WM8994_WRITE_SEQUENCER_60 0x303C +#define WM8994_WRITE_SEQUENCER_61 0x303D +#define WM8994_WRITE_SEQUENCER_62 0x303E +#define WM8994_WRITE_SEQUENCER_63 0x303F +#define WM8994_WRITE_SEQUENCER_64 0x3040 +#define WM8994_WRITE_SEQUENCER_65 0x3041 +#define WM8994_WRITE_SEQUENCER_66 0x3042 +#define WM8994_WRITE_SEQUENCER_67 0x3043 +#define WM8994_WRITE_SEQUENCER_68 0x3044 +#define WM8994_WRITE_SEQUENCER_69 0x3045 +#define WM8994_WRITE_SEQUENCER_70 0x3046 +#define WM8994_WRITE_SEQUENCER_71 0x3047 +#define WM8994_WRITE_SEQUENCER_72 0x3048 +#define WM8994_WRITE_SEQUENCER_73 0x3049 +#define WM8994_WRITE_SEQUENCER_74 0x304A +#define WM8994_WRITE_SEQUENCER_75 0x304B +#define WM8994_WRITE_SEQUENCER_76 0x304C +#define WM8994_WRITE_SEQUENCER_77 0x304D +#define WM8994_WRITE_SEQUENCER_78 0x304E +#define WM8994_WRITE_SEQUENCER_79 0x304F +#define WM8994_WRITE_SEQUENCER_80 0x3050 +#define WM8994_WRITE_SEQUENCER_81 0x3051 +#define WM8994_WRITE_SEQUENCER_82 0x3052 +#define WM8994_WRITE_SEQUENCER_83 0x3053 +#define WM8994_WRITE_SEQUENCER_84 0x3054 +#define WM8994_WRITE_SEQUENCER_85 0x3055 +#define WM8994_WRITE_SEQUENCER_86 0x3056 +#define WM8994_WRITE_SEQUENCER_87 0x3057 +#define WM8994_WRITE_SEQUENCER_88 0x3058 +#define WM8994_WRITE_SEQUENCER_89 0x3059 +#define WM8994_WRITE_SEQUENCER_90 0x305A +#define WM8994_WRITE_SEQUENCER_91 0x305B +#define WM8994_WRITE_SEQUENCER_92 0x305C +#define WM8994_WRITE_SEQUENCER_93 0x305D +#define WM8994_WRITE_SEQUENCER_94 0x305E +#define WM8994_WRITE_SEQUENCER_95 0x305F +#define WM8994_WRITE_SEQUENCER_96 0x3060 +#define WM8994_WRITE_SEQUENCER_97 0x3061 +#define WM8994_WRITE_SEQUENCER_98 0x3062 +#define WM8994_WRITE_SEQUENCER_99 0x3063 +#define WM8994_WRITE_SEQUENCER_100 0x3064 +#define WM8994_WRITE_SEQUENCER_101 0x3065 +#define WM8994_WRITE_SEQUENCER_102 0x3066 +#define WM8994_WRITE_SEQUENCER_103 0x3067 +#define WM8994_WRITE_SEQUENCER_104 0x3068 +#define WM8994_WRITE_SEQUENCER_105 0x3069 +#define WM8994_WRITE_SEQUENCER_106 0x306A +#define WM8994_WRITE_SEQUENCER_107 0x306B +#define WM8994_WRITE_SEQUENCER_108 0x306C +#define WM8994_WRITE_SEQUENCER_109 0x306D +#define WM8994_WRITE_SEQUENCER_110 0x306E +#define WM8994_WRITE_SEQUENCER_111 0x306F +#define WM8994_WRITE_SEQUENCER_112 0x3070 +#define WM8994_WRITE_SEQUENCER_113 0x3071 +#define WM8994_WRITE_SEQUENCER_114 0x3072 +#define WM8994_WRITE_SEQUENCER_115 0x3073 +#define WM8994_WRITE_SEQUENCER_116 0x3074 +#define WM8994_WRITE_SEQUENCER_117 0x3075 +#define WM8994_WRITE_SEQUENCER_118 0x3076 +#define WM8994_WRITE_SEQUENCER_119 0x3077 +#define WM8994_WRITE_SEQUENCER_120 0x3078 +#define WM8994_WRITE_SEQUENCER_121 0x3079 +#define WM8994_WRITE_SEQUENCER_122 0x307A +#define WM8994_WRITE_SEQUENCER_123 0x307B +#define WM8994_WRITE_SEQUENCER_124 0x307C +#define WM8994_WRITE_SEQUENCER_125 0x307D +#define WM8994_WRITE_SEQUENCER_126 0x307E +#define WM8994_WRITE_SEQUENCER_127 0x307F +#define WM8994_WRITE_SEQUENCER_128 0x3080 +#define WM8994_WRITE_SEQUENCER_129 0x3081 +#define WM8994_WRITE_SEQUENCER_130 0x3082 +#define WM8994_WRITE_SEQUENCER_131 0x3083 +#define WM8994_WRITE_SEQUENCER_132 0x3084 +#define WM8994_WRITE_SEQUENCER_133 0x3085 +#define WM8994_WRITE_SEQUENCER_134 0x3086 +#define WM8994_WRITE_SEQUENCER_135 0x3087 +#define WM8994_WRITE_SEQUENCER_136 0x3088 +#define WM8994_WRITE_SEQUENCER_137 0x3089 +#define WM8994_WRITE_SEQUENCER_138 0x308A +#define WM8994_WRITE_SEQUENCER_139 0x308B +#define WM8994_WRITE_SEQUENCER_140 0x308C +#define WM8994_WRITE_SEQUENCER_141 0x308D +#define WM8994_WRITE_SEQUENCER_142 0x308E +#define WM8994_WRITE_SEQUENCER_143 0x308F +#define WM8994_WRITE_SEQUENCER_144 0x3090 +#define WM8994_WRITE_SEQUENCER_145 0x3091 +#define WM8994_WRITE_SEQUENCER_146 0x3092 +#define WM8994_WRITE_SEQUENCER_147 0x3093 +#define WM8994_WRITE_SEQUENCER_148 0x3094 +#define WM8994_WRITE_SEQUENCER_149 0x3095 +#define WM8994_WRITE_SEQUENCER_150 0x3096 +#define WM8994_WRITE_SEQUENCER_151 0x3097 +#define WM8994_WRITE_SEQUENCER_152 0x3098 +#define WM8994_WRITE_SEQUENCER_153 0x3099 +#define WM8994_WRITE_SEQUENCER_154 0x309A +#define WM8994_WRITE_SEQUENCER_155 0x309B +#define WM8994_WRITE_SEQUENCER_156 0x309C +#define WM8994_WRITE_SEQUENCER_157 0x309D +#define WM8994_WRITE_SEQUENCER_158 0x309E +#define WM8994_WRITE_SEQUENCER_159 0x309F +#define WM8994_WRITE_SEQUENCER_160 0x30A0 +#define WM8994_WRITE_SEQUENCER_161 0x30A1 +#define WM8994_WRITE_SEQUENCER_162 0x30A2 +#define WM8994_WRITE_SEQUENCER_163 0x30A3 +#define WM8994_WRITE_SEQUENCER_164 0x30A4 +#define WM8994_WRITE_SEQUENCER_165 0x30A5 +#define WM8994_WRITE_SEQUENCER_166 0x30A6 +#define WM8994_WRITE_SEQUENCER_167 0x30A7 +#define WM8994_WRITE_SEQUENCER_168 0x30A8 +#define WM8994_WRITE_SEQUENCER_169 0x30A9 +#define WM8994_WRITE_SEQUENCER_170 0x30AA +#define WM8994_WRITE_SEQUENCER_171 0x30AB +#define WM8994_WRITE_SEQUENCER_172 0x30AC +#define WM8994_WRITE_SEQUENCER_173 0x30AD +#define WM8994_WRITE_SEQUENCER_174 0x30AE +#define WM8994_WRITE_SEQUENCER_175 0x30AF +#define WM8994_WRITE_SEQUENCER_176 0x30B0 +#define WM8994_WRITE_SEQUENCER_177 0x30B1 +#define WM8994_WRITE_SEQUENCER_178 0x30B2 +#define WM8994_WRITE_SEQUENCER_179 0x30B3 +#define WM8994_WRITE_SEQUENCER_180 0x30B4 +#define WM8994_WRITE_SEQUENCER_181 0x30B5 +#define WM8994_WRITE_SEQUENCER_182 0x30B6 +#define WM8994_WRITE_SEQUENCER_183 0x30B7 +#define WM8994_WRITE_SEQUENCER_184 0x30B8 +#define WM8994_WRITE_SEQUENCER_185 0x30B9 +#define WM8994_WRITE_SEQUENCER_186 0x30BA +#define WM8994_WRITE_SEQUENCER_187 0x30BB +#define WM8994_WRITE_SEQUENCER_188 0x30BC +#define WM8994_WRITE_SEQUENCER_189 0x30BD +#define WM8994_WRITE_SEQUENCER_190 0x30BE +#define WM8994_WRITE_SEQUENCER_191 0x30BF +#define WM8994_WRITE_SEQUENCER_192 0x30C0 +#define WM8994_WRITE_SEQUENCER_193 0x30C1 +#define WM8994_WRITE_SEQUENCER_194 0x30C2 +#define WM8994_WRITE_SEQUENCER_195 0x30C3 +#define WM8994_WRITE_SEQUENCER_196 0x30C4 +#define WM8994_WRITE_SEQUENCER_197 0x30C5 +#define WM8994_WRITE_SEQUENCER_198 0x30C6 +#define WM8994_WRITE_SEQUENCER_199 0x30C7 +#define WM8994_WRITE_SEQUENCER_200 0x30C8 +#define WM8994_WRITE_SEQUENCER_201 0x30C9 +#define WM8994_WRITE_SEQUENCER_202 0x30CA +#define WM8994_WRITE_SEQUENCER_203 0x30CB +#define WM8994_WRITE_SEQUENCER_204 0x30CC +#define WM8994_WRITE_SEQUENCER_205 0x30CD +#define WM8994_WRITE_SEQUENCER_206 0x30CE +#define WM8994_WRITE_SEQUENCER_207 0x30CF +#define WM8994_WRITE_SEQUENCER_208 0x30D0 +#define WM8994_WRITE_SEQUENCER_209 0x30D1 +#define WM8994_WRITE_SEQUENCER_210 0x30D2 +#define WM8994_WRITE_SEQUENCER_211 0x30D3 +#define WM8994_WRITE_SEQUENCER_212 0x30D4 +#define WM8994_WRITE_SEQUENCER_213 0x30D5 +#define WM8994_WRITE_SEQUENCER_214 0x30D6 +#define WM8994_WRITE_SEQUENCER_215 0x30D7 +#define WM8994_WRITE_SEQUENCER_216 0x30D8 +#define WM8994_WRITE_SEQUENCER_217 0x30D9 +#define WM8994_WRITE_SEQUENCER_218 0x30DA +#define WM8994_WRITE_SEQUENCER_219 0x30DB +#define WM8994_WRITE_SEQUENCER_220 0x30DC +#define WM8994_WRITE_SEQUENCER_221 0x30DD +#define WM8994_WRITE_SEQUENCER_222 0x30DE +#define WM8994_WRITE_SEQUENCER_223 0x30DF +#define WM8994_WRITE_SEQUENCER_224 0x30E0 +#define WM8994_WRITE_SEQUENCER_225 0x30E1 +#define WM8994_WRITE_SEQUENCER_226 0x30E2 +#define WM8994_WRITE_SEQUENCER_227 0x30E3 +#define WM8994_WRITE_SEQUENCER_228 0x30E4 +#define WM8994_WRITE_SEQUENCER_229 0x30E5 +#define WM8994_WRITE_SEQUENCER_230 0x30E6 +#define WM8994_WRITE_SEQUENCER_231 0x30E7 +#define WM8994_WRITE_SEQUENCER_232 0x30E8 +#define WM8994_WRITE_SEQUENCER_233 0x30E9 +#define WM8994_WRITE_SEQUENCER_234 0x30EA +#define WM8994_WRITE_SEQUENCER_235 0x30EB +#define WM8994_WRITE_SEQUENCER_236 0x30EC +#define WM8994_WRITE_SEQUENCER_237 0x30ED +#define WM8994_WRITE_SEQUENCER_238 0x30EE +#define WM8994_WRITE_SEQUENCER_239 0x30EF +#define WM8994_WRITE_SEQUENCER_240 0x30F0 +#define WM8994_WRITE_SEQUENCER_241 0x30F1 +#define WM8994_WRITE_SEQUENCER_242 0x30F2 +#define WM8994_WRITE_SEQUENCER_243 0x30F3 +#define WM8994_WRITE_SEQUENCER_244 0x30F4 +#define WM8994_WRITE_SEQUENCER_245 0x30F5 +#define WM8994_WRITE_SEQUENCER_246 0x30F6 +#define WM8994_WRITE_SEQUENCER_247 0x30F7 +#define WM8994_WRITE_SEQUENCER_248 0x30F8 +#define WM8994_WRITE_SEQUENCER_249 0x30F9 +#define WM8994_WRITE_SEQUENCER_250 0x30FA +#define WM8994_WRITE_SEQUENCER_251 0x30FB +#define WM8994_WRITE_SEQUENCER_252 0x30FC +#define WM8994_WRITE_SEQUENCER_253 0x30FD +#define WM8994_WRITE_SEQUENCER_254 0x30FE +#define WM8994_WRITE_SEQUENCER_255 0x30FF +#define WM8994_WRITE_SEQUENCER_256 0x3100 +#define WM8994_WRITE_SEQUENCER_257 0x3101 +#define WM8994_WRITE_SEQUENCER_258 0x3102 +#define WM8994_WRITE_SEQUENCER_259 0x3103 +#define WM8994_WRITE_SEQUENCER_260 0x3104 +#define WM8994_WRITE_SEQUENCER_261 0x3105 +#define WM8994_WRITE_SEQUENCER_262 0x3106 +#define WM8994_WRITE_SEQUENCER_263 0x3107 +#define WM8994_WRITE_SEQUENCER_264 0x3108 +#define WM8994_WRITE_SEQUENCER_265 0x3109 +#define WM8994_WRITE_SEQUENCER_266 0x310A +#define WM8994_WRITE_SEQUENCER_267 0x310B +#define WM8994_WRITE_SEQUENCER_268 0x310C +#define WM8994_WRITE_SEQUENCER_269 0x310D +#define WM8994_WRITE_SEQUENCER_270 0x310E +#define WM8994_WRITE_SEQUENCER_271 0x310F +#define WM8994_WRITE_SEQUENCER_272 0x3110 +#define WM8994_WRITE_SEQUENCER_273 0x3111 +#define WM8994_WRITE_SEQUENCER_274 0x3112 +#define WM8994_WRITE_SEQUENCER_275 0x3113 +#define WM8994_WRITE_SEQUENCER_276 0x3114 +#define WM8994_WRITE_SEQUENCER_277 0x3115 +#define WM8994_WRITE_SEQUENCER_278 0x3116 +#define WM8994_WRITE_SEQUENCER_279 0x3117 +#define WM8994_WRITE_SEQUENCER_280 0x3118 +#define WM8994_WRITE_SEQUENCER_281 0x3119 +#define WM8994_WRITE_SEQUENCER_282 0x311A +#define WM8994_WRITE_SEQUENCER_283 0x311B +#define WM8994_WRITE_SEQUENCER_284 0x311C +#define WM8994_WRITE_SEQUENCER_285 0x311D +#define WM8994_WRITE_SEQUENCER_286 0x311E +#define WM8994_WRITE_SEQUENCER_287 0x311F +#define WM8994_WRITE_SEQUENCER_288 0x3120 +#define WM8994_WRITE_SEQUENCER_289 0x3121 +#define WM8994_WRITE_SEQUENCER_290 0x3122 +#define WM8994_WRITE_SEQUENCER_291 0x3123 +#define WM8994_WRITE_SEQUENCER_292 0x3124 +#define WM8994_WRITE_SEQUENCER_293 0x3125 +#define WM8994_WRITE_SEQUENCER_294 0x3126 +#define WM8994_WRITE_SEQUENCER_295 0x3127 +#define WM8994_WRITE_SEQUENCER_296 0x3128 +#define WM8994_WRITE_SEQUENCER_297 0x3129 +#define WM8994_WRITE_SEQUENCER_298 0x312A +#define WM8994_WRITE_SEQUENCER_299 0x312B +#define WM8994_WRITE_SEQUENCER_300 0x312C +#define WM8994_WRITE_SEQUENCER_301 0x312D +#define WM8994_WRITE_SEQUENCER_302 0x312E +#define WM8994_WRITE_SEQUENCER_303 0x312F +#define WM8994_WRITE_SEQUENCER_304 0x3130 +#define WM8994_WRITE_SEQUENCER_305 0x3131 +#define WM8994_WRITE_SEQUENCER_306 0x3132 +#define WM8994_WRITE_SEQUENCER_307 0x3133 +#define WM8994_WRITE_SEQUENCER_308 0x3134 +#define WM8994_WRITE_SEQUENCER_309 0x3135 +#define WM8994_WRITE_SEQUENCER_310 0x3136 +#define WM8994_WRITE_SEQUENCER_311 0x3137 +#define WM8994_WRITE_SEQUENCER_312 0x3138 +#define WM8994_WRITE_SEQUENCER_313 0x3139 +#define WM8994_WRITE_SEQUENCER_314 0x313A +#define WM8994_WRITE_SEQUENCER_315 0x313B +#define WM8994_WRITE_SEQUENCER_316 0x313C +#define WM8994_WRITE_SEQUENCER_317 0x313D +#define WM8994_WRITE_SEQUENCER_318 0x313E +#define WM8994_WRITE_SEQUENCER_319 0x313F +#define WM8994_WRITE_SEQUENCER_320 0x3140 +#define WM8994_WRITE_SEQUENCER_321 0x3141 +#define WM8994_WRITE_SEQUENCER_322 0x3142 +#define WM8994_WRITE_SEQUENCER_323 0x3143 +#define WM8994_WRITE_SEQUENCER_324 0x3144 +#define WM8994_WRITE_SEQUENCER_325 0x3145 +#define WM8994_WRITE_SEQUENCER_326 0x3146 +#define WM8994_WRITE_SEQUENCER_327 0x3147 +#define WM8994_WRITE_SEQUENCER_328 0x3148 +#define WM8994_WRITE_SEQUENCER_329 0x3149 +#define WM8994_WRITE_SEQUENCER_330 0x314A +#define WM8994_WRITE_SEQUENCER_331 0x314B +#define WM8994_WRITE_SEQUENCER_332 0x314C +#define WM8994_WRITE_SEQUENCER_333 0x314D +#define WM8994_WRITE_SEQUENCER_334 0x314E +#define WM8994_WRITE_SEQUENCER_335 0x314F +#define WM8994_WRITE_SEQUENCER_336 0x3150 +#define WM8994_WRITE_SEQUENCER_337 0x3151 +#define WM8994_WRITE_SEQUENCER_338 0x3152 +#define WM8994_WRITE_SEQUENCER_339 0x3153 +#define WM8994_WRITE_SEQUENCER_340 0x3154 +#define WM8994_WRITE_SEQUENCER_341 0x3155 +#define WM8994_WRITE_SEQUENCER_342 0x3156 +#define WM8994_WRITE_SEQUENCER_343 0x3157 +#define WM8994_WRITE_SEQUENCER_344 0x3158 +#define WM8994_WRITE_SEQUENCER_345 0x3159 +#define WM8994_WRITE_SEQUENCER_346 0x315A +#define WM8994_WRITE_SEQUENCER_347 0x315B +#define WM8994_WRITE_SEQUENCER_348 0x315C +#define WM8994_WRITE_SEQUENCER_349 0x315D +#define WM8994_WRITE_SEQUENCER_350 0x315E +#define WM8994_WRITE_SEQUENCER_351 0x315F +#define WM8994_WRITE_SEQUENCER_352 0x3160 +#define WM8994_WRITE_SEQUENCER_353 0x3161 +#define WM8994_WRITE_SEQUENCER_354 0x3162 +#define WM8994_WRITE_SEQUENCER_355 0x3163 +#define WM8994_WRITE_SEQUENCER_356 0x3164 +#define WM8994_WRITE_SEQUENCER_357 0x3165 +#define WM8994_WRITE_SEQUENCER_358 0x3166 +#define WM8994_WRITE_SEQUENCER_359 0x3167 +#define WM8994_WRITE_SEQUENCER_360 0x3168 +#define WM8994_WRITE_SEQUENCER_361 0x3169 +#define WM8994_WRITE_SEQUENCER_362 0x316A +#define WM8994_WRITE_SEQUENCER_363 0x316B +#define WM8994_WRITE_SEQUENCER_364 0x316C +#define WM8994_WRITE_SEQUENCER_365 0x316D +#define WM8994_WRITE_SEQUENCER_366 0x316E +#define WM8994_WRITE_SEQUENCER_367 0x316F +#define WM8994_WRITE_SEQUENCER_368 0x3170 +#define WM8994_WRITE_SEQUENCER_369 0x3171 +#define WM8994_WRITE_SEQUENCER_370 0x3172 +#define WM8994_WRITE_SEQUENCER_371 0x3173 +#define WM8994_WRITE_SEQUENCER_372 0x3174 +#define WM8994_WRITE_SEQUENCER_373 0x3175 +#define WM8994_WRITE_SEQUENCER_374 0x3176 +#define WM8994_WRITE_SEQUENCER_375 0x3177 +#define WM8994_WRITE_SEQUENCER_376 0x3178 +#define WM8994_WRITE_SEQUENCER_377 0x3179 +#define WM8994_WRITE_SEQUENCER_378 0x317A +#define WM8994_WRITE_SEQUENCER_379 0x317B +#define WM8994_WRITE_SEQUENCER_380 0x317C +#define WM8994_WRITE_SEQUENCER_381 0x317D +#define WM8994_WRITE_SEQUENCER_382 0x317E +#define WM8994_WRITE_SEQUENCER_383 0x317F +#define WM8994_WRITE_SEQUENCER_384 0x3180 +#define WM8994_WRITE_SEQUENCER_385 0x3181 +#define WM8994_WRITE_SEQUENCER_386 0x3182 +#define WM8994_WRITE_SEQUENCER_387 0x3183 +#define WM8994_WRITE_SEQUENCER_388 0x3184 +#define WM8994_WRITE_SEQUENCER_389 0x3185 +#define WM8994_WRITE_SEQUENCER_390 0x3186 +#define WM8994_WRITE_SEQUENCER_391 0x3187 +#define WM8994_WRITE_SEQUENCER_392 0x3188 +#define WM8994_WRITE_SEQUENCER_393 0x3189 +#define WM8994_WRITE_SEQUENCER_394 0x318A +#define WM8994_WRITE_SEQUENCER_395 0x318B +#define WM8994_WRITE_SEQUENCER_396 0x318C +#define WM8994_WRITE_SEQUENCER_397 0x318D +#define WM8994_WRITE_SEQUENCER_398 0x318E +#define WM8994_WRITE_SEQUENCER_399 0x318F +#define WM8994_WRITE_SEQUENCER_400 0x3190 +#define WM8994_WRITE_SEQUENCER_401 0x3191 +#define WM8994_WRITE_SEQUENCER_402 0x3192 +#define WM8994_WRITE_SEQUENCER_403 0x3193 +#define WM8994_WRITE_SEQUENCER_404 0x3194 +#define WM8994_WRITE_SEQUENCER_405 0x3195 +#define WM8994_WRITE_SEQUENCER_406 0x3196 +#define WM8994_WRITE_SEQUENCER_407 0x3197 +#define WM8994_WRITE_SEQUENCER_408 0x3198 +#define WM8994_WRITE_SEQUENCER_409 0x3199 +#define WM8994_WRITE_SEQUENCER_410 0x319A +#define WM8994_WRITE_SEQUENCER_411 0x319B +#define WM8994_WRITE_SEQUENCER_412 0x319C +#define WM8994_WRITE_SEQUENCER_413 0x319D +#define WM8994_WRITE_SEQUENCER_414 0x319E +#define WM8994_WRITE_SEQUENCER_415 0x319F +#define WM8994_WRITE_SEQUENCER_416 0x31A0 +#define WM8994_WRITE_SEQUENCER_417 0x31A1 +#define WM8994_WRITE_SEQUENCER_418 0x31A2 +#define WM8994_WRITE_SEQUENCER_419 0x31A3 +#define WM8994_WRITE_SEQUENCER_420 0x31A4 +#define WM8994_WRITE_SEQUENCER_421 0x31A5 +#define WM8994_WRITE_SEQUENCER_422 0x31A6 +#define WM8994_WRITE_SEQUENCER_423 0x31A7 +#define WM8994_WRITE_SEQUENCER_424 0x31A8 +#define WM8994_WRITE_SEQUENCER_425 0x31A9 +#define WM8994_WRITE_SEQUENCER_426 0x31AA +#define WM8994_WRITE_SEQUENCER_427 0x31AB +#define WM8994_WRITE_SEQUENCER_428 0x31AC +#define WM8994_WRITE_SEQUENCER_429 0x31AD +#define WM8994_WRITE_SEQUENCER_430 0x31AE +#define WM8994_WRITE_SEQUENCER_431 0x31AF +#define WM8994_WRITE_SEQUENCER_432 0x31B0 +#define WM8994_WRITE_SEQUENCER_433 0x31B1 +#define WM8994_WRITE_SEQUENCER_434 0x31B2 +#define WM8994_WRITE_SEQUENCER_435 0x31B3 +#define WM8994_WRITE_SEQUENCER_436 0x31B4 +#define WM8994_WRITE_SEQUENCER_437 0x31B5 +#define WM8994_WRITE_SEQUENCER_438 0x31B6 +#define WM8994_WRITE_SEQUENCER_439 0x31B7 +#define WM8994_WRITE_SEQUENCER_440 0x31B8 +#define WM8994_WRITE_SEQUENCER_441 0x31B9 +#define WM8994_WRITE_SEQUENCER_442 0x31BA +#define WM8994_WRITE_SEQUENCER_443 0x31BB +#define WM8994_WRITE_SEQUENCER_444 0x31BC +#define WM8994_WRITE_SEQUENCER_445 0x31BD +#define WM8994_WRITE_SEQUENCER_446 0x31BE +#define WM8994_WRITE_SEQUENCER_447 0x31BF +#define WM8994_WRITE_SEQUENCER_448 0x31C0 +#define WM8994_WRITE_SEQUENCER_449 0x31C1 +#define WM8994_WRITE_SEQUENCER_450 0x31C2 +#define WM8994_WRITE_SEQUENCER_451 0x31C3 +#define WM8994_WRITE_SEQUENCER_452 0x31C4 +#define WM8994_WRITE_SEQUENCER_453 0x31C5 +#define WM8994_WRITE_SEQUENCER_454 0x31C6 +#define WM8994_WRITE_SEQUENCER_455 0x31C7 +#define WM8994_WRITE_SEQUENCER_456 0x31C8 +#define WM8994_WRITE_SEQUENCER_457 0x31C9 +#define WM8994_WRITE_SEQUENCER_458 0x31CA +#define WM8994_WRITE_SEQUENCER_459 0x31CB +#define WM8994_WRITE_SEQUENCER_460 0x31CC +#define WM8994_WRITE_SEQUENCER_461 0x31CD +#define WM8994_WRITE_SEQUENCER_462 0x31CE +#define WM8994_WRITE_SEQUENCER_463 0x31CF +#define WM8994_WRITE_SEQUENCER_464 0x31D0 +#define WM8994_WRITE_SEQUENCER_465 0x31D1 +#define WM8994_WRITE_SEQUENCER_466 0x31D2 +#define WM8994_WRITE_SEQUENCER_467 0x31D3 +#define WM8994_WRITE_SEQUENCER_468 0x31D4 +#define WM8994_WRITE_SEQUENCER_469 0x31D5 +#define WM8994_WRITE_SEQUENCER_470 0x31D6 +#define WM8994_WRITE_SEQUENCER_471 0x31D7 +#define WM8994_WRITE_SEQUENCER_472 0x31D8 +#define WM8994_WRITE_SEQUENCER_473 0x31D9 +#define WM8994_WRITE_SEQUENCER_474 0x31DA +#define WM8994_WRITE_SEQUENCER_475 0x31DB +#define WM8994_WRITE_SEQUENCER_476 0x31DC +#define WM8994_WRITE_SEQUENCER_477 0x31DD +#define WM8994_WRITE_SEQUENCER_478 0x31DE +#define WM8994_WRITE_SEQUENCER_479 0x31DF +#define WM8994_WRITE_SEQUENCER_480 0x31E0 +#define WM8994_WRITE_SEQUENCER_481 0x31E1 +#define WM8994_WRITE_SEQUENCER_482 0x31E2 +#define WM8994_WRITE_SEQUENCER_483 0x31E3 +#define WM8994_WRITE_SEQUENCER_484 0x31E4 +#define WM8994_WRITE_SEQUENCER_485 0x31E5 +#define WM8994_WRITE_SEQUENCER_486 0x31E6 +#define WM8994_WRITE_SEQUENCER_487 0x31E7 +#define WM8994_WRITE_SEQUENCER_488 0x31E8 +#define WM8994_WRITE_SEQUENCER_489 0x31E9 +#define WM8994_WRITE_SEQUENCER_490 0x31EA +#define WM8994_WRITE_SEQUENCER_491 0x31EB +#define WM8994_WRITE_SEQUENCER_492 0x31EC +#define WM8994_WRITE_SEQUENCER_493 0x31ED +#define WM8994_WRITE_SEQUENCER_494 0x31EE +#define WM8994_WRITE_SEQUENCER_495 0x31EF +#define WM8994_WRITE_SEQUENCER_496 0x31F0 +#define WM8994_WRITE_SEQUENCER_497 0x31F1 +#define WM8994_WRITE_SEQUENCER_498 0x31F2 +#define WM8994_WRITE_SEQUENCER_499 0x31F3 +#define WM8994_WRITE_SEQUENCER_500 0x31F4 +#define WM8994_WRITE_SEQUENCER_501 0x31F5 +#define WM8994_WRITE_SEQUENCER_502 0x31F6 +#define WM8994_WRITE_SEQUENCER_503 0x31F7 +#define WM8994_WRITE_SEQUENCER_504 0x31F8 +#define WM8994_WRITE_SEQUENCER_505 0x31F9 +#define WM8994_WRITE_SEQUENCER_506 0x31FA +#define WM8994_WRITE_SEQUENCER_507 0x31FB +#define WM8994_WRITE_SEQUENCER_508 0x31FC +#define WM8994_WRITE_SEQUENCER_509 0x31FD +#define WM8994_WRITE_SEQUENCER_510 0x31FE +#define WM8994_WRITE_SEQUENCER_511 0x31FF + +#define WM8994_REGISTER_COUNT 736 +#define WM8994_MAX_REGISTER 0x31FF +#define WM8994_MAX_CACHED_REGISTER 0x749 + +/* + * Field Definitions. + */ + +/* + * R0 (0x00) - Software Reset + */ +#define WM8994_SW_RESET_MASK 0xFFFF /* SW_RESET - [15:0] */ +#define WM8994_SW_RESET_SHIFT 0 /* SW_RESET - [15:0] */ +#define WM8994_SW_RESET_WIDTH 16 /* SW_RESET - [15:0] */ + +/* + * R1 (0x01) - Power Management (1) + */ +#define WM8994_SPKOUTR_ENA 0x2000 /* SPKOUTR_ENA */ +#define WM8994_SPKOUTR_ENA_MASK 0x2000 /* SPKOUTR_ENA */ +#define WM8994_SPKOUTR_ENA_SHIFT 13 /* SPKOUTR_ENA */ +#define WM8994_SPKOUTR_ENA_WIDTH 1 /* SPKOUTR_ENA */ +#define WM8994_SPKOUTL_ENA 0x1000 /* SPKOUTL_ENA */ +#define WM8994_SPKOUTL_ENA_MASK 0x1000 /* SPKOUTL_ENA */ +#define WM8994_SPKOUTL_ENA_SHIFT 12 /* SPKOUTL_ENA */ +#define WM8994_SPKOUTL_ENA_WIDTH 1 /* SPKOUTL_ENA */ +#define WM8994_HPOUT2_ENA 0x0800 /* HPOUT2_ENA */ +#define WM8994_HPOUT2_ENA_MASK 0x0800 /* HPOUT2_ENA */ +#define WM8994_HPOUT2_ENA_SHIFT 11 /* HPOUT2_ENA */ +#define WM8994_HPOUT2_ENA_WIDTH 1 /* HPOUT2_ENA */ +#define WM8994_HPOUT1L_ENA 0x0200 /* HPOUT1L_ENA */ +#define WM8994_HPOUT1L_ENA_MASK 0x0200 /* HPOUT1L_ENA */ +#define WM8994_HPOUT1L_ENA_SHIFT 9 /* HPOUT1L_ENA */ +#define WM8994_HPOUT1L_ENA_WIDTH 1 /* HPOUT1L_ENA */ +#define WM8994_HPOUT1R_ENA 0x0100 /* HPOUT1R_ENA */ +#define WM8994_HPOUT1R_ENA_MASK 0x0100 /* HPOUT1R_ENA */ +#define WM8994_HPOUT1R_ENA_SHIFT 8 /* HPOUT1R_ENA */ +#define WM8994_HPOUT1R_ENA_WIDTH 1 /* HPOUT1R_ENA */ +#define WM8994_MICB2_ENA 0x0020 /* MICB2_ENA */ +#define WM8994_MICB2_ENA_MASK 0x0020 /* MICB2_ENA */ +#define WM8994_MICB2_ENA_SHIFT 5 /* MICB2_ENA */ +#define WM8994_MICB2_ENA_WIDTH 1 /* MICB2_ENA */ +#define WM8994_MICB1_ENA 0x0010 /* MICB1_ENA */ +#define WM8994_MICB1_ENA_MASK 0x0010 /* MICB1_ENA */ +#define WM8994_MICB1_ENA_SHIFT 4 /* MICB1_ENA */ +#define WM8994_MICB1_ENA_WIDTH 1 /* MICB1_ENA */ +#define WM8994_VMID_SEL_MASK 0x0006 /* VMID_SEL - [2:1] */ +#define WM8994_VMID_SEL_SHIFT 1 /* VMID_SEL - [2:1] */ +#define WM8994_VMID_SEL_WIDTH 2 /* VMID_SEL - [2:1] */ +#define WM8994_BIAS_ENA 0x0001 /* BIAS_ENA */ +#define WM8994_BIAS_ENA_MASK 0x0001 /* BIAS_ENA */ +#define WM8994_BIAS_ENA_SHIFT 0 /* BIAS_ENA */ +#define WM8994_BIAS_ENA_WIDTH 1 /* BIAS_ENA */ + +/* + * R2 (0x02) - Power Management (2) + */ +#define WM8994_TSHUT_ENA 0x4000 /* TSHUT_ENA */ +#define WM8994_TSHUT_ENA_MASK 0x4000 /* TSHUT_ENA */ +#define WM8994_TSHUT_ENA_SHIFT 14 /* TSHUT_ENA */ +#define WM8994_TSHUT_ENA_WIDTH 1 /* TSHUT_ENA */ +#define WM8994_TSHUT_OPDIS 0x2000 /* TSHUT_OPDIS */ +#define WM8994_TSHUT_OPDIS_MASK 0x2000 /* TSHUT_OPDIS */ +#define WM8994_TSHUT_OPDIS_SHIFT 13 /* TSHUT_OPDIS */ +#define WM8994_TSHUT_OPDIS_WIDTH 1 /* TSHUT_OPDIS */ +#define WM8994_OPCLK_ENA 0x0800 /* OPCLK_ENA */ +#define WM8994_OPCLK_ENA_MASK 0x0800 /* OPCLK_ENA */ +#define WM8994_OPCLK_ENA_SHIFT 11 /* OPCLK_ENA */ +#define WM8994_OPCLK_ENA_WIDTH 1 /* OPCLK_ENA */ +#define WM8994_MIXINL_ENA 0x0200 /* MIXINL_ENA */ +#define WM8994_MIXINL_ENA_MASK 0x0200 /* MIXINL_ENA */ +#define WM8994_MIXINL_ENA_SHIFT 9 /* MIXINL_ENA */ +#define WM8994_MIXINL_ENA_WIDTH 1 /* MIXINL_ENA */ +#define WM8994_MIXINR_ENA 0x0100 /* MIXINR_ENA */ +#define WM8994_MIXINR_ENA_MASK 0x0100 /* MIXINR_ENA */ +#define WM8994_MIXINR_ENA_SHIFT 8 /* MIXINR_ENA */ +#define WM8994_MIXINR_ENA_WIDTH 1 /* MIXINR_ENA */ +#define WM8994_IN2L_ENA 0x0080 /* IN2L_ENA */ +#define WM8994_IN2L_ENA_MASK 0x0080 /* IN2L_ENA */ +#define WM8994_IN2L_ENA_SHIFT 7 /* IN2L_ENA */ +#define WM8994_IN2L_ENA_WIDTH 1 /* IN2L_ENA */ +#define WM8994_IN1L_ENA 0x0040 /* IN1L_ENA */ +#define WM8994_IN1L_ENA_MASK 0x0040 /* IN1L_ENA */ +#define WM8994_IN1L_ENA_SHIFT 6 /* IN1L_ENA */ +#define WM8994_IN1L_ENA_WIDTH 1 /* IN1L_ENA */ +#define WM8994_IN2R_ENA 0x0020 /* IN2R_ENA */ +#define WM8994_IN2R_ENA_MASK 0x0020 /* IN2R_ENA */ +#define WM8994_IN2R_ENA_SHIFT 5 /* IN2R_ENA */ +#define WM8994_IN2R_ENA_WIDTH 1 /* IN2R_ENA */ +#define WM8994_IN1R_ENA 0x0010 /* IN1R_ENA */ +#define WM8994_IN1R_ENA_MASK 0x0010 /* IN1R_ENA */ +#define WM8994_IN1R_ENA_SHIFT 4 /* IN1R_ENA */ +#define WM8994_IN1R_ENA_WIDTH 1 /* IN1R_ENA */ + +/* + * R3 (0x03) - Power Management (3) + */ +#define WM8994_LINEOUT1N_ENA 0x2000 /* LINEOUT1N_ENA */ +#define WM8994_LINEOUT1N_ENA_MASK 0x2000 /* LINEOUT1N_ENA */ +#define WM8994_LINEOUT1N_ENA_SHIFT 13 /* LINEOUT1N_ENA */ +#define WM8994_LINEOUT1N_ENA_WIDTH 1 /* LINEOUT1N_ENA */ +#define WM8994_LINEOUT1P_ENA 0x1000 /* LINEOUT1P_ENA */ +#define WM8994_LINEOUT1P_ENA_MASK 0x1000 /* LINEOUT1P_ENA */ +#define WM8994_LINEOUT1P_ENA_SHIFT 12 /* LINEOUT1P_ENA */ +#define WM8994_LINEOUT1P_ENA_WIDTH 1 /* LINEOUT1P_ENA */ +#define WM8994_LINEOUT2N_ENA 0x0800 /* LINEOUT2N_ENA */ +#define WM8994_LINEOUT2N_ENA_MASK 0x0800 /* LINEOUT2N_ENA */ +#define WM8994_LINEOUT2N_ENA_SHIFT 11 /* LINEOUT2N_ENA */ +#define WM8994_LINEOUT2N_ENA_WIDTH 1 /* LINEOUT2N_ENA */ +#define WM8994_LINEOUT2P_ENA 0x0400 /* LINEOUT2P_ENA */ +#define WM8994_LINEOUT2P_ENA_MASK 0x0400 /* LINEOUT2P_ENA */ +#define WM8994_LINEOUT2P_ENA_SHIFT 10 /* LINEOUT2P_ENA */ +#define WM8994_LINEOUT2P_ENA_WIDTH 1 /* LINEOUT2P_ENA */ +#define WM8994_SPKRVOL_ENA 0x0200 /* SPKRVOL_ENA */ +#define WM8994_SPKRVOL_ENA_MASK 0x0200 /* SPKRVOL_ENA */ +#define WM8994_SPKRVOL_ENA_SHIFT 9 /* SPKRVOL_ENA */ +#define WM8994_SPKRVOL_ENA_WIDTH 1 /* SPKRVOL_ENA */ +#define WM8994_SPKLVOL_ENA 0x0100 /* SPKLVOL_ENA */ +#define WM8994_SPKLVOL_ENA_MASK 0x0100 /* SPKLVOL_ENA */ +#define WM8994_SPKLVOL_ENA_SHIFT 8 /* SPKLVOL_ENA */ +#define WM8994_SPKLVOL_ENA_WIDTH 1 /* SPKLVOL_ENA */ +#define WM8994_MIXOUTLVOL_ENA 0x0080 /* MIXOUTLVOL_ENA */ +#define WM8994_MIXOUTLVOL_ENA_MASK 0x0080 /* MIXOUTLVOL_ENA */ +#define WM8994_MIXOUTLVOL_ENA_SHIFT 7 /* MIXOUTLVOL_ENA */ +#define WM8994_MIXOUTLVOL_ENA_WIDTH 1 /* MIXOUTLVOL_ENA */ +#define WM8994_MIXOUTRVOL_ENA 0x0040 /* MIXOUTRVOL_ENA */ +#define WM8994_MIXOUTRVOL_ENA_MASK 0x0040 /* MIXOUTRVOL_ENA */ +#define WM8994_MIXOUTRVOL_ENA_SHIFT 6 /* MIXOUTRVOL_ENA */ +#define WM8994_MIXOUTRVOL_ENA_WIDTH 1 /* MIXOUTRVOL_ENA */ +#define WM8994_MIXOUTL_ENA 0x0020 /* MIXOUTL_ENA */ +#define WM8994_MIXOUTL_ENA_MASK 0x0020 /* MIXOUTL_ENA */ +#define WM8994_MIXOUTL_ENA_SHIFT 5 /* MIXOUTL_ENA */ +#define WM8994_MIXOUTL_ENA_WIDTH 1 /* MIXOUTL_ENA */ +#define WM8994_MIXOUTR_ENA 0x0010 /* MIXOUTR_ENA */ +#define WM8994_MIXOUTR_ENA_MASK 0x0010 /* MIXOUTR_ENA */ +#define WM8994_MIXOUTR_ENA_SHIFT 4 /* MIXOUTR_ENA */ +#define WM8994_MIXOUTR_ENA_WIDTH 1 /* MIXOUTR_ENA */ + +/* + * R4 (0x04) - Power Management (4) + */ +#define WM8994_AIF2ADCL_ENA 0x2000 /* AIF2ADCL_ENA */ +#define WM8994_AIF2ADCL_ENA_MASK 0x2000 /* AIF2ADCL_ENA */ +#define WM8994_AIF2ADCL_ENA_SHIFT 13 /* AIF2ADCL_ENA */ +#define WM8994_AIF2ADCL_ENA_WIDTH 1 /* AIF2ADCL_ENA */ +#define WM8994_AIF2ADCR_ENA 0x1000 /* AIF2ADCR_ENA */ +#define WM8994_AIF2ADCR_ENA_MASK 0x1000 /* AIF2ADCR_ENA */ +#define WM8994_AIF2ADCR_ENA_SHIFT 12 /* AIF2ADCR_ENA */ +#define WM8994_AIF2ADCR_ENA_WIDTH 1 /* AIF2ADCR_ENA */ +#define WM8994_AIF1ADC2L_ENA 0x0800 /* AIF1ADC2L_ENA */ +#define WM8994_AIF1ADC2L_ENA_MASK 0x0800 /* AIF1ADC2L_ENA */ +#define WM8994_AIF1ADC2L_ENA_SHIFT 11 /* AIF1ADC2L_ENA */ +#define WM8994_AIF1ADC2L_ENA_WIDTH 1 /* AIF1ADC2L_ENA */ +#define WM8994_AIF1ADC2R_ENA 0x0400 /* AIF1ADC2R_ENA */ +#define WM8994_AIF1ADC2R_ENA_MASK 0x0400 /* AIF1ADC2R_ENA */ +#define WM8994_AIF1ADC2R_ENA_SHIFT 10 /* AIF1ADC2R_ENA */ +#define WM8994_AIF1ADC2R_ENA_WIDTH 1 /* AIF1ADC2R_ENA */ +#define WM8994_AIF1ADC1L_ENA 0x0200 /* AIF1ADC1L_ENA */ +#define WM8994_AIF1ADC1L_ENA_MASK 0x0200 /* AIF1ADC1L_ENA */ +#define WM8994_AIF1ADC1L_ENA_SHIFT 9 /* AIF1ADC1L_ENA */ +#define WM8994_AIF1ADC1L_ENA_WIDTH 1 /* AIF1ADC1L_ENA */ +#define WM8994_AIF1ADC1R_ENA 0x0100 /* AIF1ADC1R_ENA */ +#define WM8994_AIF1ADC1R_ENA_MASK 0x0100 /* AIF1ADC1R_ENA */ +#define WM8994_AIF1ADC1R_ENA_SHIFT 8 /* AIF1ADC1R_ENA */ +#define WM8994_AIF1ADC1R_ENA_WIDTH 1 /* AIF1ADC1R_ENA */ +#define WM8994_DMIC2L_ENA 0x0020 /* DMIC2L_ENA */ +#define WM8994_DMIC2L_ENA_MASK 0x0020 /* DMIC2L_ENA */ +#define WM8994_DMIC2L_ENA_SHIFT 5 /* DMIC2L_ENA */ +#define WM8994_DMIC2L_ENA_WIDTH 1 /* DMIC2L_ENA */ +#define WM8994_DMIC2R_ENA 0x0010 /* DMIC2R_ENA */ +#define WM8994_DMIC2R_ENA_MASK 0x0010 /* DMIC2R_ENA */ +#define WM8994_DMIC2R_ENA_SHIFT 4 /* DMIC2R_ENA */ +#define WM8994_DMIC2R_ENA_WIDTH 1 /* DMIC2R_ENA */ +#define WM8994_DMIC1L_ENA 0x0008 /* DMIC1L_ENA */ +#define WM8994_DMIC1L_ENA_MASK 0x0008 /* DMIC1L_ENA */ +#define WM8994_DMIC1L_ENA_SHIFT 3 /* DMIC1L_ENA */ +#define WM8994_DMIC1L_ENA_WIDTH 1 /* DMIC1L_ENA */ +#define WM8994_DMIC1R_ENA 0x0004 /* DMIC1R_ENA */ +#define WM8994_DMIC1R_ENA_MASK 0x0004 /* DMIC1R_ENA */ +#define WM8994_DMIC1R_ENA_SHIFT 2 /* DMIC1R_ENA */ +#define WM8994_DMIC1R_ENA_WIDTH 1 /* DMIC1R_ENA */ +#define WM8994_ADCL_ENA 0x0002 /* ADCL_ENA */ +#define WM8994_ADCL_ENA_MASK 0x0002 /* ADCL_ENA */ +#define WM8994_ADCL_ENA_SHIFT 1 /* ADCL_ENA */ +#define WM8994_ADCL_ENA_WIDTH 1 /* ADCL_ENA */ +#define WM8994_ADCR_ENA 0x0001 /* ADCR_ENA */ +#define WM8994_ADCR_ENA_MASK 0x0001 /* ADCR_ENA */ +#define WM8994_ADCR_ENA_SHIFT 0 /* ADCR_ENA */ +#define WM8994_ADCR_ENA_WIDTH 1 /* ADCR_ENA */ + +/* + * R5 (0x05) - Power Management (5) + */ +#define WM8994_AIF2DACL_ENA 0x2000 /* AIF2DACL_ENA */ +#define WM8994_AIF2DACL_ENA_MASK 0x2000 /* AIF2DACL_ENA */ +#define WM8994_AIF2DACL_ENA_SHIFT 13 /* AIF2DACL_ENA */ +#define WM8994_AIF2DACL_ENA_WIDTH 1 /* AIF2DACL_ENA */ +#define WM8994_AIF2DACR_ENA 0x1000 /* AIF2DACR_ENA */ +#define WM8994_AIF2DACR_ENA_MASK 0x1000 /* AIF2DACR_ENA */ +#define WM8994_AIF2DACR_ENA_SHIFT 12 /* AIF2DACR_ENA */ +#define WM8994_AIF2DACR_ENA_WIDTH 1 /* AIF2DACR_ENA */ +#define WM8994_AIF1DAC2L_ENA 0x0800 /* AIF1DAC2L_ENA */ +#define WM8994_AIF1DAC2L_ENA_MASK 0x0800 /* AIF1DAC2L_ENA */ +#define WM8994_AIF1DAC2L_ENA_SHIFT 11 /* AIF1DAC2L_ENA */ +#define WM8994_AIF1DAC2L_ENA_WIDTH 1 /* AIF1DAC2L_ENA */ +#define WM8994_AIF1DAC2R_ENA 0x0400 /* AIF1DAC2R_ENA */ +#define WM8994_AIF1DAC2R_ENA_MASK 0x0400 /* AIF1DAC2R_ENA */ +#define WM8994_AIF1DAC2R_ENA_SHIFT 10 /* AIF1DAC2R_ENA */ +#define WM8994_AIF1DAC2R_ENA_WIDTH 1 /* AIF1DAC2R_ENA */ +#define WM8994_AIF1DAC1L_ENA 0x0200 /* AIF1DAC1L_ENA */ +#define WM8994_AIF1DAC1L_ENA_MASK 0x0200 /* AIF1DAC1L_ENA */ +#define WM8994_AIF1DAC1L_ENA_SHIFT 9 /* AIF1DAC1L_ENA */ +#define WM8994_AIF1DAC1L_ENA_WIDTH 1 /* AIF1DAC1L_ENA */ +#define WM8994_AIF1DAC1R_ENA 0x0100 /* AIF1DAC1R_ENA */ +#define WM8994_AIF1DAC1R_ENA_MASK 0x0100 /* AIF1DAC1R_ENA */ +#define WM8994_AIF1DAC1R_ENA_SHIFT 8 /* AIF1DAC1R_ENA */ +#define WM8994_AIF1DAC1R_ENA_WIDTH 1 /* AIF1DAC1R_ENA */ +#define WM8994_DAC2L_ENA 0x0008 /* DAC2L_ENA */ +#define WM8994_DAC2L_ENA_MASK 0x0008 /* DAC2L_ENA */ +#define WM8994_DAC2L_ENA_SHIFT 3 /* DAC2L_ENA */ +#define WM8994_DAC2L_ENA_WIDTH 1 /* DAC2L_ENA */ +#define WM8994_DAC2R_ENA 0x0004 /* DAC2R_ENA */ +#define WM8994_DAC2R_ENA_MASK 0x0004 /* DAC2R_ENA */ +#define WM8994_DAC2R_ENA_SHIFT 2 /* DAC2R_ENA */ +#define WM8994_DAC2R_ENA_WIDTH 1 /* DAC2R_ENA */ +#define WM8994_DAC1L_ENA 0x0002 /* DAC1L_ENA */ +#define WM8994_DAC1L_ENA_MASK 0x0002 /* DAC1L_ENA */ +#define WM8994_DAC1L_ENA_SHIFT 1 /* DAC1L_ENA */ +#define WM8994_DAC1L_ENA_WIDTH 1 /* DAC1L_ENA */ +#define WM8994_DAC1R_ENA 0x0001 /* DAC1R_ENA */ +#define WM8994_DAC1R_ENA_MASK 0x0001 /* DAC1R_ENA */ +#define WM8994_DAC1R_ENA_SHIFT 0 /* DAC1R_ENA */ +#define WM8994_DAC1R_ENA_WIDTH 1 /* DAC1R_ENA */ + +/* + * R6 (0x06) - Power Management (6) + */ +#define WM8994_AIF3_TRI 0x0020 /* AIF3_TRI */ +#define WM8994_AIF3_TRI_MASK 0x0020 /* AIF3_TRI */ +#define WM8994_AIF3_TRI_SHIFT 5 /* AIF3_TRI */ +#define WM8994_AIF3_TRI_WIDTH 1 /* AIF3_TRI */ +#define WM8994_AIF3_ADCDAT_SRC_MASK 0x0018 /* AIF3_ADCDAT_SRC - [4:3] */ +#define WM8994_AIF3_ADCDAT_SRC_SHIFT 3 /* AIF3_ADCDAT_SRC - [4:3] */ +#define WM8994_AIF3_ADCDAT_SRC_WIDTH 2 /* AIF3_ADCDAT_SRC - [4:3] */ +#define WM8994_AIF2_ADCDAT_SRC 0x0004 /* AIF2_ADCDAT_SRC */ +#define WM8994_AIF2_ADCDAT_SRC_MASK 0x0004 /* AIF2_ADCDAT_SRC */ +#define WM8994_AIF2_ADCDAT_SRC_SHIFT 2 /* AIF2_ADCDAT_SRC */ +#define WM8994_AIF2_ADCDAT_SRC_WIDTH 1 /* AIF2_ADCDAT_SRC */ +#define WM8994_AIF2_DACDAT_SRC 0x0002 /* AIF2_DACDAT_SRC */ +#define WM8994_AIF2_DACDAT_SRC_MASK 0x0002 /* AIF2_DACDAT_SRC */ +#define WM8994_AIF2_DACDAT_SRC_SHIFT 1 /* AIF2_DACDAT_SRC */ +#define WM8994_AIF2_DACDAT_SRC_WIDTH 1 /* AIF2_DACDAT_SRC */ +#define WM8994_AIF1_DACDAT_SRC 0x0001 /* AIF1_DACDAT_SRC */ +#define WM8994_AIF1_DACDAT_SRC_MASK 0x0001 /* AIF1_DACDAT_SRC */ +#define WM8994_AIF1_DACDAT_SRC_SHIFT 0 /* AIF1_DACDAT_SRC */ +#define WM8994_AIF1_DACDAT_SRC_WIDTH 1 /* AIF1_DACDAT_SRC */ + +/* + * R21 (0x15) - Input Mixer (1) + */ +#define WM8994_IN1RP_MIXINR_BOOST 0x0100 /* IN1RP_MIXINR_BOOST */ +#define WM8994_IN1RP_MIXINR_BOOST_MASK 0x0100 /* IN1RP_MIXINR_BOOST */ +#define WM8994_IN1RP_MIXINR_BOOST_SHIFT 8 /* IN1RP_MIXINR_BOOST */ +#define WM8994_IN1RP_MIXINR_BOOST_WIDTH 1 /* IN1RP_MIXINR_BOOST */ +#define WM8994_IN1LP_MIXINL_BOOST 0x0080 /* IN1LP_MIXINL_BOOST */ +#define WM8994_IN1LP_MIXINL_BOOST_MASK 0x0080 /* IN1LP_MIXINL_BOOST */ +#define WM8994_IN1LP_MIXINL_BOOST_SHIFT 7 /* IN1LP_MIXINL_BOOST */ +#define WM8994_IN1LP_MIXINL_BOOST_WIDTH 1 /* IN1LP_MIXINL_BOOST */ +#define WM8994_INPUTS_CLAMP 0x0040 /* INPUTS_CLAMP */ +#define WM8994_INPUTS_CLAMP_MASK 0x0040 /* INPUTS_CLAMP */ +#define WM8994_INPUTS_CLAMP_SHIFT 6 /* INPUTS_CLAMP */ +#define WM8994_INPUTS_CLAMP_WIDTH 1 /* INPUTS_CLAMP */ + +/* + * R24 (0x18) - Left Line Input 1&2 Volume + */ +#define WM8994_IN1_VU 0x0100 /* IN1_VU */ +#define WM8994_IN1_VU_MASK 0x0100 /* IN1_VU */ +#define WM8994_IN1_VU_SHIFT 8 /* IN1_VU */ +#define WM8994_IN1_VU_WIDTH 1 /* IN1_VU */ +#define WM8994_IN1L_MUTE 0x0080 /* IN1L_MUTE */ +#define WM8994_IN1L_MUTE_MASK 0x0080 /* IN1L_MUTE */ +#define WM8994_IN1L_MUTE_SHIFT 7 /* IN1L_MUTE */ +#define WM8994_IN1L_MUTE_WIDTH 1 /* IN1L_MUTE */ +#define WM8994_IN1L_ZC 0x0040 /* IN1L_ZC */ +#define WM8994_IN1L_ZC_MASK 0x0040 /* IN1L_ZC */ +#define WM8994_IN1L_ZC_SHIFT 6 /* IN1L_ZC */ +#define WM8994_IN1L_ZC_WIDTH 1 /* IN1L_ZC */ +#define WM8994_IN1L_VOL_MASK 0x001F /* IN1L_VOL - [4:0] */ +#define WM8994_IN1L_VOL_SHIFT 0 /* IN1L_VOL - [4:0] */ +#define WM8994_IN1L_VOL_WIDTH 5 /* IN1L_VOL - [4:0] */ + +/* + * R25 (0x19) - Left Line Input 3&4 Volume + */ +#define WM8994_IN2_VU 0x0100 /* IN2_VU */ +#define WM8994_IN2_VU_MASK 0x0100 /* IN2_VU */ +#define WM8994_IN2_VU_SHIFT 8 /* IN2_VU */ +#define WM8994_IN2_VU_WIDTH 1 /* IN2_VU */ +#define WM8994_IN2L_MUTE 0x0080 /* IN2L_MUTE */ +#define WM8994_IN2L_MUTE_MASK 0x0080 /* IN2L_MUTE */ +#define WM8994_IN2L_MUTE_SHIFT 7 /* IN2L_MUTE */ +#define WM8994_IN2L_MUTE_WIDTH 1 /* IN2L_MUTE */ +#define WM8994_IN2L_ZC 0x0040 /* IN2L_ZC */ +#define WM8994_IN2L_ZC_MASK 0x0040 /* IN2L_ZC */ +#define WM8994_IN2L_ZC_SHIFT 6 /* IN2L_ZC */ +#define WM8994_IN2L_ZC_WIDTH 1 /* IN2L_ZC */ +#define WM8994_IN2L_VOL_MASK 0x001F /* IN2L_VOL - [4:0] */ +#define WM8994_IN2L_VOL_SHIFT 0 /* IN2L_VOL - [4:0] */ +#define WM8994_IN2L_VOL_WIDTH 5 /* IN2L_VOL - [4:0] */ + +/* + * R26 (0x1A) - Right Line Input 1&2 Volume + */ +#define WM8994_IN1_VU 0x0100 /* IN1_VU */ +#define WM8994_IN1_VU_MASK 0x0100 /* IN1_VU */ +#define WM8994_IN1_VU_SHIFT 8 /* IN1_VU */ +#define WM8994_IN1_VU_WIDTH 1 /* IN1_VU */ +#define WM8994_IN1R_MUTE 0x0080 /* IN1R_MUTE */ +#define WM8994_IN1R_MUTE_MASK 0x0080 /* IN1R_MUTE */ +#define WM8994_IN1R_MUTE_SHIFT 7 /* IN1R_MUTE */ +#define WM8994_IN1R_MUTE_WIDTH 1 /* IN1R_MUTE */ +#define WM8994_IN1R_ZC 0x0040 /* IN1R_ZC */ +#define WM8994_IN1R_ZC_MASK 0x0040 /* IN1R_ZC */ +#define WM8994_IN1R_ZC_SHIFT 6 /* IN1R_ZC */ +#define WM8994_IN1R_ZC_WIDTH 1 /* IN1R_ZC */ +#define WM8994_IN1R_VOL_MASK 0x001F /* IN1R_VOL - [4:0] */ +#define WM8994_IN1R_VOL_SHIFT 0 /* IN1R_VOL - [4:0] */ +#define WM8994_IN1R_VOL_WIDTH 5 /* IN1R_VOL - [4:0] */ + +/* + * R27 (0x1B) - Right Line Input 3&4 Volume + */ +#define WM8994_IN2_VU 0x0100 /* IN2_VU */ +#define WM8994_IN2_VU_MASK 0x0100 /* IN2_VU */ +#define WM8994_IN2_VU_SHIFT 8 /* IN2_VU */ +#define WM8994_IN2_VU_WIDTH 1 /* IN2_VU */ +#define WM8994_IN2R_MUTE 0x0080 /* IN2R_MUTE */ +#define WM8994_IN2R_MUTE_MASK 0x0080 /* IN2R_MUTE */ +#define WM8994_IN2R_MUTE_SHIFT 7 /* IN2R_MUTE */ +#define WM8994_IN2R_MUTE_WIDTH 1 /* IN2R_MUTE */ +#define WM8994_IN2R_ZC 0x0040 /* IN2R_ZC */ +#define WM8994_IN2R_ZC_MASK 0x0040 /* IN2R_ZC */ +#define WM8994_IN2R_ZC_SHIFT 6 /* IN2R_ZC */ +#define WM8994_IN2R_ZC_WIDTH 1 /* IN2R_ZC */ +#define WM8994_IN2R_VOL_MASK 0x001F /* IN2R_VOL - [4:0] */ +#define WM8994_IN2R_VOL_SHIFT 0 /* IN2R_VOL - [4:0] */ +#define WM8994_IN2R_VOL_WIDTH 5 /* IN2R_VOL - [4:0] */ + +/* + * R28 (0x1C) - Left Output Volume + */ +#define WM8994_HPOUT1_VU 0x0100 /* HPOUT1_VU */ +#define WM8994_HPOUT1_VU_MASK 0x0100 /* HPOUT1_VU */ +#define WM8994_HPOUT1_VU_SHIFT 8 /* HPOUT1_VU */ +#define WM8994_HPOUT1_VU_WIDTH 1 /* HPOUT1_VU */ +#define WM8994_HPOUT1L_ZC 0x0080 /* HPOUT1L_ZC */ +#define WM8994_HPOUT1L_ZC_MASK 0x0080 /* HPOUT1L_ZC */ +#define WM8994_HPOUT1L_ZC_SHIFT 7 /* HPOUT1L_ZC */ +#define WM8994_HPOUT1L_ZC_WIDTH 1 /* HPOUT1L_ZC */ +#define WM8994_HPOUT1L_MUTE_N 0x0040 /* HPOUT1L_MUTE_N */ +#define WM8994_HPOUT1L_MUTE_N_MASK 0x0040 /* HPOUT1L_MUTE_N */ +#define WM8994_HPOUT1L_MUTE_N_SHIFT 6 /* HPOUT1L_MUTE_N */ +#define WM8994_HPOUT1L_MUTE_N_WIDTH 1 /* HPOUT1L_MUTE_N */ +#define WM8994_HPOUT1L_VOL_MASK 0x003F /* HPOUT1L_VOL - [5:0] */ +#define WM8994_HPOUT1L_VOL_SHIFT 0 /* HPOUT1L_VOL - [5:0] */ +#define WM8994_HPOUT1L_VOL_WIDTH 6 /* HPOUT1L_VOL - [5:0] */ + +/* + * R29 (0x1D) - Right Output Volume + */ +#define WM8994_HPOUT1_VU 0x0100 /* HPOUT1_VU */ +#define WM8994_HPOUT1_VU_MASK 0x0100 /* HPOUT1_VU */ +#define WM8994_HPOUT1_VU_SHIFT 8 /* HPOUT1_VU */ +#define WM8994_HPOUT1_VU_WIDTH 1 /* HPOUT1_VU */ +#define WM8994_HPOUT1R_ZC 0x0080 /* HPOUT1R_ZC */ +#define WM8994_HPOUT1R_ZC_MASK 0x0080 /* HPOUT1R_ZC */ +#define WM8994_HPOUT1R_ZC_SHIFT 7 /* HPOUT1R_ZC */ +#define WM8994_HPOUT1R_ZC_WIDTH 1 /* HPOUT1R_ZC */ +#define WM8994_HPOUT1R_MUTE_N 0x0040 /* HPOUT1R_MUTE_N */ +#define WM8994_HPOUT1R_MUTE_N_MASK 0x0040 /* HPOUT1R_MUTE_N */ +#define WM8994_HPOUT1R_MUTE_N_SHIFT 6 /* HPOUT1R_MUTE_N */ +#define WM8994_HPOUT1R_MUTE_N_WIDTH 1 /* HPOUT1R_MUTE_N */ +#define WM8994_HPOUT1R_VOL_MASK 0x003F /* HPOUT1R_VOL - [5:0] */ +#define WM8994_HPOUT1R_VOL_SHIFT 0 /* HPOUT1R_VOL - [5:0] */ +#define WM8994_HPOUT1R_VOL_WIDTH 6 /* HPOUT1R_VOL - [5:0] */ + +/* + * R30 (0x1E) - Line Outputs Volume + */ +#define WM8994_LINEOUT1N_MUTE 0x0040 /* LINEOUT1N_MUTE */ +#define WM8994_LINEOUT1N_MUTE_MASK 0x0040 /* LINEOUT1N_MUTE */ +#define WM8994_LINEOUT1N_MUTE_SHIFT 6 /* LINEOUT1N_MUTE */ +#define WM8994_LINEOUT1N_MUTE_WIDTH 1 /* LINEOUT1N_MUTE */ +#define WM8994_LINEOUT1P_MUTE 0x0020 /* LINEOUT1P_MUTE */ +#define WM8994_LINEOUT1P_MUTE_MASK 0x0020 /* LINEOUT1P_MUTE */ +#define WM8994_LINEOUT1P_MUTE_SHIFT 5 /* LINEOUT1P_MUTE */ +#define WM8994_LINEOUT1P_MUTE_WIDTH 1 /* LINEOUT1P_MUTE */ +#define WM8994_LINEOUT1_VOL 0x0010 /* LINEOUT1_VOL */ +#define WM8994_LINEOUT1_VOL_MASK 0x0010 /* LINEOUT1_VOL */ +#define WM8994_LINEOUT1_VOL_SHIFT 4 /* LINEOUT1_VOL */ +#define WM8994_LINEOUT1_VOL_WIDTH 1 /* LINEOUT1_VOL */ +#define WM8994_LINEOUT2N_MUTE 0x0004 /* LINEOUT2N_MUTE */ +#define WM8994_LINEOUT2N_MUTE_MASK 0x0004 /* LINEOUT2N_MUTE */ +#define WM8994_LINEOUT2N_MUTE_SHIFT 2 /* LINEOUT2N_MUTE */ +#define WM8994_LINEOUT2N_MUTE_WIDTH 1 /* LINEOUT2N_MUTE */ +#define WM8994_LINEOUT2P_MUTE 0x0002 /* LINEOUT2P_MUTE */ +#define WM8994_LINEOUT2P_MUTE_MASK 0x0002 /* LINEOUT2P_MUTE */ +#define WM8994_LINEOUT2P_MUTE_SHIFT 1 /* LINEOUT2P_MUTE */ +#define WM8994_LINEOUT2P_MUTE_WIDTH 1 /* LINEOUT2P_MUTE */ +#define WM8994_LINEOUT2_VOL 0x0001 /* LINEOUT2_VOL */ +#define WM8994_LINEOUT2_VOL_MASK 0x0001 /* LINEOUT2_VOL */ +#define WM8994_LINEOUT2_VOL_SHIFT 0 /* LINEOUT2_VOL */ +#define WM8994_LINEOUT2_VOL_WIDTH 1 /* LINEOUT2_VOL */ + +/* + * R31 (0x1F) - HPOUT2 Volume + */ +#define WM8994_HPOUT2_MUTE 0x0020 /* HPOUT2_MUTE */ +#define WM8994_HPOUT2_MUTE_MASK 0x0020 /* HPOUT2_MUTE */ +#define WM8994_HPOUT2_MUTE_SHIFT 5 /* HPOUT2_MUTE */ +#define WM8994_HPOUT2_MUTE_WIDTH 1 /* HPOUT2_MUTE */ +#define WM8994_HPOUT2_VOL 0x0010 /* HPOUT2_VOL */ +#define WM8994_HPOUT2_VOL_MASK 0x0010 /* HPOUT2_VOL */ +#define WM8994_HPOUT2_VOL_SHIFT 4 /* HPOUT2_VOL */ +#define WM8994_HPOUT2_VOL_WIDTH 1 /* HPOUT2_VOL */ + +/* + * R32 (0x20) - Left OPGA Volume + */ +#define WM8994_MIXOUT_VU 0x0100 /* MIXOUT_VU */ +#define WM8994_MIXOUT_VU_MASK 0x0100 /* MIXOUT_VU */ +#define WM8994_MIXOUT_VU_SHIFT 8 /* MIXOUT_VU */ +#define WM8994_MIXOUT_VU_WIDTH 1 /* MIXOUT_VU */ +#define WM8994_MIXOUTL_ZC 0x0080 /* MIXOUTL_ZC */ +#define WM8994_MIXOUTL_ZC_MASK 0x0080 /* MIXOUTL_ZC */ +#define WM8994_MIXOUTL_ZC_SHIFT 7 /* MIXOUTL_ZC */ +#define WM8994_MIXOUTL_ZC_WIDTH 1 /* MIXOUTL_ZC */ +#define WM8994_MIXOUTL_MUTE_N 0x0040 /* MIXOUTL_MUTE_N */ +#define WM8994_MIXOUTL_MUTE_N_MASK 0x0040 /* MIXOUTL_MUTE_N */ +#define WM8994_MIXOUTL_MUTE_N_SHIFT 6 /* MIXOUTL_MUTE_N */ +#define WM8994_MIXOUTL_MUTE_N_WIDTH 1 /* MIXOUTL_MUTE_N */ +#define WM8994_MIXOUTL_VOL_MASK 0x003F /* MIXOUTL_VOL - [5:0] */ +#define WM8994_MIXOUTL_VOL_SHIFT 0 /* MIXOUTL_VOL - [5:0] */ +#define WM8994_MIXOUTL_VOL_WIDTH 6 /* MIXOUTL_VOL - [5:0] */ + +/* + * R33 (0x21) - Right OPGA Volume + */ +#define WM8994_MIXOUT_VU 0x0100 /* MIXOUT_VU */ +#define WM8994_MIXOUT_VU_MASK 0x0100 /* MIXOUT_VU */ +#define WM8994_MIXOUT_VU_SHIFT 8 /* MIXOUT_VU */ +#define WM8994_MIXOUT_VU_WIDTH 1 /* MIXOUT_VU */ +#define WM8994_MIXOUTR_ZC 0x0080 /* MIXOUTR_ZC */ +#define WM8994_MIXOUTR_ZC_MASK 0x0080 /* MIXOUTR_ZC */ +#define WM8994_MIXOUTR_ZC_SHIFT 7 /* MIXOUTR_ZC */ +#define WM8994_MIXOUTR_ZC_WIDTH 1 /* MIXOUTR_ZC */ +#define WM8994_MIXOUTR_MUTE_N 0x0040 /* MIXOUTR_MUTE_N */ +#define WM8994_MIXOUTR_MUTE_N_MASK 0x0040 /* MIXOUTR_MUTE_N */ +#define WM8994_MIXOUTR_MUTE_N_SHIFT 6 /* MIXOUTR_MUTE_N */ +#define WM8994_MIXOUTR_MUTE_N_WIDTH 1 /* MIXOUTR_MUTE_N */ +#define WM8994_MIXOUTR_VOL_MASK 0x003F /* MIXOUTR_VOL - [5:0] */ +#define WM8994_MIXOUTR_VOL_SHIFT 0 /* MIXOUTR_VOL - [5:0] */ +#define WM8994_MIXOUTR_VOL_WIDTH 6 /* MIXOUTR_VOL - [5:0] */ + +/* + * R34 (0x22) - SPKMIXL Attenuation + */ +#define WM8994_DAC2L_SPKMIXL_VOL 0x0040 /* DAC2L_SPKMIXL_VOL */ +#define WM8994_DAC2L_SPKMIXL_VOL_MASK 0x0040 /* DAC2L_SPKMIXL_VOL */ +#define WM8994_DAC2L_SPKMIXL_VOL_SHIFT 6 /* DAC2L_SPKMIXL_VOL */ +#define WM8994_DAC2L_SPKMIXL_VOL_WIDTH 1 /* DAC2L_SPKMIXL_VOL */ +#define WM8994_MIXINL_SPKMIXL_VOL 0x0020 /* MIXINL_SPKMIXL_VOL */ +#define WM8994_MIXINL_SPKMIXL_VOL_MASK 0x0020 /* MIXINL_SPKMIXL_VOL */ +#define WM8994_MIXINL_SPKMIXL_VOL_SHIFT 5 /* MIXINL_SPKMIXL_VOL */ +#define WM8994_MIXINL_SPKMIXL_VOL_WIDTH 1 /* MIXINL_SPKMIXL_VOL */ +#define WM8994_IN1LP_SPKMIXL_VOL 0x0010 /* IN1LP_SPKMIXL_VOL */ +#define WM8994_IN1LP_SPKMIXL_VOL_MASK 0x0010 /* IN1LP_SPKMIXL_VOL */ +#define WM8994_IN1LP_SPKMIXL_VOL_SHIFT 4 /* IN1LP_SPKMIXL_VOL */ +#define WM8994_IN1LP_SPKMIXL_VOL_WIDTH 1 /* IN1LP_SPKMIXL_VOL */ +#define WM8994_MIXOUTL_SPKMIXL_VOL 0x0008 /* MIXOUTL_SPKMIXL_VOL */ +#define WM8994_MIXOUTL_SPKMIXL_VOL_MASK 0x0008 /* MIXOUTL_SPKMIXL_VOL */ +#define WM8994_MIXOUTL_SPKMIXL_VOL_SHIFT 3 /* MIXOUTL_SPKMIXL_VOL */ +#define WM8994_MIXOUTL_SPKMIXL_VOL_WIDTH 1 /* MIXOUTL_SPKMIXL_VOL */ +#define WM8994_DAC1L_SPKMIXL_VOL 0x0004 /* DAC1L_SPKMIXL_VOL */ +#define WM8994_DAC1L_SPKMIXL_VOL_MASK 0x0004 /* DAC1L_SPKMIXL_VOL */ +#define WM8994_DAC1L_SPKMIXL_VOL_SHIFT 2 /* DAC1L_SPKMIXL_VOL */ +#define WM8994_DAC1L_SPKMIXL_VOL_WIDTH 1 /* DAC1L_SPKMIXL_VOL */ +#define WM8994_SPKMIXL_VOL_MASK 0x0003 /* SPKMIXL_VOL - [1:0] */ +#define WM8994_SPKMIXL_VOL_SHIFT 0 /* SPKMIXL_VOL - [1:0] */ +#define WM8994_SPKMIXL_VOL_WIDTH 2 /* SPKMIXL_VOL - [1:0] */ + +/* + * R35 (0x23) - SPKMIXR Attenuation + */ +#define WM8994_SPKOUT_CLASSAB 0x0100 /* SPKOUT_CLASSAB */ +#define WM8994_SPKOUT_CLASSAB_MASK 0x0100 /* SPKOUT_CLASSAB */ +#define WM8994_SPKOUT_CLASSAB_SHIFT 8 /* SPKOUT_CLASSAB */ +#define WM8994_SPKOUT_CLASSAB_WIDTH 1 /* SPKOUT_CLASSAB */ +#define WM8994_DAC2R_SPKMIXR_VOL 0x0040 /* DAC2R_SPKMIXR_VOL */ +#define WM8994_DAC2R_SPKMIXR_VOL_MASK 0x0040 /* DAC2R_SPKMIXR_VOL */ +#define WM8994_DAC2R_SPKMIXR_VOL_SHIFT 6 /* DAC2R_SPKMIXR_VOL */ +#define WM8994_DAC2R_SPKMIXR_VOL_WIDTH 1 /* DAC2R_SPKMIXR_VOL */ +#define WM8994_MIXINR_SPKMIXR_VOL 0x0020 /* MIXINR_SPKMIXR_VOL */ +#define WM8994_MIXINR_SPKMIXR_VOL_MASK 0x0020 /* MIXINR_SPKMIXR_VOL */ +#define WM8994_MIXINR_SPKMIXR_VOL_SHIFT 5 /* MIXINR_SPKMIXR_VOL */ +#define WM8994_MIXINR_SPKMIXR_VOL_WIDTH 1 /* MIXINR_SPKMIXR_VOL */ +#define WM8994_IN1RP_SPKMIXR_VOL 0x0010 /* IN1RP_SPKMIXR_VOL */ +#define WM8994_IN1RP_SPKMIXR_VOL_MASK 0x0010 /* IN1RP_SPKMIXR_VOL */ +#define WM8994_IN1RP_SPKMIXR_VOL_SHIFT 4 /* IN1RP_SPKMIXR_VOL */ +#define WM8994_IN1RP_SPKMIXR_VOL_WIDTH 1 /* IN1RP_SPKMIXR_VOL */ +#define WM8994_MIXOUTR_SPKMIXR_VOL 0x0008 /* MIXOUTR_SPKMIXR_VOL */ +#define WM8994_MIXOUTR_SPKMIXR_VOL_MASK 0x0008 /* MIXOUTR_SPKMIXR_VOL */ +#define WM8994_MIXOUTR_SPKMIXR_VOL_SHIFT 3 /* MIXOUTR_SPKMIXR_VOL */ +#define WM8994_MIXOUTR_SPKMIXR_VOL_WIDTH 1 /* MIXOUTR_SPKMIXR_VOL */ +#define WM8994_DAC1R_SPKMIXR_VOL 0x0004 /* DAC1R_SPKMIXR_VOL */ +#define WM8994_DAC1R_SPKMIXR_VOL_MASK 0x0004 /* DAC1R_SPKMIXR_VOL */ +#define WM8994_DAC1R_SPKMIXR_VOL_SHIFT 2 /* DAC1R_SPKMIXR_VOL */ +#define WM8994_DAC1R_SPKMIXR_VOL_WIDTH 1 /* DAC1R_SPKMIXR_VOL */ +#define WM8994_SPKMIXR_VOL_MASK 0x0003 /* SPKMIXR_VOL - [1:0] */ +#define WM8994_SPKMIXR_VOL_SHIFT 0 /* SPKMIXR_VOL - [1:0] */ +#define WM8994_SPKMIXR_VOL_WIDTH 2 /* SPKMIXR_VOL - [1:0] */ + +/* + * R36 (0x24) - SPKOUT Mixers + */ +#define WM8994_IN2LRP_TO_SPKOUTL 0x0020 /* IN2LRP_TO_SPKOUTL */ +#define WM8994_IN2LRP_TO_SPKOUTL_MASK 0x0020 /* IN2LRP_TO_SPKOUTL */ +#define WM8994_IN2LRP_TO_SPKOUTL_SHIFT 5 /* IN2LRP_TO_SPKOUTL */ +#define WM8994_IN2LRP_TO_SPKOUTL_WIDTH 1 /* IN2LRP_TO_SPKOUTL */ +#define WM8994_SPKMIXL_TO_SPKOUTL 0x0010 /* SPKMIXL_TO_SPKOUTL */ +#define WM8994_SPKMIXL_TO_SPKOUTL_MASK 0x0010 /* SPKMIXL_TO_SPKOUTL */ +#define WM8994_SPKMIXL_TO_SPKOUTL_SHIFT 4 /* SPKMIXL_TO_SPKOUTL */ +#define WM8994_SPKMIXL_TO_SPKOUTL_WIDTH 1 /* SPKMIXL_TO_SPKOUTL */ +#define WM8994_SPKMIXR_TO_SPKOUTL 0x0008 /* SPKMIXR_TO_SPKOUTL */ +#define WM8994_SPKMIXR_TO_SPKOUTL_MASK 0x0008 /* SPKMIXR_TO_SPKOUTL */ +#define WM8994_SPKMIXR_TO_SPKOUTL_SHIFT 3 /* SPKMIXR_TO_SPKOUTL */ +#define WM8994_SPKMIXR_TO_SPKOUTL_WIDTH 1 /* SPKMIXR_TO_SPKOUTL */ +#define WM8994_IN2LRP_TO_SPKOUTR 0x0004 /* IN2LRP_TO_SPKOUTR */ +#define WM8994_IN2LRP_TO_SPKOUTR_MASK 0x0004 /* IN2LRP_TO_SPKOUTR */ +#define WM8994_IN2LRP_TO_SPKOUTR_SHIFT 2 /* IN2LRP_TO_SPKOUTR */ +#define WM8994_IN2LRP_TO_SPKOUTR_WIDTH 1 /* IN2LRP_TO_SPKOUTR */ +#define WM8994_SPKMIXL_TO_SPKOUTR 0x0002 /* SPKMIXL_TO_SPKOUTR */ +#define WM8994_SPKMIXL_TO_SPKOUTR_MASK 0x0002 /* SPKMIXL_TO_SPKOUTR */ +#define WM8994_SPKMIXL_TO_SPKOUTR_SHIFT 1 /* SPKMIXL_TO_SPKOUTR */ +#define WM8994_SPKMIXL_TO_SPKOUTR_WIDTH 1 /* SPKMIXL_TO_SPKOUTR */ +#define WM8994_SPKMIXR_TO_SPKOUTR 0x0001 /* SPKMIXR_TO_SPKOUTR */ +#define WM8994_SPKMIXR_TO_SPKOUTR_MASK 0x0001 /* SPKMIXR_TO_SPKOUTR */ +#define WM8994_SPKMIXR_TO_SPKOUTR_SHIFT 0 /* SPKMIXR_TO_SPKOUTR */ +#define WM8994_SPKMIXR_TO_SPKOUTR_WIDTH 1 /* SPKMIXR_TO_SPKOUTR */ + +/* + * R37 (0x25) - ClassD + */ +#define WM8994_SPKOUTL_BOOST_MASK 0x0038 /* SPKOUTL_BOOST - [5:3] */ +#define WM8994_SPKOUTL_BOOST_SHIFT 3 /* SPKOUTL_BOOST - [5:3] */ +#define WM8994_SPKOUTL_BOOST_WIDTH 3 /* SPKOUTL_BOOST - [5:3] */ +#define WM8994_SPKOUTR_BOOST_MASK 0x0007 /* SPKOUTR_BOOST - [2:0] */ +#define WM8994_SPKOUTR_BOOST_SHIFT 0 /* SPKOUTR_BOOST - [2:0] */ +#define WM8994_SPKOUTR_BOOST_WIDTH 3 /* SPKOUTR_BOOST - [2:0] */ + +/* + * R38 (0x26) - Speaker Volume Left + */ +#define WM8994_SPKOUT_VU 0x0100 /* SPKOUT_VU */ +#define WM8994_SPKOUT_VU_MASK 0x0100 /* SPKOUT_VU */ +#define WM8994_SPKOUT_VU_SHIFT 8 /* SPKOUT_VU */ +#define WM8994_SPKOUT_VU_WIDTH 1 /* SPKOUT_VU */ +#define WM8994_SPKOUTL_ZC 0x0080 /* SPKOUTL_ZC */ +#define WM8994_SPKOUTL_ZC_MASK 0x0080 /* SPKOUTL_ZC */ +#define WM8994_SPKOUTL_ZC_SHIFT 7 /* SPKOUTL_ZC */ +#define WM8994_SPKOUTL_ZC_WIDTH 1 /* SPKOUTL_ZC */ +#define WM8994_SPKOUTL_MUTE_N 0x0040 /* SPKOUTL_MUTE_N */ +#define WM8994_SPKOUTL_MUTE_N_MASK 0x0040 /* SPKOUTL_MUTE_N */ +#define WM8994_SPKOUTL_MUTE_N_SHIFT 6 /* SPKOUTL_MUTE_N */ +#define WM8994_SPKOUTL_MUTE_N_WIDTH 1 /* SPKOUTL_MUTE_N */ +#define WM8994_SPKOUTL_VOL_MASK 0x003F /* SPKOUTL_VOL - [5:0] */ +#define WM8994_SPKOUTL_VOL_SHIFT 0 /* SPKOUTL_VOL - [5:0] */ +#define WM8994_SPKOUTL_VOL_WIDTH 6 /* SPKOUTL_VOL - [5:0] */ + +/* + * R39 (0x27) - Speaker Volume Right + */ +#define WM8994_SPKOUT_VU 0x0100 /* SPKOUT_VU */ +#define WM8994_SPKOUT_VU_MASK 0x0100 /* SPKOUT_VU */ +#define WM8994_SPKOUT_VU_SHIFT 8 /* SPKOUT_VU */ +#define WM8994_SPKOUT_VU_WIDTH 1 /* SPKOUT_VU */ +#define WM8994_SPKOUTR_ZC 0x0080 /* SPKOUTR_ZC */ +#define WM8994_SPKOUTR_ZC_MASK 0x0080 /* SPKOUTR_ZC */ +#define WM8994_SPKOUTR_ZC_SHIFT 7 /* SPKOUTR_ZC */ +#define WM8994_SPKOUTR_ZC_WIDTH 1 /* SPKOUTR_ZC */ +#define WM8994_SPKOUTR_MUTE_N 0x0040 /* SPKOUTR_MUTE_N */ +#define WM8994_SPKOUTR_MUTE_N_MASK 0x0040 /* SPKOUTR_MUTE_N */ +#define WM8994_SPKOUTR_MUTE_N_SHIFT 6 /* SPKOUTR_MUTE_N */ +#define WM8994_SPKOUTR_MUTE_N_WIDTH 1 /* SPKOUTR_MUTE_N */ +#define WM8994_SPKOUTR_VOL_MASK 0x003F /* SPKOUTR_VOL - [5:0] */ +#define WM8994_SPKOUTR_VOL_SHIFT 0 /* SPKOUTR_VOL - [5:0] */ +#define WM8994_SPKOUTR_VOL_WIDTH 6 /* SPKOUTR_VOL - [5:0] */ + +/* + * R40 (0x28) - Input Mixer (2) + */ +#define WM8994_IN2LP_TO_IN2L 0x0080 /* IN2LP_TO_IN2L */ +#define WM8994_IN2LP_TO_IN2L_MASK 0x0080 /* IN2LP_TO_IN2L */ +#define WM8994_IN2LP_TO_IN2L_SHIFT 7 /* IN2LP_TO_IN2L */ +#define WM8994_IN2LP_TO_IN2L_WIDTH 1 /* IN2LP_TO_IN2L */ +#define WM8994_IN2LN_TO_IN2L 0x0040 /* IN2LN_TO_IN2L */ +#define WM8994_IN2LN_TO_IN2L_MASK 0x0040 /* IN2LN_TO_IN2L */ +#define WM8994_IN2LN_TO_IN2L_SHIFT 6 /* IN2LN_TO_IN2L */ +#define WM8994_IN2LN_TO_IN2L_WIDTH 1 /* IN2LN_TO_IN2L */ +#define WM8994_IN1LP_TO_IN1L 0x0020 /* IN1LP_TO_IN1L */ +#define WM8994_IN1LP_TO_IN1L_MASK 0x0020 /* IN1LP_TO_IN1L */ +#define WM8994_IN1LP_TO_IN1L_SHIFT 5 /* IN1LP_TO_IN1L */ +#define WM8994_IN1LP_TO_IN1L_WIDTH 1 /* IN1LP_TO_IN1L */ +#define WM8994_IN1LN_TO_IN1L 0x0010 /* IN1LN_TO_IN1L */ +#define WM8994_IN1LN_TO_IN1L_MASK 0x0010 /* IN1LN_TO_IN1L */ +#define WM8994_IN1LN_TO_IN1L_SHIFT 4 /* IN1LN_TO_IN1L */ +#define WM8994_IN1LN_TO_IN1L_WIDTH 1 /* IN1LN_TO_IN1L */ +#define WM8994_IN2RP_TO_IN2R 0x0008 /* IN2RP_TO_IN2R */ +#define WM8994_IN2RP_TO_IN2R_MASK 0x0008 /* IN2RP_TO_IN2R */ +#define WM8994_IN2RP_TO_IN2R_SHIFT 3 /* IN2RP_TO_IN2R */ +#define WM8994_IN2RP_TO_IN2R_WIDTH 1 /* IN2RP_TO_IN2R */ +#define WM8994_IN2RN_TO_IN2R 0x0004 /* IN2RN_TO_IN2R */ +#define WM8994_IN2RN_TO_IN2R_MASK 0x0004 /* IN2RN_TO_IN2R */ +#define WM8994_IN2RN_TO_IN2R_SHIFT 2 /* IN2RN_TO_IN2R */ +#define WM8994_IN2RN_TO_IN2R_WIDTH 1 /* IN2RN_TO_IN2R */ +#define WM8994_IN1RP_TO_IN1R 0x0002 /* IN1RP_TO_IN1R */ +#define WM8994_IN1RP_TO_IN1R_MASK 0x0002 /* IN1RP_TO_IN1R */ +#define WM8994_IN1RP_TO_IN1R_SHIFT 1 /* IN1RP_TO_IN1R */ +#define WM8994_IN1RP_TO_IN1R_WIDTH 1 /* IN1RP_TO_IN1R */ +#define WM8994_IN1RN_TO_IN1R 0x0001 /* IN1RN_TO_IN1R */ +#define WM8994_IN1RN_TO_IN1R_MASK 0x0001 /* IN1RN_TO_IN1R */ +#define WM8994_IN1RN_TO_IN1R_SHIFT 0 /* IN1RN_TO_IN1R */ +#define WM8994_IN1RN_TO_IN1R_WIDTH 1 /* IN1RN_TO_IN1R */ + +/* + * R41 (0x29) - Input Mixer (3) + */ +#define WM8994_IN2L_TO_MIXINL 0x0100 /* IN2L_TO_MIXINL */ +#define WM8994_IN2L_TO_MIXINL_MASK 0x0100 /* IN2L_TO_MIXINL */ +#define WM8994_IN2L_TO_MIXINL_SHIFT 8 /* IN2L_TO_MIXINL */ +#define WM8994_IN2L_TO_MIXINL_WIDTH 1 /* IN2L_TO_MIXINL */ +#define WM8994_IN2L_MIXINL_VOL 0x0080 /* IN2L_MIXINL_VOL */ +#define WM8994_IN2L_MIXINL_VOL_MASK 0x0080 /* IN2L_MIXINL_VOL */ +#define WM8994_IN2L_MIXINL_VOL_SHIFT 7 /* IN2L_MIXINL_VOL */ +#define WM8994_IN2L_MIXINL_VOL_WIDTH 1 /* IN2L_MIXINL_VOL */ +#define WM8994_IN1L_TO_MIXINL 0x0020 /* IN1L_TO_MIXINL */ +#define WM8994_IN1L_TO_MIXINL_MASK 0x0020 /* IN1L_TO_MIXINL */ +#define WM8994_IN1L_TO_MIXINL_SHIFT 5 /* IN1L_TO_MIXINL */ +#define WM8994_IN1L_TO_MIXINL_WIDTH 1 /* IN1L_TO_MIXINL */ +#define WM8994_IN1L_MIXINL_VOL 0x0010 /* IN1L_MIXINL_VOL */ +#define WM8994_IN1L_MIXINL_VOL_MASK 0x0010 /* IN1L_MIXINL_VOL */ +#define WM8994_IN1L_MIXINL_VOL_SHIFT 4 /* IN1L_MIXINL_VOL */ +#define WM8994_IN1L_MIXINL_VOL_WIDTH 1 /* IN1L_MIXINL_VOL */ +#define WM8994_MIXOUTL_MIXINL_VOL_MASK 0x0007 /* MIXOUTL_MIXINL_VOL - [2:0] */ +#define WM8994_MIXOUTL_MIXINL_VOL_SHIFT 0 /* MIXOUTL_MIXINL_VOL - [2:0] */ +#define WM8994_MIXOUTL_MIXINL_VOL_WIDTH 3 /* MIXOUTL_MIXINL_VOL - [2:0] */ + +/* + * R42 (0x2A) - Input Mixer (4) + */ +#define WM8994_IN2R_TO_MIXINR 0x0100 /* IN2R_TO_MIXINR */ +#define WM8994_IN2R_TO_MIXINR_MASK 0x0100 /* IN2R_TO_MIXINR */ +#define WM8994_IN2R_TO_MIXINR_SHIFT 8 /* IN2R_TO_MIXINR */ +#define WM8994_IN2R_TO_MIXINR_WIDTH 1 /* IN2R_TO_MIXINR */ +#define WM8994_IN2R_MIXINR_VOL 0x0080 /* IN2R_MIXINR_VOL */ +#define WM8994_IN2R_MIXINR_VOL_MASK 0x0080 /* IN2R_MIXINR_VOL */ +#define WM8994_IN2R_MIXINR_VOL_SHIFT 7 /* IN2R_MIXINR_VOL */ +#define WM8994_IN2R_MIXINR_VOL_WIDTH 1 /* IN2R_MIXINR_VOL */ +#define WM8994_IN1R_TO_MIXINR 0x0020 /* IN1R_TO_MIXINR */ +#define WM8994_IN1R_TO_MIXINR_MASK 0x0020 /* IN1R_TO_MIXINR */ +#define WM8994_IN1R_TO_MIXINR_SHIFT 5 /* IN1R_TO_MIXINR */ +#define WM8994_IN1R_TO_MIXINR_WIDTH 1 /* IN1R_TO_MIXINR */ +#define WM8994_IN1R_MIXINR_VOL 0x0010 /* IN1R_MIXINR_VOL */ +#define WM8994_IN1R_MIXINR_VOL_MASK 0x0010 /* IN1R_MIXINR_VOL */ +#define WM8994_IN1R_MIXINR_VOL_SHIFT 4 /* IN1R_MIXINR_VOL */ +#define WM8994_IN1R_MIXINR_VOL_WIDTH 1 /* IN1R_MIXINR_VOL */ +#define WM8994_MIXOUTR_MIXINR_VOL_MASK 0x0007 /* MIXOUTR_MIXINR_VOL - [2:0] */ +#define WM8994_MIXOUTR_MIXINR_VOL_SHIFT 0 /* MIXOUTR_MIXINR_VOL - [2:0] */ +#define WM8994_MIXOUTR_MIXINR_VOL_WIDTH 3 /* MIXOUTR_MIXINR_VOL - [2:0] */ + +/* + * R43 (0x2B) - Input Mixer (5) + */ +#define WM8994_IN1LP_MIXINL_VOL_MASK 0x01C0 /* IN1LP_MIXINL_VOL - [8:6] */ +#define WM8994_IN1LP_MIXINL_VOL_SHIFT 6 /* IN1LP_MIXINL_VOL - [8:6] */ +#define WM8994_IN1LP_MIXINL_VOL_WIDTH 3 /* IN1LP_MIXINL_VOL - [8:6] */ +#define WM8994_IN2LRP_MIXINL_VOL_MASK 0x0007 /* IN2LRP_MIXINL_VOL - [2:0] */ +#define WM8994_IN2LRP_MIXINL_VOL_SHIFT 0 /* IN2LRP_MIXINL_VOL - [2:0] */ +#define WM8994_IN2LRP_MIXINL_VOL_WIDTH 3 /* IN2LRP_MIXINL_VOL - [2:0] */ + +/* + * R44 (0x2C) - Input Mixer (6) + */ +#define WM8994_IN1RP_MIXINR_VOL_MASK 0x01C0 /* IN1RP_MIXINR_VOL - [8:6] */ +#define WM8994_IN1RP_MIXINR_VOL_SHIFT 6 /* IN1RP_MIXINR_VOL - [8:6] */ +#define WM8994_IN1RP_MIXINR_VOL_WIDTH 3 /* IN1RP_MIXINR_VOL - [8:6] */ +#define WM8994_IN2LRP_MIXINR_VOL_MASK 0x0007 /* IN2LRP_MIXINR_VOL - [2:0] */ +#define WM8994_IN2LRP_MIXINR_VOL_SHIFT 0 /* IN2LRP_MIXINR_VOL - [2:0] */ +#define WM8994_IN2LRP_MIXINR_VOL_WIDTH 3 /* IN2LRP_MIXINR_VOL - [2:0] */ + +/* + * R45 (0x2D) - Output Mixer (1) + */ +#define WM8994_DAC1L_TO_HPOUT1L 0x0100 /* DAC1L_TO_HPOUT1L */ +#define WM8994_DAC1L_TO_HPOUT1L_MASK 0x0100 /* DAC1L_TO_HPOUT1L */ +#define WM8994_DAC1L_TO_HPOUT1L_SHIFT 8 /* DAC1L_TO_HPOUT1L */ +#define WM8994_DAC1L_TO_HPOUT1L_WIDTH 1 /* DAC1L_TO_HPOUT1L */ +#define WM8994_MIXINR_TO_MIXOUTL 0x0080 /* MIXINR_TO_MIXOUTL */ +#define WM8994_MIXINR_TO_MIXOUTL_MASK 0x0080 /* MIXINR_TO_MIXOUTL */ +#define WM8994_MIXINR_TO_MIXOUTL_SHIFT 7 /* MIXINR_TO_MIXOUTL */ +#define WM8994_MIXINR_TO_MIXOUTL_WIDTH 1 /* MIXINR_TO_MIXOUTL */ +#define WM8994_MIXINL_TO_MIXOUTL 0x0040 /* MIXINL_TO_MIXOUTL */ +#define WM8994_MIXINL_TO_MIXOUTL_MASK 0x0040 /* MIXINL_TO_MIXOUTL */ +#define WM8994_MIXINL_TO_MIXOUTL_SHIFT 6 /* MIXINL_TO_MIXOUTL */ +#define WM8994_MIXINL_TO_MIXOUTL_WIDTH 1 /* MIXINL_TO_MIXOUTL */ +#define WM8994_IN2RN_TO_MIXOUTL 0x0020 /* IN2RN_TO_MIXOUTL */ +#define WM8994_IN2RN_TO_MIXOUTL_MASK 0x0020 /* IN2RN_TO_MIXOUTL */ +#define WM8994_IN2RN_TO_MIXOUTL_SHIFT 5 /* IN2RN_TO_MIXOUTL */ +#define WM8994_IN2RN_TO_MIXOUTL_WIDTH 1 /* IN2RN_TO_MIXOUTL */ +#define WM8994_IN2LN_TO_MIXOUTL 0x0010 /* IN2LN_TO_MIXOUTL */ +#define WM8994_IN2LN_TO_MIXOUTL_MASK 0x0010 /* IN2LN_TO_MIXOUTL */ +#define WM8994_IN2LN_TO_MIXOUTL_SHIFT 4 /* IN2LN_TO_MIXOUTL */ +#define WM8994_IN2LN_TO_MIXOUTL_WIDTH 1 /* IN2LN_TO_MIXOUTL */ +#define WM8994_IN1R_TO_MIXOUTL 0x0008 /* IN1R_TO_MIXOUTL */ +#define WM8994_IN1R_TO_MIXOUTL_MASK 0x0008 /* IN1R_TO_MIXOUTL */ +#define WM8994_IN1R_TO_MIXOUTL_SHIFT 3 /* IN1R_TO_MIXOUTL */ +#define WM8994_IN1R_TO_MIXOUTL_WIDTH 1 /* IN1R_TO_MIXOUTL */ +#define WM8994_IN1L_TO_MIXOUTL 0x0004 /* IN1L_TO_MIXOUTL */ +#define WM8994_IN1L_TO_MIXOUTL_MASK 0x0004 /* IN1L_TO_MIXOUTL */ +#define WM8994_IN1L_TO_MIXOUTL_SHIFT 2 /* IN1L_TO_MIXOUTL */ +#define WM8994_IN1L_TO_MIXOUTL_WIDTH 1 /* IN1L_TO_MIXOUTL */ +#define WM8994_IN2LP_TO_MIXOUTL 0x0002 /* IN2LP_TO_MIXOUTL */ +#define WM8994_IN2LP_TO_MIXOUTL_MASK 0x0002 /* IN2LP_TO_MIXOUTL */ +#define WM8994_IN2LP_TO_MIXOUTL_SHIFT 1 /* IN2LP_TO_MIXOUTL */ +#define WM8994_IN2LP_TO_MIXOUTL_WIDTH 1 /* IN2LP_TO_MIXOUTL */ +#define WM8994_DAC1L_TO_MIXOUTL 0x0001 /* DAC1L_TO_MIXOUTL */ +#define WM8994_DAC1L_TO_MIXOUTL_MASK 0x0001 /* DAC1L_TO_MIXOUTL */ +#define WM8994_DAC1L_TO_MIXOUTL_SHIFT 0 /* DAC1L_TO_MIXOUTL */ +#define WM8994_DAC1L_TO_MIXOUTL_WIDTH 1 /* DAC1L_TO_MIXOUTL */ + +/* + * R46 (0x2E) - Output Mixer (2) + */ +#define WM8994_DAC1R_TO_HPOUT1R 0x0100 /* DAC1R_TO_HPOUT1R */ +#define WM8994_DAC1R_TO_HPOUT1R_MASK 0x0100 /* DAC1R_TO_HPOUT1R */ +#define WM8994_DAC1R_TO_HPOUT1R_SHIFT 8 /* DAC1R_TO_HPOUT1R */ +#define WM8994_DAC1R_TO_HPOUT1R_WIDTH 1 /* DAC1R_TO_HPOUT1R */ +#define WM8994_MIXINL_TO_MIXOUTR 0x0080 /* MIXINL_TO_MIXOUTR */ +#define WM8994_MIXINL_TO_MIXOUTR_MASK 0x0080 /* MIXINL_TO_MIXOUTR */ +#define WM8994_MIXINL_TO_MIXOUTR_SHIFT 7 /* MIXINL_TO_MIXOUTR */ +#define WM8994_MIXINL_TO_MIXOUTR_WIDTH 1 /* MIXINL_TO_MIXOUTR */ +#define WM8994_MIXINR_TO_MIXOUTR 0x0040 /* MIXINR_TO_MIXOUTR */ +#define WM8994_MIXINR_TO_MIXOUTR_MASK 0x0040 /* MIXINR_TO_MIXOUTR */ +#define WM8994_MIXINR_TO_MIXOUTR_SHIFT 6 /* MIXINR_TO_MIXOUTR */ +#define WM8994_MIXINR_TO_MIXOUTR_WIDTH 1 /* MIXINR_TO_MIXOUTR */ +#define WM8994_IN2LN_TO_MIXOUTR 0x0020 /* IN2LN_TO_MIXOUTR */ +#define WM8994_IN2LN_TO_MIXOUTR_MASK 0x0020 /* IN2LN_TO_MIXOUTR */ +#define WM8994_IN2LN_TO_MIXOUTR_SHIFT 5 /* IN2LN_TO_MIXOUTR */ +#define WM8994_IN2LN_TO_MIXOUTR_WIDTH 1 /* IN2LN_TO_MIXOUTR */ +#define WM8994_IN2RN_TO_MIXOUTR 0x0010 /* IN2RN_TO_MIXOUTR */ +#define WM8994_IN2RN_TO_MIXOUTR_MASK 0x0010 /* IN2RN_TO_MIXOUTR */ +#define WM8994_IN2RN_TO_MIXOUTR_SHIFT 4 /* IN2RN_TO_MIXOUTR */ +#define WM8994_IN2RN_TO_MIXOUTR_WIDTH 1 /* IN2RN_TO_MIXOUTR */ +#define WM8994_IN1L_TO_MIXOUTR 0x0008 /* IN1L_TO_MIXOUTR */ +#define WM8994_IN1L_TO_MIXOUTR_MASK 0x0008 /* IN1L_TO_MIXOUTR */ +#define WM8994_IN1L_TO_MIXOUTR_SHIFT 3 /* IN1L_TO_MIXOUTR */ +#define WM8994_IN1L_TO_MIXOUTR_WIDTH 1 /* IN1L_TO_MIXOUTR */ +#define WM8994_IN1R_TO_MIXOUTR 0x0004 /* IN1R_TO_MIXOUTR */ +#define WM8994_IN1R_TO_MIXOUTR_MASK 0x0004 /* IN1R_TO_MIXOUTR */ +#define WM8994_IN1R_TO_MIXOUTR_SHIFT 2 /* IN1R_TO_MIXOUTR */ +#define WM8994_IN1R_TO_MIXOUTR_WIDTH 1 /* IN1R_TO_MIXOUTR */ +#define WM8994_IN2RP_TO_MIXOUTR 0x0002 /* IN2RP_TO_MIXOUTR */ +#define WM8994_IN2RP_TO_MIXOUTR_MASK 0x0002 /* IN2RP_TO_MIXOUTR */ +#define WM8994_IN2RP_TO_MIXOUTR_SHIFT 1 /* IN2RP_TO_MIXOUTR */ +#define WM8994_IN2RP_TO_MIXOUTR_WIDTH 1 /* IN2RP_TO_MIXOUTR */ +#define WM8994_DAC1R_TO_MIXOUTR 0x0001 /* DAC1R_TO_MIXOUTR */ +#define WM8994_DAC1R_TO_MIXOUTR_MASK 0x0001 /* DAC1R_TO_MIXOUTR */ +#define WM8994_DAC1R_TO_MIXOUTR_SHIFT 0 /* DAC1R_TO_MIXOUTR */ +#define WM8994_DAC1R_TO_MIXOUTR_WIDTH 1 /* DAC1R_TO_MIXOUTR */ + +/* + * R47 (0x2F) - Output Mixer (3) + */ +#define WM8994_IN2LP_MIXOUTL_VOL_MASK 0x0E00 /* IN2LP_MIXOUTL_VOL - [11:9] */ +#define WM8994_IN2LP_MIXOUTL_VOL_SHIFT 9 /* IN2LP_MIXOUTL_VOL - [11:9] */ +#define WM8994_IN2LP_MIXOUTL_VOL_WIDTH 3 /* IN2LP_MIXOUTL_VOL - [11:9] */ +#define WM8994_IN2LN_MIXOUTL_VOL_MASK 0x01C0 /* IN2LN_MIXOUTL_VOL - [8:6] */ +#define WM8994_IN2LN_MIXOUTL_VOL_SHIFT 6 /* IN2LN_MIXOUTL_VOL - [8:6] */ +#define WM8994_IN2LN_MIXOUTL_VOL_WIDTH 3 /* IN2LN_MIXOUTL_VOL - [8:6] */ +#define WM8994_IN1R_MIXOUTL_VOL_MASK 0x0038 /* IN1R_MIXOUTL_VOL - [5:3] */ +#define WM8994_IN1R_MIXOUTL_VOL_SHIFT 3 /* IN1R_MIXOUTL_VOL - [5:3] */ +#define WM8994_IN1R_MIXOUTL_VOL_WIDTH 3 /* IN1R_MIXOUTL_VOL - [5:3] */ +#define WM8994_IN1L_MIXOUTL_VOL_MASK 0x0007 /* IN1L_MIXOUTL_VOL - [2:0] */ +#define WM8994_IN1L_MIXOUTL_VOL_SHIFT 0 /* IN1L_MIXOUTL_VOL - [2:0] */ +#define WM8994_IN1L_MIXOUTL_VOL_WIDTH 3 /* IN1L_MIXOUTL_VOL - [2:0] */ + +/* + * R48 (0x30) - Output Mixer (4) + */ +#define WM8994_IN2RP_MIXOUTR_VOL_MASK 0x0E00 /* IN2RP_MIXOUTR_VOL - [11:9] */ +#define WM8994_IN2RP_MIXOUTR_VOL_SHIFT 9 /* IN2RP_MIXOUTR_VOL - [11:9] */ +#define WM8994_IN2RP_MIXOUTR_VOL_WIDTH 3 /* IN2RP_MIXOUTR_VOL - [11:9] */ +#define WM8994_IN2RN_MIXOUTR_VOL_MASK 0x01C0 /* IN2RN_MIXOUTR_VOL - [8:6] */ +#define WM8994_IN2RN_MIXOUTR_VOL_SHIFT 6 /* IN2RN_MIXOUTR_VOL - [8:6] */ +#define WM8994_IN2RN_MIXOUTR_VOL_WIDTH 3 /* IN2RN_MIXOUTR_VOL - [8:6] */ +#define WM8994_IN1L_MIXOUTR_VOL_MASK 0x0038 /* IN1L_MIXOUTR_VOL - [5:3] */ +#define WM8994_IN1L_MIXOUTR_VOL_SHIFT 3 /* IN1L_MIXOUTR_VOL - [5:3] */ +#define WM8994_IN1L_MIXOUTR_VOL_WIDTH 3 /* IN1L_MIXOUTR_VOL - [5:3] */ +#define WM8994_IN1R_MIXOUTR_VOL_MASK 0x0007 /* IN1R_MIXOUTR_VOL - [2:0] */ +#define WM8994_IN1R_MIXOUTR_VOL_SHIFT 0 /* IN1R_MIXOUTR_VOL - [2:0] */ +#define WM8994_IN1R_MIXOUTR_VOL_WIDTH 3 /* IN1R_MIXOUTR_VOL - [2:0] */ + +/* + * R49 (0x31) - Output Mixer (5) + */ +#define WM8994_DAC1L_MIXOUTL_VOL_MASK 0x0E00 /* DAC1L_MIXOUTL_VOL - [11:9] */ +#define WM8994_DAC1L_MIXOUTL_VOL_SHIFT 9 /* DAC1L_MIXOUTL_VOL - [11:9] */ +#define WM8994_DAC1L_MIXOUTL_VOL_WIDTH 3 /* DAC1L_MIXOUTL_VOL - [11:9] */ +#define WM8994_IN2RN_MIXOUTL_VOL_MASK 0x01C0 /* IN2RN_MIXOUTL_VOL - [8:6] */ +#define WM8994_IN2RN_MIXOUTL_VOL_SHIFT 6 /* IN2RN_MIXOUTL_VOL - [8:6] */ +#define WM8994_IN2RN_MIXOUTL_VOL_WIDTH 3 /* IN2RN_MIXOUTL_VOL - [8:6] */ +#define WM8994_MIXINR_MIXOUTL_VOL_MASK 0x0038 /* MIXINR_MIXOUTL_VOL - [5:3] */ +#define WM8994_MIXINR_MIXOUTL_VOL_SHIFT 3 /* MIXINR_MIXOUTL_VOL - [5:3] */ +#define WM8994_MIXINR_MIXOUTL_VOL_WIDTH 3 /* MIXINR_MIXOUTL_VOL - [5:3] */ +#define WM8994_MIXINL_MIXOUTL_VOL_MASK 0x0007 /* MIXINL_MIXOUTL_VOL - [2:0] */ +#define WM8994_MIXINL_MIXOUTL_VOL_SHIFT 0 /* MIXINL_MIXOUTL_VOL - [2:0] */ +#define WM8994_MIXINL_MIXOUTL_VOL_WIDTH 3 /* MIXINL_MIXOUTL_VOL - [2:0] */ + +/* + * R50 (0x32) - Output Mixer (6) + */ +#define WM8994_DAC1R_MIXOUTR_VOL_MASK 0x0E00 /* DAC1R_MIXOUTR_VOL - [11:9] */ +#define WM8994_DAC1R_MIXOUTR_VOL_SHIFT 9 /* DAC1R_MIXOUTR_VOL - [11:9] */ +#define WM8994_DAC1R_MIXOUTR_VOL_WIDTH 3 /* DAC1R_MIXOUTR_VOL - [11:9] */ +#define WM8994_IN2LN_MIXOUTR_VOL_MASK 0x01C0 /* IN2LN_MIXOUTR_VOL - [8:6] */ +#define WM8994_IN2LN_MIXOUTR_VOL_SHIFT 6 /* IN2LN_MIXOUTR_VOL - [8:6] */ +#define WM8994_IN2LN_MIXOUTR_VOL_WIDTH 3 /* IN2LN_MIXOUTR_VOL - [8:6] */ +#define WM8994_MIXINL_MIXOUTR_VOL_MASK 0x0038 /* MIXINL_MIXOUTR_VOL - [5:3] */ +#define WM8994_MIXINL_MIXOUTR_VOL_SHIFT 3 /* MIXINL_MIXOUTR_VOL - [5:3] */ +#define WM8994_MIXINL_MIXOUTR_VOL_WIDTH 3 /* MIXINL_MIXOUTR_VOL - [5:3] */ +#define WM8994_MIXINR_MIXOUTR_VOL_MASK 0x0007 /* MIXINR_MIXOUTR_VOL - [2:0] */ +#define WM8994_MIXINR_MIXOUTR_VOL_SHIFT 0 /* MIXINR_MIXOUTR_VOL - [2:0] */ +#define WM8994_MIXINR_MIXOUTR_VOL_WIDTH 3 /* MIXINR_MIXOUTR_VOL - [2:0] */ + +/* + * R51 (0x33) - HPOUT2 Mixer + */ +#define WM8994_IN2LRP_TO_HPOUT2 0x0020 /* IN2LRP_TO_HPOUT2 */ +#define WM8994_IN2LRP_TO_HPOUT2_MASK 0x0020 /* IN2LRP_TO_HPOUT2 */ +#define WM8994_IN2LRP_TO_HPOUT2_SHIFT 5 /* IN2LRP_TO_HPOUT2 */ +#define WM8994_IN2LRP_TO_HPOUT2_WIDTH 1 /* IN2LRP_TO_HPOUT2 */ +#define WM8994_MIXOUTLVOL_TO_HPOUT2 0x0010 /* MIXOUTLVOL_TO_HPOUT2 */ +#define WM8994_MIXOUTLVOL_TO_HPOUT2_MASK 0x0010 /* MIXOUTLVOL_TO_HPOUT2 */ +#define WM8994_MIXOUTLVOL_TO_HPOUT2_SHIFT 4 /* MIXOUTLVOL_TO_HPOUT2 */ +#define WM8994_MIXOUTLVOL_TO_HPOUT2_WIDTH 1 /* MIXOUTLVOL_TO_HPOUT2 */ +#define WM8994_MIXOUTRVOL_TO_HPOUT2 0x0008 /* MIXOUTRVOL_TO_HPOUT2 */ +#define WM8994_MIXOUTRVOL_TO_HPOUT2_MASK 0x0008 /* MIXOUTRVOL_TO_HPOUT2 */ +#define WM8994_MIXOUTRVOL_TO_HPOUT2_SHIFT 3 /* MIXOUTRVOL_TO_HPOUT2 */ +#define WM8994_MIXOUTRVOL_TO_HPOUT2_WIDTH 1 /* MIXOUTRVOL_TO_HPOUT2 */ + +/* + * R52 (0x34) - Line Mixer (1) + */ +#define WM8994_MIXOUTL_TO_LINEOUT1N 0x0040 /* MIXOUTL_TO_LINEOUT1N */ +#define WM8994_MIXOUTL_TO_LINEOUT1N_MASK 0x0040 /* MIXOUTL_TO_LINEOUT1N */ +#define WM8994_MIXOUTL_TO_LINEOUT1N_SHIFT 6 /* MIXOUTL_TO_LINEOUT1N */ +#define WM8994_MIXOUTL_TO_LINEOUT1N_WIDTH 1 /* MIXOUTL_TO_LINEOUT1N */ +#define WM8994_MIXOUTR_TO_LINEOUT1N 0x0020 /* MIXOUTR_TO_LINEOUT1N */ +#define WM8994_MIXOUTR_TO_LINEOUT1N_MASK 0x0020 /* MIXOUTR_TO_LINEOUT1N */ +#define WM8994_MIXOUTR_TO_LINEOUT1N_SHIFT 5 /* MIXOUTR_TO_LINEOUT1N */ +#define WM8994_MIXOUTR_TO_LINEOUT1N_WIDTH 1 /* MIXOUTR_TO_LINEOUT1N */ +#define WM8994_LINEOUT1_MODE 0x0010 /* LINEOUT1_MODE */ +#define WM8994_LINEOUT1_MODE_MASK 0x0010 /* LINEOUT1_MODE */ +#define WM8994_LINEOUT1_MODE_SHIFT 4 /* LINEOUT1_MODE */ +#define WM8994_LINEOUT1_MODE_WIDTH 1 /* LINEOUT1_MODE */ +#define WM8994_IN1R_TO_LINEOUT1P 0x0004 /* IN1R_TO_LINEOUT1P */ +#define WM8994_IN1R_TO_LINEOUT1P_MASK 0x0004 /* IN1R_TO_LINEOUT1P */ +#define WM8994_IN1R_TO_LINEOUT1P_SHIFT 2 /* IN1R_TO_LINEOUT1P */ +#define WM8994_IN1R_TO_LINEOUT1P_WIDTH 1 /* IN1R_TO_LINEOUT1P */ +#define WM8994_IN1L_TO_LINEOUT1P 0x0002 /* IN1L_TO_LINEOUT1P */ +#define WM8994_IN1L_TO_LINEOUT1P_MASK 0x0002 /* IN1L_TO_LINEOUT1P */ +#define WM8994_IN1L_TO_LINEOUT1P_SHIFT 1 /* IN1L_TO_LINEOUT1P */ +#define WM8994_IN1L_TO_LINEOUT1P_WIDTH 1 /* IN1L_TO_LINEOUT1P */ +#define WM8994_MIXOUTL_TO_LINEOUT1P 0x0001 /* MIXOUTL_TO_LINEOUT1P */ +#define WM8994_MIXOUTL_TO_LINEOUT1P_MASK 0x0001 /* MIXOUTL_TO_LINEOUT1P */ +#define WM8994_MIXOUTL_TO_LINEOUT1P_SHIFT 0 /* MIXOUTL_TO_LINEOUT1P */ +#define WM8994_MIXOUTL_TO_LINEOUT1P_WIDTH 1 /* MIXOUTL_TO_LINEOUT1P */ + +/* + * R53 (0x35) - Line Mixer (2) + */ +#define WM8994_MIXOUTR_TO_LINEOUT2N 0x0040 /* MIXOUTR_TO_LINEOUT2N */ +#define WM8994_MIXOUTR_TO_LINEOUT2N_MASK 0x0040 /* MIXOUTR_TO_LINEOUT2N */ +#define WM8994_MIXOUTR_TO_LINEOUT2N_SHIFT 6 /* MIXOUTR_TO_LINEOUT2N */ +#define WM8994_MIXOUTR_TO_LINEOUT2N_WIDTH 1 /* MIXOUTR_TO_LINEOUT2N */ +#define WM8994_MIXOUTL_TO_LINEOUT2N 0x0020 /* MIXOUTL_TO_LINEOUT2N */ +#define WM8994_MIXOUTL_TO_LINEOUT2N_MASK 0x0020 /* MIXOUTL_TO_LINEOUT2N */ +#define WM8994_MIXOUTL_TO_LINEOUT2N_SHIFT 5 /* MIXOUTL_TO_LINEOUT2N */ +#define WM8994_MIXOUTL_TO_LINEOUT2N_WIDTH 1 /* MIXOUTL_TO_LINEOUT2N */ +#define WM8994_LINEOUT2_MODE 0x0010 /* LINEOUT2_MODE */ +#define WM8994_LINEOUT2_MODE_MASK 0x0010 /* LINEOUT2_MODE */ +#define WM8994_LINEOUT2_MODE_SHIFT 4 /* LINEOUT2_MODE */ +#define WM8994_LINEOUT2_MODE_WIDTH 1 /* LINEOUT2_MODE */ +#define WM8994_IN1L_TO_LINEOUT2P 0x0004 /* IN1L_TO_LINEOUT2P */ +#define WM8994_IN1L_TO_LINEOUT2P_MASK 0x0004 /* IN1L_TO_LINEOUT2P */ +#define WM8994_IN1L_TO_LINEOUT2P_SHIFT 2 /* IN1L_TO_LINEOUT2P */ +#define WM8994_IN1L_TO_LINEOUT2P_WIDTH 1 /* IN1L_TO_LINEOUT2P */ +#define WM8994_IN1R_TO_LINEOUT2P 0x0002 /* IN1R_TO_LINEOUT2P */ +#define WM8994_IN1R_TO_LINEOUT2P_MASK 0x0002 /* IN1R_TO_LINEOUT2P */ +#define WM8994_IN1R_TO_LINEOUT2P_SHIFT 1 /* IN1R_TO_LINEOUT2P */ +#define WM8994_IN1R_TO_LINEOUT2P_WIDTH 1 /* IN1R_TO_LINEOUT2P */ +#define WM8994_MIXOUTR_TO_LINEOUT2P 0x0001 /* MIXOUTR_TO_LINEOUT2P */ +#define WM8994_MIXOUTR_TO_LINEOUT2P_MASK 0x0001 /* MIXOUTR_TO_LINEOUT2P */ +#define WM8994_MIXOUTR_TO_LINEOUT2P_SHIFT 0 /* MIXOUTR_TO_LINEOUT2P */ +#define WM8994_MIXOUTR_TO_LINEOUT2P_WIDTH 1 /* MIXOUTR_TO_LINEOUT2P */ + +/* + * R54 (0x36) - Speaker Mixer + */ +#define WM8994_DAC2L_TO_SPKMIXL 0x0200 /* DAC2L_TO_SPKMIXL */ +#define WM8994_DAC2L_TO_SPKMIXL_MASK 0x0200 /* DAC2L_TO_SPKMIXL */ +#define WM8994_DAC2L_TO_SPKMIXL_SHIFT 9 /* DAC2L_TO_SPKMIXL */ +#define WM8994_DAC2L_TO_SPKMIXL_WIDTH 1 /* DAC2L_TO_SPKMIXL */ +#define WM8994_DAC2R_TO_SPKMIXR 0x0100 /* DAC2R_TO_SPKMIXR */ +#define WM8994_DAC2R_TO_SPKMIXR_MASK 0x0100 /* DAC2R_TO_SPKMIXR */ +#define WM8994_DAC2R_TO_SPKMIXR_SHIFT 8 /* DAC2R_TO_SPKMIXR */ +#define WM8994_DAC2R_TO_SPKMIXR_WIDTH 1 /* DAC2R_TO_SPKMIXR */ +#define WM8994_MIXINL_TO_SPKMIXL 0x0080 /* MIXINL_TO_SPKMIXL */ +#define WM8994_MIXINL_TO_SPKMIXL_MASK 0x0080 /* MIXINL_TO_SPKMIXL */ +#define WM8994_MIXINL_TO_SPKMIXL_SHIFT 7 /* MIXINL_TO_SPKMIXL */ +#define WM8994_MIXINL_TO_SPKMIXL_WIDTH 1 /* MIXINL_TO_SPKMIXL */ +#define WM8994_MIXINR_TO_SPKMIXR 0x0040 /* MIXINR_TO_SPKMIXR */ +#define WM8994_MIXINR_TO_SPKMIXR_MASK 0x0040 /* MIXINR_TO_SPKMIXR */ +#define WM8994_MIXINR_TO_SPKMIXR_SHIFT 6 /* MIXINR_TO_SPKMIXR */ +#define WM8994_MIXINR_TO_SPKMIXR_WIDTH 1 /* MIXINR_TO_SPKMIXR */ +#define WM8994_IN1LP_TO_SPKMIXL 0x0020 /* IN1LP_TO_SPKMIXL */ +#define WM8994_IN1LP_TO_SPKMIXL_MASK 0x0020 /* IN1LP_TO_SPKMIXL */ +#define WM8994_IN1LP_TO_SPKMIXL_SHIFT 5 /* IN1LP_TO_SPKMIXL */ +#define WM8994_IN1LP_TO_SPKMIXL_WIDTH 1 /* IN1LP_TO_SPKMIXL */ +#define WM8994_IN1RP_TO_SPKMIXR 0x0010 /* IN1RP_TO_SPKMIXR */ +#define WM8994_IN1RP_TO_SPKMIXR_MASK 0x0010 /* IN1RP_TO_SPKMIXR */ +#define WM8994_IN1RP_TO_SPKMIXR_SHIFT 4 /* IN1RP_TO_SPKMIXR */ +#define WM8994_IN1RP_TO_SPKMIXR_WIDTH 1 /* IN1RP_TO_SPKMIXR */ +#define WM8994_MIXOUTL_TO_SPKMIXL 0x0008 /* MIXOUTL_TO_SPKMIXL */ +#define WM8994_MIXOUTL_TO_SPKMIXL_MASK 0x0008 /* MIXOUTL_TO_SPKMIXL */ +#define WM8994_MIXOUTL_TO_SPKMIXL_SHIFT 3 /* MIXOUTL_TO_SPKMIXL */ +#define WM8994_MIXOUTL_TO_SPKMIXL_WIDTH 1 /* MIXOUTL_TO_SPKMIXL */ +#define WM8994_MIXOUTR_TO_SPKMIXR 0x0004 /* MIXOUTR_TO_SPKMIXR */ +#define WM8994_MIXOUTR_TO_SPKMIXR_MASK 0x0004 /* MIXOUTR_TO_SPKMIXR */ +#define WM8994_MIXOUTR_TO_SPKMIXR_SHIFT 2 /* MIXOUTR_TO_SPKMIXR */ +#define WM8994_MIXOUTR_TO_SPKMIXR_WIDTH 1 /* MIXOUTR_TO_SPKMIXR */ +#define WM8994_DAC1L_TO_SPKMIXL 0x0002 /* DAC1L_TO_SPKMIXL */ +#define WM8994_DAC1L_TO_SPKMIXL_MASK 0x0002 /* DAC1L_TO_SPKMIXL */ +#define WM8994_DAC1L_TO_SPKMIXL_SHIFT 1 /* DAC1L_TO_SPKMIXL */ +#define WM8994_DAC1L_TO_SPKMIXL_WIDTH 1 /* DAC1L_TO_SPKMIXL */ +#define WM8994_DAC1R_TO_SPKMIXR 0x0001 /* DAC1R_TO_SPKMIXR */ +#define WM8994_DAC1R_TO_SPKMIXR_MASK 0x0001 /* DAC1R_TO_SPKMIXR */ +#define WM8994_DAC1R_TO_SPKMIXR_SHIFT 0 /* DAC1R_TO_SPKMIXR */ +#define WM8994_DAC1R_TO_SPKMIXR_WIDTH 1 /* DAC1R_TO_SPKMIXR */ + +/* + * R55 (0x37) - Additional Control + */ +#define WM8994_LINEOUT1_FB 0x0080 /* LINEOUT1_FB */ +#define WM8994_LINEOUT1_FB_MASK 0x0080 /* LINEOUT1_FB */ +#define WM8994_LINEOUT1_FB_SHIFT 7 /* LINEOUT1_FB */ +#define WM8994_LINEOUT1_FB_WIDTH 1 /* LINEOUT1_FB */ +#define WM8994_LINEOUT2_FB 0x0040 /* LINEOUT2_FB */ +#define WM8994_LINEOUT2_FB_MASK 0x0040 /* LINEOUT2_FB */ +#define WM8994_LINEOUT2_FB_SHIFT 6 /* LINEOUT2_FB */ +#define WM8994_LINEOUT2_FB_WIDTH 1 /* LINEOUT2_FB */ +#define WM8994_VROI 0x0001 /* VROI */ +#define WM8994_VROI_MASK 0x0001 /* VROI */ +#define WM8994_VROI_SHIFT 0 /* VROI */ +#define WM8994_VROI_WIDTH 1 /* VROI */ + +/* + * R56 (0x38) - AntiPOP (1) + */ +#define WM8994_LINEOUT_VMID_BUF_ENA 0x0080 /* LINEOUT_VMID_BUF_ENA */ +#define WM8994_LINEOUT_VMID_BUF_ENA_MASK 0x0080 /* LINEOUT_VMID_BUF_ENA */ +#define WM8994_LINEOUT_VMID_BUF_ENA_SHIFT 7 /* LINEOUT_VMID_BUF_ENA */ +#define WM8994_LINEOUT_VMID_BUF_ENA_WIDTH 1 /* LINEOUT_VMID_BUF_ENA */ +#define WM8994_HPOUT2_IN_ENA 0x0040 /* HPOUT2_IN_ENA */ +#define WM8994_HPOUT2_IN_ENA_MASK 0x0040 /* HPOUT2_IN_ENA */ +#define WM8994_HPOUT2_IN_ENA_SHIFT 6 /* HPOUT2_IN_ENA */ +#define WM8994_HPOUT2_IN_ENA_WIDTH 1 /* HPOUT2_IN_ENA */ +#define WM8994_LINEOUT1_DISCH 0x0020 /* LINEOUT1_DISCH */ +#define WM8994_LINEOUT1_DISCH_MASK 0x0020 /* LINEOUT1_DISCH */ +#define WM8994_LINEOUT1_DISCH_SHIFT 5 /* LINEOUT1_DISCH */ +#define WM8994_LINEOUT1_DISCH_WIDTH 1 /* LINEOUT1_DISCH */ +#define WM8994_LINEOUT2_DISCH 0x0010 /* LINEOUT2_DISCH */ +#define WM8994_LINEOUT2_DISCH_MASK 0x0010 /* LINEOUT2_DISCH */ +#define WM8994_LINEOUT2_DISCH_SHIFT 4 /* LINEOUT2_DISCH */ +#define WM8994_LINEOUT2_DISCH_WIDTH 1 /* LINEOUT2_DISCH */ + +/* + * R57 (0x39) - AntiPOP (2) + */ +#define WM8994_MICB2_DISCH 0x0100 /* MICB2_DISCH */ +#define WM8994_MICB2_DISCH_MASK 0x0100 /* MICB2_DISCH */ +#define WM8994_MICB2_DISCH_SHIFT 8 /* MICB2_DISCH */ +#define WM8994_MICB2_DISCH_WIDTH 1 /* MICB2_DISCH */ +#define WM8994_MICB1_DISCH 0x0080 /* MICB1_DISCH */ +#define WM8994_MICB1_DISCH_MASK 0x0080 /* MICB1_DISCH */ +#define WM8994_MICB1_DISCH_SHIFT 7 /* MICB1_DISCH */ +#define WM8994_MICB1_DISCH_WIDTH 1 /* MICB1_DISCH */ +#define WM8994_VMID_RAMP_MASK 0x0060 /* VMID_RAMP - [6:5] */ +#define WM8994_VMID_RAMP_SHIFT 5 /* VMID_RAMP - [6:5] */ +#define WM8994_VMID_RAMP_WIDTH 2 /* VMID_RAMP - [6:5] */ +#define WM8994_VMID_BUF_ENA 0x0008 /* VMID_BUF_ENA */ +#define WM8994_VMID_BUF_ENA_MASK 0x0008 /* VMID_BUF_ENA */ +#define WM8994_VMID_BUF_ENA_SHIFT 3 /* VMID_BUF_ENA */ +#define WM8994_VMID_BUF_ENA_WIDTH 1 /* VMID_BUF_ENA */ +#define WM8994_STARTUP_BIAS_ENA 0x0004 /* STARTUP_BIAS_ENA */ +#define WM8994_STARTUP_BIAS_ENA_MASK 0x0004 /* STARTUP_BIAS_ENA */ +#define WM8994_STARTUP_BIAS_ENA_SHIFT 2 /* STARTUP_BIAS_ENA */ +#define WM8994_STARTUP_BIAS_ENA_WIDTH 1 /* STARTUP_BIAS_ENA */ +#define WM8994_BIAS_SRC 0x0002 /* BIAS_SRC */ +#define WM8994_BIAS_SRC_MASK 0x0002 /* BIAS_SRC */ +#define WM8994_BIAS_SRC_SHIFT 1 /* BIAS_SRC */ +#define WM8994_BIAS_SRC_WIDTH 1 /* BIAS_SRC */ +#define WM8994_VMID_DISCH 0x0001 /* VMID_DISCH */ +#define WM8994_VMID_DISCH_MASK 0x0001 /* VMID_DISCH */ +#define WM8994_VMID_DISCH_SHIFT 0 /* VMID_DISCH */ +#define WM8994_VMID_DISCH_WIDTH 1 /* VMID_DISCH */ + +/* + * R58 (0x3A) - MICBIAS + */ +#define WM8994_MICD_SCTHR_MASK 0x00C0 /* MICD_SCTHR - [7:6] */ +#define WM8994_MICD_SCTHR_SHIFT 6 /* MICD_SCTHR - [7:6] */ +#define WM8994_MICD_SCTHR_WIDTH 2 /* MICD_SCTHR - [7:6] */ +#define WM8994_MICD_THR_MASK 0x0038 /* MICD_THR - [5:3] */ +#define WM8994_MICD_THR_SHIFT 3 /* MICD_THR - [5:3] */ +#define WM8994_MICD_THR_WIDTH 3 /* MICD_THR - [5:3] */ +#define WM8994_MICD_ENA 0x0004 /* MICD_ENA */ +#define WM8994_MICD_ENA_MASK 0x0004 /* MICD_ENA */ +#define WM8994_MICD_ENA_SHIFT 2 /* MICD_ENA */ +#define WM8994_MICD_ENA_WIDTH 1 /* MICD_ENA */ +#define WM8994_MICB2_LVL 0x0002 /* MICB2_LVL */ +#define WM8994_MICB2_LVL_MASK 0x0002 /* MICB2_LVL */ +#define WM8994_MICB2_LVL_SHIFT 1 /* MICB2_LVL */ +#define WM8994_MICB2_LVL_WIDTH 1 /* MICB2_LVL */ +#define WM8994_MICB1_LVL 0x0001 /* MICB1_LVL */ +#define WM8994_MICB1_LVL_MASK 0x0001 /* MICB1_LVL */ +#define WM8994_MICB1_LVL_SHIFT 0 /* MICB1_LVL */ +#define WM8994_MICB1_LVL_WIDTH 1 /* MICB1_LVL */ + +/* + * R59 (0x3B) - LDO 1 + */ +#define WM8994_LDO1_VSEL_MASK 0x000E /* LDO1_VSEL - [3:1] */ +#define WM8994_LDO1_VSEL_SHIFT 1 /* LDO1_VSEL - [3:1] */ +#define WM8994_LDO1_VSEL_WIDTH 3 /* LDO1_VSEL - [3:1] */ +#define WM8994_LDO1_DISCH 0x0001 /* LDO1_DISCH */ +#define WM8994_LDO1_DISCH_MASK 0x0001 /* LDO1_DISCH */ +#define WM8994_LDO1_DISCH_SHIFT 0 /* LDO1_DISCH */ +#define WM8994_LDO1_DISCH_WIDTH 1 /* LDO1_DISCH */ + +/* + * R60 (0x3C) - LDO 2 + */ +#define WM8994_LDO2_VSEL_MASK 0x0006 /* LDO2_VSEL - [2:1] */ +#define WM8994_LDO2_VSEL_SHIFT 1 /* LDO2_VSEL - [2:1] */ +#define WM8994_LDO2_VSEL_WIDTH 2 /* LDO2_VSEL - [2:1] */ +#define WM8994_LDO2_DISCH 0x0001 /* LDO2_DISCH */ +#define WM8994_LDO2_DISCH_MASK 0x0001 /* LDO2_DISCH */ +#define WM8994_LDO2_DISCH_SHIFT 0 /* LDO2_DISCH */ +#define WM8994_LDO2_DISCH_WIDTH 1 /* LDO2_DISCH */ + +/* + * R76 (0x4C) - Charge Pump (1) + */ +#define WM8994_CP_ENA 0x8000 /* CP_ENA */ +#define WM8994_CP_ENA_MASK 0x8000 /* CP_ENA */ +#define WM8994_CP_ENA_SHIFT 15 /* CP_ENA */ +#define WM8994_CP_ENA_WIDTH 1 /* CP_ENA */ + +/* + * R81 (0x51) - Class W (1) + */ +#define WM8994_CP_DYN_SRC_SEL_MASK 0x0300 /* CP_DYN_SRC_SEL - [9:8] */ +#define WM8994_CP_DYN_SRC_SEL_SHIFT 8 /* CP_DYN_SRC_SEL - [9:8] */ +#define WM8994_CP_DYN_SRC_SEL_WIDTH 2 /* CP_DYN_SRC_SEL - [9:8] */ +#define WM8994_CP_DYN_PWR 0x0001 /* CP_DYN_PWR */ +#define WM8994_CP_DYN_PWR_MASK 0x0001 /* CP_DYN_PWR */ +#define WM8994_CP_DYN_PWR_SHIFT 0 /* CP_DYN_PWR */ +#define WM8994_CP_DYN_PWR_WIDTH 1 /* CP_DYN_PWR */ + +/* + * R84 (0x54) - DC Servo (1) + */ +#define WM8994_DCS_TRIG_SINGLE_1 0x2000 /* DCS_TRIG_SINGLE_1 */ +#define WM8994_DCS_TRIG_SINGLE_1_MASK 0x2000 /* DCS_TRIG_SINGLE_1 */ +#define WM8994_DCS_TRIG_SINGLE_1_SHIFT 13 /* DCS_TRIG_SINGLE_1 */ +#define WM8994_DCS_TRIG_SINGLE_1_WIDTH 1 /* DCS_TRIG_SINGLE_1 */ +#define WM8994_DCS_TRIG_SINGLE_0 0x1000 /* DCS_TRIG_SINGLE_0 */ +#define WM8994_DCS_TRIG_SINGLE_0_MASK 0x1000 /* DCS_TRIG_SINGLE_0 */ +#define WM8994_DCS_TRIG_SINGLE_0_SHIFT 12 /* DCS_TRIG_SINGLE_0 */ +#define WM8994_DCS_TRIG_SINGLE_0_WIDTH 1 /* DCS_TRIG_SINGLE_0 */ +#define WM8994_DCS_TRIG_SERIES_1 0x0200 /* DCS_TRIG_SERIES_1 */ +#define WM8994_DCS_TRIG_SERIES_1_MASK 0x0200 /* DCS_TRIG_SERIES_1 */ +#define WM8994_DCS_TRIG_SERIES_1_SHIFT 9 /* DCS_TRIG_SERIES_1 */ +#define WM8994_DCS_TRIG_SERIES_1_WIDTH 1 /* DCS_TRIG_SERIES_1 */ +#define WM8994_DCS_TRIG_SERIES_0 0x0100 /* DCS_TRIG_SERIES_0 */ +#define WM8994_DCS_TRIG_SERIES_0_MASK 0x0100 /* DCS_TRIG_SERIES_0 */ +#define WM8994_DCS_TRIG_SERIES_0_SHIFT 8 /* DCS_TRIG_SERIES_0 */ +#define WM8994_DCS_TRIG_SERIES_0_WIDTH 1 /* DCS_TRIG_SERIES_0 */ +#define WM8994_DCS_TRIG_STARTUP_1 0x0020 /* DCS_TRIG_STARTUP_1 */ +#define WM8994_DCS_TRIG_STARTUP_1_MASK 0x0020 /* DCS_TRIG_STARTUP_1 */ +#define WM8994_DCS_TRIG_STARTUP_1_SHIFT 5 /* DCS_TRIG_STARTUP_1 */ +#define WM8994_DCS_TRIG_STARTUP_1_WIDTH 1 /* DCS_TRIG_STARTUP_1 */ +#define WM8994_DCS_TRIG_STARTUP_0 0x0010 /* DCS_TRIG_STARTUP_0 */ +#define WM8994_DCS_TRIG_STARTUP_0_MASK 0x0010 /* DCS_TRIG_STARTUP_0 */ +#define WM8994_DCS_TRIG_STARTUP_0_SHIFT 4 /* DCS_TRIG_STARTUP_0 */ +#define WM8994_DCS_TRIG_STARTUP_0_WIDTH 1 /* DCS_TRIG_STARTUP_0 */ +#define WM8994_DCS_TRIG_DAC_WR_1 0x0008 /* DCS_TRIG_DAC_WR_1 */ +#define WM8994_DCS_TRIG_DAC_WR_1_MASK 0x0008 /* DCS_TRIG_DAC_WR_1 */ +#define WM8994_DCS_TRIG_DAC_WR_1_SHIFT 3 /* DCS_TRIG_DAC_WR_1 */ +#define WM8994_DCS_TRIG_DAC_WR_1_WIDTH 1 /* DCS_TRIG_DAC_WR_1 */ +#define WM8994_DCS_TRIG_DAC_WR_0 0x0004 /* DCS_TRIG_DAC_WR_0 */ +#define WM8994_DCS_TRIG_DAC_WR_0_MASK 0x0004 /* DCS_TRIG_DAC_WR_0 */ +#define WM8994_DCS_TRIG_DAC_WR_0_SHIFT 2 /* DCS_TRIG_DAC_WR_0 */ +#define WM8994_DCS_TRIG_DAC_WR_0_WIDTH 1 /* DCS_TRIG_DAC_WR_0 */ +#define WM8994_DCS_ENA_CHAN_1 0x0002 /* DCS_ENA_CHAN_1 */ +#define WM8994_DCS_ENA_CHAN_1_MASK 0x0002 /* DCS_ENA_CHAN_1 */ +#define WM8994_DCS_ENA_CHAN_1_SHIFT 1 /* DCS_ENA_CHAN_1 */ +#define WM8994_DCS_ENA_CHAN_1_WIDTH 1 /* DCS_ENA_CHAN_1 */ +#define WM8994_DCS_ENA_CHAN_0 0x0001 /* DCS_ENA_CHAN_0 */ +#define WM8994_DCS_ENA_CHAN_0_MASK 0x0001 /* DCS_ENA_CHAN_0 */ +#define WM8994_DCS_ENA_CHAN_0_SHIFT 0 /* DCS_ENA_CHAN_0 */ +#define WM8994_DCS_ENA_CHAN_0_WIDTH 1 /* DCS_ENA_CHAN_0 */ + +/* + * R85 (0x55) - DC Servo (2) + */ +#define WM8994_DCS_SERIES_NO_01_MASK 0x0FE0 /* DCS_SERIES_NO_01 - [11:5] */ +#define WM8994_DCS_SERIES_NO_01_SHIFT 5 /* DCS_SERIES_NO_01 - [11:5] */ +#define WM8994_DCS_SERIES_NO_01_WIDTH 7 /* DCS_SERIES_NO_01 - [11:5] */ +#define WM8994_DCS_TIMER_PERIOD_01_MASK 0x000F /* DCS_TIMER_PERIOD_01 - [3:0] */ +#define WM8994_DCS_TIMER_PERIOD_01_SHIFT 0 /* DCS_TIMER_PERIOD_01 - [3:0] */ +#define WM8994_DCS_TIMER_PERIOD_01_WIDTH 4 /* DCS_TIMER_PERIOD_01 - [3:0] */ + +/* + * R87 (0x57) - DC Servo (4) + */ +#define WM8994_DCS_DAC_WR_VAL_1_MASK 0xFF00 /* DCS_DAC_WR_VAL_1 - [15:8] */ +#define WM8994_DCS_DAC_WR_VAL_1_SHIFT 8 /* DCS_DAC_WR_VAL_1 - [15:8] */ +#define WM8994_DCS_DAC_WR_VAL_1_WIDTH 8 /* DCS_DAC_WR_VAL_1 - [15:8] */ +#define WM8994_DCS_DAC_WR_VAL_0_MASK 0x00FF /* DCS_DAC_WR_VAL_0 - [7:0] */ +#define WM8994_DCS_DAC_WR_VAL_0_SHIFT 0 /* DCS_DAC_WR_VAL_0 - [7:0] */ +#define WM8994_DCS_DAC_WR_VAL_0_WIDTH 8 /* DCS_DAC_WR_VAL_0 - [7:0] */ + +/* + * R88 (0x58) - DC Servo Readback + */ +#define WM8994_DCS_CAL_COMPLETE_MASK 0x0300 /* DCS_CAL_COMPLETE - [9:8] */ +#define WM8994_DCS_CAL_COMPLETE_SHIFT 8 /* DCS_CAL_COMPLETE - [9:8] */ +#define WM8994_DCS_CAL_COMPLETE_WIDTH 2 /* DCS_CAL_COMPLETE - [9:8] */ +#define WM8994_DCS_DAC_WR_COMPLETE_MASK 0x0030 /* DCS_DAC_WR_COMPLETE - [5:4] */ +#define WM8994_DCS_DAC_WR_COMPLETE_SHIFT 4 /* DCS_DAC_WR_COMPLETE - [5:4] */ +#define WM8994_DCS_DAC_WR_COMPLETE_WIDTH 2 /* DCS_DAC_WR_COMPLETE - [5:4] */ +#define WM8994_DCS_STARTUP_COMPLETE_MASK 0x0003 /* DCS_STARTUP_COMPLETE - [1:0] */ +#define WM8994_DCS_STARTUP_COMPLETE_SHIFT 0 /* DCS_STARTUP_COMPLETE - [1:0] */ +#define WM8994_DCS_STARTUP_COMPLETE_WIDTH 2 /* DCS_STARTUP_COMPLETE - [1:0] */ + +/* + * R96 (0x60) - Analogue HP (1) + */ +#define WM8994_HPOUT1L_RMV_SHORT 0x0080 /* HPOUT1L_RMV_SHORT */ +#define WM8994_HPOUT1L_RMV_SHORT_MASK 0x0080 /* HPOUT1L_RMV_SHORT */ +#define WM8994_HPOUT1L_RMV_SHORT_SHIFT 7 /* HPOUT1L_RMV_SHORT */ +#define WM8994_HPOUT1L_RMV_SHORT_WIDTH 1 /* HPOUT1L_RMV_SHORT */ +#define WM8994_HPOUT1L_OUTP 0x0040 /* HPOUT1L_OUTP */ +#define WM8994_HPOUT1L_OUTP_MASK 0x0040 /* HPOUT1L_OUTP */ +#define WM8994_HPOUT1L_OUTP_SHIFT 6 /* HPOUT1L_OUTP */ +#define WM8994_HPOUT1L_OUTP_WIDTH 1 /* HPOUT1L_OUTP */ +#define WM8994_HPOUT1L_DLY 0x0020 /* HPOUT1L_DLY */ +#define WM8994_HPOUT1L_DLY_MASK 0x0020 /* HPOUT1L_DLY */ +#define WM8994_HPOUT1L_DLY_SHIFT 5 /* HPOUT1L_DLY */ +#define WM8994_HPOUT1L_DLY_WIDTH 1 /* HPOUT1L_DLY */ +#define WM8994_HPOUT1R_RMV_SHORT 0x0008 /* HPOUT1R_RMV_SHORT */ +#define WM8994_HPOUT1R_RMV_SHORT_MASK 0x0008 /* HPOUT1R_RMV_SHORT */ +#define WM8994_HPOUT1R_RMV_SHORT_SHIFT 3 /* HPOUT1R_RMV_SHORT */ +#define WM8994_HPOUT1R_RMV_SHORT_WIDTH 1 /* HPOUT1R_RMV_SHORT */ +#define WM8994_HPOUT1R_OUTP 0x0004 /* HPOUT1R_OUTP */ +#define WM8994_HPOUT1R_OUTP_MASK 0x0004 /* HPOUT1R_OUTP */ +#define WM8994_HPOUT1R_OUTP_SHIFT 2 /* HPOUT1R_OUTP */ +#define WM8994_HPOUT1R_OUTP_WIDTH 1 /* HPOUT1R_OUTP */ +#define WM8994_HPOUT1R_DLY 0x0002 /* HPOUT1R_DLY */ +#define WM8994_HPOUT1R_DLY_MASK 0x0002 /* HPOUT1R_DLY */ +#define WM8994_HPOUT1R_DLY_SHIFT 1 /* HPOUT1R_DLY */ +#define WM8994_HPOUT1R_DLY_WIDTH 1 /* HPOUT1R_DLY */ + +/* + * R256 (0x100) - Chip Revision + */ +#define WM8994_CHIP_REV_MASK 0x000F /* CHIP_REV - [3:0] */ +#define WM8994_CHIP_REV_SHIFT 0 /* CHIP_REV - [3:0] */ +#define WM8994_CHIP_REV_WIDTH 4 /* CHIP_REV - [3:0] */ + +/* + * R257 (0x101) - Control Interface + */ +#define WM8994_SPI_CONTRD 0x0040 /* SPI_CONTRD */ +#define WM8994_SPI_CONTRD_MASK 0x0040 /* SPI_CONTRD */ +#define WM8994_SPI_CONTRD_SHIFT 6 /* SPI_CONTRD */ +#define WM8994_SPI_CONTRD_WIDTH 1 /* SPI_CONTRD */ +#define WM8994_SPI_4WIRE 0x0020 /* SPI_4WIRE */ +#define WM8994_SPI_4WIRE_MASK 0x0020 /* SPI_4WIRE */ +#define WM8994_SPI_4WIRE_SHIFT 5 /* SPI_4WIRE */ +#define WM8994_SPI_4WIRE_WIDTH 1 /* SPI_4WIRE */ +#define WM8994_SPI_CFG 0x0010 /* SPI_CFG */ +#define WM8994_SPI_CFG_MASK 0x0010 /* SPI_CFG */ +#define WM8994_SPI_CFG_SHIFT 4 /* SPI_CFG */ +#define WM8994_SPI_CFG_WIDTH 1 /* SPI_CFG */ +#define WM8994_AUTO_INC 0x0004 /* AUTO_INC */ +#define WM8994_AUTO_INC_MASK 0x0004 /* AUTO_INC */ +#define WM8994_AUTO_INC_SHIFT 2 /* AUTO_INC */ +#define WM8994_AUTO_INC_WIDTH 1 /* AUTO_INC */ + +/* + * R272 (0x110) - Write Sequencer Ctrl (1) + */ +#define WM8994_WSEQ_ENA 0x8000 /* WSEQ_ENA */ +#define WM8994_WSEQ_ENA_MASK 0x8000 /* WSEQ_ENA */ +#define WM8994_WSEQ_ENA_SHIFT 15 /* WSEQ_ENA */ +#define WM8994_WSEQ_ENA_WIDTH 1 /* WSEQ_ENA */ +#define WM8994_WSEQ_ABORT 0x0200 /* WSEQ_ABORT */ +#define WM8994_WSEQ_ABORT_MASK 0x0200 /* WSEQ_ABORT */ +#define WM8994_WSEQ_ABORT_SHIFT 9 /* WSEQ_ABORT */ +#define WM8994_WSEQ_ABORT_WIDTH 1 /* WSEQ_ABORT */ +#define WM8994_WSEQ_START 0x0100 /* WSEQ_START */ +#define WM8994_WSEQ_START_MASK 0x0100 /* WSEQ_START */ +#define WM8994_WSEQ_START_SHIFT 8 /* WSEQ_START */ +#define WM8994_WSEQ_START_WIDTH 1 /* WSEQ_START */ +#define WM8994_WSEQ_START_INDEX_MASK 0x007F /* WSEQ_START_INDEX - [6:0] */ +#define WM8994_WSEQ_START_INDEX_SHIFT 0 /* WSEQ_START_INDEX - [6:0] */ +#define WM8994_WSEQ_START_INDEX_WIDTH 7 /* WSEQ_START_INDEX - [6:0] */ + +/* + * R273 (0x111) - Write Sequencer Ctrl (2) + */ +#define WM8994_WSEQ_BUSY 0x0100 /* WSEQ_BUSY */ +#define WM8994_WSEQ_BUSY_MASK 0x0100 /* WSEQ_BUSY */ +#define WM8994_WSEQ_BUSY_SHIFT 8 /* WSEQ_BUSY */ +#define WM8994_WSEQ_BUSY_WIDTH 1 /* WSEQ_BUSY */ +#define WM8994_WSEQ_CURRENT_INDEX_MASK 0x007F /* WSEQ_CURRENT_INDEX - [6:0] */ +#define WM8994_WSEQ_CURRENT_INDEX_SHIFT 0 /* WSEQ_CURRENT_INDEX - [6:0] */ +#define WM8994_WSEQ_CURRENT_INDEX_WIDTH 7 /* WSEQ_CURRENT_INDEX - [6:0] */ + +/* + * R512 (0x200) - AIF1 Clocking (1) + */ +#define WM8994_AIF1CLK_SRC_MASK 0x0018 /* AIF1CLK_SRC - [4:3] */ +#define WM8994_AIF1CLK_SRC_SHIFT 3 /* AIF1CLK_SRC - [4:3] */ +#define WM8994_AIF1CLK_SRC_WIDTH 2 /* AIF1CLK_SRC - [4:3] */ +#define WM8994_AIF1CLK_INV 0x0004 /* AIF1CLK_INV */ +#define WM8994_AIF1CLK_INV_MASK 0x0004 /* AIF1CLK_INV */ +#define WM8994_AIF1CLK_INV_SHIFT 2 /* AIF1CLK_INV */ +#define WM8994_AIF1CLK_INV_WIDTH 1 /* AIF1CLK_INV */ +#define WM8994_AIF1CLK_DIV 0x0002 /* AIF1CLK_DIV */ +#define WM8994_AIF1CLK_DIV_MASK 0x0002 /* AIF1CLK_DIV */ +#define WM8994_AIF1CLK_DIV_SHIFT 1 /* AIF1CLK_DIV */ +#define WM8994_AIF1CLK_DIV_WIDTH 1 /* AIF1CLK_DIV */ +#define WM8994_AIF1CLK_ENA 0x0001 /* AIF1CLK_ENA */ +#define WM8994_AIF1CLK_ENA_MASK 0x0001 /* AIF1CLK_ENA */ +#define WM8994_AIF1CLK_ENA_SHIFT 0 /* AIF1CLK_ENA */ +#define WM8994_AIF1CLK_ENA_WIDTH 1 /* AIF1CLK_ENA */ + +/* + * R513 (0x201) - AIF1 Clocking (2) + */ +#define WM8994_AIF1DAC_DIV_MASK 0x0038 /* AIF1DAC_DIV - [5:3] */ +#define WM8994_AIF1DAC_DIV_SHIFT 3 /* AIF1DAC_DIV - [5:3] */ +#define WM8994_AIF1DAC_DIV_WIDTH 3 /* AIF1DAC_DIV - [5:3] */ +#define WM8994_AIF1ADC_DIV_MASK 0x0007 /* AIF1ADC_DIV - [2:0] */ +#define WM8994_AIF1ADC_DIV_SHIFT 0 /* AIF1ADC_DIV - [2:0] */ +#define WM8994_AIF1ADC_DIV_WIDTH 3 /* AIF1ADC_DIV - [2:0] */ + +/* + * R516 (0x204) - AIF2 Clocking (1) + */ +#define WM8994_AIF2CLK_SRC_MASK 0x0018 /* AIF2CLK_SRC - [4:3] */ +#define WM8994_AIF2CLK_SRC_SHIFT 3 /* AIF2CLK_SRC - [4:3] */ +#define WM8994_AIF2CLK_SRC_WIDTH 2 /* AIF2CLK_SRC - [4:3] */ +#define WM8994_AIF2CLK_INV 0x0004 /* AIF2CLK_INV */ +#define WM8994_AIF2CLK_INV_MASK 0x0004 /* AIF2CLK_INV */ +#define WM8994_AIF2CLK_INV_SHIFT 2 /* AIF2CLK_INV */ +#define WM8994_AIF2CLK_INV_WIDTH 1 /* AIF2CLK_INV */ +#define WM8994_AIF2CLK_DIV 0x0002 /* AIF2CLK_DIV */ +#define WM8994_AIF2CLK_DIV_MASK 0x0002 /* AIF2CLK_DIV */ +#define WM8994_AIF2CLK_DIV_SHIFT 1 /* AIF2CLK_DIV */ +#define WM8994_AIF2CLK_DIV_WIDTH 1 /* AIF2CLK_DIV */ +#define WM8994_AIF2CLK_ENA 0x0001 /* AIF2CLK_ENA */ +#define WM8994_AIF2CLK_ENA_MASK 0x0001 /* AIF2CLK_ENA */ +#define WM8994_AIF2CLK_ENA_SHIFT 0 /* AIF2CLK_ENA */ +#define WM8994_AIF2CLK_ENA_WIDTH 1 /* AIF2CLK_ENA */ + +/* + * R517 (0x205) - AIF2 Clocking (2) + */ +#define WM8994_AIF2DAC_DIV_MASK 0x0038 /* AIF2DAC_DIV - [5:3] */ +#define WM8994_AIF2DAC_DIV_SHIFT 3 /* AIF2DAC_DIV - [5:3] */ +#define WM8994_AIF2DAC_DIV_WIDTH 3 /* AIF2DAC_DIV - [5:3] */ +#define WM8994_AIF2ADC_DIV_MASK 0x0007 /* AIF2ADC_DIV - [2:0] */ +#define WM8994_AIF2ADC_DIV_SHIFT 0 /* AIF2ADC_DIV - [2:0] */ +#define WM8994_AIF2ADC_DIV_WIDTH 3 /* AIF2ADC_DIV - [2:0] */ + +/* + * R520 (0x208) - Clocking (1) + */ +#define WM8994_TOCLK_ENA 0x0010 /* TOCLK_ENA */ +#define WM8994_TOCLK_ENA_MASK 0x0010 /* TOCLK_ENA */ +#define WM8994_TOCLK_ENA_SHIFT 4 /* TOCLK_ENA */ +#define WM8994_TOCLK_ENA_WIDTH 1 /* TOCLK_ENA */ +#define WM8994_AIF1DSPCLK_ENA 0x0008 /* AIF1DSPCLK_ENA */ +#define WM8994_AIF1DSPCLK_ENA_MASK 0x0008 /* AIF1DSPCLK_ENA */ +#define WM8994_AIF1DSPCLK_ENA_SHIFT 3 /* AIF1DSPCLK_ENA */ +#define WM8994_AIF1DSPCLK_ENA_WIDTH 1 /* AIF1DSPCLK_ENA */ +#define WM8994_AIF2DSPCLK_ENA 0x0004 /* AIF2DSPCLK_ENA */ +#define WM8994_AIF2DSPCLK_ENA_MASK 0x0004 /* AIF2DSPCLK_ENA */ +#define WM8994_AIF2DSPCLK_ENA_SHIFT 2 /* AIF2DSPCLK_ENA */ +#define WM8994_AIF2DSPCLK_ENA_WIDTH 1 /* AIF2DSPCLK_ENA */ +#define WM8994_SYSDSPCLK_ENA 0x0002 /* SYSDSPCLK_ENA */ +#define WM8994_SYSDSPCLK_ENA_MASK 0x0002 /* SYSDSPCLK_ENA */ +#define WM8994_SYSDSPCLK_ENA_SHIFT 1 /* SYSDSPCLK_ENA */ +#define WM8994_SYSDSPCLK_ENA_WIDTH 1 /* SYSDSPCLK_ENA */ +#define WM8994_SYSCLK_SRC 0x0001 /* SYSCLK_SRC */ +#define WM8994_SYSCLK_SRC_MASK 0x0001 /* SYSCLK_SRC */ +#define WM8994_SYSCLK_SRC_SHIFT 0 /* SYSCLK_SRC */ +#define WM8994_SYSCLK_SRC_WIDTH 1 /* SYSCLK_SRC */ + +/* + * R521 (0x209) - Clocking (2) + */ +#define WM8994_TOCLK_DIV_MASK 0x0700 /* TOCLK_DIV - [10:8] */ +#define WM8994_TOCLK_DIV_SHIFT 8 /* TOCLK_DIV - [10:8] */ +#define WM8994_TOCLK_DIV_WIDTH 3 /* TOCLK_DIV - [10:8] */ +#define WM8994_DBCLK_DIV_MASK 0x0070 /* DBCLK_DIV - [6:4] */ +#define WM8994_DBCLK_DIV_SHIFT 4 /* DBCLK_DIV - [6:4] */ +#define WM8994_DBCLK_DIV_WIDTH 3 /* DBCLK_DIV - [6:4] */ +#define WM8994_OPCLK_DIV_MASK 0x0007 /* OPCLK_DIV - [2:0] */ +#define WM8994_OPCLK_DIV_SHIFT 0 /* OPCLK_DIV - [2:0] */ +#define WM8994_OPCLK_DIV_WIDTH 3 /* OPCLK_DIV - [2:0] */ + +/* + * R528 (0x210) - AIF1 Rate + */ +#define WM8994_AIF1_SR_MASK 0x00F0 /* AIF1_SR - [7:4] */ +#define WM8994_AIF1_SR_SHIFT 4 /* AIF1_SR - [7:4] */ +#define WM8994_AIF1_SR_WIDTH 4 /* AIF1_SR - [7:4] */ +#define WM8994_AIF1CLK_RATE_MASK 0x000F /* AIF1CLK_RATE - [3:0] */ +#define WM8994_AIF1CLK_RATE_SHIFT 0 /* AIF1CLK_RATE - [3:0] */ +#define WM8994_AIF1CLK_RATE_WIDTH 4 /* AIF1CLK_RATE - [3:0] */ + +/* + * R529 (0x211) - AIF2 Rate + */ +#define WM8994_AIF2_SR_MASK 0x00F0 /* AIF2_SR - [7:4] */ +#define WM8994_AIF2_SR_SHIFT 4 /* AIF2_SR - [7:4] */ +#define WM8994_AIF2_SR_WIDTH 4 /* AIF2_SR - [7:4] */ +#define WM8994_AIF2CLK_RATE_MASK 0x000F /* AIF2CLK_RATE - [3:0] */ +#define WM8994_AIF2CLK_RATE_SHIFT 0 /* AIF2CLK_RATE - [3:0] */ +#define WM8994_AIF2CLK_RATE_WIDTH 4 /* AIF2CLK_RATE - [3:0] */ + +/* + * R530 (0x212) - Rate Status + */ +#define WM8994_SR_ERROR_MASK 0x000F /* SR_ERROR - [3:0] */ +#define WM8994_SR_ERROR_SHIFT 0 /* SR_ERROR - [3:0] */ +#define WM8994_SR_ERROR_WIDTH 4 /* SR_ERROR - [3:0] */ + +/* + * R544 (0x220) - FLL1 Control (1) + */ +#define WM8994_FLL1_FRAC 0x0004 /* FLL1_FRAC */ +#define WM8994_FLL1_FRAC_MASK 0x0004 /* FLL1_FRAC */ +#define WM8994_FLL1_FRAC_SHIFT 2 /* FLL1_FRAC */ +#define WM8994_FLL1_FRAC_WIDTH 1 /* FLL1_FRAC */ +#define WM8994_FLL1_OSC_ENA 0x0002 /* FLL1_OSC_ENA */ +#define WM8994_FLL1_OSC_ENA_MASK 0x0002 /* FLL1_OSC_ENA */ +#define WM8994_FLL1_OSC_ENA_SHIFT 1 /* FLL1_OSC_ENA */ +#define WM8994_FLL1_OSC_ENA_WIDTH 1 /* FLL1_OSC_ENA */ +#define WM8994_FLL1_ENA 0x0001 /* FLL1_ENA */ +#define WM8994_FLL1_ENA_MASK 0x0001 /* FLL1_ENA */ +#define WM8994_FLL1_ENA_SHIFT 0 /* FLL1_ENA */ +#define WM8994_FLL1_ENA_WIDTH 1 /* FLL1_ENA */ + +/* + * R545 (0x221) - FLL1 Control (2) + */ +#define WM8994_FLL1_OUTDIV_MASK 0x3F00 /* FLL1_OUTDIV - [13:8] */ +#define WM8994_FLL1_OUTDIV_SHIFT 8 /* FLL1_OUTDIV - [13:8] */ +#define WM8994_FLL1_OUTDIV_WIDTH 6 /* FLL1_OUTDIV - [13:8] */ +#define WM8994_FLL1_CTRL_RATE_MASK 0x0070 /* FLL1_CTRL_RATE - [6:4] */ +#define WM8994_FLL1_CTRL_RATE_SHIFT 4 /* FLL1_CTRL_RATE - [6:4] */ +#define WM8994_FLL1_CTRL_RATE_WIDTH 3 /* FLL1_CTRL_RATE - [6:4] */ +#define WM8994_FLL1_FRATIO_MASK 0x0007 /* FLL1_FRATIO - [2:0] */ +#define WM8994_FLL1_FRATIO_SHIFT 0 /* FLL1_FRATIO - [2:0] */ +#define WM8994_FLL1_FRATIO_WIDTH 3 /* FLL1_FRATIO - [2:0] */ + +/* + * R546 (0x222) - FLL1 Control (3) + */ +#define WM8994_FLL1_K_MASK 0xFFFF /* FLL1_K - [15:0] */ +#define WM8994_FLL1_K_SHIFT 0 /* FLL1_K - [15:0] */ +#define WM8994_FLL1_K_WIDTH 16 /* FLL1_K - [15:0] */ + +/* + * R547 (0x223) - FLL1 Control (4) + */ +#define WM8994_FLL1_N_MASK 0x7FE0 /* FLL1_N - [14:5] */ +#define WM8994_FLL1_N_SHIFT 5 /* FLL1_N - [14:5] */ +#define WM8994_FLL1_N_WIDTH 10 /* FLL1_N - [14:5] */ +#define WM8994_FLL1_LOOP_GAIN_MASK 0x000F /* FLL1_LOOP_GAIN - [3:0] */ +#define WM8994_FLL1_LOOP_GAIN_SHIFT 0 /* FLL1_LOOP_GAIN - [3:0] */ +#define WM8994_FLL1_LOOP_GAIN_WIDTH 4 /* FLL1_LOOP_GAIN - [3:0] */ + +/* + * R548 (0x224) - FLL1 Control (5) + */ +#define WM8994_FLL1_FRC_NCO_VAL_MASK 0x1F80 /* FLL1_FRC_NCO_VAL - [12:7] */ +#define WM8994_FLL1_FRC_NCO_VAL_SHIFT 7 /* FLL1_FRC_NCO_VAL - [12:7] */ +#define WM8994_FLL1_FRC_NCO_VAL_WIDTH 6 /* FLL1_FRC_NCO_VAL - [12:7] */ +#define WM8994_FLL1_FRC_NCO 0x0040 /* FLL1_FRC_NCO */ +#define WM8994_FLL1_FRC_NCO_MASK 0x0040 /* FLL1_FRC_NCO */ +#define WM8994_FLL1_FRC_NCO_SHIFT 6 /* FLL1_FRC_NCO */ +#define WM8994_FLL1_FRC_NCO_WIDTH 1 /* FLL1_FRC_NCO */ +#define WM8994_FLL1_REFCLK_DIV_MASK 0x0018 /* FLL1_REFCLK_DIV - [4:3] */ +#define WM8994_FLL1_REFCLK_DIV_SHIFT 3 /* FLL1_REFCLK_DIV - [4:3] */ +#define WM8994_FLL1_REFCLK_DIV_WIDTH 2 /* FLL1_REFCLK_DIV - [4:3] */ +#define WM8994_FLL1_REFCLK_SRC_MASK 0x0003 /* FLL1_REFCLK_SRC - [1:0] */ +#define WM8994_FLL1_REFCLK_SRC_SHIFT 0 /* FLL1_REFCLK_SRC - [1:0] */ +#define WM8994_FLL1_REFCLK_SRC_WIDTH 2 /* FLL1_REFCLK_SRC - [1:0] */ + +/* + * R576 (0x240) - FLL2 Control (1) + */ +#define WM8994_FLL2_FRAC 0x0004 /* FLL2_FRAC */ +#define WM8994_FLL2_FRAC_MASK 0x0004 /* FLL2_FRAC */ +#define WM8994_FLL2_FRAC_SHIFT 2 /* FLL2_FRAC */ +#define WM8994_FLL2_FRAC_WIDTH 1 /* FLL2_FRAC */ +#define WM8994_FLL2_OSC_ENA 0x0002 /* FLL2_OSC_ENA */ +#define WM8994_FLL2_OSC_ENA_MASK 0x0002 /* FLL2_OSC_ENA */ +#define WM8994_FLL2_OSC_ENA_SHIFT 1 /* FLL2_OSC_ENA */ +#define WM8994_FLL2_OSC_ENA_WIDTH 1 /* FLL2_OSC_ENA */ +#define WM8994_FLL2_ENA 0x0001 /* FLL2_ENA */ +#define WM8994_FLL2_ENA_MASK 0x0001 /* FLL2_ENA */ +#define WM8994_FLL2_ENA_SHIFT 0 /* FLL2_ENA */ +#define WM8994_FLL2_ENA_WIDTH 1 /* FLL2_ENA */ + +/* + * R577 (0x241) - FLL2 Control (2) + */ +#define WM8994_FLL2_OUTDIV_MASK 0x3F00 /* FLL2_OUTDIV - [13:8] */ +#define WM8994_FLL2_OUTDIV_SHIFT 8 /* FLL2_OUTDIV - [13:8] */ +#define WM8994_FLL2_OUTDIV_WIDTH 6 /* FLL2_OUTDIV - [13:8] */ +#define WM8994_FLL2_CTRL_RATE_MASK 0x0070 /* FLL2_CTRL_RATE - [6:4] */ +#define WM8994_FLL2_CTRL_RATE_SHIFT 4 /* FLL2_CTRL_RATE - [6:4] */ +#define WM8994_FLL2_CTRL_RATE_WIDTH 3 /* FLL2_CTRL_RATE - [6:4] */ +#define WM8994_FLL2_FRATIO_MASK 0x0007 /* FLL2_FRATIO - [2:0] */ +#define WM8994_FLL2_FRATIO_SHIFT 0 /* FLL2_FRATIO - [2:0] */ +#define WM8994_FLL2_FRATIO_WIDTH 3 /* FLL2_FRATIO - [2:0] */ + +/* + * R578 (0x242) - FLL2 Control (3) + */ +#define WM8994_FLL2_K_MASK 0xFFFF /* FLL2_K - [15:0] */ +#define WM8994_FLL2_K_SHIFT 0 /* FLL2_K - [15:0] */ +#define WM8994_FLL2_K_WIDTH 16 /* FLL2_K - [15:0] */ + +/* + * R579 (0x243) - FLL2 Control (4) + */ +#define WM8994_FLL2_N_MASK 0x7FE0 /* FLL2_N - [14:5] */ +#define WM8994_FLL2_N_SHIFT 5 /* FLL2_N - [14:5] */ +#define WM8994_FLL2_N_WIDTH 10 /* FLL2_N - [14:5] */ +#define WM8994_FLL2_LOOP_GAIN_MASK 0x000F /* FLL2_LOOP_GAIN - [3:0] */ +#define WM8994_FLL2_LOOP_GAIN_SHIFT 0 /* FLL2_LOOP_GAIN - [3:0] */ +#define WM8994_FLL2_LOOP_GAIN_WIDTH 4 /* FLL2_LOOP_GAIN - [3:0] */ + +/* + * R580 (0x244) - FLL2 Control (5) + */ +#define WM8994_FLL2_FRC_NCO_VAL_MASK 0x1F80 /* FLL2_FRC_NCO_VAL - [12:7] */ +#define WM8994_FLL2_FRC_NCO_VAL_SHIFT 7 /* FLL2_FRC_NCO_VAL - [12:7] */ +#define WM8994_FLL2_FRC_NCO_VAL_WIDTH 6 /* FLL2_FRC_NCO_VAL - [12:7] */ +#define WM8994_FLL2_FRC_NCO 0x0040 /* FLL2_FRC_NCO */ +#define WM8994_FLL2_FRC_NCO_MASK 0x0040 /* FLL2_FRC_NCO */ +#define WM8994_FLL2_FRC_NCO_SHIFT 6 /* FLL2_FRC_NCO */ +#define WM8994_FLL2_FRC_NCO_WIDTH 1 /* FLL2_FRC_NCO */ +#define WM8994_FLL2_REFCLK_DIV_MASK 0x0018 /* FLL2_REFCLK_DIV - [4:3] */ +#define WM8994_FLL2_REFCLK_DIV_SHIFT 3 /* FLL2_REFCLK_DIV - [4:3] */ +#define WM8994_FLL2_REFCLK_DIV_WIDTH 2 /* FLL2_REFCLK_DIV - [4:3] */ +#define WM8994_FLL2_REFCLK_SRC_MASK 0x0003 /* FLL2_REFCLK_SRC - [1:0] */ +#define WM8994_FLL2_REFCLK_SRC_SHIFT 0 /* FLL2_REFCLK_SRC - [1:0] */ +#define WM8994_FLL2_REFCLK_SRC_WIDTH 2 /* FLL2_REFCLK_SRC - [1:0] */ + +/* + * R768 (0x300) - AIF1 Control (1) + */ +#define WM8994_AIF1ADCL_SRC 0x8000 /* AIF1ADCL_SRC */ +#define WM8994_AIF1ADCL_SRC_MASK 0x8000 /* AIF1ADCL_SRC */ +#define WM8994_AIF1ADCL_SRC_SHIFT 15 /* AIF1ADCL_SRC */ +#define WM8994_AIF1ADCL_SRC_WIDTH 1 /* AIF1ADCL_SRC */ +#define WM8994_AIF1ADCR_SRC 0x4000 /* AIF1ADCR_SRC */ +#define WM8994_AIF1ADCR_SRC_MASK 0x4000 /* AIF1ADCR_SRC */ +#define WM8994_AIF1ADCR_SRC_SHIFT 14 /* AIF1ADCR_SRC */ +#define WM8994_AIF1ADCR_SRC_WIDTH 1 /* AIF1ADCR_SRC */ +#define WM8994_AIF1ADC_TDM 0x2000 /* AIF1ADC_TDM */ +#define WM8994_AIF1ADC_TDM_MASK 0x2000 /* AIF1ADC_TDM */ +#define WM8994_AIF1ADC_TDM_SHIFT 13 /* AIF1ADC_TDM */ +#define WM8994_AIF1ADC_TDM_WIDTH 1 /* AIF1ADC_TDM */ +#define WM8994_AIF1_BCLK_INV 0x0100 /* AIF1_BCLK_INV */ +#define WM8994_AIF1_BCLK_INV_MASK 0x0100 /* AIF1_BCLK_INV */ +#define WM8994_AIF1_BCLK_INV_SHIFT 8 /* AIF1_BCLK_INV */ +#define WM8994_AIF1_BCLK_INV_WIDTH 1 /* AIF1_BCLK_INV */ +#define WM8994_AIF1_LRCLK_INV 0x0080 /* AIF1_LRCLK_INV */ +#define WM8994_AIF1_LRCLK_INV_MASK 0x0080 /* AIF1_LRCLK_INV */ +#define WM8994_AIF1_LRCLK_INV_SHIFT 7 /* AIF1_LRCLK_INV */ +#define WM8994_AIF1_LRCLK_INV_WIDTH 1 /* AIF1_LRCLK_INV */ +#define WM8994_AIF1_WL_MASK 0x0060 /* AIF1_WL - [6:5] */ +#define WM8994_AIF1_WL_SHIFT 5 /* AIF1_WL - [6:5] */ +#define WM8994_AIF1_WL_WIDTH 2 /* AIF1_WL - [6:5] */ +#define WM8994_AIF1_FMT_MASK 0x0018 /* AIF1_FMT - [4:3] */ +#define WM8994_AIF1_FMT_SHIFT 3 /* AIF1_FMT - [4:3] */ +#define WM8994_AIF1_FMT_WIDTH 2 /* AIF1_FMT - [4:3] */ + +/* + * R769 (0x301) - AIF1 Control (2) + */ +#define WM8994_AIF1DACL_SRC 0x8000 /* AIF1DACL_SRC */ +#define WM8994_AIF1DACL_SRC_MASK 0x8000 /* AIF1DACL_SRC */ +#define WM8994_AIF1DACL_SRC_SHIFT 15 /* AIF1DACL_SRC */ +#define WM8994_AIF1DACL_SRC_WIDTH 1 /* AIF1DACL_SRC */ +#define WM8994_AIF1DACR_SRC 0x4000 /* AIF1DACR_SRC */ +#define WM8994_AIF1DACR_SRC_MASK 0x4000 /* AIF1DACR_SRC */ +#define WM8994_AIF1DACR_SRC_SHIFT 14 /* AIF1DACR_SRC */ +#define WM8994_AIF1DACR_SRC_WIDTH 1 /* AIF1DACR_SRC */ +#define WM8994_AIF1DAC_BOOST_MASK 0x0C00 /* AIF1DAC_BOOST - [11:10] */ +#define WM8994_AIF1DAC_BOOST_SHIFT 10 /* AIF1DAC_BOOST - [11:10] */ +#define WM8994_AIF1DAC_BOOST_WIDTH 2 /* AIF1DAC_BOOST - [11:10] */ +#define WM8994_AIF1_MONO 0x0100 /* AIF1_MONO */ +#define WM8994_AIF1_MONO_MASK 0x0100 /* AIF1_MONO */ +#define WM8994_AIF1_MONO_SHIFT 8 /* AIF1_MONO */ +#define WM8994_AIF1_MONO_WIDTH 1 /* AIF1_MONO */ +#define WM8994_AIF1DAC_COMP 0x0010 /* AIF1DAC_COMP */ +#define WM8994_AIF1DAC_COMP_MASK 0x0010 /* AIF1DAC_COMP */ +#define WM8994_AIF1DAC_COMP_SHIFT 4 /* AIF1DAC_COMP */ +#define WM8994_AIF1DAC_COMP_WIDTH 1 /* AIF1DAC_COMP */ +#define WM8994_AIF1DAC_COMPMODE 0x0008 /* AIF1DAC_COMPMODE */ +#define WM8994_AIF1DAC_COMPMODE_MASK 0x0008 /* AIF1DAC_COMPMODE */ +#define WM8994_AIF1DAC_COMPMODE_SHIFT 3 /* AIF1DAC_COMPMODE */ +#define WM8994_AIF1DAC_COMPMODE_WIDTH 1 /* AIF1DAC_COMPMODE */ +#define WM8994_AIF1ADC_COMP 0x0004 /* AIF1ADC_COMP */ +#define WM8994_AIF1ADC_COMP_MASK 0x0004 /* AIF1ADC_COMP */ +#define WM8994_AIF1ADC_COMP_SHIFT 2 /* AIF1ADC_COMP */ +#define WM8994_AIF1ADC_COMP_WIDTH 1 /* AIF1ADC_COMP */ +#define WM8994_AIF1ADC_COMPMODE 0x0002 /* AIF1ADC_COMPMODE */ +#define WM8994_AIF1ADC_COMPMODE_MASK 0x0002 /* AIF1ADC_COMPMODE */ +#define WM8994_AIF1ADC_COMPMODE_SHIFT 1 /* AIF1ADC_COMPMODE */ +#define WM8994_AIF1ADC_COMPMODE_WIDTH 1 /* AIF1ADC_COMPMODE */ +#define WM8994_AIF1_LOOPBACK 0x0001 /* AIF1_LOOPBACK */ +#define WM8994_AIF1_LOOPBACK_MASK 0x0001 /* AIF1_LOOPBACK */ +#define WM8994_AIF1_LOOPBACK_SHIFT 0 /* AIF1_LOOPBACK */ +#define WM8994_AIF1_LOOPBACK_WIDTH 1 /* AIF1_LOOPBACK */ + +/* + * R770 (0x302) - AIF1 Master/Slave + */ +#define WM8994_AIF1_TRI 0x8000 /* AIF1_TRI */ +#define WM8994_AIF1_TRI_MASK 0x8000 /* AIF1_TRI */ +#define WM8994_AIF1_TRI_SHIFT 15 /* AIF1_TRI */ +#define WM8994_AIF1_TRI_WIDTH 1 /* AIF1_TRI */ +#define WM8994_AIF1_MSTR 0x4000 /* AIF1_MSTR */ +#define WM8994_AIF1_MSTR_MASK 0x4000 /* AIF1_MSTR */ +#define WM8994_AIF1_MSTR_SHIFT 14 /* AIF1_MSTR */ +#define WM8994_AIF1_MSTR_WIDTH 1 /* AIF1_MSTR */ +#define WM8994_AIF1_CLK_FRC 0x2000 /* AIF1_CLK_FRC */ +#define WM8994_AIF1_CLK_FRC_MASK 0x2000 /* AIF1_CLK_FRC */ +#define WM8994_AIF1_CLK_FRC_SHIFT 13 /* AIF1_CLK_FRC */ +#define WM8994_AIF1_CLK_FRC_WIDTH 1 /* AIF1_CLK_FRC */ +#define WM8994_AIF1_LRCLK_FRC 0x1000 /* AIF1_LRCLK_FRC */ +#define WM8994_AIF1_LRCLK_FRC_MASK 0x1000 /* AIF1_LRCLK_FRC */ +#define WM8994_AIF1_LRCLK_FRC_SHIFT 12 /* AIF1_LRCLK_FRC */ +#define WM8994_AIF1_LRCLK_FRC_WIDTH 1 /* AIF1_LRCLK_FRC */ + +/* + * R771 (0x303) - AIF1 BCLK + */ +#define WM8994_AIF1_BCLK_DIV_MASK 0x01F0 /* AIF1_BCLK_DIV - [8:4] */ +#define WM8994_AIF1_BCLK_DIV_SHIFT 4 /* AIF1_BCLK_DIV - [8:4] */ +#define WM8994_AIF1_BCLK_DIV_WIDTH 5 /* AIF1_BCLK_DIV - [8:4] */ + +/* + * R772 (0x304) - AIF1ADC LRCLK + */ +#define WM8994_AIF1ADC_LRCLK_DIR 0x0800 /* AIF1ADC_LRCLK_DIR */ +#define WM8994_AIF1ADC_LRCLK_DIR_MASK 0x0800 /* AIF1ADC_LRCLK_DIR */ +#define WM8994_AIF1ADC_LRCLK_DIR_SHIFT 11 /* AIF1ADC_LRCLK_DIR */ +#define WM8994_AIF1ADC_LRCLK_DIR_WIDTH 1 /* AIF1ADC_LRCLK_DIR */ +#define WM8994_AIF1ADC_RATE_MASK 0x07FF /* AIF1ADC_RATE - [10:0] */ +#define WM8994_AIF1ADC_RATE_SHIFT 0 /* AIF1ADC_RATE - [10:0] */ +#define WM8994_AIF1ADC_RATE_WIDTH 11 /* AIF1ADC_RATE - [10:0] */ + +/* + * R773 (0x305) - AIF1DAC LRCLK + */ +#define WM8994_AIF1DAC_LRCLK_DIR 0x0800 /* AIF1DAC_LRCLK_DIR */ +#define WM8994_AIF1DAC_LRCLK_DIR_MASK 0x0800 /* AIF1DAC_LRCLK_DIR */ +#define WM8994_AIF1DAC_LRCLK_DIR_SHIFT 11 /* AIF1DAC_LRCLK_DIR */ +#define WM8994_AIF1DAC_LRCLK_DIR_WIDTH 1 /* AIF1DAC_LRCLK_DIR */ +#define WM8994_AIF1DAC_RATE_MASK 0x07FF /* AIF1DAC_RATE - [10:0] */ +#define WM8994_AIF1DAC_RATE_SHIFT 0 /* AIF1DAC_RATE - [10:0] */ +#define WM8994_AIF1DAC_RATE_WIDTH 11 /* AIF1DAC_RATE - [10:0] */ + +/* + * R774 (0x306) - AIF1DAC Data + */ +#define WM8994_AIF1DACL_DAT_INV 0x0002 /* AIF1DACL_DAT_INV */ +#define WM8994_AIF1DACL_DAT_INV_MASK 0x0002 /* AIF1DACL_DAT_INV */ +#define WM8994_AIF1DACL_DAT_INV_SHIFT 1 /* AIF1DACL_DAT_INV */ +#define WM8994_AIF1DACL_DAT_INV_WIDTH 1 /* AIF1DACL_DAT_INV */ +#define WM8994_AIF1DACR_DAT_INV 0x0001 /* AIF1DACR_DAT_INV */ +#define WM8994_AIF1DACR_DAT_INV_MASK 0x0001 /* AIF1DACR_DAT_INV */ +#define WM8994_AIF1DACR_DAT_INV_SHIFT 0 /* AIF1DACR_DAT_INV */ +#define WM8994_AIF1DACR_DAT_INV_WIDTH 1 /* AIF1DACR_DAT_INV */ + +/* + * R775 (0x307) - AIF1ADC Data + */ +#define WM8994_AIF1ADCL_DAT_INV 0x0002 /* AIF1ADCL_DAT_INV */ +#define WM8994_AIF1ADCL_DAT_INV_MASK 0x0002 /* AIF1ADCL_DAT_INV */ +#define WM8994_AIF1ADCL_DAT_INV_SHIFT 1 /* AIF1ADCL_DAT_INV */ +#define WM8994_AIF1ADCL_DAT_INV_WIDTH 1 /* AIF1ADCL_DAT_INV */ +#define WM8994_AIF1ADCR_DAT_INV 0x0001 /* AIF1ADCR_DAT_INV */ +#define WM8994_AIF1ADCR_DAT_INV_MASK 0x0001 /* AIF1ADCR_DAT_INV */ +#define WM8994_AIF1ADCR_DAT_INV_SHIFT 0 /* AIF1ADCR_DAT_INV */ +#define WM8994_AIF1ADCR_DAT_INV_WIDTH 1 /* AIF1ADCR_DAT_INV */ + +/* + * R784 (0x310) - AIF2 Control (1) + */ +#define WM8994_AIF2ADCL_SRC 0x8000 /* AIF2ADCL_SRC */ +#define WM8994_AIF2ADCL_SRC_MASK 0x8000 /* AIF2ADCL_SRC */ +#define WM8994_AIF2ADCL_SRC_SHIFT 15 /* AIF2ADCL_SRC */ +#define WM8994_AIF2ADCL_SRC_WIDTH 1 /* AIF2ADCL_SRC */ +#define WM8994_AIF2ADCR_SRC 0x4000 /* AIF2ADCR_SRC */ +#define WM8994_AIF2ADCR_SRC_MASK 0x4000 /* AIF2ADCR_SRC */ +#define WM8994_AIF2ADCR_SRC_SHIFT 14 /* AIF2ADCR_SRC */ +#define WM8994_AIF2ADCR_SRC_WIDTH 1 /* AIF2ADCR_SRC */ +#define WM8994_AIF2ADC_TDM 0x2000 /* AIF2ADC_TDM */ +#define WM8994_AIF2ADC_TDM_MASK 0x2000 /* AIF2ADC_TDM */ +#define WM8994_AIF2ADC_TDM_SHIFT 13 /* AIF2ADC_TDM */ +#define WM8994_AIF2ADC_TDM_WIDTH 1 /* AIF2ADC_TDM */ +#define WM8994_AIF2ADC_TDM_CHAN 0x1000 /* AIF2ADC_TDM_CHAN */ +#define WM8994_AIF2ADC_TDM_CHAN_MASK 0x1000 /* AIF2ADC_TDM_CHAN */ +#define WM8994_AIF2ADC_TDM_CHAN_SHIFT 12 /* AIF2ADC_TDM_CHAN */ +#define WM8994_AIF2ADC_TDM_CHAN_WIDTH 1 /* AIF2ADC_TDM_CHAN */ +#define WM8994_AIF2_BCLK_INV 0x0100 /* AIF2_BCLK_INV */ +#define WM8994_AIF2_BCLK_INV_MASK 0x0100 /* AIF2_BCLK_INV */ +#define WM8994_AIF2_BCLK_INV_SHIFT 8 /* AIF2_BCLK_INV */ +#define WM8994_AIF2_BCLK_INV_WIDTH 1 /* AIF2_BCLK_INV */ +#define WM8994_AIF2_LRCLK_INV 0x0080 /* AIF2_LRCLK_INV */ +#define WM8994_AIF2_LRCLK_INV_MASK 0x0080 /* AIF2_LRCLK_INV */ +#define WM8994_AIF2_LRCLK_INV_SHIFT 7 /* AIF2_LRCLK_INV */ +#define WM8994_AIF2_LRCLK_INV_WIDTH 1 /* AIF2_LRCLK_INV */ +#define WM8994_AIF2_WL_MASK 0x0060 /* AIF2_WL - [6:5] */ +#define WM8994_AIF2_WL_SHIFT 5 /* AIF2_WL - [6:5] */ +#define WM8994_AIF2_WL_WIDTH 2 /* AIF2_WL - [6:5] */ +#define WM8994_AIF2_FMT_MASK 0x0018 /* AIF2_FMT - [4:3] */ +#define WM8994_AIF2_FMT_SHIFT 3 /* AIF2_FMT - [4:3] */ +#define WM8994_AIF2_FMT_WIDTH 2 /* AIF2_FMT - [4:3] */ + +/* + * R785 (0x311) - AIF2 Control (2) + */ +#define WM8994_AIF2DACL_SRC 0x8000 /* AIF2DACL_SRC */ +#define WM8994_AIF2DACL_SRC_MASK 0x8000 /* AIF2DACL_SRC */ +#define WM8994_AIF2DACL_SRC_SHIFT 15 /* AIF2DACL_SRC */ +#define WM8994_AIF2DACL_SRC_WIDTH 1 /* AIF2DACL_SRC */ +#define WM8994_AIF2DACR_SRC 0x4000 /* AIF2DACR_SRC */ +#define WM8994_AIF2DACR_SRC_MASK 0x4000 /* AIF2DACR_SRC */ +#define WM8994_AIF2DACR_SRC_SHIFT 14 /* AIF2DACR_SRC */ +#define WM8994_AIF2DACR_SRC_WIDTH 1 /* AIF2DACR_SRC */ +#define WM8994_AIF2DAC_TDM 0x2000 /* AIF2DAC_TDM */ +#define WM8994_AIF2DAC_TDM_MASK 0x2000 /* AIF2DAC_TDM */ +#define WM8994_AIF2DAC_TDM_SHIFT 13 /* AIF2DAC_TDM */ +#define WM8994_AIF2DAC_TDM_WIDTH 1 /* AIF2DAC_TDM */ +#define WM8994_AIF2DAC_TDM_CHAN 0x1000 /* AIF2DAC_TDM_CHAN */ +#define WM8994_AIF2DAC_TDM_CHAN_MASK 0x1000 /* AIF2DAC_TDM_CHAN */ +#define WM8994_AIF2DAC_TDM_CHAN_SHIFT 12 /* AIF2DAC_TDM_CHAN */ +#define WM8994_AIF2DAC_TDM_CHAN_WIDTH 1 /* AIF2DAC_TDM_CHAN */ +#define WM8994_AIF2DAC_BOOST_MASK 0x0C00 /* AIF2DAC_BOOST - [11:10] */ +#define WM8994_AIF2DAC_BOOST_SHIFT 10 /* AIF2DAC_BOOST - [11:10] */ +#define WM8994_AIF2DAC_BOOST_WIDTH 2 /* AIF2DAC_BOOST - [11:10] */ +#define WM8994_AIF2_MONO 0x0100 /* AIF2_MONO */ +#define WM8994_AIF2_MONO_MASK 0x0100 /* AIF2_MONO */ +#define WM8994_AIF2_MONO_SHIFT 8 /* AIF2_MONO */ +#define WM8994_AIF2_MONO_WIDTH 1 /* AIF2_MONO */ +#define WM8994_AIF2DAC_COMP 0x0010 /* AIF2DAC_COMP */ +#define WM8994_AIF2DAC_COMP_MASK 0x0010 /* AIF2DAC_COMP */ +#define WM8994_AIF2DAC_COMP_SHIFT 4 /* AIF2DAC_COMP */ +#define WM8994_AIF2DAC_COMP_WIDTH 1 /* AIF2DAC_COMP */ +#define WM8994_AIF2DAC_COMPMODE 0x0008 /* AIF2DAC_COMPMODE */ +#define WM8994_AIF2DAC_COMPMODE_MASK 0x0008 /* AIF2DAC_COMPMODE */ +#define WM8994_AIF2DAC_COMPMODE_SHIFT 3 /* AIF2DAC_COMPMODE */ +#define WM8994_AIF2DAC_COMPMODE_WIDTH 1 /* AIF2DAC_COMPMODE */ +#define WM8994_AIF2ADC_COMP 0x0004 /* AIF2ADC_COMP */ +#define WM8994_AIF2ADC_COMP_MASK 0x0004 /* AIF2ADC_COMP */ +#define WM8994_AIF2ADC_COMP_SHIFT 2 /* AIF2ADC_COMP */ +#define WM8994_AIF2ADC_COMP_WIDTH 1 /* AIF2ADC_COMP */ +#define WM8994_AIF2ADC_COMPMODE 0x0002 /* AIF2ADC_COMPMODE */ +#define WM8994_AIF2ADC_COMPMODE_MASK 0x0002 /* AIF2ADC_COMPMODE */ +#define WM8994_AIF2ADC_COMPMODE_SHIFT 1 /* AIF2ADC_COMPMODE */ +#define WM8994_AIF2ADC_COMPMODE_WIDTH 1 /* AIF2ADC_COMPMODE */ +#define WM8994_AIF2_LOOPBACK 0x0001 /* AIF2_LOOPBACK */ +#define WM8994_AIF2_LOOPBACK_MASK 0x0001 /* AIF2_LOOPBACK */ +#define WM8994_AIF2_LOOPBACK_SHIFT 0 /* AIF2_LOOPBACK */ +#define WM8994_AIF2_LOOPBACK_WIDTH 1 /* AIF2_LOOPBACK */ + +/* + * R786 (0x312) - AIF2 Master/Slave + */ +#define WM8994_AIF2_TRI 0x8000 /* AIF2_TRI */ +#define WM8994_AIF2_TRI_MASK 0x8000 /* AIF2_TRI */ +#define WM8994_AIF2_TRI_SHIFT 15 /* AIF2_TRI */ +#define WM8994_AIF2_TRI_WIDTH 1 /* AIF2_TRI */ +#define WM8994_AIF2_MSTR 0x4000 /* AIF2_MSTR */ +#define WM8994_AIF2_MSTR_MASK 0x4000 /* AIF2_MSTR */ +#define WM8994_AIF2_MSTR_SHIFT 14 /* AIF2_MSTR */ +#define WM8994_AIF2_MSTR_WIDTH 1 /* AIF2_MSTR */ +#define WM8994_AIF2_CLK_FRC 0x2000 /* AIF2_CLK_FRC */ +#define WM8994_AIF2_CLK_FRC_MASK 0x2000 /* AIF2_CLK_FRC */ +#define WM8994_AIF2_CLK_FRC_SHIFT 13 /* AIF2_CLK_FRC */ +#define WM8994_AIF2_CLK_FRC_WIDTH 1 /* AIF2_CLK_FRC */ +#define WM8994_AIF2_LRCLK_FRC 0x1000 /* AIF2_LRCLK_FRC */ +#define WM8994_AIF2_LRCLK_FRC_MASK 0x1000 /* AIF2_LRCLK_FRC */ +#define WM8994_AIF2_LRCLK_FRC_SHIFT 12 /* AIF2_LRCLK_FRC */ +#define WM8994_AIF2_LRCLK_FRC_WIDTH 1 /* AIF2_LRCLK_FRC */ + +/* + * R787 (0x313) - AIF2 BCLK + */ +#define WM8994_AIF2_BCLK_DIV_MASK 0x01F0 /* AIF2_BCLK_DIV - [8:4] */ +#define WM8994_AIF2_BCLK_DIV_SHIFT 4 /* AIF2_BCLK_DIV - [8:4] */ +#define WM8994_AIF2_BCLK_DIV_WIDTH 5 /* AIF2_BCLK_DIV - [8:4] */ + +/* + * R788 (0x314) - AIF2ADC LRCLK + */ +#define WM8994_AIF2ADC_LRCLK_DIR 0x0800 /* AIF2ADC_LRCLK_DIR */ +#define WM8994_AIF2ADC_LRCLK_DIR_MASK 0x0800 /* AIF2ADC_LRCLK_DIR */ +#define WM8994_AIF2ADC_LRCLK_DIR_SHIFT 11 /* AIF2ADC_LRCLK_DIR */ +#define WM8994_AIF2ADC_LRCLK_DIR_WIDTH 1 /* AIF2ADC_LRCLK_DIR */ +#define WM8994_AIF2ADC_RATE_MASK 0x07FF /* AIF2ADC_RATE - [10:0] */ +#define WM8994_AIF2ADC_RATE_SHIFT 0 /* AIF2ADC_RATE - [10:0] */ +#define WM8994_AIF2ADC_RATE_WIDTH 11 /* AIF2ADC_RATE - [10:0] */ + +/* + * R789 (0x315) - AIF2DAC LRCLK + */ +#define WM8994_AIF2DAC_LRCLK_DIR 0x0800 /* AIF2DAC_LRCLK_DIR */ +#define WM8994_AIF2DAC_LRCLK_DIR_MASK 0x0800 /* AIF2DAC_LRCLK_DIR */ +#define WM8994_AIF2DAC_LRCLK_DIR_SHIFT 11 /* AIF2DAC_LRCLK_DIR */ +#define WM8994_AIF2DAC_LRCLK_DIR_WIDTH 1 /* AIF2DAC_LRCLK_DIR */ +#define WM8994_AIF2DAC_RATE_MASK 0x07FF /* AIF2DAC_RATE - [10:0] */ +#define WM8994_AIF2DAC_RATE_SHIFT 0 /* AIF2DAC_RATE - [10:0] */ +#define WM8994_AIF2DAC_RATE_WIDTH 11 /* AIF2DAC_RATE - [10:0] */ + +/* + * R790 (0x316) - AIF2DAC Data + */ +#define WM8994_AIF2DACL_DAT_INV 0x0002 /* AIF2DACL_DAT_INV */ +#define WM8994_AIF2DACL_DAT_INV_MASK 0x0002 /* AIF2DACL_DAT_INV */ +#define WM8994_AIF2DACL_DAT_INV_SHIFT 1 /* AIF2DACL_DAT_INV */ +#define WM8994_AIF2DACL_DAT_INV_WIDTH 1 /* AIF2DACL_DAT_INV */ +#define WM8994_AIF2DACR_DAT_INV 0x0001 /* AIF2DACR_DAT_INV */ +#define WM8994_AIF2DACR_DAT_INV_MASK 0x0001 /* AIF2DACR_DAT_INV */ +#define WM8994_AIF2DACR_DAT_INV_SHIFT 0 /* AIF2DACR_DAT_INV */ +#define WM8994_AIF2DACR_DAT_INV_WIDTH 1 /* AIF2DACR_DAT_INV */ + +/* + * R791 (0x317) - AIF2ADC Data + */ +#define WM8994_AIF2ADCL_DAT_INV 0x0002 /* AIF2ADCL_DAT_INV */ +#define WM8994_AIF2ADCL_DAT_INV_MASK 0x0002 /* AIF2ADCL_DAT_INV */ +#define WM8994_AIF2ADCL_DAT_INV_SHIFT 1 /* AIF2ADCL_DAT_INV */ +#define WM8994_AIF2ADCL_DAT_INV_WIDTH 1 /* AIF2ADCL_DAT_INV */ +#define WM8994_AIF2ADCR_DAT_INV 0x0001 /* AIF2ADCR_DAT_INV */ +#define WM8994_AIF2ADCR_DAT_INV_MASK 0x0001 /* AIF2ADCR_DAT_INV */ +#define WM8994_AIF2ADCR_DAT_INV_SHIFT 0 /* AIF2ADCR_DAT_INV */ +#define WM8994_AIF2ADCR_DAT_INV_WIDTH 1 /* AIF2ADCR_DAT_INV */ + +/* + * R1024 (0x400) - AIF1 ADC1 Left Volume + */ +#define WM8994_AIF1ADC1_VU 0x0100 /* AIF1ADC1_VU */ +#define WM8994_AIF1ADC1_VU_MASK 0x0100 /* AIF1ADC1_VU */ +#define WM8994_AIF1ADC1_VU_SHIFT 8 /* AIF1ADC1_VU */ +#define WM8994_AIF1ADC1_VU_WIDTH 1 /* AIF1ADC1_VU */ +#define WM8994_AIF1ADC1L_VOL_MASK 0x00FF /* AIF1ADC1L_VOL - [7:0] */ +#define WM8994_AIF1ADC1L_VOL_SHIFT 0 /* AIF1ADC1L_VOL - [7:0] */ +#define WM8994_AIF1ADC1L_VOL_WIDTH 8 /* AIF1ADC1L_VOL - [7:0] */ + +/* + * R1025 (0x401) - AIF1 ADC1 Right Volume + */ +#define WM8994_AIF1ADC1_VU 0x0100 /* AIF1ADC1_VU */ +#define WM8994_AIF1ADC1_VU_MASK 0x0100 /* AIF1ADC1_VU */ +#define WM8994_AIF1ADC1_VU_SHIFT 8 /* AIF1ADC1_VU */ +#define WM8994_AIF1ADC1_VU_WIDTH 1 /* AIF1ADC1_VU */ +#define WM8994_AIF1ADC1R_VOL_MASK 0x00FF /* AIF1ADC1R_VOL - [7:0] */ +#define WM8994_AIF1ADC1R_VOL_SHIFT 0 /* AIF1ADC1R_VOL - [7:0] */ +#define WM8994_AIF1ADC1R_VOL_WIDTH 8 /* AIF1ADC1R_VOL - [7:0] */ + +/* + * R1026 (0x402) - AIF1 DAC1 Left Volume + */ +#define WM8994_AIF1DAC1_VU 0x0100 /* AIF1DAC1_VU */ +#define WM8994_AIF1DAC1_VU_MASK 0x0100 /* AIF1DAC1_VU */ +#define WM8994_AIF1DAC1_VU_SHIFT 8 /* AIF1DAC1_VU */ +#define WM8994_AIF1DAC1_VU_WIDTH 1 /* AIF1DAC1_VU */ +#define WM8994_AIF1DAC1L_VOL_MASK 0x00FF /* AIF1DAC1L_VOL - [7:0] */ +#define WM8994_AIF1DAC1L_VOL_SHIFT 0 /* AIF1DAC1L_VOL - [7:0] */ +#define WM8994_AIF1DAC1L_VOL_WIDTH 8 /* AIF1DAC1L_VOL - [7:0] */ + +/* + * R1027 (0x403) - AIF1 DAC1 Right Volume + */ +#define WM8994_AIF1DAC1_VU 0x0100 /* AIF1DAC1_VU */ +#define WM8994_AIF1DAC1_VU_MASK 0x0100 /* AIF1DAC1_VU */ +#define WM8994_AIF1DAC1_VU_SHIFT 8 /* AIF1DAC1_VU */ +#define WM8994_AIF1DAC1_VU_WIDTH 1 /* AIF1DAC1_VU */ +#define WM8994_AIF1DAC1R_VOL_MASK 0x00FF /* AIF1DAC1R_VOL - [7:0] */ +#define WM8994_AIF1DAC1R_VOL_SHIFT 0 /* AIF1DAC1R_VOL - [7:0] */ +#define WM8994_AIF1DAC1R_VOL_WIDTH 8 /* AIF1DAC1R_VOL - [7:0] */ + +/* + * R1028 (0x404) - AIF1 ADC2 Left Volume + */ +#define WM8994_AIF1ADC2_VU 0x0100 /* AIF1ADC2_VU */ +#define WM8994_AIF1ADC2_VU_MASK 0x0100 /* AIF1ADC2_VU */ +#define WM8994_AIF1ADC2_VU_SHIFT 8 /* AIF1ADC2_VU */ +#define WM8994_AIF1ADC2_VU_WIDTH 1 /* AIF1ADC2_VU */ +#define WM8994_AIF1ADC2L_VOL_MASK 0x00FF /* AIF1ADC2L_VOL - [7:0] */ +#define WM8994_AIF1ADC2L_VOL_SHIFT 0 /* AIF1ADC2L_VOL - [7:0] */ +#define WM8994_AIF1ADC2L_VOL_WIDTH 8 /* AIF1ADC2L_VOL - [7:0] */ + +/* + * R1029 (0x405) - AIF1 ADC2 Right Volume + */ +#define WM8994_AIF1ADC2_VU 0x0100 /* AIF1ADC2_VU */ +#define WM8994_AIF1ADC2_VU_MASK 0x0100 /* AIF1ADC2_VU */ +#define WM8994_AIF1ADC2_VU_SHIFT 8 /* AIF1ADC2_VU */ +#define WM8994_AIF1ADC2_VU_WIDTH 1 /* AIF1ADC2_VU */ +#define WM8994_AIF1ADC2R_VOL_MASK 0x00FF /* AIF1ADC2R_VOL - [7:0] */ +#define WM8994_AIF1ADC2R_VOL_SHIFT 0 /* AIF1ADC2R_VOL - [7:0] */ +#define WM8994_AIF1ADC2R_VOL_WIDTH 8 /* AIF1ADC2R_VOL - [7:0] */ + +/* + * R1030 (0x406) - AIF1 DAC2 Left Volume + */ +#define WM8994_AIF1DAC2_VU 0x0100 /* AIF1DAC2_VU */ +#define WM8994_AIF1DAC2_VU_MASK 0x0100 /* AIF1DAC2_VU */ +#define WM8994_AIF1DAC2_VU_SHIFT 8 /* AIF1DAC2_VU */ +#define WM8994_AIF1DAC2_VU_WIDTH 1 /* AIF1DAC2_VU */ +#define WM8994_AIF1DAC2L_VOL_MASK 0x00FF /* AIF1DAC2L_VOL - [7:0] */ +#define WM8994_AIF1DAC2L_VOL_SHIFT 0 /* AIF1DAC2L_VOL - [7:0] */ +#define WM8994_AIF1DAC2L_VOL_WIDTH 8 /* AIF1DAC2L_VOL - [7:0] */ + +/* + * R1031 (0x407) - AIF1 DAC2 Right Volume + */ +#define WM8994_AIF1DAC2_VU 0x0100 /* AIF1DAC2_VU */ +#define WM8994_AIF1DAC2_VU_MASK 0x0100 /* AIF1DAC2_VU */ +#define WM8994_AIF1DAC2_VU_SHIFT 8 /* AIF1DAC2_VU */ +#define WM8994_AIF1DAC2_VU_WIDTH 1 /* AIF1DAC2_VU */ +#define WM8994_AIF1DAC2R_VOL_MASK 0x00FF /* AIF1DAC2R_VOL - [7:0] */ +#define WM8994_AIF1DAC2R_VOL_SHIFT 0 /* AIF1DAC2R_VOL - [7:0] */ +#define WM8994_AIF1DAC2R_VOL_WIDTH 8 /* AIF1DAC2R_VOL - [7:0] */ + +/* + * R1040 (0x410) - AIF1 ADC1 Filters + */ +#define WM8994_AIF1ADC_4FS 0x8000 /* AIF1ADC_4FS */ +#define WM8994_AIF1ADC_4FS_MASK 0x8000 /* AIF1ADC_4FS */ +#define WM8994_AIF1ADC_4FS_SHIFT 15 /* AIF1ADC_4FS */ +#define WM8994_AIF1ADC_4FS_WIDTH 1 /* AIF1ADC_4FS */ +#define WM8994_AIF1ADC1_HPF_CUT_MASK 0x6000 /* AIF1ADC1_HPF_CUT - [14:13] */ +#define WM8994_AIF1ADC1_HPF_CUT_SHIFT 13 /* AIF1ADC1_HPF_CUT - [14:13] */ +#define WM8994_AIF1ADC1_HPF_CUT_WIDTH 2 /* AIF1ADC1_HPF_CUT - [14:13] */ +#define WM8994_AIF1ADC1L_HPF 0x1000 /* AIF1ADC1L_HPF */ +#define WM8994_AIF1ADC1L_HPF_MASK 0x1000 /* AIF1ADC1L_HPF */ +#define WM8994_AIF1ADC1L_HPF_SHIFT 12 /* AIF1ADC1L_HPF */ +#define WM8994_AIF1ADC1L_HPF_WIDTH 1 /* AIF1ADC1L_HPF */ +#define WM8994_AIF1ADC1R_HPF 0x0800 /* AIF1ADC1R_HPF */ +#define WM8994_AIF1ADC1R_HPF_MASK 0x0800 /* AIF1ADC1R_HPF */ +#define WM8994_AIF1ADC1R_HPF_SHIFT 11 /* AIF1ADC1R_HPF */ +#define WM8994_AIF1ADC1R_HPF_WIDTH 1 /* AIF1ADC1R_HPF */ + +/* + * R1041 (0x411) - AIF1 ADC2 Filters + */ +#define WM8994_AIF1ADC2_HPF_CUT_MASK 0x6000 /* AIF1ADC2_HPF_CUT - [14:13] */ +#define WM8994_AIF1ADC2_HPF_CUT_SHIFT 13 /* AIF1ADC2_HPF_CUT - [14:13] */ +#define WM8994_AIF1ADC2_HPF_CUT_WIDTH 2 /* AIF1ADC2_HPF_CUT - [14:13] */ +#define WM8994_AIF1ADC2L_HPF 0x1000 /* AIF1ADC2L_HPF */ +#define WM8994_AIF1ADC2L_HPF_MASK 0x1000 /* AIF1ADC2L_HPF */ +#define WM8994_AIF1ADC2L_HPF_SHIFT 12 /* AIF1ADC2L_HPF */ +#define WM8994_AIF1ADC2L_HPF_WIDTH 1 /* AIF1ADC2L_HPF */ +#define WM8994_AIF1ADC2R_HPF 0x0800 /* AIF1ADC2R_HPF */ +#define WM8994_AIF1ADC2R_HPF_MASK 0x0800 /* AIF1ADC2R_HPF */ +#define WM8994_AIF1ADC2R_HPF_SHIFT 11 /* AIF1ADC2R_HPF */ +#define WM8994_AIF1ADC2R_HPF_WIDTH 1 /* AIF1ADC2R_HPF */ + +/* + * R1056 (0x420) - AIF1 DAC1 Filters (1) + */ +#define WM8994_AIF1DAC1_MUTE 0x0200 /* AIF1DAC1_MUTE */ +#define WM8994_AIF1DAC1_MUTE_MASK 0x0200 /* AIF1DAC1_MUTE */ +#define WM8994_AIF1DAC1_MUTE_SHIFT 9 /* AIF1DAC1_MUTE */ +#define WM8994_AIF1DAC1_MUTE_WIDTH 1 /* AIF1DAC1_MUTE */ +#define WM8994_AIF1DAC1_MONO 0x0080 /* AIF1DAC1_MONO */ +#define WM8994_AIF1DAC1_MONO_MASK 0x0080 /* AIF1DAC1_MONO */ +#define WM8994_AIF1DAC1_MONO_SHIFT 7 /* AIF1DAC1_MONO */ +#define WM8994_AIF1DAC1_MONO_WIDTH 1 /* AIF1DAC1_MONO */ +#define WM8994_AIF1DAC1_MUTERATE 0x0020 /* AIF1DAC1_MUTERATE */ +#define WM8994_AIF1DAC1_MUTERATE_MASK 0x0020 /* AIF1DAC1_MUTERATE */ +#define WM8994_AIF1DAC1_MUTERATE_SHIFT 5 /* AIF1DAC1_MUTERATE */ +#define WM8994_AIF1DAC1_MUTERATE_WIDTH 1 /* AIF1DAC1_MUTERATE */ +#define WM8994_AIF1DAC1_UNMUTE_RAMP 0x0010 /* AIF1DAC1_UNMUTE_RAMP */ +#define WM8994_AIF1DAC1_UNMUTE_RAMP_MASK 0x0010 /* AIF1DAC1_UNMUTE_RAMP */ +#define WM8994_AIF1DAC1_UNMUTE_RAMP_SHIFT 4 /* AIF1DAC1_UNMUTE_RAMP */ +#define WM8994_AIF1DAC1_UNMUTE_RAMP_WIDTH 1 /* AIF1DAC1_UNMUTE_RAMP */ +#define WM8994_AIF1DAC1_DEEMP_MASK 0x0006 /* AIF1DAC1_DEEMP - [2:1] */ +#define WM8994_AIF1DAC1_DEEMP_SHIFT 1 /* AIF1DAC1_DEEMP - [2:1] */ +#define WM8994_AIF1DAC1_DEEMP_WIDTH 2 /* AIF1DAC1_DEEMP - [2:1] */ + +/* + * R1057 (0x421) - AIF1 DAC1 Filters (2) + */ +#define WM8994_AIF1DAC1_3D_GAIN_MASK 0x3E00 /* AIF1DAC1_3D_GAIN - [13:9] */ +#define WM8994_AIF1DAC1_3D_GAIN_SHIFT 9 /* AIF1DAC1_3D_GAIN - [13:9] */ +#define WM8994_AIF1DAC1_3D_GAIN_WIDTH 5 /* AIF1DAC1_3D_GAIN - [13:9] */ +#define WM8994_AIF1DAC1_3D_ENA 0x0100 /* AIF1DAC1_3D_ENA */ +#define WM8994_AIF1DAC1_3D_ENA_MASK 0x0100 /* AIF1DAC1_3D_ENA */ +#define WM8994_AIF1DAC1_3D_ENA_SHIFT 8 /* AIF1DAC1_3D_ENA */ +#define WM8994_AIF1DAC1_3D_ENA_WIDTH 1 /* AIF1DAC1_3D_ENA */ + +/* + * R1058 (0x422) - AIF1 DAC2 Filters (1) + */ +#define WM8994_AIF1DAC2_MUTE 0x0200 /* AIF1DAC2_MUTE */ +#define WM8994_AIF1DAC2_MUTE_MASK 0x0200 /* AIF1DAC2_MUTE */ +#define WM8994_AIF1DAC2_MUTE_SHIFT 9 /* AIF1DAC2_MUTE */ +#define WM8994_AIF1DAC2_MUTE_WIDTH 1 /* AIF1DAC2_MUTE */ +#define WM8994_AIF1DAC2_MONO 0x0080 /* AIF1DAC2_MONO */ +#define WM8994_AIF1DAC2_MONO_MASK 0x0080 /* AIF1DAC2_MONO */ +#define WM8994_AIF1DAC2_MONO_SHIFT 7 /* AIF1DAC2_MONO */ +#define WM8994_AIF1DAC2_MONO_WIDTH 1 /* AIF1DAC2_MONO */ +#define WM8994_AIF1DAC2_MUTERATE 0x0020 /* AIF1DAC2_MUTERATE */ +#define WM8994_AIF1DAC2_MUTERATE_MASK 0x0020 /* AIF1DAC2_MUTERATE */ +#define WM8994_AIF1DAC2_MUTERATE_SHIFT 5 /* AIF1DAC2_MUTERATE */ +#define WM8994_AIF1DAC2_MUTERATE_WIDTH 1 /* AIF1DAC2_MUTERATE */ +#define WM8994_AIF1DAC2_UNMUTE_RAMP 0x0010 /* AIF1DAC2_UNMUTE_RAMP */ +#define WM8994_AIF1DAC2_UNMUTE_RAMP_MASK 0x0010 /* AIF1DAC2_UNMUTE_RAMP */ +#define WM8994_AIF1DAC2_UNMUTE_RAMP_SHIFT 4 /* AIF1DAC2_UNMUTE_RAMP */ +#define WM8994_AIF1DAC2_UNMUTE_RAMP_WIDTH 1 /* AIF1DAC2_UNMUTE_RAMP */ +#define WM8994_AIF1DAC2_DEEMP_MASK 0x0006 /* AIF1DAC2_DEEMP - [2:1] */ +#define WM8994_AIF1DAC2_DEEMP_SHIFT 1 /* AIF1DAC2_DEEMP - [2:1] */ +#define WM8994_AIF1DAC2_DEEMP_WIDTH 2 /* AIF1DAC2_DEEMP - [2:1] */ + +/* + * R1059 (0x423) - AIF1 DAC2 Filters (2) + */ +#define WM8994_AIF1DAC2_3D_GAIN_MASK 0x3E00 /* AIF1DAC2_3D_GAIN - [13:9] */ +#define WM8994_AIF1DAC2_3D_GAIN_SHIFT 9 /* AIF1DAC2_3D_GAIN - [13:9] */ +#define WM8994_AIF1DAC2_3D_GAIN_WIDTH 5 /* AIF1DAC2_3D_GAIN - [13:9] */ +#define WM8994_AIF1DAC2_3D_ENA 0x0100 /* AIF1DAC2_3D_ENA */ +#define WM8994_AIF1DAC2_3D_ENA_MASK 0x0100 /* AIF1DAC2_3D_ENA */ +#define WM8994_AIF1DAC2_3D_ENA_SHIFT 8 /* AIF1DAC2_3D_ENA */ +#define WM8994_AIF1DAC2_3D_ENA_WIDTH 1 /* AIF1DAC2_3D_ENA */ + +/* + * R1088 (0x440) - AIF1 DRC1 (1) + */ +#define WM8994_AIF1DRC1_SIG_DET_RMS_MASK 0xF800 /* AIF1DRC1_SIG_DET_RMS - [15:11] */ +#define WM8994_AIF1DRC1_SIG_DET_RMS_SHIFT 11 /* AIF1DRC1_SIG_DET_RMS - [15:11] */ +#define WM8994_AIF1DRC1_SIG_DET_RMS_WIDTH 5 /* AIF1DRC1_SIG_DET_RMS - [15:11] */ +#define WM8994_AIF1DRC1_SIG_DET_PK_MASK 0x0600 /* AIF1DRC1_SIG_DET_PK - [10:9] */ +#define WM8994_AIF1DRC1_SIG_DET_PK_SHIFT 9 /* AIF1DRC1_SIG_DET_PK - [10:9] */ +#define WM8994_AIF1DRC1_SIG_DET_PK_WIDTH 2 /* AIF1DRC1_SIG_DET_PK - [10:9] */ +#define WM8994_AIF1DRC1_NG_ENA 0x0100 /* AIF1DRC1_NG_ENA */ +#define WM8994_AIF1DRC1_NG_ENA_MASK 0x0100 /* AIF1DRC1_NG_ENA */ +#define WM8994_AIF1DRC1_NG_ENA_SHIFT 8 /* AIF1DRC1_NG_ENA */ +#define WM8994_AIF1DRC1_NG_ENA_WIDTH 1 /* AIF1DRC1_NG_ENA */ +#define WM8994_AIF1DRC1_SIG_DET_MODE 0x0080 /* AIF1DRC1_SIG_DET_MODE */ +#define WM8994_AIF1DRC1_SIG_DET_MODE_MASK 0x0080 /* AIF1DRC1_SIG_DET_MODE */ +#define WM8994_AIF1DRC1_SIG_DET_MODE_SHIFT 7 /* AIF1DRC1_SIG_DET_MODE */ +#define WM8994_AIF1DRC1_SIG_DET_MODE_WIDTH 1 /* AIF1DRC1_SIG_DET_MODE */ +#define WM8994_AIF1DRC1_SIG_DET 0x0040 /* AIF1DRC1_SIG_DET */ +#define WM8994_AIF1DRC1_SIG_DET_MASK 0x0040 /* AIF1DRC1_SIG_DET */ +#define WM8994_AIF1DRC1_SIG_DET_SHIFT 6 /* AIF1DRC1_SIG_DET */ +#define WM8994_AIF1DRC1_SIG_DET_WIDTH 1 /* AIF1DRC1_SIG_DET */ +#define WM8994_AIF1DRC1_KNEE2_OP_ENA 0x0020 /* AIF1DRC1_KNEE2_OP_ENA */ +#define WM8994_AIF1DRC1_KNEE2_OP_ENA_MASK 0x0020 /* AIF1DRC1_KNEE2_OP_ENA */ +#define WM8994_AIF1DRC1_KNEE2_OP_ENA_SHIFT 5 /* AIF1DRC1_KNEE2_OP_ENA */ +#define WM8994_AIF1DRC1_KNEE2_OP_ENA_WIDTH 1 /* AIF1DRC1_KNEE2_OP_ENA */ +#define WM8994_AIF1DRC1_QR 0x0010 /* AIF1DRC1_QR */ +#define WM8994_AIF1DRC1_QR_MASK 0x0010 /* AIF1DRC1_QR */ +#define WM8994_AIF1DRC1_QR_SHIFT 4 /* AIF1DRC1_QR */ +#define WM8994_AIF1DRC1_QR_WIDTH 1 /* AIF1DRC1_QR */ +#define WM8994_AIF1DRC1_ANTICLIP 0x0008 /* AIF1DRC1_ANTICLIP */ +#define WM8994_AIF1DRC1_ANTICLIP_MASK 0x0008 /* AIF1DRC1_ANTICLIP */ +#define WM8994_AIF1DRC1_ANTICLIP_SHIFT 3 /* AIF1DRC1_ANTICLIP */ +#define WM8994_AIF1DRC1_ANTICLIP_WIDTH 1 /* AIF1DRC1_ANTICLIP */ +#define WM8994_AIF1DAC1_DRC_ENA 0x0004 /* AIF1DAC1_DRC_ENA */ +#define WM8994_AIF1DAC1_DRC_ENA_MASK 0x0004 /* AIF1DAC1_DRC_ENA */ +#define WM8994_AIF1DAC1_DRC_ENA_SHIFT 2 /* AIF1DAC1_DRC_ENA */ +#define WM8994_AIF1DAC1_DRC_ENA_WIDTH 1 /* AIF1DAC1_DRC_ENA */ +#define WM8994_AIF1ADC1L_DRC_ENA 0x0002 /* AIF1ADC1L_DRC_ENA */ +#define WM8994_AIF1ADC1L_DRC_ENA_MASK 0x0002 /* AIF1ADC1L_DRC_ENA */ +#define WM8994_AIF1ADC1L_DRC_ENA_SHIFT 1 /* AIF1ADC1L_DRC_ENA */ +#define WM8994_AIF1ADC1L_DRC_ENA_WIDTH 1 /* AIF1ADC1L_DRC_ENA */ +#define WM8994_AIF1ADC1R_DRC_ENA 0x0001 /* AIF1ADC1R_DRC_ENA */ +#define WM8994_AIF1ADC1R_DRC_ENA_MASK 0x0001 /* AIF1ADC1R_DRC_ENA */ +#define WM8994_AIF1ADC1R_DRC_ENA_SHIFT 0 /* AIF1ADC1R_DRC_ENA */ +#define WM8994_AIF1ADC1R_DRC_ENA_WIDTH 1 /* AIF1ADC1R_DRC_ENA */ + +/* + * R1089 (0x441) - AIF1 DRC1 (2) + */ +#define WM8994_AIF1DRC1_ATK_MASK 0x1E00 /* AIF1DRC1_ATK - [12:9] */ +#define WM8994_AIF1DRC1_ATK_SHIFT 9 /* AIF1DRC1_ATK - [12:9] */ +#define WM8994_AIF1DRC1_ATK_WIDTH 4 /* AIF1DRC1_ATK - [12:9] */ +#define WM8994_AIF1DRC1_DCY_MASK 0x01E0 /* AIF1DRC1_DCY - [8:5] */ +#define WM8994_AIF1DRC1_DCY_SHIFT 5 /* AIF1DRC1_DCY - [8:5] */ +#define WM8994_AIF1DRC1_DCY_WIDTH 4 /* AIF1DRC1_DCY - [8:5] */ +#define WM8994_AIF1DRC1_MINGAIN_MASK 0x001C /* AIF1DRC1_MINGAIN - [4:2] */ +#define WM8994_AIF1DRC1_MINGAIN_SHIFT 2 /* AIF1DRC1_MINGAIN - [4:2] */ +#define WM8994_AIF1DRC1_MINGAIN_WIDTH 3 /* AIF1DRC1_MINGAIN - [4:2] */ +#define WM8994_AIF1DRC1_MAXGAIN_MASK 0x0003 /* AIF1DRC1_MAXGAIN - [1:0] */ +#define WM8994_AIF1DRC1_MAXGAIN_SHIFT 0 /* AIF1DRC1_MAXGAIN - [1:0] */ +#define WM8994_AIF1DRC1_MAXGAIN_WIDTH 2 /* AIF1DRC1_MAXGAIN - [1:0] */ + +/* + * R1090 (0x442) - AIF1 DRC1 (3) + */ +#define WM8994_AIF1DRC1_NG_MINGAIN_MASK 0xF000 /* AIF1DRC1_NG_MINGAIN - [15:12] */ +#define WM8994_AIF1DRC1_NG_MINGAIN_SHIFT 12 /* AIF1DRC1_NG_MINGAIN - [15:12] */ +#define WM8994_AIF1DRC1_NG_MINGAIN_WIDTH 4 /* AIF1DRC1_NG_MINGAIN - [15:12] */ +#define WM8994_AIF1DRC1_NG_EXP_MASK 0x0C00 /* AIF1DRC1_NG_EXP - [11:10] */ +#define WM8994_AIF1DRC1_NG_EXP_SHIFT 10 /* AIF1DRC1_NG_EXP - [11:10] */ +#define WM8994_AIF1DRC1_NG_EXP_WIDTH 2 /* AIF1DRC1_NG_EXP - [11:10] */ +#define WM8994_AIF1DRC1_QR_THR_MASK 0x0300 /* AIF1DRC1_QR_THR - [9:8] */ +#define WM8994_AIF1DRC1_QR_THR_SHIFT 8 /* AIF1DRC1_QR_THR - [9:8] */ +#define WM8994_AIF1DRC1_QR_THR_WIDTH 2 /* AIF1DRC1_QR_THR - [9:8] */ +#define WM8994_AIF1DRC1_QR_DCY_MASK 0x00C0 /* AIF1DRC1_QR_DCY - [7:6] */ +#define WM8994_AIF1DRC1_QR_DCY_SHIFT 6 /* AIF1DRC1_QR_DCY - [7:6] */ +#define WM8994_AIF1DRC1_QR_DCY_WIDTH 2 /* AIF1DRC1_QR_DCY - [7:6] */ +#define WM8994_AIF1DRC1_HI_COMP_MASK 0x0038 /* AIF1DRC1_HI_COMP - [5:3] */ +#define WM8994_AIF1DRC1_HI_COMP_SHIFT 3 /* AIF1DRC1_HI_COMP - [5:3] */ +#define WM8994_AIF1DRC1_HI_COMP_WIDTH 3 /* AIF1DRC1_HI_COMP - [5:3] */ +#define WM8994_AIF1DRC1_LO_COMP_MASK 0x0007 /* AIF1DRC1_LO_COMP - [2:0] */ +#define WM8994_AIF1DRC1_LO_COMP_SHIFT 0 /* AIF1DRC1_LO_COMP - [2:0] */ +#define WM8994_AIF1DRC1_LO_COMP_WIDTH 3 /* AIF1DRC1_LO_COMP - [2:0] */ + +/* + * R1091 (0x443) - AIF1 DRC1 (4) + */ +#define WM8994_AIF1DRC1_KNEE_IP_MASK 0x07E0 /* AIF1DRC1_KNEE_IP - [10:5] */ +#define WM8994_AIF1DRC1_KNEE_IP_SHIFT 5 /* AIF1DRC1_KNEE_IP - [10:5] */ +#define WM8994_AIF1DRC1_KNEE_IP_WIDTH 6 /* AIF1DRC1_KNEE_IP - [10:5] */ +#define WM8994_AIF1DRC1_KNEE_OP_MASK 0x001F /* AIF1DRC1_KNEE_OP - [4:0] */ +#define WM8994_AIF1DRC1_KNEE_OP_SHIFT 0 /* AIF1DRC1_KNEE_OP - [4:0] */ +#define WM8994_AIF1DRC1_KNEE_OP_WIDTH 5 /* AIF1DRC1_KNEE_OP - [4:0] */ + +/* + * R1092 (0x444) - AIF1 DRC1 (5) + */ +#define WM8994_AIF1DRC1_KNEE2_IP_MASK 0x03E0 /* AIF1DRC1_KNEE2_IP - [9:5] */ +#define WM8994_AIF1DRC1_KNEE2_IP_SHIFT 5 /* AIF1DRC1_KNEE2_IP - [9:5] */ +#define WM8994_AIF1DRC1_KNEE2_IP_WIDTH 5 /* AIF1DRC1_KNEE2_IP - [9:5] */ +#define WM8994_AIF1DRC1_KNEE2_OP_MASK 0x001F /* AIF1DRC1_KNEE2_OP - [4:0] */ +#define WM8994_AIF1DRC1_KNEE2_OP_SHIFT 0 /* AIF1DRC1_KNEE2_OP - [4:0] */ +#define WM8994_AIF1DRC1_KNEE2_OP_WIDTH 5 /* AIF1DRC1_KNEE2_OP - [4:0] */ + +/* + * R1104 (0x450) - AIF1 DRC2 (1) + */ +#define WM8994_AIF1DRC2_SIG_DET_RMS_MASK 0xF800 /* AIF1DRC2_SIG_DET_RMS - [15:11] */ +#define WM8994_AIF1DRC2_SIG_DET_RMS_SHIFT 11 /* AIF1DRC2_SIG_DET_RMS - [15:11] */ +#define WM8994_AIF1DRC2_SIG_DET_RMS_WIDTH 5 /* AIF1DRC2_SIG_DET_RMS - [15:11] */ +#define WM8994_AIF1DRC2_SIG_DET_PK_MASK 0x0600 /* AIF1DRC2_SIG_DET_PK - [10:9] */ +#define WM8994_AIF1DRC2_SIG_DET_PK_SHIFT 9 /* AIF1DRC2_SIG_DET_PK - [10:9] */ +#define WM8994_AIF1DRC2_SIG_DET_PK_WIDTH 2 /* AIF1DRC2_SIG_DET_PK - [10:9] */ +#define WM8994_AIF1DRC2_NG_ENA 0x0100 /* AIF1DRC2_NG_ENA */ +#define WM8994_AIF1DRC2_NG_ENA_MASK 0x0100 /* AIF1DRC2_NG_ENA */ +#define WM8994_AIF1DRC2_NG_ENA_SHIFT 8 /* AIF1DRC2_NG_ENA */ +#define WM8994_AIF1DRC2_NG_ENA_WIDTH 1 /* AIF1DRC2_NG_ENA */ +#define WM8994_AIF1DRC2_SIG_DET_MODE 0x0080 /* AIF1DRC2_SIG_DET_MODE */ +#define WM8994_AIF1DRC2_SIG_DET_MODE_MASK 0x0080 /* AIF1DRC2_SIG_DET_MODE */ +#define WM8994_AIF1DRC2_SIG_DET_MODE_SHIFT 7 /* AIF1DRC2_SIG_DET_MODE */ +#define WM8994_AIF1DRC2_SIG_DET_MODE_WIDTH 1 /* AIF1DRC2_SIG_DET_MODE */ +#define WM8994_AIF1DRC2_SIG_DET 0x0040 /* AIF1DRC2_SIG_DET */ +#define WM8994_AIF1DRC2_SIG_DET_MASK 0x0040 /* AIF1DRC2_SIG_DET */ +#define WM8994_AIF1DRC2_SIG_DET_SHIFT 6 /* AIF1DRC2_SIG_DET */ +#define WM8994_AIF1DRC2_SIG_DET_WIDTH 1 /* AIF1DRC2_SIG_DET */ +#define WM8994_AIF1DRC2_KNEE2_OP_ENA 0x0020 /* AIF1DRC2_KNEE2_OP_ENA */ +#define WM8994_AIF1DRC2_KNEE2_OP_ENA_MASK 0x0020 /* AIF1DRC2_KNEE2_OP_ENA */ +#define WM8994_AIF1DRC2_KNEE2_OP_ENA_SHIFT 5 /* AIF1DRC2_KNEE2_OP_ENA */ +#define WM8994_AIF1DRC2_KNEE2_OP_ENA_WIDTH 1 /* AIF1DRC2_KNEE2_OP_ENA */ +#define WM8994_AIF1DRC2_QR 0x0010 /* AIF1DRC2_QR */ +#define WM8994_AIF1DRC2_QR_MASK 0x0010 /* AIF1DRC2_QR */ +#define WM8994_AIF1DRC2_QR_SHIFT 4 /* AIF1DRC2_QR */ +#define WM8994_AIF1DRC2_QR_WIDTH 1 /* AIF1DRC2_QR */ +#define WM8994_AIF1DRC2_ANTICLIP 0x0008 /* AIF1DRC2_ANTICLIP */ +#define WM8994_AIF1DRC2_ANTICLIP_MASK 0x0008 /* AIF1DRC2_ANTICLIP */ +#define WM8994_AIF1DRC2_ANTICLIP_SHIFT 3 /* AIF1DRC2_ANTICLIP */ +#define WM8994_AIF1DRC2_ANTICLIP_WIDTH 1 /* AIF1DRC2_ANTICLIP */ +#define WM8994_AIF1DAC2_DRC_ENA 0x0004 /* AIF1DAC2_DRC_ENA */ +#define WM8994_AIF1DAC2_DRC_ENA_MASK 0x0004 /* AIF1DAC2_DRC_ENA */ +#define WM8994_AIF1DAC2_DRC_ENA_SHIFT 2 /* AIF1DAC2_DRC_ENA */ +#define WM8994_AIF1DAC2_DRC_ENA_WIDTH 1 /* AIF1DAC2_DRC_ENA */ +#define WM8994_AIF1ADC2L_DRC_ENA 0x0002 /* AIF1ADC2L_DRC_ENA */ +#define WM8994_AIF1ADC2L_DRC_ENA_MASK 0x0002 /* AIF1ADC2L_DRC_ENA */ +#define WM8994_AIF1ADC2L_DRC_ENA_SHIFT 1 /* AIF1ADC2L_DRC_ENA */ +#define WM8994_AIF1ADC2L_DRC_ENA_WIDTH 1 /* AIF1ADC2L_DRC_ENA */ +#define WM8994_AIF1ADC2R_DRC_ENA 0x0001 /* AIF1ADC2R_DRC_ENA */ +#define WM8994_AIF1ADC2R_DRC_ENA_MASK 0x0001 /* AIF1ADC2R_DRC_ENA */ +#define WM8994_AIF1ADC2R_DRC_ENA_SHIFT 0 /* AIF1ADC2R_DRC_ENA */ +#define WM8994_AIF1ADC2R_DRC_ENA_WIDTH 1 /* AIF1ADC2R_DRC_ENA */ + +/* + * R1105 (0x451) - AIF1 DRC2 (2) + */ +#define WM8994_AIF1DRC2_ATK_MASK 0x1E00 /* AIF1DRC2_ATK - [12:9] */ +#define WM8994_AIF1DRC2_ATK_SHIFT 9 /* AIF1DRC2_ATK - [12:9] */ +#define WM8994_AIF1DRC2_ATK_WIDTH 4 /* AIF1DRC2_ATK - [12:9] */ +#define WM8994_AIF1DRC2_DCY_MASK 0x01E0 /* AIF1DRC2_DCY - [8:5] */ +#define WM8994_AIF1DRC2_DCY_SHIFT 5 /* AIF1DRC2_DCY - [8:5] */ +#define WM8994_AIF1DRC2_DCY_WIDTH 4 /* AIF1DRC2_DCY - [8:5] */ +#define WM8994_AIF1DRC2_MINGAIN_MASK 0x001C /* AIF1DRC2_MINGAIN - [4:2] */ +#define WM8994_AIF1DRC2_MINGAIN_SHIFT 2 /* AIF1DRC2_MINGAIN - [4:2] */ +#define WM8994_AIF1DRC2_MINGAIN_WIDTH 3 /* AIF1DRC2_MINGAIN - [4:2] */ +#define WM8994_AIF1DRC2_MAXGAIN_MASK 0x0003 /* AIF1DRC2_MAXGAIN - [1:0] */ +#define WM8994_AIF1DRC2_MAXGAIN_SHIFT 0 /* AIF1DRC2_MAXGAIN - [1:0] */ +#define WM8994_AIF1DRC2_MAXGAIN_WIDTH 2 /* AIF1DRC2_MAXGAIN - [1:0] */ + +/* + * R1106 (0x452) - AIF1 DRC2 (3) + */ +#define WM8994_AIF1DRC2_NG_MINGAIN_MASK 0xF000 /* AIF1DRC2_NG_MINGAIN - [15:12] */ +#define WM8994_AIF1DRC2_NG_MINGAIN_SHIFT 12 /* AIF1DRC2_NG_MINGAIN - [15:12] */ +#define WM8994_AIF1DRC2_NG_MINGAIN_WIDTH 4 /* AIF1DRC2_NG_MINGAIN - [15:12] */ +#define WM8994_AIF1DRC2_NG_EXP_MASK 0x0C00 /* AIF1DRC2_NG_EXP - [11:10] */ +#define WM8994_AIF1DRC2_NG_EXP_SHIFT 10 /* AIF1DRC2_NG_EXP - [11:10] */ +#define WM8994_AIF1DRC2_NG_EXP_WIDTH 2 /* AIF1DRC2_NG_EXP - [11:10] */ +#define WM8994_AIF1DRC2_QR_THR_MASK 0x0300 /* AIF1DRC2_QR_THR - [9:8] */ +#define WM8994_AIF1DRC2_QR_THR_SHIFT 8 /* AIF1DRC2_QR_THR - [9:8] */ +#define WM8994_AIF1DRC2_QR_THR_WIDTH 2 /* AIF1DRC2_QR_THR - [9:8] */ +#define WM8994_AIF1DRC2_QR_DCY_MASK 0x00C0 /* AIF1DRC2_QR_DCY - [7:6] */ +#define WM8994_AIF1DRC2_QR_DCY_SHIFT 6 /* AIF1DRC2_QR_DCY - [7:6] */ +#define WM8994_AIF1DRC2_QR_DCY_WIDTH 2 /* AIF1DRC2_QR_DCY - [7:6] */ +#define WM8994_AIF1DRC2_HI_COMP_MASK 0x0038 /* AIF1DRC2_HI_COMP - [5:3] */ +#define WM8994_AIF1DRC2_HI_COMP_SHIFT 3 /* AIF1DRC2_HI_COMP - [5:3] */ +#define WM8994_AIF1DRC2_HI_COMP_WIDTH 3 /* AIF1DRC2_HI_COMP - [5:3] */ +#define WM8994_AIF1DRC2_LO_COMP_MASK 0x0007 /* AIF1DRC2_LO_COMP - [2:0] */ +#define WM8994_AIF1DRC2_LO_COMP_SHIFT 0 /* AIF1DRC2_LO_COMP - [2:0] */ +#define WM8994_AIF1DRC2_LO_COMP_WIDTH 3 /* AIF1DRC2_LO_COMP - [2:0] */ + +/* + * R1107 (0x453) - AIF1 DRC2 (4) + */ +#define WM8994_AIF1DRC2_KNEE_IP_MASK 0x07E0 /* AIF1DRC2_KNEE_IP - [10:5] */ +#define WM8994_AIF1DRC2_KNEE_IP_SHIFT 5 /* AIF1DRC2_KNEE_IP - [10:5] */ +#define WM8994_AIF1DRC2_KNEE_IP_WIDTH 6 /* AIF1DRC2_KNEE_IP - [10:5] */ +#define WM8994_AIF1DRC2_KNEE_OP_MASK 0x001F /* AIF1DRC2_KNEE_OP - [4:0] */ +#define WM8994_AIF1DRC2_KNEE_OP_SHIFT 0 /* AIF1DRC2_KNEE_OP - [4:0] */ +#define WM8994_AIF1DRC2_KNEE_OP_WIDTH 5 /* AIF1DRC2_KNEE_OP - [4:0] */ + +/* + * R1108 (0x454) - AIF1 DRC2 (5) + */ +#define WM8994_AIF1DRC2_KNEE2_IP_MASK 0x03E0 /* AIF1DRC2_KNEE2_IP - [9:5] */ +#define WM8994_AIF1DRC2_KNEE2_IP_SHIFT 5 /* AIF1DRC2_KNEE2_IP - [9:5] */ +#define WM8994_AIF1DRC2_KNEE2_IP_WIDTH 5 /* AIF1DRC2_KNEE2_IP - [9:5] */ +#define WM8994_AIF1DRC2_KNEE2_OP_MASK 0x001F /* AIF1DRC2_KNEE2_OP - [4:0] */ +#define WM8994_AIF1DRC2_KNEE2_OP_SHIFT 0 /* AIF1DRC2_KNEE2_OP - [4:0] */ +#define WM8994_AIF1DRC2_KNEE2_OP_WIDTH 5 /* AIF1DRC2_KNEE2_OP - [4:0] */ + +/* + * R1152 (0x480) - AIF1 DAC1 EQ Gains (1) + */ +#define WM8994_AIF1DAC1_EQ_B1_GAIN_MASK 0xF800 /* AIF1DAC1_EQ_B1_GAIN - [15:11] */ +#define WM8994_AIF1DAC1_EQ_B1_GAIN_SHIFT 11 /* AIF1DAC1_EQ_B1_GAIN - [15:11] */ +#define WM8994_AIF1DAC1_EQ_B1_GAIN_WIDTH 5 /* AIF1DAC1_EQ_B1_GAIN - [15:11] */ +#define WM8994_AIF1DAC1_EQ_B2_GAIN_MASK 0x07C0 /* AIF1DAC1_EQ_B2_GAIN - [10:6] */ +#define WM8994_AIF1DAC1_EQ_B2_GAIN_SHIFT 6 /* AIF1DAC1_EQ_B2_GAIN - [10:6] */ +#define WM8994_AIF1DAC1_EQ_B2_GAIN_WIDTH 5 /* AIF1DAC1_EQ_B2_GAIN - [10:6] */ +#define WM8994_AIF1DAC1_EQ_B3_GAIN_MASK 0x003E /* AIF1DAC1_EQ_B3_GAIN - [5:1] */ +#define WM8994_AIF1DAC1_EQ_B3_GAIN_SHIFT 1 /* AIF1DAC1_EQ_B3_GAIN - [5:1] */ +#define WM8994_AIF1DAC1_EQ_B3_GAIN_WIDTH 5 /* AIF1DAC1_EQ_B3_GAIN - [5:1] */ +#define WM8994_AIF1DAC1_EQ_ENA 0x0001 /* AIF1DAC1_EQ_ENA */ +#define WM8994_AIF1DAC1_EQ_ENA_MASK 0x0001 /* AIF1DAC1_EQ_ENA */ +#define WM8994_AIF1DAC1_EQ_ENA_SHIFT 0 /* AIF1DAC1_EQ_ENA */ +#define WM8994_AIF1DAC1_EQ_ENA_WIDTH 1 /* AIF1DAC1_EQ_ENA */ + +/* + * R1153 (0x481) - AIF1 DAC1 EQ Gains (2) + */ +#define WM8994_AIF1DAC1_EQ_B4_GAIN_MASK 0xF800 /* AIF1DAC1_EQ_B4_GAIN - [15:11] */ +#define WM8994_AIF1DAC1_EQ_B4_GAIN_SHIFT 11 /* AIF1DAC1_EQ_B4_GAIN - [15:11] */ +#define WM8994_AIF1DAC1_EQ_B4_GAIN_WIDTH 5 /* AIF1DAC1_EQ_B4_GAIN - [15:11] */ +#define WM8994_AIF1DAC1_EQ_B5_GAIN_MASK 0x07C0 /* AIF1DAC1_EQ_B5_GAIN - [10:6] */ +#define WM8994_AIF1DAC1_EQ_B5_GAIN_SHIFT 6 /* AIF1DAC1_EQ_B5_GAIN - [10:6] */ +#define WM8994_AIF1DAC1_EQ_B5_GAIN_WIDTH 5 /* AIF1DAC1_EQ_B5_GAIN - [10:6] */ + +/* + * R1154 (0x482) - AIF1 DAC1 EQ Band 1 A + */ +#define WM8994_AIF1DAC1_EQ_B1_A_MASK 0xFFFF /* AIF1DAC1_EQ_B1_A - [15:0] */ +#define WM8994_AIF1DAC1_EQ_B1_A_SHIFT 0 /* AIF1DAC1_EQ_B1_A - [15:0] */ +#define WM8994_AIF1DAC1_EQ_B1_A_WIDTH 16 /* AIF1DAC1_EQ_B1_A - [15:0] */ + +/* + * R1155 (0x483) - AIF1 DAC1 EQ Band 1 B + */ +#define WM8994_AIF1DAC1_EQ_B1_B_MASK 0xFFFF /* AIF1DAC1_EQ_B1_B - [15:0] */ +#define WM8994_AIF1DAC1_EQ_B1_B_SHIFT 0 /* AIF1DAC1_EQ_B1_B - [15:0] */ +#define WM8994_AIF1DAC1_EQ_B1_B_WIDTH 16 /* AIF1DAC1_EQ_B1_B - [15:0] */ + +/* + * R1156 (0x484) - AIF1 DAC1 EQ Band 1 PG + */ +#define WM8994_AIF1DAC1_EQ_B1_PG_MASK 0xFFFF /* AIF1DAC1_EQ_B1_PG - [15:0] */ +#define WM8994_AIF1DAC1_EQ_B1_PG_SHIFT 0 /* AIF1DAC1_EQ_B1_PG - [15:0] */ +#define WM8994_AIF1DAC1_EQ_B1_PG_WIDTH 16 /* AIF1DAC1_EQ_B1_PG - [15:0] */ + +/* + * R1157 (0x485) - AIF1 DAC1 EQ Band 2 A + */ +#define WM8994_AIF1DAC1_EQ_B2_A_MASK 0xFFFF /* AIF1DAC1_EQ_B2_A - [15:0] */ +#define WM8994_AIF1DAC1_EQ_B2_A_SHIFT 0 /* AIF1DAC1_EQ_B2_A - [15:0] */ +#define WM8994_AIF1DAC1_EQ_B2_A_WIDTH 16 /* AIF1DAC1_EQ_B2_A - [15:0] */ + +/* + * R1158 (0x486) - AIF1 DAC1 EQ Band 2 B + */ +#define WM8994_AIF1DAC1_EQ_B2_B_MASK 0xFFFF /* AIF1DAC1_EQ_B2_B - [15:0] */ +#define WM8994_AIF1DAC1_EQ_B2_B_SHIFT 0 /* AIF1DAC1_EQ_B2_B - [15:0] */ +#define WM8994_AIF1DAC1_EQ_B2_B_WIDTH 16 /* AIF1DAC1_EQ_B2_B - [15:0] */ + +/* + * R1159 (0x487) - AIF1 DAC1 EQ Band 2 C + */ +#define WM8994_AIF1DAC1_EQ_B2_C_MASK 0xFFFF /* AIF1DAC1_EQ_B2_C - [15:0] */ +#define WM8994_AIF1DAC1_EQ_B2_C_SHIFT 0 /* AIF1DAC1_EQ_B2_C - [15:0] */ +#define WM8994_AIF1DAC1_EQ_B2_C_WIDTH 16 /* AIF1DAC1_EQ_B2_C - [15:0] */ + +/* + * R1160 (0x488) - AIF1 DAC1 EQ Band 2 PG + */ +#define WM8994_AIF1DAC1_EQ_B2_PG_MASK 0xFFFF /* AIF1DAC1_EQ_B2_PG - [15:0] */ +#define WM8994_AIF1DAC1_EQ_B2_PG_SHIFT 0 /* AIF1DAC1_EQ_B2_PG - [15:0] */ +#define WM8994_AIF1DAC1_EQ_B2_PG_WIDTH 16 /* AIF1DAC1_EQ_B2_PG - [15:0] */ + +/* + * R1161 (0x489) - AIF1 DAC1 EQ Band 3 A + */ +#define WM8994_AIF1DAC1_EQ_B3_A_MASK 0xFFFF /* AIF1DAC1_EQ_B3_A - [15:0] */ +#define WM8994_AIF1DAC1_EQ_B3_A_SHIFT 0 /* AIF1DAC1_EQ_B3_A - [15:0] */ +#define WM8994_AIF1DAC1_EQ_B3_A_WIDTH 16 /* AIF1DAC1_EQ_B3_A - [15:0] */ + +/* + * R1162 (0x48A) - AIF1 DAC1 EQ Band 3 B + */ +#define WM8994_AIF1DAC1_EQ_B3_B_MASK 0xFFFF /* AIF1DAC1_EQ_B3_B - [15:0] */ +#define WM8994_AIF1DAC1_EQ_B3_B_SHIFT 0 /* AIF1DAC1_EQ_B3_B - [15:0] */ +#define WM8994_AIF1DAC1_EQ_B3_B_WIDTH 16 /* AIF1DAC1_EQ_B3_B - [15:0] */ + +/* + * R1163 (0x48B) - AIF1 DAC1 EQ Band 3 C + */ +#define WM8994_AIF1DAC1_EQ_B3_C_MASK 0xFFFF /* AIF1DAC1_EQ_B3_C - [15:0] */ +#define WM8994_AIF1DAC1_EQ_B3_C_SHIFT 0 /* AIF1DAC1_EQ_B3_C - [15:0] */ +#define WM8994_AIF1DAC1_EQ_B3_C_WIDTH 16 /* AIF1DAC1_EQ_B3_C - [15:0] */ + +/* + * R1164 (0x48C) - AIF1 DAC1 EQ Band 3 PG + */ +#define WM8994_AIF1DAC1_EQ_B3_PG_MASK 0xFFFF /* AIF1DAC1_EQ_B3_PG - [15:0] */ +#define WM8994_AIF1DAC1_EQ_B3_PG_SHIFT 0 /* AIF1DAC1_EQ_B3_PG - [15:0] */ +#define WM8994_AIF1DAC1_EQ_B3_PG_WIDTH 16 /* AIF1DAC1_EQ_B3_PG - [15:0] */ + +/* + * R1165 (0x48D) - AIF1 DAC1 EQ Band 4 A + */ +#define WM8994_AIF1DAC1_EQ_B4_A_MASK 0xFFFF /* AIF1DAC1_EQ_B4_A - [15:0] */ +#define WM8994_AIF1DAC1_EQ_B4_A_SHIFT 0 /* AIF1DAC1_EQ_B4_A - [15:0] */ +#define WM8994_AIF1DAC1_EQ_B4_A_WIDTH 16 /* AIF1DAC1_EQ_B4_A - [15:0] */ + +/* + * R1166 (0x48E) - AIF1 DAC1 EQ Band 4 B + */ +#define WM8994_AIF1DAC1_EQ_B4_B_MASK 0xFFFF /* AIF1DAC1_EQ_B4_B - [15:0] */ +#define WM8994_AIF1DAC1_EQ_B4_B_SHIFT 0 /* AIF1DAC1_EQ_B4_B - [15:0] */ +#define WM8994_AIF1DAC1_EQ_B4_B_WIDTH 16 /* AIF1DAC1_EQ_B4_B - [15:0] */ + +/* + * R1167 (0x48F) - AIF1 DAC1 EQ Band 4 C + */ +#define WM8994_AIF1DAC1_EQ_B4_C_MASK 0xFFFF /* AIF1DAC1_EQ_B4_C - [15:0] */ +#define WM8994_AIF1DAC1_EQ_B4_C_SHIFT 0 /* AIF1DAC1_EQ_B4_C - [15:0] */ +#define WM8994_AIF1DAC1_EQ_B4_C_WIDTH 16 /* AIF1DAC1_EQ_B4_C - [15:0] */ + +/* + * R1168 (0x490) - AIF1 DAC1 EQ Band 4 PG + */ +#define WM8994_AIF1DAC1_EQ_B4_PG_MASK 0xFFFF /* AIF1DAC1_EQ_B4_PG - [15:0] */ +#define WM8994_AIF1DAC1_EQ_B4_PG_SHIFT 0 /* AIF1DAC1_EQ_B4_PG - [15:0] */ +#define WM8994_AIF1DAC1_EQ_B4_PG_WIDTH 16 /* AIF1DAC1_EQ_B4_PG - [15:0] */ + +/* + * R1169 (0x491) - AIF1 DAC1 EQ Band 5 A + */ +#define WM8994_AIF1DAC1_EQ_B5_A_MASK 0xFFFF /* AIF1DAC1_EQ_B5_A - [15:0] */ +#define WM8994_AIF1DAC1_EQ_B5_A_SHIFT 0 /* AIF1DAC1_EQ_B5_A - [15:0] */ +#define WM8994_AIF1DAC1_EQ_B5_A_WIDTH 16 /* AIF1DAC1_EQ_B5_A - [15:0] */ + +/* + * R1170 (0x492) - AIF1 DAC1 EQ Band 5 B + */ +#define WM8994_AIF1DAC1_EQ_B5_B_MASK 0xFFFF /* AIF1DAC1_EQ_B5_B - [15:0] */ +#define WM8994_AIF1DAC1_EQ_B5_B_SHIFT 0 /* AIF1DAC1_EQ_B5_B - [15:0] */ +#define WM8994_AIF1DAC1_EQ_B5_B_WIDTH 16 /* AIF1DAC1_EQ_B5_B - [15:0] */ + +/* + * R1171 (0x493) - AIF1 DAC1 EQ Band 5 PG + */ +#define WM8994_AIF1DAC1_EQ_B5_PG_MASK 0xFFFF /* AIF1DAC1_EQ_B5_PG - [15:0] */ +#define WM8994_AIF1DAC1_EQ_B5_PG_SHIFT 0 /* AIF1DAC1_EQ_B5_PG - [15:0] */ +#define WM8994_AIF1DAC1_EQ_B5_PG_WIDTH 16 /* AIF1DAC1_EQ_B5_PG - [15:0] */ + +/* + * R1184 (0x4A0) - AIF1 DAC2 EQ Gains (1) + */ +#define WM8994_AIF1DAC2_EQ_B1_GAIN_MASK 0xF800 /* AIF1DAC2_EQ_B1_GAIN - [15:11] */ +#define WM8994_AIF1DAC2_EQ_B1_GAIN_SHIFT 11 /* AIF1DAC2_EQ_B1_GAIN - [15:11] */ +#define WM8994_AIF1DAC2_EQ_B1_GAIN_WIDTH 5 /* AIF1DAC2_EQ_B1_GAIN - [15:11] */ +#define WM8994_AIF1DAC2_EQ_B2_GAIN_MASK 0x07C0 /* AIF1DAC2_EQ_B2_GAIN - [10:6] */ +#define WM8994_AIF1DAC2_EQ_B2_GAIN_SHIFT 6 /* AIF1DAC2_EQ_B2_GAIN - [10:6] */ +#define WM8994_AIF1DAC2_EQ_B2_GAIN_WIDTH 5 /* AIF1DAC2_EQ_B2_GAIN - [10:6] */ +#define WM8994_AIF1DAC2_EQ_B3_GAIN_MASK 0x003E /* AIF1DAC2_EQ_B3_GAIN - [5:1] */ +#define WM8994_AIF1DAC2_EQ_B3_GAIN_SHIFT 1 /* AIF1DAC2_EQ_B3_GAIN - [5:1] */ +#define WM8994_AIF1DAC2_EQ_B3_GAIN_WIDTH 5 /* AIF1DAC2_EQ_B3_GAIN - [5:1] */ +#define WM8994_AIF1DAC2_EQ_ENA 0x0001 /* AIF1DAC2_EQ_ENA */ +#define WM8994_AIF1DAC2_EQ_ENA_MASK 0x0001 /* AIF1DAC2_EQ_ENA */ +#define WM8994_AIF1DAC2_EQ_ENA_SHIFT 0 /* AIF1DAC2_EQ_ENA */ +#define WM8994_AIF1DAC2_EQ_ENA_WIDTH 1 /* AIF1DAC2_EQ_ENA */ + +/* + * R1185 (0x4A1) - AIF1 DAC2 EQ Gains (2) + */ +#define WM8994_AIF1DAC2_EQ_B4_GAIN_MASK 0xF800 /* AIF1DAC2_EQ_B4_GAIN - [15:11] */ +#define WM8994_AIF1DAC2_EQ_B4_GAIN_SHIFT 11 /* AIF1DAC2_EQ_B4_GAIN - [15:11] */ +#define WM8994_AIF1DAC2_EQ_B4_GAIN_WIDTH 5 /* AIF1DAC2_EQ_B4_GAIN - [15:11] */ +#define WM8994_AIF1DAC2_EQ_B5_GAIN_MASK 0x07C0 /* AIF1DAC2_EQ_B5_GAIN - [10:6] */ +#define WM8994_AIF1DAC2_EQ_B5_GAIN_SHIFT 6 /* AIF1DAC2_EQ_B5_GAIN - [10:6] */ +#define WM8994_AIF1DAC2_EQ_B5_GAIN_WIDTH 5 /* AIF1DAC2_EQ_B5_GAIN - [10:6] */ + +/* + * R1186 (0x4A2) - AIF1 DAC2 EQ Band 1 A + */ +#define WM8994_AIF1DAC2_EQ_B1_A_MASK 0xFFFF /* AIF1DAC2_EQ_B1_A - [15:0] */ +#define WM8994_AIF1DAC2_EQ_B1_A_SHIFT 0 /* AIF1DAC2_EQ_B1_A - [15:0] */ +#define WM8994_AIF1DAC2_EQ_B1_A_WIDTH 16 /* AIF1DAC2_EQ_B1_A - [15:0] */ + +/* + * R1187 (0x4A3) - AIF1 DAC2 EQ Band 1 B + */ +#define WM8994_AIF1DAC2_EQ_B1_B_MASK 0xFFFF /* AIF1DAC2_EQ_B1_B - [15:0] */ +#define WM8994_AIF1DAC2_EQ_B1_B_SHIFT 0 /* AIF1DAC2_EQ_B1_B - [15:0] */ +#define WM8994_AIF1DAC2_EQ_B1_B_WIDTH 16 /* AIF1DAC2_EQ_B1_B - [15:0] */ + +/* + * R1188 (0x4A4) - AIF1 DAC2 EQ Band 1 PG + */ +#define WM8994_AIF1DAC2_EQ_B1_PG_MASK 0xFFFF /* AIF1DAC2_EQ_B1_PG - [15:0] */ +#define WM8994_AIF1DAC2_EQ_B1_PG_SHIFT 0 /* AIF1DAC2_EQ_B1_PG - [15:0] */ +#define WM8994_AIF1DAC2_EQ_B1_PG_WIDTH 16 /* AIF1DAC2_EQ_B1_PG - [15:0] */ + +/* + * R1189 (0x4A5) - AIF1 DAC2 EQ Band 2 A + */ +#define WM8994_AIF1DAC2_EQ_B2_A_MASK 0xFFFF /* AIF1DAC2_EQ_B2_A - [15:0] */ +#define WM8994_AIF1DAC2_EQ_B2_A_SHIFT 0 /* AIF1DAC2_EQ_B2_A - [15:0] */ +#define WM8994_AIF1DAC2_EQ_B2_A_WIDTH 16 /* AIF1DAC2_EQ_B2_A - [15:0] */ + +/* + * R1190 (0x4A6) - AIF1 DAC2 EQ Band 2 B + */ +#define WM8994_AIF1DAC2_EQ_B2_B_MASK 0xFFFF /* AIF1DAC2_EQ_B2_B - [15:0] */ +#define WM8994_AIF1DAC2_EQ_B2_B_SHIFT 0 /* AIF1DAC2_EQ_B2_B - [15:0] */ +#define WM8994_AIF1DAC2_EQ_B2_B_WIDTH 16 /* AIF1DAC2_EQ_B2_B - [15:0] */ + +/* + * R1191 (0x4A7) - AIF1 DAC2 EQ Band 2 C + */ +#define WM8994_AIF1DAC2_EQ_B2_C_MASK 0xFFFF /* AIF1DAC2_EQ_B2_C - [15:0] */ +#define WM8994_AIF1DAC2_EQ_B2_C_SHIFT 0 /* AIF1DAC2_EQ_B2_C - [15:0] */ +#define WM8994_AIF1DAC2_EQ_B2_C_WIDTH 16 /* AIF1DAC2_EQ_B2_C - [15:0] */ + +/* + * R1192 (0x4A8) - AIF1 DAC2 EQ Band 2 PG + */ +#define WM8994_AIF1DAC2_EQ_B2_PG_MASK 0xFFFF /* AIF1DAC2_EQ_B2_PG - [15:0] */ +#define WM8994_AIF1DAC2_EQ_B2_PG_SHIFT 0 /* AIF1DAC2_EQ_B2_PG - [15:0] */ +#define WM8994_AIF1DAC2_EQ_B2_PG_WIDTH 16 /* AIF1DAC2_EQ_B2_PG - [15:0] */ + +/* + * R1193 (0x4A9) - AIF1 DAC2 EQ Band 3 A + */ +#define WM8994_AIF1DAC2_EQ_B3_A_MASK 0xFFFF /* AIF1DAC2_EQ_B3_A - [15:0] */ +#define WM8994_AIF1DAC2_EQ_B3_A_SHIFT 0 /* AIF1DAC2_EQ_B3_A - [15:0] */ +#define WM8994_AIF1DAC2_EQ_B3_A_WIDTH 16 /* AIF1DAC2_EQ_B3_A - [15:0] */ + +/* + * R1194 (0x4AA) - AIF1 DAC2 EQ Band 3 B + */ +#define WM8994_AIF1DAC2_EQ_B3_B_MASK 0xFFFF /* AIF1DAC2_EQ_B3_B - [15:0] */ +#define WM8994_AIF1DAC2_EQ_B3_B_SHIFT 0 /* AIF1DAC2_EQ_B3_B - [15:0] */ +#define WM8994_AIF1DAC2_EQ_B3_B_WIDTH 16 /* AIF1DAC2_EQ_B3_B - [15:0] */ + +/* + * R1195 (0x4AB) - AIF1 DAC2 EQ Band 3 C + */ +#define WM8994_AIF1DAC2_EQ_B3_C_MASK 0xFFFF /* AIF1DAC2_EQ_B3_C - [15:0] */ +#define WM8994_AIF1DAC2_EQ_B3_C_SHIFT 0 /* AIF1DAC2_EQ_B3_C - [15:0] */ +#define WM8994_AIF1DAC2_EQ_B3_C_WIDTH 16 /* AIF1DAC2_EQ_B3_C - [15:0] */ + +/* + * R1196 (0x4AC) - AIF1 DAC2 EQ Band 3 PG + */ +#define WM8994_AIF1DAC2_EQ_B3_PG_MASK 0xFFFF /* AIF1DAC2_EQ_B3_PG - [15:0] */ +#define WM8994_AIF1DAC2_EQ_B3_PG_SHIFT 0 /* AIF1DAC2_EQ_B3_PG - [15:0] */ +#define WM8994_AIF1DAC2_EQ_B3_PG_WIDTH 16 /* AIF1DAC2_EQ_B3_PG - [15:0] */ + +/* + * R1197 (0x4AD) - AIF1 DAC2 EQ Band 4 A + */ +#define WM8994_AIF1DAC2_EQ_B4_A_MASK 0xFFFF /* AIF1DAC2_EQ_B4_A - [15:0] */ +#define WM8994_AIF1DAC2_EQ_B4_A_SHIFT 0 /* AIF1DAC2_EQ_B4_A - [15:0] */ +#define WM8994_AIF1DAC2_EQ_B4_A_WIDTH 16 /* AIF1DAC2_EQ_B4_A - [15:0] */ + +/* + * R1198 (0x4AE) - AIF1 DAC2 EQ Band 4 B + */ +#define WM8994_AIF1DAC2_EQ_B4_B_MASK 0xFFFF /* AIF1DAC2_EQ_B4_B - [15:0] */ +#define WM8994_AIF1DAC2_EQ_B4_B_SHIFT 0 /* AIF1DAC2_EQ_B4_B - [15:0] */ +#define WM8994_AIF1DAC2_EQ_B4_B_WIDTH 16 /* AIF1DAC2_EQ_B4_B - [15:0] */ + +/* + * R1199 (0x4AF) - AIF1 DAC2 EQ Band 4 C + */ +#define WM8994_AIF1DAC2_EQ_B4_C_MASK 0xFFFF /* AIF1DAC2_EQ_B4_C - [15:0] */ +#define WM8994_AIF1DAC2_EQ_B4_C_SHIFT 0 /* AIF1DAC2_EQ_B4_C - [15:0] */ +#define WM8994_AIF1DAC2_EQ_B4_C_WIDTH 16 /* AIF1DAC2_EQ_B4_C - [15:0] */ + +/* + * R1200 (0x4B0) - AIF1 DAC2 EQ Band 4 PG + */ +#define WM8994_AIF1DAC2_EQ_B4_PG_MASK 0xFFFF /* AIF1DAC2_EQ_B4_PG - [15:0] */ +#define WM8994_AIF1DAC2_EQ_B4_PG_SHIFT 0 /* AIF1DAC2_EQ_B4_PG - [15:0] */ +#define WM8994_AIF1DAC2_EQ_B4_PG_WIDTH 16 /* AIF1DAC2_EQ_B4_PG - [15:0] */ + +/* + * R1201 (0x4B1) - AIF1 DAC2 EQ Band 5 A + */ +#define WM8994_AIF1DAC2_EQ_B5_A_MASK 0xFFFF /* AIF1DAC2_EQ_B5_A - [15:0] */ +#define WM8994_AIF1DAC2_EQ_B5_A_SHIFT 0 /* AIF1DAC2_EQ_B5_A - [15:0] */ +#define WM8994_AIF1DAC2_EQ_B5_A_WIDTH 16 /* AIF1DAC2_EQ_B5_A - [15:0] */ + +/* + * R1202 (0x4B2) - AIF1 DAC2 EQ Band 5 B + */ +#define WM8994_AIF1DAC2_EQ_B5_B_MASK 0xFFFF /* AIF1DAC2_EQ_B5_B - [15:0] */ +#define WM8994_AIF1DAC2_EQ_B5_B_SHIFT 0 /* AIF1DAC2_EQ_B5_B - [15:0] */ +#define WM8994_AIF1DAC2_EQ_B5_B_WIDTH 16 /* AIF1DAC2_EQ_B5_B - [15:0] */ + +/* + * R1203 (0x4B3) - AIF1 DAC2 EQ Band 5 PG + */ +#define WM8994_AIF1DAC2_EQ_B5_PG_MASK 0xFFFF /* AIF1DAC2_EQ_B5_PG - [15:0] */ +#define WM8994_AIF1DAC2_EQ_B5_PG_SHIFT 0 /* AIF1DAC2_EQ_B5_PG - [15:0] */ +#define WM8994_AIF1DAC2_EQ_B5_PG_WIDTH 16 /* AIF1DAC2_EQ_B5_PG - [15:0] */ + +/* + * R1280 (0x500) - AIF2 ADC Left Volume + */ +#define WM8994_AIF2ADC_VU 0x0100 /* AIF2ADC_VU */ +#define WM8994_AIF2ADC_VU_MASK 0x0100 /* AIF2ADC_VU */ +#define WM8994_AIF2ADC_VU_SHIFT 8 /* AIF2ADC_VU */ +#define WM8994_AIF2ADC_VU_WIDTH 1 /* AIF2ADC_VU */ +#define WM8994_AIF2ADCL_VOL_MASK 0x00FF /* AIF2ADCL_VOL - [7:0] */ +#define WM8994_AIF2ADCL_VOL_SHIFT 0 /* AIF2ADCL_VOL - [7:0] */ +#define WM8994_AIF2ADCL_VOL_WIDTH 8 /* AIF2ADCL_VOL - [7:0] */ + +/* + * R1281 (0x501) - AIF2 ADC Right Volume + */ +#define WM8994_AIF2ADC_VU 0x0100 /* AIF2ADC_VU */ +#define WM8994_AIF2ADC_VU_MASK 0x0100 /* AIF2ADC_VU */ +#define WM8994_AIF2ADC_VU_SHIFT 8 /* AIF2ADC_VU */ +#define WM8994_AIF2ADC_VU_WIDTH 1 /* AIF2ADC_VU */ +#define WM8994_AIF2ADCR_VOL_MASK 0x00FF /* AIF2ADCR_VOL - [7:0] */ +#define WM8994_AIF2ADCR_VOL_SHIFT 0 /* AIF2ADCR_VOL - [7:0] */ +#define WM8994_AIF2ADCR_VOL_WIDTH 8 /* AIF2ADCR_VOL - [7:0] */ + +/* + * R1282 (0x502) - AIF2 DAC Left Volume + */ +#define WM8994_AIF2DAC_VU 0x0100 /* AIF2DAC_VU */ +#define WM8994_AIF2DAC_VU_MASK 0x0100 /* AIF2DAC_VU */ +#define WM8994_AIF2DAC_VU_SHIFT 8 /* AIF2DAC_VU */ +#define WM8994_AIF2DAC_VU_WIDTH 1 /* AIF2DAC_VU */ +#define WM8994_AIF2DACL_VOL_MASK 0x00FF /* AIF2DACL_VOL - [7:0] */ +#define WM8994_AIF2DACL_VOL_SHIFT 0 /* AIF2DACL_VOL - [7:0] */ +#define WM8994_AIF2DACL_VOL_WIDTH 8 /* AIF2DACL_VOL - [7:0] */ + +/* + * R1283 (0x503) - AIF2 DAC Right Volume + */ +#define WM8994_AIF2DAC_VU 0x0100 /* AIF2DAC_VU */ +#define WM8994_AIF2DAC_VU_MASK 0x0100 /* AIF2DAC_VU */ +#define WM8994_AIF2DAC_VU_SHIFT 8 /* AIF2DAC_VU */ +#define WM8994_AIF2DAC_VU_WIDTH 1 /* AIF2DAC_VU */ +#define WM8994_AIF2DACR_VOL_MASK 0x00FF /* AIF2DACR_VOL - [7:0] */ +#define WM8994_AIF2DACR_VOL_SHIFT 0 /* AIF2DACR_VOL - [7:0] */ +#define WM8994_AIF2DACR_VOL_WIDTH 8 /* AIF2DACR_VOL - [7:0] */ + +/* + * R1296 (0x510) - AIF2 ADC Filters + */ +#define WM8994_AIF2ADC_4FS 0x8000 /* AIF2ADC_4FS */ +#define WM8994_AIF2ADC_4FS_MASK 0x8000 /* AIF2ADC_4FS */ +#define WM8994_AIF2ADC_4FS_SHIFT 15 /* AIF2ADC_4FS */ +#define WM8994_AIF2ADC_4FS_WIDTH 1 /* AIF2ADC_4FS */ +#define WM8994_AIF2ADC_HPF_CUT_MASK 0x6000 /* AIF2ADC_HPF_CUT - [14:13] */ +#define WM8994_AIF2ADC_HPF_CUT_SHIFT 13 /* AIF2ADC_HPF_CUT - [14:13] */ +#define WM8994_AIF2ADC_HPF_CUT_WIDTH 2 /* AIF2ADC_HPF_CUT - [14:13] */ +#define WM8994_AIF2ADCL_HPF 0x1000 /* AIF2ADCL_HPF */ +#define WM8994_AIF2ADCL_HPF_MASK 0x1000 /* AIF2ADCL_HPF */ +#define WM8994_AIF2ADCL_HPF_SHIFT 12 /* AIF2ADCL_HPF */ +#define WM8994_AIF2ADCL_HPF_WIDTH 1 /* AIF2ADCL_HPF */ +#define WM8994_AIF2ADCR_HPF 0x0800 /* AIF2ADCR_HPF */ +#define WM8994_AIF2ADCR_HPF_MASK 0x0800 /* AIF2ADCR_HPF */ +#define WM8994_AIF2ADCR_HPF_SHIFT 11 /* AIF2ADCR_HPF */ +#define WM8994_AIF2ADCR_HPF_WIDTH 1 /* AIF2ADCR_HPF */ + +/* + * R1312 (0x520) - AIF2 DAC Filters (1) + */ +#define WM8994_AIF2DAC_MUTE 0x0200 /* AIF2DAC_MUTE */ +#define WM8994_AIF2DAC_MUTE_MASK 0x0200 /* AIF2DAC_MUTE */ +#define WM8994_AIF2DAC_MUTE_SHIFT 9 /* AIF2DAC_MUTE */ +#define WM8994_AIF2DAC_MUTE_WIDTH 1 /* AIF2DAC_MUTE */ +#define WM8994_AIF2DAC_MONO 0x0080 /* AIF2DAC_MONO */ +#define WM8994_AIF2DAC_MONO_MASK 0x0080 /* AIF2DAC_MONO */ +#define WM8994_AIF2DAC_MONO_SHIFT 7 /* AIF2DAC_MONO */ +#define WM8994_AIF2DAC_MONO_WIDTH 1 /* AIF2DAC_MONO */ +#define WM8994_AIF2DAC_MUTERATE 0x0020 /* AIF2DAC_MUTERATE */ +#define WM8994_AIF2DAC_MUTERATE_MASK 0x0020 /* AIF2DAC_MUTERATE */ +#define WM8994_AIF2DAC_MUTERATE_SHIFT 5 /* AIF2DAC_MUTERATE */ +#define WM8994_AIF2DAC_MUTERATE_WIDTH 1 /* AIF2DAC_MUTERATE */ +#define WM8994_AIF2DAC_UNMUTE_RAMP 0x0010 /* AIF2DAC_UNMUTE_RAMP */ +#define WM8994_AIF2DAC_UNMUTE_RAMP_MASK 0x0010 /* AIF2DAC_UNMUTE_RAMP */ +#define WM8994_AIF2DAC_UNMUTE_RAMP_SHIFT 4 /* AIF2DAC_UNMUTE_RAMP */ +#define WM8994_AIF2DAC_UNMUTE_RAMP_WIDTH 1 /* AIF2DAC_UNMUTE_RAMP */ +#define WM8994_AIF2DAC_DEEMP_MASK 0x0006 /* AIF2DAC_DEEMP - [2:1] */ +#define WM8994_AIF2DAC_DEEMP_SHIFT 1 /* AIF2DAC_DEEMP - [2:1] */ +#define WM8994_AIF2DAC_DEEMP_WIDTH 2 /* AIF2DAC_DEEMP - [2:1] */ + +/* + * R1313 (0x521) - AIF2 DAC Filters (2) + */ +#define WM8994_AIF2DAC_3D_GAIN_MASK 0x3E00 /* AIF2DAC_3D_GAIN - [13:9] */ +#define WM8994_AIF2DAC_3D_GAIN_SHIFT 9 /* AIF2DAC_3D_GAIN - [13:9] */ +#define WM8994_AIF2DAC_3D_GAIN_WIDTH 5 /* AIF2DAC_3D_GAIN - [13:9] */ +#define WM8994_AIF2DAC_3D_ENA 0x0100 /* AIF2DAC_3D_ENA */ +#define WM8994_AIF2DAC_3D_ENA_MASK 0x0100 /* AIF2DAC_3D_ENA */ +#define WM8994_AIF2DAC_3D_ENA_SHIFT 8 /* AIF2DAC_3D_ENA */ +#define WM8994_AIF2DAC_3D_ENA_WIDTH 1 /* AIF2DAC_3D_ENA */ + +/* + * R1344 (0x540) - AIF2 DRC (1) + */ +#define WM8994_AIF2DRC_SIG_DET_RMS_MASK 0xF800 /* AIF2DRC_SIG_DET_RMS - [15:11] */ +#define WM8994_AIF2DRC_SIG_DET_RMS_SHIFT 11 /* AIF2DRC_SIG_DET_RMS - [15:11] */ +#define WM8994_AIF2DRC_SIG_DET_RMS_WIDTH 5 /* AIF2DRC_SIG_DET_RMS - [15:11] */ +#define WM8994_AIF2DRC_SIG_DET_PK_MASK 0x0600 /* AIF2DRC_SIG_DET_PK - [10:9] */ +#define WM8994_AIF2DRC_SIG_DET_PK_SHIFT 9 /* AIF2DRC_SIG_DET_PK - [10:9] */ +#define WM8994_AIF2DRC_SIG_DET_PK_WIDTH 2 /* AIF2DRC_SIG_DET_PK - [10:9] */ +#define WM8994_AIF2DRC_NG_ENA 0x0100 /* AIF2DRC_NG_ENA */ +#define WM8994_AIF2DRC_NG_ENA_MASK 0x0100 /* AIF2DRC_NG_ENA */ +#define WM8994_AIF2DRC_NG_ENA_SHIFT 8 /* AIF2DRC_NG_ENA */ +#define WM8994_AIF2DRC_NG_ENA_WIDTH 1 /* AIF2DRC_NG_ENA */ +#define WM8994_AIF2DRC_SIG_DET_MODE 0x0080 /* AIF2DRC_SIG_DET_MODE */ +#define WM8994_AIF2DRC_SIG_DET_MODE_MASK 0x0080 /* AIF2DRC_SIG_DET_MODE */ +#define WM8994_AIF2DRC_SIG_DET_MODE_SHIFT 7 /* AIF2DRC_SIG_DET_MODE */ +#define WM8994_AIF2DRC_SIG_DET_MODE_WIDTH 1 /* AIF2DRC_SIG_DET_MODE */ +#define WM8994_AIF2DRC_SIG_DET 0x0040 /* AIF2DRC_SIG_DET */ +#define WM8994_AIF2DRC_SIG_DET_MASK 0x0040 /* AIF2DRC_SIG_DET */ +#define WM8994_AIF2DRC_SIG_DET_SHIFT 6 /* AIF2DRC_SIG_DET */ +#define WM8994_AIF2DRC_SIG_DET_WIDTH 1 /* AIF2DRC_SIG_DET */ +#define WM8994_AIF2DRC_KNEE2_OP_ENA 0x0020 /* AIF2DRC_KNEE2_OP_ENA */ +#define WM8994_AIF2DRC_KNEE2_OP_ENA_MASK 0x0020 /* AIF2DRC_KNEE2_OP_ENA */ +#define WM8994_AIF2DRC_KNEE2_OP_ENA_SHIFT 5 /* AIF2DRC_KNEE2_OP_ENA */ +#define WM8994_AIF2DRC_KNEE2_OP_ENA_WIDTH 1 /* AIF2DRC_KNEE2_OP_ENA */ +#define WM8994_AIF2DRC_QR 0x0010 /* AIF2DRC_QR */ +#define WM8994_AIF2DRC_QR_MASK 0x0010 /* AIF2DRC_QR */ +#define WM8994_AIF2DRC_QR_SHIFT 4 /* AIF2DRC_QR */ +#define WM8994_AIF2DRC_QR_WIDTH 1 /* AIF2DRC_QR */ +#define WM8994_AIF2DRC_ANTICLIP 0x0008 /* AIF2DRC_ANTICLIP */ +#define WM8994_AIF2DRC_ANTICLIP_MASK 0x0008 /* AIF2DRC_ANTICLIP */ +#define WM8994_AIF2DRC_ANTICLIP_SHIFT 3 /* AIF2DRC_ANTICLIP */ +#define WM8994_AIF2DRC_ANTICLIP_WIDTH 1 /* AIF2DRC_ANTICLIP */ +#define WM8994_AIF2DAC_DRC_ENA 0x0004 /* AIF2DAC_DRC_ENA */ +#define WM8994_AIF2DAC_DRC_ENA_MASK 0x0004 /* AIF2DAC_DRC_ENA */ +#define WM8994_AIF2DAC_DRC_ENA_SHIFT 2 /* AIF2DAC_DRC_ENA */ +#define WM8994_AIF2DAC_DRC_ENA_WIDTH 1 /* AIF2DAC_DRC_ENA */ +#define WM8994_AIF2ADCL_DRC_ENA 0x0002 /* AIF2ADCL_DRC_ENA */ +#define WM8994_AIF2ADCL_DRC_ENA_MASK 0x0002 /* AIF2ADCL_DRC_ENA */ +#define WM8994_AIF2ADCL_DRC_ENA_SHIFT 1 /* AIF2ADCL_DRC_ENA */ +#define WM8994_AIF2ADCL_DRC_ENA_WIDTH 1 /* AIF2ADCL_DRC_ENA */ +#define WM8994_AIF2ADCR_DRC_ENA 0x0001 /* AIF2ADCR_DRC_ENA */ +#define WM8994_AIF2ADCR_DRC_ENA_MASK 0x0001 /* AIF2ADCR_DRC_ENA */ +#define WM8994_AIF2ADCR_DRC_ENA_SHIFT 0 /* AIF2ADCR_DRC_ENA */ +#define WM8994_AIF2ADCR_DRC_ENA_WIDTH 1 /* AIF2ADCR_DRC_ENA */ + +/* + * R1345 (0x541) - AIF2 DRC (2) + */ +#define WM8994_AIF2DRC_ATK_MASK 0x1E00 /* AIF2DRC_ATK - [12:9] */ +#define WM8994_AIF2DRC_ATK_SHIFT 9 /* AIF2DRC_ATK - [12:9] */ +#define WM8994_AIF2DRC_ATK_WIDTH 4 /* AIF2DRC_ATK - [12:9] */ +#define WM8994_AIF2DRC_DCY_MASK 0x01E0 /* AIF2DRC_DCY - [8:5] */ +#define WM8994_AIF2DRC_DCY_SHIFT 5 /* AIF2DRC_DCY - [8:5] */ +#define WM8994_AIF2DRC_DCY_WIDTH 4 /* AIF2DRC_DCY - [8:5] */ +#define WM8994_AIF2DRC_MINGAIN_MASK 0x001C /* AIF2DRC_MINGAIN - [4:2] */ +#define WM8994_AIF2DRC_MINGAIN_SHIFT 2 /* AIF2DRC_MINGAIN - [4:2] */ +#define WM8994_AIF2DRC_MINGAIN_WIDTH 3 /* AIF2DRC_MINGAIN - [4:2] */ +#define WM8994_AIF2DRC_MAXGAIN_MASK 0x0003 /* AIF2DRC_MAXGAIN - [1:0] */ +#define WM8994_AIF2DRC_MAXGAIN_SHIFT 0 /* AIF2DRC_MAXGAIN - [1:0] */ +#define WM8994_AIF2DRC_MAXGAIN_WIDTH 2 /* AIF2DRC_MAXGAIN - [1:0] */ + +/* + * R1346 (0x542) - AIF2 DRC (3) + */ +#define WM8994_AIF2DRC_NG_MINGAIN_MASK 0xF000 /* AIF2DRC_NG_MINGAIN - [15:12] */ +#define WM8994_AIF2DRC_NG_MINGAIN_SHIFT 12 /* AIF2DRC_NG_MINGAIN - [15:12] */ +#define WM8994_AIF2DRC_NG_MINGAIN_WIDTH 4 /* AIF2DRC_NG_MINGAIN - [15:12] */ +#define WM8994_AIF2DRC_NG_EXP_MASK 0x0C00 /* AIF2DRC_NG_EXP - [11:10] */ +#define WM8994_AIF2DRC_NG_EXP_SHIFT 10 /* AIF2DRC_NG_EXP - [11:10] */ +#define WM8994_AIF2DRC_NG_EXP_WIDTH 2 /* AIF2DRC_NG_EXP - [11:10] */ +#define WM8994_AIF2DRC_QR_THR_MASK 0x0300 /* AIF2DRC_QR_THR - [9:8] */ +#define WM8994_AIF2DRC_QR_THR_SHIFT 8 /* AIF2DRC_QR_THR - [9:8] */ +#define WM8994_AIF2DRC_QR_THR_WIDTH 2 /* AIF2DRC_QR_THR - [9:8] */ +#define WM8994_AIF2DRC_QR_DCY_MASK 0x00C0 /* AIF2DRC_QR_DCY - [7:6] */ +#define WM8994_AIF2DRC_QR_DCY_SHIFT 6 /* AIF2DRC_QR_DCY - [7:6] */ +#define WM8994_AIF2DRC_QR_DCY_WIDTH 2 /* AIF2DRC_QR_DCY - [7:6] */ +#define WM8994_AIF2DRC_HI_COMP_MASK 0x0038 /* AIF2DRC_HI_COMP - [5:3] */ +#define WM8994_AIF2DRC_HI_COMP_SHIFT 3 /* AIF2DRC_HI_COMP - [5:3] */ +#define WM8994_AIF2DRC_HI_COMP_WIDTH 3 /* AIF2DRC_HI_COMP - [5:3] */ +#define WM8994_AIF2DRC_LO_COMP_MASK 0x0007 /* AIF2DRC_LO_COMP - [2:0] */ +#define WM8994_AIF2DRC_LO_COMP_SHIFT 0 /* AIF2DRC_LO_COMP - [2:0] */ +#define WM8994_AIF2DRC_LO_COMP_WIDTH 3 /* AIF2DRC_LO_COMP - [2:0] */ + +/* + * R1347 (0x543) - AIF2 DRC (4) + */ +#define WM8994_AIF2DRC_KNEE_IP_MASK 0x07E0 /* AIF2DRC_KNEE_IP - [10:5] */ +#define WM8994_AIF2DRC_KNEE_IP_SHIFT 5 /* AIF2DRC_KNEE_IP - [10:5] */ +#define WM8994_AIF2DRC_KNEE_IP_WIDTH 6 /* AIF2DRC_KNEE_IP - [10:5] */ +#define WM8994_AIF2DRC_KNEE_OP_MASK 0x001F /* AIF2DRC_KNEE_OP - [4:0] */ +#define WM8994_AIF2DRC_KNEE_OP_SHIFT 0 /* AIF2DRC_KNEE_OP - [4:0] */ +#define WM8994_AIF2DRC_KNEE_OP_WIDTH 5 /* AIF2DRC_KNEE_OP - [4:0] */ + +/* + * R1348 (0x544) - AIF2 DRC (5) + */ +#define WM8994_AIF2DRC_KNEE2_IP_MASK 0x03E0 /* AIF2DRC_KNEE2_IP - [9:5] */ +#define WM8994_AIF2DRC_KNEE2_IP_SHIFT 5 /* AIF2DRC_KNEE2_IP - [9:5] */ +#define WM8994_AIF2DRC_KNEE2_IP_WIDTH 5 /* AIF2DRC_KNEE2_IP - [9:5] */ +#define WM8994_AIF2DRC_KNEE2_OP_MASK 0x001F /* AIF2DRC_KNEE2_OP - [4:0] */ +#define WM8994_AIF2DRC_KNEE2_OP_SHIFT 0 /* AIF2DRC_KNEE2_OP - [4:0] */ +#define WM8994_AIF2DRC_KNEE2_OP_WIDTH 5 /* AIF2DRC_KNEE2_OP - [4:0] */ + +/* + * R1408 (0x580) - AIF2 EQ Gains (1) + */ +#define WM8994_AIF2DAC_EQ_B1_GAIN_MASK 0xF800 /* AIF2DAC_EQ_B1_GAIN - [15:11] */ +#define WM8994_AIF2DAC_EQ_B1_GAIN_SHIFT 11 /* AIF2DAC_EQ_B1_GAIN - [15:11] */ +#define WM8994_AIF2DAC_EQ_B1_GAIN_WIDTH 5 /* AIF2DAC_EQ_B1_GAIN - [15:11] */ +#define WM8994_AIF2DAC_EQ_B2_GAIN_MASK 0x07C0 /* AIF2DAC_EQ_B2_GAIN - [10:6] */ +#define WM8994_AIF2DAC_EQ_B2_GAIN_SHIFT 6 /* AIF2DAC_EQ_B2_GAIN - [10:6] */ +#define WM8994_AIF2DAC_EQ_B2_GAIN_WIDTH 5 /* AIF2DAC_EQ_B2_GAIN - [10:6] */ +#define WM8994_AIF2DAC_EQ_B3_GAIN_MASK 0x003E /* AIF2DAC_EQ_B3_GAIN - [5:1] */ +#define WM8994_AIF2DAC_EQ_B3_GAIN_SHIFT 1 /* AIF2DAC_EQ_B3_GAIN - [5:1] */ +#define WM8994_AIF2DAC_EQ_B3_GAIN_WIDTH 5 /* AIF2DAC_EQ_B3_GAIN - [5:1] */ +#define WM8994_AIF2DAC_EQ_ENA 0x0001 /* AIF2DAC_EQ_ENA */ +#define WM8994_AIF2DAC_EQ_ENA_MASK 0x0001 /* AIF2DAC_EQ_ENA */ +#define WM8994_AIF2DAC_EQ_ENA_SHIFT 0 /* AIF2DAC_EQ_ENA */ +#define WM8994_AIF2DAC_EQ_ENA_WIDTH 1 /* AIF2DAC_EQ_ENA */ + +/* + * R1409 (0x581) - AIF2 EQ Gains (2) + */ +#define WM8994_AIF2DAC_EQ_B4_GAIN_MASK 0xF800 /* AIF2DAC_EQ_B4_GAIN - [15:11] */ +#define WM8994_AIF2DAC_EQ_B4_GAIN_SHIFT 11 /* AIF2DAC_EQ_B4_GAIN - [15:11] */ +#define WM8994_AIF2DAC_EQ_B4_GAIN_WIDTH 5 /* AIF2DAC_EQ_B4_GAIN - [15:11] */ +#define WM8994_AIF2DAC_EQ_B5_GAIN_MASK 0x07C0 /* AIF2DAC_EQ_B5_GAIN - [10:6] */ +#define WM8994_AIF2DAC_EQ_B5_GAIN_SHIFT 6 /* AIF2DAC_EQ_B5_GAIN - [10:6] */ +#define WM8994_AIF2DAC_EQ_B5_GAIN_WIDTH 5 /* AIF2DAC_EQ_B5_GAIN - [10:6] */ + +/* + * R1410 (0x582) - AIF2 EQ Band 1 A + */ +#define WM8994_AIF2DAC_EQ_B1_A_MASK 0xFFFF /* AIF2DAC_EQ_B1_A - [15:0] */ +#define WM8994_AIF2DAC_EQ_B1_A_SHIFT 0 /* AIF2DAC_EQ_B1_A - [15:0] */ +#define WM8994_AIF2DAC_EQ_B1_A_WIDTH 16 /* AIF2DAC_EQ_B1_A - [15:0] */ + +/* + * R1411 (0x583) - AIF2 EQ Band 1 B + */ +#define WM8994_AIF2DAC_EQ_B1_B_MASK 0xFFFF /* AIF2DAC_EQ_B1_B - [15:0] */ +#define WM8994_AIF2DAC_EQ_B1_B_SHIFT 0 /* AIF2DAC_EQ_B1_B - [15:0] */ +#define WM8994_AIF2DAC_EQ_B1_B_WIDTH 16 /* AIF2DAC_EQ_B1_B - [15:0] */ + +/* + * R1412 (0x584) - AIF2 EQ Band 1 PG + */ +#define WM8994_AIF2DAC_EQ_B1_PG_MASK 0xFFFF /* AIF2DAC_EQ_B1_PG - [15:0] */ +#define WM8994_AIF2DAC_EQ_B1_PG_SHIFT 0 /* AIF2DAC_EQ_B1_PG - [15:0] */ +#define WM8994_AIF2DAC_EQ_B1_PG_WIDTH 16 /* AIF2DAC_EQ_B1_PG - [15:0] */ + +/* + * R1413 (0x585) - AIF2 EQ Band 2 A + */ +#define WM8994_AIF2DAC_EQ_B2_A_MASK 0xFFFF /* AIF2DAC_EQ_B2_A - [15:0] */ +#define WM8994_AIF2DAC_EQ_B2_A_SHIFT 0 /* AIF2DAC_EQ_B2_A - [15:0] */ +#define WM8994_AIF2DAC_EQ_B2_A_WIDTH 16 /* AIF2DAC_EQ_B2_A - [15:0] */ + +/* + * R1414 (0x586) - AIF2 EQ Band 2 B + */ +#define WM8994_AIF2DAC_EQ_B2_B_MASK 0xFFFF /* AIF2DAC_EQ_B2_B - [15:0] */ +#define WM8994_AIF2DAC_EQ_B2_B_SHIFT 0 /* AIF2DAC_EQ_B2_B - [15:0] */ +#define WM8994_AIF2DAC_EQ_B2_B_WIDTH 16 /* AIF2DAC_EQ_B2_B - [15:0] */ + +/* + * R1415 (0x587) - AIF2 EQ Band 2 C + */ +#define WM8994_AIF2DAC_EQ_B2_C_MASK 0xFFFF /* AIF2DAC_EQ_B2_C - [15:0] */ +#define WM8994_AIF2DAC_EQ_B2_C_SHIFT 0 /* AIF2DAC_EQ_B2_C - [15:0] */ +#define WM8994_AIF2DAC_EQ_B2_C_WIDTH 16 /* AIF2DAC_EQ_B2_C - [15:0] */ + +/* + * R1416 (0x588) - AIF2 EQ Band 2 PG + */ +#define WM8994_AIF2DAC_EQ_B2_PG_MASK 0xFFFF /* AIF2DAC_EQ_B2_PG - [15:0] */ +#define WM8994_AIF2DAC_EQ_B2_PG_SHIFT 0 /* AIF2DAC_EQ_B2_PG - [15:0] */ +#define WM8994_AIF2DAC_EQ_B2_PG_WIDTH 16 /* AIF2DAC_EQ_B2_PG - [15:0] */ + +/* + * R1417 (0x589) - AIF2 EQ Band 3 A + */ +#define WM8994_AIF2DAC_EQ_B3_A_MASK 0xFFFF /* AIF2DAC_EQ_B3_A - [15:0] */ +#define WM8994_AIF2DAC_EQ_B3_A_SHIFT 0 /* AIF2DAC_EQ_B3_A - [15:0] */ +#define WM8994_AIF2DAC_EQ_B3_A_WIDTH 16 /* AIF2DAC_EQ_B3_A - [15:0] */ + +/* + * R1418 (0x58A) - AIF2 EQ Band 3 B + */ +#define WM8994_AIF2DAC_EQ_B3_B_MASK 0xFFFF /* AIF2DAC_EQ_B3_B - [15:0] */ +#define WM8994_AIF2DAC_EQ_B3_B_SHIFT 0 /* AIF2DAC_EQ_B3_B - [15:0] */ +#define WM8994_AIF2DAC_EQ_B3_B_WIDTH 16 /* AIF2DAC_EQ_B3_B - [15:0] */ + +/* + * R1419 (0x58B) - AIF2 EQ Band 3 C + */ +#define WM8994_AIF2DAC_EQ_B3_C_MASK 0xFFFF /* AIF2DAC_EQ_B3_C - [15:0] */ +#define WM8994_AIF2DAC_EQ_B3_C_SHIFT 0 /* AIF2DAC_EQ_B3_C - [15:0] */ +#define WM8994_AIF2DAC_EQ_B3_C_WIDTH 16 /* AIF2DAC_EQ_B3_C - [15:0] */ + +/* + * R1420 (0x58C) - AIF2 EQ Band 3 PG + */ +#define WM8994_AIF2DAC_EQ_B3_PG_MASK 0xFFFF /* AIF2DAC_EQ_B3_PG - [15:0] */ +#define WM8994_AIF2DAC_EQ_B3_PG_SHIFT 0 /* AIF2DAC_EQ_B3_PG - [15:0] */ +#define WM8994_AIF2DAC_EQ_B3_PG_WIDTH 16 /* AIF2DAC_EQ_B3_PG - [15:0] */ + +/* + * R1421 (0x58D) - AIF2 EQ Band 4 A + */ +#define WM8994_AIF2DAC_EQ_B4_A_MASK 0xFFFF /* AIF2DAC_EQ_B4_A - [15:0] */ +#define WM8994_AIF2DAC_EQ_B4_A_SHIFT 0 /* AIF2DAC_EQ_B4_A - [15:0] */ +#define WM8994_AIF2DAC_EQ_B4_A_WIDTH 16 /* AIF2DAC_EQ_B4_A - [15:0] */ + +/* + * R1422 (0x58E) - AIF2 EQ Band 4 B + */ +#define WM8994_AIF2DAC_EQ_B4_B_MASK 0xFFFF /* AIF2DAC_EQ_B4_B - [15:0] */ +#define WM8994_AIF2DAC_EQ_B4_B_SHIFT 0 /* AIF2DAC_EQ_B4_B - [15:0] */ +#define WM8994_AIF2DAC_EQ_B4_B_WIDTH 16 /* AIF2DAC_EQ_B4_B - [15:0] */ + +/* + * R1423 (0x58F) - AIF2 EQ Band 4 C + */ +#define WM8994_AIF2DAC_EQ_B4_C_MASK 0xFFFF /* AIF2DAC_EQ_B4_C - [15:0] */ +#define WM8994_AIF2DAC_EQ_B4_C_SHIFT 0 /* AIF2DAC_EQ_B4_C - [15:0] */ +#define WM8994_AIF2DAC_EQ_B4_C_WIDTH 16 /* AIF2DAC_EQ_B4_C - [15:0] */ + +/* + * R1424 (0x590) - AIF2 EQ Band 4 PG + */ +#define WM8994_AIF2DAC_EQ_B4_PG_MASK 0xFFFF /* AIF2DAC_EQ_B4_PG - [15:0] */ +#define WM8994_AIF2DAC_EQ_B4_PG_SHIFT 0 /* AIF2DAC_EQ_B4_PG - [15:0] */ +#define WM8994_AIF2DAC_EQ_B4_PG_WIDTH 16 /* AIF2DAC_EQ_B4_PG - [15:0] */ + +/* + * R1425 (0x591) - AIF2 EQ Band 5 A + */ +#define WM8994_AIF2DAC_EQ_B5_A_MASK 0xFFFF /* AIF2DAC_EQ_B5_A - [15:0] */ +#define WM8994_AIF2DAC_EQ_B5_A_SHIFT 0 /* AIF2DAC_EQ_B5_A - [15:0] */ +#define WM8994_AIF2DAC_EQ_B5_A_WIDTH 16 /* AIF2DAC_EQ_B5_A - [15:0] */ + +/* + * R1426 (0x592) - AIF2 EQ Band 5 B + */ +#define WM8994_AIF2DAC_EQ_B5_B_MASK 0xFFFF /* AIF2DAC_EQ_B5_B - [15:0] */ +#define WM8994_AIF2DAC_EQ_B5_B_SHIFT 0 /* AIF2DAC_EQ_B5_B - [15:0] */ +#define WM8994_AIF2DAC_EQ_B5_B_WIDTH 16 /* AIF2DAC_EQ_B5_B - [15:0] */ + +/* + * R1427 (0x593) - AIF2 EQ Band 5 PG + */ +#define WM8994_AIF2DAC_EQ_B5_PG_MASK 0xFFFF /* AIF2DAC_EQ_B5_PG - [15:0] */ +#define WM8994_AIF2DAC_EQ_B5_PG_SHIFT 0 /* AIF2DAC_EQ_B5_PG - [15:0] */ +#define WM8994_AIF2DAC_EQ_B5_PG_WIDTH 16 /* AIF2DAC_EQ_B5_PG - [15:0] */ + +/* + * R1536 (0x600) - DAC1 Mixer Volumes + */ +#define WM8994_ADCR_DAC1_VOL_MASK 0x01E0 /* ADCR_DAC1_VOL - [8:5] */ +#define WM8994_ADCR_DAC1_VOL_SHIFT 5 /* ADCR_DAC1_VOL - [8:5] */ +#define WM8994_ADCR_DAC1_VOL_WIDTH 4 /* ADCR_DAC1_VOL - [8:5] */ +#define WM8994_ADCL_DAC1_VOL_MASK 0x000F /* ADCL_DAC1_VOL - [3:0] */ +#define WM8994_ADCL_DAC1_VOL_SHIFT 0 /* ADCL_DAC1_VOL - [3:0] */ +#define WM8994_ADCL_DAC1_VOL_WIDTH 4 /* ADCL_DAC1_VOL - [3:0] */ + +/* + * R1537 (0x601) - DAC1 Left Mixer Routing + */ +#define WM8994_ADCR_TO_DAC1L 0x0020 /* ADCR_TO_DAC1L */ +#define WM8994_ADCR_TO_DAC1L_MASK 0x0020 /* ADCR_TO_DAC1L */ +#define WM8994_ADCR_TO_DAC1L_SHIFT 5 /* ADCR_TO_DAC1L */ +#define WM8994_ADCR_TO_DAC1L_WIDTH 1 /* ADCR_TO_DAC1L */ +#define WM8994_ADCL_TO_DAC1L 0x0010 /* ADCL_TO_DAC1L */ +#define WM8994_ADCL_TO_DAC1L_MASK 0x0010 /* ADCL_TO_DAC1L */ +#define WM8994_ADCL_TO_DAC1L_SHIFT 4 /* ADCL_TO_DAC1L */ +#define WM8994_ADCL_TO_DAC1L_WIDTH 1 /* ADCL_TO_DAC1L */ +#define WM8994_AIF2DACL_TO_DAC1L 0x0004 /* AIF2DACL_TO_DAC1L */ +#define WM8994_AIF2DACL_TO_DAC1L_MASK 0x0004 /* AIF2DACL_TO_DAC1L */ +#define WM8994_AIF2DACL_TO_DAC1L_SHIFT 2 /* AIF2DACL_TO_DAC1L */ +#define WM8994_AIF2DACL_TO_DAC1L_WIDTH 1 /* AIF2DACL_TO_DAC1L */ +#define WM8994_AIF1DAC2L_TO_DAC1L 0x0002 /* AIF1DAC2L_TO_DAC1L */ +#define WM8994_AIF1DAC2L_TO_DAC1L_MASK 0x0002 /* AIF1DAC2L_TO_DAC1L */ +#define WM8994_AIF1DAC2L_TO_DAC1L_SHIFT 1 /* AIF1DAC2L_TO_DAC1L */ +#define WM8994_AIF1DAC2L_TO_DAC1L_WIDTH 1 /* AIF1DAC2L_TO_DAC1L */ +#define WM8994_AIF1DAC1L_TO_DAC1L 0x0001 /* AIF1DAC1L_TO_DAC1L */ +#define WM8994_AIF1DAC1L_TO_DAC1L_MASK 0x0001 /* AIF1DAC1L_TO_DAC1L */ +#define WM8994_AIF1DAC1L_TO_DAC1L_SHIFT 0 /* AIF1DAC1L_TO_DAC1L */ +#define WM8994_AIF1DAC1L_TO_DAC1L_WIDTH 1 /* AIF1DAC1L_TO_DAC1L */ + +/* + * R1538 (0x602) - DAC1 Right Mixer Routing + */ +#define WM8994_ADCR_TO_DAC1R 0x0020 /* ADCR_TO_DAC1R */ +#define WM8994_ADCR_TO_DAC1R_MASK 0x0020 /* ADCR_TO_DAC1R */ +#define WM8994_ADCR_TO_DAC1R_SHIFT 5 /* ADCR_TO_DAC1R */ +#define WM8994_ADCR_TO_DAC1R_WIDTH 1 /* ADCR_TO_DAC1R */ +#define WM8994_ADCL_TO_DAC1R 0x0010 /* ADCL_TO_DAC1R */ +#define WM8994_ADCL_TO_DAC1R_MASK 0x0010 /* ADCL_TO_DAC1R */ +#define WM8994_ADCL_TO_DAC1R_SHIFT 4 /* ADCL_TO_DAC1R */ +#define WM8994_ADCL_TO_DAC1R_WIDTH 1 /* ADCL_TO_DAC1R */ +#define WM8994_AIF2DACR_TO_DAC1R 0x0004 /* AIF2DACR_TO_DAC1R */ +#define WM8994_AIF2DACR_TO_DAC1R_MASK 0x0004 /* AIF2DACR_TO_DAC1R */ +#define WM8994_AIF2DACR_TO_DAC1R_SHIFT 2 /* AIF2DACR_TO_DAC1R */ +#define WM8994_AIF2DACR_TO_DAC1R_WIDTH 1 /* AIF2DACR_TO_DAC1R */ +#define WM8994_AIF1DAC2R_TO_DAC1R 0x0002 /* AIF1DAC2R_TO_DAC1R */ +#define WM8994_AIF1DAC2R_TO_DAC1R_MASK 0x0002 /* AIF1DAC2R_TO_DAC1R */ +#define WM8994_AIF1DAC2R_TO_DAC1R_SHIFT 1 /* AIF1DAC2R_TO_DAC1R */ +#define WM8994_AIF1DAC2R_TO_DAC1R_WIDTH 1 /* AIF1DAC2R_TO_DAC1R */ +#define WM8994_AIF1DAC1R_TO_DAC1R 0x0001 /* AIF1DAC1R_TO_DAC1R */ +#define WM8994_AIF1DAC1R_TO_DAC1R_MASK 0x0001 /* AIF1DAC1R_TO_DAC1R */ +#define WM8994_AIF1DAC1R_TO_DAC1R_SHIFT 0 /* AIF1DAC1R_TO_DAC1R */ +#define WM8994_AIF1DAC1R_TO_DAC1R_WIDTH 1 /* AIF1DAC1R_TO_DAC1R */ + +/* + * R1539 (0x603) - DAC2 Mixer Volumes + */ +#define WM8994_ADCR_DAC2_VOL_MASK 0x01E0 /* ADCR_DAC2_VOL - [8:5] */ +#define WM8994_ADCR_DAC2_VOL_SHIFT 5 /* ADCR_DAC2_VOL - [8:5] */ +#define WM8994_ADCR_DAC2_VOL_WIDTH 4 /* ADCR_DAC2_VOL - [8:5] */ +#define WM8994_ADCL_DAC2_VOL_MASK 0x000F /* ADCL_DAC2_VOL - [3:0] */ +#define WM8994_ADCL_DAC2_VOL_SHIFT 0 /* ADCL_DAC2_VOL - [3:0] */ +#define WM8994_ADCL_DAC2_VOL_WIDTH 4 /* ADCL_DAC2_VOL - [3:0] */ + +/* + * R1540 (0x604) - DAC2 Left Mixer Routing + */ +#define WM8994_ADCR_TO_DAC2L 0x0020 /* ADCR_TO_DAC2L */ +#define WM8994_ADCR_TO_DAC2L_MASK 0x0020 /* ADCR_TO_DAC2L */ +#define WM8994_ADCR_TO_DAC2L_SHIFT 5 /* ADCR_TO_DAC2L */ +#define WM8994_ADCR_TO_DAC2L_WIDTH 1 /* ADCR_TO_DAC2L */ +#define WM8994_ADCL_TO_DAC2L 0x0010 /* ADCL_TO_DAC2L */ +#define WM8994_ADCL_TO_DAC2L_MASK 0x0010 /* ADCL_TO_DAC2L */ +#define WM8994_ADCL_TO_DAC2L_SHIFT 4 /* ADCL_TO_DAC2L */ +#define WM8994_ADCL_TO_DAC2L_WIDTH 1 /* ADCL_TO_DAC2L */ +#define WM8994_AIF2DACL_TO_DAC2L 0x0004 /* AIF2DACL_TO_DAC2L */ +#define WM8994_AIF2DACL_TO_DAC2L_MASK 0x0004 /* AIF2DACL_TO_DAC2L */ +#define WM8994_AIF2DACL_TO_DAC2L_SHIFT 2 /* AIF2DACL_TO_DAC2L */ +#define WM8994_AIF2DACL_TO_DAC2L_WIDTH 1 /* AIF2DACL_TO_DAC2L */ +#define WM8994_AIF1DAC2L_TO_DAC2L 0x0002 /* AIF1DAC2L_TO_DAC2L */ +#define WM8994_AIF1DAC2L_TO_DAC2L_MASK 0x0002 /* AIF1DAC2L_TO_DAC2L */ +#define WM8994_AIF1DAC2L_TO_DAC2L_SHIFT 1 /* AIF1DAC2L_TO_DAC2L */ +#define WM8994_AIF1DAC2L_TO_DAC2L_WIDTH 1 /* AIF1DAC2L_TO_DAC2L */ +#define WM8994_AIF1DAC1L_TO_DAC2L 0x0001 /* AIF1DAC1L_TO_DAC2L */ +#define WM8994_AIF1DAC1L_TO_DAC2L_MASK 0x0001 /* AIF1DAC1L_TO_DAC2L */ +#define WM8994_AIF1DAC1L_TO_DAC2L_SHIFT 0 /* AIF1DAC1L_TO_DAC2L */ +#define WM8994_AIF1DAC1L_TO_DAC2L_WIDTH 1 /* AIF1DAC1L_TO_DAC2L */ + +/* + * R1541 (0x605) - DAC2 Right Mixer Routing + */ +#define WM8994_ADCR_TO_DAC2R 0x0020 /* ADCR_TO_DAC2R */ +#define WM8994_ADCR_TO_DAC2R_MASK 0x0020 /* ADCR_TO_DAC2R */ +#define WM8994_ADCR_TO_DAC2R_SHIFT 5 /* ADCR_TO_DAC2R */ +#define WM8994_ADCR_TO_DAC2R_WIDTH 1 /* ADCR_TO_DAC2R */ +#define WM8994_ADCL_TO_DAC2R 0x0010 /* ADCL_TO_DAC2R */ +#define WM8994_ADCL_TO_DAC2R_MASK 0x0010 /* ADCL_TO_DAC2R */ +#define WM8994_ADCL_TO_DAC2R_SHIFT 4 /* ADCL_TO_DAC2R */ +#define WM8994_ADCL_TO_DAC2R_WIDTH 1 /* ADCL_TO_DAC2R */ +#define WM8994_AIF2DACR_TO_DAC2R 0x0004 /* AIF2DACR_TO_DAC2R */ +#define WM8994_AIF2DACR_TO_DAC2R_MASK 0x0004 /* AIF2DACR_TO_DAC2R */ +#define WM8994_AIF2DACR_TO_DAC2R_SHIFT 2 /* AIF2DACR_TO_DAC2R */ +#define WM8994_AIF2DACR_TO_DAC2R_WIDTH 1 /* AIF2DACR_TO_DAC2R */ +#define WM8994_AIF1DAC2R_TO_DAC2R 0x0002 /* AIF1DAC2R_TO_DAC2R */ +#define WM8994_AIF1DAC2R_TO_DAC2R_MASK 0x0002 /* AIF1DAC2R_TO_DAC2R */ +#define WM8994_AIF1DAC2R_TO_DAC2R_SHIFT 1 /* AIF1DAC2R_TO_DAC2R */ +#define WM8994_AIF1DAC2R_TO_DAC2R_WIDTH 1 /* AIF1DAC2R_TO_DAC2R */ +#define WM8994_AIF1DAC1R_TO_DAC2R 0x0001 /* AIF1DAC1R_TO_DAC2R */ +#define WM8994_AIF1DAC1R_TO_DAC2R_MASK 0x0001 /* AIF1DAC1R_TO_DAC2R */ +#define WM8994_AIF1DAC1R_TO_DAC2R_SHIFT 0 /* AIF1DAC1R_TO_DAC2R */ +#define WM8994_AIF1DAC1R_TO_DAC2R_WIDTH 1 /* AIF1DAC1R_TO_DAC2R */ + +/* + * R1542 (0x606) - AIF1 ADC1 Left Mixer Routing + */ +#define WM8994_ADC1L_TO_AIF1ADC1L 0x0002 /* ADC1L_TO_AIF1ADC1L */ +#define WM8994_ADC1L_TO_AIF1ADC1L_MASK 0x0002 /* ADC1L_TO_AIF1ADC1L */ +#define WM8994_ADC1L_TO_AIF1ADC1L_SHIFT 1 /* ADC1L_TO_AIF1ADC1L */ +#define WM8994_ADC1L_TO_AIF1ADC1L_WIDTH 1 /* ADC1L_TO_AIF1ADC1L */ +#define WM8994_AIF2DACL_TO_AIF1ADC1L 0x0001 /* AIF2DACL_TO_AIF1ADC1L */ +#define WM8994_AIF2DACL_TO_AIF1ADC1L_MASK 0x0001 /* AIF2DACL_TO_AIF1ADC1L */ +#define WM8994_AIF2DACL_TO_AIF1ADC1L_SHIFT 0 /* AIF2DACL_TO_AIF1ADC1L */ +#define WM8994_AIF2DACL_TO_AIF1ADC1L_WIDTH 1 /* AIF2DACL_TO_AIF1ADC1L */ + +/* + * R1543 (0x607) - AIF1 ADC1 Right Mixer Routing + */ +#define WM8994_ADC1R_TO_AIF1ADC1R 0x0002 /* ADC1R_TO_AIF1ADC1R */ +#define WM8994_ADC1R_TO_AIF1ADC1R_MASK 0x0002 /* ADC1R_TO_AIF1ADC1R */ +#define WM8994_ADC1R_TO_AIF1ADC1R_SHIFT 1 /* ADC1R_TO_AIF1ADC1R */ +#define WM8994_ADC1R_TO_AIF1ADC1R_WIDTH 1 /* ADC1R_TO_AIF1ADC1R */ +#define WM8994_AIF2DACR_TO_AIF1ADC1R 0x0001 /* AIF2DACR_TO_AIF1ADC1R */ +#define WM8994_AIF2DACR_TO_AIF1ADC1R_MASK 0x0001 /* AIF2DACR_TO_AIF1ADC1R */ +#define WM8994_AIF2DACR_TO_AIF1ADC1R_SHIFT 0 /* AIF2DACR_TO_AIF1ADC1R */ +#define WM8994_AIF2DACR_TO_AIF1ADC1R_WIDTH 1 /* AIF2DACR_TO_AIF1ADC1R */ + +/* + * R1544 (0x608) - AIF1 ADC2 Left Mixer Routing + */ +#define WM8994_ADC2L_TO_AIF1ADC2L 0x0002 /* ADC2L_TO_AIF1ADC2L */ +#define WM8994_ADC2L_TO_AIF1ADC2L_MASK 0x0002 /* ADC2L_TO_AIF1ADC2L */ +#define WM8994_ADC2L_TO_AIF1ADC2L_SHIFT 1 /* ADC2L_TO_AIF1ADC2L */ +#define WM8994_ADC2L_TO_AIF1ADC2L_WIDTH 1 /* ADC2L_TO_AIF1ADC2L */ +#define WM8994_AIF2DACL_TO_AIF1ADC2L 0x0001 /* AIF2DACL_TO_AIF1ADC2L */ +#define WM8994_AIF2DACL_TO_AIF1ADC2L_MASK 0x0001 /* AIF2DACL_TO_AIF1ADC2L */ +#define WM8994_AIF2DACL_TO_AIF1ADC2L_SHIFT 0 /* AIF2DACL_TO_AIF1ADC2L */ +#define WM8994_AIF2DACL_TO_AIF1ADC2L_WIDTH 1 /* AIF2DACL_TO_AIF1ADC2L */ + +/* + * R1545 (0x609) - AIF1 ADC2 Right mixer Routing + */ +#define WM8994_ADC2R_TO_AIF1ADC2R 0x0002 /* ADC2R_TO_AIF1ADC2R */ +#define WM8994_ADC2R_TO_AIF1ADC2R_MASK 0x0002 /* ADC2R_TO_AIF1ADC2R */ +#define WM8994_ADC2R_TO_AIF1ADC2R_SHIFT 1 /* ADC2R_TO_AIF1ADC2R */ +#define WM8994_ADC2R_TO_AIF1ADC2R_WIDTH 1 /* ADC2R_TO_AIF1ADC2R */ +#define WM8994_AIF2DACR_TO_AIF1ADC2R 0x0001 /* AIF2DACR_TO_AIF1ADC2R */ +#define WM8994_AIF2DACR_TO_AIF1ADC2R_MASK 0x0001 /* AIF2DACR_TO_AIF1ADC2R */ +#define WM8994_AIF2DACR_TO_AIF1ADC2R_SHIFT 0 /* AIF2DACR_TO_AIF1ADC2R */ +#define WM8994_AIF2DACR_TO_AIF1ADC2R_WIDTH 1 /* AIF2DACR_TO_AIF1ADC2R */ + +/* + * R1552 (0x610) - DAC1 Left Volume + */ +#define WM8994_DAC1L_MUTE 0x0200 /* DAC1L_MUTE */ +#define WM8994_DAC1L_MUTE_MASK 0x0200 /* DAC1L_MUTE */ +#define WM8994_DAC1L_MUTE_SHIFT 9 /* DAC1L_MUTE */ +#define WM8994_DAC1L_MUTE_WIDTH 1 /* DAC1L_MUTE */ +#define WM8994_DAC1_VU 0x0100 /* DAC1_VU */ +#define WM8994_DAC1_VU_MASK 0x0100 /* DAC1_VU */ +#define WM8994_DAC1_VU_SHIFT 8 /* DAC1_VU */ +#define WM8994_DAC1_VU_WIDTH 1 /* DAC1_VU */ +#define WM8994_DAC1L_VOL_MASK 0x00FF /* DAC1L_VOL - [7:0] */ +#define WM8994_DAC1L_VOL_SHIFT 0 /* DAC1L_VOL - [7:0] */ +#define WM8994_DAC1L_VOL_WIDTH 8 /* DAC1L_VOL - [7:0] */ + +/* + * R1553 (0x611) - DAC1 Right Volume + */ +#define WM8994_DAC1R_MUTE 0x0200 /* DAC1R_MUTE */ +#define WM8994_DAC1R_MUTE_MASK 0x0200 /* DAC1R_MUTE */ +#define WM8994_DAC1R_MUTE_SHIFT 9 /* DAC1R_MUTE */ +#define WM8994_DAC1R_MUTE_WIDTH 1 /* DAC1R_MUTE */ +#define WM8994_DAC1_VU 0x0100 /* DAC1_VU */ +#define WM8994_DAC1_VU_MASK 0x0100 /* DAC1_VU */ +#define WM8994_DAC1_VU_SHIFT 8 /* DAC1_VU */ +#define WM8994_DAC1_VU_WIDTH 1 /* DAC1_VU */ +#define WM8994_DAC1R_VOL_MASK 0x00FF /* DAC1R_VOL - [7:0] */ +#define WM8994_DAC1R_VOL_SHIFT 0 /* DAC1R_VOL - [7:0] */ +#define WM8994_DAC1R_VOL_WIDTH 8 /* DAC1R_VOL - [7:0] */ + +/* + * R1554 (0x612) - DAC2 Left Volume + */ +#define WM8994_DAC2L_MUTE 0x0200 /* DAC2L_MUTE */ +#define WM8994_DAC2L_MUTE_MASK 0x0200 /* DAC2L_MUTE */ +#define WM8994_DAC2L_MUTE_SHIFT 9 /* DAC2L_MUTE */ +#define WM8994_DAC2L_MUTE_WIDTH 1 /* DAC2L_MUTE */ +#define WM8994_DAC2_VU 0x0100 /* DAC2_VU */ +#define WM8994_DAC2_VU_MASK 0x0100 /* DAC2_VU */ +#define WM8994_DAC2_VU_SHIFT 8 /* DAC2_VU */ +#define WM8994_DAC2_VU_WIDTH 1 /* DAC2_VU */ +#define WM8994_DAC2L_VOL_MASK 0x00FF /* DAC2L_VOL - [7:0] */ +#define WM8994_DAC2L_VOL_SHIFT 0 /* DAC2L_VOL - [7:0] */ +#define WM8994_DAC2L_VOL_WIDTH 8 /* DAC2L_VOL - [7:0] */ + +/* + * R1555 (0x613) - DAC2 Right Volume + */ +#define WM8994_DAC2R_MUTE 0x0200 /* DAC2R_MUTE */ +#define WM8994_DAC2R_MUTE_MASK 0x0200 /* DAC2R_MUTE */ +#define WM8994_DAC2R_MUTE_SHIFT 9 /* DAC2R_MUTE */ +#define WM8994_DAC2R_MUTE_WIDTH 1 /* DAC2R_MUTE */ +#define WM8994_DAC2_VU 0x0100 /* DAC2_VU */ +#define WM8994_DAC2_VU_MASK 0x0100 /* DAC2_VU */ +#define WM8994_DAC2_VU_SHIFT 8 /* DAC2_VU */ +#define WM8994_DAC2_VU_WIDTH 1 /* DAC2_VU */ +#define WM8994_DAC2R_VOL_MASK 0x00FF /* DAC2R_VOL - [7:0] */ +#define WM8994_DAC2R_VOL_SHIFT 0 /* DAC2R_VOL - [7:0] */ +#define WM8994_DAC2R_VOL_WIDTH 8 /* DAC2R_VOL - [7:0] */ + +/* + * R1556 (0x614) - DAC Softmute + */ +#define WM8994_DAC_SOFTMUTEMODE 0x0002 /* DAC_SOFTMUTEMODE */ +#define WM8994_DAC_SOFTMUTEMODE_MASK 0x0002 /* DAC_SOFTMUTEMODE */ +#define WM8994_DAC_SOFTMUTEMODE_SHIFT 1 /* DAC_SOFTMUTEMODE */ +#define WM8994_DAC_SOFTMUTEMODE_WIDTH 1 /* DAC_SOFTMUTEMODE */ +#define WM8994_DAC_MUTERATE 0x0001 /* DAC_MUTERATE */ +#define WM8994_DAC_MUTERATE_MASK 0x0001 /* DAC_MUTERATE */ +#define WM8994_DAC_MUTERATE_SHIFT 0 /* DAC_MUTERATE */ +#define WM8994_DAC_MUTERATE_WIDTH 1 /* DAC_MUTERATE */ + +/* + * R1568 (0x620) - Oversampling + */ +#define WM8994_ADC_OSR128 0x0002 /* ADC_OSR128 */ +#define WM8994_ADC_OSR128_MASK 0x0002 /* ADC_OSR128 */ +#define WM8994_ADC_OSR128_SHIFT 1 /* ADC_OSR128 */ +#define WM8994_ADC_OSR128_WIDTH 1 /* ADC_OSR128 */ +#define WM8994_DAC_OSR128 0x0001 /* DAC_OSR128 */ +#define WM8994_DAC_OSR128_MASK 0x0001 /* DAC_OSR128 */ +#define WM8994_DAC_OSR128_SHIFT 0 /* DAC_OSR128 */ +#define WM8994_DAC_OSR128_WIDTH 1 /* DAC_OSR128 */ + +/* + * R1569 (0x621) - Sidetone + */ +#define WM8994_ST_HPF_CUT_MASK 0x0380 /* ST_HPF_CUT - [9:7] */ +#define WM8994_ST_HPF_CUT_SHIFT 7 /* ST_HPF_CUT - [9:7] */ +#define WM8994_ST_HPF_CUT_WIDTH 3 /* ST_HPF_CUT - [9:7] */ +#define WM8994_ST_HPF 0x0040 /* ST_HPF */ +#define WM8994_ST_HPF_MASK 0x0040 /* ST_HPF */ +#define WM8994_ST_HPF_SHIFT 6 /* ST_HPF */ +#define WM8994_ST_HPF_WIDTH 1 /* ST_HPF */ +#define WM8994_STR_SEL 0x0002 /* STR_SEL */ +#define WM8994_STR_SEL_MASK 0x0002 /* STR_SEL */ +#define WM8994_STR_SEL_SHIFT 1 /* STR_SEL */ +#define WM8994_STR_SEL_WIDTH 1 /* STR_SEL */ +#define WM8994_STL_SEL 0x0001 /* STL_SEL */ +#define WM8994_STL_SEL_MASK 0x0001 /* STL_SEL */ +#define WM8994_STL_SEL_SHIFT 0 /* STL_SEL */ +#define WM8994_STL_SEL_WIDTH 1 /* STL_SEL */ + +/* + * R1824 (0x720) - Pull Control (1) + */ +#define WM8994_DMICDAT2_PU 0x0800 /* DMICDAT2_PU */ +#define WM8994_DMICDAT2_PU_MASK 0x0800 /* DMICDAT2_PU */ +#define WM8994_DMICDAT2_PU_SHIFT 11 /* DMICDAT2_PU */ +#define WM8994_DMICDAT2_PU_WIDTH 1 /* DMICDAT2_PU */ +#define WM8994_DMICDAT2_PD 0x0400 /* DMICDAT2_PD */ +#define WM8994_DMICDAT2_PD_MASK 0x0400 /* DMICDAT2_PD */ +#define WM8994_DMICDAT2_PD_SHIFT 10 /* DMICDAT2_PD */ +#define WM8994_DMICDAT2_PD_WIDTH 1 /* DMICDAT2_PD */ +#define WM8994_DMICDAT1_PU 0x0200 /* DMICDAT1_PU */ +#define WM8994_DMICDAT1_PU_MASK 0x0200 /* DMICDAT1_PU */ +#define WM8994_DMICDAT1_PU_SHIFT 9 /* DMICDAT1_PU */ +#define WM8994_DMICDAT1_PU_WIDTH 1 /* DMICDAT1_PU */ +#define WM8994_DMICDAT1_PD 0x0100 /* DMICDAT1_PD */ +#define WM8994_DMICDAT1_PD_MASK 0x0100 /* DMICDAT1_PD */ +#define WM8994_DMICDAT1_PD_SHIFT 8 /* DMICDAT1_PD */ +#define WM8994_DMICDAT1_PD_WIDTH 1 /* DMICDAT1_PD */ +#define WM8994_MCLK1_PU 0x0080 /* MCLK1_PU */ +#define WM8994_MCLK1_PU_MASK 0x0080 /* MCLK1_PU */ +#define WM8994_MCLK1_PU_SHIFT 7 /* MCLK1_PU */ +#define WM8994_MCLK1_PU_WIDTH 1 /* MCLK1_PU */ +#define WM8994_MCLK1_PD 0x0040 /* MCLK1_PD */ +#define WM8994_MCLK1_PD_MASK 0x0040 /* MCLK1_PD */ +#define WM8994_MCLK1_PD_SHIFT 6 /* MCLK1_PD */ +#define WM8994_MCLK1_PD_WIDTH 1 /* MCLK1_PD */ +#define WM8994_DACDAT1_PU 0x0020 /* DACDAT1_PU */ +#define WM8994_DACDAT1_PU_MASK 0x0020 /* DACDAT1_PU */ +#define WM8994_DACDAT1_PU_SHIFT 5 /* DACDAT1_PU */ +#define WM8994_DACDAT1_PU_WIDTH 1 /* DACDAT1_PU */ +#define WM8994_DACDAT1_PD 0x0010 /* DACDAT1_PD */ +#define WM8994_DACDAT1_PD_MASK 0x0010 /* DACDAT1_PD */ +#define WM8994_DACDAT1_PD_SHIFT 4 /* DACDAT1_PD */ +#define WM8994_DACDAT1_PD_WIDTH 1 /* DACDAT1_PD */ +#define WM8994_DACLRCLK1_PU 0x0008 /* DACLRCLK1_PU */ +#define WM8994_DACLRCLK1_PU_MASK 0x0008 /* DACLRCLK1_PU */ +#define WM8994_DACLRCLK1_PU_SHIFT 3 /* DACLRCLK1_PU */ +#define WM8994_DACLRCLK1_PU_WIDTH 1 /* DACLRCLK1_PU */ +#define WM8994_DACLRCLK1_PD 0x0004 /* DACLRCLK1_PD */ +#define WM8994_DACLRCLK1_PD_MASK 0x0004 /* DACLRCLK1_PD */ +#define WM8994_DACLRCLK1_PD_SHIFT 2 /* DACLRCLK1_PD */ +#define WM8994_DACLRCLK1_PD_WIDTH 1 /* DACLRCLK1_PD */ +#define WM8994_BCLK1_PU 0x0002 /* BCLK1_PU */ +#define WM8994_BCLK1_PU_MASK 0x0002 /* BCLK1_PU */ +#define WM8994_BCLK1_PU_SHIFT 1 /* BCLK1_PU */ +#define WM8994_BCLK1_PU_WIDTH 1 /* BCLK1_PU */ +#define WM8994_BCLK1_PD 0x0001 /* BCLK1_PD */ +#define WM8994_BCLK1_PD_MASK 0x0001 /* BCLK1_PD */ +#define WM8994_BCLK1_PD_SHIFT 0 /* BCLK1_PD */ +#define WM8994_BCLK1_PD_WIDTH 1 /* BCLK1_PD */ + +/* + * R1825 (0x721) - Pull Control (2) + */ +#define WM8994_CSNADDR_PD 0x0100 /* CSNADDR_PD */ +#define WM8994_CSNADDR_PD_MASK 0x0100 /* CSNADDR_PD */ +#define WM8994_CSNADDR_PD_SHIFT 8 /* CSNADDR_PD */ +#define WM8994_CSNADDR_PD_WIDTH 1 /* CSNADDR_PD */ +#define WM8994_LDO2ENA_PD 0x0040 /* LDO2ENA_PD */ +#define WM8994_LDO2ENA_PD_MASK 0x0040 /* LDO2ENA_PD */ +#define WM8994_LDO2ENA_PD_SHIFT 6 /* LDO2ENA_PD */ +#define WM8994_LDO2ENA_PD_WIDTH 1 /* LDO2ENA_PD */ +#define WM8994_LDO1ENA_PD 0x0010 /* LDO1ENA_PD */ +#define WM8994_LDO1ENA_PD_MASK 0x0010 /* LDO1ENA_PD */ +#define WM8994_LDO1ENA_PD_SHIFT 4 /* LDO1ENA_PD */ +#define WM8994_LDO1ENA_PD_WIDTH 1 /* LDO1ENA_PD */ +#define WM8994_CIFMODE_PD 0x0004 /* CIFMODE_PD */ +#define WM8994_CIFMODE_PD_MASK 0x0004 /* CIFMODE_PD */ +#define WM8994_CIFMODE_PD_SHIFT 2 /* CIFMODE_PD */ +#define WM8994_CIFMODE_PD_WIDTH 1 /* CIFMODE_PD */ +#define WM8994_SPKMODE_PU 0x0002 /* SPKMODE_PU */ +#define WM8994_SPKMODE_PU_MASK 0x0002 /* SPKMODE_PU */ +#define WM8994_SPKMODE_PU_SHIFT 1 /* SPKMODE_PU */ +#define WM8994_SPKMODE_PU_WIDTH 1 /* SPKMODE_PU */ + +/* + * R1840 (0x730) - Interrupt Status 1 + */ +#define WM8994_GP11_EINT 0x0400 /* GP11_EINT */ +#define WM8994_GP11_EINT_MASK 0x0400 /* GP11_EINT */ +#define WM8994_GP11_EINT_SHIFT 10 /* GP11_EINT */ +#define WM8994_GP11_EINT_WIDTH 1 /* GP11_EINT */ +#define WM8994_GP10_EINT 0x0200 /* GP10_EINT */ +#define WM8994_GP10_EINT_MASK 0x0200 /* GP10_EINT */ +#define WM8994_GP10_EINT_SHIFT 9 /* GP10_EINT */ +#define WM8994_GP10_EINT_WIDTH 1 /* GP10_EINT */ +#define WM8994_GP9_EINT 0x0100 /* GP9_EINT */ +#define WM8994_GP9_EINT_MASK 0x0100 /* GP9_EINT */ +#define WM8994_GP9_EINT_SHIFT 8 /* GP9_EINT */ +#define WM8994_GP9_EINT_WIDTH 1 /* GP9_EINT */ +#define WM8994_GP8_EINT 0x0080 /* GP8_EINT */ +#define WM8994_GP8_EINT_MASK 0x0080 /* GP8_EINT */ +#define WM8994_GP8_EINT_SHIFT 7 /* GP8_EINT */ +#define WM8994_GP8_EINT_WIDTH 1 /* GP8_EINT */ +#define WM8994_GP7_EINT 0x0040 /* GP7_EINT */ +#define WM8994_GP7_EINT_MASK 0x0040 /* GP7_EINT */ +#define WM8994_GP7_EINT_SHIFT 6 /* GP7_EINT */ +#define WM8994_GP7_EINT_WIDTH 1 /* GP7_EINT */ +#define WM8994_GP6_EINT 0x0020 /* GP6_EINT */ +#define WM8994_GP6_EINT_MASK 0x0020 /* GP6_EINT */ +#define WM8994_GP6_EINT_SHIFT 5 /* GP6_EINT */ +#define WM8994_GP6_EINT_WIDTH 1 /* GP6_EINT */ +#define WM8994_GP5_EINT 0x0010 /* GP5_EINT */ +#define WM8994_GP5_EINT_MASK 0x0010 /* GP5_EINT */ +#define WM8994_GP5_EINT_SHIFT 4 /* GP5_EINT */ +#define WM8994_GP5_EINT_WIDTH 1 /* GP5_EINT */ +#define WM8994_GP4_EINT 0x0008 /* GP4_EINT */ +#define WM8994_GP4_EINT_MASK 0x0008 /* GP4_EINT */ +#define WM8994_GP4_EINT_SHIFT 3 /* GP4_EINT */ +#define WM8994_GP4_EINT_WIDTH 1 /* GP4_EINT */ +#define WM8994_GP3_EINT 0x0004 /* GP3_EINT */ +#define WM8994_GP3_EINT_MASK 0x0004 /* GP3_EINT */ +#define WM8994_GP3_EINT_SHIFT 2 /* GP3_EINT */ +#define WM8994_GP3_EINT_WIDTH 1 /* GP3_EINT */ +#define WM8994_GP2_EINT 0x0002 /* GP2_EINT */ +#define WM8994_GP2_EINT_MASK 0x0002 /* GP2_EINT */ +#define WM8994_GP2_EINT_SHIFT 1 /* GP2_EINT */ +#define WM8994_GP2_EINT_WIDTH 1 /* GP2_EINT */ +#define WM8994_GP1_EINT 0x0001 /* GP1_EINT */ +#define WM8994_GP1_EINT_MASK 0x0001 /* GP1_EINT */ +#define WM8994_GP1_EINT_SHIFT 0 /* GP1_EINT */ +#define WM8994_GP1_EINT_WIDTH 1 /* GP1_EINT */ + +/* + * R1841 (0x731) - Interrupt Status 2 + */ +#define WM8994_TEMP_WARN_EINT 0x8000 /* TEMP_WARN_EINT */ +#define WM8994_TEMP_WARN_EINT_MASK 0x8000 /* TEMP_WARN_EINT */ +#define WM8994_TEMP_WARN_EINT_SHIFT 15 /* TEMP_WARN_EINT */ +#define WM8994_TEMP_WARN_EINT_WIDTH 1 /* TEMP_WARN_EINT */ +#define WM8994_DCS_DONE_EINT 0x4000 /* DCS_DONE_EINT */ +#define WM8994_DCS_DONE_EINT_MASK 0x4000 /* DCS_DONE_EINT */ +#define WM8994_DCS_DONE_EINT_SHIFT 14 /* DCS_DONE_EINT */ +#define WM8994_DCS_DONE_EINT_WIDTH 1 /* DCS_DONE_EINT */ +#define WM8994_WSEQ_DONE_EINT 0x2000 /* WSEQ_DONE_EINT */ +#define WM8994_WSEQ_DONE_EINT_MASK 0x2000 /* WSEQ_DONE_EINT */ +#define WM8994_WSEQ_DONE_EINT_SHIFT 13 /* WSEQ_DONE_EINT */ +#define WM8994_WSEQ_DONE_EINT_WIDTH 1 /* WSEQ_DONE_EINT */ +#define WM8994_FIFOS_ERR_EINT 0x1000 /* FIFOS_ERR_EINT */ +#define WM8994_FIFOS_ERR_EINT_MASK 0x1000 /* FIFOS_ERR_EINT */ +#define WM8994_FIFOS_ERR_EINT_SHIFT 12 /* FIFOS_ERR_EINT */ +#define WM8994_FIFOS_ERR_EINT_WIDTH 1 /* FIFOS_ERR_EINT */ +#define WM8994_AIF2DRC_SIG_DET_EINT 0x0800 /* AIF2DRC_SIG_DET_EINT */ +#define WM8994_AIF2DRC_SIG_DET_EINT_MASK 0x0800 /* AIF2DRC_SIG_DET_EINT */ +#define WM8994_AIF2DRC_SIG_DET_EINT_SHIFT 11 /* AIF2DRC_SIG_DET_EINT */ +#define WM8994_AIF2DRC_SIG_DET_EINT_WIDTH 1 /* AIF2DRC_SIG_DET_EINT */ +#define WM8994_AIF1DRC2_SIG_DET_EINT 0x0400 /* AIF1DRC2_SIG_DET_EINT */ +#define WM8994_AIF1DRC2_SIG_DET_EINT_MASK 0x0400 /* AIF1DRC2_SIG_DET_EINT */ +#define WM8994_AIF1DRC2_SIG_DET_EINT_SHIFT 10 /* AIF1DRC2_SIG_DET_EINT */ +#define WM8994_AIF1DRC2_SIG_DET_EINT_WIDTH 1 /* AIF1DRC2_SIG_DET_EINT */ +#define WM8994_AIF1DRC1_SIG_DET_EINT 0x0200 /* AIF1DRC1_SIG_DET_EINT */ +#define WM8994_AIF1DRC1_SIG_DET_EINT_MASK 0x0200 /* AIF1DRC1_SIG_DET_EINT */ +#define WM8994_AIF1DRC1_SIG_DET_EINT_SHIFT 9 /* AIF1DRC1_SIG_DET_EINT */ +#define WM8994_AIF1DRC1_SIG_DET_EINT_WIDTH 1 /* AIF1DRC1_SIG_DET_EINT */ +#define WM8994_SRC2_LOCK_EINT 0x0100 /* SRC2_LOCK_EINT */ +#define WM8994_SRC2_LOCK_EINT_MASK 0x0100 /* SRC2_LOCK_EINT */ +#define WM8994_SRC2_LOCK_EINT_SHIFT 8 /* SRC2_LOCK_EINT */ +#define WM8994_SRC2_LOCK_EINT_WIDTH 1 /* SRC2_LOCK_EINT */ +#define WM8994_SRC1_LOCK_EINT 0x0080 /* SRC1_LOCK_EINT */ +#define WM8994_SRC1_LOCK_EINT_MASK 0x0080 /* SRC1_LOCK_EINT */ +#define WM8994_SRC1_LOCK_EINT_SHIFT 7 /* SRC1_LOCK_EINT */ +#define WM8994_SRC1_LOCK_EINT_WIDTH 1 /* SRC1_LOCK_EINT */ +#define WM8994_FLL2_LOCK_EINT 0x0040 /* FLL2_LOCK_EINT */ +#define WM8994_FLL2_LOCK_EINT_MASK 0x0040 /* FLL2_LOCK_EINT */ +#define WM8994_FLL2_LOCK_EINT_SHIFT 6 /* FLL2_LOCK_EINT */ +#define WM8994_FLL2_LOCK_EINT_WIDTH 1 /* FLL2_LOCK_EINT */ +#define WM8994_FLL1_LOCK_EINT 0x0020 /* FLL1_LOCK_EINT */ +#define WM8994_FLL1_LOCK_EINT_MASK 0x0020 /* FLL1_LOCK_EINT */ +#define WM8994_FLL1_LOCK_EINT_SHIFT 5 /* FLL1_LOCK_EINT */ +#define WM8994_FLL1_LOCK_EINT_WIDTH 1 /* FLL1_LOCK_EINT */ +#define WM8994_MIC2_SHRT_EINT 0x0010 /* MIC2_SHRT_EINT */ +#define WM8994_MIC2_SHRT_EINT_MASK 0x0010 /* MIC2_SHRT_EINT */ +#define WM8994_MIC2_SHRT_EINT_SHIFT 4 /* MIC2_SHRT_EINT */ +#define WM8994_MIC2_SHRT_EINT_WIDTH 1 /* MIC2_SHRT_EINT */ +#define WM8994_MIC2_DET_EINT 0x0008 /* MIC2_DET_EINT */ +#define WM8994_MIC2_DET_EINT_MASK 0x0008 /* MIC2_DET_EINT */ +#define WM8994_MIC2_DET_EINT_SHIFT 3 /* MIC2_DET_EINT */ +#define WM8994_MIC2_DET_EINT_WIDTH 1 /* MIC2_DET_EINT */ +#define WM8994_MIC1_SHRT_EINT 0x0004 /* MIC1_SHRT_EINT */ +#define WM8994_MIC1_SHRT_EINT_MASK 0x0004 /* MIC1_SHRT_EINT */ +#define WM8994_MIC1_SHRT_EINT_SHIFT 2 /* MIC1_SHRT_EINT */ +#define WM8994_MIC1_SHRT_EINT_WIDTH 1 /* MIC1_SHRT_EINT */ +#define WM8994_MIC1_DET_EINT 0x0002 /* MIC1_DET_EINT */ +#define WM8994_MIC1_DET_EINT_MASK 0x0002 /* MIC1_DET_EINT */ +#define WM8994_MIC1_DET_EINT_SHIFT 1 /* MIC1_DET_EINT */ +#define WM8994_MIC1_DET_EINT_WIDTH 1 /* MIC1_DET_EINT */ +#define WM8994_TEMP_SHUT_EINT 0x0001 /* TEMP_SHUT_EINT */ +#define WM8994_TEMP_SHUT_EINT_MASK 0x0001 /* TEMP_SHUT_EINT */ +#define WM8994_TEMP_SHUT_EINT_SHIFT 0 /* TEMP_SHUT_EINT */ +#define WM8994_TEMP_SHUT_EINT_WIDTH 1 /* TEMP_SHUT_EINT */ + +/* + * R1842 (0x732) - Interrupt Raw Status 2 + */ +#define WM8994_TEMP_WARN_STS 0x8000 /* TEMP_WARN_STS */ +#define WM8994_TEMP_WARN_STS_MASK 0x8000 /* TEMP_WARN_STS */ +#define WM8994_TEMP_WARN_STS_SHIFT 15 /* TEMP_WARN_STS */ +#define WM8994_TEMP_WARN_STS_WIDTH 1 /* TEMP_WARN_STS */ +#define WM8994_DCS_DONE_STS 0x4000 /* DCS_DONE_STS */ +#define WM8994_DCS_DONE_STS_MASK 0x4000 /* DCS_DONE_STS */ +#define WM8994_DCS_DONE_STS_SHIFT 14 /* DCS_DONE_STS */ +#define WM8994_DCS_DONE_STS_WIDTH 1 /* DCS_DONE_STS */ +#define WM8994_WSEQ_DONE_STS 0x2000 /* WSEQ_DONE_STS */ +#define WM8994_WSEQ_DONE_STS_MASK 0x2000 /* WSEQ_DONE_STS */ +#define WM8994_WSEQ_DONE_STS_SHIFT 13 /* WSEQ_DONE_STS */ +#define WM8994_WSEQ_DONE_STS_WIDTH 1 /* WSEQ_DONE_STS */ +#define WM8994_FIFOS_ERR_STS 0x1000 /* FIFOS_ERR_STS */ +#define WM8994_FIFOS_ERR_STS_MASK 0x1000 /* FIFOS_ERR_STS */ +#define WM8994_FIFOS_ERR_STS_SHIFT 12 /* FIFOS_ERR_STS */ +#define WM8994_FIFOS_ERR_STS_WIDTH 1 /* FIFOS_ERR_STS */ +#define WM8994_AIF2DRC_SIG_DET_STS 0x0800 /* AIF2DRC_SIG_DET_STS */ +#define WM8994_AIF2DRC_SIG_DET_STS_MASK 0x0800 /* AIF2DRC_SIG_DET_STS */ +#define WM8994_AIF2DRC_SIG_DET_STS_SHIFT 11 /* AIF2DRC_SIG_DET_STS */ +#define WM8994_AIF2DRC_SIG_DET_STS_WIDTH 1 /* AIF2DRC_SIG_DET_STS */ +#define WM8994_AIF1DRC2_SIG_DET_STS 0x0400 /* AIF1DRC2_SIG_DET_STS */ +#define WM8994_AIF1DRC2_SIG_DET_STS_MASK 0x0400 /* AIF1DRC2_SIG_DET_STS */ +#define WM8994_AIF1DRC2_SIG_DET_STS_SHIFT 10 /* AIF1DRC2_SIG_DET_STS */ +#define WM8994_AIF1DRC2_SIG_DET_STS_WIDTH 1 /* AIF1DRC2_SIG_DET_STS */ +#define WM8994_AIF1DRC1_SIG_DET_STS 0x0200 /* AIF1DRC1_SIG_DET_STS */ +#define WM8994_AIF1DRC1_SIG_DET_STS_MASK 0x0200 /* AIF1DRC1_SIG_DET_STS */ +#define WM8994_AIF1DRC1_SIG_DET_STS_SHIFT 9 /* AIF1DRC1_SIG_DET_STS */ +#define WM8994_AIF1DRC1_SIG_DET_STS_WIDTH 1 /* AIF1DRC1_SIG_DET_STS */ +#define WM8994_SRC2_LOCK_STS 0x0100 /* SRC2_LOCK_STS */ +#define WM8994_SRC2_LOCK_STS_MASK 0x0100 /* SRC2_LOCK_STS */ +#define WM8994_SRC2_LOCK_STS_SHIFT 8 /* SRC2_LOCK_STS */ +#define WM8994_SRC2_LOCK_STS_WIDTH 1 /* SRC2_LOCK_STS */ +#define WM8994_SRC1_LOCK_STS 0x0080 /* SRC1_LOCK_STS */ +#define WM8994_SRC1_LOCK_STS_MASK 0x0080 /* SRC1_LOCK_STS */ +#define WM8994_SRC1_LOCK_STS_SHIFT 7 /* SRC1_LOCK_STS */ +#define WM8994_SRC1_LOCK_STS_WIDTH 1 /* SRC1_LOCK_STS */ +#define WM8994_FLL2_LOCK_STS 0x0040 /* FLL2_LOCK_STS */ +#define WM8994_FLL2_LOCK_STS_MASK 0x0040 /* FLL2_LOCK_STS */ +#define WM8994_FLL2_LOCK_STS_SHIFT 6 /* FLL2_LOCK_STS */ +#define WM8994_FLL2_LOCK_STS_WIDTH 1 /* FLL2_LOCK_STS */ +#define WM8994_FLL1_LOCK_STS 0x0020 /* FLL1_LOCK_STS */ +#define WM8994_FLL1_LOCK_STS_MASK 0x0020 /* FLL1_LOCK_STS */ +#define WM8994_FLL1_LOCK_STS_SHIFT 5 /* FLL1_LOCK_STS */ +#define WM8994_FLL1_LOCK_STS_WIDTH 1 /* FLL1_LOCK_STS */ +#define WM8994_MIC2_SHRT_STS 0x0010 /* MIC2_SHRT_STS */ +#define WM8994_MIC2_SHRT_STS_MASK 0x0010 /* MIC2_SHRT_STS */ +#define WM8994_MIC2_SHRT_STS_SHIFT 4 /* MIC2_SHRT_STS */ +#define WM8994_MIC2_SHRT_STS_WIDTH 1 /* MIC2_SHRT_STS */ +#define WM8994_MIC2_DET_STS 0x0008 /* MIC2_DET_STS */ +#define WM8994_MIC2_DET_STS_MASK 0x0008 /* MIC2_DET_STS */ +#define WM8994_MIC2_DET_STS_SHIFT 3 /* MIC2_DET_STS */ +#define WM8994_MIC2_DET_STS_WIDTH 1 /* MIC2_DET_STS */ +#define WM8994_MIC1_SHRT_STS 0x0004 /* MIC1_SHRT_STS */ +#define WM8994_MIC1_SHRT_STS_MASK 0x0004 /* MIC1_SHRT_STS */ +#define WM8994_MIC1_SHRT_STS_SHIFT 2 /* MIC1_SHRT_STS */ +#define WM8994_MIC1_SHRT_STS_WIDTH 1 /* MIC1_SHRT_STS */ +#define WM8994_MIC1_DET_STS 0x0002 /* MIC1_DET_STS */ +#define WM8994_MIC1_DET_STS_MASK 0x0002 /* MIC1_DET_STS */ +#define WM8994_MIC1_DET_STS_SHIFT 1 /* MIC1_DET_STS */ +#define WM8994_MIC1_DET_STS_WIDTH 1 /* MIC1_DET_STS */ +#define WM8994_TEMP_SHUT_STS 0x0001 /* TEMP_SHUT_STS */ +#define WM8994_TEMP_SHUT_STS_MASK 0x0001 /* TEMP_SHUT_STS */ +#define WM8994_TEMP_SHUT_STS_SHIFT 0 /* TEMP_SHUT_STS */ +#define WM8994_TEMP_SHUT_STS_WIDTH 1 /* TEMP_SHUT_STS */ + +/* + * R1848 (0x738) - Interrupt Status 1 Mask + */ +#define WM8994_IM_GP11_EINT 0x0400 /* IM_GP11_EINT */ +#define WM8994_IM_GP11_EINT_MASK 0x0400 /* IM_GP11_EINT */ +#define WM8994_IM_GP11_EINT_SHIFT 10 /* IM_GP11_EINT */ +#define WM8994_IM_GP11_EINT_WIDTH 1 /* IM_GP11_EINT */ +#define WM8994_IM_GP10_EINT 0x0200 /* IM_GP10_EINT */ +#define WM8994_IM_GP10_EINT_MASK 0x0200 /* IM_GP10_EINT */ +#define WM8994_IM_GP10_EINT_SHIFT 9 /* IM_GP10_EINT */ +#define WM8994_IM_GP10_EINT_WIDTH 1 /* IM_GP10_EINT */ +#define WM8994_IM_GP9_EINT 0x0100 /* IM_GP9_EINT */ +#define WM8994_IM_GP9_EINT_MASK 0x0100 /* IM_GP9_EINT */ +#define WM8994_IM_GP9_EINT_SHIFT 8 /* IM_GP9_EINT */ +#define WM8994_IM_GP9_EINT_WIDTH 1 /* IM_GP9_EINT */ +#define WM8994_IM_GP8_EINT 0x0080 /* IM_GP8_EINT */ +#define WM8994_IM_GP8_EINT_MASK 0x0080 /* IM_GP8_EINT */ +#define WM8994_IM_GP8_EINT_SHIFT 7 /* IM_GP8_EINT */ +#define WM8994_IM_GP8_EINT_WIDTH 1 /* IM_GP8_EINT */ +#define WM8994_IM_GP7_EINT 0x0040 /* IM_GP7_EINT */ +#define WM8994_IM_GP7_EINT_MASK 0x0040 /* IM_GP7_EINT */ +#define WM8994_IM_GP7_EINT_SHIFT 6 /* IM_GP7_EINT */ +#define WM8994_IM_GP7_EINT_WIDTH 1 /* IM_GP7_EINT */ +#define WM8994_IM_GP6_EINT 0x0020 /* IM_GP6_EINT */ +#define WM8994_IM_GP6_EINT_MASK 0x0020 /* IM_GP6_EINT */ +#define WM8994_IM_GP6_EINT_SHIFT 5 /* IM_GP6_EINT */ +#define WM8994_IM_GP6_EINT_WIDTH 1 /* IM_GP6_EINT */ +#define WM8994_IM_GP5_EINT 0x0010 /* IM_GP5_EINT */ +#define WM8994_IM_GP5_EINT_MASK 0x0010 /* IM_GP5_EINT */ +#define WM8994_IM_GP5_EINT_SHIFT 4 /* IM_GP5_EINT */ +#define WM8994_IM_GP5_EINT_WIDTH 1 /* IM_GP5_EINT */ +#define WM8994_IM_GP4_EINT 0x0008 /* IM_GP4_EINT */ +#define WM8994_IM_GP4_EINT_MASK 0x0008 /* IM_GP4_EINT */ +#define WM8994_IM_GP4_EINT_SHIFT 3 /* IM_GP4_EINT */ +#define WM8994_IM_GP4_EINT_WIDTH 1 /* IM_GP4_EINT */ +#define WM8994_IM_GP3_EINT 0x0004 /* IM_GP3_EINT */ +#define WM8994_IM_GP3_EINT_MASK 0x0004 /* IM_GP3_EINT */ +#define WM8994_IM_GP3_EINT_SHIFT 2 /* IM_GP3_EINT */ +#define WM8994_IM_GP3_EINT_WIDTH 1 /* IM_GP3_EINT */ +#define WM8994_IM_GP2_EINT 0x0002 /* IM_GP2_EINT */ +#define WM8994_IM_GP2_EINT_MASK 0x0002 /* IM_GP2_EINT */ +#define WM8994_IM_GP2_EINT_SHIFT 1 /* IM_GP2_EINT */ +#define WM8994_IM_GP2_EINT_WIDTH 1 /* IM_GP2_EINT */ +#define WM8994_IM_GP1_EINT 0x0001 /* IM_GP1_EINT */ +#define WM8994_IM_GP1_EINT_MASK 0x0001 /* IM_GP1_EINT */ +#define WM8994_IM_GP1_EINT_SHIFT 0 /* IM_GP1_EINT */ +#define WM8994_IM_GP1_EINT_WIDTH 1 /* IM_GP1_EINT */ + +/* + * R1849 (0x739) - Interrupt Status 2 Mask + */ +#define WM8994_IM_TEMP_WARN_EINT 0x8000 /* IM_TEMP_WARN_EINT */ +#define WM8994_IM_TEMP_WARN_EINT_MASK 0x8000 /* IM_TEMP_WARN_EINT */ +#define WM8994_IM_TEMP_WARN_EINT_SHIFT 15 /* IM_TEMP_WARN_EINT */ +#define WM8994_IM_TEMP_WARN_EINT_WIDTH 1 /* IM_TEMP_WARN_EINT */ +#define WM8994_IM_DCS_DONE_EINT 0x4000 /* IM_DCS_DONE_EINT */ +#define WM8994_IM_DCS_DONE_EINT_MASK 0x4000 /* IM_DCS_DONE_EINT */ +#define WM8994_IM_DCS_DONE_EINT_SHIFT 14 /* IM_DCS_DONE_EINT */ +#define WM8994_IM_DCS_DONE_EINT_WIDTH 1 /* IM_DCS_DONE_EINT */ +#define WM8994_IM_WSEQ_DONE_EINT 0x2000 /* IM_WSEQ_DONE_EINT */ +#define WM8994_IM_WSEQ_DONE_EINT_MASK 0x2000 /* IM_WSEQ_DONE_EINT */ +#define WM8994_IM_WSEQ_DONE_EINT_SHIFT 13 /* IM_WSEQ_DONE_EINT */ +#define WM8994_IM_WSEQ_DONE_EINT_WIDTH 1 /* IM_WSEQ_DONE_EINT */ +#define WM8994_IM_FIFOS_ERR_EINT 0x1000 /* IM_FIFOS_ERR_EINT */ +#define WM8994_IM_FIFOS_ERR_EINT_MASK 0x1000 /* IM_FIFOS_ERR_EINT */ +#define WM8994_IM_FIFOS_ERR_EINT_SHIFT 12 /* IM_FIFOS_ERR_EINT */ +#define WM8994_IM_FIFOS_ERR_EINT_WIDTH 1 /* IM_FIFOS_ERR_EINT */ +#define WM8994_IM_AIF2DRC_SIG_DET_EINT 0x0800 /* IM_AIF2DRC_SIG_DET_EINT */ +#define WM8994_IM_AIF2DRC_SIG_DET_EINT_MASK 0x0800 /* IM_AIF2DRC_SIG_DET_EINT */ +#define WM8994_IM_AIF2DRC_SIG_DET_EINT_SHIFT 11 /* IM_AIF2DRC_SIG_DET_EINT */ +#define WM8994_IM_AIF2DRC_SIG_DET_EINT_WIDTH 1 /* IM_AIF2DRC_SIG_DET_EINT */ +#define WM8994_IM_AIF1DRC2_SIG_DET_EINT 0x0400 /* IM_AIF1DRC2_SIG_DET_EINT */ +#define WM8994_IM_AIF1DRC2_SIG_DET_EINT_MASK 0x0400 /* IM_AIF1DRC2_SIG_DET_EINT */ +#define WM8994_IM_AIF1DRC2_SIG_DET_EINT_SHIFT 10 /* IM_AIF1DRC2_SIG_DET_EINT */ +#define WM8994_IM_AIF1DRC2_SIG_DET_EINT_WIDTH 1 /* IM_AIF1DRC2_SIG_DET_EINT */ +#define WM8994_IM_AIF1DRC1_SIG_DET_EINT 0x0200 /* IM_AIF1DRC1_SIG_DET_EINT */ +#define WM8994_IM_AIF1DRC1_SIG_DET_EINT_MASK 0x0200 /* IM_AIF1DRC1_SIG_DET_EINT */ +#define WM8994_IM_AIF1DRC1_SIG_DET_EINT_SHIFT 9 /* IM_AIF1DRC1_SIG_DET_EINT */ +#define WM8994_IM_AIF1DRC1_SIG_DET_EINT_WIDTH 1 /* IM_AIF1DRC1_SIG_DET_EINT */ +#define WM8994_IM_SRC2_LOCK_EINT 0x0100 /* IM_SRC2_LOCK_EINT */ +#define WM8994_IM_SRC2_LOCK_EINT_MASK 0x0100 /* IM_SRC2_LOCK_EINT */ +#define WM8994_IM_SRC2_LOCK_EINT_SHIFT 8 /* IM_SRC2_LOCK_EINT */ +#define WM8994_IM_SRC2_LOCK_EINT_WIDTH 1 /* IM_SRC2_LOCK_EINT */ +#define WM8994_IM_SRC1_LOCK_EINT 0x0080 /* IM_SRC1_LOCK_EINT */ +#define WM8994_IM_SRC1_LOCK_EINT_MASK 0x0080 /* IM_SRC1_LOCK_EINT */ +#define WM8994_IM_SRC1_LOCK_EINT_SHIFT 7 /* IM_SRC1_LOCK_EINT */ +#define WM8994_IM_SRC1_LOCK_EINT_WIDTH 1 /* IM_SRC1_LOCK_EINT */ +#define WM8994_IM_FLL2_LOCK_EINT 0x0040 /* IM_FLL2_LOCK_EINT */ +#define WM8994_IM_FLL2_LOCK_EINT_MASK 0x0040 /* IM_FLL2_LOCK_EINT */ +#define WM8994_IM_FLL2_LOCK_EINT_SHIFT 6 /* IM_FLL2_LOCK_EINT */ +#define WM8994_IM_FLL2_LOCK_EINT_WIDTH 1 /* IM_FLL2_LOCK_EINT */ +#define WM8994_IM_FLL1_LOCK_EINT 0x0020 /* IM_FLL1_LOCK_EINT */ +#define WM8994_IM_FLL1_LOCK_EINT_MASK 0x0020 /* IM_FLL1_LOCK_EINT */ +#define WM8994_IM_FLL1_LOCK_EINT_SHIFT 5 /* IM_FLL1_LOCK_EINT */ +#define WM8994_IM_FLL1_LOCK_EINT_WIDTH 1 /* IM_FLL1_LOCK_EINT */ +#define WM8994_IM_MIC2_SHRT_EINT 0x0010 /* IM_MIC2_SHRT_EINT */ +#define WM8994_IM_MIC2_SHRT_EINT_MASK 0x0010 /* IM_MIC2_SHRT_EINT */ +#define WM8994_IM_MIC2_SHRT_EINT_SHIFT 4 /* IM_MIC2_SHRT_EINT */ +#define WM8994_IM_MIC2_SHRT_EINT_WIDTH 1 /* IM_MIC2_SHRT_EINT */ +#define WM8994_IM_MIC2_DET_EINT 0x0008 /* IM_MIC2_DET_EINT */ +#define WM8994_IM_MIC2_DET_EINT_MASK 0x0008 /* IM_MIC2_DET_EINT */ +#define WM8994_IM_MIC2_DET_EINT_SHIFT 3 /* IM_MIC2_DET_EINT */ +#define WM8994_IM_MIC2_DET_EINT_WIDTH 1 /* IM_MIC2_DET_EINT */ +#define WM8994_IM_MIC1_SHRT_EINT 0x0004 /* IM_MIC1_SHRT_EINT */ +#define WM8994_IM_MIC1_SHRT_EINT_MASK 0x0004 /* IM_MIC1_SHRT_EINT */ +#define WM8994_IM_MIC1_SHRT_EINT_SHIFT 2 /* IM_MIC1_SHRT_EINT */ +#define WM8994_IM_MIC1_SHRT_EINT_WIDTH 1 /* IM_MIC1_SHRT_EINT */ +#define WM8994_IM_MIC1_DET_EINT 0x0002 /* IM_MIC1_DET_EINT */ +#define WM8994_IM_MIC1_DET_EINT_MASK 0x0002 /* IM_MIC1_DET_EINT */ +#define WM8994_IM_MIC1_DET_EINT_SHIFT 1 /* IM_MIC1_DET_EINT */ +#define WM8994_IM_MIC1_DET_EINT_WIDTH 1 /* IM_MIC1_DET_EINT */ +#define WM8994_IM_TEMP_SHUT_EINT 0x0001 /* IM_TEMP_SHUT_EINT */ +#define WM8994_IM_TEMP_SHUT_EINT_MASK 0x0001 /* IM_TEMP_SHUT_EINT */ +#define WM8994_IM_TEMP_SHUT_EINT_SHIFT 0 /* IM_TEMP_SHUT_EINT */ +#define WM8994_IM_TEMP_SHUT_EINT_WIDTH 1 /* IM_TEMP_SHUT_EINT */ + +/* + * R1856 (0x740) - Interrupt Control + */ +#define WM8994_IM_IRQ 0x0001 /* IM_IRQ */ +#define WM8994_IM_IRQ_MASK 0x0001 /* IM_IRQ */ +#define WM8994_IM_IRQ_SHIFT 0 /* IM_IRQ */ +#define WM8994_IM_IRQ_WIDTH 1 /* IM_IRQ */ + +/* + * R1864 (0x748) - IRQ Debounce + */ +#define WM8994_TEMP_WARN_DB 0x0020 /* TEMP_WARN_DB */ +#define WM8994_TEMP_WARN_DB_MASK 0x0020 /* TEMP_WARN_DB */ +#define WM8994_TEMP_WARN_DB_SHIFT 5 /* TEMP_WARN_DB */ +#define WM8994_TEMP_WARN_DB_WIDTH 1 /* TEMP_WARN_DB */ +#define WM8994_MIC2_SHRT_DB 0x0010 /* MIC2_SHRT_DB */ +#define WM8994_MIC2_SHRT_DB_MASK 0x0010 /* MIC2_SHRT_DB */ +#define WM8994_MIC2_SHRT_DB_SHIFT 4 /* MIC2_SHRT_DB */ +#define WM8994_MIC2_SHRT_DB_WIDTH 1 /* MIC2_SHRT_DB */ +#define WM8994_MIC2_DET_DB 0x0008 /* MIC2_DET_DB */ +#define WM8994_MIC2_DET_DB_MASK 0x0008 /* MIC2_DET_DB */ +#define WM8994_MIC2_DET_DB_SHIFT 3 /* MIC2_DET_DB */ +#define WM8994_MIC2_DET_DB_WIDTH 1 /* MIC2_DET_DB */ +#define WM8994_MIC1_SHRT_DB 0x0004 /* MIC1_SHRT_DB */ +#define WM8994_MIC1_SHRT_DB_MASK 0x0004 /* MIC1_SHRT_DB */ +#define WM8994_MIC1_SHRT_DB_SHIFT 2 /* MIC1_SHRT_DB */ +#define WM8994_MIC1_SHRT_DB_WIDTH 1 /* MIC1_SHRT_DB */ +#define WM8994_MIC1_DET_DB 0x0002 /* MIC1_DET_DB */ +#define WM8994_MIC1_DET_DB_MASK 0x0002 /* MIC1_DET_DB */ +#define WM8994_MIC1_DET_DB_SHIFT 1 /* MIC1_DET_DB */ +#define WM8994_MIC1_DET_DB_WIDTH 1 /* MIC1_DET_DB */ +#define WM8994_TEMP_SHUT_DB 0x0001 /* TEMP_SHUT_DB */ +#define WM8994_TEMP_SHUT_DB_MASK 0x0001 /* TEMP_SHUT_DB */ +#define WM8994_TEMP_SHUT_DB_SHIFT 0 /* TEMP_SHUT_DB */ +#define WM8994_TEMP_SHUT_DB_WIDTH 1 /* TEMP_SHUT_DB */ + +#endif diff --git a/include/linux/pm.h b/include/linux/pm.h index e80df06..8e258c7 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -215,20 +215,59 @@ struct dev_pm_ops { int (*runtime_idle)(struct device *dev); }; +#ifdef CONFIG_PM_SLEEP +#define SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ + .suspend = suspend_fn, \ + .resume = resume_fn, \ + .freeze = suspend_fn, \ + .thaw = resume_fn, \ + .poweroff = suspend_fn, \ + .restore = resume_fn, +#else +#define SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) +#endif + +#ifdef CONFIG_PM_RUNTIME +#define SET_RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn) \ + .runtime_suspend = suspend_fn, \ + .runtime_resume = resume_fn, \ + .runtime_idle = idle_fn, +#else +#define SET_RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn) +#endif + /* * Use this if you want to use the same suspend and resume callbacks for suspend * to RAM and hibernation. */ #define SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \ const struct dev_pm_ops name = { \ - .suspend = suspend_fn, \ - .resume = resume_fn, \ - .freeze = suspend_fn, \ - .thaw = resume_fn, \ - .poweroff = suspend_fn, \ - .restore = resume_fn, \ + SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ +} + +/* + * Use this for defining a set of PM operations to be used in all situations + * (sustem suspend, hibernation or runtime PM). + */ +#define UNIVERSAL_DEV_PM_OPS(name, suspend_fn, resume_fn, idle_fn) \ +const struct dev_pm_ops name = { \ + SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ + SET_RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn) \ } +/* + * Use this for subsystems (bus types, device types, device classes) that don't + * need any special suspend/resume handling in addition to invoking the PM + * callbacks provided by device drivers supporting both the system sleep PM and + * runtime PM, make the pm member point to generic_subsys_pm_ops. + */ +#ifdef CONFIG_PM_OPS +extern struct dev_pm_ops generic_subsys_pm_ops; +#define GENERIC_SUBSYS_PM_OPS (&generic_subsys_pm_ops) +#else +#define GENERIC_SUBSYS_PM_OPS NULL +#endif + /** * PM_EVENT_ messages * diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h index 7d773aa..b776db7 100644 --- a/include/linux/pm_runtime.h +++ b/include/linux/pm_runtime.h @@ -62,6 +62,11 @@ static inline void device_set_run_wake(struct device *dev, bool enable) dev->power.run_wake = enable; } +static inline bool pm_runtime_suspended(struct device *dev) +{ + return dev->power.runtime_status == RPM_SUSPENDED; +} + #else /* !CONFIG_PM_RUNTIME */ static inline int pm_runtime_idle(struct device *dev) { return -ENOSYS; } @@ -89,6 +94,7 @@ static inline void pm_runtime_get_noresume(struct device *dev) {} static inline void pm_runtime_put_noidle(struct device *dev) {} static inline bool device_run_wake(struct device *dev) { return false; } static inline void device_set_run_wake(struct device *dev, bool enable) {} +static inline bool pm_runtime_suspended(struct device *dev) { return false; } #endif /* !CONFIG_PM_RUNTIME */ diff --git a/include/linux/serial_sci.h b/include/linux/serial_sci.h index 1c297dd..1b177d2 100644 --- a/include/linux/serial_sci.h +++ b/include/linux/serial_sci.h @@ -2,6 +2,7 @@ #define __LINUX_SERIAL_SCI_H #include <linux/serial_core.h> +#include <asm/dmaengine.h> /* * Generic header for SuperH SCI(F) (used by sh/sh64/h8300 and related parts) @@ -16,6 +17,8 @@ enum { SCIx_NR_IRQS, }; +struct device; + /* * Platform device specific platform_data struct */ @@ -26,6 +29,9 @@ struct plat_sci_port { unsigned int type; /* SCI / SCIF / IRDA */ upf_t flags; /* UPF_* flags */ char *clk; /* clock string */ + struct device *dma_dev; + enum sh_dmae_slave_chan_id dma_slave_tx; + enum sh_dmae_slave_chan_id dma_slave_rx; }; #endif /* __LINUX_SERIAL_SCI_H */ diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index 718ef91..df2c6d9 100644 --- a/sound/soc/codecs/wm8350.c +++ b/sound/soc/codecs/wm8350.c @@ -1349,7 +1349,7 @@ static irqreturn_t wm8350_hp_jack_handler(int irq, void *data) int mask; struct wm8350_jack_data *jack = NULL; - switch (irq) { + switch (irq - wm8350->irq_base) { case WM8350_IRQ_CODEC_JCK_DET_L: jack = &priv->hpl; mask = WM8350_JACK_L_LVL; @@ -1424,7 +1424,7 @@ int wm8350_hp_jack_detect(struct snd_soc_codec *codec, enum wm8350_jack which, wm8350_set_bits(wm8350, WM8350_JACK_DETECT, ena); /* Sync status */ - wm8350_hp_jack_handler(irq, priv); + wm8350_hp_jack_handler(irq + wm8350->irq_base, priv); return 0; } @@ -1521,8 +1521,8 @@ static int wm8350_remove(struct platform_device *pdev) WM8350_JDL_ENA | WM8350_JDR_ENA); wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_TOCLK_ENA); - wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L); - wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R); + wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L, priv); + wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R, priv); priv->hpl.jack = NULL; priv->hpr.jack = NULL; diff --git a/sound/soc/sh/siu.h b/sound/soc/sh/siu.h index 9cc04ab..c0bfab8 100644 --- a/sound/soc/sh/siu.h +++ b/sound/soc/sh/siu.h @@ -72,7 +72,7 @@ struct siu_firmware { #include <linux/interrupt.h> #include <linux/io.h> -#include <asm/dma-sh.h> +#include <asm/dmaengine.h> #include <sound/core.h> #include <sound/pcm.h> diff --git a/sound/soc/sh/siu_pcm.c b/sound/soc/sh/siu_pcm.c index c5efc30..ba7f8d0 100644 --- a/sound/soc/sh/siu_pcm.c +++ b/sound/soc/sh/siu_pcm.c @@ -32,7 +32,7 @@ #include <sound/pcm_params.h> #include <sound/soc-dai.h> -#include <asm/dma-sh.h> +#include <asm/dmaengine.h> #include <asm/siu.h> #include "siu.h" |