Fix: i2c access fail when AC108 as master, support make DEBUG=1
This commit is contained in:
parent
1901914b56
commit
860d38fc47
4 changed files with 70 additions and 42 deletions
6
Makefile
6
Makefile
|
@ -7,6 +7,12 @@ obj-m += snd-soc-wm8960.o
|
||||||
obj-m += snd-soc-ac108.o
|
obj-m += snd-soc-ac108.o
|
||||||
obj-m += snd-soc-simple-card.o
|
obj-m += snd-soc-simple-card.o
|
||||||
|
|
||||||
|
ifdef DEBUG
|
||||||
|
ifneq ($(DEBUG),0)
|
||||||
|
ccflags-y += -DDEBUG -DAC101_DEBG
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
all:
|
all:
|
||||||
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
|
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
|
||||||
|
|
28
ac101.c
28
ac101.c
|
@ -20,7 +20,10 @@
|
||||||
* the License, or (at your option) any later version.
|
* the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#undef AC101_DEBG
|
|
||||||
|
/* #undef AC101_DEBG
|
||||||
|
* use 'make DEBUG=1' to enable debugging
|
||||||
|
*/
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <sound/pcm.h>
|
#include <sound/pcm.h>
|
||||||
#include <sound/pcm_params.h>
|
#include <sound/pcm_params.h>
|
||||||
|
@ -292,22 +295,17 @@ static int ac101_aif1clk(struct snd_soc_codec* codec, int event) {
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
AC101_DBG("%s() L%d event=%d pre_up/%d post_down/%d\n", __func__, __LINE__,
|
/* I know it will degrades performance, but I have no choice */
|
||||||
event, SND_SOC_DAPM_PRE_PMU, SND_SOC_DAPM_POST_PMD);
|
spin_lock_irqsave(&ac10x->lock, flags);
|
||||||
|
|
||||||
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case SND_SOC_DAPM_PRE_PMU:
|
case SND_SOC_DAPM_PRE_PMU:
|
||||||
if (ac10x->aif1_clken == 0){
|
if (ac10x->aif1_clken == 0){
|
||||||
/* I know it will degrades performance, but I have no choice */
|
|
||||||
spin_lock_irqsave(&ac10x->lock, flags);
|
|
||||||
|
|
||||||
/* enable aif1clk & sysclk */
|
/* enable aif1clk & sysclk */
|
||||||
ret = ac101_update_bits(codec, SYSCLK_CTRL, (0x1<<AIF1CLK_ENA), (0x1<<AIF1CLK_ENA));
|
ret = ac101_update_bits(codec, SYSCLK_CTRL, (0x1<<AIF1CLK_ENA), (0x1<<AIF1CLK_ENA));
|
||||||
ret = ret || ac101_update_bits(codec, MOD_CLK_ENA, (0x1<<MOD_CLK_AIF1), (0x1<<MOD_CLK_AIF1));
|
ret = ret || ac101_update_bits(codec, MOD_CLK_ENA, (0x1<<MOD_CLK_AIF1), (0x1<<MOD_CLK_AIF1));
|
||||||
ret = ret || ac101_update_bits(codec, MOD_RST_CTRL, (0x1<<MOD_RESET_AIF1), (0x1<<MOD_RESET_AIF1));
|
ret = ret || ac101_update_bits(codec, MOD_RST_CTRL, (0x1<<MOD_RESET_AIF1), (0x1<<MOD_RESET_AIF1));
|
||||||
ret = ret || ac101_update_bits(codec, SYSCLK_CTRL, (0x1<<SYSCLK_ENA), (0x1<<SYSCLK_ENA));
|
ret = ret || ac101_update_bits(codec, SYSCLK_CTRL, (0x1<<SYSCLK_ENA), (0x1<<SYSCLK_ENA));
|
||||||
spin_unlock_irqrestore(&ac10x->lock, flags);
|
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
AC101_DBG("%s() L%d start sysclk failed\n", __func__, __LINE__);
|
AC101_DBG("%s() L%d start sysclk failed\n", __func__, __LINE__);
|
||||||
|
@ -319,15 +317,11 @@ static int ac101_aif1clk(struct snd_soc_codec* codec, int event) {
|
||||||
break;
|
break;
|
||||||
case SND_SOC_DAPM_POST_PMD:
|
case SND_SOC_DAPM_POST_PMD:
|
||||||
if (ac10x->aif1_clken != 0) {
|
if (ac10x->aif1_clken != 0) {
|
||||||
/* I know it will degrades performance, but I have no choice */
|
|
||||||
spin_lock_irqsave(&ac10x->lock, flags);
|
|
||||||
|
|
||||||
/* disable aif1clk & sysclk */
|
/* disable aif1clk & sysclk */
|
||||||
ret = ac101_update_bits(codec, SYSCLK_CTRL, (0x1<<AIF1CLK_ENA),(0x0<<AIF1CLK_ENA));
|
ret = ac101_update_bits(codec, SYSCLK_CTRL, (0x1<<AIF1CLK_ENA),(0x0<<AIF1CLK_ENA));
|
||||||
ret = ret || ac101_update_bits(codec, MOD_CLK_ENA, (0x1<<MOD_CLK_AIF1), (0x0<<MOD_CLK_AIF1));
|
ret = ret || ac101_update_bits(codec, MOD_CLK_ENA, (0x1<<MOD_CLK_AIF1), (0x0<<MOD_CLK_AIF1));
|
||||||
ret = ret || ac101_update_bits(codec, MOD_RST_CTRL, (0x1<<MOD_RESET_AIF1), (0x0<<MOD_RESET_AIF1));
|
ret = ret || ac101_update_bits(codec, MOD_RST_CTRL, (0x1<<MOD_RESET_AIF1), (0x0<<MOD_RESET_AIF1));
|
||||||
ret = ret || ac101_update_bits(codec, SYSCLK_CTRL, (0x1<<SYSCLK_ENA), (0x0<<SYSCLK_ENA));
|
ret = ret || ac101_update_bits(codec, SYSCLK_CTRL, (0x1<<SYSCLK_ENA), (0x0<<SYSCLK_ENA));
|
||||||
spin_unlock_irqrestore(&ac10x->lock, flags);
|
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
AC101_DBG("%s() L%d stop sysclk failed\n", __func__, __LINE__);
|
AC101_DBG("%s() L%d stop sysclk failed\n", __func__, __LINE__);
|
||||||
|
@ -338,6 +332,10 @@ static int ac101_aif1clk(struct snd_soc_codec* codec, int event) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
spin_unlock_irqrestore(&ac10x->lock, flags);
|
||||||
|
|
||||||
|
AC101_DBG("%s() L%d event=%d pre_up/%d post_down/%d\n", __func__, __LINE__,
|
||||||
|
event, SND_SOC_DAPM_PRE_PMU, SND_SOC_DAPM_POST_PMD);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1178,6 +1176,12 @@ int ac101_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Chip reset */
|
||||||
|
/*
|
||||||
|
ret = regmap_write(ac10x->regmap101, CHIP_AUDIO_RST, 0);
|
||||||
|
msleep(50);
|
||||||
|
*/
|
||||||
|
|
||||||
ret = regmap_read(ac10x->regmap101, CHIP_AUDIO_RST, &v);
|
ret = regmap_read(ac10x->regmap101, CHIP_AUDIO_RST, &v);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dev_err(&i2c->dev, "failed to read vendor ID: %d\n", ret);
|
dev_err(&i2c->dev, "failed to read vendor ID: %d\n", ret);
|
||||||
|
|
70
ac108.c
70
ac108.c
|
@ -8,7 +8,10 @@
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
* published by the Free Software Foundation.
|
* published by the Free Software Foundation.
|
||||||
*/
|
*/
|
||||||
#undef DEBUG
|
|
||||||
|
/* #undef DEBUG
|
||||||
|
* use 'make DEBUG=1' to enable debugging
|
||||||
|
*/
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/moduleparam.h>
|
#include <linux/moduleparam.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
|
@ -547,10 +550,6 @@ static int ac108_config_pll(struct ac10x_priv *ac10x, unsigned rate, unsigned lr
|
||||||
/*0x18: PLL clk lock enable*/
|
/*0x18: PLL clk lock enable*/
|
||||||
ac108_multi_update_bits(PLL_LOCK_CTRL, 0x1 << PLL_LOCK_EN, 0x1 << PLL_LOCK_EN, ac10x);
|
ac108_multi_update_bits(PLL_LOCK_CTRL, 0x1 << PLL_LOCK_EN, 0x1 << PLL_LOCK_EN, ac10x);
|
||||||
|
|
||||||
/*0x10: PLL Common voltage Enable, PLL Enable,PLL loop divider factor detection enable*/
|
|
||||||
ac108_multi_update_bits(PLL_CTRL1, 0x01 << PLL_EN | 0x01 << PLL_COM_EN | 0x01 << PLL_NDET,
|
|
||||||
0x01 << PLL_EN | 0x01 << PLL_COM_EN | 0x01 << PLL_NDET, ac10x);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 0x20: enable pll, pll source from mclk/bclk, sysclk source from pll, enable sysclk
|
* 0x20: enable pll, pll source from mclk/bclk, sysclk source from pll, enable sysclk
|
||||||
*/
|
*/
|
||||||
|
@ -670,8 +669,8 @@ static int ac108_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_h
|
||||||
|
|
||||||
/* Master mode, to clear cpu_dai fifos, output bclk without lrck */
|
/* Master mode, to clear cpu_dai fifos, output bclk without lrck */
|
||||||
ac10x_read(I2S_CTRL, &v, ac10x->i2cmap[_MASTER_INDEX]);
|
ac10x_read(I2S_CTRL, &v, ac10x->i2cmap[_MASTER_INDEX]);
|
||||||
if (v & (0x02 << LRCK_IOEN)) {
|
if (v & (0x01 << BCLK_IOEN)) {
|
||||||
ac10x_update_bits(I2S_CTRL, 0x03 << LRCK_IOEN, 0x02 << LRCK_IOEN, ac10x->i2cmap[_MASTER_INDEX]);
|
ac10x_update_bits(I2S_CTRL, 0x1 << LRCK_IOEN, 0x0 << LRCK_IOEN, ac10x->i2cmap[_MASTER_INDEX]);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (params_format(params)) {
|
switch (params_format(params)) {
|
||||||
|
@ -792,6 +791,11 @@ static int ac108_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_h
|
||||||
*/
|
*/
|
||||||
ac108_multi_chips_slots(ac10x, channels);
|
ac108_multi_chips_slots(ac10x, channels);
|
||||||
|
|
||||||
|
/*0x21: Module clock enable<I2S, ADC digital, MIC offset Calibration, ADC analog>*/
|
||||||
|
ac108_multi_write(MOD_CLK_EN, 1 << I2S | 1 << ADC_DIGITAL | 1 << MIC_OFFSET_CALIBRATION | 1 << ADC_ANALOG, ac10x);
|
||||||
|
/*0x22: Module reset de-asserted<I2S, ADC digital, MIC offset Calibration, ADC analog>*/
|
||||||
|
ac108_multi_write(MOD_RST_CTRL, 1 << I2S | 1 << ADC_DIGITAL | 1 << MIC_OFFSET_CALIBRATION | 1 << ADC_ANALOG, ac10x);
|
||||||
|
|
||||||
dev_dbg(dai->dev, "%s() stream=%s ---\n", __func__,
|
dev_dbg(dai->dev, "%s() stream=%s ---\n", __func__,
|
||||||
snd_pcm_stream_str(substream));
|
snd_pcm_stream_str(substream));
|
||||||
|
|
||||||
|
@ -851,7 +855,7 @@ static int ac108_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) {
|
||||||
ac108_multi_update_bits(I2S_CTRL, 0x03 << LRCK_IOEN | 0x03 << SDO1_EN | 0x1 << TXEN | 0x1 << GEN,
|
ac108_multi_update_bits(I2S_CTRL, 0x03 << LRCK_IOEN | 0x03 << SDO1_EN | 0x1 << TXEN | 0x1 << GEN,
|
||||||
0x00 << LRCK_IOEN | 0x03 << SDO1_EN | 0x1 << TXEN | 0x1 << GEN, ac10x);
|
0x00 << LRCK_IOEN | 0x03 << SDO1_EN | 0x1 << TXEN | 0x1 << GEN, ac10x);
|
||||||
/* multi_chips: only one chip set as Master, and the others also need to set as Slave */
|
/* multi_chips: only one chip set as Master, and the others also need to set as Slave */
|
||||||
ac10x_update_bits(I2S_CTRL, 0x3 << LRCK_IOEN, 0x2 << LRCK_IOEN, ac10x->i2cmap[_MASTER_INDEX]);
|
ac10x_update_bits(I2S_CTRL, 0x3 << LRCK_IOEN, 0x01 << BCLK_IOEN, ac10x->i2cmap[_MASTER_INDEX]);
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
/* TODO: Both cpu_dai and codec_dai(AC108) be set as slave in DTS */
|
/* TODO: Both cpu_dai and codec_dai(AC108) be set as slave in DTS */
|
||||||
|
@ -863,8 +867,8 @@ static int ac108_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) {
|
||||||
* 0x30:chip is slave mode, BCLK & LRCK input,enable SDO1_EN and
|
* 0x30:chip is slave mode, BCLK & LRCK input,enable SDO1_EN and
|
||||||
* SDO2_EN, Transmitter Block Enable, Globe Enable
|
* SDO2_EN, Transmitter Block Enable, Globe Enable
|
||||||
*/
|
*/
|
||||||
ac108_multi_update_bits(I2S_CTRL, 0x03 << LRCK_IOEN | 0x03 << SDO1_EN | 0x1 << TXEN | 0x1 << GEN,
|
ac108_multi_update_bits(I2S_CTRL, 0x03 << LRCK_IOEN | 0x03 << SDO1_EN | 0x0 << TXEN | 0x0 << GEN,
|
||||||
0x00 << LRCK_IOEN | 0x03 << SDO1_EN | 0x1 << TXEN | 0x1 << GEN, ac10x);
|
0x00 << LRCK_IOEN | 0x03 << SDO1_EN | 0x0 << TXEN | 0x0 << GEN, ac10x);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
pr_err("AC108 Master/Slave mode config error:%u\n\n", (fmt & SND_SOC_DAIFMT_MASTER_MASK) >> 12);
|
pr_err("AC108 Master/Slave mode config error:%u\n\n", (fmt & SND_SOC_DAIFMT_MASTER_MASK) >> 12);
|
||||||
|
@ -930,13 +934,6 @@ static int ac108_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* revert LRCK polarity if it's single chip (master mode) */
|
|
||||||
if (ac10x->tdm_chips_cnt < 2) {
|
|
||||||
lrck_polarity = (lrck_polarity == LRCK_LEFT_HIGH_RIGHT_LOW)?
|
|
||||||
LRCK_LEFT_LOW_RIGHT_HIGH: LRCK_LEFT_HIGH_RIGHT_LOW;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
ac108_configure_power(ac10x);
|
ac108_configure_power(ac10x);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -987,14 +984,16 @@ static int ac108_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) {
|
||||||
* due to miss channels order in cpu_dai, we meed defer the clock starting.
|
* due to miss channels order in cpu_dai, we meed defer the clock starting.
|
||||||
*/
|
*/
|
||||||
static int ac108_set_clock(int y_start_n_stop) {
|
static int ac108_set_clock(int y_start_n_stop) {
|
||||||
|
unsigned long flags;
|
||||||
u8 r;
|
u8 r;
|
||||||
|
|
||||||
dev_dbg(ac10x->codec->dev, "%s() L%d start:%d\n", __func__, __LINE__, y_start_n_stop);
|
dev_dbg(ac10x->codec->dev, "%s() L%d start:%d\n", __func__, __LINE__, y_start_n_stop);
|
||||||
|
|
||||||
|
spin_lock_irqsave(&ac10x->lock, flags);
|
||||||
if (y_start_n_stop) {
|
if (y_start_n_stop) {
|
||||||
/* enable lrck clock */
|
/* enable lrck clock */
|
||||||
ac10x_read(I2S_CTRL, &r, ac10x->i2cmap[_MASTER_INDEX]);
|
ac10x_read(I2S_CTRL, &r, ac10x->i2cmap[_MASTER_INDEX]);
|
||||||
if (r & (0x02 << LRCK_IOEN)) {
|
if (r & (0x01 << BCLK_IOEN)) {
|
||||||
ac10x_update_bits(I2S_CTRL, 0x03 << LRCK_IOEN, 0x03 << LRCK_IOEN, ac10x->i2cmap[_MASTER_INDEX]);
|
ac10x_update_bits(I2S_CTRL, 0x03 << LRCK_IOEN, 0x03 << LRCK_IOEN, ac10x->i2cmap[_MASTER_INDEX]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1005,10 +1004,11 @@ static int ac108_set_clock(int y_start_n_stop) {
|
||||||
ac10x_read(I2S_CTRL, &r, ac10x->i2cmap[_MASTER_INDEX]);
|
ac10x_read(I2S_CTRL, &r, ac10x->i2cmap[_MASTER_INDEX]);
|
||||||
if (r & (0x01 << LRCK_IOEN)) {
|
if (r & (0x01 << LRCK_IOEN)) {
|
||||||
ac108_multi_update_bits(I2S_CTRL, 0x1 << TXEN | 0x1 << GEN, 0x1 << TXEN | 0x0 << GEN, ac10x);
|
ac108_multi_update_bits(I2S_CTRL, 0x1 << TXEN | 0x1 << GEN, 0x1 << TXEN | 0x0 << GEN, ac10x);
|
||||||
ac10x_update_bits(I2S_CTRL, 0x03 << LRCK_IOEN, 0x02 << LRCK_IOEN, ac10x->i2cmap[_MASTER_INDEX]);
|
ac10x_update_bits(I2S_CTRL, 0x03 << LRCK_IOEN, 0x01 << BCLK_IOEN, ac10x->i2cmap[_MASTER_INDEX]);
|
||||||
ac108_multi_update_bits(I2S_CTRL, 0x1 << TXEN | 0x1 << GEN, 0x1 << TXEN | 0x1 << GEN, ac10x);
|
ac108_multi_update_bits(I2S_CTRL, 0x1 << TXEN | 0x1 << GEN, 0x1 << TXEN | 0x1 << GEN, ac10x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
spin_unlock_irqrestore(&ac10x->lock, flags);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1028,6 +1028,7 @@ static int ac108_trigger(struct snd_pcm_substream *substream, int cmd,
|
||||||
{
|
{
|
||||||
struct snd_soc_codec *codec = dai->codec;
|
struct snd_soc_codec *codec = dai->codec;
|
||||||
struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
|
struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
|
||||||
|
unsigned long flags;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
u8 r;
|
u8 r;
|
||||||
|
|
||||||
|
@ -1036,10 +1037,12 @@ static int ac108_trigger(struct snd_pcm_substream *substream, int cmd,
|
||||||
snd_pcm_stream_str(substream),
|
snd_pcm_stream_str(substream),
|
||||||
cmd);
|
cmd);
|
||||||
|
|
||||||
|
spin_lock_irqsave(&ac10x->lock, flags);
|
||||||
|
|
||||||
if (ac10x->i2c101 && _MASTER_MULTI_CODEC == _MASTER_AC101) {
|
if (ac10x->i2c101 && _MASTER_MULTI_CODEC == _MASTER_AC101) {
|
||||||
ac101_trigger(substream, cmd, dai);
|
ac101_trigger(substream, cmd, dai);
|
||||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||||
return 0;
|
goto __ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1049,27 +1052,39 @@ static int ac108_trigger(struct snd_pcm_substream *substream, int cmd,
|
||||||
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
|
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
|
||||||
/* disable global clock if lrck disabled */
|
/* disable global clock if lrck disabled */
|
||||||
ac10x_read(I2S_CTRL, &r, ac10x->i2cmap[_MASTER_INDEX]);
|
ac10x_read(I2S_CTRL, &r, ac10x->i2cmap[_MASTER_INDEX]);
|
||||||
if ((r & (0x02 << LRCK_IOEN)) && (r & (0x01 << LRCK_IOEN)) == 0) {
|
if ((r & (0x01 << BCLK_IOEN)) && (r & (0x01 << LRCK_IOEN)) == 0) {
|
||||||
/* disable global clock */
|
/* disable global clock */
|
||||||
ac108_multi_update_bits(I2S_CTRL, 0x1 << TXEN | 0x1 << GEN, 0x1 << TXEN | 0x0 << GEN, ac10x);
|
ac108_multi_update_bits(I2S_CTRL, 0x1 << TXEN | 0x1 << GEN, 0x1 << TXEN | 0x0 << GEN, ac10x);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*0x21: Module clock enable<I2S, ADC digital, MIC offset Calibration, ADC analog>*/
|
/*0x10: PLL Common voltage enable, PLL enable */
|
||||||
ac108_multi_write(MOD_CLK_EN, 1 << I2S | 1 << ADC_DIGITAL | 1 << MIC_OFFSET_CALIBRATION | 1 << ADC_ANALOG, ac10x);
|
ac108_multi_update_bits(PLL_CTRL1, 0x01 << PLL_EN | 0x01 << PLL_COM_EN,
|
||||||
|
0x01 << PLL_EN | 0x01 << PLL_COM_EN, ac10x);
|
||||||
/*0x22: Module reset de-asserted<I2S, ADC digital, MIC offset Calibration, ADC analog>*/
|
|
||||||
ac108_multi_write(MOD_RST_CTRL, 1 << I2S | 1 << ADC_DIGITAL | 1 << MIC_OFFSET_CALIBRATION | 1 << ADC_ANALOG, ac10x);
|
|
||||||
|
|
||||||
|
if (ac10x->i2c101 && _MASTER_MULTI_CODEC == _MASTER_AC101) {
|
||||||
|
/* enable global clock */
|
||||||
|
ac108_multi_update_bits(I2S_CTRL, 0x1 << TXEN | 0x1 << GEN, 0x1 << TXEN | 0x1 << GEN, ac10x);
|
||||||
|
}
|
||||||
/* delayed clock starting, move to simple_card_trigger() */
|
/* delayed clock starting, move to simple_card_trigger() */
|
||||||
break;
|
break;
|
||||||
case SNDRV_PCM_TRIGGER_STOP:
|
case SNDRV_PCM_TRIGGER_STOP:
|
||||||
case SNDRV_PCM_TRIGGER_SUSPEND:
|
case SNDRV_PCM_TRIGGER_SUSPEND:
|
||||||
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
|
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
|
||||||
|
/*0x10: PLL Common voltage disable, PLL disable */
|
||||||
|
ac108_multi_update_bits(PLL_CTRL1, 0x01 << PLL_EN | 0x01 << PLL_COM_EN,
|
||||||
|
0x00 << PLL_EN | 0x00 << PLL_COM_EN, ac10x);
|
||||||
|
if (ac10x->i2c101 && _MASTER_MULTI_CODEC == _MASTER_AC101) {
|
||||||
|
/* disable global clock */
|
||||||
|
ac108_multi_update_bits(I2S_CTRL, 0x1 << TXEN | 0x1 << GEN, 0x0 << TXEN | 0x0 << GEN, ac10x);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__ret:
|
||||||
|
spin_unlock_irqrestore(&ac10x->lock, flags);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1378,6 +1393,9 @@ static int ac108_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *i
|
||||||
ac10x->i2c101 = i2c;
|
ac10x->i2c101 = i2c;
|
||||||
i2c_set_clientdata(i2c, ac10x);
|
i2c_set_clientdata(i2c, ac10x);
|
||||||
ret = ac101_probe(i2c, i2c_id);
|
ret = ac101_probe(i2c, i2c_id);
|
||||||
|
if (ret) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
goto __ret;
|
goto __ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
* published by the Free Software Foundation.
|
* published by the Free Software Foundation.
|
||||||
*/
|
*/
|
||||||
#undef DEBUG
|
/* #undef DEBUG */
|
||||||
#include <linux/clk.h>
|
#include <linux/clk.h>
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
#include <linux/gpio.h>
|
#include <linux/gpio.h>
|
||||||
|
@ -240,7 +240,7 @@ static int asoc_simple_card_trigger(struct snd_pcm_substream *substream, int cmd
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct snd_soc_ops asoc_simple_card_ops = {
|
static struct snd_soc_ops asoc_simple_card_ops = {
|
||||||
|
|
Loading…
Reference in a new issue