예제 #1
0
static int ak4671_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
{
	struct snd_soc_codec *codec = dai->codec;
	u8 mode;
	u8 format;

	/* set master/slave audio interface */
	mode = ak4671_read_reg_cache(codec, AK4671_PLL_MODE_SELECT1);

	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
	case SND_SOC_DAIFMT_CBM_CFM:
		mode |= AK4671_PMPLL;
		mode |= AK4671_M_S;
		break;
	case SND_SOC_DAIFMT_CBM_CFS:
		mode |= AK4671_PMPLL;
		mode &= ~(AK4671_M_S);
		break;
	default:
		return -EINVAL;
	}

	/* interface format */
	format = ak4671_read_reg_cache(codec, AK4671_FORMAT_SELECT);
	format &= ~AK4671_DIF;

	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
	case SND_SOC_DAIFMT_I2S:
		format |= AK4671_DIF_I2S_MODE;
		break;
	case SND_SOC_DAIFMT_LEFT_J:
		format |= AK4671_DIF_MSB_MODE;
		break;
	case SND_SOC_DAIFMT_DSP_A:
		format |= AK4671_DIF_DSP_MODE;
		format |= AK4671_BCKP;
		format |= AK4671_MSBS;
		break;
	default:
		return -EINVAL;
	}

	/* set mode and format */
	ak4671_write(codec, AK4671_PLL_MODE_SELECT1, mode);
	ak4671_write(codec, AK4671_FORMAT_SELECT, format);

	return 0;
}
예제 #2
0
static int ak4671_hw_params(struct snd_pcm_substream *substream,
			    struct snd_pcm_hw_params *params,
			    struct snd_soc_dai *dai)
{
#if 0
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_device *socdev = rtd->socdev;
	struct snd_soc_codec *codec = socdev->codec;
	struct ak4671_priv *ak4671 = codec->private_data;
	u8 mode2 = ak4671_read_reg_cache(codec, AK4671_MODE2) & ~(0x3 << 5);
	int rate = params_rate(params), fs = 256;

	if (rate)
		fs = ak4671->sysclk / rate;

	/* set fs */
	switch (fs) {
	case 1024:
		mode2 |= (0x2 << 5);
		break;
	case 512:
		mode2 |= (0x1 << 5);
		break;
	case 256:
		break;
	}

	/* set rate */
	ak4671_write(codec, ak4671_mode2, mode2);
#endif
	return 0;
}
예제 #3
0
static int ak4671_mute(struct snd_soc_dai *dai, int mute)
{
#if 0
	P("mute %d", mute);
	struct snd_soc_codec *codec = dai->codec;

	u16 mute_reg = ak4671_read_reg_cache(codec, AK4671_MODE_CONTROL2) & 0xfffb;
	if (!mute)
		ak4671_write(codec, AK4671_MODE_CONTROL2, mute_reg | 1);
	else
		ak4671_write(codec, AK4671_MODE_CONTROL2, mute_reg | 0x4 | 1);
#else
	P("mute is not supported (%d)", mute);
#endif

	return 0;
}
예제 #4
0
static int ak4671_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;
	u8 fs;

	fs = ak4671_read_reg_cache(codec, AK4671_PLL_MODE_SELECT0);
	fs &= ~AK4671_FS;

	switch (params_rate(params)) {
	case 8000:
		fs |= AK4671_FS_8KHZ;
		break;
	case 12000:
		fs |= AK4671_FS_12KHZ;
		break;
	case 16000:
		fs |= AK4671_FS_16KHZ;
		break;
	case 24000:
		fs |= AK4671_FS_24KHZ;
		break;
	case 11025:
		fs |= AK4671_FS_11_025KHZ;
		break;
	case 22050:
		fs |= AK4671_FS_22_05KHZ;
		break;
	case 32000:
		fs |= AK4671_FS_32KHZ;
		break;
	case 44100:
		fs |= AK4671_FS_44_1KHZ;
		break;
	case 48000:
		fs |= AK4671_FS_48KHZ;
		break;
	default:
		return -EINVAL;
	}

	ak4671_write(codec, AK4671_PLL_MODE_SELECT0, fs);

	return 0;
}
예제 #5
0
static int ak4671_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
		unsigned int freq, int dir)
{
	struct snd_soc_codec *codec = dai->codec;
	u8 pll;

	pll = ak4671_read_reg_cache(codec, AK4671_PLL_MODE_SELECT0);
	pll &= ~AK4671_PLL;

	switch (freq) {
	case 11289600:
		pll |= AK4671_PLL_11_2896MHZ;
		break;
	case 12000000:
		pll |= AK4671_PLL_12MHZ;
		break;
	case 12288000:
		pll |= AK4671_PLL_12_288MHZ;
		break;
	case 13000000:
		pll |= AK4671_PLL_13MHZ;
		break;
	case 13500000:
		pll |= AK4671_PLL_13_5MHZ;
		break;
	case 19200000:
		pll |= AK4671_PLL_19_2MHZ;
		break;
	case 24000000:
		pll |= AK4671_PLL_24MHZ;
		break;
	case 26000000:
		pll |= AK4671_PLL_26MHZ;
		break;
	case 27000000:
		pll |= AK4671_PLL_27MHZ;
		break;
	default:
		return -EINVAL;
	}

	ak4671_write(codec, AK4671_PLL_MODE_SELECT0, pll);

	return 0;
}
예제 #6
0
static int ak4671_set_bias_level(struct snd_soc_codec *codec,
		enum snd_soc_bias_level level)
{
	u8 reg;

	switch (level) {
	case SND_SOC_BIAS_ON:
		break;
	case SND_SOC_BIAS_PREPARE:
		break;
	case SND_SOC_BIAS_STANDBY:
		reg = ak4671_read_reg_cache(codec,
				AK4671_AD_DA_POWER_MANAGEMENT);
		ak4671_write(codec, AK4671_AD_DA_POWER_MANAGEMENT,
				reg | AK4671_PMVCM);
		break;
	case SND_SOC_BIAS_OFF:
		ak4671_write(codec, AK4671_AD_DA_POWER_MANAGEMENT, 0x00);
		break;
	}
	codec->bias_level = level;
	return 0;
}