From daf07e486601b92272b03544e6e043e4a582d2e1 Mon Sep 17 00:00:00 2001 From: Sugar Zhang Date: Tue, 19 Nov 2019 14:45:04 +0800 Subject: [PATCH] ASoC: codecs: remove unused codecs Change-Id: I8ed1e51666c767c8698d6d0a8f647ee64cfa5a02 Signed-off-by: Sugar Zhang --- sound/soc/codecs/ak4396.c | 467 ---- sound/soc/codecs/cx2070x-i2c.h | 415 ---- sound/soc/codecs/cx2070x.c | 2290 ------------------ sound/soc/codecs/cx2070x.h | 90 - sound/soc/codecs/cxdebug.c | 266 -- sound/soc/codecs/cxdebug.h | 46 - sound/soc/codecs/cxpump.c | 978 -------- sound/soc/codecs/cxpump.h | 207 -- sound/soc/codecs/dw-hdmi-audio.c | 107 - sound/soc/codecs/es8323_pcm.c | 366 --- sound/soc/codecs/gva_codec.c | 93 - sound/soc/codecs/pickle.h | 8 - sound/soc/codecs/rk2928_codec.c | 671 ------ sound/soc/codecs/rk2928_codec.h | 89 - sound/soc/codecs/rk3026_codec.c | 2169 ----------------- sound/soc/codecs/rk3026_codec.h | 565 ----- sound/soc/codecs/rk3036_codec.c | 1132 --------- sound/soc/codecs/rk3036_codec.h | 160 -- sound/soc/codecs/rk3190_codec.c | 2278 ------------------ sound/soc/codecs/rk3190_codec.h | 591 ----- sound/soc/codecs/rk610_codec.c | 1111 --------- sound/soc/codecs/rk610_codec.h | 268 --- sound/soc/codecs/rk616_codec.c | 3280 ------------------------- sound/soc/codecs/rk616_codec.h | 793 ------ sound/soc/codecs/rt3261-dsp.c | 1299 ---------- sound/soc/codecs/rt3261-dsp.h | 42 - sound/soc/codecs/rt3261.c | 3749 ----------------------------- sound/soc/codecs/rt3261.h | 2170 ----------------- sound/soc/codecs/rt3261_ioctl.c | 467 ---- sound/soc/codecs/rt3261_ioctl.h | 35 - sound/soc/codecs/rt5512.c | 1855 -------------- sound/soc/codecs/rt5512.h | 50 - sound/soc/codecs/rt5621.c | 1234 ---------- sound/soc/codecs/rt5621.h | 515 ---- sound/soc/codecs/rt5623.c | 206 -- sound/soc/codecs/rt5623.h | 506 ---- sound/soc/codecs/rt5625.c | 3185 ------------------------ sound/soc/codecs/rt5625.h | 823 ------- sound/soc/codecs/rt_codec_ioctl.c | 179 -- sound/soc/codecs/rt_codec_ioctl.h | 78 - sound/soc/codecs/tc358749x.c | 307 --- 41 files changed, 35140 deletions(-) delete mode 100755 sound/soc/codecs/ak4396.c delete mode 100755 sound/soc/codecs/cx2070x-i2c.h delete mode 100755 sound/soc/codecs/cx2070x.c delete mode 100755 sound/soc/codecs/cx2070x.h delete mode 100644 sound/soc/codecs/cxdebug.c delete mode 100644 sound/soc/codecs/cxdebug.h delete mode 100644 sound/soc/codecs/cxpump.c delete mode 100644 sound/soc/codecs/cxpump.h delete mode 100644 sound/soc/codecs/dw-hdmi-audio.c delete mode 100755 sound/soc/codecs/es8323_pcm.c delete mode 100644 sound/soc/codecs/gva_codec.c delete mode 100644 sound/soc/codecs/pickle.h delete mode 100755 sound/soc/codecs/rk2928_codec.c delete mode 100755 sound/soc/codecs/rk2928_codec.h delete mode 100644 sound/soc/codecs/rk3026_codec.c delete mode 100644 sound/soc/codecs/rk3026_codec.h delete mode 100755 sound/soc/codecs/rk3036_codec.c delete mode 100644 sound/soc/codecs/rk3036_codec.h delete mode 100644 sound/soc/codecs/rk3190_codec.c delete mode 100644 sound/soc/codecs/rk3190_codec.h delete mode 100755 sound/soc/codecs/rk610_codec.c delete mode 100755 sound/soc/codecs/rk610_codec.h delete mode 100644 sound/soc/codecs/rk616_codec.c delete mode 100644 sound/soc/codecs/rk616_codec.h delete mode 100644 sound/soc/codecs/rt3261-dsp.c delete mode 100644 sound/soc/codecs/rt3261-dsp.h delete mode 100755 sound/soc/codecs/rt3261.c delete mode 100755 sound/soc/codecs/rt3261.h delete mode 100755 sound/soc/codecs/rt3261_ioctl.c delete mode 100644 sound/soc/codecs/rt3261_ioctl.h delete mode 100644 sound/soc/codecs/rt5512.c delete mode 100644 sound/soc/codecs/rt5512.h delete mode 100644 sound/soc/codecs/rt5621.c delete mode 100644 sound/soc/codecs/rt5621.h delete mode 100755 sound/soc/codecs/rt5623.c delete mode 100644 sound/soc/codecs/rt5623.h delete mode 100644 sound/soc/codecs/rt5625.c delete mode 100644 sound/soc/codecs/rt5625.h delete mode 100644 sound/soc/codecs/rt_codec_ioctl.c delete mode 100644 sound/soc/codecs/rt_codec_ioctl.h delete mode 100644 sound/soc/codecs/tc358749x.c diff --git a/sound/soc/codecs/ak4396.c b/sound/soc/codecs/ak4396.c deleted file mode 100755 index 882d7ec8a18f..000000000000 --- a/sound/soc/codecs/ak4396.c +++ /dev/null @@ -1,467 +0,0 @@ -/* - * AK4396 ALSA SoC (ASoC) driver - * - * Copyright (c) 2009 Daniel Mack - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -/* AK4396 registers addresses */ -#define AK4396_REG_CONTROL1 0x00 -#define AK4396_REG_CONTROL2 0x01 -#define AK4396_REG_CONTROL3 0x02 -#define AK4396_REG_LCH_ATT 0x03 -#define AK4396_REG_RCH_ATT 0x04 -#define AK4396_NUM_REGS 5 - -#define AK4396_REG_MASK 0x1f -#define AK4396_WRITE 0x20 /*C1 C0 R/W A4 A3 A2 A1 A0 8bit==0010 0000 */ - -/* Bit masks for AK4396 registers */ -#define AK4396_CONTROL1_RSTN (1 << 0) -#define AK4396_CONTROL1_DIF0 (1 << 1) -#define AK4396_CONTROL1_DIF1 (1 << 2) -#define AK4396_CONTROL1_DIF2 (1 << 3) - -#define DRV_NAME "AK4396" - -struct ak4396_private { - enum snd_soc_control_type control_type; - void *control_data; - unsigned int sysclk; -}; - -#if 0 - -static const u16 ak4396_reg[AK4396_NUM_REGS] = { - 0x87, 0x02, 0x00, 0xff, 0xff -}; //CONFIG_LINF -#else -static const u16 ak4396_reg[AK4396_NUM_REGS] = { - 0x05, 0x02, 0x00, 0xff, 0xff -}; //CONFIG_LINF - -#endif - -static void on_off_ext_amp(int i) -{ - - #ifdef SPK_CTL - //gpio_direction_output(SPK_CTL, GPIO_LOW); - gpio_set_value(SPK_CTL, i); - printk("*** %s() SPEAKER set as %d\n", __FUNCTION__, i); - #endif - #ifdef EAR_CON_PIN - //gpio_direction_output(EAR_CON_PIN, GPIO_LOW); - gpio_set_value(EAR_CON_PIN, i); - printk("*** %s() HEADPHONE set as %d\n", __FUNCTION__, i); - mdelay(50); - #endif -} - -static int ak4396_fill_cache(struct snd_soc_codec *codec) -{ - int i; - u8 *reg_cache = codec->reg_cache; - struct spi_device *spi = codec->control_data; - - for (i = 0; i < codec->driver->reg_cache_size; i++) { - int ret = spi_w8r8(spi, i); - if (ret < 0) { - dev_err(&spi->dev, "SPI write failure\n"); - return ret; - } - - reg_cache[i] = ret; - } - - return 0; -} - -/* read the reg_cache */ -static unsigned int ak4396_read_reg_cache(struct snd_soc_codec *codec, - unsigned int reg) -{ - u8 *reg_cache = codec->reg_cache; - - if (reg >= codec->driver->reg_cache_size) - return -EINVAL; - -// printk("read reg_cache[%x]====%d\n", reg, reg_cache[reg]); - return reg_cache[reg]; -} - -static int ak4396_spi_write(struct snd_soc_codec *codec, unsigned int reg, - unsigned int value) -{ - u8 *cache = codec->reg_cache; - struct spi_device *spi = codec->control_data; - - if (reg >= codec->driver->reg_cache_size) - return -EINVAL; - - /* only write to the hardware if value has changed */ - //if (cache[reg] != value) - //{ - u8 tmp[2] = { (reg & AK4396_REG_MASK) | AK4396_WRITE, value}; - //printk("tmp[0]===%d\n", tmp[0]); - //printk("tmp[1]===%d\n", tmp[1]); - if (spi_write(spi, tmp, sizeof(tmp))) { - dev_err(&spi->dev, "SPI write failed\n"); - return -EIO; - } - - cache[reg] = value; - //} - return 0; -} - -/* write the register space */ -static ak4396_write(struct snd_soc_codec *codec) -{ - int ret, val, i; - val = 0; - int addr[5] = {0x00, 0x01, 0x02, 0x03, 0x04}; - int dat[5] = {0x87, 0x02, 0x00, 0xff, 0xff}; -// while(1){ - val |= AK4396_CONTROL1_RSTN; - ak4396_spi_write(codec, AK4396_REG_CONTROL1, val); - - for(i=0; i<5; i++) - { - ret = ak4396_spi_write(codec, addr[i], dat[i]); - if (ret < 0) - printk("ak4396_spi_write failed!\n"); - - printk("write %d time(s)\n", i); - } -// } -} - -/* - * Note that this should be called from init rather than from hw_params. - */ -static int ak4396_set_dai_sysclk(struct snd_soc_dai *codec_dai, - int clk_id, unsigned int freq, int dir) -{ - struct snd_soc_codec *codec = codec_dai->codec; - struct ak4396_private *ak4396 = snd_soc_codec_get_drvdata(codec); - - printk("Enter::%s----%d\n",__FUNCTION__,__LINE__); - printk("freq======%d\n", freq); - ak4396->sysclk = freq; - - return 0; -} - -static int ak4396_set_dai_fmt(struct snd_soc_dai *codec_dai, - unsigned int format) -{ - struct snd_soc_codec *codec = codec_dai->codec; - int val = 0; - - printk("%s----%d, format[%02x]\n",__FUNCTION__,__LINE__,format); - val = ak4396_read_reg_cache(codec, AK4396_REG_CONTROL1); - if (val < 0) - return val; - val &= ~(AK4396_CONTROL1_DIF0 | AK4396_CONTROL1_DIF1 | AK4396_CONTROL1_DIF2); -// printk("ak4396 val=%d\n", val); - - /* set DAI format */ - switch (format & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_RIGHT_J: - val |= AK4396_CONTROL1_DIF2 ; - printk("SND_SOC_DAIFMT_RIGHT_J: \n"); - break; - case SND_SOC_DAIFMT_LEFT_J: - val |= AK4396_CONTROL1_DIF1 ; - printk("SND_SOC_DAIFMT_LEFT_J: \n"); - break; - case SND_SOC_DAIFMT_I2S: - val |= AK4396_CONTROL1_DIF0 | AK4396_CONTROL1_DIF1 ; - //val |= 0x87; - - printk("SND_SOC_DAIFMT_I2S is ok!\n"); - break; - default: - dev_err(codec->dev, "invalid dai format\n"); - return -EINVAL; - } - - /* This device can only be slave */ - if ((format & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) - { - printk("%s failed!----%d\n",__FUNCTION__,__LINE__); - return -EINVAL; - } - - //val |= AK4396_CONTROL1_RSTN; - printk("AK4396 CONTROL1 val ==== %d\n", val); - ak4396_spi_write(codec, AK4396_REG_CONTROL1, val); - - return 0; -} - -static int ak4396_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec *codec = rtd->codec; - int val = 0; - - switch (params_rate(params)) { - - case 176400: - val |= IEC958_AES3_CON_FS_176400; - printk("params_rate::=176400!\n"); - break; - - case 192000: - val |= IEC958_AES3_CON_FS_192000; - printk("params_rate::=192000!\n"); - break; - - case 88200: - val |= IEC958_AES3_CON_FS_88200; - printk("params_rate::=88200!\n"); - break; - - - case 96000: - val |= IEC958_AES3_CON_FS_96000; - printk("params_rate::=96000!\n"); - break; - - case 44100: - val |= IEC958_AES3_CON_FS_44100; - printk("params_rate::=44100!\n"); - break; - case 48000: - val |= IEC958_AES3_CON_FS_48000; - break; - case 32000: - val |= IEC958_AES3_CON_FS_32000; - break; - default: - dev_err(codec->dev, "unsupported sampling rate\n"); - return -EINVAL; - } - val = 0; - val = ak4396_read_reg_cache(codec, AK4396_REG_CONTROL1); - //reset RSTN bit; - val &= 0xFE; - printk("val ==== %d\n", val); - ak4396_spi_write(codec, AK4396_REG_CONTROL1, val); - val |= 0x01; - printk("val ==== %d\n", val); - ak4396_spi_write(codec, AK4396_REG_CONTROL1, val); - - //printk("val === %d\n", val); - //ak4396_spi_write(codec, AK4396_REG_CONTROL2, val); - return 0; -} - -static struct snd_soc_dai_ops ak4396_dai_ops = { - .hw_params = ak4396_hw_params, - .set_fmt = ak4396_set_dai_fmt, - .set_sysclk = ak4396_set_dai_sysclk, -}; - -static struct snd_soc_dai_driver ak4396_dai = { - .name = "AK4396 HiFi", - .playback = { - .stream_name = "Playback", - .channels_min = 2, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_8000_192000, - .formats = SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S24_3LE | - SNDRV_PCM_FMTBIT_S24_LE | - SNDRV_PCM_FMTBIT_S32_LE - }, - .ops = &ak4396_dai_ops, -}; - -struct snd_soc_codec *codec_temp; -static int ak4396_probe(struct snd_soc_codec *codec) -{ - struct ak4396_private *ak4396 = snd_soc_codec_get_drvdata(codec); - int ret; - printk("ak4396_probe begin!\n"); - codec->control_data = ak4396->control_data; - codec_temp = codec; -#if 0 - /* read all regs and fill the cache */ - ret = ak4396_fill_cache(codec); - if (ret < 0) { - dev_err(codec->dev, "failed to fill register cache\n"); - return ret; - } -#endif - /* write to ak4396_reg */ -// ak4396_write(codec); - - printk("ak4396_probe is ok!\n"); - dev_info(codec->dev, "SPI device initialized\n"); - return 0; -} - -static int ak4396_remove(struct snd_soc_codec *codec) -{ - int val, ret; - - val = ak4396_read_reg_cache(codec, AK4396_REG_CONTROL1); - if (val < 0) - return val; - - /* set non-reset bits */ - val &= ~AK4396_CONTROL1_RSTN; - ret = ak4396_spi_write(codec, AK4396_REG_CONTROL1, val); - - return ret; -} - -static int ak4396_suspend(struct snd_soc_codec *codec) -{ - return 0; -} - -static int ak4396_resume(struct snd_soc_codec *codec) -{ - //ak4396_write(codec); - return 0; -} - -static struct snd_soc_codec_driver soc_codec_device_ak4396 = { - .probe = ak4396_probe, - .remove = ak4396_remove, - .suspend = ak4396_suspend, - .resume = ak4396_resume, - .reg_cache_size = AK4396_NUM_REGS, - .reg_word_size = sizeof(u16), - .reg_cache_default = ak4396_reg, -}; - -static struct class *cls = NULL; - -static ssize_t store_ak4396_reg(struct class *dev, - struct class_attribute *attr, const char *buf, size_t count) -{ - int reg, value, ret; -// char buf[10] = "123 11"; - char *start = buf; - - printk("%s, the first dat is reg, the second dat is data, data type is dex\n", __FUNCTION__); - while (*start == ' ') - start++; - reg = simple_strtoull(start, &start, 16); - - while (*start == ' ') - start++; - value = simple_strtoull(start, &start, 16); - - - ret = ak4396_spi_write(codec_temp, reg, value); - if (ret < 0) - printk("ak4396_spi_write failed!\n"); - - printk("reg = %d, value =%d\n", reg, value); -// return 0; -} -static struct class_attribute attr[] = { - __ATTR(write_reg, 0644, NULL, store_ak4396_reg), - __ATTR_NULL, -}; -static int ak4396_spi_probe(struct spi_device *spi) -{ - struct ak4396_private *ak4396; - int ret; - printk("ak4396_spi_probe begin!\n"); - -#if 0 //defined(CONFIG_ARCH_RK3188) - iomux_set(SPI1_CS0); - iomux_set(SPI1_CLK); - iomux_set(SPI1_TXD); - printk("iomux_set is OK!!!\n"); -#endif - - spi->bits_per_word = 8; - spi->mode = SPI_MODE_0; - ret = spi_setup(spi); - if (ret < 0) - return ret; - - ak4396 = kzalloc(sizeof(struct ak4396_private), GFP_KERNEL); - if (ak4396 == NULL) - return -ENOMEM; - - ak4396->control_data = spi; - ak4396->control_type = SND_SOC_SPI; - spi_set_drvdata(spi, ak4396); - - cls = class_create(THIS_MODULE, DRV_NAME); - if (IS_ERR(cls)) - { - printk("class_create failed!\n"); - } - ret = class_create_file(cls, attr); - if (ret < 0) - { - printk("class_create_file failed!\n"); - } - - ret = snd_soc_register_codec(&spi->dev, - &soc_codec_device_ak4396, &ak4396_dai, 1); - if (ret < 0) - kfree(ak4396); - - printk("ak4396_spi_probe successful!\n"); - return ret; -} - -static int ak4396_spi_remove(struct spi_device *spi) -{ - snd_soc_unregister_codec(&spi->dev); - kfree(spi_get_drvdata(spi)); - return 0; -} - -static struct spi_driver ak4396_spi_driver = { - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - }, - .probe = ak4396_spi_probe, - .remove = ak4396_spi_remove, -}; - -static int __init ak4396_init(void) -{ - printk("%s\n", __FUNCTION__); - return spi_register_driver(&ak4396_spi_driver); -} -module_init(ak4396_init); - -static void __exit ak4396_exit(void) -{ - spi_unregister_driver(&ak4396_spi_driver); -} -module_exit(ak4396_exit); - -MODULE_AUTHOR("Daniel Mack "); -MODULE_DESCRIPTION("Asahi Kasei AK4396 ALSA SoC driver"); -MODULE_LICENSE("GPL"); - diff --git a/sound/soc/codecs/cx2070x-i2c.h b/sound/soc/codecs/cx2070x-i2c.h deleted file mode 100755 index 958b801bfd47..000000000000 --- a/sound/soc/codecs/cx2070x-i2c.h +++ /dev/null @@ -1,415 +0,0 @@ -/* - * Cx2070x ASoc codec driver. - * - * Copyright: (C) 2010/2011 Conexant Systems - * - * Based on sound/soc/codecs/tlv320aic2x.c by Vladimir Barinov - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * The software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along with - * this software. If not, see - * - * All copies of the software must include all unaltered copyright notices, - * disclaimers of warranty, all notices that refer to the General Public License - * and the absence of any warranty. - * - * History - * Added support for CX2070x codec [www.conexant.com] -*/ - - -// force to enable TX/RX on 2nd PCM interface. - -#ifndef _PASS1_COMPLETE_ -# ifdef CONFIG_SND_DIGICOLOR_SOC_CHANNEL_VER_3_13F -# endif -# ifdef CONFIG_SND_DIGICOLOR_SOC_CHANNEL_VER_4_30F -# endif -#endif - - __REG(PLAYBACK_REGISTER, 0xffff, 0xffff, 0x00, 0, DM, B) - __REG(CAPTURE_REGISTER, 0xffff, 0xffff, 0x00, 0, DM, B) - __REG(MICBIAS_REGISTER, 0xffff, 0xffff, 0x00, 0, DM, B) - -///////////////////////////////////////////////////////////////////////// -// General codec operations registers -///////////////////////////////////////////////////////////////////////// -// id addr data bias type - __REG(ABORT_CODE, 0x1000, 0x1000, 0x00, 0, RO,B) - __REG(FIRMWARE_VERSION, 0x1001, 0x1001, 0x00, 0, RO,W) - __REG(PATCH_VERSION, 0x1003, 0x1003, 0x00, 0, RO,W) - __REG(CHIP_VERSION, 0x1005, 0x1005, 0x00, 0, RO,B) - __REG(RELEASE_TYPE, 0x1006, 0x1006, 0x00, 0, RO,B) - __REG(USB_LOCAL_VOLUME, 0x004E, 0x004E, 0x42, 0, RW,B) - __REG(ROM_PATCH_VER_HB, 0x1584, 0xFFFF, 0x00, 0, RO,B) - __REG(ROM_PATCH_VER_MB, 0x1585, 0xFFFF, 0x00, 0, RO,B) - __REG(ROM_PATCH_VER_LB, 0x1586, 0xFFFF, 0x00, 0, RO,B) - - __REG(DAC1_GAIN_LEFT, 0x100D, 0x100D, 0x00, 0x00, RW,B) - __REG(DAC2_GAIN_RIGHT, 0x100E, 0x100E, 0x00, 0x00, RW,B) - __REG(DSP_MAX_VOLUME, 0x100F, 0x100F, 0x00, 0, RW,B) - - __REG(CLASS_D_GAIN, 0x1011, 0x1010, b_00000000, 0, RW,B) -#ifndef _PASS1_COMPLETE_ -#define CLASS_D_GAIN_2W8 b_00000000 // 2.8W -#define CLASS_D_GAIN_2W6 b_00000001 // 2.6W -#define CLASS_D_GAIN_2W5 b_00000010 // 2.5W -#define CLASS_D_GAIN_2W4 b_00000011 // 2.4W -#define CLASS_D_GAIN_2W3 b_00000100 // 2.3W -#define CLASS_D_GAIN_2W2 b_00000101 // 2.2W -#define CLASS_D_GAIN_2W1 b_00000110 // 2.1W -#define CLASS_D_GAIN_2W0 b_00000111 // 2.0W -#define CLASS_D_GAIN_1W3 b_00001000 // 1.3W -#define CLASS_D_GAIN_1W25 b_00001001 // 1.25W -#define CLASS_D_GAIN_1W2 b_00001010 // 1.2W -#define CLASS_D_GAIN_1W15 b_00001011 // 1.15W -#define CLASS_D_GAIN_1W1 b_00001100 // 1.1W -#define CLASS_D_GAIN_1W05 b_00001101 // 1.05W -#define CLASS_D_GAIN_1W0 b_00001110 // 1.0W -#define CLASS_D_GAIN_0W9 b_00001111 // 0.9W -#endif - - __REG(DAC3_GAIN_SUB, 0x1012, 0x1011, 0x00, 0x4A, RW,B) - - __REG(ADC1_GAIN_LEFT, 0x1013, 0x1012, 0x00, 0x4A, RW,B) - __REG(ADC1_GAIN_RIGHT, 0x1014, 0x1013, 0x00, 0x4A, RW,B) - __REG(ADC2_GAIN_LEFT, 0x1015, 0x1014, 0x00, 0x00, RW,B) - __REG(ADC2_GAIN_RIGHT, 0x1016, 0x1015, 0x00, 0x00, RW,B) - __REG(DSP_MAX_MIC_GAIN, 0x1017, 0x1016, 0x00, 0, RW,B) - - __REG(VOLUME_MUTE, 0x1018, 0x1017, 0, 0, WI,B) -#ifndef _PASS1_COMPLETE_ -#define LEFT_AUX_MUTE b_01000000 -#define RIGH_AUX_MUTE b_00100000 -#define LEFT_MIC_MUTE b_00010000 -#define RIGH_MIC_MUTE b_00001000 -#define SUB_SPEAKER_MUTE b_00000100 -#define LEFT_SPEAKER_MUTE b_00000010 -#define RIGH_SPEAKER_MUTE b_00000001 -#define VOLUME_MUTE_ALL b_01111111 -#endif - -//since the playback path is determined in register value,we have to enable one port. - __REG(OUTPUT_CONTROL, 0x1019, 0x1018, b_10000000, 0, WC,B) //class -d is selected by default. -#ifndef _PASS1_COMPLETE_ -#define OUT_CTRL_AUTO b_10000000 // Automatic FW Control base on Jack Sense and DAC enables, 1= Auto, 0= Manual -#define OUT_CTRL_SUB_DIFF b_01000000 // Sub Differential control, 1=Differential, 0=Single Ended -#define OUT_CTRL_LO_DIFF b_00100000 // Line Out Differential control, 1=Differential, 0=Single Ended -#define OUT_CTRL_CLASSD_OUT b_00010000 // ClassD Output, 1=PWM, 0=Speakers -#define OUT_CTRL_CLASSD_MONO b_00001000 // ClassD Mono, 1=Mono, 0=Stereo -#define OUT_CTRL_CLASSD_EN b_00000100 // If OutCTL[7]=0, 1=Enable ClassD Speakers, 0=Disable ClassD Speakers -#define OUT_CTRL_LO_EN b_00000010 // If OutCTL[7]=0, 1=Enable Line Out, 0=Disable Line Out -#define OUT_CTRL_HP_EN b_00000001 // If OutCTL[7]=0, 1=Enable Headphone, 0=Disable Headphone -#endif - - __REG(INPUT_CONTROL, 0x101A, 0x1019, b_10000000, 0, WI,B) -#ifndef _PASS1_COMPLETE_ -#define IN_CTRL_AUTO b_10000000 // Automatic FW Control base on Jack Sense and ADC enables, 1=Auto, 0=Manual -#define IN_CTRL_L1_DIFF b_00001000 // Line In 1 Differential control, 1=Differential, 0=Single Ended -#define IN_CTRL_L3_EN b_00000100 // If LineCTL[7]=0, 1=Enable Line In 3, 0=Disable Line In 3 -#define IN_CTRL_L2_EN b_00000010 // If LineCTL[7]=0, 1=Enable Line In 2, 0=Disable Line In 2 -#define IN_CTRL_L1_EN b_00000001 // If LineCTL[7]=0, 1=Enable Line In 1, 0=Disable Line In 1 -#endif - - __REG(LINE1_GAIN, 0x101B, 0x101A, b_00000000, 0, RW,B) -#ifndef _PASS1_COMPLETE_ -#define LINE1_MUTE b_10000000 // 1=mute, 0=unmute -#define LINE1_GAIN_MASK b_00011111 // range 0x00-0x1F (-35.5dB to +12dB) -#endif - - __REG(LINE2_GAIN, 0x101C, 0x101B, b_00000000, 0, RW,B) -#ifndef _PASS1_COMPLETE_ -#define LINE2_MUTE b_10000000 // 1=mute, 0=unmute -#define LINE2_GAIN_MASK b_00011111 // range 0x00-0x1F (-35.5dB to +12dB) -#endif - - __REG(LINE3_GAIN, 0x101D, 0x101C, b_00000000, 0, RW,B) -#ifndef _PASS1_COMPLETE_ -#define LINE3_MUTE b_10000000 // 1=mute, 0=unmute -#define LINE3_GAIN_MASK b_00011111 // range 0x00-0x1F (-35.5dB to +12dB) -#endif - - __REG(MIC_CONTROL, 0x101E, 0x101D, b_00000110, 0, WC,B) -#ifndef _PASS1_COMPLETE_ -#define MICROPHONE_POWER_ALWAYS b_00010000 // 1 = leave microphone and bias always on to avoid pops (burns power), 0 = microphone powered up as needed, mute for 400ms to remove pops -#define MICROPHONE_BIAS SELECT b_00001000 // 1= 80%, 0= 50% -#define MICROPHONE_BOOST_MASK b_00000111 // 2:0 MicCTL [2:0] Microphone Boost in 6dB Steps, 0= 0dB, 7= +42dB -#endif - -#if defined(CONFIG_SND_DIGICOLOR_SOC_CHANNEL_VER_3_13E) -// adc - __REG(STREAM1_MIX, 0xffff, 0x101E, b_00000000, 0, WI,B) -#ifndef _PASS1_COMPLETE_ -#define STREAM1_MUTE b_10000000 // 1=mute, 0=unmute -#define STREAM1_GAIN_MASK b_00011111 // range 0x00-0x4A (0dB to -74dB) -#endif -// i2s - __REG(STREAM3_MIX, 0xffff, 0x101F, b_00000000, 0, WI,B) -#ifndef _PASS1_COMPLETE_ -#define STREAM3_MUTE b_10000000 // 1=mute, 0=unmute -#define STREAM3_GAIN_MASK b_00011111 // range 0x00-0x4A (0dB to -74dB) -#endif -// usb? - __REG(STREAM4_MIX, 0xffff, 0x1020, b_00000000, 0, WI,B) -#ifndef _PASS1_COMPLETE_ -#define STREAM4_MUTE b_10000000 // 1=mute, 0=unmute -#define STREAM4_GAIN_MASK b_00011111 // range 0x00-0x4A (0dB to -74dB) -#endif -#endif -#if defined(CONFIG_SND_DIGICOLOR_SOC_CHANNEL_VER_4_30F) - __REG(MIX0_INPUT0, 0x101F, 0xffff, b_00000000, 0, WI,B) // stream1 out - __REG(MIX0_INPUT1, 0x1020, 0xffff, b_00000000, 0, WI,B) // stream3 out - __REG(MIX0_INPUT2, 0x1021, 0xffff, b_00000000, 0, WI,B) // stream4 out - __REG(MIX0_INPUT3, 0x1022, 0xffff, b_10000000, 0, WI,B) // none - __REG(MIX1_INPUT0, 0x1023, 0xffff, b_10000000, 0, WI,B) // none - __REG(MIX1_INPUT1, 0x1024, 0xffff, b_10000000, 0, WI,B) // none - __REG(MIX1_INPUT2, 0x1025, 0xffff, b_10000000, 0, WI,B) // none - __REG(MIX1_INPUT3, 0x1026, 0xffff, b_10000000, 0, WI,B) // nonw - __REG(MIX0_SOURCE0, 0x1184, 0xffff, b_00000000, 0, WI,B) // stream1 out - __REG(MIX0_SOURCE1, 0x1185, 0xffff, b_00000011, 0, WI,B) // stream3 out - __REG(MIX0_SOURCE2, 0x1186, 0xffff, b_00000100, 0, WI,B) // stream4 out - __REG(MIX0_SOURCE3, 0x1187, 0xffff, b_00000000, 0, WI,B) // none - __REG(MIX1_SOURCE0, 0x1188, 0xffff, b_00000001, 0, WI,B) // none - __REG(MIX1_SOURCE1, 0x1189, 0xffff, b_00000000, 0, WI,B) // none - __REG(MIX1_SOURCE2, 0x118a, 0xffff, b_00000000, 0, WI,B) // none - __REG(MIX1_SOURCE3, 0x118b, 0xffff, b_00000000, 0, WI,B) // none - __REG(VOICE_IN_SOURCE, 0x118c, 0xffff, b_00000010, 0, WI,B) // stream2 - //__REG(VOICE_IN_SOURCE, 0x118c, 0xffff, 0x04, 0, WI,B) // stream2 -#endif - -///////////////////////////////////////////////////////////////////////// -// Hardware registers -///////////////////////////////////////////////////////////////////////// -// id addr data bias type -// __REG(CLOCK_DIVIDER, 0x0F50, 0x0F50, b_00001111, 0, WI,B) // Port1 external clock enabled - __REG(CLOCK_DIVIDER, 0x0F50, 0x0F50, 0xFF, 0, WI,B) // Port1 slave, Port2 Master 2.048 MHz -#ifndef _PASS1_COMPLETE_ -#define PORT2_DIV_SEL_6_144MHz b_00000000 // 0x0 = 6.144 MHz -#define PORT2_DIV_SEL_4_096MHz b_00010000 // 0x1 = 4.096 MHz -#define PORT2_DIV_SEL_3_072MHz b_00100000 // 0x2 = 3.072 MHz -#define PORT2_DIV_SEL_2_048MHz b_00110000 // 0x3 = 2.048 MHz -#define PORT2_DIV_SEL_1_536MHz b_01000000 // 0x4 = 1.536 MHz -#define PORT2_DIV_SEL_1_024MHz b_01010000 // 0x5 = 1.024 MHz -#define PORT2_DIV_SEL_768kHz b_01100000 // 0x6 = 768kHz -#define PORT2_DIV_SEL_512kHz b_01110000 // 0x7 = 512 kHz -#define PORT2_DIV_SEL_384kHz b_10000000 // 0x8 = 384 kHz -#define PORT2_DIV_SEL_256kHz b_10010000 // 0x9 = 256 kHz -#define PORT2_DIV_SEL_5_644MHz b_10100000 // 0xa = 5.644 MHz -#define PORT2_DIV_SEL_2_822MHz b_10110000 // 0xb = 2.822 MHz -#define PORT2_DIV_SEL_1_411MHz b_11000000 // 0xc = 1.411 MHz -#define PORT2_DIV_SEL_705kHz b_11010000 // 0xd = 705 kHz -#define PORT2_DIV_SEL_352kHz b_11100000 // 0xe = 352 kHz -#define PORT2_DIV_SEL_EXT b_11110000 // 0xf = external clock enabled -#define PORT1_DIV_SEL_6_144MHz b_00000000 // 0x0 = 6.144 MHz -#define PORT1_DIV_SEL_4_096MHz b_00000001 // 0x1 = 4.096 MHz -#define PORT1_DIV_SEL_3_072MHz b_00000010 // 0x2 = 3.072 MHz -#define PORT1_DIV_SEL_2_048MHz b_00000011 // 0x3 = 2.048 MHz -#define PORT1_DIV_SEL_1_536MHz b_00000100 // 0x4 = 1.536 MHz -#define PORT1_DIV_SEL_1_024MHz b_00000101 // 0x5 = 1.024 MHz -#define PORT1_DIV_SEL_768kHz b_00000110 // 0x6 = 768kHz -#define PORT1_DIV_SEL_512kHz b_00000111 // 0x7 = 512 kHz -#define PORT1_DIV_SEL_384kHz b_00001000 // 0x8 = 384 kHz -#define PORT1_DIV_SEL_256kHz b_00001001 // 0x9 = 256 kHz -#define PORT1_DIV_SEL_5_644MHz b_00001010 // 0xa = 5.644 MHz -#define PORT1_DIV_SEL_2_822MHz b_00001011 // 0xb = 2.822 MHz -#define PORT1_DIV_SEL_1_411MHz b_00001100 // 0xc = 1.411 MHz -#define PORT1_DIV_SEL_705kHz b_00001101 // 0xd = 705 kHz -#define PORT1_DIV_SEL_352kHz b_00001110 // 0xe = 352 kHz -#define PORT1_DIV_SEL_EXT b_00001111 // 0xf = external clock enabled -#endif - - __REG(PORT1_CONTROL, 0x0F51, 0x0F51, b_10110000, 0, WI,B) -#ifndef _PASS1_COMPLETE_ -#define PORT1_DELAY b_10000000 // 1=Data delayed 1 bit (I2S standard), 0=no delay (sony mode) -#define PORT1_JUSTR_LSBF b_01000000 // [1/0]=Right/Left Justify (I2S) or LSB/MSB First (PCM) -#define PORT1_RX_EN b_00100000 // 1=RX Clock Enable, 0=RX Clock Disabled -#define PORT1_TX_EN b_00010000 // 1=TX Clock Enable, 0=TX Clock Disabled -//#define PORT1_ b_00001000 // -#define PORT1_BITCLK_POL b_00000100 // 0=Normal clock, 1=Inverted clock -#define PORT1_WS_POL b_00000010 // 0=Rising Edge Active for Word Strobe, 1=Falling Edge Active for Word Strobe -#define PORT1_PCM_MODE b_00000001 // 0=I2S mode, 1=PCM Mode -#endif - - __REG(PORT1_TX_CLOCKS_PER_FRAME_PHASE,0x0F52, 0x0F52, b_00000011, 0, WI,B) // clocks/frame=(N+1)*8 - __REG(PORT1_RX_CLOCKS_PER_FRAME_PHASE,0x0F53, 0x0F53, b_00000011, 0, WI,B) // clocks/frame=(N+1)*8 - __REG(PORT1_TX_SYNC_WIDTH, 0x0F54, 0x0F54, b_00001111, 0, WI,B) // clocks=(N+1) - __REG(PORT1_RX_SYNC_WIDTH, 0x0F55, 0x0F55, b_00001111, 0, WI,B) // clocks=(N+1) - - __REG(PORT1_CONTROL_2, 0x0F56, 0x0F56, b_00000101, 0, WI,B) -#ifndef _PASS1_COMPLETE_ -#define PORT1_CTRL_TX_PT b_00100000 // Tx passthrough mode, 0=off, 1=on -#define PORT1_CTRL_RX_PT b_00010000 // Rx passthrough mode, 0=off, 1=on -#define PORT1_CTRL_RX_SIZE_8 b_00000000 // RX Sample Size, 00=8 bits -#define PORT1_CTRL_RX_SIZE_16 b_00000100 // RX Sample Size, 01=16 bit -#define PORT1_CTRL_RX_SIZE_24T b_00001000 // RX Sample Size, 10=24 bit truncated to 16 bits -#define PORT1_CTRL_RX_SIZE_24 b_00001100 // RX Sample Size, 11=24 bit -#define PORT1_CTRL_TX_SIZE_8 b_00000000 // TX Sample Size, 00=8 bits -#define PORT1_CTRL_TX_SIZE_16 b_00000001 // TX Sample Size, 01=16 bit -#define PORT1_CTRL_TX_SIZE_24T b_00000010 // TX Sample Size, 10=24 bit truncated to 16 bits -#define PORT1_CTRL_TX_SIZE_24 b_00000011 // TX Sample Size, 11=24 bit -#endif - -///////////////////////////////////////////////////////////////////////// -// Codec registers, most need NEWC to be set -///////////////////////////////////////////////////////////////////////// -// id addr data bias type - __REG(STREAM2_RATE, 0x116b, 0xffff, 0xa2, 0, WI,B) // Mic -#ifndef _PASS1_COMPLETE_ -#define STREAM2_STREAM_MONO_LEFT 0x00 // -#define STREAM2_STREAM_MONO_RIGHT 0x40 // -#define STREAM2_STREAM_STEREO 0x80 // -#define STREAM2_SAMPLE_A_LAW 0x00 // 8-bit A law -#define STREAM2_SAMPLE_U_LAW 0x10 // 8-bit µ law -#define STREAM2_SAMPLE_16_LIN 0x20 // 16 bit linear -#define STREAM2_SAMPLE_24_LIN 0x30 // 24 bit linear -#define STREAM2_RATE_8000 0x00 // 8000 samples/sec -#define STREAM2_RATE_11025 0x01 // 11025 samples/sec -#define STREAM2_RATE_16000 0x02 // 16000 samples/sec -#define STREAM2_RATE_22050 0x03 // 22050 samples/sec -#define STREAM2_RATE_24000 0x04 // 24000 samples/sec -#define STREAM2_RATE_32000 0x05 // 32000 samples/sec -#define STREAM2_RATE_44100 0x06 // 44100 samples/sec -#define STREAM2_RATE_48000 0x07 // 48000 samples/sec -#define STREAM2_RATE_88200 0x08 // 88200 samples/sec -#define STREAM2_RATE_96000 0x09 // 96000 samples/sec -#endif - - __REG(STREAM5_RATE, 0x1171, 0x112D, 0x26, 0, WI,B) // Mic -> I2S (5 wire) -#ifndef _PASS1_COMPLETE_ -#define STREAM5_SAMPLE_A_LAW 0x00 // 8-bit A law -#define STREAM5_SAMPLE_U_LAW 0x10 // 8-bit µ law -#define STREAM5_SAMPLE_16_LIN 0x20 // 16 bit linear -#define STREAM5_SAMPLE_24_LIN 0x30 // 24 bit linear -#define STREAM5_RATE_8000 0x00 // 8000 samples/sec -#define STREAM5_RATE_11025 0x01 // 11025 samples/sec -#define STREAM5_RATE_16000 0x02 // 16000 samples/sec -#define STREAM5_RATE_22050 0x03 // 22050 samples/sec -#define STREAM5_RATE_24000 0x04 // 24000 samples/sec -#define STREAM5_RATE_32000 0x05 // 32000 samples/sec -#define STREAM5_RATE_44100 0x06 // 44100 samples/sec -#define STREAM5_RATE_48000 0x07 // 48000 samples/sec -#define STREAM5_RATE_88200 0x08 // 88200 samples/sec -#define STREAM5_RATE_96000 0x09 // 96000 samples/sec -#endif - - __REG(STREAM3_RATE, 0x116D, 0x112F, 0xA6, 0, WI,B) // 44.1kHz, 16 bit linear -#ifndef _PASS1_COMPLETE_ -#define STREAM3_STREAM_MONO_LEFT 0x00 // -#define STREAM3_STREAM_MONO_RIGHT 0x40 // -#define STREAM3_STREAM_STEREO 0x80 // -#define STREAM3_SAMPLE_A_LAW 0x00 // 8-bit A law -#define STREAM3_SAMPLE_U_LAW 0x10 // 8-bit µ law -#define STREAM3_SAMPLE_16_LIN 0x20 // 16 bit linear -#define STREAM3_SAMPLE_24_LIN 0x30 // 24 bit linear -#define STREAM3_RATE_8000 0x00 // 8000 samples/sec -#define STREAM3_RATE_11025 0x01 // 11025 samples/sec -#define STREAM3_RATE_16000 0x02 // 16000 samples/sec -#define STREAM3_RATE_22050 0x03 // 22050 samples/sec -#define STREAM3_RATE_24000 0x04 // 24000 samples/sec -#define STREAM3_RATE_32000 0x05 // 32000 samples/sec -#define STREAM3_RATE_44100 0x06 // 44100 samples/sec -#define STREAM3_RATE_48000 0x07 // 48000 samples/sec -#define STREAM3_RATE_88200 0x08 // 88200 samples/sec -#define STREAM3_RATE_96000 0x09 // 96000 samples/sec -#endif - - __REG(STREAM_3_ROUTING, 0x116E, 0x1130, 0x02, 0, WI,B) -#ifndef _PASS1_COMPLETE_ -#define STREAM3_ROUTE_SRC_D1 0x00 // Source = Digital Port1 -#define STREAM3_ROUTE_SRC_D2 0x10 // Source = Digital Port2 -#define STREAM3_ROUTE_DST_D1 0x00 // Destination = Digital Port1 -#define STREAM3_ROUTE_DST_D2 0x01 // Destination = Digital Port2 -#define STREAM3_ROUTE_DST_DAC 0x02 // Destination = DAC -#define STREAM3_ROUTE_DST_SUB 0x03 // Destination = DAC (sub) -#define STREAM3_ROUTE_DST_SPDIF 0x04 // Destination = SPDIF -#define STREAM3_ROUTE_DST_USB 0x05 // Destination = USB -#endif - - __REG(EQ_GAIN, 0x10D7, 0x10D1, 0x1000, 0, WI,W) - __REG(EQS_GAIN, 0x10D9, 0x10D3, 0x1000, 0, WI,W) - -// __REG(SPDIF_CODE, 0x1178, 0x1134, 0x00, 0, WI,B) -// __REG(SPDIF_CONTROL, 0x1179, 0x1135, 0x00, 0, WI,B) - - __REG(DSP_PROCESSING_ENABLE_1, 0x117A, 0x1136, 0x00, 0, WC,B) -#ifndef _PASS1_COMPLETE_ -#define RIGHT_MIKE b_01000000 -#define IN_NOISE_REDUCTION b_00100000 -#define MIC_AGC b_00010000 -#define BEAM_FORMING b_00001000 -#define NOICE_REDUCTION b_00000100 -#define LEC b_00000010 -#define AEC b_00000001 -#endif - __REG(DSP_PROCESSING_ENABLE_2, 0x117B, 0x1137, 0x00, 0, WC,B) -#ifndef _PASS1_COMPLETE_ -#define DSP_MONO_OUTPUT b_00100000 // 0=Stereo, 1=Mono (L+R)=L (L+R)=R -#define LOUDNESS_ADAPTER b_00010000 // 1=Enable, 0=Disable -#define STAGE_ENHANCER b_00001000 // 1=Enable 3D processing, 0=Disable -#define DYNAMIC_RANGE_COMPRESSION b_00000100 // 1=Enable, 0=Disable -#define SUBWOOFER_CROSSOVER b_00000010 // 1=Enable, 0=Disable -#define EQUALIZER_10_BAND b_00000001 // 1=Enable, 0=Disable -#endif - -#if defined(CONFIG_SND_DIGICOLOR_SOC_CHANNEL_VER_4_30F) - __REG(DSP_INIT_H, 0x117C, 0xffff, 0x00, 0, WI,B) // special - __REG(DSP_INIT, 0x117D, 0xffff, 0x00, 0, WC,B) // special - __REG(DSP_POWER, 0x117E, 0xffff, 0xE0, 0, WC,B) // special - -#ifndef _PASS1_COMPLETE_ -#define DSP_INIT_NEWC b_00000001 -#define DSP_INIT_STREAM_OFF b_00000001 -#define DSP_INIT_STREAM_3 b_10001001 // enable stream 3 and 7 -#define DSP_INIT_STREAM_5 b_00100101 // enable stream 2 and 5 -#define DSP_INIT_STREAM_5_3 b_10101101 // enable streams 2,3,5,7 -#define DSP_NO_SOURCE b_00000000 -#define DSP_ENABLE_STREAM_3 b_00001000 -#define DSP_ENABLE_STREAM_4 b_00010000 -#define DSP_ENABLE_STREAM_3_4 b_00011000 -#endif -#else - __REG(DSP_INIT, 0xffff, 0x1138, 0x00, 0, WI,B) // special -#ifndef _PASS1_COMPLETE_000000000000000000000000 -#define DSP_INIT_NEWC b_00000001 -#define DSP_INIT_STREAM_OFF b_00000001 -#define DSP_INIT_STREAM_3 b_00001001 -#define DSP_INIT_STREAM_5 b_00100001 -#define DSP_INIT_STREAM_5_3 b_00101001 -#endif -#endif - -#ifdef CX20709_TRISTATE_EEPROM - __REG(PAD, 0x0004, 0x0004, 0x00, 0, WO,B) - __REG(PBD, 0x0005, 0x0005, 0x00, 0, W0,B) -#endif -// temp code. -// added rerouting render stream to second I2S output ( 16 Kbps/ 16BITS) - __REG(STREAM4_RATE, 0x116F, 0xffff, 0xA7, 0, WI,B) // dsp -> PCM-2 8Kbps output - __REG(STREAM4_ROUTING, 0x1170, 0xffff, 0x12, 0, WI,B) - __REG(STREAM6_RATE, 0x1172, 0xffff, 0x27, 0, WI,B) // dsp -> PCM-2 8Kbps output - __REG(STREAM7_RATE, 0x1173, 0xffff, 0x07, 0, WC,B) // dsp -> I2S-2 (5 wire) - __REG(STREAMOP_ROUTING, 0x1176, 0xffff, 0x60, 0, WC,B) // AEC narrow band. 48 KHz - __REG(STREAM6_ROUTING, 0x1182, 0xffff, 0x06, 0, WI,B) - __REG(STREAM7_SOURCE, 0x117F, 0xffff, 0x05, 0, WI,B) // dsp -> I2S-2 (5 wire) - __REG(STREAM8_SOURCE, 0x1180, 0xffff, 0x05, 0, WC,B) - __REG(STREAM8_RATE, 0x1175, 0xffff, 0x07, 0, WC,B) - __REG(PORT2_CONTROL, 0x0F5E, 0x0F5E, 0XB0, 0, WI,B) // Delay 1 bit, RX/TX en, mode =i2s - __REG(PORT2_CLOCK_PER_FRAME, 0x0F5F, 0x0F5F, 0X07, 0, WI,B) // 64-bits per frame. - __REG(PORT2_SYNC_WIDTH, 0x0F60, 0x0F60, 0X0f, 0, WI,B) // clocks=(N+1) - __REG(PORT2_SAMPLE_WIDTH, 0x0F61, 0x0F61, 0X01, 0, WI,B) // 16 bits. - __REG(PORT2_RX_STREAM1, 0x0F62, 0x0F62, 0X20, 0, WI,B) // RX 1 <- Slot 0 - __REG(PORT2_RX_STREAM2, 0x0F63, 0x0F63, 0X24, 0, WI,B) // RX 2 <- Slot 4 - __REG(PORT2_TX_STREAM1, 0x0F65, 0x0F65, 0X20, 0, WI,B) // TX 1 -> Slot 0 - __REG(PORT2_TX_STREAM2, 0x0F66, 0x0F66, 0X24, 0, WI,B) // TX 2 -> Slot 4 - -#ifndef _PASS1_COMPLETE_ -#define _PASS1_COMPLETE_ -#endif diff --git a/sound/soc/codecs/cx2070x.c b/sound/soc/codecs/cx2070x.c deleted file mode 100755 index 1a89c3f2b796..000000000000 --- a/sound/soc/codecs/cx2070x.c +++ /dev/null @@ -1,2290 +0,0 @@ -/* -* ALSA SoC CX2070X codec driver -* -* Copyright: (C) 2009/2010 Conexant Systems -* -* Based on sound/soc/codecs/tlv320aic2x.c by Vladimir Barinov -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License version 2 as -* published by the Free Software Foundation. -* -* -* -************************************************************************* -* Modified Date: 09/14/12 -* File Version: 3.1.10.13 -************************************************************************* -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "cx2070x.h" - -#define CX2070X_DRIVER_VERSION AUDDRV_VERSION( 3, 1 ,0x10 ,0x13) - -#ifdef USING_I2C -#include -#endif - -#ifdef USING_SPI -#include -#endif - -#if defined(CONFIG_SND_CXLIFEGUARD) -#include "cxdebug.h" -#endif - -#ifdef CONFIG_SND_CX2070X_LOAD_FW -#ifdef CONFIG_SND_CX2070X_USE_FW_H -#include "cx2070x_fw.h" -#else -#include -#endif -#include "cxpump.h" -#endif - - -#define CX2070X_TRISTATE_EEPROM 0 -#define CX2070X_REG_NAMES 1 -#define CX2070X_REG_WIDE 1 - - -#define AUDIO_NAME "cx2070x" - - -#define CX2070X_RATES ( \ - SNDRV_PCM_RATE_8000 \ - | SNDRV_PCM_RATE_11025 \ - | SNDRV_PCM_RATE_16000 \ - | SNDRV_PCM_RATE_22050 \ - | SNDRV_PCM_RATE_32000 \ - | SNDRV_PCM_RATE_44100 \ - | SNDRV_PCM_RATE_48000 \ - | SNDRV_PCM_RATE_88200 \ - | SNDRV_PCM_RATE_96000 ) - -#if defined(CONFIG_SND_DIGICOLOR_SOC_CHANNEL_VER_4_30F) - -#define CX2070X_FORMATS ( SNDRV_PCM_FMTBIT_S16_LE \ - | SNDRV_PCM_FMTBIT_S16_BE \ - | SNDRV_PCM_FMTBIT_MU_LAW \ - | SNDRV_PCM_FMTBIT_A_LAW ) -#else -#define CX2070X_FORMATS ( SNDRV_PCM_FMTBIT_S16_LE \ - | SNDRV_PCM_FMTBIT_S16_BE ) -#endif - - - -#define noof(a) (sizeof(a)/sizeof(a[0])) -#define NOINLINE __attribute__((__noinline__)) -//#ifdef DEBUG -#if 1 -# define INFO(fmt,...) printk(KERN_INFO fmt, ##__VA_ARGS__) -# define _INFO(fmt,...) printk(KERN_INFO fmt, ##__VA_ARGS__) -# define _INFO_ 1 -#else -# define INFO(fmt,...) -# define _INFO(fmt,...) -# define _INFO_ 1 -#endif -#define MSG(fmt,...) printk(KERN_INFO fmt, ##__VA_ARGS__) -#define ERROR(fmt,...) printk(KERN_ERR fmt, ##__VA_ARGS__) - -enum { - b_00000000,b_00000001,b_00000010,b_00000011, b_00000100,b_00000101,b_00000110,b_00000111, - b_00001000,b_00001001,b_00001010,b_00001011, b_00001100,b_00001101,b_00001110,b_00001111, - b_00010000,b_00010001,b_00010010,b_00010011, b_00010100,b_00010101,b_00010110,b_00010111, - b_00011000,b_00011001,b_00011010,b_00011011, b_00011100,b_00011101,b_00011110,b_00011111, - b_00100000,b_00100001,b_00100010,b_00100011, b_00100100,b_00100101,b_00100110,b_00100111, - b_00101000,b_00101001,b_00101010,b_00101011, b_00101100,b_00101101,b_00101110,b_00101111, - b_00110000,b_00110001,b_00110010,b_00110011, b_00110100,b_00110101,b_00110110,b_00110111, - b_00111000,b_00111001,b_00111010,b_00111011, b_00111100,b_00111101,b_00111110,b_00111111, - b_01000000,b_01000001,b_01000010,b_01000011, b_01000100,b_01000101,b_01000110,b_01000111, - b_01001000,b_01001001,b_01001010,b_01001011, b_01001100,b_01001101,b_01001110,b_01001111, - b_01010000,b_01010001,b_01010010,b_01010011, b_01010100,b_01010101,b_01010110,b_01010111, - b_01011000,b_01011001,b_01011010,b_01011011, b_01011100,b_01011101,b_01011110,b_01011111, - b_01100000,b_01100001,b_01100010,b_01100011, b_01100100,b_01100101,b_01100110,b_01100111, - b_01101000,b_01101001,b_01101010,b_01101011, b_01101100,b_01101101,b_01101110,b_01101111, - b_01110000,b_01110001,b_01110010,b_01110011, b_01110100,b_01110101,b_01110110,b_01110111, - b_01111000,b_01111001,b_01111010,b_01111011, b_01111100,b_01111101,b_01111110,b_01111111, - b_10000000,b_10000001,b_10000010,b_10000011, b_10000100,b_10000101,b_10000110,b_10000111, - b_10001000,b_10001001,b_10001010,b_10001011, b_10001100,b_10001101,b_10001110,b_10001111, - b_10010000,b_10010001,b_10010010,b_10010011, b_10010100,b_10010101,b_10010110,b_10010111, - b_10011000,b_10011001,b_10011010,b_10011011, b_10011100,b_10011101,b_10011110,b_10011111, - b_10100000,b_10100001,b_10100010,b_10100011, b_10100100,b_10100101,b_10100110,b_10100111, - b_10101000,b_10101001,b_10101010,b_10101011, b_10101100,b_10101101,b_10101110,b_10101111, - b_10110000,b_10110001,b_10110010,b_10110011, b_10110100,b_10110101,b_10110110,b_10110111, - b_10111000,b_10111001,b_10111010,b_10111011, b_10111100,b_10111101,b_10111110,b_10111111, - b_11000000,b_11000001,b_11000010,b_11000011, b_11000100,b_11000101,b_11000110,b_11000111, - b_11001000,b_11001001,b_11001010,b_11001011, b_11001100,b_11001101,b_11001110,b_11001111, - b_11010000,b_11010001,b_11010010,b_11010011, b_11010100,b_11010101,b_11010110,b_11010111, - b_11011000,b_11011001,b_11011010,b_11011011, b_11011100,b_11011101,b_11011110,b_11011111, - b_11100000,b_11100001,b_11100010,b_11100011, b_11100100,b_11100101,b_11100110,b_11100111, - b_11101000,b_11101001,b_11101010,b_11101011, b_11101100,b_11101101,b_11101110,b_11101111, - b_11110000,b_11110001,b_11110010,b_11110011, b_11110100,b_11110101,b_11110110,b_11110111, - b_11111000,b_11111001,b_11111010,b_11111011, b_11111100,b_11111101,b_11111110,b_11111111, -}; - -enum { - NO_INPUT = 0, - I2S_ONLY, - USB_ONLY, - I2S_USB_MIXING, -}; - -#define REG_TYPE_RO 0 // read only, read during initialization -#define REG_TYPE_RW 1 // read/write, read during initialization -#define REG_TYPE_WI 2 // write only, written during initialization -#define REG_TYPE_WC 3 // write/init, needs NEWC to be set when written -#define REG_TYPE_DM 4 // dummy register, read/write to cache only -#if CX2070X_REG_WIDE -# define REG_TYPE_MASK 0x0F -# define REG_WIDTH_B 0x00 // 8-bit data -# define REG_WIDTH_W 0x10 // 16-bit data -# define REG_WIDTH_MASK 0xF0 -#endif -enum { -#define __REG(a,b2,b1,c,d,e,f) a, -#include "cx2070x-i2c.h" -#undef __REG -}; - -#if CX2070X_REG_WIDE -typedef u16 cx2070x_reg_t; -#else -typedef u8 cx2070x_reg_t; -#endif -static const cx2070x_reg_t cx2070x_data[]= -{ -#define __REG(a,b2,b1,c,d,e,f) c, -#include "cx2070x-i2c.h" -#undef __REG -}; - -struct cx2070x_reg -{ -#if CX2070X_REG_NAMES - char *name; -#endif - u16 addr; - u8 bias; - u8 type; -}; - -static const struct cx2070x_reg cx2070x_regs[]= -{ -#if defined(CONFIG_SND_DIGICOLOR_SOC_CHANNEL_VER_3_13E) -# if CX2070X_REG_NAMES -# define __REG(a,b2,b1,c,d,e,f) { #a,b1,d,REG_TYPE_##e|REG_WIDTH_##f }, -# else -# define __REG(a,b2,b1,c,d,e,f) { b1,d,REG_TYPE_##e|REG_WIDTH_##f }, -# endif -#elif defined(CONFIG_SND_DIGICOLOR_SOC_CHANNEL_VER_4_30F) -# if CX2070X_REG_NAMES -# define __REG(a,b2,b1,c,d,e,f) { #a,b2,d,REG_TYPE_##e|REG_WIDTH_##f }, -# else -# define __REG(a,b2,b1,c,d,e,f) { b2,d,REG_TYPE_##e|REG_WIDTH_##f }, -# endif -#else -# if CX2070X_REG_NAMES -# define __REG(a,b2,b1,c,d,e,f) { #a,b2,d,REG_TYPE_##e|REG_WIDTH_##f }, -# else -# define __REG(a,b2,b1,c,d,e,f) { b2,d,REG_TYPE_##e|REG_WIDTH_##f }, -# endif -#endif -#include "cx2070x-i2c.h" -#undef __REG -}; - -// codec private data -struct cx2070x_priv -{ - enum snd_soc_control_type control_type; - void *control_data; - unsigned int sysclk; - int master; - enum Cx_INPUT_SEL input_sel; - enum Cx_OUTPUT_SEL output_sel; - unsigned int mute; - long int playback_path; - long int capture_path; -}; - -#define get_cx2070x_priv(_codec_) ((struct cx2070x_priv *)snd_soc_codec_get_drvdata(codec)) - -#if defined(CONFIG_CXNT_SOFTWOARE_SIMULATION) -static int bNoHW = 1; -#else -static int bNoHW = 0; -#endif - - -/* - * Playback Volume - * - * max : 0x00 : 0 dB - * ( 1 dB step ) - * min : 0xB6 : -74 dB - */ -static const DECLARE_TLV_DB_SCALE(dac_tlv, -7400 , 100, 0); - - -/* - * Capture Volume - * - * max : 0x00 : 0 dB - * ( 1 dB step ) - * min : 0xB6 : -74 dB - */ -static const DECLARE_TLV_DB_SCALE(adc_tlv, -7400 , 100, 0); - - -#if defined (CONFIG_SND_CX2070X_GPIO_JACKSENSE) -// TODO : the jack sensing code should be moved to machine layer. -static struct snd_soc_jack hs_jack ; -/* Headset jack detection DAPM pins */ -static struct snd_soc_jack_pin hs_jack_pins[] = { - { - /*.list_head list*/{}, - /*.pin*/"Headphone", - /*.mask*/SND_JACK_HEADPHONE, - /*.invert*/1 - }, - { - /*.list_head list*/{}, - /*.pin*/"INT SPK", - /*.mask*/SND_JACK_HEADPHONE, - /*.invert*/0 - } -}; - -/* Headset jack detection gpios */ -static struct snd_soc_jack_gpio hs_jack_gpios[] = { - { - /*.gpio*/ JACK_SENSE_GPIO_PIN, - /*.name*/ "hsdet-gpio", - /*.report*/ SND_JACK_HEADSET, - /*.invert*/ 0, - /*.debounce_time*/ 200, - /*.jack*/ NULL, - /*.work*/ NULL, - }, -}; - -#endif //CONFIG_SND_CX2070X_GPIO_JACKSENSE - -#if defined(CONFIG_SND_CX2070X_LOAD_FW) -int I2cWrite( struct snd_soc_codec *codec, unsigned char ChipAddr, unsigned long cbBuf, unsigned char* pBuf); -int I2cWriteThenRead( struct snd_soc_codec *codec, unsigned char ChipAddr, unsigned long cbBuf, - unsigned char* pBuf, unsigned long cbReadBuf, unsigned char*pReadBuf); -#endif - -#define GET_REG_CACHE(_codec_) (cx2070x_reg_t *) (_codec_)->reg_cache -static inline unsigned int cx2070x_read_reg_cache(struct snd_soc_codec *codec, unsigned int reg) -{ - cx2070x_reg_t *reg_cache; - if (reg >= noof(cx2070x_regs)) - return (unsigned int)0; - reg_cache = GET_REG_CACHE(codec); - return reg_cache[reg]; -} - -static inline void cx2070x_write_reg_cache(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) -{ - cx2070x_reg_t *reg_cache; - if (reg >= noof(cx2070x_regs)) - return; - reg_cache=GET_REG_CACHE(codec); - reg_cache[reg] = value; -} - -#ifdef USING_SPI -static int NOINLINE cx2070x_real_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) -{ /* SPI bus */ - int ret; - u8 data[4]; - struct spi_device * spi = (struct spi_device *) codec->control_data; - int len=0; - const struct cx2070x_reg *ri; - - ri=&cx2070x_regs[reg]; - - - switch(ri->type®_TYPE_MASK) - { - case REG_TYPE_RO: // read only, read during initialization -#if CX2070X_REG_NAMES - ERROR("%s(): write to Read-only register '%s'\n",__func__,ri->name); -#endif - break; - - case REG_TYPE_RW: // read/write, read during initialization - case REG_TYPE_WI: // write only, written during initialization - case REG_TYPE_WC: // write/init, needs NEWC to be set when written - // msg[0].addr = client->addr; - // msg[0].flags = client->flags & I2C_M_TEN; - data[0]=(u8)(ri->addr>>8); - data[1]=(u8)(ri->addr>>0); - switch(ri->type®_WIDTH_MASK) - { - case REG_WIDTH_B: - data[2]=(u8)(value-ri->bias); - len=3; - break; - case REG_WIDTH_W: - data[2]=(u8)((value-ri->bias)>>0)&0xFF; - data[3]=(u8)((value-ri->bias)>>8)&0xFF; - len=4; - break; - default: - return -EIO; - } - data[0] |= 0x80; //Write flag. -#ifdef DBG_MONITOR_REG - printk(KERN_ERR "Write REG %02x%02x %02x\n",data[0],data[1],data[2]); -#endif - spi_write(spi, data, len); - break; - -#if defined(REG_TYPE_DM) - case REG_TYPE_DM: // dummy register, no I2C transfers - break; -#endif - } - - cx2070x_write_reg_cache(codec,reg,value); - return 0; -} - -static int NOINLINE cx2070x_real_read(struct snd_soc_codec *codec, unsigned int reg) -{ - struct spi_device * spi = (struct spi_device *) codec->control_data; - int len=0; - - u8 data[4]; - const struct cx2070x_reg *ri; - int dat; - int ret; - ri=&cx2070x_regs[reg]; - - if ((ri->type®_TYPE_MASK)==REG_TYPE_DM) - return cx2070x_read_reg_cache(codec,reg); - - data[0]=(u8)(ri->addr>>8); - data[1]=(u8)(ri->addr>>0); - len = ((ri->type®_WIDTH_MASK)==REG_WIDTH_W)?2:1; - data[2] = 0; - if (spi_write_then_read(spi, &data[0], 3, &data[2],len)) - { - - } - switch(ri->type®_WIDTH_MASK) - { - case REG_WIDTH_B: - dat=ri->bias+data[2]; - break; - case REG_WIDTH_W: - dat=ri->bias+(data[2]<<0)+(data[3]<<8); - break; - default: - return -EIO; - } - cx2070x_write_reg_cache(codec,reg,dat); - return dat; -} -#else -static int NOINLINE cx2070x_real_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) -{ - struct i2c_client *client = (struct i2c_client *) codec->control_data; - struct i2c_adapter *adap = client->adapter; - struct i2c_msg msg[2]; - u8 data[4]; - const struct cx2070x_reg *ri; - if(reg == MIC_CONTROL) - printk(">>>>>>>>>>>>>%s value = %0x\n", __func__, value); - if(reg == MIC_CONTROL) - dump_stack(); - - ri=&cx2070x_regs[reg]; - - switch(ri->type®_TYPE_MASK) - { - case REG_TYPE_RO: // read only, read during initialization -#if CX2070X_REG_NAMES - ERROR("%s(): write to Read-only register '%s'\n",__func__,ri->name); -#endif - break; - - case REG_TYPE_RW: // read/write, read during initialization - case REG_TYPE_WI: // write only, written during initialization - case REG_TYPE_WC: // write/init, needs NEWC to be set when written - msg[0].addr = client->addr; - msg[0].flags = client->flags & I2C_M_TEN; - msg[0].buf = &data[0]; - msg[0].scl_rate = 200 * 1000; - data[0]=(u8)(ri->addr>>8); - data[1]=(u8)(ri->addr>>0); - switch(ri->type®_WIDTH_MASK) - { - case REG_WIDTH_B: - data[2]=(u8)(value-ri->bias); - msg[0].len=3; - break; - case REG_WIDTH_W: - data[2]=(u8)((value-ri->bias)>>0)&0xFF; - data[3]=(u8)((value-ri->bias)>>8)&0xFF; - msg[0].len=4; - break; - default: - return -EIO; - } -#ifdef DBG_MONITOR_REG - printk(KERN_ERR "Write REG %02x%02x %02x\n",data[0],data[1],data[2]); -#endif - - if (i2c_transfer(adap,msg,1)!=1) - return -EIO; - break; - -#if defined(REG_TYPE_DM) - case REG_TYPE_DM: // dummy register, no I2C transfers - break; -#endif - } - - cx2070x_write_reg_cache(codec,reg,value); - return 0; -} - -static int NOINLINE cx2070x_real_read(struct snd_soc_codec *codec, unsigned int reg) -{ - struct i2c_client *client =(struct i2c_client *) codec->control_data; - struct i2c_adapter *adap = client->adapter; - struct i2c_msg msg[2]; - u8 data[4]; - const struct cx2070x_reg *ri; - int dat; - - ri=&cx2070x_regs[reg]; - - if ((ri->type®_TYPE_MASK)==REG_TYPE_DM) - return cx2070x_read_reg_cache(codec,reg); - - data[0]=(u8)(ri->addr>>8); - data[1]=(u8)(ri->addr>>0); - - msg[0].addr = client->addr; - msg[0].flags = client->flags & I2C_M_TEN; - msg[0].len = 2; - msg[0].buf = &data[0]; - msg[0].scl_rate = 200 * 1000; - - msg[1].addr = client->addr; - msg[1].flags = (client->flags & I2C_M_TEN) | I2C_M_RD; - msg[1].len = ((ri->type®_WIDTH_MASK)==REG_WIDTH_W)?2:1; - msg[1].buf = &data[2]; - msg[1].scl_rate = 200 * 1000; - - if (i2c_transfer(adap,msg,2)!=2) - return -EIO; - - switch(ri->type®_WIDTH_MASK) - { - case REG_WIDTH_B: - dat=ri->bias+data[2]; - break; - case REG_WIDTH_W: - dat=ri->bias+(data[2]<<0)+(data[3]<<8); - break; - default: - return -EIO; - } - cx2070x_write_reg_cache(codec,reg,dat); - return dat; -} -#endif //#!ENABLE_SPI - -// reset codec via gpio pin. -#if defined(CONFIG_SND_CX2070X_GPIO_RESET) -static int cx2070x_reset_device(void) -{ - - int err = 0; - int reset_pin = CODEC_RESET_GPIO_PIN; - INFO("%lu: %s() called\n",jiffies,__func__); - if (gpio_is_valid(reset_pin)) { - if (gpio_request(reset_pin, "reset_pin")) { - printk( KERN_ERR "cx2070x: reset pin %d not available\n",reset_pin); - err = -ENODEV; - } else { - gpio_direction_output(reset_pin, 1); - mdelay(3); - gpio_set_value(reset_pin, 0); - //udelay(1);// simon :need to re-check the reset timing. - mdelay(3); - gpio_set_value(reset_pin, 1); - gpio_free(reset_pin); - mdelay(200); //simon :not sure how long the device become ready. - } - } - else - { - printk( KERN_ERR "cx2070x: reset pin %d is not valid\n",reset_pin); - err = -ENODEV; - } - return err; -} -#endif //#if defined(CONFIG_SND_CX2070X_GPIO_RESET) - - -static int cx2070x_dsp_init(struct snd_soc_codec *codec,unsigned mode) -{ - unsigned r; - cx2070x_real_write(codec,DSP_INIT,mode); - printk("******************%s mode = %0x\n",__func__, mode); - // maximum time for the NEWC to clear is about 2ms. - for(r=1000;;) - if (!(cx2070x_real_read(codec,DSP_INIT)&DSP_INIT_NEWC)) - return 0; - else if (--r==0) - return -EIO; - else - msleep(1); -} - -static int NOINLINE cx2070x_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) -{ - int err = 0; - - if ((err=cx2070x_real_write(codec,reg,value))<0) - return err; - - switch(cx2070x_regs[reg].type®_TYPE_MASK) - { - case REG_TYPE_WC: - printk("^^^^^^^^^%0x\n",cx2070x_read_reg_cache(codec,DSP_INIT)); - printk("^^^^^^^^^%0x\n",cx2070x_read_reg_cache(codec,DSP_INIT)|DSP_INIT_NEWC); - return cx2070x_dsp_init(codec,cx2070x_read_reg_cache(codec,DSP_INIT)|DSP_INIT_NEWC); - default: - return err; - } -} - - -static int output_select_event_set(struct snd_kcontrol *kcontrol, -struct snd_ctl_elem_value *ucontrol) -{ - - int changed = 0; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct soc_enum *control = (struct soc_enum *)kcontrol->private_value; - struct cx2070x_priv *channel = get_cx2070x_priv(codec); - - // unsigned short sel; - - /* Refuse any mode changes if we are not able to control the codec. */ - if (!codec->control_data) - return -EUNATCH; - - if (ucontrol->value.enumerated.item[0] >= control->max) - return -EINVAL; - - mutex_lock(&codec->mutex); - - /* Translate selection to bitmap */ - channel->output_sel = (enum Cx_OUTPUT_SEL) ucontrol->value.enumerated.item[0]; - - - switch(ucontrol->value.enumerated.item[0]) - { - case Cx_OUTPUT_SEL_BY_GPIO: - { - //disable BT output. - snd_soc_dapm_disable_pin(&codec->dapm, "BT OUT"); - //snd_soc_dapm_disable_pin(codec, "Headphone"); - snd_soc_dapm_disable_pin(&codec->dapm, "BT OUT"); - //enable analog pin -#if defined(CONFIG_SND_CX2070X_GPIO_JACKSENSE) - #ifdef CONFIG_GPIOLIB - // snd_soc_jack_gpio_detect(&hs_jack_gpios[0]); - //snd_soc_dapm_enable_pin(codec, "INT SPK"); - #else - snd_soc_dapm_enable_pin(&codec->dapm, "INT SPK"); - #endif -#else - snd_soc_dapm_enable_pin(&codec->dapm, "INT SPK"); -#endif //if defined(CONFIG_SND_CX2070X_GPIO_JACKSENSE) - break; - } - case Cx_OUTPUT_SEL_SPK: - case Cx_OUTPUT_SEL_LINE: - { - snd_soc_dapm_disable_pin(&codec->dapm, "BT OUT"); - snd_soc_dapm_disable_pin(&codec->dapm, "Headphone"); - - snd_soc_dapm_enable_pin(&codec->dapm, "INT SPK"); - break; - } - case Cx_OUTPUT_SEL_HP: - { - snd_soc_dapm_disable_pin(&codec->dapm, "BT OUT"); - snd_soc_dapm_disable_pin(&codec->dapm, "INT SPK"); - snd_soc_dapm_enable_pin(&codec->dapm, "Headphone"); - break; - } - case Cx_OUTPUT_SEL_DPORT2: - { - snd_soc_dapm_disable_pin(&codec->dapm, "INT SPK"); - snd_soc_dapm_disable_pin(&codec->dapm, "Headphone"); - snd_soc_dapm_enable_pin(&codec->dapm, "BT OUT"); - break; - } - default:; - printk( KERN_ERR "output mode is not valid\n"); - } - - snd_soc_dapm_sync(&codec->dapm); - mutex_unlock(&codec->mutex); - return changed; -} - -static int output_select_event_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct cx2070x_priv *channel = get_cx2070x_priv(codec); - ucontrol->value.enumerated.item[0] = channel->output_sel; - return 0; -} - - -static const char *output_select_mode[] = -{"AUTO", "SPK" ,"LINE", "HP" ,"PCM2"}; - -static const struct soc_enum output_select_enum[] = { - SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(output_select_mode), - output_select_mode), -}; - -static const char *input_select_mode[] = -{"MIC", "PCM" }; - -static const struct soc_enum input_select_enum[] = { - SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(input_select_mode), - input_select_mode), -}; - -static const struct snd_kcontrol_new input_select_controls = -SOC_DAPM_ENUM("Route", input_select_enum); - -static const struct snd_kcontrol_new cx2070x_snd_controls[]= -{ - // Output - SOC_DOUBLE_R_TLV("Master Playback Volume", DAC1_GAIN_LEFT, DAC2_GAIN_RIGHT, 0, 74, 0,dac_tlv), - SOC_SINGLE( "EQ Switch", DSP_PROCESSING_ENABLE_2, 0, 0x01, 0), - SOC_SINGLE( "SWC Switch", DSP_PROCESSING_ENABLE_2, 1, 0x01, 0), - SOC_SINGLE( "DRC Switch", DSP_PROCESSING_ENABLE_2, 2, 0x01, 0), - SOC_SINGLE( "Stage Enhancer Switch", DSP_PROCESSING_ENABLE_2, 3, 0x01, 0), - SOC_SINGLE( "Loudness Switch", DSP_PROCESSING_ENABLE_2, 4, 0x01, 0), - SOC_SINGLE( "DSP Mono Out Switch", DSP_PROCESSING_ENABLE_2, 5, 0x01, 0), - - //// Input - - SOC_DOUBLE_R_TLV("Mic Pga Volume", ADC2_GAIN_LEFT, ADC2_GAIN_RIGHT, 0, 74, 0,adc_tlv), - SOC_SINGLE( "Right Microphone Switch", DSP_PROCESSING_ENABLE_1, 6, 0x01, 0), - SOC_SINGLE( "Inbound Noice Reduction Switch", DSP_PROCESSING_ENABLE_1, 5, 0x01, 0), - SOC_SINGLE( "Mic AGC Switch", DSP_PROCESSING_ENABLE_1, 4, 0x01, 0), - SOC_SINGLE( "Beam Forming Switch", DSP_PROCESSING_ENABLE_1, 3, 0x01, 0), - SOC_SINGLE( "Noise Reduction Switch", DSP_PROCESSING_ENABLE_1, 2, 0x01, 0), - SOC_SINGLE( "LEC Switch", DSP_PROCESSING_ENABLE_1, 1, 0x01, 0), - SOC_SINGLE( "AEC Switch", DSP_PROCESSING_ENABLE_1, 0, 0x01, 0), - SOC_ENUM_EXT("Master Playback Switch", output_select_enum[0], output_select_event_get, output_select_event_set), -}; - -//For tiny alsa playback/capture/voice call path -static const char *cx2070x_playback_path_mode[] = {"OFF", "RCV", "SPK", "HP", "HP_NO_MIC", "BT", "SPK_HP", //0-6 - "RING_SPK", "RING_HP", "RING_HP_NO_MIC", "RING_SPK_HP"};//7-10 - -static const char *cx2070x_capture_path_mode[] = {"MIC OFF", "Main Mic", "Hands Free Mic", "BT Sco Mic"}; - -static const SOC_ENUM_SINGLE_DECL(cx2070x_playback_path_type, 0, 0, cx2070x_playback_path_mode); - -static const SOC_ENUM_SINGLE_DECL(cx2070x_capture_path_type, 0, 0, cx2070x_capture_path_mode); - - -static int cx2070x_playback_path_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct cx2070x_priv *cx2070x = get_cx2070x_priv(codec); - - if (!cx2070x) { - printk("%s : cx2070x_priv is NULL\n", __func__); - return -EINVAL; - } - - printk("%s : playback_path %ld\n",__func__,ucontrol->value.integer.value[0]); - - ucontrol->value.integer.value[0] = cx2070x->playback_path; - - return 0; -} - -static int cx2070x_playback_path_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct cx2070x_priv *cx2070x = get_cx2070x_priv(codec); - long int pre_path; - - if (!cx2070x) { - printk("%s : cx2070x_priv is NULL\n", __func__); - return -EINVAL; - } - - if (cx2070x->playback_path == ucontrol->value.integer.value[0]){ - printk("%s : playback_path is not changed!\n",__func__); - return 0; - } - - pre_path = cx2070x->playback_path; - cx2070x->playback_path = ucontrol->value.integer.value[0]; - - printk("%s : set playback_path %ld, pre_path %ld\n", __func__, - cx2070x->playback_path, pre_path); - - switch (cx2070x->playback_path) { - case OFF: - if (pre_path != OFF) { - cx2070x_real_read(codec,DSP_INIT); - cx2070x_write(codec,DSP_INIT,(cx2070x_read_reg_cache(codec,DSP_INIT)| DSP_INIT_NEWC) & ~(1 << 3)); - } - break; - case RCV: - break; - case SPK_PATH: - case RING_SPK: - printk("%s : >>>>>>>>>>>>>>>PUT SPK_PATH\n",__func__); - if (pre_path == OFF) { - cx2070x_real_read(codec,DSP_INIT); - cx2070x_write(codec,DSP_INIT,cx2070x_read_reg_cache(codec,DSP_INIT)| DSP_INIT_NEWC | DSP_INIT_STREAM_3); - } - break; - case HP_PATH: - case HP_NO_MIC: - case RING_HP: - case RING_HP_NO_MIC: - if (pre_path == OFF) { - cx2070x_real_read(codec,DSP_INIT); - cx2070x_write(codec,DSP_INIT,cx2070x_read_reg_cache(codec,DSP_INIT)| DSP_INIT_NEWC | DSP_INIT_STREAM_3); - } - break; - case BT: - break; - case SPK_HP: - case RING_SPK_HP: - if (pre_path == OFF) { - cx2070x_real_read(codec,DSP_INIT); - cx2070x_write(codec,DSP_INIT,cx2070x_read_reg_cache(codec,DSP_INIT)| DSP_INIT_NEWC | DSP_INIT_STREAM_3); - } - break; - default: - return -EINVAL; - } - - return 0; -} - -static int cx2070x_capture_path_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct cx2070x_priv *cx2070x = get_cx2070x_priv(codec); - - if (!cx2070x) { - printk("%s : cx2070x_priv is NULL\n", __func__); - return -EINVAL; - } - - printk("%s : capture_path %ld\n", __func__, - ucontrol->value.integer.value[0]); - - ucontrol->value.integer.value[0] = cx2070x->capture_path; - - return 0; -} - -static int cx2070x_capture_path_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct cx2070x_priv *cx2070x = get_cx2070x_priv(codec); - long int pre_path; - - if (!cx2070x) { - printk("%s : cx2070x_priv is NULL\n", __func__); - return -EINVAL; - } - - if (cx2070x->capture_path == ucontrol->value.integer.value[0]){ - printk("%s : capture_path is not changed!\n", __func__); - return 0; - } - - pre_path = cx2070x->capture_path; - cx2070x->capture_path = ucontrol->value.integer.value[0]; - - printk("%s : set capture_path %ld, pre_path %ld\n", __func__, - cx2070x->capture_path, pre_path); - - switch (cx2070x->capture_path) { - case MIC_OFF: - if (pre_path != MIC_OFF) { - cx2070x_real_read(codec,DSP_INIT); - cx2070x_write(codec,DSP_INIT,(cx2070x_read_reg_cache(codec,DSP_INIT)| DSP_INIT_NEWC) & ~(DSP_INIT_STREAM_5)); - } - break; - case Main_Mic: - printk("%s : >>>>>>>>>>>>>>>PUT MAIN_MIC_PATH\n",__func__); - if (pre_path == MIC_OFF) { - cx2070x_real_read(codec,DSP_INIT); - cx2070x_write(codec,DSP_INIT,cx2070x_read_reg_cache(codec,DSP_INIT)| DSP_INIT_NEWC | DSP_INIT_STREAM_5); - } - break; - case Hands_Free_Mic: - if (pre_path == MIC_OFF) { - cx2070x_real_read(codec,DSP_INIT); - cx2070x_write(codec,DSP_INIT,cx2070x_read_reg_cache(codec,DSP_INIT)| DSP_INIT_NEWC | DSP_INIT_STREAM_5); - } - break; - case BT_Sco_Mic: - break; - default: - return -EINVAL; - } - - return 0; -} - -static const struct snd_kcontrol_new cx2070x_snd_path_controls[] = { - SOC_ENUM_EXT("Playback Path", cx2070x_playback_path_type, - cx2070x_playback_path_get, cx2070x_playback_path_put), - - SOC_ENUM_EXT("Capture MIC Path", cx2070x_capture_path_type, - cx2070x_capture_path_get, cx2070x_capture_path_put), -}; - - -// add non dapm controls -static int cx2070x_add_controls(struct snd_soc_codec *codec) -{ - INFO("%lu: %s() called\n",jiffies,__func__); - - return (snd_soc_add_codec_controls(codec, cx2070x_snd_controls, ARRAY_SIZE(cx2070x_snd_controls))); -} - -static int hpportpga_event(struct snd_soc_dapm_widget *w, -struct snd_kcontrol *kcontrol, int event) -{ - unsigned int old; - struct snd_soc_codec * codec = w->codec; - unsigned int on = 0x1; - old = cx2070x_read_reg_cache(codec,OUTPUT_CONTROL); - old &=~ on; - old &= 0xFF; - switch (event) { - case SND_SOC_DAPM_POST_PMU: - cx2070x_write(codec,OUTPUT_CONTROL,old|on ); - break; - case SND_SOC_DAPM_POST_PMD: - cx2070x_write(codec,OUTPUT_CONTROL,old); - break; - } - return 0; - -} - -static int lineoutpga_event(struct snd_soc_dapm_widget *w, -struct snd_kcontrol *kcontrol, int event) -{ - unsigned int val; - struct snd_soc_codec * codec = w->codec; - unsigned int on = (unsigned int)1<<1; - val = cx2070x_read_reg_cache(codec,OUTPUT_CONTROL); - val &=~ on; - val &= 0xFF; - switch (event) { - case SND_SOC_DAPM_POST_PMU: - cx2070x_write(codec,OUTPUT_CONTROL,val|on); - break; - case SND_SOC_DAPM_POST_PMD: - cx2070x_write(codec,OUTPUT_CONTROL,val); - break; - } - return 0; -} -static int clsdportpga_event(struct snd_soc_dapm_widget *w, -struct snd_kcontrol *kcontrol, int event) -{ - unsigned int val; - struct snd_soc_codec * codec = w->codec; - unsigned int on = (unsigned int)1<<2; - val = cx2070x_read_reg_cache(codec,OUTPUT_CONTROL); - val &=~ on; - val &= 0xFF; - switch (event) { - case SND_SOC_DAPM_POST_PMU: - cx2070x_write(codec,OUTPUT_CONTROL,val|on); - break; - case SND_SOC_DAPM_POST_PMD: - cx2070x_write(codec,OUTPUT_CONTROL,val); - break; - } - return 0; -} - -static int lineinpga_event(struct snd_soc_dapm_widget *w, -struct snd_kcontrol *kcontrol, int event) -{ - //unsigned int val; - //struct snd_soc_codec * codec = w->codec; - //unsigned int on = (unsigned int)1<<2; - //val = cx2070x_read_reg_cache(codec,OUTPUT_CONTROL); - //val &=~ on; - //val &= 0xFF; - //switch (event) { - //case SND_SOC_DAPM_POST_PMU: - // cx2070x_write(codec,OUTPUT_CONTROL,val|on); - // break; - //case SND_SOC_DAPM_POST_PMD: - // cx2070x_write(codec,OUTPUT_CONTROL,val); - // break; - //} - return 0; -} - -static int micportpga_event(struct snd_soc_dapm_widget *w, -struct snd_kcontrol *kcontrol, int event) -{ - //unsigned int val; - //struct snd_soc_codec * codec = w->codec; - //unsigned int on = (unsigned int)1<<1; - //val = cx2070x_read_reg_cache(codec,OUTPUT_CONTROL); - //val &=~ on; - //val &= 0xFF; - //switch (event) { - //case SND_SOC_DAPM_POST_PMU: - // cx2070x_write(codec,OUTPUT_CONTROL,val|on); - // break; - //case SND_SOC_DAPM_POST_PMD: - // cx2070x_write(codec,OUTPUT_CONTROL,val); - // break; - //} - return 0; -} - -static int aout_pga_event(struct snd_soc_dapm_widget *w, -struct snd_kcontrol *kcontrol, int event) -{ - unsigned int val; - struct snd_soc_codec * codec = w->codec; - unsigned int on = (unsigned int)1<<7; //steam 7 - unsigned int reg = DSP_INIT; - val = cx2070x_read_reg_cache(codec,reg); - val &=~ on; - val &= 0xFF; - switch (event) { - case SND_SOC_DAPM_POST_PMU: - cx2070x_write(codec,STREAMOP_ROUTING,0x60 ); // scal_out - cx2070x_write(codec,STREAM7_SOURCE,5 ); //Scale_out - cx2070x_write(codec,reg,val|on ); - break; - case SND_SOC_DAPM_POST_PMD: - cx2070x_write(codec,STREAM7_SOURCE,0 ); //disconnect - cx2070x_write(codec,reg,val); - break; - } - return 0; -} - -static int dout_pga_event(struct snd_soc_dapm_widget *w, -struct snd_kcontrol *kcontrol, int event) -{ - unsigned int val; - struct snd_soc_codec * codec = w->codec; - unsigned int on = (unsigned int)1<<4; - unsigned int reg = DSP_INIT; - val = cx2070x_read_reg_cache(codec,reg); - val &=~ on; - val &= 0xFF; - switch (event) { - case SND_SOC_DAPM_POST_PMU: - cx2070x_write(codec,STREAMOP_ROUTING,0x60 ); // scal_out - snd_soc_update_bits(codec, MIC_CONTROL, 3, 1); - //cx2070x_write(codec,STREAM6_ROUTING,5 ); // scal_out - cx2070x_write(codec,reg,val|on ); - break; - case SND_SOC_DAPM_POST_PMD: - cx2070x_write(codec,STREAMOP_ROUTING,0x62 ); // scal_out - cx2070x_write(codec,STREAM6_ROUTING,0 ); //disconnect - cx2070x_write(codec,reg,val); - break; - } - return 0; -} - -static int ain_pga_event(struct snd_soc_dapm_widget *w, -struct snd_kcontrol *kcontrol, int event) -{ - unsigned int val; - struct snd_soc_codec * codec = w->codec; - unsigned int on = (unsigned int)1<<2; //steam 2 - unsigned int reg = DSP_INIT; - val = cx2070x_read_reg_cache(codec,reg); - val &=~ on; - val &= 0xFF; - switch (event) { - case SND_SOC_DAPM_POST_PMU: - //cx2070x_write(codec,VOICE_IN_SOURCE, 0x2 ); //stream 2 -> Voice In - cx2070x_write(codec,reg,val|on ); - break; - case SND_SOC_DAPM_POST_PMD: - cx2070x_write(codec,reg,val); - break; - } - return 0; -} - -static int din_pga_event(struct snd_soc_dapm_widget *w, -struct snd_kcontrol *kcontrol, int event) -{ - unsigned int val; - struct snd_soc_codec * codec = w->codec; - unsigned int on = (unsigned int)1<<4; //stream 4 - unsigned int reg = DSP_INIT; - val = cx2070x_read_reg_cache(codec,reg); - val &=~ on; - val &= 0xFF; - switch (event) { - case SND_SOC_DAPM_POST_PMU: - cx2070x_write(codec,VOICE_IN_SOURCE, 0x4 ); //stream 4 -> Voice In - cx2070x_write(codec,reg,val|on ); - break; - case SND_SOC_DAPM_POST_PMD: - cx2070x_write(codec,reg,val); - break; - } - return 0; -} - -static int adc_pga_event(struct snd_soc_dapm_widget *w, -struct snd_kcontrol *kcontrol, int event) -{ - unsigned int val; - struct snd_soc_codec * codec = w->codec; - unsigned int on = (unsigned int)1<<5; //stream 5 - unsigned int reg = DSP_INIT; - val = cx2070x_read_reg_cache(codec,reg); - val &=~ on; - val &= 0xFF; - switch (event) { - case SND_SOC_DAPM_POST_PMU: - cx2070x_write(codec,reg,val|on ); - break; - case SND_SOC_DAPM_POST_PMD: - cx2070x_write(codec,reg,val); - break; - } - return 0; -} - -static const struct snd_soc_dapm_widget cx2070x_dapm_widgets[]= -{ - - //Playback - SND_SOC_DAPM_DAC( "DAC", "Playback", DSP_INIT,3,0), //stream 3 - - SND_SOC_DAPM_PGA_E("AOUT PGA", SND_SOC_NOPM, - 0, 0, NULL, 0, aout_pga_event, - SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_PGA_E("DOUT PGA", SND_SOC_NOPM, - 0, 0, NULL, 0, dout_pga_event, - SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_PGA_E("HP Port", SND_SOC_NOPM, - 0, 0, NULL, 0, hpportpga_event, - SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_PGA_E("CLASSD Port", SND_SOC_NOPM, - 0, 0, NULL, 0, clsdportpga_event, - SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_PGA_E("LINEOUT Port", SND_SOC_NOPM, - 0, 0, NULL, 0, lineoutpga_event, - SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), - - //Output Pin. - SND_SOC_DAPM_OUTPUT("SPK OUT"), - SND_SOC_DAPM_OUTPUT("LINE OUT"), - SND_SOC_DAPM_OUTPUT("HP OUT"), - SND_SOC_DAPM_OUTPUT("PCM OUT"), - - // - // Captuer - // - SND_SOC_DAPM_ADC_E("ADC", "Capture", SND_SOC_NOPM, - 0, 0, adc_pga_event, - SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), - - - SND_SOC_DAPM_PGA_E("AIN PGA", SND_SOC_NOPM, - 0, 0, NULL, 0, ain_pga_event, - SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_PGA_E("DIN PGA", SND_SOC_NOPM, - 0, 0, NULL, 0, din_pga_event, - SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_PGA_E("MIC Port", SND_SOC_NOPM, - 0, 0, NULL, 0, micportpga_event, - SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_PGA_E("LINEIN Port", SND_SOC_NOPM, - 0, 0, NULL, 0, lineinpga_event, - SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), - - //DECLARE_TLV_DB_SCALE - - SND_SOC_DAPM_INPUT("MIC IN"), - SND_SOC_DAPM_INPUT("PCM IN"), - SND_SOC_DAPM_INPUT("LINE IN"), - - SND_SOC_DAPM_MUX("Capture Source", SND_SOC_NOPM, 0, 0, - &input_select_controls), - - SND_SOC_DAPM_MICBIAS("Mic Bias",MIC_CONTROL,3,0), -#if 0 - //machina layer. - SND_SOC_DAPM_MIC("INT MIC", NULL), - SND_SOC_DAPM_MIC("BT IN", NULL), - SND_SOC_DAPM_HP("BT OUT", NULL), - SND_SOC_DAPM_SPK("INT SPK", NULL), - SND_SOC_DAPM_HP("Headphone", NULL), -#endif -}; - -static const struct snd_soc_dapm_route cx2070x_routes[] = -{ - //playback. - { "AOUT PGA", NULL,"DAC" }, - { "DOUT PGA", NULL,"DAC" }, - - { "HP Port", NULL,"AOUT PGA" }, - { "LINEOUT Port", NULL,"AOUT PGA" }, - { "CLASSD Port", NULL,"AOUT PGA" }, - - { "HP OUT", NULL,"HP Port" }, - { "LINE OUT", NULL,"LINEOUT Port" }, - { "SPK OUT", NULL,"CLASSD Port" }, - { "PCM OUT", NULL,"DOUT PGA" }, - - //capture. - { "ADC", NULL,"Capture Source" }, - - { "Capture Source", "MIC","AIN PGA" }, - { "Capture Source", "PCM","DIN PGA" }, - - { "AIN PGA", NULL,"MIC Port" }, - // { "MIC Port", NULL,"Mic Bias" }, - { "MIC Port", NULL,"MIC IN" }, - - // { "Mic Bias", NULL,"MIC IN" }, - { "DIN PGA", NULL,"PCM IN" }, -#if 0 - //machina layer. - { "Headphone", NULL,"HP OUT" }, - { "INT SPK", NULL,"SPK OUT" }, - { "BT OUT", NULL,"PCM OUT" }, - { "MIC IN", NULL,"INT MIC" }, - { "PCM IN", NULL,"BT IN" }, -#endif -}; - -static int cx2070x_add_widgets(struct snd_soc_codec *codec) -{ - struct snd_soc_dapm_context *dapm = &codec->dapm; - - INFO("%lu: %s() called\n",jiffies,__func__); - - snd_soc_dapm_new_controls(dapm, cx2070x_dapm_widgets, ARRAY_SIZE(cx2070x_dapm_widgets)); - snd_soc_dapm_add_routes(dapm, cx2070x_routes, ARRAY_SIZE(cx2070x_routes)); - return 0; -} - -static int cx2070x_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) - -{ - struct snd_soc_codec *codec = dai->codec; - unsigned int s5,s3,i2s,dsp; -#define _3_3_f_f_5 1 -#define _1_1_7_7_0 0 - int err =0; - - ERROR("%lu: %s() called\n",jiffies,__func__); - ERROR("\tformat:%u speed:%u\n",params_format(params),params_rate(params)); - - switch(params_format(params)) - { - case SNDRV_PCM_FORMAT_S16_LE: s5=STREAM5_SAMPLE_16_LIN; s3=STREAM5_SAMPLE_16_LIN; i2s=_3_3_f_f_5; break; - case SNDRV_PCM_FORMAT_S16_BE: s5=STREAM5_SAMPLE_16_LIN; s3=STREAM5_SAMPLE_16_LIN; i2s=_3_3_f_f_5; break; - case SNDRV_PCM_FORMAT_MU_LAW: s5=STREAM5_SAMPLE_U_LAW; s3=STREAM5_SAMPLE_U_LAW; i2s=_1_1_7_7_0; break; - case SNDRV_PCM_FORMAT_A_LAW: s5=STREAM5_SAMPLE_A_LAW; s3=STREAM5_SAMPLE_A_LAW; i2s=_1_1_7_7_0; break; - default: - printk(KERN_ERR "cx2070x: unsupported PCM format 0x%u\n",params_format(params)); - return -EINVAL; - } - - switch(params_rate(params)) - { - case 8000: s5|= STREAM5_RATE_8000; - s3|=STREAM3_STREAM_STEREO|STREAM3_RATE_8000; break; - case 11025: s5|= STREAM5_RATE_11025; - s3|=STREAM3_STREAM_STEREO|STREAM3_RATE_11025; break; - case 16000: s5|= STREAM5_RATE_16000; - s3|=STREAM3_STREAM_STEREO|STREAM3_RATE_16000; break; - case 22050: s5|= STREAM5_RATE_22050; - s3|=STREAM3_STREAM_STEREO|STREAM3_RATE_22050; break; - case 24000: s5|= STREAM5_RATE_24000; - s3|=STREAM3_STREAM_STEREO|STREAM3_RATE_24000; break; - case 32000: s5|= STREAM5_RATE_32000; - s3|=STREAM3_STREAM_STEREO|STREAM3_RATE_32000; break; - case 44100: s5|= STREAM5_RATE_44100; - s3|=STREAM3_STREAM_STEREO|STREAM3_RATE_44100; break; - case 48000: s5|= STREAM5_RATE_48000; - s3|=STREAM3_STREAM_STEREO|STREAM3_RATE_48000; break; - case 88200: s5|= STREAM5_RATE_88200; - s3|=STREAM3_STREAM_STEREO|STREAM3_RATE_88200; break; - case 96000: s5|= STREAM5_RATE_96000; - s3|=STREAM3_STREAM_STEREO|STREAM3_RATE_96000; break; - default: - printk(KERN_ERR "cx2070x: unsupported rate %d\n",params_rate(params)); - return -EINVAL; - } - - cx2070x_real_write(codec,PORT1_TX_CLOCKS_PER_FRAME_PHASE,i2s?0x07:0x01); - cx2070x_real_write(codec,PORT1_RX_CLOCKS_PER_FRAME_PHASE,i2s?0x07:0x01); - cx2070x_real_write(codec,PORT1_TX_SYNC_WIDTH, i2s?0x0f:0x07); - cx2070x_real_write(codec,PORT1_RX_SYNC_WIDTH, i2s?0x0f:0x07); - cx2070x_real_write(codec,PORT1_CONTROL_2, i2s?0x05:0x00); - /*params for port2 by showy.zhang*/ - cx2070x_real_write(codec,STREAM5_RATE,s5); - cx2070x_real_write(codec,STREAM3_RATE,s3);// cause by incorrect parameter -#if 0 - cx2070x_real_read(codec,DSP_INIT); - dsp=cx2070x_read_reg_cache(codec,DSP_INIT); - printk(">>>>>>>>>>>> dsp = %0x", dsp); - if ((err=cx2070x_dsp_init(codec,dsp|DSP_INIT_NEWC))<0) - return err; -#endif - return 0; -} - -static int cx2070x_mute(struct snd_soc_dai *dai, int mute) -{ - struct snd_soc_codec *codec = dai->codec; - - ERROR("%lu: %s(%d) called\n",jiffies,__func__,mute); -#if 0 - cx2070x_real_write(codec,VOLUME_MUTE,mute?VOLUME_MUTE_ALL:b_00000000); - - if( mute) - { -// cx2070x_real_write(codec,DSP_POWER,0xe0); // deep sleep mode -// cx2070x_dsp_init(codec,DSP_INIT_STREAM_OFF); - /*mute I2S output*/ - cx2070x_real_read(codec,DSP_INIT); - cx2070x_write(codec,DSP_INIT,(cx2070x_read_reg_cache(codec,DSP_INIT)| DSP_INIT_NEWC) & ~(1 << 3)); - } - else - { - /*unmute I2S output*/ - cx2070x_real_read(codec,DSP_INIT); - cx2070x_write(codec,DSP_INIT,cx2070x_read_reg_cache(codec,DSP_INIT)| DSP_INIT_NEWC | DSP_INIT_STREAM_3); - //cx2070x_dsp_init(codec,DSP_INIT_NEWC | 0xff); - } -#endif - return 0; -} - -static int cx2070x_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id, unsigned int freq, int dir) -{ - struct snd_soc_codec *codec = dai->codec; - struct cx2070x_priv *channel = get_cx2070x_priv(codec); - - INFO("%lu: %s() called\n",jiffies,__func__); - - // sysclk is not used where, but store it anyway - channel->sysclk = freq; - return 0; -} - -static int cx2070x_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) -{ - struct snd_soc_codec *codec = dai->codec; - struct cx2070x_priv *channel = get_cx2070x_priv(codec); - - INFO("%lu: %s() called\n",jiffies,__func__); - - // set master/slave audio interface - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) - { - case SND_SOC_DAIFMT_CBS_CFS: // This design only supports slave mode - channel->master = 0; - break; - default: - printk(KERN_ERR "unsupport DAI format, driver only supports slave mode\n"); - return -EINVAL; - } - - switch (fmt & SND_SOC_DAIFMT_INV_MASK) - { - case SND_SOC_DAIFMT_NB_NF: // This design only supports normal bclk + frm - break; - default: - printk(KERN_ERR "unsupport DAI format, driver only supports normal bclk+ frm\n"); - return -EINVAL; - } - - // interface format - switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) - { - case SND_SOC_DAIFMT_I2S: // This design only supports I2S - break; - default: - printk( KERN_ERR "unspoort DAI format, driver only supports I2S interface.\n"); - return -EINVAL; - } - - return 0; -} - -struct snd_soc_dai_ops cx2070x_dai_ops = -{ - .set_sysclk=cx2070x_set_dai_sysclk, - .set_fmt = cx2070x_set_dai_fmt, - .digital_mute=cx2070x_mute, - .hw_params = cx2070x_hw_params, -}; - -struct snd_soc_dai_driver soc_codec_cx2070x_dai = -{ - .name = "cx2070x-hifi", - .ops = &cx2070x_dai_ops, - .capture = { - .stream_name="Capture", - .formats = CX2070X_FORMATS, - .rates = CX2070X_RATES, - .channels_min = 1, - .channels_max = 2, - }, - .playback= { - .stream_name="Playback", - .formats = CX2070X_FORMATS, - .rates = CX2070X_RATES, - .channels_min = 1, - .channels_max = 2, - }, - .symmetric_rates = 1, -}; -EXPORT_SYMBOL_GPL(soc_codec_cx2070x_dai); - -static int cx2070x_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) -{ - INFO("%lu: %s(,%d) called\n",jiffies,__func__,level); - - switch (level) - { - // Fully on - case SND_SOC_BIAS_ON: - cx2070x_real_write(codec,DSP_POWER,0x20); - // all power is driven by DAPM system - break; - - // Partial on - case SND_SOC_BIAS_PREPARE: - break; - - // Off, with power - case SND_SOC_BIAS_STANDBY: - //cx2070x_real_write(codec,VOLUME_MUTE,VOLUME_MUTE_ALL); // mute all - //cx2070x_real_write(codec,DSP_POWER,0xe0); // deep sleep mode - //cx2070x_dsp_init(codec,DSP_INIT_STREAM_OFF); - - // TODO: power down channel - break; - - // Off, without power - case SND_SOC_BIAS_OFF: - cx2070x_real_write(codec,VOLUME_MUTE,VOLUME_MUTE_ALL); // mute all - cx2070x_real_write(codec,DSP_POWER,0xe0); // deep sleep mode - cx2070x_dsp_init(codec,DSP_INIT_STREAM_OFF); - // TODO: put channel into deep-sleep - break; - } - - return 0; -} - -int I2cWrite( struct snd_soc_codec *codec, unsigned char ChipAddr, unsigned long cbBuf, unsigned char* pBuf) -{ -#ifdef USING_SPI - struct spi_device * spi = (struct spi_device *) codec->control_data; - pBuf[0] |= 0x80; //SPI_WRITE - spi_write(spi,pBuf,cbBuf); - return true; -#else //#ifdef ENABLE_SPI - struct i2c_client *client = (struct i2c_client *)codec->control_data; - struct i2c_adapter *adap = client->adapter; - struct i2c_msg msg[1]; - - - msg[0].addr = client->addr; - msg[0].flags = client->flags & I2C_M_TEN; - msg[0].buf = pBuf; - msg[0].len = cbBuf; - if (i2c_transfer(adap,msg,1)!=1) - { - printk(KERN_ERR "cx2070x: I2cWriteThenRead failed.\n"); - - return 0; - } - else - { - return 1; - } -#endif //#!ENABLE_SPI -} - -int I2cWriteThenRead( struct snd_soc_codec *codec, unsigned char ChipAddr, unsigned long cbBuf, - unsigned char* pBuf, unsigned long cbReadBuf, unsigned char*pReadBuf) -{ - -#ifdef USING_SPI - u8 reg[3]; - struct spi_device * spi = (struct spi_device *) codec->control_data; - reg[0] = pBuf[0]; - reg[1] = pBuf[1]; - reg[2] = 0; - spi_write_then_read(spi, reg, 3, pReadBuf,cbReadBuf); - return true; -#else //#ifdef USING_SPI - struct i2c_client *client = (struct i2c_client *)codec->control_data; - struct i2c_adapter *adap = client->adapter; - struct i2c_msg msg[2]; - - msg[0].addr = client->addr; - msg[0].flags = client->flags & I2C_M_TEN; - msg[0].len = cbBuf; - msg[0].buf = pBuf; - - msg[1].addr = client->addr; - msg[1].flags = (client->flags & I2C_M_TEN) | I2C_M_RD; - msg[1].len = cbReadBuf; - msg[1].buf = pReadBuf; - - if (i2c_transfer(adap,msg,2)!=2) - { - printk(KERN_ERR "cx2070x: I2cWriteThenRead failed.\n"); - return 0; - } - else - { - return 1; - } -#endif //#!ENABLE_SPI -} - - -#if defined(CONFIG_SND_CX2070X_LOAD_FW) -static int cx2070x_apply_firmware_patch(struct snd_soc_codec *codec) -{ - int ret = 0; - const struct firmware *fw = NULL; - const unsigned char *dsp_code = NULL; - struct device *dev = codec->dev; - -#if defined(CONFIG_SND_CX2070X_USE_FW_H) - // load firmware from c head file. - dsp_code = ChannelFW; -#else - // load firmware from file. - ret = request_firmware(&fw, CX2070X_FIRMWARE_FILENAME, dev); - if (ret < 0) { - printk( KERN_ERR "%s(): Firmware %s not available %d", - __func__, CX2070X_FIRMWARE_FILENAME, ret); - return ret; - } - dsp_code = fw->data; -#endif - - ret = ApplyDSPChanges(dsp_code); - if (ret) { - printk(KERN_ERR "cx2070x: patch firmware failed, Error %d\n", ret); - } else { - printk(KERN_INFO "cx2070x: patch firmware successfully.\n"); - } - - return ret; -} - -static int cx2070x_download_firmware(struct snd_soc_codec *codec) -{ - int ret = 0; - char *buf = NULL; - const struct firmware *fw = NULL; - const unsigned char *dsp_code = NULL; -#if !defined(CONFIG_SND_CX2070X_USE_FW_H) - struct device *dev = codec->dev; -#endif - - // load firmware to memory. -#if defined(CONFIG_SND_CX2070X_USE_FW_H) - // load firmware from c head file. - dsp_code = ChannelFW; -#else - // load firmware from file. - ret = request_firmware(&fw, CX2070X_FIRMWARE_FILENAME,dev); - if( ret < 0) - { - printk( KERN_ERR "%s(): Firmware %s not available %d",__func__,CX2070X_FIRMWARE_FILENAME,ret); - goto LEAVE; - } - dsp_code = fw->data; -#endif // #if defined(CONFIG_SND_CX2070X_USE_FW_H) - // - // Load rom data from a array. - // - buf = (char*)kzalloc(0x200,GFP_KERNEL); - if (buf == NULL) - { - printk(KERN_ERR "cx2070x: out of memory .\n"); - ret = -ENOMEM; - goto LEAVE; - } - - // - // Setup the i2c callback function. - // - SetupI2cWriteCallback( (void *) codec, (fun_I2cWrite) I2cWrite,32); - SetupI2cWriteThenReadCallback( (void *) codec, (fun_I2cWriteThenRead) I2cWriteThenRead); - - // download - SetupMemoryBuffer(buf); - - ret = DownloadFW(dsp_code); - if(ret) - { - printk(KERN_ERR "cx2070x: download firmware failed, Error %d\n",ret); - } - else - { - printk(KERN_INFO "cx2070x: download firmware successfully.\n"); - } - if (buf) - { - kfree(buf); - } -LEAVE: - -#if defined(CONFIG_SND_CX2070X_LOAD_FW) && !defined(CONFIG_SND_CX2070X_USE_FW_H) - if(fw) - { - release_firmware(fw); - } -#endif - return ret; - -} -#endif - -unsigned int cx2070x_hw_read( struct snd_soc_codec *codec, unsigned int regaddr) -{ - unsigned char data; - unsigned char chipaddr = 0; - unsigned char reg[2]; -#ifdef USING_I2C - struct i2c_client *client = (struct i2c_client *) codec->control_data; - chipaddr = client->addr; -#endif - reg[0] = regaddr>>8; - reg[1] = regaddr&0xff; - I2cWriteThenRead(codec,chipaddr, 2, reg, 1,&data); - return (unsigned int)data; -} - -unsigned int (*hw_read)(struct snd_soc_codec *, unsigned int); - -// -// Initialise the cx2070x driver -// Register the mixer and dsp interfaces with the kernel -// -static int NOINLINE cx2070x_init(struct snd_soc_codec* codec) -{ - struct cx2070x_priv *cx2070x = get_cx2070x_priv(codec); - int n,vl,vh,vm,fh, fl,ret = 0; - cx2070x_reg_t *reg_cache; - - printk(">>>>>>>%s",__func__); - INFO("%lu: %s() called\n",jiffies,__func__); - - codec->control_data = cx2070x->control_data; - - -#if defined(CONFIG_SND_CX2070X_GPIO_RESET) - cx2070x_reset_device(); -#endif - -#if CX2070X_TRISTATE_EEPROM - // If CX2070X has to float the pins to the NVRAM, enable this code - for(;;) - { - int pad,pbd; - pad=cx2070x_real_read(codec,PAD); - pbd=cx2070x_real_read(codec,PBD); - printk("%s(): PAD/PBD=%02x/%02x\n",__func__,pad,pbd); - - _cx2070x_real_write(codec,PAD,pad&~(1<<4)); - _cx2070x_real_write(codec,PBD,pbd&~(1<<6)); - msleep(1000); - } -#endif - - -#if defined(CONFIG_SND_CX2070X_LOAD_FW) - ret = cx2070x_download_firmware(codec); - if( ret < 0) - { - printk(KERN_ERR "%s: failed to download firmware\n",__func__); - return ret; - } - -#endif - // Verify that Channel/Balboa is ready. - // May have to wait for ~5sec becore Channel/Balboa comes out of reset - for(n=5000;!bNoHW;) - { - int abcode=cx2070x_real_read(codec,ABORT_CODE); - // int abcode=cx2070x_real_read(codec,CHIP_VERSION); - printk(">>>>>>>>>>>>>>>%s abcode = %d",__func__, abcode); - if (abcode==0x01) - break; // initialization done! - if (--n==0) - { - printk(KERN_ERR "Timeout waiting for cx2070x to come out of reset!\n"); - return -EIO; - } - msleep(1); - } - - cx2070x_real_read(codec,FIRMWARE_VERSION); - cx2070x_real_read(codec,PATCH_VERSION); - cx2070x_real_read(codec,CHIP_VERSION); - cx2070x_real_read(codec,RELEASE_TYPE); - - reg_cache = GET_REG_CACHE(codec); - fl=(reg_cache[FIRMWARE_VERSION]>>0)&0xFF; - fl=(fl>>4)*10+(fl&0xf); - fh=(reg_cache[FIRMWARE_VERSION]>>8)&0xFF; - - // determine whether the codec is ROM version or not. - if( fh == 5) - { //firmware 5.x - //shows the firmware patch version. - cx2070x_real_read(codec,ROM_PATCH_VER_HB); - cx2070x_real_read(codec,ROM_PATCH_VER_MB); - cx2070x_real_read(codec,ROM_PATCH_VER_LB); - vh = reg_cache[ROM_PATCH_VER_HB]; - vm = reg_cache[ROM_PATCH_VER_MB]; - vl = reg_cache[ROM_PATCH_VER_LB]; - printk("cx2070x: firmware version %u.%u, patch %u.%u.%u, chip CX2070%u (ROM)\n",fh,fl,vh,vm,vl,reg_cache[CHIP_VERSION]); - } - else if( fh == 4) - { - //firmware 4.x - printk("cx2070x: firmware version %u.%u, chip CX2070%u (RAM), ",fh,fl,reg_cache[CHIP_VERSION]); - // shows the firmware release type. - switch(reg_cache[RELEASE_TYPE]) - { - case 12: printk("Custom Release\n"); break; - case 14: printk("Engineering Release\n"); break; - case 15: printk("Field Release\n"); break; - default: printk("Release %u?\n",reg_cache[RELEASE_TYPE]); break; - } - } - else - { - printk("cx2070x: Unsupported firmware version %u.%u!!!\n",fh,fl); - ret = -EINVAL; - goto card_err; - } - - - if (reg_cache[PATCH_VERSION]) - { - vl=(reg_cache[PATCH_VERSION]>>0)&0xFF; - vh=(reg_cache[PATCH_VERSION]>>8)&0xFF; - printk("%s(): CX2070X patch version %u.%u\n",__func__,vh,vl); - } - - // Initialize the CX2070X regisers and/or read them as needed. - for(n=0;ndapm, "LINE IN"); - //snd_soc_dapm_nc_pin( &codec->dapm, "LINE OUT"); - //snd_soc_dapm_enable_pin( &codec->dapm, "INT MIC"); - //snd_soc_dapm_enable_pin( &codec->dapm, "INT SPK"); - //snd_soc_dapm_disable_pin( &codec->dapm, "BT IN"); - //snd_soc_dapm_enable_pin( &codec->dapm, "Headphone"); - //snd_soc_dapm_disable_pin( &codec->dapm, "BT OUT"); - - -#if defined(CONFIG_SND_CX2070X_GPIO_JACKSENSE) - /* Headset jack detection */ - ret = snd_soc_jack_new(codec, "Headset Jack", - SND_JACK_HEADSET, &hs_jack); - if (ret) - { - printk(KERN_ERR "CX2070X: failed to register Headset Jack\n"); - goto card_err; - } - - ret = snd_soc_jack_add_gpios(&hs_jack, ARRAY_SIZE(hs_jack_gpios), - hs_jack_gpios); - if (ret) - { - printk(KERN_ERR "CX2070X: failed to add jack gpios.\n"); - goto card_err; - } - - ret = snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins), - hs_jack_pins); - if (ret) - { - printk(KERN_ERR "CX2070X: failed to add soc jack pin\n"); - goto card_err; - } -#else - snd_soc_dapm_sync( &codec->dapm); -#endif //#if defined(CONFIG_SND_CX2070X_GPIO_JACKSENSE) - -#if defined(CONFIG_SND_CXLIFEGUARD) - cxdbg_dev_init(codec); -#endif - - cx2070x_real_write(codec, USB_LOCAL_VOLUME, 0x42); - - if( ret == 0) - { - printk(KERN_INFO "CX2070X: codec is ready.\n"); - } - return ret; - -card_err: - return ret; -} - -static int cx2070x_hw_reset(void) -{ - int err; - /* Reset */ - err = gpio_request(CODEC_RESET_GPIO_PIN, "nCX2070X_Reset"); - printk(KERN_ERR "channel reset gpio=%d\n", CODEC_RESET_GPIO_PIN); - if (err) - printk(KERN_ERR "#### failed to request GPH3_2 for Audio Reset\n"); - - gpio_direction_output(CODEC_RESET_GPIO_PIN, 0); - msleep(150); - gpio_direction_output(CODEC_RESET_GPIO_PIN, 1); - gpio_free(CODEC_RESET_GPIO_PIN); - msleep(150); - - return 0; -} - -#ifdef CONFIG_DEBUG_FS -#include -#include -static struct snd_soc_codec *g_cx2070x_codec; - -static int cx2070x_dbg_show_regs(struct seq_file *s, void *unused) -{ - - int reg_no = (int)s->private; - int i = 0; - int source_switch = 0; - if(reg_no == 0x4321) { - cx2070x_real_read(g_cx2070x_codec, DSP_INIT); - source_switch = cx2070x_read_reg_cache(g_cx2070x_codec,DSP_INIT) & DSP_ENABLE_STREAM_3_4; - printk(">>>>>>>>>>>>source_switch = %0x",source_switch); - switch (source_switch) { - case DSP_NO_SOURCE: - seq_printf(s, "NO_INPUT\t"); - break; - case DSP_ENABLE_STREAM_3: - seq_printf(s, "I2S_ONLY\t"); - break; - case DSP_ENABLE_STREAM_4: - seq_printf(s, "USB_ONLY\t"); - break; - case DSP_ENABLE_STREAM_3_4: - seq_printf(s, "I2S_USB_MIXING\t"); - break; - default: - seq_printf(s, "UNKNOWN\t"); - } - return 0; - } - - if (reg_no == noof(cx2070x_regs)) { - seq_printf(s, "Offset\tType\tValue\tName\n"); - for (i = 0; i < reg_no; i++) { - seq_printf(s, "0x%02X\t", cx2070x_regs[i].addr); - switch (cx2070x_regs[i].type) { - case REG_TYPE_RO: - seq_printf(s, "R"); - break; - case REG_TYPE_RW: - seq_printf(s, "RW"); - break; - case REG_TYPE_WC: - seq_printf(s, "WC"); - break; - case REG_TYPE_WI: - seq_printf(s, "WI"); - break; - default: - seq_printf(s, "UNKNOWN\t"); - } - seq_printf(s, "\t0x%02X\t%s\n", cx2070x_read_reg_cache(g_cx2070x_codec, i), - cx2070x_regs[i].name); - } - return 0; - } - - seq_printf(s, "Offset:\t0x%02X\n", cx2070x_regs[reg_no].addr); - - seq_printf(s, "Type:\t"); - switch (cx2070x_regs[reg_no].type) { - case REG_TYPE_RO: - seq_printf(s, "R"); - break; - case REG_TYPE_RW: - seq_printf(s, "RW"); - break; - case REG_TYPE_WC: - seq_printf(s, "WC"); - break; - case REG_TYPE_WI: - seq_printf(s, "WI"); - break; - default: - seq_printf(s, "UNKNOWN"); - } - seq_printf(s, "\n"); - - seq_printf(s, "Value:\t0x%02X\n", cx2070x_read_reg_cache(g_cx2070x_codec, reg_no)); - - return 0; -} - -static int cx2070x_dbg_reg_open(struct inode *inode, struct file *file) -{ - return single_open(file, cx2070x_dbg_show_regs, inode->i_private); -} - -static ssize_t cx2070x_dbg_reg_write(struct file *file, - const char __user *ubuf, - size_t count, loff_t *off) -{ - struct seq_file *seq = file->private_data; - char buf[8]; - unsigned long val; - int reg_no = (int)seq->private; - int ret = 0; - - if (count >= sizeof(buf)) { - ERROR("%s, The buffer is not enough.\n", __func__); - return -EINVAL; - } if (copy_from_user(buf, ubuf, count)) { - ERROR("%s, Faied to copy data from user space.\n", __func__); - return -EFAULT; - } - - buf[count] = 0; - - ret = strict_strtoul(buf, 16, &val); - if (ret < 0) { - ERROR("%s, Failed to convert a string to an unsinged long integer.\n", __func__); - return ret; - } - - if(reg_no == 0x4321) { - printk(">>>>>>>>>>>>>>>>>>>>>>val = %d",val); - cx2070x_real_read(g_cx2070x_codec, DSP_INIT); - switch (val) { - case NO_INPUT: - cx2070x_write(g_cx2070x_codec,DSP_INIT,(cx2070x_read_reg_cache(g_cx2070x_codec,DSP_INIT)| - DSP_INIT_NEWC) & ~DSP_ENABLE_STREAM_3_4); - break; - case I2S_ONLY: - cx2070x_write(g_cx2070x_codec,DSP_INIT,(cx2070x_read_reg_cache(g_cx2070x_codec,DSP_INIT)| - DSP_INIT_NEWC | DSP_ENABLE_STREAM_3) & ~DSP_ENABLE_STREAM_4); - break; - case USB_ONLY: - cx2070x_write(g_cx2070x_codec,DSP_INIT,(cx2070x_read_reg_cache(g_cx2070x_codec,DSP_INIT)| - DSP_INIT_NEWC | DSP_ENABLE_STREAM_4) & ~DSP_ENABLE_STREAM_3); - break; - case I2S_USB_MIXING: - cx2070x_write(g_cx2070x_codec,DSP_INIT,cx2070x_read_reg_cache(g_cx2070x_codec,DSP_INIT)| - DSP_INIT_NEWC | DSP_ENABLE_STREAM_3_4); - break; - default: - return count; - } - return count; - } - switch (cx2070x_regs[reg_no].type) { - case REG_TYPE_RO: - ERROR("%s, A read-only register 0x%02x cannot be written.\n", - __func__, cx2070x_regs[reg_no].addr); - return -EINVAL; - case REG_TYPE_WI: - case REG_TYPE_WC: - case REG_TYPE_RW: - ret = cx2070x_write(g_cx2070x_codec, reg_no, (u8)val); - if (ret) { - ERROR("%s, Failed to write register 0x%02x.\n", __func__, - cx2070x_regs[reg_no].addr); - return ret; - } - break; - default: - ERROR("%s, Unknown type register\n", __func__); - return -EINVAL; - } - - return count; -} - -static const struct file_operations cx2070x_debug_reg_fops = { - .open = cx2070x_dbg_reg_open, - .read = seq_read, - .write = cx2070x_dbg_reg_write, - .llseek = seq_lseek, - .release = single_release, -}; -#endif - -static int cx2070x_probe(struct snd_soc_codec *codec) -{ -#ifdef CONFIG_DEBUG_FS - struct dentry *d, *regs; - int n = 0; - int m = 0x4321; -#endif - - INFO("%lu: %s() called\n",jiffies,__func__); - printk(KERN_INFO "cx2070x codec driver version: %02x,%02x,%02x,%02x\n",(u8)((CX2070X_DRIVER_VERSION)>>24), - (u8)((CX2070X_DRIVER_VERSION)>>16), - (u8)((CX2070X_DRIVER_VERSION)>>8), - (u8)((CX2070X_DRIVER_VERSION))); - -#ifdef CONFIG_DEBUG_FS - g_cx2070x_codec = codec; - d = debugfs_create_dir("cx2070x", NULL); - if (IS_ERR(d)) - return PTR_ERR(d); - - debugfs_create_file("SOURCE_SWITCH", 0644, d, (void *)m, - &cx2070x_debug_reg_fops); - - regs = debugfs_create_dir("regs", d); - if (IS_ERR(regs)) - return PTR_ERR(regs); - - for (n = 0; n < noof(cx2070x_regs); n++) - debugfs_create_file(cx2070x_regs[n].name, 0644, regs, (void *)n, - &cx2070x_debug_reg_fops); - - debugfs_create_file("ALL", 0644, regs, (void *)n, - &cx2070x_debug_reg_fops); -#endif - - return cx2070x_init(codec); -} - -static int cx2070x_remove(struct snd_soc_codec *codec) -{ - INFO("%lu: %s() called\n",jiffies,__func__); - // power down chip - cx2070x_set_bias_level(codec, SND_SOC_BIAS_OFF); - -#if defined (CONFIG_SND_CX2070X_GPIO_JACKSENSE) - snd_soc_jack_free_gpios(&hs_jack, ARRAY_SIZE(hs_jack_gpios), - hs_jack_gpios); -#endif//#if defined (CONFIG_SND_CX2070X_GPIO_JACKSENSE) - return 0; -} - -static int cx2070x_suspend(struct snd_soc_codec *codec) -{ - INFO("%lu: %s() called\n",jiffies,__func__); - cx2070x_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - -static int cx2070x_resume(struct snd_soc_codec *codec) -{ - int n; - INFO("%lu: %s() called\n",jiffies,__func__); - - // Sync reg_cache with the hardware - for(n=0;ncontrol_data = (void*)i2c; - cx2070x->control_type = SND_SOC_I2C; - - cx2070x->input_sel = Cx_INPUT_SEL_BY_GPIO; - cx2070x->output_sel = Cx_OUTPUT_SEL_BY_GPIO; - - ret = snd_soc_register_codec(&i2c->dev, - &soc_codec_dev_cx2070x, &soc_codec_cx2070x_dai, 1); - printk(">>>>>>>%s ret = %d ",__func__,ret); - - if (ret < 0) - INFO("%s() failed ret = %d\n", __func__, ret); - return ret; -} - -static int cx2070x_i2c_remove(struct i2c_client *client) -{ - snd_soc_unregister_codec(&client->dev); -#if defined(CONFIG_SND_CXLIFEGUARD) - cxdbg_dev_exit(); -#endif - kfree(i2c_get_clientdata(client)); - return 0; -} - -static const struct i2c_device_id cx2070x_i2c_id[] = -{ - { "cx2070x", 0 }, - { } -}; - -MODULE_DEVICE_TABLE(i2c, cx2070x_i2c_id); - -static struct i2c_driver cx2070x_i2c_driver = { - .driver = { - .name = "cx2070x", - .owner = THIS_MODULE, - }, - .probe=cx2070x_i2c_probe, - .remove=__devexit_p(cx2070x_i2c_remove), - .id_table=cx2070x_i2c_id, -}; - -#elif defined(USING_SPI) -static int cx2070x_spi_probe(struct spi_device *spi) -{ - INFO("%lu: %s() called\n", jiffies, __func__); - - struct cx2070x_priv *cx2070x; - int ret = 0; - - //printk(KERN_INFO "Channel Audio Codec %08x\n", CX2070X_DRIVER_VERSION); - - cx2070x = (struct cx2070x_priv *)kzalloc(sizeof(struct cx2070x_priv), GFP_KERNEL); - if (cx2070x == NULL) - { - return -ENOMEM; - } - - spi_set_drvdata(spi, cx2070x); - - cx2070x->control_data = (void*)spi; - cx2070x->control_type = SND_SOC_SPI; - - cx2070x->input_sel = Cx_INPUT_SEL_BY_GPIO; - cx2070x->output_sel = Cx_OUTPUT_SEL_BY_GPIO; - - ret = snd_soc_register_codec(&spi->dev, - &soc_codec_dev_cx2070x, &soc_codec_cx2070x_dai, 1); - - if (ret < 0) - INFO("%s() failed ret = %d\n", __func__, ret); - return ret; -} - -static int cx2070x_spi_remove(struct spi_device *client) -{ - struct snd_soc_codec *codec = (struct snd_soc_codec *)spi_get_drvdata(client); - - kfree(codec->reg_cache); - return 0; -} - -static const struct spi_device_id cx2070x_spi_id[]={ - { CX2070X_SPI_DRIVER_NAME,NULL}, -}; - -static struct spi_driver cx2070x_spi_driver = { - .driver = { - .name = "cx2070x-codec", - .owner = THIS_MODULE, - }, - .probe = cx2070x_spi_probe, - .remove = __devexit_p(cx2070x_spi_remove), -}; -#endif - -static int __init cx2070x_modinit(void) -{ - int ret; - INFO("%lu: %s() called\n",jiffies,__func__); -#if defined(USING_I2C) - ret = i2c_add_driver(&cx2070x_i2c_driver); - if (ret != 0) { - printk(KERN_ERR "Failed to register CX2070X I2C driver: %d\n", - ret); - } -#elif defined(USING_SPI) - ret = spi_register_driver(&cx2070x_spi_driver); - if (ret != 0) { - printk(KERN_ERR "Failed to register CX2070X SPI driver: %d\n", - ret); - } -#endif - return ret; -} -module_init(cx2070x_modinit); - -static void __exit cx2070x_exit(void) -{ - INFO("%lu: %s() called\n",jiffies,__func__); -#if defined(USING_I2C) - i2c_del_driver(&cx2070x_i2c_driver); -#elif defined(USING_SPI) - spi_unregister_driver(&cx2070x_spi_driver); -#endif -} -module_exit(cx2070x_exit); - -int CX_AUDDRV_VERSION = CX2070X_DRIVER_VERSION; -EXPORT_SYMBOL_GPL(CX_AUDDRV_VERSION); -EXPORT_SYMBOL_GPL(soc_codec_dev_cx2070x); -MODULE_DESCRIPTION("ASoC cx2070x Codec Driver"); -MODULE_LICENSE("GPL"); - diff --git a/sound/soc/codecs/cx2070x.h b/sound/soc/codecs/cx2070x.h deleted file mode 100755 index 2c7c7133e461..000000000000 --- a/sound/soc/codecs/cx2070x.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * ALSA SoC CX2070X Channel codec driver - * - * Copyright: (C) 2009/2010 Conexant Systems - * - * Based on sound/soc/codecs/tlv320aic2x.c by Vladimir Barinov - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef _CX2070X_H -#define _CX2070X_H - - -#define CONFIG_SND_DIGICOLOR_SOC_CHANNEL_VER_4_30F 1 - -#ifdef CONFIG_SND_SOC_CNXT_FW_UPDATE -#define CONFIG_SND_CX2070X_LOAD_FW 1 -#endif -//#define CONFIG_SND_CX2070X_USE_FW_H 1 -//#define CONFIG_CNXT_USING_SPI_BUS 1 - -#ifdef CONFIG_SND_SOC_CNXT_JACKSENSE -#define CONFIG_SND_CX2070X_GPIO_JACKSENSE 1 -#endif -//#define CONFIG_SND_CX2070X_GPIO_RESET 1 -#define CONFIG_SND_CXLIFEGUARD 1 -//#define CONFIG_CXNT_SOFTWOARE_SIMULATION 1 -#define DBG_MONITOR_REG 1 - -//#define GPIO_HP_JACKSENSE 178 //Tegra 250 -//.#define JACK_SENSE_GPIO_PIN 178 // Tegra -//#define CODEC_RESET_GPIO_PIN 184 // Tegra - -#define JACK_SENSE_GPIO_PIN 151 //s5pc110 GPH2_5 -#define CODEC_RESET_GPIO_PIN 157 //s5pc110 reset pin. -#define FOR_MID 0 - -#if (defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) ) && !defined(CONFIG_CNXT_USING_SPI_BUS) -#define USING_I2C 1 -#endif - -#if defined(CONFIG_SPI_MASTER) && defined(CONFIG_CNXT_USING_SPI_BUS) -#define USING_SPI 1 -#endif - - -enum Cx_INPUT_SEL{ - Cx_INPUT_SEL_BY_GPIO = 0, - Cx_INPUT_SEL_MIC, - Cx_INPUT_SEL_LINE, - Cx_INPUT_SEL_DPORT2, -}; - -enum Cx_OUTPUT_SEL{ - Cx_OUTPUT_SEL_BY_GPIO = 0, - Cx_OUTPUT_SEL_SPK, - Cx_OUTPUT_SEL_LINE, - Cx_OUTPUT_SEL_HP, - Cx_OUTPUT_SEL_DPORT2, -}; - -enum { - OFF, - RCV, - SPK_PATH, - HP_PATH, - HP_NO_MIC, - BT, - SPK_HP, - RING_SPK, - RING_HP, - RING_HP_NO_MIC, - RING_SPK_HP, -}; - -enum { - MIC_OFF, - Main_Mic, - Hands_Free_Mic, - BT_Sco_Mic, -}; - -#define CX2070X_I2C_DRIVER_NAME "cx2070x-i2c" -#define CX2070X_SPI_DRIVER_NAME "cx2070x-spi" -#define CX2070X_FIRMWARE_FILENAME "cnxt/cx2070x.fw" -#define AUDDRV_VERSION(major0,major1, minor, build ) ((major0)<<24|(major1)<<16| (minor)<<8 |(build)) - -#endif diff --git a/sound/soc/codecs/cxdebug.c b/sound/soc/codecs/cxdebug.c deleted file mode 100644 index 43c4ab41a7b2..000000000000 --- a/sound/soc/codecs/cxdebug.c +++ /dev/null @@ -1,266 +0,0 @@ -/* -* ALSA SoC CX20709 Channel codec driver -* -* Copyright: (C) 2009/2010 Conexant Systems -* -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License version 2 as -* published by the Free Software Foundation. -* -* -* -************************************************************************* -* Modified Date: 12/01/11 -* File Version: 2.26.35.11 -************************************************************************* -*/ - -#include -#include -#include /* Specifically, a module */ -#include -#include /* for get_user and put_user */ -//#include -//#include -//#include -#include -//#include -#include -#include - -//#define DEBUG 1 - -#include "cxdebug.h" - -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) -#include -#endif - -#if defined(CONFIG_SPI_MASTER) -#include -#endif - - -/* -* - * Is the device open right now? Used to prevent - * concurent access into the same device - */ -static int Device_Open = 0; -extern int CX_AUDDRV_VERSION; -struct snd_soc_codec *g_codec = NULL; - -/* - * This is called whenever a process attempts to open the device file - */ -static int cxdbg_dev_open(struct inode *inode, struct file *file) -{ -#ifdef DEBUG - printk(KERN_INFO "cxdbg_dev: device_open(%p)\n", file); -#endif - - /* - * We don't want to talk to two processes at the same time - */ - if (Device_Open) - return -EBUSY; - - Device_Open++; - /* - * Initialize the message - */ - - // try_module_get(THIS_MODULE); - return 0; -} - -/* - * This is called whenever a process attempts to open the device file - */ -static int cxdbg_dev_release(struct inode *inode, struct file *file) -{ -#ifdef DEBUG - printk(KERN_INFO "cxdbg_dev: device_release(%p)\n", file); -#endif - - - Device_Open--; - /* - * Initialize the message - */ - - return 0; -} -static int codec_reg_write(struct CXDBG_IODATA *reg) -{ - int errno = 0; - - BUG_ON(!g_codec); - BUG_ON(!g_codec->hw_write); - - if(g_codec&& g_codec->hw_write) - { - if( g_codec->hw_write(g_codec,(char*)reg->data,reg->len) - !=reg->len) - { - errno =-EIO; - printk(KERN_ERR "cxdbg_dev: codec_reg_write failed\n"); - } - } - else - { - errno = -EBUSY; - printk(KERN_ERR "cxdbg_dev: codec_reg_write failed, device is not ready.\n"); - } - return errno; -} - -static unsigned int codec_reg_read(struct CXDBG_IODATA *reg) -{ - int errno = 0; - unsigned int regaddr; - unsigned int data; - - - BUG_ON(!g_codec); - BUG_ON(!g_codec->hw_read); - - if (reg-> len == 2) - { - regaddr = (((unsigned int)reg->data[0])<<8) + reg->data[1]; - } - else if (reg->len == 1) - { - regaddr = (unsigned int)reg->data[0]; - } - else - { - printk(KERN_ERR "cxdbg_dev: codec_reg_read failed, invalid parameter.\n"); - return -EINVAL; - } - memset(reg,0,sizeof(*reg)); - if(g_codec && g_codec->hw_read) - { - data = g_codec->hw_read(g_codec,regaddr); - reg->data[0] = data & 0xFF; - reg->len = 1; - } - else - { - errno = -EBUSY; - printk(KERN_ERR "cxdbg_dev: codec_reg_read failed, device is not ready.\n"); - } - return errno; - return 0; -} - -long cxdbg_dev_ioctl(struct file * file, unsigned int cmd, unsigned long arg) -{ - struct CXDBG_IODATA *reg=NULL ; - int __user *ip = (int __user*) arg; - long err = -1; -#ifdef DEBUG - printk(KERN_INFO "cxdbg_dev: ioctl, cmd=0x%02x, arg=0x%02lx\n", cmd, arg); -#endif - - /* - * Switch according to the ioctl called - */ - switch (cmd) { - case CXDBG_IOCTL_REG_SET: - reg = (struct CXDBG_IODATA*) kmalloc(sizeof(*reg),GFP_KERNEL); - err = copy_from_user((char*) reg, (char*)arg,sizeof(*reg)); - if(err==0) - { - codec_reg_write(reg); - } - break; - - case CXDBG_IOCTL_REG_GET: - reg = (struct CXDBG_IODATA*) kmalloc(sizeof(*reg),GFP_KERNEL); - err =copy_from_user((char*) reg, (char*)arg,sizeof(*reg)); - if( err == 0) - { - codec_reg_read(reg); - err = copy_to_user((char*) arg, (char*)reg,sizeof(*reg)); - } - break; - case CXDBG_IOCTL_PDRIVER_VERSION: - err = put_user(CX_AUDDRV_VERSION,ip); - break; - default: - err = -EINVAL; - } - - if(reg) - { - kfree(reg); - } - - return err; -} - - -#if defined(_MSC_VER) -static const struct file_operations cxdbg_dev_fops = -{ - /*.owner = */THIS_MODULE, - /*.llseek*/NULL, - /*.read = */NULL, - /*.write*/ NULL, - /*.aio_read*/ NULL, - /*.aio_write*/NULL, - /*readdir*/NULL, - /*.poll*/NULL, - /*ioctl*/ NULL /*i2cdev_ioctl*/, - /*.unlocked_ioctl*/cxdbg_dev_ioctl, - /*.compat_ioctl*/NULL, - /*.mmap*/NULL, - /*.open*/cxdbg_dev_open, - /*.flush*/NULL, - /*.release*/NULL, - /*.fsync*/NULL, - /*.aio_fsync*/NULL, - /*.fasync*/NULL, - /*.lock*/NULL, - /*.sendpage*/NULL, -}; -#else -static const struct file_operations cxdbg_dev_fops = { - .owner = THIS_MODULE, - .unlocked_ioctl = cxdbg_dev_ioctl, - .open = cxdbg_dev_open, - .release = cxdbg_dev_release, -}; -#endif - - -/* -* Initialize the module - Register the character device -*/ -int cxdbg_dev_init(struct snd_soc_codec *socdev) -{ - int err; - printk(KERN_INFO "cxdbg_dev: entries driver\n"); - - g_codec = socdev; - - err = register_chrdev(CXDBG_MAJOR, CXDBG_DEVICE_NAME, &cxdbg_dev_fops); - if (err) - { - printk(KERN_ERR "cxdbg_dev: Driver Initialisation failed\n"); - } - return err; -} - -void cxdbg_dev_exit(void) -{ - unregister_chrdev(CXDBG_MAJOR,CXDBG_DEVICE_NAME); -} - - -MODULE_AUTHOR("Simon Ho // For _MAX_PATH definition -#include -#include -#define msleep(_x_) -int printk(const char *s, ...); -#define KERN_ERR "<3>" -#elif defined(__KERNEL__) -// linux kernel environment. -#include -#include -#include -#include -#else -// -// linux user mode environment. -// -#include // For _MAX_PATH definition -#include -#endif -#include "cxpump.h" - -#if defined( __BIG_ENDIAN) && !defined(__BYTE_ORDER) -#define __BYTE_ORDER __BIG_ENDIAN -#elif defined( __LITTLE_ENDIAN ) && !defined(__BYTE_ORDER) -#define __BYTE_ORDER __LITTLE_ENDIAN -#endif - - -#ifndef __BYTE_ORDER -#error __BYTE_ORDER is undefined. -#endif - -#define ENABLE_I2C_BURST_MODE - -#if defined(_MSC_VER) -#pragma warning(disable:4127 4706 4101) // conditional experssion is constant -typedef enum I2C_STATE{I2C_OK,I2C_ERR,I2C_RETRY} ; -void ShowProgress(int curPos,bool bForceRedraw, I2C_STATE eState, const int MaxPos); -void InitShowProgress(const int MaxPos); -#elif defined(__KERNEL__) -//linux kernel mode -#define ShowProgress(curPos,bForceRedraw,eState, axPos) -#define InitShowProgress(MaxPos) -#else -//linux user mode -#define InitShowProgress(MaxPos) -#define ShowProgress(curPos,bForceRedraw,eState, axPos) -#endif - - -#ifndef NULL -#define NULL 0 -#endif //#ifndef NULL - -#define S_DESC "Cnxt Channel Firmware" /*Specify the string that will show on head of rom file*/ -#define S_ROM_FILE_NAME "cx2070x.fw" /*Specify the file name of rom file*/ -#define CHIP_ADDR 0x14 /*Specify the i2c chip address*/ -#define MEMORY_UPDATE_TIMEOUT 300 -#define MAX_ROM_SIZE (1024*1024) -//#define DBG_ERROR "ERROR : " -#define DBG_ERROR KERN_ERR -#define LOG( _msg_ ) printk _msg_ -//#define LOG( _msg_ ) ; - -typedef struct CX_CODEC_ROM_DATA -{ -#ifdef USE_TYPE_DEFINE - unsigned long Type; -#endif //#ifdef USE_TYPE_DEFINE - unsigned long Length; - unsigned long Address; - unsigned char data[1]; -}CX_CODEC_ROM_DATA; - -#define ROM_DATA_TYPE_S37 0xAA55CC01 // S37 format. -#define ROM_DATA_TYPE_CNXT 0xAA55CC04 // Conexant SPI format. -#define ROM_DATA_SEPARATED_LINE 0x23232323 //()()()() - -typedef struct CX_CODEC_ROM{ - char sDesc[24]; - char cOpenBracket; - char sVersion[5]; - char cCloseBracket; - char cEOF; - unsigned long FileSize; - unsigned long LoaderAddr; - unsigned long LoaderLen; - unsigned long CtlAddr; - unsigned long CtlLen; - unsigned long SpxAddr; - unsigned long SpxLen; - struct CX_CODEC_ROM_DATA Data[1]; -}CX_CODEC_ROM; - -typedef struct CX_CODEC_APPENDED_DATA -{ - unsigned char Address[2]; // The address of data. - unsigned char padding; // The actual firmware data. - unsigned char data; // The actual firmware data. -}CX_CODEC_APPENDED_DATA; - -typedef struct CX_CODEC_ROM_APPENDED{ - unsigned long TuningAddr; - unsigned long TuningLen; - CX_CODEC_APPENDED_DATA data[1]; // following by Jira id and time. -}CX_CODEC_ROM_APPENDED; - -typedef struct CX_CODEC_ROM_APPENDED_INFO{ - char sJIRAID[16]; - char sTime[16]; -}CX_CODEC_ROM_APPENDED_INFO; - - -// To convert two digital ASCII into one BYTE. -unsigned char ASCII_2_BYTE( char ah, char al) ; - -#define BUF_SIZE 0x1000 -#define BIBF(_x_) if(!(_x_)) break; -#define BIF(_x_) if((ErrNo=(_x_)) !=0) break; - - -#ifndef BIBF -#define BIBF( _x_ ) if(!(_x_)) break; -#endif - -enum { - MEM_TYPE_RAM = 1 /* CTL*/, - MEM_TYPE_SPX = 2, - MEM_TYPE_EEPROM = 3, - MEM_TYPE_CPX =0x04, - MEM_TYPE_EEPROM_RESET = 0x8003, //reset after writing. -}; - - -fun_I2cWriteThenRead g_I2cWriteThenReadPtr = NULL; -fun_I2cWrite g_I2cWritePtr = NULL; -unsigned char * g_AllocatedBuffer = NULL; -unsigned char * g_Buffer = NULL; -unsigned long g_cbMaxWriteBufSize = 0; -void * g_pContextI2cWrite = NULL; -void * g_pContextI2cWriteThenRead = NULL; - - -/* -* The SetupI2cWriteCallback sets the I2cWrite callback function. -* -* PARAMETERS -* -* pCallbackContext [in] - A pointer to a caller-defined structure of data items -* to be passed as the context parameter of the callback -* routine each time it is called. -* -* I2cWritePtr [in] - A pointer to a i2cwirte callback routine, which is to -* write I2C data. The callback routine must conform to -* the following prototype: -* -* int (*fun_I2cWrite)( -* void * pCallbackContext, -* unsigned char ChipAddr, -* unsigned long cbBuf, -* unsigned char* pBuf -* ); -* -* The callback routine parameters are as follows: -* -* pCallbackContext [in] - A pointer to a caller-supplied -* context area as specified in the -* CallbackContext parameter of -* SetupI2cWriteCallback. -* ChipAddr [in] - The i2c chip address. -* cbBuf [in] - The size of the input buffer, in bytes. -* pBuf [in] - A pointer to the input buffer that contains -* the data required to perform the operation. -* -* -* cbMaxWriteBuf [in] - Specify the maximux transfer size for a I2c continue -* writing with 'STOP'. This is limited in I2C bus Master -* device. The size can not less then 3 since Channel -* requires 2 address bytes plus a data byte. -* -* -* -* RETURN -* -* None -* -*/ -void SetupI2cWriteCallback( void * pCallbackContext, - fun_I2cWrite I2cWritePtr, - unsigned long cbMaxWriteBufSize) -{ - g_pContextI2cWrite = pCallbackContext; - g_I2cWritePtr = I2cWritePtr; - g_cbMaxWriteBufSize = cbMaxWriteBufSize; -} - -/* -* The SetupI2cWriteThenReadCallback sets the SetupI2cWriteThenRead callback function. -* -* PARAMETERS -* -* pCallbackContext [in] - A pointer to a caller-defined structure of data items -* to be passed as the context parameter of the callback -* routine each time it is called. -* -* I2cWriteThenReadPtr [in] - A pointer to a i2cwirte callback routine, which is to -* write I2C data. The callback routine must conform to -* the following prototype: -* -* int (*fun_I2cWriteThenRead)( -* void * pCallbackContext, -* unsigned char ChipAddr, -* unsigned long cbBuf, -* unsigned char* pBuf -* ); -* -* The callback routine parameters are as follows: -* -* pCallbackContext [in] - A pointer to a caller-supplied -* context area as specified in the -* CallbackContext parameter of -* SetupI2cWriteCallback. -* ChipAddr [in] - The i2c chip address. -* cbBuf [in] - The size of the input buffer, in bytes. -* pBuf [in] - A pointer to the input buffer that contains -* the data required to perform the operation. -* -* RETURN -* None -* -*/ -void SetupI2cWriteThenReadCallback( void * pCallbackContext, - fun_I2cWriteThenRead I2cWriteThenReadPtr) -{ - g_pContextI2cWriteThenRead = pCallbackContext; - g_I2cWriteThenReadPtr = I2cWriteThenReadPtr; -} - -void SetupMemoryBuffer(void * pAllocedMemoryBuffer) -{ - g_AllocatedBuffer = (unsigned char*)pAllocedMemoryBuffer; - g_Buffer = g_AllocatedBuffer +2; -} - -/* -* Convert a 4-byte number from a ByteOrder into another ByteOrder. -*/ -unsigned long ByteOrderSwapULONG(unsigned long i) -{ - return((i&0xff)<<24)+((i&0xff00)<<8)+((i&0xff0000)>>8)+((i>>24)&0xff); -} - -/* -* Convert a 2-byte number from a ByteOrder into another ByteOrder. -*/ -unsigned short ByteOrderSwapWORD(unsigned short i) -{ - return ((i>>8)&0xff)+((i << 8)&0xff00); -} - -/* -* Convert a 4-byte number from generic byte order into Big Endia -*/ -unsigned long ToBigEndiaULONG(unsigned long i) -{ -#if __BYTE_ORDER == __LITTLE_ENDIAN - return ByteOrderSwapULONG(i); -#else - return i; -#endif -} - - -/* -* Convert a 2-byte number from generic byte order into Big Endia -*/ -unsigned short ToBigEndiaWORD(unsigned short i) -{ -#if __BYTE_ORDER == __LITTLE_ENDIAN - return ByteOrderSwapWORD(i); -#else - return i; -#endif -} - -/* -* Convert a 4-byte number from Big Endia into generic byte order. -*/ -unsigned long FromBigEndiaULONG(unsigned long i) -{ -#if __BYTE_ORDER == __LITTLE_ENDIAN - return ByteOrderSwapULONG(i); -#else - return i; -#endif -} - - -/* -* Convert a 2-byte number from Big Endia into generic byte order. -*/ -unsigned short FromBigEndiaWORD(unsigned short i) -{ -#if __BYTE_ORDER == __LITTLE_ENDIAN - return ByteOrderSwapWORD(i); -#else - return i; -#endif -} - - -/* -* To convert two digital ASCII into one BYTE. -*/ -unsigned char ASCII_2_BYTE( char ah, char al) -{ - unsigned char ret = '\0'; - int i =2; - - for(;i>0;i--) - { - if( 'a' <= ah && 'f' >= ah) - { - ret += ah - 'a'+10; - } - else if( 'A' <= ah && 'F' >= ah) - { - ret += ah -'A'+10; - } - - else if( '0' <= ah && '9' >= ah) - { - ret += ah - '0'; - } - else - { - LOG((DBG_ERROR "Invalid txt data.\n")); - - // ErrNo = ERRNO_INVALID_DATA; - break; - } - ah =al; - if(i==2) - ret = (unsigned short)ret << 4; - } - return ret; -} - -/* -* Read a byte from the specified register address. -* -* PARAMETERS -* -* RegAddr [in] - Specifies the register address. -* -* RETURN -* -* Returns the byte that is read from the specified register address. -* -*/ -unsigned char ReadReg(unsigned short RegAddr) -{ - - unsigned char RegData; - - if(!g_I2cWriteThenReadPtr) - { - LOG((DBG_ERROR "i2C function is not set.\n")); - return 0; - } - - - RegAddr = ToBigEndiaWORD(RegAddr); - - g_I2cWriteThenReadPtr(g_pContextI2cWriteThenRead,CHIP_ADDR, - 2,(unsigned char*) &RegAddr,1,&RegData); - - return RegData; -} - - -/* -* Write a byte from the specified register address. -* -* PARAMETERS -* -* RegAddr [in] - Specifies the register address. -* -* RETURN -* -* Returns the byte that is read from the specified register address. -* -* REMARK -* -* The g_I2cWriteThenReadPtr must be set before calling this function. -*/ -int WriteReg(unsigned short RegAddr, unsigned char RegData) -{ - unsigned char WrBuf[3]; - - if(!g_I2cWritePtr) - { - LOG((DBG_ERROR "i2C function is not set.\n")); - return -ERRNO_I2CFUN_NOT_SET; - } - - *((unsigned short*) WrBuf) = ToBigEndiaWORD(RegAddr); - WrBuf[2] = RegData; - - g_I2cWritePtr(g_pContextI2cWrite,CHIP_ADDR,sizeof(WrBuf),WrBuf); - - return ERRNO_NOERR; -} - -/* -* Writes a number of bytes from a buffer to Channel via I2C bus. -* -* PARAMETERS -* -* NumOfBytes [in] - Specifies the number of bytes to be written -* to the memory address. -* pData [in] - Pointer to a buffer from an array of I2C data -* are to be written. -* -* RETURN -* -* If the operation completes successfully, the return value is ERRNO_NOERR. -* Otherwise, return ERRON_* error code. -*/ -int ChannelI2cBulkWrite( unsigned long NumOfBytes, unsigned char *pData) -{ - int ErrNo = ERRNO_NOERR; - unsigned short CurAddr; - - //unsigned char *pDataEnd = pData + NumOfBytes; - unsigned char *pCurData = pData; - unsigned short *pCurAddrByte = NULL; - unsigned long BytesToProcess = 0; - unsigned short backup = 0; - const unsigned long cbAddressBytes = 2; - const unsigned long cbMaxDataLen = g_cbMaxWriteBufSize-cbAddressBytes; - - - if(!g_I2cWritePtr ) - { - LOG((DBG_ERROR "i2C function is not set.\n")); - return -ERRNO_I2CFUN_NOT_SET; - } - - //assert(NumOfBytes < 3); - CurAddr = FromBigEndiaWORD( *((unsigned short*)pData)); - - //skip first 2 bytes data (address). - NumOfBytes -= cbAddressBytes; - pCurData += cbAddressBytes; - - for(;NumOfBytes;) - { - BytesToProcess = NumOfBytes > cbMaxDataLen? cbMaxDataLen : NumOfBytes; - NumOfBytes-= BytesToProcess; - // save the pervious 2 bytes for later use. - pCurAddrByte = (unsigned short*) (pCurData -cbAddressBytes); - backup = *pCurAddrByte; - *pCurAddrByte= ToBigEndiaWORD(CurAddr); - BIBF(g_I2cWritePtr(g_pContextI2cWrite,CHIP_ADDR, BytesToProcess + cbAddressBytes,(unsigned char*)pCurAddrByte)); - //restore the data - *pCurAddrByte = backup; - - pCurData += BytesToProcess; - CurAddr += (unsigned short)BytesToProcess; - } - return ErrNo; -} - -/* -* Writes a number of bytes from a buffer to the specified memory address. -* -* PARAMETERS -* -* dwAddr [in] - Specifies the memory address. -* NumOfBytes [in] - Specifies the number of bytes to be written -* to the memory address. -* pData [in] - Pointer to a buffer from an struct of -* CX_CODEC_ROM_DATA is to be written. -* MemType [in] - Specifies the requested memory type, the value must be from -* the following table. -* -* MEM_TYPE_RAM = 1 -* MEM_TYPE_SPX = 2 -* MEM_TYPE_EEPROM = 3 -* -* RETURN -* -* If the operation completes successfully, the return value is ERRNO_NOERR. -* Otherwise, return ERRON_* error code. -*/ -int CxWriteMemory(unsigned long dwAddr, unsigned long NumOfBytes, unsigned char * pData, int MemType ) -{ - int ErrNo = ERRNO_NOERR; - unsigned char Address[4]; - unsigned char WrData[8]; - unsigned char offset = 0; - const unsigned long MAX_BUF_LEN = 0x100; - unsigned char cr = 0; - int bNeedToContinue = 0; - int i=0; - - - const unsigned long cbAddressBytes = 2; - - unsigned short * pAddressByte; - unsigned char *pEndData = pData + NumOfBytes; - unsigned short RegMemMapAddr = ToBigEndiaWORD(0x300); - unsigned long BytesToProcess = 0; - - while(NumOfBytes) - { - - BytesToProcess = NumOfBytes <= MAX_BUF_LEN ? NumOfBytes : MAX_BUF_LEN; - NumOfBytes -= BytesToProcess; - pEndData = pData + BytesToProcess; - - *((unsigned long*)&Address) = ToBigEndiaULONG(dwAddr); - // dwAddr += offset; - offset = 0; - - if( !bNeedToContinue ) - { -#ifdef ENABLE_I2C_BURST_MODE - // - // Update the memory target address and buffer length. - // - WrData[0] = 0x02; //update target address Low 0x02FC - WrData[1] = 0xFC; - WrData[2] = Address[3]; - WrData[3] = Address[2]; - WrData[4] = Address[1]; - WrData[5] = (unsigned char)BytesToProcess -1 ; // X bytes - 1 - BIBF(g_I2cWritePtr(g_pContextI2cWrite,CHIP_ADDR, 6 , WrData)); -#else - // - // Update the memory target address and buffer length. - // - WrData[0] = 0x02; //update target address Low 0x02FC - WrData[1] = 0xFC; - WrData[2] = Address[3]; - BIBF(g_I2cWritePtr(g_pContextI2cWrite,CHIP_ADDR, 3 , WrData)); - - WrData[0] = 0x02; //update target address Middle 0x02FD - WrData[1] = 0xFD; - WrData[2] = Address[2]; - BIBF(g_I2cWritePtr(g_pContextI2cWrite,CHIP_ADDR, 3 , WrData)); - - WrData[0] = 0x02; //update target address High 0x02FE - WrData[1] = 0xFE; - WrData[2] = Address[1]; - BIBF(g_I2cWritePtr(g_pContextI2cWrite,CHIP_ADDR, 3 , WrData)); - - WrData[0] = 0x02; //update Buffer Length. 0x02FF - WrData[1] = 0xFF; - WrData[2] = (unsigned char)BytesToProcess -1 ; // X bytes - 1 - BIBF(g_I2cWritePtr(g_pContextI2cWrite,CHIP_ADDR, 3 , WrData)); -#endif - } - - // - // Update buffer. - // -#ifdef ENABLE_I2C_BURST_MODE - pAddressByte = (unsigned short*) (pData - cbAddressBytes); - memcpy(g_Buffer, pAddressByte, BytesToProcess+cbAddressBytes); - *((unsigned short*)g_Buffer) = RegMemMapAddr; - ChannelI2cBulkWrite(BytesToProcess+cbAddressBytes, (unsigned char*)g_Buffer); - pData = pEndData; -#else - for(offset=0;pData != pEndData;offset++,pData++) - { - WrData[0] = 0x03; //update Buffer [0x0300 - 0x03ff] - WrData[1] = (unsigned char) offset; - WrData[2] = *pData; - BIBF(g_I2cWritePtr(g_pContextI2cWrite,CHIP_ADDR, 3 , WrData)); - } -#endif - - // - // Commit the changes and start to transfer buffer to memory. - // - if( MemType == MEM_TYPE_RAM) - { - cr = 0x81; - } - else if( MemType == MEM_TYPE_EEPROM) - { - cr = 0x83; - } - else if( MemType == MEM_TYPE_SPX) - { - cr = 0x85; - if( bNeedToContinue ) - { - cr |= 0x08; - } - } - - WrData[0] = 0x04; // UpdateCtl [0x400] - WrData[1] = 0x00; - WrData[2] = cr; // start to transfer - BIBF(g_I2cWritePtr(g_pContextI2cWrite,CHIP_ADDR, 3 , WrData)); - - for(i = 0;i= 1) - { - printk( KERN_ERR "write pending loop =%d\n", i); - } - - bNeedToContinue = 1; - }while(0); - - return ErrNo ; -} - -#define WAIT_UNTIL_DEVICE_READY(_x_,_msg_) \ -for (timeout=0;timeoutsDesc,sizeof(CHAN_PATH)-1)) { - printk(KERN_INFO "[CNXT] sDesc = %s", pRom->sDesc); - bIsRomVersion = 1; - } - - if (bIsRomVersion) { - WAIT_UNTIL_DEVICE_READY(== 0X01,"cx2070x: Timed out waiting for codecto be ready!\n"); - } else { - //Check if there is a FIRMWARE present. the Channel should get - // a clear reset signal before we download firmware to it. - if( (ReadReg(0x009) & 0x04) == 0) { - LOG((DBG_ERROR "cx2070x: did not get a clear reset..!")); - ErrNo = -ERRNO_DEVICE_NOT_RESET; - break; - } - } - - TotalLen = FromBigEndiaULONG(pRom->LoaderLen) + FromBigEndiaULONG(pRom->CtlLen) + FromBigEndiaULONG(pRom->SpxLen); - // InitShowProgress(TotalLen); - - //Download the loader. - pRomData = (struct CX_CODEC_ROM_DATA *) ( (char*)pRom + FromBigEndiaULONG(pRom->LoaderAddr)); - pRomDataEnd = (struct CX_CODEC_ROM_DATA *) ((char*)pRomData +FromBigEndiaULONG(pRom->LoaderLen)); - - for( ;pRomData!=pRomDataEnd;) - { -#ifdef ENABLE_I2C_BURST_MODE - pData = &pRomData->data[0]; - pDataEnd= pData + FromBigEndiaULONG(pRomData->Length) - sizeof(unsigned long); - memcpy(g_Buffer, pData-2, FromBigEndiaULONG(pRomData->Length) - sizeof(unsigned short)); - BIF(ChannelI2cBulkWrite( FromBigEndiaULONG(pRomData->Length) - sizeof(unsigned short), g_Buffer)); - curProgress += FromBigEndiaULONG(pRomData->Length) ; - ShowProgress(curProgress,false, I2C_OK,TotalLen); - - pRomData = (struct CX_CODEC_ROM_DATA *)pDataEnd; - -#else - CurAddr = FromBigEndiaULONG(pRomData->Address); - pData = &pRomData->data[0]; - pDataEnd= pData + FromBigEndiaULONG(pRomData->Length) - sizeof(unsigned long); - for( ;pData!=pDataEnd;pData++) - { - *((unsigned short*)writeBuf) = ToBigEndiaWORD((unsigned short)CurAddr); - writeBuf[2]= *pData; - g_I2cWritePtr(g_pContextI2cWrite,CHIP_ADDR,3, writeBuf); - CurAddr++; - } - pRomData = (struct CX_CODEC_ROM_DATA *)pData; -#endif - - } - - //* check if the device is ready. - if (bIsRomVersion) { - WAIT_UNTIL_DEVICE_READY(== 0X01,"cx2070x: Timed out waiting for cx2070x to be ready after loader downloaded!\n"); - } else { - WAIT_UNTIL_DEVICE_READY(!= 0xFF,"cx2070x: Timed out waiting for cx2070x to be ready after loader downloaded!\n"); - } - - //Download the CTL - pRomData = (struct CX_CODEC_ROM_DATA *) ( (char*)pRom + FromBigEndiaULONG(pRom->CtlAddr )); - pRomDataEnd = (struct CX_CODEC_ROM_DATA *) ((char*)pRomData +FromBigEndiaULONG(pRom->CtlLen)); - - for( ;pRomData!=pRomDataEnd;) - { - CurAddr = FromBigEndiaULONG(pRomData->Address); - pData = &pRomData->data[0]; - cbDataLen = FromBigEndiaULONG(pRomData->Length) ; - BIF(CxWriteMemory(CurAddr,cbDataLen -sizeof(unsigned long)/*subtracts the address bytes*/ , pData, MEM_TYPE_RAM )); - // The next RoMData position = current romData position + cbDataLen + sizeof( data len bytes) - pRomData = (struct CX_CODEC_ROM_DATA *)((char*) pRomData + cbDataLen + sizeof(unsigned long)); - - curProgress += cbDataLen ; - ShowProgress(curProgress,false, I2C_OK,TotalLen); - } - - pRomData = (struct CX_CODEC_ROM_DATA *) ( (char*)pRom + FromBigEndiaULONG(pRom->SpxAddr )); - pRomDataEnd = (struct CX_CODEC_ROM_DATA *) ((char*)pRomData +FromBigEndiaULONG(pRom->SpxLen)); - - for( ;pRomData!=pRomDataEnd;) - { - CurAddr = FromBigEndiaULONG(pRomData->Address); - pData = &pRomData->data[0]; - cbDataLen = FromBigEndiaULONG(pRomData->Length) ; - BIF(CxWriteMemory(CurAddr,cbDataLen -sizeof(unsigned long)/*subtracts the address bytes*/ , pData, MEM_TYPE_SPX )); - // The next RoMData position = current romData position + cbDataLen + sizeof( data len bytes) - pRomData = (struct CX_CODEC_ROM_DATA *)((char*) pRomData + cbDataLen + sizeof(unsigned long)); - - curProgress += cbDataLen ; - ShowProgress(curProgress,false, I2C_OK,TotalLen); - } - - if(ErrNo != 0) break; - - ShowProgress(TotalLen,false, I2C_OK,TotalLen); - - // - // Reset - // - if(bIsRomVersion) - { - WriteReg(0x1000,0x00); - // msleep(400); //delay 400 ms - } - else - { - WriteReg(0x400,0x40); - msleep(400); //delay 400 ms - } - - WAIT_UNTIL_DEVICE_READY(== 0x01,"cx2070x: Timed out waiting for cx2070x to be ready after firmware downloaded!\n"); - - //check if XPS code is working or not. - - WriteReg(0x117d,0x01); - for (timeout=0;timeout>16), - (unsigned char)(fwVer>>8), - (unsigned char)fwVer, - (unsigned char)(fwPatchVer>>16), - (unsigned char)(fwPatchVer>>8), - (unsigned char)fwPatchVer); - } - else - { - printk(KERN_INFO "cx2070x: firmware download successfully! FW: %u,%u,%u\n", - (unsigned char)(fwVer>>16), - (unsigned char)(fwVer>>8), - (unsigned char)fwVer); - } - - }while(0); - - return ErrNo; -} - -int ApplyDSPChanges(const unsigned char *const pRom) -{ - int ErrNo = ERRNO_NOERR; - struct CX_CODEC_ROM* pNewRom ; - struct CX_CODEC_ROM_APPENDED *pRomAppended; - struct CX_CODEC_ROM_APPENDED_INFO *pInfo; - struct CX_CODEC_APPENDED_DATA *pData; - struct CX_CODEC_APPENDED_DATA *pDataEnd; - unsigned short wRegAddr; - unsigned char NewC; - -#define DESC_LEN (16) - char szJira[DESC_LEN+1]; - char szDate[DESC_LEN+1]; - - pNewRom = (struct CX_CODEC_ROM*) pRom; - - // check if firmware contains DSP tuning data. - if( (FromBigEndiaULONG(pNewRom->SpxLen) + FromBigEndiaULONG(pNewRom->SpxAddr)) != FromBigEndiaULONG(pNewRom->FileSize) ) - { - // has DSP Tuning data. - - pRomAppended = (struct CX_CODEC_ROM_APPENDED*)((char*)pNewRom + FromBigEndiaULONG(pNewRom->SpxAddr) + FromBigEndiaULONG(pNewRom->SpxLen)); - pInfo = (struct CX_CODEC_ROM_APPENDED_INFO*) ((char*)pNewRom + FromBigEndiaULONG(pRomAppended ->TuningAddr) + - FromBigEndiaULONG(pRomAppended ->TuningLen)); - - strncpy(szJira,pInfo->sJIRAID,DESC_LEN); - strncpy(szDate,pInfo->sTime,DESC_LEN); - szJira[DESC_LEN]=0; - szDate[DESC_LEN-1]=0; //remove the last lettle $. - printk(KERN_INFO "Applying the DSP tuning changes..Jira: %s Date: %s\n" - ,szJira,szDate); - - pData = pRomAppended->data; - pDataEnd = (struct CX_CODEC_APPENDED_DATA*)((char*)pData + FromBigEndiaULONG(pRomAppended->TuningLen)); - for(;pData != pDataEnd; pData++) - { - wRegAddr = pData->Address[0]; - wRegAddr <<=8; - wRegAddr |= pData->Address[1]; - WriteReg(wRegAddr,pData->data); - //printk(KERN_INFO "0X%04x=0x%02x\n",wRegAddr,pData->data); - } - // re-set NewC. - NewC = ReadReg(0x117d); - WriteReg(0x117d,NewC|1); - } - - return ErrNo; -} - diff --git a/sound/soc/codecs/cxpump.h b/sound/soc/codecs/cxpump.h deleted file mode 100644 index 10766aa9af70..000000000000 --- a/sound/soc/codecs/cxpump.h +++ /dev/null @@ -1,207 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/**************************************************************************************** -***************************************************************************************** -*** *** -*** Copyright (c) 2011 *** -*** *** -*** Conexant Systems, Inc. *** -*** *** -*** All Rights Reserved *** -*** *** -*** CONFIDENTIAL *** -*** *** -*** NO DISSEMINATION OR USE WITHOUT PRIOR WRITTEN PERMISSION *** -*** *** -***************************************************************************************** -** -** File Name: -** pump.c -** -** Abstract: -** This code is to download the firmware to CX20709 device via I2C bus. -** -** -** Product Name: -** Conexant Channel CX20709 -** -** Remark: -** -** -** -******************************************************************************** -** Revision History -** Date Description Author -** 01/21/11 Created. Simon Ho -** 01/24/11 Speed up the firmware download by sending Simon Ho -** I2C data continually without addressing -******************************************************************************** -*****************************************************************************************/ -#ifdef __cplusplus -extern "C"{ -#endif - - -typedef int (*fun_I2cWriteThenRead)( void * pCallbackContext, - unsigned char ChipAddr, - unsigned long cbBuf, - unsigned char* pBuf, - unsigned long cbReadBuf, - unsigned char*pReadBuf); - -typedef int (*fun_I2cWrite)( void * pCallbackContext, - unsigned char ChipAddr, - unsigned long cbBuf, - unsigned char* pBuf); - -/* - * Set the I2cWrite callback function. - * - * PARAMETERS - * - * pCallbackContext [in] - A pointer to a caller-defined structure of data items - * to be passed as the context parameter of the callback - * routine each time it is called. - * - * I2cWritePtr [in] - A pointer to a i2cwirte callback routine, which is to - * write I2C data. The callback routine must conform to - * the following prototype: - * - * int (*fun_I2cWrite)( - * void * pCallbackContext, - * unsigned char ChipAddr, - * unsigned long cbBuf, - * unsigned char* pBuf - * ); - * - * The callback routine parameters are as follows: - * - * pCallbackContext [in] - A pointer to a caller-supplied - * context area as specified in the - * CallbackContext parameter of - * SetupI2cWriteCallback. - * ChipAddr [in] - The i2c chip address. - * cbBuf [in] - The size of the input buffer, in bytes. - * pBuf [in] - A pointer to the input buffer that contains - * the data required to perform the operation. - * - * - * cbMaxWriteBufSize [in] - Specify the maximux transfer size for a I2c continue - * writing with 'STOP'. This is limited in I2C bus Master - * device. The size can not less then 3 since Channel - * requires 2 address bytes plus a data byte. - * - * - * - * RETURN - * None - * - */ -void SetupI2cWriteCallback( void * pCallbackContext, - fun_I2cWrite I2cWritePtr, - unsigned long cbMaxWriteBufSize); - - -/* - * Set the SetupI2cWriteThenRead callback function. - * - * PARAMETERS - * - * pCallbackContext [in] - A pointer to a caller-defined structure of data items - * to be passed as the context parameter of the callback - * routine each time it is called. - * - * I2cWriteThenReadPtr [in] - A pointer to a i2cwirte callback routine, which is to - * write I2C data. The callback routine must conform to - * the following prototype: - * - * int (*fun_I2cWriteThenRead)( - * void * pCallbackContext, - * unsigned char ChipAddr, - * unsigned long cbBuf, - * unsigned char* pBuf - * ); - * - * The callback routine parameters are as follows: - * - * pCallbackContext [in] - A pointer to a caller-supplied - * context area as specified in the - * CallbackContext parameter of - * SetupI2cWriteCallback. - * ChipAddr [in] - The i2c chip address. - * cbBuf [in] - The size of the input buffer, in bytes. - * pBuf [in] - A pointer to the input buffer that contains - * the data required to perform the operation. - * - * RETURN - * - * If the operation completes successfully, the return value is ERRNO_NOERR. - * Otherwise, return ERRON_* error code. - * - */ -void SetupI2cWriteThenReadCallback( void * pCallbackContext, - fun_I2cWriteThenRead I2cWriteThenReadPtr); - - -void SetupMemoryBuffer(void * pAllocedMemoryBuffer); - - -/* - * Download Firmware to Channel. - * - * PARAMETERS - * - * pRomData [in] - A pointer fo the input buffer that contains rom data. - * - * RETURN - * - * If the operation completes successfully, the return value is ERRNO_NOERR. - * Otherwise, return ERRON_* error code. - * - * REMARKS - * - * You need to set up both I2cWrite and I2cWriteThenRead callback function by calling - * SetupI2cWriteCallback and SetupI2cWriteThenReadCallback before you call this function. - */ -int DownloadFW(const unsigned char *const pRomData); - -/* - * Apply the extra DSP changes from FW file. - * - * PARAMETERS - * - * pRomData [in] - A pointer fo the input buffer that contains rom data. - * - * RETURN - * - * If the operation completes successfully, the return value is ERRNO_NOERR. - * Otherwise, return ERRON_* error code. - * - * REMARKS - * - * You need to set up both I2C/SPI Write and I2C/SPI WriteThenRead callback function - * by calling SetupI2cSpiWriteCallback and SetupI2cSpiWriteThenReadCallback before you call - * this function. - */ -int ApplyDSPChanges(const unsigned char *const pRom); - -#ifdef __cplusplus -} -#endif - - -/*Error codes*/ -#define ERRNO_NOERR 0 -#define ERRNO_SRC_FILE_NOT_EXIST 101 -#define ERRNO_WRITE_FILE_FAILED 102 -#define ERRNO_INVALID_DATA 103 -#define ERRNO_CHECKSUM_FAILED 104 -#define ERRNO_FAILED 105 -#define ERRNO_INVALID_PARAMETER 106 -#define ERRNO_NOMEM 107 -#define ERRNO_I2CFUN_NOT_SET 108 -#define ERRNO_UPDATE_MEMORY_FAILED 109 -#define ERRNO_DEVICE_NOT_RESET 110 -#define ERRNO_DEVICE_OUT_OF_CONTROL 111 -#define ERRNO_DEVICE_DSP_LOCKUP 112 - - diff --git a/sound/soc/codecs/dw-hdmi-audio.c b/sound/soc/codecs/dw-hdmi-audio.c deleted file mode 100644 index 33cd801ecd72..000000000000 --- a/sound/soc/codecs/dw-hdmi-audio.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * dw-hdmi-audio.c - * - * DesignerWare ALSA SoC Codec driver for DW HDMI audio. - * Copyright (c) 2016 Fuzhou Rockchip Electronics Co., Ltd - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see .* - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include "../../../drivers/video/rockchip/hdmi/rockchip-hdmi.h" - -static int snd_dw_hdmi_dai_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *codec_dai) -{ - return snd_config_hdmi_audio(params); -} - -static const struct snd_soc_dapm_widget snd_dw_hdmi_audio_widgets[] = { - SND_SOC_DAPM_OUTPUT("TX"), -}; - -static const struct snd_soc_dapm_route snd_dw_hdmi_audio_routes[] = { - { "TX", NULL, "Playback" }, -}; - -static const struct snd_soc_dai_ops dw_hdmi_dai_ops = { - .hw_params = snd_dw_hdmi_dai_hw_params, -}; - -static struct snd_soc_dai_driver dw_hdmi_audio_dai = { - .name = "dw-hdmi-hifi", - .playback = { - .stream_name = "Playback", - .channels_min = 2, - .channels_max = 8, - .rates = SNDRV_PCM_RATE_32000 | - SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | - SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | - SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000, - .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, - }, - .ops = &dw_hdmi_dai_ops, -}; - -static const struct snd_soc_codec_driver dw_hdmi_audio = { - .dapm_widgets = snd_dw_hdmi_audio_widgets, - .num_dapm_widgets = ARRAY_SIZE(snd_dw_hdmi_audio_widgets), - .dapm_routes = snd_dw_hdmi_audio_routes, - .num_dapm_routes = ARRAY_SIZE(snd_dw_hdmi_audio_routes), -}; - -static int dw_hdmi_audio_probe(struct platform_device *pdev) -{ - int ret; - - ret = snd_soc_register_codec(&pdev->dev, &dw_hdmi_audio, - &dw_hdmi_audio_dai, 1); - if (ret) - dev_err(&pdev->dev, "register codec failed (%d)\n", ret); - - return ret; -} - -static int dw_hdmi_audio_remove(struct platform_device *pdev) -{ - snd_soc_unregister_codec(&pdev->dev); - - return 0; -} - -static const struct of_device_id dw_hdmi_audio_ids[] = { - { .compatible = "dw-hdmi-audio", }, - { } -}; - -static struct platform_driver dw_hdmi_audio_driver = { - .driver = { - .name = "dw-hdmi-audio", - .of_match_table = of_match_ptr(dw_hdmi_audio_ids), - }, - .probe = dw_hdmi_audio_probe, - .remove = dw_hdmi_audio_remove, -}; -module_platform_driver(dw_hdmi_audio_driver); - -MODULE_AUTHOR("Sugar Zhang "); -MODULE_DESCRIPTION("DW HDMI Audio ASoC Interface"); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/es8323_pcm.c b/sound/soc/codecs/es8323_pcm.c deleted file mode 100755 index 8000d51c4206..000000000000 --- a/sound/soc/codecs/es8323_pcm.c +++ /dev/null @@ -1,366 +0,0 @@ -/* - * es8323.c -- es8323 ALSA SoC audio driver - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "es8323.h" - -//#define ES8323_PROC -#ifdef ES8323_PROC -#include -#include -#include -#endif - -#if 1 -#define DBG(x...) printk(KERN_INFO x) -#else -#define DBG(x...) -#endif - -enum { - OFF, - RCV, - SPK_PATH, - HP_PATH, - HP_NO_MIC, - BT, -}; - -static struct i2c_client *i2c_client; -int es8323_codec_state = OFF; - -static int codec_write(struct i2c_client *client, unsigned int reg, - unsigned int value) -{ - u8 data[2]; - - data[0] = reg; - data[1] = value & 0x00ff; - - //printk("%s: reg=0x%x value=0x%x\n",__func__,reg,value); - if (i2c_master_send(client, data, 2) == 2) - return 0; - else - return -EIO; -} - -static unsigned int codec_read(struct i2c_client *client, - unsigned int r) -{ - struct i2c_msg xfer[2]; - u8 reg = r; - u16 data; - int ret; - - /* Write register */ - xfer[0].addr = client->addr; - xfer[0].flags = 0; - xfer[0].len = 1; - xfer[0].buf = ® - xfer[0].scl_rate = 100 * 1000; - - /* Read data */ - xfer[1].addr = client->addr; - xfer[1].flags = I2C_M_RD; - xfer[1].len = 2; - xfer[1].buf = (u8 *)&data; - xfer[1].scl_rate = 100 * 1000; - - ret = i2c_transfer(client->adapter, xfer, 2); - if (ret != 2) { - dev_err(&client->dev, "i2c_transfer() returned %d\n", ret); - return 0; - } - //printk("%s: reg=0x%x value=0x%x\n",__func__,reg,(data >> 8) | ((data & 0xff) << 8)); - - return (data >> 8) | ((data & 0xff) << 8); -} - -static int es8323_reg_init(struct i2c_client *client, bool main_mic) -{ - if (es8323_codec_state != OFF) { - if (main_mic) { - codec_write(client, 0x0b,0x82); //ADC INPUT=LIN2/RIN2 //82 - } else { - codec_write(client, 0x0b,0x02); //ADC INPUT=LIN1/RIN1 //02 - } - - DBG("es8323_reg_init() change to %s\n", - main_mic ? "main mic" : "headset mic"); - return 0; - } - codec_write(client, 0x35, 0xa0); - codec_write(client, 0x36, 0xc8); //for 1.8V VDD - codec_write(client, 0x08, 0x20); //slave 0x00, master 0x80, bclk invert(bit5) - codec_write(client, 0x02, 0xf3); - codec_write(client, 0x2b, 0x80); //use ADC LRCK, slave 0x80, master 0xc0 - codec_write(client, 0x00, 0x36); //DACMCLK is the chip master clock source - codec_write(client, 0x01, 0x72); //all normal - codec_write(client, 0x03, 0x00); //all normal - codec_write(client, 0x04, 0x3c); //L/R DAC power up, L/R out1 enable - codec_write(client, 0x05, 0x00); //normal - codec_write(client, 0x06, 0x00); //normal - codec_write(client, 0x07, 0x7c); - codec_write(client, 0x09, 0x88); //MIC GAIN=24dB - codec_write(client, 0x0a, 0xf0); //L-R diff - if (main_mic) { - codec_write(client, 0x0b,0x82); //ADC INPUT=LIN2/RIN2 //82 - } else { - codec_write(client, 0x0b,0x02); //ADC INPUT=LIN1/RIN1 //02 - } - codec_write(client, 0x0c, 0x23); //ADC PCM(bit0-1), 18bit(bit2-4), 2nd(bit5) - codec_write(client, 0x0d, 0x02); - codec_write(client, 0x0f, 0xf0); //unmute ADC - codec_write(client, 0x10, 0x00); - codec_write(client, 0x11, 0x00); - codec_write(client, 0x12, 0x2a); //ALC off - codec_write(client, 0x13, 0xC0); //ALC - codec_write(client, 0x14, 0x05); //ALC - codec_write(client, 0x15, 0x06); //ALC - codec_write(client, 0x16, 0x50); //ALC - codec_write(client, 0x17, 0x06); //DAC PCM(bit1-2), 16bit(bit3-5), 2nd(bit6), lr swap(bit 7) - codec_write(client, 0x18, 0x02); // MCLK/256 - codec_write(client, 0x19, 0x22); - codec_write(client, 0x1a, 0x00); //lout digital - codec_write(client, 0x1b, 0x00); //rout digital - codec_write(client, 0x26, 0x00); - codec_write(client, 0x27, 0xb8); //LD2LO to left mixer - codec_write(client, 0x28, 0x38); - codec_write(client, 0x29, 0x38); - codec_write(client, 0x2a, 0xb8); //RD2RO to right mixer - codec_write(client, 0x30, 0x1e); - codec_write(client, 0x31, 0x1e); - codec_write(client, 0x02, 0x00); - - DBG("es8323_reg_init() set codec route with %s\n", - main_mic ? "main mic" : "headset mic"); - - return 0; -} - -static int es8323_reset(struct i2c_client *client) -{ - es8323_codec_state = OFF; - - codec_write(client, ES8323_CONTROL1, 0x80); - return codec_write(client, ES8323_CONTROL1, 0x00); -} - -int set_es8323(int cmd) -{ - DBG("%s : set voice_call_path = %d\n", __func__, - cmd); - - if (i2c_client == NULL) { - printk("%s : i2c_client is NULL!\n", __func__); - return -EINVAL; - } - - switch (cmd) { - case OFF: - es8323_reset(i2c_client); - break; - case HP_PATH: - es8323_reg_init(i2c_client, 0); - break; - case RCV: - case SPK_PATH: - case HP_NO_MIC: - es8323_reg_init(i2c_client, 1); - break; - case BT: - break; - default: - return -EINVAL; - } - - es8323_codec_state = cmd; - - return 0; -} - -EXPORT_SYMBOL(set_es8323); - -static const struct i2c_device_id es8323_i2c_id[] = { - { "es8323-pcm", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, es8323_i2c_id); - -#ifdef ES8323_PROC -static int es8323_proc_init(void); -#endif - -static int es8323_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) -{ - DBG("%s\n", __func__); - - #ifdef ES8323_PROC - es8323_proc_init(); - #endif - - i2c_client = i2c; - es8323_reset(i2c); - - return 0; -} - -static int es8323_i2c_remove(struct i2c_client *i2c) -{ - return 0; -} - -struct i2c_driver es8323_i2c_driver = { - .driver = { - .name = "es8323-pcm", - .owner = THIS_MODULE, - }, - .probe = es8323_i2c_probe, - .remove = es8323_i2c_remove, - .id_table = es8323_i2c_id, -}; - -static int __init es8323_modinit(void) -{ - return i2c_add_driver(&es8323_i2c_driver); -} -late_initcall(es8323_modinit); - -static void __exit es8323_modexit(void) -{ - i2c_del_driver(&es8323_i2c_driver); -} -module_exit(es8323_modexit); - -MODULE_DESCRIPTION("ASoC ES8323 driver"); -MODULE_AUTHOR("Jear"); -MODULE_LICENSE("GPL"); - - -#ifdef ES8323_PROC - -static ssize_t es8323_proc_write(struct file *file, const char __user *buffer, - unsigned long len, void *data) -{ - char *cookie_pot; - char *p; - int reg; - int value; - - cookie_pot = (char *)vmalloc( len ); - if (!cookie_pot) - { - return -ENOMEM; - } - else - { - if (copy_from_user( cookie_pot, buffer, len )) - return -EFAULT; - } - - switch(cookie_pot[0]) - { - case 'r': - case 'R': - printk("Read reg debug\n"); - if(cookie_pot[1] ==':') - { - strsep(&cookie_pot,":"); - while((p=strsep(&cookie_pot,","))) - { - reg = simple_strtol(p,NULL,16); - value = codec_read(i2c_client,reg); - printk("codec_read:0x%04x = 0x%04x\n",reg,value); - } - printk("\n"); - } - else - { - printk("Error Read reg debug.\n"); - printk("For example: echo r:22,23,24,25>es8323_ts\n"); - } - break; - case 'w': - case 'W': - printk("Write reg debug\n"); - if(cookie_pot[1] ==':') - { - strsep(&cookie_pot,":"); - while((p=strsep(&cookie_pot,"="))) - { - reg = simple_strtol(p,NULL,16); - p=strsep(&cookie_pot,","); - value = simple_strtol(p,NULL,16); - codec_write(i2c_client,reg,value); - printk("codec_write:0x%04x = 0x%04x\n",reg,value); - } - printk("\n"); - } - else - { - printk("Error Write reg debug.\n"); - printk("For example: w:22=0,23=0,24=0,25=0>es8323_ts\n"); - } - break; - case 'a': - printk("Dump reg \n"); - - for(reg = 0; reg < 0x6e; reg+=2) - { - value = codec_read(i2c_client,reg); - printk("codec_read:0x%04x = 0x%04x\n",reg,value); - } - - break; - default: - printk("Help for es8323_ts .\n-->The Cmd list: \n"); - printk("-->'d&&D' Open or Off the debug\n"); - printk("-->'r&&R' Read reg debug,Example: echo 'r:22,23,24,25'>es8323_ts\n"); - printk("-->'w&&W' Write reg debug,Example: echo 'w:22=0,23=0,24=0,25=0'>es8323_ts\n"); - break; - } - - return len; -} - -static const struct file_operations es8323_proc_fops = { - .owner = THIS_MODULE, -}; - -static int es8323_proc_init(void) -{ - struct proc_dir_entry *es8323_proc_entry; - es8323_proc_entry = create_proc_entry("driver/es8323_pcm_ts", 0777, NULL); - if(es8323_proc_entry != NULL) - { - es8323_proc_entry->write_proc = es8323_proc_write; - return 0; - } - else - { - printk("create proc error !\n"); - return -1; - } -} -#endif diff --git a/sound/soc/codecs/gva_codec.c b/sound/soc/codecs/gva_codec.c deleted file mode 100644 index 581689d3ca8f..000000000000 --- a/sound/soc/codecs/gva_codec.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Driver for virtual codec - * - * Copyright (C) 2017 Rockchip Electronics Co., Ltd. - * Author: Li Dongqiang - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include - -#include - -static const struct snd_soc_dapm_widget gva_codec_widgets[] = { - SND_SOC_DAPM_INPUT("RX"), - SND_SOC_DAPM_OUTPUT("TX"), -}; - -static const struct snd_soc_dapm_route gva_codec_routes[] = { - { "Capture", NULL, "RX" }, - { "TX", NULL, "Playback" }, -}; - -#define gva_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ - SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) - -static struct snd_soc_dai_driver gva_codec_dai = { - .name = "gva_codec", - .playback = { - .stream_name = "Playback", - .channels_min = 1, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_8000_192000, - .formats = gva_FORMATS, - }, - .capture = { - .stream_name = "Capture", - .channels_min = 1, - .channels_max = 8, - .rates = SNDRV_PCM_RATE_8000_192000, - .formats = gva_FORMATS, - }, -}; - -static struct snd_soc_codec_driver soc_codec_dev_gva_codec = { - .dapm_widgets = gva_codec_widgets, - .num_dapm_widgets = ARRAY_SIZE(gva_codec_widgets), - .dapm_routes = gva_codec_routes, - .num_dapm_routes = ARRAY_SIZE(gva_codec_routes), -}; - -static int gva_codec_probe(struct platform_device *pdev) -{ - return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_gva_codec, - &gva_codec_dai, 1); -} - -static int gva_codec_remove(struct platform_device *pdev) -{ - snd_soc_unregister_codec(&pdev->dev); - - return 0; -} - -static const struct of_device_id gva_codec_of_match[] = { - { .compatible = "rockchip,gva-codec", }, - {}, -}; -MODULE_DEVICE_TABLE(of, gva_codec_of_match); - -static struct platform_driver gva_codec_driver = { - .driver = { - .name = "gva_codec", - .of_match_table = of_match_ptr(gva_codec_of_match), - }, - .probe = gva_codec_probe, - .remove = gva_codec_remove, -}; - -module_platform_driver(gva_codec_driver); - -MODULE_AUTHOR("Li Dongqiang "); -MODULE_DESCRIPTION("ASoC gva virtual driver"); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/pickle.h b/sound/soc/codecs/pickle.h deleted file mode 100644 index 7d39812751ac..000000000000 --- a/sound/soc/codecs/pickle.h +++ /dev/null @@ -1,8 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef PICKLE_H_ -#define PICKLE_H_ - -void *pickle_pjt(cfw_project *p, int *n); -cfw_project *unpickle_pjt(void *p, int n); - -#endif diff --git a/sound/soc/codecs/rk2928_codec.c b/sound/soc/codecs/rk2928_codec.c deleted file mode 100755 index 006228e4404b..000000000000 --- a/sound/soc/codecs/rk2928_codec.c +++ /dev/null @@ -1,671 +0,0 @@ -/* - * rk2928_codec.c ALSA SoC RK2928 codec driver - * - * Copyright 2012 Rockchip - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "rk2928_codec.h" -#define HP_OUT 0 -#define HP_IN 1 - -static struct rk2928_codec_data { - struct device *dev; - struct snd_soc_codec *codec; - int regbase; - int regbase_phy; - int regsize_phy; - struct clk *pclk; - int mute; - int hdmi_enable; - int spkctl; - int hp_ctl; - int call_enable; - int headset_status; - struct rk2928_codec_pdata *pdata; - bool stop_phone_depop; - struct delayed_work h_delayed_work; - struct mutex mutex_lock; -} rk2928_data; - -static int DAC_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = w->codec; - struct rk2928_codec_data *priv = snd_soc_codec_get_drvdata(codec); - - DBG("%s::%d event = %d\n",__FUNCTION__,__LINE__,event); - - switch (event) { - case SND_SOC_DAPM_PRE_PMD: -#ifdef CONFIG_MODEM_SOUND - if(rk2928_data.call_enable) - return 0; -#endif - //before widget power down - if(rk2928_data.spkctl != INVALID_GPIO) { - gpio_direction_output(rk2928_data.spkctl, GPIO_LOW); - } - if(rk2928_data.hp_ctl != 0 && rk2928_data.headset_status == HP_IN) { - // gpio_direction_output(rk2928_data.hp_ctl, GPIO_LOW); - } - break; - case SND_SOC_DAPM_POST_PMU: - //after widget power up - if(rk2928_data.spkctl != INVALID_GPIO && rk2928_data.headset_status == HP_OUT) { - gpio_direction_output(rk2928_data.spkctl, GPIO_HIGH); - msleep(200); - } - if(rk2928_data.hp_ctl != 0 ) {//&& rk2928_data.headset_status == HP_IN - gpio_direction_output(rk2928_data.hp_ctl, GPIO_HIGH); - } - break; - } - - return 0; -} - -static const struct snd_soc_dapm_widget rk2928_dapm_widgets[] = { - SND_SOC_DAPM_DAC_E("DACL", "HIFI Playback", CODEC_REG_POWER, 5, 1,DAC_event, SND_SOC_DAPM_PRE_PMD|SND_SOC_DAPM_POST_PMU), - SND_SOC_DAPM_DAC_E("DACR", "HIFI Playback", CODEC_REG_POWER, 4, 1,DAC_event, SND_SOC_DAPM_PRE_PMD|SND_SOC_DAPM_POST_PMU), - SND_SOC_DAPM_PGA("DACL Amp", CODEC_REG_DAC_GAIN, 2, 0, NULL, 0), - SND_SOC_DAPM_PGA("DACR Amp", CODEC_REG_DAC_GAIN, 0, 0, NULL, 0), - SND_SOC_DAPM_OUTPUT("SPKL"), - SND_SOC_DAPM_OUTPUT("SPKR"), - SND_SOC_DAPM_ADC("ADCL", "HIFI Capture", CODEC_REG_POWER, 3, 1), - SND_SOC_DAPM_INPUT("MICL"), - SND_SOC_DAPM_ADC("ADCR", "HIFI Capture", CODEC_REG_POWER, 2, 1), - SND_SOC_DAPM_INPUT("MICR"), -}; - -static const struct snd_soc_dapm_route rk2928_audio_map[] = { - {"SPKL", "DACL Amp", "DACL"}, - {"SPKR", "DACR Amp", "DACR"}, - {"ADCL", NULL, "MICL"}, - {"ADCR", NULL, "MICR"}, -}; - -static const struct snd_soc_dapm_widget rk2926_dapm_widgets[] = { - SND_SOC_DAPM_DAC("DACL", "HIFI Playback", CODEC_REG_POWER, 5, 1), - SND_SOC_DAPM_DAC("DACR", "HIFI Playback", CODEC_REG_POWER, 4, 1), - SND_SOC_DAPM_PGA("DACL Amp", CODEC_REG_DAC_GAIN, 2, 0, NULL, 0), - SND_SOC_DAPM_PGA("DACR Amp", CODEC_REG_DAC_GAIN, 0, 0, NULL, 0), - SND_SOC_DAPM_OUTPUT("SPKL"), - SND_SOC_DAPM_OUTPUT("SPKR"), - SND_SOC_DAPM_ADC("ADCR", "HIFI Capture", CODEC_REG_POWER, 2, 1), - SND_SOC_DAPM_INPUT("MICR"), -}; - -static const struct snd_soc_dapm_route rk2926_audio_map[] = { - {"SPKL", "DACL Amp", "DACL"}, - {"SPKR", "DACR Amp", "DACR"}, - {"ADCR", NULL, "MICR"}, -}; - -static unsigned int rk2928_read(struct snd_soc_codec *codec, unsigned int reg) -{ - return readl(rk2928_data.regbase + reg*4); -} - -static int rk2928_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) -{ -#ifdef CONFIG_MODEM_SOUND - if(rk2928_data.call_enable) - return 0; -#endif - DBG("%s reg 0x%02x value 0x%02x", __FUNCTION__, reg, value); - if(reg == 0xc) - value &= ~0x31; - writel(value, rk2928_data.regbase + reg*4); - if( (reg == CODEC_REG_POWER) && ( (value & m_PD_DAC) == 0)) { - msleep(100); - } - return 0; -} -static int rk2928_write_incall(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) -{ - DBG("%s reg 0x%02x value 0x%02x", __FUNCTION__, reg, value); - if(reg == 0xc) - value &= ~0x31; - writel(value, rk2928_data.regbase + reg*4); - if( (reg == CODEC_REG_POWER) && ( (value & m_PD_DAC) == 0)) { - msleep(100); - } - return 0; -} - -static int rk2928_write_mask(struct snd_soc_codec *codec, unsigned int reg, - unsigned int mask, unsigned int value) -{ - unsigned int regvalue = rk2928_read(codec, reg); - - DBG("%s reg 0x%02x mask 0x%02x value 0x%02x", __FUNCTION__, reg, mask, value); - - regvalue &= ~mask; - regvalue |= mask & value; - return rk2928_write(codec, reg, regvalue); -} - -static void call_delay_work(struct work_struct *work) -{ - struct snd_soc_codec *codec = rk2928_data.codec; - if(codec == NULL) - return; - printk("%s speaker is disabled\n", __FUNCTION__); - rk2928_write_incall(NULL, CODEC_REG_DAC_MUTE, v_MUTE_DAC(0)); - rk2928_write_incall(codec, CODEC_REG_POWER, 0x0c); - rk2928_write_incall(codec, CODEC_REG_ADC_SOURCE, 0x03); - rk2928_write_incall(codec, CODEC_REG_ADC_PGA_GAIN, 0x33);//spk 0x33 - rk2928_data.call_enable = 1; - mutex_unlock(&rk2928_data.mutex_lock); - -} -#ifdef CONFIG_MODEM_SOUND -void call_set_spk(int on) -{ - struct snd_soc_codec *codec = rk2928_data.codec; - if(codec == NULL) - return; - mutex_lock(&rk2928_data.mutex_lock); - switch(on) - { - case 0: - printk("%s speaker is enabled\n", __FUNCTION__); - rk2928_data.call_enable = 0; - // rk2928_write(NULL, CODEC_REG_DAC_MUTE, v_MUTE_DAC(0)); - rk2928_write(codec, CODEC_REG_ADC_SOURCE, 0x00); - printk("rk2928 codec stop phone need depop\n"); - rk2928_data.stop_phone_depop = true; - break; - case 1: - rk2928_write_incall(NULL, CODEC_REG_DAC_MUTE, v_MUTE_DAC(1)); - schedule_delayed_work(&rk2928_data.h_delayed_work, msecs_to_jiffies(1000)); - return; - case 2: - printk("%s speaker is disabled\n", __FUNCTION__); - rk2928_write(NULL, CODEC_REG_DAC_MUTE, v_MUTE_DAC(0)); - rk2928_write(codec, CODEC_REG_POWER, 0x0c); - rk2928_write(codec, CODEC_REG_ADC_SOURCE, 0x03); - rk2928_write(codec, CODEC_REG_ADC_PGA_GAIN, 0x11);//headset - rk2928_data.call_enable = 1; - break; - case 3: - printk("%s speaker is disabled\n", __FUNCTION__); - rk2928_write(NULL, CODEC_REG_DAC_MUTE, v_MUTE_DAC(0)); - rk2928_write(codec, CODEC_REG_POWER, 0x0c); - rk2928_write(codec, CODEC_REG_ADC_SOURCE, 0x03); - rk2928_write(codec, CODEC_REG_ADC_PGA_GAIN, 0x33);//spk 0x33 - rk2928_data.call_enable = 1; - break; - } - mutex_unlock(&rk2928_data.mutex_lock); - return; -} -#endif -#ifdef CONFIG_RK_HEADSET_DET -//for headset -void rk2928_codec_set_spk(bool on) -{ - struct snd_soc_codec *codec = rk2928_data.codec; - if(codec == NULL) - return; - if(on) - rk2928_data.headset_status = HP_IN; - else - rk2928_data.headset_status = HP_OUT; - if(rk2928_data.call_enable) - return; - printk("%s: headset %s %s PA bias_level=%d\n",__FUNCTION__,on?"in":"out",on?"disable":"enable",codec->dapm.bias_level); - if(on) { - if(rk2928_data.spkctl != INVALID_GPIO) - { - gpio_direction_output(rk2928_data.spkctl, GPIO_LOW); - } - } - else { - if(codec->dapm.bias_level == SND_SOC_BIAS_STANDBY - || codec->dapm.bias_level == SND_SOC_BIAS_OFF){ - return; - } - if(rk2928_data.spkctl != INVALID_GPIO) - { - gpio_direction_output(rk2928_data.spkctl, GPIO_HIGH); - } - } -} -#endif - -static int rk2928_audio_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) -{ -// struct snd_soc_pcm_runtime *rtd = substream->private_data; -// struct snd_soc_codec *codec = rtd->codec; -// struct rk2928_codec_data *priv = snd_soc_codec_get_drvdata(codec); - - DBG("%s", __FUNCTION__); - - return 0; -} - -static int rk2928_audio_trigger(struct snd_pcm_substream *substream, int cmd, - struct snd_soc_dai *dai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec *codec = rtd->codec; - struct rk2928_codec_data *priv = snd_soc_codec_get_drvdata(codec); - int err = 0; - int data, pd_adc; - DBG("%s cmd 0x%x", __FUNCTION__, cmd); - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { -// rk2928_write(codec, CODEC_REG_DAC_GAIN, v_GAIN_DAC(DAC_GAIN_3DB_P)); - if(!rk2928_data.hdmi_enable) { - data = rk2928_read(codec, CODEC_REG_POWER); - if(soc_is_rk2928g()){ - if( (data & m_PD_ADC) == 0) { - data &= ~m_PD_ADC; - data |= v_PD_ADC(1); - pd_adc = 1; - } - else - pd_adc = 0; - } - else{ - if( (data & m_PD_ADC_R) == 0) { - data &= ~m_PD_ADC_R; - data |= v_PD_ADC_R(1); - pd_adc = 1; - } - else - pd_adc = 0; - } - if(pd_adc == 1) { - DBG("%s reg 0x%02x value 0x%02x", __FUNCTION__, CODEC_REG_POWER, data); - writel(data, rk2928_data.regbase + CODEC_REG_POWER*4); - udelay(100); - } - - rk2928_write(codec, CODEC_REG_ADC_SOURCE, 0x03); - udelay(100); - rk2928_write(codec, CODEC_REG_ADC_SOURCE, 0x00); - - udelay(100); - rk2928_write(codec, CODEC_REG_ADC_SOURCE, 0x03); - udelay(100); - rk2928_write(codec, CODEC_REG_ADC_SOURCE, 0x00); - - udelay(100); - rk2928_write(codec, CODEC_REG_ADC_SOURCE, 0x03); - udelay(100); - rk2928_write(codec, CODEC_REG_ADC_SOURCE, 0x00); - - if(pd_adc == 1) { - udelay(100); - data = rk2928_read(codec, CODEC_REG_POWER); - if( soc_is_rk2928g() ) { - data &= ~m_PD_ADC; - data |= v_PD_ADC(0); - } - else { - data &= ~m_PD_ADC_R; - data |= v_PD_ADC_R(0); - } - DBG("%s reg 0x%02x value 0x%02x", __FUNCTION__, CODEC_REG_POWER, data); - writel(data, rk2928_data.regbase + CODEC_REG_POWER*4); - } - - rk2928_write(codec, CODEC_REG_DAC_MUTE, v_MUTE_DAC(0)); - if(rk2928_data.spkctl != INVALID_GPIO && rk2928_data.headset_status == HP_OUT && rk2928_data.stop_phone_depop ) { - mdelay(100); - gpio_direction_output(rk2928_data.spkctl, GPIO_HIGH); - rk2928_data.stop_phone_depop = false; - } - } - rk2928_data.mute = 0; - // if(rk2928_data.spkctl != INVALID_GPIO && rk2928_data.headset_status == HP_OUT) { - // gpio_direction_output(rk2928_data.spkctl, GPIO_HIGH); - // } - } - else { - rk2928_write(codec, CODEC_REG_ADC_PGA_GAIN, 0xFF); - rk2928_write(codec, 0x08, 0xff); - rk2928_write(codec, 0x09, 0x07); - } - break; - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: -#ifdef CONFIG_MODEM_SOUND - if(rk2928_data.call_enable) - return err; -#endif - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - //if(rk2928_data.spkctl != INVALID_GPIO) { - //gpio_direction_output(rk2928_data.spkctl, GPIO_LOW); - //} - rk2928_write(codec, CODEC_REG_DAC_MUTE, v_MUTE_DAC(1)); - rk2928_data.mute = 1; - } - break; - default: - err = -EINVAL; - } - return err; -} - -static int rk2928_audio_startup(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ -// struct snd_soc_pcm_runtime *rtd = substream->private_data; -// struct snd_soc_codec *codec = rtd->codec; - DBG("%s", __FUNCTION__); - return 0; -} - -static int rk2928_set_bias_level(struct snd_soc_codec *codec, - enum snd_soc_bias_level level) -{ - DBG("%s level %d\n", __FUNCTION__, level); - - if(codec == NULL) - return -1; - - switch(level) - { - case SND_SOC_BIAS_ON: - break; - case SND_SOC_BIAS_PREPARE: - rk2928_write_mask(codec, CODEC_REG_POWER, m_PD_MIC_BIAS | m_PD_CODEC, v_PD_MIC_BIAS(0) | v_PD_CODEC(0)); - break; - case SND_SOC_BIAS_STANDBY: - case SND_SOC_BIAS_OFF: - printk("rk2928 codec standby\n"); -#ifdef CONFIG_MODEM_SOUND - if(rk2928_data.call_enable) - break; -#endif - // if(rk2928_data.spkctl != INVALID_GPIO) { - // gpio_direction_output(rk2928_data.spkctl, GPIO_LOW); - // } - rk2928_write(codec, CODEC_REG_POWER, v_PWR_OFF); - break; - default: - return -1; - } - codec->dapm.bias_level = level; - return 0; -} - -static void rk2929_codec_reset(void) -{ - // Reset Codec - cru_set_soft_reset(SOFT_RST_ACODEC, true); - udelay(1000); - cru_set_soft_reset(SOFT_RST_ACODEC, false); -} - -static int rk2928_probe(struct snd_soc_codec *codec) -{ - struct platform_device *pdev = to_platform_device(codec->dev); - struct snd_soc_dapm_context *dapm = &codec->dapm; - struct resource *res, *mem; - struct rk2928_codec_pdata *pdata; - int ret; - - DBG("%s", __FUNCTION__); - - snd_soc_codec_set_drvdata(codec, &rk2928_data); - - rk2928_data.dev = &pdev->dev; - rk2928_data.pdata = pdev->dev.platform_data; - pdata = rk2928_data.pdata; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "Unable to get register resource\n"); - ret = -ENXIO; - goto err0; - } - rk2928_data.regbase_phy = res->start; - rk2928_data.regsize_phy = (res->end - res->start) + 1; - mem = request_mem_region(res->start, (res->end - res->start) + 1, pdev->name); - if (!mem) - { - dev_err(&pdev->dev, "failed to request mem region for rk2928 codec\n"); - ret = -ENOENT; - goto err0; - } - - rk2928_data.regbase = (int)ioremap(res->start, (res->end - res->start) + 1); - if (!rk2928_data.regbase) { - dev_err(&pdev->dev, "cannot ioremap acodec registers\n"); - ret = -ENXIO; - goto err1; - } - - rk2928_data.pclk = clk_get(NULL,"pclk_acodec"); - if(IS_ERR(rk2928_data.pclk)) - { - dev_err(rk2928_data.dev, "Unable to get acodec hclk\n"); - ret = -ENXIO; - goto err1; - } - clk_enable(rk2928_data.pclk); - - res = platform_get_resource(pdev, IORESOURCE_IO, 0); - if(!res) { - rk2928_data.spkctl = INVALID_GPIO; - } - else { - rk2928_data.spkctl = res->start; - } - - if(rk2928_data.spkctl != INVALID_GPIO) { - ret = gpio_request(rk2928_data.spkctl, NULL); - if (ret != 0) { - gpio_free(rk2928_data.spkctl); - } - else - gpio_direction_output(rk2928_data.spkctl, GPIO_LOW); - } -//------------------------------------------------------------------ - if (pdata->hpctl) { - ret = pdata->hpctl_io_init(); - if (ret) - goto err1; - rk2928_data.hp_ctl = pdata->hpctl; - gpio_direction_output(rk2928_data.hp_ctl, GPIO_LOW); - } - //Reset Codec - rk2929_codec_reset(); - - // Select SDI input from internal audio codec - writel(0x04000400, RK2928_GRF_BASE + GRF_SOC_CON0); - - // Mute and Power off codec - rk2928_write(codec, CODEC_REG_DAC_MUTE, v_MUTE_DAC(1)); - rk2928_set_bias_level(codec, SND_SOC_BIAS_OFF); - if(soc_is_rk2928g()){ - snd_soc_dapm_new_controls(dapm, rk2928_dapm_widgets, - ARRAY_SIZE(rk2928_dapm_widgets)); - snd_soc_dapm_add_routes(dapm, rk2928_audio_map, ARRAY_SIZE(rk2928_audio_map)); - }else{ - snd_soc_dapm_new_controls(dapm, rk2926_dapm_widgets, - ARRAY_SIZE(rk2926_dapm_widgets)); - snd_soc_dapm_add_routes(dapm, rk2926_audio_map, ARRAY_SIZE(rk2926_audio_map)); - } - - INIT_DELAYED_WORK(&rk2928_data.h_delayed_work, call_delay_work); - mutex_init(&rk2928_data.mutex_lock); - rk2928_data.call_enable = 0; - rk2928_data.headset_status = HP_OUT; - rk2928_data.codec=codec; - rk2928_data.stop_phone_depop=false; - return 0; - -err1: - release_mem_region(res->start,(res->end - res->start) + 1); -// clk_disable(rk2928_data.hclk); -err0: - DBG("%s failed", __FUNCTION__); - return ret; -} - -static int rk2928_remove(struct snd_soc_codec *codec) -{ - return 0; -} - -static int rk2928_suspend(struct snd_soc_codec *codec) -{ - DBG("%s", __FUNCTION__); - rk2928_set_bias_level(codec, SND_SOC_BIAS_OFF); - clk_disable(rk2928_data.pclk); - return 0; -} - -static int rk2928_resume(struct snd_soc_codec *codec) -{ - DBG("%s", __FUNCTION__); - clk_enable(rk2928_data.pclk); - rk2928_write(codec, CODEC_REG_POWER, v_PD_ADC(1) | v_PD_DAC(1) | v_PD_MIC_BIAS(0)); - return 0; -} - -static struct snd_soc_codec_driver rk2928_audio_codec_drv = { - .probe = rk2928_probe, - .remove = rk2928_remove, - .suspend = rk2928_suspend, - .resume = rk2928_resume, - .read = rk2928_read, - .write = rk2928_write, - .set_bias_level = rk2928_set_bias_level, -}; - -static struct snd_soc_dai_ops rk2928_audio_codec_ops = { - .hw_params = rk2928_audio_hw_params, - .trigger = rk2928_audio_trigger, - .startup = rk2928_audio_startup, -}; - -static struct snd_soc_dai_driver rk2928_codec_dai = { - .name = "rk2928-codec", - .playback = { - .stream_name = "HIFI Playback", - .channels_min = 1, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_8000_48000, - .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | - SNDRV_PCM_FMTBIT_S24_LE, - }, - .capture = { - .stream_name = "HIFI Capture", - .channels_min = 1, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_8000_48000, - .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S18_3LE, - }, - .ops = &rk2928_audio_codec_ops, -}; - -static int rk2928_codec_probe(struct platform_device *pdev) -{ - int r; - - DBG("%s", __FUNCTION__); - - /* Register ASoC codec DAI */ - r = snd_soc_register_codec(&pdev->dev, &rk2928_audio_codec_drv, - &rk2928_codec_dai, 1); - if (r) { - dev_err(&pdev->dev, "can't register ASoC rk2928 audio codec\n"); - return r; - } - - DBG("%s success", __FUNCTION__); - return 0; - -} - -static int __devexit rk2928_codec_remove(struct platform_device *pdev) -{ - snd_soc_unregister_codec(&pdev->dev); - return 0; -} - -static void rk2928_codec_shutdown(struct platform_device *pdev) -{ - printk("%s .....\n", __FUNCTION__); - if(rk2928_data.spkctl != INVALID_GPIO) - gpio_direction_output(rk2928_data.spkctl, GPIO_LOW); - if(rk2928_data.hp_ctl != 0 ) - gpio_direction_output(rk2928_data.hp_ctl, GPIO_LOW); -} -static struct platform_driver rk2928_codec_driver = { - .probe = rk2928_codec_probe, - .remove = __devexit_p(rk2928_codec_remove), - .driver = { - .name = "rk2928-codec", - .owner = THIS_MODULE, - }, - .shutdown = rk2928_codec_shutdown, -}; - -static int __init rk2928_codec_init(void) -{ - return platform_driver_register(&rk2928_codec_driver); -} -module_init(rk2928_codec_init); - -static void __exit rk2928_codec_exit(void) -{ - #ifdef CODEC_I2C_MODE - i2c_del_driver(&rk2928_codec_driver); - #else - platform_driver_unregister(&rk2928_codec_driver); - #endif -} -module_exit(rk2928_codec_exit); - -MODULE_DESCRIPTION("ASoC RK2928 codec driver"); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/rk2928_codec.h b/sound/soc/codecs/rk2928_codec.h deleted file mode 100755 index a7ec8693c8c0..000000000000 --- a/sound/soc/codecs/rk2928_codec.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * rk2928.h ALSA SoC RK2928 codec driver - * - * Copyright 2012 Rockchip - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef __RK2928_CODEC_H__ -#define __RK2928_CODEC_H__ - -#define CODEC_REG_ADC_DIGITAL_GIAN_L 0x08 -#define CODEC_REG_ADC_DIGITAL_GIAN_H 0x09 - -#define CODEC_REG_ADC_PGA_GAIN 0x0b - #define m_MIC_GAIN_CHANNEL_L (0x0F << 4) - #define m_MIC_GAIN_CHANNEL_R (0x0F) - #define v_MIC_GAIN_CHANNEL_L(n) ((n) << 4) - #define v_MIC_GAIN_CHANNEL_R(n) (n) - -#define CODEC_REG_POWER 0x0c - #define m_PD_CODEC (0x01) - #define m_PD_MIC_BIAS (0x01 << 1) - #define m_PD_ADC_R (0x01 << 2) - #define m_PD_ADC_L (0x01 << 3) - #define m_PD_ADC (0x03 << 2) - #define m_PD_DAC (0x03 << 4) - #define v_PD_CODEC(n) (n) - #define v_PD_MIC_BIAS(n) (n << 1) - #define v_PD_ADC_R(n) (n << 2) - #define v_PD_ADC_L(n) (n << 3) - #define v_PD_DAC_R(n) (n << 4) - #define v_PD_DAC_L(n) (n << 5) - #define v_PD_ADC(n) (v_PD_ADC_L(n) | v_PD_ADC_R(n)) - #define v_PD_DAC(n) (v_PD_DAC_L(n) | v_PD_DAC_R(n)) - #define v_PWR_OFF v_PD_DAC_L(1) | v_PD_DAC_R(1) | v_PD_ADC_L(1) | v_PD_ADC_R(1) | v_PD_MIC_BIAS(0) | v_PD_CODEC(1) //²»¹Ø±Õmic_bias for phone_pad - -#define CODEC_REG_VCM_BIAS 0x0d - #define v_MIC_BIAS(n) (n) - enum { - VCM_RESISTOR_100K = 0, - VCM_RESISTOR_25K - }; - #define v_VCM_25K_100K(n) (n << 2) - -#define CODEC_REG_DAC_MUTE 0x0e - #define v_MUTE_DAC_L(n) (n << 1) - #define v_MUTE_DAC_R(n) (n) - #define v_MUTE_DAC(n) v_MUTE_DAC_L(n) | v_MUTE_DAC_R(n) - -#define CODEC_REG_ADC_SOURCE 0x0f - enum { - ADC_SRC_MIC = 0, - ADC_SRC_LINE_IN - }; - #define v_SRC_ADC_L(n) (n << 1) - #define v_SRC_ADC_R(n) (n) - -#define CODEC_REG_DAC_GAIN 0x10 - #define m_GAIN_DAC_L (0x03 << 2) - #define m_GAIN_DAC_R (0x03) - enum { - DAC_GAIN_0DB = 0, - DAC_GAIN_3DB_P = 0x2, //3db - DAC_GAIN_3DB_N //-3db - }; - #define v_GAIN_DAC_L(n) (n << 2) - #define v_GAIN_DAC_R(n) (n) - #define v_GAIN_DAC(n) (v_GAIN_DAC_L(n) | v_GAIN_DAC_R(n)) - -//#ifndef DEBUG -//#define DEBUG -//#endif - -#ifdef DEBUG -#define DBG(format, ...) \ - printk(KERN_INFO "RK2928 CODEC: " format "\n", ## __VA_ARGS__) -#else -#define DBG(format, ...) -#endif - -struct rk2928_codec_pdata { - int hpctl; - int (*hpctl_io_init)(void); -}; - -#endif /* __RK2928_CODEC_H__ */ diff --git a/sound/soc/codecs/rk3026_codec.c b/sound/soc/codecs/rk3026_codec.c deleted file mode 100644 index 30d0a620d305..000000000000 --- a/sound/soc/codecs/rk3026_codec.c +++ /dev/null @@ -1,2169 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * rk3026.c -- RK3026 CODEC ALSA SoC audio driver - * - * Copyright 2013 Rockchip - * Author: chenjq - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "rk3026_codec.h" - - -#ifdef CONFIG_RK_HEADSET_DET -#include "../../../drivers/headset_observe/rk_headset.h" -#endif - -static int debug; -module_param(debug, int, S_IRUGO|S_IWUSR); - -#define dbg_codec(level, fmt, arg...) do { \ - if (debug >= level) \ - printk(fmt , ## arg); } while (0) - -#define DBG(fmt,...) dbg_codec(1,fmt,## __VA_ARGS__) - - -/* volume setting - * 0: -39dB - * 26: 0dB - * 31: 6dB - * Step: 1.5dB -*/ -#define OUT_VOLUME 31//0~31 - -/* capture vol set - * 0: -18db - * 12: 0db - * 31: 28.5db - * step: 1.5db -*/ -#define CAP_VOL 17//0-31 - -//with capacity or not -#define WITH_CAP -#ifdef CONFIG_MACH_RK_FAC - rk3026_hdmi_ctrl=0; -#endif -struct rk3026_codec_priv { - struct snd_soc_codec *codec; - - unsigned int stereo_sysclk; - unsigned int rate; - - int playback_active; - int capture_active; - - int spk_ctl_gpio; - int hp_ctl_gpio; - int delay_time; - - long int playback_path; - long int capture_path; - long int voice_call_path; - - int regbase; - int regbase_phy; - int regsize_phy; - struct clk *pclk; -}; - -static struct rk3026_codec_priv *rk3026_priv = NULL; - -#define RK3026_CODEC_ALL 0 -#define RK3026_CODEC_PLAYBACK 1 -#define RK3026_CODEC_CAPTURE 2 -#define RK3026_CODEC_INCALL 3 - -#define RK3026_CODEC_WORK_NULL 0 -#define RK3026_CODEC_WORK_POWER_DOWN 1 -#define RK3026_CODEC_WORK_POWER_UP 2 - -static struct workqueue_struct *rk3026_codec_workq; - -static void rk3026_codec_capture_work(struct work_struct *work); -static DECLARE_DELAYED_WORK(capture_delayed_work, rk3026_codec_capture_work); -static int rk3026_codec_work_capture_type = RK3026_CODEC_WORK_NULL; -static bool rk3026_for_mid = 1; - -static int rk3026_get_parameter(void) -{ - int val; - char *command_line = strstr(saved_command_line, "ap_has_alsa="); - - if (command_line == NULL) { - printk("%s : Can not get ap_has_alsa from kernel command line!\n", __func__); - return 0; - } - - command_line += 12; - - val = simple_strtol(command_line, NULL, 10); - if (val == 0 || val == 1) { - rk3026_for_mid = (val ? 0 : 1); - printk("%s : THIS IS FOR %s\n", __func__, rk3026_for_mid ? "mid" : "phone"); - } else { - printk("%s : get ap_has_alsa error, val = %d\n", __func__, val); - } - - return 0; -} - -static const unsigned int rk3026_reg_defaults[RK3026_PGAR_AGC_CTL5+1] = { - [RK3026_RESET] = 0x0003, - [RK3026_ADC_INT_CTL1] = 0x0050, - [RK3026_ADC_INT_CTL2] = 0x000e, - [RK3026_DAC_INT_CTL1] = 0x0050, - [RK3026_DAC_INT_CTL2] = 0x000e, - [RK3026_DAC_INT_CTL3] = 0x22, - [RK3026_ADC_MIC_CTL] = 0x0000, - [RK3026_BST_CTL] = 0x000, - [RK3026_ALC_MUNIN_CTL] = 0x0044, - [RK3026_BSTL_ALCL_CTL] = 0x000c, - [RK3026_ALCR_GAIN_CTL] = 0x000C, - [RK3026_ADC_ENABLE] = 0x0000, - [RK3026_DAC_CTL] = 0x0000, - [RK3026_DAC_ENABLE] = 0x0000, - [RK3026_HPMIX_CTL] = 0x0000, - [RK3026_HPMIX_S_SELECT] = 0x0000, - [RK3026_HPOUT_CTL] = 0x0000, - [RK3026_HPOUTL_GAIN] = 0x0000, - [RK3026_HPOUTR_GAIN] = 0x0000, - [RK3026_SELECT_CURRENT] = 0x003e, - [RK3026_PGAL_AGC_CTL1] = 0x0000, - [RK3026_PGAL_AGC_CTL2] = 0x0046, - [RK3026_PGAL_AGC_CTL3] = 0x0041, - [RK3026_PGAL_AGC_CTL4] = 0x002c, - [RK3026_PGAL_ASR_CTL] = 0x0000, - [RK3026_PGAL_AGC_MAX_H] = 0x0026, - [RK3026_PGAL_AGC_MAX_L] = 0x0040, - [RK3026_PGAL_AGC_MIN_H] = 0x0036, - [RK3026_PGAL_AGC_MIN_L] = 0x0020, - [RK3026_PGAL_AGC_CTL5] = 0x0038, - [RK3026_PGAR_AGC_CTL1] = 0x0000, - [RK3026_PGAR_AGC_CTL2] = 0x0046, - [RK3026_PGAR_AGC_CTL3] = 0x0041, - [RK3026_PGAR_AGC_CTL4] = 0x002c, - [RK3026_PGAR_ASR_CTL] = 0x0000, - [RK3026_PGAR_AGC_MAX_H] = 0x0026, - [RK3026_PGAR_AGC_MAX_L] = 0x0040, - [RK3026_PGAR_AGC_MIN_H] = 0x0036, - [RK3026_PGAR_AGC_MIN_L] = 0x0020, - [RK3026_PGAR_AGC_CTL5] = 0x0038, -}; - -static struct rk3026_init_bit_typ rk3026_init_bit_list[] = { - {RK3026_HPOUT_CTL, RK3026_HPOUTL_EN, RK3026_HPOUTL_WORK,RK3026_HPVREF_EN}, - {RK3026_HPOUT_CTL, RK3026_HPOUTR_EN, RK3026_HPOUTR_WORK,RK3026_HPVREF_WORK}, - {RK3026_HPMIX_CTL, RK3026_HPMIXR_EN, RK3026_HPMIXR_WORK2,RK3026_HPMIXR_WORK1}, - {RK3026_HPMIX_CTL, RK3026_HPMIXL_EN, RK3026_HPMIXL_WORK2,RK3026_HPMIXL_WORK1}, - -}; -#define RK3026_INIT_BIT_LIST_LEN ARRAY_SIZE(rk3026_init_bit_list) - -static int rk3026_init_bit_register(unsigned int reg, int i) -{ - for (; i < RK3026_INIT_BIT_LIST_LEN; i++) { - if (rk3026_init_bit_list[i].reg == reg) - return i; - } - - return -1; -} - -static unsigned int rk3026_codec_read(struct snd_soc_codec *codec, unsigned int reg); -static inline void rk3026_write_reg_cache(struct snd_soc_codec *codec, - unsigned int reg, unsigned int value); - -static unsigned int rk3026_set_init_value(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) -{ - unsigned int read_value, power_bit, set_bit2,set_bit1; - int i; - int tmp = 0; - // read codec init register - i = rk3026_init_bit_register(reg, 0); - - // set codec init bit - // widget init bit should be setted 0 after widget power up or unmute, - // and should be setted 1 after widget power down or mute. - if (i >= 0) { - read_value = rk3026_codec_read(codec, reg); - while (i >= 0) { - power_bit = rk3026_init_bit_list[i].power_bit; - set_bit2 = rk3026_init_bit_list[i].init2_bit; - set_bit1 = rk3026_init_bit_list[i].init1_bit; - - if ((read_value & power_bit) != (value & power_bit)) - { - if (value & power_bit) - { - tmp = value | set_bit2 | set_bit1; - writel(value, rk3026_priv->regbase+reg); - writel(tmp, rk3026_priv->regbase+reg); - - } - else - { - tmp = value & (~set_bit2) & (~set_bit1); - writel(tmp, rk3026_priv->regbase+reg); - writel(value, rk3026_priv->regbase+reg); - } - value = tmp; - } - else - { - if (read_value != value) - writel(value, rk3026_priv->regbase+reg); - } - - i = rk3026_init_bit_register(reg, ++i); - - rk3026_write_reg_cache(codec, reg, value); - } - } - else - { - return i; - } - - return value; -} - -static int rk3026_volatile_register(struct snd_soc_codec *codec, unsigned int reg) -{ - switch (reg) { - case RK3026_RESET: - return 1; - default: - return 0; - } -} - -static int rk3026_codec_register(struct snd_soc_codec *codec, unsigned int reg) -{ - switch (reg) { - case RK3026_RESET: - case RK3026_ADC_INT_CTL1: - case RK3026_ADC_INT_CTL2: - case RK3026_DAC_INT_CTL1: - case RK3026_DAC_INT_CTL2: - case RK3026_DAC_INT_CTL3: - case RK3026_ADC_MIC_CTL: - case RK3026_BST_CTL: - case RK3026_ALC_MUNIN_CTL: - case RK3026_BSTL_ALCL_CTL: - case RK3026_ALCR_GAIN_CTL: - case RK3026_ADC_ENABLE: - case RK3026_DAC_CTL: - case RK3026_DAC_ENABLE: - case RK3026_HPMIX_CTL: - case RK3026_HPMIX_S_SELECT: - case RK3026_HPOUT_CTL: - case RK3026_HPOUTL_GAIN: - case RK3026_HPOUTR_GAIN: - case RK3026_SELECT_CURRENT: - case RK3026_PGAL_AGC_CTL1: - case RK3026_PGAL_AGC_CTL2: - case RK3026_PGAL_AGC_CTL3: - case RK3026_PGAL_AGC_CTL4: - case RK3026_PGAL_ASR_CTL: - case RK3026_PGAL_AGC_MAX_H: - case RK3026_PGAL_AGC_MAX_L: - case RK3026_PGAL_AGC_MIN_H: - case RK3026_PGAL_AGC_MIN_L: - case RK3026_PGAL_AGC_CTL5: - case RK3026_PGAR_AGC_CTL1: - case RK3026_PGAR_AGC_CTL2: - case RK3026_PGAR_AGC_CTL3: - case RK3026_PGAR_AGC_CTL4: - case RK3026_PGAR_ASR_CTL: - case RK3026_PGAR_AGC_MAX_H: - case RK3026_PGAR_AGC_MAX_L: - case RK3026_PGAR_AGC_MIN_H: - case RK3026_PGAR_AGC_MIN_L: - case RK3026_PGAR_AGC_CTL5: - return 1; - default: - return 0; - } -} - -static inline unsigned int rk3026_read_reg_cache(struct snd_soc_codec *codec, - unsigned int reg) -{ - unsigned int *cache = codec->reg_cache; - - if (rk3026_codec_register(codec, reg) ) - return cache[reg]; - - printk("%s : reg error!\n", __func__); - - return -EINVAL; -} - -static inline void rk3026_write_reg_cache(struct snd_soc_codec *codec, - unsigned int reg, unsigned int value) -{ - unsigned int *cache = codec->reg_cache; - - if (rk3026_codec_register(codec, reg)) { - cache[reg] = value; - return; - } - - printk("%s : reg error!\n", __func__); -} - -static unsigned int rk3026_codec_read(struct snd_soc_codec *codec, unsigned int reg) -{ - unsigned int value; - - if (!rk3026_priv) { - printk("%s : rk3026 is NULL\n", __func__); - return -EINVAL; - } - - if (!rk3026_codec_register(codec, reg)) { - printk("%s : reg error!\n", __func__); - return -EINVAL; - } - - if (rk3026_volatile_register(codec, reg) == 0) { - value = rk3026_read_reg_cache(codec, reg); - } else { - value = readl_relaxed(rk3026_priv->regbase+reg); - } - - value = readl_relaxed(rk3026_priv->regbase+reg); - dbg_codec(2,"%s : reg = 0x%x, val= 0x%x\n", __func__, reg, value); - - return value; -} - -static int rk3026_codec_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) -{ - int new_value; - - if (!rk3026_priv) { - printk("%s : rk3026 is NULL\n", __func__); - return -EINVAL; - } else if (!rk3026_codec_register(codec, reg)) { - printk("%s : reg error!\n", __func__); - return -EINVAL; - } - - new_value = rk3026_set_init_value(codec, reg, value); - - if (new_value == -1) - { - writel(value, rk3026_priv->regbase+reg); - rk3026_write_reg_cache(codec, reg, value); - } - - dbg_codec(2,"%s : reg = 0x%x, val = 0x%x, new_value=%d\n", __func__, reg, value,new_value); - return 0; -} - -static int rk3026_hw_write(const struct i2c_client *client, const char *buf, int count) -{ - unsigned int reg, value; - - if (!rk3026_priv || !rk3026_priv->codec) { - printk("%s : rk3026_priv or rk3026_priv->codec is NULL\n", __func__); - return -EINVAL; - } - - if (count == 3) { - reg = (unsigned int)buf[0]; - value = (buf[1] & 0xff00) | (0x00ff & buf[2]); - writel(value, rk3026_priv->regbase+reg); - } else { - printk("%s : i2c len error\n", __func__); - } - - return count; -} - -static int rk3026_reset(struct snd_soc_codec *codec) -{ - writel(0x00, rk3026_priv->regbase+RK3026_RESET); - mdelay(10); - writel(0x03, rk3026_priv->regbase+RK3026_RESET); - mdelay(10); - - memcpy(codec->reg_cache, rk3026_reg_defaults, - sizeof(rk3026_reg_defaults)); - - return 0; -} - -int rk3026_headset_mic_detect(bool headset_status) -{ -#if 0 - struct snd_soc_codec *codec = rk3026_priv->codec; - - DBG("%s\n", __func__); - - if (!rk3026_priv || !rk3026_priv->codec) { - printk("%s : rk3026_priv or rk3026_priv->codec is NULL\n", __func__); - return -EINVAL; - } - - if (headset_status) { - snd_soc_update_bits(codec, RK3026_ADC_MIC_CTL, - RK3026_MICBIAS2_PWRD | RK3026_MICBIAS2_V_MASK, - RK3026_MICBIAS2_V_1_7); - } else {// headset is out, disable MIC2 && MIC1 Bias - DBG("%s : headset is out,disable Mic2 Bias\n", __func__); - snd_soc_update_bits(codec, RK3026_ADC_MIC_CTL, - RK3026_MICBIAS2_PWRD | RK3026_MICBIAS2_V_MASK, - RK3026_MICBIAS2_V_1_0|RK3026_MICBIAS2_PWRD); - } -#endif - return 0; -} -EXPORT_SYMBOL(rk3026_headset_mic_detect); - -static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -3900, 150, 0); -static const DECLARE_TLV_DB_SCALE(pga_vol_tlv, -1800, 150, 0); -static const DECLARE_TLV_DB_SCALE(bst_vol_tlv, 0, 2000, 0); -static const DECLARE_TLV_DB_SCALE(pga_agc_max_vol_tlv, -1350, 600, 0); -static const DECLARE_TLV_DB_SCALE(pga_agc_min_vol_tlv, -1800, 600, 0); - -static const char *rk3026_input_mode[] = {"Differential","Single-Ended"}; - -static const char *rk3026_micbias_ratio[] = {"1.0 Vref", "1.1 Vref", - "1.2 Vref", "1.3 Vref", "1.4 Vref", "1.5 Vref", "1.6 Vref", "1.7 Vref",}; - -static const char *rk3026_dis_en_sel[] = {"Disable", "Enable"}; - -static const char *rk3026_pga_agc_way[] = {"Normal", "Jack"}; - -static const char *rk3026_agc_backup_way[] = {"Normal", "Jack1", "Jack2", "Jack3"}; - -static const char *rk3026_pga_agc_hold_time[] = {"0ms", "2ms", - "4ms", "8ms", "16ms", "32ms", "64ms", "128ms", "256ms", "512ms", "1s"}; - -static const char *rk3026_pga_agc_ramp_up_time[] = {"Normal:500us Jack:125us", - "Normal:1ms Jack:250us", "Normal:2ms Jack:500us", "Normal:4ms Jack:1ms", - "Normal:8ms Jack:2ms", "Normal:16ms Jack:4ms", "Normal:32ms Jack:8ms", - "Normal:64ms Jack:16ms", "Normal:128ms Jack:32ms", "Normal:256ms Jack:64ms", - "Normal:512ms Jack:128ms"}; - -static const char *rk3026_pga_agc_ramp_down_time[] = {"Normal:125us Jack:32us", - "Normal:250us Jack:64us", "Normal:500us Jack:125us", "Normal:1ms Jack:250us", - "Normal:2ms Jack:500us", "Normal:4ms Jack:1ms", "Normal:8ms Jack:2ms", - "Normal:16ms Jack:4ms", "Normal:32ms Jack:8ms", "Normal:64ms Jack:16ms", - "Normal:128ms Jack:32ms"}; - -static const char *rk3026_pga_agc_mode[] = {"Normal", "Limiter"}; - -static const char *rk3026_pga_agc_recovery_mode[] = {"Right Now", "After AGC to Limiter"}; - -static const char *rk3026_pga_agc_noise_gate_threhold[] = {"-39dB", "-45dB", "-51dB", - "-57dB", "-63dB", "-69dB", "-75dB", "-81dB"}; - -static const char *rk3026_pga_agc_update_gain[] = {"Right Now", "After 1st Zero Cross"}; - -static const char *rk3026_pga_agc_approximate_sample_rate[] = {"96KHZ","48KHz","441KHZ", "32KHz", - "24KHz", "16KHz", "12KHz", "8KHz"}; - -static const struct soc_enum rk3026_bst_enum[] = { -SOC_ENUM_SINGLE(RK3026_BSTL_ALCL_CTL, RK3026_BSTL_MODE_SFT, 2, rk3026_input_mode), -}; - - -static const struct soc_enum rk3026_micbias_enum[] = { -SOC_ENUM_SINGLE(RK3026_ADC_MIC_CTL, RK3026_MICBIAS_VOL_SHT, 8, rk3026_micbias_ratio), -}; - -static const struct soc_enum rk3026_agcl_enum[] = { -SOC_ENUM_SINGLE(RK3026_PGAL_AGC_CTL1, RK3026_PGA_AGC_BK_WAY_SFT, 4, rk3026_agc_backup_way),/*0*/ -SOC_ENUM_SINGLE(RK3026_PGAL_AGC_CTL1, RK3026_PGA_AGC_WAY_SFT, 2, rk3026_pga_agc_way),/*1*/ -SOC_ENUM_SINGLE(RK3026_PGAL_AGC_CTL1, RK3026_PGA_AGC_HOLD_T_SFT, 11, rk3026_pga_agc_hold_time),/*2*/ -SOC_ENUM_SINGLE(RK3026_PGAL_AGC_CTL2, RK3026_PGA_AGC_GRU_T_SFT, 11, rk3026_pga_agc_ramp_up_time),/*3*/ -SOC_ENUM_SINGLE(RK3026_PGAL_AGC_CTL2, RK3026_PGA_AGC_GRD_T_SFT, 11, rk3026_pga_agc_ramp_down_time),/*4*/ -SOC_ENUM_SINGLE(RK3026_PGAL_AGC_CTL3, RK3026_PGA_AGC_MODE_SFT, 2, rk3026_pga_agc_mode),/*5*/ -SOC_ENUM_SINGLE(RK3026_PGAL_AGC_CTL3, RK3026_PGA_AGC_ZO_SFT, 2, rk3026_dis_en_sel),/*6*/ -SOC_ENUM_SINGLE(RK3026_PGAL_AGC_CTL3, RK3026_PGA_AGC_REC_MODE_SFT, 2, rk3026_pga_agc_recovery_mode),/*7*/ -SOC_ENUM_SINGLE(RK3026_PGAL_AGC_CTL3, RK3026_PGA_AGC_FAST_D_SFT, 2, rk3026_dis_en_sel),/*8*/ -SOC_ENUM_SINGLE(RK3026_PGAL_AGC_CTL3, RK3026_PGA_AGC_NG_SFT, 2, rk3026_dis_en_sel),/*9*/ -SOC_ENUM_SINGLE(RK3026_PGAL_AGC_CTL3, RK3026_PGA_AGC_NG_THR_SFT, 8, rk3026_pga_agc_noise_gate_threhold),/*10*/ -SOC_ENUM_SINGLE(RK3026_PGAL_AGC_CTL4, RK3026_PGA_AGC_ZO_MODE_SFT, 2, rk3026_pga_agc_update_gain),/*11*/ -SOC_ENUM_SINGLE(RK3026_PGAL_ASR_CTL, RK3026_PGA_SLOW_CLK_SFT, 2, rk3026_dis_en_sel),/*12*/ -SOC_ENUM_SINGLE(RK3026_PGAL_ASR_CTL, RK3026_PGA_ASR_SFT, 8, rk3026_pga_agc_approximate_sample_rate),/*13*/ -SOC_ENUM_SINGLE(RK3026_PGAL_AGC_CTL5, RK3026_PGA_AGC_SFT, 2, rk3026_dis_en_sel),/*14*/ -}; - -static const struct soc_enum rk3026_agcr_enum[] = { -SOC_ENUM_SINGLE(RK3026_PGAR_AGC_CTL1, RK3026_PGA_AGC_BK_WAY_SFT, 4, rk3026_agc_backup_way),/*0*/ -SOC_ENUM_SINGLE(RK3026_PGAR_AGC_CTL1, RK3026_PGA_AGC_WAY_SFT, 2, rk3026_pga_agc_way),/*1*/ -SOC_ENUM_SINGLE(RK3026_PGAR_AGC_CTL1, RK3026_PGA_AGC_HOLD_T_SFT, 11, rk3026_pga_agc_hold_time),/*2*/ -SOC_ENUM_SINGLE(RK3026_PGAR_AGC_CTL2, RK3026_PGA_AGC_GRU_T_SFT, 11, rk3026_pga_agc_ramp_up_time),/*3*/ -SOC_ENUM_SINGLE(RK3026_PGAR_AGC_CTL2, RK3026_PGA_AGC_GRD_T_SFT, 11, rk3026_pga_agc_ramp_down_time),/*4*/ -SOC_ENUM_SINGLE(RK3026_PGAR_AGC_CTL3, RK3026_PGA_AGC_MODE_SFT, 2, rk3026_pga_agc_mode),/*5*/ -SOC_ENUM_SINGLE(RK3026_PGAR_AGC_CTL3, RK3026_PGA_AGC_ZO_SFT, 2, rk3026_dis_en_sel),/*6*/ -SOC_ENUM_SINGLE(RK3026_PGAR_AGC_CTL3, RK3026_PGA_AGC_REC_MODE_SFT, 2, rk3026_pga_agc_recovery_mode),/*7*/ -SOC_ENUM_SINGLE(RK3026_PGAR_AGC_CTL3, RK3026_PGA_AGC_FAST_D_SFT, 2, rk3026_dis_en_sel),/*8*/ -SOC_ENUM_SINGLE(RK3026_PGAR_AGC_CTL3, RK3026_PGA_AGC_NG_SFT, 2, rk3026_dis_en_sel),/*9*/ -SOC_ENUM_SINGLE(RK3026_PGAR_AGC_CTL3, RK3026_PGA_AGC_NG_THR_SFT, 8, rk3026_pga_agc_noise_gate_threhold),/*10*/ -SOC_ENUM_SINGLE(RK3026_PGAR_AGC_CTL4, RK3026_PGA_AGC_ZO_MODE_SFT, 2, rk3026_pga_agc_update_gain),/*11*/ -SOC_ENUM_SINGLE(RK3026_PGAR_ASR_CTL, RK3026_PGA_SLOW_CLK_SFT, 2, rk3026_dis_en_sel),/*12*/ -SOC_ENUM_SINGLE(RK3026_PGAR_ASR_CTL, RK3026_PGA_ASR_SFT, 8, rk3026_pga_agc_approximate_sample_rate),/*13*/ -SOC_ENUM_SINGLE(RK3026_PGAR_AGC_CTL5, RK3026_PGA_AGC_SFT, 2, rk3026_dis_en_sel),/*14*/ -}; - -static const struct snd_kcontrol_new rk3026_snd_controls[] = { - //Add for set voice volume - SOC_DOUBLE_R_TLV("Speaker Playback Volume", RK3026_HPOUTL_GAIN, - RK3026_HPOUTR_GAIN, RK3026_HPOUT_GAIN_SFT, 31, 0, out_vol_tlv), - SOC_DOUBLE("Speaker Playback Switch", RK3026_HPOUT_CTL, - RK3026_HPOUTL_MUTE_SHT, RK3026_HPOUTR_MUTE_SHT, 1, 0), - SOC_DOUBLE_R_TLV("Headphone Playback Volume", RK3026_HPOUTL_GAIN, - RK3026_HPOUTR_GAIN, RK3026_HPOUT_GAIN_SFT, 31, 0, out_vol_tlv), - SOC_DOUBLE("Headphone Playback Switch", RK3026_HPOUT_CTL, - RK3026_HPOUTL_MUTE_SHT, RK3026_HPOUTR_MUTE_SHT, 1, 0), - SOC_DOUBLE_R_TLV("Earpiece Playback Volume", RK3026_HPOUTL_GAIN, - RK3026_HPOUTR_GAIN, RK3026_HPOUT_GAIN_SFT, 31, 0, out_vol_tlv), - SOC_DOUBLE("Earpiece Playback Switch", RK3026_HPOUT_CTL, - RK3026_HPOUTL_MUTE_SHT, RK3026_HPOUTR_MUTE_SHT, 1, 0), - - - //Add for set capture mute - SOC_SINGLE_TLV("Main Mic Capture Volume", RK3026_BST_CTL, - RK3026_BSTL_GAIN_SHT, 1, 0, bst_vol_tlv), - SOC_SINGLE("Main Mic Capture Switch", RK3026_BST_CTL, - RK3026_BSTL_MUTE_SHT, 1, 0), - SOC_SINGLE_TLV("Headset Mic Capture Volume", RK3026_BST_CTL, - RK3026_BSTR_GAIN_SHT, 1, 0, bst_vol_tlv), - SOC_SINGLE("Headset Mic Capture Switch", RK3026_BST_CTL, - RK3026_BSTR_MUTE_SHT, 1, 0), - - SOC_SINGLE("ALCL Switch", RK3026_ALC_MUNIN_CTL, - RK3026_ALCL_MUTE_SHT, 1, 0), - SOC_SINGLE_TLV("ALCL Capture Volume", RK3026_BSTL_ALCL_CTL, - RK3026_ALCL_GAIN_SHT, 31, 0, pga_vol_tlv), - SOC_SINGLE("ALCR Switch", RK3026_ALC_MUNIN_CTL, - RK3026_ALCR_MUTE_SHT, 1, 0), - SOC_SINGLE_TLV("ALCR Capture Volume", RK3026_ALCR_GAIN_CTL, - RK3026_ALCL_GAIN_SHT, 31, 0, pga_vol_tlv), - - SOC_ENUM("BST_L Mode", rk3026_bst_enum[0]), - - SOC_ENUM("Micbias Voltage", rk3026_micbias_enum[0]), - SOC_ENUM("PGAL AGC Back Way", rk3026_agcl_enum[0]), - SOC_ENUM("PGAL AGC Way", rk3026_agcl_enum[1]), - SOC_ENUM("PGAL AGC Hold Time", rk3026_agcl_enum[2]), - SOC_ENUM("PGAL AGC Ramp Up Time", rk3026_agcl_enum[3]), - SOC_ENUM("PGAL AGC Ramp Down Time", rk3026_agcl_enum[4]), - SOC_ENUM("PGAL AGC Mode", rk3026_agcl_enum[5]), - SOC_ENUM("PGAL AGC Gain Update Zero Enable", rk3026_agcl_enum[6]), - SOC_ENUM("PGAL AGC Gain Recovery LPGA VOL", rk3026_agcl_enum[7]), - SOC_ENUM("PGAL AGC Fast Decrement Enable", rk3026_agcl_enum[8]), - SOC_ENUM("PGAL AGC Noise Gate Enable", rk3026_agcl_enum[9]), - SOC_ENUM("PGAL AGC Noise Gate Threhold", rk3026_agcl_enum[10]), - SOC_ENUM("PGAL AGC Upate Gain", rk3026_agcl_enum[11]), - SOC_ENUM("PGAL AGC Slow Clock Enable", rk3026_agcl_enum[12]), - SOC_ENUM("PGAL AGC Approximate Sample Rate", rk3026_agcl_enum[13]), - SOC_ENUM("PGAL AGC Enable", rk3026_agcl_enum[14]), - - SOC_SINGLE_TLV("PGAL AGC Volume", RK3026_PGAL_AGC_CTL4, - RK3026_PGA_AGC_VOL_SFT, 31, 0, pga_vol_tlv),//AGC disable and 0x0a bit 5 is 1 - - SOC_SINGLE("PGAL AGC Max Level High 8 Bits", RK3026_PGAL_AGC_MAX_H, - 0, 255, 0), - SOC_SINGLE("PGAL AGC Max Level Low 8 Bits", RK3026_PGAL_AGC_MAX_L, - 0, 255, 0), - SOC_SINGLE("PGAL AGC Min Level High 8 Bits", RK3026_PGAL_AGC_MIN_H, - 0, 255, 0), - SOC_SINGLE("PGAL AGC Min Level Low 8 Bits", RK3026_PGAL_AGC_MIN_L, - 0, 255, 0), - - SOC_SINGLE_TLV("PGAL AGC Max Gain", RK3026_PGAL_AGC_CTL5, - RK3026_PGA_AGC_MAX_G_SFT, 7, 0, pga_agc_max_vol_tlv),//AGC enable and 0x0a bit 5 is 1 - SOC_SINGLE_TLV("PGAL AGC Min Gain", RK3026_PGAL_AGC_CTL5, - RK3026_PGA_AGC_MIN_G_SFT, 7, 0, pga_agc_min_vol_tlv),//AGC enable and 0x0a bit 5 is 1 - - SOC_ENUM("PGAR AGC Back Way", rk3026_agcr_enum[0]), - SOC_ENUM("PGAR AGC Way", rk3026_agcr_enum[1]), - SOC_ENUM("PGAR AGC Hold Time", rk3026_agcr_enum[2]), - SOC_ENUM("PGAR AGC Ramp Up Time", rk3026_agcr_enum[3]), - SOC_ENUM("PGAR AGC Ramp Down Time", rk3026_agcr_enum[4]), - SOC_ENUM("PGAR AGC Mode", rk3026_agcr_enum[5]), - SOC_ENUM("PGAR AGC Gain Update Zero Enable", rk3026_agcr_enum[6]), - SOC_ENUM("PGAR AGC Gain Recovery LPGA VOL", rk3026_agcr_enum[7]), - SOC_ENUM("PGAR AGC Fast Decrement Enable", rk3026_agcr_enum[8]), - SOC_ENUM("PGAR AGC Noise Gate Enable", rk3026_agcr_enum[9]), - SOC_ENUM("PGAR AGC Noise Gate Threhold", rk3026_agcr_enum[10]), - SOC_ENUM("PGAR AGC Upate Gain", rk3026_agcr_enum[11]), - SOC_ENUM("PGAR AGC Slow Clock Enable", rk3026_agcr_enum[12]), - SOC_ENUM("PGAR AGC Approximate Sample Rate", rk3026_agcr_enum[13]), - SOC_ENUM("PGAR AGC Enable", rk3026_agcr_enum[14]), - - SOC_SINGLE_TLV("PGAR AGC Volume", RK3026_PGAR_AGC_CTL4, - RK3026_PGA_AGC_VOL_SFT, 31, 0, pga_vol_tlv),//AGC disable and 0x0a bit 4 is 1 - - SOC_SINGLE("PGAR AGC Max Level High 8 Bits", RK3026_PGAR_AGC_MAX_H, - 0, 255, 0), - SOC_SINGLE("PGAR AGC Max Level Low 8 Bits", RK3026_PGAR_AGC_MAX_L, - 0, 255, 0), - SOC_SINGLE("PGAR AGC Min Level High 8 Bits", RK3026_PGAR_AGC_MIN_H, - 0, 255, 0), - SOC_SINGLE("PGAR AGC Min Level Low 8 Bits", RK3026_PGAR_AGC_MIN_L, - 0, 255, 0), - - SOC_SINGLE_TLV("PGAR AGC Max Gain", RK3026_PGAR_AGC_CTL5, - RK3026_PGA_AGC_MAX_G_SFT, 7, 0, pga_agc_max_vol_tlv),//AGC enable and 0x06 bit 4 is 1 - SOC_SINGLE_TLV("PGAR AGC Min Gain", RK3026_PGAR_AGC_CTL5, - RK3026_PGA_AGC_MIN_G_SFT, 7, 0, pga_agc_min_vol_tlv),//AGC enable and 0x06 bit 4 is 1 - -}; - -//For tiny alsa playback/capture/voice call path -static const char *rk3026_playback_path_mode[] = {"OFF", "RCV", "SPK", "HP", "HP_NO_MIC", "BT", "SPK_HP", //0-6 - "RING_SPK", "RING_HP", "RING_HP_NO_MIC", "RING_SPK_HP"};//7-10 - -static const char *rk3026_capture_path_mode[] = {"MIC OFF", "Main Mic", "Hands Free Mic", "BT Sco Mic"}; - -static const char *rk3026_voice_call_path_mode[] = {"OFF", "RCV", "SPK", "HP", "HP_NO_MIC", "BT"};//0-5 - -static const SOC_ENUM_SINGLE_DECL(rk3026_playback_path_type, 0, 0, rk3026_playback_path_mode); - -static const SOC_ENUM_SINGLE_DECL(rk3026_capture_path_type, 0, 0, rk3026_capture_path_mode); - -static const SOC_ENUM_SINGLE_DECL(rk3026_voice_call_path_type, 0, 0, rk3026_voice_call_path_mode); - -static int rk3026_codec_power_up(int type); -static int rk3026_codec_power_down(int type); - -static int rk3026_playback_path_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - if (!rk3026_priv) { - printk("%s : rk3026_priv is NULL\n", __func__); - return -EINVAL; - } - - DBG("%s : playback_path = %ld\n",__func__,ucontrol->value.integer.value[0]); - - ucontrol->value.integer.value[0] = rk3026_priv->playback_path; - - return 0; -} - -static int rk3026_playback_path_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - long int pre_path; - - if (!rk3026_priv) { - printk("%s : rk3026_priv is NULL\n", __func__); - return -EINVAL; - } - - if (rk3026_priv->playback_path == ucontrol->value.integer.value[0]){ - printk("%s : playback_path is not changed!\n",__func__); - return 0; - } - - pre_path = rk3026_priv->playback_path; - rk3026_priv->playback_path = ucontrol->value.integer.value[0]; - - DBG("%s : set playback_path = %ld\n", __func__, - rk3026_priv->playback_path); - - switch (rk3026_priv->playback_path) { - case OFF: - if (pre_path != OFF) - rk3026_codec_power_down(RK3026_CODEC_PLAYBACK); - break; - case RCV: - break; - case SPK_PATH: - case RING_SPK: - if (pre_path == OFF) - rk3026_codec_power_up(RK3026_CODEC_PLAYBACK); - break; - case HP_PATH: - case HP_NO_MIC: - case RING_HP: - case RING_HP_NO_MIC: - if (pre_path == OFF) - rk3026_codec_power_up(RK3026_CODEC_PLAYBACK); - break; - case BT: - break; - case SPK_HP: - case RING_SPK_HP: - if (pre_path == OFF) - rk3026_codec_power_up(RK3026_CODEC_PLAYBACK); - break; - default: - return -EINVAL; - } - - return 0; -} - -static int rk3026_capture_path_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - if (!rk3026_priv) { - printk("%s : rk3026_priv is NULL\n", __func__); - return -EINVAL; - } - - DBG("%s : capture_path = %ld\n", __func__, - ucontrol->value.integer.value[0]); - - ucontrol->value.integer.value[0] = rk3026_priv->capture_path; - - return 0; -} - -static int rk3026_capture_path_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - long int pre_path; - - if (!rk3026_priv) { - printk("%s : rk3026_priv is NULL\n", __func__); - return -EINVAL; - } - - if (rk3026_priv->capture_path == ucontrol->value.integer.value[0]){ - printk("%s : capture_path is not changed!\n", __func__); - //return 0; - } - - pre_path = rk3026_priv->capture_path; - rk3026_priv->capture_path = ucontrol->value.integer.value[0]; - - DBG("%s : set capture_path = %ld\n", __func__, rk3026_priv->capture_path); - - switch (rk3026_priv->capture_path) { - case MIC_OFF: - if (pre_path != MIC_OFF) - rk3026_codec_power_down(RK3026_CODEC_CAPTURE); - break; - case Main_Mic: - if (pre_path == MIC_OFF) - rk3026_codec_power_up(RK3026_CODEC_CAPTURE); - break; - case Hands_Free_Mic: - if (pre_path == MIC_OFF) - rk3026_codec_power_up(RK3026_CODEC_CAPTURE); - break; - case BT_Sco_Mic: - break; - - default: - return -EINVAL; - } - - return 0; -} - -static int rk3026_voice_call_path_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - if (!rk3026_priv) { - printk("%s : rk3026_priv is NULL\n", __func__); - return -EINVAL; - } - - DBG("%s : playback_path = %ld\n", __func__, - ucontrol->value.integer.value[0]); - - ucontrol->value.integer.value[0] = rk3026_priv->voice_call_path; - - return 0; -} - -static int rk3026_voice_call_path_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - long int pre_path; - - if (!rk3026_priv) { - printk("%s : rk3026_priv is NULL\n", __func__); - return -EINVAL; - } - - if (rk3026_priv->voice_call_path == ucontrol->value.integer.value[0]){ - printk("%s : playback_path is not changed!\n",__func__); - //return 0; - } - - pre_path = rk3026_priv->voice_call_path; - rk3026_priv->voice_call_path = ucontrol->value.integer.value[0]; - - DBG("%s : set playback_path = %ld\n", __func__, - rk3026_priv->voice_call_path); - - //open playback route for incall route and keytone - if (pre_path == OFF) { - if (rk3026_priv->playback_path != OFF) { - //mute output for incall route pop nosie - mdelay(100); - } else - rk3026_codec_power_up(RK3026_CODEC_PLAYBACK); - } - - switch (rk3026_priv->voice_call_path) { - case OFF: - if (pre_path != MIC_OFF) - rk3026_codec_power_down(RK3026_CODEC_CAPTURE); - break; - case RCV: - break; - case SPK_PATH: - //open incall route - if (pre_path == OFF || pre_path == RCV || pre_path == BT) - rk3026_codec_power_up(RK3026_CODEC_INCALL); - - break; - case HP_PATH: - case HP_NO_MIC: - //open incall route - if (pre_path == OFF || pre_path == RCV || pre_path == BT) - rk3026_codec_power_up(RK3026_CODEC_INCALL); - break; - case BT: - break; - default: - return -EINVAL; - } - - return 0; -} - -static const struct snd_kcontrol_new rk3026_snd_path_controls[] = { - SOC_ENUM_EXT("Playback Path", rk3026_playback_path_type, - rk3026_playback_path_get, rk3026_playback_path_put), - - SOC_ENUM_EXT("Capture MIC Path", rk3026_capture_path_type, - rk3026_capture_path_get, rk3026_capture_path_put), - - SOC_ENUM_EXT("Voice Call Path", rk3026_voice_call_path_type, - rk3026_voice_call_path_get, rk3026_voice_call_path_put), -}; - -static int rk3026_dacl_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = w->codec; - - switch (event) { - case SND_SOC_DAPM_POST_PMU: - snd_soc_update_bits(codec, RK3026_DAC_ENABLE, - RK3026_DACL_WORK,0); - snd_soc_update_bits(codec, RK3026_DAC_ENABLE, - RK3026_DACL_EN | RK3026_DACL_CLK_EN, - RK3026_DACL_EN | RK3026_DACL_CLK_EN); - snd_soc_update_bits(codec, RK3026_DAC_ENABLE, - RK3026_DACL_WORK, RK3026_DACL_WORK); - break; - - case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, RK3026_DAC_ENABLE, - RK3026_DACL_EN | RK3026_DACL_CLK_EN,0); - snd_soc_update_bits(codec, RK3026_DAC_ENABLE, - RK3026_DACL_WORK, 0); - break; - - default: - return 0; - } - - return 0; -} - -static int rk3026_dacr_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = w->codec; - - switch (event) { - case SND_SOC_DAPM_POST_PMU: - snd_soc_update_bits(codec, RK3026_DAC_ENABLE, - RK3026_DACR_WORK,0); - snd_soc_update_bits(codec, RK3026_DAC_ENABLE, - RK3026_DACR_EN | RK3026_DACR_CLK_EN, - RK3026_DACR_EN | RK3026_DACR_CLK_EN); - snd_soc_update_bits(codec, RK3026_DAC_ENABLE, - RK3026_DACR_WORK, RK3026_DACR_WORK); - break; - - case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, RK3026_DAC_ENABLE, - RK3026_DACR_EN | RK3026_DACR_CLK_EN,0); - snd_soc_update_bits(codec, RK3026_DAC_ENABLE, - RK3026_DACR_WORK, 0); - break; - - default: - return 0; - } - - return 0; -} - -static int rk3026_adcl_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = w->codec; - - switch (event) { - case SND_SOC_DAPM_POST_PMU: - snd_soc_update_bits(codec, RK3026_ADC_ENABLE, - RK3026_ADCL_CLK_EN_SFT | RK3026_ADCL_AMP_EN_SFT, - RK3026_ADCL_CLK_EN | RK3026_ADCL_AMP_EN); - break; - - case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, RK3026_ADC_ENABLE, - RK3026_ADCL_CLK_EN_SFT | RK3026_ADCL_AMP_EN_SFT,0); - break; - - default: - return 0; - } - - return 0; -} - -static int rk3026_adcr_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = w->codec; - - switch (event) { - case SND_SOC_DAPM_POST_PMU: - snd_soc_update_bits(codec, RK3026_ADC_ENABLE, - RK3026_ADCR_CLK_EN_SFT | RK3026_ADCR_AMP_EN_SFT, - RK3026_ADCR_CLK_EN | RK3026_ADCR_AMP_EN ); - break; - - case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, RK3026_ADC_ENABLE, - RK3026_ADCR_CLK_EN_SFT | RK3026_ADCR_AMP_EN_SFT,0); - break; - - default: - return 0; - } - - return 0; -} - -/* HPmix */ -static const struct snd_kcontrol_new rk3026_hpmixl[] = { - SOC_DAPM_SINGLE("ALCR Switch", RK3026_HPMIX_S_SELECT, - RK3026_HPMIXL_SEL_ALCR_SFT, 1, 0), - SOC_DAPM_SINGLE("ALCL Switch", RK3026_HPMIX_S_SELECT, - RK3026_HPMIXL_SEL_ALCL_SFT, 1, 0), - SOC_DAPM_SINGLE("DACL Switch", RK3026_HPMIX_S_SELECT, - RK3026_HPMIXL_SEL_DACL_SFT, 1, 0), -}; - -static const struct snd_kcontrol_new rk3026_hpmixr[] = { - SOC_DAPM_SINGLE("ALCR Switch", RK3026_HPMIX_S_SELECT, - RK3026_HPMIXR_SEL_ALCR_SFT, 1, 0), - SOC_DAPM_SINGLE("ALCL Switch", RK3026_HPMIX_S_SELECT, - RK3026_HPMIXR_SEL_ALCL_SFT, 1, 0), - SOC_DAPM_SINGLE("DACR Switch", RK3026_HPMIX_S_SELECT, - RK3026_HPMIXR_SEL_DACR_SFT, 1, 0), -}; - -static int rk3026_hpmixl_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = w->codec; - - switch (event) { - case SND_SOC_DAPM_POST_PMU: - snd_soc_update_bits(codec, RK3026_DAC_CTL, - RK3026_ZO_DET_VOUTR_SFT, RK3026_ZO_DET_VOUTR_EN); - snd_soc_update_bits(codec, RK3026_DAC_CTL, - RK3026_ZO_DET_VOUTL_SFT, RK3026_ZO_DET_VOUTL_EN); - break; - - case SND_SOC_DAPM_PRE_PMD: - snd_soc_update_bits(codec, RK3026_DAC_CTL, - RK3026_ZO_DET_VOUTR_SFT, RK3026_ZO_DET_VOUTR_DIS); - snd_soc_update_bits(codec, RK3026_DAC_CTL, - RK3026_ZO_DET_VOUTL_SFT, RK3026_ZO_DET_VOUTL_DIS); - break; - - default: - return 0; - } - - return 0; -} - -static int rk3026_hpmixr_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = w->codec; -#if 0 - switch (event) { - case SND_SOC_DAPM_POST_PMU: - snd_soc_update_bits(codec, RK3026_HPMIX_CTL, - RK3026_HPMIXR_WORK2, RK3026_HPMIXR_WORK2); - break; - - case SND_SOC_DAPM_PRE_PMD: - snd_soc_update_bits(codec, RK3026_HPMIX_CTL, - RK3026_HPMIXR_WORK2, 0); - break; - - default: - return 0; - } -#endif - return 0; -} - -/* HP MUX */ - -static const char *hpl_sel[] = {"HPMIXL", "DACL"}; - -static const struct soc_enum hpl_sel_enum = - SOC_ENUM_SINGLE(RK3026_HPMIX_S_SELECT, RK3026_HPMIXL_BYPASS_SFT, - ARRAY_SIZE(hpl_sel), hpl_sel); - -static const struct snd_kcontrol_new hpl_sel_mux = - SOC_DAPM_ENUM("HPL select Mux", hpl_sel_enum); - -static const char *hpr_sel[] = {"HPMIXR", "DACR"}; - -static const struct soc_enum hpr_sel_enum = - SOC_ENUM_SINGLE(RK3026_HPMIX_S_SELECT, RK3026_HPMIXR_BYPASS_SFT, - ARRAY_SIZE(hpr_sel), hpr_sel); - -static const struct snd_kcontrol_new hpr_sel_mux = - SOC_DAPM_ENUM("HPR select Mux", hpr_sel_enum); - -/* IN_L MUX */ -static const char *lnl_sel[] = {"NO","BSTL", "LINEL","NOUSE"}; - -static const struct soc_enum lnl_sel_enum = - SOC_ENUM_SINGLE(RK3026_ALC_MUNIN_CTL, RK3026_MUXINL_F_SHT, - ARRAY_SIZE(lnl_sel), lnl_sel); - -static const struct snd_kcontrol_new lnl_sel_mux = - SOC_DAPM_ENUM("MUXIN_L select", lnl_sel_enum); - -/* IN_R MUX */ -static const char *lnr_sel[] = {"NO","BSTR", "LINER","NOUSE"}; - -static const struct soc_enum lnr_sel_enum = - SOC_ENUM_SINGLE(RK3026_ALC_MUNIN_CTL, RK3026_MUXINR_F_SHT, - ARRAY_SIZE(lnr_sel), lnr_sel); - -static const struct snd_kcontrol_new lnr_sel_mux = - SOC_DAPM_ENUM("MUXIN_R select", lnr_sel_enum); - - -static const struct snd_soc_dapm_widget rk3026_dapm_widgets[] = { - - /* microphone bias */ - SND_SOC_DAPM_MICBIAS("Mic Bias", RK3026_ADC_MIC_CTL, - RK3026_MICBIAS_VOL_ENABLE, 0), - - /* DACs */ - SND_SOC_DAPM_DAC_E("DACL", NULL, SND_SOC_NOPM, - 0, 0, rk3026_dacl_event, - SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU), - SND_SOC_DAPM_DAC_E("DACR", NULL, SND_SOC_NOPM, - 0, 0, rk3026_dacr_event, - SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU), - - /* ADCs */ - SND_SOC_DAPM_ADC_E("ADCL", NULL, SND_SOC_NOPM, - 0, 0, rk3026_adcl_event, - SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU), - SND_SOC_DAPM_ADC_E("ADCR", NULL, SND_SOC_NOPM, - 0, 0, rk3026_adcr_event, - SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU), - - /* PGA */ - SND_SOC_DAPM_PGA("BSTL", RK3026_BST_CTL, - RK3026_BSTL_PWRD_SFT, 0, NULL, 0), - SND_SOC_DAPM_PGA("BSTR", RK3026_BST_CTL, - RK3026_BSTR_PWRD_SFT, 0, NULL, 0), - SND_SOC_DAPM_PGA("ALCL", RK3026_ALC_MUNIN_CTL, - RK3026_ALCL_PWR_SHT , 0, NULL, 0), - SND_SOC_DAPM_PGA("ALCR", RK3026_ALC_MUNIN_CTL, - RK3026_ALCR_PWR_SHT , 0, NULL, 0), - SND_SOC_DAPM_PGA("HPL", RK3026_HPOUT_CTL, - RK3026_HPOUTL_PWR_SHT, 0, NULL, 0), - SND_SOC_DAPM_PGA("HPR", RK3026_HPOUT_CTL, - RK3026_HPOUTR_PWR_SHT, 0, NULL, 0), - - /* MIXER */ - SND_SOC_DAPM_MIXER_E("HPMIXL", RK3026_HPMIX_CTL, - RK3026_HPMIXL_SFT, 0, rk3026_hpmixl, - ARRAY_SIZE(rk3026_hpmixl),rk3026_hpmixl_event, - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), - SND_SOC_DAPM_MIXER_E("HPMIXR", RK3026_HPMIX_CTL, - RK3026_HPMIXR_SFT, 0, rk3026_hpmixr, - ARRAY_SIZE(rk3026_hpmixr),rk3026_hpmixr_event, - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), - - /* MUX */ - SND_SOC_DAPM_MUX("IN_R Mux", SND_SOC_NOPM, 0, 0, - &lnr_sel_mux), - SND_SOC_DAPM_MUX("IN_L Mux", SND_SOC_NOPM, 0, 0, - &lnl_sel_mux), - SND_SOC_DAPM_MUX("HPL Mux", SND_SOC_NOPM, 0, 0, - &hpl_sel_mux), - SND_SOC_DAPM_MUX("HPR Mux", SND_SOC_NOPM, 0, 0, - &hpr_sel_mux), - - /* Audio Interface */ - SND_SOC_DAPM_AIF_IN("I2S DAC", "HiFi Playback", 0, - SND_SOC_NOPM, 0, 0), - SND_SOC_DAPM_AIF_OUT("I2S ADC", "HiFi Capture", 0, - SND_SOC_NOPM, 0, 0), - - /* Input */ - SND_SOC_DAPM_INPUT("LINEL"), - SND_SOC_DAPM_INPUT("LINER"), - SND_SOC_DAPM_INPUT("MICP"), - SND_SOC_DAPM_INPUT("MICN"), - - /* Output */ - SND_SOC_DAPM_OUTPUT("HPOUTL"), - SND_SOC_DAPM_OUTPUT("HPOUTR"), - -}; - -static const struct snd_soc_dapm_route rk3026_dapm_routes[] = { - /* Input */ - {"BSTR", NULL, "MICP"}, - {"BSTL", NULL, "MICP"}, - {"BSTL", NULL, "MICN"}, - - {"IN_R Mux", "LINER", "LINER"}, - {"IN_R Mux", "BSTR", "BSTR"}, - {"IN_L Mux", "LINEL", "LINEL"}, - {"IN_L Mux", "BSTL", "BSTL"}, - - {"ALCL", NULL, "IN_L Mux"}, - {"ALCR", NULL, "IN_R Mux"}, - - - {"ADCR", NULL, "ALCR"}, - {"ADCL", NULL, "ALCL"}, - - {"I2S ADC", NULL, "ADCR"}, - {"I2S ADC", NULL, "ADCL"}, - - /* Output */ - - {"DACR", NULL, "I2S DAC"}, - {"DACL", NULL, "I2S DAC"}, - - {"HPMIXR", "ALCR Switch", "ALCR"}, - {"HPMIXR", "ALCL Switch", "ALCL"}, - {"HPMIXR", "DACR Switch", "DACR"}, - - {"HPMIXL", "ALCR Switch", "ALCR"}, - {"HPMIXL", "ALCL Switch", "ALCL"}, - {"HPMIXL", "DACL Switch", "DACL"}, - - - {"HPR Mux", "DACR", "DACR"}, - {"HPR Mux", "HPMIXR", "HPMIXR"}, - {"HPL Mux", "DACL", "DACL"}, - {"HPL Mux", "HPMIXL", "HPMIXL"}, - - {"HPR", NULL, "HPR Mux"}, - {"HPL", NULL, "HPL Mux"}, - - {"HPOUTR", NULL, "HPR"}, - {"HPOUTL", NULL, "HPL"}, -}; - -static int rk3026_set_bias_level(struct snd_soc_codec *codec, - enum snd_soc_bias_level level) -{ - DBG("%s level=%d\n",__func__,level); - - switch (level) { - case SND_SOC_BIAS_ON: - break; - - case SND_SOC_BIAS_PREPARE: - break; - - case SND_SOC_BIAS_STANDBY: - if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { - writel(0x32, rk3026_priv->regbase+RK3026_DAC_INT_CTL3); - snd_soc_update_bits(codec, RK3026_ADC_MIC_CTL, - RK3026_ADC_CURRENT_ENABLE, RK3026_ADC_CURRENT_ENABLE); - snd_soc_update_bits(codec, RK3026_DAC_CTL, - RK3026_CURRENT_EN, RK3026_CURRENT_EN); - /* set power */ - snd_soc_update_bits(codec, RK3026_ADC_ENABLE, - RK3026_ADCL_REF_VOL_EN_SFT | RK3026_ADCR_REF_VOL_EN_SFT, - RK3026_ADCL_REF_VOL_EN | RK3026_ADCR_REF_VOL_EN); - - snd_soc_update_bits(codec, RK3026_ADC_MIC_CTL, - RK3026_ADCL_ZERO_DET_EN_SFT | RK3026_ADCR_ZERO_DET_EN_SFT, - RK3026_ADCL_ZERO_DET_EN | RK3026_ADCR_ZERO_DET_EN); - - snd_soc_update_bits(codec, RK3026_DAC_CTL, - RK3026_REF_VOL_DACL_EN_SFT | RK3026_REF_VOL_DACR_EN_SFT, - RK3026_REF_VOL_DACL_EN | RK3026_REF_VOL_DACR_EN ); - - snd_soc_update_bits(codec, RK3026_DAC_ENABLE, - RK3026_DACL_REF_VOL_EN_SFT | RK3026_DACR_REF_VOL_EN_SFT, - RK3026_DACL_REF_VOL_EN | RK3026_DACR_REF_VOL_EN ); - } - break; - - case SND_SOC_BIAS_OFF: - snd_soc_update_bits(codec, RK3026_DAC_ENABLE, - RK3026_DACL_REF_VOL_EN_SFT | RK3026_DACR_REF_VOL_EN_SFT,0); - snd_soc_update_bits(codec, RK3026_DAC_CTL, - RK3026_REF_VOL_DACL_EN_SFT | RK3026_REF_VOL_DACR_EN_SFT,0); - snd_soc_update_bits(codec, RK3026_ADC_MIC_CTL, - RK3026_ADCL_ZERO_DET_EN_SFT | RK3026_ADCR_ZERO_DET_EN_SFT,0); - snd_soc_update_bits(codec, RK3026_ADC_ENABLE, - RK3026_ADCL_REF_VOL_EN_SFT | RK3026_ADCR_REF_VOL_EN_SFT,0); - snd_soc_update_bits(codec, RK3026_ADC_MIC_CTL, - RK3026_ADC_CURRENT_ENABLE, 0); - snd_soc_update_bits(codec, RK3026_DAC_CTL, - RK3026_CURRENT_EN, 0); - writel(0x22, rk3026_priv->regbase+RK3026_DAC_INT_CTL3); - break; - } - codec->dapm.bias_level = level; - - return 0; -} - -static int rk3026_set_dai_sysclk(struct snd_soc_dai *codec_dai, - int clk_id, unsigned int freq, int dir) -{ - struct rk3026_codec_priv *rk3026 = rk3026_priv; - - if (!rk3026) { - printk("%s : rk3026 is NULL\n", __func__); - return -EINVAL; - } - - rk3026->stereo_sysclk = freq; - - return 0; -} - -static int rk3026_set_dai_fmt(struct snd_soc_dai *codec_dai, - unsigned int fmt) -{ - struct snd_soc_codec *codec = codec_dai->codec; - unsigned int adc_aif1 = 0, adc_aif2 = 0, dac_aif1 = 0, dac_aif2 = 0; - - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: - adc_aif2 |= RK3026_I2S_MODE_SLV; - break; - case SND_SOC_DAIFMT_CBM_CFM: - adc_aif2 |= RK3026_I2S_MODE_MST; - break; - default: - printk("%s : set master mask failed!\n", __func__); - return -EINVAL; - } - - switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_DSP_A: - adc_aif1 |= RK3026_ADC_DF_PCM; - dac_aif1 |= RK3026_DAC_DF_PCM; - break; - case SND_SOC_DAIFMT_DSP_B: - break; - case SND_SOC_DAIFMT_I2S: - adc_aif1 |= RK3026_ADC_DF_I2S; - dac_aif1 |= RK3026_DAC_DF_I2S; - break; - case SND_SOC_DAIFMT_RIGHT_J: - adc_aif1 |= RK3026_ADC_DF_RJ; - dac_aif1 |= RK3026_DAC_DF_RJ; - break; - case SND_SOC_DAIFMT_LEFT_J: - adc_aif1 |= RK3026_ADC_DF_LJ; - dac_aif1 |= RK3026_DAC_DF_LJ; - break; - default: - printk("%s : set format failed!\n", __func__); - return -EINVAL; - } - - switch (fmt & SND_SOC_DAIFMT_INV_MASK) { - case SND_SOC_DAIFMT_NB_NF: - adc_aif1 |= RK3026_ALRCK_POL_DIS; - adc_aif2 |= RK3026_ABCLK_POL_DIS; - dac_aif1 |= RK3026_DLRCK_POL_DIS; - dac_aif2 |= RK3026_DBCLK_POL_DIS; - break; - case SND_SOC_DAIFMT_IB_IF: - adc_aif1 |= RK3026_ALRCK_POL_EN; - adc_aif2 |= RK3026_ABCLK_POL_EN; - dac_aif1 |= RK3026_DLRCK_POL_EN; - dac_aif2 |= RK3026_DBCLK_POL_EN; - break; - case SND_SOC_DAIFMT_IB_NF: - adc_aif1 |= RK3026_ALRCK_POL_DIS; - adc_aif2 |= RK3026_ABCLK_POL_EN; - dac_aif1 |= RK3026_DLRCK_POL_DIS; - dac_aif2 |= RK3026_DBCLK_POL_EN; - break; - case SND_SOC_DAIFMT_NB_IF: - adc_aif1 |= RK3026_ALRCK_POL_EN; - adc_aif2 |= RK3026_ABCLK_POL_DIS; - dac_aif1 |= RK3026_DLRCK_POL_EN; - dac_aif2 |= RK3026_DBCLK_POL_DIS; - break; - default: - printk("%s : set dai format failed!\n", __func__); - return -EINVAL; - } - - snd_soc_update_bits(codec, RK3026_ADC_INT_CTL1, - RK3026_ALRCK_POL_MASK | RK3026_ADC_DF_MASK, adc_aif1); - snd_soc_update_bits(codec, RK3026_ADC_INT_CTL2, - RK3026_ABCLK_POL_MASK | RK3026_I2S_MODE_MASK, adc_aif2); - snd_soc_update_bits(codec, RK3026_DAC_INT_CTL1, - RK3026_DLRCK_POL_MASK | RK3026_DAC_DF_MASK, dac_aif1); - snd_soc_update_bits(codec, RK3026_DAC_INT_CTL2, - RK3026_DBCLK_POL_MASK, dac_aif2); - - return 0; -} - -static int rk3026_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec *codec =rtd->codec; - struct rk3026_codec_priv *rk3026 = rk3026_priv; - unsigned int rate = params_rate(params); - unsigned int div; - unsigned int adc_aif1 = 0, adc_aif2 = 0, dac_aif1 = 0, dac_aif2 = 0; - - if (!rk3026) { - printk("%s : rk3026 is NULL\n", __func__); - return -EINVAL; - } - - // bclk = codec_clk / 4 - // lrck = bclk / (wl * 2) - div = (((rk3026->stereo_sysclk / 4) / rate) / 2); - - if ((rk3026->stereo_sysclk % (4 * rate * 2) > 0) || - (div != 16 && div != 20 && div != 24 && div != 32)) { - printk("%s : need PLL\n", __func__); - return -EINVAL; - } - - switch (div) { - case 16: - adc_aif2 |= RK3026_ADC_WL_16; - dac_aif2 |= RK3026_DAC_WL_16; - break; - case 20: - adc_aif2 |= RK3026_ADC_WL_20; - dac_aif2 |= RK3026_DAC_WL_20; - break; - case 24: - adc_aif2 |= RK3026_ADC_WL_24; - dac_aif2 |= RK3026_DAC_WL_24; - break; - case 32: - adc_aif2 |= RK3026_ADC_WL_32; - dac_aif2 |= RK3026_DAC_WL_32; - break; - default: - return -EINVAL; - } - - - DBG("%s : MCLK = %dHz, sample rate = %dHz, div = %d\n", __func__, - rk3026->stereo_sysclk, rate, div); - - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: - adc_aif1 |= RK3026_ADC_VWL_16; - dac_aif1 |= RK3026_DAC_VWL_16; - break; - case SNDRV_PCM_FORMAT_S20_3LE: - adc_aif1 |= RK3026_ADC_VWL_20; - dac_aif1 |= RK3026_DAC_VWL_20; - break; - case SNDRV_PCM_FORMAT_S24_LE: - adc_aif1 |= RK3026_ADC_VWL_24; - dac_aif1 |= RK3026_DAC_VWL_24; - break; - case SNDRV_PCM_FORMAT_S32_LE: - adc_aif1 |= RK3026_ADC_VWL_32; - dac_aif1 |= RK3026_DAC_VWL_32; - break; - default: - return -EINVAL; - } - - switch (params_channels(params)) { - case RK3026_MONO: - adc_aif1 |= RK3026_ADC_TYPE_MONO; - break; - case RK3026_STEREO: - adc_aif1 |= RK3026_ADC_TYPE_STEREO; - break; - default: - return -EINVAL; - } - - adc_aif1 |= RK3026_ADC_SWAP_DIS; - adc_aif2 |= RK3026_ADC_RST_DIS; - dac_aif1 |= RK3026_DAC_SWAP_DIS; - dac_aif2 |= RK3026_DAC_RST_DIS; - - rk3026->rate = rate; - - snd_soc_update_bits(codec, RK3026_ADC_INT_CTL1, - RK3026_ADC_VWL_MASK | RK3026_ADC_SWAP_MASK | - RK3026_ADC_TYPE_MASK, adc_aif1); - snd_soc_update_bits(codec, RK3026_ADC_INT_CTL2, - RK3026_ADC_WL_MASK | RK3026_ADC_RST_MASK, adc_aif2); - snd_soc_update_bits(codec, RK3026_DAC_INT_CTL1, - RK3026_DAC_VWL_MASK | RK3026_DAC_SWAP_MASK, dac_aif1); - snd_soc_update_bits(codec, RK3026_DAC_INT_CTL2, - RK3026_DAC_WL_MASK | RK3026_DAC_RST_MASK, dac_aif2); - - return 0; -} - -static int rk3026_digital_mute(struct snd_soc_dai *dai, int mute) -{ - struct snd_soc_codec *codec = dai->codec; - unsigned int is_hp_pd; - - - is_hp_pd = (RK3026_HPOUTL_MSK | RK3026_HPOUTR_MSK) & snd_soc_read(codec, RK3026_HPOUT_CTL); - - if (mute) { - if (rk3026_priv && rk3026_priv->hp_ctl_gpio != INVALID_GPIO && - is_hp_pd) { - DBG("%s : set hp ctl gpio LOW\n", __func__); - gpio_set_value(rk3026_priv->hp_ctl_gpio, GPIO_LOW); - msleep(200);//rk3026_priv->delay_time); - } - - } else { - if (rk3026_priv && rk3026_priv->hp_ctl_gpio != INVALID_GPIO && - is_hp_pd) { - DBG("%s : set hp ctl gpio HIGH\n", __func__); - gpio_set_value(rk3026_priv->hp_ctl_gpio, GPIO_HIGH); - msleep(100);//rk3026_priv->delay_time); - } - } - return 0; -} - -static struct rk3026_reg_val_typ playback_power_up_list[] = { - {0x18,0x32}, - {0xa0,0x40}, - {0xa0,0x62}, - {0xa4,0x88}, - {0xa4,0xcc}, - {0xa4,0xee}, - {0xa8,0x44}, - {0xb0,0x92}, - {0xb0,0xdb}, - {0xac,0x11},//DAC - {0xa8,0x55}, - {0xa8,0x77}, - {0xa4,0xff}, - {0xb0,0xff}, - {0xa0,0x73}, - {0xb4,OUT_VOLUME}, - {0xb8,OUT_VOLUME}, -}; -#define RK3026_CODEC_PLAYBACK_POWER_UP_LIST_LEN ARRAY_SIZE(playback_power_up_list) - -static struct rk3026_reg_val_typ playback_power_down_list[] = { - {0xb0,0xdb}, - {0xa8,0x44}, - {0xac,0x00}, - {0xb0,0x92}, - {0xa0,0x22}, - {0xb0,0x00}, - {0xa8,0x00}, - {0xa4,0x00}, - {0xa0,0x00}, - {0x18,0x22}, -#ifdef WITH_CAP - //{0xbc,0x08}, -#endif - {0xb4,0x0}, - {0xb8,0x0}, - {0x18,0x22}, -}; -#define RK3026_CODEC_PLAYBACK_POWER_DOWN_LIST_LEN ARRAY_SIZE(playback_power_down_list) - -static struct rk3026_reg_val_typ capture_power_up_list[] = { - {0x88, 0x80}, - {0x88, 0xc0}, - {0x88, 0xc7}, - {0x9c, 0x88}, - {0x8c, 0x04}, - {0x90, 0x66}, - {0x9c, 0xcc}, - {0x9c, 0xee}, - {0x8c, 0x07}, - {0x90, 0x77}, - {0x94, 0x20 | CAP_VOL}, - {0x98, CAP_VOL}, - {0x88, 0xf7}, - -}; -#define RK3026_CODEC_CAPTURE_POWER_UP_LIST_LEN ARRAY_SIZE(capture_power_up_list) - -static struct rk3026_reg_val_typ capture_power_down_list[] = { - {0x9c, 0xcc}, - {0x90, 0x66}, - {0x8c, 0x44}, - {0x9c, 0x88}, - {0x88, 0xc7}, - {0x88, 0xc0}, - {0x88, 0x80}, - {0x8c, 0x00}, - {0X94, 0x0c}, - {0X98, 0x0c}, - {0x9c, 0x00}, - {0x88, 0x00}, - {0x90, 0x44}, -}; -#define RK3026_CODEC_CAPTURE_POWER_DOWN_LIST_LEN ARRAY_SIZE(capture_power_down_list) - -static int rk3026_codec_power_up(int type) -{ - struct snd_soc_codec *codec = rk3026_priv->codec; - int i; - - if (!rk3026_priv || !rk3026_priv->codec) { - printk("%s : rk3026_priv or rk3026_priv->codec is NULL\n", __func__); - return -EINVAL; - } - - printk("%s : power up %s%s\n", __func__, - type == RK3026_CODEC_PLAYBACK ? "playback" : "", - type == RK3026_CODEC_CAPTURE ? "capture" : ""); - - if (type == RK3026_CODEC_PLAYBACK) { - for (i = 0; i < RK3026_CODEC_PLAYBACK_POWER_UP_LIST_LEN; i++) { - snd_soc_write(codec, playback_power_up_list[i].reg, - playback_power_up_list[i].value); - } - } else if (type == RK3026_CODEC_CAPTURE) { - for (i = 0; i < RK3026_CODEC_CAPTURE_POWER_UP_LIST_LEN; i++) { - snd_soc_write(codec, capture_power_up_list[i].reg, - capture_power_up_list[i].value); - } - } else if (type == RK3026_CODEC_INCALL) { - snd_soc_update_bits(codec, RK3026_ALC_MUNIN_CTL, - RK3026_MUXINL_F_MSK | RK3026_MUXINR_F_MSK, - RK3026_MUXINR_F_INR | RK3026_MUXINL_F_INL); - - } - - return 0; -} - -static int rk3026_codec_power_down(int type) -{ - struct snd_soc_codec *codec = rk3026_priv->codec; - int i; - - if (!rk3026_priv || !rk3026_priv->codec) { - printk("%s : rk3026_priv or rk3026_priv->codec is NULL\n", __func__); - return -EINVAL; - } - - printk("%s : power down %s%s%s\n", __func__, - type == RK3026_CODEC_PLAYBACK ? "playback" : "", - type == RK3026_CODEC_CAPTURE ? "capture" : "", - type == RK3026_CODEC_ALL ? "all" : ""); - - if ((type == RK3026_CODEC_CAPTURE) || (type == RK3026_CODEC_INCALL)) { - for (i = 0; i < RK3026_CODEC_CAPTURE_POWER_DOWN_LIST_LEN; i++) { - snd_soc_write(codec, capture_power_down_list[i].reg, - capture_power_down_list[i].value); - } - } else if (type == RK3026_CODEC_PLAYBACK) { -#if 0 - snd_soc_write(codec, 0xa0,0x62); - for ( i = OUT_VOLUME; i >= 0; i--) - { - snd_soc_write(codec, 0xb4,i); - snd_soc_write(codec, 0xb8,i); - } - msleep(20); -#endif - for (i = 0; i < RK3026_CODEC_PLAYBACK_POWER_DOWN_LIST_LEN; i++) { - snd_soc_write(codec, playback_power_down_list[i].reg, - playback_power_down_list[i].value); - - } - - } else if (type == RK3026_CODEC_ALL) { - rk3026_reset(codec); - } - - return 0; -} - -static void rk3026_codec_capture_work(struct work_struct *work) -{ - DBG("%s : rk3026_codec_work_capture_type = %d\n", __func__, - rk3026_codec_work_capture_type); - - switch (rk3026_codec_work_capture_type) { - case RK3026_CODEC_WORK_POWER_DOWN: - rk3026_codec_power_down(RK3026_CODEC_CAPTURE); - break; - case RK3026_CODEC_WORK_POWER_UP: - rk3026_codec_power_up(RK3026_CODEC_CAPTURE); - break; - default: - break; - } - - rk3026_codec_work_capture_type = RK3026_CODEC_WORK_NULL; -} - -static int rk3026_startup(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct rk3026_codec_priv *rk3026 = rk3026_priv; - bool playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); - bool is_codec_playback_running = rk3026->playback_active > 0 ; - bool is_codec_capture_running = rk3026->capture_active > 0; - - if (!rk3026_for_mid) - { - DBG("%s immediately return for phone\n",__func__); - return 0; - } - - if (!rk3026) { - printk("%s : rk3026 is NULL\n", __func__); - return -EINVAL; - } - - DBG("%s : substream->stream : %s \n", __func__, - playback ? "PLAYBACK":"CAPTURE"); - - if (playback) - rk3026->playback_active++; - else - rk3026->capture_active++; - - if (playback) { - if (rk3026->playback_active > 0) { - if (!is_codec_playback_running) - rk3026_codec_power_up(RK3026_CODEC_PLAYBACK); - else - DBG(" Warning : playback has been opened, so return! \n"); - } - } else {//capture - if (rk3026->capture_active > 0 && !is_codec_capture_running) { - if (rk3026_codec_work_capture_type != RK3026_CODEC_WORK_POWER_UP) { - cancel_delayed_work_sync(&capture_delayed_work); - if (rk3026_codec_work_capture_type == RK3026_CODEC_WORK_NULL) { - rk3026_codec_power_up(RK3026_CODEC_CAPTURE); - } else { - DBG(" Warning : capture being closed, so interrupt the shutdown process ! \n"); - rk3026_codec_work_capture_type = RK3026_CODEC_WORK_NULL; - } - } else { - DBG("Warning : capture being opened, so return ! \n"); - } - } - } - return 0; -} - -static void rk3026_shutdown(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct rk3026_codec_priv *rk3026 = rk3026_priv; - bool playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); - bool is_codec_playback_running = rk3026->playback_active > 0; - bool is_codec_capture_running = rk3026->capture_active > 0; - - if (!rk3026_for_mid) - { - DBG("%s immediately return for phone\n", __func__); - return; - } - - if (!rk3026) { - printk("%s : rk3026 is NULL\n", __func__); - return; - } - - DBG("%s : substream->stream : %s \n", __func__, - playback ? "PLAYBACK":"CAPTURE"); - - if (playback) - rk3026->playback_active--; - else - rk3026->capture_active--; - - if (playback) { - if (rk3026->playback_active <= 0) { - if (is_codec_playback_running == true) - rk3026_codec_power_down(RK3026_CODEC_PLAYBACK); - else - DBG(" Warning : playback has been closed, so return !\n"); - } - } else {//capture - if (rk3026->capture_active <= 0) { - if ((rk3026_codec_work_capture_type != RK3026_CODEC_WORK_POWER_DOWN) && - (is_codec_capture_running == true)) { - cancel_delayed_work_sync(&capture_delayed_work); - /* - * If rk3026_codec_work_capture_type is NULL means codec already power down, - * so power up codec. - * If rk3026_codec_work_capture_type is RK3026_CODEC_WORK_POWER_UP it means - * codec haven't be powered up, so we don't need to power down codec. - * If is playback call power down, power down immediatly, because audioflinger - * already has delay 3s. - */ - if (rk3026_codec_work_capture_type == RK3026_CODEC_WORK_NULL) { - rk3026_codec_work_capture_type = RK3026_CODEC_WORK_POWER_DOWN; - queue_delayed_work(rk3026_codec_workq, &capture_delayed_work,msecs_to_jiffies(3000)); - } else { - rk3026_codec_work_capture_type = RK3026_CODEC_WORK_NULL; - DBG(" Warning : capture being opened, so interrupt the open process ! \n"); - } - } else { - DBG(" Warning : capture has been closed or it being closed, so return !\n"); - } - } - } -} - -#define RK3026_PLAYBACK_RATES (SNDRV_PCM_RATE_8000 |\ - SNDRV_PCM_RATE_16000 | \ - SNDRV_PCM_RATE_32000 | \ - SNDRV_PCM_RATE_44100 | \ - SNDRV_PCM_RATE_48000 | \ - SNDRV_PCM_RATE_96000) - -#define RK3026_CAPTURE_RATES (SNDRV_PCM_RATE_8000 |\ - SNDRV_PCM_RATE_16000 | \ - SNDRV_PCM_RATE_32000 | \ - SNDRV_PCM_RATE_44100 | \ - SNDRV_PCM_RATE_48000 | \ - SNDRV_PCM_RATE_96000) - -#define RK3026_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ - SNDRV_PCM_FMTBIT_S20_3LE |\ - SNDRV_PCM_FMTBIT_S24_LE |\ - SNDRV_PCM_FMTBIT_S32_LE) - -static struct snd_soc_dai_ops rk3026_dai_ops = { - .hw_params = rk3026_hw_params, - .set_fmt = rk3026_set_dai_fmt, - .set_sysclk = rk3026_set_dai_sysclk, - .digital_mute = rk3026_digital_mute, - .startup = rk3026_startup, - .shutdown = rk3026_shutdown, -}; - -static struct snd_soc_dai_driver rk3026_dai[] = { - { - .name = "rk3026-hifi", - .id = RK3026_HIFI, - .playback = { - .stream_name = "HiFi Playback", - .channels_min = 2, - .channels_max = 2, - .rates = RK3026_PLAYBACK_RATES, - .formats = RK3026_FORMATS, - }, - .capture = { - .stream_name = "HiFi Capture", - .channels_min = 2, - .channels_max = 2, - .rates = RK3026_CAPTURE_RATES, - .formats = RK3026_FORMATS, - }, - .ops = &rk3026_dai_ops, - }, - { - .name = "rk3026-voice", - .id = RK3026_VOICE, - .playback = { - .stream_name = "Voice Playback", - .channels_min = 1, - .channels_max = 2, - .rates = RK3026_PLAYBACK_RATES, - .formats = RK3026_FORMATS, - }, - .capture = { - .stream_name = "Voice Capture", - .channels_min = 1, - .channels_max = 2, - .rates = RK3026_CAPTURE_RATES, - .formats = RK3026_FORMATS, - }, - .ops = &rk3026_dai_ops, - }, - -}; - -static int rk3026_suspend(struct snd_soc_codec *codec) -{ - if (rk3026_for_mid) - { - cancel_delayed_work_sync(&capture_delayed_work); - - if (rk3026_codec_work_capture_type != RK3026_CODEC_WORK_NULL) { - rk3026_codec_work_capture_type = RK3026_CODEC_WORK_NULL; - } - rk3026_codec_power_down(RK3026_CODEC_PLAYBACK); - rk3026_codec_power_down(RK3026_CODEC_ALL); - snd_soc_write(codec, RK3026_SELECT_CURRENT,0x1e); - snd_soc_write(codec, RK3026_SELECT_CURRENT,0x3e); - } - else - rk3026_set_bias_level(codec, SND_SOC_BIAS_OFF); - - return 0; -} - -static int rk3026_resume(struct snd_soc_codec *codec) -{ - if (!rk3026_for_mid) - rk3026_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - return 0; -} - -static int rk3026_probe(struct snd_soc_codec *codec) -{ - struct rk3026_codec_priv *rk3026; - struct rk3026_codec_pdata *rk3026_plt = codec->dev->platform_data; - struct platform_device *pdev = to_platform_device(codec->dev); - struct resource *res, *mem; - int ret; - unsigned int val; - - DBG("%s\n", __func__); - - rk3026 = kzalloc(sizeof(struct rk3026_codec_priv), GFP_KERNEL); - if (!rk3026) { - printk("%s : rk3026 priv kzalloc failed!\n", __func__); - return -ENOMEM; - } - - rk3026->codec = codec; - - res = pdev->resource; - rk3026->regbase_phy = res->start; - rk3026->regsize_phy = (res->end - res->start) + 1; - - mem = request_mem_region(res->start, (res->end - res->start) + 1, pdev->name); - if (!mem) - { - dev_err(&pdev->dev, "failed to request mem region for rk2928 codec\n"); - ret = -ENOENT; - goto err__; - } - - rk3026->regbase = (int)ioremap(res->start, (res->end - res->start) + 1); - if (!rk3026->regbase) { - dev_err(&pdev->dev, "cannot ioremap acodec registers\n"); - ret = -ENXIO; - goto err__; - } - - rk3026->pclk = clk_get(NULL,"pclk_acodec"); - if(IS_ERR(rk3026->pclk)) - { - dev_err(&pdev->dev, "Unable to get acodec hclk\n"); - ret = -ENXIO; - goto err__; - } - clk_enable(rk3026->pclk); - - rk3026_priv = rk3026; - - if (rk3026_priv && rk3026_plt->spk_ctl_gpio) { - gpio_request(rk3026_plt->spk_ctl_gpio, NULL); - gpio_direction_output(rk3026_plt->spk_ctl_gpio, GPIO_LOW); - rk3026->spk_ctl_gpio = rk3026_plt->spk_ctl_gpio; - rk3026->hp_ctl_gpio = rk3026_plt->hp_ctl_gpio; - } else { - printk("%s : rk3026 spk_ctl_gpio is NULL!\n", __func__); - rk3026->spk_ctl_gpio = INVALID_GPIO; - } - - if (rk3026_priv && rk3026_plt->hp_ctl_gpio) { - gpio_request(rk3026_plt->hp_ctl_gpio, NULL); - gpio_direction_output(rk3026_plt->hp_ctl_gpio, GPIO_LOW); - rk3026->hp_ctl_gpio = rk3026_plt->hp_ctl_gpio; - } else { - printk("%s : rk3026 hp_ctl_gpio is NULL!\n", __func__); - rk3026->hp_ctl_gpio = INVALID_GPIO; - } - - if (rk3026_plt->delay_time) { - rk3026->delay_time = rk3026_plt->delay_time; - } else { - printk("%s : rk3026 delay_time is NULL!\n", __func__); - rk3026->delay_time = 10; - } - - - if (rk3026_for_mid) - { - rk3026->playback_active = 0; - rk3026->capture_active = 0; - - rk3026_codec_workq = create_freezable_workqueue("rk3026-codec"); - - if (rk3026_codec_workq == NULL) { - printk("%s : create work FAIL! rk3026_codec_workq is NULL!\n", __func__); - ret = -ENOMEM; - goto err__; - } - } - - ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); - if (ret != 0) { - printk("%s : Failed to set cache I/O: %d\n", __func__, ret); - goto err__; - } - - codec->hw_read = rk3026_codec_read; - codec->hw_write = (hw_write_t)rk3026_hw_write; - codec->read = rk3026_codec_read; - codec->write = rk3026_codec_write; - - val = snd_soc_read(codec, RK3026_RESET); - if (val != rk3026_reg_defaults[RK3026_RESET]) { - printk("%s : codec register 0: %x is not a 0x00000003\n", __func__, val); - ret = -ENODEV; - goto err__; - } - - rk3026_reset(codec); - - if (!rk3026_for_mid) - { - codec->dapm.bias_level = SND_SOC_BIAS_OFF; - rk3026_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - } - -#ifdef WITH_CAP - //set for capacity output,clear up noise - snd_soc_write(codec, RK3026_SELECT_CURRENT,0x1e); - snd_soc_write(codec, RK3026_SELECT_CURRENT,0x3e); - //snd_soc_write(codec, 0xbc,0x28); -#endif - // select i2s sdi from acodec soc_con[0] bit 10 - val = readl(RK2928_GRF_BASE+GRF_SOC_CON0); - writel(val | 0x04000400,RK2928_GRF_BASE+GRF_SOC_CON0); - val = readl(RK2928_GRF_BASE+GRF_SOC_CON0); - printk("%s : i2s sdi from acodec val=0x%x,soc_con[0] bit 10 =1 is correct\n",__func__,val); - - - if(!rk3026_for_mid) - { - codec->dapm.bias_level = SND_SOC_BIAS_OFF; - rk3026_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - - snd_soc_add_codec_controls(codec, rk3026_snd_controls, - ARRAY_SIZE(rk3026_snd_controls)); - snd_soc_dapm_new_controls(&codec->dapm, rk3026_dapm_widgets, - ARRAY_SIZE(rk3026_dapm_widgets)); - snd_soc_dapm_add_routes(&codec->dapm, rk3026_dapm_routes, - ARRAY_SIZE(rk3026_dapm_routes)); - - } - -#ifdef CONFIG_MACH_RK_FAC - rk3026_hdmi_ctrl=1; -#endif - return 0; - -err__: - release_mem_region(res->start,(res->end - res->start) + 1); - kfree(rk3026); - rk3026 = NULL; - rk3026_priv = NULL; - - return ret; -} - -/* power down chip */ -static int rk3026_remove(struct snd_soc_codec *codec) -{ - - DBG("%s\n", __func__); - - if (!rk3026_priv) { - printk("%s : rk3026_priv is NULL\n", __func__); - return 0; - } - - if (rk3026_priv->spk_ctl_gpio != INVALID_GPIO) - gpio_set_value(rk3026_priv->spk_ctl_gpio, GPIO_LOW); - - if (rk3026_priv->hp_ctl_gpio != INVALID_GPIO) - gpio_set_value(rk3026_priv->hp_ctl_gpio, GPIO_LOW); - - mdelay(10); - - if (rk3026_for_mid) - { - cancel_delayed_work_sync(&capture_delayed_work); - - if (rk3026_codec_work_capture_type != RK3026_CODEC_WORK_NULL) { - rk3026_codec_work_capture_type = RK3026_CODEC_WORK_NULL; - } - } - - snd_soc_write(codec, RK3026_RESET, 0xfc); - mdelay(10); - snd_soc_write(codec, RK3026_RESET, 0x3); - mdelay(10); - - if (rk3026_priv) - kfree(rk3026_priv); - - return 0; -} - -static struct snd_soc_codec_driver soc_codec_dev_rk3026 = { - .probe =rk3026_probe, - .remove =rk3026_remove, - .suspend =rk3026_suspend, - .resume = rk3026_resume, - .set_bias_level = rk3026_set_bias_level, - .reg_cache_size = ARRAY_SIZE(rk3026_reg_defaults), - .reg_word_size = sizeof(unsigned int), - .reg_cache_default = rk3026_reg_defaults, - .volatile_register = rk3026_volatile_register, - .readable_register = rk3026_codec_register, - .reg_cache_step = sizeof(unsigned int), -}; - -static int rk3026_platform_probe(struct platform_device *pdev) -{ - DBG("%s\n", __func__); - - return snd_soc_register_codec(&pdev->dev, - &soc_codec_dev_rk3026, rk3026_dai, ARRAY_SIZE(rk3026_dai)); -} - -static int rk3026_platform_remove(struct platform_device *pdev) -{ - snd_soc_unregister_codec(&pdev->dev); - return 0; -} - -void rk3026_platform_shutdown(struct platform_device *pdev) -{ - - DBG("%s\n", __func__); - - if (!rk3026_priv || !rk3026_priv->codec) { - printk("%s : rk3026_priv or rk3026_priv->codec is NULL\n", __func__); - return; - } - - if (rk3026_priv->spk_ctl_gpio != INVALID_GPIO) - gpio_set_value(rk3026_priv->spk_ctl_gpio, GPIO_LOW); - - if (rk3026_priv->hp_ctl_gpio != INVALID_GPIO) - gpio_set_value(rk3026_priv->hp_ctl_gpio, GPIO_LOW); - - mdelay(10); - - if (rk3026_for_mid) { - cancel_delayed_work_sync(&capture_delayed_work); - - if (rk3026_codec_work_capture_type != RK3026_CODEC_WORK_NULL) { - rk3026_codec_work_capture_type = RK3026_CODEC_WORK_NULL; - } - } - - writel(0xfc, rk3026_priv->regbase+RK3026_RESET); - mdelay(10); - writel(0x03, rk3026_priv->regbase+RK3026_RESET); - - if (rk3026_priv) - kfree(rk3026_priv); -} - -static struct platform_driver rk3026_codec_driver = { - .driver = { - .name = "rk3026-codec", - .owner = THIS_MODULE, - }, - .probe = rk3026_platform_probe, - .remove = rk3026_platform_remove, - .shutdown = rk3026_platform_shutdown, -}; - - -static __init int rk3026_modinit(void) -{ - rk3026_get_parameter(); - return platform_driver_register(&rk3026_codec_driver); -} -module_init(rk3026_modinit); - -static __exit void rk3026_exit(void) -{ - platform_driver_unregister(&rk3026_codec_driver); -} -module_exit(rk3026_exit); - -MODULE_DESCRIPTION("ASoC RK3026 driver"); -MODULE_AUTHOR("yj "); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/rk3026_codec.h b/sound/soc/codecs/rk3026_codec.h deleted file mode 100644 index 2704670ad107..000000000000 --- a/sound/soc/codecs/rk3026_codec.h +++ /dev/null @@ -1,565 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * rk3026.h -- RK3026 CODEC ALSA SoC audio driver - * - * Copyright 2013 Rockship - * Author: chenjq - * - */ - -#ifndef __RK3026_CODEC_H__ -#define __RK3026_CODEC_H__ - - - -/* codec register */ -#define RK3026_CODEC_BASE (0x0) - -#define RK3026_RESET (RK3026_CODEC_BASE + 0x00) -#define RK3026_ADC_INT_CTL1 (RK3026_CODEC_BASE + 0x08) -#define RK3026_ADC_INT_CTL2 (RK3026_CODEC_BASE + 0x0c) -#define RK3026_DAC_INT_CTL1 (RK3026_CODEC_BASE + 0x10) -#define RK3026_DAC_INT_CTL2 (RK3026_CODEC_BASE + 0x14) -#define RK3026_DAC_INT_CTL3 (RK3026_CODEC_BASE + 0x18) -#define RK3026_ADC_MIC_CTL (RK3026_CODEC_BASE + 0x88) -#define RK3026_BST_CTL (RK3026_CODEC_BASE + 0x8c) -#define RK3026_ALC_MUNIN_CTL (RK3026_CODEC_BASE + 0x90) -#define RK3026_BSTL_ALCL_CTL (RK3026_CODEC_BASE + 0x94) -#define RK3026_ALCR_GAIN_CTL (RK3026_CODEC_BASE + 0x98) -#define RK3026_ADC_ENABLE (RK3026_CODEC_BASE + 0x9c) -#define RK3026_DAC_CTL (RK3026_CODEC_BASE + 0xa0) -#define RK3026_DAC_ENABLE (RK3026_CODEC_BASE + 0xa4) -#define RK3026_HPMIX_CTL (RK3026_CODEC_BASE + 0xa8) -#define RK3026_HPMIX_S_SELECT (RK3026_CODEC_BASE + 0xac) -#define RK3026_HPOUT_CTL (RK3026_CODEC_BASE + 0xB0) -#define RK3026_HPOUTL_GAIN (RK3026_CODEC_BASE + 0xB4) -#define RK3026_HPOUTR_GAIN (RK3026_CODEC_BASE + 0xB8) -#define RK3026_SELECT_CURRENT (RK3026_CODEC_BASE + 0xBC) -#define RK3026_PGAL_AGC_CTL1 (RK3026_CODEC_BASE + 0x100) -#define RK3026_PGAL_AGC_CTL2 (RK3026_CODEC_BASE + 0x104) -#define RK3026_PGAL_AGC_CTL3 (RK3026_CODEC_BASE + 0x108) -#define RK3026_PGAL_AGC_CTL4 (RK3026_CODEC_BASE + 0x10c) -#define RK3026_PGAL_ASR_CTL (RK3026_CODEC_BASE + 0x110) -#define RK3026_PGAL_AGC_MAX_H (RK3026_CODEC_BASE + 0x114) -#define RK3026_PGAL_AGC_MAX_L (RK3026_CODEC_BASE + 0x118) -#define RK3026_PGAL_AGC_MIN_H (RK3026_CODEC_BASE + 0x11c) -#define RK3026_PGAL_AGC_MIN_L (RK3026_CODEC_BASE + 0x120) -#define RK3026_PGAL_AGC_CTL5 (RK3026_CODEC_BASE + 0x124) -#define RK3026_PGAR_AGC_CTL1 (RK3026_CODEC_BASE + 0x140) -#define RK3026_PGAR_AGC_CTL2 (RK3026_CODEC_BASE + 0x144) -#define RK3026_PGAR_AGC_CTL3 (RK3026_CODEC_BASE + 0x148) -#define RK3026_PGAR_AGC_CTL4 (RK3026_CODEC_BASE + 0x14c) -#define RK3026_PGAR_ASR_CTL (RK3026_CODEC_BASE + 0x150) -#define RK3026_PGAR_AGC_MAX_H (RK3026_CODEC_BASE + 0x154) -#define RK3026_PGAR_AGC_MAX_L (RK3026_CODEC_BASE + 0x158) -#define RK3026_PGAR_AGC_MIN_H (RK3026_CODEC_BASE + 0x15c) -#define RK3026_PGAR_AGC_MIN_L (RK3026_CODEC_BASE + 0x160) -#define RK3026_PGAR_AGC_CTL5 (RK3026_CODEC_BASE + 0x164) - -/* ADC Interface Control 1 (0x08) */ -#define RK3026_ALRCK_POL_MASK (0x1 << 7) -#define RK3026_ALRCK_POL_SFT 7 -#define RK3026_ALRCK_POL_EN (0x1 << 7) -#define RK3026_ALRCK_POL_DIS (0x0 << 7) - -#define RK3026_ADC_VWL_MASK (0x3 << 5) -#define RK3026_ADC_VWL_SFT 5 -#define RK3026_ADC_VWL_32 (0x3 << 5) -#define RK3026_ADC_VWL_24 (0x2 << 5) -#define RK3026_ADC_VWL_20 (0x1 << 5) -#define RK3026_ADC_VWL_16 (0x0 << 5) - -#define RK3026_ADC_DF_MASK (0x3 << 3) -#define RK3026_ADC_DF_SFT 3 -#define RK3026_ADC_DF_PCM (0x3 << 3) -#define RK3026_ADC_DF_I2S (0x2 << 3) -#define RK3026_ADC_DF_LJ (0x1 << 3) -#define RK3026_ADC_DF_RJ (0x0 << 3) - -#define RK3026_ADC_SWAP_MASK (0x1 << 1) -#define RK3026_ADC_SWAP_SFT 1 -#define RK3026_ADC_SWAP_EN (0x1 << 1) -#define RK3026_ADC_SWAP_DIS (0x0 << 1) - -#define RK3026_ADC_TYPE_MASK 0x1 -#define RK3026_ADC_TYPE_SFT 0 -#define RK3026_ADC_TYPE_MONO 0x1 -#define RK3026_ADC_TYPE_STEREO 0x0 - -/* ADC Interface Control 2 (0x0c) */ -#define RK3026_I2S_MODE_MASK (0x1 << 4) -#define RK3026_I2S_MODE_SFT (4) -#define RK3026_I2S_MODE_MST (0x1 << 4) -#define RK3026_I2S_MODE_SLV (0x0 << 4) - -#define RK3026_ADC_WL_MASK (0x3 << 2) -#define RK3026_ADC_WL_SFT (2) -#define RK3026_ADC_WL_32 (0x3 << 2) -#define RK3026_ADC_WL_24 (0x2 << 2) -#define RK3026_ADC_WL_20 (0x1 << 2) -#define RK3026_ADC_WL_16 (0x0 << 2) - -#define RK3026_ADC_RST_MASK (0x1 << 1) -#define RK3026_ADC_RST_SFT 91) -#define RK3026_ADC_RST_DIS (0x1 << 1) -#define RK3026_ADC_RST_EN (0x0 << 1) - -#define RK3026_ABCLK_POL_MASK 0x1 -#define RK3026_ABCLK_POL_SFT 0 -#define RK3026_ABCLK_POL_EN 0x1 -#define RK3026_ABCLK_POL_DIS 0x0 - -/* DAC Interface Control 1 (0x10) */ -#define RK3026_DLRCK_POL_MASK (0x1 << 7) -#define RK3026_DLRCK_POL_SFT 7 -#define RK3026_DLRCK_POL_EN (0x1 << 7) -#define RK3026_DLRCK_POL_DIS (0x0 << 7) - -#define RK3026_DAC_VWL_MASK (0x3 << 5) -#define RK3026_DAC_VWL_SFT 5 -#define RK3026_DAC_VWL_32 (0x3 << 5) -#define RK3026_DAC_VWL_24 (0x2 << 5) -#define RK3026_DAC_VWL_20 (0x1 << 5) -#define RK3026_DAC_VWL_16 (0x0 << 5) - -#define RK3026_DAC_DF_MASK (0x3 << 3) -#define RK3026_DAC_DF_SFT 3 -#define RK3026_DAC_DF_PCM (0x3 << 3) -#define RK3026_DAC_DF_I2S (0x2 << 3) -#define RK3026_DAC_DF_LJ (0x1 << 3) -#define RK3026_DAC_DF_RJ (0x0 << 3) - -#define RK3026_DAC_SWAP_MASK (0x1 << 2) -#define RK3026_DAC_SWAP_SFT 2 -#define RK3026_DAC_SWAP_EN (0x1 << 2) -#define RK3026_DAC_SWAP_DIS (0x0 << 2) - -/* DAC Interface Control 2 (0x14) */ -#define RK3026_DAC_WL_MASK (0x3 << 2) -#define RK3026_DAC_WL_SFT 2 -#define RK3026_DAC_WL_32 (0x3 << 2) -#define RK3026_DAC_WL_24 (0x2 << 2) -#define RK3026_DAC_WL_20 (0x1 << 2) -#define RK3026_DAC_WL_16 (0x0 << 2) - -#define RK3026_DAC_RST_MASK (0x1 << 1) -#define RK3026_DAC_RST_SFT 1 -#define RK3026_DAC_RST_DIS (0x1 << 1) -#define RK3026_DAC_RST_EN (0x0 << 1) - -#define RK3026_DBCLK_POL_MASK 0x1 -#define RK3026_DBCLK_POL_SFT 0 -#define RK3026_DBCLK_POL_EN 0x1 -#define RK3026_DBCLK_POL_DIS 0x0 - -/* ADC & MICBIAS (0x88) */ -#define RK3026_ADC_CURRENT_ENABLE (0x1 << 7) -#define RK3026_ADC_CURRENT_DISABLE (0x0 << 7) - -#define RK3026_MICBIAS_VOL_ENABLE (6) - -#define RK3026_ADCL_ZERO_DET_EN_SFT (5) -#define RK3026_ADCL_ZERO_DET_EN (0x1 << 5) -#define RK3026_ADCL_ZERO_DET_DIS (0x0 << 5) - -#define RK3026_ADCR_ZERO_DET_EN_SFT (4) -#define RK3026_ADCR_ZERO_DET_EN (0x1 << 4) -#define RK3026_ADCR_ZERO_DET_DIS (0x0 << 4) - -#define RK3026_MICBIAS_VOL_SHT 0 -#define RK3026_MICBIAS_VOL_MSK 7 -#define RK3026_MICBIAS_VOL_MIN (0x0 << 0) -#define RK3026_MICBIAS_VOL_MAX (0x7 << 0) - -/* BST_L BST_R CONTROL (0x8C) */ -#define RK3026_BSTL_PWRD_SFT (6) -#define RK3026_BSTL_EN (0x1 << 6) -#define RK3026_BSTL_DIS (0x0 << 6) -#define RK3026_BSTL_GAIN_SHT (5) -#define RK3026_BSTL_GAIN_20 (0x1 << 5) -#define RK3026_BSTL_GAIN_0 (0x0 << 5) -#define RK3026_BSTL_MUTE_SHT (4) - -#define RK3026_BSTR_PWRD_SFT (2) -#define RK3026_BSTR_EN (0x1 << 2) -#define RK3026_BSTR_DIS (0x0 << 2) -#define RK3026_BSTR_GAIN_SHT (1) -#define RK3026_BSTR_GAIN_20 (0x1 << 1) -#define RK3026_BSTR_GAIN_0 (0x0 << 1) -#define RK3026_BSTR_MUTE_SHT (0) - - -/* MUXINL ALCL MUXINR ALCR (0x90) */ -#define RK3026_MUXINL_F_SHT (6) -#define RK3026_MUXINL_F_MSK (0x03 << 6) -#define RK3026_MUXINL_F_INL (0x02 << 6) -#define RK3026_MUXINL_F_BSTL (0x01 << 6) -#define RK3026_ALCL_PWR_SHT (5) -#define RK3026_ALCL_EN (0x1 << 5) -#define RK3026_ALCL_DIS (0x0 << 5) -#define RK3026_ALCL_MUTE_SHT (4) -#define RK3026_MUXINR_F_SHT (2) -#define RK3026_MUXINR_F_MSK (0x03 << 2) -#define RK3026_MUXINR_F_INR (0x02 << 2) -#define RK3026_MUXINR_F_BSTR (0x01 << 2) -#define RK3026_ALCR_PWR_SHT (1) -#define RK3026_ALCR_EN (0x1 << 1) -#define RK3026_ALCR_DIS (0x0 << 1) -#define RK3026_ALCR_MUTE_SHT (0) - -/* BST_L MODE & ALC_L GAIN (0x94) */ -#define RK3026_BSTL_MODE_SFT (5) -#define RK3026_BSTL_MODE_SINGLE (0x1 << 5) -#define RK3026_BSTL_MODE_DIFF (0x0 << 5) - -#define RK3026_ALCL_GAIN_SHT (0) -#define RK3026_ALCL_GAIN_MSK (0x1f) - -/* ALC_R GAIN (0x98) */ -#define RK3026_ALCR_GAIN_SHT (0) -#define RK3026_ALCR_GAIN_MSK (0x1f) - -/* ADC control (0x9C) */ -#define RK3026_ADCL_REF_VOL_EN_SFT (3) -#define RK3026_ADCL_REF_VOL_EN (0x1 << 7) -#define RK3026_ADCL_REF_VOL_DIS (0x0 << 7) - -#define RK3026_ADCL_CLK_EN_SFT (6) -#define RK3026_ADCL_CLK_EN (0x1 << 6) -#define RK3026_ADCL_CLK_DIS (0x0 << 6) - -#define RK3026_ADCL_AMP_EN_SFT (5) -#define RK3026_ADCL_AMP_EN (0x1 << 5) -#define RK3026_ADCL_AMP_DIS (0x0 << 5) - -#define RK3026_ADCL_RST_EN (0x1 << 4) -#define RK3026_ADCL_RST_DIS (0x0 << 4) - -#define RK3026_ADCR_REF_VOL_EN_SFT (3) -#define RK3026_ADCR_REF_VOL_EN (0x1 << 3) -#define RK3026_ADCR_REF_VOL_DIS (0x0 << 3) - -#define RK3026_ADCR_CLK_EN_SFT (2) -#define RK3026_ADCR_CLK_EN (0x1 << 2) -#define RK3026_ADCR_CLK_DIS (0x0 << 2) - -#define RK3026_ADCR_AMP_EN_SFT (1) -#define RK3026_ADCR_AMP_EN (0x1 << 1) -#define RK3026_ADCR_AMP_DIS (0x0 << 1) - -#define RK3026_ADCR_RST_EN (0x1 << 0) -#define RK3026_ADCR_RST_DIS (0x0 << 0) - -/* DAC & VOUT Control (0xa0) */ -#define RK3026_CURRENT_EN (0x1 << 6) -#define RK3026_CURRENT_DIS (0x0 << 6) -#define RK3026_REF_VOL_DACL_EN_SFT (5) -#define RK3026_REF_VOL_DACL_EN (0x1 << 5) -#define RK3026_REF_VOL_DACL_DIS (0x0 << 5) -#define RK3026_ZO_DET_VOUTL_SFT (4) -#define RK3026_ZO_DET_VOUTL_EN (0x1 << 4) -#define RK3026_ZO_DET_VOUTL_DIS (0x0 << 4) -#define RK3026_DET_ERAPHONE_DIS (0x0 << 3) -#define RK3026_DET_ERAPHONE_EN (0x1 << 3) -#define RK3026_REF_VOL_DACR_EN_SFT (1) -#define RK3026_REF_VOL_DACR_EN (0x1 << 1) -#define RK3026_REF_VOL_DACR_DIS (0x0 << 1) -#define RK3026_ZO_DET_VOUTR_SFT (0) -#define RK3026_ZO_DET_VOUTR_EN (0x1 << 0) -#define RK3026_ZO_DET_VOUTR_DIS (0x0 << 0) - -/* DAC control (0xa4) */ -#define RK3026_DACL_REF_VOL_EN_SFT (7) -#define RK3026_DACL_REF_VOL_EN (0x1 << 7) -#define RK3026_DACL_REF_VOL_DIS (0x0 << 7) - -#define RK3026_DACL_CLK_EN (0x1 << 6) -#define RK3026_DACL_CLK_DIS (0x0 << 6) - -#define RK3026_DACL_EN (0x1 << 5) -#define RK3026_DACL_DIS (0x0 << 5) - -#define RK3026_DACL_INIT (0x0 << 4) -#define RK3026_DACL_WORK (0x1 << 4) - -#define RK3026_DACR_REF_VOL_EN_SFT (3) -#define RK3026_DACR_REF_VOL_EN (0x1 << 3) -#define RK3026_DACR_REF_VOL_DIS (0x0 << 3) - -#define RK3026_DACR_CLK_EN (0x1 << 2) -#define RK3026_DACR_CLK_DIS (0x0 << 2) - -#define RK3026_DACR_EN (0x1 << 1) -#define RK3026_DACR_DIS (0x0 << 1) - -#define RK3026_DACR_INIT (0x0 << 0) -#define RK3026_DACR_WORK (0x1 << 0) - -/* HPMIXL HPMIXR Control (0xa8) */ -#define RK3026_HPMIXL_SFT (6) -#define RK3026_HPMIXL_EN (0x1 << 6) -#define RK3026_HPMIXL_DIS (0x0 << 6) -#define RK3026_HPMIXL_INIT1 (0x0 << 5) -#define RK3026_HPMIXL_WORK1 (0x1 << 5) -#define RK3026_HPMIXL_INIT2 (0x0 << 4) -#define RK3026_HPMIXL_WORK2 (0x1 << 4) -#define RK3026_HPMIXR_SFT (2) -#define RK3026_HPMIXR_EN (0x1 << 2) -#define RK3026_HPMIXR_DIS (0x0 << 2) -#define RK3026_HPMIXR_INIT1 (0x0 << 1) -#define RK3026_HPMIXR_WORK1 (0x1 << 1) -#define RK3026_HPMIXR_INIT2 (0x0 << 0) -#define RK3026_HPMIXR_WORK2 (0x1 << 0) - -/* HPMIXL Control (0xac) */ -#define RK3026_HPMIXL_BYPASS_SFT (7) -#define RK3026_HPMIXL_SEL_ALCL_SFT (6) -#define RK3026_HPMIXL_SEL_ALCR_SFT (5) -#define RK3026_HPMIXL_SEL_DACL_SFT (4) -#define RK3026_HPMIXR_BYPASS_SFT (3) -#define RK3026_HPMIXR_SEL_ALCL_SFT (2) -#define RK3026_HPMIXR_SEL_ALCR_SFT (1) -#define RK3026_HPMIXR_SEL_DACR_SFT (0) - -/* HPOUT Control (0xb0) */ -#define RK3026_HPOUTL_PWR_SHT (7) -#define RK3026_HPOUTL_MSK (0x1 << 7) -#define RK3026_HPOUTL_EN (0x1 << 7) -#define RK3026_HPOUTL_DIS (0x0 << 7) -#define RK3026_HPOUTL_INIT_MSK (0x1 << 6) -#define RK3026_HPOUTL_INIT (0x0 << 6) -#define RK3026_HPOUTL_WORK (0x1 << 6) -#define RK3026_HPOUTL_MUTE_SHT (5) -#define RK3026_HPOUTL_MUTE_MSK (0x1 << 5) -#define RK3026_HPOUTL_MUTE_EN (0x0 << 5) -#define RK3026_HPOUTL_MUTE_DIS (0x1 << 5) -#define RK3026_HPOUTR_PWR_SHT (4) -#define RK3026_HPOUTR_MSK (0x1 << 4) -#define RK3026_HPOUTR_EN (0x1 << 4) -#define RK3026_HPOUTR_DIS (0x0 << 4) -#define RK3026_HPOUTR_INIT_MSK (0x1 << 3) -#define RK3026_HPOUTR_WORK (0x1 << 3) -#define RK3026_HPOUTR_INIT (0x0 << 3) -#define RK3026_HPOUTR_MUTE_SHT (2) -#define RK3026_HPOUTR_MUTE_MSK (0x1 << 2) -#define RK3026_HPOUTR_MUTE_EN (0x0 << 2) -#define RK3026_HPOUTR_MUTE_DIS (0x1 << 2) - -#define RK3026_HPVREF_PWR_SHT (1) -#define RK3026_HPVREF_EN (0x1 << 1) -#define RK3026_HPVREF_DIS (0x0 << 1) -#define RK3026_HPVREF_WORK (0x1 << 0) -#define RK3026_HPVREF_INIT (0x0 << 0) - -/* HPOUT GAIN (0xb4 0xb8) */ -#define RK3026_HPOUT_GAIN_SFT (0) - -/* SELECT CURR prechagrge/discharge (0xbc) */ -#define RK3026_PRE_HPOUT (0x1 << 5) -#define RK3026_DIS_HPOUT (0x0 << 5) -#define RK3026_CUR_10UA_EN (0x0 << 4) -#define RK3026_CUR_10UA_DIS (0x1 << 4) -#define RK3026_CUR_I_EN (0x0 << 3) -#define RK3026_CUR_I_DIS (0x1 << 3) -#define RK3026_CUR_2I_EN (0x0 << 2) -#define RK3026_CUR_2I_DIS (0x1 << 2) -#define RK3026_CUR_4I_EN (0x0 << 0) -#define RK3026_CUR_4I_DIS (0x3 << 0) - -/* PGA AGC control 1 (0xc0 0x100) */ -#define RK3026_PGA_AGC_WAY_MASK (0x1 << 6) -#define RK3026_PGA_AGC_WAY_SFT 6 -#define RK3026_PGA_AGC_WAY_JACK (0x1 << 6) -#define RK3026_PGA_AGC_WAY_NOR (0x0 << 6) - -#define RK3026_PGA_AGC_BK_WAY_SFT 4 -#define RK3026_PGA_AGC_BK_WAY_JACK1 (0x1 << 4) -#define RK3026_PGA_AGC_BK_WAY_NOR (0x0 << 4) -#define RK3026_PGA_AGC_BK_WAY_JACK2 (0x2 << 4) -#define RK3026_PGA_AGC_BK_WAY_JACK3 (0x3 << 4) - -#define RK3026_PGA_AGC_HOLD_T_MASK 0xf -#define RK3026_PGA_AGC_HOLD_T_SFT 0 -#define RK3026_PGA_AGC_HOLD_T_1024 0xa -#define RK3026_PGA_AGC_HOLD_T_512 0x9 -#define RK3026_PGA_AGC_HOLD_T_256 0x8 -#define RK3026_PGA_AGC_HOLD_T_128 0x7 -#define RK3026_PGA_AGC_HOLD_T_64 0x6 -#define RK3026_PGA_AGC_HOLD_T_32 0x5 -#define RK3026_PGA_AGC_HOLD_T_16 0x4 -#define RK3026_PGA_AGC_HOLD_T_8 0x3 -#define RK3026_PGA_AGC_HOLD_T_4 0x2 -#define RK3026_PGA_AGC_HOLD_T_2 0x1 -#define RK3026_PGA_AGC_HOLD_T_0 0x0 - -/* PGA AGC control 2 (0xc4 0x104) */ -#define RK3026_PGA_AGC_GRU_T_MASK (0xf << 4) -#define RK3026_PGA_AGC_GRU_T_SFT 4 -#define RK3026_PGA_AGC_GRU_T_512 (0xa << 4) -#define RK3026_PGA_AGC_GRU_T_256 (0x9 << 4) -#define RK3026_PGA_AGC_GRU_T_128 (0x8 << 4) -#define RK3026_PGA_AGC_GRU_T_64 (0x7 << 4) -#define RK3026_PGA_AGC_GRU_T_32 (0x6 << 4) -#define RK3026_PGA_AGC_GRU_T_16 (0x5 << 4) -#define RK3026_PGA_AGC_GRU_T_8 (0x4 << 4) -#define RK3026_PGA_AGC_GRU_T_4 (0x3 << 4) -#define RK3026_PGA_AGC_GRU_T_2 (0x2 << 4) -#define RK3026_PGA_AGC_GRU_T_1 (0x1 << 4) -#define RK3026_PGA_AGC_GRU_T_0_5 (0x0 << 4) - -#define RK3026_PGA_AGC_GRD_T_MASK 0xf -#define RK3026_PGA_AGC_GRD_T_SFT 0 -#define RK3026_PGA_AGC_GRD_T_128_32 0xa -#define RK3026_PGA_AGC_GRD_T_64_16 0x9 -#define RK3026_PGA_AGC_GRD_T_32_8 0x8 -#define RK3026_PGA_AGC_GRD_T_16_4 0x7 -#define RK3026_PGA_AGC_GRD_T_8_2 0x6 -#define RK3026_PGA_AGC_GRD_T_4_1 0x5 -#define RK3026_PGA_AGC_GRD_T_2_0_512 0x4 -#define RK3026_PGA_AGC_GRD_T_1_0_256 0x3 -#define RK3026_PGA_AGC_GRD_T_0_500_128 0x2 -#define RK3026_PGA_AGC_GRD_T_0_250_64 0x1 -#define RK3026_PGA_AGC_GRD_T_0_125_32 0x0 - -/* PGA AGC control 3 (0xc8 0x108) */ -#define RK3026_PGA_AGC_MODE_MASK (0x1 << 7) -#define RK3026_PGA_AGC_MODE_SFT 7 -#define RK3026_PGA_AGC_MODE_LIMIT (0x1 << 7) -#define RK3026_PGA_AGC_MODE_NOR (0x0 << 7) - -#define RK3026_PGA_AGC_ZO_MASK (0x1 << 6) -#define RK3026_PGA_AGC_ZO_SFT 6 -#define RK3026_PGA_AGC_ZO_EN (0x1 << 6) -#define RK3026_PGA_AGC_ZO_DIS (0x0 << 6) - -#define RK3026_PGA_AGC_REC_MODE_MASK (0x1 << 5) -#define RK3026_PGA_AGC_REC_MODE_SFT 5 -#define RK3026_PGA_AGC_REC_MODE_AC (0x1 << 5) -#define RK3026_PGA_AGC_REC_MODE_RN (0x0 << 5) - -#define RK3026_PGA_AGC_FAST_D_MASK (0x1 << 4) -#define RK3026_PGA_AGC_FAST_D_SFT 4 -#define RK3026_PGA_AGC_FAST_D_EN (0x1 << 4) -#define RK3026_PGA_AGC_FAST_D_DIS (0x0 << 4) - -#define RK3026_PGA_AGC_NG_MASK (0x1 << 3) -#define RK3026_PGA_AGC_NG_SFT 3 -#define RK3026_PGA_AGC_NG_EN (0x1 << 3) -#define RK3026_PGA_AGC_NG_DIS (0x0 << 3) - -#define RK3026_PGA_AGC_NG_THR_MASK 0x7 -#define RK3026_PGA_AGC_NG_THR_SFT 0 -#define RK3026_PGA_AGC_NG_THR_N81DB 0x7 -#define RK3026_PGA_AGC_NG_THR_N75DB 0x6 -#define RK3026_PGA_AGC_NG_THR_N69DB 0x5 -#define RK3026_PGA_AGC_NG_THR_N63DB 0x4 -#define RK3026_PGA_AGC_NG_THR_N57DB 0x3 -#define RK3026_PGA_AGC_NG_THR_N51DB 0x2 -#define RK3026_PGA_AGC_NG_THR_N45DB 0x1 -#define RK3026_PGA_AGC_NG_THR_N39DB 0x0 - -/* PGA AGC Control 4 (0xcc 0x10c) */ -#define RK3026_PGA_AGC_ZO_MODE_MASK (0x1 << 5) -#define RK3026_PGA_AGC_ZO_MODE_SFT 5 -#define RK3026_PGA_AGC_ZO_MODE_UWRC (0x1 << 5) -#define RK3026_PGA_AGC_ZO_MODE_UARC (0x0 << 5) - -#define RK3026_PGA_AGC_VOL_MASK 0x1f -#define RK3026_PGA_AGC_VOL_SFT 0 - -/* PGA ASR Control (0xd0 0x110) */ -#define RK3026_PGA_SLOW_CLK_MASK (0x1 << 3) -#define RK3026_PGA_SLOW_CLK_SFT 3 -#define RK3026_PGA_SLOW_CLK_EN (0x1 << 3) -#define RK3026_PGA_SLOW_CLK_DIS (0x0 << 3) - -#define RK3026_PGA_ASR_MASK 0x7 -#define RK3026_PGA_ASR_SFT 0 -#define RK3026_PGA_ASR_8KHz 0x7 -#define RK3026_PGA_ASR_12KHz 0x6 -#define RK3026_PGA_ASR_16KHz 0x5 -#define RK3026_PGA_ASR_24KHz 0x4 -#define RK3026_PGA_ASR_32KHz 0x3 -#define RK3026_PGA_ASR_441KHz 0x2 -#define RK3026_PGA_ASR_48KHz 0x1 -#define RK3026_PGA_ASR_96KHz 0x0 - -/* PGA AGC Control 5 (0xe4 0x124) */ -#define RK3026_PGA_AGC_MASK (0x1 << 6) -#define RK3026_PGA_AGC_SFT 6 -#define RK3026_PGA_AGC_EN (0x1 << 6) -#define RK3026_PGA_AGC_DIS (0x0 << 6) - -#define RK3026_PGA_AGC_MAX_G_MASK (0x7 << 3) -#define RK3026_PGA_AGC_MAX_G_SFT 3 -#define RK3026_PGA_AGC_MAX_G_28_5DB (0x7 << 3) -#define RK3026_PGA_AGC_MAX_G_22_5DB (0x6 << 3) -#define RK3026_PGA_AGC_MAX_G_16_5DB (0x5 << 3) -#define RK3026_PGA_AGC_MAX_G_10_5DB (0x4 << 3) -#define RK3026_PGA_AGC_MAX_G_4_5DB (0x3 << 3) -#define RK3026_PGA_AGC_MAX_G_N1_5DB (0x2 << 3) -#define RK3026_PGA_AGC_MAX_G_N7_5DB (0x1 << 3) -#define RK3026_PGA_AGC_MAX_G_N13_5DB (0x0 << 3) - -#define RK3026_PGA_AGC_MIN_G_MASK 0x7 -#define RK3026_PGA_AGC_MIN_G_SFT 0 -#define RK3026_PGA_AGC_MIN_G_24DB 0x7 -#define RK3026_PGA_AGC_MIN_G_18DB 0x6 -#define RK3026_PGA_AGC_MIN_G_12DB 0x5 -#define RK3026_PGA_AGC_MIN_G_6DB 0x4 -#define RK3026_PGA_AGC_MIN_G_0DB 0x3 -#define RK3026_PGA_AGC_MIN_G_N6DB 0x2 -#define RK3026_PGA_AGC_MIN_G_N12DB 0x1 -#define RK3026_PGA_AGC_MIN_G_N18DB 0x0 - -enum { - RK3026_HIFI, - RK3026_VOICE, -}; - -enum { - RK3026_MONO = 1, - RK3026_STEREO, -}; - -enum { - OFF, - RCV, - SPK_PATH, - HP_PATH, - HP_NO_MIC, - BT, - SPK_HP, - RING_SPK, - RING_HP, - RING_HP_NO_MIC, - RING_SPK_HP, -}; - -enum { - MIC_OFF, - Main_Mic, - Hands_Free_Mic, - BT_Sco_Mic, -}; - -struct rk3026_reg_val_typ { - unsigned int reg; - unsigned int value; -}; - -struct rk3026_init_bit_typ { - unsigned int reg; - unsigned int power_bit; - unsigned int init2_bit; - unsigned int init1_bit; - unsigned int init0_bit; -}; - -struct rk3026_codec_pdata { - int spk_ctl_gpio; - int hp_ctl_gpio; - int delay_time; -}; - -#endif //__RK3026_CODEC_H__ diff --git a/sound/soc/codecs/rk3036_codec.c b/sound/soc/codecs/rk3036_codec.c deleted file mode 100755 index a2af66533bf6..000000000000 --- a/sound/soc/codecs/rk3036_codec.c +++ /dev/null @@ -1,1132 +0,0 @@ -/* - * rk3036_codec.c - * - * Driver for rockchip rk3036 codec - * Copyright (C) 2014 - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "rk3036_codec.h" - -static int debug = -1; -module_param(debug, int, S_IRUGO|S_IWUSR); - -#define dbg_codec(level, fmt, arg...) \ - do { \ - if (debug >= level) \ - printk(fmt , ## arg); \ - } while (0) - -#define DBG(fmt, ...) dbg_codec(0, fmt, ## __VA_ARGS__) - - -#define INVALID_GPIO -1 -#define SPK_CTRL_OPEN 1 -#define SPK_CTRL_CLOSE 0 - -/* volume setting - * 0: -39dB - * 26: 0dB - * 31: 6dB - * Step: 1.5dB -*/ -#define OUT_VOLUME 26 - -#define CODECDEBUG 0 - -#if CODECDEBUG -static struct delayed_work debug_delayed_work; -#endif - -struct rk3036_codec_priv { - void __iomem *regbase; - struct snd_soc_codec *codec; - - unsigned int stereo_sysclk; - unsigned int rate; - - struct delayed_work codec_delayed_work; - struct delayed_work spk_ctrl_delayed_work; - int spk_ctl_gpio; - int delay_time; - - struct clk *pclk; -}; -static struct rk3036_codec_priv *rk3036_priv; - -static const unsigned int rk3036_reg_defaults[RK3036_CODEC_REG28+1] = { - [RK3036_CODEC_RESET] = 0x03, - [RK3036_CODEC_REG03] = 0x00, - [RK3036_CODEC_REG04] = 0x50, - [RK3036_CODEC_REG05] = 0x0E, - [RK3036_CODEC_REG22] = 0x00, - [RK3036_CODEC_REG23] = 0x00, - [RK3036_CODEC_REG24] = 0x00, - [RK3036_CODEC_REG25] = 0x00, - [RK3036_CODEC_REG26] = 0x00, - [RK3036_CODEC_REG27] = 0x05, - [RK3036_CODEC_REG28] = 0x00, -}; - -/* function declare: */ -static int rk3036_codec_register( - struct snd_soc_codec *codec, unsigned int reg); -static int rk3036_volatile_register( - struct snd_soc_codec *codec, unsigned int reg); -static int rk3036_set_bias_level( - struct snd_soc_codec *codec, enum snd_soc_bias_level level); -static unsigned int rk3036_codec_read( - struct snd_soc_codec *codec, unsigned int reg); -static inline void rk3036_write_reg_cache( - struct snd_soc_codec *codec, unsigned int reg, unsigned int value); - -static inline unsigned int rk3036_read_reg_cache(struct snd_soc_codec * - codec, unsigned int reg) -{ - unsigned int *cache = codec->reg_cache; - - if (rk3036_codec_register(codec, reg)) - return cache[reg]; - - DBG("%s : reg error!\n", __func__); - - return -EINVAL; -} - -static inline void rk3036_write_reg_cache(struct snd_soc_codec * - codec, unsigned int reg, unsigned int value) -{ - unsigned int *cache = codec->reg_cache; - - if (rk3036_codec_register(codec, reg)) { - cache[reg] = value; - return; - } - - DBG("%s : reg error!\n", __func__); -} - -static int rk3036_reset(struct snd_soc_codec *codec) -{ - writel(0x00, rk3036_priv->regbase+RK3036_CODEC_RESET); - mdelay(10); - writel(0x03, rk3036_priv->regbase+RK3036_CODEC_RESET); - mdelay(10); - memcpy(codec->reg_cache, rk3036_reg_defaults, - sizeof(rk3036_reg_defaults)); - return 0; -} - -static int rk3036_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec *codec = rtd->codec; - struct rk3036_codec_priv *rk3036 = rk3036_priv; - unsigned int dac_aif1 = 0, dac_aif2 = 0; - - if (!rk3036) { - DBG("%s : rk3036 is NULL\n", __func__); - return -EINVAL; - } - dac_aif2 |= RK3036_CR05_FRAMEH_32BITS; - - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: - dac_aif1 |= RK3036_CR04_HFVALID_16BITS; - break; - case SNDRV_PCM_FORMAT_S20_3LE: - dac_aif1 |= RK3036_CR04_HFVALID_20BITS; - break; - case SNDRV_PCM_FORMAT_S24_LE: - dac_aif1 |= RK3036_CR04_HFVALID_24BITS; - break; - case SNDRV_PCM_FORMAT_S32_LE: - dac_aif1 |= RK3036_CR04_HFVALID_32BITS; - break; - default: - return -EINVAL; - } - - dac_aif1 |= RK3036_CR04_LR_SWAP_DIS; - dac_aif2 |= RK3036_CR05_DAC_RESET_DIS; - - snd_soc_update_bits( - codec, RK3036_CODEC_REG04, - RK3036_CR04_HFVALID_MASK - |RK3036_CR04_LR_SWAP_MASK, dac_aif1); - snd_soc_update_bits( - codec, RK3036_CODEC_REG05, - RK3036_CR05_FRAMEH_MASK - |RK3036_CR05_DAC_RESET_MASK, dac_aif2); - - return 0; -} - -static int rk3036_set_dai_fmt(struct snd_soc_dai *codec_dai, - unsigned int fmt) -{ - struct snd_soc_codec *codec = codec_dai->codec; - unsigned int fmt_ms = 0, dac_aif1 = 0, dac_aif2 = 0; - - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: - fmt_ms |= RK3036_CR03_DIRECTION_IN|RK3036_CR03_I2SMODE_SLAVE; - break; - case SND_SOC_DAIFMT_CBM_CFM: - fmt_ms |= RK3036_CR03_DIRECTION_IOUT|RK3036_CR03_I2SMODE_MASTER; - break; - default: - DBG("%s : set master mask failed!\n", __func__); - return -EINVAL; - } - - switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_DSP_A: - dac_aif1 |= RK3036_CR04_MODE_PCM; - break; - case SND_SOC_DAIFMT_DSP_B: - break; - case SND_SOC_DAIFMT_I2S: - dac_aif1 |= RK3036_CR04_MODE_I2S; - break; - case SND_SOC_DAIFMT_RIGHT_J: - dac_aif1 |= RK3036_CR04_MODE_RIGHT; - break; - case SND_SOC_DAIFMT_LEFT_J: - dac_aif1 |= RK3036_CR04_MODE_LEFT; - break; - default: - DBG("%s : set format failed!\n", __func__); - return -EINVAL; - } - - switch (fmt & SND_SOC_DAIFMT_INV_MASK) { - case SND_SOC_DAIFMT_NB_NF: - dac_aif1 |= RK3036_CR04_I2SLRC_NORMAL; - dac_aif2 |= RK3036_CR05_BCLKPOL_NORMAL; - break; - case SND_SOC_DAIFMT_IB_IF: - dac_aif1 |= RK3036_CR04_I2SLRC_REVERSAL; - dac_aif2 |= RK3036_CR05_BCLKPOL_REVERSAL; - break; - case SND_SOC_DAIFMT_IB_NF: - dac_aif1 |= RK3036_CR04_I2SLRC_REVERSAL; - dac_aif2 |= RK3036_CR05_BCLKPOL_NORMAL; - break; - case SND_SOC_DAIFMT_NB_IF: - dac_aif1 |= RK3036_CR04_I2SLRC_NORMAL; - dac_aif2 |= RK3036_CR05_BCLKPOL_REVERSAL; - break; - default: - DBG("%s : set dai format failed!\n", __func__); - return -EINVAL; - } - - snd_soc_update_bits( - codec, RK3036_CODEC_REG03, - RK3036_CR03_DIRECTION_MASK - |RK3036_CR03_I2SMODE_MASK, fmt_ms); - snd_soc_update_bits( - codec, RK3036_CODEC_REG04, - RK3036_CR04_I2SLRC_MASK - | RK3036_CR04_MODE_MASK, dac_aif1); - snd_soc_update_bits( - codec, RK3036_CODEC_REG05, - RK3036_CR05_BCLKPOL_MASK, dac_aif2); - return 0; -} - -static int rk3036_set_dai_sysclk(struct snd_soc_dai *codec_dai, - int clk_id, unsigned int freq, int dir) -{ - struct rk3036_codec_priv *rk3036 = rk3036_priv; - - if (!rk3036) { - DBG("%s : rk3036 is NULL\n", __func__); - return -EINVAL; - } - - rk3036->stereo_sysclk = freq; - - return 0; -} - -static int rk3036_digital_mute(struct snd_soc_dai *dai, int mute) -{ - struct snd_soc_codec *codec = dai->codec; - unsigned int val; - - DBG("rk3036_digital_mute = %d\n", mute); - if (mute) { - val = snd_soc_read(codec, RK3036_CODEC_REG27); - if (val & (RK3036_CR27_HPOUTL_G_WORK - |RK3036_CR27_HPOUTR_G_WORK)) { - val &= ~RK3036_CR27_HPOUTL_G_WORK; - val &= ~RK3036_CR27_HPOUTR_G_WORK; - snd_soc_write(codec, RK3036_CODEC_REG27, val); - } - } else { - val = snd_soc_read(codec, RK3036_CODEC_REG27); - if ((val | ~RK3036_CR27_HPOUTL_G_WORK) || (val - | ~RK3036_CR27_HPOUTR_G_WORK)) { - val |= RK3036_CR27_HPOUTL_G_WORK - |RK3036_CR27_HPOUTR_G_WORK; - snd_soc_write(codec, RK3036_CODEC_REG27, val); - } - } - return 0; -} - -static int rk3036_codec_power_on(int wait_ms) -{ - struct snd_soc_codec *codec = rk3036_priv->codec; - - if (!rk3036_priv || !rk3036_priv->codec) - return -EINVAL; - - /* set a big current for capacitor charge. */ - snd_soc_write(codec, RK3036_CODEC_REG28, RK3036_CR28_YES_027I - |RK3036_CR28_YES_050I - |RK3036_CR28_YES_100I - |RK3036_CR28_YES_130I - |RK3036_CR28_YES_260I - |RK3036_CR28_YES_400I); - mdelay(10); - snd_soc_write(codec,RK3036_CODEC_REG27,((RK3036_CR27_DACL_WORK - |RK3036_CR27_DACR_WORK - |RK3036_CR27_HPOUTL_G_MUTE - |RK3036_CR27_HPOUTR_G_MUTE - |RK3036_CR27_HPOUTL_POP_WORK - |RK3036_CR27_HPOUTR_POP_WORK) & 0x00)); - mdelay(10); - snd_soc_write(codec, RK3036_CODEC_REG24, RK3036_CR24_DAC_SOURCE_STOP - |RK3036_CR24_DAC_PRECHARGE - |RK3036_CR24_DACL_REFV_STOP - |RK3036_CR24_DACR_REFV_STOP - |RK3036_CR24_VOUTL_ZEROD_STOP - |RK3036_CR24_VOUTR_ZEROD_STOP); - - /* wait for capacitor charge finish. */ - mdelay(wait_ms); - - - return 0; -} - -static struct rk3036_reg_val_typ codec_open_list_p[] = { - /*S1*/{RK3036_CODEC_REG24, - RK3036_CR24_DAC_SOURCE_WORK - |RK3036_CR24_DAC_PRECHARGE - |RK3036_CR24_DAC_PRECHARGE - |RK3036_CR24_DACL_REFV_STOP - |RK3036_CR24_DACR_REFV_STOP - |RK3036_CR24_VOUTL_ZEROD_STOP - |RK3036_CR24_VOUTR_ZEROD_STOP}, - /* open current source. */ - - /*S2*/{RK3036_CODEC_REG22, - RK3036_CR22_DACL_PATH_REFV_WORK - |RK3036_CR22_DACR_PATH_REFV_WORK - |RK3036_CR22_DACL_CLK_STOP - |RK3036_CR22_DACR_CLK_STOP - |RK3036_CR22_DACL_STOP - |RK3036_CR22_DACR_STOP}, - /* power on dac path reference voltage. */ - - /*S3*/{RK3036_CODEC_REG27, - RK3036_CR27_DACL_INIT - |RK3036_CR27_DACR_INIT - |RK3036_CR27_HPOUTL_G_MUTE - |RK3036_CR27_HPOUTR_G_MUTE - |RK3036_CR27_HPOUTL_POP_WORK - |RK3036_CR27_HPOUTR_POP_WORK}, - /* pop precharge work. */ - - /*S4*/{RK3036_CODEC_REG23, - RK3036_CR23_HPOUTL_INIT - |RK3036_CR23_HPOUTR_INIT - |RK3036_CR23_HPOUTL_EN_WORK - |RK3036_CR23_HPOUTR_EN_WORK}, - /* start-up HPOUTL HPOUTR */ - - /*S5*/{RK3036_CODEC_REG23, - RK3036_CR23_HPOUTL_WORK - |RK3036_CR23_HPOUTR_WORK - |RK3036_CR23_HPOUTL_EN_WORK - |RK3036_CR23_HPOUTR_EN_WORK}, - /* end the init state of HPOUTL HPOUTR */ - - /*S6*/{RK3036_CODEC_REG24, - RK3036_CR24_DAC_SOURCE_WORK - |RK3036_CR24_DAC_PRECHARGE - |RK3036_CR24_DACL_REFV_WORK - |RK3036_CR24_DACR_REFV_WORK - |RK3036_CR24_VOUTL_ZEROD_STOP - |RK3036_CR24_VOUTR_ZEROD_STOP}, - /* start-up special ref_v of DACL DACR */ - - /*S7*/{RK3036_CODEC_REG22, - RK3036_CR22_DACL_PATH_REFV_WORK - |RK3036_CR22_DACR_PATH_REFV_WORK - |RK3036_CR22_DACL_CLK_WORK - |RK3036_CR22_DACR_CLK_WORK - |RK3036_CR22_DACL_STOP - |RK3036_CR22_DACR_STOP}, - /* start-up clock modul of LR channel */ - - /*S8*/{RK3036_CODEC_REG22, - RK3036_CR22_DACL_PATH_REFV_WORK - |RK3036_CR22_DACR_PATH_REFV_WORK - |RK3036_CR22_DACL_CLK_WORK - |RK3036_CR22_DACR_CLK_WORK - |RK3036_CR22_DACL_WORK - |RK3036_CR22_DACR_WORK}, - /* start-up DACL DACR module */ - - /*S9*/{RK3036_CODEC_REG27, - RK3036_CR27_DACL_WORK - |RK3036_CR27_DACR_WORK - |RK3036_CR27_HPOUTL_G_MUTE - |RK3036_CR27_HPOUTR_G_MUTE - |RK3036_CR27_HPOUTL_POP_WORK - |RK3036_CR27_HPOUTR_POP_WORK}, - /* end the init state of DACL DACR */ - - /*S10*/{RK3036_CODEC_REG25, OUT_VOLUME}, - /*S10*/{RK3036_CODEC_REG26, OUT_VOLUME}, - - /*S11*/{RK3036_CODEC_REG24, - RK3036_CR24_DAC_SOURCE_WORK - |RK3036_CR24_DAC_PRECHARGE - |RK3036_CR24_DACL_REFV_WORK - |RK3036_CR24_DACR_REFV_WORK - |RK3036_CR24_VOUTL_ZEROD_STOP //RK3036_CR24_VOUTL_ZEROD_WORK - |RK3036_CR24_VOUTR_ZEROD_STOP}, //RK3036_CR24_VOUTR_ZEROD_WORK - /* according to the need, open the zero-crossing detection function. */ - - /*S12*/{RK3036_CODEC_REG27, - RK3036_CR27_DACL_WORK - |RK3036_CR27_DACR_WORK - |RK3036_CR27_HPOUTL_G_WORK - |RK3036_CR27_HPOUTR_G_WORK - |RK3036_CR27_HPOUTL_POP_WORK - |RK3036_CR27_HPOUTR_POP_WORK}, - /* end initial status of HPOUTL HPOUTR module,start normal output. */ -}; -#define OPEN_LIST_LEN_P ARRAY_SIZE(codec_open_list_p) - -static int rk3036_codec_open_p(void) -{ - struct snd_soc_codec *codec = rk3036_priv->codec; - int i, volume = 0; - - if (!rk3036_priv || !rk3036_priv->codec) - return -EINVAL; - - for (i = 0; i < OPEN_LIST_LEN_P; i++) { - if ((codec_open_list_p[i].reg == - RK3036_CODEC_REG25) && (volume < OUT_VOLUME)) { - snd_soc_write(codec, RK3036_CODEC_REG25, volume); - snd_soc_write(codec, RK3036_CODEC_REG26, volume); - volume++; - mdelay(10); - i--; - } else { - snd_soc_write(codec, codec_open_list_p[i].reg, codec_open_list_p[i].value); - mdelay(1); - } - } - - return 0; -} - -static struct rk3036_reg_val_typ codec_close_list_p[] = { - /*S1*/{RK3036_CODEC_REG24, - RK3036_CR24_DAC_SOURCE_WORK - |RK3036_CR24_DAC_PRECHARGE - |RK3036_CR24_DACL_REFV_WORK - |RK3036_CR24_DACR_REFV_WORK - |RK3036_CR24_VOUTL_ZEROD_STOP - |RK3036_CR24_VOUTR_ZEROD_STOP}, - - /*S2*/{RK3036_CODEC_REG25, 0x00}, - /*S2*/{RK3036_CODEC_REG26, 0x00}, - - /*S3*/{RK3036_CODEC_REG27, - RK3036_CR27_DACL_WORK - |RK3036_CR27_DACR_WORK - |RK3036_CR27_HPOUTL_G_MUTE - |RK3036_CR27_HPOUTR_G_MUTE - |RK3036_CR27_HPOUTL_POP_WORK - |RK3036_CR27_HPOUTR_POP_WORK}, - - /*S4*/{RK3036_CODEC_REG23, - RK3036_CR23_HPOUTL_WORK - |RK3036_CR23_HPOUTR_WORK - |RK3036_CR23_HPOUTL_EN_STOP - |RK3036_CR23_HPOUTR_EN_STOP}, - - /*S5*/{RK3036_CODEC_REG23, - RK3036_CR23_HPOUTL_INIT - |RK3036_CR23_HPOUTR_INIT - |RK3036_CR23_HPOUTL_EN_STOP - |RK3036_CR23_HPOUTR_EN_STOP}, - - /*S6*/{RK3036_CODEC_REG27, - RK3036_CR27_DACL_WORK - |RK3036_CR27_DACR_WORK - |RK3036_CR27_HPOUTL_G_MUTE - |RK3036_CR27_HPOUTR_G_MUTE - |RK3036_CR27_HPOUTL_POP_PRECHARGE - |RK3036_CR27_HPOUTR_POP_PRECHARGE}, - - /*S7*/{RK3036_CODEC_REG22, - RK3036_CR22_DACL_PATH_REFV_STOP - |RK3036_CR22_DACR_PATH_REFV_STOP - |RK3036_CR22_DACL_CLK_STOP - |RK3036_CR22_DACR_CLK_STOP - |RK3036_CR22_DACL_STOP - |RK3036_CR22_DACR_STOP}, - - /*S8*/{RK3036_CODEC_REG24, - RK3036_CR24_DAC_SOURCE_STOP - |RK3036_CR24_DAC_PRECHARGE - |RK3036_CR24_DACL_REFV_STOP - |RK3036_CR24_DACR_REFV_STOP - |RK3036_CR24_VOUTL_ZEROD_STOP - |RK3036_CR24_VOUTR_ZEROD_STOP}, - - /*S9*/{RK3036_CODEC_REG27, - RK3036_CR27_DACL_INIT - |RK3036_CR27_DACR_INIT - |RK3036_CR27_HPOUTL_G_MUTE - |RK3036_CR27_HPOUTR_G_MUTE - |RK3036_CR27_HPOUTL_POP_PRECHARGE - |RK3036_CR27_HPOUTR_POP_PRECHARGE}, - -}; -#define CLOSE_LIST_LEN_P ARRAY_SIZE(codec_close_list_p) - -static int rk3036_codec_close_p(void) -{ - struct snd_soc_codec *codec = rk3036_priv->codec; - int i, volume = 0; - - if (!rk3036_priv || !rk3036_priv->codec) - return -EINVAL; - - for (i = 0; i < CLOSE_LIST_LEN_P; i++) { - if ((codec_close_list_p[i].reg == - RK3036_CODEC_REG25) && (volume > 0)) { - snd_soc_write(codec, RK3036_CODEC_REG25, volume); - snd_soc_write(codec, RK3036_CODEC_REG26, volume); - volume++; - mdelay(10); - i--; - } else { - snd_soc_write(codec, codec_close_list_p[i].reg, codec_close_list_p[i].value); - mdelay(1); - } - } - - return 0; -} - -static int rk3036_codec_power_off(int wait_ms) -{ - struct snd_soc_codec *codec = rk3036_priv->codec; - - if (!rk3036_priv || !rk3036_priv->codec) - return -EINVAL; - - /* set a big current for capacitor discharge. */ - snd_soc_write(codec, RK3036_CODEC_REG28, RK3036_CR28_YES_027I - |RK3036_CR28_YES_050I - |RK3036_CR28_YES_100I - |RK3036_CR28_YES_130I - |RK3036_CR28_YES_260I - |RK3036_CR28_YES_400I); - - /* start discharge. */ - snd_soc_write(codec, RK3036_CODEC_REG24, RK3036_CR24_DAC_SOURCE_STOP - |RK3036_CR24_DAC_DISCHARGE - |RK3036_CR24_DACL_REFV_STOP - |RK3036_CR24_DACR_REFV_STOP - |RK3036_CR24_VOUTL_ZEROD_STOP - |RK3036_CR24_VOUTR_ZEROD_STOP); - - /* wait for capacitor discharge finish. */ - mdelay(wait_ms); - - return 0; -} - -#define RK3036_PLAYBACK_RATES (SNDRV_PCM_RATE_8000 |\ - SNDRV_PCM_RATE_16000 | \ - SNDRV_PCM_RATE_32000 | \ - SNDRV_PCM_RATE_44100 | \ - SNDRV_PCM_RATE_48000 | \ - SNDRV_PCM_RATE_96000) - -#define RK3036_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ - SNDRV_PCM_FMTBIT_S20_3LE |\ - SNDRV_PCM_FMTBIT_S24_LE |\ - SNDRV_PCM_FMTBIT_S32_LE) - - -static struct snd_soc_dai_ops rk3036_dai_ops = { - .hw_params = rk3036_hw_params, - .set_fmt = rk3036_set_dai_fmt, - .set_sysclk = rk3036_set_dai_sysclk, - .digital_mute = rk3036_digital_mute, -}; - -static struct snd_soc_dai_driver rk3036_dai[] = { - { - .name = "rk3036-voice", - .id = RK3036_VOICE, - .playback = { - .stream_name = "RK3036 CODEC PCM", - .channels_min = 1, - .channels_max = 2, - .rates = RK3036_PLAYBACK_RATES, - .formats = RK3036_FORMATS, - }, - .ops = &rk3036_dai_ops, - }, -}; - -static unsigned int rk3036_codec_read(struct snd_soc_codec * - codec, unsigned int reg) -{ - unsigned int value; - - if (!rk3036_priv) { - DBG("%s : rk3036 is NULL\n", __func__); - return -EINVAL; - } - - if (!rk3036_codec_register(codec, reg)) { - DBG("%s : reg error!\n", __func__); - return -EINVAL; - } - - value = readl_relaxed(rk3036_priv->regbase+reg); - DBG("%s : reg = 0x%x, val= 0x%x\n", __func__, reg, value); - - return value; -} - -static int rk3036_hw_write(const struct i2c_client * - client, const char *buf, int count) -{ - unsigned int reg, value; - - if (!rk3036_priv || !rk3036_priv->codec) - return -EINVAL; - - if (count == 2) { - reg = (unsigned int)buf[0]; - value = (unsigned int)buf[1]; - writel(value, rk3036_priv->regbase+reg); - } else { - DBG("%s : i2c len error\n", __func__); - } - - return count; -} - -static int rk3036_codec_write(struct snd_soc_codec * - codec, unsigned int reg, unsigned int value) -{ - int new_value = -1; - - if (!rk3036_priv) { - DBG("%s : rk3036 is NULL\n", __func__); - return -EINVAL; - } else if (!rk3036_codec_register(codec, reg)) { - DBG("%s : reg error!\n", __func__); - return -EINVAL; - } - - /*new_value = rk3036_set_init_value(codec, reg, value);*/ - if (new_value == -1) { - writel(value, rk3036_priv->regbase+reg); - rk3036_write_reg_cache(codec, reg, value); - } - - return 0; -} - -static void spk_ctrl_fun(int status) -{ - if (rk3036_priv == NULL) - return; - - if (rk3036_priv->spk_ctl_gpio != INVALID_GPIO) - gpio_set_value(rk3036_priv->spk_ctl_gpio, status); -} - -static void codec_delayedwork_fun(struct work_struct *work) -{ - DBG("codec_delayedwork_fun\n"); - - /* codec start up. */ - rk3036_codec_open_p(); - - /* for sure, start codec again. */ - mdelay(200); - rk3036_codec_open_p(); -} - -static void spk_ctrl_delayedwork_fun(struct work_struct *work) -{ - if (rk3036_priv == NULL) - return; - DBG("spk_ctrl_delayedwork_fun\n"); - spk_ctrl_fun(SPK_CTRL_OPEN); -} - -#if CODECDEBUG -static int delay_time_try = 10; -static void rk3036_cmd_fun(struct work_struct *work) -{ - unsigned int cmd; - unsigned int next_delay; - - if (rk3036_priv == NULL) - return; - - cmd = readl_relaxed(rk3036_priv->regbase+(0x0d << 2)); - if (cmd == 0x50) - return; - - writel(0, rk3036_priv->regbase+(0x0d << 2)); - if (cmd) - { - printk("\n\n\n\n\n"); - printk("===rk3036_cmd_fun cmd :=> %d\n\n", cmd); - } - - next_delay = 500; - switch(cmd) - { - case 1: - delay_time_try = -1; - printk("rk3036_codec_close_p\n"); - rk3036_codec_close_p(); - break; - - case 2: - printk("rk3036_codec_power_off\n"); - rk3036_codec_power_off(0); - break; - - case 3: - printk("reset+rk3036_codec_power_on\n"); - writel(0x00, rk3036_priv->regbase + RK3036_CODEC_RESET); - mdelay(10); - writel(0x03, rk3036_priv->regbase + RK3036_CODEC_RESET); - mdelay(10); - rk3036_codec_power_on(10); - break; - - case 4: - printk("rk3036_codec_open_p\n"); - rk3036_codec_open_p(); - break; - - case 12: - printk("rk3036_codec_close_p\n"); - rk3036_codec_close_p(); - printk("rk3036_codec_power_off\n"); - rk3036_codec_power_off(0); - break; - - case 34: - delay_time_try += 10; - printk("reset+rk3036_codec_power_on delay_time_try=%d\n", delay_time_try); - writel(0x00, rk3036_priv->regbase + RK3036_CODEC_RESET); - mdelay(10); - writel(0x03, rk3036_priv->regbase + RK3036_CODEC_RESET); - mdelay(10); - rk3036_codec_power_on(delay_time_try/2); - printk("rk3036_codec_open_p\n"); - rk3036_codec_open_p(); - - printk("reset+rk3036_codec_power_on delay_time_try=%d\n", delay_time_try); - writel(0x00, rk3036_priv->regbase + RK3036_CODEC_RESET); - mdelay(10); - writel(0x03, rk3036_priv->regbase + RK3036_CODEC_RESET); - mdelay(10); - rk3036_codec_power_on(delay_time_try/2); - printk("rk3036_codec_open_p\n"); - rk3036_codec_open_p(); - break; - - case 43: - delay_time_try -= 10; - printk("reset+rk3036_codec_power_on delay_time_try=%d\n", delay_time_try); - writel(0x00, rk3036_priv->regbase + RK3036_CODEC_RESET); - mdelay(10); - writel(0x03, rk3036_priv->regbase + RK3036_CODEC_RESET); - mdelay(10); - rk3036_codec_power_on(delay_time_try); - printk("rk3036_codec_open_p\n"); - rk3036_codec_open_p(); - break; - - case 37: - printk("rk3036_codec_close_p\n"); - rk3036_codec_close_p(); - printk("rk3036_codec_power_off\n"); - rk3036_codec_power_off(0); - writel(73, rk3036_priv->regbase+(0x0d << 2)); - next_delay = 1000; - break; - - case 73: - printk("reset+rk3036_codec_power_on\n"); - writel(0x00, rk3036_priv->regbase + RK3036_CODEC_RESET); - mdelay(10); - writel(0x03, rk3036_priv->regbase + RK3036_CODEC_RESET); - mdelay(10); - rk3036_codec_power_on(10); - printk("rk3036_codec_open_p\n"); - rk3036_codec_open_p(); - writel(37, rk3036_priv->regbase+(0x0d << 2)); - next_delay = 2000; - break; - - default: - break; - } - schedule_delayed_work(&debug_delayed_work, msecs_to_jiffies(next_delay)); -} -#endif - -static int rk3036_probe(struct snd_soc_codec *codec) -{ - struct rk3036_codec_priv *rk3036_codec - = snd_soc_codec_get_drvdata(codec); - unsigned int val; - int ret; - - rk3036_codec->codec = codec; - - clk_prepare_enable(rk3036_codec->pclk); - - ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C); - if (ret != 0) - goto err__; - - codec->hw_read = rk3036_codec_read; - codec->hw_write = (hw_write_t)rk3036_hw_write; - codec->read = rk3036_codec_read; - codec->write = rk3036_codec_write; - - INIT_DELAYED_WORK(&rk3036_codec->codec_delayed_work, - codec_delayedwork_fun); - - INIT_DELAYED_WORK(&rk3036_codec->spk_ctrl_delayed_work, - spk_ctrl_delayedwork_fun); - - val = snd_soc_read(codec, RK3036_CODEC_RESET); - if (val != rk3036_reg_defaults[RK3036_CODEC_RESET]) { - ret = -ENODEV; - goto err__; - } - - /* config i2s output to acodec module. */ - val = readl_relaxed(RK_GRF_VIRT + RK3036_GRF_SOC_CON0); - writel_relaxed(val | 0x04000400, RK_GRF_VIRT + RK3036_GRF_SOC_CON0); - - /* codec reset. */ - rk3036_reset(codec); - - /* discharge the capacity at frist. */ - rk3036_codec_power_off(20); - - /* codec power on. */ - rk3036_codec_power_on(200); - - schedule_delayed_work(&rk3036_codec->codec_delayed_work, - msecs_to_jiffies(6000));/* codec_delayedwork_fun */ - codec->dapm.bias_level = SND_SOC_BIAS_PREPARE; - - schedule_delayed_work(&rk3036_codec->spk_ctrl_delayed_work, - msecs_to_jiffies(5000));/* spk_ctrl_delayedwork_fun */ - -#if CODECDEBUG - INIT_DELAYED_WORK(&debug_delayed_work, rk3036_cmd_fun); - schedule_delayed_work(&debug_delayed_work, msecs_to_jiffies(1000)); -#endif - - return 0; - -err__: - DBG("%s err ret=%d\n", __func__, ret); - return ret; -} - -static int rk3036_remove(struct snd_soc_codec *codec) -{ - if (!rk3036_priv) { - DBG("%s : rk3036_priv is NULL\n", __func__); - return 0; - } - - spk_ctrl_fun(SPK_CTRL_CLOSE); - - rk3036_codec_close_p(); - - return 0; -} - -static int rk3036_suspend(struct snd_soc_codec *codec) -{ - rk3036_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - -static int rk3036_resume(struct snd_soc_codec *codec) -{ - rk3036_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - return 0; -} - -static int rk3036_set_bias_level(struct snd_soc_codec *codec, enum - snd_soc_bias_level level) -{ - switch (level) { - case SND_SOC_BIAS_ON: - break; - - case SND_SOC_BIAS_PREPARE: - break; - - case SND_SOC_BIAS_STANDBY: - break; - - case SND_SOC_BIAS_OFF: - break; - } - codec->dapm.bias_level = level; - return 0; -} - -static int rk3036_volatile_register(struct snd_soc_codec * - codec, unsigned int reg) -{ - switch (reg) { - case RK3036_CODEC_RESET: - return 1; - default: - return 0; - } -} - -static int rk3036_codec_register(struct snd_soc_codec *codec, unsigned int reg) -{ - switch (reg) { - case RK3036_CODEC_RESET: - case RK3036_CODEC_REG03: - case RK3036_CODEC_REG04: - case RK3036_CODEC_REG05: - case RK3036_CODEC_REG22: - case RK3036_CODEC_REG23: - case RK3036_CODEC_REG24: - case RK3036_CODEC_REG25: - case RK3036_CODEC_REG26: - case RK3036_CODEC_REG27: - case RK3036_CODEC_REG28: - return 1; - default: - return 0; - } -} - -static struct snd_soc_codec_driver soc_codec_dev_rk3036 = { - .probe = rk3036_probe, - .remove = rk3036_remove, - .suspend = rk3036_suspend, - .resume = rk3036_resume, - .set_bias_level = rk3036_set_bias_level, - .reg_cache_size = ARRAY_SIZE(rk3036_reg_defaults), - .reg_word_size = sizeof(unsigned int), - .reg_cache_default = rk3036_reg_defaults, - .volatile_register = rk3036_volatile_register, - .readable_register = rk3036_codec_register, - .reg_cache_step = sizeof(unsigned int), -}; - -#ifdef CONFIG_PM -static int rk3036_codec_suspend_noirq(struct device *dev) -{ - spk_ctrl_fun(SPK_CTRL_CLOSE); - - /* close the codec */ - rk3036_codec_close_p(); - - /* power off the codec */ - rk3036_codec_power_off(10); - - return 0; -} - -static int rk3036_codec_resume_noirq(struct device *dev) -{ - struct snd_soc_codec *codec = rk3036_priv->codec; - - /* codec reset. */ - rk3036_reset(codec); - - /* codec power on. */ - rk3036_codec_power_on(100); - - /* codec start up. */ - rk3036_codec_open_p(); - - spk_ctrl_fun(SPK_CTRL_OPEN); - - return 0; -} -#else -/*#define rk3036_codec_suspend_noirq NULL*/ -/*#define rk3036_codec_resume_noirq NULL*/ -#endif - -static int rk3036_platform_probe(struct platform_device *pdev) -{ - struct device_node *rk3036_np = pdev->dev.of_node; - struct rk3036_codec_priv *rk3036; - struct resource *res; - int ret; - - rk3036 = devm_kzalloc(&pdev->dev, sizeof(*rk3036), GFP_KERNEL); - if (!rk3036) { - DBG("%s : rk3036 priv kzalloc failed!\n", __func__); - return -ENOMEM; - } - rk3036_priv = rk3036; - platform_set_drvdata(pdev, rk3036); - - rk3036->spk_ctl_gpio = of_get_named_gpio(rk3036_np, "spk_ctl_io", 0); - if (!gpio_is_valid(rk3036->spk_ctl_gpio)) { - DBG("invalid reset_gpio: %d\n", rk3036->spk_ctl_gpio); - ret = -ENOENT; - goto err__; - } - - ret = devm_gpio_request(&pdev->dev, rk3036->spk_ctl_gpio, "spk_ctl"); - if (ret < 0) { - DBG("rk3036_platform_probe spk_ctl_gpio fail\n"); - goto err__; - } - - gpio_direction_output(rk3036->spk_ctl_gpio, SPK_CTRL_CLOSE); - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - rk3036->regbase = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(rk3036->regbase)) - return PTR_ERR(rk3036->regbase); - - rk3036->pclk = devm_clk_get(&pdev->dev, "g_pclk_acodec"); - if (IS_ERR(rk3036->pclk)) { - dev_err(&pdev->dev, "Unable to get acodec hclk\n"); - ret = -ENXIO; - goto err__; - } - - return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_rk3036, - rk3036_dai, ARRAY_SIZE(rk3036_dai)); - -err__: - platform_set_drvdata(pdev, NULL); - rk3036_priv = NULL; - return ret; -} - -static int rk3036_platform_remove(struct platform_device *pdev) -{ - rk3036_priv = NULL; - snd_soc_unregister_codec(&pdev->dev); - return 0; -} - -void rk3036_platform_shutdown(struct platform_device *pdev) -{ - if (!rk3036_priv || !rk3036_priv->codec) - return; - - spk_ctrl_fun(SPK_CTRL_CLOSE); - - mdelay(10); - writel(0xfc, rk3036_priv->regbase + RK3036_CODEC_RESET); - mdelay(10); - writel(0x03, rk3036_priv->regbase + RK3036_CODEC_RESET); -} - -#ifdef CONFIG_OF -static const struct of_device_id rk3036codec_of_match[] = { - { .compatible = "rk3036-codec"}, - {}, -}; -MODULE_DEVICE_TABLE(of, rk3036codec_of_match); -#endif - -static const struct dev_pm_ops rk3036_codec_pm_ops = { - .suspend_noirq = rk3036_codec_suspend_noirq, - .resume_noirq = rk3036_codec_resume_noirq, -}; - -static struct platform_driver rk3036_codec_driver = { - .driver = { - .name = "rk3036-codec", - .owner = THIS_MODULE, - .of_match_table = of_match_ptr(rk3036codec_of_match), - .pm = &rk3036_codec_pm_ops, - }, - .probe = rk3036_platform_probe, - .remove = rk3036_platform_remove, - .shutdown = rk3036_platform_shutdown, -}; -module_platform_driver(rk3036_codec_driver); - -/* Module information */ -MODULE_AUTHOR("rockchip"); -MODULE_DESCRIPTION("ROCKCHIP i2s ASoC Interface"); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/rk3036_codec.h b/sound/soc/codecs/rk3036_codec.h deleted file mode 100644 index f2bd98103f31..000000000000 --- a/sound/soc/codecs/rk3036_codec.h +++ /dev/null @@ -1,160 +0,0 @@ -/* - * - * Copyright (C) 2014 rockchip - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ - -#ifndef _RK3036_CODEC_H -#define _RK3036_CODEC_H - -/* codec register */ -#define RK3036_CODEC_RESET (0x00 << 2) -#define RK3036_CODEC_REG03 (0x03 << 2) -#define RK3036_CODEC_REG04 (0x04 << 2) -#define RK3036_CODEC_REG05 (0x05 << 2) - -#define RK3036_CODEC_REG22 (0x22 << 2) -#define RK3036_CODEC_REG23 (0x23 << 2) -#define RK3036_CODEC_REG24 (0x24 << 2) -#define RK3036_CODEC_REG25 (0x25 << 2) -#define RK3036_CODEC_REG26 (0x26 << 2) -#define RK3036_CODEC_REG27 (0x27 << 2) -#define RK3036_CODEC_REG28 (0x28 << 2) - -/* RK3036_CODEC_RESET */ -#define RK3036_CR00_DIGITAL_RESET (0 << 1) -#define RK3036_CR00_DIGITAL_WORK (1 << 1) -#define RK3036_CR00_SYSTEM_RESET (0 << 0) -#define RK3036_CR00_SYSTEM_WORK (1 << 0) - -/*RK3036_CODEC_REG03*/ -#define RK3036_CR03_DIRECTION_MASK (1 << 5) -#define RK3036_CR03_DIRECTION_IN (0 << 5) -#define RK3036_CR03_DIRECTION_IOUT (1 << 5) -#define RK3036_CR03_I2SMODE_MASK (1 << 4) -#define RK3036_CR03_I2SMODE_SLAVE (0 << 4) -#define RK3036_CR03_I2SMODE_MASTER (1 << 4) - -/*RK3036_CODEC_REG04*/ -#define RK3036_CR04_I2SLRC_MASK (1 << 7) -#define RK3036_CR04_I2SLRC_NORMAL (0 << 7) -#define RK3036_CR04_I2SLRC_REVERSAL (1 << 7) -#define RK3036_CR04_HFVALID_MASK (3 << 5) -#define RK3036_CR04_HFVALID_16BITS (0 << 5) -#define RK3036_CR04_HFVALID_20BITS (1 << 5) -#define RK3036_CR04_HFVALID_24BITS (2 << 5) -#define RK3036_CR04_HFVALID_32BITS (3 << 5) -#define RK3036_CR04_MODE_MASK (3 << 3) -#define RK3036_CR04_MODE_RIGHT (0 << 3) -#define RK3036_CR04_MODE_LEFT (1 << 3) -#define RK3036_CR04_MODE_I2S (2 << 3) -#define RK3036_CR04_MODE_PCM (3 << 3) -#define RK3036_CR04_LR_SWAP_MASK (1 << 2) -#define RK3036_CR04_LR_SWAP_DIS (0 << 2) -#define RK3036_CR04_LR_SWAP_EN (1 << 2) - -/*RK3036_CODEC_REG05*/ -#define RK3036_CR05_FRAMEH_MASK (3 << 2) -#define RK3036_CR05_FRAMEH_16BITS (0 << 2) -#define RK3036_CR05_FRAMEH_20BITS (1 << 2) -#define RK3036_CR05_FRAMEH_24BITS (2 << 2) -#define RK3036_CR05_FRAMEH_32BITS (3 << 2) -#define RK3036_CR05_DAC_RESET_MASK (1 << 1) -#define RK3036_CR05_DAC_RESET_EN (0 << 1) -#define RK3036_CR05_DAC_RESET_DIS (1 << 1) -#define RK3036_CR05_BCLKPOL_MASK (1 << 0) -#define RK3036_CR05_BCLKPOL_NORMAL (0 << 0) -#define RK3036_CR05_BCLKPOL_REVERSAL (1 << 0) - -/*RK3036_CODEC_REG22*/ -#define RK3036_CR22_DACL_PATH_REFV_MASK (1 << 5) -#define RK3036_CR22_DACL_PATH_REFV_STOP (0 << 5) -#define RK3036_CR22_DACL_PATH_REFV_WORK (1 << 5) -#define RK3036_CR22_DACR_PATH_REFV_MASK (1 << 4) -#define RK3036_CR22_DACR_PATH_REFV_STOP (0 << 4) -#define RK3036_CR22_DACR_PATH_REFV_WORK (1 << 4) -#define RK3036_CR22_DACL_CLK_STOP (0 << 3) -#define RK3036_CR22_DACL_CLK_WORK (1 << 3) -#define RK3036_CR22_DACR_CLK_STOP (0 << 2) -#define RK3036_CR22_DACR_CLK_WORK (1 << 2) -#define RK3036_CR22_DACL_STOP (0 << 1) -#define RK3036_CR22_DACL_WORK (1 << 1) -#define RK3036_CR22_DACR_STOP (0 << 0) -#define RK3036_CR22_DACR_WORK (1 << 0) - -/*RK3036_CODEC_REG23*/ -#define RK3036_CR23_HPOUTL_INIT (0 << 3) -#define RK3036_CR23_HPOUTL_WORK (1 << 3) -#define RK3036_CR23_HPOUTR_INIT (0 << 2) -#define RK3036_CR23_HPOUTR_WORK (1 << 2) -#define RK3036_CR23_HPOUTL_EN_STOP (0 << 1) -#define RK3036_CR23_HPOUTL_EN_WORK (1 << 1) -#define RK3036_CR23_HPOUTR_EN_STOP (0 << 0) -#define RK3036_CR23_HPOUTR_EN_WORK (1 << 0) - -/*RK3036_CODEC_REG24*/ -#define RK3036_CR24_DAC_SOURCE_STOP (0 << 5) -#define RK3036_CR24_DAC_SOURCE_WORK (1 << 5) -#define RK3036_CR24_DAC_PRECHARGE (0 << 4) -#define RK3036_CR24_DAC_DISCHARGE (1 << 4) -#define RK3036_CR24_DACL_REFV_STOP (0 << 3) -#define RK3036_CR24_DACL_REFV_WORK (1 << 3) -#define RK3036_CR24_DACR_REFV_STOP (0 << 2) -#define RK3036_CR24_DACR_REFV_WORK (1 << 2) -#define RK3036_CR24_VOUTL_ZEROD_STOP (0 << 1) -#define RK3036_CR24_VOUTL_ZEROD_WORK (1 << 1) -#define RK3036_CR24_VOUTR_ZEROD_STOP (0 << 0) -#define RK3036_CR24_VOUTR_ZEROD_WORK (1 << 0) - -/*RK3036_CODEC_REG27*/ -#define RK3036_CR27_DACL_INIT (0 << 7) -#define RK3036_CR27_DACL_WORK (1 << 7) -#define RK3036_CR27_DACR_INIT (0 << 6) -#define RK3036_CR27_DACR_WORK (1 << 6) -#define RK3036_CR27_HPOUTL_G_MUTE (0 << 5) -#define RK3036_CR27_HPOUTL_G_WORK (1 << 5) -#define RK3036_CR27_HPOUTR_G_MUTE (0 << 4) -#define RK3036_CR27_HPOUTR_G_WORK (1 << 4) -#define RK3036_CR27_HPOUTL_POP_PRECHARGE (1 << 2) -#define RK3036_CR27_HPOUTL_POP_WORK (2 << 2) -#define RK3036_CR27_HPOUTR_POP_PRECHARGE (1 << 0) -#define RK3036_CR27_HPOUTR_POP_WORK (2 << 0) - -/*RK3036_CODEC_REG28*/ -#define RK3036_CR28_YES_027I (0 << 5) -#define RK3036_CR28_NON_027I (1 << 5) -#define RK3036_CR28_YES_050I (0 << 4) -#define RK3036_CR28_NON_050I (1 << 4) -#define RK3036_CR28_YES_100I (0 << 3) -#define RK3036_CR28_NON_100I (1 << 3) -#define RK3036_CR28_YES_130I (0 << 2) -#define RK3036_CR28_NON_130I (1 << 2) -#define RK3036_CR28_YES_260I (0 << 1) -#define RK3036_CR28_NON_260I (1 << 1) -#define RK3036_CR28_YES_400I (0 << 0) -#define RK3036_CR28_NON_400I (1 << 0) - -enum { - RK3036_HIFI, - RK3036_VOICE, -}; - -struct rk3036_reg_val_typ { - unsigned int reg; - unsigned int value; -}; - -struct rk3036_init_bit_typ { - unsigned int reg; - unsigned int power_bit; - unsigned int init2_bit; - unsigned int init1_bit; - unsigned int init0_bit; -}; - -#endif diff --git a/sound/soc/codecs/rk3190_codec.c b/sound/soc/codecs/rk3190_codec.c deleted file mode 100644 index 14ee4e55d2bc..000000000000 --- a/sound/soc/codecs/rk3190_codec.c +++ /dev/null @@ -1,2278 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * rk3190_codec.c -- RK3190 CODEC ALSA SoC audio driver - * - * Copyright 2013 Rockchip - * Author: zhangjun - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "rk3190_codec.h" - -#ifdef CONFIG_RK_HEADSET_DET -#include "../../../drivers/headset_observe/rk_headset.h" -#endif - -#if 0 -#define DBG(x...) printk(KERN_INFO x) -#else -#define DBG(x...) -#endif - -/* volume setting - * 0: -39dB - * 26: 0dB - * 31: 6dB - * Step: 1.5dB -*/ -#define OUT_VOLUME 26//0~31 - -/* capture vol set - * 0: -18db - * 12: 0db - * 31: 28.5db - * step: 1.5db -*/ -#define CAP_VOL 18//0-31 - -//with capacity or not -#define WITH_CAP -#define SPK_AMP_DELAY 200 -#define HP_MOS_DELAY 200 -#ifdef CONFIG_MACH_RK_FAC - rk3190_hdmi_ctrl=0; -#endif - -#define GPIO_LOW 0 -#define GPIO_HIGH 1 -#define INVALID_GPIO -1 - -struct rk3190_codec_priv { - struct snd_soc_codec *codec; - - unsigned int stereo_sysclk; - unsigned int rate; - - int playback_active; - int capture_active; - - int spk_ctl_gpio; - int hp_ctl_gpio; - int ear_ctl_gpio; - int mic_sel_gpio; - int delay_time; - - long int playback_path; - long int capture_path; - long int voice_call_path; - - int regbase; - int regbase_phy; - int regsize_phy; - struct clk *pclk; -}; - -static struct rk3190_codec_priv *rk3190_priv = NULL; - -#define RK3190_CODEC_ALL 0 -#define RK3190_CODEC_PLAYBACK 1 -#define RK3190_CODEC_CAPTURE 2 -#define RK3190_CODEC_INCALL 3 - -static bool rk3190_for_mid = 1; - -static const unsigned int rk3190_reg_defaults[RK3190_PGA_AGC_CTL5+1] = { - [RK3190_RESET] = 0x0003, - [RK3190_ADC_INT_CTL1] = 0x0050, - [RK3190_ADC_INT_CTL2] = 0x000e, - [RK3190_DAC_INT_CTL1] = 0x0050, - [RK3190_DAC_INT_CTL2] = 0x000e, - [RK3190_BIST_CTL] = 0x0000, - [RK3190_SELECT_CURRENT] = 0x0001, - [RK3190_BIAS_CTL] = 0x0000, - [RK3190_ADC_CTL] = 0x0000, - [RK3190_BST_CTL] = 0x0000, - [RK3190_ALC_MUNIN_CTL] = 0x0044, - [RK3190_ALCL_GAIN_CTL] = 0x000c, - [RK3190_ALCR_GAIN_CTL] = 0x000c, - [RK3190_ADC_ENABLE] = 0x0000, - [RK3190_DAC_CTL] = 0x0000, - [RK3190_DAC_ENABLE] = 0x0000, - [RK3190_HPMIX_CTL] = 0x0000, - [RK3190_HPMIX_S_SELECT] = 0x0000, - [RK3190_HPOUT_CTL] = 0x0000, - [RK3190_HPOUTL_GAIN] = 0x0000, - [RK3190_HPOUTR_GAIN] = 0x0000, - [RK3190_PGA_AGC_CTL1] = 0x0000, - [RK3190_PGA_AGC_CTL2] = 0x0046, - [RK3190_PGA_AGC_CTL3] = 0x0041, - [RK3190_PGA_AGC_CTL4] = 0x002c, - [RK3190_PGA_ASR_CTL] = 0x0000, - [RK3190_PGA_AGC_MAX_H] = 0x0026, - [RK3190_PGA_AGC_MAX_L] = 0x0040, - [RK3190_PGA_AGC_MIN_H] = 0x0036, - [RK3190_PGA_AGC_MIN_L] = 0x0020, - [RK3190_PGA_AGC_CTL5] = 0x0038, -}; - -static struct rk3190_init_bit_typ rk3190_init_bit_list[] = { - {RK3190_HPOUT_CTL, RK3190_HPOUTL_EN, RK3190_HPOUTL_WORK,RK3190_HPVREF_EN}, - {RK3190_HPOUT_CTL, RK3190_HPOUTR_EN, RK3190_HPOUTR_WORK,RK3190_HPVREF_WORK}, - {RK3190_HPMIX_CTL, RK3190_HPMIXR_EN, RK3190_HPMIXR_WORK2,RK3190_HPMIXR_WORK1}, - {RK3190_HPMIX_CTL, RK3190_HPMIXL_EN, RK3190_HPMIXL_WORK2,RK3190_HPMIXL_WORK1}, - -}; -#define RK3190_INIT_BIT_LIST_LEN ARRAY_SIZE(rk3190_init_bit_list) - -static int rk3190_init_bit_register(unsigned int reg, int i) -{ - for (; i < RK3190_INIT_BIT_LIST_LEN; i++) { - if (rk3190_init_bit_list[i].reg == reg) - return i; - } - - return -1; -} - -static unsigned int rk3190_codec_read(struct snd_soc_codec *codec, unsigned int reg); -static inline void rk3190_write_reg_cache(struct snd_soc_codec *codec, - unsigned int reg, unsigned int value); - -static unsigned int rk3190_set_init_value(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) -{ - unsigned int read_value, power_bit, set_bit2,set_bit1; - int i; - int tmp = 0; - // read codec init register - i = rk3190_init_bit_register(reg, 0); - - // set codec init bit - // widget init bit should be setted 0 after widget power up or unmute, - // and should be setted 1 after widget power down or mute. - if (i >= 0) { - read_value = rk3190_codec_read(codec, reg); - while (i >= 0) { - power_bit = rk3190_init_bit_list[i].power_bit; - set_bit2 = rk3190_init_bit_list[i].init2_bit; - set_bit1 = rk3190_init_bit_list[i].init1_bit; - - if ((read_value & power_bit) != (value & power_bit)) - { - if (value & power_bit) - { - tmp = value | set_bit2 | set_bit1; - writel(value, rk3190_priv->regbase+reg); - writel(tmp, rk3190_priv->regbase+reg); - - } - else - { - tmp = value & (~set_bit2) & (~set_bit1); - writel(tmp, rk3190_priv->regbase+reg); - writel(value, rk3190_priv->regbase+reg); - } - value = tmp; - } - else - { - if (read_value != value) - writel(value, rk3190_priv->regbase+reg); - } - - i = rk3190_init_bit_register(reg, ++i); - - rk3190_write_reg_cache(codec, reg, value); - } - } - else - { - return i; - } - - return value; -} - -static int rk3190_volatile_register(struct snd_soc_codec *codec, unsigned int reg) -{ - switch (reg) { - case RK3190_RESET: - return 1; - default: - return 0; - } -} - -static int rk3190_codec_register(struct snd_soc_codec *codec, unsigned int reg) -{ - switch (reg) { - case RK3190_RESET: - case RK3190_ADC_INT_CTL1: - case RK3190_ADC_INT_CTL2: - case RK3190_DAC_INT_CTL1: - case RK3190_DAC_INT_CTL2: - case RK3190_BIST_CTL: - case RK3190_SELECT_CURRENT: - case RK3190_BIAS_CTL: - case RK3190_ADC_CTL: - case RK3190_BST_CTL: - case RK3190_ALC_MUNIN_CTL: - case RK3190_ALCL_GAIN_CTL: - case RK3190_ALCR_GAIN_CTL: - case RK3190_ADC_ENABLE: - case RK3190_DAC_CTL: - case RK3190_DAC_ENABLE: - case RK3190_HPMIX_CTL: - case RK3190_HPMIX_S_SELECT: - case RK3190_HPOUT_CTL: - case RK3190_HPOUTL_GAIN: - case RK3190_HPOUTR_GAIN: - case RK3190_PGA_AGC_CTL1: - case RK3190_PGA_AGC_CTL2: - case RK3190_PGA_AGC_CTL3: - case RK3190_PGA_AGC_CTL4: - case RK3190_PGA_ASR_CTL: - case RK3190_PGA_AGC_MAX_H: - case RK3190_PGA_AGC_MAX_L: - case RK3190_PGA_AGC_MIN_H: - case RK3190_PGA_AGC_MIN_L: - case RK3190_PGA_AGC_CTL5: - return 1; - default: - return 0; - } -} - -static inline unsigned int rk3190_read_reg_cache(struct snd_soc_codec *codec, - unsigned int reg) -{ - unsigned int *cache = codec->reg_cache; - - if (rk3190_codec_register(codec, reg) ) - return cache[reg]; - - printk("%s : reg error!\n", __func__); - - return -EINVAL; -} - -static inline void rk3190_write_reg_cache(struct snd_soc_codec *codec, - unsigned int reg, unsigned int value) -{ - unsigned int *cache = codec->reg_cache; - - if (rk3190_codec_register(codec, reg)) { - cache[reg] = value; - return; - } - - printk("%s : reg error!\n", __func__); -} - -static unsigned int rk3190_codec_read(struct snd_soc_codec *codec, unsigned int reg) -{ - unsigned int value; - - if (!rk3190_priv) { - printk("%s : rk3190 is NULL\n", __func__); - return -EINVAL; - } - - if (!rk3190_codec_register(codec, reg)) { - printk("%s : reg error!\n", __func__); - return -EINVAL; - } - - if (rk3190_volatile_register(codec, reg) == 0) { - value = rk3190_read_reg_cache(codec, reg); - } else { - value = readl_relaxed(rk3190_priv->regbase+reg); - } - - value = readl_relaxed(rk3190_priv->regbase+reg); - DBG("%s : reg = 0x%x, val= 0x%x\n", __func__, reg, value); - - return value; -} - -static int rk3190_codec_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) -{ - int new_value = -1; - - if (!rk3190_priv) { - printk("%s : rk3190 is NULL\n", __func__); - return -EINVAL; - } else if (!rk3190_codec_register(codec, reg)) { - printk("%s : reg error!\n", __func__); - return -EINVAL; - } - - //new_value = rk3190_set_init_value(codec, reg, value); - - if (new_value == -1) - { - writel(value, rk3190_priv->regbase+reg); - rk3190_write_reg_cache(codec, reg, value); - } - - DBG("%s : reg = 0x%x, val = 0x%x, new_value=%d\n", __func__, reg, value,new_value); - return 0; -} - -static int rk3190_hw_write(const struct i2c_client *client, const char *buf, int count) -{ - unsigned int reg, value; - - if (!rk3190_priv || !rk3190_priv->codec) { - printk("%s : rk3190_priv or rk3190_priv->codec is NULL\n", __func__); - return -EINVAL; - } - - if (count == 3) { - reg = (unsigned int)buf[0]; - value = (buf[1] & 0xff00) | (0x00ff & buf[2]); - writel(value, rk3190_priv->regbase+reg); - } else { - printk("%s : i2c len error\n", __func__); - } - - return count; -} - -static int rk3190_reset(struct snd_soc_codec *codec) -{ - writel(0x00, rk3190_priv->regbase+RK3190_RESET); - mdelay(10); - writel(0x03, rk3190_priv->regbase+RK3190_RESET); - mdelay(10); - - memcpy(codec->reg_cache, rk3190_reg_defaults, - sizeof(rk3190_reg_defaults)); - - return 0; -} - -int rk3190_headset_mic_detect(bool headset_status) -{ -#if 0 - struct snd_soc_codec *codec = rk3190_priv->codec; - - DBG("%s\n", __func__); - - if (!rk3190_priv || !rk3190_priv->codec) { - printk("%s : rk3190_priv or rk3190_priv->codec is NULL\n", __func__); - return -EINVAL; - } - - if (headset_status) { - snd_soc_update_bits(codec, RK3190_ADC_MIC_CTL, - RK3190_MICBIAS2_PWRD | RK3190_MICBIAS2_V_MASK, - RK3190_MICBIAS2_V_1_7); - } else {// headset is out, disable MIC2 && MIC1 Bias - DBG("%s : headset is out,disable Mic2 Bias\n", __func__); - snd_soc_update_bits(codec, RK3190_ADC_MIC_CTL, - RK3190_MICBIAS2_PWRD | RK3190_MICBIAS2_V_MASK, - RK3190_MICBIAS2_V_1_0|RK3190_MICBIAS2_PWRD); - } -#endif - return 0; -} -EXPORT_SYMBOL(rk3190_headset_mic_detect); - -#if 0 -static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -3900, 150, 0); -static const DECLARE_TLV_DB_SCALE(pga_vol_tlv, -1800, 150, 0); -static const DECLARE_TLV_DB_SCALE(bst_vol_tlv, 0, 2000, 0); -static const DECLARE_TLV_DB_SCALE(pga_agc_max_vol_tlv, -1350, 600, 0); -static const DECLARE_TLV_DB_SCALE(pga_agc_min_vol_tlv, -1800, 600, 0); - -static const char *rk3190_input_mode[] = {"Differential","Single-Ended"}; - -static const char *rk3190_micbias_ratio[] = {"1.0 Vref", "1.1 Vref", - "1.2 Vref", "1.3 Vref", "1.4 Vref", "1.5 Vref", "1.6 Vref", "1.7 Vref",}; - -static const char *rk3190_dis_en_sel[] = {"Disable", "Enable"}; - -static const char *rk3190_pga_agc_way[] = {"Normal", "Jack"}; - -static const char *rk3190_agc_backup_way[] = {"Normal", "Jack1", "Jack2", "Jack3"}; - -static const char *rk3190_pga_agc_hold_time[] = {"0ms", "2ms", - "4ms", "8ms", "16ms", "32ms", "64ms", "128ms", "256ms", "512ms", "1s"}; - -static const char *rk3190_pga_agc_ramp_up_time[] = {"Normal:500us Jack:125us", - "Normal:1ms Jack:250us", "Normal:2ms Jack:500us", "Normal:4ms Jack:1ms", - "Normal:8ms Jack:2ms", "Normal:16ms Jack:4ms", "Normal:32ms Jack:8ms", - "Normal:64ms Jack:16ms", "Normal:128ms Jack:32ms", "Normal:256ms Jack:64ms", - "Normal:512ms Jack:128ms"}; - -static const char *rk3190_pga_agc_ramp_down_time[] = {"Normal:125us Jack:32us", - "Normal:250us Jack:64us", "Normal:500us Jack:125us", "Normal:1ms Jack:250us", - "Normal:2ms Jack:500us", "Normal:4ms Jack:1ms", "Normal:8ms Jack:2ms", - "Normal:16ms Jack:4ms", "Normal:32ms Jack:8ms", "Normal:64ms Jack:16ms", - "Normal:128ms Jack:32ms"}; - -static const char *rk3190_pga_agc_mode[] = {"Normal", "Limiter"}; - -static const char *rk3190_pga_agc_recovery_mode[] = {"Right Now", "After AGC to Limiter"}; - -static const char *rk3190_pga_agc_noise_gate_threhold[] = {"-39dB", "-45dB", "-51dB", - "-57dB", "-63dB", "-69dB", "-75dB", "-81dB"}; - -static const char *rk3190_pga_agc_update_gain[] = {"Right Now", "After 1st Zero Cross"}; - -static const char *rk3190_pga_agc_approximate_sample_rate[] = {"96KHZ","48KHz","441KHZ", "32KHz", - "24KHz", "16KHz", "12KHz", "8KHz"}; - -static const struct soc_enum rk3190_bst_enum[] = { -SOC_ENUM_SINGLE(RK3190_BSTL_ALCL_CTL, RK3190_BSTL_MODE_SFT, 2, rk3190_input_mode), -}; - - -static const struct soc_enum rk3190_micbias_enum[] = { -SOC_ENUM_SINGLE(RK3190_ADC_MIC_CTL, RK3190_MICBIAS_VOL_SHT, 8, rk3190_micbias_ratio), -}; - -static const struct soc_enum rk3190_agcl_enum[] = { -SOC_ENUM_SINGLE(RK3190_PGAL_AGC_CTL1, RK3190_PGA_AGC_BK_WAY_SFT, 4, rk3190_agc_backup_way),/*0*/ -SOC_ENUM_SINGLE(RK3190_PGAL_AGC_CTL1, RK3190_PGA_AGC_WAY_SFT, 2, rk3190_pga_agc_way),/*1*/ -SOC_ENUM_SINGLE(RK3190_PGAL_AGC_CTL1, RK3190_PGA_AGC_HOLD_T_SFT, 11, rk3190_pga_agc_hold_time),/*2*/ -SOC_ENUM_SINGLE(RK3190_PGAL_AGC_CTL2, RK3190_PGA_AGC_GRU_T_SFT, 11, rk3190_pga_agc_ramp_up_time),/*3*/ -SOC_ENUM_SINGLE(RK3190_PGAL_AGC_CTL2, RK3190_PGA_AGC_GRD_T_SFT, 11, rk3190_pga_agc_ramp_down_time),/*4*/ -SOC_ENUM_SINGLE(RK3190_PGAL_AGC_CTL3, RK3190_PGA_AGC_MODE_SFT, 2, rk3190_pga_agc_mode),/*5*/ -SOC_ENUM_SINGLE(RK3190_PGAL_AGC_CTL3, RK3190_PGA_AGC_ZO_SFT, 2, rk3190_dis_en_sel),/*6*/ -SOC_ENUM_SINGLE(RK3190_PGAL_AGC_CTL3, RK3190_PGA_AGC_REC_MODE_SFT, 2, rk3190_pga_agc_recovery_mode),/*7*/ -SOC_ENUM_SINGLE(RK3190_PGAL_AGC_CTL3, RK3190_PGA_AGC_FAST_D_SFT, 2, rk3190_dis_en_sel),/*8*/ -SOC_ENUM_SINGLE(RK3190_PGAL_AGC_CTL3, RK3190_PGA_AGC_NG_SFT, 2, rk3190_dis_en_sel),/*9*/ -SOC_ENUM_SINGLE(RK3190_PGAL_AGC_CTL3, RK3190_PGA_AGC_NG_THR_SFT, 8, rk3190_pga_agc_noise_gate_threhold),/*10*/ -SOC_ENUM_SINGLE(RK3190_PGAL_AGC_CTL4, RK3190_PGA_AGC_ZO_MODE_SFT, 2, rk3190_pga_agc_update_gain),/*11*/ -SOC_ENUM_SINGLE(RK3190_PGAL_ASR_CTL, RK3190_PGA_SLOW_CLK_SFT, 2, rk3190_dis_en_sel),/*12*/ -SOC_ENUM_SINGLE(RK3190_PGAL_ASR_CTL, RK3190_PGA_ASR_SFT, 8, rk3190_pga_agc_approximate_sample_rate),/*13*/ -SOC_ENUM_SINGLE(RK3190_PGAL_AGC_CTL5, RK3190_PGA_AGC_SFT, 2, rk3190_dis_en_sel),/*14*/ -}; - -static const struct soc_enum rk3190_agcr_enum[] = { -SOC_ENUM_SINGLE(RK3190_PGAR_AGC_CTL1, RK3190_PGA_AGC_BK_WAY_SFT, 4, rk3190_agc_backup_way),/*0*/ -SOC_ENUM_SINGLE(RK3190_PGAR_AGC_CTL1, RK3190_PGA_AGC_WAY_SFT, 2, rk3190_pga_agc_way),/*1*/ -SOC_ENUM_SINGLE(RK3190_PGAR_AGC_CTL1, RK3190_PGA_AGC_HOLD_T_SFT, 11, rk3190_pga_agc_hold_time),/*2*/ -SOC_ENUM_SINGLE(RK3190_PGAR_AGC_CTL2, RK3190_PGA_AGC_GRU_T_SFT, 11, rk3190_pga_agc_ramp_up_time),/*3*/ -SOC_ENUM_SINGLE(RK3190_PGAR_AGC_CTL2, RK3190_PGA_AGC_GRD_T_SFT, 11, rk3190_pga_agc_ramp_down_time),/*4*/ -SOC_ENUM_SINGLE(RK3190_PGAR_AGC_CTL3, RK3190_PGA_AGC_MODE_SFT, 2, rk3190_pga_agc_mode),/*5*/ -SOC_ENUM_SINGLE(RK3190_PGAR_AGC_CTL3, RK3190_PGA_AGC_ZO_SFT, 2, rk3190_dis_en_sel),/*6*/ -SOC_ENUM_SINGLE(RK3190_PGAR_AGC_CTL3, RK3190_PGA_AGC_REC_MODE_SFT, 2, rk3190_pga_agc_recovery_mode),/*7*/ -SOC_ENUM_SINGLE(RK3190_PGAR_AGC_CTL3, RK3190_PGA_AGC_FAST_D_SFT, 2, rk3190_dis_en_sel),/*8*/ -SOC_ENUM_SINGLE(RK3190_PGAR_AGC_CTL3, RK3190_PGA_AGC_NG_SFT, 2, rk3190_dis_en_sel),/*9*/ -SOC_ENUM_SINGLE(RK3190_PGAR_AGC_CTL3, RK3190_PGA_AGC_NG_THR_SFT, 8, rk3190_pga_agc_noise_gate_threhold),/*10*/ -SOC_ENUM_SINGLE(RK3190_PGAR_AGC_CTL4, RK3190_PGA_AGC_ZO_MODE_SFT, 2, rk3190_pga_agc_update_gain),/*11*/ -SOC_ENUM_SINGLE(RK3190_PGAR_ASR_CTL, RK3190_PGA_SLOW_CLK_SFT, 2, rk3190_dis_en_sel),/*12*/ -SOC_ENUM_SINGLE(RK3190_PGAR_ASR_CTL, RK3190_PGA_ASR_SFT, 8, rk3190_pga_agc_approximate_sample_rate),/*13*/ -SOC_ENUM_SINGLE(RK3190_PGAR_AGC_CTL5, RK3190_PGA_AGC_SFT, 2, rk3190_dis_en_sel),/*14*/ -}; - -static const struct snd_kcontrol_new rk3190_snd_controls[] = { - //Add for set voice volume - SOC_DOUBLE_R_TLV("Speaker Playback Volume", RK3190_HPOUTL_GAIN, - RK3190_HPOUTR_GAIN, RK3190_HPOUT_GAIN_SFT, 31, 0, out_vol_tlv), - SOC_DOUBLE("Speaker Playback Switch", RK3190_HPOUT_CTL, - RK3190_HPOUTL_MUTE_SHT, RK3190_HPOUTR_MUTE_SHT, 1, 0), - SOC_DOUBLE_R_TLV("Headphone Playback Volume", RK3190_HPOUTL_GAIN, - RK3190_HPOUTR_GAIN, RK3190_HPOUT_GAIN_SFT, 31, 0, out_vol_tlv), - SOC_DOUBLE("Headphone Playback Switch", RK3190_HPOUT_CTL, - RK3190_HPOUTL_MUTE_SHT, RK3190_HPOUTR_MUTE_SHT, 1, 0), - SOC_DOUBLE_R_TLV("Earpiece Playback Volume", RK3190_HPOUTL_GAIN, - RK3190_HPOUTR_GAIN, RK3190_HPOUT_GAIN_SFT, 31, 0, out_vol_tlv), - SOC_DOUBLE("Earpiece Playback Switch", RK3190_HPOUT_CTL, - RK3190_HPOUTL_MUTE_SHT, RK3190_HPOUTR_MUTE_SHT, 1, 0), - - - //Add for set capture mute - SOC_SINGLE_TLV("Main Mic Capture Volume", RK3190_BST_CTL, - RK3190_BSTL_GAIN_SHT, 1, 0, bst_vol_tlv), - SOC_SINGLE("Main Mic Capture Switch", RK3190_BST_CTL, - RK3190_BSTL_MUTE_SHT, 1, 0), - SOC_SINGLE_TLV("Headset Mic Capture Volume", RK3190_BST_CTL, - RK3190_BSTR_GAIN_SHT, 1, 0, bst_vol_tlv), - SOC_SINGLE("Headset Mic Capture Switch", RK3190_BST_CTL, - RK3190_BSTR_MUTE_SHT, 1, 0), - - SOC_SINGLE("ALCL Switch", RK3190_ALC_MUNIN_CTL, - RK3190_ALCL_MUTE_SHT, 1, 0), - SOC_SINGLE_TLV("ALCL Capture Volume", RK3190_BSTL_ALCL_CTL, - RK3190_ALCL_GAIN_SHT, 31, 0, pga_vol_tlv), - SOC_SINGLE("ALCR Switch", RK3190_ALC_MUNIN_CTL, - RK3190_ALCR_MUTE_SHT, 1, 0), - SOC_SINGLE_TLV("ALCR Capture Volume", RK3190_ALCR_GAIN_CTL, - RK3190_ALCL_GAIN_SHT, 31, 0, pga_vol_tlv), - - SOC_ENUM("BST_L Mode", rk3190_bst_enum[0]), - - SOC_ENUM("Micbias Voltage", rk3190_micbias_enum[0]), - SOC_ENUM("PGAL AGC Back Way", rk3190_agcl_enum[0]), - SOC_ENUM("PGAL AGC Way", rk3190_agcl_enum[1]), - SOC_ENUM("PGAL AGC Hold Time", rk3190_agcl_enum[2]), - SOC_ENUM("PGAL AGC Ramp Up Time", rk3190_agcl_enum[3]), - SOC_ENUM("PGAL AGC Ramp Down Time", rk3190_agcl_enum[4]), - SOC_ENUM("PGAL AGC Mode", rk3190_agcl_enum[5]), - SOC_ENUM("PGAL AGC Gain Update Zero Enable", rk3190_agcl_enum[6]), - SOC_ENUM("PGAL AGC Gain Recovery LPGA VOL", rk3190_agcl_enum[7]), - SOC_ENUM("PGAL AGC Fast Decrement Enable", rk3190_agcl_enum[8]), - SOC_ENUM("PGAL AGC Noise Gate Enable", rk3190_agcl_enum[9]), - SOC_ENUM("PGAL AGC Noise Gate Threhold", rk3190_agcl_enum[10]), - SOC_ENUM("PGAL AGC Upate Gain", rk3190_agcl_enum[11]), - SOC_ENUM("PGAL AGC Slow Clock Enable", rk3190_agcl_enum[12]), - SOC_ENUM("PGAL AGC Approximate Sample Rate", rk3190_agcl_enum[13]), - SOC_ENUM("PGAL AGC Enable", rk3190_agcl_enum[14]), - - SOC_SINGLE_TLV("PGAL AGC Volume", RK3190_PGAL_AGC_CTL4, - RK3190_PGA_AGC_VOL_SFT, 31, 0, pga_vol_tlv),//AGC disable and 0x0a bit 5 is 1 - - SOC_SINGLE("PGAL AGC Max Level High 8 Bits", RK3190_PGAL_AGC_MAX_H, - 0, 255, 0), - SOC_SINGLE("PGAL AGC Max Level Low 8 Bits", RK3190_PGAL_AGC_MAX_L, - 0, 255, 0), - SOC_SINGLE("PGAL AGC Min Level High 8 Bits", RK3190_PGAL_AGC_MIN_H, - 0, 255, 0), - SOC_SINGLE("PGAL AGC Min Level Low 8 Bits", RK3190_PGAL_AGC_MIN_L, - 0, 255, 0), - - SOC_SINGLE_TLV("PGAL AGC Max Gain", RK3190_PGAL_AGC_CTL5, - RK3190_PGA_AGC_MAX_G_SFT, 7, 0, pga_agc_max_vol_tlv),//AGC enable and 0x0a bit 5 is 1 - SOC_SINGLE_TLV("PGAL AGC Min Gain", RK3190_PGAL_AGC_CTL5, - RK3190_PGA_AGC_MIN_G_SFT, 7, 0, pga_agc_min_vol_tlv),//AGC enable and 0x0a bit 5 is 1 - - SOC_ENUM("PGAR AGC Back Way", rk3190_agcr_enum[0]), - SOC_ENUM("PGAR AGC Way", rk3190_agcr_enum[1]), - SOC_ENUM("PGAR AGC Hold Time", rk3190_agcr_enum[2]), - SOC_ENUM("PGAR AGC Ramp Up Time", rk3190_agcr_enum[3]), - SOC_ENUM("PGAR AGC Ramp Down Time", rk3190_agcr_enum[4]), - SOC_ENUM("PGAR AGC Mode", rk3190_agcr_enum[5]), - SOC_ENUM("PGAR AGC Gain Update Zero Enable", rk3190_agcr_enum[6]), - SOC_ENUM("PGAR AGC Gain Recovery LPGA VOL", rk3190_agcr_enum[7]), - SOC_ENUM("PGAR AGC Fast Decrement Enable", rk3190_agcr_enum[8]), - SOC_ENUM("PGAR AGC Noise Gate Enable", rk3190_agcr_enum[9]), - SOC_ENUM("PGAR AGC Noise Gate Threhold", rk3190_agcr_enum[10]), - SOC_ENUM("PGAR AGC Upate Gain", rk3190_agcr_enum[11]), - SOC_ENUM("PGAR AGC Slow Clock Enable", rk3190_agcr_enum[12]), - SOC_ENUM("PGAR AGC Approximate Sample Rate", rk3190_agcr_enum[13]), - SOC_ENUM("PGAR AGC Enable", rk3190_agcr_enum[14]), - - SOC_SINGLE_TLV("PGAR AGC Volume", RK3190_PGAR_AGC_CTL4, - RK3190_PGA_AGC_VOL_SFT, 31, 0, pga_vol_tlv),//AGC disable and 0x0a bit 4 is 1 - - SOC_SINGLE("PGAR AGC Max Level High 8 Bits", RK3190_PGAR_AGC_MAX_H, - 0, 255, 0), - SOC_SINGLE("PGAR AGC Max Level Low 8 Bits", RK3190_PGAR_AGC_MAX_L, - 0, 255, 0), - SOC_SINGLE("PGAR AGC Min Level High 8 Bits", RK3190_PGAR_AGC_MIN_H, - 0, 255, 0), - SOC_SINGLE("PGAR AGC Min Level Low 8 Bits", RK3190_PGAR_AGC_MIN_L, - 0, 255, 0), - - SOC_SINGLE_TLV("PGAR AGC Max Gain", RK3190_PGAR_AGC_CTL5, - RK3190_PGA_AGC_MAX_G_SFT, 7, 0, pga_agc_max_vol_tlv),//AGC enable and 0x06 bit 4 is 1 - SOC_SINGLE_TLV("PGAR AGC Min Gain", RK3190_PGAR_AGC_CTL5, - RK3190_PGA_AGC_MIN_G_SFT, 7, 0, pga_agc_min_vol_tlv),//AGC enable and 0x06 bit 4 is 1 - -}; -#endif - -//For tiny alsa playback/capture/voice call path -static const char *rk3190_playback_path_mode[] = {"OFF", "RCV", "SPK", "HP", "HP_NO_MIC", "BT", "SPK_HP", //0-6 - "RING_SPK", "RING_HP", "RING_HP_NO_MIC", "RING_SPK_HP"};//7-10 - -static const char *rk3190_capture_path_mode[] = {"MIC OFF", "Main Mic", "Hands Free Mic", "BT Sco Mic"}; - -static const char *rk3190_voice_call_path_mode[] = {"OFF", "RCV", "SPK", "HP", "HP_NO_MIC", "BT"};//0-5 - -static const SOC_ENUM_SINGLE_DECL(rk3190_playback_path_type, 0, 0, rk3190_playback_path_mode); - -static const SOC_ENUM_SINGLE_DECL(rk3190_capture_path_type, 0, 0, rk3190_capture_path_mode); - -static const SOC_ENUM_SINGLE_DECL(rk3190_voice_call_path_type, 0, 0, rk3190_voice_call_path_mode); - -static int rk3190_codec_power_up(int type); -static int rk3190_codec_power_down(int type); - -static int rk3190_playback_path_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct rk3190_codec_priv *rk3190 = rk3190_priv; - - if (!rk3190) { - printk("%s : rk3190_priv is NULL\n", __func__); - return -EINVAL; - } - - DBG("%s : playback_path %ld\n",__func__,ucontrol->value.integer.value[0]); - - ucontrol->value.integer.value[0] = rk3190->playback_path; - - return 0; -} - -static int rk3190_playback_path_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct rk3190_codec_priv *rk3190 = rk3190_priv; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - long int pre_path; - - if (!rk3190) { - printk("%s : rk3190_priv is NULL\n", __func__); - return -EINVAL; - } - - if (rk3190->playback_path == ucontrol->value.integer.value[0]){ - DBG("%s : playback_path is not changed!\n",__func__); - return 0; - } - - pre_path = rk3190->playback_path; - rk3190->playback_path = ucontrol->value.integer.value[0]; - - printk("%s : set playback_path %ld, pre_path %ld\n", __func__, - rk3190->playback_path, pre_path); - - - // mute output for pop noise - if (rk3190 && rk3190->spk_ctl_gpio != INVALID_GPIO) { - DBG("%s : set spk ctl gpio LOW\n", __func__); - gpio_set_value(rk3190->spk_ctl_gpio, GPIO_LOW); - } - - if (rk3190 && rk3190->hp_ctl_gpio != INVALID_GPIO) { - DBG("%s : set hp ctl gpio LOW\n", __func__); - gpio_set_value(rk3190->hp_ctl_gpio, GPIO_LOW); - } - - switch (rk3190->playback_path) { - case OFF: - if (pre_path != OFF) - rk3190_codec_power_down(RK3190_CODEC_PLAYBACK); - break; - case RCV: - if (rk3190->voice_call_path != OFF) { - //close incall route - rk3190_codec_power_down(RK3190_CODEC_INCALL); - - rk3190->voice_call_path = OFF; - } - break; - case SPK_PATH: - case RING_SPK: - DBG("%s : PUT SPK_PATH\n",__func__); - if (pre_path == OFF) - rk3190_codec_power_up(RK3190_CODEC_PLAYBACK); -#if 0 - snd_soc_update_bits(codec, RK3190_SPKL_CTL, - rk3190_VOL_MASK, SPKOUT_VOLUME); //, volume (bit 0-4) - snd_soc_update_bits(codec, rk3190_SPKR_CTL, - rk3190_VOL_MASK, SPKOUT_VOLUME); -#endif - if (rk3190 && rk3190->hp_ctl_gpio != INVALID_GPIO) { - DBG("%s : set hp ctl gpio LOW\n", __func__); - gpio_set_value(rk3190->hp_ctl_gpio, GPIO_LOW); - //sleep for MOSFET or SPK power amplifier chip - msleep(HP_MOS_DELAY); - } - if (rk3190 && rk3190->spk_ctl_gpio != INVALID_GPIO) { - DBG("%s : set spk ctl gpio HIGH\n", __func__); - gpio_set_value(rk3190->spk_ctl_gpio, GPIO_HIGH); - //sleep for MOSFET or SPK power amplifier chip - msleep(SPK_AMP_DELAY); - } - - break; - case HP_PATH: - case HP_NO_MIC: - case RING_HP: - case RING_HP_NO_MIC: - if (pre_path == OFF) - rk3190_codec_power_up(RK3190_CODEC_PLAYBACK); -#if 0 - snd_soc_update_bits(codec, rk3190_SPKL_CTL, - rk3190_VOL_MASK, HPOUT_VOLUME); //, volume (bit 0-4) - snd_soc_update_bits(codec, rk3190_SPKR_CTL, - rk3190_VOL_MASK, HPOUT_VOLUME); -#endif - if (rk3190 && rk3190->hp_ctl_gpio != INVALID_GPIO) { - DBG("%s : set hp ctl gpio HIGH\n", __func__); - gpio_set_value(rk3190->hp_ctl_gpio, GPIO_HIGH); - //sleep for MOSFET or SPK power amplifier chip - msleep(HP_MOS_DELAY); - } - if (rk3190 && rk3190->spk_ctl_gpio != INVALID_GPIO) { - DBG("%s : set spk ctl gpio LOW\n", __func__); - gpio_set_value(rk3190->spk_ctl_gpio, GPIO_LOW); - //sleep for MOSFET or SPK power amplifier chip - msleep(SPK_AMP_DELAY); - } - - break; - case BT: - break; - case SPK_HP: - case RING_SPK_HP: - if (pre_path == OFF) - rk3190_codec_power_up(RK3190_CODEC_PLAYBACK); -#if 0 - snd_soc_update_bits(codec, rk3190_SPKL_CTL, - rk3190_VOL_MASK, HPOUT_VOLUME); //, volume (bit 0-4) - snd_soc_update_bits(codec, rk3190_SPKR_CTL, - rk3190_VOL_MASK, HPOUT_VOLUME); -#endif - if (rk3190 && rk3190->spk_ctl_gpio != INVALID_GPIO) { - DBG("%s : set spk ctl gpio HIGH\n", __func__); - gpio_set_value(rk3190->spk_ctl_gpio, GPIO_HIGH); - //sleep for MOSFET or SPK power amplifier chip - msleep(SPK_AMP_DELAY); - } - - if (rk3190 && rk3190->hp_ctl_gpio != INVALID_GPIO) { - DBG("%s : set hp ctl gpio HIGH\n", __func__); - gpio_set_value(rk3190->hp_ctl_gpio, GPIO_HIGH); - //sleep for MOSFET or SPK power amplifier chip - msleep(HP_MOS_DELAY); - } - - break; - default: - return -EINVAL; - } - - return 0; -} - -static int rk3190_capture_path_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct rk3190_codec_priv *rk3190 = rk3190_priv; - - if (!rk3190) { - printk("%s : rk3190_priv is NULL\n", __func__); - return -EINVAL; - } - - DBG("%s : capture_path %ld\n", __func__, - ucontrol->value.integer.value[0]); - - ucontrol->value.integer.value[0] = rk3190->capture_path; - - return 0; -} - -static int rk3190_capture_path_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct rk3190_codec_priv *rk3190 = rk3190_priv; - //struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - long int pre_path; - - if (!rk3190) { - printk("%s : rk3190_priv is NULL\n", __func__); - return -EINVAL; - } - - if (rk3190->capture_path == ucontrol->value.integer.value[0]){ - DBG("%s : capture_path is not changed!\n", __func__); - return 0; - } - - pre_path = rk3190->capture_path; - rk3190->capture_path = ucontrol->value.integer.value[0]; - - printk("%s : set capture_path %ld, pre_path %ld\n", __func__, - rk3190->capture_path, pre_path); - - switch (rk3190->capture_path) { - case MIC_OFF: - if (pre_path != MIC_OFF) - rk3190_codec_power_down(RK3190_CODEC_CAPTURE); - break; - case Main_Mic: - DBG("%s : PUT MAIN_MIC_PATH\n",__func__); - if (pre_path == MIC_OFF) - rk3190_codec_power_up(RK3190_CODEC_CAPTURE); -#if 0 - if (rk3190 && rk3190->mic_sel_gpio != INVALID_GPIO) { - DBG("%s : set mic sel gpio HIGH\n", __func__); - gpio_set_value(rk3190->mic_sel_gpio, GPIO_HIGH); - } -#endif - break; - case Hands_Free_Mic: - if (pre_path == MIC_OFF) - rk3190_codec_power_up(RK3190_CODEC_CAPTURE); -#if 0 - if (rk3190 && rk3190->mic_sel_gpio != INVALID_GPIO) { - DBG("%s : set mic sel gpio HIGH\n", __func__); - gpio_set_value(rk3190->mic_sel_gpio, GPIO_LOW); - } -#endif - break; - case BT_Sco_Mic: - break; - default: - return -EINVAL; - } - - return 0; -} - -static int rk3190_voice_call_path_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct rk3190_codec_priv *rk3190 = rk3190_priv; - - if (!rk3190) { - printk("%s : rk3190_priv is NULL\n", __func__); - return -EINVAL; - } - - DBG("%s : voice_call_path %ld\n", __func__, - ucontrol->value.integer.value[0]); - - ucontrol->value.integer.value[0] = rk3190->voice_call_path; - - return 0; -} - -static int rk3190_voice_call_path_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct rk3190_codec_priv *rk3190 = rk3190_priv; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - long int pre_path; - - if (!rk3190) { - printk("%s : rk3190_priv is NULL\n", __func__); - return -EINVAL; - } - - if (rk3190->voice_call_path == ucontrol->value.integer.value[0]){ - DBG("%s : voice_call_path is not changed!\n",__func__); - return 0; - } - - pre_path = rk3190->voice_call_path; - rk3190->voice_call_path = ucontrol->value.integer.value[0]; - - printk("%s : set voice_call_path %ld, pre_path %ld\n", __func__, - rk3190->voice_call_path, pre_path); -/* - if (rk3190 && rk3190->spk_ctl_gpio != INVALID_GPIO) { - DBG("%s : set spk ctl gpio LOW\n", __func__); - gpio_set_value(rk3190->spk_ctl_gpio, GPIO_LOW); - } - - if (rk3190 && rk3190->hp_ctl_gpio != INVALID_GPIO) { - DBG("%s : set hp ctl gpio LOW\n", __func__); - gpio_set_value(rk3190->hp_ctl_gpio, GPIO_LOW); - } -*/ - switch (rk3190->voice_call_path) { - case OFF: - - if (rk3190 && rk3190->spk_ctl_gpio != INVALID_GPIO) { - DBG("%s : set spk ctl gpio LOW\n", __func__); - gpio_set_value(rk3190->spk_ctl_gpio, GPIO_LOW); - } - - if (rk3190 && rk3190->hp_ctl_gpio != INVALID_GPIO) { - DBG("%s : set hp ctl gpio LOW\n", __func__); - gpio_set_value(rk3190->hp_ctl_gpio, GPIO_LOW); - } - - if (rk3190 && rk3190->ear_ctl_gpio != INVALID_GPIO) { - DBG("%s : set ear ctl gpio LOW\n", __func__); - gpio_set_value(rk3190->ear_ctl_gpio, GPIO_LOW); - } - - rk3190_codec_power_down(RK3190_CODEC_INCALL); - rk3190_codec_power_up(RK3190_CODEC_PLAYBACK); - break; - case RCV: -#if 0 - //set mic for modem - if (rk3190 && rk3190->mic_sel_gpio != INVALID_GPIO) { - DBG("%s : set mic sel gpio HIGH\n", __func__); - gpio_set_value(rk3190->mic_sel_gpio, GPIO_HIGH); - } -#endif - -#if 0 - //rcv is controled by modem, so close incall route - if (pre_path != OFF && pre_path != BT) - rk3190_codec_power_down(RK3190_CODEC_INCALL); -#endif - rk3190_codec_power_up(RK3190_CODEC_INCALL); - - if (rk3190 && rk3190->hp_ctl_gpio != INVALID_GPIO) { - DBG("%s : set spk ctl gpio LOW\n", __func__); - gpio_set_value(rk3190->hp_ctl_gpio, GPIO_LOW); - } - - if (rk3190 && rk3190->spk_ctl_gpio != INVALID_GPIO) { - DBG("%s : set spk ctl gpio LOW\n", __func__); - gpio_set_value(rk3190->spk_ctl_gpio, GPIO_LOW); - } - - if (rk3190 && rk3190->ear_ctl_gpio != INVALID_GPIO) { - DBG("%s : set ear ctl gpio HIGH\n", __func__); - gpio_set_value(rk3190->ear_ctl_gpio, GPIO_HIGH); - } - - break; - case SPK_PATH: -#if 0 - //set mic for modem - if (rk3190 && rk3190->mic_sel_gpio != INVALID_GPIO) { - DBG("%s : set mic sel gpio HIGH\n", __func__); - gpio_set_value(rk3190->mic_sel_gpio, GPIO_HIGH); - } -#endif - //open incall route - if (pre_path == OFF || - pre_path == RCV || - pre_path == BT) - rk3190_codec_power_up(RK3190_CODEC_INCALL); -#if 0 - snd_soc_update_bits(codec, rk3190_SPKL_CTL, - rk3190_VOL_MASK, SPKOUT_VOLUME); //, volume (bit 0-4) - snd_soc_update_bits(codec, rk3190_SPKR_CTL, - rk3190_VOL_MASK, SPKOUT_VOLUME); -#endif - if (rk3190 && rk3190->hp_ctl_gpio != INVALID_GPIO) { - DBG("%s : set spk ctl gpio LOW\n", __func__); - gpio_set_value(rk3190->hp_ctl_gpio, GPIO_LOW); - } - - if (rk3190 && rk3190->ear_ctl_gpio != INVALID_GPIO) { - DBG("%s : set ear ctl gpio LOW\n", __func__); - gpio_set_value(rk3190->ear_ctl_gpio, GPIO_LOW); - } - if (rk3190 && rk3190->spk_ctl_gpio != INVALID_GPIO) { - DBG("%s : set spk ctl gpio HIGH\n", __func__); - gpio_set_value(rk3190->spk_ctl_gpio, GPIO_HIGH); - //sleep for MOSFET or SPK power amplifier chip - msleep(SPK_AMP_DELAY); - } - break; - case HP_PATH: -#if 0 - //set mic for modem - if (rk3190 && rk3190->mic_sel_gpio != INVALID_GPIO) { - DBG("%s : set mic sel gpio HIGH\n", __func__); - gpio_set_value(rk3190->mic_sel_gpio, GPIO_LOW); - } -#endif - //open incall route - if (pre_path == OFF || - pre_path == RCV || - pre_path == BT) - rk3190_codec_power_up(RK3190_CODEC_INCALL); -#if 0 - snd_soc_update_bits(codec, rk3190_SPKL_CTL, - rk3190_VOL_MASK, HPOUT_VOLUME); //, volume (bit 0-4) - snd_soc_update_bits(codec, rk3190_SPKR_CTL, - rk3190_VOL_MASK, HPOUT_VOLUME); -#endif - - if (rk3190 && rk3190->hp_ctl_gpio != INVALID_GPIO) { - DBG("%s : set spk ctl gpio HIGH\n", __func__); - gpio_set_value(rk3190->hp_ctl_gpio, GPIO_HIGH); - //sleep for MOSFET or SPK power amplifier chip - msleep(HP_MOS_DELAY); - } - - if (rk3190 && rk3190->spk_ctl_gpio != INVALID_GPIO) { - DBG("%s : set spk ctl gpio LOW\n", __func__); - gpio_set_value(rk3190->spk_ctl_gpio, GPIO_LOW); - } - - if (rk3190 && rk3190->ear_ctl_gpio != INVALID_GPIO) { - DBG("%s : set ear ctl gpio LOW\n", __func__); - gpio_set_value(rk3190->ear_ctl_gpio, GPIO_LOW); - } - - break; - case HP_NO_MIC: -#if 0 - //set mic for modem - if (rk3190 && rk3190->mic_sel_gpio != INVALID_GPIO) { - DBG("%s : set mic sel gpio HIGH\n", __func__); - gpio_set_value(rk3190->mic_sel_gpio, GPIO_HIGH); - } -#endif - //open incall route - if (pre_path == OFF || - pre_path == RCV || - pre_path == BT) - rk3190_codec_power_up(RK3190_CODEC_INCALL); -#if 0 - snd_soc_update_bits(codec, rk3190_SPKL_CTL, - rk3190_VOL_MASK, HPOUT_VOLUME); //, volume (bit 0-4) - snd_soc_update_bits(codec, rk3190_SPKR_CTL, - rk3190_VOL_MASK, HPOUT_VOLUME); -#endif - - if (rk3190 && rk3190->hp_ctl_gpio != INVALID_GPIO) { - DBG("%s : set spk ctl gpio HIGH\n", __func__); - gpio_set_value(rk3190->hp_ctl_gpio, GPIO_HIGH); - //sleep for MOSFET or SPK power amplifier chip - msleep(HP_MOS_DELAY); - } - - if (rk3190 && rk3190->spk_ctl_gpio != INVALID_GPIO) { - DBG("%s : set spk ctl gpio LOW\n", __func__); - gpio_set_value(rk3190->spk_ctl_gpio, GPIO_LOW); - } - - if (rk3190 && rk3190->ear_ctl_gpio != INVALID_GPIO) { - DBG("%s : set ear ctl gpio LOW\n", __func__); - gpio_set_value(rk3190->ear_ctl_gpio, GPIO_LOW); - } - - break; - case BT: - //BT is controled by modem, so close incall route - if (pre_path != OFF && - pre_path != RCV) - rk3190_codec_power_down(RK3190_CODEC_INCALL); - break; - - if (rk3190 && rk3190->hp_ctl_gpio != INVALID_GPIO) { - DBG("%s : set spk ctl gpio LOW\n", __func__); - gpio_set_value(rk3190->hp_ctl_gpio, GPIO_LOW); - //sleep for MOSFET or SPK power amplifier chip - msleep(HP_MOS_DELAY); - } - - if (rk3190 && rk3190->spk_ctl_gpio != INVALID_GPIO) { - DBG("%s : set spk ctl gpio LOW\n", __func__); - gpio_set_value(rk3190->spk_ctl_gpio, GPIO_LOW); - } - - if (rk3190 && rk3190->ear_ctl_gpio != INVALID_GPIO) { - DBG("%s : set ear ctl gpio LOW\n", __func__); - gpio_set_value(rk3190->ear_ctl_gpio, GPIO_LOW); - } - - default: - return -EINVAL; - } - - return 0; -} - -static const struct snd_kcontrol_new rk3190_snd_path_controls[] = { - SOC_ENUM_EXT("Playback Path", rk3190_playback_path_type, - rk3190_playback_path_get, rk3190_playback_path_put), - - SOC_ENUM_EXT("Capture MIC Path", rk3190_capture_path_type, - rk3190_capture_path_get, rk3190_capture_path_put), - - SOC_ENUM_EXT("Voice Call Path", rk3190_voice_call_path_type, - rk3190_voice_call_path_get, rk3190_voice_call_path_put), -}; - -#if 0 -static int rk3190_dacl_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = w->codec; - - switch (event) { - case SND_SOC_DAPM_POST_PMU: - snd_soc_update_bits(codec, RK3190_DAC_ENABLE, - RK3190_DACL_WORK,0); - snd_soc_update_bits(codec, RK3190_DAC_ENABLE, - RK3190_DACL_EN | RK3190_DACL_CLK_EN, - RK3190_DACL_EN | RK3190_DACL_CLK_EN); - snd_soc_update_bits(codec, RK3190_DAC_ENABLE, - RK3190_DACL_WORK, RK3190_DACL_WORK); - break; - - case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, RK3190_DAC_ENABLE, - RK3190_DACL_EN | RK3190_DACL_CLK_EN,0); - snd_soc_update_bits(codec, RK3190_DAC_ENABLE, - RK3190_DACL_WORK, 0); - break; - - default: - return 0; - } - - return 0; -} - -static int rk3190_dacr_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = w->codec; - - switch (event) { - case SND_SOC_DAPM_POST_PMU: - snd_soc_update_bits(codec, RK3190_DAC_ENABLE, - RK3190_DACR_WORK,0); - snd_soc_update_bits(codec, RK3190_DAC_ENABLE, - RK3190_DACR_EN | RK3190_DACR_CLK_EN, - RK3190_DACR_EN | RK3190_DACR_CLK_EN); - snd_soc_update_bits(codec, RK3190_DAC_ENABLE, - RK3190_DACR_WORK, RK3190_DACR_WORK); - break; - - case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, RK3190_DAC_ENABLE, - RK3190_DACR_EN | RK3190_DACR_CLK_EN,0); - snd_soc_update_bits(codec, RK3190_DAC_ENABLE, - RK3190_DACR_WORK, 0); - break; - - default: - return 0; - } - - return 0; -} - -static int rk3190_adcl_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = w->codec; - - switch (event) { - case SND_SOC_DAPM_POST_PMU: - snd_soc_update_bits(codec, RK3190_ADC_ENABLE, - RK3190_ADCL_CLK_EN_SFT | RK3190_ADCL_AMP_EN_SFT, - RK3190_ADCL_CLK_EN | RK3190_ADCL_AMP_EN); - break; - - case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, RK3190_ADC_ENABLE, - RK3190_ADCL_CLK_EN_SFT | RK3190_ADCL_AMP_EN_SFT,0); - break; - - default: - return 0; - } - - return 0; -} - -static int rk3190_adcr_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = w->codec; - - switch (event) { - case SND_SOC_DAPM_POST_PMU: - snd_soc_update_bits(codec, RK3190_ADC_ENABLE, - RK3190_ADCR_CLK_EN_SFT | RK3190_ADCR_AMP_EN_SFT, - RK3190_ADCR_CLK_EN | RK3190_ADCR_AMP_EN ); - break; - - case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, RK3190_ADC_ENABLE, - RK3190_ADCR_CLK_EN_SFT | RK3190_ADCR_AMP_EN_SFT,0); - break; - - default: - return 0; - } - - return 0; -} - -/* HPmix */ -static const struct snd_kcontrol_new rk3190_hpmixl[] = { - SOC_DAPM_SINGLE("ALCR Switch", RK3190_HPMIX_S_SELECT, - RK3190_HPMIXL_SEL_ALCR_SFT, 1, 0), - SOC_DAPM_SINGLE("ALCL Switch", RK3190_HPMIX_S_SELECT, - RK3190_HPMIXL_SEL_ALCL_SFT, 1, 0), - SOC_DAPM_SINGLE("DACL Switch", RK3190_HPMIX_S_SELECT, - RK3190_HPMIXL_SEL_DACL_SFT, 1, 0), -}; - -static const struct snd_kcontrol_new rk3190_hpmixr[] = { - SOC_DAPM_SINGLE("ALCR Switch", RK3190_HPMIX_S_SELECT, - RK3190_HPMIXR_SEL_ALCR_SFT, 1, 0), - SOC_DAPM_SINGLE("ALCL Switch", RK3190_HPMIX_S_SELECT, - RK3190_HPMIXR_SEL_ALCL_SFT, 1, 0), - SOC_DAPM_SINGLE("DACR Switch", RK3190_HPMIX_S_SELECT, - RK3190_HPMIXR_SEL_DACR_SFT, 1, 0), -}; - -static int rk3190_hpmixl_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = w->codec; - - switch (event) { - case SND_SOC_DAPM_POST_PMU: - snd_soc_update_bits(codec, RK3190_DAC_CTL, - RK3190_ZO_DET_VOUTR_SFT, RK3190_ZO_DET_VOUTR_EN); - snd_soc_update_bits(codec, RK3190_DAC_CTL, - RK3190_ZO_DET_VOUTL_SFT, RK3190_ZO_DET_VOUTL_EN); - break; - - case SND_SOC_DAPM_PRE_PMD: - snd_soc_update_bits(codec, RK3190_DAC_CTL, - RK3190_ZO_DET_VOUTR_SFT, RK3190_ZO_DET_VOUTR_DIS); - snd_soc_update_bits(codec, RK3190_DAC_CTL, - RK3190_ZO_DET_VOUTL_SFT, RK3190_ZO_DET_VOUTL_DIS); - break; - - default: - return 0; - } - - return 0; -} - -static int rk3190_hpmixr_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = w->codec; -#if 0 - switch (event) { - case SND_SOC_DAPM_POST_PMU: - snd_soc_update_bits(codec, RK3190_HPMIX_CTL, - RK3190_HPMIXR_WORK2, RK3190_HPMIXR_WORK2); - break; - - case SND_SOC_DAPM_PRE_PMD: - snd_soc_update_bits(codec, RK3190_HPMIX_CTL, - RK3190_HPMIXR_WORK2, 0); - break; - - default: - return 0; - } -#endif - return 0; -} - -/* HP MUX */ - -static const char *hpl_sel[] = {"HPMIXL", "DACL"}; - -static const struct soc_enum hpl_sel_enum = - SOC_ENUM_SINGLE(RK3190_HPMIX_S_SELECT, RK3190_HPMIXL_BYPASS_SFT, - ARRAY_SIZE(hpl_sel), hpl_sel); - -static const struct snd_kcontrol_new hpl_sel_mux = - SOC_DAPM_ENUM("HPL select Mux", hpl_sel_enum); - -static const char *hpr_sel[] = {"HPMIXR", "DACR"}; - -static const struct soc_enum hpr_sel_enum = - SOC_ENUM_SINGLE(RK3190_HPMIX_S_SELECT, RK3190_HPMIXR_BYPASS_SFT, - ARRAY_SIZE(hpr_sel), hpr_sel); - -static const struct snd_kcontrol_new hpr_sel_mux = - SOC_DAPM_ENUM("HPR select Mux", hpr_sel_enum); - -/* IN_L MUX */ -static const char *lnl_sel[] = {"NO","BSTL", "LINEL","NOUSE"}; - -static const struct soc_enum lnl_sel_enum = - SOC_ENUM_SINGLE(RK3190_ALC_MUNIN_CTL, RK3190_MUXINL_F_SHT, - ARRAY_SIZE(lnl_sel), lnl_sel); - -static const struct snd_kcontrol_new lnl_sel_mux = - SOC_DAPM_ENUM("MUXIN_L select", lnl_sel_enum); - -/* IN_R MUX */ -static const char *lnr_sel[] = {"NO","BSTR", "LINER","NOUSE"}; - -static const struct soc_enum lnr_sel_enum = - SOC_ENUM_SINGLE(RK3190_ALC_MUNIN_CTL, RK3190_MUXINR_F_SHT, - ARRAY_SIZE(lnr_sel), lnr_sel); - -static const struct snd_kcontrol_new lnr_sel_mux = - SOC_DAPM_ENUM("MUXIN_R select", lnr_sel_enum); - - -static const struct snd_soc_dapm_widget rk3190_dapm_widgets[] = { - - /* microphone bias */ - SND_SOC_DAPM_MICBIAS("Mic Bias", RK3190_ADC_MIC_CTL, - RK3190_MICBIAS_VOL_ENABLE, 0), - - /* DACs */ - SND_SOC_DAPM_DAC_E("DACL", NULL, SND_SOC_NOPM, - 0, 0, rk3190_dacl_event, - SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU), - SND_SOC_DAPM_DAC_E("DACR", NULL, SND_SOC_NOPM, - 0, 0, rk3190_dacr_event, - SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU), - - /* ADCs */ - SND_SOC_DAPM_ADC_E("ADCL", NULL, SND_SOC_NOPM, - 0, 0, rk3190_adcl_event, - SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU), - SND_SOC_DAPM_ADC_E("ADCR", NULL, SND_SOC_NOPM, - 0, 0, rk3190_adcr_event, - SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU), - - /* PGA */ - SND_SOC_DAPM_PGA("BSTL", RK3190_BST_CTL, - RK3190_BSTL_PWRD_SFT, 0, NULL, 0), - SND_SOC_DAPM_PGA("BSTR", RK3190_BST_CTL, - RK3190_BSTR_PWRD_SFT, 0, NULL, 0), - SND_SOC_DAPM_PGA("ALCL", RK3190_ALC_MUNIN_CTL, - RK3190_ALCL_PWR_SHT , 0, NULL, 0), - SND_SOC_DAPM_PGA("ALCR", RK3190_ALC_MUNIN_CTL, - RK3190_ALCR_PWR_SHT , 0, NULL, 0), - SND_SOC_DAPM_PGA("HPL", RK3190_HPOUT_CTL, - RK3190_HPOUTL_PWR_SHT, 0, NULL, 0), - SND_SOC_DAPM_PGA("HPR", RK3190_HPOUT_CTL, - RK3190_HPOUTR_PWR_SHT, 0, NULL, 0), - - /* MIXER */ - SND_SOC_DAPM_MIXER_E("HPMIXL", RK3190_HPMIX_CTL, - RK3190_HPMIXL_SFT, 0, rk3190_hpmixl, - ARRAY_SIZE(rk3190_hpmixl),rk3190_hpmixl_event, - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), - SND_SOC_DAPM_MIXER_E("HPMIXR", RK3190_HPMIX_CTL, - RK3190_HPMIXR_SFT, 0, rk3190_hpmixr, - ARRAY_SIZE(rk3190_hpmixr),rk3190_hpmixr_event, - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), - - /* MUX */ - SND_SOC_DAPM_MUX("IN_R Mux", SND_SOC_NOPM, 0, 0, - &lnr_sel_mux), - SND_SOC_DAPM_MUX("IN_L Mux", SND_SOC_NOPM, 0, 0, - &lnl_sel_mux), - SND_SOC_DAPM_MUX("HPL Mux", SND_SOC_NOPM, 0, 0, - &hpl_sel_mux), - SND_SOC_DAPM_MUX("HPR Mux", SND_SOC_NOPM, 0, 0, - &hpr_sel_mux), - - /* Audio Interface */ - SND_SOC_DAPM_AIF_IN("I2S DAC", "HiFi Playback", 0, - SND_SOC_NOPM, 0, 0), - SND_SOC_DAPM_AIF_OUT("I2S ADC", "HiFi Capture", 0, - SND_SOC_NOPM, 0, 0), - - /* Input */ - SND_SOC_DAPM_INPUT("LINEL"), - SND_SOC_DAPM_INPUT("LINER"), - SND_SOC_DAPM_INPUT("MICP"), - SND_SOC_DAPM_INPUT("MICN"), - - /* Output */ - SND_SOC_DAPM_OUTPUT("HPOUTL"), - SND_SOC_DAPM_OUTPUT("HPOUTR"), - -}; - -static const struct snd_soc_dapm_route rk3190_dapm_routes[] = { - /* Input */ - {"BSTR", NULL, "MICP"}, - {"BSTL", NULL, "MICP"}, - {"BSTL", NULL, "MICN"}, - - {"IN_R Mux", "LINER", "LINER"}, - {"IN_R Mux", "BSTR", "BSTR"}, - {"IN_L Mux", "LINEL", "LINEL"}, - {"IN_L Mux", "BSTL", "BSTL"}, - - {"ALCL", NULL, "IN_L Mux"}, - {"ALCR", NULL, "IN_R Mux"}, - - - {"ADCR", NULL, "ALCR"}, - {"ADCL", NULL, "ALCL"}, - - {"I2S ADC", NULL, "ADCR"}, - {"I2S ADC", NULL, "ADCL"}, - - /* Output */ - - {"DACR", NULL, "I2S DAC"}, - {"DACL", NULL, "I2S DAC"}, - - {"HPMIXR", "ALCR Switch", "ALCR"}, - {"HPMIXR", "ALCL Switch", "ALCL"}, - {"HPMIXR", "DACR Switch", "DACR"}, - - {"HPMIXL", "ALCR Switch", "ALCR"}, - {"HPMIXL", "ALCL Switch", "ALCL"}, - {"HPMIXL", "DACL Switch", "DACL"}, - - - {"HPR Mux", "DACR", "DACR"}, - {"HPR Mux", "HPMIXR", "HPMIXR"}, - {"HPL Mux", "DACL", "DACL"}, - {"HPL Mux", "HPMIXL", "HPMIXL"}, - - {"HPR", NULL, "HPR Mux"}, - {"HPL", NULL, "HPL Mux"}, - - {"HPOUTR", NULL, "HPR"}, - {"HPOUTL", NULL, "HPL"}, -}; -#endif - -static int rk3190_set_bias_level(struct snd_soc_codec *codec, - enum snd_soc_bias_level level) -{ - DBG("%s level=%d\n",__func__,level); - - switch (level) { - case SND_SOC_BIAS_ON: - break; - - case SND_SOC_BIAS_PREPARE: - break; - - case SND_SOC_BIAS_STANDBY: -#if 0 - if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { - writel(0x32, rk3190_priv->regbase+RK3190_DAC_INT_CTL3); - snd_soc_update_bits(codec, RK3190_ADC_MIC_CTL, - RK3190_ADC_CURRENT_ENABLE, RK3190_ADC_CURRENT_ENABLE); - snd_soc_update_bits(codec, RK3190_DAC_CTL, - RK3190_CURRENT_EN, RK3190_CURRENT_EN); - /* set power */ - snd_soc_update_bits(codec, RK3190_ADC_ENABLE, - RK3190_ADCL_REF_VOL_EN_SFT | RK3190_ADCR_REF_VOL_EN_SFT, - RK3190_ADCL_REF_VOL_EN | RK3190_ADCR_REF_VOL_EN); - - snd_soc_update_bits(codec, RK3190_ADC_MIC_CTL, - RK3190_ADCL_ZERO_DET_EN_SFT | RK3190_ADCR_ZERO_DET_EN_SFT, - RK3190_ADCL_ZERO_DET_EN | RK3190_ADCR_ZERO_DET_EN); - - snd_soc_update_bits(codec, RK3190_DAC_CTL, - RK3190_REF_VOL_DACL_EN_SFT | RK3190_REF_VOL_DACR_EN_SFT, - RK3190_REF_VOL_DACL_EN | RK3190_REF_VOL_DACR_EN ); - - snd_soc_update_bits(codec, RK3190_DAC_ENABLE, - RK3190_DACL_REF_VOL_EN_SFT | RK3190_DACR_REF_VOL_EN_SFT, - RK3190_DACL_REF_VOL_EN | RK3190_DACR_REF_VOL_EN ); - } - break; -#endif - case SND_SOC_BIAS_OFF: -#if 0 - snd_soc_update_bits(codec, RK3190_DAC_ENABLE, - RK3190_DACL_REF_VOL_EN_SFT | RK3190_DACR_REF_VOL_EN_SFT,0); - snd_soc_update_bits(codec, RK3190_DAC_CTL, - RK3190_REF_VOL_DACL_EN_SFT | RK3190_REF_VOL_DACR_EN_SFT,0); - snd_soc_update_bits(codec, RK3190_ADC_MIC_CTL, - RK3190_ADCL_ZERO_DET_EN_SFT | RK3190_ADCR_ZERO_DET_EN_SFT,0); - snd_soc_update_bits(codec, RK3190_ADC_ENABLE, - RK3190_ADCL_REF_VOL_EN_SFT | RK3190_ADCR_REF_VOL_EN_SFT,0); - snd_soc_update_bits(codec, RK3190_ADC_MIC_CTL, - RK3190_ADC_CURRENT_ENABLE, 0); - snd_soc_update_bits(codec, RK3190_DAC_CTL, - RK3190_CURRENT_EN, 0); - writel(0x22, rk3190_priv->regbase+RK3190_DAC_INT_CTL3); -#endif - break; - } - codec->dapm.bias_level = level; - - return 0; -} - -static int rk3190_set_dai_sysclk(struct snd_soc_dai *codec_dai, - int clk_id, unsigned int freq, int dir) -{ - struct rk3190_codec_priv *rk3190 = rk3190_priv; - - if (!rk3190) { - printk("%s : rk3190 is NULL\n", __func__); - return -EINVAL; - } - - rk3190->stereo_sysclk = freq; - - return 0; -} - -static int rk3190_set_dai_fmt(struct snd_soc_dai *codec_dai, - unsigned int fmt) -{ - struct snd_soc_codec *codec = codec_dai->codec; - unsigned int adc_aif1 = 0, adc_aif2 = 0, dac_aif1 = 0, dac_aif2 = 0; - - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: - adc_aif2 |= RK3190_I2S_MODE_SLV; - break; - case SND_SOC_DAIFMT_CBM_CFM: - adc_aif2 |= RK3190_I2S_MODE_MST; - break; - default: - printk("%s : set master mask failed!\n", __func__); - return -EINVAL; - } - - switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_DSP_A: - adc_aif1 |= RK3190_ADC_DF_PCM; - dac_aif1 |= RK3190_DAC_DF_PCM; - break; - case SND_SOC_DAIFMT_DSP_B: - break; - case SND_SOC_DAIFMT_I2S: - adc_aif1 |= RK3190_ADC_DF_I2S; - dac_aif1 |= RK3190_DAC_DF_I2S; - break; - case SND_SOC_DAIFMT_RIGHT_J: - adc_aif1 |= RK3190_ADC_DF_RJ; - dac_aif1 |= RK3190_DAC_DF_RJ; - break; - case SND_SOC_DAIFMT_LEFT_J: - adc_aif1 |= RK3190_ADC_DF_LJ; - dac_aif1 |= RK3190_DAC_DF_LJ; - break; - default: - printk("%s : set format failed!\n", __func__); - return -EINVAL; - } - - switch (fmt & SND_SOC_DAIFMT_INV_MASK) { - case SND_SOC_DAIFMT_NB_NF: - adc_aif1 |= RK3190_ALRCK_POL_DIS; - adc_aif2 |= RK3190_ABCLK_POL_DIS; - dac_aif1 |= RK3190_DLRCK_POL_DIS; - dac_aif2 |= RK3190_DBCLK_POL_DIS; - break; - case SND_SOC_DAIFMT_IB_IF: - adc_aif1 |= RK3190_ALRCK_POL_EN; - adc_aif2 |= RK3190_ABCLK_POL_EN; - dac_aif1 |= RK3190_DLRCK_POL_EN; - dac_aif2 |= RK3190_DBCLK_POL_EN; - break; - case SND_SOC_DAIFMT_IB_NF: - adc_aif1 |= RK3190_ALRCK_POL_DIS; - adc_aif2 |= RK3190_ABCLK_POL_EN; - dac_aif1 |= RK3190_DLRCK_POL_DIS; - dac_aif2 |= RK3190_DBCLK_POL_EN; - break; - case SND_SOC_DAIFMT_NB_IF: - adc_aif1 |= RK3190_ALRCK_POL_EN; - adc_aif2 |= RK3190_ABCLK_POL_DIS; - dac_aif1 |= RK3190_DLRCK_POL_EN; - dac_aif2 |= RK3190_DBCLK_POL_DIS; - break; - default: - printk("%s : set dai format failed!\n", __func__); - return -EINVAL; - } - - snd_soc_update_bits(codec, RK3190_ADC_INT_CTL1, - RK3190_ALRCK_POL_MASK | RK3190_ADC_DF_MASK, adc_aif1); - snd_soc_update_bits(codec, RK3190_ADC_INT_CTL2, - RK3190_ABCLK_POL_MASK | RK3190_I2S_MODE_MASK, adc_aif2); - snd_soc_update_bits(codec, RK3190_DAC_INT_CTL1, - RK3190_DLRCK_POL_MASK | RK3190_DAC_DF_MASK, dac_aif1); - snd_soc_update_bits(codec, RK3190_DAC_INT_CTL2, - RK3190_DBCLK_POL_MASK, dac_aif2); - - return 0; -} - -static int rk3190_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec *codec =rtd->codec; - struct rk3190_codec_priv *rk3190 = rk3190_priv; - unsigned int rate = params_rate(params); - unsigned int div; - unsigned int adc_aif1 = 0, adc_aif2 = 0, dac_aif1 = 0, dac_aif2 = 0; - - if (!rk3190) { - printk("%s : rk3190 is NULL\n", __func__); - return -EINVAL; - } - - // bclk = codec_clk / 4 - // lrck = bclk / (wl * 2) - div = (((rk3190->stereo_sysclk / 4) / rate) / 2); - - if ((rk3190->stereo_sysclk % (4 * rate * 2) > 0) || - (div != 16 && div != 20 && div != 24 && div != 32)) { - printk("%s : need PLL\n", __func__); - return -EINVAL; - } - - switch (div) { - case 16: - adc_aif2 |= RK3190_ADC_WL_16; - dac_aif2 |= RK3190_DAC_WL_16; - break; - case 20: - adc_aif2 |= RK3190_ADC_WL_20; - dac_aif2 |= RK3190_DAC_WL_20; - break; - case 24: - adc_aif2 |= RK3190_ADC_WL_24; - dac_aif2 |= RK3190_DAC_WL_24; - break; - case 32: - adc_aif2 |= RK3190_ADC_WL_32; - dac_aif2 |= RK3190_DAC_WL_32; - break; - default: - return -EINVAL; - } - - - DBG("%s : MCLK = %dHz, sample rate = %dHz, div = %d\n", __func__, - rk3190->stereo_sysclk, rate, div); - - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: - adc_aif1 |= RK3190_ADC_VWL_16; - dac_aif1 |= RK3190_DAC_VWL_16; - break; - case SNDRV_PCM_FORMAT_S20_3LE: - adc_aif1 |= RK3190_ADC_VWL_20; - dac_aif1 |= RK3190_DAC_VWL_20; - break; - case SNDRV_PCM_FORMAT_S24_LE: - adc_aif1 |= RK3190_ADC_VWL_24; - dac_aif1 |= RK3190_DAC_VWL_24; - break; - case SNDRV_PCM_FORMAT_S32_LE: - adc_aif1 |= RK3190_ADC_VWL_32; - dac_aif1 |= RK3190_DAC_VWL_32; - break; - default: - return -EINVAL; - } - - switch (params_channels(params)) { - case RK3190_MONO: - adc_aif1 |= RK3190_ADC_TYPE_MONO; - break; - case RK3190_STEREO: - adc_aif1 |= RK3190_ADC_TYPE_STEREO; - break; - default: - return -EINVAL; - } - - adc_aif1 |= RK3190_ADC_SWAP_DIS; - adc_aif2 |= RK3190_ADC_RST_DIS; - dac_aif1 |= RK3190_DAC_SWAP_DIS; - dac_aif2 |= RK3190_DAC_RST_DIS; - - rk3190->rate = rate; - - snd_soc_update_bits(codec, RK3190_ADC_INT_CTL1, - RK3190_ADC_VWL_MASK | RK3190_ADC_SWAP_MASK | - RK3190_ADC_TYPE_MASK, adc_aif1); - snd_soc_update_bits(codec, RK3190_ADC_INT_CTL2, - RK3190_ADC_WL_MASK | RK3190_ADC_RST_MASK, adc_aif2); - snd_soc_update_bits(codec, RK3190_DAC_INT_CTL1, - RK3190_DAC_VWL_MASK | RK3190_DAC_SWAP_MASK, dac_aif1); - snd_soc_update_bits(codec, RK3190_DAC_INT_CTL2, - RK3190_DAC_WL_MASK | RK3190_DAC_RST_MASK, dac_aif2); - - return 0; -} - -static int rk3190_digital_mute(struct snd_soc_dai *dai, int mute) -{ - return 0; -} - -static struct rk3190_reg_val_typ playback_power_up_list[] = { - //{RK3190_DAC_INT_CTL3,0x32}, - {RK3190_DAC_CTL,0x40}, - {RK3190_DAC_CTL,0x62}, - {RK3190_DAC_ENABLE,0x88}, - {RK3190_DAC_ENABLE,0xcc}, - {RK3190_DAC_ENABLE,0xee}, - {RK3190_HPMIX_CTL,0x44}, - {RK3190_HPOUT_CTL,0x90}, - {RK3190_HPOUT_CTL,0xd8}, - {RK3190_HPMIX_S_SELECT,0x11},//DAC - {RK3190_HPMIX_CTL,0x55}, - {RK3190_HPMIX_CTL,0x77}, - {RK3190_DAC_ENABLE,0xff}, - {RK3190_HPOUT_CTL,0xfc}, - {RK3190_DAC_CTL,0x73}, - {RK3190_HPOUTL_GAIN,OUT_VOLUME}, - {RK3190_HPOUTR_GAIN,OUT_VOLUME}, -}; -#define RK3190_CODEC_PLAYBACK_POWER_UP_LIST_LEN ARRAY_SIZE(playback_power_up_list) - -static struct rk3190_reg_val_typ playback_power_down_list[] = { - {RK3190_HPOUT_CTL,0xdb}, - {RK3190_HPMIX_CTL,0x44}, - {RK3190_HPMIX_S_SELECT,0x00}, - {RK3190_HPOUT_CTL,0x92}, - {RK3190_DAC_CTL,0x22}, - {RK3190_HPOUT_CTL,0x00}, - {RK3190_HPMIX_CTL,0x00}, - {RK3190_DAC_ENABLE,0x00}, - {RK3190_DAC_CTL,0x00}, - //{RK3190_DAC_INT_CTL3,0x22}, -#ifdef WITH_CAP - //{RK3190_SELECT_CURRENT,0x08}, -#endif - {RK3190_HPOUTL_GAIN,0x0}, - {RK3190_HPOUTR_GAIN,0x0}, -}; -#define RK3190_CODEC_PLAYBACK_POWER_DOWN_LIST_LEN ARRAY_SIZE(playback_power_down_list) - -static struct rk3190_reg_val_typ capture_power_up_list[] = { - {RK3190_ADC_CTL, 0x40}, - //{RK3190_BIAS_CTL, 0x08}, - //{RK3190_BIAS_CTL, 0x0f}, - {RK3190_ADC_CTL, 0x62}, - {RK3190_BST_CTL, 0x88}, - {RK3190_ALC_MUNIN_CTL, 0x66}, - {RK3190_ADC_ENABLE, 0x44}, - {RK3190_ADC_ENABLE, 0x66}, - {RK3190_BST_CTL, 0xee}, - {RK3190_BST_CTL, 0xfe}, //single-ended - {RK3190_ALC_MUNIN_CTL, 0x77}, - {RK3190_ALCL_GAIN_CTL, CAP_VOL}, - {RK3190_ALCR_GAIN_CTL, CAP_VOL}, - {RK3190_ADC_CTL, 0x73}, - -}; -#define RK3190_CODEC_CAPTURE_POWER_UP_LIST_LEN ARRAY_SIZE(capture_power_up_list) - -static struct rk3190_reg_val_typ capture_power_down_list[] = { - {RK3190_ADC_ENABLE, 0x44}, - {RK3190_ALC_MUNIN_CTL, 0x66}, - {RK3190_BST_CTL, 0x88}, - {RK3190_ADC_ENABLE, 0x00}, - {RK3190_ADC_CTL, 0x62}, - //{RK3190_BIAS_CTL, 0x08}, - {RK3190_ADC_CTL, 0x40}, - {RK3190_BST_CTL, 0x00}, - {RK3190_ALCL_GAIN_CTL, 0x00}, - {RK3190_ALCR_GAIN_CTL, 0x00}, - {RK3190_ADC_CTL, 0x00}, - //{RK3190_BIAS_CTL, 0x00}, - {RK3190_ALC_MUNIN_CTL, 0x00}, -}; -#define RK3190_CODEC_CAPTURE_POWER_DOWN_LIST_LEN ARRAY_SIZE(capture_power_down_list) - -static struct rk3190_reg_val_typ lineIn_bypass_power_up_list[] = { -#if 1 - //{RK3190_DAC_INT_CTL3, 0x32}, - {RK3190_ADC_CTL, 0x40}, - {RK3190_BIAS_CTL, 0x08}, - {RK3190_BIAS_CTL, 0x0f}, - {RK3190_ALC_MUNIN_CTL, 0x22}, - {RK3190_ALC_MUNIN_CTL, 0x66}, - {RK3190_ADC_CTL, 0x62}, - {RK3190_DAC_CTL, 0x40}, - {RK3190_DAC_CTL, 0x62}, - {RK3190_DAC_ENABLE, 0x88}, - {RK3190_DAC_ENABLE, 0xcc}, - {RK3190_DAC_ENABLE, 0xee}, - {RK3190_HPMIX_CTL, 0x44}, - {RK3190_HPOUT_CTL, 0x92}, - {RK3190_HPOUT_CTL, 0xdb}, - {RK3190_HPMIX_S_SELECT, 0x22},//ALCL/R+DACL/R - {RK3190_HPMIX_CTL, 0x55}, - {RK3190_HPMIX_CTL, 0x77}, - {RK3190_DAC_ENABLE, 0xff}, - {RK3190_HPOUT_CTL, 0xff}, - {RK3190_ALC_MUNIN_CTL, 0x77}, - {RK3190_ALCL_GAIN_CTL, CAP_VOL}, - {RK3190_ALCR_GAIN_CTL, CAP_VOL}, - {RK3190_HPOUTL_GAIN, OUT_VOLUME}, - {RK3190_HPOUTR_GAIN, OUT_VOLUME}, - {RK3190_ADC_CTL, 0x73}, - {RK3190_DAC_CTL, 0x73}, -#endif -}; -#define RK3190_CODEC_LINEIN_BYPASS_POWER_UP_LIST_LEN ARRAY_SIZE(lineIn_bypass_power_up_list) - -static struct rk3190_reg_val_typ lineIn_bypass_power_down_list[] = { - {RK3190_ALC_MUNIN_CTL, 0xaa}, - {RK3190_BIAS_CTL, 0xc7}, - //{RK3190_BIAS_CTL, 0x80}, - {RK3190_ADC_CTL, 0x62}, - //{RK3190_BIAS_CTL, 0x00}, - {RK3190_ALC_MUNIN_CTL, 0x00}, - {RK3190_HPOUT_CTL, 0xdb}, - {RK3190_HPMIX_CTL, 0x44}, - {RK3190_HPMIX_S_SELECT, 0x00}, - {RK3190_HPOUT_CTL, 0x92}, - {RK3190_DAC_CTL, 0x22}, - {RK3190_ADC_CTL, 0x00}, - {RK3190_HPOUT_CTL, 0x00}, - {RK3190_HPMIX_CTL, 0x00}, - {RK3190_DAC_CTL, 0x00}, - {RK3190_DAC_ENABLE, 0x00}, - {RK3190_HPOUTL_GAIN, 0x00}, - {RK3190_HPOUTR_GAIN, 0x00}, - {RK3190_ALCL_GAIN_CTL, 0x00}, - {RK3190_ALCR_GAIN_CTL, 0x00}, - //{RK3190_DAC_INT_CTL3, 0x00}, -}; -#define RK3190_CODEC_LINEIN_BYPASS_POWER_DOWN_LIST_LEN ARRAY_SIZE(lineIn_bypass_power_down_list) - - -static int rk3190_codec_power_up(int type) -{ - struct snd_soc_codec *codec = rk3190_priv->codec; - int i; - - if (!rk3190_priv || !rk3190_priv->codec) { - printk("%s : rk3190_priv or rk3190_priv->codec is NULL\n", __func__); - return -EINVAL; - } - - printk("%s : power up %s%s%s\n", __func__, - type == RK3190_CODEC_PLAYBACK ? "playback" : "", - type == RK3190_CODEC_CAPTURE ? "capture" : "", - type == RK3190_CODEC_INCALL ? "incall" : ""); - - if (type == RK3190_CODEC_PLAYBACK) { - for (i = 0; i < RK3190_CODEC_PLAYBACK_POWER_UP_LIST_LEN; i++) { - snd_soc_write(codec, playback_power_up_list[i].reg, - playback_power_up_list[i].value); - msleep(10); - } - } else if (type == RK3190_CODEC_CAPTURE) { - for (i = 0; i < RK3190_CODEC_CAPTURE_POWER_UP_LIST_LEN; i++) { - snd_soc_write(codec, capture_power_up_list[i].reg, - capture_power_up_list[i].value); - msleep(10); - } - } else if (type == RK3190_CODEC_INCALL) { - /*To be perfect*/ - for (i = 0; i < RK3190_CODEC_LINEIN_BYPASS_POWER_UP_LIST_LEN; i++) { - snd_soc_write(codec, lineIn_bypass_power_up_list[i].reg, - lineIn_bypass_power_up_list[i].value); - msleep(10); - } - } - - return 0; -} - -static int rk3190_codec_power_down(int type) -{ - struct snd_soc_codec *codec = rk3190_priv->codec; - int i; - - if (!rk3190_priv || !rk3190_priv->codec) { - printk("%s : rk3190_priv or rk3190_priv->codec is NULL\n", __func__); - return -EINVAL; - } - - printk("%s : power down %s%s%s%s\n", __func__, - type == RK3190_CODEC_PLAYBACK ? "playback" : "", - type == RK3190_CODEC_CAPTURE ? "capture" : "", - type == RK3190_CODEC_INCALL ? "incall" : "", - type == RK3190_CODEC_ALL ? "all" : ""); - - if ((type == RK3190_CODEC_CAPTURE) || (type == RK3190_CODEC_INCALL)) { - for (i = 0; i < RK3190_CODEC_CAPTURE_POWER_DOWN_LIST_LEN; i++) { - snd_soc_write(codec, capture_power_down_list[i].reg, - capture_power_down_list[i].value); - } - } else if (type == RK3190_CODEC_PLAYBACK) { -#if 0 - snd_soc_write(codec, RK3190_DAC_CTL,0x62); - for ( i = OUT_VOLUME; i >= 0; i--) - { - snd_soc_write(codec, 0xb4,i); - snd_soc_write(codec, 0xb8,i); - } - msleep(20); -#endif - for (i = 0; i < RK3190_CODEC_PLAYBACK_POWER_DOWN_LIST_LEN; i++) { - snd_soc_write(codec, playback_power_down_list[i].reg, - playback_power_down_list[i].value); - - } - } else if (type == RK3190_CODEC_INCALL) { - /*To be perfect*/ - for (i = 0; i < RK3190_CODEC_LINEIN_BYPASS_POWER_DOWN_LIST_LEN; i++) { - snd_soc_write(codec, lineIn_bypass_power_down_list[i].reg, - lineIn_bypass_power_down_list[i].value); - } - } else if (type == RK3190_CODEC_ALL) { - rk3190_reset(codec); - } - - return 0; -} - -#define RK3190_PLAYBACK_RATES (SNDRV_PCM_RATE_8000 |\ - SNDRV_PCM_RATE_16000 | \ - SNDRV_PCM_RATE_32000 | \ - SNDRV_PCM_RATE_44100 | \ - SNDRV_PCM_RATE_48000 | \ - SNDRV_PCM_RATE_96000) - -#define RK3190_CAPTURE_RATES (SNDRV_PCM_RATE_8000 |\ - SNDRV_PCM_RATE_16000 | \ - SNDRV_PCM_RATE_32000 | \ - SNDRV_PCM_RATE_44100 | \ - SNDRV_PCM_RATE_48000 | \ - SNDRV_PCM_RATE_96000) - -#define RK3190_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ - SNDRV_PCM_FMTBIT_S20_3LE |\ - SNDRV_PCM_FMTBIT_S24_LE |\ - SNDRV_PCM_FMTBIT_S32_LE) - -static struct snd_soc_dai_ops rk3190_dai_ops = { - .hw_params = rk3190_hw_params, - .set_fmt = rk3190_set_dai_fmt, - .set_sysclk = rk3190_set_dai_sysclk, - .digital_mute = rk3190_digital_mute, -}; - -static struct snd_soc_dai_driver rk3190_dai[] = { - { - .name = "rk3190-hifi", - .id = RK3190_HIFI, - .playback = { - .stream_name = "HiFi Playback", - .channels_min = 2, - .channels_max = 2, - .rates = RK3190_PLAYBACK_RATES, - .formats = RK3190_FORMATS, - }, - .capture = { - .stream_name = "HiFi Capture", - .channels_min = 2, - .channels_max = 2, - .rates = RK3190_CAPTURE_RATES, - .formats = RK3190_FORMATS, - }, - .ops = &rk3190_dai_ops, - }, - { - .name = "rk3190-voice", - .id = RK3190_VOICE, - .playback = { - .stream_name = "Voice Playback", - .channels_min = 1, - .channels_max = 2, - .rates = RK3190_PLAYBACK_RATES, - .formats = RK3190_FORMATS, - }, - .capture = { - .stream_name = "Voice Capture", - .channels_min = 1, - .channels_max = 2, - .rates = RK3190_CAPTURE_RATES, - .formats = RK3190_FORMATS, - }, - .ops = &rk3190_dai_ops, - }, - -}; - -static int rk3190_suspend(struct snd_soc_codec *codec) -{ - if (rk3190_for_mid) - { - rk3190_codec_power_down(RK3190_CODEC_PLAYBACK); - rk3190_codec_power_down(RK3190_CODEC_ALL); -#ifdef WITH_CAP - snd_soc_write(codec, RK3190_SELECT_CURRENT,0x3e); - snd_soc_write(codec, RK3190_SELECT_CURRENT,0x1e); -#endif - } - else - rk3190_set_bias_level(codec, SND_SOC_BIAS_OFF); - - return 0; -} - -static int rk3190_resume(struct snd_soc_codec *codec) -{ - if (!rk3190_for_mid) - rk3190_set_bias_level(codec, SND_SOC_BIAS_STANDBY); -#ifdef WITH_CAP - snd_soc_write(codec, RK3190_SELECT_CURRENT,0x1e); - snd_soc_write(codec, RK3190_SELECT_CURRENT,0x3e); -#endif - return 0; -} - -static int rk3190_probe(struct snd_soc_codec *codec) -{ - struct rk3190_codec_priv *rk3190; - struct rk3190_codec_pdata *rk3190_plt = codec->dev->platform_data; - struct platform_device *pdev = to_platform_device(codec->dev); - struct resource *res, *mem; - int ret; - unsigned int val; - - DBG("%s\n", __func__); - - rk3190 = kzalloc(sizeof(struct rk3190_codec_priv), GFP_KERNEL); - if (!rk3190) { - printk("%s : rk3190 priv kzalloc failed!\n", __func__); - return -ENOMEM; - } - - rk3190->codec = codec; - - res = pdev->resource; - rk3190->regbase_phy = res->start; - rk3190->regsize_phy = (res->end - res->start) + 1; - - mem = request_mem_region(res->start, (res->end - res->start) + 1, pdev->name); - if (!mem) - { - dev_err(&pdev->dev, "failed to request mem region for rk2928 codec\n"); - ret = -ENOENT; - goto err__; - } - - rk3190->regbase = (int)ioremap(res->start, (res->end - res->start) + 1); - if (!rk3190->regbase) { - dev_err(&pdev->dev, "cannot ioremap acodec registers\n"); - ret = -ENXIO; - goto err__; - } - - rk3190->pclk = clk_get(NULL,"pclk_acodec"); - if(IS_ERR(rk3190->pclk)) - { - dev_err(&pdev->dev, "Unable to get acodec hclk\n"); - ret = -ENXIO; - goto err__; - } - clk_enable(rk3190->pclk); - - rk3190_priv = rk3190; - - if (rk3190_priv && rk3190_plt->spk_ctl_gpio) { - gpio_request(rk3190_plt->spk_ctl_gpio, NULL); - gpio_direction_output(rk3190_plt->spk_ctl_gpio, GPIO_LOW); - rk3190->spk_ctl_gpio = rk3190_plt->spk_ctl_gpio; - } else { - printk("%s : rk3190 spk_ctl_gpio is NULL!\n", __func__); - rk3190->spk_ctl_gpio = INVALID_GPIO; - } - - if (rk3190_priv && rk3190_plt->hp_ctl_gpio) { - gpio_request(rk3190_plt->hp_ctl_gpio, NULL); - gpio_direction_output(rk3190_plt->hp_ctl_gpio, GPIO_LOW); - rk3190->hp_ctl_gpio = rk3190_plt->hp_ctl_gpio; - } else { - printk("%s : rk3190 hp_ctl_gpio is NULL!\n", __func__); - rk3190->hp_ctl_gpio = INVALID_GPIO; - } - - if (rk3190_plt->delay_time) { - rk3190->delay_time = rk3190_plt->delay_time; - } else { - printk("%s : rk3190 delay_time is NULL!\n", __func__); - rk3190->delay_time = 10; - } - - if (rk3190_plt->ear_ctl_gpio) { - gpio_request(rk3190_plt->ear_ctl_gpio, NULL); - gpio_direction_output(rk3190_plt->ear_ctl_gpio, GPIO_LOW); - rk3190->ear_ctl_gpio = rk3190_plt->ear_ctl_gpio; - } else { - printk("%s : rk3190 ear_ctl_gpio is NULL!\n", __func__); - rk3190->ear_ctl_gpio = INVALID_GPIO; - } - - ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); - if (ret != 0) { - printk("%s : Failed to set cache I/O: %d\n", __func__, ret); - goto err__; - } - - codec->hw_read = rk3190_codec_read; - codec->hw_write = (hw_write_t)rk3190_hw_write; - codec->read = rk3190_codec_read; - codec->write = rk3190_codec_write; - - rk3190_reset(codec); - - val = snd_soc_read(codec, RK3190_RESET); - if (val != rk3190_reg_defaults[RK3190_RESET]) { - printk("%s : codec register 0: %x is not a 0x00000003\n", __func__, val); - ret = -ENODEV; - goto err__; - } - - if (!rk3190_for_mid) - { - codec->dapm.bias_level = SND_SOC_BIAS_OFF; - rk3190_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - } - -#ifdef WITH_CAP - //set for capacity output,clear up noise - snd_soc_write(codec, RK3190_SELECT_CURRENT,0x1e); - snd_soc_write(codec, RK3190_SELECT_CURRENT,0x3e); -#endif - -#if 1 - // select used with internal audio codec soc_con[4] bit 7 - val = readl(RK319X_GRF_BASE+GRF_SOC_CON4); - writel(val | 0x00800080,RK319X_GRF_BASE+GRF_SOC_CON4); - val = readl(RK319X_GRF_BASE+GRF_SOC_CON4); - printk("%s : i2s used with internal audio codec val=0x%x,soc_con[4] bit 7 =1 is correct\n",__func__,val); -#endif - - /*ENABLE MICBIAS and always ON*/ -#if 1 - snd_soc_write(codec, RK3190_BIAS_CTL, 0x08); - snd_soc_write(codec, RK3190_BIAS_CTL, 0x0f); -#endif - if(rk3190_for_mid) { - snd_soc_add_codec_controls(codec, rk3190_snd_path_controls, - ARRAY_SIZE(rk3190_snd_path_controls)); - } - - return 0; - -err__: - release_mem_region(res->start,(res->end - res->start) + 1); - kfree(rk3190); - rk3190 = NULL; - rk3190_priv = NULL; - - return ret; -} - -/* power down chip */ -static int rk3190_remove(struct snd_soc_codec *codec) -{ - - DBG("%s\n", __func__); - - if (!rk3190_priv) { - printk("%s : rk3190_priv is NULL\n", __func__); - return 0; - } - - if (rk3190_priv->spk_ctl_gpio != INVALID_GPIO) - gpio_set_value(rk3190_priv->spk_ctl_gpio, GPIO_LOW); - - if (rk3190_priv->hp_ctl_gpio != INVALID_GPIO) - gpio_set_value(rk3190_priv->hp_ctl_gpio, GPIO_LOW); - - mdelay(10); - - snd_soc_write(codec, RK3190_RESET, 0xfc); - mdelay(10); - snd_soc_write(codec, RK3190_RESET, 0x3); - mdelay(10); - - if (rk3190_priv) - kfree(rk3190_priv); - - return 0; -} - -static struct snd_soc_codec_driver soc_codec_dev_rk3190 = { - .probe =rk3190_probe, - .remove =rk3190_remove, - .suspend =rk3190_suspend, - .resume = rk3190_resume, - .set_bias_level = rk3190_set_bias_level, - .reg_cache_size = ARRAY_SIZE(rk3190_reg_defaults), - .reg_word_size = sizeof(unsigned int), - .reg_cache_default = rk3190_reg_defaults, - .volatile_register = rk3190_volatile_register, - .readable_register = rk3190_codec_register, - .reg_cache_step = sizeof(unsigned int), -}; - -static int rk3190_platform_probe(struct platform_device *pdev) -{ - DBG("%s\n", __func__); - - return snd_soc_register_codec(&pdev->dev, - &soc_codec_dev_rk3190, rk3190_dai, ARRAY_SIZE(rk3190_dai)); -} - -static int rk3190_platform_remove(struct platform_device *pdev) -{ - snd_soc_unregister_codec(&pdev->dev); - return 0; -} - -void rk3190_platform_shutdown(struct platform_device *pdev) -{ - - DBG("%s\n", __func__); - - if (!rk3190_priv || !rk3190_priv->codec) { - printk("%s : rk3190_priv or rk3190_priv->codec is NULL\n", __func__); - return; - } - - if (rk3190_priv->spk_ctl_gpio != INVALID_GPIO) - gpio_set_value(rk3190_priv->spk_ctl_gpio, GPIO_LOW); - - if (rk3190_priv->hp_ctl_gpio != INVALID_GPIO) - gpio_set_value(rk3190_priv->hp_ctl_gpio, GPIO_LOW); - - mdelay(10); - - writel(0xfc, rk3190_priv->regbase+RK3190_RESET); - mdelay(10); - writel(0x03, rk3190_priv->regbase+RK3190_RESET); - - if (rk3190_priv) - kfree(rk3190_priv); -} - -static struct platform_driver rk3190_codec_driver = { - .driver = { - .name = "rk3190-codec", - .owner = THIS_MODULE, - }, - .probe = rk3190_platform_probe, - .remove = rk3190_platform_remove, - .shutdown = rk3190_platform_shutdown, -}; - - -static __init int rk3190_modinit(void) -{ - return platform_driver_register(&rk3190_codec_driver); -} -module_init(rk3190_modinit); - -static __exit void rk3190_exit(void) -{ - platform_driver_unregister(&rk3190_codec_driver); -} -module_exit(rk3190_exit); - -MODULE_DESCRIPTION("ASoC RK3190 driver"); -MODULE_AUTHOR("zhangjun "); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/rk3190_codec.h b/sound/soc/codecs/rk3190_codec.h deleted file mode 100644 index bdac4bf3e852..000000000000 --- a/sound/soc/codecs/rk3190_codec.h +++ /dev/null @@ -1,591 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * rk3190_codec.h -- RK3190 CODEC ALSA SoC audio driver - * - * Copyright 2013 Rockship - * Author: zhangjun - * - */ - -#ifndef __RK3190_CODEC_H__ -#define __RK3190_CODEC_H__ - - - -/* codec register */ -#define RK3190_CODEC_BASE (0x0) - -#define RK3190_RESET (RK3190_CODEC_BASE + 0x00) -#define RK3190_ADC_INT_CTL1 (RK3190_CODEC_BASE + 0x08) -#define RK3190_ADC_INT_CTL2 (RK3190_CODEC_BASE + 0x0c) -#define RK3190_DAC_INT_CTL1 (RK3190_CODEC_BASE + 0x10) -#define RK3190_DAC_INT_CTL2 (RK3190_CODEC_BASE + 0x14) -//#define RK3190_DAC_INT_CTL3 (RK3190_CODEC_BASE + 0x18) -#define RK3190_BIST_CTL (RK3190_CODEC_BASE + 0x1c) -#define RK3190_SELECT_CURRENT (RK3190_CODEC_BASE + 0x88) -#define RK3190_BIAS_CTL (RK3190_CODEC_BASE + 0x8c) -#define RK3190_ADC_CTL (RK3190_CODEC_BASE + 0x90) -#define RK3190_BST_CTL (RK3190_CODEC_BASE + 0x94) -#define RK3190_ALC_MUNIN_CTL (RK3190_CODEC_BASE + 0x98) -#define RK3190_ALCL_GAIN_CTL (RK3190_CODEC_BASE + 0x9c) -#define RK3190_ALCR_GAIN_CTL (RK3190_CODEC_BASE + 0xa0) -#define RK3190_ADC_ENABLE (RK3190_CODEC_BASE + 0xa4) -#define RK3190_DAC_CTL (RK3190_CODEC_BASE + 0xa8) -#define RK3190_DAC_ENABLE (RK3190_CODEC_BASE + 0xac) -#define RK3190_HPMIX_CTL (RK3190_CODEC_BASE + 0xb0) -#define RK3190_HPMIX_S_SELECT (RK3190_CODEC_BASE + 0xb4) -#define RK3190_HPOUT_CTL (RK3190_CODEC_BASE + 0xb8) -#define RK3190_HPOUTL_GAIN (RK3190_CODEC_BASE + 0xbc) -#define RK3190_HPOUTR_GAIN (RK3190_CODEC_BASE + 0xc0) -#define RK3190_PGA_AGC_CTL1 (RK3190_CODEC_BASE + 0x100) -#define RK3190_PGA_AGC_CTL2 (RK3190_CODEC_BASE + 0x104) -#define RK3190_PGA_AGC_CTL3 (RK3190_CODEC_BASE + 0x108) -#define RK3190_PGA_AGC_CTL4 (RK3190_CODEC_BASE + 0x10c) -#define RK3190_PGA_ASR_CTL (RK3190_CODEC_BASE + 0x110) -#define RK3190_PGA_AGC_MAX_H (RK3190_CODEC_BASE + 0x114) -#define RK3190_PGA_AGC_MAX_L (RK3190_CODEC_BASE + 0x118) -#define RK3190_PGA_AGC_MIN_H (RK3190_CODEC_BASE + 0x11c) -#define RK3190_PGA_AGC_MIN_L (RK3190_CODEC_BASE + 0x120) -#define RK3190_PGA_AGC_CTL5 (RK3190_CODEC_BASE + 0x124) -#if 0 -#define RK3190_PGAR_AGC_CTL1 (RK3190_CODEC_BASE + 0x140) -#define RK3190_PGAR_AGC_CTL2 (RK3190_CODEC_BASE + 0x144) -#define RK3190_PGAR_AGC_CTL3 (RK3190_CODEC_BASE + 0x148) -#define RK3190_PGAR_AGC_CTL4 (RK3190_CODEC_BASE + 0x14c) -#define RK3190_PGAR_ASR_CTL (RK3190_CODEC_BASE + 0x150) -#define RK3190_PGAR_AGC_MAX_H (RK3190_CODEC_BASE + 0x154) -#define RK3190_PGAR_AGC_MAX_L (RK3190_CODEC_BASE + 0x158) -#define RK3190_PGAR_AGC_MIN_H (RK3190_CODEC_BASE + 0x15c) -#define RK3190_PGAR_AGC_MIN_L (RK3190_CODEC_BASE + 0x160) -#define RK3190_PGAR_AGC_CTL5 (RK3190_CODEC_BASE + 0x164) -#endif - -/* ADC Interface Control 1 (0x08) */ -#define RK3190_ALRCK_POL_MASK (0x1 << 7) -#define RK3190_ALRCK_POL_SFT 7 -#define RK3190_ALRCK_POL_EN (0x1 << 7) -#define RK3190_ALRCK_POL_DIS (0x0 << 7) - -#define RK3190_ADC_VWL_MASK (0x3 << 5) -#define RK3190_ADC_VWL_SFT 5 -#define RK3190_ADC_VWL_32 (0x3 << 5) -#define RK3190_ADC_VWL_24 (0x2 << 5) -#define RK3190_ADC_VWL_20 (0x1 << 5) -#define RK3190_ADC_VWL_16 (0x0 << 5) - -#define RK3190_ADC_DF_MASK (0x3 << 3) -#define RK3190_ADC_DF_SFT 3 -#define RK3190_ADC_DF_PCM (0x3 << 3) -#define RK3190_ADC_DF_I2S (0x2 << 3) -#define RK3190_ADC_DF_LJ (0x1 << 3) -#define RK3190_ADC_DF_RJ (0x0 << 3) - -#define RK3190_ADC_SWAP_MASK (0x1 << 1) -#define RK3190_ADC_SWAP_SFT 1 -#define RK3190_ADC_SWAP_EN (0x1 << 1) -#define RK3190_ADC_SWAP_DIS (0x0 << 1) - -#define RK3190_ADC_TYPE_MASK 0x1 -#define RK3190_ADC_TYPE_SFT 0 -#define RK3190_ADC_TYPE_MONO 0x1 -#define RK3190_ADC_TYPE_STEREO 0x0 - -/* ADC Interface Control 2 (0x0c) */ -#define RK3190_I2S_MODE_MASK (0x1 << 4) -#define RK3190_I2S_MODE_SFT (4) -#define RK3190_I2S_MODE_MST (0x1 << 4) -#define RK3190_I2S_MODE_SLV (0x0 << 4) - -#define RK3190_ADC_WL_MASK (0x3 << 2) -#define RK3190_ADC_WL_SFT (2) -#define RK3190_ADC_WL_32 (0x3 << 2) -#define RK3190_ADC_WL_24 (0x2 << 2) -#define RK3190_ADC_WL_20 (0x1 << 2) -#define RK3190_ADC_WL_16 (0x0 << 2) - -#define RK3190_ADC_RST_MASK (0x1 << 1) -#define RK3190_ADC_RST_SFT 91) -#define RK3190_ADC_RST_DIS (0x1 << 1) -#define RK3190_ADC_RST_EN (0x0 << 1) - -#define RK3190_ABCLK_POL_MASK 0x1 -#define RK3190_ABCLK_POL_SFT 0 -#define RK3190_ABCLK_POL_EN 0x1 -#define RK3190_ABCLK_POL_DIS 0x0 - -/* DAC Interface Control 1 (0x10) */ -#define RK3190_DLRCK_POL_MASK (0x1 << 7) -#define RK3190_DLRCK_POL_SFT 7 -#define RK3190_DLRCK_POL_EN (0x1 << 7) -#define RK3190_DLRCK_POL_DIS (0x0 << 7) - -#define RK3190_DAC_VWL_MASK (0x3 << 5) -#define RK3190_DAC_VWL_SFT 5 -#define RK3190_DAC_VWL_32 (0x3 << 5) -#define RK3190_DAC_VWL_24 (0x2 << 5) -#define RK3190_DAC_VWL_20 (0x1 << 5) -#define RK3190_DAC_VWL_16 (0x0 << 5) - -#define RK3190_DAC_DF_MASK (0x3 << 3) -#define RK3190_DAC_DF_SFT 3 -#define RK3190_DAC_DF_PCM (0x3 << 3) -#define RK3190_DAC_DF_I2S (0x2 << 3) -#define RK3190_DAC_DF_LJ (0x1 << 3) -#define RK3190_DAC_DF_RJ (0x0 << 3) - -#define RK3190_DAC_SWAP_MASK (0x1 << 2) -#define RK3190_DAC_SWAP_SFT 2 -#define RK3190_DAC_SWAP_EN (0x1 << 2) -#define RK3190_DAC_SWAP_DIS (0x0 << 2) - -/* DAC Interface Control 2 (0x14) */ -#define RK3190_DAC_WL_MASK (0x3 << 2) -#define RK3190_DAC_WL_SFT 2 -#define RK3190_DAC_WL_32 (0x3 << 2) -#define RK3190_DAC_WL_24 (0x2 << 2) -#define RK3190_DAC_WL_20 (0x1 << 2) -#define RK3190_DAC_WL_16 (0x0 << 2) - -#define RK3190_DAC_RST_MASK (0x1 << 1) -#define RK3190_DAC_RST_SFT 1 -#define RK3190_DAC_RST_DIS (0x1 << 1) -#define RK3190_DAC_RST_EN (0x0 << 1) - -#define RK3190_DBCLK_POL_MASK 0x1 -#define RK3190_DBCLK_POL_SFT 0 -#define RK3190_DBCLK_POL_EN 0x1 -#define RK3190_DBCLK_POL_DIS 0x0 - -/* BIST MODE SELECT (0x1c) */ - -/* SELECT CURR prechagrge/discharge (0x88) */ -#define RK3190_PRE_HPOUT (0x1 << 5) -#define RK3190_DIS_HPOUT (0x0 << 5) -#define RK3190_CUR_10UA_EN (0x0 << 4) -#define RK3190_CUR_10UA_DIS (0x1 << 4) -#define RK3190_CUR_I_EN (0x0 << 3) -#define RK3190_CUR_I_DIS (0x1 << 3) -#define RK3190_CUR_2I_EN (0x0 << 2) -#define RK3190_CUR_2I_DIS (0x1 << 2) -#define RK3190_CUR_4I_EN (0x0 << 0) -#define RK3190_CUR_4I_DIS (0x3 << 0) - -/* MICBIAS (0x8c) */ -#define RK3190_MICBIAS_VOL_ENABLE (3) -#define RK3190_MICBIAS_VOL_SHT 0 -#define RK3190_MICBIAS_VOL_MSK 7 -#define RK3190_MICBIAS_VOL_MIN (0x0 << 0) -#define RK3190_MICBIAS_VOL_MAX (0x7 << 0) - -/* ADC control (0x90) */ -#define RK3190_ADC_CURRENT_ENABLE (0x1 << 6) -#define RK3190_ADC_CURRENT_DISABLE (0x0 << 6) - -#define RK3190_ADCL_REF_VOL_EN_SFT (5) -#define RK3190_ADCL_REF_VOL_EN (0x1 << 5) -#define RK3190_ADCL_REF_VOL_DIS (0x0 << 5) - -#define RK3190_ADCL_ZERO_DET_EN_SFT (4) -#define RK3190_ADCL_ZERO_DET_EN (0x1 << 4) -#define RK3190_ADCL_ZERO_DET_DIS (0x0 << 4) - -#define RK3190_ADCR_REF_VOL_EN_SFT (1) -#define RK3190_ADCR_REF_VOL_EN (0x1 << 1) -#define RK3190_ADCR_REF_VOL_DIS (0x0 << 1) - -#define RK3190_ADCR_ZERO_DET_EN_SFT (0) -#define RK3190_ADCR_ZERO_DET_EN (0x1 << 0) -#define RK3190_ADCR_ZERO_DET_DIS (0x0 << 0) - -/* BST_L BST_R CONTROL (0x94) */ -#define RK3190_BSTL_PWRD_SFT (7) -#define RK3190_BSTL_EN (0x1 << 7) -#define RK3190_BSTL_DIS (0x0 << 7) -#define RK3190_BSTL_GAIN_SHT (6) -#define RK3190_BSTL_GAIN_20 (0x1 << 6) -#define RK3190_BSTL_GAIN_0 (0x0 << 6) -#define RK3190_BSTL_MUTE_SHT (5) - -#define RK3190_BSTL_MODE_SFT (4) -#define RK3190_BSTL_MODE_SINGLE (0x1 << 4) -#define RK3190_BSTL_MODE_DIFF (0x0 << 4) - -#define RK3190_BSTR_PWRD_SFT (3) -#define RK3190_BSTR_EN (0x1 << 3) -#define RK3190_BSTR_DIS (0x0 << 3) -#define RK3190_BSTR_GAIN_SHT (2) -#define RK3190_BSTR_GAIN_20 (0x1 << 2) -#define RK3190_BSTR_GAIN_0 (0x0 << 2) -#define RK3190_BSTR_MUTE_SHT (1) - -/* MUXINL ALCL MUXINR ALCR (0x98) */ -#define RK3190_MUXINL_BSTL_SHT (7) -#define RK3190_MUXINL_BSTL_EN (0x0 << 7) -#define RK3190_MUXINL_BSTL_DIS (0x1 << 7) -#define RK3190_MUXINL_INL_SHT (6) -#define RK3190_MUXINL_INL_EN (0x0 << 6) -#define RK3190_MUXINL_INL_DIS (0x1 << 6) - -#define RK3190_ALCL_PWR_SHT (5) -#define RK3190_ALCL_EN (0x1 << 5) -#define RK3190_ALCL_DIS (0x0 << 5) -#define RK3190_ALCL_MUTE_SHT (4) - -#define RK3190_MUXINR_BSTR_SHT (3) -#define RK3190_MUXINR_BSTR_EN (0x0 << 3) -#define RK3190_MUXINR_BSTR_DIS (0x1 << 3) -#define RK3190_MUXINR_INR_SHT (2) -#define RK3190_MUXINR_INR_EN (0x0 << 2) -#define RK3190_MUXINR_INR_DIS (0x1 << 2) - -#define RK3190_ALCR_PWR_SHT (1) -#define RK3190_ALCR_EN (0x1 << 1) -#define RK3190_ALCR_DIS (0x0 << 1) -#define RK3190_ALCR_MUTE_SHT (0) - -/* ALC_L GAIN (0x9c) */ - -#define RK3190_ALCL_GAIN_SHT (0) -#define RK3190_ALCL_GAIN_MSK (0x1f) - -/* ALC_R GAIN (0xa0) */ -#define RK3190_ALCR_GAIN_SHT (0) -#define RK3190_ALCR_GAIN_MSK (0x1f) - -/* ADC ENABLE (0xa4) */ -#define RK3190_ADCL_CLK_EN_SFT (6) -#define RK3190_ADCL_CLK_EN (0x1 << 6) -#define RK3190_ADCL_CLK_DIS (0x0 << 6) - -#define RK3190_ADCL_AMP_EN_SFT (5) -#define RK3190_ADCL_AMP_EN (0x1 << 5) -#define RK3190_ADCL_AMP_DIS (0x0 << 5) - -#define RK3190_ADCL_RST_EN (0x1 << 4) -#define RK3190_ADCL_RST_DIS (0x0 << 4) - -#define RK3190_ADCR_CLK_EN_SFT (2) -#define RK3190_ADCR_CLK_EN (0x1 << 2) -#define RK3190_ADCR_CLK_DIS (0x0 << 2) - -#define RK3190_ADCR_AMP_EN_SFT (1) -#define RK3190_ADCR_AMP_EN (0x1 << 1) -#define RK3190_ADCR_AMP_DIS (0x0 << 1) - -#define RK3190_ADCR_RST_EN (0x1 << 0) -#define RK3190_ADCR_RST_DIS (0x0 << 0) - -/* DAC & VOUT Control (0xa8) */ -#define RK3190_CURRENT_EN (0x1 << 6) -#define RK3190_CURRENT_DIS (0x0 << 6) -#define RK3190_REF_VOL_DACL_EN_SFT (5) -#define RK3190_REF_VOL_DACL_EN (0x1 << 5) -#define RK3190_REF_VOL_DACL_DIS (0x0 << 5) -#define RK3190_ZO_DET_VOUTL_SFT (4) -#define RK3190_ZO_DET_VOUTL_EN (0x1 << 4) -#define RK3190_ZO_DET_VOUTL_DIS (0x0 << 4) -#define RK3190_DET_ERAPHONE_DIS (0x0 << 3) -#define RK3190_DET_ERAPHONE_EN (0x1 << 3) -#define RK3190_REF_VOL_DACR_EN_SFT (1) -#define RK3190_REF_VOL_DACR_EN (0x1 << 1) -#define RK3190_REF_VOL_DACR_DIS (0x0 << 1) -#define RK3190_ZO_DET_VOUTR_SFT (0) -#define RK3190_ZO_DET_VOUTR_EN (0x1 << 0) -#define RK3190_ZO_DET_VOUTR_DIS (0x0 << 0) - -/* DAC control (0xac) */ -#define RK3190_DACL_REF_VOL_EN_SFT (7) -#define RK3190_DACL_REF_VOL_EN (0x1 << 7) -#define RK3190_DACL_REF_VOL_DIS (0x0 << 7) - -#define RK3190_DACL_CLK_EN (0x1 << 6) -#define RK3190_DACL_CLK_DIS (0x0 << 6) - -#define RK3190_DACL_EN (0x1 << 5) -#define RK3190_DACL_DIS (0x0 << 5) - -#define RK3190_DACL_INIT (0x0 << 4) -#define RK3190_DACL_WORK (0x1 << 4) - -#define RK3190_DACR_REF_VOL_EN_SFT (3) -#define RK3190_DACR_REF_VOL_EN (0x1 << 3) -#define RK3190_DACR_REF_VOL_DIS (0x0 << 3) - -#define RK3190_DACR_CLK_EN (0x1 << 2) -#define RK3190_DACR_CLK_DIS (0x0 << 2) - -#define RK3190_DACR_EN (0x1 << 1) -#define RK3190_DACR_DIS (0x0 << 1) - -#define RK3190_DACR_INIT (0x0 << 0) -#define RK3190_DACR_WORK (0x1 << 0) - -/* HPMIXL HPMIXR Control (0xb0) */ -#define RK3190_HPMIXL_SFT (6) -#define RK3190_HPMIXL_EN (0x1 << 6) -#define RK3190_HPMIXL_DIS (0x0 << 6) -#define RK3190_HPMIXL_INIT1 (0x0 << 5) -#define RK3190_HPMIXL_WORK1 (0x1 << 5) -#define RK3190_HPMIXL_INIT2 (0x0 << 4) -#define RK3190_HPMIXL_WORK2 (0x1 << 4) -#define RK3190_HPMIXR_SFT (2) -#define RK3190_HPMIXR_EN (0x1 << 2) -#define RK3190_HPMIXR_DIS (0x0 << 2) -#define RK3190_HPMIXR_INIT1 (0x0 << 1) -#define RK3190_HPMIXR_WORK1 (0x1 << 1) -#define RK3190_HPMIXR_INIT2 (0x0 << 0) -#define RK3190_HPMIXR_WORK2 (0x1 << 0) - -/* HPMIXL Control (0xb4) */ -#define RK3190_HPMIXL_BYPASS_SFT (7) -#define RK3190_HPMIXL_SEL_ALCL_SFT (6) -#define RK3190_HPMIXL_SEL_ALCR_SFT (5) -#define RK3190_HPMIXL_SEL_DACL_SFT (4) -#define RK3190_HPMIXR_BYPASS_SFT (3) -#define RK3190_HPMIXR_SEL_ALCL_SFT (2) -#define RK3190_HPMIXR_SEL_ALCR_SFT (1) -#define RK3190_HPMIXR_SEL_DACR_SFT (0) - -/* HPOUT Control (0xb8) */ -#define RK3190_HPOUTL_PWR_SHT (7) -#define RK3190_HPOUTL_MSK (0x1 << 7) -#define RK3190_HPOUTL_EN (0x1 << 7) -#define RK3190_HPOUTL_DIS (0x0 << 7) -#define RK3190_HPOUTL_INIT_MSK (0x1 << 6) -#define RK3190_HPOUTL_INIT (0x0 << 6) -#define RK3190_HPOUTL_WORK (0x1 << 6) -#define RK3190_HPOUTL_MUTE_SHT (5) -#define RK3190_HPOUTL_MUTE_MSK (0x1 << 5) -#define RK3190_HPOUTL_MUTE_EN (0x0 << 5) -#define RK3190_HPOUTL_MUTE_DIS (0x1 << 5) -#define RK3190_HPOUTR_PWR_SHT (4) -#define RK3190_HPOUTR_MSK (0x1 << 4) -#define RK3190_HPOUTR_EN (0x1 << 4) -#define RK3190_HPOUTR_DIS (0x0 << 4) -#define RK3190_HPOUTR_INIT_MSK (0x1 << 3) -#define RK3190_HPOUTR_WORK (0x1 << 3) -#define RK3190_HPOUTR_INIT (0x0 << 3) -#define RK3190_HPOUTR_MUTE_SHT (2) -#define RK3190_HPOUTR_MUTE_MSK (0x1 << 2) -#define RK3190_HPOUTR_MUTE_EN (0x0 << 2) -#define RK3190_HPOUTR_MUTE_DIS (0x1 << 2) - -#define RK3190_HPVREF_PWR_SHT (1) -#define RK3190_HPVREF_EN (0x1 << 1) -#define RK3190_HPVREF_DIS (0x0 << 1) -#define RK3190_HPVREF_WORK (0x1 << 0) -#define RK3190_HPVREF_INIT (0x0 << 0) - -/* HPOUT GAIN (0xbc 0xc0) */ -#define RK3190_HPOUT_GAIN_SFT (0) - -/* SELECT CURR prechagrge/discharge (0xbc) */ -#define RK3190_PRE_HPOUT (0x1 << 5) -#define RK3190_DIS_HPOUT (0x0 << 5) -#define RK3190_CUR_10UA_EN (0x0 << 4) -#define RK3190_CUR_10UA_DIS (0x1 << 4) -#define RK3190_CUR_I_EN (0x0 << 3) -#define RK3190_CUR_I_DIS (0x1 << 3) -#define RK3190_CUR_2I_EN (0x0 << 2) -#define RK3190_CUR_2I_DIS (0x1 << 2) -#define RK3190_CUR_4I_EN (0x0 << 0) -#define RK3190_CUR_4I_DIS (0x3 << 0) - -/* PGA AGC control 1 (0x100) */ -#define RK3190_PGA_AGC_WAY_MASK (0x1 << 6) -#define RK3190_PGA_AGC_WAY_SFT 6 -#define RK3190_PGA_AGC_WAY_JACK (0x1 << 6) -#define RK3190_PGA_AGC_WAY_NOR (0x0 << 6) - -#define RK3190_PGA_AGC_BK_WAY_SFT 4 -#define RK3190_PGA_AGC_BK_WAY_JACK1 (0x1 << 4) -#define RK3190_PGA_AGC_BK_WAY_NOR (0x0 << 4) -#define RK3190_PGA_AGC_BK_WAY_JACK2 (0x2 << 4) -#define RK3190_PGA_AGC_BK_WAY_JACK3 (0x3 << 4) - -#define RK3190_PGA_AGC_HOLD_T_MASK 0xf -#define RK3190_PGA_AGC_HOLD_T_SFT 0 -#define RK3190_PGA_AGC_HOLD_T_1024 0xa -#define RK3190_PGA_AGC_HOLD_T_512 0x9 -#define RK3190_PGA_AGC_HOLD_T_256 0x8 -#define RK3190_PGA_AGC_HOLD_T_128 0x7 -#define RK3190_PGA_AGC_HOLD_T_64 0x6 -#define RK3190_PGA_AGC_HOLD_T_32 0x5 -#define RK3190_PGA_AGC_HOLD_T_16 0x4 -#define RK3190_PGA_AGC_HOLD_T_8 0x3 -#define RK3190_PGA_AGC_HOLD_T_4 0x2 -#define RK3190_PGA_AGC_HOLD_T_2 0x1 -#define RK3190_PGA_AGC_HOLD_T_0 0x0 - -/* PGA AGC control 2 (0x104) */ -#define RK3190_PGA_AGC_GRU_T_MASK (0xf << 4) -#define RK3190_PGA_AGC_GRU_T_SFT 4 -#define RK3190_PGA_AGC_GRU_T_512 (0xa << 4) -#define RK3190_PGA_AGC_GRU_T_256 (0x9 << 4) -#define RK3190_PGA_AGC_GRU_T_128 (0x8 << 4) -#define RK3190_PGA_AGC_GRU_T_64 (0x7 << 4) -#define RK3190_PGA_AGC_GRU_T_32 (0x6 << 4) -#define RK3190_PGA_AGC_GRU_T_16 (0x5 << 4) -#define RK3190_PGA_AGC_GRU_T_8 (0x4 << 4) -#define RK3190_PGA_AGC_GRU_T_4 (0x3 << 4) -#define RK3190_PGA_AGC_GRU_T_2 (0x2 << 4) -#define RK3190_PGA_AGC_GRU_T_1 (0x1 << 4) -#define RK3190_PGA_AGC_GRU_T_0_5 (0x0 << 4) - -#define RK3190_PGA_AGC_GRD_T_MASK 0xf -#define RK3190_PGA_AGC_GRD_T_SFT 0 -#define RK3190_PGA_AGC_GRD_T_128_32 0xa -#define RK3190_PGA_AGC_GRD_T_64_16 0x9 -#define RK3190_PGA_AGC_GRD_T_32_8 0x8 -#define RK3190_PGA_AGC_GRD_T_16_4 0x7 -#define RK3190_PGA_AGC_GRD_T_8_2 0x6 -#define RK3190_PGA_AGC_GRD_T_4_1 0x5 -#define RK3190_PGA_AGC_GRD_T_2_0_512 0x4 -#define RK3190_PGA_AGC_GRD_T_1_0_256 0x3 -#define RK3190_PGA_AGC_GRD_T_0_500_128 0x2 -#define RK3190_PGA_AGC_GRD_T_0_250_64 0x1 -#define RK3190_PGA_AGC_GRD_T_0_125_32 0x0 - -/* PGA AGC control 3 (0x108) */ -#define RK3190_PGA_AGC_MODE_MASK (0x1 << 7) -#define RK3190_PGA_AGC_MODE_SFT 7 -#define RK3190_PGA_AGC_MODE_LIMIT (0x1 << 7) -#define RK3190_PGA_AGC_MODE_NOR (0x0 << 7) - -#define RK3190_PGA_AGC_ZO_MASK (0x1 << 6) -#define RK3190_PGA_AGC_ZO_SFT 6 -#define RK3190_PGA_AGC_ZO_EN (0x1 << 6) -#define RK3190_PGA_AGC_ZO_DIS (0x0 << 6) - -#define RK3190_PGA_AGC_REC_MODE_MASK (0x1 << 5) -#define RK3190_PGA_AGC_REC_MODE_SFT 5 -#define RK3190_PGA_AGC_REC_MODE_AC (0x1 << 5) -#define RK3190_PGA_AGC_REC_MODE_RN (0x0 << 5) - -#define RK3190_PGA_AGC_FAST_D_MASK (0x1 << 4) -#define RK3190_PGA_AGC_FAST_D_SFT 4 -#define RK3190_PGA_AGC_FAST_D_EN (0x1 << 4) -#define RK3190_PGA_AGC_FAST_D_DIS (0x0 << 4) - -#define RK3190_PGA_AGC_NG_MASK (0x1 << 3) -#define RK3190_PGA_AGC_NG_SFT 3 -#define RK3190_PGA_AGC_NG_EN (0x1 << 3) -#define RK3190_PGA_AGC_NG_DIS (0x0 << 3) - -#define RK3190_PGA_AGC_NG_THR_MASK 0x7 -#define RK3190_PGA_AGC_NG_THR_SFT 0 -#define RK3190_PGA_AGC_NG_THR_N81DB 0x7 -#define RK3190_PGA_AGC_NG_THR_N75DB 0x6 -#define RK3190_PGA_AGC_NG_THR_N69DB 0x5 -#define RK3190_PGA_AGC_NG_THR_N63DB 0x4 -#define RK3190_PGA_AGC_NG_THR_N57DB 0x3 -#define RK3190_PGA_AGC_NG_THR_N51DB 0x2 -#define RK3190_PGA_AGC_NG_THR_N45DB 0x1 -#define RK3190_PGA_AGC_NG_THR_N39DB 0x0 - -/* PGA AGC Control 4 (0x10c) */ -#define RK3190_PGA_AGC_ZO_MODE_MASK (0x1 << 5) -#define RK3190_PGA_AGC_ZO_MODE_SFT 5 -#define RK3190_PGA_AGC_ZO_MODE_UWRC (0x1 << 5) -#define RK3190_PGA_AGC_ZO_MODE_UARC (0x0 << 5) - -#define RK3190_PGA_AGC_VOL_MASK 0x1f -#define RK3190_PGA_AGC_VOL_SFT 0 - -/* PGA ASR Control (0x110) */ -#define RK3190_PGA_SLOW_CLK_MASK (0x1 << 3) -#define RK3190_PGA_SLOW_CLK_SFT 3 -#define RK3190_PGA_SLOW_CLK_EN (0x1 << 3) -#define RK3190_PGA_SLOW_CLK_DIS (0x0 << 3) - -#define RK3190_PGA_ASR_MASK 0x7 -#define RK3190_PGA_ASR_SFT 0 -#define RK3190_PGA_ASR_8KHz 0x7 -#define RK3190_PGA_ASR_12KHz 0x6 -#define RK3190_PGA_ASR_16KHz 0x5 -#define RK3190_PGA_ASR_24KHz 0x4 -#define RK3190_PGA_ASR_32KHz 0x3 -#define RK3190_PGA_ASR_441KHz 0x2 -#define RK3190_PGA_ASR_48KHz 0x1 -#define RK3190_PGA_ASR_96KHz 0x0 - -/* PGA AGC Control 5 (0x124) */ -#define RK3190_PGA_AGC_MASK (0x1 << 6) -#define RK3190_PGA_AGC_SFT 6 -#define RK3190_PGA_AGC_EN (0x1 << 6) -#define RK3190_PGA_AGC_DIS (0x0 << 6) - -#define RK3190_PGA_AGC_MAX_G_MASK (0x7 << 3) -#define RK3190_PGA_AGC_MAX_G_SFT 3 -#define RK3190_PGA_AGC_MAX_G_28_5DB (0x7 << 3) -#define RK3190_PGA_AGC_MAX_G_22_5DB (0x6 << 3) -#define RK3190_PGA_AGC_MAX_G_16_5DB (0x5 << 3) -#define RK3190_PGA_AGC_MAX_G_10_5DB (0x4 << 3) -#define RK3190_PGA_AGC_MAX_G_4_5DB (0x3 << 3) -#define RK3190_PGA_AGC_MAX_G_N1_5DB (0x2 << 3) -#define RK3190_PGA_AGC_MAX_G_N7_5DB (0x1 << 3) -#define RK3190_PGA_AGC_MAX_G_N13_5DB (0x0 << 3) - -#define RK3190_PGA_AGC_MIN_G_MASK 0x7 -#define RK3190_PGA_AGC_MIN_G_SFT 0 -#define RK3190_PGA_AGC_MIN_G_24DB 0x7 -#define RK3190_PGA_AGC_MIN_G_18DB 0x6 -#define RK3190_PGA_AGC_MIN_G_12DB 0x5 -#define RK3190_PGA_AGC_MIN_G_6DB 0x4 -#define RK3190_PGA_AGC_MIN_G_0DB 0x3 -#define RK3190_PGA_AGC_MIN_G_N6DB 0x2 -#define RK3190_PGA_AGC_MIN_G_N12DB 0x1 -#define RK3190_PGA_AGC_MIN_G_N18DB 0x0 - -enum { - RK3190_HIFI, - RK3190_VOICE, -}; - -enum { - RK3190_MONO = 1, - RK3190_STEREO, -}; - -enum { - OFF, - RCV, - SPK_PATH, - HP_PATH, - HP_NO_MIC, - BT, - SPK_HP, - RING_SPK, - RING_HP, - RING_HP_NO_MIC, - RING_SPK_HP, -}; - -enum { - MIC_OFF, - Main_Mic, - Hands_Free_Mic, - BT_Sco_Mic, -}; - -struct rk3190_reg_val_typ { - unsigned int reg; - unsigned int value; -}; - -struct rk3190_init_bit_typ { - unsigned int reg; - unsigned int power_bit; - unsigned int init2_bit; - unsigned int init1_bit; - unsigned int init0_bit; -}; - -struct rk3190_codec_pdata { - int spk_ctl_gpio; - int hp_ctl_gpio; - int ear_ctl_gpio; - int delay_time; -}; - -#endif //__RK3190_CODEC_H__ diff --git a/sound/soc/codecs/rk610_codec.c b/sound/soc/codecs/rk610_codec.c deleted file mode 100755 index 86af3bec7969..000000000000 --- a/sound/soc/codecs/rk610_codec.c +++ /dev/null @@ -1,1111 +0,0 @@ -/* - * rk610.c -- RK610 ALSA SoC audio driver - * - * Copyright (C) 2009 rockchip lhh - * - * - * Based on RK610.c - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "rk610_codec.h" - -#define RK610_PROC - -#define HP_OUT 0 -#define HP_IN 1 - -//if you find resume rk610 cannot work,you can try RESUME_PROBLEM 1. -//if rk610 Normal working on RESUME_PROBLEM 1, you must detect Machine other driver queue. -//you can look soc-core.c the resume source.s -#define RESUME_PROBLEM 0 - -//1:set pll from rk610 -#define RK610_CTL_PLL 0 - -/* - * Debug - */ -#if 0 -#define DBG(x...) printk(KERN_INFO x) -#else -#define DBG(x...) -#endif - -//rk610 output volume,DAC Digital Gain -//0x0000 ~ 0xF42 -#define Volume_Output 0xF42 -//0x0 ~ 0x3f(bit0-bit5) max=0x0(+6DB) min=0x3f(-60DB) //Analog Gain -#define Volume_Codec_PA 0x0 - -//rk610 input volume,rk610 can not adjust the recording volume -#define Volume_Input 0x07 - - - -#define OUT_CAPLESS (1) //ÊÇ·ñΪÎÞµçÈÝÊä³ö£¬1:ÎÞµçÈÝÊä³ö£¬0:ÓеçÈÝÊä³ö - -static u8 gR0AReg = 0; //ÓÃÓڼǼR0A¼Ä´æÆ÷µÄÖµ£¬ÓÃÓڸıä²ÉÑùÂÊǰͨ¹ýR0AÍ£Ö¹clk -static u8 gR0BReg = 0; //ÓÃÓڼǼR0B¼Ä´æÆ÷µÄÖµ£¬ÓÃÓڸıä²ÉÑùÂÊǰͨ¹ýR0BÍ£Ö¹interplateºÍdecimation - - -/* - * rk610 register cache - * We can't read the RK610 register space when we - * are using 2 wire for device control, so we cache them instead. - */ -static const u16 rk610_codec_reg[] = { - 0x0005, 0x0004, 0x00fd, 0x00f3, /* 0 */ - 0x0003, 0x0000, 0x0000, 0x0000, /* 4 */ - 0x0000, 0x0005, 0x0000, 0x0000, /* 8 */ - 0x0097, 0x0097, 0x0097, 0x0097, /* 12 */ - 0x0097, 0x0097, 0x00cc, 0x0000, /* 16 */ - 0x0000, 0x00f1, 0x0090, 0x00ff, /* 20 */ - 0x00ff, 0x00ff, 0x009c, 0x0000, /* 24 */ - 0x0000, 0x00ff, 0x00ff, 0x00ff, /* 28 */ -}; - -static struct snd_soc_codec *rk610_codec_codec=NULL; -/* codec private data */ -struct rk610_codec_priv { - enum snd_soc_control_type control_type; - unsigned int sysclk; - struct snd_soc_codec codec; - struct snd_pcm_hw_constraint_list *sysclk_constraints; - u16 reg_cache[RK610_CODEC_NUM_REG]; - - struct delayed_work rk610_delayed_work; - unsigned int spk_ctrl_io; - /* - Some amplifiers enable a longer time. - config after pa_enable_io delay pa_enable_time(ms) - default = 0,preferably not more than 1000ms - so value range is 0 - 1000. - */ - unsigned int pa_enable_time; - bool hdmi_ndet; - int boot_depop;//if found boot pop,set boot_depop 1 test -#if RESUME_PROBLEM - int rk610_workstatus; -#endif - int call_enable; - int headset_status; -}; - -static void spk_ctrl_fun(int status) -{ - struct rk610_codec_priv *rk610_codec = NULL; - if(rk610_codec_codec == NULL) - return; - rk610_codec = snd_soc_codec_get_drvdata(rk610_codec_codec); - if(rk610_codec == NULL) - return; -#ifdef CONFIG_MODEM_SOUND - if(rk610_codec->call_enable){ - DBG("%s:: is calling cannot set spk\n",__FUNCTION__); - return; - } -#endif - if(rk610_codec->spk_ctrl_io) - { - DBG("%s:: spk status = %d\n",__FUNCTION__,status); - gpio_set_value(rk610_codec->spk_ctrl_io, status); - } -} - -/* - * read rk610 register cache - */ -static inline unsigned int rk610_codec_read_reg_cache(struct snd_soc_codec *codec, - unsigned int reg) -{ - u16 *cache = codec->reg_cache; - if (reg > RK610_CACHE_REGNUM) - return -1; - return cache[reg]; -} - -static unsigned int rk610_codec_read(struct snd_soc_codec *codec, unsigned int r) -{ - struct i2c_msg xfer[1]; - u8 reg = r; - int ret; - struct i2c_client *i2c = to_i2c_client(codec->dev); - - /* Read register */ - xfer[0].addr = (i2c->addr& 0x60)|(reg); - xfer[0].flags = I2C_M_RD; - xfer[0].len = 1; - xfer[0].buf = ® - xfer[0].scl_rate = 100000; - ret = i2c_transfer(i2c->adapter, xfer, 1); - if (ret != 1) { - dev_err(&i2c->dev, "i2c_transfer() returned %d\n", ret); - return 0; - } - - return reg; -} - -/* - * write rk610 register cache - */ -static inline void rk610_codec_write_reg_cache(struct snd_soc_codec *codec, - unsigned int reg, unsigned int value) -{ - u16 *cache = codec->reg_cache; - if (reg > RK610_CACHE_REGNUM) - return; - cache[reg] = value; -} - -static int rk610_codec_write(struct snd_soc_codec *codec, unsigned int reg, - unsigned int value) -{ - - struct rk610_codec_priv *rk610_codec = snd_soc_codec_get_drvdata(rk610_codec_codec); - u8 data[2]; - struct i2c_client *i2c = to_i2c_client(codec->dev); -#ifdef CONFIG_MODEM_SOUND - if(rk610_codec->call_enable) - return 0; -#endif - if(value == rk610_codec_read_reg_cache(codec,reg)) - return 0; - DBG("Enter::%s, %d, reg=0x%02X, value=0x%02X\n",__FUNCTION__,__LINE__, reg, value); - data[0] = value & 0x00ff; - - i2c->addr = (i2c->addr & 0x60)|reg; - - if (codec->hw_write(i2c, data, 1) == 1){ -// DBG("================%s %d Run OK================\n",__FUNCTION__,__LINE__); - rk610_codec_write_reg_cache (codec, reg, value); - return 0; - }else{ - DBG("================%s %d Run EIO================\n",__FUNCTION__,__LINE__); - return -EIO; - } -} - -#ifdef CONFIG_MODEM_SOUND -static int rk610_codec_write_incall(struct snd_soc_codec *codec, unsigned int reg, - unsigned int value) -{ - u8 data[2]; - struct i2c_client *i2c = to_i2c_client(codec->dev); - DBG("Enter::%s, %d, reg=0x%02X, value=0x%02X\n",__FUNCTION__,__LINE__, reg, value); - data[0] = value & 0x00ff; - rk610_codec_write_reg_cache (codec, reg, value); - i2c = (struct i2c_client *)codec->control_data; - i2c->addr = (i2c->addr & 0x60)|reg; - - if (codec->hw_write(i2c, data, 1) == 1) - return 0; - else - return -EIO; -} - -void call_set_spk(int on) -{ - struct rk610_codec_priv *rk610_codec; - if(!rk610_codec_codec) - return; - rk610_codec = snd_soc_codec_get_drvdata(rk610_codec_codec); - if(!rk610_codec) - return; - - switch(on) - { - case 0: - //modem exit call,codec disable loopback - printk("%s modem exit call \n", __FUNCTION__); - rk610_codec_write_incall(rk610_codec_codec,ACCELCODEC_R0E, 0x80); - rk610_codec->call_enable = 0; - break; - case 1: - //modem calling,codec enable loopback,spk hp different volume - printk("%s spk incalling\n", __FUNCTION__); - rk610_codec->call_enable = 1; - rk610_codec_write_incall(rk610_codec_codec,ACCELCODEC_R0E, 0x00); - return; - case 2: - printk("%s hp incalling\n", __FUNCTION__); - rk610_codec->call_enable = 1; - rk610_codec_write_incall(rk610_codec_codec,ACCELCODEC_R0E, 0x00); - break; - case 3: - printk("%s bt incalling\n", __FUNCTION__); - rk610_codec->call_enable = 1; - rk610_codec_write_incall(rk610_codec_codec,ACCELCODEC_R0E, 0x00); - break; - } - - return; -} -#endif -#ifdef CONFIG_RK_HEADSET_DET -//for headset -void rk2928_codec_set_spk(bool on) -{ - struct rk610_codec_priv *rk610_codec; - if(!rk610_codec_codec) - return; - rk610_codec=snd_soc_codec_get_drvdata(rk610_codec_codec); - if(!rk610_codec) - return; - - if(on) - rk610_codec->headset_status = HP_IN; - else - rk610_codec->headset_status = HP_OUT; - - if(rk610_codec->call_enable) - return; - - printk("%s: headset %s %s PA bias_level=%d\n",__FUNCTION__,on?"in":"out",on?"disable":"enable",codec->dapm.bias_level); - if(on) { - if(rk610_codec->spk_ctrl_io) - gpio_set_value(rk610_codec->spk_ctrl_io, GPIO_LOW); - } - else { - if(codec->dapm.bias_level == SND_SOC_BIAS_STANDBY - || codec->dapm.bias_level == SND_SOC_BIAS_OFF){ - return; - } - if(rk610_codec->spk_ctrl_io) - gpio_set_value(rk610_codec->spk_ctrl_io, GPIO_HIGH); - } -} -#endif - -void rk610_codec_reg_read(void) -{ - struct snd_soc_codec *codec = rk610_codec_codec; - int i; - unsigned int data; - - for (i=0; i<=0x1f; i++){ - data = rk610_codec_read(codec, i); - printk("reg[0x%x]=0x%x\n",i,data); - } -} - -struct _coeff_div { - u32 mclk; - u32 rate; - u16 fs; - u8 sr:5; - u8 usb:1; - u8 bclk; -}; - -/* codec hifi mclk clock divider coefficients */ -static const struct _coeff_div coeff_div[] = { - /* 8k */ - {12288000, 8000, 1536, 0x6, 0x0,ASC_BCLKDIV_16}, - {11289600, 8000, 1408, 0x16, 0x0,ASC_BCLKDIV_16}, - {18432000, 8000, 2304, 0x7, 0x0,ASC_BCLKDIV_16}, - {16934400, 8000, 2112, 0x17, 0x0,ASC_BCLKDIV_16}, - {8192000, 8000, 1024, 0x0, 0x0,ASC_BCLKDIV_16}, - {12000000, 8000, 1500, 0x6, 0x1,ASC_BCLKDIV_16}, - - /* 11.025k */ - {11289600, 11025, 1024, 0x18, 0x0,ASC_BCLKDIV_16}, - {16934400, 11025, 1536, 0x19, 0x0,ASC_BCLKDIV_16}, - {12000000, 11025, 1088, 0x19, 0x1,ASC_BCLKDIV_16}, - - /* 12k */ - {12288000, 12000, 1024, 0x8, 0x0,ASC_BCLKDIV_16}, - {18432000, 12000, 1536, 0x9, 0x0,ASC_BCLKDIV_16}, - {12000000, 12000, 1000, 0x8, 0x1,ASC_BCLKDIV_16}, - - /* 16k */ - {12288000, 16000, 768, 0xa, 0x0,ASC_BCLKDIV_8}, - {18432000, 16000, 1152, 0xb, 0x0,ASC_BCLKDIV_8}, - {12000000, 16000, 750, 0xa, 0x1,ASC_BCLKDIV_8}, - - /* 22.05k */ - {11289600, 22050, 512, 0x1a, 0x0,ASC_BCLKDIV_8}, - {16934400, 22050, 768, 0x1b, 0x0,ASC_BCLKDIV_8}, - {12000000, 22050, 544, 0x1b, 0x1,ASC_BCLKDIV_8}, - - /* 24k */ - {12288000, 24000, 512, 0x1c, 0x0,ASC_BCLKDIV_8}, - {18432000, 24000, 768, 0x1d, 0x0,ASC_BCLKDIV_8}, - {12000000, 24000, 500, 0x1c, 0x1,ASC_BCLKDIV_8}, - - /* 32k */ - {12288000, 32000, 384, 0xc, 0x0,ASC_BCLKDIV_8}, - {18432000, 32000, 576, 0xd, 0x0,ASC_BCLKDIV_8}, - {12000000, 32000, 375, 0xa, 0x1,ASC_BCLKDIV_8}, - - /* 44.1k */ - {11289600, 44100, 256, 0x10, 0x0,ASC_BCLKDIV_4}, - {16934400, 44100, 384, 0x11, 0x0,ASC_BCLKDIV_8}, - {12000000, 44100, 272, 0x11, 0x1,ASC_BCLKDIV_8}, - - /* 48k */ - {12288000, 48000, 256, 0x0, 0x0,ASC_BCLKDIV_4}, - {18432000, 48000, 384, 0x1, 0x0,ASC_BCLKDIV_4}, - {12000000, 48000, 250, 0x0, 0x1,ASC_BCLKDIV_4}, - - /* 88.2k */ - {11289600, 88200, 128, 0x1e, 0x0,ASC_BCLKDIV_4}, - {16934400, 88200, 192, 0x1f, 0x0,ASC_BCLKDIV_4}, - {12000000, 88200, 136, 0x1f, 0x1,ASC_BCLKDIV_4}, - - /* 96k */ - {12288000, 96000, 128, 0xe, 0x0,ASC_BCLKDIV_4}, - {18432000, 96000, 192, 0xf, 0x0,ASC_BCLKDIV_4}, - {12000000, 96000, 125, 0xe, 0x1,ASC_BCLKDIV_4}, -}; - -static inline int get_coeff(int mclk, int rate) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(coeff_div); i++) { - if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk) - return i; - } - - return -EINVAL; -} - -/* The set of rates we can generate from the above for each SYSCLK */ - -static unsigned int rates_12288[] = { - 8000, 12000, 16000, 24000, 24000, 32000, 48000, 96000, -}; - -static struct snd_pcm_hw_constraint_list constraints_12288 = { - .count = ARRAY_SIZE(rates_12288), - .list = rates_12288, -}; - -static unsigned int rates_112896[] = { - 8000, 11025, 22050, 44100, -}; - -static struct snd_pcm_hw_constraint_list constraints_112896 = { - .count = ARRAY_SIZE(rates_112896), - .list = rates_112896, -}; - -static unsigned int rates_12[] = { - 8000, 11025, 12000, 16000, 22050, 2400, 32000, 41100, 48000, - 48000, 88235, 96000, -}; - -static struct snd_pcm_hw_constraint_list constraints_12 = { - .count = ARRAY_SIZE(rates_12), - .list = rates_12, -}; - -static int rk610_codec_set_bias_level(struct snd_soc_codec *codec, - enum snd_soc_bias_level level) -{ - struct rk610_codec_priv *rk610_codec =snd_soc_codec_get_drvdata(codec); - DBG("Enter::%s----%d now_level =%d old_level = %d\n",__FUNCTION__,__LINE__,level,codec->dapm.bias_level); - switch (level) { - case SND_SOC_BIAS_ON: - break; - case SND_SOC_BIAS_PREPARE: - /* VREF, VMID=2x50k, digital enabled */ - // rk610_codec_write(codec, ACCELCODEC_R1D, pwr_reg | 0x0080); - break; - - case SND_SOC_BIAS_STANDBY: -#if RESUME_PROBLEM - if(rk610_codec->rk610_workstatus == SND_SOC_DAPM_STREAM_RESUME) - { - DBG("rk610 is resume,have not into standby\n"); - rk610_codec->rk610_workstatus = SND_SOC_DAPM_STREAM_NOP; - break; - } -#endif - printk("rk610 standby\n"); - spk_ctrl_fun(GPIO_LOW); - rk610_codec_write(codec,ACCELCODEC_R0A, ASC_CLK_DISABLE); - rk610_codec_write(codec, ACCELCODEC_R1D, 0xFE); - rk610_codec_write(codec, ACCELCODEC_R1E, 0xFF); - rk610_codec_write(codec, ACCELCODEC_R1F, 0xFF); - break; - - case SND_SOC_BIAS_OFF: - printk("rk610 power off\n"); - spk_ctrl_fun(GPIO_LOW); - rk610_codec_write(codec,ACCELCODEC_R0A, ASC_CLK_DISABLE); - rk610_codec_write(codec, ACCELCODEC_R1D, 0xFF); - rk610_codec_write(codec, ACCELCODEC_R1E, 0xFF); - rk610_codec_write(codec, ACCELCODEC_R1F, 0xFF); - break; - } - - codec->dapm.bias_level = level; - - return 0; -} - -/* - * Note that this should be called from init rather than from hw_params. - */ -static int rk610_codec_set_dai_sysclk(struct snd_soc_dai *codec_dai, - int clk_id, unsigned int freq, int dir) -{ - struct snd_soc_codec *codec = codec_dai->codec; - - struct rk610_codec_priv *rk610_codec =snd_soc_codec_get_drvdata(codec); - - DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); - -#if RK610_CTL_PLL - if(rk610_codec_pll_set(freq)) - return -EINVAL; -#endif - switch (freq) { - case 11289600: - case 18432000: - case 22579200: - case 36864000: - rk610_codec->sysclk_constraints = &constraints_112896; - rk610_codec->sysclk = freq; - break; - - case 12288000: - case 16934400: - case 24576000: - case 33868800: - rk610_codec->sysclk_constraints = &constraints_12288; - rk610_codec->sysclk = freq; - break; - - case 12000000: - case 24000000: - rk610_codec->sysclk_constraints = &constraints_12; - rk610_codec->sysclk = freq; - break; - default: - return -EINVAL; - } - return 0; -} - -static int rk610_codec_set_dai_fmt(struct snd_soc_dai *codec_dai, - unsigned int fmt) -{ - struct snd_soc_codec *codec = codec_dai->codec; - struct rk610_codec_priv *rk610_codec =snd_soc_codec_get_drvdata(codec); - u16 iface = 0; - -//modify 2013-06-27 - if(rk610_codec->pa_enable_time<300) - spk_ctrl_fun(GPIO_LOW); - else - spk_ctrl_fun(GPIO_HIGH); - rk610_codec_write(codec,ACCELCODEC_R1D, 0x2a); //setup Vmid and Vref, other module power down - rk610_codec_write(codec,ACCELCODEC_R1E, 0x40); ///|ASC_PDASDML_ENABLE); - - /* set master/slave audio interface */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: - iface = 0x0040; - break; - case SND_SOC_DAIFMT_CBS_CFS: - iface = 0x0000; - break; - default: - return -EINVAL; - } - - /* interface format */ - switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_I2S: - iface |= 0x0002; - break; - case SND_SOC_DAIFMT_RIGHT_J: - break; - case SND_SOC_DAIFMT_LEFT_J: - iface |= 0x0001; - break; - case SND_SOC_DAIFMT_DSP_A: - iface |= 0x0003; - break; - case SND_SOC_DAIFMT_DSP_B: - iface |= 0x0013; - break; - default: - return -EINVAL; - } - - /* clock inversion */ - switch (fmt & SND_SOC_DAIFMT_INV_MASK) { - case SND_SOC_DAIFMT_NB_NF: - break; - case SND_SOC_DAIFMT_IB_IF: - iface |= 0x0090; - break; - case SND_SOC_DAIFMT_IB_NF: - iface |= 0x0080; - break; - case SND_SOC_DAIFMT_NB_IF: - iface |= 0x0010; - break; - default: - return -EINVAL; - } - - DBG("Enter::%s----%d iface=%x\n",__FUNCTION__,__LINE__,iface); - rk610_codec_write(codec, ACCELCODEC_R09, iface); - return 0; -} - -static int rk610_codec_pcm_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec *codec = rtd->codec; - struct rk610_codec_priv *rk610_codec =snd_soc_codec_get_drvdata(codec); - unsigned int dai_fmt = rtd->card->dai_link[0].dai_fmt; - - u16 iface = rk610_codec_read_reg_cache(codec, ACCELCODEC_R09) & 0x1f3; - u16 srate = rk610_codec_read_reg_cache(codec, ACCELCODEC_R00) & 0x180; - int coeff; - - coeff = get_coeff(rk610_codec->sysclk, params_rate(params)); - DBG("Enter::%s----%d rk610_codec->sysclk=%d coeff = %d\n",__FUNCTION__,__LINE__,rk610_codec->sysclk, coeff); - /* bit size */ - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: - break; - case SNDRV_PCM_FORMAT_S20_3LE: - iface |= 0x0004; - break; - case SNDRV_PCM_FORMAT_S24_LE: - iface |= 0x0008; - break; - case SNDRV_PCM_FORMAT_S32_LE: - iface |= 0x000c; - break; - } - DBG("Enter::%s----%d iface=%x srate =%x rate=%d\n",__FUNCTION__,__LINE__,iface,srate,params_rate(params)); - -// rk610_codec_write(codec,ACCELCODEC_R0C, 0x17); - rk610_codec_write(codec,ACCELCODEC_R04, ASC_INT_MUTE_L|ASC_INT_MUTE_R|ASC_SIDETONE_L_OFF|ASC_SIDETONE_R_OFF); //soft mute - //±ØÐëÏȽ«clkºÍEN_INT¶¼disableµô£¬·ñÔòÇл»bclk·ÖƵֵ¿ÉÄܵ¼ÖÂcodecÄÚ²¿Ê±Ðò»ìÂÒµô£¬ - //±íÏÖ³öÀ´µÄÏÖÏóÊÇ£¬ÒÔºóµÄÒôÀÖ¶¼±ä³ÉÁËÔëÒô£¬¶øÇÒ¾ÍËã°ÑÊäÈëcodecµÄI2S_DATAOUT¶Ï¿ªÒ²Ò»Ñù³öÔëÒô - rk610_codec_write(codec,ACCELCODEC_R0B, ASC_DEC_DISABLE|ASC_INT_DISABLE); //0x00 - - /* set iface & srate */ - if ((dai_fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBM_CFM) - iface |= ASC_INVERT_BCLK;//·­×ªBCLK master״̬ËͳöµÄÉÙÁ˰ë¸öʱÖÓ£¬µ¼ÖÂδµ½×î´óÒôÁ¿µÄʱºòÆÆÒô¡¢ - - rk610_codec_write(codec, ACCELCODEC_R09, iface); - if (coeff >= 0){ - // rk610_codec_write(codec, ACCELCODEC_R00, srate|coeff_div[coeff].bclk); - rk610_codec_write(codec, ACCELCODEC_R0A, (coeff_div[coeff].sr << 1) | coeff_div[coeff].usb|ASC_CLKNODIV|ASC_CLK_ENABLE); - } - rk610_codec_write(codec,ACCELCODEC_R0B, gR0BReg); - - return 0; -} - -static int rk610_codec_mute(struct snd_soc_dai *dai, int mute) -{ - struct snd_soc_codec *codec = dai->codec; - struct rk610_codec_priv *rk610_codec =snd_soc_codec_get_drvdata(codec); - printk("Enter::%s----%d--mute=%d\n",__FUNCTION__,__LINE__,mute); - - if (mute) - { - rk610_codec_write(codec,ACCELCODEC_R17, 0xFF); //AOL - rk610_codec_write(codec,ACCELCODEC_R18, 0xFF); //AOR - rk610_codec_write(codec,ACCELCODEC_R19, 0xFF); //AOM - rk610_codec_write(codec,ACCELCODEC_R04, ASC_INT_MUTE_L|ASC_INT_MUTE_R|ASC_SIDETONE_L_OFF|ASC_SIDETONE_R_OFF); //soft mute - //add for standby - // if(!dai->capture_active) - // { - // rk610_codec_write(codec, ACCELCODEC_R1D, 0xFE); - // rk610_codec_write(codec, ACCELCODEC_R1E, 0xFF); - // rk610_codec_write(codec, ACCELCODEC_R1F, 0xFF); - // } - } - else - { - // rk610_codec_write(codec,ACCELCODEC_R1D, 0x2a); //setup Vmid and Vref, other module power down - // rk610_codec_write(codec,ACCELCODEC_R1E, 0x40); ///|ASC_PDASDML_ENABLE); - rk610_codec_write(codec,ACCELCODEC_R17, Volume_Codec_PA|ASC_OUTPUT_ACTIVE|ASC_CROSSZERO_EN); //AOL Volume_Codec_PA|ASC_OUTPUT_ACTIVE|ASC_CROSSZERO_EN); //AOL - rk610_codec_write(codec,ACCELCODEC_R18, Volume_Codec_PA|ASC_OUTPUT_ACTIVE|ASC_CROSSZERO_EN); //Volume_Codec_PA|ASC_OUTPUT_ACTIVE|ASC_CROSSZERO_EN); //AOR - rk610_codec_write(codec,ACCELCODEC_R04, ASC_INT_ACTIVE_L|ASC_INT_ACTIVE_R|ASC_SIDETONE_L_OFF|ASC_SIDETONE_R_OFF); - rk610_codec_write(codec,ACCELCODEC_R19, 0x7F); //AOM - - if(rk610_codec->pa_enable_time == 0) - msleep(300); - #if OUT_CAPLESS - rk610_codec_write(codec,ACCELCODEC_R1F, 0x09|ASC_PDMIXM_ENABLE); - #else - rk610_codec_write(codec,ACCELCODEC_R1F, 0x09|ASC_PDMIXM_ENABLE|ASC_PDPAM_ENABLE); - #endif - // schedule_delayed_work(&rk610_codec->rk610_delayed_work, 0); - // rk610_codec_reg_read(); - if(rk610_codec->hdmi_ndet){ - if(rk610_codec->pa_enable_time == 0 ) - spk_ctrl_fun(GPIO_HIGH); - else if(rk610_codec->pa_enable_time > 0 && rk610_codec->pa_enable_time < 300){ - spk_ctrl_fun(GPIO_HIGH); - msleep(rk610_codec->pa_enable_time) ; - } - else if(rk610_codec->pa_enable_time >=300 && rk610_codec->pa_enable_time < 1000) - msleep(rk610_codec->pa_enable_time); - } - } - - return 0; -} - -static void rk610_delayedwork_fun(struct work_struct *work) -{ - struct snd_soc_codec *codec = rk610_codec_codec; - struct rk610_codec_priv *rk610_codec =snd_soc_codec_get_drvdata(codec); - - DBG("--------%s----------\n",__FUNCTION__); - if(!rk610_codec->boot_depop){ - #if OUT_CAPLESS - rk610_codec_write(codec,ACCELCODEC_R1F, 0x09|ASC_PDMIXM_ENABLE); - #else - rk610_codec_write(codec,ACCELCODEC_R1F, 0x09|ASC_PDMIXM_ENABLE|ASC_PDPAM_ENABLE); - #endif - } - spk_ctrl_fun(GPIO_HIGH); -} - -static struct snd_soc_dai_ops rk610_codec_ops = { - .hw_params = rk610_codec_pcm_hw_params, - .set_fmt = rk610_codec_set_dai_fmt, - .set_sysclk = rk610_codec_set_dai_sysclk, - .digital_mute = rk610_codec_mute, -}; - -#define RK610_CODEC_RATES SNDRV_PCM_RATE_8000_96000 -#define RK610_CODEC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ - SNDRV_PCM_FMTBIT_S24_LE) - -static struct snd_soc_dai_driver rk610_codec_dai = { - .name = "rk610_codec", - .playback = { - .stream_name = "Playback", - .channels_min = 1, - .channels_max = 2, - .rates = RK610_CODEC_RATES, - .formats = RK610_CODEC_FORMATS, - }, - .capture = { - .stream_name = "Capture", - .channels_min = 1, - .channels_max = 2, - .rates = RK610_CODEC_RATES, - .formats = RK610_CODEC_FORMATS, - }, - .ops = &rk610_codec_ops, - .symmetric_rates = 1, -}; - -static int rk610_codec_suspend(struct snd_soc_codec *codec) -{ - DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); - rk610_codec_set_bias_level(codec, SND_SOC_BIAS_OFF); -// rk610_codec_reg_read(); - return 0; -} - -static int rk610_codec_resume(struct snd_soc_codec *codec) -{ - struct rk610_codec_priv *rk610_codec =snd_soc_codec_get_drvdata(codec); - - DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); - /* Sync reg_cache with the hardware */ - -// rk610_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY); -#if RESUME_PROBLEM - rk610_codec->rk610_workstatus = SND_SOC_DAPM_STREAM_RESUME; -#endif - return 0; -} - -#define USE_MIC_IN -#define USE_LPF -void rk610_codec_reg_set(void) -{ - struct snd_soc_codec *codec = rk610_codec_codec; - struct rk610_codec_priv *rk610_codec =snd_soc_codec_get_drvdata(codec); - - unsigned int digital_gain; - unsigned int mic_vol = Volume_Input; - rk610_codec_write(codec,ACCELCODEC_R1D, 0x30); - rk610_codec_write(codec,ACCELCODEC_R1E, 0x40); - -#ifdef USE_LPF - // Route R-LPF->R-Mixer, L-LPF->L-Mixer - rk610_codec_write(codec,ACCELCODEC_R15, 0xC1); -#else - // Route RDAC->R-Mixer, LDAC->L->Mixer - rk610_codec_write(codec,ACCELCODEC_R15, 0x0C); -#endif - // With Cap Output, VMID ramp up slow - rk610_codec_write(codec,ACCELCODEC_R1A, 0x14); - mdelay(10); - - rk610_codec_write(codec,ACCELCODEC_R0C, 0x10|ASC_INPUT_VOL_0DB); //LIL - rk610_codec_write(codec,ACCELCODEC_R0D, 0x10|ASC_INPUT_VOL_0DB); //LIR - -#ifdef USE_MIC_IN - if(mic_vol > 0x07) - { - rk610_codec_write(codec,ACCELCODEC_R12, 0x4c|ASC_MIC_INPUT|ASC_MIC_BOOST_20DB); //Select MIC input - mic_vol -= 0x07; - } - else - rk610_codec_write(codec,ACCELCODEC_R12, 0x4c|ASC_MIC_INPUT); //Select MIC input - rk610_codec_write(codec,ACCELCODEC_R1C, ASC_DEM_ENABLE); //0x00); //use default value -#else - rk610_codec_write(codec,ACCELCODEC_R12, 0x4c); //Select Line input -#endif - - rk610_codec_write(codec,ACCELCODEC_R0E, 0x10|mic_vol); //MIC - - // Diable route PGA->R/L Mixer, PGA gain 0db. - rk610_codec_write(codec,ACCELCODEC_R13, 0x05 | 0 << 3); - rk610_codec_write(codec,ACCELCODEC_R14, 0x05 | 0 << 3); - - //2soft mute - rk610_codec_write(codec,ACCELCODEC_R04, ASC_INT_MUTE_L|ASC_INT_MUTE_R|ASC_SIDETONE_L_OFF|ASC_SIDETONE_R_OFF); //soft mute - - //2set default SR and clk - rk610_codec_write(codec,ACCELCODEC_R0A, ASC_NORMAL_MODE|(0x10 << 1)|ASC_CLKNODIV|ASC_CLK_DISABLE); - gR0AReg = ASC_NORMAL_MODE|(0x10 << 1)|ASC_CLKNODIV|ASC_CLK_DISABLE; - //2Config audio interface - rk610_codec_write(codec,ACCELCODEC_R09, ASC_I2S_MODE|ASC_16BIT_MODE|ASC_NORMAL_LRCLK|ASC_LRSWAP_DISABLE|ASC_NORMAL_BCLK); - rk610_codec_write(codec,ACCELCODEC_R00, ASC_HPF_ENABLE|ASC_DSM_MODE_ENABLE|ASC_SCRAMBLE_ENABLE|ASC_DITHER_ENABLE|ASC_BCLKDIV_4); - //2volume,input,output - digital_gain = Volume_Output; - - if(rk610_codec_read(codec,ACCELCODEC_R05)!=0x0f) { - rk610_codec_write(codec,ACCELCODEC_R05, (digital_gain >> 8) & 0xFF); - rk610_codec_write(codec,ACCELCODEC_R06, digital_gain & 0xFF); - } - if(rk610_codec_read(codec,ACCELCODEC_R07)!=0x0f){ - rk610_codec_write(codec,ACCELCODEC_R07, (digital_gain >> 8) & 0xFF); - rk610_codec_write(codec,ACCELCODEC_R08, digital_gain & 0xFF); - } - rk610_codec_write(codec,ACCELCODEC_R0B, ASC_DEC_ENABLE|ASC_INT_ENABLE); - gR0BReg = ASC_DEC_ENABLE|ASC_INT_ENABLE; //ASC_DEC_DISABLE|ASC_INT_ENABLE; - - if(rk610_codec->boot_depop){ - #if OUT_CAPLESS - rk610_codec_write(codec,ACCELCODEC_R1F, 0x09|ASC_PDMIXM_ENABLE); - #else - rk610_codec_write(codec,ACCELCODEC_R1F, 0x09|ASC_PDMIXM_ENABLE|ASC_PDPAM_ENABLE); - #endif - } -} - -static int rk610_codec_probe(struct snd_soc_codec *codec) -{ - struct rk610_codec_priv *rk610_codec = snd_soc_codec_get_drvdata(codec); - int ret; - - rk610_codec_codec = codec; - DBG("[%s] start\n", __FUNCTION__); - ret = snd_soc_codec_set_cache_io(codec, 8, 16, rk610_codec->control_type); - if (ret != 0) { - dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); - return ret; - } - - //For RK610, i2c write&read method is special, do not use system default method. - codec->write = rk610_codec_write; - codec->read = rk610_codec_read; - codec->hw_write = (hw_write_t)i2c_master_send; - - if (rk610_codec_codec == NULL) { - dev_err(codec->dev, "Codec device not registered\n"); - return -ENODEV; - } - - INIT_DELAYED_WORK(&rk610_codec->rk610_delayed_work, rk610_delayedwork_fun); - - if(rk610_codec->spk_ctrl_io) - { - ret = gpio_request(rk610_codec->spk_ctrl_io, "rk610 spk_ctrl"); - if (ret){ - printk("rk610_control request gpio fail!\n"); - return ret; - } - gpio_direction_output(rk610_codec->spk_ctrl_io, GPIO_LOW); - gpio_set_value(rk610_codec->spk_ctrl_io, GPIO_LOW); - } - - rk610_codec->hdmi_ndet = true; - rk610_codec->call_enable = 0; - rk610_codec->headset_status = HP_OUT; -#if RESUME_PROBLEM - rk610_codec->rk610_workstatus = SND_SOC_DAPM_STREAM_NOP; -#endif - - rk610_control_init_codec(); - rk610_codec_reg_set(); -// rk610_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - schedule_delayed_work(&rk610_codec->rk610_delayed_work, msecs_to_jiffies(1000)); - - codec->dapm.bias_level = SND_SOC_BIAS_PREPARE; - return ret; -} - -/* power down chip */ -static int rk610_codec_remove(struct snd_soc_codec *codec) -{ - rk610_codec_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - -static struct snd_soc_codec_driver soc_codec_dev_rk610_codec = { - .probe = rk610_codec_probe, - .remove = rk610_codec_remove, - .suspend = rk610_codec_suspend, - .resume = rk610_codec_resume, - .set_bias_level = rk610_codec_set_bias_level, -// .volatile_register = wm8900_volatile_register, - .reg_cache_size = ARRAY_SIZE(rk610_codec_reg), - .reg_word_size = sizeof(u16), - .reg_cache_default = rk610_codec_reg, -// .dapm_widgets = rk610_codec_dapm_widgets, -// .num_dapm_widgets = ARRAY_SIZE(rk610_codec_dapm_widgets), -// .dapm_routes = audio_map, -// .num_dapm_routes = ARRAY_SIZE(audio_map), -}; - -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) -static int rk610_codec_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) -{ - struct rk610_codec_priv *rk610_codec; - struct device_node *rk610_np = i2c->dev.of_node; - int ret; - int val = 0; - DBG("%s start\n", __FUNCTION__); - rk610_codec = kzalloc(sizeof(struct rk610_codec_priv), GFP_KERNEL); - if (rk610_codec == NULL) - return -ENOMEM; - - if(!of_property_read_u32(rk610_np, "boot_depop", &val)) - rk610_codec->boot_depop = val; - if(!of_property_read_u32(rk610_np, "pa_enable_time", &val)) - rk610_codec->pa_enable_time = val; - if(rk610_codec->pa_enable_time > 1000) - rk610_codec->pa_enable_time = 1000; - - rk610_codec->spk_ctrl_io = of_get_named_gpio(rk610_np,"spk_ctl_io", 0); - if (!gpio_is_valid(rk610_codec->spk_ctrl_io)){ - printk("invalid core_info->reset_gpio: %d\n",rk610_codec->spk_ctrl_io); - return -1; - } - - i2c_set_clientdata(i2c, rk610_codec); - rk610_codec->control_type = SND_SOC_I2C; - - ret = snd_soc_register_codec(&i2c->dev, - &soc_codec_dev_rk610_codec, &rk610_codec_dai, 1); - if (ret < 0) { - dev_err(&i2c->dev, "Failed to register codec: %d\n", ret); - kfree(rk610_codec); - } - return ret; -} - -static int rk610_codec_i2c_remove(struct i2c_client *client) -{ - snd_soc_unregister_codec(&client->dev); - kfree(i2c_get_clientdata(client)); - return 0; -} - -static const struct i2c_device_id rk610_codec_i2c_id[] = { - { "rk610_codec", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, rk610_codec_i2c_id); - -/* corgi i2c codec control layer */ -static struct i2c_driver rk610_codec_i2c_driver = { - .driver = { - .name = "rk610_codec", - .owner = THIS_MODULE, - }, - .probe = rk610_codec_i2c_probe, - .remove = rk610_codec_i2c_remove, - .id_table = rk610_codec_i2c_id, -}; -#endif - -static int __init rk610_codec_modinit(void) -{ - int ret; - DBG("[%s] start\n", __FUNCTION__); - ret = i2c_add_driver(&rk610_codec_i2c_driver); - if (ret != 0) - pr_err("rk610 codec: Unable to register I2C driver: %d\n", ret); - return ret; -} -module_init(rk610_codec_modinit); - -static void __exit rk610_codec_exit(void) -{ - i2c_del_driver(&rk610_codec_i2c_driver); -} -module_exit(rk610_codec_exit); - -MODULE_DESCRIPTION("ASoC RK610 CODEC driver"); -MODULE_AUTHOR("rk@rock-chips.com"); -MODULE_LICENSE("GPL"); - -//===================================================================== -//Proc -#ifdef RK610_PROC -#include -#include -#include -static ssize_t rk610_reg_write(struct file *file, - const char __user *buffer, size_t len, loff_t *ppos) -{ - char *cookie_pot; - char *p; - int reg; - int value; - struct rk610_codec_priv *rk610_codec = snd_soc_codec_get_drvdata(rk610_codec_codec); - - cookie_pot = (char *)vmalloc( len ); - if (!cookie_pot) - { - return -ENOMEM; - } - else - { - if (copy_from_user( cookie_pot, buffer, len )) - return -EFAULT; - } - - switch(cookie_pot[0]) - { - case 'p': - spk_ctrl_fun(GPIO_HIGH); - break; - case 'o': - spk_ctrl_fun(GPIO_LOW); - break; - case 'r': - case 'R': - printk("Read reg debug\n"); - if(cookie_pot[1] ==':') - { - strsep(&cookie_pot,":"); - while((p=strsep(&cookie_pot,","))) - { - reg = simple_strtol(p,NULL,16); - value = rk610_codec_read(rk610_codec_codec,reg); - printk("wm8994_read:0x%04x = 0x%04x\n",reg,value); - } - printk("\n"); - } - else - { - printk("Error Read reg debug.\n"); - printk("For example: echo 'r:22,23,24,25'>wm8994_ts\n"); - } - break; - case 'w': - case 'W': - printk("Write reg debug\n"); - if(cookie_pot[1] ==':') - { - strsep(&cookie_pot,":"); - while((p=strsep(&cookie_pot,"="))) - { - reg = simple_strtol(p,NULL,16); - p=strsep(&cookie_pot,","); - value = simple_strtol(p,NULL,16); - rk610_codec_write(rk610_codec_codec,reg,value); - printk("wm8994_write:0x%04x = 0x%04x\n",reg,value); - } - printk("\n"); - } - else - { - printk("Error Write reg debug.\n"); - printk("For example: w:22=0,23=0,24=0,25=0\n"); - } - break; - case 'D' : - printk("Dump reg\n"); - rk610_codec_reg_read(); - break; - case 't' : - printk("old pa_enable_time = %d\n",rk610_codec->pa_enable_time); - if(cookie_pot[1] ==':') - { - strsep(&cookie_pot,":"); - p=strsep(&cookie_pot," "); - rk610_codec->pa_enable_time = simple_strtol(p,NULL,10); - printk("new pa_enable_time = %d\n",rk610_codec->pa_enable_time); - } - break; - } - - return len; -} -static int proc_reg_show(struct seq_file *s, void *v) -{ - - return 0; -} -static int proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, proc_reg_show, NULL); -} - -static const struct file_operations proc_i2s_fops = { - .open = proc_open, - .read = seq_read, - .write = rk610_reg_write, - .llseek = seq_lseek, - .release = single_release, -}; -static int __init rk610_proc_init(void) -{ - proc_create("driver/rk610_ts", 0, NULL, &proc_i2s_fops); - return 0; -} -late_initcall(rk610_proc_init); -#endif diff --git a/sound/soc/codecs/rk610_codec.h b/sound/soc/codecs/rk610_codec.h deleted file mode 100755 index 8f52a973ab66..000000000000 --- a/sound/soc/codecs/rk610_codec.h +++ /dev/null @@ -1,268 +0,0 @@ -/* - * - * Copyright (C) 2009 rockchip lhh - * - * Based on WM8750.h - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ - -#ifndef _RK610_CODEC_H -#define _RK610_CODEC_H - -/* RK610 register space */ - -#define ACCELCODEC_R00 0x00 //ADC High Pass Filter / DSM -#define ACCELCODEC_R01 0x01 //DITHER power -#define ACCELCODEC_R02 0x02 //DITHER power -#define ACCELCODEC_R03 0x03 //DITHER power -#define ACCELCODEC_R04 0x04 //Soft mute / sidetone gain control -#define ACCELCODEC_R05 0x05 //Right interpolate filter volume control (MSB) -#define ACCELCODEC_R06 0x06 //Right interpolate filter volume control (LSB) -#define ACCELCODEC_R07 0x07 //Left interpolate filter volume control (MSB) -#define ACCELCODEC_R08 0x08 //Left interpolate filter volume control (LSB) -#define ACCELCODEC_R09 0x09 //Audio interface control -#define ACCELCODEC_R0A 0x0A //Sample Rate / CLK control -#define ACCELCODEC_R0B 0x0B //Decimation filter / Interpolate filter enable -#define ACCELCODEC_R0C 0x0C //LIN volume -#define ACCELCODEC_R0D 0x0D //LIP volume -#define ACCELCODEC_R0E 0x0E //AL volume -//#define ACCELCODEC_R0F 0x0F //RIN volume -//#define ACCELCODEC_R10 0x10 //RIP volume -//#define ACCELCODEC_R11 0x11 //AR volume -#define ACCELCODEC_R12 0x12 //Input volume -#define ACCELCODEC_R13 0x13 //Left out mix -#define ACCELCODEC_R14 0x14 //Right out mix -#define ACCELCODEC_R15 0x15 //LPF out mix / SCF -#define ACCELCODEC_R16 0x16 //SCF control -#define ACCELCODEC_R17 0x17 //LOUT (AOL) volume -#define ACCELCODEC_R18 0x18 //ROUT (AOR) volume -#define ACCELCODEC_R19 0x19 //MONOOUT (AOM) volume -#define ACCELCODEC_R1A 0x1A //MONOOUT / Reference control -#define ACCELCODEC_R1B 0x1B //Bias Current control -#define ACCELCODEC_R1C 0x1C //ADC control -#define ACCELCODEC_R1D 0x1D //Power Mrg 1 -#define ACCELCODEC_R1E 0x1E //Power Mrg 2 -#define ACCELCODEC_R1F 0x1F //Power Mrg 3 - -#define RK610_CACHE_REGNUM 0x1F - -//ACCELCODEC_R00 -#define ASC_HPF_ENABLE (0x1) //high_pass filter -#define ASC_HPF_DISABLE (0x0) - -#define ASC_DSM_MODE_ENABLE (0x1 << 1) -#define ASC_DSM_MODE_DISABLE (0x0 << 1) - -#define ASC_SCRAMBLE_ENABLE (0x1 << 2) -#define ASC_SCRAMBLE_DISABLE (0x0 << 2) - -#define ASC_DITHER_ENABLE (0x1 << 3) -#define ASC_DITHER_DISABLE (0x0 << 3) - -#define ASC_BCLKDIV_4 (0x1 << 4) -#define ASC_BCLKDIV_8 (0x2 << 4) -#define ASC_BCLKDIV_16 (0x3 << 4) - -//ACCECODEC_R04 -#define ASC_INT_MUTE_L (0x1) -#define ASC_INT_ACTIVE_L (0x0) -#define ASC_INT_MUTE_R (0x1 << 1) -#define ASC_INT_ACTIVE_R (0x0 << 1) - -#define ASC_SIDETONE_L_OFF (0x0 << 2) -#define ASC_SIDETONE_L_GAIN_MAX (0x1 << 2) -#define ASC_SIDETONE_R_OFF (0x0 << 5) -#define ASC_SIDETONE_R_GAIN_MAX (0x1 << 5) - - -//ACCELCODEC_R05 -#define ASC_INT_VOL_0DB (0x0) - - -//ACCELCODEC_R09 -#define ASC_DSP_MODE (0x3) -#define ASC_I2S_MODE (0x2) -#define ASC_LEFT_MODE (0x1) -//#define ASC_RIGHT_MODE (0x0) - -#define ASC_32BIT_MODE (0x3 << 2) -#define ASC_24BIT_MODE (0x2 << 2) -#define ASC_20BIT_MODE (0x1 << 2) -#define ASC_16BIT_MODE (0x0 << 2) - -#define ASC_INVERT_LRCLK (0x1 << 4) -#define ASC_NORMAL_LRCLK (0x0 << 4) - -#define ASC_LRSWAP_ENABLE (0x1 << 5) -#define ASC_LRSWAP_DISABLE (0x0 << 5) - -#define ASC_MASTER_MODE (0x1 << 6) -#define ASC_SLAVE_MODE (0x0 << 6) - -#define ASC_INVERT_BCLK (0x1 << 7) -#define ASC_NORMAL_BCLK (0x0 << 7) - -//ACCELCODEC_R0A -#define ASC_USB_MODE (0x1) -#define ASC_NORMAL_MODE (0x0) - -#define FREQ96kHz (0x0e << 1) -#define FREQ48kHz (0x00 << 1) -#define FREQ441kHz (0x11 << 1) -#define FREQ32kHz (0x0c << 1) -#define FREQ24kHz (0x1c << 1) -#define FREQ2205kHz (0x1B << 1) -#define FREQ16kHz (0x0a << 1) -#define FREQ12kHz (0x08 << 1) -#define FREQ11025kHz (0x19 << 1) -//#define FREQ9k6Hz 0x09 -#define FREQ8kHz (0x06<<1) - -#define ASC_CLKDIV2 (0x1 << 6) -#define ASC_CLKNODIV (0x0 << 6) - -#define ASC_CLK_ENABLE (0x1 << 7) -#define ASC_CLK_DISABLE (0x0 << 7) - -//ACCELCODEC_R0B -#define ASC_DEC_ENABLE (0x1) //decimation filter enable -#define ASC_DEC_DISABLE (0x0) -#define ASC_INT_ENABLE (0x1 << 1) //interpolate filter enable -#define ASC_INT_DISABLE (0x0 << 1) - -//Input ACCELCODEC_R0E -#define ASC_INPUT_MUTE (0x1 << 7) -#define ASC_INPUT_ACTIVE (0x0 << 7) -#define ASC_INPUT_VOL_0DB (0x0) - -//ACCELCODEC_R12 -#define ASC_LINE_INPUT (0) -#define ASC_MIC_INPUT (1 << 7) - -#define ASC_MIC_BOOST_0DB (0) -#define ASC_MIC_BOOST_20DB (1 << 5) - -//ACCELCODEC_R13 -#define ASC_LPGAMXVOL_0DB (0x5) -#define ASC_LPGAMX_ENABLE (0x1 << 3) //the left channel PGA output is directly fed into the left mixer -#define ASC_LPGAMX_DISABLE (0x0 << 3) -#define ASC_ALMXVOL_0DB (0x5 << 4) -#define ASC_ALMX_ENABLE (0x1 << 7) //the left second line input is directly fed into the left mixer -#define ASC_ALMX_DISABLE (0x0 << 7) - -//ACCELCODEC_R14 -#define ASC_RPGAMXVOL_0DB (0x5) -#define ASC_RPGAMX_ENABLE (0x1 << 3) //the right channel PGA output is directly fed into the right mixer -#define ASC_RPGAMX_DISABLE (0x0 << 3) -#define ASC_ARMXVOL_0DB (0x5 << 4) -#define ASC_ARMX_ENABLE (0x1 << 7) //)the right second line input is directly fed into the right mixer -#define ASC_ARMX_DISABLE (0x0 << 7) - -//ACCELCODEC_R15 -#define ASC_LDAMX_ENABLE (0x1 << 2) //the left differential signal from DAC is directly fed into the left mixer -#define ASC_LDAMX_DISABLE (0x0 << 2) -#define ASC_RDAMX_ENABLE (0x1 << 3) //the right differential signal from DAC is directly fed into the right mixer -#define ASC_RDAMX_DISABLE (0x0 << 3) -#define ASC_LSCF_MUTE (0x1 << 4) //the left channel LPF is mute -#define ASC_LSCF_ACTIVE (0x0 << 4) -#define ASC_RSCF_MUTE (0x1 << 5) //the right channel LPF is mute -#define ASC_RSCF_ACTIVE (0x0 << 5) -#define ASC_LLPFMX_ENABLE (0x1 << 6) //the left channel LPF output is fed into the left into the mixer -#define ASC_LLPFMX_DISABLE (0x0 << 6) -#define ASC_RLPFMX_ENABLE (0x1 << 7) //the right channel LPF output is fed into the right into the mixer. -#define ASC_RLPFMX_DISABLE (0x0 << 7) - -//ACCELCODEC_R17/R18 -#define ASC_OUTPUT_MUTE (0x1 << 6) -#define ASC_OUTPUT_ACTIVE (0x0 << 6) -#define ASC_CROSSZERO_EN (0x1 << 7) -#define ASC_OUTPUT_VOL_0DB (0x0F) -//ACCELCODEC_R19 -#define ASC_MONO_OUTPUT_MUTE (0x1 << 7) -#define ASC_MONO_OUTPUT_ACTIVE (0x0 << 7) -#define ASC_MONO_CROSSZERO_EN (0x1 << 6) - -//ACCELCODEC_R1A -#define ASC_VMDSCL_SLOWEST (0x0 << 2) -#define ASC_VMDSCL_SLOW (0x1 << 2) -#define ASC_VMDSCL_FAST (0x2 << 2) -#define ASC_VMDSCL_FASTEST (0x3 << 2) - -#define ASC_MICBIAS_09 (0x1 << 4) -#define ASC_MICBIAS_06 (0x0 << 4) - -#define ASC_L2M_ENABLE (0x1 << 5) //the right channel LPF output is fed to mono PA -#define ASC_L2M_DISABLE (0x0 << 5) -#define ASC_R2M_ENABLE (0x1 << 6) //the left channel LPF output is fed to mono PA -#define ASC_R2M_DISABLE (0x0 << 6) -#define ASC_CAPLESS_ENABLE (0x1 << 7) //the capless connection is enable -#define ASC_CAPLESS_DISABLE (0x0 << 7) - -//ACCELCODEC_R1C -#define ASC_DITH_0_DIV (0x0 << 3) //the amplitude setting of the ASDM dither(div=vdd/48) -#define ASC_DITH_2_DIV (0x1 << 3) -#define ASC_DITH_4_DIV (0x2 << 3) -#define ASC_DITH_8_DIV (0x3 << 3) - -#define ASC_DITH_ENABLE (0x1 << 5) //the ASDM dither is enabled -#define ASC_DITH_DISABLE (0x0 << 5) - -#define ASC_DEM_ENABLE (0x1 << 7) //the ASDM DEM is enabled -#define ASC_DEM_DISABLE (0x0 << 7) - -//ACCELCODEC_R1D -#define ASC_PDVMID_ENABLE (0x1) //the VMID reference is powered down. VMID is connected to GND -#define ASC_PDVMID_DISABLE (0x0) -#define ASC_PDSDL_ENABLE (0x1 << 2) //the PGA S2D buffer is power down -#define ASC_PDSDL_DISABLE (0x0 << 2) -#define ASC_PDBSTL_ENABLE (0x1 << 4) //the micphone input Op-Amp is power down -#define ASC_PDBSTL_DISABLE (0x0 << 4) -#define ASC_PDPGAL_ENABLE (0x1 << 6) //the PGA is power down -#define ASC_PDPGAL_DISABLE (0x0 << 6) -#define ASC_PDREF_ENABLE (0x1 << 7) //reference generator is power down -#define ASC_PDREF_DISABLE (0x0 << 7) - -//ACCELCODEC_R1E -#define ASC_PDPAR_ENABLE (0x1) //the right channel PA is power down -#define ASC_PDPAR_DISABLE (0x0) -#define ASC_PDPAL_ENABLE (0x1 << 1) //the left channel power amplifier is power down -#define ASC_PDPAL_DISABLE (0x0 << 1) -#define ASC_PDMIXR_ENABLE (0x1 << 2) //the right mixer is power down -#define ASC_PDMIXR_DISABLE (0x0 << 2) -#define ASC_PDMIXL_ENABLE (0x1 << 3) //the left mixer is power down -#define ASC_PDMIXL_DISABLE (0x0 << 3) -#define ASC_PDLPFR_ENABLE (0x1 << 4) //the right RC LPF is power down -#define ASC_PDLPFR_DISABLE (0x0 << 4) -#define ASC_PDLPFL_ENABLE (0x1 << 5) //the left channel RC LPF is power down -#define ASC_PDLPFL_DISABLE (0x0 << 5) -#define ASC_PDASDML_ENABLE (0x1 << 7) //the ASDM is power down -#define ASC_PDASDML_DISABLE (0x0 << 7) - -//ACCELCODEC_R1F -#define ASC_PDSCFR_ENABLE (0x1 << 1) //the right channel DAC is power down -#define ASC_PDSCFR_DISABLE (0x0 << 1) -#define ASC_PDSCFL_ENABLE (0x1 << 2) //the left channel DAC is power down -#define ASC_PDSCFL_DISABLE (0x0 << 2) -#define ASC_PDMICB_ENABLE (0x1 << 4) //the micbias is power down -#define ASC_PDMICB_DISABLE (0x0 << 4) -#define ASC_PDIB_ENABLE (0x1 << 5) //the left channel LPF is power down -#define ASC_PDIB_DISABLE (0x0 << 5) -#define ASC_PDMIXM_ENABLE (0x1 << 6) //the mon mixer is power down -#define ASC_PDMIXM_DISABLE (0x0 << 6) -#define ASC_PDPAM_ENABLE (0x1 << 7) //the mono PA is power down. -#define ASC_PDPAM_DISABLE (0x0 << 7) - -#define LINE_2_MIXER_GAIN (0x5) //left and right PA gain -#define RK610_CODEC_NUM_REG 0x20 - -#define GPIO_HIGH 1 -#define GPIO_LOW 0 - - -extern int rk610_control_init_codec(void); -extern int rk610_codec_pll_set(unsigned int rate); -#endif diff --git a/sound/soc/codecs/rk616_codec.c b/sound/soc/codecs/rk616_codec.c deleted file mode 100644 index ab593eee361a..000000000000 --- a/sound/soc/codecs/rk616_codec.c +++ /dev/null @@ -1,3280 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * rk616.c -- RK616 CODEC ALSA SoC audio driver - * - * Copyright 2013 Rockship - * Author: chenjq - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "rk616_codec.h" - -#if 0 -#define DBG(x...) pr_info(x) -#else -#define DBG(x...) -#endif - -/* For route */ -#define RK616_CODEC_PLAYBACK 1 -#define RK616_CODEC_CAPTURE 2 -#define RK616_CODEC_INCALL 4 -#define RK616_CODEC_ALL (RK616_CODEC_PLAYBACK |\ - RK616_CODEC_CAPTURE | RK616_CODEC_INCALL) - -/* for gpio */ -#define RK616_CODEC_SET_SPK 1 -#define RK616_CODEC_SET_HP 2 -#define RK616_CODEC_SET_RCV 4 -#define RK616_CODEC_SET_MIC 8 - -#define GPIO_LOW 0 -#define GPIO_HIGH 1 -#define INVALID_GPIO -1 - -struct rk616_codec_priv { - struct snd_soc_codec *codec; - - unsigned int stereo_sysclk; - unsigned int rate; - - int spk_ctl_gpio; - int hp_ctl_gpio; - int rcv_ctl_gpio; - int mic_sel_gpio; - - bool spk_gpio_level; - bool hp_gpio_level; - bool rcv_gpio_level; - bool mic_gpio_level; - - unsigned int spk_amp_delay; - unsigned int hp_mos_delay; - - unsigned int spk_volume; - unsigned int hp_volume; - unsigned int capture_volume; - - bool hpmic_from_linein; - bool hpmic_from_mic2in; - bool virtual_gnd; - - long int playback_path; - long int capture_path; - long int voice_call_path; - long int voip_path; - long int modem_input_enable; -}; - -static struct rk616_codec_priv *rk616_priv; -static struct mfd_rk616 *rk616_mfd; -static bool rk616_for_mid = 1; - -bool rk616_get_for_mid(void) -{ - return rk616_for_mid; -} - -static int rk616_get_parameter(void) -{ - int val; - char *command_line = strstr(saved_command_line, "ap_has_alsa="); - - if (command_line == NULL) { - pr_info("%s : Can not get ap_has_alsa from kernel command line!\n", - __func__); - return 0; - } - - command_line += 12; - - val = kstrtol(command_line, 10, NULL); - if (val == 0 || val == 1) { - rk616_for_mid = (val ? 0 : 1); - pr_info("%s : THIS IS FOR %s\n", - __func__, rk616_for_mid ? "mid" : "phone"); - } else { - pr_info("%s : get ap_has_alsa error, val = %d\n", - __func__, val); - } - - return 0; -} - -static const unsigned int rk616_reg_defaults[RK616_PGAR_AGC_CTL5 + 1] = { - [RK616_RESET] = 0x0003, - [RK616_DAC_VOL] = 0x0046, - [RK616_ADC_INT_CTL1] = 0x0050, - [RK616_ADC_INT_CTL2] = 0x000e, - [RK616_DAC_INT_CTL1] = 0x0050, - [RK616_DAC_INT_CTL2] = 0x000e, - [RK616_CLK_CHPUMP] = 0x0021, - [RK616_PGA_AGC_CTL] = 0x000c, - [RK616_PWR_ADD1] = 0x007c, - [RK616_BST_CTL] = 0x0099, - [RK616_DIFFIN_CTL] = 0x0024, - [RK616_MIXINL_CTL] = 0x001f, - [RK616_MIXINL_VOL1] = 0x0024, - [RK616_MIXINL_VOL2] = 0x0004, - [RK616_MIXINR_CTL] = 0x003f, - [RK616_MIXINR_VOL1] = 0x0024, - [RK616_MIXINR_VOL2] = 0x0024, - [RK616_PGAL_CTL] = 0x00cc, - [RK616_PGAR_CTL] = 0x00cc, - [RK616_PWR_ADD2] = 0x00ff, - [RK616_DAC_CTL] = 0x003f, - [RK616_LINEMIX_CTL] = 0x001f, - [RK616_MUXHP_HPMIX_CTL] = 0x003c, - [RK616_HPMIX_CTL] = 0x00ff, - [RK616_HPMIX_VOL1] = 0x0000, - [RK616_HPMIX_VOL2] = 0x0000, - [RK616_LINEOUT1_CTL] = 0x0060, - [RK616_LINEOUT2_CTL] = 0x0060, - [RK616_SPKL_CTL] = 0x00e0, - [RK616_SPKR_CTL] = 0x00e0, - [RK616_HPL_CTL] = 0x00e0, - [RK616_HPR_CTL] = 0x00e0, - [RK616_MICBIAS_CTL] = 0x00ff, - [RK616_MICKEY_DET_CTL] = 0x0028, - [RK616_PWR_ADD3] = 0x000f, - [RK616_ADC_CTL] = 0x0036, - [RK616_SINGNAL_ZC_CTL1] = 0x003f, - [RK616_SINGNAL_ZC_CTL2] = 0x00ff, - [RK616_PGAL_AGC_CTL1] = 0x0010, - [RK616_PGAL_AGC_CTL2] = 0x0025, - [RK616_PGAL_AGC_CTL3] = 0x0041, - [RK616_PGAL_AGC_CTL4] = 0x002c, - [RK616_PGAL_ASR_CTL] = 0x0000, - [RK616_PGAL_AGC_MAX_H] = 0x0026, - [RK616_PGAL_AGC_MAX_L] = 0x0040, - [RK616_PGAL_AGC_MIN_H] = 0x0036, - [RK616_PGAL_AGC_MIN_L] = 0x0020, - [RK616_PGAL_AGC_CTL5] = 0x0038, - [RK616_PGAR_AGC_CTL1] = 0x0010, - [RK616_PGAR_AGC_CTL2] = 0x0025, - [RK616_PGAR_AGC_CTL3] = 0x0041, - [RK616_PGAR_AGC_CTL4] = 0x002c, - [RK616_PGAR_ASR_CTL] = 0x0000, - [RK616_PGAR_AGC_MAX_H] = 0x0026, - [RK616_PGAR_AGC_MAX_L] = 0x0040, - [RK616_PGAR_AGC_MIN_H] = 0x0036, - [RK616_PGAR_AGC_MIN_L] = 0x0020, - [RK616_PGAR_AGC_CTL5] = 0x0038, -}; - -/* mfd registers default list */ -static struct rk616_reg_val_typ rk616_mfd_reg_defaults[] = { - {CRU_CODEC_DIV, 0x00000000}, - {CRU_IO_CON0, (I2S1_OUT_DISABLE | I2S0_OUT_DISABLE | - I2S1_PD_DISABLE | I2S0_PD_DISABLE) | - ((I2S1_OUT_DISABLE | I2S0_OUT_DISABLE | - I2S1_PD_DISABLE | I2S0_PD_DISABLE) << 16)}, - {CRU_IO_CON1, (I2S1_SI_EN | I2S0_SI_EN) | - ((I2S1_SI_EN | I2S0_SI_EN) << 16)}, - {CRU_PCM2IS2_CON2, (0) | ((PCM_TO_I2S_MUX | APS_SEL | - APS_CLR | I2S_CHANNEL_SEL) << 16)}, - {CRU_CFGMISC_CON, 0x00000000}, -}; - -/* mfd registers cache list */ -static struct rk616_reg_val_typ rk616_mfd_reg_cache[] = { - {CRU_CODEC_DIV, 0x00000000}, - {CRU_IO_CON0, (I2S1_OUT_DISABLE | I2S0_OUT_DISABLE | - I2S1_PD_DISABLE | I2S0_PD_DISABLE) | - ((I2S1_OUT_DISABLE | I2S0_OUT_DISABLE | - I2S1_PD_DISABLE | I2S0_PD_DISABLE) << 16)}, - {CRU_IO_CON1, (I2S1_SI_EN | I2S0_SI_EN) | - ((I2S1_SI_EN | I2S0_SI_EN) << 16)}, - {CRU_PCM2IS2_CON2, (0) | ((PCM_TO_I2S_MUX | APS_SEL | - APS_CLR | I2S_CHANNEL_SEL) << 16)}, - {CRU_CFGMISC_CON, 0x00000000}, -}; -#define RK616_MFD_REG_LEN ARRAY_SIZE(rk616_mfd_reg_cache) - -static int rk616_mfd_register(unsigned int reg) -{ - int i; - - for (i = 0; i < RK616_MFD_REG_LEN; i++) { - if (rk616_mfd_reg_cache[i].reg == reg) - return 1; - } - - return 0; -} - -/* If register's bit16-31 is mask bit add to this fun */ -static int rk616_mfd_mask_register(unsigned int reg) -{ - switch (reg) { - case CRU_IO_CON0: - case CRU_IO_CON1: - case CRU_PCM2IS2_CON2: - return 1; - default: - return 0; - } -} - -static struct rk616_reg_val_typ rk616_mfd_codec_bit_list[] = { - {CRU_CFGMISC_CON, AD_DA_LOOP | MICDET2_PIN_F_CODEC | - MICDET1_PIN_F_CODEC}, -}; -#define RK616_MFD_CODEC_BIT_LEN ARRAY_SIZE(rk616_mfd_codec_bit_list) - -static int rk616_mfd_codec_bit(unsigned int reg) -{ - int i; - - for (i = 0; i < RK616_MFD_CODEC_BIT_LEN; i++) { - if (rk616_mfd_codec_bit_list[i].reg == reg) - return i; - } - - return -1; -} - -static struct rk616_init_bit_typ rk616_init_bit_list[] = { - {RK616_SPKL_CTL, RK616_MUTE, RK616_INIT_MASK}, - {RK616_SPKR_CTL, RK616_MUTE, RK616_INIT_MASK}, - {RK616_HPL_CTL, RK616_MUTE, RK616_INIT_MASK}, - {RK616_HPR_CTL, RK616_MUTE, RK616_INIT_MASK}, - {RK616_MUXHP_HPMIX_CTL, RK616_HML_PWRD, RK616_HML_INIT_MASK}, - {RK616_MUXHP_HPMIX_CTL, RK616_HMR_PWRD, RK616_HMR_INIT_MASK}, -}; -#define RK616_INIT_BIT_LIST_LEN ARRAY_SIZE(rk616_init_bit_list) - -static int rk616_init_bit_register(unsigned int reg, int i) -{ - for (; i < RK616_INIT_BIT_LIST_LEN; i++) { - if (rk616_init_bit_list[i].reg == reg) - return i; - } - - return -1; -} - -static unsigned int rk616_codec_read(struct snd_soc_codec *codec, - unsigned int reg); - -static unsigned int rk616_set_init_value(struct snd_soc_codec *codec, - unsigned int reg, unsigned int value) -{ - unsigned int read_value, power_bit, set_bit; - int i; - - /* read codec init register */ - i = rk616_init_bit_register(reg, 0); - - /* - * Set codec init bit - * widget init bit should be setted 0 after widget power up or unmute, - * and should be setted 1 after widget power down or mute. - */ - if (i >= 0) { - read_value = rk616_codec_read(codec, reg); - while (i >= 0) { - power_bit = rk616_init_bit_list[i].power_bit; - set_bit = rk616_init_bit_list[i].init_bit; - - if ((read_value & power_bit) != (value & power_bit)) - value = (value & ~set_bit) | - ((value & power_bit) ? set_bit : 0); - - i = rk616_init_bit_register(reg, ++i); - } - } - - return value; -} - -static int rk616_volatile_register(struct snd_soc_codec *codec, - unsigned int reg) -{ - switch (reg) { - case RK616_RESET: - case RK616_CLK_CHPUMP: - case RK616_MICKEY_DET_CTL: - case CRU_CFGMISC_CON: - return 1; - default: - return 0; - } -} - -static int rk616_codec_register(struct snd_soc_codec *codec, - unsigned int reg) -{ - switch (reg) { - case RK616_RESET: - case RK616_DAC_VOL: - case RK616_ADC_INT_CTL1: - case RK616_ADC_INT_CTL2: - case RK616_DAC_INT_CTL1: - case RK616_DAC_INT_CTL2: - case RK616_CLK_CHPUMP: - case RK616_PGA_AGC_CTL: - case RK616_PWR_ADD1: - case RK616_BST_CTL: - case RK616_DIFFIN_CTL: - case RK616_MIXINL_CTL: - case RK616_MIXINL_VOL1: - case RK616_MIXINL_VOL2: - case RK616_MIXINR_CTL: - case RK616_MIXINR_VOL1: - case RK616_MIXINR_VOL2: - case RK616_PGAL_CTL: - case RK616_PGAR_CTL: - case RK616_PWR_ADD2: - case RK616_DAC_CTL: - case RK616_LINEMIX_CTL: - case RK616_MUXHP_HPMIX_CTL: - case RK616_HPMIX_CTL: - case RK616_HPMIX_VOL1: - case RK616_HPMIX_VOL2: - case RK616_LINEOUT1_CTL: - case RK616_LINEOUT2_CTL: - case RK616_SPKL_CTL: - case RK616_SPKR_CTL: - case RK616_HPL_CTL: - case RK616_HPR_CTL: - case RK616_MICBIAS_CTL: - case RK616_MICKEY_DET_CTL: - case RK616_PWR_ADD3: - case RK616_ADC_CTL: - case RK616_SINGNAL_ZC_CTL1: - case RK616_SINGNAL_ZC_CTL2: - case RK616_PGAL_AGC_CTL1: - case RK616_PGAL_AGC_CTL2: - case RK616_PGAL_AGC_CTL3: - case RK616_PGAL_AGC_CTL4: - case RK616_PGAL_ASR_CTL: - case RK616_PGAL_AGC_MAX_H: - case RK616_PGAL_AGC_MAX_L: - case RK616_PGAL_AGC_MIN_H: - case RK616_PGAL_AGC_MIN_L: - case RK616_PGAL_AGC_CTL5: - case RK616_PGAR_AGC_CTL1: - case RK616_PGAR_AGC_CTL2: - case RK616_PGAR_AGC_CTL3: - case RK616_PGAR_AGC_CTL4: - case RK616_PGAR_ASR_CTL: - case RK616_PGAR_AGC_MAX_H: - case RK616_PGAR_AGC_MAX_L: - case RK616_PGAR_AGC_MIN_H: - case RK616_PGAR_AGC_MIN_L: - case RK616_PGAR_AGC_CTL5: - return 1; - default: - return 0; - } -} - -static inline unsigned int rk616_read_reg_cache(struct snd_soc_codec *codec, - unsigned int reg) -{ - unsigned int *cache = codec->reg_cache; - int i; - - if (rk616_codec_register(codec, reg)) - return cache[reg]; - - if (rk616_mfd_register(reg)) { - for (i = 0; i < RK616_MFD_REG_LEN; i++) { - if (rk616_mfd_reg_cache[i].reg == reg) - return rk616_mfd_reg_cache[i].value; - } - } - - pr_err("%s : reg error!\n", __func__); - - return -EINVAL; -} - -static inline void rk616_write_reg_cache(struct snd_soc_codec *codec, - unsigned int reg, unsigned int value) -{ - unsigned int *cache = codec->reg_cache; - int i; - - if (rk616_codec_register(codec, reg)) { - cache[reg] = value; - return; - } - - if (rk616_mfd_register(reg)) { - for (i = 0; i < RK616_MFD_REG_LEN; i++) { - if (rk616_mfd_reg_cache[i].reg == reg) { - rk616_mfd_reg_cache[i].value = value; - return; - } - } - } - - pr_err("%s : reg error!\n", __func__); -} - -static unsigned int rk616_codec_read(struct snd_soc_codec *codec, - unsigned int reg) -{ - struct mfd_rk616 *rk616 = rk616_mfd; - unsigned int value; - - if (!rk616) { - pr_err("%s : rk616 is NULL\n", __func__); - return -EINVAL; - } - - if (!rk616_mfd_register(reg) && !rk616_codec_register(codec, reg)) { - pr_err("%s : reg error!\n", __func__); - return -EINVAL; - } - - if (rk616_volatile_register(codec, reg) == 0) { - value = rk616_read_reg_cache(codec, reg); - } else { - if (rk616->read_dev(rk616, reg, &value) < 0) { - pr_err("%s : reg = 0x%x failed\n", - __func__, reg); - return -EIO; - } - } - - DBG("%s : reg = 0x%x, val= 0x%x\n", __func__, reg, value); - - return value; -} - -static int rk616_codec_write(struct snd_soc_codec *codec, - unsigned int reg, unsigned int value) -{ - struct mfd_rk616 *rk616 = rk616_mfd; - unsigned int set_bit, read_value, new_value; - int i; - - if (!rk616) { - pr_err("%s : rk616 is NULL\n", __func__); - return -EINVAL; - } else if (!rk616_mfd_register(reg) && - !rk616_codec_register(codec, reg)) { - pr_err("%s : reg error!\n", __func__); - return -EINVAL; - } - - /* set codec mask bit */ - i = rk616_mfd_codec_bit(reg); - if (i >= 0) { - set_bit = rk616_mfd_codec_bit_list[i].value; - read_value = rk616_codec_read(codec, reg); - value = (read_value & ~set_bit) | (value & set_bit); - } else if (rk616_mfd_mask_register(reg)) { - value = ((0xffff0000 & rk616_read_reg_cache(codec, reg)) | - (value & 0x0000ffff)); - } - - new_value = rk616_set_init_value(codec, reg, value); - - /* write i2c */ - if (rk616->write_dev(rk616, reg, &value) < 0) { - pr_err("%s : reg = 0x%x failed\n", - __func__, reg); - return -EIO; - } - - if (new_value != value) { - if (rk616->write_dev(rk616, reg, &new_value) < 0) { - pr_err("%s : reg = 0x%x failed\n", - __func__, reg); - return -EIO; - } - value = new_value; - } - - rk616_write_reg_cache(codec, reg, value); - - DBG("%s : reg = 0x%x, val = 0x%x\n", __func__, reg, value); - return 0; -} - -static int rk616_hw_write(const struct i2c_client *client, - const char *buf, int count) -{ - struct rk616_codec_priv *rk616 = rk616_priv; - struct snd_soc_codec *codec; - unsigned int reg, value; - int ret = -1; - - if (!rk616 || !rk616->codec) { - pr_err("%s : rk616_priv or rk616_priv->codec is NULL\n", - __func__); - return -EINVAL; - } - - codec = rk616->codec; - - if (count == 3) { - reg = (unsigned int)buf[0]; - value = (buf[1] & 0xff00) | (0x00ff & buf[2]); - ret = rk616_codec_write(codec, reg, value); - } else { - pr_err("%s : i2c len error\n", - __func__); - } - - return (ret == 0) ? count : ret; -} - -static int rk616_reset(struct snd_soc_codec *codec) -{ - int i; - - snd_soc_write(codec, RK616_RESET, 0xfc); - mdelay(10); - snd_soc_write(codec, RK616_RESET, 0x43); - mdelay(10); - - for (i = 0; i < RK616_MFD_REG_LEN; i++) - snd_soc_write(codec, rk616_mfd_reg_defaults[i].reg, - rk616_mfd_reg_defaults[i].value); - - memcpy(codec->reg_cache, rk616_reg_defaults, - sizeof(rk616_reg_defaults)); - - /* close charge pump */ - snd_soc_write(codec, RK616_CLK_CHPUMP, 0x41); - - /* bypass zero-crossing detection */ - snd_soc_write(codec, RK616_SINGNAL_ZC_CTL1, 0x3f); - snd_soc_write(codec, RK616_SINGNAL_ZC_CTL2, 0xff); - - /* set ADC Power for MICBIAS */ - snd_soc_update_bits(codec, RK616_PWR_ADD1, - RK616_ADC_PWRD, 0); - - return 0; -} - -static int rk616_set_gpio(int gpio, bool level) -{ - struct rk616_codec_priv *rk616 = rk616_priv; - - if (!rk616) { - pr_err("%s : rk616_priv is NULL\n", - __func__); - return 0; - } - - DBG("%s : set %s %s %s %s ctl gpio %s\n", __func__, - gpio & RK616_CODEC_SET_SPK ? "spk" : "", - gpio & RK616_CODEC_SET_HP ? "hp" : "", - gpio & RK616_CODEC_SET_RCV ? "rcv" : "", - gpio & RK616_CODEC_SET_MIC ? "mic" : "", - level ? "HIGH" : "LOW"); - - if ((gpio & RK616_CODEC_SET_SPK) && rk616 && - rk616->spk_ctl_gpio != INVALID_GPIO) { - gpio_set_value(rk616->spk_ctl_gpio, level); - } - - if ((gpio & RK616_CODEC_SET_HP) && rk616 && - rk616->hp_ctl_gpio != INVALID_GPIO) { - gpio_set_value(rk616->hp_ctl_gpio, level); - } - - if ((gpio & RK616_CODEC_SET_RCV) && rk616 && - rk616->rcv_ctl_gpio != INVALID_GPIO) { - gpio_set_value(rk616->rcv_ctl_gpio, level); - } - - if ((gpio & RK616_CODEC_SET_MIC) && rk616 && - rk616->mic_sel_gpio != INVALID_GPIO) { - gpio_set_value(rk616->mic_sel_gpio, level); - } - - if (gpio & RK616_CODEC_SET_SPK) - mdelay(rk616->spk_amp_delay); - else if (gpio & RK616_CODEC_SET_HP) - mdelay(rk616->hp_mos_delay); - - return 0; -} - -static struct rk616_reg_val_typ playback_power_up_list[] = { - /* DAC DSM, 0x06: x1, 0x26: x1.25, 0x46: x1.5, 0x66: x1.75 */ - {0x804, 0x46}, - {0x868, 0x02}, /* power up */ - {0x86c, 0x0f}, /* DACL/R UN INIT */ - {0x86c, 0x00}, /* DACL/R and DACL/R CLK power up */ - {0x86c, 0x30}, /* DACL/R INIT */ - /* - * Mux HPMIXR from HPMIXR(bit 0), - * Mux HPMIXL from HPMIXL(bit 1), - * HPMIXL/R power up - */ - {0x874, 0x14}, - /* HPMIXL/HPMIXR from DACL/DACR(bit 4, bit 0) */ - {0x878, 0xee}, - {0x88c, 2<<5}, /* power up SPKOUTL (bit 7) */ - {0x890, 2<<5}, /* power up SPKOUTR (bit 7) */ -}; -#define RK616_CODEC_PLAYBACK_POWER_UP_LIST_LEN \ - ARRAY_SIZE(playback_power_up_list) - -static struct rk616_reg_val_typ playback_power_down_list[] = { - {0x890, 0xe0}, /* mute SPKOUTR (bit 5), volume (bit 0-4) */ - {0x88c, 0xe0}, /* mute SPKOUTL (bit 5), volume (bit 0-4) */ - {0x878, 0xff}, /* HPMIXL/HPMIXR from DACL/DACR(bit 4, bit 0) */ - {0x874, 0x3c}, /* Power down HPMIXL/R */ - {0x86c, 0x3f}, /* DACL/R INIT */ - {0x868, 0xff}, /* power down */ -}; -#define RK616_CODEC_PLAYBACK_POWER_DOWN_LIST_LEN \ - ARRAY_SIZE(playback_power_down_list) - -static struct rk616_reg_val_typ capture_power_up_list[] = { - /* - * MIXINL power up and unmute, - * MININL from MICMUX, - * MICMUX from BST_L - */ - {0x848, 0x06}, - {0x84c, 0x3c}, /* MIXINL from MIXMUX volume (bit 3-5) */ - {0x860, 0x00}, /* PGAL power up unmute */ - {0x828, 0x09}, /* Set for Capture pop noise */ - {0x83c, 0x00}, /* power up */ - /* - * BST_L power up, - * unmute, - * and Single-Ended(bit 6), - * volume 0-20dB(bit 5) - */ - {0x840, 0x69}, - {0x8a8, 0x09}, /* ADCL/R power, and clear ADCL/R buf */ - {0x8a8, 0x00}, /* ADCL/R power, and clear ADCL/R buf */ -}; -#define RK616_CODEC_CAPTURE_POWER_UP_LIST_LEN \ - ARRAY_SIZE(capture_power_up_list) - -static struct rk616_reg_val_typ capture_power_down_list[] = { - {0x8a8, 0x3f}, /* ADCL/R power down, and clear ADCL/R buf */ - {0x860, 0xc0}, /* PGAL power down ,mute */ - {0x84c, 0x3c}, /* MIXINL from MIXMUX volume 0dB(bit 3-5) */ - /* - * MIXINL power down and mute, - * MININL No selecting, - * MICMUX from BST_L - */ - {0x848, 0x1f}, - /* - * BST_L power down, - * mute, and Single-Ended(bit 6), - * volume 0(bit 5) - */ - {0x840, 0x99}, - {0x83c, 0x3c}, /* power down */ -}; -#define RK616_CODEC_CAPTURE_POWER_DOWN_LIST_LEN \ - ARRAY_SIZE(capture_power_down_list) - -static int rk616_codec_power_up(int type) -{ - struct rk616_codec_priv *rk616 = rk616_priv; - struct snd_soc_codec *codec; - int i; - - if (!rk616 || !rk616->codec) { - pr_err("%s : rk616_priv or rk616_priv->codec is NULL\n", - __func__); - return -EINVAL; - } - - codec = rk616->codec; - - pr_info("%s : power up %s %s %s\n", __func__, - type & RK616_CODEC_PLAYBACK ? "playback" : "", - type & RK616_CODEC_CAPTURE ? "capture" : "", - type & RK616_CODEC_INCALL ? "incall" : ""); - - /* mute output for pop noise */ - if ((type & RK616_CODEC_PLAYBACK) || - (type & RK616_CODEC_INCALL)) { - rk616_set_gpio(RK616_CODEC_SET_SPK | - RK616_CODEC_SET_HP, GPIO_LOW); - } - - if (type & RK616_CODEC_PLAYBACK) { - for (i = 0; i < RK616_CODEC_PLAYBACK_POWER_UP_LIST_LEN; i++) { - snd_soc_write(codec, playback_power_up_list[i].reg, - playback_power_up_list[i].value); - } - - if (rk616->virtual_gnd) { - snd_soc_write(codec, 0x894, 0); - snd_soc_write(codec, 0x898, 0); - } - - snd_soc_update_bits(codec, RK616_SPKL_CTL, - RK616_VOL_MASK, rk616->spk_volume); - snd_soc_update_bits(codec, RK616_SPKR_CTL, - RK616_VOL_MASK, rk616->spk_volume); - } - - if (type & RK616_CODEC_CAPTURE) { - for (i = 0; i < RK616_CODEC_CAPTURE_POWER_UP_LIST_LEN; i++) { - snd_soc_write(codec, capture_power_up_list[i].reg, - capture_power_up_list[i].value); - } - snd_soc_update_bits(codec, RK616_PGAL_CTL, - RK616_VOL_MASK, rk616->capture_volume); - } - - if (type & RK616_CODEC_INCALL) { - /* set for capture pop noise */ - snd_soc_update_bits(codec, RK616_PGA_AGC_CTL, - 0x0f, 0x09); - if (rk616->modem_input_enable != OFF) { - /* IN3L to MIXINL, unmute IN3L */ - snd_soc_update_bits(codec, RK616_MIXINL_CTL, - RK616_MIL_F_IN3L | RK616_MIL_MUTE | - RK616_MIL_PWRD, - 0); - } else { - /* IN3L to MIXINL */ - snd_soc_update_bits(codec, RK616_MIXINL_CTL, - RK616_MIL_F_IN3L | RK616_MIL_PWRD, - 0); - } - snd_soc_update_bits(codec, RK616_PWR_ADD1, - RK616_ADC_PWRD | RK616_DIFFIN_MIR_PGAR_RLPWRD | - RK616_MIC1_MIC2_MIL_PGAL_RLPWRD | - RK616_ADCL_RLPWRD | RK616_ADCR_RLPWRD, 0); - /* IN3L to MIXINL vol */ - snd_soc_update_bits(codec, RK616_MIXINL_VOL2, - RK616_MIL_F_IN3L_VOL_MASK, 0); - /* PU unmute PGAL,PGAL vol */ - snd_soc_update_bits(codec, RK616_PGAL_CTL, - 0xff, 0x15); - snd_soc_update_bits(codec, RK616_HPMIX_CTL, - RK616_HML_F_PGAL | RK616_HMR_F_PGAL, 0); - /* set min volume for incall voice volume setting */ - snd_soc_update_bits(codec, RK616_SPKL_CTL, - RK616_VOL_MASK, 0); - snd_soc_update_bits(codec, RK616_SPKR_CTL, - RK616_VOL_MASK, 0); - } - - return 0; -} - -static int rk616_codec_power_down(int type) -{ - struct rk616_codec_priv *rk616 = rk616_priv; - struct snd_soc_codec *codec; - int i; - - if (!rk616 || !rk616->codec) { - pr_err("%s : rk616_priv or rk616_priv->codec is NULL\n", - __func__); - return -EINVAL; - } - - codec = rk616->codec; - - pr_info("%s : power down %s %s %s\n", __func__, - type & RK616_CODEC_PLAYBACK ? "playback" : "", - type & RK616_CODEC_CAPTURE ? "capture" : "", - type & RK616_CODEC_INCALL ? "incall" : ""); - - /* mute output for pop noise */ - if ((type & RK616_CODEC_PLAYBACK) || - (type & RK616_CODEC_INCALL)) { - rk616_set_gpio(RK616_CODEC_SET_SPK | RK616_CODEC_SET_HP, - GPIO_LOW); - } - - if (type & RK616_CODEC_CAPTURE) { - for (i = 0; i < RK616_CODEC_CAPTURE_POWER_DOWN_LIST_LEN; i++) { - snd_soc_write(codec, capture_power_down_list[i].reg, - capture_power_down_list[i].value); - } - } - - if (type & RK616_CODEC_PLAYBACK) { - if (rk616->virtual_gnd) { - snd_soc_write(codec, 0x894, 0xe0); - snd_soc_write(codec, 0x898, 0xe0); - } - - for (i = 0; i < RK616_CODEC_PLAYBACK_POWER_DOWN_LIST_LEN; i++) { - snd_soc_write(codec, playback_power_down_list[i].reg, - playback_power_down_list[i].value); - } - } - - if (type & RK616_CODEC_INCALL) { - /* close incall route */ - snd_soc_update_bits(codec, RK616_HPMIX_CTL, - RK616_HML_F_PGAL | RK616_HMR_F_PGAL, - RK616_HML_F_PGAL | RK616_HMR_F_PGAL); - snd_soc_update_bits(codec, RK616_PGA_AGC_CTL, - 0x0f, 0x0c); - snd_soc_update_bits(codec, RK616_MIXINL_CTL, - RK616_MIL_F_IN3L | RK616_MIL_MUTE | RK616_MIL_PWRD, - RK616_MIL_F_IN3L | RK616_MIL_MUTE | RK616_MIL_PWRD); - snd_soc_update_bits(codec, RK616_MIXINL_VOL2, - RK616_MIL_F_IN3L_VOL_MASK, 0); - snd_soc_update_bits(codec, RK616_PGAL_CTL, - 0xff, 0xd5); - } - - return 0; -} -static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -3900, 150, 0); -static const DECLARE_TLV_DB_SCALE(pga_vol_tlv, -1800, 150, 0); -static const DECLARE_TLV_DB_SCALE(bst_vol_tlv, 0, 2000, 0); -static const DECLARE_TLV_DB_SCALE(mix_vol_tlv, -1200, 300, 0); -static const DECLARE_TLV_DB_SCALE(pga_agc_max_vol_tlv, -1350, 600, 0); -static const DECLARE_TLV_DB_SCALE(pga_agc_min_vol_tlv, -1800, 600, 0); - -static const char * const rk616_input_mode[] = { - "Differential", "Single-Ended"}; - -static const char * const rk616_micbias_ratio[] = { - "1.0 Vref", "1.1 Vref", "1.2 Vref", "1.3 Vref", - "1.4 Vref", "1.5 Vref", "1.6 Vref", "1.7 Vref",}; - -static const char * const rk616_dis_en_sel[] = {"Disable", "Enable"}; - -static const char * const rk616_mickey_range[] = { - "100uA", "300uA", "500uA", "700uA", - "900uA", "1100uA", "1300uA", "1500uA"}; - -static const char * const rk616_pga_gain_control[] = {"Normal", "AGC"}; - -static const char * const rk616_pga_agc_way[] = {"Normal", "Jack"}; - -static const char * const rk616_pga_agc_hold_time[] = { - "0ms", "2ms", "4ms", "8ms", "16ms", "32ms", - "64ms", "128ms", "256ms", "512ms", "1s"}; - -static const char * const rk616_pga_agc_ramp_up_time[] = { - "500us", "1ms", "2ms", "4ms", "8ms", "16ms", - "32ms", "64ms", "128ms", "256ms", "512ms"}; - -static const char * const rk616_pga_agc_ramp_down_time[] = { - "Normal:125us Jack:32us", "Normal:250us Jack:64us", - "Normal:500us Jack:125us", "Normal:1ms Jack:250us", - "Normal:2ms Jack:500us", "Normal:4ms Jack:1ms", - "Normal:8ms Jack:2ms", "Normal:16ms Jack:4ms", - "Normal:32ms Jack:8ms", "Normal:64ms Jack:16ms", - "Normal:128ms Jack:32ms"}; - -static const char * const rk616_pga_agc_mode[] = { - "Normal", "Limiter"}; - -static const char * const rk616_pga_agc_recovery_mode[] = { - "Right Now", "After AGC to Limiter"}; - -static const char * const rk616_pga_agc_noise_gate_threhold[] = { - "-39dB", "-45dB", "-51dB", "-57dB", - "-63dB", "-69dB", "-75dB", "-81dB"}; - -static const char * const rk616_pga_agc_update_gain[] = { - "Right Now", "After 1st Zero Cross"}; - -static const char * const rk616_pga_agc_approximate_sample_rate[] = { - "48KHz", "32KHz", "24KHz", "16KHz", "12KHz", "8KHz"}; - -static const char * const rk616_gpio_sel[] = {"Low", "High"}; - -static const struct soc_enum rk616_bst_enum[] = { -SOC_ENUM_SINGLE(RK616_BST_CTL, RK616_BSTL_MODE_SFT, - 2, rk616_input_mode), -SOC_ENUM_SINGLE(RK616_BST_CTL, RK616_BSTR_MODE_SFT, - 2, rk616_input_mode), -}; - -static const struct soc_enum rk616_diffin_enum = - SOC_ENUM_SINGLE(RK616_DIFFIN_CTL, RK616_DIFFIN_MODE_SFT, - 2, rk616_input_mode); - -static const struct soc_enum rk616_micbias_enum[] = { -SOC_ENUM_SINGLE(RK616_MICBIAS_CTL, RK616_MICBIAS1_V_SFT, - 8, rk616_micbias_ratio), -SOC_ENUM_SINGLE(RK616_MICBIAS_CTL, RK616_MICBIAS2_V_SFT, - 8, rk616_micbias_ratio), -}; - -static const struct soc_enum rk616_mickey_enum[] = { -SOC_ENUM_SINGLE(RK616_MICKEY_DET_CTL, RK616_MK1_DET_SFT, - 2, rk616_dis_en_sel), -SOC_ENUM_SINGLE(RK616_MICKEY_DET_CTL, RK616_MK2_DET_SFT, - 2, rk616_dis_en_sel), -SOC_ENUM_SINGLE(RK616_MICKEY_DET_CTL, RK616_MK1_DET_I_SFT, - 8, rk616_mickey_range), -SOC_ENUM_SINGLE(RK616_MICKEY_DET_CTL, RK616_MK2_DET_I_SFT, - 8, rk616_mickey_range), -}; - -static const struct soc_enum rk616_agcl_enum[] = { -SOC_ENUM_SINGLE(RK616_PGA_AGC_CTL, RK616_PGAL_AGC_EN_SFT, - 2, rk616_pga_gain_control),/*0*/ -SOC_ENUM_SINGLE(RK616_PGAL_AGC_CTL1, RK616_PGA_AGC_WAY_SFT, - 2, rk616_pga_agc_way),/*1*/ -SOC_ENUM_SINGLE(RK616_PGAL_AGC_CTL1, RK616_PGA_AGC_HOLD_T_SFT, - 11, rk616_pga_agc_hold_time),/*2*/ -SOC_ENUM_SINGLE(RK616_PGAL_AGC_CTL2, RK616_PGA_AGC_GRU_T_SFT, - 11, rk616_pga_agc_ramp_up_time),/*3*/ -SOC_ENUM_SINGLE(RK616_PGAL_AGC_CTL2, RK616_PGA_AGC_GRD_T_SFT, - 11, rk616_pga_agc_ramp_down_time),/*4*/ -SOC_ENUM_SINGLE(RK616_PGAL_AGC_CTL3, RK616_PGA_AGC_MODE_SFT, - 2, rk616_pga_agc_mode),/*5*/ -SOC_ENUM_SINGLE(RK616_PGAL_AGC_CTL3, RK616_PGA_AGC_ZO_SFT, - 2, rk616_dis_en_sel),/*6*/ -SOC_ENUM_SINGLE(RK616_PGAL_AGC_CTL3, RK616_PGA_AGC_REC_MODE_SFT, - 2, rk616_pga_agc_recovery_mode),/*7*/ -SOC_ENUM_SINGLE(RK616_PGAL_AGC_CTL3, RK616_PGA_AGC_FAST_D_SFT, - 2, rk616_dis_en_sel),/*8*/ -SOC_ENUM_SINGLE(RK616_PGAL_AGC_CTL3, RK616_PGA_AGC_NG_SFT, - 2, rk616_dis_en_sel),/*9*/ -SOC_ENUM_SINGLE(RK616_PGAL_AGC_CTL3, RK616_PGA_AGC_NG_THR_SFT, - 8, rk616_pga_agc_noise_gate_threhold),/*10*/ -SOC_ENUM_SINGLE(RK616_PGAL_AGC_CTL4, RK616_PGA_AGC_ZO_MODE_SFT, - 2, rk616_pga_agc_update_gain),/*11*/ -SOC_ENUM_SINGLE(RK616_PGAL_ASR_CTL, RK616_PGA_SLOW_CLK_SFT, - 2, rk616_dis_en_sel),/*12*/ -SOC_ENUM_SINGLE(RK616_PGAL_ASR_CTL, RK616_PGA_ASR_SFT, - 6, rk616_pga_agc_approximate_sample_rate),/*13*/ -SOC_ENUM_SINGLE(RK616_PGAL_AGC_CTL5, RK616_PGA_AGC_SFT, - 2, rk616_dis_en_sel),/*14*/ -}; - -static const struct soc_enum rk616_agcr_enum[] = { -SOC_ENUM_SINGLE(RK616_PGA_AGC_CTL, RK616_PGAR_AGC_EN_SFT, - 2, rk616_pga_gain_control),/*0*/ -SOC_ENUM_SINGLE(RK616_PGAR_AGC_CTL1, RK616_PGA_AGC_WAY_SFT, - 2, rk616_pga_agc_way),/*1*/ -SOC_ENUM_SINGLE(RK616_PGAR_AGC_CTL1, RK616_PGA_AGC_HOLD_T_SFT, - 11, rk616_pga_agc_hold_time),/*2*/ -SOC_ENUM_SINGLE(RK616_PGAR_AGC_CTL2, RK616_PGA_AGC_GRU_T_SFT, - 11, rk616_pga_agc_ramp_up_time),/*3*/ -SOC_ENUM_SINGLE(RK616_PGAR_AGC_CTL2, RK616_PGA_AGC_GRD_T_SFT, - 11, rk616_pga_agc_ramp_down_time),/*4*/ -SOC_ENUM_SINGLE(RK616_PGAR_AGC_CTL3, RK616_PGA_AGC_MODE_SFT, - 2, rk616_pga_agc_mode),/*5*/ -SOC_ENUM_SINGLE(RK616_PGAR_AGC_CTL3, RK616_PGA_AGC_ZO_SFT, - 2, rk616_dis_en_sel),/*6*/ -SOC_ENUM_SINGLE(RK616_PGAR_AGC_CTL3, RK616_PGA_AGC_REC_MODE_SFT, - 2, rk616_pga_agc_recovery_mode),/*7*/ -SOC_ENUM_SINGLE(RK616_PGAR_AGC_CTL3, RK616_PGA_AGC_FAST_D_SFT, - 2, rk616_dis_en_sel),/*8*/ -SOC_ENUM_SINGLE(RK616_PGAR_AGC_CTL3, RK616_PGA_AGC_NG_SFT, - 2, rk616_dis_en_sel),/*9*/ -SOC_ENUM_SINGLE(RK616_PGAR_AGC_CTL3, RK616_PGA_AGC_NG_THR_SFT, - 8, rk616_pga_agc_noise_gate_threhold),/*10*/ -SOC_ENUM_SINGLE(RK616_PGAR_AGC_CTL4, RK616_PGA_AGC_ZO_MODE_SFT, - 2, rk616_pga_agc_update_gain),/*11*/ -SOC_ENUM_SINGLE(RK616_PGAR_ASR_CTL, RK616_PGA_SLOW_CLK_SFT, - 2, rk616_dis_en_sel),/*12*/ -SOC_ENUM_SINGLE(RK616_PGAR_ASR_CTL, RK616_PGA_ASR_SFT, - 6, rk616_pga_agc_approximate_sample_rate),/*13*/ -SOC_ENUM_SINGLE(RK616_PGAR_AGC_CTL5, RK616_PGA_AGC_SFT, - 2, rk616_dis_en_sel),/*14*/ -}; - -static const struct soc_enum rk616_loop_enum = - SOC_ENUM_SINGLE(CRU_CFGMISC_CON, AD_DA_LOOP_SFT, - 2, rk616_dis_en_sel); - -static const struct soc_enum rk616_gpio_enum[] = { - SOC_ENUM_SINGLE(RK616_CODEC_SET_SPK, 0, 2, rk616_gpio_sel), - SOC_ENUM_SINGLE(RK616_CODEC_SET_HP, 0, 2, rk616_gpio_sel), - SOC_ENUM_SINGLE(RK616_CODEC_SET_RCV, 0, 2, rk616_gpio_sel), - SOC_ENUM_SINGLE(RK616_CODEC_SET_MIC, 0, 2, rk616_gpio_sel), -}; - -int snd_soc_put_pgal_volsw(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct soc_mixer_control *mc = - (struct soc_mixer_control *)kcontrol->private_value; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - unsigned int val; - int max = mc->max; - unsigned int mask = (1 << fls(max)) - 1; - - val = (ucontrol->value.integer.value[0] & mask); - - /* set for capture pop noise */ - if (val) - snd_soc_update_bits(codec, RK616_PGA_AGC_CTL, 0x0f, 0x09); - - return snd_soc_put_volsw(kcontrol, ucontrol); -} - -/* for setting volume pop noise, turn volume step up/down. */ -int snd_soc_put_step_volsw(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct soc_mixer_control *mc = - (struct soc_mixer_control *)kcontrol->private_value; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - unsigned int reg = mc->reg; - unsigned int reg2 = mc->rreg; - unsigned int shift = mc->shift; - int max = mc->max; - unsigned int mask = (1 << fls(max)) - 1; - unsigned int invert = mc->invert; - int err = 0; - unsigned int val, val2, val_mask; - unsigned int old_l, old_r, old_reg_l, old_reg_r, step = 1; - - val_mask = mask << shift; - val = (ucontrol->value.integer.value[0] & mask); - val2 = (ucontrol->value.integer.value[1] & mask); - - old_reg_l = snd_soc_read(codec, reg); - if (old_l < 0) - return old_l; - - old_l = (old_reg_l & val_mask) >> shift; - - old_reg_r = snd_soc_read(codec, reg); - if (old_r < 0) - return old_r; - - old_r = (old_reg_r & val_mask) >> shift; - - old_reg_l &= ~mask; - old_reg_r &= ~mask; - - while (old_l != val || old_r != val2) { - if (old_l != val) { - if (old_l > val) { - old_l -= step; - if (old_l < val) - old_l = val; - } else { - old_l += step; - if (old_l > val) - old_l = val; - } - - if (invert) - old_l = max - old_l; - - old_l = old_l << shift; - - mutex_lock(&codec->mutex); - err = snd_soc_write(codec, reg, old_reg_l | old_l); - mutex_unlock(&codec->mutex); - if (err < 0) - return err; - } - if (old_r != val2) { - if (old_r > val2) { - old_r -= step; - if (old_r < val2) - old_r = val2; - } else { - old_r += step; - if (old_r > val2) - old_r = val2; - } - - if (invert) - old_r = max - old_r; - - old_r = old_r << shift; - - mutex_lock(&codec->mutex); - err = snd_soc_write(codec, reg2, old_reg_r | old_r); - mutex_unlock(&codec->mutex); - if (err < 0) - return err; - } - } - return err; -} - -static int snd_soc_get_gpio_enum_double(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - struct rk616_codec_priv *rk616 = rk616_priv; - - if (!rk616) { - pr_err("%s : rk616_priv is NULL\n", __func__); - return -EINVAL; - } - - switch (e->reg) { - case RK616_CODEC_SET_SPK: - ucontrol->value.enumerated.item[0] = rk616->spk_gpio_level; - break; - case RK616_CODEC_SET_HP: - ucontrol->value.enumerated.item[0] = rk616->hp_gpio_level; - break; - case RK616_CODEC_SET_RCV: - ucontrol->value.enumerated.item[0] = rk616->rcv_gpio_level; - break; - case RK616_CODEC_SET_MIC: - ucontrol->value.enumerated.item[0] = rk616->mic_gpio_level; - break; - default: - return -EINVAL; - } - return 0; -} - -static int snd_soc_put_gpio_enum_double(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - struct rk616_codec_priv *rk616 = rk616_priv; - - if (!rk616) { - pr_err("%s : rk616_priv is NULL\n", - __func__); - return -EINVAL; - } - - if (ucontrol->value.enumerated.item[0] > e->max - 1) - return -EINVAL; - - /* - * The gpio of SPK HP and RCV will be setting - * in digital_mute for pop noise. - */ - switch (e->reg) { - case RK616_CODEC_SET_SPK: - rk616->spk_gpio_level = ucontrol->value.enumerated.item[0]; - break; - case RK616_CODEC_SET_HP: - rk616->hp_gpio_level = ucontrol->value.enumerated.item[0]; - break; - case RK616_CODEC_SET_RCV: - rk616->rcv_gpio_level = ucontrol->value.enumerated.item[0]; - break; - case RK616_CODEC_SET_MIC: - rk616->mic_gpio_level = ucontrol->value.enumerated.item[0]; - return rk616_set_gpio(e->reg, - ucontrol->value.enumerated.item[0]); - default: - return -EINVAL; - } - - return 0; -} - -#define SOC_DOUBLE_R_STEP_TLV(xname, reg_left, reg_right, \ - xshift, xmax, xinvert, tlv_array) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ - .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ - SNDRV_CTL_ELEM_ACCESS_READWRITE,\ - .tlv.p = (tlv_array), \ - .info = snd_soc_info_volsw, \ - .get = snd_soc_get_volsw, .put = snd_soc_put_step_volsw, \ - .private_value = (unsigned long)&(struct soc_mixer_control) \ - {.reg = reg_left, .rreg = reg_right, .shift = xshift, \ - .max = xmax, .platform_max = xmax, .invert = xinvert} } - -#define SOC_GPIO_ENUM(xname, xenum) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,\ - .info = snd_soc_info_enum_double, \ - .get = snd_soc_get_gpio_enum_double, \ - .put = snd_soc_put_gpio_enum_double, \ - .private_value = (unsigned long)&xenum } - -static struct snd_kcontrol_new rk616_snd_controls[] = { - - /* add for incall volume setting */ - SOC_DOUBLE_R_STEP_TLV("Speaker Playback Volume", RK616_SPKL_CTL, - RK616_SPKR_CTL, RK616_VOL_SFT, 31, 0, out_vol_tlv), - SOC_DOUBLE_R_STEP_TLV("Headphone Playback Volume", RK616_HPL_CTL, - RK616_HPR_CTL, RK616_VOL_SFT, 31, 0, out_vol_tlv), - SOC_DOUBLE_R_STEP_TLV("Earpiece Playback Volume", RK616_SPKL_CTL, - RK616_SPKR_CTL, RK616_VOL_SFT, 31, 0, out_vol_tlv), - - SOC_DOUBLE_R("Speaker Playback Switch", RK616_SPKL_CTL, - RK616_SPKR_CTL, RK616_MUTE_SFT, 1, 1), - - SOC_DOUBLE_R("Headphone Playback Switch", RK616_HPL_CTL, - RK616_HPR_CTL, RK616_MUTE_SFT, 1, 1), - - SOC_DOUBLE_R("Earpiece Playback Switch", RK616_HPL_CTL, - RK616_HPR_CTL, RK616_MUTE_SFT, 1, 1), - - SOC_SINGLE_TLV("LINEOUT1 Playback Volume", RK616_LINEOUT1_CTL, - RK616_LINEOUT_VOL_SFT, 31, 0, out_vol_tlv), - SOC_SINGLE("LINEOUT1 Playback Switch", RK616_LINEOUT1_CTL, - RK616_LINEOUT_MUTE_SFT, 1, 1), - SOC_SINGLE_TLV("LINEOUT2 Playback Volume", RK616_LINEOUT2_CTL, - RK616_LINEOUT_VOL_SFT, 31, 0, out_vol_tlv), - SOC_SINGLE("LINEOUT2 Playback Switch", RK616_LINEOUT2_CTL, - RK616_LINEOUT_MUTE_SFT, 1, 1), - - /* 0x0a bit 5 is 0 */ - SOC_SINGLE_TLV("PGAL Capture Volume", RK616_PGAL_CTL, - RK616_PGA_VOL_SFT, 31, 0, pga_vol_tlv), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "PGAL Capture Switch", - .info = snd_soc_info_volsw, .get = snd_soc_get_volsw, - .put = snd_soc_put_pgal_volsw, - .private_value = SOC_SINGLE_VALUE(RK616_PGAL_CTL, - RK616_PGA_MUTE_SFT, 1, 1) - }, - /* 0x0a bit 4 is 0 */ - SOC_SINGLE_TLV("PGAR Capture Volume", RK616_PGAR_CTL, - RK616_PGA_VOL_SFT, 31, 0, pga_vol_tlv), - SOC_SINGLE("PGAR Capture Switch", RK616_PGAR_CTL, - RK616_PGA_MUTE_SFT, 1, 1), - - SOC_SINGLE_TLV("DIFFIN Capture Volume", RK616_DIFFIN_CTL, - RK616_DIFFIN_GAIN_SFT, 1, 0, bst_vol_tlv), - SOC_SINGLE("DIFFIN Capture Switch", RK616_DIFFIN_CTL, - RK616_DIFFIN_MUTE_SFT, 1, 1), - - /* Add for set capture mute */ - SOC_SINGLE_TLV("Main Mic Capture Volume", RK616_BST_CTL, - RK616_BSTL_GAIN_SFT, 1, 0, bst_vol_tlv), - SOC_SINGLE("Main Mic Capture Switch", RK616_BST_CTL, - RK616_BSTL_MUTE_SFT, 1, 1), - SOC_SINGLE_TLV("Headset Mic Capture Volume", RK616_BST_CTL, - RK616_BSTR_GAIN_SFT, 1, 0, bst_vol_tlv), - SOC_SINGLE("Headset Mic Capture Switch", RK616_BST_CTL, - RK616_BSTR_MUTE_SFT, 1, 1), - - SOC_ENUM("BST_L Mode", rk616_bst_enum[0]), - SOC_ENUM("BST_R Mode", rk616_bst_enum[1]), - SOC_ENUM("DIFFIN Mode", rk616_diffin_enum), - - SOC_SINGLE_TLV("MUXMIC to MIXINL Volume", RK616_MIXINL_VOL1, - RK616_MIL_F_MUX_VOL_SFT, 7, 0, mix_vol_tlv), - SOC_SINGLE_TLV("IN1P to MIXINL Volume", RK616_MIXINL_VOL1, - RK616_MIL_F_IN1P_VOL_SFT, 7, 0, mix_vol_tlv), - SOC_SINGLE_TLV("IN3L to MIXINL Volume", RK616_MIXINL_VOL2, - RK616_MIL_F_IN3L_VOL_SFT, 7, 0, mix_vol_tlv), - - SOC_SINGLE_TLV("MIXINR MUX to MIXINR Volume", RK616_MIXINR_VOL1, - RK616_MIR_F_MIRM_VOL_SFT, 7, 0, mix_vol_tlv), - SOC_SINGLE_TLV("IN3R to MIXINR Volume", RK616_MIXINR_VOL1, - RK616_MIR_F_IN3R_VOL_SFT, 7, 0, mix_vol_tlv), - SOC_SINGLE_TLV("MIC2N to MIXINR Volume", RK616_MIXINR_VOL2, - RK616_MIR_F_MIC2N_VOL_SFT, 7, 0, mix_vol_tlv), - SOC_SINGLE_TLV("IN1P to MIXINR Volume", RK616_MIXINR_VOL2, - RK616_MIR_F_IN1P_VOL_SFT, 7, 0, mix_vol_tlv), - - SOC_SINGLE("MIXINL Switch", RK616_MIXINL_CTL, - RK616_MIL_MUTE_SFT, 1, 1), - SOC_SINGLE("MIXINR Switch", RK616_MIXINR_CTL, - RK616_MIR_MUTE_SFT, 1, 1), - - SOC_SINGLE_TLV("IN1P to HPMIXL Volume", RK616_HPMIX_VOL1, - RK616_HML_F_IN1P_VOL_SFT, 7, 0, mix_vol_tlv), - SOC_SINGLE_TLV("HPMIX MUX to HPMIXL Volume", RK616_HPMIX_VOL2, - RK616_HML_F_HMM_VOL_SFT, 7, 0, mix_vol_tlv), - SOC_SINGLE_TLV("HPMIX MUX to HPMIXR Volume", RK616_HPMIX_VOL2, - RK616_HMR_F_HMM_VOL_SFT, 7, 0, mix_vol_tlv), - - SOC_ENUM("Micbias1 Voltage", rk616_micbias_enum[0]), - SOC_ENUM("Micbias2 Voltage", rk616_micbias_enum[1]), - - SOC_ENUM("MIC1 Key Detection Enable", rk616_mickey_enum[0]), - SOC_ENUM("MIC2 Key Detection Enable", rk616_mickey_enum[1]), - SOC_ENUM("MIC1 Key Range", rk616_mickey_enum[2]), - SOC_ENUM("MIC2 Key Range", rk616_mickey_enum[3]), - - SOC_ENUM("PGAL Gain Control", rk616_agcl_enum[0]), - SOC_ENUM("PGAL AGC Way", rk616_agcl_enum[1]), - SOC_ENUM("PGAL AGC Hold Time", rk616_agcl_enum[2]), - SOC_ENUM("PGAL AGC Ramp Up Time", rk616_agcl_enum[3]), - SOC_ENUM("PGAL AGC Ramp Down Time", rk616_agcl_enum[4]), - SOC_ENUM("PGAL AGC Mode", rk616_agcl_enum[5]), - SOC_ENUM("PGAL AGC Gain Update Zero Enable", rk616_agcl_enum[6]), - SOC_ENUM("PGAL AGC Gain Recovery LPGA VOL", rk616_agcl_enum[7]), - SOC_ENUM("PGAL AGC Fast Decrement Enable", rk616_agcl_enum[8]), - SOC_ENUM("PGAL AGC Noise Gate Enable", rk616_agcl_enum[9]), - SOC_ENUM("PGAL AGC Noise Gate Threhold", rk616_agcl_enum[10]), - SOC_ENUM("PGAL AGC Upate Gain", rk616_agcl_enum[11]), - SOC_ENUM("PGAL AGC Slow Clock Enable", rk616_agcl_enum[12]), - SOC_ENUM("PGAL AGC Approximate Sample Rate", rk616_agcl_enum[13]), - SOC_ENUM("PGAL AGC Enable", rk616_agcl_enum[14]), - - /* AGC disable and 0x0a bit 5 is 1 */ - SOC_SINGLE_TLV("PGAL AGC Volume", RK616_PGAL_AGC_CTL4, - RK616_PGA_AGC_VOL_SFT, 31, 0, pga_vol_tlv), - - SOC_SINGLE("PGAL AGC Max Level High 8 Bits", RK616_PGAL_AGC_MAX_H, - 0, 255, 0), - SOC_SINGLE("PGAL AGC Max Level Low 8 Bits", RK616_PGAL_AGC_MAX_L, - 0, 255, 0), - SOC_SINGLE("PGAL AGC Min Level High 8 Bits", RK616_PGAL_AGC_MIN_H, - 0, 255, 0), - SOC_SINGLE("PGAL AGC Min Level Low 8 Bits", RK616_PGAL_AGC_MIN_L, - 0, 255, 0), - - /* AGC enable and 0x0a bit 5 is 1 */ - SOC_SINGLE_TLV("PGAL AGC Max Gain", RK616_PGAL_AGC_CTL5, - RK616_PGA_AGC_MAX_G_SFT, 7, 0, pga_agc_max_vol_tlv), - /* AGC enable and 0x0a bit 5 is 1 */ - SOC_SINGLE_TLV("PGAL AGC Min Gain", RK616_PGAL_AGC_CTL5, - RK616_PGA_AGC_MIN_G_SFT, 7, 0, pga_agc_min_vol_tlv), - - SOC_ENUM("PGAR Gain Control", rk616_agcr_enum[0]), - SOC_ENUM("PGAR AGC Way", rk616_agcr_enum[1]), - SOC_ENUM("PGAR AGC Hold Time", rk616_agcr_enum[2]), - SOC_ENUM("PGAR AGC Ramp Up Time", rk616_agcr_enum[3]), - SOC_ENUM("PGAR AGC Ramp Down Time", rk616_agcr_enum[4]), - SOC_ENUM("PGAR AGC Mode", rk616_agcr_enum[5]), - SOC_ENUM("PGAR AGC Gain Update Zero Enable", rk616_agcr_enum[6]), - SOC_ENUM("PGAR AGC Gain Recovery LPGA VOL", rk616_agcr_enum[7]), - SOC_ENUM("PGAR AGC Fast Decrement Enable", rk616_agcr_enum[8]), - SOC_ENUM("PGAR AGC Noise Gate Enable", rk616_agcr_enum[9]), - SOC_ENUM("PGAR AGC Noise Gate Threhold", rk616_agcr_enum[10]), - SOC_ENUM("PGAR AGC Upate Gain", rk616_agcr_enum[11]), - SOC_ENUM("PGAR AGC Slow Clock Enable", rk616_agcr_enum[12]), - SOC_ENUM("PGAR AGC Approximate Sample Rate", rk616_agcr_enum[13]), - SOC_ENUM("PGAR AGC Enable", rk616_agcr_enum[14]), - - /* AGC disable and 0x0a bit 4 is 1 */ - SOC_SINGLE_TLV("PGAR AGC Volume", RK616_PGAR_AGC_CTL4, - RK616_PGA_AGC_VOL_SFT, 31, 0, pga_vol_tlv), - - SOC_SINGLE("PGAR AGC Max Level High 8 Bits", RK616_PGAR_AGC_MAX_H, - 0, 255, 0), - SOC_SINGLE("PGAR AGC Max Level Low 8 Bits", RK616_PGAR_AGC_MAX_L, - 0, 255, 0), - SOC_SINGLE("PGAR AGC Min Level High 8 Bits", RK616_PGAR_AGC_MIN_H, - 0, 255, 0), - SOC_SINGLE("PGAR AGC Min Level Low 8 Bits", RK616_PGAR_AGC_MIN_L, - 0, 255, 0), - - /* AGC enable and 0x06 bit 4 is 1 */ - SOC_SINGLE_TLV("PGAR AGC Max Gain", RK616_PGAR_AGC_CTL5, - RK616_PGA_AGC_MAX_G_SFT, 7, 0, pga_agc_max_vol_tlv), - /* AGC enable and 0x06 bit 4 is 1 */ - SOC_SINGLE_TLV("PGAR AGC Min Gain", RK616_PGAR_AGC_CTL5, - RK616_PGA_AGC_MIN_G_SFT, 7, 0, pga_agc_min_vol_tlv), - - SOC_ENUM("I2S Loop Enable", rk616_loop_enum), - - SOC_GPIO_ENUM("SPK GPIO Control", rk616_gpio_enum[0]), - SOC_GPIO_ENUM("HP GPIO Control", rk616_gpio_enum[1]), - SOC_GPIO_ENUM("RCV GPIO Control", rk616_gpio_enum[2]), - SOC_GPIO_ENUM("MIC GPIO Control", rk616_gpio_enum[3]), -}; - -/* For tiny alsa playback/capture/voice call path */ -static const char * const rk616_playback_path_mode[] = { - "OFF", "RCV", "SPK", "HP", "HP_NO_MIC", "BT", "SPK_HP", /* 0-6 */ - "RING_SPK", "RING_HP", "RING_HP_NO_MIC", "RING_SPK_HP"}; /* 7-10 */ - -static const char * const rk616_capture_path_mode[] = { - "MIC OFF", "Main Mic", "Hands Free Mic", "BT Sco Mic"}; - -static const char * const rk616_call_path_mode[] = { - "OFF", "RCV", "SPK", "HP", "HP_NO_MIC", "BT"}; /* 0-5 */ - -static const char * const rk616_modem_input_mode[] = {"OFF", "ON"}; - -static const SOC_ENUM_SINGLE_DECL(rk616_playback_path_type, - 0, 0, rk616_playback_path_mode); - -static const SOC_ENUM_SINGLE_DECL(rk616_capture_path_type, - 0, 0, rk616_capture_path_mode); - -static const SOC_ENUM_SINGLE_DECL(rk616_call_path_type, - 0, 0, rk616_call_path_mode); - -static const SOC_ENUM_SINGLE_DECL(rk616_modem_input_type, - 0, 0, rk616_modem_input_mode); - -static int rk616_playback_path_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct rk616_codec_priv *rk616 = rk616_priv; - - if (!rk616) { - pr_err("%s : rk616_priv is NULL\n", - __func__); - return -EINVAL; - } - - DBG("%s : playback_path %ld\n", __func__, rk616->playback_path); - - ucontrol->value.integer.value[0] = rk616->playback_path; - - return 0; -} - -static int rk616_playback_path_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct rk616_codec_priv *rk616 = rk616_priv; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - long int pre_path; - - if (!rk616) { - pr_err("%s : rk616_priv is NULL\n", - __func__); - return -EINVAL; - } - - if (rk616->playback_path == ucontrol->value.integer.value[0]) { - DBG("%s : playback_path is not changed!\n", - __func__); - return 0; - } - - pre_path = rk616->playback_path; - rk616->playback_path = ucontrol->value.integer.value[0]; - - DBG("%s : set playback_path %ld, pre_path %ld\n", - __func__, rk616->playback_path, pre_path); - - switch (rk616->playback_path) { - case OFF: - if (pre_path != OFF) - rk616_codec_power_down(RK616_CODEC_PLAYBACK); - break; - case RCV: - case SPK_PATH: - case RING_SPK: - rk616_set_gpio(RK616_CODEC_SET_HP, GPIO_LOW); - - if (pre_path == OFF) - rk616_codec_power_up(RK616_CODEC_PLAYBACK); - - snd_soc_update_bits(codec, RK616_SPKL_CTL, - RK616_VOL_MASK, rk616->spk_volume); - snd_soc_update_bits(codec, RK616_SPKR_CTL, - RK616_VOL_MASK, rk616->spk_volume); - - rk616_set_gpio(RK616_CODEC_SET_SPK, GPIO_HIGH); - break; - case HP_PATH: - case HP_NO_MIC: - case RING_HP: - case RING_HP_NO_MIC: - rk616_set_gpio(RK616_CODEC_SET_SPK, GPIO_LOW); - - if (pre_path == OFF) - rk616_codec_power_up(RK616_CODEC_PLAYBACK); - - snd_soc_update_bits(codec, RK616_SPKL_CTL, - RK616_VOL_MASK, rk616->hp_volume); - snd_soc_update_bits(codec, RK616_SPKR_CTL, - RK616_VOL_MASK, rk616->hp_volume); - - rk616_set_gpio(RK616_CODEC_SET_HP, GPIO_HIGH); - break; - case BT: - break; - case SPK_HP: - case RING_SPK_HP: - if (pre_path == OFF) - rk616_codec_power_up(RK616_CODEC_PLAYBACK); - - snd_soc_update_bits(codec, RK616_SPKL_CTL, - RK616_VOL_MASK, rk616->hp_volume); - snd_soc_update_bits(codec, RK616_SPKR_CTL, - RK616_VOL_MASK, rk616->hp_volume); - - rk616_set_gpio(RK616_CODEC_SET_SPK | RK616_CODEC_SET_HP, - GPIO_HIGH); - break; - default: - return -EINVAL; - } - - return 0; -} - -static int rk616_capture_path_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct rk616_codec_priv *rk616 = rk616_priv; - - if (!rk616) { - pr_err("%s : rk616_priv is NULL\n", - __func__); - return -EINVAL; - } - - DBG("%s : capture_path %ld\n", __func__, - rk616->capture_path); - - ucontrol->value.integer.value[0] = rk616->capture_path; - - return 0; -} - -static int rk616_capture_path_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct rk616_codec_priv *rk616 = rk616_priv; - long int pre_path; - - if (!rk616) { - pr_err("%s : rk616_priv is NULL\n", - __func__); - return -EINVAL; - } - - if (rk616->capture_path == ucontrol->value.integer.value[0]) { - DBG("%s : capture_path is not changed!\n", - __func__); - return 0; - } - - pre_path = rk616->capture_path; - rk616->capture_path = ucontrol->value.integer.value[0]; - - DBG("%s : set capture_path %ld, pre_path %ld\n", __func__, - rk616->capture_path, pre_path); - - switch (rk616->capture_path) { - case MIC_OFF: - if (pre_path != MIC_OFF) - rk616_codec_power_down(RK616_CODEC_CAPTURE); - - if (rk616->hpmic_from_mic2in) - snd_soc_update_bits(codec, RK616_MICBIAS_CTL, - RK616_MICBIAS1_PWRD | RK616_MICBIAS1_V_MASK, - RK616_MICBIAS1_PWRD); - - break; - case MAIN_MIC: - if (pre_path == MIC_OFF) - rk616_codec_power_up(RK616_CODEC_CAPTURE); - - if (rk616->hpmic_from_linein) - snd_soc_write(codec, 0x848, 0x06); - - if (rk616->hpmic_from_mic2in) { - snd_soc_write(codec, 0x848, 0x06); - snd_soc_write(codec, 0x840, 0x69); - snd_soc_update_bits(codec, RK616_MICBIAS_CTL, - RK616_MICBIAS1_PWRD | RK616_MICBIAS1_V_MASK, - RK616_MICBIAS1_V_1_7); - } - rk616_set_gpio(RK616_CODEC_SET_MIC, GPIO_HIGH); - break; - case HANDS_FREE_MIC: - if (pre_path == MIC_OFF) - rk616_codec_power_up(RK616_CODEC_CAPTURE); - - if (rk616->hpmic_from_linein) - snd_soc_write(codec, 0x848, 0x03); - - if (rk616->hpmic_from_mic2in) { - snd_soc_write(codec, 0x848, 0x26); - snd_soc_write(codec, 0x840, 0x96); - snd_soc_update_bits(codec, RK616_MICBIAS_CTL, - RK616_MICBIAS1_PWRD | RK616_MICBIAS1_V_MASK, - RK616_MICBIAS1_PWRD); - } - rk616_set_gpio(RK616_CODEC_SET_MIC, GPIO_LOW); - break; - case BT_SCO_MIC: - break; - default: - return -EINVAL; - } - - return 0; -} - -static int rk616_voice_call_path_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct rk616_codec_priv *rk616 = rk616_priv; - - if (!rk616) { - pr_err("%s : rk616_priv is NULL\n", - __func__); - return -EINVAL; - } - - DBG("%s : voice_call_path %ld\n", __func__, - rk616->voice_call_path); - - ucontrol->value.integer.value[0] = rk616->voice_call_path; - - return 0; -} - -static int rk616_voice_call_path_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct rk616_codec_priv *rk616 = rk616_priv; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - long int pre_path; - - if (!rk616) { - pr_err("%s : rk616_priv is NULL\n", - __func__); - return -EINVAL; - } - - if (rk616->voice_call_path == ucontrol->value.integer.value[0]) { - DBG("%s : voice_call_path is not changed!\n", - __func__); - return 0; - } - - pre_path = rk616->voice_call_path; - rk616->voice_call_path = ucontrol->value.integer.value[0]; - - DBG("%s : set voice_call_path %ld, pre_path %ld\n", - __func__, rk616->voice_call_path, pre_path); - - /* open playback route for incall route and keytone */ - if (pre_path == OFF && rk616->playback_path == OFF) - rk616_codec_power_up(RK616_CODEC_PLAYBACK); - - switch (rk616->voice_call_path) { - case OFF: - if (pre_path != RCV && - pre_path != BT) - rk616_codec_power_down(RK616_CODEC_INCALL); - - - if (pre_path == SPK_PATH) - rk616_set_gpio(RK616_CODEC_SET_SPK, GPIO_HIGH); - else if (pre_path == HP_PATH || pre_path == HP_NO_MIC) - rk616_set_gpio(RK616_CODEC_SET_HP, GPIO_HIGH); - - break; - case RCV: - /* set mic for modem */ - rk616_set_gpio(RK616_CODEC_SET_MIC, GPIO_HIGH); - - /* rcv is controled by modem, so close incall route */ - if (pre_path != OFF && - pre_path != BT) - rk616_codec_power_down(RK616_CODEC_INCALL); - - /* open spk for key tone */ - rk616_set_gpio(RK616_CODEC_SET_SPK, GPIO_HIGH); - break; - case SPK_PATH: - /* set mic for modem */ - rk616_set_gpio(RK616_CODEC_SET_MIC, GPIO_HIGH); - - /* open incall route */ - if (pre_path == OFF || - pre_path == RCV || - pre_path == BT) { - rk616_codec_power_up(RK616_CODEC_INCALL); - } else { - rk616_set_gpio(RK616_CODEC_SET_HP, GPIO_LOW); - - /* set min volume for incall voice volume setting */ - snd_soc_update_bits(codec, RK616_SPKL_CTL, - RK616_VOL_MASK, 0); - snd_soc_update_bits(codec, RK616_SPKR_CTL, - RK616_VOL_MASK, 0); - } - - rk616_set_gpio(RK616_CODEC_SET_SPK, GPIO_HIGH); - break; - case HP_PATH: - /* set mic for modem */ - rk616_set_gpio(RK616_CODEC_SET_MIC, GPIO_LOW); - - /* open incall route */ - if (pre_path == OFF || - pre_path == RCV || - pre_path == BT) { - rk616_codec_power_up(RK616_CODEC_INCALL); - } else { - rk616_set_gpio(RK616_CODEC_SET_SPK, GPIO_LOW); - - /* set min volume for incall voice volume setting */ - snd_soc_update_bits(codec, RK616_SPKL_CTL, - RK616_VOL_MASK, 0); - snd_soc_update_bits(codec, RK616_SPKR_CTL, - RK616_VOL_MASK, 0); - } - - rk616_set_gpio(RK616_CODEC_SET_HP, GPIO_HIGH); - break; - case HP_NO_MIC: - /* set mic for modem */ - rk616_set_gpio(RK616_CODEC_SET_MIC, GPIO_HIGH); - - /* open incall route */ - if (pre_path == OFF || - pre_path == RCV || - pre_path == BT) - rk616_codec_power_up(RK616_CODEC_INCALL); - else { - rk616_set_gpio(RK616_CODEC_SET_SPK, GPIO_LOW); - - /* set min volume for incall voice volume setting */ - snd_soc_update_bits(codec, RK616_SPKL_CTL, - RK616_VOL_MASK, 0); /* volume (bit 0-4) */ - snd_soc_update_bits(codec, RK616_SPKR_CTL, - RK616_VOL_MASK, 0); - } - - rk616_set_gpio(RK616_CODEC_SET_HP, GPIO_HIGH); - break; - case BT: - /* BT is controled by modem, so close incall route */ - if (pre_path != OFF && - pre_path != RCV) { - rk616_codec_power_down(RK616_CODEC_INCALL); - } - - /* open spk for key tone */ - rk616_set_gpio(RK616_CODEC_SET_SPK, GPIO_HIGH); - break; - default: - return -EINVAL; - } - - return 0; -} - -static int rk616_voip_path_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct rk616_codec_priv *rk616 = rk616_priv; - - if (!rk616) { - pr_err("%s : rk616_priv is NULL\n", - __func__); - return -EINVAL; - } - - DBG("%s : voip_path %ld\n", __func__, - rk616->voip_path); - - ucontrol->value.integer.value[0] = rk616->voip_path; - - return 0; -} - -static int rk616_voip_path_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct rk616_codec_priv *rk616 = rk616_priv; - long int pre_path; - - if (!rk616) { - pr_err("%s : rk616_priv is NULL\n", - __func__); - return -EINVAL; - } - - if (rk616->voip_path == ucontrol->value.integer.value[0]) { - DBG("%s : voip_path is not changed!\n", __func__); - return 0; - } - - pre_path = rk616->voip_path; - rk616->voip_path = ucontrol->value.integer.value[0]; - - DBG("%s : set voip_path %ld, pre_path %ld\n", - __func__, rk616->voip_path, pre_path); - - switch (rk616->voip_path) { - case OFF: - break; - case RCV: - case SPK_PATH: - rk616_set_gpio(RK616_CODEC_SET_MIC, GPIO_HIGH); - - if (pre_path == OFF) { - if (rk616->playback_path == OFF) - rk616_codec_power_up(RK616_CODEC_PLAYBACK); - else - rk616_set_gpio(RK616_CODEC_SET_HP, GPIO_LOW); - - if (rk616->capture_path == OFF) - rk616_codec_power_up(RK616_CODEC_CAPTURE); - } else - rk616_set_gpio(RK616_CODEC_SET_HP, GPIO_LOW); - - rk616_set_gpio(RK616_CODEC_SET_SPK, GPIO_HIGH); - break; - case HP_PATH: - rk616_set_gpio(RK616_CODEC_SET_MIC, GPIO_LOW); - - if (pre_path == OFF) { - if (rk616->playback_path == OFF) - rk616_codec_power_up(RK616_CODEC_PLAYBACK); - else - rk616_set_gpio(RK616_CODEC_SET_SPK, GPIO_LOW); - - if (rk616->capture_path == OFF) - rk616_codec_power_up(RK616_CODEC_CAPTURE); - } else - rk616_set_gpio(RK616_CODEC_SET_SPK, GPIO_LOW); - - rk616_set_gpio(RK616_CODEC_SET_HP, GPIO_HIGH); - break; - case HP_NO_MIC: - rk616_set_gpio(RK616_CODEC_SET_MIC, GPIO_HIGH); - - if (pre_path == OFF) { - if (rk616->playback_path == OFF) - rk616_codec_power_up(RK616_CODEC_PLAYBACK); - else - rk616_set_gpio(RK616_CODEC_SET_SPK, GPIO_LOW); - - if (rk616->capture_path == OFF) - rk616_codec_power_up(RK616_CODEC_CAPTURE); - } else - rk616_set_gpio(RK616_CODEC_SET_SPK, GPIO_LOW); - - rk616_set_gpio(RK616_CODEC_SET_HP, GPIO_HIGH); - break; - case BT: - break; - default: - return -EINVAL; - } - - return 0; -} - -static int rk616_modem_input_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct rk616_codec_priv *rk616 = rk616_priv; - - if (!rk616) { - pr_err("%s : rk616_priv is NULL\n", - __func__); - return -EINVAL; - } - - DBG("%s : modem_input_enable %ld\n", __func__, - rk616->modem_input_enable); - - ucontrol->value.integer.value[0] = rk616->modem_input_enable; - - return 0; -} - -static int rk616_modem_input_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct rk616_codec_priv *rk616 = rk616_priv; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - int set_gpio = 0; - - if (!rk616) { - pr_err("%s : rk616_priv is NULL\n", - __func__); - return -EINVAL; - } - - if (rk616->modem_input_enable == ucontrol->value.integer.value[0]) { - DBG("%s : modem_input_enable: %ld is not changed!\n", - __func__, rk616->modem_input_enable); - return 0; - } - - rk616->modem_input_enable = ucontrol->value.integer.value[0]; - - DBG("%s : modem_input_enable %ld\n", __func__, - rk616->modem_input_enable); - - switch (rk616->voice_call_path) { - case OFF: - break; - case RCV: - case SPK_PATH: - case BT: - set_gpio = RK616_CODEC_SET_SPK; - break; - case HP_PATH: - case HP_NO_MIC: - set_gpio = RK616_CODEC_SET_HP; - break; - default: - return -EINVAL; - } - - if (rk616->modem_input_enable == OFF) { - if (set_gpio != 0) - rk616_set_gpio(set_gpio, GPIO_LOW); - - snd_soc_update_bits(codec, RK616_MIXINL_CTL, - RK616_MIL_MUTE, RK616_MIL_MUTE); - - if (set_gpio != 0) - rk616_set_gpio(set_gpio, GPIO_HIGH); - } else { - if (set_gpio != 0) - rk616_set_gpio(set_gpio, GPIO_LOW); - - snd_soc_update_bits(codec, RK616_MIXINL_CTL, - RK616_MIL_MUTE, 0); - - if (set_gpio != 0) - rk616_set_gpio(set_gpio, GPIO_HIGH); - } - - return 0; -} - -static struct snd_kcontrol_new rk616_snd_path_controls[] = { - SOC_ENUM_EXT("Playback Path", rk616_playback_path_type, - rk616_playback_path_get, rk616_playback_path_put), - - SOC_ENUM_EXT("Capture MIC Path", rk616_capture_path_type, - rk616_capture_path_get, rk616_capture_path_put), - - SOC_ENUM_EXT("Voice Call Path", rk616_call_path_type, - rk616_voice_call_path_get, rk616_voice_call_path_put), - - SOC_ENUM_EXT("Voip Path", rk616_call_path_type, - rk616_voip_path_get, rk616_voip_path_put), - - /* add for incall volume setting */ - SOC_DOUBLE_R_STEP_TLV("Speaker Playback Volume", RK616_SPKL_CTL, - RK616_SPKR_CTL, RK616_VOL_SFT, 31, 0, out_vol_tlv), - SOC_DOUBLE_R_STEP_TLV("Headphone Playback Volume", RK616_SPKL_CTL, - RK616_SPKR_CTL, RK616_VOL_SFT, 31, 0, out_vol_tlv), - /* Earpiece incall volume is setting by modem */ - /* - * SOC_DOUBLE_R_STEP_TLV("Earpiece Playback Volume", RK616_SPKL_CTL, - * RK616_SPKR_CTL, RK616_VOL_SFT, 31, 0, out_vol_tlv), - */ - - /* - * When modem connecting, it will make some pop noise. - * So, add this control for modem. Modem will set 'OFF' - * before incall connected, and set 'ON' after connected. - */ - SOC_ENUM_EXT("Modem Input Enable", rk616_modem_input_type, - rk616_modem_input_get, rk616_modem_input_put), -}; - -static int rk616_dacl_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = w->codec; - - switch (event) { - case SND_SOC_DAPM_POST_PMU: - snd_soc_update_bits(codec, RK616_DAC_CTL, - RK616_DACL_INIT_MASK, 0); - snd_soc_update_bits(codec, RK616_DAC_CTL, - RK616_DACL_PWRD | RK616_DACL_CLK_PWRD | - RK616_DACL_INIT_MASK, 0); - snd_soc_update_bits(codec, RK616_DAC_CTL, - RK616_DACL_INIT_MASK, RK616_DACL_INIT_WORK); - break; - - case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, RK616_DAC_CTL, - RK616_DACL_PWRD | RK616_DACL_CLK_PWRD | - RK616_DACL_INIT_MASK, - RK616_DACL_PWRD | RK616_DACL_CLK_PWRD | - RK616_DACL_INIT_WORK); - snd_soc_update_bits(codec, RK616_DAC_CTL, - RK616_DACL_INIT_MASK, 0); - break; - - default: - return 0; - } - - return 0; -} - -static int rk616_dacr_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = w->codec; - - switch (event) { - case SND_SOC_DAPM_POST_PMU: - snd_soc_update_bits(codec, RK616_DAC_CTL, - RK616_DACR_INIT_MASK, 0); - snd_soc_update_bits(codec, RK616_DAC_CTL, - RK616_DACR_PWRD | RK616_DACR_CLK_PWRD | - RK616_DACR_INIT_MASK, 0); - snd_soc_update_bits(codec, RK616_DAC_CTL, - RK616_DACR_INIT_MASK, RK616_DACR_INIT_WORK); - break; - - case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, RK616_DAC_CTL, - RK616_DACR_PWRD | RK616_DACR_CLK_PWRD | - RK616_DACR_INIT_MASK, - RK616_DACR_PWRD | RK616_DACR_CLK_PWRD | - RK616_DACR_INIT_WORK); - snd_soc_update_bits(codec, RK616_DAC_CTL, - RK616_DACR_INIT_MASK, 0); - break; - - default: - return 0; - } - - return 0; -} - -static int rk616_adcl_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = w->codec; - - switch (event) { - case SND_SOC_DAPM_POST_PMU: - snd_soc_update_bits(codec, RK616_ADC_CTL, - RK616_ADCL_CLK_PWRD | RK616_ADCL_PWRD, 0); - break; - - case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, RK616_ADC_CTL, - RK616_ADCL_CLK_PWRD | RK616_ADCL_PWRD, - RK616_ADCL_CLK_PWRD | RK616_ADCL_PWRD); - break; - - default: - return 0; - } - - return 0; -} - -static int rk616_adcr_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = w->codec; - - switch (event) { - case SND_SOC_DAPM_POST_PMU: - snd_soc_update_bits(codec, RK616_ADC_CTL, - RK616_ADCR_CLK_PWRD | RK616_ADCR_PWRD, 0); - break; - - case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, RK616_ADC_CTL, - RK616_ADCR_CLK_PWRD | RK616_ADCR_PWRD, - RK616_ADCR_CLK_PWRD | RK616_ADCR_PWRD); - break; - - default: - return 0; - } - - return 0; -} - -/* Mixin */ -static const struct snd_kcontrol_new rk616_mixinl[] = { - SOC_DAPM_SINGLE("IN3L Switch", RK616_MIXINL_CTL, - RK616_MIL_F_IN3L_SFT, 1, 1), - SOC_DAPM_SINGLE("IN1P Switch", RK616_MIXINL_CTL, - RK616_MIL_F_IN1P_SFT, 1, 1), - SOC_DAPM_SINGLE("MUXMIC Switch", RK616_MIXINL_CTL, - RK616_MIL_F_MUX_SFT, 1, 1), -}; - -static const struct snd_kcontrol_new rk616_mixinr[] = { - SOC_DAPM_SINGLE("MIC2N Switch", RK616_MIXINR_CTL, - RK616_MIR_F_MIC2N_SFT, 1, 1), - SOC_DAPM_SINGLE("IN1P Switch", RK616_MIXINR_CTL, - RK616_MIR_F_IN1P_SFT, 1, 1), - SOC_DAPM_SINGLE("IN3R Switch", RK616_MIXINR_CTL, - RK616_MIR_F_IN3R_SFT, 1, 1), - SOC_DAPM_SINGLE("MIXINR Mux Switch", RK616_MIXINR_CTL, - RK616_MIR_F_MIRM_SFT, 1, 1), -}; - -/* Linemix */ -static const struct snd_kcontrol_new rk616_linemix[] = { - SOC_DAPM_SINGLE("PGAR Switch", RK616_LINEMIX_CTL, - RK616_LM_F_PGAR_SFT, 1, 1), - SOC_DAPM_SINGLE("PGAL Switch", RK616_LINEMIX_CTL, - RK616_LM_F_PGAL_SFT, 1, 1), - SOC_DAPM_SINGLE("DACR Switch", RK616_LINEMIX_CTL, - RK616_LM_F_DACR_SFT, 1, 1), - SOC_DAPM_SINGLE("DACL Switch", RK616_LINEMIX_CTL, - RK616_LM_F_DACL_SFT, 1, 1), -}; - -/* HPmix */ -static const struct snd_kcontrol_new rk616_hpmixl[] = { - SOC_DAPM_SINGLE("HPMix Mux Switch", RK616_HPMIX_CTL, - RK616_HML_F_HMM_SFT, 1, 1), - SOC_DAPM_SINGLE("IN1P Switch", RK616_HPMIX_CTL, - RK616_HML_F_IN1P_SFT, 1, 1), - SOC_DAPM_SINGLE("PGAL Switch", RK616_HPMIX_CTL, - RK616_HML_F_PGAL_SFT, 1, 1), - SOC_DAPM_SINGLE("DACL Switch", RK616_HPMIX_CTL, - RK616_HML_F_DACL_SFT, 1, 1), -}; - -static const struct snd_kcontrol_new rk616_hpmixr[] = { - SOC_DAPM_SINGLE("HPMix Mux Switch", RK616_HPMIX_CTL, - RK616_HMR_F_HMM_SFT, 1, 1), - SOC_DAPM_SINGLE("PGAR Switch", RK616_HPMIX_CTL, - RK616_HMR_F_PGAR_SFT, 1, 1), - SOC_DAPM_SINGLE("PGAL Switch", RK616_HPMIX_CTL, - RK616_HMR_F_PGAL_SFT, 1, 1), - SOC_DAPM_SINGLE("DACR Switch", RK616_HPMIX_CTL, - RK616_HMR_F_DACR_SFT, 1, 1), -}; - -/* HP MUX */ -static const char * const hpl_sel[] = {"HPMIXL", "DACL"}; - -static const struct soc_enum hpl_sel_enum = - SOC_ENUM_SINGLE(RK616_MUXHP_HPMIX_CTL, RK616_MHL_F_SFT, - ARRAY_SIZE(hpl_sel), hpl_sel); - -static const struct snd_kcontrol_new hpl_sel_mux = - SOC_DAPM_ENUM("HPL select Mux", hpl_sel_enum); - -static const char * const hpr_sel[] = {"HPMIXR", "DACR"}; - -static const struct soc_enum hpr_sel_enum = - SOC_ENUM_SINGLE(RK616_MUXHP_HPMIX_CTL, RK616_MHR_F_SFT, - ARRAY_SIZE(hpr_sel), hpr_sel); - -static const struct snd_kcontrol_new hpr_sel_mux = - SOC_DAPM_ENUM("HPR select Mux", hpr_sel_enum); - -/* MIC MUX */ -static const char * const mic_sel[] = {"BSTL", "BSTR"}; - -static const struct soc_enum mic_sel_enum = - SOC_ENUM_SINGLE(RK616_MIXINL_CTL, RK616_MM_F_SFT, - ARRAY_SIZE(mic_sel), mic_sel); - -static const struct snd_kcontrol_new mic_sel_mux = - SOC_DAPM_ENUM("Mic select Mux", mic_sel_enum); - -/* MIXINR MUX */ -static const char * const mixinr_sel[] = {"DIFFIN", "IN1N"}; - -static const struct soc_enum mixinr_sel_enum = - SOC_ENUM_SINGLE(RK616_DIFFIN_CTL, RK616_MIRM_F_SFT, - ARRAY_SIZE(mixinr_sel), mixinr_sel); - -static const struct snd_kcontrol_new mixinr_sel_mux = - SOC_DAPM_ENUM("Mixinr select Mux", mixinr_sel_enum); - -/* HPMIX MUX */ -static const char * const hpmix_sel[] = {"DIFFIN", "IN1N"}; - -static const struct soc_enum hpmix_sel_enum = - SOC_ENUM_SINGLE(RK616_DIFFIN_CTL, RK616_HMM_F_SFT, - ARRAY_SIZE(hpmix_sel), hpmix_sel); - -static const struct snd_kcontrol_new hpmix_sel_mux = - SOC_DAPM_ENUM("HPMix select Mux", hpmix_sel_enum); - - -static const struct snd_soc_dapm_widget rk616_dapm_widgets[] = { - /* supply */ - SND_SOC_DAPM_SUPPLY("I2S0 Interface", CRU_IO_CON0, - 3, 1, NULL, 0), - SND_SOC_DAPM_SUPPLY("I2S1 Interface", CRU_IO_CON0, - 4, 1, NULL, 0), - - /* microphone bias */ - SND_SOC_DAPM_MICBIAS("Mic1 Bias", RK616_MICBIAS_CTL, - RK616_MICBIAS1_PWRD_SFT, 1), - SND_SOC_DAPM_MICBIAS("Mic2 Bias", RK616_MICBIAS_CTL, - RK616_MICBIAS2_PWRD_SFT, 1), - - /* DACs */ - SND_SOC_DAPM_ADC_E("DACL", NULL, SND_SOC_NOPM, - 0, 0, rk616_dacl_event, - SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU), - SND_SOC_DAPM_ADC_E("DACR", NULL, SND_SOC_NOPM, - 0, 0, rk616_dacr_event, - SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU), - - /* ADCs */ - SND_SOC_DAPM_ADC_E("ADCL", NULL, SND_SOC_NOPM, - 0, 0, rk616_adcl_event, - SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU), - SND_SOC_DAPM_ADC_E("ADCR", NULL, SND_SOC_NOPM, - 0, 0, rk616_adcr_event, - SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU), - - /* PGA */ - SND_SOC_DAPM_PGA("BSTL", RK616_BST_CTL, - RK616_BSTL_PWRD_SFT, 1, NULL, 0), - SND_SOC_DAPM_PGA("BSTR", RK616_BST_CTL, - RK616_BSTR_PWRD_SFT, 1, NULL, 0), - SND_SOC_DAPM_PGA("DIFFIN", RK616_DIFFIN_CTL, - RK616_DIFFIN_PWRD_SFT, 1, NULL, 0), - SND_SOC_DAPM_PGA("PGAL", RK616_PGAL_CTL, - RK616_PGA_PWRD_SFT, 1, NULL, 0), - SND_SOC_DAPM_PGA("PGAR", RK616_PGAR_CTL, - RK616_PGA_PWRD_SFT, 1, NULL, 0), - SND_SOC_DAPM_PGA("SPKL", RK616_SPKL_CTL, - RK616_PWRD_SFT, 1, NULL, 0), - SND_SOC_DAPM_PGA("SPKR", RK616_SPKR_CTL, - RK616_PWRD_SFT, 1, NULL, 0), - SND_SOC_DAPM_PGA("HPL", RK616_HPL_CTL, - RK616_PWRD_SFT, 1, NULL, 0), - SND_SOC_DAPM_PGA("HPR", RK616_HPR_CTL, - RK616_PWRD_SFT, 1, NULL, 0), - SND_SOC_DAPM_PGA("LINE1", RK616_LINEOUT1_CTL, - RK616_LINEOUT_PWRD_SFT, 1, NULL, 0), - SND_SOC_DAPM_PGA("LINE2", RK616_LINEOUT2_CTL, - RK616_LINEOUT_PWRD_SFT, 1, NULL, 0), - - /* MIXER */ - SND_SOC_DAPM_MIXER("MIXINL", RK616_MIXINL_CTL, - RK616_MIL_PWRD_SFT, 1, rk616_mixinl, - ARRAY_SIZE(rk616_mixinl)), - SND_SOC_DAPM_MIXER("MIXINR", RK616_MIXINR_CTL, - RK616_MIR_PWRD_SFT, 1, rk616_mixinr, - ARRAY_SIZE(rk616_mixinr)), - SND_SOC_DAPM_MIXER("LINEMIX", RK616_LINEMIX_CTL, - RK616_LM_PWRD_SFT, 1, rk616_linemix, - ARRAY_SIZE(rk616_linemix)), - SND_SOC_DAPM_MIXER("HPMIXL", RK616_MUXHP_HPMIX_CTL, - RK616_HML_PWRD_SFT, 1, rk616_hpmixl, - ARRAY_SIZE(rk616_hpmixl)), - SND_SOC_DAPM_MIXER("HPMIXR", RK616_MUXHP_HPMIX_CTL, - RK616_HMR_PWRD_SFT, 1, rk616_hpmixr, - ARRAY_SIZE(rk616_hpmixr)), - - /* MUX */ - SND_SOC_DAPM_MUX("HPL Mux", SND_SOC_NOPM, 0, 0, - &hpl_sel_mux), - SND_SOC_DAPM_MUX("HPR Mux", SND_SOC_NOPM, 0, 0, - &hpr_sel_mux), - SND_SOC_DAPM_MUX("Mic Mux", SND_SOC_NOPM, 0, 0, - &mic_sel_mux), - SND_SOC_DAPM_MUX("MIXINR Mux", SND_SOC_NOPM, 0, 0, - &mixinr_sel_mux), - SND_SOC_DAPM_MUX("HPMix Mux", SND_SOC_NOPM, 0, 0, - &hpmix_sel_mux), - - /* Audio Interface */ - SND_SOC_DAPM_AIF_IN("I2S0 DAC", "HiFi Playback", 0, - SND_SOC_NOPM, 0, 0), - SND_SOC_DAPM_AIF_OUT("I2S0 ADC", "HiFi Capture", 0, - SND_SOC_NOPM, 0, 0), - SND_SOC_DAPM_AIF_IN("I2S1 DAC", "Voice Playback", 0, - SND_SOC_NOPM, 0, 0), - SND_SOC_DAPM_AIF_OUT("I2S1 ADC", "Voice Capture", 0, - SND_SOC_NOPM, 0, 0), - - /* Input */ - SND_SOC_DAPM_INPUT("IN3L"), - SND_SOC_DAPM_INPUT("IN3R"), - SND_SOC_DAPM_INPUT("IN1P"), - SND_SOC_DAPM_INPUT("IN1N"), - SND_SOC_DAPM_INPUT("MIC2P"), - SND_SOC_DAPM_INPUT("MIC2N"), - SND_SOC_DAPM_INPUT("MIC1P"), - SND_SOC_DAPM_INPUT("MIC1N"), - - /* Output */ - SND_SOC_DAPM_OUTPUT("SPKOUTL"), - SND_SOC_DAPM_OUTPUT("SPKOUTR"), - SND_SOC_DAPM_OUTPUT("HPOUTL"), - SND_SOC_DAPM_OUTPUT("HPOUTR"), - SND_SOC_DAPM_OUTPUT("LINEOUT1"), - SND_SOC_DAPM_OUTPUT("LINEOUT2"), -}; - -static const struct snd_soc_dapm_route rk616_dapm_routes[] = { - {"I2S0 DAC", NULL, "I2S0 Interface"}, - {"I2S0 ADC", NULL, "I2S0 Interface"}, - {"I2S1 DAC", NULL, "I2S1 Interface"}, - {"I2S1 ADC", NULL, "I2S1 Interface"}, - - /* Input */ - {"DIFFIN", NULL, "IN1P"}, - {"DIFFIN", NULL, "IN1N"}, - - {"BSTR", NULL, "MIC2P"}, - {"BSTR", NULL, "MIC2N"}, - {"BSTL", NULL, "MIC1P"}, - {"BSTL", NULL, "MIC1N"}, - - {"HPMix Mux", "DIFFIN", "DIFFIN"}, - {"HPMix Mux", "IN1N", "IN1N"}, - - {"MIXINR Mux", "DIFFIN", "DIFFIN"}, - {"MIXINR Mux", "IN1N", "IN1N"}, - - {"Mic Mux", "BSTR", "BSTR"}, - {"Mic Mux", "BSTL", "BSTL"}, - - {"MIXINR", "MIC2N Switch", "MIC2N"}, - {"MIXINR", "IN1P Switch", "IN1P"}, - {"MIXINR", "IN3R Switch", "IN3R"}, - {"MIXINR", "MIXINR Mux Switch", "MIXINR Mux"}, - - {"MIXINL", "IN3L Switch", "IN3L"}, - {"MIXINL", "IN1P Switch", "IN1P"}, - {"MIXINL", "MUXMIC Switch", "Mic Mux"}, - - {"PGAR", NULL, "MIXINR"}, - {"PGAL", NULL, "MIXINL"}, - - {"ADCR", NULL, "PGAR"}, - {"ADCL", NULL, "PGAL"}, - - {"I2S0 ADC", NULL, "ADCR"}, - {"I2S0 ADC", NULL, "ADCL"}, - - {"I2S1 ADC", NULL, "ADCR"}, - {"I2S1 ADC", NULL, "ADCL"}, - - /* Output */ - {"DACR", NULL, "I2S0 DAC"}, - {"DACL", NULL, "I2S0 DAC"}, - - {"DACR", NULL, "I2S1 DAC"}, - {"DACL", NULL, "I2S1 DAC"}, - - {"LINEMIX", "PGAR Switch", "PGAR"}, - {"LINEMIX", "PGAL Switch", "PGAL"}, - {"LINEMIX", "DACR Switch", "DACR"}, - {"LINEMIX", "DACL Switch", "DACL"}, - - {"HPMIXR", "HPMix Mux Switch", "HPMix Mux"}, - {"HPMIXR", "PGAR Switch", "PGAR"}, - {"HPMIXR", "PGAL Switch", "PGAL"}, - {"HPMIXR", "DACR Switch", "DACR"}, - - {"HPMIXL", "HPMix Mux Switch", "HPMix Mux"}, - {"HPMIXL", "IN1P Switch", "IN1P"}, - {"HPMIXL", "PGAL Switch", "PGAL"}, - {"HPMIXL", "DACL Switch", "DACL"}, - - {"HPR Mux", "DACR", "DACR"}, - {"HPR Mux", "HPMIXR", "HPMIXR"}, - {"HPL Mux", "DACL", "DACL"}, - {"HPL Mux", "HPMIXL", "HPMIXL"}, - - {"LINE1", NULL, "LINEMIX"}, - {"LINE2", NULL, "LINEMIX"}, - {"SPKR", NULL, "HPR Mux"}, - {"SPKL", NULL, "HPL Mux"}, - {"HPR", NULL, "HPR Mux"}, - {"HPL", NULL, "HPL Mux"}, - - {"LINEOUT1", NULL, "LINE1"}, - {"LINEOUT2", NULL, "LINE2"}, - {"SPKOUTR", NULL, "SPKR"}, - {"SPKOUTL", NULL, "SPKL"}, - {"HPOUTR", NULL, "HPR"}, - {"HPOUTL", NULL, "HPL"}, -}; - -static int rk616_set_bias_level(struct snd_soc_codec *codec, - enum snd_soc_bias_level level) -{ - switch (level) { - case SND_SOC_BIAS_ON: - break; - - case SND_SOC_BIAS_PREPARE: - if (!rk616_for_mid) { - snd_soc_update_bits(codec, RK616_MICBIAS_CTL, - RK616_MICBIAS2_PWRD | RK616_MICBIAS2_V_MASK, - RK616_MICBIAS2_V_1_7); - mdelay(100); - } - break; - - case SND_SOC_BIAS_STANDBY: - if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { - /* set power */ - snd_soc_update_bits(codec, RK616_PWR_ADD1, - RK616_ADC_PWRD | RK616_DIFFIN_MIR_PGAR_RLPWRD | - RK616_MIC1_MIC2_MIL_PGAL_RLPWRD | - RK616_ADCL_RLPWRD | RK616_ADCR_RLPWRD, 0); - - snd_soc_update_bits(codec, RK616_PWR_ADD2, - RK616_HPL_HPR_PWRD | RK616_DAC_PWRD | - RK616_DACL_SPKL_RLPWRD | RK616_DACL_RLPWRD | - RK616_DACR_SPKR_RLPWRD | RK616_DACR_RLPWRD | - RK616_LM_LO_RLPWRD | RK616_HM_RLPWRD, 0); - - snd_soc_update_bits(codec, RK616_PWR_ADD3, - RK616_ADCL_ZO_PWRD | RK616_ADCR_ZO_PWRD | - RK616_DACL_ZO_PWRD | RK616_DACR_ZO_PWRD, - RK616_ADCL_ZO_PWRD | RK616_ADCR_ZO_PWRD | - RK616_DACL_ZO_PWRD | RK616_DACR_ZO_PWRD); - - if (!rk616_for_mid) - snd_soc_update_bits(codec, RK616_MICBIAS_CTL, - RK616_MICBIAS2_PWRD | - RK616_MICBIAS2_V_MASK, - RK616_MICBIAS2_V_1_7); - } - break; - - case SND_SOC_BIAS_OFF: - snd_soc_write(codec, RK616_PWR_ADD1, - rk616_reg_defaults[RK616_PWR_ADD1] & ~RK616_ADC_PWRD); - snd_soc_write(codec, RK616_PWR_ADD2, - rk616_reg_defaults[RK616_PWR_ADD2]); - snd_soc_write(codec, RK616_PWR_ADD3, - rk616_reg_defaults[RK616_PWR_ADD3]); - if (!rk616_for_mid) - snd_soc_update_bits(codec, RK616_MICBIAS_CTL, - RK616_MICBIAS1_PWRD, - RK616_MICBIAS1_PWRD); - break; - } - - codec->dapm.bias_level = level; - - return 0; -} - -static int rk616_set_dai_sysclk(struct snd_soc_dai *codec_dai, - int clk_id, unsigned int freq, int dir) -{ - struct rk616_codec_priv *rk616 = rk616_priv; - - if (!rk616 || !rk616_mfd) { - pr_err("%s : %s %s\n", - __func__, !rk616 ? "rk616 is NULL" : "", - !rk616_mfd ? "rk616_mfd is NULL" : ""); - return -EINVAL; - } - - rk616->stereo_sysclk = freq; - - /* set I2S mclk for mipi */ - rk616_mclk_set_rate(rk616_mfd->mclk, freq); - - return 0; -} - -static int rk616_set_dai_fmt(struct snd_soc_dai *codec_dai, - unsigned int fmt) -{ - struct snd_soc_codec *codec = codec_dai->codec; - unsigned int adc_aif1 = 0, adc_aif2 = 0, dac_aif1 = 0, dac_aif2 = 0; - - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: - adc_aif2 |= RK616_I2S_MODE_SLV; - break; - case SND_SOC_DAIFMT_CBM_CFM: - adc_aif2 |= RK616_I2S_MODE_MST; - break; - default: - pr_err("%s : set master mask failed!\n", - __func__); - return -EINVAL; - } - - switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_DSP_A: - adc_aif1 |= RK616_ADC_DF_PCM; - dac_aif1 |= RK616_DAC_DF_PCM; - break; - case SND_SOC_DAIFMT_DSP_B: - break; - case SND_SOC_DAIFMT_I2S: - adc_aif1 |= RK616_ADC_DF_I2S; - dac_aif1 |= RK616_DAC_DF_I2S; - break; - case SND_SOC_DAIFMT_RIGHT_J: - adc_aif1 |= RK616_ADC_DF_RJ; - dac_aif1 |= RK616_DAC_DF_RJ; - break; - case SND_SOC_DAIFMT_LEFT_J: - adc_aif1 |= RK616_ADC_DF_LJ; - dac_aif1 |= RK616_DAC_DF_LJ; - break; - default: - pr_err("%s : set format failed!\n", __func__); - return -EINVAL; - } - - switch (fmt & SND_SOC_DAIFMT_INV_MASK) { - case SND_SOC_DAIFMT_NB_NF: - adc_aif1 |= RK616_ALRCK_POL_DIS; - adc_aif2 |= RK616_ABCLK_POL_DIS; - dac_aif1 |= RK616_DLRCK_POL_DIS; - dac_aif2 |= RK616_DBCLK_POL_DIS; - break; - case SND_SOC_DAIFMT_IB_IF: - adc_aif1 |= RK616_ALRCK_POL_EN; - adc_aif2 |= RK616_ABCLK_POL_EN; - dac_aif1 |= RK616_DLRCK_POL_EN; - dac_aif2 |= RK616_DBCLK_POL_EN; - break; - case SND_SOC_DAIFMT_IB_NF: - adc_aif1 |= RK616_ALRCK_POL_DIS; - adc_aif2 |= RK616_ABCLK_POL_EN; - dac_aif1 |= RK616_DLRCK_POL_DIS; - dac_aif2 |= RK616_DBCLK_POL_EN; - break; - case SND_SOC_DAIFMT_NB_IF: - adc_aif1 |= RK616_ALRCK_POL_EN; - adc_aif2 |= RK616_ABCLK_POL_DIS; - dac_aif1 |= RK616_DLRCK_POL_EN; - dac_aif2 |= RK616_DBCLK_POL_DIS; - break; - default: - pr_err("%s : set dai format failed!\n", __func__); - return -EINVAL; - } - - snd_soc_update_bits(codec, RK616_ADC_INT_CTL1, - RK616_ALRCK_POL_MASK | RK616_ADC_DF_MASK, adc_aif1); - snd_soc_update_bits(codec, RK616_ADC_INT_CTL2, - RK616_ABCLK_POL_MASK | RK616_I2S_MODE_MASK, adc_aif2); - snd_soc_update_bits(codec, RK616_DAC_INT_CTL1, - RK616_DLRCK_POL_MASK | RK616_DAC_DF_MASK, dac_aif1); - snd_soc_update_bits(codec, RK616_DAC_INT_CTL2, - RK616_DBCLK_POL_MASK, dac_aif2); - - return 0; -} - -static int rk616_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec *codec = rtd->codec; - struct rk616_codec_priv *rk616 = rk616_priv; - unsigned int rate = params_rate(params); - unsigned int div, dai_fmt = rtd->card->dai_link->dai_fmt; - unsigned int adc_aif1 = 0, adc_aif2 = 0, dac_aif1 = 0, dac_aif2 = 0; - u32 mfd_aif1 = 0, mfd_aif2 = 0, mfd_i2s_ctl = 0; - - if (!rk616) { - pr_err("%s : rk616 is NULL\n", __func__); - return -EINVAL; - } - - if ((dai_fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBM_CFM) { - /* - * bclk = codec_clk / 4 - * lrck = bclk / (wl * 2) - */ - div = (((rk616->stereo_sysclk / 4) / rate) / 2); - - if ((rk616->stereo_sysclk % (4 * rate * 2) > 0) || - (div != 16 && div != 20 && div != 24 && div != 32)) { - pr_err("%s : need PLL\n", __func__); - return -EINVAL; - } - } else { - /* - * If codec is slave mode, it don't need to set div - * according to sysclk and rate. - */ - div = 32; - } - - switch (div) { - case 16: - adc_aif2 |= RK616_ADC_WL_16; - dac_aif2 |= RK616_DAC_WL_16; - break; - case 20: - adc_aif2 |= RK616_ADC_WL_20; - dac_aif2 |= RK616_DAC_WL_20; - break; - case 24: - adc_aif2 |= RK616_ADC_WL_24; - dac_aif2 |= RK616_DAC_WL_24; - break; - case 32: - adc_aif2 |= RK616_ADC_WL_32; - dac_aif2 |= RK616_DAC_WL_32; - break; - default: - return -EINVAL; - } - - - DBG("%s : MCLK = %dHz, sample rate = %dHz, div = %d\n", - __func__, rk616->stereo_sysclk, rate, div); - - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: - adc_aif1 |= RK616_ADC_VWL_16; - dac_aif1 |= RK616_DAC_VWL_16; - break; - case SNDRV_PCM_FORMAT_S20_3LE: - adc_aif1 |= RK616_ADC_VWL_20; - dac_aif1 |= RK616_DAC_VWL_20; - break; - case SNDRV_PCM_FORMAT_S24_LE: - adc_aif1 |= RK616_ADC_VWL_24; - dac_aif1 |= RK616_DAC_VWL_24; - break; - case SNDRV_PCM_FORMAT_S32_LE: - adc_aif1 |= RK616_ADC_VWL_32; - dac_aif1 |= RK616_DAC_VWL_32; - break; - default: - return -EINVAL; - } - - /*switch (params_channels(params)) { - case RK616_MONO: - adc_aif1 |= RK616_ADC_TYPE_MONO; - break; - case RK616_STEREO: - adc_aif1 |= RK616_ADC_TYPE_STEREO; - break; - default: - return -EINVAL; - }*/ - - /* MIC1N/P and MIC2N/P can only line to ADCL, so set mono type. */ - adc_aif1 |= RK616_ADC_TYPE_MONO; - - adc_aif1 |= RK616_ADC_SWAP_DIS; - adc_aif2 |= RK616_ADC_RST_DIS; - dac_aif1 |= RK616_DAC_SWAP_DIS; - dac_aif2 |= RK616_DAC_RST_DIS; - - rk616->rate = rate; - - snd_soc_update_bits(codec, RK616_ADC_INT_CTL1, - RK616_ADC_VWL_MASK | RK616_ADC_SWAP_MASK | - RK616_ADC_TYPE_MASK, adc_aif1); - snd_soc_update_bits(codec, RK616_ADC_INT_CTL2, - RK616_ADC_WL_MASK | RK616_ADC_RST_MASK, - adc_aif2); - snd_soc_update_bits(codec, RK616_DAC_INT_CTL1, - RK616_DAC_VWL_MASK | RK616_DAC_SWAP_MASK, - dac_aif1); - snd_soc_update_bits(codec, RK616_DAC_INT_CTL2, - RK616_DAC_WL_MASK | RK616_DAC_RST_MASK, - dac_aif2); - - switch (dai->id) { - case RK616_HIFI: - mfd_aif1 |= I2S1_OUT_DISABLE | I2S0_PD_DISABLE; - mfd_aif2 |= I2S0_SI_EN; - mfd_i2s_ctl |= 0; - break; - case RK616_VOICE: - mfd_aif1 |= I2S0_OUT_DISABLE | I2S1_PD_DISABLE; - mfd_aif2 |= I2S1_SI_EN; - mfd_i2s_ctl |= I2S_CHANNEL_SEL | PCM_TO_I2S_MUX; - break; - default: - return -EINVAL; - } - - snd_soc_update_bits(codec, CRU_IO_CON0, - I2S1_OUT_DISABLE | I2S0_OUT_DISABLE | - I2S1_PD_DISABLE | I2S0_PD_DISABLE, mfd_aif1); - snd_soc_update_bits(codec, CRU_IO_CON1, - I2S1_SI_EN | I2S0_SI_EN, mfd_aif2); - snd_soc_update_bits(codec, CRU_PCM2IS2_CON2, - APS_SEL | APS_CLR | I2S_CHANNEL_SEL, - mfd_i2s_ctl); - return 0; -} - -static int rk616_digital_mute(struct snd_soc_dai *dai, int mute) -{ - struct rk616_codec_priv *rk616 = rk616_priv; - - if (rk616_for_mid) { - DBG("%s immediately return for mid\n", __func__); - return 0; - } - - if (!rk616) { - pr_err("%s : rk616_priv is NULL\n", __func__); - return -EINVAL; - } - - if (mute) { - rk616_set_gpio(RK616_CODEC_SET_SPK | - RK616_CODEC_SET_HP | RK616_CODEC_SET_RCV, GPIO_LOW); - } else { - if (rk616->spk_gpio_level) - rk616_set_gpio(RK616_CODEC_SET_SPK, - rk616->spk_gpio_level); - - if (rk616->hp_gpio_level) - rk616_set_gpio(RK616_CODEC_SET_HP, - rk616->hp_gpio_level); - - if (rk616->rcv_gpio_level) - rk616_set_gpio(RK616_CODEC_SET_RCV, - rk616->rcv_gpio_level); - } - - return 0; -} - -#define RK616_PLAYBACK_RATES (SNDRV_PCM_RATE_8000 |\ - SNDRV_PCM_RATE_16000 | \ - SNDRV_PCM_RATE_32000 | \ - SNDRV_PCM_RATE_44100 | \ - SNDRV_PCM_RATE_48000 | \ - SNDRV_PCM_RATE_96000) - -#define RK616_CAPTURE_RATES (SNDRV_PCM_RATE_8000 |\ - SNDRV_PCM_RATE_16000 | \ - SNDRV_PCM_RATE_32000 | \ - SNDRV_PCM_RATE_44100 | \ - SNDRV_PCM_RATE_48000 | \ - SNDRV_PCM_RATE_96000) - -#define RK616_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ - SNDRV_PCM_FMTBIT_S20_3LE |\ - SNDRV_PCM_FMTBIT_S24_LE |\ - SNDRV_PCM_FMTBIT_S32_LE) - -static struct snd_soc_dai_ops rk616_dai_ops = { - .hw_params = rk616_hw_params, - .set_fmt = rk616_set_dai_fmt, - .set_sysclk = rk616_set_dai_sysclk, - .digital_mute = rk616_digital_mute, -}; - -static struct snd_soc_dai_driver rk616_dai[] = { - { - .name = "rk616-hifi", - .id = RK616_HIFI, - .playback = { - .stream_name = "HiFi Playback", - .channels_min = 2, - .channels_max = 2, - .rates = RK616_PLAYBACK_RATES, - .formats = RK616_FORMATS, - }, - .capture = { - .stream_name = "HiFi Capture", - .channels_min = 2, - .channels_max = 2, - .rates = RK616_CAPTURE_RATES, - .formats = RK616_FORMATS, - }, - .ops = &rk616_dai_ops, - }, - { - .name = "rk616-voice", - .id = RK616_VOICE, - .playback = { - .stream_name = "Voice Playback", - .channels_min = 1, - .channels_max = 2, - .rates = RK616_PLAYBACK_RATES, - .formats = RK616_FORMATS, - }, - .capture = { - .stream_name = "Voice Capture", - .channels_min = 1, - .channels_max = 2, - .rates = RK616_CAPTURE_RATES, - .formats = RK616_FORMATS, - }, - .ops = &rk616_dai_ops, - }, - -}; - -static int rk616_suspend(struct snd_soc_codec *codec) -{ - if (rk616_for_mid) - rk616_codec_power_down(RK616_CODEC_ALL); - else - rk616_set_bias_level(codec, SND_SOC_BIAS_OFF); - - return 0; -} - -static int rk616_resume(struct snd_soc_codec *codec) -{ - struct rk616_codec_priv *rk616 = rk616_priv; - - if (!rk616) { - pr_err("%s : rk616 priv is NULL!\n", __func__); - return -EINVAL; - } - - if (rk616_for_mid) { - if (rk616->hpmic_from_mic2in) - snd_soc_write(codec, RK616_MICBIAS_CTL, - RK616_MICBIAS1_PWRD | RK616_MICBIAS2_V_1_7); - else - snd_soc_write(codec, RK616_MICBIAS_CTL, - RK616_MICBIAS2_PWRD | RK616_MICBIAS1_V_1_7); - } else { - rk616_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - } - - return 0; -} - -static int rk616_probe(struct snd_soc_codec *codec) -{ - struct rk616_codec_priv *rk616 = rk616_priv; - struct snd_kcontrol_new *kcontrol; - struct soc_mixer_control *mixer; - unsigned int val; - int ret, i, num_controls; - - DBG("%s\n", __func__); - - if (!rk616) { - pr_err("%s : rk616 priv is NULL!\n", - __func__); - return -EINVAL; - } - - rk616->codec = codec; - rk616->playback_path = OFF; - rk616->capture_path = MIC_OFF; - rk616->voice_call_path = OFF; - rk616->voip_path = OFF; - rk616->spk_gpio_level = GPIO_LOW; - rk616->hp_gpio_level = GPIO_LOW; - rk616->rcv_gpio_level = GPIO_LOW; - rk616->mic_gpio_level = GPIO_LOW; - rk616->modem_input_enable = 1; - - /* virtual gnd will make hpout a litter louder. */ - if (rk616->virtual_gnd && (rk616->hp_volume >= 4)) - rk616->hp_volume -= 4; - - ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); - if (ret != 0) { - pr_err("%s : Failed to set cache I/O: %d\n", - __func__, ret); - goto err__; - } - - codec->hw_read = rk616_codec_read; - codec->hw_write = (hw_write_t)rk616_hw_write; - codec->read = rk616_codec_read; - codec->write = rk616_codec_write; - - val = snd_soc_read(codec, RK616_RESET); - if (val != rk616_reg_defaults[RK616_RESET] && val != 0x43) { - pr_err("%s : codec register 0: %x is not a 0x00000003\n", - __func__, val); - ret = -ENODEV; - goto err__; - } - - rk616_reset(codec); - - if (rk616_for_mid) { - kcontrol = rk616_snd_path_controls; - num_controls = ARRAY_SIZE(rk616_snd_path_controls); - } else { - kcontrol = rk616_snd_controls; - num_controls = ARRAY_SIZE(rk616_snd_controls); - } - - /* update the max of volume controls for incall */ - for (i = 0; i < num_controls; i++) { - if (strcmp(kcontrol[i].name, - "Speaker Playback Volume") == 0) { - mixer = (struct soc_mixer_control *) - kcontrol[i].private_value; - pr_info("Speaker Playback Volume mixer->max %d\n", - mixer->max); - mixer->max = rk616->spk_volume; - mixer->platform_max = rk616->spk_volume; - } else if (strcmp(kcontrol[i].name, - "Headphone Playback Volume") == 0) { - mixer = (struct soc_mixer_control *) - kcontrol[i].private_value; - pr_info("Headphone Playback Volume mixer->max %d\n", - mixer->max); - mixer->max = rk616->hp_volume; - mixer->platform_max = rk616->hp_volume; - } else if (strcmp(kcontrol[i].name, - "Earpiece Playback Volume") == 0) { - mixer = (struct soc_mixer_control *) - kcontrol[i].private_value; - pr_info("Headphone Playback Volume mixer->max %d\n", - mixer->max); - mixer->max = rk616->spk_volume; - mixer->platform_max = rk616->spk_volume; - } - } - - if (rk616_for_mid) { - snd_soc_add_codec_controls(codec, rk616_snd_path_controls, - ARRAY_SIZE(rk616_snd_path_controls)); - if (rk616->hpmic_from_mic2in) - snd_soc_write(codec, RK616_MICBIAS_CTL, - RK616_MICBIAS1_PWRD | RK616_MICBIAS2_V_1_7); - else - snd_soc_write(codec, RK616_MICBIAS_CTL, - RK616_MICBIAS2_PWRD | RK616_MICBIAS1_V_1_7); - } else { - codec->dapm.bias_level = SND_SOC_BIAS_OFF; - rk616_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - - snd_soc_add_codec_controls(codec, rk616_snd_controls, - ARRAY_SIZE(rk616_snd_controls)); - snd_soc_dapm_new_controls(&codec->dapm, rk616_dapm_widgets, - ARRAY_SIZE(rk616_dapm_widgets)); - snd_soc_dapm_add_routes(&codec->dapm, rk616_dapm_routes, - ARRAY_SIZE(rk616_dapm_routes)); - } - - return 0; - -err__: - kfree(rk616); - rk616 = NULL; - rk616_priv = NULL; - - return ret; -} - -/* power down chip */ -static int rk616_remove(struct snd_soc_codec *codec) -{ - struct rk616_codec_priv *rk616 = rk616_priv; - - DBG("%s\n", __func__); - - if (!rk616) { - pr_err("%s : rk616_priv is NULL\n", __func__); - return 0; - } - - rk616_set_gpio(RK616_CODEC_SET_SPK | RK616_CODEC_SET_HP, GPIO_LOW); - - mdelay(10); - - snd_soc_write(codec, RK616_RESET, 0xfc); - mdelay(10); - snd_soc_write(codec, RK616_RESET, 0x3); - mdelay(10); - - kfree(rk616); - - return 0; -} - -static struct snd_soc_codec_driver soc_codec_dev_rk616 = { - .probe = rk616_probe, - .remove = rk616_remove, - .suspend = rk616_suspend, - .resume = rk616_resume, - .set_bias_level = rk616_set_bias_level, - .reg_cache_size = ARRAY_SIZE(rk616_reg_defaults), - .reg_word_size = sizeof(unsigned int), - .reg_cache_default = rk616_reg_defaults, - .volatile_register = rk616_volatile_register, - .readable_register = rk616_codec_register, -}; - -static int rk616_codec_parse_gpio(struct device *dev, - struct device_node *node, int *gpio, char *name) -{ - enum of_gpio_flags flags; - int ret; - - *gpio = of_get_named_gpio_flags(node, name, 0, &flags); - if (*gpio < 0) { - pr_err("%s : %s is NULL!\n", - __func__, name); - *gpio = INVALID_GPIO; - } else { - ret = devm_gpio_request(dev, *gpio, name); - if (ret < 0) { - pr_err("%s() %s request ERROR\n", - __func__, name); - return ret; - } - /* set gpio to low level */ - ret = gpio_direction_output(*gpio , flags); - if (ret < 0) { - pr_err("%s() %s set ERROR\n", - __func__, name); - return ret; - } - } - - return 0; -} - -/* -* dts: - -* rk616-codec { -* spk-ctl-gpio = <&gpio2 GPIO_D7 GPIO_ACTIVE_HIGH>; -* hp-ctl-gpio = <&gpio2 GPIO_D7 GPIO_ACTIVE_HIGH>; -* // rcv-ctl-gpio = <&gpio2 GPIO_D7 GPIO_ACTIVE_HIGH>; -* // mic-sel-gpio = <&gpio2 GPIO_D7 GPIO_ACTIVE_HIGH>; -* -* // delay for MOSFET or SPK power amplifier chip(ms) -* spk-amplifier-delay = <150>; -* hp-mosfet-delay = <50>; -* -* // hp-mic-capture-from-linein; // hpmic is connected to linein -* // hp-mic-capture-from-mic2in; // hpmic is connected to mic2 -* // virtual-hp-gnd; // hp gnd is not connected to gnd(0V) -* -* // volume setting: 0 ~ 31, -18dB ~ 28.5dB, Step: 1.5dB -* skp-volume = <24>; -* hp-volume = <24>; -* capture-volume = <24>; -* }; -*/ -#ifdef CONFIG_OF -static int rk616_codec_parse_dt_property(struct device *dev, - struct rk616_codec_priv *rk616) -{ - struct device_node *node = dev->of_node; - int ret; - - DBG("%s()\n", __func__); - - if (!node) { - pr_err("%s() dev->of_node is NULL\n", - __func__); - return -ENODEV; - } - - node = of_get_child_by_name(dev->of_node, "rk616-codec"); - if (!node) { - pr_err("%s() Can not get child: rk616-codec\n", - __func__); - return -ENODEV; - } - - ret = rk616_codec_parse_gpio(dev, node, - &rk616->spk_ctl_gpio, "spk-ctl-gpio"); - if (ret < 0) { - pr_err("%s() parse gpio : spk-ctl-gpio ERROR\n", - __func__); - return ret; - } - - ret = rk616_codec_parse_gpio(dev, node, - &rk616->hp_ctl_gpio, "hp-ctl-gpio"); - if ((ret < 0) && (rk616->hp_ctl_gpio != rk616->spk_ctl_gpio)) { - pr_err("%s() parse gpio : hp-ctl-gpio ERROR\n", - __func__); - return ret; - } - - ret = rk616_codec_parse_gpio(dev, node, - &rk616->rcv_ctl_gpio, "rcv-ctl-gpio"); - if (ret < 0) { - pr_err("%s() parse gpio : rcv-ctl-gpio ERROR\n", - __func__); - return ret; - } - - ret = rk616_codec_parse_gpio(dev, node, - &rk616->mic_sel_gpio, "mic-sel-gpio"); - if (ret < 0) { - pr_err("%s() parse gpio : mic-sel-gpio ERROR\n", - __func__); - return ret; - } - - ret = of_property_read_u32(node, "spk-amplifier-delay", - &rk616->spk_amp_delay); - if (ret < 0) { - DBG("%s() Can not read property spk-amplifier-delay\n", - __func__); - rk616->spk_amp_delay = 0; - } - - ret = of_property_read_u32(node, "hp-mosfet-delay", - &rk616->hp_mos_delay); - if (ret < 0) { - DBG("%s() Can not read property hp-mosfet-delay\n", - __func__); - rk616->hp_mos_delay = 0; - } - - rk616->hpmic_from_linein = - !!of_get_property(node, "hp-mic-capture-from-linein", NULL); - rk616->hpmic_from_mic2in = - !!of_get_property(node, "hp-mic-capture-from-mic2in", NULL); - rk616->virtual_gnd = !!of_get_property(node, "virtual-hp-gnd", NULL); - - ret = of_property_read_u32(node, "skp-volume", &rk616->spk_volume); - if (ret < 0) { - DBG("%s() Can not read property skp-volume\n", __func__); - rk616->spk_volume = 24; - } - - ret = of_property_read_u32(node, "hp-volume", - &rk616->hp_volume); - if (ret < 0) { - DBG("%s() Can not read property hp-volume\n", - __func__); - rk616->hp_volume = 24; - } - - ret = of_property_read_u32(node, "capture-volume", - &rk616->capture_volume); - if (ret < 0) { - DBG("%s() Can not read property capture-volume\n", - __func__); - rk616->spk_volume = 24; - } - - return 0; -} -#else -static int rk616_codec_parse_dt_property(struct device *dev, - struct rk616_codec_priv *rk616) -{ - return -ENOSYS; -} -#endif - -static int rk616_platform_probe(struct platform_device *pdev) -{ - struct mfd_rk616 *rk616 = dev_get_drvdata(pdev->dev.parent); - int ret; - - DBG("%s\n", __func__); - - if (!rk616) { - pr_err("%s : rk616 is NULL\n", __func__); - return -EINVAL; - } - - rk616_mfd = rk616; - - rk616_priv = kzalloc(sizeof(struct rk616_codec_priv), GFP_KERNEL); - if (!rk616) { - pr_err("%s : rk616 priv kzalloc failed!\n", - __func__); - return -ENOMEM; - } - - /* For sound card register(codec_of_node). */ - pdev->dev.of_node = pdev->dev.parent->of_node; - - ret = rk616_codec_parse_dt_property(&pdev->dev, rk616_priv); - if (ret < 0) { - pr_err("%s() parse device tree property error %d\n", - __func__, ret); - goto err_; - } - - ret = snd_soc_register_codec(&pdev->dev, - &soc_codec_dev_rk616, rk616_dai, ARRAY_SIZE(rk616_dai)); - if (ret < 0) { - pr_err("%s() register codec error %d\n", - __func__, ret); - goto err_; - } - - return 0; -err_: - - kfree(rk616_priv); - rk616_priv = NULL; - rk616_mfd = NULL; - - return ret; -} - -static int rk616_platform_remove(struct platform_device *pdev) -{ - snd_soc_unregister_codec(&pdev->dev); - - kfree(rk616_priv); - rk616_priv = NULL; - rk616_mfd = NULL; - - return 0; -} - -void rk616_platform_shutdown(struct platform_device *pdev) -{ - struct rk616_codec_priv *rk616 = rk616_priv; - struct snd_soc_codec *codec; - - DBG("%s\n", __func__); - - if (!rk616 || !rk616->codec) { - pr_err("%s : rk616_priv or rk616_priv->codec is NULL\n", - __func__); - return; - } - - codec = rk616->codec; - - rk616_set_gpio(RK616_CODEC_SET_SPK | RK616_CODEC_SET_HP, GPIO_LOW); - - mdelay(10); - - snd_soc_write(codec, RK616_RESET, 0xfc); - mdelay(10); - snd_soc_write(codec, RK616_RESET, 0x3); - - if (rk616_priv) { - kfree(rk616_priv); - if (rk616_priv) - rk616_priv = NULL; - } -} - -static struct platform_driver rk616_codec_driver = { - .driver = { - .name = "rk616-codec", - .owner = THIS_MODULE, - }, - .probe = rk616_platform_probe, - .remove = rk616_platform_remove, - .shutdown = rk616_platform_shutdown, -}; - - -static __init int rk616_modinit(void) -{ - rk616_get_parameter(); - return platform_driver_register(&rk616_codec_driver); -} -module_init(rk616_modinit); - -static __exit void rk616_exit(void) -{ - platform_driver_unregister(&rk616_codec_driver); -} -module_exit(rk616_exit); - -MODULE_DESCRIPTION("ASoC RK616 driver"); -MODULE_AUTHOR("chenjq "); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/rk616_codec.h b/sound/soc/codecs/rk616_codec.h deleted file mode 100644 index dc2b4102618e..000000000000 --- a/sound/soc/codecs/rk616_codec.h +++ /dev/null @@ -1,793 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * rk616.h -- RK616 CODEC ALSA SoC audio driver - * - * Copyright 2013 Rockship - * Author: chenjq - * - */ - -#ifndef __RK616_CODEC_H__ -#define __RK616_CODEC_H__ - -/* mfd register */ -/* CRU_PCM2IS2_CON2 (0x0098) */ -#define PCM_TO_I2S_MUX (1 << 3) -#define APS_SEL (1 << 2) -#define APS_CLR (1 << 1) -#define I2S_CHANNEL_SEL (1 << 0) - -/* CRU_CFGMISC_CON (0x009C) */ -#define MICDET1_PIN_F_CODEC (1 << 18) -#define MICDET2_PIN_F_CODEC (1 << 17) -#define AD_DA_LOOP (1 << 0) -#define AD_DA_LOOP_SFT 0 - -/* codec register */ -#define RK616_CODEC_BASE 0x0800 - -#define RK616_RESET (RK616_CODEC_BASE + 0x00) -#define RK616_DAC_VOL (RK616_CODEC_BASE + 0x04) -#define RK616_ADC_INT_CTL1 (RK616_CODEC_BASE + 0x08) -#define RK616_ADC_INT_CTL2 (RK616_CODEC_BASE + 0x0c) -#define RK616_DAC_INT_CTL1 (RK616_CODEC_BASE + 0x10) -#define RK616_DAC_INT_CTL2 (RK616_CODEC_BASE + 0x14) -#define RK616_CLK_CHPUMP (RK616_CODEC_BASE + 0x1c) -#define RK616_PGA_AGC_CTL (RK616_CODEC_BASE + 0x28) -#define RK616_PWR_ADD1 (RK616_CODEC_BASE + 0x3c) -#define RK616_BST_CTL (RK616_CODEC_BASE + 0x40) -#define RK616_DIFFIN_CTL (RK616_CODEC_BASE + 0x44) -#define RK616_MIXINL_CTL (RK616_CODEC_BASE + 0x48) -#define RK616_MIXINL_VOL1 (RK616_CODEC_BASE + 0x4c) -#define RK616_MIXINL_VOL2 (RK616_CODEC_BASE + 0x50) -#define RK616_MIXINR_CTL (RK616_CODEC_BASE + 0x54) -#define RK616_MIXINR_VOL1 (RK616_CODEC_BASE + 0x58) -#define RK616_MIXINR_VOL2 (RK616_CODEC_BASE + 0x5c) -#define RK616_PGAL_CTL (RK616_CODEC_BASE + 0x60) -#define RK616_PGAR_CTL (RK616_CODEC_BASE + 0x64) -#define RK616_PWR_ADD2 (RK616_CODEC_BASE + 0x68) -#define RK616_DAC_CTL (RK616_CODEC_BASE + 0x6c) -#define RK616_LINEMIX_CTL (RK616_CODEC_BASE + 0x70) -#define RK616_MUXHP_HPMIX_CTL (RK616_CODEC_BASE + 0x74) -#define RK616_HPMIX_CTL (RK616_CODEC_BASE + 0x78) -#define RK616_HPMIX_VOL1 (RK616_CODEC_BASE + 0x7c) -#define RK616_HPMIX_VOL2 (RK616_CODEC_BASE + 0x80) -#define RK616_LINEOUT1_CTL (RK616_CODEC_BASE + 0x84) -#define RK616_LINEOUT2_CTL (RK616_CODEC_BASE + 0x88) -#define RK616_SPKL_CTL (RK616_CODEC_BASE + 0x8c) -#define RK616_SPKR_CTL (RK616_CODEC_BASE + 0x90) -#define RK616_HPL_CTL (RK616_CODEC_BASE + 0x94) -#define RK616_HPR_CTL (RK616_CODEC_BASE + 0x98) -#define RK616_MICBIAS_CTL (RK616_CODEC_BASE + 0x9c) -#define RK616_MICKEY_DET_CTL (RK616_CODEC_BASE + 0xa0) -#define RK616_PWR_ADD3 (RK616_CODEC_BASE + 0xa4) -#define RK616_ADC_CTL (RK616_CODEC_BASE + 0xa8) -/* Signal zero-crossing detection */ -#define RK616_SINGNAL_ZC_CTL1 (RK616_CODEC_BASE + 0xac) -/* Signal zero-crossing detection */ -#define RK616_SINGNAL_ZC_CTL2 (RK616_CODEC_BASE + 0xB0) -#define RK616_PGAL_AGC_CTL1 (RK616_CODEC_BASE + 0xc0) -#define RK616_PGAL_AGC_CTL2 (RK616_CODEC_BASE + 0xc4) -#define RK616_PGAL_AGC_CTL3 (RK616_CODEC_BASE + 0xc8) -#define RK616_PGAL_AGC_CTL4 (RK616_CODEC_BASE + 0xcc) -#define RK616_PGAL_ASR_CTL (RK616_CODEC_BASE + 0xd0) -#define RK616_PGAL_AGC_MAX_H (RK616_CODEC_BASE + 0xd4) -#define RK616_PGAL_AGC_MAX_L (RK616_CODEC_BASE + 0xd8) -#define RK616_PGAL_AGC_MIN_H (RK616_CODEC_BASE + 0xdc) -#define RK616_PGAL_AGC_MIN_L (RK616_CODEC_BASE + 0xe0) -#define RK616_PGAL_AGC_CTL5 (RK616_CODEC_BASE + 0xe4) -#define RK616_PGAR_AGC_CTL1 (RK616_CODEC_BASE + 0x100) -#define RK616_PGAR_AGC_CTL2 (RK616_CODEC_BASE + 0x104) -#define RK616_PGAR_AGC_CTL3 (RK616_CODEC_BASE + 0x108) -#define RK616_PGAR_AGC_CTL4 (RK616_CODEC_BASE + 0x10c) -#define RK616_PGAR_ASR_CTL (RK616_CODEC_BASE + 0x110) -#define RK616_PGAR_AGC_MAX_H (RK616_CODEC_BASE + 0x114) -#define RK616_PGAR_AGC_MAX_L (RK616_CODEC_BASE + 0x118) -#define RK616_PGAR_AGC_MIN_H (RK616_CODEC_BASE + 0x11c) -#define RK616_PGAR_AGC_MIN_L (RK616_CODEC_BASE + 0x120) -#define RK616_PGAR_AGC_CTL5 (RK616_CODEC_BASE + 0x124) - -/* global definition (0x8c 0x90 0x94 0x98) */ -#define RK616_PWRD (0x1 << 7) -#define RK616_PWRD_SFT 7 - -#define RK616_INIT_MASK (0x1 << 6) -#define RK616_INIT_SFT 6 -#define RK616_INIT_RN (0x1 << 6) -#define RK616_INIT_AFT (0x0 << 6) - -#define RK616_MUTE (0x1 << 5) -#define RK616_MUTE_SFT 5 - -#define RK616_VOL_MASK 0x1f -#define RK616_VOL_SFT 0 - -/* ADC Interface Control 1 (0x08) */ -#define RK616_ALRCK_POL_MASK (0x1 << 7) -#define RK616_ALRCK_POL_SFT 7 -#define RK616_ALRCK_POL_EN (0x1 << 7) -#define RK616_ALRCK_POL_DIS (0x0 << 7) - -#define RK616_ADC_VWL_MASK (0x3 << 5) -#define RK616_ADC_VWL_SFT 5 -#define RK616_ADC_VWL_32 (0x3 << 5) -#define RK616_ADC_VWL_24 (0x2 << 5) -#define RK616_ADC_VWL_20 (0x1 << 5) -#define RK616_ADC_VWL_16 (0x0 << 5) - -#define RK616_ADC_DF_MASK (0x3 << 3) -#define RK616_ADC_DF_SFT 3 -#define RK616_ADC_DF_PCM (0x3 << 3) -#define RK616_ADC_DF_I2S (0x2 << 3) -#define RK616_ADC_DF_LJ (0x1 << 3) -#define RK616_ADC_DF_RJ (0x0 << 3) - -#define RK616_ADC_SWAP_MASK (0x1 << 1) -#define RK616_ADC_SWAP_SFT 1 -#define RK616_ADC_SWAP_EN (0x1 << 1) -#define RK616_ADC_SWAP_DIS (0x0 << 1) - -#define RK616_ADC_TYPE_MASK 0x1 -#define RK616_ADC_TYPE_SFT 0 -#define RK616_ADC_TYPE_MONO 0x1 -#define RK616_ADC_TYPE_STEREO 0x0 - -/* ADC Interface Control 2 (0x0c) */ -#define RK616_I2S_MODE_MASK (0x1 << 4) -#define RK616_I2S_MODE_SFT 4 -#define RK616_I2S_MODE_MST (0x1 << 4) -#define RK616_I2S_MODE_SLV (0x0 << 4) - -#define RK616_ADC_WL_MASK (0x3 << 2) -#define RK616_ADC_WL_SFT 2 -#define RK616_ADC_WL_32 (0x3 << 2) -#define RK616_ADC_WL_24 (0x2 << 2) -#define RK616_ADC_WL_20 (0x1 << 2) -#define RK616_ADC_WL_16 (0x0 << 2) - -#define RK616_ADC_RST_MASK (0x1 << 1) -#define RK616_ADC_RST_SFT 1 -#define RK616_ADC_RST_DIS (0x1 << 1) -#define RK616_ADC_RST_EN (0x0 << 1) - -#define RK616_ABCLK_POL_MASK 0x1 -#define RK616_ABCLK_POL_SFT 0 -#define RK616_ABCLK_POL_EN 0x1 -#define RK616_ABCLK_POL_DIS 0x0 - -/* DAC Interface Control 1 (0x10) */ -#define RK616_DLRCK_POL_MASK (0x1 << 7) -#define RK616_DLRCK_POL_SFT 7 -#define RK616_DLRCK_POL_EN (0x1 << 7) -#define RK616_DLRCK_POL_DIS (0x0 << 7) - -#define RK616_DAC_VWL_MASK (0x3 << 5) -#define RK616_DAC_VWL_SFT 5 -#define RK616_DAC_VWL_32 (0x3 << 5) -#define RK616_DAC_VWL_24 (0x2 << 5) -#define RK616_DAC_VWL_20 (0x1 << 5) -#define RK616_DAC_VWL_16 (0x0 << 5) - -#define RK616_DAC_DF_MASK (0x3 << 3) -#define RK616_DAC_DF_SFT 3 -#define RK616_DAC_DF_PCM (0x3 << 3) -#define RK616_DAC_DF_I2S (0x2 << 3) -#define RK616_DAC_DF_LJ (0x1 << 3) -#define RK616_DAC_DF_RJ (0x0 << 3) - -#define RK616_DAC_SWAP_MASK (0x1 << 2) -#define RK616_DAC_SWAP_SFT 2 -#define RK616_DAC_SWAP_EN (0x1 << 2) -#define RK616_DAC_SWAP_DIS (0x0 << 2) - -/* DAC Interface Control 2 (0x14) */ -#define RK616_DAC_WL_MASK (0x3 << 2) -#define RK616_DAC_WL_SFT 2 -#define RK616_DAC_WL_32 (0x3 << 2) -#define RK616_DAC_WL_24 (0x2 << 2) -#define RK616_DAC_WL_20 (0x1 << 2) -#define RK616_DAC_WL_16 (0x0 << 2) - -#define RK616_DAC_RST_MASK (0x1 << 1) -#define RK616_DAC_RST_SFT 1 -#define RK616_DAC_RST_DIS (0x1 << 1) -#define RK616_DAC_RST_EN (0x0 << 1) - -#define RK616_DBCLK_POL_MASK 0x1 -#define RK616_DBCLK_POL_SFT 0 -#define RK616_DBCLK_POL_EN 0x1 -#define RK616_DBCLK_POL_DIS 0x0 - -/* PGA AGC Enable (0x28) */ -#define RK616_PGAL_AGC_EN_MASK (0x1 << 5) -#define RK616_PGAL_AGC_EN_SFT 5 -#define RK616_PGAL_AGC_EN (0x1 << 5) -#define RK616_PGAL_AGC_DIS (0x0 << 5) - -#define RK616_PGAR_AGC_EN_MASK (0x1 << 4) -#define RK616_PGAR_AGC_EN_SFT 4 -#define RK616_PGAR_AGC_EN (0x1 << 4) -#define RK616_PGAR_AGC_DIS (0x0 << 4) - -/* Power Management Addition 1 (0x3c) */ -#define RK616_ADC_PWRD (0x1 << 6) -#define RK616_ADC_PWRD_SFT 6 - -#define RK616_DIFFIN_MIR_PGAR_RLPWRD (0x1 << 5) -#define RK616_DIFFIN_MIR_PGAR_RLPWRD_SFT 5 - -#define RK616_MIC1_MIC2_MIL_PGAL_RLPWRD (0x1 << 4) -#define RK616_MIC1_MIC2_MIL_PGAL_RLPWRD_SFT 4 - -#define RK616_ADCL_RLPWRD (0x1 << 3) -#define RK616_ADCL_RLPWRD_SFT 3 - -#define RK616_ADCR_RLPWRD (0x1 << 2) -#define RK616_ADCR_RLPWRD_SFT 2 - -/* BST Control (0x40) */ -#define RK616_BSTL_PWRD (0x1 << 7) -#define RK616_BSTL_PWRD_SFT 7 - -#define RK616_BSTL_MODE_MASK (0x1 << 6) -#define RK616_BSTL_MODE_SFT 6 -#define RK616_BSTL_MODE_SE (0x1 << 6) -#define RK616_BSTL_MODE_DIFF (0x0 << 6) - -#define RK616_BSTL_GAIN_MASK (0x1 << 5) -#define RK616_BSTL_GAIN_SFT 5 -#define RK616_BSTL_GAIN_20DB (0x1 << 5) -#define RK616_BSTL_GAIN_0DB (0x0 << 5) - -#define RK616_BSTL_MUTE (0x1 << 4) -#define RK616_BSTL_MUTE_SFT 4 - -#define RK616_BSTR_PWRD (0x1 << 3) -#define RK616_BSTR_PWRD_SFT 3 - -#define RK616_BSTR_MODE_MASK (0x1 << 2) -#define RK616_BSTR_MODE_SFT 2 -#define RK616_BSTR_MODE_SE (0x1 << 2) -#define RK616_BSTR_MODE_DIFF (0x0 << 2) - -#define RK616_BSTR_GAIN_MASK (0x1 << 1) -#define RK616_BSTR_GAIN_SFT 1 -#define RK616_BSTR_GAIN_20DB (0x1 << 1) -#define RK616_BSTR_GAIN_0DB (0x0 << 1) - -#define RK616_BSTR_MUTE 0x1 -#define RK616_BSTR_MUTE_SFT 0 - -/* DIFFIN Control (0x44) */ -#define RK616_DIFFIN_PWRD (0x1 << 5) -#define RK616_DIFFIN_PWRD_SFT 5 - -#define RK616_DIFFIN_MODE_MASK (0x1 << 4) -#define RK616_DIFFIN_MODE_SFT 4 -#define RK616_DIFFIN_MODE_SE (0x1 << 4) -#define RK616_DIFFIN_MODE_DIFF (0x0 << 4) - -#define RK616_DIFFIN_GAIN_MASK (0x1 << 3) -#define RK616_DIFFIN_GAIN_SFT 3 -#define RK616_DIFFIN_GAIN_20DB (0x1 << 3) -#define RK616_DIFFIN_GAIN_0DB (0x0 << 3) - -#define RK616_DIFFIN_MUTE (0x1 << 2) -#define RK616_DIFFIN_MUTE_SFT 2 - -#define RK616_MIRM_F_MASK (0x1 << 1) -#define RK616_MIRM_F_SFT 1 -#define RK616_MIRM_F_IN1N (0x1 << 1) -#define RK616_MIRM_F_DIFFIN (0x0 << 1) - -#define RK616_HMM_F_MASK 0x1 -#define RK616_HMM_F_SFT 0 -#define RK616_HMM_F_IN1N 0x1 -#define RK616_HMM_F_DIFFIN 0x0 - -/* BSTR MUXMIC MIXINL Control (0x48) */ -#define RK616_SE_BSTR_F_MASK (0x1 << 6) -#define RK616_SE_BSTR_F_SFT 6 -#define RK616_SE_BSTR_F_MIN2P (0x1 << 6) -#define RK616_SE_BSTR_F_MIN2N (0x0 << 6) - -#define RK616_MM_F_MASK (0x1 << 5) -#define RK616_MM_F_SFT 5 -#define RK616_MM_F_BSTR (0x1 << 5) -#define RK616_MM_F_BSTL (0x0 << 5) - -#define RK616_MIL_PWRD (0x1 << 4) -#define RK616_MIL_PWRD_SFT 4 - -#define RK616_MIL_MUTE (0x1 << 3) -#define RK616_MIL_MUTE_SFT 3 - -#define RK616_MIL_F_IN3L (0x1 << 2) -#define RK616_MIL_F_IN3L_SFT 2 - -#define RK616_MIL_F_IN1P (0x1 << 1) -#define RK616_MIL_F_IN1P_SFT 1 - -#define RK616_MIL_F_MUX (0x1 << 0) -#define RK616_MIL_F_MUX_SFT 0 - -/* MIXINL volume 1 (0x4c) */ -#define RK616_MIL_F_MUX_VOL_MASK (0x7 << 3) -#define RK616_MIL_F_MUX_VOL_SFT 3 - -#define RK616_MIL_F_IN1P_VOL_MASK 0x7 -#define RK616_MIL_F_IN1P_VOL_SFT 0 - -/* MIXINL volume 2 (0x50) */ -#define RK616_MIL_F_IN3L_VOL_MASK 0x7 -#define RK616_MIL_F_IN3L_VOL_SFT 0 - -/* MIXINR Control (0x54) */ -#define RK616_MIR_PWRD (0x1 << 5) -#define RK616_MIR_PWRD_SFT 5 - -#define RK616_MIR_MUTE (0x1 << 4) -#define RK616_MIR_MUTE_SFT 4 - -#define RK616_MIR_F_MIC2N (0x1 << 3) -#define RK616_MIR_F_MIC2N_SFT 3 - -#define RK616_MIR_F_IN1P (0x1 << 2) -#define RK616_MIR_F_IN1P_SFT 2 - -#define RK616_MIR_F_IN3R (0x1 << 1) -#define RK616_MIR_F_IN3R_SFT 1 - -#define RK616_MIR_F_MIRM 0x1 -#define RK616_MIR_F_MIRM_SFT 0 - -/* MIXINR volume 1 (0x58) */ -#define RK616_MIR_F_MIRM_VOL_MASK (0x7 << 3) -#define RK616_MIR_F_MIRM_VOL_SFT 3 - -#define RK616_MIR_F_IN3R_VOL_MASK 0x7 -#define RK616_MIR_F_IN3R_VOL_SFT 0 - -/* MIXINR volume 2 (0x5c) */ -#define RK616_MIR_F_MIC2N_VOL_MASK (0x7 << 3) -#define RK616_MIR_F_MIC2N_VOL_SFT 3 - -#define RK616_MIR_F_IN1P_VOL_MASK 0x7 -#define RK616_MIR_F_IN1P_VOL_SFT 0 - -/* PGA Control (0x60 0x64) */ -#define RK616_PGA_PWRD (0x1 << 7) -#define RK616_PGA_PWRD_SFT 7 - -#define RK616_PGA_MUTE (0x1 << 6) -#define RK616_PGA_MUTE_SFT 6 - -#define RK616_PGA_VOL_MASK (0x1f << 0) -#define RK616_PGA_VOL_SFT 0 - -/* Power Management Addition 2 (0x68) */ -#define RK616_HPL_HPR_PWRD (0x1 << 7) -#define RK616_HPL_HPR_PWRD_SFT 7 - -#define RK616_DAC_PWRD (0x1 << 6) -#define RK616_DAC_PWRD_SFT 6 - -#define RK616_DACL_RLPWRD (0x1 << 5) -#define RK616_DACL_RLPWRD_SFT 5 - -#define RK616_DACL_SPKL_RLPWRD (0x1 << 4) -#define RK616_DACL_SPKL_RLPWRD_SFT 4 - -#define RK616_DACR_RLPWRD (0x1 << 3) -#define RK616_DACR_RLPWRD_SFT 3 - -#define RK616_DACR_SPKR_RLPWRD (0x1 << 2) -#define RK616_DACR_SPKR_RLPWRD_SFT 2 - -#define RK616_LM_LO_RLPWRD (0x1 << 1) -#define RK616_LM_LO_RLPWRD_SFT 1 - -#define RK616_HM_RLPWRD 0x1 -#define RK616_HM_RLPWRD_SFT 0 - -/* DAC Control (0x6c) */ -#define RK616_DACL_INIT_MASK (0x1 << 5) -#define RK616_DACL_INIT_SFT 5 -#define RK616_DACL_INIT_WORK (0x1 << 5) -#define RK616_DACL_INIT_NOT (0x0 << 5) - -#define RK616_DACR_INIT_MASK (0x1 << 4) -#define RK616_DACR_INIT_SFT 4 -#define RK616_DACR_INIT_WORK (0x1 << 4) -#define RK616_DACR_INIT_NOT (0x0 << 4) - -#define RK616_DACL_PWRD (0x1 << 3) -#define RK616_DACL_PWRD_SFT 3 - -#define RK616_DACR_PWRD (0x1 << 2) -#define RK616_DACR_PWRD_SFT 2 - -#define RK616_DACR_CLK_PWRD (0x1 << 1) -#define RK616_DACR_CLK_PWRD_SFT 1 - -#define RK616_DACL_CLK_PWRD 0x1 -#define RK616_DACL_CLK_PWRD_SFT 0 - -/* Linemix Control (0x70) */ -#define RK616_LM_PWRD (0x1 << 4) -#define RK616_LM_PWRD_SFT 4 - -#define RK616_LM_F_PGAR (0x1 << 3) -#define RK616_LM_F_PGAR_SFT 3 - -#define RK616_LM_F_PGAL (0x1 << 2) -#define RK616_LM_F_PGAL_SFT 2 - -#define RK616_LM_F_DACR (0x1 << 1) -#define RK616_LM_F_DACR_SFT 1 - -#define RK616_LM_F_DACL 0x1 -#define RK616_LM_F_DACL_SFT 0 - -/* MUXHP HPMIX Control (0x74) */ -#define RK616_HML_PWRD (0x1 << 5) -#define RK616_HML_PWRD_SFT 5 - -#define RK616_HML_INIT_MASK (0x1 << 4) -#define RK616_HML_INIT_SFT 4 -#define RK616_HML_INIT_RN (0x1 << 4) -#define RK616_HML_INIT_AFT (0x0 << 4) - -#define RK616_HMR_PWRD (0x1 << 3) -#define RK616_HMR_PWRD_SFT 3 - -#define RK616_HMR_INIT_MASK (0x1 << 2) -#define RK616_HMR_INIT_SFT 2 -#define RK616_HMR_INIT_RN (0x1 << 2) -#define RK616_HMR_INIT_AFT (0x0 << 2) - -#define RK616_MHL_F_MASK (0x1 << 1) -#define RK616_MHL_F_SFT 1 -#define RK616_MHL_F_DACL (0x1 << 1) -#define RK616_MHL_F_HPMIXL (0x0 << 1) - -#define RK616_MHR_F_MASK 0x1 -#define RK616_MHR_F_SFT 0 -#define RK616_MHR_F_DACR 0x1 -#define RK616_MHR_F_HPMIXR 0x0 - -/* HPMIX Control (0x78) */ -#define RK616_HML_F_HMM (0x1 << 7) -#define RK616_HML_F_HMM_SFT 7 - -#define RK616_HML_F_IN1P (0x1 << 6) -#define RK616_HML_F_IN1P_SFT 6 - -#define RK616_HML_F_PGAL (0x1 << 5) -#define RK616_HML_F_PGAL_SFT 5 - -#define RK616_HML_F_DACL (0x1 << 4) -#define RK616_HML_F_DACL_SFT 4 - -#define RK616_HMR_F_HMM (0x1 << 3) -#define RK616_HMR_F_HMM_SFT 3 - -#define RK616_HMR_F_PGAR (0x1 << 2) -#define RK616_HMR_F_PGAR_SFT 2 - -#define RK616_HMR_F_PGAL (0x1 << 1) -#define RK616_HMR_F_PGAL_SFT 1 - -#define RK616_HMR_F_DACR 0x1 -#define RK616_HMR_F_DACR_SFT 0 - -/* HPMIX Volume Control 1 (0x7c) */ -#define RK616_HML_F_IN1P_VOL_MASK 0x7 -#define RK616_HML_F_IN1P_VOL_SFT 0 - -/* HPMIX Volume Control 2 (0x80) */ -#define RK616_HML_F_HMM_VOL_MASK (0x7 << 3) -#define RK616_HML_F_HMM_VOL_SFT 3 - -#define RK616_HMR_F_HMM_VOL_MASK 0x7 -#define RK616_HMR_F_HMM_VOL_SFT 0 - -/* Lineout1 Control (0x84 0x88) */ -#define RK616_LINEOUT_PWRD (0x1 << 6) -#define RK616_LINEOUT_PWRD_SFT 6 - -#define RK616_LINEOUT_MUTE (0x1 << 5) -#define RK616_LINEOUT_MUTE_SFT 5 - -#define RK616_LINEOUT_VOL_MASK 0x1f -#define RK616_LINEOUT_VOL_SFT 0 - -/* Micbias Control 1 (0x9c) */ -#define RK616_MICBIAS1_PWRD (0x1 << 7) -#define RK616_MICBIAS1_PWRD_SFT 7 - -#define RK616_MICBIAS2_PWRD (0x1 << 6) -#define RK616_MICBIAS2_PWRD_SFT 6 - -#define RK616_MICBIAS1_V_MASK (0x7 << 3) -#define RK616_MICBIAS1_V_SFT 3 -#define RK616_MICBIAS1_V_1_7 (0x7 << 3) -#define RK616_MICBIAS1_V_1_6 (0x6 << 3) -#define RK616_MICBIAS1_V_1_5 (0x5 << 3) -#define RK616_MICBIAS1_V_1_4 (0x4 << 3) -#define RK616_MICBIAS1_V_1_3 (0x3 << 3) -#define RK616_MICBIAS1_V_1_2 (0x2 << 3) -#define RK616_MICBIAS1_V_1_1 (0x1 << 3) -#define RK616_MICBIAS1_V_1_0 (0x0 << 3) - -#define RK616_MICBIAS2_V_MASK 0x7 -#define RK616_MICBIAS2_V_SFT 0 -#define RK616_MICBIAS2_V_1_7 0x7 -#define RK616_MICBIAS2_V_1_6 0x6 -#define RK616_MICBIAS2_V_1_5 0x5 -#define RK616_MICBIAS2_V_1_4 0x4 -#define RK616_MICBIAS2_V_1_3 0x3 -#define RK616_MICBIAS2_V_1_2 0x2 -#define RK616_MICBIAS2_V_1_1 0x1 -#define RK616_MICBIAS2_V_1_0 0x0 - -/* MIC Key Detection Control (0xa0) */ -#define RK616_MK1_DET_MASK (0x1 << 7) -#define RK616_MK1_DET_SFT 7 -#define RK616_MK1_EN (0x1 << 7) -#define RK616_MK1_DIS (0x0 << 7) - -#define RK616_MK2_DET_MASK (0x1 << 6) -#define RK616_MK2_DET_SFT 6 -#define RK616_MK2_EN (0x1 << 6) -#define RK616_MK2_DIS (0x0 << 6) - -#define RK616_MK1_DET_I_MASK (0x7 << 3) -#define RK616_MK1_DET_I_SFT 3 -#define RK616_MK1_DET_I_1500 (0x7 << 3) -#define RK616_MK1_DET_I_1300 (0x6 << 3) -#define RK616_MK1_DET_I_1100 (0x5 << 3) -#define RK616_MK1_DET_I_900 (0x4 << 3) -#define RK616_MK1_DET_I_700 (0x3 << 3) -#define RK616_MK1_DET_I_500 (0x2 << 3) -#define RK616_MK1_DET_I_300 (0x1 << 3) -#define RK616_MK1_DET_I_100 (0x0 << 3) - -#define RK616_MK2_DET_I_MASK 0x7 -#define RK616_MK2_DET_I_SFT 0 -#define RK616_MK2_DET_I_1500 0x7 -#define RK616_MK2_DET_I_1300 0x6 -#define RK616_MK2_DET_I_1100 0x5 -#define RK616_MK2_DET_I_900 0x4 -#define RK616_MK2_DET_I_700 0x3 -#define RK616_MK2_DET_I_500 0x2 -#define RK616_MK2_DET_I_300 0x1 -#define RK616_MK2_DET_I_100 0x0 - -/* Power Management Addition 3 (0xa4) */ -#define RK616_ADCL_ZO_PWRD (0x1 << 3) -#define RK616_ADCL_ZO_PWRD_SFT 3 - -#define RK616_ADCR_ZO_PWRD (0x1 << 2) -#define RK616_ADCR_ZO_PWRD_SFT 2 - -#define RK616_DACL_ZO_PWRD (0x1 << 1) -#define RK616_DACL_ZO_PWRD_SFT 1 - -#define RK616_DACR_ZO_PWRD 0x1 -#define RK616_DACR_ZO_PWRD_SFT 0 - -/* ADC control (0xa8) */ -#define RK616_ADCL_CLK_PWRD (0x1 << 5) -#define RK616_ADCL_CLK_PWRD_SFT 5 - -#define RK616_ADCL_PWRD (0x1 << 4) -#define RK616_ADCL_PWRD_SFT 4 - -#define RK616_ADCL_CLEAR_MASK (0x1 << 3) -#define RK616_ADCL_CLEAR_SFT 3 -#define RK616_ADCL_CLEAR_EN (0x1 << 3) -#define RK616_ADCL_CLEAR_DIS (0x0 << 3) - -#define RK616_ADCR_CLK_PWRD (0x1 << 2) -#define RK616_ADCR_CLK_PWRD_SFT 2 - -#define RK616_ADCR_PWRD (0x1 << 1) -#define RK616_ADCR_PWRD_SFT 1 - -#define RK616_ADCR_CLEAR_MASK 0x1 -#define RK616_ADCR_CLEAR_SFT 0 -#define RK616_ADCR_CLEAR_EN 0x1 -#define RK616_ADCR_CLEAR_DIS 0x0 - -/* PGA AGC control 1 (0xc0 0x110) */ -#define RK616_PGA_AGC_WAY_MASK (0x1 << 4) -#define RK616_PGA_AGC_WAY_SFT 4 -#define RK616_PGA_AGC_WAY_JACK (0x1 << 4) -#define RK616_PGA_AGC_WAY_NOR (0x0 << 4) - -#define RK616_PGA_AGC_HOLD_T_MASK 0xf -#define RK616_PGA_AGC_HOLD_T_SFT 0 -#define RK616_PGA_AGC_HOLD_T_1024 0xa -#define RK616_PGA_AGC_HOLD_T_512 0x9 -#define RK616_PGA_AGC_HOLD_T_256 0x8 -#define RK616_PGA_AGC_HOLD_T_128 0x7 -#define RK616_PGA_AGC_HOLD_T_64 0x6 -#define RK616_PGA_AGC_HOLD_T_32 0x5 -#define RK616_PGA_AGC_HOLD_T_16 0x4 -#define RK616_PGA_AGC_HOLD_T_8 0x3 -#define RK616_PGA_AGC_HOLD_T_4 0x2 -#define RK616_PGA_AGC_HOLD_T_2 0x1 -#define RK616_PGA_AGC_HOLD_T_0 0x0 - -/* PGA AGC control 2 (0xc4 0x104) */ -#define RK616_PGA_AGC_GRU_T_MASK (0xf << 4) -#define RK616_PGA_AGC_GRU_T_SFT 4 -#define RK616_PGA_AGC_GRU_T_512 (0xa << 4) -#define RK616_PGA_AGC_GRU_T_256 (0x9 << 4) -#define RK616_PGA_AGC_GRU_T_128 (0x8 << 4) -#define RK616_PGA_AGC_GRU_T_64 (0x7 << 4) -#define RK616_PGA_AGC_GRU_T_32 (0x6 << 4) -#define RK616_PGA_AGC_GRU_T_16 (0x5 << 4) -#define RK616_PGA_AGC_GRU_T_8 (0x4 << 4) -#define RK616_PGA_AGC_GRU_T_4 (0x3 << 4) -#define RK616_PGA_AGC_GRU_T_2 (0x2 << 4) -#define RK616_PGA_AGC_GRU_T_1 (0x1 << 4) -#define RK616_PGA_AGC_GRU_T_0_5 (0x0 << 4) - -#define RK616_PGA_AGC_GRD_T_MASK 0xf -#define RK616_PGA_AGC_GRD_T_SFT 0 -#define RK616_PGA_AGC_GRD_T_128_32 0xa -#define RK616_PGA_AGC_GRD_T_64_16 0x9 -#define RK616_PGA_AGC_GRD_T_32_8 0x8 -#define RK616_PGA_AGC_GRD_T_16_4 0x7 -#define RK616_PGA_AGC_GRD_T_8_2 0x6 -#define RK616_PGA_AGC_GRD_T_4_1 0x5 -#define RK616_PGA_AGC_GRD_T_2_0_512 0x4 -#define RK616_PGA_AGC_GRD_T_1_0_256 0x3 -#define RK616_PGA_AGC_GRD_T_0_500_128 0x2 -#define RK616_PGA_AGC_GRD_T_0_250_64 0x1 -#define RK616_PGA_AGC_GRD_T_0_125_32 0x0 - -/* PGA AGC control 3 (0xc8 0x108) */ -#define RK616_PGA_AGC_MODE_MASK (0x1 << 7) -#define RK616_PGA_AGC_MODE_SFT 7 -#define RK616_PGA_AGC_MODE_LIMIT (0x1 << 7) -#define RK616_PGA_AGC_MODE_NOR (0x0 << 7) - -#define RK616_PGA_AGC_ZO_MASK (0x1 << 6) -#define RK616_PGA_AGC_ZO_SFT 6 -#define RK616_PGA_AGC_ZO_EN (0x1 << 6) -#define RK616_PGA_AGC_ZO_DIS (0x0 << 6) - -#define RK616_PGA_AGC_REC_MODE_MASK (0x1 << 5) -#define RK616_PGA_AGC_REC_MODE_SFT 5 -#define RK616_PGA_AGC_REC_MODE_AC (0x1 << 5) -#define RK616_PGA_AGC_REC_MODE_RN (0x0 << 5) - -#define RK616_PGA_AGC_FAST_D_MASK (0x1 << 4) -#define RK616_PGA_AGC_FAST_D_SFT 4 -#define RK616_PGA_AGC_FAST_D_EN (0x1 << 4) -#define RK616_PGA_AGC_FAST_D_DIS (0x0 << 4) - -#define RK616_PGA_AGC_NG_MASK (0x1 << 3) -#define RK616_PGA_AGC_NG_SFT 3 -#define RK616_PGA_AGC_NG_EN (0x1 << 3) -#define RK616_PGA_AGC_NG_DIS (0x0 << 3) - -#define RK616_PGA_AGC_NG_THR_MASK 0x7 -#define RK616_PGA_AGC_NG_THR_SFT 0 -#define RK616_PGA_AGC_NG_THR_N81DB 0x7 -#define RK616_PGA_AGC_NG_THR_N75DB 0x6 -#define RK616_PGA_AGC_NG_THR_N69DB 0x5 -#define RK616_PGA_AGC_NG_THR_N63DB 0x4 -#define RK616_PGA_AGC_NG_THR_N57DB 0x3 -#define RK616_PGA_AGC_NG_THR_N51DB 0x2 -#define RK616_PGA_AGC_NG_THR_N45DB 0x1 -#define RK616_PGA_AGC_NG_THR_N39DB 0x0 - -/* PGA AGC Control 4 (0xcc 0x10c) */ -#define RK616_PGA_AGC_ZO_MODE_MASK (0x1 << 5) -#define RK616_PGA_AGC_ZO_MODE_SFT 5 -#define RK616_PGA_AGC_ZO_MODE_UWRC (0x1 << 5) -#define RK616_PGA_AGC_ZO_MODE_UARC (0x0 << 5) - -#define RK616_PGA_AGC_VOL_MASK 0x1f -#define RK616_PGA_AGC_VOL_SFT 0 - -/* PGA ASR Control (0xd0 0x110) */ -#define RK616_PGA_SLOW_CLK_MASK (0x1 << 3) -#define RK616_PGA_SLOW_CLK_SFT 3 -#define RK616_PGA_SLOW_CLK_EN (0x1 << 3) -#define RK616_PGA_SLOW_CLK_DIS (0x0 << 3) - -#define RK616_PGA_ASR_MASK 0x7 -#define RK616_PGA_ASR_SFT 0 -#define RK616_PGA_ASR_8KHz 0x5 -#define RK616_PGA_ASR_12KHz 0x4 -#define RK616_PGA_ASR_16KHz 0x3 -#define RK616_PGA_ASR_24KHz 0x2 -#define RK616_PGA_ASR_32KHz 0x1 -#define RK616_PGA_ASR_48KHz 0x0 - -/* PGA AGC Control 5 (0xe4 0x124) */ -#define RK616_PGA_AGC_MASK (0x1 << 6) -#define RK616_PGA_AGC_SFT 6 -#define RK616_PGA_AGC_EN (0x1 << 6) -#define RK616_PGA_AGC_DIS (0x0 << 6) - -#define RK616_PGA_AGC_MAX_G_MASK (0x7 << 3) -#define RK616_PGA_AGC_MAX_G_SFT 3 -#define RK616_PGA_AGC_MAX_G_28_5DB (0x7 << 3) -#define RK616_PGA_AGC_MAX_G_22_5DB (0x6 << 3) -#define RK616_PGA_AGC_MAX_G_16_5DB (0x5 << 3) -#define RK616_PGA_AGC_MAX_G_10_5DB (0x4 << 3) -#define RK616_PGA_AGC_MAX_G_4_5DB (0x3 << 3) -#define RK616_PGA_AGC_MAX_G_N1_5DB (0x2 << 3) -#define RK616_PGA_AGC_MAX_G_N7_5DB (0x1 << 3) -#define RK616_PGA_AGC_MAX_G_N13_5DB (0x0 << 3) - -#define RK616_PGA_AGC_MIN_G_MASK 0x7 -#define RK616_PGA_AGC_MIN_G_SFT 0 -#define RK616_PGA_AGC_MIN_G_24DB 0x7 -#define RK616_PGA_AGC_MIN_G_18DB 0x6 -#define RK616_PGA_AGC_MIN_G_12DB 0x5 -#define RK616_PGA_AGC_MIN_G_6DB 0x4 -#define RK616_PGA_AGC_MIN_G_0DB 0x3 -#define RK616_PGA_AGC_MIN_G_N6DB 0x2 -#define RK616_PGA_AGC_MIN_G_N12DB 0x1 -#define RK616_PGA_AGC_MIN_G_N18DB 0x0 - -enum { - RK616_HIFI, - RK616_VOICE, -}; - -enum { - RK616_MONO = 1, - RK616_STEREO, -}; - -enum { - OFF, - RCV, - SPK_PATH, - HP_PATH, - HP_NO_MIC, - BT, - SPK_HP, - RING_SPK, - RING_HP, - RING_HP_NO_MIC, - RING_SPK_HP, -}; - -enum { - MIC_OFF, - MAIN_MIC, - HANDS_FREE_MIC, - BT_SCO_MIC, -}; - -struct rk616_reg_val_typ { - unsigned int reg; - unsigned int value; -}; - -struct rk616_init_bit_typ { - unsigned int reg; - unsigned int power_bit; - unsigned int init_bit; -}; - -bool rk616_get_for_mid(void); - -#ifdef CONFIG_HDMI -extern int hdmi_is_insert(void); -#endif - -#ifdef CONFIG_HDMI_RK30 -extern int hdmi_get_hotplug(void); -#endif - -#endif /* __RK616_CODEC_H__ */ diff --git a/sound/soc/codecs/rt3261-dsp.c b/sound/soc/codecs/rt3261-dsp.c deleted file mode 100644 index e4468bd211d9..000000000000 --- a/sound/soc/codecs/rt3261-dsp.c +++ /dev/null @@ -1,1299 +0,0 @@ -/* - * rt3261.c -- RT3261 ALSA SoC DSP driver - * - * Copyright 2011 Realtek Semiconductor Corp. - * Author: Johnny Hsu - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include - -#define RTK_IOCTL -#ifdef RTK_IOCTL -#include -#include "rt_codec_ioctl.h" -#endif - -#include "rt3261.h" -#include "rt3261-dsp.h" - -#define INIT_DSP_IN_PROBE - -static const u16 rt3261_dsp_init[][2] = { - {0x3fd2, 0x0038}, {0x229C, 0x0fa0}, {0x22d2, 0x8400}, {0x22ee, 0x0000}, - {0x22f2, 0x0040}, {0x22f5, 0x8000}, {0x22f6, 0x0000}, {0x22f9, 0x007f}, - {0x2310, 0x0880}, -}; -#define RT3261_DSP_INIT_NUM \ - (sizeof(rt3261_dsp_init) / sizeof(rt3261_dsp_init[0])) - -static const u16 rt3261_dsp_48[][2] = { - {0x22c8, 0x0026}, {0x22fe, 0x0fa0}, {0x22ff, 0x3893}, {0x22fa, 0x2487}, - {0x2301, 0x0002}, -}; -#define RT3261_DSP_48_NUM (sizeof(rt3261_dsp_48) / sizeof(rt3261_dsp_48[0])) - -static const u16 rt3261_dsp_441[][2] = { - {0x22c6, 0x0031}, {0x22c7, 0x0050}, {0x22c8, 0x0009}, {0x22fe, 0x0e5b}, - {0x22ff, 0x3883}, {0x22fa, 0x2484}, {0x2301, 0x0001}, -}; -#define RT3261_DSP_441_NUM (sizeof(rt3261_dsp_441) / sizeof(rt3261_dsp_441[0])) - -static const u16 rt3261_dsp_16[][2] = { - {0x22c8, 0x0026}, {0x22fa, 0x2484}, {0x2301, 0x0002}, -}; -#define RT3261_DSP_16_NUM (sizeof(rt3261_dsp_16) / sizeof(rt3261_dsp_16[0])) - -static const u16 rt3261_dsp_rate_tab[] = { - 0x22c6, 0x22c7, 0x22c8, 0x22fe, 0x22ff, 0x22fa, 0x2301, -}; -#define RT3261_DSP_RATE_NUM (sizeof(rt3261_dsp_rate_tab) / sizeof(rt3261_dsp_rate_tab[0])) - -static const u16 rt3261_dsp_aec_ns_fens[][2] = { - {0x22F8, 0x8005}, - {0x2309, 0x0400}, - {0x2310, 0x0824}, - {0x2332, 0x0080}, - {0x2348, 0x1000}, - {0x2362, 0x0180}, - {0x236E, 0x1800}, - {0x2373, 0x3000}, - {0x2381, 0x4000}, - {0x2398, 0x0020}, - {0x23B4, 0x0012}, - {0x23BD, 0x0100}, - {0x23D1, 0xFF80}, - {0x23D5, 0x7FFF}, - {0x2303, 0x0931}, - {0x2333, 0x0008}, - {0x2349, 0x6800}, - {0x2363, 0x0100}, - {0x236F, 0x0A0A}, - {0x2374, 0x2400}, - {0x2382, 0x0400}, - {0x238C, 0x0400}, - {0x23A5, 0x0006}, - {0x23B7, 0x0008}, - {0x23BE, 0x2400}, - {0x23D2, 0xFF80}, - {0x23ED, 0x0300}, - {0x2304, 0xC31F}, - {0x230C, 0x0900}, - {0x2337, 0x0002}, - {0x2360, 0x0080}, - {0x2364, 0x0078}, - {0x2370, 0x0F00}, - {0x2375, 0x1800}, - {0x2383, 0x0400}, - {0x2396, 0x2000}, - {0x23A6, 0x7FFF}, - {0x23BB, 0x1000}, - {0x23CF, 0x7FFF}, - {0x2305, 0x0005}, - {0x232F, 0x0080}, - {0x2339, 0x0010}, - {0x2361, 0x1800}, - {0x2380, 0x7FFF}, - {0x2384, 0x0005}, - {0x23B3, 0x0018}, - {0x23BC, 0x0130}, - {0x2328, 0x7FFF}, - {0x233A, 0x7FFF}, - {0x233B, 0x7FFF}, - {0x233C, 0x7FFF}, - {0x2302, 0x0101}, - {0x22F2, 0x0040}, - {0x230A, 0x1B00}, - {0x22FB, 0x0000}, -}; - -#define RT3261_DSP_AEC_NUM \ - (sizeof(rt3261_dsp_aec_ns_fens) / sizeof(rt3261_dsp_aec_ns_fens[0])) -static const u16 rt3261_dsp_hfbf[][2] = { - {0x22f8, 0x8004}, {0x22a0, 0x1205}, {0x22a1, 0x0f00}, {0x22a2, 0x1000}, - {0x22a3, 0x1000}, {0x22a4, 0x1000}, {0x22aa, 0x0006}, {0x22ad, 0x0060}, - {0x22ae, 0x0080}, {0x22af, 0x0000}, {0x22b0, 0x000e}, {0x22b1, 0x0010}, - {0x22b2, 0x0006}, {0x22b3, 0x0001}, {0x22b4, 0x0010}, {0x22b5, 0x0001}, - {0x22b7, 0x0005}, {0x22d8, 0x0017}, {0x22f9, 0x007f}, {0x2303, 0x0971}, - {0x2304, 0x0302}, {0x2303, 0x0971}, {0x2304, 0x4302}, {0x2305, 0x102d}, - {0x2309, 0x0400}, {0x230c, 0x0400}, {0x230d, 0x0200}, {0x232f, 0x0020}, - {0x2332, 0x0100}, {0x2333, 0x0020}, {0x2337, 0xffff}, {0x2339, 0x0010}, - {0x2348, 0x1000}, {0x2349, 0x1000}, {0x236e, 0x1800}, {0x236f, 0x1006}, - {0x2370, 0x1000}, {0x2372, 0x0200}, {0x237b, 0x001e}, {0x2380, 0x7fff}, - {0x2381, 0x4000}, {0x2382, 0x0080}, {0x2383, 0x0200}, {0x2386, 0x7f80}, - {0x2387, 0x0040}, {0x238a, 0x0280}, {0x238c, 0x6000}, {0x238e, 0x5000}, - {0x2396, 0x6a00}, {0x2397, 0x6000}, {0x2398, 0x00e0}, {0x23a5, 0x0005}, - {0x23b3, 0x000f}, {0x23b4, 0x0003}, {0x23bb, 0x2000}, {0x23bc, 0x00d0}, - {0x23bd, 0x0140}, {0x23be, 0x1000}, {0x23cf, 0x0800}, {0x23d0, 0x0400}, - {0x23d1, 0x0100}, {0x23d2, 0x0100}, {0x23d5, 0x7c00}, {0x23ed, 0x0300}, - {0x23ee, 0x3000}, {0x23ef, 0x2800}, {0x22fb, 0x0000}, -}; -#define RT3261_DSP_HFBF_NUM \ - (sizeof(rt3261_dsp_hfbf) / sizeof(rt3261_dsp_hfbf[0])) - -static const u16 rt3261_dsp_ffp[][2] = { - {0x22f8, 0x8005}, {0x2303, 0x1971}, {0x2304, 0x8312}, {0x2305, 0x0005}, - {0x2309, 0x0200}, {0x230a, 0x1b00}, {0x230c, 0x0800}, {0x230d, 0x0400}, - {0x2325, 0x5000}, {0x2326, 0x0040}, {0x232f, 0x0080}, {0x2332, 0x0100}, - {0x2333, 0x0020}, {0x2337, 0x0001}, {0x2339, 0x0010}, {0x233c, 0x0040}, - {0x2348, 0x1000}, {0x2349, 0x1000}, {0x2360, 0x0180}, {0x2361, 0x1800}, - {0x2362, 0x0200}, {0x2363, 0x0200}, {0x2364, 0x0200}, {0x2365, 0x2000}, - {0x236e, 0x1000}, {0x236f, 0x0a05}, {0x2370, 0x0f00}, {0x2372, 0x1a00}, - {0x2373, 0x3000}, {0x2374, 0x2400}, {0x2375, 0x1800}, {0x2380, 0x7fff}, - {0x2381, 0x4000}, {0x2382, 0x0400}, {0x2383, 0x0400}, {0x2384, 0x0005}, - {0x2385, 0x0005}, {0x238e, 0x7000}, {0x2393, 0x4444}, {0x2394, 0x4444}, - {0x2395, 0x4444}, {0x2396, 0x2000}, {0x2397, 0x3000}, {0x2398, 0x0020}, - {0x23a5, 0x0006}, {0x23a6, 0x7fff}, {0x23b3, 0x000a}, {0x23b4, 0x0006}, - {0x23b7, 0x0008}, {0x23bb, 0x1000}, {0x23bc, 0x0130}, {0x23bd, 0x0160}, - {0x23be, 0x2400}, {0x23cf, 0x0800}, {0x23d0, 0x0400}, {0x23d1, 0xff80}, - {0x23d2, 0xff80}, {0x23d3, 0x2000}, {0x23d4, 0x5000}, {0x23d5, 0x5000}, - {0x23e7, 0x0c00}, {0x23e8, 0x1400}, {0x23e9, 0x6000}, {0x23ea, 0x7f00}, - {0x23ed, 0x0300}, {0x23ee, 0x2800}, {0x22fb, 0x0000}, -}; -#define RT3261_DSP_FFP_NUM (sizeof(rt3261_dsp_ffp) / sizeof(rt3261_dsp_ffp[0])) - -static const u16 rt3261_dsp_p3_tab[][3] = { - {0x4af0, 0x1000, 0x822b}, {0x90f0, 0x1001, 0x8393}, - {0x64f0, 0x1002, 0x822b}, {0x0ff0, 0x1003, 0x26e0}, - {0x55f0, 0x1004, 0x2200}, {0xcff0, 0x1005, 0x1a7b}, - {0x5af0, 0x1006, 0x823a}, {0x90f0, 0x1007, 0x8393}, - {0x64f0, 0x1008, 0x822b}, {0x0ff0, 0x1009, 0x26e0}, - {0x03f0, 0x100a, 0x2218}, {0x0ef0, 0x100b, 0x3400}, - {0x4ff0, 0x100c, 0x195e}, {0x00f0, 0x100d, 0x0000}, - {0xf0f0, 0x100e, 0x8143}, {0x1ff0, 0x100f, 0x2788}, - {0x0ef0, 0x1010, 0x3400}, {0xe0f0, 0x1011, 0x1a26}, - {0x2cf0, 0x1012, 0x8001}, {0x0ff0, 0x1013, 0x267c}, - {0x82f0, 0x1014, 0x1a27}, {0x3cf0, 0x1015, 0x8001}, - {0x0ff0, 0x1016, 0x267c}, {0x82f0, 0x1017, 0x1a27}, - {0xeff0, 0x1018, 0x1a26}, {0x01f0, 0x1019, 0x4ff0}, - {0x5cf0, 0x101a, 0x2b81}, {0xfaf0, 0x101b, 0x2a6a}, - {0x05f0, 0x101c, 0x4011}, {0x0ff0, 0x101d, 0x278e}, - {0x0ef0, 0x101e, 0x3400}, {0xe1f0, 0x101f, 0x1997}, - {0x1ff0, 0x1020, 0x1997}, {0x03f0, 0x1021, 0x2279}, - {0xb8f0, 0x1022, 0x8206}, {0xf8f0, 0x1023, 0x0f00}, - {0xfff0, 0x1024, 0x279e}, {0x0ff0, 0x1025, 0x2272}, - {0x0ef0, 0x1026, 0x3400}, {0x3ff0, 0x1027, 0x199a}, - {0x0ff0, 0x1028, 0x2262}, {0x0ff0, 0x1029, 0x2272}, - {0x0ef0, 0x102a, 0x3400}, {0xfff0, 0x102b, 0x199a}, - {0x7ff0, 0x102c, 0x22e2}, {0x0ef0, 0x102d, 0x3400}, - {0xfff0, 0x102e, 0x19cb}, {0xfff0, 0x102f, 0x47ff}, - {0xb1f0, 0x1030, 0x80b1}, {0x5ff0, 0x1031, 0x2261}, - {0x62f0, 0x1032, 0x1903}, {0x9af0, 0x1033, 0x0d00}, - {0xcff0, 0x1034, 0x80b1}, {0x0ff0, 0x1035, 0x0e27}, - {0x8ff0, 0x1036, 0x9229}, {0x0ef0, 0x1037, 0x3400}, - {0xaff0, 0x1038, 0x19f5}, {0x81f0, 0x1039, 0x8229}, - {0x0ef0, 0x103a, 0x3400}, {0xfff0, 0x103b, 0x19f6}, - {0x5af0, 0x103c, 0x8234}, {0xeaf0, 0x103d, 0x9113}, - {0x0ef0, 0x103e, 0x3400}, {0x7ff0, 0x103f, 0x19ea}, - {0x8af0, 0x1040, 0x924d}, {0x08f0, 0x1041, 0x3400}, - {0x3ff0, 0x1042, 0x1a74}, {0x00f0, 0x1043, 0x0000}, - {0x00f0, 0x1044, 0x0000}, {0x00f0, 0x1045, 0x0c38}, - {0x0ff0, 0x1046, 0x2618}, {0xb0f0, 0x1047, 0x8148}, - {0x01f0, 0x1048, 0x3700}, {0x02f0, 0x1049, 0x3a70}, - {0x03f0, 0x104a, 0x3a78}, {0x9af0, 0x104b, 0x8229}, - {0xd6f0, 0x104c, 0x47c4}, {0x95f0, 0x104d, 0x4361}, - {0x0ff0, 0x104e, 0x2082}, {0x76f0, 0x104f, 0x626b}, - {0x0ff0, 0x1050, 0x208a}, {0x0ff0, 0x1051, 0x204a}, - {0xc9f0, 0x1052, 0x7882}, {0x75f0, 0x1053, 0x626b}, - {0x0ff0, 0x1054, 0x208a}, {0x0ff0, 0x1055, 0x204a}, - {0xcdf0, 0x1056, 0x7882}, {0x0ff0, 0x1057, 0x2630}, - {0x8af0, 0x1058, 0x2b30}, {0xf4f0, 0x1059, 0x1904}, - {0x98f0, 0x105a, 0x9229}, {0x0ef0, 0x105b, 0x3400}, - {0xeff0, 0x105c, 0x19fd}, {0xd7f0, 0x105d, 0x40cc}, - {0x0ef0, 0x105e, 0x3400}, {0xdff0, 0x105f, 0x1a44}, - {0x00f0, 0x1060, 0x0000}, {0xcef0, 0x1061, 0x1507}, - {0x90f0, 0x1062, 0x1020}, {0x5ff0, 0x1063, 0x1006}, - {0x89f0, 0x1064, 0x608f}, {0x0ff0, 0x1065, 0x0e64}, - {0x49f0, 0x1066, 0x1044}, {0xcff0, 0x1067, 0x2b28}, - {0x93f0, 0x1068, 0x2a62}, {0x5ff0, 0x1069, 0x266a}, - {0x54f0, 0x106a, 0x22a8}, {0x0af0, 0x106b, 0x0f22}, - {0xfbf0, 0x106c, 0x0f0c}, {0x5ff0, 0x106d, 0x0d00}, - {0x90f0, 0x106e, 0x1020}, {0x4ff0, 0x106f, 0x1006}, - {0x8df0, 0x1070, 0x6087}, {0x0ff0, 0x1071, 0x0e64}, - {0xb9f0, 0x1072, 0x1044}, {0xcff0, 0x1073, 0x2a63}, - {0x5ff0, 0x1074, 0x266a}, {0x54f0, 0x1075, 0x22a8}, - {0x0af0, 0x1076, 0x0f22}, {0xfbf0, 0x1077, 0x0f0c}, - {0x93f0, 0x1078, 0x2aef}, {0x0ff0, 0x1079, 0x227a}, - {0xc2f0, 0x107a, 0x1907}, {0xf5f0, 0x107b, 0x0d00}, - {0xfdf0, 0x107c, 0x7800}, {0x0ef0, 0x107d, 0x3400}, - {0xaff0, 0x107e, 0x1899}, -}; -#define RT3261_DSP_PATCH3_NUM \ - (sizeof(rt3261_dsp_p3_tab) / sizeof(rt3261_dsp_p3_tab[0])) - -static const u16 rt3261_dsp_p2_tab[][2] = { - {0x3fa1, 0xe7bb}, {0x3fb1, 0x5000}, {0x3fa2, 0xa26b}, {0x3fb2, 0x500e}, - {0x3fa3, 0xa27c}, {0x3fb3, 0x2282}, {0x3fa4, 0x996e}, {0x3fb4, 0x5019}, - {0x3fa5, 0x99a2}, {0x3fb5, 0x5021}, {0x3fa6, 0x99ae}, {0x3fb6, 0x5028}, - {0x3fa7, 0x9cbb}, {0x3fb7, 0x502c}, {0x3fa8, 0x9900}, {0x3fb8, 0x1903}, - {0x3fa9, 0x9f59}, {0x3fb9, 0x502f}, {0x3faa, 0x9f6e}, {0x3fba, 0x5039}, - {0x3fab, 0x9ea2}, {0x3fbb, 0x503c}, {0x3fac, 0x9fc8}, {0x3fbc, 0x5045}, - {0x3fad, 0xa44c}, {0x3fbd, 0x505d}, {0x3fae, 0x8983}, {0x3fbe, 0x5061}, - {0x3faf, 0x95e3}, {0x3fbf, 0x5006}, {0x3fa0, 0xe742}, {0x3fb0, 0x5040}, -}; -#define RT3261_DSP_PATCH2_NUM \ - (sizeof(rt3261_dsp_p2_tab) / sizeof(rt3261_dsp_p2_tab[0])) - -/** - * rt3261_dsp_done - Wait until DSP is ready. - * @codec: SoC Audio Codec device. - * - * To check voice DSP status and confirm it's ready for next work. - * - * Returns 0 for success or negative error code. - */ -static int rt3261_dsp_done(struct snd_soc_codec *codec) -{ - unsigned int count = 0, dsp_val; - - dsp_val = snd_soc_read(codec, RT3261_DSP_CTRL3); - while(dsp_val & RT3261_DSP_BUSY_MASK) { - if(count > 10) - return -EBUSY; - dsp_val = snd_soc_read(codec, RT3261_DSP_CTRL3); - count ++; - } - - return 0; -} - - -/** - * rt3261_dsp_write - Write DSP register. - * @codec: SoC audio codec device. - * @param: DSP parameters. - * - * Modify voice DSP register for sound effect. The DSP can be controlled - * through DSP command format (0xfc), addr (0xc4), data (0xc5) and cmd (0xc6) - * register. It has to wait until the DSP is ready. - * - * Returns 0 for success or negative error code. - */ -int rt3261_dsp_write(struct snd_soc_codec *codec, - struct rt3261_dsp_param *param) -{ - unsigned int dsp_val = snd_soc_read(codec, RT3261_DSP_CTRL3); - int ret; - - ret = rt3261_dsp_done(codec); - if (ret < 0) { - dev_err(codec->dev, "DSP is busy: %d\n", ret); - goto err; - } - ret = snd_soc_write(codec, RT3261_GEN_CTRL3, param->cmd_fmt); - if (ret < 0) { - dev_err(codec->dev, "Failed to write cmd format: %d\n", ret); - goto err; - } - ret = snd_soc_write(codec, RT3261_DSP_CTRL1, param->addr); - if (ret < 0) { - dev_err(codec->dev, "Failed to write DSP addr reg: %d\n", ret); - goto err; - } - ret = snd_soc_write(codec, RT3261_DSP_CTRL2, param->data); - if (ret < 0) { - dev_err(codec->dev, "Failed to write DSP data reg: %d\n", ret); - goto err; - } - dsp_val &= ~(RT3261_DSP_R_EN | RT3261_DSP_CMD_MASK); - dsp_val |= RT3261_DSP_W_EN | param->cmd; - ret = snd_soc_write(codec, RT3261_DSP_CTRL3, dsp_val); - if (ret < 0) { - dev_err(codec->dev, "Failed to write DSP cmd reg: %d\n", ret); - goto err; - } - //mdelay(10); - return 0; - -err: - return ret; -} - -EXPORT_SYMBOL_GPL(rt3261_dsp_write); - -/** - * rt3261_dsp_read - Read DSP register. - * @codec: SoC audio codec device. - * @reg: DSP register index. - * - * Read DSP setting value from voice DSP. The DSP can be controlled - * through DSP addr (0xc4), data (0xc5) and cmd (0xc6) register. Each - * command has to wait until the DSP is ready. - * - * Returns DSP register value or negative error code. - */ -unsigned int rt3261_dsp_read( - struct snd_soc_codec *codec, unsigned int reg) -{ - unsigned int val_h, val_l, value; - unsigned int dsp_val = snd_soc_read(codec, RT3261_DSP_CTRL3); - int ret = 0; - - ret = rt3261_dsp_done(codec); - if (ret < 0) { - dev_err(codec->dev, "DSP is busy: %d\n", ret); - goto err; - } - ret = snd_soc_write(codec, RT3261_GEN_CTRL3, 0); - if (ret < 0) { - dev_err(codec->dev, "Failed to write fc = 0: %d\n", ret); - goto err; - } - ret = snd_soc_write(codec, RT3261_DSP_CTRL1, reg); - if (ret < 0) { - dev_err(codec->dev, "Failed to write DSP addr reg: %d\n", ret); - goto err; - } - dsp_val &= ~(RT3261_DSP_W_EN | RT3261_DSP_CMD_MASK); - dsp_val |= RT3261_DSP_R_EN | RT3261_DSP_CMD_MR; - ret = snd_soc_write(codec, RT3261_DSP_CTRL3, dsp_val); - if (ret < 0) { - dev_err(codec->dev, "Failed to write DSP cmd reg: %d\n", ret); - goto err; - } - - /* Read DSP high byte data */ - ret = rt3261_dsp_done(codec); - if (ret < 0) { - dev_err(codec->dev, "DSP is busy: %d\n", ret); - goto err; - } - ret = snd_soc_write(codec, RT3261_DSP_CTRL1, RT3261_DSP_REG_DATHI); - if (ret < 0) { - dev_err(codec->dev, "Failed to write DSP addr reg: %d\n", ret); - goto err; - } - dsp_val &= ~(RT3261_DSP_W_EN | RT3261_DSP_CMD_MASK); - dsp_val |= RT3261_DSP_R_EN | RT3261_DSP_CMD_RR; - ret = snd_soc_write(codec, RT3261_DSP_CTRL3, dsp_val); - if (ret < 0) { - dev_err(codec->dev, "Failed to write DSP cmd reg: %d\n", ret); - goto err; - } - ret = rt3261_dsp_done(codec); - if (ret < 0) { - dev_err(codec->dev, "DSP is busy: %d\n", ret); - goto err; - } - ret = snd_soc_read(codec, RT3261_DSP_CTRL2); - if (ret < 0) { - dev_err(codec->dev, "Failed to read DSP data reg: %d\n", ret); - goto err; - } - val_h = ret; - - /* Read DSP low byte data */ - ret = snd_soc_write(codec, RT3261_DSP_CTRL1, RT3261_DSP_REG_DATLO); - if (ret < 0) { - dev_err(codec->dev, "Failed to write DSP addr reg: %d\n", ret); - goto err; - } - ret = snd_soc_write(codec, RT3261_DSP_CTRL3, dsp_val); - if (ret < 0) { - dev_err(codec->dev, "Failed to write DSP cmd reg: %d\n", ret); - goto err; - } - ret = rt3261_dsp_done(codec); - if (ret < 0) { - dev_err(codec->dev, "DSP is busy: %d\n", ret); - goto err; - } - ret = snd_soc_read(codec, RT3261_DSP_CTRL2); - if (ret < 0) { - dev_err(codec->dev, "Failed to read DSP data reg: %d\n", ret); - goto err; - } - val_l = ret; - - value = ((val_h & 0xff) << 8) |(val_l & 0xff); - return value; - -err: - return ret; -} -EXPORT_SYMBOL_GPL(rt3261_dsp_read); - -static int rt3261_dsp_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct rt3261_priv *rt3261 = snd_soc_codec_get_drvdata(codec); - - ucontrol->value.integer.value[0] = rt3261->dsp_sw; - - return 0; -} - -static int rt3261_dsp_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct rt3261_priv *rt3261 = snd_soc_codec_get_drvdata(codec); - - if (rt3261->dsp_sw != ucontrol->value.integer.value[0]) - rt3261->dsp_sw = ucontrol->value.integer.value[0]; - - return 0; -} - -/* DSP Path Control 1 */ -static const char *rt3261_src_rxdp_mode[] = { - "Normal", "Divided by 3"}; - -static const SOC_ENUM_SINGLE_DECL( - rt3261_src_rxdp_enum, RT3261_DSP_PATH1, - RT3261_RXDP_SRC_SFT, rt3261_src_rxdp_mode); - -static const char *rt3261_src_txdp_mode[] = { - "Normal", "Multiplied by 3"}; - -static const SOC_ENUM_SINGLE_DECL( - rt3261_src_txdp_enum, RT3261_DSP_PATH1, - RT3261_TXDP_SRC_SFT, rt3261_src_txdp_mode); - -/* DSP data select */ -static const char *rt3261_dsp_data_select[] = { - "Normal", "left copy to right", "right copy to left", "Swap"}; - -static const SOC_ENUM_SINGLE_DECL(rt3261_rxdc_data_enum, RT3261_DSP_PATH2, - RT3261_RXDC_SEL_SFT, rt3261_dsp_data_select); - -static const SOC_ENUM_SINGLE_DECL(rt3261_rxdp_data_enum, RT3261_DSP_PATH2, - RT3261_RXDP_SEL_SFT, rt3261_dsp_data_select); - -static const SOC_ENUM_SINGLE_DECL(rt3261_txdc_data_enum, RT3261_DSP_PATH2, - RT3261_TXDC_SEL_SFT, rt3261_dsp_data_select); - -static const SOC_ENUM_SINGLE_DECL(rt3261_txdp_data_enum, RT3261_DSP_PATH2, - RT3261_TXDP_SEL_SFT, rt3261_dsp_data_select); - -/* Sound Effect */ -static const char *rt3261_dsp_mode[] = { - "Disable", "AEC+NS+FENS", "HFBF", "Far Field Pick-up"}; - -static const SOC_ENUM_SINGLE_DECL(rt3261_dsp_enum, 0, 0, rt3261_dsp_mode); - -static const char *rt3261_rxdp2_src[] = - {"IF2_DAC", "Stereo_ADC"}; - -static const SOC_ENUM_SINGLE_DECL( - rt3261_rxdp2_enum, RT3261_GEN_CTRL2, - RT3261_RXDP2_SEL_SFT, rt3261_rxdp2_src); - -static const struct snd_kcontrol_new rt3261_rxdp2_mux = - SOC_DAPM_ENUM("RxDP2 sel", rt3261_rxdp2_enum); - -static const char *rt3261_rxdp_src[] = - {"RxDP2", "RxDP1"}; - -static const SOC_ENUM_SINGLE_DECL( - rt3261_rxdp_enum, RT3261_DUMMY_PR3F, - 10, rt3261_rxdp_src); - -static const struct snd_kcontrol_new rt3261_rxdp_mux = - SOC_DAPM_ENUM("RxDP sel", rt3261_rxdp_enum); - -static const char *rt3261_rxdc_src[] = - {"Mono_ADC", "Stereo_ADC"}; - -static const SOC_ENUM_SINGLE_DECL( - rt3261_rxdc_enum, RT3261_GEN_CTRL2, - RT3261_RXDC_SRC_SFT, rt3261_rxdc_src); - -static const struct snd_kcontrol_new rt3261_rxdc_mux = - SOC_DAPM_ENUM("RxDC sel", rt3261_rxdc_enum); - -static const char *rt3261_rxdp1_src[] = - {"DAC1", "IF1_DAC"}; - -static const SOC_ENUM_SINGLE_DECL( - rt3261_rxdp1_enum, RT3261_DUMMY_PR3F, - 9, rt3261_rxdp1_src); - -static const struct snd_kcontrol_new rt3261_rxdp1_mux = - SOC_DAPM_ENUM("RxDP1 sel", rt3261_rxdp1_enum); - -static const struct snd_kcontrol_new rt3261_dsp_snd_controls[] = { - SOC_ENUM("RxDC input data", rt3261_rxdc_data_enum), - SOC_ENUM("RxDP input data", rt3261_rxdp_data_enum), - SOC_ENUM("TxDC input data", rt3261_txdc_data_enum), - SOC_ENUM("TxDP input data", rt3261_txdp_data_enum), - SOC_ENUM("SRC for RxDP", rt3261_src_rxdp_enum), - SOC_ENUM("SRC for TxDP", rt3261_src_txdp_enum), - /* AEC */ - SOC_ENUM_EXT("DSP Function Switch", rt3261_dsp_enum, - rt3261_dsp_get, rt3261_dsp_put), -}; - -/*static int rt3261_dsp_patch_3(struct snd_soc_codec *codec) -{ - struct rt3261_dsp_param param; - int ret, i; - - param.cmd_fmt = 0x0090; - param.addr = 0x0064; - param.data = 0x0004; - param.cmd = RT3261_DSP_CMD_RW; - ret = rt3261_dsp_write(codec, ¶m); - if (ret < 0) { - dev_err(codec->dev, - "Fail to set DSP 3 bytes patch entrance: %d\n", ret); - goto patch_err; - } - - param.cmd = RT3261_DSP_CMD_PE; - for(i = 0; i < RT3261_DSP_PATCH3_NUM; i++) { - param.cmd_fmt = rt3261_dsp_p3_tab[i][0]; - param.addr = rt3261_dsp_p3_tab[i][1]; - param.data = rt3261_dsp_p3_tab[i][2]; - ret = rt3261_dsp_write(codec, ¶m); - if (ret < 0) { - dev_err(codec->dev, "Fail to patch Dsp: %d\n", ret); - goto patch_err; - } - } - - return 0; - -patch_err: - - return ret; -} - -static int rt3261_dsp_patch_2(struct snd_soc_codec *codec) -{ - struct rt3261_dsp_param param; - int ret, i; - - param.cmd_fmt = 0x0090; - param.addr = 0x0064; - param.data = 0x0000; - param.cmd = RT3261_DSP_CMD_RW; - ret = rt3261_dsp_write(codec, ¶m); - if (ret < 0) { - dev_err(codec->dev, - "Fail to set DSP 2 bytes patch entrance: %d\n", ret); - goto patch_err; - } - - param.cmd_fmt = 0x00e0; - param.cmd = RT3261_DSP_CMD_MW; - for(i = 0; i < RT3261_DSP_PATCH2_NUM; i++) { - param.addr = rt3261_dsp_p2_tab[i][0]; - param.data = rt3261_dsp_p2_tab[i][1]; - ret = rt3261_dsp_write(codec, ¶m); - if (ret < 0) { - dev_err(codec->dev, "Fail to patch Dsp: %d\n", ret); - goto patch_err; - } - } - - return 0; - -patch_err: - - return ret; -}*/ - -/** - * rt3261_dsp_patch - Write DSP patch code. - * - * @codec: SoC audio codec device. - * - * Write patch codes to DSP including 3 and 2 bytes data. - * - * Returns 0 for success or negative error code. - */ -/*static int rt3261_dsp_patch(struct snd_soc_codec *codec) -{ - int ret; - - dev_dbg(codec->dev, "\n DSP Patch Start ......\n"); - - ret = snd_soc_update_bits(codec, RT3261_MICBIAS, - RT3261_PWR_CLK25M_MASK, RT3261_PWR_CLK25M_PU); - if (ret < 0) - goto patch_err; - - ret = snd_soc_update_bits(codec, RT3261_GLB_CLK, - RT3261_SCLK_SRC_MASK, RT3261_SCLK_SRC_RCCLK); - if (ret < 0) - goto patch_err; - - ret = snd_soc_update_bits(codec, RT3261_PWR_DIG2, - RT3261_PWR_I2S_DSP, RT3261_PWR_I2S_DSP); - if (ret < 0) - goto patch_err; - - ret = snd_soc_update_bits(codec, RT3261_DSP_CTRL3, - RT3261_DSP_PD_PIN_MASK, RT3261_DSP_PD_PIN_HI); - if (ret < 0) { - dev_err(codec->dev, "Failed to power up DSP: %d\n", ret); - goto patch_err; - } - - ret = snd_soc_update_bits(codec, RT3261_DSP_CTRL3, - RT3261_DSP_RST_PIN_MASK, RT3261_DSP_RST_PIN_LO); - if (ret < 0) { - dev_err(codec->dev, "Failed to reset DSP: %d\n", ret); - goto patch_err; - } - - mdelay(10); - - ret = snd_soc_update_bits(codec, RT3261_DSP_CTRL3, - RT3261_DSP_RST_PIN_MASK, RT3261_DSP_RST_PIN_HI); - if (ret < 0) { - dev_err(codec->dev, "Failed to recover DSP: %d\n", ret); - goto patch_err; - } - - ret = rt3261_dsp_patch_3(codec); - if (ret < 0) - goto patch_err; - - ret = rt3261_dsp_patch_2(codec); - if (ret < 0) - goto patch_err; - - return 0; - -patch_err: - - return ret; -} - -static void rt3261_do_dsp_patch(struct work_struct *work) -{ - struct rt3261_priv *rt3261 = - container_of(work, struct rt3261_priv, patch_work.work); - struct snd_soc_codec *codec = rt3261->codec; - - if (rt3261_dsp_patch(codec) < 0) - dev_err(codec->dev, "Patch DSP rom code Fail !!!\n"); -}*/ - - -/** - * rt3261_dsp_conf - Set DSP basic setting. - * - * @codec: SoC audio codec device. - * - * Set parameters of basic setting to DSP. - * - * Returns 0 for success or negative error code. - */ -static int rt3261_dsp_conf(struct snd_soc_codec *codec) -{ - struct rt3261_dsp_param param; - int ret, i; - - ret = snd_soc_update_bits(codec, RT3261_DSP_CTRL3, - RT3261_DSP_PD_PIN_MASK, RT3261_DSP_PD_PIN_HI); - if (ret < 0) { - dev_err(codec->dev, "Failed to power up DSP: %d\n", ret); - goto conf_err; - } - - ret = snd_soc_update_bits(codec, RT3261_DSP_CTRL3, - RT3261_DSP_RST_PIN_MASK, RT3261_DSP_RST_PIN_LO); - if (ret < 0) { - dev_err(codec->dev, "Failed to reset DSP: %d\n", ret); - goto conf_err; - } - - mdelay(10); - - ret = snd_soc_update_bits(codec, RT3261_DSP_CTRL3, - RT3261_DSP_RST_PIN_MASK | RT3261_DSP_CLK_MASK, - RT3261_DSP_RST_PIN_HI | RT3261_DSP_CLK_384K); - if (ret < 0) { - dev_err(codec->dev, "Failed to recover DSP: %d\n", ret); - goto conf_err; - } - - param.cmd_fmt = 0x00e0; - param.cmd = RT3261_DSP_CMD_MW; - for(i = 0; i < RT3261_DSP_INIT_NUM; i++) { - param.addr = rt3261_dsp_init[i][0]; - param.data = rt3261_dsp_init[i][1]; - ret = rt3261_dsp_write(codec, ¶m); - if (ret < 0) { - dev_err(codec->dev, "Fail to config Dsp: %d\n", ret); - goto conf_err; - } - } - - return 0; - -conf_err: - - return ret; -} - -/** - * rt3261_dsp_rate - Set DSP rate setting. - * - * @codec: SoC audio codec device. - * @rate: Sampling rate. - * - * Set parameters of sampling rate to DSP. - * - * Returns 0 for success or negative error code. - */ -static int rt3261_dsp_rate(struct snd_soc_codec *codec, int rate) -{ - struct rt3261_dsp_param param; - int ret, i, tab_num; - static const unsigned short (*rate_tab)[2]; - - if (rate != 48000 && rate != 44100 && rate != 16000) - return -EINVAL; - - if (rate > 44100) { - rate_tab = rt3261_dsp_48; - tab_num = RT3261_DSP_48_NUM; - } else { - if (rate > 16000) { - rate_tab = rt3261_dsp_441; - tab_num = RT3261_DSP_441_NUM; - } else { - rate_tab = rt3261_dsp_16; - tab_num = RT3261_DSP_16_NUM; - } - } - - param.cmd_fmt = 0x00e0; - param.cmd = RT3261_DSP_CMD_MW; - for (i = 0; i < tab_num; i++) { - param.addr = rate_tab[i][0]; - param.data = rate_tab[i][1]; - ret = rt3261_dsp_write(codec, ¶m); - if (ret < 0) - goto rate_err; - } - - return 0; - -rate_err: - - dev_err(codec->dev, "Fail to set rate %d parameters: %d\n", rate, ret); - return ret; -} - -/** - * rt3261_dsp_set_mode - Set DSP mode parameters. - * - * @codec: SoC audio codec device. - * @mode: DSP mode. - * - * Set parameters of mode to DSP. - * There are three modes which includes " mic AEC + NS + FENS", - * "HFBF" and "Far-field pickup". - * - * Returns 0 for success or negative error code. - */ -static int rt3261_dsp_set_mode(struct snd_soc_codec *codec, int mode) -{ - struct rt3261_dsp_param param; - int ret, i; -/* - unsigned short (*mode_tab)[2]; - - switch (mode) { - case RT3261_DSP_AEC_NS_FENS: - dev_info(codec->dev, "AEC\n"); - mode_tab = rt3261_dsp_aec_ns_fens; - tab_num = RT3261_DSP_AEC_NUM; - break; - - case RT3261_DSP_HFBF: - dev_info(codec->dev, "Beamforming\n"); - mode_tab = rt3261_dsp_hfbf; - tab_num = RT3261_DSP_HFBF_NUM; - break; - - case RT3261_DSP_FFP: - dev_info(codec->dev, "Far Field Pick-up\n"); - mode_tab = rt3261_dsp_ffp; - tab_num = RT3261_DSP_FFP_NUM; - break; - - case RT3261_DSP_DIS: - default: - dev_info(codec->dev, "Disable\n"); - return 0; - } -*/ - param.cmd_fmt = 0x00e0; - param.cmd = RT3261_DSP_CMD_MW; - for (i = 0; i < RT3261_DSP_AEC_NUM; i++) { - param.addr = rt3261_dsp_aec_ns_fens[i][0]; - param.data = rt3261_dsp_aec_ns_fens[i][1]; - ret = rt3261_dsp_write(codec, ¶m); - if (ret < 0) - goto mode_err; - } - - return 0; - -mode_err: - - dev_err(codec->dev, "Fail to set mode %d parameters: %d\n", mode, ret); - return ret; -} - -/** - * rt3261_dsp_snd_effect - Set DSP sound effect. - * - * Set parameters of sound effect to DSP. - * - * Returns 0 for success or negative error code. - */ -static int rt3261_dsp_snd_effect(struct snd_soc_codec *codec) -{ - struct rt3261_priv *rt3261 = snd_soc_codec_get_drvdata(codec); - int ret; - - ret = rt3261_dsp_conf(codec); - if (ret < 0) - goto effect_err; - - ret = rt3261_dsp_rate(codec, rt3261->lrck[rt3261->aif_pu] ? - rt3261->lrck[rt3261->aif_pu] : 44100); - if (ret < 0) - goto effect_err; - - ret = rt3261_dsp_set_mode(codec, rt3261->dsp_sw); - if (ret < 0) - goto effect_err; - - mdelay(20); - - return 0; - -effect_err: - - return ret; -} - -static int rt3261_dsp_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *k, int event) -{ - struct snd_soc_codec *codec = w->codec; - struct rt3261_priv *rt3261 = snd_soc_codec_get_drvdata(codec); - static unsigned int power_on; - - switch (event) { - case SND_SOC_DAPM_POST_PMD: - pr_info("%s(): PMD\n", __func__); - if (!power_on) - return 0; - - power_on--; - if (!power_on) { - snd_soc_update_bits(codec, RT3261_PWR_DIG2, - RT3261_PWR_I2S_DSP, 0); - snd_soc_update_bits(codec, RT3261_DSP_CTRL3, - RT3261_DSP_PD_PIN_MASK, RT3261_DSP_PD_PIN_LO); - } - break; - - case SND_SOC_DAPM_POST_PMU: - pr_info("%s(): PMU\n", __func__); - if (rt3261->dsp_sw == RT3261_DSP_DIS || 2 <= power_on) - return 0; - - if (!power_on) { - snd_soc_update_bits(codec, RT3261_PWR_DIG2, - RT3261_PWR_I2S_DSP, RT3261_PWR_I2S_DSP); -#ifdef INIT_DSP_IN_PROBE - snd_soc_update_bits(codec, RT3261_DSP_CTRL3, - RT3261_DSP_PD_PIN_MASK, RT3261_DSP_PD_PIN_HI); -#else - rt3261_dsp_snd_effect(codec); -#endif - } - power_on++; - break; - - default: - return 0; - } - - return 0; -} - -static const struct snd_soc_dapm_widget rt3261_dsp_dapm_widgets[] = { - SND_SOC_DAPM_PGA_E("DSP Downstream", SND_SOC_NOPM, - 0, 0, NULL, 0, rt3261_dsp_event, - SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU), - SND_SOC_DAPM_PGA_E("DSP Upstream", SND_SOC_NOPM, - 0, 0, NULL, 0, rt3261_dsp_event, - SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU), - SND_SOC_DAPM_MUX("RxDP Mux", SND_SOC_NOPM, 0, 0, - &rt3261_rxdp_mux), - SND_SOC_DAPM_MUX("RxDP2 Mux", SND_SOC_NOPM, 0, 0, - &rt3261_rxdp2_mux), - SND_SOC_DAPM_MUX("RxDP1 Mux", SND_SOC_NOPM, 0, 0, - &rt3261_rxdp1_mux), - SND_SOC_DAPM_MUX("RxDC Mux", SND_SOC_NOPM, 0, 0, - &rt3261_rxdc_mux), - SND_SOC_DAPM_PGA("RxDP", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_PGA("RxDC", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_PGA("TxDC", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_PGA("TxDP", SND_SOC_NOPM, 0, 0, NULL, 0), -}; - -static const struct snd_soc_dapm_route rt3261_dsp_dapm_routes[] = { - {"RxDC", NULL, "RxDC Mux"}, - {"RxDC Mux", "Mono_ADC", "Mono ADC MIXL"}, - {"RxDC Mux", "Mono_ADC", "Mono ADC MIXR"}, - {"RxDC Mux", "Stereo_ADC", "Stereo ADC MIXL"}, - {"RxDC Mux", "Stereo_ADC", "Stereo ADC MIXR"}, - {"RxDP", NULL, "RxDP Mux"}, - {"RxDP Mux", "RxDP2", "RxDP2 Mux"}, - {"RxDP Mux", "RxDP1", "RxDP1 Mux"}, - {"RxDP2 Mux", "IF2_DAC", "IF2 DAC L"}, - {"RxDP2 Mux", "IF2_DAC", "IF2 DAC R"}, - {"RxDP2 Mux", "Stereo_ADC", "Stereo ADC MIXL"}, - {"RxDP2 Mux", "Stereo_ADC", "Stereo ADC MIXR"}, - {"RxDP1 Mux", "DAC1", "Stereo DAC MIXL"}, - {"RxDP1 Mux", "DAC1", "Stereo DAC MIXR"}, - {"RxDP1 Mux", "IF1_DAC", "IF1 DAC L"}, - {"RxDP1 Mux", "IF1_DAC", "IF1 DAC R"}, - - {"DSP Downstream", NULL, "RxDP"}, - {"TxDC", NULL, "DSP Downstream"}, - {"DSP Upstream", NULL, "RxDP"}, - {"DSP Upstream", NULL, "RxDC"}, - {"TxDP", NULL, "DSP Upstream"}, - - {"IF2 ADC L Mux", "TxDP", "TxDP"}, - {"IF2 ADC R Mux", "TxDP", "TxDP"}, - {"DAC L2 Mux", "TxDC", "TxDC"}, - {"DAC R2 Mux", "TxDC", "TxDC"}, -}; - -/** - * rt3261_dsp_show - Dump DSP registers. - * @dev: codec device. - * @attr: device attribute. - * @buf: buffer for display. - * - * To show non-zero values of all DSP registers. - * - * Returns buffer length. - */ -static ssize_t rt3261_dsp_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - struct rt3261_priv *rt3261 = i2c_get_clientdata(client); - struct snd_soc_codec *codec = rt3261->codec; - static const unsigned short (*rt3261_dsp_tab)[2]; - unsigned int val; - int cnt = 0, i, tab_num; - - switch (rt3261->dsp_sw) { - case RT3261_DSP_AEC_NS_FENS: - cnt += sprintf(buf, "[ RT3261 DSP 'AEC' ]\n"); - rt3261_dsp_tab = rt3261_dsp_aec_ns_fens; - tab_num = RT3261_DSP_AEC_NUM; - break; - - case RT3261_DSP_HFBF: - cnt += sprintf(buf, "[ RT3261 DSP 'Beamforming' ]\n"); - rt3261_dsp_tab = rt3261_dsp_hfbf; - tab_num = RT3261_DSP_HFBF_NUM; - break; - - case RT3261_DSP_FFP: - cnt += sprintf(buf, "[ RT3261 DSP 'Far Field Pick-up' ]\n"); - rt3261_dsp_tab = rt3261_dsp_ffp; - tab_num = RT3261_DSP_FFP_NUM; - break; - - case RT3261_DSP_DIS: - default: - cnt += sprintf(buf, "RT3261 DSP Disabled\n"); - goto dsp_done; - } - - for (i = 0; i < tab_num; i++) { - if (cnt + RT3261_DSP_REG_DISP_LEN >= PAGE_SIZE) - break; - val = rt3261_dsp_read(codec, rt3261_dsp_tab[i][0]); - if (!val) - continue; - cnt += snprintf(buf + cnt, RT3261_DSP_REG_DISP_LEN, - "#rnv%04x #rv%04x #rd0\n\n", rt3261_dsp_tab[i][0], val); - } - - tab_num = RT3261_DSP_INIT_NUM; - for (i = 0; i < tab_num; i++) { - if (cnt + RT3261_DSP_REG_DISP_LEN >= PAGE_SIZE) - break; - val = rt3261_dsp_read(codec, rt3261_dsp_init[i][0]); - if (!val) - continue; - cnt += snprintf(buf + cnt, RT3261_DSP_REG_DISP_LEN, - "#rnv%04x #rv%04x #rd0\n", rt3261_dsp_init[i][0], val); - } - for (i = 0; i < RT3261_DSP_RATE_NUM; i++) { - if (cnt + RT3261_DSP_REG_DISP_LEN >= PAGE_SIZE) - break; - val = rt3261_dsp_read(codec, rt3261_dsp_rate_tab[i]); - if (!val) - continue; - cnt += snprintf(buf + cnt, RT3261_DSP_REG_DISP_LEN, - "#rnv%04x #rv%04x #rd0\n", rt3261_dsp_rate_tab[i], val); - } - -dsp_done: - - if (cnt >= PAGE_SIZE) - cnt = PAGE_SIZE - 1; - - return cnt; -} - -static ssize_t dsp_reg_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - struct i2c_client *client = to_i2c_client(dev); - struct rt3261_priv *rt3261 = i2c_get_clientdata(client); - struct snd_soc_codec *codec = rt3261->codec; - struct rt3261_dsp_param param; - unsigned int val=0,addr=0; - int i; - - dev_dbg(codec->dev, "register \"%s\" count=%zu\n", buf, count); - - for(i=0;i='0') - { - addr = (addr << 4) | (*(buf+i)-'0'); - } - else if(*(buf+i) <= 'f' && *(buf+i)>='a') - { - addr = (addr << 4) | ((*(buf+i)-'a')+0xa); - } - else if(*(buf+i) <= 'A' && *(buf+i)>='A') - { - addr = (addr << 4) | ((*(buf+i)-'A')+0xa); - } - else - { - break; - } - } - - for(i=i+1 ;i='0') - { - val = (val << 4) | (*(buf+i)-'0'); - } - else if(*(buf+i) <= 'f' && *(buf+i)>='a') - { - val = (val << 4) | ((*(buf+i)-'a')+0xa); - } - else if(*(buf+i) <= 'F' && *(buf+i)>='A') - { - val = (val << 4) | ((*(buf+i)-'A')+0xa); - - } - else - { - break; - } - } - dev_dbg(codec->dev, "addr=0x%x val=0x%x\n", addr, val); - if(i==count) - { - dev_dbg(codec->dev, "0x%04x = 0x%04x\n", - addr, rt3261_dsp_read(codec, addr)); - } - else - { - param.cmd_fmt = 0x00e0; - param.cmd = RT3261_DSP_CMD_MW; - param.addr = addr; - param.data = val; - rt3261_dsp_write(codec, ¶m); - } - - return count; -} - -static DEVICE_ATTR(dsp_reg, 0666, rt3261_dsp_show, dsp_reg_store); - -/** - * rt3261_dsp_probe - register DSP for rt3261 - * @codec: audio codec - * - * To register DSP function for rt3261. - * - * Returns 0 for success or negative error code. - */ -int rt3261_dsp_probe(struct snd_soc_codec *codec) -{ - //struct rt3261_priv *rt3261; - int ret; - - if (codec == NULL) - return -EINVAL; - - snd_soc_add_codec_controls(codec, rt3261_dsp_snd_controls, - ARRAY_SIZE(rt3261_dsp_snd_controls)); - snd_soc_dapm_new_controls(&codec->dapm, rt3261_dsp_dapm_widgets, - ARRAY_SIZE(rt3261_dsp_dapm_widgets)); - snd_soc_dapm_add_routes(&codec->dapm, rt3261_dsp_dapm_routes, - ARRAY_SIZE(rt3261_dsp_dapm_routes)); - - /* Patch DSP rom code if IC version is larger than C version */ - - ret = snd_soc_update_bits(codec, RT3261_PWR_DIG2, - RT3261_PWR_I2S_DSP, RT3261_PWR_I2S_DSP); - if (ret < 0) { - dev_err(codec->dev, - "Failed to power up DSP IIS interface: %d\n", ret); - } - -#ifdef INIT_DSP_IN_PROBE - rt3261_dsp_snd_effect(codec); - ret = rt3261_dsp_read(codec, 0x22fb); - if(ret == 0x5a5a) - pr_info("DSP init success\n"); - else - pr_info("DSP init failed\n"); -#else - rt3261_dsp_conf(codec); -#endif - ret = rt3261_dsp_read(codec, 0x3800); - pr_info("DSP version code = 0x%04x\n",ret); - /*if(ret != 0x501a) { - rt3261 = snd_soc_codec_get_drvdata(codec); - INIT_DELAYED_WORK(&rt3261->patch_work, rt3261_do_dsp_patch); - schedule_delayed_work(&rt3261->patch_work, - msecs_to_jiffies(100)); - }*/ -#ifdef INIT_DSP_IN_PROBE - snd_soc_update_bits(codec, RT3261_DSP_CTRL3, - RT3261_DSP_PD_PIN_MASK, RT3261_DSP_PD_PIN_LO); -#endif - snd_soc_update_bits(codec, RT3261_PWR_DIG2, - RT3261_PWR_I2S_DSP, 0); - - ret = device_create_file(codec->dev, &dev_attr_dsp_reg); - if (ret != 0) { - dev_err(codec->dev, - "Failed to create index_reg sysfs files: %d\n", ret); - return ret; - } - - return 0; -} -EXPORT_SYMBOL_GPL(rt3261_dsp_probe); - -#ifdef RTK_IOCTL -int rt_codec_dsp_ioctl_common(struct snd_hwdep *hw, struct file *file, unsigned int cmd, unsigned long arg) -{ - struct rt_codec_cmd rt_codec; - int *buf; - int *p; - int ret; - struct rt3261_dsp_param param; - - //int mask1 = 0, mask2 = 0; - - struct rt_codec_cmd __user *_rt_codec = (struct rt_codec_cmd *)arg; - struct snd_soc_codec *codec = hw->private_data; - struct rt3261_priv *rt3261 = snd_soc_codec_get_drvdata(codec); - - if (copy_from_user(&rt_codec, _rt_codec, sizeof(rt_codec))) { - dev_err(codec->dev, "copy_from_user faild\n"); - return -EFAULT; - } - dev_dbg(codec->dev, "rt_codec.number=%zu\n", rt_codec.number); - buf = kmalloc(sizeof(*buf) * rt_codec.number, GFP_KERNEL); - if (buf == NULL) - return -ENOMEM; - if (copy_from_user(buf, rt_codec.buf, sizeof(*buf) * rt_codec.number)) { - goto err; - } - - ret = snd_soc_update_bits(codec, RT3261_PWR_DIG2, - RT3261_PWR_I2S_DSP, RT3261_PWR_I2S_DSP); - if (ret < 0) { - dev_err(codec->dev, - "Failed to power up DSP IIS interface: %d\n", ret); - goto err; - } - - switch (cmd) { - case RT_READ_CODEC_DSP_IOCTL: - for (p = buf; p < buf + rt_codec.number/2; p++) - *(p+rt_codec.number/2) = rt3261_dsp_read(codec, *p); - if (copy_to_user(rt_codec.buf, buf, sizeof(*buf) * rt_codec.number)) - goto err; - break; - - case RT_WRITE_CODEC_DSP_IOCTL: - param.cmd_fmt = 0x00e0; - param.cmd = RT3261_DSP_CMD_MW; - p = buf; - param.addr = *p; - param.data = *(p+rt_codec.number/2); - if(codec == NULL) { - dev_dbg(codec->dev, "codec is null\n"); - break; - } - for (p = buf; p < buf + rt_codec.number/2; p++) - rt3261_dsp_write(codec, ¶m); - break; - - case RT_GET_CODEC_DSP_MODE_IOCTL: - *buf = rt3261->dsp_sw; - if (copy_to_user(rt_codec.buf, buf, sizeof(*buf) * rt_codec.number)) - goto err; - break; - - default: - dev_info(codec->dev, "unsported dsp command\n"); - break; - } - - kfree(buf); - return 0; - -err: - kfree(buf); - return -EFAULT; -} -EXPORT_SYMBOL_GPL(rt_codec_dsp_ioctl_common); -#endif - -#ifdef CONFIG_PM -int rt3261_dsp_suspend(struct snd_soc_codec *codec) -{ - return 0; -} -EXPORT_SYMBOL_GPL(rt3261_dsp_suspend); - -int rt3261_dsp_resume(struct snd_soc_codec *codec) -{ - return 0; -} -EXPORT_SYMBOL_GPL(rt3261_dsp_resume); -#endif - diff --git a/sound/soc/codecs/rt3261-dsp.h b/sound/soc/codecs/rt3261-dsp.h deleted file mode 100644 index f78151bd0359..000000000000 --- a/sound/soc/codecs/rt3261-dsp.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * rt3261-dsp.h -- RT3261 ALSA SoC DSP driver - * - * Copyright 2011 Realtek Microelectronics - * Author: Johnny Hsu - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef __RT3261_DSP_H__ -#define __RT3261_DSP_H__ - -/* Debug String Length */ -#define RT3261_DSP_REG_DISP_LEN 25 - -enum { - RT3261_DSP_DIS, - RT3261_DSP_AEC_NS_FENS, - RT3261_DSP_HFBF, - RT3261_DSP_FFP, -}; - -struct rt3261_dsp_param { - u16 cmd_fmt; - u16 addr; - u16 data; - u8 cmd; -}; - -int rt3261_dsp_write(struct snd_soc_codec *codec, struct rt3261_dsp_param *param); -unsigned int rt3261_dsp_read(struct snd_soc_codec *codec, unsigned int reg); -int rt3261_dsp_probe(struct snd_soc_codec *codec); -int rt_codec_dsp_ioctl_common(struct snd_hwdep *hw, struct file *file, unsigned int cmd, unsigned long arg); -#ifdef CONFIG_PM -int rt3261_dsp_suspend(struct snd_soc_codec *codec); -int rt3261_dsp_resume(struct snd_soc_codec *codec); -#endif - -#endif /* __RT3261_DSP_H__ */ - diff --git a/sound/soc/codecs/rt3261.c b/sound/soc/codecs/rt3261.c deleted file mode 100755 index 1541f3137b61..000000000000 --- a/sound/soc/codecs/rt3261.c +++ /dev/null @@ -1,3749 +0,0 @@ -/* - * rt3261.c -- RT3261 ALSA SoC audio codec driver - * - * Copyright 2011 Realtek Semiconductor Corp. - * Author: Johnny Hsu - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -//#define USE_INT_CLK -#define DIFFERENTIAL 1 -#define SINGLE_END 0 -#define TWO_SPK 2 -#define ONE_SPK 1 - -enum { - SPK_AMPLIFY_ZERO_POINT_FIVE_WATT=1, - SPK_AMPLIFY_ZERO_POINT_SIX_WATT, - SPK_AMPLIFY_ZERO_POINT_EIGHT_WATT, - SPK_AMPLIFY_ONE_WATT, -}; - -enum { - LR_NORMAL, - LR_SWAP, - LEFT_COPY_TO_RIGHT, - RIGHT_COPY_LEFT, -}; - -static struct snd_soc_codec *rt3261_codec; - -#if 0 -#define DBG(x...) printk(KERN_DEBUG x) -#else -#define DBG(x...) -#endif - -#define RTK_IOCTL -#ifdef RTK_IOCTL -#if defined(CONFIG_SND_HWDEP) || defined(CONFIG_SND_HWDEP_MODULE) -#include "rt_codec_ioctl.h" -#include "rt3261_ioctl.h" -#endif -#endif - -#include "rt3261.h" -#if defined (CONFIG_SND_SOC_RT3261) -#include "rt3261-dsp.h" -#endif - -#define RT3261_REG_RW 1 /* for debug */ -#define RT3261_DET_EXT_MIC 0 - -#define VERSION "RT3261_V1.3.0" - -#if defined (CONFIG_SND_SOC_RT5623) -extern void rt5623_on(void); -extern void rt5623_off(void); -#endif - -struct rt3261_init_reg { - u8 reg; - u16 val; -}; - -static struct rt3261_init_reg init_list[] = { - {RT3261_GEN_CTRL1 , 0x3701},//fa[12:13] = 1'b; fa[8~10]=1; fa[0]=1 - {RT3261_ADDA_CLK1 , 0x1114},//73[2] = 1'b - {RT3261_MICBIAS , 0x3030},//93[5:4] = 11'b - {RT3261_CLS_D_OUT , 0xa000},//8d[11] = 0'b - {RT3261_CLS_D_OVCD , 0x0334},//8c[8] = 1'b - {RT3261_PRIV_INDEX , 0x001d},//PR1d[8] = 1'b; - {RT3261_PRIV_DATA , 0x0347}, - {RT3261_PRIV_INDEX , 0x003d},//PR3d[12] = 0'b; PR3d[9] = 1'b - {RT3261_PRIV_DATA , 0x3600}, - {RT3261_PRIV_INDEX , 0x0012},//PR12 = 0aa8'h - {RT3261_PRIV_DATA , 0x0aa8}, - {RT3261_PRIV_INDEX , 0x0014},//PR14 = 8aaa'h - {RT3261_PRIV_DATA , 0x8aaa}, - {RT3261_PRIV_INDEX , 0x0020},//PR20 = 6115'h - {RT3261_PRIV_DATA , 0x6115}, - {RT3261_PRIV_INDEX , 0x0023},//PR23 = 0804'h - {RT3261_PRIV_DATA , 0x0804}, - {RT3261_SPK_VOL , 0x8888},//SPKMIX -> SPKVOL - {RT3261_HP_VOL , 0x8888}, - {RT3261_OUTPUT , 0x8888},//unmute OUTVOLL/R - {RT3261_SPO_CLSD_RATIO , 0x0001}, - {RT3261_I2S1_SDP , 0xd000}, - {RT3261_GLB_CLK , 0x4000},//0424 - //{0x90 , 0x636},//0424 - {RT3261_CHARGE_PUMP , 0xe00},//0424 - {RT3261_DEPOP_M3 , 0x636},//0424 - {RT3261_DEPOP_M1 , 0x84},//0424 - {RT3261_PWR_DIG1 , 0x8000},//0424 - {RT3261_PWR_ANLG2 , 0x0800}, - // huangcun 20130816 s -#if 0 - /*speaker*/ - {RT3261_DSP_PATH2 , 0x0000}, - {RT3261_PRIV_INDEX , 0x003f},//PR3d[14] = 0'b; - {RT3261_PRIV_DATA , 0x0000}, - {RT3261_DAC2_CTRL , 0x0000}, - {RT3261_MONO_DAC_MIXER, 0x4444}, - {RT3261_SPK_L_MIXER, 0x003a}, - {RT3261_SPK_R_MIXER, 0x003a}, - {RT3261_SPO_L_MIXER, 0xc800}, - /*headphone*/ - {RT3261_OUT_L3_MIXER, 0x01fd}, - {RT3261_OUT_R3_MIXER, 0x01fd}, - {RT3261_HPO_MIXER, 0xc000}, -#endif -#if 0 - /*capture*/ - {RT3261_IN1_IN2, 0x2080},//boost1 = 24db - {RT3261_REC_R2_MIXER, 0x007d}, - {RT3261_MONO_ADC_MIXER,0x7030}, - //{RT3261_GEN_CTRL1 , 0x2701},//regfa[13]=0 - {RT3261_DSP_PATH2 , 0x0400}, - {RT3261_DIG_INF_DATA, 0x0300},//right copy to left -#endif -#if 0 - /*lin out*/ - {RT3261_DSP_PATH2 , 0x0000}, - {RT3261_PRIV_INDEX , 0x003f},//PR3d[14] = 0'b; - {RT3261_PRIV_DATA , 0x0000}, - {RT3261_DAC2_CTRL , 0x0000}, - {RT3261_MONO_DAC_MIXER, 0x4444}, - {RT3261_OUT_L3_MIXER, 0x01fd}, - {RT3261_OUT_R3_MIXER, 0x01fd}, - {RT3261_LOUT_MIXER, 0xc000}, -#endif - // huangcun 20130816 e -}; -#define RT3261_INIT_REG_LEN ARRAY_SIZE(init_list) - -static int rt3261_reg_init(struct snd_soc_codec *codec) -{ - int i; - - for (i = 0; i < RT3261_INIT_REG_LEN; i++) - snd_soc_write(codec, init_list[i].reg, init_list[i].val); - - return 0; -} - -static int rt3261_customer_redefine(struct snd_soc_codec *codec, struct rt3261_priv *rt3261) -{ - if(rt3261->spk_num==TWO_SPK) - { - snd_soc_update_bits(codec, RT3261_SPO_L_MIXER, - RT3261_M_SV_R_SPM_L | RT3261_M_SV_L_SPM_L, - 1 << RT3261_M_SV_R_SPM_L_SFT | 0 << RT3261_M_SV_L_SPM_L_SFT); - snd_soc_update_bits(codec, RT3261_SPO_R_MIXER, - RT3261_M_SV_R_SPM_R, 0 << RT3261_M_SV_R_SPM_R_SFT); - } - else - { - snd_soc_update_bits(codec, RT3261_SPO_L_MIXER, - RT3261_M_SV_R_SPM_L | RT3261_M_SV_L_SPM_L, - 0 << RT3261_M_SV_R_SPM_L_SFT | 0 << RT3261_M_SV_L_SPM_L_SFT); - snd_soc_update_bits(codec, RT3261_SPO_R_MIXER, - RT3261_M_SV_R_SPM_R, 1 << RT3261_M_SV_R_SPM_R_SFT); - } - - - snd_soc_update_bits(codec, RT3261_IN3_IN4, - RT3261_IN_DF2, rt3261->modem_input_mode << RT3261_IN_SFT2); - snd_soc_update_bits(codec, RT3261_GEN_CTRL1, - RT3261_LOUT_DF_MASK, rt3261->lout_to_modem_mode << RT3261_LOUT_DF); - snd_soc_update_bits(codec, RT3261_SPO_CLSD_RATIO, - RT3261_SPO_CLSD_RATIO_MASK, rt3261->spk_amplify); - snd_soc_update_bits(codec, RT3261_DIG_INF_DATA, - RT3261_IF1_DAC_SEL_MASK | RT3261_IF2_DAC_SEL_MASK, - (rt3261->playback_if1_data_control<playback_if2_data_control<hw_read(codec, reg); - return val; -} -#endif -static int do_hw_write(struct snd_soc_codec *codec, unsigned int reg, - unsigned int value, const void *data, int len) -{ - struct rt3261_priv *rt3261 = snd_soc_codec_get_drvdata(codec); - int ret; - - if (!snd_soc_codec_volatile_register(codec, reg) && - reg < codec->driver->reg_cache_size && - !codec->cache_bypass) { - ret = snd_soc_cache_write(codec, reg, value); - if (ret < 0) - return -1; - } - - if (codec->cache_only) { - codec->cache_sync = 1; - return 0; - } - - if (i2c_master_send(rt3261->i2c, data, len) == len) - return 0; - else - return -EIO; -} - -static int rt3261_write(struct snd_soc_codec *codec, unsigned int reg, - unsigned int value) -{ - u8 data[3]; - - data[0] = reg; - data[1] = (value >> 8) & 0xff; - data[2] = value & 0xff; - - DBG("rt3261_write 0x%x = 0x%x\n",reg,value); - - return do_hw_write(codec, reg, value, data, 3); -} - -/** - * rt3261_index_write - Write private register. - * @codec: SoC audio codec device. - * @reg: Private register index. - * @value: Private register Data. - * - * Modify private register for advanced setting. It can be written through - * private index (0x6a) and data (0x6c) register. - * - * Returns 0 for success or negative error code. - */ -static int rt3261_index_write(struct snd_soc_codec *codec, - unsigned int reg, unsigned int value) -{ - int ret; - - ret = snd_soc_write(codec, RT3261_PRIV_INDEX, reg); - if (ret < 0) { - dev_err(codec->dev, "Failed to set private addr: %d\n", ret); - goto err; - } - ret = snd_soc_write(codec, RT3261_PRIV_DATA, value); - if (ret < 0) { - dev_err(codec->dev, "Failed to set private value: %d\n", ret); - goto err; - } - return 0; - -err: - return ret; -} - -/** - * rt3261_index_read - Read private register. - * @codec: SoC audio codec device. - * @reg: Private register index. - * - * Read advanced setting from private register. It can be read through - * private index (0x6a) and data (0x6c) register. - * - * Returns private register value or negative error code. - */ -static unsigned int rt3261_index_read( - struct snd_soc_codec *codec, unsigned int reg) -{ - int ret; - - ret = snd_soc_write(codec, RT3261_PRIV_INDEX, reg); - if (ret < 0) { - dev_err(codec->dev, "Failed to set private addr: %d\n", ret); - return ret; - } - return snd_soc_read(codec, RT3261_PRIV_DATA); -} - -/** - * rt3261_index_update_bits - update private register bits - * @codec: audio codec - * @reg: Private register index. - * @mask: register mask - * @value: new value - * - * Writes new register value. - * - * Returns 1 for change, 0 for no change, or negative error code. - */ -static int rt3261_index_update_bits(struct snd_soc_codec *codec, - unsigned int reg, unsigned int mask, unsigned int value) -{ - unsigned int old, new; - int change, ret; - - ret = rt3261_index_read(codec, reg); - if (ret < 0) { - dev_err(codec->dev, "Failed to read private reg: %d\n", ret); - goto err; - } - - old = ret; - new = (old & ~mask) | (value & mask); - change = old != new; - if (change) { - ret = rt3261_index_write(codec, reg, new); - if (ret < 0) { - dev_err(codec->dev, - "Failed to write private reg: %d\n", ret); - goto err; - } - } - return change; - -err: - return ret; -} - -static int rt3261_volatile_register( - struct snd_soc_codec *codec, unsigned int reg) -{ - switch (reg) { - case RT3261_RESET: - case RT3261_PRIV_DATA: - case RT3261_ASRC_5: - case RT3261_EQ_CTRL1: - case RT3261_DRC_AGC_1: - case RT3261_ANC_CTRL1: - case RT3261_IRQ_CTRL2: - case RT3261_INT_IRQ_ST: - case RT3261_DSP_CTRL2: - case RT3261_DSP_CTRL3: - case RT3261_PGM_REG_ARR1: - case RT3261_PGM_REG_ARR3: - case RT3261_VENDOR_ID: - case RT3261_VENDOR_ID1: - case RT3261_VENDOR_ID2: - return 1; - default: - return 0; - } -} - -static int rt3261_readable_register( - struct snd_soc_codec *codec, unsigned int reg) -{ - switch (reg) { - case RT3261_RESET: - case RT3261_SPK_VOL: - case RT3261_HP_VOL: - case RT3261_OUTPUT: - case RT3261_MONO_OUT: - case RT3261_IN1_IN2: - case RT3261_IN3_IN4: - case RT3261_INL_INR_VOL: - case RT3261_DAC1_DIG_VOL: - case RT3261_DAC2_DIG_VOL: - case RT3261_DAC2_CTRL: - case RT3261_ADC_DIG_VOL: - case RT3261_ADC_DATA: - case RT3261_ADC_BST_VOL: - case RT3261_STO_ADC_MIXER: - case RT3261_MONO_ADC_MIXER: - case RT3261_AD_DA_MIXER: - case RT3261_STO_DAC_MIXER: - case RT3261_MONO_DAC_MIXER: - case RT3261_DIG_MIXER: - case RT3261_DSP_PATH1: - case RT3261_DSP_PATH2: - case RT3261_DIG_INF_DATA: - case RT3261_REC_L1_MIXER: - case RT3261_REC_L2_MIXER: - case RT3261_REC_R1_MIXER: - case RT3261_REC_R2_MIXER: - case RT3261_HPO_MIXER: - case RT3261_SPK_L_MIXER: - case RT3261_SPK_R_MIXER: - case RT3261_SPO_L_MIXER: - case RT3261_SPO_R_MIXER: - case RT3261_SPO_CLSD_RATIO: - case RT3261_MONO_MIXER: - case RT3261_OUT_L1_MIXER: - case RT3261_OUT_L2_MIXER: - case RT3261_OUT_L3_MIXER: - case RT3261_OUT_R1_MIXER: - case RT3261_OUT_R2_MIXER: - case RT3261_OUT_R3_MIXER: - case RT3261_LOUT_MIXER: - case RT3261_PWR_DIG1: - case RT3261_PWR_DIG2: - case RT3261_PWR_ANLG1: - case RT3261_PWR_ANLG2: - case RT3261_PWR_MIXER: - case RT3261_PWR_VOL: - case RT3261_PRIV_INDEX: - case RT3261_PRIV_DATA: - case RT3261_I2S1_SDP: - case RT3261_I2S2_SDP: - case RT3261_I2S3_SDP: - case RT3261_ADDA_CLK1: - case RT3261_ADDA_CLK2: - case RT3261_DMIC: - case RT3261_GLB_CLK: - case RT3261_PLL_CTRL1: - case RT3261_PLL_CTRL2: - case RT3261_ASRC_1: - case RT3261_ASRC_2: - case RT3261_ASRC_3: - case RT3261_ASRC_4: - case RT3261_ASRC_5: - case RT3261_HP_OVCD: - case RT3261_CLS_D_OVCD: - case RT3261_CLS_D_OUT: - case RT3261_DEPOP_M1: - case RT3261_DEPOP_M2: - case RT3261_DEPOP_M3: - case RT3261_CHARGE_PUMP: - case RT3261_PV_DET_SPK_G: - case RT3261_MICBIAS: - case RT3261_EQ_CTRL1: - case RT3261_EQ_CTRL2: - case RT3261_WIND_FILTER: - case RT3261_DRC_AGC_1: - case RT3261_DRC_AGC_2: - case RT3261_DRC_AGC_3: - case RT3261_SVOL_ZC: - case RT3261_ANC_CTRL1: - case RT3261_ANC_CTRL2: - case RT3261_ANC_CTRL3: - case RT3261_JD_CTRL: - case RT3261_ANC_JD: - case RT3261_IRQ_CTRL1: - case RT3261_IRQ_CTRL2: - case RT3261_INT_IRQ_ST: - case RT3261_GPIO_CTRL1: - case RT3261_GPIO_CTRL2: - case RT3261_GPIO_CTRL3: - case RT3261_DSP_CTRL1: - case RT3261_DSP_CTRL2: - case RT3261_DSP_CTRL3: - case RT3261_DSP_CTRL4: - case RT3261_PGM_REG_ARR1: - case RT3261_PGM_REG_ARR2: - case RT3261_PGM_REG_ARR3: - case RT3261_PGM_REG_ARR4: - case RT3261_PGM_REG_ARR5: - case RT3261_SCB_FUNC: - case RT3261_SCB_CTRL: - case RT3261_BASE_BACK: - case RT3261_MP3_PLUS1: - case RT3261_MP3_PLUS2: - case RT3261_3D_HP: - case RT3261_ADJ_HPF: - case RT3261_HP_CALIB_AMP_DET: - case RT3261_HP_CALIB2: - case RT3261_SV_ZCD1: - case RT3261_SV_ZCD2: - case RT3261_GEN_CTRL1: - case RT3261_GEN_CTRL2: - case RT3261_GEN_CTRL3: - case RT3261_VENDOR_ID: - case RT3261_VENDOR_ID1: - case RT3261_VENDOR_ID2: - return 1; - default: - return 0; - } -} - -/** - * rt3261_headset_mic_detect - Detect headset. - * @codec: SoC audio codec device. - * @jack_insert: Jack insert or not. - * - * Detect whether is headset or not when jack inserted. - * - * Returns detect status. - */ -int rt3261_headset_mic_detect(int jack_insert) -{ - int jack_type; -#ifdef USE_INT_CLK - int sclk_src; -#endif - - if(rt3261_codec == NULL){ - return -1; - } - - if(jack_insert) { - if (SND_SOC_BIAS_OFF == rt3261_codec->dapm.bias_level) { - snd_soc_write(rt3261_codec, RT3261_PWR_ANLG1, 0x2004); - snd_soc_write(rt3261_codec, RT3261_MICBIAS, 0x3830); - snd_soc_write(rt3261_codec, RT3261_GEN_CTRL1 , 0x3701); - } -#ifdef USE_INT_CLK - sclk_src = snd_soc_read(rt3261_codec, RT3261_GLB_CLK) & - RT3261_SCLK_SRC_MASK; - snd_soc_update_bits(rt3261_codec, RT3261_GLB_CLK, - RT3261_SCLK_SRC_MASK, 0x3 << RT3261_SCLK_SRC_SFT); -#endif - snd_soc_update_bits(rt3261_codec, RT3261_PWR_ANLG1, - RT3261_PWR_LDO2, RT3261_PWR_LDO2); - snd_soc_update_bits(rt3261_codec, RT3261_PWR_ANLG2, - RT3261_PWR_MB1, RT3261_PWR_MB1); - msleep(400); - snd_soc_update_bits(rt3261_codec, RT3261_MICBIAS, - RT3261_MIC1_OVCD_MASK | RT3261_MIC1_OVTH_MASK | - RT3261_PWR_CLK25M_MASK | RT3261_PWR_MB_MASK, - RT3261_MIC1_OVCD_EN | RT3261_MIC1_OVTH_600UA | - RT3261_PWR_MB_PU | RT3261_PWR_CLK25M_PU); - snd_soc_update_bits(rt3261_codec, RT3261_GEN_CTRL1, - 0x1, 0x1); - msleep(100); - if (snd_soc_read(rt3261_codec, RT3261_IRQ_CTRL2) & 0x8) - jack_type = RT3261_HEADPHO_DET; - else - jack_type = RT3261_HEADSET_DET; - snd_soc_update_bits(rt3261_codec, RT3261_IRQ_CTRL2, - RT3261_MB1_OC_CLR, 0); -#ifdef USE_INT_CLK - snd_soc_update_bits(rt3261_codec, RT3261_GLB_CLK, - RT3261_SCLK_SRC_MASK, sclk_src); -#endif - } else { - snd_soc_update_bits(rt3261_codec, RT3261_MICBIAS, - RT3261_MIC1_OVCD_MASK, - RT3261_MIC1_OVCD_DIS); - - jack_type = RT3261_NO_JACK; - } - - return jack_type; -} -EXPORT_SYMBOL(rt3261_headset_mic_detect); - -static const char *rt3261_dacr2_src[] = { "TxDC_R", "TxDP_R" }; - -static const SOC_ENUM_SINGLE_DECL(rt3261_dacr2_enum,RT3261_DUMMY_PR3F, - 14, rt3261_dacr2_src); -static const struct snd_kcontrol_new rt3261_dacr2_mux = - SOC_DAPM_ENUM("Mono dacr source", rt3261_dacr2_enum); - -static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -4650, 150, 0); -static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -65625, 375, 0); -static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0); -static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -17625, 375, 0); -static const DECLARE_TLV_DB_SCALE(adc_bst_tlv, 0, 1200, 0); - -/* {0, +20, +24, +30, +35, +40, +44, +50, +52} dB */ -static unsigned int bst_tlv[] = { - TLV_DB_RANGE_HEAD(7), - 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0), - 1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0), - 2, 2, TLV_DB_SCALE_ITEM(2400, 0, 0), - 3, 5, TLV_DB_SCALE_ITEM(3000, 500, 0), - 6, 6, TLV_DB_SCALE_ITEM(4400, 0, 0), - 7, 7, TLV_DB_SCALE_ITEM(5000, 0, 0), - 8, 8, TLV_DB_SCALE_ITEM(5200, 0, 0), -}; - -static int rt3261_dmic_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct rt3261_priv *rt3261 = snd_soc_codec_get_drvdata(codec); - - ucontrol->value.integer.value[0] = rt3261->dmic_en; - - return 0; -} - -static int rt3261_dmic_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct rt3261_priv *rt3261 = snd_soc_codec_get_drvdata(codec); - - if (rt3261->dmic_en == ucontrol->value.integer.value[0]) - return 0; - - rt3261->dmic_en = ucontrol->value.integer.value[0]; - switch (rt3261->dmic_en) { - case RT3261_DMIC_DIS: - snd_soc_update_bits(codec, RT3261_GPIO_CTRL1, - RT3261_GP2_PIN_MASK | RT3261_GP3_PIN_MASK | - RT3261_GP4_PIN_MASK, - RT3261_GP2_PIN_GPIO2 | RT3261_GP3_PIN_GPIO3 | - RT3261_GP4_PIN_GPIO4); - snd_soc_update_bits(codec, RT3261_DMIC, - RT3261_DMIC_1_DP_MASK | RT3261_DMIC_2_DP_MASK, - RT3261_DMIC_1_DP_GPIO3 | RT3261_DMIC_2_DP_GPIO4); - snd_soc_update_bits(codec, RT3261_DMIC, - RT3261_DMIC_1_EN_MASK | RT3261_DMIC_2_EN_MASK, - RT3261_DMIC_1_DIS | RT3261_DMIC_2_DIS); - break; - - case RT3261_DMIC1: - snd_soc_update_bits(codec, RT3261_GPIO_CTRL1, - RT3261_GP2_PIN_MASK | RT3261_GP3_PIN_MASK, - RT3261_GP2_PIN_DMIC1_SCL | RT3261_GP3_PIN_DMIC1_SDA); - snd_soc_update_bits(codec, RT3261_DMIC, - RT3261_DMIC_1L_LH_MASK | RT3261_DMIC_1R_LH_MASK | - RT3261_DMIC_1_DP_MASK, - RT3261_DMIC_1L_LH_FALLING | RT3261_DMIC_1R_LH_RISING | - RT3261_DMIC_1_DP_IN1P); - snd_soc_update_bits(codec, RT3261_DMIC, - RT3261_DMIC_1_EN_MASK, RT3261_DMIC_1_EN); - break; - - case RT3261_DMIC2: - snd_soc_update_bits(codec, RT3261_GPIO_CTRL1, - RT3261_GP2_PIN_MASK | RT3261_GP4_PIN_MASK, - RT3261_GP2_PIN_DMIC1_SCL | RT3261_GP4_PIN_DMIC2_SDA); - snd_soc_update_bits(codec, RT3261_DMIC, - RT3261_DMIC_2L_LH_MASK | RT3261_DMIC_2R_LH_MASK | - RT3261_DMIC_2_DP_MASK, - RT3261_DMIC_2L_LH_FALLING | RT3261_DMIC_2R_LH_RISING | - RT3261_DMIC_2_DP_IN1N); - snd_soc_update_bits(codec, RT3261_DMIC, - RT3261_DMIC_2_EN_MASK, RT3261_DMIC_2_EN); - break; - - default: - return -EINVAL; - } - - return 0; -} - -static int rt3261_asrc_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct rt3261_priv *rt3261 = snd_soc_codec_get_drvdata(codec); - - DBG("%s\n", __FUNCTION__); - ucontrol->value.integer.value[0] = rt3261->asrc_en; - - return 0; -} - -static int rt3261_asrc_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct rt3261_priv *rt3261 = snd_soc_codec_get_drvdata(codec); - - DBG("%s\n", __FUNCTION__); - if (rt3261->asrc_en == ucontrol->value.integer.value[0]) - return 0; - - rt3261->asrc_en = ucontrol->value.integer.value[0]; - switch (rt3261->asrc_en) { - case RT3261_ASRC_DIS://disable ASRC - DBG("%s disable\n", __FUNCTION__); - snd_soc_write(codec, RT3261_ASRC_1, 0x0); - snd_soc_write(codec, RT3261_ASRC_2, 0x0); - snd_soc_update_bits(codec, RT3261_GEN_CTRL1, 0x70, 0x0); //bard 8-29 - mutex_lock(&codec->mutex); - snd_soc_dapm_disable_pin(&codec->dapm, "DAC L2 Power"); //bard 9-4 - snd_soc_dapm_disable_pin(&codec->dapm, "stereo filter"); //bard 9-4 - snd_soc_dapm_sync(&codec->dapm); //bard 9-4 - mutex_unlock(&codec->mutex); - break; - - case RT3261_ASRC_EN://enable ASRC - DBG("%s enable\n", __FUNCTION__); - snd_soc_write(codec, RT3261_ASRC_1, 0x9800); - snd_soc_write(codec, RT3261_ASRC_2, 0xF800); - snd_soc_update_bits(codec, RT3261_GEN_CTRL1, 0x70, 0x70); //bard 8-29 - snd_soc_write(codec, RT3261_JD_CTRL, 0x03); //bard 8-29 - //snd_soc_update_bits(codec, RT3261_PWR_DIG1, 0x0080, 0x0080); - //snd_soc_update_bits(codec, RT3261_PWR_DIG2, 0x8000, 0x8000); - mutex_lock(&codec->mutex); - snd_soc_dapm_force_enable_pin(&codec->dapm, "DAC L2 Power"); //bard 9-4 - snd_soc_dapm_force_enable_pin(&codec->dapm, "stereo filter"); //bard 9-4 - snd_soc_dapm_sync(&codec->dapm); //bard 9-4 - mutex_unlock(&codec->mutex); - snd_soc_write(codec, RT3261_ADDA_CLK1, 0x1114); - break; - - default: - return -EINVAL; - } - - return 0; -} - -//bard 8-9 s -static int rt3261_mic1_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - - ucontrol->value.integer.value[0] = - (snd_soc_read(codec, RT3261_REC_L2_MIXER) & RT3261_M_BST1_RM_L) >> RT3261_M_BST1_RM_L_SFT; - - return 0; -} - -static int rt3261_mic1_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - - if(ucontrol->value.integer.value[0]==0) { - snd_soc_update_bits(codec, RT3261_REC_L2_MIXER, - RT3261_M_BST1_RM_L, 0); - snd_soc_update_bits(codec, RT3261_REC_R2_MIXER, - RT3261_M_BST1_RM_R, 0); - }else { - snd_soc_update_bits(codec, RT3261_REC_L2_MIXER, - RT3261_M_BST1_RM_L, RT3261_M_BST1_RM_L); - snd_soc_update_bits(codec, RT3261_REC_R2_MIXER, - RT3261_M_BST1_RM_R, RT3261_M_BST1_RM_R); - } - - return 0; -} - -static int rt3261_mic2_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - - ucontrol->value.integer.value[0] = - (snd_soc_read(codec, RT3261_REC_L2_MIXER) & RT3261_M_BST1_RM_L) >> RT3261_M_BST1_RM_L_SFT; - - return 0; -} - -static int rt3261_mic2_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - - if(ucontrol->value.integer.value[0]==0) { - snd_soc_update_bits(codec, RT3261_REC_L2_MIXER, - RT3261_M_BST4_RM_L, 0); - snd_soc_update_bits(codec, RT3261_REC_R2_MIXER, - RT3261_M_BST4_RM_R, 0); - }else { - snd_soc_update_bits(codec, RT3261_REC_L2_MIXER, - RT3261_M_BST4_RM_L, RT3261_M_BST4_RM_L); - snd_soc_update_bits(codec, RT3261_REC_R2_MIXER, - RT3261_M_BST4_RM_R, RT3261_M_BST4_RM_R); - } - - return 0; -} -//bard 8-9 e - -void rt3261_hp_amp_power(struct snd_soc_codec *codec, int on) -{ - static int hp_amp_power_count; - DBG("rt3261_hp_amp_power on=%d hp_amp_power_count=%d\n",on,hp_amp_power_count); -// dump_reg(codec); - if(on) { - if(hp_amp_power_count <= 0) { - snd_soc_update_bits(codec, RT3261_PWR_DIG1, - RT3261_PWR_I2S1, RT3261_PWR_I2S1); - /* depop parameters */ - rt3261_index_update_bits(codec, RT3261_CHPUMP_INT_REG1,0x0700, 0x0200); //bard 12-6 - snd_soc_write(codec, RT3261_DEPOP_M2, 0x3100); //bard 4-22 - snd_soc_write(codec, RT3261_DEPOP_M1, 0x0009); //bard 4-22 - msleep(50); -/* - snd_soc_update_bits(codec, RT3261_DEPOP_M2, - RT3261_DEPOP_MASK, RT3261_DEPOP_MAN); - snd_soc_update_bits(codec, RT3261_DEPOP_M1, - RT3261_HP_CP_MASK | RT3261_HP_SG_MASK | RT3261_HP_CB_MASK, - RT3261_HP_CP_PU | RT3261_HP_SG_DIS | RT3261_HP_CB_PU); -*/ - rt3261_index_write(codec, RT3261_HP_DCC_INT1, 0x9f00); - /* headphone amp power on */ - snd_soc_update_bits(codec, RT3261_PWR_ANLG1, - RT3261_PWR_FV1 | RT3261_PWR_FV2 , 0); - snd_soc_update_bits(codec, RT3261_PWR_VOL, - RT3261_PWR_HV_L | RT3261_PWR_HV_R, - RT3261_PWR_HV_L | RT3261_PWR_HV_R); - snd_soc_update_bits(codec, RT3261_PWR_ANLG1, - RT3261_PWR_HP_L | RT3261_PWR_HP_R | RT3261_PWR_HA , //bard 10-18 - RT3261_PWR_HP_L | RT3261_PWR_HP_R | RT3261_PWR_HA); //bard 10-18 - msleep(30); //bard 4-22 - snd_soc_update_bits(codec, RT3261_PWR_ANLG1, - RT3261_PWR_FV1 | RT3261_PWR_FV2, - RT3261_PWR_FV1 | RT3261_PWR_FV2); - - snd_soc_update_bits(codec, RT3261_CHARGE_PUMP, - RT3261_PM_HP_MASK, RT3261_PM_HP_HV); - rt3261_index_update_bits(codec, RT3261_CHOP_DAC_ADC, 0x0200, 0x0200); - snd_soc_update_bits(codec, RT3261_DEPOP_M1, - RT3261_HP_CO_MASK | RT3261_HP_SG_MASK, - RT3261_HP_CO_EN | RT3261_HP_SG_EN); - rt3261_index_update_bits(codec, RT3261_CHPUMP_INT_REG1,0x0700, 0x0400); //bard 12-6 - } - hp_amp_power_count++; - } else { - hp_amp_power_count--; - if(hp_amp_power_count <= 0) { - //rt3261_index_update_bits(codec, RT3261_CHOP_DAC_ADC, 0x0200, 0x0); - snd_soc_update_bits(codec, RT3261_DEPOP_M1, - RT3261_HP_SG_MASK | RT3261_HP_L_SMT_MASK | - RT3261_HP_R_SMT_MASK, RT3261_HP_SG_DIS | - RT3261_HP_L_SMT_DIS | RT3261_HP_R_SMT_DIS); - /* headphone amp power down */ - snd_soc_update_bits(codec, RT3261_DEPOP_M1, - RT3261_SMT_TRIG_MASK | RT3261_HP_CD_PD_MASK | - RT3261_HP_CO_MASK | RT3261_HP_CP_MASK | - RT3261_HP_SG_MASK | RT3261_HP_CB_MASK, - RT3261_SMT_TRIG_DIS | RT3261_HP_CD_PD_EN | - RT3261_HP_CO_DIS | RT3261_HP_CP_PD | - RT3261_HP_SG_EN | RT3261_HP_CB_PD); - snd_soc_update_bits(codec, RT3261_PWR_ANLG1, - RT3261_PWR_HP_L | RT3261_PWR_HP_R | RT3261_PWR_HA , //bard 10-18 - 0); - } - } -} - -static int rt3261_hp_mute_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - - ucontrol->value.integer.value[0] = - !((snd_soc_read(codec, RT3261_HP_VOL) & RT3261_L_MUTE) >> RT3261_L_MUTE_SFT); - - return 0; -} - -static int rt3261_hp_mute_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - - if(ucontrol->value.integer.value[0]) { - /* headphone unmute sequence */ - - snd_soc_update_bits(codec, RT3261_DEPOP_M3, - RT3261_CP_FQ1_MASK | RT3261_CP_FQ2_MASK | RT3261_CP_FQ3_MASK, - (RT3261_CP_FQ_192_KHZ << RT3261_CP_FQ1_SFT) | - (RT3261_CP_FQ_12_KHZ << RT3261_CP_FQ2_SFT) | - (RT3261_CP_FQ_192_KHZ << RT3261_CP_FQ3_SFT)); - rt3261_index_write(codec, RT3261_MAMP_INT_REG2, 0xfc00); - snd_soc_update_bits(codec, RT3261_DEPOP_M1, - RT3261_SMT_TRIG_MASK, RT3261_SMT_TRIG_EN); - snd_soc_update_bits(codec, RT3261_DEPOP_M1, - RT3261_RSTN_MASK, RT3261_RSTN_EN); - snd_soc_update_bits(codec, RT3261_DEPOP_M1, - RT3261_RSTN_MASK | RT3261_HP_L_SMT_MASK | RT3261_HP_R_SMT_MASK, - RT3261_RSTN_DIS | RT3261_HP_L_SMT_EN | RT3261_HP_R_SMT_EN); - //snd_soc_update_bits(codec, RT3261_HP_VOL, - // RT3261_L_MUTE | RT3261_R_MUTE, RT3261_L_MUTE | RT3261_R_MUTE); - msleep(60); //bard 4-22 - snd_soc_update_bits(codec, RT3261_DEPOP_M1, - RT3261_HP_SG_MASK | RT3261_HP_L_SMT_MASK | - RT3261_HP_R_SMT_MASK, RT3261_HP_SG_DIS | - RT3261_HP_L_SMT_DIS | RT3261_HP_R_SMT_DIS); - /*bard 10-18 r - msleep(20); - snd_soc_update_bits(codec, RT3261_HP_CALIB_AMP_DET, - RT3261_HPD_PS_MASK, RT3261_HPD_PS_EN); - */ - }else { - /* headphone mute sequence */ - snd_soc_update_bits(codec, RT3261_DEPOP_M3, - RT3261_CP_FQ1_MASK | RT3261_CP_FQ2_MASK | RT3261_CP_FQ3_MASK, - (RT3261_CP_FQ_96_KHZ << RT3261_CP_FQ1_SFT) | - (RT3261_CP_FQ_12_KHZ << RT3261_CP_FQ2_SFT) | - (RT3261_CP_FQ_96_KHZ << RT3261_CP_FQ3_SFT)); - rt3261_index_write(codec, RT3261_MAMP_INT_REG2, 0xfc00); - snd_soc_update_bits(codec, RT3261_DEPOP_M1, - RT3261_HP_SG_MASK, RT3261_HP_SG_EN); - snd_soc_update_bits(codec, RT3261_DEPOP_M1, - RT3261_RSTP_MASK, RT3261_RSTP_EN); - snd_soc_update_bits(codec, RT3261_DEPOP_M1, - RT3261_RSTP_MASK | RT3261_HP_L_SMT_MASK | - RT3261_HP_R_SMT_MASK, RT3261_RSTP_DIS | - RT3261_HP_L_SMT_EN | RT3261_HP_R_SMT_EN); - /*bard 10-18 r - snd_soc_update_bits(codec, RT3261_HP_CALIB_AMP_DET, - RT3261_HPD_PS_MASK, RT3261_HPD_PS_DIS); - msleep(90); - */ - snd_soc_update_bits(codec, RT3261_HP_VOL, - RT3261_L_MUTE | RT3261_R_MUTE, RT3261_L_MUTE | RT3261_R_MUTE); - msleep(60); -/* - snd_soc_update_bits(codec, RT3261_DEPOP_M1, - RT3261_HP_R_SMT_MASK | RT3261_HP_L_SMT_MASK, - RT3261_HP_L_SMT_DIS | RT3261_HP_R_SMT_DIS); -*/ - } - return 0; -} - -#if defined (CONFIG_SND_SOC_RT5623) -static int rt3261_modem_input_switch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct rt3261_priv *rt3261 = snd_soc_codec_get_drvdata(codec); - - ucontrol->value.integer.value[0] = rt3261->modem_is_open; - return 0; -} - -static int rt3261_modem_input_switch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct rt3261_priv *rt3261 = snd_soc_codec_get_drvdata(codec); - - if(ucontrol->value.integer.value[0]) { - rt5623_on( ); - rt3261->modem_is_open = 1; - }else { - rt5623_off( ); - rt3261->modem_is_open = 0; - } - - return 0; -} -#else -static int rt3261_modem_input_switch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - return 0; -} - -static int rt3261_modem_input_switch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - return 0; -} -#endif - -static int rt3261_dacr_sel_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - - ucontrol->value.integer.value[0] = (rt3261_index_read(codec, RT3261_MIXER_INT_REG) & 0x4000) >> 14; - - return 0; -} - -static int rt3261_dacr_sel_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - - if(ucontrol->value.integer.value[0]) - rt3261_index_update_bits(codec, RT3261_MIXER_INT_REG, 0x4000, 0x4000); - else - rt3261_index_update_bits(codec, RT3261_MIXER_INT_REG, 0x4000, 0x0); - - - return 0; -} - -static int rt3261_rxdp_sel_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - - ucontrol->value.integer.value[0] = (rt3261_index_read(codec, RT3261_MIXER_INT_REG) & 0x0400) >> 10; - - return 0; -} - -static int rt3261_rxdp_sel_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - - if(ucontrol->value.integer.value[0]) - rt3261_index_update_bits(codec, RT3261_MIXER_INT_REG, 0x0400, 0x0400); - else - rt3261_index_update_bits(codec, RT3261_MIXER_INT_REG, 0x0400, 0x0); - - - return 0; -} - -static int rt3261_rxdp1_sel_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - - ucontrol->value.integer.value[0] = (rt3261_index_read(codec, RT3261_MIXER_INT_REG) & 0x0200) >> 9; - - return 0; -} - -static int rt3261_rxdp1_sel_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - - if(ucontrol->value.integer.value[0]) - rt3261_index_update_bits(codec, RT3261_MIXER_INT_REG, 0x0200, 0x0200); - else - rt3261_index_update_bits(codec, RT3261_MIXER_INT_REG, 0x0200, 0x0); - - - return 0; -} - -/* IN1/IN2 Input Type */ -static const char *rt3261_input_mode[] = { - "Single ended", "Differential"}; - -static const SOC_ENUM_SINGLE_DECL( - rt3261_in1_mode_enum, RT3261_IN1_IN2, - RT3261_IN_SFT1, rt3261_input_mode); - -static const SOC_ENUM_SINGLE_DECL( - rt3261_in2_mode_enum, RT3261_IN3_IN4, - RT3261_IN_SFT2, rt3261_input_mode); - -static const SOC_ENUM_SINGLE_DECL( - rt3261_in3_mode_enum, RT3261_IN1_IN2, - RT3261_IN_SFT2, rt3261_input_mode); - -//output type -static const char *rt3261_output_mode[] = { - "Single ended", "Differential"}; - -static const SOC_ENUM_SINGLE_DECL( - rt3261_lout_mode_enum, RT3261_GEN_CTRL1, - RT3261_LOUT_DF, rt3261_output_mode); - - -/* Interface data select */ -static const char *rt3261_data_select[] = { - "Normal", "Swap", "left copy to right", "right copy to left"}; - -static const SOC_ENUM_SINGLE_DECL(rt3261_if1_dac_enum, RT3261_DIG_INF_DATA, - RT3261_IF1_DAC_SEL_SFT, rt3261_data_select); - -static const SOC_ENUM_SINGLE_DECL(rt3261_if1_adc_enum, RT3261_DIG_INF_DATA, - RT3261_IF1_ADC_SEL_SFT, rt3261_data_select); - -static const SOC_ENUM_SINGLE_DECL(rt3261_if2_dac_enum, RT3261_DIG_INF_DATA, - RT3261_IF2_DAC_SEL_SFT, rt3261_data_select); - -static const SOC_ENUM_SINGLE_DECL(rt3261_if2_adc_enum, RT3261_DIG_INF_DATA, - RT3261_IF2_ADC_SEL_SFT, rt3261_data_select); - -static const SOC_ENUM_SINGLE_DECL(rt3261_if3_dac_enum, RT3261_DIG_INF_DATA, - RT3261_IF3_DAC_SEL_SFT, rt3261_data_select); - -static const SOC_ENUM_SINGLE_DECL(rt3261_if3_adc_enum, RT3261_DIG_INF_DATA, - RT3261_IF3_ADC_SEL_SFT, rt3261_data_select); - -/* Class D speaker gain ratio */ -static const char *rt3261_clsd_spk_ratio[] = {"1.66x", "1.83x", "1.94x", "2x", - "2.11x", "2.22x", "2.33x", "2.44x", "2.55x", "2.66x", "2.77x"}; - -static const SOC_ENUM_SINGLE_DECL( - rt3261_clsd_spk_ratio_enum, RT3261_CLS_D_OUT, - RT3261_CLSD_RATIO_SFT, rt3261_clsd_spk_ratio); - -/* DMIC */ -static const char *rt3261_dmic_mode[] = {"Disable", "DMIC1", "DMIC2"}; - -static const SOC_ENUM_SINGLE_DECL(rt3261_dmic_enum, 0, 0, rt3261_dmic_mode); -/* ASRC */ -static const char *rt3261_asrc_mode[] = {"Disable", "Enable"}; - -static const SOC_ENUM_SINGLE_DECL(rt3261_asrc_enum, 0, 0, rt3261_asrc_mode); - -/* PR-3F */ -static const char *rt3261_dacr_sel_mode[] = {"IF2_DAC", "IF2_ADC"}; - -static const SOC_ENUM_SINGLE_DECL(rt3261_dacr_sel_enum, 0, 0, rt3261_dacr_sel_mode); - -static const char *rt3261_rxdp_sel_mode[] = {"RxDP2", "RxDP1"}; - -static const SOC_ENUM_SINGLE_DECL(rt3261_rxdp_sel_enum, 0, 0, rt3261_rxdp_sel_mode); - -static const char *rt3261_rxdp1_sel_mode[] = {"DAC1", "IF1_DAC"}; - -static const SOC_ENUM_SINGLE_DECL(rt3261_rxdp1_sel_enum, 0, 0, rt3261_rxdp1_sel_mode); - - -//bard 8-9 s -static const char *rt3261_mic_mode[] = {"off", "on",}; -static const SOC_ENUM_SINGLE_DECL(rt3261_mic_enum, 0, 0, rt3261_mic_mode); -//bard 8-9 e - -static const char *rt3261_hp_mute_mode[] = {"off", "on",}; - -static const SOC_ENUM_SINGLE_DECL(rt3261_hp_mute_enum, 0, 0, rt3261_hp_mute_mode); - -static const char *rt3261_modem_input_switch_mode[] = {"off", "on",}; - -static const SOC_ENUM_SINGLE_DECL(rt3261_modem_input_switch_enum, 0, 0, rt3261_modem_input_switch_mode); - -#ifdef RT3261_REG_RW -#define REGVAL_MAX 0xffff -static unsigned int regctl_addr; -static int rt3261_regctl_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 2; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = REGVAL_MAX; - return 0; -} - -static int rt3261_regctl_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - ucontrol->value.integer.value[0] = regctl_addr; - ucontrol->value.integer.value[1] = snd_soc_read(codec, regctl_addr); - return 0; -} - -static int rt3261_regctl_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - regctl_addr = ucontrol->value.integer.value[0]; - if(ucontrol->value.integer.value[1] <= REGVAL_MAX) - snd_soc_write(codec, regctl_addr, ucontrol->value.integer.value[1]); - return 0; -} -#endif - - -static int rt3261_vol_rescale_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct soc_mixer_control *mc = - (struct soc_mixer_control *)kcontrol->private_value; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - unsigned int val = snd_soc_read(codec, mc->reg); - - ucontrol->value.integer.value[0] = RT3261_VOL_RSCL_MAX - - ((val & RT3261_L_VOL_MASK) >> mc->shift); - ucontrol->value.integer.value[1] = RT3261_VOL_RSCL_MAX - - (val & RT3261_R_VOL_MASK); - - return 0; -} - -static int rt3261_vol_rescale_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct soc_mixer_control *mc = - (struct soc_mixer_control *)kcontrol->private_value; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - unsigned int val, val2; - - val = RT3261_VOL_RSCL_MAX - ucontrol->value.integer.value[0]; - val2 = RT3261_VOL_RSCL_MAX - ucontrol->value.integer.value[1]; - return snd_soc_update_bits_locked(codec, mc->reg, RT3261_L_VOL_MASK | - RT3261_R_VOL_MASK, val << mc->shift | val2); -} - - -static const struct snd_kcontrol_new rt3261_snd_controls[] = { - /* Speaker Output Volume */ - SOC_DOUBLE("Speaker Playback Switch", RT3261_SPK_VOL, - RT3261_L_MUTE_SFT, RT3261_R_MUTE_SFT, 1, 1), - SOC_DOUBLE_EXT_TLV("Speaker Playback Volume", RT3261_SPK_VOL, - RT3261_L_VOL_SFT, RT3261_R_VOL_SFT, RT3261_VOL_RSCL_RANGE, 0, - rt3261_vol_rescale_get, rt3261_vol_rescale_put, out_vol_tlv), - SOC_DOUBLE_EXT_TLV("Earpiece Playback Volume", RT3261_SPK_VOL, - RT3261_L_VOL_SFT, RT3261_R_VOL_SFT, RT3261_VOL_RSCL_RANGE, 0, - rt3261_vol_rescale_get, rt3261_vol_rescale_put, out_vol_tlv), - /* Headphone Output Volume */ -/* - SOC_DOUBLE("HP Playback Switch", RT3261_HP_VOL, - RT3261_L_MUTE_SFT, RT3261_R_MUTE_SFT, 1, 1), -*/ - SOC_DOUBLE_EXT_TLV("Headphone Playback Volume", RT3261_HP_VOL, - RT3261_L_VOL_SFT, RT3261_R_VOL_SFT, RT3261_VOL_RSCL_RANGE, 0, - rt3261_vol_rescale_get, rt3261_vol_rescale_put, out_vol_tlv), - /* OUTPUT Control */ - SOC_DOUBLE("OUT Playback Switch", RT3261_OUTPUT, - RT3261_L_MUTE_SFT, RT3261_R_MUTE_SFT, 1, 1), - SOC_DOUBLE("OUT Channel Switch", RT3261_OUTPUT, - RT3261_VOL_L_SFT, RT3261_VOL_R_SFT, 1, 1), - SOC_DOUBLE_TLV("OUT Playback Volume", RT3261_OUTPUT, - RT3261_L_VOL_SFT, RT3261_R_VOL_SFT, 39, 1, out_vol_tlv), - /* MONO Output Control */ - SOC_SINGLE("Mono Playback Switch", RT3261_MONO_OUT, - RT3261_L_MUTE_SFT, 1, 1), - /* DAC Digital Volume */ - SOC_DOUBLE("DAC2 Playback Switch", RT3261_DAC2_CTRL, - RT3261_M_DAC_L2_VOL_SFT, RT3261_M_DAC_R2_VOL_SFT, 1, 1), - SOC_DOUBLE_TLV("DAC1 Playback Volume", RT3261_DAC1_DIG_VOL, - RT3261_L_VOL_SFT, RT3261_R_VOL_SFT, - 175, 0, dac_vol_tlv), - SOC_DOUBLE_TLV("Mono DAC Playback Volume", RT3261_DAC2_DIG_VOL, - RT3261_L_VOL_SFT, RT3261_R_VOL_SFT, - 175, 0, dac_vol_tlv), - /* IN1/IN2 Control */ - SOC_ENUM("IN1 Mode Control", rt3261_in1_mode_enum), - SOC_SINGLE_TLV("IN1 Boost", RT3261_IN1_IN2, - RT3261_BST_SFT1, 8, 0, bst_tlv), - SOC_ENUM("IN2 Mode Control", rt3261_in2_mode_enum), - SOC_SINGLE_TLV("IN2 Boost", RT3261_IN3_IN4, - RT3261_BST_SFT2, 8, 0, bst_tlv), - SOC_ENUM("IN3 Mode Control", rt3261_in3_mode_enum), - SOC_SINGLE_TLV("IN3 Boost", RT3261_IN1_IN2, - RT3261_BST_SFT2, 8, 0, bst_tlv), - - SOC_ENUM("LOUT Mode Control", rt3261_lout_mode_enum), - /* INL/INR Volume Control */ - SOC_DOUBLE_TLV("IN Capture Volume", RT3261_INL_INR_VOL, - RT3261_INL_VOL_SFT, RT3261_INR_VOL_SFT, - 31, 1, in_vol_tlv), - /* ADC Digital Volume Control */ - SOC_DOUBLE("ADC Capture Switch", RT3261_ADC_DIG_VOL, - RT3261_L_MUTE_SFT, RT3261_R_MUTE_SFT, 1, 1), - SOC_DOUBLE_TLV("ADC Capture Volume", RT3261_ADC_DIG_VOL, - RT3261_L_VOL_SFT, RT3261_R_VOL_SFT, - 127, 0, adc_vol_tlv), - SOC_DOUBLE_TLV("Mono ADC Capture Volume", RT3261_ADC_DATA, - RT3261_L_VOL_SFT, RT3261_R_VOL_SFT, - 127, 0, adc_vol_tlv), - /* ADC Boost Volume Control */ - SOC_DOUBLE_TLV("ADC Boost Gain", RT3261_ADC_BST_VOL, - RT3261_ADC_L_BST_SFT, RT3261_ADC_R_BST_SFT, - 3, 0, adc_bst_tlv), - /* Class D speaker gain ratio */ - SOC_ENUM("Class D SPK Ratio Control", rt3261_clsd_spk_ratio_enum), - /* DMIC */ - SOC_ENUM_EXT("DMIC Switch", rt3261_dmic_enum, - rt3261_dmic_get, rt3261_dmic_put), - /* ASRC */ - SOC_ENUM_EXT("ASRC Switch", rt3261_asrc_enum, - rt3261_asrc_get, rt3261_asrc_put), - /* PR-3F */ - SOC_ENUM_EXT("DACR Select", rt3261_dacr_sel_enum, - rt3261_dacr_sel_get, rt3261_dacr_sel_put), - SOC_ENUM_EXT("RxDP Select", rt3261_rxdp_sel_enum, - rt3261_rxdp_sel_get, rt3261_rxdp_sel_put), - SOC_ENUM_EXT("RxDP1 Select", rt3261_rxdp1_sel_enum, - rt3261_rxdp1_sel_get, rt3261_rxdp1_sel_put), -#ifdef RT3261_REG_RW - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Register Control", - .info = rt3261_regctl_info, - .get = rt3261_regctl_get, - .put = rt3261_regctl_put, - }, -#endif -//bard 8-9 s - SOC_SINGLE_TLV("Main Mic Capture Volume", RT3261_IN1_IN2, - RT3261_BST_SFT1, 8, 0, bst_tlv), - SOC_SINGLE_TLV("Headset Mic Capture Volume", RT3261_IN3_IN4, - RT3261_BST_SFT2, 8, 0, bst_tlv), - SOC_ENUM_EXT("Main Mic Capture Switch", rt3261_mic_enum, - rt3261_mic1_get, rt3261_mic1_put), - SOC_ENUM_EXT("Headset Mic Capture Switch", rt3261_mic_enum, - rt3261_mic2_get, rt3261_mic2_put), -//bard 8-9 e - - SOC_ENUM_EXT("HP mute Switch", rt3261_hp_mute_enum, - rt3261_hp_mute_get, rt3261_hp_mute_put), - - SOC_ENUM_EXT("Modem Input Switch", rt3261_modem_input_switch_enum, - rt3261_modem_input_switch_get, rt3261_modem_input_switch_put), - - SOC_ENUM("ADC IF1 Data Switch", rt3261_if1_adc_enum), - SOC_ENUM("DAC IF1 Data Switch", rt3261_if1_dac_enum), - SOC_ENUM("ADC IF2 Data Switch", rt3261_if2_adc_enum), - SOC_ENUM("DAC IF2 Data Switch", rt3261_if2_dac_enum), -}; - -/** - * set_dmic_clk - Set parameter of dmic. - * - * @w: DAPM widget. - * @kcontrol: The kcontrol of this widget. - * @event: Event id. - * - * Choose dmic clock between 1MHz and 3MHz. - * It is better for clock to approximate 3MHz. - */ -static int set_dmic_clk(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = w->codec; - struct rt3261_priv *rt3261 = snd_soc_codec_get_drvdata(codec); - int div[] = {2, 3, 4, 6, 12}, idx = -EINVAL, i, rate, red, bound, temp; - - rate = rt3261->lrck[rt3261->aif_pu] << 8; - red = 3000000 * 12; - for (i = 0; i < ARRAY_SIZE(div); i++) { - bound = div[i] * 3000000; - if (rate > bound) - continue; - temp = bound - rate; - if (temp < red) { - red = temp; - idx = i; - } - } - if (idx < 0) - dev_err(codec->dev, "Failed to set DMIC clock\n"); - else - snd_soc_update_bits(codec, RT3261_DMIC, RT3261_DMIC_CLK_MASK, - idx << RT3261_DMIC_CLK_SFT); - return idx; -} - -static int check_sysclk1_source(struct snd_soc_dapm_widget *source, - struct snd_soc_dapm_widget *sink) -{ - unsigned int val; - - val = snd_soc_read(source->codec, RT3261_GLB_CLK); - val &= RT3261_SCLK_SRC_MASK; - if (val == RT3261_SCLK_SRC_PLL1) - return 1; - else - return 0; -} - -/* Digital Mixer */ -static const struct snd_kcontrol_new rt3261_sto_adc_l_mix[] = { - SOC_DAPM_SINGLE("ADC1 Switch", RT3261_STO_ADC_MIXER, - RT3261_M_ADC_L1_SFT, 1, 1), - SOC_DAPM_SINGLE("ADC2 Switch", RT3261_STO_ADC_MIXER, - RT3261_M_ADC_L2_SFT, 1, 1), -}; - -static const struct snd_kcontrol_new rt3261_sto_adc_r_mix[] = { - SOC_DAPM_SINGLE("ADC1 Switch", RT3261_STO_ADC_MIXER, - RT3261_M_ADC_R1_SFT, 1, 1), - SOC_DAPM_SINGLE("ADC2 Switch", RT3261_STO_ADC_MIXER, - RT3261_M_ADC_R2_SFT, 1, 1), -}; - -static const struct snd_kcontrol_new rt3261_mono_adc_l_mix[] = { - SOC_DAPM_SINGLE("ADC1 Switch", RT3261_MONO_ADC_MIXER, - RT3261_M_MONO_ADC_L1_SFT, 1, 1), - SOC_DAPM_SINGLE("ADC2 Switch", RT3261_MONO_ADC_MIXER, - RT3261_M_MONO_ADC_L2_SFT, 1, 1), -}; - -static const struct snd_kcontrol_new rt3261_mono_adc_r_mix[] = { - SOC_DAPM_SINGLE("ADC1 Switch", RT3261_MONO_ADC_MIXER, - RT3261_M_MONO_ADC_R1_SFT, 1, 1), - SOC_DAPM_SINGLE("ADC2 Switch", RT3261_MONO_ADC_MIXER, - RT3261_M_MONO_ADC_R2_SFT, 1, 1), -}; - -static const struct snd_kcontrol_new rt3261_dac_l_mix[] = { - SOC_DAPM_SINGLE("Stereo ADC Switch", RT3261_AD_DA_MIXER, - RT3261_M_ADCMIX_L_SFT, 1, 1), - SOC_DAPM_SINGLE("INF1 Switch", RT3261_AD_DA_MIXER, - RT3261_M_IF1_DAC_L_SFT, 1, 1), -}; - -static const struct snd_kcontrol_new rt3261_dac_r_mix[] = { - SOC_DAPM_SINGLE("Stereo ADC Switch", RT3261_AD_DA_MIXER, - RT3261_M_ADCMIX_R_SFT, 1, 1), - SOC_DAPM_SINGLE("INF1 Switch", RT3261_AD_DA_MIXER, - RT3261_M_IF1_DAC_R_SFT, 1, 1), -}; - -static const struct snd_kcontrol_new rt3261_sto_dac_l_mix[] = { - SOC_DAPM_SINGLE("DAC L1 Switch", RT3261_STO_DAC_MIXER, - RT3261_M_DAC_L1_SFT, 1, 1), - SOC_DAPM_SINGLE("DAC L2 Switch", RT3261_STO_DAC_MIXER, - RT3261_M_DAC_L2_SFT, 1, 1), - SOC_DAPM_SINGLE("ANC Switch", RT3261_STO_DAC_MIXER, - RT3261_M_ANC_DAC_L_SFT, 1, 1), -}; - -static const struct snd_kcontrol_new rt3261_sto_dac_r_mix[] = { - SOC_DAPM_SINGLE("DAC R1 Switch", RT3261_STO_DAC_MIXER, - RT3261_M_DAC_R1_SFT, 1, 1), - SOC_DAPM_SINGLE("DAC R2 Switch", RT3261_STO_DAC_MIXER, - RT3261_M_DAC_R2_SFT, 1, 1), - SOC_DAPM_SINGLE("ANC Switch", RT3261_STO_DAC_MIXER, - RT3261_M_ANC_DAC_R_SFT, 1, 1), -}; - -static const struct snd_kcontrol_new rt3261_mono_dac_l_mix[] = { - SOC_DAPM_SINGLE("DAC L1 Switch", RT3261_MONO_DAC_MIXER, - RT3261_M_DAC_L1_MONO_L_SFT, 1, 1), - SOC_DAPM_SINGLE("DAC L2 Switch", RT3261_MONO_DAC_MIXER, - RT3261_M_DAC_L2_MONO_L_SFT, 1, 1), - SOC_DAPM_SINGLE("DAC R2 Switch", RT3261_MONO_DAC_MIXER, - RT3261_M_DAC_R2_MONO_L_SFT, 1, 1), -}; - -static const struct snd_kcontrol_new rt3261_mono_dac_r_mix[] = { - SOC_DAPM_SINGLE("DAC R1 Switch", RT3261_MONO_DAC_MIXER, - RT3261_M_DAC_R1_MONO_R_SFT, 1, 1), - SOC_DAPM_SINGLE("DAC R2 Switch", RT3261_MONO_DAC_MIXER, - RT3261_M_DAC_R2_MONO_R_SFT, 1, 1), - SOC_DAPM_SINGLE("DAC L2 Switch", RT3261_MONO_DAC_MIXER, - RT3261_M_DAC_L2_MONO_R_SFT, 1, 1), -}; - -static const struct snd_kcontrol_new rt3261_dig_l_mix[] = { - SOC_DAPM_SINGLE("DAC L1 Switch", RT3261_DIG_MIXER, - RT3261_M_STO_L_DAC_L_SFT, 1, 1), - SOC_DAPM_SINGLE("DAC L2 Switch", RT3261_DIG_MIXER, - RT3261_M_DAC_L2_DAC_L_SFT, 1, 1), -}; - -static const struct snd_kcontrol_new rt3261_dig_r_mix[] = { - SOC_DAPM_SINGLE("DAC R1 Switch", RT3261_DIG_MIXER, - RT3261_M_STO_R_DAC_R_SFT, 1, 1), - SOC_DAPM_SINGLE("DAC R2 Switch", RT3261_DIG_MIXER, - RT3261_M_DAC_R2_DAC_R_SFT, 1, 1), -}; - -/* Analog Input Mixer */ -static const struct snd_kcontrol_new rt3261_rec_l_mix[] = { - SOC_DAPM_SINGLE("HPOL Switch", RT3261_REC_L2_MIXER, - RT3261_M_HP_L_RM_L_SFT, 1, 1), - SOC_DAPM_SINGLE("INL Switch", RT3261_REC_L2_MIXER, - RT3261_M_IN_L_RM_L_SFT, 1, 1), - SOC_DAPM_SINGLE("BST3 Switch", RT3261_REC_L2_MIXER, - RT3261_M_BST2_RM_L, 1, 1), - SOC_DAPM_SINGLE("BST2 Switch", RT3261_REC_L2_MIXER, - RT3261_M_BST4_RM_L_SFT, 1, 1), - SOC_DAPM_SINGLE("BST1 Switch", RT3261_REC_L2_MIXER, - RT3261_M_BST1_RM_L_SFT, 1, 1), - SOC_DAPM_SINGLE("OUT MIXL Switch", RT3261_REC_L2_MIXER, - RT3261_M_OM_L_RM_L_SFT, 1, 1), -}; - -static const struct snd_kcontrol_new rt3261_rec_r_mix[] = { - SOC_DAPM_SINGLE("HPOR Switch", RT3261_REC_R2_MIXER, - RT3261_M_HP_R_RM_R_SFT, 1, 1), - SOC_DAPM_SINGLE("INR Switch", RT3261_REC_R2_MIXER, - RT3261_M_IN_R_RM_R_SFT, 1, 1), - SOC_DAPM_SINGLE("BST3 Switch", RT3261_REC_R2_MIXER, - RT3261_M_BST2_RM_R_SFT, 1, 1), - SOC_DAPM_SINGLE("BST2 Switch", RT3261_REC_R2_MIXER, - RT3261_M_BST4_RM_R_SFT, 1, 1), - SOC_DAPM_SINGLE("BST1 Switch", RT3261_REC_R2_MIXER, - RT3261_M_BST1_RM_R_SFT, 1, 1), - SOC_DAPM_SINGLE("OUT MIXR Switch", RT3261_REC_R2_MIXER, - RT3261_M_OM_R_RM_R_SFT, 1, 1), -}; - -/* Analog Output Mixer */ -static const struct snd_kcontrol_new rt3261_spk_l_mix[] = { - SOC_DAPM_SINGLE("REC MIXL Switch", RT3261_SPK_L_MIXER, - RT3261_M_RM_L_SM_L_SFT, 1, 1), - SOC_DAPM_SINGLE("INL Switch", RT3261_SPK_L_MIXER, - RT3261_M_IN_L_SM_L_SFT, 1, 1), - SOC_DAPM_SINGLE("DAC L1 Switch", RT3261_SPK_L_MIXER, - RT3261_M_DAC_L1_SM_L_SFT, 1, 1), - SOC_DAPM_SINGLE("DAC L2 Switch", RT3261_SPK_L_MIXER, - RT3261_M_DAC_L2_SM_L_SFT, 1, 1), - SOC_DAPM_SINGLE("OUT MIXL Switch", RT3261_SPK_L_MIXER, - RT3261_M_OM_L_SM_L_SFT, 1, 1), -}; - -static const struct snd_kcontrol_new rt3261_spk_r_mix[] = { - SOC_DAPM_SINGLE("REC MIXR Switch", RT3261_SPK_R_MIXER, - RT3261_M_RM_R_SM_R_SFT, 1, 1), - SOC_DAPM_SINGLE("INR Switch", RT3261_SPK_R_MIXER, - RT3261_M_IN_R_SM_R_SFT, 1, 1), - SOC_DAPM_SINGLE("DAC R1 Switch", RT3261_SPK_R_MIXER, - RT3261_M_DAC_R1_SM_R_SFT, 1, 1), - SOC_DAPM_SINGLE("DAC R2 Switch", RT3261_SPK_R_MIXER, - RT3261_M_DAC_R2_SM_R_SFT, 1, 1), - SOC_DAPM_SINGLE("OUT MIXR Switch", RT3261_SPK_R_MIXER, - RT3261_M_OM_R_SM_R_SFT, 1, 1), -}; - -static const struct snd_kcontrol_new rt3261_out_l_mix[] = { - SOC_DAPM_SINGLE("SPK MIXL Switch", RT3261_OUT_L3_MIXER, - RT3261_M_SM_L_OM_L_SFT, 1, 1), - SOC_DAPM_SINGLE("BST3 Switch", RT3261_OUT_L3_MIXER, - RT3261_M_BST2_OM_L_SFT, 1, 1), - SOC_DAPM_SINGLE("BST1 Switch", RT3261_OUT_L3_MIXER, - RT3261_M_BST1_OM_L_SFT, 1, 1), - SOC_DAPM_SINGLE("INL Switch", RT3261_OUT_L3_MIXER, - RT3261_M_IN_L_OM_L_SFT, 1, 1), - SOC_DAPM_SINGLE("REC MIXL Switch", RT3261_OUT_L3_MIXER, - RT3261_M_RM_L_OM_L_SFT, 1, 1), - SOC_DAPM_SINGLE("DAC R2 Switch", RT3261_OUT_L3_MIXER, - RT3261_M_DAC_R2_OM_L_SFT, 1, 1), - SOC_DAPM_SINGLE("DAC L2 Switch", RT3261_OUT_L3_MIXER, - RT3261_M_DAC_L2_OM_L_SFT, 1, 1), - SOC_DAPM_SINGLE("DAC L1 Switch", RT3261_OUT_L3_MIXER, - RT3261_M_DAC_L1_OM_L_SFT, 1, 1), -}; - -static const struct snd_kcontrol_new rt3261_out_r_mix[] = { - SOC_DAPM_SINGLE("SPK MIXR Switch", RT3261_OUT_R3_MIXER, - RT3261_M_SM_L_OM_R_SFT, 1, 1), - SOC_DAPM_SINGLE("BST3 Switch", RT3261_OUT_R3_MIXER, - RT3261_M_BST2_OM_R_SFT, 1, 1), - SOC_DAPM_SINGLE("BST2 Switch", RT3261_OUT_R3_MIXER, - RT3261_M_BST4_OM_R_SFT, 1, 1), - SOC_DAPM_SINGLE("BST1 Switch", RT3261_OUT_R3_MIXER, - RT3261_M_BST1_OM_R_SFT, 1, 1), - SOC_DAPM_SINGLE("INR Switch", RT3261_OUT_R3_MIXER, - RT3261_M_IN_R_OM_R_SFT, 1, 1), - SOC_DAPM_SINGLE("REC MIXR Switch", RT3261_OUT_R3_MIXER, - RT3261_M_RM_R_OM_R_SFT, 1, 1), - SOC_DAPM_SINGLE("DAC L2 Switch", RT3261_OUT_R3_MIXER, - RT3261_M_DAC_L2_OM_R_SFT, 1, 1), - SOC_DAPM_SINGLE("DAC R2 Switch", RT3261_OUT_R3_MIXER, - RT3261_M_DAC_R2_OM_R_SFT, 1, 1), - SOC_DAPM_SINGLE("DAC R1 Switch", RT3261_OUT_R3_MIXER, - RT3261_M_DAC_R1_OM_R_SFT, 1, 1), -}; - -static const struct snd_kcontrol_new rt3261_spo_l_mix[] = { -#if 0 //org - SOC_DAPM_SINGLE("DAC R1 Switch", RT3261_SPO_L_MIXER, - RT3261_M_DAC_R1_SPM_L_SFT, 1, 1), - SOC_DAPM_SINGLE("DAC L1 Switch", RT3261_SPO_L_MIXER, - RT3261_M_DAC_L1_SPM_L_SFT, 1, 1), -#else //bard 8-27 - SOC_DAPM_SINGLE("DAC Switch", RT3261_DUMMY_SPKMIXER, - RT3261_M_DAC_R1_SPM_L_SFT, 1, 1), -#endif - SOC_DAPM_SINGLE("SPKVOL R Switch", RT3261_SPO_L_MIXER, - RT3261_M_SV_R_SPM_L_SFT, 1, 1), - SOC_DAPM_SINGLE("SPKVOL L Switch", RT3261_SPO_L_MIXER, - RT3261_M_SV_L_SPM_L_SFT, 1, 1), - SOC_DAPM_SINGLE("BST1 Switch", RT3261_SPO_L_MIXER, - RT3261_M_BST1_SPM_L_SFT, 1, 1), -}; -//bard 8-27 s -static const struct snd_kcontrol_new rt3261_spo_dac_mix[] = { - SOC_DAPM_SINGLE("DAC R1 Switch", RT3261_SPO_L_MIXER, - RT3261_M_DAC_R1_SPM_L_SFT, 1, 1), - SOC_DAPM_SINGLE("DAC L1 Switch", RT3261_SPO_L_MIXER, - RT3261_M_DAC_L1_SPM_L_SFT, 1, 1), - -}; -//bard 8-27 e -static const struct snd_kcontrol_new rt3261_spo_r_mix[] = { - SOC_DAPM_SINGLE("DAC R1 Switch", RT3261_SPO_R_MIXER, - RT3261_M_DAC_R1_SPM_R_SFT, 1, 1), - SOC_DAPM_SINGLE("SPKVOL R Switch", RT3261_SPO_R_MIXER, - RT3261_M_SV_R_SPM_R_SFT, 1, 1), - SOC_DAPM_SINGLE("BST1 Switch", RT3261_SPO_R_MIXER, - RT3261_M_BST1_SPM_R_SFT, 1, 1), -}; - -static const struct snd_kcontrol_new rt3261_hpo_mix[] = { - SOC_DAPM_SINGLE("DAC2 Switch", RT3261_HPO_MIXER, - RT3261_M_DAC2_HM_SFT, 1, 1), - SOC_DAPM_SINGLE("DAC1 Switch", RT3261_HPO_MIXER, - RT3261_M_DAC1_HM_SFT, 1, 1), - SOC_DAPM_SINGLE("HPVOL Switch", RT3261_HPO_MIXER, - RT3261_M_HPVOL_HM_SFT, 1, 1), -}; - -static const struct snd_kcontrol_new rt3261_lout_mix[] = { - SOC_DAPM_SINGLE("DAC L1 Switch", RT3261_LOUT_MIXER, - RT3261_M_DAC_L1_LM_SFT, 1, 1), - SOC_DAPM_SINGLE("DAC R1 Switch", RT3261_LOUT_MIXER, - RT3261_M_DAC_R1_LM_SFT, 1, 1), - SOC_DAPM_SINGLE("OUTVOL L Switch", RT3261_LOUT_MIXER, - RT3261_M_OV_L_LM_SFT, 1, 1), - SOC_DAPM_SINGLE("OUTVOL R Switch", RT3261_LOUT_MIXER, - RT3261_M_OV_R_LM_SFT, 1, 1), -}; - -static const struct snd_kcontrol_new rt3261_mono_mix[] = { - SOC_DAPM_SINGLE("DAC R2 Switch", RT3261_MONO_MIXER, - RT3261_M_DAC_R2_MM_SFT, 1, 1), - SOC_DAPM_SINGLE("DAC L2 Switch", RT3261_MONO_MIXER, - RT3261_M_DAC_L2_MM_SFT, 1, 1), - SOC_DAPM_SINGLE("OUTVOL R Switch", RT3261_MONO_MIXER, - RT3261_M_OV_R_MM_SFT, 1, 1), - SOC_DAPM_SINGLE("OUTVOL L Switch", RT3261_MONO_MIXER, - RT3261_M_OV_L_MM_SFT, 1, 1), - SOC_DAPM_SINGLE("BST1 Switch", RT3261_MONO_MIXER, - RT3261_M_BST1_MM_SFT, 1, 1), -}; - -/* INL/R source */ -static const char *rt3261_inl_src[] = {"IN2P", "MonoP"}; - -static const SOC_ENUM_SINGLE_DECL( - rt3261_inl_enum, RT3261_INL_INR_VOL, - RT3261_INL_SEL_SFT, rt3261_inl_src); - -static const struct snd_kcontrol_new rt3261_inl_mux = - SOC_DAPM_ENUM("INL source", rt3261_inl_enum); - -static const char *rt3261_inr_src[] = {"IN2N", "MonoN"}; - -static const SOC_ENUM_SINGLE_DECL( - rt3261_inr_enum, RT3261_INL_INR_VOL, - RT3261_INR_SEL_SFT, rt3261_inr_src); - -static const struct snd_kcontrol_new rt3261_inr_mux = - SOC_DAPM_ENUM("INR source", rt3261_inr_enum); - -/* Stereo ADC source */ -static const char *rt3261_stereo_adc1_src[] = {"DIG MIX", "ADC"}; - -static const SOC_ENUM_SINGLE_DECL( - rt3261_stereo_adc1_enum, RT3261_STO_ADC_MIXER, - RT3261_ADC_1_SRC_SFT, rt3261_stereo_adc1_src); - -static const struct snd_kcontrol_new rt3261_sto_adc_l1_mux = - SOC_DAPM_ENUM("Stereo ADC L1 source", rt3261_stereo_adc1_enum); - -static const struct snd_kcontrol_new rt3261_sto_adc_r1_mux = - SOC_DAPM_ENUM("Stereo ADC R1 source", rt3261_stereo_adc1_enum); - -static const char *rt3261_stereo_adc2_src[] = {"DMIC1", "DMIC2", "DIG MIX"}; - -static const SOC_ENUM_SINGLE_DECL( - rt3261_stereo_adc2_enum, RT3261_STO_ADC_MIXER, - RT3261_ADC_2_SRC_SFT, rt3261_stereo_adc2_src); - -static const struct snd_kcontrol_new rt3261_sto_adc_l2_mux = - SOC_DAPM_ENUM("Stereo ADC L2 source", rt3261_stereo_adc2_enum); - -static const struct snd_kcontrol_new rt3261_sto_adc_r2_mux = - SOC_DAPM_ENUM("Stereo ADC R2 source", rt3261_stereo_adc2_enum); - -/* Mono ADC source */ -static const char *rt3261_mono_adc_l1_src[] = {"Mono DAC MIXL", "ADCL"}; - -static const SOC_ENUM_SINGLE_DECL( - rt3261_mono_adc_l1_enum, RT3261_MONO_ADC_MIXER, - RT3261_MONO_ADC_L1_SRC_SFT, rt3261_mono_adc_l1_src); - -static const struct snd_kcontrol_new rt3261_mono_adc_l1_mux = - SOC_DAPM_ENUM("Mono ADC1 left source", rt3261_mono_adc_l1_enum); - -static const char *rt3261_mono_adc_l2_src[] = - {"DMIC L1", "DMIC L2", "Mono DAC MIXL"}; - -static const SOC_ENUM_SINGLE_DECL( - rt3261_mono_adc_l2_enum, RT3261_MONO_ADC_MIXER, - RT3261_MONO_ADC_L2_SRC_SFT, rt3261_mono_adc_l2_src); - -static const struct snd_kcontrol_new rt3261_mono_adc_l2_mux = - SOC_DAPM_ENUM("Mono ADC2 left source", rt3261_mono_adc_l2_enum); - -static const char *rt3261_mono_adc_r1_src[] = {"Mono DAC MIXR", "ADCR"}; - -static const SOC_ENUM_SINGLE_DECL( - rt3261_mono_adc_r1_enum, RT3261_MONO_ADC_MIXER, - RT3261_MONO_ADC_R1_SRC_SFT, rt3261_mono_adc_r1_src); - -static const struct snd_kcontrol_new rt3261_mono_adc_r1_mux = - SOC_DAPM_ENUM("Mono ADC1 right source", rt3261_mono_adc_r1_enum); - -static const char *rt3261_mono_adc_r2_src[] = - {"DMIC R1", "DMIC R2", "Mono DAC MIXR"}; - -static const SOC_ENUM_SINGLE_DECL( - rt3261_mono_adc_r2_enum, RT3261_MONO_ADC_MIXER, - RT3261_MONO_ADC_R2_SRC_SFT, rt3261_mono_adc_r2_src); - -static const struct snd_kcontrol_new rt3261_mono_adc_r2_mux = - SOC_DAPM_ENUM("Mono ADC2 right source", rt3261_mono_adc_r2_enum); - -/* DAC2 channel source */ -static const char *rt3261_dac_l2_src[] = {"IF2", "IF3", "TxDC", "Base L/R"}; - -static const SOC_ENUM_SINGLE_DECL(rt3261_dac_l2_enum, RT3261_DSP_PATH2, - RT3261_DAC_L2_SEL_SFT, rt3261_dac_l2_src); - -static const struct snd_kcontrol_new rt3261_dac_l2_mux = - SOC_DAPM_ENUM("DAC2 left channel source", rt3261_dac_l2_enum); - -static const char *rt3261_dac_r2_src[] = {"IF2", "IF3", "TxDC"}; - -static const SOC_ENUM_SINGLE_DECL( - rt3261_dac_r2_enum, RT3261_DSP_PATH2, - RT3261_DAC_R2_SEL_SFT, rt3261_dac_r2_src); - -static const struct snd_kcontrol_new rt3261_dac_r2_mux = - SOC_DAPM_ENUM("DAC2 right channel source", rt3261_dac_r2_enum); - -/* Interface 2 ADC channel source */ -static const char *rt3261_if2_adc_l_src[] = {"TxDP", "Mono ADC MIXL"}; - -static const SOC_ENUM_SINGLE_DECL(rt3261_if2_adc_l_enum, RT3261_DSP_PATH2, - RT3261_IF2_ADC_L_SEL_SFT, rt3261_if2_adc_l_src); - -static const struct snd_kcontrol_new rt3261_if2_adc_l_mux = - SOC_DAPM_ENUM("IF2 ADC left channel source", rt3261_if2_adc_l_enum); - -static const char *rt3261_if2_adc_r_src[] = {"TxDP", "Mono ADC MIXR"}; - -static const SOC_ENUM_SINGLE_DECL(rt3261_if2_adc_r_enum, RT3261_DSP_PATH2, - RT3261_IF2_ADC_R_SEL_SFT, rt3261_if2_adc_r_src); - -static const struct snd_kcontrol_new rt3261_if2_adc_r_mux = - SOC_DAPM_ENUM("IF2 ADC right channel source", rt3261_if2_adc_r_enum); - -/* digital interface and iis interface map */ -static const char *rt3261_dai_iis_map[] = {"1:1|2:2|3:3", "1:1|2:3|3:2", - "1:3|2:1|3:2", "1:3|2:2|3:1", "1:2|2:3|3:1", - "1:2|2:1|3:3", "1:1|2:1|3:3", "1:2|2:2|3:3"}; - -static const SOC_ENUM_SINGLE_DECL( - rt3261_dai_iis_map_enum, RT3261_I2S1_SDP, - RT3261_I2S_IF_SFT, rt3261_dai_iis_map); - -static const struct snd_kcontrol_new rt3261_dai_mux = - SOC_DAPM_ENUM("DAI select", rt3261_dai_iis_map_enum); - -/* SDI select */ -static const char *rt3261_sdi_sel[] = {"IF1", "IF2"}; - -static const SOC_ENUM_SINGLE_DECL( - rt3261_sdi_sel_enum, RT3261_I2S2_SDP, - RT3261_I2S2_SDI_SFT, rt3261_sdi_sel); - -static const struct snd_kcontrol_new rt3261_sdi_mux = - SOC_DAPM_ENUM("SDI select", rt3261_sdi_sel_enum); - -static int rt3261_adc_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - //struct snd_soc_codec *codec = w->codec; - //unsigned int val, mask; - - switch (event) { - case SND_SOC_DAPM_POST_PMU: - //rt3261_index_update_bits(codec, - // RT3261_CHOP_DAC_ADC, 0x1000, 0x1000); - /*bard 3-26 r - val = snd_soc_read(codec, RT3261_MONO_ADC_MIXER); - mask = RT3261_M_MONO_ADC_L1 | RT3261_M_MONO_ADC_L2 | - RT3261_M_MONO_ADC_R1 | RT3261_M_MONO_ADC_R2; - if ((val & mask) ^ mask) - snd_soc_update_bits(codec, RT3261_GEN_CTRL1, - RT3261_M_MAMIX_L | RT3261_M_MAMIX_R, 0); - */ - break; - - case SND_SOC_DAPM_POST_PMD: - /*bard 3-26 r - snd_soc_update_bits(codec, RT3261_GEN_CTRL1, - RT3261_M_MAMIX_L | RT3261_M_MAMIX_R, - RT3261_M_MAMIX_L | RT3261_M_MAMIX_R); - */ - //rt3261_index_update_bits(codec, - // RT3261_CHOP_DAC_ADC, 0x1000, 0x0000); - break; - - default: - return 0; - } - - return 0; -} - -//bard 3-26 s -static int rt3261_mono_adcl_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = w->codec; - //unsigned int val, mask; - - switch (event) { - case SND_SOC_DAPM_POST_PMU: - snd_soc_update_bits(codec, RT3261_GEN_CTRL1, - RT3261_M_MAMIX_L, 0); - break; - case SND_SOC_DAPM_PRE_PMD: - snd_soc_update_bits(codec, RT3261_GEN_CTRL1, - RT3261_M_MAMIX_L, - RT3261_M_MAMIX_L); - break; - - default: - return 0; - } - - return 0; -} - -static int rt3261_mono_adcr_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = w->codec; - //unsigned int val, mask; - - switch (event) { - case SND_SOC_DAPM_POST_PMU: - snd_soc_update_bits(codec, RT3261_GEN_CTRL1, - RT3261_M_MAMIX_R, 0); - break; - case SND_SOC_DAPM_PRE_PMD: - snd_soc_update_bits(codec, RT3261_GEN_CTRL1, - RT3261_M_MAMIX_R, - RT3261_M_MAMIX_R); - break; - - default: - return 0; - } - - return 0; -} -//bard 3-26 e -static int rt3261_spk_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = w->codec; - unsigned int val; - - switch (event) { - case SND_SOC_DAPM_POST_PMU: -//bard 8-26 s - val = snd_soc_read(codec, RT3261_PWR_DIG1); - if(val & (RT3261_PWR_DAC_L1 | RT3261_PWR_DAC_R1)) { - snd_soc_update_bits(codec, RT3261_PWR_DIG1, - RT3261_PWR_DAC_L1 | RT3261_PWR_DAC_R1, - RT3261_PWR_DAC_L1 | RT3261_PWR_DAC_R1); - } -//bard 8-26 e - snd_soc_update_bits(codec, RT3261_PWR_DIG1, - RT3261_PWR_CLS_D, RT3261_PWR_CLS_D); - rt3261_index_update_bits(codec, - RT3261_CLSD_INT_REG1, 0xf000, 0xf000); - snd_soc_update_bits(codec, RT3261_SPK_VOL, - RT3261_L_MUTE | RT3261_R_MUTE, 0); - break; - - case SND_SOC_DAPM_PRE_PMD: - snd_soc_update_bits(codec, RT3261_SPK_VOL, - RT3261_L_MUTE | RT3261_R_MUTE, - RT3261_L_MUTE | RT3261_R_MUTE); - rt3261_index_update_bits(codec, - RT3261_CLSD_INT_REG1, 0xf000, 0x0000); - snd_soc_update_bits(codec, RT3261_PWR_DIG1, - RT3261_PWR_CLS_D, 0); - break; - - default: - return 0; - } - - return 0; -} - -#if 1 //seq -static void rt3261_pmu_depop(struct snd_soc_codec *codec) -{ -#if 0 - /* depop parameters */ - rt3261_index_update_bits(codec, RT3261_CHPUMP_INT_REG1,0x0700, 0x0200); //bard 12-6 - snd_soc_update_bits(codec, RT3261_DEPOP_M2, - RT3261_DEPOP_MASK, RT3261_DEPOP_MAN); - snd_soc_update_bits(codec, RT3261_DEPOP_M1, - RT3261_HP_CP_MASK | RT3261_HP_SG_MASK | RT3261_HP_CB_MASK, - RT3261_HP_CP_PU | RT3261_HP_SG_DIS | RT3261_HP_CB_PU); - rt3261_index_write(codec, RT3261_HP_DCC_INT1, 0x9f00); - /* headphone amp power on */ - snd_soc_update_bits(codec, RT3261_PWR_ANLG1, - RT3261_PWR_FV1 | RT3261_PWR_FV2, 0); - snd_soc_update_bits(codec, RT3261_PWR_VOL, - RT3261_PWR_HV_L | RT3261_PWR_HV_R, - RT3261_PWR_HV_L | RT3261_PWR_HV_R); - snd_soc_update_bits(codec, RT3261_PWR_ANLG1, - RT3261_PWR_HP_L | RT3261_PWR_HP_R | RT3261_PWR_HA, - RT3261_PWR_HP_L | RT3261_PWR_HP_R | RT3261_PWR_HA); - msleep(50); - snd_soc_update_bits(codec, RT3261_PWR_ANLG1, - RT3261_PWR_FV1 | RT3261_PWR_FV2 | RT3261_PWR_HP_L | - RT3261_PWR_HP_R | RT3261_PWR_HA, - RT3261_PWR_FV1 | RT3261_PWR_FV2 | RT3261_PWR_HP_L | - RT3261_PWR_HP_R | RT3261_PWR_HA); - snd_soc_update_bits(codec, RT3261_CHARGE_PUMP, - RT3261_PM_HP_MASK, RT3261_PM_HP_HV); - rt3261_index_update_bits(codec, RT3261_CHOP_DAC_ADC, 0x0200, 0x0200); - snd_soc_update_bits(codec, RT3261_DEPOP_M1, - RT3261_HP_CO_MASK | RT3261_HP_SG_MASK, - RT3261_HP_CO_EN | RT3261_HP_SG_EN); - rt3261_index_update_bits(codec, RT3261_CHPUMP_INT_REG1,0x0700, 0x0400); //bard 12-6 -#else - rt3261_hp_amp_power(codec, 1); -#endif - /* headphone unmute sequence */ - snd_soc_update_bits(codec, RT3261_DEPOP_M3, - RT3261_CP_FQ1_MASK | RT3261_CP_FQ2_MASK | RT3261_CP_FQ3_MASK, - (RT3261_CP_FQ_192_KHZ << RT3261_CP_FQ1_SFT) | - (RT3261_CP_FQ_12_KHZ << RT3261_CP_FQ2_SFT) | - (RT3261_CP_FQ_192_KHZ << RT3261_CP_FQ3_SFT)); - rt3261_index_write(codec, RT3261_MAMP_INT_REG2, 0xfc00); - snd_soc_update_bits(codec, RT3261_DEPOP_M1, - RT3261_SMT_TRIG_MASK, RT3261_SMT_TRIG_EN); - snd_soc_update_bits(codec, RT3261_DEPOP_M1, - RT3261_RSTN_MASK, RT3261_RSTN_EN); - snd_soc_update_bits(codec, RT3261_DEPOP_M1, - RT3261_RSTN_MASK | RT3261_HP_L_SMT_MASK | RT3261_HP_R_SMT_MASK, - RT3261_RSTN_DIS | RT3261_HP_L_SMT_EN | RT3261_HP_R_SMT_EN); - //msleep(30); - snd_soc_update_bits(codec, RT3261_HP_VOL, - RT3261_L_MUTE | RT3261_R_MUTE, 0); - msleep(30); //bard 4-22 - snd_soc_update_bits(codec, RT3261_DEPOP_M1, - RT3261_HP_SG_MASK | RT3261_HP_L_SMT_MASK | - RT3261_HP_R_SMT_MASK, RT3261_HP_SG_DIS | - RT3261_HP_L_SMT_DIS | RT3261_HP_R_SMT_DIS); - /*bard 10-18 r - msleep(20); - snd_soc_update_bits(codec, RT3261_HP_CALIB_AMP_DET, - RT3261_HPD_PS_MASK, RT3261_HPD_PS_EN); - */ -} - -static void rt3261_pmd_depop(struct snd_soc_codec *codec) -{ - /* headphone mute sequence */ - snd_soc_update_bits(codec, RT3261_DEPOP_M3, - RT3261_CP_FQ1_MASK | RT3261_CP_FQ2_MASK | RT3261_CP_FQ3_MASK, - (RT3261_CP_FQ_96_KHZ << RT3261_CP_FQ1_SFT) | - (RT3261_CP_FQ_12_KHZ << RT3261_CP_FQ2_SFT) | - (RT3261_CP_FQ_96_KHZ << RT3261_CP_FQ3_SFT)); - rt3261_index_write(codec, RT3261_MAMP_INT_REG2, 0xfc00); - snd_soc_update_bits(codec, RT3261_DEPOP_M1, - RT3261_HP_SG_MASK, RT3261_HP_SG_EN); - snd_soc_update_bits(codec, RT3261_DEPOP_M1, - RT3261_RSTP_MASK, RT3261_RSTP_EN); - snd_soc_update_bits(codec, RT3261_DEPOP_M1, - RT3261_RSTP_MASK | RT3261_HP_L_SMT_MASK | - RT3261_HP_R_SMT_MASK, RT3261_RSTP_DIS | - RT3261_HP_L_SMT_EN | RT3261_HP_R_SMT_EN); - /*bard 10-18 r - snd_soc_update_bits(codec, RT3261_HP_CALIB_AMP_DET, - RT3261_HPD_PS_MASK, RT3261_HPD_PS_DIS);*/ - //msleep(90); - snd_soc_update_bits(codec, RT3261_HP_VOL, - RT3261_L_MUTE | RT3261_R_MUTE, RT3261_L_MUTE | RT3261_R_MUTE); - msleep(30); -#if 0 - //rt3261_index_update_bits(codec, RT3261_CHOP_DAC_ADC, 0x0200, 0x0); - snd_soc_update_bits(codec, RT3261_DEPOP_M1, - RT3261_HP_SG_MASK | RT3261_HP_L_SMT_MASK | - RT3261_HP_R_SMT_MASK, RT3261_HP_SG_DIS | - RT3261_HP_L_SMT_DIS | RT3261_HP_R_SMT_DIS); - /* headphone amp power down */ - snd_soc_update_bits(codec, RT3261_DEPOP_M1, - RT3261_SMT_TRIG_MASK | RT3261_HP_CD_PD_MASK | - RT3261_HP_CO_MASK | RT3261_HP_CP_MASK | - RT3261_HP_SG_MASK | RT3261_HP_CB_MASK, - RT3261_SMT_TRIG_DIS | RT3261_HP_CD_PD_EN | - RT3261_HP_CO_DIS | RT3261_HP_CP_PD | - RT3261_HP_SG_EN | RT3261_HP_CB_PD); - snd_soc_update_bits(codec, RT3261_PWR_ANLG1, - RT3261_PWR_HP_L | RT3261_PWR_HP_R | RT3261_PWR_HA, - 0); -#else - rt3261_hp_amp_power(codec, 0); -#endif -} -#else //one bit -static void rt3261_pmu_depop(struct snd_soc_codec *codec) -{ - /* depop parameters */ - rt3261_index_update_bits(codec, RT3261_CHPUMP_INT_REG1,0x0700, 0x0200); //bard 12-6 - snd_soc_update_bits(codec, RT3261_DEPOP_M2, - RT3261_DEPOP_MASK, RT3261_DEPOP_MAN); - snd_soc_update_bits(codec, RT3261_DEPOP_M1, - RT3261_HP_CP_MASK | RT3261_HP_SG_MASK | RT3261_HP_CB_MASK, - RT3261_HP_CP_PU | RT3261_HP_SG_DIS | RT3261_HP_CB_PU); - rt3261_index_write(codec, RT3261_HP_DCC_INT1, 0x9f00); - /* headphone amp power on */ - snd_soc_update_bits(codec, RT3261_PWR_ANLG1, - RT3261_PWR_FV1 | RT3261_PWR_FV2, 0); - snd_soc_update_bits(codec, RT3261_PWR_VOL, - RT3261_PWR_HV_L | RT3261_PWR_HV_R, - RT3261_PWR_HV_L | RT3261_PWR_HV_R); - snd_soc_update_bits(codec, RT3261_PWR_ANLG1, - RT3261_PWR_HP_L | RT3261_PWR_HP_R | RT3261_PWR_HA, - RT3261_PWR_HP_L | RT3261_PWR_HP_R | RT3261_PWR_HA); - msleep(50); - snd_soc_update_bits(codec, RT3261_PWR_ANLG1, - RT3261_PWR_FV1 | RT3261_PWR_FV2 , - RT3261_PWR_FV1 | RT3261_PWR_FV2 ); - rt3261_index_update_bits(codec, RT3261_CHOP_DAC_ADC, 0x0200, 0x0200); - /* headphone unmute sequence */ - snd_soc_update_bits(codec, RT3261_DEPOP_M2, - RT3261_DEPOP_MASK | RT3261_DIG_DP_MASK, - RT3261_DEPOP_AUTO | RT3261_DIG_DP_EN); - snd_soc_update_bits(codec, RT3261_CHARGE_PUMP, - RT3261_PM_HP_MASK, RT3261_PM_HP_HV); - snd_soc_update_bits(codec, RT3261_DEPOP_M3, - RT3261_CP_FQ1_MASK | RT3261_CP_FQ2_MASK | RT3261_CP_FQ3_MASK, - (RT3261_CP_FQ_96_KHZ << RT3261_CP_FQ1_SFT) | - (RT3261_CP_FQ_12_KHZ << RT3261_CP_FQ2_SFT) | - (RT3261_CP_FQ_96_KHZ << RT3261_CP_FQ3_SFT)); - snd_soc_update_bits(codec, RT3261_DEPOP_M1, - RT3261_HP_CP_MASK | RT3261_HP_SG_MASK, - RT3261_HP_CP_PD | RT3261_HP_SG_EN); - rt3261_index_update_bits(codec, RT3261_CHPUMP_INT_REG1,0x0700, 0x0400); //bard 12-6 - msleep(10); - snd_soc_update_bits(codec, RT3261_HP_VOL, - RT3261_L_MUTE | RT3261_R_MUTE, 0); - msleep(70); //bard 10-18 - /*bard 10-18 r - snd_soc_update_bits(codec, RT3261_HP_CALIB_AMP_DET, - RT3261_HPD_PS_MASK, RT3261_HPD_PS_EN); - */ -} - -static void rt3261_pmd_depop(struct snd_soc_codec *codec) -{ - /*bard 10-18 r - snd_soc_update_bits(codec, RT3261_HP_CALIB_AMP_DET, - RT3261_HPD_PS_MASK, RT3261_HPD_PS_DIS); - */ - snd_soc_update_bits(codec, RT3261_HP_VOL, - RT3261_L_MUTE | RT3261_R_MUTE, - RT3261_L_MUTE | RT3261_R_MUTE); - snd_soc_update_bits(codec, RT3261_DEPOP_M1, - RT3261_HP_CB_MASK, RT3261_HP_CB_PD); - //rt3261_index_update_bits(codec, RT3261_CHOP_DAC_ADC, 0x0200, 0x0); - snd_soc_update_bits(codec, RT3261_PWR_ANLG1, - RT3261_PWR_HP_L | RT3261_PWR_HP_R | RT3261_PWR_HA, - 0); -} -#endif - -static int rt3261_hp_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = w->codec; - switch (event) { - case SND_SOC_DAPM_POST_PMU: - rt3261_pmu_depop(codec); - break; - - case SND_SOC_DAPM_PRE_PMD: - rt3261_pmd_depop(codec); - break; - - default: - return 0; - } - - return 0; -} - -static int rt3261_mono_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = w->codec; - - switch (event) { - case SND_SOC_DAPM_POST_PMU: - snd_soc_update_bits(codec, RT3261_MONO_OUT, - RT3261_L_MUTE, 0); - break; - - case SND_SOC_DAPM_PRE_PMD: - snd_soc_update_bits(codec, RT3261_MONO_OUT, - RT3261_L_MUTE, RT3261_L_MUTE); - break; - - default: - return 0; - } - - return 0; -} - -static int rt3261_lout_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = w->codec; - - switch (event) { - case SND_SOC_DAPM_POST_PMU: - rt3261_hp_amp_power(codec,1); - snd_soc_update_bits(codec, RT3261_PWR_ANLG1, - RT3261_PWR_LM, RT3261_PWR_LM); //bard 10-18 - snd_soc_update_bits(codec, RT3261_OUTPUT, - RT3261_L_MUTE | RT3261_R_MUTE, 0); - break; - - case SND_SOC_DAPM_PRE_PMD: - snd_soc_update_bits(codec, RT3261_OUTPUT, - RT3261_L_MUTE | RT3261_R_MUTE, - RT3261_L_MUTE | RT3261_R_MUTE); - snd_soc_update_bits(codec, RT3261_PWR_ANLG1, - RT3261_PWR_LM, 0); //bard 10-18 - rt3261_hp_amp_power(codec,0); - break; - - default: - return 0; - } - - return 0; -} -//bard 8-29 s -static int rt3261_dac_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = w->codec; - struct rt3261_priv *rt3261 = snd_soc_codec_get_drvdata(codec); - - switch (event) { - case SND_SOC_DAPM_POST_PMU: - if( rt3261->asrc_en == RT3261_ASRC_EN) - rt3261_update_eqmode(codec, 2);//BT_VOIP - break; - - case SND_SOC_DAPM_PRE_PMD: - rt3261_update_eqmode(codec, 0);//NORMAL - break; - - default: - return 0; - } - - return 0; -} -//bard 8-29 e -static const struct snd_soc_dapm_widget rt3261_dapm_widgets[] = { - SND_SOC_DAPM_SUPPLY("PLL1", RT3261_PWR_ANLG2, - RT3261_PWR_PLL_BIT, 0, NULL, 0), - /* Input Side */ - /* micbias */ - SND_SOC_DAPM_SUPPLY("LDO2", RT3261_PWR_ANLG1, - RT3261_PWR_LDO2_BIT, 0, NULL, 0), - #if 0 - SND_SOC_DAPM_MICBIAS("micbias1", RT3261_PWR_ANLG2, - RT3261_PWR_MB1_BIT, 0), - #else - SND_SOC_DAPM_MICBIAS("micbias1", SND_SOC_NOPM, - 0, 0), - #endif - SND_SOC_DAPM_MICBIAS("micbias2", RT3261_PWR_ANLG2, - RT3261_PWR_MB2_BIT, 0), - /* Input Lines */ - SND_SOC_DAPM_INPUT("MIC1"), - SND_SOC_DAPM_INPUT("MIC2"), - SND_SOC_DAPM_INPUT("MIC3"), - SND_SOC_DAPM_INPUT("DMIC1"), - SND_SOC_DAPM_INPUT("DMIC2"), - - SND_SOC_DAPM_INPUT("IN1P"), - SND_SOC_DAPM_INPUT("IN1N"), - SND_SOC_DAPM_INPUT("IN2P"), - SND_SOC_DAPM_INPUT("IN2N"), - SND_SOC_DAPM_INPUT("IN3P"), - SND_SOC_DAPM_INPUT("IN3N"), - SND_SOC_DAPM_INPUT("DMIC L1"), - SND_SOC_DAPM_INPUT("DMIC R1"), - SND_SOC_DAPM_INPUT("DMIC L2"), - SND_SOC_DAPM_INPUT("DMIC R2"), - SND_SOC_DAPM_SUPPLY("DMIC CLK", SND_SOC_NOPM, 0, 0, - set_dmic_clk, SND_SOC_DAPM_PRE_PMU), - /* Boost */ - SND_SOC_DAPM_PGA("BST1", RT3261_PWR_ANLG2, - RT3261_PWR_BST1_BIT, 0, NULL, 0), - SND_SOC_DAPM_PGA("BST2", RT3261_PWR_ANLG2, - RT3261_PWR_BST4_BIT, 0, NULL, 0), - SND_SOC_DAPM_PGA("BST3", RT3261_PWR_ANLG2, - RT3261_PWR_BST2_BIT, 0, NULL, 0), - /* Input Volume */ - SND_SOC_DAPM_PGA("INL VOL", RT3261_PWR_VOL, - RT3261_PWR_IN_L_BIT, 0, NULL, 0), - SND_SOC_DAPM_PGA("INR VOL", RT3261_PWR_VOL, - RT3261_PWR_IN_R_BIT, 0, NULL, 0), - /* IN Mux */ -/* - SND_SOC_DAPM_MUX("INL Mux", SND_SOC_NOPM, 0, 0, &rt3261_inl_mux), - SND_SOC_DAPM_MUX("INR Mux", SND_SOC_NOPM, 0, 0, &rt3261_inr_mux), -*/ - /* REC Mixer */ - SND_SOC_DAPM_MIXER("RECMIXL", RT3261_PWR_MIXER, RT3261_PWR_RM_L_BIT, 0, - rt3261_rec_l_mix, ARRAY_SIZE(rt3261_rec_l_mix)), - SND_SOC_DAPM_MIXER("RECMIXR", RT3261_PWR_MIXER, RT3261_PWR_RM_R_BIT, 0, - rt3261_rec_r_mix, ARRAY_SIZE(rt3261_rec_r_mix)), - /* ADCs */ - SND_SOC_DAPM_ADC("ADC L", NULL, SND_SOC_NOPM, - 0, 0), - SND_SOC_DAPM_ADC_E("ADC R", NULL, SND_SOC_NOPM, - 0, 0, rt3261_adc_event, - SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU), - - SND_SOC_DAPM_SUPPLY("ADC L power",RT3261_PWR_DIG1, - RT3261_PWR_ADC_L_BIT, 0, NULL, 0), - SND_SOC_DAPM_SUPPLY("ADC R power",RT3261_PWR_DIG1, - RT3261_PWR_ADC_R_BIT, 0, NULL, 0), - /* ADC Mux */ - SND_SOC_DAPM_MUX("Stereo ADC L2 Mux", SND_SOC_NOPM, 0, 0, - &rt3261_sto_adc_l2_mux), - SND_SOC_DAPM_MUX("Stereo ADC R2 Mux", SND_SOC_NOPM, 0, 0, - &rt3261_sto_adc_r2_mux), - SND_SOC_DAPM_MUX("Stereo ADC L1 Mux", SND_SOC_NOPM, 0, 0, - &rt3261_sto_adc_l1_mux), - SND_SOC_DAPM_MUX("Stereo ADC R1 Mux", SND_SOC_NOPM, 0, 0, - &rt3261_sto_adc_r1_mux), - SND_SOC_DAPM_MUX("Mono ADC L2 Mux", SND_SOC_NOPM, 0, 0, - &rt3261_mono_adc_l2_mux), - SND_SOC_DAPM_MUX("Mono ADC L1 Mux", SND_SOC_NOPM, 0, 0, - &rt3261_mono_adc_l1_mux), - SND_SOC_DAPM_MUX("Mono ADC R1 Mux", SND_SOC_NOPM, 0, 0, - &rt3261_mono_adc_r1_mux), - SND_SOC_DAPM_MUX("Mono ADC R2 Mux", SND_SOC_NOPM, 0, 0, - &rt3261_mono_adc_r2_mux), - /* ADC Mixer */ - SND_SOC_DAPM_SUPPLY("stereo filter", RT3261_PWR_DIG2, - RT3261_PWR_ADC_SF_BIT, 0, NULL, 0), - SND_SOC_DAPM_MIXER("Stereo ADC MIXL", SND_SOC_NOPM, 0, 0, - rt3261_sto_adc_l_mix, ARRAY_SIZE(rt3261_sto_adc_l_mix)), - SND_SOC_DAPM_MIXER("Stereo ADC MIXR", SND_SOC_NOPM, 0, 0, - rt3261_sto_adc_r_mix, ARRAY_SIZE(rt3261_sto_adc_r_mix)), - SND_SOC_DAPM_SUPPLY("mono left filter", RT3261_PWR_DIG2, - RT3261_PWR_ADC_MF_L_BIT, 0, NULL, 0), - SND_SOC_DAPM_MIXER_E("Mono ADC MIXL", SND_SOC_NOPM, 0, 0, - rt3261_mono_adc_l_mix, ARRAY_SIZE(rt3261_mono_adc_l_mix), - rt3261_mono_adcl_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), //bard 3-26 - SND_SOC_DAPM_SUPPLY("mono right filter", RT3261_PWR_DIG2, - RT3261_PWR_ADC_MF_R_BIT, 0, NULL, 0), - SND_SOC_DAPM_MIXER_E("Mono ADC MIXR", SND_SOC_NOPM, 0, 0, - rt3261_mono_adc_r_mix, ARRAY_SIZE(rt3261_mono_adc_r_mix), - rt3261_mono_adcr_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), //bard 3-26 - - /* IF2 Mux */ - SND_SOC_DAPM_MUX("IF2 ADC L Mux", SND_SOC_NOPM, 0, 0, - &rt3261_if2_adc_l_mux), - SND_SOC_DAPM_MUX("IF2 ADC R Mux", SND_SOC_NOPM, 0, 0, - &rt3261_if2_adc_r_mux), - - /* Digital Interface */ - SND_SOC_DAPM_SUPPLY("I2S1", SND_SOC_NOPM, - 0, 0, NULL, 0), - SND_SOC_DAPM_PGA("IF1 DAC", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_PGA("IF1 DAC L", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_PGA("IF1 DAC R", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_PGA("IF1 ADC", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_PGA("IF1 ADC L", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_PGA("IF1 ADC R", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_SUPPLY("I2S2", RT3261_PWR_DIG1, - RT3261_PWR_I2S2_BIT, 0, NULL, 0), - SND_SOC_DAPM_PGA("IF2 DAC", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_PGA("IF2 DAC L", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_PGA("IF2 DAC R", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_PGA("IF2 ADC", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_PGA("IF2 ADC L", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_PGA("IF2 ADC R", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_SUPPLY("I2S3", RT3261_PWR_DIG1, - RT3261_PWR_I2S3_BIT, 0, NULL, 0), - SND_SOC_DAPM_PGA("IF3 DAC", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_PGA("IF3 DAC L", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_PGA("IF3 DAC R", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_PGA("IF3 ADC", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_PGA("IF3 ADC L", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_PGA("IF3 ADC R", SND_SOC_NOPM, 0, 0, NULL, 0), - - /* Digital Interface Select */ - SND_SOC_DAPM_MUX("DAI1 RX Mux", SND_SOC_NOPM, 0, 0, &rt3261_dai_mux), - SND_SOC_DAPM_MUX("DAI1 TX Mux", SND_SOC_NOPM, 0, 0, &rt3261_dai_mux), - SND_SOC_DAPM_MUX("DAI1 IF1 Mux", SND_SOC_NOPM, 0, 0, &rt3261_dai_mux), - SND_SOC_DAPM_MUX("DAI1 IF2 Mux", SND_SOC_NOPM, 0, 0, &rt3261_dai_mux), - SND_SOC_DAPM_MUX("SDI1 TX Mux", SND_SOC_NOPM, 0, 0, &rt3261_sdi_mux), - - SND_SOC_DAPM_MUX("DAI2 RX Mux", SND_SOC_NOPM, 0, 0, &rt3261_dai_mux), - SND_SOC_DAPM_MUX("DAI2 TX Mux", SND_SOC_NOPM, 0, 0, &rt3261_dai_mux), - SND_SOC_DAPM_MUX("DAI2 IF1 Mux", SND_SOC_NOPM, 0, 0, &rt3261_dai_mux), - SND_SOC_DAPM_MUX("DAI2 IF2 Mux", SND_SOC_NOPM, 0, 0, &rt3261_dai_mux), - SND_SOC_DAPM_MUX("SDI2 TX Mux", SND_SOC_NOPM, 0, 0, &rt3261_sdi_mux), - - SND_SOC_DAPM_MUX("DAI3 RX Mux", SND_SOC_NOPM, 0, 0, &rt3261_dai_mux), - SND_SOC_DAPM_MUX("DAI3 TX Mux", SND_SOC_NOPM, 0, 0, &rt3261_dai_mux), - - /* Audio Interface */ - SND_SOC_DAPM_AIF_IN("AIF1RX", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), - SND_SOC_DAPM_AIF_OUT("AIF1TX", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0), - SND_SOC_DAPM_AIF_IN("AIF2RX", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0), - SND_SOC_DAPM_AIF_OUT("AIF2TX", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0), - SND_SOC_DAPM_AIF_IN("AIF3RX", "AIF3 Playback", 0, SND_SOC_NOPM, 0, 0), - SND_SOC_DAPM_AIF_OUT("AIF3TX", "AIF3 Capture", 0, SND_SOC_NOPM, 0, 0), - - /* Audio DSP */ - SND_SOC_DAPM_PGA("Audio DSP", SND_SOC_NOPM, 0, 0, NULL, 0), - - /* ANC */ - SND_SOC_DAPM_PGA("ANC", SND_SOC_NOPM, 0, 0, NULL, 0), - - /* Output Side */ - /* DAC mixer before sound effect */ -#if 0 //org - SND_SOC_DAPM_MIXER("DAC MIXL", SND_SOC_NOPM, 0, 0, - rt3261_dac_l_mix, ARRAY_SIZE(rt3261_dac_l_mix)), - SND_SOC_DAPM_MIXER("DAC MIXR", SND_SOC_NOPM, 0, 0, - rt3261_dac_r_mix, ARRAY_SIZE(rt3261_dac_r_mix)), -#else //bard 8-29 - SND_SOC_DAPM_MIXER_E("DAC MIXL", SND_SOC_NOPM, 0, 0, - rt3261_dac_l_mix, ARRAY_SIZE(rt3261_dac_l_mix), - rt3261_dac_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), - SND_SOC_DAPM_MIXER_E("DAC MIXR", SND_SOC_NOPM, 0, 0, - rt3261_dac_r_mix, ARRAY_SIZE(rt3261_dac_r_mix), - rt3261_dac_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), -#endif - - /* DAC2 channel Mux */ - SND_SOC_DAPM_MUX("DAC L2 Mux", SND_SOC_NOPM, 0, 0, - &rt3261_dac_l2_mux), - SND_SOC_DAPM_MUX("DAC R2 Mux", SND_SOC_NOPM, 0, 0, - &rt3261_dac_r2_mux), -#if 0 //org - SND_SOC_DAPM_PGA("DAC L2 Volume", RT3261_PWR_DIG1, - RT3261_PWR_DAC_L2_BIT, 0, NULL, 0), - SND_SOC_DAPM_PGA("DAC R2 Volume", RT3261_PWR_DIG1, - RT3261_PWR_DAC_R2_BIT, 0, NULL, 0), -#else //bard 9-26 - SND_SOC_DAPM_PGA("DAC L2 Volume", SND_SOC_NOPM, - 0, 0, NULL, 0), - SND_SOC_DAPM_PGA("DAC R2 Volume", SND_SOC_NOPM, - 0, 0, NULL, 0), - SND_SOC_DAPM_SUPPLY("DAC L1 Power", RT3261_PWR_DIG1, - RT3261_PWR_DAC_L1_BIT, 0, NULL, 0), - SND_SOC_DAPM_SUPPLY("DAC R1 Power", RT3261_PWR_DIG1, - RT3261_PWR_DAC_R1_BIT, 0, NULL, 0), - SND_SOC_DAPM_SUPPLY("DAC L2 Power", RT3261_PWR_DIG1, - RT3261_PWR_DAC_L2_BIT, 0, NULL, 0), - SND_SOC_DAPM_SUPPLY("DAC R2 Power", RT3261_PWR_DIG1, - RT3261_PWR_DAC_R2_BIT, 0, NULL, 0), -#endif - - /* DAC Mixer */ - SND_SOC_DAPM_MIXER("Stereo DAC MIXL", SND_SOC_NOPM, 0, 0, - rt3261_sto_dac_l_mix, ARRAY_SIZE(rt3261_sto_dac_l_mix)), - SND_SOC_DAPM_MIXER("Stereo DAC MIXR", SND_SOC_NOPM, 0, 0, - rt3261_sto_dac_r_mix, ARRAY_SIZE(rt3261_sto_dac_r_mix)), - SND_SOC_DAPM_MIXER("Mono DAC MIXL", SND_SOC_NOPM, 0, 0, - rt3261_mono_dac_l_mix, ARRAY_SIZE(rt3261_mono_dac_l_mix)), - SND_SOC_DAPM_MIXER("Mono DAC MIXR", SND_SOC_NOPM, 0, 0, - rt3261_mono_dac_r_mix, ARRAY_SIZE(rt3261_mono_dac_r_mix)), - SND_SOC_DAPM_MIXER("DIG MIXL", SND_SOC_NOPM, 0, 0, - rt3261_dig_l_mix, ARRAY_SIZE(rt3261_dig_l_mix)), - SND_SOC_DAPM_MIXER("DIG MIXR", SND_SOC_NOPM, 0, 0, - rt3261_dig_r_mix, ARRAY_SIZE(rt3261_dig_r_mix)), - SND_SOC_DAPM_MUX("Mono dacr Mux", SND_SOC_NOPM, 0, 0, - &rt3261_dacr2_mux), - - /* DACs */ -#if 0 //org - SND_SOC_DAPM_DAC("DAC L1", NULL, RT3261_PWR_DIG1, - RT3261_PWR_DAC_L1_BIT, 0), - SND_SOC_DAPM_DAC("DAC L2", NULL, RT3261_PWR_DIG1, - RT3261_PWR_DAC_L2_BIT, 0), - SND_SOC_DAPM_DAC("DAC R1", NULL, RT3261_PWR_DIG1, - RT3261_PWR_DAC_R1_BIT, 0), - SND_SOC_DAPM_DAC("DAC R2", NULL, RT3261_PWR_DIG1, - RT3261_PWR_DAC_R2_BIT, 0), -#else //bard 9-26 - SND_SOC_DAPM_DAC("DAC L1", NULL, SND_SOC_NOPM, 0, 0), - SND_SOC_DAPM_DAC("DAC R1", NULL, SND_SOC_NOPM, 0, 0), - SND_SOC_DAPM_DAC("DAC L2", NULL, SND_SOC_NOPM, 0, 0), - SND_SOC_DAPM_DAC("DAC R2", NULL, SND_SOC_NOPM, 0, 0), -#endif - SND_SOC_DAPM_PGA("DAC 1", SND_SOC_NOPM, - 0, 0, NULL, 0), - SND_SOC_DAPM_PGA("DAC 2", SND_SOC_NOPM, - 0, 0, NULL, 0), - /* SPK/OUT Mixer */ - SND_SOC_DAPM_MIXER("SPK MIXL", RT3261_PWR_MIXER, RT3261_PWR_SM_L_BIT, - 0, rt3261_spk_l_mix, ARRAY_SIZE(rt3261_spk_l_mix)), - SND_SOC_DAPM_MIXER("SPK MIXR", RT3261_PWR_MIXER, RT3261_PWR_SM_R_BIT, - 0, rt3261_spk_r_mix, ARRAY_SIZE(rt3261_spk_r_mix)), - SND_SOC_DAPM_MIXER("OUT MIXL", RT3261_PWR_MIXER, RT3261_PWR_OM_L_BIT, - 0, rt3261_out_l_mix, ARRAY_SIZE(rt3261_out_l_mix)), - SND_SOC_DAPM_MIXER("OUT MIXR", RT3261_PWR_MIXER, RT3261_PWR_OM_R_BIT, - 0, rt3261_out_r_mix, ARRAY_SIZE(rt3261_out_r_mix)), - /* Ouput Volume */ - SND_SOC_DAPM_PGA("SPKVOL L", RT3261_PWR_VOL, - RT3261_PWR_SV_L_BIT, 0, NULL, 0), - SND_SOC_DAPM_PGA("SPKVOL R", RT3261_PWR_VOL, - RT3261_PWR_SV_R_BIT, 0, NULL, 0), - SND_SOC_DAPM_PGA("OUTVOL L", RT3261_PWR_VOL, - RT3261_PWR_OV_L_BIT, 0, NULL, 0), - SND_SOC_DAPM_PGA("OUTVOL R", RT3261_PWR_VOL, - RT3261_PWR_OV_R_BIT, 0, NULL, 0), - SND_SOC_DAPM_PGA("HPOVOL L", RT3261_PWR_VOL, - RT3261_PWR_HV_L_BIT, 0, NULL, 0), - SND_SOC_DAPM_PGA("HPOVOL R", RT3261_PWR_VOL, - RT3261_PWR_HV_R_BIT, 0, NULL, 0), - SND_SOC_DAPM_PGA("HPOVOL", SND_SOC_NOPM, - 0, 0, NULL, 0), - /* SPO/HPO/LOUT/Mono Mixer */ - SND_SOC_DAPM_MIXER("SPOL MIX", SND_SOC_NOPM, 0, - 0, rt3261_spo_l_mix, ARRAY_SIZE(rt3261_spo_l_mix)), - SND_SOC_DAPM_MIXER("SPOR MIX", SND_SOC_NOPM, 0, - 0, rt3261_spo_r_mix, ARRAY_SIZE(rt3261_spo_r_mix)), - SND_SOC_DAPM_MIXER("DAC SPK", SND_SOC_NOPM, 0, - 0, rt3261_spo_dac_mix, ARRAY_SIZE(rt3261_spo_dac_mix)), //bard 8-27 - SND_SOC_DAPM_MIXER("HPO MIX", SND_SOC_NOPM, 0, 0, - rt3261_hpo_mix, ARRAY_SIZE(rt3261_hpo_mix)), - SND_SOC_DAPM_MIXER("LOUT MIX", SND_SOC_NOPM, 0, 0, - rt3261_lout_mix, ARRAY_SIZE(rt3261_lout_mix)), - SND_SOC_DAPM_MIXER("Mono MIX", RT3261_PWR_ANLG1, RT3261_PWR_MM_BIT, 0, - rt3261_mono_mix, ARRAY_SIZE(rt3261_mono_mix)), - - SND_SOC_DAPM_PGA_S("HP amp", 1, SND_SOC_NOPM, 0, 0, - rt3261_hp_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), - SND_SOC_DAPM_PGA_S("SPK amp", 1, SND_SOC_NOPM, 0, 0, - rt3261_spk_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), - SND_SOC_DAPM_PGA_S("LOUT amp", 1, SND_SOC_NOPM, 0, 0, - rt3261_lout_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), - SND_SOC_DAPM_PGA_S("Mono amp", 1, RT3261_PWR_ANLG1, - RT3261_PWR_MA_BIT, 0, rt3261_mono_event, - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), - - /* Output Lines */ - SND_SOC_DAPM_OUTPUT("SPOLP"), - SND_SOC_DAPM_OUTPUT("SPOLN"), - SND_SOC_DAPM_OUTPUT("SPORP"), - SND_SOC_DAPM_OUTPUT("SPORN"), - SND_SOC_DAPM_OUTPUT("HPOL"), - SND_SOC_DAPM_OUTPUT("HPOR"), - SND_SOC_DAPM_OUTPUT("LOUTL"), - SND_SOC_DAPM_OUTPUT("LOUTR"), - SND_SOC_DAPM_OUTPUT("MonoP"), - SND_SOC_DAPM_OUTPUT("MonoN"), -}; - -static const struct snd_soc_dapm_route rt3261_dapm_routes[] = { - {"IN1P", NULL, "LDO2"}, - {"IN2P", NULL, "LDO2"}, - {"IN3P", NULL, "LDO2"}, - - {"IN1P", NULL, "MIC1"}, - {"IN1N", NULL, "MIC1"}, - {"IN2P", NULL, "MIC2"}, - {"IN2N", NULL, "MIC2"}, - {"IN3P", NULL, "MIC3"}, - {"IN3N", NULL, "MIC3"}, - - {"DMIC L1", NULL, "DMIC1"}, - {"DMIC R1", NULL, "DMIC1"}, - {"DMIC L2", NULL, "DMIC2"}, - {"DMIC R2", NULL, "DMIC2"}, - - {"BST1", NULL, "IN1P"}, - {"BST1", NULL, "IN1N"}, - {"BST2", NULL, "IN2P"}, - {"BST2", NULL, "IN2N"}, - {"BST3", NULL, "IN3P"}, - {"BST3", NULL, "IN3N"}, - - {"INL VOL", NULL, "IN2P"}, - {"INR VOL", NULL, "IN2N"}, - - {"RECMIXL", "HPOL Switch", "HPOL"}, - {"RECMIXL", "INL Switch", "INL VOL"}, - {"RECMIXL", "BST3 Switch", "BST3"}, - {"RECMIXL", "BST2 Switch", "BST2"}, - {"RECMIXL", "BST1 Switch", "BST1"}, - {"RECMIXL", "OUT MIXL Switch", "OUT MIXL"}, - - {"RECMIXR", "HPOR Switch", "HPOR"}, - {"RECMIXR", "INR Switch", "INR VOL"}, - {"RECMIXR", "BST3 Switch", "BST3"}, - {"RECMIXR", "BST2 Switch", "BST2"}, - {"RECMIXR", "BST1 Switch", "BST1"}, - {"RECMIXR", "OUT MIXR Switch", "OUT MIXR"}, - - {"ADC L", NULL, "RECMIXL"}, - {"ADC L", NULL, "ADC L power"}, - {"ADC R", NULL, "RECMIXR"}, - {"ADC R", NULL, "ADC R power"}, - - {"DMIC L1", NULL, "DMIC CLK"}, - {"DMIC L2", NULL, "DMIC CLK"}, - - {"Stereo ADC L2 Mux", "DMIC1", "DMIC L1"}, - {"Stereo ADC L2 Mux", "DMIC2", "DMIC L2"}, - {"Stereo ADC L2 Mux", "DIG MIX", "DIG MIXL"}, - {"Stereo ADC L1 Mux", "ADC", "ADC L"}, - {"Stereo ADC L1 Mux", "DIG MIX", "DIG MIXL"}, - - {"Stereo ADC R1 Mux", "ADC", "ADC R"}, - {"Stereo ADC R1 Mux", "DIG MIX", "DIG MIXR"}, - {"Stereo ADC R2 Mux", "DMIC1", "DMIC R1"}, - {"Stereo ADC R2 Mux", "DMIC2", "DMIC R2"}, - {"Stereo ADC R2 Mux", "DIG MIX", "DIG MIXR"}, - - {"Mono ADC L2 Mux", "DMIC L1", "DMIC L1"}, - {"Mono ADC L2 Mux", "DMIC L2", "DMIC L2"}, - {"Mono ADC L2 Mux", "Mono DAC MIXL", "Mono DAC MIXL"}, - {"Mono ADC L1 Mux", "Mono DAC MIXL", "Mono DAC MIXL"}, - {"Mono ADC L1 Mux", "ADCL", "ADC L"}, - - {"Mono ADC R1 Mux", "Mono DAC MIXR", "Mono DAC MIXR"}, - {"Mono ADC R1 Mux", "ADCR", "ADC R"}, - {"Mono ADC R2 Mux", "DMIC R1", "DMIC R1"}, - {"Mono ADC R2 Mux", "DMIC R2", "DMIC R2"}, - {"Mono ADC R2 Mux", "Mono DAC MIXR", "Mono DAC MIXR"}, - - {"Stereo ADC MIXL", "ADC1 Switch", "Stereo ADC L1 Mux"}, - {"Stereo ADC MIXL", "ADC2 Switch", "Stereo ADC L2 Mux"}, - {"Stereo ADC MIXL", NULL, "stereo filter"}, - {"stereo filter", NULL, "PLL1", check_sysclk1_source}, - - {"Stereo ADC MIXR", "ADC1 Switch", "Stereo ADC R1 Mux"}, - {"Stereo ADC MIXR", "ADC2 Switch", "Stereo ADC R2 Mux"}, - {"Stereo ADC MIXR", NULL, "stereo filter"}, - {"stereo filter", NULL, "PLL1", check_sysclk1_source}, - - {"Mono ADC MIXL", "ADC1 Switch", "Mono ADC L1 Mux"}, - {"Mono ADC MIXL", "ADC2 Switch", "Mono ADC L2 Mux"}, - {"Mono ADC MIXL", NULL, "mono left filter"}, - {"mono left filter", NULL, "PLL1", check_sysclk1_source}, - - {"Mono ADC MIXR", "ADC1 Switch", "Mono ADC R1 Mux"}, - {"Mono ADC MIXR", "ADC2 Switch", "Mono ADC R2 Mux"}, - {"Mono ADC MIXR", NULL, "mono right filter"}, - {"mono right filter", NULL, "PLL1", check_sysclk1_source}, - - {"IF2 ADC L Mux", "Mono ADC MIXL", "Mono ADC MIXL"}, - {"IF2 ADC R Mux", "Mono ADC MIXR", "Mono ADC MIXR"}, - - {"IF2 ADC L", NULL, "IF2 ADC L Mux"}, - {"IF2 ADC R", NULL, "IF2 ADC R Mux"}, - {"IF3 ADC L", NULL, "Mono ADC MIXL"}, - {"IF3 ADC R", NULL, "Mono ADC MIXR"}, - {"IF1 ADC L", NULL, "Stereo ADC MIXL"}, - {"IF1 ADC R", NULL, "Stereo ADC MIXR"}, - - {"IF1 ADC", NULL, "I2S1"}, - {"IF1 ADC", NULL, "IF1 ADC L"}, - {"IF1 ADC", NULL, "IF1 ADC R"}, - {"IF2 ADC", NULL, "I2S2"}, - {"IF2 ADC", NULL, "IF2 ADC L"}, - {"IF2 ADC", NULL, "IF2 ADC R"}, - {"IF3 ADC", NULL, "I2S3"}, - {"IF3 ADC", NULL, "IF3 ADC L"}, - {"IF3 ADC", NULL, "IF3 ADC R"}, - - {"DAI1 TX Mux", "1:1|2:2|3:3", "IF1 ADC"}, - {"DAI1 TX Mux", "1:1|2:3|3:2", "IF1 ADC"}, - {"DAI1 TX Mux", "1:3|2:1|3:2", "IF2 ADC"}, - {"DAI1 TX Mux", "1:2|2:1|3:3", "IF2 ADC"}, - {"DAI1 TX Mux", "1:3|2:2|3:1", "IF3 ADC"}, - {"DAI1 TX Mux", "1:2|2:3|3:1", "IF3 ADC"}, - {"DAI1 IF1 Mux", "1:1|2:1|3:3", "IF1 ADC"}, - {"DAI1 IF2 Mux", "1:1|2:1|3:3", "IF2 ADC"}, - {"SDI1 TX Mux", "IF1", "DAI1 IF1 Mux"}, - {"SDI1 TX Mux", "IF2", "DAI1 IF2 Mux"}, - - {"DAI2 TX Mux", "1:2|2:3|3:1", "IF1 ADC"}, - {"DAI2 TX Mux", "1:2|2:1|3:3", "IF1 ADC"}, - {"DAI2 TX Mux", "1:1|2:2|3:3", "IF2 ADC"}, - {"DAI2 TX Mux", "1:3|2:2|3:1", "IF2 ADC"}, - {"DAI2 TX Mux", "1:1|2:3|3:2", "IF3 ADC"}, - {"DAI2 TX Mux", "1:3|2:1|3:2", "IF3 ADC"}, - {"DAI2 IF1 Mux", "1:2|2:2|3:3", "IF1 ADC"}, - {"DAI2 IF2 Mux", "1:2|2:2|3:3", "IF2 ADC"}, - {"SDI2 TX Mux", "IF1", "DAI2 IF1 Mux"}, - {"SDI2 TX Mux", "IF2", "DAI2 IF2 Mux"}, - - {"DAI3 TX Mux", "1:3|2:1|3:2", "IF1 ADC"}, - {"DAI3 TX Mux", "1:3|2:2|3:1", "IF1 ADC"}, - {"DAI3 TX Mux", "1:1|2:3|3:2", "IF2 ADC"}, - {"DAI3 TX Mux", "1:2|2:3|3:1", "IF2 ADC"}, - {"DAI3 TX Mux", "1:1|2:2|3:3", "IF3 ADC"}, - {"DAI3 TX Mux", "1:2|2:1|3:3", "IF3 ADC"}, - {"DAI3 TX Mux", "1:1|2:1|3:3", "IF3 ADC"}, - {"DAI3 TX Mux", "1:2|2:2|3:3", "IF3 ADC"}, - - {"AIF1TX", NULL, "DAI1 TX Mux"}, - {"AIF1TX", NULL, "SDI1 TX Mux"}, - {"AIF2TX", NULL, "DAI2 TX Mux"}, - {"AIF2TX", NULL, "SDI2 TX Mux"}, - {"AIF3TX", NULL, "DAI3 TX Mux"}, - - {"DAI1 RX Mux", "1:1|2:2|3:3", "AIF1RX"}, - {"DAI1 RX Mux", "1:1|2:3|3:2", "AIF1RX"}, - {"DAI1 RX Mux", "1:1|2:1|3:3", "AIF1RX"}, - {"DAI1 RX Mux", "1:2|2:3|3:1", "AIF2RX"}, - {"DAI1 RX Mux", "1:2|2:1|3:3", "AIF2RX"}, - {"DAI1 RX Mux", "1:2|2:2|3:3", "AIF2RX"}, - {"DAI1 RX Mux", "1:3|2:1|3:2", "AIF3RX"}, - {"DAI1 RX Mux", "1:3|2:2|3:1", "AIF3RX"}, - - {"DAI2 RX Mux", "1:3|2:1|3:2", "AIF1RX"}, - {"DAI2 RX Mux", "1:2|2:1|3:3", "AIF1RX"}, - {"DAI2 RX Mux", "1:1|2:1|3:3", "AIF1RX"}, - {"DAI2 RX Mux", "1:1|2:2|3:3", "AIF2RX"}, - {"DAI2 RX Mux", "1:3|2:2|3:1", "AIF2RX"}, - {"DAI2 RX Mux", "1:2|2:2|3:3", "AIF2RX"}, - {"DAI2 RX Mux", "1:1|2:3|3:2", "AIF3RX"}, - {"DAI2 RX Mux", "1:2|2:3|3:1", "AIF3RX"}, - - {"DAI3 RX Mux", "1:3|2:2|3:1", "AIF1RX"}, - {"DAI3 RX Mux", "1:2|2:3|3:1", "AIF1RX"}, - {"DAI3 RX Mux", "1:1|2:3|3:2", "AIF2RX"}, - {"DAI3 RX Mux", "1:3|2:1|3:2", "AIF2RX"}, - {"DAI3 RX Mux", "1:1|2:2|3:3", "AIF3RX"}, - {"DAI3 RX Mux", "1:2|2:1|3:3", "AIF3RX"}, - {"DAI3 RX Mux", "1:1|2:1|3:3", "AIF3RX"}, - {"DAI3 RX Mux", "1:2|2:2|3:3", "AIF3RX"}, - - {"IF1 DAC", NULL, "I2S1"}, - {"IF1 DAC", NULL, "DAI1 RX Mux"}, - {"IF2 DAC", NULL, "I2S2"}, - {"IF2 DAC", NULL, "DAI2 RX Mux"}, - {"IF3 DAC", NULL, "I2S3"}, - {"IF3 DAC", NULL, "DAI3 RX Mux"}, - - {"IF1 DAC L", NULL, "IF1 DAC"}, - {"IF1 DAC R", NULL, "IF1 DAC"}, - {"IF2 DAC L", NULL, "IF2 DAC"}, - {"IF2 DAC R", NULL, "IF2 DAC"}, - {"IF3 DAC L", NULL, "IF3 DAC"}, - {"IF3 DAC R", NULL, "IF3 DAC"}, - - {"DAC MIXL", "Stereo ADC Switch", "Stereo ADC MIXL"}, - {"DAC MIXL", "INF1 Switch", "IF1 DAC L"}, - {"DAC MIXL", NULL, "DAC L1 Power"}, //bard 9-26 - {"DAC MIXR", "Stereo ADC Switch", "Stereo ADC MIXR"}, - {"DAC MIXR", "INF1 Switch", "IF1 DAC R"}, - {"DAC MIXR", NULL, "DAC R1 Power"}, //bard 9-26 - - {"ANC", NULL, "Stereo ADC MIXL"}, - {"ANC", NULL, "Stereo ADC MIXR"}, - - {"Audio DSP", NULL, "DAC MIXL"}, - {"Audio DSP", NULL, "DAC MIXR"}, - - {"DAC L2 Mux", "IF2", "IF2 DAC L"}, - {"DAC L2 Mux", "IF3", "IF3 DAC L"}, - {"DAC L2 Mux", "Base L/R", "Audio DSP"}, - {"DAC L2 Volume", NULL, "DAC L2 Mux"}, - {"DAC L2 Volume", NULL, "DAC L2 Power"}, //bard 9-26 - - {"DAC R2 Mux", "IF2", "IF2 DAC R"}, - {"DAC R2 Mux", "IF3", "IF3 DAC R"}, - {"DAC R2 Volume", NULL, "Mono dacr Mux"}, - {"Mono dacr Mux", "TxDC_R", "DAC R2 Mux"}, - {"Mono dacr Mux", "TxDP_R", "IF2 ADC R Mux"}, - {"DAC R2 Volume", NULL, "DAC R2 Power"}, //bsrd 9-26 - - {"Stereo DAC MIXL", "DAC L1 Switch", "DAC MIXL"}, - {"Stereo DAC MIXL", "DAC L2 Switch", "DAC L2 Volume"}, - {"Stereo DAC MIXL", "ANC Switch", "ANC"}, - {"Stereo DAC MIXR", "DAC R1 Switch", "DAC MIXR"}, - {"Stereo DAC MIXR", "DAC R2 Switch", "DAC R2 Volume"}, - {"Stereo DAC MIXR", "ANC Switch", "ANC"}, - - {"Mono DAC MIXL", "DAC L1 Switch", "DAC MIXL"}, - {"Mono DAC MIXL", "DAC L2 Switch", "DAC L2 Volume"}, - {"Mono DAC MIXL", "DAC R2 Switch", "DAC R2 Volume"}, - {"Mono DAC MIXR", "DAC R1 Switch", "DAC MIXR"}, - {"Mono DAC MIXR", "DAC R2 Switch", "DAC R2 Volume"}, - {"Mono DAC MIXR", "DAC L2 Switch", "DAC L2 Volume"}, - - {"DIG MIXL", "DAC L1 Switch", "DAC MIXL"}, - {"DIG MIXL", "DAC L2 Switch", "DAC L2 Volume"}, - {"DIG MIXR", "DAC R1 Switch", "DAC MIXR"}, - {"DIG MIXR", "DAC R2 Switch", "DAC R2 Volume"}, - - {"DAC L1", NULL, "Stereo DAC MIXL"}, - {"DAC L1", NULL, "PLL1", check_sysclk1_source}, - {"DAC L1", NULL, "DAC L1 Power"}, //bard 9-26 - {"DAC R1", NULL, "Stereo DAC MIXR"}, - {"DAC R1", NULL, "PLL1", check_sysclk1_source}, - {"DAC R1", NULL, "DAC R1 Power"}, //bard 9-26 - {"DAC L2", NULL, "Mono DAC MIXL"}, - {"DAC L2", NULL, "PLL1", check_sysclk1_source}, - {"DAC L2", NULL, "DAC L2 Power"}, //bard 9-26 - {"DAC R2", NULL, "Mono DAC MIXR"}, - {"DAC R2", NULL, "PLL1", check_sysclk1_source}, - {"DAC R2", NULL, "DAC R2 Power"}, //bard 9-26 - - {"SPK MIXL", "REC MIXL Switch", "RECMIXL"}, - {"SPK MIXL", "INL Switch", "INL VOL"}, - {"SPK MIXL", "DAC L1 Switch", "DAC L1"}, - {"SPK MIXL", "DAC L2 Switch", "DAC L2"}, - {"SPK MIXL", "OUT MIXL Switch", "OUT MIXL"}, - {"SPK MIXR", "REC MIXR Switch", "RECMIXR"}, - {"SPK MIXR", "INR Switch", "INR VOL"}, - {"SPK MIXR", "DAC R1 Switch", "DAC R1"}, - {"SPK MIXR", "DAC R2 Switch", "DAC R2"}, - {"SPK MIXR", "OUT MIXR Switch", "OUT MIXR"}, - - {"OUT MIXL", "BST3 Switch", "BST3"}, - {"OUT MIXL", "BST1 Switch", "BST1"}, - {"OUT MIXL", "INL Switch", "INL VOL"}, - {"OUT MIXL", "REC MIXL Switch", "RECMIXL"}, - {"OUT MIXL", "DAC R2 Switch", "DAC R2"}, - {"OUT MIXL", "DAC L2 Switch", "DAC L2"}, - {"OUT MIXL", "DAC L1 Switch", "DAC L1"}, - - {"OUT MIXR", "BST3 Switch", "BST3"}, - {"OUT MIXR", "BST2 Switch", "BST2"}, - {"OUT MIXR", "BST1 Switch", "BST1"}, - {"OUT MIXR", "INR Switch", "INR VOL"}, - {"OUT MIXR", "REC MIXR Switch", "RECMIXR"}, - {"OUT MIXR", "DAC L2 Switch", "DAC L2"}, - {"OUT MIXR", "DAC R2 Switch", "DAC R2"}, - {"OUT MIXR", "DAC R1 Switch", "DAC R1"}, - - {"SPKVOL L", NULL, "SPK MIXL"}, - {"SPKVOL R", NULL, "SPK MIXR"}, - {"HPOVOL L", NULL, "OUT MIXL"}, - {"HPOVOL R", NULL, "OUT MIXR"}, - {"OUTVOL L", NULL, "OUT MIXL"}, - {"OUTVOL R", NULL, "OUT MIXR"}, -#if 0//org - {"SPOL MIX", "DAC R1 Switch", "DAC R1"}, - {"SPOL MIX", "DAC L1 Switch", "DAC L1"}, -#else //bard 8-27 - {"SPOL MIX", "DAC Switch", "DAC SPK"}, - {"DAC SPK", "DAC L1 Switch", "DAC L1"}, - {"DAC SPK", "DAC R1 Switch", "DAC R1"}, -#endif - {"SPOL MIX", "SPKVOL R Switch", "SPKVOL R"}, - {"SPOL MIX", "SPKVOL L Switch", "SPKVOL L"}, - {"SPOL MIX", "BST1 Switch", "BST1"}, - {"SPOR MIX", "DAC R1 Switch", "DAC R1"}, - {"SPOR MIX", "SPKVOL R Switch", "SPKVOL R"}, - {"SPOR MIX", "BST1 Switch", "BST1"}, - - {"DAC 2", NULL, "DAC L2"}, - {"DAC 2", NULL, "DAC R2"}, - {"DAC 1", NULL, "DAC L1"}, - {"DAC 1", NULL, "DAC R1"}, - {"HPOVOL", NULL, "HPOVOL L"}, - {"HPOVOL", NULL, "HPOVOL R"}, - {"HPO MIX", "DAC2 Switch", "DAC 2"}, - {"HPO MIX", "DAC1 Switch", "DAC 1"}, - {"HPO MIX", "HPVOL Switch", "HPOVOL"}, - - {"LOUT MIX", "DAC L1 Switch", "DAC L1"}, - {"LOUT MIX", "DAC R1 Switch", "DAC R1"}, - {"LOUT MIX", "OUTVOL L Switch", "OUTVOL L"}, - {"LOUT MIX", "OUTVOL R Switch", "OUTVOL R"}, - - {"Mono MIX", "DAC R2 Switch", "DAC R2"}, - {"Mono MIX", "DAC L2 Switch", "DAC L2"}, - {"Mono MIX", "OUTVOL R Switch", "OUTVOL R"}, - {"Mono MIX", "OUTVOL L Switch", "OUTVOL L"}, - {"Mono MIX", "BST1 Switch", "BST1"}, - - {"SPK amp", NULL, "SPOL MIX"}, - {"SPK amp", NULL, "SPOR MIX"}, - {"SPOLP", NULL, "SPK amp"}, - {"SPOLN", NULL, "SPK amp"}, - {"SPORP", NULL, "SPK amp"}, - {"SPORN", NULL, "SPK amp"}, - - {"HP amp", NULL, "HPO MIX"}, - {"HPOL", NULL, "HP amp"}, - {"HPOR", NULL, "HP amp"}, - - {"LOUT amp", NULL, "LOUT MIX"}, - {"LOUTL", NULL, "LOUT amp"}, - {"LOUTR", NULL, "LOUT amp"}, - - {"Mono amp", NULL, "Mono MIX"}, - {"MonoP", NULL, "Mono amp"}, - {"MonoN", NULL, "Mono amp"}, -}; - -static int get_sdp_info(struct snd_soc_codec *codec, int dai_id) -{ - int ret = 0, val; - - if(codec == NULL) - return -EINVAL; - - val = snd_soc_read(codec, RT3261_I2S1_SDP); - val = (val & RT3261_I2S_IF_MASK) >> RT3261_I2S_IF_SFT; - switch (dai_id) { - case RT3261_AIF1: - if (val == RT3261_IF_123 || val == RT3261_IF_132 || - val == RT3261_IF_113) - ret |= RT3261_U_IF1; - if (val == RT3261_IF_312 || val == RT3261_IF_213 || - val == RT3261_IF_113) - ret |= RT3261_U_IF2; - if (val == RT3261_IF_321 || val == RT3261_IF_231) - ret |= RT3261_U_IF3; - break; - - case RT3261_AIF2: - if (val == RT3261_IF_231 || val == RT3261_IF_213 || - val == RT3261_IF_223) - ret |= RT3261_U_IF1; - if (val == RT3261_IF_123 || val == RT3261_IF_321 || - val == RT3261_IF_223) - ret |= RT3261_U_IF2; - if (val == RT3261_IF_132 || val == RT3261_IF_312) - ret |= RT3261_U_IF3; - break; - - default: - ret = -EINVAL; - break; - } - - return ret; -} - -static int get_clk_info(int sclk, int rate) -{ - int i, pd[] = {1, 2, 3, 4, 6, 8, 12, 16}; - struct snd_soc_codec *codec = rt3261_codec; - struct rt3261_priv *rt3261 = snd_soc_codec_get_drvdata(codec); - - if (sclk <= 0 || rate <= 0) - return -EINVAL; -//bard 8-29 s - if (rt3261->asrc_en) - return 1; -//bard 8-29 e - rate = rate << 8; - for (i = 0; i < ARRAY_SIZE(pd); i++) - if (sclk == rate * pd[i]) - return i; - - return -EINVAL; -} - -static int rt3261_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec *codec = rtd->codec; - struct rt3261_priv *rt3261 = snd_soc_codec_get_drvdata(codec); - unsigned int val_len = 0, val_clk, mask_clk, dai_sel; - int pre_div, bclk_ms, frame_size; - - rt3261->lrck[dai->id] = params_rate(params); - if(dai->id == 1) - rt3261->lrck[dai->id] = 8000; - pre_div = get_clk_info(rt3261->sysclk, rt3261->lrck[dai->id]); - if (pre_div < 0) { - dev_err(codec->dev, "Unsupported clock setting\n"); - return -EINVAL; - } - frame_size = snd_soc_params_to_frame_size(params); - if (frame_size < 0) { - dev_err(codec->dev, "Unsupported frame size: %d\n", frame_size); - return -EINVAL; - } - bclk_ms = frame_size > 32 ? 1 : 0; - rt3261->bclk[dai->id] = rt3261->lrck[dai->id] * (32 << bclk_ms); - - dev_dbg(dai->dev, "bclk is %dHz and lrck is %dHz\n", - rt3261->bclk[dai->id], rt3261->lrck[dai->id]); - dev_dbg(dai->dev, "bclk_ms is %d and pre_div is %d for iis %d\n", - bclk_ms, pre_div, dai->id); - - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: - break; - case SNDRV_PCM_FORMAT_S20_3LE: - val_len |= RT3261_I2S_DL_20; - break; - case SNDRV_PCM_FORMAT_S24_LE: - val_len |= RT3261_I2S_DL_24; - break; - case SNDRV_PCM_FORMAT_S8: - val_len |= RT3261_I2S_DL_8; - break; - default: - return -EINVAL; - } - - dai_sel = get_sdp_info(codec, dai->id); - dai_sel |= (RT3261_U_IF1 | RT3261_U_IF2); - if (dai_sel < 0) { - dev_err(codec->dev, "Failed to get sdp info: %d\n", dai_sel); - return -EINVAL; - } - if (dai_sel & RT3261_U_IF1) { - mask_clk = RT3261_I2S_BCLK_MS1_MASK | RT3261_I2S_PD1_MASK; - val_clk = bclk_ms << RT3261_I2S_BCLK_MS1_SFT | - pre_div << RT3261_I2S_PD1_SFT; - snd_soc_update_bits(codec, RT3261_I2S1_SDP, - RT3261_I2S_DL_MASK, val_len); - //snd_soc_update_bits(codec, RT3261_ADDA_CLK1, mask_clk, val_clk); - } - if (dai_sel & RT3261_U_IF2) { - mask_clk |= RT3261_I2S_BCLK_MS2_MASK | RT3261_I2S_PD2_MASK; - val_clk |= bclk_ms << RT3261_I2S_BCLK_MS2_SFT | - pre_div << RT3261_I2S_PD2_SFT; - snd_soc_update_bits(codec, RT3261_I2S2_SDP, - RT3261_I2S_DL_MASK, val_len); - //snd_soc_update_bits(codec, RT3261_ADDA_CLK1, mask_clk, val_clk); - } - if (rt3261->asrc_en) - snd_soc_write(codec, RT3261_ADDA_CLK1, 0x1114); - else - snd_soc_update_bits(codec, RT3261_ADDA_CLK1, mask_clk, val_clk); - - return 0; -} - -static int rt3261_prepare(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec *codec = rtd->codec; - struct rt3261_priv *rt3261 = snd_soc_codec_get_drvdata(codec); - - rt3261->aif_pu = dai->id; - return 0; -} - -static int rt3261_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) -{ - struct snd_soc_codec *codec = dai->codec; - struct rt3261_priv *rt3261 = snd_soc_codec_get_drvdata(codec); - unsigned int reg_val = 0, dai_sel; - - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: - rt3261->master[dai->id] = 1; - break; - case SND_SOC_DAIFMT_CBS_CFS: - reg_val |= RT3261_I2S_MS_S; - rt3261->master[dai->id] = 0; - break; - default: - return -EINVAL; - } - - switch (fmt & SND_SOC_DAIFMT_INV_MASK) { - case SND_SOC_DAIFMT_NB_NF: - break; - case SND_SOC_DAIFMT_IB_NF: - reg_val |= RT3261_I2S_BP_INV; - break; - default: - return -EINVAL; - } - - switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_I2S: - break; - case SND_SOC_DAIFMT_LEFT_J: - reg_val |= RT3261_I2S_DF_LEFT; - break; - case SND_SOC_DAIFMT_DSP_A: - reg_val |= RT3261_I2S_DF_PCM_A; - break; - case SND_SOC_DAIFMT_DSP_B: - reg_val |= RT3261_I2S_DF_PCM_B; - break; - default: - return -EINVAL; - } - - dai_sel = get_sdp_info(codec, dai->id); - if (dai_sel < 0) { - dev_err(codec->dev, "Failed to get sdp info: %d\n", dai_sel); - return -EINVAL; - } - if (dai_sel & RT3261_U_IF1) { - snd_soc_update_bits(codec, RT3261_I2S1_SDP, - RT3261_I2S_MS_MASK | RT3261_I2S_BP_MASK | - RT3261_I2S_DF_MASK, reg_val); - } - if (dai_sel & RT3261_U_IF2) { - snd_soc_update_bits(codec, RT3261_I2S2_SDP, - RT3261_I2S_MS_MASK | RT3261_I2S_BP_MASK | - RT3261_I2S_DF_MASK, reg_val); - } - - return 0; -} - -static int rt3261_set_dai_sysclk(struct snd_soc_dai *dai, - int clk_id, unsigned int freq, int dir) -{ - struct snd_soc_codec *codec = dai->codec; - struct rt3261_priv *rt3261 = snd_soc_codec_get_drvdata(codec); - unsigned int reg_val = 0; - - if (freq == rt3261->sysclk && clk_id == rt3261->sysclk_src) - return 0; - snd_soc_update_bits(codec, RT3261_PWR_ANLG2, RT3261_PWR_PLL, RT3261_PWR_PLL); - - switch (clk_id) { - case RT3261_SCLK_S_MCLK: - reg_val |= RT3261_SCLK_SRC_MCLK; - break; - case RT3261_SCLK_S_PLL1: - reg_val |= RT3261_SCLK_SRC_PLL1; - break; - case RT3261_SCLK_S_RCCLK: - reg_val |= RT3261_SCLK_SRC_RCCLK; - break; - default: - dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id); - return -EINVAL; - } - snd_soc_update_bits(codec, RT3261_GLB_CLK, - RT3261_SCLK_SRC_MASK, reg_val); - rt3261->sysclk = freq; - rt3261->sysclk_src = clk_id; - - dev_dbg(dai->dev, "Sysclk is %dHz and clock id is %d\n", freq, clk_id); - - return 0; -} - -/** - * rt3261_pll_calc - Calcualte PLL M/N/K code. - * @freq_in: external clock provided to codec. - * @freq_out: target clock which codec works on. - * @pll_code: Pointer to structure with M, N, K and bypass flag. - * - * Calcualte M/N/K code to configure PLL for codec. And K is assigned to 2 - * which make calculation more efficiently. - * - * Returns 0 for success or negative error code. - */ -static int rt3261_pll_calc(const unsigned int freq_in, - const unsigned int freq_out, struct rt3261_pll_code *pll_code) -{ - int max_n = RT3261_PLL_N_MAX, max_m = RT3261_PLL_M_MAX; - int n, m, red, n_t, m_t, in_t, out_t, red_t = abs(freq_out - freq_in); - bool bypass = false; - - if (RT3261_PLL_INP_MAX < freq_in || RT3261_PLL_INP_MIN > freq_in) - return -EINVAL; - - for (n_t = 0; n_t <= max_n; n_t++) { - in_t = (freq_in >> 1) + (freq_in >> 2) * n_t; - if (in_t < 0) - continue; - if (in_t == freq_out) { - bypass = true; - n = n_t; - goto code_find; - } - for (m_t = 0; m_t <= max_m; m_t++) { - out_t = in_t / (m_t + 2); - red = abs(out_t - freq_out); - if (red < red_t) { - n = n_t; - m = m_t; - if (red == 0) - goto code_find; - red_t = red; - } - } - } - pr_debug("Only get approximation about PLL\n"); - -code_find: - - pll_code->m_bp = bypass; - pll_code->m_code = m; - pll_code->n_code = n; - pll_code->k_code = 2; - return 0; -} - -static int rt3261_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source, - unsigned int freq_in, unsigned int freq_out) -{ - struct snd_soc_codec *codec = dai->codec; - struct rt3261_priv *rt3261 = snd_soc_codec_get_drvdata(codec); - struct rt3261_pll_code pll_code; - int ret, dai_sel; - - if (source == rt3261->pll_src && freq_in == rt3261->pll_in && - freq_out == rt3261->pll_out) - return 0; - - if (!freq_in || !freq_out) { - dev_dbg(codec->dev, "PLL disabled\n"); - - rt3261->pll_in = 0; - rt3261->pll_out = 0; - snd_soc_update_bits(codec, RT3261_GLB_CLK, - RT3261_SCLK_SRC_MASK, RT3261_SCLK_SRC_MCLK); - return 0; - } - - switch (source) { - case RT3261_PLL1_S_MCLK: - snd_soc_update_bits(codec, RT3261_GLB_CLK, - RT3261_PLL1_SRC_MASK, RT3261_PLL1_SRC_MCLK); - break; - case RT3261_PLL1_S_BCLK1: - case RT3261_PLL1_S_BCLK2: - dai_sel = get_sdp_info(codec, dai->id); - if (dai_sel < 0) { - dev_err(codec->dev, - "Failed to get sdp info: %d\n", dai_sel); - return -EINVAL; - } - if (dai_sel & RT3261_U_IF1) { - snd_soc_update_bits(codec, RT3261_GLB_CLK, - RT3261_PLL1_SRC_MASK, RT3261_PLL1_SRC_BCLK1); - } - if (dai_sel & RT3261_U_IF2) { - snd_soc_update_bits(codec, RT3261_GLB_CLK, - RT3261_PLL1_SRC_MASK, RT3261_PLL1_SRC_BCLK2); - } - if (dai_sel & RT3261_U_IF3) { - snd_soc_update_bits(codec, RT3261_GLB_CLK, - RT3261_PLL1_SRC_MASK, RT3261_PLL1_SRC_BCLK3); - } - break; - default: - dev_err(codec->dev, "Unknown PLL source %d\n", source); - return -EINVAL; - } - - ret = rt3261_pll_calc(freq_in, freq_out, &pll_code); - if (ret < 0) { - dev_err(codec->dev, "Unsupport input clock %d\n", freq_in); - return ret; - } - - dev_dbg(codec->dev, "bypass=%d m=%d n=%d k=2\n", pll_code.m_bp, - (pll_code.m_bp ? 0 : pll_code.m_code), pll_code.n_code); - - snd_soc_write(codec, RT3261_PLL_CTRL1, - pll_code.n_code << RT3261_PLL_N_SFT | pll_code.k_code); - snd_soc_write(codec, RT3261_PLL_CTRL2, - (pll_code.m_bp ? 0 : pll_code.m_code) << RT3261_PLL_M_SFT | - pll_code.m_bp << RT3261_PLL_M_BP_SFT); - - rt3261->pll_in = freq_in; - rt3261->pll_out = freq_out; - rt3261->pll_src = source; - - return 0; -} - -/** - * rt3261_index_show - Dump private registers. - * @dev: codec device. - * @attr: device attribute. - * @buf: buffer for display. - * - * To show non-zero values of all private registers. - * - * Returns buffer length. - */ -static ssize_t rt3261_index_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - struct rt3261_priv *rt3261 = i2c_get_clientdata(client); - struct snd_soc_codec *codec = rt3261->codec; - unsigned int val; - int cnt = 0, i; - - cnt += sprintf(buf, "RT3261 index register\n"); - for (i = 0; i < 0xb4; i++) { - if (cnt + RT3261_REG_DISP_LEN >= PAGE_SIZE) - break; - val = rt3261_index_read(codec, i); - if (!val) - continue; - cnt += snprintf(buf + cnt, RT3261_REG_DISP_LEN, - "%02x: %04x\n", i, val); - } - - if (cnt >= PAGE_SIZE) - cnt = PAGE_SIZE - 1; - - return cnt; -} -static DEVICE_ATTR(index_reg, 0444, rt3261_index_show, NULL); - -static int rt3261_set_bias_level(struct snd_soc_codec *codec, - enum snd_soc_bias_level level) -{ - switch (level) { - case SND_SOC_BIAS_ON: - break; - - case SND_SOC_BIAS_PREPARE: - //snd_soc_update_bits(codec, RT3261_HP_VOL, - // RT3261_L_MUTE | RT3261_R_MUTE, RT3261_L_MUTE | RT3261_R_MUTE); //bard 12-7 - snd_soc_update_bits(codec, RT3261_SPK_VOL, - RT3261_L_MUTE | RT3261_R_MUTE, - RT3261_L_MUTE | RT3261_R_MUTE); - snd_soc_update_bits(codec, RT3261_PWR_ANLG2, - RT3261_PWR_MB1 | RT3261_PWR_MB2, - RT3261_PWR_MB1 | RT3261_PWR_MB2); - break; - - case SND_SOC_BIAS_STANDBY: - if (SND_SOC_BIAS_OFF == codec->dapm.bias_level) { - snd_soc_update_bits(codec, RT3261_PWR_ANLG1, - RT3261_PWR_VREF1 | RT3261_PWR_MB | - RT3261_PWR_BG | RT3261_PWR_VREF2, - RT3261_PWR_VREF1 | RT3261_PWR_MB | - RT3261_PWR_BG | RT3261_PWR_VREF2); - msleep(10); - snd_soc_update_bits(codec, RT3261_PWR_ANLG1, - RT3261_PWR_FV1 | RT3261_PWR_FV2, - RT3261_PWR_FV1 | RT3261_PWR_FV2); - snd_soc_write(codec, RT3261_GEN_CTRL1, 0x3701); - snd_soc_update_bits(codec, RT3261_PWR_ANLG2, - RT3261_PWR_MB1 | RT3261_PWR_MB2, - RT3261_PWR_MB1 | RT3261_PWR_MB2); - codec->cache_only = false; - codec->cache_sync = 1; - snd_soc_cache_sync(codec); - rt3261_index_sync(codec); - } - break; - - case SND_SOC_BIAS_OFF: - //snd_soc_write(codec, RT3261_DEPOP_M1, 0x0004);//bard 4-22 r - //snd_soc_write(codec, RT3261_DEPOP_M2, 0x1100);//bard 4-22 r - snd_soc_write(codec, RT3261_GEN_CTRL1, 0x3700); - snd_soc_write(codec, RT3261_PWR_DIG1, 0x0000); - snd_soc_write(codec, RT3261_PWR_DIG2, 0x0000); - snd_soc_write(codec, RT3261_PWR_VOL, 0x0000); - snd_soc_write(codec, RT3261_PWR_MIXER, 0x0000); - snd_soc_write(codec, RT3261_PWR_ANLG1, 0x0000); - snd_soc_write(codec, RT3261_PWR_ANLG2, 0x0000); - break; - - default: - break; - } - codec->dapm.bias_level = level; - - return 0; -} - -static int rt3261_probe(struct snd_soc_codec *codec) -{ - struct rt3261_priv *rt3261 = snd_soc_codec_get_drvdata(codec); - int ret; -#ifdef RTK_IOCTL -#if defined(CONFIG_SND_HWDEP) || defined(CONFIG_SND_HWDEP_MODULE) - struct rt_codec_ops *ioctl_ops = rt_codec_get_ioctl_ops(); -#endif -#endif - #if defined (CONFIG_SND_SOC_RT3224) - pr_info("Codec driver version %s, in fact you choose rt3224, no dsp!\n", VERSION); - #else - pr_info("Codec driver version %s, in fact you choose rt3261 with a dsp!\n", VERSION); - #endif - - ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); - if (ret != 0) { - dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); - return ret; - } - codec->write = rt3261_write; - - #if 0//defined (CONFIG_SND_SOC_RT5623) - struct clk *iis_clk; - //for rt5623 MCLK use - iis_clk = clk_get_sys("rk_i2s.2", "i2s"); - if (IS_ERR(iis_clk)) { - DBG("failed to get i2s clk\n"); - ret = PTR_ERR(iis_clk); - }else{ - DBG("I2S2 got i2s clk ok!\n"); - clk_enable(iis_clk); - clk_set_rate(iis_clk, 11289600); - rk30_mux_api_set(GPIO0D0_I2S22CHCLK_SMCCSN0_NAME, GPIO0D_I2S2_2CH_CLK); - clk_put(iis_clk); - } - #endif - - ret=rt3261_reset(codec); - if (ret < 0) - { - return -ENODEV; - } - snd_soc_update_bits(codec, RT3261_PWR_ANLG1, - RT3261_PWR_VREF1 | RT3261_PWR_MB | - RT3261_PWR_BG | RT3261_PWR_VREF2, - RT3261_PWR_VREF1 | RT3261_PWR_MB | - RT3261_PWR_BG | RT3261_PWR_VREF2); - msleep(10); - snd_soc_update_bits(codec, RT3261_PWR_ANLG1, - RT3261_PWR_FV1 | RT3261_PWR_FV2, - RT3261_PWR_FV1 | RT3261_PWR_FV2); - /* DMIC */ - if (rt3261->dmic_en == RT3261_DMIC1) { - snd_soc_update_bits(codec, RT3261_GPIO_CTRL1, - RT3261_GP2_PIN_MASK, RT3261_GP2_PIN_DMIC1_SCL); - snd_soc_update_bits(codec, RT3261_DMIC, - RT3261_DMIC_1L_LH_MASK | RT3261_DMIC_1R_LH_MASK, - RT3261_DMIC_1L_LH_FALLING | RT3261_DMIC_1R_LH_RISING); - } else if (rt3261->dmic_en == RT3261_DMIC2) { - snd_soc_update_bits(codec, RT3261_GPIO_CTRL1, - RT3261_GP2_PIN_MASK, RT3261_GP2_PIN_DMIC1_SCL); - snd_soc_update_bits(codec, RT3261_DMIC, - RT3261_DMIC_2L_LH_MASK | RT3261_DMIC_2R_LH_MASK, - RT3261_DMIC_2L_LH_FALLING | RT3261_DMIC_2R_LH_RISING); - } - snd_soc_write(codec, RT3261_GEN_CTRL2, 0x4040); - ret = snd_soc_read(codec, RT3261_VENDOR_ID); - printk("read codec chip id is 0x%x\n",ret); - if(0x5==ret) { - snd_soc_update_bits(codec, RT3261_JD_CTRL, - RT3261_JD1_IN4P_MASK | RT3261_JD2_IN4N_MASK, - RT3261_JD1_IN4P_EN | RT3261_JD2_IN4N_EN); - } - else if(0x3==ret) - { - printk("you use an old chip, please use a new one\n"); - } - snd_soc_update_bits(codec, RT3261_PWR_ANLG1, - RT3261_PWR_HP_L | RT3261_PWR_HP_R, - 0<<7 | 0<<6 ); - rt3261_reg_init(codec); - rt3261_customer_redefine(codec, rt3261); - - codec->dapm.bias_level = SND_SOC_BIAS_STANDBY; - rt3261->codec = codec; - - snd_soc_add_codec_controls(codec, rt3261_snd_controls, - ARRAY_SIZE(rt3261_snd_controls)); - snd_soc_dapm_new_controls(&codec->dapm, rt3261_dapm_widgets, - ARRAY_SIZE(rt3261_dapm_widgets)); - snd_soc_dapm_add_routes(&codec->dapm, rt3261_dapm_routes, - ARRAY_SIZE(rt3261_dapm_routes)); - - -#if defined (CONFIG_SND_SOC_RT3261) - rt3261->dsp_sw = RT3261_DSP_AEC_NS_FENS; - rt3261_dsp_probe(codec); -#endif - -#ifdef RTK_IOCTL -#if defined(CONFIG_SND_HWDEP) || defined(CONFIG_SND_HWDEP_MODULE) - ioctl_ops->index_write = rt3261_index_write; - ioctl_ops->index_read = rt3261_index_read; - ioctl_ops->index_update_bits = rt3261_index_update_bits; - ioctl_ops->ioctl_common = rt3261_ioctl_common; - realtek_ce_init_hwdep(codec); -#endif -#endif - - - ret = device_create_file(codec->dev, &dev_attr_index_reg); - if (ret != 0) { - dev_err(codec->dev, - "Failed to create index_reg sysfs files: %d\n", ret); - return ret; - } - rt3261_codec = codec; - - return 0; -} - -static int rt3261_remove(struct snd_soc_codec *codec) -{ - rt3261_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - -#ifdef CONFIG_PM -static int rt3261_suspend(struct snd_soc_codec *codec) -{ -#if defined (CONFIG_SND_SOC_RT3261) - /* After opening LDO of DSP, then close LDO of codec. - * (1) DSP LDO power on - * (2) DSP core power off - * (3) DSP IIS interface power off - * (4) Toggle pin of codec LDO1 to power off - */ - rt3261_dsp_suspend(codec); -#endif - rt3261_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - -static int rt3261_resume(struct snd_soc_codec *codec) -{ - rt3261_set_bias_level(codec, SND_SOC_BIAS_STANDBY); -#if defined (CONFIG_SND_SOC_RT3261) - /* After opening LDO of codec, then close LDO of DSP. */ - rt3261_dsp_resume(codec); -#endif - return 0; -} -#else -#define rt3261_suspend NULL -#define rt3261_resume NULL -#endif - -#define RT3261_STEREO_RATES SNDRV_PCM_RATE_8000_96000 -#define RT3261_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ - SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8) - -struct snd_soc_dai_ops rt3261_aif_dai_ops = { - .hw_params = rt3261_hw_params, - .prepare = rt3261_prepare, - .set_fmt = rt3261_set_dai_fmt, - .set_sysclk = rt3261_set_dai_sysclk, - .set_pll = rt3261_set_dai_pll, -}; - -struct snd_soc_dai_driver rt3261_dai[] = { - { - .name = "rt3261-aif1", - .id = RT3261_AIF1, - .playback = { - .stream_name = "AIF1 Playback", - .channels_min = 1, - .channels_max = 2, - .rates = RT3261_STEREO_RATES, - .formats = RT3261_FORMATS, - }, - .capture = { - .stream_name = "AIF1 Capture", - .channels_min = 1, - .channels_max = 2, - .rates = RT3261_STEREO_RATES, - .formats = RT3261_FORMATS, - }, - .ops = &rt3261_aif_dai_ops, - }, - { - .name = "rt3261-aif2", - .id = RT3261_AIF2, - .playback = { - .stream_name = "AIF2 Playback", - .channels_min = 1, - .channels_max = 2, - .rates = RT3261_STEREO_RATES, - .formats = RT3261_FORMATS, - }, - .capture = { - .stream_name = "AIF2 Capture", - .channels_min = 1, - .channels_max = 2, - .rates = RT3261_STEREO_RATES, - .formats = RT3261_FORMATS, - }, - .ops = &rt3261_aif_dai_ops, - }, -}; - -static struct snd_soc_codec_driver soc_codec_dev_rt3261 = { - .probe = rt3261_probe, - .remove = rt3261_remove, - .suspend = rt3261_suspend, - .resume = rt3261_resume, - .write = rt3261_write, - .set_bias_level = rt3261_set_bias_level, - .reg_cache_size = RT3261_VENDOR_ID2 + 1, - .reg_word_size = sizeof(u16), - .reg_cache_default = rt3261_reg, - .volatile_register = rt3261_volatile_register, - .readable_register = rt3261_readable_register, - .reg_cache_step = 1, -}; - -static const struct i2c_device_id rt3261_i2c_id[] = { - { "rt3261", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, rt3261_i2c_id); - -#ifdef CONFIG_OF -/* -dts: - rt3261: rt3261@1c { - compatible = "rt3261"; - reg = <0x1c>; - codec-en-gpio = <&gpio3 GPIO_D7 GPIO_ACTIVE_HIGH>; - spk-num= <2>; - modem-input-mode = <1>; - lout-to-modem_mode = <1>; - spk-amplify = <2>; - playback-if1-data_control = <0>; - playback-if2-data_control = <0>; - }; -*/ - -static int rt3261_parse_dt_property(struct device *dev, - struct rt3261_priv *rt3261) -{ - struct device_node *node = dev->of_node; - int ret; - enum of_gpio_flags flags; - - DBG("%s()\n", __FUNCTION__); - - if (!node) - return -ENODEV; - - rt3261->codec_en_gpio = of_get_named_gpio_flags(node, "codec-en-gpio", 0, &flags); - if (rt3261->codec_en_gpio <= 0) { - DBG("%s() Can not read property codec-en-gpio\n", __FUNCTION__); - } else { - ret = devm_gpio_request(dev, rt3261->codec_en_gpio, "codec_en_gpio"); - if(ret){ - printk("%s() codec_en_gpio request ERROR", __FUNCTION__); - return ret; - } - ret = gpio_direction_output(rt3261->codec_en_gpio , !flags); - if(ret){ - printk("%s() codec_en_gpio set ERROR", __FUNCTION__); - return ret; - } - } - - ret = of_property_read_u32(node, "spk-num", &rt3261->spk_num); - if (ret < 0) { - DBG("%s() Can not read property spk-num\n", __FUNCTION__); - rt3261->spk_num = TWO_SPK; - } - - ret = of_property_read_u32(node, "modem-input-mode", &rt3261->modem_input_mode); - if (ret < 0) { - DBG("%s() Can not read property modem-input-mode\n", __FUNCTION__); - rt3261->modem_input_mode = DIFFERENTIAL; - } - - ret = of_property_read_u32(node, "lout-to-modem-mode", &rt3261->lout_to_modem_mode); - if (ret < 0) { - DBG("%s() Can not read property lout-to-modem-mode\n", __FUNCTION__); - rt3261->lout_to_modem_mode = DIFFERENTIAL; - } - - ret = of_property_read_u32(node, "spk-amplify", &rt3261->spk_amplify); - if (ret < 0) { - DBG("%s() Can not read property spk-amplify\n", __FUNCTION__); - rt3261->spk_amplify = SPK_AMPLIFY_ZERO_POINT_SIX_WATT; - } - - ret = of_property_read_u32(node, "playback-if1-data-control", &rt3261->playback_if1_data_control); - if (ret < 0) { - DBG("%s() Can not read property playback-if1-data-control\n", __FUNCTION__); - rt3261->playback_if1_data_control = LR_NORMAL; - } - - ret = of_property_read_u32(node, "playback-if2-data-control", &rt3261->playback_if2_data_control); - if (ret < 0) { - DBG("%s() Can not read property playback-if2-data-control\n", __FUNCTION__); - rt3261->playback_if1_data_control = LR_NORMAL; - } - return 0; -} -#else -static int rt3261_parse_dt_property(struct device *dev, - struct rt3261_priv *rt3261) -{ - return -ENOSYS; -} -#endif //#ifdef CONFIG_OF - -static int rt3261_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) -{ - struct rt3261_priv *rt3261; - int ret; - char reg; - - reg = RT3261_VENDOR_ID; - ret = i2c_master_recv(i2c, ®, 1); - if (ret < 0){ - printk("rt3261 && rt3224 probe error\n"); - return ret; - } - - rt3261 = devm_kzalloc(&i2c->dev,sizeof(struct rt3261_priv), GFP_KERNEL); - if (NULL == rt3261) - return -ENOMEM; - rt3261->i2c = i2c; - - ret = rt3261_parse_dt_property(&i2c->dev, rt3261); - if (ret < 0) { - printk("%s() parse device tree property error %d\n", __FUNCTION__, ret); - return ret; - } - - #if defined (CONFIG_SND_SOC_RT5623) - rt3261->modem_is_open = 0; - #endif - - i2c_set_clientdata(i2c, rt3261); - DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); - ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt3261, - rt3261_dai, ARRAY_SIZE(rt3261_dai)); - - return ret; -} - -static int rt3261_i2c_remove(struct i2c_client *i2c) -{ - snd_soc_unregister_codec(&i2c->dev); - kfree(i2c_get_clientdata(i2c)); - return 0; -} - -static void rt3261_i2c_shutdown(struct i2c_client *client) -{ - struct rt3261_priv *rt3261 = i2c_get_clientdata(client); - struct snd_soc_codec *codec = rt3261->codec; - - if (codec != NULL) - rt3261_set_bias_level(codec, SND_SOC_BIAS_OFF); -} - -struct i2c_driver rt3261_i2c_driver = { - .driver = { - .name = "rt3261", - .owner = THIS_MODULE, - }, - .probe = rt3261_i2c_probe, - .remove = rt3261_i2c_remove, - .shutdown = rt3261_i2c_shutdown, - .id_table = rt3261_i2c_id, -}; - -static int __init rt3261_modinit(void) -{ - return i2c_add_driver(&rt3261_i2c_driver); -} -module_init(rt3261_modinit); - -static void __exit rt3261_modexit(void) -{ - i2c_del_driver(&rt3261_i2c_driver); -} -module_exit(rt3261_modexit); - -MODULE_DESCRIPTION("ASoC RT3261 driver"); -MODULE_AUTHOR("Johnny Hsu "); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/rt3261.h b/sound/soc/codecs/rt3261.h deleted file mode 100755 index 589199cee1b0..000000000000 --- a/sound/soc/codecs/rt3261.h +++ /dev/null @@ -1,2170 +0,0 @@ -/* - * rt3261.h -- RT3261 ALSA SoC audio driver - * - * Copyright 2011 Realtek Microelectronics - * Author: Johnny Hsu - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef __RT3261_H__ -#define __RT3261_H__ - -/* Info */ -#define RT3261_RESET 0x00 -#define RT3261_VENDOR_ID 0xfd -#define RT3261_VENDOR_ID1 0xfe -#define RT3261_VENDOR_ID2 0xff -/* I/O - Output */ -#define RT3261_SPK_VOL 0x01 -#define RT3261_HP_VOL 0x02 -#define RT3261_OUTPUT 0x03 -#define RT3261_MONO_OUT 0x04 -/* Dummy */ -#define RT3261_DUMMY_PR3F 0x05 -#define RT3261_DUMMY_SPKMIXER 0x06 -/* I/O - Input */ -#define RT3261_IN1_IN2 0x0d -#define RT3261_IN3_IN4 0x0e -#define RT3261_INL_INR_VOL 0x0f -/* I/O - ADC/DAC/DMIC */ -#define RT3261_DAC1_DIG_VOL 0x19 -#define RT3261_DAC2_DIG_VOL 0x1a -#define RT3261_DAC2_CTRL 0x1b -#define RT3261_ADC_DIG_VOL 0x1c -#define RT3261_ADC_DATA 0x1d -#define RT3261_ADC_BST_VOL 0x1e -/* Mixer - D-D */ -#define RT3261_STO_ADC_MIXER 0x27 -#define RT3261_MONO_ADC_MIXER 0x28 -#define RT3261_AD_DA_MIXER 0x29 -#define RT3261_STO_DAC_MIXER 0x2a -#define RT3261_MONO_DAC_MIXER 0x2b -#define RT3261_DIG_MIXER 0x2c -#define RT3261_DSP_PATH1 0x2d -#define RT3261_DSP_PATH2 0x2e -#define RT3261_DIG_INF_DATA 0x2f -/* Mixer - ADC */ -#define RT3261_REC_L1_MIXER 0x3b -#define RT3261_REC_L2_MIXER 0x3c -#define RT3261_REC_R1_MIXER 0x3d -#define RT3261_REC_R2_MIXER 0x3e -/* Mixer - DAC */ -#define RT3261_HPO_MIXER 0x45 -#define RT3261_SPK_L_MIXER 0x46 -#define RT3261_SPK_R_MIXER 0x47 -#define RT3261_SPO_L_MIXER 0x48 -#define RT3261_SPO_R_MIXER 0x49 -#define RT3261_SPO_CLSD_RATIO 0x4a -#define RT3261_MONO_MIXER 0x4c -#define RT3261_OUT_L1_MIXER 0x4d -#define RT3261_OUT_L2_MIXER 0x4e -#define RT3261_OUT_L3_MIXER 0x4f -#define RT3261_OUT_R1_MIXER 0x50 -#define RT3261_OUT_R2_MIXER 0x51 -#define RT3261_OUT_R3_MIXER 0x52 -#define RT3261_LOUT_MIXER 0x53 -/* Power */ -#define RT3261_PWR_DIG1 0x61 -#define RT3261_PWR_DIG2 0x62 -#define RT3261_PWR_ANLG1 0x63 -#define RT3261_PWR_ANLG2 0x64 -#define RT3261_PWR_MIXER 0x65 -#define RT3261_PWR_VOL 0x66 -/* Private Register Control */ -#define RT3261_PRIV_INDEX 0x6a -#define RT3261_PRIV_DATA 0x6c -/* Format - ADC/DAC */ -#define RT3261_I2S1_SDP 0x70 -#define RT3261_I2S2_SDP 0x71 -#define RT3261_I2S3_SDP 0x72 -#define RT3261_ADDA_CLK1 0x73 -#define RT3261_ADDA_CLK2 0x74 -#define RT3261_DMIC 0x75 -/* Function - Analog */ -#define RT3261_GLB_CLK 0x80 -#define RT3261_PLL_CTRL1 0x81 -#define RT3261_PLL_CTRL2 0x82 -#define RT3261_ASRC_1 0x83 -#define RT3261_ASRC_2 0x84 -#define RT3261_ASRC_3 0x85 -#define RT3261_ASRC_4 0x89 -#define RT3261_ASRC_5 0x8a -#define RT3261_HP_OVCD 0x8b -#define RT3261_CLS_D_OVCD 0x8c -#define RT3261_CLS_D_OUT 0x8d -#define RT3261_DEPOP_M1 0x8e -#define RT3261_DEPOP_M2 0x8f -#define RT3261_DEPOP_M3 0x90 -#define RT3261_CHARGE_PUMP 0x91 -#define RT3261_PV_DET_SPK_G 0x92 -#define RT3261_MICBIAS 0x93 -/* Function - Digital */ -#define RT3261_EQ_CTRL1 0xb0 -#define RT3261_EQ_CTRL2 0xb1 -#define RT3261_WIND_FILTER 0xb2 -#define RT3261_DRC_AGC_1 0xb4 -#define RT3261_DRC_AGC_2 0xb5 -#define RT3261_DRC_AGC_3 0xb6 -#define RT3261_SVOL_ZC 0xb7 -#define RT3261_ANC_CTRL1 0xb8 -#define RT3261_ANC_CTRL2 0xb9 -#define RT3261_ANC_CTRL3 0xba -#define RT3261_JD_CTRL 0xbb -#define RT3261_ANC_JD 0xbc -#define RT3261_IRQ_CTRL1 0xbd -#define RT3261_IRQ_CTRL2 0xbe -#define RT3261_INT_IRQ_ST 0xbf -#define RT3261_GPIO_CTRL1 0xc0 -#define RT3261_GPIO_CTRL2 0xc1 -#define RT3261_GPIO_CTRL3 0xc2 -#define RT3261_DSP_CTRL1 0xc4 -#define RT3261_DSP_CTRL2 0xc5 -#define RT3261_DSP_CTRL3 0xc6 -#define RT3261_DSP_CTRL4 0xc7 -#define RT3261_PGM_REG_ARR1 0xc8 -#define RT3261_PGM_REG_ARR2 0xc9 -#define RT3261_PGM_REG_ARR3 0xca -#define RT3261_PGM_REG_ARR4 0xcb -#define RT3261_PGM_REG_ARR5 0xcc -#define RT3261_SCB_FUNC 0xcd -#define RT3261_SCB_CTRL 0xce -#define RT3261_BASE_BACK 0xcf -#define RT3261_MP3_PLUS1 0xd0 -#define RT3261_MP3_PLUS2 0xd1 -#define RT3261_3D_HP 0xd2 -#define RT3261_ADJ_HPF 0xd3 -#define RT3261_HP_CALIB_AMP_DET 0xd6 -#define RT3261_HP_CALIB2 0xd7 -#define RT3261_SV_ZCD1 0xd9 -#define RT3261_SV_ZCD2 0xda -/* General Control */ -#define RT3261_GEN_CTRL1 0xfa -#define RT3261_GEN_CTRL2 0xfb -#define RT3261_GEN_CTRL3 0xfc - - -/* Index of Codec Private Register definition */ -#define RT3261_BIAS_CUR1 0x12 -#define RT3261_BIAS_CUR3 0x14 -#define RT3261_CLSD_INT_REG1 0x1c -#define RT3261_CHPUMP_INT_REG1 0x24 //bard 11-6 -#define RT3261_MAMP_INT_REG2 0x37 -#define RT3261_CHOP_DAC_ADC 0x3d -#define RT3261_MIXER_INT_REG 0x3f -#define RT3261_3D_SPK 0x63 -#define RT3261_WND_1 0x6c -#define RT3261_WND_2 0x6d -#define RT3261_WND_3 0x6e -#define RT3261_WND_4 0x6f -#define RT3261_WND_5 0x70 -#define RT3261_WND_8 0x73 -#define RT3261_DIP_SPK_INF 0x75 -#define RT3261_HP_DCC_INT1 0x77 -#define RT3261_EQ_BW_LOP 0xa0 -#define RT3261_EQ_GN_LOP 0xa1 -#define RT3261_EQ_FC_BP1 0xa2 -#define RT3261_EQ_BW_BP1 0xa3 -#define RT3261_EQ_GN_BP1 0xa4 -#define RT3261_EQ_FC_BP2 0xa5 -#define RT3261_EQ_BW_BP2 0xa6 -#define RT3261_EQ_GN_BP2 0xa7 -#define RT3261_EQ_FC_BP3 0xa8 -#define RT3261_EQ_BW_BP3 0xa9 -#define RT3261_EQ_GN_BP3 0xaa -#define RT3261_EQ_FC_BP4 0xab -#define RT3261_EQ_BW_BP4 0xac -#define RT3261_EQ_GN_BP4 0xad -#define RT3261_EQ_FC_HIP1 0xae -#define RT3261_EQ_GN_HIP1 0xaf -#define RT3261_EQ_FC_HIP2 0xb0 -#define RT3261_EQ_BW_HIP2 0xb1 -#define RT3261_EQ_GN_HIP2 0xb2 -#define RT3261_EQ_PRE_VOL 0xb3 -#define RT3261_EQ_PST_VOL 0xb4 - - -/* global definition */ -#define RT3261_L_MUTE (0x1 << 15) -#define RT3261_L_MUTE_SFT 15 -#define RT3261_VOL_L_MUTE (0x1 << 14) -#define RT3261_VOL_L_SFT 14 -#define RT3261_R_MUTE (0x1 << 7) -#define RT3261_R_MUTE_SFT 7 -#define RT3261_VOL_R_MUTE (0x1 << 6) -#define RT3261_VOL_R_SFT 6 -#define RT3261_L_VOL_MASK (0x3f << 8) -#define RT3261_L_VOL_SFT 8 -#define RT3261_R_VOL_MASK (0x3f) -#define RT3261_R_VOL_SFT 0 - -/* IN1 and IN2 Control (0x0d) */ -/* IN3 and IN4 Control (0x0e) */ -#define RT3261_BST_MASK1 (0xf<<12) -#define RT3261_BST_SFT1 12 -#define RT3261_BST_MASK2 (0xf<<8) -#define RT3261_BST_SFT2 8 -#define RT3261_IN_DF1 (0x1 << 7) -#define RT3261_IN_SFT1 7 -#define RT3261_IN_DF2 (0x1 << 6) -#define RT3261_IN_SFT2 6 - -/* INL and INR Volume Control (0x0f) */ -#define RT3261_INL_SEL_MASK (0x1 << 15) -#define RT3261_INL_SEL_SFT 15 -#define RT3261_INL_SEL_IN4P (0x0 << 15) -#define RT3261_INL_SEL_MONOP (0x1 << 15) -#define RT3261_INL_VOL_MASK (0x1f << 8) -#define RT3261_INL_VOL_SFT 8 -#define RT3261_INR_SEL_MASK (0x1 << 7) -#define RT3261_INR_SEL_SFT 7 -#define RT3261_INR_SEL_IN4N (0x0 << 7) -#define RT3261_INR_SEL_MONON (0x1 << 7) -#define RT3261_INR_VOL_MASK (0x1f) -#define RT3261_INR_VOL_SFT 0 - -/* DAC1 Digital Volume (0x19) */ -#define RT3261_DAC_L1_VOL_MASK (0xff << 8) -#define RT3261_DAC_L1_VOL_SFT 8 -#define RT3261_DAC_R1_VOL_MASK (0xff) -#define RT3261_DAC_R1_VOL_SFT 0 - -/* DAC2 Digital Volume (0x1a) */ -#define RT3261_DAC_L2_VOL_MASK (0xff << 8) -#define RT3261_DAC_L2_VOL_SFT 8 -#define RT3261_DAC_R2_VOL_MASK (0xff) -#define RT3261_DAC_R2_VOL_SFT 0 - -/* DAC2 Control (0x1b) */ -#define RT3261_M_DAC_L2_VOL (0x1 << 13) -#define RT3261_M_DAC_L2_VOL_SFT 13 -#define RT3261_M_DAC_R2_VOL (0x1 << 12) -#define RT3261_M_DAC_R2_VOL_SFT 12 - -/* ADC Digital Volume Control (0x1c) */ -#define RT3261_ADC_L_VOL_MASK (0x7f << 8) -#define RT3261_ADC_L_VOL_SFT 8 -#define RT3261_ADC_R_VOL_MASK (0x7f) -#define RT3261_ADC_R_VOL_SFT 0 - -/* Mono ADC Digital Volume Control (0x1d) */ -#define RT3261_MONO_ADC_L_VOL_MASK (0x7f << 8) -#define RT3261_MONO_ADC_L_VOL_SFT 8 -#define RT3261_MONO_ADC_R_VOL_MASK (0x7f) -#define RT3261_MONO_ADC_R_VOL_SFT 0 - -/* ADC Boost Volume Control (0x1e) */ -#define RT3261_ADC_L_BST_MASK (0x3 << 14) -#define RT3261_ADC_L_BST_SFT 14 -#define RT3261_ADC_R_BST_MASK (0x3 << 12) -#define RT3261_ADC_R_BST_SFT 12 -#define RT3261_ADC_COMP_MASK (0x3 << 10) -#define RT3261_ADC_COMP_SFT 10 - -/* Stereo ADC Mixer Control (0x27) */ -#define RT3261_M_ADC_L1 (0x1 << 14) -#define RT3261_M_ADC_L1_SFT 14 -#define RT3261_M_ADC_L2 (0x1 << 13) -#define RT3261_M_ADC_L2_SFT 13 -#define RT3261_ADC_1_SRC_MASK (0x1 << 12) -#define RT3261_ADC_1_SRC_SFT 12 -#define RT3261_ADC_1_SRC_ADC (0x1 << 12) -#define RT3261_ADC_1_SRC_DACMIX (0x0 << 12) -#define RT3261_ADC_2_SRC_MASK (0x3 << 10) -#define RT3261_ADC_2_SRC_SFT 10 -#define RT3261_ADC_2_SRC_DMIC1 (0x0 << 10) -#define RT3261_ADC_2_SRC_DMIC2 (0x1 << 10) -#define RT3261_ADC_2_SRC_DACMIX (0x2 << 10) -#define RT3261_M_ADC_R1 (0x1 << 6) -#define RT3261_M_ADC_R1_SFT 6 -#define RT3261_M_ADC_R2 (0x1 << 5) -#define RT3261_M_ADC_R2_SFT 5 - -/* Mono ADC Mixer Control (0x28) */ -#define RT3261_M_MONO_ADC_L1 (0x1 << 14) -#define RT3261_M_MONO_ADC_L1_SFT 14 -#define RT3261_M_MONO_ADC_L2 (0x1 << 13) -#define RT3261_M_MONO_ADC_L2_SFT 13 -#define RT3261_MONO_ADC_L1_SRC_MASK (0x1 << 12) -#define RT3261_MONO_ADC_L1_SRC_SFT 12 -#define RT3261_MONO_ADC_L1_SRC_DACMIXL (0x0 << 12) -#define RT3261_MONO_ADC_L1_SRC_ADCL (0x1 << 12) -#define RT3261_MONO_ADC_L2_SRC_MASK (0x3 << 10) -#define RT3261_MONO_ADC_L2_SRC_SFT 10 -#define RT3261_MONO_ADC_L2_SRC_DMIC_L1 (0x0 << 10) -#define RT3261_MONO_ADC_L2_SRC_DMIC_L2 (0x1 << 10) -#define RT3261_MONO_ADC_L2_SRC_DACMIXL (0x2 << 10) -#define RT3261_M_MONO_ADC_R1 (0x1 << 6) -#define RT3261_M_MONO_ADC_R1_SFT 6 -#define RT3261_M_MONO_ADC_R2 (0x1 << 5) -#define RT3261_M_MONO_ADC_R2_SFT 5 -#define RT3261_MONO_ADC_R1_SRC_MASK (0x1 << 4) -#define RT3261_MONO_ADC_R1_SRC_SFT 4 -#define RT3261_MONO_ADC_R1_SRC_ADCR (0x1 << 4) -#define RT3261_MONO_ADC_R1_SRC_DACMIXR (0x0 << 4) -#define RT3261_MONO_ADC_R2_SRC_MASK (0x3 << 2) -#define RT3261_MONO_ADC_R2_SRC_SFT 2 -#define RT3261_MONO_ADC_R2_SRC_DMIC_R1 (0x0 << 2) -#define RT3261_MONO_ADC_R2_SRC_DMIC_R2 (0x1 << 2) -#define RT3261_MONO_ADC_R2_SRC_DACMIXR (0x2 << 2) - -/* ADC Mixer to DAC Mixer Control (0x29) */ -#define RT3261_M_ADCMIX_L (0x1 << 15) -#define RT3261_M_ADCMIX_L_SFT 15 -#define RT3261_M_IF1_DAC_L (0x1 << 14) -#define RT3261_M_IF1_DAC_L_SFT 14 -#define RT3261_M_ADCMIX_R (0x1 << 7) -#define RT3261_M_ADCMIX_R_SFT 7 -#define RT3261_M_IF1_DAC_R (0x1 << 6) -#define RT3261_M_IF1_DAC_R_SFT 6 - -/* Stereo DAC Mixer Control (0x2a) */ -#define RT3261_M_DAC_L1 (0x1 << 14) -#define RT3261_M_DAC_L1_SFT 14 -#define RT3261_DAC_L1_STO_L_VOL_MASK (0x1 << 13) -#define RT3261_DAC_L1_STO_L_VOL_SFT 13 -#define RT3261_M_DAC_L2 (0x1 << 12) -#define RT3261_M_DAC_L2_SFT 12 -#define RT3261_DAC_L2_STO_L_VOL_MASK (0x1 << 11) -#define RT3261_DAC_L2_STO_L_VOL_SFT 11 -#define RT3261_M_ANC_DAC_L (0x1 << 10) -#define RT3261_M_ANC_DAC_L_SFT 10 -#define RT3261_M_DAC_R1 (0x1 << 6) -#define RT3261_M_DAC_R1_SFT 6 -#define RT3261_DAC_R1_STO_R_VOL_MASK (0x1 << 5) -#define RT3261_DAC_R1_STO_R_VOL_SFT 5 -#define RT3261_M_DAC_R2 (0x1 << 4) -#define RT3261_M_DAC_R2_SFT 4 -#define RT3261_DAC_R2_STO_R_VOL_MASK (0x1 << 3) -#define RT3261_DAC_R2_STO_R_VOL_SFT 3 -#define RT3261_M_ANC_DAC_R (0x1 << 2) -#define RT3261_M_ANC_DAC_R_SFT 2 - -/* Mono DAC Mixer Control (0x2b) */ -#define RT3261_M_DAC_L1_MONO_L (0x1 << 14) -#define RT3261_M_DAC_L1_MONO_L_SFT 14 -#define RT3261_DAC_L1_MONO_L_VOL_MASK (0x1 << 13) -#define RT3261_DAC_L1_MONO_L_VOL_SFT 13 -#define RT3261_M_DAC_L2_MONO_L (0x1 << 12) -#define RT3261_M_DAC_L2_MONO_L_SFT 12 -#define RT3261_DAC_L2_MONO_L_VOL_MASK (0x1 << 11) -#define RT3261_DAC_L2_MONO_L_VOL_SFT 11 -#define RT3261_M_DAC_R2_MONO_L (0x1 << 10) -#define RT3261_M_DAC_R2_MONO_L_SFT 10 -#define RT3261_DAC_R2_MONO_L_VOL_MASK (0x1 << 9) -#define RT3261_DAC_R2_MONO_L_VOL_SFT 9 -#define RT3261_M_DAC_R1_MONO_R (0x1 << 6) -#define RT3261_M_DAC_R1_MONO_R_SFT 6 -#define RT3261_DAC_R1_MONO_R_VOL_MASK (0x1 << 5) -#define RT3261_DAC_R1_MONO_R_VOL_SFT 5 -#define RT3261_M_DAC_R2_MONO_R (0x1 << 4) -#define RT3261_M_DAC_R2_MONO_R_SFT 4 -#define RT3261_DAC_R2_MONO_R_VOL_MASK (0x1 << 3) -#define RT3261_DAC_R2_MONO_R_VOL_SFT 3 -#define RT3261_M_DAC_L2_MONO_R (0x1 << 2) -#define RT3261_M_DAC_L2_MONO_R_SFT 2 -#define RT3261_DAC_L2_MONO_R_VOL_MASK (0x1 << 1) -#define RT3261_DAC_L2_MONO_R_VOL_SFT 1 - -/* Digital Mixer Control (0x2c) */ -#define RT3261_M_STO_L_DAC_L (0x1 << 15) -#define RT3261_M_STO_L_DAC_L_SFT 15 -#define RT3261_STO_L_DAC_L_VOL_MASK (0x1 << 14) -#define RT3261_STO_L_DAC_L_VOL_SFT 14 -#define RT3261_M_DAC_L2_DAC_L (0x1 << 13) -#define RT3261_M_DAC_L2_DAC_L_SFT 13 -#define RT3261_DAC_L2_DAC_L_VOL_MASK (0x1 << 12) -#define RT3261_DAC_L2_DAC_L_VOL_SFT 12 -#define RT3261_M_STO_R_DAC_R (0x1 << 11) -#define RT3261_M_STO_R_DAC_R_SFT 11 -#define RT3261_STO_R_DAC_R_VOL_MASK (0x1 << 10) -#define RT3261_STO_R_DAC_R_VOL_SFT 10 -#define RT3261_M_DAC_R2_DAC_R (0x1 << 9) -#define RT3261_M_DAC_R2_DAC_R_SFT 9 -#define RT3261_DAC_R2_DAC_R_VOL_MASK (0x1 << 8) -#define RT3261_DAC_R2_DAC_R_VOL_SFT 8 - -/* DSP Path Control 1 (0x2d) */ -#define RT3261_RXDP_SRC_MASK (0x1 << 15) -#define RT3261_RXDP_SRC_SFT 15 -#define RT3261_RXDP_SRC_NOR (0x0 << 15) -#define RT3261_RXDP_SRC_DIV3 (0x1 << 15) -#define RT3261_TXDP_SRC_MASK (0x1 << 14) -#define RT3261_TXDP_SRC_SFT 14 -#define RT3261_TXDP_SRC_NOR (0x0 << 14) -#define RT3261_TXDP_SRC_DIV3 (0x1 << 14) - -/* DSP Path Control 2 (0x2e) */ -#define RT3261_DAC_L2_SEL_MASK (0x3 << 14) -#define RT3261_DAC_L2_SEL_SFT 14 -#define RT3261_DAC_L2_SEL_IF2 (0x0 << 14) -#define RT3261_DAC_L2_SEL_IF3 (0x1 << 14) -#define RT3261_DAC_L2_SEL_TXDC (0x2 << 14) -#define RT3261_DAC_L2_SEL_BASS (0x3 << 14) -#define RT3261_DAC_R2_SEL_MASK (0x3 << 12) -#define RT3261_DAC_R2_SEL_SFT 12 -#define RT3261_DAC_R2_SEL_IF2 (0x0 << 12) -#define RT3261_DAC_R2_SEL_IF3 (0x1 << 12) -#define RT3261_DAC_R2_SEL_TXDC (0x2 << 12) -#define RT3261_IF2_ADC_L_SEL_MASK (0x1 << 11) -#define RT3261_IF2_ADC_L_SEL_SFT 11 -#define RT3261_IF2_ADC_L_SEL_TXDP (0x0 << 11) -#define RT3261_IF2_ADC_L_SEL_PASS (0x1 << 11) -#define RT3261_IF2_ADC_R_SEL_MASK (0x1 << 10) -#define RT3261_IF2_ADC_R_SEL_SFT 10 -#define RT3261_IF2_ADC_R_SEL_TXDP (0x0 << 10) -#define RT3261_IF2_ADC_R_SEL_PASS (0x1 << 10) -#define RT3261_RXDC_SEL_MASK (0x3 << 8) -#define RT3261_RXDC_SEL_SFT 8 -#define RT3261_RXDC_SEL_NOR (0x0 << 8) -#define RT3261_RXDC_SEL_L2R (0x1 << 8) -#define RT3261_RXDC_SEL_R2L (0x2 << 8) -#define RT3261_RXDC_SEL_SWAP (0x3 << 8) -#define RT3261_RXDP_SEL_MASK (0x3 << 6) -#define RT3261_RXDP_SEL_SFT 6 -#define RT3261_RXDP_SEL_NOR (0x0 << 6) -#define RT3261_RXDP_SEL_L2R (0x1 << 6) -#define RT3261_RXDP_SEL_R2L (0x2 << 6) -#define RT3261_RXDP_SEL_SWAP (0x3 << 6) -#define RT3261_TXDC_SEL_MASK (0x3 << 4) -#define RT3261_TXDC_SEL_SFT 4 -#define RT3261_TXDC_SEL_NOR (0x0 << 4) -#define RT3261_TXDC_SEL_L2R (0x1 << 4) -#define RT3261_TXDC_SEL_R2L (0x2 << 4) -#define RT3261_TXDC_SEL_SWAP (0x3 << 4) -#define RT3261_TXDP_SEL_MASK (0x3 << 2) -#define RT3261_TXDP_SEL_SFT 2 -#define RT3261_TXDP_SEL_NOR (0x0 << 2) -#define RT3261_TXDP_SEL_L2R (0x1 << 2) -#define RT3261_TXDP_SEL_R2L (0x2 << 2) -#define RT3261_TRXDP_SEL_SWAP (0x3 << 2) - -/* Digital Interface Data Control (0x2f) */ -#define RT3261_IF1_DAC_SEL_MASK (0x3 << 14) -#define RT3261_IF1_DAC_SEL_SFT 14 -#define RT3261_IF1_DAC_SEL_NOR (0x0 << 14) -#define RT3261_IF1_DAC_SEL_L2R (0x1 << 14) -#define RT3261_IF1_DAC_SEL_R2L (0x2 << 14) -#define RT3261_IF1_DAC_SEL_SWAP (0x3 << 14) -#define RT3261_IF1_ADC_SEL_MASK (0x3 << 12) -#define RT3261_IF1_ADC_SEL_SFT 12 -#define RT3261_IF1_ADC_SEL_NOR (0x0 << 12) -#define RT3261_IF1_ADC_SEL_L2R (0x1 << 12) -#define RT3261_IF1_ADC_SEL_R2L (0x2 << 12) -#define RT3261_IF1_ADC_SEL_SWAP (0x3 << 12) -#define RT3261_IF2_DAC_SEL_MASK (0x3 << 10) -#define RT3261_IF2_DAC_SEL_SFT 10 -#define RT3261_IF2_DAC_SEL_NOR (0x0 << 10) -#define RT3261_IF2_DAC_SEL_L2R (0x1 << 10) -#define RT3261_IF2_DAC_SEL_R2L (0x2 << 10) -#define RT3261_IF2_DAC_SEL_SWAP (0x3 << 10) -#define RT3261_IF2_ADC_SEL_MASK (0x3 << 8) -#define RT3261_IF2_ADC_SEL_SFT 8 -#define RT3261_IF2_ADC_SEL_NOR (0x0 << 8) -#define RT3261_IF2_ADC_SEL_L2R (0x1 << 8) -#define RT3261_IF2_ADC_SEL_R2L (0x2 << 8) -#define RT3261_IF2_ADC_SEL_SWAP (0x3 << 8) -#define RT3261_IF3_DAC_SEL_MASK (0x3 << 6) -#define RT3261_IF3_DAC_SEL_SFT 6 -#define RT3261_IF3_DAC_SEL_NOR (0x0 << 6) -#define RT3261_IF3_DAC_SEL_L2R (0x1 << 6) -#define RT3261_IF3_DAC_SEL_R2L (0x2 << 6) -#define RT3261_IF3_DAC_SEL_SWAP (0x3 << 6) -#define RT3261_IF3_ADC_SEL_MASK (0x3 << 4) -#define RT3261_IF3_ADC_SEL_SFT 4 -#define RT3261_IF3_ADC_SEL_NOR (0x0 << 4) -#define RT3261_IF3_ADC_SEL_L2R (0x1 << 4) -#define RT3261_IF3_ADC_SEL_R2L (0x2 << 4) -#define RT3261_IF3_ADC_SEL_SWAP (0x3 << 4) - -/* REC Left Mixer Control 1 (0x3b) */ -#define RT3261_G_HP_L_RM_L_MASK (0x7 << 13) -#define RT3261_G_HP_L_RM_L_SFT 13 -#define RT3261_G_IN_L_RM_L_MASK (0x7 << 10) -#define RT3261_G_IN_L_RM_L_SFT 10 -#define RT3261_G_BST4_RM_L_MASK (0x7 << 7) -#define RT3261_G_BST4_RM_L_SFT 7 -#define RT3261_G_BST3_RM_L_MASK (0x7 << 4) -#define RT3261_G_BST3_RM_L_SFT 4 -#define RT3261_G_BST2_RM_L_MASK (0x7 << 1) -#define RT3261_G_BST2_RM_L_SFT 1 - -/* REC Left Mixer Control 2 (0x3c) */ -#define RT3261_G_BST1_RM_L_MASK (0x7 << 13) -#define RT3261_G_BST1_RM_L_SFT 13 -#define RT3261_G_OM_L_RM_L_MASK (0x7 << 10) -#define RT3261_G_OM_L_RM_L_SFT 10 -#define RT3261_M_HP_L_RM_L (0x1 << 6) -#define RT3261_M_HP_L_RM_L_SFT 6 -#define RT3261_M_IN_L_RM_L (0x1 << 5) -#define RT3261_M_IN_L_RM_L_SFT 5 -#define RT3261_M_BST4_RM_L (0x1 << 4) -#define RT3261_M_BST4_RM_L_SFT 4 -#define RT3261_M_BST3_RM_L (0x1 << 3) -#define RT3261_M_BST3_RM_L_SFT 3 -#define RT3261_M_BST2_RM_L (0x1 << 2) -#define RT3261_M_BST2_RM_L_SFT 2 -#define RT3261_M_BST1_RM_L (0x1 << 1) -#define RT3261_M_BST1_RM_L_SFT 1 -#define RT3261_M_OM_L_RM_L (0x1) -#define RT3261_M_OM_L_RM_L_SFT 0 - -/* REC Right Mixer Control 1 (0x3d) */ -#define RT3261_G_HP_R_RM_R_MASK (0x7 << 13) -#define RT3261_G_HP_R_RM_R_SFT 13 -#define RT3261_G_IN_R_RM_R_MASK (0x7 << 10) -#define RT3261_G_IN_R_RM_R_SFT 10 -#define RT3261_G_BST4_RM_R_MASK (0x7 << 7) -#define RT3261_G_BST4_RM_R_SFT 7 -#define RT3261_G_BST3_RM_R_MASK (0x7 << 4) -#define RT3261_G_BST3_RM_R_SFT 4 -#define RT3261_G_BST2_RM_R_MASK (0x7 << 1) -#define RT3261_G_BST2_RM_R_SFT 1 - -/* REC Right Mixer Control 2 (0x3e) */ -#define RT3261_G_BST1_RM_R_MASK (0x7 << 13) -#define RT3261_G_BST1_RM_R_SFT 13 -#define RT3261_G_OM_R_RM_R_MASK (0x7 << 10) -#define RT3261_G_OM_R_RM_R_SFT 10 -#define RT3261_M_HP_R_RM_R (0x1 << 6) -#define RT3261_M_HP_R_RM_R_SFT 6 -#define RT3261_M_IN_R_RM_R (0x1 << 5) -#define RT3261_M_IN_R_RM_R_SFT 5 -#define RT3261_M_BST4_RM_R (0x1 << 4) -#define RT3261_M_BST4_RM_R_SFT 4 -#define RT3261_M_BST3_RM_R (0x1 << 3) -#define RT3261_M_BST3_RM_R_SFT 3 -#define RT3261_M_BST2_RM_R (0x1 << 2) -#define RT3261_M_BST2_RM_R_SFT 2 -#define RT3261_M_BST1_RM_R (0x1 << 1) -#define RT3261_M_BST1_RM_R_SFT 1 -#define RT3261_M_OM_R_RM_R (0x1) -#define RT3261_M_OM_R_RM_R_SFT 0 - -/* HPMIX Control (0x45) */ -#define RT3261_M_DAC2_HM (0x1 << 15) -#define RT3261_M_DAC2_HM_SFT 15 -#define RT3261_M_DAC1_HM (0x1 << 14) -#define RT3261_M_DAC1_HM_SFT 14 -#define RT3261_M_HPVOL_HM (0x1 << 13) -#define RT3261_M_HPVOL_HM_SFT 13 -#define RT3261_G_HPOMIX_MASK (0x1 << 12) -#define RT3261_G_HPOMIX_SFT 12 - -/* SPK Left Mixer Control (0x46) */ -#define RT3261_G_RM_L_SM_L_MASK (0x3 << 14) -#define RT3261_G_RM_L_SM_L_SFT 14 -#define RT3261_G_IN_L_SM_L_MASK (0x3 << 12) -#define RT3261_G_IN_L_SM_L_SFT 12 -#define RT3261_G_DAC_L1_SM_L_MASK (0x3 << 10) -#define RT3261_G_DAC_L1_SM_L_SFT 10 -#define RT3261_G_DAC_L2_SM_L_MASK (0x3 << 8) -#define RT3261_G_DAC_L2_SM_L_SFT 8 -#define RT3261_G_OM_L_SM_L_MASK (0x3 << 6) -#define RT3261_G_OM_L_SM_L_SFT 6 -#define RT3261_M_RM_L_SM_L (0x1 << 5) -#define RT3261_M_RM_L_SM_L_SFT 5 -#define RT3261_M_IN_L_SM_L (0x1 << 4) -#define RT3261_M_IN_L_SM_L_SFT 4 -#define RT3261_M_DAC_L1_SM_L (0x1 << 3) -#define RT3261_M_DAC_L1_SM_L_SFT 3 -#define RT3261_M_DAC_L2_SM_L (0x1 << 2) -#define RT3261_M_DAC_L2_SM_L_SFT 2 -#define RT3261_M_OM_L_SM_L (0x1 << 1) -#define RT3261_M_OM_L_SM_L_SFT 1 - -/* SPK Right Mixer Control (0x47) */ -#define RT3261_G_RM_R_SM_R_MASK (0x3 << 14) -#define RT3261_G_RM_R_SM_R_SFT 14 -#define RT3261_G_IN_R_SM_R_MASK (0x3 << 12) -#define RT3261_G_IN_R_SM_R_SFT 12 -#define RT3261_G_DAC_R1_SM_R_MASK (0x3 << 10) -#define RT3261_G_DAC_R1_SM_R_SFT 10 -#define RT3261_G_DAC_R2_SM_R_MASK (0x3 << 8) -#define RT3261_G_DAC_R2_SM_R_SFT 8 -#define RT3261_G_OM_R_SM_R_MASK (0x3 << 6) -#define RT3261_G_OM_R_SM_R_SFT 6 -#define RT3261_M_RM_R_SM_R (0x1 << 5) -#define RT3261_M_RM_R_SM_R_SFT 5 -#define RT3261_M_IN_R_SM_R (0x1 << 4) -#define RT3261_M_IN_R_SM_R_SFT 4 -#define RT3261_M_DAC_R1_SM_R (0x1 << 3) -#define RT3261_M_DAC_R1_SM_R_SFT 3 -#define RT3261_M_DAC_R2_SM_R (0x1 << 2) -#define RT3261_M_DAC_R2_SM_R_SFT 2 -#define RT3261_M_OM_R_SM_R (0x1 << 1) -#define RT3261_M_OM_R_SM_R_SFT 1 - -/* SPOLMIX Control (0x48) */ -#define RT3261_M_DAC_R1_SPM_L (0x1 << 15) -#define RT3261_M_DAC_R1_SPM_L_SFT 15 -#define RT3261_M_DAC_L1_SPM_L (0x1 << 14) -#define RT3261_M_DAC_L1_SPM_L_SFT 14 -#define RT3261_M_SV_R_SPM_L (0x1 << 13) -#define RT3261_M_SV_R_SPM_L_SFT 13 -#define RT3261_M_SV_L_SPM_L (0x1 << 12) -#define RT3261_M_SV_L_SPM_L_SFT 12 -#define RT3261_M_BST1_SPM_L (0x1 << 11) -#define RT3261_M_BST1_SPM_L_SFT 11 - -/* SPORMIX Control (0x49) */ -#define RT3261_M_DAC_R1_SPM_R (0x1 << 13) -#define RT3261_M_DAC_R1_SPM_R_SFT 13 -#define RT3261_M_SV_R_SPM_R (0x1 << 12) -#define RT3261_M_SV_R_SPM_R_SFT 12 -#define RT3261_M_BST1_SPM_R (0x1 << 11) -#define RT3261_M_BST1_SPM_R_SFT 11 - -/* SPOLMIX / SPORMIX Ratio Control (0x4a) */ -#define RT3261_SPO_CLSD_RATIO_MASK (0x7) -#define RT3261_SPO_CLSD_RATIO_SFT 0 - -/* Mono Output Mixer Control (0x4c) */ -#define RT3261_M_DAC_R2_MM (0x1 << 15) -#define RT3261_M_DAC_R2_MM_SFT 15 -#define RT3261_M_DAC_L2_MM (0x1 << 14) -#define RT3261_M_DAC_L2_MM_SFT 14 -#define RT3261_M_OV_R_MM (0x1 << 13) -#define RT3261_M_OV_R_MM_SFT 13 -#define RT3261_M_OV_L_MM (0x1 << 12) -#define RT3261_M_OV_L_MM_SFT 12 -#define RT3261_M_BST1_MM (0x1 << 11) -#define RT3261_M_BST1_MM_SFT 11 -#define RT3261_G_MONOMIX_MASK (0x1 << 10) -#define RT3261_G_MONOMIX_SFT 10 - -/* Output Left Mixer Control 1 (0x4d) */ -#define RT3261_G_BST3_OM_L_MASK (0x7 << 13) -#define RT3261_G_BST3_OM_L_SFT 13 -#define RT3261_G_BST2_OM_L_MASK (0x7 << 10) -#define RT3261_G_BST2_OM_L_SFT 10 -#define RT3261_G_BST1_OM_L_MASK (0x7 << 7) -#define RT3261_G_BST1_OM_L_SFT 7 -#define RT3261_G_IN_L_OM_L_MASK (0x7 << 4) -#define RT3261_G_IN_L_OM_L_SFT 4 -#define RT3261_G_RM_L_OM_L_MASK (0x7 << 1) -#define RT3261_G_RM_L_OM_L_SFT 1 - -/* Output Left Mixer Control 2 (0x4e) */ -#define RT3261_G_DAC_R2_OM_L_MASK (0x7 << 13) -#define RT3261_G_DAC_R2_OM_L_SFT 13 -#define RT3261_G_DAC_L2_OM_L_MASK (0x7 << 10) -#define RT3261_G_DAC_L2_OM_L_SFT 10 -#define RT3261_G_DAC_L1_OM_L_MASK (0x7 << 7) -#define RT3261_G_DAC_L1_OM_L_SFT 7 - -/* Output Left Mixer Control 3 (0x4f) */ -#define RT3261_M_SM_L_OM_L (0x1 << 8) -#define RT3261_M_SM_L_OM_L_SFT 8 -#define RT3261_M_BST3_OM_L (0x1 << 7) -#define RT3261_M_BST3_OM_L_SFT 7 -#define RT3261_M_BST2_OM_L (0x1 << 6) -#define RT3261_M_BST2_OM_L_SFT 6 -#define RT3261_M_BST1_OM_L (0x1 << 5) -#define RT3261_M_BST1_OM_L_SFT 5 -#define RT3261_M_IN_L_OM_L (0x1 << 4) -#define RT3261_M_IN_L_OM_L_SFT 4 -#define RT3261_M_RM_L_OM_L (0x1 << 3) -#define RT3261_M_RM_L_OM_L_SFT 3 -#define RT3261_M_DAC_R2_OM_L (0x1 << 2) -#define RT3261_M_DAC_R2_OM_L_SFT 2 -#define RT3261_M_DAC_L2_OM_L (0x1 << 1) -#define RT3261_M_DAC_L2_OM_L_SFT 1 -#define RT3261_M_DAC_L1_OM_L (0x1) -#define RT3261_M_DAC_L1_OM_L_SFT 0 - -/* Output Right Mixer Control 1 (0x50) */ -#define RT3261_G_BST4_OM_R_MASK (0x7 << 13) -#define RT3261_G_BST4_OM_R_SFT 13 -#define RT3261_G_BST2_OM_R_MASK (0x7 << 10) -#define RT3261_G_BST2_OM_R_SFT 10 -#define RT3261_G_BST1_OM_R_MASK (0x7 << 7) -#define RT3261_G_BST1_OM_R_SFT 7 -#define RT3261_G_IN_R_OM_R_MASK (0x7 << 4) -#define RT3261_G_IN_R_OM_R_SFT 4 -#define RT3261_G_RM_R_OM_R_MASK (0x7 << 1) -#define RT3261_G_RM_R_OM_R_SFT 1 - -/* Output Right Mixer Control 2 (0x51) */ -#define RT3261_G_DAC_L2_OM_R_MASK (0x7 << 13) -#define RT3261_G_DAC_L2_OM_R_SFT 13 -#define RT3261_G_DAC_R2_OM_R_MASK (0x7 << 10) -#define RT3261_G_DAC_R2_OM_R_SFT 10 -#define RT3261_G_DAC_R1_OM_R_MASK (0x7 << 7) -#define RT3261_G_DAC_R1_OM_R_SFT 7 - -/* Output Right Mixer Control 3 (0x52) */ -#define RT3261_M_SM_L_OM_R (0x1 << 8) -#define RT3261_M_SM_L_OM_R_SFT 8 -#define RT3261_M_BST4_OM_R (0x1 << 7) -#define RT3261_M_BST4_OM_R_SFT 7 -#define RT3261_M_BST2_OM_R (0x1 << 6) -#define RT3261_M_BST2_OM_R_SFT 6 -#define RT3261_M_BST1_OM_R (0x1 << 5) -#define RT3261_M_BST1_OM_R_SFT 5 -#define RT3261_M_IN_R_OM_R (0x1 << 4) -#define RT3261_M_IN_R_OM_R_SFT 4 -#define RT3261_M_RM_R_OM_R (0x1 << 3) -#define RT3261_M_RM_R_OM_R_SFT 3 -#define RT3261_M_DAC_L2_OM_R (0x1 << 2) -#define RT3261_M_DAC_L2_OM_R_SFT 2 -#define RT3261_M_DAC_R2_OM_R (0x1 << 1) -#define RT3261_M_DAC_R2_OM_R_SFT 1 -#define RT3261_M_DAC_R1_OM_R (0x1) -#define RT3261_M_DAC_R1_OM_R_SFT 0 - -/* LOUT Mixer Control (0x53) */ -#define RT3261_M_DAC_L1_LM (0x1 << 15) -#define RT3261_M_DAC_L1_LM_SFT 15 -#define RT3261_M_DAC_R1_LM (0x1 << 14) -#define RT3261_M_DAC_R1_LM_SFT 14 -#define RT3261_M_OV_L_LM (0x1 << 13) -#define RT3261_M_OV_L_LM_SFT 13 -#define RT3261_M_OV_R_LM (0x1 << 12) -#define RT3261_M_OV_R_LM_SFT 12 -#define RT3261_G_LOUTMIX_MASK (0x1 << 11) -#define RT3261_G_LOUTMIX_SFT 11 - -/* Power Management for Digital 1 (0x61) */ -#define RT3261_PWR_I2S1 (0x1 << 15) -#define RT3261_PWR_I2S1_BIT 15 -#define RT3261_PWR_I2S2 (0x1 << 14) -#define RT3261_PWR_I2S2_BIT 14 -#define RT3261_PWR_I2S3 (0x1 << 13) -#define RT3261_PWR_I2S3_BIT 13 -#define RT3261_PWR_DAC_L1 (0x1 << 12) -#define RT3261_PWR_DAC_L1_BIT 12 -#define RT3261_PWR_DAC_R1 (0x1 << 11) -#define RT3261_PWR_DAC_R1_BIT 11 -#define RT3261_PWR_DAC_L2 (0x1 << 7) -#define RT3261_PWR_DAC_L2_BIT 7 -#define RT3261_PWR_DAC_R2 (0x1 << 6) -#define RT3261_PWR_DAC_R2_BIT 6 -#define RT3261_PWR_ADC_L (0x1 << 2) -#define RT3261_PWR_ADC_L_BIT 2 -#define RT3261_PWR_ADC_R (0x1 << 1) -#define RT3261_PWR_ADC_R_BIT 1 -#define RT3261_PWR_CLS_D (0x1) -#define RT3261_PWR_CLS_D_BIT 0 - -/* Power Management for Digital 2 (0x62) */ -#define RT3261_PWR_ADC_SF (0x1 << 15) -#define RT3261_PWR_ADC_SF_BIT 15 -#define RT3261_PWR_ADC_MF_L (0x1 << 14) -#define RT3261_PWR_ADC_MF_L_BIT 14 -#define RT3261_PWR_ADC_MF_R (0x1 << 13) -#define RT3261_PWR_ADC_MF_R_BIT 13 -#define RT3261_PWR_I2S_DSP (0x1 << 12) -#define RT3261_PWR_I2S_DSP_BIT 12 - -/* Power Management for Analog 1 (0x63) */ -#define RT3261_PWR_VREF1 (0x1 << 15) -#define RT3261_PWR_VREF1_BIT 15 -#define RT3261_PWR_FV1 (0x1 << 14) -#define RT3261_PWR_FV1_BIT 14 -#define RT3261_PWR_MB (0x1 << 13) -#define RT3261_PWR_MB_BIT 13 -#define RT3261_PWR_LM (0x1 << 12) -#define RT3261_PWR_LM_BIT 12 -#define RT3261_PWR_BG (0x1 << 11) -#define RT3261_PWR_BG_BIT 11 -#define RT3261_PWR_MM (0x1 << 10) -#define RT3261_PWR_MM_BIT 10 -#define RT3261_PWR_MA (0x1 << 8) -#define RT3261_PWR_MA_BIT 8 -#define RT3261_PWR_HP_L (0x1 << 7) -#define RT3261_PWR_HP_L_BIT 7 -#define RT3261_PWR_HP_R (0x1 << 6) -#define RT3261_PWR_HP_R_BIT 6 -#define RT3261_PWR_HA (0x1 << 5) -#define RT3261_PWR_HA_BIT 5 -#define RT3261_PWR_VREF2 (0x1 << 4) -#define RT3261_PWR_VREF2_BIT 4 -#define RT3261_PWR_FV2 (0x1 << 3) -#define RT3261_PWR_FV2_BIT 3 -#define RT3261_PWR_LDO2 (0x1 << 2) -#define RT3261_PWR_LDO2_BIT 2 - -/* Power Management for Analog 2 (0x64) */ -#define RT3261_PWR_BST1 (0x1 << 15) -#define RT3261_PWR_BST1_BIT 15 -#define RT3261_PWR_BST2 (0x1 << 14) -#define RT3261_PWR_BST2_BIT 14 -#define RT3261_PWR_BST3 (0x1 << 13) -#define RT3261_PWR_BST3_BIT 13 -#define RT3261_PWR_BST4 (0x1 << 12) -#define RT3261_PWR_BST4_BIT 12 -#define RT3261_PWR_MB1 (0x1 << 11) -#define RT3261_PWR_MB1_BIT 11 -#define RT3261_PWR_MB2 (0x1 << 10) -#define RT3261_PWR_MB2_BIT 10 -#define RT3261_PWR_PLL (0x1 << 9) -#define RT3261_PWR_PLL_BIT 9 - -/* Power Management for Mixer (0x65) */ -#define RT3261_PWR_OM_L (0x1 << 15) -#define RT3261_PWR_OM_L_BIT 15 -#define RT3261_PWR_OM_R (0x1 << 14) -#define RT3261_PWR_OM_R_BIT 14 -#define RT3261_PWR_SM_L (0x1 << 13) -#define RT3261_PWR_SM_L_BIT 13 -#define RT3261_PWR_SM_R (0x1 << 12) -#define RT3261_PWR_SM_R_BIT 12 -#define RT3261_PWR_RM_L (0x1 << 11) -#define RT3261_PWR_RM_L_BIT 11 -#define RT3261_PWR_RM_R (0x1 << 10) -#define RT3261_PWR_RM_R_BIT 10 - -/* Power Management for Volume (0x66) */ -#define RT3261_PWR_SV_L (0x1 << 15) -#define RT3261_PWR_SV_L_BIT 15 -#define RT3261_PWR_SV_R (0x1 << 14) -#define RT3261_PWR_SV_R_BIT 14 -#define RT3261_PWR_OV_L (0x1 << 13) -#define RT3261_PWR_OV_L_BIT 13 -#define RT3261_PWR_OV_R (0x1 << 12) -#define RT3261_PWR_OV_R_BIT 12 -#define RT3261_PWR_HV_L (0x1 << 11) -#define RT3261_PWR_HV_L_BIT 11 -#define RT3261_PWR_HV_R (0x1 << 10) -#define RT3261_PWR_HV_R_BIT 10 -#define RT3261_PWR_IN_L (0x1 << 9) -#define RT3261_PWR_IN_L_BIT 9 -#define RT3261_PWR_IN_R (0x1 << 8) -#define RT3261_PWR_IN_R_BIT 8 - -/* I2S1/2/3 Audio Serial Data Port Control (0x70 0x71 0x72) */ -#define RT3261_I2S_MS_MASK (0x1 << 15) -#define RT3261_I2S_MS_SFT 15 -#define RT3261_I2S_MS_M (0x0 << 15) -#define RT3261_I2S_MS_S (0x1 << 15) -#define RT3261_I2S_IF_MASK (0x7 << 12) -#define RT3261_I2S_IF_SFT 12 -#define RT3261_I2S_O_CP_MASK (0x3 << 10) -#define RT3261_I2S_O_CP_SFT 10 -#define RT3261_I2S_O_CP_OFF (0x0 << 10) -#define RT3261_I2S_O_CP_U_LAW (0x1 << 10) -#define RT3261_I2S_O_CP_A_LAW (0x2 << 10) -#define RT3261_I2S_I_CP_MASK (0x3 << 8) -#define RT3261_I2S_I_CP_SFT 8 -#define RT3261_I2S_I_CP_OFF (0x0 << 8) -#define RT3261_I2S_I_CP_U_LAW (0x1 << 8) -#define RT3261_I2S_I_CP_A_LAW (0x2 << 8) -#define RT3261_I2S_BP_MASK (0x1 << 7) -#define RT3261_I2S_BP_SFT 7 -#define RT3261_I2S_BP_NOR (0x0 << 7) -#define RT3261_I2S_BP_INV (0x1 << 7) -#define RT3261_I2S_DL_MASK (0x3 << 2) -#define RT3261_I2S_DL_SFT 2 -#define RT3261_I2S_DL_16 (0x0 << 2) -#define RT3261_I2S_DL_20 (0x1 << 2) -#define RT3261_I2S_DL_24 (0x2 << 2) -#define RT3261_I2S_DL_8 (0x3 << 2) -#define RT3261_I2S_DF_MASK (0x3) -#define RT3261_I2S_DF_SFT 0 -#define RT3261_I2S_DF_I2S (0x0) -#define RT3261_I2S_DF_LEFT (0x1) -#define RT3261_I2S_DF_PCM_A (0x2) -#define RT3261_I2S_DF_PCM_B (0x3) - -/* I2S2 Audio Serial Data Port Control (0x71) */ -#define RT3261_I2S2_SDI_MASK (0x1 << 6) -#define RT3261_I2S2_SDI_SFT 6 -#define RT3261_I2S2_SDI_I2S1 (0x0 << 6) -#define RT3261_I2S2_SDI_I2S2 (0x1 << 6) - -/* ADC/DAC Clock Control 1 (0x73) */ -#define RT3261_I2S_BCLK_MS1_MASK (0x1 << 15) -#define RT3261_I2S_BCLK_MS1_SFT 15 -#define RT3261_I2S_BCLK_MS1_32 (0x0 << 15) -#define RT3261_I2S_BCLK_MS1_64 (0x1 << 15) -#define RT3261_I2S_PD1_MASK (0x7 << 12) -#define RT3261_I2S_PD1_SFT 12 -#define RT3261_I2S_PD1_1 (0x0 << 12) -#define RT3261_I2S_PD1_2 (0x1 << 12) -#define RT3261_I2S_PD1_3 (0x2 << 12) -#define RT3261_I2S_PD1_4 (0x3 << 12) -#define RT3261_I2S_PD1_6 (0x4 << 12) -#define RT3261_I2S_PD1_8 (0x5 << 12) -#define RT3261_I2S_PD1_12 (0x6 << 12) -#define RT3261_I2S_PD1_16 (0x7 << 12) -#define RT3261_I2S_BCLK_MS2_MASK (0x1 << 11) -#define RT3261_I2S_BCLK_MS2_SFT 11 -#define RT3261_I2S_BCLK_MS2_32 (0x0 << 11) -#define RT3261_I2S_BCLK_MS2_64 (0x1 << 11) -#define RT3261_I2S_PD2_MASK (0x7 << 8) -#define RT3261_I2S_PD2_SFT 8 -#define RT3261_I2S_PD2_1 (0x0 << 8) -#define RT3261_I2S_PD2_2 (0x1 << 8) -#define RT3261_I2S_PD2_3 (0x2 << 8) -#define RT3261_I2S_PD2_4 (0x3 << 8) -#define RT3261_I2S_PD2_6 (0x4 << 8) -#define RT3261_I2S_PD2_8 (0x5 << 8) -#define RT3261_I2S_PD2_12 (0x6 << 8) -#define RT3261_I2S_PD2_16 (0x7 << 8) -#define RT3261_I2S_BCLK_MS3_MASK (0x1 << 7) -#define RT3261_I2S_BCLK_MS3_SFT 7 -#define RT3261_I2S_BCLK_MS3_32 (0x0 << 7) -#define RT3261_I2S_BCLK_MS3_64 (0x1 << 7) -#define RT3261_I2S_PD3_MASK (0x7 << 4) -#define RT3261_I2S_PD3_SFT 4 -#define RT3261_I2S_PD3_1 (0x0 << 4) -#define RT3261_I2S_PD3_2 (0x1 << 4) -#define RT3261_I2S_PD3_3 (0x2 << 4) -#define RT3261_I2S_PD3_4 (0x3 << 4) -#define RT3261_I2S_PD3_6 (0x4 << 4) -#define RT3261_I2S_PD3_8 (0x5 << 4) -#define RT3261_I2S_PD3_12 (0x6 << 4) -#define RT3261_I2S_PD3_16 (0x7 << 4) -#define RT3261_DAC_OSR_MASK (0x3 << 2) -#define RT3261_DAC_OSR_SFT 2 -#define RT3261_DAC_OSR_128 (0x0 << 2) -#define RT3261_DAC_OSR_64 (0x1 << 2) -#define RT3261_DAC_OSR_32 (0x2 << 2) -#define RT3261_DAC_OSR_16 (0x3 << 2) -#define RT3261_ADC_OSR_MASK (0x3) -#define RT3261_ADC_OSR_SFT 0 -#define RT3261_ADC_OSR_128 (0x0) -#define RT3261_ADC_OSR_64 (0x1) -#define RT3261_ADC_OSR_32 (0x2) -#define RT3261_ADC_OSR_16 (0x3) - -/* ADC/DAC Clock Control 2 (0x74) */ -#define RT3261_DAC_L_OSR_MASK (0x3 << 14) -#define RT3261_DAC_L_OSR_SFT 14 -#define RT3261_DAC_L_OSR_128 (0x0 << 14) -#define RT3261_DAC_L_OSR_64 (0x1 << 14) -#define RT3261_DAC_L_OSR_32 (0x2 << 14) -#define RT3261_DAC_L_OSR_16 (0x3 << 14) -#define RT3261_ADC_R_OSR_MASK (0x3 << 12) -#define RT3261_ADC_R_OSR_SFT 12 -#define RT3261_ADC_R_OSR_128 (0x0 << 12) -#define RT3261_ADC_R_OSR_64 (0x1 << 12) -#define RT3261_ADC_R_OSR_32 (0x2 << 12) -#define RT3261_ADC_R_OSR_16 (0x3 << 12) -#define RT3261_DAHPF_EN (0x1 << 11) -#define RT3261_DAHPF_EN_SFT 11 -#define RT3261_ADHPF_EN (0x1 << 10) -#define RT3261_ADHPF_EN_SFT 10 - -/* Digital Microphone Control (0x75) */ -#define RT3261_DMIC_1_EN_MASK (0x1 << 15) -#define RT3261_DMIC_1_EN_SFT 15 -#define RT3261_DMIC_1_DIS (0x0 << 15) -#define RT3261_DMIC_1_EN (0x1 << 15) -#define RT3261_DMIC_2_EN_MASK (0x1 << 14) -#define RT3261_DMIC_2_EN_SFT 14 -#define RT3261_DMIC_2_DIS (0x0 << 14) -#define RT3261_DMIC_2_EN (0x1 << 14) -#define RT3261_DMIC_1L_LH_MASK (0x1 << 13) -#define RT3261_DMIC_1L_LH_SFT 13 -#define RT3261_DMIC_1L_LH_FALLING (0x0 << 13) -#define RT3261_DMIC_1L_LH_RISING (0x1 << 13) -#define RT3261_DMIC_1R_LH_MASK (0x1 << 12) -#define RT3261_DMIC_1R_LH_SFT 12 -#define RT3261_DMIC_1R_LH_FALLING (0x0 << 12) -#define RT3261_DMIC_1R_LH_RISING (0x1 << 12) -#define RT3261_DMIC_1_DP_MASK (0x1 << 11) -#define RT3261_DMIC_1_DP_SFT 11 -#define RT3261_DMIC_1_DP_GPIO3 (0x0 << 11) -#define RT3261_DMIC_1_DP_IN1P (0x1 << 11) -#define RT3261_DMIC_2_DP_MASK (0x1 << 10) -#define RT3261_DMIC_2_DP_SFT 10 -#define RT3261_DMIC_2_DP_GPIO4 (0x0 << 10) -#define RT3261_DMIC_2_DP_IN1N (0x1 << 10) -#define RT3261_DMIC_2L_LH_MASK (0x1 << 9) -#define RT3261_DMIC_2L_LH_SFT 9 -#define RT3261_DMIC_2L_LH_FALLING (0x0 << 9) -#define RT3261_DMIC_2L_LH_RISING (0x1 << 9) -#define RT3261_DMIC_2R_LH_MASK (0x1 << 8) -#define RT3261_DMIC_2R_LH_SFT 8 -#define RT3261_DMIC_2R_LH_FALLING (0x0 << 8) -#define RT3261_DMIC_2R_LH_RISING (0x1 << 8) -#define RT3261_DMIC_CLK_MASK (0x7 << 5) -#define RT3261_DMIC_CLK_SFT 5 - -/* Global Clock Control (0x80) */ -#define RT3261_SCLK_SRC_MASK (0x3 << 14) -#define RT3261_SCLK_SRC_SFT 14 -#define RT3261_SCLK_SRC_MCLK (0x0 << 14) -#define RT3261_SCLK_SRC_PLL1 (0x1 << 14) -#define RT3261_SCLK_SRC_RCCLK (0x2 << 14) /* 15MHz */ -#define RT3261_PLL1_SRC_MASK (0x3 << 12) -#define RT3261_PLL1_SRC_SFT 12 -#define RT3261_PLL1_SRC_MCLK (0x0 << 12) -#define RT3261_PLL1_SRC_BCLK1 (0x1 << 12) -#define RT3261_PLL1_SRC_BCLK2 (0x2 << 12) -#define RT3261_PLL1_SRC_BCLK3 (0x3 << 12) -#define RT3261_PLL1_PD_MASK (0x1 << 3) -#define RT3261_PLL1_PD_SFT 3 -#define RT3261_PLL1_PD_1 (0x0 << 3) -#define RT3261_PLL1_PD_2 (0x1 << 3) - -#define RT3261_PLL_INP_MAX 40000000 -#define RT3261_PLL_INP_MIN 256000 -/* PLL M/N/K Code Control 1 (0x81) */ -#define RT3261_PLL_N_MAX 0x1ff -#define RT3261_PLL_N_MASK (RT3261_PLL_N_MAX << 7) -#define RT3261_PLL_N_SFT 7 -#define RT3261_PLL_K_MAX 0x1f -#define RT3261_PLL_K_MASK (RT3261_PLL_K_MAX) -#define RT3261_PLL_K_SFT 0 - -/* PLL M/N/K Code Control 2 (0x82) */ -#define RT3261_PLL_M_MAX 0xf -#define RT3261_PLL_M_MASK (RT3261_PLL_M_MAX << 12) -#define RT3261_PLL_M_SFT 12 -#define RT3261_PLL_M_BP (0x1 << 11) -#define RT3261_PLL_M_BP_SFT 11 - -/* ASRC Control 1 (0x83) */ -#define RT3261_STO_T_MASK (0x1 << 15) -#define RT3261_STO_T_SFT 15 -#define RT3261_STO_T_SCLK (0x0 << 15) -#define RT3261_STO_T_LRCK1 (0x1 << 15) -#define RT3261_M1_T_MASK (0x1 << 14) -#define RT3261_M1_T_SFT 14 -#define RT3261_M1_T_I2S2 (0x0 << 14) -#define RT3261_M1_T_I2S2_D3 (0x1 << 14) -#define RT3261_I2S2_F_MASK (0x1 << 12) -#define RT3261_I2S2_F_SFT 12 -#define RT3261_I2S2_F_I2S2_D2 (0x0 << 12) -#define RT3261_I2S2_F_I2S1_TCLK (0x1 << 12) -#define RT3261_DMIC_1_M_MASK (0x1 << 9) -#define RT3261_DMIC_1_M_SFT 9 -#define RT3261_DMIC_1_M_NOR (0x0 << 9) -#define RT3261_DMIC_1_M_ASYN (0x1 << 9) -#define RT3261_DMIC_2_M_MASK (0x1 << 8) -#define RT3261_DMIC_2_M_SFT 8 -#define RT3261_DMIC_2_M_NOR (0x0 << 8) -#define RT3261_DMIC_2_M_ASYN (0x1 << 8) - -/* ASRC Control 2 (0x84) */ -#define RT3261_MDA_L_M_MASK (0x1 << 15) -#define RT3261_MDA_L_M_SFT 15 -#define RT3261_MDA_L_M_NOR (0x0 << 15) -#define RT3261_MDA_L_M_ASYN (0x1 << 15) -#define RT3261_MDA_R_M_MASK (0x1 << 14) -#define RT3261_MDA_R_M_SFT 14 -#define RT3261_MDA_R_M_NOR (0x0 << 14) -#define RT3261_MDA_R_M_ASYN (0x1 << 14) -#define RT3261_MAD_L_M_MASK (0x1 << 13) -#define RT3261_MAD_L_M_SFT 13 -#define RT3261_MAD_L_M_NOR (0x0 << 13) -#define RT3261_MAD_L_M_ASYN (0x1 << 13) -#define RT3261_MAD_R_M_MASK (0x1 << 12) -#define RT3261_MAD_R_M_SFT 12 -#define RT3261_MAD_R_M_NOR (0x0 << 12) -#define RT3261_MAD_R_M_ASYN (0x1 << 12) -#define RT3261_ADC_M_MASK (0x1 << 11) -#define RT3261_ADC_M_SFT 11 -#define RT3261_ADC_M_NOR (0x0 << 11) -#define RT3261_ADC_M_ASYN (0x1 << 11) -#define RT3261_STO_DAC_M_MASK (0x1 << 5) -#define RT3261_STO_DAC_M_SFT 5 -#define RT3261_STO_DAC_M_NOR (0x0 << 5) -#define RT3261_STO_DAC_M_ASYN (0x1 << 5) -#define RT3261_I2S1_R_D_MASK (0x1 << 4) -#define RT3261_I2S1_R_D_SFT 4 -#define RT3261_I2S1_R_D_DIS (0x0 << 4) -#define RT3261_I2S1_R_D_EN (0x1 << 4) -#define RT3261_I2S2_R_D_MASK (0x1 << 3) -#define RT3261_I2S2_R_D_SFT 3 -#define RT3261_I2S2_R_D_DIS (0x0 << 3) -#define RT3261_I2S2_R_D_EN (0x1 << 3) -#define RT3261_PRE_SCLK_MASK (0x3) -#define RT3261_PRE_SCLK_SFT 0 -#define RT3261_PRE_SCLK_512 (0x0) -#define RT3261_PRE_SCLK_1024 (0x1) -#define RT3261_PRE_SCLK_2048 (0x2) - -/* ASRC Control 3 (0x85) */ -#define RT3261_I2S1_RATE_MASK (0xf << 12) -#define RT3261_I2S1_RATE_SFT 12 -#define RT3261_I2S2_RATE_MASK (0xf << 8) -#define RT3261_I2S2_RATE_SFT 8 - -/* ASRC Control 4 (0x89) */ -#define RT3261_I2S1_PD_MASK (0x7 << 12) -#define RT3261_I2S1_PD_SFT 12 -#define RT3261_I2S2_PD_MASK (0x7 << 8) -#define RT3261_I2S2_PD_SFT 8 - -/* HPOUT Over Current Detection (0x8b) */ -#define RT3261_HP_OVCD_MASK (0x1 << 10) -#define RT3261_HP_OVCD_SFT 10 -#define RT3261_HP_OVCD_DIS (0x0 << 10) -#define RT3261_HP_OVCD_EN (0x1 << 10) -#define RT3261_HP_OC_TH_MASK (0x3 << 8) -#define RT3261_HP_OC_TH_SFT 8 -#define RT3261_HP_OC_TH_90 (0x0 << 8) -#define RT3261_HP_OC_TH_105 (0x1 << 8) -#define RT3261_HP_OC_TH_120 (0x2 << 8) -#define RT3261_HP_OC_TH_135 (0x3 << 8) - -/* Class D Over Current Control (0x8c) */ -#define RT3261_CLSD_OC_MASK (0x1 << 9) -#define RT3261_CLSD_OC_SFT 9 -#define RT3261_CLSD_OC_PU (0x0 << 9) -#define RT3261_CLSD_OC_PD (0x1 << 9) -#define RT3261_AUTO_PD_MASK (0x1 << 8) -#define RT3261_AUTO_PD_SFT 8 -#define RT3261_AUTO_PD_DIS (0x0 << 8) -#define RT3261_AUTO_PD_EN (0x1 << 8) -#define RT3261_CLSD_OC_TH_MASK (0x3f) -#define RT3261_CLSD_OC_TH_SFT 0 - -/* Class D Output Control (0x8d) */ -#define RT3261_CLSD_RATIO_MASK (0xf << 12) -#define RT3261_CLSD_RATIO_SFT 12 -#define RT3261_CLSD_OM_MASK (0x1 << 11) -#define RT3261_CLSD_OM_SFT 11 -#define RT3261_CLSD_OM_MONO (0x0 << 11) -#define RT3261_CLSD_OM_STO (0x1 << 11) -#define RT3261_CLSD_SCH_MASK (0x1 << 10) -#define RT3261_CLSD_SCH_SFT 10 -#define RT3261_CLSD_SCH_L (0x0 << 10) -#define RT3261_CLSD_SCH_S (0x1 << 10) - -/* Depop Mode Control 1 (0x8e) */ -#define RT3261_SMT_TRIG_MASK (0x1 << 15) -#define RT3261_SMT_TRIG_SFT 15 -#define RT3261_SMT_TRIG_DIS (0x0 << 15) -#define RT3261_SMT_TRIG_EN (0x1 << 15) -#define RT3261_HP_L_SMT_MASK (0x1 << 9) -#define RT3261_HP_L_SMT_SFT 9 -#define RT3261_HP_L_SMT_DIS (0x0 << 9) -#define RT3261_HP_L_SMT_EN (0x1 << 9) -#define RT3261_HP_R_SMT_MASK (0x1 << 8) -#define RT3261_HP_R_SMT_SFT 8 -#define RT3261_HP_R_SMT_DIS (0x0 << 8) -#define RT3261_HP_R_SMT_EN (0x1 << 8) -#define RT3261_HP_CD_PD_MASK (0x1 << 7) -#define RT3261_HP_CD_PD_SFT 7 -#define RT3261_HP_CD_PD_DIS (0x0 << 7) -#define RT3261_HP_CD_PD_EN (0x1 << 7) -#define RT3261_RSTN_MASK (0x1 << 6) -#define RT3261_RSTN_SFT 6 -#define RT3261_RSTN_DIS (0x0 << 6) -#define RT3261_RSTN_EN (0x1 << 6) -#define RT3261_RSTP_MASK (0x1 << 5) -#define RT3261_RSTP_SFT 5 -#define RT3261_RSTP_DIS (0x0 << 5) -#define RT3261_RSTP_EN (0x1 << 5) -#define RT3261_HP_CO_MASK (0x1 << 4) -#define RT3261_HP_CO_SFT 4 -#define RT3261_HP_CO_DIS (0x0 << 4) -#define RT3261_HP_CO_EN (0x1 << 4) -#define RT3261_HP_CP_MASK (0x1 << 3) -#define RT3261_HP_CP_SFT 3 -#define RT3261_HP_CP_PD (0x0 << 3) -#define RT3261_HP_CP_PU (0x1 << 3) -#define RT3261_HP_SG_MASK (0x1 << 2) -#define RT3261_HP_SG_SFT 2 -#define RT3261_HP_SG_DIS (0x0 << 2) -#define RT3261_HP_SG_EN (0x1 << 2) -#define RT3261_HP_DP_MASK (0x1 << 1) -#define RT3261_HP_DP_SFT 1 -#define RT3261_HP_DP_PD (0x0 << 1) -#define RT3261_HP_DP_PU (0x1 << 1) -#define RT3261_HP_CB_MASK (0x1) -#define RT3261_HP_CB_SFT 0 -#define RT3261_HP_CB_PD (0x0) -#define RT3261_HP_CB_PU (0x1) - -/* Depop Mode Control 2 (0x8f) */ -#define RT3261_DEPOP_MASK (0x1 << 13) -#define RT3261_DEPOP_SFT 13 -#define RT3261_DEPOP_AUTO (0x0 << 13) -#define RT3261_DEPOP_MAN (0x1 << 13) -#define RT3261_RAMP_MASK (0x1 << 12) -#define RT3261_RAMP_SFT 12 -#define RT3261_RAMP_DIS (0x0 << 12) -#define RT3261_RAMP_EN (0x1 << 12) -#define RT3261_BPS_MASK (0x1 << 11) -#define RT3261_BPS_SFT 11 -#define RT3261_BPS_DIS (0x0 << 11) -#define RT3261_BPS_EN (0x1 << 11) -#define RT3261_FAST_UPDN_MASK (0x1 << 10) -#define RT3261_FAST_UPDN_SFT 10 -#define RT3261_FAST_UPDN_DIS (0x0 << 10) -#define RT3261_FAST_UPDN_EN (0x1 << 10) -#define RT3261_MRES_MASK (0x3 << 8) -#define RT3261_MRES_SFT 8 -#define RT3261_MRES_15MO (0x0 << 8) -#define RT3261_MRES_25MO (0x1 << 8) -#define RT3261_MRES_35MO (0x2 << 8) -#define RT3261_MRES_45MO (0x3 << 8) -#define RT3261_VLO_MASK (0x1 << 7) -#define RT3261_VLO_SFT 7 -#define RT3261_VLO_3V (0x0 << 7) -#define RT3261_VLO_32V (0x1 << 7) -#define RT3261_DIG_DP_MASK (0x1 << 6) -#define RT3261_DIG_DP_SFT 6 -#define RT3261_DIG_DP_DIS (0x0 << 6) -#define RT3261_DIG_DP_EN (0x1 << 6) -#define RT3261_DP_TH_MASK (0x3 << 4) -#define RT3261_DP_TH_SFT 4 - -/* Depop Mode Control 3 (0x90) */ -#define RT3261_CP_SYS_MASK (0x7 << 12) -#define RT3261_CP_SYS_SFT 12 -#define RT3261_CP_FQ1_MASK (0x7 << 8) -#define RT3261_CP_FQ1_SFT 8 -#define RT3261_CP_FQ2_MASK (0x7 << 4) -#define RT3261_CP_FQ2_SFT 4 -#define RT3261_CP_FQ3_MASK (0x7) -#define RT3261_CP_FQ3_SFT 0 -#define RT3261_CP_FQ_1_5_KHZ 0 -#define RT3261_CP_FQ_3_KHZ 1 -#define RT3261_CP_FQ_6_KHZ 2 -#define RT3261_CP_FQ_12_KHZ 3 -#define RT3261_CP_FQ_24_KHZ 4 -#define RT3261_CP_FQ_48_KHZ 5 -#define RT3261_CP_FQ_96_KHZ 6 -#define RT3261_CP_FQ_192_KHZ 7 - -/* HPOUT charge pump (0x91) */ -#define RT3261_OSW_L_MASK (0x1 << 11) -#define RT3261_OSW_L_SFT 11 -#define RT3261_OSW_L_DIS (0x0 << 11) -#define RT3261_OSW_L_EN (0x1 << 11) -#define RT3261_OSW_R_MASK (0x1 << 10) -#define RT3261_OSW_R_SFT 10 -#define RT3261_OSW_R_DIS (0x0 << 10) -#define RT3261_OSW_R_EN (0x1 << 10) -#define RT3261_PM_HP_MASK (0x3 << 8) -#define RT3261_PM_HP_SFT 8 -#define RT3261_PM_HP_LV (0x0 << 8) -#define RT3261_PM_HP_MV (0x1 << 8) -#define RT3261_PM_HP_HV (0x2 << 8) -#define RT3261_IB_HP_MASK (0x3 << 6) -#define RT3261_IB_HP_SFT 6 -#define RT3261_IB_HP_125IL (0x0 << 6) -#define RT3261_IB_HP_25IL (0x1 << 6) -#define RT3261_IB_HP_5IL (0x2 << 6) -#define RT3261_IB_HP_1IL (0x3 << 6) - -/* PV detection and SPK gain control (0x92) */ -#define RT3261_PVDD_DET_MASK (0x1 << 15) -#define RT3261_PVDD_DET_SFT 15 -#define RT3261_PVDD_DET_DIS (0x0 << 15) -#define RT3261_PVDD_DET_EN (0x1 << 15) -#define RT3261_SPK_AG_MASK (0x1 << 14) -#define RT3261_SPK_AG_SFT 14 -#define RT3261_SPK_AG_DIS (0x0 << 14) -#define RT3261_SPK_AG_EN (0x1 << 14) - -/* Micbias Control (0x93) */ -#define RT3261_MIC1_BS_MASK (0x1 << 15) -#define RT3261_MIC1_BS_SFT 15 -#define RT3261_MIC1_BS_9AV (0x0 << 15) -#define RT3261_MIC1_BS_75AV (0x1 << 15) -#define RT3261_MIC2_BS_MASK (0x1 << 14) -#define RT3261_MIC2_BS_SFT 14 -#define RT3261_MIC2_BS_9AV (0x0 << 14) -#define RT3261_MIC2_BS_75AV (0x1 << 14) -#define RT3261_MIC1_CLK_MASK (0x1 << 13) -#define RT3261_MIC1_CLK_SFT 13 -#define RT3261_MIC1_CLK_DIS (0x0 << 13) -#define RT3261_MIC1_CLK_EN (0x1 << 13) -#define RT3261_MIC2_CLK_MASK (0x1 << 12) -#define RT3261_MIC2_CLK_SFT 12 -#define RT3261_MIC2_CLK_DIS (0x0 << 12) -#define RT3261_MIC2_CLK_EN (0x1 << 12) -#define RT3261_MIC1_OVCD_MASK (0x1 << 11) -#define RT3261_MIC1_OVCD_SFT 11 -#define RT3261_MIC1_OVCD_DIS (0x0 << 11) -#define RT3261_MIC1_OVCD_EN (0x1 << 11) -#define RT3261_MIC1_OVTH_MASK (0x3 << 9) -#define RT3261_MIC1_OVTH_SFT 9 -#define RT3261_MIC1_OVTH_600UA (0x0 << 9) -#define RT3261_MIC1_OVTH_1500UA (0x1 << 9) -#define RT3261_MIC1_OVTH_2000UA (0x2 << 9) -#define RT3261_MIC2_OVCD_MASK (0x1 << 8) -#define RT3261_MIC2_OVCD_SFT 8 -#define RT3261_MIC2_OVCD_DIS (0x0 << 8) -#define RT3261_MIC2_OVCD_EN (0x1 << 8) -#define RT3261_MIC2_OVTH_MASK (0x3 << 6) -#define RT3261_MIC2_OVTH_SFT 6 -#define RT3261_MIC2_OVTH_600UA (0x0 << 6) -#define RT3261_MIC2_OVTH_1500UA (0x1 << 6) -#define RT3261_MIC2_OVTH_2000UA (0x2 << 6) -#define RT3261_PWR_MB_MASK (0x1 << 5) -#define RT3261_PWR_MB_SFT 5 -#define RT3261_PWR_MB_PD (0x0 << 5) -#define RT3261_PWR_MB_PU (0x1 << 5) -#define RT3261_PWR_CLK25M_MASK (0x1 << 4) -#define RT3261_PWR_CLK25M_SFT 4 -#define RT3261_PWR_CLK25M_PD (0x0 << 4) -#define RT3261_PWR_CLK25M_PU (0x1 << 4) - -/* EQ Control 1 (0xb0) */ -#define RT3261_EQ_SRC_MASK (0x1 << 15) -#define RT3261_EQ_SRC_SFT 15 -#define RT3261_EQ_SRC_DAC (0x0 << 15) -#define RT3261_EQ_SRC_ADC (0x1 << 15) -#define RT3261_EQ_UPD (0x1 << 14) -#define RT3261_EQ_UPD_BIT 14 -#define RT3261_EQ_CD_MASK (0x1 << 13) -#define RT3261_EQ_CD_SFT 13 -#define RT3261_EQ_CD_DIS (0x0 << 13) -#define RT3261_EQ_CD_EN (0x1 << 13) -#define RT3261_EQ_DITH_MASK (0x3 << 8) -#define RT3261_EQ_DITH_SFT 8 -#define RT3261_EQ_DITH_NOR (0x0 << 8) -#define RT3261_EQ_DITH_LSB (0x1 << 8) -#define RT3261_EQ_DITH_LSB_1 (0x2 << 8) -#define RT3261_EQ_DITH_LSB_2 (0x3 << 8) - -/* EQ Control 2 (0xb1) */ -#define RT3261_EQ_HPF1_M_MASK (0x1 << 8) -#define RT3261_EQ_HPF1_M_SFT 8 -#define RT3261_EQ_HPF1_M_HI (0x0 << 8) -#define RT3261_EQ_HPF1_M_1ST (0x1 << 8) -#define RT3261_EQ_LPF1_M_MASK (0x1 << 7) -#define RT3261_EQ_LPF1_M_SFT 7 -#define RT3261_EQ_LPF1_M_LO (0x0 << 7) -#define RT3261_EQ_LPF1_M_1ST (0x1 << 7) -#define RT3261_EQ_HPF2_MASK (0x1 << 6) -#define RT3261_EQ_HPF2_SFT 6 -#define RT3261_EQ_HPF2_DIS (0x0 << 6) -#define RT3261_EQ_HPF2_EN (0x1 << 6) -#define RT3261_EQ_HPF1_MASK (0x1 << 5) -#define RT3261_EQ_HPF1_SFT 5 -#define RT3261_EQ_HPF1_DIS (0x0 << 5) -#define RT3261_EQ_HPF1_EN (0x1 << 5) -#define RT3261_EQ_BPF4_MASK (0x1 << 4) -#define RT3261_EQ_BPF4_SFT 4 -#define RT3261_EQ_BPF4_DIS (0x0 << 4) -#define RT3261_EQ_BPF4_EN (0x1 << 4) -#define RT3261_EQ_BPF3_MASK (0x1 << 3) -#define RT3261_EQ_BPF3_SFT 3 -#define RT3261_EQ_BPF3_DIS (0x0 << 3) -#define RT3261_EQ_BPF3_EN (0x1 << 3) -#define RT3261_EQ_BPF2_MASK (0x1 << 2) -#define RT3261_EQ_BPF2_SFT 2 -#define RT3261_EQ_BPF2_DIS (0x0 << 2) -#define RT3261_EQ_BPF2_EN (0x1 << 2) -#define RT3261_EQ_BPF1_MASK (0x1 << 1) -#define RT3261_EQ_BPF1_SFT 1 -#define RT3261_EQ_BPF1_DIS (0x0 << 1) -#define RT3261_EQ_BPF1_EN (0x1 << 1) -#define RT3261_EQ_LPF_MASK (0x1) -#define RT3261_EQ_LPF_SFT 0 -#define RT3261_EQ_LPF_DIS (0x0) -#define RT3261_EQ_LPF_EN (0x1) -#define RT3261_EQ_CTRL_MASK (0x7f) - -/* Memory Test (0xb2) */ -#define RT3261_MT_MASK (0x1 << 15) -#define RT3261_MT_SFT 15 -#define RT3261_MT_DIS (0x0 << 15) -#define RT3261_MT_EN (0x1 << 15) - -/* DRC/AGC Control 1 (0xb4) */ -#define RT3261_DRC_AGC_P_MASK (0x1 << 15) -#define RT3261_DRC_AGC_P_SFT 15 -#define RT3261_DRC_AGC_P_DAC (0x0 << 15) -#define RT3261_DRC_AGC_P_ADC (0x1 << 15) -#define RT3261_DRC_AGC_MASK (0x1 << 14) -#define RT3261_DRC_AGC_SFT 14 -#define RT3261_DRC_AGC_DIS (0x0 << 14) -#define RT3261_DRC_AGC_EN (0x1 << 14) -#define RT3261_DRC_AGC_UPD (0x1 << 13) -#define RT3261_DRC_AGC_UPD_BIT 13 -#define RT3261_DRC_AGC_AR_MASK (0x1f << 8) -#define RT3261_DRC_AGC_AR_SFT 8 -#define RT3261_DRC_AGC_R_MASK (0x7 << 5) -#define RT3261_DRC_AGC_R_SFT 5 -#define RT3261_DRC_AGC_R_48K (0x1 << 5) -#define RT3261_DRC_AGC_R_96K (0x2 << 5) -#define RT3261_DRC_AGC_R_192K (0x3 << 5) -#define RT3261_DRC_AGC_R_441K (0x5 << 5) -#define RT3261_DRC_AGC_R_882K (0x6 << 5) -#define RT3261_DRC_AGC_R_1764K (0x7 << 5) -#define RT3261_DRC_AGC_RC_MASK (0x1f) -#define RT3261_DRC_AGC_RC_SFT 0 - -/* DRC/AGC Control 2 (0xb5) */ -#define RT3261_DRC_AGC_POB_MASK (0x3f << 8) -#define RT3261_DRC_AGC_POB_SFT 8 -#define RT3261_DRC_AGC_CP_MASK (0x1 << 7) -#define RT3261_DRC_AGC_CP_SFT 7 -#define RT3261_DRC_AGC_CP_DIS (0x0 << 7) -#define RT3261_DRC_AGC_CP_EN (0x1 << 7) -#define RT3261_DRC_AGC_CPR_MASK (0x3 << 5) -#define RT3261_DRC_AGC_CPR_SFT 5 -#define RT3261_DRC_AGC_CPR_1_1 (0x0 << 5) -#define RT3261_DRC_AGC_CPR_1_2 (0x1 << 5) -#define RT3261_DRC_AGC_CPR_1_3 (0x2 << 5) -#define RT3261_DRC_AGC_CPR_1_4 (0x3 << 5) -#define RT3261_DRC_AGC_PRB_MASK (0x1f) -#define RT3261_DRC_AGC_PRB_SFT 0 - -/* DRC/AGC Control 3 (0xb6) */ -#define RT3261_DRC_AGC_NGB_MASK (0xf << 12) -#define RT3261_DRC_AGC_NGB_SFT 12 -#define RT3261_DRC_AGC_TAR_MASK (0x1f << 7) -#define RT3261_DRC_AGC_TAR_SFT 7 -#define RT3261_DRC_AGC_NG_MASK (0x1 << 6) -#define RT3261_DRC_AGC_NG_SFT 6 -#define RT3261_DRC_AGC_NG_DIS (0x0 << 6) -#define RT3261_DRC_AGC_NG_EN (0x1 << 6) -#define RT3261_DRC_AGC_NGH_MASK (0x1 << 5) -#define RT3261_DRC_AGC_NGH_SFT 5 -#define RT3261_DRC_AGC_NGH_DIS (0x0 << 5) -#define RT3261_DRC_AGC_NGH_EN (0x1 << 5) -#define RT3261_DRC_AGC_NGT_MASK (0x1f) -#define RT3261_DRC_AGC_NGT_SFT 0 - -/* ANC Control 1 (0xb8) */ -#define RT3261_ANC_M_MASK (0x1 << 15) -#define RT3261_ANC_M_SFT 15 -#define RT3261_ANC_M_NOR (0x0 << 15) -#define RT3261_ANC_M_REV (0x1 << 15) -#define RT3261_ANC_MASK (0x1 << 14) -#define RT3261_ANC_SFT 14 -#define RT3261_ANC_DIS (0x0 << 14) -#define RT3261_ANC_EN (0x1 << 14) -#define RT3261_ANC_MD_MASK (0x3 << 12) -#define RT3261_ANC_MD_SFT 12 -#define RT3261_ANC_MD_DIS (0x0 << 12) -#define RT3261_ANC_MD_67MS (0x1 << 12) -#define RT3261_ANC_MD_267MS (0x2 << 12) -#define RT3261_ANC_MD_1067MS (0x3 << 12) -#define RT3261_ANC_SN_MASK (0x1 << 11) -#define RT3261_ANC_SN_SFT 11 -#define RT3261_ANC_SN_DIS (0x0 << 11) -#define RT3261_ANC_SN_EN (0x1 << 11) -#define RT3261_ANC_CLK_MASK (0x1 << 10) -#define RT3261_ANC_CLK_SFT 10 -#define RT3261_ANC_CLK_ANC (0x0 << 10) -#define RT3261_ANC_CLK_REG (0x1 << 10) -#define RT3261_ANC_ZCD_MASK (0x3 << 8) -#define RT3261_ANC_ZCD_SFT 8 -#define RT3261_ANC_ZCD_DIS (0x0 << 8) -#define RT3261_ANC_ZCD_T1 (0x1 << 8) -#define RT3261_ANC_ZCD_T2 (0x2 << 8) -#define RT3261_ANC_ZCD_WT (0x3 << 8) -#define RT3261_ANC_CS_MASK (0x1 << 7) -#define RT3261_ANC_CS_SFT 7 -#define RT3261_ANC_CS_DIS (0x0 << 7) -#define RT3261_ANC_CS_EN (0x1 << 7) -#define RT3261_ANC_SW_MASK (0x1 << 6) -#define RT3261_ANC_SW_SFT 6 -#define RT3261_ANC_SW_NOR (0x0 << 6) -#define RT3261_ANC_SW_AUTO (0x1 << 6) -#define RT3261_ANC_CO_L_MASK (0x3f) -#define RT3261_ANC_CO_L_SFT 0 - -/* ANC Control 2 (0xb6) */ -#define RT3261_ANC_FG_R_MASK (0xf << 12) -#define RT3261_ANC_FG_R_SFT 12 -#define RT3261_ANC_FG_L_MASK (0xf << 8) -#define RT3261_ANC_FG_L_SFT 8 -#define RT3261_ANC_CG_R_MASK (0xf << 4) -#define RT3261_ANC_CG_R_SFT 4 -#define RT3261_ANC_CG_L_MASK (0xf) -#define RT3261_ANC_CG_L_SFT 0 - -/* ANC Control 3 (0xb6) */ -#define RT3261_ANC_CD_MASK (0x1 << 6) -#define RT3261_ANC_CD_SFT 6 -#define RT3261_ANC_CD_BOTH (0x0 << 6) -#define RT3261_ANC_CD_IND (0x1 << 6) -#define RT3261_ANC_CO_R_MASK (0x3f) -#define RT3261_ANC_CO_R_SFT 0 - -/* Jack Detect Control (0xbb) */ -#define RT3261_JD_MASK (0x7 << 13) -#define RT3261_JD_SFT 13 -#define RT3261_JD_DIS (0x0 << 13) -#define RT3261_JD_GPIO1 (0x1 << 13) -#define RT3261_JD_JD1_IN4P (0x2 << 13) -#define RT3261_JD_JD2_IN4N (0x3 << 13) -#define RT3261_JD_GPIO2 (0x4 << 13) -#define RT3261_JD_GPIO3 (0x5 << 13) -#define RT3261_JD_GPIO4 (0x6 << 13) -#define RT3261_JD_HP_MASK (0x1 << 11) -#define RT3261_JD_HP_SFT 11 -#define RT3261_JD_HP_DIS (0x0 << 11) -#define RT3261_JD_HP_EN (0x1 << 11) -#define RT3261_JD_HP_TRG_MASK (0x1 << 10) -#define RT3261_JD_HP_TRG_SFT 10 -#define RT3261_JD_HP_TRG_LO (0x0 << 10) -#define RT3261_JD_HP_TRG_HI (0x1 << 10) -#define RT3261_JD_SPL_MASK (0x1 << 9) -#define RT3261_JD_SPL_SFT 9 -#define RT3261_JD_SPL_DIS (0x0 << 9) -#define RT3261_JD_SPL_EN (0x1 << 9) -#define RT3261_JD_SPL_TRG_MASK (0x1 << 8) -#define RT3261_JD_SPL_TRG_SFT 8 -#define RT3261_JD_SPL_TRG_LO (0x0 << 8) -#define RT3261_JD_SPL_TRG_HI (0x1 << 8) -#define RT3261_JD_SPR_MASK (0x1 << 7) -#define RT3261_JD_SPR_SFT 7 -#define RT3261_JD_SPR_DIS (0x0 << 7) -#define RT3261_JD_SPR_EN (0x1 << 7) -#define RT3261_JD_SPR_TRG_MASK (0x1 << 6) -#define RT3261_JD_SPR_TRG_SFT 6 -#define RT3261_JD_SPR_TRG_LO (0x0 << 6) -#define RT3261_JD_SPR_TRG_HI (0x1 << 6) -#define RT3261_JD_MO_MASK (0x1 << 5) -#define RT3261_JD_MO_SFT 5 -#define RT3261_JD_MO_DIS (0x0 << 5) -#define RT3261_JD_MO_EN (0x1 << 5) -#define RT3261_JD_MO_TRG_MASK (0x1 << 4) -#define RT3261_JD_MO_TRG_SFT 4 -#define RT3261_JD_MO_TRG_LO (0x0 << 4) -#define RT3261_JD_MO_TRG_HI (0x1 << 4) -#define RT3261_JD_LO_MASK (0x1 << 3) -#define RT3261_JD_LO_SFT 3 -#define RT3261_JD_LO_DIS (0x0 << 3) -#define RT3261_JD_LO_EN (0x1 << 3) -#define RT3261_JD_LO_TRG_MASK (0x1 << 2) -#define RT3261_JD_LO_TRG_SFT 2 -#define RT3261_JD_LO_TRG_LO (0x0 << 2) -#define RT3261_JD_LO_TRG_HI (0x1 << 2) -#define RT3261_JD1_IN4P_MASK (0x1 << 1) -#define RT3261_JD1_IN4P_SFT 1 -#define RT3261_JD1_IN4P_DIS (0x0 << 1) -#define RT3261_JD1_IN4P_EN (0x1 << 1) -#define RT3261_JD2_IN4N_MASK (0x1) -#define RT3261_JD2_IN4N_SFT 0 -#define RT3261_JD2_IN4N_DIS (0x0) -#define RT3261_JD2_IN4N_EN (0x1) - -/* Jack detect for ANC (0xbc) */ -#define RT3261_ANC_DET_MASK (0x3 << 4) -#define RT3261_ANC_DET_SFT 4 -#define RT3261_ANC_DET_DIS (0x0 << 4) -#define RT3261_ANC_DET_MB1 (0x1 << 4) -#define RT3261_ANC_DET_MB2 (0x2 << 4) -#define RT3261_ANC_DET_JD (0x3 << 4) -#define RT3261_AD_TRG_MASK (0x1 << 3) -#define RT3261_AD_TRG_SFT 3 -#define RT3261_AD_TRG_LO (0x0 << 3) -#define RT3261_AD_TRG_HI (0x1 << 3) -#define RT3261_ANCM_DET_MASK (0x3 << 4) -#define RT3261_ANCM_DET_SFT 4 -#define RT3261_ANCM_DET_DIS (0x0 << 4) -#define RT3261_ANCM_DET_MB1 (0x1 << 4) -#define RT3261_ANCM_DET_MB2 (0x2 << 4) -#define RT3261_ANCM_DET_JD (0x3 << 4) -#define RT3261_AMD_TRG_MASK (0x1 << 3) -#define RT3261_AMD_TRG_SFT 3 -#define RT3261_AMD_TRG_LO (0x0 << 3) -#define RT3261_AMD_TRG_HI (0x1 << 3) - -/* IRQ Control 1 (0xbd) */ -#define RT3261_IRQ_JD_MASK (0x1 << 15) -#define RT3261_IRQ_JD_SFT 15 -#define RT3261_IRQ_JD_BP (0x0 << 15) -#define RT3261_IRQ_JD_NOR (0x1 << 15) -#define RT3261_IRQ_OT_MASK (0x1 << 14) -#define RT3261_IRQ_OT_SFT 14 -#define RT3261_IRQ_OT_BP (0x0 << 14) -#define RT3261_IRQ_OT_NOR (0x1 << 14) -#define RT3261_JD_STKY_MASK (0x1 << 13) -#define RT3261_JD_STKY_SFT 13 -#define RT3261_JD_STKY_DIS (0x0 << 13) -#define RT3261_JD_STKY_EN (0x1 << 13) -#define RT3261_OT_STKY_MASK (0x1 << 12) -#define RT3261_OT_STKY_SFT 12 -#define RT3261_OT_STKY_DIS (0x0 << 12) -#define RT3261_OT_STKY_EN (0x1 << 12) -#define RT3261_JD_P_MASK (0x1 << 11) -#define RT3261_JD_P_SFT 11 -#define RT3261_JD_P_NOR (0x0 << 11) -#define RT3261_JD_P_INV (0x1 << 11) -#define RT3261_OT_P_MASK (0x1 << 10) -#define RT3261_OT_P_SFT 10 -#define RT3261_OT_P_NOR (0x0 << 10) -#define RT3261_OT_P_INV (0x1 << 10) - -/* IRQ Control 2 (0xbe) */ -#define RT3261_IRQ_MB1_OC_MASK (0x1 << 15) -#define RT3261_IRQ_MB1_OC_SFT 15 -#define RT3261_IRQ_MB1_OC_BP (0x0 << 15) -#define RT3261_IRQ_MB1_OC_NOR (0x1 << 15) -#define RT3261_IRQ_MB2_OC_MASK (0x1 << 14) -#define RT3261_IRQ_MB2_OC_SFT 14 -#define RT3261_IRQ_MB2_OC_BP (0x0 << 14) -#define RT3261_IRQ_MB2_OC_NOR (0x1 << 14) -#define RT3261_MB1_OC_STKY_MASK (0x1 << 11) -#define RT3261_MB1_OC_STKY_SFT 11 -#define RT3261_MB1_OC_STKY_DIS (0x0 << 11) -#define RT3261_MB1_OC_STKY_EN (0x1 << 11) -#define RT3261_MB2_OC_STKY_MASK (0x1 << 10) -#define RT3261_MB2_OC_STKY_SFT 10 -#define RT3261_MB2_OC_STKY_DIS (0x0 << 10) -#define RT3261_MB2_OC_STKY_EN (0x1 << 10) -#define RT3261_MB1_OC_P_MASK (0x1 << 7) -#define RT3261_MB1_OC_P_SFT 7 -#define RT3261_MB1_OC_P_NOR (0x0 << 7) -#define RT3261_MB1_OC_P_INV (0x1 << 7) -#define RT3261_MB2_OC_P_MASK (0x1 << 6) -#define RT3261_MB2_OC_P_SFT 6 -#define RT3261_MB2_OC_P_NOR (0x0 << 6) -#define RT3261_MB2_OC_P_INV (0x1 << 6) -#define RT3261_MB1_OC_CLR (0x1 << 3) -#define RT3261_MB1_OC_CLR_SFT 3 -#define RT3261_MB2_OC_CLR (0x1 << 2) -#define RT3261_MB2_OC_CLR_SFT 2 - -/* GPIO Control 1 (0xc0) */ -#define RT3261_GP1_PIN_MASK (0x1 << 15) -#define RT3261_GP1_PIN_SFT 15 -#define RT3261_GP1_PIN_GPIO1 (0x0 << 15) -#define RT3261_GP1_PIN_IRQ (0x1 << 15) -#define RT3261_GP2_PIN_MASK (0x1 << 14) -#define RT3261_GP2_PIN_SFT 14 -#define RT3261_GP2_PIN_GPIO2 (0x0 << 14) -#define RT3261_GP2_PIN_DMIC1_SCL (0x1 << 14) -#define RT3261_GP3_PIN_MASK (0x3 << 12) -#define RT3261_GP3_PIN_SFT 12 -#define RT3261_GP3_PIN_GPIO3 (0x0 << 12) -#define RT3261_GP3_PIN_DMIC1_SDA (0x1 << 12) -#define RT3261_GP3_PIN_IRQ (0x2 << 12) -#define RT3261_GP4_PIN_MASK (0x1 << 11) -#define RT3261_GP4_PIN_SFT 11 -#define RT3261_GP4_PIN_GPIO4 (0x0 << 11) -#define RT3261_GP4_PIN_DMIC2_SDA (0x1 << 11) -#define RT3261_DP_SIG_MASK (0x1 << 10) -#define RT3261_DP_SIG_SFT 10 -#define RT3261_DP_SIG_TEST (0x0 << 10) -#define RT3261_DP_SIG_AP (0x1 << 10) -#define RT3261_GPIO_M_MASK (0x1 << 9) -#define RT3261_GPIO_M_SFT 9 -#define RT3261_GPIO_M_FLT (0x0 << 9) -#define RT3261_GPIO_M_PH (0x1 << 9) - -/* GPIO Control 3 (0xc2) */ -#define RT3261_GP4_PF_MASK (0x1 << 11) -#define RT3261_GP4_PF_SFT 11 -#define RT3261_GP4_PF_IN (0x0 << 11) -#define RT3261_GP4_PF_OUT (0x1 << 11) -#define RT3261_GP4_OUT_MASK (0x1 << 10) -#define RT3261_GP4_OUT_SFT 10 -#define RT3261_GP4_OUT_LO (0x0 << 10) -#define RT3261_GP4_OUT_HI (0x1 << 10) -#define RT3261_GP4_P_MASK (0x1 << 9) -#define RT3261_GP4_P_SFT 9 -#define RT3261_GP4_P_NOR (0x0 << 9) -#define RT3261_GP4_P_INV (0x1 << 9) -#define RT3261_GP3_PF_MASK (0x1 << 8) -#define RT3261_GP3_PF_SFT 8 -#define RT3261_GP3_PF_IN (0x0 << 8) -#define RT3261_GP3_PF_OUT (0x1 << 8) -#define RT3261_GP3_OUT_MASK (0x1 << 7) -#define RT3261_GP3_OUT_SFT 7 -#define RT3261_GP3_OUT_LO (0x0 << 7) -#define RT3261_GP3_OUT_HI (0x1 << 7) -#define RT3261_GP3_P_MASK (0x1 << 6) -#define RT3261_GP3_P_SFT 6 -#define RT3261_GP3_P_NOR (0x0 << 6) -#define RT3261_GP3_P_INV (0x1 << 6) -#define RT3261_GP2_PF_MASK (0x1 << 5) -#define RT3261_GP2_PF_SFT 5 -#define RT3261_GP2_PF_IN (0x0 << 5) -#define RT3261_GP2_PF_OUT (0x1 << 5) -#define RT3261_GP2_OUT_MASK (0x1 << 4) -#define RT3261_GP2_OUT_SFT 4 -#define RT3261_GP2_OUT_LO (0x0 << 4) -#define RT3261_GP2_OUT_HI (0x1 << 4) -#define RT3261_GP2_P_MASK (0x1 << 3) -#define RT3261_GP2_P_SFT 3 -#define RT3261_GP2_P_NOR (0x0 << 3) -#define RT3261_GP2_P_INV (0x1 << 3) -#define RT3261_GP1_PF_MASK (0x1 << 2) -#define RT3261_GP1_PF_SFT 2 -#define RT3261_GP1_PF_IN (0x0 << 2) -#define RT3261_GP1_PF_OUT (0x1 << 2) -#define RT3261_GP1_OUT_MASK (0x1 << 1) -#define RT3261_GP1_OUT_SFT 1 -#define RT3261_GP1_OUT_LO (0x0 << 1) -#define RT3261_GP1_OUT_HI (0x1 << 1) -#define RT3261_GP1_P_MASK (0x1) -#define RT3261_GP1_P_SFT 0 -#define RT3261_GP1_P_NOR (0x0) -#define RT3261_GP1_P_INV (0x1) - -/* FM34-500 Register Control 1 (0xc4) */ -#define RT3261_DSP_ADD_SFT 0 - -/* FM34-500 Register Control 2 (0xc5) */ -#define RT3261_DSP_DAT_SFT 0 - -/* FM34-500 Register Control 3 (0xc6) */ -#define RT3261_DSP_BUSY_MASK (0x1 << 15) -#define RT3261_DSP_BUSY_BIT 15 -#define RT3261_DSP_DS_MASK (0x1 << 14) -#define RT3261_DSP_DS_SFT 14 -#define RT3261_DSP_DS_FM3010 (0x1 << 14) -#define RT3261_DSP_DS_TEMP (0x1 << 14) -#define RT3261_DSP_CLK_MASK (0x3 << 12) -#define RT3261_DSP_CLK_SFT 12 -#define RT3261_DSP_CLK_384K (0x0 << 12) -#define RT3261_DSP_CLK_192K (0x1 << 12) -#define RT3261_DSP_CLK_96K (0x2 << 12) -#define RT3261_DSP_CLK_64K (0x3 << 12) -#define RT3261_DSP_PD_PIN_MASK (0x1 << 11) -#define RT3261_DSP_PD_PIN_SFT 11 -#define RT3261_DSP_PD_PIN_LO (0x0 << 11) -#define RT3261_DSP_PD_PIN_HI (0x1 << 11) -#define RT3261_DSP_RST_PIN_MASK (0x1 << 10) -#define RT3261_DSP_RST_PIN_SFT 10 -#define RT3261_DSP_RST_PIN_LO (0x0 << 10) -#define RT3261_DSP_RST_PIN_HI (0x1 << 10) -#define RT3261_DSP_R_EN (0x1 << 9) -#define RT3261_DSP_W_EN (0x1 << 8) -#define RT3261_DSP_CMD_MASK (0xff) -#define RT3261_DSP_CMD_PE (0x0d) /* Patch Entry */ -#define RT3261_DSP_CMD_MW (0x3b) /* Memory Write */ -#define RT3261_DSP_CMD_MR (0x37) /* Memory Read */ -#define RT3261_DSP_CMD_RR (0x60) /* Register Read */ -#define RT3261_DSP_CMD_RW (0x68) /* Register Write */ -#define RT3261_DSP_REG_DATHI (0x26) /* High Data Addr */ -#define RT3261_DSP_REG_DATLO (0x25) /* Low Data Addr */ - -/* Programmable Register Array Control 1 (0xc8) */ -#define RT3261_REG_SEQ_MASK (0xf << 12) -#define RT3261_REG_SEQ_SFT 12 -#define RT3261_SEQ1_ST_MASK (0x1 << 11) /*RO*/ -#define RT3261_SEQ1_ST_SFT 11 -#define RT3261_SEQ1_ST_RUN (0x0 << 11) -#define RT3261_SEQ1_ST_FIN (0x1 << 11) -#define RT3261_SEQ2_ST_MASK (0x1 << 10) /*RO*/ -#define RT3261_SEQ2_ST_SFT 10 -#define RT3261_SEQ2_ST_RUN (0x0 << 10) -#define RT3261_SEQ2_ST_FIN (0x1 << 10) -#define RT3261_REG_LV_MASK (0x1 << 9) -#define RT3261_REG_LV_SFT 9 -#define RT3261_REG_LV_MX (0x0 << 9) -#define RT3261_REG_LV_PR (0x1 << 9) -#define RT3261_SEQ_2_PT_MASK (0x1 << 8) -#define RT3261_SEQ_2_PT_BIT 8 -#define RT3261_REG_IDX_MASK (0xff) -#define RT3261_REG_IDX_SFT 0 - -/* Programmable Register Array Control 2 (0xc9) */ -#define RT3261_REG_DAT_MASK (0xffff) -#define RT3261_REG_DAT_SFT 0 - -/* Programmable Register Array Control 3 (0xca) */ -#define RT3261_SEQ_DLY_MASK (0xff << 8) -#define RT3261_SEQ_DLY_SFT 8 -#define RT3261_PROG_MASK (0x1 << 7) -#define RT3261_PROG_SFT 7 -#define RT3261_PROG_DIS (0x0 << 7) -#define RT3261_PROG_EN (0x1 << 7) -#define RT3261_SEQ1_PT_RUN (0x1 << 6) -#define RT3261_SEQ1_PT_RUN_BIT 6 -#define RT3261_SEQ2_PT_RUN (0x1 << 5) -#define RT3261_SEQ2_PT_RUN_BIT 5 - -/* Programmable Register Array Control 4 (0xcb) */ -#define RT3261_SEQ1_START_MASK (0xf << 8) -#define RT3261_SEQ1_START_SFT 8 -#define RT3261_SEQ1_END_MASK (0xf) -#define RT3261_SEQ1_END_SFT 0 - -/* Programmable Register Array Control 5 (0xcc) */ -#define RT3261_SEQ2_START_MASK (0xf << 8) -#define RT3261_SEQ2_START_SFT 8 -#define RT3261_SEQ2_END_MASK (0xf) -#define RT3261_SEQ2_END_SFT 0 - -/* Scramble Function (0xcd) */ -#define RT3261_SCB_KEY_MASK (0xff) -#define RT3261_SCB_KEY_SFT 0 - -/* Scramble Control (0xce) */ -#define RT3261_SCB_SWAP_MASK (0x1 << 15) -#define RT3261_SCB_SWAP_SFT 15 -#define RT3261_SCB_SWAP_DIS (0x0 << 15) -#define RT3261_SCB_SWAP_EN (0x1 << 15) -#define RT3261_SCB_MASK (0x1 << 14) -#define RT3261_SCB_SFT 14 -#define RT3261_SCB_DIS (0x0 << 14) -#define RT3261_SCB_EN (0x1 << 14) - -/* Baseback Control (0xcf) */ -#define RT3261_BB_MASK (0x1 << 15) -#define RT3261_BB_SFT 15 -#define RT3261_BB_DIS (0x0 << 15) -#define RT3261_BB_EN (0x1 << 15) -#define RT3261_BB_CT_MASK (0x7 << 12) -#define RT3261_BB_CT_SFT 12 -#define RT3261_BB_CT_A (0x0 << 12) -#define RT3261_BB_CT_B (0x1 << 12) -#define RT3261_BB_CT_C (0x2 << 12) -#define RT3261_BB_CT_D (0x3 << 12) -#define RT3261_M_BB_L_MASK (0x1 << 9) -#define RT3261_M_BB_L_SFT 9 -#define RT3261_M_BB_R_MASK (0x1 << 8) -#define RT3261_M_BB_R_SFT 8 -#define RT3261_M_BB_HPF_L_MASK (0x1 << 7) -#define RT3261_M_BB_HPF_L_SFT 7 -#define RT3261_M_BB_HPF_R_MASK (0x1 << 6) -#define RT3261_M_BB_HPF_R_SFT 6 -#define RT3261_G_BB_BST_MASK (0x3f) -#define RT3261_G_BB_BST_SFT 0 - -/* MP3 Plus Control 1 (0xd0) */ -#define RT3261_M_MP3_L_MASK (0x1 << 15) -#define RT3261_M_MP3_L_SFT 15 -#define RT3261_M_MP3_R_MASK (0x1 << 14) -#define RT3261_M_MP3_R_SFT 14 -#define RT3261_M_MP3_MASK (0x1 << 13) -#define RT3261_M_MP3_SFT 13 -#define RT3261_M_MP3_DIS (0x0 << 13) -#define RT3261_M_MP3_EN (0x1 << 13) -#define RT3261_EG_MP3_MASK (0x1f << 8) -#define RT3261_EG_MP3_SFT 8 -#define RT3261_MP3_HLP_MASK (0x1 << 7) -#define RT3261_MP3_HLP_SFT 7 -#define RT3261_MP3_HLP_DIS (0x0 << 7) -#define RT3261_MP3_HLP_EN (0x1 << 7) -#define RT3261_M_MP3_ORG_L_MASK (0x1 << 6) -#define RT3261_M_MP3_ORG_L_SFT 6 -#define RT3261_M_MP3_ORG_R_MASK (0x1 << 5) -#define RT3261_M_MP3_ORG_R_SFT 5 - -/* MP3 Plus Control 2 (0xd1) */ -#define RT3261_MP3_WT_MASK (0x1 << 13) -#define RT3261_MP3_WT_SFT 13 -#define RT3261_MP3_WT_1_4 (0x0 << 13) -#define RT3261_MP3_WT_1_2 (0x1 << 13) -#define RT3261_OG_MP3_MASK (0x1f << 8) -#define RT3261_OG_MP3_SFT 8 -#define RT3261_HG_MP3_MASK (0x3f) -#define RT3261_HG_MP3_SFT 0 - -/* 3D HP Control 1 (0xd2) */ -#define RT3261_3D_CF_MASK (0x1 << 15) -#define RT3261_3D_CF_SFT 15 -#define RT3261_3D_CF_DIS (0x0 << 15) -#define RT3261_3D_CF_EN (0x1 << 15) -#define RT3261_3D_HP_MASK (0x1 << 14) -#define RT3261_3D_HP_SFT 14 -#define RT3261_3D_HP_DIS (0x0 << 14) -#define RT3261_3D_HP_EN (0x1 << 14) -#define RT3261_3D_BT_MASK (0x1 << 13) -#define RT3261_3D_BT_SFT 13 -#define RT3261_3D_BT_DIS (0x0 << 13) -#define RT3261_3D_BT_EN (0x1 << 13) -#define RT3261_3D_1F_MIX_MASK (0x3 << 11) -#define RT3261_3D_1F_MIX_SFT 11 -#define RT3261_3D_HP_M_MASK (0x1 << 10) -#define RT3261_3D_HP_M_SFT 10 -#define RT3261_3D_HP_M_SUR (0x0 << 10) -#define RT3261_3D_HP_M_FRO (0x1 << 10) -#define RT3261_M_3D_HRTF_MASK (0x1 << 9) -#define RT3261_M_3D_HRTF_SFT 9 -#define RT3261_M_3D_D2H_MASK (0x1 << 8) -#define RT3261_M_3D_D2H_SFT 8 -#define RT3261_M_3D_D2R_MASK (0x1 << 7) -#define RT3261_M_3D_D2R_SFT 7 -#define RT3261_M_3D_REVB_MASK (0x1 << 6) -#define RT3261_M_3D_REVB_SFT 6 - -/* Adjustable high pass filter control 1 (0xd3) */ -#define RT3261_2ND_HPF_MASK (0x1 << 15) -#define RT3261_2ND_HPF_SFT 15 -#define RT3261_2ND_HPF_DIS (0x0 << 15) -#define RT3261_2ND_HPF_EN (0x1 << 15) -#define RT3261_HPF_CF_L_MASK (0x7 << 12) -#define RT3261_HPF_CF_L_SFT 12 -#define RT3261_1ST_HPF_MASK (0x1 << 11) -#define RT3261_1ST_HPF_SFT 11 -#define RT3261_1ST_HPF_DIS (0x0 << 11) -#define RT3261_1ST_HPF_EN (0x1 << 11) -#define RT3261_HPF_CF_R_MASK (0x7 << 8) -#define RT3261_HPF_CF_R_SFT 8 -#define RT3261_ZD_T_MASK (0x3 << 6) -#define RT3261_ZD_T_SFT 6 -#define RT3261_ZD_F_MASK (0x3 << 4) -#define RT3261_ZD_F_SFT 4 -#define RT3261_ZD_F_IM (0x0 << 4) -#define RT3261_ZD_F_ZC_IM (0x1 << 4) -#define RT3261_ZD_F_ZC_IOD (0x2 << 4) -#define RT3261_ZD_F_UN (0x3 << 4) - -/* HP calibration control and Amp detection (0xd6) */ -#define RT3261_SI_DAC_MASK (0x1 << 11) -#define RT3261_SI_DAC_SFT 11 -#define RT3261_SI_DAC_AUTO (0x0 << 11) -#define RT3261_SI_DAC_TEST (0x1 << 11) -#define RT3261_DC_CAL_M_MASK (0x1 << 10) -#define RT3261_DC_CAL_M_SFT 10 -#define RT3261_DC_CAL_M_CAL (0x0 << 10) -#define RT3261_DC_CAL_M_NOR (0x1 << 10) -#define RT3261_DC_CAL_MASK (0x1 << 9) -#define RT3261_DC_CAL_SFT 9 -#define RT3261_DC_CAL_DIS (0x0 << 9) -#define RT3261_DC_CAL_EN (0x1 << 9) -#define RT3261_HPD_RCV_MASK (0x7 << 6) -#define RT3261_HPD_RCV_SFT 6 -#define RT3261_HPD_PS_MASK (0x1 << 5) -#define RT3261_HPD_PS_SFT 5 -#define RT3261_HPD_PS_DIS (0x0 << 5) -#define RT3261_HPD_PS_EN (0x1 << 5) -#define RT3261_CAL_M_MASK (0x1 << 4) -#define RT3261_CAL_M_SFT 4 -#define RT3261_CAL_M_DEP (0x0 << 4) -#define RT3261_CAL_M_CAL (0x1 << 4) -#define RT3261_CAL_MASK (0x1 << 3) -#define RT3261_CAL_SFT 3 -#define RT3261_CAL_DIS (0x0 << 3) -#define RT3261_CAL_EN (0x1 << 3) -#define RT3261_CAL_TEST_MASK (0x1 << 2) -#define RT3261_CAL_TEST_SFT 2 -#define RT3261_CAL_TEST_DIS (0x0 << 2) -#define RT3261_CAL_TEST_EN (0x1 << 2) -#define RT3261_CAL_P_MASK (0x3) -#define RT3261_CAL_P_SFT 0 -#define RT3261_CAL_P_NONE (0x0) -#define RT3261_CAL_P_CAL (0x1) -#define RT3261_CAL_P_DAC_CAL (0x2) - -/* Soft volume and zero cross control 1 (0xd9) */ -#define RT3261_SV_MASK (0x1 << 15) -#define RT3261_SV_SFT 15 -#define RT3261_SV_DIS (0x0 << 15) -#define RT3261_SV_EN (0x1 << 15) -#define RT3261_SPO_SV_MASK (0x1 << 14) -#define RT3261_SPO_SV_SFT 14 -#define RT3261_SPO_SV_DIS (0x0 << 14) -#define RT3261_SPO_SV_EN (0x1 << 14) -#define RT3261_OUT_SV_MASK (0x1 << 13) -#define RT3261_OUT_SV_SFT 13 -#define RT3261_OUT_SV_DIS (0x0 << 13) -#define RT3261_OUT_SV_EN (0x1 << 13) -#define RT3261_HP_SV_MASK (0x1 << 12) -#define RT3261_HP_SV_SFT 12 -#define RT3261_HP_SV_DIS (0x0 << 12) -#define RT3261_HP_SV_EN (0x1 << 12) -#define RT3261_ZCD_DIG_MASK (0x1 << 11) -#define RT3261_ZCD_DIG_SFT 11 -#define RT3261_ZCD_DIG_DIS (0x0 << 11) -#define RT3261_ZCD_DIG_EN (0x1 << 11) -#define RT3261_ZCD_MASK (0x1 << 10) -#define RT3261_ZCD_SFT 10 -#define RT3261_ZCD_PD (0x0 << 10) -#define RT3261_ZCD_PU (0x1 << 10) -#define RT3261_M_ZCD_MASK (0x3f << 4) -#define RT3261_M_ZCD_SFT 4 -#define RT3261_M_ZCD_RM_L (0x1 << 9) -#define RT3261_M_ZCD_RM_R (0x1 << 8) -#define RT3261_M_ZCD_SM_L (0x1 << 7) -#define RT3261_M_ZCD_SM_R (0x1 << 6) -#define RT3261_M_ZCD_OM_L (0x1 << 5) -#define RT3261_M_ZCD_OM_R (0x1 << 4) -#define RT3261_SV_DLY_MASK (0xf) -#define RT3261_SV_DLY_SFT 0 - -/* Soft volume and zero cross control 2 (0xda) */ -#define RT3261_ZCD_HP_MASK (0x1 << 15) -#define RT3261_ZCD_HP_SFT 15 -#define RT3261_ZCD_HP_DIS (0x0 << 15) -#define RT3261_ZCD_HP_EN (0x1 << 15) - - -/* Codec Private Register definition */ -/* 3D Speaker Control (0x63) */ -#define RT3261_3D_SPK_MASK (0x1 << 15) -#define RT3261_3D_SPK_SFT 15 -#define RT3261_3D_SPK_DIS (0x0 << 15) -#define RT3261_3D_SPK_EN (0x1 << 15) -#define RT3261_3D_SPK_M_MASK (0x3 << 13) -#define RT3261_3D_SPK_M_SFT 13 -#define RT3261_3D_SPK_CG_MASK (0x1f << 8) -#define RT3261_3D_SPK_CG_SFT 8 -#define RT3261_3D_SPK_SG_MASK (0x1f) -#define RT3261_3D_SPK_SG_SFT 0 - -/* Wind Noise Detection Control 1 (0x6c) */ -#define RT3261_WND_MASK (0x1 << 15) -#define RT3261_WND_SFT 15 -#define RT3261_WND_DIS (0x0 << 15) -#define RT3261_WND_EN (0x1 << 15) - -/* Wind Noise Detection Control 2 (0x6d) */ -#define RT3261_WND_FC_NW_MASK (0x3f << 10) -#define RT3261_WND_FC_NW_SFT 10 -#define RT3261_WND_FC_WK_MASK (0x3f << 4) -#define RT3261_WND_FC_WK_SFT 4 - -/* Wind Noise Detection Control 3 (0x6e) */ -#define RT3261_HPF_FC_MASK (0x3f << 6) -#define RT3261_HPF_FC_SFT 6 -#define RT3261_WND_FC_ST_MASK (0x3f) -#define RT3261_WND_FC_ST_SFT 0 - -/* Wind Noise Detection Control 4 (0x6f) */ -#define RT3261_WND_TH_LO_MASK (0x3ff) -#define RT3261_WND_TH_LO_SFT 0 - -/* Wind Noise Detection Control 5 (0x70) */ -#define RT3261_WND_TH_HI_MASK (0x3ff) -#define RT3261_WND_TH_HI_SFT 0 - -/* Wind Noise Detection Control 8 (0x73) */ -#define RT3261_WND_WIND_MASK (0x1 << 13) /* Read-Only */ -#define RT3261_WND_WIND_SFT 13 -#define RT3261_WND_STRONG_MASK (0x1 << 12) /* Read-Only */ -#define RT3261_WND_STRONG_SFT 12 -enum { - RT3261_NO_WIND, - RT3261_BREEZE, - RT3261_STORM, -}; - -/* Dipole Speaker Interface (0x75) */ -#define RT3261_DP_ATT_MASK (0x3 << 14) -#define RT3261_DP_ATT_SFT 14 -#define RT3261_DP_SPK_MASK (0x1 << 10) -#define RT3261_DP_SPK_SFT 10 -#define RT3261_DP_SPK_DIS (0x0 << 10) -#define RT3261_DP_SPK_EN (0x1 << 10) - -/* EQ Pre Volume Control (0xb3) */ -#define RT3261_EQ_PRE_VOL_MASK (0xffff) -#define RT3261_EQ_PRE_VOL_SFT 0 - -/* EQ Post Volume Control (0xb4) */ -#define RT3261_EQ_PST_VOL_MASK (0xffff) -#define RT3261_EQ_PST_VOL_SFT 0 - -/* General Control1 (0xfa) */ -#define RT3261_LOUT_DF_MASK (0x1 << 14) -#define RT3261_LOUT_DF 14 -#define RT3261_M_MAMIX_L (0x1 << 13) -#define RT3261_M_MAMIX_R (0x1 << 12) - -/* General Control2 (0xfb) */ -#define RT3261_RXDC_SRC_MASK (0x1 << 7) -#define RT3261_RXDC_SRC_STO (0x0 << 7) -#define RT3261_RXDC_SRC_MONO (0x1 << 7) -#define RT3261_RXDC_SRC_SFT (7) -#define RT3261_RXDP2_SEL_MASK (0x1 << 3) -#define RT3261_RXDP2_SEL_IF2 (0x0 << 3) -#define RT3261_RXDP2_SEL_ADC (0x1 << 3) -#define RT3261_RXDP2_SEL_SFT (3) - - -/* Vendor ID (0xfd) */ -#define RT3261_VER_C 0x2 -#define RT3261_VER_D 0x3 - - -/* Volume Rescale */ -#define RT3261_VOL_RSCL_MAX 0x27 -#define RT3261_VOL_RSCL_RANGE 0x1F -#define RT3261_HP_VOL_RSCL_RANGE 0x19 -/* Debug String Length */ -#define RT3261_REG_DISP_LEN 10 - -#define RT3261_NO_JACK BIT(0) -#define RT3261_HEADSET_DET BIT(1) -#define RT3261_HEADPHO_DET BIT(2) - -/* System Clock Source */ -enum { - RT3261_SCLK_S_MCLK, - RT3261_SCLK_S_PLL1, - RT3261_SCLK_S_RCCLK, -}; - -/* PLL1 Source */ -enum { - RT3261_PLL1_S_MCLK, - RT3261_PLL1_S_BCLK1, - RT3261_PLL1_S_BCLK2, - RT3261_PLL1_S_BCLK3, -}; - -enum { - RT3261_AIF1, - RT3261_AIF2, - RT3261_AIF3, - RT3261_AIFS, -}; - -#define RT3261_U_IF1 (0x1) -#define RT3261_U_IF2 (0x1 << 1) -#define RT3261_U_IF3 (0x1 << 2) - -enum { - RT3261_IF_123, - RT3261_IF_132, - RT3261_IF_312, - RT3261_IF_321, - RT3261_IF_231, - RT3261_IF_213, - RT3261_IF_113, - RT3261_IF_223, - RT3261_IF_ALL, -}; - -enum { - RT3261_DMIC_DIS, - RT3261_DMIC1, - RT3261_DMIC2, -}; - -enum { - RT3261_ASRC_DIS, - RT3261_ASRC_EN, -}; - -struct rt3261_pll_code { - bool m_bp; /* Indicates bypass m code or not. */ - int m_code; - int n_code; - int k_code; -}; - -struct rt3261_priv { - struct i2c_client *i2c; - struct snd_soc_codec *codec; - struct delayed_work patch_work; - - int aif_pu; - int sysclk; - int sysclk_src; - int lrck[RT3261_AIFS]; - int bclk[RT3261_AIFS]; - int master[RT3261_AIFS]; - - int pll_src; - int pll_in; - int pll_out; - - int dmic_en; - int asrc_en; - int dsp_sw; /* expected parameter setting */ - bool dsp_play_pass; - bool dsp_rec_pass; - - int codec_en_gpio; - - unsigned int modem_is_open; - unsigned int spk_num; - unsigned int modem_input_mode; - unsigned int lout_to_modem_mode; - unsigned int spk_amplify; - unsigned int playback_if1_data_control; - unsigned int playback_if2_data_control; -}; - -int rt3261_conn_mux_path(struct snd_soc_codec *codec, - char *widget_name, char *path_name); - -int rt3261_headset_mic_detect(int jack_insert); - -#endif /* __RT3261_H__ */ diff --git a/sound/soc/codecs/rt3261_ioctl.c b/sound/soc/codecs/rt3261_ioctl.c deleted file mode 100755 index 1350dadb900d..000000000000 --- a/sound/soc/codecs/rt3261_ioctl.c +++ /dev/null @@ -1,467 +0,0 @@ -/* - * rt3261_ioctl.h -- RT3261 ALSA SoC audio driver IO control - * - * Copyright 2012 Realtek Microelectronics - * Author: Bard - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include "rt_codec_ioctl.h" -#include "rt3261_ioctl.h" -#include "rt3261.h" -#if defined (CONFIG_SND_SOC_RT3261) -#include "rt3261-dsp.h" -#endif - -static hweq_t hweq_param[] = { - {/* NORMAL */ - {0}, - {0}, - 0x0000, - }, - {/* SPK */ - {0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2}, - {0x1c10,0x01f4, 0xc5e9, 0x1a98, 0x1d2c, 0xc882, 0x1c10, 0x01f4, 0xe904, 0x1c10, 0x01f4, 0xe904, 0x1c10, 0x01f4, 0x1c10, 0x01f4, 0x2000, 0x0000, 0x2000}, - 0x0000, - }, - {/* HP */ - {0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2}, - {0x1c10,0x01f4, 0xc5e9, 0x1a98, 0x1d2c, 0xc882, 0x1c10, 0x01f4, 0xe904, 0x1c10, 0x01f4, 0xe904, 0x1c10, 0x01f4, 0x1c10, 0x01f4, 0x2000, 0x0000, 0x2000}, - 0x0000, - }, -}; -#define RT3261_HWEQ_LEN ARRAY_SIZE(hweq_param) - -int rt3261_update_eqmode( - struct snd_soc_codec *codec, int mode) -{ - struct rt_codec_ops *ioctl_ops = rt_codec_get_ioctl_ops(); - int i; - static int eq_mode; - - if(codec == NULL || mode >= RT3261_HWEQ_LEN) - return -EINVAL; - - dev_dbg(codec->dev, "%s(): mode=%d\n", __func__, mode); - - if(mode == eq_mode) - return 0; - for(i = 0; i <= EQ_REG_NUM; i++) { - if(hweq_param[mode].reg[i]) - ioctl_ops->index_write(codec, hweq_param[mode].reg[i], - hweq_param[mode].value[i]); - else - break; - } - snd_soc_update_bits(codec, RT3261_EQ_CTRL2, RT3261_EQ_CTRL_MASK, - hweq_param[mode].ctrl); - snd_soc_update_bits(codec, RT3261_EQ_CTRL1, - RT3261_EQ_UPD, RT3261_EQ_UPD); - snd_soc_update_bits(codec, RT3261_EQ_CTRL1, RT3261_EQ_UPD, 0); - - eq_mode = mode; - return 0; -} - -static void set_drc_agc_enable(struct snd_soc_codec *codec, int enable, int path) -{ - snd_soc_update_bits(codec, RT3261_DRC_AGC_1, RT3261_DRC_AGC_P_MASK | - RT3261_DRC_AGC_MASK | RT3261_DRC_AGC_UPD, - enable << RT3261_DRC_AGC_SFT | path << RT3261_DRC_AGC_P_SFT | - 1 << RT3261_DRC_AGC_UPD_BIT); -} - -static void set_drc_agc_parameters(struct snd_soc_codec *codec, int attack_rate, - int sample_rate, int recovery_rate, int limit_level) -{ - snd_soc_update_bits(codec, RT3261_DRC_AGC_3, RT3261_DRC_AGC_TAR_MASK, - limit_level << RT3261_DRC_AGC_TAR_SFT); - snd_soc_update_bits(codec, RT3261_DRC_AGC_1, RT3261_DRC_AGC_AR_MASK | - RT3261_DRC_AGC_R_MASK | RT3261_DRC_AGC_UPD | - RT3261_DRC_AGC_RC_MASK, attack_rate << RT3261_DRC_AGC_AR_SFT | - sample_rate << RT3261_DRC_AGC_R_SFT | - recovery_rate << RT3261_DRC_AGC_RC_SFT | - 0x1 << RT3261_DRC_AGC_UPD_BIT); -} - -static void set_digital_boost_gain(struct snd_soc_codec *codec, - int post_gain, int pre_gain) -{ - snd_soc_update_bits(codec, RT3261_DRC_AGC_2, - RT3261_DRC_AGC_POB_MASK | RT3261_DRC_AGC_PRB_MASK, - post_gain << RT3261_DRC_AGC_POB_SFT | - pre_gain << RT3261_DRC_AGC_PRB_SFT); - snd_soc_update_bits(codec, RT3261_DRC_AGC_1, - RT3261_DRC_AGC_UPD, 1 << RT3261_DRC_AGC_UPD_BIT); -} - -static void set_noise_gate(struct snd_soc_codec *codec, int noise_gate_en, - int noise_gate_hold_en, int compression_gain, int noise_gate_th) -{ - snd_soc_update_bits(codec, RT3261_DRC_AGC_3, - RT3261_DRC_AGC_NGB_MASK | RT3261_DRC_AGC_NG_MASK | - RT3261_DRC_AGC_NGH_MASK | RT3261_DRC_AGC_NGT_MASK, - noise_gate_en << RT3261_DRC_AGC_NG_SFT | - noise_gate_hold_en << RT3261_DRC_AGC_NGH_SFT | - compression_gain << RT3261_DRC_AGC_NGB_SFT | - noise_gate_th << RT3261_DRC_AGC_NGT_SFT); - snd_soc_update_bits(codec, RT3261_DRC_AGC_1, - RT3261_DRC_AGC_UPD, 1 << RT3261_DRC_AGC_UPD_BIT); -} - -static void set_drc_agc_compression(struct snd_soc_codec *codec, - int compression_en, int compression_ratio) -{ - snd_soc_update_bits(codec, RT3261_DRC_AGC_2, - RT3261_DRC_AGC_CP_MASK | RT3261_DRC_AGC_CPR_MASK, - compression_en << RT3261_DRC_AGC_CP_SFT | - compression_ratio << RT3261_DRC_AGC_CPR_SFT); - snd_soc_update_bits(codec, RT3261_DRC_AGC_1, - RT3261_DRC_AGC_UPD, 1 << RT3261_DRC_AGC_UPD_BIT); -} - -static void get_drc_agc_enable(struct snd_soc_codec *codec, int *enable, int *path) -{ - unsigned int reg = snd_soc_read(codec, RT3261_DRC_AGC_1); - - *enable = (reg & RT3261_DRC_AGC_MASK) >> RT3261_DRC_AGC_SFT; - *path = (reg & RT3261_DRC_AGC_P_MASK) >> RT3261_DRC_AGC_P_SFT; -} - -void get_drc_agc_parameters(struct snd_soc_codec *codec, int *attack_rate, - int *sample_rate, int *recovery_rate, int *limit_level) -{ - unsigned int reg = snd_soc_read(codec, RT3261_DRC_AGC_3); - - *limit_level = (reg & RT3261_DRC_AGC_TAR_MASK) >> - RT3261_DRC_AGC_TAR_SFT; - reg = snd_soc_read(codec, RT3261_DRC_AGC_1); - *attack_rate = (reg & RT3261_DRC_AGC_AR_MASK) >> RT3261_DRC_AGC_AR_SFT; - *sample_rate = (reg & RT3261_DRC_AGC_R_MASK) >> RT3261_DRC_AGC_R_SFT; - *recovery_rate = (reg & RT3261_DRC_AGC_RC_MASK) >> - RT3261_DRC_AGC_RC_SFT; -} - -static void get_digital_boost_gain(struct snd_soc_codec *codec, - int *post_gain, int *pre_gain) -{ - unsigned int reg = snd_soc_read(codec, RT3261_DRC_AGC_2); - - *post_gain = (reg & RT3261_DRC_AGC_POB_MASK) >> RT3261_DRC_AGC_POB_SFT; - *pre_gain = (reg & RT3261_DRC_AGC_PRB_MASK) >> RT3261_DRC_AGC_PRB_SFT; -} - -static void get_noise_gate(struct snd_soc_codec *codec, int *noise_gate_en, - int *noise_gate_hold_en, int *compression_gain, int *noise_gate_th) -{ - unsigned int reg = snd_soc_read(codec, RT3261_DRC_AGC_3); - - printk("get_noise_gate reg=0x%04x\n",reg); - *noise_gate_en = (reg & RT3261_DRC_AGC_NG_MASK) >> - RT3261_DRC_AGC_NG_SFT; - *noise_gate_hold_en = (reg & RT3261_DRC_AGC_NGH_MASK) >> - RT3261_DRC_AGC_NGH_SFT; - *compression_gain = (reg & RT3261_DRC_AGC_NGB_MASK) >> - RT3261_DRC_AGC_NGB_SFT; - *noise_gate_th = (reg & RT3261_DRC_AGC_NGT_MASK) >> - RT3261_DRC_AGC_NGT_SFT; -} - -static void get_drc_agc_compression(struct snd_soc_codec *codec, - int *compression_en, int *compression_ratio) -{ - unsigned int reg = snd_soc_read(codec, RT3261_DRC_AGC_2); - - *compression_en = (reg & RT3261_DRC_AGC_CP_MASK) >> - RT3261_DRC_AGC_CP_SFT; - *compression_ratio = (reg & RT3261_DRC_AGC_CPR_MASK) >> - RT3261_DRC_AGC_CPR_SFT; -} - -int rt3261_ioctl_common(struct snd_hwdep *hw, struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct snd_soc_codec *codec = hw->private_data; - struct rt_codec_cmd __user *_rt_codec = (struct rt_codec_cmd *)arg; - struct rt_codec_cmd rt_codec; - struct rt_codec_ops *ioctl_ops = rt_codec_get_ioctl_ops(); - int *buf, mask1 = 0, mask2 = 0; - static int eq_mode; - - if (copy_from_user(&rt_codec, _rt_codec, sizeof(rt_codec))) { - dev_err(codec->dev,"copy_from_user faild\n"); - return -EFAULT; - } - dev_dbg(codec->dev, "%s(): rt_codec.number=%zu, cmd=%d\n", - __func__, rt_codec.number, cmd); - buf = kmalloc(sizeof(*buf) * rt_codec.number, GFP_KERNEL); - if (buf == NULL) - return -ENOMEM; - if (copy_from_user(buf, rt_codec.buf, sizeof(*buf) * rt_codec.number)) { - goto err; - } - - switch (cmd) { - case RT_SET_CODEC_HWEQ_IOCTL: - if (eq_mode == *buf) - break; - eq_mode = *buf; - rt3261_update_eqmode(codec, eq_mode); - break; - - case RT_GET_CODEC_ID: - *buf = snd_soc_read(codec, RT3261_VENDOR_ID2); - if (copy_to_user(rt_codec.buf, buf, sizeof(*buf) * rt_codec.number)) - goto err; - break; - - case RT_SET_CODEC_SPK_VOL_IOCTL: - if(*(buf) <= 0x27) { - snd_soc_update_bits(codec, RT3261_SPK_VOL, - RT3261_L_VOL_MASK | RT3261_R_VOL_MASK, - *(buf) << RT3261_L_VOL_SFT | - *(buf) << RT3261_R_VOL_SFT); - } - break; - - case RT_SET_CODEC_MIC_GAIN_IOCTL: - if(*(buf) <= 0x8) { - snd_soc_update_bits(codec, RT3261_IN1_IN2, - RT3261_BST_MASK1, *(buf) << RT3261_BST_SFT1); - snd_soc_update_bits(codec, RT3261_IN3_IN4, - RT3261_BST_MASK2, *(buf) << RT3261_BST_SFT2); - } - break; - - case RT_SET_CODEC_3D_SPK_IOCTL: - if(rt_codec.number < 4) - break; - if (NULL == ioctl_ops->index_update_bits) - break; - - mask1 = 0; - if(*buf != -1) - mask1 |= RT3261_3D_SPK_MASK; - if(*(buf + 1) != -1) - mask1 |= RT3261_3D_SPK_M_MASK; - if(*(buf + 2) != -1) - mask1 |= RT3261_3D_SPK_CG_MASK; - if(*(buf + 3) != -1) - mask1 |= RT3261_3D_SPK_SG_MASK; - ioctl_ops->index_update_bits(codec, RT3261_3D_SPK, mask1, - *(buf) << RT3261_3D_SPK_SFT | - *(buf + 1) << RT3261_3D_SPK_M_SFT | - *(buf + 2) << RT3261_3D_SPK_CG_SFT | - *(buf + 3) << RT3261_3D_SPK_SG_SFT); - break; - - case RT_SET_CODEC_MP3PLUS_IOCTL: - if(rt_codec.number < 5) - break; - mask1 = mask2 = 0; - if(*buf != -1) - mask1 |= RT3261_M_MP3_MASK; - if(*(buf + 1) != -1) - mask1 |= RT3261_EG_MP3_MASK; - if(*(buf + 2) != -1) - mask2 |= RT3261_OG_MP3_MASK; - if(*(buf + 3) != -1) - mask2 |= RT3261_HG_MP3_MASK; - if(*(buf + 4) != -1) - mask2 |= RT3261_MP3_WT_MASK; - - snd_soc_update_bits(codec, RT3261_MP3_PLUS1, mask1, - *(buf) << RT3261_M_MP3_SFT | - *(buf + 1) << RT3261_EG_MP3_SFT); - snd_soc_update_bits(codec, RT3261_MP3_PLUS2, mask2, - *(buf + 2) << RT3261_OG_MP3_SFT | - *(buf + 3) << RT3261_HG_MP3_SFT | - *(buf + 4) << RT3261_MP3_WT_SFT); - break; - case RT_SET_CODEC_3D_HEADPHONE_IOCTL: - if(rt_codec.number < 4) - break; - if (NULL == ioctl_ops->index_update_bits) - break; - - mask1 = 0; - if(*buf != -1) - mask1 |= RT3261_3D_HP_MASK; - if(*(buf + 1) != -1) - mask1 |= RT3261_3D_BT_MASK; - if(*(buf + 2) != -1) - mask1 |= RT3261_3D_1F_MIX_MASK; - if(*(buf + 3) != -1) - mask1 |= RT3261_3D_HP_M_MASK; - - snd_soc_update_bits(codec, RT3261_3D_HP, mask1, - *(buf)<index_update_bits(codec, - 0x59, 0x1f, *(buf+4)); - break; - - case RT_SET_CODEC_BASS_BACK_IOCTL: - if(rt_codec.number < 3) - break; - mask1 = 0; - if(*buf != -1) - mask1 |= RT3261_BB_MASK; - if(*(buf + 1) != -1) - mask1 |= RT3261_BB_CT_MASK; - if(*(buf + 2) != -1) - mask1 |= RT3261_G_BB_BST_MASK; - - snd_soc_update_bits(codec, RT3261_BASE_BACK, mask1, - *(buf) << RT3261_BB_SFT | - *(buf + 1) << RT3261_BB_CT_SFT | - *(buf + 2) << RT3261_G_BB_BST_SFT); - break; - - case RT_SET_CODEC_DIPOLE_SPK_IOCTL: - if(rt_codec.number < 2) - break; - if (NULL == ioctl_ops->index_update_bits) - break; - - mask1 = 0; - if(*buf != -1) - mask1 |= RT3261_DP_SPK_MASK; - if(*(buf + 1) != -1) - mask1 |= RT3261_DP_ATT_MASK; - - ioctl_ops->index_update_bits(codec, RT3261_DIP_SPK_INF, - mask1, *(buf) << RT3261_DP_SPK_SFT | - *(buf + 1) << RT3261_DP_ATT_SFT ); - break; - - case RT_SET_CODEC_DRC_AGC_ENABLE_IOCTL: - if(rt_codec.number < 2) - break; - set_drc_agc_enable(codec, *(buf), *(buf + 1)); - break; - - case RT_SET_CODEC_DRC_AGC_PAR_IOCTL: - if(rt_codec.number < 4) - break; - set_drc_agc_parameters(codec, *(buf), *(buf + 1), - *(buf + 2), *(buf + 3)); - break; - - case RT_SET_CODEC_DIGI_BOOST_GAIN_IOCTL: - if(rt_codec.number < 2) - break; - set_digital_boost_gain(codec, *(buf), *(buf + 1)); - break; - - case RT_SET_CODEC_NOISE_GATE_IOCTL: - if(rt_codec.number < 4) - break; - set_noise_gate(codec, *(buf), *(buf + 1), - *(buf + 2), *(buf + 3)); - break; - - case RT_SET_CODEC_DRC_AGC_COMP_IOCTL: - if(rt_codec.number < 2) - break; - set_drc_agc_compression(codec, *(buf), *(buf + 1)); - break; - - case RT_SET_CODEC_WNR_ENABLE_IOCTL: - if (NULL == ioctl_ops->index_update_bits) - break; - - ioctl_ops->index_update_bits(codec, RT3261_WND_1, - RT3261_WND_MASK, *(buf) << RT3261_WND_SFT ); - break; - - case RT_GET_CODEC_DRC_AGC_ENABLE_IOCTL: - if(rt_codec.number < 2) - break; - get_drc_agc_enable(codec, (buf), (buf + 1)); - if (copy_to_user(rt_codec.buf, buf, sizeof(*buf) * rt_codec.number)) - goto err; - break; - - case RT_GET_CODEC_DRC_AGC_PAR_IOCTL: - if(rt_codec.number < 4) - break; - get_drc_agc_parameters(codec, (buf), (buf + 1), - (buf + 2), (buf + 3)); - if (copy_to_user(rt_codec.buf, buf, - sizeof(*buf) * rt_codec.number)) - goto err; - break; - - case RT_GET_CODEC_DIGI_BOOST_GAIN_IOCTL: - if(rt_codec.number < 2) - break; - get_digital_boost_gain(codec, (buf), (buf + 1)); - if (copy_to_user(rt_codec.buf, buf, - sizeof(*buf) * rt_codec.number)) - goto err; - break; - - case RT_GET_CODEC_NOISE_GATE_IOCTL: - if(rt_codec.number < 4) - break; - get_noise_gate(codec, (buf), (buf + 1), (buf + 2), (buf + 3)); - if (copy_to_user(rt_codec.buf, buf, - sizeof(*buf) * rt_codec.number)) - goto err; - break; - - case RT_GET_CODEC_DRC_AGC_COMP_IOCTL: - if(rt_codec.number < 2) - break; - get_drc_agc_compression(codec, (buf), (buf + 1)); - if (copy_to_user(rt_codec.buf, buf, - sizeof(*buf) * rt_codec.number)) - goto err; - break; - - case RT_GET_CODEC_SPK_VOL_IOCTL: - *buf = (snd_soc_read(codec, RT3261_SPK_VOL) & RT3261_L_VOL_MASK) - >> RT3261_L_VOL_SFT; - if (copy_to_user(rt_codec.buf, buf, sizeof(*buf) * rt_codec.number)) - goto err; - break; - - case RT_GET_CODEC_MIC_GAIN_IOCTL: - *buf = (snd_soc_read(codec, RT3261_IN1_IN2) & RT3261_BST_MASK1) - >> RT3261_BST_SFT1; - if (copy_to_user(rt_codec.buf, buf, sizeof(*buf) * rt_codec.number)) - goto err; - break; -#if defined (CONFIG_SND_SOC_RT3261) - case RT_READ_CODEC_DSP_IOCTL: - case RT_WRITE_CODEC_DSP_IOCTL: - case RT_GET_CODEC_DSP_MODE_IOCTL: - return rt_codec_dsp_ioctl_common(hw, file, cmd, arg); -#endif - case RT_GET_CODEC_HWEQ_IOCTL: - case RT_GET_CODEC_3D_SPK_IOCTL: - case RT_GET_CODEC_MP3PLUS_IOCTL: - case RT_GET_CODEC_3D_HEADPHONE_IOCTL: - case RT_GET_CODEC_BASS_BACK_IOCTL: - case RT_GET_CODEC_DIPOLE_SPK_IOCTL: - default: - break; - } - - kfree(buf); - return 0; - -err: - kfree(buf); - return -EFAULT; -} -EXPORT_SYMBOL_GPL(rt3261_ioctl_common); diff --git a/sound/soc/codecs/rt3261_ioctl.h b/sound/soc/codecs/rt3261_ioctl.h deleted file mode 100644 index 98981160c133..000000000000 --- a/sound/soc/codecs/rt3261_ioctl.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * rt3261_ioctl.h -- RT3261 ALSA SoC audio driver IO control - * - * Copyright 2012 Realtek Microelectronics - * Author: Bard - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef __RT3261_IOCTL_H__ -#define __RT3261_IOCTL_H__ - -#include -#include - -enum { - NORMAL=0, - SPK, - HP, - MODE_NUM, -}; - -#define EQ_REG_NUM 19 -typedef struct hweq_s { - unsigned int reg[EQ_REG_NUM]; - unsigned int value[EQ_REG_NUM]; - unsigned int ctrl; -} hweq_t; - -int rt3261_ioctl_common(struct snd_hwdep *hw, struct file *file, - unsigned int cmd, unsigned long arg); -int rt3261_update_eqmode(struct snd_soc_codec *codec, int mode); -#endif /* __RT3261_IOCTL_H__ */ diff --git a/sound/soc/codecs/rt5512.c b/sound/soc/codecs/rt5512.c deleted file mode 100644 index 96b28b92392b..000000000000 --- a/sound/soc/codecs/rt5512.c +++ /dev/null @@ -1,1855 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#include -#include -#include -#include -#include -#include -#include - -#ifdef CONFIG_DEBUG_FS -#include -#include -#include -#include -#endif - -#include -#include -#include -#include -#include -#include -#include - -#include "rt5512.h" - -#define RT5512_SRATE_MASK 0x7 -#define RT5512_AUDBIT_MASK 0x3 -#define RT5512_MCLKSELBIT_MASK 0xf -#define RT5512_CLKBASEBIT_MASK 0x2 -#define RT5512_AUDFMT_MASK 0xc -#define RT5512_PDBIT_MASK 0x40 -#define RT5512_RSTBIT_MASK 0x80 - -#define RT5512_RATES SNDRV_PCM_RATE_8000_96000 -#define RT5512_FORMATS (SNDRV_PCM_FMTBIT_S16_LE|SNDRV_PCM_FMTBIT_S20_3LE|SNDRV_PCM_FMTBIT_S24_LE) - -#define RT5512_MAX_REG 0xEC -#define RT5512_VIRTUAL_REG 0xEC - -struct rt5512_codec_reg -{ - unsigned char reg_size; - unsigned int reg_cache; // support maximum 4 byte data - unsigned char sync_needed; -}; - -static struct rt5512_codec_reg rt5512_reg_priv[RT5512_MAX_REG+1] = -{ - [0x00] = { 1, 0, 0}, - [0x01] = { 1, 0, 0}, - [0x02] = { 1, 0, 0}, - [0x03] = { 1, 0, 0}, - [0x04] = { 1, 0, 0}, - [0x05] = { 1, 0, 0}, - [0x06] = { 1, 0, 0}, - [0x07] = { 1, 0, 0}, - [0x08] = { 4, 0, 0}, - [0x09] = { 4, 0, 0}, - [0x0A] = { 4, 0, 0}, - [0x0B] = { 4, 0, 0}, - [0x0C] = { 4, 0, 0}, - [0x0D] = { 4, 0, 0}, - [0x0E] = { 4, 0, 0}, - [0x0F] = { 4, 0, 0}, - [0x10] = { 1, 0, 0}, - [0x11] = { 1, 0, 0}, - [0x12] = { 1, 0, 0}, - [0x13] = { 1, 0, 0}, - [0x14] = { 1, 0, 0}, - [0x15] = { 1, 0, 0}, - [0x16] = { 1, 0, 0}, - [0x17] = { 1, 0, 0}, - [0x1A] = { 1, 0, 0}, - [0x1B] = { 1, 0, 0}, - [0x1C] = { 1, 0, 0}, - [0x1D] = { 4, 0, 0}, - [0x1F] = { 1, 0, 0}, - [0x20] = { 20, 0, 0}, - [0x21] = { 20, 0, 0}, - [0x22] = { 20, 0, 0}, - [0x23] = { 20, 0, 0}, - [0x24] = { 20, 0, 0}, - [0x25] = { 20, 0, 0}, - [0x26] = { 20, 0, 0}, - [0x27] = { 20, 0, 0}, - [0x28] = { 20, 0, 0}, - [0x29] = { 20, 0, 0}, - [0x2A] = { 20, 0, 0}, - [0x2B] = { 20, 0, 0}, - [0x2C] = { 20, 0, 0}, - [0x30] = { 1, 0, 0}, - [0x31] = { 1, 0, 0}, - [0x38] = { 8, 0, 0}, - [0x39] = { 8, 0, 0}, - [0x3A] = { 8, 0, 0}, - [0x3B] = { 8, 0, 0}, - [0x3C] = { 8, 0, 0}, - [0x3D] = { 8, 0, 0}, - [0x3E] = { 8, 0, 0}, - [0x3F] = { 8, 0, 0}, - [0x40] = { 16, 0, 0}, - [0x41] = { 16, 0, 0}, - [0x42] = { 16, 0, 0}, - [0x43] = { 16, 0, 0}, - [0x44] = { 16, 0, 0}, - [0x45] = { 16, 0, 0}, - [0x50] = { 1, 0, 0}, - [0x51] = { 1, 0, 0}, - [0x52] = { 1, 0, 0}, - [0x55] = { 4, 0, 0}, - [0x56] = { 1, 0, 0}, - [0x57] = { 1, 0, 0}, - [0x58] = { 1, 0, 0}, - [0x59] = { 1, 0, 0}, - [0x5B] = { 1, 0, 0}, - [0x5C] = { 1, 0, 0}, - [0x5D] = { 1, 0, 0}, - [0x75] = { 1, 0, 0}, - [0x78] = { 1, 0, 0}, - [0x80] = { 1, 0, 0}, - [0x81] = { 1, 0, 0}, - [0x82] = { 1, 0, 0}, - [0x83] = { 1, 0, 0}, - [0x84] = { 1, 0, 0}, - [0x85] = { 1, 0, 0}, - [0x86] = { 1, 0, 0}, - [0x87] = { 1, 0, 0}, - [0x88] = { 1, 0, 0}, - [0x89] = { 1, 0, 0}, - [0x8A] = { 1, 0, 0}, - [0x8B] = { 1, 0, 0}, - [0x8C] = { 1, 0, 0}, - [0x8D] = { 1, 0, 0}, - [0x8E] = { 1, 0, 0}, - [0x8F] = { 1, 0, 0}, - [0x90] = { 1, 0, 0}, - [0x91] = { 1, 0, 0}, - [0x92] = { 1, 0, 0}, - [0x93] = { 1, 0, 0}, - [0x94] = { 1, 0, 0}, - [0x95] = { 1, 0, 0}, - [0x96] = { 1, 0, 0}, - [0x97] = { 1, 0, 0}, - [0x98] = { 1, 0, 0}, - [0x99] = { 1, 0, 0}, - [0x9A] = { 1, 0, 0}, - [0x9B] = { 1, 0, 0}, - [0x9C] = { 1, 0, 0}, - [0x9D] = { 1, 0, 0}, - [0x9E] = { 1, 0, 0}, - [0x9F] = { 1, 0, 0}, - [0xA0] = { 1, 0, 0}, - [0xA1] = { 1, 0, 0}, - [0xA2] = { 1, 0, 0}, - [0xA3] = { 1, 0, 0}, - [0xA4] = { 1, 0, 0}, - [0xA5] = { 1, 0, 0}, - [0xA6] = { 1, 0, 0}, - [0xA7] = { 1, 0, 0}, - [0xA8] = { 1, 0, 0}, - [0xCA] = { 1, 0, 0}, - [0xCC] = { 1, 0, 0}, - [0xCD] = { 1, 0, 0}, - [0xCE] = { 1, 0, 0}, - [0xE0] = { 1, 0, 0}, - [0xE8] = { 1, 0, 0}, - [0xEB] = { 1, 0, 0}, - [0xEC] = { 4, 0, 0}, -}; - -#if FOR_MID - -struct rt5512_init_reg { - u8 reg; - u32 regval; -}; - -static struct rt5512_init_reg init_list[] = { - /*playback*/ - {0x10 , 0x30}, - {0x11 , 0x30}, - {0x82 , 0x30}, - {0x84 , 0x03}, - {0x8c , 0x09}, - {0xec , 0x27c}, - /*record*/ - {0x95 , 0x82}, - {0x85 , 0x30}, -}; -#define RT5512_INIT_REG_LEN ARRAY_SIZE(init_list) - -static int rt5512_reg_init(struct snd_soc_codec *codec) -{ - int i; - - for (i = 0; i < RT5512_INIT_REG_LEN; i++) - snd_soc_write(codec, init_list[i].reg, init_list[i].regval); - - return 0; -} -#endif - -static int rt5512_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) -{ - struct snd_soc_codec *codec = dai->codec; - unsigned short srate_reg; - unsigned int new_srate_regval, new_datfmt_regval; - - // set sampling rate - RT_DBG("codec hw_param\n"); - RT_DBG("codec hw_param dai id %d\n", dai->id); - switch (dai->id) - { - case 0: // AIF1 - srate_reg = 0x03; - break; - case 1: // AIF2 - srate_reg = 0x04; - break; - default: - dev_err(codec->dev, "this codec dai id is not supported\n"); - return -EINVAL; - } - - RT_DBG("codec hw_param rate%d\n", params_rate(params)); - switch (params_rate(params)) - { - case 8000: - new_srate_regval = 0x0; - break; - case 11025: - case 12000: - new_srate_regval = 0x1; - break; - case 16000: - new_srate_regval = 0x2; - break; - case 22050: - case 24000: - new_srate_regval = 0x3; - break; - case 32000: - new_srate_regval = 0x4; - break; - case 44100: - case 48000: - new_srate_regval = 0x5; - break; - case 88200: - case 96000: - new_srate_regval = 0x6; - break; - default: - dev_err(codec->dev, "not supported sampling rate\n"); - return -EINVAL; - } - snd_soc_update_bits(codec, srate_reg, RT5512_SRATE_MASK, new_srate_regval); - - // set data format - RT_DBG("codec hw_param format%d\n", params_format(params)); - switch (params_format(params)) - { - case SNDRV_PCM_FORMAT_S16_LE: - new_datfmt_regval = 0x3; - break; - case SNDRV_PCM_FORMAT_S20_3LE: - new_datfmt_regval = 0x1; - break; - case SNDRV_PCM_FORMAT_S24_LE: - new_datfmt_regval = 0x0; - break; - default: - dev_err(codec->dev, "not supported data bit format\n"); - return -EINVAL; - } - snd_soc_update_bits(codec, 0x02, RT5512_AUDBIT_MASK, new_datfmt_regval); - - RT_DBG("stream direction %d\n", substream->stream); - if (substream->stream == 0) //Playback - snd_soc_write(codec, 0x56, 0xA4); - else if (substream->stream == 1) //Record - { - snd_soc_update_bits(codec, 0x9F, 0xC0, 0x40); - snd_soc_update_bits(codec, 0x81, 0x40, 0x00); - snd_soc_write(codec, 0x9E, 0x00); - } - - RT_DBG("special register configuration\n"); - snd_soc_write(codec, 0xE0, 0x2F); - snd_soc_write(codec, 0xEB, 0xB4); - snd_soc_write(codec, 0xE8, 0x53); - - return 0; -} - -static int rt5512_set_dai_sysclk(struct snd_soc_dai *dai, - int clk_id, unsigned int freq, int dir) -{ - struct snd_soc_codec *codec = dai->codec; - unsigned int new_mclk_sel, new_clk_basesel; - - RT_DBG("codec dai_sysclk\n"); - switch (dai->id) - { - case 0: // AIF1 - new_mclk_sel = 0x1; - break; - case 1: // AIF2 - new_mclk_sel = 0x1; - break; - default: - dev_err(codec->dev, "no this codec dai id\n"); - return -EINVAL; - } - snd_soc_update_bits(codec, 0x01, RT5512_MCLKSELBIT_MASK, new_mclk_sel); - - if (freq == 11289600) //22.579200 MHz - new_clk_basesel = RT5512_CLKBASEBIT_MASK; - else //24.576000 MHz - new_clk_basesel = 0; - - snd_soc_update_bits(codec, 0x1A, RT5512_CLKBASEBIT_MASK, new_clk_basesel); - - snd_soc_dapm_sync(&codec->dapm); - return 0; -} - -static int rt5512_digital_mute(struct snd_soc_dai *dai, int mute) -{ - struct snd_soc_codec *codec = dai->codec; - unsigned int mute_mask; - - RT_DBG("codec digital_mute id = %d\n", dai->id); - switch (dai->id) - { - case 0: // AIF1 - mute_mask = 0x03; - break; - case 1: // AIF2 - mute_mask = 0x0C; - break; - default: - dev_err(codec->dev, "no this codec dai id\n"); - return -EINVAL; - } - snd_soc_update_bits(codec, 0x07, mute_mask, (mute?mute_mask:0)); - if (!mute) - msleep(50); - return 0; -} - -static int rt5512_set_dai_fmt(struct snd_soc_dai *codec_dai, - unsigned int fmt) -{ - struct snd_soc_codec *codec = codec_dai->codec; - unsigned int new_daifmt_regval; - - RT_DBG("codec dai_fmt\n"); - if (fmt & SND_SOC_DAIFMT_I2S) - new_daifmt_regval = 0x00; - else if (fmt & SND_SOC_DAIFMT_RIGHT_J) - new_daifmt_regval = 0x08; - else if (fmt & SND_SOC_DAIFMT_LEFT_J) - new_daifmt_regval = 0x04; - else - new_daifmt_regval = 0x00; - - snd_soc_update_bits(codec, 0x02, RT5512_AUDFMT_MASK, new_daifmt_regval); - return 0; -} - -static int rt5512_set_clkdiv(struct snd_soc_dai *codec_dai, int div_id, int div) -{ - struct snd_soc_codec *codec = codec_dai->codec; - - RT_DBG("codec clk_div(%d) value %d\n", div_id, div); - switch (div_id) - { - case RT5512_CLK_DIV_ID: - snd_soc_write(codec, 0x55, (div&0x1ffff) << 16); - break; - default: - dev_err(codec->dev, "Invalid clock divider"); - return -EINVAL; - } - - return 0; -} - -static struct snd_soc_dai_ops rt5512_dai_ops = -{ - .hw_params = rt5512_hw_params, - .digital_mute = rt5512_digital_mute, - .set_sysclk = rt5512_set_dai_sysclk, - .set_fmt = rt5512_set_dai_fmt, - .set_clkdiv = rt5512_set_clkdiv, -}; - -static struct snd_soc_dai_driver rt5512_dai[] = -{ - // AIF1 - { - .name = "RT5512-aif1", - .playback = - { - .stream_name = "AIF1 Playback", - .channels_min = 1, - .channels_max = 2, - .rates = RT5512_RATES, - .formats = RT5512_FORMATS, - }, - .capture = - { - .stream_name = "AIF1 Capture", - .channels_min = 1, - .channels_max = 2, - .rates = RT5512_RATES, - .formats = RT5512_FORMATS, - }, - .ops = &rt5512_dai_ops, - .symmetric_rates = 1, - }, - #if 0 - // AIF2 - { - .name = "RT5512-aif2", - .playback = - { - .stream_name = "AIF2 Playback", - .channels_min = 1, - .channels_max = 2, - .rates = RT5512_RATES, - .formats = RT5512_FORMATS, - }, - .capture = - { - .stream_name = "AIF2 Capture", - .channels_min = 1, - .channels_max = 2, - .rates = RT5512_RATES, - .formats = RT5512_FORMATS, - }, - .ops = &rt5512_dai_ops, - .symmetric_rates = 1, - }, - #endif /* #if 0 */ -}; - -static const DECLARE_TLV_DB_SCALE(mic_pga_tlv, -1650, 150, 0); -static const DECLARE_TLV_DB_SCALE(mic_lrpga_tlv, 0, 600, 0); -static const DECLARE_TLV_DB_SCALE(aux_pga_tlv, -500, 100, 0); // range from -5dB to 26dB -static const DECLARE_TLV_DB_SCALE(aux_lrpga_tlv, -300, 300, 0); -static const DECLARE_TLV_DB_SCALE(lrpga2lrspk_tlv, -600, 300, 0); -static const DECLARE_TLV_DB_SCALE(lrpga2lrhp_tlv, -6000, 300, 0); -static const DECLARE_TLV_DB_SCALE(lrspkpga_tlv, -4300, 100, 0); -static const DECLARE_TLV_DB_SCALE(lrhppga_tlv, -3100, 100, 0); -static const DECLARE_TLV_DB_SCALE(recvoutdrv_tlv, -600, 600, 0); -static const DECLARE_TLV_DB_SCALE(spkoutdrv_tlv, 600, 300, 0); -static const DECLARE_TLV_DB_SCALE(hpoutdrv_tlv, -1200, 100, 0); -static const DECLARE_TLV_DB_SCALE(digital_tlv, -10375, 25, 0); -static const char *mic_mode_sel[] = {"Single Ended", "Differential"}; -static const char *mic_inv_mode_sel[] = {"Non-inverting mode", "Inverting mode"}; -static const char *analog_bypass_sel[] = {"Aux", "Mic1", "Mic2", "Mic3"}; -static const char *digital_output_percent[] = {"zero", "quarter", "half", "one"}; -static const char *out_path[] = { "Off", "Recv", "LR_SPK", "LR_HP"}; -static const char *in_path[] = {"Off", "Mic1", "Mic2", "Mic3", "Aux"}; -static const char *hpf_freqcut_option[] = {"4Hz", "379Hz", "770Hz", "1594Hz"}; -static const struct soc_enum rt5512_enum[] = -{ - SOC_ENUM_SINGLE(0x92, 7, 2, mic_mode_sel), - SOC_ENUM_SINGLE(0x92, 6, 2, mic_inv_mode_sel), - SOC_ENUM_SINGLE(0x98, 0, 4, analog_bypass_sel), - SOC_ENUM_SINGLE(0x10, 6, 4, digital_output_percent), - SOC_ENUM_SINGLE(0x10, 4, 4, digital_output_percent), //4 - SOC_ENUM_SINGLE(0x10, 2, 4, digital_output_percent), - SOC_ENUM_SINGLE(0x10, 0, 4, digital_output_percent), - SOC_ENUM_SINGLE(0x11, 6, 4, digital_output_percent), - SOC_ENUM_SINGLE(0x11, 4, 4, digital_output_percent), - SOC_ENUM_SINGLE(0x11, 2, 4, digital_output_percent), - SOC_ENUM_SINGLE(0x11, 0, 4, digital_output_percent), - SOC_ENUM_SINGLE(0x12, 6, 4, digital_output_percent), - SOC_ENUM_SINGLE(0x12, 4, 4, digital_output_percent), - SOC_ENUM_SINGLE(0x12, 2, 4, digital_output_percent), - SOC_ENUM_SINGLE(0x12, 0, 4, digital_output_percent), - SOC_ENUM_SINGLE(0x13, 6, 4, digital_output_percent), - SOC_ENUM_SINGLE(0x13, 4, 4, digital_output_percent), - SOC_ENUM_SINGLE(0x13, 2, 4, digital_output_percent), - SOC_ENUM_SINGLE(0x13, 0, 4, digital_output_percent), - SOC_ENUM_SINGLE(0x93, 7, 2, mic_mode_sel), - SOC_ENUM_SINGLE(0x93, 6, 2, mic_inv_mode_sel), - SOC_ENUM_SINGLE(0x94, 7, 2, mic_mode_sel), - SOC_ENUM_SINGLE(0x94, 6, 2, mic_inv_mode_sel), - SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(out_path), out_path), - SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(in_path), in_path), - SOC_ENUM_SINGLE(0x17, 0, 4, hpf_freqcut_option), - SOC_ENUM_SINGLE(0x17, 2, 4, hpf_freqcut_option), - SOC_ENUM_SINGLE(0x17, 4, 4, hpf_freqcut_option), -}; - -#if FOR_MID -static const char *rt5512_playback_path_mode[] = {"OFF", "RCV", "SPK", "HP", "HP_NO_MIC", "BT", "SPK_HP", //0-6 - "RING_SPK", "RING_HP", "RING_HP_NO_MIC", "RING_SPK_HP"};//7-10 - -static const SOC_ENUM_SINGLE_DECL(rt5512_path_type, 0, 0, rt5512_playback_path_mode); - -static int rt5512_playback_path_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct rt5512_codec_chip *chip = snd_soc_codec_get_drvdata(codec); - - RT_DBG("\n"); - RT_DBG("%s:playback_path=%ld\n",__func__,ucontrol->value.integer.value[0]); - - ucontrol->value.integer.value[0] = chip->curr_outpath; - return 0; -} - - -static int rt5512_playback_path_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ret = 0; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct rt5512_codec_chip *chip = snd_soc_codec_get_drvdata(codec); - struct snd_soc_dapm_context *dapm = &codec->dapm; - - RT_DBG("\n"); - if (ucontrol->value.integer.value[0] != chip->curr_outpath) - { - mutex_lock(&codec->mutex); - switch (ucontrol->value.integer.value[0]) - { - case OFF: - RT_DBG(">>>>>>>>>>>>>>>>%s OFF",__FUNCTION__); - snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); - snd_soc_dapm_disable_pin(dapm, "Ext Spk"); - snd_soc_dapm_sync(dapm); - chip->curr_outpath = ucontrol->value.integer.value[0]; - break; - - case RCV: - break; - - case SPK_PATH: - case RING_SPK: - RT_DBG(">>>>>>>>>>>>>>>>%s spk",__FUNCTION__); - snd_soc_dapm_enable_pin(dapm, "Ext Spk"); - snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); - snd_soc_dapm_sync(dapm); - RT_DBG("Ext Spk status=%d\n", snd_soc_dapm_get_pin_status(dapm, "Ext Spk")); - RT_DBG("Headphone Jack status=%d\n", snd_soc_dapm_get_pin_status(dapm, "Headphone Jack")); - chip->curr_outpath = ucontrol->value.integer.value[0]; - break; - - case HP_PATH: - case HP_NO_MIC: - case RING_HP: - case RING_HP_NO_MIC: - RT_DBG(">>>>>>>>>>>>>>>>%s hp",__FUNCTION__); - snd_soc_dapm_disable_pin(dapm, "Ext Spk"); - snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); - snd_soc_dapm_sync(dapm); - chip->curr_outpath = ucontrol->value.integer.value[0]; - break; - - case BT: - break; - - case SPK_HP: - case RING_SPK_HP: - RT_DBG(">>>>>>>>>>>>>>>>%s spk+hp",__FUNCTION__); - snd_soc_dapm_enable_pin(dapm, "Ext Spk"); - snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); - snd_soc_dapm_sync(dapm); - chip->curr_outpath = ucontrol->value.integer.value[0]; - break; - - default: - dev_err(codec->dev, "Not valid path\n"); - mutex_unlock(&codec->mutex); - ret = -EINVAL; - break; - } - mutex_unlock(&codec->mutex); - } - - return ret; -} - -static const char *rt5512_capture_path_mode[] = {"MIC OFF", "Main Mic", "Hands Free Mic", "BT Sco Mic"};// - -static const SOC_ENUM_SINGLE_DECL(rt5512_capture_type, 0, 0, rt5512_capture_path_mode); - -static int rt5512_capture_path_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct rt5512_codec_chip *chip = snd_soc_codec_get_drvdata(codec); - - RT_DBG("\n"); - RT_DBG("%s:capture_path=%ld\n",__func__,ucontrol->value.integer.value[0]); - - ucontrol->value.integer.value[0] = chip->curr_outpath; - return 0; -} - - -static int rt5512_capture_path_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ret = 0; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct rt5512_codec_chip *chip = snd_soc_codec_get_drvdata(codec); - struct snd_soc_dapm_context *dapm = &codec->dapm; - - RT_DBG("\n"); - if (ucontrol->value.integer.value[0] != chip->curr_outpath) - { - mutex_lock(&codec->mutex); - switch (ucontrol->value.integer.value[0]) - { - case MIC_OFF: - RT_DBG(">>>>>>>>>>>>>>>>%s MIC_OFF",__FUNCTION__); - snd_soc_dapm_disable_pin(dapm, "Main Mic"); - snd_soc_dapm_disable_pin(dapm, "LineIn"); - snd_soc_dapm_sync(dapm); - chip->curr_outpath = ucontrol->value.integer.value[0]; - break; - - case Main_Mic: - RT_DBG(">>>>>>>>>>>>>>>>%s Main_Mic",__FUNCTION__); - /*Mic2 record gain*/ - snd_soc_update_bits(codec, 0x93, 0x1f, 0x15); - snd_soc_update_bits(codec, 0x97, 0x0c, 0x08); - snd_soc_dapm_enable_pin(dapm, "Main Mic"); - snd_soc_dapm_disable_pin(dapm, "LineIn"); - snd_soc_dapm_sync(dapm); - RT_DBG("Main Mic status=%d\n", snd_soc_dapm_get_pin_status(dapm, "Main Mic")); - RT_DBG("LineIn status=%d\n", snd_soc_dapm_get_pin_status(dapm, "LineIn")); - chip->curr_outpath = ucontrol->value.integer.value[0]; - break; - - case Hands_Free_Mic: - RT_DBG(">>>>>>>>>>>>>>>>%s Hands_Free_Mic",__FUNCTION__); - /*Aux record gain*/ - snd_soc_update_bits(codec, 0x91, 0x1f, 0x15); - snd_soc_update_bits(codec, 0x96, 0xc0, 0x80); - snd_soc_dapm_disable_pin(dapm, "Main Mic"); - snd_soc_dapm_enable_pin(dapm, "LineIn"); - snd_soc_dapm_sync(dapm); - chip->curr_outpath = ucontrol->value.integer.value[0]; - break; - - case BT_Sco_Mic: - break; - - default: - dev_err(codec->dev, "Not valid path\n"); - mutex_unlock(&codec->mutex); - ret = -EINVAL; - break; - } - mutex_unlock(&codec->mutex); - } - - return ret; -} - -#else -static int rt5512_inpath_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct rt5512_codec_chip *chip = snd_soc_codec_get_drvdata(codec); - - RT_DBG("\n"); - ucontrol->value.integer.value[0] = chip->curr_inpath; - return 0; -} - -static int rt5512_inpath_set(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ret = 0; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct rt5512_codec_chip *chip = snd_soc_codec_get_drvdata(codec); - struct snd_soc_dapm_context *dapm = &codec->dapm; - - RT_DBG("\n"); - if (ucontrol->value.integer.value[0] != chip->curr_inpath) - { - switch (ucontrol->value.integer.value[0]) - { - case 0: - snd_soc_dapm_disable_pin(dapm, "Mic1"); - snd_soc_dapm_disable_pin(dapm, "Mic2"); - snd_soc_dapm_disable_pin(dapm, "Mic3"); - snd_soc_dapm_disable_pin(dapm, "Aux"); - chip->curr_inpath = ucontrol->value.integer.value[0]; - break; - case 1: - snd_soc_dapm_enable_pin(dapm, "Mic1"); - snd_soc_dapm_disable_pin(dapm, "Mic2"); - snd_soc_dapm_disable_pin(dapm, "Mic3"); - snd_soc_dapm_disable_pin(dapm, "Aux"); - chip->curr_inpath = ucontrol->value.integer.value[0]; - break; - case 2: - snd_soc_dapm_disable_pin(dapm, "Mic1"); - snd_soc_dapm_enable_pin(dapm, "Mic2"); - snd_soc_dapm_disable_pin(dapm, "Mic3"); - snd_soc_dapm_enable_pin(dapm, "Aux"); - chip->curr_inpath = ucontrol->value.integer.value[0]; - break; - case 3: - snd_soc_dapm_disable_pin(dapm, "Mic1"); - snd_soc_dapm_disable_pin(dapm, "Mic2"); - snd_soc_dapm_enable_pin(dapm, "Mic3"); - snd_soc_dapm_disable_pin(dapm, "Aux"); - chip->curr_inpath = ucontrol->value.integer.value[0]; - break; - case 4: - snd_soc_dapm_disable_pin(dapm, "Mic1"); - snd_soc_dapm_disable_pin(dapm, "Mic2"); - snd_soc_dapm_disable_pin(dapm, "Mic3"); - snd_soc_dapm_enable_pin(dapm, "Aux"); - chip->curr_inpath = ucontrol->value.integer.value[0]; - break; - default: - dev_err(codec->dev, "Not valid path\n"); - ret = -EINVAL; - break; - } - } - - return ret; -} - -static int rt5512_outpath_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct rt5512_codec_chip *chip = snd_soc_codec_get_drvdata(codec); - - RT_DBG("\n"); - ucontrol->value.integer.value[0] = chip->curr_outpath; - return 0; -} - -static int rt5512_outpath_set(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ret = 0; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct rt5512_codec_chip *chip = snd_soc_codec_get_drvdata(codec); - struct snd_soc_dapm_context *dapm = &codec->dapm; - - RT_DBG("\n"); - if (ucontrol->value.integer.value[0] != chip->curr_outpath) - { - switch (ucontrol->value.integer.value[0]) - { - case 0: - snd_soc_dapm_disable_pin(dapm, "Receiver"); - snd_soc_dapm_disable_pin(dapm, "LSpeaker"); - snd_soc_dapm_disable_pin(dapm, "RSpeaker"); - snd_soc_dapm_disable_pin(dapm, "LHeadphone"); - snd_soc_dapm_disable_pin(dapm, "RHeadphone"); - chip->curr_outpath = ucontrol->value.integer.value[0]; - break; - case 1: - snd_soc_dapm_enable_pin(dapm, "Receiver"); - snd_soc_dapm_disable_pin(dapm, "LSpeaker"); - snd_soc_dapm_disable_pin(dapm, "RSpeaker"); - snd_soc_dapm_disable_pin(dapm, "LHeadphone"); - snd_soc_dapm_disable_pin(dapm, "RHeadphone"); - chip->curr_outpath = ucontrol->value.integer.value[0]; - break; - case 2: - snd_soc_dapm_disable_pin(dapm, "Receiver"); - snd_soc_dapm_enable_pin(dapm, "LSpeaker"); - snd_soc_dapm_enable_pin(dapm, "RSpeaker"); - snd_soc_dapm_disable_pin(dapm, "LHeadphone"); - snd_soc_dapm_disable_pin(dapm, "RHeadphone"); - chip->curr_outpath = ucontrol->value.integer.value[0]; - break; - case 3: - snd_soc_dapm_disable_pin(dapm, "Receiver"); - snd_soc_dapm_disable_pin(dapm, "LSpeaker"); - snd_soc_dapm_disable_pin(dapm, "RSpeaker"); - snd_soc_dapm_enable_pin(dapm, "LHeadphone"); - snd_soc_dapm_enable_pin(dapm, "RHeadphone"); - chip->curr_outpath = ucontrol->value.integer.value[0]; - break; - default: - dev_err(codec->dev, "Not valid path\n"); - ret = -EINVAL; - break; - } - } - - return ret; -} - -#endif - -static const struct snd_kcontrol_new rt5512_snd_controls[] = -{ - //MicMode parameter - SOC_ENUM("Mic1 ModeSel", rt5512_enum[0]), - SOC_ENUM("Mic1 InvModeSel", rt5512_enum[1]), - SOC_ENUM("Mic2 ModeSel", rt5512_enum[19]), - SOC_ENUM("Mic2 InvModeSel", rt5512_enum[20]), - SOC_ENUM("Mic3 ModeSel", rt5512_enum[21]), - SOC_ENUM("Mic3 InvModeSel", rt5512_enum[22]), - SOC_SINGLE_TLV("Aux PGA Volume", 0x91, 0, 31, 0, aux_pga_tlv), - SOC_SINGLE_TLV("Mic1 PGA Volume", 0x92, 0, 31, 0, mic_pga_tlv), - SOC_SINGLE_TLV("Mic2 PGA Volume", 0x93, 0, 31, 0, mic_pga_tlv), - SOC_SINGLE_TLV("Mic3 PGA Volume", 0x94, 0, 31, 0, mic_pga_tlv), - SOC_SINGLE_TLV("AuxL LPGA Volume", 0x96, 6, 3, 0, aux_lrpga_tlv), - SOC_SINGLE_TLV("AuxR RPGA Volume", 0x97, 6, 3, 0, aux_lrpga_tlv), - SOC_SINGLE_TLV("Mic1 LPGA Volume", 0x96, 4, 3, 0, mic_lrpga_tlv), - SOC_SINGLE_TLV("Mic1 RPGA Volume", 0x97, 4, 3, 0, mic_lrpga_tlv), - SOC_SINGLE_TLV("Mic2 LPGA Volume", 0x96, 2, 3, 0, mic_lrpga_tlv), - SOC_SINGLE_TLV("Mic2 RPGA Volume", 0x97, 2, 3, 0, mic_lrpga_tlv), - SOC_SINGLE_TLV("Mic3 LPGA Volume", 0x96, 0, 3, 0, mic_lrpga_tlv), - SOC_SINGLE_TLV("Mic3 RPGA Volume", 0x97, 0, 3, 0, mic_lrpga_tlv), - SOC_SINGLE_TLV("LPGA2LSPK PGA Volume", 0x8d, 6, 3, 0, lrpga2lrspk_tlv), - SOC_SINGLE_TLV("RPGA2LSPK PGA Volume", 0x8d, 4, 3, 0, lrpga2lrspk_tlv), - SOC_SINGLE_TLV("LPGA2RSPK PGA Volume", 0x8d, 2, 3, 0, lrpga2lrspk_tlv), - SOC_SINGLE_TLV("RPGA2RSPK PGA Volume", 0x8d, 0, 3, 0, lrpga2lrspk_tlv), - SOC_SINGLE_TLV("LPGA2LHP PGA Volume", 0x87, 6, 3, 0, lrpga2lrhp_tlv), - SOC_SINGLE_TLV("RPGA2LHP PGA Volume", 0x87, 4, 3, 0, lrpga2lrhp_tlv), - SOC_SINGLE_TLV("LPGA2RHP PGA Volume", 0x87, 2, 3, 0, lrpga2lrhp_tlv), - SOC_SINGLE_TLV("RPGA2RHP PGA Volume", 0x87, 0, 3, 0, lrpga2lrhp_tlv), - SOC_SINGLE_TLV("LSPKPreMixer PGA Volume", 0x8e, 0, 46, 0, lrspkpga_tlv), - SOC_SINGLE_TLV("RSPKPreMixer PGA Volume", 0x8f, 0, 46, 0, lrspkpga_tlv), - SOC_SINGLE_TLV("LHPPreMixer PGA Volume", 0x88, 0, 31, 0, lrhppga_tlv), - SOC_SINGLE_TLV("RHPPreMixer PGA Volume", 0x89, 0, 31, 0, lrhppga_tlv), - SOC_SINGLE_TLV("RECVDrv Volume", 0x84, 3, 1, 0, recvoutdrv_tlv), - SOC_SINGLE_TLV("LSPKDrv Volume", 0x90, 4, 3, 0, spkoutdrv_tlv), - SOC_SINGLE_TLV("RSPKDrv Volume", 0x90, 0, 3, 0, spkoutdrv_tlv), - SOC_SINGLE_TLV("LHPDrv Volume", 0x8a, 0, 15, 0, hpoutdrv_tlv), - SOC_SINGLE_TLV("RHPDrv Volume", 0x8b, 0, 15, 0, hpoutdrv_tlv), - SOC_DOUBLE_TLV("AUD_ADC1 PGA Volume", 0x0c, 17, 1, 511, 1, digital_tlv), - SOC_DOUBLE_TLV("AUD_ADC2 PGA Volume", 0x0d, 17, 1, 511, 1, digital_tlv), - SOC_DOUBLE_TLV("AUD_DAC1 PGA Volume", 0x0a, 17, 1, 511, 1, digital_tlv), - SOC_DOUBLE_TLV("AUD_DAC2 PGA Volume", 0x0b, 17, 1, 511, 1, digital_tlv), - SOC_DOUBLE_TLV("Sidetone PGA Volume", 0x0e, 17, 1, 511, 1, digital_tlv), - SOC_ENUM("AIF2L2DACL sel", rt5512_enum[3]), - SOC_ENUM("AIF1L2DACL sel", rt5512_enum[4]), - SOC_ENUM("ADCL2DACL sel", rt5512_enum[5]), - SOC_ENUM("ADCR2DACL sel", rt5512_enum[6]), - SOC_ENUM("AIF2R2DACR sel", rt5512_enum[7]), - SOC_ENUM("AIF1R2DACR sel", rt5512_enum[8]), - SOC_ENUM("ADCL2DACR sel", rt5512_enum[9]), - SOC_ENUM("ADCR2DACR sel", rt5512_enum[10]), - SOC_ENUM("AIF2L2TX2L sel", rt5512_enum[11]), - SOC_ENUM("AIF1L2TX2L sel", rt5512_enum[12]), - SOC_ENUM("ADCL2TX2L sel", rt5512_enum[13]), - SOC_ENUM("ADCR2TX2L sel", rt5512_enum[14]), - SOC_ENUM("AIF2R2TX2R sel", rt5512_enum[15]), - SOC_ENUM("AIF1R2TX2R sel", rt5512_enum[16]), - SOC_ENUM("ADCL2TX2R sel", rt5512_enum[17]), - SOC_ENUM("ADCR2TX2R sel", rt5512_enum[18]), - SOC_SINGLE("ADC_HPF1 Switch", 0x16, 1, 1, 0), - SOC_ENUM("ADC_HPF1 FC", rt5512_enum[25]), - SOC_SINGLE("ADC_HPF2 Switch", 0x16, 2, 1, 0), - SOC_ENUM("ADC_HPF2 FC", rt5512_enum[26]), - SOC_SINGLE("ADC_HPF3 Switch", 0x16, 3, 1, 0), - SOC_ENUM("ADC_HPF3 FC", rt5512_enum[27]), - SOC_SINGLE("ADC_DRC1 Switch", 0x16, 4, 1, 0), - SOC_SINGLE("ADC_DRC2 Switch", 0x16, 5, 1, 0), - SOC_SINGLE("ADC_DRC NG Switch", 0x31, 0, 1, 0), - SOC_SINGLE("DAC_3D1 Switch", 0x14, 0, 1, 0), - SOC_SINGLE("DAC_3D2 Switch", 0x14, 1, 1, 0), - SOC_SINGLE("DAC_DRC1 Switch", 0x15, 2, 1, 0), - SOC_SINGLE("DAC_DRC2 Switch", 0x15, 3, 1, 0), - SOC_SINGLE("DAC_DRC3 Switch", 0x15, 4, 1, 0), - SOC_SINGLE("DAC_DRC4 Switch", 0x15, 5, 1, 0), - SOC_SINGLE("DAC_DRC NG Switch", 0x31, 1, 1, 0), - SOC_SINGLE("DAC_BASS1 Switch", 0x14, 2, 1, 0), - SOC_SINGLE("DAC_BASS2 Switch", 0x14, 3, 1, 0), - SOC_SINGLE("DAC_EQ1 Switch", 0x15, 0, 1, 0), - SOC_SINGLE("DAC_EQ2 Switch", 0x15, 1, 1, 0), -#if FOR_MID - SOC_ENUM_EXT("Playback Path", rt5512_path_type, - rt5512_playback_path_get, rt5512_playback_path_put), - SOC_ENUM_EXT("Capture MIC Path", rt5512_capture_type, - rt5512_capture_path_get, rt5512_capture_path_put), -#else - SOC_ENUM_EXT("Out Sel", rt5512_enum[23], rt5512_outpath_get, rt5512_outpath_set), - SOC_ENUM_EXT("In Sel", rt5512_enum[24], rt5512_inpath_get, rt5512_inpath_set), -#endif -}; - -static const struct snd_kcontrol_new linput_mixer_controls[] = -{ - SOC_DAPM_SINGLE("AuxL Switch", 0x95, 7, 1, 0), - SOC_DAPM_SINGLE("Mic1 Switch", 0x95, 6, 1, 0), - SOC_DAPM_SINGLE("Mic2 Switch", 0x95, 5, 1, 0), - SOC_DAPM_SINGLE("Mic3 Switch", 0x95, 4, 1, 0), -}; - -static const struct snd_kcontrol_new rinput_mixer_controls[] = -{ - SOC_DAPM_SINGLE("AuxR Switch", 0x95, 3, 1, 0), - SOC_DAPM_SINGLE("Mic1 Switch", 0x95, 2, 1, 0), - SOC_DAPM_SINGLE("Mic2 Switch", 0x95, 1, 1, 0), - SOC_DAPM_SINGLE("Mic3 Switch", 0x95, 0, 1, 0), -}; - -static const struct snd_kcontrol_new analog_bypass_controls = - SOC_DAPM_ENUM("Analog Bypass", rt5512_enum[2]); - -static const struct snd_kcontrol_new lspkpre_mixer_controls[] = -{ - SOC_DAPM_SINGLE("LPGA Switch", 0x8c, 7, 1, 0), - SOC_DAPM_SINGLE("LSPKDAC Switch", 0x84, 1, 1, 0), - SOC_DAPM_SINGLE("RPGA Switch", 0x8c, 6, 1, 0), -}; - -static const struct snd_kcontrol_new rspkpre_mixer_controls[] = -{ - SOC_DAPM_SINGLE("LPGA Switch", 0x8c, 5, 1, 0), - SOC_DAPM_SINGLE("RSPKDAC Switch", 0x84, 0, 1, 0), - SOC_DAPM_SINGLE("RPGA Switch", 0x8c, 4, 1, 0), -}; - -static const struct snd_kcontrol_new recvout_mixer_controls[] = -{ - SOC_DAPM_SINGLE("LSPKPGA Switch", 0x84, 6, 1, 0), - SOC_DAPM_SINGLE("RSPKPGA Switch", 0x84, 5, 1, 0), - SOC_DAPM_SINGLE("BYPASS Switch", 0x84, 4, 1, 0), -}; - -static const struct snd_kcontrol_new lspkpost_mixer_controls[] = -{ - SOC_DAPM_SINGLE("RSPKPGA Switch", 0x8c, 2, 1, 0), - SOC_DAPM_SINGLE("LSPKPGA Switch", 0x8c, 3, 1, 0), - SOC_DAPM_SINGLE("BYPASS Switch", 0x90, 7, 1, 0), -}; - -static const struct snd_kcontrol_new rspkpost_mixer_controls[] = -{ - SOC_DAPM_SINGLE("LSPKPGA Switch", 0x8c, 1, 1, 0), - SOC_DAPM_SINGLE("RSPKPGA Switch", 0x8c, 0, 1, 0), - SOC_DAPM_SINGLE("BYPASS Switch", 0x90, 3, 1, 0), -}; - -static const struct snd_kcontrol_new lhppre_mixer_controls[] = -{ - SOC_DAPM_SINGLE("LPGA Switch", 0x86, 7, 1, 0), - SOC_DAPM_SINGLE("RPGA Switch", 0x86, 6, 1, 0), -}; - -static const struct snd_kcontrol_new rhppre_mixer_controls[] = -{ - SOC_DAPM_SINGLE("LPGA Switch", 0x86, 5, 1, 0), - SOC_DAPM_SINGLE("RPGA Switch", 0x86, 4, 1, 0), -}; - -static const struct snd_kcontrol_new lhppost_mixer_controls[] = -{ - SOC_DAPM_SINGLE("LHPDAC Switch", RT5512_VIRTUAL_REG, 6, 1, 0), - SOC_DAPM_SINGLE("BYPASS Switch", 0x86, 1, 1, 0), - SOC_DAPM_SINGLE("LRPGAMixer Switch", RT5512_VIRTUAL_REG, 7, 1, 0), -}; - -static const struct snd_kcontrol_new rhppost_mixer_controls[] = -{ - SOC_DAPM_SINGLE("LRPGAMixer Switch", RT5512_VIRTUAL_REG, 8, 1, 0), - SOC_DAPM_SINGLE("BYPASS Switch", 0x86, 0, 1, 0), - SOC_DAPM_SINGLE("RHPDAC Switch", RT5512_VIRTUAL_REG, 9, 1, 0), -}; - -static int rt5512_power_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) -{ - RT_DBG("\n"); - switch (event) - { - case SND_SOC_DAPM_PRE_PMU: - snd_soc_update_bits(w->codec, 0x81, 0x7, 0x7); - mdelay(20); - snd_soc_update_bits(w->codec, 0x81, 0x4, 0x0); - mdelay(1); - break; - case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(w->codec, 0x81, 0x7, 0x4); - break; - } - return 0; -} - -static int rt5512_lhpdrv_pevent(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) -{ - RT_DBG("\n"); - switch (event) - { - case SND_SOC_DAPM_PRE_PMU: - snd_soc_update_bits(w->codec, 0x83, 0x80, 0x80); - mdelay(1); - break; - case SND_SOC_DAPM_PRE_PMD: - snd_soc_update_bits(w->codec, 0x8A, 0x0F, 0x00); - mdelay(50); - break; - case SND_SOC_DAPM_POST_PMD: - mdelay(10); - snd_soc_update_bits(w->codec, 0x83, 0x80, 0x0); - mdelay(10); - snd_soc_update_bits(w->codec, 0x8A, 0x0F, 0x0B); - break; - } - return 0; -} - -static int rt5512_rhpdrv_pevent(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) -{ - RT_DBG("\n"); - switch (event) - { - case SND_SOC_DAPM_PRE_PMU: - snd_soc_update_bits(w->codec, 0x83, 0x80, 0x80); - mdelay(1); - break; - case SND_SOC_DAPM_PRE_PMD: - snd_soc_update_bits(w->codec, 0x8B, 0x0F, 0x00); - mdelay(50); - break; - case SND_SOC_DAPM_POST_PMD: - mdelay(10); - snd_soc_update_bits(w->codec, 0x83, 0x80, 0x0); - mdelay(10); - snd_soc_update_bits(w->codec, 0x8B, 0x0F, 0x0B); - break; - } - return 0; -} - -static int rt5512_spkdac_pevent(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) -{ - RT_DBG("\n"); - switch (event) - { - case SND_SOC_DAPM_POST_PMU: - mdelay(125); - break; - } - return 0; -} - -static int rt5512_spkdrv_pevent(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) -{ - RT_DBG("\n"); - switch (event) - { - case SND_SOC_DAPM_PRE_PMU: - mdelay(1); - break; - case SND_SOC_DAPM_POST_PMD: - mdelay(1); - break; - } - return 0; -} - -static int rt5512_recvdrv_pevent(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) -{ - RT_DBG("\n"); - switch (event) - { - case SND_SOC_DAPM_PRE_PMU: - snd_soc_update_bits(w->codec, 0x83, 0x80, 0x80); - mdelay(2); - break; - case SND_SOC_DAPM_POST_PMD: - mdelay(1); - snd_soc_update_bits(w->codec, 0x83, 0x80, 0x0); - mdelay(1); - break; - } - return 0; -} - -static const struct snd_soc_dapm_widget rt5512_dapm_widgets[] = -{ - SND_SOC_DAPM_PRE("Pre Power", rt5512_power_event), - SND_SOC_DAPM_POST("Post Power",rt5512_power_event), - // Input Related - // Analog Input Pin - SND_SOC_DAPM_INPUT("Mic1"), - SND_SOC_DAPM_INPUT("Mic2"), - SND_SOC_DAPM_INPUT("Mic3"), - SND_SOC_DAPM_INPUT("Aux"), - // Analog Bypass - SND_SOC_DAPM_MUX("Analog Bypass Mux", RT5512_VIRTUAL_REG, 0, 0, &analog_bypass_controls), - // Input PGA - SND_SOC_DAPM_PGA("Aux PGA", 0x85, 3, 0, NULL, 0), - SND_SOC_DAPM_PGA("Mic1 PGA", 0x85, 2, 0, NULL, 0), - SND_SOC_DAPM_PGA("Mic2 PGA", 0x85, 1, 0, NULL, 0), - SND_SOC_DAPM_PGA("Mic3 PGA", 0x85, 0, 0, NULL, 0), - // Input Mixer - SND_SOC_DAPM_MIXER("LInput Mixer", 0x85, 5, 0, linput_mixer_controls, ARRAY_SIZE(linput_mixer_controls)), - SND_SOC_DAPM_MIXER("RInput Mixer", 0x85, 4, 0, rinput_mixer_controls, ARRAY_SIZE(rinput_mixer_controls)), - // Input ADC - SND_SOC_DAPM_ADC("LADC", NULL, 0x85, 7, 0), - SND_SOC_DAPM_ADC("RADC", NULL, 0x85, 6, 0), - // Digital Input Interface - SND_SOC_DAPM_AIF_OUT("AIF1ADC", NULL, 0, 0x06, 0, 0), - //SND_SOC_DAPM_AIF_OUT("AIF1ADCR", NULL, 0, 0x06, 0, 0), - SND_SOC_DAPM_AIF_OUT("AIF1ADCDAT", "AIF1 Capture", 0, 0x05, 2, 1), - SND_SOC_DAPM_AIF_OUT("AIF2ADC", NULL, 0, 0x06, 1, 0), - //SND_SOC_DAPM_AIF_OUT("AIF2ADCR", NULL, 0, 0x06, 1, 0), - SND_SOC_DAPM_AIF_OUT("AIF2ADCDAT", "AIF2 Capture", 0, 0x05, 3, 1), - - //Digital DSP Routing - //Mixer - SND_SOC_DAPM_MIXER("DACL Mixer", 0x07, 7, 1, NULL, 0), - SND_SOC_DAPM_MIXER("DACR Mixer", 0x07, 6, 1, NULL, 0), - SND_SOC_DAPM_MIXER("TX2L Mixer", 0x07, 5, 1, NULL, 0), - SND_SOC_DAPM_MIXER("TX2R Mixer", 0x07, 4, 1, NULL, 0), - - // Output Related - SND_SOC_DAPM_AIF_IN("AIF1DAC", NULL, 0, 0x06, 2, 0), - //SND_SOC_DAPM_AIF_IN("AIF1DACR", NULL, 0, 0x06, 2, 0), - SND_SOC_DAPM_AIF_IN("AIF1DACDAT", "AIF1 Playback", 0, 0x05, 0, 1), - SND_SOC_DAPM_AIF_IN("AIF2DAC", NULL, 0, 0x06, 3, 0), - //SND_SOC_DAPM_AIF_IN("AIF2DACR", NULL, 0, 0x06, 3, 0), - SND_SOC_DAPM_AIF_IN("AIF2DACDAT", "AIF2 Playback", 0, 0x05, 1, 1), - // Output DAC - SND_SOC_DAPM_DAC_E("LSPKDAC", NULL, 0x82, 1, 0, rt5512_spkdac_pevent, - SND_SOC_DAPM_POST_PMU), - SND_SOC_DAPM_DAC("RSPKDAC", NULL, 0x82, 0, 0), - SND_SOC_DAPM_DAC("LHPDAC", NULL, 0x82, 3, 0), - SND_SOC_DAPM_DAC("RHPDAC", NULL, 0x82, 2, 0), - // Output Mixer - SND_SOC_DAPM_MIXER("LSPK Pre Mixer", 0x82, 5, 0, lspkpre_mixer_controls, ARRAY_SIZE(lspkpre_mixer_controls)), - SND_SOC_DAPM_MIXER("RSPK Pre Mixer", 0x82, 4, 0, rspkpre_mixer_controls, ARRAY_SIZE(rspkpre_mixer_controls)), - SND_SOC_DAPM_MIXER("RECV Mixer", RT5512_VIRTUAL_REG, 1, 0, recvout_mixer_controls, ARRAY_SIZE(recvout_mixer_controls)), - SND_SOC_DAPM_MIXER("LSPK Post Mixer", RT5512_VIRTUAL_REG, 2, 0, lspkpost_mixer_controls, ARRAY_SIZE(lspkpost_mixer_controls)), - SND_SOC_DAPM_MIXER("RSPK Post Mixer", RT5512_VIRTUAL_REG, 3, 0, rspkpost_mixer_controls, ARRAY_SIZE(rspkpost_mixer_controls)), - SND_SOC_DAPM_MIXER("LHP Pre Mixer", 0x82, 7, 0, lhppre_mixer_controls, ARRAY_SIZE(lhppre_mixer_controls)), - SND_SOC_DAPM_MIXER("RHP Pre Mixer", 0x82, 6, 0, rhppre_mixer_controls, ARRAY_SIZE(rhppre_mixer_controls)), - SND_SOC_DAPM_MIXER("LHP Post Mixer", RT5512_VIRTUAL_REG, 4, 0, lhppost_mixer_controls, ARRAY_SIZE(lhppost_mixer_controls)), - SND_SOC_DAPM_MIXER("RHP Post Mixer", RT5512_VIRTUAL_REG, 5, 0, rhppost_mixer_controls, ARRAY_SIZE(rhppost_mixer_controls)), - // Output Drv - SND_SOC_DAPM_OUT_DRV_E("RECV Drv", 0x84, 7, 0, NULL, 0, rt5512_recvdrv_pevent, - SND_SOC_DAPM_PRE_PMU|SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_OUT_DRV_E("LSPK Drv", 0x83, 3, 0, NULL, 0, rt5512_spkdrv_pevent, - SND_SOC_DAPM_PRE_PMU|SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_OUT_DRV_E("RSPK Drv", 0x83, 2, 0, NULL, 0, rt5512_spkdrv_pevent, - SND_SOC_DAPM_PRE_PMU|SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_OUT_DRV_E("LHP Drv", 0x83, 1, 0, NULL, 0, rt5512_lhpdrv_pevent, - SND_SOC_DAPM_PRE_PMU|SND_SOC_DAPM_PRE_PMD|SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_OUT_DRV_E("RHP Drv", 0x83, 0, 0, NULL, 0, rt5512_rhpdrv_pevent, - SND_SOC_DAPM_PRE_PMU|SND_SOC_DAPM_PRE_PMD||SND_SOC_DAPM_POST_PMU), - // Output Pin - SND_SOC_DAPM_OUTPUT("Receiver"), - SND_SOC_DAPM_OUTPUT("LSpeaker"), - SND_SOC_DAPM_OUTPUT("RSpeaker"), - SND_SOC_DAPM_OUTPUT("LHeadphone"), - SND_SOC_DAPM_OUTPUT("RHeadphone"), - //MicBias - SND_SOC_DAPM_MICBIAS("MicBias1", 0x81, 5, 0), - SND_SOC_DAPM_MICBIAS("MicBias2", 0x81, 5, 0), -}; - -static const struct snd_soc_dapm_route rt5512_dapm_routes[] = -{ - // Input - {"Mic1 PGA", NULL, "Mic1"}, - {"Mic2 PGA", NULL, "Mic2"}, - {"Mic3 PGA", NULL, "Mic3"}, - {"Aux PGA", NULL, "Aux"}, - {"Analog Bypass Mux", "Mic1", "Mic1"}, - {"Analog Bypass Mux", "Mic2", "Mic2"}, - {"Analog Bypass Mux", "Mic3", "Mic3"}, - {"Analog Bypass Mux", "Aux", "Aux"}, - {"LInput Mixer", "Mic1 Switch", "Mic1 PGA"}, - {"LInput Mixer", "Mic2 Switch", "Mic2 PGA"}, - {"LInput Mixer", "Mic3 Switch", "Mic3 PGA"}, - {"LInput Mixer", "AuxL Switch", "Aux PGA"}, - {"RInput Mixer", "Mic1 Switch", "Mic1 PGA"}, - {"RInput Mixer", "Mic2 Switch", "Mic2 PGA"}, - {"RInput Mixer", "Mic3 Switch", "Mic3 PGA"}, - {"RInput Mixer", "AuxR Switch", "Aux PGA"}, - {"LADC", NULL, "LInput Mixer"}, - {"RADC", NULL, "RInput Mixer"}, - {"AIF1ADC", NULL, "LADC"}, - {"AIF1ADC", NULL, "RADC"}, - {"AIF1ADCDAT", NULL, "AIF1ADC"}, - //{"AIF1ADCDAT", NULL, "AIF1ADCR"}, - {"AIF2ADC", NULL, "TX2L Mixer"}, - {"AIF2ADC", NULL, "TX2R Mixer"}, - {"AIF2ADCDAT", NULL, "AIF2ADC"}, - //{"AIF2ADCDAT", NULL, "AIF2ADCR"}, - // Output - {"AIF1DAC", NULL, "AIF1DACDAT"}, - //{"AIF1DACR", NULL, "AIF1DACDAT"}, - {"AIF2DAC", NULL, "AIF2DACDAT"}, - //{"AIF2DACR", NULL, "AIF2DACDAT"}, - {"DACL Mixer", NULL, "AIF1DAC"}, - {"DACL Mixer", NULL, "AIF2DAC"}, - {"DACL Mixer", NULL, "LADC"}, - {"DACL Mixer", NULL, "RADC"}, - {"DACR Mixer", NULL, "AIF1DAC"}, - {"DACR Mixer", NULL, "AIF2DAC"}, - {"DACR Mixer", NULL, "LADC"}, - {"DACR Mixer", NULL, "RADC"}, - {"TX2L Mixer", NULL, "AIF1DAC"}, - {"TX2L Mixer", NULL, "AIF2DAC"}, - {"TX2L Mixer", NULL, "LADC"}, - {"TX2L Mixer", NULL, "RADC"}, - {"TX2R Mixer", NULL, "AIF1DAC"}, - {"TX2R Mixer", NULL, "AIF2DAC"}, - {"TX2R Mixer", NULL, "LADC"}, - {"TX2R Mixer", NULL, "RADC"}, - {"LSPKDAC", NULL, "DACL Mixer"}, - {"RSPKDAC", NULL, "DACR Mixer"}, - {"LHPDAC", NULL, "DACL Mixer"}, - {"RHPDAC", NULL, "DACR Mixer"}, - {"LSPK Pre Mixer", "LPGA Switch", "LInput Mixer"}, - {"LSPK Pre Mixer", "LSPKDAC Switch", "LSPKDAC"}, - {"LSPK Pre Mixer", "RPGA Switch", "RInput Mixer"}, - {"RSPK Pre Mixer", "LPGA Switch", "LInput Mixer"}, - {"RSPK Pre Mixer", "RSPKDAC Switch", "RSPKDAC"}, - {"RSPK Pre Mixer", "RPGA Switch", "RInput Mixer"}, - {"LHP Pre Mixer", "LPGA Switch", "LInput Mixer"}, - {"LHP Pre Mixer", "RPGA Switch", "RInput Mixer"}, - {"RHP Pre Mixer", "LPGA Switch", "LInput Mixer"}, - {"RHP Pre Mixer", "RPGA Switch", "RInput Mixer"}, - {"RECV Mixer", "LSPKPGA Switch", "LSPK Pre Mixer"}, - {"RECV Mixer", "RSPKPGA Switch", "RSPK Pre Mixer"}, - {"RECV Mixer", "BYPASS Switch", "Analog Bypass Mux"}, - {"LSPK Post Mixer", "RSPKPGA Switch", "RSPK Pre Mixer"}, - {"LSPK Post Mixer", "LSPKPGA Switch", "LSPK Pre Mixer"}, - {"LSPK Post Mixer", "BYPASS Switch", "Analog Bypass Mux"}, - {"RSPK Post Mixer", "LSPKPGA Switch", "LSPK Pre Mixer"}, - {"RSPK Post Mixer", "RSPKPGA Switch", "RSPK Pre Mixer"}, - {"RSPK Post Mixer", "BYPASS Switch", "Analog Bypass Mux"}, - {"LHP Post Mixer", "LHPDAC Switch", "LHPDAC"}, - {"LHP Post Mixer", "BYPASS Switch", "Analog Bypass Mux"}, - {"LHP Post Mixer", "LRPGAMixer Switch", "LHP Pre Mixer"}, - {"RHP Post Mixer", "LRPGAMixer Switch", "RHP Pre Mixer"}, - {"RHP Post Mixer", "BYPASS Switch", "Analog Bypass Mux"}, - {"RHP Post Mixer", "RHPDAC Switch", "RHPDAC"}, - {"RECV Drv", NULL, "RECV Mixer"}, - {"LSPK Drv", NULL, "LSPK Post Mixer"}, - {"RSPK Drv", NULL, "RSPK Post Mixer"}, - {"LHP Drv", NULL, "LHP Post Mixer"}, - {"RHP Drv", NULL, "RHP Post Mixer"}, - {"Receiver", NULL, "RECV Drv"}, - {"LSpeaker", NULL, "LSPK Drv"}, - {"RSpeaker", NULL, "RSPK Drv"}, - {"LHeadphone", NULL, "LHP Drv"}, - {"RHeadphone", NULL, "RHP Drv"}, -}; - -void odroid_audio_tvout(bool tvout) -{ - return; -} - - -static int rt5512_id_check(struct snd_soc_codec *codec) -{ - int ret = -1; - u8 regaddr = 0x00; // always revision id register - u8 regval; - - ret = i2c_master_send(codec->control_data, ®addr, 1); - if (ret != 1) - { - dev_err(codec->dev, "send reg addr fail\n"); - return -EIO; - } - ret = i2c_master_recv(codec->control_data, ®val, 1); - if (ret != 1) - { - dev_err(codec->dev, "read regval fail\n"); - return -EIO; - } - - return regval; -} -static unsigned int rt5512_io_read(struct snd_soc_codec *codec, unsigned int reg) -{ - int ret; - char regaddr = reg&0xff; // 8bit register address - char regval[4] = {0}; - int len = rt5512_reg_priv[reg].reg_size; - int i; - - RT_DBG("reg 0x%02x\n", reg); - if (reg == RT5512_VIRTUAL_REG) - { - return rt5512_reg_priv[reg].reg_cache; - } - - if (len == 8 || len == 16 || len == 20) - { - pr_err("rt5512-codec: not supported reg data size in this read function\n"); - return -EINVAL; - } - else if (len == 0) - { - dev_err(codec->dev, "Invalid reg_addr 0x%02x\n", reg); - return -EINVAL; - } - - if (rt5512_reg_priv[reg].sync_needed) - { - ret = i2c_master_send(codec->control_data, ®addr, 1); - if (ret != 1) - { - dev_err(codec->dev, "send reg addr fail\n"); - return -EIO; - } - ret = i2c_master_recv(codec->control_data, regval, len); - if (ret != len) - { - dev_err(codec->dev, "read regval fail\n"); - return -EIO; - } - - switch (len) - { - case 1: - ret = 0x00 | regval[0]; - break; - case 4: - for (i=0, ret=0x0; i<4 ; i++) - ret |= (regval[i] << (24-8*i)); - break; - } - rt5512_reg_priv[reg].reg_cache = ret; - rt5512_reg_priv[reg].sync_needed = 0; - } - else - ret = rt5512_reg_priv[reg].reg_cache; - - return ret; -} - -static int rt5512_io_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int regval) -{ - int ret; - char data[5] = {0}; - int len = rt5512_reg_priv[reg].reg_size; - int i; - - RT_DBG("reg 0x%02x, val 0x%08x\n", reg, regval); - if (reg == RT5512_VIRTUAL_REG) - { - rt5512_reg_priv[reg].reg_cache = regval; - return 0; - } - - if (len == 8 || len == 16 || len == 20) - { - pr_err("rt5512-codec: not supported reg data size in this write function\n"); - return -EINVAL; - } - else if (len == 0) - { - dev_err(codec->dev, "Invalid reg_addr 0x%02x\n", reg); - return -EINVAL; - } - - data[0] = reg&0xff; - - switch (len) - { - case 1: - data[1] = regval&0xff; - break; - case 4: - for (i=1; i<5; i++) - data[i] = (regval>>(32-8*i))&0xff; - break; - } - - ret = i2c_master_send(codec->control_data, data, 1+len); - if (ret != (1+len)) - { - dev_err(codec->dev, "write register fail\n"); - return -EIO; - } - rt5512_reg_priv[reg].sync_needed = 1; - return 0; -} - -static int rt5512_set_codec_io(struct snd_soc_codec *codec) -{ - struct rt5512_codec_chip *chip = snd_soc_codec_get_drvdata(codec); - - RT_DBG("\n"); - codec->read = rt5512_io_read; - codec->write = rt5512_io_write; - codec->control_data = chip->client; - return 0; -} - -static int rt5512_digital_block_power(struct snd_soc_codec *codec, int pd) -{ - RT_DBG("powerdown = %d\n", pd); - snd_soc_update_bits(codec, 0x80, RT5512_PDBIT_MASK, (pd?RT5512_PDBIT_MASK:0)); - return 0; -} - -static int rt5512_set_bias_level(struct snd_soc_codec *codec, - enum snd_soc_bias_level level) -{ - RT_DBG("bias_level->%d\n",(int)level); - if (codec->dapm.bias_level != level) - { - switch (level) - { - case SND_SOC_BIAS_ON: - case SND_SOC_BIAS_PREPARE: - case SND_SOC_BIAS_STANDBY: - rt5512_digital_block_power(codec, 0); - break; - case SND_SOC_BIAS_OFF: - rt5512_digital_block_power(codec, 1); - break; - default: - dev_err(codec->dev, "not supported bias level\n"); - } - //snd_soc_write(codec, reg, value); - codec->dapm.bias_level = level; - } - else - dev_warn(codec->dev, "the same bias level, no need to change\n"); - return 0; -} - -static void rt5512_codec_reset(struct snd_soc_codec *codec) -{ - RT_DBG("\n"); - snd_soc_update_bits(codec, 0x80, RT5512_RSTBIT_MASK, RT5512_RSTBIT_MASK); -} - -static void rt5512_codec_force_reload_cache(struct snd_soc_codec *codec) -{ - int i; - int ret; - RT_DBG("\n"); - for (i=0; iprivate_data = inode->i_private; - return 0; -} - -static int get_parameters(char *buf, long int *param1, int num_of_par) -{ - char *token; - int base, cnt; - - RT_DBG("\n"); - - token = strsep(&buf, " "); - - for (cnt = 0; cnt < num_of_par; cnt++) { - if (token != NULL) { - if ((token[1] == 'x') || (token[1] == 'X')) - base = 16; - else - base = 10; - - if (strict_strtoul(token, base, ¶m1[cnt]) != 0) - return -EINVAL; - - token = strsep(&buf, " "); - } - else - break; - } - return cnt; -} - -#define STR_4TIMES "0x%02x 0x%02x 0x%02x 0x%02x " - -static ssize_t codec_debug_read(struct file *filp, char __user *ubuf, - size_t count, loff_t *ppos) -{ - char lbuf[200]; - - RT_DBG("\n"); - - switch (read_size) - { - case 1: - snprintf(lbuf, sizeof(lbuf), "0x%02x\n", read_data[0]); - break; - case 4: - snprintf(lbuf, sizeof(lbuf), STR_4TIMES "\n", - read_data[0], read_data[1], read_data[2], read_data[3]); - break; - case 8: - snprintf(lbuf, sizeof(lbuf), STR_4TIMES STR_4TIMES "\n", - read_data[0], read_data[1], read_data[2], read_data[3], - read_data[4], read_data[5], read_data[6], read_data[7]); - break; - case 16: - snprintf(lbuf, sizeof(lbuf), STR_4TIMES STR_4TIMES STR_4TIMES STR_4TIMES "\n", - read_data[0], read_data[1], read_data[2], read_data[3], - read_data[4], read_data[5], read_data[6], read_data[7], - read_data[8], read_data[9], read_data[10], read_data[11], - read_data[12], read_data[13], read_data[14], read_data[15]); - break; - case 20: - snprintf(lbuf, sizeof(lbuf), STR_4TIMES STR_4TIMES STR_4TIMES STR_4TIMES STR_4TIMES "\n", - read_data[0], read_data[1], read_data[2], read_data[3], - read_data[4], read_data[5], read_data[6], read_data[7], - read_data[8], read_data[9], read_data[10], read_data[11], - read_data[12], read_data[13], read_data[14], read_data[15], - read_data[16], read_data[17], read_data[18], read_data[19]); - break; - default: - return 0; - } - return simple_read_from_buffer(ubuf, count, ppos, lbuf, strlen(lbuf)); -} - -static int rt5512_simulate_headset(struct i2c_client *client, int id) -{ - struct rt5512_codec_chip *chip = i2c_get_clientdata(client); - - RT_DBG("id = %d\n", id); - switch (id) - { - case 0: // simulate headset insert - snd_soc_jack_report(chip->rt_jack, SND_JACK_HEADSET, SND_JACK_HEADSET); - break; - case 1: // simulate headset plug out - snd_soc_jack_report(chip->rt_jack, 0, SND_JACK_HEADSET); - break; - case 2: // simulate headphone(no microphone) insert - snd_soc_jack_report(chip->rt_jack, SND_JACK_HEADPHONE, SND_JACK_HEADPHONE); - break; - case 3: // simulate headphone(no microphone) plug out - snd_soc_jack_report(chip->rt_jack, 0, SND_JACK_HEADPHONE); - break; - case 4: // simulate headset jack btn 0 click - snd_soc_jack_report(chip->rt_jack, SND_JACK_BTN_0, SND_JACK_BTN_0); - mdelay(1); - snd_soc_jack_report(chip->rt_jack, 0, SND_JACK_BTN_0); - break; - case 5: // simulate headset jack btn 1 click - snd_soc_jack_report(chip->rt_jack, SND_JACK_BTN_1, SND_JACK_BTN_1); - mdelay(1); - snd_soc_jack_report(chip->rt_jack, 0, SND_JACK_BTN_1); - break; - case 6: // simulate headset jack btn 2 click - snd_soc_jack_report(chip->rt_jack, SND_JACK_BTN_2, SND_JACK_BTN_2); - mdelay(1); - snd_soc_jack_report(chip->rt_jack, 0, SND_JACK_BTN_2); - break; - } - return 0; -} - -static ssize_t codec_debug_write(struct file *filp, - const char __user *ubuf, size_t cnt, loff_t *ppos) -{ - char *access_str = filp->private_data; - char lbuf[200]; - int rc; - long int param[21]; - int i = 0; - int reg_dsize = 0; - - RT_DBG("\n"); - - if (cnt > sizeof(lbuf) - 1) - return -EINVAL; - - rc = copy_from_user(lbuf, ubuf, cnt); - if (rc) - return -EFAULT; - - lbuf[cnt] = '\0'; - - if (!strcmp(access_str, "poke")) { - /* write */ - rc = get_parameters(lbuf, param, 21); - if (rc > 0 && param[0]<=RT5512_MAX_REG && rc == (rt5512_reg_priv[param[0]].reg_size+1)) - { - reg_dsize = rt5512_reg_priv[param[0]].reg_size; - switch (reg_dsize) - { - case 1: - case 4: - case 8: - case 16: - case 20: - for (i = 0; i 0 && param[0] <= RT5512_MAX_REG) - { - reg_dsize = rt5512_reg_priv[param[0]].reg_size; - switch (reg_dsize) - { - case 1: - case 4: - case 8: - case 16: - case 20: - lbuf[0] = (unsigned char)param[0]; - i2c_master_send(this_client, lbuf, 1); - i2c_master_recv(this_client, lbuf, reg_dsize); - for (i=0; i< reg_dsize; i++) - read_data[i] = lbuf[i]; - read_size = reg_dsize; - break; - default: - break; - } - } - else - rc = -EINVAL; - } else if (!strcmp(access_str, "headset_test")) { - rc = get_parameters(lbuf, param, 1); - if (rc > 0) - { - if (param[0] >= 0 && param[0] <= 6) - rt5512_simulate_headset(this_client, param[0]); - else - rc = -EINVAL; - } - else - rc = -EINVAL; - } - - if (rc > 0) - rc = cnt; - - return rc; -} - -static const struct file_operations codec_debug_ops = { - .open = codec_debug_open, - .write = codec_debug_write, - .read = codec_debug_read -}; -#endif - -static int rt5512_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) -{ - int ret; - struct rt5512_codec_chip *chip; - - RT_DBG("\n"); - chip = kzalloc(sizeof(*chip), GFP_KERNEL); - if (!chip) - { - pr_err("%s: could not allocate kernel memory\n", __func__); - return -ENOMEM; - } - - chip->dev = &client->dev; - chip->client = client; - chip->control_type = SND_SOC_I2C; - - i2c_set_clientdata(client, chip); - - ret = snd_soc_register_codec(&client->dev, - &soc_codec_dev_rt5512, rt5512_dai, ARRAY_SIZE(rt5512_dai)); - if (ret < 0) - { - dev_err(&client->dev, "register codec failed\n"); - goto codec_reg_fail; - } - - #ifdef CONFIG_DEBUG_FS - RT_DBG("add debugfs for core debug\n"); - this_client = client; - debugfs_rt_dent = debugfs_create_dir("rt5512_codec_dbg", 0); - if (!IS_ERR(debugfs_rt_dent)) { - debugfs_peek = debugfs_create_file("peek", - S_IFREG | S_IRUGO, debugfs_rt_dent, - (void *) "peek", &codec_debug_ops); - - debugfs_poke = debugfs_create_file("poke", - S_IFREG | S_IRUGO, debugfs_rt_dent, - (void *) "poke", &codec_debug_ops); - - debugfs_headset_test = debugfs_create_file("headset_test", - S_IFREG | S_IRUGO, debugfs_rt_dent, - (void *) "headset_test", &codec_debug_ops); - } - #endif - - pr_info("rt5512-codec driver successfully loaded\n"); - return 0; - -codec_reg_fail: - kfree(chip); - return ret; -} - -static int rt5512_i2c_remove(struct i2c_client *client) -{ - struct rt5512_codec_chip *chip = i2c_get_clientdata(client); - - if (!IS_ERR(debugfs_rt_dent)) - debugfs_remove_recursive(debugfs_rt_dent); - kfree(chip); - return 0; -} - -static const struct i2c_device_id rt5512_i2c_id[] = -{ - {"rt5512", 0}, - {} -}; -MODULE_DEVICE_TABLE(i2c, rt5512_i2c_id); - -struct i2c_driver rt5512_i2c_driver = -{ - .driver = { - .name = "rt5512", - .owner = THIS_MODULE, - }, - .probe = rt5512_i2c_probe, - .remove = rt5512_i2c_remove, - .id_table = rt5512_i2c_id, -}; - -static int __init rt5512_init(void) -{ - return i2c_add_driver(&rt5512_i2c_driver); -} - -static void __exit rt5512_exit(void) -{ - i2c_del_driver(&rt5512_i2c_driver); -} - -module_init(rt5512_init); -module_exit(rt5512_exit); - -MODULE_AUTHOR("cy_huang "); -MODULE_DESCRIPTION("RT5512 audio codec for Rockchip board"); -MODULE_LICENSE("GPL"); -MODULE_VERSION(RT5512_DRV_VER); diff --git a/sound/soc/codecs/rt5512.h b/sound/soc/codecs/rt5512.h deleted file mode 100644 index cb5ce5cad029..000000000000 --- a/sound/soc/codecs/rt5512.h +++ /dev/null @@ -1,50 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __SND_SOC_CODEC_RT5512_H -#define __SND_SOC_CODEC_RT5512_H - -#define RT5512_CODEC_NAME "rt5512-codec" -#define RT5512_DRV_VER "1.0.1_G" - -#define RT5512_CLK_DIV_ID 1 -#define FOR_MID 1 - - -struct rt5512_codec_chip -{ - struct device *dev; - struct i2c_client *client; - struct snd_soc_jack *rt_jack; - enum snd_soc_control_type control_type; - int curr_outpath; - int curr_inpath; -}; - -enum { - OFF, - RCV, - SPK_PATH, - HP_PATH, - HP_NO_MIC, - BT, - SPK_HP, - RING_SPK, - RING_HP, - RING_HP_NO_MIC, - RING_SPK_HP, -}; - -enum { - MIC_OFF, - Main_Mic, - Hands_Free_Mic, - BT_Sco_Mic, -}; - - -#if 1 -#define RT_DBG(format, args...) pr_info("%s:%s() line-%d: " format, RT5512_CODEC_NAME, __FUNCTION__, __LINE__, ##args) -#else -#define RT_DBG(format, args...) -#endif /* #if 1 */ - -#endif /* #ifndef __SND_SOC_CODEC_RT5512_H */ diff --git a/sound/soc/codecs/rt5621.c b/sound/soc/codecs/rt5621.c deleted file mode 100644 index ef4f006604bd..000000000000 --- a/sound/soc/codecs/rt5621.c +++ /dev/null @@ -1,1234 +0,0 @@ -/* - * rt5621.c -- RT5621 ALSA SoC audio codec driver - * - * Copyright 2011 Realtek Semiconductor Corp. - * Author: Johnny Hsu - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -//#include - -#include "rt5621.h" - -#if REALTEK_HWDEP -#include -#include -#endif - -#if 0 -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif - -#define GPIO_HIGH 1 -#define GPIO_LOW 0 -#define INVALID_GPIO -1 - -#define RT5621_VERSION "0.01 alsa 1.0.24" - -int rt5621_spk_ctl_gpio = INVALID_GPIO; -static int caps_charge = 500; -module_param(caps_charge, int, 0); -MODULE_PARM_DESC(caps_charge, "RT5621 cap charge time (msecs)"); - -struct snd_soc_codec *rt5621_codec; - -static void rt5621_work(struct work_struct *work); - -static struct workqueue_struct *rt5621_workq; -static DECLARE_DELAYED_WORK(delayed_work, rt5621_work); - -#define ENABLE_EQ_HREQ 1 - -struct rt5621_priv { - unsigned int sysclk; -}; - -enum { - NORMAL, - CLUB, - DANCE, - LIVE, - POP, - ROCK, - OPPO, - TREBLE, - BASS, - HFREQ, - EQTEST, - SPK_FR -}; - -typedef struct _HW_EQ_PRESET -{ - u16 HwEqType; - u16 EqValue[14]; - u16 HwEQCtrl; - -}HW_EQ_PRESET; - -HW_EQ_PRESET HwEq_Preset[]={ - /* 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x 0x9 0xa 0x 0xc 0x62*/ - {NORMAL,{0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000},0x0000}, - {CLUB ,{0x1C10,0x0000,0xC1CC,0x1E5D,0x0699,0xCD48,0x188D,0x0699,0xC3B6,0x1CD0,0x0699,0x0436,0x0000},0x800E}, - {DANCE ,{0x1F2C,0x095B,0xC071,0x1F95,0x0616,0xC96E,0x1B11,0xFC91,0xDCF2,0x1194,0xFAF2,0x0436,0x0000},0x800F}, - {LIVE ,{0x1EB5,0xFCB6,0xC24A,0x1DF8,0x0E7C,0xC883,0x1C10,0x0699,0xDA41,0x1561,0x0295,0x0436,0x0000},0x800F}, - {POP ,{0x1E98,0xFCB6,0xC340,0x1D60,0x095B,0xC6AC,0x1BBC,0x0556,0x0689,0x0F33,0x0000,0xEDD1,0xF805},0x801F}, - {ROCK ,{0x1EB5,0xFCB6,0xC071,0x1F95,0x0424,0xC30A,0x1D27,0xF900,0x0C5D,0x0FC7,0x0E23,0x0436,0x0000},0x800F}, - {OPPO ,{0x0000,0x0000,0xCA4A,0x17F8,0x0FEC,0xCA4A,0x17F8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000},0x800F}, - {TREBLE,{0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x188D,0x1699},0x8010}, - {BASS ,{0x1A43,0x0C00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000},0x8001}, - {EQTEST,{0x1F8C,0x1830,0xC118,0x1EEF,0xFD77,0xD8CB,0x1BBC,0x0556,0x0689,0x0F33,0x0000,0xF17F,0x0FEC},0x8003}, -}; - -static const u16 rt5621_reg[RT5621_VENDOR_ID2 + 1] = { - [RT5621_RESET] = 0x59b4, - [RT5621_SPK_OUT_VOL] = 0x8080, - [RT5621_HP_OUT_VOL] = 0x8080, - [RT5621_MONO_AUX_OUT_VOL] = 0x8080, - [RT5621_AUXIN_VOL] = 0xe808, - [RT5621_LINE_IN_VOL] = 0xe808, - [RT5621_STEREO_DAC_VOL] = 0xe808, - [RT5621_MIC_VOL] = 0x0808, - [RT5621_MIC_ROUTING_CTRL] = 0xe0e0, - [RT5621_ADC_REC_GAIN] = 0xf58b, - [RT5621_ADC_REC_MIXER] = 0x7f7f, - [RT5621_SOFT_VOL_CTRL_TIME] = 0x000a, - [RT5621_OUTPUT_MIXER_CTRL] = 0xc000, - [RT5621_AUDIO_INTERFACE] = 0x8000, - [RT5621_STEREO_AD_DA_CLK_CTRL] = 0x166d, - [RT5621_ADD_CTRL_REG] = 0x5300, - [RT5621_GPIO_PIN_CONFIG] = 0x1c0e, - [RT5621_GPIO_PIN_POLARITY] = 0x1c0e, - [RT5621_GPIO_PIN_STATUS] = 0x0002, - [RT5621_OVER_TEMP_CURR_STATUS] = 0x003c, - [RT5621_PSEDUEO_SPATIAL_CTRL] = 0x0497, - [RT5621_AVC_CTRL] = 0x000b, - [RT5621_VENDOR_ID1] = 0x10ec, - [RT5621_VENDOR_ID2] = 0x2003, -}; - -#define rt5621_write_mask(c, reg, value, mask) snd_soc_update_bits(c, reg, mask, value) - -#define rt5621_write_index_reg(c, addr, data) \ -{ \ - snd_soc_write(c, 0x6a, addr); \ - snd_soc_write(c, 0x6c, data); \ -} - -static int rt5621_reset(struct snd_soc_codec *codec) -{ - return snd_soc_write(codec, RT5621_RESET, 0); -} - -static int rt5621_volatile_register( - struct snd_soc_codec *codec, unsigned int reg) -{ - switch (reg) { - case RT5621_RESET: - case RT5621_HID_CTRL_DATA: - case RT5621_GPIO_PIN_STATUS: - case RT5621_OVER_TEMP_CURR_STATUS: - return 1; - default: - return 0; - } -} - -static int rt5621_readable_register( - struct snd_soc_codec *codec, unsigned int reg) -{ - switch (reg) { - case RT5621_RESET: - case RT5621_SPK_OUT_VOL: - case RT5621_HP_OUT_VOL: - case RT5621_MONO_AUX_OUT_VOL: - case RT5621_AUXIN_VOL: - case RT5621_LINE_IN_VOL: - case RT5621_STEREO_DAC_VOL: - case RT5621_MIC_VOL: - case RT5621_MIC_ROUTING_CTRL: - case RT5621_ADC_REC_GAIN: - case RT5621_ADC_REC_MIXER: - case RT5621_SOFT_VOL_CTRL_TIME: - case RT5621_OUTPUT_MIXER_CTRL: - case RT5621_MIC_CTRL: - case RT5621_AUDIO_INTERFACE: - case RT5621_STEREO_AD_DA_CLK_CTRL: - case RT5621_COMPANDING_CTRL: - case RT5621_PWR_MANAG_ADD1: - case RT5621_PWR_MANAG_ADD2: - case RT5621_PWR_MANAG_ADD3: - case RT5621_ADD_CTRL_REG: - case RT5621_GLOBAL_CLK_CTRL_REG: - case RT5621_PLL_CTRL: - case RT5621_GPIO_OUTPUT_PIN_CTRL: - case RT5621_GPIO_PIN_CONFIG: - case RT5621_GPIO_PIN_POLARITY: - case RT5621_GPIO_PIN_STICKY: - case RT5621_GPIO_PIN_WAKEUP: - case RT5621_GPIO_PIN_STATUS: - case RT5621_GPIO_PIN_SHARING: - case RT5621_OVER_TEMP_CURR_STATUS: - case RT5621_JACK_DET_CTRL: - case RT5621_MISC_CTRL: - case RT5621_PSEDUEO_SPATIAL_CTRL: - case RT5621_EQ_CTRL: - case RT5621_EQ_MODE_ENABLE: - case RT5621_AVC_CTRL: - case RT5621_HID_CTRL_INDEX: - case RT5621_HID_CTRL_DATA: - case RT5621_VENDOR_ID1: - case RT5621_VENDOR_ID2: - return 1; - default: - return 0; - } -} - - -//static const char *rt5621_spkl_pga[] = {"Vmid","HPL mixer","SPK mixer","Mono Mixer"}; -static const char *rt5621_spkn_source_sel[] = {"RN", "RP", "LN"}; -static const char *rt5621_spk_pga[] = {"Vmid","HP mixer","SPK mixer","Mono Mixer"}; -static const char *rt5621_hpl_pga[] = {"Vmid","HPL mixer"}; -static const char *rt5621_hpr_pga[] = {"Vmid","HPR mixer"}; -static const char *rt5621_mono_pga[] = {"Vmid","HP mixer","SPK mixer","Mono Mixer"}; -static const char *rt5621_amp_type_sel[] = {"Class AB","Class D"}; -static const char *rt5621_mic_boost_sel[] = {"Bypass","20db","30db","40db"}; - -static const struct soc_enum rt5621_enum[] = { -SOC_ENUM_SINGLE(RT5621_OUTPUT_MIXER_CTRL, 14, 3, rt5621_spkn_source_sel), /* spkn source from hp mixer */ -SOC_ENUM_SINGLE(RT5621_OUTPUT_MIXER_CTRL, 10, 4, rt5621_spk_pga), /* spk input sel 1 */ -SOC_ENUM_SINGLE(RT5621_OUTPUT_MIXER_CTRL, 9, 2, rt5621_hpl_pga), /* hp left input sel 2 */ -SOC_ENUM_SINGLE(RT5621_OUTPUT_MIXER_CTRL, 8, 2, rt5621_hpr_pga), /* hp right input sel 3 */ -SOC_ENUM_SINGLE(RT5621_OUTPUT_MIXER_CTRL, 6, 4, rt5621_mono_pga), /* mono input sel 4 */ -SOC_ENUM_SINGLE(RT5621_MIC_CTRL, 10,4, rt5621_mic_boost_sel), /*Mic1 boost sel 5 */ -SOC_ENUM_SINGLE(RT5621_MIC_CTRL, 8,4,rt5621_mic_boost_sel), /*Mic2 boost sel 6 */ -SOC_ENUM_SINGLE(RT5621_OUTPUT_MIXER_CTRL,13,2,rt5621_amp_type_sel), /*Speaker AMP sel 7 */ -}; - -static int rt5621_amp_sel_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - unsigned short val; - unsigned short mask, bitmask; - - for (bitmask = 1; bitmask < e->max; bitmask <<= 1); - - if (ucontrol->value.enumerated.item[0] > e->max - 1) - return -EINVAL; - val = ucontrol->value.enumerated.item[0] << e->shift_l; - mask = (bitmask - 1) << e->shift_l; - if (e->shift_l != e->shift_r) { - if (ucontrol->value.enumerated.item[1] > e->max - 1) - return -EINVAL; - val |= ucontrol->value.enumerated.item[1] << e->shift_r; - mask |= (bitmask - 1) << e->shift_r; - } - - snd_soc_update_bits(codec, e->reg, mask, val); - val &= (0x1 << 13); - - if (val == 0) - { - snd_soc_update_bits(codec, 0x3c, 0x0000, 0x4000); /*power off classd*/ - snd_soc_update_bits(codec, 0x3c, 0x8000, 0x8000); /*power on classab*/ - } else { - snd_soc_update_bits(codec, 0x3c, 0x0000, 0x8000); /*power off classab*/ - snd_soc_update_bits(codec, 0x3c, 0x4000, 0x4000); /*power on classd*/ - } - - return 0; -} - -//***************************************************************************** -// -//function:Change audio codec power status -// -//***************************************************************************** -static int rt5621_ChangeCodecPowerStatus(struct snd_soc_codec *codec,int power_state) -{ - unsigned short int PowerDownState=0; - - switch(power_state) { - case POWER_STATE_D0: //FULL ON-----power on all power - - snd_soc_write(codec,RT5621_PWR_MANAG_ADD1,~PowerDownState); - snd_soc_write(codec,RT5621_PWR_MANAG_ADD2,~PowerDownState); - snd_soc_write(codec,RT5621_PWR_MANAG_ADD3,~PowerDownState); - break; - case POWER_STATE_D1: //LOW ON----- - rt5621_write_mask(codec, RT5621_PWR_MANAG_ADD2 ,PWR_VREF | - PWR_DAC_REF_CIR | PWR_L_DAC_CLK | PWR_R_DAC_CLK | - PWR_L_HP_MIXER | PWR_R_HP_MIXER | PWR_L_ADC_CLK_GAIN | - PWR_R_ADC_CLK_GAIN | PWR_L_ADC_REC_MIXER | PWR_R_ADC_REC_MIXER | - PWR_CLASS_AB, PWR_VREF | PWR_DAC_REF_CIR | PWR_L_DAC_CLK | - PWR_R_DAC_CLK | PWR_L_HP_MIXER | PWR_R_HP_MIXER | - PWR_L_ADC_CLK_GAIN | PWR_R_ADC_CLK_GAIN | - PWR_L_ADC_REC_MIXER | PWR_R_ADC_REC_MIXER | PWR_CLASS_AB); - - rt5621_write_mask(codec, RT5621_PWR_MANAG_ADD3 ,PWR_MAIN_BIAS | - PWR_HP_R_OUT_VOL | PWR_HP_L_OUT_VOL | PWR_SPK_OUT | - PWR_MIC1_FUN_CTRL | PWR_MIC1_BOOST_MIXER, PWR_MAIN_BIAS | - PWR_HP_R_OUT_VOL | PWR_HP_L_OUT_VOL | PWR_SPK_OUT | - PWR_MIC1_FUN_CTRL | PWR_MIC1_BOOST_MIXER); - - rt5621_write_mask(codec, RT5621_PWR_MANAG_ADD1 ,PWR_MAIN_I2S_EN | - PWR_HP_OUT_ENH_AMP | PWR_HP_OUT_AMP | PWR_MIC1_BIAS_EN, - PWR_MAIN_I2S_EN | PWR_HP_OUT_ENH_AMP | PWR_HP_OUT_AMP | - PWR_MIC1_BIAS_EN); - break; - - case POWER_STATE_D1_PLAYBACK: //Low on of Playback - rt5621_write_mask(codec, RT5621_PWR_MANAG_ADD2, PWR_VREF | PWR_DAC_REF_CIR | - PWR_L_DAC_CLK | PWR_R_DAC_CLK | PWR_L_HP_MIXER | PWR_R_HP_MIXER | - PWR_CLASS_AB | PWR_CLASS_D|PWR_SPK_MIXER, PWR_VREF | PWR_DAC_REF_CIR | - PWR_L_DAC_CLK | PWR_R_DAC_CLK | PWR_L_HP_MIXER | PWR_R_HP_MIXER | - PWR_CLASS_AB | PWR_CLASS_D|PWR_SPK_MIXER); - - rt5621_write_mask(codec, RT5621_PWR_MANAG_ADD3, PWR_MAIN_BIAS | - PWR_HP_R_OUT_VOL | PWR_HP_L_OUT_VOL | PWR_SPK_OUT, - PWR_MAIN_BIAS | PWR_HP_R_OUT_VOL | PWR_HP_L_OUT_VOL | PWR_SPK_OUT); - - rt5621_write_mask(codec, RT5621_PWR_MANAG_ADD1, PWR_MAIN_I2S_EN | - PWR_HP_OUT_ENH_AMP | PWR_HP_OUT_AMP, PWR_MAIN_I2S_EN | - PWR_HP_OUT_ENH_AMP | PWR_HP_OUT_AMP); - break; - - case POWER_STATE_D1_RECORD: //Low on of Record - rt5621_write_mask(codec, RT5621_PWR_MANAG_ADD1, PWR_MAIN_I2S_EN | - PWR_MIC1_BIAS_EN, PWR_MAIN_I2S_EN | PWR_MIC1_BIAS_EN); - rt5621_write_mask(codec, RT5621_PWR_MANAG_ADD2, PWR_VREF | - PWR_L_ADC_CLK_GAIN | PWR_R_ADC_CLK_GAIN | PWR_L_ADC_REC_MIXER | - PWR_R_ADC_REC_MIXER, PWR_VREF | PWR_L_ADC_CLK_GAIN | - PWR_R_ADC_CLK_GAIN | PWR_L_ADC_REC_MIXER | PWR_R_ADC_REC_MIXER); - rt5621_write_mask(codec, RT5621_PWR_MANAG_ADD3, PWR_MAIN_BIAS | - PWR_MIC2_BOOST_MIXER | PWR_MIC1_BOOST_MIXER, PWR_MAIN_BIAS | - PWR_MIC2_BOOST_MIXER | PWR_MIC1_BOOST_MIXER); - break; - - case POWER_STATE_D2: //STANDBY---- - rt5621_write_mask(codec, RT5621_PWR_MANAG_ADD1, 0, PWR_MAIN_I2S_EN | - PWR_HP_OUT_ENH_AMP | PWR_HP_OUT_AMP | PWR_MIC1_BIAS_EN); - rt5621_write_mask(codec, RT5621_PWR_MANAG_ADD3, 0, PWR_HP_R_OUT_VOL | - PWR_HP_L_OUT_VOL | PWR_SPK_OUT | PWR_MIC1_FUN_CTRL | - PWR_MIC1_BOOST_MIXER); - rt5621_write_mask(codec, RT5621_PWR_MANAG_ADD2, 0, PWR_DAC_REF_CIR | - PWR_L_DAC_CLK | PWR_R_DAC_CLK | PWR_L_HP_MIXER | PWR_R_HP_MIXER| - PWR_L_ADC_CLK_GAIN | PWR_R_ADC_CLK_GAIN | PWR_L_ADC_REC_MIXER | - PWR_R_ADC_REC_MIXER | PWR_CLASS_AB | PWR_CLASS_D); - break; - - case POWER_STATE_D2_PLAYBACK: //STANDBY of playback - rt5621_write_mask(codec, RT5621_PWR_MANAG_ADD3, 0, /*PWR_HP_R_OUT_VOL | - PWR_HP_L_OUT_VOL |*/ PWR_SPK_OUT); - rt5621_write_mask(codec, RT5621_PWR_MANAG_ADD1, 0, PWR_HP_OUT_ENH_AMP | - PWR_HP_OUT_AMP); - rt5621_write_mask(codec, RT5621_PWR_MANAG_ADD2, 0, PWR_DAC_REF_CIR | - PWR_L_DAC_CLK | PWR_R_DAC_CLK | PWR_L_HP_MIXER | PWR_R_HP_MIXER | - PWR_CLASS_AB | PWR_CLASS_D); - break; - - case POWER_STATE_D2_RECORD: //STANDBY of record - rt5621_write_mask(codec, RT5621_PWR_MANAG_ADD1, 0, PWR_MIC1_BIAS_EN); - rt5621_write_mask(codec, RT5621_PWR_MANAG_ADD2, 0, PWR_L_ADC_CLK_GAIN | - PWR_R_ADC_CLK_GAIN | PWR_L_ADC_REC_MIXER | PWR_R_ADC_REC_MIXER); - rt5621_write_mask(codec, RT5621_PWR_MANAG_ADD3, 0, PWR_MIC2_BOOST_MIXER | - PWR_MIC1_BOOST_MIXER); - break; - - case POWER_STATE_D3: //SLEEP - case POWER_STATE_D4: //OFF----power off all power - rt5621_write_mask(codec, RT5621_PWR_MANAG_ADD1, 0, PWR_HP_OUT_ENH_AMP | - PWR_HP_OUT_AMP); - snd_soc_write(codec, RT5621_PWR_MANAG_ADD3, 0); - snd_soc_write(codec, RT5621_PWR_MANAG_ADD1, 0); - snd_soc_write(codec, RT5621_PWR_MANAG_ADD2, 0); - break; - - default: - break; - } - - return 0; -} - - -//***************************************************************************** -// -//function AudioOutEnable:Mute/Unmute audio out channel -//WavOutPath:output channel -//Mute :Mute/Unmute output channel -// -//***************************************************************************** -static int rt5621_AudioOutEnable(struct snd_soc_codec *codec, - unsigned short int WavOutPath, int Mute) -{ - int RetVal=0; - - if(Mute) { - switch(WavOutPath) { - case RT_WAVOUT_ALL_ON: - RetVal = rt5621_write_mask(codec, RT5621_SPK_OUT_VOL, RT_L_MUTE | RT_R_MUTE, - RT_L_MUTE | RT_R_MUTE); //Mute Speaker right/left channel - RetVal = rt5621_write_mask(codec, RT5621_HP_OUT_VOL, RT_L_MUTE | RT_R_MUTE, - RT_L_MUTE | RT_R_MUTE); //Mute headphone right/left channel - RetVal = rt5621_write_mask(codec, RT5621_MONO_AUX_OUT_VOL, RT_L_MUTE | - RT_R_MUTE, RT_L_MUTE | RT_R_MUTE); //Mute Aux/Mono right/left channel - RetVal = rt5621_write_mask(codec, RT5621_STEREO_DAC_VOL, RT_M_HP_MIXER | - RT_M_SPK_MIXER | RT_M_MONO_MIXER, RT_M_HP_MIXER | - RT_M_SPK_MIXER | RT_M_MONO_MIXER); //Mute DAC to HP,Speaker,Mono Mixer - break; - - case RT_WAVOUT_HP: - RetVal = rt5621_write_mask(codec, RT5621_HP_OUT_VOL, RT_L_MUTE | RT_R_MUTE, - RT_L_MUTE | RT_R_MUTE); //Mute headphone right/left channel - break; - - case RT_WAVOUT_SPK: - RetVal = rt5621_write_mask(codec, RT5621_SPK_OUT_VOL, RT_L_MUTE | RT_R_MUTE, - RT_L_MUTE | RT_R_MUTE); //Mute Speaker right/left channel - break; - - case RT_WAVOUT_AUXOUT: - RetVal = rt5621_write_mask(codec, RT5621_MONO_AUX_OUT_VOL, RT_L_MUTE | - RT_R_MUTE, RT_L_MUTE | RT_R_MUTE); //Mute AuxOut right/left channel - break; - - case RT_WAVOUT_MONO: - - RetVal = rt5621_write_mask(codec, RT5621_MONO_AUX_OUT_VOL, RT_L_MUTE, - RT_L_MUTE); //Mute MonoOut channel - break; - - case RT_WAVOUT_DAC: - RetVal = rt5621_write_mask(codec, RT5621_STEREO_DAC_VOL, RT_M_HP_MIXER | - RT_M_SPK_MIXER | RT_M_MONO_MIXER, RT_M_HP_MIXER | RT_M_SPK_MIXER | - RT_M_MONO_MIXER); //Mute DAC to HP,Speaker,Mono Mixer - break; - - default: - return 0; - } - } else { - switch(WavOutPath) { - case RT_WAVOUT_ALL_ON: - RetVal = rt5621_write_mask(codec, RT5621_SPK_OUT_VOL, 0, RT_L_MUTE | - RT_R_MUTE); //Mute Speaker right/left channel - RetVal = rt5621_write_mask(codec, RT5621_HP_OUT_VOL, 0, RT_L_MUTE | - RT_R_MUTE); //Mute headphone right/left channel - RetVal = rt5621_write_mask(codec, RT5621_MONO_AUX_OUT_VOL, 0, RT_L_MUTE | - RT_R_MUTE); //Mute Aux/Mono right/left channel - RetVal = rt5621_write_mask(codec, RT5621_STEREO_DAC_VOL, 0, RT_M_HP_MIXER | - RT_M_SPK_MIXER | RT_M_MONO_MIXER); //Mute DAC to HP,Speaker,Mono Mixer - break; - case RT_WAVOUT_HP: - RetVal = rt5621_write_mask(codec, RT5621_HP_OUT_VOL, 0, RT_L_MUTE | - RT_R_MUTE); //UnMute headphone right/left channel - break; - - case RT_WAVOUT_SPK: - RetVal = rt5621_write_mask(codec, RT5621_SPK_OUT_VOL, 0, RT_L_MUTE | - RT_R_MUTE); //unMute Speaker right/left channel - break; - case RT_WAVOUT_AUXOUT: - RetVal = rt5621_write_mask(codec, RT5621_MONO_AUX_OUT_VOL, 0, RT_L_MUTE | - RT_R_MUTE); //unMute AuxOut right/left channel - break; - - case RT_WAVOUT_MONO: - RetVal = rt5621_write_mask(codec, RT5621_MONO_AUX_OUT_VOL, 0, - RT_L_MUTE); //unMute MonoOut channel - break; - - case RT_WAVOUT_DAC: - RetVal = rt5621_write_mask(codec, RT5621_STEREO_DAC_VOL, 0, RT_M_HP_MIXER | - RT_M_SPK_MIXER | RT_M_MONO_MIXER); //unMute DAC to HP,Speaker,Mono Mixer - break; - default: - return 0; - } - - } - - return RetVal; -} - - -//***************************************************************************** -// -//function:Enable/Disable ADC input source control -// -//***************************************************************************** -static int Enable_ADC_Input_Source(struct snd_soc_codec *codec,unsigned short int ADC_Input_Sour,int Enable) -{ - int bRetVal=0; - - if(Enable) { - //Enable ADC source - bRetVal=rt5621_write_mask(codec,RT5621_ADC_REC_MIXER,0,ADC_Input_Sour); - } else { - //Disable ADC source - bRetVal=rt5621_write_mask(codec,RT5621_ADC_REC_MIXER,ADC_Input_Sour,ADC_Input_Sour); - } - - return bRetVal; -} - -static void rt5621_update_eqmode(struct snd_soc_codec *codec, int mode) -{ - u16 HwEqIndex=0; - - if (mode == NORMAL) { - /*clear EQ parameter*/ - for (HwEqIndex=0; HwEqIndex<=0x0C; HwEqIndex++) { - - rt5621_write_index_reg(codec, HwEqIndex, HwEq_Preset[mode].EqValue[HwEqIndex]) - } - - snd_soc_write(codec, 0x62, 0x0); /*disable EQ block*/ - } else { - snd_soc_write(codec, 0x62, HwEq_Preset[mode].HwEQCtrl); - - /*Fill EQ parameter*/ - for (HwEqIndex=0; HwEqIndex<=0x0C; HwEqIndex++) { - - rt5621_write_index_reg(codec, HwEqIndex, HwEq_Preset[mode].EqValue[HwEqIndex]) - } - //update EQ parameter - snd_soc_write(codec, 0x66, 0x1f); - schedule_timeout_uninterruptible(msecs_to_jiffies(1)); - snd_soc_write(codec, 0x66, 0x0); - } -} - -static const struct snd_kcontrol_new rt5621_snd_controls[] = { -SOC_DOUBLE("Speaker Playback Volume", RT5621_SPK_OUT_VOL, 8, 0, 31, 1), -SOC_DOUBLE("Speaker Playback Switch", RT5621_SPK_OUT_VOL, 15, 7, 1, 1), -SOC_DOUBLE("Headphone Playback Volume", RT5621_HP_OUT_VOL, 8, 0, 31, 1), -SOC_DOUBLE("Headphone Playback Switch", RT5621_HP_OUT_VOL,15, 7, 1, 1), -SOC_DOUBLE("AUX Playback Volume", RT5621_MONO_AUX_OUT_VOL, 8, 0, 31, 1), -SOC_DOUBLE("AUX Playback Switch", RT5621_MONO_AUX_OUT_VOL, 15, 7, 1, 1), -SOC_DOUBLE("PCM Playback Volume", RT5621_STEREO_DAC_VOL, 8, 0, 31, 1), -SOC_DOUBLE("Line In Volume", RT5621_LINE_IN_VOL, 8, 0, 31, 1), -SOC_SINGLE("Mic 1 Volume", RT5621_MIC_VOL, 8, 31, 1), -SOC_SINGLE("Mic 2 Volume", RT5621_MIC_VOL, 0, 31, 1), -SOC_ENUM("Mic 1 Boost", rt5621_enum[5]), -SOC_ENUM("Mic 2 Boost", rt5621_enum[6]), -SOC_ENUM_EXT("Speaker Amp Type", rt5621_enum[7], snd_soc_get_enum_double, rt5621_amp_sel_put), -SOC_DOUBLE("AUX In Volume", RT5621_AUXIN_VOL, 8, 0, 31, 1), -SOC_DOUBLE("Capture Volume", RT5621_ADC_REC_GAIN, 7, 0, 31, 0), -}; - -void hp_depop_mode2(struct snd_soc_codec *codec) -{ - snd_soc_update_bits(codec, 0x3e, 0x8000, 0x8000); - snd_soc_update_bits(codec, 0x04, 0x8080, 0x8080); - snd_soc_update_bits(codec, 0x3a, 0x0100, 0x0100); - snd_soc_update_bits(codec, 0x3c, 0x2000, 0x2000); - snd_soc_update_bits(codec, 0x3e, 0x0600, 0x0600); - snd_soc_update_bits(codec, 0x5e, 0x0200, 0x0200); - schedule_timeout_uninterruptible(msecs_to_jiffies(300)); -} - -void aux_depop_mode2(struct snd_soc_codec *codec) -{ - snd_soc_update_bits(codec, 0x3e, 0x8000, 0x8000); - snd_soc_update_bits(codec, 0x06, 0x8080, 0x8080); - snd_soc_update_bits(codec, 0x3a, 0x0100, 0x0100); - snd_soc_update_bits(codec, 0x3c, 0x2000, 0x2000); - snd_soc_update_bits(codec, 0x3e, 0x6000, 0x6000); - snd_soc_update_bits(codec, 0x5e, 0x0020, 0x0200); - schedule_timeout_uninterruptible(msecs_to_jiffies(300)); - snd_soc_update_bits(codec, 0x3a, 0x0002, 0x0002); - snd_soc_update_bits(codec, 0x3a, 0x0001, 0x0001); -} - -static int rt5621_pcm_hw_prepare(struct snd_pcm_substream *substream, - struct snd_soc_dai *codec_dai) -{ - - struct snd_soc_codec *codec = codec_dai->codec; - int stream = substream->stream; - - switch (stream) - { - case SNDRV_PCM_STREAM_PLAYBACK: - - rt5621_ChangeCodecPowerStatus(codec,POWER_STATE_D1_PLAYBACK); //power on dac to hp and speaker out - - rt5621_AudioOutEnable(codec,RT_WAVOUT_SPK,0); //unmute speaker out - - rt5621_AudioOutEnable(codec,RT_WAVOUT_HP,0); //unmute hp - - rt5621_AudioOutEnable(codec,RT_WAVOUT_AUXOUT,0); //unmute auxout out - - break; - case SNDRV_PCM_STREAM_CAPTURE: - - rt5621_ChangeCodecPowerStatus(codec,POWER_STATE_D1_RECORD); //power on input to adc - - Enable_ADC_Input_Source(codec,RT_WAVIN_L_MIC1|RT_WAVIN_R_MIC1,1); //enable record source from mic1 - - break; - } - - return 0; -} - -/* PLL divisors */ -struct _pll_div { - u32 pll_in; - u32 pll_out; - u16 regvalue; -}; - -static const struct _pll_div codec_pll_div[] = { - - { 2048000, 8192000, 0x0ea0}, - { 3686400, 8192000, 0x4e27}, - { 12000000, 8192000, 0x456b}, - { 13000000, 8192000, 0x495f}, - { 13100000, 8192000, 0x0320}, - { 2048000, 11289600, 0xf637}, - { 3686400, 11289600, 0x2f22}, - { 12000000, 11289600, 0x3e2f}, - { 13000000, 11289600, 0x4d5b}, - { 13100000, 11289600, 0x363b}, - { 2048000, 16384000, 0x1ea0}, - { 3686400, 16384000, 0x9e27}, - { 12000000, 16384000, 0x452b}, - { 13000000, 16384000, 0x542f}, - { 13100000, 16384000, 0x03a0}, - { 2048000, 16934400, 0xe625}, - { 3686400, 16934400, 0x9126}, - { 12000000, 16934400, 0x4d2c}, - { 13000000, 16934400, 0x742f}, - { 13100000, 16934400, 0x3c27}, - { 2048000, 22579200, 0x2aa0}, - { 3686400, 22579200, 0x2f20}, - { 12000000, 22579200, 0x7e2f}, - { 13000000, 22579200, 0x742f}, - { 13100000, 22579200, 0x3c27}, - { 2048000, 24576000, 0x2ea0}, - { 3686400, 24576000, 0xee27}, - { 12000000, 24576000, 0x2915}, - { 13000000, 24576000, 0x772e}, - { 13100000, 24576000, 0x0d20}, -}; - -static const struct _pll_div codec_bclk_pll_div[] = { - - { 1536000, 24576000, 0x3ea0}, - { 3072000, 24576000, 0x1ea0}, - { 512000, 24576000, 0x8e90}, - { 256000, 24576000, 0xbe80}, - { 2822400, 11289600, 0x1ee0}, - { 3072000, 12288000, 0x1ee0}, -}; - - -static int rt5621_set_dai_pll(struct snd_soc_dai *dai, - int pll_id,int source, unsigned int freq_in, unsigned int freq_out) -{ - int i; - int ret = -EINVAL; - struct snd_soc_codec *codec = dai->codec; - - if (pll_id < RT5621_PLL_FR_MCLK || pll_id > RT5621_PLL_FR_BCLK) - return -EINVAL; - - //rt5621_write_mask(codec,RT5621_PWR_MANAG_ADD2, 0x0000,0x1000); //disable PLL power - - if (!freq_in || !freq_out) { - - return 0; - } - - if (RT5621_PLL_FR_MCLK == pll_id) { - for (i = 0; i < ARRAY_SIZE(codec_pll_div); i++) { - - if (codec_pll_div[i].pll_in == freq_in && codec_pll_div[i].pll_out == freq_out) - { - snd_soc_update_bits(codec, RT5621_GLOBAL_CLK_CTRL_REG, 0x0000, 0x4000); - snd_soc_write(codec,RT5621_PLL_CTRL,codec_pll_div[i].regvalue);//set PLL parameter - snd_soc_update_bits(codec,RT5621_PWR_MANAG_ADD2, 0x1000,0x1000); //enable PLL power - ret = 0; - } - } - } - else if (RT5621_PLL_FR_BCLK == pll_id) - { - for (i = 0; i < ARRAY_SIZE(codec_bclk_pll_div); i++) - { - if ((freq_in == codec_bclk_pll_div[i].pll_in) && (freq_out == codec_bclk_pll_div[i].pll_out)) - { - snd_soc_update_bits(codec, RT5621_GLOBAL_CLK_CTRL_REG, 0x4000, 0x4000); - snd_soc_write(codec,RT5621_PLL_CTRL,codec_bclk_pll_div[i].regvalue);//set PLL parameter - snd_soc_update_bits(codec,RT5621_PWR_MANAG_ADD2, 0x1000,0x1000); //enable PLL power - ret = 0; - } - } - } - - snd_soc_update_bits(codec,RT5621_GLOBAL_CLK_CTRL_REG,0x8000,0x8000);//Codec sys-clock from PLL - return ret; -} - - -struct _coeff_div { - u32 mclk; - u32 rate; - u16 fs; - u16 regvalue; -}; - -/* codec hifi mclk (after PLL) clock divider coefficients */ -static const struct _coeff_div coeff_div[] = { - /* 8k */ - { 8192000, 8000, 256*4, 0x2a2d}, - {12288000, 8000, 384*4, 0x2c2f}, - - /* 11.025k */ - {11289600, 11025, 256*4, 0x2a2d}, - {16934400, 11025, 384*4, 0x2c2f}, - - /* 16k */ - {12288000, 16000, 384*2, 0x1c2f}, - {16384000, 16000, 256*4, 0x2a2d}, - {24576000, 16000, 384*4, 0x2c2f}, - - /* 22.05k */ - {11289600, 22050, 256*2, 0x1a2d}, - {16934400, 22050, 384*2, 0x1c2f}, - - /* 32k */ - {12288000, 32000, 384 , 0x0c2f}, - {16384000, 32000, 256*2, 0x1a2d}, - {24576000, 32000, 384*2, 0x1c2f}, - - /* 44.1k */ - {11289600, 44100, 256*1, 0x0a2d}, - {22579200, 44100, 256*2, 0x1a2d}, - {45158400, 44100, 256*4, 0x2a2d}, - - /* 48k */ - {12288000, 48000, 256*1, 0x0a2d}, - {24576000, 48000, 256*2, 0x1a2d}, - {49152000, 48000, 256*4, 0x2a2d}, - - //MCLK is 24.576Mhz(for 8k,16k,32k) - {24576000, 8000, 384*8, 0x3c6b}, - {24576000, 16000, 384*4, 0x2c6b}, - {24576000, 32000, 384*2, 0x1c6b}, - - //MCLK is 22.5792mHz(for 11k,22k) - {22579200, 11025, 256*8, 0x3a2d}, - {22579200, 22050, 256*4, 0x2a2d}, -}; - - - -static int get_coeff(int mclk, int rate) -{ - int i; - - DBG("get_coeff mclk=%d,rate=%d\n",mclk,rate); - - for (i = 0; i < ARRAY_SIZE(coeff_div); i++) { - if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk) - return i; - } - return -EINVAL; -} - - -/* - * Clock after PLL and dividers - */ - /*in this driver, you have to set sysclk to be 24576000, - * but you don't need to give a clk to be 24576000, our - * internal pll will generate this clock! so it won't make - * you any difficult. - */ -static int rt5621_set_dai_sysclk(struct snd_soc_dai *dai, - int clk_id, unsigned int freq, int dir) -{ - struct snd_soc_codec *codec = dai->codec; - struct rt5621_priv *rt5621 = snd_soc_codec_get_drvdata(codec); - - if ((freq >= (256 * 8000)) && (freq <= (512 * 48000))) { - rt5621->sysclk = freq; - return 0; - } - - printk("unsupported sysclk freq %u for audio i2s\n", freq); - - return -EINVAL; -} - - -static int rt5621_set_dai_fmt(struct snd_soc_dai *dai, - unsigned int fmt) -{ - struct snd_soc_codec *codec = dai->codec; - u16 iface = 0; - - /* set master/slave audio interface */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: - iface = 0x0000; - break; - case SND_SOC_DAIFMT_CBS_CFS: - iface = 0x8000; - break; - default: - return -EINVAL; - } - - /* interface format */ - switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_I2S: - iface |= 0x0000; - break; - case SND_SOC_DAIFMT_RIGHT_J: - iface |= 0x0001; - break; - case SND_SOC_DAIFMT_LEFT_J: - iface |= 0x0002; - break; - case SND_SOC_DAIFMT_DSP_A: - iface |= 0x0003; - break; - case SND_SOC_DAIFMT_DSP_B: - iface |= 0x4003; - break; - default: - return -EINVAL; - } - - /* clock inversion */ - switch (fmt & SND_SOC_DAIFMT_INV_MASK) { - case SND_SOC_DAIFMT_NB_NF: - iface |= 0x0000; - break; - case SND_SOC_DAIFMT_IB_NF: - iface |= 0x0100; - break; - default: - return -EINVAL; - } - - snd_soc_write(codec,RT5621_AUDIO_INTERFACE,iface); - return 0; -} - - -static int rt5621_pcm_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) -{ - struct snd_soc_codec *codec = dai->codec; - struct rt5621_priv *rt5621 = snd_soc_codec_get_drvdata(codec); - u16 iface = snd_soc_read(codec,RT5621_AUDIO_INTERFACE)&0xfff3; - int coeff = get_coeff(rt5621->sysclk, params_rate(params)); - - DBG("rt5621_pcm_hw_params\n"); - if (coeff < 0) - coeff = get_coeff(24576000, params_rate(params)); /*if not set sysclk, default to be 24.576MHz*/ - - /* bit size */ - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: - iface |= 0x0000; - break; - case SNDRV_PCM_FORMAT_S20_3LE: - iface |= 0x0004; - break; - case SNDRV_PCM_FORMAT_S24_LE: - iface |= 0x0008; - break; - case SNDRV_PCM_FORMAT_S32_LE: - iface |= 0x000c; - break; - } - - /* set iface & srate */ - snd_soc_write(codec, RT5621_AUDIO_INTERFACE, iface); - - if (coeff >= 0) - snd_soc_write(codec, RT5621_STEREO_AD_DA_CLK_CTRL, coeff_div[coeff].regvalue); - else - { - printk(KERN_ERR "cant find matched sysclk and rate config\n"); - return -EINVAL; - - } - return 0; -} - -static int rt5621_set_bias_level(struct snd_soc_codec *codec, - enum snd_soc_bias_level level) -{ - switch (level) { - case SND_SOC_BIAS_ON: - snd_soc_update_bits(codec, RT5621_SPK_OUT_VOL, RT_L_MUTE | RT_R_MUTE, 0); - snd_soc_update_bits(codec, RT5621_HP_OUT_VOL, RT_L_MUTE | RT_R_MUTE, 0); - break; - - case SND_SOC_BIAS_PREPARE: - break; - - case SND_SOC_BIAS_STANDBY: - snd_soc_update_bits(codec, RT5621_SPK_OUT_VOL, RT_L_MUTE | RT_R_MUTE, RT_L_MUTE | RT_R_MUTE); - snd_soc_update_bits(codec, RT5621_HP_OUT_VOL, RT_L_MUTE | RT_R_MUTE, RT_L_MUTE | RT_R_MUTE); - if (SND_SOC_BIAS_OFF == codec->dapm.bias_level) { - snd_soc_write(codec, RT5621_PWR_MANAG_ADD3, 0x8000);//enable Main bias - snd_soc_write(codec, RT5621_PWR_MANAG_ADD2, 0x2000);//enable Vref - codec->cache_only = false; - snd_soc_cache_sync(codec); - } - break; - - case SND_SOC_BIAS_OFF: - snd_soc_update_bits(codec, RT5621_SPK_OUT_VOL, RT_L_MUTE | RT_R_MUTE, RT_L_MUTE | RT_R_MUTE); - snd_soc_update_bits(codec, RT5621_HP_OUT_VOL, RT_L_MUTE | RT_R_MUTE, RT_L_MUTE | RT_R_MUTE); - snd_soc_write(codec, RT5621_PWR_MANAG_ADD3, 0x0000); - snd_soc_write(codec, RT5621_PWR_MANAG_ADD2, 0x0000); - snd_soc_write(codec, RT5621_PWR_MANAG_ADD1, 0x0000); - break; - - default: - break; - } - codec->dapm.bias_level = level; - - return 0; -} - - - -struct rt5621_init_reg{ - - u8 reg_index; - u16 reg_value; -}; - -static struct rt5621_init_reg init_data[] = { - {RT5621_AUDIO_INTERFACE, 0x8000}, //set I2S codec to slave mode - {RT5621_STEREO_DAC_VOL, 0x0808}, //default stereo DAC volume to 0db - {RT5621_OUTPUT_MIXER_CTRL, 0x2b40}, //default output mixer control - {RT5621_ADC_REC_MIXER, 0x3f3f}, //set record source is Mic1 by default - {RT5621_MIC_CTRL, 0x0a00}, //set Mic1,Mic2 boost 20db - {RT5621_SPK_OUT_VOL, 0x8080}, //default speaker volume to 0db - {RT5621_HP_OUT_VOL, 0x8080}, //default HP volume to -12db - {RT5621_ADD_CTRL_REG, 0x4b00}, //Class AB/D speaker ratio is 1.25VDD - {RT5621_STEREO_AD_DA_CLK_CTRL, 0x066d}, //set Dac filter to 256fs - {RT5621_ADC_REC_GAIN, 0xfa95}, //set ADC boost to 15db - {RT5621_HID_CTRL_INDEX, 0x46}, //Class D setting - {RT5621_MIC_VOL, 0x0808}, - {RT5621_MIC_ROUTING_CTRL, 0xf0e0}, - {RT5621_HID_CTRL_DATA, 0xFFFF}, //power on Class D Internal register - {RT5621_JACK_DET_CTRL, 0x4810}, //power on Class D Internal register -}; -#define RT5621_INIT_REG_NUM ARRAY_SIZE(init_data) - -static int rt5621_reg_init(struct snd_soc_codec *codec) -{ - int i; - - for (i = 0; i < RT5621_INIT_REG_NUM; i++) - snd_soc_write(codec, init_data[i].reg_index, init_data[i].reg_value); - - return 0; -} - -static void rt5621_work(struct work_struct *work) -{ - struct snd_soc_codec *codec = rt5621_codec; - - rt5621_set_bias_level(codec, codec->dapm.bias_level); -} - -static int rt5621_probe(struct snd_soc_codec *codec) -{ - int ret; - - printk("##################### %s ######################\n", __FUNCTION__); - - ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); - if (ret != 0) { - dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); - return ret; - } - codec->cache_bypass = 1; - - rt5621_reset(codec); - snd_soc_write(codec, RT5621_PWR_MANAG_ADD3, 0x8000);//enable Main bias - snd_soc_write(codec, RT5621_PWR_MANAG_ADD2, 0x2000);//enable Vref - hp_depop_mode2(codec); - rt5621_reg_init(codec); - -#if ENABLE_EQ_HREQ - - rt5621_write_index_reg(codec, 0x11,0x1); - rt5621_write_index_reg(codec, 0x12,0x1); - rt5621_update_eqmode(codec, HFREQ); - -#endif - rt5621_workq = create_freezable_workqueue("rt5621"); - if (rt5621_workq == NULL) { - printk("wm8900_probe::create_freezeable_workqueue ERROR !"); - kfree(codec); - return -ENOMEM; - } - - rt5621_set_bias_level(codec, SND_SOC_BIAS_PREPARE); - codec->dapm.bias_level = SND_SOC_BIAS_STANDBY; - - queue_delayed_work(rt5621_workq, &delayed_work, - msecs_to_jiffies(caps_charge)); - - codec->dapm.bias_level = SND_SOC_BIAS_STANDBY; - - rt5621_codec = codec; - - return 0; -} - -static int rt5621_remove(struct snd_soc_codec *codec) -{ - rt5621_set_bias_level(codec, SND_SOC_BIAS_OFF); - - cancel_delayed_work_sync(&delayed_work); - return 0; -} - -#ifdef CONFIG_PM -static int rt5621_suspend(struct snd_soc_codec *codec) -{ - rt5621_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - -static int rt5621_resume(struct snd_soc_codec *codec) -{ - - rt5621_reset(codec); - snd_soc_write(codec, RT5621_PWR_MANAG_ADD3, 0x8000);//enable Main bias - snd_soc_write(codec, RT5621_PWR_MANAG_ADD2, 0x2000);//enable Vref - - hp_depop_mode2(codec); - - rt5621_reg_init(codec); - -#if ENABLE_EQ_HREQ - - rt5621_write_index_reg(codec, 0x11,0x1); - rt5621_write_index_reg(codec, 0x12,0x1); - rt5621_update_eqmode(codec, HFREQ); -#endif - - rt5621_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - if (codec->dapm.suspend_bias_level == SND_SOC_BIAS_ON) { - rt5621_set_bias_level(codec, SND_SOC_BIAS_PREPARE); - codec->dapm.bias_level = SND_SOC_BIAS_ON; - queue_delayed_work(rt5621_workq, &delayed_work, - msecs_to_jiffies(caps_charge)); - } - return 0; -} -#else -#define rt5621_suspend NULL -#define rt5621_resume NULL -#endif - -static void rt5621_shutdown(struct snd_pcm_substream *substream, - struct snd_soc_dai *codec_dai) -{ - struct snd_soc_codec *codec = codec_dai->codec; - int stream = substream->stream; - - switch (stream) - { - case SNDRV_PCM_STREAM_PLAYBACK: - - rt5621_AudioOutEnable(codec,RT_WAVOUT_SPK,1); //mute speaker out - - rt5621_AudioOutEnable(codec,RT_WAVOUT_HP,1); //mute hp out - - rt5621_AudioOutEnable(codec,RT_WAVOUT_AUXOUT,1); //mute auxout - - rt5621_ChangeCodecPowerStatus(codec,POWER_STATE_D2_PLAYBACK); //power off dac to hp and speaker out and auxout - - - - break; - case SNDRV_PCM_STREAM_CAPTURE: - - Enable_ADC_Input_Source(codec,RT_WAVIN_L_MIC1|RT_WAVIN_R_MIC1,0); //disable record source from mic1 - - rt5621_ChangeCodecPowerStatus(codec,POWER_STATE_D2_RECORD); - - - break; - } -} - -//#define RT5621_HIFI_RATES SNDRV_PCM_RATE_8000_48000 -#define RT5621_HIFI_RATES (SNDRV_PCM_RATE_44100) // zyy 20110704, playback and record use same sample rate - -#define RT5621_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ - SNDRV_PCM_FMTBIT_S24_LE) - -struct snd_soc_dai_ops rt5621_hifi_ops = { - .hw_params = rt5621_pcm_hw_params, - .set_fmt = rt5621_set_dai_fmt, - .set_sysclk = rt5621_set_dai_sysclk, - .set_pll = rt5621_set_dai_pll, - .prepare = rt5621_pcm_hw_prepare, - .shutdown = rt5621_shutdown, -}; - -struct snd_soc_dai_driver rt5621_dai = { - .name = "RT5621 HiFi", - .playback = { - .stream_name = "HiFi Playback", - .channels_min = 1, - .channels_max = 2, - .rates = RT5621_HIFI_RATES, - .formats = RT5621_FORMATS, - }, - .capture = { - .stream_name = "HiFi Capture", - .channels_min = 1, - .channels_max = 2, - .rates = RT5621_HIFI_RATES, - .formats = RT5621_FORMATS, - }, - .ops = &rt5621_hifi_ops, -}; - -static struct snd_soc_codec_driver soc_codec_dev_rt5621 = { - .probe = rt5621_probe, - .remove = rt5621_remove, - .suspend = rt5621_suspend, - .resume = rt5621_resume, - .set_bias_level = rt5621_set_bias_level, - .reg_cache_size = RT5621_VENDOR_ID2 + 1, - .reg_word_size = sizeof(u16), - .reg_cache_default = rt5621_reg, - .volatile_register = rt5621_volatile_register, - .readable_register = rt5621_readable_register, - .reg_cache_step = 1, - .controls = rt5621_snd_controls, - .num_controls = ARRAY_SIZE(rt5621_snd_controls), -}; - -static const struct i2c_device_id rt5621_i2c_id[] = { - { "rt5621", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, rt5621_i2c_id); - -/* -dts: - codec@1a { - compatible = "rt5621"; - reg = <0x1a>; - spk-ctl-gpio = <&gpio6 GPIO_B6 GPIO_ACTIVE_HIGH>; - }; -*/ -static int rt5621_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) -{ - struct rt5621_priv *rt5621; - int ret; - - printk("##################### %s ######################\n", __FUNCTION__); - -#ifdef CONFIG_OF - rt5621_spk_ctl_gpio= of_get_named_gpio_flags(i2c->dev.of_node, "spk-ctl-gpio", 0, NULL); - if (rt5621_spk_ctl_gpio < 0) { - DBG("%s() Can not read property spk-ctl-gpio\n", __FUNCTION__); - rt5621_spk_ctl_gpio = INVALID_GPIO; - } -#endif //#ifdef CONFIG_OF - - ret = gpio_request(rt5621_spk_ctl_gpio, "spk_con"); - if(ret < 0){ - printk("gpio request spk_con error!\n"); - } - else{ - printk("########################### set spk_con HIGH ##################################\n"); - gpio_direction_output(rt5621_spk_ctl_gpio, GPIO_HIGH); - gpio_set_value(rt5621_spk_ctl_gpio, GPIO_HIGH); - } - - rt5621 = kzalloc(sizeof(struct rt5621_priv), GFP_KERNEL); - if (NULL == rt5621) - return -ENOMEM; - - i2c_set_clientdata(i2c, rt5621); - - ret = snd_soc_register_codec(&i2c->dev, - &soc_codec_dev_rt5621, &rt5621_dai, 1); - if (ret < 0) - kfree(rt5621); - - return ret; -} - -static int rt5621_i2c_remove(struct i2c_client *i2c) -{ - snd_soc_unregister_codec(&i2c->dev); - kfree(i2c_get_clientdata(i2c)); - return 0; -} - -struct i2c_driver rt5621_i2c_driver = { - .driver = { - .name = "RT5621", - .owner = THIS_MODULE, - }, - .probe = rt5621_i2c_probe, - .remove = rt5621_i2c_remove, - .id_table = rt5621_i2c_id, -}; - -static int __init rt5621_modinit(void) -{ - return i2c_add_driver(&rt5621_i2c_driver); -} -module_init(rt5621_modinit); - -static void __exit rt5621_modexit(void) -{ - i2c_del_driver(&rt5621_i2c_driver); -} -module_exit(rt5621_modexit); - -MODULE_DESCRIPTION("ASoC RT5621 driver"); -MODULE_AUTHOR("Johnny Hsu "); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/rt5621.h b/sound/soc/codecs/rt5621.h deleted file mode 100644 index 9c1459c89360..000000000000 --- a/sound/soc/codecs/rt5621.h +++ /dev/null @@ -1,515 +0,0 @@ -/* - * rt5621.h -- RT5621 ALSA SoC audio driver - * - * Copyright 2011 Realtek Microelectronics - * Author: Johnny Hsu - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef __RT5621_H__ -#define __RT5621_H__ - -#define RT5621_RESET 0X00 //RESET CODEC TO DEFAULT -#define RT5621_SPK_OUT_VOL 0X02 //SPEAKER OUT VOLUME -#define RT5621_HP_OUT_VOL 0X04 //HEADPHONE OUTPUT VOLUME -#define RT5621_MONO_AUX_OUT_VOL 0X06 //MONO OUTPUT/AUXOUT VOLUME -#define RT5621_AUXIN_VOL 0X08 //AUXIN VOLUME -#define RT5621_LINE_IN_VOL 0X0A //LINE IN VOLUME -#define RT5621_STEREO_DAC_VOL 0X0C //STEREO DAC VOLUME -#define RT5621_MIC_VOL 0X0E //MICROPHONE VOLUME -#define RT5621_MIC_ROUTING_CTRL 0X10 //MIC ROUTING CONTROL -#define RT5621_ADC_REC_GAIN 0X12 //ADC RECORD GAIN -#define RT5621_ADC_REC_MIXER 0X14 //ADC RECORD MIXER CONTROL -#define RT5621_SOFT_VOL_CTRL_TIME 0X16 //SOFT VOLUME CONTROL TIME -#define RT5621_OUTPUT_MIXER_CTRL 0X1C //OUTPUT MIXER CONTROL -#define RT5621_MIC_CTRL 0X22 //MICROPHONE CONTROL -#define RT5621_AUDIO_INTERFACE 0X34 //AUDIO INTERFACE -#define RT5621_STEREO_AD_DA_CLK_CTRL 0X36 //STEREO AD/DA CLOCK CONTROL -#define RT5621_COMPANDING_CTRL 0X38 //COMPANDING CONTROL -#define RT5621_PWR_MANAG_ADD1 0X3A //POWER MANAGMENT ADDITION 1 -#define RT5621_PWR_MANAG_ADD2 0X3C //POWER MANAGMENT ADDITION 2 -#define RT5621_PWR_MANAG_ADD3 0X3E //POWER MANAGMENT ADDITION 3 -#define RT5621_ADD_CTRL_REG 0X40 //ADDITIONAL CONTROL REGISTER -#define RT5621_GLOBAL_CLK_CTRL_REG 0X42 //GLOBAL CLOCK CONTROL REGISTER -#define RT5621_PLL_CTRL 0X44 //PLL CONTROL -#define RT5621_GPIO_OUTPUT_PIN_CTRL 0X4A //GPIO OUTPUT PIN CONTROL -#define RT5621_GPIO_PIN_CONFIG 0X4C //GPIO PIN CONFIGURATION -#define RT5621_GPIO_PIN_POLARITY 0X4E //GPIO PIN POLARITY/TYPE -#define RT5621_GPIO_PIN_STICKY 0X50 //GPIO PIN STICKY -#define RT5621_GPIO_PIN_WAKEUP 0X52 //GPIO PIN WAKE UP -#define RT5621_GPIO_PIN_STATUS 0X54 //GPIO PIN STATUS -#define RT5621_GPIO_PIN_SHARING 0X56 //GPIO PIN SHARING -#define RT5621_OVER_TEMP_CURR_STATUS 0X58 //OVER TEMPERATURE AND CURRENT STATUS -#define RT5621_JACK_DET_CTRL 0X5A //JACK DETECT CONTROL REGISTER -#define RT5621_MISC_CTRL 0X5E //MISC CONTROL -#define RT5621_PSEDUEO_SPATIAL_CTRL 0X60 //PSEDUEO STEREO & SPATIAL EFFECT BLOCK CONTROL -#define RT5621_EQ_CTRL 0X62 //EQ CONTROL -#define RT5621_EQ_MODE_ENABLE 0X66 //EQ MODE CHANGE ENABLE -#define RT5621_AVC_CTRL 0X68 //AVC CONTROL -#define RT5621_HID_CTRL_INDEX 0X6A //HIDDEN CONTROL INDEX PORT -#define RT5621_HID_CTRL_DATA 0X6C //HIDDEN CONTROL DATA PORT -#define RT5621_VENDOR_ID1 0x7C //VENDOR ID1 -#define RT5621_VENDOR_ID2 0x7E //VENDOR ID2 - - -//global definition -#define RT_L_MUTE (0x1<<15) //MUTE LEFT CONTROL BIT -#define RT_L_ZC (0x1<<14) //LEFT ZERO CROSS CONTROL BIT -#define RT_L_SM (0x1<<13) //LEFT SOFTMUTE CONTROL BIT -#define RT_R_MUTE (0x1<<7) //MUTE RIGHT CONTROL BIT -#define RT_R_ZC (0x1<<6) //RIGHT ZERO CROSS CONTROL BIT -#define RT_R_SM (0x1<<5) //RIGHT SOFTMUTE CONTROL BIT -#define RT_M_HP_MIXER (0x1<<15) //Mute source to HP Mixer -#define RT_M_SPK_MIXER (0x1<<14) //Mute source to Speaker Mixer -#define RT_M_MONO_MIXER (0x1<<13) //Mute source to Mono Mixer -#define SPK_CLASS_AB 0 -#define SPK_CLASS_D 1 - -//Mic Routing Control(0x10) -#define M_MIC1_TO_HP_MIXER (0x1<<15) //Mute MIC1 to HP mixer -#define M_MIC1_TO_SPK_MIXER (0x1<<14) //Mute MiC1 to SPK mixer -#define M_MIC1_TO_MONO_MIXER (0x1<<13) //Mute MIC1 to MONO mixer -#define MIC1_DIFF_INPUT_CTRL (0x1<<12) //MIC1 different input control -#define M_MIC2_TO_HP_MIXER (0x1<<7) //Mute MIC2 to HP mixer -#define M_MIC2_TO_SPK_MIXER (0x1<<6) //Mute MiC2 to SPK mixer -#define M_MIC2_TO_MONO_MIXER (0x1<<5) //Mute MIC2 to MONO mixer -#define MIC2_DIFF_INPUT_CTRL (0x1<<4) //MIC2 different input control - -//ADC Record Gain(0x12) -#define M_ADC_L_TO_HP_MIXER (0x1<<15) //Mute left of ADC to HP Mixer -#define M_ADC_R_TO_HP_MIXER (0x1<<14) //Mute right of ADC to HP Mixer -#define M_ADC_L_TO_MONO_MIXER (0x1<<13) //Mute left of ADC to MONO Mixer -#define M_ADC_R_TO_MONO_MIXER (0x1<<12) //Mute right of ADC to MONO Mixer -#define ADC_L_GAIN_MASK (0x1f<<7) //ADC Record Gain Left channel Mask -#define ADC_L_ZC_DET (0x1<<6) //ADC Zero-Cross Detector Control -#define ADC_R_ZC_DET (0x1<<5) //ADC Zero-Cross Detector Control -#define ADC_R_GAIN_MASK (0x1f<<0) //ADC Record Gain Right channel Mask - -//ADC Input Mixer Control(0x14) -#define M_MIC1_TO_ADC_L_MIXER (0x1<<14) //Mute mic1 to left channel of ADC mixer -#define M_MIC2_TO_ADC_L_MIXER (0x1<<13) //Mute mic2 to left channel of ADC mixer -#define M_LINEIN_L_TO_ADC_L_MIXER (0x1<<12) //Mute line In left channel to left channel of ADC mixer -#define M_AUXIN_L_TO_ADC_L_MIXER (0x1<<11) //Mute aux In left channel to left channel of ADC mixer -#define M_HPMIXER_L_TO_ADC_L_MIXER (0x1<<10) //Mute HP mixer left channel to left channel of ADC mixer -#define M_SPKMIXER_L_TO_ADC_L_MIXER (0x1<<9) //Mute SPK mixer left channel to left channel of ADC mixer -#define M_MONOMIXER_L_TO_ADC_L_MIXER (0x1<<8) //Mute MONO mixer left channel to left channel of ADC mixer -#define M_MIC1_TO_ADC_R_MIXER (0x1<<6) //Mute mic1 to right channel of ADC mixer -#define M_MIC2_TO_ADC_R_MIXER (0x1<<5) //Mute mic2 to right channel of ADC mixer -#define M_LINEIN_R_TO_ADC_R_MIXER (0x1<<4) //Mute lineIn right channel to right channel of ADC mixer -#define M_AUXIN_R_TO_ADC_R_MIXER (0x1<<3) //Mute aux In right channel to right channel of ADC mixer -#define M_HPMIXER_R_TO_ADC_R_MIXER (0x1<<2) //Mute HP mixer right channel to right channel of ADC mixer -#define M_SPKMIXER_R_TO_ADC_R_MIXER (0x1<<1) //Mute SPK mixer right channel to right channel of ADC mixer -#define M_MONOMIXER_R_TO_ADC_R_MIXER (0x1<<0) //Mute MONO mixer right channel to right channel of ADC mixer - -//Output Mixer Control(0x1C) -#define SPKOUT_N_SOUR_MASK (0x3<<14) -#define SPKOUT_N_SOUR_LN (0x2<<14) -#define SPKOUT_N_SOUR_RP (0x1<<14) -#define SPKOUT_N_SOUR_RN (0x0<<14) -#define SPK_OUTPUT_CLASS_AB (0x0<<13) -#define SPK_OUTPUT_CLASS_D (0x1<<13) -#define SPK_CLASS_AB_S_AMP (0x0<<12) -#define SPK_CALSS_AB_W_AMP (0x1<<12) -#define SPKOUT_INPUT_SEL_MASK (0x3<<10) -#define SPKOUT_INPUT_SEL_MONOMIXER (0x3<<10) -#define SPKOUT_INPUT_SEL_SPKMIXER (0x2<<10) -#define SPKOUT_INPUT_SEL_HPMIXER (0x1<<10) -#define SPKOUT_INPUT_SEL_VMID (0x0<<10) -#define HPL_INPUT_SEL_HPLMIXER (0x1<<9) -#define HPR_INPUT_SEL_HPRMIXER (0x1<<8) -#define MONO_AUX_INPUT_SEL_MASK (0x3<<6) -#define MONO_AUX_INPUT_SEL_MONO (0x3<<6) -#define MONO_AUX_INPUT_SEL_SPK (0x2<<6) -#define MONO_AUX_INPUT_SEL_HP (0x1<<6) -#define MONO_AUX_INPUT_SEL_VMID (0x0<<6) - -//Micphone Control define(0x22) -#define MIC1 1 -#define MIC2 2 -#define MIC_BIAS_90_PRECNET_AVDD 1 -#define MIC_BIAS_75_PRECNET_AVDD 2 - -#define MIC1_BOOST_CTRL_MASK (0x3<<10) -#define MIC1_BOOST_CTRL_BYPASS (0x0<<10) -#define MIC1_BOOST_CTRL_20DB (0x1<<10) -#define MIC1_BOOST_CTRL_30DB (0x2<<10) -#define MIC1_BOOST_CTRL_40DB (0x3<<10) - -#define MIC2_BOOST_CTRL_MASK (0x3<<8) -#define MIC2_BOOST_CTRL_BYPASS (0x0<<8) -#define MIC2_BOOST_CTRL_20DB (0x1<<8) -#define MIC2_BOOST_CTRL_30DB (0x2<<8) -#define MIC2_BOOST_CTRL_40DB (0x3<<8) - -#define MICBIAS_VOLT_CTRL_MASK (0x1<<5) -#define MICBIAS_VOLT_CTRL_90P (0x0<<5) -#define MICBIAS_VOLT_CTRL_75P (0x1<<5) - -#define MICBIAS_SHORT_CURR_DET_MASK (0x3) -#define MICBIAS_SHORT_CURR_DET_600UA (0x0) -#define MICBIAS_SHORT_CURR_DET_1200UA (0x1) -#define MICBIAS_SHORT_CURR_DET_1800UA (0x2) - -//Audio Interface(0x34) -#define SDP_MASTER_MODE (0x0<<15) //Main I2S interface select Master mode -#define SDP_SLAVE_MODE (0x1<<15) //Main I2S interface select Slave mode -#define I2S_PCM_MODE (0x1<<14) //PCM 0:mode A ,1:mode B -#define MAIN_I2S_BCLK_POL_CTRL (0x1<<7) //0:Normal 1:Invert -#define ADC_DATA_L_R_SWAP (0x1<<5) //0:ADC data appear at left phase of LRCK - //1:ADC data appear at right phase of LRCK -#define DAC_DATA_L_R_SWAP (0x1<<4) //0:DAC data appear at left phase of LRCK - //1:DAC data appear at right phase of LRCK -//Data Length Slection -#define I2S_DL_MASK (0x3<<2) //main i2s Data Length mask -#define I2S_DL_16 (0x0<<2) //16 bits -#define I2S_DL_20 (0x1<<2) //20 bits -#define I2S_DL_24 (0x2<<2) //24 bits -#define I2S_DL_32 (0x3<<2) //32 bits - -//PCM Data Format Selection -#define I2S_DF_MASK (0x3) //main i2s Data Format mask -#define I2S_DF_I2S (0x0) //I2S FORMAT -#define I2S_DF_RIGHT (0x1) //RIGHT JUSTIFIED format -#define I2S_DF_LEFT (0x2) //LEFT JUSTIFIED format -#define I2S_DF_PCM (0x3) //PCM format - -//Stereo AD/DA Clock Control(0x36h) -#define I2S_PRE_DIV_MASK (0x7<<12) -#define I2S_PRE_DIV_1 (0x0<<12) //DIV 1 -#define I2S_PRE_DIV_2 (0x1<<12) //DIV 2 -#define I2S_PRE_DIV_4 (0x2<<12) //DIV 4 -#define I2S_PRE_DIV_8 (0x3<<12) //DIV 8 -#define I2S_PRE_DIV_16 (0x4<<12) //DIV 16 -#define I2S_PRE_DIV_32 (0x5<<12) //DIV 32 - -#define I2S_SCLK_DIV_MASK (0x7<<9) -#define I2S_SCLK_DIV_1 (0x0<<9) //DIV 1 -#define I2S_SCLK_DIV_2 (0x1<<9) //DIV 2 -#define I2S_SCLK_DIV_3 (0x2<<9) //DIV 3 -#define I2S_SCLK_DIV_4 (0x3<<9) //DIV 4 -#define I2S_SCLK_DIV_6 (0x4<<9) //DIV 6 -#define I2S_SCLK_DIV_8 (0x5<<9) //DIV 8 -#define I2S_SCLK_DIV_12 (0x6<<9) //DIV 12 -#define I2S_SCLK_DIV_16 (0x7<<9) //DIV 16 - -#define I2S_WCLK_DIV_PRE_MASK (0xF<<5) -#define I2S_WCLK_PRE_DIV_1 (0x0<<5) //DIV 1 -#define I2S_WCLK_PRE_DIV_2 (0x1<<5) //DIV 2 -#define I2S_WCLK_PRE_DIV_3 (0x2<<5) //DIV 3 -#define I2S_WCLK_PRE_DIV_4 (0x3<<5) //DIV 4 -#define I2S_WCLK_PRE_DIV_5 (0x4<<5) //DIV 5 -#define I2S_WCLK_PRE_DIV_6 (0x5<<5) //DIV 6 -#define I2S_WCLK_PRE_DIV_7 (0x6<<5) //DIV 7 -#define I2S_WCLK_PRE_DIV_8 (0x7<<5) //DIV 8 -//........................ - -#define I2S_WCLK_DIV_MASK (0x7<<2) -#define I2S_WCLK_DIV_2 (0x0<<2) //DIV 2 -#define I2S_WCLK_DIV_4 (0x1<<2) //DIV 4 -#define I2S_WCLK_DIV_8 (0x2<<2) //DIV 8 -#define I2S_WCLK_DIV_16 (0x3<<2) //DIV 16 -#define I2S_WCLK_DIV_32 (0x4<<2) //DIV 32 - -#define ADDA_FILTER_CLK_SEL_256FS (0<<1) //256FS -#define ADDA_FILTER_CLK_SEL_384FS (1<<1) //384FS - -#define ADDA_OSR_SEL_64FS (0) //64FS -#define ADDA_OSR_SEL_128FS (1) //128FS - -//Power managment addition 1 (0x3A),0:Disable,1:Enable -#define PWR_MAIN_I2S_EN (0x1<<15) -#define PWR_ZC_DET_PD_EN (0x1<<14) -#define PWR_MIC1_BIAS_EN (0x1<<11) -#define PWR_SHORT_CURR_DET_EN (0x1<<10) -#define PWR_SOFTGEN_EN (0x1<<8) -#define PWR_DEPOP_BUF_HP (0x1<<6) -#define PWR_HP_OUT_AMP (0x1<<5) -#define PWR_HP_OUT_ENH_AMP (0x1<<4) -#define PWR_DEPOP_BUF_AUX (0x1<<2) -#define PWR_AUX_OUT_AMP (0x1<<1) -#define PWR_AUX_OUT_ENH_AMP (0x1) - - -//Power managment addition 2(0x3C),0:Disable,1:Enable -#define PWR_CLASS_AB (0x1<<15) -#define PWR_CLASS_D (0x1<<14) -#define PWR_VREF (0x1<<13) -#define PWR_PLL (0x1<<12) -#define PWR_DAC_REF_CIR (0x1<<10) -#define PWR_L_DAC_CLK (0x1<<9) -#define PWR_R_DAC_CLK (0x1<<8) -#define PWR_L_ADC_CLK_GAIN (0x1<<7) -#define PWR_R_ADC_CLK_GAIN (0x1<<6) -#define PWR_L_HP_MIXER (0x1<<5) -#define PWR_R_HP_MIXER (0x1<<4) -#define PWR_SPK_MIXER (0x1<<3) -#define PWR_MONO_MIXER (0x1<<2) -#define PWR_L_ADC_REC_MIXER (0x1<<1) -#define PWR_R_ADC_REC_MIXER (0x1) - -//Power managment addition 3(0x3E),0:Disable,1:Enable -#define PWR_MAIN_BIAS (0x1<<15) -#define PWR_AUXOUT_L_VOL_AMP (0x1<<14) -#define PWR_AUXOUT_R_VOL_AMP (0x1<<13) -#define PWR_SPK_OUT (0x1<<12) -#define PWR_HP_L_OUT_VOL (0x1<<10) -#define PWR_HP_R_OUT_VOL (0x1<<9) -#define PWR_LINEIN_L_VOL (0x1<<7) -#define PWR_LINEIN_R_VOL (0x1<<6) -#define PWR_AUXIN_L_VOL (0x1<<5) -#define PWR_AUXIN_R_VOL (0x1<<4) -#define PWR_MIC1_FUN_CTRL (0x1<<3) -#define PWR_MIC2_FUN_CTRL (0x1<<2) -#define PWR_MIC1_BOOST_MIXER (0x1<<1) -#define PWR_MIC2_BOOST_MIXER (0x1) - - -//Additional Control Register(0x40) -#define AUXOUT_SEL_DIFF (0x1<<15) //Differential Mode -#define AUXOUT_SEL_SE (0x1<<15) //Single-End Mode - -#define SPK_AB_AMP_CTRL_MASK (0x7<<12) -#define SPK_AB_AMP_CTRL_RATIO_225 (0x0<<12) //2.25 Vdd -#define SPK_AB_AMP_CTRL_RATIO_200 (0x1<<12) //2.00 Vdd -#define SPK_AB_AMP_CTRL_RATIO_175 (0x2<<12) //1.75 Vdd -#define SPK_AB_AMP_CTRL_RATIO_150 (0x3<<12) //1.50 Vdd -#define SPK_AB_AMP_CTRL_RATIO_125 (0x4<<12) //1.25 Vdd -#define SPK_AB_AMP_CTRL_RATIO_100 (0x5<<12) //1.00 Vdd - -#define SPK_D_AMP_CTRL_MASK (0x3<<10) -#define SPK_D_AMP_CTRL_RATIO_175 (0x0<<10) //1.75 Vdd -#define SPK_D_AMP_CTRL_RATIO_150 (0x1<<10) //1.50 Vdd -#define SPK_D_AMP_CTRL_RATIO_125 (0x2<<10) //1.25 Vdd -#define SPK_D_AMP_CTRL_RATIO_100 (0x3<<10) //1.00 Vdd - -#define STEREO_DAC_HI_PASS_FILTER_EN (0x1<<9) //Stereo DAC high pass filter enable -#define STEREO_ADC_HI_PASS_FILTER_EN (0x1<<8) //Stereo ADC high pass filter enable - -#define DIG_VOL_BOOST_MASK (0x3<<4) //Digital volume Boost mask -#define DIG_VOL_BOOST_0DB (0x0<<4) //Digital volume Boost 0DB -#define DIG_VOL_BOOST_6DB (0x1<<4) //Digital volume Boost 6DB -#define DIG_VOL_BOOST_12DB (0x2<<4) //Digital volume Boost 12DB -#define DIG_VOL_BOOST_18DB (0x3<<4) //Digital volume Boost 18DB - - -//Global Clock Control Register(0x42) -#define SYSCLK_SOUR_SEL_MASK (0x1<<15) -#define SYSCLK_SOUR_SEL_MCLK (0x0<<15) //system Clock source from MCLK -#define SYSCLK_SOUR_SEL_PLL (0x1<<15) //system Clock source from PLL -#define PLLCLK_SOUR_SEL_MCLK (0x0<<14) //PLL clock source from MCLK -#define PLLCLK_SOUR_SEL_BITCLK (0x1<<14) //PLL clock source from BITCLK - -#define PLLCLK_DIV_RATIO_MASK (0x3<<1) -#define PLLCLK_DIV_RATIO_DIV1 (0x0<<1) //DIV 1 -#define PLLCLK_DIV_RATIO_DIV2 (0x1<<1) //DIV 2 -#define PLLCLK_DIV_RATIO_DIV4 (0x2<<1) //DIV 4 -#define PLLCLK_DIV_RATIO_DIV8 (0x3<<1) //DIV 8 - -#define PLLCLK_PRE_DIV1 (0x0) //DIV 1 -#define PLLCLK_PRE_DIV2 (0x1) //DIV 2 - -//PLL Control(0x44) - -#define PLL_CTRL_M_VAL(m) ((m)&0xf) -#define PLL_CTRL_K_VAL(k) (((k)&0x7)<<4) -#define PLL_CTRL_N_VAL(n) (((n)&0xff)<<8) - -//GPIO Pin Configuration(0x4C) -#define GPIO_PIN_MASK (0x1<<1) -#define GPIO_PIN_SET_INPUT (0x1<<1) -#define GPIO_PIN_SET_OUTPUT (0x0<<1) - -//Pin Sharing(0x56) -#define LINEIN_L_PIN_SHARING (0x1<<15) -#define LINEIN_L_PIN_AS_LINEIN_L (0x0<<15) -#define LINEIN_L_PIN_AS_JD1 (0x1<<15) - -#define LINEIN_R_PIN_SHARING (0x1<<14) -#define LINEIN_R_PIN_AS_LINEIN_R (0x0<<14) -#define LINEIN_R_PIN_AS_JD2 (0x1<<14) - -#define GPIO_PIN_SHARING (0x3) -#define GPIO_PIN_AS_GPIO (0x0) -#define GPIO_PIN_AS_IRQOUT (0x1) -#define GPIO_PIN_AS_PLLOUT (0x3) - -//Jack Detect Control Register(0x5A) -#define JACK_DETECT_MASK (0x3<<14) -#define JACK_DETECT_USE_JD2 (0x3<<14) -#define JACK_DETECT_USE_JD1 (0x2<<14) -#define JACK_DETECT_USE_GPIO (0x1<<14) -#define JACK_DETECT_OFF (0x0<<14) - -#define SPK_EN_IN_HI (0x1<<11) -#define AUX_R_EN_IN_HI (0x1<<10) -#define AUX_L_EN_IN_HI (0x1<<9) -#define HP_EN_IN_HI (0x1<<8) -#define SPK_EN_IN_LO (0x1<<7) -#define AUX_R_EN_IN_LO (0x1<<6) -#define AUX_L_EN_IN_LO (0x1<<5) -#define HP_EN_IN_LO (0x1<<4) - -////MISC CONTROL(0x5E) -#define DISABLE_FAST_VREG (0x1<<15) -#define SPK_CLASS_AB_OC_PD (0x1<<13) -#define SPK_CLASS_AB_OC_DET (0x1<<12) -#define HP_DEPOP_MODE3_EN (0x1<<10) -#define HP_DEPOP_MODE2_EN (0x1<<9) -#define HP_DEPOP_MODE1_EN (0x1<<8) -#define AUXOUT_DEPOP_MODE3_EN (0x1<<6) -#define AUXOUT_DEPOP_MODE2_EN (0x1<<5) -#define AUXOUT_DEPOP_MODE1_EN (0x1<<4) -#define M_DAC_L_INPUT (0x1<<3) -#define M_DAC_R_INPUT (0x1<<2) -#define IRQOUT_INV_CTRL (0x1<<0) - -//Psedueo Stereo & Spatial Effect Block Control(0x60) -#define SPATIAL_CTRL_EN (0x1<<15) -#define ALL_PASS_FILTER_EN (0x1<<14) -#define PSEUDO_STEREO_EN (0x1<<13) -#define STEREO_EXPENSION_EN (0x1<<12) - -#define GAIN_3D_PARA_L_MASK (0x7<<9) -#define GAIN_3D_PARA_L_1_00 (0x0<<9) -#define GAIN_3D_PARA_L_1_25 (0x1<<9) -#define GAIN_3D_PARA_L_1_50 (0x2<<9) -#define GAIN_3D_PARA_L_1_75 (0x3<<9) -#define GAIN_3D_PARA_L_2_00 (0x4<<9) - -#define GAIN_3D_PARA_R_MASK (0x7<<6) -#define GAIN_3D_PARA_R_1_00 (0x0<<6) -#define GAIN_3D_PARA_R_1_25 (0x1<<6) -#define GAIN_3D_PARA_R_1_50 (0x2<<6) -#define GAIN_3D_PARA_R_1_75 (0x3<<6) -#define GAIN_3D_PARA_R_2_00 (0x4<<6) - -#define RATIO_3D_L_MASK (0x3<<4) -#define RATIO_3D_L_0_0 (0x0<<4) -#define RATIO_3D_L_0_66 (0x1<<4) -#define RATIO_3D_L_1_0 (0x2<<4) - -#define RATIO_3D_R_MASK (0x3<<2) -#define RATIO_3D_R_0_0 (0x0<<2) -#define RATIO_3D_R_0_66 (0x1<<2) -#define RATIO_3D_R_1_0 (0x2<<2) - -#define APF_MASK (0x3) -#define APF_FOR_48K (0x3) -#define APF_FOR_44_1K (0x2) -#define APF_FOR_32K (0x1) - -//EQ CONTROL(0x62) - -#define EN_HW_EQ_BLK (0x1<<15) //HW EQ block control -#define EN_HW_EQ_HPF_MODE (0x1<<14) //High Frequency shelving filter mode -#define EN_HW_EQ_SOUR (0x1<<11) //0:DAC PATH,1:ADC PATH -#define EN_HW_EQ_HPF (0x1<<4) //EQ High Pass Filter Control -#define EN_HW_EQ_BP3 (0x1<<3) //EQ Band-3 Control -#define EN_HW_EQ_BP2 (0x1<<2) //EQ Band-2 Control -#define EN_HW_EQ_BP1 (0x1<<1) //EQ Band-1 Control -#define EN_HW_EQ_LPF (0x1<<0) //EQ Low Pass Filter Control - -//EQ Mode Change Enable(0x66) -#define EQ_HPF_CHANGE_EN (0x1<<4) //EQ High Pass Filter Mode Change Enable -#define EQ_BP3_CHANGE_EN (0x1<<3) //EQ Band-3 Pass Filter Mode Change Enable -#define EQ_BP2_CHANGE_EN (0x1<<2) //EQ Band-2 Pass Filter Mode Change Enable -#define EQ_BP1_CHANGE_EN (0x1<<1) //EQ Band-1 Pass Filter Mode Change Enable -#define EQ_LPF_CHANGE_EN (0x1<<0) //EQ Low Pass Filter Mode Change Enable - - -//AVC Control(0x68) -#define AVC_ENABLE (0x1<<15) -#define AVC_TARTGET_SEL_MASK (0x1<<14) -#define AVC_TARTGET_SEL_R (0x1<<14) -#define AVC_TARTGET_SEL_L (0x0<<14) - - -#define RT5621_PLL_FR_MCLK 0 -#define RT5621_PLL_FR_BCLK 1 - - -#define REALTEK_HWDEP 0 - -//WaveOut channel for realtek codec -enum -{ - RT_WAVOUT_SPK =(0x1<<0), - RT_WAVOUT_SPK_R =(0x1<<1), - RT_WAVOUT_SPK_L =(0x1<<2), - RT_WAVOUT_HP =(0x1<<3), - RT_WAVOUT_HP_R =(0x1<<4), - RT_WAVOUT_HP_L =(0x1<<5), - RT_WAVOUT_MONO =(0x1<<6), - RT_WAVOUT_AUXOUT =(0x1<<7), - RT_WAVOUT_AUXOUT_R =(0x1<<8), - RT_WAVOUT_AUXOUT_L =(0x1<<9), - RT_WAVOUT_LINEOUT =(0x1<<10), - RT_WAVOUT_LINEOUT_R =(0x1<<11), - RT_WAVOUT_LINEOUT_L =(0x1<<12), - RT_WAVOUT_DAC =(0x1<<13), - RT_WAVOUT_ALL_ON =(0x1<<14), -}; - -//WaveIn channel for realtek codec -enum -{ - RT_WAVIN_R_MONO_MIXER =(0x1<<0), - RT_WAVIN_R_SPK_MIXER =(0x1<<1), - RT_WAVIN_R_HP_MIXER =(0x1<<2), - RT_WAVIN_R_PHONE =(0x1<<3), - RT_WAVIN_R_AUXIN =(0x1<<3), - RT_WAVIN_R_LINE_IN =(0x1<<4), - RT_WAVIN_R_MIC2 =(0x1<<5), - RT_WAVIN_R_MIC1 =(0x1<<6), - - RT_WAVIN_L_MONO_MIXER =(0x1<<8), - RT_WAVIN_L_SPK_MIXER =(0x1<<9), - RT_WAVIN_L_HP_MIXER =(0x1<<10), - RT_WAVIN_L_PHONE =(0x1<<11), - RT_WAVIN_L_AUXIN =(0x1<<11), - RT_WAVIN_L_LINE_IN =(0x1<<12), - RT_WAVIN_L_MIC2 =(0x1<<13), - RT_WAVIN_L_MIC1 =(0x1<<14), -}; - -enum -{ - POWER_STATE_D0=0, - POWER_STATE_D1, - POWER_STATE_D1_PLAYBACK, - POWER_STATE_D1_RECORD, - POWER_STATE_D2, - POWER_STATE_D2_PLAYBACK, - POWER_STATE_D2_RECORD, - POWER_STATE_D3, - POWER_STATE_D4 - -}; - -#if REALTEK_HWDEP - -struct rt56xx_reg_state -{ - unsigned int reg_index; - unsigned int reg_value; -}; - -struct rt56xx_cmd -{ - size_t number; - struct rt56xx_reg_state __user *buf; -}; - -enum -{ - RT_READ_CODEC_REG_IOCTL = _IOR('R', 0x01, struct rt56xx_cmd), - RT_READ_ALL_CODEC_REG_IOCTL = _IOR('R', 0x02, struct rt56xx_cmd), - RT_WRITE_CODEC_REG_IOCTL = _IOW('R', 0x03, struct rt56xx_cmd), -}; - -#endif - -#endif /* __RT5621_H__ */ diff --git a/sound/soc/codecs/rt5623.c b/sound/soc/codecs/rt5623.c deleted file mode 100755 index 899a2be7b225..000000000000 --- a/sound/soc/codecs/rt5623.c +++ /dev/null @@ -1,206 +0,0 @@ -/* - * rt5623.c -- RT5623 ALSA SoC audio codec driver - * - * Copyright 2011 Realtek Semiconductor Corp. - * Author: Johnny Hsu - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "rt5623.h" - -#define MODEM_ON 1 -#define MODEM_OFF 0 - -static struct i2c_client *i2c_client; -static int status; - -static int codec_write(struct i2c_client *client, unsigned int reg, - unsigned int value) -{ - u8 data[3]; - - data[0] = reg; - data[1] = (value >> 8) & 0xff; - data[2] = value & 0xff; - - //printk("%s: reg=0x%x value=0x%x\n",__func__,reg,value); - if (i2c_master_send(client, data, 3) == 3) - return 0; - else - return -EIO; -} - -static unsigned int codec_read(struct i2c_client *client, - unsigned int r) -{ - struct i2c_msg xfer[2]; - u8 reg = r; - u16 data; - int ret; - - /* Write register */ - xfer[0].addr = client->addr; - xfer[0].flags = 0; - xfer[0].len = 1; - xfer[0].buf = ® - xfer[0].scl_rate = 100 * 1000; - - /* Read data */ - xfer[1].addr = client->addr; - xfer[1].flags = I2C_M_RD; - xfer[1].len = 2; - xfer[1].buf = (u8 *)&data; - xfer[1].scl_rate = 100 * 1000; - - ret = i2c_transfer(client->adapter, xfer, 2); - if (ret != 2) { - dev_err(&client->dev, "i2c_transfer() returned %d\n", ret); - return 0; - } - //printk("%s: reg=0x%x value=0x%x\n",__func__,reg,(data >> 8) | ((data & 0xff) << 8)); - - return (data >> 8) | ((data & 0xff) << 8); -} - -struct rt5623_reg { - u8 reg_index; - u16 reg_value; -}; - -static struct rt5623_reg init_data[] = { - {RT5623_PWR_MANAG_ADD3 , 0x8000}, - {RT5623_PWR_MANAG_ADD2 , 0x2000}, - {RT5623_LINE_IN_VOL , 0xa808}, - {RT5623_STEREO_DAC_VOL , 0x6808}, - {RT5623_OUTPUT_MIXER_CTRL , 0x1400}, - {RT5623_ADC_REC_GAIN , 0xf58b}, - {RT5623_ADC_REC_MIXER , 0x7d7d}, - {RT5623_AUDIO_INTERFACE , 0x8083}, - {RT5623_STEREO_AD_DA_CLK_CTRL , 0x0a2d}, - {RT5623_PWR_MANAG_ADD1 , 0x8000}, - {RT5623_PWR_MANAG_ADD2 , 0xb7f3}, - {RT5623_PWR_MANAG_ADD3 , 0x90c0}, - {RT5623_SPK_OUT_VOL , 0x0000}, - {RT5623_PLL_CTRL , 0x481f}, - {RT5623_GLOBAL_CLK_CTRL_REG , 0x8000}, - {RT5623_STEREO_AD_DA_CLK_CTRL , 0x3a2d}, -}; -#define RT5623_INIT_REG_NUM ARRAY_SIZE(init_data) - -static int rt5623_reg_init(struct i2c_client *client) -{ - int i; - - for (i = 0; i < RT5623_INIT_REG_NUM; i++) - codec_write(client, init_data[i].reg_index, - init_data[i].reg_value); - - return 0; -} - -static int rt5623_reset(struct i2c_client *client) -{ - return codec_write(client, RT5623_RESET, 0); -} - -void rt5623_on(void) -{ - if(status == MODEM_OFF) - { - printk("enter %s\n",__func__); - rt5623_reset(i2c_client); - rt5623_reg_init(i2c_client); - status = MODEM_ON; - } -} -EXPORT_SYMBOL(rt5623_on); - -void rt5623_off(void) -{ - if(status == MODEM_ON) - { - printk("enter %s\n",__func__); - codec_write(i2c_client, RT5623_SPK_OUT_VOL, 0x8080); - rt5623_reset(i2c_client); - codec_write(i2c_client, RT5623_PWR_MANAG_ADD3, 0x0000); - codec_write(i2c_client, RT5623_PWR_MANAG_ADD2, 0x0000); - codec_write(i2c_client, RT5623_PWR_MANAG_ADD1, 0x0000); - status = MODEM_OFF; - } -} -EXPORT_SYMBOL(rt5623_off); - -static const struct i2c_device_id rt5623_i2c_id[] = { - { "rt5623", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, rt5623_i2c_id); - - -static int rt5623_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) -{ - pr_info("%s(%d)\n", __func__, __LINE__); - - i2c_client = i2c; - rt5623_reset(i2c); - status = MODEM_ON; - rt5623_off( ); - return 0; -} - -static int rt5623_i2c_remove(struct i2c_client *i2c) -{ - return 0; -} - -struct i2c_driver rt5623_i2c_driver = { - .driver = { - .name = "rt5623", - .owner = THIS_MODULE, - }, - .probe = rt5623_i2c_probe, - .remove = rt5623_i2c_remove, - .id_table = rt5623_i2c_id, -}; - -static int __init rt5623_modinit(void) -{ - return i2c_add_driver(&rt5623_i2c_driver); -} -late_initcall(rt5623_modinit); - -static void __exit rt5623_modexit(void) -{ - i2c_del_driver(&rt5623_i2c_driver); -} -module_exit(rt5623_modexit); - -MODULE_DESCRIPTION("ASoC RT5623 driver"); -MODULE_AUTHOR("Johnny Hsu "); -MODULE_LICENSE("GPL"); - - - - - - diff --git a/sound/soc/codecs/rt5623.h b/sound/soc/codecs/rt5623.h deleted file mode 100644 index 1dd070c0caad..000000000000 --- a/sound/soc/codecs/rt5623.h +++ /dev/null @@ -1,506 +0,0 @@ -/* - * rt5623.h -- RT5623 ALSA SoC audio driver - * - * Copyright 2011 Realtek Microelectronics - * Author: Johnny Hsu - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef __RT5623_H__ -#define __RT5623_H__ - -#define RT5623_RESET 0x00 -#define RT5623_SPK_OUT_VOL 0x02 -#define RT5623_HP_OUT_VOL 0x04 -#define RT5623_MONO_AUX_OUT_VOL 0x06 -#define RT5623_AUXIN_VOL 0x08 -#define RT5623_LINE_IN_VOL 0x0a -#define RT5623_STEREO_DAC_VOL 0x0c -#define RT5623_MIC_VOL 0x0e -#define RT5623_MIC_ROUTING_CTRL 0x10 -#define RT5623_ADC_REC_GAIN 0x12 -#define RT5623_ADC_REC_MIXER 0x14 -#define RT5623_SOFT_VOL_CTRL_TIME 0x16 -#define RT5623_OUTPUT_MIXER_CTRL 0x1c -#define RT5623_MIC_CTRL 0x22 -#define RT5623_AUDIO_INTERFACE 0x34 -#define RT5623_STEREO_AD_DA_CLK_CTRL 0x36 -#define RT5623_COMPANDING_CTRL 0x38 -#define RT5623_PWR_MANAG_ADD1 0x3a -#define RT5623_PWR_MANAG_ADD2 0x3c -#define RT5623_PWR_MANAG_ADD3 0x3e -#define RT5623_ADD_CTRL_REG 0x40 -#define RT5623_GLOBAL_CLK_CTRL_REG 0x42 -#define RT5623_PLL_CTRL 0x44 -#define RT5623_GPIO_OUTPUT_PIN_CTRL 0x4a -#define RT5623_GPIO_PIN_CONFIG 0x4c -#define RT5623_GPIO_PIN_POLARITY 0x4e -#define RT5623_GPIO_PIN_STICKY 0x50 -#define RT5623_GPIO_PIN_WAKEUP 0x52 -#define RT5623_GPIO_PIN_STATUS 0x54 -#define RT5623_GPIO_PIN_SHARING 0x56 -#define RT5623_OVER_TEMP_CURR_STATUS 0x58 -#define RT5623_JACK_DET_CTRL 0x5a -#define RT5623_MISC_CTRL 0x5e -#define RT5623_PSEDUEO_SPATIAL_CTRL 0x60 -#define RT5623_EQ_CTRL 0x62 -#define RT5623_EQ_MODE_ENABLE 0x66 -#define RT5623_AVC_CTRL 0x68 -#define RT5623_HID_CTRL_INDEX 0x6a -#define RT5623_HID_CTRL_DATA 0x6c -#define RT5623_VENDOR_ID1 0x7c -#define RT5623_VENDOR_ID2 0x7e - -/* global definition */ -#define RT5623_L_MUTE (0x1 << 15) -#define RT5623_L_MUTE_SFT 15 -#define RT5623_L_ZC (0x1 << 14) -#define RT5623_L_SM (0x1 << 13) -#define RT5623_L_VOL_MASK (0x1f << 8) -#define RT5623_L_VOL_SFT 8 -#define RT5623_ADCL_VOL_SFT 7 -#define RT5623_R_MUTE (0x1 << 7) -#define RT5623_R_MUTE_SFT 7 -#define RT5623_R_ZC (0x1 << 6) -#define RT5623_R_VOL_MASK (0x1f) -#define RT5623_R_VOL_SFT 0 -#define RT5623_M_HPMIX (0x1 << 15) -#define RT5623_M_SPKMIX (0x1 << 14) -#define RT5623_M_MONOMIX (0x1 << 13) -#define RT5623_SPK_CLASS_AB 0 -#define RT5623_SPK_CLASS_D 1 - -/* AUXIN Volume (0x08) */ -#define RT5623_M_AXI_TO_HPM (0x1 << 15) -#define RT5623_M_AXI_TO_HPM_SFT 15 -#define RT5623_M_AXI_TO_SPKM (0x1 << 14) -#define RT5623_M_AXI_TO_SPKM_SFT 14 -#define RT5623_M_AXI_TO_MOM (0x1 << 13) -#define RT5623_M_AXI_TO_MOM_SFT 13 - -/* LINE_IN Volume (0x0a) */ -#define RT5623_M_LINEIN_TO_HPM (0x1 << 15) -#define RT5623_M_LINEIN_TO_HPM_SFT 15 -#define RT5623_M_LINEIN_TO_SPKM (0x1 << 14) -#define RT5623_M_LINEIN_TO_SPKM_SFT 14 -#define RT5623_M_LINEIN_TO_MOM (0x1 << 13) -#define RT5623_M_LINEIN_TO_MOM_SFT 13 - -/* Stereo DAC Volume (0x0c) */ -#define RT5623_M_DAC_TO_HPM (0x1 << 15) -#define RT5623_M_DAC_TO_HPM_SFT 15 -#define RT5623_M_DAC_TO_SPKM (0x1 << 14) -#define RT5623_M_DAC_TO_SPKM_SFT 14 -#define RT5623_M_DAC_TO_MOM (0x1 << 13) -#define RT5623_M_DAC_TO_MOM_SFT 13 - -/* Mic Routing Control(0x10) */ -#define RT5623_M_MIC1_TO_HP_MIXER (0x1 << 15) -#define RT5623_M_MIC1_TO_HP_MIXER_SFT 15 -#define RT5623_M_MIC1_TO_SPK_MIXER (0x1 << 14) -#define RT5623_M_MIC1_TO_SPK_MIXER_SFT 14 -#define RT5623_M_MIC1_TO_MONO_MIXER (0x1 << 13) -#define RT5623_M_MIC1_TO_MONO_MIXER_SFT 13 -#define RT5623_MIC1_DIFF_INPUT_CTRL (0x1 << 12) -#define RT5623_MIC1_DIFF_INPUT_CTRL_SFT 12 -#define RT5623_M_MIC2_TO_HP_MIXER (0x1 << 7) -#define RT5623_M_MIC2_TO_HP_MIXER_SFT 7 -#define RT5623_M_MIC2_TO_SPK_MIXER (0x1 << 6) -#define RT5623_M_MIC2_TO_SPK_MIXER_SFT 6 -#define RT5623_M_MIC2_TO_MONO_MIXER (0x1 << 5) -#define RT5623_M_MIC2_TO_MONO_MIXER_SFT 5 -#define RT5623_MIC2_DIFF_INPUT_CTRL (0x1 << 4) -#define RT5623_MIC2_DIFF_INPUT_CTRL_SFT 4 - -/* ADC Record Gain (0x12) */ -#define RT5623_M_ADC_L_TO_HP_MIXER (0x1 << 15) -#define RT5623_M_ADC_L_TO_HP_MIXER_SFT 15 -#define RT5623_M_ADC_R_TO_HP_MIXER (0x1 << 14) -#define RT5623_M_ADC_R_TO_HP_MIXER_SFT 14 -#define RT5623_M_ADC_L_TO_MONO_MIXER (0x1 << 13) -#define RT5623_M_ADC_L_TO_MONO_MIXER_SFT 13 -#define RT5623_M_ADC_R_TO_MONO_MIXER (0x1 << 12) -#define RT5623_M_ADC_R_TO_MONO_MIXER_SFT 12 -#define RT5623_ADC_L_GAIN_MASK (0x1f << 7) -#define RT5623_ADC_L_ZC_DET (0x1 << 6) -#define RT5623_ADC_R_ZC_DET (0x1 << 5) -#define RT5623_ADC_R_GAIN_MASK (0x1f << 0) - -/* ADC Input Mixer Control (0x14) */ -#define RT5623_M_MIC1_TO_ADC_L_MIXER (0x1 << 14) -#define RT5623_M_MIC1_TO_ADC_L_MIXER_SFT 14 -#define RT5623_M_MIC2_TO_ADC_L_MIXER (0x1 << 13) -#define RT5623_M_MIC2_TO_ADC_L_MIXER_SFT 13 -#define RT5623_M_LINEIN_L_TO_ADC_L_MIXER (0x1 << 12) -#define RT5623_M_LINEIN_L_TO_ADC_L_MIXER_SFT 12 -#define RT5623_M_AUXIN_L_TO_ADC_L_MIXER (0x1 << 11) -#define RT5623_M_AUXIN_L_TO_ADC_L_MIXER_SFT 11 -#define RT5623_M_HPMIXER_L_TO_ADC_L_MIXER (0x1 << 10) -#define RT5623_M_HPMIXER_L_TO_ADC_L_MIXER_SFT 10 -#define RT5623_M_SPKMIXER_L_TO_ADC_L_MIXER (0x1 << 9) -#define RT5623_M_SPKMIXER_L_TO_ADC_L_MIXER_SFT 9 -#define RT5623_M_MONOMIXER_L_TO_ADC_L_MIXER (0x1 << 8) -#define RT5623_M_MONOMIXER_L_TO_ADC_L_MIXER_SFT 8 -#define RT5623_M_MIC1_TO_ADC_R_MIXER (0x1 << 6) -#define RT5623_M_MIC1_TO_ADC_R_MIXER_SFT 6 -#define RT5623_M_MIC2_TO_ADC_R_MIXER (0x1 << 5) -#define RT5623_M_MIC2_TO_ADC_R_MIXER_SFT 5 -#define RT5623_M_LINEIN_R_TO_ADC_R_MIXER (0x1 << 4) -#define RT5623_M_LINEIN_R_TO_ADC_R_MIXER_SFT 4 -#define RT5623_M_AUXIN_R_TO_ADC_R_MIXER (0x1 << 3) -#define RT5623_M_AUXIN_R_TO_ADC_R_MIXER_SFT 3 -#define RT5623_M_HPMIXER_R_TO_ADC_R_MIXER (0x1 << 2) -#define RT5623_M_HPMIXER_R_TO_ADC_R_MIXER_SFT 2 -#define RT5623_M_SPKMIXER_R_TO_ADC_R_MIXER (0x1 << 1) -#define RT5623_M_SPKMIXER_R_TO_ADC_R_MIXER_SFT 1 -#define RT5623_M_MONOMIXER_R_TO_ADC_R_MIXER (0x1 << 0) -#define RT5623_M_MONOMIXER_R_TO_ADC_R_MIXER_SFT 0 - -/* Output Mixer Control(0x1c) */ -#define RT5623_SPKOUT_N_SOUR_MASK (0x3 << 14) -#define RT5623_SPKOUT_N_SOUR_SFT 14 -#define RT5623_SPKOUT_N_SOUR_LN (0x2 << 14) -#define RT5623_SPKOUT_N_SOUR_RP (0x1 << 14) -#define RT5623_SPKOUT_N_SOUR_RN (0x0 << 14) -#define RT5623_SPK_OUTPUT_CLASS_MASK (0x1 << 13) -#define RT5623_SPK_OUTPUT_CLASS_SFT 13 -#define RT5623_SPK_OUTPUT_CLASS_AB (0x0 << 13) -#define RT5623_SPK_OUTPUT_CLASS_D (0x1 << 13) -#define RT5623_SPK_CLASS_AB_S_AMP (0x0 << 12) -#define RT5623_SPK_CALSS_AB_W_AMP (0x1 << 12) -#define RT5623_SPKOUT_INPUT_SEL_MASK (0x3 << 10) -#define RT5623_SPKOUT_INPUT_SEL_SFT 10 -#define RT5623_SPKOUT_INPUT_SEL_MONOMIXER (0x3 << 10) -#define RT5623_SPKOUT_INPUT_SEL_SPKMIXER (0x2 << 10) -#define RT5623_SPKOUT_INPUT_SEL_HPMIXER (0x1 << 10) -#define RT5623_SPKOUT_INPUT_SEL_VMID (0x0 << 10) -#define RT5623_HPL_INPUT_SEL_HPLMIXER_MASK (0x1 << 9) -#define RT5623_HPL_INPUT_SEL_HPLMIXER_SFT 9 -#define RT5623_HPL_INPUT_SEL_HPLMIXER (0x1 << 9) -#define RT5623_HPR_INPUT_SEL_HPRMIXER_MASK (0x1 << 8) -#define RT5623_HPR_INPUT_SEL_HPRMIXER_SFT 8 -#define RT5623_HPR_INPUT_SEL_HPRMIXER (0x1 << 8) -#define RT5623_MONO_AUX_INPUT_SEL_MASK (0x3 << 6) -#define RT5623_MONO_AUX_INPUT_SEL_SFT 6 -#define RT5623_MONO_AUX_INPUT_SEL_MONO (0x3 << 6) -#define RT5623_MONO_AUX_INPUT_SEL_SPK (0x2 << 6) -#define RT5623_MONO_AUX_INPUT_SEL_HP (0x1 << 6) -#define RT5623_MONO_AUX_INPUT_SEL_VMID (0x0 << 6) - -/* Micphone Control define(0x22) */ -#define RT5623_MIC1 1 -#define RT5623_MIC2 2 -#define RT5623_MIC_BIAS_90_PRECNET_AVDD 1 -#define RT5623_MIC_BIAS_75_PRECNET_AVDD 2 -#define RT5623_MIC1_BOOST_CTRL_MASK (0x3 << 10) -#define RT5623_MIC1_BOOST_CTRL_SFT 10 -#define RT5623_MIC1_BOOST_CTRL_BYPASS 0x0 << 10) -#define RT5623_MIC1_BOOST_CTRL_20DB (0x1 << 10) -#define RT5623_MIC1_BOOST_CTRL_30DB (0x2 << 10) -#define RT5623_MIC1_BOOST_CTRL_40DB (0x3 << 10) -#define RT5623_MIC2_BOOST_CTRL_MASK (0x3 << 8) -#define RT5623_MIC2_BOOST_CTRL_SFT 8 -#define RT5623_MIC2_BOOST_CTRL_BYPASS (0x0 << 8) -#define RT5623_MIC2_BOOST_CTRL_20DB (0x1 << 8) -#define RT5623_MIC2_BOOST_CTRL_30DB (0x2 << 8) -#define RT5623_MIC2_BOOST_CTRL_40DB (0x3 << 8) -#define RT5623_MICBIAS_VOLT_CTRL_MASK (0x1 << 5) -#define RT5623_MICBIAS_VOLT_CTRL_90P (0x0 << 5) -#define RT5623_MICBIAS_VOLT_CTRL_75P (0x1 << 5) -#define RT5623_MICBIAS_SHORT_CURR_DET_MASK (0x3) -#define RT5623_MICBIAS_SHORT_CURR_DET_600UA (0x0) -#define RT5623_MICBIAS_SHORT_CURR_DET_1200UA (0x1) -#define RT5623_MICBIAS_SHORT_CURR_DET_1800UA (0x2) - -/* Audio Interface (0x34) */ -#define RT5623_SDP_MASTER_MODE (0x0 << 15) -#define RT5623_SDP_SLAVE_MODE (0x1 << 15) -#define RT5623_I2S_PCM_MODE (0x1 << 14) -#define RT5623_MAIN_I2S_BCLK_POL_CTRL (0x1 << 7) - /* 0:ADC data appear at left phase of LRCK - * 1:ADC data appear at right phase of LRCK - */ -#define RT5623_ADC_DATA_L_R_SWAP (0x1 << 5) - /* 0:DAC data appear at left phase of LRCK - * 1:DAC data appear at right phase of LRCK - */ -#define RT5623_DAC_DATA_L_R_SWAP (0x1 << 4) -#define RT5623_I2S_DL_MASK (0x3 << 2) -#define RT5623_I2S_DL_16 (0x0 << 2) -#define RT5623_I2S_DL_20 (0x1 << 2) -#define RT5623_I2S_DL_24 (0x2 << 2) -#define RT5623_I2S_DL_32 (0x3 << 2) -#define RT5623_I2S_DF_MASK (0x3) -#define RT5623_I2S_DF_I2S (0x0) -#define RT5623_I2S_DF_RIGHT (0x1) -#define RT5623_I2S_DF_LEFT (0x2) -#define RT5623_I2S_DF_PCM (0x3) - -/* Stereo AD/DA Clock Control(0x36h) */ -#define RT5623_I2S_PRE_DIV_MASK (0x7 << 12) -#define RT5623_I2S_PRE_DIV_1 (0x0 << 12) -#define RT5623_I2S_PRE_DIV_2 (0x1 << 12) -#define RT5623_I2S_PRE_DIV_4 (0x2 << 12) -#define RT5623_I2S_PRE_DIV_8 (0x3 << 12) -#define RT5623_I2S_PRE_DIV_16 (0x4 << 12) -#define RT5623_I2S_PRE_DIV_32 (0x5 << 12) -#define RT5623_I2S_SCLK_DIV_MASK (0x7 << 9) -#define RT5623_I2S_SCLK_DIV_1 (0x0 << 9) -#define RT5623_I2S_SCLK_DIV_2 (0x1 << 9) -#define RT5623_I2S_SCLK_DIV_3 (0x2 << 9) -#define RT5623_I2S_SCLK_DIV_4 (0x3 << 9) -#define RT5623_I2S_SCLK_DIV_6 (0x4 << 9) -#define RT5623_I2S_SCLK_DIV_8 (0x5 << 9) -#define RT5623_I2S_SCLK_DIV_12 (0x6 << 9) -#define RT5623_I2S_SCLK_DIV_16 (0x7 << 9) -#define RT5623_I2S_WCLK_DIV_PRE_MASK (0xF << 5) -#define RT5623_I2S_WCLK_PRE_DIV_1 (0x0 << 5) -#define RT5623_I2S_WCLK_PRE_DIV_2 (0x1 << 5) -#define RT5623_I2S_WCLK_PRE_DIV_3 (0x2 << 5) -#define RT5623_I2S_WCLK_PRE_DIV_4 (0x3 << 5) -#define RT5623_I2S_WCLK_PRE_DIV_5 (0x4 << 5) -#define RT5623_I2S_WCLK_PRE_DIV_6 (0x5 << 5) -#define RT5623_I2S_WCLK_PRE_DIV_7 (0x6 << 5) -#define RT5623_I2S_WCLK_PRE_DIV_8 (0x7 << 5) -#define RT5623_I2S_WCLK_DIV_MASK (0x7 << 2) -#define RT5623_I2S_WCLK_DIV_2 (0x0 << 2) -#define RT5623_I2S_WCLK_DIV_4 (0x1 << 2) -#define RT5623_I2S_WCLK_DIV_8 (0x2 << 2) -#define RT5623_I2S_WCLK_DIV_16 (0x3 << 2) -#define RT5623_I2S_WCLK_DIV_32 (0x4 << 2) -#define RT5623_ADDA_FILTER_CLK_SEL_256FS (0 << 1) -#define RT5623_ADDA_FILTER_CLK_SEL_384FS (1 << 1) -#define RT5623_ADDA_OSR_SEL_64FS (0) -#define RT5623_ADDA_OSR_SEL_128FS (1) - -/* Power managment addition 1 (0x3a) */ -#define RT5623_PWR_MAIN_I2S_EN (0x1 << 15) -#define RT5623_PWR_MAIN_I2S_EN_BIT 15 -#define RT5623_PWR_ZC_DET_PD_EN (0x1 << 14) -#define RT5623_PWR_ZC_DET_PD_EN_BIT 14 -#define RT5623_PWR_MIC1_BIAS_EN (0x1 << 11) -#define RT5623_PWR_MIC1_BIAS_EN_BIT 11 -#define RT5623_PWR_SHORT_CURR_DET_EN (0x1 << 10) -#define RT5623_PWR_SHORT_CURR_DET_EN_BIT 10 -#define RT5623_PWR_SOFTGEN_EN (0x1 << 8) -#define RT5623_PWR_SOFTGEN_EN_BIT 8 -#define RT5623_PWR_DEPOP_BUF_HP (0x1 << 6) -#define RT5623_PWR_DEPOP_BUF_HP_BIT 6 -#define RT5623_PWR_HP_OUT_AMP (0x1 << 5) -#define RT5623_PWR_HP_OUT_AMP_BIT 5 -#define RT5623_PWR_HP_OUT_ENH_AMP (0x1 << 4) -#define RT5623_PWR_HP_OUT_ENH_AMP_BIT 4 -#define RT5623_PWR_DEPOP_BUF_AUX (0x1 << 2) -#define RT5623_PWR_DEPOP_BUF_AUX_BIT 2 -#define RT5623_PWR_AUX_OUT_AMP (0x1 << 1) -#define RT5623_PWR_AUX_OUT_AMP_BIT 1 -#define RT5623_PWR_AUX_OUT_ENH_AMP (0x1) -#define RT5623_PWR_AUX_OUT_ENH_AMP_BIT 0 - -/* Power managment addition 2 (0x3c) */ -#define RT5623_PWR_CLASS_AB (0x1 << 15) -#define RT5623_PWR_CLASS_AB_BIT 15 -#define RT5623_PWR_CLASS_D (0x1 << 14) -#define RT5623_PWR_CLASS_D_BIT 14 -#define RT5623_PWR_VREF (0x1 << 13) -#define RT5623_PWR_VREF_BIT 13 -#define RT5623_PWR_PLL (0x1 << 12) -#define RT5623_PWR_PLL_BIT 12 -#define RT5623_PWR_DAC_REF_CIR (0x1 << 10) -#define RT5623_PWR_DAC_REF_CIR_BIT 10 -#define RT5623_PWR_L_DAC_CLK (0x1 << 9) -#define RT5623_PWR_L_DAC_CLK_BIT 9 -#define RT5623_PWR_R_DAC_CLK (0x1 << 8) -#define RT5623_PWR_R_DAC_CLK_BIT 8 -#define RT5623_PWR_L_ADC_CLK_GAIN (0x1 << 7) -#define RT5623_PWR_L_ADC_CLK_GAIN_BIT 7 -#define RT5623_PWR_R_ADC_CLK_GAIN (0x1 << 6) -#define RT5623_PWR_R_ADC_CLK_GAIN_BIT 6 -#define RT5623_PWR_L_HP_MIXER (0x1 << 5) -#define RT5623_PWR_L_HP_MIXER_BIT 5 -#define RT5623_PWR_R_HP_MIXER (0x1 << 4) -#define RT5623_PWR_R_HP_MIXER_BIT 4 -#define RT5623_PWR_SPK_MIXER (0x1 << 3) -#define RT5623_PWR_SPK_MIXER_BIT 3 -#define RT5623_PWR_MONO_MIXER (0x1 << 2) -#define RT5623_PWR_MONO_MIXER_BIT 2 -#define RT5623_PWR_L_ADC_REC_MIXER (0x1 << 1) -#define RT5623_PWR_L_ADC_REC_MIXER_BIT 1 -#define RT5623_PWR_R_ADC_REC_MIXER (0x1) -#define RT5623_PWR_R_ADC_REC_MIXER_BIT 0 - -/* Power managment addition 3 (0x3e) */ -#define RT5623_PWR_MAIN_BIAS (0x1 << 15) -#define RT5623_PWR_MAIN_BIAS_BIT 15 -#define RT5623_PWR_AUXOUT_L_VOL_AMP (0x1 << 14) -#define RT5623_PWR_AUXOUT_L_VOL_AMP_BIT 14 -#define RT5623_PWR_AUXOUT_R_VOL_AMP (0x1 << 13) -#define RT5623_PWR_AUXOUT_R_VOL_AMP_BIT 13 -#define RT5623_PWR_SPK_OUT (0x1 << 12) -#define RT5623_PWR_SPK_OUT_BIT 12 -#define RT5623_PWR_HP_L_OUT_VOL (0x1 << 10) -#define RT5623_PWR_HP_L_OUT_VOL_BIT 10 -#define RT5623_PWR_HP_R_OUT_VOL (0x1 << 9) -#define RT5623_PWR_HP_R_OUT_VOL_BIT 9 -#define RT5623_PWR_LINEIN_L_VOL (0x1 << 7) -#define RT5623_PWR_LINEIN_L_VOL_BIT 7 -#define RT5623_PWR_LINEIN_R_VOL (0x1 << 6) -#define RT5623_PWR_LINEIN_R_VOL_BIT 6 -#define RT5623_PWR_AUXIN_L_VOL (0x1 << 5) -#define RT5623_PWR_AUXIN_L_VOL_BIT 5 -#define RT5623_PWR_AUXIN_R_VOL (0x1 << 4) -#define RT5623_PWR_AUXIN_R_VOL_BIT 4 -#define RT5623_PWR_MIC1_FUN_CTRL (0x1 << 3) -#define RT5623_PWR_MIC1_FUN_CTRL_BIT 3 -#define RT5623_PWR_MIC2_FUN_CTRL (0x1 << 2) -#define RT5623_PWR_MIC2_FUN_CTRL_BIT 2 -#define RT5623_PWR_MIC1_BOOST_MIXER (0x1 << 1) -#define RT5623_PWR_MIC1_BOOST_MIXER_BIT 1 -#define RT5623_PWR_MIC2_BOOST_MIXER (0x1) -#define RT5623_PWR_MIC2_BOOST_MIXER_BIT 0 - -/* Additional Control Register (0x40) */ -#define RT5623_AUXOUT_SEL_DIFF (0x1 << 15) -#define RT5623_AUXOUT_SEL_SE (0x1 << 15) -#define RT5623_SPK_AB_AMP_CTRL_MASK (0x7 << 12) -#define RT5623_SPK_AB_AMP_CTRL_RATIO_225 (0x0 << 12) -#define RT5623_SPK_AB_AMP_CTRL_RATIO_200 (0x1 << 12) -#define RT5623_SPK_AB_AMP_CTRL_RATIO_175 (0x2 << 12) -#define RT5623_SPK_AB_AMP_CTRL_RATIO_150 (0x3 << 12) -#define RT5623_SPK_AB_AMP_CTRL_RATIO_125 (0x4 << 12) -#define RT5623_SPK_AB_AMP_CTRL_RATIO_100 (0x5 << 12) -#define RT5623_SPK_D_AMP_CTRL_MASK (0x3 << 10) -#define RT5623_SPK_D_AMP_CTRL_RATIO_175 (0x0 << 10) -#define RT5623_SPK_D_AMP_CTRL_RATIO_150 (0x1 << 10) -#define RT5623_SPK_D_AMP_CTRL_RATIO_125 (0x2 << 10) -#define RT5623_SPK_D_AMP_CTRL_RATIO_100 (0x3 << 10) -#define RT5623_STEREO_DAC_HI_PASS_FILTER_EN (0x1 << 9) -#define RT5623_STEREO_ADC_HI_PASS_FILTER_EN (0x1 << 8) -#define RT5623_DIG_VOL_BOOST_MASK (0x3 << 4) -#define RT5623_DIG_VOL_BOOST_0DB (0x0 << 4) -#define RT5623_DIG_VOL_BOOST_6DB (0x1 << 4) -#define RT5623_DIG_VOL_BOOST_12DB (0x2 << 4) -#define RT5623_DIG_VOL_BOOST_18DB (0x3 << 4) - -/* Global Clock Control Register (0x42) */ -#define RT5623_SYSCLK_SOUR_SEL_MASK (0x1 << 15) -#define RT5623_SYSCLK_SOUR_SEL_MCLK (0x0 << 15) -#define RT5623_SYSCLK_SOUR_SEL_PLL (0x1 << 15) -#define RT5623_PLLCLK_SOUR_SEL_MCLK (0x0 << 14) -#define RT5623_PLLCLK_SOUR_SEL_BITCLK (0x1 << 14) -#define RT5623_PLLCLK_DIV_RATIO_MASK (0x3 << 1) -#define RT5623_PLLCLK_DIV_RATIO_DIV1 (0x0 << 1) -#define RT5623_PLLCLK_DIV_RATIO_DIV2 (0x1 << 1) -#define RT5623_PLLCLK_DIV_RATIO_DIV4 (0x2 << 1) -#define RT5623_PLLCLK_DIV_RATIO_DIV8 (0x3 << 1) -#define PLLCLK_PRE_DIV1 (0x0) -#define PLLCLK_PRE_DIV2 (0x1) - -/* GPIO Pin Configuration (0x4c) */ -#define RT5623_GPIO_PIN_MASK (0x1 << 1) -#define RT5623_GPIO_PIN_SET_INPUT (0x1 << 1) -#define RT5623_GPIO_PIN_SET_OUTPUT (0x0 << 1) - -/* Pin Sharing (0x56) */ -#define RT5623_LINEIN_L_PIN_SHARING (0x1 << 15) -#define RT5623_LINEIN_L_PIN_AS_LINEIN_L (0x0 << 15) -#define RT5623_LINEIN_L_PIN_AS_JD1 (0x1 << 15) -#define RT5623_LINEIN_R_PIN_SHARING (0x1 << 14) -#define RT5623_LINEIN_R_PIN_AS_LINEIN_R (0x0 << 14) -#define RT5623_LINEIN_R_PIN_AS_JD2 (0x1 << 14) -#define RT5623_GPIO_PIN_SHARE (0x3) -#define RT5623_GPIO_PIN_AS_GPIO (0x0) -#define RT5623_GPIO_PIN_AS_IRQOUT (0x1) -#define RT5623_GPIO_PIN_AS_PLLOUT (0x3) - -/* Jack Detect Control Register (0x5a) */ -#define RT5623_JACK_DETECT_MASK (0x3 << 14) -#define RT5623_JACK_DETECT_USE_JD2 (0x3 << 14) -#define RT5623_JACK_DETECT_USE_JD1 (0x2 << 14) -#define RT5623_JACK_DETECT_USE_GPIO (0x1 << 14) -#define RT5623_JACK_DETECT_OFF (0x0 << 14) -#define RT5623_SPK_EN_IN_HI (0x1 << 11) -#define RT5623_AUX_R_EN_IN_HI (0x1 << 10) -#define RT5623_AUX_L_EN_IN_HI (0x1 << 9) -#define RT5623_HP_EN_IN_HI (0x1 << 8) -#define RT5623_SPK_EN_IN_LO (0x1 << 7) -#define RT5623_AUX_R_EN_IN_LO (0x1 << 6) -#define RT5623_AUX_L_EN_IN_LO (0x1 << 5) -#define RT5623_HP_EN_IN_LO (0x1 << 4) - -/* MISC CONTROL (0x5e) */ -#define RT5623_DISABLE_FAST_VREG (0x1 << 15) -#define RT5623_SPK_CLASS_AB_OC_PD (0x1 << 13) -#define RT5623_SPK_CLASS_AB_OC_DET (0x1 << 12) -#define RT5623_HP_DEPOP_MODE3_EN (0x1 << 10) -#define RT5623_HP_DEPOP_MODE2_EN (0x1 << 9) -#define RT5623_HP_DEPOP_MODE1_EN (0x1 << 8) -#define RT5623_AUXOUT_DEPOP_MODE3_EN (0x1 << 6) -#define RT5623_AUXOUT_DEPOP_MODE2_EN (0x1 << 5) -#define RT5623_AUXOUT_DEPOP_MODE1_EN (0x1 << 4) -#define RT5623_M_DAC_L_INPUT (0x1 << 3) -#define RT5623_M_DAC_R_INPUT (0x1 << 2) -#define RT5623_IRQOUT_INV_CTRL (0x1 << 0) - -/* Psedueo Stereo & Spatial Effect Block Control (0x60) */ -#define RT5623_SPATIAL_CTRL_EN (0x1 << 15) -#define RT5623_ALL_PASS_FILTER_EN (0x1 << 14) -#define RT5623_PSEUDO_STEREO_EN (0x1 << 13) -#define RT5623_STEREO_EXPENSION_EN (0x1 << 12) -#define RT5623_GAIN_3D_PARA_L_MASK (0x7 << 9) -#define RT5623_GAIN_3D_PARA_L_1_00 (0x0 << 9) -#define RT5623_GAIN_3D_PARA_L_1_25 (0x1 << 9) -#define RT5623_GAIN_3D_PARA_L_1_50 (0x2 << 9) -#define RT5623_GAIN_3D_PARA_L_1_75 (0x3 << 9) -#define RT5623_GAIN_3D_PARA_L_2_00 (0x4 << 9) -#define RT5623_GAIN_3D_PARA_R_MASK (0x7 << 6) -#define RT5623_GAIN_3D_PARA_R_1_00 (0x0 << 6) -#define RT5623_GAIN_3D_PARA_R_1_25 (0x1 << 6) -#define RT5623_GAIN_3D_PARA_R_1_50 (0x2 << 6) -#define RT5623_GAIN_3D_PARA_R_1_75 (0x3 << 6) -#define RT5623_GAIN_3D_PARA_R_2_00 (0x4 << 6) -#define RT5623_RATIO_3D_L_MASK (0x3 << 4) -#define RT5623_RATIO_3D_L_0_0 (0x0 << 4) -#define RT5623_RATIO_3D_L_0_66 (0x1 << 4) -#define RT5623_RATIO_3D_L_1_0 (0x2 << 4) -#define RT5623_RATIO_3D_R_MASK (0x3 << 2) -#define RT5623_RATIO_3D_R_0_0 (0x0 << 2) -#define RT5623_RATIO_3D_R_0_66 (0x1 << 2) -#define RT5623_RATIO_3D_R_1_0 (0x2 << 2) -#define RT5623_APF_MASK (0x3) -#define RT5623_APF_FOR_48K (0x3) -#define RT5623_APF_FOR_44_1K (0x2) -#define RT5623_APF_FOR_32K (0x1) - -/* EQ CONTROL (0x62) */ -#define RT5623_EN_HW_EQ_BLK (0x1 << 15) -#define RT5623_EN_HW_EQ_HPF_MODE (0x1 << 14) -#define RT5623_EN_HW_EQ_SOUR (0x1 << 11) -#define RT5623_EN_HW_EQ_HPF (0x1 << 4) -#define RT5623_EN_HW_EQ_BP3 (0x1 << 3) -#define RT5623_EN_HW_EQ_BP2 (0x1 << 2) -#define RT5623_EN_HW_EQ_BP1 (0x1 << 1) -#define RT5623_EN_HW_EQ_LPF (0x1 << 0) - -/* EQ Mode Change Enable (0x66) */ -#define RT5623_EQ_HPF_CHANGE_EN (0x1 << 4) -#define RT5623_EQ_BP3_CHANGE_EN (0x1 << 3) -#define RT5623_EQ_BP2_CHANGE_EN (0x1 << 2) -#define RT5623_EQ_BP1_CHANGE_EN (0x1 << 1) -#define RT5623_EQ_LPF_CHANGE_EN (0x1 << 0) - -/* AVC Control (0x68) */ -#define RT5623_AVC_ENABLE (0x1 << 15) -#define RT5623_AVC_TARTGET_SEL_MASK (0x1 << 14) -#define RT5623_AVC_TARTGET_SEL_R (0x1 << 14) -#define RT5623_AVC_TARTGET_SEL_L (0x0 << 14) - - -#define RT5623_PLL_FR_MCLK 0 -#define RT5623_PLL_FR_BCLK 1 - - -#endif /* __RT5623_H__ */ diff --git a/sound/soc/codecs/rt5625.c b/sound/soc/codecs/rt5625.c deleted file mode 100644 index 94d1489e6c63..000000000000 --- a/sound/soc/codecs/rt5625.c +++ /dev/null @@ -1,3185 +0,0 @@ -/* - * rt5625.c -- RT5625 ALSA SoC audio codec driver - * - * Copyright 2011 Realtek Semiconductor Corp. - * Author: Johnny Hsu - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "rt5625.h" - -#define INVALID_GPIO -1 - -//#define RT5625_PROC -#ifdef RT5625_PROC -#include -#include -#include -char debug_write_read = 0; -#endif - -#if 1 -#define DBG(x...) printk(KERN_INFO x) -#else -#define DBG(x...) do { } while (0) -#endif - -static struct snd_soc_codec *rt5625_codec; - -#define RT5625_REG_RW 1 /* for debug */ -//#define RT5625_DEMO 1 /* only for demo; please remove it */ - -#define RT5625_F_SMT_PHO -#define RT5625_PLY_BIT 0 -#define RT5625_PLY_MASK (0x1) -#define RT5625_REC_BIT 1 -#define RT5625_REC_MASK (0x1 << RT5625_REC_BIT) -#define RT5625_3G_BIT 2 -#define RT5625_3G_MASK (0x1 << RT5625_3G_BIT) -#define RT5625_BT_BIT 3 -#define RT5625_BT_MASK (0x1 << RT5625_BT_BIT) -#define RT5625_VOIP_BIT 4 -#define RT5625_VOIP_MASK (0x1 << RT5625_VOIP_BIT) - -struct rt5625_priv { - unsigned int stereo_sysclk; - unsigned int voice_sysclk; - - int vodsp_fun; - int spk_ctr_status; - int spk_ctr_pin; - int spk_ctr_on; - int spk_ctr_off; -#ifdef RT5625_F_SMT_PHO - int app_bmp;/* bit{0, 1, 2, 3, 4} = {play, rec, 3g, bt, voip} */ - int pll_sel; - int pll2_sel; - int dac_active; - int adc_active; - int headset; - int vodsp_fun_bak; -#endif -}; - -#ifdef RT5625_F_SMT_PHO -static u16 rt5625_voip_back[][2] = { - {RT5625_VODSP_PDM_CTL, 0x0000}, - {RT5625_F_DAC_ADC_VDAC, 0x0000}, -}; -#define RT5625_VOIP_BK_NUM \ - (sizeof(rt5625_voip_back) / sizeof(rt5625_voip_back[0])) -#endif - -#ifdef RT5625_DEMO -struct rt5625_init_reg { - u8 reg; - u16 val; -}; - -static struct rt5625_init_reg init_list[] = { - {RT5625_HP_OUT_VOL , 0x8888}, //default is -12db - {RT5625_SPK_OUT_VOL , 0x8080}, //default is 0db - {RT5625_PHONEIN_VOL , 0xe800}, //phone differential - {RT5625_DAC_MIC_CTRL , 0xee01}, //DAC to hpmixer & spkmixer - {RT5625_OUTMIX_CTRL , 0x2bc8}, //spk from spkmixer; hp from hpmixer; aux from monomixer; classAB - {RT5625_ADC_REC_MIXER , 0x1f1f}, //record source from mic1 & mic2 - {RT5625_GEN_CTRL1 , 0x0c08}, //speaker vdd ratio is 1; 1.25VDD ratio -}; -#define RT5625_INIT_REG_LEN ARRAY_SIZE(init_list) - -static int rt5625_reg_init(struct snd_soc_codec *codec) -{ - int i; - for (i = 0; i < RT5625_INIT_REG_LEN; i++) - snd_soc_write(codec, init_list[i].reg, init_list[i].val); - return 0; -} -#endif - -static const u16 rt5625_reg[0x80] = { - [RT5625_RESET] = 0x59b4, - [RT5625_SPK_OUT_VOL] = 0x8080, - [RT5625_HP_OUT_VOL] = 0x8080, - [RT5625_AUX_OUT_VOL] = 0x8080, - [RT5625_PHONEIN_VOL] = 0xc800, - [RT5625_LINE_IN_VOL] = 0xe808, - [RT5625_DAC_VOL] = 0x1010, - [RT5625_MIC_VOL] = 0x0808, - [RT5625_DAC_MIC_CTRL] = 0xee0f, - [RT5625_ADC_REC_GAIN] = 0xcbcb, - [RT5625_ADC_REC_MIXER] = 0x7f7f, - [RT5625_VDAC_OUT_VOL] = 0xe010, - [RT5625_OUTMIX_CTRL] = 0x8008, - [RT5625_VODSP_CTL] = 0x2007, - [RT5625_DMIC_CTRL] = 0x00c0, - [RT5625_PD_CTRL] = 0xef00, - [RT5625_GEN_CTRL1] = 0x0c0a, - [RT5625_LDO_CTRL] = 0x0029, - [RT5625_GPIO_CONFIG] = 0xbe3e, - [RT5625_GPIO_POLAR] = 0x3e3e, - [RT5625_GPIO_STATUS] = 0x803a, - [RT5625_SOFT_VOL_CTRL] = 0x0009, - [RT5625_DAC_CLK_CTRL1] = 0x3075, - [RT5625_DAC_CLK_CTRL2] = 0x1010, - [RT5625_VDAC_CLK_CTRL1] = 0x3110, - [RT5625_PS_CTRL] = 0x0553, - [RT5625_VENDOR_ID1] = 0x10ec, - [RT5625_VENDOR_ID2] = 0x5c02, -}; - -rt5625_dsp_reg rt5625_dsp_init[] = { - {0x232C, 0x0025}, - {0x230B, 0x0001}, - {0x2308, 0x007F}, - {0x23F8, 0x4003}, - {0x2301, 0x0002}, - {0x2328, 0x0001}, - {0x2304, 0x00FA}, - {0x2305, 0x0500}, - {0x2306, 0x4000}, - {0x230D, 0x0300}, - {0x230E, 0x0280}, - {0x2312, 0x00B1}, - {0x2314, 0xC000}, - {0x2316, 0x0041}, - {0x2317, 0x2800}, - {0x2318, 0x0800}, - {0x231D, 0x0050}, - {0x231F, 0x4000}, - {0x2330, 0x0008}, - {0x2335, 0x000A}, - {0x2336, 0x0004}, - {0x2337, 0x5000}, - {0x233A, 0x0300}, - {0x233B, 0x0030}, - {0x2341, 0x0008}, - {0x2343, 0x0800}, - {0x2352, 0x7FFF}, - {0x237F, 0x0400}, - {0x23A7, 0x2800}, - {0x22CE, 0x0400}, - {0x22D3, 0x1500}, - {0x22D4, 0x2800}, - {0x22D5, 0x3000}, - {0x2399, 0x2800}, - {0x230C, 0x0000}, -}; -#define RT5625_DSP_INIT_NUM ARRAY_SIZE(rt5625_dsp_init) - -static int rt5625_volatile_register( - struct snd_soc_codec *codec, unsigned int reg) -{ - switch (reg) { - case RT5625_RESET: - case RT5625_PD_CTRL: - case RT5625_GPIO_STATUS: - case RT5625_OTC_STATUS: - case RT5625_PRIV_DATA: - case RT5625_EQ_CTRL: - case RT5625_DSP_DATA: - case RT5625_DSP_CMD: - case RT5625_VENDOR_ID1: - case RT5625_VENDOR_ID2: - return 1; - default: - return 0; - } -} - -static int rt5625_readable_register( - struct snd_soc_codec *codec, unsigned int reg) -{ - switch (reg) { - case RT5625_RESET: - case RT5625_SPK_OUT_VOL: - case RT5625_HP_OUT_VOL: - case RT5625_AUX_OUT_VOL: - case RT5625_PHONEIN_VOL: - case RT5625_LINE_IN_VOL: - case RT5625_DAC_VOL: - case RT5625_MIC_VOL: - case RT5625_DAC_MIC_CTRL: - case RT5625_ADC_REC_GAIN: - case RT5625_ADC_REC_MIXER: - case RT5625_VDAC_OUT_VOL: - case RT5625_VODSP_PDM_CTL: - case RT5625_OUTMIX_CTRL: - case RT5625_VODSP_CTL: - case RT5625_MIC_CTRL: - case RT5625_DMIC_CTRL: - case RT5625_PD_CTRL: - case RT5625_F_DAC_ADC_VDAC: - case RT5625_SDP_CTRL: - case RT5625_EXT_SDP_CTRL: - case RT5625_PWR_ADD1: - case RT5625_PWR_ADD2: - case RT5625_PWR_ADD3: - case RT5625_GEN_CTRL1: - case RT5625_GEN_CTRL2: - case RT5625_PLL_CTRL: - case RT5625_PLL2_CTRL: - case RT5625_LDO_CTRL: - case RT5625_GPIO_CONFIG: - case RT5625_GPIO_POLAR: - case RT5625_GPIO_STICKY: - case RT5625_GPIO_WAKEUP: - case RT5625_GPIO_STATUS: - case RT5625_GPIO_SHARING: - case RT5625_OTC_STATUS: - case RT5625_SOFT_VOL_CTRL: - case RT5625_GPIO_OUT_CTRL: - case RT5625_MISC_CTRL: - case RT5625_DAC_CLK_CTRL1: - case RT5625_DAC_CLK_CTRL2: - case RT5625_VDAC_CLK_CTRL1: - case RT5625_PS_CTRL: - case RT5625_PRIV_INDEX: - case RT5625_PRIV_DATA: - case RT5625_EQ_CTRL: - case RT5625_DSP_ADDR: - case RT5625_DSP_DATA: - case RT5625_DSP_CMD: - case RT5625_VENDOR_ID1: - case RT5625_VENDOR_ID2: - return 1; - default: - return 0; - } -} - -static unsigned int rt5625_read(struct snd_soc_codec *codec, - unsigned int reg) -{ - unsigned int val; - - val = codec->hw_read(codec, reg); - return val; -} - -static int rt5625_write(struct snd_soc_codec *codec, unsigned int reg, - unsigned int value) -{ - unsigned int val; - u8 data[3]; - - data[0] = reg; - data[1] = (value >> 8) & 0xff; - data[2] = value & 0xff; - - val = codec->hw_write(codec->control_data, data, 3); - return val; -} - -static int rt5625_reset(struct snd_soc_codec *codec) -{ - return snd_soc_write(codec, RT5625_RESET, 0); -} - -/** - * rt5625_index_write - Write private register. - * @codec: SoC audio codec device. - * @reg: Private register index. - * @value: Private register Data. - * - * Modify private register for advanced setting. It can be written through - * private index (0x6a) and data (0x6c) register. - * - * Returns 0 for success or negative error code. - */ -static int rt5625_index_write(struct snd_soc_codec *codec, - unsigned int reg, unsigned int value) -{ - int ret; - - ret = snd_soc_write(codec, RT5625_PRIV_INDEX, reg); - if (ret < 0) { - dev_err(codec->dev, "Failed to set private addr: %d\n", ret); - goto err; - } - ret = snd_soc_write(codec, RT5625_PRIV_DATA, value); - if (ret < 0) { - dev_err(codec->dev, "Failed to set private value: %d\n", ret); - goto err; - } - return 0; - -err: - return ret; -} - -/** - * rt5625_index_read - Read private register. - * @codec: SoC audio codec device. - * @reg: Private register index. - * - * Read advanced setting from private register. It can be read through - * private index (0x6a) and data (0x6c) register. - * - * Returns private register value or negative error code. - */ -static unsigned int rt5625_index_read( - struct snd_soc_codec *codec, unsigned int reg) -{ - int ret; - - ret = snd_soc_write(codec, RT5625_PRIV_INDEX, reg); - if (ret < 0) { - dev_err(codec->dev, "Failed to set private addr: %d\n", ret); - return ret; - } - return snd_soc_read(codec, RT5625_PRIV_DATA); -} - -/** - * rt5625_index_update_bits - update private register bits - * @codec: Audio codec - * @reg: Private register index. - * @mask: Register mask - * @value: New value - * - * Writes new register value. - * - * Returns 1 for change, 0 for no change, or negative error code. - */ -static int rt5625_index_update_bits(struct snd_soc_codec *codec, - unsigned int reg, unsigned int mask, unsigned int value) -{ - unsigned int old, new; - int change, ret; - - ret = rt5625_index_read(codec, reg); - if (ret < 0) { - dev_err(codec->dev, "Failed to read private reg: %d\n", ret); - goto err; - } - - old = ret; - new = (old & ~mask) | (value & mask); - change = old != new; - if (change) { - ret = rt5625_index_write(codec, reg, new); - if (ret < 0) { - dev_err(codec->dev, - "Failed to write private reg: %d\n", ret); - goto err; - } - } - return change; - -err: - return ret; -} - -/** - * rt5625_dsp_done - Wait until DSP is ready. - * @codec: SoC Audio Codec device. - * - * To check voice DSP status and confirm it's ready for next work. - * - * Returns 0 for success or negative error code. - */ -static int rt5625_dsp_done(struct snd_soc_codec *codec) -{ - unsigned int count = 0, dsp_val; - - dsp_val = snd_soc_read(codec, RT5625_DSP_CMD); - while(dsp_val & RT5625_DSP_BUSY_MASK) { - if(count > 10) - return -EBUSY; - dsp_val = snd_soc_read(codec, RT5625_DSP_CMD); - count ++; - } - - return 0; -} - -/** - * rt5625_dsp_write - Write DSP register. - * @codec: SoC audio codec device. - * @reg: DSP register index. - * @value: DSP register Data. - * - * Modify voice DSP register for sound effect. The DSP can be controlled - * through DSP addr (0x70), data (0x72) and cmd (0x74) register. It has - * to wait until the DSP is ready. - * - * Returns 0 for success or negative error code. - */ -static int rt5625_dsp_write(struct snd_soc_codec *codec, - unsigned int reg, unsigned int value) -{ - int ret; - - ret = rt5625_dsp_done(codec); - if (ret < 0) { - dev_err(codec->dev, "DSP is busy: %d\n", ret); - goto err; - } - ret = snd_soc_write(codec, RT5625_DSP_ADDR, reg); - if (ret < 0) { - dev_err(codec->dev, "Failed to write DSP addr reg: %d\n", ret); - goto err; - } - ret = snd_soc_write(codec, RT5625_DSP_DATA, value); - if (ret < 0) { - dev_err(codec->dev, "Failed to write DSP data reg: %d\n", ret); - goto err; - } - ret = snd_soc_write(codec, RT5625_DSP_CMD, - RT5625_DSP_W_EN | RT5625_DSP_CMD_MW); - if (ret < 0) { - dev_err(codec->dev, "Failed to write DSP cmd reg: %d\n", ret); - goto err; - } - mdelay(10); - return 0; - -err: - return ret; -} - -/** - * rt5625_dsp_read - Read DSP register. - * @codec: SoC audio codec device. - * @reg: DSP register index. - * - * Read DSP setting value from voice DSP. The DSP can be controlled - * through DSP addr (0x70), data (0x72) and cmd (0x74) register. Each - * command has to wait until the DSP is ready. - * - * Returns DSP register value or negative error code. - */ -static unsigned int rt5625_dsp_read( - struct snd_soc_codec *codec, unsigned int reg) -{ - unsigned int val_h, val_l; - int ret = 0; - - ret = rt5625_dsp_done(codec); - if (ret < 0) { - dev_err(codec->dev, "DSP is busy: %d\n", ret); - goto err; - } - ret = snd_soc_write(codec, RT5625_DSP_ADDR, reg); - if (ret < 0) { - dev_err(codec->dev, "Failed to write DSP addr reg: %d\n", ret); - goto err; - } - ret = snd_soc_write(codec, RT5625_DSP_CMD, - RT5625_DSP_R_EN | RT5625_DSP_CMD_MR); - if (ret < 0) { - dev_err(codec->dev, "Failed to write DSP cmd reg: %d\n", ret); - goto err; - } - - /* Read DSP high byte data */ - ret = rt5625_dsp_done(codec); - if (ret < 0) { - dev_err(codec->dev, "DSP is busy: %d\n", ret); - goto err; - } - ret = snd_soc_write(codec, RT5625_DSP_ADDR, 0x26); - if (ret < 0) { - dev_err(codec->dev, "Failed to write DSP addr reg: %d\n", ret); - goto err; - } - ret = snd_soc_write(codec, RT5625_DSP_CMD, - RT5625_DSP_R_EN | RT5625_DSP_CMD_RR); - if (ret < 0) { - dev_err(codec->dev, "Failed to write DSP cmd reg: %d\n", ret); - goto err; - } - ret = rt5625_dsp_done(codec); - if (ret < 0) { - dev_err(codec->dev, "DSP is busy: %d\n", ret); - goto err; - } - ret = snd_soc_read(codec, RT5625_DSP_DATA); - if (ret < 0) { - dev_err(codec->dev, "Failed to read DSP data reg: %d\n", ret); - goto err; - } - val_h = ret; - - /* Read DSP low byte data */ - ret = snd_soc_write(codec, RT5625_DSP_ADDR, 0x25); - if (ret < 0) { - dev_err(codec->dev, "Failed to write DSP addr reg: %d\n", ret); - goto err; - } - ret = snd_soc_write(codec, RT5625_DSP_CMD, - RT5625_DSP_R_EN | RT5625_DSP_CMD_RR); - if (ret < 0) { - dev_err(codec->dev, "Failed to write DSP cmd reg: %d\n", ret); - goto err; - } - ret = rt5625_dsp_done(codec); - if (ret < 0) { - dev_err(codec->dev, "DSP is busy: %d\n", ret); - goto err; - } - ret = snd_soc_read(codec, RT5625_DSP_DATA); - if (ret < 0) { - dev_err(codec->dev, "Failed to read DSP data reg: %d\n", ret); - goto err; - } - val_l = ret; - - return ((val_h & 0xff) << 8) |(val_l & 0xff); - -err: - return ret; -} - -static const char *rt5625_spk_ctr_sel[] = {"Disable", "Enable"}; - -/* ADCR function select */ -static const char *adcr_fun_sel[] = { - "Stereo ADC", "Voice ADC", "VoDSP", "PDM Slave"}; - -static const struct soc_enum adcr_fun_sel_enum = - SOC_ENUM_SINGLE(RT5625_F_DAC_ADC_VDAC, RT5625_ADCR_F_SFT, - ARRAY_SIZE(adcr_fun_sel), adcr_fun_sel); - -/* ADCL function select */ -static const char *adcl_fun_sel[] = {"Stereo ADC", "VoDSP"}; - -static const struct soc_enum adcl_fun_sel_enum = - SOC_ENUM_SINGLE(RT5625_F_DAC_ADC_VDAC, RT5625_ADCL_F_SFT, - ARRAY_SIZE(adcl_fun_sel), adcl_fun_sel); - -/* Voice DSP */ -static const char *rt5625_aec_fun[] = {"Disable", "Enable"}; - -static const SOC_ENUM_SINGLE_DECL(rt5625_aec_fun_enum, 0, 0, rt5625_aec_fun); - -static const char *rt5625_dsp_lrck[] = {"8KHz", "16KHz"}; - -static const SOC_ENUM_SINGLE_DECL(rt5625_dsp_lrck_enum, - RT5625_VODSP_CTL, RT5625_DSP_LRCK_SFT, rt5625_dsp_lrck); - -static const char *rt5625_bp_ctrl[] = {"Bypass", "Normal"}; - -static const SOC_ENUM_SINGLE_DECL(rt5625_bp_ctrl_enum, - RT5625_VODSP_CTL, RT5625_DSP_BP_SFT, rt5625_bp_ctrl); - -static const char *rt5625_pd_ctrl[] = {"Power down", "Normal"}; - -static const SOC_ENUM_SINGLE_DECL(rt5625_pd_ctrl_enum, - RT5625_VODSP_CTL, RT5625_DSP_PD_SFT, rt5625_pd_ctrl); - -static const char *rt5625_rst_ctrl[] = {"Reset", "Normal"}; - -static const SOC_ENUM_SINGLE_DECL(rt5625_rst_ctrl_enum, - RT5625_VODSP_CTL, RT5625_DSP_RST_SFT, rt5625_rst_ctrl); -/* Speaker */ -static const char *rt5625_spk_out[] = {"Class AB", "Class D"}; - -static const SOC_ENUM_SINGLE_DECL(rt5625_spk_out_enum, - RT5625_OUTMIX_CTRL, RT5625_SPK_T_SFT, rt5625_spk_out); - -static const char *rt5625_spkl_src[] = {"LPRN", "LPRP", "LPLN", "MM"}; - -static const SOC_ENUM_SINGLE_DECL(rt5625_spkl_src_enum, - RT5625_OUTMIX_CTRL, RT5625_SPKN_S_SFT, rt5625_spkl_src); - -static const char *rt5625_spkamp_ratio[] = {"2.25 Vdd", "2.00 Vdd", - "1.75 Vdd", "1.50 Vdd", "1.25 Vdd", "1.00 Vdd"}; - -static const SOC_ENUM_SINGLE_DECL(rt5625_spkamp_ratio_enum, - RT5625_GEN_CTRL1, RT5625_SPK_R_SFT, rt5625_spkamp_ratio); - -static const char *rt5625_Pin_mode[] = {"IRQ Out", "GPIO enable", "Reserved", "VoDSP bypass"}; -static const char *rt5625_Pin_configuration[] = {"Output", "Input"}; -static const char *rt5625_Pin_level[] = {"Low", "High"}; - -/* Output/Input Mode */ -//static const char *rt5625_auxout_mode[] = {"Differential", "Single ended"}; - -//static const SOC_ENUM_SINGLE_DECL(rt5625_auxout_mode_enum, -// RT5625_OUTMIX_CTRL, RT5625_AUXOUT_MODE_SFT, rt5625_auxout_mode); - -//static const char *rt5625_input_mode[] = {"Single ended", "Differential"}; - -//static const SOC_ENUM_SINGLE_DECL(rt5625_phone_mode_enum, -// RT5625_PHONEIN_VOL, RT5625_PHO_DIFF_SFT, rt5625_input_mode); - -//static const SOC_ENUM_SINGLE_DECL(rt5625_mic1_mode_enum, -// RT5625_MIC_VOL, RT5625_MIC1_DIFF_SFT, rt5625_input_mode); - -//static const SOC_ENUM_SINGLE_DECL(rt5625_mic2_mode_enum, -// RT5625_MIC_VOL, RT5625_MIC2_DIFF_SFT, rt5625_input_mode); - -static const struct soc_enum rt5625_gpio2_enum[] = { -SOC_ENUM_SINGLE(RT5625_GPIO_SHARING, 0, 4, rt5625_Pin_mode), /*0*/ -SOC_ENUM_SINGLE(RT5625_GPIO_CONFIG, 2, 2, rt5625_Pin_configuration),/*1*/ -SOC_ENUM_SINGLE(RT5625_GPIO_OUT_CTRL, 2, 2, rt5625_Pin_level), /*2*/ -}; - -static int rt5625_adcr_fun_sel_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec); - unsigned int val, mask, bitmask; - - for (bitmask = 1; bitmask < e->max; bitmask <<= 1) - ; - if (ucontrol->value.enumerated.item[0] > e->max - 1) - return -EINVAL; - val = ucontrol->value.enumerated.item[0] << e->shift_l; - mask = (bitmask - 1) << e->shift_l; - - snd_soc_update_bits(codec, RT5625_PD_CTRL, - RT5625_PWR_PR0, RT5625_PWR_PR0); - if ((rt5625->app_bmp & RT5625_3G_MASK) && - rt5625->vodsp_fun == RT5625_AEC_EN) { - snd_soc_update_bits(codec, e->reg, mask, RT5625_ADCR_F_PDM); - } else if (rt5625->app_bmp & RT5625_VOIP_MASK && - rt5625->vodsp_fun == RT5625_AEC_EN) { - snd_soc_update_bits(codec, e->reg, mask, RT5625_ADCR_F_PDM); - } else if (rt5625->app_bmp & RT5625_BT_MASK) { - snd_soc_update_bits(codec, e->reg, mask, RT5625_ADCR_F_VADC); - } else { - snd_soc_update_bits(codec, e->reg, mask, val); - } - snd_soc_update_bits(codec, RT5625_PD_CTRL, RT5625_PWR_PR0, 0); - - return 0; -} - -static int rt5625_adcl_fun_sel_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec); - unsigned int val, mask, bitmask; - - for (bitmask = 1; bitmask < e->max; bitmask <<= 1) - ; - if (ucontrol->value.enumerated.item[0] > e->max - 1) - return -EINVAL; - val = ucontrol->value.enumerated.item[0] << e->shift_l; - mask = (bitmask - 1) << e->shift_l; - - snd_soc_update_bits(codec, RT5625_PD_CTRL, - RT5625_PWR_PR0, RT5625_PWR_PR0); - if ((rt5625->app_bmp & RT5625_3G_MASK) && - rt5625->vodsp_fun == RT5625_AEC_EN) { - snd_soc_update_bits(codec, e->reg, mask, RT5625_ADCL_F_DSP); - } else { - snd_soc_update_bits(codec, e->reg, mask, val); - } - snd_soc_update_bits(codec, RT5625_PD_CTRL, RT5625_PWR_PR0, 0); - - return 0; -} - -static int rt5625_init_vodsp_aec(struct snd_soc_codec *codec) -{ - int i, ret = 0; - - /*disable LDO power*/ - snd_soc_update_bits(codec, RT5625_LDO_CTRL, - RT5625_LDO_MASK, RT5625_LDO_DIS); - mdelay(20); - snd_soc_update_bits(codec, RT5625_VODSP_CTL, - RT5625_DSP_PD_MASK, RT5625_DSP_PD_NOR); - /*enable LDO power and set output voltage to 1.2V*/ - snd_soc_update_bits(codec, RT5625_LDO_CTRL, - RT5625_LDO_MASK | RT5625_LDO_VC_MASK, - RT5625_LDO_EN | RT5625_LDO_VC_1_20V); - mdelay(20); - /*enable power of VODSP I2C interface*/ - snd_soc_update_bits(codec, RT5625_PWR_ADD3, RT5625_P_DSP_IF | - RT5625_P_DSP_I2C, RT5625_P_DSP_IF | RT5625_P_DSP_I2C); - mdelay(1); - /*Reset VODSP*/ - snd_soc_update_bits(codec, RT5625_VODSP_CTL, - RT5625_DSP_RST_MASK, RT5625_DSP_RST_EN); - mdelay(1); - /*set VODSP to non-reset status*/ - snd_soc_update_bits(codec, RT5625_VODSP_CTL, - RT5625_DSP_RST_MASK, RT5625_DSP_RST_NOR); - mdelay(20); - - /*initize AEC paramter*/ - for(i = 0; i < RT5625_DSP_INIT_NUM; i++) { - ret = rt5625_dsp_write(codec, rt5625_dsp_init[i].index, - rt5625_dsp_init[i].value); - if(ret) - return -EIO; - } - mdelay(10); - //printk("[DSP poweron] 0x%04x: 0x%04x\n", 0x230C, rt5625_dsp_read(codec, 0x230C)); - - return 0; -} - -static int rt5625_aec_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec); - - ucontrol->value.integer.value[0] = rt5625->vodsp_fun; - return 0; -} - - -static int rt5625_aec_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec); - - if(ucontrol->value.integer.value[0] == rt5625->vodsp_fun) - return 0; - rt5625->vodsp_fun = ucontrol->value.integer.value[0]; - - switch(rt5625->vodsp_fun) { - case RT5625_AEC_EN: - break; - case RT5625_AEC_DIS: - if (!(rt5625->app_bmp & RT5625_3G_MASK) || - ((rt5625->app_bmp & RT5625_3G_MASK) && rt5625->headset)) { - snd_soc_update_bits(codec, RT5625_VODSP_CTL, - RT5625_DSP_PD_MASK, RT5625_DSP_PD_EN); - snd_soc_update_bits(codec, RT5625_PWR_ADD3, - RT5625_P_DSP_IF | RT5625_P_DSP_I2C, 0); - snd_soc_update_bits(codec, RT5625_LDO_CTRL, - RT5625_LDO_MASK, RT5625_LDO_DIS); - } - break; - default: - break; - } - - return 0; -} - -#ifdef RT5625_F_SMT_PHO -static int rt5625_app_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec); - - pr_info("App status: %x\n", rt5625->app_bmp); - - return 0; -} - -static int rt5625_cap_voip_chk_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec); - int i, upd; - - /* VoIP start up if record & playback all turn on, or AEC * - * is disabled. otherwise, cheat dapm. */ - if ((rt5625->app_bmp & RT5625_REC_MASK) == 0 || - (rt5625->app_bmp & RT5625_PLY_MASK) == 0) { - /* backup registers for voip routing */ - for(i = 0; i < RT5625_VOIP_BK_NUM; i++) - rt5625_voip_back[i][1] = - snd_soc_read(codec, rt5625_voip_back[i][0]); - /* cheat dapm */ - snd_soc_update_bits(codec, RT5625_VODSP_PDM_CTL, - RT5625_REC_IIS_S_MASK, RT5625_REC_IIS_S_SRC2); - return 0; - } - - if (rt5625->headset) { - /* backup registers for voip routing */ - for(i = 0; i < RT5625_VOIP_BK_NUM; i++) - rt5625_voip_back[i][1] = - snd_soc_read(codec, rt5625_voip_back[i][0]); - /* cheat dapm */ - snd_soc_update_bits(codec, RT5625_VODSP_PDM_CTL, - RT5625_REC_IIS_S_MASK, RT5625_REC_IIS_S_SRC2); - } else - rt5625->vodsp_fun = RT5625_AEC_EN; - - upd = (rt5625->app_bmp & ~RT5625_VOIP_MASK) | - (ucontrol->value.integer.value[0] << RT5625_VOIP_BIT); - if (rt5625->app_bmp != upd) { - rt5625->app_bmp = upd; - rt5625->app_bmp &= ~(RT5625_3G_MASK | RT5625_BT_MASK); - } - - return 0; -} - -static int rt5625_cap_voip_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec); - int i; - - if (rt5625->app_bmp & RT5625_VOIP_MASK) { - if (rt5625->headset) { - snd_soc_update_bits(codec, RT5625_ADC_REC_MIXER, - RT5625_M_RM_L_MIC1 | RT5625_M_RM_R_MIC1 | RT5625_M_RM_L_PHO, - RT5625_M_RM_L_MIC1 | RT5625_M_RM_R_MIC1 | RT5625_M_RM_L_PHO); - /* recover all changes by voip */ - for(i = 0; i < RT5625_VOIP_BK_NUM; i++) - snd_soc_write(codec, rt5625_voip_back[i][0], - rt5625_voip_back[i][1]); - snd_soc_update_bits(codec, RT5625_VODSP_PDM_CTL, - RT5625_SRC1_PWR | RT5625_SRC2_PWR, 0); - } else { - snd_soc_update_bits(codec, RT5625_ADC_REC_MIXER, - RT5625_M_RM_L_MIC1 | RT5625_M_RM_L_MIC2 | RT5625_M_RM_R_MIC2 | RT5625_M_RM_L_PHO, - RT5625_M_RM_L_MIC1 | RT5625_M_RM_L_MIC2 | RT5625_M_RM_R_MIC2 | RT5625_M_RM_L_PHO); - rt5625->vodsp_fun = RT5625_AEC_EN; - /* Mic1 & Mic2 boost 0db */ - snd_soc_update_bits(codec, RT5625_MIC_CTRL, - RT5625_MIC1_BST_MASK | RT5625_MIC2_BST_MASK, - RT5625_MIC1_BST_BYPASS | RT5625_MIC2_BST_BYPASS); - /* Capture volume gain 9db */ - snd_soc_update_bits(codec, RT5625_ADC_REC_GAIN, - RT5625_G_ADCL_MASK | RT5625_G_ADCR_MASK, (0x11 << 8 ) | 0x11); - } - } else { - /* recover all changes by voip */ - for(i = 0; i < RT5625_VOIP_BK_NUM; i++) - snd_soc_write(codec, rt5625_voip_back[i][0], - rt5625_voip_back[i][1]); - snd_soc_update_bits(codec, RT5625_VODSP_PDM_CTL, - RT5625_SRC1_PWR | RT5625_SRC2_PWR, 0); - if (rt5625->app_bmp & RT5625_3G_MASK && - rt5625->vodsp_fun == RT5625_AEC_EN) { - /* Mic1 boost 0db */ - snd_soc_update_bits(codec, RT5625_MIC_CTRL, - RT5625_MIC1_BST_MASK, RT5625_MIC1_BST_BYPASS); - /* Capture volume gain 9db */ - snd_soc_update_bits(codec, RT5625_ADC_REC_GAIN, - RT5625_G_ADCR_MASK, 0x11); - } - } - - return 0; -} - -static int rt5625_hs_voip_chk_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec); - int i, upd; - - rt5625->headset = true; - if ((rt5625->app_bmp & RT5625_REC_MASK) == 0 || - (rt5625->app_bmp & RT5625_PLY_MASK) == 0) { - /* backup registers for voip routing */ - for(i = 0; i < RT5625_VOIP_BK_NUM; i++) - rt5625_voip_back[i][1] = - snd_soc_read(codec, rt5625_voip_back[i][0]); - rt5625->vodsp_fun_bak = rt5625->vodsp_fun; - /* cheat dapm */ - snd_soc_update_bits(codec, RT5625_VODSP_PDM_CTL, - RT5625_REC_IIS_S_MASK | RT5625_RXDP_PWR, RT5625_REC_IIS_S_ADC); - return 0; - } - - upd = (rt5625->app_bmp & ~RT5625_VOIP_MASK) | - (ucontrol->value.integer.value[0] << RT5625_VOIP_BIT); - if (rt5625->app_bmp != upd) { - rt5625->app_bmp = upd; - rt5625->app_bmp &= ~(RT5625_3G_MASK | RT5625_BT_MASK); - } - - return 0; -} - -static int rt5625_hs_voip_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec); - int i; - - if (rt5625->app_bmp & RT5625_VOIP_MASK) { - snd_soc_update_bits(codec, RT5625_ADC_REC_MIXER, - RT5625_M_RM_R_MIC1 | RT5625_M_RM_L_PHO, - RT5625_M_RM_R_MIC1 | RT5625_M_RM_L_PHO); - /* Mic1 & Mic2 boost 0db */ - snd_soc_update_bits(codec, RT5625_MIC_CTRL, - RT5625_MIC1_BST_MASK | RT5625_MIC2_BST_MASK, - RT5625_MIC1_BST_BYPASS | RT5625_MIC2_BST_BYPASS); - /* Capture volume gain 9db */ - snd_soc_update_bits(codec, RT5625_ADC_REC_GAIN, - RT5625_G_ADCL_MASK | RT5625_G_ADCR_MASK, (0x11 << 8 ) | 0x11); - } else { - /* recover all changes by voip */ - for(i = 0; i < RT5625_VOIP_BK_NUM; i++) - snd_soc_write(codec, rt5625_voip_back[i][0], - rt5625_voip_back[i][1]); - rt5625->vodsp_fun = rt5625->vodsp_fun_bak; - if ((rt5625->app_bmp & RT5625_3G_MASK) && rt5625->vodsp_fun == RT5625_AEC_EN) { - snd_soc_update_bits(codec, RT5625_F_DAC_ADC_VDAC, - RT5625_ADCR_F_MASK, RT5625_ADCR_F_PDM); - } else if (rt5625->app_bmp & RT5625_BT_MASK) { - snd_soc_update_bits(codec, RT5625_F_DAC_ADC_VDAC, - RT5625_ADCR_F_MASK, RT5625_ADCR_F_VADC); - } else { - snd_soc_update_bits(codec, RT5625_F_DAC_ADC_VDAC, - RT5625_ADCR_F_MASK, RT5625_ADCR_F_ADC); - } - } - - return 0; -} - -static int rt5625_voip_chk_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec); - int i, upd; - - rt5625->headset = false; - /* voip start-up if record is on-going; otherwise, cheat dapm */ - if ((rt5625->app_bmp & RT5625_REC_MASK) == 0 || - (rt5625->app_bmp & RT5625_PLY_MASK) == 0) { - /* backup registers for voip routing */ - for(i = 0; i < RT5625_VOIP_BK_NUM; i++) - rt5625_voip_back[i][1] = - snd_soc_read(codec, rt5625_voip_back[i][0]); - rt5625->vodsp_fun_bak = rt5625->vodsp_fun; - /* cheat dapm */ - snd_soc_update_bits(codec, RT5625_VODSP_PDM_CTL, - RT5625_RXDP_S_MASK | RT5625_REC_IIS_S_MASK | RT5625_RXDP_PWR, - RT5625_RXDP_S_SRC1 | RT5625_REC_IIS_S_SRC2); - return 0; - } - - upd = (rt5625->app_bmp & ~RT5625_VOIP_MASK) | - (ucontrol->value.integer.value[0] << RT5625_VOIP_BIT); - if (rt5625->app_bmp != upd) { - rt5625->app_bmp = upd; - rt5625->app_bmp &= ~(RT5625_3G_MASK | RT5625_BT_MASK); - } - - return 0; -} - -static int rt5625_voip_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec); - int i; - - if (rt5625->app_bmp & RT5625_VOIP_MASK) { - snd_soc_update_bits(codec, RT5625_ADC_REC_MIXER, - RT5625_M_RM_R_MIC2 | RT5625_M_RM_L_PHO, - RT5625_M_RM_R_MIC2 | RT5625_M_RM_L_PHO); - /* Mic1 & Mic2 boost 0db */ - snd_soc_update_bits(codec, RT5625_MIC_CTRL, - RT5625_MIC1_BST_MASK | RT5625_MIC2_BST_MASK, - RT5625_MIC1_BST_BYPASS | RT5625_MIC2_BST_BYPASS); - /* Capture volume gain 9db */ - snd_soc_update_bits(codec, RT5625_ADC_REC_GAIN, - RT5625_G_ADCL_MASK | RT5625_G_ADCR_MASK, (0x11 << 8 ) | 0x11); - } else { - /* recover all changes by voip */ - for(i = 0; i < RT5625_VOIP_BK_NUM; i++) - snd_soc_write(codec, rt5625_voip_back[i][0], - rt5625_voip_back[i][1]); - rt5625->vodsp_fun = rt5625->vodsp_fun_bak; - snd_soc_update_bits(codec, RT5625_VODSP_PDM_CTL, - RT5625_SRC1_PWR | RT5625_SRC2_PWR, 0); - if ((rt5625->app_bmp & RT5625_3G_MASK) && rt5625->vodsp_fun == RT5625_AEC_EN) { - snd_soc_update_bits(codec, RT5625_F_DAC_ADC_VDAC, - RT5625_ADCR_F_MASK, RT5625_ADCR_F_PDM); - } else if (rt5625->app_bmp & RT5625_BT_MASK) { - snd_soc_update_bits(codec, RT5625_F_DAC_ADC_VDAC, - RT5625_ADCR_F_MASK, RT5625_ADCR_F_VADC); - } else { - snd_soc_update_bits(codec, RT5625_F_DAC_ADC_VDAC, - RT5625_ADCR_F_MASK, RT5625_ADCR_F_ADC); - } - } - - return 0; -} - -static int rt5625_voip_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec); - - ucontrol->value.integer.value[0] = - (rt5625->app_bmp & RT5625_VOIP_MASK) >> RT5625_VOIP_BIT; - - return 0; -} - -static int rt5625_play_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec); - - ucontrol->value.integer.value[0] = - (rt5625->app_bmp & RT5625_PLY_MASK) >> RT5625_PLY_BIT; - - return 0; -} - -static int rt5625_play_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec); - int upd; - - upd = (rt5625->app_bmp & ~RT5625_PLY_MASK) | - (ucontrol->value.integer.value[0] << RT5625_PLY_BIT); - if (rt5625->app_bmp != upd) - rt5625->app_bmp = upd; - - if (!(rt5625->app_bmp & RT5625_3G_MASK) || - ((rt5625->app_bmp & RT5625_3G_MASK) && rt5625->headset)) { - snd_soc_update_bits(codec, RT5625_ADC_REC_MIXER, - RT5625_M_RM_L_PHO, RT5625_M_RM_L_PHO); - } - - return 0; -} - -static int rt5625_rec_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec); - - ucontrol->value.integer.value[0] = - (rt5625->app_bmp & RT5625_REC_MASK) >> RT5625_REC_BIT; - - return 0; -} - -static int rt5625_rec_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec); - int upd; - - upd = (rt5625->app_bmp & ~RT5625_REC_MASK) | - (ucontrol->value.integer.value[0] << RT5625_REC_BIT); - if (rt5625->app_bmp != upd) - rt5625->app_bmp = upd; - - if (!(rt5625->app_bmp & RT5625_3G_MASK) || - ((rt5625->app_bmp & RT5625_3G_MASK) && rt5625->headset)) { - snd_soc_update_bits(codec, RT5625_ADC_REC_MIXER, - RT5625_M_RM_L_PHO, RT5625_M_RM_L_PHO); - } - - - return 0; -} - -static int rt5625_bt_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec); - - ucontrol->value.integer.value[0] = - (rt5625->app_bmp & RT5625_BT_MASK) >> RT5625_BT_BIT; - - return 0; -} - -static int rt5625_bt_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec); - int upd; - - if (!(rt5625->app_bmp & RT5625_REC_MASK)) { - snd_soc_update_bits(codec, RT5625_ADC_REC_MIXER, - RT5625_M_RM_L_MIC1 | RT5625_M_RM_L_MIC2 | - RT5625_M_RM_R_MIC1 | RT5625_M_RM_R_MIC2, - RT5625_M_RM_L_MIC1 | RT5625_M_RM_L_MIC2 | - RT5625_M_RM_R_MIC1 | RT5625_M_RM_R_MIC2); - } - - upd = (rt5625->app_bmp & ~RT5625_BT_MASK) | - (ucontrol->value.integer.value[0] << RT5625_BT_BIT); - if (rt5625->app_bmp != upd) { - rt5625->app_bmp = upd; - rt5625->app_bmp &= ~(RT5625_3G_MASK | RT5625_VOIP_MASK); - } - - return 0; -} - -static int rt5625_3g_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec); - - ucontrol->value.integer.value[0] = - (rt5625->app_bmp & RT5625_3G_MASK) >> RT5625_3G_BIT; - - return 0; -} - -static int rt5625_3g_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec); - int upd; - - rt5625->headset = false; - if (!(rt5625->app_bmp & RT5625_REC_MASK)) { - snd_soc_update_bits(codec, RT5625_ADC_REC_MIXER, - RT5625_M_RM_L_MIC1 | RT5625_M_RM_L_MIC2 | RT5625_M_RM_R_MIC2, - RT5625_M_RM_L_MIC1 | RT5625_M_RM_L_MIC2 | RT5625_M_RM_R_MIC2); - } - - upd = (rt5625->app_bmp & ~RT5625_3G_MASK) | - (ucontrol->value.integer.value[0] << RT5625_3G_BIT); - if (rt5625->app_bmp != upd) { - rt5625->app_bmp = upd; - rt5625->app_bmp &= ~(RT5625_BT_MASK | RT5625_VOIP_MASK); - } - - return 0; -} - -static int rt5625_hs_3g_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec); - int upd; - - rt5625->headset = true; - if (!(rt5625->app_bmp & RT5625_REC_MASK)) { - snd_soc_update_bits(codec, RT5625_ADC_REC_MIXER, - RT5625_M_RM_L_MIC1 | RT5625_M_RM_L_MIC2 | - RT5625_M_RM_R_MIC1 | RT5625_M_RM_R_MIC2, - RT5625_M_RM_L_MIC1 | RT5625_M_RM_L_MIC2 | - RT5625_M_RM_R_MIC1 | RT5625_M_RM_R_MIC2); - } - upd = (rt5625->app_bmp & ~RT5625_3G_MASK) | - (ucontrol->value.integer.value[0] << RT5625_3G_BIT); - if (rt5625->app_bmp != upd) { - rt5625->app_bmp = upd; - rt5625->app_bmp &= ~(RT5625_BT_MASK | RT5625_VOIP_MASK); - } - - return 0; -} - -static int rt5625_dump_dsp_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - int i; - u16 val; - - pr_info("\n[ RT5625 DSP Register ]\n"); - for (i = 0; i < RT5625_DSP_INIT_NUM; i++) { - val = rt5625_dsp_read(codec, rt5625_dsp_init[i].index); - if (val) pr_info(" 0x%x: 0x%x\n", - rt5625_dsp_init[i].index, val); - } - return 0; -} - -static int rt5625_dac_active_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec); - - ucontrol->value.integer.value[0] = rt5625->dac_active; - return 0; -} - -static int rt5625_dac_active_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct snd_soc_dapm_context *dapm = &codec->dapm; - struct snd_soc_dapm_widget *w; - struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec); - - if(ucontrol->value.integer.value[0] == rt5625->dac_active) - return 0; - rt5625->dac_active = ucontrol->value.integer.value[0]; - - /* playback is on-going; do nothing when turn off BT */ - if (rt5625->dac_active == 0 && rt5625->app_bmp & RT5625_PLY_MASK) - return 0; - - list_for_each_entry(w, &dapm->card->widgets, list) - { - if (!w->sname || w->dapm != dapm) - continue; - if (strstr(w->sname, "Playback")) { - pr_info("widget %s %s %s\n", w->name, w->sname, - rt5625->dac_active ? "active" : "inactive"); - w->active = rt5625->dac_active; - } - } - - if (!(rt5625->dac_active)) - snd_soc_dapm_sync(dapm); - - return 0; -} - -static int rt5625_adc_active_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec); - - ucontrol->value.integer.value[0] = rt5625->adc_active; - return 0; -} - -static int rt5625_adc_active_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct snd_soc_dapm_context *dapm = &codec->dapm; - struct snd_soc_dapm_widget *w; - struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec); - - if(ucontrol->value.integer.value[0] == rt5625->adc_active) - return 0; - rt5625->adc_active = ucontrol->value.integer.value[0]; - - /* record is on-going; do nothing when turn off BT */ - if (rt5625->adc_active == 0 && rt5625->app_bmp & RT5625_REC_MASK) - return 0; - - list_for_each_entry(w, &dapm->card->widgets, list) - { - if (!w->sname || w->dapm != dapm) - continue; - if (strstr(w->sname, "Capture")) { - pr_info("widget %s %s %s\n", w->name, w->sname, - rt5625->adc_active ? "active" : "inactive"); - w->active = rt5625->adc_active; - } - } - - if (!(rt5625->adc_active)) - snd_soc_dapm_sync(dapm); - - return 0; -} - -static int rt5625_pll_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec); - - ucontrol->value.integer.value[0] = rt5625->pll_sel; - return 0; -} - - -static int rt5625_pll_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec); - - if(ucontrol->value.integer.value[0] == rt5625->pll_sel) - return 0; - rt5625->pll_sel = ucontrol->value.integer.value[0]; - - switch(rt5625->pll_sel) { - case RT5625_PLL_DIS: - pr_info("%s(): Disable\n", __func__); - snd_soc_update_bits(codec, RT5625_GEN_CTRL1, - RT5625_SCLK_PLL1, 0); - snd_soc_write(codec, RT5625_DAC_CLK_CTRL2, 0); - break; - - case RT5625_PLL_112896_225792: - pr_info("%s(): 11.2896>22.5792\n", __func__); - snd_soc_write(codec, RT5625_GEN_CTRL2, 0x0000); - snd_soc_write(codec, RT5625_PLL_CTRL, 0x06a0); - snd_soc_update_bits(codec, RT5625_GEN_CTRL1, - RT5625_SCLK_PLL1, RT5625_SCLK_PLL1); - snd_soc_write(codec, RT5625_DAC_CLK_CTRL2, 0x0210); - break; - - case RT5625_PLL_112896_24576: - pr_info("%s(): 11.2896->24.576\n", __func__); - snd_soc_write(codec, RT5625_GEN_CTRL2, 0x0000); - snd_soc_write(codec, RT5625_PLL_CTRL, 0x922f); - snd_soc_update_bits(codec, RT5625_GEN_CTRL1, - RT5625_SCLK_PLL1, RT5625_SCLK_PLL1); - snd_soc_write(codec, RT5625_DAC_CLK_CTRL2, 0x0210); - break; - - default: - break; - } - - return 0; -} - -static int rt5625_pll2_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec); - - ucontrol->value.integer.value[0] = rt5625->pll2_sel; - return 0; -} - -static int rt5625_pll2_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec); - - if(ucontrol->value.integer.value[0] == rt5625->pll2_sel) - return 0; - rt5625->pll2_sel = ucontrol->value.integer.value[0]; - - if(rt5625->pll2_sel != RT5625_PLL_DIS) { - snd_soc_update_bits(codec, RT5625_GEN_CTRL1, - RT5625_VSCLK_MASK, RT5625_VSCLK_PLL2); - snd_soc_write(codec, RT5625_PLL2_CTRL, RT5625_PLL2_EN); - snd_soc_write(codec, RT5625_VDAC_CLK_CTRL1, - RT5625_VBCLK_DIV1_4); - snd_soc_update_bits(codec, RT5625_EXT_SDP_CTRL, - RT5625_PCM_CS_MASK, RT5625_PCM_CS_VSCLK); - } - - return 0; -} - -static const char *rt5625_pll_sel[] = {"Disable", "11.2896->22.5792", "11.2896->24.576"}; - -static const SOC_ENUM_SINGLE_DECL(rt5625_pll_sel_enum, 0, 0, rt5625_pll_sel); - -static const char *rt5625_pll2_sel[] = {"Disable", "Enable"}; - -static const SOC_ENUM_SINGLE_DECL(rt5625_pll2_sel_enum, 0, 0, rt5625_pll2_sel); -#endif - -static const char *rt5625_AUXOUT_mode[] = {"Differential mode", "Single-ended mode"}; -static const char *rt5625_Differential_Input_Control[] = {"Disable", "Enable"}; - -static const struct soc_enum rt5625_differential_enum[] = { -SOC_ENUM_SINGLE(RT5625_OUTMIX_CTRL, 4, 2, rt5625_AUXOUT_mode), /*0*/ -SOC_ENUM_SINGLE(RT5625_PHONEIN_VOL, 13, 2, rt5625_Differential_Input_Control),/*1*/ -SOC_ENUM_SINGLE(RT5625_MIC_VOL, 15, 2, rt5625_Differential_Input_Control), /*2*/ -SOC_ENUM_SINGLE(RT5625_MIC_VOL, 7, 2, rt5625_Differential_Input_Control), /*3*/ -}; - -static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -4650, 150, 0); -static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -3525, 75, 0); -static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0); -static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -1650, 150, 0); -static const DECLARE_TLV_DB_SCALE(dmic_bst_tlv, 0, 600, 0); -/* {0, +20, +30, +40} dB */ -static unsigned int mic_bst_tlv[] = { - TLV_DB_RANGE_HEAD(2), - 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0), - 1, 3, TLV_DB_SCALE_ITEM(2000, 1000, 0), -}; - -#ifdef RT5625_REG_RW -#define REGVAL_MAX 0xffff -static unsigned int regctl_addr = 0x3e; -static int rt5625_regctl_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 2; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = REGVAL_MAX; - return 0; -} - -static int rt5625_regctl_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - ucontrol->value.integer.value[0] = regctl_addr; - ucontrol->value.integer.value[1] = snd_soc_read(codec, regctl_addr); - return 0; -} - -static int rt5625_regctl_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - regctl_addr = ucontrol->value.integer.value[0]; - if(ucontrol->value.integer.value[1] <= REGVAL_MAX) - snd_soc_write(codec, regctl_addr, ucontrol->value.integer.value[1]); - return 0; -} -#endif - -/*speaker ext control*/ -static const struct soc_enum spk_ctr_enum = - SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(rt5625_spk_ctr_sel), rt5625_spk_ctr_sel); - -static int rt5625_spk_ctr_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec); - - ucontrol->value.integer.value[0] = rt5625->spk_ctr_status; - return 0; -} - -static int rt5625_spk_ctr_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec); - - rt5625->spk_ctr_status = ucontrol->value.integer.value[0]; - - if(rt5625->spk_ctr_pin != INVALID_GPIO) - { - if(rt5625->spk_ctr_status) - gpio_set_value(rt5625->spk_ctr_pin,rt5625->spk_ctr_on); - else - gpio_set_value(rt5625->spk_ctr_pin,rt5625->spk_ctr_off); - } - return 0; -} - -static const struct snd_kcontrol_new rt5625_snd_controls[] = { - - #if defined (CONFIG_SND_SOC_RT5625_SPK_FORM_SPKOUT) - SOC_DOUBLE_TLV("SPKOUT Playback Volume", RT5625_SPK_OUT_VOL, - RT5625_L_VOL_SFT, RT5625_R_VOL_SFT, 31, 1, out_vol_tlv), - SOC_DOUBLE("SPKOUT Playback Switch", RT5625_SPK_OUT_VOL, - RT5625_L_MUTE_SFT, RT5625_R_MUTE_SFT, 1, 1), - SOC_DOUBLE_TLV("Earpiece Playback Volume", RT5625_SPK_OUT_VOL, - RT5625_L_VOL_SFT, RT5625_R_VOL_SFT, 31, 1, out_vol_tlv), - SOC_DOUBLE("Earpiece Playback Switch", RT5625_SPK_OUT_VOL, - RT5625_L_MUTE_SFT, RT5625_R_MUTE_SFT, 1, 1), - #endif - - #if defined (CONFIG_SND_SOC_RT5625_SPK_FORM_HPOUT) - SOC_DOUBLE_TLV("SPKOUT Playback Volume", RT5625_HP_OUT_VOL, - RT5625_L_VOL_SFT, RT5625_R_VOL_SFT, 31, 1, out_vol_tlv), - SOC_DOUBLE("SPKOUT Playback Switch", RT5625_HP_OUT_VOL, - RT5625_L_MUTE_SFT, RT5625_R_MUTE_SFT, 1, 1), - SOC_DOUBLE_TLV("Earpiece Playback Volume", RT5625_HP_OUT_VOL, - RT5625_L_VOL_SFT, RT5625_R_VOL_SFT, 31, 1, out_vol_tlv), - SOC_DOUBLE("Earpiece Playback Switch", RT5625_HP_OUT_VOL, - RT5625_L_MUTE_SFT, RT5625_R_MUTE_SFT, 1, 1), - SOC_ENUM_EXT("SPK_CTR",spk_ctr_enum, rt5625_spk_ctr_get, rt5625_spk_ctr_put), - #endif - - SOC_ENUM("SPK Amp Type", rt5625_spk_out_enum), - SOC_ENUM("Left SPK Source", rt5625_spkl_src_enum), - SOC_ENUM("SPK Amp Ratio", rt5625_spkamp_ratio_enum), - //SOC_DOUBLE_TLV("Headphone Playback Volume", RT5625_HP_OUT_VOL, - // RT5625_L_VOL_SFT, RT5625_R_VOL_SFT, 31, 1, out_vol_tlv), - //SOC_DOUBLE("Headphone Playback Switch", RT5625_HP_OUT_VOL, - // RT5625_L_MUTE_SFT, RT5625_R_MUTE_SFT, 1, 1), - //SOC_ENUM("AUXOUT Mode Control", rt5625_auxout_mode_enum), - SOC_DOUBLE_TLV("AUXOUT Playback Volume", RT5625_AUX_OUT_VOL, - RT5625_L_VOL_SFT, RT5625_R_VOL_SFT, 31, 1, out_vol_tlv), - SOC_DOUBLE("AUXOUT Playback Switch", RT5625_AUX_OUT_VOL, - RT5625_L_MUTE_SFT, RT5625_R_MUTE_SFT, 1, 1), - SOC_DOUBLE_TLV("PCM Playback Volume", RT5625_DAC_VOL, - RT5625_L_VOL_SFT, RT5625_R_VOL_SFT, 63, 1, dmic_bst_tlv), - //SOC_ENUM("Phone Mode Control", rt5625_phone_mode_enum), - SOC_SINGLE_TLV("Phone Playback Volume", RT5625_PHONEIN_VOL, - RT5625_L_VOL_SFT, 31, 1, in_vol_tlv), - //SOC_ENUM("MIC1 Mode Control", rt5625_mic1_mode_enum), - SOC_SINGLE_TLV("MIC1 Boost", RT5625_MIC_CTRL, - RT5625_MIC1_BST_SFT, 3, 0, mic_bst_tlv), - SOC_SINGLE_TLV("Mic1 Playback Volume", RT5625_MIC_VOL, - RT5625_L_VOL_SFT, 31, 1, in_vol_tlv), - //SOC_ENUM("MIC2 Mode Control", rt5625_mic2_mode_enum), - SOC_SINGLE_TLV("MIC2 Boost", RT5625_MIC_CTRL, - RT5625_MIC2_BST_SFT, 3, 0, mic_bst_tlv), - SOC_SINGLE_TLV("Mic2 Playback Volume", RT5625_MIC_VOL, - RT5625_R_VOL_SFT, 31, 1, in_vol_tlv), - SOC_SINGLE_TLV("Dmic Boost", RT5625_DMIC_CTRL, - RT5625_DIG_BST_SFT, 7, 0, dmic_bst_tlv), - SOC_DOUBLE_TLV("LineIn Playback Volume", RT5625_LINE_IN_VOL, - RT5625_L_VOL_SFT, RT5625_R_VOL_SFT, 31, 1, in_vol_tlv), - SOC_DOUBLE_TLV("PCM Capture Volume", RT5625_ADC_REC_GAIN, - RT5625_L_VOL_SFT, RT5625_R_VOL_SFT, 31, 0, adc_vol_tlv), - //SOC_DOUBLE_TLV("ADC Record Gain", RT5625_ADC_REC_GAIN, - // RT5625_L_VOL_SFT, RT5625_R_VOL_SFT, 31, 0, adc_vol_tlv), - /* This item does'nt affect path connected; only for clock choosen */ - SOC_ENUM_EXT("ADCR fun select Control", adcr_fun_sel_enum, - snd_soc_get_enum_double, rt5625_adcr_fun_sel_put), - SOC_ENUM_EXT("ADCL fun select Control", adcl_fun_sel_enum, - snd_soc_get_enum_double, rt5625_adcl_fun_sel_put), - - /* Voice DSP */ - SOC_ENUM_EXT("VoDSP AEC", rt5625_aec_fun_enum, - rt5625_aec_get, rt5625_aec_put), - SOC_ENUM("VoDSP LRCK Control", rt5625_dsp_lrck_enum), - SOC_ENUM("VoDSP BP Pin Control", rt5625_bp_ctrl_enum), - SOC_ENUM("VoDSP Power Down Pin Control", rt5625_pd_ctrl_enum), - SOC_ENUM("VoDSP Reset Pin Control", rt5625_rst_ctrl_enum), - -#ifdef RT5625_F_SMT_PHO - SOC_ENUM("GPIO2 mode", rt5625_gpio2_enum[0]), - SOC_ENUM("GPIO2 configuration", rt5625_gpio2_enum[1]), - SOC_ENUM("GPIO2 level", rt5625_gpio2_enum[2]), - - SOC_SINGLE_EXT("VoDSP Dump", 0, 0, 1, 0, rt5625_dump_dsp_get, NULL), - SOC_SINGLE_EXT("DAC Switch", 0, 0, 1, 0, rt5625_dac_active_get, rt5625_dac_active_put), - SOC_SINGLE_EXT("ADC Switch", 0, 0, 1, 0, rt5625_adc_active_get, rt5625_adc_active_put), - SOC_ENUM_EXT("PLL Switch", rt5625_pll_sel_enum, rt5625_pll_get, rt5625_pll_put), - SOC_ENUM_EXT("PLL2 Switch", rt5625_pll2_sel_enum, rt5625_pll2_get, rt5625_pll2_put), - SOC_SINGLE_EXT("VoIP Check", 0, 0, 1, 0, rt5625_voip_get, rt5625_voip_chk_put), - SOC_SINGLE_EXT("VoIP Switch", 0, 0, 1, 0, rt5625_voip_get, rt5625_voip_put), - SOC_SINGLE_EXT("Capture VoIP Check", 0, 0, 1, 0, rt5625_voip_get, rt5625_cap_voip_chk_put), - SOC_SINGLE_EXT("Capture VoIP Switch", 0, 0, 1, 0, rt5625_voip_get, rt5625_cap_voip_put), - SOC_SINGLE_EXT("Headset VoIP Check", 0, 0, 1, 0, rt5625_voip_get, rt5625_hs_voip_chk_put), - SOC_SINGLE_EXT("Headset VoIP Switch", 0, 0, 1, 0, rt5625_voip_get, rt5625_hs_voip_put), - SOC_SINGLE_EXT("Playback Switch", 0, 0, 1, 0, rt5625_play_get, rt5625_play_put), - SOC_SINGLE_EXT("Record Switch", 0, 0, 1, 0, rt5625_rec_get, rt5625_rec_put), - SOC_SINGLE_EXT("BT Switch", 0, 0, 1, 0, rt5625_bt_get, rt5625_bt_put), - SOC_SINGLE_EXT("3G Switch", 0, 0, 1, 0, rt5625_3g_get, rt5625_3g_put), - SOC_SINGLE_EXT("Headset 3G Switch", 0, 0, 1, 0, rt5625_3g_get, rt5625_hs_3g_put), - SOC_SINGLE_EXT("APP disp", 0, 0, 1, 0, rt5625_app_get, NULL), -#endif - //SOC_DOUBLE_TLV("SPKOUT Playback Volume", RT5625_SPK_OUT_VOL, - // RT5625_L_VOL_SFT, RT5625_R_VOL_SFT, 31, 1, out_vol_tlv), - //SOC_DOUBLE("SPKOUT Playback Switch", RT5625_SPK_OUT_VOL, - // RT5625_L_MUTE_SFT, RT5625_R_MUTE_SFT, 1, 1), - SOC_DOUBLE_TLV("HPOUT Playback Volume", RT5625_HP_OUT_VOL, - RT5625_L_VOL_SFT, RT5625_R_VOL_SFT, 31, 1, out_vol_tlv), - SOC_DOUBLE("HPOUT Playback Switch", RT5625_HP_OUT_VOL, - RT5625_L_MUTE_SFT, RT5625_R_MUTE_SFT, 1, 1), - SOC_ENUM("AUXOUT mode switch", rt5625_differential_enum[0]), - SOC_ENUM("Phone Differential Input Control", rt5625_differential_enum[1]), - SOC_ENUM("MIC1 Differential Input Control", rt5625_differential_enum[2]), - SOC_ENUM("MIC2 Differential Input Control", rt5625_differential_enum[3]), - -#ifdef RT5625_REG_RW - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Register Control", - .info = rt5625_regctl_info, - .get = rt5625_regctl_get, - .put = rt5625_regctl_put, - }, -#endif -}; - - - /*Left ADC Rec mixer*/ -static const struct snd_kcontrol_new rt5625_adcl_rec_mixer[] = { - SOC_DAPM_SINGLE("Mic1 Capture Switch", RT5625_ADC_REC_MIXER, - RT5625_M_RM_L_MIC1_SFT, 1, 1), - SOC_DAPM_SINGLE("Mic2 Capture Switch", RT5625_ADC_REC_MIXER, - RT5625_M_RM_L_MIC2_SFT, 1, 1), - SOC_DAPM_SINGLE("LineIn Capture Switch", RT5625_ADC_REC_MIXER, - RT5625_M_RM_L_LINE_SFT, 1, 1), - SOC_DAPM_SINGLE("Phone Capture Switch", RT5625_ADC_REC_MIXER, - RT5625_M_RM_L_PHO_SFT, 1, 1), - SOC_DAPM_SINGLE("HP Mixer Capture Switch", RT5625_ADC_REC_MIXER, - RT5625_M_RM_L_HM_SFT, 1, 1), - SOC_DAPM_SINGLE("SPK Mixer Capture Switch", RT5625_ADC_REC_MIXER, - RT5625_M_RM_L_SM_SFT, 1, 1), - SOC_DAPM_SINGLE("MoNo Mixer Capture Switch", RT5625_ADC_REC_MIXER, - RT5625_M_RM_L_MM_SFT, 1, 1), -}; - -/*Right ADC Rec mixer*/ -static const struct snd_kcontrol_new rt5625_adcr_rec_mixer[] = { - SOC_DAPM_SINGLE("Mic1 Capture Switch", RT5625_ADC_REC_MIXER, - RT5625_M_RM_R_MIC1_SFT, 1, 1), - SOC_DAPM_SINGLE("Mic2 Capture Switch", RT5625_ADC_REC_MIXER, - RT5625_M_RM_R_MIC2_SFT, 1, 1), - SOC_DAPM_SINGLE("LineIn Capture Switch", RT5625_ADC_REC_MIXER, - RT5625_M_RM_R_LINE_SFT, 1, 1), - SOC_DAPM_SINGLE("Phone Capture Switch", RT5625_ADC_REC_MIXER, - RT5625_M_RM_R_PHO_SFT, 1, 1), - SOC_DAPM_SINGLE("HP Mixer Capture Switch", RT5625_ADC_REC_MIXER, - RT5625_M_RM_R_HM_SFT, 1, 1), - SOC_DAPM_SINGLE("SPK Mixer Capture Switch", RT5625_ADC_REC_MIXER, - RT5625_M_RM_R_SM_SFT, 1, 1), - SOC_DAPM_SINGLE("MoNo Mixer Capture Switch", RT5625_ADC_REC_MIXER, - RT5625_M_RM_R_MM_SFT, 1, 1), -}; - -/* HP Mixer for mono input */ -static const struct snd_kcontrol_new rt5625_hp_mixer[] = { - SOC_DAPM_SINGLE("LineIn Playback Switch", RT5625_LINE_IN_VOL, - RT5625_M_LI_HM_SFT, 1, 1), - SOC_DAPM_SINGLE("Phone Playback Switch", RT5625_PHONEIN_VOL, - RT5625_M_PHO_HM_SFT, 1, 1), - SOC_DAPM_SINGLE("Mic1 Playback Switch", RT5625_DAC_MIC_CTRL, - RT5625_M_MIC1_HM_SFT, 1, 1), - SOC_DAPM_SINGLE("Mic2 Playback Switch", RT5625_DAC_MIC_CTRL, - RT5625_M_MIC2_HM_SFT, 1, 1), - SOC_DAPM_SINGLE("Voice DAC Playback Switch", RT5625_VDAC_OUT_VOL, - RT5625_M_VDAC_HM_SFT, 1, 1), -}; - -/* Left HP Mixer */ -static const struct snd_kcontrol_new rt5625_hpl_mixer[] = { - SOC_DAPM_SINGLE("ADC Playback Switch", RT5625_ADC_REC_GAIN, - RT5625_M_ADCL_HM_SFT, 1, 1), - SOC_DAPM_SINGLE("DAC Playback Switch", RT5625_DAC_MIC_CTRL, - RT5625_M_DACL_HM_SFT, 1, 1), -}; - -/* Right HP Mixer */ -static const struct snd_kcontrol_new rt5625_hpr_mixer[] = { - SOC_DAPM_SINGLE("ADC Playback Switch", RT5625_ADC_REC_GAIN, - RT5625_M_ADCR_HM_SFT, 1, 1), - SOC_DAPM_SINGLE("DAC Playback Switch", RT5625_DAC_MIC_CTRL, - RT5625_M_DACR_HM_SFT, 1, 1), -}; - -/* Mono Mixer */ -static const struct snd_kcontrol_new rt5625_mono_mixer[] = { - SOC_DAPM_SINGLE("ADCL Playback Switch", RT5625_ADC_REC_GAIN, - RT5625_M_ADCL_MM_SFT, 1, 1), - SOC_DAPM_SINGLE("ADCR Playback Switch", RT5625_ADC_REC_GAIN, - RT5625_M_ADCR_MM_SFT, 1, 1), - SOC_DAPM_SINGLE("Line Mixer Playback Switch", RT5625_LINE_IN_VOL, - RT5625_M_LI_MM_SFT, 1, 1), - SOC_DAPM_SINGLE("Mic1 Playback Switch", RT5625_DAC_MIC_CTRL, - RT5625_M_MIC1_MM_SFT, 1, 1), - SOC_DAPM_SINGLE("Mic2 Playback Switch", RT5625_DAC_MIC_CTRL, - RT5625_M_MIC2_MM_SFT, 1, 1), - SOC_DAPM_SINGLE("DAC Mixer Playback Switch", RT5625_DAC_MIC_CTRL, - RT5625_M_DAC_MM_SFT, 1, 1), - SOC_DAPM_SINGLE("Voice DAC Playback Switch", RT5625_VDAC_OUT_VOL, - RT5625_M_VDAC_MM_SFT, 1, 1), -}; - -/* Speaker Mixer */ -static const struct snd_kcontrol_new rt5625_spk_mixer[] = { - SOC_DAPM_SINGLE("Line Mixer Playback Switch", RT5625_LINE_IN_VOL, - RT5625_M_LI_SM_SFT, 1, 1), - SOC_DAPM_SINGLE("Phone Playback Switch", RT5625_PHONEIN_VOL, - RT5625_M_PHO_SM_SFT, 1, 1), - SOC_DAPM_SINGLE("Mic1 Playback Switch", RT5625_DAC_MIC_CTRL, - RT5625_M_MIC1_SM_SFT, 1, 1), - SOC_DAPM_SINGLE("Mic2 Playback Switch", RT5625_DAC_MIC_CTRL, - RT5625_M_MIC2_SM_SFT, 1, 1), - SOC_DAPM_SINGLE("DAC Mixer Playback Switch", RT5625_DAC_MIC_CTRL, - RT5625_M_DAC_SM_SFT, 1, 1), - SOC_DAPM_SINGLE("Voice DAC Playback Switch", RT5625_VDAC_OUT_VOL, - RT5625_M_VDAC_SM_SFT, 1, 1), -}; - -static int rt5625_dac_func_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event) -{ - struct snd_soc_codec *codec = w->codec; - - switch (event) { - case SND_SOC_DAPM_PRE_REG: - snd_soc_update_bits(codec, RT5625_PD_CTRL, - RT5625_PWR_PR1, RT5625_PWR_PR1); - break; - - case SND_SOC_DAPM_POST_REG: - snd_soc_update_bits(codec, RT5625_PD_CTRL, - RT5625_PWR_PR1, 0); - break; - - default: - return 0; - } - - return 0; -} - -static int rt5625_hpmix_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = w->codec; - - switch (event) { - case SND_SOC_DAPM_PRE_PMD: - snd_soc_update_bits(codec, RT5625_PWR_ADD2, - RT5625_P_HM_L | RT5625_P_HM_R, 0); - break; - - case SND_SOC_DAPM_POST_PMU: - snd_soc_update_bits(codec, RT5625_PWR_ADD2, - RT5625_P_HM_L | RT5625_P_HM_R, - RT5625_P_HM_L | RT5625_P_HM_R); - break; - - default: - return 0; - } - - return 0; -} - -static int rt5625_vodsp_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event) -{ - struct snd_soc_codec *codec = w->codec; - struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec); - - switch (event) { - case SND_SOC_DAPM_POST_PMD: - //pr_info("%s(): PMD\n", __func__); - snd_soc_update_bits(codec, RT5625_VODSP_CTL, - RT5625_DSP_PD_MASK, RT5625_DSP_PD_EN); - snd_soc_update_bits(codec, RT5625_PWR_ADD3, - RT5625_P_DSP_IF | RT5625_P_DSP_I2C, 0); - snd_soc_update_bits(codec, RT5625_LDO_CTRL, - RT5625_LDO_MASK, RT5625_LDO_DIS); - break; - - case SND_SOC_DAPM_POST_PMU: - //pr_info("%s(): PMU\n", __func__); - if(rt5625->vodsp_fun == RT5625_AEC_EN) - rt5625_init_vodsp_aec(codec); - //pr_info("[DSP poweron] 0x%04x: 0x%04x\n", 0x230C, rt5625_dsp_read(codec, 0x230C)); - break; - - default: - return 0; - } - - return 0; -} - - -static void hp_depop_mode2(struct snd_soc_codec *codec) -{ - snd_soc_update_bits(codec, RT5625_PWR_ADD1, - RT5625_P_SG_EN, RT5625_P_SG_EN); - snd_soc_update_bits(codec, RT5625_PWR_ADD3, - RT5625_P_HPL_VOL | RT5625_P_HPR_VOL, - RT5625_P_HPL_VOL | RT5625_P_HPR_VOL); - snd_soc_write(codec, RT5625_MISC_CTRL, RT5625_HP_DEPOP_M2); - schedule_timeout_uninterruptible(msecs_to_jiffies(500)); - snd_soc_update_bits(codec, RT5625_PWR_ADD1, - RT5625_P_HPO_AMP | RT5625_P_HPO_ENH, - RT5625_P_HPO_AMP | RT5625_P_HPO_ENH); -} - -/* enable depop function for mute/unmute */ -static void hp_mute_unmute_depop(struct snd_soc_codec *codec,int mute) -{ - if(mute) { - snd_soc_update_bits(codec, RT5625_PWR_ADD1, - RT5625_P_SG_EN, RT5625_P_SG_EN); - snd_soc_write(codec, RT5625_MISC_CTRL, RT5625_MUM_DEPOP | - RT5625_HPR_MUM_DEPOP | RT5625_HPL_MUM_DEPOP); - snd_soc_update_bits(codec, RT5625_HP_OUT_VOL, - RT5625_L_MUTE | RT5625_R_MUTE, - RT5625_L_MUTE | RT5625_R_MUTE); - mdelay(50); - snd_soc_update_bits(codec, RT5625_PWR_ADD1, RT5625_P_SG_EN, 0); - } else { - snd_soc_update_bits(codec, RT5625_PWR_ADD1, - RT5625_P_SG_EN, RT5625_P_SG_EN); - snd_soc_write(codec, RT5625_MISC_CTRL, RT5625_MUM_DEPOP | - RT5625_HPR_MUM_DEPOP | RT5625_HPL_MUM_DEPOP); - snd_soc_update_bits(codec,RT5625_HP_OUT_VOL, - RT5625_L_MUTE | RT5625_R_MUTE, 0); - mdelay(50); - } -} - -static int rt5625_hp_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event) -{ - struct snd_soc_codec *codec = w->codec; - - switch (event) { - case SND_SOC_DAPM_PRE_PMD: - hp_mute_unmute_depop(codec,1); - snd_soc_update_bits(codec, RT5625_PWR_ADD1, - RT5625_P_HPO_AMP | RT5625_P_HPO_ENH, 0); - snd_soc_update_bits(codec, RT5625_PWR_ADD3, - RT5625_P_HPL_VOL | RT5625_P_HPR_VOL, 0); - break; - - case SND_SOC_DAPM_POST_PMU: - hp_depop_mode2(codec); - hp_mute_unmute_depop(codec,0); - break; - - default: - return 0; - } - - return 0; -} - -/* DAC function select MUX */ -static const char *dac_fun_sel[] = { - "Stereo DAC", "SRC2 Out", "TxDP", "TxDC"}; - -static const struct soc_enum dac_fun_sel_enum = - SOC_ENUM_SINGLE(RT5625_F_DAC_ADC_VDAC, RT5625_DAC_F_SFT, - ARRAY_SIZE(dac_fun_sel), dac_fun_sel); - -static const struct snd_kcontrol_new dac_fun_sel_mux = - SOC_DAPM_ENUM("DAC Function Select Mux", dac_fun_sel_enum); - -/* Voice DAC source select MUX */ -static const char *vdac_src_sel[] = { - "Voice PCM", "SRC2 Out", "TxDP", "TxDC"}; - -static const struct soc_enum vdac_src_sel_enum = - SOC_ENUM_SINGLE(RT5625_F_DAC_ADC_VDAC, RT5625_VDAC_S_SFT, - ARRAY_SIZE(vdac_src_sel), vdac_src_sel); - -static const struct snd_kcontrol_new vdac_src_sel_mux = - SOC_DAPM_ENUM("Voice DAC Source Mux", vdac_src_sel_enum); - -/* SRC1 power switch */ -static const struct snd_kcontrol_new src1_pwr_sw_control = - SOC_DAPM_SINGLE("Switch", RT5625_VODSP_PDM_CTL, - RT5625_SRC1_PWR_SFT, 1, 0); - -/* SRC2 power switch */ -static const struct snd_kcontrol_new src2_pwr_sw_control = - SOC_DAPM_SINGLE("Switch", RT5625_VODSP_PDM_CTL, - RT5625_SRC2_PWR_SFT, 1, 0); - -/* SRC2 source select MUX */ -static const char *src2_src_sel[] = {"TxDP", "TxDC"}; - -static const struct soc_enum src2_src_sel_enum = - SOC_ENUM_SINGLE(RT5625_VODSP_PDM_CTL, RT5625_SRC2_S_SFT, - ARRAY_SIZE(src2_src_sel), src2_src_sel); - -static const struct snd_kcontrol_new src2_src_sel_mux = - SOC_DAPM_ENUM("SRC2 Source Mux", src2_src_sel_enum); - -/* VoDSP RxDP power switch */ -static const struct snd_kcontrol_new rxdp_pwr_sw_control = - SOC_DAPM_SINGLE("Switch", RT5625_VODSP_PDM_CTL, - RT5625_RXDP_PWR_SFT, 1, 0); -/* VoDSP RxDC power switch */ -static const struct snd_kcontrol_new rxdc_pwr_sw_control = - SOC_DAPM_SINGLE("Switch", RT5625_VODSP_PDM_CTL, - RT5625_RXDC_PWR_SFT, 1, 0); - -/* VoDSP RxDP source select MUX */ -static const char *rxdp_src_sel[] = {"SRC1 Output", "ADCL to VoDSP", - "Voice to Stereo", "ADCR to VoDSP"}; - -static const struct soc_enum rxdp_src_sel_enum = - SOC_ENUM_SINGLE(RT5625_VODSP_PDM_CTL, RT5625_RXDP_S_SFT, - ARRAY_SIZE(rxdp_src_sel), rxdp_src_sel); - -static const struct snd_kcontrol_new rxdp_src_sel_mux = - SOC_DAPM_ENUM("RxDP Source Mux", rxdp_src_sel_enum); - -/* PCM source select MUX */ -static const char *pcm_src_sel[] = {"ADCR", "TxDP"}; - -static const struct soc_enum pcm_src_sel_enum = - SOC_ENUM_SINGLE(RT5625_VODSP_PDM_CTL, RT5625_PCM_S_SFT, - ARRAY_SIZE(pcm_src_sel), pcm_src_sel); - -static const struct snd_kcontrol_new pcm_src_sel_mux = - SOC_DAPM_ENUM("PCM Source Mux", pcm_src_sel_enum); - -/* Main stereo record I2S source select MUX */ -static const char *rec_iis_src_sel[] = {"ADC", "Voice to Stereo", "SRC2 Output"}; - -static const struct soc_enum rec_iis_src_enum = - SOC_ENUM_SINGLE(RT5625_VODSP_PDM_CTL, RT5625_REC_IIS_S_SFT, - ARRAY_SIZE(rec_iis_src_sel), rec_iis_src_sel); - -static const struct snd_kcontrol_new rec_iis_src_mux = - SOC_DAPM_ENUM("REC I2S Source Mux", rec_iis_src_enum); - -/* SPK volume input select MUX */ -static const char *spkvol_input_sel[] = {"VMID", "HP Mixer", "SPK Mixer", "Mono Mixer"}; - -static const struct soc_enum spkvol_input_enum = - SOC_ENUM_SINGLE(RT5625_OUTMIX_CTRL, RT5625_SPKVOL_S_SFT, - ARRAY_SIZE(spkvol_input_sel), spkvol_input_sel); - -static const struct snd_kcontrol_new spkvol_input_mux = - SOC_DAPM_ENUM("SPK Vol Input Mux", spkvol_input_enum); - -/* HP volume input select MUX */ -static const char *hpvol_input_sel[] = {"VMID", "HP Mixer"}; - -static const struct soc_enum hplvol_input_enum = - SOC_ENUM_SINGLE(RT5625_OUTMIX_CTRL, RT5625_HPVOL_L_S_SFT, - ARRAY_SIZE(hpvol_input_sel), hpvol_input_sel); - -static const struct snd_kcontrol_new hplvol_input_mux = - SOC_DAPM_ENUM("HPL Vol Input Mux", hplvol_input_enum); - -static const struct soc_enum hprvol_input_enum = - SOC_ENUM_SINGLE(RT5625_OUTMIX_CTRL, RT5625_HPVOL_R_S_SFT, - ARRAY_SIZE(hpvol_input_sel), hpvol_input_sel); - -static const struct snd_kcontrol_new hprvol_input_mux = - SOC_DAPM_ENUM("HPR Vol Input Mux", hprvol_input_enum); - -/* AUX volume input select MUX */ -static const struct soc_enum auxvol_input_enum = - SOC_ENUM_SINGLE(RT5625_OUTMIX_CTRL, RT5625_AUXVOL_S_SFT, - ARRAY_SIZE(spkvol_input_sel), spkvol_input_sel); - -static const struct snd_kcontrol_new auxvol_input_mux = - SOC_DAPM_ENUM("AUX Vol Input Mux", auxvol_input_enum); - -static const struct snd_soc_dapm_widget rt5625_dapm_widgets[] = { - /* supply */ - SND_SOC_DAPM_SUPPLY("IIS Interface", RT5625_PWR_ADD1, - RT5625_P_I2S_BIT, 0, NULL, 0), - SND_SOC_DAPM_SUPPLY("PLL1", RT5625_PWR_ADD2, - RT5625_P_PLL1_BIT, 0, NULL, 0), - SND_SOC_DAPM_SUPPLY("PLL2", RT5625_PWR_ADD2, - RT5625_P_PLL2_BIT, 0, NULL, 0), - SND_SOC_DAPM_VMID("VMID"), - SND_SOC_DAPM_SUPPLY("DAC Ref", RT5625_PWR_ADD1, - RT5625_P_DAC_REF_BIT, 0, NULL, 0), - /* microphone bias */ - SND_SOC_DAPM_MICBIAS("Mic1 Bias", RT5625_PWR_ADD1, - RT5625_P_MB1_BIT, 0), - SND_SOC_DAPM_MICBIAS("Mic2 Bias", RT5625_PWR_ADD1, - RT5625_P_MB2_BIT, 0), - - /* Input */ - SND_SOC_DAPM_INPUT("Left LineIn"), - SND_SOC_DAPM_INPUT("Right LineIn"), - SND_SOC_DAPM_INPUT("Phone"), - SND_SOC_DAPM_INPUT("Mic1"), - SND_SOC_DAPM_INPUT("Mic2"), - - SND_SOC_DAPM_PGA("Mic1 Boost", RT5625_PWR_ADD3, - RT5625_P_MIC1_BST_BIT, 0, NULL, 0), - SND_SOC_DAPM_PGA("Mic2 Boost", RT5625_PWR_ADD3, - RT5625_P_MIC2_BST_BIT, 0, NULL, 0), - SND_SOC_DAPM_PGA("Phone Rec Mixer", RT5625_PWR_ADD3, - RT5625_P_PH_ADMIX_BIT, 0, NULL, 0), - - SND_SOC_DAPM_MIXER("Left Rec Mixer", RT5625_PWR_ADD2, - RT5625_P_ADCL_RM_BIT, 0, rt5625_adcl_rec_mixer, - ARRAY_SIZE(rt5625_adcl_rec_mixer)), - SND_SOC_DAPM_MIXER("Right Rec Mixer", RT5625_PWR_ADD2, - RT5625_P_ADCR_RM_BIT, 0, rt5625_adcr_rec_mixer, - ARRAY_SIZE(rt5625_adcr_rec_mixer)), - - SND_SOC_DAPM_ADC("Left ADC", NULL, RT5625_PWR_ADD2, - RT5625_P_ADCL_BIT, 0), - SND_SOC_DAPM_ADC("Right ADC", NULL, RT5625_PWR_ADD2, - RT5625_P_ADCR_BIT, 0), - SND_SOC_DAPM_PGA("ADC", SND_SOC_NOPM, 0, 0, NULL, 0),//johnny-3-9 - SND_SOC_DAPM_MUX("PCM src select Mux", SND_SOC_NOPM, 0, 0, - &pcm_src_sel_mux), - SND_SOC_DAPM_MUX("IIS src select Mux", SND_SOC_NOPM, 0, 0, - &rec_iis_src_mux), - - /* Input Stream Audio Interface */ - SND_SOC_DAPM_AIF_OUT("AIF1TX", "AIF1 HiFi Capture", 0, SND_SOC_NOPM, 0, 0), - SND_SOC_DAPM_AIF_OUT("AIF2TX", "AIF2 Voice Capture", 0, SND_SOC_NOPM, 0, 0), - - /* Voice DSP */ - SND_SOC_DAPM_MUX("SRC2 src select Mux", SND_SOC_NOPM, 0, 0, - &src2_src_sel_mux), - SND_SOC_DAPM_SWITCH("SRC1 Enable", SND_SOC_NOPM, 0, 0, - &src1_pwr_sw_control), - SND_SOC_DAPM_SWITCH("SRC2 Enable", SND_SOC_NOPM, 0, 0, - &src2_pwr_sw_control), - SND_SOC_DAPM_SWITCH("RxDP Enable", SND_SOC_NOPM, 0, 0, - &rxdp_pwr_sw_control), - SND_SOC_DAPM_SWITCH("RxDC Enable", SND_SOC_NOPM, 0, 0, - &rxdc_pwr_sw_control), - - SND_SOC_DAPM_MUX("RxDP src select Mux", SND_SOC_NOPM, 0, 0, - &rxdp_src_sel_mux), - - SND_SOC_DAPM_PGA("TxDP", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_PGA("TxDC", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_PGA("PDM", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_PGA("RxDP", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_PGA("RxDC", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_PGA_E("Voice DSP", SND_SOC_NOPM, - 0, 0, NULL, 0, rt5625_vodsp_event, - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), - - /* Output */ - /* Output Stream Audio Interface */ - SND_SOC_DAPM_AIF_IN("AIF1RX", "AIF1 HiFi Playback", - 0, SND_SOC_NOPM, 0, 0), - SND_SOC_DAPM_AIF_IN("AIF2RX", "AIF2 Voice Playback", - 0, SND_SOC_NOPM, 0, 0), - - /* DAC function select Mux */ - SND_SOC_DAPM_MUX_E("DAC fun Mux", SND_SOC_NOPM, 0, 0, - &dac_fun_sel_mux, rt5625_dac_func_event, - SND_SOC_DAPM_PRE_REG | SND_SOC_DAPM_POST_REG), - /* VDAC source select Mux */ - SND_SOC_DAPM_MUX_E("VDAC src Mux", SND_SOC_NOPM, 0, 0, - &vdac_src_sel_mux, rt5625_dac_func_event, - SND_SOC_DAPM_PRE_REG | SND_SOC_DAPM_POST_REG), - - SND_SOC_DAPM_DAC("Left DAC", NULL, RT5625_PWR_ADD2, - RT5625_P_DACL_BIT, 0), - SND_SOC_DAPM_DAC("Right DAC", NULL, RT5625_PWR_ADD2, - RT5625_P_DACR_BIT, 0), - SND_SOC_DAPM_DAC("Voice DAC", NULL, RT5625_PWR_ADD2, - RT5625_P_VDAC_BIT, 0), - - SND_SOC_DAPM_PGA("Mic1 Volume", RT5625_PWR_ADD3, - RT5625_P_MIC1_VOL_BIT, 0, NULL, 0), - SND_SOC_DAPM_PGA("Mic2 Volume", RT5625_PWR_ADD3, - RT5625_P_MIC2_VOL_BIT, 0, NULL, 0), - SND_SOC_DAPM_PGA("Left LineIn Volume", RT5625_PWR_ADD3, - RT5625_P_LV_L_BIT, 0, NULL, 0), - SND_SOC_DAPM_PGA("Right LineIn Volume", RT5625_PWR_ADD3, - RT5625_P_LV_R_BIT, 0, NULL, 0), - SND_SOC_DAPM_PGA("Phone Volume", RT5625_PWR_ADD3, - RT5625_P_PH_VOL_BIT, 0, NULL, 0), - - SND_SOC_DAPM_PGA("Left DAC To Mixer", RT5625_PWR_ADD1, - RT5625_P_DACL_MIX_BIT, 0, NULL, 0), - SND_SOC_DAPM_PGA("Right DAC To Mixer", RT5625_PWR_ADD1, - RT5625_P_DACR_MIX_BIT, 0, NULL, 0), - SND_SOC_DAPM_PGA("Voice DAC To Mixer", RT5625_PWR_ADD1, - RT5625_P_VDAC_MIX_BIT, 0, NULL, 0), - - SND_SOC_DAPM_MIXER("SPK Mixer", RT5625_PWR_ADD2, - RT5625_P_SM_BIT, 0, rt5625_spk_mixer, - ARRAY_SIZE(rt5625_spk_mixer)), - SND_SOC_DAPM_MIXER("Mono HP Mixer", SND_SOC_NOPM, 0, 0, - rt5625_hp_mixer, ARRAY_SIZE(rt5625_hp_mixer)), - SND_SOC_DAPM_MIXER("Left HP Mixer", SND_SOC_NOPM, 0, 0, - rt5625_hpl_mixer, ARRAY_SIZE(rt5625_hpl_mixer)), - SND_SOC_DAPM_MIXER("Right HP Mixer", SND_SOC_NOPM, 0, 0, - rt5625_hpr_mixer, ARRAY_SIZE(rt5625_hpr_mixer)), - SND_SOC_DAPM_MIXER("Mono Mixer", RT5625_PWR_ADD2, - RT5625_P_MM_BIT, 0, rt5625_mono_mixer, - ARRAY_SIZE(rt5625_mono_mixer)), - - SND_SOC_DAPM_MIXER_E("HP Mixer", SND_SOC_NOPM, 0, 0, NULL, 0, - rt5625_hpmix_event, SND_SOC_DAPM_PRE_PMD | - SND_SOC_DAPM_POST_PMU), - - SND_SOC_DAPM_MIXER("DAC Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_MIXER("Line Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), - - SND_SOC_DAPM_MUX("SPK Vol Input Mux", SND_SOC_NOPM, - 0, 0, &spkvol_input_mux), - SND_SOC_DAPM_SUPPLY("SPKL Vol", RT5625_PWR_ADD3, - RT5625_P_SPKL_VOL_BIT, 0, NULL, 0), - SND_SOC_DAPM_SUPPLY("SPKR Vol", RT5625_PWR_ADD3, - RT5625_P_SPKR_VOL_BIT, 0, NULL, 0), - SND_SOC_DAPM_MUX("HPL Vol Input Mux", RT5625_PWR_ADD3, - RT5625_P_HPL_VOL_BIT, 0, &hplvol_input_mux), - SND_SOC_DAPM_MUX("HPR Vol Input Mux", RT5625_PWR_ADD3, - RT5625_P_HPR_VOL_BIT, 0, &hprvol_input_mux), - SND_SOC_DAPM_MUX("AUX Vol Input Mux", RT5625_PWR_ADD3, - RT5625_P_AUX_VOL_BIT, 0, &auxvol_input_mux), - - SND_SOC_DAPM_SUPPLY("SPK Amp", RT5625_PWR_ADD1, - RT5625_P_SPK_AMP_BIT, 0, NULL, 0), - SND_SOC_DAPM_PGA_E("HP Amp", SND_SOC_NOPM, 0, 0, NULL, 0, - rt5625_hp_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), - - SND_SOC_DAPM_OUTPUT("SPKL"), - SND_SOC_DAPM_OUTPUT("SPKR"), - SND_SOC_DAPM_OUTPUT("HPL"), - SND_SOC_DAPM_OUTPUT("HPR"), - SND_SOC_DAPM_OUTPUT("AUX"), -}; - -static const struct snd_soc_dapm_route rt5625_dapm_routes[] = { - {"DAC Ref", NULL, "IIS Interface"}, - {"DAC Ref", NULL, "PLL1"}, - {"DAC Ref", NULL, "PLL2"}, - - /* Input */ - {"Phone Rec Mixer", NULL, "Phone"}, - {"Mic1 Boost", NULL, "Mic1"}, - {"Mic2 Boost", NULL, "Mic2"}, - - {"Left Rec Mixer", "LineIn Capture Switch", "Left LineIn"}, - {"Left Rec Mixer", "Phone Capture Switch", "Phone Rec Mixer"}, - {"Left Rec Mixer", "Mic1 Capture Switch", "Mic1 Boost"}, - {"Left Rec Mixer", "Mic2 Capture Switch", "Mic2 Boost"}, - {"Left Rec Mixer", "HP Mixer Capture Switch", "Left HP Mixer"}, - {"Left Rec Mixer", "SPK Mixer Capture Switch", "SPK Mixer"}, - {"Left Rec Mixer", "MoNo Mixer Capture Switch", "Mono Mixer"}, - - {"Right Rec Mixer", "LineIn Capture Switch", "Right LineIn"}, - {"Right Rec Mixer", "Phone Capture Switch", "Phone Rec Mixer"}, - {"Right Rec Mixer", "Mic1 Capture Switch", "Mic1 Boost"}, - {"Right Rec Mixer", "Mic2 Capture Switch", "Mic2 Boost"}, - {"Right Rec Mixer", "HP Mixer Capture Switch", "Right HP Mixer"}, - {"Right Rec Mixer", "SPK Mixer Capture Switch", "SPK Mixer"}, - {"Right Rec Mixer", "MoNo Mixer Capture Switch", "Mono Mixer"}, - - {"Left ADC", NULL, "DAC Ref"}, - {"Left ADC", NULL, "Left Rec Mixer"}, - {"Right ADC", NULL, "DAC Ref"}, - {"Right ADC", NULL, "Right Rec Mixer"}, - - {"PCM src select Mux", "TxDP", "TxDP"}, - {"PCM src select Mux", "ADCR", "Right ADC"}, - - //johnny-3-9 [s] - {"ADC", NULL, "Left ADC"}, - {"ADC", NULL, "Right ADC"}, - {"IIS src select Mux", "ADC", "ADC"}, - //{"IIS src select Mux", "ADC", "Left ADC"}, - //{"IIS src select Mux", "ADC", "Right ADC"}, - //johnny-3-9 [e] - {"IIS src select Mux", "Voice to Stereo", "AIF2RX"}, - {"IIS src select Mux", "SRC2 Output", "SRC2 Enable"}, - - {"AIF2TX", NULL, "IIS Interface"}, - {"AIF2TX", NULL, "PCM src select Mux"}, - {"AIF1TX", NULL, "IIS Interface"}, - {"AIF1TX", NULL, "IIS src select Mux"}, - - /* Output */ - {"AIF1RX", NULL, "IIS Interface"}, - {"AIF2RX", NULL, "IIS Interface"}, - - {"DAC fun Mux", "SRC2 Out", "SRC2 Enable"}, - {"DAC fun Mux", "TxDP", "TxDP"}, - {"DAC fun Mux", "TxDC", "TxDC"}, - {"DAC fun Mux", "Stereo DAC", "AIF1RX"}, - - {"VDAC src Mux", "SRC2 Out", "SRC2 Enable"}, - {"VDAC src Mux", "TxDP", "TxDP"}, - {"VDAC src Mux", "TxDC", "TxDC"}, - {"VDAC src Mux", "Voice PCM", "AIF2RX"}, - - {"Left DAC", NULL, "DAC Ref"}, - {"Left DAC", NULL, "DAC fun Mux"}, - {"Right DAC", NULL, "DAC Ref"}, - {"Right DAC", NULL, "DAC fun Mux"}, - {"Voice DAC", NULL, "DAC Ref"}, - {"Voice DAC", NULL, "VDAC src Mux"}, - - {"Left LineIn Volume", NULL, "Left LineIn"}, - {"Right LineIn Volume", NULL, "Right LineIn"}, - {"Phone Volume", NULL, "Phone"}, - {"Mic1 Volume", NULL, "Mic1 Boost"}, - {"Mic2 Volume", NULL, "Mic2 Boost"}, - - {"Left DAC To Mixer", NULL, "Left DAC"}, - {"Right DAC To Mixer", NULL, "Right DAC"}, - {"Voice DAC To Mixer", NULL, "Voice DAC"}, - - {"DAC Mixer", NULL, "Left DAC To Mixer"}, - {"DAC Mixer", NULL, "Right DAC To Mixer"}, - {"Line Mixer", NULL, "Left LineIn Volume"}, - {"Line Mixer", NULL, "Right LineIn Volume"}, - - {"Mono HP Mixer", "LineIn Playback Switch", "Line Mixer"}, - {"Mono HP Mixer", "Phone Playback Switch", "Phone Volume"}, - {"Mono HP Mixer", "Mic1 Playback Switch", "Mic1 Volume"}, - {"Mono HP Mixer", "Mic2 Playback Switch", "Mic2 Volume"}, - {"Mono HP Mixer", "Voice DAC Playback Switch", "Voice DAC To Mixer"}, - {"Left HP Mixer", "ADC Playback Switch", "Left Rec Mixer"}, - {"Left HP Mixer", "DAC Playback Switch", "Left DAC To Mixer"}, - {"Right HP Mixer", "ADC Playback Switch", "Right Rec Mixer"}, - {"Right HP Mixer", "DAC Playback Switch", "Right DAC To Mixer"}, - - {"SPK Mixer", "Line Mixer Playback Switch", "Line Mixer"}, - {"SPK Mixer", "Phone Playback Switch", "Phone Volume"}, - {"SPK Mixer", "Mic1 Playback Switch", "Mic1 Volume"}, - {"SPK Mixer", "Mic2 Playback Switch", "Mic2 Volume"}, - {"SPK Mixer", "DAC Mixer Playback Switch", "DAC Mixer"}, - {"SPK Mixer", "Voice DAC Playback Switch", "Voice DAC To Mixer"}, - - {"Mono Mixer", "Line Mixer Playback Switch", "Line Mixer"}, - {"Mono Mixer", "ADCL Playback Switch","Left Rec Mixer"}, - {"Mono Mixer", "ADCR Playback Switch","Right Rec Mixer"}, - {"Mono Mixer", "Mic1 Playback Switch", "Mic1 Volume"}, - {"Mono Mixer", "Mic2 Playback Switch", "Mic2 Volume"}, - {"Mono Mixer", "DAC Mixer Playback Switch", "DAC Mixer"}, - {"Mono Mixer", "Voice DAC Playback Switch", "Voice DAC To Mixer"}, - - {"HP Mixer", NULL, "Mono HP Mixer"}, - {"HP Mixer", NULL, "Left HP Mixer"}, - {"HP Mixer", NULL, "Right HP Mixer"}, - - {"SPK Vol Input Mux", "VMID", "VMID"}, - {"SPK Vol Input Mux", "HP Mixer", "HP Mixer"}, - {"SPK Vol Input Mux", "SPK Mixer", "SPK Mixer"}, - {"SPK Vol Input Mux", "Mono Mixer", "Mono Mixer"}, - {"SPK Vol Input Mux", NULL, "SPKL Vol"}, - {"SPK Vol Input Mux", NULL, "SPKR Vol"}, - - {"HPL Vol Input Mux", "HP Mixer", "HP Mixer"}, - {"HPL Vol Input Mux", "VMID", "VMID"}, - {"HP Amp", NULL, "HPL Vol Input Mux"}, - {"HPR Vol Input Mux", "HP Mixer", "HP Mixer"}, - {"HPR Vol Input Mux", "VMID", "VMID"}, - {"HP Amp", NULL, "HPR Vol Input Mux"}, - - {"AUX Vol Input Mux", "VMID", "VMID"}, - {"AUX Vol Input Mux", "HP Mixer", "HP Mixer"}, - {"AUX Vol Input Mux", "SPK Mixer", "SPK Mixer"}, - {"AUX Vol Input Mux", "Mono Mixer", "Mono Mixer"}, - - {"SPKL", NULL, "SPK Amp"}, - {"SPKL", NULL, "SPK Vol Input Mux"}, - {"SPKR", NULL, "SPK Amp"}, - {"SPKR", NULL, "SPK Vol Input Mux"}, - {"HPL", NULL, "HP Amp"}, - {"HPR", NULL, "HP Amp"}, - {"AUX", NULL, "AUX Vol Input Mux"}, - - /* Voice DSP */ - {"SRC1 Enable", "Switch", "AIF1RX"}, - - {"RxDP src select Mux", "Voice to Stereo", "AIF2RX"}, - {"RxDP src select Mux", "ADCL to VoDSP", "Left ADC"}, - {"RxDP src select Mux", "SRC1 Output", "SRC1 Enable"}, - {"RxDP src select Mux", "ADCR to VoDSP", "Right ADC"}, - - {"RxDP Enable", "Switch", "RxDP src select Mux"}, - {"RxDC Enable", "Switch", "Left ADC"}, - - {"RxDP", NULL, "RxDP Enable"}, - {"RxDC", NULL, "RxDC Enable"}, - {"PDM", NULL, "Right ADC"}, - - {"Voice DSP", NULL, "RxDP"}, - {"Voice DSP", NULL, "RxDC"}, - {"Voice DSP", NULL, "PDM"}, - - {"TxDP", NULL, "Voice DSP"}, - {"TxDC", NULL, "Voice DSP"}, - - {"SRC2 src select Mux", "TxDP", "TxDP"}, - {"SRC2 src select Mux", "TxDC", "TxDC"}, - {"SRC2 Enable", "Switch", "SRC2 src select Mux"}, -}; - -struct _pll_div{ - u32 pll_in; - u32 pll_out; - u16 regvalue; -}; - -/************************************************************** - * watch out! - * our codec support you to select different source as pll input, but if you - * use both of the I2S audio interface and pcm interface instantially. - * The two DAI must have the same pll setting params, so you have to offer - * the same pll input, and set our codec's sysclk the same one, we suggest - * 24576000. - **************************************************************/ -static const struct _pll_div codec_master_pll1_div[] = { - { 2048000, 8192000, 0x0ea0}, - { 3686400, 8192000, 0x4e27}, - { 12000000, 8192000, 0x456b}, - { 13000000, 8192000, 0x495f}, - { 13100000, 8192000, 0x0320}, - { 2048000, 11289600, 0xf637}, - { 3686400, 11289600, 0x2f22}, - { 12000000, 11289600, 0x3e2f}, - { 13000000, 11289600, 0x4d5b}, - { 13100000, 11289600, 0x363b}, - { 2048000, 16384000, 0x1ea0}, - { 3686400, 16384000, 0x9e27}, - { 12000000, 16384000, 0x452b}, - { 13000000, 16384000, 0x542f}, - { 13100000, 16384000, 0x03a0}, - { 2048000, 16934400, 0xe625}, - { 3686400, 16934400, 0x9126}, - { 12000000, 16934400, 0x4d2c}, - { 13000000, 16934400, 0x742f}, - { 13100000, 16934400, 0x3c27}, - { 2048000, 22579200, 0x2aa0}, - { 3686400, 22579200, 0x2f20}, - { 12000000, 22579200, 0x7e2f}, - { 13000000, 22579200, 0x742f}, - { 13100000, 22579200, 0x3c27}, - { 2048000, 24576000, 0x2ea0}, - { 3686400, 24576000, 0xee27}, - { 11289600, 24576000, 0x950F}, - { 12000000, 24576000, 0x2915}, - { 12288000, 24576000, 0x0600}, - { 13000000, 24576000, 0x772e}, - { 13100000, 24576000, 0x0d20}, - { 26000000, 24576000, 0x2027}, - { 26000000, 22579200, 0x392f}, - { 24576000, 22579200, 0x0921}, - { 24576000, 24576000, 0x02a0}, -}; - -static const struct _pll_div codec_bclk_pll1_div[] = { - { 256000, 4096000, 0x3ea0}, - { 352800, 5644800, 0x3ea0}, - { 512000, 8192000, 0x3ea0}, - { 705600, 11289600, 0x3ea0}, - { 1024000, 16384000, 0x3ea0}, - { 1411200, 22579200, 0x3ea0}, - { 1536000, 24576000, 0x3ea0}, - { 2048000, 16384000, 0x1ea0}, - { 2822400, 22579200, 0x1ea0}, - { 3072000, 24576000, 0x1ea0}, - { 705600, 11289600, 0x3ea0}, - { 705600, 8467200, 0x3ab0}, - { 2822400, 11289600, 0x1ee0}, - { 3072000, 12288000, 0x1ee0}, -}; - -static const struct _pll_div codec_vbclk_pll1_div[] = { - { 256000, 4096000, 0x3ea0}, - { 352800, 5644800, 0x3ea0}, - { 512000, 8192000, 0x3ea0}, - { 705600, 11289600, 0x3ea0}, - { 1024000, 16384000, 0x3ea0}, - { 1411200, 22579200, 0x3ea0}, - { 1536000, 24576000, 0x3ea0}, - { 2048000, 16384000, 0x1ea0}, - { 2822400, 22579200, 0x1ea0}, - { 3072000, 24576000, 0x1ea0}, - { 705600, 11289600, 0x3ea0}, - { 705600, 8467200, 0x3ab0}, -}; - -struct _coeff_div_stereo { - unsigned int mclk; - unsigned int rate; - unsigned int reg60; - unsigned int reg62; -}; - -struct _coeff_div_voice { - unsigned int mclk; - unsigned int rate; - unsigned int reg64; -}; - -/* bclk is config to 32fs, if codec is choose to be slave mode, -input bclk should be 32*fs */ -static const struct _coeff_div_stereo coeff_div_stereo[] = { - {24576000, 48000, 0x3174, 0x1010}, - {12288000, 48000, 0x1174, 0x0000}, - {18432000, 48000, 0x2174, 0x1111}, - {36864000, 48000, 0x2274, 0x2020}, - {49152000, 48000, 0xf074, 0x3030}, - {24576000, 48000, 0x3172, 0x1010}, - {24576000, 8000, 0xB274, 0x2424}, - {24576000, 16000, 0xB174, 0x2222}, - {24576000, 32000, 0xB074, 0x2121}, - {22579200, 11025, 0X3374, 0x1414}, - {22579200, 22050, 0X3274, 0x1212}, - {22579200, 44100, 0X3174, 0x1010}, - {12288000, 8000, 0xB174, 0x2222}, - {11289600, 44100, 0X3072, 0x0000}, -}; - -/* bclk is config to 32fs, if codec is choose to be slave mode, -input bclk should be 32*fs */ -static const struct _coeff_div_voice coeff_div_voice[] = { - {24576000, 16000, 0x2622}, - {24576000, 8000, 0x2824}, - {2048000,8000,0x3000}, -}; - -static int get_coeff(unsigned int mclk, unsigned int rate, int mode) -{ - int i; - - pr_info("mclk = %d, rate = %d, mode = %d\n", mclk, rate, mode); - - if (!mode) - for (i = 0; i < ARRAY_SIZE(coeff_div_stereo); i++) { - if ((coeff_div_stereo[i].rate == rate) && - (coeff_div_stereo[i].mclk == mclk)) - return i; - } - else - for (i = 0; i< ARRAY_SIZE(coeff_div_voice); i++) { - if ((coeff_div_voice[i].rate == rate) && - (coeff_div_voice[i].mclk == mclk)) - return i; - } - - pr_err("can't find a matched mclk and rate in %s\n", - (mode ? "coeff_div_voice[]" : "coeff_div_audio[]")); - - return -EINVAL; -} - - -static int rt5625_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source, - unsigned int freq_in, unsigned int freq_out) -{ - struct snd_soc_codec *codec = dai->codec; - int i, ret = -EINVAL; - - if (pll_id < RT5625_PLL_MCLK || pll_id > RT5625_PLL_VBCLK) - return -EINVAL; - - if (!freq_in || !freq_out) { - dev_info(dai->dev, "PLL is closed\n"); - snd_soc_update_bits(codec, RT5625_GEN_CTRL1, - RT5625_SCLK_MASK, RT5625_SCLK_MCLK); - return 0; - } - - if (RT5625_PLL_MCLK == pll_id) { - for (i = 0; i < ARRAY_SIZE(codec_master_pll1_div); i ++) - if ((freq_in == codec_master_pll1_div[i].pll_in) && - (freq_out == codec_master_pll1_div[i].pll_out)) { - snd_soc_write(codec, RT5625_GEN_CTRL2, - RT5625_PLL1_S_MCLK); - snd_soc_write(codec, RT5625_PLL_CTRL, - codec_master_pll1_div[i].regvalue); - snd_soc_update_bits(codec, RT5625_GEN_CTRL1, - RT5625_SCLK_MASK, RT5625_SCLK_PLL1); - ret = 0; - break; - } - } else if (RT5625_PLL_MCLK_TO_VSYSCLK == pll_id) { - for (i = 0; i < ARRAY_SIZE(codec_master_pll1_div); i ++) - { - if ((freq_in == codec_master_pll1_div[i].pll_in) && (freq_out == codec_master_pll1_div[i].pll_out)) - { - snd_soc_write(codec, RT5625_GEN_CTRL2, 0x0000); /*PLL source from MCLK*/ - snd_soc_write(codec, RT5625_PLL_CTRL, codec_master_pll1_div[i].regvalue); /*set pll code*/ - snd_soc_update_bits(codec, RT5625_GEN_CTRL1, 0x0030, 0x0030); /* Voice SYSCLK source from FLL1 */ - ret = 0; - } - } - }else if (RT5625_PLL_BCLK == pll_id) { - for (i = 0; i < ARRAY_SIZE(codec_bclk_pll1_div); i ++) - if ((freq_in == codec_bclk_pll1_div[i].pll_in) && - (freq_out == codec_bclk_pll1_div[i].pll_out)) { - snd_soc_write(codec, RT5625_GEN_CTRL2, - RT5625_PLL1_S_BCLK); - snd_soc_write(codec, RT5625_PLL_CTRL, - codec_bclk_pll1_div[i].regvalue); - snd_soc_update_bits(codec, RT5625_GEN_CTRL1, - RT5625_SCLK_MASK, RT5625_SCLK_PLL1); - ret = 0; - break; - } - } else if (RT5625_PLL_VBCLK == pll_id) { - for (i = 0; i < ARRAY_SIZE(codec_vbclk_pll1_div); i ++) - if ((freq_in == codec_vbclk_pll1_div[i].pll_in) && - (freq_out == codec_vbclk_pll1_div[i].pll_out)) { - snd_soc_write(codec, RT5625_GEN_CTRL2, - RT5625_PLL1_S_VBCLK); - snd_soc_write(codec, RT5625_PLL_CTRL, - codec_vbclk_pll1_div[i].regvalue); - snd_soc_update_bits(codec, RT5625_GEN_CTRL1, - RT5625_SCLK_MASK, RT5625_SCLK_PLL1); - ret = 0; - break; - } - } - - return ret; -} - - -static int rt5625_set_dai_sysclk(struct snd_soc_dai *dai, - int clk_id, unsigned int freq, int dir) -{ - struct snd_soc_codec *codec = dai->codec; - struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec); - unsigned int val = 0; - - switch (dai->id) { - case RT5625_AIF1: - if (freq == rt5625->stereo_sysclk) - return 0; - rt5625->stereo_sysclk = freq; - break; - - case RT5625_AIF2: - if (freq == rt5625->voice_sysclk) - return 0; - rt5625->voice_sysclk = freq; - break; - - default: - return -EINVAL; - } - - switch (clk_id) { - case RT5625_SCLK_S_MCLK: - break; - - case RT5625_SCLK_S_PLL: - val |= RT5625_SCLK_PLL1; - break; - - default: - dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id); - return -EINVAL; - } - snd_soc_update_bits(codec, RT5625_GEN_CTRL1, - RT5625_SCLK_MASK, val); - - dev_dbg(dai->dev, "Sysclk is %dHz and clock id is %d\n", freq, clk_id); - - return 0; -} - -static int rt5625_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec *codec = rtd->codec; - struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec); - unsigned int iface = 0, rate = params_rate(params), coeff; - - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: - break; - - case SNDRV_PCM_FORMAT_S20_3LE: - iface |= RT5625_I2S_DL_20; - break; - - case SNDRV_PCM_FORMAT_S24_LE: - iface |= RT5625_I2S_DL_24; - break; - - case SNDRV_PCM_FORMAT_S8: - iface |= RT5625_I2S_DL_8; - break; - - default: - return -EINVAL; - } - - switch (dai->id) { - case RT5625_AIF1: - coeff = get_coeff(rt5625->stereo_sysclk, rate, 0); - if (coeff < 0) { - dev_err(codec->dev, "Unsupported clock setting\n"); - return -EINVAL; - } - snd_soc_write(codec, RT5625_DAC_CLK_CTRL1, - coeff_div_stereo[coeff].reg60); - snd_soc_write(codec, RT5625_DAC_CLK_CTRL2, - coeff_div_stereo[coeff].reg62); - snd_soc_update_bits(codec, RT5625_SDP_CTRL, - RT5625_I2S_DL_MASK, iface); - break; - - case RT5625_AIF2: - rate = 8000; - coeff = get_coeff(rt5625->voice_sysclk, rate, 1); - if (coeff < 0) { - dev_err(codec->dev, "Unsupported clock setting\n"); - return -EINVAL; - } - snd_soc_write(codec, RT5625_VDAC_CLK_CTRL1, - coeff_div_voice[coeff].reg64); - iface |= 0x0100; //Voice SYSCLK source from FLL1 - snd_soc_update_bits(codec, RT5625_EXT_SDP_CTRL, - RT5625_I2S_DL_MASK, iface); - break; - - default: - return -EINVAL; - } - -#ifdef RT5625_F_SMT_PHO - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - rt5625->app_bmp |= RT5625_PLY_MASK; - else - rt5625->app_bmp |= RT5625_REC_MASK; -#endif - - return 0; -} - -static int rt5625_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) -{ - struct snd_soc_codec *codec = dai->codec; - unsigned int iface = 0; - bool slave; - - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: - slave = false; - break; - - case SND_SOC_DAIFMT_CBS_CFS: - slave = true; - break; - - default: - return -EINVAL; - } - - switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_I2S: - break; - - case SND_SOC_DAIFMT_LEFT_J: - iface |= RT5625_I2S_DF_LEFT; - break; - - case SND_SOC_DAIFMT_DSP_A: - iface |= RT5625_I2S_DF_PCM_A; - break; - - case SND_SOC_DAIFMT_DSP_B: - iface |= RT5625_I2S_DF_PCM_B; - break; - - default: - return -EINVAL; - } - - switch (fmt & SND_SOC_DAIFMT_INV_MASK) { - case SND_SOC_DAIFMT_NB_NF: - break; - - case SND_SOC_DAIFMT_IB_NF: - iface |= RT5625_I2S_BP_INV; - break; - - default: - return -EINVAL; - } - iface |= 0x8000; /*enable vopcm*/ - - switch (dai->id) { - case RT5625_AIF1: - if (slave) - iface |= RT5625_I2S_M_SLV; - snd_soc_update_bits(codec, RT5625_SDP_CTRL, - RT5625_I2S_M_MASK | RT5625_I2S_BP_MASK | - RT5625_I2S_DF_MASK, iface); - break; - - case RT5625_AIF2: - if (slave) - iface |= RT5625_PCM_M_SLV; - snd_soc_update_bits(codec, RT5625_EXT_SDP_CTRL, - RT5625_PCM_M_MASK | RT5625_I2S_BP_MASK | - RT5625_I2S_DF_MASK, iface); - break; - - default: - return -EINVAL; - } - return 0; -} - -#ifdef RT5625_F_SMT_PHO -static int rt5625_trigger(struct snd_pcm_substream *substream, - int cmd, struct snd_soc_dai *dai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec *codec = rtd->codec; - struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec); - int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - if (capture) - rt5625->app_bmp |= RT5625_REC_MASK; - else - rt5625->app_bmp |= RT5625_PLY_MASK; - break; - - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - if (capture) - rt5625->app_bmp &= ~RT5625_REC_MASK; - else - rt5625->app_bmp &= ~RT5625_PLY_MASK; - rt5625->app_bmp &= ~RT5625_VOIP_MASK; - break; - - default: - break; - } - - return 0; -} -#endif - -static int rt5625_set_bias_level(struct snd_soc_codec *codec, - enum snd_soc_bias_level level) -{ - switch(level) { - case SND_SOC_BIAS_ON: -#ifdef RT5625_DEMO - snd_soc_update_bits(codec, RT5625_HP_OUT_VOL, - RT5625_L_MUTE | RT5625_R_MUTE, 0); - snd_soc_update_bits(codec, RT5625_SPK_OUT_VOL, - RT5625_L_MUTE | RT5625_R_MUTE, 0); -#endif - break; - - case SND_SOC_BIAS_PREPARE: - snd_soc_write(codec, RT5625_PD_CTRL, 0x0000); - snd_soc_update_bits(codec, RT5625_PWR_ADD1, - RT5625_P_MB1 | RT5625_P_MB2, - RT5625_P_MB1 | RT5625_P_MB2); - break; - - case SND_SOC_BIAS_STANDBY: -#ifdef RT5625_DEMO - snd_soc_update_bits(codec, RT5625_HP_OUT_VOL, - RT5625_L_MUTE | RT5625_R_MUTE, - RT5625_L_MUTE | RT5625_R_MUTE); - snd_soc_update_bits(codec, RT5625_SPK_OUT_VOL, - RT5625_L_MUTE | RT5625_R_MUTE, - RT5625_L_MUTE | RT5625_R_MUTE); - snd_soc_update_bits(codec, RT5625_PWR_ADD1, - RT5625_P_MB1 | RT5625_P_MB2, 0); -#endif - if (SND_SOC_BIAS_OFF == codec->dapm.bias_level) { - snd_soc_write(codec, RT5625_PD_CTRL, 0); - snd_soc_write(codec, RT5625_PWR_ADD1, - RT5625_P_MAIN_BIAS); - snd_soc_write(codec, RT5625_PWR_ADD2, RT5625_P_VREF); - codec->cache_only = false; - snd_soc_cache_sync(codec); - } - break; - - case SND_SOC_BIAS_OFF: -#ifdef RT5625_DEMO - snd_soc_update_bits(codec, RT5625_HP_OUT_VOL, - RT5625_L_MUTE | RT5625_R_MUTE, - RT5625_L_MUTE | RT5625_R_MUTE); - snd_soc_update_bits(codec, RT5625_SPK_OUT_VOL, - RT5625_L_MUTE | RT5625_R_MUTE, - RT5625_L_MUTE | RT5625_R_MUTE); -#endif - snd_soc_write(codec, RT5625_PWR_ADD1, 0x0000); - snd_soc_write(codec, RT5625_PWR_ADD2, 0x0000); - snd_soc_write(codec, RT5625_PWR_ADD3, 0x0000); - - break; - } - codec->dapm.bias_level = level; - - return 0; -} - -#ifdef RT5625_PROC -static int rt5625_proc_init(void); -#endif - -static int rt5625_probe(struct snd_soc_codec *codec) -{ - int ret; - - ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); - if (ret != 0) { - dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); - return ret; - } - - #ifdef RT5625_PROC - rt5625_proc_init(); - #endif - - rt5625_reset(codec); - snd_soc_write(codec, RT5625_PD_CTRL, 0); - snd_soc_write(codec, RT5625_PWR_ADD1, RT5625_P_MAIN_BIAS); - snd_soc_write(codec, RT5625_PWR_ADD2, RT5625_P_VREF); -#ifdef RT5625_DEMO - rt5625_reg_init(codec); -#endif - codec->dapm.bias_level = SND_SOC_BIAS_STANDBY; - rt5625_codec = codec; - return 0; -} - -static int rt5625_remove(struct snd_soc_codec *codec) -{ - rt5625_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - -#ifdef CONFIG_PM -static int rt5625_suspend(struct snd_soc_codec *codec) -{ - rt5625_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - -static int rt5625_resume(struct snd_soc_codec *codec) -{ - rt5625_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - return 0; -} -#else -#define rt5625_suspend NULL -#define rt5625_resume NULL -#endif - -#define RT5625_STEREO_RATES SNDRV_PCM_RATE_8000_48000 -#define RT5625_VOICE_RATES SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_8000 -#define RT5625_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ - SNDRV_PCM_FMTBIT_S20_3LE |\ - SNDRV_PCM_FMTBIT_S24_LE |\ - SNDRV_PCM_FMTBIT_S8) - -struct snd_soc_dai_ops rt5625_aif_dai_ops = { -#ifdef RT5625_F_SMT_PHO - .trigger = rt5625_trigger, -#endif - .hw_params = rt5625_hw_params, - .set_fmt = rt5625_set_dai_fmt, - .set_sysclk = rt5625_set_dai_sysclk, - .set_pll = rt5625_set_dai_pll, -}; - -struct snd_soc_dai_driver rt5625_dai[] = { - { - .name = "rt5625-aif1", - .id = RT5625_AIF1, - .playback = { - .stream_name = "HiFi Playback", - .channels_min = 1, - .channels_max = 2, - .rates = RT5625_STEREO_RATES, - .formats = RT5625_FORMATS, - }, - .capture = { - .stream_name = "HiFi Capture", - .channels_min = 1, - .channels_max = 2, - .rates = RT5625_STEREO_RATES, - .formats = RT5625_FORMATS, - }, - .ops = &rt5625_aif_dai_ops, - }, - { - .name = "rt5625-aif2", - .id = RT5625_AIF2, - .playback = { - .stream_name = "Voice Playback", - .channels_min = 1, - .channels_max = 2, - .rates = RT5625_VOICE_RATES, - .formats = RT5625_FORMATS, - }, - .capture = { - .stream_name = "Voice Capture", - .channels_min = 1, - .channels_max = 2, - .rates = RT5625_VOICE_RATES, - .formats = RT5625_FORMATS, - }, - .ops = &rt5625_aif_dai_ops, - }, -}; - -static struct snd_soc_codec_driver soc_codec_dev_rt5625 = { - .probe = rt5625_probe, - .remove = rt5625_remove, - .suspend = rt5625_suspend, - .resume = rt5625_resume, - .set_bias_level = rt5625_set_bias_level, - .reg_cache_size = 0x80, - .reg_word_size = sizeof(u16), - .reg_cache_default = rt5625_reg, - .volatile_register = rt5625_volatile_register, - .readable_register = rt5625_readable_register, - .reg_cache_step = 1, - .controls = rt5625_snd_controls, - .num_controls = ARRAY_SIZE(rt5625_snd_controls), - .dapm_widgets = rt5625_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(rt5625_dapm_widgets), - .dapm_routes = rt5625_dapm_routes, - .num_dapm_routes = ARRAY_SIZE(rt5625_dapm_routes), -}; - -static const struct i2c_device_id rt5625_i2c_id[] = { - { "rt5625", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, rt5625_i2c_id); - -#ifdef CONFIG_OF -/* -dts: - codec@1e { - compatible = "rt5625"; - reg = <0x1e>; - spk-ctr-pin = <&gpio3 GPIO_D7 GPIO_ACTIVE_HIGH>; - spk-ctr-on = <1>; - spk-ctr-off = <0>; - }; -*/ - -static int rt5625_parse_dt_property(struct device *dev, - struct rt5625_priv *rt5625) -{ - struct device_node *node = dev->of_node; - int ret; - - printk("%s()\n", __FUNCTION__); - - if (!node) - return -ENODEV; - - rt5625->spk_ctr_pin= of_get_named_gpio_flags(node, "spk-ctr-pin", 0, NULL); - if (rt5625->spk_ctr_pin < 0) { - DBG("%s() Can not read property spk-ctr-pin\n", __FUNCTION__); - rt5625->spk_ctr_pin = INVALID_GPIO; - } - - ret = of_property_read_u32(node, "spk-ctr-on", &rt5625->spk_ctr_on); - if (ret < 0) { - DBG("%s() Can not read property spk-ctr-on\n", __FUNCTION__); - rt5625->spk_ctr_on = 1; - } - - ret = of_property_read_u32(node, "spk-ctr-off", &rt5625->spk_ctr_off); - if (ret < 0) { - DBG("%s() Can not read property spk-ctr-off\n", __FUNCTION__); - rt5625->spk_ctr_off = 0; - } - - return 0; -} -#else -static int rt5625_parse_dt_property(struct device *dev, - struct rt3261_priv *rt3261) -{ - return -ENOSYS; -} -#endif //#ifdef CONFIG_OF - -static int rt5625_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) -{ - struct rt5625_priv *rt5625; - int ret; - //struct rt5625_platform_data *pdata = pdata = i2c->dev.platform_data; - - rt5625 = kzalloc(sizeof(struct rt5625_priv), GFP_KERNEL); - if (NULL == rt5625) - return -ENOMEM; - - ret = rt5625_parse_dt_property(&i2c->dev, rt5625); - if (ret < 0) { - printk("%s() parse device tree property error %d\n", __FUNCTION__, ret); - return ret; - } - - if(rt5625->spk_ctr_pin != INVALID_GPIO) - { - gpio_request(rt5625->spk_ctr_pin,NULL); - gpio_direction_output(rt5625->spk_ctr_pin,rt5625->spk_ctr_off); - rt5625->spk_ctr_status = 0; - } - - i2c_set_clientdata(i2c, rt5625); - - ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5625, - rt5625_dai, ARRAY_SIZE(rt5625_dai)); - if (ret < 0) - kfree(rt5625); - - return ret; -} - -static int rt5625_i2c_remove(struct i2c_client *i2c) -{ - snd_soc_unregister_codec(&i2c->dev); - kfree(i2c_get_clientdata(i2c)); - return 0; -} - -struct i2c_driver rt5625_i2c_driver = { - .driver = { - .name = "rt5625", - .owner = THIS_MODULE, - }, - .probe = rt5625_i2c_probe, - .remove = rt5625_i2c_remove, - .id_table = rt5625_i2c_id, -}; - -static int __init rt5625_modinit(void) -{ - return i2c_add_driver(&rt5625_i2c_driver); -} -module_init(rt5625_modinit); - -static void __exit rt5625_modexit(void) -{ - i2c_del_driver(&rt5625_i2c_driver); -} -module_exit(rt5625_modexit); - -MODULE_DESCRIPTION("ASoC RT5625 driver"); -MODULE_AUTHOR("Johnny Hsu "); -MODULE_LICENSE("GPL"); - - -#ifdef RT5625_PROC - -static ssize_t rt5625_proc_write(struct file *file, const char __user *buffer, - unsigned long len, void *data) -{ - char *cookie_pot; - char *p; - int reg; - int value; - - cookie_pot = (char *)vmalloc( len ); - if (!cookie_pot) - { - return -ENOMEM; - } - else - { - if (copy_from_user( cookie_pot, buffer, len )) - return -EFAULT; - } - - switch(cookie_pot[0]) - { - case 'd': - case 'D': - debug_write_read ++; - debug_write_read %= 2; - if(debug_write_read != 0) - printk("Debug read and write reg on\n"); - else - printk("Debug read and write reg off\n"); - break; - case 'r': - case 'R': - printk("Read reg debug\n"); - if(cookie_pot[1] ==':') - { - debug_write_read = 1; - strsep(&cookie_pot,":"); - while((p=strsep(&cookie_pot,","))) - { - reg = simple_strtol(p,NULL,16); - value = rt5625_read(rt5625_codec,reg); - printk("rt5625_read:0x%04x = 0x%04x\n",reg,value); - } - debug_write_read = 0; - printk("\n"); - } - else - { - printk("Error Read reg debug.\n"); - printk("For example: echo r:22,23,24,25>rt5625_ts\n"); - } - break; - case 'w': - case 'W': - printk("Write reg debug\n"); - if(cookie_pot[1] ==':') - { - debug_write_read = 1; - strsep(&cookie_pot,":"); - while((p=strsep(&cookie_pot,"="))) - { - reg = simple_strtol(p,NULL,16); - p=strsep(&cookie_pot,","); - value = simple_strtol(p,NULL,16); - rt5625_write(rt5625_codec,reg,value); - printk("rt5625_write:0x%04x = 0x%04x\n",reg,value); - } - debug_write_read = 0; - printk("\n"); - } - else - { - printk("Error Write reg debug.\n"); - printk("For example: w:22=0,23=0,24=0,25=0>rt5625_ts\n"); - } - break; - case 'a': - printk("Dump reg \n"); - - for(reg = 0; reg < 0x6e; reg+=2) - { - value = rt5625_read(rt5625_codec,reg); - printk("rt5625_read:0x%04x = 0x%04x\n",reg,value); - } - - break; - default: - printk("Help for rt5625_ts .\n-->The Cmd list: \n"); - printk("-->'d&&D' Open or Off the debug\n"); - printk("-->'r&&R' Read reg debug,Example: echo 'r:22,23,24,25'>rt5625_ts\n"); - printk("-->'w&&W' Write reg debug,Example: echo 'w:22=0,23=0,24=0,25=0'>rt5625_ts\n"); - break; - } - - return len; -} - -static const struct file_operations rt5625_proc_fops = { - .owner = THIS_MODULE, -}; - -static int rt5625_proc_init(void) -{ - struct proc_dir_entry *rt5625_proc_entry; - rt5625_proc_entry = create_proc_entry("driver/rt5625_ts", 0777, NULL); - if(rt5625_proc_entry != NULL) - { - rt5625_proc_entry->write_proc = rt5625_proc_write; - return 0; - } - else - { - printk("create proc error !\n"); - return -1; - } -} -#endif - diff --git a/sound/soc/codecs/rt5625.h b/sound/soc/codecs/rt5625.h deleted file mode 100644 index f61e439426dc..000000000000 --- a/sound/soc/codecs/rt5625.h +++ /dev/null @@ -1,823 +0,0 @@ -/* - * rt5625.h -- RT5625 ALSA SoC audio driver - * - * Copyright 2011 Realtek Microelectronics - * Author: Johnny Hsu - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef __RT5625_H__ -#define __RT5625_H__ - -#define RT5625_RESET 0x00 -#define RT5625_SPK_OUT_VOL 0x02 -#define RT5625_HP_OUT_VOL 0x04 -#define RT5625_AUX_OUT_VOL 0x06 -#define RT5625_PHONEIN_VOL 0x08 -#define RT5625_LINE_IN_VOL 0x0a -#define RT5625_DAC_VOL 0x0c -#define RT5625_MIC_VOL 0x0e -#define RT5625_DAC_MIC_CTRL 0x10 -#define RT5625_ADC_REC_GAIN 0x12 -#define RT5625_ADC_REC_MIXER 0x14 -#define RT5625_VDAC_OUT_VOL 0x18 -#define RT5625_VODSP_PDM_CTL 0x1a -#define RT5625_OUTMIX_CTRL 0x1c -#define RT5625_VODSP_CTL 0x1e -#define RT5625_MIC_CTRL 0x22 -#define RT5625_DMIC_CTRL 0x24 -#define RT5625_PD_CTRL 0x26 -#define RT5625_F_DAC_ADC_VDAC 0x2e -#define RT5625_SDP_CTRL 0x34 -#define RT5625_EXT_SDP_CTRL 0x36 -#define RT5625_PWR_ADD1 0x3a -#define RT5625_PWR_ADD2 0x3c -#define RT5625_PWR_ADD3 0x3e -#define RT5625_GEN_CTRL1 0x40 -#define RT5625_GEN_CTRL2 0x42 -#define RT5625_PLL_CTRL 0x44 -#define RT5625_PLL2_CTRL 0x46 -#define RT5625_LDO_CTRL 0x48 -#define RT5625_GPIO_CONFIG 0x4c -#define RT5625_GPIO_POLAR 0x4e -#define RT5625_GPIO_STICKY 0x50 -#define RT5625_GPIO_WAKEUP 0x52 -#define RT5625_GPIO_STATUS 0x54 -#define RT5625_GPIO_SHARING 0x56 -#define RT5625_OTC_STATUS 0x58 -#define RT5625_SOFT_VOL_CTRL 0x5a -#define RT5625_GPIO_OUT_CTRL 0x5c -#define RT5625_MISC_CTRL 0x5e -#define RT5625_DAC_CLK_CTRL1 0x60 -#define RT5625_DAC_CLK_CTRL2 0x62 -#define RT5625_VDAC_CLK_CTRL1 0x64 -#define RT5625_PS_CTRL 0x68 -#define RT5625_PRIV_INDEX 0x6a -#define RT5625_PRIV_DATA 0x6c -#define RT5625_EQ_CTRL 0x6e -#define RT5625_DSP_ADDR 0x70 -#define RT5625_DSP_DATA 0x72 -#define RT5625_DSP_CMD 0x74 -#define RT5625_VENDOR_ID1 0x7c -#define RT5625_VENDOR_ID2 0x7e - -/* global definition */ -#define RT5625_L_MUTE (0x1 << 15) -#define RT5625_L_MUTE_SFT 15 -#define RT5625_L_ZC (0x1 << 14) -#define RT5625_L_VOL_MASK (0x1f << 8) -#define RT5625_L_HVOL_MASK (0x3f << 8) -#define RT5625_L_VOL_SFT 8 -#define RT5625_R_MUTE (0x1 << 7) -#define RT5625_R_MUTE_SFT 7 -#define RT5625_R_ZC (0x1 << 6) -#define RT5625_R_VOL_MASK (0x1f) -#define RT5625_R_HVOL_MASK (0x3f) -#define RT5625_R_VOL_SFT 0 -#define RT5625_M_HPMIX (0x1 << 15) -#define RT5625_M_SPKMIX (0x1 << 14) -#define RT5625_M_MONOMIX (0x1 << 13) - -/* Phone Input (0x08) */ -#define RT5625_M_PHO_HM (0x1 << 15) -#define RT5625_M_PHO_HM_SFT 15 -#define RT5625_M_PHO_SM (0x1 << 14) -#define RT5625_M_PHO_SM_SFT 14 -#define RT5625_PHO_DIFF (0x1 << 13) -#define RT5625_PHO_DIFF_SFT 13 -#define RT5625_PHO_DIFF_DIS (0x0 << 13) -#define RT5625_PHO_DIFF_EN (0x1 << 13) - -/* Linein Volume (0x0a) */ -#define RT5625_M_LI_HM (0x1 << 15) -#define RT5625_M_LI_HM_SFT 15 -#define RT5625_M_LI_SM (0x1 << 14) -#define RT5625_M_LI_SM_SFT 14 -#define RT5625_M_LI_MM (0x1 << 13) -#define RT5625_M_LI_MM_SFT 13 - -/* MIC Input Volume (0x0e) */ -#define RT5625_MIC1_DIFF_MASK (0x1 << 15) -#define RT5625_MIC1_DIFF_SFT 15 -#define RT5625_MIC1_DIFF_DIS (0x0 << 15) -#define RT5625_MIC1_DIFF_EN (0x1 << 15) -#define RT5625_MIC2_DIFF_MASK (0x1 << 7) -#define RT5625_MIC2_DIFF_SFT 7 -#define RT5625_MIC2_DIFF_DIS (0x0 << 7) -#define RT5625_MIC2_DIFF_EN (0x1 << 7) - -/* Stereo DAC and MIC Routing Control (0x10) */ -#define RT5625_M_MIC1_HM (0x1 << 15) -#define RT5625_M_MIC1_HM_SFT 15 -#define RT5625_M_MIC1_SM (0x1 << 14) -#define RT5625_M_MIC1_SM_SFT 14 -#define RT5625_M_MIC1_MM (0x1 << 13) -#define RT5625_M_MIC1_MM_SFT 13 -#define RT5625_M_MIC2_HM (0x1 << 11) -#define RT5625_M_MIC2_HM_SFT 11 -#define RT5625_M_MIC2_SM (0x1 << 10) -#define RT5625_M_MIC2_SM_SFT 10 -#define RT5625_M_MIC2_MM (0x1 << 9) -#define RT5625_M_MIC2_MM_SFT 9 -#define RT5625_M_DACL_HM (0x1 << 3) -#define RT5625_M_DACL_HM_SFT 3 -#define RT5625_M_DACR_HM (0x1 << 2) -#define RT5625_M_DACR_HM_SFT 2 -#define RT5625_M_DAC_SM (0x1 << 1) -#define RT5625_M_DAC_SM_SFT 1 -#define RT5625_M_DAC_MM (0x1) -#define RT5625_M_DAC_MM_SFT 0 - -/* ADC Record Gain (0x12) */ -#define RT5625_M_ADCL_HM (0x1 << 15) -#define RT5625_M_ADCL_HM_SFT 15 -#define RT5625_M_ADCL_MM (0x1 << 14) -#define RT5625_M_ADCL_MM_SFT 14 -#define RT5625_ADCL_ZCD (0x1 << 13) -#define RT5625_G_ADCL_MASK (0x1f << 8) -#define RT5625_M_ADCR_HM (0x1 << 7) -#define RT5625_M_ADCR_HM_SFT 7 -#define RT5625_M_ADCR_MM (0x1 << 6) -#define RT5625_M_ADCR_MM_SFT 6 -#define RT5625_ADCR_ZCD (0x1 << 5) -#define RT5625_G_ADCR_MASK (0x1f) - -/* ADC Record Mixer Control (0x14) */ -#define RT5625_M_RM_L_MIC1 (0x1 << 14) -#define RT5625_M_RM_L_MIC1_SFT 14 -#define RT5625_M_RM_L_MIC2 (0x1 << 13) -#define RT5625_M_RM_L_MIC2_SFT 13 -#define RT5625_M_RM_L_LINE (0x1 << 12) -#define RT5625_M_RM_L_LINE_SFT 12 -#define RT5625_M_RM_L_PHO (0x1 << 11) -#define RT5625_M_RM_L_PHO_SFT 11 -#define RT5625_M_RM_L_HM (0x1 << 10) -#define RT5625_M_RM_L_HM_SFT 10 -#define RT5625_M_RM_L_SM (0x1 << 9) -#define RT5625_M_RM_L_SM_SFT 9 -#define RT5625_M_RM_L_MM (0x1 << 8) -#define RT5625_M_RM_L_MM_SFT 8 -#define RT5625_M_RM_R_MIC1 (0x1 << 6) -#define RT5625_M_RM_R_MIC1_SFT 6 -#define RT5625_M_RM_R_MIC2 (0x1 << 5) -#define RT5625_M_RM_R_MIC2_SFT 5 -#define RT5625_M_RM_R_LINE (0x1 << 4) -#define RT5625_M_RM_R_LINE_SFT 4 -#define RT5625_M_RM_R_PHO (0x1 << 3) -#define RT5625_M_RM_R_PHO_SFT 3 -#define RT5625_M_RM_R_HM (0x1 << 2) -#define RT5625_M_RM_R_HM_SFT 2 -#define RT5625_M_RM_R_SM (0x1 << 1) -#define RT5625_M_RM_R_SM_SFT 1 -#define RT5625_M_RM_R_MM (0x1) -#define RT5625_M_RM_R_MM_SFT 0 - -/* Voice DAC Volume (0x18) */ -#define RT5625_M_VDAC_HM (0x1 << 15) -#define RT5625_M_VDAC_HM_SFT 15 -#define RT5625_M_VDAC_SM (0x1 << 14) -#define RT5625_M_VDAC_SM_SFT 14 -#define RT5625_M_VDAC_MM (0x1 << 13) -#define RT5625_M_VDAC_MM_SFT 13 - -/* AEC & PDM Control (0x1a) */ -#define RT5625_SRC1_PWR (0x1 << 15) -#define RT5625_SRC1_PWR_SFT 15 -#define RT5625_SRC2_PWR (0x1 << 13) -#define RT5625_SRC2_PWR_SFT 13 -#define RT5625_SRC2_S_MASK (0x1 << 12) -#define RT5625_SRC2_S_SFT 12 -#define RT5625_SRC2_S_TXDP (0x0 << 12) -#define RT5625_SRC2_S_TXDC (0x1 << 12) -#define RT5625_RXDP_PWR (0x1 << 11) -#define RT5625_RXDP_PWR_SFT 11 -#define RT5625_RXDP_S_MASK (0x3 << 9) -#define RT5625_RXDP_S_SFT 9 -#define RT5625_RXDP_S_SRC1 (0x0 << 9) -#define RT5625_RXDP_S_ADCL (0x1 << 9) -#define RT5625_RXDP_S_VOICE (0x2 << 9) -#define RT5625_RXDP_S_ADCR (0x3 << 9) -#define RT5625_RXDC_PWR (0x1 << 8) -#define RT5625_RXDC_PWR_SFT 8 -#define RT5625_PCM_S_MASK (0x1 << 7) -#define RT5625_PCM_S_SFT 7 -#define RT5625_PCM_S_ADCR (0x0 << 7) -#define RT5625_PCM_S_TXDP (0x1 << 7) -#define RT5625_REC_IIS_S_MASK (0x3 << 4) -#define RT5625_REC_IIS_S_SFT 4 -#define RT5625_REC_IIS_S_ADC (0x0 << 4) -#define RT5625_REC_IIS_S_VOICE (0x1 << 4) -#define RT5625_REC_IIS_S_SRC2 (0x2 << 4) - -/* Output Mixer Control (0x1c) */ -#define RT5625_SPKN_S_MASK (0x3 << 14) -#define RT5625_SPKN_S_SFT 14 -#define RT5625_SPKN_S_LN (0x2 << 14) -#define RT5625_SPKN_S_RP (0x1 << 14) -#define RT5625_SPKN_S_RN (0x0 << 14) -#define RT5625_SPK_T_MASK (0x1 << 13) -#define RT5625_SPK_T_SFT 13 -#define RT5625_SPK_T_CLS_D (0x1 << 13) -#define RT5625_SPK_T_CLS_AB (0x0 << 13) -#define RT5625_CLS_AB_MASK (0x1 << 12) -#define RT5625_CLS_AB_SFT 12 -#define RT5625_CLS_AB_S_AMP (0x0 << 12) -#define RT5625_CLS_AB_W_AMP (0x1 << 12) -#define RT5625_SPKVOL_S_MASK (0x3 << 10) -#define RT5625_SPKVOL_S_SFT 10 -#define RT5625_SPKVOL_S_MM (0x3 << 10) -#define RT5625_SPKVOL_S_SM (0x2 << 10) -#define RT5625_SPKVOL_S_HM (0x1 << 10) -#define RT5625_SPKVOL_S_VMID (0x0 << 10) -#define RT5625_HPVOL_L_S_MASK (0x1 << 9) -#define RT5625_HPVOL_L_S_SFT 9 -#define RT5625_HPVOL_L_S_HM (0x1 << 9) -#define RT5625_HPVOL_L_S_VMID (0x0 << 9) -#define RT5625_HPVOL_R_S_MASK (0x1 << 8) -#define RT5625_HPVOL_R_S_SFT 8 -#define RT5625_HPVOL_R_S_HM (0x1 << 8) -#define RT5625_HPVOL_R_S_VMID (0x0 << 8) -#define RT5625_AUXVOL_S_MASK (0x3 << 6) -#define RT5625_AUXVOL_S_SFT 6 -#define RT5625_AUXVOL_S_MM (0x3 << 6) -#define RT5625_AUXVOL_S_SM (0x2 << 6) -#define RT5625_AUXVOL_S_HM (0x1 << 6) -#define RT5625_AUXVOL_S_VMID (0x0 << 6) -#define RT5625_AUXOUT_MODE (0x1 << 4) -#define RT5625_AUXOUT_MODE_SFT 4 -#define RT5625_DACL_HP_MASK (0x1 << 1) -#define RT5625_DACL_HP_SFT 1 -#define RT5625_DACL_HP_MUTE (0x0 << 1) -#define RT5625_DACL_HP_ON (0x1 << 1) -#define RT5625_DACR_HP_MASK (0x1) -#define RT5625_DACR_HP_SFT 0 -#define RT5625_DACR_HP_MUTE (0x0) -#define RT5625_DACR_HP_ON (0x1) - -/* VoDSP Control (0x1e) */ -#define RT5625_DSP_SCLK_S_MASK (0x1 << 15) -#define RT5625_DSP_SCLK_S_SFT 15 -#define RT5625_DSP_SCLK_S_MCLK (0x0 << 15) -#define RT5625_DSP_SCLK_S_VCLK (0x1 << 15) -#define RT5625_DSP_LRCK_MASK (0x1 << 13) -#define RT5625_DSP_LRCK_SFT 13 -#define RT5625_DSP_LRCK_8K (0x0 << 13) -#define RT5625_DSP_LRCK_16K (0x1 << 13) -#define RT5625_DSP_TP_MASK (0x1 << 3) -#define RT5625_DSP_TP_SFT 3 -#define RT5625_DSP_TP_NOR (0x0 << 3) -#define RT5625_DSP_TP_TEST (0x1 << 3) -#define RT5625_DSP_BP_MASK (0x1 << 2) -#define RT5625_DSP_BP_SFT 2 -#define RT5625_DSP_BP_EN (0x0 << 2) -#define RT5625_DSP_BP_NOR (0x1 << 2) -#define RT5625_DSP_PD_MASK (0x1 << 1) -#define RT5625_DSP_PD_SFT 1 -#define RT5625_DSP_PD_EN (0x0 << 1) -#define RT5625_DSP_PD_NOR (0x1 << 1) -#define RT5625_DSP_RST_MASK (0x1) -#define RT5625_DSP_RST_SFT 0 -#define RT5625_DSP_RST_EN (0x0) -#define RT5625_DSP_RST_NOR (0x1) - -/* Microphone Control (0x22) */ -#define RT5625_MIC1_BST_MASK (0x3 << 10) -#define RT5625_MIC1_BST_SFT 10 -#define RT5625_MIC1_BST_BYPASS (0x0 << 10) -#define RT5625_MIC1_BST_20DB (0x1 << 10) -#define RT5625_MIC1_BST_30DB (0x2 << 10) -#define RT5625_MIC1_BST_40DB (0x3 << 10) -#define RT5625_MIC2_BST_MASK (0x3 << 8) -#define RT5625_MIC2_BST_SFT 8 -#define RT5625_MIC2_BST_BYPASS (0x0 << 8) -#define RT5625_MIC2_BST_20DB (0x1 << 8) -#define RT5625_MIC2_BST_30DB (0x2 << 8) -#define RT5625_MIC2_BST_40DB (0x3 << 8) -#define RT5625_MB1_OV_MASK (0x1 << 5) -#define RT5625_MB1_OV_90P (0x0 << 5) -#define RT5625_MB1_OV_75P (0x1 << 5) -#define RT5625_MB2_OV_MASK (0x1 << 4) -#define RT5625_MB2_OV_90P (0x0 << 4) -#define RT5625_MB2_OV_75P (0x1 << 4) -#define RT5625_SCD_THD_MASK (0x3) -#define RT5625_SCD_THD_600UA (0x0) -#define RT5625_SCD_THD_1500UA (0x1) -#define RT5625_SCD_THD_2000UA (0x2) - -/* Digital Boost Control (0x24) */ -#define RT5625_DIG_BST_MASK (0x7) -#define RT5625_DIG_BST_SFT 0 - -/* Power Down Control/Status (0x26) */ -#define RT5625_PWR_PR7 (0x1 << 15) -#define RT5625_PWR_PR6 (0x1 << 14) -#define RT5625_PWR_PR5 (0x1 << 13) -#define RT5625_PWR_PR3 (0x1 << 11) -#define RT5625_PWR_PR2 (0x1 << 10) -#define RT5625_PWR_PR1 (0x1 << 9) -#define RT5625_PWR_PR0 (0x1 << 8) -#define RT5625_PWR_REF_ST (0x1 << 3) -#define RT5625_PWR_AM_ST (0x1 << 2) -#define RT5625_PWR_DAC_ST (0x1 << 1) -#define RT5625_PWR_ADC_ST (0x1) - -/* Stereo DAC/Voice DAC/Stereo ADC Function Select (0x2e) */ -#define RT5625_DAC_F_MASK (0x3 << 12) -#define RT5625_DAC_F_SFT 12 -#define RT5625_DAC_F_DAC (0x0 << 12) -#define RT5625_DAC_F_SRC2 (0x1 << 12) -#define RT5625_DAC_F_TXDP (0x2 << 12) -#define RT5625_DAC_F_TXDC (0x3 << 12) -#define RT5625_VDAC_S_MASK (0x7 << 8) -#define RT5625_VDAC_S_SFT 8 -#define RT5625_VDAC_S_VOICE (0x0 << 8) -#define RT5625_VDAC_S_SRC2 (0x1 << 8) -#define RT5625_VDAC_S_TXDP (0x2 << 8) -#define RT5625_VDAC_S_TXDC (0x3 << 8) -#define RT5625_ADCR_F_MASK (0x3 << 4) -#define RT5625_ADCR_F_SFT 4 -#define RT5625_ADCR_F_ADC (0x0 << 4) -#define RT5625_ADCR_F_VADC (0x1 << 4) -#define RT5625_ADCR_F_DSP (0x2 << 4) -#define RT5625_ADCR_F_PDM (0x3 << 4) -#define RT5625_ADCL_F_MASK (0x1) -#define RT5625_ADCL_F_SFT 0 -#define RT5625_ADCL_F_ADC (0x0) -#define RT5625_ADCL_F_DSP (0x1) - -/* Main Serial Data Port Control (Stereo IIS) (0x34) */ -#define RT5625_I2S_M_MASK (0x1 << 15) -#define RT5625_I2S_M_SFT 15 -#define RT5625_I2S_M_MST (0x0 << 15) -#define RT5625_I2S_M_SLV (0x1 << 15) -#define RT5625_I2S_SAD_MASK (0x1 << 14) -#define RT5625_I2S_SAD_SFT 14 -#define RT5625_I2S_SAD_DIS (0x0 << 14) -#define RT5625_I2S_SAD_EN (0x1 << 14) -#define RT5625_I2S_S_MASK (0x1 << 8) -#define RT5625_I2S_S_SFT 8 -#define RT5625_I2S_S_MSCLK (0x0 << 8) -#define RT5625_I2S_S_VSCLK (0x1 << 8) -#define RT5625_I2S_BP_MASK (0x1 << 7) -#define RT5625_I2S_BP_SFT 7 -#define RT5625_I2S_BP_NOR (0x0 << 7) -#define RT5625_I2S_BP_INV (0x1 << 7) -#define RT5625_I2S_LRCK_MASK (0x1 << 6) -#define RT5625_I2S_LRCK_SFT 6 -#define RT5625_I2S_LRCK_NOR (0x0 << 6) -#define RT5625_I2S_LRCK_INV (0x1 << 6) -#define RT5625_I2S_DL_MASK (0x3 << 2) -#define RT5625_I2S_DL_SFT 2 -#define RT5625_I2S_DL_16 (0x0 << 2) -#define RT5625_I2S_DL_20 (0x1 << 2) -#define RT5625_I2S_DL_24 (0x2 << 2) -#define RT5625_I2S_DL_8 (0x3 << 2) -#define RT5625_I2S_DF_MASK (0x3) -#define RT5625_I2S_DF_SFT 0 -#define RT5625_I2S_DF_I2S (0x0) -#define RT5625_I2S_DF_LEFT (0x1) -#define RT5625_I2S_DF_PCM_A (0x2) -#define RT5625_I2S_DF_PCM_B (0x3) - -/* Extend Serial Data Port Control (0x36) */ -#define RT5625_PCM_F_MASK (0x1 << 15) -#define RT5625_PCM_F_SFT 15 -#define RT5625_PCM_F_GPIO (0x0 << 15) -#define RT5625_PCM_F_PCM (0x1 << 15) -#define RT5625_PCM_M_MASK (0x1 << 14) -#define RT5625_PCM_M_SFT 14 -#define RT5625_PCM_M_MST (0x0 << 14) -#define RT5625_PCM_M_SLV (0x1 << 14) -#define RT5625_PCM_CS_MASK (0x1 << 8) -#define RT5625_PCM_CS_SFT 8 -#define RT5625_PCM_CS_SCLK (0x0 << 8) -#define RT5625_PCM_CS_VSCLK (0x1 << 8) - -/* Power Management Addition 1 (0x3a) */ -#define RT5625_P_DACL_MIX (0x1 << 15) -#define RT5625_P_DACL_MIX_BIT 15 -#define RT5625_P_DACR_MIX (0x1 << 14) -#define RT5625_P_DACR_MIX_BIT 14 -#define RT5625_P_ZCD (0x1 << 13) -#define RT5625_P_ZCD_BIT 13 -#define RT5625_P_I2S (0x1 << 11) -#define RT5625_P_I2S_BIT 11 -#define RT5625_P_SPK_AMP (0x1 << 10) -#define RT5625_P_SPK_AMP_BIT 10 -#define RT5625_P_HPO_AMP (0x1 << 9) -#define RT5625_P_HPO_AMP_BIT 9 -#define RT5625_P_HPO_ENH (0x1 << 8) -#define RT5625_P_HPO_ENH_BIT 8 -#define RT5625_P_VDAC_MIX (0x1 << 7) -#define RT5625_P_VDAC_MIX_BIT 7 -#define RT5625_P_SG_EN (0x1 << 6) -#define RT5625_P_SG_EN_BIT 6 -#define RT5625_P_MB1_SCD (0x1 << 5) -#define RT5625_P_MB1_SCD_BIT 5 -#define RT5625_P_MB2_SCD (0x1 << 4) -#define RT5625_P_MB2_SCD_BIT 4 -#define RT5625_P_MB1 (0x1 << 3) -#define RT5625_P_MB1_BIT 3 -#define RT5625_P_MB2 (0x1 << 2) -#define RT5625_P_MB2_BIT 2 -#define RT5625_P_MAIN_BIAS (0x1 << 1) -#define RT5625_P_MAIN_BIAS_BIT 1 -#define RT5625_P_DAC_REF (0x1) -#define RT5625_P_DAC_REF_BIT 0 - -/* Power Management Addition 2 (0x3c) */ -#define RT5625_P_PLL1 (0x1 << 15) -#define RT5625_P_PLL1_BIT 15 -#define RT5625_P_PLL2 (0x1 << 14) -#define RT5625_P_PLL2_BIT 14 -#define RT5625_P_VREF (0x1 << 13) -#define RT5625_P_VREF_BIT 13 -#define RT5625_P_OVT (0x1 << 12) -#define RT5625_P_OVT_BIT 12 -#define RT5625_P_AUX_ADC (0x1 << 11) -#define RT5625_P_AUX_ADC_BIT 11 -#define RT5625_P_VDAC (0x1 << 10) -#define RT5625_P_VDAC_BIT 10 -#define RT5625_P_DACL (0x1 << 9) -#define RT5625_P_DACL_BIT 9 -#define RT5625_P_DACR (0x1 << 8) -#define RT5625_P_DACR_BIT 8 -#define RT5625_P_ADCL (0x1 << 7) -#define RT5625_P_ADCL_BIT 7 -#define RT5625_P_ADCR (0x1 << 6) -#define RT5625_P_ADCR_BIT 6 -#define RT5625_P_HM_L (0x1 << 5) -#define RT5625_P_HM_L_BIT 5 -#define RT5625_P_HM_R (0x1 << 4) -#define RT5625_P_HM_R_BIT 4 -#define RT5625_P_SM (0x1 << 3) -#define RT5625_P_SM_BIT 3 -#define RT5625_P_MM (0x1 << 2) -#define RT5625_P_MM_BIT 2 -#define RT5625_P_ADCL_RM (0x1 << 1) -#define RT5625_P_ADCL_RM_BIT 1 -#define RT5625_P_ADCR_RM (0x1) -#define RT5625_P_ADCR_RM_BIT 0 - -/* Power Management Addition 3 (0x3e) */ -#define RT5625_P_OSC_EN (0x1 << 15) -#define RT5625_P_OSC_EN_BIT 15 -#define RT5625_P_AUX_VOL (0x1 << 14) -#define RT5625_P_AUX_VOL_BIT 14 -#define RT5625_P_SPKL_VOL (0x1 << 13) -#define RT5625_P_SPKL_VOL_BIT 13 -#define RT5625_P_SPKR_VOL (0x1 << 12) -#define RT5625_P_SPKR_VOL_BIT 12 -#define RT5625_P_HPL_VOL (0x1 << 11) -#define RT5625_P_HPL_VOL_BIT 11 -#define RT5625_P_HPR_VOL (0x1 << 10) -#define RT5625_P_HPR_VOL_BIT 10 -#define RT5625_P_DSP_IF (0x1 << 9) -#define RT5625_P_DSP_IF_BIT 9 -#define RT5625_P_DSP_I2C (0x1 << 8) -#define RT5625_P_DSP_I2C_BIT 8 -#define RT5625_P_LV_L (0x1 << 7) -#define RT5625_P_LV_L_BIT 7 -#define RT5625_P_LV_R (0x1 << 6) -#define RT5625_P_LV_R_BIT 6 -#define RT5625_P_PH_VOL (0x1 << 5) -#define RT5625_P_PH_VOL_BIT 5 -#define RT5625_P_PH_ADMIX (0x1 << 4) -#define RT5625_P_PH_ADMIX_BIT 4 -#define RT5625_P_MIC1_VOL (0x1 << 3) -#define RT5625_P_MIC1_VOL_BIT 3 -#define RT5625_P_MIC2_VOL (0x1 << 2) -#define RT5625_P_MIC2_VOL_BIT 2 -#define RT5625_P_MIC1_BST (0x1 << 1) -#define RT5625_P_MIC1_BST_BIT 1 -#define RT5625_P_MIC2_BST (0x1) -#define RT5625_P_MIC2_BST_BIT 0 - -/* General Purpose Control Register 1 (0x40) */ -#define RT5625_SCLK_MASK (0x1 << 15) -#define RT5625_SCLK_SFT 15 -#define RT5625_SCLK_MCLK (0x0 << 15) -#define RT5625_SCLK_PLL1 (0x1 << 15) -#define RT5625_VSCLK_MASK (0x1 << 4) -#define RT5625_VSCLK_SFT 4 -#define RT5625_VSCLK_PLL2 (0x0<<4) -#define RT5625_VSCLK_EXTCLK (0x1<<4) -#define RT5625_SPK_R_MASK (0x7 << 1) -#define RT5625_SPK_R_SFT 1 -#define RT5625_SPK_R_225V (0x0 << 1) -#define RT5625_SPK_R_200V (0x1 << 1) -#define RT5625_SPK_R_175V (0x2 << 1) -#define RT5625_SPK_R_150V (0x3 << 1) -#define RT5625_SPK_R_125V (0x4 << 1) -#define RT5625_SPK_R_100V (0x5 << 1) - -/* General Purpose Control Register 2 (0x42) */ -#define RT5625_PLL1_S_MASK (0x3 << 12) -#define RT5625_PLL1_S_SFT 12 -#define RT5625_PLL1_S_MCLK (0x0 << 12) -#define RT5625_PLL1_S_BCLK (0x2 << 12) -#define RT5625_PLL1_S_VBCLK (0x3 << 12) - -/* PLL2 Control (0x46) */ -#define RT5625_PLL2_MASK (0x1 << 15) -#define RT5625_PLL2_DIS (0x0 << 15) -#define RT5625_PLL2_EN (0x1 << 15) -#define RT5625_PLL2_R_MASK (0x1) -#define RT5625_PLL2_R_8X (0x0) -#define RT5625_PLL2_R_16X (0x1) - -/* LDO Control (0x48) */ -#define RT5625_LDO_MASK (0x1 << 15) -#define RT5625_LDO_DIS (0x0 << 15) -#define RT5625_LDO_EN (0x1 << 15) -#define RT5625_LDO_VC_MASK (0xf) -#define RT5625_LDO_VC_1_55V (0xf<<0) -#define RT5625_LDO_VC_1_50V (0xe<<0) -#define RT5625_LDO_VC_1_45V (0xd<<0) -#define RT5625_LDO_VC_1_40V (0xc<<0) -#define RT5625_LDO_VC_1_35V (0xb<<0) -#define RT5625_LDO_VC_1_30V (0xa<<0) -#define RT5625_LDO_VC_1_25V (0x9<<0) -#define RT5625_LDO_VC_1_20V (0x8<<0) -#define RT5625_LDO_VC_1_15V (0x7<<0) -#define RT5625_LDO_VC_1_05V (0x6<<0) -#define RT5625_LDO_VC_1_00V (0x5<<0) -#define RT5625_LDO_VC_0_95V (0x4<<0) -#define RT5625_LDO_VC_0_90V (0x3<<0) -#define RT5625_LDO_VC_0_85V (0x2<<0) -#define RT5625_LDO_VC_0_80V (0x1<<0) -#define RT5625_LDO_VC_0_75V (0x0<<0) - -/* GPIO Pin Configuration (0x4c) */ -#define RT5625_GPIO_5 (0x1 << 5) -#define RT5625_GPIO_4 (0x1 << 4) -#define RT5625_GPIO_3 (0x1 << 3) -#define RT5625_GPIO_2 (0x1 << 2) -#define RT5625_GPIO_1 (0x1 << 1) - -/* MISC Control (0x5e) */ -#define RT5625_FAST_VREF_MASK (0x1 << 15) -#define RT5625_FAST_VREF_EN (0x0 << 15) -#define RT5625_FAST_VREF_DIS (0x1 << 15) -#define RT5625_HP_DEPOP_M2 (0x1 << 8) -#define RT5625_HP_DEPOP_M1 (0x1 << 9) -#define RT5625_HPL_MUM_DEPOP (0x1 << 7) -#define RT5625_HPR_MUM_DEPOP (0x1 << 6) -#define RT5625_MUM_DEPOP (0x1 << 5) - -/* Stereo DAC Clock Control 1 (0x60) */ -#define RT5625_BCLK_DIV1_MASK (0xf << 12) -#define RT5625_BCLK_DIV1_1 (0x0 << 12) -#define RT5625_BCLK_DIV1_2 (0x1 << 12) -#define RT5625_BCLK_DIV1_3 (0x2 << 12) -#define RT5625_BCLK_DIV1_4 (0x3 << 12) -#define RT5625_BCLK_DIV1_5 (0x4 << 12) -#define RT5625_BCLK_DIV1_6 (0x5 << 12) -#define RT5625_BCLK_DIV1_7 (0x6 << 12) -#define RT5625_BCLK_DIV1_8 (0x7 << 12) -#define RT5625_BCLK_DIV1_9 (0x8 << 12) -#define RT5625_BCLK_DIV1_10 (0x9 << 12) -#define RT5625_BCLK_DIV1_11 (0xa << 12) -#define RT5625_BCLK_DIV1_12 (0xb << 12) -#define RT5625_BCLK_DIV1_13 (0xc << 12) -#define RT5625_BCLK_DIV1_14 (0xd << 12) -#define RT5625_BCLK_DIV1_15 (0xe << 12) -#define RT5625_BCLK_DIV1_16 (0xf << 12) -#define RT5625_BCLK_DIV2_MASK (0x7 << 8) -#define RT5625_BCLK_DIV2_2 (0x0 << 8) -#define RT5625_BCLK_DIV2_4 (0x1 << 8) -#define RT5625_BCLK_DIV2_8 (0x2 << 8) -#define RT5625_BCLK_DIV2_16 (0x3 << 8) -#define RT5625_BCLK_DIV2_32 (0x4 << 8) -#define RT5625_AD_LRCK_DIV1_MASK (0xf << 4) -#define RT5625_AD_LRCK_DIV1_1 (0x0 << 4) -#define RT5625_AD_LRCK_DIV1_2 (0x1 << 4) -#define RT5625_AD_LRCK_DIV1_3 (0x2 << 4) -#define RT5625_AD_LRCK_DIV1_4 (0x3 << 4) -#define RT5625_AD_LRCK_DIV1_5 (0x4 << 4) -#define RT5625_AD_LRCK_DIV1_6 (0x5 << 4) -#define RT5625_AD_LRCK_DIV1_7 (0x6 << 4) -#define RT5625_AD_LRCK_DIV1_8 (0x7 << 4) -#define RT5625_AD_LRCK_DIV1_9 (0x8 << 4) -#define RT5625_AD_LRCK_DIV1_10 (0x9 << 4) -#define RT5625_AD_LRCK_DIV1_11 (0xa << 4) -#define RT5625_AD_LRCK_DIV1_12 (0xb << 4) -#define RT5625_AD_LRCK_DIV1_13 (0xc << 4) -#define RT5625_AD_LRCK_DIV1_14 (0xd << 4) -#define RT5625_AD_LRCK_DIV1_15 (0xe << 4) -#define RT5625_AD_LRCK_DIV1_16 (0xf << 4) -#define RT5625_AD_LRCK_DIV2_MASK (0x7 << 1) -#define RT5625_AD_LRCK_DIV2_2 (0x0 << 1) -#define RT5625_AD_LRCK_DIV2_4 (0x1 << 1) -#define RT5625_AD_LRCK_DIV2_8 (0x2 << 1) -#define RT5625_AD_LRCK_DIV2_16 (0x3 << 1) -#define RT5625_AD_LRCK_DIV2_32 (0x4 << 1) -#define RT5625_DA_LRCK_DIV_MASK (1) -#define RT5625_DA_LRCK_DIV_32 (0) -#define RT5625_DA_LRCK_DIV_64 (1) - -/* Stereo DAC Clock Control 2 (0x62) */ -#define RT5625_DF_DIV1_MASK (0xF << 12) -#define RT5625_DF_DIV1_1 (0x0 << 12) -#define RT5625_DF_DIV1_2 (0x1 << 12) -#define RT5625_DF_DIV1_3 (0x2 << 12) -#define RT5625_DF_DIV1_4 (0x3 << 12) -#define RT5625_DF_DIV1_5 (0x4 << 12) -#define RT5625_DF_DIV1_6 (0x5 << 12) -#define RT5625_DF_DIV1_7 (0x6 << 12) -#define RT5625_DF_DIV1_8 (0x7 << 12) -#define RT5625_DF_DIV1_9 (0x8 << 12) -#define RT5625_DF_DIV1_10 (0x9 << 12) -#define RT5625_DF_DIV1_11 (0xA << 12) -#define RT5625_DF_DIV1_12 (0xB << 12) -#define RT5625_DF_DIV1_13 (0xC << 12) -#define RT5625_DF_DIV1_14 (0xD << 12) -#define RT5625_DF_DIV1_15 (0xE << 12) -#define RT5625_DF_DIV1_16 (0xF << 12) -#define RT5625_DF_DIV2_MASK (0x7 << 9) -#define RT5625_DF_DIV2_2 (0x0 << 9) -#define RT5625_DF_DIV2_4 (0x1 << 9) -#define RT5625_DF_DIV2_8 (0x2 << 9) -#define RT5625_DF_DIV2_16 (0x3 << 9) -#define RT5625_DF_DIV2_32 (0x4 << 9) -#define RT5625_AF_DIV1_MASK (0xF << 4) -#define RT5625_AF_DIV1_1 (0x0 << 4) -#define RT5625_AF_DIV1_2 (0x1 << 4) -#define RT5625_AF_DIV1_3 (0x2 << 4) -#define RT5625_AF_DIV1_4 (0x3 << 4) -#define RT5625_AF_DIV1_5 (0x4 << 4) -#define RT5625_AF_DIV1_6 (0x5 << 4) -#define RT5625_AF_DIV1_7 (0x6 << 4) -#define RT5625_AF_DIV1_8 (0x7 << 4) -#define RT5625_AF_DIV1_9 (0x8 << 4) -#define RT5625_AF_DIV1_10 (0x9 << 4) -#define RT5625_AF_DIV1_11 (0xA << 4) -#define RT5625_AF_DIV1_12 (0xB << 4) -#define RT5625_AF_DIV1_13 (0xC << 4) -#define RT5625_AF_DIV1_14 (0xD << 4) -#define RT5625_AF_DIV1_15 (0xE << 4) -#define RT5625_AF_DIV1_16 (0xF << 4) -#define RT5625_AF_DIV2_MASK (0x7 << 1) -#define RT5625_AF_DIV2_1 (0x0 << 1) -#define RT5625_AF_DIV2_2 (0x1 << 1) -#define RT5625_AF_DIV2_4 (0x2 << 1) -#define RT5625_AF_DIV2_8 (0x3 << 1) -#define RT5625_AF_DIV2_16 (0x4 << 1) -#define RT5625_AF_DIV2_32 (0x5 << 1) - -/* Voice DAC PCM Clock Control 1 (0x64) */ -#define RT5625_VBCLK_DIV1_MASK (0xF << 12) -#define RT5625_VBCLK_DIV1_1 (0x0 << 12) -#define RT5625_VBCLK_DIV1_2 (0x1 << 12) -#define RT5625_VBCLK_DIV1_3 (0x2 << 12) -#define RT5625_VBCLK_DIV1_4 (0x3 << 12) -#define RT5625_VBCLK_DIV1_5 (0x4 << 12) -#define RT5625_VBCLK_DIV1_6 (0x5 << 12) -#define RT5625_VBCLK_DIV1_7 (0x6 << 12) -#define RT5625_VBCLK_DIV1_8 (0x7 << 12) -#define RT5625_VBCLK_DIV1_9 (0x8 << 12) -#define RT5625_VBCLK_DIV1_10 (0x9 << 12) -#define RT5625_VBCLK_DIV1_11 (0xA << 12) -#define RT5625_VBCLK_DIV1_12 (0xB << 12) -#define RT5625_VBCLK_DIV1_13 (0xC << 12) -#define RT5625_VBCLK_DIV1_14 (0xD << 12) -#define RT5625_VBCLK_DIV1_15 (0xE << 12) -#define RT5625_VBCLK_DIV1_16 (0xF << 12) -#define RT5625_VBCLK_DIV2_MASK (0x7 << 8) -#define RT5625_VBCLK_DIV2_2 (0x0 << 8) -#define RT5625_VBCLK_DIV2_4 (0x1 << 8) -#define RT5625_VBCLK_DIV2_8 (0x2 << 8) -#define RT5625_VBCLK_DIV2_16 (0x3 << 8) -#define RT5625_VBCLK_DIV2_32 (0x4 << 8) -#define RT5625_AD_VLRCK_DIV1_MASK (0xF << 4) -#define RT5625_AD_VLRCK_DIV1_1 (0x0 << 4) -#define RT5625_AD_VLRCK_DIV1_2 (0x1 << 4) -#define RT5625_AD_VLRCK_DIV1_3 (0x2 << 4) -#define RT5625_AD_VLRCK_DIV1_4 (0x3 << 4) -#define RT5625_AD_VLRCK_DIV1_5 (0x4 << 4) -#define RT5625_AD_VLRCK_DIV1_6 (0x5 << 4) -#define RT5625_AD_VLRCK_DIV1_7 (0x6 << 4) -#define RT5625_AD_VLRCK_DIV1_8 (0x7 << 4) -#define RT5625_AD_VLRCK_DIV1_9 (0x8 << 4) -#define RT5625_AD_VLRCK_DIV1_10 (0x9 << 4) -#define RT5625_AD_VLRCK_DIV1_11 (0xA << 4) -#define RT5625_AD_VLRCK_DIV1_12 (0xB << 4) -#define RT5625_AD_VLRCK_DIV1_13 (0xC << 4) -#define RT5625_AD_VLRCK_DIV1_14 (0xD << 4) -#define RT5625_AD_VLRCK_DIV1_15 (0xE << 4) -#define RT5625_AD_VLRCK_DIV1_16 (0xF << 4) -#define RT5625_AD_VLRCK_DIV2_MASK (0x7 << 1) -#define RT5625_AD_VLRCK_DIV2_2 (0x0 << 1) -#define RT5625_AD_VLRCK_DIV2_4 (0x1 << 1) -#define RT5625_AD_VLRCK_DIV2_8 (0x2 << 1) -#define RT5625_AD_VLRCK_DIV2_16 (0x3 << 1) -#define RT5625_AD_VLRCK_DIV2_32 (0x4 << 1) -#define RT5625_DA_VLRCK_DIV_MASK (1) -#define RT5625_DA_VLRCK_DIV_32 (0) -#define RT5625_DA_VLRCK_DIV_64 (1) - -/* Psedueo Stereo & Spatial Effect Block Control (0x68) */ -#define RT5625_SP_CTRL_EN (0x1 << 15) -#define RT5625_APF_EN (0x1 << 14) -#define RT5625_PS_EN (0x1 << 13) -#define RT5625_STO_EXP_EN (0x1 << 12) -#define RT5625_SP_3D_G1_MASK (0x3 << 10) -#define RT5625_SP_3D_G1_1_0 (0x0 << 10) -#define RT5625_SP_3D_G1_1_5 (0x1 << 10) -#define RT5625_SP_3D_G1_2_0 (0x2 << 10) -#define RT5625_SP_3D_R1_MASK (0x3 << 8) -#define RT5625_SP_3D_R1_0_0 (0x0 << 8) -#define RT5625_SP_3D_R1_0_66 (0x1 << 8) -#define RT5625_SP_3D_R1_1_0 (0x2 << 8) -#define RT5625_SP_3D_G2_MASK (0x3 << 6) -#define RT5625_SP_3D_G2_1_0 (0x0 << 6) -#define RT5625_SP_3D_G2_1_5 (0x1 << 6) -#define RT5625_SP_3D_G2_2_0 (0x2 << 6) -#define RT5625_SP_3D_R2_MASK (0x3 << 4) -#define RT5625_SP_3D_R2_0_0 (0x0 << 4) -#define RT5625_SP_3D_R2_0_66 (0x1 << 4) -#define RT5625_SP_3D_R2_1_0 (0x2 << 4) -#define RT5625_APF_MASK (0x3) -#define RT5625_APF_48K (0x3) -#define RT5625_APF_44_1K (0x2) -#define RT5625_APF_32K (0x1) - -/* EQ Control and Status /ADC HPF Control (0x6E) */ -#define RT5625_EN_HW_EQ_BLK (0x1 << 15) -#define RT5625_EQ_SRC_DAC (0x0 << 14) -#define RT5625_EQ_SRC_ADC (0x1 << 14) -#define RT5625_EQ_CHG_EN (0x1 << 7) -#define RT5625_EN_HW_EQ_HPF (0x1 << 4) -#define RT5625_EN_HW_EQ_BP3 (0x1 << 3) -#define RT5625_EN_HW_EQ_BP2 (0x1 << 2) -#define RT5625_EN_HW_EQ_BP1 (0x1 << 1) -#define RT5625_EN_HW_EQ_LPF (0x1 << 0) - -/* VoDSP Register Command (0x74) */ -#define RT5625_DSP_BUSY_MASK (0x1 << 15) -#define RT5625_DSP_DS_MASK (0x1 << 14) -#define RT5625_DSP_DS_VODSP (0x0 << 14) -#define RT5625_DSP_DS_REG72 (0x1 << 14) -#define RT5625_DSP_CLK_MASK (0x3 << 12) -#define RT5625_DSP_CLK_12_288M (0x0 << 12) -#define RT5625_DSP_CLK_6_144M (0x1 << 12) -#define RT5625_DSP_CLK_3_072M (0x2 << 12) -#define RT5625_DSP_CLK_2_048M (0x3 << 12) -#define RT5625_DSP_R_EN (0x1 << 9) -#define RT5625_DSP_W_EN (0x1 << 8) -#define RT5625_DSP_CMD_MASK (0xff) -#define RT5625_DSP_CMD_SFT 0 -#define RT5625_DSP_CMD_MW (0x3B) /* Memory Write */ -#define RT5625_DSP_CMD_MR (0x37) /* Memory Read */ -#define RT5625_DSP_CMD_RR (0x60) /* Register Read */ -#define RT5625_DSP_CMD_RW (0x68) /* Register Write */ - - -/* Index(0x20) for Auto Volume Control */ -#define RT5625_AVC_CH_MASK (0x1 << 7) -#define RT5625_AVC_CH_L_CH (0x0 << 7) -#define RT5625_AVC_CH_R_CH (0x1 << 7) -#define RT5625_AVC_GAIN_EN (0x1 << 15) - - - -enum { - RT5625_AIF1, - RT5625_AIF2, -}; - -/* System Clock Source */ -enum { - RT5625_SCLK_S_MCLK, - RT5625_SCLK_S_PLL, -}; - -enum pll_sel { - RT5625_PLL_MCLK = 0, - RT5625_PLL_MCLK_TO_VSYSCLK, - RT5625_PLL_BCLK, - RT5625_PLL_VBCLK, -}; - -enum { - RT5625_AEC_DIS, - RT5625_AEC_EN, -}; - -//#ifdef RT5625_F_SMT_PHO -enum { - RT5625_PLL_DIS, - RT5625_PLL_112896_225792, - RT5625_PLL_112896_24576, -}; -//#endif - -typedef struct { - unsigned short index; - unsigned short value; -} rt5625_dsp_reg; - -#endif diff --git a/sound/soc/codecs/rt_codec_ioctl.c b/sound/soc/codecs/rt_codec_ioctl.c deleted file mode 100644 index ab952a62a8d5..000000000000 --- a/sound/soc/codecs/rt_codec_ioctl.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - * rt_codec_ioctl.h -- RT56XX ALSA SoC audio driver IO control - * - * Copyright 2012 Realtek Microelectronics - * Author: Bard - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include "rt_codec_ioctl.h" - -static struct rt_codec_ops rt_codec_ioctl_ops; - -#if defined(CONFIG_SND_HWDEP) || defined(CONFIG_SND_HWDEP_MODULE) -#define RT_CE_CODEC_HWDEP_NAME "rt_codec hwdep " -static int rt_codec_hwdep_open(struct snd_hwdep *hw, struct file *file) -{ - struct snd_soc_codec *codec = hw->private_data; - dev_dbg(codec->dev, "%s()\n", __func__); - return 0; -} - -static int rt_codec_hwdep_release(struct snd_hwdep *hw, struct file *file) -{ - struct snd_soc_codec *codec = hw->private_data; - dev_dbg(codec->dev, "%s()\n", __func__); - return 0; -} - -static int rt_codec_hwdep_ioctl_common(struct snd_hwdep *hw, - struct file *file, unsigned int cmd, unsigned long arg) -{ - struct snd_soc_codec *codec = hw->private_data; - struct rt_codec_cmd __user *_rt_codec = (struct rt_codec_cmd *)arg; - struct rt_codec_cmd rt_codec; - int *buf, *p; - - if (copy_from_user(&rt_codec, _rt_codec, sizeof(rt_codec))) { - dev_err(codec->dev,"copy_from_user faild\n"); - return -EFAULT; - } - dev_dbg(codec->dev, "%s(): rt_codec.number=%zu, cmd=%d\n", - __func__, rt_codec.number, cmd); - buf = kmalloc(sizeof(*buf) * rt_codec.number, GFP_KERNEL); - if (buf == NULL) - return -ENOMEM; - if (copy_from_user(buf, rt_codec.buf, sizeof(*buf) * rt_codec.number)) { - goto err; - } - - switch (cmd) { - case RT_READ_CODEC_REG_IOCTL: - for (p = buf; p < buf + rt_codec.number / 2; p++) { - *(p + rt_codec.number / 2) = snd_soc_read(codec, *p); - } - if (copy_to_user(rt_codec.buf, buf, sizeof(*buf) * rt_codec.number)) - goto err; - break; - - case RT_WRITE_CODEC_REG_IOCTL: - for (p = buf; p < buf + rt_codec.number / 2; p++) - snd_soc_write(codec, *p, *(p + rt_codec.number / 2)); - break; - - case RT_READ_CODEC_INDEX_IOCTL: - if (NULL == rt_codec_ioctl_ops.index_read) - goto err; - - for (p = buf; p < buf + rt_codec.number / 2; p++) - *(p+rt_codec.number/2) = rt_codec_ioctl_ops.index_read( - codec, *p); - if (copy_to_user(rt_codec.buf, buf, - sizeof(*buf) * rt_codec.number)) - goto err; - break; - - case RT_WRITE_CODEC_INDEX_IOCTL: - if (NULL == rt_codec_ioctl_ops.index_write) - goto err; - - for (p = buf; p < buf + rt_codec.number / 2; p++) - rt_codec_ioctl_ops.index_write(codec, *p, - *(p+rt_codec.number/2)); - break; - - default: - if (NULL == rt_codec_ioctl_ops.ioctl_common) - goto err; - - rt_codec_ioctl_ops.ioctl_common(hw, file, cmd, arg); - break; - } - - kfree(buf); - return 0; - -err: - kfree(buf); - return -EFAULT; -} - -static int rt_codec_codec_dump_reg(struct snd_hwdep *hw, - struct file *file, unsigned long arg) -{ - struct snd_soc_codec *codec = hw->private_data; - struct rt_codec_cmd __user *_rt_codec =(struct rt_codec_cmd *)arg; - struct rt_codec_cmd rt_codec; - int i, *buf, number = codec->driver->reg_cache_size; - - dev_dbg(codec->dev, "enter %s, number = %d\n", __func__, number); - if (copy_from_user(&rt_codec, _rt_codec, sizeof(rt_codec))) - return -EFAULT; - - buf = kmalloc(sizeof(*buf) * number, GFP_KERNEL); - if (buf == NULL) - return -ENOMEM; - - for (i = 0; i < number/2; i++) { - buf[i] = i << 1; - buf[i + number / 2] = codec->read(codec, buf[i]); - } - if (copy_to_user(rt_codec.buf, buf, sizeof(*buf) * i)) - goto err; - rt_codec.number = number; - if (copy_to_user(_rt_codec, &rt_codec, sizeof(rt_codec))) - goto err; - kfree(buf); - return 0; - -err: - kfree(buf); - return -EFAULT; -} - -static int rt_codec_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, - unsigned int cmd, unsigned long arg) -{ - switch (cmd) { - case RT_READ_ALL_CODEC_REG_IOCTL: - return rt_codec_codec_dump_reg(hw, file, arg); - - default: - return rt_codec_hwdep_ioctl_common(hw, file, cmd, arg); - } - - return 0; -} - -int realtek_ce_init_hwdep(struct snd_soc_codec *codec) -{ - struct snd_hwdep *hw; - struct snd_card *card = codec->card->snd_card; - int err; - - dev_dbg(codec->dev, "enter %s\n", __func__); - - if ((err = snd_hwdep_new(card, RT_CE_CODEC_HWDEP_NAME, 0, &hw)) < 0) - return err; - - strcpy(hw->name, RT_CE_CODEC_HWDEP_NAME); - hw->private_data = codec; - hw->ops.open = rt_codec_hwdep_open; - hw->ops.release = rt_codec_hwdep_release; - hw->ops.ioctl = rt_codec_hwdep_ioctl; - - return 0; -} -EXPORT_SYMBOL_GPL(realtek_ce_init_hwdep); -#endif - -struct rt_codec_ops *rt_codec_get_ioctl_ops(void) -{ - return &rt_codec_ioctl_ops; -} -EXPORT_SYMBOL_GPL(rt_codec_get_ioctl_ops); diff --git a/sound/soc/codecs/rt_codec_ioctl.h b/sound/soc/codecs/rt_codec_ioctl.h deleted file mode 100644 index 56daa3712c8b..000000000000 --- a/sound/soc/codecs/rt_codec_ioctl.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * rt_codec_ioctl.h -- RT56XX ALSA SoC audio driver IO control - * - * Copyright 2012 Realtek Microelectronics - * Author: Bard - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef __RT56XX_IOCTL_H__ -#define __RT56XX_IOCTL_H__ - -#include -#include - -struct rt_codec_cmd { - size_t number; - int __user *buf; -}; - -struct rt_codec_ops { - int (*index_write)(struct snd_soc_codec *codec, - unsigned int reg, unsigned int value); - unsigned int (*index_read)(struct snd_soc_codec *codec, - unsigned int reg); - int (*index_update_bits)(struct snd_soc_codec *codec, - unsigned int reg, unsigned int mask, unsigned int value); - int (*ioctl_common)(struct snd_hwdep *hw, struct file *file, - unsigned int cmd, unsigned long arg); -}; - -enum { - RT_READ_CODEC_REG_IOCTL = _IOR('R', 0x01, struct rt_codec_cmd), - RT_WRITE_CODEC_REG_IOCTL = _IOW('R', 0x01, struct rt_codec_cmd), - RT_READ_ALL_CODEC_REG_IOCTL = _IOR('R', 0x02, struct rt_codec_cmd), - RT_READ_CODEC_INDEX_IOCTL = _IOR('R', 0x03, struct rt_codec_cmd), - RT_WRITE_CODEC_INDEX_IOCTL = _IOW('R', 0x03, struct rt_codec_cmd), - RT_READ_CODEC_DSP_IOCTL = _IOR('R', 0x04, struct rt_codec_cmd), - RT_WRITE_CODEC_DSP_IOCTL = _IOW('R', 0x04, struct rt_codec_cmd), - RT_SET_CODEC_HWEQ_IOCTL = _IOW('R', 0x05, struct rt_codec_cmd), - RT_GET_CODEC_HWEQ_IOCTL = _IOR('R', 0x05, struct rt_codec_cmd), - RT_SET_CODEC_SPK_VOL_IOCTL = _IOW('R', 0x06, struct rt_codec_cmd), - RT_GET_CODEC_SPK_VOL_IOCTL = _IOR('R', 0x06, struct rt_codec_cmd), - RT_SET_CODEC_MIC_GAIN_IOCTL = _IOW('R', 0x07, struct rt_codec_cmd), - RT_GET_CODEC_MIC_GAIN_IOCTL = _IOR('R', 0x07, struct rt_codec_cmd), - RT_SET_CODEC_3D_SPK_IOCTL = _IOW('R', 0x08, struct rt_codec_cmd), - RT_GET_CODEC_3D_SPK_IOCTL = _IOR('R', 0x08, struct rt_codec_cmd), - RT_SET_CODEC_MP3PLUS_IOCTL = _IOW('R', 0x09, struct rt_codec_cmd), - RT_GET_CODEC_MP3PLUS_IOCTL = _IOR('R', 0x09, struct rt_codec_cmd), - RT_SET_CODEC_3D_HEADPHONE_IOCTL = _IOW('R', 0x0a, struct rt_codec_cmd), - RT_GET_CODEC_3D_HEADPHONE_IOCTL = _IOR('R', 0x0a, struct rt_codec_cmd), - RT_SET_CODEC_BASS_BACK_IOCTL = _IOW('R', 0x0b, struct rt_codec_cmd), - RT_GET_CODEC_BASS_BACK_IOCTL = _IOR('R', 0x0b, struct rt_codec_cmd), - RT_SET_CODEC_DIPOLE_SPK_IOCTL = _IOW('R', 0x0c, struct rt_codec_cmd), - RT_GET_CODEC_DIPOLE_SPK_IOCTL = _IOR('R', 0x0c, struct rt_codec_cmd), - RT_SET_CODEC_DRC_AGC_ENABLE_IOCTL = _IOW('R', 0x0d, struct rt_codec_cmd), - RT_GET_CODEC_DRC_AGC_ENABLE_IOCTL = _IOR('R', 0x0d, struct rt_codec_cmd), - RT_SET_CODEC_DSP_MODE_IOCTL = _IOW('R', 0x0e, struct rt_codec_cmd), - RT_GET_CODEC_DSP_MODE_IOCTL = _IOR('R', 0x0e, struct rt_codec_cmd), - RT_SET_CODEC_WNR_ENABLE_IOCTL = _IOW('R', 0x0f, struct rt_codec_cmd), - RT_GET_CODEC_WNR_ENABLE_IOCTL = _IOR('R', 0x0f, struct rt_codec_cmd), - RT_SET_CODEC_DRC_AGC_PAR_IOCTL = _IOW('R', 0x10, struct rt_codec_cmd), - RT_GET_CODEC_DRC_AGC_PAR_IOCTL = _IOR('R', 0x10, struct rt_codec_cmd), - RT_SET_CODEC_DIGI_BOOST_GAIN_IOCTL = _IOW('R', 0x11, struct rt_codec_cmd), - RT_GET_CODEC_DIGI_BOOST_GAIN_IOCTL = _IOR('R', 0x11, struct rt_codec_cmd), - RT_SET_CODEC_NOISE_GATE_IOCTL = _IOW('R', 0x12, struct rt_codec_cmd), - RT_GET_CODEC_NOISE_GATE_IOCTL = _IOR('R', 0x12, struct rt_codec_cmd), - RT_SET_CODEC_DRC_AGC_COMP_IOCTL = _IOW('R', 0x13, struct rt_codec_cmd), - RT_GET_CODEC_DRC_AGC_COMP_IOCTL = _IOR('R', 0x13, struct rt_codec_cmd), - RT_GET_CODEC_ID = _IOR('R', 0x30, struct rt_codec_cmd), -}; - -int realtek_ce_init_hwdep(struct snd_soc_codec *codec); -struct rt_codec_ops *rt_codec_get_ioctl_ops(void); - -#endif /* __RT56XX_IOCTL_H__ */ diff --git a/sound/soc/codecs/tc358749x.c b/sound/soc/codecs/tc358749x.c deleted file mode 100644 index 6c0252e61f31..000000000000 --- a/sound/soc/codecs/tc358749x.c +++ /dev/null @@ -1,307 +0,0 @@ -/* - * tc358749x.c TC358749XBG ALSA SoC audio codec driver - * - * Copyright (c) 2016 Fuzhou Rockchip Electronics Co., Ltd - * Author: Roy - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see .* - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "tc358749x.h" - -static int snd_tc358749x_dai_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *codec_dai) -{ - struct snd_soc_codec *codec = codec_dai->codec; - unsigned int fs; - - switch (params_rate(params)) { - case 32000: - fs = FS_32000; - break; - case 44100: - fs = FS_44100; - break; - case 48000: - fs = FS_48000; - break; - case 88200: - fs = FS_88200; - break; - case 96000: - fs = FS_96000; - break; - case 176400: - fs = FS_176400; - break; - case 192000: - fs = FS_192000; - break; - default: - dev_err(codec->dev, "Enter:%s, %d, Error rate=%d\n", - __func__, __LINE__, params_rate(params)); - return -EINVAL; - } - snd_soc_update_bits(codec, TC358749X_FS_SET, FS_SET_MASK, fs); - return 0; -} - -static int snd_tc358749x_mute(struct snd_soc_dai *dai, int mute) -{ - struct snd_soc_codec *codec = dai->codec; - - if (mute) - snd_soc_update_bits(codec, TC358749X_FORCE_MUTE, - FORCE_DMUTE_MASK, MUTE); - else - snd_soc_update_bits(codec, TC358749X_FORCE_MUTE, - FORCE_DMUTE_MASK, !MUTE); - - return 0; -} - -static const struct snd_soc_dai_ops tc358749x_dai_ops = { - .hw_params = snd_tc358749x_dai_hw_params, - .digital_mute = snd_tc358749x_mute, -}; - -static struct snd_soc_dai_driver tc358749x_dai = { - .name = "tc358749x-audio", - .playback = { - .stream_name = "Playback", - .channels_min = 2, - .channels_max = 8, - .rates = SNDRV_PCM_RATE_32000 | - SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | - SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | - SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000, - .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, - }, - - .capture = { - .stream_name = "Capture", - .channels_min = 2, - .channels_max = 8, - .rates = SNDRV_PCM_RATE_32000 | - SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | - SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | - SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000, - .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, - }, - .ops = &tc358749x_dai_ops, -}; - -static int tc358749x_probe(struct snd_soc_codec *codec) -{ - snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - -static int tc358749_set_bias_level(struct snd_soc_codec *codec, - enum snd_soc_bias_level level) -{ - switch (level) { - case SND_SOC_BIAS_ON: - break; - - case SND_SOC_BIAS_PREPARE: - snd_soc_update_bits(codec, TC358749X_FORCE_MUTE, - FORCE_DMUTE_MASK, !MUTE); - break; - - case SND_SOC_BIAS_STANDBY: - break; - - case SND_SOC_BIAS_OFF: - snd_soc_update_bits(codec, TC358749X_FORCE_MUTE, - FORCE_DMUTE_MASK, MUTE); - break; - } - - return 0; -} - -static struct snd_soc_codec_driver soc_codec_dev_tc358749x = { - .probe = tc358749x_probe, - .set_bias_level = tc358749_set_bias_level, -}; - -static bool tc358749x_readable_register(struct device *dev, unsigned int reg) -{ - switch (reg) { - case TC358749X_FORCE_MUTE: - case TC358749X_FS_SET: - return true; - default: - return false; - } -} - -static const struct reg_default tc358749x_reg_defaults[] = { - { TC358749X_FORCE_MUTE, 0xb1 }, - { TC358749X_FS_SET, 0x00 }, -}; - -const struct regmap_config tc358749x_regmap_config = { - .reg_bits = 16, - .val_bits = 8, - .max_register = TC358749X_FS_SET, - .cache_type = REGCACHE_RBTREE, - .reg_defaults = tc358749x_reg_defaults, - .num_reg_defaults = ARRAY_SIZE(tc358749x_reg_defaults), - .readable_reg = tc358749x_readable_register, -}; - -static const struct i2c_device_id tc358749x_i2c_id[] = { - { "tc358749x", 0 }, - { } -}; - -MODULE_DEVICE_TABLE(i2c, tc358749x_i2c_id); - -static int tc358749x_parse_dts(struct i2c_client *i2c, - struct tc358749x_priv *tc358749x) -{ - int ret = 0; - struct device *dev = &i2c->dev; - - tc358749x->gpio_power18 = devm_gpiod_get_optional(dev, "power18", - GPIOD_OUT_LOW); - - tc358749x->gpio_power = devm_gpiod_get_optional(dev, "power", - GPIOD_OUT_LOW); - if (IS_ERR(tc358749x->gpio_power)) { - ret = PTR_ERR(tc358749x->gpio_power); - dev_err(&i2c->dev, "Unable to claim gpio \"power\".\n"); - return ret; - } - - tc358749x->gpio_power33 = devm_gpiod_get_optional(dev, "power33", - GPIOD_OUT_LOW); - - tc358749x->gpio_int = devm_gpiod_get_optional(dev, "int", - GPIOD_OUT_LOW); - if (IS_ERR(tc358749x->gpio_int)) { - ret = PTR_ERR(tc358749x->gpio_int); - dev_err(&i2c->dev, "Unable to claim gpio \"int\".\n"); - return ret; - } - - tc358749x->gpio_reset = devm_gpiod_get_optional(dev, "reset", - GPIOD_OUT_LOW); - if (IS_ERR(tc358749x->gpio_reset)) { - ret = PTR_ERR(tc358749x->gpio_reset); - dev_err(&i2c->dev, "Unable to claim gpio \"reset\".\n"); - return ret; - } - - tc358749x->gpio_csi_ctl = devm_gpiod_get_optional(dev, "csi-ctl", - GPIOD_OUT_LOW); - if (IS_ERR(tc358749x->gpio_csi_ctl)) { - ret = PTR_ERR(tc358749x->gpio_csi_ctl); - dev_err(&i2c->dev, "Unable to claim gpio \"csi-ctl\".\n"); - } - - tc358749x->gpio_stanby = devm_gpiod_get_optional(dev, "stanby", - GPIOD_OUT_LOW); - if (IS_ERR(tc358749x->gpio_stanby)) { - ret = PTR_ERR(tc358749x->gpio_stanby); - dev_err(&i2c->dev, "Unable to claim gpio \"stanby\".\n"); - return ret; - } - - if (IS_ERR(tc358749x->gpio_power18)) { - ret = PTR_ERR(tc358749x->gpio_power18); - dev_err(&i2c->dev, "Unable to claim gpio \"power18\".\n"); - } else { - gpiod_direction_output(tc358749x->gpio_power18, 1); - } - - if (IS_ERR(tc358749x->gpio_power33)) { - ret = PTR_ERR(tc358749x->gpio_power33); - dev_err(&i2c->dev, "Unable to claim gpio \"power33\".\n"); - } else { - gpiod_direction_output(tc358749x->gpio_power33, 1); - } - - gpiod_direction_output(tc358749x->gpio_power, 1); - gpiod_direction_output(tc358749x->gpio_stanby, 1); - gpiod_direction_output(tc358749x->gpio_reset, 1); - - /* Wait 10ms tc358749x lock I2C Slave address */ - usleep_range(10000, 11000); - /* after I2C address has been lock and set it input */ - gpiod_direction_input(tc358749x->gpio_int); - return 0; -} - -static int tc358749x_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) -{ - struct tc358749x_priv *tc358749x; - int ret; - - tc358749x = devm_kzalloc(&i2c->dev, sizeof(*tc358749x), - GFP_KERNEL); - if (!tc358749x) - return -ENOMEM; - - i2c_set_clientdata(i2c, tc358749x); - tc358749x_parse_dts(i2c, tc358749x); - - tc358749x->regmap = devm_regmap_init_i2c(i2c, &tc358749x_regmap_config); - if (IS_ERR(tc358749x->regmap)) { - ret = PTR_ERR(tc358749x->regmap); - dev_err(&i2c->dev, "Failed to init regmap: %d\n", ret); - return ret; - } - - ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_tc358749x, - &tc358749x_dai, 1); - - dev_info(&i2c->dev, "%s success\n", __func__); - return ret; -} - -static int tc358749x_i2c_remove(struct i2c_client *i2c) -{ - snd_soc_unregister_codec(&i2c->dev); - - return 0; -} - -static struct i2c_driver tc358749x_i2c_driver = { - .driver = { - .name = "tc358749x", - }, - .probe = tc358749x_i2c_probe, - .remove = tc358749x_i2c_remove, - .id_table = tc358749x_i2c_id, -}; -module_i2c_driver(tc358749x_i2c_driver); - -MODULE_AUTHOR("Roy "); -MODULE_DESCRIPTION("TC358749X HDMI Audio RX ASoC Interface"); -MODULE_LICENSE("GPL");