*.lzo
*.patch
*.gcno
-Untitled Project.*
#
# Top-level generic files
/System.map
/Module.markers
/Module.symvers
-/kernel.img
#
# git files that we don't want to ignore even it they are dot-files
include/config
include/linux/version.h
include/generated
-include/asm-arm/mach-types.h
# stgit generated dirs
patches-*
* 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
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);
}
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);
}
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);
}
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,
#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)
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.
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
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
* 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
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
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
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
source "drivers/spi/Kconfig"
-source "drivers/adc/Kconfig"
-
-source "drivers/headset_observe/Kconfig"
-
source "drivers/pps/Kconfig"
source "drivers/gpio/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
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/
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/
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/
-
#include <linux/sched.h>
#include <linux/async.h>
#include <linux/timer.h>
-#ifdef CONFIG_ARCH_RK29
-#include <linux/console.h>
-#endif
#include "../base.h"
#include "power.h"
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);
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
#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)
spin_lock_irqsave(&gpio_lock, flags);
- if (value !=0 && value !=1)
- goto fail;
if (!gpio_is_valid(gpio))
goto fail;
chip = desc->chip;
}
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
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;
{
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);
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);
+++ /dev/null
-/*
- * tps65910_gpio.c -- access to GPIOs on TPS65910x chips
- *
- * Copyright (C) 2010 Mistral solutions Pvt Ltd <www.mistralsolutions.com>
- *
- * 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 <linux/module.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/kthread.h>
-#include <linux/irq.h>
-#include <linux/gpio.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-
-#include <linux/i2c/tps65910.h>
-
-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");
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/
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
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
# 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
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
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
-
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
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"
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
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
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/
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/
+++ /dev/null
-/*
-o* Driver for MT9M001 CMOS Image Sensor from Micron
- *
- * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/videodev2.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/log2.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/circ_buf.h>
-#include <linux/miscdevice.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/soc_camera.h>
-#include <mach/rk29_camera.h>
-
-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) ((x<y) ? x: y)
-#define MAX(x,y) ((x>y) ? 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; i<ext_ctrl->count; 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; i<ext_ctrl->count; 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 <kernel@rock-chips>");
-MODULE_LICENSE("GPL");
-
-
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) {
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,
ret = soc_camera_set_fmt(icf, &f);
if (ret < 0)
goto esfmt;
- }
}
file->private_data = icf;
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);
{
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] && (i<VIDEO_MAX_FRAME)) {
- if (icf->vb_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);
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)
{
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);
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);
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);
/*
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;
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)
{
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; i<ctrl->count; 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)
{
.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,
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;
}
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);
}
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);
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);
int is_ext_ctrl;
size_t ctrls_size = 0;
void __user *user_ptr = NULL;
-
+
#ifdef __OLD_VIDIOC_
cmd = video_fix_command(cmd);
#endif
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
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
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
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
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/i2c.h>
#include <linux/bcd.h>
#include <linux/delay.h>
#include <linux/mfd/core.h>
#include <linux/slab.h>
-#include <linux/irq.h>
#include <linux/mfd/wm831x/core.h>
#include <linux/mfd/wm831x/pdata.h>
#include <linux/mfd/wm831x/auxadc.h>
#include <linux/mfd/wm831x/otp.h>
#include <linux/mfd/wm831x/regulator.h>
-#include <linux/mfd/wm831x/pmu.h>
-
/* 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,
};
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)
* 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;
.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[] = {
/*
* 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;
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;
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;
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;
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:
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;
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);
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
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");
+++ /dev/null
-/*
- * wm831x-i2c.c -- I2C access for Wolfson WM831x PMICs
- *
- * Copyright 2009,2010 Wolfson Microelectronics PLC.
- *
- * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/i2c.h>
-#include <linux/delay.h>
-#include <linux/mfd/core.h>
-#include <linux/slab.h>
-#include <linux/gpio.h>
-
-#include <linux/mfd/wm831x/core.h>
-#include <linux/mfd/wm831x/pdata.h>
-
-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);
#include <linux/mfd/wm831x/irq.h>
#include <linux/delay.h>
-#include <linux/wakelock.h>
+
/*
* Since generic IRQs don't currently support interrupt controllers on
* interrupt driven buses we don't use genirq but instead provide an
* 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;
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,
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)
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)
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;
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) {
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
dev_err(wm831x->dev,
"Failed to read IRQ status: %d\n",
*status);
- goto out_lock;
+ goto out;
}
read[offset] = 1;
/* 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;
}
{
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 */
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;
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);
+++ /dev/null
-/*
- * wm831x-spi.c -- SPI access for Wolfson WM831x PMICs
- *
- * Copyright 2009,2010 Wolfson Microelectronics PLC.
- *
- * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/spi/spi.h>
-#include <linux/gpio.h>
-
-
-#include <linux/mfd/wm831x/core.h>
-
-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");
{ .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,
+ },
};
/*
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)
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];
if (pdata) {
+ wm8994->irq_base = pdata->irq_base;
wm8994->gpio_base = pdata->gpio_base;
/* GPIO configuration is only applied if it's non-zero */
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);
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);
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);
}
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
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"
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
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;
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;
schedule();
remove_wait_queue(&wait_q, &wait);
}
-#endif
printk(KERN_DEBUG "apanic: %s partition erased\n",
CONFIG_APANIC_PLABEL);
out:
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;
}
}
}
-#ifndef CONFIG_MTD_RKNAND
if (!proc_entry_created)
mtd_panic_erase();
-#endif
return;
out_err:
printk(KERN_EMERG "Crash partition in use!\n");
goto out;
}
- console_offset = ctx->mtd->erasesize;
+ console_offset = ctx->mtd->writesize;
/*
* Write out the console
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
}
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;
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;
#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
*/
{
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);
ret = -EROFS;
}
}
-#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD)
- mutex_unlock(&block_mutex);
-#else
unlock_kernel();
-#endif
-
return ret;
}
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;
}
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;
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)
{
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;
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
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;
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);
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),
}
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;
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;
}
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
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)) {
*/
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;
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);
}
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 =
* release the lock here.
*/
mmc_bus_put(host);
-
+
if (host->ops->get_cd && host->ops->get_cd(host) == 0)
goto out;
mmc_power_up(host);
sdio_reset(host);
mmc_go_idle(host);
-
+
mmc_send_if_cond(host, host->ocr_avail);
/*
if (host->caps & MMC_CAP_NEEDS_POLL)
mmc_schedule_delayed_work(&host->detect, HZ);
}
-#endif
void mmc_start_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 "
mmc_hostname(host), err);
err = 0;
}
-#endif
}
mmc_bus_put(host);
/* 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.
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;
}
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);
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;
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);
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
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;
}
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;
}
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;
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
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;
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;
*/
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;
- }
}
/*
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);
}
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);
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
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 <file:Documentation/networking/ray_cs.txt> 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
+ <http://www.thekelleys.org.uk/atmel>
+
+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
#
# 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/
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.
-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 \
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) */
{
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 */
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)
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);
}
}
if (func->num == 2) {
sd_trace(("F2 found, calling bcmsdh_probe...\n"));
- ret = bcmsdh_probe(&sdmmc_dev);
+ ret = bcmsdh_probe(&func->dev);
}
return ret;
if (func->num == 2) {
sd_trace(("F2 found, calling bcmsdh_remove...\n"));
- bcmsdh_remove(&sdmmc_dev);
+ bcmsdh_remove(&func->dev);
}
}
if (!gInstance)
return -ENOMEM;
- bzero(&sdmmc_dev, sizeof(sdmmc_dev));
error = sdio_register_driver(&bcmsdh_sdmmc_driver);
-
return error;
}
{
sd_trace(("%s Enter\n", __FUNCTION__));
-
sdio_unregister_driver(&bcmsdh_sdmmc_driver);
if (gInstance)
* 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 $
*/
/****************
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;
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)
#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);
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_ */
#include <dhd_bus.h>
#include <dhd_dbg.h>
-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) */
return ret;
}
memcpy(dhd->mac.octet, buf, ETHER_ADDR_LEN);
- memcpy(wlan_mac_addr, buf, ETHER_ADDR_LEN);
dhd_os_proto_unblock(dhd);
* 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 <typedefs.h>
#include <osl.h>
#include <wlioctl.h>
-#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 <linux/random.h>
#include <linux/jiffies.h>
}
#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)
{
}
#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__));
}
}
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))) {
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) {
/* 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];
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;
}
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);
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));
}
* 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 $
*/
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)
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
+}
* 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
#include <linux/ethtool.h>
#include <linux/fcntl.h>
#include <linux/fs.h>
+#include <linux/inetdevice.h>
#include <asm/uaccess.h>
#include <asm/unaligned.h>
-#include <wifi_version.h>
#include <epivers.h>
#include <bcmutils.h>
#include <bcmendian.h>
#include <linux/wakelock.h>
#endif
#if defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC)
-//#include <linux/wlan_plat.h>
-#include <mach/board.h>
+#include <linux/wlan_plat.h>
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;
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 =
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;
}
}
#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 <linux/suspend.h>
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))
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;
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)
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;
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)) {
up(&dhd->sysioc_sem);
}
+
dhd_pub_t *
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:
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;
}
}
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)
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;
}
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));
};
#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)
{
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
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);
}
}
-void
-rockchip_wifi_exit_module(void)
+static void __exit
+dhd_module_cleanup(void)
{
DHD_TRACE(("%s: Enter\n", __FUNCTION__));
#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 */
goto fail_2;
}
#endif
- bcm4329_power_save_init();
-
return error;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
fail_2:
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
/* 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 */
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;
}
#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);
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);
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
#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
* 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 $
*/
#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 {
#define PM_MAX 1
#define PM_FAST 2
-#define LISTEN_INTERVAL 20
+#define LISTEN_INTERVAL 10
#define INTERFERE_NONE 0
#define NON_WLAN 1
#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
int32 lost_network_timeout;
int16 flags;
int16 rssi_margin;
+ int32 repeat_scan;
+ int32 max_freq_adjust;
} wl_pfn_param_t;
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
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;
* 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 $
*/
#define WL_INFORM(x)
#define WL_WSEC(x)
#define WL_SCAN(x)
+#define WL_PNO(x)
#define WL_TRACE_COEX(x)
#include <wl_iw.h>
-#include <linux/wakelock.h>
+
#ifndef IW_ENCODE_ALG_SM4
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 <bcmsdbus.h>
#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;
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,
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(
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:
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(
#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;
}
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)
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;
'G', 'O', 'O', 'G',
'T',
'1','E',
+ 'R',
+ '2',
+ 'M',
+ '2',
0x00
};
#endif
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) && \
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 {
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);
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)
{
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;
}
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", \
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;
}
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",
}
#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,
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__));
}
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)
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);
#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);
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) {
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));
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)) {
goto wl_iw_event_end;
}
}
+#endif
break;
case WLC_E_DEAUTH_IND:
case WLC_E_DISASSOC_IND:
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"));
* 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 $
*/
#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"
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
} 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 {
};
-#define MACLIST_MODE_DISABLED 0
+#define MACLIST_MODE_DISABLED 0
#define MACLIST_MODE_DENY 1
#define MACLIST_MODE_ALLOW 2
struct mflist {
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);
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'
#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;
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 {
extern int wl_iw_parse_channel_list(char** list_str, uint16* channel_list, int channel_num);
-#endif
+#endif
-#endif
+#endif
#include <linux/mfd/wm831x/auxadc.h>
#include <linux/mfd/wm831x/pmu.h>
#include <linux/mfd/wm831x/pdata.h>
-#include <linux/mfd/wm831x/irq.h>
-
-#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)
{
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
{ 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;
{
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,
reg1 = 0;
reg2 = 0;
- reg3 = 0;
if (!pdata->enable) {
dev_info(wm831x->dev, "Battery charger disabled\n");
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);
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 |
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);
}
if (ret < 0)
return ret;
-
switch (ret & WM831X_CHG_STATE_MASK) {
case WM831X_CHG_STATE_OFF:
*status = POWER_SUPPLY_STATUS_NOT_CHARGING;
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)
{
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;
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",
{
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
/* 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;
}
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);
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",
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]);
}
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);
{
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);
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);
}
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 <broonie@opensource.wolfsonmicro.com>");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:wm831x-power");
-
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
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
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 */
+++ /dev/null
-/*
- * tps65910-regulator.c -- support regulators in tps65910x family chips
- *
- *
- * Copyright (C) 2010 Mistral Solutions Pvt Ltd <www.mistralsolutions.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation 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 <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/err.h>
-#include <linux/delay.h>
-#include <linux/platform_device.h>
-#include <linux/regulator/driver.h>
-#include <linux/regulator/machine.h>
-#include <linux/i2c/tps65910.h>
-
-#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 <cwz@rock-chips.com>");
-MODULE_DESCRIPTION("TPS65910 voltage regulator driver");
-MODULE_LICENSE("GPL");
#include <linux/mfd/wm831x/regulator.h>
#include <linux/mfd/wm831x/pdata.h>
-#include <linux/delay.h>
-#include <linux/time.h>
-#include <linux/timer.h>
-#include <linux/string.h>
-
-//#include "../../arch/arm/mach-rk29/include/mach/gpio.h"
-
-//#include <linux/hrtimer.h>
-
-
-
-
#define WM831X_BUCKV_MAX_SELECTOR 0x68
#define WM831X_BUCKP_MAX_SELECTOR 0x66
#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
/*
* Shared
*/
-#if 0
+
struct wm831x_dcdc {
char name[WM831X_DCDC_MAX_NAME];
struct regulator_desc desc;
int on_vsel;
int dvs_vsel;
};
-#endif
static int wm831x_dcdc_is_enabled(struct regulator_dev *rdev)
{
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)
{
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)
{
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,
.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,
};
/*
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)
.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)
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);
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);
#include <linux/mfd/wm831x/regulator.h>
#include <linux/mfd/wm831x/pdata.h>
-//#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;
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);
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;
}
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;
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;
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;
}
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);
#include <linux/mfd/wm831x/regulator.h>
#include <linux/mfd/wm831x/pdata.h>
-//#define WM831X_LDO_MAX_NAME 6
+#define WM831X_LDO_MAX_NAME 6
#define WM831X_LDO_CONTROL 0
#define WM831X_LDO_ON_CONTROL 1
#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;
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);
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);
}
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);
}
{
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);
}
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);
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,
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,
.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)
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;
{
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);
}
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);
}
.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)
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;
.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)
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;
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,
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);
if (ret != 0)
pr_err("Failed to register WM831x alive LDO driver: %d\n",
ret);
- return 0;
+
+ return 0;
}
subsys_initcall(wm831x_ldo_init);
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
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
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
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
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
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
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);
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);
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
};
static struct platform_driver alarm_driver = {
.suspend = alarm_suspend,
.resume = alarm_resume,
- .shutdown = alarm_shutdown,
.driver = {
.name = "alarm"
}
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
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
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"
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/
#include <linux/hrtimer.h>
#include <linux/err.h>
#include <linux/gpio.h>
-#include <linux/wakelock.h>
-#include <linux/delay.h>
+
#include "timed_output.h"
#include "timed_gpio.h"
-#define GPIO_TYPE 0
struct timed_gpio_data {
struct timed_output_dev dev;
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;
}
{
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)
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;
}
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 <lockwood@android.com>");
unsigned gpio;
int max_timeout;
u8 active_low;
- int adjust_time;
};
struct timed_gpio_platform_data {
obj-$(CONFIG_USB_ATM) += atm/
obj-$(CONFIG_USB_SPEEDTOUCH) += atm/
-obj-$(CONFIG_DWC_OTG) += dwc_otg/
-obj-$(CONFIG_USB_GADGET) += gadget/
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.
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
# 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
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;
{
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))
.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 = {
#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 <linux/power_supply.h>
-#include <linux/reboot.h>
-#include <linux/syscalls.h>
-
-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"
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) {
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 */
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;
}
-#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;
int reply = -EINVAL;
int i;
static char unknown[16];
-#ifdef CONFIG_ARCH_RK29
- struct fsg_common *fsg = common;
-#endif
dump_cdb(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:
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);
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);
}
#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)
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 = {
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;
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
#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 */
#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 */
#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,
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) },
{ 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) },
{ 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) },
{ 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 */
#include <linux/mfd/wm831x/core.h>
#include <linux/mfd/wm831x/pdata.h>
#include <linux/mfd/wm831x/regulator.h>
-#ifdef CONFIG_HAS_EARLYSUSPEND
-#include <linux/earlysuspend.h>
-#endif
-#include <linux/delay.h>
-#include <linux/ktime.h>
-#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,
/* 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;
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;
if (bl->props.state & BL_CORE_SUSPENDED)
brightness = 0;
- printk("backlight brightness=%d\n", brightness);
-
return wm831x_backlight_set(bl, brightness);
}
.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)
{
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",
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)) {
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;
}
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",
},
.probe = wm831x_backlight_probe,
.remove = wm831x_backlight_remove,
- .shutdown = wm831x_backlight_shutdown,
};
static int __init wm831x_backlight_init(void)
*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;
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;
}
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;
}
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;
}
}
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;
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;
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++;
}
* 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);
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)
struct device_node *of_node;
#endif
int irq;
- int udelay; //add by kfx
};
/**
#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 */
#include <linux/completion.h>
#include <linux/interrupt.h>
-#include <linux/wakelock.h>
-#include <linux/regulator/driver.h>
/*
* Register values.
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;
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 */
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,
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);
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**/
};
/**
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
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;
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];
#ifndef __MFD_WM8994_CORE_H__
#define __MFD_WM8994_CORE_H__
+#include <linux/interrupt.h>
+
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,
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];
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
#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
u16 regs[WM8994_EQ_REGS];
};
-#define PCM_BB 1
-#define NO_PCM_BB 0
-
struct wm8994_pdata {
int gpio_base;
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;
/* 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
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)
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);
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;
* number of jiffies until all active wake locks time out.
*/
long has_wake_lock(int type);
-void print_active_wake_locks(int type);
#else
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
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,
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,
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,
/* 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! */
};
#include <linux/syscalls.h> /* sys_sync */
#include <linux/wakelock.h>
#include <linux/workqueue.h>
-#include <linux/kallsyms.h>
#include "power.h"
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);
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);
}
}
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:
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");
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)
}
/* 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;
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;
}
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;
}
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);
#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;
}
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);
}
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
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/unistd.h>
-/***************
-* 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)
*/
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);
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;
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;
break;
}
buffer[sizeof(buffer) - 1] = '\0';
- /*
- * debug trace
- */
- restart_dbg("%s->%d->cmd=%x args=%s",__FUNCTION__,__LINE__,cmd,buffer);
-
+
kernel_restart(buffer);
break;
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
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
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
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
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
config SND_SOC_WM8990
tristate
-config SND_SOC_CS42L52
- tristate
-
config SND_SOC_WM8993
tristate
config SND_SOC_WM9713
tristate
-config SND_SOC_RK1000
- tristate
- depends on RK1000_CONTROL
+
# Amp
config SND_SOC_MAX9877
tristate
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
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
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
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
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
#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
-#include <mach/gpio.h>
-#include <mach/irqs.h>
-#include <mach/rk29_iomap.h>
#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
#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
#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;
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,
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)) {
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;
}
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;
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;
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);
}
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);
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);
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 | \
.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 = {
{
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 */
WM8900_REG_POWER2_SYSCLK_ENA);
break;
}
-
codec->bias_level = level;
return 0;
}
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) {
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;
}
}
-#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)
{
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;
/* 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;
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);
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 },
{ }
},
.probe = wm8900_i2c_probe,
.remove = __devexit_p(wm8900_i2c_remove),
- .shutdown = wm8900_i2c_shutdown,
.id_table = wm8900_i2c_id,
};
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;
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;
#include <sound/soc-dapm.h>
#include <sound/initval.h>
-#include <mach/iomux.h>
-#include <mach/gpio.h>
-
#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
else
adctl2 |= 0x4;
- DBG("Enter::%s----%d, adctl2 = %x\n",__FUNCTION__,__LINE__,adctl2);
-
return snd_soc_write(codec, WM8988_ADCTL2, adctl2);
}
return -EINVAL;
}
- DBG("Enter::%s----%d iface=%x\n",__FUNCTION__,__LINE__,iface);
snd_soc_write(codec, WM8988_IFACE, iface);
return 0;
}
/* 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");
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));
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);
{
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
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;
{
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;
}
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)
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);
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);
/*
- * 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 <broonie@opensource.wolfsonmicro.com>
*
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
-#include <linux/spi/spi.h>
#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
-#include <sound/tlv.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>
#include <sound/initval.h>
-#include <linux/wakelock.h>
-#include <linux/earlysuspend.h>
-
-#include <mach/iomux.h>
-#include <mach/gpio.h>
+#include <sound/tlv.h>
-#include "wm8994.h"
-#include <linux/miscdevice.h>
-#include <linux/circ_buf.h>
#include <linux/mfd/wm8994/core.h>
#include <linux/mfd/wm8994/registers.h>
#include <linux/mfd/wm8994/pdata.h>
#include <linux/mfd/wm8994/gpio.h>
-#define WM8994_PROC
-#ifdef WM8994_PROC
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/vmalloc.h>
-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<null&&
- 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;
}
{
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_value<SPEAKER_INCALL || kcontrol.private_value>HEADSET_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_value<SPEAKER_INCALL || kcontrol.private_value>HEADSET_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");
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)
};
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);
MODULE_DESCRIPTION("ASoC WM8994 driver");
MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:wm8994-codec");
/*
- * Copyright 2005 Openedhand Ltd.
- *
- * Author: Richard Purdie <richard@openedhand.com>
- *
- * 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 <sound/soc.h>
+
+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 = ((value<min) ? min: value)
-
-extern struct snd_soc_dai wm8994_dai;
-extern struct snd_soc_codec_device soc_codec_dev_wm8994;
-extern int Headset_isMic(void);
-#define ERROR 1
-#define TRUE 0
-
-#define SUSPEND 3
-#define POWER_ON 2
-#define BUSY 1
-#define IDLE 0
#endif
/* Trigger the command */
snd_soc_write(codec, WM8993_DC_SERVO_0, val);
- dev_vdbg(codec->dev, "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)
*/
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 */
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)
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,
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);
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),
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:
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);
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;
}
};
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" },
{ "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" },
{ "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" },
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" },
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" },
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);
/* 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,
xfer[0].flags = 0;
xfer[0].len = 1;
xfer[0].buf = ®
- xfer[0].scl_rate = 100 * 1000;
/* Read data */
xfer[1].addr = client->addr;