From 15f7fabcb88e67792e49279de0b28d70fcfca0cd Mon Sep 17 00:00:00 2001 From: =?utf8?q?=E9=BB=84=E6=B6=9B?= Date: Fri, 28 Oct 2011 15:41:18 +0800 Subject: [PATCH] temp revert rk change --- .gitignore | 3 - arch/arm/boot/compressed/head.S | 4 - arch/arm/common/gic.c | 18 - arch/arm/kernel/Makefile | 3 +- arch/arm/mm/proc-v7.S | 11 - arch/arm/tools/mach-types | 4 +- arch/arm/vfp/vfphw.S | 17 - drivers/Kconfig | 13 - drivers/Makefile | 11 +- drivers/base/power/main.c | 6 - drivers/char/Makefile | 1 - drivers/cpufreq/cpufreq_ondemand.c | 5 - drivers/gpio/gpiolib.c | 79 +- drivers/gpio/tps65910-gpio.c | 364 - drivers/input/Makefile | 5 - drivers/input/keyboard/Kconfig | 34 - drivers/input/keyboard/Makefile | 5 - drivers/input/touchscreen/Kconfig | 269 - drivers/media/video/Makefile | 28 +- drivers/media/video/ov2640.c | 2968 -------- drivers/media/video/soc_camera.c | 174 +- drivers/media/video/uvc/uvc_v4l2.c | 21 +- drivers/media/video/v4l2-ioctl.c | 6 +- drivers/mfd/Kconfig | 49 +- drivers/mfd/Makefile | 5 - drivers/mfd/wm831x-core.c | 252 +- drivers/mfd/wm831x-i2c.c | 188 - drivers/mfd/wm831x-irq.c | 216 +- drivers/mfd/wm831x-spi.c | 250 - drivers/mfd/wm8994-core.c | 51 +- drivers/misc/Kconfig | 27 +- drivers/misc/Makefile | 11 +- drivers/misc/apanic.c | 19 +- drivers/misc/pmem.c | 8 +- drivers/mmc/card/block.c | 86 +- drivers/mmc/core/core.c | 205 +- drivers/mmc/core/mmc.c | 38 +- drivers/mmc/core/sd.c | 69 +- drivers/mmc/core/sdio.c | 21 +- drivers/mmc/host/Makefile | 6 - drivers/net/wireless/Kconfig | 313 +- drivers/net/wireless/Makefile | 59 +- drivers/net/wireless/bcm4329/Kconfig | 2 +- drivers/net/wireless/bcm4329/Makefile | 11 +- drivers/net/wireless/bcm4329/bcmsdh_linux.c | 12 +- .../net/wireless/bcm4329/bcmsdh_sdmmc_linux.c | 10 +- drivers/net/wireless/bcm4329/dhd.h | 25 +- drivers/net/wireless/bcm4329/dhd_cdc.c | 3 - drivers/net/wireless/bcm4329/dhd_common.c | 135 +- .../net/wireless/bcm4329/dhd_custom_gpio.c | 95 +- drivers/net/wireless/bcm4329/dhd_linux.c | 150 +- drivers/net/wireless/bcm4329/dhd_sdio.c | 60 - .../net/wireless/bcm4329/include/epivers.h | 10 +- .../net/wireless/bcm4329/include/wlioctl.h | 25 +- drivers/net/wireless/bcm4329/linux_osl.c | 4 +- drivers/net/wireless/bcm4329/wl_iw.c | 364 +- drivers/net/wireless/bcm4329/wl_iw.h | 56 +- drivers/power/wm831x_power.c | 712 +- drivers/regulator/Makefile | 6 - drivers/regulator/core.c | 16 - drivers/regulator/tps65910-regulator.c | 767 -- drivers/regulator/wm831x-dcdc.c | 132 +- drivers/regulator/wm831x-isink.c | 17 +- drivers/regulator/wm831x-ldo.c | 106 +- drivers/rtc/Kconfig | 32 - drivers/rtc/Makefile | 4 - drivers/rtc/alarm.c | 15 - drivers/serial/Kconfig | 62 - drivers/serial/Makefile | 6 - drivers/staging/Kconfig | 3 - drivers/staging/Makefile | 2 - drivers/staging/android/timed_gpio.c | 61 +- drivers/staging/android/timed_gpio.h | 1 - drivers/usb/Makefile | 2 - drivers/usb/gadget/Kconfig | 17 +- drivers/usb/gadget/android.c | 6 +- drivers/usb/gadget/f_adb.c | 2 +- drivers/usb/gadget/f_mass_storage.c | 293 - drivers/usb/gadget/storage_common.c | 7 - drivers/usb/serial/option.c | 51 - drivers/video/backlight/wm831x_bl.c | 121 +- fs/fat/dir.c | 2 +- fs/fat/fatent.c | 4 +- fs/fat/inode.c | 4 +- fs/yaffs2/yaffs_fs.c | 3 - fs/yaffs2/yaffs_mtdif2.c | 5 - include/linux/i2c.h | 18 - include/linux/mfd/wm831x/core.h | 63 - include/linux/mfd/wm831x/pdata.h | 30 +- include/linux/mfd/wm8994/core.h | 53 +- include/linux/mfd/wm8994/pdata.h | 35 +- include/linux/mmc/host.h | 6 - include/linux/regulator/consumer.h | 10 - include/linux/wakelock.h | 2 - include/media/v4l2-chip-ident.h | 29 +- kernel/power/earlysuspend.c | 12 +- kernel/power/process.c | 1 - kernel/power/wakelock.c | 41 +- kernel/sys.c | 37 +- mm/page_alloc.c | 3 +- sound/soc/codecs/Kconfig | 24 +- sound/soc/codecs/Makefile | 13 +- sound/soc/codecs/wm8900.c | 784 +- sound/soc/codecs/wm8988.c | 50 +- sound/soc/codecs/wm8994.c | 6692 +++++++++-------- sound/soc/codecs/wm8994.h | 49 +- sound/soc/codecs/wm_hubs.c | 74 +- sound/soc/soc-cache.c | 1 - 108 files changed, 5639 insertions(+), 11731 deletions(-) delete mode 100644 drivers/gpio/tps65910-gpio.c delete mode 100755 drivers/media/video/ov2640.c delete mode 100755 drivers/mfd/wm831x-i2c.c delete mode 100755 drivers/mfd/wm831x-spi.c delete mode 100644 drivers/regulator/tps65910-regulator.c diff --git a/.gitignore b/.gitignore index ea3e54bd9701..8faa6c02b39e 100644 --- a/.gitignore +++ b/.gitignore @@ -31,7 +31,6 @@ modules.builtin *.lzo *.patch *.gcno -Untitled Project.* # # Top-level generic files @@ -44,7 +43,6 @@ Untitled Project.* /System.map /Module.markers /Module.symvers -/kernel.img # # git files that we don't want to ignore even it they are dot-files @@ -58,7 +56,6 @@ Untitled Project.* include/config include/linux/version.h include/generated -include/asm-arm/mach-types.h # stgit generated dirs patches-* diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index 81e6d74ccb3a..051b179c9135 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S @@ -246,10 +246,6 @@ not_relocated: mov r0, #0 * pointers, and start decompressing. */ bl cache_on -#ifdef CONFIG_ARCH_RK29 - bl cache_off - bl cache_on -#endif mov r1, sp @ malloc space above stack add r2, sp, #0x10000 @ 64k max diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c index c086fb5cbe39..48a70afca283 100755 --- a/arch/arm/common/gic.c +++ b/arch/arm/common/gic.c @@ -94,7 +94,6 @@ void gic_ack_irq(unsigned int irq) spin_lock(&irq_controller_lock); writel(mask, gic_dist_base(irq) + GIC_DIST_ENABLE_CLEAR + (gic_irq(irq) / 32) * 4); writel(gic_irq(irq), gic_cpu_base(irq) + GIC_CPU_EOI); - dsb(); spin_unlock(&irq_controller_lock); } @@ -104,7 +103,6 @@ void gic_mask_irq(unsigned int irq) spin_lock(&irq_controller_lock); writel(mask, gic_dist_base(irq) + GIC_DIST_ENABLE_CLEAR + (gic_irq(irq) / 32) * 4); - dsb(); spin_unlock(&irq_controller_lock); } @@ -114,7 +112,6 @@ void gic_unmask_irq(unsigned int irq) spin_lock(&irq_controller_lock); writel(mask, gic_dist_base(irq) + GIC_DIST_ENABLE_SET + (gic_irq(irq) / 32) * 4); - dsb(); spin_unlock(&irq_controller_lock); } @@ -211,13 +208,6 @@ static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc) chip->unmask(irq); } -#if defined(CONFIG_PM) && defined(CONFIG_ARCH_RK29) -static int gic_set_wake(unsigned int irq, unsigned int on) -{ - return 0; -} -#endif - static struct irq_chip gic_chip = { .name = "GIC", .ack = gic_ack_irq, @@ -227,9 +217,6 @@ static struct irq_chip gic_chip = { #ifdef CONFIG_SMP .set_affinity = gic_set_cpu, #endif -#if defined(CONFIG_PM) && defined(CONFIG_ARCH_RK29) - .set_wake = gic_set_wake, -#endif }; void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq) @@ -252,16 +239,11 @@ static unsigned int _gic_dist_init(unsigned int gic_nr) writel(0, base + GIC_DIST_CTRL); -#ifdef CONFIG_ARCH_RK29 - /* rk29 read GIC_DIST_CTR is 2, why? */ - max_irq = NR_AIC_IRQS; -#else /* * Find out how many interrupts are supported. */ max_irq = readl(base + GIC_DIST_CTR) & 0x1f; max_irq = (max_irq + 1) * 32; -#endif /* * The GIC only supports up to 1020 interrupt sources. diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index 45a79ea2bf5f..980b78e31328 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -15,7 +15,7 @@ CFLAGS_REMOVE_return_address.o = -pg obj-y := elf.o entry-armv.o entry-common.o irq.o \ process.o ptrace.o return_address.o setup.o signal.o \ - sys_arm.o stacktrace.o time.o traps.o dma.o + sys_arm.o stacktrace.o time.o traps.o obj-$(CONFIG_DEPRECATED_PARAM_STRUCT) += compat.o @@ -29,7 +29,6 @@ obj-$(CONFIG_MODULES) += armksyms.o module.o obj-$(CONFIG_ARTHUR) += arthur.o obj-$(CONFIG_ISA_DMA) += dma-isa.o obj-$(CONFIG_PCI) += bios32.o isa.o -obj-$(CONFIG_HAVE_SCHED_CLOCK) += sched_clock.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o obj-$(CONFIG_HAVE_ARM_TWD) += smp_twd.o diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S index 18d04feda60e..8cdf3bf26719 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S @@ -302,17 +302,6 @@ __v7_setup: * NS1 = PRRR[19] = 1 - normal shareable property * NOS = PRRR[24+n] = 1 - not outer shareable */ -#ifdef CONFIG_ARCH_RK29 - /* Setup L2 cache */ - mrc p15, 1, r5, c9, c0, 2 - bic r5, r5, #1 << 29 @ L2 data RAM read multiplexer select: 0 = two cycles - bic r5, r5, #7 << 6 - bic r5, r5, #15 - orr r5, r5, #2 << 6 @ Tag RAM latency: b010 = 3 cycles - orr r5, r5, #3 @ Data RAM latency: b0011 = 4 cycles - mcr p15, 1, r5, c9, c0, 2 -#endif - ldr r5, =0xff0a89a8 @ PRRR #ifdef CONFIG_SMP ldr r6, =0xc0e0c4e0 @ NMRR diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types index 28ccae2cb6d4..55590a4d87c9 100644 --- a/arch/arm/tools/mach-types +++ b/arch/arm/tools/mach-types @@ -1608,6 +1608,7 @@ kb9263 MACH_KB9263 KB9263 1612 mt7108 MACH_MT7108 MT7108 1613 smtr2440 MACH_SMTR2440 SMTR2440 1614 manao MACH_MANAO MANAO 1615 +cm_x300 MACH_CM_X300 CM_X300 1616 gulfstream_kp MACH_GULFSTREAM_KP GULFSTREAM_KP 1617 lanreadyfn522 MACH_LANREADYFN522 LANREADYFN522 1618 arma37 MACH_ARMA37 ARMA37 1619 @@ -2911,8 +2912,7 @@ smdkv310 MACH_SMDKV310 SMDKV310 2925 siemens_l0 MACH_SIEMENS_L0 SIEMENS_L0 2926 ventana MACH_VENTANA VENTANA 2927 wm8505_7in_netbook MACH_WM8505_7IN_NETBOOK WM8505_7IN_NETBOOK 2928 -rk29 MACH_RK29 RK29 2929 -#ec4350sdb MACH_EC4350SDB EC4350SDB 2929 +ec4350sdb MACH_EC4350SDB EC4350SDB 2929 mimas MACH_MIMAS MIMAS 2930 titan MACH_TITAN TITAN 2931 craneboard MACH_CRANEBOARD CRANEBOARD 2932 diff --git a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S index 7b0f0dae5b1d..d66cead97d28 100644 --- a/arch/arm/vfp/vfphw.S +++ b/arch/arm/vfp/vfphw.S @@ -206,23 +206,6 @@ ENTRY(vfp_save_state) mov pc, lr ENDPROC(vfp_save_state) -ENTRY(vfp_load_state) - @ Save the current VFP state - @ r0 - save location - @ r1 - FPEXC - DBGSTR1 "save VFP state %p", r0 - VFPFLDMIA r0, r2 @ save the working registers - ldmia r0, {r1,r2,r3,r12} - tst r1, #FPEXC_EX @ is there additional state to save? - beq 1f - tst r1, #FPEXC_FP2V @ is there an FPINST2 to read? - beq 1f -1: - VFPFMXR FPSCR, r2 - VFPFMXR FPEXC, r1 - mov pc, lr -ENDPROC(vfp_load_state) - last_VFP_context_address: .word last_VFP_context diff --git a/drivers/Kconfig b/drivers/Kconfig index 148cee62c0b5..6781b709cac5 100755 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -50,10 +50,6 @@ source "drivers/i2c/Kconfig" source "drivers/spi/Kconfig" -source "drivers/adc/Kconfig" - -source "drivers/headset_observe/Kconfig" - source "drivers/pps/Kconfig" source "drivers/gpio/Kconfig" @@ -117,13 +113,4 @@ source "drivers/xen/Kconfig" source "drivers/staging/Kconfig" source "drivers/platform/Kconfig" - -source "drivers/cmmb/Kconfig" - -source "drivers/testcode/Kconfig" - -source "drivers/smc/Kconfig" - -source "drivers/cir/Kconfig" - endmenu diff --git a/drivers/Makefile b/drivers/Makefile index da0c8ed4d7a4..d7f34f1a6cab 100755 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -47,7 +47,6 @@ obj-$(CONFIG_SCSI) += scsi/ obj-$(CONFIG_ATA) += ata/ obj-$(CONFIG_MTD) += mtd/ obj-$(CONFIG_SPI) += spi/ -obj-y += headset_observe/ obj-y += net/ obj-$(CONFIG_ATM) += atm/ obj-$(CONFIG_FUSION) += message/ @@ -66,16 +65,16 @@ obj-$(CONFIG_PARIDE) += block/paride/ obj-$(CONFIG_TC) += tc/ obj-$(CONFIG_UWB) += uwb/ obj-$(CONFIG_USB_OTG_UTILS) += usb/otg/ -obj-$(CONFIG_USB_SUPPORT) += usb/ +obj-$(CONFIG_USB) += usb/ obj-$(CONFIG_USB_MUSB_HDRC) += usb/musb/ obj-$(CONFIG_PCI) += usb/ +obj-$(CONFIG_USB_GADGET) += usb/gadget/ obj-$(CONFIG_SERIO) += input/serio/ obj-$(CONFIG_GAMEPORT) += input/gameport/ obj-$(CONFIG_INPUT) += input/ obj-$(CONFIG_I2O) += message/ obj-$(CONFIG_RTC_LIB) += rtc/ obj-y += i2c/ media/ -obj-y += adc/ obj-$(CONFIG_PPS) += pps/ obj-$(CONFIG_W1) += w1/ obj-$(CONFIG_POWER_SUPPLY) += power/ @@ -117,9 +116,3 @@ obj-$(CONFIG_VLYNQ) += vlynq/ obj-$(CONFIG_STAGING) += staging/ obj-y += platform/ obj-y += ieee802154/ -obj-$(CONFIG_CMMB) += cmmb/ -obj-$(CONFIG_TEST_CODE) += testcode/ -obj-y += smc/ -obj-y += cir/ -obj-y += dbg/ - diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index bb322473210e..1ba3de8015b5 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -27,9 +27,6 @@ #include #include #include -#ifdef CONFIG_ARCH_RK29 -#include -#endif #include "../base.h" #include "power.h" @@ -614,9 +611,6 @@ static void dpm_drv_timeout(unsigned long data) printk(KERN_EMERG "**** DPM device timeout: %s (%s)\n", dev_name(dev), (dev->driver ? dev->driver->name : "no driver")); -#ifdef CONFIG_ARCH_RK29 - resume_console(); -#endif printk(KERN_EMERG "dpm suspend stack:\n"); show_stack(tsk, NULL); diff --git a/drivers/char/Makefile b/drivers/char/Makefile index b8ddad9ddf4d..720d6e8142cd 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile @@ -19,7 +19,6 @@ obj-$(CONFIG_CONSOLE_TRANSLATIONS) += consolemap.o consolemap_deftbl.o obj-$(CONFIG_HW_CONSOLE) += vt.o defkeymap.o obj-$(CONFIG_AUDIT) += tty_audit.o obj-$(CONFIG_MAGIC_SYSRQ) += sysrq.o -obj-$(CONFIG_MAGIC_SYSRQ) += rk_sysrq.o obj-$(CONFIG_MVME147_SCC) += generic_serial.o vme_scc.o obj-$(CONFIG_MVME162_SCC) += generic_serial.o vme_scc.o obj-$(CONFIG_BVME6000_SCC) += generic_serial.o vme_scc.o diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index 11eebdac96c5..7b5093664e49 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c @@ -30,13 +30,8 @@ #define DEF_FREQUENCY_DOWN_DIFFERENTIAL (10) #define DEF_FREQUENCY_UP_THRESHOLD (80) -#ifdef CONFIG_ARCH_RK29 -#define MICRO_FREQUENCY_DOWN_DIFFERENTIAL (10) -#define MICRO_FREQUENCY_UP_THRESHOLD (80) -#else #define MICRO_FREQUENCY_DOWN_DIFFERENTIAL (3) #define MICRO_FREQUENCY_UP_THRESHOLD (95) -#endif #define MICRO_FREQUENCY_MIN_SAMPLE_RATE (10000) #define MIN_FREQUENCY_UP_THRESHOLD (11) #define MAX_FREQUENCY_UP_THRESHOLD (100) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 9fda464d7db0..21da9c19a0cb 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1421,8 +1421,6 @@ int gpio_direction_output(unsigned gpio, int value) spin_lock_irqsave(&gpio_lock, flags); - if (value !=0 && value !=1) - goto fail; if (!gpio_is_valid(gpio)) goto fail; chip = desc->chip; @@ -1467,67 +1465,6 @@ fail: } EXPORT_SYMBOL_GPL(gpio_direction_output); -/* -gpio pull up or pull down -value = 0, normal -value = 1, pull up -value = 2, pull down -*/ -int gpio_pull_updown(unsigned gpio, unsigned value) -{ - unsigned long flags; - struct gpio_chip *chip; - struct gpio_desc *desc = &gpio_desc[gpio]; - int status = -EINVAL; - - spin_lock_irqsave(&gpio_lock, flags); - - if (value >3) - goto fail; - if (!gpio_is_valid(gpio)) - goto fail; - chip = desc->chip; - if (!chip || !chip->get || !chip->pull_updown) - goto fail; - gpio -= chip->base; - if (gpio >= chip->ngpio) - goto fail; - status = gpio_ensure_requested(desc, gpio); - if (status < 0) - goto fail; - - /* now we know the gpio is valid and chip won't vanish */ - - spin_unlock_irqrestore(&gpio_lock, flags); - - might_sleep_if(extra_checks && chip->can_sleep); - - if (status) { - status = chip->request(chip, gpio); - if (status < 0) { - pr_debug("GPIO-%d: chip request fail, %d\n", - chip->base + gpio, status); - /* and it's not available to anyone else ... - * gpio_request() is the fully clean solution. - */ - goto lose; - } - } - status = chip->pull_updown(chip, gpio,value); - if (status == 0) - clear_bit(FLAG_IS_OUT, &desc->flags); - -lose: - return status; -fail: - spin_unlock_irqrestore(&gpio_lock, flags); - if (status) - pr_debug("%s: gpio-%d status %d\n", - __func__, gpio, status); - return status; -} -EXPORT_SYMBOL_GPL(gpio_pull_updown); - /** * gpio_set_debounce - sets @debounce time for a @gpio * @gpio: the gpio to set debounce time @@ -1606,9 +1543,7 @@ EXPORT_SYMBOL_GPL(gpio_set_debounce); int __gpio_get_value(unsigned gpio) { struct gpio_chip *chip; - - if (!gpio_is_valid(gpio)) - return -1; + chip = gpio_to_chip(gpio); WARN_ON(chip->can_sleep); return chip->get ? chip->get(chip, gpio - chip->base) : 0; @@ -1628,10 +1563,6 @@ void __gpio_set_value(unsigned gpio, int value) { struct gpio_chip *chip; - if(value !=0 && value !=1) - return; - if (!gpio_is_valid(gpio)) - return; chip = gpio_to_chip(gpio); WARN_ON(chip->can_sleep); chip->set(chip, gpio - chip->base, value); @@ -1669,13 +1600,9 @@ EXPORT_SYMBOL_GPL(__gpio_cansleep); int __gpio_to_irq(unsigned gpio) { struct gpio_chip *chip; - - if (!gpio_is_valid(gpio)) - return -1; - + chip = gpio_to_chip(gpio); - - return chip->to_irq ? chip->to_irq(chip, gpio - chip->base) : -1; + return chip->to_irq ? chip->to_irq(chip, gpio - chip->base) : -ENXIO; } EXPORT_SYMBOL_GPL(__gpio_to_irq); diff --git a/drivers/gpio/tps65910-gpio.c b/drivers/gpio/tps65910-gpio.c deleted file mode 100644 index 36e1889767d3..000000000000 --- a/drivers/gpio/tps65910-gpio.c +++ /dev/null @@ -1,364 +0,0 @@ -/* - * tps65910_gpio.c -- access to GPIOs on TPS65910x chips - * - * Copyright (C) 2010 Mistral solutions Pvt Ltd - * - * Based on twl4030-gpio.c - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -static int gpio_tps65910_remove(struct platform_device *pdev); - -/* - * The GPIO "subchip" supports 1 GPIOs which can be configured as - * inputs or outputs, with pullups or pulldowns on each pin. Each - * GPIO can trigger interrupts on either or both edges. - */ - - -/* Data structures */ -static struct gpio_chip tps65910_gpiochip; -static DEFINE_MUTEX(gpio_lock); -static unsigned int gpio_usage_count; -static struct work_struct gpio_work; -static struct mutex work_lock; -/* - * To configure TPS65910 GPIO registers - */ -static inline int gpio_tps65910_write(u8 address, u8 data) -{ - return tps65910_i2c_write_u8(TPS65910_I2C_ID0, data, address); -} - - -/* - * To read a TPS65910 GPIO module register - */ -static inline int gpio_tps65910_read(u8 address) -{ - u8 data; - int ret = 0; - - ret = tps65910_i2c_read_u8(TPS65910_I2C_ID0, &data, address); - return (ret < 0) ? ret : data; -} - -static int tps65910_request(struct gpio_chip *chip, unsigned offset) -{ - int status = 0; - - mutex_lock(&gpio_lock); - - /* initialize TPS65910 GPIO */ - /* By default the GPIO_CKSYNC signal is GPIO */ - if (!gpio_usage_count) - gpio_usage_count++; - - mutex_unlock(&gpio_lock); - return status; -} - -static void tps65910_free(struct gpio_chip *chip, unsigned offset) -{ - mutex_lock(&gpio_lock); - - /* on last use, switch off GPIO module */ - if (!gpio_usage_count) - gpio_usage_count--; - - mutex_unlock(&gpio_lock); -} - -static int tps65910_direction_in(struct gpio_chip *chip, unsigned offset) -{ - /* Configure TPS65910 GPIO as input */ - u8 val; - - mutex_lock(&gpio_lock); - - val = gpio_tps65910_read(TPS65910_REG_GPIO0); - - val &= ~(TPS65910_GPIO_CFG_OUTPUT); - - val = gpio_tps65910_read(TPS65910_REG_GPIO0); - - mutex_unlock(&gpio_lock); - - return 0; -} - -static int tps65910_get(struct gpio_chip *chip, unsigned offset) -{ - int status = 0; - - mutex_lock(&gpio_lock); - - status = gpio_tps65910_read(TPS65910_REG_GPIO0); - - mutex_unlock(&gpio_lock); - if (status & 0x01) - return 1; - else - return 0; -} -static -int tps65910_direction_out(struct gpio_chip *chip, unsigned offset, int value) -{ - /* Configure TPS65910 GPIO as input */ - u8 val; - u32 ret; - mutex_lock(&gpio_lock); - val = gpio_tps65910_read(TPS65910_REG_GPIO0); - - val |= TPS65910_GPIO_CFG_OUTPUT; - - ret = gpio_tps65910_write(TPS65910_REG_GPIO0, val); - mutex_unlock(&gpio_lock); - - if (ret != 0) - return -EIO; - return 0; -} - -static void tps65910_set(struct gpio_chip *chip, unsigned offset, int value) -{ - int val = 0; - u32 ret; - - mutex_lock(&gpio_lock); - val = gpio_tps65910_read(TPS65910_REG_GPIO0); - - if (value == 1) - val |= 0x01; - else - val &= 0xFE; - - ret = gpio_tps65910_write(TPS65910_REG_GPIO0, val); - - mutex_unlock(&gpio_lock); -} - - - -static void tps65910_gpio_set_debounce(u8 debounce) -{ - u8 val; - - mutex_lock(&gpio_lock); - - val = gpio_tps65910_read(TPS65910_REG_GPIO0); - - if (debounce == TPS65910_DEBOUNCE_91_5_MS) - val = (0<<4); - else if (debounce == TPS65910_DEBOUNCE_150_MS) - val = (1<<4); - else - printk(KERN_ERR "Invalid argument to %s\n", __func__); - - gpio_tps65910_write(TPS65910_REG_GPIO0, val); - - mutex_unlock(&gpio_lock); -} -EXPORT_SYMBOL(tps65910_gpio_set_debounce); - - -static void tps65910_gpio_pullup_enable(void) -{ - u8 val; - u32 ret; - - mutex_lock(&gpio_lock); - - val = gpio_tps65910_read(TPS65910_REG_GPIO0); - - val = (1<<3); - - ret = gpio_tps65910_write(TPS65910_REG_GPIO0, val); - - mutex_unlock(&gpio_lock); - - if (ret != 0) - printk(KERN_ERR "Error writing to TPS65910_REG_GPIO0 in %s \n", - __func__); -} -EXPORT_SYMBOL(tps65910_gpio_pullup_enable); - -static void tps65910_gpio_pullup_disable(void) -{ - u8 val; - u32 ret; - - mutex_lock(&gpio_lock); - - val = gpio_tps65910_read(TPS65910_REG_GPIO0); - - val = (0<<3); - - ret = gpio_tps65910_write(TPS65910_REG_GPIO0, val); - - mutex_unlock(&gpio_lock); -} -EXPORT_SYMBOL(tps65910_gpio_pullup_disable); - -static void tps65910_gpio_work(struct work_struct *work) -{ - - /* Read the status register and take action */ - u8 status2; - int err; - mutex_lock(&work_lock); - err = tps65910_i2c_read_u8(TPS65910_I2C_ID0, &status2, - TPS65910_REG_INT_STS); - if (!err) { - switch (status2) { - case TPS65910_GPIO_F_IT: - printk(KERN_NOTICE "Received TPS65910 GPIO falling \ - edge interrupt \n"); - /* Clear interrupt */ - tps65910_i2c_write_u8(TPS65910_I2C_ID0, status2, - TPS65910_REG_INT_STS); - /* Add code accroding to board requirment */ - break; - case TPS65910_GPIO_R_IT: - printk(KERN_NOTICE "Received TPS65910 GPIO Raising \ - edge interrupt \n"); - /* Clear interrupt */ - tps65910_i2c_write_u8(TPS65910_I2C_ID0, status2, - TPS65910_REG_INT_STS); - /* Add code accroding to board requirment */ - break; - } - } else { - printk(KERN_ERR"Could not read TPS65910_REG_INT_STS\n"); - } - - mutex_unlock(&work_lock); - -} - - - -static irqreturn_t tps65910_gpio_isr(int irq, void *_tps65910) -{ - /* Disable IRQ, schedule work, enable IRQ and acknowledge */ - disable_irq(irq); - (void) schedule_work(&gpio_work); - enable_irq(irq); - return IRQ_HANDLED; -} - - -static struct gpio_chip tps65910_gpiochip = { - .label = "tps65910", - .owner = THIS_MODULE, - .request = tps65910_request, - .free = tps65910_free, - .direction_input = tps65910_direction_in, - .get = tps65910_get, - .direction_output = tps65910_direction_out, - .set = tps65910_set, -}; - - -static int __devinit gpio_tps65910_probe(struct platform_device *pdev) -{ - int ret = -1; - int status = 0; - - struct tps65910_gpio *pdata = pdev->dev.platform_data; - - if (pdata->gpio_mode == TPS65910_GPIO_AS_IRQ) { - - if (pdata->irq_num) { - status = request_irq(pdata->irq_num, tps65910_gpio_isr, - IRQF_SHARED, "tps65910_gpio", pdev); - if (status < 0) { - pr_err("tps65910: could not claim irq%d: %d\n", - pdata->irq_num, status); - } - - } - - INIT_WORK(&gpio_work, tps65910_gpio_work); - mutex_init(&work_lock); - - tps65910_gpiochip.ngpio = TPS65910_GPIO_MAX; - tps65910_gpiochip.dev = &pdev->dev; - - ret = gpiochip_add(&tps65910_gpiochip); - - if (ret < 0) { - dev_err(&pdev->dev, "could not register gpiochip \ - %d\n", ret); - tps65910_gpiochip.ngpio = 0; - gpio_tps65910_remove(pdev); - return -ENODEV; - } - if (pdata->gpio_setup) - pdata->gpio_setup(pdata); - } - return ret; -} - -static int gpio_tps65910_remove(struct platform_device *pdev) -{ - struct tps65910_gpio *pdata = pdev->dev.platform_data; - int status; - - if (pdata->gpio_taredown) - pdata->gpio_taredown(pdata); - if (pdata->gpio_mode == TPS65910_GPIO_AS_IRQ) - free_irq(pdata->irq_num, NULL); - - status = gpiochip_remove(&tps65910_gpiochip); - if (status < 0) - return status; - return 0; -} - -static struct platform_driver gpio_tps65910_driver = { - .driver.name = "tps65910_gpio", - .driver.owner = THIS_MODULE, - .probe = gpio_tps65910_probe, - .remove = gpio_tps65910_remove, -}; - -static int __init gpio_tps65910_init(void) -{ - return platform_driver_register(&gpio_tps65910_driver); -} -subsys_initcall(gpio_tps65910_init); - -static void __exit gpio_tps65910_exit(void) -{ - platform_driver_unregister(&gpio_tps65910_driver); -} -module_exit(gpio_tps65910_exit); - -MODULE_AUTHOR("Mistral Solutions Pvt Ltd."); -MODULE_DESCRIPTION("GPIO interface for TPS65910"); -MODULE_LICENSE("GPL"); diff --git a/drivers/input/Makefile b/drivers/input/Makefile index 370bd0f94f73..3c7125758b7f 100755 --- a/drivers/input/Makefile +++ b/drivers/input/Makefile @@ -22,13 +22,8 @@ obj-$(CONFIG_INPUT_JOYSTICK) += joystick/ obj-$(CONFIG_INPUT_TABLET) += tablet/ obj-$(CONFIG_INPUT_TOUCHSCREEN) += touchscreen/ obj-$(CONFIG_INPUT_MISC) += misc/ -obj-$(CONFIG_G_SENSOR_DEVICE) += gsensor/ -obj-$(CONFIG_GYRO_SENSOR_DEVICE) += gyroscope/ -obj-$(CONFIG_INPUT_JOGBALL) += jogball/ -obj-$(CONFIG_LIGHT_SENSOR_DEVICE) += lightsensor/ obj-$(CONFIG_INPUT_APMPOWER) += apm-power.o obj-$(CONFIG_INPUT_KEYRESET) += keyreset.o obj-$(CONFIG_XEN_KBDDEV_FRONTEND) += xen-kbdfront.o -obj-y += magnetometer/ diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index 0592a9f6ba0a..9cc488d21490 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig @@ -12,25 +12,6 @@ menuconfig INPUT_KEYBOARD if INPUT_KEYBOARD -config KEYS_RK29 - tristate "rk29 keyboard" - depends on ARCH_RK29 - default y - help - rk29 keyboard drivers(gpio and adc) - -config KEYS_RK29_NEWTON - tristate "rk29 newton keyboard" - depends on ARCH_RK29 - help - rk29 newton keyboard drivers(gpio and adc) - -config SYNAPTICS_SO340010 - tristate "Synaptics So340010 TouchPad KEY" - depends on I2C - help - Synaptics So340010 Touch Key (I2C) driver - config KEYBOARD_AAED2000 tristate "AAED-2000 keyboard" depends on MACH_AAED2000 @@ -198,21 +179,6 @@ config KEYBOARD_GPIO To compile this driver as a module, choose M here: the module will be called gpio_keys. -config KEYBOARD_WM831X_GPIO - tristate "WM831X_GPIO Buttons" - depends on GENERIC_GPIO - help - This driver implements support for buttons connected - to GPIO pins of various CPUs (and some other chips). - - Say Y here if your device has buttons connected - directly to such GPIO pins. Your board-specific - setup logic must also provide a platform device, - with configuration data saying which GPIOs are used. - - To compile this driver as a module, choose M here: the - module will be called wm831x_gpio_keys. - config KEYBOARD_TCA6416 tristate "TCA6416 Keypad Support" depends on I2C diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index bc9f81d107e5..504b591be0cd 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile @@ -4,8 +4,6 @@ # Each configuration option enables a list of files. -obj-$(CONFIG_KEYS_RK29) += rk29_keys.o -obj-$(CONFIG_KEYS_RK29_NEWTON) += rk29_newton_keys.o obj-$(CONFIG_KEYBOARD_AAED2000) += aaed2000_kbd.o obj-$(CONFIG_KEYBOARD_ADP5520) += adp5520-keys.o obj-$(CONFIG_KEYBOARD_ADP5588) += adp5588-keys.o @@ -16,7 +14,6 @@ obj-$(CONFIG_KEYBOARD_BFIN) += bf54x-keys.o obj-$(CONFIG_KEYBOARD_DAVINCI) += davinci_keyscan.o obj-$(CONFIG_KEYBOARD_EP93XX) += ep93xx_keypad.o obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o -obj-$(CONFIG_KEYBOARD_WM831X_GPIO) += wm831x_gpio_keys.o obj-$(CONFIG_KEYBOARD_TCA6416) += tca6416-keypad.o obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o @@ -44,5 +41,3 @@ obj-$(CONFIG_KEYBOARD_SUNKBD) += sunkbd.o obj-$(CONFIG_KEYBOARD_TWL4030) += twl4030_keypad.o obj-$(CONFIG_KEYBOARD_XTKBD) += xtkbd.o obj-$(CONFIG_KEYBOARD_W90P910) += w90p910_keypad.o -obj-$(CONFIG_SYNAPTICS_SO340010) += synaptics_so340010.o - diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index d920a863f342..a390cbad3049 100755 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -11,58 +11,6 @@ menuconfig INPUT_TOUCHSCREEN if INPUT_TOUCHSCREEN -config TOUCHSCREEN_XPT2046_SPI - tristate "XPT2046 based touchscreens:SPI Interface" - depends on SPIM_RK29 - - config TOUCHSCREEN_XPT2046_NORMAL_SPI - tristate "normal mode" - depends on TOUCHSCREEN_XPT2046_SPI - - config TOUCHSCREEN_480X800 - tristate "480X800 resolution" - depends on TOUCHSCREEN_XPT2046_NORMAL_SPI - - config TOUCHSCREEN_800X480 - tristate "800X480 resolution" - depends on TOUCHSCREEN_XPT2046_NORMAL_SPI - - config TOUCHSCREEN_320X480 - tristate "320X480 resolution" - depends on TOUCHSCREEN_XPT2046_NORMAL_SPI - - config TOUCHSCREEN_XPT2046_TSLIB_SPI - tristate "tslib mode" - depends on TOUCHSCREEN_XPT2046_SPI - - config TOUCHSCREEN_480X800 - tristate "480X800 resolution" - depends on TOUCHSCREEN_XPT2046_TSLIB_SPI - - config TOUCHSCREEN_800X480 - tristate "800X480 resolution" - depends on TOUCHSCREEN_XPT2046_TSLIB_SPI - - config TOUCHSCREEN_320X480 - tristate "320X480 resolution" - depends on TOUCHSCREEN_XPT2046_TSLIB_SPI - - config TOUCHSCREEN_XPT2046_CBN_SPI - tristate "calibration mode" - depends on TOUCHSCREEN_XPT2046_SPI - - config TOUCHSCREEN_480X800 - tristate "480X800 resolution" - depends on TOUCHSCREEN_XPT2046_CBN_SPI - - config TOUCHSCREEN_800X480 - tristate "800X480 resolution" - depends on TOUCHSCREEN_XPT2046_CBN_SPI - - config TOUCHSCREEN_320X480 - tristate "320X480 resolution" - depends on TOUCHSCREEN_XPT2046_CBN_SPI - config TOUCHSCREEN_88PM860X tristate "Marvell 88PM860x touchscreen" depends on MFD_88PM860X @@ -106,28 +54,6 @@ config TOUCHSCREEN_AD7877 To compile this driver as a module, choose M here: the module will be called ad7877. - -config TOUCHSCREEN_ILI2102_IIC - tristate "ili2102 based touchscreens: IIC Interface" - help - Say Y here if you have a touchscreen interface using the - hx8520 controller, and your board-specific initialization - code includes that in its table of IIC devices. - - If unsure, say N (but it's safe to say "Y"). - -config RK28_I2C_TS_NTP070 - tristate "NTP070 based touchscreens: NTP070 Interface" - depends on I2C_RK2818 - -config TOUCHSCREEN_IT7250 - tristate "IT7250 based touchscreens: IT7250 Interface" - help - Say Y here if you have a touchscreen interface using the - xpt2046 controller, and your board-specific initialization - code includes that in its table of SPI devices. - - If unsure, say N (but it's safe to say "Y"). config TOUCHSCREEN_AD7879 tristate "Analog Devices AD7879-1/AD7889-1 touchscreen interface" @@ -709,172 +635,6 @@ config TOUCHSCREEN_PCAP To compile this driver as a module, choose M here: the module will be called pcap_ts. -config HANNSTAR_P1003 - tristate "Hannstar P1003 touchscreen" - depends on I2C2_RK29 - help - RK29 hannstar touch - - config HANNSTAR_MAX_X - int "hannstar touch x max" - depends on HANNSTAR_P1003 - default 1087 - help - RK29 hannstar touch max X size - - config HANNSTAR_MAX_Y - int "hannstar touch Y max" - depends on HANNSTAR_P1003 - default 800 - help - RK29 hannstar touch max Y size - - config HANNSTAR_DEBUG - bool "hannstar debug" - depends on HANNSTAR_P1003 - default n - help - RK29 hannstar touch debug - -config ATMEL_MXT224 - tristate "Atmel mXT224 touchscreen" - depends on I2C2_RK29 - help - RK29 Atmel_mXT224 touch - - config MXT224_MAX_X - int "atmel_mxt224 touch X max" - depends on ATMEL_MXT224 - default 4095 - help - RK29 atmel_mxt224 touch max X size - - config MXT224_MAX_Y - int "atmel_mxt224 touch Y max" - depends on ATMEL_MXT224 - default 4095 - help - RK29 atmel_mxt224 touch max Y size - -config SINTEK_3FA16 - tristate "Sintek 3FA16 touchscreen" - depends on I2C2_RK29 - help - RK29 Sintek touch - - config HANNSTAR_MAX_X - int "Sintek touch x max" - depends on SINTEK_3FA16 - default 1024 - help - RK29 hannstar touch max X size - - config HANNSTAR_MAX_Y - int "Sintek touch Y max" - depends on SINTEK_3FA16 - default 600 - help - RK29 hannstar touch max Y size - - config HANNSTAR_DEBUG - bool "Sintek debug" - depends on SINTEK_3FA16 - default n - help - RK29 hannstar touch debug - -config EETI_EGALAX - tristate "EETI_EGALAX touchscreen panel support" - depends on I2C - help - Say Y here to enable support for I2C connected EETI touch panels. - - To compile this driver as a module, choose M here: the - module will be called eeti_egalax_ts. - - config EETI_EGALAX_MAX_X - int "EETI_EGALAX_MAX_X" - depends on EETI_EGALAX - default 2047 - help - RK29 EETI_EGALAX touch max X size - - config EETI_EGALAX_MAX_Y - int "EETI_EGALAX_MAX_Y" - depends on EETI_EGALAX - default 2047 - help - RK29 EETI_EGALAX touch max Y size - - config EETI_EGALAX_DEBUG - bool "EETI_EGALAX debug" - depends on EETI_EGALAX - default n - help - RK29 EETI_EGALAX touch debug - -config TOUCHSCREEN_IT7260 - tristate "IT7260 based touchscreens: IT7260 Interface" - depends on I2C2_RK29 - help - Say Y here if you have a touchscreen interface using the - it7260 controller, and your board-specific initialization - code includes that in its table of I2C devices. - - If unsure, say N (but it's safe to say "Y"). - -config TOUCHSCREEN_IT7260_I2C - tristate "IT7260 based touchscreens: IT7260 I2C Interface" - depends on I2C_RK29 - help - Say Y here if you have a touchscreen interface using the - IT7260 controller, and your board-specific initialization - code includes that in its table of I2C devices. - - If unsure, say N (but it's safe to say "Y"). - -config TOUCHSCREEN_NAS - tristate "NAS based touchscreens: NAS Interface" - depends on I2C2_RK29 - help - Say Y here if you have a touchscreen interface using the - nas controller, and your board-specific initialization - code includes that in its table of I2C devices. - - If unsure, say N (but it's safe to say "Y"). - -config LAIBAO_TS - tristate "LAIBAO touchscreen" - depends on I2C2_RK29 - help - RK29 LAIBAO touchscreen - -config TOUCHSCREEN_GT801_IIC - tristate "GT801_IIC based touchscreens" - depends on I2C2_RK29 - -config TOUCHSCREEN_GT818_IIC - tristate "GT818_IIC based touchscreens" - depends on I2C2_RK29 - -config D70_L3188A - tristate "D70-L3188A based touchscreens" - depends on I2C2_RK29 - -config TOUCHSCREEN_GT819 - tristate "GT819 based touchscreens" - depends on I2C2_RK29 - -config TOUCHSCREEN_FT5406 - tristate "FT5406 based touchscreens: FT5406 Interface" - depends on I2C2_RK29 - help - say Y here if you have a touchscreen interface using the FT5406 - controller,and your board-specific initialization code includes that - in its table of I2C devices. - - If unsure, say N(but it's safe to say "Y"). - config TOUCHSCREEN_TPS6507X tristate "TPS6507x based touchscreens" depends on I2C @@ -906,33 +666,4 @@ config TOUCHSCREEN_QUANTUM_OBP If unsure, say N. -config ATMEL_MXT1386 - tristate "ATMEL_MXT1386 touchscreen panel support" - depends on I2C - help - Say Y here to enable support for I2C connected ATMEL_MXT1386 touch panels. - - To compile this driver as a module, choose M here: the - module will be called atmel_mxt1386_ts. - - config ATMEL_MXT1386_MAX_X - int "ATMEL_MXT1386_MAX_X" - depends on ATMEL_MXT1386 - default 4095 - help - RK29 ATMEL_MXT1386 touch max X size - - config ATMEL_MXT1386_MAX_Y - int "ATMEL_MXT1386_MAX_Y" - depends on ATMEL_MXT1386 - default 4095 - help - RK29 ATMEL_MXT1386 touch max Y size - - config ATMEL_MXT1386_DEBUG - bool "ATMEL_MXT1386 debug" - depends on ATMEL_MXT1386 - default n - help - RK29 ATMEL_MXT1386 touch debug endif diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index 864fd089fed7..399ff510d79c 100755 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile @@ -76,37 +76,14 @@ obj-$(CONFIG_VIDEO_MT9V011) += mt9v011.o obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o obj-$(CONFIG_SOC_CAMERA_MT9M111) += mt9m111.o -obj-$(CONFIG_SOC_CAMERA_MT9M112) += mt9m112.o obj-$(CONFIG_SOC_CAMERA_MT9T031) += mt9t031.o -obj-$(CONFIG_SOC_CAMERA_MT9T111) += mt9t111.o obj-$(CONFIG_SOC_CAMERA_MT9T112) += mt9t112.o obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o -obj-$(CONFIG_SOC_CAMERA_MT9P111) += mt9p111.o -obj-$(CONFIG_SOC_CAMERA_MT9D112) += mt9d112.o -obj-$(CONFIG_SOC_CAMERA_MT9D113) += mt9d113.o obj-$(CONFIG_SOC_CAMERA_OV772X) += ov772x.o obj-$(CONFIG_SOC_CAMERA_OV9640) += ov9640.o obj-$(CONFIG_SOC_CAMERA_RJ54N1) += rj54n1cb0c.o obj-$(CONFIG_SOC_CAMERA_TW9910) += tw9910.o -obj-$(CONFIG_SOC_CAMERA_OV7675) += ov7675.o -obj-$(CONFIG_SOC_CAMERA_OV2655) += ov2655.o -obj-$(CONFIG_SOC_CAMERA_OV2659) += ov2659.o -obj-$(CONFIG_SOC_CAMERA_OV9650) += ov9650.o -obj-$(CONFIG_SOC_CAMERA_OV2640) += ov2640.o -obj-$(CONFIG_SOC_CAMERA_OV3640) += ov3640.o -obj-$(CONFIG_SOC_CAMERA_OV5640) += ov5640.o -obj-$(CONFIG_SOC_CAMERA_OV5642) += ov5642.o -obj-$(CONFIG_SOC_CAMERA_S5K6AA) += s5k6aa.o -obj-$(CONFIG_SOC_CAMERA_GT2005) += gt2005.o -obj-$(CONFIG_SOC_CAMERA_GC0307) += gc0307.o -obj-$(CONFIG_SOC_CAMERA_GC0308) += gc0308.o -obj-$(CONFIG_SOC_CAMERA_GC0309) += gc0309.o -obj-$(CONFIG_SOC_CAMERA_GC2015) += gc2015.o -obj-$(CONFIG_SOC_CAMERA_SIV120B) += siv120b.o -obj-$(CONFIG_SOC_CAMERA_SID130B) += sid130B.o -obj-$(CONFIG_SOC_CAMERA_HI253) += hi253.o -obj-$(CONFIG_SOC_CAMERA_HI704) += hi704.o -obj-$(CONFIG_SOC_CAMERA_NT99250) += nt99250.o + # And now the v4l2 drivers: obj-$(CONFIG_VIDEO_BT848) += bt8xx/ @@ -184,9 +161,6 @@ obj-$(CONFIG_VIDEO_MX1) += mx1_camera.o obj-$(CONFIG_VIDEO_MX2) += mx2_camera.o obj-$(CONFIG_VIDEO_MX3) += mx3_camera.o obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o -obj-$(CONFIG_VIDEO_RK29_WORK_ONEFRAME) += rk29_camera_oneframe.o -obj-$(CONFIG_VIDEO_RK29_WORK_PINGPONG) += rk29_camera_pingpong.o -obj-$(CONFIG_VIDEO_RK29XX_VOUT) += rk29xx/ obj-$(CONFIG_VIDEO_SH_MOBILE_CSI2) += sh_mobile_csi2.o obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o obj-$(CONFIG_VIDEO_SAMSUNG_S5P_FIMC) += s5p-fimc/ diff --git a/drivers/media/video/ov2640.c b/drivers/media/video/ov2640.c deleted file mode 100755 index f8368ab308eb..000000000000 --- a/drivers/media/video/ov2640.c +++ /dev/null @@ -1,2968 +0,0 @@ -/* -o* Driver for MT9M001 CMOS Image Sensor from Micron - * - * Copyright (C) 2008, Guennadi Liakhovetski - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static int debug; -module_param(debug, int, S_IRUGO|S_IWUSR); - -#define dprintk(level, fmt, arg...) do { \ - if (debug >= level) \ - printk(KERN_WARNING fmt , ## arg); } while (0) - -#define SENSOR_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__) -#define SENSOR_DG(format, ...) dprintk(1, format, ## __VA_ARGS__) - - -#define _CONS(a,b) a##b -#define CONS(a,b) _CONS(a,b) - -#define __STR(x) #x -#define _STR(x) __STR(x) -#define STR(x) _STR(x) - -#define MIN(x,y) ((xy) ? x: y) - -/* Sensor Driver Configuration */ -#define SENSOR_NAME RK29_CAM_SENSOR_OV2640 -#define SENSOR_V4L2_IDENT V4L2_IDENT_OV2640 -#define SENSOR_ID 0x2642 -#define SENSOR_ID1 0x2641 -#define SENSOR_MIN_WIDTH 640 -#define SENSOR_MIN_HEIGHT 480 -#define SENSOR_MAX_WIDTH 1600 -#define SENSOR_MAX_HEIGHT 1200 -#define SENSOR_INIT_WIDTH 640 /* Sensor pixel size for sensor_init_data array */ -#define SENSOR_INIT_HEIGHT 480 -#define SENSOR_INIT_WINSEQADR sensor_vga -#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8 - -#define CONFIG_SENSOR_WhiteBalance 0 -#define CONFIG_SENSOR_Brightness 1 -#define CONFIG_SENSOR_Contrast 0 -#define CONFIG_SENSOR_Saturation 1 -#define CONFIG_SENSOR_Effect 1 -#define CONFIG_SENSOR_Scene 0 -#define CONFIG_SENSOR_DigitalZoom 0 -#define CONFIG_SENSOR_Focus 0 -#define CONFIG_SENSOR_Exposure 0 -#define CONFIG_SENSOR_Flash 0 -#define CONFIG_SENSOR_Mirror 0 -#define CONFIG_SENSOR_Flip 0 - -#define CONFIG_SENSOR_I2C_SPEED 250000 /* Hz */ -/* Sensor write register continues by preempt_disable/preempt_enable for current process not be scheduled */ -#define CONFIG_SENSOR_I2C_NOSCHED 0 -#define CONFIG_SENSOR_I2C_RDWRCHK 0 - -#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\ - SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |\ - SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) - -#define COLOR_TEMPERATURE_CLOUDY_DN 6500 -#define COLOR_TEMPERATURE_CLOUDY_UP 8000 -#define COLOR_TEMPERATURE_CLEARDAY_DN 5000 -#define COLOR_TEMPERATURE_CLEARDAY_UP 6500 -#define COLOR_TEMPERATURE_OFFICE_DN 3500 -#define COLOR_TEMPERATURE_OFFICE_UP 5000 -#define COLOR_TEMPERATURE_HOME_DN 2500 -#define COLOR_TEMPERATURE_HOME_UP 3500 - -#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a)) -#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a) - -struct reginfo -{ - u8 reg; - u8 val; -}; - -/* init 800*600 SVGA */ -static struct reginfo sensor_init_data[] = -{ -#if 1 - {0xff,0x01}, - {0x12,0x80}, - {0xff,0x00}, - {0x2c,0xff}, - {0x2e,0xdf}, - {0xff,0x01}, - - {0x03,0x4f}, - {0x0f,0x4b}, - - - {0x3c,0x32}, - {0x11,0x00}, - {0x09,0x02}, - {0x04,0xF8},//b7,b6 directs - {0x13,0xe5}, - {0x14,0x48}, - {0x2c,0x0c}, - {0x33,0x78}, - {0x3a,0x33}, - {0x3b,0xfB}, - {0x3e,0x00}, - {0x43,0x11}, - {0x16,0x10}, - {0x39,0x02}, - {0x35,0x88}, - {0x22,0x09}, - {0x37,0x40}, - {0x23,0x00}, - {0x34,0xa0}, - {0x36,0x1a}, - {0x06,0x02}, - {0x07,0xc0}, - {0x0d,0xb7}, - {0x0e,0x01}, - {0x4c,0x00}, - {0x4a,0x81}, - {0x21,0x99}, - - //{0x24,0x58}, - //{0x25,0x50}, - //{0x26,0x92}, - - {0x24, 0x70}, - {0x25, 0x60}, - {0x26, 0xa4}, - - {0x5c,0x00}, - {0x63,0x00}, - {0x46,0x3f}, - {0x0c,0x3c}, - {0x61,0x70}, - {0x62,0x80}, - {0x7c,0x05}, - {0x20,0x80}, - {0x28,0x30}, - {0x6c,0x00}, - {0x6d,0x80}, - {0x6e,0x00}, - {0x70,0x02}, - {0x71,0x94}, - {0x73,0xc1}, - {0x3d,0x34}, - {0x5a,0x57}, - {0x4f,0xbb}, - {0x50,0x9c}, - {0xff,0x00}, - {0xe5,0x7f}, - {0xf9,0xc0}, - {0x41,0x24}, - {0xe0,0x14}, - {0x76,0xff}, - {0x33,0xa0}, - {0x42,0x20}, - {0x43,0x18}, - {0x4c,0x00}, - {0x87,0xd0}, - {0x88,0x3f}, - {0xd7,0x03}, - {0xd9,0x10}, - {0xd3,0x82}, - {0xc8,0x08}, - {0xc9,0x80}, - {0x7c,0x00}, - {0x7d,0x00},//0x00//0x07 - {0x7c,0x03}, - {0x7d,0x48},//0x48//0x40 - {0x7d,0x48},//0x48//0x40 - {0x7c,0x08}, - {0x7d,0x20}, - {0x7d,0x10},//0x10 - {0x7d,0x0e},//0x0e - - {0x92,0x00}, - {0x93,0x06}, - {0x93,0xc8},//e3 - {0x93,0x05}, - {0x93,0x05}, - {0x93,0x00}, - {0x93,0x04}, - {0x93,0x00}, - {0x93,0x00}, - {0x93,0x00}, - {0x93,0x00}, - {0x93,0x00}, - {0x93,0x00}, - {0x93,0x00}, - {0x96,0x00}, - {0x97,0x08}, - {0x97,0x19}, - {0x97,0x02}, - {0x97,0x0c}, - {0x97,0x24}, - {0x97,0x30}, - {0x97,0x28}, - {0x97,0x26}, - {0x97,0x02}, - {0x97,0x98}, - {0x97,0x80}, - {0x97,0x00}, - {0x97,0x00}, - {0xc3,0xef},//ed - {0xa4,0x00}, - {0xa8,0x00}, - - {0xbf, 0x00}, - {0xba, 0xdc}, - {0xbb, 0x08}, - {0xb6, 0x20}, - {0xb8, 0x30}, - {0xb7, 0x20}, - {0xb9, 0x30}, - {0xb3, 0xb4}, - {0xb4, 0xca}, - {0xb5, 0x34}, - {0xb0, 0x46}, - {0xb1, 0x46}, - {0xb2, 0x06}, - {0xc7, 0x00}, - {0xc6, 0x51}, - {0xc5, 0x11}, - {0xc4, 0x9c}, -//// - {0xc0,0xc8}, - {0xc1,0x96}, - {0x86,0x3d}, - {0x50,0x92}, - {0x51,0x90}, - {0x52,0x2c}, - {0x53,0x00}, - {0x54,0x00}, - {0x55,0x88}, - {0x57,0x00}, - {0x5a,0x50}, - {0x5b,0x3c}, - {0x5c,0x00}, - {0xc3,0xed}, - {0x7f,0x00}, - {0xda,0x01}, - {0xe5,0x1f}, - {0xe1,0x67}, - {0xe0,0x00}, - {0xdd,0xff}, - {0x05,0x00}, - -#endif -#if 1 - {0xff, 0x01}, - {0x5d, 0x00}, - {0x5e, 0x3c}, - {0x5f, 0x28}, - {0x60, 0x55}, - - - {0xff, 0x00}, - {0xc3, 0xef}, - {0xa6, 0x00}, - {0xa7, 0x0f}, - {0xa7, 0x4e}, - {0xa7, 0x7a}, - {0xa7, 0x33}, - {0xa7, 0x00}, - {0xa7, 0x23}, - {0xa7, 0x27}, - {0xa7, 0x3a}, - {0xa7, 0x70}, - {0xa7, 0x33}, - {0xa7, 0x00},//L - {0xa7, 0x23}, - {0xa7, 0x20}, - {0xa7, 0x0c}, - {0xa7, 0x66}, - {0xa7, 0x33}, - {0xa7, 0x00}, - {0xa7, 0x23}, - {0xc3, 0xef}, -#endif - - -#if 1 - {0xff,0x00}, - {0x92,0x00}, - {0x93,0x06}, - {0x93,0xc1},//e - {0x93,0x02}, - {0x93,0x02}, - {0x93,0x00}, - {0x93,0x04}, -#endif - - {0x03, 0x0f}, - {0xe0, 0x04}, - {0xc0, 0xc8}, - {0xc1, 0x96}, - {0x86, 0x3d}, - {0x50, 0x89}, - {0x51, 0x90}, - {0x52, 0x2c}, - {0x53, 0x00}, - {0x54, 0x00}, - {0x55, 0x88}, - {0x57, 0x00}, - {0x5a, 0xa0}, - {0x5b, 0x78}, - {0x5c, 0x00}, - {0xd3, 0x04}, - {0xe0, 0x00}, - - {0x0, 0x0} //end flag - -}; - -/* 1600X1200 UXGA */ -static struct reginfo sensor_uxga[] = -{ - {0xff, 0x00}, - {0xe0, 0x04}, - {0xc0, 0xc8}, - {0xc1, 0x96}, - {0x86, 0x3d}, - {0x50, 0x00}, - {0x51, 0x90}, - {0x52, 0x2c}, - {0x53, 0x00}, - {0x54, 0x00}, - {0x55, 0x88}, - {0x57, 0x00}, - {0x5a, 0x90}, - {0x5b, 0x2c}, - {0x5c, 0x05}, - {0xd3, 0x82}, - {0xe0, 0x00}, - {0x0, 0x0} //end flag -}; - -/* 1280X1024 SXGA */ -static struct reginfo sensor_sxga[] = -{ - {0xff, 0x00}, - {0xe0, 0x04}, - {0xc0, 0xc8}, - {0xc1, 0x96}, - {0x86, 0x3d}, - {0x50, 0x00}, - {0x51, 0x90}, - {0x52, 0x2c}, - {0x53, 0x00}, - {0x54, 0x00}, - {0x55, 0x88}, - {0x57, 0x00}, - {0x5a, 0x40}, - {0x5b, 0x00}, - {0x5c, 0x05}, - {0xd3, 0x82}, - {0xe0, 0x00}, - {0x0, 0x0} //end flag -}; - - -static struct reginfo sensor_xga[] = -{ - {0xff, 0x00}, - {0xe0, 0x04}, - {0xc0, 0xc8}, - {0xc1, 0x96}, - {0x86, 0x3d}, - {0x50, 0x00}, - {0x51, 0x90}, - {0x52, 0x2c}, - {0x53, 0x00}, - {0x54, 0x00}, - {0x55, 0x88}, - {0x57, 0x00}, - {0x5a, 0x40}, - {0x5b, 0x00}, - {0x5c, 0x05}, - {0xd3, 0x82}, - {0xe0, 0x00}, - {0x0, 0x0} //end flag - - -}; - - -/* 800X600 SVGA*/ -static struct reginfo sensor_svga[] = -{ - {0x0, 0x0} //end flag -}; - -/* 640X480 VGA */ -static struct reginfo sensor_vga[] = -{ - {0x0, 0x0} //end flag - }; - -/* 352X288 CIF */ -static struct reginfo sensor_cif[] = -{ - {0x0, 0x0} //end flag -}; - -/* 320*240 QVGA */ -static struct reginfo sensor_qvga[] = -{ - {0x0, 0x0} //end flag -}; - -/* 176X144 QCIF*/ -static struct reginfo sensor_qcif[] = -{ - {0x0, 0x0} //end flag -}; -#if 0 -/* 160X120 QQVGA*/ -static struct reginfo ov2655_qqvga[] = -{ - - {0x300E, 0x34}, - {0x3011, 0x01}, - {0x3012, 0x10}, - {0x302a, 0x02}, - {0x302b, 0xE6}, - {0x306f, 0x14}, - {0x3362, 0x90}, - - {0x3070, 0x5d}, - {0x3072, 0x5d}, - {0x301c, 0x07}, - {0x301d, 0x07}, - - {0x3020, 0x01}, - {0x3021, 0x18}, - {0x3022, 0x00}, - {0x3023, 0x06}, - {0x3024, 0x06}, - {0x3025, 0x58}, - {0x3026, 0x02}, - {0x3027, 0x61}, - {0x3088, 0x00}, - {0x3089, 0xa0}, - {0x308a, 0x00}, - {0x308b, 0x78}, - {0x3316, 0x64}, - {0x3317, 0x25}, - {0x3318, 0x80}, - {0x3319, 0x08}, - {0x331a, 0x0a}, - {0x331b, 0x07}, - {0x331c, 0x80}, - {0x331d, 0x38}, - {0x3100, 0x00}, - {0x3302, 0x11}, - - {0x0, 0x0}, -}; - - - -static struct reginfo ov2655_Sharpness_auto[] = -{ - {0x3306, 0x00}, -}; - -static struct reginfo ov2655_Sharpness1[] = -{ - {0x3306, 0x08}, - {0x3371, 0x00}, -}; - -static struct reginfo ov2655_Sharpness2[][3] = -{ - //Sharpness 2 - {0x3306, 0x08}, - {0x3371, 0x01}, -}; - -static struct reginfo ov2655_Sharpness3[] = -{ - //default - {0x3306, 0x08}, - {0x332d, 0x02}, -}; -static struct reginfo ov2655_Sharpness4[]= -{ - //Sharpness 4 - {0x3306, 0x08}, - {0x332d, 0x03}, -}; - -static struct reginfo ov2655_Sharpness5[] = -{ - //Sharpness 5 - {0x3306, 0x08}, - {0x332d, 0x04}, -}; -#endif - -static struct reginfo sensor_ClrFmt_YUYV[]= -{ - //{0x4300, 0x30}, - {0x00, 0x00} -}; - -static struct reginfo sensor_ClrFmt_UYVY[]= -{ - //{0x4300, 0x32}, - {0x00, 0x00} -}; - -#if CONFIG_SENSOR_WhiteBalance -static struct reginfo sensor_WhiteB_Auto[]= -{ - {0x3406, 0x00}, //AWB auto, bit[1]:0,auto - {0x0000, 0x00} -}; -/* Cloudy Colour Temperature : 6500K - 8000K */ -static struct reginfo sensor_WhiteB_Cloudy[]= -{ - {0x3406, 0x01}, - {0x3400, 0x07}, - {0x3401, 0x08}, - {0x3402, 0x04}, - {0x3403, 0x00}, - {0x3404, 0x05}, - {0x3405, 0x00}, - {0x0000, 0x00} -}; -/* ClearDay Colour Temperature : 5000K - 6500K */ -static struct reginfo sensor_WhiteB_ClearDay[]= -{ - //Sunny - {0x3406, 0x01}, - {0x3400, 0x07}, - {0x3401, 0x02}, - {0x3402, 0x04}, - {0x3403, 0x00}, - {0x3404, 0x05}, - {0x3405, 0x15}, - {0x0000, 0x00} -}; -/* Office Colour Temperature : 3500K - 5000K */ -static struct reginfo sensor_WhiteB_TungstenLamp1[]= -{ - //Office - {0x3406, 0x01}, - {0x3400, 0x06}, - {0x3401, 0x2a}, - {0x3402, 0x04}, - {0x3403, 0x00}, - {0x3404, 0x07}, - {0x3405, 0x24}, - {0x0000, 0x00} - -}; -/* Home Colour Temperature : 2500K - 3500K */ -static struct reginfo sensor_WhiteB_TungstenLamp2[]= -{ - //Home - {0x3406, 0x01}, - {0x3400, 0x04}, - {0x3401, 0x58}, - {0x3402, 0x04}, - {0x3403, 0x00}, - {0x3404, 0x07}, - {0x3405, 0x24}, - {0x0000, 0x00} -}; -static struct reginfo *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2, - sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy,NULL, -}; -#endif - -#if CONFIG_SENSOR_Brightness -static struct reginfo sensor_Brightness0[]= -{ - // Brightness -2 - {0xff, 0x01}, - {0x24, 0x34}, - {0x25, 0x22}, - {0x26, 0x70}, - {0x0, 0x0} //end flag -}; - -static struct reginfo sensor_Brightness1[]= -{ - // Brightness -1 - - {0xff, 0x01}, - {0x24, 0x58}, - {0x25, 0x50}, - {0x26, 0x92}, - {0x0, 0x0} //end flag -}; - -static struct reginfo sensor_Brightness2[]= -{ - // Brightness 0 - - {0xff, 0x01}, - {0x24, 0xa8}, - {0x25, 0x90}, - {0x26, 0xd6}, - {0x0, 0x0} //end flag -}; - -static struct reginfo sensor_Brightness3[]= -{ - // Brightness +1 - - {0xff, 0x01}, - {0x24, 0x48}, - {0x25, 0x40}, - {0x26, 0x81}, - {0x0, 0x0} //end flag -}; - -static struct reginfo sensor_Brightness4[]= -{ - // Brightness +2 - - {0xff, 0x01}, - {0x24, 0x58}, - {0x25, 0x50}, - {0x26, 0x92}, - {0x0, 0x0} //end flag -}; - -static struct reginfo sensor_Brightness5[]= -{ - // Brightness +3 - {0xff, 0x01}, - {0x24, 0x70}, - {0x25, 0x60}, - {0x26, 0xa4}, - {0x0, 0x0} //end flag -}; -static struct reginfo *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3, - sensor_Brightness4, sensor_Brightness5,NULL, -}; - -#endif - -#if CONFIG_SENSOR_Effect -static struct reginfo sensor_Effect_Normal[] = -{ - {0xff,0x00}, - {0x7c,0x00}, - {0x7d,0x00}, - {0x7c,0x05}, - {0x7d,0x80}, - {0x7d,0x80}, - {0x0, 0x0} //end flag -}; - -static struct reginfo sensor_Effect_WandB[] = -{ - {0xff,0x00}, - {0x7c,0x00}, - {0x7d,0x18}, - {0x7c,0x05}, - {0x7d,0x80}, - {0x7d,0x80}, - {0x0, 0x0} //end flag -}; - -static struct reginfo sensor_Effect_Sepia[] = -{ - {0xff,0x00}, - {0x7c,0x00}, - {0x7d,0x18}, - {0x7c,0x05}, - {0x7d,0x40}, - {0x7d,0xc0}, - {0x0, 0x0} //end flag -}; - -static struct reginfo sensor_Effect_Negative[] = -{ - {0xff,0x00}, - {0x7c,0x00}, - {0x7d,0x40}, - {0x7c,0x05}, - {0x7d,0x80}, - {0x7d,0x80}, - {0x0, 0x0} //end flag -}; -static struct reginfo sensor_Effect_Bluish[] = -{ - {0Xff, 0X00}, - {0X7c, 0X00}, - {0X7d, 0X18}, - {0X7c, 0X05}, - {0X7d, 0Xa0}, - {0X7d, 0X40}, - {0x0, 0x0} //end flag -}; - -static struct reginfo sensor_Effect_Green[] = -{ - {0Xff, 0X00}, - {0X7c, 0X00}, - {0X7d, 0X18}, - {0X7c, 0X05}, - {0X7d, 0X40}, - {0X7d, 0X40}, - {0x0, 0x0} //end flag -}; - -static struct reginfo sensor_Effect_Exp_Windows_Half[] = -{ - {0xff, 0x01}, - {0x5d, 0x00}, - {0x5e, 0x3c}, - {0x5f, 0x28}, - {0x60, 0x55}, - {0x0, 0x0} //end flag -}; -static struct reginfo *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Negative,sensor_Effect_Sepia, - sensor_Effect_Bluish, sensor_Effect_Green,NULL, -}; -#endif -#if CONFIG_SENSOR_Exposure -static struct reginfo sensor_Exposure0[]= -{ - {0x0000, 0x00} -}; - -static struct reginfo sensor_Exposure1[]= -{ - {0x0000, 0x00} -}; - -static struct reginfo sensor_Exposure2[]= -{ - {0x0000, 0x00} -}; - -static struct reginfo sensor_Exposure3[]= -{ - {0x0000, 0x00} -}; - -static struct reginfo sensor_Exposure4[]= -{ - {0x0000, 0x00} -}; - -static struct reginfo sensor_Exposure5[]= -{ - {0x0000, 0x00} -}; - -static struct reginfo sensor_Exposure6[]= -{ - {0x0000, 0x00} -}; - -static struct reginfo *sensor_ExposureSeqe[] = {sensor_Exposure0, sensor_Exposure1, sensor_Exposure2, sensor_Exposure3, - sensor_Exposure4, sensor_Exposure5,sensor_Exposure6,NULL, -}; -#endif -#if CONFIG_SENSOR_Saturation -static struct reginfo sensor_Saturation0[]= -{ - {0xff, 0x00}, - {0x90, 0x00}, - {0x91, 0x0e}, - {0x91, 0x1a}, - {0x91, 0x31}, - {0x91, 0x5a}, - {0x91, 0x69}, - {0x91, 0x75}, - {0x91, 0x7e}, - {0x91, 0x88}, - {0x91, 0x8f}, - {0x91, 0x96}, - {0x91, 0xa3}, - {0x91, 0xaf}, - {0x91, 0xc4}, - {0x91, 0xd7}, - {0x91, 0xe8}, - {0x91, 0x20}, - {0x0, 0x0} //end flag -}; - -static struct reginfo sensor_Saturation1[]= -{ - {0xff, 0x00}, - {0x90, 0x00}, - {0x91, 0x03}, - {0x91, 0x0a}, - {0x91, 0x1a}, - {0x91, 0x3f}, - {0x91, 0x4e}, - {0x91, 0x5b}, - {0x91, 0x68}, - {0x91, 0x75}, - {0x91, 0x7f}, - {0x91, 0x89}, - {0x91, 0x9a}, - {0x91, 0xa6}, - {0x91, 0xbd}, - {0x91, 0xd3}, - {0x91, 0xe5}, - {0x91, 0x24}, - {0x0, 0x0} //end flag -}; - -static struct reginfo sensor_Saturation2[]= -{ - {0xff, 0x00}, - {0x90, 0x00}, - {0x91, 0x04}, - {0x91, 0x07}, - {0x91, 0x10}, - {0x91, 0x28}, - {0x91, 0x36}, - {0x91, 0x44}, - {0x91, 0x52}, - {0x91, 0x60}, - {0x91, 0x6c}, - {0x91, 0x78}, - {0x91, 0x8c}, - {0x91, 0x9e}, - {0x91, 0xbb}, - {0x91, 0xd3}, - {0x91, 0xe5}, - {0x91, 0x24}, - {0x0, 0x0} //end flag -}; -static struct reginfo *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,}; - - -#endif -#if CONFIG_SENSOR_Contrast -static struct reginfo sensor_Contrast0[]= -{ - {0xff, 0x00}, - {0x7c, 0x00}, - {0x7d, 0x04}, - {0x7c, 0x07}, - {0x7d, 0x20}, - {0x7d, 0x10}, - {0x7d, 0x4a}, - {0x7d, 0x06}, - {0x0, 0x0} //end flag - -}; - -static struct reginfo sensor_Contrast1[]= -{ - {0xff, 0x00}, - {0x7c, 0x00}, - {0x7d, 0x04}, - {0x7c, 0x07}, - {0x7d, 0x20}, - {0x7d, 0x14}, - {0x7d, 0x40}, - {0x7d, 0x06}, - {0x0, 0x0} //end flag -}; - -static struct reginfo sensor_Contrast2[]= -{ - {0xff, 0x00}, - {0x7c, 0x00}, - {0x7d, 0x04}, - {0x7c, 0x07}, - {0x7d, 0x20}, - {0x7d, 0x18}, - {0x7d, 0x34}, - {0x7d, 0x06}, - {0x0, 0x0} //end flag -}; - -static struct reginfo sensor_Contrast3[]= -{ - {0xff, 0x00}, - {0x7c, 0x00}, - {0x7d, 0x04}, - {0x7c, 0x07}, - {0x7d, 0x20}, - {0x7d, 0x1c}, - {0x7d, 0x2a}, - {0x7d, 0x06}, - {0x0, 0x0} //end flag -}; - -static struct reginfo sensor_Contrast4[]= -{ - {0xff,0x00}, - {0x7c,0x00}, - {0x7d,0x04}, - {0x7c,0x07}, - {0x7d,0x20}, - {0x7d,0x24}, - {0x7d,0x16}, - {0x7d,0x06}, - {0x0, 0x0} //end flag -}; - - -static struct reginfo sensor_Contrast5[]= -{ - {0xff, 0x00}, - {0x7c, 0x00}, - {0x7d, 0x04}, - {0x7c, 0x07}, - {0x7d, 0x20}, - {0x7d, 0x20}, - {0x7d, 0x20}, - {0x7d, 0x06}, - {0x0, 0x0} //end flag -}; - -static struct reginfo sensor_Contrast6[]= -{ - {0xff, 0x00}, - {0x7c, 0x00}, - {0x7d, 0x04}, - {0x7c, 0x07}, - {0x7d, 0x20}, - {0x7d, 0x24}, - {0x7d, 0x16}, - {0x7d, 0x06}, - {0x0, 0x0} //end flag -}; - - -static struct reginfo sensor_Contrast7[]= -{ - {0xff, 0x00}, - {0x7c, 0x00}, - {0x7d, 0x04}, - {0x7c, 0x07}, - {0x7d, 0x20}, - {0x7d, 0x28}, - {0x7d, 0x0c}, - {0x7d, 0x06}, - {0x0, 0x0} //end flag -}; - -static struct reginfo sensor_Contrast8[]= -{ - {0xff, 0x00}, - {0x7c, 0x00}, - {0x7d, 0x04}, - {0x7c, 0x07}, - {0x7d, 0x20}, - {0x7d, 0x2c}, - {0x7d, 0x02}, - {0x7d, 0x06}, - {0x0, 0x0} //end flag -}; - -static struct reginfo sensor_Contrast9[]= -{ - {0xff, 0x00}, - {0x7c, 0x00}, - {0x7d, 0x04}, - {0x7c, 0x07}, - {0x7d, 0x20}, - {0x7d, 0x30}, - {0x7d, 0x08}, - {0x7d, 0x0e}, - {0x0, 0x0} //end flag -}; - - - -static struct reginfo *sensor_ContrastSeqe[] = {sensor_Contrast0, sensor_Contrast1, sensor_Contrast2, sensor_Contrast3, - sensor_Contrast4, sensor_Contrast5, sensor_Contrast6, NULL, -}; - -#endif -#if CONFIG_SENSOR_Mirror -static struct reginfo sensor_MirrorOn[]= -{ - {0x0000, 0x00} -}; - -static struct reginfo sensor_MirrorOff[]= -{ - {0x0000, 0x00} -}; -static struct reginfo *sensor_MirrorSeqe[] = {sensor_MirrorOff, sensor_MirrorOn,NULL,}; -#endif -#if CONFIG_SENSOR_Flip -static struct reginfo sensor_FlipOn[]= -{ - {0x0000, 0x00} -}; - -static struct reginfo sensor_FlipOff[]= -{ - {0x0000, 0x00} -}; -static struct reginfo *sensor_FlipSeqe[] = {sensor_FlipOff, sensor_FlipOn,NULL,}; - -#endif -#if CONFIG_SENSOR_Scene -static struct reginfo sensor_SceneAuto[] = -{ - {0x3a00, 0x78}, - {0x0000, 0x00} -}; - -static struct reginfo sensor_SceneNight[] = -{ - {0x3003, 0x80}, - {0x3004, 0x20}, - {0x3005, 0x18}, - {0x3006, 0x0d}, - {0x3a00, 0x7c}, - {0x3a02 ,0x07}, - {0x3a03 ,0x38}, - {0x3a14 ,0x07}, - {0x3a15 ,0x38}, - {0x0000, 0x00} -}; -static struct reginfo *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,}; - -#endif -#if CONFIG_SENSOR_DigitalZoom -static struct reginfo sensor_Zoom0[] = -{ - {0x0, 0x0}, -}; - -static struct reginfo sensor_Zoom1[] = -{ - {0x0, 0x0}, -}; - -static struct reginfo sensor_Zoom2[] = -{ - {0x0, 0x0}, -}; - - -static struct reginfo sensor_Zoom3[] = -{ - {0x0, 0x0}, -}; -static struct reginfo *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL,}; -#endif -static const struct v4l2_querymenu sensor_menus[] = -{ - #if CONFIG_SENSOR_WhiteBalance - { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 0, .name = "auto", .reserved = 0, }, { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 1, .name = "incandescent", .reserved = 0,}, - { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 2, .name = "fluorescent", .reserved = 0,}, { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 3, .name = "daylight", .reserved = 0,}, - { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 4, .name = "cloudy-daylight", .reserved = 0,}, - #endif - - #if CONFIG_SENSOR_Effect - { .id = V4L2_CID_EFFECT, .index = 0, .name = "none", .reserved = 0, }, { .id = V4L2_CID_EFFECT, .index = 1, .name = "mono", .reserved = 0,}, - { .id = V4L2_CID_EFFECT, .index = 2, .name = "negative", .reserved = 0,}, { .id = V4L2_CID_EFFECT, .index = 3, .name = "sepia", .reserved = 0,}, - { .id = V4L2_CID_EFFECT, .index = 4, .name = "posterize", .reserved = 0,} ,{ .id = V4L2_CID_EFFECT, .index = 5, .name = "aqua", .reserved = 0,}, - #endif - - #if CONFIG_SENSOR_Scene - { .id = V4L2_CID_SCENE, .index = 0, .name = "auto", .reserved = 0,} ,{ .id = V4L2_CID_SCENE, .index = 1, .name = "night", .reserved = 0,}, - #endif - - #if CONFIG_SENSOR_Flash - { .id = V4L2_CID_FLASH, .index = 0, .name = "off", .reserved = 0, }, { .id = V4L2_CID_FLASH, .index = 1, .name = "auto", .reserved = 0,}, - { .id = V4L2_CID_FLASH, .index = 2, .name = "on", .reserved = 0,}, { .id = V4L2_CID_FLASH, .index = 3, .name = "torch", .reserved = 0,}, - #endif -}; - -static const struct v4l2_queryctrl sensor_controls[] = -{ - #if CONFIG_SENSOR_WhiteBalance - { - .id = V4L2_CID_DO_WHITE_BALANCE, - .type = V4L2_CTRL_TYPE_MENU, - .name = "White Balance Control", - .minimum = 0, - .maximum = 4, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Brightness - { - .id = V4L2_CID_BRIGHTNESS, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Brightness Control", - .minimum = -3, - .maximum = 2, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Effect - { - .id = V4L2_CID_EFFECT, - .type = V4L2_CTRL_TYPE_MENU, - .name = "Effect Control", - .minimum = 0, - .maximum = 5, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Exposure - { - .id = V4L2_CID_EXPOSURE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Exposure Control", - .minimum = 0, - .maximum = 6, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Saturation - { - .id = V4L2_CID_SATURATION, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Saturation Control", - .minimum = 0, - .maximum = 2, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Contrast - { - .id = V4L2_CID_CONTRAST, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Contrast Control", - .minimum = -3, - .maximum = 3, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Mirror - { - .id = V4L2_CID_HFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Mirror Control", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1, - }, - #endif - - #if CONFIG_SENSOR_Flip - { - .id = V4L2_CID_VFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Flip Control", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1, - }, - #endif - - #if CONFIG_SENSOR_Scene - { - .id = V4L2_CID_SCENE, - .type = V4L2_CTRL_TYPE_MENU, - .name = "Scene Control", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_DigitalZoom - { - .id = V4L2_CID_ZOOM_RELATIVE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "DigitalZoom Control", - .minimum = -1, - .maximum = 1, - .step = 1, - .default_value = 0, - }, { - .id = V4L2_CID_ZOOM_ABSOLUTE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "DigitalZoom Control", - .minimum = 0, - .maximum = 3, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Focus - { - .id = V4L2_CID_FOCUS_RELATIVE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Focus Control", - .minimum = -1, - .maximum = 1, - .step = 1, - .default_value = 0, - }, { - .id = V4L2_CID_FOCUS_ABSOLUTE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Focus Control", - .minimum = 0, - .maximum = 255, - .step = 1, - .default_value = 125, - }, - #endif - - #if CONFIG_SENSOR_Flash - { - .id = V4L2_CID_FLASH, - .type = V4L2_CTRL_TYPE_MENU, - .name = "Flash Control", - .minimum = 0, - .maximum = 3, - .step = 1, - .default_value = 0, - }, - #endif -}; - -static int sensor_probe(struct i2c_client *client, const struct i2c_device_id *did); -static int sensor_video_probe(struct soc_camera_device *icd, struct i2c_client *client); -static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl); -static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl); -static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl); -static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl); -static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg); -static int sensor_resume(struct soc_camera_device *icd); -static int sensor_set_bus_param(struct soc_camera_device *icd,unsigned long flags); -static unsigned long sensor_query_bus_param(struct soc_camera_device *icd); -#if CONFIG_SENSOR_Effect -static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value); -#endif -#if CONFIG_SENSOR_WhiteBalance -static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value); -#endif -static int sensor_deactivate(struct i2c_client *client); - -static struct soc_camera_ops sensor_ops = -{ - .suspend = sensor_suspend, - .resume = sensor_resume, - .set_bus_param = sensor_set_bus_param, - .query_bus_param = sensor_query_bus_param, - .controls = sensor_controls, - .menus = sensor_menus, - .num_controls = ARRAY_SIZE(sensor_controls), - .num_menus = ARRAY_SIZE(sensor_menus), -}; - -/* only one fixed colorspace per pixelcode */ -struct sensor_datafmt { - enum v4l2_mbus_pixelcode code; - enum v4l2_colorspace colorspace; -}; - -/* Find a data format by a pixel code in an array */ -static const struct sensor_datafmt *sensor_find_datafmt( - enum v4l2_mbus_pixelcode code, const struct sensor_datafmt *fmt, - int n) -{ - int i; - for (i = 0; i < n; i++) - if (fmt[i].code == code) - return fmt + i; - - return NULL; -} - -static const struct sensor_datafmt sensor_colour_fmts[] = { - {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG}, - {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} -}; - -typedef struct sensor_info_priv_s -{ - int whiteBalance; - int brightness; - int contrast; - int saturation; - int effect; - int scene; - int digitalzoom; - int focus; - int flash; - int exposure; - bool snap2preview; - bool video2preview; - unsigned char mirror; /* HFLIP */ - unsigned char flip; /* VFLIP */ - unsigned int winseqe_cur_addr; - struct sensor_datafmt fmt; - -} sensor_info_priv_t; - -struct sensor -{ - struct v4l2_subdev subdev; - struct i2c_client *client; - sensor_info_priv_t info_priv; - int model; /* V4L2_IDENT_OV* codes from v4l2-chip-ident.h */ -#if CONFIG_SENSOR_I2C_NOSCHED - atomic_t tasklock_cnt; -#endif - struct rk29camera_platform_data *sensor_io_request; - struct rk29camera_gpio_res *sensor_gpio_res; -}; - -static struct sensor* to_sensor(const struct i2c_client *client) -{ - return container_of(i2c_get_clientdata(client), struct sensor, subdev); -} - -static int sensor_task_lock(struct i2c_client *client, int lock) -{ -#if CONFIG_SENSOR_I2C_NOSCHED - int cnt = 3; - struct sensor *sensor = to_sensor(client); - - if (lock) { - if (atomic_read(&sensor->tasklock_cnt) == 0) { - while ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt>0)) { - SENSOR_TR("\n %s will obtain i2c in atomic, but i2c bus is locked! Wait...\n",SENSOR_NAME_STRING()); - msleep(35); - cnt--; - } - if ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt<=0)) { - SENSOR_TR("\n %s obtain i2c fail in atomic!!\n",SENSOR_NAME_STRING()); - goto sensor_task_lock_err; - } - preempt_disable(); - } - - atomic_add(1, &sensor->tasklock_cnt); - } else { - if (atomic_read(&sensor->tasklock_cnt) > 0) { - atomic_sub(1, &sensor->tasklock_cnt); - - if (atomic_read(&sensor->tasklock_cnt) == 0) - preempt_enable(); - } - } - return 0; -sensor_task_lock_err: - return -1; -#else - return 0; -#endif - -} -static int sensor_write(struct i2c_client *client, u8 reg, u8 val) -{ - int err,cnt; - u8 buf[2]; - struct i2c_msg msg[1]; - - buf[0] = reg & 0xFF; - buf[1] = val; - - msg->addr = client->addr; - msg->flags = client->flags; - msg->buf = buf; - msg->len = sizeof(buf); - msg->scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ - msg->read_type = 0; /* fpga i2c:0==I2C_NORMAL : direct use number not enum for don't want include spi_fpga.h */ - - cnt = 3; - err = -EAGAIN; - - while ((cnt-->0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ - err = i2c_transfer(client->adapter, msg, 1); - - if (err >= 0) { - return 0; - } else { - SENSOR_TR("\n %s write reg(0x%x, val:0x%x) failed, try to write again!\n",SENSOR_NAME_STRING(),reg, val); - udelay(10); - } - } - - return err; -} - -/* sensor register read */ -static int sensor_read(struct i2c_client *client, u8 reg, u8 *val) -{ - int err,cnt; - u8 buf[1]; - struct i2c_msg msg[2]; - - buf[0] = reg ;//>> 8; - // buf[1] = 0; - - msg[0].addr = client->addr; - msg[0].flags = client->flags; - msg[0].buf = buf; - msg[0].len = sizeof(buf); - msg[0].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ - msg[0].read_type = 2;//0x55; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */ - - msg[1].addr = client->addr; - msg[1].flags = client->flags|I2C_M_RD; - msg[1].buf = buf; - msg[1].len = 1; - msg[1].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ - msg[1].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */ - - cnt = 3; - err = -EAGAIN; - while ((cnt-->0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ - err = i2c_transfer(client->adapter, msg, 2); - - if (err >= 0) { - *val = buf[0]; - return 0; - } else { - SENSOR_TR("\n %s read reg(0x%x val:0x%x) failed, try to read again! \n",SENSOR_NAME_STRING(),reg, *val); - udelay(10); - } - } - - return err; -} - -/* write a array of registers */ -static int sensor_write_array(struct i2c_client *client, struct reginfo *regarray) -{ - int err = 0, cnt; - int i = 0; -#if CONFIG_SENSOR_I2C_RDWRCHK - char valchk; -#endif - - cnt = 0; - if (sensor_task_lock(client, 1) < 0) - goto sensor_write_array_end; - while (regarray[i].reg != 0) - { - err = sensor_write(client, regarray[i].reg, regarray[i].val); - if (err < 0) - { - if (cnt-- > 0) { - SENSOR_TR("%s..write failed current reg:0x%x, Write array again !\n", SENSOR_NAME_STRING(),regarray[i].reg); - i = 0; - continue; - } else { - SENSOR_TR("%s..write array failed!!!\n", SENSOR_NAME_STRING()); - err = -EPERM; - goto sensor_write_array_end; - } - } else { - #if CONFIG_SENSOR_I2C_RDWRCHK - sensor_read(client, regarray[i].reg, &valchk); - if (valchk != regarray[i].val) - SENSOR_TR("%s Reg:0x%x write(0x%x, 0x%x) fail\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk); - #endif - } - i++; - } - -sensor_write_array_end: - sensor_task_lock(client,0); - return err; -} -#if CONFIG_SENSOR_I2C_RDWRCHK -static int sensor_readchk_array(struct i2c_client *client, struct reginfo *regarray) -{ - int cnt; - int i = 0; - char valchk; - - cnt = 0; - valchk = 0; - while (regarray[i].reg != 0) - { - sensor_read(client, regarray[i].reg, &valchk); - if (valchk != regarray[i].val) - SENSOR_TR("%s Reg:0x%x read(0x%x, 0x%x) error\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk); - - i++; - } - return 0; -} -#endif -static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd cmd, int on) -{ - struct soc_camera_link *icl = to_soc_camera_link(icd); - int ret = 0; - - SENSOR_DG("%s %s cmd(%d) on(%d)\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd,on); - - switch (cmd) - { - case Sensor_PowerDown: - { - if (icl->powerdown) { - ret = icl->powerdown(icd->pdev, on); - if (ret == RK29_CAM_IO_SUCCESS) { - if (on == 0) { - mdelay(2); - if (icl->reset) - icl->reset(icd->pdev); - } - } else if (ret == RK29_CAM_EIO_REQUESTFAIL) { - ret = -ENODEV; - goto sensor_power_end; - } - } - break; - } - case Sensor_Flash: - { - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - - if (sensor->sensor_io_request && sensor->sensor_io_request->sensor_ioctrl) { - sensor->sensor_io_request->sensor_ioctrl(icd->pdev,Cam_Flash, on); - } - break; - } - default: - { - SENSOR_TR("%s %s cmd(0x%x) is unknown!",SENSOR_NAME_STRING(),__FUNCTION__,cmd); - break; - } - } -sensor_power_end: - return ret; -} -static int sensor_init(struct v4l2_subdev *sd, u32 val) -{ - struct i2c_client *client = sd->priv; - struct soc_camera_device *icd = client->dev.platform_data; - struct sensor *sensor = to_sensor(client); - const struct v4l2_queryctrl *qctrl; - const struct sensor_datafmt *fmt; - char value; - int ret,pid = 0; - - SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); - - if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { - ret = -ENODEV; - goto sensor_INIT_ERR; - } - - /* soft reset */ - if (sensor_task_lock(client,1)<0) - goto sensor_INIT_ERR; - ret = sensor_write(client, 0xff, 1); - ret |= sensor_write(client, 0x12, 0x80); - if (ret != 0) - { - SENSOR_TR("%s soft reset sensor failed\n",SENSOR_NAME_STRING()); - ret = -ENODEV; - goto sensor_INIT_ERR; - } - - mdelay(5); //delay 5 microseconds - /* check if it is an sensor sensor */ - ret = sensor_write(client, 0xff, 1); - ret |= sensor_read(client, 0x0a, &value); - if (ret != 0) { - SENSOR_TR("read chip id high byte failed\n"); - ret = -ENODEV; - goto sensor_INIT_ERR; - } - - pid = value << 8; - ret = sensor_read(client, 0x0b, &value); - if (ret != 0) { - SENSOR_TR("read chip id low byte failed\n"); - ret = -ENODEV; - goto sensor_INIT_ERR; - } - - pid |= (value & 0xff); - - SENSOR_DG("\n %s pid = 0x%x\n", SENSOR_NAME_STRING(), pid); - if ((pid == SENSOR_ID)||(pid == SENSOR_ID1)) { - sensor->model = SENSOR_V4L2_IDENT; - } else { - SENSOR_TR("error: %s mismatched pid = 0x%x\n", SENSOR_NAME_STRING(), pid); - ret = -ENODEV; - goto sensor_INIT_ERR; - } - - ret = sensor_write_array(client, sensor_init_data); - if (ret != 0) - { - SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING()); - goto sensor_INIT_ERR; - } - sensor_task_lock(client,0); - sensor->info_priv.winseqe_cur_addr = (int)SENSOR_INIT_WINSEQADR; - fmt = sensor_find_datafmt(SENSOR_INIT_PIXFMT,sensor_colour_fmts, ARRAY_SIZE(sensor_colour_fmts)); - if (!fmt) { - SENSOR_TR("error: %s initial array colour fmts is not support!!",SENSOR_NAME_STRING()); - ret = -EINVAL; - goto sensor_INIT_ERR; - } - sensor->info_priv.fmt = *fmt; - - /* sensor sensor information for initialization */ - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); - if (qctrl) - sensor->info_priv.whiteBalance = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_BRIGHTNESS); - if (qctrl) - sensor->info_priv.brightness = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); - if (qctrl) - sensor->info_priv.effect = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EXPOSURE); - if (qctrl) - sensor->info_priv.exposure = qctrl->default_value; - - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SATURATION); - if (qctrl) - sensor->info_priv.saturation = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_CONTRAST); - if (qctrl) - sensor->info_priv.contrast = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_HFLIP); - if (qctrl) - sensor->info_priv.mirror = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_VFLIP); - if (qctrl) - sensor->info_priv.flip = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SCENE); - if (qctrl) - sensor->info_priv.scene = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE); - if (qctrl) - sensor->info_priv.digitalzoom = qctrl->default_value; - - /* ddl@rock-chips.com : if sensor support auto focus and flash, programer must run focus and flash code */ - #if CONFIG_SENSOR_Focus - sensor_set_focus(); - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FOCUS_ABSOLUTE); - if (qctrl) - sensor->info_priv.focus = qctrl->default_value; - #endif - - #if CONFIG_SENSOR_Flash - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FLASH); - if (qctrl) - sensor->info_priv.flash = qctrl->default_value; - #endif - - SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),((val == 0)?__FUNCTION__:"sensor_reinit"),icd->user_width,icd->user_height); - - return 0; -sensor_INIT_ERR: - sensor_task_lock(client,0); - sensor_deactivate(client); - return ret; -} - -static int sensor_deactivate(struct i2c_client *client) -{ - struct soc_camera_device *icd = client->dev.platform_data; - - SENSOR_DG("\n%s..%s.. Enter\n",SENSOR_NAME_STRING(),__FUNCTION__); - - /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */ -#if 0 - sensor_task_lock(client, 1); - sensor_write(client, 0x3000, reg_val&0xfc); - sensor_write(client, 0x3001, 0x00); - sensor_task_lock(client, 0); -#endif - sensor_ioctrl(icd, Sensor_PowerDown, 1); - /* ddl@rock-chips.com : sensor config init width , because next open sensor quickly(soc_camera_open -> Try to configure with default parameters) */ - icd->user_width = SENSOR_INIT_WIDTH; - icd->user_height = SENSOR_INIT_HEIGHT; - msleep(100); - return 0; -} - -static struct reginfo sensor_power_down_sequence[]= -{ - {0x00,0x00} -}; -static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg) -{ - int ret; - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if (pm_msg.event == PM_EVENT_SUSPEND) { - SENSOR_DG("\n %s Enter Suspend.. \n", SENSOR_NAME_STRING()); - ret = sensor_write_array(client, sensor_power_down_sequence) ; - if (ret != 0) { - SENSOR_TR("\n %s..%s WriteReg Fail.. \n", SENSOR_NAME_STRING(),__FUNCTION__); - return ret; - } else { - ret = sensor_ioctrl(icd, Sensor_PowerDown, 1); - if (ret < 0) { - SENSOR_TR("\n %s suspend fail for turn on power!\n", SENSOR_NAME_STRING()); - return -EINVAL; - } - } - } else { - SENSOR_TR("\n %s cann't suppout Suspend..\n",SENSOR_NAME_STRING()); - return -EINVAL; - } - return 0; -} - -static int sensor_resume(struct soc_camera_device *icd) -{ - int ret; - - ret = sensor_ioctrl(icd, Sensor_PowerDown, 0); - if (ret < 0) { - SENSOR_TR("\n %s resume fail for turn on power!\n", SENSOR_NAME_STRING()); - return -EINVAL; - } - - SENSOR_DG("\n %s Enter Resume.. \n", SENSOR_NAME_STRING()); - - return 0; - -} - -static int sensor_set_bus_param(struct soc_camera_device *icd, - unsigned long flags) -{ - - return 0; -} - -static unsigned long sensor_query_bus_param(struct soc_camera_device *icd) -{ - struct soc_camera_link *icl = to_soc_camera_link(icd); - unsigned long flags = SENSOR_BUS_PARAM; - - return soc_camera_apply_sensor_flags(icl, flags); -} - -static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - struct i2c_client *client = sd->priv; - struct soc_camera_device *icd = client->dev.platform_data; - struct sensor *sensor = to_sensor(client); - - mf->width = icd->user_width; - mf->height = icd->user_height; - mf->code = sensor->info_priv.fmt.code; - mf->colorspace = sensor->info_priv.fmt.colorspace; - mf->field = V4L2_FIELD_NONE; - - return 0; -} -static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - bool ret = false; - - if ((mf->width == 1024) && (mf->height == 768)) { - ret = true; - } else if ((mf->width == 1280) && (mf->height == 1024)) { - ret = true; - } else if ((mf->width == 1600) && (mf->height == 1200)) { - ret = true; - } else if ((mf->width == 2048) && (mf->height == 1536)) { - ret = true; - } else if ((mf->width == 2592) && (mf->height == 1944)) { - ret = true; - } - - if (ret == true) - SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, mf->width, mf->height); - return ret; -} - -static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - bool ret = false; - - if ((mf->width == 1280) && (mf->height == 720)) { - ret = true; - } else if ((mf->width == 1920) && (mf->height == 1080)) { - ret = true; - } - - if (ret == true) - SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, mf->width, mf->height); - return ret; -} -static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - struct i2c_client *client = sd->priv; - struct sensor *sensor = to_sensor(client); - const struct sensor_datafmt *fmt; - const struct v4l2_queryctrl *qctrl; - struct soc_camera_device *icd = client->dev.platform_data; - struct reginfo *winseqe_set_addr=NULL; - int ret=0, set_w,set_h; - - fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, - ARRAY_SIZE(sensor_colour_fmts)); - if (!fmt) { - ret = -EINVAL; - goto sensor_s_fmt_end; - } - - if (sensor->info_priv.fmt.code != mf->code) { - switch (mf->code) - { - case V4L2_MBUS_FMT_YUYV8_2X8: - { - winseqe_set_addr = sensor_ClrFmt_YUYV; - break; - } - case V4L2_MBUS_FMT_UYVY8_2X8: - { - winseqe_set_addr = sensor_ClrFmt_UYVY; - break; - } - default: - break; - } - if (winseqe_set_addr != NULL) { - sensor_write_array(client, winseqe_set_addr); - sensor->info_priv.fmt.code = mf->code; - sensor->info_priv.fmt.colorspace= mf->colorspace; - SENSOR_DG("%s v4l2_mbus_code:%d set success!\n", SENSOR_NAME_STRING(),mf->code); - } else { - SENSOR_TR("%s v4l2_mbus_code:%d is invalidate!\n", SENSOR_NAME_STRING(),mf->code); - } - } - - set_w = mf->width; - set_h = mf->height; - - if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg) - { - winseqe_set_addr = sensor_qcif; - set_w = 176; - set_h = 144; - } - else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg) - { - winseqe_set_addr = sensor_qvga; - set_w = 320; - set_h = 240; - } - else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg) - { - winseqe_set_addr = sensor_cif; - set_w = 352; - set_h = 288; - } - else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg) - { - winseqe_set_addr = sensor_vga; - set_w = 640; - set_h = 480; - } - else if (((set_w <= 800) && (set_h <= 600)) && sensor_svga[0].reg) - { - winseqe_set_addr = sensor_svga; - set_w = 800; - set_h = 600; - } - else if (((set_w <= 1024) && (set_h <= 768)) && sensor_xga[0].reg) - { - winseqe_set_addr = sensor_xga; - set_w = 1024; - set_h = 768; - } - else if (((set_w <= 1280) && (set_h <= 1024)) && sensor_sxga[0].reg) - { - winseqe_set_addr = sensor_sxga; - set_w = 1280; - set_h = 1024; - } - else if (((set_w <= 1600) && (set_h <= 1200)) && sensor_uxga[0].reg) - { - winseqe_set_addr = sensor_uxga; - set_w = 1600; - set_h = 1200; - } - else - { - winseqe_set_addr = SENSOR_INIT_WINSEQADR; /* ddl@rock-chips.com : Sensor output smallest size if isn't support app */ - set_w = SENSOR_INIT_WIDTH; - set_h = SENSOR_INIT_HEIGHT; - SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,mf->width,mf->height); - } - - if ((int)winseqe_set_addr != sensor->info_priv.winseqe_cur_addr) { - #if CONFIG_SENSOR_Flash - if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ - if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { - sensor_ioctrl(icd, Sensor_Flash, Flash_On); - SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING()); - } - } else { /* ddl@rock-chips.com : Video */ - if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { - sensor_ioctrl(icd, Sensor_Flash, Flash_Off); - SENSOR_DG("%s flash off in preivew!\n", SENSOR_NAME_STRING()); - } - } - #endif - ret |= sensor_write_array(client, winseqe_set_addr); - if (ret != 0) { - SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING()); - #if CONFIG_SENSOR_Flash - if (sensor_fmt_capturechk(sd,mf) == true) { - if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { - sensor_ioctrl(icd, Sensor_Flash, Flash_Off); - SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING()); - } - } - #endif - goto sensor_s_fmt_end; - } - - sensor->info_priv.winseqe_cur_addr = (int)winseqe_set_addr; - - if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ - #if CONFIG_SENSOR_Effect - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); - sensor_set_effect(icd, qctrl,sensor->info_priv.effect); - #endif - #if CONFIG_SENSOR_WhiteBalance - if (sensor->info_priv.whiteBalance != 0) { - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); - sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); - } - #endif - sensor->info_priv.snap2preview = true; - } else if (sensor_fmt_videochk(sd,mf) == true) { /* ddl@rock-chips.com : Video */ - #if CONFIG_SENSOR_Effect - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); - sensor_set_effect(icd, qctrl,sensor->info_priv.effect); - #endif - #if CONFIG_SENSOR_WhiteBalance - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); - sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); - #endif - sensor->info_priv.video2preview = true; - } else if ((sensor->info_priv.snap2preview == true) || (sensor->info_priv.video2preview == true)) { - #if CONFIG_SENSOR_Effect - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); - sensor_set_effect(icd, qctrl,sensor->info_priv.effect); - #endif - #if CONFIG_SENSOR_WhiteBalance - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); - sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); - #endif - sensor->info_priv.video2preview = false; - sensor->info_priv.snap2preview = false; - } - SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),__FUNCTION__,set_w,set_h); - } - else - { - SENSOR_DG("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h); - } - - mf->width = set_w; - mf->height = set_h; - -sensor_s_fmt_end: - return ret; -} - -static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - struct i2c_client *client = sd->priv; - struct sensor *sensor = to_sensor(client); - const struct sensor_datafmt *fmt; - int ret = 0; - - fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, - ARRAY_SIZE(sensor_colour_fmts)); - if (fmt == NULL) { - fmt = &sensor->info_priv.fmt; - mf->code = fmt->code; - } - - if (mf->height > SENSOR_MAX_HEIGHT) - mf->height = SENSOR_MAX_HEIGHT; - else if (mf->height < SENSOR_MIN_HEIGHT) - mf->height = SENSOR_MIN_HEIGHT; - - if (mf->width > SENSOR_MAX_WIDTH) - mf->width = SENSOR_MAX_WIDTH; - else if (mf->width < SENSOR_MIN_WIDTH) - mf->width = SENSOR_MIN_WIDTH; - - mf->colorspace = fmt->colorspace; - - return ret; -} - static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id) -{ - struct i2c_client *client = sd->priv; - - if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) - return -EINVAL; - - if (id->match.addr != client->addr) - return -ENODEV; - - id->ident = SENSOR_V4L2_IDENT; /* ddl@rock-chips.com : Return OV2655 identifier */ - id->revision = 0; - - return 0; -} -#if CONFIG_SENSOR_Brightness -static int sensor_set_brightness(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_BrightnessSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_BrightnessSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Effect -static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_EffectSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_EffectSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Exposure -static int sensor_set_exposure(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_ExposureSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_ExposureSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Saturation -static int sensor_set_saturation(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_SaturationSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_SaturationSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Contrast -static int sensor_set_contrast(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_ContrastSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_ContrastSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Mirror -static int sensor_set_mirror(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_MirrorSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_MirrorSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Flip -static int sensor_set_flip(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_FlipSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_FlipSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Scene -static int sensor_set_scene(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_SceneSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_SceneSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_WhiteBalance -static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_WhiteBalanceSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_WhiteBalanceSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_DigitalZoom -static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int *value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - const struct v4l2_queryctrl *qctrl_info; - int digitalzoom_cur, digitalzoom_total; - - qctrl_info = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE); - if (qctrl_info) - return -EINVAL; - - digitalzoom_cur = sensor->info_priv.digitalzoom; - digitalzoom_total = qctrl_info->maximum; - - if ((*value > 0) && (digitalzoom_cur >= digitalzoom_total)) - { - SENSOR_TR("%s digitalzoom is maximum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); - return -EINVAL; - } - - if ((*value < 0) && (digitalzoom_cur <= qctrl_info->minimum)) - { - SENSOR_TR("%s digitalzoom is minimum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); - return -EINVAL; - } - - if ((*value > 0) && ((digitalzoom_cur + *value) > digitalzoom_total)) - { - *value = digitalzoom_total - digitalzoom_cur; - } - - if ((*value < 0) && ((digitalzoom_cur + *value) < 0)) - { - *value = 0 - digitalzoom_cur; - } - - digitalzoom_cur += *value; - - if (sensor_ZoomSeqe[digitalzoom_cur] != NULL) - { - if (sensor_write_array(client, sensor_ZoomSeqe[digitalzoom_cur]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, *value); - return 0; - } - - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Flash -static int sensor_set_flash(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) { - if (value == 3) { /* ddl@rock-chips.com: torch */ - sensor_ioctrl(icd, Sensor_Flash, Flash_Torch); /* Flash On */ - } else { - sensor_ioctrl(icd, Sensor_Flash, Flash_Off); - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif - -static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) -{ - struct i2c_client *client = sd->priv; - struct sensor *sensor = to_sensor(client); - const struct v4l2_queryctrl *qctrl; - - qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id); - - if (!qctrl) - { - SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ctrl->id); - return -EINVAL; - } - - switch (ctrl->id) - { - case V4L2_CID_BRIGHTNESS: - { - ctrl->value = sensor->info_priv.brightness; - break; - } - case V4L2_CID_SATURATION: - { - ctrl->value = sensor->info_priv.saturation; - break; - } - case V4L2_CID_CONTRAST: - { - ctrl->value = sensor->info_priv.contrast; - break; - } - case V4L2_CID_DO_WHITE_BALANCE: - { - ctrl->value = sensor->info_priv.whiteBalance; - break; - } - case V4L2_CID_EXPOSURE: - { - ctrl->value = sensor->info_priv.exposure; - break; - } - case V4L2_CID_HFLIP: - { - ctrl->value = sensor->info_priv.mirror; - break; - } - case V4L2_CID_VFLIP: - { - ctrl->value = sensor->info_priv.flip; - break; - } - default : - break; - } - return 0; -} - - - -static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) -{ - struct i2c_client *client = sd->priv; - struct sensor *sensor = to_sensor(client); - struct soc_camera_device *icd = client->dev.platform_data; - const struct v4l2_queryctrl *qctrl; - - - qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id); - - if (!qctrl) - { - SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ctrl->id); - return -EINVAL; - } - - switch (ctrl->id) - { -#if CONFIG_SENSOR_Brightness - case V4L2_CID_BRIGHTNESS: - { - if (ctrl->value != sensor->info_priv.brightness) - { - if (sensor_set_brightness(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.brightness = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Exposure - case V4L2_CID_EXPOSURE: - { - if (ctrl->value != sensor->info_priv.exposure) - { - if (sensor_set_exposure(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.exposure = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Saturation - case V4L2_CID_SATURATION: - { - if (ctrl->value != sensor->info_priv.saturation) - { - if (sensor_set_saturation(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.saturation = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Contrast - case V4L2_CID_CONTRAST: - { - if (ctrl->value != sensor->info_priv.contrast) - { - if (sensor_set_contrast(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.contrast = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_WhiteBalance - case V4L2_CID_DO_WHITE_BALANCE: - { - if (ctrl->value != sensor->info_priv.whiteBalance) - { - if (sensor_set_whiteBalance(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.whiteBalance = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Mirror - case V4L2_CID_HFLIP: - { - if (ctrl->value != sensor->info_priv.mirror) - { - if (sensor_set_mirror(icd, qctrl,ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.mirror = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Flip - case V4L2_CID_VFLIP: - { - if (ctrl->value != sensor->info_priv.flip) - { - if (sensor_set_flip(icd, qctrl,ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.flip = ctrl->value; - } - break; - } -#endif - default: - break; - } - - return 0; -} -static int sensor_g_ext_control(struct soc_camera_device *icd , struct v4l2_ext_control *ext_ctrl) -{ - const struct v4l2_queryctrl *qctrl; - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - - qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id); - - if (!qctrl) - { - SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id); - return -EINVAL; - } - - switch (ext_ctrl->id) - { - case V4L2_CID_SCENE: - { - ext_ctrl->value = sensor->info_priv.scene; - break; - } - case V4L2_CID_EFFECT: - { - ext_ctrl->value = sensor->info_priv.effect; - break; - } - case V4L2_CID_ZOOM_ABSOLUTE: - { - ext_ctrl->value = sensor->info_priv.digitalzoom; - break; - } - case V4L2_CID_ZOOM_RELATIVE: - { - return -EINVAL; - } - case V4L2_CID_FOCUS_ABSOLUTE: - { - ext_ctrl->value = sensor->info_priv.focus; - break; - } - case V4L2_CID_FOCUS_RELATIVE: - { - return -EINVAL; - } - case V4L2_CID_FLASH: - { - ext_ctrl->value = sensor->info_priv.flash; - break; - } - default : - break; - } - return 0; -} -static int sensor_s_ext_control(struct soc_camera_device *icd, struct v4l2_ext_control *ext_ctrl) -{ - const struct v4l2_queryctrl *qctrl; - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - int val_offset; - - qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id); - - if (!qctrl) - { - SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id); - return -EINVAL; - } - - val_offset = 0; - switch (ext_ctrl->id) - { -#if CONFIG_SENSOR_Scene - case V4L2_CID_SCENE: - { - if (ext_ctrl->value != sensor->info_priv.scene) - { - if (sensor_set_scene(icd, qctrl,ext_ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.scene = ext_ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Effect - case V4L2_CID_EFFECT: - { - if (ext_ctrl->value != sensor->info_priv.effect) - { - if (sensor_set_effect(icd, qctrl,ext_ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.effect= ext_ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_DigitalZoom - case V4L2_CID_ZOOM_ABSOLUTE: - { - if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum)) - return -EINVAL; - - if (ext_ctrl->value != sensor->info_priv.digitalzoom) - { - val_offset = ext_ctrl->value -sensor->info_priv.digitalzoom; - - if (sensor_set_digitalzoom(icd, qctrl,&val_offset) != 0) - return -EINVAL; - sensor->info_priv.digitalzoom += val_offset; - - SENSOR_DG("%s digitalzoom is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom); - } - - break; - } - case V4L2_CID_ZOOM_RELATIVE: - { - if (ext_ctrl->value) - { - if (sensor_set_digitalzoom(icd, qctrl,&ext_ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.digitalzoom += ext_ctrl->value; - - SENSOR_DG("%s digitalzoom is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom); - } - break; - } -#endif -#if CONFIG_SENSOR_Focus - case V4L2_CID_FOCUS_ABSOLUTE: - { - if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum)) - return -EINVAL; - - if (ext_ctrl->value != sensor->info_priv.focus) - { - val_offset = ext_ctrl->value -sensor->info_priv.focus; - - sensor->info_priv.focus += val_offset; - } - - break; - } - case V4L2_CID_FOCUS_RELATIVE: - { - if (ext_ctrl->value) - { - sensor->info_priv.focus += ext_ctrl->value; - - SENSOR_DG("%s focus is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.focus); - } - break; - } -#endif -#if CONFIG_SENSOR_Flash - case V4L2_CID_FLASH: - { - if (sensor_set_flash(icd, qctrl,ext_ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.flash = ext_ctrl->value; - - SENSOR_DG("%s flash is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.flash); - break; - } -#endif - default: - break; - } - - return 0; -} - -static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) -{ - struct i2c_client *client = sd->priv; - struct soc_camera_device *icd = client->dev.platform_data; - int i, error_cnt=0, error_idx=-1; - - - for (i=0; icount; i++) { - if (sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) { - error_cnt++; - error_idx = i; - } - } - - if (error_cnt > 1) - error_idx = ext_ctrl->count; - - if (error_idx != -1) { - ext_ctrl->error_idx = error_idx; - return -EINVAL; - } else { - return 0; - } -} - -static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) -{ - struct i2c_client *client = sd->priv; - struct soc_camera_device *icd = client->dev.platform_data; - int i, error_cnt=0, error_idx=-1; - - - for (i=0; icount; i++) { - if (sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) { - error_cnt++; - error_idx = i; - } - } - - if (error_cnt > 1) - error_idx = ext_ctrl->count; - - if (error_idx != -1) { - ext_ctrl->error_idx = error_idx; - return -EINVAL; - } else { - return 0; - } -} - -/* Interface active, can use i2c. If it fails, it can indeed mean, that - * this wasn't our capture interface, so, we wait for the right one */ -static int sensor_video_probe(struct soc_camera_device *icd, - struct i2c_client *client) -{ - char value; - int ret,pid = 0; - struct sensor *sensor = to_sensor(client); - - /* We must have a parent by now. And it cannot be a wrong one. - * So this entire test is completely redundant. */ - if (!icd->dev.parent || - to_soc_camera_host(icd->dev.parent)->nr != icd->iface) - return -ENODEV; - - if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { - ret = -ENODEV; - goto sensor_video_probe_err; - } - - /* soft reset */ - ret = sensor_write(client, 0xff, 0x1); - if (ret != 0) { - SENSOR_TR("soft reset %s failed\n",SENSOR_NAME_STRING()); - ret = -ENODEV; - goto sensor_video_probe_err; - } - mdelay(5); //delay 5 microseconds - - /* check if it is an sensor sensor */ - ret = sensor_read(client, 0x0a, &value); - if (ret != 0) { - SENSOR_TR("read chip id high byte failed\n"); - ret = -ENODEV; - goto sensor_video_probe_err; - } - pid = value << 8; - - ret = sensor_read(client, 0x0b, &value); - if (ret != 0) { - SENSOR_TR("read chip id low byte failed\n"); - ret = -ENODEV; - goto sensor_video_probe_err; - } - - pid |= (value & 0xff); - SENSOR_DG("\n %s pid = 0x%x\n", SENSOR_NAME_STRING(), pid); - - if ((pid == SENSOR_ID)||(pid == SENSOR_ID1)) { - sensor->model = SENSOR_V4L2_IDENT; - } else { - SENSOR_TR("error: %s mismatched pid = 0x%x\n", SENSOR_NAME_STRING(), pid); - ret = -ENODEV; - goto sensor_video_probe_err; - } - - return 0; - -sensor_video_probe_err: - - return ret; -} - -static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) -{ - struct i2c_client *client = sd->priv; - struct soc_camera_device *icd = client->dev.platform_data; - struct sensor *sensor = to_sensor(client); - int ret = 0; - - SENSOR_DG("\n%s..%s..cmd:%x \n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); - switch (cmd) - { - case RK29_CAM_SUBDEV_DEACTIVATE: - { - sensor_deactivate(client); - break; - } - - case RK29_CAM_SUBDEV_IOREQUEST: - { - sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; - if (sensor->sensor_io_request != NULL) { - if (sensor->sensor_io_request->gpio_res[0].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[0].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[0]; - } else if (sensor->sensor_io_request->gpio_res[1].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[1].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[1]; - } - } else { - SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); - ret = -EINVAL; - goto sensor_ioctl_end; - } - /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control - for this project */ - #if CONFIG_SENSOR_Flash - if (sensor->sensor_gpio_res) { - if (sensor->sensor_gpio_res->gpio_flash == INVALID_GPIO) { - for (i = 0; i < icd->ops->num_controls; i++) { - if (V4L2_CID_FLASH == icd->ops->controls[i].id) { - memset((char*)&icd->ops->controls[i],0x00,sizeof(struct v4l2_queryctrl)); - } - } - sensor->info_priv.flash = 0xff; - SENSOR_DG("%s flash gpio is invalidate!\n",SENSOR_NAME_STRING()); - } - } - #endif - break; - } - default: - { - SENSOR_TR("%s %s cmd(0x%x) is unknown !\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); - break; - } - } - -sensor_ioctl_end: - return ret; - -} -static int sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) -{ - if (index >= ARRAY_SIZE(sensor_colour_fmts)) - return -EINVAL; - - *code = sensor_colour_fmts[index].code; - return 0; -} -static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { - .init = sensor_init, - .g_ctrl = sensor_g_control, - .s_ctrl = sensor_s_control, - .g_ext_ctrls = sensor_g_ext_controls, - .s_ext_ctrls = sensor_s_ext_controls, - .g_chip_ident = sensor_g_chip_ident, - .ioctl = sensor_ioctl, -}; - -static struct v4l2_subdev_video_ops sensor_subdev_video_ops = { - .s_mbus_fmt = sensor_s_fmt, - .g_mbus_fmt = sensor_g_fmt, - .try_mbus_fmt = sensor_try_fmt, - .enum_mbus_fmt = sensor_enum_fmt, -}; - -static struct v4l2_subdev_ops sensor_subdev_ops = { - .core = &sensor_subdev_core_ops, - .video = &sensor_subdev_video_ops, -}; - -static int sensor_probe(struct i2c_client *client, - const struct i2c_device_id *did) -{ - struct sensor *sensor; - struct soc_camera_device *icd = client->dev.platform_data; - struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); - struct soc_camera_link *icl; - int ret; - - SENSOR_DG("\n%s..%s..%d..\n",__FUNCTION__,__FILE__,__LINE__); - if (!icd) { - dev_err(&client->dev, "%s: missing soc-camera data!\n",SENSOR_NAME_STRING()); - return -EINVAL; - } - - icl = to_soc_camera_link(icd); - if (!icl) { - dev_err(&client->dev, "%s driver needs platform data\n", SENSOR_NAME_STRING()); - return -EINVAL; - } - - if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) { - dev_warn(&adapter->dev, - "I2C-Adapter doesn't support I2C_FUNC_I2C\n"); - return -EIO; - } - - sensor = kzalloc(sizeof(struct sensor), GFP_KERNEL); - if (!sensor) - return -ENOMEM; - - v4l2_i2c_subdev_init(&sensor->subdev, client, &sensor_subdev_ops); - - /* Second stage probe - when a capture adapter is there */ - icd->ops = &sensor_ops; - sensor->info_priv.fmt = sensor_colour_fmts[0]; - #if CONFIG_SENSOR_I2C_NOSCHED - atomic_set(&sensor->tasklock_cnt,0); - #endif - - ret = sensor_video_probe(icd, client); - if (ret < 0) { - icd->ops = NULL; - i2c_set_clientdata(client, NULL); - kfree(sensor); - sensor = NULL; - } - SENSOR_DG("\n%s..%s..%d ret = %x \n",__FUNCTION__,__FILE__,__LINE__,ret); - return ret; -} - -static int sensor_remove(struct i2c_client *client) -{ - struct sensor *sensor = to_sensor(client); - struct soc_camera_device *icd = client->dev.platform_data; - - icd->ops = NULL; - i2c_set_clientdata(client, NULL); - client->driver = NULL; - kfree(sensor); - sensor = NULL; - return 0; -} - -static const struct i2c_device_id sensor_id[] = { - {SENSOR_NAME_STRING(), 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, sensor_id); - -static struct i2c_driver sensor_i2c_driver = { - .driver = { - .name = SENSOR_NAME_STRING(), - }, - .probe = sensor_probe, - .remove = sensor_remove, - .id_table = sensor_id, -}; - -static int __init sensor_mod_init(void) -{ - SENSOR_DG("\n%s..%s.. \n",__FUNCTION__,SENSOR_NAME_STRING()); - return i2c_add_driver(&sensor_i2c_driver); -} - -static void __exit sensor_mod_exit(void) -{ - i2c_del_driver(&sensor_i2c_driver); -} - -device_initcall_sync(sensor_mod_init); -module_exit(sensor_mod_exit); - -MODULE_DESCRIPTION(SENSOR_NAME_STRING(Camera sensor driver)); -MODULE_AUTHOR("ddl "); -MODULE_LICENSE("GPL"); - - diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c index 818777eaf735..a499cacec1f3 100644 --- a/drivers/media/video/soc_camera.c +++ b/drivers/media/video/soc_camera.c @@ -373,18 +373,16 @@ static int soc_camera_open(struct file *file) icd->current_fmt->host_fmt->fourcc, }, }; - /* ddl@rock-chips.com : accelerate device open */ - if ((file->f_flags & O_ACCMODE) == O_RDWR) { - if (icl->power) { - ret = icl->power(icd->pdev, 1); - if (ret < 0) - goto epower; - } - - /* The camera could have been already on, try to reset */ - if (icl->reset) - icl->reset(icd->pdev); - } + + if (icl->power) { + ret = icl->power(icd->pdev, 1); + if (ret < 0) + goto epower; + } + + /* The camera could have been already on, try to reset */ + if (icl->reset) + icl->reset(icd->pdev); ret = ici->ops->add(icd); if (ret < 0) { @@ -397,7 +395,6 @@ static int soc_camera_open(struct file *file) if (ret < 0 && ret != -ENOSYS) goto eresume; - if ((file->f_flags & O_ACCMODE) == O_RDWR) { /* * Try to configure with default parameters. Notice: this is the * very first open, so, we cannot race against other calls, @@ -407,7 +404,6 @@ static int soc_camera_open(struct file *file) ret = soc_camera_set_fmt(icf, &f); if (ret < 0) goto esfmt; - } } file->private_data = icf; @@ -455,10 +451,8 @@ static int soc_camera_close(struct file *file) ici->ops->remove(icd); - if ((file->f_flags & O_ACCMODE) == O_RDWR) { if (icl->power) icl->power(icd->pdev, 0); - } } mutex_unlock(&icd->video_lock); @@ -531,34 +525,17 @@ static int soc_camera_s_fmt_vid_cap(struct file *file, void *priv, { struct soc_camera_file *icf = file->private_data; struct soc_camera_device *icd = icf->icd; - int ret,i; + int ret; WARN_ON(priv != file->private_data); mutex_lock(&icf->vb_vidq.vb_lock); - #if 1 if (icf->vb_vidq.bufs[0]) { dev_err(&icd->dev, "S_FMT denied: queue initialised\n"); ret = -EBUSY; goto unlock; } - #else - - /* ddl@rock-chips.com : - Judge queue initialised by Judge icf->vb_vidq.bufs[0] whether is NULL , it is error. */ - - i = 0; - while (icf->vb_vidq.bufs[i] && (ivb_vidq.bufs[i]->state != VIDEOBUF_NEEDS_INIT) { - dev_err(&icd->dev, "S_FMT denied: queue initialised, icf->vb_vidq.bufs[%d]->state:0x%x\n",i,icf->vb_vidq.bufs[i]->state); - ret = -EBUSY; - goto unlock; - } - i++; - } - - #endif ret = soc_camera_set_fmt(icf, f); @@ -567,27 +544,7 @@ unlock: return ret; } -static int soc_camera_enum_frameintervals (struct file *file, void *priv, - struct v4l2_frmivalenum *fival) -{ - struct soc_camera_file *icf = file->private_data; - struct soc_camera_device *icd = icf->icd; - const struct soc_camera_data_format *format; - struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); - struct v4l2_subdev *sd = soc_camera_to_subdev(icd); - int ret; - - WARN_ON(priv != file->private_data); - ret = v4l2_subdev_call(sd, video, enum_frameintervals, fival); - if (ret == -ENOIOCTLCMD) - if (ici->ops->enum_frameinervals) - ret = ici->ops->enum_frameinervals(icd, fival); - else - ret = -ENOIOCTLCMD; - - return ret; -} static int soc_camera_enum_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fmtdesc *f) { @@ -651,8 +608,6 @@ static int soc_camera_streamon(struct file *file, void *priv, struct soc_camera_file *icf = file->private_data; struct soc_camera_device *icd = icf->icd; struct v4l2_subdev *sd = soc_camera_to_subdev(icd); - struct soc_camera_host *ici = - to_soc_camera_host(icd->dev.parent); int ret; WARN_ON(priv != file->private_data); @@ -663,8 +618,7 @@ static int soc_camera_streamon(struct file *file, void *priv, mutex_lock(&icd->video_lock); v4l2_subdev_call(sd, video, s_stream, 1); - if (ici->ops->s_stream) - ici->ops->s_stream(icd, 1); /* ddl@rock-chips.com : Add stream control for host */ + /* This calls buf_queue from host driver's videobuf_queue_ops */ ret = videobuf_streamon(&icf->vb_vidq); @@ -679,14 +633,12 @@ static int soc_camera_streamoff(struct file *file, void *priv, struct soc_camera_file *icf = file->private_data; struct soc_camera_device *icd = icf->icd; struct v4l2_subdev *sd = soc_camera_to_subdev(icd); - struct soc_camera_host *ici = - to_soc_camera_host(icd->dev.parent); WARN_ON(priv != file->private_data); if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; - + mutex_lock(&icd->video_lock); /* @@ -696,10 +648,7 @@ static int soc_camera_streamoff(struct file *file, void *priv, videobuf_streamoff(&icf->vb_vidq); v4l2_subdev_call(sd, video, s_stream, 0); - if (ici->ops->s_stream) - ici->ops->s_stream(icd, 0); /* ddl@rock-chips.com : Add stream control for host */ - videobuf_mmap_free(&icf->vb_vidq); /* ddl@rock-chips.com : free video buf */ mutex_unlock(&icd->video_lock); return 0; @@ -737,40 +686,6 @@ static int soc_camera_queryctrl(struct file *file, void *priv, return -EINVAL; } -/* ddl@rock-chips.com : Add ioctrl -VIDIOC_QUERYMENU */ -static int soc_camera_querymenu(struct file *file, void *priv, - struct v4l2_querymenu *qm) -{ - struct soc_camera_file *icf = file->private_data; - struct soc_camera_device *icd = icf->icd; - struct v4l2_queryctrl qctrl; - int i,j; - - qctrl.id = qm->id; - - if (soc_camera_queryctrl(file,priv, &qctrl) == 0) { - for (i = 0; i < icd->ops->num_menus; i++) { - if (qm->id == icd->ops->menus[i].id) { - for (j=0; j<=(qctrl.maximum - qctrl.minimum); j++) { - - if (qm->index == icd->ops->menus[i].index) { - snprintf(qm->name, sizeof(qm->name), icd->ops->menus[i].name); - qm->reserved = 0; - - return 0; - } else { - i++; - if ( i >= icd->ops->num_menus) - return -EINVAL; - } - } - } - } - } - - return -EINVAL; -} - static int soc_camera_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { @@ -811,64 +726,6 @@ static int soc_camera_s_ctrl(struct file *file, void *priv, return v4l2_subdev_call(sd, core, s_ctrl, ctrl); } - - /* ddl@rock-chips.com : Add ioctrl -VIDIOC_XXX_ext_ctrl for soc-camera */ -static int soc_camera_try_ext_ctrl(struct file *file, void *priv, - struct v4l2_ext_controls *ctrl) -{ - struct soc_camera_file *icf = file->private_data; - struct soc_camera_device *icd = icf->icd; - const struct v4l2_queryctrl *qctrl; - int i; - - WARN_ON(priv != file->private_data); - - if (ctrl->ctrl_class != V4L2_CTRL_CLASS_CAMERA) - return -EINVAL; - - for (i=0; icount; i++) { - qctrl = soc_camera_find_qctrl(icd->ops, ctrl->controls[i].id); - if (!qctrl) - return -EINVAL; - - if ((ctrl->controls[i].value < qctrl->minimum) ||(ctrl->controls[i].value > qctrl->minimum)) - return -ERANGE; - } - - return 0; -} - /* ddl@rock-chips.com : Add ioctrl -VIDIOC_XXX_ext_ctrl for soc-camera */ -static int soc_camera_g_ext_ctrl(struct file *file, void *priv, - struct v4l2_ext_controls *ctrl) -{ - struct soc_camera_file *icf = file->private_data; - struct soc_camera_device *icd = icf->icd; - struct v4l2_subdev *sd = soc_camera_to_subdev(icd); - - WARN_ON(priv != file->private_data); - - if (ctrl->ctrl_class != V4L2_CTRL_CLASS_CAMERA) - return -EINVAL; - - return v4l2_subdev_call(sd, core, g_ext_ctrls, ctrl); -} - /* ddl@rock-chips.com : Add ioctrl -VIDIOC_XXX_ext_ctrl for soc-camera */ -static int soc_camera_s_ext_ctrl(struct file *file, void *priv, - struct v4l2_ext_controls *ctrl) -{ - struct soc_camera_file *icf = file->private_data; - struct soc_camera_device *icd = icf->icd; - struct v4l2_subdev *sd = soc_camera_to_subdev(icd); - - WARN_ON(priv != file->private_data); - - if (ctrl->ctrl_class != V4L2_CTRL_CLASS_CAMERA) - return -EINVAL; - - return v4l2_subdev_call(sd, core, s_ext_ctrls, ctrl); -} - - static int soc_camera_cropcap(struct file *file, void *fh, struct v4l2_cropcap *a) { @@ -1437,13 +1294,8 @@ static const struct v4l2_ioctl_ops soc_camera_ioctl_ops = { .vidioc_streamon = soc_camera_streamon, .vidioc_streamoff = soc_camera_streamoff, .vidioc_queryctrl = soc_camera_queryctrl, - .vidioc_querymenu = soc_camera_querymenu, /* ddl@rock-chips.com: Add ioctrl - vidioc_querymenu for soc-camera */ .vidioc_g_ctrl = soc_camera_g_ctrl, .vidioc_s_ctrl = soc_camera_s_ctrl, - .vidioc_g_ext_ctrls = soc_camera_g_ext_ctrl, /* ddl@rock-chips.com: Add ioctrl - vidioc_g_ext_ctrls for soc-camera */ - .vidioc_s_ext_ctrls = soc_camera_s_ext_ctrl, /* ddl@rock-chips.com: Add ioctrl - vidioc_s_ext_ctrls for soc-camera */ - .vidioc_try_ext_ctrls = soc_camera_try_ext_ctrl,/* ddl@rock-chips.com: Add ioctrl - vidioc_try_ext_ctrls for soc-camera */ - .vidioc_enum_frameintervals = soc_camera_enum_frameintervals,/* ddl@rock-chips.com: Add ioctrl - VIDIOC_ENUM_FRAMEINTERVALS for soc-camera */ .vidioc_cropcap = soc_camera_cropcap, .vidioc_g_crop = soc_camera_g_crop, .vidioc_s_crop = soc_camera_s_crop, diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c index 47e5e4daab0a..86db32697b80 100644 --- a/drivers/media/video/uvc/uvc_v4l2.c +++ b/drivers/media/video/uvc/uvc_v4l2.c @@ -315,17 +315,12 @@ static int uvc_v4l2_set_format(struct uvc_streaming *stream, struct uvc_frame *frame; int ret; - if (fmt->type != stream->type) { - printk("uvc_v4l2_set_format, fmt->type(%d) != stream->type(%d)\n",fmt->type,stream->type); + if (fmt->type != stream->type) return -EINVAL; - } - if (uvc_queue_allocated(&stream->queue)) { - printk("uvc_queue_allocated failed\n"); + if (uvc_queue_allocated(&stream->queue)) return -EBUSY; - } - ret = uvc_v4l2_try_format(stream, fmt, &probe, &format, &frame); if (ret < 0) return ret; @@ -796,10 +791,8 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) } case VIDIOC_S_FMT: - if ((ret = uvc_acquire_privileges(handle)) < 0) { - printk("uvc_acquire_privileges error."); + if ((ret = uvc_acquire_privileges(handle)) < 0) return ret; - } return uvc_v4l2_set_format(stream, arg); @@ -970,18 +963,14 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) } case VIDIOC_QBUF: - if (!uvc_has_privileges(handle)) { - printk("uvcvideo: VIDIOC_QBUF uvc_has_privileges failed\n"); + if (!uvc_has_privileges(handle)) return -EBUSY; - } return uvc_queue_buffer(&stream->queue, arg); case VIDIOC_DQBUF: - if (!uvc_has_privileges(handle)) { - printk("uvcvideo: VIDIOC_DQBUF uvc_has_privileges failed\n"); + if (!uvc_has_privileges(handle)) return -EBUSY; - } return uvc_dequeue_buffer(&stream->queue, arg, file->f_flags & O_NONBLOCK); diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c index 2de543e9bb4d..dd9283fcb564 100644 --- a/drivers/media/video/v4l2-ioctl.c +++ b/drivers/media/video/v4l2-ioctl.c @@ -807,10 +807,10 @@ static long __video_do_ioctl(struct file *file, case VIDIOC_S_FMT: { struct v4l2_format *f = (struct v4l2_format *)arg; - + /* FIXME: Should be one dump per type */ dbgarg(cmd, "type=%s\n", prt_names(f->type, v4l2_type_names)); - + switch (f->type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: CLEAR_AFTER_FIELD(f, fmt.pix); @@ -2090,7 +2090,7 @@ long video_ioctl2(struct file *file, int is_ext_ctrl; size_t ctrls_size = 0; void __user *user_ptr = NULL; - + #ifdef __OLD_VIDIOC_ cmd = video_fix_command(cmd); #endif diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 71ea410390bf..d2924a2cf3cd 100755 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -180,18 +180,6 @@ config TWL4030_POWER and load scripts controling which resources are switched off/on or reset when a sleep, wakeup or warm reset event occurs. -config TPS65910_CORE - bool "Texas Instruments TPS65910 Support" - depends on I2C=y && GENERIC_HARDIRQS - help - Say yes here if you have TPS65910 family chip on your board. - This core driver provides register access and registers devices - for the various functions so that function-specific drivers can - bind to them. - - These multi-function chips are found on many AM35xx boards, - providing power management, RTC, GPIO features. - config TWL4030_CODEC bool depends on TWL4030_CORE @@ -326,42 +314,15 @@ config MFD_WM8400 the functionality of the device. config MFD_WM831X - bool - depends on GENERIC_HARDIRQS - -config MFD_WM831X_I2C - bool "Support Wolfson Microelectronics WM831x/2x PMICs with I2C" + bool "Support Wolfson Microelectronics WM831x/2x PMICs" select MFD_CORE - select MFD_WM831X depends on I2C=y && GENERIC_HARDIRQS help - Support for the Wolfson Microelecronics WM831x and WM832x PMICs - when controlled using I2C. This driver provides common support - for accessing the device, additional drivers must be enabled in - order to use the functionality of the device. + Support for the Wolfson Microelecronics WM831x and WM832x PMICs. + This driver provides common support for accessing the device, + additional drivers must be enabled in order to use the + functionality of the device. -config MFD_WM831X_SPI - bool "Support Wolfson Microelectronics WM831x/2x PMICs with SPI" - select MFD_CORE - select MFD_WM831X - depends on SPI_MASTER && GENERIC_HARDIRQS - help - Support for the Wolfson Microelecronics WM831x and WM832x PMICs - when controlled using SPI. This driver provides common support - for accessing the device, additional drivers must be enabled in - order to use the functionality of the device. - -config MFD_WM831X_SPI_A22 - bool "Support Wolfson Microelectronics WM831x/2x PMICs with SPI for A22" - #select MFD_CORE - #select MFD_WM831X - depends on SPI_MASTER && GENERIC_HARDIRQS - help - Support for the Wolfson Microelecronics WM831x and WM832x PMICs - when controlled using SPI. This driver provides common support - for accessing the device, additional drivers must be enabled in - order to use the functionality of the device. - config MFD_WM8350 bool depends on GENERIC_HARDIRQS diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 866cb2898e57..a28fc814aea6 100755 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -24,9 +24,6 @@ obj-$(CONFIG_MFD_TC6393XB) += tc6393xb.o tmio_core.o obj-$(CONFIG_MFD_WM8400) += wm8400-core.o wm831x-objs := wm831x-core.o wm831x-irq.o wm831x-otp.o obj-$(CONFIG_MFD_WM831X) += wm831x.o -obj-$(CONFIG_MFD_WM831X_I2C) += wm831x-i2c.o -obj-$(CONFIG_MFD_WM831X_SPI) += wm831x-spi.o -obj-$(CONFIG_MFD_WM831X_SPI_A22) += wm831x-spi-a22.o wm8350-objs := wm8350-core.o wm8350-regmap.o wm8350-gpio.o wm8350-objs += wm8350-irq.o obj-$(CONFIG_MFD_WM8350) += wm8350.o @@ -42,8 +39,6 @@ obj-$(CONFIG_TWL4030_POWER) += twl4030-power.o obj-$(CONFIG_TWL4030_CODEC) += twl4030-codec.o obj-$(CONFIG_TWL6030_PWM) += twl6030-pwm.o -obj-$(CONFIG_TPS65910_CORE) += tps65910-core.o - obj-$(CONFIG_MFD_MC13783) += mc13783-core.o obj-$(CONFIG_MFD_CORE) += mfd-core.o diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c index 1bfd65bd3743..b5347167aa72 100644 --- a/drivers/mfd/wm831x-core.c +++ b/drivers/mfd/wm831x-core.c @@ -14,11 +14,11 @@ #include #include +#include #include #include #include #include -#include #include #include @@ -26,13 +26,10 @@ #include #include #include -#include - /* Current settings - values are 2*2^(reg_val/4) microamps. These are * exported since they are used by multiple drivers. */ - extern int reboot_cmd_get(void); int wm831x_isinkv_values[WM831X_ISINK_MAX_ISEL + 1] = { 2, 2, @@ -93,6 +90,14 @@ int wm831x_isinkv_values[WM831X_ISINK_MAX_ISEL + 1] = { }; EXPORT_SYMBOL_GPL(wm831x_isinkv_values); +enum wm831x_parent { + WM8310 = 0x8310, + WM8311 = 0x8311, + WM8312 = 0x8312, + WM8320 = 0x8320, + WM8321 = 0x8321, +}; + static int wm831x_reg_locked(struct wm831x *wm831x, unsigned short reg) { if (!wm831x->locked) @@ -387,7 +392,7 @@ int wm831x_auxadc_read(struct wm831x *wm831x, enum wm831x_auxadc input) * the notification of the interrupt may be delayed by * threaded IRQ handling. */ if (!wait_for_completion_timeout(&wm831x->auxadc_done, - msecs_to_jiffies(2000))) { + msecs_to_jiffies(500))) { dev_err(wm831x->dev, "Timed out waiting for AUXADC\n"); ret = -EBUSY; goto disable; @@ -1001,20 +1006,6 @@ static struct mfd_cell wm8310_devs[] = { .num_resources = ARRAY_SIZE(wm831x_wdt_resources), .resources = wm831x_wdt_resources, }, -#if defined(CONFIG_KEYBOARD_WM831X_GPIO) - { - .name = "wm831x_gpio-keys", - .num_resources = 0, - }, -#endif -#if defined(CONFIG_WM831X_CHARGER_DISPLAY) - { - .name = "wm831x_charger_display", - .num_resources = 0, - }, -#endif - - }; static struct mfd_cell wm8311_devs[] = { @@ -1455,7 +1446,7 @@ static struct mfd_cell backlight_devs[] = { /* * Instantiate the generic non-control parts of the device. */ -int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq) +static int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq) { struct wm831x_pdata *pdata = wm831x->dev->platform_data; int rev; @@ -1473,7 +1464,11 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq) dev_err(wm831x->dev, "Failed to read parent ID: %d\n", ret); goto err; } - if (ret != 0x6204) { + switch (ret) { + case 0x6204: + case 0x6246: + break; + default: dev_err(wm831x->dev, "Device is not a WM831x: ID %x\n", ret); ret = -EINVAL; goto err; @@ -1503,15 +1498,12 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq) switch (ret) { case WM8310: parent = WM8310; - wm831x->num_gpio = 12; + wm831x->num_gpio = 16; wm831x->charger_irq_wake = 1; if (rev > 0) { wm831x->has_gpio_ena = 1; wm831x->has_cs_sts = 1; } - //ILIM = 900ma - ret = wm831x_reg_read(wm831x, WM831X_POWER_STATE) & 0xffff; - wm831x_reg_write(wm831x, WM831X_POWER_STATE, (ret&0xfff8) | 0x04); dev_info(wm831x->dev, "WM8310 revision %c\n", 'A' + rev); break; @@ -1552,12 +1544,6 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq) dev_info(wm831x->dev, "WM8321 revision %c\n", 'A' + rev); break; - case WM8325: - parent = WM8325; - wm831x->num_gpio = 12; - dev_info(wm831x->dev, "WM8325 revision %c\n", 'A' + rev); - break; - default: dev_err(wm831x->dev, "Unknown WM831x device %04x\n", ret); ret = -EINVAL; @@ -1635,13 +1621,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq) case WM8321: ret = mfd_add_devices(wm831x->dev, -1, wm8320_devs, ARRAY_SIZE(wm8320_devs), - NULL, 0); - break; - - case WM8325: - ret = mfd_add_devices(wm831x->dev, -1, - wm8320_devs, ARRAY_SIZE(wm8320_devs), - NULL, 0); + NULL, wm831x->irq_base); break; default: @@ -1667,11 +1647,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq) wm831x_otp_init(wm831x); if (pdata && pdata->post_init) { - wm831x_reg_unlock(wm831x); - wm831x_set_bits(wm831x, WM831X_RESET_CONTROL,0x0010,0x0000); - wm831x_set_bits(wm831x, WM831X_LDO_ENABLE,0Xf800,0Xf800); ret = pdata->post_init(wm831x); - wm831x_reg_lock(wm831x); if (ret != 0) { dev_err(wm831x->dev, "post_init() failed: %d\n", ret); goto err_irq; @@ -1688,7 +1664,7 @@ err: return ret; } -void wm831x_device_exit(struct wm831x *wm831x) +static void wm831x_device_exit(struct wm831x *wm831x) { wm831x_otp_exit(wm831x); mfd_remove_devices(wm831x->dev); @@ -1698,25 +1674,9 @@ void wm831x_device_exit(struct wm831x *wm831x) kfree(wm831x); } -int wm831x_device_suspend(struct wm831x *wm831x) +static int wm831x_device_suspend(struct wm831x *wm831x) { int reg, mask; - int i; - - //mask some intterupt avoid wakeing up system while suspending - for (i = 0; i < ARRAY_SIZE(wm831x->irq_masks_cur); i++) { - /* If there's been a change in the mask write it back - * to the hardware. */ - //printk("irq_masks_cur[%d]=0x%x\n",i,wm831x->irq_masks_cur[i]); - - if (wm831x->irq_masks_cur[i] != wm831x->irq_masks_cache[i]) { - wm831x->irq_masks_cache[i] = wm831x->irq_masks_cur[i]; - wm831x_reg_write(wm831x, - WM831X_INTERRUPT_STATUS_1_MASK + i, - wm831x->irq_masks_cur[i]); - } - - } /* If the charger IRQs are a wake source then make sure we ack * them even if they're not actively being used (eg, no power @@ -1749,100 +1709,126 @@ int wm831x_device_suspend(struct wm831x *wm831x) return 0; } -void wm831x_enter_sleep(void){ -#if 1//def CONFIG_RK2818_SOC_PM - struct regulator *dcdc; - int i; - dcdc=regulator_get(NULL, "dcdc1"); - struct wm831x_dcdc *dc = regulator_get_drvdata(dcdc); - struct wm831x *wm831x = dc->wm831x; - if(wm831x){ - wm831x_set_bits(wm831x, WM831X_POWER_STATE, 0x4000, 0x4000); // SYSTEM SLEEP MODE - for (i=0; i<5; i++) - wm831x_reg_write(wm831x,WM831X_INTERRUPT_STATUS_1+i, 0xffff); // INTRUPT FLAG CLEAR - - printk("%s:complete! \n",__func__); - - }else{ - printk("%s:error!",__func__); - } - regulator_put(dcdc); -#endif -} -EXPORT_SYMBOL_GPL(wm831x_enter_sleep); - -void wm831x_exit_sleep(void){ -#if 1//def CONFIG_RK2818_SOC_PM - struct regulator *dcdc; - dcdc=regulator_get(NULL, "dcdc1"); - struct wm831x_dcdc *dc = regulator_get_drvdata(dcdc); - struct wm831x *wm831x = dc->wm831x; - if(wm831x){ - wm831x_set_bits(wm831x, WM831X_POWER_STATE, 0x4000, 0); // SYSTEM ON MODE - printk("%s:complete! \n",__func__); - - }else{ - printk("%s:error!",__func__); - } - regulator_put(dcdc); -#endif + +static int wm831x_i2c_read_device(struct wm831x *wm831x, unsigned short reg, + int bytes, void *dest) +{ + struct i2c_client *i2c = wm831x->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; } -EXPORT_SYMBOL_GPL(wm831x_exit_sleep); -int wm831x_device_shutdown(struct wm831x *wm831x) +/* 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 wm831x_i2c_write_device(struct wm831x *wm831x, unsigned short reg, + int bytes, void *src) { - struct wm831x_pdata *pdata = wm831x->dev->platform_data; - int ret = 0; - - printk("pre WM831X_POWER_STATE = 0x%x\n", wm831x_reg_read(wm831x, WM831X_POWER_STATE)); + struct i2c_client *i2c = wm831x->control_data; + unsigned char msg[bytes + 2]; + int ret; - if (pdata && pdata->last_deinit) { - ret = pdata->last_deinit(wm831x); - if (ret != 0) { - dev_info(wm831x->dev, "last_deinit() failed: %d\n", ret); - //goto err_irq; - } - } + reg = cpu_to_be16(reg); + memcpy(&msg[0], ®, 2); + memcpy(&msg[2], src, bytes); - //if(0 == reboot_cmd_get()) - { - if(wm831x_set_bits(wm831x, WM831X_POWER_STATE, WM831X_CHIP_ON_MASK, 0) < 0) - printk("%s wm831x_set_bits err\n", __FUNCTION__); - //printk("post WM831X_POWER_STATE = 0x%x\n", wm831x_reg_read(wm831x, WM831X_POWER_STATE)); - } + ret = i2c_master_send(i2c, msg, bytes + 2); + if (ret < 0) + return ret; + if (ret < bytes + 2) + return -EIO; - return 0; + return 0; } -EXPORT_SYMBOL_GPL(wm831x_device_shutdown); +static int wm831x_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + struct wm831x *wm831x; + + wm831x = kzalloc(sizeof(struct wm831x), GFP_KERNEL); + if (wm831x == NULL) + return -ENOMEM; + i2c_set_clientdata(i2c, wm831x); + wm831x->dev = &i2c->dev; + wm831x->control_data = i2c; + wm831x->read_dev = wm831x_i2c_read_device; + wm831x->write_dev = wm831x_i2c_write_device; + + return wm831x_device_init(wm831x, id->driver_data, i2c->irq); +} -int wm831x_read_usb(struct wm831x *wm831x) +static int wm831x_i2c_remove(struct i2c_client *i2c) { - int ret, usb_chg = 0, wall_chg = 0; - - ret = wm831x_reg_read(wm831x, WM831X_SYSTEM_STATUS); - if (ret < 0) - return ret; + struct wm831x *wm831x = i2c_get_clientdata(i2c); - if (ret & WM831X_PWR_USB) - usb_chg = 1; - if (ret & WM831X_PWR_WALL) - wall_chg = 1; + wm831x_device_exit(wm831x); - return ((usb_chg | wall_chg) ? 1 : 0); + return 0; +} +static int wm831x_i2c_suspend(struct i2c_client *i2c, pm_message_t mesg) +{ + struct wm831x *wm831x = i2c_get_clientdata(i2c); + + return wm831x_device_suspend(wm831x); } +static const struct i2c_device_id wm831x_i2c_id[] = { + { "wm8310", WM8310 }, + { "wm8311", WM8311 }, + { "wm8312", WM8312 }, + { "wm8320", WM8320 }, + { "wm8321", WM8321 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, wm831x_i2c_id); + + +static struct i2c_driver wm831x_i2c_driver = { + .driver = { + .name = "wm831x", + .owner = THIS_MODULE, + }, + .probe = wm831x_i2c_probe, + .remove = wm831x_i2c_remove, + .suspend = wm831x_i2c_suspend, + .id_table = wm831x_i2c_id, +}; -int wm831x_device_restart(struct wm831x *wm831x) +static int __init wm831x_i2c_init(void) { - wm831x_reg_write(wm831x,WM831X_RESET_ID, 0xffff); + int ret; - return 0; + ret = i2c_add_driver(&wm831x_i2c_driver); + if (ret != 0) + pr_err("Failed to register wm831x I2C driver: %d\n", ret); + + return ret; } +subsys_initcall(wm831x_i2c_init); +static void __exit wm831x_i2c_exit(void) +{ + i2c_del_driver(&wm831x_i2c_driver); +} +module_exit(wm831x_i2c_exit); -MODULE_DESCRIPTION("Core support for the WM831X AudioPlus PMIC"); +MODULE_DESCRIPTION("I2C support for the WM831X AudioPlus PMIC"); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Mark Brown"); diff --git a/drivers/mfd/wm831x-i2c.c b/drivers/mfd/wm831x-i2c.c deleted file mode 100755 index 5c6e2e7980bc..000000000000 --- a/drivers/mfd/wm831x-i2c.c +++ /dev/null @@ -1,188 +0,0 @@ -/* - * wm831x-i2c.c -- I2C access for Wolfson WM831x PMICs - * - * Copyright 2009,2010 Wolfson Microelectronics PLC. - * - * Author: Mark Brown - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -static int wm831x_i2c_read_device(struct wm831x *wm831x, unsigned short reg, - int bytes, void *dest) -{ - struct i2c_client *i2c = wm831x->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 wm831x_i2c_write_device(struct wm831x *wm831x, unsigned short reg, - int bytes, void *src) -{ - struct i2c_client *i2c = wm831x->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 wm831x_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) -{ - struct wm831x *wm831x; - int ret,gpio,irq; - - wm831x = kzalloc(sizeof(struct wm831x), GFP_KERNEL); - if (wm831x == NULL) - return -ENOMEM; - - i2c_set_clientdata(i2c, wm831x); - - gpio = i2c->irq; - ret = gpio_request(gpio, "wm831x"); - if (ret) { - printk( "failed to request rk gpio irq for wm831x \n"); - return ret; - } - gpio_pull_updown(gpio, GPIOPullUp); - if (ret) { - printk("failed to pull up gpio irq for wm831x \n"); - return ret; - } - irq = gpio_to_irq(gpio); - - wm831x->dev = &i2c->dev; - wm831x->control_data = i2c; - wm831x->read_dev = wm831x_i2c_read_device; - wm831x->write_dev = wm831x_i2c_write_device; - - return wm831x_device_init(wm831x, id->driver_data, irq); -} - -static int wm831x_i2c_remove(struct i2c_client *i2c) -{ - struct wm831x *wm831x = i2c_get_clientdata(i2c); - - wm831x_device_exit(wm831x); - - return 0; -} - -static int wm831x_i2c_suspend(struct i2c_client *i2c, pm_message_t mesg) -{ - struct wm831x *wm831x = i2c_get_clientdata(i2c); - - return wm831x_device_suspend(wm831x); -} - -static int wm831x_i2c_resume(struct i2c_client *i2c) -{ - struct wm831x *wm831x = i2c_get_clientdata(i2c); - int i; - //set some intterupt again while resume - for (i = 0; i < ARRAY_SIZE(wm831x->irq_masks_cur); i++) { - //printk("irq_masks_cur[%d]=0x%x\n",i,wm831x->irq_masks_cur[i]); - - if (wm831x->irq_masks_cur[i] != wm831x->irq_masks_cache[i]) { - wm831x->irq_masks_cache[i] = wm831x->irq_masks_cur[i]; - wm831x_reg_write(wm831x, - WM831X_INTERRUPT_STATUS_1_MASK + i, - wm831x->irq_masks_cur[i]); - } - - } - - return 0; -} - -void wm831x_i2c_shutdown(struct i2c_client *i2c) -{ - struct wm831x *wm831x = i2c_get_clientdata(i2c); - printk("%s\n", __FUNCTION__); - wm831x_device_shutdown(wm831x); -} - -static const struct i2c_device_id wm831x_i2c_id[] = { - { "wm8310", WM8310 }, - { "wm8311", WM8311 }, - { "wm8312", WM8312 }, - { "wm8320", WM8320 }, - { "wm8321", WM8321 }, - { "wm8325", WM8325 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, wm831x_i2c_id); - - -static struct i2c_driver wm831x_i2c_driver = { - .driver = { - .name = "wm831x", - .owner = THIS_MODULE, - }, - .probe = wm831x_i2c_probe, - .remove = wm831x_i2c_remove, - .suspend = wm831x_i2c_suspend, - .resume = wm831x_i2c_resume, - .shutdown = wm831x_i2c_shutdown, - .id_table = wm831x_i2c_id, -}; - -static int __init wm831x_i2c_init(void) -{ - int ret; - printk("%s \n", __FUNCTION__); - ret = i2c_add_driver(&wm831x_i2c_driver); - if (ret != 0) - pr_err("Failed to register wm831x I2C driver: %d\n", ret); - - return ret; -} -subsys_initcall(wm831x_i2c_init); - -static void __exit wm831x_i2c_exit(void) -{ - i2c_del_driver(&wm831x_i2c_driver); -} -module_exit(wm831x_i2c_exit); diff --git a/drivers/mfd/wm831x-irq.c b/drivers/mfd/wm831x-irq.c index d33c6f28e916..294183b6260b 100755 --- a/drivers/mfd/wm831x-irq.c +++ b/drivers/mfd/wm831x-irq.c @@ -25,7 +25,7 @@ #include #include -#include + /* * Since generic IRQs don't currently support interrupt controllers on * interrupt driven buses we don't use genirq but instead provide an @@ -34,7 +34,6 @@ * the static irq_data table we use to look up the data for individual * interrupts, but hopefully won't last too long. */ -#define WM831X_IRQ_TYPE IRQF_TRIGGER_LOW struct wm831x_irq_data { int primary; @@ -42,12 +41,6 @@ struct wm831x_irq_data { int mask; }; -struct wm831x_handle_irq -{ - int irq; - struct list_head queue; -}; - static struct wm831x_irq_data wm831x_irqs[] = { [WM831X_IRQ_TEMP_THW] = { .primary = WM831X_TEMP_INT, @@ -384,7 +377,6 @@ static void wm831x_irq_unmask(unsigned int irq) struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x, irq); wm831x->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask; - //printk("%s:irq=%d\n",__FUNCTION__,irq); } static void wm831x_irq_mask(unsigned int irq) @@ -393,16 +385,6 @@ static void wm831x_irq_mask(unsigned int irq) struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x, irq); wm831x->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask; - //printk("%s:irq=%d\n",__FUNCTION__,irq); -} - -static void wm831x_irq_disable(unsigned int irq) -{ - struct wm831x *wm831x = get_irq_chip_data(irq); - struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x, irq); - - wm831x->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask; - //printk("%s:irq=%d\n",__FUNCTION__,irq); } static int wm831x_irq_set_type(unsigned int irq, unsigned int type) @@ -411,14 +393,15 @@ static int wm831x_irq_set_type(unsigned int irq, unsigned int type) int val; irq = irq - wm831x->irq_base; - if (irq < WM831X_IRQ_GPIO_1 || irq > WM831X_IRQ_GPIO_12) { + + if (irq < WM831X_IRQ_GPIO_1 || irq > WM831X_IRQ_GPIO_11) { /* Ignore internal-only IRQs */ if (irq >= 0 && irq < WM831X_NUM_IRQS) return 0; else return -EINVAL; } - //printk("wm831x_irq_set_type:type=%x,irq=%d\n",type,irq); + switch (type) { case IRQ_TYPE_EDGE_BOTH: val = WM831X_GPN_INT_MODE; @@ -433,97 +416,29 @@ static int wm831x_irq_set_type(unsigned int irq, unsigned int type) return -EINVAL; } - return wm831x_set_bits(wm831x, WM831X_GPIO1_CONTROL + irq - 1, + return wm831x_set_bits(wm831x, WM831X_GPIO1_CONTROL + irq, WM831X_GPN_INT_MODE | WM831X_GPN_POL, val); } -static int wm831x_irq_set_wake(unsigned irq, unsigned state) -{ - struct wm831x *wm831x = get_irq_chip_data(irq); - - //only wm831x irq - if ((irq > wm831x->irq_base + WM831X_IRQ_TEMP_THW) &&( irq < wm831x->irq_base + WM831X_NUM_IRQS)) - { - if(state) - wm831x_irq_unmask(irq); - else - wm831x_irq_mask(irq); - return 0; - } - else - { - printk("%s:irq number err!irq=%d\n",__FUNCTION__,irq); - return -EINVAL; - } - - -} - static struct irq_chip wm831x_irq_chip = { .name = "wm831x", .bus_lock = wm831x_irq_lock, .bus_sync_unlock = wm831x_irq_sync_unlock, - .disable = wm831x_irq_disable, .mask = wm831x_irq_mask, .unmask = wm831x_irq_unmask, .set_type = wm831x_irq_set_type, - .set_wake = wm831x_irq_set_wake, }; -#if WM831X_IRQ_LIST -static void wm831x_handle_worker(struct work_struct *work) -{ - struct wm831x *wm831x = container_of(work, struct wm831x, handle_work); - int irq; - - while (1) { - unsigned long flags; - struct wm831x_handle_irq *hd = NULL; - - spin_lock_irqsave(&wm831x->work_lock, flags); - if (!list_empty(&wm831x->handle_queue)) { - hd = list_first_entry(&wm831x->handle_queue, struct wm831x_handle_irq, queue); - list_del(&hd->queue); - } - spin_unlock_irqrestore(&wm831x->work_lock, flags); - - if (!hd) // trans_queue empty - break; - - irq = hd->irq; //get wm831x intterupt status - //printk("%s:irq=%d\n",__FUNCTION__,irq); - - /*start to handle wm831x intterupt*/ - handle_nested_irq(wm831x->irq_base + irq); - - kfree(hd); - - } -} -#endif -/* Main interrupt handling occurs in a workqueue since we need - * interrupts enabled to interact with the chip. */ -static void wm831x_irq_worker(struct work_struct *work) +/* The processing of the primary interrupt occurs in a thread so that + * we can interact with the device over I2C or SPI. */ +static irqreturn_t wm831x_irq_thread(int irq, void *data) { - struct wm831x *wm831x = container_of(work, struct wm831x, irq_work); + struct wm831x *wm831x = data; unsigned int i; int primary; int status_regs[WM831X_NUM_IRQ_REGS] = { 0 }; int read[WM831X_NUM_IRQ_REGS] = { 0 }; int *status; - unsigned long flags; - struct wm831x_handle_irq *hd; - int ret; - -#if (WM831X_IRQ_TYPE != IRQF_TRIGGER_LOW) - /*mask wm831x irq at first*/ - ret = wm831x_set_bits(wm831x, WM831X_IRQ_CONFIG, - WM831X_IRQ_IM_MASK, WM831X_IRQ_IM_EANBLE); - if (ret < 0) { - dev_err(wm831x->dev, "Failed to mask irq: %d\n", ret); - goto out; - } -#endif primary = wm831x_reg_read(wm831x, WM831X_SYSTEM_INTERRUPTS); if (primary < 0) { @@ -531,15 +446,13 @@ static void wm831x_irq_worker(struct work_struct *work) primary); goto out; } - - mutex_lock(&wm831x->irq_lock); for (i = 0; i < ARRAY_SIZE(wm831x_irqs); i++) { int offset = wm831x_irqs[i].reg - 1; - + if (!(primary & wm831x_irqs[i].primary)) continue; - + status = &status_regs[offset]; /* Hopefully there should only be one register to read @@ -551,7 +464,7 @@ static void wm831x_irq_worker(struct work_struct *work) dev_err(wm831x->dev, "Failed to read IRQ status: %d\n", *status); - goto out_lock; + goto out; } read[offset] = 1; @@ -560,84 +473,18 @@ static void wm831x_irq_worker(struct work_struct *work) /* Report it if it isn't masked, or forget the status. */ if ((*status & ~wm831x->irq_masks_cur[offset]) & wm831x_irqs[i].mask) - { - #if WM831X_IRQ_LIST - /*add intterupt handle on list*/ - hd = kzalloc(sizeof(struct wm831x_handle_irq), GFP_KERNEL); - if (!hd) - { - printk("err:%s:ENOMEM\n",__FUNCTION__); - return ; - } - - if(i == WM831X_IRQ_ON) - wake_lock(&wm831x->handle_wake); //keep wake while handle WM831X_IRQ_ON - hd->irq = i; - spin_lock_irqsave(&wm831x->work_lock, flags); - list_add_tail(&hd->queue, &wm831x->handle_queue); - spin_unlock_irqrestore(&wm831x->work_lock, flags); - queue_work(wm831x->handle_wq, &wm831x->handle_work); - - #else - if(i == WM831X_IRQ_ON) - wake_lock(&wm831x->handle_wake); //keep wake while handle WM831X_IRQ_ON handle_nested_irq(wm831x->irq_base + i); - - #endif - } - else *status &= ~wm831x_irqs[i].mask; } - -out_lock: - mutex_unlock(&wm831x->irq_lock); - + out: for (i = 0; i < ARRAY_SIZE(status_regs); i++) { if (status_regs[i]) wm831x_reg_write(wm831x, WM831X_INTERRUPT_STATUS_1 + i, status_regs[i]); } - -#if (WM831X_IRQ_TYPE != IRQF_TRIGGER_LOW) - ret = wm831x_set_bits(wm831x, WM831X_IRQ_CONFIG, - WM831X_IRQ_IM_MASK, 0); - if (ret < 0) { - dev_err(wm831x->dev, "Failed to open irq: %d\n", ret); - } -#endif -#if (WM831X_IRQ_TYPE == IRQF_TRIGGER_LOW) - enable_irq(wm831x->irq); -#endif - wake_unlock(&wm831x->irq_wake); -} -/* The processing of the primary interrupt occurs in a thread so that - * we can interact with the device over I2C or SPI. */ -static irqreturn_t wm831x_irq_thread(int irq, void *data) -{ - struct wm831x *wm831x = data; - int msdelay = 0; - /* Shut the interrupt to the CPU up and schedule the actual - * handler; we can't check that the IRQ is asserted. */ -#if (WM831X_IRQ_TYPE == IRQF_TRIGGER_LOW) - disable_irq_nosync(irq); -#endif - wake_lock(&wm831x->irq_wake); - if(wm831x->flag_suspend) - { - spin_lock(&wm831x->flag_lock); - wm831x->flag_suspend = 0; - spin_unlock(&wm831x->flag_lock); - msdelay = 50; //wait for spi/i2c resume - printk("%s:msdelay=%d\n",__FUNCTION__,msdelay); - } - else - msdelay = 0; - - queue_delayed_work(wm831x->irq_wq, &wm831x->irq_work, msecs_to_jiffies(msdelay)); - //printk("%s\n",__FUNCTION__); return IRQ_HANDLED; } @@ -645,7 +492,7 @@ int wm831x_irq_init(struct wm831x *wm831x, int irq) { struct wm831x_pdata *pdata = wm831x->dev->platform_data; int i, cur_irq, ret; - printk( "wm831x_irq_init:irq=%d,%d\n",irq,pdata->irq_base); + mutex_init(&wm831x->irq_lock); /* Mask the individual interrupt sources */ @@ -668,30 +515,9 @@ int wm831x_irq_init(struct wm831x *wm831x, int irq) return 0; } - wm831x->irq_wq = create_singlethread_workqueue("wm831x-irq"); - if (!wm831x->irq_wq) { - dev_err(wm831x->dev, "Failed to allocate IRQ worker\n"); - return -ESRCH; - } - - wm831x->irq = irq; - wm831x->flag_suspend = 0; wm831x->irq_base = pdata->irq_base; - INIT_DELAYED_WORK(&wm831x->irq_work, wm831x_irq_worker); - wake_lock_init(&wm831x->irq_wake, WAKE_LOCK_SUSPEND, "wm831x_irq_wake"); - wake_lock_init(&wm831x->handle_wake, WAKE_LOCK_SUSPEND, "wm831x_handle_wake"); -#if WM831X_IRQ_LIST - wm831x->handle_wq = create_rt_workqueue("wm831x_handle_wq"); - if (!wm831x->handle_wq) { - printk("cannot create workqueue\n"); - return -EBUSY; - } - INIT_WORK(&wm831x->handle_work, wm831x_handle_worker); - INIT_LIST_HEAD(&wm831x->handle_queue); -#endif - /* Register them with genirq */ for (cur_irq = wm831x->irq_base; cur_irq < ARRAY_SIZE(wm831x_irqs) + wm831x->irq_base; @@ -709,22 +535,16 @@ int wm831x_irq_init(struct wm831x *wm831x, int irq) set_irq_noprobe(cur_irq); #endif } -#if (WM831X_IRQ_TYPE == IRQF_TRIGGER_LOW) - ret = request_threaded_irq(wm831x->irq, wm831x_irq_thread, NULL, - IRQF_TRIGGER_LOW| IRQF_ONESHOT,//IRQF_TRIGGER_FALLING, // - "wm831x", wm831x); -#else - ret = request_threaded_irq(wm831x->irq, wm831x_irq_thread, NULL, - IRQF_TRIGGER_FALLING, //IRQF_TRIGGER_LOW| IRQF_ONESHOT,// + + ret = request_threaded_irq(irq, NULL, wm831x_irq_thread, + IRQF_TRIGGER_LOW | IRQF_ONESHOT, "wm831x", wm831x); -#endif if (ret != 0) { dev_err(wm831x->dev, "Failed to request IRQ %d: %d\n", - wm831x->irq, ret); + irq, ret); return ret; } - enable_irq_wake(wm831x->irq); // so wm831x irq can wake up system /* Enable top level interrupts, we mask at secondary level */ wm831x_reg_write(wm831x, WM831X_SYSTEM_INTERRUPTS_MASK, 0); diff --git a/drivers/mfd/wm831x-spi.c b/drivers/mfd/wm831x-spi.c deleted file mode 100755 index e0032b9b2a05..000000000000 --- a/drivers/mfd/wm831x-spi.c +++ /dev/null @@ -1,250 +0,0 @@ -/* - * wm831x-spi.c -- SPI access for Wolfson WM831x PMICs - * - * Copyright 2009,2010 Wolfson Microelectronics PLC. - * - * Author: Mark Brown - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -#include -#include -#include -#include - - -#include - -static int wm831x_spi_read_device(struct wm831x *wm831x, unsigned short reg, - int bytes, void *dest) -{ - u16 tx_val; - u16 *d = dest; - int r, ret; - - /* Go register at a time */ - for (r = reg; r < reg + (bytes / 2); r++) { - tx_val = cpu_to_be16(r | 0x8000); - //printk("read:reg=0x%x,",reg); - ret = spi_write_then_read(wm831x->control_data, - (u8 *)&tx_val, 2, (u8 *)d, 2); - if (ret != 0) - return ret; - //printk("rec=0x%x\n",be16_to_cpu(*d)); - //*d = be16_to_cpu(*d); - - d++; - } - - return 0; -} - -static int wm831x_spi_write_device(struct wm831x *wm831x, unsigned short reg, - int bytes, void *src) -{ - struct spi_device *spi = wm831x->control_data; - u16 *s = src; - u16 data[2]; - int ret, r; - - /* Go register at a time */ - for (r = reg; r < reg + (bytes / 2); r++) { - data[0] = cpu_to_be16(r); - data[1] = *s++; - //printk("write:reg=0x%x,send=0x%x\n",reg, data[0]); - ret = spi_write(spi, (char *)&data, sizeof(data)); - if (ret != 0) - return ret; - } - - return 0; -} - -static int __devinit wm831x_spi_probe(struct spi_device *spi) -{ - struct wm831x *wm831x; - enum wm831x_parent type; - int ret,gpio,irq; - - /* Currently SPI support for ID tables is unmerged, we're faking it */ - if (strcmp(spi->modalias, "wm8310") == 0) - type = WM8310; - else if (strcmp(spi->modalias, "wm8311") == 0) - type = WM8311; - else if (strcmp(spi->modalias, "wm8312") == 0) - type = WM8312; - else if (strcmp(spi->modalias, "wm8320") == 0) - type = WM8320; - else if (strcmp(spi->modalias, "wm8321") == 0) - type = WM8321; - else if (strcmp(spi->modalias, "wm8325") == 0) - type = WM8325; - else { - dev_err(&spi->dev, "Unknown device type\n"); - return -EINVAL; - } - - wm831x = kzalloc(sizeof(struct wm831x), GFP_KERNEL); - if (wm831x == NULL) - return -ENOMEM; - - spi->bits_per_word = 16; - spi->mode = SPI_MODE_0; - - gpio = spi->irq; - ret = gpio_request(gpio, "wm831x"); - if (ret) { - printk( "failed to request rk gpio irq for wm831x \n"); - return ret; - } - gpio_pull_updown(gpio, GPIOPullUp); - if (ret) { - printk("failed to pull up gpio irq for wm831x \n"); - return ret; - } - irq = gpio_to_irq(gpio); - - dev_set_drvdata(&spi->dev, wm831x); - wm831x->dev = &spi->dev; - wm831x->control_data = spi; - wm831x->read_dev = wm831x_spi_read_device; - wm831x->write_dev = wm831x_spi_write_device; - - return wm831x_device_init(wm831x, type, irq); -} - -static int __devexit wm831x_spi_remove(struct spi_device *spi) -{ - struct wm831x *wm831x = dev_get_drvdata(&spi->dev); - - wm831x_device_exit(wm831x); - - return 0; -} - -static int wm831x_spi_suspend(struct spi_device *spi, pm_message_t m) -{ - struct wm831x *wm831x = dev_get_drvdata(&spi->dev); - spin_lock(&wm831x->flag_lock); - wm831x->flag_suspend = 1; - spin_unlock(&wm831x->flag_lock); - return wm831x_device_suspend(wm831x); -} - -static struct spi_driver wm8310_spi_driver = { - .driver = { - .name = "wm8310", - .bus = &spi_bus_type, - .owner = THIS_MODULE, - }, - .probe = wm831x_spi_probe, - .remove = __devexit_p(wm831x_spi_remove), - .suspend = wm831x_spi_suspend, -}; - -static struct spi_driver wm8311_spi_driver = { - .driver = { - .name = "wm8311", - .bus = &spi_bus_type, - .owner = THIS_MODULE, - }, - .probe = wm831x_spi_probe, - .remove = __devexit_p(wm831x_spi_remove), - .suspend = wm831x_spi_suspend, -}; - -static struct spi_driver wm8312_spi_driver = { - .driver = { - .name = "wm8312", - .bus = &spi_bus_type, - .owner = THIS_MODULE, - }, - .probe = wm831x_spi_probe, - .remove = __devexit_p(wm831x_spi_remove), - .suspend = wm831x_spi_suspend, -}; - -static struct spi_driver wm8320_spi_driver = { - .driver = { - .name = "wm8320", - .bus = &spi_bus_type, - .owner = THIS_MODULE, - }, - .probe = wm831x_spi_probe, - .remove = __devexit_p(wm831x_spi_remove), - .suspend = wm831x_spi_suspend, -}; - -static struct spi_driver wm8321_spi_driver = { - .driver = { - .name = "wm8321", - .bus = &spi_bus_type, - .owner = THIS_MODULE, - }, - .probe = wm831x_spi_probe, - .remove = __devexit_p(wm831x_spi_remove), - .suspend = wm831x_spi_suspend, -}; - -static struct spi_driver wm8325_spi_driver = { - .driver = { - .name = "wm8325", - .bus = &spi_bus_type, - .owner = THIS_MODULE, - }, - .probe = wm831x_spi_probe, - .remove = __devexit_p(wm831x_spi_remove), - .suspend = wm831x_spi_suspend, -}; - -static int __init wm831x_spi_init(void) -{ - int ret; - - ret = spi_register_driver(&wm8310_spi_driver); - if (ret != 0) - pr_err("Failed to register WM8310 SPI driver: %d\n", ret); - - ret = spi_register_driver(&wm8311_spi_driver); - if (ret != 0) - pr_err("Failed to register WM8311 SPI driver: %d\n", ret); - - ret = spi_register_driver(&wm8312_spi_driver); - if (ret != 0) - pr_err("Failed to register WM8312 SPI driver: %d\n", ret); - - ret = spi_register_driver(&wm8320_spi_driver); - if (ret != 0) - pr_err("Failed to register WM8320 SPI driver: %d\n", ret); - - ret = spi_register_driver(&wm8321_spi_driver); - if (ret != 0) - pr_err("Failed to register WM8321 SPI driver: %d\n", ret); - - ret = spi_register_driver(&wm8325_spi_driver); - if (ret != 0) - pr_err("Failed to register WM8325 SPI driver: %d\n", ret); - - return 0; -} -subsys_initcall(wm831x_spi_init); - -static void __exit wm831x_spi_exit(void) -{ - spi_unregister_driver(&wm8325_spi_driver); - spi_unregister_driver(&wm8321_spi_driver); - spi_unregister_driver(&wm8320_spi_driver); - spi_unregister_driver(&wm8312_spi_driver); - spi_unregister_driver(&wm8311_spi_driver); - spi_unregister_driver(&wm8310_spi_driver); -} -module_exit(wm831x_spi_exit); - -MODULE_DESCRIPTION("SPI support for WM831x/2x AudioPlus PMICs"); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mark Brown"); diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c index cc524df10aa1..b3b2aaf89dbe 100755 --- a/drivers/mfd/wm8994-core.c +++ b/drivers/mfd/wm8994-core.c @@ -173,9 +173,34 @@ static struct mfd_cell wm8994_regulator_devs[] = { { .name = "wm8994-ldo", .id = 2 }, }; +static struct resource wm8994_codec_resources[] = { + { + .start = WM8994_IRQ_TEMP_SHUT, + .end = WM8994_IRQ_TEMP_WARN, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct resource wm8994_gpio_resources[] = { + { + .start = WM8994_IRQ_GPIO(1), + .end = WM8994_IRQ_GPIO(11), + .flags = IORESOURCE_IRQ, + }, +}; + static struct mfd_cell wm8994_devs[] = { - { .name = "wm8994-codec" }, - { .name = "wm8994-gpio" }, + { + .name = "wm8994-codec", + .num_resources = ARRAY_SIZE(wm8994_codec_resources), + .resources = wm8994_codec_resources, + }, + + { + .name = "wm8994-gpio", + .num_resources = ARRAY_SIZE(wm8994_gpio_resources), + .resources = wm8994_gpio_resources, + }, }; /* @@ -236,6 +261,11 @@ static int wm8994_device_resume(struct device *dev) return ret; } + ret = wm8994_write(wm8994, WM8994_INTERRUPT_STATUS_1_MASK, + WM8994_NUM_IRQ_REGS * 2, &wm8994->irq_masks_cur); + if (ret < 0) + dev_err(dev, "Failed to restore interrupt masks: %d\n", ret); + ret = wm8994_write(wm8994, WM8994_LDO_1, WM8994_NUM_LDO_REGS * 2, &wm8994->ldo_regs); if (ret < 0) @@ -296,8 +326,10 @@ static int wm8994_device_init(struct wm8994 *wm8994, unsigned long id, int irq) wm8994->supplies = kzalloc(sizeof(struct regulator_bulk_data) * ARRAY_SIZE(wm8994_main_supplies), GFP_KERNEL); - if (!wm8994->supplies) + if (!wm8994->supplies) { + ret = -ENOMEM; goto err; + } for (i = 0; i < ARRAY_SIZE(wm8994_main_supplies); i++) wm8994->supplies[i].supply = wm8994_main_supplies[i]; @@ -348,6 +380,7 @@ static int wm8994_device_init(struct wm8994 *wm8994, unsigned long id, int irq) if (pdata) { + wm8994->irq_base = pdata->irq_base; wm8994->gpio_base = pdata->gpio_base; /* GPIO configuration is only applied if it's non-zero */ @@ -375,16 +408,20 @@ static int wm8994_device_init(struct wm8994 *wm8994, unsigned long id, int irq) WM8994_LDO1_DISCH, 0); } + wm8994_irq_init(wm8994); + 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; + goto err_irq; } return 0; +err_irq: + wm8994_irq_exit(wm8994); err_enable: regulator_bulk_disable(ARRAY_SIZE(wm8994_main_supplies), wm8994->supplies); @@ -401,6 +438,7 @@ err: static void wm8994_device_exit(struct wm8994 *wm8994) { mfd_remove_devices(wm8994->dev); + wm8994_irq_exit(wm8994); regulator_bulk_disable(ARRAY_SIZE(wm8994_main_supplies), wm8994->supplies); regulator_bulk_free(ARRAY_SIZE(wm8994_main_supplies), wm8994->supplies); @@ -459,16 +497,15 @@ static int wm8994_i2c_probe(struct i2c_client *i2c, struct wm8994 *wm8994; wm8994 = kzalloc(sizeof(struct wm8994), GFP_KERNEL); - if (wm8994 == NULL) { - kfree(i2c); + if (wm8994 == NULL) 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; + wm8994->irq = i2c->irq; return wm8994_device_init(wm8994, id->driver_data, i2c->irq); } diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index e8ec569bad82..9c4ef5015d6e 100755 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -348,7 +348,7 @@ config SENSORS_CAP_PROX Say yes here if you wish to include the Motorola Capacitive Proximity Sensor driver. -config SENSORS_MOTO_KXTF9 +config SENSORS_KXTF9 tristate "KXTF9 Accelerometer" default n depends on I2C @@ -496,34 +496,9 @@ config TEGRA_CRYPTO_DEV Dev node /dev/tegra-crypto in order to get access to tegra aes hardware from user space -config STE - bool "STE modem control driver" - default n - -config MTK23D - bool "MTK6223D modem control driver" - default n - -config FM580X - bool "FM rda580x driver" - default n - -config MU509 - bool "MU509 modem control driver" - default n -config MW100 - bool "MW100 modem control driver" - default n -config RK29_NEWTON - bool "RK29_NEWTON misc driver" - default n - source "drivers/misc/c2port/Kconfig" source "drivers/misc/eeprom/Kconfig" source "drivers/misc/cb710/Kconfig" -source "drivers/misc/rk29_modem/Kconfig" -source "drivers/misc/gps/Kconfig" -source "drivers/misc/mpu3050/Kconfig" source "drivers/misc/ts27010mux/Kconfig" source "drivers/misc/iwmc3200top/Kconfig" source "drivers/misc/radio_ctrl/Kconfig" diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 03c6ab515f65..c7c058e406cf 100755 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -36,21 +36,12 @@ obj-$(CONFIG_IWMC3200TOP) += iwmc3200top/ obj-$(CONFIG_HMC6352) += hmc6352.o obj-y += eeprom/ obj-y += cb710/ -obj-$(CONFIG_MTK23D) += mtk23d.o -obj-$(CONFIG_FM580X) += fm580x.o -obj-$(CONFIG_MU509) += mu509.o -obj-$(CONFIG_MW100) += MW100.o -obj-$(CONFIG_STE) += ste.o -obj-$(CONFIG_RK29_SUPPORT_MODEM) += rk29_modem/ -obj-$(CONFIG_GPS_GNS7560) += gps/ -obj-y += mpu3050/ -obj-$(CONFIG_RK29_NEWTON) += newton.o obj-$(CONFIG_VMWARE_BALLOON) += vmw_balloon.o obj-$(CONFIG_ARM_CHARLCD) += arm-charlcd.o obj-$(CONFIG_WL127X_RFKILL) += wl127x-rfkill.o obj-$(CONFIG_APANIC) += apanic.o obj-$(CONFIG_SENSORS_AK8975) += akm8975.o -obj-$(CONFIG_SENSORS_MOTO_KXTF9)+= kxtf9.o +obj-$(CONFIG_SENSORS_KXTF9) += kxtf9.o obj-$(CONFIG_SENSORS_CAP_PROX) += cap_prox.o obj-$(CONFIG_SENSORS_MAX9635) += max9635.o obj-$(CONFIG_SENSORS_NCT1008) += nct1008.o diff --git a/drivers/misc/apanic.c b/drivers/misc/apanic.c index 4a9f48ac7480..ca875f89da7a 100644 --- a/drivers/misc/apanic.c +++ b/drivers/misc/apanic.c @@ -193,13 +193,8 @@ static int apanic_proc_read(char *buffer, char **start, off_t offset, ctx->mtd->writesize, &len, ctx->bounce); -#ifdef CONFIG_MTD_RKNAND - if (count > (ctx->mtd->writesize - page_offset)) - count = ctx->mtd->writesize - page_offset; -#else if (page_offset) count -= page_offset; -#endif memcpy(buffer, ctx->bounce + page_offset, count); *start = count; @@ -214,11 +209,6 @@ static int apanic_proc_read(char *buffer, char **start, off_t offset, static void mtd_panic_erase(void) { struct apanic_data *ctx = &drv_ctx; -#ifdef CONFIG_MTD_RKNAND - size_t wlen; - memset(ctx->bounce, 0, ctx->mtd->writesize); - ctx->mtd->write(ctx->mtd, 0, ctx->mtd->writesize, &wlen, ctx->bounce); -#else struct erase_info erase; DECLARE_WAITQUEUE(wait, current); wait_queue_head_t wait_q; @@ -270,7 +260,6 @@ static void mtd_panic_erase(void) schedule(); remove_wait_queue(&wait_q, &wait); } -#endif printk(KERN_DEBUG "apanic: %s partition erased\n", CONFIG_APANIC_PLABEL); out: @@ -342,18 +331,14 @@ static void mtd_panic_notify_add(struct mtd_info *mtd) if (hdr->magic != PANIC_MAGIC) { printk(KERN_INFO "apanic: No panic data available\n"); -#ifndef CONFIG_MTD_RKNAND mtd_panic_erase(); -#endif return; } if (hdr->version != PHDR_VERSION) { printk(KERN_INFO "apanic: Version mismatch (%d != %d)\n", hdr->version, PHDR_VERSION); -#ifndef CONFIG_MTD_RKNAND mtd_panic_erase(); -#endif return; } @@ -393,10 +378,8 @@ static void mtd_panic_notify_add(struct mtd_info *mtd) } } -#ifndef CONFIG_MTD_RKNAND if (!proc_entry_created) mtd_panic_erase(); -#endif return; out_err: @@ -528,7 +511,7 @@ static int apanic(struct notifier_block *this, unsigned long event, printk(KERN_EMERG "Crash partition in use!\n"); goto out; } - console_offset = ctx->mtd->erasesize; + console_offset = ctx->mtd->writesize; /* * Write out the console diff --git a/drivers/misc/pmem.c b/drivers/misc/pmem.c index 499507541a87..890831e2deb7 100644 --- a/drivers/misc/pmem.c +++ b/drivers/misc/pmem.c @@ -438,7 +438,7 @@ static int pmem_allocate(int id, unsigned long len) return best_fit; } -static pgprot_t pmem_phys_mem_access_prot(struct file *file, pgprot_t vma_prot) +static pgprot_t phys_mem_access_prot(struct file *file, pgprot_t vma_prot) { int id = get_id(file); #ifdef pgprot_noncached @@ -628,7 +628,7 @@ static int pmem_mmap(struct file *file, struct vm_area_struct *vma) } vma->vm_pgoff = pmem_start_addr(id, data) >> PAGE_SHIFT; - vma->vm_page_prot = pmem_phys_mem_access_prot(file, vma->vm_page_prot); + vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_page_prot); if (data->flags & PMEM_FLAGS_CONNECTED) { struct pmem_region_node *region_node; @@ -1086,8 +1086,8 @@ static long pmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg) region.offset = pmem_start_addr(id, data); region.len = pmem_len(id, data); } - //printk(KERN_INFO "pmem: request for physical address of pmem region " - // "from process %d.\n", current->pid); + printk(KERN_INFO "pmem: request for physical address of pmem region " + "from process %d.\n", current->pid); if (copy_to_user((void __user *)arg, ®ion, sizeof(struct pmem_region))) return -EFAULT; diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index d50a23be1654..e6f74718e06f 100755 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -52,10 +52,6 @@ MODULE_ALIAS("mmc:block"); #define INAND_CMD38_ARG_SECTRIM1 0x81 #define INAND_CMD38_ARG_SECTRIM2 0x88 -#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) -static DEFINE_MUTEX(block_mutex); //added by xbw at 2011-04-21 -#endif - /* * max 8 partitions per card */ @@ -114,12 +110,8 @@ static int mmc_blk_open(struct block_device *bdev, fmode_t mode) { struct mmc_blk_data *md = mmc_blk_get(bdev->bd_disk); int ret = -ENXIO; - -#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) - mutex_lock(&block_mutex); //added by xbw at 2011-04-21 -#else - //lock_kernel(); // The feature of block_mutex is same with lock_kernel£¬but the better. noted by xbw at 2011-08-09 -#endif + + lock_kernel(); if (md) { if (md->usage == 2) check_disk_change(bdev); @@ -130,12 +122,7 @@ static int mmc_blk_open(struct block_device *bdev, fmode_t mode) ret = -EROFS; } } -#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) - mutex_unlock(&block_mutex); -#else unlock_kernel(); -#endif - return ret; } @@ -143,20 +130,10 @@ static int mmc_blk_open(struct block_device *bdev, fmode_t mode) static int mmc_blk_release(struct gendisk *disk, fmode_t mode) { struct mmc_blk_data *md = disk->private_data; - -#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) - mutex_lock(&block_mutex); //added by xbw at 2011-04-21 -#else - //lock_kernel(); // The feature of block_mutex is same with lock_kernel£¬but the better. noted by xbw at 2011-08-09 -#endif - mmc_blk_put(md); - -#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) - mutex_unlock(&block_mutex); -#else - unlock_kernel(); -#endif + lock_kernel(); + mmc_blk_put(md); + unlock_kernel(); return 0; } @@ -256,13 +233,6 @@ static u32 mmc_sd_num_wr_blocks(struct mmc_card *card) return result; } -#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) //Deleted by xbw@2011-03-21 -//static u32 get_card_status(struct mmc_card *card, struct request *req) -//{ -// return 0; -//} - -#else static u32 get_card_status(struct mmc_card *card, struct request *req) { struct mmc_command cmd; @@ -275,11 +245,10 @@ static u32 get_card_status(struct mmc_card *card, struct request *req) cmd.flags = MMC_RSP_SPI_R2 | MMC_RSP_R1 | MMC_CMD_AC; err = mmc_wait_for_cmd(card->host, &cmd, 0); if (err) - printk(KERN_DEBUG "%s: error %d sending status comand", + printk(KERN_ERR "%s: error %d sending status comand", req->rq_disk->disk_name, err); return cmd.resp[0]; } -#endif static int mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req) { @@ -386,22 +355,13 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req) mmc_claim_host(card->host); do { - #if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) - //struct mmc_command cmd;//Deleted by xbw@2011-03-21 - #else - struct mmc_command cmd; - #endif - + struct mmc_command cmd; u32 readcmd, writecmd, status = 0; memset(&brq, 0, sizeof(struct mmc_blk_request)); brq.mrq.cmd = &brq.cmd; brq.mrq.data = &brq.data; - - #if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) - brq.cmd.retries = 2; //suppot retry read-write; added by xbw@2011-03-21 - #endif - + brq.cmd.arg = blk_rq_pos(req); if (!mmc_card_blockaddr(card)) brq.cmd.arg <<= 9; @@ -481,11 +441,6 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req) mmc_queue_bounce_post(mq); - #if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) - //not turn CMD18 to CMD17. deleted by xbw at 2011-04-21 - - #else - /* * Check for errors here, but don't jump to cmd_err * until later as we need to wait for the card to leave @@ -494,7 +449,7 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req) if (brq.cmd.error || brq.data.error || brq.stop.error) { if (brq.data.blocks > 1 && rq_data_dir(req) == READ) { /* Redo read one sector at a time */ - printk(KERN_DEBUG "%s: retrying using single " + printk(KERN_WARNING "%s: retrying using single " "block read\n", req->rq_disk->disk_name); disable_multi = 1; continue; @@ -502,11 +457,10 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req) status = get_card_status(card, req); } else if (disable_multi == 1) { disable_multi = 0; - } - #endif + } if (brq.cmd.error) { - printk(KERN_DEBUG "%s: error %d sending read/write " + printk(KERN_ERR "%s: error %d sending read/write " "command, response %#x, card status %#x\n", req->rq_disk->disk_name, brq.cmd.error, brq.cmd.resp[0], status); @@ -516,7 +470,7 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req) if (brq.data.error == -ETIMEDOUT && brq.mrq.stop) /* 'Stop' response contains card status */ status = brq.mrq.stop->resp[0]; - printk(KERN_DEBUG "%s: error %d transferring data," + printk(KERN_ERR "%s: error %d transferring data," " sector %u, nr %u, card status %#x\n", req->rq_disk->disk_name, brq.data.error, (unsigned)blk_rq_pos(req), @@ -524,16 +478,12 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req) } if (brq.stop.error) { - printk(KERN_DEBUG "%s: error %d sending stop command, " + printk(KERN_ERR "%s: error %d sending stop command, " "response %#x, card status %#x\n", req->rq_disk->disk_name, brq.stop.error, brq.stop.resp[0], status); } - #if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) - //Deleted by xbw@2011-03-21 - - #else if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) { do { int err; @@ -543,7 +493,7 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req) cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; err = mmc_wait_for_cmd(card->host, &cmd, 5); if (err) { - printk(KERN_DEBUG "%s: error %d requesting status\n", + printk(KERN_ERR "%s: error %d requesting status\n", req->rq_disk->disk_name, err); goto cmd_err; } @@ -563,9 +513,8 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req) goto cmd_err; #endif } -#endif - if (brq.cmd.error || brq.stop.error || brq.data.error) { + if (brq.cmd.error || brq.stop.error || brq.data.error) { if (rq_data_dir(req) == READ) { /* * After an error, we redo I/O one sector at a @@ -718,11 +667,6 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) sprintf(md->disk->disk_name, "mmcblk%d", devidx); -#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) - printk("%s..%d **** devidx=%d, dev_use[0]=%lu, disk_name=%s *** ==xbw[%s]==\n",\ - __FUNCTION__,__LINE__, devidx, dev_use[0], md->disk->disk_name,mmc_hostname(card->host)); -#endif - blk_queue_logical_block_size(md->queue.queue, 512); if (!mmc_card_sd(card) && mmc_card_blockaddr(card)) { diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index b90497f93be2..ad32bd77321f 100755 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -211,9 +211,6 @@ static void mmc_wait_done(struct mmc_request *mrq) */ void mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq) { - unsigned long datasize, waittime=0xFFFF; - u32 multi, unit; - DECLARE_COMPLETION_ONSTACK(complete); mrq->done_data = &complete; @@ -221,47 +218,7 @@ void mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq) mmc_start_request(host, mrq); -#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) - if( strncmp( mmc_hostname(host) ,"mmc0" , strlen("mmc0")) ) - { - multi = (mrq->cmd->retries>0)?mrq->cmd->retries:1; - waittime = wait_for_completion_timeout(&complete,HZ*7*multi); //sdio; for cmd dead. Modifyed by xbw at 2011-06-02 - } - else - { - //calculate the timeout value for SDMMC; added by xbw at 2011-09-27 - if(mrq->data) - { - unit = 3*(1<<20);// unit=3MB - datasize = mrq->data->blksz*mrq->data->blocks; - multi = datasize/unit; - multi += (datasize%unit)?1:0; - multi = (multi>0) ? multi : 1; - multi += (mrq->cmd->retries>0)?1:0; - waittime = wait_for_completion_timeout(&complete,HZ*7*multi); //It should be longer than bottom driver's time,due to the sum of two cmd time. - //modifyed by xbw at 2011-10-08 - // - //example: - //rk29_sdmmc_request_end..2336... CMD12 wait busy timeout!!!!! ====xbw=[sd_mmc]==== - //mmc_wait_for_req..236.. !!!!! wait for CMD25 timeout ===xbw[mmc0]=== - } - else - { - multi = (mrq->cmd->retries>0)?mrq->cmd->retries:1; - waittime = wait_for_completion_timeout(&complete,HZ*7*multi); - } - } - - if(waittime <= 1) - { - host->doneflag = 0; - mrq->cmd->error = -EIO; - printk("%s..%d.. !!!!! wait for CMD%d timeout ===xbw[%s]===\n",\ - __FUNCTION__, __LINE__, mrq->cmd->opcode, mmc_hostname(host)); - } -#else wait_for_completion(&complete); -#endif } EXPORT_SYMBOL(mmc_wait_for_req); @@ -1471,157 +1428,6 @@ int mmc_erase_group_aligned(struct mmc_card *card, unsigned int from, } EXPORT_SYMBOL(mmc_erase_group_aligned); -#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) -void mmc_rescan(struct work_struct *work) -{ - struct mmc_host *host = - container_of(work, struct mmc_host, detect.work); - u32 ocr; - int err; - int extend_wakelock = 0; - - - mmc_bus_get(host); - - /* if there is a card registered, check whether it is still present */ - if ((host->bus_ops != NULL) && host->bus_ops->detect && !host->bus_dead) - host->bus_ops->detect(host); - - /* If the card was removed the bus will be marked - * as dead - extend the wakelock so userspace - * can respond */ - if (host->bus_dead) - extend_wakelock = 1; - - mmc_bus_put(host); - - - mmc_bus_get(host); - - /* if there still is a card present, stop here */ - if (host->bus_ops != NULL) { - mmc_bus_put(host); - goto out; - } - - /* detect a newly inserted card */ - - /* - * Only we can add a new handler, so it's safe to - * release the lock here. - */ - mmc_bus_put(host); - printk("\n%s...%d.. ===== mmc_rescan Begin....======xbw[%s]=====\n",__FILE__, __LINE__, mmc_hostname(host)); - - if (host->ops->get_cd && host->ops->get_cd(host) == 0) - { - printk("\n=================\n%s..%d.. ====find no SDMMC host.====xbw[%s]=====\n", \ - __FUNCTION__, __LINE__, mmc_hostname(host)); - - goto out; - } - - mmc_claim_host(host); - - mmc_power_up(host); - - mmc_go_idle(host); - - /* - In oder to improve the initialization process in rockchip IC, I modify the following code about the the initialization process of SDIO-SD-MMC. - So I deleted the CMD8 and add a conditional to distinguish between the two card type,i.e.SDMMC process and SDIO process. - For detail,please refer to "RK29XX Technical Reference Manual" and "SD-MMC-SDIO Specifications". - Noted by xbw@2011-04-09 - */ - - //mmc_send_if_cond(host, host->ocr_avail); //deleted by xbw@2011-04-09 -#if !defined(CONFIG_USE_SDMMC0_FOR_WIFI_DEVELOP_BOARD) - if( strncmp( mmc_hostname(host) ,"mmc0" , strlen("mmc0")) ){ -#endif - /* - * First we search for SDIO... - */ - err = mmc_send_io_op_cond(host, 0, &ocr); - if (!err) { - printk("\n%s..%d.. ===== Begin to identify card as SDIO-card===xbw[%s]===\n",__FUNCTION__, __LINE__, mmc_hostname(host)); - - if (mmc_attach_sdio(host, ocr)) - { - printk("\n=====\n %s..%d.. ===== Initialize SDIO-card unsuccessfully!!! ===xbw[%s]===\n=====\n",\ - __FUNCTION__, __LINE__, mmc_hostname(host)); - - mmc_power_off(host); - } - else - { - printk("%s..%d.. ===== Initialize SDIO successfully. ===xbw[%s]===\n",__FUNCTION__, __LINE__, mmc_hostname(host)); - } - extend_wakelock = 1; - goto out; - } -#if !defined(CONFIG_USE_SDMMC0_FOR_WIFI_DEVELOP_BOARD) - } -#endif - - /* - * ...then normal SD... - */ - err = mmc_send_app_op_cond(host, 0, &ocr); - if (!err) { - printk("\n%s..%d.. ===== Begin to identify card as SD-card ===xbw[%s]===\n",__FUNCTION__, __LINE__, mmc_hostname(host)); - - if (mmc_attach_sd(host, ocr)) - { - printk("\n=====\n%s..%d.. ===== Initialize SD-card unsuccessfully!!! ===xbw[%s]===\n====\n",\ - __FUNCTION__, __LINE__, mmc_hostname(host)); - - mmc_power_off(host); - } - else - { - printk("%s..%d.. ===== Initialize SD-card successfully. ===xbw[%s]===\n",__FUNCTION__, __LINE__, mmc_hostname(host)); - } - extend_wakelock = 1; - goto out; - } - - /* - * ...and finally MMC. - */ - err = mmc_send_op_cond(host, 0, &ocr); - if (!err) { - printk("\n%s..%d.. ===== Begin to identify card as MMC-card ===xbw[%s]===\n", __FUNCTION__, __LINE__, mmc_hostname(host)); - - if (mmc_attach_mmc(host, ocr)) - { - printk("\n =====\n%s..%d.. ===== Initialize MMC-card unsuccessfully!!! ===xbw[%s]===\n======\n",\ - __FUNCTION__, __LINE__, mmc_hostname(host)); - - mmc_power_off(host); - } - else - { - printk("%s...%d.. ===== Initialize MMC-card successfully. ===xbw[%s]===\n",__FUNCTION__, __LINE__, mmc_hostname(host)); - } - extend_wakelock = 1; - goto out; - } - - mmc_release_host(host); - mmc_power_off(host); - -out: - - if (extend_wakelock) - wake_lock_timeout(&mmc_delayed_work_wake_lock, HZ / 2); - else - wake_unlock(&mmc_delayed_work_wake_lock); - - if (host->caps & MMC_CAP_NEEDS_POLL) - mmc_schedule_delayed_work(&host->detect, HZ); -} - -#else void mmc_rescan(struct work_struct *work) { struct mmc_host *host = @@ -1671,7 +1477,7 @@ void mmc_rescan(struct work_struct *work) * release the lock here. */ mmc_bus_put(host); - + if (host->ops->get_cd && host->ops->get_cd(host) == 0) goto out; @@ -1680,7 +1486,7 @@ void mmc_rescan(struct work_struct *work) mmc_power_up(host); sdio_reset(host); mmc_go_idle(host); - + mmc_send_if_cond(host, host->ocr_avail); /* @@ -1736,7 +1542,6 @@ out: if (host->caps & MMC_CAP_NEEDS_POLL) mmc_schedule_delayed_work(&host->detect, HZ); } -#endif void mmc_start_host(struct mmc_host *host) { @@ -1920,11 +1725,6 @@ int mmc_resume_host(struct mmc_host *host) mmc_select_voltage(host, host->ocr); } BUG_ON(!host->bus_ops->resume); -#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) - //panic if the card is being removed during the resume, deleted by xbw at 2011-06-20 - host->bus_ops->resume(host); - -#else err = host->bus_ops->resume(host); if (err) { printk(KERN_WARNING "%s: error %d during resume " @@ -1932,7 +1732,6 @@ int mmc_resume_host(struct mmc_host *host) mmc_hostname(host), err); err = 0; } -#endif } mmc_bus_put(host); diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 1f4fd781ef29..6909a54c39be 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -378,13 +378,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, /* The extra bit indicates that we support high capacity */ err = mmc_send_op_cond(host, ocr | (1 << 30), NULL); if (err) - { -#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) - printk("%s..%d.. ====*Identify the card as MMC , but OCR error, so fail to initialize.===xbw[%s]===\n",\ - __FUNCTION__, __LINE__, mmc_hostname(host)); -#endif goto err; - } /* * For SPI, enable CRC as appropriate. @@ -503,10 +497,6 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, if (max_dtr > card->ext_csd.hs_max_dtr) max_dtr = card->ext_csd.hs_max_dtr; } else if (max_dtr > card->csd.max_dtr) { -#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) - //in order to expand the compatibility of card. Added by xbw@2011-03-21 - card->csd.max_dtr = (card->csd.max_dtr > MMC_FPP_FREQ) ? MMC_FPP_FREQ : (card->csd.max_dtr); -#endif max_dtr = card->csd.max_dtr; } @@ -708,9 +698,6 @@ static void mmc_attach_bus_ops(struct mmc_host *host) int mmc_attach_mmc(struct mmc_host *host, u32 ocr) { int err; -#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) - int retry_times = 3; -#endif BUG_ON(!host); WARN_ON(!host->claimed); @@ -755,33 +742,10 @@ int mmc_attach_mmc(struct mmc_host *host, u32 ocr) goto err; mmc_release_host(host); - -#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) -//modifyed by xbw at 2011--04-11 -Retry_add: - err = mmc_add_card(host->card); - if (err) - { - //retry add the card; Added by xbw - if((--retry_times >= 0)) - { - printk("\n%s..%s..%d ****error in add partition, so retry. ===xbw[%s]===\n",__FUNCTION__,__FILE__,__LINE__, mmc_hostname(host)); - /* sleep some time */ - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(HZ/2); - - goto Retry_add; - } - goto remove_card; - - } -#else - err = mmc_add_card(host->card); + err = mmc_add_card(host->card); if (err) goto remove_card; -#endif - return 0; diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index 52da7745b98f..7ab8fdc61c77 100755 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -422,13 +422,8 @@ int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid) ocr |= 1 << 30; err = mmc_send_app_op_cond(host, ocr, NULL); - if (err) { -#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) - printk("%s..%d.. ====*Identify the card as SD , but OCR error, so fail to initialize.===xbw[%s]===\n", \ - __FUNCTION__, __LINE__, mmc_hostname(host)); -#endif + if (err) return err; - } if (mmc_host_is_spi(host)) err = mmc_send_cid(host, cid); @@ -503,13 +498,6 @@ int mmc_sd_setup_card(struct mmc_host *host, struct mmc_card *card, printk(KERN_WARNING "%s: read switch failed (attempt %d)\n", mmc_hostname(host), retries); - -#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) - if(0 == host->re_initialized_flags) - { - break; //Added by xbw at 2011-06-21 - } -#endif } } #else @@ -562,11 +550,6 @@ unsigned mmc_sd_get_max_clock(struct mmc_card *card) if (max_dtr > card->sw_caps.hs_max_dtr) max_dtr = card->sw_caps.hs_max_dtr; } else if (max_dtr > card->csd.max_dtr) { - -#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) - //in order to expand the compatibility of card. Added by xbw@2011-03-21 - card->csd.max_dtr = (card->csd.max_dtr > SD_FPP_FREQ) ? SD_FPP_FREQ : (card->csd.max_dtr); -#endif max_dtr = card->csd.max_dtr; } @@ -719,15 +702,6 @@ static void mmc_sd_detect(struct mmc_host *host) err = mmc_send_status(host->card, NULL); if (err) { retries--; - -#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) - if(0 == host->re_initialized_flags) - { - retries = 0; - break; //Added by xbw at 2011-06-21 - } -#endif - udelay(5); continue; } @@ -795,13 +769,6 @@ static int mmc_sd_resume(struct mmc_host *host) mmc_hostname(host), err, retries); mdelay(5); retries--; - -#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) - if(0 == host->re_initialized_flags) - { - break; //Added by xbw at 2011-06-21 - } -#endif continue; } break; @@ -855,10 +822,6 @@ static void mmc_sd_attach_bus_ops(struct mmc_host *host) int mmc_attach_sd(struct mmc_host *host, u32 ocr) { int err; -#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) - int retry_times = 3; -#endif - #ifdef CONFIG_MMC_PARANOID_SD_INIT int retries; #endif @@ -916,14 +879,6 @@ int mmc_attach_sd(struct mmc_host *host, u32 ocr) err = mmc_sd_init_card(host, host->ocr, NULL); if (err) { retries--; - - #if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) - if(0 == host->re_initialized_flags) - { - retries = 0; - break; //Added by xbw at 2011-06-21 - } - #endif continue; } break; @@ -942,31 +897,9 @@ int mmc_attach_sd(struct mmc_host *host, u32 ocr) mmc_release_host(host); -#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) -//modifyed by xbw at 2011--04-11 -Retry_add: err = mmc_add_card(host->card); - if (err) - { - //retry add the card; Added by xbw - if((--retry_times >= 0)) - { - printk("\n%s..%s..%d ****error in add partition, so retry. ===xbw[%s]===\n",__FUNCTION__,__FILE__,__LINE__, mmc_hostname(host)); - /* sleep some time */ - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(HZ/2); - - goto Retry_add; - } - - goto remove_card; - - } -#else - err = mmc_add_card(host->card); if (err) goto remove_card; -#endif return 0; diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index da17bddc15fc..d3ec4dc18d14 100755 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -346,13 +346,8 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, */ if (!powered_resume) { err = mmc_send_io_op_cond(host, host->ocr, &ocr); - if (err) { -#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) - printk("%s..%d.. ====*Identify the card as SDIO , but OCR error, so fail to initialize.===xbw[%s]===\n", \ - __FUNCTION__, __LINE__, mmc_hostname(host)); -#endif + if (err) goto err; - } } /* @@ -405,16 +400,6 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, if (err) goto remove; -#if defined(CONFIG_SDMMC_RK29) && defined(CONFIG_SDMMC_RK29_OLD) //old driver add the code ,reform to kernel2.6.38 - /* - * Update oldcard with the new RCA received from the SDIO - * device -- we're doing this so that it's updated in the - * "card" struct when oldcard overwrites that later. - */ - if (oldcard) - oldcard->rca = card->rca; -#endif - mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); } @@ -822,10 +807,6 @@ int sdio_reset_comm(struct mmc_card *card) printk("%s():\n", __func__); mmc_claim_host(host); - -#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) - host->sdmmc_host_hw_init(mmc_priv(host)); //added by xbw , at 2011-10-18 -#endif mmc_go_idle(host); diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index 762b4dda25d3..ba4c798b7cf6 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -6,12 +6,6 @@ ifeq ($(CONFIG_MMC_DEBUG),y) EXTRA_CFLAGS += -DDEBUG endif -ifeq ($(CONFIG_SDMMC_RK29_OLD),y) -obj-$(CONFIG_SDMMC_RK29) += rk29_sdmmc_old.o -else -obj-$(CONFIG_SDMMC_RK29) += rk29_sdmmc.o -endif - obj-$(CONFIG_MMC_ARMMMCI) += mmci.o obj-$(CONFIG_MMC_PXA) += pxamci.o obj-$(CONFIG_MMC_IMX) += imxmmc.o diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index 991df931d4aa..a37a8293f43b 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig @@ -17,53 +17,270 @@ menuconfig WLAN if WLAN -config WLAN_80211 - bool "Wireless LAN (IEEE 802.11)" - depends on NETDEVICES +config PCMCIA_RAYCS + tristate "Aviator/Raytheon 2.4GHz wireless support" + depends on PCMCIA + select WIRELESS_EXT + select WEXT_SPY + select WEXT_PRIV ---help--- - Say Y if you have any 802.11 wireless LAN hardware. - - This option does not affect the kernel build, it only - lets you choose drivers. - -choice - prompt "WiFi device driver support" - default WIFI_NONE - - config WIFI_NONE - bool "No WiFi" - - config BCM4329 - depends on WLAN_80211 && MMC - select WIRELESS_EXT - select WEXT_PRIV - select IEEE80211 - select FW_LOADER - bool "Broadcom BCM4329 WiFi/BT Combo SDIO" - ---help--- - A library for Broadcom BCM4329 SDIO WLAN/BT combo devices. - So far, the following modules have been verified: - (1) Samsung SWL-B23 - - config MV8686 - depends on WLAN_80211 && MMC - select WIRELESS_EXT - select IEEE80211 - select FW_LOADER - bool "Marvell MV8686 SDIO" - ---help--- - A library for Marvell 8686 SDIO WLAN devices. - So far, the following modules have been verified: - (1) Samsung SWL-2480 - (2) Azurewave AW-GH321 - (3) USI WM-G-MR-09 - (4) Murata SP-8HEP-P - -source "drivers/net/wireless/bcm4319/Kconfig" -source "drivers/net/wireless/rtl8192c/Kconfig" -endchoice - -#source "drivers/net/wireless/bcm4329/Kconfig" - -endif + Say Y here if you intend to attach an Aviator/Raytheon PCMCIA + (PC-card) wireless Ethernet networking card to your computer. + Please read the file for + details. + To compile this driver as a module, choose M here: the module will be + called ray_cs. If unsure, say N. + +config LIBERTAS_THINFIRM + tristate "Marvell 8xxx Libertas WLAN driver support with thin firmware" + depends on MAC80211 + select FW_LOADER + ---help--- + A library for Marvell Libertas 8xxx devices using thinfirm. + +config LIBERTAS_THINFIRM_DEBUG + bool "Enable full debugging output in the Libertas thin firmware module." + depends on LIBERTAS_THINFIRM + ---help--- + Debugging support. + +config LIBERTAS_THINFIRM_USB + tristate "Marvell Libertas 8388 USB 802.11b/g cards with thin firmware" + depends on LIBERTAS_THINFIRM && USB + ---help--- + A driver for Marvell Libertas 8388 USB devices using thinfirm. + +config AIRO + tristate "Cisco/Aironet 34X/35X/4500/4800 ISA and PCI cards" + depends on ISA_DMA_API && (PCI || BROKEN) + select WIRELESS_EXT + select CRYPTO + select WEXT_SPY + select WEXT_PRIV + ---help--- + This is the standard Linux driver to support Cisco/Aironet ISA and + PCI 802.11 wireless cards. + It supports the new 802.11b cards from Cisco (Cisco 34X, Cisco 35X + - with or without encryption) as well as card before the Cisco + acquisition (Aironet 4500, Aironet 4800, Aironet 4800B). + + This driver support both the standard Linux Wireless Extensions + and Cisco proprietary API, so both the Linux Wireless Tools and the + Cisco Linux utilities can be used to configure the card. + + The driver can be compiled as a module and will be named "airo". + +config ATMEL + tristate "Atmel at76c50x chipset 802.11b support" + depends on (PCI || PCMCIA) + select WIRELESS_EXT + select WEXT_PRIV + select FW_LOADER + select CRC32 + ---help--- + A driver 802.11b wireless cards based on the Atmel fast-vnet + chips. This driver supports standard Linux wireless extensions. + + Many cards based on this chipset do not have flash memory + and need their firmware loaded at start-up. If yours is + one of these, you will need to provide a firmware image + to be loaded into the card by the driver. The Atmel + firmware package can be downloaded from + + +config PCI_ATMEL + tristate "Atmel at76c506 PCI cards" + depends on ATMEL && PCI + ---help--- + Enable support for PCI and mini-PCI cards containing the + Atmel at76c506 chip. + +config PCMCIA_ATMEL + tristate "Atmel at76c502/at76c504 PCMCIA cards" + depends on ATMEL && PCMCIA + select WIRELESS_EXT + select FW_LOADER + select CRC32 + ---help--- + Enable support for PCMCIA cards containing the + Atmel at76c502 and at76c504 chips. + +config AT76C50X_USB + tristate "Atmel at76c503/at76c505/at76c505a USB cards" + depends on MAC80211 && USB + select FW_LOADER + ---help--- + Enable support for USB Wireless devices using Atmel at76c503, + at76c505 or at76c505a chips. + +config AIRO_CS + tristate "Cisco/Aironet 34X/35X/4500/4800 PCMCIA cards" + depends on PCMCIA && (BROKEN || !M32R) + select WIRELESS_EXT + select WEXT_SPY + select WEXT_PRIV + select CRYPTO + select CRYPTO_AES + ---help--- + This is the standard Linux driver to support Cisco/Aironet PCMCIA + 802.11 wireless cards. This driver is the same as the Aironet + driver part of the Linux Pcmcia package. + It supports the new 802.11b cards from Cisco (Cisco 34X, Cisco 35X + - with or without encryption) as well as card before the Cisco + acquisition (Aironet 4500, Aironet 4800, Aironet 4800B). It also + supports OEM of Cisco such as the DELL TrueMobile 4800 and Xircom + 802.11b cards. + + This driver support both the standard Linux Wireless Extensions + and Cisco proprietary API, so both the Linux Wireless Tools and the + Cisco Linux utilities can be used to configure the card. + +config PCMCIA_WL3501 + tristate "Planet WL3501 PCMCIA cards" + depends on EXPERIMENTAL && PCMCIA + select WIRELESS_EXT + select WEXT_SPY + help + A driver for WL3501 PCMCIA 802.11 wireless cards made by Planet. + It has basic support for Linux wireless extensions and initial + micro support for ethtool. + +config PRISM54 + tristate 'Intersil Prism GT/Duette/Indigo PCI/Cardbus (DEPRECATED)' + depends on PCI && EXPERIMENTAL + select WIRELESS_EXT + select WEXT_SPY + select WEXT_PRIV + select FW_LOADER + ---help--- + This enables support for FullMAC PCI/Cardbus prism54 devices. This + driver is now deprecated in favor for the SoftMAC driver, p54pci. + p54pci supports FullMAC PCI/Cardbus devices as well. For details on + the scheduled removal of this driver on the kernel see the feature + removal schedule: + + Documentation/feature-removal-schedule.txt + + For more information refer to the p54 wiki: + + http://wireless.kernel.org/en/users/Drivers/p54 + + Note: You need a motherboard with DMA support to use any of these cards + + When built as module you get the module prism54 + +config USB_ZD1201 + tristate "USB ZD1201 based Wireless device support" + depends on USB + select WIRELESS_EXT + select WEXT_PRIV + select FW_LOADER + ---help--- + Say Y if you want to use wireless LAN adapters based on the ZyDAS + ZD1201 chip. + + This driver makes the adapter appear as a normal Ethernet interface, + typically on wlan0. + + The zd1201 device requires external firmware to be loaded. + This can be found at http://linux-lc100020.sourceforge.net/ + + To compile this driver as a module, choose M here: the + module will be called zd1201. + +config USB_NET_RNDIS_WLAN + tristate "Wireless RNDIS USB support" + depends on USB && EXPERIMENTAL + depends on CFG80211 + select USB_USBNET + select USB_NET_CDCETHER + select USB_NET_RNDIS_HOST + ---help--- + This is a driver for wireless RNDIS devices. + These are USB based adapters found in devices such as: + + Buffalo WLI-U2-KG125S + U.S. Robotics USR5421 + Belkin F5D7051 + Linksys WUSB54GSv2 + Linksys WUSB54GSC + Asus WL169gE + Eminent EM4045 + BT Voyager 1055 + Linksys WUSB54GSv1 + U.S. Robotics USR5420 + BUFFALO WLI-USB-G54 + + All of these devices are based on Broadcom 4320 chip which is the + only wireless RNDIS chip known to date. + + If you choose to build a module, it'll be called rndis_wlan. + +source "drivers/net/wireless/rtl818x/Kconfig" + +config ADM8211 + tristate "ADMtek ADM8211 support" + depends on MAC80211 && PCI && EXPERIMENTAL + select CRC32 + select EEPROM_93CX6 + ---help--- + This driver is for ADM8211A, ADM8211B, and ADM8211C based cards. + These are PCI/mini-PCI/Cardbus 802.11b chips found in cards such as: + + Xterasys Cardbus XN-2411b + Blitz NetWave Point PC + TrendNet 221pc + Belkin F5D6001 + SMC 2635W + Linksys WPC11 v1 + Fiberline FL-WL-200X + 3com Office Connect (3CRSHPW796) + Corega WLPCIB-11 + SMC 2602W V2 EU + D-Link DWL-520 Revision C + + However, some of these cards have been replaced with other chips + like the RTL8180L (Xterasys Cardbus XN-2411b, Belkin F5D6001) or + the Ralink RT2400 (SMC2635W) without a model number change. + + Thanks to Infineon-ADMtek for their support of this driver. + +config MAC80211_HWSIM + tristate "Simulated radio testing tool for mac80211" + depends on MAC80211 + ---help--- + This driver is a developer testing tool that can be used to test + IEEE 802.11 networking stack (mac80211) functionality. This is not + needed for normal wireless LAN usage and is only for testing. See + Documentation/networking/mac80211_hwsim for more information on how + to use this tool. + + To compile this driver as a module, choose M here: the module will be + called mac80211_hwsim. If unsure, say N. + +config MWL8K + tristate "Marvell 88W8xxx PCI/PCIe Wireless support" + depends on MAC80211 && PCI && EXPERIMENTAL + ---help--- + This driver supports Marvell TOPDOG 802.11 wireless cards. + + To compile this driver as a module, choose M here: the module + will be called mwl8k. If unsure, say N. + +source "drivers/net/wireless/ath/Kconfig" +source "drivers/net/wireless/b43/Kconfig" +source "drivers/net/wireless/b43legacy/Kconfig" +source "drivers/net/wireless/bcm4329/Kconfig" +source "drivers/net/wireless/hostap/Kconfig" +source "drivers/net/wireless/ipw2x00/Kconfig" +source "drivers/net/wireless/iwlwifi/Kconfig" +source "drivers/net/wireless/iwmc3200wifi/Kconfig" +source "drivers/net/wireless/libertas/Kconfig" +source "drivers/net/wireless/orinoco/Kconfig" +source "drivers/net/wireless/p54/Kconfig" +source "drivers/net/wireless/rt2x00/Kconfig" +source "drivers/net/wireless/wl12xx/Kconfig" +source "drivers/net/wireless/zd1211rw/Kconfig" + +endif # WLAN diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile index 2ccf4df000cb..06cf827833cf 100644 --- a/drivers/net/wireless/Makefile +++ b/drivers/net/wireless/Makefile @@ -1,9 +1,56 @@ # # Makefile for the Linux Wireless network device drivers. # -obj-y += wifi_sys/rkwifi_sys_iface.o -obj-$(CONFIG_BCM4329) += bcm4329/ -obj-$(CONFIG_MV8686) += mv8686/ -obj-$(CONFIG_BCM4319) += bcm4319/ -obj-$(CONFIG_RTL8192CU) += rtl8192c/ -#obj-m += wlan/ + +obj-$(CONFIG_IPW2100) += ipw2x00/ +obj-$(CONFIG_IPW2200) += ipw2x00/ + +obj-$(CONFIG_HERMES) += orinoco/ + +obj-$(CONFIG_AIRO) += airo.o +obj-$(CONFIG_AIRO_CS) += airo_cs.o airo.o + +obj-$(CONFIG_ATMEL) += atmel.o +obj-$(CONFIG_PCI_ATMEL) += atmel_pci.o +obj-$(CONFIG_PCMCIA_ATMEL) += atmel_cs.o + +obj-$(CONFIG_AT76C50X_USB) += at76c50x-usb.o + +obj-$(CONFIG_PRISM54) += prism54/ + +obj-$(CONFIG_HOSTAP) += hostap/ +obj-$(CONFIG_B43) += b43/ +obj-$(CONFIG_B43LEGACY) += b43legacy/ +obj-$(CONFIG_ZD1211RW) += zd1211rw/ +obj-$(CONFIG_RTL8180) += rtl818x/ +obj-$(CONFIG_RTL8187) += rtl818x/ + +# 16-bit wireless PCMCIA client drivers +obj-$(CONFIG_PCMCIA_RAYCS) += ray_cs.o +obj-$(CONFIG_PCMCIA_WL3501) += wl3501_cs.o + +obj-$(CONFIG_USB_NET_RNDIS_WLAN) += rndis_wlan.o + +obj-$(CONFIG_USB_ZD1201) += zd1201.o +obj-$(CONFIG_LIBERTAS) += libertas/ + +obj-$(CONFIG_LIBERTAS_THINFIRM) += libertas_tf/ + +obj-$(CONFIG_ADM8211) += adm8211.o + +obj-$(CONFIG_MWL8K) += mwl8k.o + +obj-$(CONFIG_IWLWIFI) += iwlwifi/ +obj-$(CONFIG_RT2X00) += rt2x00/ + +obj-$(CONFIG_P54_COMMON) += p54/ + +obj-$(CONFIG_ATH_COMMON) += ath/ + +obj-$(CONFIG_MAC80211_HWSIM) += mac80211_hwsim.o + +obj-$(CONFIG_WL12XX) += wl12xx/ + +obj-$(CONFIG_IWM) += iwmc3200wifi/ + +obj-$(CONFIG_BCM4329) += bcm4329/ diff --git a/drivers/net/wireless/bcm4329/Kconfig b/drivers/net/wireless/bcm4329/Kconfig index aa4355a6225e..ca5760d32385 100644 --- a/drivers/net/wireless/bcm4329/Kconfig +++ b/drivers/net/wireless/bcm4329/Kconfig @@ -22,6 +22,6 @@ config BCM4329_FW_PATH config BCM4329_NVRAM_PATH depends on BCM4329 string "NVRAM path" - default "/system/etc/firmware/nvram_B23.txt" + default "/proc/calibration" ---help--- Path to the calibration file. diff --git a/drivers/net/wireless/bcm4329/Makefile b/drivers/net/wireless/bcm4329/Makefile index fd04754d70b1..5a662be7fc53 100755 --- a/drivers/net/wireless/bcm4329/Makefile +++ b/drivers/net/wireless/bcm4329/Makefile @@ -3,16 +3,13 @@ DHDCFLAGS = -DLINUX -DBCMDRIVER -DBCMDONGLEHOST -DDHDTHREAD -DBCMWPA2 \ -DUNRELEASEDCHIP -Dlinux -DDHD_SDALIGN=64 -DMAX_HDR_READ=64 \ -DDHD_FIRSTREAD=64 -DDHD_GPL -DDHD_SCHED -DBDC -DTOE -DDHD_BCMEVENTS \ -DSHOW_EVENTS -DBCMSDIO -DDHD_GPL -DBCMLXSDMMC -DBCMPLATFORM_BUS \ - -Wall -Wstrict-prototypes -Werror -DCUSTOMER_HW2 \ - -DDHD_USE_STATIC_BUF -DDHD_DEBUG_TRAP -DSOFTAP -DSDIO_ISR_THREAD \ + -Wall -Wstrict-prototypes -Werror -DOOB_INTR_ONLY -DCUSTOMER_HW2 \ + -DDHD_USE_STATIC_BUF -DMMC_SDIO_ABORT -DDHD_DEBUG_TRAP -DSOFTAP \ -DEMBEDDED_PLATFORM -DARP_OFFLOAD_SUPPORT -DPKT_FILTER_SUPPORT \ - -DGET_CUSTOM_MAC_ENABLE -DSET_RANDOM_MAC_SOFTAP -DCSCAN \ - -DKEEP_ALIVE -DCONFIG_US_NON_DFS_CHANNELS_ONLY \ + -DGET_CUSTOM_MAC_ENABLE -DSET_RANDOM_MAC_SOFTAP -DCSCAN -DHW_OOB \ + -DKEEP_ALIVE -DPNO_SUPPORT \ -Idrivers/net/wireless/bcm4329 -Idrivers/net/wireless/bcm4329/include -#options defines dependent on platform board and applicantion requirements: -#-DOOB_INTR_ONLY -DMMC_SDIO_ABORT -DHW_OOB - DHDOFILES = dhd_linux.o linux_osl.o bcmutils.o dhd_common.o dhd_custom_gpio.o \ wl_iw.o siutils.o sbutils.o aiutils.o hndpmu.o bcmwifi.o dhd_sdio.o \ dhd_linux_sched.o dhd_cdc.o bcmsdh_sdmmc.o bcmsdh.o bcmsdh_linux.o \ diff --git a/drivers/net/wireless/bcm4329/bcmsdh_linux.c b/drivers/net/wireless/bcm4329/bcmsdh_linux.c index cdb2c5e1f1ec..94f19a1c46a4 100644 --- a/drivers/net/wireless/bcm4329/bcmsdh_linux.c +++ b/drivers/net/wireless/bcm4329/bcmsdh_linux.c @@ -301,7 +301,7 @@ int bcmsdh_remove(struct device *dev) MFREE(osh, sdhc, sizeof(bcmsdh_hc_t)); osl_detach(osh); -#if !defined(BCMLXSDMMC) +#if !defined(BCMLXSDMMC) || defined(OOB_INTR_ONLY) dev_set_drvdata(dev, NULL); #endif /* !defined(BCMLXSDMMC) */ @@ -661,10 +661,12 @@ void bcmsdh_unregister_oob_intr(void) { SDLX_MSG(("%s: Enter\n", __FUNCTION__)); - set_irq_wake(sdhcinfo->oob_irq, 0); - disable_irq(sdhcinfo->oob_irq); /* just in case.. */ - free_irq(sdhcinfo->oob_irq, NULL); - sdhcinfo->oob_irq_registered = FALSE; + if (sdhcinfo->oob_irq_registered) { + set_irq_wake(sdhcinfo->oob_irq, 0); + disable_irq(sdhcinfo->oob_irq); /* just in case.. */ + free_irq(sdhcinfo->oob_irq, NULL); + sdhcinfo->oob_irq_registered = FALSE; + } } #endif /* defined(OOB_INTR_ONLY) */ /* Module parameters specific to each host-controller driver */ diff --git a/drivers/net/wireless/bcm4329/bcmsdh_sdmmc_linux.c b/drivers/net/wireless/bcm4329/bcmsdh_sdmmc_linux.c index 8992a4267f9f..5a1a46c93571 100644 --- a/drivers/net/wireless/bcm4329/bcmsdh_sdmmc_linux.c +++ b/drivers/net/wireless/bcm4329/bcmsdh_sdmmc_linux.c @@ -82,7 +82,6 @@ PBCMSDH_SDMMC_INSTANCE gInstance; extern int bcmsdh_probe(struct device *dev); extern int bcmsdh_remove(struct device *dev); -struct device sdmmc_dev; static int bcmsdh_sdmmc_probe(struct sdio_func *func, const struct sdio_device_id *id) @@ -102,7 +101,7 @@ static int bcmsdh_sdmmc_probe(struct sdio_func *func, if(func->device == 0x4) { /* 4318 */ gInstance->func[2] = NULL; sd_trace(("NIC found, calling bcmsdh_probe...\n")); - ret = bcmsdh_probe(&sdmmc_dev); + ret = bcmsdh_probe(&func->dev); } } @@ -110,7 +109,7 @@ static int bcmsdh_sdmmc_probe(struct sdio_func *func, if (func->num == 2) { sd_trace(("F2 found, calling bcmsdh_probe...\n")); - ret = bcmsdh_probe(&sdmmc_dev); + ret = bcmsdh_probe(&func->dev); } return ret; @@ -126,7 +125,7 @@ static void bcmsdh_sdmmc_remove(struct sdio_func *func) if (func->num == 2) { sd_trace(("F2 found, calling bcmsdh_remove...\n")); - bcmsdh_remove(&sdmmc_dev); + bcmsdh_remove(&func->dev); } } @@ -250,10 +249,8 @@ int sdio_function_init(void) if (!gInstance) return -ENOMEM; - bzero(&sdmmc_dev, sizeof(sdmmc_dev)); error = sdio_register_driver(&bcmsdh_sdmmc_driver); - return error; } @@ -265,7 +262,6 @@ void sdio_function_cleanup(void) { sd_trace(("%s Enter\n", __FUNCTION__)); - sdio_unregister_driver(&bcmsdh_sdmmc_driver); if (gInstance) diff --git a/drivers/net/wireless/bcm4329/dhd.h b/drivers/net/wireless/bcm4329/dhd.h index 1ddf1ff61e70..573f425527ff 100644 --- a/drivers/net/wireless/bcm4329/dhd.h +++ b/drivers/net/wireless/bcm4329/dhd.h @@ -24,7 +24,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: dhd.h,v 1.32.4.7.2.4.14.49.4.7 2010/11/12 22:48:36 Exp $ + * $Id: dhd.h,v 1.32.4.7.2.4.14.49.4.9 2011/01/14 22:40:45 Exp $ */ /**************** @@ -164,7 +164,7 @@ typedef struct dhd_pub { char * pktfilter[100]; int pktfilter_count; - uint8 country_code[WLC_CNTRY_BUF_SZ]; + wl_country_t dhd_cspec; /* Current Locale info */ char eventmask[WL_EVENTING_MASK_LEN]; } dhd_pub_t; @@ -179,7 +179,7 @@ typedef struct dhd_pub { wait_event_interruptible_timeout(a, FALSE, HZ/100); \ } \ } while (0) - #define DHD_PM_RESUME_WAIT(a) _DHD_PM_RESUME_WAIT(a, 30) + #define DHD_PM_RESUME_WAIT(a) _DHD_PM_RESUME_WAIT(a, 200) #define DHD_PM_RESUME_WAIT_FOREVER(a) _DHD_PM_RESUME_WAIT(a, ~0) #define DHD_PM_RESUME_RETURN_ERROR(a) do { if (dhd_mmc_suspend) return a; } while (0) #define DHD_PM_RESUME_RETURN do { if (dhd_mmc_suspend) return; } while (0) @@ -214,6 +214,20 @@ typedef struct dhd_pub { #define DHD_IF_VIF 0x01 /* Virtual IF (Hidden from user) */ +inline static void NETIF_ADDR_LOCK(struct net_device *dev) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)) + netif_addr_lock_bh(dev); +#endif +} + +inline static void NETIF_ADDR_UNLOCK(struct net_device *dev) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)) + netif_addr_unlock_bh(dev); +#endif +} + /* Wakelock Functions */ extern int dhd_os_wake_lock(dhd_pub_t *pub); extern int dhd_os_wake_unlock(dhd_pub_t *pub); @@ -434,4 +448,9 @@ extern char nv_path[MOD_PARAM_PATHLEN]; extern void dhd_wait_for_event(dhd_pub_t *dhd, bool *lockvar); extern void dhd_wait_event_wakeup(dhd_pub_t*dhd); +/* dhd_commn arp offload wrapers */ +extern void dhd_arp_cleanup(dhd_pub_t *dhd); +int dhd_arp_get_arp_hostip_table(dhd_pub_t *dhd, void *buf, int buflen); +void dhd_arp_offload_add_ip(dhd_pub_t *dhd, u32 ipaddr); + #endif /* _dhd_h_ */ diff --git a/drivers/net/wireless/bcm4329/dhd_cdc.c b/drivers/net/wireless/bcm4329/dhd_cdc.c index a68ad61c58b4..61f6a6f393a9 100644 --- a/drivers/net/wireless/bcm4329/dhd_cdc.c +++ b/drivers/net/wireless/bcm4329/dhd_cdc.c @@ -41,8 +41,6 @@ #include #include -uint8 wlan_mac_addr[ETHER_ADDR_LEN]; - extern int dhd_preinit_ioctls(dhd_pub_t *dhd); /* Packet alignment for most efficient SDIO (can change based on platform) */ @@ -504,7 +502,6 @@ dhd_prot_init(dhd_pub_t *dhd) return ret; } memcpy(dhd->mac.octet, buf, ETHER_ADDR_LEN); - memcpy(wlan_mac_addr, buf, ETHER_ADDR_LEN); dhd_os_proto_unblock(dhd); diff --git a/drivers/net/wireless/bcm4329/dhd_common.c b/drivers/net/wireless/bcm4329/dhd_common.c index 47e29969126a..e50da1414c9e 100644 --- a/drivers/net/wireless/bcm4329/dhd_common.c +++ b/drivers/net/wireless/bcm4329/dhd_common.c @@ -21,7 +21,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: dhd_common.c,v 1.5.6.8.2.6.6.69.4.20 2010/12/20 23:37:28 Exp $ + * $Id: dhd_common.c,v 1.5.6.8.2.6.6.69.4.25 2011-02-11 21:16:02 Exp $ */ #include #include @@ -39,9 +39,6 @@ #include -#define CONFIG_BCM4329_FW_PATH "/system/etc/firmware/fw_bcm4329.bin" -#define CONFIG_BCM4329_NVRAM_PATH "/system/etc/firmware/nvram_B23.txt" - #ifdef SET_RANDOM_MAC_SOFTAP #include #include @@ -1223,6 +1220,82 @@ dhd_arp_offload_enable(dhd_pub_t * dhd, int arp_enable) } #endif + +void dhd_arp_cleanup(dhd_pub_t *dhd) +{ +#ifdef ARP_OFFLOAD_SUPPORT + int ret = 0; + int iov_len = 0; + char iovbuf[128]; + + if (dhd == NULL) return; + + dhd_os_proto_block(dhd); + + iov_len = bcm_mkiovar("arp_hostip_clear", 0, 0, iovbuf, sizeof(iovbuf)); + if ((ret = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, iov_len)) < 0) + DHD_ERROR(("%s failed code %d\n", __FUNCTION__, ret)); + + iov_len = bcm_mkiovar("arp_table_clear", 0, 0, iovbuf, sizeof(iovbuf)); + if ((ret = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, iov_len)) < 0) + DHD_ERROR(("%s failed code %d\n", __FUNCTION__, ret)); + + dhd_os_proto_unblock(dhd); + +#endif /* ARP_OFFLOAD_SUPPORT */ +} + +void dhd_arp_offload_add_ip(dhd_pub_t *dhd, u32 ipaddr) +{ +#ifdef ARP_OFFLOAD_SUPPORT + int iov_len = 0; + char iovbuf[32]; + int retcode; + + dhd_os_proto_block(dhd); + + iov_len = bcm_mkiovar("arp_hostip", (char *)&ipaddr, 4, iovbuf, sizeof(iovbuf)); + retcode = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, iov_len); + + dhd_os_proto_unblock(dhd); + + if (retcode) + DHD_TRACE(("%s: ARP ip addr add failed, retcode = %d\n", + __FUNCTION__, retcode)); + else + DHD_TRACE(("%s: ARP ipaddr entry added\n", + __FUNCTION__)); +#endif /* ARP_OFFLOAD_SUPPORT */ +} + + +int dhd_arp_get_arp_hostip_table(dhd_pub_t *dhd, void *buf, int buflen) +{ +#ifdef ARP_OFFLOAD_SUPPORT + int retcode; + int iov_len = 0; + + if (!buf) + return -1; + + dhd_os_proto_block(dhd); + + iov_len = bcm_mkiovar("arp_hostip", 0, 0, buf, buflen); + retcode = dhdcdc_query_ioctl(dhd, 0, WLC_GET_VAR, buf, buflen); + + dhd_os_proto_unblock(dhd); + + if (retcode) { + DHD_TRACE(("%s: ioctl WLC_GET_VAR error %d\n", + __FUNCTION__, retcode)); + + return -1; + } +#endif /* ARP_OFFLOAD_SUPPORT */ + return 0; +} + + int dhd_preinit_ioctls(dhd_pub_t *dhd) { @@ -1289,15 +1362,11 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) } #endif /* SET_RANDOM_MAC_SOFTAP */ - /* Set Country code - * "US" ---> 11 channels, this is default setting. - * "EU" ---> 13 channels - * "JP" ---> 14 channels - */ - strcpy(dhd->country_code, "EU"); - if (dhd->country_code[0] != 0) { - if (dhdcdc_set_ioctl(dhd, 0, WLC_SET_COUNTRY, - dhd->country_code, sizeof(dhd->country_code)) < 0) { + /* Set Country code */ + if (dhd->dhd_cspec.ccode[0] != 0) { + bcm_mkiovar("country", (char *)&dhd->dhd_cspec, \ + sizeof(wl_country_t), iovbuf, sizeof(iovbuf)); + if ((ret = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf))) < 0) { DHD_ERROR(("%s: country code setting failed\n", __FUNCTION__)); } } @@ -1904,6 +1973,7 @@ int dhd_pno_clean(dhd_pub_t *dhd) int dhd_pno_enable(dhd_pub_t *dhd, int pfn_enabled) { char iovbuf[128]; + uint8 bssid[6]; int ret = -1; if ((!dhd) && ((pfn_enabled != 0) || (pfn_enabled != 1))) { @@ -1911,6 +1981,20 @@ int dhd_pno_enable(dhd_pub_t *dhd, int pfn_enabled) return ret; } + memset(iovbuf, 0, sizeof(iovbuf)); + + /* Check if disassoc to enable pno */ + if ((pfn_enabled) && \ + ((ret = dhdcdc_set_ioctl(dhd, 0, WLC_GET_BSSID, \ + (char *)&bssid, ETHER_ADDR_LEN)) == BCME_NOTASSOCIATED)) { + DHD_TRACE(("%s pno enable called in disassoc mode\n", __FUNCTION__)); + } + else if (pfn_enabled) { + DHD_ERROR(("%s pno enable called in assoc mode ret=%d\n", \ + __FUNCTION__, ret)); + return ret; + } + /* Enable/disable PNO */ if ((ret = bcm_mkiovar("pfn", (char *)&pfn_enabled, 4, iovbuf, sizeof(iovbuf))) > 0) { if ((ret = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf))) < 0) { @@ -1929,7 +2013,8 @@ int dhd_pno_enable(dhd_pub_t *dhd, int pfn_enabled) /* Function to execute combined scan */ int -dhd_pno_set(dhd_pub_t *dhd, wlc_ssid_t* ssids_local, int nssid, ushort scan_fr) +dhd_pno_set(dhd_pub_t *dhd, wlc_ssid_t* ssids_local, int nssid, ushort scan_fr, \ + int pno_repeat, int pno_freq_expo_max) { int err = -1; char iovbuf[128]; @@ -1974,12 +2059,23 @@ dhd_pno_set(dhd_pub_t *dhd, wlc_ssid_t* ssids_local, int nssid, ushort scan_fr) pfn_param.version = htod32(PFN_VERSION); pfn_param.flags = htod16((PFN_LIST_ORDER << SORT_CRITERIA_BIT)); + /* check and set extra pno params */ + if ((pno_repeat != 0) || (pno_freq_expo_max != 0)) { + pfn_param.flags |= htod16(ENABLE << ENABLE_ADAPTSCAN_BIT); + pfn_param.repeat_scan = htod32(pno_repeat); + pfn_param.max_freq_adjust = htod32(pno_freq_expo_max); + } + /* set up pno scan fr */ if (scan_fr != 0) pfn_param.scan_freq = htod32(scan_fr); - if (pfn_param.scan_freq > PNO_SCAN_MAX_FW) { - DHD_ERROR(("%s pno freq above %d sec\n", __FUNCTION__, PNO_SCAN_MAX_FW)); + if (pfn_param.scan_freq > PNO_SCAN_MAX_FW_SEC) { + DHD_ERROR(("%s pno freq above %d sec\n", __FUNCTION__, PNO_SCAN_MAX_FW_SEC)); + return err; + } + if (pfn_param.scan_freq < PNO_SCAN_MIN_FW_SEC) { + DHD_ERROR(("%s pno freq less %d sec\n", __FUNCTION__, PNO_SCAN_MIN_FW_SEC)); return err; } @@ -1991,8 +2087,6 @@ dhd_pno_set(dhd_pub_t *dhd, wlc_ssid_t* ssids_local, int nssid, ushort scan_fr) pfn_element.bss_type = htod32(DOT11_BSSTYPE_INFRASTRUCTURE); pfn_element.auth = (DOT11_OPEN_SYSTEM); - pfn_element.wpa_auth = htod32(WPA_AUTH_PFN_ANY); - pfn_element.wsec = htod32(0); pfn_element.infra = htod32(1); memcpy((char *)pfn_element.ssid.SSID, ssids_local[i].SSID, ssids_local[i].SSID_len); @@ -2008,8 +2102,9 @@ dhd_pno_set(dhd_pub_t *dhd, wlc_ssid_t* ssids_local, int nssid, ushort scan_fr) return err; } else - DHD_ERROR(("%s set OK with PNO time=%d\n", __FUNCTION__, \ - pfn_param.scan_freq)); + DHD_ERROR(("%s set OK with PNO time=%d repeat=%d max_adjust=%d\n", \ + __FUNCTION__, pfn_param.scan_freq, \ + pfn_param.repeat_scan, pfn_param.max_freq_adjust)); } else DHD_ERROR(("%s failed err=%d\n", __FUNCTION__, err)); } diff --git a/drivers/net/wireless/bcm4329/dhd_custom_gpio.c b/drivers/net/wireless/bcm4329/dhd_custom_gpio.c index 8c6ec470b8bd..4d32863e2982 100644 --- a/drivers/net/wireless/bcm4329/dhd_custom_gpio.c +++ b/drivers/net/wireless/bcm4329/dhd_custom_gpio.c @@ -20,7 +20,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * -* $Id: dhd_custom_gpio.c,v 1.1.4.8.4.1 2010/09/02 23:13:16 Exp $ +* $Id: dhd_custom_gpio.c,v 1.1.4.8.4.4 2011/01/20 20:23:09 Exp $ */ @@ -47,6 +47,7 @@ int wifi_set_carddetect(int on); int wifi_set_power(int on, unsigned long msec); int wifi_get_irq_number(unsigned long *irq_flags_ptr); int wifi_get_mac_addr(unsigned char *buf); +void *wifi_get_country_code(char *ccode); #endif #if defined(OOB_INTR_ONLY) @@ -177,3 +178,95 @@ dhd_custom_get_mac_address(unsigned char *buf) return ret; } #endif /* GET_CUSTOM_MAC_ENABLE */ + +/* Customized Locale table : OPTIONAL feature */ +const struct cntry_locales_custom translate_custom_table[] = { +/* Table should be filled out based on custom platform regulatory requirement */ +#ifdef EXAMPLE_TABLE + {"", "XY", 4}, /* universal */ + {"US", "US", 69}, /* input ISO "US" to : US regrev 69 */ + {"CA", "US", 69}, /* input ISO "CA" to : US regrev 69 */ + {"EU", "EU", 5}, /* European union countries */ + {"AT", "EU", 5}, + {"BE", "EU", 5}, + {"BG", "EU", 5}, + {"CY", "EU", 5}, + {"CZ", "EU", 5}, + {"DK", "EU", 5}, + {"EE", "EU", 5}, + {"FI", "EU", 5}, + {"FR", "EU", 5}, + {"DE", "EU", 5}, + {"GR", "EU", 5}, + {"HU", "EU", 5}, + {"IE", "EU", 5}, + {"IT", "EU", 5}, + {"LV", "EU", 5}, + {"LI", "EU", 5}, + {"LT", "EU", 5}, + {"LU", "EU", 5}, + {"MT", "EU", 5}, + {"NL", "EU", 5}, + {"PL", "EU", 5}, + {"PT", "EU", 5}, + {"RO", "EU", 5}, + {"SK", "EU", 5}, + {"SI", "EU", 5}, + {"ES", "EU", 5}, + {"SE", "EU", 5}, + {"GB", "EU", 5}, /* input ISO "GB" to : EU regrev 05 */ + {"IL", "IL", 0}, + {"CH", "CH", 0}, + {"TR", "TR", 0}, + {"NO", "NO", 0}, + {"KR", "XY", 3}, + {"AU", "XY", 3}, + {"CN", "XY", 3}, /* input ISO "CN" to : XY regrev 03 */ + {"TW", "XY", 3}, + {"AR", "XY", 3}, + {"MX", "XY", 3} +#endif /* EXAMPLE_TABLE */ +}; + + +/* Customized Locale convertor +* input : ISO 3166-1 country abbreviation +* output: customized cspec +*/ +void get_customized_country_code(char *country_iso_code, wl_country_t *cspec) +{ +#ifdef CUSTOMER_HW2 + struct cntry_locales_custom *cloc_ptr; + + if (!cspec) + return; + + cloc_ptr = wifi_get_country_code(country_iso_code); + if (cloc_ptr) { + strlcpy(cspec->ccode, cloc_ptr->custom_locale, WLC_CNTRY_BUF_SZ); + cspec->rev = cloc_ptr->custom_locale_rev; + } + return; +#else + int size, i; + + size = ARRAYSIZE(translate_custom_table); + + if (cspec == 0) + return; + + if (size == 0) + return; + + for (i = 0; i < size; i++) { + if (strcmp(country_iso_code, translate_custom_table[i].iso_abbrev) == 0) { + memcpy(cspec->ccode, translate_custom_table[i].custom_locale, WLC_CNTRY_BUF_SZ); + cspec->rev = translate_custom_table[i].custom_locale_rev; + return; + } + } + memcpy(cspec->ccode, translate_custom_table[0].custom_locale, WLC_CNTRY_BUF_SZ); + cspec->rev = translate_custom_table[0].custom_locale_rev; + return; +#endif +} diff --git a/drivers/net/wireless/bcm4329/dhd_linux.c b/drivers/net/wireless/bcm4329/dhd_linux.c index d9af222f7c29..3b21e41dd54b 100644 --- a/drivers/net/wireless/bcm4329/dhd_linux.c +++ b/drivers/net/wireless/bcm4329/dhd_linux.c @@ -22,7 +22,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: dhd_linux.c,v 1.65.4.9.2.12.2.104.4.35 2010/11/17 03:13:21 Exp $ + * $Id: dhd_linux.c,v 1.65.4.9.2.12.2.104.4.40 2011/02/03 19:55:18 Exp $ */ #ifdef CONFIG_WIFI_CONTROL_FUNC @@ -43,11 +43,11 @@ #include #include #include +#include #include #include -#include #include #include #include @@ -63,16 +63,12 @@ #include #endif #if defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC) -//#include -#include +#include struct semaphore wifi_control_sem; struct dhd_bus *g_bus; -extern void bcm4329_power_save_exit(void); -extern void bcm4329_power_save_init(void); - static struct wifi_platform_data *wifi_control_data = NULL; static struct resource *wifi_irqres = NULL; @@ -131,6 +127,17 @@ int wifi_get_mac_addr(unsigned char *buf) return -EOPNOTSUPP; } +void *wifi_get_country_code(char *ccode) +{ + DHD_TRACE(("%s\n", __FUNCTION__)); + if (!ccode) + return NULL; + if (wifi_control_data && wifi_control_data->get_country_code) { + return wifi_control_data->get_country_code(ccode); + } + return NULL; +} + static int wifi_probe(struct platform_device *pdev) { struct wifi_platform_data *wifi_ctrl = @@ -161,14 +168,21 @@ static int wifi_remove(struct platform_device *pdev) up(&wifi_control_sem); return 0; } + static int wifi_suspend(struct platform_device *pdev, pm_message_t state) { DHD_TRACE(("##> %s\n", __FUNCTION__)); +#if defined(OOB_INTR_ONLY) + bcmsdh_oob_intr_set(0); +#endif /* (OOB_INTR_ONLY) */ return 0; } static int wifi_resume(struct platform_device *pdev) { DHD_TRACE(("##> %s\n", __FUNCTION__)); +#if defined(OOB_INTR_ONLY) + bcmsdh_oob_intr_set(1); +#endif /* (OOB_INTR_ONLY) */ return 0; } @@ -195,6 +209,12 @@ void wifi_del_dev(void) } #endif /* defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC) */ +static int dhd_device_event(struct notifier_block *this, unsigned long event, + void *ptr); + +static struct notifier_block dhd_notifier = { + .notifier_call = dhd_device_event +}; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) #include @@ -380,7 +400,7 @@ uint dhd_roam = 1; uint dhd_radio_up = 1; /* Network inteface name */ -char iface_name[IFNAMSIZ] = "wlan0"; +char iface_name[IFNAMSIZ]; module_param_string(iface_name, iface_name, IFNAMSIZ, 0); #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) @@ -768,13 +788,13 @@ _dhd_set_multicast_list(dhd_info_t *dhd, int ifidx) ASSERT(dhd && dhd->iflist[ifidx]); dev = dhd->iflist[ifidx]->net; - netif_addr_lock_bh(dev); + NETIF_ADDR_LOCK(dev); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35) cnt = netdev_mc_count(dev); #else cnt = dev->mc_count; #endif - netif_addr_unlock_bh(dev); + NETIF_ADDR_UNLOCK(dev); /* Determine initial value of allmulti flag */ allmulti = (dev->flags & IFF_ALLMULTI) ? TRUE : FALSE; @@ -794,7 +814,7 @@ _dhd_set_multicast_list(dhd_info_t *dhd, int ifidx) memcpy(bufp, &cnt, sizeof(cnt)); bufp += sizeof(cnt); - netif_addr_lock_bh(dev); + NETIF_ADDR_LOCK(dev); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35) netdev_for_each_mc_addr(ha, dev) { if (!cnt) @@ -804,12 +824,12 @@ _dhd_set_multicast_list(dhd_info_t *dhd, int ifidx) cnt--; } #else - for (mclist = dev->mc_list;(mclist && (cnt > 0)); cnt--, mclist = mclist->next) { + for (mclist = dev->mc_list; (mclist && (cnt > 0)); cnt--, mclist = mclist->next) { memcpy(bufp, (void *)mclist->dmi_addr, ETHER_ADDR_LEN); bufp += ETHER_ADDR_LEN; } #endif - netif_addr_unlock_bh(dev); + NETIF_ADDR_UNLOCK(dev); memset(&ioc, 0, sizeof(ioc)); ioc.cmd = WLC_SET_VAR; @@ -1907,8 +1927,6 @@ dhd_open(struct net_device *net) wl_control_wl_start(net); ifidx = dhd_net2idx(dhd, net); - if (ifidx == DHD_BAD_IF) - return -1; DHD_TRACE(("%s: ifidx %d\n", __FUNCTION__, ifidx)); if ((dhd->iflist[ifidx]) && (dhd->iflist[ifidx]->state == WLC_E_IF_DEL)) { @@ -2011,6 +2029,7 @@ dhd_del_if(dhd_info_t *dhd, int ifidx) up(&dhd->sysioc_sem); } + dhd_pub_t * dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen) { @@ -2167,6 +2186,8 @@ dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen) register_early_suspend(&dhd->early_suspend); #endif + register_inetaddr_notifier(&dhd_notifier); + return &dhd->pub; fail: @@ -2192,12 +2213,15 @@ dhd_bus_start(dhd_pub_t *dhdp) DHD_TRACE(("%s: \n", __FUNCTION__)); + dhd_os_sdlock(dhdp); + /* try to download image and nvram to the dongle */ if (dhd->pub.busstate == DHD_BUS_DOWN) { if (!(dhd_bus_download_firmware(dhd->pub.bus, dhd->pub.osh, fw_path, nv_path))) { DHD_ERROR(("%s: dhdsdio_probe_download failed. firmware = %s nvram = %s\n", __FUNCTION__, fw_path, nv_path)); + dhd_os_sdunlock(dhdp); return -1; } } @@ -2207,8 +2231,9 @@ dhd_bus_start(dhd_pub_t *dhdp) dhd_os_wd_timer(&dhd->pub, dhd_watchdog_ms); /* Bring up the bus */ - if ((ret = dhd_bus_init(&dhd->pub, TRUE)) != 0) { + if ((ret = dhd_bus_init(&dhd->pub, FALSE)) != 0) { DHD_ERROR(("%s, dhd_bus_init failed %d\n", __FUNCTION__, ret)); + dhd_os_sdunlock(dhdp); return ret; } #if defined(OOB_INTR_ONLY) @@ -2217,6 +2242,7 @@ dhd_bus_start(dhd_pub_t *dhdp) dhd->wd_timer_valid = FALSE; del_timer_sync(&dhd->timer); DHD_ERROR(("%s Host failed to resgister for OOB\n", __FUNCTION__)); + dhd_os_sdunlock(dhdp); return -ENODEV; } @@ -2229,9 +2255,12 @@ dhd_bus_start(dhd_pub_t *dhdp) dhd->wd_timer_valid = FALSE; del_timer_sync(&dhd->timer); DHD_ERROR(("%s failed bus is not ready\n", __FUNCTION__)); + dhd_os_sdunlock(dhdp); return -ENODEV; } + dhd_os_sdunlock(dhdp); + #ifdef EMBEDDED_PLATFORM bcm_mkiovar("event_msgs", dhdp->eventmask, WL_EVENTING_MASK_LEN, iovbuf, sizeof(iovbuf)); dhdcdc_query_ioctl(dhdp, 0, WLC_GET_VAR, iovbuf, sizeof(iovbuf)); @@ -2319,6 +2348,48 @@ static struct net_device_ops dhd_ops_virt = { }; #endif +static int dhd_device_event(struct notifier_block *this, unsigned long event, + void *ptr) +{ + struct in_ifaddr *ifa = (struct in_ifaddr *)ptr; + dhd_info_t *dhd; + dhd_pub_t *dhd_pub; + + if (!ifa) + return NOTIFY_DONE; + + dhd = *(dhd_info_t **)netdev_priv(ifa->ifa_dev->dev); + dhd_pub = &dhd->pub; + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 31)) + if (ifa->ifa_dev->dev->netdev_ops == &dhd_ops_pri) { +#else + if (ifa->ifa_dev->dev->open == &dhd_open) { +#endif + switch (event) { + case NETDEV_UP: + DHD_TRACE(("%s: [%s] Up IP: 0x%x\n", + __FUNCTION__, ifa->ifa_label, ifa->ifa_address)); + + dhd_arp_cleanup(dhd_pub); + break; + + case NETDEV_DOWN: + DHD_TRACE(("%s: [%s] Down IP: 0x%x\n", + __FUNCTION__, ifa->ifa_label, ifa->ifa_address)); + + dhd_arp_cleanup(dhd_pub); + break; + + default: + DHD_TRACE(("%s: [%s] Event: %lu\n", + __FUNCTION__, ifa->ifa_label, event)); + break; + } + } + return NOTIFY_DONE; +} + int dhd_net_attach(dhd_pub_t *dhdp, int ifidx) { @@ -2392,6 +2463,7 @@ dhd_net_attach(dhd_pub_t *dhdp, int ifidx) dhd->pub.mac.octet[0], dhd->pub.mac.octet[1], dhd->pub.mac.octet[2], dhd->pub.mac.octet[3], dhd->pub.mac.octet[4], dhd->pub.mac.octet[5]); + #if defined(CONFIG_WIRELESS_EXT) #if defined(CONFIG_FIRST_SCAN) #ifdef SOFTAP @@ -2457,6 +2529,8 @@ dhd_detach(dhd_pub_t *dhdp) dhd_if_t *ifp; int i; + unregister_inetaddr_notifier(&dhd_notifier); + #if defined(CONFIG_HAS_EARLYSUSPEND) if (dhd->early_suspend.suspend) unregister_early_suspend(&dhd->early_suspend); @@ -2521,8 +2595,8 @@ dhd_detach(dhd_pub_t *dhdp) } } -void -rockchip_wifi_exit_module(void) +static void __exit +dhd_module_cleanup(void) { DHD_TRACE(("%s: Enter\n", __FUNCTION__)); @@ -2532,17 +2606,15 @@ rockchip_wifi_exit_module(void) #endif /* Call customer gpio to turn off power with WL_REG_ON signal */ dhd_customer_gpio_wlan_ctrl(WLAN_POWER_OFF); - bcm4329_power_save_exit(); } -int -rockchip_wifi_init_module(void) +static int __init +dhd_module_init(void) { int error; DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - printk("BCM4329 Wi-Fi driver (Powered by Rockchip,Ver %s) init.\n", BCM4329_DRV_VERSION); /* Sanity check on the module parameters */ do { /* Both watchdog and DPC as tasklets are ok */ @@ -2601,8 +2673,6 @@ rockchip_wifi_init_module(void) goto fail_2; } #endif - bcm4329_power_save_init(); - return error; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) fail_2: @@ -2620,23 +2690,8 @@ fail_0: return error; } -//module_init(dhd_module_init); -//module_exit(dhd_module_cleanup); -int mv88w8686_if_sdio_init_module(void) -{ - return rockchip_wifi_init_module(); -} - -void mv88w8686_if_sdio_exit_module(void) -{ - rockchip_wifi_exit_module(); -} - -EXPORT_SYMBOL(rockchip_wifi_init_module); -EXPORT_SYMBOL(rockchip_wifi_exit_module); -EXPORT_SYMBOL(mv88w8686_if_sdio_init_module); -EXPORT_SYMBOL(mv88w8686_if_sdio_exit_module); - +module_init(dhd_module_init); +module_exit(dhd_module_cleanup); /* * OS specific functions required to implement DHD driver in OS independent way @@ -3063,11 +3118,12 @@ dhd_dev_pno_enable(struct net_device *dev, int pfn_enabled) /* Linux wrapper to call common dhd_pno_set */ int -dhd_dev_pno_set(struct net_device *dev, wlc_ssid_t* ssids_local, int nssid, ushort scan_fr) +dhd_dev_pno_set(struct net_device *dev, wlc_ssid_t* ssids_local, int nssid, + ushort scan_fr, int pno_repeat, int pno_freq_expo_max) { dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - return (dhd_pno_set(&dhd->pub, ssids_local, nssid, scan_fr)); + return (dhd_pno_set(&dhd->pub, ssids_local, nssid, scan_fr, pno_repeat, pno_freq_expo_max)); } /* Linux wrapper to get pno status */ @@ -3095,20 +3151,20 @@ int net_os_send_hang_message(struct net_device *dev) return ret; } -void dhd_bus_country_set(struct net_device *dev, char *country_code) +void dhd_bus_country_set(struct net_device *dev, wl_country_t *cspec) { dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); if (dhd && dhd->pub.up) - strncpy(dhd->pub.country_code, country_code, WLC_CNTRY_BUF_SZ); + memcpy(&dhd->pub.dhd_cspec, cspec, sizeof(wl_country_t)); } char *dhd_bus_country_get(struct net_device *dev) { dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - if (dhd && (dhd->pub.country_code[0] != 0)) - return dhd->pub.country_code; + if (dhd && (dhd->pub.dhd_cspec.ccode[0] != 0)) + return dhd->pub.dhd_cspec.ccode; return NULL; } diff --git a/drivers/net/wireless/bcm4329/dhd_sdio.c b/drivers/net/wireless/bcm4329/dhd_sdio.c index 78dff1c489b8..1380dd389cf6 100644 --- a/drivers/net/wireless/bcm4329/dhd_sdio.c +++ b/drivers/net/wireless/bcm4329/dhd_sdio.c @@ -428,7 +428,6 @@ static void dhdsdio_sdtest_set(dhd_bus_t *bus, bool start); #ifdef DHD_DEBUG_TRAP static int dhdsdio_checkdied(dhd_bus_t *bus, uint8 *data, uint size); -static int dhdsdio_mem_dump(dhd_bus_t *bus); #endif /* DHD_DEBUG_TRAP */ static int dhdsdio_download_state(dhd_bus_t *bus, bool enter); @@ -1845,11 +1844,6 @@ dhdsdio_checkdied(dhd_bus_t *bus, uint8 *data, uint size) DHD_ERROR(("%s: %s\n", __FUNCTION__, strbuf.origbuf)); } - if (sdpcm_shared.flags & SDPCM_SHARED_TRAP) { - /* Mem dump to a file on device */ - dhdsdio_mem_dump(bus); - } - done: if (mbuffer) MFREE(bus->dhd->osh, mbuffer, msize); @@ -1858,60 +1852,6 @@ done: return bcmerror; } - -static int -dhdsdio_mem_dump(dhd_bus_t *bus) -{ - int ret = 0; - int size; /* Full mem size */ - int start = 0; /* Start address */ - int read_size = 0; /* Read size of each iteration */ - uint8 *buf = NULL, *databuf = NULL; - - /* Get full mem size */ - size = bus->ramsize; - buf = MALLOC(bus->dhd->osh, size); - if (!buf) { - printf("%s: Out of memory (%d bytes)\n", __FUNCTION__, size); - return -1; - } - - /* Read mem content */ - printf("Dump dongle memory"); - databuf = buf; - while (size) - { - read_size = MIN(MEMBLOCK, size); - if ((ret = dhdsdio_membytes(bus, FALSE, start, databuf, read_size))) - { - printf("%s: Error membytes %d\n", __FUNCTION__, ret); - if (buf) { - MFREE(bus->dhd->osh, buf, size); - } - return -1; - } - printf("."); - - /* Decrement size and increment start address */ - size -= read_size; - start += read_size; - databuf += read_size; - } - printf("Done\n"); - -#ifdef DHD_DEBUG - /* free buf before return !!! */ - if (write_to_file(bus->dhd, buf, bus->ramsize)) - { - printf("%s: Error writing to files\n", __FUNCTION__); - return -1; - } - /* buf free handled in write_to_file, not here */ -#else - MFREE(bus->dhd->osh, buf, size); -#endif - return 0; -} #endif /* DHD_DEBUG_TRAP */ #ifdef DHD_DEBUG diff --git a/drivers/net/wireless/bcm4329/include/epivers.h b/drivers/net/wireless/bcm4329/include/epivers.h index 23ee514a7b6b..cd66a9501cb6 100644 --- a/drivers/net/wireless/bcm4329/include/epivers.h +++ b/drivers/net/wireless/bcm4329/include/epivers.h @@ -33,16 +33,16 @@ #define EPI_RC_NUMBER 248 -#define EPI_INCREMENTAL_NUMBER 18 +#define EPI_INCREMENTAL_NUMBER 23 #define EPI_BUILD_NUMBER 0 -#define EPI_VERSION 4, 218, 248, 18 +#define EPI_VERSION 4, 218, 248, 23 -#define EPI_VERSION_NUM 0x04daf812 +#define EPI_VERSION_NUM 0x04daf817 -#define EPI_VERSION_STR "4.218.248.18" -#define EPI_ROUTER_VERSION_STR "4.219.248.18" +#define EPI_VERSION_STR "4.218.248.23" +#define EPI_ROUTER_VERSION_STR "4.219.248.23" #endif diff --git a/drivers/net/wireless/bcm4329/include/wlioctl.h b/drivers/net/wireless/bcm4329/include/wlioctl.h index cd7725a70db4..00c61f10782f 100644 --- a/drivers/net/wireless/bcm4329/include/wlioctl.h +++ b/drivers/net/wireless/bcm4329/include/wlioctl.h @@ -24,7 +24,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: wlioctl.h,v 1.601.4.15.2.14.2.62.4.1 2010/11/17 03:09:28 Exp $ + * $Id: wlioctl.h,v 1.601.4.15.2.14.2.62.4.3 2011/02/09 23:31:02 Exp $ */ @@ -254,6 +254,11 @@ typedef struct wl_join_params { #define WLC_CNTRY_BUF_SZ 4 +typedef struct wl_country { + char country_abbrev[WLC_CNTRY_BUF_SZ]; + int32 rev; + char ccode[WLC_CNTRY_BUF_SZ]; +} wl_country_t; typedef enum sup_auth_status { @@ -857,7 +862,7 @@ typedef struct wl_ioctl { #define PM_MAX 1 #define PM_FAST 2 -#define LISTEN_INTERVAL 20 +#define LISTEN_INTERVAL 10 #define INTERFERE_NONE 0 #define NON_WLAN 1 @@ -1309,12 +1314,16 @@ enum { #define ENABLE_BKGRD_SCAN_BIT 2 #define IMMEDIATE_SCAN_BIT 3 #define AUTO_CONNECT_BIT 4 +#define ENABLE_BD_SCAN_BIT 5 +#define ENABLE_ADAPTSCAN_BIT 6 #define SORT_CRITERIA_MASK 0x01 #define AUTO_NET_SWITCH_MASK 0x02 #define ENABLE_BKGRD_SCAN_MASK 0x04 #define IMMEDIATE_SCAN_MASK 0x08 #define AUTO_CONNECT_MASK 0x10 +#define ENABLE_BD_SCAN_MASK 0x20 +#define ENABLE_ADAPTSCAN_MASK 0x40 #define PFN_VERSION 1 @@ -1327,6 +1336,8 @@ typedef struct wl_pfn_param { int32 lost_network_timeout; int16 flags; int16 rssi_margin; + int32 repeat_scan; + int32 max_freq_adjust; } wl_pfn_param_t; typedef struct wl_pfn { @@ -1336,14 +1347,12 @@ typedef struct wl_pfn { int32 auth; uint32 wpa_auth; int32 wsec; -#ifdef WLPFN_AUTO_CONNECT - union { - wl_wsec_key_t sec_key; - wsec_pmk_t wpa_sec_key; - } pfn_security; -#endif } wl_pfn_t; +#define PNO_SCAN_MAX_FW 508*1000 +#define PNO_SCAN_MAX_FW_SEC PNO_SCAN_MAX_FW/1000 +#define PNO_SCAN_MIN_FW_SEC 10 + #define TOE_TX_CSUM_OL 0x00000001 #define TOE_RX_CSUM_OL 0x00000002 diff --git a/drivers/net/wireless/bcm4329/linux_osl.c b/drivers/net/wireless/bcm4329/linux_osl.c index d00bd1ca291b..3a026eed516e 100644 --- a/drivers/net/wireless/bcm4329/linux_osl.c +++ b/drivers/net/wireless/bcm4329/linux_osl.c @@ -246,8 +246,10 @@ void* osl_pktget(osl_t *osh, uint len) { struct sk_buff *skb; + gfp_t flags; - if ((skb = dev_alloc_skb(len))) { + flags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL; + if ((skb = __dev_alloc_skb(len, flags))) { skb_put(skb, len); skb->priority = 0; diff --git a/drivers/net/wireless/bcm4329/wl_iw.c b/drivers/net/wireless/bcm4329/wl_iw.c index 146dffd52976..230619d901ec 100644 --- a/drivers/net/wireless/bcm4329/wl_iw.c +++ b/drivers/net/wireless/bcm4329/wl_iw.c @@ -21,7 +21,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: wl_iw.c,v 1.51.4.9.2.6.4.142.4.69 2010/12/21 03:00:08 Exp $ + * $Id: wl_iw.c,v 1.51.4.9.2.6.4.142.4.78 2011/02/11 21:27:52 Exp $ */ @@ -54,10 +54,11 @@ typedef const struct si_pub si_t; #define WL_INFORM(x) #define WL_WSEC(x) #define WL_SCAN(x) +#define WL_PNO(x) #define WL_TRACE_COEX(x) #include -#include + #ifndef IW_ENCODE_ALG_SM4 @@ -115,10 +116,6 @@ static int g_onoff = G_WLAN_SET_ON; wl_iw_extra_params_t g_wl_iw_params; static struct mutex wl_cache_lock; -#ifdef CONFIG_US_NON_DFS_CHANNELS_ONLY -static bool use_non_dfs_channels = true; -#endif - extern bool wl_iw_conn_status_str(uint32 event_type, uint32 status, uint32 reason, char* stringBuf, uint buflen); #include @@ -161,12 +158,13 @@ extern int dhd_wait_pend8021x(struct net_device *dev); #endif static void *g_scan = NULL; -static volatile uint g_scan_specified_ssid; -static wlc_ssid_t g_specific_ssid; +static volatile uint g_scan_specified_ssid; +static wlc_ssid_t g_specific_ssid; static wlc_ssid_t g_ssid; -static wl_iw_ss_cache_ctrl_t g_ss_cache_ctrl; +bool btcoex_is_sco_active(struct net_device *dev); +static wl_iw_ss_cache_ctrl_t g_ss_cache_ctrl; #if defined(CONFIG_FIRST_SCAN) static volatile uint g_first_broadcast_scan; static volatile uint g_first_counter_scans; @@ -594,6 +592,36 @@ wl_iw_set_passive_scan( return error; } + +static int +wl_iw_set_txpower( + struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra +) +{ + int error = 0; + char *p = extra; + int txpower = -1; + + txpower = bcm_atoi(extra + strlen(TXPOWER_SET_CMD) + 1); + if ((txpower >= 0) && (txpower <= 127)) { + txpower |= WL_TXPWR_OVERRIDE; + txpower = htod32(txpower); + + error = dev_wlc_intvar_set(dev, "qtxpower", txpower); + p += snprintf(p, MAX_WX_STRING, "OK"); + WL_TRACE(("%s: set TXpower 0x%X is OK\n", __FUNCTION__, txpower)); + } else { + WL_ERROR(("%s: set tx power failed\n", __FUNCTION__)); + p += snprintf(p, MAX_WX_STRING, "FAIL"); + } + + wrqu->data.length = p - extra + 1; + return error; +} + static int wl_iw_get_macaddr( struct net_device *dev, @@ -619,31 +647,6 @@ wl_iw_get_macaddr( return error; } -static int -wl_iw_set_country_code(struct net_device *dev, char *ccode) -{ - char country_code[WLC_CNTRY_BUF_SZ]; - int ret = -1; - - WL_TRACE(("%s\n", __FUNCTION__)); - if (!ccode) - ccode = dhd_bus_country_get(dev); - strncpy(country_code, ccode, sizeof(country_code)); - if (ccode && (country_code[0] != 0)) { -#ifdef CONFIG_US_NON_DFS_CHANNELS_ONLY - if (use_non_dfs_channels && !strncmp(country_code, "US", 2)) - strncpy(country_code, "Q2", WLC_CNTRY_BUF_SZ); - if (!use_non_dfs_channels && !strncmp(country_code, "Q2", 2)) - strncpy(country_code, "US", WLC_CNTRY_BUF_SZ); -#endif - ret = dev_wlc_ioctl(dev, WLC_SET_COUNTRY, &country_code, sizeof(country_code)); - if (ret >= 0) { - WL_TRACE(("%s: set country %s OK\n", __FUNCTION__, country_code)); - dhd_bus_country_set(dev, &country_code[0]); - } - } - return ret; -} static int wl_iw_set_country( @@ -658,25 +661,39 @@ wl_iw_set_country( char *p = extra; int country_offset; int country_code_size; + wl_country_t cspec = {{0}, 0, {0}}; + char smbuf[WLC_IOCTL_SMLEN]; - WL_TRACE(("%s\n", __FUNCTION__)); + cspec.rev = -1; memset(country_code, 0, sizeof(country_code)); + memset(smbuf, 0, sizeof(smbuf)); country_offset = strcspn(extra, " "); country_code_size = strlen(extra) - country_offset; if (country_offset != 0) { - strncpy(country_code, extra + country_offset + 1, + strncpy(country_code, extra + country_offset +1, MIN(country_code_size, sizeof(country_code))); - error = wl_iw_set_country_code(dev, country_code); - if (error >= 0) { + + + memcpy(cspec.country_abbrev, country_code, WLC_CNTRY_BUF_SZ); + memcpy(cspec.ccode, country_code, WLC_CNTRY_BUF_SZ); + + get_customized_country_code((char *)&cspec.country_abbrev, &cspec); + + if ((error = dev_iw_iovar_setbuf(dev, "country", &cspec, \ + sizeof(cspec), smbuf, sizeof(smbuf))) >= 0) { p += snprintf(p, MAX_WX_STRING, "OK"); - WL_TRACE(("%s: set country %s OK\n", __FUNCTION__, country_code)); + WL_ERROR(("%s: set country for %s as %s rev %d is OK\n", \ + __FUNCTION__, country_code, cspec.ccode, cspec.rev)); + dhd_bus_country_set(dev, &cspec); goto exit; } } - WL_ERROR(("%s: set country %s failed code %d\n", __FUNCTION__, country_code, error)); + WL_ERROR(("%s: set country for %s as %s rev %d failed\n", \ + __FUNCTION__, country_code, cspec.ccode, cspec.rev)); + p += snprintf(p, MAX_WX_STRING, "FAIL"); exit: @@ -684,33 +701,6 @@ exit: return error; } -static int -wl_iw_get_country( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - char *ccode; - int current_channels; - - WL_TRACE(("%s\n", __FUNCTION__)); - - ccode = dhd_bus_country_get(dev); - if(ccode){ - if(0 == strcmp(ccode, "Q2")) - current_channels = 11; - else if(0 == strcmp(ccode, "EU")) - current_channels = 13; - else if(0 == strcmp(ccode, "JP")) - current_channels = 14; - } - sprintf(extra, "Scan-Channels = %d", current_channels); - printk("Get Channels return %d,(country code = %s)\n",current_channels, ccode); - return 0; -} - #ifdef CUSTOMER_HW2 static int wl_iw_set_power_mode( @@ -765,26 +755,40 @@ wl_iw_set_power_mode( #endif -static bool btcoex_is_sco_active(struct net_device *dev) +bool btcoex_is_sco_active(struct net_device *dev) { int ioc_res = 0; bool res = false; - int temp = 0; + int sco_id_cnt = 0; + int param27; + int i; + + for (i = 0; i < 12; i++) { - ioc_res = dev_wlc_intvar_get_reg(dev, "btc_params", 4, &temp); + ioc_res = dev_wlc_intvar_get_reg(dev, "btc_params", 27, ¶m27); - if (ioc_res == 0) { - WL_TRACE_COEX(("%s: read btc_params[4] = %x\n", __FUNCTION__, temp)); + WL_TRACE_COEX(("%s, sample[%d], btc params: 27:%x\n", + __FUNCTION__, i, param27)); + + if (ioc_res < 0) { + WL_ERROR(("%s ioc read btc params error\n", __FUNCTION__)); + break; + } + + if ((param27 & 0x6) == 2) { + sco_id_cnt++; + } - if ((temp > 0xea0) && (temp < 0xed8)) { - WL_TRACE_COEX(("%s: BT SCO/eSCO is ACTIVE\n", __FUNCTION__)); + if (sco_id_cnt > 2) { + WL_TRACE_COEX(("%s, sco/esco detected, pkt id_cnt:%d samples:%d\n", + __FUNCTION__, sco_id_cnt, i)); res = true; - } else { - WL_TRACE_COEX(("%s: BT SCO/eSCO is NOT detected\n", __FUNCTION__)); + break; } - } else { - WL_ERROR(("%s ioc read btc params error\n", __FUNCTION__)); + + msleep(5); } + return res; } @@ -1070,21 +1074,6 @@ wl_iw_set_suspend( return ret; } -#ifdef CONFIG_US_NON_DFS_CHANNELS_ONLY -static int -wl_iw_set_dfs_channels( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - use_non_dfs_channels = *(extra + strlen(SETDFSCHANNELS_CMD) + 1) - '0'; - use_non_dfs_channels = (use_non_dfs_channels != 0) ? false : true; - wl_iw_set_country_code(dev, NULL); - return 0; -} -#endif int wl_format_ssid(char* ssid_buf, uint8* ssid, int ssid_len) @@ -1370,9 +1359,10 @@ wl_iw_set_pno_set( int nssid = 0; cmd_tlv_t *cmd_tlv_temp; char *str_ptr; - char *str_ptr_end; int tlv_size_left; int pno_time; + int pno_repeat; + int pno_freq_expo_max; #ifdef PNO_SET_DEBUG int i; @@ -1386,6 +1376,10 @@ wl_iw_set_pno_set( 'G', 'O', 'O', 'G', 'T', '1','E', + 'R', + '2', + 'M', + '2', 0x00 }; #endif @@ -1429,6 +1423,7 @@ wl_iw_set_pno_set( cmd_tlv_temp = (cmd_tlv_t *)str_ptr; memset(ssids_local, 0, sizeof(ssids_local)); + pno_repeat = pno_freq_expo_max = 0; if ((cmd_tlv_temp->prefix == PNO_TLV_PREFIX) && \ (cmd_tlv_temp->version == PNO_TLV_VERSION) && \ @@ -1449,9 +1444,28 @@ wl_iw_set_pno_set( goto exit_proc; } str_ptr++; - pno_time = simple_strtoul(str_ptr, &str_ptr_end, 16); - WL_ERROR((" got %d bytes left pno_time %d or %#x\n", \ - tlv_size_left, pno_time, pno_time)); + pno_time = simple_strtoul(str_ptr, &str_ptr, 16); + WL_PNO(("%s: pno_time=%d\n", __FUNCTION__, pno_time)); + + if (str_ptr[0] != 0) { + if ((str_ptr[0] != PNO_TLV_FREQ_REPEAT)) { + WL_ERROR(("%s pno repeat : corrupted field\n", \ + __FUNCTION__)); + goto exit_proc; + } + str_ptr++; + pno_repeat = simple_strtoul(str_ptr, &str_ptr, 16); + WL_PNO(("%s :got pno_repeat=%d\n", __FUNCTION__, pno_repeat)); + if (str_ptr[0] != PNO_TLV_FREQ_EXPO_MAX) { + WL_ERROR(("%s FREQ_EXPO_MAX corrupted field size\n", \ + __FUNCTION__)); + goto exit_proc; + } + str_ptr++; + pno_freq_expo_max = simple_strtoul(str_ptr, &str_ptr, 16); + WL_PNO(("%s: pno_freq_expo_max=%d\n", \ + __FUNCTION__, pno_freq_expo_max)); + } } } else { @@ -1459,7 +1473,7 @@ wl_iw_set_pno_set( goto exit_proc; } - res = dhd_dev_pno_set(dev, ssids_local, nssid, pno_time); + res = dhd_dev_pno_set(dev, ssids_local, nssid, pno_time, pno_repeat, pno_freq_expo_max); exit_proc: net_os_wake_unlock(dev); @@ -1746,6 +1760,79 @@ int hstr_2_buf(const char *txt, u8 *buf, int len) return 0; } +#if defined(SOFTAP) && defined(SOFTAP_TLV_CFG) + +static int wl_iw_softap_cfg_tlv( + struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra +) +{ + int res = -1; + char *str_ptr; + int tlv_size_left; + + +#define SOFTAP_TLV_DEBUG 1 +#ifdef SOFTAP_TLV_DEBUG +char softap_cmd_example[] = { + + 'S', 'O', 'F', 'T', 'A', 'P', 'S', 'E', 'T', ' ', + + SOFTAP_TLV_PREFIX, SOFTAP_TLV_VERSION, + SOFTAP_TLV_SUBVERSION, SOFTAP_TLV_RESERVED, + + TLV_TYPE_SSID, 9, 'B', 'R', 'C', 'M', ',', 'G', 'O', 'O', 'G', + + TLV_TYPE_SECUR, 4, 'O', 'P', 'E', 'N', + + TLV_TYPE_KEY, 4, 0x31, 0x32, 0x33, 0x34, + + TLV_TYPE_CHANNEL, 4, 0x06, 0x00, 0x00, 0x00 +}; +#endif + + +#ifdef SOFTAP_TLV_DEBUG + { + int i; + if (!(extra = kmalloc(sizeof(softap_cmd_example) +10, GFP_KERNEL))) + return -ENOMEM; + memcpy(extra, softap_cmd_example, sizeof(softap_cmd_example)); + wrqu->data.length = sizeof(softap_cmd_example); + print_buf(extra, wrqu->data.length, 16); + for (i = 0; i < wrqu->data.length; i++) + printf("%c ", extra[i]); + printf("\n"); + } +#endif + + WL_ERROR(("\n### %s: info->cmd:%x, info->flags:%x, u.data=0x%p, u.len=%d\n", + __FUNCTION__, info->cmd, info->flags, + wrqu->data.pointer, wrqu->data.length)); + + if (g_onoff == G_WLAN_SET_OFF) { + WL_TRACE(("%s: driver is not up yet after START\n", __FUNCTION__)); + return -1; + } + + if (wrqu->data.length < (strlen(SOFTAP_SET_CMD) + sizeof(cmd_tlv_t))) { + WL_ERROR(("%s argument=%d less %d\n", __FUNCTION__, + wrqu->data.length, strlen(SOFTAP_SET_CMD) + sizeof(cmd_tlv_t))); + return -1; + } + + str_ptr = extra + strlen(SOFTAP_SET_CMD)+1; + tlv_size_left = wrqu->data.length - (strlen(SOFTAP_SET_CMD)+1); + + memset(&my_ap, 0, sizeof(my_ap)); + + return res; +} +#endif + + #ifdef SOFTAP int init_ap_profile_from_string(char *param_str, struct ap_profile *ap_cfg) { @@ -3713,6 +3800,7 @@ wl_iw_handle_scanresults_ies(char **event_p, char *end, wpa_snprintf_hex(buf + 10, 2+1, &(ie->len), 1); wpa_snprintf_hex(buf + 12, 2*ie->len+1, ie->data, ie->len); event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, buf); + kfree(buf); #endif break; } @@ -5754,7 +5842,7 @@ wl_iw_combined_scan_set(struct net_device *dev, wlc_ssid_t* ssids_local, int nss WL_SCAN(("scan_type=%d\n", iscan->iscan_ex_params_p->params.scan_type)); WL_SCAN(("\n###################\n")); } -#endif +#endif if (params_size > WLC_IOCTL_MEDLEN) { WL_ERROR(("Set ISCAN for %s due to params_size=%d \n", \ @@ -5794,6 +5882,11 @@ static int iwpriv_set_cscan(struct net_device *dev, struct iw_request_info *info return -1; } +#ifdef PNO_SET_DEBUG + wl_iw_set_pno_set(dev, info, wrqu, extra); + return 0; +#endif + if (wrqu->data.length != 0) { char *str_ptr; @@ -6321,16 +6414,8 @@ static int set_ap_cfg(struct net_device *dev, struct ap_profile *ap) } if (strlen(ap->country_code)) { - int error = 0; - if ((error = dev_wlc_ioctl(dev, WLC_SET_COUNTRY, - ap->country_code, sizeof(ap->country_code))) >= 0) { - WL_SOFTAP(("%s: set country %s OK\n", - __FUNCTION__, ap->country_code)); - dhd_bus_country_set(dev, &ap->country_code[0]); - } else { - WL_ERROR(("%s: ERROR:%d setting country %s\n", - __FUNCTION__, error, ap->country_code)); - } + WL_ERROR(("%s: Igonored: Country MUST be specified \ + COUNTRY command with \n", __FUNCTION__)); } else { WL_SOFTAP(("%s: Country code is not specified," " will use Radio's default\n", @@ -7072,30 +7157,6 @@ int wl_iw_process_private_ascii_cmd( } #endif -#define BCM4329_WAKELOCK_NAME "bcm4329_wifi_wakelock" - -static struct wake_lock bcm4329_suspend_lock; - -int bcm4329_wakelock_init = 0; - -void bcm4329_power_save_init(void) -{ - wake_lock_init(&bcm4329_suspend_lock, WAKE_LOCK_SUSPEND, BCM4329_WAKELOCK_NAME); - wake_lock(&bcm4329_suspend_lock); - - bcm4329_wakelock_init = 2; -} - -void bcm4329_power_save_exit(void) -{ - bcm4329_wakelock_init = 0; - msleep(100); - - if (bcm4329_wakelock_init == 2) - wake_unlock(&bcm4329_suspend_lock); - wake_lock_destroy(&bcm4329_suspend_lock); -} - static int wl_iw_set_priv( struct net_device *dev, struct iw_request_info *info, @@ -7121,11 +7182,6 @@ static int wl_iw_set_priv( if (dwrq->length && extra) { if (strnicmp(extra, "START", strlen("START")) == 0) { - if (bcm4329_wakelock_init == 1) - { - wake_lock(&bcm4329_suspend_lock); - bcm4329_wakelock_init = 2; - } wl_iw_control_wl_on(dev, info); WL_TRACE(("%s, Received regular START command\n", __FUNCTION__)); } @@ -7157,16 +7213,8 @@ static int wl_iw_set_priv( ret = wl_iw_get_macaddr(dev, info, (union iwreq_data *)dwrq, extra); else if (strnicmp(extra, "COUNTRY", strlen("COUNTRY")) == 0) ret = wl_iw_set_country(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, "SCAN-CHANNELS", strlen("SCAN-CHANNELS")) == 0) - ret = wl_iw_get_country(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, "STOP", strlen("STOP")) == 0){ + else if (strnicmp(extra, "STOP", strlen("STOP")) == 0) ret = wl_iw_control_wl_off(dev, info); - if (bcm4329_wakelock_init == 2) - { - wake_unlock(&bcm4329_suspend_lock); - bcm4329_wakelock_init = 1; - } - } else if (strnicmp(extra, BAND_GET_CMD, strlen(BAND_GET_CMD)) == 0) ret = wl_iw_get_band(dev, info, (union iwreq_data *)dwrq, extra); else if (strnicmp(extra, BAND_SET_CMD, strlen(BAND_SET_CMD)) == 0) @@ -7177,10 +7225,8 @@ static int wl_iw_set_priv( ret = wl_iw_set_dtim_skip(dev, info, (union iwreq_data *)dwrq, extra); else if (strnicmp(extra, SETSUSPEND_CMD, strlen(SETSUSPEND_CMD)) == 0) ret = wl_iw_set_suspend(dev, info, (union iwreq_data *)dwrq, extra); -#ifdef CONFIG_US_NON_DFS_CHANNELS_ONLY - else if (strnicmp(extra, SETDFSCHANNELS_CMD, strlen(SETDFSCHANNELS_CMD)) == 0) - ret = wl_iw_set_dfs_channels(dev, info, (union iwreq_data *)dwrq, extra); -#endif + else if (strnicmp(extra, TXPOWER_SET_CMD, strlen(TXPOWER_SET_CMD)) == 0) + ret = wl_iw_set_txpower(dev, info, (union iwreq_data *)dwrq, extra); #if defined(PNO_SUPPORT) else if (strnicmp(extra, PNOSSIDCLR_SET_CMD, strlen(PNOSSIDCLR_SET_CMD)) == 0) ret = wl_iw_set_pno_reset(dev, info, (union iwreq_data *)dwrq, extra); @@ -7196,8 +7242,10 @@ static int wl_iw_set_priv( #ifdef CUSTOMER_HW2 else if (strnicmp(extra, "POWERMODE", strlen("POWERMODE")) == 0) ret = wl_iw_set_power_mode(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, "BTCOEXMODE", strlen("BTCOEXMODE")) == 0) + else if (strnicmp(extra, "BTCOEXMODE", strlen("BTCOEXMODE")) == 0) { + WL_TRACE_COEX(("%s:got Framwrork cmd: 'BTCOEXMODE'\n", __FUNCTION__)); ret = wl_iw_set_btcoex_dhcp(dev, info, (union iwreq_data *)dwrq, extra); + } #else else if (strnicmp(extra, "POWERMODE", strlen("POWERMODE")) == 0) ret = wl_iw_set_btcoex_dhcp(dev, info, (union iwreq_data *)dwrq, extra); @@ -7205,6 +7253,11 @@ static int wl_iw_set_priv( else if (strnicmp(extra, "GETPOWER", strlen("GETPOWER")) == 0) ret = wl_iw_get_power_mode(dev, info, (union iwreq_data *)dwrq, extra); #ifdef SOFTAP +#ifdef SOFTAP_TLV_CFG + else if (strnicmp(extra, SOFTAP_SET_CMD, strlen(SOFTAP_SET_CMD)) == 0) { + wl_iw_softap_cfg_tlv(dev, info, (union iwreq_data *)dwrq, extra); + } +#endif else if (strnicmp(extra, "ASCII_CMD", strlen("ASCII_CMD")) == 0) { wl_iw_process_private_ascii_cmd(dev, info, (union iwreq_data *)dwrq, extra); } else if (strnicmp(extra, "AP_MAC_LIST_SET", strlen("AP_MAC_LIST_SET")) == 0) { @@ -7725,9 +7778,10 @@ wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void* data) uint32 datalen = ntoh32(e->datalen); uint32 status = ntoh32(e->status); uint32 toto; +#if defined(ROAM_NOT_USED) static uint32 roam_no_success = 0; static bool roam_no_success_send = FALSE; - +#endif memset(&wrqu, 0, sizeof(wrqu)); memset(extra, 0, sizeof(extra)); @@ -7802,6 +7856,7 @@ wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void* data) wrqu.addr.sa_family = ARPHRD_ETHER; cmd = SIOCGIWAP; } +#if defined(ROAM_NOT_USED) else if (status == WLC_E_STATUS_NO_NETWORKS) { roam_no_success++; if ((roam_no_success == 5) && (roam_no_success_send == FALSE)) { @@ -7816,6 +7871,7 @@ wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void* data) goto wl_iw_event_end; } } +#endif break; case WLC_E_DEAUTH_IND: case WLC_E_DISASSOC_IND: @@ -7871,8 +7927,10 @@ wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void* data) wl_iw_send_priv_event(priv_dev, "AP_UP"); } else { WL_TRACE(("STA_LINK_UP\n")); +#if defined(ROAM_NOT_USED) roam_no_success_send = FALSE; roam_no_success = 0; +#endif } #endif WL_TRACE(("Link UP\n")); diff --git a/drivers/net/wireless/bcm4329/wl_iw.h b/drivers/net/wireless/bcm4329/wl_iw.h index 928291fe589a..d94bdb432723 100644 --- a/drivers/net/wireless/bcm4329/wl_iw.h +++ b/drivers/net/wireless/bcm4329/wl_iw.h @@ -21,7 +21,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: wl_iw.h,v 1.5.34.1.6.36.4.15 2010/11/17 03:13:51 Exp $ + * $Id: wl_iw.h,v 1.5.34.1.6.36.4.18 2011/02/10 19:33:12 Exp $ */ @@ -52,7 +52,7 @@ #define PNOSETUP_SET_CMD "PNOSETUP " #define PNOENABLE_SET_CMD "PNOFORCE" #define PNODEBUG_SET_CMD "PNODEBUG" -#define SETDFSCHANNELS_CMD "SETDFSCHANNELS" +#define TXPOWER_SET_CMD "TXPOWER" #define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] #define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x" @@ -62,6 +62,12 @@ typedef struct wl_iw_extra_params { int target_channel; } wl_iw_extra_params_t; +struct cntry_locales_custom { + char iso_abbrev[WLC_CNTRY_BUF_SZ]; + char custom_locale[WLC_CNTRY_BUF_SZ]; + int32 custom_locale_rev; +}; + #define WL_IW_RSSI_MINVAL -200 #define WL_IW_RSSI_NO_SIGNAL -91 #define WL_IW_RSSI_VERY_LOW -80 @@ -133,13 +139,13 @@ typedef struct wl_iw_ss_cache { } wl_iw_ss_cache_t; typedef struct wl_iw_ss_cache_ctrl { - wl_iw_ss_cache_t *m_cache_head; - int m_link_down; - int m_timer_expired; - char m_active_bssid[ETHER_ADDR_LEN]; - uint m_prev_scan_mode; - uint m_cons_br_scan_cnt; - struct timer_list *m_timer; + wl_iw_ss_cache_t *m_cache_head; + int m_link_down; + int m_timer_expired; + char m_active_bssid[ETHER_ADDR_LEN]; + uint m_prev_scan_mode; + uint m_cons_br_scan_cnt; + struct timer_list *m_timer; } wl_iw_ss_cache_ctrl_t; typedef enum broadcast_first_scan { @@ -165,7 +171,7 @@ struct ap_profile { }; -#define MACLIST_MODE_DISABLED 0 +#define MACLIST_MODE_DISABLED 0 #define MACLIST_MODE_DENY 1 #define MACLIST_MODE_ALLOW 2 struct mflist { @@ -199,7 +205,7 @@ extern int net_os_set_suspend_disable(struct net_device *dev, int val); extern int net_os_set_suspend(struct net_device *dev, int val); extern int net_os_set_dtim_skip(struct net_device *dev, int val); extern int net_os_set_packet_filter(struct net_device *dev, int val); -extern void dhd_bus_country_set(struct net_device *dev, char *country_code); +extern void get_customized_country_code(char *country_iso_code, wl_country_t *cspec); extern char *dhd_bus_country_get(struct net_device *dev); extern int dhd_get_dtim_skip(dhd_pub_t *dhd); @@ -221,13 +227,15 @@ extern int dhd_get_dtim_skip(dhd_pub_t *dhd); extern int dhd_pno_enable(dhd_pub_t *dhd, int pfn_enabled); extern int dhd_pno_clean(dhd_pub_t *dhd); -extern int dhd_pno_set(dhd_pub_t *dhd, wlc_ssid_t* ssids_local, int nssid, ushort scan_fr); +extern int dhd_pno_set(dhd_pub_t *dhd, wlc_ssid_t* ssids_local, int nssid, \ + ushort scan_fr, int pno_repeat, int pno_freq_expo_max); extern int dhd_pno_get_status(dhd_pub_t *dhd); extern int dhd_dev_pno_reset(struct net_device *dev); extern int dhd_dev_pno_set(struct net_device *dev, wlc_ssid_t* ssids_local, \ - int nssid, ushort scan_fr); + int nssid, ushort scan_fr, int pno_repeat, int pno_freq_expo_max); extern int dhd_dev_pno_enable(struct net_device *dev, int pfn_enabled); extern int dhd_dev_get_pno_status(struct net_device *dev); +extern void dhd_bus_country_set(struct net_device *dev, wl_country_t *cspec); #define PNO_TLV_PREFIX 'S' #define PNO_TLV_VERSION '1' @@ -235,8 +243,9 @@ extern int dhd_dev_get_pno_status(struct net_device *dev); #define PNO_TLV_RESERVED '0' #define PNO_TLV_TYPE_SSID_IE 'S' #define PNO_TLV_TYPE_TIME 'T' -#define PNO_EVENT_UP "PNO_EVENT" -#define PNO_SCAN_MAX_FW 508 +#define PNO_TLV_FREQ_REPEAT 'R' +#define PNO_TLV_FREQ_EXPO_MAX 'M' +#define PNO_EVENT_UP "PNO_EVENT" typedef struct cmd_tlv { char prefix; @@ -245,6 +254,19 @@ typedef struct cmd_tlv { char reserved; } cmd_tlv_t; +#ifdef SOFTAP_TLV_CFG +#define SOFTAP_SET_CMD "SOFTAPSET " +#define SOFTAP_TLV_PREFIX 'A' +#define SOFTAP_TLV_VERSION '1' +#define SOFTAP_TLV_SUBVERSION '0' +#define SOFTAP_TLV_RESERVED '0' + +#define TLV_TYPE_SSID 'S' +#define TLV_TYPE_SECUR 'E' +#define TLV_TYPE_KEY 'K' +#define TLV_TYPE_CHANNEL 'C' +#endif + #if defined(CSCAN) typedef struct cscan_tlv { @@ -279,6 +301,6 @@ extern int wl_iw_parse_ssid_list(char** list_str, wlc_ssid_t* ssid, int idx, int extern int wl_iw_parse_channel_list(char** list_str, uint16* channel_list, int channel_num); -#endif +#endif -#endif +#endif diff --git a/drivers/power/wm831x_power.c b/drivers/power/wm831x_power.c index 82beeca9d49e..fbcc36dae470 100755 --- a/drivers/power/wm831x_power.c +++ b/drivers/power/wm831x_power.c @@ -18,110 +18,14 @@ #include #include #include -#include - -#define WM831X_DEBUG -#undef WM831X_DEBUG - -#ifdef WM831X_DEBUG -#define WM_BATT_DBG(x...) printk(KERN_INFO x) -#else -#define WM_BATT_DBG(x...) do {} while (0) -#endif - -#define WM831X_CHG_SYSLO_SHIFT 4 -#define WM831X_CHG_SYSOK_SHIFT 0 -#define WM831X_CHG_SYSLO_MASK ~(0x7 << 4) -#define WM831X_CHG_SYSOK_MASK ~(0x7 << 0) - -#define batt_num 52 - -static int batt_step_table[batt_num] = { - 3400,3420,3440,3475,3505,3525, - 3540,3557,3570,3580,3610, - 3630,3640,3652,3662,3672, - 3680,3687,3693,3699,3705, - 3710,3714,3718,3722,3726, - 3730,3734,3738,3742,3746, - 3750,3756,3764,3774,3786, - 3800,3808,3817,3827,3838, - 3950,3964,3982,4002,4026, - 4050,4074,4098,4123,4149,4178 -}; - -static int batt_disp_table[batt_num] = { - 0,1,2,3,5,7, - 9,11,13,15,17, - 19,21,23,25,27, - 29,31,33,35,37, - 39,41,43,45,47, - 49,51,53,55,57, - 59,61,63,65,67, - 69,71,73,75,77, - 79,81,83,85,87, - 89,91,93,95,97,100 -}; - -static int batt_chg_step_table[batt_num] = { - 3530,3565,3600,3635,3655,3680,//+160 - 3700,3717,3734,3745,3755,//+150 - 3770,3778,3786,3795,3803,//+140 - 3810,3814,3818,3822,3825,//+130 - 3830,3832,3834,3836,3837,//+120 - 3840,3842,3844,3846,3847,//+110 - 3850,3857,3864,3871,3876,//+100 - 3890,3897,3904,3911,3918,//+90 - 4030,4047,4064,4080,4096,//+80 - 4120,4132,4144,4156,4170,4180//+70 -}; - - - -#define TIMER_MS_COUNTS 1000 -struct wm_batt_priv_data { - int online; - int status; - int health; - int level; - int temp; - int voltage; -}; struct wm831x_power { struct wm831x *wm831x; struct power_supply wall; struct power_supply usb; struct power_supply battery; - struct work_struct batt_work; - struct timer_list timer; - struct wm_batt_priv_data batt_info; - struct wake_lock syslo_wake; - int interval; }; -struct wm831x_power *g_wm831x_power; - -static int power_test_sysfs_init(void); -extern void wm831x_batt_vol_level(struct wm831x_power *power, int batt_vol, int *level); -static DEFINE_MUTEX(charging_mutex); - -int wm831x_read_on_pin_status(void) -{ - int ret; - - if(!g_wm831x_power) - { - printk("err:%s:g_wm831x_power address is 0\n",__FUNCTION__); - return -1; - } - - ret = wm831x_reg_read(g_wm831x_power->wm831x, WM831X_ON_PIN_CONTROL); - if (ret < 0) - return ret; - - return !(ret & WM831X_ON_PIN_STS) ? 1 : 0; -} - static int wm831x_power_check_online(struct wm831x *wm831x, int supply, union power_supply_propval *val) { @@ -139,54 +43,18 @@ static int wm831x_power_check_online(struct wm831x *wm831x, int supply, return 0; } -int wm831x_read_chg_status(void) -{ - int ret, usb_chg = 0, wall_chg = 0; - - if(!g_wm831x_power) - { - printk("err:%s:g_wm831x_power address is 0\n",__FUNCTION__); - return -1; - } - - ret = wm831x_reg_read(g_wm831x_power->wm831x, WM831X_SYSTEM_STATUS); - if (ret < 0) - return ret; - - if (ret & WM831X_PWR_USB) - usb_chg = 1; - if (ret & WM831X_PWR_WALL) - wall_chg = 1; - - return ((usb_chg | wall_chg) ? 1 : 0); -} - static int wm831x_power_read_voltage(struct wm831x *wm831x, enum wm831x_auxadc src, union power_supply_propval *val) { int ret; + ret = wm831x_auxadc_read_uv(wm831x, src); if (ret >= 0) - val->intval = ret / 1000; - - return ret ; -} + val->intval = ret; -int wm831x_read_batt_voltage(void) -{ - int ret = 0; - - if(!g_wm831x_power) - { - printk("err:%s:g_wm831x_power address is 0\n",__FUNCTION__); - return -1; - } - - ret = wm831x_auxadc_read_uv(g_wm831x_power->wm831x, WM831X_AUX_BATT); - return ret / 1000; + return ret; } -//EXPORT_SYMBOL_GPL(wm831x_get_batt_voltage); /********************************************************************* * WALL Power @@ -322,34 +190,13 @@ static struct chg_map chg_times[] = { { 510, 15 << WM831X_CHG_TIME_SHIFT }, }; -static struct chg_map chg_syslos[] = { - { 2800, 0 << WM831X_CHG_SYSLO_SHIFT}, - { 2900, 1 << WM831X_CHG_SYSLO_SHIFT}, - { 3000, 2 << WM831X_CHG_SYSLO_SHIFT}, - { 3100, 3 << WM831X_CHG_SYSLO_SHIFT}, - { 3200, 4 << WM831X_CHG_SYSLO_SHIFT}, - { 3300, 5 << WM831X_CHG_SYSLO_SHIFT}, - { 3400, 6 << WM831X_CHG_SYSLO_SHIFT}, - { 3500, 7 << WM831X_CHG_SYSLO_SHIFT}, -}; - -static struct chg_map chg_sysoks[] = { - { 2800, 0 << WM831X_CHG_SYSOK_SHIFT}, - { 2900, 1 << WM831X_CHG_SYSOK_SHIFT}, - { 3000, 2 << WM831X_CHG_SYSOK_SHIFT}, - { 3100, 3 << WM831X_CHG_SYSOK_SHIFT}, - { 3200, 4 << WM831X_CHG_SYSOK_SHIFT}, - { 3300, 5 << WM831X_CHG_SYSOK_SHIFT}, - { 3400, 6 << WM831X_CHG_SYSOK_SHIFT}, - { 3500, 7 << WM831X_CHG_SYSOK_SHIFT}, -}; - static void wm831x_battey_apply_config(struct wm831x *wm831x, struct chg_map *map, int count, int val, int *reg, const char *name, const char *units) { int i; + for (i = 0; i < count; i++) if (val == map[i].val) break; @@ -366,7 +213,7 @@ static void wm831x_config_battery(struct wm831x *wm831x) { struct wm831x_pdata *wm831x_pdata = wm831x->dev->platform_data; struct wm831x_battery_pdata *pdata; - int ret, reg1, reg2, reg3; + int ret, reg1, reg2; if (!wm831x_pdata || !wm831x_pdata->battery) { dev_warn(wm831x->dev, @@ -378,7 +225,6 @@ static void wm831x_config_battery(struct wm831x *wm831x) reg1 = 0; reg2 = 0; - reg3 = 0; if (!pdata->enable) { dev_info(wm831x->dev, "Battery charger disabled\n"); @@ -412,14 +258,6 @@ static void wm831x_config_battery(struct wm831x *wm831x) pdata->timeout, ®2, "charger timeout", "min"); - wm831x_battey_apply_config(wm831x, chg_syslos, ARRAY_SIZE(chg_syslos), - pdata->syslo, ®3, - "syslo voltage", "mV"); - - wm831x_battey_apply_config(wm831x, chg_sysoks, ARRAY_SIZE(chg_sysoks), - pdata->sysok, ®3, - "sysok voltage", "mV"); - ret = wm831x_reg_unlock(wm831x); if (ret != 0) { dev_err(wm831x->dev, "Failed to unlock registers: %d\n", ret); @@ -429,12 +267,13 @@ static void wm831x_config_battery(struct wm831x *wm831x) ret = wm831x_set_bits(wm831x, WM831X_CHARGER_CONTROL_1, WM831X_CHG_ENA_MASK | WM831X_CHG_FAST_MASK | + WM831X_CHG_ITERM_MASK | WM831X_CHG_ITERM_MASK, reg1); - if (ret != 0) { + if (ret != 0) dev_err(wm831x->dev, "Failed to set charger control 1: %d\n", ret); - } + ret = wm831x_set_bits(wm831x, WM831X_CHARGER_CONTROL_2, WM831X_CHG_OFF_MSK | WM831X_CHG_TIME_MASK | @@ -442,18 +281,9 @@ static void wm831x_config_battery(struct wm831x *wm831x) WM831X_CHG_TRKL_ILIM_MASK | WM831X_CHG_VSEL_MASK, reg2); - if (ret != 0) { + if (ret != 0) dev_err(wm831x->dev, "Failed to set charger control 2: %d\n", ret); - } - - ret = wm831x_set_bits(wm831x, WM831X_SYSVDD_CONTROL, - WM831X_CHG_SYSLO_MASK | - WM831X_CHG_SYSOK_MASK, - reg3); - if (ret < 0) { - dev_err(wm831x->dev, "Failed to set sysvdd control reg: %d\n",ret); - } wm831x_reg_lock(wm831x); } @@ -475,7 +305,6 @@ static int wm831x_bat_check_status(struct wm831x *wm831x, int *status) if (ret < 0) return ret; - switch (ret & WM831X_CHG_STATE_MASK) { case WM831X_CHG_STATE_OFF: *status = POWER_SUPPLY_STATUS_NOT_CHARGING; @@ -492,53 +321,10 @@ static int wm831x_bat_check_status(struct wm831x *wm831x, int *status) return 0; } -int wm831x_read_bat_charging_status(void) -{ - int ret, status; - - if(!g_wm831x_power) - { - printk("err:%s:g_wm831x_power address is 0\n",__FUNCTION__); - return -1; - } - - ret = wm831x_bat_check_status(g_wm831x_power->wm831x, &status); - if (ret < 0) - return ret; - if (status == POWER_SUPPLY_STATUS_CHARGING) - return 1; - return 0; -} static int wm831x_bat_check_type(struct wm831x *wm831x, int *type) { int ret; -#ifdef WM831X_DEBUG_0 - ret = wm831x_reg_read(wm831x, WM831X_POWER_STATE); - if (ret < 0) - return ret; - WM_BATT_DBG("%s: wm831x power status %#x\n", __FUNCTION__, ret); - - ret = wm831x_reg_read(wm831x, WM831X_SYSTEM_STATUS); - if (ret < 0) - return ret; - WM_BATT_DBG("%s: wm831x system status %#x\n", __FUNCTION__, ret); - - ret = wm831x_reg_read(wm831x, WM831X_CHARGER_CONTROL_1); - if (ret < 0) - return ret; - WM_BATT_DBG("%s: wm831x charger control1 %#x\n", __FUNCTION__, ret); - - ret = wm831x_reg_read(wm831x, WM831X_CHARGER_CONTROL_2); - if (ret < 0) - return ret; - WM_BATT_DBG("%s: wm831x charger control2 %#x\n", __FUNCTION__, ret); - - ret = wm831x_reg_read(wm831x, WM831X_CHARGER_STATUS); - if (ret < 0) - return ret; - WM_BATT_DBG("%s: wm831x charger status %#x\n\n", __FUNCTION__, ret); -#endif ret = wm831x_reg_read(wm831x, WM831X_CHARGER_STATUS); if (ret < 0) @@ -606,41 +392,25 @@ static int wm831x_bat_get_prop(struct power_supply *psy, { struct wm831x_power *wm831x_power = dev_get_drvdata(psy->dev->parent); struct wm831x *wm831x = wm831x_power->wm831x; - int ret = 0; + int ret = 0; switch (psp) { case POWER_SUPPLY_PROP_STATUS: ret = wm831x_bat_check_status(wm831x, &val->intval); - //val->intval = wm831x_power->batt_info.status; break; - case POWER_SUPPLY_PROP_PRESENT: case POWER_SUPPLY_PROP_ONLINE: - //ret = wm831x_power_check_online(wm831x, WM831X_PWR_SRC_BATT, val); - val->intval = wm831x_power->batt_info.online; + ret = wm831x_power_check_online(wm831x, WM831X_PWR_SRC_BATT, + val); break; case POWER_SUPPLY_PROP_VOLTAGE_NOW: - //ret = wm831x_power_read_voltage(wm831x, WM831X_AUX_BATT, val); - val->intval = wm831x_power->batt_info.voltage*1000;//uV + ret = wm831x_power_read_voltage(wm831x, WM831X_AUX_BATT, val); break; case POWER_SUPPLY_PROP_HEALTH: - //ret = wm831x_bat_check_health(wm831x, &val->intval); - val->intval = wm831x_power->batt_info.health; + ret = wm831x_bat_check_health(wm831x, &val->intval); break; case POWER_SUPPLY_PROP_CHARGE_TYPE: ret = wm831x_bat_check_type(wm831x, &val->intval); break; - case POWER_SUPPLY_PROP_CAPACITY: - //ret = wm831x_power_read_voltage(wm831x, WM831X_AUX_BATT, val); - //wm831x_batt_vol_level(wm831x_power, val->intval, &level); - //val->intval = level; - val->intval = wm831x_power->batt_info.level; - break; - case POWER_SUPPLY_PROP_TEMP: - val->intval = 0; - break; - case POWER_SUPPLY_PROP_TECHNOLOGY: - val->intval = POWER_SUPPLY_TECHNOLOGY_LION; - break; default: ret = -EINVAL; break; @@ -651,16 +421,12 @@ static int wm831x_bat_get_prop(struct power_supply *psy, static enum power_supply_property wm831x_bat_props[] = { POWER_SUPPLY_PROP_STATUS, - POWER_SUPPLY_PROP_HEALTH, - POWER_SUPPLY_PROP_PRESENT, + POWER_SUPPLY_PROP_ONLINE, POWER_SUPPLY_PROP_VOLTAGE_NOW, - POWER_SUPPLY_PROP_CAPACITY, /* in percents! */ - POWER_SUPPLY_PROP_TECHNOLOGY, - POWER_SUPPLY_PROP_TEMP, + POWER_SUPPLY_PROP_HEALTH, POWER_SUPPLY_PROP_CHARGE_TYPE, }; -#ifdef CONFIG_WM831X_WITH_BATTERY static const char *wm831x_bat_irqs[] = { "BATT HOT", "BATT COLD", @@ -676,18 +442,16 @@ static irqreturn_t wm831x_bat_irq(int irq, void *data) { struct wm831x_power *wm831x_power = data; struct wm831x *wm831x = wm831x_power->wm831x; - int irq0; - - irq0 = wm831x->irq_base + WM831X_IRQ_CHG_BATT_HOT + 1; - dev_crit(wm831x->dev, "battery changed: i=%d\n", irq-irq0); - + + dev_dbg(wm831x->dev, "Battery status changed: %d\n", irq); + /* The battery charger is autonomous so we don't need to do * anything except kick user space */ power_supply_changed(&wm831x_power->battery); return IRQ_HANDLED; } -#endif + /********************************************************************* * Initialisation @@ -700,8 +464,8 @@ static irqreturn_t wm831x_syslo_irq(int irq, void *data) /* Not much we can actually *do* but tell people for * posterity, we're probably about to run out of power. */ - dev_crit(wm831x->dev, "SYSVDD under voltage and wake lock 60s\n"); - wake_lock_timeout(&wm831x_power->syslo_wake,60*HZ);//wait for android closing system + dev_crit(wm831x->dev, "SYSVDD under voltage\n"); + return IRQ_HANDLED; } @@ -711,299 +475,15 @@ static irqreturn_t wm831x_pwr_src_irq(int irq, void *data) struct wm831x *wm831x = wm831x_power->wm831x; dev_dbg(wm831x->dev, "Power source changed\n"); - WM_BATT_DBG("%s:Power source changed\n", __FUNCTION__); + /* Just notify for everything - little harm in overnotifying. */ power_supply_changed(&wm831x_power->battery); power_supply_changed(&wm831x_power->usb); power_supply_changed(&wm831x_power->wall); - return IRQ_HANDLED; } -static void wm831x_batt_timer_handler(unsigned long data) -{ - struct wm831x_power *wm831x_power = (struct wm831x_power*)data; - schedule_work(&wm831x_power->batt_work); - mod_timer(&wm831x_power->timer, jiffies + msecs_to_jiffies(wm831x_power->interval)); -} - -void wm831x_batt_vol_level(struct wm831x_power *wm831x_power, int batt_vol, int *level) -{ - int i, ret, status; - static int chg_plus = 1000; - static int chg_minus = 1000; - static int chg_curr = 0; - static int chg_num = 60; - static int disp_plus = 1000; - static int disp_minus = 1000; - static int disp_curr = 0; - static int disp_num = 50; - - - *level = wm831x_power->batt_info.level; - ret = wm831x_bat_check_status(wm831x_power->wm831x, &status); - if (ret < 0) { - printk("%s: check bat status failer...err = %d\n", __FUNCTION__, ret); - return; - } - - if (status == POWER_SUPPLY_STATUS_NOT_CHARGING - && batt_vol >= batt_step_table[batt_num-1]) { - *level = 100; - return; - } - - if (status == POWER_SUPPLY_STATUS_CHARGING) - { - disp_plus = 0; - disp_minus = 0; - disp_curr = 0; - - for(i = 0; i < batt_num; i++){ - if((batt_chg_step_table[i] <= batt_vol) && - (batt_chg_step_table[i+1] > batt_vol)) - break; - } - *level = batt_disp_table[i]; - - if (batt_vol <= batt_chg_step_table[0]) - *level = 0; - if (batt_vol >= batt_chg_step_table[batt_num - 1]) - *level = 100; - - // ³õʼ״̬ - if ((chg_plus == 1000) && (chg_minus == 1000)) - { - *level = *level; - chg_plus = 0; - chg_minus = 0; - chg_curr = 0; - } - else - { - - if (*level >= (wm831x_power->batt_info.level+1)) - { - chg_minus = 0; - chg_curr = 0; - - if (++chg_plus > chg_num) - { - *level = wm831x_power->batt_info.level + 1; - chg_plus = 0; - - if(*level < 85) - chg_num = 60; - else - chg_num = 20; - - } - else - { - *level = wm831x_power->batt_info.level; - } - } - - else if (*level >= wm831x_power->batt_info.level) - { - chg_plus = 0; - chg_minus = 0; - - if (++chg_curr > chg_num) - { - *level = *level; - chg_curr = 0; - } - else - { - *level = wm831x_power->batt_info.level; - } - } - else if (*level < (wm831x_power->batt_info.level-1)) - { - chg_plus = 0; - chg_curr = 0; - - if (++chg_minus > (chg_num<<1)) - { - *level = wm831x_power->batt_info.level - 1; - chg_minus = 0; - - if(*level < 85) - chg_num = 60; - else - chg_num = 20; - - } - else - { - *level = wm831x_power->batt_info.level; - } - } - else - { - chg_plus = 0; - chg_minus = 0; - chg_curr = 0; - *level = wm831x_power->batt_info.level; - } - } - - - if (*level >= 100) - *level = 100; - if (*level < 0) - *level = 0; - } - else - { - chg_plus = 0; - chg_minus = 0; - chg_curr = 0; - - for(i = 0; i < batt_num; i++){ - if(batt_vol >= batt_step_table[i] && - batt_vol < batt_step_table[i+1]) - break; - } - *level = batt_disp_table[i]; - - if (batt_vol <= batt_step_table[0]) - *level = 0; - if (batt_vol >= batt_step_table[batt_num - 1]) - *level = 100; - - // ³õʼ״̬ - if ((disp_plus == 1000) && (disp_minus == 1000)) - { - *level = *level; - disp_plus = 0; - disp_minus = 0; - disp_curr = 0; - } - else - { - - if (*level <= (wm831x_power->batt_info.level-1)) - { - disp_plus = 0; - disp_curr = 0; - - if (++disp_minus > disp_num) - { - *level = wm831x_power->batt_info.level - 1; - disp_minus = 0; - - if((*level < 17) || (*level > 85)) - disp_num = 10; - else - disp_num = 50; - - } - else - { - *level = wm831x_power->batt_info.level; - } - } - else if (*level <= wm831x_power->batt_info.level) - { - disp_plus = 0; - disp_minus = 0; - - if (++disp_curr > disp_num) - { - *level = *level; - disp_curr = 0; - } - else - { - *level = wm831x_power->batt_info.level; - } - } - else if (*level >= (wm831x_power->batt_info.level+1)) - { - disp_minus = 0; - disp_curr = 0; - - if (++disp_plus > (disp_num<<1)) - { - *level = wm831x_power->batt_info.level + 1; - disp_plus = 0; - if((*level < 17) || (*level > 85)) - disp_num = 10; - else - disp_num = 50; - } - else - { - *level = wm831x_power->batt_info.level; - } - } - else - { - disp_plus = 0; - disp_minus = 0; - disp_curr = 0; - *level = wm831x_power->batt_info.level; - } - } - - if (*level >= 100) - *level = 100; - if (*level < 0) - *level = 0; - } -} - -static void wm831x_batt_work(struct work_struct *work) -{ - int online, status,health,level, ret; - union power_supply_propval val; - struct wm831x_power *power = container_of(work, struct wm831x_power, batt_work); - - ret = wm831x_power_check_online(power->wm831x, WM831X_PWR_SRC_BATT, &val); - if (ret < 0) { - printk("%s: check bat online failer... err = %d\n", __FUNCTION__, ret); - return; - } - online = val.intval; - - ret = wm831x_bat_check_status(power->wm831x, &status); - if (ret < 0) { - printk("%s: check bat status failer... err = %d\n", __FUNCTION__, ret); - return; - } - - ret = wm831x_bat_check_health(power->wm831x, &health); - if (ret < 0) { - printk("%s: check bat health failer... err = %d\n", __FUNCTION__, ret); - return; - } - - ret = wm831x_power_read_voltage(power->wm831x, WM831X_AUX_BATT, &val); - if (ret < 0) { - printk("%s: read bat voltage failer...err = %d\n", __FUNCTION__, ret); - return; - } - power->batt_info.voltage = val.intval; - - wm831x_batt_vol_level(power, val.intval, &level); - //mod_timer(&power->timer, jiffies + msecs_to_jiffies(power->interval)); - - if (online != power->batt_info.online || status != power->batt_info.status - || health != power->batt_info.health || level != power->batt_info.level) - { - power->batt_info.online = online; - power->batt_info.status = status; - power->batt_info.health = health; - power->batt_info.level = level; - - power_supply_changed(&power->battery); - } - -} - static __devinit int wm831x_power_probe(struct platform_device *pdev) { struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); @@ -1076,14 +556,12 @@ static __devinit int wm831x_power_probe(struct platform_device *pdev) goto err_syslo; } -#ifdef CONFIG_WM831X_WITH_BATTERY for (i = 0; i < ARRAY_SIZE(wm831x_bat_irqs); i++) { irq = platform_get_irq_byname(pdev, wm831x_bat_irqs[i]); ret = request_threaded_irq(irq, NULL, wm831x_bat_irq, IRQF_TRIGGER_RISING, wm831x_bat_irqs[i], power); - WM_BATT_DBG("%s: %s irq no %d\n", __FUNCTION__, wm831x_bat_irqs[i], irq); if (ret != 0) { dev_err(&pdev->dev, "Failed to request %s IRQ %d: %d\n", @@ -1091,27 +569,9 @@ static __devinit int wm831x_power_probe(struct platform_device *pdev) goto err_bat_irq; } } -#endif - - power->interval = TIMER_MS_COUNTS; - power->batt_info.level = 100; - power->batt_info.voltage = 4200; - power->batt_info.online = 1; - power->batt_info.status = POWER_SUPPLY_STATUS_DISCHARGING; - power->batt_info.health = POWER_SUPPLY_HEALTH_GOOD; - - wake_lock_init(&power->syslo_wake, WAKE_LOCK_SUSPEND, "wm831x_syslo_wake"); - INIT_WORK(&power->batt_work, wm831x_batt_work); - setup_timer(&power->timer, wm831x_batt_timer_handler, (unsigned long)power); - power->timer.expires = jiffies + msecs_to_jiffies(1000); - add_timer(&power->timer); - - g_wm831x_power = power; - printk("%s:wm831x_power initialized\n",__FUNCTION__); - power_test_sysfs_init(); + return ret; - -#ifdef CONFIG_WM831X_WITH_BATTERY + err_bat_irq: for (; i >= 0; i--) { irq = platform_get_irq_byname(pdev, wm831x_bat_irqs[i]); @@ -1119,8 +579,6 @@ err_bat_irq: } irq = platform_get_irq_byname(pdev, "PWR SRC"); free_irq(irq, power); -#endif - err_syslo: irq = platform_get_irq_byname(pdev, "SYSLO"); free_irq(irq, power); @@ -1139,12 +597,12 @@ static __devexit int wm831x_power_remove(struct platform_device *pdev) { struct wm831x_power *wm831x_power = platform_get_drvdata(pdev); int irq, i; -#ifdef CONFIG_WM831X_WITH_BATTERY + for (i = 0; i < ARRAY_SIZE(wm831x_bat_irqs); i++) { irq = platform_get_irq_byname(pdev, wm831x_bat_irqs[i]); free_irq(irq, wm831x_power); } -#endif + irq = platform_get_irq_byname(pdev, "PWR SRC"); free_irq(irq, wm831x_power); @@ -1154,40 +612,17 @@ static __devexit int wm831x_power_remove(struct platform_device *pdev) power_supply_unregister(&wm831x_power->battery); power_supply_unregister(&wm831x_power->wall); power_supply_unregister(&wm831x_power->usb); - kfree(wm831x_power); - return 0; -} - -#ifdef CONFIG_PM -static int wm831x_battery_suspend(struct platform_device *dev, pm_message_t state) -{ - struct wm831x_power *power = (struct wm831x_power *)platform_get_drvdata(dev); - flush_scheduled_work(); - del_timer(&power->timer); return 0; } -static int wm831x_battery_resume(struct platform_device *dev) -{ - struct wm831x_power *power = (struct wm831x_power *)platform_get_drvdata(dev); - power->timer.expires = jiffies + msecs_to_jiffies(power->interval); - add_timer(&power->timer); - return 0; -} -#else -#define wm831x_battery_suspend NULL -#define wm831x_battery_resume NULL -#endif - static struct platform_driver wm831x_power_driver = { .probe = wm831x_power_probe, .remove = __devexit_p(wm831x_power_remove), - .suspend = wm831x_battery_suspend, - .resume = wm831x_battery_resume, .driver = { .name = "wm831x-power", }, }; + static int __init wm831x_power_init(void) { return platform_driver_register(&wm831x_power_driver); @@ -1200,98 +635,7 @@ static void __exit wm831x_power_exit(void) } module_exit(wm831x_power_exit); - -static ssize_t power_prop_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - ssize_t ret = 0; - int level, power_status, system_status, chg_ctl1, chg_ctl2, chg_status; - union power_supply_propval val; - - if (!g_wm831x_power) - return -1; - power_status = wm831x_reg_read(g_wm831x_power->wm831x, WM831X_POWER_STATE); - if (power_status < 0) - return power_status; - //printk("wm831x power status %#x\n", ret); - - system_status = wm831x_reg_read(g_wm831x_power->wm831x, WM831X_SYSTEM_STATUS); - if (system_status < 0) - return system_status; - //printk("wm831x system status %#x\n", ret); - - chg_ctl1 = wm831x_reg_read(g_wm831x_power->wm831x, WM831X_CHARGER_CONTROL_1); - if (chg_ctl1 < 0) - return chg_ctl1; - //printk("wm831x charger control1 %#x\n", ret); - - chg_ctl2 = wm831x_reg_read(g_wm831x_power->wm831x, WM831X_CHARGER_CONTROL_2); - if (chg_ctl2 < 0) - return chg_ctl2; - //printk("wm831x charger control2 %#x\n", ret); - - chg_status = wm831x_reg_read(g_wm831x_power->wm831x, WM831X_CHARGER_STATUS); - if (chg_status < 0) - return chg_status; - //printk("wm831x charger status %#x\n", ret); - - ret = wm831x_power_read_voltage(g_wm831x_power->wm831x, WM831X_AUX_BATT, &val); - if (ret < 0) - return ret; - wm831x_batt_vol_level(g_wm831x_power, val.intval, &level); - //printk("batt_vol = %d batt_level = %d\n", val.intval, level); - // - sprintf(buf, "power_status=%#x\n" - "system_status=%#x\n" - "chg_ctl1=%#x\n" - "chg_ctl2=%#x\n" - "chg_status=%#x\n" - "batt_vol=%d\n" - "batt_level=%d%%\n", - power_status, - system_status, - chg_ctl1, - chg_ctl2, - chg_status, - val.intval, - level); - ret = strlen(buf) + 1; - return ret; -} - -static DEVICE_ATTR(prop, 0444, power_prop_show, NULL); - -static struct kobject *power_test_kobj; - -static int power_test_sysfs_init(void) -{ - int ret ; - power_test_kobj = kobject_create_and_add("power_test_prop", NULL); - if (power_test_kobj == NULL) { - printk(KERN_ERR - "power_test_sysfs_init:"\ - "subsystem_register failed\n"); - ret = -ENOMEM; - goto err; - } - ret = sysfs_create_file(power_test_kobj, &dev_attr_prop.attr); - if (ret) { - printk(KERN_ERR - "power_test_sysfs_init:"\ - "sysfs_create_group failed\n"); - goto err1; - } - - return 0 ; -err1: - kobject_del(power_test_kobj); -err: - return ret ; -} - - MODULE_DESCRIPTION("Power supply driver for WM831x PMICs"); MODULE_AUTHOR("Mark Brown "); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:wm831x-power"); - diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 0b4200a25a53..085384e7e27e 100755 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -25,16 +25,11 @@ obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o obj-$(CONFIG_REGULATOR_WM8994) += wm8994-regulator.o obj-$(CONFIG_REGULATOR_TPS6586X) += tps6586x-regulator.o -obj-$(CONFIG_REGULATOR_TPS65910) += tps65910-regulator.o obj-$(CONFIG_REGULATOR_DA903X) += da903x.o obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o -obj-$(CONFIG_RK2818_REGULATOR_LP8725) += rk2818_lp8725.o -obj-$(CONFIG_RK2818_REGULATOR_CHARGE) += charge-regulator.o -obj-$(CONFIG_RK29_PWM_REGULATOR) += rk29-pwm-regulator.o - obj-$(CONFIG_REGULATOR_CPCAP) += cpcap-regulator.o obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o @@ -42,6 +37,5 @@ obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.o obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o obj-$(CONFIG_REGULATOR_AB8500) += ab8500.o -obj-$(CONFIG_REGULATOR_ACT8891) += act8891.o ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 61855ef1ae5e..cc8b337b9119 100755 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1621,23 +1621,7 @@ out: return ret; } EXPORT_SYMBOL_GPL(regulator_set_voltage); -int regulator_set_suspend_voltage(struct regulator *regulator, int uV) -{ - struct regulator_dev *rdev = regulator->rdev; - int ret = 0; - - if (rdev->desc->ops->set_suspend_voltage && uV > 0) { - ret = rdev->desc->ops->set_suspend_voltage(rdev, uV); - if (ret < 0) { - printk(KERN_ERR "%s: failed to set voltage\n", - __func__); - return ret; - } - } - return ret; -} -EXPORT_SYMBOL_GPL(regulator_set_suspend_voltage); static int _regulator_get_voltage(struct regulator_dev *rdev) { /* sanity check */ diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c deleted file mode 100644 index e823237555b0..000000000000 --- a/drivers/regulator/tps65910-regulator.c +++ /dev/null @@ -1,767 +0,0 @@ -/* - * tps65910-regulator.c -- support regulators in tps65910x family chips - * - * - * Copyright (C) 2010 Mistral Solutions Pvt Ltd - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation version 2. - * - * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind, - * whether express or implied; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if 0 -#define DBG(x...) printk(KERN_INFO x) -#else -#define DBG(x...) -#endif - -/* - * The TPS65910x family chips include power management, a GPIO - * RTC. These chips are often used in AM35xx-based systems. - * - * This driver implements software-based resource control for various - * voltage regulators. This is usually augmented with state machine - * based control. - */ - - -struct tps65910reg_info { - /* tps65910 resource ID, for resource control state machine */ - u8 id; - /* voltage in mV = table[VSEL]; table_len must be a power-of-two */ - u8 table_len; - const u16 *table; - - /* regulator specific turn-on delay */ - u32 delay; - /* chip constraints on regulator behavior */ - u16 min_mV; - u16 max_mV; - /* used by regulator core */ - struct regulator_desc desc; -}; - - -/* Supported voltage values for regulators */ - -/* TPS65910 VIO */ -static const u16 VIO_VSEL_table[] = { - 1500, 1800, 2500, 3300, -}; - -/* TPS65910 VDD1 and VDD2 */ -/* value round off 12.5 is made as 12 */ -static const u16 VDD1_VSEL_table[] = { - 0, 600, 600, 600, 612, 625, 637, 650, - 662, 675, 687, 700, 712, 725, 737, 750, - 762, 775, 787, 800, 812, 825, 837, 850, - 862, 875, 887, 900, 912, 925, 937, 950, - 962, 975, 987, 1000, 1012, 1025, 1037, 1050, - 1062, 1075, 1087, 1100, 1112, 1125, 1137, 1150, - 1162, 1175, 1187, 1200, 1212, 1225, 1237, 1250, - 1262, 1275, 1287, 1300, 1312, 1325, 1337, 1350, - 1362, 1375, 1387, 1400, 1412, 1425, 1437, 1450, - 1462, 1475, 1487, 1500, -}; - -static const u16 VDD2_VSEL_table[] = { - 0, 600, 600, 600, 612, 625, 637, 650, - 662, 675, 687, 700, 712, 725, 737, 750, - 762, 775, 787, 800, 812, 825, 837, 850, - 862, 875, 887, 900, 912, 925, 937, 950, - 962, 975, 987, 1000, 1012, 1025, 1037, 1050, - 1062, 1075, 1087, 1100, 1112, 1125, 1137, 1150, - 1162, 1175, 1187, 1200, 1212, 1225, 1237, 1250, - 1262, 1275, 1287, 1300, 1312, 1325, 1337, 1350, - 1362, 1375, 1387, 1400, 1412, 1425, 1437, 1450, - 1462, 1475, 1487, 1500, -}; - -/* TPS65910 VDD3 */ -static const u16 VDD3_VSEL_table[] = { - 5000, -}; - -/* VDIG1 */ -static const u16 VDIG1_VSEL_table[] = { - 1200, 1500, 1800, 2700, -}; - -/* VDIG2 */ -static const u16 VDIG2_VSEL_table[] = { - 1000, 1100, 1200, 1800, -}; - -/* VAUX33 */ -static const u16 VAUX33_VSEL_table[] = { - 1800, 2000, 2800, 3300, -}; - -/* VMMC */ -static const u16 VMMC_VSEL_table[] = { - 1800, 2800, 3000, 3300, -}; - -/* VAUX1 */ -static const u16 VAUX1_VSEL_table[] = { - 1800, 2000, 2800, 3300, -}; - -/* VAUX2 */ -static const u16 VAUX2_VSEL_table[] = { - 1800, 2800, 2900, 3300, -}; - -/* VDAC */ -static const u16 VDAC_VSEL_table[] = { - 1800, 2600, 2800, 2850, -}; - - -/* VPLL */ -static const u16 VPLL_VSEL_table[] = { - 1000, 1100, 1800, 2500, -}; - -/* VRTC, supports only enable/disable */ -static const u16 VRTC_VSEL_table[] = { - 1800, -}; - -static inline int -tps65910reg_read(struct tps65910reg_info *info, unsigned slave_addr, - u8 offset) -{ - u8 value; - int status; - status = tps65910_i2c_read_u8(slave_addr, &value, offset); - - return (status < 0) ? status : value; -} - -static inline int -tps65910reg_write(struct tps65910reg_info *info, unsigned slave_addr, - u8 offset, u8 value) -{ - if (0 == tps65910_i2c_write_u8(slave_addr, value, offset)) - return 0; - else - return -1; -} - -static u8 tps65910reg_find_offset(u8 regulator_id) -{ - u8 offset = 0; - - switch (regulator_id) { - - case TPS65910_VIO: - offset = TPS65910_REG_VIO; - break; - case TPS65910_VDD1: - offset = TPS65910_REG_VDD1_OP; - break; - case TPS65910_VDD2: - offset = TPS65910_REG_VDD2_OP; - break; - case TPS65910_VDD3: - offset = TPS65910_REG_VDD3; - break; - case TPS65910_VDIG1: - offset = TPS65910_REG_VDIG1; - break; - case TPS65910_VDIG2: - offset = TPS65910_REG_VDIG2; - break; - case TPS65910_VAUX33: - offset = TPS65910_REG_VAUX33; - break; - case TPS65910_VMMC: - offset = TPS65910_REG_VMMC; - break; - case TPS65910_VAUX1: - offset = TPS65910_REG_VAUX1; - break; - case TPS65910_VAUX2: - offset = TPS65910_REG_VAUX2; - break; - case TPS65910_VDAC: - offset = TPS65910_REG_VDAC; - break; - case TPS65910_VPLL: - offset = TPS65910_REG_VPLL; - break; - } - return offset; -} - -static int tps65910reg_is_enabled(struct regulator_dev *rdev) -{ - int val; - u8 offset; - - struct tps65910reg_info *info = rdev_get_drvdata(rdev); - - offset = tps65910reg_find_offset(info->id); - - val = tps65910reg_read(info, TPS65910_I2C_ID0, offset); - if (val < 0) { - printk(KERN_ERR "Unable to read TPS65910 Reg at offset 0x%x= \ - \n", offset); - return -EIO; - } - if ((val & TPS65910_REG_OHP) || (val & TPS65910_REG_OLP)) - return 1; - else - return 0; -} - - -static int tps65910reg_enable(struct regulator_dev *rdev) -{ - int val; - u8 offset; - struct tps65910reg_info *info = rdev_get_drvdata(rdev); - - offset = tps65910reg_find_offset(info->id); - - val = tps65910reg_read(info, TPS65910_I2C_ID0, offset); - - if (val < 0) { - - printk(KERN_ERR "Unable to read TPS65910 Reg at offset = 0x%x \ - \n", offset); - return -EIO; - } - val |= TPS65910_REG_OHP; - - DBG("%s: enable regulator id=%d\n", __FUNCTION__, info->id); - - return tps65910reg_write(info, TPS65910_I2C_ID0, offset, val); -} - -static int tps65910reg_disable(struct regulator_dev *rdev) -{ - int val; - u8 offset; - - struct tps65910reg_info *info = rdev_get_drvdata(rdev); - - offset = tps65910reg_find_offset(info->id); - - val = tps65910reg_read(info, TPS65910_I2C_ID0, offset); - - if (val < 0) { - - printk(KERN_ERR "Unable to read TPS65910 Reg at offset = \ - 0x%x\n", offset); - return -EIO; - } - val &= TPS65910_REG_OFF_00; - - DBG("%s: disable regulator id=%d\n", __FUNCTION__, info->id); - - return tps65910reg_write(info, TPS65910_I2C_ID0, offset, val); -} - -static int tps65910reg_get_status(struct regulator_dev *rdev) -{ - int val; - u8 offset; - u8 ret; - struct tps65910reg_info *info = rdev_get_drvdata(rdev); - - offset = tps65910reg_find_offset(info->id); - - val = tps65910reg_read(info, TPS65910_I2C_ID0, offset); - - if (val < 0) { - - printk(KERN_ERR "Unable to read TPS65910 Reg at offset = \ - 0x%x\n", offset); - return -EIO; - } - switch ((val & SUPPLY_STATE_FLAG)) { - - case TPS65910_REG_OFF_00: - case TPS65910_REG_OFF_10: - ret = REGULATOR_STATUS_OFF; - break; - case TPS65910_REG_OHP: - case TPS65910_REG_OLP: - ret = REGULATOR_STATUS_ON; - break; - default: - ret = REGULATOR_STATUS_OFF; - } - return ret; -} - - -static int tps65910reg_set_mode(struct regulator_dev *rdev, unsigned mode) -{ - struct tps65910reg_info *info = rdev_get_drvdata(rdev); - u8 offset; - u8 val; - - offset = tps65910reg_find_offset(info->id); - val = tps65910reg_read(info, TPS65910_I2C_ID0, offset); - - if (val < 0) { - printk(KERN_ERR"Unable to read TPS65910 Reg at offset \ - = 0x%x\n", offset); - return -EIO; - } - - switch (mode) { - case REGULATOR_MODE_NORMAL: - return tps65910reg_write(info, TPS65910_I2C_ID0, offset, - (val | TPS65910_REG_OHP)); - case REGULATOR_MODE_STANDBY: - return tps65910reg_write(info, TPS65910_I2C_ID0, offset, - (val | TPS65910_REG_OLP)); - default: - return -EINVAL; - } -} - -static -int tps65910_ldo_list_voltage(struct regulator_dev *rdev, unsigned index) -{ - struct tps65910reg_info *info = rdev_get_drvdata(rdev); - int mV = info->table[index]; - return mV * 1000; -} - -static int get_voltage_index(int ldo_id, int uv) -{ - int i = 0; - int size = 0; - u16 *ptr = NULL; - - uv = uv/1000; - - if (((ldo_id == TPS65910_VDD1) || (ldo_id == TPS65910_VDD2))) { - for (i = 0; i < ARRAY_SIZE(VDD1_VSEL_table); i++) { - if (VDD1_VSEL_table[i] == uv) { - DBG("%s: regulator id=%d, volage=%d, get index=%d\n", __FUNCTION__, ldo_id, uv, i); - return i; - } - } - if (i == ARRAY_SIZE(VDD1_VSEL_table)) { - DBG("%s: regulator id=%d, can't find volage index\n", __FUNCTION__, ldo_id); - return -1; - } - } - - /* Lookup table to match LDO volatge to Index*/ - switch (ldo_id) { - - case TPS65910_VIO: - ptr = (u16 *)&VIO_VSEL_table[0]; - size = ARRAY_SIZE(VIO_VSEL_table); - break; - case TPS65910_VDIG1: - ptr = (u16 *)&VDIG1_VSEL_table[0]; - size = ARRAY_SIZE(VDIG1_VSEL_table); - break; - case TPS65910_VDIG2: - ptr = (u16 *)&VDIG2_VSEL_table[0]; - size = ARRAY_SIZE(VDIG2_VSEL_table); - break; - case TPS65910_VAUX33: - ptr = (u16 *)&VAUX33_VSEL_table[0]; - size = ARRAY_SIZE(VAUX33_VSEL_table); - break; - case TPS65910_VMMC: - ptr = (u16 *)&VMMC_VSEL_table[0]; - size = ARRAY_SIZE(VMMC_VSEL_table); - break; - case TPS65910_VAUX1: - ptr = (u16 *)&VAUX1_VSEL_table[0]; - size = ARRAY_SIZE(VAUX1_VSEL_table); - break; - case TPS65910_VAUX2: - ptr = (u16 *)&VAUX2_VSEL_table[0]; - size = ARRAY_SIZE(VAUX2_VSEL_table); - break; - case TPS65910_VDAC: - ptr = (u16 *)&VDAC_VSEL_table[0]; - size = ARRAY_SIZE(VDAC_VSEL_table); - break; - case TPS65910_VPLL: - ptr = (u16 *)&VPLL_VSEL_table[0]; - size = ARRAY_SIZE(VPLL_VSEL_table); - break; - default: - ptr = NULL; - break; - } - - if (ptr != NULL) { - for (i = 0; i < size; i++) { - if (*ptr++ == uv) { - DBG("%s: regulator id=%d, volage=%d, get index=%d\n", __FUNCTION__, ldo_id, uv, i); - return i; - } - } - } - DBG("%s: regulator id=%d, can't find volage index\n", __FUNCTION__, ldo_id); - - if (ptr == NULL || i == size) - return -1; - /* For warning */ - return -1; -} - -static int get_index_voltage(int ldo_id, int index) -{ - int vsel; - int size = 0; - u16 *ptr = NULL; - - /* Get the index of voltage value from Reg and map to table */ - if (ldo_id == TPS65910_VDD1 || ldo_id == TPS65910_VDD2) { - index &= 0x7F; - ptr = (u16 *)&VDD1_VSEL_table[0]; - size = ARRAY_SIZE(VDD1_VSEL_table); - /* For VDD1 and VDD2 */ - if (index >= size) { - vsel = size - 1; - } else { - vsel = index; - } - } else { - vsel = (index & 0xF3); - vsel = (vsel >> 2); - - /* Lookup table to match LDO volatge to Index*/ - switch (ldo_id) { - - case TPS65910_VIO: - ptr = (u16 *)&VIO_VSEL_table[0]; - size = ARRAY_SIZE(VIO_VSEL_table); - break; - case TPS65910_VDIG1: - ptr = (u16 *)&VDIG1_VSEL_table[0]; - size = ARRAY_SIZE(VDIG1_VSEL_table); - break; - case TPS65910_VDIG2: - ptr = (u16 *)&VDIG2_VSEL_table[0]; - size = ARRAY_SIZE(VDIG2_VSEL_table); - break; - case TPS65910_VAUX33: - ptr = (u16 *)&VAUX33_VSEL_table[0]; - size = ARRAY_SIZE(VAUX33_VSEL_table); - break; - case TPS65910_VMMC: - ptr = (u16 *)&VMMC_VSEL_table[0]; - size = ARRAY_SIZE(VMMC_VSEL_table); - break; - case TPS65910_VAUX1: - ptr = (u16 *)&VAUX1_VSEL_table[0]; - size = ARRAY_SIZE(VAUX1_VSEL_table); - break; - case TPS65910_VAUX2: - ptr = (u16 *)&VAUX2_VSEL_table[0]; - size = ARRAY_SIZE(VAUX2_VSEL_table); - break; - case TPS65910_VDAC: - ptr = (u16 *)&VDAC_VSEL_table[0]; - size = ARRAY_SIZE(VDAC_VSEL_table); - break; - case TPS65910_VPLL: - ptr = (u16 *)&VPLL_VSEL_table[0]; - size = ARRAY_SIZE(VPLL_VSEL_table); - break; - default: - ptr = NULL; - break; - } - - if (vsel >= size) - vsel = size - 1; - } - - if (ptr != NULL) { - DBG("%s: regulator id=%d index=%d, get volage=%d(mV)\n", __FUNCTION__, ldo_id, index, ptr[vsel]); - return ptr[vsel] * 1000; - } - /* For warning */ - DBG("%s: regulator id=%d index=%d, get volage error\n", __FUNCTION__, ldo_id, index); - return -1; -} - -static int -tps65910_ldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) -{ - struct tps65910reg_info *info = rdev_get_drvdata(rdev); - int vsel; - u8 offset; - u8 val; - u8 index; - - if (info == NULL) - return 0; - - DBG("%s: regulator(%s) id=%d, set volage=(min_uV:%d, max_uV:%d)\n", __FUNCTION__, info->desc.name, info->id, min_uV, max_uV); - if (rdev->constraints) { - if (min_uV < rdev->constraints->min_uV || min_uV > rdev->constraints->max_uV) - return -EINVAL; - if (max_uV < rdev->constraints->min_uV || max_uV > rdev->constraints->max_uV) - return -EINVAL; - } - - for (vsel = 0; vsel < info->table_len; vsel++) { - - int mV = info->table[vsel]; - int uV; - - uV = mV * 1000; - - /* Break at the first in-range value */ - if (min_uV <= uV && uV <= max_uV) { - offset = tps65910reg_find_offset(info->id); - val = tps65910reg_read(info, TPS65910_I2C_ID0, offset); - if (val < 0) { - printk(KERN_ERR"Unable to read TPS65910 Reg at offset = 0x%x\n", - offset); - return -EIO; - } - - index = get_voltage_index(info->id, uV); - /* For VDD1 and VDD2 */ - if (info->id == TPS65910_VDD1 || info->id == TPS65910_VDD2) { - val = index; - return tps65910reg_write(info, TPS65910_I2C_ID0, offset, val); - } - - val &= 0xF3; - val = (index << 2); - val |= 0x01; - if (index < 0) { - printk(KERN_ERR "Invaild voltage for LDO \n"); - return -EINVAL; - } - - return tps65910reg_write(info, TPS65910_I2C_ID0, offset, val); - } - } - - return -EINVAL; -} - -static int tps65910_ldo_get_voltage(struct regulator_dev *rdev) -{ - struct tps65910reg_info *info = rdev_get_drvdata(rdev); - int vsel; - u8 offset; - - offset = tps65910reg_find_offset(info->id); - vsel = tps65910reg_read(info, TPS65910_I2C_ID0, offset); - if (vsel < 0) { - printk(KERN_ERR"Unable to read TPS65910 Reg at offset = \ - 0x%x\n", offset); - return -EIO; - } - - /* Get the index of voltage value from Reg and map to table */ - return get_index_voltage(info->id, vsel); -} - - -static struct regulator_ops tps65910_ldo_ops = { - .list_voltage = tps65910_ldo_list_voltage, - .set_voltage = tps65910_ldo_set_voltage, - .get_voltage = tps65910_ldo_get_voltage, - .enable = tps65910reg_enable, - .disable = tps65910reg_disable, - .is_enabled = tps65910reg_is_enabled, - .set_mode = tps65910reg_set_mode, - .get_status = tps65910reg_get_status, -}; - -static -int tps65910_fixed_list_voltage(struct regulator_dev *rdev, unsigned index) -{ - struct tps65910reg_info *info = rdev_get_drvdata(rdev); - - return info->min_mV * 1000; -} - -static int tps65910_fixed_get_voltage(struct regulator_dev *rdev) -{ - struct tps65910reg_info *info = rdev_get_drvdata(rdev); - - return info->min_mV * 1000; -} - -static struct regulator_ops tps65910_fixed_ops = { - .list_voltage = tps65910_fixed_list_voltage, - .get_voltage = tps65910_fixed_get_voltage, - .enable = tps65910reg_enable, - .disable = tps65910reg_disable, - .is_enabled = tps65910reg_is_enabled, - .set_mode = tps65910reg_set_mode, - .get_status = tps65910reg_get_status, -}; - -#define TPS65910_ADJUSTABLE_LDO(label, num, min_mVolts, max_mVolts,\ - turnon_delay) { \ - .id = num, \ - .table_len = ARRAY_SIZE(label##_VSEL_table), \ - .table = label##_VSEL_table, \ - .min_mV = min_mVolts, \ - .max_mV = max_mVolts, \ - .delay = turnon_delay, \ - .desc = { \ - .name = #label, \ - .id = TPS65910_##label, \ - .n_voltages = ARRAY_SIZE(label##_VSEL_table), \ - .ops = &tps65910_ldo_ops, \ - .type = REGULATOR_VOLTAGE, \ - .owner = THIS_MODULE, \ - }, \ -} - -#define TPS65910_FIXED_LDO(label, num, mVolts, turnon_delay) { \ - .id = num, \ - .min_mV = mVolts, \ - .delay = turnon_delay, \ - .desc = { \ - .name = #label, \ - .id = TPS65910_##label, \ - .n_voltages = 1, \ - .ops = &tps65910_fixed_ops, \ - .type = REGULATOR_VOLTAGE, \ - .owner = THIS_MODULE, \ - }, \ -} - -/* - * We list regulators here if systems need some level of - * software control over them after boot. - */ -static struct tps65910reg_info tps65910_regs[] = { - - TPS65910_ADJUSTABLE_LDO(VDD1, TPS65910_VDD1, 950, 1400, 4), - TPS65910_FIXED_LDO(VDD2, TPS65910_VDD2, 1500, 4), - TPS65910_FIXED_LDO(VIO, TPS65910_VIO, 3300, 1), - - TPS65910_FIXED_LDO(VDD3, TPS65910_VDD3, 5000, 0), - - TPS65910_FIXED_LDO(VDIG1, TPS65910_VDIG1, 2700, 7), - TPS65910_FIXED_LDO(VDIG2, TPS65910_VDIG2, 1200, 2), - TPS65910_FIXED_LDO(VAUX33, TPS65910_VAUX33, 3300, 2), - TPS65910_FIXED_LDO(VMMC, TPS65910_VMMC, 3000, 7), - TPS65910_FIXED_LDO(VAUX1, TPS65910_VAUX1, 2800, 7), - TPS65910_FIXED_LDO(VAUX2, TPS65910_VAUX2, 2900, 6), - TPS65910_FIXED_LDO(VDAC, TPS65910_VDAC, 1800, 6), - TPS65910_FIXED_LDO(VPLL, TPS65910_VPLL, 2500, 2), -}; - -static int tps65910_regulator_probe(struct platform_device *pdev) -{ - int i; - struct tps65910reg_info *info; - struct regulator_init_data *initdata; - struct regulation_constraints *c; - struct regulator_dev *rdev; - - for (i = 0, info = NULL; i < ARRAY_SIZE(tps65910_regs); i++) { - if (tps65910_regs[i].desc.id != pdev->id) - continue; - info = tps65910_regs + i; - break; - } - if (!info) - return -ENODEV; - - DBG("%s: reguloter(%s) id=%d\n", __FUNCTION__, info->desc.name, info->id); - - initdata = pdev->dev.platform_data; - if (!initdata) - return -EINVAL; - - /* Constrain board-specific capabilities according to what - * this driver and the chip itself can actually do. - */ - c = &initdata->constraints; - c->valid_modes_mask &= REGULATOR_MODE_NORMAL | REGULATOR_MODE_STANDBY; - c->valid_ops_mask &= REGULATOR_CHANGE_VOLTAGE - | REGULATOR_CHANGE_MODE - | REGULATOR_CHANGE_STATUS; - - switch (pdev->id) { - case TPS65910_REG_VIO: - case TPS65910_REG_VDD1: - case TPS65910_REG_VDD2: - case TPS65910_REG_VDIG2: - case TPS65910_REG_VPLL: - c->always_on = true; - break; - default: - break; - } - - rdev = regulator_register(&info->desc, &pdev->dev, initdata, info); - - if (IS_ERR(rdev)) { - dev_err(&pdev->dev, "can't register %s, %ld\n", - info->desc.name, PTR_ERR(rdev)); - return PTR_ERR(rdev); - } - // cwz add for init status, for regulator disable - rdev->use_count = 1; - - platform_set_drvdata(pdev, rdev); - - DBG("%s: reguloter register OK.\n", __FUNCTION__); - return 0; -} - -static int __devexit tps65910_regulator_remove(struct platform_device *pdev) -{ - regulator_unregister(platform_get_drvdata(pdev)); - return 0; -} - - -MODULE_ALIAS("platform:tps65910_regulator"); -static struct platform_driver tps65910_regulator_driver = { - .probe = tps65910_regulator_probe, - .remove = tps65910_regulator_remove, - .driver.name = "tps65910_regulator", - .driver.owner = THIS_MODULE, -}; - -static int __init tps65910_regulator_init(void) -{ - return platform_driver_register(&tps65910_regulator_driver); -} -rootfs_initcall(tps65910_regulator_init); - -static void __exit tps65910_regulator_exit(void) -{ - platform_driver_unregister(&tps65910_regulator_driver); -} -module_exit(tps65910_regulator_exit) - -MODULE_AUTHOR("cwz "); -MODULE_DESCRIPTION("TPS65910 voltage regulator driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c index 275fd7ad7ce7..dbfaf5945e48 100755 --- a/drivers/regulator/wm831x-dcdc.c +++ b/drivers/regulator/wm831x-dcdc.c @@ -27,18 +27,6 @@ #include #include -#include -#include -#include -#include - -//#include "../../arch/arm/mach-rk29/include/mach/gpio.h" - -//#include - - - - #define WM831X_BUCKV_MAX_SELECTOR 0x68 #define WM831X_BUCKP_MAX_SELECTOR 0x66 @@ -47,7 +35,7 @@ #define WM831X_DCDC_MODE_IDLE 2 #define WM831X_DCDC_MODE_STANDBY 3 -//#define WM831X_DCDC_MAX_NAME 6 +#define WM831X_DCDC_MAX_NAME 6 /* Register offsets in control block */ #define WM831X_DCDC_CONTROL_1 0 @@ -59,7 +47,7 @@ /* * Shared */ -#if 0 + struct wm831x_dcdc { char name[WM831X_DCDC_MAX_NAME]; struct regulator_desc desc; @@ -71,7 +59,6 @@ struct wm831x_dcdc { int on_vsel; int dvs_vsel; }; -#endif static int wm831x_dcdc_is_enabled(struct regulator_dev *rdev) { @@ -313,28 +300,7 @@ static int wm831x_buckv_set_dvs(struct regulator_dev *rdev, int state) return 0; } -//wm831x_buckv_get_voltage - -int wm831x_reg_read(struct wm831x *wm831x, unsigned short reg); -static int wm831x_buckv_read_voltage(struct regulator_dev *rdev) -{ - int vol_read; - int ret; - struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev); - struct wm831x *wm831x = dcdc->wm831x; - int on_reg = dcdc->base + WM831X_DCDC_ON_CONFIG; - ret = wm831x_reg_read(wm831x, on_reg); - if (ret < 0) - return ret; - ret &= WM831X_DC1_ON_VSEL_MASK; - vol_read = (ret-8)*12500 + 600000; - - return vol_read; - - - -} static int wm831x_buckv_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) { @@ -424,78 +390,6 @@ static u16 wm831x_dcdc_ilim[] = { 125, 250, 375, 500, 625, 750, 875, 1000 }; -static int wm831x_buckv_set_voltage_step(struct regulator_dev * rdev, int min_uV, int max_uV) -{ - int old_vol; - int new_min_uV,new_max_uV; - int diff_value,step; - int ret=0; - - struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev); - struct wm831x *wm831x = dcdc->wm831x; - struct wm831x_pdata *pdata = wm831x->dev->platform_data; - - - //if(strcmp(rdev->constraints->name,"DCDC2") != 0) - if(strcmp(pdata->dcdc[1]->consumer_supplies[1].supply,"vcore") != 0) - { - - ret = wm831x_buckv_set_voltage(rdev,min_uV,max_uV); - } - else - { - old_vol = wm831x_buckv_read_voltage(rdev); - - new_min_uV = old_vol; - new_max_uV = old_vol+max_uV-min_uV; - - if(old_vol > min_uV) //reduce voltage - { - diff_value = (old_vol - min_uV); - - for(step = 100000; step<=diff_value; step += 100000) - { - new_min_uV = old_vol-step; - new_max_uV = old_vol+max_uV-min_uV-step; - - ret = wm831x_buckv_set_voltage(rdev,new_min_uV,new_max_uV); - usleep_range(1000,1000); - } - - if(new_min_uV > min_uV) //0< old_vol - min_uV < 100000 ||0< new_min_uV - min_uV < 1000000 - { - - ret = wm831x_buckv_set_voltage(rdev,min_uV,max_uV); - usleep_range(1000,1000); - - } - - } - else //rise voltage - { - diff_value = (min_uV- old_vol); - - for(step = 100000; step<=diff_value; step += 100000) - { - new_min_uV = old_vol + step; - new_max_uV = old_vol+max_uV-min_uV+step; - - ret = wm831x_buckv_set_voltage(rdev,new_min_uV,new_max_uV); - usleep_range(1000,1000); - } - if(new_min_uV < min_uV)// min_uV - old_vol < 100000 || new_min_uV - old_vol < 100000 - { - ret = wm831x_buckv_set_voltage(rdev,min_uV,max_uV); - usleep_range(1000,1000); - } - - } - - } - return ret; - -} - static int wm831x_buckv_set_current_limit(struct regulator_dev *rdev, int min_uA, int max_uA) { @@ -528,19 +422,8 @@ static int wm831x_buckv_get_current_limit(struct regulator_dev *rdev) return wm831x_dcdc_ilim[val & WM831X_DC1_HC_THR_MASK]; } -int wm831x_dcdc_set_suspend_enable(struct regulator_dev *rdev) -{ - - return 0; -} -int wm831x_dcdc_set_suspend_disable(struct regulator_dev *rdev) -{ - - return 0; -} - static struct regulator_ops wm831x_buckv_ops = { - .set_voltage = wm831x_buckv_set_voltage_step, + .set_voltage = wm831x_buckv_set_voltage, .get_voltage = wm831x_buckv_get_voltage, .list_voltage = wm831x_buckv_list_voltage, .set_suspend_voltage = wm831x_buckv_set_suspend_voltage, @@ -554,8 +437,6 @@ static struct regulator_ops wm831x_buckv_ops = { .get_mode = wm831x_dcdc_get_mode, .set_mode = wm831x_dcdc_set_mode, .set_suspend_mode = wm831x_dcdc_set_suspend_mode, - .set_suspend_enable = wm831x_dcdc_set_suspend_enable, - .set_suspend_disable = wm831x_dcdc_set_suspend_disable, }; /* @@ -624,7 +505,7 @@ static __devinit int wm831x_buckv_probe(struct platform_device *pdev) struct wm831x_dcdc *dcdc; struct resource *res; int ret, irq; - + dev_dbg(&pdev->dev, "Probing DCDC%d\n", id + 1); if (pdata == NULL || pdata->dcdc[id] == NULL) @@ -817,8 +698,6 @@ static struct regulator_ops wm831x_buckp_ops = { .get_mode = wm831x_dcdc_get_mode, .set_mode = wm831x_dcdc_set_mode, .set_suspend_mode = wm831x_dcdc_set_suspend_mode, - .set_suspend_enable = wm831x_dcdc_set_suspend_enable, - .set_suspend_disable = wm831x_dcdc_set_suspend_disable, }; static __devinit int wm831x_buckp_probe(struct platform_device *pdev) @@ -1130,7 +1009,6 @@ static struct platform_driver wm831x_epe_driver = { static int __init wm831x_dcdc_init(void) { int ret; - printk("%s \n", __FUNCTION__); ret = platform_driver_register(&wm831x_buckv_driver); if (ret != 0) pr_err("Failed to register WM831x BUCKV driver: %d\n", ret); @@ -1146,7 +1024,7 @@ static int __init wm831x_dcdc_init(void) ret = platform_driver_register(&wm831x_epe_driver); if (ret != 0) pr_err("Failed to register WM831x EPE driver: %d\n", ret); - + return 0; } subsys_initcall(wm831x_dcdc_init); diff --git a/drivers/regulator/wm831x-isink.c b/drivers/regulator/wm831x-isink.c index e754528100f8..6c446cd6ad54 100755 --- a/drivers/regulator/wm831x-isink.c +++ b/drivers/regulator/wm831x-isink.c @@ -25,9 +25,8 @@ #include #include -//#define WM831X_ISINK_MAX_NAME 7 +#define WM831X_ISINK_MAX_NAME 7 -#if 0 struct wm831x_isink { char name[WM831X_ISINK_MAX_NAME]; struct regulator_desc desc; @@ -35,14 +34,13 @@ struct wm831x_isink { struct wm831x *wm831x; struct regulator_dev *regulator; }; -#endif static int wm831x_isink_enable(struct regulator_dev *rdev) { struct wm831x_isink *isink = rdev_get_drvdata(rdev); struct wm831x *wm831x = isink->wm831x; int ret; - printk("%s:line=%d\n",__FUNCTION__,__LINE__); + /* We have a two stage enable: first start the ISINK... */ ret = wm831x_set_bits(wm831x, isink->reg, WM831X_CS1_ENA, WM831X_CS1_ENA); @@ -54,7 +52,7 @@ static int wm831x_isink_enable(struct regulator_dev *rdev) WM831X_CS1_DRIVE); if (ret != 0) wm831x_set_bits(wm831x, isink->reg, WM831X_CS1_ENA, 0); - printk("%s:line=%d,ret=0x%x\n",__FUNCTION__,__LINE__,ret); + return ret; } @@ -64,7 +62,7 @@ static int wm831x_isink_disable(struct regulator_dev *rdev) struct wm831x_isink *isink = rdev_get_drvdata(rdev); struct wm831x *wm831x = isink->wm831x; int ret; - printk("%s:line=%d\n",__FUNCTION__,__LINE__); + ret = wm831x_set_bits(wm831x, isink->reg, WM831X_CS1_DRIVE, 0); if (ret < 0) return ret; @@ -82,11 +80,11 @@ static int wm831x_isink_is_enabled(struct regulator_dev *rdev) struct wm831x_isink *isink = rdev_get_drvdata(rdev); struct wm831x *wm831x = isink->wm831x; int ret; - printk("%s:line=%d\n",__FUNCTION__,__LINE__); + ret = wm831x_reg_read(wm831x, isink->reg); if (ret < 0) return ret; - + if ((ret & (WM831X_CS1_ENA | WM831X_CS1_DRIVE)) == (WM831X_CS1_ENA | WM831X_CS1_DRIVE)) return 1; @@ -160,7 +158,7 @@ static __devinit int wm831x_isink_probe(struct platform_device *pdev) int ret, irq; dev_dbg(&pdev->dev, "Probing ISINK%d\n", id + 1); - printk("%s:line=%d\n",__FUNCTION__,__LINE__); + if (pdata == NULL || pdata->isink[id] == NULL) return -ENODEV; @@ -200,7 +198,6 @@ static __devinit int wm831x_isink_probe(struct platform_device *pdev) } irq = platform_get_irq(pdev, 0); - printk("%s:line=%d,irq=%d\n",__FUNCTION__,__LINE__,irq); ret = wm831x_request_irq(wm831x, irq, wm831x_isink_irq, IRQF_TRIGGER_RISING, isink->name, isink); diff --git a/drivers/regulator/wm831x-ldo.c b/drivers/regulator/wm831x-ldo.c index f74692826dfb..9edf8f692341 100755 --- a/drivers/regulator/wm831x-ldo.c +++ b/drivers/regulator/wm831x-ldo.c @@ -25,7 +25,7 @@ #include #include -//#define WM831X_LDO_MAX_NAME 6 +#define WM831X_LDO_MAX_NAME 6 #define WM831X_LDO_CONTROL 0 #define WM831X_LDO_ON_CONTROL 1 @@ -34,7 +34,6 @@ #define WM831X_ALIVE_LDO_ON_CONTROL 0 #define WM831X_ALIVE_LDO_SLEEP_CONTROL 1 -#if 0 struct wm831x_ldo { char name[WM831X_LDO_MAX_NAME]; struct regulator_desc desc; @@ -42,12 +41,11 @@ struct wm831x_ldo { struct wm831x *wm831x; struct regulator_dev *regulator; }; -#endif /* * Shared */ -extern int reboot_cmd_get(void); + static int wm831x_ldo_is_enabled(struct regulator_dev *rdev) { struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); @@ -70,7 +68,7 @@ static int wm831x_ldo_enable(struct regulator_dev *rdev) struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); struct wm831x *wm831x = ldo->wm831x; int mask = 1 << rdev_get_id(rdev); - //printk("%s,%x\n", __FUNCTION__,mask); + return wm831x_set_bits(wm831x, WM831X_LDO_ENABLE, mask, mask); } @@ -79,7 +77,7 @@ static int wm831x_ldo_disable(struct regulator_dev *rdev) struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); struct wm831x *wm831x = ldo->wm831x; int mask = 1 << rdev_get_id(rdev); - //printk("%s\n", __FUNCTION__); + return wm831x_set_bits(wm831x, WM831X_LDO_ENABLE, mask, 0); } @@ -143,7 +141,7 @@ static int wm831x_gp_ldo_set_voltage(struct regulator_dev *rdev, { struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); int reg = ldo->base + WM831X_LDO_ON_CONTROL; - //printk("%s base=%x,%d,%d\n", __FUNCTION__,ldo->base,min_uV,max_uV); + return wm831x_gp_ldo_set_voltage_int(rdev, reg, min_uV, max_uV); } @@ -166,7 +164,7 @@ static int wm831x_gp_ldo_get_voltage(struct regulator_dev *rdev) ret = wm831x_reg_read(wm831x, reg); if (ret < 0) return ret; - //printk("%s base=%x,ret=%x\n", __FUNCTION__,ldo->base,ret); + ret &= WM831X_LDO1_ON_VSEL_MASK; return wm831x_gp_ldo_list_voltage(rdev, ret); @@ -206,7 +204,7 @@ static int wm831x_gp_ldo_set_mode(struct regulator_dev *rdev, int on_reg = ldo->base + WM831X_LDO_ON_CONTROL; int ret; - printk("%s base=%x,mode=%x\n", __FUNCTION__,ldo->base,mode); + switch (mode) { case REGULATOR_MODE_NORMAL: ret = wm831x_set_bits(wm831x, on_reg, @@ -286,16 +284,6 @@ static unsigned int wm831x_gp_ldo_get_optimum_mode(struct regulator_dev *rdev, return REGULATOR_MODE_NORMAL; } -int wm831x_ldo_set_suspend_enable(struct regulator_dev *rdev) -{ - - return 0; -} -int wm831x_ldo_set_suspend_disable(struct regulator_dev *rdev) -{ - - return 0; -} static struct regulator_ops wm831x_gp_ldo_ops = { .list_voltage = wm831x_gp_ldo_list_voltage, @@ -310,8 +298,6 @@ static struct regulator_ops wm831x_gp_ldo_ops = { .is_enabled = wm831x_ldo_is_enabled, .enable = wm831x_ldo_enable, .disable = wm831x_ldo_disable, - .set_suspend_enable = wm831x_ldo_set_suspend_enable, - .set_suspend_disable = wm831x_ldo_set_suspend_disable, }; static __devinit int wm831x_gp_ldo_probe(struct platform_device *pdev) @@ -324,7 +310,7 @@ static __devinit int wm831x_gp_ldo_probe(struct platform_device *pdev) int ret, irq; dev_dbg(&pdev->dev, "Probing LDO%d\n", id + 1); - printk("Probing LDO%d\n", id + 1); + if (pdata == NULL || pdata->ldo[id] == NULL) return -ENODEV; @@ -455,7 +441,7 @@ static int wm831x_aldo_set_voltage(struct regulator_dev *rdev, { struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); int reg = ldo->base + WM831X_LDO_ON_CONTROL; - printk("%s base=%x,min_uV=%d,%d\n", __FUNCTION__,ldo->base,min_uV,max_uV); + return wm831x_aldo_set_voltage_int(rdev, reg, min_uV, max_uV); } @@ -474,13 +460,13 @@ static int wm831x_aldo_get_voltage(struct regulator_dev *rdev) struct wm831x *wm831x = ldo->wm831x; int reg = ldo->base + WM831X_LDO_ON_CONTROL; int ret; - + ret = wm831x_reg_read(wm831x, reg); if (ret < 0) return ret; - printk("%s base=%x,ret=%x\n", __FUNCTION__,ldo->base,ret); + ret &= WM831X_LDO7_ON_VSEL_MASK; - + return wm831x_aldo_list_voltage(rdev, ret); } @@ -572,8 +558,6 @@ static struct regulator_ops wm831x_aldo_ops = { .is_enabled = wm831x_ldo_is_enabled, .enable = wm831x_ldo_enable, .disable = wm831x_ldo_disable, - .set_suspend_enable = wm831x_ldo_set_suspend_enable, - .set_suspend_disable = wm831x_ldo_set_suspend_disable, }; static __devinit int wm831x_aldo_probe(struct platform_device *pdev) @@ -586,7 +570,7 @@ static __devinit int wm831x_aldo_probe(struct platform_device *pdev) int ret, irq; dev_dbg(&pdev->dev, "Probing LDO%d\n", id + 1); - printk("Probing LDO%d--\n", id + 1); + if (pdata == NULL || pdata->ldo[id] == NULL) return -ENODEV; @@ -760,8 +744,6 @@ static struct regulator_ops wm831x_alive_ldo_ops = { .is_enabled = wm831x_ldo_is_enabled, .enable = wm831x_ldo_enable, .disable = wm831x_ldo_disable, - .set_suspend_enable = wm831x_ldo_set_suspend_enable, - .set_suspend_disable = wm831x_ldo_set_suspend_disable, }; static __devinit int wm831x_alive_ldo_probe(struct platform_device *pdev) @@ -774,7 +756,7 @@ static __devinit int wm831x_alive_ldo_probe(struct platform_device *pdev) int ret; dev_dbg(&pdev->dev, "Probing LDO%d\n", id + 1); - printk("wm831x_alive_ldo_probe Probing LDO%d\n", id + 1); + if (pdata == NULL || pdata->ldo[id] == NULL) return -ENODEV; @@ -830,64 +812,9 @@ static __devexit int wm831x_alive_ldo_remove(struct platform_device *pdev) return 0; } -static __devexit int wm831x_alive_ldo_shutdown(struct platform_device *pdev) /*ZMF*/ -{ - //struct wm831x_ldo *ldo = platform_get_drvdata(pdev); -#if 0 - //close ldo in wm831x_last_deinit() - struct regulator* ldo; - - //if (reboot_cmd_get()) - // return 0; - printk("%s\n", __FUNCTION__); - - ldo = regulator_get(NULL, "ldo1"); - regulator_disable(ldo); - regulator_put(ldo); - - ldo = regulator_get(NULL, "ldo2"); - regulator_disable(ldo); - regulator_put(ldo); - - ldo = regulator_get(NULL, "ldo3"); - regulator_disable(ldo); - regulator_put(ldo); - - ldo = regulator_get(NULL, "ldo4"); - //regulator_disable(ldo); - regulator_put(ldo); - - ldo = regulator_get(NULL, "ldo5"); - regulator_disable(ldo); - regulator_put(ldo); - - ldo = regulator_get(NULL, "ldo6"); - regulator_disable(ldo); - regulator_put(ldo); - - ldo = regulator_get(NULL, "ldo7"); - regulator_disable(ldo); - regulator_put(ldo); - - ldo = regulator_get(NULL, "ldo8"); - //regulator_disable(ldo); - regulator_put(ldo); - - ldo = regulator_get(NULL, "ldo9"); - regulator_disable(ldo); - regulator_put(ldo); - - ldo = regulator_get(NULL, "ldo10"); - regulator_disable(ldo); - regulator_put(ldo); -#endif - return 0; -} - static struct platform_driver wm831x_alive_ldo_driver = { .probe = wm831x_alive_ldo_probe, .remove = __devexit_p(wm831x_alive_ldo_remove), - .shutdown = __devexit_p(wm831x_alive_ldo_shutdown), .driver = { .name = "wm831x-alive-ldo", .owner = THIS_MODULE, @@ -897,7 +824,7 @@ static struct platform_driver wm831x_alive_ldo_driver = { static int __init wm831x_ldo_init(void) { int ret; - printk("%s \n", __FUNCTION__); + ret = platform_driver_register(&wm831x_gp_ldo_driver); if (ret != 0) pr_err("Failed to register WM831x GP LDO driver: %d\n", ret); @@ -910,7 +837,8 @@ static int __init wm831x_ldo_init(void) if (ret != 0) pr_err("Failed to register WM831x alive LDO driver: %d\n", ret); - return 0; + + return 0; } subsys_initcall(wm831x_ldo_init); diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 8ffe3f701035..9c9228fbab61 100755 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -153,21 +153,6 @@ comment "I2C RTC drivers" if I2C -config RTC_HYM8563 - tristate "RK2818 or RK29 extern HYM8563 RTC" - depends on I2C_RK2818 || I2C_RK29 - help - If you say yes here you will get support for the - HYM8563 I2C RTC chip. - This driver can also be built as a module. If so, the module - will be called rtc-HYM8563. - -config RTC_M41T66 - tristate "ST M41T66" - depends on I2C_RK2818 || I2C_RK29 - help - If you say Y here you will get support for the ST M41T66. - config RTC_DRV_DS1307 tristate "Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSON RX-8025" help @@ -352,13 +337,6 @@ config RTC_DRV_TWL4030 This driver can also be built as a module. If so, the module will be called rtc-twl. -config RTC_DRV_TPS65910 - boolean "TI TPS65910" - depends on RTC_CLASS && TPS65910_CORE - help - If you say yes here you get support for the RTC on the - TPS65910 family chips, used mostly with OMAP3/AM35xx platforms. - config RTC_DRV_S35390A tristate "Seiko Instruments S-35390A" select BITREVERSE @@ -369,16 +347,6 @@ config RTC_DRV_S35390A This driver can also be built as a module. If so the module will be called rtc-s35390a. -config RTC_DRV_S35392A - tristate "Seiko Instruments S-35392A" - select BITREVERSE - help - If you say yes here you will get support for the Seiko - Instruments S-35392A. - - This driver can also be built as a module. If so the module - will be called rtc-s35392a. - config RTC_DRV_FM3130 tristate "Ramtron FM3130" help diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 55a71df8aec5..1849ff0b5963 100755 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -85,7 +85,6 @@ obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o obj-$(CONFIG_RTC_DRV_RX8025) += rtc-rx8025.o obj-$(CONFIG_RTC_DRV_RX8581) += rtc-rx8581.o obj-$(CONFIG_RTC_DRV_S35390A) += rtc-s35390a.o -obj-$(CONFIG_RTC_DRV_S35392A) += rtc-s35392a.o obj-$(CONFIG_RTC_DRV_S3C) += rtc-s3c.o obj-$(CONFIG_RTC_DRV_SA1100) += rtc-sa1100.o obj-$(CONFIG_RTC_DRV_SH) += rtc-sh.o @@ -95,7 +94,6 @@ obj-$(CONFIG_RTC_DRV_STMP) += rtc-stmp3xxx.o obj-$(CONFIG_RTC_DRV_SUN4V) += rtc-sun4v.o obj-$(CONFIG_RTC_DRV_TEST) += rtc-test.o obj-$(CONFIG_RTC_DRV_TPS6586X) += rtc-tps6586x.o -obj-$(CONFIG_RTC_DRV_TPS65910) += rtc-tps65910.o obj-$(CONFIG_RTC_DRV_TWL4030) += rtc-twl.o obj-$(CONFIG_RTC_DRV_TX4939) += rtc-tx4939.o obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o @@ -103,6 +101,4 @@ obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o obj-$(CONFIG_RTC_DRV_WM831X) += rtc-wm831x.o obj-$(CONFIG_RTC_DRV_WM8350) += rtc-wm8350.o obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o -obj-$(CONFIG_RTC_HYM8563) += rtc-HYM8563.o -obj-$(CONFIG_RTC_M41T66) += rtc-m41t66.o obj-$(CONFIG_RTC_DRV_CPCAP) += rtc-cpcap.o diff --git a/drivers/rtc/alarm.c b/drivers/rtc/alarm.c index 35b078d29adb..b445a8675850 100644 --- a/drivers/rtc/alarm.c +++ b/drivers/rtc/alarm.c @@ -423,7 +423,6 @@ static int alarm_suspend(struct platform_device *pdev, pm_message_t state) if (rtc_current_time + 1 >= rtc_alarm_time) { pr_alarm(SUSPEND, "alarm about to go off\n"); memset(&rtc_alarm, 0, sizeof(rtc_alarm)); - rtc_time_to_tm(0, &rtc_alarm.time); rtc_alarm.enabled = 0; rtc_set_alarm(alarm_rtc_dev, &rtc_alarm); @@ -449,7 +448,6 @@ static int alarm_resume(struct platform_device *pdev) pr_alarm(SUSPEND, "alarm_resume(%p)\n", pdev); memset(&alarm, 0, sizeof(alarm)); - rtc_time_to_tm(0, &alarm.time); alarm.enabled = 0; rtc_set_alarm(alarm_rtc_dev, &alarm); @@ -463,18 +461,6 @@ static int alarm_resume(struct platform_device *pdev) return 0; } -static void alarm_shutdown(struct platform_device *pdev) -{ - struct rtc_wkalrm alarm; - - pr_alarm(FLOW, "alarm_shutdown(%p)\n", pdev); - - memset(&alarm, 0, sizeof(alarm)); - rtc_time_to_tm(0, &alarm.time); - alarm.enabled = 0; - rtc_set_alarm(alarm_rtc_dev, &alarm); -} - static struct rtc_task alarm_rtc_task = { .func = alarm_triggered_func }; @@ -534,7 +520,6 @@ static struct class_interface rtc_alarm_interface = { static struct platform_driver alarm_driver = { .suspend = alarm_suspend, .resume = alarm_resume, - .shutdown = alarm_shutdown, .driver = { .name = "alarm" } diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index cac32f312790..3053d8d8cd89 100755 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -1554,68 +1554,6 @@ config SERIAL_BCM63XX_CONSOLE If you have enabled the serial port on the bcm63xx CPU you can make it the console by answering Y to this option. -config SERIAL_RK29 - bool "RockChip rk29 serial port support" - depends on ARM && ARCH_RK29 - select SERIAL_CORE - -config SERIAL_RK29_STANDARD - bool "Use RockChip rk29 serial port support standard" - default y - depends on SERIAL_RK29 - -config UART0_RK29 - bool "RockChip rk29 serial port 0 support" - depends on SERIAL_RK29 - -config UART0_CTS_RTS_RK29 - bool "RockChip rk29 serial port 0 cts rts support" - depends on UART0_RK29 - -config UART0_DMA_RK29 - bool "RockChip rk29 serial port 0 dma support (EXPERIMENTAL)" - depends on UART0_RK29 && SERIAL_RK29_STANDARD - -config UART1_RK29 - bool "RockChip rk29 serial port 1 support" - depends on SERIAL_RK29 - -config UART2_RK29 - bool "RockChip rk29 serial port 2 support" - depends on SERIAL_RK29 - -config UART2_CTS_RTS_RK29 - bool "RockChip rk29 serial port 2 cts rts support" - depends on UART2_RK29 - -config UART2_DMA_RK29 - bool "RockChip rk29 serial port 2 dma support (EXPERIMENTAL)" - depends on UART2_RK29 && SERIAL_RK29_STANDARD - -config UART3_RK29 - bool "RockChip rk29 serial port 3 support" - depends on SERIAL_RK29 - -config UART3_CTS_RTS_RK29 - bool "RockChip rk29 serial port 3 cts rts support" - depends on UART3_RK29 - -config UART3_DMA_RK29 - bool "RockChip rk29 serial port 3 dma support (EXPERIMENTAL)" - depends on UART3_RK29 && SERIAL_RK29_STANDARD - -config SERIAL_RK29_CONSOLE - bool "Rockchip rk29 serial console support" - depends on SERIAL_RK29=y - select SERIAL_CORE_CONSOLE - -config SERIAL_SC8800 - tristate "SC8800 support" - depends on SPI - select SERIAL_CORE - help - SC8800 spi-serial support - config SERIAL_GRLIB_GAISLER_APBUART tristate "GRLIB APBUART serial support" depends on OF diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index 8a29576027f0..f0faee6ec05a 100755 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -83,12 +83,6 @@ obj-$(CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL) += nwpserial.o obj-$(CONFIG_SERIAL_KS8695) += serial_ks8695.o obj-$(CONFIG_KGDB_SERIAL_CONSOLE) += kgdboc.o obj-$(CONFIG_SERIAL_QE) += ucc_uart.o -ifeq ($(CONFIG_SERIAL_RK29_STANDARD),y) -obj-$(CONFIG_SERIAL_RK29) += rk_serial.o -else -obj-$(CONFIG_SERIAL_RK29) += rk29_serial.o -endif -obj-$(CONFIG_SERIAL_SC8800) += sc8800.o obj-$(CONFIG_SERIAL_TIMBERDALE) += timbuart.o obj-$(CONFIG_SERIAL_GRLIB_GAISLER_APBUART) += apbuart.o obj-$(CONFIG_SERIAL_ALTERA_JTAGUART) += altera_jtaguart.o diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 0d5e0134ce9d..96f6dda3ee69 100755 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -117,9 +117,6 @@ source "drivers/staging/memrar/Kconfig" source "drivers/staging/iio/Kconfig" -source "drivers/staging/rk29/vivante/Kconfig" -source "drivers/staging/rk29/ipp/Kconfig" - source "drivers/staging/zram/Kconfig" source "drivers/staging/wlags49_h2/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 4ca0c0575945..47c0b9489caf 100755 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -40,8 +40,6 @@ obj-$(CONFIG_HYPERV) += hv/ obj-$(CONFIG_VME_BUS) += vme/ obj-$(CONFIG_MRST_RAR_HANDLER) += memrar/ obj-$(CONFIG_IIO) += iio/ -obj-$(CONFIG_VIVANTE) += rk29/vivante/ -obj-$(CONFIG_RK29_IPP) += rk29/ipp/ obj-$(CONFIG_ZRAM) += zram/ obj-$(CONFIG_WLAGS49_H2) += wlags49_h2/ obj-$(CONFIG_WLAGS49_H25) += wlags49_h25/ diff --git a/drivers/staging/android/timed_gpio.c b/drivers/staging/android/timed_gpio.c index 4c3e8fc63099..a64481c3e86d 100755 --- a/drivers/staging/android/timed_gpio.c +++ b/drivers/staging/android/timed_gpio.c @@ -20,12 +20,10 @@ #include #include #include -#include -#include + #include "timed_output.h" #include "timed_gpio.h" -#define GPIO_TYPE 0 struct timed_gpio_data { struct timed_output_dev dev; @@ -34,40 +32,14 @@ struct timed_gpio_data { unsigned gpio; int max_timeout; u8 active_low; - int adjust_time; -#if (GPIO_TYPE == 1) - struct work_struct timed_gpio_work; -#endif - struct wake_lock irq_wake; }; -#if (GPIO_TYPE == 1) -static void timed_gpio_work_handler(struct work_struct *work) -{ - struct timed_gpio_data *data = - container_of(work, struct timed_gpio_data, timed_gpio_work); - int ret = 0,i = 0; - //set gpio several times once error happened - for(i=0; i<3; i++) - { - ret = gpio_direction_output(data->gpio, data->active_low ? 1 : 0); - if(!ret) - break; - printk("%s:ret=%d,fail to set gpio and set again,i=%d\n",__FUNCTION__,ret,i); - } -} -#endif - static enum hrtimer_restart gpio_timer_func(struct hrtimer *timer) { struct timed_gpio_data *data = container_of(timer, struct timed_gpio_data, timer); - -#if (GPIO_TYPE == 0) + gpio_direction_output(data->gpio, data->active_low ? 1 : 0); -#else - schedule_work(&data->timed_gpio_work); -#endif return HRTIMER_NORESTART; } @@ -88,26 +60,24 @@ static void gpio_enable(struct timed_output_dev *dev, int value) { struct timed_gpio_data *data = container_of(dev, struct timed_gpio_data, dev); - int ret = 0,i = 0; + unsigned long flags; + + spin_lock_irqsave(&data->lock, flags); /* cancel previous timer and set GPIO according to value */ hrtimer_cancel(&data->timer); - //set gpio several times once error happened - for(i=0; i<3; i++) - { - ret = gpio_direction_output(data->gpio, data->active_low ? !value : !!value); - if(!ret) - break; - printk("%s:ret=%d,fail to set gpio and set again,i=%d\n",__FUNCTION__,ret,i); - } + gpio_direction_output(data->gpio, data->active_low ? !value : !!value); + if (value > 0) { - value += data->adjust_time; if (value > data->max_timeout) value = data->max_timeout; + hrtimer_start(&data->timer, ktime_set(value / 1000, (value % 1000) * 1000000), HRTIMER_MODE_REL); } + + spin_unlock_irqrestore(&data->lock, flags); } static int timed_gpio_probe(struct platform_device *pdev) @@ -155,17 +125,10 @@ static int timed_gpio_probe(struct platform_device *pdev) gpio_dat->gpio = cur_gpio->gpio; gpio_dat->max_timeout = cur_gpio->max_timeout; gpio_dat->active_low = cur_gpio->active_low; - gpio_dat->adjust_time = cur_gpio->adjust_time; gpio_direction_output(gpio_dat->gpio, gpio_dat->active_low); } -#if (GPIO_TYPE == 1) - INIT_WORK(&gpio_dat->timed_gpio_work, timed_gpio_work_handler); -#endif - platform_set_drvdata(pdev, gpio_data); - wake_lock_init(&gpio_data->irq_wake, WAKE_LOCK_SUSPEND, "timed_gpio_wake"); - gpio_enable(&gpio_data ->dev, 100); - printk("%s\n",__FUNCTION__); + platform_set_drvdata(pdev, gpio_data); return 0; } @@ -205,7 +168,7 @@ static void __exit timed_gpio_exit(void) platform_driver_unregister(&timed_gpio_driver); } -subsys_initcall(timed_gpio_init); +module_init(timed_gpio_init); module_exit(timed_gpio_exit); MODULE_AUTHOR("Mike Lockwood "); diff --git a/drivers/staging/android/timed_gpio.h b/drivers/staging/android/timed_gpio.h index c8487df9a109..a0e15f8be3f7 100644 --- a/drivers/staging/android/timed_gpio.h +++ b/drivers/staging/android/timed_gpio.h @@ -23,7 +23,6 @@ struct timed_gpio { unsigned gpio; int max_timeout; u8 active_low; - int adjust_time; }; struct timed_gpio_platform_data { diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile index d35657238b57..239f050efa35 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile @@ -45,5 +45,3 @@ obj-$(CONFIG_EARLY_PRINTK_DBGP) += early/ obj-$(CONFIG_USB_ATM) += atm/ obj-$(CONFIG_USB_SPEEDTOUCH) += atm/ -obj-$(CONFIG_DWC_OTG) += dwc_otg/ -obj-$(CONFIG_USB_GADGET) += gadget/ diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 9fdaf6c87e03..a096d6f0932b 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -112,7 +112,6 @@ config USB_GADGET_SELECTED choice prompt "USB Peripheral Controller" depends on USB_GADGET - default USB_GADGET_DWC_OTG help A USB device uses a controller to talk to its host. Systems should have only one such upstream link. @@ -506,18 +505,6 @@ config USB_LANGWELL default USB_GADGET select USB_GADGET_SELECTED -config USB_GADGET_DWC_OTG - boolean "Synopsys DWC OTG Controller" - select USB_GADGET_DUALSPEED - help - This driver provides USB Device Controller support for the - Synopsys DesignWare USB OTG Core used on the Rockchip RK28. - -config USB_DWC_OTG - tristate - depends on USB_GADGET_DWC_OTG - default USB_GADGET - select USB_GADGET_SELECTED # # LAST -- dummy/emulated controller @@ -569,9 +556,9 @@ config USB_GADGET_DUALSPEED # USB Gadget Drivers # choice - bool "USB Gadget Drivers" + tristate "USB Gadget Drivers" depends on USB_GADGET && USB_GADGET_SELECTED - default USB_ANDROID + default USB_ETH help A Linux "Gadget Driver" talks to the USB Peripheral Controller driver through the abstract "gadget" API. Some other operating diff --git a/drivers/usb/gadget/android.c b/drivers/usb/gadget/android.c index cbbf691db2b4..a107dd25fc8f 100644 --- a/drivers/usb/gadget/android.c +++ b/drivers/usb/gadget/android.c @@ -54,8 +54,8 @@ MODULE_VERSION("1.0"); static const char longname[] = "Gadget Android"; /* Default vendor and product IDs, overridden by platform data */ -#define VENDOR_ID 0x2207//0x18D1 -#define PRODUCT_ID 0x2910 +#define VENDOR_ID 0x18D1 +#define PRODUCT_ID 0x0001 struct android_dev { struct usb_composite_dev *cdev; @@ -187,7 +187,7 @@ static int android_bind_config(struct usb_configuration *c) { struct android_dev *dev = _android_dev; - printk("android_bind_config\n"); + printk(KERN_DEBUG "android_bind_config\n"); dev->config = c; if (should_bind_functions(dev)) diff --git a/drivers/usb/gadget/f_adb.c b/drivers/usb/gadget/f_adb.c index 827d1b931271..a0b0774b9556 100644 --- a/drivers/usb/gadget/f_adb.c +++ b/drivers/usb/gadget/f_adb.c @@ -77,7 +77,7 @@ static struct usb_endpoint_descriptor adb_highspeed_in_desc = { .bDescriptorType = USB_DT_ENDPOINT, .bEndpointAddress = USB_DIR_IN, .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = __constant_cpu_to_le16(64), + .wMaxPacketSize = __constant_cpu_to_le16(512), }; static struct usb_endpoint_descriptor adb_highspeed_out_desc = { diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 3c78083bf57c..9e37e0863143 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -302,32 +302,6 @@ #define FUNCTION_NAME "usb_mass_storage" #endif -#ifdef CONFIG_ARCH_RK29 -/* flush after every 4 meg of writes to avoid excessive block level caching */ -#define MAX_UNFLUSHED_BYTES (64 * 1024)// (4 * 1024 * 1024) //original value is 4MB,Modifyed by xbw at 2011-08-18 -#define MAX_UNFLUSHED_PACKETS 4//16 - -#include -#include -#include - -static int usb_msc_connected; /*usb charge status*/ - -static void set_msc_connect_flag( int connected ) -{ - printk("%s status = %d 20101216\n" , __func__, connected); - if( usb_msc_connected == connected ) - return; - usb_msc_connected = connected;//usb mass storage is ok -} - -int get_msc_connect_flag( void ) -{ - return usb_msc_connected; -} -EXPORT_SYMBOL(get_msc_connect_flag); -#endif - /*------------------------------------------------------------------------*/ #define FSG_DRIVER_DESC "Mass Storage Function" @@ -813,13 +787,6 @@ static int do_read(struct fsg_common *common) amount = min(amount, (unsigned int) PAGE_CACHE_SIZE - partial_page); - /* kever@rk - * max size for dwc_otg ctonroller is 64(max pkt sizt) * 1023(pkt) - * because of the DOEPTSIZ.PKTCNT has only 10 bits - */ - if((common->gadget->speed != USB_SPEED_HIGH)&&(amount >0x8000)) - amount = 0x8000; - /* Wait for the next buffer to become available */ bh = common->next_buffhd_to_fill; while (bh->state != BUF_STATE_EMPTY) { @@ -992,13 +959,6 @@ static int do_write(struct fsg_common *common) amount_left_to_req -= amount; if (amount_left_to_req == 0) get_some_more = 0; - - /* kever@rk - * max size for dwc_otg ctonroller is 64(max pkt sizt) * 1023(pkt) - * because of the DOEPTSIZ.PKTCNT has only 10 bits - */ - if((common->gadget->speed != USB_SPEED_HIGH)&&(amount >0x8000)) - amount = 0x8000; /* amount is always divisible by 512, hence by * the bulk-out maxpacket size */ @@ -1065,15 +1025,6 @@ static int do_write(struct fsg_common *common) amount_left_to_write -= nwritten; common->residue -= nwritten; -#ifdef MAX_UNFLUSHED_PACKETS - curlun->unflushed_packet ++; - curlun->unflushed_bytes += nwritten; - if( (curlun->unflushed_packet >= MAX_UNFLUSHED_PACKETS) || (curlun->unflushed_bytes >= MAX_UNFLUSHED_BYTES)) { - fsg_lun_fsync_sub(curlun); - curlun->unflushed_packet = 0; - curlun->unflushed_bytes = 0; - } -#endif /* If an error occurred, report it and its position */ if (nwritten < amount) { curlun->sense_data = SS_WRITE_ERROR; @@ -1989,153 +1940,6 @@ static int check_command(struct fsg_common *common, int cmnd_size, } -#ifdef CONFIG_ARCH_RK29 -static void deferred_restart(struct work_struct *dummy) -{ - sys_sync(); - kernel_restart("loader"); -} -static DECLARE_WORK(restart_work, deferred_restart); - -typedef struct tagLoaderParam -{ - int tag; - int length; - char parameter[1]; - int crc; -} PARM_INFO; -#define PARM_TAG 0x4D524150 -#define MSC_EXT_DBG 1 -extern int GetParamterInfo(char * pbuf , int len); - -/* the buf is bh->buf,it is large enough. */ -static char * get_param_tag( char* buf , const char* tag ) -{ - PARM_INFO *pi; - int i; - char *pp = buf+256; - char *spp; - i = GetParamterInfo( pp , 1024 ); - pi = (PARM_INFO*)pp; - if( pi->tag != PARM_TAG ){ -error_out: - printk("paramter error,tag=0x%x\n" , pi->tag ); - return NULL; - } - if( pi->length+sizeof(PARM_INFO) > i ) { - GetParamterInfo( pp , pi->length+sizeof(PARM_INFO) + 511 ); - } - pp = strstr( pi->parameter , tag ); - if( !pp ) goto error_out; - pp += strlen(tag); // sizeof "MACHINE_MODEL:" - while( *pp == ' ' || *pp == '\t' ) { - if(pp - pi->parameter >= pi->length) - break; - pp++; - } - spp = pp; - while( *pp != 0x0d && *pp != 0x0a ) { - if(pp - pi->parameter >= pi->length) - break; - pp++; - } - *pp = 0; - if( spp == pp ) return NULL; - return spp; -} - -static int do_get_product_name(int ret ,char *buf) -{ - char *tag = "MACHINE_MODEL:"; - char *pname; - #if MSC_EXT_DBG - char tbuf[1300]; - if( buf == NULL ) buf = tbuf; - #endif - memset( buf , 0 , ret ); - pname = get_param_tag( buf , tag ); - if( pname ){ - strcpy( buf , pname); - } - #if MSC_EXT_DBG - printk("%s%s\n" , tag , buf ); - #endif - return ret; -} - -static int do_get_versions( int ret ,char* buf ) -{ - /* get boot version and fireware version from cmdline - * bootver=2010-07-08#4.02 firmware_ver=1.0.0 // Firmware Ver:16.01.0000 - * return format: 0x02 0x04 0x00 0x00 0x00 0x01 - * RK29: bootver=2011-07-18#2.05 firmware_ver=0.2.3 (==00.02.0003) - * for the old loader,the firmware_ver may be empty,so get the fw ver from paramter. - */ -#define ASC_BCD0( c ) (((c-'0'))&0xf) -#define ASC_BCD1( c ) (((c-'0')<<4)&0xf0) - - char *ver = buf; - char *p_l , *p_f; - char *l_tag = "bootver="; - char *fw_tag = "FIRMWARE_VER:"; - - #if MSC_EXT_DBG - char tbuf[1300]; - if( ver == NULL ) ver = tbuf; - #endif - - memset( ver , 0x00 , ret ); - p_l = strstr( saved_command_line , l_tag ); - if( !p_l ) { - return ret; - } - p_l+=strlen( l_tag ); - if( (p_l = strchr( p_l,'#')) ) { - p_l++; - if( p_l[1] == '.' ) { - ver[1] = ASC_BCD0(p_l[0]); - p_l+=2; - } else { - ver[1] = ASC_BCD1(p_l[0])|ASC_BCD0(p_l[1]); - p_l+=3; - } - ver[0] = ASC_BCD1(p_l[0])|ASC_BCD0(p_l[1]); - } - - p_f = get_param_tag( ver , fw_tag ); - if( !p_f ) return ret; - - if( p_f[1] == '.' ) { - ver[5] = ASC_BCD0(p_f[0]); - p_f+=2; - } else { - ver[5] = ASC_BCD1(p_f[0])|ASC_BCD0(p_f[1]); - p_f+=3; - } - if( p_f[1] == '.' ) { - ver[4] = ASC_BCD0(p_f[0]); - p_f+=2; - } else { - ver[4] = ASC_BCD1(p_f[0])|ASC_BCD0(p_f[1]); - p_f+=3; - } - ver[2] = ASC_BCD0(p_f[0]); - p_f++; - if( p_f[0] != ' ' ){ - ver[2] |= ASC_BCD1(p_f[0]); - p_f++; - } - // only support 2 byte version. - ver[3] = 0; - - #if MSC_EXT_DBG - printk("VERSION:%02x %02x %02x %02x %02x %02x\n" , - ver[0],ver[1],ver[2],ver[3],ver[4],ver[5]); - #endif - return ret; -} -#endif - static int do_scsi_command(struct fsg_common *common) { struct fsg_buffhd *bh; @@ -2143,9 +1947,6 @@ static int do_scsi_command(struct fsg_common *common) int reply = -EINVAL; int i; static char unknown[16]; -#ifdef CONFIG_ARCH_RK29 - struct fsg_common *fsg = common; -#endif dump_cdb(common); @@ -2334,11 +2135,7 @@ static int do_scsi_command(struct fsg_common *common) (1<<1) | (0xf<<2) | (3<<7), 1, "VERIFY"); if (reply == 0) -#ifdef CONFIG_ARCH_RK29 - reply = 0; //zyf 20100302 -#else reply = do_verify(common); -#endif break; case SC_WRITE_6: @@ -2392,26 +2189,6 @@ unknown_cmnd: reply = -EINVAL; } break; -#ifdef CONFIG_ARCH_RK29 - case 0xff: - if( fsg->cmnd[1] != 0xe0 || - fsg->cmnd[2] != 0xff || fsg->cmnd[3] != 0xff || - fsg->cmnd[4] != 0xff ) - break; - if (fsg->cmnd_size >= 6 && fsg->cmnd[5] == 0xfe) { - schedule_work(&restart_work); - } - else if ( fsg->cmnd[5] == 0xf3 ) { - fsg->data_size_from_cmnd = fsg->data_size; - /* get product name from parameter section */ - reply = do_get_product_name( fsg->data_size,bh->buf ); - } - else if ( fsg->cmnd[5] == 0xff ){ - fsg->data_size_from_cmnd = fsg->data_size; - reply = do_get_versions( fsg->data_size,bh->buf ); - } - break; -#endif } up_read(&common->filesem); @@ -2666,8 +2443,6 @@ static void fsg_disable(struct usb_function *f) struct fsg_dev *fsg = fsg_from_func(f); fsg->common->new_fsg = NULL; raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE); - // yk 201009 - set_msc_connect_flag(0); } @@ -3399,60 +3174,6 @@ fsg_common_from_params(struct fsg_common *common, #ifdef CONFIG_USB_ANDROID_MASS_STORAGE -#ifdef CONFIG_ARCH_RK29 -static enum power_supply_property usb_props[] = { -// POWER_SUPPLY_PROP_STATUS, - POWER_SUPPLY_PROP_ONLINE, -}; - -static int usb_get_property(struct power_supply *psy, - enum power_supply_property psp, - union power_supply_propval *val) -{ - int ret = 0; - - switch (psp) { - case POWER_SUPPLY_PROP_ONLINE: -#ifndef CONFIG_DWC_OTG_HOST_ONLY - val->intval = get_msc_connect_flag(); -#else - val->intval = 0; -#endif - break; - default: - return -EINVAL; - } - - return ret; -} - -static int usb_power_supply_register(struct device* parent) -{ - struct power_supply *ps; - int retval = 0; - - ps = kzalloc(sizeof(*ps), GFP_KERNEL); - if (!ps) { - dev_err(parent, "failed to allocate power supply data\n"); - retval = -ENOMEM; - goto out; - } - ps->name = "usb"; - ps->type = POWER_SUPPLY_TYPE_USB; - ps->properties = usb_props; - ps->num_properties = ARRAY_SIZE(usb_props); - ps->get_property = usb_get_property; - ps->external_power_changed = NULL; - retval = power_supply_register(parent, ps); - if (retval) { - dev_err(parent, "failed to register battery\n"); - goto out; - } -out: - return retval; -} -#endif - static struct fsg_config fsg_cfg; static int fsg_probe(struct platform_device *pdev) @@ -3477,21 +3198,7 @@ static int fsg_probe(struct platform_device *pdev) fsg_cfg.can_stall = 0; fsg_cfg.pdev = pdev; -#ifdef CONFIG_ARCH_RK29 -{ - /* - * Initialize usb power supply - */ - int retval = usb_power_supply_register(&pdev->dev); - if (retval != 0) { - dev_err(&pdev->dev, "usb_power_supply_register failed\n"); - } - - return retval; -} -#else return 0; -#endif } static struct platform_driver fsg_platform_driver = { diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c index 5bf801b1c8bc..2771166ac69a 100644 --- a/drivers/usb/gadget/storage_common.c +++ b/drivers/usb/gadget/storage_common.c @@ -276,10 +276,6 @@ struct fsg_lun { struct file *filp; loff_t file_length; loff_t num_sectors; -#ifdef MAX_UNFLUSHED_PACKETS - unsigned int unflushed_packet; - unsigned int unflushed_bytes; -#endif unsigned int initially_ro:1; unsigned int ro:1; @@ -809,9 +805,6 @@ static ssize_t fsg_store_file(struct device *dev, struct device_attribute *attr, struct rw_semaphore *filesem = dev_get_drvdata(dev); int rc = 0; -#ifdef CONFIG_ARCH_RK29 - printk("store_file: \"%s\"\n", buf); -#endif #ifndef CONFIG_USB_ANDROID_MASS_STORAGE /* disabled in android because we need to allow closing the backing file diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 01ef86983a2b..12d5f82616a3 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -308,7 +308,6 @@ static void option_instat_callback(struct urb *urb); #define ZTE_PRODUCT_CDMA_TECH 0xfffe #define ZTE_PRODUCT_AC8710 0xfff1 #define ZTE_PRODUCT_AC2726 0xfff5 -#define ZTE_PRODUCT_AC100 0x0094 #define ZTE_PRODUCT_AC8710T 0xffff /* ZTE PRODUCTS -- alternate vendor ID */ @@ -383,11 +382,6 @@ static void option_instat_callback(struct urb *urb); #define HAIER_VENDOR_ID 0x201e #define HAIER_PRODUCT_CE100 0x2009 -/* Thinkwill products */ -#define THINKWILL_VENDOR_ID 0x19f5 -#define THINKWILL_PRODUCT_ID 0x9909 -#define THINKWILL_MI900_PRODUCT_ID 0x9013 - #define CINTERION_VENDOR_ID 0x0681 /* Olivetti products */ @@ -398,13 +392,6 @@ static void option_instat_callback(struct urb *urb); #define CELOT_VENDOR_ID 0x211f #define CELOT_PRODUCT_CT680M 0x6801 -/* leadcore LC1808*/ -#define LEADCORE_VENDOR_ID 0x1ab7 -#define LEADCORE_PRODUCT_LC1808 0x2200 -/*展讯模组*/ -#define SC8800G_VENDOR_ID 0x067b -#define SC8800G_PRODUCT_ID 0x2303 - /* some devices interfaces need special handling due to a number of reasons */ enum option_blacklist_reason { OPTION_BLACKLIST_NONE = 0, @@ -427,10 +414,6 @@ static const struct option_blacklist_info four_g_w14_blacklist = { static const struct usb_device_id option_ids[] = { { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, - { USB_DEVICE(THINKWILL_VENDOR_ID,THINKWILL_PRODUCT_ID)}, - - { USB_DEVICE(THINKWILL_VENDOR_ID,THINKWILL_MI900_PRODUCT_ID)}, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_LIGHT) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_QUAD) }, @@ -460,7 +443,6 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLX) }, { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GKE) }, { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLE) }, - { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600)}, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220BIS, 0xff, 0xff, 0xff) }, @@ -918,11 +900,6 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xFFED, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xFFFE, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xFFEB, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xF006, 0xff, 0xff, 0xff) }, - { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_AC100)}, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710T, 0xff, 0xff, 0xff) }, { USB_DEVICE(ZTE_VENDOR_ID2, ZTE_PRODUCT_MF_330) }, { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, @@ -962,34 +939,6 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100F) }, { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1011)}, { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1012)}, - { USB_DEVICE(LEADCORE_VENDOR_ID, LEADCORE_PRODUCT_LC1808) }, //zzc - { USB_DEVICE(SC8800G_VENDOR_ID,SC8800G_PRODUCT_ID)}, - { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100) }, - { USB_DEVICE(CELOT_VENDOR_ID, CELOT_PRODUCT_CT680M) }, /* CT-650 CDMA 450 1xEVDO modem */ - -// cmy: - { USB_DEVICE(0x0685, 0x6000) }, - { USB_DEVICE(0x1E89, 0x1E16) }, - { USB_DEVICE(0x7693, 0x0001) }, - { USB_DEVICE(0x1D09, 0x4308) }, - { USB_DEVICE(0x1234, 0x0033) }, - { USB_DEVICE(0xFEED, 0x0001) }, - { USB_DEVICE(ALCATEL_VENDOR_ID, 0x0017) }, - { USB_DEVICE(0x1C9E, 0x9E00) }, - { USB_DEVICE(0x1C9E, 0xF000) }, - { USB_DEVICE(0x19D2, 0x1303) }, - { USB_DEVICE(0x19F5, 0x9013) }, // MW100 - { USB_DEVICE(0x21F5, 0x2008) }, - { USB_DEVICE(0x12D1, 0x1D09) }, - { USB_DEVICE(0x04CC, 0x2259) }, - { USB_DEVICE(0x04CC, 0x226E) }, - { USB_DEVICE(0x04CC, 0x225A) }, - { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x0015) }, - { USB_DEVICE(ALCATEL_VENDOR_ID, 0x00b7) }, - { USB_DEVICE(ZTE_VENDOR_ID, 0xFFFF) }, - { USB_DEVICE(LEADCORE_VENDOR_ID, 0x5700) }, - { USB_DEVICE(LEADCORE_VENDOR_ID, 0x6341) }, - { USB_DEVICE(CINTERION_VENDOR_ID, 0x0047) }, { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100) }, { USB_DEVICE(CELOT_VENDOR_ID, CELOT_PRODUCT_CT680M) }, /* CT-650 CDMA 450 1xEVDO modem */ diff --git a/drivers/video/backlight/wm831x_bl.c b/drivers/video/backlight/wm831x_bl.c index 920a23b9b949..08fd87f3aecc 100755 --- a/drivers/video/backlight/wm831x_bl.c +++ b/drivers/video/backlight/wm831x_bl.c @@ -18,46 +18,21 @@ #include #include #include -#ifdef CONFIG_HAS_EARLYSUSPEND -#include -#endif -#include -#include -#define BL_SET 255 -#define BL_MISC_VALUE 20 -#define BL_INIT_VALUE 102 + struct wm831x_backlight_data { struct wm831x *wm831x; int isink_reg; int current_brightness; -#ifdef CONFIG_HAS_EARLYSUSPEND - struct early_suspend early_suspend; - struct delayed_work work; - int suspend_flag; - int shutdown_flag; -#endif }; -#define TS_POLL_DELAY (10000*1000*1000) -int wm831x_bright = 0; -int max_tp = 0; -#ifdef CONFIG_HAS_EARLYSUSPEND -static struct backlight_device *gwm831x_bl; -static struct wm831x_backlight_data *gwm831x_data; -#endif + static int wm831x_backlight_set(struct backlight_device *bl, int brightness) { struct wm831x_backlight_data *data = bl_get_data(bl); struct wm831x *wm831x = data->wm831x; -// int power_up = !data->current_brightness && brightness; -// int power_down = data->current_brightness && !brightness; - int power_up; - int power_down; + int power_up = !data->current_brightness && brightness; + int power_down = data->current_brightness && !brightness; int ret; - int bright_tp; - bright_tp =( max_tp*brightness)/BL_SET; - power_up =!data->current_brightness && bright_tp; - power_down = data->current_brightness && !bright_tp; if (power_up) { /* Enable the ISINK */ ret = wm831x_set_bits(wm831x, data->isink_reg, @@ -88,7 +63,7 @@ static int wm831x_backlight_set(struct backlight_device *bl, int brightness) /* Set the new brightness */ ret = wm831x_set_bits(wm831x, data->isink_reg, - WM831X_CS1_ISEL_MASK, bright_tp); + WM831X_CS1_ISEL_MASK, brightness); if (ret < 0) goto err; @@ -119,21 +94,7 @@ err: static int wm831x_backlight_update_status(struct backlight_device *bl) { int brightness = bl->props.brightness; - if (brightness<=BL_MISC_VALUE) { - brightness = 8*brightness; - } - else if (brightness<=BL_INIT_VALUE) { - brightness = 31*brightness/41 + 145; - } - else { - brightness = 33*brightness/153 + 200; - } - if(gwm831x_data->suspend_flag == 1) - brightness = 0; - if (gwm831x_data->shutdown_flag == 1) - brightness = 0; - if (bl->props.power != FB_BLANK_UNBLANK) brightness = 0; @@ -143,8 +104,6 @@ static int wm831x_backlight_update_status(struct backlight_device *bl) if (bl->props.state & BL_CORE_SUSPENDED) brightness = 0; - printk("backlight brightness=%d\n", brightness); - return wm831x_backlight_set(bl, brightness); } @@ -159,40 +118,6 @@ static const struct backlight_ops wm831x_backlight_ops = { .update_status = wm831x_backlight_update_status, .get_brightness = wm831x_backlight_get_brightness, }; -#ifdef CONFIG_HAS_EARLYSUSPEND -static void wm831x_bl_work(struct work_struct *work) -{ - //struct wm831x_backlight_data *wm831x_data = container_of(work, struct wm831x_backlight_data, - //work.work); - backlight_update_status(gwm831x_bl); -} - -static void wm831x_bl_suspend(struct early_suspend *h) -{ - struct wm831x_backlight_data *wm831x_data; - wm831x_data = container_of(h, struct wm831x_backlight_data, early_suspend); - wm831x_data->suspend_flag = 1; - - schedule_delayed_work(&wm831x_data->work, msecs_to_jiffies(100)); -} - - -static void wm831x_bl_resume(struct early_suspend *h) -{ - struct wm831x_backlight_data *wm831x_data; - wm831x_data = container_of(h, struct wm831x_backlight_data, early_suspend); - wm831x_data->suspend_flag = 0; - - schedule_delayed_work(&wm831x_data->work, msecs_to_jiffies(100)); -} - -#endif - -int rk29_backlight_ctrl(int open) -{ - gwm831x_data->suspend_flag = !open; - schedule_delayed_work(&gwm831x_data->work, 0); -} static int wm831x_backlight_probe(struct platform_device *pdev) { @@ -228,7 +153,7 @@ static int wm831x_backlight_probe(struct platform_device *pdev) return -EINVAL; } max_isel = i - 1; - max_tp = max_isel; + if (pdata->max_uA != wm831x_isinkv_values[max_isel]) dev_warn(&pdev->dev, "Maximum current is %duA not %duA as requested\n", @@ -268,7 +193,7 @@ static int wm831x_backlight_probe(struct platform_device *pdev) data->current_brightness = 0; data->isink_reg = isink_reg; - props.max_brightness = BL_SET; + props.max_brightness = max_isel; bl = backlight_device_register("wm831x", &pdev->dev, data, &wm831x_backlight_ops, &props); if (IS_ERR(bl)) { @@ -277,26 +202,15 @@ static int wm831x_backlight_probe(struct platform_device *pdev) return PTR_ERR(bl); } - bl->props.brightness = BL_INIT_VALUE; + bl->props.brightness = max_isel; platform_set_drvdata(pdev, bl); -#ifdef CONFIG_HAS_EARLYSUSPEND - data->early_suspend.level = ~0x0; - data->early_suspend.suspend = wm831x_bl_suspend; - data->early_suspend.resume = wm831x_bl_resume; - register_early_suspend(&data->early_suspend); - INIT_DELAYED_WORK(&data->work, wm831x_bl_work); - gwm831x_bl = bl; - gwm831x_data = data; -#endif - - /* Disable the DCDC if it was started so we can bootstrap */ wm831x_set_bits(wm831x, WM831X_DCDC_ENABLE, WM831X_DC4_ENA, 0); - //backlight_update_status(bl); - schedule_delayed_work(&data->work, msecs_to_jiffies(100)); + + backlight_update_status(bl); return 0; } @@ -307,24 +221,10 @@ static int wm831x_backlight_remove(struct platform_device *pdev) struct wm831x_backlight_data *data = bl_get_data(bl); backlight_device_unregister(bl); -#ifdef CONFIG_HAS_EARLYSUSPEND - unregister_early_suspend(&data->early_suspend); -#endif kfree(data); return 0; } -static void wm831x_backlight_shutdown(struct platform_device *pdev) -{ - struct backlight_device *bl = platform_get_drvdata(pdev); - struct wm831x_backlight_data *data = bl_get_data(bl); - - printk("enter %s\n", __func__); - data->shutdown_flag = 1; - wm831x_backlight_update_status(bl); - return; -} - static struct platform_driver wm831x_backlight_driver = { .driver = { .name = "wm831x-backlight", @@ -332,7 +232,6 @@ static struct platform_driver wm831x_backlight_driver = { }, .probe = wm831x_backlight_probe, .remove = wm831x_backlight_remove, - .shutdown = wm831x_backlight_shutdown, }; static int __init wm831x_backlight_init(void) diff --git a/fs/fat/dir.c b/fs/fat/dir.c index bf11b1cfa7fe..2242ac239866 100644 --- a/fs/fat/dir.c +++ b/fs/fat/dir.c @@ -98,7 +98,7 @@ next: *bh = sb_bread(sb, phys); if (*bh == NULL) { - printk(KERN_DEBUG "FAT: Directory bread(block %llu) failed\n", + printk(KERN_ERR "FAT: Directory bread(block %llu) failed\n", (llu)phys); /* skip this block */ *pos = (iblock + 1) << sb->s_blocksize_bits; diff --git a/fs/fat/fatent.c b/fs/fat/fatent.c index 617b12270940..81184d3b75a3 100644 --- a/fs/fat/fatent.c +++ b/fs/fat/fatent.c @@ -95,7 +95,7 @@ static int fat12_ent_bread(struct super_block *sb, struct fat_entry *fatent, err_brelse: brelse(bhs[0]); err: - printk(KERN_DEBUG "FAT: FAT read failed (blocknr %llu)\n", (llu)blocknr); + printk(KERN_ERR "FAT: FAT read failed (blocknr %llu)\n", (llu)blocknr); return -EIO; } @@ -108,7 +108,7 @@ static int fat_ent_bread(struct super_block *sb, struct fat_entry *fatent, fatent->fat_inode = MSDOS_SB(sb)->fat_inode; fatent->bhs[0] = sb_bread(sb, blocknr); if (!fatent->bhs[0]) { - printk(KERN_DEBUG "FAT: FAT read failed (blocknr %llu)\n", + printk(KERN_ERR "FAT: FAT read failed (blocknr %llu)\n", (llu)blocknr); return -EIO; } diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 894cb48704a2..ab81a7e31157 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c @@ -1283,7 +1283,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, sb_min_blocksize(sb, 512); bh = sb_bread(sb, 0); if (bh == NULL) { - printk(KERN_DEBUG "FAT: unable to read boot sector\n"); + printk(KERN_ERR "FAT: unable to read boot sector\n"); goto out_fail; } @@ -1349,7 +1349,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, } bh = sb_bread(sb, 0); if (bh == NULL) { - printk(KERN_DEBUG "FAT: unable to read boot sector" + printk(KERN_ERR "FAT: unable to read boot sector" " (logical sector size = %lu)\n", sb->s_blocksize); goto out_fail; diff --git a/fs/yaffs2/yaffs_fs.c b/fs/yaffs2/yaffs_fs.c index 62933f89d6f1..11eca48d064f 100644 --- a/fs/yaffs2/yaffs_fs.c +++ b/fs/yaffs2/yaffs_fs.c @@ -2633,9 +2633,6 @@ static struct super_block *yaffs_internal_read_super(int yaffsVersion, param->nReservedBlocks = 5; param->nShortOpCaches = (options.no_cache) ? 0 : 10; param->inbandTags = options.inband_tags; -#if defined (CONFIG_ARCH_RK2818) || (CONFIG_ARCH_RK29) - dev->inbandTags = 1; -#endif #ifdef CONFIG_YAFFS_DISABLE_LAZY_LOAD param->disableLazyLoad = 1; diff --git a/fs/yaffs2/yaffs_mtdif2.c b/fs/yaffs2/yaffs_mtdif2.c index 8abf2491d7a2..c1d447819970 100644 --- a/fs/yaffs2/yaffs_mtdif2.c +++ b/fs/yaffs2/yaffs_mtdif2.c @@ -179,12 +179,7 @@ int nandmtd2_ReadChunkWithTagsFromNAND(yaffs_Device *dev, int chunkInNAND, if (localData) yaffs_ReleaseTempBuffer(dev, data, __LINE__); -#ifdef CONFIG_MTD_NAND_RK29 - //dxj 20101221@ if return -EBADMSG then i think the page is badchunk so just set the eccResult=YAFFS_ECC_RESULT_NO_ERROR - if (tags && retval == -EBADMSG /*&& tags->eccResult == YAFFS_ECC_RESULT_NO_ERROR*/) { -#else if (tags && retval == -EBADMSG && tags->eccResult == YAFFS_ECC_RESULT_NO_ERROR) { -#endif tags->eccResult = YAFFS_ECC_RESULT_UNFIXED; dev->eccUnfixed++; } diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 493791bdb5c4..4bae0b72ed3c 100755 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -57,17 +57,6 @@ struct i2c_board_info; * transmit an arbitrary number of messages without interruption. * @count must be be less than 64k since msg.len is u16. */ -#if defined (CONFIG_I2C_RK2818) || defined(CONFIG_I2C_RK29) -/* If everything went ok, return 'count' transmitted, else error code. */ -extern int i2c_master_normal_send(struct i2c_client *client,const char *buf ,int count, int scl_rate); -extern int i2c_master_normal_recv(struct i2c_client *client, char *buf ,int count, int scl_rate); -extern int i2c_master_reg8_send(struct i2c_client *client, const char reg, const char *buf, int count, int scl_rate); -extern int i2c_master_reg8_recv(struct i2c_client *client, const char reg, char *buf, int count, int scl_rate); -extern int i2c_master_reg16_send(struct i2c_client *client, const short regs, const short *buf, int count, int scl_rate); -extern int i2c_master_reg16_recv(struct i2c_client *client, const short regs, short *buf, int count, int scl_rate); -extern int i2c_suspended(struct i2c_adapter *adap); -#endif - extern int i2c_master_send(struct i2c_client *client, const char *buf, int count); extern int i2c_master_recv(struct i2c_client *client, char *buf, int count); @@ -217,7 +206,6 @@ struct i2c_client { struct i2c_driver *driver; /* and our access routines */ struct device dev; /* the device structure */ int irq; /* irq issued by device */ - int udelay; struct list_head detected; }; #define to_i2c_client(d) container_of(d, struct i2c_client, dev) @@ -271,7 +259,6 @@ struct i2c_board_info { struct device_node *of_node; #endif int irq; - int udelay; //add by kfx }; /** @@ -527,13 +514,8 @@ struct i2c_msg { #define I2C_M_IGNORE_NAK 0x1000 /* if I2C_FUNC_PROTOCOL_MANGLING */ #define I2C_M_NO_RD_ACK 0x0800 /* if I2C_FUNC_PROTOCOL_MANGLING */ #define I2C_M_RECV_LEN 0x0400 /* length will be first received byte */ -#define I2C_M_NEED_DELAY 0x0020 // add by kfx -#define I2C_M_REG8_DIRECT 0x0040 // add by kfx __u16 len; /* msg length */ __u8 *buf; /* pointer to msg data */ - __u32 scl_rate; // add by kfx - int udelay; //add by kfx - __u16 read_type; }; /* To determine what functionality is present */ diff --git a/include/linux/mfd/wm831x/core.h b/include/linux/mfd/wm831x/core.h index b702517a76bc..eb5bd4e0e03c 100644 --- a/include/linux/mfd/wm831x/core.h +++ b/include/linux/mfd/wm831x/core.h @@ -17,8 +17,6 @@ #include #include -#include -#include /* * Register values. @@ -239,15 +237,6 @@ struct regulator_dev; #define WM831X_NUM_IRQ_REGS 5 -#define WM831X_IRQ_LIST 1 -enum wm831x_parent { - WM8310 = 0x8310, - WM8311 = 0x8311, - WM8312 = 0x8312, - WM8320 = 0x8320, - WM8321 = 0x8321, - WM8325 = 0x8325, -}; struct wm831x { struct mutex io_lock; @@ -261,19 +250,7 @@ struct wm831x { void *control_data; int irq; /* Our chip IRQ */ - int flag_suspend; - spinlock_t flag_lock; struct mutex irq_lock; - struct workqueue_struct *irq_wq; - struct delayed_work irq_work; - struct wake_lock irq_wake; - struct wake_lock handle_wake; -#if WM831X_IRQ_LIST - struct workqueue_struct *handle_wq; - struct work_struct handle_work; - spinlock_t work_lock; - struct list_head handle_queue; -#endif unsigned int irq_base; int irq_masks_cur[WM831X_NUM_IRQ_REGS]; /* Currently active value */ int irq_masks_cache[WM831X_NUM_IRQ_REGS]; /* Cached hardware value */ @@ -297,39 +274,6 @@ struct wm831x { unsigned int locked:1; }; -#define WM831X_DCDC_MAX_NAME 6 -#define WM831X_LDO_MAX_NAME 6 -#define WM831X_ISINK_MAX_NAME 7 - -struct wm831x_dcdc { - char name[WM831X_DCDC_MAX_NAME]; - struct regulator_desc desc; - int base; - struct wm831x *wm831x; - struct regulator_dev *regulator; - int dvs_gpio; - int dvs_gpio_state; - int on_vsel; - int dvs_vsel; -}; - -struct wm831x_ldo { - char name[WM831X_LDO_MAX_NAME]; - struct regulator_desc desc; - int base; - struct wm831x *wm831x; - struct regulator_dev *regulator; -}; - -struct wm831x_isink { - char name[WM831X_ISINK_MAX_NAME]; - struct regulator_desc desc; - int reg; - struct wm831x *wm831x; - struct regulator_dev *regulator; -}; - - /* Device I/O API */ int wm831x_reg_read(struct wm831x *wm831x, unsigned short reg); int wm831x_reg_write(struct wm831x *wm831x, unsigned short reg, @@ -341,13 +285,6 @@ int wm831x_set_bits(struct wm831x *wm831x, unsigned short reg, int wm831x_bulk_read(struct wm831x *wm831x, unsigned short reg, int count, u16 *buf); -int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq); -void wm831x_device_exit(struct wm831x *wm831x); -int wm831x_device_suspend(struct wm831x *wm831x); -int wm831x_device_resume(struct wm831x *wm831x); -int wm831x_device_shutdown(struct wm831x *wm831x); -int wm831x_read_usb(struct wm831x *wm831x); -int wm831x_device_restart(struct wm831x *wm831x); int wm831x_irq_init(struct wm831x *wm831x, int irq); void wm831x_irq_exit(struct wm831x *wm831x); diff --git a/include/linux/mfd/wm831x/pdata.h b/include/linux/mfd/wm831x/pdata.h index 92cefe8721e1..fd322aca33ba 100755 --- a/include/linux/mfd/wm831x/pdata.h +++ b/include/linux/mfd/wm831x/pdata.h @@ -39,8 +39,6 @@ struct wm831x_battery_pdata { int eoc_iterm; /** End of trickle charge current, in mA */ int fast_ilim; /** Fast charge current limit, in mA */ int timeout; /** Charge cycle timeout, in minutes */ - int syslo; /** syslo threshold, in mV**/ - int sysok; /** sysok threshold, in mV**/ }; /** @@ -97,22 +95,6 @@ struct wm831x_watchdog_pdata { int update_gpio; unsigned int software:1; }; -struct wm831x_gpio_keys_button { - /* Configuration parameters */ - int code; /* input event code (KEY_*, SW_*) */ - int gpio; - int active_low; - char *desc; - int type; /* input event type (EV_KEY, EV_SW) */ - int wakeup; /* configure the button as a wake-up source */ - int debounce_interval; /* debounce ticks interval in msecs */ -}; - -struct wm831x_gpio_keys_pdata { - struct wm831x_gpio_keys_button *buttons; - int nbuttons; - unsigned int rep:1; /* enable input subsystem auto repeat */ -}; #define WM831X_MAX_STATUS 2 #define WM831X_MAX_DCDC 4 @@ -125,14 +107,7 @@ struct wm831x_pdata { int (*pre_init)(struct wm831x *wm831x); /** Called after subdevices are set up */ int (*post_init)(struct wm831x *wm831x); - /** Called before subdevices are power down */ - int (*last_deinit)(struct wm831x *wm831x); - //add by sxj - unsigned int gpio_pin_num; - struct rk2818_gpio_expander_info *settinginfo; - int settinginfolen; - int (*pin_type_init)(struct wm831x *wm831x); - //above add by sxj + int irq_base; int gpio_base; struct wm831x_backlight_pdata *backlight; @@ -140,9 +115,6 @@ struct wm831x_pdata { struct wm831x_battery_pdata *battery; struct wm831x_touch_pdata *touch; struct wm831x_watchdog_pdata *watchdog; - //add by srt - struct wm831x_gpio_keys_pdata *gpio_keys; - //end by srt /** LED1 = 0 and so on */ struct wm831x_status_pdata *status[WM831X_MAX_STATUS]; diff --git a/include/linux/mfd/wm8994/core.h b/include/linux/mfd/wm8994/core.h index b06ff2846748..de79baee4925 100644 --- a/include/linux/mfd/wm8994/core.h +++ b/include/linux/mfd/wm8994/core.h @@ -15,14 +15,38 @@ #ifndef __MFD_WM8994_CORE_H__ #define __MFD_WM8994_CORE_H__ +#include + struct regulator_dev; struct regulator_bulk_data; #define WM8994_NUM_GPIO_REGS 11 -#define WM8994_NUM_LDO_REGS 2 +#define WM8994_NUM_LDO_REGS 2 +#define WM8994_NUM_IRQ_REGS 2 + +#define WM8994_IRQ_TEMP_SHUT 0 +#define WM8994_IRQ_MIC1_DET 1 +#define WM8994_IRQ_MIC1_SHRT 2 +#define WM8994_IRQ_MIC2_DET 3 +#define WM8994_IRQ_MIC2_SHRT 4 +#define WM8994_IRQ_FLL1_LOCK 5 +#define WM8994_IRQ_FLL2_LOCK 6 +#define WM8994_IRQ_SRC1_LOCK 7 +#define WM8994_IRQ_SRC2_LOCK 8 +#define WM8994_IRQ_AIF1DRC1_SIG_DET 9 +#define WM8994_IRQ_AIF1DRC2_SIG_DET 10 +#define WM8994_IRQ_AIF2DRC_SIG_DET 11 +#define WM8994_IRQ_FIFOS_ERR 12 +#define WM8994_IRQ_WSEQ_DONE 13 +#define WM8994_IRQ_DCS_DONE 14 +#define WM8994_IRQ_TEMP_WARN 15 + +/* GPIOs in the chip are numbered from 1-11 */ +#define WM8994_IRQ_GPIO(x) (x + WM8994_IRQ_TEMP_WARN) struct wm8994 { struct mutex io_lock; + struct mutex irq_lock; struct device *dev; int (*read_dev)(struct wm8994 *wm8994, unsigned short reg, @@ -33,6 +57,11 @@ struct wm8994 { void *control_data; int gpio_base; + int irq_base; + + int irq; + u16 irq_masks_cur[WM8994_NUM_IRQ_REGS]; + u16 irq_masks_cache[WM8994_NUM_IRQ_REGS]; /* Used over suspend/resume */ u16 ldo_regs[WM8994_NUM_LDO_REGS]; @@ -51,4 +80,26 @@ int wm8994_set_bits(struct wm8994 *wm8994, unsigned short reg, int wm8994_bulk_read(struct wm8994 *wm8994, unsigned short reg, int count, u16 *buf); + +/* Helper to save on boilerplate */ +static inline int wm8994_request_irq(struct wm8994 *wm8994, int irq, + irq_handler_t handler, const char *name, + void *data) +{ + if (!wm8994->irq_base) + return -EINVAL; + return request_threaded_irq(wm8994->irq_base + irq, NULL, handler, + IRQF_TRIGGER_RISING, name, + data); +} +static inline void wm8994_free_irq(struct wm8994 *wm8994, int irq, void *data) +{ + if (!wm8994->irq_base) + return; + free_irq(wm8994->irq_base + irq, data); +} + +int wm8994_irq_init(struct wm8994 *wm8994); +void wm8994_irq_exit(struct wm8994 *wm8994); + #endif diff --git a/include/linux/mfd/wm8994/pdata.h b/include/linux/mfd/wm8994/pdata.h index f63b990b366e..add8a1b8bcf0 100644 --- a/include/linux/mfd/wm8994/pdata.h +++ b/include/linux/mfd/wm8994/pdata.h @@ -29,7 +29,7 @@ struct wm8994_ldo_pdata { #define WM8994_CONFIGURE_GPIO 0x8000 #define WM8994_DRC_REGS 5 -#define WM8994_EQ_REGS 19 +#define WM8994_EQ_REGS 20 /** * DRC configurations are specified with a label and a set of register @@ -59,9 +59,6 @@ struct wm8994_retune_mobile_cfg { u16 regs[WM8994_EQ_REGS]; }; -#define PCM_BB 1 -#define NO_PCM_BB 0 - struct wm8994_pdata { int gpio_base; @@ -73,6 +70,7 @@ struct wm8994_pdata { struct wm8994_ldo_pdata ldo[WM8994_NUM_LDO]; + int irq_base; /** Base IRQ number for WM8994, required for IRQs */ int num_drc_cfgs; struct wm8994_drc_cfg *drc_cfgs; @@ -95,35 +93,6 @@ struct wm8994_pdata { /* Jack detect threashold levels, see datasheet for values */ unsigned int jd_scthr:2; unsigned int jd_thr:2; - - //for phonepad - unsigned int no_earpiece:1; // =1 don't have a earpiece, =0 has a earpiece - unsigned int sp_hp_same_channel:1; - - //BB input can be differential or single ended - unsigned int BB_input_diff:1; // =0 single ended =1 differential - unsigned int BB_class:1;//PCM_BB= 1 NO_PCM_BB=0 - - //If an external amplifier speakers wm8994 enable>0 disable=0 - unsigned int PA_control_pin; - - //wm8994 LDO1_ENA and LDO2_ENA - unsigned int Power_EN_Pin; - char PowerEN_iomux_name[50]; - int PowerEN_iomux_mode; - - //volume - int speaker_incall_vol; //max = 6, min = -21 - int speaker_incall_mic_vol; //max = 30, min = -22 - int speaker_normal_vol; //max = 6, min = -57 - int earpiece_incall_vol; //max = 6, min = -21 - int headset_incall_vol; //max = 6, min = -12 - int headset_incall_mic_vol; //max = 30, min = -22 - int headset_normal_vol; //max = 6, min = -57 - int BT_incall_vol; //max = 30, min = -16 - int BT_incall_mic_vol; //max = 6, min = -57 - int recorder_vol; //max = 60 , min = -16 - }; #endif diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 75de541f4153..8187e32d917d 100755 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -203,12 +203,6 @@ struct mmc_host { const struct mmc_bus_ops *bus_ops; /* current bus driver */ unsigned int bus_refs; /* reference counter */ -#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) - unsigned int re_initialized_flags; //in order to begin the rescan ; added by xbw@2011-04-07 - unsigned int doneflag; //added by xbw at 2011-08-27 - int (*sdmmc_host_hw_init)(void *data); -#endif - unsigned int bus_resume_flags; #define MMC_BUSRESUME_MANUAL_RESUME (1 << 0) #define MMC_BUSRESUME_NEEDS_RESUME (1 << 1) diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h index 76650be01ed0..ebd747265294 100755 --- a/include/linux/regulator/consumer.h +++ b/include/linux/regulator/consumer.h @@ -153,9 +153,6 @@ int regulator_list_voltage(struct regulator *regulator, unsigned selector); int regulator_is_supported_voltage(struct regulator *regulator, int min_uV, int max_uV); int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV); -#ifdef CONFIG_ARCH_RK29 -int regulator_set_suspend_voltage(struct regulator *regulator, int uV); -#endif int regulator_get_voltage(struct regulator *regulator); int regulator_set_current_limit(struct regulator *regulator, int min_uA, int max_uA); @@ -243,13 +240,6 @@ static inline int regulator_set_voltage(struct regulator *regulator, return 0; } -#ifdef CONFIG_ARCH_RK29 -static inline int regulator_set_suspend_voltage(struct regulator *regulator, int uV) -{ - return 0; -} -#endif - static inline int regulator_get_voltage(struct regulator *regulator) { return 0; diff --git a/include/linux/wakelock.h b/include/linux/wakelock.h index 492aa649629a..a096d24ada1d 100755 --- a/include/linux/wakelock.h +++ b/include/linux/wakelock.h @@ -72,7 +72,6 @@ int wake_lock_active(struct wake_lock *lock); * number of jiffies until all active wake locks time out. */ long has_wake_lock(int type); -void print_active_wake_locks(int type); #else @@ -85,7 +84,6 @@ 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; } -static inline void print_active_wake_locks(int type) {} #endif diff --git a/include/media/v4l2-chip-ident.h b/include/media/v4l2-chip-ident.h index 7482878f63db..21b4428c12ab 100755 --- a/include/media/v4l2-chip-ident.h +++ b/include/media/v4l2-chip-ident.h @@ -69,21 +69,11 @@ enum { V4L2_IDENT_OV9650 = 254, V4L2_IDENT_OV9655 = 255, V4L2_IDENT_SOI968 = 256, - V4L2_IDENT_OV2655 = 257, /* ddl@rock-chips.com : ov2655 support */ - V4L2_IDENT_OV2659 = 258, - V4L2_IDENT_OV3640 = 259, - V4L2_IDENT_OV5640 = 260, - V4L2_IDENT_OV5642 = 261, - V4L2_IDENT_OV7675 = 262, - V4L2_IDENT_OV2640 = 263, - V4L2_IDENT_OV9640 = 264, + V4L2_IDENT_OV9640 = 257, /* module saa7146: reserved range 300-309 */ V4L2_IDENT_SAA7146 = 300, - /* Samsung sensors: reserved range 310-319 */ - V4L2_IDENT_S5K66A = 310, /* ddl@rock-chips.com : s5k66a support */ - /* Conexant MPEG encoder/decoders: reserved range 400-420 */ V4L2_IDENT_CX23418_843 = 403, /* Integrated A/V Decoder on the '418 */ V4L2_IDENT_CX23415 = 415, @@ -287,7 +277,6 @@ enum { V4L2_IDENT_MT9M001C12STM = 45005, V4L2_IDENT_MT9M111 = 45007, V4L2_IDENT_MT9M112 = 45008, - V4L2_IDENT_MT9D112 = 45009, /* ddl@rock-chips.com : MT9D112 support */ V4L2_IDENT_MT9V022IX7ATC = 45010, /* No way to detect "normal" I77ATx */ V4L2_IDENT_MT9V022IX7ATM = 45015, /* and "lead free" IA7ATx chips */ V4L2_IDENT_MT9T031 = 45020, @@ -296,9 +285,6 @@ enum { V4L2_IDENT_MT9V111 = 45031, V4L2_IDENT_MT9V112 = 45032, - V4L2_IDENT_MT9P111 = 45033, /* ddl@rock-chips.com : MT9P111 support */ - V4L2_IDENT_MT9D113 = 45034, /* ddl@rock-chips.com : MT9D113 support */ - /* HV7131R CMOS sensor: just ident 46000 */ V4L2_IDENT_HV7131R = 46000, @@ -322,19 +308,6 @@ enum { /* module upd64083: just ident 64083 */ V4L2_IDENT_UPD64083 = 64083, - - V4L2_IDENT_GT2005 = 64099, /* ddl@rock-chips.com : GT2005 support */ - V4L2_IDENT_GC0307 = 64100, /* ddl@rock-chips.com : GC0308 support */ - V4L2_IDENT_GC0308 = 64101, /* ddl@rock-chips.com : GC0308 support */ - V4L2_IDENT_GC0309 = 64102, /* ddl@rock-chips.com : GC0309 support */ - V4L2_IDENT_SIV120B = 64103, /* ddl@rock-chips.com : siv120b support */ - - V4L2_IDENT_GC2015 = 64105, /* ddl@rock-chips.com : gc2015 support */ - V4L2_IDENT_HI253 = 64106, /* ddl@rock-chips.com : hi253 support */ - V4L2_IDENT_HI704 = 64107, /* ddl@rock-chips.com : hi704 support */ - V4L2_IDENT_NT99250 = 64108, /* ddl@rock-chips.com : nt99250 support */ - V4L2_IDENT_SID130B = 64109, /* ddl@rock-chips.com : sid130B support */ - /* Don't just add new IDs at the end: KEEP THIS LIST ORDERED BY ID! */ }; diff --git a/kernel/power/earlysuspend.c b/kernel/power/earlysuspend.c index d76c496d773d..84bed51dcdce 100644 --- a/kernel/power/earlysuspend.c +++ b/kernel/power/earlysuspend.c @@ -20,7 +20,6 @@ #include /* sys_sync */ #include #include -#include #include "power.h" @@ -28,11 +27,7 @@ enum { DEBUG_USER_STATE = 1U << 0, DEBUG_SUSPEND = 1U << 2, }; -#ifdef DEBUG -static int debug_mask = DEBUG_USER_STATE | DEBUG_SUSPEND; -#else static int debug_mask = DEBUG_USER_STATE; -#endif module_param_named(debug_mask, debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP); static DEFINE_MUTEX(early_suspend_lock); @@ -99,8 +94,6 @@ static void early_suspend(struct work_struct *work) if (debug_mask & DEBUG_SUSPEND) pr_info("early_suspend: call handlers\n"); list_for_each_entry(pos, &early_suspend_handlers, link) { - if (debug_mask & DEBUG_SUSPEND) - print_symbol("early_suspend: call %s\n", (unsigned long)pos->suspend); if (pos->suspend != NULL) pos->suspend(pos); } @@ -138,12 +131,9 @@ static void late_resume(struct work_struct *work) } if (debug_mask & DEBUG_SUSPEND) pr_info("late_resume: call handlers\n"); - list_for_each_entry_reverse(pos, &early_suspend_handlers, link) { - if (debug_mask & DEBUG_SUSPEND) - print_symbol("late_resume: call %s\n", (unsigned long)pos->resume); + list_for_each_entry_reverse(pos, &early_suspend_handlers, link) if (pos->resume != NULL) pos->resume(pos); - } if (debug_mask & DEBUG_SUSPEND) pr_info("late_resume: done\n"); abort: diff --git a/kernel/power/process.c b/kernel/power/process.c index 1ac4d4582bf2..cdac5f955b85 100644 --- a/kernel/power/process.c +++ b/kernel/power/process.c @@ -106,7 +106,6 @@ static int try_to_freeze_tasks(bool sig_only) printk("\n"); printk(KERN_ERR "Freezing of %s aborted\n", sig_only ? "user space " : "tasks "); - print_active_wake_locks(WAKE_LOCK_SUSPEND); } else { printk("\n"); diff --git a/kernel/power/wakelock.c b/kernel/power/wakelock.c index dffdc02f7d95..ee9781c5adb2 100644 --- a/kernel/power/wakelock.c +++ b/kernel/power/wakelock.c @@ -30,9 +30,8 @@ enum { DEBUG_SUSPEND = 1U << 2, DEBUG_EXPIRE = 1U << 3, DEBUG_WAKE_LOCK = 1U << 4, - DEBUG_FORBID_SUSPEND = 1U << 5, }; -static int debug_mask = DEBUG_EXIT_SUSPEND | DEBUG_WAKEUP | DEBUG_FORBID_SUSPEND; +static int debug_mask = DEBUG_EXIT_SUSPEND | DEBUG_WAKEUP; module_param_named(debug_mask, debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP); #define WAKE_LOCK_TYPE_MASK (0x0f) @@ -207,33 +206,28 @@ static void expire_wake_lock(struct wake_lock *lock) } /* Caller must acquire the list_lock spinlock */ -static void print_active_locks_locked(int type) +static void print_active_locks(int type) { struct wake_lock *lock; + bool print_expired = true; BUG_ON(type >= WAKE_LOCK_TYPE_COUNT); list_for_each_entry(lock, &active_wake_locks[type], link) { if (lock->flags & WAKE_LOCK_AUTO_EXPIRE) { long timeout = lock->expires - jiffies; - if (timeout <= 0) + if (timeout > 0) + pr_info("active wake lock %s, time left %ld\n", + lock->name, timeout); + else if (print_expired) pr_info("wake lock %s, expired\n", lock->name); - else - pr_info("active wake lock %s, time left %ld.%03lu\n", - lock->name, timeout / HZ, - (timeout % HZ) * MSEC_PER_SEC / HZ); - } else + } else { pr_info("active wake lock %s\n", lock->name); + if (!(debug_mask & DEBUG_EXPIRE)) + print_expired = false; + } } } -void print_active_wake_locks(int type) -{ - unsigned long irqflags; - spin_lock_irqsave(&list_lock, irqflags); - print_active_locks_locked(type); - spin_unlock_irqrestore(&list_lock, irqflags); -} - static long has_wake_lock_locked(int type) { struct wake_lock *lock, *n; @@ -259,6 +253,8 @@ long has_wake_lock(int type) unsigned long irqflags; spin_lock_irqsave(&list_lock, irqflags); ret = has_wake_lock_locked(type); + if (ret && (debug_mask & DEBUG_SUSPEND) && type == WAKE_LOCK_SUSPEND) + print_active_locks(type); spin_unlock_irqrestore(&list_lock, irqflags); return ret; } @@ -269,10 +265,8 @@ static void suspend(struct work_struct *work) int entry_event_num; if (has_wake_lock(WAKE_LOCK_SUSPEND)) { - if (debug_mask & DEBUG_SUSPEND || debug_mask & DEBUG_FORBID_SUSPEND) + if (debug_mask & DEBUG_SUSPEND) pr_info("suspend: abort suspend\n"); - if (debug_mask & DEBUG_FORBID_SUSPEND) - print_active_wake_locks(WAKE_LOCK_SUSPEND); return; } @@ -307,7 +301,7 @@ static void expire_wake_locks(unsigned long data) pr_info("expire_wake_locks: start\n"); spin_lock_irqsave(&list_lock, irqflags); if (debug_mask & DEBUG_SUSPEND) - print_active_locks_locked(WAKE_LOCK_SUSPEND); + print_active_locks(WAKE_LOCK_SUSPEND); has_lock = has_wake_lock_locked(WAKE_LOCK_SUSPEND); if (debug_mask & DEBUG_EXPIRE) pr_info("expire_wake_locks: done, has_lock %ld\n", has_lock); @@ -325,8 +319,6 @@ static int power_suspend_late(struct device *dev) #endif if (debug_mask & DEBUG_SUSPEND) pr_info("power_suspend_late return %d\n", ret); - if (ret && (debug_mask & DEBUG_FORBID_SUSPEND)) - print_active_wake_locks(WAKE_LOCK_SUSPEND); return ret; } @@ -349,7 +341,6 @@ void wake_lock_init(struct wake_lock *lock, int type, const char *name) if (name) lock->name = name; BUG_ON(!lock->name); - BUG_ON(lock->flags & WAKE_LOCK_INITIALIZED); if (debug_mask & DEBUG_WAKE_LOCK) pr_info("wake_lock_init name=%s\n", lock->name); @@ -516,7 +507,7 @@ void wake_unlock(struct wake_lock *lock) } if (lock == &main_wake_lock) { if (debug_mask & DEBUG_SUSPEND) - print_active_locks_locked(WAKE_LOCK_SUSPEND); + print_active_locks(WAKE_LOCK_SUSPEND); #ifdef CONFIG_WAKELOCK_STAT update_sleep_wait_stats_locked(0); #endif diff --git a/kernel/sys.c b/kernel/sys.c index fef7bdb1af80..7f5a0cd296a9 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -46,18 +46,6 @@ #include #include #include -/*************** -* DEBUG -****************/ -#define RESTART_DEBUG -#ifdef RESTART_DEBUG -#define restart_dbg(format, arg...) \ - printk("RESTART_DEBUG : " format "\n" , ## arg) -#else -#define restart_dbg(format, arg...) do {} while (0) -#endif - - #ifndef SET_UNALIGN_CTL # define SET_UNALIGN_CTL(a,b) (-EINVAL) @@ -319,16 +307,11 @@ void kernel_restart_prepare(char *cmd) */ void kernel_restart(char *cmd) { - /* - * debug trace - */ - restart_dbg("%s->%d->cmd=%s",__FUNCTION__,__LINE__,cmd); - kernel_restart_prepare(cmd); if (!cmd) - printk( "Restarting system.\n"); + printk(KERN_EMERG "Restarting system.\n"); else - printk( "Restarting system with command '%s'.\n", cmd); + printk(KERN_EMERG "Restarting system with command '%s'.\n", cmd); machine_restart(cmd); } EXPORT_SYMBOL_GPL(kernel_restart); @@ -409,11 +392,6 @@ SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd, mutex_lock(&reboot_mutex); switch (cmd) { case LINUX_REBOOT_CMD_RESTART: - /* - * debug trace - */ - restart_dbg("%s->%d->cmd=%x",__FUNCTION__,__LINE__,cmd); - kernel_restart(NULL); break; @@ -431,11 +409,6 @@ SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd, panic("cannot halt"); case LINUX_REBOOT_CMD_POWER_OFF: - /* - * debug trace - */ - restart_dbg("%s->%d->cmd=%x",__FUNCTION__,__LINE__,cmd); - kernel_power_off(); do_exit(0); break; @@ -446,11 +419,7 @@ SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd, break; } buffer[sizeof(buffer) - 1] = '\0'; - /* - * debug trace - */ - restart_dbg("%s->%d->cmd=%x args=%s",__FUNCTION__,__LINE__,cmd,buffer); - + kernel_restart(buffer); break; diff --git a/mm/page_alloc.c b/mm/page_alloc.c index ab5395281ec0..9e9fc05c438b 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -2003,8 +2003,7 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order, goto nopage; restart: - if (!(gfp_mask & __GFP_NO_KSWAPD)) - wake_all_kswapd(order, zonelist, high_zoneidx); + wake_all_kswapd(order, zonelist, high_zoneidx); /* * OK, we're below the kswapd watermark and have kicked background diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index f122f8c748b7..83f5c67d3c41 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -55,9 +55,6 @@ config SND_SOC_ALL_CODECS select SND_SOC_WM8753 if SND_SOC_I2C_AND_SPI select SND_SOC_WM8776 if SND_SOC_I2C_AND_SPI select SND_SOC_WM8900 if I2C - select SND_SOC_alc5621 if I2C - select SND_SOC_alc5631 if I2C - select SND_SOC_RT5625 if I2C select SND_SOC_WM8903 if I2C select SND_SOC_WM8904 if I2C select SND_SOC_WM8940 if I2C @@ -69,7 +66,6 @@ config SND_SOC_ALL_CODECS select SND_SOC_WM8978 if I2C select SND_SOC_WM8988 if SND_SOC_I2C_AND_SPI select SND_SOC_WM8990 if I2C - select SND_SOC_CS42L52 if I2C select SND_SOC_WM8993 if I2C select SND_SOC_WM8994 if MFD_WM8994 select SND_SOC_WM9081 if I2C @@ -87,9 +83,7 @@ config SND_SOC_ALL_CODECS be selected separately. If unsure select "N". -select SND_SOC_ALC5623_RT if I2C -config SND_SOC_ALC5623 - tristate + config SND_SOC_WM_HUBS tristate default y if SND_SOC_WM8993=y || SND_SOC_WM8994=y @@ -236,15 +230,6 @@ config SND_SOC_WM8776 config SND_SOC_WM8900 tristate -config SND_SOC_alc5621 - tristate - -config SND_SOC_alc5631 - tristate - -config SND_SOC_RT5625 - tristate - config SND_SOC_WM8903 tristate @@ -278,9 +263,6 @@ config SND_SOC_WM8988 config SND_SOC_WM8990 tristate -config SND_SOC_CS42L52 - tristate - config SND_SOC_WM8993 tristate @@ -298,9 +280,7 @@ config SND_SOC_WM9712 config SND_SOC_WM9713 tristate -config SND_SOC_RK1000 - tristate - depends on RK1000_CONTROL + # Amp config SND_SOC_MAX9877 tristate diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 158acdb7ee0e..53524095759c 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -40,10 +40,6 @@ snd-soc-wm8750-objs := wm8750.o snd-soc-wm8753-objs := wm8753.o snd-soc-wm8776-objs := wm8776.o snd-soc-wm8900-objs := wm8900.o -snd-soc-alc5621-objs := alc5621.o -snd-soc-alc5631-objs := rt5631.o -snd-soc-rt5625-objs := rt5625.o -snd-soc-cs42l52-objs := cs42l52.o snd-soc-wm8903-objs := wm8903.o snd-soc-wm8904-objs := wm8904.o snd-soc-wm8940-objs := wm8940.o @@ -62,7 +58,6 @@ snd-soc-wm9705-objs := wm9705.o snd-soc-wm9712-objs := wm9712.o snd-soc-wm9713-objs := wm9713.o snd-soc-wm-hubs-objs := wm_hubs.o -snd-soc-rk1000-objs := rk1000_codec.o snd-soc-jz4740-codec-objs := jz4740.o # Amp @@ -71,8 +66,6 @@ snd-soc-tpa6130a2-objs := tpa6130a2.o snd-soc-wm2000-objs := wm2000.o snd-soc-wm9090-objs := wm9090.o -snd-soc-alc5623-objs := alc5623_tuning.o -obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o obj-$(CONFIG_SND_SOC_AD193X) += snd-soc-ad193x.o @@ -116,10 +109,6 @@ obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o obj-$(CONFIG_SND_SOC_WM8776) += snd-soc-wm8776.o obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o -obj-$(CONFIG_SND_SOC_alc5621) += snd-soc-alc5621.o -obj-$(CONFIG_SND_SOC_alc5631) += snd-soc-alc5631.o -obj-$(CONFIG_SND_SOC_RT5625) += snd-soc-rt5625.o -obj-$(CONFIG_SND_SOC_CS42L52) += snd-soc-cs42l52.o obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o obj-$(CONFIG_SND_SOC_WM8904) += snd-soc-wm8904.o obj-$(CONFIG_SND_SOC_WM8940) += snd-soc-wm8940.o @@ -138,7 +127,7 @@ obj-$(CONFIG_SND_SOC_WM9705) += snd-soc-wm9705.o obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o -obj-$(CONFIG_SND_SOC_RK1000) += snd-soc-rk1000.o + # Amp obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c index 0c7057f5bd4c..4b8ffc2ea71d 100755 --- a/sound/soc/codecs/wm8900.c +++ b/sound/soc/codecs/wm8900.c @@ -32,19 +32,9 @@ #include #include #include -#include -#include -#include #include "wm8900.h" - -#if 0 -#define WM8900_DBG(x...) printk(KERN_INFO x) -#else -#define WM8900_DBG(x...) -#endif - /* WM8900 register space */ #define WM8900_REG_RESET 0x0 #define WM8900_REG_ID 0x0 @@ -123,8 +113,8 @@ #define WM8900_REG_CLOCKING1_BCLK_MASK (~0x01e) #define WM8900_REG_CLOCKING1_OPCLK_MASK (~0x7000) -#define WM8900_REG_CLOCKING2_ADC_CLKDIV 0x1c -#define WM8900_REG_CLOCKING2_DAC_CLKDIV 0xe0 +#define WM8900_REG_CLOCKING2_ADC_CLKDIV 0xe0 +#define WM8900_REG_CLOCKING2_DAC_CLKDIV 0x1c #define WM8900_REG_DACCTRL_MUTE 0x004 #define WM8900_REG_DACCTRL_DAC_SB_FILT 0x100 @@ -146,28 +136,8 @@ #define WM8900_REG_HPCTL1_HP_SHORT2 0x04 #define WM8900_LRC_MASK 0xfc00 -#define SPK_CON RK29_PIN6_PB6 - -#define WM8900_NO_POWEROFF /* Do not close codec except suspend or poweroff */ - -#define WM8900_IS_SHUTDOWN 0 -#define WM8900_IS_STARTUP 1 - -#define WM8900_WORK_NULL 0 -#define WM8900_WORK_POWERDOWN_PLAYBACK 1 -#define WM8900_WORK_POWERDOWN_CAPTURE 2 -#define WM8900_WORK_POWERDOWN_PLAYBACK_CAPTURE 3 -#define WM8900_WORK_HW_SET 4 - -static void wm8900_work(struct work_struct *work); - -static struct workqueue_struct *wm8900_workq; -static DECLARE_DELAYED_WORK(delayed_work, wm8900_work); -static int wm8900_current_status = WM8900_IS_SHUTDOWN, wm8900_work_type = WM8900_WORK_NULL; struct snd_soc_codec_device soc_codec_dev_wm8900; -static struct snd_soc_codec *wm8900_codec; -static bool isSPKon = true; struct wm8900_priv { struct snd_soc_codec codec; @@ -226,144 +196,429 @@ static int wm8900_volatile_register(unsigned int reg) static void wm8900_reset(struct snd_soc_codec *codec) { - WM8900_DBG("Enter:%s, %d, codec=0x%8X \n", __FUNCTION__, __LINE__,codec); - snd_soc_write(codec, WM8900_REG_RESET, 0); memcpy(codec->reg_cache, wm8900_reg_defaults, sizeof(wm8900_reg_defaults)); } -void codec_set_spk(bool on) +static int wm8900_hp_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) { - isSPKon = on; - if (on) { -#ifdef SPK_CON - gpio_set_value(SPK_CON, GPIO_HIGH); -#endif - } else { -#ifdef SPK_CON - gpio_set_value(SPK_CON, GPIO_LOW); -#endif - } -} + struct snd_soc_codec *codec = w->codec; + u16 hpctl1 = snd_soc_read(codec, WM8900_REG_HPCTL1); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + /* Clamp headphone outputs */ + hpctl1 = WM8900_REG_HPCTL1_HP_CLAMP_IP | + WM8900_REG_HPCTL1_HP_CLAMP_OP; + snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1); + break; -EXPORT_SYMBOL_GPL(codec_set_spk); + case SND_SOC_DAPM_POST_PMU: + /* Enable the input stage */ + hpctl1 &= ~WM8900_REG_HPCTL1_HP_CLAMP_IP; + hpctl1 |= WM8900_REG_HPCTL1_HP_SHORT | + WM8900_REG_HPCTL1_HP_SHORT2 | + WM8900_REG_HPCTL1_HP_IPSTAGE_ENA; + snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1); + + msleep(400); + + /* Enable the output stage */ + hpctl1 &= ~WM8900_REG_HPCTL1_HP_CLAMP_OP; + hpctl1 |= WM8900_REG_HPCTL1_HP_OPSTAGE_ENA; + snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1); + + /* Remove the shorts */ + hpctl1 &= ~WM8900_REG_HPCTL1_HP_SHORT2; + snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1); + hpctl1 &= ~WM8900_REG_HPCTL1_HP_SHORT; + snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1); + break; -static void wm8900_powerdown(void) -{ - printk("Power down wm8900\n"); -#ifndef WM8900_NO_POWEROFF - gpio_set_value(RK29_PIN1_PD6, GPIO_LOW); -#endif - - snd_soc_write(wm8900_codec, WM8900_REG_POWER1, 0x210D); - - if (wm8900_current_status != WM8900_IS_SHUTDOWN) { -#ifdef SPK_CON - gpio_set_value(SPK_CON, GPIO_LOW); -#endif - msleep(20); - snd_soc_write(wm8900_codec, WM8900_REG_RESET, 0); - wm8900_current_status = WM8900_IS_SHUTDOWN; + case SND_SOC_DAPM_PRE_PMD: + /* Short the output */ + hpctl1 |= WM8900_REG_HPCTL1_HP_SHORT; + snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1); + + /* Disable the output stage */ + hpctl1 &= ~WM8900_REG_HPCTL1_HP_OPSTAGE_ENA; + snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1); + + /* Clamp the outputs and power down input */ + hpctl1 |= WM8900_REG_HPCTL1_HP_CLAMP_IP | + WM8900_REG_HPCTL1_HP_CLAMP_OP; + hpctl1 &= ~WM8900_REG_HPCTL1_HP_IPSTAGE_ENA; + snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1); + break; + + case SND_SOC_DAPM_POST_PMD: + /* Disable everything */ + snd_soc_write(codec, WM8900_REG_HPCTL1, 0); + break; + + default: + BUG(); } + + return 0; } -static void wm8900_set_hw(struct snd_soc_codec *codec) -{ - u16 reg; +static const DECLARE_TLV_DB_SCALE(out_pga_tlv, -5700, 100, 0); - if (wm8900_current_status & WM8900_IS_STARTUP) - return; - - printk("Power up wm8900\n"); -//CLK , PATH, VOL,POW. - - snd_soc_write(codec, WM8900_REG_HPCTL1, 0x30); - snd_soc_write(codec, WM8900_REG_POWER1, 0x0100); - snd_soc_write(codec, WM8900_REG_POWER3, 0x60); - snd_soc_write(codec, WM8900_REG_POWER1, 0x0101); - msleep(400); - snd_soc_write(codec, WM8900_REG_POWER1, 0x0109); - snd_soc_write(codec, WM8900_REG_ADDCTL, 0x02); - snd_soc_write(codec, WM8900_REG_POWER1, 0x09); - snd_soc_write(codec, WM8900_REG_POWER3, 0xEF); - snd_soc_write(codec, WM8900_REG_DACCTRL, WM8900_REG_DACCTRL_MUTE); - snd_soc_write(codec, WM8900_REG_LOUTMIXCTL1, 0x150); - snd_soc_write(codec, WM8900_REG_ROUTMIXCTL1, 0x150); - - snd_soc_write(codec, WM8900_REG_HPCTL1, 0xB0); - snd_soc_write(codec, WM8900_REG_HPCTL1, 0xF0); - snd_soc_write(codec, WM8900_REG_HPCTL1, 0xC0); - - //for recorder - snd_soc_write(codec, WM8900_REG_POWER1, 0x210D); - snd_soc_write(codec, WM8900_REG_POWER2, 0xC1AF); - - snd_soc_write(codec, WM8900_REG_LADC_DV, 0x01C0); - snd_soc_write(codec, WM8900_REG_RADC_DV, 0x01C0); - - snd_soc_write(codec, WM8900_REG_INCTL, 0x0040); - - snd_soc_write(codec, WM8900_REG_LINVOL, 0x011A); - snd_soc_write(codec, WM8900_REG_RINVOL, 0x011A); - snd_soc_write(codec, WM8900_REG_INBOOSTMIX1, 0x0042); - snd_soc_write(codec, WM8900_REG_INBOOSTMIX2, 0x0042); - snd_soc_write(codec, WM8900_REG_ADCPATH, 0x0055); +static const DECLARE_TLV_DB_SCALE(out_mix_tlv, -1500, 300, 0); - reg = snd_soc_read(codec, WM8900_REG_DACCTRL); +static const DECLARE_TLV_DB_SCALE(in_boost_tlv, -1200, 600, 0); - reg &= ~WM8900_REG_DACCTRL_MUTE; - snd_soc_write(codec, WM8900_REG_DACCTRL, reg); +static const DECLARE_TLV_DB_SCALE(in_pga_tlv, -1200, 100, 0); - snd_soc_write(codec, WM8900_REG_LOUT1CTL, 0x130); - snd_soc_write(codec, WM8900_REG_ROUT1CTL, 0x130); +static const DECLARE_TLV_DB_SCALE(dac_boost_tlv, 0, 600, 0); - /* Turn up vol slowly, for HP out pop noise */ +static const DECLARE_TLV_DB_SCALE(dac_tlv, -7200, 75, 1); - for (reg = 0; reg <= 0x33; reg += 0x10) { - snd_soc_write(codec, WM8900_REG_LOUT2CTL, 0x100 + reg); - snd_soc_write(codec, WM8900_REG_ROUT2CTL, 0x100 + reg); - msleep(5); - } - snd_soc_write(codec, WM8900_REG_LOUT2CTL, 0x133); - snd_soc_write(codec, WM8900_REG_ROUT2CTL, 0x133); +static const DECLARE_TLV_DB_SCALE(adc_svol_tlv, -3600, 300, 0); - msleep(20); +static const DECLARE_TLV_DB_SCALE(adc_tlv, -7200, 75, 1); -#ifdef SPK_CON - if (isSPKon) { - gpio_set_value(SPK_CON, GPIO_HIGH); - } -#endif -#ifndef WM8900_NO_POWEROFF - msleep(350); - gpio_set_value(RK29_PIN1_PD6, GPIO_HIGH); -#endif - wm8900_current_status |= WM8900_IS_STARTUP; -} +static const char *mic_bias_level_txt[] = { "0.9*AVDD", "0.65*AVDD" }; + +static const struct soc_enum mic_bias_level = +SOC_ENUM_SINGLE(WM8900_REG_INCTL, 8, 2, mic_bias_level_txt); + +static const char *dac_mute_rate_txt[] = { "Fast", "Slow" }; + +static const struct soc_enum dac_mute_rate = +SOC_ENUM_SINGLE(WM8900_REG_DACCTRL, 7, 2, dac_mute_rate_txt); -static void wm8900_work(struct work_struct *work) +static const char *dac_deemphasis_txt[] = { + "Disabled", "32kHz", "44.1kHz", "48kHz" +}; + +static const struct soc_enum dac_deemphasis = +SOC_ENUM_SINGLE(WM8900_REG_DACCTRL, 4, 4, dac_deemphasis_txt); + +static const char *adc_hpf_cut_txt[] = { + "Hi-fi mode", "Voice mode 1", "Voice mode 2", "Voice mode 3" +}; + +static const struct soc_enum adc_hpf_cut = +SOC_ENUM_SINGLE(WM8900_REG_ADCCTRL, 5, 4, adc_hpf_cut_txt); + +static const char *lr_txt[] = { + "Left", "Right" +}; + +static const struct soc_enum aifl_src = +SOC_ENUM_SINGLE(WM8900_REG_AUDIO1, 15, 2, lr_txt); + +static const struct soc_enum aifr_src = +SOC_ENUM_SINGLE(WM8900_REG_AUDIO1, 14, 2, lr_txt); + +static const struct soc_enum dacl_src = +SOC_ENUM_SINGLE(WM8900_REG_AUDIO2, 15, 2, lr_txt); + +static const struct soc_enum dacr_src = +SOC_ENUM_SINGLE(WM8900_REG_AUDIO2, 14, 2, lr_txt); + +static const char *sidetone_txt[] = { + "Disabled", "Left ADC", "Right ADC" +}; + +static const struct soc_enum dacl_sidetone = +SOC_ENUM_SINGLE(WM8900_REG_SIDETONE, 2, 3, sidetone_txt); + +static const struct soc_enum dacr_sidetone = +SOC_ENUM_SINGLE(WM8900_REG_SIDETONE, 0, 3, sidetone_txt); + +static const struct snd_kcontrol_new wm8900_snd_controls[] = { +SOC_ENUM("Mic Bias Level", mic_bias_level), + +SOC_SINGLE_TLV("Left Input PGA Volume", WM8900_REG_LINVOL, 0, 31, 0, + in_pga_tlv), +SOC_SINGLE("Left Input PGA Switch", WM8900_REG_LINVOL, 6, 1, 1), +SOC_SINGLE("Left Input PGA ZC Switch", WM8900_REG_LINVOL, 7, 1, 0), + +SOC_SINGLE_TLV("Right Input PGA Volume", WM8900_REG_RINVOL, 0, 31, 0, + in_pga_tlv), +SOC_SINGLE("Right Input PGA Switch", WM8900_REG_RINVOL, 6, 1, 1), +SOC_SINGLE("Right Input PGA ZC Switch", WM8900_REG_RINVOL, 7, 1, 0), + +SOC_SINGLE("DAC Soft Mute Switch", WM8900_REG_DACCTRL, 6, 1, 1), +SOC_ENUM("DAC Mute Rate", dac_mute_rate), +SOC_SINGLE("DAC Mono Switch", WM8900_REG_DACCTRL, 9, 1, 0), +SOC_ENUM("DAC Deemphasis", dac_deemphasis), +SOC_SINGLE("DAC Sigma-Delta Modulator Clock Switch", WM8900_REG_DACCTRL, + 12, 1, 0), + +SOC_SINGLE("ADC HPF Switch", WM8900_REG_ADCCTRL, 8, 1, 0), +SOC_ENUM("ADC HPF Cut-Off", adc_hpf_cut), +SOC_DOUBLE("ADC Invert Switch", WM8900_REG_ADCCTRL, 1, 0, 1, 0), +SOC_SINGLE_TLV("Left ADC Sidetone Volume", WM8900_REG_SIDETONE, 9, 12, 0, + adc_svol_tlv), +SOC_SINGLE_TLV("Right ADC Sidetone Volume", WM8900_REG_SIDETONE, 5, 12, 0, + adc_svol_tlv), +SOC_ENUM("Left Digital Audio Source", aifl_src), +SOC_ENUM("Right Digital Audio Source", aifr_src), + +SOC_SINGLE_TLV("DAC Input Boost Volume", WM8900_REG_AUDIO2, 10, 4, 0, + dac_boost_tlv), +SOC_ENUM("Left DAC Source", dacl_src), +SOC_ENUM("Right DAC Source", dacr_src), +SOC_ENUM("Left DAC Sidetone", dacl_sidetone), +SOC_ENUM("Right DAC Sidetone", dacr_sidetone), +SOC_DOUBLE("DAC Invert Switch", WM8900_REG_DACCTRL, 1, 0, 1, 0), + +SOC_DOUBLE_R_TLV("Digital Playback Volume", + WM8900_REG_LDAC_DV, WM8900_REG_RDAC_DV, + 1, 96, 0, dac_tlv), +SOC_DOUBLE_R_TLV("Digital Capture Volume", + WM8900_REG_LADC_DV, WM8900_REG_RADC_DV, 1, 119, 0, adc_tlv), + +SOC_SINGLE_TLV("LINPUT3 Bypass Volume", WM8900_REG_LOUTMIXCTL1, 4, 7, 0, + out_mix_tlv), +SOC_SINGLE_TLV("RINPUT3 Bypass Volume", WM8900_REG_ROUTMIXCTL1, 4, 7, 0, + out_mix_tlv), +SOC_SINGLE_TLV("Left AUX Bypass Volume", WM8900_REG_AUXOUT_CTL, 4, 7, 0, + out_mix_tlv), +SOC_SINGLE_TLV("Right AUX Bypass Volume", WM8900_REG_AUXOUT_CTL, 0, 7, 0, + out_mix_tlv), + +SOC_SINGLE_TLV("LeftIn to RightOut Mixer Volume", WM8900_REG_BYPASS1, 0, 7, 0, + out_mix_tlv), +SOC_SINGLE_TLV("LeftIn to LeftOut Mixer Volume", WM8900_REG_BYPASS1, 4, 7, 0, + out_mix_tlv), +SOC_SINGLE_TLV("RightIn to LeftOut Mixer Volume", WM8900_REG_BYPASS2, 0, 7, 0, + out_mix_tlv), +SOC_SINGLE_TLV("RightIn to RightOut Mixer Volume", WM8900_REG_BYPASS2, 4, 7, 0, + out_mix_tlv), + +SOC_SINGLE_TLV("IN2L Boost Volume", WM8900_REG_INBOOSTMIX1, 0, 3, 0, + in_boost_tlv), +SOC_SINGLE_TLV("IN3L Boost Volume", WM8900_REG_INBOOSTMIX1, 4, 3, 0, + in_boost_tlv), +SOC_SINGLE_TLV("IN2R Boost Volume", WM8900_REG_INBOOSTMIX2, 0, 3, 0, + in_boost_tlv), +SOC_SINGLE_TLV("IN3R Boost Volume", WM8900_REG_INBOOSTMIX2, 4, 3, 0, + in_boost_tlv), +SOC_SINGLE_TLV("Left AUX Boost Volume", WM8900_REG_AUXBOOST, 4, 3, 0, + in_boost_tlv), +SOC_SINGLE_TLV("Right AUX Boost Volume", WM8900_REG_AUXBOOST, 0, 3, 0, + in_boost_tlv), + +SOC_DOUBLE_R_TLV("LINEOUT1 Volume", WM8900_REG_LOUT1CTL, WM8900_REG_ROUT1CTL, + 0, 63, 0, out_pga_tlv), +SOC_DOUBLE_R("LINEOUT1 Switch", WM8900_REG_LOUT1CTL, WM8900_REG_ROUT1CTL, + 6, 1, 1), +SOC_DOUBLE_R("LINEOUT1 ZC Switch", WM8900_REG_LOUT1CTL, WM8900_REG_ROUT1CTL, + 7, 1, 0), + +SOC_DOUBLE_R_TLV("LINEOUT2 Volume", + WM8900_REG_LOUT2CTL, WM8900_REG_ROUT2CTL, + 0, 63, 0, out_pga_tlv), +SOC_DOUBLE_R("LINEOUT2 Switch", + WM8900_REG_LOUT2CTL, WM8900_REG_ROUT2CTL, 6, 1, 1), +SOC_DOUBLE_R("LINEOUT2 ZC Switch", + WM8900_REG_LOUT2CTL, WM8900_REG_ROUT2CTL, 7, 1, 0), +SOC_SINGLE("LINEOUT2 LP -12dB", WM8900_REG_LOUTMIXCTL1, + 0, 1, 1), + +}; + +static const struct snd_kcontrol_new wm8900_dapm_loutput2_control = +SOC_DAPM_SINGLE("LINEOUT2L Switch", WM8900_REG_POWER3, 6, 1, 0); + +static const struct snd_kcontrol_new wm8900_dapm_routput2_control = +SOC_DAPM_SINGLE("LINEOUT2R Switch", WM8900_REG_POWER3, 5, 1, 0); + +static const struct snd_kcontrol_new wm8900_loutmix_controls[] = { +SOC_DAPM_SINGLE("LINPUT3 Bypass Switch", WM8900_REG_LOUTMIXCTL1, 7, 1, 0), +SOC_DAPM_SINGLE("AUX Bypass Switch", WM8900_REG_AUXOUT_CTL, 7, 1, 0), +SOC_DAPM_SINGLE("Left Input Mixer Switch", WM8900_REG_BYPASS1, 7, 1, 0), +SOC_DAPM_SINGLE("Right Input Mixer Switch", WM8900_REG_BYPASS2, 3, 1, 0), +SOC_DAPM_SINGLE("DACL Switch", WM8900_REG_LOUTMIXCTL1, 8, 1, 0), +}; + +static const struct snd_kcontrol_new wm8900_routmix_controls[] = { +SOC_DAPM_SINGLE("RINPUT3 Bypass Switch", WM8900_REG_ROUTMIXCTL1, 7, 1, 0), +SOC_DAPM_SINGLE("AUX Bypass Switch", WM8900_REG_AUXOUT_CTL, 3, 1, 0), +SOC_DAPM_SINGLE("Left Input Mixer Switch", WM8900_REG_BYPASS1, 3, 1, 0), +SOC_DAPM_SINGLE("Right Input Mixer Switch", WM8900_REG_BYPASS2, 7, 1, 0), +SOC_DAPM_SINGLE("DACR Switch", WM8900_REG_ROUTMIXCTL1, 8, 1, 0), +}; + +static const struct snd_kcontrol_new wm8900_linmix_controls[] = { +SOC_DAPM_SINGLE("LINPUT2 Switch", WM8900_REG_INBOOSTMIX1, 2, 1, 1), +SOC_DAPM_SINGLE("LINPUT3 Switch", WM8900_REG_INBOOSTMIX1, 6, 1, 1), +SOC_DAPM_SINGLE("AUX Switch", WM8900_REG_AUXBOOST, 6, 1, 1), +SOC_DAPM_SINGLE("Input PGA Switch", WM8900_REG_ADCPATH, 6, 1, 0), +}; + +static const struct snd_kcontrol_new wm8900_rinmix_controls[] = { +SOC_DAPM_SINGLE("RINPUT2 Switch", WM8900_REG_INBOOSTMIX2, 2, 1, 1), +SOC_DAPM_SINGLE("RINPUT3 Switch", WM8900_REG_INBOOSTMIX2, 6, 1, 1), +SOC_DAPM_SINGLE("AUX Switch", WM8900_REG_AUXBOOST, 2, 1, 1), +SOC_DAPM_SINGLE("Input PGA Switch", WM8900_REG_ADCPATH, 2, 1, 0), +}; + +static const struct snd_kcontrol_new wm8900_linpga_controls[] = { +SOC_DAPM_SINGLE("LINPUT1 Switch", WM8900_REG_INCTL, 6, 1, 0), +SOC_DAPM_SINGLE("LINPUT2 Switch", WM8900_REG_INCTL, 5, 1, 0), +SOC_DAPM_SINGLE("LINPUT3 Switch", WM8900_REG_INCTL, 4, 1, 0), +}; + +static const struct snd_kcontrol_new wm8900_rinpga_controls[] = { +SOC_DAPM_SINGLE("RINPUT1 Switch", WM8900_REG_INCTL, 2, 1, 0), +SOC_DAPM_SINGLE("RINPUT2 Switch", WM8900_REG_INCTL, 1, 1, 0), +SOC_DAPM_SINGLE("RINPUT3 Switch", WM8900_REG_INCTL, 0, 1, 0), +}; + +static const char *wm9700_lp_mux[] = { "Disabled", "Enabled" }; + +static const struct soc_enum wm8900_lineout2_lp_mux = +SOC_ENUM_SINGLE(WM8900_REG_LOUTMIXCTL1, 1, 2, wm9700_lp_mux); + +static const struct snd_kcontrol_new wm8900_lineout2_lp = +SOC_DAPM_ENUM("Route", wm8900_lineout2_lp_mux); + +static const struct snd_soc_dapm_widget wm8900_dapm_widgets[] = { + +/* Externally visible pins */ +SND_SOC_DAPM_OUTPUT("LINEOUT1L"), +SND_SOC_DAPM_OUTPUT("LINEOUT1R"), +SND_SOC_DAPM_OUTPUT("LINEOUT2L"), +SND_SOC_DAPM_OUTPUT("LINEOUT2R"), +SND_SOC_DAPM_OUTPUT("HP_L"), +SND_SOC_DAPM_OUTPUT("HP_R"), + +SND_SOC_DAPM_INPUT("RINPUT1"), +SND_SOC_DAPM_INPUT("LINPUT1"), +SND_SOC_DAPM_INPUT("RINPUT2"), +SND_SOC_DAPM_INPUT("LINPUT2"), +SND_SOC_DAPM_INPUT("RINPUT3"), +SND_SOC_DAPM_INPUT("LINPUT3"), +SND_SOC_DAPM_INPUT("AUX"), + +SND_SOC_DAPM_VMID("VMID"), + +/* Input */ +SND_SOC_DAPM_MIXER("Left Input PGA", WM8900_REG_POWER2, 3, 0, + wm8900_linpga_controls, + ARRAY_SIZE(wm8900_linpga_controls)), +SND_SOC_DAPM_MIXER("Right Input PGA", WM8900_REG_POWER2, 2, 0, + wm8900_rinpga_controls, + ARRAY_SIZE(wm8900_rinpga_controls)), + +SND_SOC_DAPM_MIXER("Left Input Mixer", WM8900_REG_POWER2, 5, 0, + wm8900_linmix_controls, + ARRAY_SIZE(wm8900_linmix_controls)), +SND_SOC_DAPM_MIXER("Right Input Mixer", WM8900_REG_POWER2, 4, 0, + wm8900_rinmix_controls, + ARRAY_SIZE(wm8900_rinmix_controls)), + +SND_SOC_DAPM_MICBIAS("Mic Bias", WM8900_REG_POWER1, 4, 0), + +SND_SOC_DAPM_ADC("ADCL", "Left HiFi Capture", WM8900_REG_POWER2, 1, 0), +SND_SOC_DAPM_ADC("ADCR", "Right HiFi Capture", WM8900_REG_POWER2, 0, 0), + +/* Output */ +SND_SOC_DAPM_DAC("DACL", "Left HiFi Playback", WM8900_REG_POWER3, 1, 0), +SND_SOC_DAPM_DAC("DACR", "Right HiFi Playback", WM8900_REG_POWER3, 0, 0), + +SND_SOC_DAPM_PGA_E("Headphone Amplifier", WM8900_REG_POWER3, 7, 0, NULL, 0, + wm8900_hp_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + +SND_SOC_DAPM_PGA("LINEOUT1L PGA", WM8900_REG_POWER2, 8, 0, NULL, 0), +SND_SOC_DAPM_PGA("LINEOUT1R PGA", WM8900_REG_POWER2, 7, 0, NULL, 0), + +SND_SOC_DAPM_MUX("LINEOUT2 LP", SND_SOC_NOPM, 0, 0, &wm8900_lineout2_lp), +SND_SOC_DAPM_PGA("LINEOUT2L PGA", WM8900_REG_POWER3, 6, 0, NULL, 0), +SND_SOC_DAPM_PGA("LINEOUT2R PGA", WM8900_REG_POWER3, 5, 0, NULL, 0), + +SND_SOC_DAPM_MIXER("Left Output Mixer", WM8900_REG_POWER3, 3, 0, + wm8900_loutmix_controls, + ARRAY_SIZE(wm8900_loutmix_controls)), +SND_SOC_DAPM_MIXER("Right Output Mixer", WM8900_REG_POWER3, 2, 0, + wm8900_routmix_controls, + ARRAY_SIZE(wm8900_routmix_controls)), +}; + +/* Target, Path, Source */ +static const struct snd_soc_dapm_route audio_map[] = { +/* Inputs */ +{"Left Input PGA", "LINPUT1 Switch", "LINPUT1"}, +{"Left Input PGA", "LINPUT2 Switch", "LINPUT2"}, +{"Left Input PGA", "LINPUT3 Switch", "LINPUT3"}, + +{"Right Input PGA", "RINPUT1 Switch", "RINPUT1"}, +{"Right Input PGA", "RINPUT2 Switch", "RINPUT2"}, +{"Right Input PGA", "RINPUT3 Switch", "RINPUT3"}, + +{"Left Input Mixer", "LINPUT2 Switch", "LINPUT2"}, +{"Left Input Mixer", "LINPUT3 Switch", "LINPUT3"}, +{"Left Input Mixer", "AUX Switch", "AUX"}, +{"Left Input Mixer", "Input PGA Switch", "Left Input PGA"}, + +{"Right Input Mixer", "RINPUT2 Switch", "RINPUT2"}, +{"Right Input Mixer", "RINPUT3 Switch", "RINPUT3"}, +{"Right Input Mixer", "AUX Switch", "AUX"}, +{"Right Input Mixer", "Input PGA Switch", "Right Input PGA"}, + +{"ADCL", NULL, "Left Input Mixer"}, +{"ADCR", NULL, "Right Input Mixer"}, + +/* Outputs */ +{"LINEOUT1L", NULL, "LINEOUT1L PGA"}, +{"LINEOUT1L PGA", NULL, "Left Output Mixer"}, +{"LINEOUT1R", NULL, "LINEOUT1R PGA"}, +{"LINEOUT1R PGA", NULL, "Right Output Mixer"}, + +{"LINEOUT2L PGA", NULL, "Left Output Mixer"}, +{"LINEOUT2 LP", "Disabled", "LINEOUT2L PGA"}, +{"LINEOUT2 LP", "Enabled", "Left Output Mixer"}, +{"LINEOUT2L", NULL, "LINEOUT2 LP"}, + +{"LINEOUT2R PGA", NULL, "Right Output Mixer"}, +{"LINEOUT2 LP", "Disabled", "LINEOUT2R PGA"}, +{"LINEOUT2 LP", "Enabled", "Right Output Mixer"}, +{"LINEOUT2R", NULL, "LINEOUT2 LP"}, + +{"Left Output Mixer", "LINPUT3 Bypass Switch", "LINPUT3"}, +{"Left Output Mixer", "AUX Bypass Switch", "AUX"}, +{"Left Output Mixer", "Left Input Mixer Switch", "Left Input Mixer"}, +{"Left Output Mixer", "Right Input Mixer Switch", "Right Input Mixer"}, +{"Left Output Mixer", "DACL Switch", "DACL"}, + +{"Right Output Mixer", "RINPUT3 Bypass Switch", "RINPUT3"}, +{"Right Output Mixer", "AUX Bypass Switch", "AUX"}, +{"Right Output Mixer", "Left Input Mixer Switch", "Left Input Mixer"}, +{"Right Output Mixer", "Right Input Mixer Switch", "Right Input Mixer"}, +{"Right Output Mixer", "DACR Switch", "DACR"}, + +/* Note that the headphone output stage needs to be connected + * externally to LINEOUT2 via DC blocking capacitors. Other + * configurations are not supported. + * + * Note also that left and right headphone paths are treated as a + * mono path. + */ +{"Headphone Amplifier", NULL, "LINEOUT2 LP"}, +{"Headphone Amplifier", NULL, "LINEOUT2 LP"}, +{"HP_L", NULL, "Headphone Amplifier"}, +{"HP_R", NULL, "Headphone Amplifier"}, +}; + +static int wm8900_add_widgets(struct snd_soc_codec *codec) { - WM8900_DBG("Enter::wm8900_work : wm8900_work_type = %d\n", wm8900_work_type); - - switch (wm8900_work_type) { - case WM8900_WORK_POWERDOWN_PLAYBACK : - break; - case WM8900_WORK_POWERDOWN_CAPTURE: - snd_soc_write(wm8900_codec, WM8900_REG_POWER1, 0x210D); - break; - case WM8900_WORK_POWERDOWN_PLAYBACK_CAPTURE: - wm8900_powerdown(); - break; - case WM8900_WORK_HW_SET: - wm8900_set_hw(wm8900_codec); - break; - default: - break; - } - - wm8900_work_type = WM8900_WORK_NULL; + snd_soc_dapm_new_controls(codec, wm8900_dapm_widgets, + ARRAY_SIZE(wm8900_dapm_widgets)); + + snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + + return 0; } static int wm8900_hw_params(struct snd_pcm_substream *substream, @@ -375,8 +630,6 @@ static int wm8900_hw_params(struct snd_pcm_substream *substream, struct snd_soc_codec *codec = socdev->card->codec; u16 reg; - WM8900_DBG("Enter:%s, %d \n", __FUNCTION__, __LINE__); - reg = snd_soc_read(codec, WM8900_REG_AUDIO1) & ~0x60; switch (params_format(params)) { @@ -397,6 +650,17 @@ static int wm8900_hw_params(struct snd_pcm_substream *substream, snd_soc_write(codec, WM8900_REG_AUDIO1, reg); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + reg = snd_soc_read(codec, WM8900_REG_DACCTRL); + + if (params_rate(params) <= 24000) + reg |= WM8900_REG_DACCTRL_DAC_SB_FILT; + else + reg &= ~WM8900_REG_DACCTRL_DAC_SB_FILT; + + snd_soc_write(codec, WM8900_REG_DACCTRL, reg); + } + return 0; } @@ -420,10 +684,8 @@ static int fll_factors(struct _fll_div *fll_div, unsigned int Fref, unsigned int K, Ndiv, Nmod, target; unsigned int div; - WM8900_DBG("Enter:%s, %d \n", __FUNCTION__, __LINE__); - BUG_ON(!Fout); - + /* The FLL must run at 90-100MHz which is then scaled down to * the output value by FLLCLK_DIV. */ target = Fout; @@ -486,8 +748,6 @@ static int wm8900_set_fll(struct snd_soc_codec *codec, struct _fll_div fll_div; unsigned int reg; - WM8900_DBG("Enter:%s, %d \n", __FUNCTION__, __LINE__); - if (wm8900->fll_in == freq_in && wm8900->fll_out == freq_out) return 0; @@ -555,9 +815,6 @@ reenable: static int wm8900_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, int source, unsigned int freq_in, unsigned int freq_out) { - - WM8900_DBG("Enter:%s, %d \n", __FUNCTION__, __LINE__); - return wm8900_set_fll(codec_dai->codec, pll_id, freq_in, freq_out); } @@ -567,8 +824,6 @@ static int wm8900_set_dai_clkdiv(struct snd_soc_dai *codec_dai, struct snd_soc_codec *codec = codec_dai->codec; unsigned int reg; - WM8900_DBG("Enter:%s, %d, div_id=%d, div=%d \n", __FUNCTION__, __LINE__, div_id, div); - switch (div_id) { case WM8900_BCLK_DIV: reg = snd_soc_read(codec, WM8900_REG_CLOCKING1); @@ -619,8 +874,6 @@ static int wm8900_set_dai_fmt(struct snd_soc_dai *codec_dai, struct snd_soc_codec *codec = codec_dai->codec; unsigned int clocking1, aif1, aif3, aif4; - WM8900_DBG("Enter:%s, %d, fmt=0x%08X \n", __FUNCTION__, __LINE__, fmt); - clocking1 = snd_soc_read(codec, WM8900_REG_CLOCKING1); aif1 = snd_soc_read(codec, WM8900_REG_AUDIO1); aif3 = snd_soc_read(codec, WM8900_REG_AUDIO3); @@ -730,106 +983,24 @@ static int wm8900_set_dai_fmt(struct snd_soc_dai *codec_dai, static int wm8900_digital_mute(struct snd_soc_dai *codec_dai, int mute) { - WM8900_DBG("Enter:%s, %d , mute = %d \n", __FUNCTION__, __LINE__, mute); - - return 0; -} - -static int wm8900_startup(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_codec *codec = socdev->card->codec; - struct snd_soc_dai_link *machine = rtd->dai; - struct snd_soc_dai *codec_dai = machine->codec_dai; - - WM8900_DBG("Enter::%s----%d substream->stream:%s \n",__FUNCTION__,__LINE__, - substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? "PLAYBACK":"CAPTURE"); - - cancel_delayed_work_sync(&delayed_work); - wm8900_work_type = WM8900_WORK_NULL; - - wm8900_set_hw(codec); - - if (substream->stream == SNDRV_PCM_STREAM_CAPTURE || - codec_dai->capture.active) { - snd_soc_write(codec, WM8900_REG_POWER1, 0x211D); - } else if (!codec_dai->capture.active) { - snd_soc_write(codec, WM8900_REG_POWER1, 0x210D); - } - - return 0; -} - -static void wm8900_shutdown(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai_link *machine = rtd->dai; - struct snd_soc_dai *codec_dai = machine->codec_dai; - - WM8900_DBG("Enter::%s----%d substream->stream:%s \n",__FUNCTION__,__LINE__, - substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? "PLAYBACK":"CAPTURE"); - - if (substream->stream == SNDRV_PCM_STREAM_CAPTURE && - wm8900_work_type == WM8900_WORK_NULL) { - cancel_delayed_work_sync(&delayed_work); - wm8900_work_type = WM8900_WORK_POWERDOWN_CAPTURE; - queue_delayed_work(wm8900_workq, &delayed_work, - msecs_to_jiffies(3000)); - } -#ifdef WM8900_NO_POWEROFF - return; /* Let codec not going to power off for pop noise */ -#endif - - if (!codec_dai->capture.active && !codec_dai->playback.active) { - - cancel_delayed_work_sync(&delayed_work); - wm8900_work_type = WM8900_WORK_NULL; - - /* If codec is already shutdown, return */ - if (wm8900_current_status == WM8900_IS_SHUTDOWN) - return; - - WM8900_DBG("Is going to power down wm8900\n"); - - wm8900_work_type = WM8900_WORK_POWERDOWN_PLAYBACK_CAPTURE; - - /* If codec is useless, queue work to close it */ - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - queue_delayed_work(wm8900_workq, &delayed_work, - msecs_to_jiffies(1000)); - } else { - queue_delayed_work(wm8900_workq, &delayed_work, - msecs_to_jiffies(3000)); - } - } -} + struct snd_soc_codec *codec = codec_dai->codec; + u16 reg; -static int wm8900_trigger(struct snd_pcm_substream *substream, - int status, - struct snd_soc_dai *dai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai_link *machine = rtd->dai; - struct snd_soc_dai *codec_dai = machine->codec_dai; + reg = snd_soc_read(codec, WM8900_REG_DACCTRL); - WM8900_DBG("Enter::%s----%d status = %d substream->stream:%s \n",__FUNCTION__, __LINE__, status, - substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? "PLAYBACK":"CAPTURE"); + if (mute) + reg |= WM8900_REG_DACCTRL_MUTE; + else + reg &= ~WM8900_REG_DACCTRL_MUTE; - if(status == 1 || status == 0){ - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK){ - codec_dai->playback.active = status; - }else{ - codec_dai->capture.active = status; - } - } + snd_soc_write(codec, WM8900_REG_DACCTRL, reg); return 0; } -#define WM8900_RATES SNDRV_PCM_RATE_44100 +#define WM8900_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\ + SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000) #define WM8900_PCM_FORMATS \ (SNDRV_PCM_FORMAT_S16_LE | SNDRV_PCM_FORMAT_S20_3LE | \ @@ -841,9 +1012,6 @@ static struct snd_soc_dai_ops wm8900_dai_ops = { .set_pll = wm8900_set_dai_pll, .set_fmt = wm8900_set_dai_fmt, .digital_mute = wm8900_digital_mute, - .startup = wm8900_startup, - .shutdown = wm8900_shutdown, - .trigger = wm8900_trigger, }; struct snd_soc_dai wm8900_dai = { @@ -871,11 +1039,6 @@ static int wm8900_set_bias_level(struct snd_soc_codec *codec, { u16 reg; - WM8900_DBG("Enter:%s, %d, level=0x%08X \n", __FUNCTION__, __LINE__, level); - - codec->bias_level = level; - return 0; - switch (level) { case SND_SOC_BIAS_ON: /* Enable thermal shutdown */ @@ -960,7 +1123,6 @@ static int wm8900_set_bias_level(struct snd_soc_codec *codec, WM8900_REG_POWER2_SYSCLK_ENA); break; } - codec->bias_level = level; return 0; } @@ -974,15 +1136,6 @@ static int wm8900_suspend(struct platform_device *pdev, pm_message_t state) int fll_in = wm8900->fll_in; int ret; - WM8900_DBG("Enter:%s, %d \n", __FUNCTION__, __LINE__); - - cancel_delayed_work_sync(&delayed_work); - wm8900_work_type = WM8900_WORK_NULL; - -#ifdef WM8900_NO_POWEROFF - wm8900_powerdown(); -#endif - /* Stop the FLL in an orderly fashion */ ret = wm8900_set_fll(codec, 0, 0, 0); if (ret != 0) { @@ -1003,12 +1156,17 @@ static int wm8900_resume(struct platform_device *pdev) struct snd_soc_device *socdev = platform_get_drvdata(pdev); struct snd_soc_codec *codec = socdev->card->codec; struct wm8900_priv *wm8900 = snd_soc_codec_get_drvdata(codec); + u16 *cache; + int i, ret; + cache = kmemdup(codec->reg_cache, sizeof(wm8900_reg_defaults), + GFP_KERNEL); + + wm8900_reset(codec); wm8900_set_bias_level(codec, SND_SOC_BIAS_STANDBY); /* Restart the FLL? */ if (wm8900->fll_out) { - int ret; int fll_out = wm8900->fll_out; int fll_in = wm8900->fll_in; @@ -1022,19 +1180,18 @@ static int wm8900_resume(struct platform_device *pdev) } } -#ifdef WM8900_NO_POWEROFF - if (wm8900_current_status == WM8900_IS_SHUTDOWN) { - - cancel_delayed_work_sync(&delayed_work); - wm8900_work_type = WM8900_WORK_HW_SET; - queue_delayed_work(wm8900_workq, &delayed_work, - msecs_to_jiffies(1000)); - } -#endif + if (cache) { + for (i = 0; i < WM8900_MAXREG; i++) + snd_soc_write(codec, i, cache[i]); + kfree(cache); + } else + dev_err(&pdev->dev, "Unable to allocate register cache\n"); return 0; } +static struct snd_soc_codec *wm8900_codec; + static __devinit int wm8900_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { @@ -1043,8 +1200,6 @@ static __devinit int wm8900_i2c_probe(struct i2c_client *i2c, unsigned int reg; int ret; - WM8900_DBG("Enter:%s, %d \n", __FUNCTION__, __LINE__); - wm8900 = kzalloc(sizeof(struct wm8900_priv), GFP_KERNEL); if (wm8900 == NULL) return -ENOMEM; @@ -1085,6 +1240,31 @@ static __devinit int wm8900_i2c_probe(struct i2c_client *i2c, /* Turn the chip on */ wm8900_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + /* Latch the volume update bits */ + snd_soc_write(codec, WM8900_REG_LINVOL, + snd_soc_read(codec, WM8900_REG_LINVOL) | 0x100); + snd_soc_write(codec, WM8900_REG_RINVOL, + snd_soc_read(codec, WM8900_REG_RINVOL) | 0x100); + snd_soc_write(codec, WM8900_REG_LOUT1CTL, + snd_soc_read(codec, WM8900_REG_LOUT1CTL) | 0x100); + snd_soc_write(codec, WM8900_REG_ROUT1CTL, + snd_soc_read(codec, WM8900_REG_ROUT1CTL) | 0x100); + snd_soc_write(codec, WM8900_REG_LOUT2CTL, + snd_soc_read(codec, WM8900_REG_LOUT2CTL) | 0x100); + snd_soc_write(codec, WM8900_REG_ROUT2CTL, + snd_soc_read(codec, WM8900_REG_ROUT2CTL) | 0x100); + snd_soc_write(codec, WM8900_REG_LDAC_DV, + snd_soc_read(codec, WM8900_REG_LDAC_DV) | 0x100); + snd_soc_write(codec, WM8900_REG_RDAC_DV, + snd_soc_read(codec, WM8900_REG_RDAC_DV) | 0x100); + snd_soc_write(codec, WM8900_REG_LADC_DV, + snd_soc_read(codec, WM8900_REG_LADC_DV) | 0x100); + snd_soc_write(codec, WM8900_REG_RADC_DV, + snd_soc_read(codec, WM8900_REG_RADC_DV) | 0x100); + + /* Set the DAC and mixer output bias */ + snd_soc_write(codec, WM8900_REG_OUTBIASCTL, 0x81); + wm8900_dai.dev = &i2c->dev; wm8900_codec = codec; @@ -1113,8 +1293,6 @@ err: static __devexit int wm8900_i2c_remove(struct i2c_client *client) { - WM8900_DBG("Enter:%s, %d \n", __FUNCTION__, __LINE__); - snd_soc_unregister_dai(&wm8900_dai); snd_soc_unregister_codec(wm8900_codec); @@ -1127,12 +1305,6 @@ static __devexit int wm8900_i2c_remove(struct i2c_client *client) return 0; } -void wm8900_i2c_shutdown(struct i2c_client *client) -{ - WM8900_DBG("Enter:%s, %d \n", __FUNCTION__, __LINE__); - wm8900_powerdown(); -} - static const struct i2c_device_id wm8900_i2c_id[] = { { "wm8900", 0 }, { } @@ -1146,7 +1318,6 @@ static struct i2c_driver wm8900_i2c_driver = { }, .probe = wm8900_i2c_probe, .remove = __devexit_p(wm8900_i2c_remove), - .shutdown = wm8900_i2c_shutdown, .id_table = wm8900_i2c_id, }; @@ -1156,22 +1327,11 @@ static int wm8900_probe(struct platform_device *pdev) struct snd_soc_codec *codec; int ret = 0; -#ifndef WM8900_NO_POWEROFF - gpio_set_value(RK29_PIN1_PD6, GPIO_LOW); -#endif - - WM8900_DBG("Enter:%s, %d \n", __FUNCTION__, __LINE__); - if (!wm8900_codec) { dev_err(&pdev->dev, "I2C client not yet instantiated\n"); return -ENODEV; } -#if defined(SPK_CON) - gpio_request(SPK_CON,NULL); - gpio_direction_output(SPK_CON, GPIO_LOW); -#endif - codec = wm8900_codec; socdev->card->codec = codec; @@ -1182,17 +1342,9 @@ static int wm8900_probe(struct platform_device *pdev) goto pcm_err; } - wm8900_workq = create_freezeable_workqueue("wm8900"); - if (wm8900_workq == NULL) { - kfree(codec); - return -ENOMEM; - } - -#ifdef WM8900_NO_POWEROFF - wm8900_set_hw(codec); -#endif - - return ret; + snd_soc_add_controls(codec, wm8900_snd_controls, + ARRAY_SIZE(wm8900_snd_controls)); + wm8900_add_widgets(codec); pcm_err: return ret; diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c index 4f6df1f99fcd..19ad590ca0b3 100644 --- a/sound/soc/codecs/wm8988.c +++ b/sound/soc/codecs/wm8988.c @@ -28,18 +28,8 @@ #include #include -#include -#include - #include "wm8988.h" - -#if 0 -#define DBG(x...) printk(KERN_INFO x) -#else -#define DBG(x...) do { } while (0) -#endif - /* * wm8988 register cache * We can't read the WM8988 register space when we @@ -202,8 +192,6 @@ static int wm8988_lrc_control(struct snd_soc_dapm_widget *w, else adctl2 |= 0x4; - DBG("Enter::%s----%d, adctl2 = %x\n",__FUNCTION__,__LINE__,adctl2); - return snd_soc_write(codec, WM8988_ADCTL2, adctl2); } @@ -589,7 +577,6 @@ static int wm8988_set_dai_fmt(struct snd_soc_dai *codec_dai, return -EINVAL; } - DBG("Enter::%s----%d iface=%x\n",__FUNCTION__,__LINE__,iface); snd_soc_write(codec, WM8988_IFACE, iface); return 0; } @@ -603,7 +590,6 @@ static int wm8988_pcm_startup(struct snd_pcm_substream *substream, /* The set of sample rates that can be supported depends on the * MCLK supplied to the CODEC - enforce this. */ - DBG("Enter::%s----%d wm8988->sysclk=%d\n",__FUNCTION__,__LINE__,wm8988->sysclk); if (!wm8988->sysclk) { dev_err(codec->dev, "No MCLK configured, call set_sysclk() on init\n"); @@ -628,7 +614,7 @@ static int wm8988_pcm_hw_params(struct snd_pcm_substream *substream, u16 iface = snd_soc_read(codec, WM8988_IFACE) & 0x1f3; u16 srate = snd_soc_read(codec, WM8988_SRATE) & 0x180; int coeff; - + coeff = get_coeff(wm8988->sysclk, params_rate(params)); if (coeff < 0) { coeff = get_coeff(wm8988->sysclk / 2, params_rate(params)); @@ -655,7 +641,6 @@ static int wm8988_pcm_hw_params(struct snd_pcm_substream *substream, iface |= 0x000c; break; } - DBG("Enter::%s----%d iface=%x srate =%x rate=%d\n",__FUNCTION__,__LINE__,iface,srate,params_rate(params)); /* set iface & srate */ snd_soc_write(codec, WM8988_IFACE, iface); @@ -670,7 +655,7 @@ static int wm8988_mute(struct snd_soc_dai *dai, int mute) { struct snd_soc_codec *codec = dai->codec; u16 mute_reg = snd_soc_read(codec, WM8988_ADCDAC) & 0xfff7; - DBG("Enter::%s----%d--mute=%d\n",__FUNCTION__,__LINE__,mute); + if (mute) snd_soc_write(codec, WM8988_ADCDAC, mute_reg | 0x8); else @@ -682,7 +667,7 @@ static int wm8988_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { u16 pwr_reg = snd_soc_read(codec, WM8988_PWR1) & ~0x1c1; - DBG("Enter::%s----%d level =%d\n",__FUNCTION__,__LINE__,level); + switch (level) { case SND_SOC_BIAS_ON: break; @@ -751,7 +736,7 @@ static int wm8988_suspend(struct platform_device *pdev, pm_message_t state) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); struct snd_soc_codec *codec = socdev->card->codec; - DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); + wm8988_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; } @@ -763,7 +748,7 @@ static int wm8988_resume(struct platform_device *pdev) int i; u8 data[2]; u16 *cache = codec->reg_cache; - DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); + /* Sync reg_cache with the hardware */ for (i = 0; i < WM8988_NUM_REG; i++) { if (i == WM8988_RESET) @@ -872,13 +857,7 @@ static int wm8988_register(struct wm8988_priv *wm8988, dev_err(codec->dev, "Failed to issue reset\n"); goto err; } -#if 1 - /*disable speaker */ - gpio_request(RK2818_PIN_PF7, "WM8988"); - rk2818_mux_api_set(GPIOE_SPI1_FLASH_SEL_NAME, IOMUXA_GPIO1_A3B7); - gpio_direction_output(RK2818_PIN_PF7,GPIO_HIGH); - -#endif + /* set the update bits (we always update left then right) */ reg = snd_soc_read(codec, WM8988_RADC); snd_soc_write(codec, WM8988_RADC, reg | 0x100); @@ -889,22 +868,7 @@ static int wm8988_register(struct wm8988_priv *wm8988, reg = snd_soc_read(codec, WM8988_ROUT2V); snd_soc_write(codec, WM8988_ROUT2V, reg | 0x0100); reg = snd_soc_read(codec, WM8988_RINVOL); - snd_soc_write(codec, WM8988_RINVOL, reg | 0x0100); - - snd_soc_write(codec, WM8988_LOUTM1, 0x120); - snd_soc_write(codec, WM8988_ROUTM2, 0x120); - snd_soc_write(codec, WM8988_LOUTM2, 0x0070); - snd_soc_write(codec, WM8988_ROUTM1, 0x0070); - - snd_soc_write(codec, WM8988_LOUT1V, 0x017f); - snd_soc_write(codec, WM8988_ROUT1V, 0x017f); - snd_soc_write(codec, WM8988_LDAC, 0xff); - snd_soc_write(codec, WM8988_RDAC, 0x1ff);//vol set - - snd_soc_write(codec, WM8988_SRATE,0x100); ///SET MCLK/8 - snd_soc_write(codec, WM8988_PWR1, 0x1cc); ///(0x80|0x40|0x20|0x08|0x04|0x10|0x02)); - snd_soc_write(codec, WM8988_PWR2, 0x1e0); //power r l out1 - + snd_soc_write(codec, WM8988_RINVOL, reg | 0x0100); wm8988_set_bias_level(&wm8988->codec, SND_SOC_BIAS_STANDBY); diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index b3526cb6e3f6..522249d5c2b4 100755 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -1,11 +1,11 @@ /* - * wm8994.c -- WM8994 ALSA SoC audio driver + * wm8994.c -- WM8994 ALSA SoC Audio driver * * Copyright 2009 Wolfson Microelectronics plc - * Copyright 2005 Openedhand Ltd. * * Author: Mark Brown * + * * 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. @@ -17,2747 +17,3583 @@ #include #include #include -#include #include +#include +#include #include #include #include -#include #include #include #include -#include -#include - -#include -#include +#include -#include "wm8994.h" -#include -#include #include #include #include #include -#define WM8994_PROC -#ifdef WM8994_PROC -#include -#include -#include -char debug_write_read = 0; -#endif - - -/* If digital BB is used,open this define. - Define what kind of digital BB is used. */ -#define TD688_MODE -//#define MU301_MODE -//#define CHONGY_MODE -//#define THINKWILL_M800_MODE - - -#if 1 -#define DBG(x...) printk(KERN_INFO x) -#else -#define DBG(x...) do { } while (0) -#endif +#include "wm8994.h" +#include "wm_hubs.h" static struct snd_soc_codec *wm8994_codec; +struct snd_soc_codec_device soc_codec_dev_wm8994; -enum wm8994_codec_mode -{ - wm8994_record_only, - wm8994_record_add, - wm8994_AP_to_speakers_and_headset, - wm8994_AP_to_headset, - wm8994_AP_to_speakers, - wm8994_handsetMIC_to_baseband_to_headset, - wm8994_mainMIC_to_baseband_to_headset, - wm8994_mainMIC_to_baseband_to_earpiece, - wm8994_mainMIC_to_baseband_to_speakers, - wm8994_BT_baseband, - null +struct fll_config { + int src; + int in; + int out; }; -/* wm8994_current_mode:save current wm8994 mode */ -unsigned char wm8994_current_mode=null; -enum stream_type_wm8994 -{ - VOICE_CALL =0, - BLUETOOTH_SCO =6, + +#define WM8994_NUM_DRC 3 +#define WM8994_NUM_EQ 3 + +static int wm8994_drc_base[] = { + WM8994_AIF1_DRC1_1, + WM8994_AIF1_DRC2_1, + WM8994_AIF2_DRC_1, }; -/* For voice device route set, add by phc */ -enum VoiceDeviceSwitch -{ - SPEAKER_INCALL, - SPEAKER_NORMAL, - - HEADSET_INCALL, - HEADSET_NORMAL, - - EARPIECE_INCALL, - EARPIECE_NORMAL, - - BLUETOOTH_SCO_INCALL, - BLUETOOTH_SCO_NORMAL, - - BLUETOOTH_A2DP_INCALL, - BLUETOOTH_A2DP_NORMAL, - - MIC_CAPTURE, - - EARPIECE_RINGTONE, - SPEAKER_RINGTONE, - HEADSET_RINGTONE, - - ALL_OPEN, - ALL_CLOSED + +static int wm8994_retune_mobile_base[] = { + WM8994_AIF1_DAC1_EQ_GAINS_1, + WM8994_AIF1_DAC2_EQ_GAINS_1, + WM8994_AIF2_EQ_GAINS_1, }; -//5:0 000000 0x3F -unsigned short headset_vol_table[6] ={0x012D,0x0133,0x0136,0x0139,0x013B,0x013D}; -unsigned short speakers_vol_table[6] ={0x012D,0x0133,0x0136,0x0139,0x013B,0x013D}; -unsigned short earpiece_vol_table[6] ={0x0127,0x012D,0x0130,0x0135,0x0139,0x013D};//normal -unsigned short BT_vol_table[16] ={0x01DB,0x01DC,0x01DD,0x01DE,0x01DF,0x01E0, - 0x01E1,0x01E2,0x01E3,0x01E4,0x01E5,0x01E6, - 0x01E7,0x01E8,0x01E9,0x01EA}; +#define WM8994_REG_CACHE_SIZE 0x621 -void (*handsetMIC_to_baseband_to_headset)(void); -void (*mainMIC_to_baseband_to_headset)(void); -void (*mainMIC_to_baseband_to_earpiece)(void); -void (*mainMIC_to_baseband_to_speakers)(void); -void (*BT_baseband)(void); +struct wm8994_micdet { + struct snd_soc_jack *jack; + int det; + int shrt; +}; /* codec private data */ struct wm8994_priv { - struct mutex io_lock; - struct mutex route_lock; - int route_status;//Because the time callback cannot use mutex - int sysclk; - int mclk; - int fmt;//master or salve - int rate;//Sampling rate + struct wm_hubs_data hubs; struct snd_soc_codec codec; - struct snd_kcontrol kcontrol;//The current working path - char RW_status; //ERROR = -1, TRUE = 0; + u16 reg_cache[WM8994_REG_CACHE_SIZE + 1]; + int sysclk[2]; + int sysclk_rate[2]; + int mclk[2]; + int aifclk[2]; + struct fll_config fll[2], fll_suspend[2]; + + int dac_rates[2]; + int lrclk_shared[2]; + + /* Platform dependant DRC configuration */ + const char **drc_texts; + int drc_cfg[WM8994_NUM_DRC]; + struct soc_enum drc_enum; + + /* Platform dependant ReTune mobile configuration */ + int num_retune_mobile_texts; + const char **retune_mobile_texts; + int retune_mobile_cfg[WM8994_NUM_EQ]; + struct soc_enum retune_mobile_enum; + + struct wm8994_micdet micdet[2]; + + int revision; struct wm8994_pdata *pdata; - - struct delayed_work wm8994_delayed_work; - int work_type; - - unsigned int playback_active:1; - unsigned int capture_active:1; - /* call_vol: save all kinds of system volume value. */ - unsigned char call_vol; - unsigned char BT_call_vol; +}; - struct wake_lock wm8994_on_wake; +static struct { + unsigned short readable; /* Mask of readable bits */ + unsigned short writable; /* Mask of writable bits */ + unsigned short vol; /* Mask of volatile bits */ +} access_masks[] = { + { 0xFFFF, 0xFFFF, 0x0000 }, /* R0 - Software Reset */ + { 0x3B37, 0x3B37, 0x0000 }, /* R1 - Power Management (1) */ + { 0x6BF0, 0x6BF0, 0x0000 }, /* R2 - Power Management (2) */ + { 0x3FF0, 0x3FF0, 0x0000 }, /* R3 - Power Management (3) */ + { 0x3F3F, 0x3F3F, 0x0000 }, /* R4 - Power Management (4) */ + { 0x3F0F, 0x3F0F, 0x0000 }, /* R5 - Power Management (5) */ + { 0x003F, 0x003F, 0x0000 }, /* R6 - Power Management (6) */ + { 0x0000, 0x0000, 0x0000 }, /* R7 */ + { 0x0000, 0x0000, 0x0000 }, /* R8 */ + { 0x0000, 0x0000, 0x0000 }, /* R9 */ + { 0x0000, 0x0000, 0x0000 }, /* R10 */ + { 0x0000, 0x0000, 0x0000 }, /* R11 */ + { 0x0000, 0x0000, 0x0000 }, /* R12 */ + { 0x0000, 0x0000, 0x0000 }, /* R13 */ + { 0x0000, 0x0000, 0x0000 }, /* R14 */ + { 0x0000, 0x0000, 0x0000 }, /* R15 */ + { 0x0000, 0x0000, 0x0000 }, /* R16 */ + { 0x0000, 0x0000, 0x0000 }, /* R17 */ + { 0x0000, 0x0000, 0x0000 }, /* R18 */ + { 0x0000, 0x0000, 0x0000 }, /* R19 */ + { 0x0000, 0x0000, 0x0000 }, /* R20 */ + { 0x01C0, 0x01C0, 0x0000 }, /* R21 - Input Mixer (1) */ + { 0x0000, 0x0000, 0x0000 }, /* R22 */ + { 0x0000, 0x0000, 0x0000 }, /* R23 */ + { 0x00DF, 0x01DF, 0x0000 }, /* R24 - Left Line Input 1&2 Volume */ + { 0x00DF, 0x01DF, 0x0000 }, /* R25 - Left Line Input 3&4 Volume */ + { 0x00DF, 0x01DF, 0x0000 }, /* R26 - Right Line Input 1&2 Volume */ + { 0x00DF, 0x01DF, 0x0000 }, /* R27 - Right Line Input 3&4 Volume */ + { 0x00FF, 0x01FF, 0x0000 }, /* R28 - Left Output Volume */ + { 0x00FF, 0x01FF, 0x0000 }, /* R29 - Right Output Volume */ + { 0x0077, 0x0077, 0x0000 }, /* R30 - Line Outputs Volume */ + { 0x0030, 0x0030, 0x0000 }, /* R31 - HPOUT2 Volume */ + { 0x00FF, 0x01FF, 0x0000 }, /* R32 - Left OPGA Volume */ + { 0x00FF, 0x01FF, 0x0000 }, /* R33 - Right OPGA Volume */ + { 0x007F, 0x007F, 0x0000 }, /* R34 - SPKMIXL Attenuation */ + { 0x017F, 0x017F, 0x0000 }, /* R35 - SPKMIXR Attenuation */ + { 0x003F, 0x003F, 0x0000 }, /* R36 - SPKOUT Mixers */ + { 0x003F, 0x003F, 0x0000 }, /* R37 - ClassD */ + { 0x00FF, 0x01FF, 0x0000 }, /* R38 - Speaker Volume Left */ + { 0x00FF, 0x01FF, 0x0000 }, /* R39 - Speaker Volume Right */ + { 0x00FF, 0x00FF, 0x0000 }, /* R40 - Input Mixer (2) */ + { 0x01B7, 0x01B7, 0x0000 }, /* R41 - Input Mixer (3) */ + { 0x01B7, 0x01B7, 0x0000 }, /* R42 - Input Mixer (4) */ + { 0x01C7, 0x01C7, 0x0000 }, /* R43 - Input Mixer (5) */ + { 0x01C7, 0x01C7, 0x0000 }, /* R44 - Input Mixer (6) */ + { 0x01FF, 0x01FF, 0x0000 }, /* R45 - Output Mixer (1) */ + { 0x01FF, 0x01FF, 0x0000 }, /* R46 - Output Mixer (2) */ + { 0x0FFF, 0x0FFF, 0x0000 }, /* R47 - Output Mixer (3) */ + { 0x0FFF, 0x0FFF, 0x0000 }, /* R48 - Output Mixer (4) */ + { 0x0FFF, 0x0FFF, 0x0000 }, /* R49 - Output Mixer (5) */ + { 0x0FFF, 0x0FFF, 0x0000 }, /* R50 - Output Mixer (6) */ + { 0x0038, 0x0038, 0x0000 }, /* R51 - HPOUT2 Mixer */ + { 0x0077, 0x0077, 0x0000 }, /* R52 - Line Mixer (1) */ + { 0x0077, 0x0077, 0x0000 }, /* R53 - Line Mixer (2) */ + { 0x03FF, 0x03FF, 0x0000 }, /* R54 - Speaker Mixer */ + { 0x00C1, 0x00C1, 0x0000 }, /* R55 - Additional Control */ + { 0x00F0, 0x00F0, 0x0000 }, /* R56 - AntiPOP (1) */ + { 0x01EF, 0x01EF, 0x0000 }, /* R57 - AntiPOP (2) */ + { 0x00FF, 0x00FF, 0x0000 }, /* R58 - MICBIAS */ + { 0x000F, 0x000F, 0x0000 }, /* R59 - LDO 1 */ + { 0x0007, 0x0007, 0x0000 }, /* R60 - LDO 2 */ + { 0x0000, 0x0000, 0x0000 }, /* R61 */ + { 0x0000, 0x0000, 0x0000 }, /* R62 */ + { 0x0000, 0x0000, 0x0000 }, /* R63 */ + { 0x0000, 0x0000, 0x0000 }, /* R64 */ + { 0x0000, 0x0000, 0x0000 }, /* R65 */ + { 0x0000, 0x0000, 0x0000 }, /* R66 */ + { 0x0000, 0x0000, 0x0000 }, /* R67 */ + { 0x0000, 0x0000, 0x0000 }, /* R68 */ + { 0x0000, 0x0000, 0x0000 }, /* R69 */ + { 0x0000, 0x0000, 0x0000 }, /* R70 */ + { 0x0000, 0x0000, 0x0000 }, /* R71 */ + { 0x0000, 0x0000, 0x0000 }, /* R72 */ + { 0x0000, 0x0000, 0x0000 }, /* R73 */ + { 0x0000, 0x0000, 0x0000 }, /* R74 */ + { 0x0000, 0x0000, 0x0000 }, /* R75 */ + { 0x8000, 0x8000, 0x0000 }, /* R76 - Charge Pump (1) */ + { 0x0000, 0x0000, 0x0000 }, /* R77 */ + { 0x0000, 0x0000, 0x0000 }, /* R78 */ + { 0x0000, 0x0000, 0x0000 }, /* R79 */ + { 0x0000, 0x0000, 0x0000 }, /* R80 */ + { 0x0301, 0x0301, 0x0000 }, /* R81 - Class W (1) */ + { 0x0000, 0x0000, 0x0000 }, /* R82 */ + { 0x0000, 0x0000, 0x0000 }, /* R83 */ + { 0x333F, 0x333F, 0x0000 }, /* R84 - DC Servo (1) */ + { 0x0FEF, 0x0FEF, 0x0000 }, /* R85 - DC Servo (2) */ + { 0x0000, 0x0000, 0x0000 }, /* R86 */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R87 - DC Servo (4) */ + { 0x0333, 0x0000, 0x0000 }, /* R88 - DC Servo Readback */ + { 0x0000, 0x0000, 0x0000 }, /* R89 */ + { 0x0000, 0x0000, 0x0000 }, /* R90 */ + { 0x0000, 0x0000, 0x0000 }, /* R91 */ + { 0x0000, 0x0000, 0x0000 }, /* R92 */ + { 0x0000, 0x0000, 0x0000 }, /* R93 */ + { 0x0000, 0x0000, 0x0000 }, /* R94 */ + { 0x0000, 0x0000, 0x0000 }, /* R95 */ + { 0x00EE, 0x00EE, 0x0000 }, /* R96 - Analogue HP (1) */ + { 0x0000, 0x0000, 0x0000 }, /* R97 */ + { 0x0000, 0x0000, 0x0000 }, /* R98 */ + { 0x0000, 0x0000, 0x0000 }, /* R99 */ + { 0x0000, 0x0000, 0x0000 }, /* R100 */ + { 0x0000, 0x0000, 0x0000 }, /* R101 */ + { 0x0000, 0x0000, 0x0000 }, /* R102 */ + { 0x0000, 0x0000, 0x0000 }, /* R103 */ + { 0x0000, 0x0000, 0x0000 }, /* R104 */ + { 0x0000, 0x0000, 0x0000 }, /* R105 */ + { 0x0000, 0x0000, 0x0000 }, /* R106 */ + { 0x0000, 0x0000, 0x0000 }, /* R107 */ + { 0x0000, 0x0000, 0x0000 }, /* R108 */ + { 0x0000, 0x0000, 0x0000 }, /* R109 */ + { 0x0000, 0x0000, 0x0000 }, /* R110 */ + { 0x0000, 0x0000, 0x0000 }, /* R111 */ + { 0x0000, 0x0000, 0x0000 }, /* R112 */ + { 0x0000, 0x0000, 0x0000 }, /* R113 */ + { 0x0000, 0x0000, 0x0000 }, /* R114 */ + { 0x0000, 0x0000, 0x0000 }, /* R115 */ + { 0x0000, 0x0000, 0x0000 }, /* R116 */ + { 0x0000, 0x0000, 0x0000 }, /* R117 */ + { 0x0000, 0x0000, 0x0000 }, /* R118 */ + { 0x0000, 0x0000, 0x0000 }, /* R119 */ + { 0x0000, 0x0000, 0x0000 }, /* R120 */ + { 0x0000, 0x0000, 0x0000 }, /* R121 */ + { 0x0000, 0x0000, 0x0000 }, /* R122 */ + { 0x0000, 0x0000, 0x0000 }, /* R123 */ + { 0x0000, 0x0000, 0x0000 }, /* R124 */ + { 0x0000, 0x0000, 0x0000 }, /* R125 */ + { 0x0000, 0x0000, 0x0000 }, /* R126 */ + { 0x0000, 0x0000, 0x0000 }, /* R127 */ + { 0x0000, 0x0000, 0x0000 }, /* R128 */ + { 0x0000, 0x0000, 0x0000 }, /* R129 */ + { 0x0000, 0x0000, 0x0000 }, /* R130 */ + { 0x0000, 0x0000, 0x0000 }, /* R131 */ + { 0x0000, 0x0000, 0x0000 }, /* R132 */ + { 0x0000, 0x0000, 0x0000 }, /* R133 */ + { 0x0000, 0x0000, 0x0000 }, /* R134 */ + { 0x0000, 0x0000, 0x0000 }, /* R135 */ + { 0x0000, 0x0000, 0x0000 }, /* R136 */ + { 0x0000, 0x0000, 0x0000 }, /* R137 */ + { 0x0000, 0x0000, 0x0000 }, /* R138 */ + { 0x0000, 0x0000, 0x0000 }, /* R139 */ + { 0x0000, 0x0000, 0x0000 }, /* R140 */ + { 0x0000, 0x0000, 0x0000 }, /* R141 */ + { 0x0000, 0x0000, 0x0000 }, /* R142 */ + { 0x0000, 0x0000, 0x0000 }, /* R143 */ + { 0x0000, 0x0000, 0x0000 }, /* R144 */ + { 0x0000, 0x0000, 0x0000 }, /* R145 */ + { 0x0000, 0x0000, 0x0000 }, /* R146 */ + { 0x0000, 0x0000, 0x0000 }, /* R147 */ + { 0x0000, 0x0000, 0x0000 }, /* R148 */ + { 0x0000, 0x0000, 0x0000 }, /* R149 */ + { 0x0000, 0x0000, 0x0000 }, /* R150 */ + { 0x0000, 0x0000, 0x0000 }, /* R151 */ + { 0x0000, 0x0000, 0x0000 }, /* R152 */ + { 0x0000, 0x0000, 0x0000 }, /* R153 */ + { 0x0000, 0x0000, 0x0000 }, /* R154 */ + { 0x0000, 0x0000, 0x0000 }, /* R155 */ + { 0x0000, 0x0000, 0x0000 }, /* R156 */ + { 0x0000, 0x0000, 0x0000 }, /* R157 */ + { 0x0000, 0x0000, 0x0000 }, /* R158 */ + { 0x0000, 0x0000, 0x0000 }, /* R159 */ + { 0x0000, 0x0000, 0x0000 }, /* R160 */ + { 0x0000, 0x0000, 0x0000 }, /* R161 */ + { 0x0000, 0x0000, 0x0000 }, /* R162 */ + { 0x0000, 0x0000, 0x0000 }, /* R163 */ + { 0x0000, 0x0000, 0x0000 }, /* R164 */ + { 0x0000, 0x0000, 0x0000 }, /* R165 */ + { 0x0000, 0x0000, 0x0000 }, /* R166 */ + { 0x0000, 0x0000, 0x0000 }, /* R167 */ + { 0x0000, 0x0000, 0x0000 }, /* R168 */ + { 0x0000, 0x0000, 0x0000 }, /* R169 */ + { 0x0000, 0x0000, 0x0000 }, /* R170 */ + { 0x0000, 0x0000, 0x0000 }, /* R171 */ + { 0x0000, 0x0000, 0x0000 }, /* R172 */ + { 0x0000, 0x0000, 0x0000 }, /* R173 */ + { 0x0000, 0x0000, 0x0000 }, /* R174 */ + { 0x0000, 0x0000, 0x0000 }, /* R175 */ + { 0x0000, 0x0000, 0x0000 }, /* R176 */ + { 0x0000, 0x0000, 0x0000 }, /* R177 */ + { 0x0000, 0x0000, 0x0000 }, /* R178 */ + { 0x0000, 0x0000, 0x0000 }, /* R179 */ + { 0x0000, 0x0000, 0x0000 }, /* R180 */ + { 0x0000, 0x0000, 0x0000 }, /* R181 */ + { 0x0000, 0x0000, 0x0000 }, /* R182 */ + { 0x0000, 0x0000, 0x0000 }, /* R183 */ + { 0x0000, 0x0000, 0x0000 }, /* R184 */ + { 0x0000, 0x0000, 0x0000 }, /* R185 */ + { 0x0000, 0x0000, 0x0000 }, /* R186 */ + { 0x0000, 0x0000, 0x0000 }, /* R187 */ + { 0x0000, 0x0000, 0x0000 }, /* R188 */ + { 0x0000, 0x0000, 0x0000 }, /* R189 */ + { 0x0000, 0x0000, 0x0000 }, /* R190 */ + { 0x0000, 0x0000, 0x0000 }, /* R191 */ + { 0x0000, 0x0000, 0x0000 }, /* R192 */ + { 0x0000, 0x0000, 0x0000 }, /* R193 */ + { 0x0000, 0x0000, 0x0000 }, /* R194 */ + { 0x0000, 0x0000, 0x0000 }, /* R195 */ + { 0x0000, 0x0000, 0x0000 }, /* R196 */ + { 0x0000, 0x0000, 0x0000 }, /* R197 */ + { 0x0000, 0x0000, 0x0000 }, /* R198 */ + { 0x0000, 0x0000, 0x0000 }, /* R199 */ + { 0x0000, 0x0000, 0x0000 }, /* R200 */ + { 0x0000, 0x0000, 0x0000 }, /* R201 */ + { 0x0000, 0x0000, 0x0000 }, /* R202 */ + { 0x0000, 0x0000, 0x0000 }, /* R203 */ + { 0x0000, 0x0000, 0x0000 }, /* R204 */ + { 0x0000, 0x0000, 0x0000 }, /* R205 */ + { 0x0000, 0x0000, 0x0000 }, /* R206 */ + { 0x0000, 0x0000, 0x0000 }, /* R207 */ + { 0x0000, 0x0000, 0x0000 }, /* R208 */ + { 0x0000, 0x0000, 0x0000 }, /* R209 */ + { 0x0000, 0x0000, 0x0000 }, /* R210 */ + { 0x0000, 0x0000, 0x0000 }, /* R211 */ + { 0x0000, 0x0000, 0x0000 }, /* R212 */ + { 0x0000, 0x0000, 0x0000 }, /* R213 */ + { 0x0000, 0x0000, 0x0000 }, /* R214 */ + { 0x0000, 0x0000, 0x0000 }, /* R215 */ + { 0x0000, 0x0000, 0x0000 }, /* R216 */ + { 0x0000, 0x0000, 0x0000 }, /* R217 */ + { 0x0000, 0x0000, 0x0000 }, /* R218 */ + { 0x0000, 0x0000, 0x0000 }, /* R219 */ + { 0x0000, 0x0000, 0x0000 }, /* R220 */ + { 0x0000, 0x0000, 0x0000 }, /* R221 */ + { 0x0000, 0x0000, 0x0000 }, /* R222 */ + { 0x0000, 0x0000, 0x0000 }, /* R223 */ + { 0x0000, 0x0000, 0x0000 }, /* R224 */ + { 0x0000, 0x0000, 0x0000 }, /* R225 */ + { 0x0000, 0x0000, 0x0000 }, /* R226 */ + { 0x0000, 0x0000, 0x0000 }, /* R227 */ + { 0x0000, 0x0000, 0x0000 }, /* R228 */ + { 0x0000, 0x0000, 0x0000 }, /* R229 */ + { 0x0000, 0x0000, 0x0000 }, /* R230 */ + { 0x0000, 0x0000, 0x0000 }, /* R231 */ + { 0x0000, 0x0000, 0x0000 }, /* R232 */ + { 0x0000, 0x0000, 0x0000 }, /* R233 */ + { 0x0000, 0x0000, 0x0000 }, /* R234 */ + { 0x0000, 0x0000, 0x0000 }, /* R235 */ + { 0x0000, 0x0000, 0x0000 }, /* R236 */ + { 0x0000, 0x0000, 0x0000 }, /* R237 */ + { 0x0000, 0x0000, 0x0000 }, /* R238 */ + { 0x0000, 0x0000, 0x0000 }, /* R239 */ + { 0x0000, 0x0000, 0x0000 }, /* R240 */ + { 0x0000, 0x0000, 0x0000 }, /* R241 */ + { 0x0000, 0x0000, 0x0000 }, /* R242 */ + { 0x0000, 0x0000, 0x0000 }, /* R243 */ + { 0x0000, 0x0000, 0x0000 }, /* R244 */ + { 0x0000, 0x0000, 0x0000 }, /* R245 */ + { 0x0000, 0x0000, 0x0000 }, /* R246 */ + { 0x0000, 0x0000, 0x0000 }, /* R247 */ + { 0x0000, 0x0000, 0x0000 }, /* R248 */ + { 0x0000, 0x0000, 0x0000 }, /* R249 */ + { 0x0000, 0x0000, 0x0000 }, /* R250 */ + { 0x0000, 0x0000, 0x0000 }, /* R251 */ + { 0x0000, 0x0000, 0x0000 }, /* R252 */ + { 0x0000, 0x0000, 0x0000 }, /* R253 */ + { 0x0000, 0x0000, 0x0000 }, /* R254 */ + { 0x0000, 0x0000, 0x0000 }, /* R255 */ + { 0x000F, 0x0000, 0x0000 }, /* R256 - Chip Revision */ + { 0x0074, 0x0074, 0x0000 }, /* R257 - Control Interface */ + { 0x0000, 0x0000, 0x0000 }, /* R258 */ + { 0x0000, 0x0000, 0x0000 }, /* R259 */ + { 0x0000, 0x0000, 0x0000 }, /* R260 */ + { 0x0000, 0x0000, 0x0000 }, /* R261 */ + { 0x0000, 0x0000, 0x0000 }, /* R262 */ + { 0x0000, 0x0000, 0x0000 }, /* R263 */ + { 0x0000, 0x0000, 0x0000 }, /* R264 */ + { 0x0000, 0x0000, 0x0000 }, /* R265 */ + { 0x0000, 0x0000, 0x0000 }, /* R266 */ + { 0x0000, 0x0000, 0x0000 }, /* R267 */ + { 0x0000, 0x0000, 0x0000 }, /* R268 */ + { 0x0000, 0x0000, 0x0000 }, /* R269 */ + { 0x0000, 0x0000, 0x0000 }, /* R270 */ + { 0x0000, 0x0000, 0x0000 }, /* R271 */ + { 0x807F, 0x837F, 0x0000 }, /* R272 - Write Sequencer Ctrl (1) */ + { 0x017F, 0x0000, 0x0000 }, /* R273 - Write Sequencer Ctrl (2) */ + { 0x0000, 0x0000, 0x0000 }, /* R274 */ + { 0x0000, 0x0000, 0x0000 }, /* R275 */ + { 0x0000, 0x0000, 0x0000 }, /* R276 */ + { 0x0000, 0x0000, 0x0000 }, /* R277 */ + { 0x0000, 0x0000, 0x0000 }, /* R278 */ + { 0x0000, 0x0000, 0x0000 }, /* R279 */ + { 0x0000, 0x0000, 0x0000 }, /* R280 */ + { 0x0000, 0x0000, 0x0000 }, /* R281 */ + { 0x0000, 0x0000, 0x0000 }, /* R282 */ + { 0x0000, 0x0000, 0x0000 }, /* R283 */ + { 0x0000, 0x0000, 0x0000 }, /* R284 */ + { 0x0000, 0x0000, 0x0000 }, /* R285 */ + { 0x0000, 0x0000, 0x0000 }, /* R286 */ + { 0x0000, 0x0000, 0x0000 }, /* R287 */ + { 0x0000, 0x0000, 0x0000 }, /* R288 */ + { 0x0000, 0x0000, 0x0000 }, /* R289 */ + { 0x0000, 0x0000, 0x0000 }, /* R290 */ + { 0x0000, 0x0000, 0x0000 }, /* R291 */ + { 0x0000, 0x0000, 0x0000 }, /* R292 */ + { 0x0000, 0x0000, 0x0000 }, /* R293 */ + { 0x0000, 0x0000, 0x0000 }, /* R294 */ + { 0x0000, 0x0000, 0x0000 }, /* R295 */ + { 0x0000, 0x0000, 0x0000 }, /* R296 */ + { 0x0000, 0x0000, 0x0000 }, /* R297 */ + { 0x0000, 0x0000, 0x0000 }, /* R298 */ + { 0x0000, 0x0000, 0x0000 }, /* R299 */ + { 0x0000, 0x0000, 0x0000 }, /* R300 */ + { 0x0000, 0x0000, 0x0000 }, /* R301 */ + { 0x0000, 0x0000, 0x0000 }, /* R302 */ + { 0x0000, 0x0000, 0x0000 }, /* R303 */ + { 0x0000, 0x0000, 0x0000 }, /* R304 */ + { 0x0000, 0x0000, 0x0000 }, /* R305 */ + { 0x0000, 0x0000, 0x0000 }, /* R306 */ + { 0x0000, 0x0000, 0x0000 }, /* R307 */ + { 0x0000, 0x0000, 0x0000 }, /* R308 */ + { 0x0000, 0x0000, 0x0000 }, /* R309 */ + { 0x0000, 0x0000, 0x0000 }, /* R310 */ + { 0x0000, 0x0000, 0x0000 }, /* R311 */ + { 0x0000, 0x0000, 0x0000 }, /* R312 */ + { 0x0000, 0x0000, 0x0000 }, /* R313 */ + { 0x0000, 0x0000, 0x0000 }, /* R314 */ + { 0x0000, 0x0000, 0x0000 }, /* R315 */ + { 0x0000, 0x0000, 0x0000 }, /* R316 */ + { 0x0000, 0x0000, 0x0000 }, /* R317 */ + { 0x0000, 0x0000, 0x0000 }, /* R318 */ + { 0x0000, 0x0000, 0x0000 }, /* R319 */ + { 0x0000, 0x0000, 0x0000 }, /* R320 */ + { 0x0000, 0x0000, 0x0000 }, /* R321 */ + { 0x0000, 0x0000, 0x0000 }, /* R322 */ + { 0x0000, 0x0000, 0x0000 }, /* R323 */ + { 0x0000, 0x0000, 0x0000 }, /* R324 */ + { 0x0000, 0x0000, 0x0000 }, /* R325 */ + { 0x0000, 0x0000, 0x0000 }, /* R326 */ + { 0x0000, 0x0000, 0x0000 }, /* R327 */ + { 0x0000, 0x0000, 0x0000 }, /* R328 */ + { 0x0000, 0x0000, 0x0000 }, /* R329 */ + { 0x0000, 0x0000, 0x0000 }, /* R330 */ + { 0x0000, 0x0000, 0x0000 }, /* R331 */ + { 0x0000, 0x0000, 0x0000 }, /* R332 */ + { 0x0000, 0x0000, 0x0000 }, /* R333 */ + { 0x0000, 0x0000, 0x0000 }, /* R334 */ + { 0x0000, 0x0000, 0x0000 }, /* R335 */ + { 0x0000, 0x0000, 0x0000 }, /* R336 */ + { 0x0000, 0x0000, 0x0000 }, /* R337 */ + { 0x0000, 0x0000, 0x0000 }, /* R338 */ + { 0x0000, 0x0000, 0x0000 }, /* R339 */ + { 0x0000, 0x0000, 0x0000 }, /* R340 */ + { 0x0000, 0x0000, 0x0000 }, /* R341 */ + { 0x0000, 0x0000, 0x0000 }, /* R342 */ + { 0x0000, 0x0000, 0x0000 }, /* R343 */ + { 0x0000, 0x0000, 0x0000 }, /* R344 */ + { 0x0000, 0x0000, 0x0000 }, /* R345 */ + { 0x0000, 0x0000, 0x0000 }, /* R346 */ + { 0x0000, 0x0000, 0x0000 }, /* R347 */ + { 0x0000, 0x0000, 0x0000 }, /* R348 */ + { 0x0000, 0x0000, 0x0000 }, /* R349 */ + { 0x0000, 0x0000, 0x0000 }, /* R350 */ + { 0x0000, 0x0000, 0x0000 }, /* R351 */ + { 0x0000, 0x0000, 0x0000 }, /* R352 */ + { 0x0000, 0x0000, 0x0000 }, /* R353 */ + { 0x0000, 0x0000, 0x0000 }, /* R354 */ + { 0x0000, 0x0000, 0x0000 }, /* R355 */ + { 0x0000, 0x0000, 0x0000 }, /* R356 */ + { 0x0000, 0x0000, 0x0000 }, /* R357 */ + { 0x0000, 0x0000, 0x0000 }, /* R358 */ + { 0x0000, 0x0000, 0x0000 }, /* R359 */ + { 0x0000, 0x0000, 0x0000 }, /* R360 */ + { 0x0000, 0x0000, 0x0000 }, /* R361 */ + { 0x0000, 0x0000, 0x0000 }, /* R362 */ + { 0x0000, 0x0000, 0x0000 }, /* R363 */ + { 0x0000, 0x0000, 0x0000 }, /* R364 */ + { 0x0000, 0x0000, 0x0000 }, /* R365 */ + { 0x0000, 0x0000, 0x0000 }, /* R366 */ + { 0x0000, 0x0000, 0x0000 }, /* R367 */ + { 0x0000, 0x0000, 0x0000 }, /* R368 */ + { 0x0000, 0x0000, 0x0000 }, /* R369 */ + { 0x0000, 0x0000, 0x0000 }, /* R370 */ + { 0x0000, 0x0000, 0x0000 }, /* R371 */ + { 0x0000, 0x0000, 0x0000 }, /* R372 */ + { 0x0000, 0x0000, 0x0000 }, /* R373 */ + { 0x0000, 0x0000, 0x0000 }, /* R374 */ + { 0x0000, 0x0000, 0x0000 }, /* R375 */ + { 0x0000, 0x0000, 0x0000 }, /* R376 */ + { 0x0000, 0x0000, 0x0000 }, /* R377 */ + { 0x0000, 0x0000, 0x0000 }, /* R378 */ + { 0x0000, 0x0000, 0x0000 }, /* R379 */ + { 0x0000, 0x0000, 0x0000 }, /* R380 */ + { 0x0000, 0x0000, 0x0000 }, /* R381 */ + { 0x0000, 0x0000, 0x0000 }, /* R382 */ + { 0x0000, 0x0000, 0x0000 }, /* R383 */ + { 0x0000, 0x0000, 0x0000 }, /* R384 */ + { 0x0000, 0x0000, 0x0000 }, /* R385 */ + { 0x0000, 0x0000, 0x0000 }, /* R386 */ + { 0x0000, 0x0000, 0x0000 }, /* R387 */ + { 0x0000, 0x0000, 0x0000 }, /* R388 */ + { 0x0000, 0x0000, 0x0000 }, /* R389 */ + { 0x0000, 0x0000, 0x0000 }, /* R390 */ + { 0x0000, 0x0000, 0x0000 }, /* R391 */ + { 0x0000, 0x0000, 0x0000 }, /* R392 */ + { 0x0000, 0x0000, 0x0000 }, /* R393 */ + { 0x0000, 0x0000, 0x0000 }, /* R394 */ + { 0x0000, 0x0000, 0x0000 }, /* R395 */ + { 0x0000, 0x0000, 0x0000 }, /* R396 */ + { 0x0000, 0x0000, 0x0000 }, /* R397 */ + { 0x0000, 0x0000, 0x0000 }, /* R398 */ + { 0x0000, 0x0000, 0x0000 }, /* R399 */ + { 0x0000, 0x0000, 0x0000 }, /* R400 */ + { 0x0000, 0x0000, 0x0000 }, /* R401 */ + { 0x0000, 0x0000, 0x0000 }, /* R402 */ + { 0x0000, 0x0000, 0x0000 }, /* R403 */ + { 0x0000, 0x0000, 0x0000 }, /* R404 */ + { 0x0000, 0x0000, 0x0000 }, /* R405 */ + { 0x0000, 0x0000, 0x0000 }, /* R406 */ + { 0x0000, 0x0000, 0x0000 }, /* R407 */ + { 0x0000, 0x0000, 0x0000 }, /* R408 */ + { 0x0000, 0x0000, 0x0000 }, /* R409 */ + { 0x0000, 0x0000, 0x0000 }, /* R410 */ + { 0x0000, 0x0000, 0x0000 }, /* R411 */ + { 0x0000, 0x0000, 0x0000 }, /* R412 */ + { 0x0000, 0x0000, 0x0000 }, /* R413 */ + { 0x0000, 0x0000, 0x0000 }, /* R414 */ + { 0x0000, 0x0000, 0x0000 }, /* R415 */ + { 0x0000, 0x0000, 0x0000 }, /* R416 */ + { 0x0000, 0x0000, 0x0000 }, /* R417 */ + { 0x0000, 0x0000, 0x0000 }, /* R418 */ + { 0x0000, 0x0000, 0x0000 }, /* R419 */ + { 0x0000, 0x0000, 0x0000 }, /* R420 */ + { 0x0000, 0x0000, 0x0000 }, /* R421 */ + { 0x0000, 0x0000, 0x0000 }, /* R422 */ + { 0x0000, 0x0000, 0x0000 }, /* R423 */ + { 0x0000, 0x0000, 0x0000 }, /* R424 */ + { 0x0000, 0x0000, 0x0000 }, /* R425 */ + { 0x0000, 0x0000, 0x0000 }, /* R426 */ + { 0x0000, 0x0000, 0x0000 }, /* R427 */ + { 0x0000, 0x0000, 0x0000 }, /* R428 */ + { 0x0000, 0x0000, 0x0000 }, /* R429 */ + { 0x0000, 0x0000, 0x0000 }, /* R430 */ + { 0x0000, 0x0000, 0x0000 }, /* R431 */ + { 0x0000, 0x0000, 0x0000 }, /* R432 */ + { 0x0000, 0x0000, 0x0000 }, /* R433 */ + { 0x0000, 0x0000, 0x0000 }, /* R434 */ + { 0x0000, 0x0000, 0x0000 }, /* R435 */ + { 0x0000, 0x0000, 0x0000 }, /* R436 */ + { 0x0000, 0x0000, 0x0000 }, /* R437 */ + { 0x0000, 0x0000, 0x0000 }, /* R438 */ + { 0x0000, 0x0000, 0x0000 }, /* R439 */ + { 0x0000, 0x0000, 0x0000 }, /* R440 */ + { 0x0000, 0x0000, 0x0000 }, /* R441 */ + { 0x0000, 0x0000, 0x0000 }, /* R442 */ + { 0x0000, 0x0000, 0x0000 }, /* R443 */ + { 0x0000, 0x0000, 0x0000 }, /* R444 */ + { 0x0000, 0x0000, 0x0000 }, /* R445 */ + { 0x0000, 0x0000, 0x0000 }, /* R446 */ + { 0x0000, 0x0000, 0x0000 }, /* R447 */ + { 0x0000, 0x0000, 0x0000 }, /* R448 */ + { 0x0000, 0x0000, 0x0000 }, /* R449 */ + { 0x0000, 0x0000, 0x0000 }, /* R450 */ + { 0x0000, 0x0000, 0x0000 }, /* R451 */ + { 0x0000, 0x0000, 0x0000 }, /* R452 */ + { 0x0000, 0x0000, 0x0000 }, /* R453 */ + { 0x0000, 0x0000, 0x0000 }, /* R454 */ + { 0x0000, 0x0000, 0x0000 }, /* R455 */ + { 0x0000, 0x0000, 0x0000 }, /* R456 */ + { 0x0000, 0x0000, 0x0000 }, /* R457 */ + { 0x0000, 0x0000, 0x0000 }, /* R458 */ + { 0x0000, 0x0000, 0x0000 }, /* R459 */ + { 0x0000, 0x0000, 0x0000 }, /* R460 */ + { 0x0000, 0x0000, 0x0000 }, /* R461 */ + { 0x0000, 0x0000, 0x0000 }, /* R462 */ + { 0x0000, 0x0000, 0x0000 }, /* R463 */ + { 0x0000, 0x0000, 0x0000 }, /* R464 */ + { 0x0000, 0x0000, 0x0000 }, /* R465 */ + { 0x0000, 0x0000, 0x0000 }, /* R466 */ + { 0x0000, 0x0000, 0x0000 }, /* R467 */ + { 0x0000, 0x0000, 0x0000 }, /* R468 */ + { 0x0000, 0x0000, 0x0000 }, /* R469 */ + { 0x0000, 0x0000, 0x0000 }, /* R470 */ + { 0x0000, 0x0000, 0x0000 }, /* R471 */ + { 0x0000, 0x0000, 0x0000 }, /* R472 */ + { 0x0000, 0x0000, 0x0000 }, /* R473 */ + { 0x0000, 0x0000, 0x0000 }, /* R474 */ + { 0x0000, 0x0000, 0x0000 }, /* R475 */ + { 0x0000, 0x0000, 0x0000 }, /* R476 */ + { 0x0000, 0x0000, 0x0000 }, /* R477 */ + { 0x0000, 0x0000, 0x0000 }, /* R478 */ + { 0x0000, 0x0000, 0x0000 }, /* R479 */ + { 0x0000, 0x0000, 0x0000 }, /* R480 */ + { 0x0000, 0x0000, 0x0000 }, /* R481 */ + { 0x0000, 0x0000, 0x0000 }, /* R482 */ + { 0x0000, 0x0000, 0x0000 }, /* R483 */ + { 0x0000, 0x0000, 0x0000 }, /* R484 */ + { 0x0000, 0x0000, 0x0000 }, /* R485 */ + { 0x0000, 0x0000, 0x0000 }, /* R486 */ + { 0x0000, 0x0000, 0x0000 }, /* R487 */ + { 0x0000, 0x0000, 0x0000 }, /* R488 */ + { 0x0000, 0x0000, 0x0000 }, /* R489 */ + { 0x0000, 0x0000, 0x0000 }, /* R490 */ + { 0x0000, 0x0000, 0x0000 }, /* R491 */ + { 0x0000, 0x0000, 0x0000 }, /* R492 */ + { 0x0000, 0x0000, 0x0000 }, /* R493 */ + { 0x0000, 0x0000, 0x0000 }, /* R494 */ + { 0x0000, 0x0000, 0x0000 }, /* R495 */ + { 0x0000, 0x0000, 0x0000 }, /* R496 */ + { 0x0000, 0x0000, 0x0000 }, /* R497 */ + { 0x0000, 0x0000, 0x0000 }, /* R498 */ + { 0x0000, 0x0000, 0x0000 }, /* R499 */ + { 0x0000, 0x0000, 0x0000 }, /* R500 */ + { 0x0000, 0x0000, 0x0000 }, /* R501 */ + { 0x0000, 0x0000, 0x0000 }, /* R502 */ + { 0x0000, 0x0000, 0x0000 }, /* R503 */ + { 0x0000, 0x0000, 0x0000 }, /* R504 */ + { 0x0000, 0x0000, 0x0000 }, /* R505 */ + { 0x0000, 0x0000, 0x0000 }, /* R506 */ + { 0x0000, 0x0000, 0x0000 }, /* R507 */ + { 0x0000, 0x0000, 0x0000 }, /* R508 */ + { 0x0000, 0x0000, 0x0000 }, /* R509 */ + { 0x0000, 0x0000, 0x0000 }, /* R510 */ + { 0x0000, 0x0000, 0x0000 }, /* R511 */ + { 0x001F, 0x001F, 0x0000 }, /* R512 - AIF1 Clocking (1) */ + { 0x003F, 0x003F, 0x0000 }, /* R513 - AIF1 Clocking (2) */ + { 0x0000, 0x0000, 0x0000 }, /* R514 */ + { 0x0000, 0x0000, 0x0000 }, /* R515 */ + { 0x001F, 0x001F, 0x0000 }, /* R516 - AIF2 Clocking (1) */ + { 0x003F, 0x003F, 0x0000 }, /* R517 - AIF2 Clocking (2) */ + { 0x0000, 0x0000, 0x0000 }, /* R518 */ + { 0x0000, 0x0000, 0x0000 }, /* R519 */ + { 0x001F, 0x001F, 0x0000 }, /* R520 - Clocking (1) */ + { 0x0777, 0x0777, 0x0000 }, /* R521 - Clocking (2) */ + { 0x0000, 0x0000, 0x0000 }, /* R522 */ + { 0x0000, 0x0000, 0x0000 }, /* R523 */ + { 0x0000, 0x0000, 0x0000 }, /* R524 */ + { 0x0000, 0x0000, 0x0000 }, /* R525 */ + { 0x0000, 0x0000, 0x0000 }, /* R526 */ + { 0x0000, 0x0000, 0x0000 }, /* R527 */ + { 0x00FF, 0x00FF, 0x0000 }, /* R528 - AIF1 Rate */ + { 0x00FF, 0x00FF, 0x0000 }, /* R529 - AIF2 Rate */ + { 0x000F, 0x0000, 0x0000 }, /* R530 - Rate Status */ + { 0x0000, 0x0000, 0x0000 }, /* R531 */ + { 0x0000, 0x0000, 0x0000 }, /* R532 */ + { 0x0000, 0x0000, 0x0000 }, /* R533 */ + { 0x0000, 0x0000, 0x0000 }, /* R534 */ + { 0x0000, 0x0000, 0x0000 }, /* R535 */ + { 0x0000, 0x0000, 0x0000 }, /* R536 */ + { 0x0000, 0x0000, 0x0000 }, /* R537 */ + { 0x0000, 0x0000, 0x0000 }, /* R538 */ + { 0x0000, 0x0000, 0x0000 }, /* R539 */ + { 0x0000, 0x0000, 0x0000 }, /* R540 */ + { 0x0000, 0x0000, 0x0000 }, /* R541 */ + { 0x0000, 0x0000, 0x0000 }, /* R542 */ + { 0x0000, 0x0000, 0x0000 }, /* R543 */ + { 0x0007, 0x0007, 0x0000 }, /* R544 - FLL1 Control (1) */ + { 0x3F77, 0x3F77, 0x0000 }, /* R545 - FLL1 Control (2) */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R546 - FLL1 Control (3) */ + { 0x7FEF, 0x7FEF, 0x0000 }, /* R547 - FLL1 Control (4) */ + { 0x1FDB, 0x1FDB, 0x0000 }, /* R548 - FLL1 Control (5) */ + { 0x0000, 0x0000, 0x0000 }, /* R549 */ + { 0x0000, 0x0000, 0x0000 }, /* R550 */ + { 0x0000, 0x0000, 0x0000 }, /* R551 */ + { 0x0000, 0x0000, 0x0000 }, /* R552 */ + { 0x0000, 0x0000, 0x0000 }, /* R553 */ + { 0x0000, 0x0000, 0x0000 }, /* R554 */ + { 0x0000, 0x0000, 0x0000 }, /* R555 */ + { 0x0000, 0x0000, 0x0000 }, /* R556 */ + { 0x0000, 0x0000, 0x0000 }, /* R557 */ + { 0x0000, 0x0000, 0x0000 }, /* R558 */ + { 0x0000, 0x0000, 0x0000 }, /* R559 */ + { 0x0000, 0x0000, 0x0000 }, /* R560 */ + { 0x0000, 0x0000, 0x0000 }, /* R561 */ + { 0x0000, 0x0000, 0x0000 }, /* R562 */ + { 0x0000, 0x0000, 0x0000 }, /* R563 */ + { 0x0000, 0x0000, 0x0000 }, /* R564 */ + { 0x0000, 0x0000, 0x0000 }, /* R565 */ + { 0x0000, 0x0000, 0x0000 }, /* R566 */ + { 0x0000, 0x0000, 0x0000 }, /* R567 */ + { 0x0000, 0x0000, 0x0000 }, /* R568 */ + { 0x0000, 0x0000, 0x0000 }, /* R569 */ + { 0x0000, 0x0000, 0x0000 }, /* R570 */ + { 0x0000, 0x0000, 0x0000 }, /* R571 */ + { 0x0000, 0x0000, 0x0000 }, /* R572 */ + { 0x0000, 0x0000, 0x0000 }, /* R573 */ + { 0x0000, 0x0000, 0x0000 }, /* R574 */ + { 0x0000, 0x0000, 0x0000 }, /* R575 */ + { 0x0007, 0x0007, 0x0000 }, /* R576 - FLL2 Control (1) */ + { 0x3F77, 0x3F77, 0x0000 }, /* R577 - FLL2 Control (2) */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R578 - FLL2 Control (3) */ + { 0x7FEF, 0x7FEF, 0x0000 }, /* R579 - FLL2 Control (4) */ + { 0x1FDB, 0x1FDB, 0x0000 }, /* R580 - FLL2 Control (5) */ + { 0x0000, 0x0000, 0x0000 }, /* R581 */ + { 0x0000, 0x0000, 0x0000 }, /* R582 */ + { 0x0000, 0x0000, 0x0000 }, /* R583 */ + { 0x0000, 0x0000, 0x0000 }, /* R584 */ + { 0x0000, 0x0000, 0x0000 }, /* R585 */ + { 0x0000, 0x0000, 0x0000 }, /* R586 */ + { 0x0000, 0x0000, 0x0000 }, /* R587 */ + { 0x0000, 0x0000, 0x0000 }, /* R588 */ + { 0x0000, 0x0000, 0x0000 }, /* R589 */ + { 0x0000, 0x0000, 0x0000 }, /* R590 */ + { 0x0000, 0x0000, 0x0000 }, /* R591 */ + { 0x0000, 0x0000, 0x0000 }, /* R592 */ + { 0x0000, 0x0000, 0x0000 }, /* R593 */ + { 0x0000, 0x0000, 0x0000 }, /* R594 */ + { 0x0000, 0x0000, 0x0000 }, /* R595 */ + { 0x0000, 0x0000, 0x0000 }, /* R596 */ + { 0x0000, 0x0000, 0x0000 }, /* R597 */ + { 0x0000, 0x0000, 0x0000 }, /* R598 */ + { 0x0000, 0x0000, 0x0000 }, /* R599 */ + { 0x0000, 0x0000, 0x0000 }, /* R600 */ + { 0x0000, 0x0000, 0x0000 }, /* R601 */ + { 0x0000, 0x0000, 0x0000 }, /* R602 */ + { 0x0000, 0x0000, 0x0000 }, /* R603 */ + { 0x0000, 0x0000, 0x0000 }, /* R604 */ + { 0x0000, 0x0000, 0x0000 }, /* R605 */ + { 0x0000, 0x0000, 0x0000 }, /* R606 */ + { 0x0000, 0x0000, 0x0000 }, /* R607 */ + { 0x0000, 0x0000, 0x0000 }, /* R608 */ + { 0x0000, 0x0000, 0x0000 }, /* R609 */ + { 0x0000, 0x0000, 0x0000 }, /* R610 */ + { 0x0000, 0x0000, 0x0000 }, /* R611 */ + { 0x0000, 0x0000, 0x0000 }, /* R612 */ + { 0x0000, 0x0000, 0x0000 }, /* R613 */ + { 0x0000, 0x0000, 0x0000 }, /* R614 */ + { 0x0000, 0x0000, 0x0000 }, /* R615 */ + { 0x0000, 0x0000, 0x0000 }, /* R616 */ + { 0x0000, 0x0000, 0x0000 }, /* R617 */ + { 0x0000, 0x0000, 0x0000 }, /* R618 */ + { 0x0000, 0x0000, 0x0000 }, /* R619 */ + { 0x0000, 0x0000, 0x0000 }, /* R620 */ + { 0x0000, 0x0000, 0x0000 }, /* R621 */ + { 0x0000, 0x0000, 0x0000 }, /* R622 */ + { 0x0000, 0x0000, 0x0000 }, /* R623 */ + { 0x0000, 0x0000, 0x0000 }, /* R624 */ + { 0x0000, 0x0000, 0x0000 }, /* R625 */ + { 0x0000, 0x0000, 0x0000 }, /* R626 */ + { 0x0000, 0x0000, 0x0000 }, /* R627 */ + { 0x0000, 0x0000, 0x0000 }, /* R628 */ + { 0x0000, 0x0000, 0x0000 }, /* R629 */ + { 0x0000, 0x0000, 0x0000 }, /* R630 */ + { 0x0000, 0x0000, 0x0000 }, /* R631 */ + { 0x0000, 0x0000, 0x0000 }, /* R632 */ + { 0x0000, 0x0000, 0x0000 }, /* R633 */ + { 0x0000, 0x0000, 0x0000 }, /* R634 */ + { 0x0000, 0x0000, 0x0000 }, /* R635 */ + { 0x0000, 0x0000, 0x0000 }, /* R636 */ + { 0x0000, 0x0000, 0x0000 }, /* R637 */ + { 0x0000, 0x0000, 0x0000 }, /* R638 */ + { 0x0000, 0x0000, 0x0000 }, /* R639 */ + { 0x0000, 0x0000, 0x0000 }, /* R640 */ + { 0x0000, 0x0000, 0x0000 }, /* R641 */ + { 0x0000, 0x0000, 0x0000 }, /* R642 */ + { 0x0000, 0x0000, 0x0000 }, /* R643 */ + { 0x0000, 0x0000, 0x0000 }, /* R644 */ + { 0x0000, 0x0000, 0x0000 }, /* R645 */ + { 0x0000, 0x0000, 0x0000 }, /* R646 */ + { 0x0000, 0x0000, 0x0000 }, /* R647 */ + { 0x0000, 0x0000, 0x0000 }, /* R648 */ + { 0x0000, 0x0000, 0x0000 }, /* R649 */ + { 0x0000, 0x0000, 0x0000 }, /* R650 */ + { 0x0000, 0x0000, 0x0000 }, /* R651 */ + { 0x0000, 0x0000, 0x0000 }, /* R652 */ + { 0x0000, 0x0000, 0x0000 }, /* R653 */ + { 0x0000, 0x0000, 0x0000 }, /* R654 */ + { 0x0000, 0x0000, 0x0000 }, /* R655 */ + { 0x0000, 0x0000, 0x0000 }, /* R656 */ + { 0x0000, 0x0000, 0x0000 }, /* R657 */ + { 0x0000, 0x0000, 0x0000 }, /* R658 */ + { 0x0000, 0x0000, 0x0000 }, /* R659 */ + { 0x0000, 0x0000, 0x0000 }, /* R660 */ + { 0x0000, 0x0000, 0x0000 }, /* R661 */ + { 0x0000, 0x0000, 0x0000 }, /* R662 */ + { 0x0000, 0x0000, 0x0000 }, /* R663 */ + { 0x0000, 0x0000, 0x0000 }, /* R664 */ + { 0x0000, 0x0000, 0x0000 }, /* R665 */ + { 0x0000, 0x0000, 0x0000 }, /* R666 */ + { 0x0000, 0x0000, 0x0000 }, /* R667 */ + { 0x0000, 0x0000, 0x0000 }, /* R668 */ + { 0x0000, 0x0000, 0x0000 }, /* R669 */ + { 0x0000, 0x0000, 0x0000 }, /* R670 */ + { 0x0000, 0x0000, 0x0000 }, /* R671 */ + { 0x0000, 0x0000, 0x0000 }, /* R672 */ + { 0x0000, 0x0000, 0x0000 }, /* R673 */ + { 0x0000, 0x0000, 0x0000 }, /* R674 */ + { 0x0000, 0x0000, 0x0000 }, /* R675 */ + { 0x0000, 0x0000, 0x0000 }, /* R676 */ + { 0x0000, 0x0000, 0x0000 }, /* R677 */ + { 0x0000, 0x0000, 0x0000 }, /* R678 */ + { 0x0000, 0x0000, 0x0000 }, /* R679 */ + { 0x0000, 0x0000, 0x0000 }, /* R680 */ + { 0x0000, 0x0000, 0x0000 }, /* R681 */ + { 0x0000, 0x0000, 0x0000 }, /* R682 */ + { 0x0000, 0x0000, 0x0000 }, /* R683 */ + { 0x0000, 0x0000, 0x0000 }, /* R684 */ + { 0x0000, 0x0000, 0x0000 }, /* R685 */ + { 0x0000, 0x0000, 0x0000 }, /* R686 */ + { 0x0000, 0x0000, 0x0000 }, /* R687 */ + { 0x0000, 0x0000, 0x0000 }, /* R688 */ + { 0x0000, 0x0000, 0x0000 }, /* R689 */ + { 0x0000, 0x0000, 0x0000 }, /* R690 */ + { 0x0000, 0x0000, 0x0000 }, /* R691 */ + { 0x0000, 0x0000, 0x0000 }, /* R692 */ + { 0x0000, 0x0000, 0x0000 }, /* R693 */ + { 0x0000, 0x0000, 0x0000 }, /* R694 */ + { 0x0000, 0x0000, 0x0000 }, /* R695 */ + { 0x0000, 0x0000, 0x0000 }, /* R696 */ + { 0x0000, 0x0000, 0x0000 }, /* R697 */ + { 0x0000, 0x0000, 0x0000 }, /* R698 */ + { 0x0000, 0x0000, 0x0000 }, /* R699 */ + { 0x0000, 0x0000, 0x0000 }, /* R700 */ + { 0x0000, 0x0000, 0x0000 }, /* R701 */ + { 0x0000, 0x0000, 0x0000 }, /* R702 */ + { 0x0000, 0x0000, 0x0000 }, /* R703 */ + { 0x0000, 0x0000, 0x0000 }, /* R704 */ + { 0x0000, 0x0000, 0x0000 }, /* R705 */ + { 0x0000, 0x0000, 0x0000 }, /* R706 */ + { 0x0000, 0x0000, 0x0000 }, /* R707 */ + { 0x0000, 0x0000, 0x0000 }, /* R708 */ + { 0x0000, 0x0000, 0x0000 }, /* R709 */ + { 0x0000, 0x0000, 0x0000 }, /* R710 */ + { 0x0000, 0x0000, 0x0000 }, /* R711 */ + { 0x0000, 0x0000, 0x0000 }, /* R712 */ + { 0x0000, 0x0000, 0x0000 }, /* R713 */ + { 0x0000, 0x0000, 0x0000 }, /* R714 */ + { 0x0000, 0x0000, 0x0000 }, /* R715 */ + { 0x0000, 0x0000, 0x0000 }, /* R716 */ + { 0x0000, 0x0000, 0x0000 }, /* R717 */ + { 0x0000, 0x0000, 0x0000 }, /* R718 */ + { 0x0000, 0x0000, 0x0000 }, /* R719 */ + { 0x0000, 0x0000, 0x0000 }, /* R720 */ + { 0x0000, 0x0000, 0x0000 }, /* R721 */ + { 0x0000, 0x0000, 0x0000 }, /* R722 */ + { 0x0000, 0x0000, 0x0000 }, /* R723 */ + { 0x0000, 0x0000, 0x0000 }, /* R724 */ + { 0x0000, 0x0000, 0x0000 }, /* R725 */ + { 0x0000, 0x0000, 0x0000 }, /* R726 */ + { 0x0000, 0x0000, 0x0000 }, /* R727 */ + { 0x0000, 0x0000, 0x0000 }, /* R728 */ + { 0x0000, 0x0000, 0x0000 }, /* R729 */ + { 0x0000, 0x0000, 0x0000 }, /* R730 */ + { 0x0000, 0x0000, 0x0000 }, /* R731 */ + { 0x0000, 0x0000, 0x0000 }, /* R732 */ + { 0x0000, 0x0000, 0x0000 }, /* R733 */ + { 0x0000, 0x0000, 0x0000 }, /* R734 */ + { 0x0000, 0x0000, 0x0000 }, /* R735 */ + { 0x0000, 0x0000, 0x0000 }, /* R736 */ + { 0x0000, 0x0000, 0x0000 }, /* R737 */ + { 0x0000, 0x0000, 0x0000 }, /* R738 */ + { 0x0000, 0x0000, 0x0000 }, /* R739 */ + { 0x0000, 0x0000, 0x0000 }, /* R740 */ + { 0x0000, 0x0000, 0x0000 }, /* R741 */ + { 0x0000, 0x0000, 0x0000 }, /* R742 */ + { 0x0000, 0x0000, 0x0000 }, /* R743 */ + { 0x0000, 0x0000, 0x0000 }, /* R744 */ + { 0x0000, 0x0000, 0x0000 }, /* R745 */ + { 0x0000, 0x0000, 0x0000 }, /* R746 */ + { 0x0000, 0x0000, 0x0000 }, /* R747 */ + { 0x0000, 0x0000, 0x0000 }, /* R748 */ + { 0x0000, 0x0000, 0x0000 }, /* R749 */ + { 0x0000, 0x0000, 0x0000 }, /* R750 */ + { 0x0000, 0x0000, 0x0000 }, /* R751 */ + { 0x0000, 0x0000, 0x0000 }, /* R752 */ + { 0x0000, 0x0000, 0x0000 }, /* R753 */ + { 0x0000, 0x0000, 0x0000 }, /* R754 */ + { 0x0000, 0x0000, 0x0000 }, /* R755 */ + { 0x0000, 0x0000, 0x0000 }, /* R756 */ + { 0x0000, 0x0000, 0x0000 }, /* R757 */ + { 0x0000, 0x0000, 0x0000 }, /* R758 */ + { 0x0000, 0x0000, 0x0000 }, /* R759 */ + { 0x0000, 0x0000, 0x0000 }, /* R760 */ + { 0x0000, 0x0000, 0x0000 }, /* R761 */ + { 0x0000, 0x0000, 0x0000 }, /* R762 */ + { 0x0000, 0x0000, 0x0000 }, /* R763 */ + { 0x0000, 0x0000, 0x0000 }, /* R764 */ + { 0x0000, 0x0000, 0x0000 }, /* R765 */ + { 0x0000, 0x0000, 0x0000 }, /* R766 */ + { 0x0000, 0x0000, 0x0000 }, /* R767 */ + { 0xE1F8, 0xE1F8, 0x0000 }, /* R768 - AIF1 Control (1) */ + { 0xCD1F, 0xCD1F, 0x0000 }, /* R769 - AIF1 Control (2) */ + { 0xF000, 0xF000, 0x0000 }, /* R770 - AIF1 Master/Slave */ + { 0x01F0, 0x01F0, 0x0000 }, /* R771 - AIF1 BCLK */ + { 0x0FFF, 0x0FFF, 0x0000 }, /* R772 - AIF1ADC LRCLK */ + { 0x0FFF, 0x0FFF, 0x0000 }, /* R773 - AIF1DAC LRCLK */ + { 0x0003, 0x0003, 0x0000 }, /* R774 - AIF1DAC Data */ + { 0x0003, 0x0003, 0x0000 }, /* R775 - AIF1ADC Data */ + { 0x0000, 0x0000, 0x0000 }, /* R776 */ + { 0x0000, 0x0000, 0x0000 }, /* R777 */ + { 0x0000, 0x0000, 0x0000 }, /* R778 */ + { 0x0000, 0x0000, 0x0000 }, /* R779 */ + { 0x0000, 0x0000, 0x0000 }, /* R780 */ + { 0x0000, 0x0000, 0x0000 }, /* R781 */ + { 0x0000, 0x0000, 0x0000 }, /* R782 */ + { 0x0000, 0x0000, 0x0000 }, /* R783 */ + { 0xF1F8, 0xF1F8, 0x0000 }, /* R784 - AIF2 Control (1) */ + { 0xFD1F, 0xFD1F, 0x0000 }, /* R785 - AIF2 Control (2) */ + { 0xF000, 0xF000, 0x0000 }, /* R786 - AIF2 Master/Slave */ + { 0x01F0, 0x01F0, 0x0000 }, /* R787 - AIF2 BCLK */ + { 0x0FFF, 0x0FFF, 0x0000 }, /* R788 - AIF2ADC LRCLK */ + { 0x0FFF, 0x0FFF, 0x0000 }, /* R789 - AIF2DAC LRCLK */ + { 0x0003, 0x0003, 0x0000 }, /* R790 - AIF2DAC Data */ + { 0x0003, 0x0003, 0x0000 }, /* R791 - AIF2ADC Data */ + { 0x0000, 0x0000, 0x0000 }, /* R792 */ + { 0x0000, 0x0000, 0x0000 }, /* R793 */ + { 0x0000, 0x0000, 0x0000 }, /* R794 */ + { 0x0000, 0x0000, 0x0000 }, /* R795 */ + { 0x0000, 0x0000, 0x0000 }, /* R796 */ + { 0x0000, 0x0000, 0x0000 }, /* R797 */ + { 0x0000, 0x0000, 0x0000 }, /* R798 */ + { 0x0000, 0x0000, 0x0000 }, /* R799 */ + { 0x0000, 0x0000, 0x0000 }, /* R800 */ + { 0x0000, 0x0000, 0x0000 }, /* R801 */ + { 0x0000, 0x0000, 0x0000 }, /* R802 */ + { 0x0000, 0x0000, 0x0000 }, /* R803 */ + { 0x0000, 0x0000, 0x0000 }, /* R804 */ + { 0x0000, 0x0000, 0x0000 }, /* R805 */ + { 0x0000, 0x0000, 0x0000 }, /* R806 */ + { 0x0000, 0x0000, 0x0000 }, /* R807 */ + { 0x0000, 0x0000, 0x0000 }, /* R808 */ + { 0x0000, 0x0000, 0x0000 }, /* R809 */ + { 0x0000, 0x0000, 0x0000 }, /* R810 */ + { 0x0000, 0x0000, 0x0000 }, /* R811 */ + { 0x0000, 0x0000, 0x0000 }, /* R812 */ + { 0x0000, 0x0000, 0x0000 }, /* R813 */ + { 0x0000, 0x0000, 0x0000 }, /* R814 */ + { 0x0000, 0x0000, 0x0000 }, /* R815 */ + { 0x0000, 0x0000, 0x0000 }, /* R816 */ + { 0x0000, 0x0000, 0x0000 }, /* R817 */ + { 0x0000, 0x0000, 0x0000 }, /* R818 */ + { 0x0000, 0x0000, 0x0000 }, /* R819 */ + { 0x0000, 0x0000, 0x0000 }, /* R820 */ + { 0x0000, 0x0000, 0x0000 }, /* R821 */ + { 0x0000, 0x0000, 0x0000 }, /* R822 */ + { 0x0000, 0x0000, 0x0000 }, /* R823 */ + { 0x0000, 0x0000, 0x0000 }, /* R824 */ + { 0x0000, 0x0000, 0x0000 }, /* R825 */ + { 0x0000, 0x0000, 0x0000 }, /* R826 */ + { 0x0000, 0x0000, 0x0000 }, /* R827 */ + { 0x0000, 0x0000, 0x0000 }, /* R828 */ + { 0x0000, 0x0000, 0x0000 }, /* R829 */ + { 0x0000, 0x0000, 0x0000 }, /* R830 */ + { 0x0000, 0x0000, 0x0000 }, /* R831 */ + { 0x0000, 0x0000, 0x0000 }, /* R832 */ + { 0x0000, 0x0000, 0x0000 }, /* R833 */ + { 0x0000, 0x0000, 0x0000 }, /* R834 */ + { 0x0000, 0x0000, 0x0000 }, /* R835 */ + { 0x0000, 0x0000, 0x0000 }, /* R836 */ + { 0x0000, 0x0000, 0x0000 }, /* R837 */ + { 0x0000, 0x0000, 0x0000 }, /* R838 */ + { 0x0000, 0x0000, 0x0000 }, /* R839 */ + { 0x0000, 0x0000, 0x0000 }, /* R840 */ + { 0x0000, 0x0000, 0x0000 }, /* R841 */ + { 0x0000, 0x0000, 0x0000 }, /* R842 */ + { 0x0000, 0x0000, 0x0000 }, /* R843 */ + { 0x0000, 0x0000, 0x0000 }, /* R844 */ + { 0x0000, 0x0000, 0x0000 }, /* R845 */ + { 0x0000, 0x0000, 0x0000 }, /* R846 */ + { 0x0000, 0x0000, 0x0000 }, /* R847 */ + { 0x0000, 0x0000, 0x0000 }, /* R848 */ + { 0x0000, 0x0000, 0x0000 }, /* R849 */ + { 0x0000, 0x0000, 0x0000 }, /* R850 */ + { 0x0000, 0x0000, 0x0000 }, /* R851 */ + { 0x0000, 0x0000, 0x0000 }, /* R852 */ + { 0x0000, 0x0000, 0x0000 }, /* R853 */ + { 0x0000, 0x0000, 0x0000 }, /* R854 */ + { 0x0000, 0x0000, 0x0000 }, /* R855 */ + { 0x0000, 0x0000, 0x0000 }, /* R856 */ + { 0x0000, 0x0000, 0x0000 }, /* R857 */ + { 0x0000, 0x0000, 0x0000 }, /* R858 */ + { 0x0000, 0x0000, 0x0000 }, /* R859 */ + { 0x0000, 0x0000, 0x0000 }, /* R860 */ + { 0x0000, 0x0000, 0x0000 }, /* R861 */ + { 0x0000, 0x0000, 0x0000 }, /* R862 */ + { 0x0000, 0x0000, 0x0000 }, /* R863 */ + { 0x0000, 0x0000, 0x0000 }, /* R864 */ + { 0x0000, 0x0000, 0x0000 }, /* R865 */ + { 0x0000, 0x0000, 0x0000 }, /* R866 */ + { 0x0000, 0x0000, 0x0000 }, /* R867 */ + { 0x0000, 0x0000, 0x0000 }, /* R868 */ + { 0x0000, 0x0000, 0x0000 }, /* R869 */ + { 0x0000, 0x0000, 0x0000 }, /* R870 */ + { 0x0000, 0x0000, 0x0000 }, /* R871 */ + { 0x0000, 0x0000, 0x0000 }, /* R872 */ + { 0x0000, 0x0000, 0x0000 }, /* R873 */ + { 0x0000, 0x0000, 0x0000 }, /* R874 */ + { 0x0000, 0x0000, 0x0000 }, /* R875 */ + { 0x0000, 0x0000, 0x0000 }, /* R876 */ + { 0x0000, 0x0000, 0x0000 }, /* R877 */ + { 0x0000, 0x0000, 0x0000 }, /* R878 */ + { 0x0000, 0x0000, 0x0000 }, /* R879 */ + { 0x0000, 0x0000, 0x0000 }, /* R880 */ + { 0x0000, 0x0000, 0x0000 }, /* R881 */ + { 0x0000, 0x0000, 0x0000 }, /* R882 */ + { 0x0000, 0x0000, 0x0000 }, /* R883 */ + { 0x0000, 0x0000, 0x0000 }, /* R884 */ + { 0x0000, 0x0000, 0x0000 }, /* R885 */ + { 0x0000, 0x0000, 0x0000 }, /* R886 */ + { 0x0000, 0x0000, 0x0000 }, /* R887 */ + { 0x0000, 0x0000, 0x0000 }, /* R888 */ + { 0x0000, 0x0000, 0x0000 }, /* R889 */ + { 0x0000, 0x0000, 0x0000 }, /* R890 */ + { 0x0000, 0x0000, 0x0000 }, /* R891 */ + { 0x0000, 0x0000, 0x0000 }, /* R892 */ + { 0x0000, 0x0000, 0x0000 }, /* R893 */ + { 0x0000, 0x0000, 0x0000 }, /* R894 */ + { 0x0000, 0x0000, 0x0000 }, /* R895 */ + { 0x0000, 0x0000, 0x0000 }, /* R896 */ + { 0x0000, 0x0000, 0x0000 }, /* R897 */ + { 0x0000, 0x0000, 0x0000 }, /* R898 */ + { 0x0000, 0x0000, 0x0000 }, /* R899 */ + { 0x0000, 0x0000, 0x0000 }, /* R900 */ + { 0x0000, 0x0000, 0x0000 }, /* R901 */ + { 0x0000, 0x0000, 0x0000 }, /* R902 */ + { 0x0000, 0x0000, 0x0000 }, /* R903 */ + { 0x0000, 0x0000, 0x0000 }, /* R904 */ + { 0x0000, 0x0000, 0x0000 }, /* R905 */ + { 0x0000, 0x0000, 0x0000 }, /* R906 */ + { 0x0000, 0x0000, 0x0000 }, /* R907 */ + { 0x0000, 0x0000, 0x0000 }, /* R908 */ + { 0x0000, 0x0000, 0x0000 }, /* R909 */ + { 0x0000, 0x0000, 0x0000 }, /* R910 */ + { 0x0000, 0x0000, 0x0000 }, /* R911 */ + { 0x0000, 0x0000, 0x0000 }, /* R912 */ + { 0x0000, 0x0000, 0x0000 }, /* R913 */ + { 0x0000, 0x0000, 0x0000 }, /* R914 */ + { 0x0000, 0x0000, 0x0000 }, /* R915 */ + { 0x0000, 0x0000, 0x0000 }, /* R916 */ + { 0x0000, 0x0000, 0x0000 }, /* R917 */ + { 0x0000, 0x0000, 0x0000 }, /* R918 */ + { 0x0000, 0x0000, 0x0000 }, /* R919 */ + { 0x0000, 0x0000, 0x0000 }, /* R920 */ + { 0x0000, 0x0000, 0x0000 }, /* R921 */ + { 0x0000, 0x0000, 0x0000 }, /* R922 */ + { 0x0000, 0x0000, 0x0000 }, /* R923 */ + { 0x0000, 0x0000, 0x0000 }, /* R924 */ + { 0x0000, 0x0000, 0x0000 }, /* R925 */ + { 0x0000, 0x0000, 0x0000 }, /* R926 */ + { 0x0000, 0x0000, 0x0000 }, /* R927 */ + { 0x0000, 0x0000, 0x0000 }, /* R928 */ + { 0x0000, 0x0000, 0x0000 }, /* R929 */ + { 0x0000, 0x0000, 0x0000 }, /* R930 */ + { 0x0000, 0x0000, 0x0000 }, /* R931 */ + { 0x0000, 0x0000, 0x0000 }, /* R932 */ + { 0x0000, 0x0000, 0x0000 }, /* R933 */ + { 0x0000, 0x0000, 0x0000 }, /* R934 */ + { 0x0000, 0x0000, 0x0000 }, /* R935 */ + { 0x0000, 0x0000, 0x0000 }, /* R936 */ + { 0x0000, 0x0000, 0x0000 }, /* R937 */ + { 0x0000, 0x0000, 0x0000 }, /* R938 */ + { 0x0000, 0x0000, 0x0000 }, /* R939 */ + { 0x0000, 0x0000, 0x0000 }, /* R940 */ + { 0x0000, 0x0000, 0x0000 }, /* R941 */ + { 0x0000, 0x0000, 0x0000 }, /* R942 */ + { 0x0000, 0x0000, 0x0000 }, /* R943 */ + { 0x0000, 0x0000, 0x0000 }, /* R944 */ + { 0x0000, 0x0000, 0x0000 }, /* R945 */ + { 0x0000, 0x0000, 0x0000 }, /* R946 */ + { 0x0000, 0x0000, 0x0000 }, /* R947 */ + { 0x0000, 0x0000, 0x0000 }, /* R948 */ + { 0x0000, 0x0000, 0x0000 }, /* R949 */ + { 0x0000, 0x0000, 0x0000 }, /* R950 */ + { 0x0000, 0x0000, 0x0000 }, /* R951 */ + { 0x0000, 0x0000, 0x0000 }, /* R952 */ + { 0x0000, 0x0000, 0x0000 }, /* R953 */ + { 0x0000, 0x0000, 0x0000 }, /* R954 */ + { 0x0000, 0x0000, 0x0000 }, /* R955 */ + { 0x0000, 0x0000, 0x0000 }, /* R956 */ + { 0x0000, 0x0000, 0x0000 }, /* R957 */ + { 0x0000, 0x0000, 0x0000 }, /* R958 */ + { 0x0000, 0x0000, 0x0000 }, /* R959 */ + { 0x0000, 0x0000, 0x0000 }, /* R960 */ + { 0x0000, 0x0000, 0x0000 }, /* R961 */ + { 0x0000, 0x0000, 0x0000 }, /* R962 */ + { 0x0000, 0x0000, 0x0000 }, /* R963 */ + { 0x0000, 0x0000, 0x0000 }, /* R964 */ + { 0x0000, 0x0000, 0x0000 }, /* R965 */ + { 0x0000, 0x0000, 0x0000 }, /* R966 */ + { 0x0000, 0x0000, 0x0000 }, /* R967 */ + { 0x0000, 0x0000, 0x0000 }, /* R968 */ + { 0x0000, 0x0000, 0x0000 }, /* R969 */ + { 0x0000, 0x0000, 0x0000 }, /* R970 */ + { 0x0000, 0x0000, 0x0000 }, /* R971 */ + { 0x0000, 0x0000, 0x0000 }, /* R972 */ + { 0x0000, 0x0000, 0x0000 }, /* R973 */ + { 0x0000, 0x0000, 0x0000 }, /* R974 */ + { 0x0000, 0x0000, 0x0000 }, /* R975 */ + { 0x0000, 0x0000, 0x0000 }, /* R976 */ + { 0x0000, 0x0000, 0x0000 }, /* R977 */ + { 0x0000, 0x0000, 0x0000 }, /* R978 */ + { 0x0000, 0x0000, 0x0000 }, /* R979 */ + { 0x0000, 0x0000, 0x0000 }, /* R980 */ + { 0x0000, 0x0000, 0x0000 }, /* R981 */ + { 0x0000, 0x0000, 0x0000 }, /* R982 */ + { 0x0000, 0x0000, 0x0000 }, /* R983 */ + { 0x0000, 0x0000, 0x0000 }, /* R984 */ + { 0x0000, 0x0000, 0x0000 }, /* R985 */ + { 0x0000, 0x0000, 0x0000 }, /* R986 */ + { 0x0000, 0x0000, 0x0000 }, /* R987 */ + { 0x0000, 0x0000, 0x0000 }, /* R988 */ + { 0x0000, 0x0000, 0x0000 }, /* R989 */ + { 0x0000, 0x0000, 0x0000 }, /* R990 */ + { 0x0000, 0x0000, 0x0000 }, /* R991 */ + { 0x0000, 0x0000, 0x0000 }, /* R992 */ + { 0x0000, 0x0000, 0x0000 }, /* R993 */ + { 0x0000, 0x0000, 0x0000 }, /* R994 */ + { 0x0000, 0x0000, 0x0000 }, /* R995 */ + { 0x0000, 0x0000, 0x0000 }, /* R996 */ + { 0x0000, 0x0000, 0x0000 }, /* R997 */ + { 0x0000, 0x0000, 0x0000 }, /* R998 */ + { 0x0000, 0x0000, 0x0000 }, /* R999 */ + { 0x0000, 0x0000, 0x0000 }, /* R1000 */ + { 0x0000, 0x0000, 0x0000 }, /* R1001 */ + { 0x0000, 0x0000, 0x0000 }, /* R1002 */ + { 0x0000, 0x0000, 0x0000 }, /* R1003 */ + { 0x0000, 0x0000, 0x0000 }, /* R1004 */ + { 0x0000, 0x0000, 0x0000 }, /* R1005 */ + { 0x0000, 0x0000, 0x0000 }, /* R1006 */ + { 0x0000, 0x0000, 0x0000 }, /* R1007 */ + { 0x0000, 0x0000, 0x0000 }, /* R1008 */ + { 0x0000, 0x0000, 0x0000 }, /* R1009 */ + { 0x0000, 0x0000, 0x0000 }, /* R1010 */ + { 0x0000, 0x0000, 0x0000 }, /* R1011 */ + { 0x0000, 0x0000, 0x0000 }, /* R1012 */ + { 0x0000, 0x0000, 0x0000 }, /* R1013 */ + { 0x0000, 0x0000, 0x0000 }, /* R1014 */ + { 0x0000, 0x0000, 0x0000 }, /* R1015 */ + { 0x0000, 0x0000, 0x0000 }, /* R1016 */ + { 0x0000, 0x0000, 0x0000 }, /* R1017 */ + { 0x0000, 0x0000, 0x0000 }, /* R1018 */ + { 0x0000, 0x0000, 0x0000 }, /* R1019 */ + { 0x0000, 0x0000, 0x0000 }, /* R1020 */ + { 0x0000, 0x0000, 0x0000 }, /* R1021 */ + { 0x0000, 0x0000, 0x0000 }, /* R1022 */ + { 0x0000, 0x0000, 0x0000 }, /* R1023 */ + { 0x00FF, 0x01FF, 0x0000 }, /* R1024 - AIF1 ADC1 Left Volume */ + { 0x00FF, 0x01FF, 0x0000 }, /* R1025 - AIF1 ADC1 Right Volume */ + { 0x00FF, 0x01FF, 0x0000 }, /* R1026 - AIF1 DAC1 Left Volume */ + { 0x00FF, 0x01FF, 0x0000 }, /* R1027 - AIF1 DAC1 Right Volume */ + { 0x00FF, 0x01FF, 0x0000 }, /* R1028 - AIF1 ADC2 Left Volume */ + { 0x00FF, 0x01FF, 0x0000 }, /* R1029 - AIF1 ADC2 Right Volume */ + { 0x00FF, 0x01FF, 0x0000 }, /* R1030 - AIF1 DAC2 Left Volume */ + { 0x00FF, 0x01FF, 0x0000 }, /* R1031 - AIF1 DAC2 Right Volume */ + { 0x0000, 0x0000, 0x0000 }, /* R1032 */ + { 0x0000, 0x0000, 0x0000 }, /* R1033 */ + { 0x0000, 0x0000, 0x0000 }, /* R1034 */ + { 0x0000, 0x0000, 0x0000 }, /* R1035 */ + { 0x0000, 0x0000, 0x0000 }, /* R1036 */ + { 0x0000, 0x0000, 0x0000 }, /* R1037 */ + { 0x0000, 0x0000, 0x0000 }, /* R1038 */ + { 0x0000, 0x0000, 0x0000 }, /* R1039 */ + { 0xF800, 0xF800, 0x0000 }, /* R1040 - AIF1 ADC1 Filters */ + { 0x7800, 0x7800, 0x0000 }, /* R1041 - AIF1 ADC2 Filters */ + { 0x0000, 0x0000, 0x0000 }, /* R1042 */ + { 0x0000, 0x0000, 0x0000 }, /* R1043 */ + { 0x0000, 0x0000, 0x0000 }, /* R1044 */ + { 0x0000, 0x0000, 0x0000 }, /* R1045 */ + { 0x0000, 0x0000, 0x0000 }, /* R1046 */ + { 0x0000, 0x0000, 0x0000 }, /* R1047 */ + { 0x0000, 0x0000, 0x0000 }, /* R1048 */ + { 0x0000, 0x0000, 0x0000 }, /* R1049 */ + { 0x0000, 0x0000, 0x0000 }, /* R1050 */ + { 0x0000, 0x0000, 0x0000 }, /* R1051 */ + { 0x0000, 0x0000, 0x0000 }, /* R1052 */ + { 0x0000, 0x0000, 0x0000 }, /* R1053 */ + { 0x0000, 0x0000, 0x0000 }, /* R1054 */ + { 0x0000, 0x0000, 0x0000 }, /* R1055 */ + { 0x02B6, 0x02B6, 0x0000 }, /* R1056 - AIF1 DAC1 Filters (1) */ + { 0x3F00, 0x3F00, 0x0000 }, /* R1057 - AIF1 DAC1 Filters (2) */ + { 0x02B6, 0x02B6, 0x0000 }, /* R1058 - AIF1 DAC2 Filters (1) */ + { 0x3F00, 0x3F00, 0x0000 }, /* R1059 - AIF1 DAC2 Filters (2) */ + { 0x0000, 0x0000, 0x0000 }, /* R1060 */ + { 0x0000, 0x0000, 0x0000 }, /* R1061 */ + { 0x0000, 0x0000, 0x0000 }, /* R1062 */ + { 0x0000, 0x0000, 0x0000 }, /* R1063 */ + { 0x0000, 0x0000, 0x0000 }, /* R1064 */ + { 0x0000, 0x0000, 0x0000 }, /* R1065 */ + { 0x0000, 0x0000, 0x0000 }, /* R1066 */ + { 0x0000, 0x0000, 0x0000 }, /* R1067 */ + { 0x0000, 0x0000, 0x0000 }, /* R1068 */ + { 0x0000, 0x0000, 0x0000 }, /* R1069 */ + { 0x0000, 0x0000, 0x0000 }, /* R1070 */ + { 0x0000, 0x0000, 0x0000 }, /* R1071 */ + { 0x0000, 0x0000, 0x0000 }, /* R1072 */ + { 0x0000, 0x0000, 0x0000 }, /* R1073 */ + { 0x0000, 0x0000, 0x0000 }, /* R1074 */ + { 0x0000, 0x0000, 0x0000 }, /* R1075 */ + { 0x0000, 0x0000, 0x0000 }, /* R1076 */ + { 0x0000, 0x0000, 0x0000 }, /* R1077 */ + { 0x0000, 0x0000, 0x0000 }, /* R1078 */ + { 0x0000, 0x0000, 0x0000 }, /* R1079 */ + { 0x0000, 0x0000, 0x0000 }, /* R1080 */ + { 0x0000, 0x0000, 0x0000 }, /* R1081 */ + { 0x0000, 0x0000, 0x0000 }, /* R1082 */ + { 0x0000, 0x0000, 0x0000 }, /* R1083 */ + { 0x0000, 0x0000, 0x0000 }, /* R1084 */ + { 0x0000, 0x0000, 0x0000 }, /* R1085 */ + { 0x0000, 0x0000, 0x0000 }, /* R1086 */ + { 0x0000, 0x0000, 0x0000 }, /* R1087 */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1088 - AIF1 DRC1 (1) */ + { 0x1FFF, 0x1FFF, 0x0000 }, /* R1089 - AIF1 DRC1 (2) */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1090 - AIF1 DRC1 (3) */ + { 0x07FF, 0x07FF, 0x0000 }, /* R1091 - AIF1 DRC1 (4) */ + { 0x03FF, 0x03FF, 0x0000 }, /* R1092 - AIF1 DRC1 (5) */ + { 0x0000, 0x0000, 0x0000 }, /* R1093 */ + { 0x0000, 0x0000, 0x0000 }, /* R1094 */ + { 0x0000, 0x0000, 0x0000 }, /* R1095 */ + { 0x0000, 0x0000, 0x0000 }, /* R1096 */ + { 0x0000, 0x0000, 0x0000 }, /* R1097 */ + { 0x0000, 0x0000, 0x0000 }, /* R1098 */ + { 0x0000, 0x0000, 0x0000 }, /* R1099 */ + { 0x0000, 0x0000, 0x0000 }, /* R1100 */ + { 0x0000, 0x0000, 0x0000 }, /* R1101 */ + { 0x0000, 0x0000, 0x0000 }, /* R1102 */ + { 0x0000, 0x0000, 0x0000 }, /* R1103 */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1104 - AIF1 DRC2 (1) */ + { 0x1FFF, 0x1FFF, 0x0000 }, /* R1105 - AIF1 DRC2 (2) */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1106 - AIF1 DRC2 (3) */ + { 0x07FF, 0x07FF, 0x0000 }, /* R1107 - AIF1 DRC2 (4) */ + { 0x03FF, 0x03FF, 0x0000 }, /* R1108 - AIF1 DRC2 (5) */ + { 0x0000, 0x0000, 0x0000 }, /* R1109 */ + { 0x0000, 0x0000, 0x0000 }, /* R1110 */ + { 0x0000, 0x0000, 0x0000 }, /* R1111 */ + { 0x0000, 0x0000, 0x0000 }, /* R1112 */ + { 0x0000, 0x0000, 0x0000 }, /* R1113 */ + { 0x0000, 0x0000, 0x0000 }, /* R1114 */ + { 0x0000, 0x0000, 0x0000 }, /* R1115 */ + { 0x0000, 0x0000, 0x0000 }, /* R1116 */ + { 0x0000, 0x0000, 0x0000 }, /* R1117 */ + { 0x0000, 0x0000, 0x0000 }, /* R1118 */ + { 0x0000, 0x0000, 0x0000 }, /* R1119 */ + { 0x0000, 0x0000, 0x0000 }, /* R1120 */ + { 0x0000, 0x0000, 0x0000 }, /* R1121 */ + { 0x0000, 0x0000, 0x0000 }, /* R1122 */ + { 0x0000, 0x0000, 0x0000 }, /* R1123 */ + { 0x0000, 0x0000, 0x0000 }, /* R1124 */ + { 0x0000, 0x0000, 0x0000 }, /* R1125 */ + { 0x0000, 0x0000, 0x0000 }, /* R1126 */ + { 0x0000, 0x0000, 0x0000 }, /* R1127 */ + { 0x0000, 0x0000, 0x0000 }, /* R1128 */ + { 0x0000, 0x0000, 0x0000 }, /* R1129 */ + { 0x0000, 0x0000, 0x0000 }, /* R1130 */ + { 0x0000, 0x0000, 0x0000 }, /* R1131 */ + { 0x0000, 0x0000, 0x0000 }, /* R1132 */ + { 0x0000, 0x0000, 0x0000 }, /* R1133 */ + { 0x0000, 0x0000, 0x0000 }, /* R1134 */ + { 0x0000, 0x0000, 0x0000 }, /* R1135 */ + { 0x0000, 0x0000, 0x0000 }, /* R1136 */ + { 0x0000, 0x0000, 0x0000 }, /* R1137 */ + { 0x0000, 0x0000, 0x0000 }, /* R1138 */ + { 0x0000, 0x0000, 0x0000 }, /* R1139 */ + { 0x0000, 0x0000, 0x0000 }, /* R1140 */ + { 0x0000, 0x0000, 0x0000 }, /* R1141 */ + { 0x0000, 0x0000, 0x0000 }, /* R1142 */ + { 0x0000, 0x0000, 0x0000 }, /* R1143 */ + { 0x0000, 0x0000, 0x0000 }, /* R1144 */ + { 0x0000, 0x0000, 0x0000 }, /* R1145 */ + { 0x0000, 0x0000, 0x0000 }, /* R1146 */ + { 0x0000, 0x0000, 0x0000 }, /* R1147 */ + { 0x0000, 0x0000, 0x0000 }, /* R1148 */ + { 0x0000, 0x0000, 0x0000 }, /* R1149 */ + { 0x0000, 0x0000, 0x0000 }, /* R1150 */ + { 0x0000, 0x0000, 0x0000 }, /* R1151 */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1152 - AIF1 DAC1 EQ Gains (1) */ + { 0xFFC0, 0xFFC0, 0x0000 }, /* R1153 - AIF1 DAC1 EQ Gains (2) */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1154 - AIF1 DAC1 EQ Band 1 A */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1155 - AIF1 DAC1 EQ Band 1 B */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1156 - AIF1 DAC1 EQ Band 1 PG */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1157 - AIF1 DAC1 EQ Band 2 A */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1158 - AIF1 DAC1 EQ Band 2 B */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1159 - AIF1 DAC1 EQ Band 2 C */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1160 - AIF1 DAC1 EQ Band 2 PG */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1161 - AIF1 DAC1 EQ Band 3 A */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1162 - AIF1 DAC1 EQ Band 3 B */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1163 - AIF1 DAC1 EQ Band 3 C */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1164 - AIF1 DAC1 EQ Band 3 PG */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1165 - AIF1 DAC1 EQ Band 4 A */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1166 - AIF1 DAC1 EQ Band 4 B */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1167 - AIF1 DAC1 EQ Band 4 C */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1168 - AIF1 DAC1 EQ Band 4 PG */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1169 - AIF1 DAC1 EQ Band 5 A */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1170 - AIF1 DAC1 EQ Band 5 B */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1171 - AIF1 DAC1 EQ Band 5 PG */ + { 0x0000, 0x0000, 0x0000 }, /* R1172 */ + { 0x0000, 0x0000, 0x0000 }, /* R1173 */ + { 0x0000, 0x0000, 0x0000 }, /* R1174 */ + { 0x0000, 0x0000, 0x0000 }, /* R1175 */ + { 0x0000, 0x0000, 0x0000 }, /* R1176 */ + { 0x0000, 0x0000, 0x0000 }, /* R1177 */ + { 0x0000, 0x0000, 0x0000 }, /* R1178 */ + { 0x0000, 0x0000, 0x0000 }, /* R1179 */ + { 0x0000, 0x0000, 0x0000 }, /* R1180 */ + { 0x0000, 0x0000, 0x0000 }, /* R1181 */ + { 0x0000, 0x0000, 0x0000 }, /* R1182 */ + { 0x0000, 0x0000, 0x0000 }, /* R1183 */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1184 - AIF1 DAC2 EQ Gains (1) */ + { 0xFFC0, 0xFFC0, 0x0000 }, /* R1185 - AIF1 DAC2 EQ Gains (2) */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1186 - AIF1 DAC2 EQ Band 1 A */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1187 - AIF1 DAC2 EQ Band 1 B */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1188 - AIF1 DAC2 EQ Band 1 PG */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1189 - AIF1 DAC2 EQ Band 2 A */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1190 - AIF1 DAC2 EQ Band 2 B */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1191 - AIF1 DAC2 EQ Band 2 C */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1192 - AIF1 DAC2 EQ Band 2 PG */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1193 - AIF1 DAC2 EQ Band 3 A */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1194 - AIF1 DAC2 EQ Band 3 B */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1195 - AIF1 DAC2 EQ Band 3 C */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1196 - AIF1 DAC2 EQ Band 3 PG */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1197 - AIF1 DAC2 EQ Band 4 A */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1198 - AIF1 DAC2 EQ Band 4 B */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1199 - AIF1 DAC2 EQ Band 4 C */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1200 - AIF1 DAC2 EQ Band 4 PG */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1201 - AIF1 DAC2 EQ Band 5 A */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1202 - AIF1 DAC2 EQ Band 5 B */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1203 - AIF1 DAC2 EQ Band 5 PG */ + { 0x0000, 0x0000, 0x0000 }, /* R1204 */ + { 0x0000, 0x0000, 0x0000 }, /* R1205 */ + { 0x0000, 0x0000, 0x0000 }, /* R1206 */ + { 0x0000, 0x0000, 0x0000 }, /* R1207 */ + { 0x0000, 0x0000, 0x0000 }, /* R1208 */ + { 0x0000, 0x0000, 0x0000 }, /* R1209 */ + { 0x0000, 0x0000, 0x0000 }, /* R1210 */ + { 0x0000, 0x0000, 0x0000 }, /* R1211 */ + { 0x0000, 0x0000, 0x0000 }, /* R1212 */ + { 0x0000, 0x0000, 0x0000 }, /* R1213 */ + { 0x0000, 0x0000, 0x0000 }, /* R1214 */ + { 0x0000, 0x0000, 0x0000 }, /* R1215 */ + { 0x0000, 0x0000, 0x0000 }, /* R1216 */ + { 0x0000, 0x0000, 0x0000 }, /* R1217 */ + { 0x0000, 0x0000, 0x0000 }, /* R1218 */ + { 0x0000, 0x0000, 0x0000 }, /* R1219 */ + { 0x0000, 0x0000, 0x0000 }, /* R1220 */ + { 0x0000, 0x0000, 0x0000 }, /* R1221 */ + { 0x0000, 0x0000, 0x0000 }, /* R1222 */ + { 0x0000, 0x0000, 0x0000 }, /* R1223 */ + { 0x0000, 0x0000, 0x0000 }, /* R1224 */ + { 0x0000, 0x0000, 0x0000 }, /* R1225 */ + { 0x0000, 0x0000, 0x0000 }, /* R1226 */ + { 0x0000, 0x0000, 0x0000 }, /* R1227 */ + { 0x0000, 0x0000, 0x0000 }, /* R1228 */ + { 0x0000, 0x0000, 0x0000 }, /* R1229 */ + { 0x0000, 0x0000, 0x0000 }, /* R1230 */ + { 0x0000, 0x0000, 0x0000 }, /* R1231 */ + { 0x0000, 0x0000, 0x0000 }, /* R1232 */ + { 0x0000, 0x0000, 0x0000 }, /* R1233 */ + { 0x0000, 0x0000, 0x0000 }, /* R1234 */ + { 0x0000, 0x0000, 0x0000 }, /* R1235 */ + { 0x0000, 0x0000, 0x0000 }, /* R1236 */ + { 0x0000, 0x0000, 0x0000 }, /* R1237 */ + { 0x0000, 0x0000, 0x0000 }, /* R1238 */ + { 0x0000, 0x0000, 0x0000 }, /* R1239 */ + { 0x0000, 0x0000, 0x0000 }, /* R1240 */ + { 0x0000, 0x0000, 0x0000 }, /* R1241 */ + { 0x0000, 0x0000, 0x0000 }, /* R1242 */ + { 0x0000, 0x0000, 0x0000 }, /* R1243 */ + { 0x0000, 0x0000, 0x0000 }, /* R1244 */ + { 0x0000, 0x0000, 0x0000 }, /* R1245 */ + { 0x0000, 0x0000, 0x0000 }, /* R1246 */ + { 0x0000, 0x0000, 0x0000 }, /* R1247 */ + { 0x0000, 0x0000, 0x0000 }, /* R1248 */ + { 0x0000, 0x0000, 0x0000 }, /* R1249 */ + { 0x0000, 0x0000, 0x0000 }, /* R1250 */ + { 0x0000, 0x0000, 0x0000 }, /* R1251 */ + { 0x0000, 0x0000, 0x0000 }, /* R1252 */ + { 0x0000, 0x0000, 0x0000 }, /* R1253 */ + { 0x0000, 0x0000, 0x0000 }, /* R1254 */ + { 0x0000, 0x0000, 0x0000 }, /* R1255 */ + { 0x0000, 0x0000, 0x0000 }, /* R1256 */ + { 0x0000, 0x0000, 0x0000 }, /* R1257 */ + { 0x0000, 0x0000, 0x0000 }, /* R1258 */ + { 0x0000, 0x0000, 0x0000 }, /* R1259 */ + { 0x0000, 0x0000, 0x0000 }, /* R1260 */ + { 0x0000, 0x0000, 0x0000 }, /* R1261 */ + { 0x0000, 0x0000, 0x0000 }, /* R1262 */ + { 0x0000, 0x0000, 0x0000 }, /* R1263 */ + { 0x0000, 0x0000, 0x0000 }, /* R1264 */ + { 0x0000, 0x0000, 0x0000 }, /* R1265 */ + { 0x0000, 0x0000, 0x0000 }, /* R1266 */ + { 0x0000, 0x0000, 0x0000 }, /* R1267 */ + { 0x0000, 0x0000, 0x0000 }, /* R1268 */ + { 0x0000, 0x0000, 0x0000 }, /* R1269 */ + { 0x0000, 0x0000, 0x0000 }, /* R1270 */ + { 0x0000, 0x0000, 0x0000 }, /* R1271 */ + { 0x0000, 0x0000, 0x0000 }, /* R1272 */ + { 0x0000, 0x0000, 0x0000 }, /* R1273 */ + { 0x0000, 0x0000, 0x0000 }, /* R1274 */ + { 0x0000, 0x0000, 0x0000 }, /* R1275 */ + { 0x0000, 0x0000, 0x0000 }, /* R1276 */ + { 0x0000, 0x0000, 0x0000 }, /* R1277 */ + { 0x0000, 0x0000, 0x0000 }, /* R1278 */ + { 0x0000, 0x0000, 0x0000 }, /* R1279 */ + { 0x00FF, 0x01FF, 0x0000 }, /* R1280 - AIF2 ADC Left Volume */ + { 0x00FF, 0x01FF, 0x0000 }, /* R1281 - AIF2 ADC Right Volume */ + { 0x00FF, 0x01FF, 0x0000 }, /* R1282 - AIF2 DAC Left Volume */ + { 0x00FF, 0x01FF, 0x0000 }, /* R1283 - AIF2 DAC Right Volume */ + { 0x0000, 0x0000, 0x0000 }, /* R1284 */ + { 0x0000, 0x0000, 0x0000 }, /* R1285 */ + { 0x0000, 0x0000, 0x0000 }, /* R1286 */ + { 0x0000, 0x0000, 0x0000 }, /* R1287 */ + { 0x0000, 0x0000, 0x0000 }, /* R1288 */ + { 0x0000, 0x0000, 0x0000 }, /* R1289 */ + { 0x0000, 0x0000, 0x0000 }, /* R1290 */ + { 0x0000, 0x0000, 0x0000 }, /* R1291 */ + { 0x0000, 0x0000, 0x0000 }, /* R1292 */ + { 0x0000, 0x0000, 0x0000 }, /* R1293 */ + { 0x0000, 0x0000, 0x0000 }, /* R1294 */ + { 0x0000, 0x0000, 0x0000 }, /* R1295 */ + { 0xF800, 0xF800, 0x0000 }, /* R1296 - AIF2 ADC Filters */ + { 0x0000, 0x0000, 0x0000 }, /* R1297 */ + { 0x0000, 0x0000, 0x0000 }, /* R1298 */ + { 0x0000, 0x0000, 0x0000 }, /* R1299 */ + { 0x0000, 0x0000, 0x0000 }, /* R1300 */ + { 0x0000, 0x0000, 0x0000 }, /* R1301 */ + { 0x0000, 0x0000, 0x0000 }, /* R1302 */ + { 0x0000, 0x0000, 0x0000 }, /* R1303 */ + { 0x0000, 0x0000, 0x0000 }, /* R1304 */ + { 0x0000, 0x0000, 0x0000 }, /* R1305 */ + { 0x0000, 0x0000, 0x0000 }, /* R1306 */ + { 0x0000, 0x0000, 0x0000 }, /* R1307 */ + { 0x0000, 0x0000, 0x0000 }, /* R1308 */ + { 0x0000, 0x0000, 0x0000 }, /* R1309 */ + { 0x0000, 0x0000, 0x0000 }, /* R1310 */ + { 0x0000, 0x0000, 0x0000 }, /* R1311 */ + { 0x02B6, 0x02B6, 0x0000 }, /* R1312 - AIF2 DAC Filters (1) */ + { 0x3F00, 0x3F00, 0x0000 }, /* R1313 - AIF2 DAC Filters (2) */ + { 0x0000, 0x0000, 0x0000 }, /* R1314 */ + { 0x0000, 0x0000, 0x0000 }, /* R1315 */ + { 0x0000, 0x0000, 0x0000 }, /* R1316 */ + { 0x0000, 0x0000, 0x0000 }, /* R1317 */ + { 0x0000, 0x0000, 0x0000 }, /* R1318 */ + { 0x0000, 0x0000, 0x0000 }, /* R1319 */ + { 0x0000, 0x0000, 0x0000 }, /* R1320 */ + { 0x0000, 0x0000, 0x0000 }, /* R1321 */ + { 0x0000, 0x0000, 0x0000 }, /* R1322 */ + { 0x0000, 0x0000, 0x0000 }, /* R1323 */ + { 0x0000, 0x0000, 0x0000 }, /* R1324 */ + { 0x0000, 0x0000, 0x0000 }, /* R1325 */ + { 0x0000, 0x0000, 0x0000 }, /* R1326 */ + { 0x0000, 0x0000, 0x0000 }, /* R1327 */ + { 0x0000, 0x0000, 0x0000 }, /* R1328 */ + { 0x0000, 0x0000, 0x0000 }, /* R1329 */ + { 0x0000, 0x0000, 0x0000 }, /* R1330 */ + { 0x0000, 0x0000, 0x0000 }, /* R1331 */ + { 0x0000, 0x0000, 0x0000 }, /* R1332 */ + { 0x0000, 0x0000, 0x0000 }, /* R1333 */ + { 0x0000, 0x0000, 0x0000 }, /* R1334 */ + { 0x0000, 0x0000, 0x0000 }, /* R1335 */ + { 0x0000, 0x0000, 0x0000 }, /* R1336 */ + { 0x0000, 0x0000, 0x0000 }, /* R1337 */ + { 0x0000, 0x0000, 0x0000 }, /* R1338 */ + { 0x0000, 0x0000, 0x0000 }, /* R1339 */ + { 0x0000, 0x0000, 0x0000 }, /* R1340 */ + { 0x0000, 0x0000, 0x0000 }, /* R1341 */ + { 0x0000, 0x0000, 0x0000 }, /* R1342 */ + { 0x0000, 0x0000, 0x0000 }, /* R1343 */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1344 - AIF2 DRC (1) */ + { 0x1FFF, 0x1FFF, 0x0000 }, /* R1345 - AIF2 DRC (2) */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1346 - AIF2 DRC (3) */ + { 0x07FF, 0x07FF, 0x0000 }, /* R1347 - AIF2 DRC (4) */ + { 0x03FF, 0x03FF, 0x0000 }, /* R1348 - AIF2 DRC (5) */ + { 0x0000, 0x0000, 0x0000 }, /* R1349 */ + { 0x0000, 0x0000, 0x0000 }, /* R1350 */ + { 0x0000, 0x0000, 0x0000 }, /* R1351 */ + { 0x0000, 0x0000, 0x0000 }, /* R1352 */ + { 0x0000, 0x0000, 0x0000 }, /* R1353 */ + { 0x0000, 0x0000, 0x0000 }, /* R1354 */ + { 0x0000, 0x0000, 0x0000 }, /* R1355 */ + { 0x0000, 0x0000, 0x0000 }, /* R1356 */ + { 0x0000, 0x0000, 0x0000 }, /* R1357 */ + { 0x0000, 0x0000, 0x0000 }, /* R1358 */ + { 0x0000, 0x0000, 0x0000 }, /* R1359 */ + { 0x0000, 0x0000, 0x0000 }, /* R1360 */ + { 0x0000, 0x0000, 0x0000 }, /* R1361 */ + { 0x0000, 0x0000, 0x0000 }, /* R1362 */ + { 0x0000, 0x0000, 0x0000 }, /* R1363 */ + { 0x0000, 0x0000, 0x0000 }, /* R1364 */ + { 0x0000, 0x0000, 0x0000 }, /* R1365 */ + { 0x0000, 0x0000, 0x0000 }, /* R1366 */ + { 0x0000, 0x0000, 0x0000 }, /* R1367 */ + { 0x0000, 0x0000, 0x0000 }, /* R1368 */ + { 0x0000, 0x0000, 0x0000 }, /* R1369 */ + { 0x0000, 0x0000, 0x0000 }, /* R1370 */ + { 0x0000, 0x0000, 0x0000 }, /* R1371 */ + { 0x0000, 0x0000, 0x0000 }, /* R1372 */ + { 0x0000, 0x0000, 0x0000 }, /* R1373 */ + { 0x0000, 0x0000, 0x0000 }, /* R1374 */ + { 0x0000, 0x0000, 0x0000 }, /* R1375 */ + { 0x0000, 0x0000, 0x0000 }, /* R1376 */ + { 0x0000, 0x0000, 0x0000 }, /* R1377 */ + { 0x0000, 0x0000, 0x0000 }, /* R1378 */ + { 0x0000, 0x0000, 0x0000 }, /* R1379 */ + { 0x0000, 0x0000, 0x0000 }, /* R1380 */ + { 0x0000, 0x0000, 0x0000 }, /* R1381 */ + { 0x0000, 0x0000, 0x0000 }, /* R1382 */ + { 0x0000, 0x0000, 0x0000 }, /* R1383 */ + { 0x0000, 0x0000, 0x0000 }, /* R1384 */ + { 0x0000, 0x0000, 0x0000 }, /* R1385 */ + { 0x0000, 0x0000, 0x0000 }, /* R1386 */ + { 0x0000, 0x0000, 0x0000 }, /* R1387 */ + { 0x0000, 0x0000, 0x0000 }, /* R1388 */ + { 0x0000, 0x0000, 0x0000 }, /* R1389 */ + { 0x0000, 0x0000, 0x0000 }, /* R1390 */ + { 0x0000, 0x0000, 0x0000 }, /* R1391 */ + { 0x0000, 0x0000, 0x0000 }, /* R1392 */ + { 0x0000, 0x0000, 0x0000 }, /* R1393 */ + { 0x0000, 0x0000, 0x0000 }, /* R1394 */ + { 0x0000, 0x0000, 0x0000 }, /* R1395 */ + { 0x0000, 0x0000, 0x0000 }, /* R1396 */ + { 0x0000, 0x0000, 0x0000 }, /* R1397 */ + { 0x0000, 0x0000, 0x0000 }, /* R1398 */ + { 0x0000, 0x0000, 0x0000 }, /* R1399 */ + { 0x0000, 0x0000, 0x0000 }, /* R1400 */ + { 0x0000, 0x0000, 0x0000 }, /* R1401 */ + { 0x0000, 0x0000, 0x0000 }, /* R1402 */ + { 0x0000, 0x0000, 0x0000 }, /* R1403 */ + { 0x0000, 0x0000, 0x0000 }, /* R1404 */ + { 0x0000, 0x0000, 0x0000 }, /* R1405 */ + { 0x0000, 0x0000, 0x0000 }, /* R1406 */ + { 0x0000, 0x0000, 0x0000 }, /* R1407 */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1408 - AIF2 EQ Gains (1) */ + { 0xFFC0, 0xFFC0, 0x0000 }, /* R1409 - AIF2 EQ Gains (2) */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1410 - AIF2 EQ Band 1 A */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1411 - AIF2 EQ Band 1 B */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1412 - AIF2 EQ Band 1 PG */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1413 - AIF2 EQ Band 2 A */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1414 - AIF2 EQ Band 2 B */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1415 - AIF2 EQ Band 2 C */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1416 - AIF2 EQ Band 2 PG */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1417 - AIF2 EQ Band 3 A */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1418 - AIF2 EQ Band 3 B */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1419 - AIF2 EQ Band 3 C */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1420 - AIF2 EQ Band 3 PG */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1421 - AIF2 EQ Band 4 A */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1422 - AIF2 EQ Band 4 B */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1423 - AIF2 EQ Band 4 C */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1424 - AIF2 EQ Band 4 PG */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1425 - AIF2 EQ Band 5 A */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1426 - AIF2 EQ Band 5 B */ + { 0xFFFF, 0xFFFF, 0x0000 }, /* R1427 - AIF2 EQ Band 5 PG */ + { 0x0000, 0x0000, 0x0000 }, /* R1428 */ + { 0x0000, 0x0000, 0x0000 }, /* R1429 */ + { 0x0000, 0x0000, 0x0000 }, /* R1430 */ + { 0x0000, 0x0000, 0x0000 }, /* R1431 */ + { 0x0000, 0x0000, 0x0000 }, /* R1432 */ + { 0x0000, 0x0000, 0x0000 }, /* R1433 */ + { 0x0000, 0x0000, 0x0000 }, /* R1434 */ + { 0x0000, 0x0000, 0x0000 }, /* R1435 */ + { 0x0000, 0x0000, 0x0000 }, /* R1436 */ + { 0x0000, 0x0000, 0x0000 }, /* R1437 */ + { 0x0000, 0x0000, 0x0000 }, /* R1438 */ + { 0x0000, 0x0000, 0x0000 }, /* R1439 */ + { 0x0000, 0x0000, 0x0000 }, /* R1440 */ + { 0x0000, 0x0000, 0x0000 }, /* R1441 */ + { 0x0000, 0x0000, 0x0000 }, /* R1442 */ + { 0x0000, 0x0000, 0x0000 }, /* R1443 */ + { 0x0000, 0x0000, 0x0000 }, /* R1444 */ + { 0x0000, 0x0000, 0x0000 }, /* R1445 */ + { 0x0000, 0x0000, 0x0000 }, /* R1446 */ + { 0x0000, 0x0000, 0x0000 }, /* R1447 */ + { 0x0000, 0x0000, 0x0000 }, /* R1448 */ + { 0x0000, 0x0000, 0x0000 }, /* R1449 */ + { 0x0000, 0x0000, 0x0000 }, /* R1450 */ + { 0x0000, 0x0000, 0x0000 }, /* R1451 */ + { 0x0000, 0x0000, 0x0000 }, /* R1452 */ + { 0x0000, 0x0000, 0x0000 }, /* R1453 */ + { 0x0000, 0x0000, 0x0000 }, /* R1454 */ + { 0x0000, 0x0000, 0x0000 }, /* R1455 */ + { 0x0000, 0x0000, 0x0000 }, /* R1456 */ + { 0x0000, 0x0000, 0x0000 }, /* R1457 */ + { 0x0000, 0x0000, 0x0000 }, /* R1458 */ + { 0x0000, 0x0000, 0x0000 }, /* R1459 */ + { 0x0000, 0x0000, 0x0000 }, /* R1460 */ + { 0x0000, 0x0000, 0x0000 }, /* R1461 */ + { 0x0000, 0x0000, 0x0000 }, /* R1462 */ + { 0x0000, 0x0000, 0x0000 }, /* R1463 */ + { 0x0000, 0x0000, 0x0000 }, /* R1464 */ + { 0x0000, 0x0000, 0x0000 }, /* R1465 */ + { 0x0000, 0x0000, 0x0000 }, /* R1466 */ + { 0x0000, 0x0000, 0x0000 }, /* R1467 */ + { 0x0000, 0x0000, 0x0000 }, /* R1468 */ + { 0x0000, 0x0000, 0x0000 }, /* R1469 */ + { 0x0000, 0x0000, 0x0000 }, /* R1470 */ + { 0x0000, 0x0000, 0x0000 }, /* R1471 */ + { 0x0000, 0x0000, 0x0000 }, /* R1472 */ + { 0x0000, 0x0000, 0x0000 }, /* R1473 */ + { 0x0000, 0x0000, 0x0000 }, /* R1474 */ + { 0x0000, 0x0000, 0x0000 }, /* R1475 */ + { 0x0000, 0x0000, 0x0000 }, /* R1476 */ + { 0x0000, 0x0000, 0x0000 }, /* R1477 */ + { 0x0000, 0x0000, 0x0000 }, /* R1478 */ + { 0x0000, 0x0000, 0x0000 }, /* R1479 */ + { 0x0000, 0x0000, 0x0000 }, /* R1480 */ + { 0x0000, 0x0000, 0x0000 }, /* R1481 */ + { 0x0000, 0x0000, 0x0000 }, /* R1482 */ + { 0x0000, 0x0000, 0x0000 }, /* R1483 */ + { 0x0000, 0x0000, 0x0000 }, /* R1484 */ + { 0x0000, 0x0000, 0x0000 }, /* R1485 */ + { 0x0000, 0x0000, 0x0000 }, /* R1486 */ + { 0x0000, 0x0000, 0x0000 }, /* R1487 */ + { 0x0000, 0x0000, 0x0000 }, /* R1488 */ + { 0x0000, 0x0000, 0x0000 }, /* R1489 */ + { 0x0000, 0x0000, 0x0000 }, /* R1490 */ + { 0x0000, 0x0000, 0x0000 }, /* R1491 */ + { 0x0000, 0x0000, 0x0000 }, /* R1492 */ + { 0x0000, 0x0000, 0x0000 }, /* R1493 */ + { 0x0000, 0x0000, 0x0000 }, /* R1494 */ + { 0x0000, 0x0000, 0x0000 }, /* R1495 */ + { 0x0000, 0x0000, 0x0000 }, /* R1496 */ + { 0x0000, 0x0000, 0x0000 }, /* R1497 */ + { 0x0000, 0x0000, 0x0000 }, /* R1498 */ + { 0x0000, 0x0000, 0x0000 }, /* R1499 */ + { 0x0000, 0x0000, 0x0000 }, /* R1500 */ + { 0x0000, 0x0000, 0x0000 }, /* R1501 */ + { 0x0000, 0x0000, 0x0000 }, /* R1502 */ + { 0x0000, 0x0000, 0x0000 }, /* R1503 */ + { 0x0000, 0x0000, 0x0000 }, /* R1504 */ + { 0x0000, 0x0000, 0x0000 }, /* R1505 */ + { 0x0000, 0x0000, 0x0000 }, /* R1506 */ + { 0x0000, 0x0000, 0x0000 }, /* R1507 */ + { 0x0000, 0x0000, 0x0000 }, /* R1508 */ + { 0x0000, 0x0000, 0x0000 }, /* R1509 */ + { 0x0000, 0x0000, 0x0000 }, /* R1510 */ + { 0x0000, 0x0000, 0x0000 }, /* R1511 */ + { 0x0000, 0x0000, 0x0000 }, /* R1512 */ + { 0x0000, 0x0000, 0x0000 }, /* R1513 */ + { 0x0000, 0x0000, 0x0000 }, /* R1514 */ + { 0x0000, 0x0000, 0x0000 }, /* R1515 */ + { 0x0000, 0x0000, 0x0000 }, /* R1516 */ + { 0x0000, 0x0000, 0x0000 }, /* R1517 */ + { 0x0000, 0x0000, 0x0000 }, /* R1518 */ + { 0x0000, 0x0000, 0x0000 }, /* R1519 */ + { 0x0000, 0x0000, 0x0000 }, /* R1520 */ + { 0x0000, 0x0000, 0x0000 }, /* R1521 */ + { 0x0000, 0x0000, 0x0000 }, /* R1522 */ + { 0x0000, 0x0000, 0x0000 }, /* R1523 */ + { 0x0000, 0x0000, 0x0000 }, /* R1524 */ + { 0x0000, 0x0000, 0x0000 }, /* R1525 */ + { 0x0000, 0x0000, 0x0000 }, /* R1526 */ + { 0x0000, 0x0000, 0x0000 }, /* R1527 */ + { 0x0000, 0x0000, 0x0000 }, /* R1528 */ + { 0x0000, 0x0000, 0x0000 }, /* R1529 */ + { 0x0000, 0x0000, 0x0000 }, /* R1530 */ + { 0x0000, 0x0000, 0x0000 }, /* R1531 */ + { 0x0000, 0x0000, 0x0000 }, /* R1532 */ + { 0x0000, 0x0000, 0x0000 }, /* R1533 */ + { 0x0000, 0x0000, 0x0000 }, /* R1534 */ + { 0x0000, 0x0000, 0x0000 }, /* R1535 */ + { 0x01EF, 0x01EF, 0x0000 }, /* R1536 - DAC1 Mixer Volumes */ + { 0x0037, 0x0037, 0x0000 }, /* R1537 - DAC1 Left Mixer Routing */ + { 0x0037, 0x0037, 0x0000 }, /* R1538 - DAC1 Right Mixer Routing */ + { 0x01EF, 0x01EF, 0x0000 }, /* R1539 - DAC2 Mixer Volumes */ + { 0x0037, 0x0037, 0x0000 }, /* R1540 - DAC2 Left Mixer Routing */ + { 0x0037, 0x0037, 0x0000 }, /* R1541 - DAC2 Right Mixer Routing */ + { 0x0003, 0x0003, 0x0000 }, /* R1542 - AIF1 ADC1 Left Mixer Routing */ + { 0x0003, 0x0003, 0x0000 }, /* R1543 - AIF1 ADC1 Right Mixer Routing */ + { 0x0003, 0x0003, 0x0000 }, /* R1544 - AIF1 ADC2 Left Mixer Routing */ + { 0x0003, 0x0003, 0x0000 }, /* R1545 - AIF1 ADC2 Right mixer Routing */ + { 0x0000, 0x0000, 0x0000 }, /* R1546 */ + { 0x0000, 0x0000, 0x0000 }, /* R1547 */ + { 0x0000, 0x0000, 0x0000 }, /* R1548 */ + { 0x0000, 0x0000, 0x0000 }, /* R1549 */ + { 0x0000, 0x0000, 0x0000 }, /* R1550 */ + { 0x0000, 0x0000, 0x0000 }, /* R1551 */ + { 0x02FF, 0x03FF, 0x0000 }, /* R1552 - DAC1 Left Volume */ + { 0x02FF, 0x03FF, 0x0000 }, /* R1553 - DAC1 Right Volume */ + { 0x02FF, 0x03FF, 0x0000 }, /* R1554 - DAC2 Left Volume */ + { 0x02FF, 0x03FF, 0x0000 }, /* R1555 - DAC2 Right Volume */ + { 0x0003, 0x0003, 0x0000 }, /* R1556 - DAC Softmute */ + { 0x0000, 0x0000, 0x0000 }, /* R1557 */ + { 0x0000, 0x0000, 0x0000 }, /* R1558 */ + { 0x0000, 0x0000, 0x0000 }, /* R1559 */ + { 0x0000, 0x0000, 0x0000 }, /* R1560 */ + { 0x0000, 0x0000, 0x0000 }, /* R1561 */ + { 0x0000, 0x0000, 0x0000 }, /* R1562 */ + { 0x0000, 0x0000, 0x0000 }, /* R1563 */ + { 0x0000, 0x0000, 0x0000 }, /* R1564 */ + { 0x0000, 0x0000, 0x0000 }, /* R1565 */ + { 0x0000, 0x0000, 0x0000 }, /* R1566 */ + { 0x0000, 0x0000, 0x0000 }, /* R1567 */ + { 0x0003, 0x0003, 0x0000 }, /* R1568 - Oversampling */ + { 0x03C3, 0x03C3, 0x0000 }, /* R1569 - Sidetone */ }; -int reg_send_data(struct i2c_client *client, unsigned short *reg, unsigned short *data, u32 scl_rate) +static int wm8994_readable(unsigned int reg) { - int ret; - struct i2c_adapter *adap = client->adapter; - struct i2c_msg msg; - char tx_buf[4]; - - memcpy(tx_buf, reg, 2); - memcpy(tx_buf+2, data, 2); - msg.addr = client->addr; - msg.buf = tx_buf; - msg.len = 4; - msg.flags = client->flags; - msg.scl_rate = scl_rate; - msg.read_type = 0; - ret = i2c_transfer(adap, &msg, 1); + switch (reg) { + case WM8994_GPIO_1: + case WM8994_GPIO_2: + case WM8994_GPIO_3: + case WM8994_GPIO_4: + case WM8994_GPIO_5: + case WM8994_GPIO_6: + case WM8994_GPIO_7: + case WM8994_GPIO_8: + case WM8994_GPIO_9: + case WM8994_GPIO_10: + case WM8994_GPIO_11: + case WM8994_INTERRUPT_STATUS_1: + case WM8994_INTERRUPT_STATUS_2: + case WM8994_INTERRUPT_RAW_STATUS_2: + return 1; + default: + break; + } - return ret; + if (reg >= ARRAY_SIZE(access_masks)) + return 0; + return access_masks[reg].readable != 0; } -int reg_recv_data(struct i2c_client *client, unsigned short *reg, unsigned short *buf, u32 scl_rate) +static int wm8994_volatile(unsigned int reg) { - int ret; - struct i2c_adapter *adap = client->adapter; - struct i2c_msg msgs[2]; + if (reg >= WM8994_REG_CACHE_SIZE) + return 1; + + switch (reg) { + case WM8994_SOFTWARE_RESET: + case WM8994_CHIP_REVISION: + case WM8994_DC_SERVO_1: + case WM8994_DC_SERVO_READBACK: + case WM8994_RATE_STATUS: + case WM8994_LDO_1: + case WM8994_LDO_2: + return 1; + default: + return 0; + } +} - msgs[0].addr = client->addr; - msgs[0].buf = (char *)reg; - msgs[0].flags = client->flags; - msgs[0].len = 2; - msgs[0].scl_rate = scl_rate; - msgs[0].read_type = 2; +static int wm8994_write(struct snd_soc_codec *codec, unsigned int reg, + unsigned int value) +{ + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); - msgs[1].addr = client->addr; - msgs[1].buf = (char *)buf; - msgs[1].flags = client->flags | I2C_M_RD; - msgs[1].len = 2; - msgs[1].scl_rate = scl_rate; - msgs[1].read_type = 2; + BUG_ON(reg > WM8994_MAX_REGISTER); - ret = i2c_transfer(adap, msgs, 2); + if (!wm8994_volatile(reg)) + wm8994->reg_cache[reg] = value; - return ret; -} + dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value); -int wm8994_set_status(void) -{ - struct wm8994_priv *wm8994 = wm8994_codec->private_data; - int ret = 1; - - if(wm8994->route_status != IDLE) - ret = -BUSY; - - return ret; + return wm8994_reg_write(codec->control_data, reg, value); } -EXPORT_SYMBOL_GPL(wm8994_set_status); -static int wm8994_read(unsigned short reg,unsigned short *value) +static unsigned int wm8994_read(struct snd_soc_codec *codec, + unsigned int reg) { - struct wm8994_priv *wm8994 = wm8994_codec->private_data; - - unsigned short regs=((reg>>8)&0x00FF)|((reg<<8)&0xFF00),values; - char i = 2; - mutex_lock(&wm8994->io_lock); - if(wm8994->RW_status == ERROR) goto out; - - while(i > 0) - { - i--; - if (reg_recv_data(wm8994_codec->control_data,®s,&values,400000) > 0) - { - *value=((values>>8)& 0x00FF)|((values<<8)&0xFF00); - #ifdef WM8994_PROC - if(debug_write_read != 0) - DBG("%s:0x%04x = 0x%04x",__FUNCTION__,reg,*value); - #endif - mutex_unlock(&wm8994->io_lock); - return 0; - } - } - - wm8994->RW_status = ERROR; - printk("%s---line->%d:Codec read error! reg = 0x%x , value = 0x%x\n",__FUNCTION__,__LINE__,reg,*value); -out: - mutex_unlock(&wm8994->io_lock); - return -EIO; + u16 *reg_cache = codec->reg_cache; + + BUG_ON(reg > WM8994_MAX_REGISTER); + + if (wm8994_volatile(reg)) + return wm8994_reg_read(codec->control_data, reg); + else + return reg_cache[reg]; } - -static int wm8994_write(unsigned short reg,unsigned short value) + +static int configure_aif_clock(struct snd_soc_codec *codec, int aif) { - struct wm8994_priv *wm8994 = wm8994_codec->private_data; + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + int rate; + int reg1 = 0; + int offset; + + if (aif) + offset = 4; + else + offset = 0; - unsigned short regs=((reg>>8)&0x00FF)|((reg<<8)&0xFF00),values=((value>>8)&0x00FF)|((value<<8)&0xFF00); - char i = 2; - - mutex_lock(&wm8994->io_lock); + switch (wm8994->sysclk[aif]) { + case WM8994_SYSCLK_MCLK1: + rate = wm8994->mclk[0]; + break; + + case WM8994_SYSCLK_MCLK2: + reg1 |= 0x8; + rate = wm8994->mclk[1]; + break; - if(wm8994->RW_status == ERROR) goto out; + case WM8994_SYSCLK_FLL1: + reg1 |= 0x10; + rate = wm8994->fll[0].out; + break; -#ifdef WM8994_PROC - if(debug_write_read != 0) - DBG("%s:0x%04x = 0x%04x\n",__FUNCTION__,reg,value); -#endif - while(i > 0) - { - i--; - if (reg_send_data(wm8994_codec->control_data,®s,&values,400000) > 0) - { - mutex_unlock(&wm8994->io_lock); - return 0; - } + case WM8994_SYSCLK_FLL2: + reg1 |= 0x18; + rate = wm8994->fll[1].out; + break; + + default: + return -EINVAL; + } + + if (rate >= 13500000) { + rate /= 2; + reg1 |= WM8994_AIF1CLK_DIV; + + dev_dbg(codec->dev, "Dividing AIF%d clock to %dHz\n", + aif + 1, rate); } - - wm8994->RW_status = ERROR; - printk("%s---line->%d:Codec write error! reg = 0x%x , value = 0x%x\n",__FUNCTION__,__LINE__,reg,value); -out: - mutex_unlock(&wm8994->io_lock); - return -EIO; + if (rate && rate < 3000000) + dev_warn(codec->dev, "AIF%dCLK is %dHz, should be >=3MHz for optimal performance\n", + aif + 1, rate); + + wm8994->aifclk[aif] = rate; + + snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1 + offset, + WM8994_AIF1CLK_SRC_MASK | WM8994_AIF1CLK_DIV, + reg1); + + return 0; } -static int wm8994_set_bit(unsigned short reg,unsigned short mask, unsigned short val) +static int configure_clock(struct snd_soc_codec *codec) { - int ret; - u16 r; + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + int old, new; - ret = wm8994_read(reg, &r); - if (ret < 0) - goto out; - - r &= ~mask; - r |= val; + /* Bring up the AIF clocks first */ + configure_aif_clock(codec, 0); + configure_aif_clock(codec, 1); + + /* Then switch CLK_SYS over to the higher of them; a change + * can only happen as a result of a clocking change which can + * only be made outside of DAPM so we can safely redo the + * clocking. + */ - ret = wm8994_write(reg, r); + /* If they're equal it doesn't matter which is used */ + if (wm8994->aifclk[0] == wm8994->aifclk[1]) + return 0; -out: - return ret; + if (wm8994->aifclk[0] < wm8994->aifclk[1]) + new = WM8994_SYSCLK_SRC; + else + new = 0; + + old = snd_soc_read(codec, WM8994_CLOCKING_1) & WM8994_SYSCLK_SRC; + + /* If there's no change then we're done. */ + if (old == new) + return 0; + + snd_soc_update_bits(codec, WM8994_CLOCKING_1, WM8994_SYSCLK_SRC, new); + + snd_soc_dapm_sync(codec); + + return 0; } -static void wm8994_set_volume(unsigned char wm8994_mode,unsigned char volume,unsigned char max_volume) +static int check_clk_sys(struct snd_soc_dapm_widget *source, + struct snd_soc_dapm_widget *sink) { - unsigned short lvol=0,rvol=0; -// DBG("%s::volume = %d \n",__FUNCTION__,volume); + int reg = snd_soc_read(source->codec, WM8994_CLOCKING_1); + const char *clk; - if(volume>max_volume) - volume=max_volume; - - switch(wm8994_mode) - { - case wm8994_handsetMIC_to_baseband_to_headset: - case wm8994_mainMIC_to_baseband_to_headset: - wm8994_read(0x001C, &lvol); - wm8994_read(0x001D, &rvol); - //HPOUT1L_VOL bit 0~5 /-57dB to +6dB in 1dB steps - wm8994_write(0x001C, (lvol&~0x003f)|headset_vol_table[volume]); - //HPOUT1R_VOL bit 0~5 /-57dB to +6dB in 1dB steps - wm8994_write(0x001D, (rvol&~0x003f)|headset_vol_table[volume]); - break; - case wm8994_mainMIC_to_baseband_to_speakers: - wm8994_read(0x0026, &lvol); - wm8994_read(0x0027, &rvol); - //SPKOUTL_VOL bit 0~5 /-57dB to +6dB in 1dB steps - wm8994_write(0x0026, (lvol&~0x003f)|speakers_vol_table[volume]); - //SPKOUTR_VOL bit 0~5 /-57dB to +6dB in 1dB steps - wm8994_write(0x0027, (rvol&~0x003f)|speakers_vol_table[volume]); - break; - case wm8994_mainMIC_to_baseband_to_earpiece: - wm8994_read(0x0020, &lvol); - wm8994_read(0x0021, &rvol); - //MIXOUTL_VOL bit 0~5 /-57dB to +6dB in 1dB steps - wm8994_write(0x0020, (lvol&~0x003f)|earpiece_vol_table[volume]); - //MIXOUTR_VOL bit 0~5 /-57dB to +6dB in 1dB steps - wm8994_write(0x0021, (rvol&~0x003f)|earpiece_vol_table[volume]); - break; - case wm8994_BT_baseband: - //bit 0~4 /-16.5dB to +30dB in 1.5dB steps - DBG("BT_vol_table[volume] = 0x%x\n",BT_vol_table[volume]); - wm8994_write(0x0500, BT_vol_table[volume]); - wm8994_write(0x0501, 0x0100); - break; - default: - // DBG("Set all volume\n"); - wm8994_read(0x001C, &lvol); - wm8994_read(0x001D, &rvol); - wm8994_write(0x001C, (lvol&~0x003f)|headset_vol_table[volume]); - wm8994_write(0x001D, (rvol&~0x003f)|headset_vol_table[volume]); - wm8994_read(0x0026, &lvol); - wm8994_read(0x0027, &rvol); - wm8994_write(0x0026, (lvol&~0x003f)|speakers_vol_table[volume]); - wm8994_write(0x0027, (rvol&~0x003f)|speakers_vol_table[volume]); - wm8994_read(0x0020, &lvol); - wm8994_read(0x0021, &rvol); - wm8994_write(0x0020, (lvol&~0x003f)|earpiece_vol_table[volume]); - wm8994_write(0x0021, (rvol&~0x003f)|earpiece_vol_table[volume]); - break; - } + /* Check what we're currently using for CLK_SYS */ + if (reg & WM8994_SYSCLK_SRC) + clk = "AIF2CLK"; + else + clk = "AIF1CLK"; + + return strcmp(source->name, clk) == 0; } -static void wm8994_set_all_mute(void) +static const char *sidetone_hpf_text[] = { + "2.7kHz", "1.35kHz", "675Hz", "370Hz", "180Hz", "90Hz", "45Hz" +}; + +static const struct soc_enum sidetone_hpf = + SOC_ENUM_SINGLE(WM8994_SIDETONE, 7, 7, sidetone_hpf_text); + +static const DECLARE_TLV_DB_SCALE(aif_tlv, 0, 600, 0); +static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1); +static const DECLARE_TLV_DB_SCALE(st_tlv, -3600, 300, 0); +static const DECLARE_TLV_DB_SCALE(wm8994_3d_tlv, -1600, 183, 0); +static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); + +#define WM8994_DRC_SWITCH(xname, reg, shift) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ + .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\ + .put = wm8994_put_drc_sw, \ + .private_value = SOC_SINGLE_VALUE(reg, shift, 1, 0) } + +static int wm8994_put_drc_sw(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { - int i; - struct wm8994_priv *wm8994 = wm8994_codec->private_data; + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + int mask, ret; + + /* Can't enable both ADC and DAC paths simultaneously */ + if (mc->shift == WM8994_AIF1DAC1_DRC_ENA_SHIFT) + mask = WM8994_AIF1ADC1L_DRC_ENA_MASK | + WM8994_AIF1ADC1R_DRC_ENA_MASK; + else + mask = WM8994_AIF1DAC1_DRC_ENA_MASK; - if(wm8994->call_vol < 0) - return; + ret = snd_soc_read(codec, mc->reg); + if (ret < 0) + return ret; + if (ret & mask) + return -EINVAL; + + return snd_soc_put_volsw(kcontrol, ucontrol); +} - for (i = wm8994->call_vol; i >= 0; i--) - wm8994_set_volume(null,i,call_maxvol); + +static void wm8994_set_drc(struct snd_soc_codec *codec, int drc) +{ + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + struct wm8994_pdata *pdata = wm8994->pdata; + int base = wm8994_drc_base[drc]; + int cfg = wm8994->drc_cfg[drc]; + int save, i; + + /* Save any enables; the configuration should clear them. */ + save = snd_soc_read(codec, base); + save &= WM8994_AIF1DAC1_DRC_ENA | WM8994_AIF1ADC1L_DRC_ENA | + WM8994_AIF1ADC1R_DRC_ENA; + + for (i = 0; i < WM8994_DRC_REGS; i++) + snd_soc_update_bits(codec, base + i, 0xffff, + pdata->drc_cfgs[cfg].regs[i]); + + snd_soc_update_bits(codec, base, WM8994_AIF1DAC1_DRC_ENA | + WM8994_AIF1ADC1L_DRC_ENA | + WM8994_AIF1ADC1R_DRC_ENA, save); } -static void wm8994_set_level_volume(void) +/* Icky as hell but saves code duplication */ +static int wm8994_get_drc(const char *name) { - int i; - struct wm8994_priv *wm8994 = wm8994_codec->private_data; - - for (i = 0; i <= wm8994->call_vol; i++) - wm8994_set_volume(wm8994_current_mode,i,call_maxvol); - + if (strcmp(name, "AIF1DRC1 Mode") == 0) + return 0; + if (strcmp(name, "AIF1DRC2 Mode") == 0) + return 1; + if (strcmp(name, "AIF2DRC Mode") == 0) + return 2; + return -EINVAL; } -static void PA_ctrl(unsigned char ctrl) +static int wm8994_put_drc_enum(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { - struct wm8994_priv *wm8994 = wm8994_codec->private_data; + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); struct wm8994_pdata *pdata = wm8994->pdata; - - if(pdata->PA_control_pin > 0) - { - if(ctrl == GPIO_HIGH) - { - DBG("enable PA_control\n"); - gpio_request(pdata->PA_control_pin, NULL); //AUDIO_PA_ON - gpio_direction_output(pdata->PA_control_pin,GPIO_HIGH); - gpio_free(pdata->PA_control_pin); - } - else - { - DBG("disable PA_control\n"); - gpio_request(pdata->PA_control_pin, NULL); //AUDIO_PA_ON - gpio_direction_output(pdata->PA_control_pin,GPIO_LOW); - gpio_free(pdata->PA_control_pin); - } - } -} + int drc = wm8994_get_drc(kcontrol->id.name); + int value = ucontrol->value.integer.value[0]; -/* The size in bits of the FLL divide multiplied by 10 - * to allow rounding later */ -#define FIXED_FLL_SIZE ((1 << 16) * 10) + if (drc < 0) + return drc; -struct fll_div { - u16 outdiv; - u16 n; - u16 k; - u16 clk_ref_div; - u16 fll_fratio; -}; + if (value >= pdata->num_drc_cfgs) + return -EINVAL; -static int wm8994_get_fll_config(struct fll_div *fll, - int freq_in, int freq_out) + wm8994->drc_cfg[drc] = value; + + wm8994_set_drc(codec, drc); + + return 0; +} + +static int wm8994_get_drc_enum(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { - u64 Kpart; - unsigned int K, Ndiv, Nmod; + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + int drc = wm8994_get_drc(kcontrol->id.name); -// DBG("FLL input=%dHz, output=%dHz\n", freq_in, freq_out); + ucontrol->value.enumerated.item[0] = wm8994->drc_cfg[drc]; - /* Scale the input frequency down to <= 13.5MHz */ - fll->clk_ref_div = 0; - while (freq_in > 13500000) { - fll->clk_ref_div++; - freq_in /= 2; + return 0; +} - if (fll->clk_ref_div > 3) - return -EINVAL; - } -// DBG("CLK_REF_DIV=%d, Fref=%dHz\n", fll->clk_ref_div, freq_in);//0 12m +static void wm8994_set_retune_mobile(struct snd_soc_codec *codec, int block) +{ + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + struct wm8994_pdata *pdata = wm8994->pdata; + int base = wm8994_retune_mobile_base[block]; + int iface, best, best_val, save, i, cfg; - /* Scale the output to give 90MHz<=Fvco<=100MHz */ - fll->outdiv = 3; - while (freq_out * (fll->outdiv + 1) < 90000000) { - fll->outdiv++; - if (fll->outdiv > 63) - return -EINVAL; + if (!pdata || !wm8994->num_retune_mobile_texts) + return; + + switch (block) { + case 0: + case 1: + iface = 0; + break; + case 2: + iface = 1; + break; + default: + return; } - freq_out *= fll->outdiv + 1; -// DBG("OUTDIV=%d, Fvco=%dHz\n", fll->outdiv, freq_out);//8 98.304MHz - if (freq_in > 1000000) { - fll->fll_fratio = 0; - } else { - fll->fll_fratio = 3; - freq_in *= 8; + /* Find the version of the currently selected configuration + * with the nearest sample rate. */ + cfg = wm8994->retune_mobile_cfg[block]; + best = 0; + best_val = INT_MAX; + for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) { + if (strcmp(pdata->retune_mobile_cfgs[i].name, + wm8994->retune_mobile_texts[cfg]) == 0 && + abs(pdata->retune_mobile_cfgs[i].rate + - wm8994->dac_rates[iface]) < best_val) { + best = i; + best_val = abs(pdata->retune_mobile_cfgs[i].rate + - wm8994->dac_rates[iface]); + } } -// DBG("FLL_FRATIO=%d, Fref=%dHz\n", fll->fll_fratio, freq_in);//0 12M - /* Now, calculate N.K */ - Ndiv = freq_out / freq_in; + dev_dbg(codec->dev, "ReTune Mobile %d %s/%dHz for %dHz sample rate\n", + block, + pdata->retune_mobile_cfgs[best].name, + pdata->retune_mobile_cfgs[best].rate, + wm8994->dac_rates[iface]); - fll->n = Ndiv; - Nmod = freq_out % freq_in; -// DBG("Nmod=%d\n", Nmod); + /* The EQ will be disabled while reconfiguring it, remember the + * current configuration. + */ + save = snd_soc_read(codec, base); + save &= WM8994_AIF1DAC1_EQ_ENA; - /* Calculate fractional part - scale up so we can round. */ - Kpart = FIXED_FLL_SIZE * (long long)Nmod; + for (i = 0; i < WM8994_EQ_REGS; i++) + snd_soc_update_bits(codec, base + i, 0xffff, + pdata->retune_mobile_cfgs[best].regs[i]); - do_div(Kpart, freq_in); + snd_soc_update_bits(codec, base, WM8994_AIF1DAC1_EQ_ENA, save); +} - K = Kpart & 0xFFFFFFFF; +/* Icky as hell but saves code duplication */ +static int wm8994_get_retune_mobile_block(const char *name) +{ + if (strcmp(name, "AIF1.1 EQ Mode") == 0) + return 0; + if (strcmp(name, "AIF1.2 EQ Mode") == 0) + return 1; + if (strcmp(name, "AIF2 EQ Mode") == 0) + return 2; + return -EINVAL; +} - if ((K % 10) >= 5) - K += 5; +static int wm8994_put_retune_mobile_enum(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + struct wm8994_pdata *pdata = wm8994->pdata; + int block = wm8994_get_retune_mobile_block(kcontrol->id.name); + int value = ucontrol->value.integer.value[0]; - /* Move down to proper range now rounding is done */ - fll->k = K / 10; + if (block < 0) + return block; + + if (value >= pdata->num_retune_mobile_cfgs) + return -EINVAL; + + wm8994->retune_mobile_cfg[block] = value; -// DBG("N=%x K=%x\n", fll->n, fll->k);//8 3127 + wm8994_set_retune_mobile(codec, block); return 0; } -static int wm8994_set_fll(unsigned int freq_in, unsigned int freq_out) +static int wm8994_get_retune_mobile_enum(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { - int ret; - struct fll_div fll; - u16 reg=0; -// DBG("Enter %s::%s---%d\n",__FILE__,__FUNCTION__,__LINE__); - wm8994_write(0x220, 0x0000); - /* If we're stopping the FLL redo the old config - no - * registers will actually be written but we avoid GCC flow - * analysis bugs spewing warnings. - */ - ret = wm8994_get_fll_config(&fll, freq_in, freq_out); - if (ret < 0) - return ret; + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + int block = wm8994_get_retune_mobile_block(kcontrol->id.name); + + ucontrol->value.enumerated.item[0] = wm8994->retune_mobile_cfg[block]; - reg = (fll.outdiv << WM8994_FLL1_OUTDIV_SHIFT) |(fll.fll_fratio << WM8994_FLL1_FRATIO_SHIFT); - wm8994_write(0x221, reg);//0x221 DIV - wm8994_write(0x222, fll.k);//0x222 K - wm8994_write(0x223, fll.n << WM8994_FLL1_N_SHIFT);//0x223 N - wm8994_write(0x224, fll.clk_ref_div << WM8994_FLL1_REFCLK_DIV_SHIFT);//0x224 - - wm8994_write(0x220, 0x0004); - msleep(10); - wm8994_write(0x220, 0x0005); - msleep(5); - wm8994_write(0x200, 0x0010); // sysclk = MCLK1 return 0; } -static int wm8994_sysclk_config(void) +static const struct snd_kcontrol_new wm8994_snd_controls[] = { +SOC_DOUBLE_R_TLV("AIF1ADC1 Volume", WM8994_AIF1_ADC1_LEFT_VOLUME, + WM8994_AIF1_ADC1_RIGHT_VOLUME, + 1, 119, 0, digital_tlv), +SOC_DOUBLE_R_TLV("AIF1ADC2 Volume", WM8994_AIF1_ADC2_LEFT_VOLUME, + WM8994_AIF1_ADC2_RIGHT_VOLUME, + 1, 119, 0, digital_tlv), +SOC_DOUBLE_R_TLV("AIF2ADC Volume", WM8994_AIF2_ADC_LEFT_VOLUME, + WM8994_AIF2_ADC_RIGHT_VOLUME, + 1, 119, 0, digital_tlv), + +SOC_DOUBLE_R_TLV("AIF1DAC1 Volume", WM8994_AIF1_DAC1_LEFT_VOLUME, + WM8994_AIF1_DAC1_RIGHT_VOLUME, 1, 96, 0, digital_tlv), +SOC_DOUBLE_R_TLV("AIF1DAC2 Volume", WM8994_AIF1_DAC2_LEFT_VOLUME, + WM8994_AIF1_DAC2_RIGHT_VOLUME, 1, 96, 0, digital_tlv), +SOC_DOUBLE_R_TLV("AIF2DAC Volume", WM8994_AIF2_DAC_LEFT_VOLUME, + WM8994_AIF2_DAC_RIGHT_VOLUME, 1, 96, 0, digital_tlv), + +SOC_SINGLE_TLV("AIF1 Boost Volume", WM8994_AIF1_CONTROL_2, 10, 3, 0, aif_tlv), +SOC_SINGLE_TLV("AIF2 Boost Volume", WM8994_AIF2_CONTROL_2, 10, 3, 0, aif_tlv), + +SOC_SINGLE("AIF1DAC1 EQ Switch", WM8994_AIF1_DAC1_EQ_GAINS_1, 0, 1, 0), +SOC_SINGLE("AIF1DAC2 EQ Switch", WM8994_AIF1_DAC2_EQ_GAINS_1, 0, 1, 0), +SOC_SINGLE("AIF2 EQ Switch", WM8994_AIF2_EQ_GAINS_1, 0, 1, 0), + +WM8994_DRC_SWITCH("AIF1DAC1 DRC Switch", WM8994_AIF1_DRC1_1, 2), +WM8994_DRC_SWITCH("AIF1ADC1L DRC Switch", WM8994_AIF1_DRC1_1, 1), +WM8994_DRC_SWITCH("AIF1ADC1R DRC Switch", WM8994_AIF1_DRC1_1, 0), + +WM8994_DRC_SWITCH("AIF1DAC2 DRC Switch", WM8994_AIF1_DRC2_1, 2), +WM8994_DRC_SWITCH("AIF1ADC2L DRC Switch", WM8994_AIF1_DRC2_1, 1), +WM8994_DRC_SWITCH("AIF1ADC2R DRC Switch", WM8994_AIF1_DRC2_1, 0), + +WM8994_DRC_SWITCH("AIF2DAC DRC Switch", WM8994_AIF2_DRC_1, 2), +WM8994_DRC_SWITCH("AIF2ADCL DRC Switch", WM8994_AIF2_DRC_1, 1), +WM8994_DRC_SWITCH("AIF2ADCR DRC Switch", WM8994_AIF2_DRC_1, 0), + +SOC_SINGLE_TLV("DAC1 Right Sidetone Volume", WM8994_DAC1_MIXER_VOLUMES, + 5, 12, 0, st_tlv), +SOC_SINGLE_TLV("DAC1 Left Sidetone Volume", WM8994_DAC1_MIXER_VOLUMES, + 0, 12, 0, st_tlv), +SOC_SINGLE_TLV("DAC2 Right Sidetone Volume", WM8994_DAC2_MIXER_VOLUMES, + 5, 12, 0, st_tlv), +SOC_SINGLE_TLV("DAC2 Left Sidetone Volume", WM8994_DAC2_MIXER_VOLUMES, + 0, 12, 0, st_tlv), +SOC_ENUM("Sidetone HPF Mux", sidetone_hpf), +SOC_SINGLE("Sidetone HPF Switch", WM8994_SIDETONE, 6, 1, 0), + +SOC_DOUBLE_R_TLV("DAC1 Volume", WM8994_DAC1_LEFT_VOLUME, + WM8994_DAC1_RIGHT_VOLUME, 1, 96, 0, digital_tlv), +SOC_DOUBLE_R("DAC1 Switch", WM8994_DAC1_LEFT_VOLUME, + WM8994_DAC1_RIGHT_VOLUME, 9, 1, 1), + +SOC_DOUBLE_R_TLV("DAC2 Volume", WM8994_DAC2_LEFT_VOLUME, + WM8994_DAC2_RIGHT_VOLUME, 1, 96, 0, digital_tlv), +SOC_DOUBLE_R("DAC2 Switch", WM8994_DAC2_LEFT_VOLUME, + WM8994_DAC2_RIGHT_VOLUME, 9, 1, 1), + +SOC_SINGLE_TLV("SPKL DAC2 Volume", WM8994_SPKMIXL_ATTENUATION, + 6, 1, 1, wm_hubs_spkmix_tlv), +SOC_SINGLE_TLV("SPKL DAC1 Volume", WM8994_SPKMIXL_ATTENUATION, + 2, 1, 1, wm_hubs_spkmix_tlv), + +SOC_SINGLE_TLV("SPKR DAC2 Volume", WM8994_SPKMIXR_ATTENUATION, + 6, 1, 1, wm_hubs_spkmix_tlv), +SOC_SINGLE_TLV("SPKR DAC1 Volume", WM8994_SPKMIXR_ATTENUATION, + 2, 1, 1, wm_hubs_spkmix_tlv), + +SOC_SINGLE_TLV("AIF1DAC1 3D Stereo Volume", WM8994_AIF1_DAC1_FILTERS_2, + 10, 15, 0, wm8994_3d_tlv), +SOC_SINGLE("AIF1DAC1 3D Stereo Switch", WM8994_AIF1_DAC2_FILTERS_2, + 8, 1, 0), +SOC_SINGLE_TLV("AIF1DAC2 3D Stereo Volume", WM8994_AIF1_DAC2_FILTERS_2, + 10, 15, 0, wm8994_3d_tlv), +SOC_SINGLE("AIF1DAC2 3D Stereo Switch", WM8994_AIF1_DAC2_FILTERS_2, + 8, 1, 0), +SOC_SINGLE_TLV("AIF2DAC 3D Stereo Volume", WM8994_AIF1_DAC1_FILTERS_2, + 10, 15, 0, wm8994_3d_tlv), +SOC_SINGLE("AIF2DAC 3D Stereo Switch", WM8994_AIF1_DAC2_FILTERS_2, + 8, 1, 0), +}; + +static const struct snd_kcontrol_new wm8994_eq_controls[] = { +SOC_SINGLE_TLV("AIF1DAC1 EQ1 Volume", WM8994_AIF1_DAC1_EQ_GAINS_1, 11, 31, 0, + eq_tlv), +SOC_SINGLE_TLV("AIF1DAC1 EQ2 Volume", WM8994_AIF1_DAC1_EQ_GAINS_1, 6, 31, 0, + eq_tlv), +SOC_SINGLE_TLV("AIF1DAC1 EQ3 Volume", WM8994_AIF1_DAC1_EQ_GAINS_1, 1, 31, 0, + eq_tlv), +SOC_SINGLE_TLV("AIF1DAC1 EQ4 Volume", WM8994_AIF1_DAC1_EQ_GAINS_2, 11, 31, 0, + eq_tlv), +SOC_SINGLE_TLV("AIF1DAC1 EQ5 Volume", WM8994_AIF1_DAC1_EQ_GAINS_2, 6, 31, 0, + eq_tlv), + +SOC_SINGLE_TLV("AIF1DAC2 EQ1 Volume", WM8994_AIF1_DAC2_EQ_GAINS_1, 11, 31, 0, + eq_tlv), +SOC_SINGLE_TLV("AIF1DAC2 EQ2 Volume", WM8994_AIF1_DAC2_EQ_GAINS_1, 6, 31, 0, + eq_tlv), +SOC_SINGLE_TLV("AIF1DAC2 EQ3 Volume", WM8994_AIF1_DAC2_EQ_GAINS_1, 1, 31, 0, + eq_tlv), +SOC_SINGLE_TLV("AIF1DAC2 EQ4 Volume", WM8994_AIF1_DAC2_EQ_GAINS_2, 11, 31, 0, + eq_tlv), +SOC_SINGLE_TLV("AIF1DAC2 EQ5 Volume", WM8994_AIF1_DAC2_EQ_GAINS_2, 6, 31, 0, + eq_tlv), + +SOC_SINGLE_TLV("AIF2 EQ1 Volume", WM8994_AIF2_EQ_GAINS_1, 11, 31, 0, + eq_tlv), +SOC_SINGLE_TLV("AIF2 EQ2 Volume", WM8994_AIF2_EQ_GAINS_1, 6, 31, 0, + eq_tlv), +SOC_SINGLE_TLV("AIF2 EQ3 Volume", WM8994_AIF2_EQ_GAINS_1, 1, 31, 0, + eq_tlv), +SOC_SINGLE_TLV("AIF2 EQ4 Volume", WM8994_AIF2_EQ_GAINS_2, 11, 31, 0, + eq_tlv), +SOC_SINGLE_TLV("AIF2 EQ5 Volume", WM8994_AIF2_EQ_GAINS_2, 6, 31, 0, + eq_tlv), +}; + +static int clk_sys_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) { - struct wm8994_priv *wm8994 = wm8994_codec->private_data; - unsigned int freq_in,freq_out; - - wm8994_write(0x200, 0x0000); - freq_in = wm8994->mclk; - switch(wm8994->mclk) - { - case 12288000: - case 11289600: - freq_out = wm8994->mclk; - break; - case 3072000: - case 2822400: - freq_out = wm8994->mclk * 4; + struct snd_soc_codec *codec = w->codec; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + return configure_clock(codec); + + case SND_SOC_DAPM_POST_PMD: + configure_clock(codec); break; - default: - printk("wm8994->mclk error = %d\n",wm8994->mclk); - return -1; } - - switch(wm8994->sysclk) - { - case WM8994_SYSCLK_FLL1: - wm8994_set_fll(freq_in,freq_out); - break; - case WM8994_SYSCLK_FLL2: - break; - case WM8994_SYSCLK_MCLK2: - wm8994_write(0x701, 0x0000);//MCLK2 - case WM8994_SYSCLK_MCLK1: - if(freq_out == freq_in) - break; - default: - printk("wm8994->sysclk error = %d\n",wm8994->sysclk); - return -1; + + return 0; +} + +static void wm8994_update_class_w(struct snd_soc_codec *codec) +{ + int enable = 1; + int source = 0; /* GCC flow analysis can't track enable */ + int reg, reg_r; + + /* Only support direct DAC->headphone paths */ + reg = snd_soc_read(codec, WM8994_OUTPUT_MIXER_1); + if (!(reg & WM8994_DAC1L_TO_HPOUT1L)) { + dev_vdbg(codec->dev, "HPL connected to output mixer\n"); + enable = 0; } - - wm8994_write(0x208, 0x0008); //DSP_FS1CLK_ENA=1, DSP_FSINTCLK_ENA=1 - wm8994_write(0x208, 0x000A); //DSP_FS1CLK_ENA=1, DSP_FSINTCLK_ENA=1 - - switch(wm8994->rate) - { - case 8000: - printk("wm8994->rate = %d!!!!\n",wm8994->rate); + + reg = snd_soc_read(codec, WM8994_OUTPUT_MIXER_2); + if (!(reg & WM8994_DAC1R_TO_HPOUT1R)) { + dev_vdbg(codec->dev, "HPR connected to output mixer\n"); + enable = 0; + } + + /* We also need the same setting for L/R and only one path */ + reg = snd_soc_read(codec, WM8994_DAC1_LEFT_MIXER_ROUTING); + switch (reg) { + case WM8994_AIF2DACL_TO_DAC1L: + dev_vdbg(codec->dev, "Class W source AIF2DAC\n"); + source = 2 << WM8994_CP_DYN_SRC_SEL_SHIFT; break; - case 44100: - wm8994_write(0x210, 0x0073); // SR=44.1KHz + case WM8994_AIF1DAC2L_TO_DAC1L: + dev_vdbg(codec->dev, "Class W source AIF1DAC2\n"); + source = 1 << WM8994_CP_DYN_SRC_SEL_SHIFT; break; - case 48000: - wm8994_write(0x210, 0x0083); // SR=48KHz + case WM8994_AIF1DAC1L_TO_DAC1L: + dev_vdbg(codec->dev, "Class W source AIF1DAC1\n"); + source = 0 << WM8994_CP_DYN_SRC_SEL_SHIFT; break; - case 11025: - case 16000: - case 22050: - case 32000: default: - printk("wm8994->rate error = %d\n",wm8994->rate); - return -1; - } - - switch(wm8994->fmt) - { - case SND_SOC_DAIFMT_CBS_CFS: - case SND_SOC_DAIFMT_CBM_CFM: + dev_vdbg(codec->dev, "DAC mixer setting: %x\n", reg); + enable = 0; break; - default: - printk("wm8994->fmt error = %d\n",wm8994->fmt); - return -1; } - - wm8994_write(0x200, wm8994->sysclk << 3|0x01); - return 0; -} -static void wm8994_set_AIF1DAC_EQ(void) -{ - //100HZ. 300HZ. 875HZ 2400HZ 6900HZ -// int bank_vol[6] = {0,0,-3,3,-6,3};//-12DB ~ 12DB default 0DB - int bank_vol[6] = {6,2,0,0,0,0};//-12DB ~ 12DB default 0DB - wm8994_write(0x0480, 0x0001|((bank_vol[1]+12)<<11)| - ((bank_vol[2]+12)<<6)|((bank_vol[3]+12)<<1)); - wm8994_write(0x0481, 0x0000|((bank_vol[4]+12)<<11)| - ((bank_vol[5]+12)<<6)); -} + reg_r = snd_soc_read(codec, WM8994_DAC1_RIGHT_MIXER_ROUTING); + if (reg_r != reg) { + dev_vdbg(codec->dev, "Left and right DAC mixers different\n"); + enable = 0; + } -static int wm8994_reset_ldo(void) -{ - struct wm8994_priv *wm8994 = wm8994_codec->private_data; - struct wm8994_pdata *pdata = wm8994->pdata; - unsigned short value; - - if(wm8994->RW_status == TRUE) - return 0; - - gpio_request(pdata->Power_EN_Pin, NULL); - gpio_direction_output(pdata->Power_EN_Pin,GPIO_LOW); - gpio_free(pdata->Power_EN_Pin); - msleep(50); - gpio_request(pdata->Power_EN_Pin, NULL); - gpio_direction_output(pdata->Power_EN_Pin,GPIO_HIGH); - gpio_free(pdata->Power_EN_Pin); - msleep(50); - - wm8994->RW_status = TRUE; - wm8994_read(0x00, &value); - - if(value == 0x8994) - DBG("wm8994_reset_ldo Read ID = 0x%x\n",value); - else - { - wm8994->RW_status = ERROR; - printk("wm8994_reset_ldo Read ID error value = 0x%x\n",value); - return -1; - } + if (enable) { + dev_dbg(codec->dev, "Class W enabled\n"); + snd_soc_update_bits(codec, WM8994_CLASS_W_1, + WM8994_CP_DYN_PWR | + WM8994_CP_DYN_SRC_SEL_MASK, + source | WM8994_CP_DYN_PWR); - return 0; + } else { + dev_dbg(codec->dev, "Class W disabled\n"); + snd_soc_update_bits(codec, WM8994_CLASS_W_1, + WM8994_CP_DYN_PWR, 0); + } } -//Set the volume of each channel (including recording) -static void wm8994_set_channel_vol(void) + +static const char *hp_mux_text[] = { + "Mixer", + "DAC", +}; + +#define WM8994_HP_ENUM(xname, xenum) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ + .info = snd_soc_info_enum_double, \ + .get = snd_soc_dapm_get_enum_double, \ + .put = wm8994_put_hp_enum, \ + .private_value = (unsigned long)&xenum } + +static int wm8994_put_hp_enum(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { - struct wm8994_priv *wm8994 = wm8994_codec->private_data; - struct wm8994_pdata *pdata = wm8994->pdata; - int vol; - - switch(wm8994_current_mode){ - case wm8994_AP_to_speakers_and_headset: - MAX_MIN(-57,pdata->speaker_normal_vol,6); - MAX_MIN(-57,pdata->headset_normal_vol,6); - DBG("headset_normal_vol = %ddB \n",pdata->headset_normal_vol); - DBG("speaker_normal_vol = %ddB \n",pdata->speaker_normal_vol); - - vol = pdata->speaker_normal_vol; - wm8994_write(0x26, 320+vol+57); //-57dB~6dB - wm8994_write(0x27, 320+vol+57); //-57dB~6dB - - vol = pdata->headset_normal_vol-4; - //for turn off headset volume when ringtone - if(vol >= -48) - vol -= 14; - else - vol = -57; + struct snd_soc_dapm_widget *w = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = w->codec; + int ret; - wm8994_write(0x1C, 320+vol+57); //-57dB~6dB - wm8994_write(0x1D, 320+vol+57); //-57dB~6dB + ret = snd_soc_dapm_put_enum_double(kcontrol, ucontrol); - wm8994_set_AIF1DAC_EQ(); - break; + wm8994_update_class_w(codec); - case wm8994_AP_to_headset: - MAX_MIN(-57,pdata->headset_normal_vol,6); - DBG("headset_normal_vol = %ddB \n",pdata->headset_normal_vol); - vol = pdata->headset_normal_vol; - wm8994_write(0x1C, 320+vol+57); //-57dB~6dB - wm8994_write(0x1D, 320+vol+57); //-57dB~6dB - break; + return ret; +} - case wm8994_AP_to_speakers: - MAX_MIN(-57,pdata->speaker_normal_vol,6); - DBG("speaker_normal_vol = %ddB \n",pdata->speaker_normal_vol); - vol = pdata->speaker_normal_vol; - wm8994_write(0x26, 320+vol+57); //-57dB~6dB - wm8994_write(0x27, 320+vol+57); //-57dB~6dB - break; - - case wm8994_handsetMIC_to_baseband_to_headset: - MAX_MIN(-12,pdata->headset_incall_vol,6); - MAX_MIN(-22,pdata->headset_incall_mic_vol,30); - DBG("headset_incall_mic_vol = %ddB \n",pdata->headset_incall_mic_vol); - DBG("headset_incall_vol = %ddB \n",pdata->headset_incall_vol); - - vol = pdata->headset_incall_mic_vol; - if(vol<-16) - { - wm8994_write(0x1E, 0x0016); //mic vol - wm8994_write(0x18, 320+(vol+22)*10/15); //mic vol - } - else - { - wm8994_write(0x1E, 0x0006); //mic vol - wm8994_write(0x18, 320+(vol+16)*10/15); //mic vol - } - break; - case wm8994_mainMIC_to_baseband_to_headset: - MAX_MIN(-12,pdata->headset_incall_vol,6); - MAX_MIN(-22,pdata->speaker_incall_mic_vol,30); - DBG("speaker_incall_mic_vol = %ddB \n",pdata->speaker_incall_mic_vol); - DBG("headset_incall_vol = %ddB \n",pdata->headset_incall_vol); - - vol=pdata->speaker_incall_mic_vol; - if(vol<-16) - { - wm8994_write(0x1E, 0x0016); //mic vol - wm8994_write(0x1A, 320+(vol+22)*10/15); //mic vol - } - else - { - wm8994_write(0x1E, 0x0006); //mic vol - wm8994_write(0x1A, 320+(vol+16)*10/15); //mic vol - } - break; +static const struct soc_enum hpl_enum = + SOC_ENUM_SINGLE(WM8994_OUTPUT_MIXER_1, 8, 2, hp_mux_text); - case wm8994_mainMIC_to_baseband_to_earpiece: - MAX_MIN(-22,pdata->speaker_incall_mic_vol,30); - MAX_MIN(-21,pdata->earpiece_incall_vol,6); - DBG("earpiece_incall_vol = %ddB \n",pdata->earpiece_incall_vol); - DBG("speaker_incall_mic_vol = %ddB \n",pdata->speaker_incall_mic_vol); - - vol = pdata->earpiece_incall_vol; - if(vol>=0) - { - wm8994_write(0x33, 0x0018); //6dB - wm8994_write(0x31, (((6-vol)/3)<<3)+(6-vol)/3); //-21dB - } - else - { - wm8994_write(0x33, 0x0010); - wm8994_write(0x31, (((-vol)/3)<<3)+(-vol)/3); //-21dB - } - vol = pdata->speaker_incall_mic_vol; - if(vol<-16) - { - wm8994_write(0x1E, 0x0016); - wm8994_write(0x1A, 320+(vol+22)*10/15); - } - else - { - wm8994_write(0x1E, 0x0006); - wm8994_write(0x1A, 320+(vol+16)*10/15); - } - break; +static const struct snd_kcontrol_new hpl_mux = + WM8994_HP_ENUM("Left Headphone Mux", hpl_enum); - case wm8994_mainMIC_to_baseband_to_speakers: - MAX_MIN(-22,pdata->speaker_incall_mic_vol,30); - MAX_MIN(-21,pdata->speaker_incall_vol,12); - DBG("speaker_incall_vol = %ddB \n",pdata->speaker_incall_vol); - DBG("speaker_incall_mic_vol = %ddB \n",pdata->speaker_incall_mic_vol); - - vol = pdata->speaker_incall_mic_vol; - if(vol<-16) - { - wm8994_write(0x1E, 0x0016); - wm8994_write(0x1A, 320+(vol+22)*10/15); - } - else - { - wm8994_write(0x1E, 0x0006); - wm8994_write(0x1A, 320+(vol+16)*10/15); - } - vol = pdata->speaker_incall_vol; - if(vol<=0) - { - wm8994_write(0x31, (((-vol)/3)<<3)+(-vol)/3); - } - else if(vol <= 9) - { - wm8994_write(0x25, ((vol*10/15)<<3)+vol*10/15); - } - else - { - wm8994_write(0x25, 0x003F); - } - break; +static const struct soc_enum hpr_enum = + SOC_ENUM_SINGLE(WM8994_OUTPUT_MIXER_2, 8, 2, hp_mux_text); - case wm8994_BT_baseband: - MAX_MIN(-16,pdata->BT_incall_vol,30); - MAX_MIN(-57,pdata->BT_incall_mic_vol,6); - DBG("BT_incall_mic_vol = %ddB \n",pdata->BT_incall_mic_vol); - DBG("BT_incall_vol = %ddB \n",pdata->BT_incall_vol); - vol = pdata->BT_incall_mic_vol; - wm8994_write(0x20, 320+vol+57); - vol = pdata->BT_incall_vol; - wm8994_write(0x19, 0x0500+(vol+16)*10/15); - break; - default: - printk("route error !\n"); - } +static const struct snd_kcontrol_new hpr_mux = + WM8994_HP_ENUM("Right Headphone Mux", hpr_enum); -} +static const char *adc_mux_text[] = { + "ADC", + "DMIC", +}; -#define wm8994_reset() wm8994_set_all_mute();\ - wm8994_write(WM8994_RESET, 0) +static const struct soc_enum adc_enum = + SOC_ENUM_SINGLE(0, 0, 2, adc_mux_text); -void record_only(void) -{ - DBG("%s::%d\n",__FUNCTION__,__LINE__); - if(wm8994_current_mode==wm8994_record_only)return; - wm8994_current_mode=wm8994_record_only; - wm8994_write(0,0); - msleep(WM8994_DELAY); - - wm8994_write(0x01, 0x0003); - msleep(WM8994_DELAY); -//clk - wm8994_sysclk_config(); -// wm8994_write(0x300, 0xC010); //AIF1ADCL_SRC=1, AIF1ADCR_SRC=1, AIF1_WL=00, AIF1_FMT=10 - wm8994_write(0x300, 0xC050); // AIF1ADCL_SRC=1, AIF1ADCR_SRC=1, AIF1_WL=10, AIF1_FMT=10 -//path - wm8994_write(0x28, 0x0003); // IN1RP_TO_IN1R=1, IN1RN_TO_IN1R=1 - wm8994_write(0x2A, 0x0020); //IN1R_TO_MIXINR IN1R_MIXINR_VOL - wm8994_write(0x606, 0x0002); // ADC1L_TO_AIF1ADC1L=1 - wm8994_write(0x607, 0x0002); // ADC1R_TO_AIF1ADC1R=1 - wm8994_write(0x620, 0x0000); //ADC_OSR128=0, DAC_OSR128=0 -//DRC - wm8994_write(0x440, 0x01BB); - wm8994_write(0x450, 0x01BB); -//valume -// wm8994_write(0x1A, 0x014B);//IN1_VU=1, IN1R_MUTE=0, IN1R_ZC=1, IN1R_VOL=0_1011 - wm8994_write(0x402, 0x01FF); // AIF1ADC1L_VOL [7:0] - wm8994_write(0x403, 0x01FF); // AIF1ADC1R_VOL [7:0] - -//power - wm8994_write(0x02, 0x6110); // TSHUT_ENA=1, TSHUT_OPDIS=1, MIXINR_ENA=1,IN1R_ENA=1 - wm8994_write(0x04, 0x0303); // AIF1ADC1L_ENA=1, AIF1ADC1R_ENA=1, ADCL_ENA=1, ADCR_ENA=1 - wm8994_write(0x01, 0x3033); -} +static const struct snd_kcontrol_new adcl_mux = + SOC_DAPM_ENUM_VIRT("ADCL Mux", adc_enum); -void recorder_add(void) -{ - struct wm8994_priv *wm8994 = wm8994_codec->private_data; - struct wm8994_pdata *pdata = wm8994->pdata; - if(wm8994_current_mode == null) - { - record_only(); - goto out; - } - DBG("%s::%d\n",__FUNCTION__,__LINE__); - if(wm8994_current_mode==wm8994_record_add)return; - wm8994_current_mode=wm8994_record_add; -//path - wm8994_set_bit(0x28, 0x0003 ,0x0003); // IN1RP_TO_IN1R=1, IN1RN_TO_IN1R=1 - wm8994_set_bit(0x2A, 0x0020 ,0x0020); //IN1R_TO_MIXINR IN1R_MIXINR_VOL - wm8994_set_bit(0x606,0x0002 ,0x0002); // ADC1L_TO_AIF1ADC1L=1 - wm8994_set_bit(0x607,0x0002 ,0x0002); // ADC1R_TO_AIF1ADC1R=1 -//DRC - wm8994_set_bit(0x440,0x01BB,0x01BB); - wm8994_set_bit(0x450,0x01BB,0x01BB); -//valume -// wm8994_set_bit(0x1A, 0x014B);//IN1_VU=1, IN1R_MUTE=0, IN1R_ZC=1, IN1R_VOL=0_1011 - wm8994_set_bit(0x402,0x01FF,0x01FF); // AIF1ADC1L_VOL [7:0] - wm8994_set_bit(0x403,0x01FF,0x01FF); // AIF1ADC1R_VOL [7:0] -//power - wm8994_set_bit(0x02, 0x6110,0x6110); // TSHUT_ENA=1, TSHUT_OPDIS=1, MIXINR_ENA=1,IN1R_ENA=1 - wm8994_set_bit(0x04, 0x0303,0x0303); // AIF1ADC1L_ENA=1, AIF1ADC1R_ENA=1, ADCL_ENA=1, ADCR_ENA=1 - wm8994_set_bit(0x01, 0x0033,0x0033); - -out: - MAX_MIN(-16,pdata->recorder_vol,60); - DBG("recorder_vol = %ddB \n",pdata->recorder_vol); - if(pdata->recorder_vol <= 30) - wm8994_set_bit(0x1A, 0x1FF , 320+(pdata->recorder_vol+16)*10/15); //mic vol - else - { - pdata->recorder_vol -= 30; - wm8994_set_bit(0x2A, 0x0010, 0x0010); //IN1R_TO_MIXINR IN1R_MIXINR_VOL - wm8994_set_bit(0x1A, 0x1FF , 320+(pdata->recorder_vol+16)*10/15); //mic vol - } -} +static const struct snd_kcontrol_new adcr_mux = + SOC_DAPM_ENUM_VIRT("ADCR Mux", adc_enum); -void AP_to_speakers_and_headset(void) -{ - DBG("%s::%d\n",__FUNCTION__,__LINE__); - if(wm8994_current_mode==wm8994_AP_to_speakers_and_headset)return; - wm8994_current_mode=wm8994_AP_to_speakers_and_headset; - wm8994_reset(); - msleep(WM8994_DELAY); - - wm8994_write(0x39, 0x006C); - wm8994_write(0x01, 0x0023); - msleep(WM8994_DELAY); -//clk - wm8994_sysclk_config(); - wm8994_write(0x300, 0xC010); // i2s 16 bits -//path - wm8994_write(0x2D, 0x0100); - wm8994_write(0x2E, 0x0100); - wm8994_write(0x60, 0x0022); - wm8994_write(0x60, 0x00EE); - wm8994_write(0x420, 0x0000); - wm8994_write(0x601, 0x0001); - wm8994_write(0x602, 0x0001); - wm8994_write(0x36, 0x0003); -// wm8994_write(0x24, 0x0011); -//other - wm8994_write(0x4C, 0x9F25); -//volume - wm8994_write(0x22, 0x0000); - wm8994_write(0x23, 0x0100); - wm8994_write(0x610, 0x01C0); //DAC1 Left Volume bit0~7 - wm8994_write(0x611, 0x01C0); //DAC1 Right Volume bit0~7 -// wm8994_write(0x25, 0x003F); - wm8994_set_channel_vol(); -//power - wm8994_write(0x04, 0x0303); // AIF1ADC1L_ENA=1, AIF1ADC1R_ENA=1, ADCL_ENA=1, ADCR_ENA=1 - wm8994_write(0x05, 0x0303); - wm8994_write(0x03, 0x3330); - wm8994_write(0x01, 0x3303); - msleep(50); - wm8994_write(0x01, 0x3333); -} +static const struct snd_kcontrol_new left_speaker_mixer[] = { +SOC_DAPM_SINGLE("DAC2 Switch", WM8994_SPEAKER_MIXER, 9, 1, 0), +SOC_DAPM_SINGLE("Input Switch", WM8994_SPEAKER_MIXER, 7, 1, 0), +SOC_DAPM_SINGLE("IN1LP Switch", WM8994_SPEAKER_MIXER, 5, 1, 0), +SOC_DAPM_SINGLE("Output Switch", WM8994_SPEAKER_MIXER, 3, 1, 0), +SOC_DAPM_SINGLE("DAC1 Switch", WM8994_SPEAKER_MIXER, 1, 1, 0), +}; -void AP_to_headset(void) +static const struct snd_kcontrol_new right_speaker_mixer[] = { +SOC_DAPM_SINGLE("DAC2 Switch", WM8994_SPEAKER_MIXER, 8, 1, 0), +SOC_DAPM_SINGLE("Input Switch", WM8994_SPEAKER_MIXER, 6, 1, 0), +SOC_DAPM_SINGLE("IN1RP Switch", WM8994_SPEAKER_MIXER, 4, 1, 0), +SOC_DAPM_SINGLE("Output Switch", WM8994_SPEAKER_MIXER, 2, 1, 0), +SOC_DAPM_SINGLE("DAC1 Switch", WM8994_SPEAKER_MIXER, 0, 1, 0), +}; + +/* Debugging; dump chip status after DAPM transitions */ +static int post_ev(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) { - DBG("%s::%d\n",__FUNCTION__,__LINE__); - - if(wm8994_current_mode==wm8994_AP_to_headset)return; - wm8994_current_mode=wm8994_AP_to_headset; - wm8994_reset(); - msleep(WM8994_DELAY); - - wm8994_write(0x39, 0x006C); - - wm8994_write(0x01, 0x0003); - msleep(35); - wm8994_write(0xFF, 0x0000); - msleep(5); - wm8994_write(0x4C, 0x9F25); - msleep(5); - wm8994_write(0x01, 0x0303); - wm8994_write(0x60, 0x0022); - msleep(5); - wm8994_write(0x54, 0x0033);// - - wm8994_write(0x200, 0x0000); - msleep(WM8994_DELAY); -//clk - wm8994_sysclk_config(); - wm8994_write(0x300, 0xC010); // i2s 16 bits -//path - wm8994_write(0x2D, 0x0100); // DAC1L_TO_HPOUT1L=1 - wm8994_write(0x2E, 0x0100); // DAC1R_TO_HPOUT1R=1 - wm8994_write(0x60, 0x0022); - wm8994_write(0x60, 0x00FF); - wm8994_write(0x420, 0x0000); - wm8994_write(0x601, 0x0001); // AIF1DAC1L_TO_DAC1L=1 - wm8994_write(0x602, 0x0001); // AIF1DAC1R_TO_DAC1R=1 -//volume - wm8994_write(0x610, 0x01FF); // DAC1_VU=1, DAC1L_VOL=1100_0000 - wm8994_write(0x611, 0x01FF); // DAC1_VU=1, DAC1R_VOL=1100_0000 - wm8994_set_channel_vol(); -//other - wm8994_write(0x620, 0x0001); -//power - wm8994_write(0x03, 0x3030); - wm8994_write(0x05, 0x0303); // AIF1DAC1L_ENA=1, AIF1DAC1R_ENA=1, DAC1L_ENA=1, DAC1R_ENA=1 - - wm8994_write(0x01, 0x0333); + struct snd_soc_codec *codec = w->codec; + dev_dbg(codec->dev, "SRC status: %x\n", + snd_soc_read(codec, + WM8994_RATE_STATUS)); + return 0; } -void AP_to_speakers(void) +static const struct snd_kcontrol_new aif1adc1l_mix[] = { +SOC_DAPM_SINGLE("ADC/DMIC Switch", WM8994_AIF1_ADC1_LEFT_MIXER_ROUTING, + 1, 1, 0), +SOC_DAPM_SINGLE("AIF2 Switch", WM8994_AIF1_ADC1_LEFT_MIXER_ROUTING, + 0, 1, 0), +}; + +static const struct snd_kcontrol_new aif1adc1r_mix[] = { +SOC_DAPM_SINGLE("ADC/DMIC Switch", WM8994_AIF1_ADC1_RIGHT_MIXER_ROUTING, + 1, 1, 0), +SOC_DAPM_SINGLE("AIF2 Switch", WM8994_AIF1_ADC1_RIGHT_MIXER_ROUTING, + 0, 1, 0), +}; + +static const struct snd_kcontrol_new aif1adc2l_mix[] = { +SOC_DAPM_SINGLE("DMIC Switch", WM8994_AIF1_ADC2_LEFT_MIXER_ROUTING, + 1, 1, 0), +SOC_DAPM_SINGLE("AIF2 Switch", WM8994_AIF1_ADC2_LEFT_MIXER_ROUTING, + 0, 1, 0), +}; + +static const struct snd_kcontrol_new aif1adc2r_mix[] = { +SOC_DAPM_SINGLE("DMIC Switch", WM8994_AIF1_ADC2_RIGHT_MIXER_ROUTING, + 1, 1, 0), +SOC_DAPM_SINGLE("AIF2 Switch", WM8994_AIF1_ADC2_RIGHT_MIXER_ROUTING, + 0, 1, 0), +}; + +static const struct snd_kcontrol_new aif2dac2l_mix[] = { +SOC_DAPM_SINGLE("Right Sidetone Switch", WM8994_DAC2_LEFT_MIXER_ROUTING, + 5, 1, 0), +SOC_DAPM_SINGLE("Left Sidetone Switch", WM8994_DAC2_LEFT_MIXER_ROUTING, + 4, 1, 0), +SOC_DAPM_SINGLE("AIF2 Switch", WM8994_DAC2_LEFT_MIXER_ROUTING, + 2, 1, 0), +SOC_DAPM_SINGLE("AIF1.2 Switch", WM8994_DAC2_LEFT_MIXER_ROUTING, + 1, 1, 0), +SOC_DAPM_SINGLE("AIF1.1 Switch", WM8994_DAC2_LEFT_MIXER_ROUTING, + 0, 1, 0), +}; + +static const struct snd_kcontrol_new aif2dac2r_mix[] = { +SOC_DAPM_SINGLE("Right Sidetone Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING, + 5, 1, 0), +SOC_DAPM_SINGLE("Left Sidetone Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING, + 4, 1, 0), +SOC_DAPM_SINGLE("AIF2 Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING, + 2, 1, 0), +SOC_DAPM_SINGLE("AIF1.2 Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING, + 1, 1, 0), +SOC_DAPM_SINGLE("AIF1.1 Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING, + 0, 1, 0), +}; + +#define WM8994_CLASS_W_SWITCH(xname, reg, shift, max, invert) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ + .info = snd_soc_info_volsw, \ + .get = snd_soc_dapm_get_volsw, .put = wm8994_put_class_w, \ + .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) } + +static int wm8994_put_class_w(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { - DBG("%s::%d\n",__FUNCTION__,__LINE__); - - if(wm8994_current_mode==wm8994_AP_to_speakers)return; - wm8994_current_mode=wm8994_AP_to_speakers; - wm8994_reset(); - msleep(WM8994_DELAY); - - wm8994_write(0x39, 0x006C); - wm8994_write(0x01, 0x0023); - msleep(WM8994_DELAY); -//clk - wm8994_sysclk_config(); - wm8994_write(0x300, 0xC010); // i2s 16 bits -//path - wm8994_write(0x2D, 0x0001); // DAC1L_TO_MIXOUTL=1 - wm8994_write(0x2E, 0x0001); // DAC1R_TO_MIXOUTR=1 - wm8994_write(0x36, 0x000C); // MIXOUTL_TO_SPKMIXL=1, MIXOUTR_TO_SPKMIXR=1 - wm8994_write(0x601, 0x0001); // AIF1DAC1L_TO_DAC1L=1 - wm8994_write(0x602, 0x0001); // AIF1DAC1R_TO_DAC1R=1 - wm8994_write(0x420, 0x0000); -// wm8994_write(0x24, 0x001f); -//volume - wm8994_write(0x22, 0x0000); - wm8994_write(0x23, 0x0100); // SPKOUT_CLASSAB=1 - wm8994_write(0x610, 0x01C0); // DAC1_VU=1, DAC1L_VOL=1100_0000 - wm8994_write(0x611, 0x01C0); // DAC1_VU=1, DAC1R_VOL=1100_0000 - wm8994_write(0x25, 0x003F); - wm8994_set_channel_vol(); -//other - wm8994_write(0x4C, 0x9F25); -//power - wm8994_write(0x03, 0x0330); // SPKRVOL_ENA=1, SPKLVOL_ENA=1, MIXOUTL_ENA=1, MIXOUTR_ENA=1 - wm8994_write(0x05, 0x0303); // AIF1DAC1L_ENA=1, AIF1DAC1R_ENA=1, DAC1L_ENA=1, DAC1R_ENA=1 - wm8994_write(0x01, 0x3003); - msleep(50); - wm8994_write(0x01, 0x3033); -} + struct snd_soc_dapm_widget *w = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = w->codec; + int ret; + ret = snd_soc_dapm_put_volsw(kcontrol, ucontrol); -void handsetMIC_to_BB_to_headset(void) -{// - struct wm8994_priv *wm8994 = wm8994_codec->private_data; - struct wm8994_pdata *pdata = wm8994->pdata; - - DBG("%s::%d\n",__FUNCTION__,__LINE__); - - if(wm8994_current_mode == wm8994_handsetMIC_to_baseband_to_headset)return; - wm8994_current_mode = wm8994_handsetMIC_to_baseband_to_headset; - wm8994_reset(); - msleep(WM8994_DELAY); - - wm8994_write(0x01, 0x0023); - wm8994_write(0x200, 0x0000); - msleep(WM8994_DELAY); -//clk - wm8994_sysclk_config(); - wm8994_write(0x300, 0xC010); // i2s 16 bits -//path - wm8994_write(0x28, 0x0030); //IN1LN_TO_IN1L IN1LP_TO_IN1L - wm8994_write(0x34, 0x0002); //IN1L_TO_LINEOUT1P - if(pdata->BB_input_diff == 1) - { - wm8994_write(0x2B, 0x0005); - wm8994_write(0x2D, 0x0041); - wm8994_write(0x2E, 0x0081); - } - else - { - wm8994_write(0x2D, 0x0003); //bit 1 IN2LP_TO_MIXOUTL bit 0 DAC1L_TO_MIXOUTL - wm8994_write(0x2E, 0x0003); //bit 1 IN2RP_TO_MIXOUTR bit 0 DAC1R_TO_MIXOUTL - } - wm8994_write(0x60, 0x0022); - wm8994_write(0x60, 0x00EE); - wm8994_write(0x420, 0x0000); - wm8994_write(0x601, 0x0001); //AIF1DAC1L_TO_DAC1L - wm8994_write(0x602, 0x0001); //AIF1DAC1R_TO_DAC1R -//volume - wm8994_write(0x610, 0x01A0); //DAC1 Left Volume bit0~7 - wm8994_write(0x611, 0x01A0); //DAC1 Right Volume bit0~7 - wm8994_set_channel_vol(); -//other - wm8994_write(0x4C, 0x9F25); -//power - wm8994_write(0x03, 0x3030); - wm8994_write(0x05, 0x0303); - wm8994_write(0x02, 0x6240); - wm8994_write(0x01, 0x0303); - msleep(50); - wm8994_write(0x01, 0x0333); - - wm8994_set_level_volume(); -} + wm8994_update_class_w(codec); -void mainMIC_to_BB_to_headset(void) -{// - struct wm8994_priv *wm8994 = wm8994_codec->private_data; - struct wm8994_pdata *pdata = wm8994->pdata; - - DBG("%s::%d\n",__FUNCTION__,__LINE__); - - if(wm8994_current_mode == wm8994_mainMIC_to_baseband_to_headset)return; - wm8994_current_mode = wm8994_mainMIC_to_baseband_to_headset; - wm8994_reset(); - msleep(WM8994_DELAY); - - wm8994_write(0x01, 0x0023); - wm8994_write(0x200, 0x0000); - mdelay(WM8994_DELAY); -//clk - wm8994_sysclk_config(); - wm8994_write(0x300, 0xC010); // i2s 16 bits -//path - wm8994_write(0x28, 0x0003); //IN1RN_TO_IN1R IN1RP_TO_IN1R - wm8994_write(0x34, 0x0004); //IN1R_TO_LINEOUT1P - if(pdata->BB_input_diff == 1) - { - wm8994_write(0x2B, 0x0005); - wm8994_write(0x2D, 0x0041); - wm8994_write(0x2E, 0x0081); - } - else - { - wm8994_write(0x2D, 0x0003); //bit 1 IN2LP_TO_MIXOUTL bit 0 DAC1L_TO_MIXOUTL - wm8994_write(0x2E, 0x0003); //bit 1 IN2RP_TO_MIXOUTR bit 0 DAC1R_TO_MIXOUTL - } - wm8994_write(0x36, 0x0003); - wm8994_write(0x60, 0x0022); - wm8994_write(0x60, 0x00EE); - wm8994_write(0x420, 0x0000); - wm8994_write(0x601, 0x0001); - wm8994_write(0x602, 0x0001); -//volume - wm8994_write(0x610, 0x01A0); //DAC1 Left Volume bit0~7 - wm8994_write(0x611, 0x01A0); //DAC1 Right Volume bit0~7 - wm8994_set_channel_vol(); -//other - wm8994_write(0x4C, 0x9F25); -//power - wm8994_write(0x03, 0x3030); - wm8994_write(0x05, 0x0303); - wm8994_write(0x02, 0x6250); - wm8994_write(0x01, 0x0303); - msleep(50); - wm8994_write(0x01, 0x0333); - - wm8994_set_level_volume(); + return ret; } -void mainMIC_to_BB_to_earpiece(void) -{// - struct wm8994_priv *wm8994 = wm8994_codec->private_data; - struct wm8994_pdata *pdata = wm8994->pdata; +static const struct snd_kcontrol_new dac1l_mix[] = { +WM8994_CLASS_W_SWITCH("Right Sidetone Switch", WM8994_DAC1_LEFT_MIXER_ROUTING, + 5, 1, 0), +WM8994_CLASS_W_SWITCH("Left Sidetone Switch", WM8994_DAC1_LEFT_MIXER_ROUTING, + 4, 1, 0), +WM8994_CLASS_W_SWITCH("AIF2 Switch", WM8994_DAC1_LEFT_MIXER_ROUTING, + 2, 1, 0), +WM8994_CLASS_W_SWITCH("AIF1.2 Switch", WM8994_DAC1_LEFT_MIXER_ROUTING, + 1, 1, 0), +WM8994_CLASS_W_SWITCH("AIF1.1 Switch", WM8994_DAC1_LEFT_MIXER_ROUTING, + 0, 1, 0), +}; - DBG("%s::%d\n",__FUNCTION__,__LINE__); - - if(wm8994_current_mode == wm8994_mainMIC_to_baseband_to_earpiece)return; - wm8994_current_mode = wm8994_mainMIC_to_baseband_to_earpiece; - wm8994_reset(); - msleep(WM8994_DELAY); - - wm8994_write(0x01, 0x0023); - wm8994_write(0x200, 0x0000); - msleep(WM8994_DELAY); -//clk - wm8994_sysclk_config(); - wm8994_write(0x300, 0xC010); // i2s 16 bits -//path - wm8994_write(0x28, 0x0003); //IN1RP_TO_IN1R IN1RN_TO_IN1R - wm8994_write(0x34, 0x0004); //IN1R_TO_LINEOUT1P - if(pdata->BB_input_diff == 1) - { - wm8994_write(0x2B, 0x0005); - wm8994_write(0x2D, 0x0041); - wm8994_write(0x2E, 0x0081); - } - else - { - wm8994_write(0x2D, 0x0003); //bit 1 IN2LP_TO_MIXOUTL bit 0 DAC1L_TO_MIXOUTL - wm8994_write(0x2E, 0x0003); //bit 1 IN2RP_TO_MIXOUTR bit 0 DAC1R_TO_MIXOUTL - } +static const struct snd_kcontrol_new dac1r_mix[] = { +WM8994_CLASS_W_SWITCH("Right Sidetone Switch", WM8994_DAC1_RIGHT_MIXER_ROUTING, + 5, 1, 0), +WM8994_CLASS_W_SWITCH("Left Sidetone Switch", WM8994_DAC1_RIGHT_MIXER_ROUTING, + 4, 1, 0), +WM8994_CLASS_W_SWITCH("AIF2 Switch", WM8994_DAC1_RIGHT_MIXER_ROUTING, + 2, 1, 0), +WM8994_CLASS_W_SWITCH("AIF1.2 Switch", WM8994_DAC1_RIGHT_MIXER_ROUTING, + 1, 1, 0), +WM8994_CLASS_W_SWITCH("AIF1.1 Switch", WM8994_DAC1_RIGHT_MIXER_ROUTING, + 0, 1, 0), +}; - wm8994_write(0x601, 0x0001); //AIF1DAC1L_TO_DAC1L=1 - wm8994_write(0x602, 0x0001); //AIF1DAC1R_TO_DAC1R=1 - wm8994_write(0x420, 0x0000); -//volume - wm8994_write(0x610, 0x01C0); //DAC1_VU=1, DAC1L_VOL=1100_0000 - wm8994_write(0x611, 0x01C0); //DAC1_VU=1, DAC1R_VOL=1100_0000 - wm8994_write(0x1F, 0x0000);//HPOUT2 - wm8994_set_channel_vol(); -//other - wm8994_write(0x4C, 0x9F25); -//power - wm8994_write(0x01, 0x0833); //HPOUT2_ENA=1, VMID_SEL=01, BIAS_ENA=1 - wm8994_write(0x02, 0x6210); //bit4 IN1R_ENV bit6 IN1L_ENV - wm8994_write(0x03, 0x30F0); - wm8994_write(0x05, 0x0303); - - wm8994_set_level_volume(); -} +static const char *sidetone_text[] = { + "ADC/DMIC1", "DMIC2", +}; -void mainMIC_to_BB_to_speakers(void) -{// - struct wm8994_priv *wm8994 = wm8994_codec->private_data; - struct wm8994_pdata *pdata = wm8994->pdata; +static const struct soc_enum sidetone1_enum = + SOC_ENUM_SINGLE(WM8994_SIDETONE, 0, 2, sidetone_text); - DBG("%s::%d\n",__FUNCTION__,__LINE__); - - if(wm8994_current_mode==wm8994_mainMIC_to_baseband_to_speakers)return; - - wm8994_current_mode=wm8994_mainMIC_to_baseband_to_speakers; - wm8994_reset(); - msleep(WM8994_DELAY); - - wm8994_write(0x39, 0x006C); - wm8994_write(0x01, 0x0023); - wm8994_write(0x200, 0x0000); - msleep(WM8994_DELAY); -//clk - wm8994_sysclk_config(); - wm8994_write(0x300, 0xC010); // i2s 16 bits -//path - wm8994_write(0x22, 0x0000); - wm8994_write(0x23, 0x0100); - wm8994_write(0x24, 0x0011); - //Say - wm8994_write(0x28, 0x0003); //IN1RP_TO_IN1R IN1RN_TO_IN1R - wm8994_write(0x34, 0x0004); //IN1R_TO_LINEOUT1P - //Listen - if(pdata->BB_input_diff == 1) - { - wm8994_write(0x2B, 0x0005); - wm8994_write(0x2D, 0x0041); - wm8994_write(0x2E, 0x0081); - } - else - { - wm8994_write(0x2D, 0x0003); //bit 1 IN2LP_TO_MIXOUTL bit 0 DAC1L_TO_MIXOUTL - wm8994_write(0x2E, 0x0003); //bit 1 IN2RP_TO_MIXOUTR bit 0 DAC1R_TO_MIXOUTL - } - wm8994_write(0x36, 0x000C); //MIXOUTL_TO_SPKMIXL MIXOUTR_TO_SPKMIXR - wm8994_write(0x420, 0x0000); //AIF1DAC1_MUTE = unMUTE - wm8994_write(0x601, 0x0001); //AIF1DAC1L_TO_DAC1L=1 - wm8994_write(0x602, 0x0001); //AIF1DAC1R_TO_DAC1R=1 -//volume -// wm8994_write(0x25, 0x003F); - wm8994_write(0x610, 0x01C0); //DAC1 Left Volume bit0~7 - wm8994_write(0x611, 0x01C0); //DAC1 Right Volume bit0~7 - wm8994_set_channel_vol(); -//other - wm8994_write(0x4C, 0x9F25); -//power - wm8994_write(0x02, 0x6210); - wm8994_write(0x03, 0x1330); - wm8994_write(0x05, 0x0303); - wm8994_write(0x01, 0x3003); - msleep(50); - wm8994_write(0x01, 0x3033); - - wm8994_set_level_volume(); -} +static const struct snd_kcontrol_new sidetone1_mux = + SOC_DAPM_ENUM("Left Sidetone Mux", sidetone1_enum); -void BT_BB(void) -{// - struct wm8994_priv *wm8994 = wm8994_codec->private_data; - DBG("%s::%d\n",__FUNCTION__,__LINE__); - - if(wm8994_current_mode==wm8994_BT_baseband)return; - - wm8994_current_mode=wm8994_BT_baseband; - wm8994_reset(); - msleep(WM8994_DELAY); - - wm8994_write(0x01, 0x0023); - wm8994_write(0x200, 0x0000); - msleep(WM8994_DELAY); -//CLK - //AIF1CLK - wm8994_sysclk_config(); - wm8994_write(0x300, 0xC010); // i2s 16 bits - //AIF2CLK use FLL2 - wm8994_write(0x204, 0x0000); - msleep(WM8994_DELAY); - wm8994_write(0x240, 0x0000); - switch(wm8994->mclk) - { - case 12288000: - wm8994_write(0x241, 0x2F00);//48 - wm8994_write(0x242, 0); - wm8994_write(0x243, 0x0100); - break; - case 11289600: - wm8994_write(0x241, 0x2b00); - wm8994_write(0x242, 0xfb5b); - wm8994_write(0x243, 0x00e0); - break; - case 3072000: - wm8994_write(0x241, 0x2F00);//48 - wm8994_write(0x242, 0); - wm8994_write(0x243, 0x0400); - break; - case 2822400: - wm8994_write(0x241, 0x2b00); - wm8994_write(0x242, 0xed6d); - wm8994_write(0x243, 0x03e0); - break; - default: - printk("wm8994->mclk error = %d\n",wm8994->mclk); - return; - } - - wm8994_write(0x240, 0x0004); - msleep(10); - wm8994_write(0x240, 0x0005); - msleep(5); - wm8994_write(0x204, 0x0018); // SMbus_16inx_16dat Write 0x34 * AIF2 Clocking (1)(204H): 0011 AIF2CLK_SRC=10, AIF2CLK_INV=0, AIF2CLK_DIV=0, AIF2CLK_ENA=1 - wm8994_write(0x208, 0x000E); - wm8994_write(0x211, 0x0003); - - wm8994_write(0x312, 0x3000); // SMbus_16inx_16dat Write 0x34 * AIF2 Master/Slave(312H): 7000 AIF2_TRI=0, AIF2_MSTR=1, AIF2_CLK_FRC=0, AIF2_LRCLK_FRC=0 - msleep(30); - wm8994_write(0x312, 0x7000); - wm8994_write(0x313, 0x0020); // SMbus_16inx_16dat Write 0x34 * AIF2 BCLK DIV--------AIF1CLK/2 - wm8994_write(0x314, 0x0080); // SMbus_16inx_16dat Write 0x34 * AIF2 ADCLRCK DIV-----BCLK/128 - wm8994_write(0x315, 0x0080); - wm8994_write(0x310, 0x0118); //DSP/PCM; 16bits; ADC L channel = R channel;MODE A - - wm8994_write(0x204, 0x0019); // SMbus_16inx_16dat Write 0x34 * AIF2 Clocking (1)(204H): 0011 AIF2CLK_SRC=10, AIF2CLK_INV=0, AIF2CLK_DIV=0, AIF2CLK_ENA=1 -/* - wm8994_write(0x310, 0x0118); - wm8994_write(0x204, 0x0001); - wm8994_write(0x208, 0x000F); - wm8994_write(0x211, 0x0009); - wm8994_write(0x312, 0x7000); - wm8994_write(0x313, 0x00F0); -*/ -//GPIO - wm8994_write(0x702, 0x2100); - wm8994_write(0x703, 0x2100); - wm8994_write(0x704, 0xA100); - wm8994_write(0x707, 0xA100); - wm8994_write(0x708, 0x2100); - wm8994_write(0x709, 0x2100); - wm8994_write(0x70A, 0x2100); - wm8994_write(0x06, 0x000A); -//path - wm8994_write(0x29, 0x0100); - wm8994_write(0x2A, 0x0100); - wm8994_write(0x28, 0x00C0); - wm8994_write(0x24, 0x0009); - wm8994_write(0x29, 0x0130); - wm8994_write(0x2A, 0x0130); - wm8994_write(0x2D, 0x0001); - wm8994_write(0x2E, 0x0001); - wm8994_write(0x34, 0x0001); - wm8994_write(0x36, 0x0004); - wm8994_write(0x601, 0x0004);//AIFDAC -- DAC - wm8994_write(0x602, 0x0001); - wm8994_write(0x603, 0x000C);// - wm8994_write(0x604, 0x0010);//ADC --AIFADC - wm8994_write(0x605, 0x0010); - wm8994_write(0x620, 0x0000); - wm8994_write(0x420, 0x0000); -//DRC&&EQ - wm8994_write(0x440, 0x0018); - wm8994_write(0x450, 0x0018); - wm8994_write(0x540, 0x01BF); //open nosie gate - wm8994_write(0x550, 0x01BF); //open nosie gate - wm8994_write(0x480, 0x0000); - wm8994_write(0x481, 0x0000); - wm8994_write(0x4A0, 0x0000); - wm8994_write(0x4A1, 0x0000); - wm8994_write(0x520, 0x0000); - wm8994_write(0x540, 0x0018); - wm8994_write(0x580, 0x0000); - wm8994_write(0x581, 0x0000); -//volume - wm8994_set_volume(wm8994_current_mode,wm8994->call_vol,call_maxvol); - wm8994_write(0x1E, 0x0006); - wm8994_set_channel_vol(); - wm8994_write(0x22, 0x0000); - wm8994_write(0x23, 0x0100); - wm8994_write(0x610, 0x01C0); - wm8994_write(0x611, 0x01C0); - wm8994_write(0x612, 0x01C0); - wm8994_write(0x613, 0x01C0); -//other - wm8994_write(0x4C, 0x9F25); - wm8994_write(0x60, 0x00EE); - msleep(5); -//power - wm8994_write(0x01, 0x3033); - wm8994_write(0x02, 0x63A0); - wm8994_write(0x03, 0x33F0); - wm8994_write(0x04, 0x3303); - wm8994_write(0x05, 0x3303); -} +static const struct soc_enum sidetone2_enum = + SOC_ENUM_SINGLE(WM8994_SIDETONE, 1, 2, sidetone_text); -/******************PCM BB BEGIN*****************/ -void handsetMIC_to_PCMBB_to_headset(void) //pcmbaseband -{ - DBG("%s::%d\n",__FUNCTION__,__LINE__); - - if(wm8994_current_mode==wm8994_handsetMIC_to_baseband_to_headset)return; - wm8994_current_mode=wm8994_handsetMIC_to_baseband_to_headset; - wm8994_reset(); - msleep(50); -#if 1 - wm8994_write(0x01, 0x0003|wm8994_mic_VCC); //0x0013); - mdelay(50); - - //GPIO configuration - wm8994_write(0x0700, 0xA101); - wm8994_write(0x39, 0x006C); - - //VMID and BIAS - wm8994_write(0x01, 0x0023|wm8994_mic_VCC); //0x0013); - wm8994_write(0x200, 0x0000); - mdelay(50); - wm8994_write(0x200, 0x0001); - - wm8994_write(0x220, 0x0000); - wm8994_write(0x221, 0x0700); //MCLK=12MHz //FLL1 CONTRLO(2) - wm8994_write(0x222, 0xB51E); //0x3126); //FLL1 CONTRLO(3) - wm8994_write(0x223, 0x0100); //FLL1 CONTRLO(4) - wm8994_write(0x220, 0x0004); //FLL1 CONTRLO(1) - //mdelay(50); - mdelay(10); - wm8994_write(0x220, 0x0005); //FLL1 CONTRLO(1) - mdelay(5); - - wm8994_write(0x200, 0x0010); - wm8994_write(0x208, 0x0008); - wm8994_write(0x208, 0x000A); - wm8994_write(0x210, 0x0083); - wm8994_write(0x302, 0x3000); - wm8994_write(0x302, 0x7000); - wm8994_write(0x303, 0x0040); - wm8994_write(0x304, 0x0040); - wm8994_write(0x305, 0x0040); - wm8994_write(0x300, 0x4010); - wm8994_write(0x200, 0x0011); - - //wm8994_write(0x01, 0x3003|wm8994_mic_VCC); - wm8994_write(0x01, 0x0803|wm8994_mic_VCC); - wm8994_write(0x02, 0x0110); - wm8994_write(0x03, 0x00F0); ///0x0330); - wm8994_write(0x04, 0x3003); - wm8994_write(0x05, 0x3003); - wm8994_write(0x1A, 0x0119);//0x015F); - wm8994_write(0x1F, 0x0000); - //wm8994_write(0x22, 0x0000); - //wm8994_write(0x23, 0x0100); ///0x0000); - //wm8994_write(0x25, 0x0152); - wm8994_write(0x28, 0x0003); - wm8994_write(0x2A, 0x0030); - wm8994_write(0x2D, 0x0001); - wm8994_write(0x2E, 0x0001); - wm8994_write(0x33, 0x0018); - //wm8994_write(0x36, 0x000C); //MIXOUTL_TO_SPKMIXL MIXOUTR_TO_SPKMIXR - wm8994_write(0x200, 0x0011); //AIF1 CLOCKING(1) - wm8994_write(0x204, 0x0011); //AIF2 CLOCKING(1) - wm8994_write(0x208, 0x000E);//0x000E); //CLOCKING(1) - wm8994_write(0x520, 0x0000); //AIF2 DAC FILTERS(1) - wm8994_write(0x601, 0x0004); //AIF2DACL_DAC1L - wm8994_write(0x602, 0x0004); //AIF2DACR_DAC1R - - wm8994_write(0x610, 0x01C0); //DAC1 Left Volume bit0~7 - wm8994_write(0x611, 0x01C0); //DAC1 Right Volume bit0~7 - wm8994_write(0x612, 0x01C0); //DAC2 Left Volume bit0~7 - wm8994_write(0x613, 0x01C0); //DAC2 Right Volume bit0~7 - - wm8994_write(0x702, 0xC100); //GPIO3 - wm8994_write(0x703, 0xC100); //GPIO4 - wm8994_write(0x704, 0xC100); //GPIO5 - wm8994_write(0x706, 0x4100); //GPIO7 - wm8994_write(0x204, 0x0011); //AIF2 MCLK=FLL1 - wm8994_write(0x211, 0x0009); //LRCK=8KHz, Rate=MCLK/1536 - #ifdef TD688_MODE - wm8994_write(0x310, 0xc108); ///0x4118); ///interface dsp mode 16bit - #endif - #ifdef CHONGY_MODE - wm8994_write(0x310, 0xc018); ///0x4118); ///interface dsp mode 16bit - #endif - #ifdef MU301_MODE - wm8994_write(0x310, 0xc118); ///0x4118); ///interface dsp mode 16bit - wm8994_write(0x241, 0x2f04); - wm8994_write(0x242, 0x0000); - wm8994_write(0x243, 0x0300); - wm8994_write(0x240, 0x0004); - mdelay(40); - wm8994_write(0x240, 0x0005); - wm8994_write(0x204, 0x0019); - wm8994_write(0x211, 0x0003); - wm8994_write(0x244, 0x0c83); - wm8994_write(0x620, 0x0000); - #endif - #ifdef THINKWILL_M800_MODE - //wm8994_write(0x310, 0x4118); ///0x4118); ///interface dsp mode 16bit - #endif - wm8994_write(0x310, 0x4118); - wm8994_write(0x311, 0x0000); - wm8994_write(0x313, 0x0060); //AIF2BCLK - wm8994_write(0x314, 0x0020); //AIF2ADCLRCK - wm8994_write(0x315, 0x0020); //AIF2DACLRCLK - - wm8994_write(0x603, 0x0180); //Rev.D ADCL SideTone - wm8994_write(0x604, 0x0020); ///0x0010); //ADC2_TO_DAC2L - wm8994_write(0x605, 0x0020); //0x0010); //ADC2_TO_DAC2R - wm8994_write(0x621, 0x0000); ///0x0001); - //wm8994_write(0x317, 0x0003); - //wm8994_write(0x312, 0x0000); //AIF2 SET AS MASTER - - //For handset - wm8994_write(0x01, 0x0B33);//0x3833); // - wm8994_write(0x1C, 0x01F9); - wm8994_write(0x1D, 0x01F9); - wm8994_write(0x4C, 0x9F25); - wm8994_write(0x60, 0x00EE); - - wm8994_write(0x422, 0x0000); ////AIF2 un-mute as master - wm8994_set_level_volume(); - //wm8994_set_volume(wm8994_current_mode,call_vol,call_maxvol); -#endif +static const struct snd_kcontrol_new sidetone2_mux = + SOC_DAPM_ENUM("Right Sidetone Mux", sidetone2_enum); -#if 0 - wm8994_write(0x01, 0x0003|wm8994_mic_VCC); - msleep(50); - wm8994_write(0x221, 0x0700); - wm8994_write(0x222, 0x3127); - wm8994_write(0x223, 0x0100); - wm8994_write(0x220, 0x0004); - msleep(50); - wm8994_write(0x220, 0x0005); - - wm8994_write(0x01, 0x0303|wm8994_mic_VCC); ///0x0303); // sysclk = fll (bit4 =1) 0x0011 - wm8994_write(0x02, 0x0240); - wm8994_write(0x03, 0x0030); - wm8994_write(0x04, 0x3003); - wm8994_write(0x05, 0x3003); // i2s 16 bits - wm8994_write(0x18, 0x010B); - wm8994_write(0x28, 0x0030); - wm8994_write(0x29, 0x0020); - wm8994_write(0x2D, 0x0100); //0x0100);DAC1L_TO_HPOUT1L ;;;bit 8 - wm8994_write(0x2E, 0x0100); //0x0100);DAC1R_TO_HPOUT1R ;;;bit 8 - wm8994_write(0x4C, 0x9F25); - wm8994_write(0x60, 0x00EE); - wm8994_write(0x200, 0x0001); - wm8994_write(0x204, 0x0001); - wm8994_write(0x208, 0x0007); - wm8994_write(0x520, 0x0000); - wm8994_write(0x601, 0x0004); //AIF2DACL_TO_DAC1L - wm8994_write(0x602, 0x0004); //AIF2DACR_TO_DAC1R - - wm8994_write(0x610, 0x01C0); //DAC1 Left Volume bit0~7 - wm8994_write(0x611, 0x01C0); //DAC1 Right Volume bit0~7 - wm8994_write(0x612, 0x01C0); //DAC2 Left Volume bit0~7 - wm8994_write(0x613, 0x01C0); //DAC2 Right Volume bit0~7 - - wm8994_write(0x702, 0xC100); - wm8994_write(0x703, 0xC100); - wm8994_write(0x704, 0xC100); - wm8994_write(0x706, 0x4100); - wm8994_write(0x204, 0x0011); - wm8994_write(0x211, 0x0009); - #ifdef TD688_MODE - wm8994_write(0x310, 0x4108); ///0x4118); ///interface dsp mode 16bit - #endif - #ifdef CHONGY_MODE - wm8994_write(0x310, 0x4118); ///0x4118); ///interface dsp mode 16bit - #endif - #ifdef MU301_MODE - wm8994_write(0x310, 0x4118); ///0x4118); ///interface dsp mode 16bit - wm8994_write(0x241, 0x2f04); - wm8994_write(0x242, 0x0000); - wm8994_write(0x243, 0x0300); - wm8994_write(0x240, 0x0004); - msleep(40); - wm8994_write(0x240, 0x0005); - wm8994_write(0x204, 0x0019); - wm8994_write(0x211, 0x0003); - wm8994_write(0x244, 0x0c83); - wm8994_write(0x620, 0x0000); - #endif - #ifdef THINKWILL_M800_MODE - wm8994_write(0x310, 0x4118); ///0x4118); ///interface dsp mode 16bit - #endif - wm8994_write(0x313, 0x00F0); - wm8994_write(0x314, 0x0020); - wm8994_write(0x315, 0x0020); - wm8994_write(0x603, 0x018c); ///0x000C); //Rev.D ADCL SideTone - wm8994_write(0x604, 0x0010); //XX - wm8994_write(0x605, 0x0010); //XX - wm8994_write(0x621, 0x0000); //0x0001); ///0x0000); - wm8994_write(0x317, 0x0003); - wm8994_write(0x312, 0x0000); /// as slave ///0x4000); //AIF2 SET AS MASTER -#endif +static const char *aif1dac_text[] = { + "AIF1DACDAT", "AIF3DACDAT", +}; -} +static const struct soc_enum aif1dac_enum = + SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 0, 2, aif1dac_text); -void mainMIC_to_PCMBB_to_headset(void) -{ - DBG("%s::%d\n",__FUNCTION__,__LINE__); - - if(wm8994_current_mode==wm8994_mainMIC_to_baseband_to_earpiece)return; - wm8994_current_mode=wm8994_mainMIC_to_baseband_to_earpiece; - wm8994_reset(); - msleep(50); - -#if 1 - wm8994_write(0x01, 0x0003|wm8994_mic_VCC); //0x0013); - mdelay(50); - - //GPIO configuration - wm8994_write(0x0700, 0xA101); - wm8994_write(0x39, 0x006C); - - //VMID and BIAS - wm8994_write(0x01, 0x0023|wm8994_mic_VCC); //0x0013); - wm8994_write(0x200, 0x0000); - mdelay(50); - wm8994_write(0x200, 0x0001); - - wm8994_write(0x220, 0x0000); - wm8994_write(0x221, 0x0700); //MCLK=12MHz //FLL1 CONTRLO(2) - wm8994_write(0x222, 0xB51E); //0x3126); //FLL1 CONTRLO(3) - wm8994_write(0x223, 0x0100); //FLL1 CONTRLO(4) - wm8994_write(0x220, 0x0004); //FLL1 CONTRLO(1) - //mdelay(50); - mdelay(10); - wm8994_write(0x220, 0x0005); //FLL1 CONTRLO(1) - mdelay(5); - - wm8994_write(0x200, 0x0010); - wm8994_write(0x208, 0x0008); - wm8994_write(0x208, 0x000A); - wm8994_write(0x210, 0x0083); - wm8994_write(0x302, 0x3000); - wm8994_write(0x302, 0x7000); - wm8994_write(0x303, 0x0040); - wm8994_write(0x304, 0x0040); - wm8994_write(0x305, 0x0040); - wm8994_write(0x300, 0x4010); - wm8994_write(0x200, 0x0011); - - //wm8994_write(0x01, 0x3003|wm8994_mic_VCC); - wm8994_write(0x01, 0x0803|wm8994_mic_VCC); - wm8994_write(0x02, 0x0110); - wm8994_write(0x03, 0x00F0); ///0x0330); - wm8994_write(0x04, 0x3003); - wm8994_write(0x05, 0x3003); - wm8994_write(0x1A, 0x015F); - wm8994_write(0x1F, 0x0000); - //wm8994_write(0x22, 0x0000); - //wm8994_write(0x23, 0x0100); ///0x0000); - //wm8994_write(0x25, 0x0152); - wm8994_write(0x28, 0x0003); - wm8994_write(0x2A, 0x0030); - wm8994_write(0x2D, 0x0001); - wm8994_write(0x2E, 0x0001); - wm8994_write(0x33, 0x0018); - //wm8994_write(0x36, 0x000C); //MIXOUTL_TO_SPKMIXL MIXOUTR_TO_SPKMIXR - wm8994_write(0x200, 0x0011); //AIF1 CLOCKING(1) - wm8994_write(0x204, 0x0011); //AIF2 CLOCKING(1) - wm8994_write(0x208, 0x000E); //CLOCKING(1) - wm8994_write(0x520, 0x0000); //AIF2 DAC FILTERS(1) - wm8994_write(0x601, 0x0004); //AIF2DACL_DAC1L - wm8994_write(0x602, 0x0004); //AIF2DACR_DAC1R - - wm8994_write(0x610, 0x01C0); //DAC1 Left Volume bit0~7 - wm8994_write(0x611, 0x01C0); //DAC1 Right Volume bit0~7 - wm8994_write(0x612, 0x01C0); //DAC2 Left Volume bit0~7 - wm8994_write(0x613, 0x01C0); //DAC2 Right Volume bit0~7 - - wm8994_write(0x702, 0xC100); //GPIO3 - wm8994_write(0x703, 0xC100); //GPIO4 - wm8994_write(0x704, 0xC100); //GPIO5 - wm8994_write(0x706, 0x4100); //GPIO7 - wm8994_write(0x204, 0x0011); //AIF2 MCLK=FLL1 - wm8994_write(0x211, 0x0009); //LRCK=8KHz, Rate=MCLK/1536 - #ifdef TD688_MODE - wm8994_write(0x310, 0xc108); ///0x4118); ///interface dsp mode 16bit - #endif - #ifdef CHONGY_MODE - wm8994_write(0x310, 0xc018); ///0x4118); ///interface dsp mode 16bit - #endif - #ifdef MU301_MODE - wm8994_write(0x310, 0xc118); ///0x4118); ///interface dsp mode 16bit - wm8994_write(0x241, 0x2f04); - wm8994_write(0x242, 0x0000); - wm8994_write(0x243, 0x0300); - wm8994_write(0x240, 0x0004); - mdelay(40); - wm8994_write(0x240, 0x0005); - wm8994_write(0x204, 0x0019); - wm8994_write(0x211, 0x0003); - wm8994_write(0x244, 0x0c83); - wm8994_write(0x620, 0x0000); - #endif - #ifdef THINKWILL_M800_MODE - //wm8994_write(0x310, 0x4118); ///0x4118); ///interface dsp mode 16bit - #endif - wm8994_write(0x310, 0x4118); - wm8994_write(0x311, 0x0000); - wm8994_write(0x313, 0x0060); //AIF2BCLK - wm8994_write(0x314, 0x0020); //AIF2ADCLRCK - wm8994_write(0x315, 0x0020); //AIF2DACLRCLK - - wm8994_write(0x603, 0x0180); //Rev.D ADCL SideTone - wm8994_write(0x604, 0x0020); ///0x0010); //ADC2_TO_DAC2L - wm8994_write(0x605, 0x0020); //0x0010); //ADC2_TO_DAC2R - wm8994_write(0x621, 0x0000); ///0x0001); - //wm8994_write(0x317, 0x0003); - //wm8994_write(0x312, 0x0000); //AIF2 SET AS MASTER - - //For handset - wm8994_write(0x01, 0x0B33);//0x3833); // - wm8994_write(0x1C, 0x01F9); - wm8994_write(0x1D, 0x01F9); - wm8994_write(0x4C, 0x9F25); - wm8994_write(0x60, 0x00EE); - - wm8994_write(0x422, 0x0000); ////AIF2 un-mute as master - - //wm8994_write(0x312, 0x0000); //AIF2 SET AS MASTER - wm8994_set_level_volume(); - //wm8994_set_volume(wm8994_current_mode,call_vol,call_maxvol); -#endif +static const struct snd_kcontrol_new aif1dac_mux = + SOC_DAPM_ENUM("AIF1DAC Mux", aif1dac_enum); -#if 0 - wm8994_write(0x01, 0x0003|wm8994_mic_VCC); - msleep(50); - wm8994_write(0x221, 0x0700); //MCLK=12MHz - wm8994_write(0x222, 0x3127); - wm8994_write(0x223, 0x0100); - wm8994_write(0x220, 0x0004); - msleep(50); - wm8994_write(0x220, 0x0005); - - wm8994_write(0x01, 0x0803|wm8994_mic_VCC); ///0x0813); - wm8994_write(0x02, 0x0240); ///0x0110); - wm8994_write(0x03, 0x00F0); - wm8994_write(0x04, 0x3003); - wm8994_write(0x05, 0x3003); - wm8994_write(0x18, 0x011F); - wm8994_write(0x1F, 0x0000); - wm8994_write(0x28, 0x0030); ///0x0003); - wm8994_write(0x29, 0x0020); - wm8994_write(0x2D, 0x0001); - wm8994_write(0x2E, 0x0001); - wm8994_write(0x33, 0x0018); - wm8994_write(0x200, 0x0001); - wm8994_write(0x204, 0x0001); - wm8994_write(0x208, 0x0007); - wm8994_write(0x520, 0x0000); - wm8994_write(0x601, 0x0004); - wm8994_write(0x602, 0x0004); - - wm8994_write(0x610, 0x01C0); //DAC1 Left Volume bit0~7 - wm8994_write(0x611, 0x01C0); //DAC1 Right Volume bit0~7 - wm8994_write(0x612, 0x01C0); //DAC2 Left Volume bit0~7 - wm8994_write(0x613, 0x01C0); //DAC2 Right Volume bit0~7 - - wm8994_write(0x702, 0xC100); - wm8994_write(0x703, 0xC100); - wm8994_write(0x704, 0xC100); - wm8994_write(0x706, 0x4100); - wm8994_write(0x204, 0x0011); //AIF2 MCLK=FLL1 - wm8994_write(0x211, 0x0009); //LRCK=8KHz, Rate=MCLK/1536 - #ifdef TD688_MODE - wm8994_write(0x310, 0x4108); ///0x4118); ///interface dsp mode 16bit - #endif - #ifdef CHONGY_MODE - wm8994_write(0x310, 0x4118); ///0x4118); ///interface dsp mode 16bit - #endif - #ifdef MU301_MODE - wm8994_write(0x310, 0x4118); ///0x4118); ///interface dsp mode 16bit - wm8994_write(0x241, 0x2f04); - wm8994_write(0x242, 0x0000); - wm8994_write(0x243, 0x0300); - wm8994_write(0x240, 0x0004); - msleep(40); - wm8994_write(0x240, 0x0005); - wm8994_write(0x204, 0x0019); - wm8994_write(0x211, 0x0003); - wm8994_write(0x244, 0x0c83); - wm8994_write(0x620, 0x0000); - #endif - #ifdef THINKWILL_M800_MODE - wm8994_write(0x310, 0x4118); ///0x4118); ///interface dsp mode 16bit - #endif - wm8994_write(0x313, 0x00F0); - wm8994_write(0x314, 0x0020); - wm8994_write(0x315, 0x0020); - - wm8994_write(0x603, 0x018C); //Rev.D ADCL SideTone - wm8994_write(0x604, 0x0010); - wm8994_write(0x605, 0x0010); - wm8994_write(0x621, 0x0000); ///0x0001); - wm8994_write(0x317, 0x0003); - wm8994_write(0x312, 0x0000); //AIF2 SET AS MASTER -#endif +static const char *aif2dac_text[] = { + "AIF2DACDAT", "AIF3DACDAT", +}; -} +static const struct soc_enum aif2dac_enum = + SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 1, 2, aif2dac_text); -void mainMIC_to_PCMBB_to_earpiece(void) //pcmbaseband -{ - DBG("%s::%d\n",__FUNCTION__,__LINE__); - - if(wm8994_current_mode==wm8994_mainMIC_to_baseband_to_earpiece)return; - wm8994_current_mode=wm8994_mainMIC_to_baseband_to_earpiece; - wm8994_reset(); - msleep(50); - - wm8994_write(0x01, 0x0003|wm8994_mic_VCC); - msleep(50); - wm8994_write(0x221, 0x0700); //MCLK=12MHz - wm8994_write(0x222, 0x3127); - wm8994_write(0x223, 0x0100); - wm8994_write(0x220, 0x0004); - msleep(50); - wm8994_write(0x220, 0x0005); - - wm8994_write(0x01, 0x0803|wm8994_mic_VCC); ///0x0813); - wm8994_write(0x02, 0x0240); ///0x0110); - wm8994_write(0x03, 0x00F0); - wm8994_write(0x04, 0x3003); - wm8994_write(0x05, 0x3003); - wm8994_write(0x18, 0x011F); - wm8994_write(0x1F, 0x0000); - wm8994_write(0x28, 0x0030); ///0x0003); - wm8994_write(0x29, 0x0020); - wm8994_write(0x2D, 0x0001); - wm8994_write(0x2E, 0x0001); - wm8994_write(0x33, 0x0018); - wm8994_write(0x200, 0x0001); - wm8994_write(0x204, 0x0001); - wm8994_write(0x208, 0x0007); - wm8994_write(0x520, 0x0000); - wm8994_write(0x601, 0x0004); - wm8994_write(0x602, 0x0004); - - wm8994_write(0x610, 0x01C0); //DAC1 Left Volume bit0~7 - wm8994_write(0x611, 0x01C0); //DAC1 Right Volume bit0~7 - wm8994_write(0x612, 0x01C0); //DAC2 Left Volume bit0~7 - wm8994_write(0x613, 0x01C0); //DAC2 Right Volume bit0~7 - - wm8994_write(0x702, 0xC100); - wm8994_write(0x703, 0xC100); - wm8994_write(0x704, 0xC100); - wm8994_write(0x706, 0x4100); - wm8994_write(0x204, 0x0011); //AIF2 MCLK=FLL1 - wm8994_write(0x211, 0x0009); //LRCK=8KHz, Rate=MCLK/1536 - #ifdef TD688_MODE - wm8994_write(0x310, 0x4108); ///0x4118); ///interface dsp mode 16bit - #endif - #ifdef CHONGY_MODE - wm8994_write(0x310, 0x4118); ///0x4118); ///interface dsp mode 16bit - #endif - #ifdef MU301_MODE - wm8994_write(0x310, 0x4118); ///0x4118); ///interface dsp mode 16bit - wm8994_write(0x241, 0x2f04); - wm8994_write(0x242, 0x0000); - wm8994_write(0x243, 0x0300); - wm8994_write(0x240, 0x0004); - msleep(40); - wm8994_write(0x240, 0x0005); - wm8994_write(0x204, 0x0019); - wm8994_write(0x211, 0x0003); - wm8994_write(0x244, 0x0c83); - wm8994_write(0x620, 0x0000); - #endif - #ifdef THINKWILL_M800_MODE - wm8994_write(0x310, 0x4118); ///0x4118); ///interface dsp mode 16bit - #endif - wm8994_write(0x313, 0x00F0); - wm8994_write(0x314, 0x0020); - wm8994_write(0x315, 0x0020); - - wm8994_write(0x603, 0x018C); //Rev.D ADCL SideTone - wm8994_write(0x604, 0x0010); - wm8994_write(0x605, 0x0010); - wm8994_write(0x621, 0x0000); ///0x0001); - wm8994_write(0x317, 0x0003); - wm8994_write(0x312, 0x0000); //AIF2 SET AS MASTER - - -} +static const struct snd_kcontrol_new aif2dac_mux = + SOC_DAPM_ENUM("AIF2DAC Mux", aif2dac_enum); -void mainMIC_to_PCMBB_to_speakers(void) //pcmbaseband -{ - DBG("%s::%d\n",__FUNCTION__,__LINE__); - - if(wm8994_current_mode==wm8994_mainMIC_to_baseband_to_speakers)return; - wm8994_current_mode=wm8994_mainMIC_to_baseband_to_speakers; - wm8994_reset(); - msleep(50); - -#if 1 - wm8994_write(0x01, 0x0003|wm8994_mic_VCC); //0x0013); - mdelay(50); - - //GPIO configuration - wm8994_write(0x0700, 0xA101); - wm8994_write(0x39, 0x006C); - - //VMID and BIAS - wm8994_write(0x01, 0x0023|wm8994_mic_VCC); //0x0013); - wm8994_write(0x200, 0x0000); - mdelay(50); - wm8994_write(0x200, 0x0001); - - wm8994_write(0x220, 0x0000); - wm8994_write(0x221, 0x0700); //MCLK=12MHz //FLL1 CONTRLO(2) - wm8994_write(0x222, 0xB51E); //0x3126); //FLL1 CONTRLO(3) - wm8994_write(0x223, 0x0100); //FLL1 CONTRLO(4) - wm8994_write(0x220, 0x0004); //FLL1 CONTRLO(1) - //mdelay(50); - mdelay(10); - wm8994_write(0x220, 0x0005); //FLL1 CONTRLO(1) - mdelay(5); - - wm8994_write(0x200, 0x0010); - wm8994_write(0x208, 0x0008); - wm8994_write(0x208, 0x000A); - wm8994_write(0x210, 0x0083); - wm8994_write(0x302, 0x3000); - wm8994_write(0x302, 0x7000); - wm8994_write(0x303, 0x0040); - wm8994_write(0x304, 0x0040); - wm8994_write(0x305, 0x0040); - wm8994_write(0x300, 0x4010); - wm8994_write(0x200, 0x0011); - - //wm8994_write(0x01, 0x3003|wm8994_mic_VCC); - wm8994_write(0x01, 0x0803|wm8994_mic_VCC); - wm8994_write(0x02, 0x0110); - wm8994_write(0x03, 0x00F0); ///0x0330); - wm8994_write(0x04, 0x3003); - wm8994_write(0x05, 0x3003); - wm8994_write(0x1A, 0x0119);//0x015F); - wm8994_write(0x1F, 0x0000); - //wm8994_write(0x22, 0x0000); - //wm8994_write(0x23, 0x0100); ///0x0000); - //wm8994_write(0x25, 0x0152); - wm8994_write(0x28, 0x0003); - wm8994_write(0x2A, 0x0030); - wm8994_write(0x2D, 0x0001); - wm8994_write(0x2E, 0x0001); - wm8994_write(0x33, 0x0018); - //wm8994_write(0x36, 0x000C); //MIXOUTL_TO_SPKMIXL MIXOUTR_TO_SPKMIXR - wm8994_write(0x200, 0x0011); //AIF1 CLOCKING(1) - wm8994_write(0x204, 0x0011); //AIF2 CLOCKING(1) - wm8994_write(0x208, 0x000E);//0x000E); //CLOCKING(1) - wm8994_write(0x520, 0x0000); //AIF2 DAC FILTERS(1) - wm8994_write(0x601, 0x0004); //AIF2DACL_DAC1L - wm8994_write(0x602, 0x0004); //AIF2DACR_DAC1R - - wm8994_write(0x610, 0x01C0); //DAC1 Left Volume bit0~7 - wm8994_write(0x611, 0x01C0); //DAC1 Right Volume bit0~7 - wm8994_write(0x612, 0x01C0); //DAC2 Left Volume bit0~7 - wm8994_write(0x613, 0x01C0); //DAC2 Right Volume bit0~7 - - wm8994_write(0x702, 0xC100); //GPIO3 - wm8994_write(0x703, 0xC100); //GPIO4 - wm8994_write(0x704, 0xC100); //GPIO5 - wm8994_write(0x706, 0x4100); //GPIO7 - wm8994_write(0x204, 0x0011); //AIF2 MCLK=FLL1 - wm8994_write(0x211, 0x0009); //LRCK=8KHz, Rate=MCLK/1536 - #ifdef TD688_MODE - wm8994_write(0x310, 0xc108); ///0x4118); ///interface dsp mode 16bit - #endif - #ifdef CHONGY_MODE - wm8994_write(0x310, 0xc018); ///0x4118); ///interface dsp mode 16bit - #endif - #ifdef MU301_MODE - wm8994_write(0x310, 0xc118); ///0x4118); ///interface dsp mode 16bit - wm8994_write(0x241, 0x2f04); - wm8994_write(0x242, 0x0000); - wm8994_write(0x243, 0x0300); - wm8994_write(0x240, 0x0004); - mdelay(40); - wm8994_write(0x240, 0x0005); - wm8994_write(0x204, 0x0019); - wm8994_write(0x211, 0x0003); - wm8994_write(0x244, 0x0c83); - wm8994_write(0x620, 0x0000); - #endif - #ifdef THINKWILL_M800_MODE - //wm8994_write(0x310, 0x4118); ///0x4118); ///interface dsp mode 16bit - #endif - wm8994_write(0x310, 0x4118); - wm8994_write(0x311, 0x0000); - wm8994_write(0x313, 0x0060); //AIF2BCLK - wm8994_write(0x314, 0x0020); //AIF2ADCLRCK - wm8994_write(0x315, 0x0020); //AIF2DACLRCLK - - wm8994_write(0x603, 0x0180); //Rev.D ADCL SideTone - wm8994_write(0x604, 0x0020); ///0x0010); //ADC2_TO_DAC2L - wm8994_write(0x605, 0x0020); //0x0010); //ADC2_TO_DAC2R - wm8994_write(0x621, 0x0000); ///0x0001); - //wm8994_write(0x317, 0x0003); - //wm8994_write(0x312, 0x0000); //AIF2 SET AS MASTER - - //For Speaker - wm8994_write(0x01, 0x3833); // - wm8994_write(0x03, 0x03F0); - wm8994_write(0x22, 0x0000); - wm8994_write(0x23, 0x0000); - wm8994_write(0x25, 0x017F); //+12DB 0x15B:4DB - //wm8994_write(0x25, 0x015B); - wm8994_write(0x36, 0x000C); - - wm8994_write(0x422, 0x0000); ////AIF2 un-mute as master - wm8994_set_level_volume(); - //wm8994_set_volume(wm8994_current_mode,call_vol,call_maxvol); -#endif - -#if 0 - wm8994_write(0x01, 0x0003|wm8994_mic_VCC); //0x0013); - msleep(50); - wm8994_write(0x221, 0x0700); //MCLK=12MHz //FLL1 CONTRLO(2) - wm8994_write(0x222, 0x3127); //FLL1 CONTRLO(3) - wm8994_write(0x223, 0x0100); //FLL1 CONTRLO(4) - wm8994_write(0x220, 0x0004); //FLL1 CONTRLO(1) - msleep(50); - wm8994_write(0x220, 0x0005); //FLL1 CONTRLO(1) - - wm8994_write(0x01, 0x3003|wm8994_mic_VCC); - wm8994_write(0x02, 0x0110); - wm8994_write(0x03, 0x0030); ///0x0330); - wm8994_write(0x04, 0x3003); - wm8994_write(0x05, 0x3003); - wm8994_write(0x1A, 0x011F); - wm8994_write(0x22, 0x0000); - wm8994_write(0x23, 0x0100); ///0x0000); - //wm8994_write(0x25, 0x0152); - wm8994_write(0x28, 0x0003); - wm8994_write(0x2A, 0x0020); - wm8994_write(0x2D, 0x0001); - wm8994_write(0x2E, 0x0001); - wm8994_write(0x36, 0x000C); //MIXOUTL_TO_SPKMIXL MIXOUTR_TO_SPKMIXR - wm8994_write(0x200, 0x0001); //AIF1 CLOCKING(1) - wm8994_write(0x204, 0x0001); //AIF2 CLOCKING(1) - wm8994_write(0x208, 0x0007); //CLOCKING(1) - wm8994_write(0x520, 0x0000); //AIF2 DAC FILTERS(1) - wm8994_write(0x601, 0x0004); //AIF2DACL_DAC1L - wm8994_write(0x602, 0x0004); //AIF2DACR_DAC1R - - wm8994_write(0x610, 0x01C0); //DAC1 Left Volume bit0~7 - wm8994_write(0x611, 0x01C0); //DAC1 Right Volume bit0~7 - wm8994_write(0x612, 0x01C0); //DAC2 Left Volume bit0~7 - wm8994_write(0x613, 0x01C0); //DAC2 Right Volume bit0~7 - - wm8994_write(0x702, 0xC100); //GPIO3 - wm8994_write(0x703, 0xC100); //GPIO4 - wm8994_write(0x704, 0xC100); //GPIO5 - wm8994_write(0x706, 0x4100); //GPIO7 - wm8994_write(0x204, 0x0011); //AIF2 MCLK=FLL1 - wm8994_write(0x211, 0x0009); //LRCK=8KHz, Rate=MCLK/1536 - #ifdef TD688_MODE - wm8994_write(0x310, 0xc108); ///0x4118); ///interface dsp mode 16bit - #endif - #ifdef CHONGY_MODE - wm8994_write(0x310, 0xc018); ///0x4118); ///interface dsp mode 16bit - #endif - #ifdef MU301_MODE - wm8994_write(0x310, 0xc118); ///0x4118); ///interface dsp mode 16bit - wm8994_write(0x241, 0x2f04); - wm8994_write(0x242, 0x0000); - wm8994_write(0x243, 0x0300); - wm8994_write(0x240, 0x0004); - msleep(40); - wm8994_write(0x240, 0x0005); - wm8994_write(0x204, 0x0019); - wm8994_write(0x211, 0x0003); - wm8994_write(0x244, 0x0c83); - wm8994_write(0x620, 0x0000); - #endif - #ifdef THINKWILL_M800_MODE - wm8994_write(0x310, 0xc118); ///0x4118); ///interface dsp mode 16bit - #endif - wm8994_write(0x313, 0x00F0); //AIF2BCLK - wm8994_write(0x314, 0x0020); //AIF2ADCLRCK - wm8994_write(0x315, 0x0020); //AIF2DACLRCLK - - wm8994_write(0x603, 0x018C); //Rev.D ADCL SideTone - wm8994_write(0x604, 0x0020); ///0x0010); //ADC2_TO_DAC2L - wm8994_write(0x605, 0x0020); //0x0010); //ADC2_TO_DAC2R - wm8994_write(0x621, 0x0000); ///0x0001); - wm8994_write(0x317, 0x0003); - wm8994_write(0x312, 0x0000); //AIF2 SET AS MASTER -#endif +static const char *aif2adc_text[] = { + "AIF2ADCDAT", "AIF3DACDAT", +}; -} +static const struct soc_enum aif2adc_enum = + SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 2, 2, aif2adc_text); -void BT_PCMBB(void) //pcmbaseband -{ - DBG("%s::%d\n",__FUNCTION__,__LINE__); - - if(wm8994_current_mode==wm8994_BT_baseband)return; - wm8994_current_mode=wm8994_BT_baseband; - wm8994_reset(); - msleep(50); - -#if 1 - wm8994_write(0x01, 0x0003|wm8994_mic_VCC); //0x0013); - mdelay(50); - - //GPIO configuration - wm8994_write(0x0700, 0xA101); - wm8994_write(0x39, 0x006C); - - //VMID and BIAS - wm8994_write(0x01, 0x0023|wm8994_mic_VCC); //0x0013); - wm8994_write(0x200, 0x0000); - mdelay(50); - wm8994_write(0x200, 0x0001); - - wm8994_write(0x220, 0x0000); - wm8994_write(0x221, 0x0700); //MCLK=12MHz //FLL1 CONTRLO(2) - wm8994_write(0x222, 0x3126); //FLL1 CONTRLO(3) - wm8994_write(0x223, 0x0100); //FLL1 CONTRLO(4) - wm8994_write(0x220, 0x0004); //FLL1 CONTRLO(1) - //mdelay(50); - mdelay(10); - wm8994_write(0x220, 0x0005); //FLL1 CONTRLO(1) - mdelay(5); - - wm8994_write(0x200, 0x0010); - wm8994_write(0x208, 0x0008); - wm8994_write(0x208, 0x000A); - wm8994_write(0x210, 0x0083); - wm8994_write(0x302, 0x3000); - wm8994_write(0x302, 0x7000); - wm8994_write(0x303, 0x0040); - wm8994_write(0x304, 0x0040); - wm8994_write(0x305, 0x0040); - wm8994_write(0x300, 0x4010); - wm8994_write(0x200, 0x0011); - - //wm8994_write(0x01, 0x3003|wm8994_mic_VCC); - wm8994_write(0x01, 0x0803|wm8994_mic_VCC); - wm8994_write(0x02, 0x0110); - wm8994_write(0x03, 0x00F0); ///0x0330); - wm8994_write(0x04, 0x3003); - wm8994_write(0x05, 0x3003); - wm8994_write(0x1A, 0x015F);//0x014B); - wm8994_write(0x1F, 0x0000); - //wm8994_write(0x22, 0x0000); - //wm8994_write(0x23, 0x0100); ///0x0000); - //wm8994_write(0x25, 0x0152); - wm8994_write(0x28, 0x0003); - wm8994_write(0x2A, 0x0030); - wm8994_write(0x2D, 0x0001); - wm8994_write(0x2E, 0x0001); - wm8994_write(0x33, 0x0018); - //wm8994_write(0x36, 0x000C); //MIXOUTL_TO_SPKMIXL MIXOUTR_TO_SPKMIXR - wm8994_write(0x200, 0x0011); //AIF1 CLOCKING(1) - wm8994_write(0x204, 0x0011); //AIF2 CLOCKING(1) - wm8994_write(0x208, 0x0007);//0x0007); //CLOCKING(1) - wm8994_write(0x520, 0x0000); //AIF2 DAC FILTERS(1) - wm8994_write(0x601, 0x0004); //AIF2DACL_DAC1L - wm8994_write(0x602, 0x0004); //AIF2DACR_DAC1R - - wm8994_write(0x610, 0x01C0); //DAC1 Left Volume bit0~7 - wm8994_write(0x611, 0x01C0); //DAC1 Right Volume bit0~7 - wm8994_write(0x612, 0x01C0); //DAC2 Left Volume bit0~7 - wm8994_write(0x613, 0x01C0); //DAC2 Right Volume bit0~7 - - wm8994_write(0x702, 0xC100); //GPIO3 - wm8994_write(0x703, 0xC100); //GPIO4 - wm8994_write(0x704, 0xC100); //GPIO5 - wm8994_write(0x706, 0x4100); //GPIO7 - - wm8994_write(0x707, 0xA100); - wm8994_write(0x708, 0xA100); - wm8994_write(0x709, 0xA100); - wm8994_write(0x70A, 0xA100); - wm8994_write(0x06, 0x0014); - - wm8994_write(0x204, 0x0011); //AIF2 MCLK=FLL1 - wm8994_write(0x211, 0x0009); //LRCK=8KHz, Rate=MCLK/1536 - #ifdef TD688_MODE - wm8994_write(0x310, 0xc108); ///0x4118); ///interface dsp mode 16bit - #endif - #ifdef CHONGY_MODE - wm8994_write(0x310, 0xc018); ///0x4118); ///interface dsp mode 16bit - #endif - #ifdef MU301_MODE - wm8994_write(0x310, 0xc118); ///0x4118); ///interface dsp mode 16bit - wm8994_write(0x241, 0x2f04); - wm8994_write(0x242, 0x0000); - wm8994_write(0x243, 0x0300); - wm8994_write(0x240, 0x0004); - mdelay(40); - wm8994_write(0x240, 0x0005); - wm8994_write(0x204, 0x0019); - wm8994_write(0x211, 0x0003); - wm8994_write(0x244, 0x0c83); - wm8994_write(0x620, 0x0000); - #endif - #ifdef THINKWILL_M800_MODE - //wm8994_write(0x310, 0x4118); ///0x4118); ///interface dsp mode 16bit - #endif - wm8994_write(0x310, 0x4118); - wm8994_write(0x311, 0x0000); - wm8994_write(0x313, 0x0060); //AIF2BCLK - wm8994_write(0x314, 0x0020); //AIF2ADCLRCK - wm8994_write(0x315, 0x0020); //AIF2DACLRCLK - - wm8994_write(0x603, 0x0180); //Rev.D ADCL SideTone - wm8994_write(0x604, 0x0020); ///0x0010); //ADC2_TO_DAC2L - wm8994_write(0x605, 0x0020); //0x0010); //ADC2_TO_DAC2R - wm8994_write(0x621, 0x0000); ///0x0001); - //wm8994_write(0x317, 0x0003); - //wm8994_write(0x312, 0x0000); //AIF2 SET AS MASTER - -/* //For Speaker - wm8994_write(0x01, 0x3833); // - wm8994_write(0x03, 0x03F0); - wm8994_write(0x22, 0x0000); - wm8994_write(0x23, 0x0000); - //wm8994_write(0x25, 0x017F); //+12DB 0x15B:4DB - wm8994_write(0x36, 0x000C); -*/ - wm8994_write(0x422, 0x0000); ////AIF2 un-mute as master -#endif +static const struct snd_kcontrol_new aif2adc_mux = + SOC_DAPM_ENUM("AIF2ADC Mux", aif2adc_enum); -#if 0 - wm8994_write(0x01 ,0x0003); - msleep (50); - - wm8994_write(0x200 ,0x0001); - wm8994_write(0x221 ,0x0700);//MCLK=12MHz - wm8994_write(0x222 ,0x3127); - wm8994_write(0x223 ,0x0100); - wm8994_write(0x220 ,0x0004); - msleep (50); - wm8994_write(0x220 ,0x0005); - - wm8994_write(0x02 ,0x0000); - wm8994_write(0x200 ,0x0011);// AIF1 MCLK=FLL1 - wm8994_write(0x210 ,0x0009);// LRCK=8KHz, Rate=MCLK/1536 - wm8994_write(0x300 ,0x4018);// DSP/PCM 16bits - - wm8994_write(0x204 ,0x0011);// AIF2 MCLK=FLL1 - wm8994_write(0x211 ,0x0009);// LRCK=8KHz, Rate=MCLK/1536 - wm8994_write(0x310 ,0x4118);// DSP/PCM 16bits - wm8994_write(0x208 ,0x000F); - -/////AIF1 - wm8994_write(0x700 ,0x8101); -/////AIF2 - wm8994_write(0x702 ,0xC100); - wm8994_write(0x703 ,0xC100); - wm8994_write(0x704 ,0xC100); - wm8994_write(0x706 ,0x4100); -/////AIF3 - wm8994_write(0x707 ,0xA100); - wm8994_write(0x708 ,0xA100); - wm8994_write(0x709 ,0xA100); - wm8994_write(0x70A ,0xA100); - - wm8994_write(0x06 ,0x0001); - - wm8994_write(0x02 ,0x0300); - wm8994_write(0x03 ,0x0030); - wm8994_write(0x04 ,0x3301);//ADCL off - wm8994_write(0x05 ,0x3301);//DACL off - - wm8994_write(0x2A ,0x0005); - - wm8994_write(0x313 ,0x00F0); - wm8994_write(0x314 ,0x0020); - wm8994_write(0x315 ,0x0020); - - wm8994_write(0x2E ,0x0001); - wm8994_write(0x420 ,0x0000); - wm8994_write(0x520 ,0x0000); - wm8994_write(0x601 ,0x0001); - wm8994_write(0x602 ,0x0001); - wm8994_write(0x604 ,0x0001); - wm8994_write(0x605 ,0x0001); - wm8994_write(0x607 ,0x0002); - wm8994_write(0x611, 0x01C0); //DAC1 Right Volume bit0~7 - wm8994_write(0x612, 0x01C0); //DAC2 Left Volume bit0~7 - wm8994_write(0x613, 0x01C0); //DAC2 Right Volume bit0~7 - - - wm8994_write(0x312 ,0x4000); - - wm8994_write(0x606 ,0x0001); - wm8994_write(0x607 ,0x0003);//R channel for data mix/CPU record data - - -////////////HP output test - wm8994_write(0x01 ,0x0303); - wm8994_write(0x4C ,0x9F25); - wm8994_write(0x60 ,0x00EE); -///////////end HP test -#endif -} +static const char *aif3adc_text[] = { + "AIF1ADCDAT", "AIF2ADCDAT", "AIF2DACDAT", +}; -#define SOC_DOUBLE_SWITCH_WM8994CODEC(xname, route) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ - .info = snd_soc_info_route, \ - .get = snd_soc_get_route, .put = snd_soc_put_route, \ - .private_value = route } +static const struct soc_enum aif3adc_enum = + SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 3, 3, aif3adc_text); + +static const struct snd_kcontrol_new aif3adc_mux = + SOC_DAPM_ENUM("AIF3ADC Mux", aif3adc_enum); + +static const struct snd_soc_dapm_widget wm8994_dapm_widgets[] = { +SND_SOC_DAPM_INPUT("DMIC1DAT"), +SND_SOC_DAPM_INPUT("DMIC2DAT"), +SND_SOC_DAPM_INPUT("Clock"), + +SND_SOC_DAPM_SUPPLY("CLK_SYS", SND_SOC_NOPM, 0, 0, clk_sys_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + +SND_SOC_DAPM_SUPPLY("DSP1CLK", WM8994_CLOCKING_1, 3, 0, NULL, 0), +SND_SOC_DAPM_SUPPLY("DSP2CLK", WM8994_CLOCKING_1, 2, 0, NULL, 0), +SND_SOC_DAPM_SUPPLY("DSPINTCLK", WM8994_CLOCKING_1, 1, 0, NULL, 0), + +SND_SOC_DAPM_SUPPLY("AIF1CLK", WM8994_AIF1_CLOCKING_1, 0, 0, NULL, 0), +SND_SOC_DAPM_SUPPLY("AIF2CLK", WM8994_AIF2_CLOCKING_1, 0, 0, NULL, 0), + +SND_SOC_DAPM_AIF_OUT("AIF1ADC1L", "AIF1 Capture", + 0, WM8994_POWER_MANAGEMENT_4, 9, 0), +SND_SOC_DAPM_AIF_OUT("AIF1ADC1R", "AIF1 Capture", + 0, WM8994_POWER_MANAGEMENT_4, 8, 0), +SND_SOC_DAPM_AIF_IN("AIF1DAC1L", NULL, 0, + WM8994_POWER_MANAGEMENT_5, 9, 0), +SND_SOC_DAPM_AIF_IN("AIF1DAC1R", NULL, 0, + WM8994_POWER_MANAGEMENT_5, 8, 0), + +SND_SOC_DAPM_AIF_OUT("AIF1ADC2L", "AIF1 Capture", + 0, WM8994_POWER_MANAGEMENT_4, 11, 0), +SND_SOC_DAPM_AIF_OUT("AIF1ADC2R", "AIF1 Capture", + 0, WM8994_POWER_MANAGEMENT_4, 10, 0), +SND_SOC_DAPM_AIF_IN("AIF1DAC2L", NULL, 0, + WM8994_POWER_MANAGEMENT_5, 11, 0), +SND_SOC_DAPM_AIF_IN("AIF1DAC2R", NULL, 0, + WM8994_POWER_MANAGEMENT_5, 10, 0), + +SND_SOC_DAPM_MIXER("AIF1ADC1L Mixer", SND_SOC_NOPM, 0, 0, + aif1adc1l_mix, ARRAY_SIZE(aif1adc1l_mix)), +SND_SOC_DAPM_MIXER("AIF1ADC1R Mixer", SND_SOC_NOPM, 0, 0, + aif1adc1r_mix, ARRAY_SIZE(aif1adc1r_mix)), + +SND_SOC_DAPM_MIXER("AIF1ADC2L Mixer", SND_SOC_NOPM, 0, 0, + aif1adc2l_mix, ARRAY_SIZE(aif1adc2l_mix)), +SND_SOC_DAPM_MIXER("AIF1ADC2R Mixer", SND_SOC_NOPM, 0, 0, + aif1adc2r_mix, ARRAY_SIZE(aif1adc2r_mix)), + +SND_SOC_DAPM_MIXER("AIF2DAC2L Mixer", SND_SOC_NOPM, 0, 0, + aif2dac2l_mix, ARRAY_SIZE(aif2dac2l_mix)), +SND_SOC_DAPM_MIXER("AIF2DAC2R Mixer", SND_SOC_NOPM, 0, 0, + aif2dac2r_mix, ARRAY_SIZE(aif2dac2r_mix)), + +SND_SOC_DAPM_MUX("Left Sidetone", SND_SOC_NOPM, 0, 0, &sidetone1_mux), +SND_SOC_DAPM_MUX("Right Sidetone", SND_SOC_NOPM, 0, 0, &sidetone2_mux), + +SND_SOC_DAPM_MIXER("DAC1L Mixer", SND_SOC_NOPM, 0, 0, + dac1l_mix, ARRAY_SIZE(dac1l_mix)), +SND_SOC_DAPM_MIXER("DAC1R Mixer", SND_SOC_NOPM, 0, 0, + dac1r_mix, ARRAY_SIZE(dac1r_mix)), + +SND_SOC_DAPM_AIF_OUT("AIF2ADCL", NULL, 0, + WM8994_POWER_MANAGEMENT_4, 13, 0), +SND_SOC_DAPM_AIF_OUT("AIF2ADCR", NULL, 0, + WM8994_POWER_MANAGEMENT_4, 12, 0), +SND_SOC_DAPM_AIF_IN("AIF2DACL", NULL, 0, + WM8994_POWER_MANAGEMENT_5, 13, 0), +SND_SOC_DAPM_AIF_IN("AIF2DACR", NULL, 0, + WM8994_POWER_MANAGEMENT_5, 12, 0), + +SND_SOC_DAPM_AIF_IN("AIF1DACDAT", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), +SND_SOC_DAPM_AIF_IN("AIF2DACDAT", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0), +SND_SOC_DAPM_AIF_OUT("AIF2ADCDAT", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0), + +SND_SOC_DAPM_MUX("AIF1DAC Mux", SND_SOC_NOPM, 0, 0, &aif1dac_mux), +SND_SOC_DAPM_MUX("AIF2DAC Mux", SND_SOC_NOPM, 0, 0, &aif2dac_mux), +SND_SOC_DAPM_MUX("AIF2ADC Mux", SND_SOC_NOPM, 0, 0, &aif2adc_mux), +SND_SOC_DAPM_MUX("AIF3ADC Mux", SND_SOC_NOPM, 0, 0, &aif3adc_mux), + +SND_SOC_DAPM_AIF_IN("AIF3DACDAT", "AIF3 Playback", 0, SND_SOC_NOPM, 0, 0), +SND_SOC_DAPM_AIF_IN("AIF3ADCDAT", "AIF3 Capture", 0, SND_SOC_NOPM, 0, 0), + +SND_SOC_DAPM_SUPPLY("TOCLK", WM8994_CLOCKING_1, 4, 0, NULL, 0), + +SND_SOC_DAPM_ADC("DMIC2L", NULL, WM8994_POWER_MANAGEMENT_4, 5, 0), +SND_SOC_DAPM_ADC("DMIC2R", NULL, WM8994_POWER_MANAGEMENT_4, 4, 0), +SND_SOC_DAPM_ADC("DMIC1L", NULL, WM8994_POWER_MANAGEMENT_4, 3, 0), +SND_SOC_DAPM_ADC("DMIC1R", NULL, WM8994_POWER_MANAGEMENT_4, 2, 0), + +/* Power is done with the muxes since the ADC power also controls the + * downsampling chain, the chip will automatically manage the analogue + * specific portions. + */ +SND_SOC_DAPM_ADC("ADCL", NULL, SND_SOC_NOPM, 1, 0), +SND_SOC_DAPM_ADC("ADCR", NULL, SND_SOC_NOPM, 0, 0), -int snd_soc_info_route(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; +SND_SOC_DAPM_MUX("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux), +SND_SOC_DAPM_MUX("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux), - uinfo->count = 1; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 0; - return 0; -} +SND_SOC_DAPM_DAC("DAC2L", NULL, WM8994_POWER_MANAGEMENT_5, 3, 0), +SND_SOC_DAPM_DAC("DAC2R", NULL, WM8994_POWER_MANAGEMENT_5, 2, 0), +SND_SOC_DAPM_DAC("DAC1L", NULL, WM8994_POWER_MANAGEMENT_5, 1, 0), +SND_SOC_DAPM_DAC("DAC1R", NULL, WM8994_POWER_MANAGEMENT_5, 0, 0), -int snd_soc_get_route(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - return 0; -} +SND_SOC_DAPM_MUX("Left Headphone Mux", SND_SOC_NOPM, 0, 0, &hpl_mux), +SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0, &hpr_mux), + +SND_SOC_DAPM_MIXER("SPKL", WM8994_POWER_MANAGEMENT_3, 8, 0, + left_speaker_mixer, ARRAY_SIZE(left_speaker_mixer)), +SND_SOC_DAPM_MIXER("SPKR", WM8994_POWER_MANAGEMENT_3, 9, 0, + right_speaker_mixer, ARRAY_SIZE(right_speaker_mixer)), + +SND_SOC_DAPM_POST("Debug log", post_ev), +}; + +static const struct snd_soc_dapm_route intercon[] = { + + { "CLK_SYS", NULL, "AIF1CLK", check_clk_sys }, + { "CLK_SYS", NULL, "AIF2CLK", check_clk_sys }, + + { "DSP1CLK", NULL, "CLK_SYS" }, + { "DSP2CLK", NULL, "CLK_SYS" }, + { "DSPINTCLK", NULL, "CLK_SYS" }, + + { "AIF1ADC1L", NULL, "AIF1CLK" }, + { "AIF1ADC1L", NULL, "DSP1CLK" }, + { "AIF1ADC1R", NULL, "AIF1CLK" }, + { "AIF1ADC1R", NULL, "DSP1CLK" }, + { "AIF1ADC1R", NULL, "DSPINTCLK" }, + + { "AIF1DAC1L", NULL, "AIF1CLK" }, + { "AIF1DAC1L", NULL, "DSP1CLK" }, + { "AIF1DAC1R", NULL, "AIF1CLK" }, + { "AIF1DAC1R", NULL, "DSP1CLK" }, + { "AIF1DAC1R", NULL, "DSPINTCLK" }, + + { "AIF1ADC2L", NULL, "AIF1CLK" }, + { "AIF1ADC2L", NULL, "DSP1CLK" }, + { "AIF1ADC2R", NULL, "AIF1CLK" }, + { "AIF1ADC2R", NULL, "DSP1CLK" }, + { "AIF1ADC2R", NULL, "DSPINTCLK" }, + + { "AIF1DAC2L", NULL, "AIF1CLK" }, + { "AIF1DAC2L", NULL, "DSP1CLK" }, + { "AIF1DAC2R", NULL, "AIF1CLK" }, + { "AIF1DAC2R", NULL, "DSP1CLK" }, + { "AIF1DAC2R", NULL, "DSPINTCLK" }, + + { "AIF2ADCL", NULL, "AIF2CLK" }, + { "AIF2ADCL", NULL, "DSP2CLK" }, + { "AIF2ADCR", NULL, "AIF2CLK" }, + { "AIF2ADCR", NULL, "DSP2CLK" }, + { "AIF2ADCR", NULL, "DSPINTCLK" }, + + { "AIF2DACL", NULL, "AIF2CLK" }, + { "AIF2DACL", NULL, "DSP2CLK" }, + { "AIF2DACR", NULL, "AIF2CLK" }, + { "AIF2DACR", NULL, "DSP2CLK" }, + { "AIF2DACR", NULL, "DSPINTCLK" }, + + { "DMIC1L", NULL, "DMIC1DAT" }, + { "DMIC1L", NULL, "CLK_SYS" }, + { "DMIC1R", NULL, "DMIC1DAT" }, + { "DMIC1R", NULL, "CLK_SYS" }, + { "DMIC2L", NULL, "DMIC2DAT" }, + { "DMIC2L", NULL, "CLK_SYS" }, + { "DMIC2R", NULL, "DMIC2DAT" }, + { "DMIC2R", NULL, "CLK_SYS" }, + + { "ADCL", NULL, "AIF1CLK" }, + { "ADCL", NULL, "DSP1CLK" }, + { "ADCL", NULL, "DSPINTCLK" }, + + { "ADCR", NULL, "AIF1CLK" }, + { "ADCR", NULL, "DSP1CLK" }, + { "ADCR", NULL, "DSPINTCLK" }, + + { "ADCL Mux", "ADC", "ADCL" }, + { "ADCL Mux", "DMIC", "DMIC1L" }, + { "ADCR Mux", "ADC", "ADCR" }, + { "ADCR Mux", "DMIC", "DMIC1R" }, + + { "DAC1L", NULL, "AIF1CLK" }, + { "DAC1L", NULL, "DSP1CLK" }, + { "DAC1L", NULL, "DSPINTCLK" }, + + { "DAC1R", NULL, "AIF1CLK" }, + { "DAC1R", NULL, "DSP1CLK" }, + { "DAC1R", NULL, "DSPINTCLK" }, + + { "DAC2L", NULL, "AIF2CLK" }, + { "DAC2L", NULL, "DSP2CLK" }, + { "DAC2L", NULL, "DSPINTCLK" }, + + { "DAC2R", NULL, "AIF2DACR" }, + { "DAC2R", NULL, "AIF2CLK" }, + { "DAC2R", NULL, "DSP2CLK" }, + { "DAC2R", NULL, "DSPINTCLK" }, + + { "TOCLK", NULL, "CLK_SYS" }, + + /* AIF1 outputs */ + { "AIF1ADC1L", NULL, "AIF1ADC1L Mixer" }, + { "AIF1ADC1L Mixer", "ADC/DMIC Switch", "ADCL Mux" }, + { "AIF1ADC1L Mixer", "AIF2 Switch", "AIF2DACL" }, + + { "AIF1ADC1R", NULL, "AIF1ADC1R Mixer" }, + { "AIF1ADC1R Mixer", "ADC/DMIC Switch", "ADCR Mux" }, + { "AIF1ADC1R Mixer", "AIF2 Switch", "AIF2DACR" }, + + { "AIF1ADC2L", NULL, "AIF1ADC2L Mixer" }, + { "AIF1ADC2L Mixer", "DMIC Switch", "DMIC2L" }, + { "AIF1ADC2L Mixer", "AIF2 Switch", "AIF2DACL" }, + + { "AIF1ADC2R", NULL, "AIF1ADC2R Mixer" }, + { "AIF1ADC2R Mixer", "DMIC Switch", "DMIC2R" }, + { "AIF1ADC2R Mixer", "AIF2 Switch", "AIF2DACR" }, + + /* Pin level routing for AIF3 */ + { "AIF1DAC1L", NULL, "AIF1DAC Mux" }, + { "AIF1DAC1R", NULL, "AIF1DAC Mux" }, + { "AIF1DAC2L", NULL, "AIF1DAC Mux" }, + { "AIF1DAC2R", NULL, "AIF1DAC Mux" }, + + { "AIF2DACL", NULL, "AIF2DAC Mux" }, + { "AIF2DACR", NULL, "AIF2DAC Mux" }, + + { "AIF1DAC Mux", "AIF1DACDAT", "AIF1DACDAT" }, + { "AIF1DAC Mux", "AIF3DACDAT", "AIF3DACDAT" }, + { "AIF2DAC Mux", "AIF2DACDAT", "AIF2DACDAT" }, + { "AIF2DAC Mux", "AIF3DACDAT", "AIF3DACDAT" }, + { "AIF2ADC Mux", "AIF2ADCDAT", "AIF2ADCL" }, + { "AIF2ADC Mux", "AIF2ADCDAT", "AIF2ADCR" }, + { "AIF2ADC Mux", "AIF3DACDAT", "AIF3ADCDAT" }, + + /* DAC1 inputs */ + { "DAC1L", NULL, "DAC1L Mixer" }, + { "DAC1L Mixer", "AIF2 Switch", "AIF2DACL" }, + { "DAC1L Mixer", "AIF1.2 Switch", "AIF1DAC2L" }, + { "DAC1L Mixer", "AIF1.1 Switch", "AIF1DAC1L" }, + { "DAC1L Mixer", "Left Sidetone Switch", "Left Sidetone" }, + { "DAC1L Mixer", "Right Sidetone Switch", "Right Sidetone" }, + + { "DAC1R", NULL, "DAC1R Mixer" }, + { "DAC1R Mixer", "AIF2 Switch", "AIF2DACR" }, + { "DAC1R Mixer", "AIF1.2 Switch", "AIF1DAC2R" }, + { "DAC1R Mixer", "AIF1.1 Switch", "AIF1DAC1R" }, + { "DAC1R Mixer", "Left Sidetone Switch", "Left Sidetone" }, + { "DAC1R Mixer", "Right Sidetone Switch", "Right Sidetone" }, + + /* DAC2/AIF2 outputs */ + { "AIF2ADCL", NULL, "AIF2DAC2L Mixer" }, + { "DAC2L", NULL, "AIF2DAC2L Mixer" }, + { "AIF2DAC2L Mixer", "AIF2 Switch", "AIF2DACL" }, + { "AIF2DAC2L Mixer", "AIF1.2 Switch", "AIF1DAC2L" }, + { "AIF2DAC2L Mixer", "AIF1.1 Switch", "AIF1DAC1L" }, + { "AIF2DAC2L Mixer", "Left Sidetone Switch", "Left Sidetone" }, + { "AIF2DAC2L Mixer", "Right Sidetone Switch", "Right Sidetone" }, + + { "AIF2ADCR", NULL, "AIF2DAC2R Mixer" }, + { "DAC2R", NULL, "AIF2DAC2R Mixer" }, + { "AIF2DAC2R Mixer", "AIF2 Switch", "AIF2DACR" }, + { "AIF2DAC2R Mixer", "AIF1.2 Switch", "AIF1DAC2R" }, + { "AIF2DAC2R Mixer", "AIF1.1 Switch", "AIF1DAC1R" }, + { "AIF2DAC2R Mixer", "Left Sidetone Switch", "Left Sidetone" }, + { "AIF2DAC2R Mixer", "Right Sidetone Switch", "Right Sidetone" }, + + { "AIF2ADCDAT", NULL, "AIF2ADC Mux" }, + + /* AIF3 output */ + { "AIF3ADCDAT", "AIF1ADCDAT", "AIF1ADC1L" }, + { "AIF3ADCDAT", "AIF1ADCDAT", "AIF1ADC1R" }, + { "AIF3ADCDAT", "AIF1ADCDAT", "AIF1ADC2L" }, + { "AIF3ADCDAT", "AIF1ADCDAT", "AIF1ADC2R" }, + { "AIF3ADCDAT", "AIF2ADCDAT", "AIF2ADCL" }, + { "AIF3ADCDAT", "AIF2ADCDAT", "AIF2ADCR" }, + { "AIF3ADCDAT", "AIF2DACDAT", "AIF2DACL" }, + { "AIF3ADCDAT", "AIF2DACDAT", "AIF2DACR" }, + + /* Sidetone */ + { "Left Sidetone", "ADC/DMIC1", "ADCL Mux" }, + { "Left Sidetone", "DMIC2", "DMIC2L" }, + { "Right Sidetone", "ADC/DMIC1", "ADCR Mux" }, + { "Right Sidetone", "DMIC2", "DMIC2R" }, + + /* Output stages */ + { "Left Output Mixer", "DAC Switch", "DAC1L" }, + { "Right Output Mixer", "DAC Switch", "DAC1R" }, + + { "SPKL", "DAC1 Switch", "DAC1L" }, + { "SPKL", "DAC2 Switch", "DAC2L" }, + + { "SPKR", "DAC1 Switch", "DAC1R" }, + { "SPKR", "DAC2 Switch", "DAC2R" }, + + { "Left Headphone Mux", "DAC", "DAC1L" }, + { "Right Headphone Mux", "DAC", "DAC1R" }, +}; + +/* The size in bits of the FLL divide multiplied by 10 + * to allow rounding later */ +#define FIXED_FLL_SIZE ((1 << 16) * 10) + +struct fll_div { + u16 outdiv; + u16 n; + u16 k; + u16 clk_ref_div; + u16 fll_fratio; +}; -int snd_soc_put_route(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) +static int wm8994_get_fll_config(struct fll_div *fll, + int freq_in, int freq_out) { - struct wm8994_priv *wm8994 = wm8994_codec->private_data; - struct wm8994_pdata *pdata = wm8994->pdata; - char route = kcontrol->private_value & 0xff; - char last_route = wm8994->kcontrol.private_value & 0xff; - wake_lock(&wm8994->wm8994_on_wake); - mutex_lock(&wm8994->route_lock); - wm8994->kcontrol.private_value = route;//save rount - wm8994->route_status = BUSY; - //before set the route -- disable PA - switch(route) - { - case MIC_CAPTURE: - break; - default: - PA_ctrl(GPIO_LOW); - break; - } + u64 Kpart; + unsigned int K, Ndiv, Nmod; - //set rount - switch(route) - { - case SPEAKER_NORMAL: //AP-> 8994Codec -> Speaker - case SPEAKER_RINGTONE: - case EARPIECE_RINGTONE: - if(pdata->sp_hp_same_channel == 1) - AP_to_headset(); - else - AP_to_speakers(); - break; - case SPEAKER_INCALL: //BB-> 8994Codec -> Speaker - if(pdata->sp_hp_same_channel == 1) - mainMIC_to_baseband_to_headset(); - else - mainMIC_to_baseband_to_speakers(); - break; - case HEADSET_NORMAL: //AP-> 8994Codec -> Headset - AP_to_headset(); - break; - case HEADSET_INCALL: //AP-> 8994Codec -> Headset -#ifdef CONFIG_RK_HEADSET_DET - if(Headset_isMic()) - handsetMIC_to_baseband_to_headset(); - else -#endif - mainMIC_to_baseband_to_headset(); - break; - case EARPIECE_INCALL: //BB-> 8994Codec -> EARPIECE - if(pdata->no_earpiece == 1){ - if(pdata->sp_hp_same_channel == 1) - mainMIC_to_baseband_to_headset(); - else - mainMIC_to_baseband_to_speakers(); - } - else - mainMIC_to_baseband_to_earpiece(); - break; - case EARPIECE_NORMAL: //BB-> 8994Codec -> EARPIECE - switch(wm8994_current_mode) - { - case wm8994_handsetMIC_to_baseband_to_headset: - case wm8994_mainMIC_to_baseband_to_headset: - AP_to_headset(); - break; - default: - if(pdata->sp_hp_same_channel == 1) - AP_to_headset(); - else - AP_to_speakers(); - break; - } - break; - case BLUETOOTH_SCO_INCALL: //BB-> 8994Codec -> BLUETOOTH_SCO - BT_baseband(); - break; - case MIC_CAPTURE: - recorder_add(); - break; - case HEADSET_RINGTONE: - AP_to_speakers_and_headset(); - break; - case BLUETOOTH_A2DP_NORMAL: //AP-> 8994Codec -> BLUETOOTH_A2DP - case BLUETOOTH_A2DP_INCALL: - case BLUETOOTH_SCO_NORMAL: - printk("this route not use\n"); - break; - default: - printk("wm8994 error route!!!\n"); - goto out; - } - - switch(last_route) - { - case MIC_CAPTURE: - recorder_add(); - break; - default: - break; + pr_debug("FLL input=%dHz, output=%dHz\n", freq_in, freq_out); + + /* Scale the input frequency down to <= 13.5MHz */ + fll->clk_ref_div = 0; + while (freq_in > 13500000) { + fll->clk_ref_div++; + freq_in /= 2; + + if (fll->clk_ref_div > 3) + return -EINVAL; } - - if(wm8994->RW_status == ERROR) - {//Failure to read or write, will reset wm8994 - cancel_delayed_work_sync(&wm8994->wm8994_delayed_work); - wm8994->work_type = SNDRV_PCM_TRIGGER_PAUSE_PUSH; - schedule_delayed_work(&wm8994->wm8994_delayed_work, msecs_to_jiffies(10)); - goto out; + pr_debug("CLK_REF_DIV=%d, Fref=%dHz\n", fll->clk_ref_div, freq_in); + + /* Scale the output to give 90MHz<=Fvco<=100MHz */ + fll->outdiv = 3; + while (freq_out * (fll->outdiv + 1) < 90000000) { + fll->outdiv++; + if (fll->outdiv > 63) + return -EINVAL; } - //after set the route -- enable PA - switch(route) - { - case EARPIECE_NORMAL: - if(wm8994_current_mode == wm8994_handsetMIC_to_baseband_to_headset|| - wm8994_current_mode == wm8994_mainMIC_to_baseband_to_headset) - break; - case SPEAKER_NORMAL: - case SPEAKER_RINGTONE: - case SPEAKER_INCALL: - case EARPIECE_RINGTONE: - case HEADSET_RINGTONE: - msleep(50); - PA_ctrl(GPIO_HIGH); - break; - case EARPIECE_INCALL: - if(pdata->no_earpiece == 1) - { - msleep(50); - PA_ctrl(GPIO_HIGH); - } - break; - default: - break; + freq_out *= fll->outdiv + 1; + pr_debug("OUTDIV=%d, Fvco=%dHz\n", fll->outdiv, freq_out); + + if (freq_in > 1000000) { + fll->fll_fratio = 0; + } else if (freq_in > 256000) { + fll->fll_fratio = 1; + freq_in *= 2; + } else if (freq_in > 128000) { + fll->fll_fratio = 2; + freq_in *= 4; + } else if (freq_in > 64000) { + fll->fll_fratio = 3; + freq_in *= 8; + } else { + fll->fll_fratio = 4; + freq_in *= 16; } -out: - wm8994->route_status = IDLE; - mutex_unlock(&wm8994->route_lock); - wake_unlock(&wm8994->wm8994_on_wake); - return 0; -} + pr_debug("FLL_FRATIO=%d, Fref=%dHz\n", fll->fll_fratio, freq_in); -/* - * WM8994 Controls - */ -static const struct snd_kcontrol_new wm8994_snd_controls[] = { -SOC_DOUBLE_SWITCH_WM8994CODEC("Speaker incall Switch", SPEAKER_INCALL), -SOC_DOUBLE_SWITCH_WM8994CODEC("Speaker normal Switch", SPEAKER_NORMAL), + /* Now, calculate N.K */ + Ndiv = freq_out / freq_in; + + fll->n = Ndiv; + Nmod = freq_out % freq_in; + pr_debug("Nmod=%d\n", Nmod); + + /* Calculate fractional part - scale up so we can round. */ + Kpart = FIXED_FLL_SIZE * (long long)Nmod; -SOC_DOUBLE_SWITCH_WM8994CODEC("Earpiece incall Switch", EARPIECE_INCALL), -SOC_DOUBLE_SWITCH_WM8994CODEC("Earpiece normal Switch", EARPIECE_NORMAL), + do_div(Kpart, freq_in); -SOC_DOUBLE_SWITCH_WM8994CODEC("Headset incall Switch", HEADSET_INCALL), -SOC_DOUBLE_SWITCH_WM8994CODEC("Headset normal Switch", HEADSET_NORMAL), + K = Kpart & 0xFFFFFFFF; -SOC_DOUBLE_SWITCH_WM8994CODEC("Bluetooth incall Switch", BLUETOOTH_SCO_INCALL), -SOC_DOUBLE_SWITCH_WM8994CODEC("Bluetooth normal Switch", BLUETOOTH_SCO_NORMAL), + if ((K % 10) >= 5) + K += 5; -SOC_DOUBLE_SWITCH_WM8994CODEC("Bluetooth-A2DP incall Switch", BLUETOOTH_A2DP_INCALL), -SOC_DOUBLE_SWITCH_WM8994CODEC("Bluetooth-A2DP normal Switch", BLUETOOTH_A2DP_NORMAL), + /* Move down to proper range now rounding is done */ + fll->k = K / 10; -SOC_DOUBLE_SWITCH_WM8994CODEC("Capture Switch", MIC_CAPTURE), + pr_debug("N=%x K=%x\n", fll->n, fll->k); -SOC_DOUBLE_SWITCH_WM8994CODEC("Earpiece ringtone Switch",EARPIECE_RINGTONE), -SOC_DOUBLE_SWITCH_WM8994CODEC("Speaker ringtone Switch",SPEAKER_RINGTONE), -SOC_DOUBLE_SWITCH_WM8994CODEC("Headset ringtone Switch",HEADSET_RINGTONE), -}; + return 0; +} -static void wm8994_codec_set_volume(unsigned char system_type,unsigned char volume) +static int wm8994_set_fll(struct snd_soc_dai *dai, int id, int src, + unsigned int freq_in, unsigned int freq_out) { - struct wm8994_priv *wm8994 = wm8994_codec->private_data; -// DBG("%s:: system_type = %d volume = %d \n",__FUNCTION__,system_type,volume); + struct snd_soc_codec *codec = dai->codec; + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + int reg_offset, ret; + struct fll_div fll; + u16 reg, aif1, aif2; - if(system_type == VOICE_CALL) - { - if(volume <= call_maxvol) - wm8994->call_vol=volume; - else - { - printk("%s----%d::max value is 5\n",__FUNCTION__,__LINE__); - wm8994->call_vol=call_maxvol; - } - if(wm8994_current_mode == wm8994_handsetMIC_to_baseband_to_headset || - wm8994_current_mode == wm8994_mainMIC_to_baseband_to_headset || - wm8994_current_mode == wm8994_mainMIC_to_baseband_to_earpiece|| - wm8994_current_mode == wm8994_mainMIC_to_baseband_to_speakers) - wm8994_set_volume(wm8994_current_mode,wm8994->call_vol,call_maxvol); + aif1 = snd_soc_read(codec, WM8994_AIF1_CLOCKING_1) + & WM8994_AIF1CLK_ENA; + + aif2 = snd_soc_read(codec, WM8994_AIF2_CLOCKING_1) + & WM8994_AIF2CLK_ENA; + + switch (id) { + case WM8994_FLL1: + reg_offset = 0; + id = 0; + break; + case WM8994_FLL2: + reg_offset = 0x20; + id = 1; + break; + default: + return -EINVAL; } - else if(system_type == BLUETOOTH_SCO) - { - if(volume <= BT_call_maxvol) - wm8994->BT_call_vol = volume; - else - { - printk("%s----%d::max value is 15\n",__FUNCTION__,__LINE__); - wm8994->BT_call_vol = BT_call_maxvol; - } - if(wm8994_current_mode=wm8994_BT_baseband) - wm8994_set_volume(wm8994_current_mode,wm8994->BT_call_vol,BT_call_maxvol); + + switch (src) { + case 0: + /* Allow no source specification when stopping */ + if (freq_out) + return -EINVAL; + break; + case WM8994_FLL_SRC_MCLK1: + case WM8994_FLL_SRC_MCLK2: + case WM8994_FLL_SRC_LRCLK: + case WM8994_FLL_SRC_BCLK: + break; + default: + return -EINVAL; } + + /* Are we changing anything? */ + if (wm8994->fll[id].src == src && + wm8994->fll[id].in == freq_in && wm8994->fll[id].out == freq_out) + return 0; + + /* If we're stopping the FLL redo the old config - no + * registers will actually be written but we avoid GCC flow + * analysis bugs spewing warnings. + */ + if (freq_out) + ret = wm8994_get_fll_config(&fll, freq_in, freq_out); else - { - printk("%s----%d::system type error!\n",__FUNCTION__,__LINE__); - return; + ret = wm8994_get_fll_config(&fll, wm8994->fll[id].in, + wm8994->fll[id].out); + if (ret < 0) + return ret; + + /* Gate the AIF clocks while we reclock */ + snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1, + WM8994_AIF1CLK_ENA, 0); + snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1, + WM8994_AIF2CLK_ENA, 0); + + /* We always need to disable the FLL while reconfiguring */ + snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_1 + reg_offset, + WM8994_FLL1_ENA, 0); + + reg = (fll.outdiv << WM8994_FLL1_OUTDIV_SHIFT) | + (fll.fll_fratio << WM8994_FLL1_FRATIO_SHIFT); + snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_2 + reg_offset, + WM8994_FLL1_OUTDIV_MASK | + WM8994_FLL1_FRATIO_MASK, reg); + + snd_soc_write(codec, WM8994_FLL1_CONTROL_3 + reg_offset, fll.k); + + snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_4 + reg_offset, + WM8994_FLL1_N_MASK, + fll.n << WM8994_FLL1_N_SHIFT); + + snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_5 + reg_offset, + WM8994_FLL1_REFCLK_DIV_MASK | + WM8994_FLL1_REFCLK_SRC_MASK, + (fll.clk_ref_div << WM8994_FLL1_REFCLK_DIV_SHIFT) | + (src - 1)); + + /* Enable (with fractional mode if required) */ + if (freq_out) { + if (fll.k) + reg = WM8994_FLL1_ENA | WM8994_FLL1_FRAC; + else + reg = WM8994_FLL1_ENA; + snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_1 + reg_offset, + WM8994_FLL1_ENA | WM8994_FLL1_FRAC, + reg); } + + wm8994->fll[id].in = freq_in; + wm8994->fll[id].out = freq_out; + wm8994->fll[id].src = src; + + /* Enable any gated AIF clocks */ + snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1, + WM8994_AIF1CLK_ENA, aif1); + snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1, + WM8994_AIF2CLK_ENA, aif2); + + configure_clock(codec); + + return 0; } -/* - * Note that this should be called from init rather than from hw_params. - */ -static int wm8994_set_dai_sysclk(struct snd_soc_dai *codec_dai, +static int opclk_divs[] = { 10, 20, 30, 40, 55, 60, 80, 120, 160 }; + +static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id, unsigned int freq, int dir) { - struct snd_soc_codec *codec = codec_dai->codec; - struct wm8994_priv *wm8994 = codec->private_data; - -// DBG("%s----%d\n",__FUNCTION__,__LINE__); + struct snd_soc_codec *codec = dai->codec; + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + int i; + + switch (dai->id) { + case 1: + case 2: + break; + + default: + /* AIF3 shares clocking with AIF1/2 */ + return -EINVAL; + } switch (clk_id) { case WM8994_SYSCLK_MCLK1: - wm8994->sysclk = WM8994_SYSCLK_MCLK1; - wm8994->mclk = freq; - // DBG("AIF1 using MCLK1 at %uHz\n", freq); + wm8994->sysclk[dai->id - 1] = WM8994_SYSCLK_MCLK1; + wm8994->mclk[0] = freq; + dev_dbg(dai->dev, "AIF%d using MCLK1 at %uHz\n", + dai->id, freq); break; case WM8994_SYSCLK_MCLK2: - //TODO: Set GPIO AF - wm8994->sysclk = WM8994_SYSCLK_MCLK2; - wm8994->mclk = freq; - // DBG("AIF1 using MCLK2 at %uHz\n",freq); + /* TODO: Set GPIO AF */ + wm8994->sysclk[dai->id - 1] = WM8994_SYSCLK_MCLK2; + wm8994->mclk[1] = freq; + dev_dbg(dai->dev, "AIF%d using MCLK2 at %uHz\n", + dai->id, freq); break; case WM8994_SYSCLK_FLL1: - wm8994->sysclk = WM8994_SYSCLK_FLL1; - wm8994->mclk = freq; - // DBG("AIF1 using FLL1 at %uHz\n",freq); + wm8994->sysclk[dai->id - 1] = WM8994_SYSCLK_FLL1; + dev_dbg(dai->dev, "AIF%d using FLL1\n", dai->id); break; case WM8994_SYSCLK_FLL2: - wm8994->sysclk = WM8994_SYSCLK_FLL2; - wm8994->mclk = freq; - // DBG("AIF1 using FLL2 at %uHz\n",freq); + wm8994->sysclk[dai->id - 1] = WM8994_SYSCLK_FLL2; + dev_dbg(dai->dev, "AIF%d using FLL2\n", dai->id); break; + case WM8994_SYSCLK_OPCLK: + /* Special case - a division (times 10) is given and + * no effect on main clocking. + */ + if (freq) { + for (i = 0; i < ARRAY_SIZE(opclk_divs); i++) + if (opclk_divs[i] == freq) + break; + if (i == ARRAY_SIZE(opclk_divs)) + return -EINVAL; + snd_soc_update_bits(codec, WM8994_CLOCKING_2, + WM8994_OPCLK_DIV_MASK, i); + snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_2, + WM8994_OPCLK_ENA, WM8994_OPCLK_ENA); + } else { + snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_2, + WM8994_OPCLK_ENA, 0); + } + default: - DBG("ERROR:AIF3 shares clocking with AIF1/2. \n"); return -EINVAL; } + configure_clock(codec); + return 0; } -static int wm8994_set_dai_fmt(struct snd_soc_dai *codec_dai, - unsigned int fmt) +static int wm8994_set_bias_level(struct snd_soc_codec *codec, + enum snd_soc_bias_level level) { - struct snd_soc_codec *codec = codec_dai->codec; - struct wm8994_priv *wm8994 = codec->private_data; -// DBG("Enter %s---%d\n",__FUNCTION__,__LINE__); + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + + switch (level) { + case SND_SOC_BIAS_ON: + break; + + case SND_SOC_BIAS_PREPARE: + /* VMID=2x40k */ + snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1, + WM8994_VMID_SEL_MASK, 0x2); + break; + + case SND_SOC_BIAS_STANDBY: + if (codec->bias_level == SND_SOC_BIAS_OFF) { + /* Tweak DC servo and DSP configuration for + * improved performance. */ + if (wm8994->revision < 4) { + /* Tweak DC servo and DSP configuration for + * improved performance. */ + snd_soc_write(codec, 0x102, 0x3); + snd_soc_write(codec, 0x56, 0x3); + snd_soc_write(codec, 0x817, 0); + snd_soc_write(codec, 0x102, 0); + } + + /* Discharge LINEOUT1 & 2 */ + snd_soc_update_bits(codec, WM8994_ANTIPOP_1, + WM8994_LINEOUT1_DISCH | + WM8994_LINEOUT2_DISCH, + WM8994_LINEOUT1_DISCH | + WM8994_LINEOUT2_DISCH); + + /* Startup bias, VMID ramp & buffer */ + snd_soc_update_bits(codec, WM8994_ANTIPOP_2, + WM8994_STARTUP_BIAS_ENA | + WM8994_VMID_BUF_ENA | + WM8994_VMID_RAMP_MASK, + WM8994_STARTUP_BIAS_ENA | + WM8994_VMID_BUF_ENA | + (0x11 << WM8994_VMID_RAMP_SHIFT)); + + /* Main bias enable, VMID=2x40k */ + snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1, + WM8994_BIAS_ENA | + WM8994_VMID_SEL_MASK, + WM8994_BIAS_ENA | 0x2); + + msleep(20); + } + + /* VMID=2x500k */ + snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1, + WM8994_VMID_SEL_MASK, 0x4); + + break; + + case SND_SOC_BIAS_OFF: + if (codec->bias_level == SND_SOC_BIAS_STANDBY) { + /* Switch over to startup biases */ + snd_soc_update_bits(codec, WM8994_ANTIPOP_2, + WM8994_BIAS_SRC | + WM8994_STARTUP_BIAS_ENA | + WM8994_VMID_BUF_ENA | + WM8994_VMID_RAMP_MASK, + WM8994_BIAS_SRC | + WM8994_STARTUP_BIAS_ENA | + WM8994_VMID_BUF_ENA | + (1 << WM8994_VMID_RAMP_SHIFT)); + + /* Disable main biases */ + snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1, + WM8994_BIAS_ENA | + WM8994_VMID_SEL_MASK, 0); + + /* Discharge line */ + snd_soc_update_bits(codec, WM8994_ANTIPOP_1, + WM8994_LINEOUT1_DISCH | + WM8994_LINEOUT2_DISCH, + WM8994_LINEOUT1_DISCH | + WM8994_LINEOUT2_DISCH); + + msleep(5); + + /* Switch off startup biases */ + snd_soc_update_bits(codec, WM8994_ANTIPOP_2, + WM8994_BIAS_SRC | + WM8994_STARTUP_BIAS_ENA | + WM8994_VMID_BUF_ENA | + WM8994_VMID_RAMP_MASK, 0); + } + break; + } + codec->bias_level = level; + return 0; +} + +static int wm8994_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) +{ + struct snd_soc_codec *codec = dai->codec; + int ms_reg; + int aif1_reg; + int ms = 0; + int aif1 = 0; + + switch (dai->id) { + case 1: + ms_reg = WM8994_AIF1_MASTER_SLAVE; + aif1_reg = WM8994_AIF1_CONTROL_1; + break; + case 2: + ms_reg = WM8994_AIF2_MASTER_SLAVE; + aif1_reg = WM8994_AIF2_CONTROL_1; + break; + default: + return -EINVAL; + } switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { case SND_SOC_DAIFMT_CBS_CFS: - wm8994->fmt = SND_SOC_DAIFMT_CBS_CFS; break; case SND_SOC_DAIFMT_CBM_CFM: - wm8994->fmt = SND_SOC_DAIFMT_CBM_CFM; + ms = WM8994_AIF1_MSTR; break; default: return -EINVAL; } + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_DSP_B: + aif1 |= WM8994_AIF1_LRCLK_INV; + case SND_SOC_DAIFMT_DSP_A: + aif1 |= 0x18; + break; + case SND_SOC_DAIFMT_I2S: + aif1 |= 0x10; + break; + case SND_SOC_DAIFMT_RIGHT_J: + break; + case SND_SOC_DAIFMT_LEFT_J: + aif1 |= 0x8; + break; + default: + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_DSP_A: + case SND_SOC_DAIFMT_DSP_B: + /* frame inversion not valid for DSP modes */ + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + break; + case SND_SOC_DAIFMT_IB_NF: + aif1 |= WM8994_AIF1_BCLK_INV; + break; + default: + return -EINVAL; + } + break; - return 0; + case SND_SOC_DAIFMT_I2S: + case SND_SOC_DAIFMT_RIGHT_J: + case SND_SOC_DAIFMT_LEFT_J: + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + break; + case SND_SOC_DAIFMT_IB_IF: + aif1 |= WM8994_AIF1_BCLK_INV | WM8994_AIF1_LRCLK_INV; + break; + case SND_SOC_DAIFMT_IB_NF: + aif1 |= WM8994_AIF1_BCLK_INV; + break; + case SND_SOC_DAIFMT_NB_IF: + aif1 |= WM8994_AIF1_LRCLK_INV; + break; + default: + return -EINVAL; + } + break; + default: + return -EINVAL; + } + + snd_soc_update_bits(codec, aif1_reg, + WM8994_AIF1_BCLK_INV | WM8994_AIF1_LRCLK_INV | + WM8994_AIF1_FMT_MASK, + aif1); + snd_soc_update_bits(codec, ms_reg, WM8994_AIF1_MSTR, + ms); + + return 0; } -static int wm8994_pcm_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) +static struct { + int val, rate; +} srs[] = { + { 0, 8000 }, + { 1, 11025 }, + { 2, 12000 }, + { 3, 16000 }, + { 4, 22050 }, + { 5, 24000 }, + { 6, 32000 }, + { 7, 44100 }, + { 8, 48000 }, + { 9, 88200 }, + { 10, 96000 }, +}; + +static int fs_ratios[] = { + 64, 128, 192, 256, 348, 512, 768, 1024, 1408, 1536 +}; + +static int bclk_divs[] = { + 10, 15, 20, 30, 40, 50, 60, 80, 110, 120, 160, 220, 240, 320, 440, 480, + 640, 880, 960, 1280, 1760, 1920 +}; + +static int wm8994_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) { struct snd_soc_codec *codec = dai->codec; - struct wm8994_priv *wm8994 = codec->private_data; + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + int aif1_reg; + int bclk_reg; + int lrclk_reg; + int rate_reg; + int aif1 = 0; + int bclk = 0; + int lrclk = 0; + int rate_val = 0; + int id = dai->id - 1; + + int i, cur_val, best_val, bclk_rate, best; + + switch (dai->id) { + case 1: + aif1_reg = WM8994_AIF1_CONTROL_1; + bclk_reg = WM8994_AIF1_BCLK; + rate_reg = WM8994_AIF1_RATE; + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK || + wm8994->lrclk_shared[0]) + lrclk_reg = WM8994_AIF1DAC_LRCLK; + else + lrclk_reg = WM8994_AIF1ADC_LRCLK; + break; + case 2: + aif1_reg = WM8994_AIF2_CONTROL_1; + bclk_reg = WM8994_AIF2_BCLK; + rate_reg = WM8994_AIF2_RATE; + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK || + wm8994->lrclk_shared[1]) + lrclk_reg = WM8994_AIF2DAC_LRCLK; + else + lrclk_reg = WM8994_AIF2ADC_LRCLK; + break; + default: + return -EINVAL; + } -// DBG("Enter %s::%s---%d\n",__FILE__,__FUNCTION__,__LINE__); + bclk_rate = params_rate(params) * 2; + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + bclk_rate *= 16; + break; + case SNDRV_PCM_FORMAT_S20_3LE: + bclk_rate *= 20; + aif1 |= 0x20; + break; + case SNDRV_PCM_FORMAT_S24_LE: + bclk_rate *= 24; + aif1 |= 0x40; + break; + case SNDRV_PCM_FORMAT_S32_LE: + bclk_rate *= 32; + aif1 |= 0x60; + break; + default: + return -EINVAL; + } - wm8994->rate = params_rate(params); -// DBG("Sample rate is %dHz\n",wm8994->rate); + /* Try to find an appropriate sample rate; look for an exact match. */ + for (i = 0; i < ARRAY_SIZE(srs); i++) + if (srs[i].rate == params_rate(params)) + break; + if (i == ARRAY_SIZE(srs)) + return -EINVAL; + rate_val |= srs[i].val << WM8994_AIF1_SR_SHIFT; - return 0; -} + dev_dbg(dai->dev, "Sample rate is %dHz\n", srs[i].rate); + dev_dbg(dai->dev, "AIF%dCLK is %dHz, target BCLK %dHz\n", + dai->id, wm8994->aifclk[id], bclk_rate); -static int wm8994_mute(struct snd_soc_dai *dai, int mute) -{ - return 0; -} + if (wm8994->aifclk[id] == 0) { + dev_err(dai->dev, "AIF%dCLK not configured\n", dai->id); + return -EINVAL; + } + + /* AIFCLK/fs ratio; look for a close match in either direction */ + best = 0; + best_val = abs((fs_ratios[0] * params_rate(params)) + - wm8994->aifclk[id]); + for (i = 1; i < ARRAY_SIZE(fs_ratios); i++) { + cur_val = abs((fs_ratios[i] * params_rate(params)) + - wm8994->aifclk[id]); + if (cur_val >= best_val) + continue; + best = i; + best_val = cur_val; + } + dev_dbg(dai->dev, "Selected AIF%dCLK/fs = %d\n", + dai->id, fs_ratios[best]); + rate_val |= best; + + /* We may not get quite the right frequency if using + * approximate clocks so look for the closest match that is + * higher than the target (we need to ensure that there enough + * BCLKs to clock out the samples). + */ + best = 0; + for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) { + cur_val = (wm8994->aifclk[id] * 10 / bclk_divs[i]) - bclk_rate; + if (cur_val < 0) /* BCLK table is sorted */ + break; + best = i; + } + bclk_rate = wm8994->aifclk[id] * 10 / bclk_divs[best]; + dev_dbg(dai->dev, "Using BCLK_DIV %d for actual BCLK %dHz\n", + bclk_divs[best], bclk_rate); + bclk |= best << WM8994_AIF1_BCLK_DIV_SHIFT; + + lrclk = bclk_rate / params_rate(params); + dev_dbg(dai->dev, "Using LRCLK rate %d for actual LRCLK %dHz\n", + lrclk, bclk_rate / lrclk); + + snd_soc_update_bits(codec, aif1_reg, WM8994_AIF1_WL_MASK, aif1); + snd_soc_update_bits(codec, bclk_reg, WM8994_AIF1_BCLK_DIV_MASK, bclk); + snd_soc_update_bits(codec, lrclk_reg, WM8994_AIF1DAC_RATE_MASK, + lrclk); + snd_soc_update_bits(codec, rate_reg, WM8994_AIF1_SR_MASK | + WM8994_AIF1CLK_RATE_MASK, rate_val); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + switch (dai->id) { + case 1: + wm8994->dac_rates[0] = params_rate(params); + wm8994_set_retune_mobile(codec, 0); + wm8994_set_retune_mobile(codec, 1); + break; + case 2: + wm8994->dac_rates[1] = params_rate(params); + wm8994_set_retune_mobile(codec, 2); + break; + } + } -static int wm8994_set_bias_level(struct snd_soc_codec *codec, - enum snd_soc_bias_level level) -{ return 0; } -static int wm8994_trigger(struct snd_pcm_substream *substream, - int cmd, - struct snd_soc_dai *dai) +static int wm8994_aif_mute(struct snd_soc_dai *codec_dai, int mute) { -// struct snd_soc_pcm_runtime *rtd = substream->private_data; -// struct snd_soc_dai_link *machine = rtd->dai; -// struct snd_soc_dai *codec_dai = machine->codec_dai; - struct snd_soc_codec *codec = dai->codec; - struct wm8994_priv *wm8994 = codec->private_data; - char last_route = wm8994->kcontrol.private_value & 0xff; - - if(wm8994_current_mode >= wm8994_handsetMIC_to_baseband_to_headset && wm8994_current_mode != null) - return 0; - if((last_route == SPEAKER_INCALL || last_route == EARPIECE_INCALL - || last_route == HEADSET_INCALL || BLUETOOTH_SCO_INCALL) - && wm8994_current_mode == wm8994_record_add) - return 0; -// DBG("%s::%d status = %d substream->stream '%s'\n",__FUNCTION__,__LINE__, -// cmd, substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? "PLAYBACK":"CAPTURE"); - - switch(cmd) - { - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_START: - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - { - if(wm8994->playback_active == cmd) - return 0; - wm8994->playback_active = cmd; - } - else - { - if(wm8994->capture_active == cmd) - return 0; - wm8994->capture_active = cmd; - } - break; - default: - return 0; - } + struct snd_soc_codec *codec = codec_dai->codec; + int mute_reg; + int reg; - if (!wm8994->playback_active && - !wm8994->capture_active ) - {//suspend - DBG("It's going to power down wm8994\n"); - cancel_delayed_work_sync(&wm8994->wm8994_delayed_work); - wm8994->work_type = SNDRV_PCM_TRIGGER_STOP; - schedule_delayed_work(&wm8994->wm8994_delayed_work, msecs_to_jiffies(2000)); - } - else if (wm8994->playback_active - || wm8994->capture_active) - {//resume - DBG("Power up wm8994\n"); - if(wm8994->work_type == SNDRV_PCM_TRIGGER_STOP) - cancel_delayed_work_sync(&wm8994->wm8994_delayed_work); - wm8994->work_type = SNDRV_PCM_TRIGGER_START; - schedule_delayed_work(&wm8994->wm8994_delayed_work, msecs_to_jiffies(0)); + switch (codec_dai->id) { + case 1: + mute_reg = WM8994_AIF1_DAC1_FILTERS_1; + break; + case 2: + mute_reg = WM8994_AIF2_DAC_FILTERS_1; + break; + default: + return -EINVAL; } + if (mute) + reg = WM8994_AIF1DAC1_MUTE; + else + reg = 0; + + snd_soc_update_bits(codec, mute_reg, WM8994_AIF1DAC1_MUTE, reg); + return 0; } -static void wm8994_work_fun(struct work_struct *work) -{ - struct snd_soc_codec *codec = wm8994_codec; - struct wm8994_priv *wm8994 = codec->private_data; - struct wm8994_pdata *pdata = wm8994->pdata; - int error_count = 5; -// DBG("Enter %s---%d = %d\n",__FUNCTION__,__LINE__,wm8994_current_mode); +static int wm8994_set_tristate(struct snd_soc_dai *codec_dai, int tristate) +{ + struct snd_soc_codec *codec = codec_dai->codec; + int reg, val, mask; - switch(wm8994->work_type) - { - case SNDRV_PCM_TRIGGER_STOP: - if(wm8994_current_mode > wm8994_AP_to_speakers) - return; - // DBG("wm8994 shutdown\n"); - mutex_lock(&wm8994->route_lock); - wm8994->route_status = BUSY; - PA_ctrl(GPIO_LOW); - msleep(50); - wm8994_write(0,0); - msleep(50); - wm8994_write(0x01, 0x0033); - wm8994_current_mode = null;//Automatically re-set the wake-up time - wm8994->route_status = IDLE; - mutex_unlock(&wm8994->route_lock); - break; - case SNDRV_PCM_TRIGGER_START: + switch (codec_dai->id) { + case 1: + reg = WM8994_AIF1_MASTER_SLAVE; + mask = WM8994_AIF1_TRI; break; - case SNDRV_PCM_TRIGGER_RESUME: - msleep(100); - gpio_request(pdata->Power_EN_Pin, NULL); - gpio_direction_output(pdata->Power_EN_Pin,GPIO_HIGH); - gpio_free(pdata->Power_EN_Pin); - msleep(100); - wm8994_current_mode = null; - snd_soc_put_route(&wm8994->kcontrol,NULL); + case 2: + reg = WM8994_AIF2_MASTER_SLAVE; + mask = WM8994_AIF2_TRI; break; - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - while(error_count) - { - if( wm8994_reset_ldo() == 0) - { - wm8994_current_mode = null; - snd_soc_put_route(&wm8994->kcontrol,NULL); - break; - } - error_count --; - } - if(error_count == 0) - { - PA_ctrl(GPIO_LOW); - printk("wm8994 Major problems, give me log,tks, -- qjb\n"); - } + case 3: + reg = WM8994_POWER_MANAGEMENT_6; + mask = WM8994_AIF3_TRI; break; - default: - break; + return -EINVAL; } + + if (tristate) + val = mask; + else + val = 0; + + return snd_soc_update_bits(codec, reg, mask, reg); } -#define WM8994_RATES SNDRV_PCM_RATE_8000_48000 +#define WM8994_RATES SNDRV_PCM_RATE_8000_96000 + #define WM8994_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ - SNDRV_PCM_FMTBIT_S24_LE) - -static struct snd_soc_dai_ops wm8994_ops = { - .hw_params = wm8994_pcm_hw_params, - .set_fmt = wm8994_set_dai_fmt, - .set_sysclk = wm8994_set_dai_sysclk, - .digital_mute = wm8994_mute, - .trigger = wm8994_trigger, - /*add by qiuen for volume*/ - .set_volume = wm8994_codec_set_volume, + SNDRV_PCM_FMTBIT_S24_LE) + +static struct snd_soc_dai_ops wm8994_aif1_dai_ops = { + .set_sysclk = wm8994_set_dai_sysclk, + .set_fmt = wm8994_set_dai_fmt, + .hw_params = wm8994_hw_params, + .digital_mute = wm8994_aif_mute, + .set_pll = wm8994_set_fll, + .set_tristate = wm8994_set_tristate, }; -struct snd_soc_dai wm8994_dai = { - .name = "WM8994", - .playback = { - .stream_name = "Playback", - .channels_min = 1, - .channels_max = 2, - .rates = WM8994_RATES, - .formats = WM8994_FORMATS, +static struct snd_soc_dai_ops wm8994_aif2_dai_ops = { + .set_sysclk = wm8994_set_dai_sysclk, + .set_fmt = wm8994_set_dai_fmt, + .hw_params = wm8994_hw_params, + .digital_mute = wm8994_aif_mute, + .set_pll = wm8994_set_fll, + .set_tristate = wm8994_set_tristate, +}; + +static struct snd_soc_dai_ops wm8994_aif3_dai_ops = { + .set_tristate = wm8994_set_tristate, +}; + +struct snd_soc_dai wm8994_dai[] = { + { + .name = "WM8994 AIF1", + .id = 1, + .playback = { + .stream_name = "AIF1 Playback", + .channels_min = 2, + .channels_max = 2, + .rates = WM8994_RATES, + .formats = WM8994_FORMATS, + }, + .capture = { + .stream_name = "AIF1 Capture", + .channels_min = 2, + .channels_max = 2, + .rates = WM8994_RATES, + .formats = WM8994_FORMATS, + }, + .ops = &wm8994_aif1_dai_ops, + }, + { + .name = "WM8994 AIF2", + .id = 2, + .playback = { + .stream_name = "AIF2 Playback", + .channels_min = 2, + .channels_max = 2, + .rates = WM8994_RATES, + .formats = WM8994_FORMATS, + }, + .capture = { + .stream_name = "AIF2 Capture", + .channels_min = 2, + .channels_max = 2, + .rates = WM8994_RATES, + .formats = WM8994_FORMATS, + }, + .ops = &wm8994_aif2_dai_ops, }, - .capture = { - .stream_name = "Capture", - .channels_min = 2, - .channels_max = 2, - .rates = WM8994_RATES, - .formats = WM8994_FORMATS, - }, - .ops = &wm8994_ops, - .symmetric_rates = 1, + { + .name = "WM8994 AIF3", + .id = 3, + .playback = { + .stream_name = "AIF3 Playback", + .channels_min = 2, + .channels_max = 2, + .rates = WM8994_RATES, + .formats = WM8994_FORMATS, + }, + .capture = { + .stream_name = "AIF3 Capture", + .channels_min = 2, + .channels_max = 2, + .rates = WM8994_RATES, + .formats = WM8994_FORMATS, + }, + .ops = &wm8994_aif3_dai_ops, + } }; EXPORT_SYMBOL_GPL(wm8994_dai); +#ifdef CONFIG_PM static int wm8994_suspend(struct platform_device *pdev, pm_message_t state) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); struct snd_soc_codec *codec = socdev->card->codec; - struct wm8994_priv *wm8994 = codec->private_data; - struct wm8994_pdata *pdata = wm8994->pdata; - - cancel_delayed_work_sync(&wm8994->wm8994_delayed_work); - - if(wm8994_current_mode>wm8994_AP_to_speakers && - wm8994_current_mode< null )//incall status,wm8994 not suspend - return 0; - DBG("%s----%d\n",__FUNCTION__,__LINE__); - - wm8994->route_status = SUSPEND; - PA_ctrl(GPIO_LOW); - wm8994_write(0x00, 0x00); - - gpio_request(pdata->Power_EN_Pin, NULL); - gpio_direction_output(pdata->Power_EN_Pin,GPIO_LOW); - gpio_free(pdata->Power_EN_Pin); - msleep(50); + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + int i, ret; + + for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) { + memcpy(&wm8994->fll_suspend[i], &wm8994->fll[i], + sizeof(struct fll_config)); + ret = wm8994_set_fll(&codec->dai[0], i + 1, 0, 0, 0); + if (ret < 0) + dev_warn(codec->dev, "Failed to stop FLL%d: %d\n", + i + 1, ret); + } + + wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; } @@ -2766,243 +3602,188 @@ static int wm8994_resume(struct platform_device *pdev) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); struct snd_soc_codec *codec = socdev->card->codec; - struct wm8994_priv *wm8994 = codec->private_data; -// struct wm8994_pdata *pdata = wm8994->pdata; - if(wm8994_current_mode>wm8994_AP_to_speakers && - wm8994_current_mode< null )//incall status,wm8994 not suspend - return 0; - DBG("%s----%d\n",__FUNCTION__,__LINE__); + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + u16 *reg_cache = codec->reg_cache; + int i, ret; + + /* Restore the registers */ + for (i = 1; i < ARRAY_SIZE(wm8994->reg_cache); i++) { + switch (i) { + case WM8994_LDO_1: + case WM8994_LDO_2: + case WM8994_SOFTWARE_RESET: + /* Handled by other MFD drivers */ + continue; + default: + break; + } - cancel_delayed_work_sync(&wm8994->wm8994_delayed_work); - wm8994->work_type = SNDRV_PCM_TRIGGER_RESUME; - schedule_delayed_work(&wm8994->wm8994_delayed_work, msecs_to_jiffies(0)); + if (!access_masks[i].writable) + continue; + + wm8994_reg_write(codec->control_data, i, reg_cache[i]); + } + + wm8994_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + + for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) { + if (!wm8994->fll_suspend[i].out) + continue; + + ret = wm8994_set_fll(&codec->dai[0], i + 1, + wm8994->fll_suspend[i].src, + wm8994->fll_suspend[i].in, + wm8994->fll_suspend[i].out); + if (ret < 0) + dev_warn(codec->dev, "Failed to restore FLL%d: %d\n", + i + 1, ret); + } return 0; } +#else +#define wm8994_suspend NULL +#define wm8994_resume NULL +#endif -#ifdef WM8994_PROC -static ssize_t wm8994_proc_write(struct file *file, const char __user *buffer, - unsigned long len, void *data) +static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994) { - char *cookie_pot; - char *p; - int reg; - int value; - struct snd_kcontrol kcontrol; - struct wm8994_priv *wm8994 = wm8994_codec->private_data; + struct snd_soc_codec *codec = &wm8994->codec; struct wm8994_pdata *pdata = wm8994->pdata; - - cookie_pot = (char *)vmalloc( len ); - if (!cookie_pot) - { - return -ENOMEM; - } - else - { - if (copy_from_user( cookie_pot, buffer, len )) - return -EFAULT; - } - - switch(cookie_pot[0]) - { - case 'd': - case 'D': - debug_write_read ++; - debug_write_read %= 2; - if(debug_write_read != 0) - DBG("Debug read and write reg on\n"); - else - DBG("Debug read and write reg off\n"); - break; - case 'r': - case 'R': - DBG("Read reg debug\n"); - if(cookie_pot[1] ==':') - { - debug_write_read = 1; - strsep(&cookie_pot,":"); - while((p=strsep(&cookie_pot,","))) - { - wm8994_read(simple_strtol(p,NULL,16),(unsigned short *)&value); - } - debug_write_read = 0;; - DBG("\n"); - } - else - { - DBG("Error Read reg debug.\n"); - DBG("For example: echo 'r:22,23,24,25'>wm8994_ts\n"); - } - break; - case 'w': - case 'W': - DBG("Write reg debug\n"); - if(cookie_pot[1] ==':') - { - debug_write_read = 1; - strsep(&cookie_pot,":"); - while((p=strsep(&cookie_pot,"="))) - { - reg = simple_strtol(p,NULL,16); - p=strsep(&cookie_pot,","); - value = simple_strtol(p,NULL,16); - wm8994_write(reg,value); - } - debug_write_read = 0;; - DBG("\n"); - } - else - { - DBG("Error Write reg debug.\n"); - DBG("For example: w:22=0,23=0,24=0,25=0\n"); - } - break; - case 'p': - case 'P': - if(cookie_pot[1] =='-') - { - kcontrol.private_value = simple_strtol(&cookie_pot[2],NULL,10); - printk("kcontrol.private_value = %ld\n",kcontrol.private_value); - if(kcontrol.private_valueHEADSET_RINGTONE) - { - printk("route error\n"); - goto help; - } - snd_soc_put_route(&kcontrol,NULL); - break; - } - else if(cookie_pot[1] ==':') - { - strsep(&cookie_pot,":"); - while((p=strsep(&cookie_pot,","))) - { - kcontrol.private_value = simple_strtol(p,NULL,10); - printk("kcontrol.private_value = %ld\n",kcontrol.private_value); - if(kcontrol.private_valueHEADSET_RINGTONE) - { - printk("route error\n"); - goto help; - } - snd_soc_put_route(&kcontrol,NULL); - } - break; - } - else - { - goto help; - } - help: - printk("snd_soc_put_route list\n"); - printk("SPEAKER_INCALL--\"p-0\",\nSPEAKER_NORMAL--\"p-1\",\nHEADSET_INCALL--\"p-2\",\ - \nHEADSET_NORMAL--\"p-3\",\nEARPIECE_INCALL--\"p-4\",\nEARPIECE_NORMAL--\"p-5\",\ - \nBLUETOOTH_SCO_INCALL--\"p-6\",\nMIC_CAPTURE--\"p-10\",\nEARPIECE_RINGTONE--\"p-11\",\ - \nSPEAKER_RINGTONE--\"p-12\",\nHEADSET_RINGTONE--\"p-13\"\n"); - break; - case 'S': - case 's': - printk("Debug : Set volume begin\n"); - switch(cookie_pot[1]) - { - case '+': - if(cookie_pot[2] == '\n') - { - - } - else - { - value = simple_strtol(&cookie_pot[2],NULL,10); - printk("value = %d\n",value); - - } - break; - case '-': - if(cookie_pot[2] == '\n') - { - - } - else - { - value = simple_strtol(&cookie_pot[2],NULL,10); - printk("value = %d\n",value); - } + struct snd_kcontrol_new controls[] = { + SOC_ENUM_EXT("AIF1.1 EQ Mode", + wm8994->retune_mobile_enum, + wm8994_get_retune_mobile_enum, + wm8994_put_retune_mobile_enum), + SOC_ENUM_EXT("AIF1.2 EQ Mode", + wm8994->retune_mobile_enum, + wm8994_get_retune_mobile_enum, + wm8994_put_retune_mobile_enum), + SOC_ENUM_EXT("AIF2 EQ Mode", + wm8994->retune_mobile_enum, + wm8994_get_retune_mobile_enum, + wm8994_put_retune_mobile_enum), + }; + int ret, i, j; + const char **t; + + /* We need an array of texts for the enum API but the number + * of texts is likely to be less than the number of + * configurations due to the sample rate dependency of the + * configurations. */ + wm8994->num_retune_mobile_texts = 0; + wm8994->retune_mobile_texts = NULL; + for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) { + for (j = 0; j < wm8994->num_retune_mobile_texts; j++) { + if (strcmp(pdata->retune_mobile_cfgs[i].name, + wm8994->retune_mobile_texts[j]) == 0) break; - default: - if(cookie_pot[1] == '=') - { - value = simple_strtol(&cookie_pot[2],NULL,10); - printk("value = %d\n",value); - } - else - printk("Help the set volume,Example: echo s+**>wm8994_ts,s=**>wm8994_ts,s-**>wm8994_ts\n"); - - break; - } - break; - case '1': - gpio_request(pdata->Power_EN_Pin, NULL); - gpio_direction_output(pdata->Power_EN_Pin,GPIO_LOW); - gpio_free(pdata->Power_EN_Pin); - break; - case '2': - gpio_request(pdata->Power_EN_Pin, NULL); - gpio_direction_output(pdata->Power_EN_Pin,GPIO_HIGH); - gpio_free(pdata->Power_EN_Pin); - break; - default: - DBG("Help for wm8994_ts .\n-->The Cmd list: \n"); - DBG("-->'d&&D' Open or close the debug\n"); - DBG("-->'r&&R' Read reg debug,Example: echo 'r:22,23,24,25'>wm8994_ts\n"); - DBG("-->'w&&W' Write reg debug,Example: echo 'w:22=0,23=0,24=0,25=0'>wm8994_ts\n"); - DBG("-->'ph&&Ph' cat snd_soc_put_route list\n"); - break; + } + + if (j != wm8994->num_retune_mobile_texts) + continue; + + /* Expand the array... */ + t = krealloc(wm8994->retune_mobile_texts, + sizeof(char *) * + (wm8994->num_retune_mobile_texts + 1), + GFP_KERNEL); + if (t == NULL) + continue; + + /* ...store the new entry... */ + t[wm8994->num_retune_mobile_texts] = + pdata->retune_mobile_cfgs[i].name; + + /* ...and remember the new version. */ + wm8994->num_retune_mobile_texts++; + wm8994->retune_mobile_texts = t; } - return len; + dev_dbg(codec->dev, "Allocated %d unique ReTune Mobile names\n", + wm8994->num_retune_mobile_texts); + + wm8994->retune_mobile_enum.max = wm8994->num_retune_mobile_texts; + wm8994->retune_mobile_enum.texts = wm8994->retune_mobile_texts; + + ret = snd_soc_add_controls(&wm8994->codec, controls, + ARRAY_SIZE(controls)); + if (ret != 0) + dev_err(wm8994->codec.dev, + "Failed to add ReTune Mobile controls: %d\n", ret); } -static const struct file_operations wm8994_proc_fops = { - .owner = THIS_MODULE, - //.open = snd_mem_proc_open, - //.read = seq_read, -//#ifdef CONFIG_PCI - .write = wm8994_proc_write, -//#endif - //.llseek = seq_lseek, - //.release = single_release, -}; +static void wm8994_handle_pdata(struct wm8994_priv *wm8994) +{ + struct snd_soc_codec *codec = &wm8994->codec; + struct wm8994_pdata *pdata = wm8994->pdata; + int ret, i; -static int wm8994_proc_init(void){ + if (!pdata) + return; - struct proc_dir_entry *wm8994_proc_entry; + wm_hubs_handle_analogue_pdata(codec, pdata->lineout1_diff, + pdata->lineout2_diff, + pdata->lineout1fb, + pdata->lineout2fb, + pdata->jd_scthr, + pdata->jd_thr, + pdata->micbias1_lvl, + pdata->micbias2_lvl); + + dev_dbg(codec->dev, "%d DRC configurations\n", pdata->num_drc_cfgs); + + if (pdata->num_drc_cfgs) { + struct snd_kcontrol_new controls[] = { + SOC_ENUM_EXT("AIF1DRC1 Mode", wm8994->drc_enum, + wm8994_get_drc_enum, wm8994_put_drc_enum), + SOC_ENUM_EXT("AIF1DRC2 Mode", wm8994->drc_enum, + wm8994_get_drc_enum, wm8994_put_drc_enum), + SOC_ENUM_EXT("AIF2DRC Mode", wm8994->drc_enum, + wm8994_get_drc_enum, wm8994_put_drc_enum), + }; + + /* We need an array of texts for the enum API */ + wm8994->drc_texts = kmalloc(sizeof(char *) + * pdata->num_drc_cfgs, GFP_KERNEL); + if (!wm8994->drc_texts) { + dev_err(wm8994->codec.dev, + "Failed to allocate %d DRC config texts\n", + pdata->num_drc_cfgs); + return; + } - wm8994_proc_entry = create_proc_entry("driver/wm8994_ts", 0777, NULL); + for (i = 0; i < pdata->num_drc_cfgs; i++) + wm8994->drc_texts[i] = pdata->drc_cfgs[i].name; - if(wm8994_proc_entry != NULL){ + wm8994->drc_enum.max = pdata->num_drc_cfgs; + wm8994->drc_enum.texts = wm8994->drc_texts; - wm8994_proc_entry->write_proc = wm8994_proc_write; + ret = snd_soc_add_controls(&wm8994->codec, controls, + ARRAY_SIZE(controls)); + if (ret != 0) + dev_err(wm8994->codec.dev, + "Failed to add DRC mode controls: %d\n", ret); - return -1; - }else{ - printk("create proc error !\n"); + for (i = 0; i < WM8994_NUM_DRC; i++) + wm8994_set_drc(codec, i); } - return 0; -} + dev_dbg(codec->dev, "%d ReTune Mobile configurations\n", + pdata->num_retune_mobile_cfgs); -#endif + if (pdata->num_retune_mobile_cfgs) + wm8994_handle_retune_mobile_pdata(wm8994); + else + snd_soc_add_controls(&wm8994->codec, wm8994_eq_controls, + ARRAY_SIZE(wm8994_eq_controls)); +} static int wm8994_probe(struct platform_device *pdev) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); struct snd_soc_codec *codec; - struct wm8994_priv *wm8994; - struct wm8994_pdata *pdata; int ret = 0; - - -#ifdef WM8994_PROC - wm8994_proc_init(); -#endif if (wm8994_codec == NULL) { dev_err(&pdev->dev, "Codec device not registered\n"); @@ -3011,61 +3792,25 @@ static int wm8994_probe(struct platform_device *pdev) socdev->card->codec = wm8994_codec; codec = wm8994_codec; - wm8994 = codec->private_data; - pdata = wm8994->pdata; - //disable power_EN - rk29_mux_api_set(pdata->PowerEN_iomux_name, pdata->PowerEN_iomux_mode); - gpio_request(pdata->Power_EN_Pin, NULL); - gpio_direction_output(pdata->Power_EN_Pin,GPIO_LOW); - gpio_free(pdata->Power_EN_Pin); - + /* register pcms */ ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); if (ret < 0) { dev_err(codec->dev, "failed to create pcms: %d\n", ret); - goto pcm_err; - } - - snd_soc_add_controls(codec,wm8994_snd_controls, - ARRAY_SIZE(wm8994_snd_controls)); - - ret = snd_soc_init_card(socdev); - if (ret < 0) { - dev_err(codec->dev, "failed to register card: %d\n", ret); - goto card_err; + return ret; } - if(pdata->BB_class == PCM_BB) - { - handsetMIC_to_baseband_to_headset = &handsetMIC_to_PCMBB_to_headset; - mainMIC_to_baseband_to_headset = &mainMIC_to_PCMBB_to_headset; - mainMIC_to_baseband_to_earpiece = &mainMIC_to_PCMBB_to_earpiece; - mainMIC_to_baseband_to_speakers = &mainMIC_to_PCMBB_to_speakers; - BT_baseband = &BT_PCMBB; - } - else - { - handsetMIC_to_baseband_to_headset = &handsetMIC_to_BB_to_headset; - mainMIC_to_baseband_to_headset = &mainMIC_to_BB_to_headset; - mainMIC_to_baseband_to_earpiece = &mainMIC_to_BB_to_earpiece; - mainMIC_to_baseband_to_speakers = &mainMIC_to_BB_to_speakers; - BT_baseband = &BT_BB; - } - - PA_ctrl(GPIO_LOW); - //enable power_EN - msleep(50); - gpio_request(pdata->Power_EN_Pin, NULL); - gpio_direction_output(pdata->Power_EN_Pin,GPIO_HIGH); - gpio_free(pdata->Power_EN_Pin); + wm8994_handle_pdata(snd_soc_codec_get_drvdata(codec)); - return ret; + wm_hubs_add_analogue_controls(codec); + snd_soc_add_controls(codec, wm8994_snd_controls, + ARRAY_SIZE(wm8994_snd_controls)); + snd_soc_dapm_new_controls(codec, wm8994_dapm_widgets, + ARRAY_SIZE(wm8994_dapm_widgets)); + wm_hubs_add_analogue_routes(codec, 0, 0); + snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); -card_err: - snd_soc_free_pcms(socdev); - snd_soc_dapm_free(socdev); -pcm_err: - return ret; + return 0; } static int wm8994_remove(struct platform_device *pdev) @@ -3086,251 +3831,327 @@ struct snd_soc_codec_device soc_codec_dev_wm8994 = { }; EXPORT_SYMBOL_GPL(soc_codec_dev_wm8994); -static int wm8994_register(struct wm8994_priv *wm8994, - enum snd_soc_control_type control) +/** + * wm8994_mic_detect - Enable microphone detection via the WM8994 IRQ + * + * @codec: WM8994 codec + * @jack: jack to report detection events on + * @micbias: microphone bias to detect on + * @det: value to report for presence detection + * @shrt: value to report for short detection + * + * Enable microphone detection via IRQ on the WM8994. If GPIOs are + * being used to bring out signals to the processor then only platform + * data configuration is needed for WM8903 and processor GPIOs should + * be configured using snd_soc_jack_add_gpios() instead. + * + * Configuration of detection levels is available via the micbias1_lvl + * and micbias2_lvl platform data members. + */ +int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, + int micbias, int det, int shrt) +{ + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + struct wm8994_micdet *micdet; + int reg; + + switch (micbias) { + case 1: + micdet = &wm8994->micdet[0]; + break; + case 2: + micdet = &wm8994->micdet[1]; + break; + default: + return -EINVAL; + } + + dev_dbg(codec->dev, "Configuring microphone detection on %d: %x %x\n", + micbias, det, shrt); + + /* Store the configuration */ + micdet->jack = jack; + micdet->det = det; + micdet->shrt = shrt; + + /* If either of the jacks is set up then enable detection */ + if (wm8994->micdet[0].jack || wm8994->micdet[1].jack) + reg = WM8994_MICD_ENA; + else + reg = 0; + + snd_soc_update_bits(codec, WM8994_MICBIAS, WM8994_MICD_ENA, reg); + + return 0; +} +EXPORT_SYMBOL_GPL(wm8994_mic_detect); + +static irqreturn_t wm8994_mic_irq(int irq, void *data) +{ + struct wm8994_priv *priv = data; + struct snd_soc_codec *codec = &priv->codec; + int reg; + int report; + + reg = snd_soc_read(codec, WM8994_INTERRUPT_RAW_STATUS_2); + if (reg < 0) { + dev_err(codec->dev, "Failed to read microphone status: %d\n", + reg); + return IRQ_HANDLED; + } + + dev_dbg(codec->dev, "Microphone status: %x\n", reg); + + report = 0; + if (reg & WM8994_MIC1_DET_STS) + report |= priv->micdet[0].det; + if (reg & WM8994_MIC1_SHRT_STS) + report |= priv->micdet[0].shrt; + snd_soc_jack_report(priv->micdet[0].jack, report, + priv->micdet[0].det | priv->micdet[0].shrt); + + report = 0; + if (reg & WM8994_MIC2_DET_STS) + report |= priv->micdet[1].det; + if (reg & WM8994_MIC2_SHRT_STS) + report |= priv->micdet[1].shrt; + snd_soc_jack_report(priv->micdet[1].jack, report, + priv->micdet[1].det | priv->micdet[1].shrt); + + return IRQ_HANDLED; +} + +static int wm8994_codec_probe(struct platform_device *pdev) { - struct snd_soc_codec *codec = &wm8994->codec; int ret; + struct wm8994_priv *wm8994; + struct snd_soc_codec *codec; + int i; if (wm8994_codec) { - dev_err(codec->dev, "Another WM8994 is registered\n"); - ret = -EINVAL; - goto err; + dev_err(&pdev->dev, "Another WM8994 is registered\n"); + return -EINVAL; + } + + wm8994 = kzalloc(sizeof(struct wm8994_priv), GFP_KERNEL); + if (!wm8994) { + dev_err(&pdev->dev, "Failed to allocate private data\n"); + return -ENOMEM; } + codec = &wm8994->codec; + mutex_init(&codec->mutex); INIT_LIST_HEAD(&codec->dapm_widgets); INIT_LIST_HEAD(&codec->dapm_paths); - codec->private_data = wm8994; + snd_soc_codec_set_drvdata(codec, wm8994); + codec->control_data = dev_get_drvdata(pdev->dev.parent); codec->name = "WM8994"; codec->owner = THIS_MODULE; - codec->dai = &wm8994_dai; - codec->num_dai = 1; -// codec->reg_cache_size = ARRAY_SIZE(wm8994->reg_cache); -// codec->reg_cache = &wm8994->reg_cache; + codec->read = wm8994_read; + codec->write = wm8994_write; + codec->readable_register = wm8994_readable; codec->bias_level = SND_SOC_BIAS_OFF; codec->set_bias_level = wm8994_set_bias_level; + codec->dai = &wm8994_dai[0]; + codec->num_dai = 3; + codec->reg_cache_size = WM8994_MAX_REGISTER; + codec->reg_cache = &wm8994->reg_cache; + codec->dev = &pdev->dev; + + wm8994->pdata = pdev->dev.parent->platform_data; + + /* Fill the cache with physical values we inherited; don't reset */ + ret = wm8994_bulk_read(codec->control_data, 0, + ARRAY_SIZE(wm8994->reg_cache) - 1, + codec->reg_cache); + if (ret < 0) { + dev_err(codec->dev, "Failed to fill register cache: %d\n", + ret); + goto err; + } + + /* Clear the cached values for unreadable/volatile registers to + * avoid potential confusion. + */ + for (i = 0; i < ARRAY_SIZE(wm8994->reg_cache); i++) + if (wm8994_volatile(i) || !wm8994_readable(i)) + wm8994->reg_cache[i] = 0; + + /* Set revision-specific configuration */ + wm8994->revision = snd_soc_read(codec, WM8994_CHIP_REVISION); + switch (wm8994->revision) { + case 2: + case 3: + wm8994->hubs.dcs_codes = -5; + wm8994->hubs.hp_startup_mode = 1; + wm8994->hubs.dcs_readback_mode = 1; + break; + default: + wm8994->hubs.dcs_readback_mode = 1; + break; + } + + ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC1_DET, + wm8994_mic_irq, "Mic 1 detect", wm8994); + if (ret != 0) + dev_warn(&pdev->dev, + "Failed to request Mic1 detect IRQ: %d\n", ret); + + ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, + wm8994_mic_irq, "Mic 1 short", wm8994); + if (ret != 0) + dev_warn(&pdev->dev, + "Failed to request Mic1 short IRQ: %d\n", ret); -// memcpy(codec->reg_cache, wm8994_reg, -// sizeof(wm8994_reg)); + ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC2_DET, + wm8994_mic_irq, "Mic 2 detect", wm8994); + if (ret != 0) + dev_warn(&pdev->dev, + "Failed to request Mic2 detect IRQ: %d\n", ret); + + ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT, + wm8994_mic_irq, "Mic 2 short", wm8994); + if (ret != 0) + dev_warn(&pdev->dev, + "Failed to request Mic2 short IRQ: %d\n", ret); - ret = snd_soc_codec_set_cache_io(codec,7, 9, control); + /* Remember if AIFnLRCLK is configured as a GPIO. This should be + * configured on init - if a system wants to do this dynamically + * at runtime we can deal with that then. + */ + ret = wm8994_reg_read(codec->control_data, WM8994_GPIO_1); if (ret < 0) { - dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); - goto err; + dev_err(codec->dev, "Failed to read GPIO1 state: %d\n", ret); + goto err_irq; + } + if ((ret & WM8994_GPN_FN_MASK) != WM8994_GP_FN_PIN_SPECIFIC) { + wm8994->lrclk_shared[0] = 1; + wm8994_dai[0].symmetric_rates = 1; + } else { + wm8994->lrclk_shared[0] = 0; } - ret = 0; + ret = wm8994_reg_read(codec->control_data, WM8994_GPIO_6); if (ret < 0) { - dev_err(codec->dev, "Failed to issue reset\n"); - goto err; + dev_err(codec->dev, "Failed to read GPIO6 state: %d\n", ret); + goto err_irq; + } + if ((ret & WM8994_GPN_FN_MASK) != WM8994_GP_FN_PIN_SPECIFIC) { + wm8994->lrclk_shared[1] = 1; + wm8994_dai[1].symmetric_rates = 1; + } else { + wm8994->lrclk_shared[1] = 0; } - wm8994_set_bias_level(&wm8994->codec, SND_SOC_BIAS_STANDBY); + for (i = 0; i < ARRAY_SIZE(wm8994_dai); i++) + wm8994_dai[i].dev = codec->dev; - wm8994_dai.dev = codec->dev; + wm8994_set_bias_level(codec, SND_SOC_BIAS_STANDBY); wm8994_codec = codec; + /* Latch volume updates (right only; we always do left then right). */ + snd_soc_update_bits(codec, WM8994_AIF1_DAC1_RIGHT_VOLUME, + WM8994_AIF1DAC1_VU, WM8994_AIF1DAC1_VU); + snd_soc_update_bits(codec, WM8994_AIF1_DAC2_RIGHT_VOLUME, + WM8994_AIF1DAC2_VU, WM8994_AIF1DAC2_VU); + snd_soc_update_bits(codec, WM8994_AIF2_DAC_RIGHT_VOLUME, + WM8994_AIF2DAC_VU, WM8994_AIF2DAC_VU); + snd_soc_update_bits(codec, WM8994_AIF1_ADC1_RIGHT_VOLUME, + WM8994_AIF1ADC1_VU, WM8994_AIF1ADC1_VU); + snd_soc_update_bits(codec, WM8994_AIF1_ADC2_RIGHT_VOLUME, + WM8994_AIF1ADC2_VU, WM8994_AIF1ADC2_VU); + snd_soc_update_bits(codec, WM8994_AIF2_ADC_RIGHT_VOLUME, + WM8994_AIF2ADC_VU, WM8994_AIF1ADC2_VU); + snd_soc_update_bits(codec, WM8994_DAC1_RIGHT_VOLUME, + WM8994_DAC1_VU, WM8994_DAC1_VU); + snd_soc_update_bits(codec, WM8994_DAC2_RIGHT_VOLUME, + WM8994_DAC2_VU, WM8994_DAC2_VU); + + /* Set the low bit of the 3D stereo depth so TLV matches */ + snd_soc_update_bits(codec, WM8994_AIF1_DAC1_FILTERS_2, + 1 << WM8994_AIF1DAC1_3D_GAIN_SHIFT, + 1 << WM8994_AIF1DAC1_3D_GAIN_SHIFT); + snd_soc_update_bits(codec, WM8994_AIF1_DAC2_FILTERS_2, + 1 << WM8994_AIF1DAC2_3D_GAIN_SHIFT, + 1 << WM8994_AIF1DAC2_3D_GAIN_SHIFT); + snd_soc_update_bits(codec, WM8994_AIF2_DAC_FILTERS_2, + 1 << WM8994_AIF2DAC_3D_GAIN_SHIFT, + 1 << WM8994_AIF2DAC_3D_GAIN_SHIFT); + + /* Unconditionally enable AIF1 ADC TDM mode; it only affects + * behaviour on idle TDM clock cycles. */ + snd_soc_update_bits(codec, WM8994_AIF1_CONTROL_1, + WM8994_AIF1ADC_TDM, WM8994_AIF1ADC_TDM); + + wm8994_update_class_w(codec); + ret = snd_soc_register_codec(codec); if (ret != 0) { dev_err(codec->dev, "Failed to register codec: %d\n", ret); - goto err; + goto err_irq; } - ret = snd_soc_register_dai(&wm8994_dai); + ret = snd_soc_register_dais(wm8994_dai, ARRAY_SIZE(wm8994_dai)); if (ret != 0) { - dev_err(codec->dev, "Failed to register DAI: %d\n", ret); - snd_soc_unregister_codec(codec); + dev_err(codec->dev, "Failed to register DAIs: %d\n", ret); goto err_codec; } + + platform_set_drvdata(pdev, wm8994); + return 0; err_codec: snd_soc_unregister_codec(codec); +err_irq: + wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT, wm8994); + wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET, wm8994); + wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, wm8994); + wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_DET, wm8994); err: kfree(wm8994); return ret; } -static void wm8994_unregister(struct wm8994_priv *wm8994) +static int __devexit wm8994_codec_remove(struct platform_device *pdev) { - wm8994_set_bias_level(&wm8994->codec, SND_SOC_BIAS_OFF); - snd_soc_unregister_dai(&wm8994_dai); + struct wm8994_priv *wm8994 = platform_get_drvdata(pdev); + struct snd_soc_codec *codec = &wm8994->codec; + + wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF); + snd_soc_unregister_dais(wm8994_dai, ARRAY_SIZE(wm8994_dai)); snd_soc_unregister_codec(&wm8994->codec); + wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT, wm8994); + wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET, wm8994); + wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, wm8994); + wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_DET, wm8994); kfree(wm8994); wm8994_codec = NULL; -} - -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) -static int wm8994_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) -{ - struct wm8994_priv *wm8994; - struct snd_soc_codec *codec; - - wm8994 = kzalloc(sizeof(struct wm8994_priv), GFP_KERNEL); - if (wm8994 == NULL) - return -ENOMEM; - - codec = &wm8994->codec; - - i2c_set_clientdata(i2c, wm8994); - codec->control_data = i2c; - - codec->dev = &i2c->dev; - wm8994->pdata = i2c->dev.platform_data;//add - wm8994->RW_status = TRUE;//add - wm8994->capture_active = 0; - wm8994->playback_active = 0; - wm8994->call_vol = call_maxvol; - wm8994->BT_call_vol = BT_call_maxvol; - wm8994->route_status = POWER_ON; - INIT_DELAYED_WORK(&wm8994->wm8994_delayed_work, wm8994_work_fun); - mutex_init(&wm8994->io_lock); - mutex_init(&wm8994->route_lock); - wake_lock_init(&wm8994->wm8994_on_wake, WAKE_LOCK_SUSPEND, "wm8994_on_wake"); - return wm8994_register(wm8994, SND_SOC_I2C); -} - -static int wm8994_i2c_remove(struct i2c_client *client) -{ - struct wm8994_priv *wm8994 = i2c_get_clientdata(client); - wm8994_unregister(wm8994); - return 0; -} - -#ifdef CONFIG_PM -static int wm8994_i2c_suspend(struct i2c_client *client, pm_message_t msg) -{ - return snd_soc_suspend_device(&client->dev); -} - -static int wm8994_i2c_resume(struct i2c_client *client) -{ - return snd_soc_resume_device(&client->dev); -} -#else -#define wm8994_i2c_suspend NULL -#define wm8994_i2c_resume NULL -#endif - -static void wm8994_i2c_shutdown(struct i2c_client *client) -{ - struct wm8994_priv *wm8994 = wm8994_codec->private_data; - struct wm8994_pdata *pdata = wm8994->pdata; - DBG("%s----%d\n",__FUNCTION__,__LINE__); - //disable PA - PA_ctrl(GPIO_LOW); - gpio_request(pdata->Power_EN_Pin, NULL); - gpio_direction_output(pdata->Power_EN_Pin,GPIO_LOW); - gpio_free(pdata->Power_EN_Pin); -} - -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, - .shutdown = wm8994_i2c_shutdown, -}; - -#endif - -#if defined(CONFIG_SPI_MASTER) -static int __devinit wm8994_spi_probe(struct spi_device *spi) -{ - struct wm8994_priv *wm8994; - struct snd_soc_codec *codec; - - wm8994 = kzalloc(sizeof(struct wm8994_priv), GFP_KERNEL); - if (wm8994 == NULL) - return -ENOMEM; - - codec = &wm8994->codec; - codec->control_data = spi; - codec->dev = &spi->dev; - - dev_set_drvdata(&spi->dev, wm8994); - - return wm8994_register(wm8994, SND_SOC_SPI); -} - -static int __devexit wm8994_spi_remove(struct spi_device *spi) -{ - struct wm8994_priv *wm8994 = dev_get_drvdata(&spi->dev); - - wm8994_unregister(wm8994); return 0; } -#ifdef CONFIG_PM -static int wm8994_spi_suspend(struct spi_device *spi, pm_message_t msg) -{ - return snd_soc_suspend_device(&spi->dev); -} - -static int wm8994_spi_resume(struct spi_device *spi) -{ - return snd_soc_resume_device(&spi->dev); -} -#else -#define wm8994_spi_suspend NULL -#define wm8994_spi_resume NULL -#endif - -static struct spi_driver wm8994_spi_driver = { +static struct platform_driver wm8994_codec_driver = { .driver = { - .name = "wm8994", - .bus = &spi_bus_type, - .owner = THIS_MODULE, - }, - .probe = wm8994_spi_probe, - .remove = __devexit_p(wm8994_spi_remove), - .suspend = wm8994_spi_suspend, - .resume = wm8994_spi_resume, + .name = "wm8994-codec", + .owner = THIS_MODULE, + }, + .probe = wm8994_codec_probe, + .remove = __devexit_p(wm8994_codec_remove), }; -#endif -static int __init wm8994_modinit(void) +static __init int wm8994_init(void) { - int ret; - -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) - ret = i2c_add_driver(&wm8994_i2c_driver); - if (ret != 0) - pr_err("WM8994: Unable to register I2C driver: %d\n", ret); -#endif -#if defined(CONFIG_SPI_MASTER) - ret = spi_register_driver(&wm8994_spi_driver); - if (ret != 0) - pr_err("WM8994: Unable to register SPI driver: %d\n", ret); -#endif - return ret; + return platform_driver_register(&wm8994_codec_driver); } -module_init(wm8994_modinit); +module_init(wm8994_init); -static void __exit wm8994_exit(void) +static __exit void wm8994_exit(void) { -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) - i2c_del_driver(&wm8994_i2c_driver); -#endif -#if defined(CONFIG_SPI_MASTER) - spi_unregister_driver(&wm8994_spi_driver); -#endif + platform_driver_unregister(&wm8994_codec_driver); } module_exit(wm8994_exit); @@ -3338,3 +4159,4 @@ module_exit(wm8994_exit); MODULE_DESCRIPTION("ASoC WM8994 driver"); MODULE_AUTHOR("Mark Brown "); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:wm8994-codec"); diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h index f0f3922d3bb4..2e0ca67a8df7 100755 --- a/sound/soc/codecs/wm8994.h +++ b/sound/soc/codecs/wm8994.h @@ -1,50 +1,37 @@ /* - * Copyright 2005 Openedhand Ltd. - * - * Author: Richard Purdie - * - * Based on WM8994.h + * wm8994.h -- WM8994 Soc Audio driver * * 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 _WM8994_H #define _WM8994_H -/* WM8994 register space */ -#define WM8994_RESET 0x00 -#define wm8994_SYSCLK_3072M 0 -#define wm8994_SYSCLK_12288M 1 -#define wm8994_mic_VCC 0x0010 -#define WM8994_DELAY 50 +#include + +extern struct snd_soc_codec_device soc_codec_dev_wm8994; +extern struct snd_soc_dai wm8994_dai[]; /* Sources for AIF1/2 SYSCLK - use with set_dai_sysclk() */ -#define WM8994_SYSCLK_MCLK1 0 -#define WM8994_SYSCLK_MCLK2 1 -#define WM8994_SYSCLK_FLL1 2 -#define WM8994_SYSCLK_FLL2 3 +#define WM8994_SYSCLK_MCLK1 1 +#define WM8994_SYSCLK_MCLK2 2 +#define WM8994_SYSCLK_FLL1 3 +#define WM8994_SYSCLK_FLL2 4 + +/* OPCLK is also configured with set_dai_sysclk, specify division*10 as rate. */ +#define WM8994_SYSCLK_OPCLK 5 #define WM8994_FLL1 1 #define WM8994_FLL2 2 +#define WM8994_FLL_SRC_MCLK1 1 +#define WM8994_FLL_SRC_MCLK2 2 +#define WM8994_FLL_SRC_LRCLK 3 +#define WM8994_FLL_SRC_BCLK 4 -#define call_maxvol 5 //Sound level during a call -#define BT_call_maxvol 15 +int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, + int micbias, int det, int shrt); -#define MAX_MIN(min,value,max) value = ((value>max) ? max: value); \ - value = ((valuedev, "Waiting for DC servo...\n"); + dev_dbg(codec->dev, "Waiting for DC servo...\n"); do { count++; - msleep(10); + msleep(1); reg = snd_soc_read(codec, WM8993_DC_SERVO_0); - dev_vdbg(codec->dev, "DC servo: %x\n", reg); + dev_dbg(codec->dev, "DC servo: %x\n", reg); } while (reg & op && count < 400); if (reg & op) @@ -91,7 +91,7 @@ static void wait_for_dc_servo(struct snd_soc_codec *codec, unsigned int op) */ static void calibrate_dc_servo(struct snd_soc_codec *codec) { - struct wm_hubs_data *hubs = codec->private_data; + struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); u16 reg, reg_l, reg_r, dcs_cfg; /* Set for 32 series updates */ @@ -127,6 +127,8 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec) break; } + dev_dbg(codec->dev, "DCS input: %x %x\n", reg_l, reg_r); + /* HPOUT1L */ if (reg_l + hubs->dcs_codes > 0 && reg_l + hubs->dcs_codes < 0xff) @@ -139,6 +141,8 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec) reg_r += hubs->dcs_codes; dcs_cfg |= reg_r; + dev_dbg(codec->dev, "DCS result: %x\n", dcs_cfg); + /* Do it */ snd_soc_write(codec, WM8993_DC_SERVO_3, dcs_cfg); wait_for_dc_servo(codec, @@ -154,7 +158,7 @@ static int wm8993_put_dc_servo(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct wm_hubs_data *hubs = codec->private_data; + struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); int ret; ret = snd_soc_put_volsw_2r(kcontrol, ucontrol); @@ -289,7 +293,7 @@ SOC_DOUBLE_R("Speaker Switch", SOC_DOUBLE_R("Speaker ZC Switch", WM8993_SPEAKER_VOLUME_LEFT, WM8993_SPEAKER_VOLUME_RIGHT, 7, 1, 0), -SOC_DOUBLE_TLV("Speaker Boost Volume", WM8993_SPKOUT_BOOST, 0, 3, 7, 0, +SOC_DOUBLE_TLV("Speaker Boost Volume", WM8993_SPKOUT_BOOST, 3, 0, 7, 0, spkboost_tlv), SOC_ENUM("Speaker Reference", speaker_ref), SOC_ENUM("Speaker Mode", speaker_mode), @@ -327,7 +331,7 @@ static int hp_supply_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { struct snd_soc_codec *codec = w->codec; - struct wm_hubs_data *hubs = codec->private_data; + struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); switch (event) { case SND_SOC_DAPM_PRE_PMU: @@ -380,7 +384,7 @@ static int hp_event(struct snd_soc_dapm_widget *w, snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1, WM8993_HPOUT1L_ENA | WM8993_HPOUT1R_ENA, WM8993_HPOUT1L_ENA | WM8993_HPOUT1R_ENA); - // printk("hp_event power1 up: 0x%04x",snd_soc_read(codec,WM8993_POWER_MANAGEMENT_1)); + reg |= WM8993_HPOUT1L_DLY | WM8993_HPOUT1R_DLY; snd_soc_write(codec, WM8993_ANALOGUE_HP_0, reg); @@ -397,19 +401,20 @@ static int hp_event(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_PRE_PMD: snd_soc_update_bits(codec, WM8993_ANALOGUE_HP_0, - WM8993_HPOUT1L_DLY | - WM8993_HPOUT1R_DLY | + WM8993_HPOUT1L_OUTP | + WM8993_HPOUT1R_OUTP | WM8993_HPOUT1L_RMV_SHORT | WM8993_HPOUT1R_RMV_SHORT, 0); snd_soc_update_bits(codec, WM8993_ANALOGUE_HP_0, - WM8993_HPOUT1L_OUTP | - WM8993_HPOUT1R_OUTP, 0); + WM8993_HPOUT1L_DLY | + WM8993_HPOUT1R_DLY, 0); + + snd_soc_write(codec, WM8993_DC_SERVO_0, 0); snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1, WM8993_HPOUT1L_ENA | WM8993_HPOUT1R_ENA, 0); - // printk("hp_event power1 down: 0x%04x",snd_soc_read(codec,WM8993_POWER_MANAGEMENT_1)); break; } @@ -640,13 +645,6 @@ SND_SOC_DAPM_OUTPUT("LINEOUT2N"), }; static const struct snd_soc_dapm_route analogue_routes[] = { - { "IN1L PGA", NULL , "MICBIAS2" }, - { "IN1R PGA", NULL , "MICBIAS1" }, - { "MICBIAS2", NULL , "IN1LP"}, - { "MICBIAS2", NULL , "IN1LN"}, - { "MICBIAS1", NULL , "IN1RP"}, - { "MICBIAS1", NULL , "IN1RN"}, - { "IN1L PGA", "IN1LP Switch", "IN1LP" }, { "IN1L PGA", "IN1LN Switch", "IN1LN" }, @@ -709,12 +707,12 @@ static const struct snd_soc_dapm_route analogue_routes[] = { { "SPKL", "Input Switch", "MIXINL" }, { "SPKL", "IN1LP Switch", "IN1LP" }, - { "SPKL", "Output Switch", "Left Output PGA" }, + { "SPKL", "Output Switch", "Left Output Mixer" }, { "SPKL", NULL, "TOCLK" }, { "SPKR", "Input Switch", "MIXINR" }, { "SPKR", "IN1RP Switch", "IN1RP" }, - { "SPKR", "Output Switch", "Right Output PGA" }, + { "SPKR", "Output Switch", "Right Output Mixer" }, { "SPKR", NULL, "TOCLK" }, { "SPKL Boost", "Direct Voice Switch", "Direct Voice" }, @@ -736,8 +734,8 @@ static const struct snd_soc_dapm_route analogue_routes[] = { { "SPKOUTRP", NULL, "SPKR Driver" }, { "SPKOUTRN", NULL, "SPKR Driver" }, - { "Left Headphone Mux", "Mixer", "Left Output PGA" }, - { "Right Headphone Mux", "Mixer", "Right Output PGA" }, + { "Left Headphone Mux", "Mixer", "Left Output Mixer" }, + { "Right Headphone Mux", "Mixer", "Right Output Mixer" }, { "Headphone PGA", NULL, "Left Headphone Mux" }, { "Headphone PGA", NULL, "Right Headphone Mux" }, @@ -756,17 +754,17 @@ static const struct snd_soc_dapm_route analogue_routes[] = { static const struct snd_soc_dapm_route lineout1_diff_routes[] = { { "LINEOUT1 Mixer", "IN1L Switch", "IN1L PGA" }, { "LINEOUT1 Mixer", "IN1R Switch", "IN1R PGA" }, - { "LINEOUT1 Mixer", "Output Switch", "Left Output PGA" }, + { "LINEOUT1 Mixer", "Output Switch", "Left Output Mixer" }, { "LINEOUT1N Driver", NULL, "LINEOUT1 Mixer" }, { "LINEOUT1P Driver", NULL, "LINEOUT1 Mixer" }, }; static const struct snd_soc_dapm_route lineout1_se_routes[] = { - { "LINEOUT1N Mixer", "Left Output Switch", "Left Output PGA" }, - { "LINEOUT1N Mixer", "Right Output Switch", "Right Output PGA" }, + { "LINEOUT1N Mixer", "Left Output Switch", "Left Output Mixer" }, + { "LINEOUT1N Mixer", "Right Output Switch", "Left Output Mixer" }, - { "LINEOUT1P Mixer", "Left Output Switch", "Left Output PGA" }, + { "LINEOUT1P Mixer", "Left Output Switch", "Left Output Mixer" }, { "LINEOUT1N Driver", NULL, "LINEOUT1N Mixer" }, { "LINEOUT1P Driver", NULL, "LINEOUT1P Mixer" }, @@ -775,17 +773,17 @@ static const struct snd_soc_dapm_route lineout1_se_routes[] = { static const struct snd_soc_dapm_route lineout2_diff_routes[] = { { "LINEOUT2 Mixer", "IN2L Switch", "IN2L PGA" }, { "LINEOUT2 Mixer", "IN2R Switch", "IN2R PGA" }, - { "LINEOUT2 Mixer", "Output Switch", "Right Output PGA" }, + { "LINEOUT2 Mixer", "Output Switch", "Right Output Mixer" }, { "LINEOUT2N Driver", NULL, "LINEOUT2 Mixer" }, { "LINEOUT2P Driver", NULL, "LINEOUT2 Mixer" }, }; static const struct snd_soc_dapm_route lineout2_se_routes[] = { - { "LINEOUT2N Mixer", "Left Output Switch", "Left Output PGA" }, - { "LINEOUT2N Mixer", "Right Output Switch", "Right Output PGA" }, + { "LINEOUT2N Mixer", "Left Output Switch", "Left Output Mixer" }, + { "LINEOUT2N Mixer", "Right Output Switch", "Left Output Mixer" }, - { "LINEOUT2P Mixer", "Right Output Switch", "Right Output PGA" }, + { "LINEOUT2P Mixer", "Right Output Switch", "Right Output Mixer" }, { "LINEOUT2N Driver", NULL, "LINEOUT2N Mixer" }, { "LINEOUT2P Driver", NULL, "LINEOUT2P Mixer" }, @@ -803,21 +801,17 @@ int wm_hubs_add_analogue_controls(struct snd_soc_codec *codec) snd_soc_update_bits(codec, WM8993_RIGHT_LINE_INPUT_3_4_VOLUME, WM8993_IN2_VU, WM8993_IN2_VU); - snd_soc_update_bits(codec, WM8993_SPEAKER_VOLUME_LEFT, - WM8993_SPKOUT_VU, WM8993_SPKOUT_VU); snd_soc_update_bits(codec, WM8993_SPEAKER_VOLUME_RIGHT, WM8993_SPKOUT_VU, WM8993_SPKOUT_VU); snd_soc_update_bits(codec, WM8993_LEFT_OUTPUT_VOLUME, - WM8993_HPOUT1_VU | WM8993_HPOUT1L_ZC, - WM8993_HPOUT1_VU | WM8993_HPOUT1L_ZC); + WM8993_HPOUT1L_ZC, WM8993_HPOUT1L_ZC); snd_soc_update_bits(codec, WM8993_RIGHT_OUTPUT_VOLUME, WM8993_HPOUT1_VU | WM8993_HPOUT1R_ZC, WM8993_HPOUT1_VU | WM8993_HPOUT1R_ZC); snd_soc_update_bits(codec, WM8993_LEFT_OPGA_VOLUME, - WM8993_MIXOUTL_ZC | WM8993_MIXOUT_VU, - WM8993_MIXOUTL_ZC | WM8993_MIXOUT_VU); + WM8993_MIXOUTL_ZC, WM8993_MIXOUTL_ZC); snd_soc_update_bits(codec, WM8993_RIGHT_OPGA_VOLUME, WM8993_MIXOUTR_ZC | WM8993_MIXOUT_VU, WM8993_MIXOUTR_ZC | WM8993_MIXOUT_VU); @@ -877,8 +871,8 @@ int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *codec, /* If the line outputs are differential then we aren't presenting * VMID as an output and can disable it. */ -// if (lineout1_diff && lineout2_diff) -// codec->idle_bias_off = 1; + if (lineout1_diff && lineout2_diff) + codec->idle_bias_off = 1; if (lineout1fb) snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL, diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index 9cd101f57398..f6b0d2829ea9 100644 --- a/sound/soc/soc-cache.c +++ b/sound/soc/soc-cache.c @@ -285,7 +285,6 @@ static unsigned int snd_soc_8_16_read_i2c(struct snd_soc_codec *codec, xfer[0].flags = 0; xfer[0].len = 1; xfer[0].buf = ® - xfer[0].scl_rate = 100 * 1000; /* Read data */ xfer[1].addr = client->addr; -- 2.34.1