summaryrefslogtreecommitdiff
path: root/sound/soc/codecs
diff options
context:
space:
mode:
authorNikesh Oswal <noswal@nvidia.com>2012-02-03 20:17:20 +0530
committerLokesh Pathak <lpathak@nvidia.com>2012-02-23 05:03:40 -0800
commit93028b36f893720e7e28a5cc73dc8bfc9bdad7da (patch)
tree9e9ba3fd51095e083d1f023944e07552b1c1add6 /sound/soc/codecs
parent1e48d5c5edce59e3e183ead2f14a11579695f7a0 (diff)
sound: soc: codecs: update the TI codec driver for K39
Change-Id: If40c181227981696961d3c563008261e5324e807 Signed-off-by: Nikesh Oswal <noswal@nvidia.com> Reviewed-on: http://git-master/r/84528 Reviewed-by: Scott Peterson <speterson@nvidia.com>
Diffstat (limited to 'sound/soc/codecs')
-rw-r--r--sound/soc/codecs/Makefile2
-rw-r--r--sound/soc/codecs/aic326x_tiload.c312
-rw-r--r--sound/soc/codecs/aic326x_tiload.h36
-rw-r--r--sound/soc/codecs/tlv320aic326x.c1775
-rw-r--r--sound/soc/codecs/tlv320aic326x.h35
-rw-r--r--sound/soc/codecs/tlv320aic326x_mini-dsp.c17
-rw-r--r--sound/soc/codecs/tlv320aic326x_mini-dsp.h4
-rw-r--r--sound/soc/codecs/tlv320aic326x_minidsp_config.c13
8 files changed, 1539 insertions, 655 deletions
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index b29e2ab6dd7b..2eaef5b52e08 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -36,7 +36,7 @@ snd-soc-tlv320aic23-objs := tlv320aic23.o
snd-soc-tlv320aic26-objs := tlv320aic26.o
snd-soc-tlv320aic3x-objs := tlv320aic3x.o
snd-soc-tlv320aic326x-objs := tlv320aic326x.o tlv320aic326x_minidsp_config.o
-snd-soc-tlv320aic326x-objs += tlv320aic326x_mini-dsp.o
+snd-soc-tlv320aic326x-objs += tlv320aic326x_mini-dsp.o aic326x_tiload.o
snd-soc-tlv320aic32x4-objs := tlv320aic32x4.o
snd-soc-tlv320dac33-objs := tlv320dac33.o
snd-soc-twl4030-objs := twl4030.o
diff --git a/sound/soc/codecs/aic326x_tiload.c b/sound/soc/codecs/aic326x_tiload.c
new file mode 100644
index 000000000000..00aa4d4ce7d7
--- /dev/null
+++ b/sound/soc/codecs/aic326x_tiload.c
@@ -0,0 +1,312 @@
+/*
+ * linux/sound/soc/codecs/AIC3262_tiload.c
+ *
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ *
+ *
+ *
+ * This package 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.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * History:
+ *
+ * Rev 0.1 Tiload support 16-09-2010
+ *
+ * The Tiload programming support is added to AIC3262.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/types.h>
+#include <linux/kdev_t.h>
+#include <linux/cdev.h>
+#include <linux/device.h>
+#include <asm/io.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/platform_device.h>
+#include <sound/soc.h>
+#include <sound/control.h>
+
+#include "tlv320aic326x.h"
+#include "aic326x_tiload.h"
+
+/* enable debug prints in the driver */
+#define DEBUG
+//#undef DEBUG
+
+#ifdef DEBUG
+#define dprintk(x...) printk(x)
+#else
+#define dprintk(x...)
+#endif
+
+#ifdef AIC3262_TiLoad
+
+/* Function prototypes */
+#ifdef REG_DUMP_aic3262
+static void aic3262_dump_page(struct i2c_client *i2c, u8 page);
+#endif
+
+/* externs */
+extern int aic3262_change_page(struct snd_soc_codec *codec, u8 new_page);
+extern int aic3262_change_book(struct snd_soc_codec *codec, u8 new_book);
+extern int aic3262_write(struct snd_soc_codec *codec, u16 reg, u8 value);
+int aic3262_driver_init(struct snd_soc_codec *codec);
+/************** Dynamic aic3262 driver, TI LOAD support ***************/
+
+static struct cdev *aic3262_cdev;
+static int aic3262_major = 0; /* Dynamic allocation of Mjr No. */
+static int aic3262_opened = 0; /* Dynamic allocation of Mjr No. */
+static struct snd_soc_codec *aic3262_codec;
+struct class *tiload_class;
+static unsigned int magic_num = 0xE0;
+
+/******************************** Debug section *****************************/
+
+#ifdef REG_DUMP_aic3262
+/*
+ *----------------------------------------------------------------------------
+ * Function : aic3262_dump_page
+ * Purpose : Read and display one codec register page, for debugging purpose
+ *----------------------------------------------------------------------------
+ */
+static void aic3262_dump_page(struct i2c_client *i2c, u8 page)
+{
+ int i;
+ u8 data;
+ u8 test_page_array[8];
+
+ dprintk("TiLoad DRIVER : %s\n", __FUNCTION__);
+ aic3262_change_page(codec, page);
+
+ data = 0x0;
+
+ i2c_master_send(i2c, data, 1);
+ i2c_master_recv(i2c, test_page_array, 8);
+
+ printk("\n------- aic3262 PAGE %d DUMP --------\n", page);
+ for (i = 0; i < 8; i++) {
+ printk(" [ %d ] = 0x%x\n", i, test_page_array[i]);
+ }
+}
+#endif
+
+/*
+ *----------------------------------------------------------------------------
+ * Function : tiload_open
+ *
+ * Purpose : open method for aic3262-tiload programming interface
+ *----------------------------------------------------------------------------
+ */
+static int tiload_open(struct inode *in, struct file *filp)
+{
+ dprintk("TiLoad DRIVER : %s\n", __FUNCTION__);
+ if (aic3262_opened) {
+ printk("%s device is already opened\n", "aic3262");
+ printk("%s: only one instance of driver is allowed\n",
+ "aic3262");
+ return -1;
+ }
+ aic3262_opened++;
+ return 0;
+}
+
+/*
+ *----------------------------------------------------------------------------
+ * Function : tiload_release
+ *
+ * Purpose : close method for aic3262_tilaod programming interface
+ *----------------------------------------------------------------------------
+ */
+static int tiload_release(struct inode *in, struct file *filp)
+{
+ dprintk("TiLoad DRIVER : %s\n", __FUNCTION__);
+ aic3262_opened--;
+ return 0;
+}
+
+/*
+ *----------------------------------------------------------------------------
+ * Function : tiload_read
+ *
+ * Purpose : read method for mini dsp programming interface
+ *----------------------------------------------------------------------------
+ */
+static ssize_t tiload_read(struct file *file, char __user * buf,
+ size_t count, loff_t * offset)
+{
+ static char rd_data[8];
+ char reg_addr;
+ size_t size;
+ #ifdef DEBUG
+ int i;
+ #endif
+ struct i2c_client *i2c = aic3262_codec->control_data;
+
+ dprintk("TiLoad DRIVER : %s\n", __FUNCTION__);
+ if (count > 128) {
+ printk("Max 128 bytes can be read\n");
+ count = 128;
+ }
+
+ /* copy register address from user space */
+ size = copy_from_user(&reg_addr, buf, 1);
+ if (size != 0) {
+ printk("read: copy_from_user failure\n");
+ return -1;
+ }
+ /* Send the address to device thats is to be read */
+
+ if (i2c_master_send(i2c, &reg_addr, 1) != 1) {
+ dprintk("Can not write register address\n");
+ return -1;
+ }
+ /* read the codec device registers */
+ size = i2c_master_recv(i2c, rd_data, count);
+#ifdef DEBUG
+ printk(KERN_ERR "read size = %d, reg_addr= %x , count = %d\n",
+ (int)size, reg_addr, (int)count);
+ for (i = 0; i < (int)size; i++) {
+ printk(KERN_ERR "rd_data[%d]=%x\n", i, rd_data[i]);
+ }
+#endif
+ if (size != count) {
+ printk("read %d registers from the codec\n", size);
+ }
+
+ if (copy_to_user(buf, rd_data, size) != 0) {
+ dprintk("copy_to_user failed\n");
+ return -1;
+ }
+
+ return size;
+}
+
+/*
+ *----------------------------------------------------------------------------
+ * Function : tiload_write
+ *
+ * Purpose : write method for aic3262_tiload programming interface
+ *----------------------------------------------------------------------------
+ */
+static ssize_t tiload_write(struct file *file, const char __user * buf,
+ size_t count, loff_t * offset)
+{
+ static char wr_data[8];
+ u8 pg_no;
+ #ifdef DEBUG
+ int i;
+ #endif
+ struct i2c_client *i2c = aic3262_codec->control_data;
+ struct aic3262_priv *aic3262_private = snd_soc_codec_get_drvdata(aic3262_codec);
+
+ dprintk("TiLoad DRIVER : %s\n", __FUNCTION__);
+ /* copy buffer from user space */
+ if (copy_from_user(wr_data, buf, count)) {
+ printk("copy_from_user failure\n");
+ return -1;
+ }
+#ifdef DEBUG
+ printk(KERN_ERR "write size = %d\n", (int)count);
+ for (i = 0; i < (int)count; i++) {
+ printk(KERN_INFO "\nwr_data[%d]=%x\n", i, wr_data[i]);
+ }
+#endif
+ if (wr_data[0] == 0) {
+ aic3262_change_page(aic3262_codec, wr_data[1]);
+ return count;
+ }
+ pg_no = aic3262_private->page_no;
+
+ if ((wr_data[0] == 127) && (pg_no == 0)) {
+ aic3262_change_book(aic3262_codec, wr_data[1]);
+ return count;
+ }
+ return i2c_master_send(i2c, wr_data, count);
+}
+
+static int tiload_ioctl( struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ int num = 0;
+ void __user *argp = (void __user *)arg;
+ if (_IOC_TYPE(cmd) != aic3262_IOC_MAGIC)
+ return -ENOTTY;
+
+ dprintk("TiLoad DRIVER : %s\n", __FUNCTION__);
+ switch (cmd) {
+ case aic3262_IOMAGICNUM_GET:
+ num = copy_to_user(argp, &magic_num, sizeof(int));
+ break;
+ case aic3262_IOMAGICNUM_SET:
+ num = copy_from_user(&magic_num, argp, sizeof(int));
+ break;
+ }
+ return num;
+}
+
+/*********** File operations structure for aic3262-tiload programming *************/
+static struct file_operations aic3262_fops = {
+ .owner = THIS_MODULE,
+ .open = tiload_open,
+ .release = tiload_release,
+ .read = tiload_read,
+ .write = tiload_write,
+ .unlocked_ioctl = tiload_ioctl,
+};
+
+/*
+ *----------------------------------------------------------------------------
+ * Function : aic3262_driver_init
+ *
+ * Purpose : Register a char driver for dynamic aic3262-tiload programming
+ *----------------------------------------------------------------------------
+ */
+int aic3262_driver_init(struct snd_soc_codec *codec)
+{
+ int result;
+
+ dev_t dev = MKDEV(aic3262_major, 0);
+ printk("TiLoad DRIVER : %s\n", __FUNCTION__);
+ aic3262_codec = codec;
+
+ printk("allocating dynamic major number\n");
+
+ result = alloc_chrdev_region(&dev, 0, 1, DEVICE_NAME);
+ if (result < 0) {
+ printk("cannot allocate major number %d\n", aic3262_major);
+ return result;
+ }
+ tiload_class = class_create(THIS_MODULE, DEVICE_NAME);
+ aic3262_major = MAJOR(dev);
+ printk("allocated Major Number: %d\n", aic3262_major);
+
+ aic3262_cdev = cdev_alloc();
+ cdev_init(aic3262_cdev, &aic3262_fops);
+ aic3262_cdev->owner = THIS_MODULE;
+ aic3262_cdev->ops = &aic3262_fops;
+
+ if (cdev_add(aic3262_cdev, dev, 1) < 0) {
+ dprintk("aic3262_driver: cdev_add failed \n");
+ unregister_chrdev_region(dev, 1);
+ aic3262_cdev = NULL;
+ return 1;
+ }
+ printk("Registered aic3262 TiLoad driver, Major number: %d \n",
+ aic3262_major);
+ //class_device_create(tiload_class, NULL, dev, NULL, DEVICE_NAME, 0);
+ return 0;
+}
+
+#endif
diff --git a/sound/soc/codecs/aic326x_tiload.h b/sound/soc/codecs/aic326x_tiload.h
new file mode 100644
index 000000000000..6621a4127b16
--- /dev/null
+++ b/sound/soc/codecs/aic326x_tiload.h
@@ -0,0 +1,36 @@
+/*
+ * linux/sound/soc/codecs/aic3262_tiload.h
+ *
+ *
+ * Copyright (C) 2012 Texas Instruments, Inc.
+ *
+ *
+ *
+ * This package 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.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * History:
+ *
+ *
+ *
+ *
+ */
+
+#ifndef _AIC3262_TILOAD_H
+#define _AIC3262_TILOAD_H
+
+/* typedefs required for the included header files */
+typedef char *string;
+
+/* defines */
+#define DEVICE_NAME "tiload_node"
+#define aic3262_IOC_MAGIC 0xE0
+#define aic3262_IOMAGICNUM_GET _IOR(aic3262_IOC_MAGIC, 1, int)
+#define aic3262_IOMAGICNUM_SET _IOW(aic3262_IOC_MAGIC, 2, int)
+
+#endif
diff --git a/sound/soc/codecs/tlv320aic326x.c b/sound/soc/codecs/tlv320aic326x.c
index 9f1874328b28..0d51b837463a 100644
--- a/sound/soc/codecs/tlv320aic326x.c
+++ b/sound/soc/codecs/tlv320aic326x.c
@@ -1,7 +1,7 @@
/*
* linux/sound/soc/codecs/tlv320aic3262.c
*
-* Copyright (C) 2011 Mistral Solutions Pvt Ltd.
+* Copyright (C) 2012 Texas Instruments, Inc.
*
* Based on sound/soc/codecs/tlv320aic3262.c
*
@@ -18,16 +18,16 @@
*
* History:
*
-* Rev 0.1 ASoC driver support Mistral 20-01-2011
+* Rev 0.1 ASoC driver support 20-01-2011
*
* The AIC325x ASoC driver is ported for the codec AIC3262.
-* Rev 0.2 ASoC driver support Mistral 21-03-2011
+* Rev 0.2 ASoC driver support 21-03-2011
* The AIC326x ASoC driver is updated abe changes.
*
-* Rev 0.3 ASoC driver support Mistral 12.09.2011
+* Rev 0.3 ASoC driver support 12.09.2011
* fixed the compilation issues for Whistler support
*
-* Rev 0.4 ASoC driver support Mistral 27.09.2011
+* Rev 0.4 ASoC driver support 27.09.2011
* The AIC326x driver ported for Nvidia cardhu.
*
* Rev 0.5 Modified to support Multiple ASI Ports 08-Nov-2011
@@ -59,6 +59,7 @@
#include <asm/div64.h>
#include <sound/tlv320aic326x.h>
#include <sound/jack.h>
+#include <linux/spi/spi.h>
#include "tlv320aic326x.h"
@@ -69,13 +70,20 @@
*/
static u8 aic3262_reg_ctl;
-u8 dac_reg = 0, adc_gain = 0, hpl = 0, hpr = 0;
-u8 rec_amp = 0, rampr = 0, spk_amp = 0;
+#ifdef AIC3262_TiLoad
+ extern int aic3262_driver_init(struct snd_soc_codec *codec);
+#endif
+
+
+
/* whenever aplay/arecord is run, aic3262_hw_params() function gets called.
* This function reprograms the clock dividers etc. this flag can be used to
* disable this when the clock dividers are programmed by pps config file
*/
static int soc_static_freq_config = 1;
+static struct aic3262_priv *aic3262_priv_data;
+static struct i2c_client *i2c_pdev;
+static struct snd_soc_codec *aic3262_codec;
/*
*****************************************************************************
@@ -157,7 +165,7 @@ static int aic3262_multi_i2s_asi1_mute(struct snd_soc_dai *dai, int mute);
static int aic3262_multi_i2s_asi2_mute(struct snd_soc_dai *dai, int mute);
static int aic3262_multi_i2s_asi3_mute(struct snd_soc_dai *dai, int mute);
-
+#if 0
static const char *wclk1_pincontrol[] = {
"ASI1 Word Clock Input/Output", "CLKOUT output"};
static const char *dout1_pincontrol[] = {
@@ -203,22 +211,7 @@ static const char *clkin[] = {
"mclk1", "bclk1", "gpio1", "pll_clk", "bclk2", "gpi1",
"hf_ref_clk", "hf_osc_clk", "mclk2", "gpio2", "gpi2"};
-/* List of SOC_ENUM structures for the AIC3262 PIN Control Amixer Controls */
-static const struct soc_enum aic326x_enum[] = {
- SOC_ENUM_SINGLE(WCLK1_PIN_CNTL_REG, 2, 2, wclk1_pincontrol),
- SOC_ENUM_SINGLE(DOUT1_PIN_CNTL_REG, 1, 7, dout1_pincontrol),
- SOC_ENUM_SINGLE(DIN1_PIN_CNTL_REG, 5, 2, din1_pincontrol),
- SOC_ENUM_SINGLE(WCLK2_PIN_CNTL_REG, 2, 10, wclk2_pincontrol),
- SOC_ENUM_SINGLE(BCLK2_PIN_CNTL_REG, 2, 10, bclk2_pincontrol),
- SOC_ENUM_SINGLE(DOUT2_PIN_CNTL_REG, 1, 8, dout2_pincontrol),
- SOC_ENUM_SINGLE(DIN2_PIN_CNTL_REG, 5, 2, din2_pincontrol),
- SOC_ENUM_SINGLE(WCLK3_PIN_CNTL_REG, 2, 5, wclk3_pincontrol),
- SOC_ENUM_SINGLE(BCLK3_PIN_CNTL_REG, 2, 5, bclk3_pincontrol),
- SOC_ENUM_SINGLE(DOUT3_PIN_CNTL_REG, 1, 5, dout3_pincontrol),
- SOC_ENUM_SINGLE(DIN3_PIN_CNTL_REG, 5, 2, din3_pincontrol),
- SOC_ENUM_DOUBLE(DAC_ADC_CLKIN_REG, 0, 4, 11, clkin),
-};
-
+#endif
#ifdef DAC_INDEPENDENT_VOL
/*
*----------------------------------------------------------------------------
@@ -267,14 +260,14 @@ static int n_control_get(struct snd_kcontrol *kcontrol,
if (!strcmp(kcontrol->id.name, "Left DAC Volume")) {
mask = AIC3262_8BITS_MASK;
shift = 0;
- val = aic3262_read(codec, mc->reg);
+ val = snd_soc_read(codec, mc->reg);
ucontrol->value.integer.value[0] =
(val <= 48) ? (val + 127) : (val - 129);
}
if (!strcmp(kcontrol->id.name, "Right DAC Volume")) {
mask = AIC3262_8BITS_MASK;
shift = 0;
- val = aic3262_read(codec, mc->reg);
+ val = snd_soc_read(codec, mc->reg);
ucontrol->value.integer.value[0] =
(val <= 48) ? (val + 127) : (val - 129);
}
@@ -404,8 +397,8 @@ int snd_soc_get_volsw_2r_n(struct snd_kcontrol *kcontrol,
}
/* Read, update the corresponding Registers */
- val = (aic3262_read(codec, reg) >> shift) & mask;
- val2 = (aic3262_read(codec, reg2) >> shift) & mask;
+ val = (snd_soc_read(codec, reg) >> shift) & mask;
+ val2 = (snd_soc_read(codec, reg2) >> shift) & mask;
if (!strcmp(kcontrol->id.name, "PCM Playback Volume")) {
ucontrol->value.integer.value[0] =
@@ -569,7 +562,7 @@ static int __new_control_get(struct snd_kcontrol *kcontrol,
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
u32 val;
- val = aic3262_read(codec, aic3262_reg_ctl);
+ val = snd_soc_read(codec, aic3262_reg_ctl);
ucontrol->value.integer.value[0] = val;
return 0;
}
@@ -618,30 +611,47 @@ static int __new_control_put(struct snd_kcontrol *kcontrol,
* Structure Initialization
*****************************************************************************
*/
+static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -6350, 50, 0);
+static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -1200, 50, 0);
+static const DECLARE_TLV_DB_SCALE(spk_gain_tlv, 600, 600, 0);
+static const DECLARE_TLV_DB_SCALE(output_gain_tlv, -600, 100, 0);
+static const DECLARE_TLV_DB_SCALE(micpga_gain_tlv, 0, 50, 0);
+static const DECLARE_TLV_DB_SCALE(adc_fine_gain_tlv, -40, 10, 0);
+static const DECLARE_TLV_DB_SCALE(beep_gen_volume_tlv, -6300, 100, 0);
+
+/*
+ *****************************************************************************
+ * Structure Initialization
+ *****************************************************************************
+ */
static const struct snd_kcontrol_new aic3262_snd_controls[] = {
/* Output */
- #ifndef DAC_INDEPENDENT_VOL
+#ifndef DAC_INDEPENDENT_VOL
/* sound new kcontrol for PCM Playback volume control */
- SOC_DOUBLE_R_N("PCM Playback Volume", DAC_LVOL, DAC_RVOL, 0, 0xAf, 0),
- #endif
- /* sound new kcontrol for HP driver gain */
- SOC_DOUBLE_R_N("HP Driver Gain", HPL_VOL, HPR_VOL, 0, 21, 0),
- /* sound new kcontrol for SPK driver gain*/
- SOC_DOUBLE("SPK Driver Gain", SPK_AMP_CNTL_R4, 0, 4, 5, 0),
- /* Reveiver driver Gain volume*/
- SOC_DOUBLE_R_N("REC Driver Volume",
- REC_AMP_CNTL_R5, RAMPR_VOL, 0, 36, 0),
- /* sound new kcontrol for PGA capture volume */
- SOC_DOUBLE_R_N("PGA Capture Volume", LADC_VOL, RADC_VOL, 0, 0x3F,
- 0),
- SOC_DOUBLE("ADC Fine Gain ", ADC_FINE_GAIN, 4, 0, 4, 1),
- SOC_DOUBLE_R("PGA MIC Volume", MICL_PGA, MICR_PGA, 0, 95, 0),
-
- SOC_DOUBLE_R("LO to REC Volume", RAMP_CNTL_R1, RAMP_CNTL_R2, 0, 116, 1),
- SOC_DOUBLE_R_N("LO to HP Volume",
- HP_AMP_CNTL_R2, HP_AMP_CNTL_R3, 0, 117, 0),
- SOC_DOUBLE_R("LO to SPK Volume",
- SPK_AMP_CNTL_R2, SPK_AMP_CNTL_R3, 0, 116, 1),
+
+ SOC_DOUBLE_R_SX_TLV("PCM Playback Volume",
+ DAC_LVOL, DAC_RVOL, 8,0xffffff81, 0x30, dac_vol_tlv),
+#endif
+ /*HP Driver Gain Control*/
+ SOC_DOUBLE_R_SX_TLV("HeadPhone Driver Amplifier Volume",
+ HPL_VOL, HPR_VOL, 6, 0xfffffffa, 0xe, output_gain_tlv),
+
+ /*LO Driver Gain Control*/
+ SOC_DOUBLE_TLV("Speaker Amplifier Volume",
+ SPK_AMP_CNTL_R4, 4, 0, 5, 0, spk_gain_tlv),
+
+ SOC_DOUBLE_R_SX_TLV("Receiver Amplifier Volume",
+ REC_AMP_CNTL_R5, RAMPR_VOL, 6, 0xfffffffa, 0x1d, output_gain_tlv),
+
+ SOC_DOUBLE_R_SX_TLV("PCM Capture Volume",
+ LADC_VOL, RADC_VOL, 7,0xffffff68, 0x24, adc_vol_tlv),
+
+
+ SOC_DOUBLE_R_TLV ("MicPGA Volume Control",
+ MICL_PGA, MICR_PGA, 0, 0x5F, 0, micpga_gain_tlv),
+ SOC_DOUBLE_TLV("PCM Capture Fine Gain Volume",
+ ADC_FINE_GAIN, 4, 0, 5, 1, adc_fine_gain_tlv),
+
SOC_DOUBLE("ADC channel mute", ADC_FINE_GAIN, 7, 3, 1, 0),
SOC_DOUBLE("DAC MUTE", DAC_MVOL_CONF, 2, 3, 1, 1),
@@ -649,22 +659,21 @@ static const struct snd_kcontrol_new aic3262_snd_controls[] = {
/* sound new kcontrol for Programming the registers from user space */
SOC_SINGLE_AIC3262("Program Registers"),
- SOC_SINGLE("RESET", RESET_REG, 0 , 1, 0),
+ SOC_SINGLE("RESET", RESET_REG, 0,1,0),
SOC_SINGLE("DAC VOL SOFT STEPPING", DAC_MVOL_CONF, 0, 2, 0),
- #ifdef DAC_INDEPENDENT_VOL
- SOC_SINGLE_N("Left DAC Volume", DAC_LVOL, 0, 0xAF, 0),
- SOC_SINGLE_N("Right DAC Volume", DAC_RVOL, 0, 0xAF, 0),
- #endif
+#ifdef DAC_INDEPENDENT_VOL
+ /*SOC_SINGLE_N("Left DAC Volume", DAC_LVOL, 0, 0xAF, 0),
+ SOC_SINGLE_N("Right DAC Volume", DAC_RVOL, 0, 0xAF, 0),*/
+#endif
SOC_SINGLE("DAC AUTO MUTE CONTROL", DAC_MVOL_CONF, 4, 7, 0),
SOC_SINGLE("RIGHT MODULATOR SETUP", DAC_MVOL_CONF, 7, 1, 0),
SOC_SINGLE("ADC Volume soft stepping", ADC_CHANNEL_POW, 0, 3, 0),
- SOC_DOUBLE_R_N("MA Volume",
- LADC_PGA_MAL_VOL, RADC_PGA_MAR_VOL, 0, 42, 0),
+ SOC_DOUBLE_R("MICPGA enable/disable",MICL_PGA,MICR_PGA,7, 1, 0),
SOC_SINGLE("Mic Bias ext independent enable", MIC_BIAS_CNTL, 7, 1, 0),
SOC_SINGLE("MICBIAS_EXT ON", MIC_BIAS_CNTL, 6, 1, 0),
@@ -691,81 +700,36 @@ static const struct snd_kcontrol_new aic3262_snd_controls[] = {
SOC_DOUBLE_R("AGC_GAIN_HYSTERESIS", LAGC_CNTL, RAGC_CNTL, 0, 3, 0),
SOC_DOUBLE_R("AGC_HYSTERESIS", LAGC_CNTL_R2, RAGC_CNTL_R2, 6, 3, 0),
- SOC_DOUBLE_R("AGC_NOISE_THRESHOLD",
- LAGC_CNTL_R2, RAGC_CNTL_R2, 1, 31, 1),
+ SOC_DOUBLE_R("AGC_NOISE_THRESHOLD", LAGC_CNTL_R2,
+ RAGC_CNTL_R2, 1, 31, 1),
SOC_DOUBLE_R("AGC_MAX_GAIN", LAGC_CNTL_R3, RAGC_CNTL_R3, 0, 116, 0),
SOC_DOUBLE_R("AGC_ATCK_TIME", LAGC_CNTL_R4, RAGC_CNTL_R4, 3, 31, 0),
SOC_DOUBLE_R("AGC_ATCK_SCALE_FACTOR",
- LAGC_CNTL_R4, RAGC_CNTL_R4, 0, 7, 0),
+ LAGC_CNTL_R4, RAGC_CNTL_R4, 0, 7, 0),
SOC_DOUBLE_R("AGC_DECAY_TIME", LAGC_CNTL_R5, RAGC_CNTL_R5, 3, 31, 0),
SOC_DOUBLE_R("AGC_DECAY_SCALE_FACTOR",
- LAGC_CNTL_R5, RAGC_CNTL_R5, 0, 7, 0),
- SOC_DOUBLE_R("AGC_NOISE_DEB_TIME",
- LAGC_CNTL_R6, RAGC_CNTL_R6, 0, 31, 0),
-
- SOC_DOUBLE_R("AGC_SGL_DEB_TIME",
- LAGC_CNTL_R7, RAGC_CNTL_R7, 0, 0x0F, 0),
- SOC_SINGLE("DAC PRB Selection", DAC_PRB, 0, 25, 0),
-
- SOC_SINGLE("INTERRUPT FLAG - Read only", 46, 0, 255, 0),
- SOC_SINGLE("INTERRUPT STICKY FLAG - Read only", 44, 0, 255, 0),
- SOC_SINGLE("INT1 CONTROL", 48, 0, 255, 0),
- SOC_SINGLE("GPIO1 CONTROL", (PAGE_4 + 86), 0, 255, 0),
- SOC_SINGLE("HP_DEPOP", HP_DEPOP, 0, 255, 0),
+ LAGC_CNTL_R5, RAGC_CNTL_R5, 0, 7, 0),
+ SOC_DOUBLE_R("AGC_NOISE_DEB_TIME", LAGC_CNTL_R6,
+ RAGC_CNTL_R6, 0, 31, 0),
- #if defined(FULL_IN_CNTL)
+ SOC_DOUBLE_R("AGC_SGL_DEB_TIME", LAGC_CNTL_R7,
+ RAGC_CNTL_R7, 0, 0x0F, 0),
- SOC_SINGLE("IN1L_2_LMPGA_P_CTL", LMIC_PGA_PIN, 6, 3, 0),
- SOC_SINGLE("IN2L_2_LMPGA_P_CTL", LMIC_PGA_PIN, 4, 3, 0),
- SOC_SINGLE("IN3L_2_LMPGA_P_CTL", LMIC_PGA_PIN, 2, 3, 0),
- SOC_SINGLE("IN1R_2_LMPGA_P_CTL", LMIC_PGA_PIN, 0, 3, 0),
+ SOC_SINGLE("DAC PRB Selection",DAC_PRB, 0, 25, 0),
- SOC_SINGLE("IN4L_2_LMPGA_P_CTL", LMIC_PGA_PM_IN4, 5, 1, 0),
- SOC_SINGLE("IN4R_2_LMPGA_M_CTL", LMIC_PGA_PM_IN4, 4, 1, 0),
-
- SOC_SINGLE("CM1_2_LMPGA_M_CTL", LMIC_PGA_MIN, 6, 3, 0),
- SOC_SINGLE("IN2R_2_LMPGA_M_CTL", LMIC_PGA_MIN, 4, 3, 0),
- SOC_SINGLE("IN3R_2_LMPGA_M_CTL", LMIC_PGA_MIN, 2, 3, 0),
- SOC_SINGLE("CM2_2_LMPGA_M_CTL", LMIC_PGA_MIN, 0, 3, 0),
-
- SOC_SINGLE("IN1R_2_RMPGA_P_CTL", RMIC_PGA_PIN, 6, 3, 0),
- SOC_SINGLE("IN2R_2_RMPGA_P_CTL", RMIC_PGA_PIN, 4, 3, 0),
- SOC_SINGLE("IN3R_2_RMPGA_P_CTL", RMIC_PGA_PIN, 2, 3, 0),
- SOC_SINGLE("IN2L_2_RMPGA_P_CTL", RMIC_PGA_PIN, 0, 3, 0),
-
- SOC_SINGLE("IN4R_2_RMPGA_P_CTL", RMIC_PGA_PM_IN4, 5, 1, 0),
- SOC_SINGLE("IN4L_2_RMPGA_M_CTL", RMIC_PGA_PM_IN4, 4, 1, 0),
-
- SOC_SINGLE("CM1_2_RMPGA_M_CTL", RMIC_PGA_MIN, 6, 3, 0),
- SOC_SINGLE("IN1L_2_RMPGA_M_CTL", RMIC_PGA_MIN, 4, 3, 0),
- SOC_SINGLE("IN3L_2_RMPGA_M_CTL", RMIC_PGA_MIN, 2, 3, 0),
- SOC_SINGLE("CM2_2_RMPGA_M_CTL", RMIC_PGA_MIN, 0, 3, 0),
-
- #endif
-
- SOC_DOUBLE("MA_EN_CNTL", MA_CNTL, 3, 2, 1, 0),
- SOC_DOUBLE("IN1 LO DIRECT BYPASS", MA_CNTL, 5, 4, 1, 0),
+ SOC_SINGLE("INTERRUPT FLAG - Read only", 46, 0, 255,0),
+ SOC_SINGLE("INTERRUPT STICKY FLAG - Read only", 44, 0, 255,0),
+ SOC_SINGLE("INT1 CONTROL", 48, 0, 255,0),
+ SOC_SINGLE("GPIO1 CONTROL", GPIO1_IO_CNTL, 0, 255,0),
+ SOC_SINGLE("HP_DEPOP", HP_DEPOP, 0, 255,0),
SOC_DOUBLE("IN1 LO BYPASS VOLUME" , LINE_AMP_CNTL_R2, 3, 0, 3, 1),
- SOC_DOUBLE("MA LO BYPASS EN", LINE_AMP_CNTL_R2, 7, 6, 1, 0),
-
- /* Pin control Macros */
- SOC_ENUM("DOUT1 Pin Control", aic326x_enum[DOUT1_ENUM]),
- SOC_ENUM("DIN1 Pin Control", aic326x_enum[DIN1_ENUM]),
- SOC_ENUM("WCLK2 Pin Control", aic326x_enum[WCLK2_ENUM]),
- SOC_ENUM("BCLK2 Pin Control", aic326x_enum[BCLK2_ENUM]),
- SOC_ENUM("DOUT2 Pin Control", aic326x_enum[DOUT2_ENUM]),
- SOC_ENUM("DIN2 Pin Control", aic326x_enum[DIN2_ENUM]),
- SOC_ENUM("WCLK3 Pin Control", aic326x_enum[WCLK3_ENUM]),
- SOC_ENUM("BCLK3 Pin Control", aic326x_enum[BCLK3_ENUM]),
- SOC_ENUM("DOUT3 Pin Control", aic326x_enum[DOUT3_ENUM]),
- SOC_ENUM("DIN3 Pin Control", aic326x_enum[DIN3_ENUM]),
- SOC_ENUM("DAC CLK IN", aic326x_enum[CLKIN_ENUM]),
- SOC_ENUM("ADC CLK IN", aic326x_enum[CLKIN_ENUM]),
+
};
+
/* the sturcture contains the different values for mclk */
static const struct aic3262_rate_divs aic3262_divs[] = {
/*
@@ -883,19 +847,19 @@ static void aic3262_multi_i2s_dump_regs(struct snd_soc_dai *dai)
DBG(KERN_INFO "#Page0 REGS..\n");
for (counter = 0; counter < 85; counter++) {
DBG(KERN_INFO "#%2d -> 0x%x\n", counter,
- aic3262_read(codec, counter));
+ snd_soc_read(codec, counter));
}
DBG(KERN_INFO "#Page1 REGS..\n");
for (counter = 128; counter < 176; counter++) {
DBG(KERN_INFO "#%2d -> 0x%x\n", (counter % 128),
- aic3262_read(codec, counter));
+ snd_soc_read(codec, counter));
}
DBG(KERN_INFO "#Page4 REGS..\n");
for (counter = 512; counter < 631; counter++) {
DBG(KERN_INFO "#%2d -> 0x%x\n",
- (counter % 128), aic3262_read(codec, counter));
+ (counter % 128), snd_soc_read(codec, counter));
}
for (counter = 0; counter < MAX_ASI_COUNT; counter++) {
@@ -969,19 +933,11 @@ static int aic3262_multi_i2s_asi1_mute(struct snd_soc_dai *dai, int mute)
DBG(KERN_INFO "#%s : mute %d started\n", __func__, mute);
- if (mute) {
+ if (mute && !aic3262->asiCtxt[0].port_muted ) {
DBG(KERN_INFO "Mute if part\n");
- if (!aic3262->asiCtxt[0].port_muted) {
- dac_reg = aic3262_read(codec, DAC_MVOL_CONF);
- adc_gain = aic3262_read(codec, ADC_FINE_GAIN);
- hpl = aic3262_read(codec, HPL_VOL);
- hpr = aic3262_read(codec, HPR_VOL);
- rec_amp = aic3262_read(codec, REC_AMP_CNTL_R5);
- rampr = aic3262_read(codec, RAMPR_VOL);
- spk_amp = aic3262_read(codec, SPK_AMP_CNTL_R4);
- }
- DBG(KERN_INFO "spk_reg = %2x\n\n", spk_amp);
+
+ snd_soc_update_bits(codec, DAC_MVOL_CONF, DAC_LR_MUTE_MASK,DAC_LR_MUTE);
/* First check if both Playback and Recording is going on
* this interface.
@@ -989,49 +945,29 @@ static int aic3262_multi_i2s_asi1_mute(struct snd_soc_dai *dai, int mute)
if (aic3262->asiCtxt[0].asi_active > 1) {
DBG("#%s Cannot Mute the ASI Now..\n", __func__);
} else if (!(aic3262->asiCtxt[1].playback_mode) &&
- !(aic3262->asiCtxt[2].playback_mode)) {
+ !(aic3262->asiCtxt[2].playback_mode)) {
/* Before Muting, please check if any other
* ASI is active. if so, we cannot simply mute the
* DAC and ADC Registers.
*/
- aic3262_write(codec, DAC_MVOL_CONF,
- ((dac_reg & 0xF3) | 0x0C));
- aic3262_write(codec, ADC_FINE_GAIN,
- ((adc_gain & 0x77) | 0x88));
- aic3262_write(codec, HPL_VOL, 0xB9);
- aic3262_write(codec, HPR_VOL, 0xB9);
- aic3262_write(codec, REC_AMP_CNTL_R5, 0x39);
- aic3262_write(codec, RAMPR_VOL, 0x39);
- aic3262_write(codec, SPK_AMP_CNTL_R4, 0x00);
+ DBG("#%s None of the ASI's are active now..\n", __func__);
+ snd_soc_write(codec, DAC_MVOL_CONF,
+ ((aic3262->dac_reg & 0xF3) | 0x0C));
+ snd_soc_write(codec, ADC_FINE_GAIN,
+ ((aic3262->adc_gain & 0x77) | 0x88));
+ snd_soc_write(codec, HPL_VOL, 0xB9);
+ snd_soc_write(codec, HPR_VOL, 0xB9);
+ snd_soc_write(codec, REC_AMP_CNTL_R5, 0x39);
+ snd_soc_write(codec, RAMPR_VOL, 0x39);
+ snd_soc_write(codec, SPK_AMP_CNTL_R4, 0x00);
aic3262->asiCtxt[0].port_muted = 1;
- } else {
- DBG(KERN_INFO
- "#%s: Other ASI Active. Cannot MUTE Codec..\n",
- __func__);
}
} else {
DBG(KERN_INFO "Mute else part\n");
- aic3262_write(codec, DAC_MVOL_CONF, (dac_reg & 0xF3));
- mdelay(5);
- aic3262_write(codec, ADC_FINE_GAIN, (adc_gain & 0x77));
- mdelay(5);
- aic3262_write(codec, HPL_VOL, hpl);
- mdelay(5);
- aic3262_write(codec, HPR_VOL, hpr);
- mdelay(5);
- aic3262_write(codec, REC_AMP_CNTL_R5, rec_amp);
- mdelay(5);
- aic3262_write(codec, RAMPR_VOL, rampr);
- mdelay(5);
- aic3262_write(codec, SPK_AMP_CNTL_R4, spk_amp);
- mdelay(5);
-
- /* Basic hack */
- aic3262_write(codec, LINE_AMP_CNTL_R1, 0xc3);
- aic3262_write(codec, HP_AMP_CNTL_R1, 0x33);
-
- aic3262->asiCtxt[0].port_muted = 0;
- aic3262_multi_i2s_dump_regs(dai);
+ snd_soc_update_bits(codec, DAC_MVOL_CONF,
+ DAC_LR_MUTE_MASK, 0x0);
+
+ /*aic3262_multi_i2s_dump_regs(dai);*/
}
DBG(KERN_INFO "#%s : mute %d ended\n", __func__, mute);
@@ -1042,7 +978,7 @@ static int aic3262_multi_i2s_asi1_mute(struct snd_soc_dai *dai, int mute)
/*
*----------------------------------------------------------------------------
* Function : aic3262_multi_i2s_asi2_maic3262_asi3_clk_configute
-* Purpose : This function is to mute or unmute the left and right DAC
+* Purpose : This function is to mute or unmute the left and right DAC
*
*----------------------------------------------------------------------------
*/
@@ -1053,19 +989,9 @@ static int aic3262_multi_i2s_asi2_mute(struct snd_soc_dai *dai, int mute)
DBG(KERN_INFO "#%s : mute %d started\n", __func__, mute);
- if (mute) {
+ if (mute && !aic3262->asiCtxt[1].port_muted ) {
DBG(KERN_INFO "Mute if part\n");
-
- if (!aic3262->asiCtxt[1].port_muted) {
- dac_reg = aic3262_read(codec, DAC_MVOL_CONF);
- adc_gain = aic3262_read(codec, ADC_FINE_GAIN);
- hpl = aic3262_read(codec, HPL_VOL);
- hpr = aic3262_read(codec, HPR_VOL);
- rec_amp = aic3262_read(codec, REC_AMP_CNTL_R5);
- rampr = aic3262_read(codec, RAMPR_VOL);
- spk_amp = aic3262_read(codec, SPK_AMP_CNTL_R4);
- DBG(KERN_INFO "spk_reg = %2x\n\n", spk_amp);
- }
+ snd_soc_update_bits(codec, DAC_MVOL_CONF, DAC_LR_MUTE_MASK,DAC_LR_MUTE);
/* First check if both Playback and Recording is going on
* this interface.
@@ -1073,58 +999,39 @@ static int aic3262_multi_i2s_asi2_mute(struct snd_soc_dai *dai, int mute)
if (aic3262->asiCtxt[1].asi_active > 1) {
DBG("#%s Cannot Mute the ASI Now..\n", __func__);
} else if (!(aic3262->asiCtxt[0].playback_mode) &&
- !(aic3262->asiCtxt[2].playback_mode)) {
+ !(aic3262->asiCtxt[2].playback_mode)) {
/* Before Muting, please check if any other
* ASI is active. if so, we cannot simply mute the
* DAC and ADC Registers.
*/
- aic3262_write(codec, DAC_MVOL_CONF,
- ((dac_reg & 0xF3) | 0x0C));
- aic3262_write(codec, ADC_FINE_GAIN,
- ((adc_gain & 0x77) | 0x88));
- aic3262_write(codec, HPL_VOL, 0xB9);
- aic3262_write(codec, HPR_VOL, 0xB9);
- aic3262_write(codec, REC_AMP_CNTL_R5, 0x39);
- aic3262_write(codec, RAMPR_VOL, 0x39);
- aic3262_write(codec, SPK_AMP_CNTL_R4, 0x00);
+ snd_soc_write(codec, DAC_MVOL_CONF,
+ ((aic3262->dac_reg & 0xF3) | 0x0C));
+ snd_soc_write(codec, ADC_FINE_GAIN,
+ ((aic3262->adc_gain & 0x77) | 0x88));
+ snd_soc_write(codec, HPL_VOL, 0xB9);
+ snd_soc_write(codec, HPR_VOL, 0xB9);
+ snd_soc_write(codec, REC_AMP_CNTL_R5, 0x39);
+ snd_soc_write(codec, RAMPR_VOL, 0x39);
+ snd_soc_write(codec, SPK_AMP_CNTL_R4, 0x00);
aic3262->asiCtxt[1].port_muted = 1;
- } else {
- DBG("#%s: Other ASI Active. Cannot MUTE Codec..\n",
- __func__);
}
} else {
DBG(KERN_INFO "Mute else part\n");
- aic3262_write(codec, DAC_MVOL_CONF, (dac_reg & 0xF3));
- mdelay(5);
- aic3262_write(codec, ADC_FINE_GAIN, (adc_gain & 0x77));
- mdelay(5);
- aic3262_write(codec, HPL_VOL, hpl);
- mdelay(5);
- aic3262_write(codec, HPR_VOL, hpr);
- mdelay(5);
- aic3262_write(codec, REC_AMP_CNTL_R5, rec_amp);
- mdelay(5);
- aic3262_write(codec, RAMPR_VOL, rampr);
- mdelay(5);
- aic3262_write(codec, SPK_AMP_CNTL_R4, spk_amp);
- mdelay(5);
-
- /* Basic hack */
- aic3262_write(codec, LINE_AMP_CNTL_R1, 0xc3);
- aic3262_write(codec, HP_AMP_CNTL_R1, 0x33);
-
- aic3262->asiCtxt[1].port_muted = 0;
- aic3262_multi_i2s_dump_regs(dai);
+ snd_soc_update_bits(codec, DAC_MVOL_CONF,
+ DAC_LR_MUTE_MASK, 0x0);
+
+ /*aic3262_multi_i2s_dump_regs(dai);*/
}
DBG(KERN_INFO "#%s : mute %d ended\n", __func__, mute);
return 0;
}
+
/*
*----------------------------------------------------------------------------
* Function : aic3262_multi_i2s_asi3_mute
-* Purpose : This function is to mute or unmute the left and right DAC
+* Purpose : This function is to mute or unmute the left and right DAC
*
*----------------------------------------------------------------------------
*/
@@ -1135,19 +1042,9 @@ static int aic3262_multi_i2s_asi3_mute(struct snd_soc_dai *dai, int mute)
DBG(KERN_INFO "#%s : mute %d started\n", __func__, mute);
- if (mute) {
+ if (mute && !aic3262->asiCtxt[2].port_muted) {
DBG("Mute if part\n");
-
- if (!aic3262->asiCtxt[2].port_muted) {
- dac_reg = aic3262_read(codec, DAC_MVOL_CONF);
- adc_gain = aic3262_read(codec, ADC_FINE_GAIN);
- hpl = aic3262_read(codec, HPL_VOL);
- hpr = aic3262_read(codec, HPR_VOL);
- rec_amp = aic3262_read(codec, REC_AMP_CNTL_R5);
- rampr = aic3262_read(codec, RAMPR_VOL);
- spk_amp = aic3262_read(codec, SPK_AMP_CNTL_R4);
- }
- DBG("spk_reg = %2x\n\n", spk_amp);
+ snd_soc_update_bits(codec, DAC_MVOL_CONF, DAC_LR_MUTE_MASK,DAC_LR_MUTE);
/* First check if both Playback and Recording is going on
* this interface.
@@ -1155,48 +1052,29 @@ static int aic3262_multi_i2s_asi3_mute(struct snd_soc_dai *dai, int mute)
if (aic3262->asiCtxt[2].asi_active > 1) {
DBG("#%s Cannot Mute the ASI Now..\n", __func__);
} else if (!(aic3262->asiCtxt[0].playback_mode) &&
- !(aic3262->asiCtxt[1].playback_mode)) {
+ !(aic3262->asiCtxt[1].playback_mode)) {
/* Before Muting, please check if any other
* ASI is active. if so, we cannot simply mute the
* DAC and ADC Registers.
*/
- aic3262_write(codec, DAC_MVOL_CONF,
- ((dac_reg & 0xF3) | 0x0C));
- aic3262_write(codec, ADC_FINE_GAIN,
- ((adc_gain & 0x77) | 0x88));
- aic3262_write(codec, HPL_VOL, 0xB9);
- aic3262_write(codec, HPR_VOL, 0xB9);
- aic3262_write(codec, REC_AMP_CNTL_R5, 0x39);
- aic3262_write(codec, RAMPR_VOL, 0x39);
- aic3262_write(codec, SPK_AMP_CNTL_R4, 0x00);
+ snd_soc_write(codec, DAC_MVOL_CONF,
+ ((aic3262->dac_reg & 0xF3) | 0x0C));
+ snd_soc_write(codec, ADC_FINE_GAIN,
+ ((aic3262->adc_gain & 0x77) | 0x88));
+ snd_soc_write(codec, HPL_VOL, 0xB9);
+ snd_soc_write(codec, HPR_VOL, 0xB9);
+ snd_soc_write(codec, REC_AMP_CNTL_R5, 0x39);
+ snd_soc_write(codec, RAMPR_VOL, 0x39);
+ snd_soc_write(codec, SPK_AMP_CNTL_R4, 0x00);
aic3262->asiCtxt[2].port_muted = 1;
- } else {
- DBG("#%s: Other ASI Active. Cannot MUTE Codec..\n",
- __func__);
}
} else {
DBG("Mute else part\n");
- aic3262_write(codec, DAC_MVOL_CONF, (dac_reg & 0xF3));
- mdelay(5);
- aic3262_write(codec, ADC_FINE_GAIN, (adc_gain & 0x77));
- mdelay(5);
- aic3262_write(codec, HPL_VOL, hpl);
- mdelay(5);
- aic3262_write(codec, HPR_VOL, hpr);
- mdelay(5);
- aic3262_write(codec, REC_AMP_CNTL_R5, rec_amp);
- mdelay(5);
- aic3262_write(codec, RAMPR_VOL, rampr);
- mdelay(5);
- aic3262_write(codec, SPK_AMP_CNTL_R4, spk_amp);
- mdelay(5);
-
- /* Basic hack */
- aic3262_write(codec, LINE_AMP_CNTL_R1, 0xc3);
- aic3262_write(codec, HP_AMP_CNTL_R1, 0x33);
-
- aic3262->asiCtxt[2].port_muted = 0;
- aic3262_multi_i2s_dump_regs(dai);
+ snd_soc_update_bits(codec, DAC_MVOL_CONF,
+ DAC_LR_MUTE_MASK, 0x0);
+
+ /*aic3262_multi_i2s_dump_regs(dai);*/
+
}
DBG(KERN_INFO "#%s : mute %d ended\n", __func__, mute);
@@ -1258,8 +1136,8 @@ static int aic3262_multi_i2s_asi1_set_dai_fmt(struct snd_soc_dai *codec_dai,
/* Read the B0_P4_R4 and B0_P4_R10 Registers to configure the
* ASI1 Bus and Clock Formats depending on the PCM Format.
*/
- iface_reg = aic3262_read(codec, ASI1_BUS_FMT);
- clk_reg = aic3262_read(codec, ASI1_BWCLK_CNTL_REG);
+ iface_reg = snd_soc_read(codec, ASI1_BUS_FMT);
+ clk_reg = snd_soc_read(codec, ASI1_BWCLK_CNTL_REG);
/* set master/slave audio interface */
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -1311,7 +1189,7 @@ static int aic3262_multi_i2s_asi1_set_dai_fmt(struct snd_soc_dai *codec_dai,
__func__, codec_dai->id);
iface_reg = (iface_reg & 0x1f) | 0x80;
/* voice call need data offset in 1 bitclock */
- aic3262_write(codec, ASI1_LCH_OFFSET, 1);
+ snd_soc_write(codec, ASI1_LCH_OFFSET, 1);
break;
default:
printk(KERN_ERR
@@ -1325,21 +1203,21 @@ static int aic3262_multi_i2s_asi1_set_dai_fmt(struct snd_soc_dai *codec_dai,
/* Configure B0_P4_R65_D[5:2] to 001 This configures the
* WCLK1 Pin to ASI1
*/
- regvalue = aic3262_read(codec, WCLK1_PIN_CNTL_REG);
- aic3262_write(codec, WCLK1_PIN_CNTL_REG, (regvalue | BIT2));
+ regvalue = snd_soc_read(codec, WCLK1_PIN_CNTL_REG);
+ snd_soc_write(codec, WCLK1_PIN_CNTL_REG, (regvalue | BIT2));
/* Configure B0_P4_R68_d[6:5] = 01 and B0_P4_R67_D[4:1] to 0001
* to ensure that the DIN1 and DOUT1 Pins are configured
* correctly
*/
- regvalue = aic3262_read(codec, DIN1_PIN_CNTL_REG);
- aic3262_write(codec, DIN1_PIN_CNTL_REG, (regvalue | BIT5));
- regvalue = aic3262_read(codec, DOUT1_PIN_CNTL_REG);
- aic3262_write(codec, DOUT1_PIN_CNTL_REG, (regvalue | BIT1));
+ regvalue = snd_soc_read(codec, DIN1_PIN_CNTL_REG);
+ snd_soc_write(codec, DIN1_PIN_CNTL_REG, (regvalue | BIT5));
+ regvalue = snd_soc_read(codec, DOUT1_PIN_CNTL_REG);
+ snd_soc_write(codec, DOUT1_PIN_CNTL_REG, (regvalue | BIT1));
- aic3262_write(codec, ASI1_BWCLK_CNTL_REG, clk_reg);
+ snd_soc_write(codec, ASI1_BWCLK_CNTL_REG, clk_reg);
- aic3262_write(codec, ASI1_BUS_FMT, iface_reg);
+ snd_soc_write(codec, ASI1_BUS_FMT, iface_reg);
return 0;
}
@@ -1366,8 +1244,8 @@ static int aic3262_multi_i2s_asi2_set_dai_fmt(struct snd_soc_dai *codec_dai,
/* Read the B0_P4_R17 and B0_P4_R26 Registers to configure the
* ASI1 Bus and Clock Formats depending on the PCM Format.
*/
- iface_reg = aic3262_read(codec, ASI2_BUS_FMT);
- clk_reg = aic3262_read(codec, ASI2_BWCLK_CNTL_REG);
+ iface_reg = snd_soc_read(codec, ASI2_BUS_FMT);
+ clk_reg = snd_soc_read(codec, ASI2_BWCLK_CNTL_REG);
/* set master/slave audio interface */
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -1420,7 +1298,7 @@ static int aic3262_multi_i2s_asi2_set_dai_fmt(struct snd_soc_dai *codec_dai,
__func__, codec_dai->id);
iface_reg = (iface_reg & 0x1f) | 0x80;
/* voice call need data offset in 1 bitclock */
- aic3262_write(codec, ASI2_LCH_OFFSET, 1);
+ snd_soc_write(codec, ASI2_LCH_OFFSET, 1);
break;
default:
printk(KERN_ERR "#%s:Invalid DAI interface format\n", __func__);
@@ -1435,25 +1313,25 @@ static int aic3262_multi_i2s_asi2_set_dai_fmt(struct snd_soc_dai *codec_dai,
* WCLK2 Pin to ASI2
*/
- regvalue = aic3262_read(codec, WCLK2_PIN_CNTL_REG);
- aic3262_write(codec, WCLK2_PIN_CNTL_REG, (regvalue | BIT2));
+ regvalue = snd_soc_read(codec, WCLK2_PIN_CNTL_REG);
+ snd_soc_write(codec, WCLK2_PIN_CNTL_REG, (regvalue | BIT2));
- regvalue = aic3262_read(codec, BCLK2_PIN_CNTL_REG);
- aic3262_write(codec, BCLK2_PIN_CNTL_REG, (regvalue | BIT2));
+ regvalue = snd_soc_read(codec, BCLK2_PIN_CNTL_REG);
+ snd_soc_write(codec, BCLK2_PIN_CNTL_REG, (regvalue | BIT2));
/* Configure B0_P4_R72_d[6:5] = 01 and B0_P4_R71_D[4:1] to 0001
* to ensure that the DIN2 and DOUT2 Pins are configured
* correctly
*/
- regvalue = aic3262_read(codec, DIN2_PIN_CNTL_REG);
- aic3262_write(codec, DIN2_PIN_CNTL_REG, (regvalue | BIT5));
+ regvalue = snd_soc_read(codec, DIN2_PIN_CNTL_REG);
+ snd_soc_write(codec, DIN2_PIN_CNTL_REG, (regvalue | BIT5));
- regvalue = aic3262_read(codec, DOUT2_PIN_CNTL_REG);
- aic3262_write(codec, DOUT2_PIN_CNTL_REG, (regvalue | BIT5 | BIT1));
+ regvalue = snd_soc_read(codec, DOUT2_PIN_CNTL_REG);
+ snd_soc_write(codec, DOUT2_PIN_CNTL_REG, (regvalue | BIT5 | BIT1));
- aic3262_write(codec, ASI2_BWCLK_CNTL_REG, clk_reg);
+ snd_soc_write(codec, ASI2_BWCLK_CNTL_REG, clk_reg);
- aic3262_write(codec, ASI2_BUS_FMT, iface_reg);
+ snd_soc_write(codec, ASI2_BUS_FMT, iface_reg);
return 0;
}
@@ -1479,8 +1357,8 @@ static int aic3262_multi_i2s_asi3_set_dai_fmt(struct snd_soc_dai *codec_dai,
/* Read the B0_P4_R33 and B0_P4_R42 Registers to configure the
* ASI1 Bus and Clock Formats depending on the PCM Format.
*/
- iface_reg = aic3262_read(codec, ASI3_BUS_FMT);
- clk_reg = aic3262_read(codec, ASI3_BWCLK_CNTL_REG);
+ iface_reg = snd_soc_read(codec, ASI3_BUS_FMT);
+ clk_reg = snd_soc_read(codec, ASI3_BWCLK_CNTL_REG);
/* set master/slave audio interface */
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -1531,7 +1409,7 @@ static int aic3262_multi_i2s_asi3_set_dai_fmt(struct snd_soc_dai *codec_dai,
__func__, codec_dai->id);
iface_reg = (iface_reg & 0x1f) | 0x80;
/* voice call need data offset in 1 bitclock */
- aic3262_write(codec, ASI3_LCH_OFFSET, 1);
+ snd_soc_write(codec, ASI3_LCH_OFFSET, 1);
break;
default:
printk(KERN_ERR
@@ -1545,24 +1423,24 @@ static int aic3262_multi_i2s_asi3_set_dai_fmt(struct snd_soc_dai *codec_dai,
/* Configure B0_P4_R73_D[5:2] to 0001 This configures the
* WCLK1 Pin to ASI1
*/
- regvalue = aic3262_read(codec, WCLK3_PIN_CNTL_REG);
- aic3262_write(codec, WCLK3_PIN_CNTL_REG, (regvalue | BIT2));
+ regvalue = snd_soc_read(codec, WCLK3_PIN_CNTL_REG);
+ snd_soc_write(codec, WCLK3_PIN_CNTL_REG, (regvalue | BIT2));
- regvalue = aic3262_read(codec, BCLK3_PIN_CNTL_REG);
- aic3262_write(codec, BCLK3_PIN_CNTL_REG, (regvalue | BIT2));
+ regvalue = snd_soc_read(codec, BCLK3_PIN_CNTL_REG);
+ snd_soc_write(codec, BCLK3_PIN_CNTL_REG, (regvalue | BIT2));
/* Configure B0_P4_R76_d[6:5] = 01 and B0_P4_R75_D[4:1] to 0001
* to ensure that the DIN1 and DOUT1 Pins are configured
* correctly
*/
- regvalue = aic3262_read(codec, DIN3_PIN_CNTL_REG);
- aic3262_write(codec, DIN3_PIN_CNTL_REG, (regvalue | BIT5));
- regvalue = aic3262_read(codec, DOUT3_PIN_CNTL_REG);
- aic3262_write(codec, DOUT3_PIN_CNTL_REG, (regvalue | BIT1));
+ regvalue = snd_soc_read(codec, DIN3_PIN_CNTL_REG);
+ snd_soc_write(codec, DIN3_PIN_CNTL_REG, (regvalue | BIT5));
+ regvalue = snd_soc_read(codec, DOUT3_PIN_CNTL_REG);
+ snd_soc_write(codec, DOUT3_PIN_CNTL_REG, (regvalue | BIT1));
- aic3262_write(codec, ASI3_BWCLK_CNTL_REG, clk_reg);
+ snd_soc_write(codec, ASI3_BWCLK_CNTL_REG, clk_reg);
- aic3262_write(codec, ASI3_BUS_FMT, iface_reg);
+ snd_soc_write(codec, ASI3_BUS_FMT, iface_reg);
return 0;
}
@@ -1600,9 +1478,6 @@ static int aic3262_multi_i2s_set_dai_pll(struct snd_soc_dai *codec_dai,
int pll_id, int source, unsigned int freq_in,
unsigned int freq_out)
{
- /*u16 reg, enable;
- int offset;
- struct snd_soc_codec *codec = codec_dai->codec;*/
printk(KERN_INFO "%s: DAI ID %d PLL_ID %d InFreq %d OutFreq %d\n",
__func__, pll_id, codec_dai->id, freq_in, freq_out);
@@ -1630,35 +1505,36 @@ static int aic3262_asi1_clk_config(struct snd_soc_codec *codec,
DBG(KERN_INFO "%s: Invoked\n", __func__);
- if (aic3262->asiCtxt[0].master == 1) {
- DBG(KERN_INFO
- "#%s: Codec Master on ASI1 Port. Enabling BCLK WCLK Divider.\n",
- __func__);
- bclk_N_value = aic3262->asiCtxt[0].bclk_div;
- aic3262_write(codec, ASI1_BCLK_N, (bclk_N_value | 0x80));
-
- wclk_N_value = aic3262_read(codec, ASI1_WCLK_N);
- aic3262_write(codec, ASI1_WCLK_N, (wclk_N_value | 0xA0));
- }
/* Configure the BCLK and WCLK Output Mux Options */
- regval = aic3262_read(codec, ASI1_BWCLK_OUT_CNTL);
+ regval = snd_soc_read(codec, ASI1_BWCLK_OUT_CNTL);
regval &= ~(AIC3262_ASI_BCLK_MUX_MASK | AIC3262_ASI_WCLK_MUX_MASK);
regval |= (aic3262->asiCtxt[0].bclk_output <<
AIC3262_ASI_BCLK_MUX_SHIFT);
regval |= aic3262->asiCtxt[0].wclk_output;
- aic3262_write(codec, ASI1_BWCLK_OUT_CNTL, regval);
+ snd_soc_write(codec, ASI1_BWCLK_OUT_CNTL, regval);
/* Configure the corresponding miniDSP Data Ports */
- minidspD_data = aic3262_read(codec, MINIDSP_PORT_CNTL_REG);
+ minidspD_data = snd_soc_read(codec, MINIDSP_PORT_CNTL_REG);
minidspD_data &= ~(BIT5 | BIT4);
- aic3262_write(codec, MINIDSP_PORT_CNTL_REG, minidspD_data);
+ snd_soc_write(codec, MINIDSP_PORT_CNTL_REG, minidspD_data);
- minidspA_data = aic3262_read(codec, ASI1_ADC_INPUT_CNTL);
+ minidspA_data = snd_soc_read(codec, ASI1_ADC_INPUT_CNTL);
minidspA_data &= ~(BIT2 | BIT1 | BIT0);
minidspA_data |= aic3262->asiCtxt[0].adc_input;
- aic3262_write(codec, ASI1_ADC_INPUT_CNTL, minidspA_data);
+ snd_soc_write(codec, ASI1_ADC_INPUT_CNTL, minidspA_data);
+
+ if (aic3262->asiCtxt[0].master == 1) {
+ DBG(KERN_INFO
+ "#%s: Codec Master on ASI1 Port. Enabling BCLK WCLK Divider.\n",
+ __func__);
+ bclk_N_value = aic3262->asiCtxt[0].bclk_div;
+ snd_soc_write(codec, ASI1_BCLK_N, (bclk_N_value | 0x80));
+
+ wclk_N_value = snd_soc_read(codec, ASI1_WCLK_N);
+ snd_soc_write(codec, ASI1_WCLK_N, (wclk_N_value | 0xA0));
+ }
return 0;
}
@@ -1682,34 +1558,35 @@ static int aic3262_asi2_clk_config(struct snd_soc_codec *codec,
DBG(KERN_INFO "%s: Invoked\n", __func__);
- if (aic3262->asiCtxt[1].master == 1) {
- DBG(KERN_INFO
- "#%s: Codec Master on ASI2 Port. Enabling BCLK WCLK Divider.\n",
- __func__);
- bclk_N_value = aic3262->asiCtxt[1].bclk_div;
- aic3262_write(codec, ASI2_BCLK_N, (bclk_N_value | 0x80));
- wclk_N_value = aic3262_read(codec, ASI2_WCLK_N);
- aic3262_write(codec, ASI2_WCLK_N, (wclk_N_value | 0xA0));
- }
/* Configure the BCLK and WCLK Output Mux Options */
- regval = aic3262_read(codec, ASI2_BWCLK_OUT_CNTL);
+ regval = snd_soc_read(codec, ASI2_BWCLK_OUT_CNTL);
regval &= ~(AIC3262_ASI_BCLK_MUX_MASK | AIC3262_ASI_WCLK_MUX_MASK);
regval |= (aic3262->asiCtxt[1].bclk_output <<
AIC3262_ASI_BCLK_MUX_SHIFT);
regval |= aic3262->asiCtxt[1].wclk_output;
- aic3262_write(codec, ASI2_BWCLK_OUT_CNTL, regval);
+ snd_soc_write(codec, ASI2_BWCLK_OUT_CNTL, regval);
/* Configure the corresponding miniDSP Data Ports */
- minidspD_data = aic3262_read(codec, MINIDSP_PORT_CNTL_REG);
+ minidspD_data = snd_soc_read(codec, MINIDSP_PORT_CNTL_REG);
minidspD_data |= (BIT2);
- aic3262_write(codec, MINIDSP_PORT_CNTL_REG, minidspD_data);
+ snd_soc_write(codec, MINIDSP_PORT_CNTL_REG, minidspD_data);
- minidspA_data = aic3262_read(codec, ASI2_ADC_INPUT_CNTL);
+ minidspA_data = snd_soc_read(codec, ASI2_ADC_INPUT_CNTL);
minidspA_data &= ~(BIT2 | BIT1 | BIT0);
minidspA_data |= aic3262->asiCtxt[1].adc_input;
- aic3262_write(codec, ASI2_ADC_INPUT_CNTL, minidspA_data);
+ snd_soc_write(codec, ASI2_ADC_INPUT_CNTL, minidspA_data);
+
+ if (aic3262->asiCtxt[1].master == 1) {
+ DBG(KERN_INFO
+ "#%s: Codec Master on ASI2 Port. Enabling BCLK WCLK Divider.\n",
+ __func__);
+ bclk_N_value = aic3262->asiCtxt[1].bclk_div;
+ snd_soc_write(codec, ASI2_BCLK_N, (bclk_N_value | 0x80));
+ wclk_N_value = snd_soc_read(codec, ASI2_WCLK_N);
+ snd_soc_write(codec, ASI2_WCLK_N, (wclk_N_value | 0xA0));
+ }
return 0;
}
@@ -1733,34 +1610,34 @@ static int aic3262_asi3_clk_config(struct snd_soc_codec *codec,
DBG(KERN_INFO "%s:\n", __func__);
- if (aic3262->asiCtxt[2].master == 1) {
- DBG(KERN_INFO
- "#%s: Codec Master on ASI3 Port. Enabling BCLK WCLK Divider.\n",
- __func__);
- bclk_N_value = aic3262->asiCtxt[2].bclk_div;
- aic3262_write(codec, ASI2_BCLK_N, (bclk_N_value | 0x80));
-
- wclk_N_value = aic3262_read(codec, ASI3_WCLK_N);
- aic3262_write(codec, ASI3_WCLK_N, (wclk_N_value | 0xA0));
- }
/* Configure the BCLK and WCLK Output Mux Options */
- regval = aic3262_read(codec, ASI3_BWCLK_OUT_CNTL);
+ regval = snd_soc_read(codec, ASI3_BWCLK_OUT_CNTL);
regval &= ~(AIC3262_ASI_BCLK_MUX_MASK | AIC3262_ASI_WCLK_MUX_MASK);
regval |= (aic3262->asiCtxt[2].bclk_output <<
AIC3262_ASI_BCLK_MUX_SHIFT);
regval |= aic3262->asiCtxt[2].wclk_output;
- aic3262_write(codec, ASI3_BWCLK_OUT_CNTL, regval);
+ snd_soc_write(codec, ASI3_BWCLK_OUT_CNTL, regval);
- minidspD_data = aic3262_read(codec, MINIDSP_PORT_CNTL_REG);
+ minidspD_data = snd_soc_read(codec, MINIDSP_PORT_CNTL_REG);
minidspD_data |= (BIT1);
- aic3262_write(codec, MINIDSP_PORT_CNTL_REG, minidspD_data);
+ snd_soc_write(codec, MINIDSP_PORT_CNTL_REG, minidspD_data);
- minidspA_data = aic3262_read(codec, ASI3_ADC_INPUT_CNTL);
+ minidspA_data = snd_soc_read(codec, ASI3_ADC_INPUT_CNTL);
minidspA_data &= ~(BIT2 | BIT1 | BIT0);
minidspA_data |= aic3262->asiCtxt[2].adc_input;
- aic3262_write(codec, ASI3_ADC_INPUT_CNTL, minidspA_data);
+ snd_soc_write(codec, ASI3_ADC_INPUT_CNTL, minidspA_data);
+ if (aic3262->asiCtxt[2].master == 1) {
+ DBG(KERN_INFO
+ "#%s: Codec Master on ASI3 Port. Enabling BCLK WCLK Divider.\n",
+ __func__);
+ bclk_N_value = aic3262->asiCtxt[2].bclk_div;
+ snd_soc_write(codec, ASI2_BCLK_N, (bclk_N_value | 0x80));
+
+ wclk_N_value = snd_soc_read(codec, ASI3_WCLK_N);
+ snd_soc_write(codec, ASI3_WCLK_N, (wclk_N_value | 0xA0));
+ }
return 0;
}
@@ -1807,7 +1684,7 @@ static int aic3262_multi_i2s_hw_params(struct snd_pcm_substream *substream,
/* Configure the PLL J, R D values only if none of the ASI
* Interfaces are Active.
*/
- /*if (!(AIC3262_MULTI_ASI_ACTIVE(aic3262))) {*/
+
if (1) {
DBG(KERN_INFO "#%s: None of the ASIs active yet...\n",
__func__);
@@ -1815,58 +1692,58 @@ static int aic3262_multi_i2s_hw_params(struct snd_pcm_substream *substream,
/* Setting P & R values are set to 1 and 1 at init*/
/* J value */
- aic3262_write(codec, PLL_J_REG, aic3262_divs[i].pll_j);
+ snd_soc_write(codec, PLL_J_REG, aic3262_divs[i].pll_j);
/* MSB & LSB for D value */
- aic3262_write(codec, PLL_D_MSB, (aic3262_divs[i].pll_d >> 8));
- aic3262_write(codec, PLL_D_LSB,
+ snd_soc_write(codec, PLL_D_MSB, (aic3262_divs[i].pll_d >> 8));
+ snd_soc_write(codec, PLL_D_LSB,
(aic3262_divs[i].pll_d & AIC3262_8BITS_MASK));
/* NDAC divider value */
- data = aic3262_read(codec, NDAC_DIV_POW_REG);
+ data = snd_soc_read(codec, NDAC_DIV_POW_REG);
DBG(KERN_INFO "# reading NDAC = %d , NDAC_DIV_POW_REG = %x\n",
aic3262_divs[i].ndac, data);
- aic3262_write(codec, NDAC_DIV_POW_REG,
+ snd_soc_write(codec, NDAC_DIV_POW_REG,
((data & 0x80)|(aic3262_divs[i].ndac)));
DBG(KERN_INFO "# writing NDAC = %d , NDAC_DIV_POW_REG = %x\n",
aic3262_divs[i].ndac,
((data & 0x80)|(aic3262_divs[i].ndac)));
/* MDAC divider value */
- data = aic3262_read(codec, MDAC_DIV_POW_REG);
+ data = snd_soc_read(codec, MDAC_DIV_POW_REG);
DBG(KERN_INFO "# reading MDAC = %d , MDAC_DIV_POW_REG = %x\n",
aic3262_divs[i].mdac, data);
- aic3262_write(codec, MDAC_DIV_POW_REG,
+ snd_soc_write(codec, MDAC_DIV_POW_REG,
((data & 0x80)|(aic3262_divs[i].mdac)));
DBG(KERN_INFO "# writing MDAC = %d , MDAC_DIV_POW_REG = %x\n",
aic3262_divs[i].mdac, ((data & 0x80)|(aic3262_divs[i].mdac)));
/* DOSR MSB & LSB values */
- aic3262_write(codec, DOSR_MSB_REG, aic3262_divs[i].dosr >> 8);
+ snd_soc_write(codec, DOSR_MSB_REG, aic3262_divs[i].dosr >> 8);
DBG(KERN_INFO "# writing DOSR_MSB_REG = %d\n",
(aic3262_divs[i].dosr >> 8));
- aic3262_write(codec, DOSR_LSB_REG,
+ snd_soc_write(codec, DOSR_LSB_REG,
aic3262_divs[i].dosr & AIC3262_8BITS_MASK);
DBG(KERN_INFO "# writing DOSR_LSB_REG = %d\n",
(aic3262_divs[i].dosr & AIC3262_8BITS_MASK));
/* NADC divider value */
- data = aic3262_read(codec, NADC_DIV_POW_REG);
- aic3262_write(codec, NADC_DIV_POW_REG,
+ data = snd_soc_read(codec, NADC_DIV_POW_REG);
+ snd_soc_write(codec, NADC_DIV_POW_REG,
((data & 0x80)|(aic3262_divs[i].nadc)));
DBG(KERN_INFO "# writing NADC_DIV_POW_REG = %d\n",
aic3262_divs[i].nadc);
/* MADC divider value */
- data = aic3262_read(codec, MADC_DIV_POW_REG);
- aic3262_write(codec, MADC_DIV_POW_REG,
+ data = snd_soc_read(codec, MADC_DIV_POW_REG);
+ snd_soc_write(codec, MADC_DIV_POW_REG,
((data & 0x80)|(aic3262_divs[i].madc)));
DBG(KERN_INFO "# writing MADC_DIV_POW_REG = %d\n",
aic3262_divs[i].madc);
/* AOSR value */
- aic3262_write(codec, AOSR_REG, aic3262_divs[i].aosr);
+ snd_soc_write(codec, AOSR_REG, aic3262_divs[i].aosr);
DBG(KERN_INFO "# writing AOSR = %d\n", aic3262_divs[i].aosr);
} else {
DBG(KERN_INFO "#Atleast 1 ASI Active. Cannot Program PLL..\n");
@@ -1884,7 +1761,7 @@ static int aic3262_multi_i2s_hw_params(struct snd_pcm_substream *substream,
/* Read the DAC Control Register and configure it
* as per the ASIContext Structure Settings.
*/
- dacpath = aic3262_read(codec, ASI1_DAC_OUT_CNTL);
+ dacpath = snd_soc_read(codec, ASI1_DAC_OUT_CNTL);
dacpath &= ~(AIC3262_ASI_LDAC_PATH_MASK |
AIC3262_ASI_RDAC_PATH_MASK);
dacpath |= (aic3262->asiCtxt[0].left_dac_output
@@ -1892,7 +1769,7 @@ static int aic3262_multi_i2s_hw_params(struct snd_pcm_substream *substream,
dacpath |= (aic3262->asiCtxt[0].right_dac_output
<< AIC3262_ASI_RDAC_PATH_SHIFT);
- aic3262_write(codec, ASI1_DAC_OUT_CNTL, dacpath);
+ snd_soc_write(codec, ASI1_DAC_OUT_CNTL, dacpath);
aic3262->asiCtxt[0].playback_mode = 1;
aic3262->asiCtxt[0].bclk_div =
@@ -1901,11 +1778,11 @@ static int aic3262_multi_i2s_hw_params(struct snd_pcm_substream *substream,
/* For Recording, Configure the DOUT Pin as per
* ASIContext Structure Settings.
*/
- adcpath = aic3262_read(codec, ASI1_DATA_OUT);
+ adcpath = snd_soc_read(codec, ASI1_DATA_OUT);
adcpath &= ~(AIC3262_ASI_DOUT_MASK);
adcpath |= aic3262->asiCtxt[0].dout_option;
- aic3262_write(codec, ASI1_DATA_OUT, adcpath);
+ snd_soc_write(codec, ASI1_DATA_OUT, adcpath);
aic3262->asiCtxt[0].capture_mode = 1;
}
@@ -1923,7 +1800,7 @@ static int aic3262_multi_i2s_hw_params(struct snd_pcm_substream *substream,
/* Read the DAC Control Register and configure it
* as per theASIContext Structure Settings.
*/
- dacpath = aic3262_read(codec, ASI2_DAC_OUT_CNTL);
+ dacpath = snd_soc_read(codec, ASI2_DAC_OUT_CNTL);
dacpath &= ~(AIC3262_ASI_LDAC_PATH_MASK |
AIC3262_ASI_RDAC_PATH_MASK);
dacpath |= (aic3262->asiCtxt[1].left_dac_output
@@ -1931,7 +1808,7 @@ static int aic3262_multi_i2s_hw_params(struct snd_pcm_substream *substream,
dacpath |= (aic3262->asiCtxt[1].right_dac_output
<< AIC3262_ASI_RDAC_PATH_SHIFT);
- aic3262_write(codec, ASI2_DAC_OUT_CNTL, dacpath);
+ snd_soc_write(codec, ASI2_DAC_OUT_CNTL, dacpath);
aic3262->asiCtxt[1].playback_mode = 1;
aic3262->asiCtxt[1].bclk_div =
@@ -1940,10 +1817,10 @@ static int aic3262_multi_i2s_hw_params(struct snd_pcm_substream *substream,
/* For Recording, Configure the DOUT Pin as per
* ASIContext Structure Settings.
*/
- adcpath = aic3262_read(codec, ASI2_DATA_OUT);
+ adcpath = snd_soc_read(codec, ASI2_DATA_OUT);
adcpath &= ~(AIC3262_ASI_DOUT_MASK);
adcpath |= aic3262->asiCtxt[1].dout_option;
- aic3262_write(codec, ASI2_DATA_OUT, adcpath);
+ snd_soc_write(codec, ASI2_DATA_OUT, adcpath);
aic3262->asiCtxt[1].capture_mode = 1;
}
@@ -1960,14 +1837,14 @@ static int aic3262_multi_i2s_hw_params(struct snd_pcm_substream *substream,
/* Read the DAC Control Register and configure
* it as per the ASIContext Structure Settings.
*/
- dacpath = aic3262_read(codec, ASI3_DAC_OUT_CNTL);
+ dacpath = snd_soc_read(codec, ASI3_DAC_OUT_CNTL);
dacpath &= ~(AIC3262_ASI_LDAC_PATH_MASK |
AIC3262_ASI_RDAC_PATH_MASK);
dacpath |= (aic3262->asiCtxt[2].left_dac_output
<< AIC3262_ASI_LDAC_PATH_SHIFT);
dacpath |= (aic3262->asiCtxt[2].right_dac_output
<< AIC3262_ASI_RDAC_PATH_SHIFT);
- aic3262_write(codec,
+ snd_soc_write(codec,
ASI3_DAC_OUT_CNTL, dacpath);
aic3262->asiCtxt[2].playback_mode = 1;
@@ -1980,7 +1857,7 @@ static int aic3262_multi_i2s_hw_params(struct snd_pcm_substream *substream,
*/
adcpath &= ~(AIC3262_ASI_DOUT_MASK);
adcpath |= aic3262->asiCtxt[2].dout_option;
- aic3262_write(codec, ASI3_DATA_OUT, adcpath);
+ snd_soc_write(codec, ASI3_DATA_OUT, adcpath);
aic3262->asiCtxt[2].capture_mode = 1;
}
@@ -1994,7 +1871,7 @@ static int aic3262_multi_i2s_hw_params(struct snd_pcm_substream *substream,
__func__, (regoffset/128), (regoffset % 128));
/* Read the correspondig ASI DAI Interface Register */
- data = aic3262_read(codec, regoffset);
+ data = snd_soc_read(codec, regoffset);
data = data & 0xe7;
@@ -2024,10 +1901,10 @@ static int aic3262_multi_i2s_hw_params(struct snd_pcm_substream *substream,
}
/* configure the respective Registers for the above configuration */
- aic3262_write(codec, regoffset, data);
+ snd_soc_write(codec, regoffset, data);
for (j = 0; j < NO_FEATURE_REGS; j++) {
- aic3262_write(codec,
+ snd_soc_write(codec,
aic3262_divs[i].codec_specific_regs[j].reg_offset,
aic3262_divs[i].codec_specific_regs[j].reg_val);
}
@@ -2070,7 +1947,7 @@ static int aic3262_multi_i2s_hw_params(struct snd_pcm_substream *substream,
* We can use this function to disable the DAC and ADC specific inputs from the
* individual ASI Ports of the Audio Codec.
*/
-static int aic3262_multi_i2s_hw_free(struct snd_pcm_substream *substream,
+static int aic3262_multi_i2s_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -2113,11 +1990,11 @@ static int aic3262_multi_i2s_hw_free(struct snd_pcm_substream *substream,
* going on this ASI Interface
*/
- value = aic3262_read(codec, ASI1_BCLK_N);
- aic3262_write(codec, ASI1_BCLK_N, (value & 0x7f));
+ value = snd_soc_read(codec, ASI1_BCLK_N);
+ snd_soc_write(codec, ASI1_BCLK_N, (value & 0x7f));
- value = aic3262_read(codec, ASI1_WCLK_N);
- aic3262_write(codec, ASI1_WCLK_N, (value & 0x7f));
+ value = snd_soc_read(codec, ASI1_WCLK_N);
+ snd_soc_write(codec, ASI1_WCLK_N, (value & 0x7f));
}
dacregoffset = ASI1_DAC_OUT_CNTL;
@@ -2128,11 +2005,11 @@ static int aic3262_multi_i2s_hw_free(struct snd_pcm_substream *substream,
* the Bit Clock Divider and Word Clock Dividers
*/
if (aic3262->asiCtxt[1].master == 1) {
- value = aic3262_read(codec, ASI2_BCLK_N);
- aic3262_write(codec, ASI2_BCLK_N, (value & 0x7f));
+ value = snd_soc_read(codec, ASI2_BCLK_N);
+ snd_soc_write(codec, ASI2_BCLK_N, (value & 0x7f));
- value = aic3262_read(codec, ASI2_WCLK_N);
- aic3262_write(codec, ASI2_WCLK_N, (value & 0x7f));
+ value = snd_soc_read(codec, ASI2_WCLK_N);
+ snd_soc_write(codec, ASI2_WCLK_N, (value & 0x7f));
}
dacregoffset = ASI2_DAC_OUT_CNTL;
adcregoffset = ASI2_ADC_INPUT_CNTL;
@@ -2142,11 +2019,11 @@ static int aic3262_multi_i2s_hw_free(struct snd_pcm_substream *substream,
* the Bit Clock Divider and Word Clock Dividers
*/
if (aic3262->asiCtxt[2].master == 1) {
- value = aic3262_read(codec, ASI3_BCLK_N);
- aic3262_write(codec, ASI3_BCLK_N, (value & 0x7f));
+ value = snd_soc_read(codec, ASI3_BCLK_N);
+ snd_soc_write(codec, ASI3_BCLK_N, (value & 0x7f));
- value = aic3262_read(codec, ASI3_WCLK_N);
- aic3262_write(codec, ASI3_WCLK_N, (value & 0x7f));
+ value = snd_soc_read(codec, ASI3_WCLK_N);
+ snd_soc_write(codec, ASI3_WCLK_N, (value & 0x7f));
}
dacregoffset = ASI3_DAC_OUT_CNTL;
adcregoffset = ASI3_ADC_INPUT_CNTL;
@@ -2162,8 +2039,8 @@ static int aic3262_multi_i2s_hw_free(struct snd_pcm_substream *substream,
DBG(KERN_INFO "#%s: Disabling Pg %d Reg %d DAC Inputs ..\n",
__func__, (dacregoffset/128), (dacregoffset % 128));
- dacpath = aic3262_read(codec, dacregoffset);
- aic3262_write(codec, dacregoffset, (dacpath & ~(BIT6 | BIT4)));
+ dacpath = snd_soc_read(codec, dacregoffset);
+ snd_soc_write(codec, dacregoffset, (dacpath & ~(BIT6 | BIT4)));
aic3262->asiCtxt[dai->id - 1].playback_mode = 0;
} else {
@@ -2171,8 +2048,8 @@ static int aic3262_multi_i2s_hw_free(struct snd_pcm_substream *substream,
DBG(KERN_INFO "#%s: Disabling Pg %d Reg %d for ADC Inputs..\n",
__func__, (adcregoffset/128), (adcregoffset % 128));
- adcpath = aic3262_read(codec, adcregoffset);
- aic3262_write(codec, adcregoffset,
+ adcpath = snd_soc_read(codec, adcregoffset);
+ snd_soc_write(codec, adcregoffset,
(adcpath & ~(BIT2 | BIT1 | BIT0)));
aic3262->asiCtxt[dai->id - 1].capture_mode = 0;
@@ -2184,21 +2061,21 @@ static int aic3262_multi_i2s_hw_free(struct snd_pcm_substream *substream,
switch (dai->id) {
case 1:
if (aic3262->asiCtxt[0].pcm_format == SND_SOC_DAIFMT_DSP_B) {
- aic3262_write(codec, ASI1_LCH_OFFSET, 0x00);
- aic3262_write(codec, ASI1_RCH_OFFSET, 0x00);
+ snd_soc_write(codec, ASI1_LCH_OFFSET, 0x00);
+ snd_soc_write(codec, ASI1_RCH_OFFSET, 0x00);
}
break;
case 2:
if (aic3262->asiCtxt[1].pcm_format == SND_SOC_DAIFMT_DSP_B) {
- aic3262_write(codec, ASI2_LCH_OFFSET, 0x00);
- aic3262_write(codec, ASI2_RCH_OFFSET, 0x00);
+ snd_soc_write(codec, ASI2_LCH_OFFSET, 0x00);
+ snd_soc_write(codec, ASI2_RCH_OFFSET, 0x00);
}
break;
case 3:
if (aic3262->asiCtxt[2].pcm_format == SND_SOC_DAIFMT_DSP_B) {
- aic3262_write(codec, ASI3_LCH_OFFSET, 0x00);
- aic3262_write(codec, ASI3_RCH_OFFSET, 0x00);
+ snd_soc_write(codec, ASI3_LCH_OFFSET, 0x00);
+ snd_soc_write(codec, ASI3_RCH_OFFSET, 0x00);
}
break;
}
@@ -2230,7 +2107,7 @@ struct snd_soc_dai_ops aic3262_multi_i2s_dai_ops = {
.set_fmt = aic3262_multi_i2s_set_dai_fmt,
.set_pll = aic3262_multi_i2s_set_dai_pll,
.set_sysclk = aic3262_multi_i2s_set_dai_sysclk,
- .hw_free = aic3262_multi_i2s_hw_free,
+ .shutdown = aic3262_multi_i2s_shutdown,
};
@@ -2528,8 +2405,8 @@ static const struct aic3262_configs aic3262_reg_init[] = {
{0, LMIC_PGA_MIN, 0x40}, /*CM to LMICPGA-M*/
{0, RMIC_PGA_PIN, 0x55}, /*IN1_R select - - 10k -RMIC_PGA_P*/
{0, RMIC_PGA_MIN, 0x40}, /*CM to RMICPGA_M*/
- {0, (PAGE_1 + 0x79), 33}, /*LMIC-PGA-POWERUP-DELAY - default*/
- {0, (PAGE_1 + 0x7a), 1}, /*FIXMELATER*/
+ {0, MIC_PWR_DLY , 33}, /*LMIC-PGA-POWERUP-DELAY - default*/
+ {0, REF_PWR_DLY, 1}, /*FIXMELATER*/
{0, ADC_CHANNEL_POW, 0xc2}, /*ladc, radc ON , SOFT STEP disabled*/
@@ -2576,55 +2453,394 @@ static const struct aic3262_configs aic3262_reg_init[] = {
static int reg_init_size =
sizeof(aic3262_reg_init) / sizeof(struct aic3262_configs);
-static const struct snd_kcontrol_new aic3262_snd_controls2[] = {
+static const unsigned int adc_ma_tlv[] = {
+TLV_DB_RANGE_HEAD(4),
+ 0, 29, TLV_DB_SCALE_ITEM(-1450, 500, 0),
+ 30, 35, TLV_DB_SCALE_ITEM(-2060, 1000, 0),
+ 36, 38, TLV_DB_SCALE_ITEM(-2660, 2000, 0),
+ 39, 40, TLV_DB_SCALE_ITEM(-3610, 5000, 0),
+};
+static const DECLARE_TLV_DB_SCALE(lo_hp_tlv, -7830, 50, 0);
+
+static const struct snd_kcontrol_new mal_pga_mixer_controls[] = {
+ SOC_DAPM_SINGLE("IN1L Switch", MA_CNTL, 5, 1, 0),
+ SOC_DAPM_SINGLE_TLV("Left MicPGA Volume", LADC_PGA_MAL_VOL, 0,
+ 0x3f, 1, adc_ma_tlv),
- SOC_DOUBLE_R("IN1 MPGA Route", LMIC_PGA_PIN, RMIC_PGA_PIN, 6, 3, 0),
- SOC_DOUBLE_R("IN2 MPGA Route", LMIC_PGA_PIN, RMIC_PGA_PIN, 4, 3, 0),
- SOC_DOUBLE_R("IN3 MPGA Route", LMIC_PGA_PIN, RMIC_PGA_PIN, 2, 3, 0),
- SOC_DOUBLE_R("IN4 MPGA Route",
- LMIC_PGA_PM_IN4, RMIC_PGA_PM_IN4, 5, 1, 0),
};
+
+static const struct snd_kcontrol_new mar_pga_mixer_controls[] = {
+ SOC_DAPM_SINGLE("IN1R Switch", MA_CNTL, 4, 1, 0),
+ SOC_DAPM_SINGLE_TLV("Right MicPGA Volume", RADC_PGA_MAR_VOL, 0,
+ 0x3f, 1, adc_ma_tlv),
+};
+
+/* Left HPL Mixer */
+static const struct snd_kcontrol_new hpl_output_mixer_controls[] = {
+ SOC_DAPM_SINGLE("MAL Switch", HP_AMP_CNTL_R1, 7, 1, 0),
+ SOC_DAPM_SINGLE("LDAC Switch", HP_AMP_CNTL_R1, 5, 1, 0),
+ SOC_DAPM_SINGLE_TLV("LOL-B1 Volume", HP_AMP_CNTL_R2, 0,
+ 0x7f, 1, lo_hp_tlv),
+};
+
+/* Right HPR Mixer */
+static const struct snd_kcontrol_new hpr_output_mixer_controls[] = {
+ SOC_DAPM_SINGLE_TLV("LOR-B1 Volume", HP_AMP_CNTL_R3, 0,
+ 0x7f, 1, lo_hp_tlv),
+ SOC_DAPM_SINGLE("LDAC Switch", HP_AMP_CNTL_R1, 2, 1, 0),
+ SOC_DAPM_SINGLE("RDAC Switch", HP_AMP_CNTL_R1, 4, 1, 0),
+ SOC_DAPM_SINGLE("MAR Switch", HP_AMP_CNTL_R1, 6, 1, 0),
+};
+
+/* Left LOL Mixer */
+static const struct snd_kcontrol_new lol_output_mixer_controls[] = {
+ SOC_DAPM_SINGLE("MAL Switch", LINE_AMP_CNTL_R2, 7, 1, 0),
+ SOC_DAPM_SINGLE("IN1L-B Switch", LINE_AMP_CNTL_R2, 3, 1,0),
+ SOC_DAPM_SINGLE("LDAC Switch", LINE_AMP_CNTL_R1, 7, 1, 0),
+ SOC_DAPM_SINGLE("RDAC Switch", LINE_AMP_CNTL_R1, 5, 1, 0),
+};
+
+/* Right LOR Mixer */
+static const struct snd_kcontrol_new lor_output_mixer_controls[] = {
+ SOC_DAPM_SINGLE("LOL Switch", LINE_AMP_CNTL_R1, 2, 1, 0),
+ SOC_DAPM_SINGLE("RDAC Switch", LINE_AMP_CNTL_R1, 6, 1, 0),
+ SOC_DAPM_SINGLE("MAR Switch", LINE_AMP_CNTL_R2, 6, 1, 0),
+ SOC_DAPM_SINGLE("IN1R-B Switch", LINE_AMP_CNTL_R2, 0, 1,0),
+};
+
+/* Left SPKL Mixer */
+static const struct snd_kcontrol_new spkl_output_mixer_controls[] = {
+ SOC_DAPM_SINGLE("MAL Switch", SPK_AMP_CNTL_R1, 7, 1, 0),
+ SOC_DAPM_SINGLE_TLV("LOL Volume", SPK_AMP_CNTL_R2, 0, 0x7f,1,
+ lo_hp_tlv),
+ SOC_DAPM_SINGLE("SPR_IN Switch", SPK_AMP_CNTL_R1, 2, 1, 0),
+};
+
+/* Right SPKR Mixer */
+static const struct snd_kcontrol_new spkr_output_mixer_controls[] = {
+ SOC_DAPM_SINGLE_TLV("LOR Volume", SPK_AMP_CNTL_R3, 0, 0x7f, 1,
+ lo_hp_tlv),
+ SOC_DAPM_SINGLE("MAR Switch", SPK_AMP_CNTL_R1, 6, 1, 0),
+};
+
+/* REC Mixer */
+static const struct snd_kcontrol_new rec_output_mixer_controls[] = {
+ SOC_DAPM_SINGLE_TLV("LOL-B2 Volume", RAMP_CNTL_R1, 0, 0x7f,1,
+ lo_hp_tlv),
+ SOC_DAPM_SINGLE_TLV("IN1L Volume", IN1L_SEL_RM, 0, 0x7f, 1, lo_hp_tlv),
+ SOC_DAPM_SINGLE_TLV("IN1R Volume", IN1R_SEL_RM, 0, 0x7f, 1, lo_hp_tlv),
+ SOC_DAPM_SINGLE_TLV("LOR-B2 Volume", RAMP_CNTL_R2, 0,0x7f, 1,lo_hp_tlv),
+};
+
+/* Left Input Mixer */
+static const struct snd_kcontrol_new left_input_mixer_controls[] = {
+ SOC_DAPM_SINGLE("IN1L Switch", LMIC_PGA_PIN, 6, 1, 0),
+ SOC_DAPM_SINGLE("IN2L Switch", LMIC_PGA_PIN, 4, 1, 0),
+ SOC_DAPM_SINGLE("IN3L Switch", LMIC_PGA_PIN, 2, 1, 0),
+ SOC_DAPM_SINGLE("IN4L Switch", LMIC_PGA_PM_IN4, 5, 1, 0),
+ SOC_DAPM_SINGLE("IN1R Switch", LMIC_PGA_PIN, 0, 1, 0),
+ SOC_DAPM_SINGLE("IN2R Switch", LMIC_PGA_MIN, 4, 1, 0),
+ SOC_DAPM_SINGLE("IN3R Switch", LMIC_PGA_MIN, 2, 1, 0),
+ SOC_DAPM_SINGLE("IN4R Switch", LMIC_PGA_PM_IN4, 4, 1, 0),
+ SOC_DAPM_SINGLE("CM2L Switch", LMIC_PGA_MIN, 0, 1, 0),
+ SOC_DAPM_SINGLE("CM1L Switch", LMIC_PGA_MIN, 6, 1, 0),
+};
+
+/* Right Input Mixer */
+static const struct snd_kcontrol_new right_input_mixer_controls[] = {
+ SOC_DAPM_SINGLE("IN1R Switch", RMIC_PGA_PIN, 6, 1, 0),
+ SOC_DAPM_SINGLE("IN2R Switch", RMIC_PGA_PIN, 4, 1, 0),
+ SOC_DAPM_SINGLE("IN3R Switch", RMIC_PGA_PIN, 2, 1, 0),
+ SOC_DAPM_SINGLE("IN4R Switch", RMIC_PGA_PM_IN4, 5, 1, 0),
+ SOC_DAPM_SINGLE("IN2L Switch", RMIC_PGA_PIN, 0, 1, 0),
+ SOC_DAPM_SINGLE("IN1L Switch", RMIC_PGA_MIN, 4, 1, 0),
+ SOC_DAPM_SINGLE("IN3L Switch", RMIC_PGA_MIN, 2, 1, 0),
+ SOC_DAPM_SINGLE("IN4L Switch", RMIC_PGA_PM_IN4, 4, 1, 0),
+ SOC_DAPM_SINGLE("CM1R Switch", RMIC_PGA_MIN, 6, 1, 0),
+ SOC_DAPM_SINGLE("CM2R Switch", RMIC_PGA_MIN, 0, 1, 0),
+};
+
+
+static const char *asi1lin_text[] = {
+ "Off", "ASI1 Left In","ASI1 Right In","ASI1 MonoMix In"
+};
+
+SOC_ENUM_SINGLE_DECL(asi1lin_enum, ASI1_DAC_OUT_CNTL, 6, asi1lin_text);
+
+static const struct snd_kcontrol_new asi1lin_control =
+ SOC_DAPM_ENUM("ASI1LIN Route", asi1lin_enum);
+
+
+static const char *asi1rin_text[] = {
+ "Off", "ASI1 Right In","ASI1 Left In","ASI1 MonoMix In"
+};
+
+SOC_ENUM_SINGLE_DECL(asi1rin_enum, ASI1_DAC_OUT_CNTL, 4, asi1rin_text);
+
+static const struct snd_kcontrol_new asi1rin_control =
+ SOC_DAPM_ENUM("ASI1RIN Route", asi1rin_enum);
+
+static const char *asi2lin_text[] = {
+ "Off", "ASI2 Left In","ASI2 Right In","ASI2 MonoMix In"
+};
+
+SOC_ENUM_SINGLE_DECL(asi2lin_enum, ASI2_DAC_OUT_CNTL, 6, asi2lin_text);
+static const struct snd_kcontrol_new asi2lin_control =
+ SOC_DAPM_ENUM("ASI2LIN Route", asi2lin_enum);
+
+static const char *asi2rin_text[] = {
+ "Off", "ASI2 Right In","ASI2 Left In","ASI2 MonoMix In"
+};
+
+
+SOC_ENUM_SINGLE_DECL(asi2rin_enum, ASI2_DAC_OUT_CNTL, 4, asi2rin_text);
+
+static const struct snd_kcontrol_new asi2rin_control =
+ SOC_DAPM_ENUM("ASI2RIN Route", asi2rin_enum);
+
+static const char *asi3lin_text[] = {
+ "Off", "ASI3 Left In","ASI3 Right In","ASI3 MonoMix In"
+};
+
+
+SOC_ENUM_SINGLE_DECL(asi3lin_enum, ASI3_DAC_OUT_CNTL, 6, asi3lin_text);
+static const struct snd_kcontrol_new asi3lin_control =
+ SOC_DAPM_ENUM("ASI3LIN Route", asi3lin_enum);
+
+
+static const char *asi3rin_text[] = {
+ "Off", "ASI3 Right In","ASI3 Left In","ASI3 MonoMix In"
+};
+
+
+SOC_ENUM_SINGLE_DECL(asi3rin_enum, ASI3_DAC_OUT_CNTL, 4, asi3rin_text);
+static const struct snd_kcontrol_new asi3rin_control =
+ SOC_DAPM_ENUM("ASI3RIN Route", asi3rin_enum);
+
+
+static const char *dacminidspin1_text[] = {
+ "ASI1 In", "ASI2 In","ASI3 In","ADC MiniDSP Out"
+};
+
+SOC_ENUM_SINGLE_DECL(dacminidspin1_enum, MINIDSP_PORT_CNTL_REG, 4, dacminidspin1_text);
+static const struct snd_kcontrol_new dacminidspin1_control =
+ SOC_DAPM_ENUM("DAC MiniDSP IN1 Route", dacminidspin1_enum);
+
+static const char *asi1out_text[] = {
+ "Off",
+ "ASI1 Out",
+ "ASI1In Bypass",
+ "ASI2In Bypass",
+ "ASI3In Bypass",
+};
+SOC_ENUM_SINGLE_DECL(asi1out_enum, ASI1_ADC_INPUT_CNTL, 0, asi1out_text);
+static const struct snd_kcontrol_new asi1out_control =
+ SOC_DAPM_ENUM("ASI1OUT Route", asi1out_enum);
+
+static const char *asi2out_text[] = {
+ "Off",
+ "ASI1 Out",
+ "ASI1In Bypass",
+ "ASI2In Bypass",
+ "ASI3In Bypass",
+ "ASI2 Out",
+};
+SOC_ENUM_SINGLE_DECL(asi2out_enum, ASI2_ADC_INPUT_CNTL, 0, asi2out_text);
+static const struct snd_kcontrol_new asi2out_control =
+ SOC_DAPM_ENUM("ASI2OUT Route", asi2out_enum);
+static const char *asi3out_text[] = {
+ "Off",
+ "ASI1 Out",
+ "ASI1In Bypass",
+ "ASI2In Bypass",
+ "ASI3In Bypass",
+ "ASI3 Out",
+};
+SOC_ENUM_SINGLE_DECL(asi3out_enum, ASI3_ADC_INPUT_CNTL, 0, asi3out_text);
+static const struct snd_kcontrol_new asi3out_control =
+ SOC_DAPM_ENUM("ASI3OUT Route", asi3out_enum);
+
+static const char *asi1bclk_text[] = {
+ "DAC_CLK",
+ "DAC_MOD_CLK",
+ "ADC_CLK",
+ "ADC_MOD_CLK",
+};
+
+static int aic326x_hp_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ return 0;
+}
+static int pll_power_on_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ if (event == SND_SOC_DAPM_POST_PMU)
+ {
+ mdelay(10);
+ }
+ return 0;
+}
static const struct snd_soc_dapm_widget aic3262_dapm_widgets[] = {
- SND_SOC_DAPM_DAC("Left DAC", "Playback", PASI_DAC_DP_SETUP, 7, 0),
- SND_SOC_DAPM_DAC("Right DAC", "Playback", PASI_DAC_DP_SETUP, 6, 0),
+ /* TODO: Can we switch these off ? */
+ SND_SOC_DAPM_AIF_IN("ASI1IN", "ASI1 Playback", 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_IN("ASI2IN", "ASI2 Playback", 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_IN("ASI3IN", "ASI3 Playback", 0, SND_SOC_NOPM, 0, 0),
+
+ SND_SOC_DAPM_DAC("Left DAC", NULL, PASI_DAC_DP_SETUP, 7, 0),
+ SND_SOC_DAPM_DAC("Right DAC", NULL, PASI_DAC_DP_SETUP, 6, 0),
+
- SND_SOC_DAPM_SWITCH_N("LDAC_2_HPL", HP_AMP_CNTL_R1, 5, 0),
- SND_SOC_DAPM_SWITCH_N("RDAC_2_HPR", HP_AMP_CNTL_R1, 4, 0),
+ /* dapm widget (path domain) for HPL Output Mixer */
+ SND_SOC_DAPM_MIXER("HPL Output Mixer", SND_SOC_NOPM, 0, 0,
+ &hpl_output_mixer_controls[0],
+ ARRAY_SIZE(hpl_output_mixer_controls)),
- SND_SOC_DAPM_PGA("HPL Driver", HP_AMP_CNTL_R1, 1, 0, NULL, 0),
- SND_SOC_DAPM_PGA("HPR Driver", HP_AMP_CNTL_R1, 0, 0, NULL, 0),
+ /* dapm widget (path domain) for HPR Output Mixer */
+ SND_SOC_DAPM_MIXER("HPR Output Mixer", SND_SOC_NOPM, 0, 0,
+ &hpr_output_mixer_controls[0],
+ ARRAY_SIZE(hpr_output_mixer_controls)),
- SND_SOC_DAPM_SWITCH_N("LDAC_2_LOL", LINE_AMP_CNTL_R1, 7, 0),
- SND_SOC_DAPM_SWITCH_N("RDAC_2_LOR", LINE_AMP_CNTL_R1, 6, 0),
+
+ SND_SOC_DAPM_PGA_E("HPL Driver", HP_AMP_CNTL_R1, 1, 0, NULL, 0,
+ aic326x_hp_event, SND_SOC_DAPM_POST_PMU),
+ SND_SOC_DAPM_PGA_E("HPR Driver", HP_AMP_CNTL_R1, 0, 0, NULL, 0,
+ aic326x_hp_event, SND_SOC_DAPM_POST_PMU),
+
+
+ /* dapm widget (path domain) for LOL Output Mixer */
+ SND_SOC_DAPM_MIXER("LOL Output Mixer", SND_SOC_NOPM, 0, 0,
+ &lol_output_mixer_controls[0],
+ ARRAY_SIZE(lol_output_mixer_controls)),
+
+ /* dapm widget (path domain) for LOR Output Mixer mixer */
+ SND_SOC_DAPM_MIXER("LOR Output Mixer", SND_SOC_NOPM, 0, 0,
+ &lor_output_mixer_controls[0],
+ ARRAY_SIZE(lor_output_mixer_controls)),
SND_SOC_DAPM_PGA("LOL Driver", LINE_AMP_CNTL_R1, 1, 0, NULL, 0),
SND_SOC_DAPM_PGA("LOR Driver", LINE_AMP_CNTL_R1, 0, 0, NULL, 0),
+
+ /* dapm widget (path domain) for SPKL Output Mixer */
+ SND_SOC_DAPM_MIXER("SPKL Output Mixer", SND_SOC_NOPM, 0, 0,
+ &spkl_output_mixer_controls[0],
+ ARRAY_SIZE(spkl_output_mixer_controls)),
+
+ /* dapm widget (path domain) for SPKR Output Mixer */
+ SND_SOC_DAPM_MIXER("SPKR Output Mixer", SND_SOC_NOPM, 0, 0,
+ &spkr_output_mixer_controls[0],
+ ARRAY_SIZE(spkr_output_mixer_controls)),
+
SND_SOC_DAPM_PGA("SPKL Driver", SPK_AMP_CNTL_R1, 1, 0, NULL, 0),
SND_SOC_DAPM_PGA("SPKR Driver", SPK_AMP_CNTL_R1, 0, 0, NULL, 0),
- SND_SOC_DAPM_PGA("RECL Driver", REC_AMP_CNTL_R5, 7, 0, NULL, 0),
- SND_SOC_DAPM_PGA("RECR Driver", REC_AMP_CNTL_R5, 6, 0, NULL, 0),
-
- SND_SOC_DAPM_ADC("Left ADC", "Capture", ADC_CHANNEL_POW, 7, 0),
- SND_SOC_DAPM_ADC("Right ADC", "Capture", ADC_CHANNEL_POW, 6, 0),
-
- SND_SOC_DAPM_SWITCH("IN1L Route",
- LMIC_PGA_PIN, 6, 0, &aic3262_snd_controls2[0]),
- SND_SOC_DAPM_SWITCH("IN2L Route",
- LMIC_PGA_PIN, 4, 0, &aic3262_snd_controls2[1]),
- SND_SOC_DAPM_SWITCH("IN3L Route",
- LMIC_PGA_PIN, 2, 0, &aic3262_snd_controls2[2]),
- SND_SOC_DAPM_SWITCH("IN4L Route",
- LMIC_PGA_PM_IN4, 5, 0, &aic3262_snd_controls2[3]),
- SND_SOC_DAPM_SWITCH("IN1R Route",
- RMIC_PGA_PIN, 6, 0, &aic3262_snd_controls2[4]),
- SND_SOC_DAPM_SWITCH("IN2R Route",
- RMIC_PGA_PIN, 4, 0, &aic3262_snd_controls2[5]),
- SND_SOC_DAPM_SWITCH("IN3R Route",
- RMIC_PGA_PIN, 2, 0, &aic3262_snd_controls2[6]),
- SND_SOC_DAPM_SWITCH("IN4R Route",
- RMIC_PGA_PM_IN4, 5, 0, &aic3262_snd_controls2[7]),
+
+ /* dapm widget (path domain) for SPKR Output Mixer */
+ SND_SOC_DAPM_MIXER("REC Output Mixer", SND_SOC_NOPM, 0, 0,
+ &rec_output_mixer_controls[0],
+ ARRAY_SIZE(rec_output_mixer_controls)),
+
+ SND_SOC_DAPM_PGA("RECP Driver", REC_AMP_CNTL_R5, 7, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("RECM Driver", REC_AMP_CNTL_R5, 6, 0, NULL, 0),
+
+
+ SND_SOC_DAPM_MUX("ASI1LIN Route",
+ SND_SOC_NOPM, 0, 0, &asi1lin_control),
+ SND_SOC_DAPM_MUX("ASI1RIN Route",
+ SND_SOC_NOPM, 0, 0, &asi1rin_control),
+ SND_SOC_DAPM_MUX("ASI2LIN Route",
+ SND_SOC_NOPM, 0, 0, &asi2lin_control),
+ SND_SOC_DAPM_MUX("ASI2RIN Route",
+ SND_SOC_NOPM, 0, 0, &asi2rin_control),
+ SND_SOC_DAPM_MUX("ASI3LIN Route",
+ SND_SOC_NOPM, 0, 0, &asi3lin_control),
+ SND_SOC_DAPM_MUX("ASI3RIN Route",
+ SND_SOC_NOPM, 0, 0, &asi3rin_control),
+
+ SND_SOC_DAPM_PGA("ASI1LIN", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("ASI1RIN", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("ASI2LIN", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("ASI2RIN", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("ASI3LIN", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("ASI3RIN", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ SND_SOC_DAPM_PGA("ASI1LOUT", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("ASI1ROUT", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("ASI2LOUT", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("ASI2ROUT", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("ASI3LOUT", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("ASI3ROUT", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ SND_SOC_DAPM_PGA("ASI1MonoMixIN", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("ASI2MonoMixIN", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("ASI3MonoMixIN", SND_SOC_NOPM, 0, 0, NULL, 0),
+ /* TODO: Can we switch the ASIxIN off? */
+ SND_SOC_DAPM_PGA("ASI1IN Port", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("ASI2IN Port", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("ASI3IN Port", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+
+ SND_SOC_DAPM_MUX("DAC MiniDSP IN1 Route",
+ SND_SOC_NOPM, 0, 0, &dacminidspin1_control),
+
+
+ SND_SOC_DAPM_PGA("CM", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("CM1L", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("CM2L", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("CM1R", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("CM2R", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ /* TODO: Can we switch these off ? */
+ SND_SOC_DAPM_AIF_OUT("ASI1OUT","ASI1 Capture", 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("ASI2OUT", "ASI2 Capture",0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("ASI3OUT", "ASI3 Capture",0, SND_SOC_NOPM, 0, 0),
+
+ SND_SOC_DAPM_MUX("ASI1OUT Route",
+ SND_SOC_NOPM, 0, 0, &asi1out_control),
+ SND_SOC_DAPM_MUX("ASI2OUT Route",
+ SND_SOC_NOPM, 0, 0, &asi2out_control),
+ SND_SOC_DAPM_MUX("ASI3OUT Route",
+ SND_SOC_NOPM, 0, 0, &asi3out_control),
+
+ /* TODO: Will be used during MINIDSP programming */
+ /* TODO: Can we switch them off? */
+ SND_SOC_DAPM_PGA("ADC MiniDSP OUT1", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("ADC MiniDSP OUT2", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("ADC MiniDSP OUT3", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+
+ SND_SOC_DAPM_ADC("Left ADC", NULL, ADC_CHANNEL_POW, 7, 0),
+ SND_SOC_DAPM_ADC("Right ADC", NULL, ADC_CHANNEL_POW, 6, 0),
+
+
+ SND_SOC_DAPM_PGA("Left MicPGA",MICL_PGA, 7, 1, NULL, 0),
+ SND_SOC_DAPM_PGA("Right MicPGA",MICR_PGA, 7, 1, NULL, 0),
+
+ SND_SOC_DAPM_PGA("MAL PGA", MA_CNTL, 3, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("MAR PGA", MA_CNTL, 2, 0, NULL, 0),
+
+
+ /* dapm widget for MAL PGA Mixer*/
+ SND_SOC_DAPM_MIXER("MAL PGA Mixer", SND_SOC_NOPM, 0, 0,
+ &mal_pga_mixer_controls[0],
+ ARRAY_SIZE(mal_pga_mixer_controls)),
+
+ /* dapm widget for MAR PGA Mixer*/
+ SND_SOC_DAPM_MIXER("MAR PGA Mixer", SND_SOC_NOPM, 0, 0,
+ &mar_pga_mixer_controls[0],
+ ARRAY_SIZE(mar_pga_mixer_controls)),
+
+ /* dapm widget for Left Input Mixer*/
+ SND_SOC_DAPM_MIXER("Left Input Mixer", SND_SOC_NOPM, 0, 0,
+ &left_input_mixer_controls[0],
+ ARRAY_SIZE(left_input_mixer_controls)),
+
+ /* dapm widget for Right Input Mixer*/
+ SND_SOC_DAPM_MIXER("Right Input Mixer", SND_SOC_NOPM, 0, 0,
+ &right_input_mixer_controls[0],
+ ARRAY_SIZE(right_input_mixer_controls)),
+
SND_SOC_DAPM_OUTPUT("HPL"),
SND_SOC_DAPM_OUTPUT("HPR"),
@@ -2632,60 +2848,282 @@ static const struct snd_soc_dapm_widget aic3262_dapm_widgets[] = {
SND_SOC_DAPM_OUTPUT("LOR"),
SND_SOC_DAPM_OUTPUT("SPKL"),
SND_SOC_DAPM_OUTPUT("SPKR"),
- SND_SOC_DAPM_OUTPUT("RECL"),
- SND_SOC_DAPM_OUTPUT("RECR"),
+ SND_SOC_DAPM_OUTPUT("RECP"),
+ SND_SOC_DAPM_OUTPUT("RECM"),
SND_SOC_DAPM_INPUT("IN1L"),
SND_SOC_DAPM_INPUT("IN2L"),
SND_SOC_DAPM_INPUT("IN3L"),
SND_SOC_DAPM_INPUT("IN4L"),
-
SND_SOC_DAPM_INPUT("IN1R"),
SND_SOC_DAPM_INPUT("IN2R"),
SND_SOC_DAPM_INPUT("IN3R"),
SND_SOC_DAPM_INPUT("IN4R"),
+
+
+ SND_SOC_DAPM_MICBIAS("Mic Bias Ext", MIC_BIAS_CNTL, 6, 0),
+ SND_SOC_DAPM_MICBIAS("Mic Bias Int", MIC_BIAS_CNTL, 2, 0),
+ SND_SOC_DAPM_SUPPLY("PLLCLK",PLL_PR_POW_REG,7,0,pll_power_on_event,
+ SND_SOC_DAPM_POST_PMU),
+ SND_SOC_DAPM_SUPPLY("NDAC",NDAC_DIV_POW_REG,7,0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY("MDAC",MDAC_DIV_POW_REG,7,0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY("NADC",NADC_DIV_POW_REG,7,0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY("MADC",MADC_DIV_POW_REG,7,0, NULL, 0),
+
+
};
-static const struct snd_soc_dapm_route aic3262_dapm_routes[] = {
- {"LDAC_2_HPL", NULL, "Left DAC"},
- {"HPL Driver", NULL, "LDAC_2_HPL"},
- {"HPL", NULL, "HPL Driver"},
- {"RDAC_2_HPR", NULL, "Right DAC"},
- {"HPR Driver", NULL, "RDAC_2_HPR"},
- {"HPR", NULL, "HPR Driver"},
-
- {"LDAC_2_LOL", NULL, "Left DAC"},
- {"LOL Driver", NULL, "LDAC_2_LOL"},
- {"LOL", NULL, "LOL Driver"},
- {"RDAC_2_LOR", NULL, "Right DAC"},
- {"LOR Driver", NULL, "RDAC_2_LOR"},
- {"LOR", NULL, "LOR Driver"},
-
- {"SPKL Driver", NULL, "LOL"},
- {"SPKL", NULL, "SPKL Driver"},
- {"SPKR Driver", NULL, "LOR"},
- {"SPKR", NULL, "SPKR Driver"},
-
- {"RECL Driver", NULL, "LOL"},
- {"RECL", NULL, "RECL Driver"},
- {"RECR Driver", NULL, "LOR"},
- {"RECR", NULL, "RECR Driver"},
-
- {"Left ADC", "IN1L Route", "IN1L"},
- {"Left ADC", "IN2L Route", "IN2L"},
- {"Left ADC", "IN3L Route", "IN3L"},
- {"Left ADC", "IN4L Route", "IN4L"},
-
- {"Right ADC", "IN1R Route", "IN1R"},
- {"Right ADC", "IN2R Route", "IN2R"},
- {"Right ADC", "IN3R Route", "IN3R"},
- {"Right ADC", "IN4R Route", "IN4R"},
-/*
- {"LOL Driver", NULL, "IN1L"},
- {"LOR Driver", NULL, "IN1R"},
-*/
+static const struct snd_soc_dapm_route aic3262_dapm_routes[] ={
+/* TODO: Do we need only DACCLK for ASIIN's and ADCCLK for ASIOUT??? */
+/* Clock portion */
+ {"NDAC", NULL, "PLLCLK"},
+ {"MDAC", NULL, "NDAC"},
+ {"ASI1IN", NULL , "NDAC"},
+ {"ASI1IN", NULL , "NADC"},
+ {"ASI1IN", NULL , "MDAC"},
+ {"ASI1IN", NULL , "MADC"},
+
+ {"ASI1OUT", NULL , "NDAC"},
+ {"ASI1OUT", NULL , "NADC"},
+ {"ASI1OUT", NULL , "MDAC"},
+ {"ASI1OUT", NULL , "MADC"},
+
+#ifdef AIC3262_ASI1_MASTER
+ {"ASI1IN", NULL , "ASI1_BCLK"},
+ {"ASI1OUT", NULL , "ASI1_BCLK"},
+ {"ASI1IN", NULL , "ASI1_WCLK"},
+ {"ASI1OUT", NULL , "ASI1_WCLK"},
+#else
+
+#endif
+ {"ASI2IN", NULL , "NDAC"},
+ {"ASI2IN", NULL , "NADC"},
+ {"ASI2IN", NULL , "MDAC"},
+ {"ASI2IN", NULL , "MADC"},
+
+ {"ASI2OUT", NULL , "NDAC"},
+ {"ASI2OUT", NULL , "NADC"},
+ {"ASI2OUT", NULL , "MDAC"},
+ {"ASI2OUT", NULL , "MADC"},
+
+#ifdef AIC3262_ASI2_MASTER
+ {"ASI2IN", NULL , "ASI2_BCLK"},
+ {"ASI2OUT", NULL , "ASI2_BCLK"},
+ {"ASI2IN", NULL , "ASI2_WCLK"},
+ {"ASI2OUT", NULL , "ASI2_WCLK"},
+#else
+
+#endif
+ {"ASI3IN", NULL , "NDAC"},
+ {"ASI3IN", NULL , "NADC"},
+ {"ASI3IN", NULL , "MDAC"},
+ {"ASI3IN", NULL , "MADC"},
+
+ {"ASI3OUT", NULL , "NDAC"},
+ {"ASI3OUT", NULL , "NADC"},
+ {"ASI3OUT", NULL , "MDAC"},
+ {"ASI3OUT", NULL , "MADC"},
+
+#ifdef AIC3262_ASI3_MASTER
+ {"ASI3IN", NULL , "ASI3_BCLK"},
+ {"ASI3OUT", NULL , "ASI3_BCLK"},
+ {"ASI3IN", NULL , "ASI3_WCLK"},
+ {"ASI3OUT", NULL , "ASI3_WCLK"},
+#else
+#endif
+/* Playback (DAC) Portion */
+ {"HPL Output Mixer","LDAC Switch","Left DAC"},
+ {"HPL Output Mixer","MAL Switch","MAL PGA"},
+ {"HPL Output Mixer","LOL-B1 Volume","LOL"},
+
+ {"HPR Output Mixer","LOR-B1 Volume","LOR"},
+ {"HPR Output Mixer","LDAC Switch","Left DAC"},
+ {"HPR Output Mixer","RDAC Switch","Right DAC"},
+ {"HPR Output Mixer","MAR Switch","MAR PGA"},
+
+ {"HPL Driver",NULL,"HPL Output Mixer"},
+ {"HPR Driver",NULL,"HPR Output Mixer"},
+
+ {"HPL",NULL,"HPL Driver"},
+ {"HPR",NULL,"HPR Driver"},
+
+ {"LOL Output Mixer","MAL Switch","MAL PGA"},
+ {"LOL Output Mixer","IN1L-B Switch","IN1L"},
+ {"LOL Output Mixer","LDAC Switch","Left DAC"},
+ {"LOL Output Mixer","RDAC Switch","Right DAC"},
+
+ {"LOR Output Mixer","LOL Switch","LOL"},
+ {"LOR Output Mixer","RDAC Switch","Right DAC"},
+ {"LOR Output Mixer","MAR Switch","MAR PGA"},
+ {"LOR Output Mixer","IN1R-B Switch","IN1R"},
+
+ {"LOL Driver",NULL,"LOL Output Mixer"},
+ {"LOR Driver",NULL,"LOR Output Mixer"},
+
+ {"LOL",NULL,"LOL Driver"},
+ {"LOR",NULL,"LOR Driver"},
+
+ {"REC Output Mixer","LOL-B2 Volume","LOL"},
+ {"REC Output Mixer","IN1L Volume","IN1L"},
+ {"REC Output Mixer","IN1R Volume","IN1R"},
+ {"REC Output Mixer","LOR-B2 Volume","LOR"},
+
+ {"RECP Driver",NULL,"REC Output Mixer"},
+ {"RECM Driver",NULL,"REC Output Mixer"},
+
+ {"RECP",NULL,"RECP Driver"},
+ {"RECM",NULL,"RECM Driver"},
+
+ {"SPKL Output Mixer","MAL Switch","MAL PGA"},
+ {"SPKL Output Mixer","LOL Volume","LOL"},
+ {"SPKL Output Mixer","SPR_IN Switch","SPKR Output Mixer"},
+
+ {"SPKR Output Mixer", "LOR Volume","LOR"},
+ {"SPKR Output Mixer", "MAR Switch","MAR PGA"},
+
+
+ {"SPKL Driver",NULL,"SPKL Output Mixer"},
+ {"SPKR Driver",NULL,"SPKR Output Mixer"},
+
+ {"SPKL",NULL,"SPKL Driver"},
+ {"SPKR",NULL,"SPKR Driver"},
+/* ASI Input routing */
+ {"ASI1LIN", NULL, "ASI1IN"},
+ {"ASI1RIN", NULL, "ASI1IN"},
+ {"ASI2LIN", NULL, "ASI2IN"},
+ {"ASI2RIN", NULL, "ASI2IN"},
+ {"ASI3LIN", NULL, "ASI3IN"},
+ {"ASI3RIN", NULL, "ASI3IN"},
+
+ {"ASI1MonoMixIN", NULL, "ASI1IN"},
+ {"ASI2MonoMixIN", NULL, "ASI2IN"},
+ {"ASI3MonoMixIN", NULL, "ASI3IN"},
+
+ {"ASI1LIN Route","ASI1 Left In","ASI1LIN"},
+ {"ASI1LIN Route","ASI1 Right In","ASI1RIN"},
+ {"ASI1LIN Route","ASI1 MonoMix In","ASI1MonoMixIN"},
+
+ {"ASI1RIN Route", "ASI1 Right In","ASI1RIN"},
+ {"ASI1RIN Route","ASI1 Left In","ASI1LIN"},
+ {"ASI1RIN Route","ASI1 MonoMix In","ASI1MonoMixIN"},
+
+
+ {"ASI2LIN Route","ASI2 Left In","ASI2LIN"},
+ {"ASI2LIN Route","ASI2 Right In","ASI2RIN"},
+ {"ASI2LIN Route","ASI2 MonoMix In","ASI2MonoMixIN"},
+
+ {"ASI2RIN Route","ASI2 Right In","ASI2RIN"},
+ {"ASI2RIN Route","ASI2 Left In","ASI2LIN"},
+ {"ASI2RIN Route","ASI2 MonoMix In","ASI2MonoMixIN"},
+
+
+ {"ASI3LIN Route","ASI3 Left In","ASI3LIN"},
+ {"ASI3LIN Route","ASI3 Right In","ASI3RIN"},
+ {"ASI3LIN Route","ASI3 MonoMix In","ASI3MonoMixIN"},
+
+ {"ASI3RIN Route","ASI3 Right In","ASI3RIN"},
+ {"ASI3RIN Route","ASI3 Left In","ASI3LIN"},
+ {"ASI3RIN Route","ASI3 MonoMix In","ASI3MonoMixIN"},
+
+ {"ASI1IN Port", NULL, "ASI1LIN Route"},
+ {"ASI1IN Port", NULL, "ASI1RIN Route"},
+ {"ASI2IN Port", NULL, "ASI2LIN Route"},
+ {"ASI2IN Port", NULL, "ASI2RIN Route"},
+ {"ASI3IN Port", NULL, "ASI3LIN Route"},
+ {"ASI3IN Port", NULL, "ASI3RIN Route"},
+
+ {"DAC MiniDSP IN1 Route", "ASI1 In","ASI1IN Port"},
+ {"DAC MiniDSP IN1 Route","ASI2 In","ASI2IN Port"},
+ {"DAC MiniDSP IN1 Route","ASI3 In","ASI3IN Port"},
+ {"DAC MiniDSP IN1 Route","ADC MiniDSP Out","ADC MiniDSP OUT1"},
+
+ {"Left DAC", "NULL", "DAC MiniDSP IN1 Route"},
+ {"Right DAC", "NULL", "DAC MiniDSP IN1 Route"},
+
+
+/* Mixer Amplifier */
+
+ {"MAL PGA Mixer", "IN1L Switch","IN1L"},
+ {"MAL PGA Mixer", "Left MicPGA Volume","Left MicPGA"},
+
+ {"MAL PGA", NULL, "MAL PGA Mixer"},
+
+
+ {"MAR PGA Mixer", "IN1R Switch","IN1R"},
+ {"MAR PGA Mixer", "Right MicPGA Volume","Right MicPGA"},
+
+ {"MAR PGA", NULL, "MAR PGA Mixer"},
+
+
+/* Capture (ADC) portions */
+ /* Left Positive PGA input */
+ {"Left Input Mixer","IN1L Switch","IN1L"},
+ {"Left Input Mixer","IN2L Switch","IN2L"},
+ {"Left Input Mixer","IN3L Switch","IN3L"},
+ {"Left Input Mixer","IN4L Switch","IN4L"},
+ {"Left Input Mixer","IN1R Switch","IN1R"},
+ /* Left Negative PGA input */
+ {"Left Input Mixer","IN2R Switch","IN2R"},
+ {"Left Input Mixer","IN3R Switch","IN3R"},
+ {"Left Input Mixer","IN4R Switch","IN4R"},
+ {"Left Input Mixer","CM2L Switch","CM2L"},
+ {"Left Input Mixer","CM1L Switch","CM1L"},
+
+ /* Right Positive PGA Input */
+ {"Right Input Mixer","IN1R Switch","IN1R"},
+ {"Right Input Mixer","IN2R Switch","IN2R"},
+ {"Right Input Mixer","IN3R Switch","IN3R"},
+ {"Right Input Mixer","IN4R Switch","IN4R"},
+ {"Right Input Mixer","IN2L Switch","IN2L"},
+
+ /* Right Negative PGA Input */
+ {"Right Input Mixer","IN1L Switch","IN1L"},
+ {"Right Input Mixer","IN3L Switch","IN3L"},
+ {"Right Input Mixer","IN4L Switch","IN4L"},
+ {"Right Input Mixer","CM1R Switch","CM1R"},
+ {"Right Input Mixer","CM2R Switch","CM2R"},
+
+ {"CM1L", NULL, "CM"},
+ {"CM2L", NULL, "CM"},
+ {"CM1R", NULL, "CM"},
+ {"CM1R", NULL, "CM"},
+
+ {"Left MicPGA",NULL,"Left Input Mixer"},
+ {"Right MicPGA",NULL,"Right Input Mixer"},
+
+ {"Left ADC", NULL, "Left MicPGA"},
+ {"Right ADC", NULL, "Right MicPGA"},
+
+/* ASI Output Routing */
+ {"ADC MiniDSP OUT1", NULL, "Left ADC"},
+ {"ADC MiniDSP OUT1", NULL, "Right ADC"},
+
+ {"ASI1OUT Route", "ASI1 Out","ADC MiniDSP OUT1"},// Port 1
+ {"ASI1OUT Route", "ASI1In Bypass","ASI1IN Port"},
+ {"ASI1OUT Route", "ASI2In Bypass","ASI2IN Port"},
+ {"ASI1OUT Route", "ASI3In Bypass","ASI3IN Port"},
+
+ {"ASI2OUT Route", "ASI1 Out","ADC MiniDSP OUT1"},// Port 1
+ {"ASI2OUT Route", "ASI1In Bypass","ASI1IN Port"},
+ {"ASI2OUT Route", "ASI2In Bypass","ASI2IN Port"},
+ {"ASI2OUT Route", "ASI3In Bypass","ASI3IN Port"},
+ {"ASI2OUT Route", "ASI2 Out","ADC MiniDSP OUT2"},// Port 2
+
+ {"ASI3OUT Route", "ASI1 Out","ADC MiniDSP OUT1"},// Port 1
+ {"ASI3OUT Route", "ASI1In Bypass","ASI1IN Port"},
+ {"ASI3OUT Route", "ASI2In Bypass","ASI2IN Port"},
+ {"ASI3OUT Route", "ASI3In Bypass","ASI3IN Port"},
+ {"ASI3OUT Route", "ASI3 Out","ADC MiniDSP OUT3"},// Port 3
+
+ {"ASI1OUT",NULL,"ASI1OUT Route"},
+ {"ASI2OUT",NULL,"ASI2OUT Route"},
+ {"ASI3OUT",NULL,"ASI3OUT Route"},
+
};
+
+#define AIC3262_DAPM_ROUTE_NUM (sizeof(aic3262_dapm_routes)/sizeof(struct snd_soc_dapm_route))
+
/*
*****************************************************************************
* Function Definitions
@@ -2785,25 +3223,52 @@ void aic3262_write_reg_cache(struct snd_soc_codec *codec,
*
*----------------------------------------------------------------------------
*/
+
u8 aic3262_read(struct snd_soc_codec *codec, u16 reg)
{
struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec);
u8 value;
u8 page = reg / 128;
-
+ u16 *cache = codec->reg_cache;
+ u16 cmd;
+ u8 buffer[2];
+ int rc;
reg = reg % 128;
- if (aic3262->page_no != page)
+ if (reg >= AIC3262_CACHEREGNUM) {
+ return 0;
+ }
+
+ if (aic3262->control_type == SND_SOC_I2C) {
+ if (aic3262->page_no != page) {
aic3262_change_page(codec, page);
+ }
+ i2c_master_send(codec->control_data, (char *)&reg, 1);
+ i2c_master_recv(codec->control_data, &value, 1);
+ /*DBG("r %2x %02x\r\n", reg, value); */
+ } else if (aic3262->control_type == SND_SOC_SPI) {
+ u16 value;
+
+ /* Do SPI transfer; first 16bits are command; remaining is
+ * register contents */
+ cmd = AIC3262_READ_COMMAND_WORD(reg);
+ buffer[0] = (cmd >> 8) & 0xff;
+ buffer[1] = cmd & 0xff;
+ //rc = spi_write_then_read(aic3262->spi, buffer, 2, buffer, 2);
+
+ if (rc) {
+ dev_err(&aic3262->spi->dev, "AIC26 reg read error\n");
+ return -EIO;
+ }
+ value = (buffer[0] << 8) | buffer[1];
+ } else {
+ printk(KERN_ERR "Unknown Interface Type in aic3262_read\n");
+ }
-#if defined(LOCAL_REG_ACCESS)
- i2c_master_send(codec->control_data, (char *)&reg, 1);
- i2c_master_recv(codec->control_data, &value, 1);
-#else
- value = snd_soc_read(codec, reg);
-#endif
- /*DBG("r %2x %02x\r\n", reg, value);*/
+ /* Update the cache before returning with the value */
+ cache[reg] = value;
return value;
+
}
/*
@@ -2932,44 +3397,6 @@ static inline int aic3262_get_divs(int mclk, int rate)
/*
*----------------------------------------------------------------------------
- * Function : aic3262_add_controls
- * Purpose : This function is to add non dapm kcontrols. The different
- * controls are in "aic3262_snd_controls" table.
- * The following different controls are supported
- * # PCM Playback volume control
- * # PCM Playback Volume
- * # HP Driver Gain
- * # HP DAC Playback Switch
- * # PGA Capture Volume
- * # Program Registers
- *
- *----------------------------------------------------------------------------
- */
-static int aic3262_add_controls(struct snd_soc_codec *codec)
-{
- int err;
-
- DBG("%s++\n", __func__);
-
- err = snd_soc_add_controls(codec, aic3262_snd_controls,
- ARRAY_SIZE(aic3262_snd_controls));
- if (err < 0) {
- printk(KERN_ERR "Invalid control\n");
- return err;
- }
-
- err = snd_soc_add_controls(codec, aic3262_snd_controls2,
- ARRAY_SIZE(aic3262_snd_controls2));
- if (err < 0) {
- printk(KERN_ERR "Invalid control\n");
- return err;
- }
-
- return 0;
-}
-
-/*
- *----------------------------------------------------------------------------
* Function : aic3262_add_widgets
* Purpose : This function is to add the dapm widgets
* The following are the main widgets supported
@@ -3002,7 +3429,7 @@ static int aic3262_add_widgets(struct snd_soc_codec *codec)
snd_soc_dapm_add_routes(dapm, aic3262_dapm_routes,
ARRAY_SIZE(aic3262_dapm_routes));
DBG("#Completed adding DAPM routes\n");
- /*snd_soc_dapm_new_widgets(codec);*/
+ snd_soc_dapm_new_widgets(dapm);
DBG("#Completed updating dapm\n");
return 0;
}
@@ -3028,7 +3455,7 @@ int reg_def_conf(struct snd_soc_codec *codec)
/* Configure the Codec with the default Initialization Values */
for (i = 0; i < reg_init_size; i++) {
- ret = aic3262_write(codec, aic3262_reg_init[i].reg_offset,
+ ret = snd_soc_write(codec, aic3262_reg_init[i].reg_offset,
aic3262_reg_init[i].reg_val);
if (ret)
break;
@@ -3083,132 +3510,48 @@ int i2c_verify_book0(struct snd_soc_codec *codec)
*
*----------------------------------------------------------------------------
*/
+
static int aic3262_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
+ enum snd_soc_bias_level level)
{
- u8 value;
struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec);
-
- DBG(KERN_INFO "#%s: Codec Active %d[%d]\n",
- __func__, codec->active, aic3262->active_count);
+ u8 value;
switch (level) {
/* full On */
case SND_SOC_BIAS_ON:
- DBG(KERN_INFO "#aic3262 codec : set_bias_on started\n");
- case SND_SOC_BIAS_PREPARE:
- /* all power is driven by DAPM system */
- DBG(KERN_INFO "#aic3262 codec : set_bias_prepare started\n");
-
- /* Switch on PLL */
- value = aic3262_read(codec, PLL_PR_POW_REG);
- aic3262_write(codec, PLL_PR_POW_REG, ((value | 0x80)));
-
- /* Switch on NDAC Divider */
- value = aic3262_read(codec, NDAC_DIV_POW_REG);
- aic3262_write(codec, NDAC_DIV_POW_REG,
- ((value & 0x7f) | (0x80)));
-
- /* Switch on MDAC Divider */
- value = aic3262_read(codec, MDAC_DIV_POW_REG);
- aic3262_write(codec, MDAC_DIV_POW_REG,
- ((value & 0x7f) | (0x80)));
-
- /* Switch on NADC Divider */
- value = aic3262_read(codec, NADC_DIV_POW_REG);
- aic3262_write(codec, NADC_DIV_POW_REG,
- ((value & 0x7f) | (0x80)));
-
- /* Switch on MADC Divider */
- value = aic3262_read(codec, MADC_DIV_POW_REG);
- aic3262_write(codec, MADC_DIV_POW_REG,
- ((value & 0x7f) | (0x80)));
+ /* all power is driven by DAPM system */
+ dev_dbg(codec->dev, "set_bias_on\n");
+ break;
- aic3262_write(codec, ADC_CHANNEL_POW, 0xc2);
- aic3262_write(codec, ADC_FINE_GAIN, 0x00);
+ /* partial On */
+ case SND_SOC_BIAS_PREPARE:
- DBG("#aic3262 codec : set_bias_on complete\n");
+ dev_dbg(codec->dev, "set_bias_prepare\n");
break;
-
- /* Off, with power */
+ /* Off, with power */
case SND_SOC_BIAS_STANDBY:
/*
* all power is driven by DAPM system,
* so output power is safe if bypass was set
*/
+ dev_dbg(codec->dev, "set_bias_stby\n");
- DBG("#aic3262 codec : set_bias_stby inside if condn\n");
-
- if (!aic3262->active_count) {
- /* Switch off NDAC Divider */
- value = aic3262_read(codec, NDAC_DIV_POW_REG);
- aic3262_write(codec, NDAC_DIV_POW_REG,
- (value & 0x7f));
-
- /* Switch off MDAC Divider */
- value = aic3262_read(codec, MDAC_DIV_POW_REG);
- aic3262_write(codec, MDAC_DIV_POW_REG,
- (value & 0x7f));
-
- /* Switch off NADC Divider */
- value = aic3262_read(codec, NADC_DIV_POW_REG);
- aic3262_write(codec, NADC_DIV_POW_REG,
- (value & 0x7f));
-
- /* Switch off MADC Divider */
- value = aic3262_read(codec, MADC_DIV_POW_REG);
- aic3262_write(codec, MADC_DIV_POW_REG,
- (value & 0x7f));
-
- /* Switch off PLL */
- value = aic3262_read(codec, PLL_PR_POW_REG);
- aic3262_write(codec, PLL_PR_POW_REG, (value & 0x7f));
-
- DBG("#%s: set_bias_stby complete\n", __func__);
- } else
- DBG(KERN_INFO
- "#%s: Another Stream Active. No STANDBY\n", __func__);
break;
-
- /* Off, without power */
+ /* Off, without power */
case SND_SOC_BIAS_OFF:
- /* force all power off */
-
- /* Switch off PLL */
- value = aic3262_read(codec, PLL_PR_POW_REG);
- aic3262_write(codec,
- PLL_PR_POW_REG, (value & ~(0x01 << 7)));
-
- /* Switch off NDAC Divider */
- value = aic3262_read(codec, NDAC_DIV_POW_REG);
- aic3262_write(codec, NDAC_DIV_POW_REG,
- (value & ~(0x01 << 7)));
-
- /* Switch off MDAC Divider */
- value = aic3262_read(codec, MDAC_DIV_POW_REG);
- aic3262_write(codec, MDAC_DIV_POW_REG,
- (value & ~(0x01 << 7)));
-
- /* Switch off NADC Divider */
- value = aic3262_read(codec, NADC_DIV_POW_REG);
- aic3262_write(codec, NADC_DIV_POW_REG,
- (value & ~(0x01 << 7)));
-
- /* Switch off MADC Divider */
- value = aic3262_read(codec, MADC_DIV_POW_REG);
- aic3262_write(codec, MADC_DIV_POW_REG,
- (value & ~(0x01 << 7)));
- value = aic3262_read(codec, ASI1_BCLK_N);
+ dev_dbg(codec->dev, "set_bias_off\n");
break;
}
- codec->dapm.bias_level = level;
- DBG(KERN_INFO "#aic3262 codec : set_bias exiting\n");
+ codec->dapm.bias_level=level;
+
return 0;
}
+
/*
*----------------------------------------------------------------------------
* Function : aic3262_suspend
@@ -3302,18 +3645,20 @@ static irqreturn_t aic3262_jack_handler(int irq, void *data)
unsigned int value;
unsigned int micbits, hsbits = 0;
- DBG("%s++\n", __func__);
+ //DBG("%s++\n", __func__);
+
+ pr_err("@@@@In Intrp\n");
aic3262_change_page(codec, 0);
/* Read the Jack Status Register*/
- value = aic3262_read(codec, STICKY_FLAG2);
+ value = snd_soc_read(codec, STICKY_FLAG2);
DBG(KERN_INFO "reg44 0x%x\n", value);
- value = aic3262_read(codec, INT_FLAG2);
+ value = snd_soc_read(codec, INT_FLAG2);
DBG("reg46 0x%x\n", value);
- value = aic3262_read(codec, DAC_FLAG_R1);
+ value = snd_soc_read(codec, DAC_FLAG_R1);
DBG("reg37 0x%x\n", value);
micbits = value & DAC_FLAG_MIC_MASKBITS;
@@ -3322,14 +3667,13 @@ static irqreturn_t aic3262_jack_handler(int irq, void *data)
hsbits = value & DAC_FLAG_HS_MASKBITS;
DBG("hsbits 0x%x\n", hsbits);
- /* sleep for debounce time */
- /*msleep(aic3262->pdata->debounce_time_ms);*/
/* No Headphone or Headset*/
if (!micbits && !hsbits) {
DBG("no headset/headphone\n");
snd_soc_jack_report(aic3262->headset_jack,
0, SND_JACK_HEADSET);
+ pr_err("@@@@NO HP or HS\n");
}
/* Headphone Detected */
@@ -3337,6 +3681,7 @@ static irqreturn_t aic3262_jack_handler(int irq, void *data)
DBG("headphone\n");
snd_soc_jack_report(aic3262->headset_jack,
SND_JACK_HEADPHONE, SND_JACK_HEADSET);
+ pr_err("@@@@HP detected\n");
}
/* Headset Detected - only with capless */
@@ -3344,6 +3689,7 @@ static irqreturn_t aic3262_jack_handler(int irq, void *data)
DBG("headset\n");
snd_soc_jack_report(aic3262->headset_jack,
SND_JACK_HEADSET, SND_JACK_HEADSET);
+ pr_err("@@@@HS detected\n");
}
DBG("%s--\n", __func__);
@@ -3419,7 +3765,6 @@ static void aic3262_asi_default_config(struct snd_soc_codec *codec)
aic3262->asiCtxt[2].right_dac_output = DAC_PATH_LEFT;
aic3262->asiCtxt[2].adc_input = ADC_PATH_MINIDSP_3;
aic3262->asiCtxt[2].dout_option = ASI2_INPUT;
-
return;
}
@@ -3432,6 +3777,7 @@ static void aic3262_asi_default_config(struct snd_soc_codec *codec)
*
*----------------------------------------------------------------------------
*/
+
static int aic3262_probe(struct snd_soc_codec *codec)
{
struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec);
@@ -3470,8 +3816,11 @@ static int aic3262_probe(struct snd_soc_codec *codec)
if (ret != 0) {
printk(KERN_ERR "Failed to init TI codec: %d\n", ret);
return ret;
+ } else {
+ pr_err("@@@@@@@@@@TI codec successfully init\n");
}
+
if (aic3262->irq) {
/* audio interrupt */
ret = request_threaded_irq(aic3262->irq, NULL,
@@ -3497,10 +3846,24 @@ static int aic3262_probe(struct snd_soc_codec *codec)
/* off, with power on */
aic3262_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- aic3262_add_controls(codec);
+ ret = snd_soc_add_controls(codec, aic3262_snd_controls,
+ ARRAY_SIZE(aic3262_snd_controls));
+ if(ret)
+ {
+ printk(KERN_INFO "%s failed\n", __func__);
+ }
+
aic3262_add_widgets(codec);
/*TODO*/
- aic3262_write(codec, MIC_BIAS_CNTL, 0x66);
+ snd_soc_write(codec, MIC_BIAS_CNTL, 0x66);
+
+#ifdef AIC3262_TiLoad
+ ret = aic3262_driver_init(codec);
+ if (ret < 0)
+ printk(KERN_ERR
+ "\nAIC3262 CODEC: aic3262_probe :TiLoad Initialization failed\n");
+#endif
+
#ifdef CONFIG_MINI_DSP
/* Program MINI DSP for ADC and DAC */
@@ -3517,6 +3880,8 @@ static int aic3262_probe(struct snd_soc_codec *codec)
return ret;
}
+
+
/*
*----------------------------------------------------------------------------
* Function : aic3262_remove
@@ -3581,6 +3946,7 @@ static __devinit int aic3262_codec_probe(struct i2c_client *i2c,
struct aic3262_priv *aic3262;
+ pr_err("@@@@@@@@@TI codec probe\n")
DBG(KERN_INFO "#%s: Entered\n", __func__);
aic3262 = kzalloc(sizeof(struct aic3262_priv), GFP_KERNEL);
@@ -3645,7 +4011,7 @@ static __devexit int aic3262_i2c_remove(struct i2c_client *i2c)
}
static const struct i2c_device_id tlv320aic3262_id[] = {
- {"tlv320aic3262", 0},
+ {"aic3262-codec", 0},
{}
};
MODULE_DEVICE_TABLE(i2c, tlv320aic3262_id);
@@ -3661,18 +4027,149 @@ static struct i2c_driver tlv320aic3262_i2c_driver = {
};
#endif /*#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)*/
+#if defined(CONFIG_SPI_MASTER)
+static int aic3262_spi_write(struct spi_device *spi, const char *data, int len)
+{
+ struct spi_transfer t;
+ struct spi_message m;
+ u8 msg[2];
+
+ if (len <= 0)
+ return 0;
+
+ msg[0] = data[0];
+ msg[1] = data[1];
+
+ spi_message_init(&m);
+ memset(&t, 0, (sizeof t));
+ t.tx_buf = &msg[0];
+ t.len = len;
+
+ spi_message_add_tail(&t, &m);
+ spi_sync(spi, &m);
+
+ return len;
+}
+
+/*
+ * This function forces any delayed work to be queued and run.
+ */
+static int run_delayed_work(struct delayed_work *dwork)
+{
+ int ret;
+
+ /* cancel any work waiting to be queued. */
+ ret = cancel_delayed_work(dwork);
+
+ /* if there was any work waiting then we run it now and
+ * wait for it's completion */
+ if (ret) {
+ schedule_delayed_work(dwork, 0);
+ flush_scheduled_work();
+ }
+ return ret;
+}
+static int __devinit aic3262_spi_probe(struct spi_device *spi)
+{
+ int ret;
+ struct snd_soc_codec *codec;
+ struct aic3262_priv *aic3262;
+ printk(KERN_INFO "%s entering\n",__func__);
+ aic3262 = kzalloc(sizeof(struct aic3262_priv), GFP_KERNEL);
+
+ if (!aic3262) {
+ printk(KERN_ERR "#%s: Unable to Allocate Priv struct..\n",
+ __func__);
+ return -ENOMEM;
+ }
+ codec = &aic3262->codec;
+ codec->control_data = spi;
+ aic3262->control_type = SND_SOC_SPI;
+ codec->hw_write = (hw_write_t)aic3262_spi_write;
+ codec->dev = &spi->dev;
+
+ aic3262->pdata = spi->dev.platform_data;
+
+ /* The Configuration Support will be by default to 3 which
+ * holds the MAIN Patch Configuration.
+ */
+ aic3262->current_dac_config[0] = -1;
+ aic3262->current_dac_config[1] = -1;
+ aic3262->current_adc_config[0] = -1;
+ aic3262->current_adc_config[1] = -1;
+
+ aic3262->mute_codec = 1;
+
+ aic3262->page_no = 0;
+ aic3262->book_no = 0;
+ aic3262->active_count = 0;
+ aic3262->dac_clkin_option = 3;
+ aic3262->adc_clkin_option = 3;
+ dev_set_drvdata(&spi->dev, aic3262);
+ spi_set_drvdata(spi, aic3262);
+ ret = snd_soc_register_codec(&spi->dev,
+ &soc_codec_dev_aic3262,
+ tlv320aic3262_dai, ARRAY_SIZE(tlv320aic3262_dai));
+
+ if (ret < 0) {
+ printk(KERN_INFO "%s codec registeration failed\n",__func__);
+ kfree(aic3262);
+ }
+ else {
+ printk(KERN_INFO "%s registered\n",__func__);
+ }
+ printk(KERN_INFO "#%s: Done ret %d\n", __func__, ret);
+ return ret;
+}
+
+static int __devexit aic3262_spi_remove(struct spi_device *spi)
+{
+ struct aic3262_priv *aic3262 = dev_get_drvdata(&spi->dev);
+ aic3262_set_bias_level(&aic3262->codec, SND_SOC_BIAS_OFF);
+ snd_soc_unregister_codec(&spi->dev);
+ kfree(aic3262);
+ aic3262_codec = NULL;
+ return 0;
+
+}
+
+static const struct spi_device_id tlv320aic3262_id[] = {
+ {"aic3262-codec", 0},
+ {}
+};
+static struct spi_driver aic3262_spi_driver = {
+ .driver = {
+ .name = "aic3262-codec",
+ .bus = &spi_bus_type,
+ .owner = THIS_MODULE,
+ },
+ .probe = aic3262_spi_probe,
+ .remove = __devexit_p(aic3262_spi_remove),
+ .id_table = tlv320aic3262_id,
+};
+#endif
static int __init tlv320aic3262_modinit(void)
{
int ret = 0;
+ printk(KERN_INFO "In %s\n",__func__);
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
ret = i2c_add_driver(&tlv320aic3262_i2c_driver);
if (ret != 0)
printk(KERN_ERR "Failed to register aic326x i2c driver %d\n",
ret);
+
+ pr_err("@@@@@@@@@TI modinit register I2C driver\n");
+#endif
+#if defined(CONFIG_SPI_MASTER)
+ printk(KERN_INFO "Inside config_spi_master\n");
+ ret = spi_register_driver(&aic3262_spi_driver);
+ if (ret != 0)
+ printk(KERN_ERR "Failed to register aic3262 SPI driver: %d\n", ret);
#endif
return ret;
}
+
module_init(tlv320aic3262_modinit);
static void __exit tlv320aic3262_exit(void)
diff --git a/sound/soc/codecs/tlv320aic326x.h b/sound/soc/codecs/tlv320aic326x.h
index 259ecb110787..d81b34f8eb34 100644
--- a/sound/soc/codecs/tlv320aic326x.h
+++ b/sound/soc/codecs/tlv320aic326x.h
@@ -2,7 +2,7 @@
* linux/sound/soc/codecs/tlv320aic3262.h
*
*
- * Copyright (C) 2011 Mistral Solutions Pvt Ltd.
+ * Copyright (C) 2012 Texas Instruments, Inc.
*
* This package is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -13,7 +13,7 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* History:
- * Rev 0.1 ASoC driver support Mistral 20-01-2011
+ * Rev 0.1 ASoC driver support 20-01-2011
*
* The AIC3262 ASoC driver is ported for the codec AIC3262.
*
@@ -40,6 +40,10 @@ result some issue with cache. Common code doesnot support
page, so fix that before commenting this line*/
#define LOCAL_REG_ACCESS 1
+/* Macro to enable the inclusion of tiload kernel driver */
+#define AIC3262_TiLoad
+
+
/* Macro enables or disables support for miniDSP in the driver */
/* Enable the AIC3262_TiLoad macro first before enabling these macros */
#define CONFIG_MINI_DSP
@@ -63,7 +67,7 @@ page, so fix that before commenting this line*/
#define AIC3262_MULTI_I2S 1
/* Driver Debug Messages Enabled */
-/*#define DEBUG*/
+//#define DEBUG
#ifdef DEBUG
#define DBG(x...) printk(x)
@@ -115,6 +119,7 @@ page, so fix that before commenting this line*/
/* Total number of ASI Ports */
#define MAX_ASI_COUNT 3
+
/* AIC3262 register space */
/* Updated from 256 to support Page 3 registers */
#define AIC3262_CACHEREGNUM 1024
@@ -246,7 +251,10 @@ page, so fix that before commenting this line*/
#define INT1_SEL_L (PAGE_1 + 34)
#define RAMP_CNTL_R1 (PAGE_1 + 36)
#define RAMP_CNTL_R2 (PAGE_1 + 37)
-#define INT1_SEL_RM (PAGE_1 + 39)
+//#define INT1_SEL_RM (PAGE_1 + 39)
+#define IN1L_SEL_RM (PAGE_1 + 39)
+#define IN1R_SEL_RM (PAGE_1 + 39)
+
#define REC_AMP_CNTL_R5 (PAGE_1 + 40)
#define RAMPR_VOL (PAGE_1 + 41)
#define RAMP_TIME_CNTL (PAGE_1 + 42)
@@ -304,6 +312,7 @@ page, so fix that before commenting this line*/
#define ASI3_ADC_INPUT_CNTL (PAGE_4 + 39)
#define ASI3_DAC_OUT_CNTL (PAGE_4 + 40)
#define ASI3_BWCLK_CNTL_REG (PAGE_4 + 42)
+#define ASI3_BCLK_N_CNTL (PAGE_4 + 43)
#define ASI3_BCLK_N (PAGE_4 + 44)
#define ASI3_WCLK_N (PAGE_4 + 45)
#define ASI3_BWCLK_OUT_CNTL (PAGE_4 + 46)
@@ -413,12 +422,21 @@ enum ASI_DAC_OUTPUT_OPTION {
DAC_PATH_RIGHT, /* 02 DAC Datapath Right Data */
};
+#define AIC3262_READ_COMMAND_WORD(addr) ((1 << 15) | (addr << 5))
+#define AIC3262_WRITE_COMMAND_WORD(addr) ((0 << 15) | (addr << 5))
+
/* Shift the above options by so many bits */
#define AIC3262_ASI_LDAC_PATH_SHIFT 6
#define AIC3262_ASI_LDAC_PATH_MASK (BIT5 | BIT4)
#define AIC3262_ASI_RDAC_PATH_SHIFT 4
#define AIC3262_ASI_RDAC_PATH_MASK (BIT7 | BIT6)
+
+#define DAC_LR_MUTE_MASK 0xc
+#define DAC_LR_MUTE 0xc
+#define ENABLE_CLK_MASK 0x80
+#define ENABLE_CLK 0x80
+
/* ASI specific ADC Input Control Options */
enum ASI_ADC_INPUT_OPTION {
ADC_PATH_OFF = 0, /* 00 ASI Digital Output Disabled */
@@ -509,6 +527,7 @@ struct aic3262_asi_data {
struct aic3262_priv {
enum snd_soc_control_type control_type;
struct aic326x_pdata *pdata;
+ struct snd_soc_codec codec;
u32 sysclk;
s32 master;
u8 book_no;
@@ -524,6 +543,14 @@ struct aic3262_priv {
u8 dac_clkin_option;
u8 adc_clkin_option;
int irq;
+ u8 dac_reg;
+ u8 adc_gain;
+ u8 hpl;
+ u8 hpr;
+ u8 rec_amp;
+ u8 rampr;
+ u8 spk_amp;
+ struct spi_device *spi;
struct snd_soc_jack *headset_jack;
#if defined(LOCAL_REG_ACCESS)
void *control_data;
diff --git a/sound/soc/codecs/tlv320aic326x_mini-dsp.c b/sound/soc/codecs/tlv320aic326x_mini-dsp.c
index 4d9c4de7e59a..feefe7dd8f4d 100644
--- a/sound/soc/codecs/tlv320aic326x_mini-dsp.c
+++ b/sound/soc/codecs/tlv320aic326x_mini-dsp.c
@@ -1,7 +1,7 @@
/*
* linux/sound/soc/codecs/tlv320aic326x_mini-dsp.c
*
- * Copyright (C) 2011 Mistral Solutions Pvt Ltd.
+ * Copyright (C) 2012 Texas Instruments, Inc.
*
* This package is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -16,10 +16,10 @@
*
* History:
*
- * Rev 0.1 Added the miniDSP Support Mistral 01-03-2011
+ * Rev 0.1 Added the miniDSP Support 01-03-2011
*
* Rev 0.2 Updated the code-base for miniDSP switching and
- * mux control update. Mistral 21-03-2011
+ * mux control update. 21-03-2011
*
* Rev 0.3 Updated the code-base to support Multi-Configuration feature
* of PPS GDE
@@ -192,6 +192,7 @@ void update_kcontrols(struct snd_soc_codec *codec, int process_flow)
val1 = i2c_smbus_read_byte_data(codec->control_data,
cntl[i].control_base);
snd_mux_controls[i].private_value = 0;
+ aic3262_change_book(codec,0);
}
}
@@ -236,6 +237,7 @@ int byte_i2c_array_transfer(struct snd_soc_codec *codec,
return -EIO;
}
}
+ aic3262_change_book(codec,0);
return 0;
}
@@ -434,7 +436,7 @@ set_minidsp_mode(struct snd_soc_codec *codec, int new_mode)
DBG("%s: switch mode start\n", __func__);
aic3262_reset_cache(codec);
- reg_def_conf(codec);
+ /*reg_def_conf(codec);*/
if (new_mode == 0) {
@@ -830,7 +832,9 @@ int aic3262_minidsp_program(struct snd_soc_codec *codec)
DBG("#Verifying book 0\n");
i2c_verify_book0(codec);
#endif
+ aic3262_change_book(codec,0);
set_minidsp_mode1(codec, 1);
+ aic3262_change_book(codec,0);
#ifdef DEBUG
DBG("#verifying book 0\n");
i2c_verify_book0(codec);
@@ -882,12 +886,14 @@ static int m_control_get(struct snd_kcontrol *kcontrol,
val1 = i2c_smbus_read_byte_data(codec->control_data, 1);
ucontrol->value.integer.value[0] = ((val1>>1)&0x01);
DBG(KERN_INFO "control get : mode=%d\n", aic3262->process_flow);
+ aic3262_change_book(codec,0);
}
if (!strcmp(kcontrol->id.name, "ADC Adaptive mode Enable")) {
aic3262_change_book(codec, 40);
val1 = i2c_smbus_read_byte_data(codec->control_data, 1);
ucontrol->value.integer.value[0] = ((val1>>1)&0x01);
DBG(KERN_INFO "control get : mode=%d\n", dmode);
+ aic3262_change_book(codec,0);
}
return 0;
@@ -939,6 +945,7 @@ static int m_control_put(struct snd_kcontrol *kcontrol,
aic3262_change_book(codec, 80);
val1 = i2c_smbus_read_byte_data(codec->control_data, 1);
aic3262_write(codec, 1, (val1&0xfb)|(val<<1));
+ aic3262_change_book(codec,0);
}
amode = val;
}
@@ -950,6 +957,7 @@ static int m_control_put(struct snd_kcontrol *kcontrol,
aic3262_change_book(codec, 40);
val1 = i2c_smbus_read_byte_data(codec->control_data, 1);
aic3262_write(codec, 1, (val1&0xfb)|(val<<1));
+ aic3262_change_book(codec,0);
}
dmode = val;
}
@@ -1234,6 +1242,7 @@ static int minidsp_mux_ctrl_mixer_controls(struct snd_soc_codec *codec,
snd_mux_controls[i].name);
}
}
+ aic3262_change_book(codec, 0);
return 0;
}
diff --git a/sound/soc/codecs/tlv320aic326x_mini-dsp.h b/sound/soc/codecs/tlv320aic326x_mini-dsp.h
index 394fa5954dde..bbc781776089 100644
--- a/sound/soc/codecs/tlv320aic326x_mini-dsp.h
+++ b/sound/soc/codecs/tlv320aic326x_mini-dsp.h
@@ -14,10 +14,10 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* History:
- * Rev 0.1 Added the multiconfig support Mistral 17-08-2011
+ * Rev 0.1 Added the multiconfig support 17-08-2011
*
* Rev 0.2 Migrated for aic3262 nVidia
- * Mistral 21-10-2011
+ * 21-10-2011
*/
#ifndef _TLV320AIC3262_MINI_DSP_H
diff --git a/sound/soc/codecs/tlv320aic326x_minidsp_config.c b/sound/soc/codecs/tlv320aic326x_minidsp_config.c
index 07b762aeedbc..ee8ca71dc7f8 100644
--- a/sound/soc/codecs/tlv320aic326x_minidsp_config.c
+++ b/sound/soc/codecs/tlv320aic326x_minidsp_config.c
@@ -1,7 +1,7 @@
/*
* linux/sound/soc/codecs/tlv320aic326x_minidsp_config.c
*
- * Copyright (C) 2011 Mistral Solutions Pvt Ltd.
+ * Copyright (C) 2012 Texas Instruments, Inc.
*
* This package is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -16,10 +16,10 @@
*
* History:
*
- * Rev 0.1 Added the multiconfig support Mistral 17-08-2011
+ * Rev 0.1 Added the multiconfig support 17-08-2011
*
* Rev 0.2 Migrated for aic3262 nVidia
- * Mistral 21-10-2011
+ * 21-10-2011
*/
/*
@@ -66,7 +66,7 @@
* LOCAL STATIC DECLARATIONS
*****************************************************************************
*/
-static int multibyte_coeff_change(struct snd_soc_codec *codec, int);
+int multibyte_coeff_change(struct snd_soc_codec *codec, int);
static int m_control_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
@@ -350,7 +350,7 @@ void config_multibyte_for_mode(struct snd_soc_codec *codec, int mode)
* miniDSP_D and miniDSP_A Coefficient arrays.
*---------------------------------------------------------------------------
*/
-static int multibyte_coeff_change(struct snd_soc_codec *codec, int bk)
+int multibyte_coeff_change(struct snd_soc_codec *codec, int bk)
{
u8 value[2], swap_reg_pre, swap_reg_post;
@@ -399,6 +399,9 @@ static int multibyte_coeff_change(struct snd_soc_codec *codec, int bk)
swap_reg_pre, swap_reg_post);
}
+ aic3262_change_book(codec, 0);
+ return 0;
+
err:
return 0;
}