Esempio n. 1
0
/* If the i2c layer weren't so broken, we could pass this kind of data
   around */
static int ak4671_codec_probe(struct i2c_adapter *adap, int addr, int kind)
{
	struct snd_soc_device *socdev = ak4671_socdev;
	struct ak4671_setup_data *setup = socdev->codec_data;
	struct snd_soc_codec *codec = socdev->codec;
	struct i2c_client *i2c;
	int ret;

	if (addr != setup->i2c_address)
		return -ENODEV;
	ak4671_client.adapter = adap;
	ak4671_client.addr = addr;

	i2c = kmemdup(&ak4671_client, sizeof(ak4671_client), GFP_KERNEL);
	if (i2c == NULL)
		return -ENOMEM;

	i2c_set_clientdata(i2c, codec);
	codec->control_data = i2c;

	ret = i2c_attach_client(i2c);
	if (ret < 0) {
		printk(KERN_ERR "failed to attach codec at addr %x\n", addr);
		goto err;
	}

	ret = ak4671_init(socdev);
	if (ret < 0) {
		printk(KERN_ERR "failed to initialise AK4671\n");
		goto err;
	}

	set_registers(codec, MM_AUDIO_PLAYBACK_SPK);

#if 0 // i2c test
	p("---> 0x01 = 0x%02x\n", ak4671_read(codec, 0x01)); 	
	ak4671_write(codec, 0x01, 0x78); 	
	P("---> 0x01 = 0x%02x\n", ak4671_read(codec, 0x01)); 	

	P("---> 0x02 = 0x%02x\n", ak4671_read(codec, 0x02)); 	
	ak4671_write(codec, 0x02, 0x01); 
	P("---> 0x02 = 0x%02x\n", ak4671_read(codec, 0x02)); 	

	P("---> 0x03 = 0x%02x\n", ak4671_read(codec, 0x03)); 	
	ak4671_write(codec, 0x03, 0x03);
	P("---> 0x03 = 0x%02x\n", ak4671_read(codec, 0x03)); 	
#endif

	return ret;

err:
	kfree(i2c);
	return ret;
}
Esempio n. 2
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;
}
Esempio n. 3
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;
}
Esempio n. 4
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;
}
Esempio n. 5
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;
}
Esempio n. 6
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;
}
Esempio n. 7
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;
}
Esempio n. 8
0
static int ak4671_set_dai_fmt(struct snd_soc_dai *codec_dai,
		unsigned int fmt)
{
	struct snd_soc_codec *codec = codec_dai->codec;
	u8 mode1 = 0;

	/* interface format */
	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
	case SND_SOC_DAIFMT_I2S:
		mode1 = 0x03;
		break;
	default:
		printk("!! invalid interface format !!\n");
		return -EINVAL;
	}

	ak4671_write(codec, AK4671_FORMAT, mode1);

	return 0;
}
Esempio n. 9
0
static ssize_t ak4671_control_store(
		struct device *dev, struct device_attribute *attr,
		const char *buf, size_t size)
{
	u8 reg, value = 0;
	int ret = 0;
	struct snd_soc_device *socdev = dev_get_drvdata(dev);
	struct snd_soc_codec *codec = socdev->codec;

	printk("echo [REGISTER NUMBER(HEX)][VALUE(HEX)] > ak4671_control\n");
	printk("ex) echo 030f > ak4671_control\n");

	P("buf = %s", buf);
	P("buf size = %d", sizeof(buf));
	P("buf size = %d", strlen(buf));

	if(sizeof(buf) != 4) {
		printk("input error\n");
		printk("store ex) echo 030f\n");
		return -1;
	}

	ret = hex2dec(buf[0]);
	if (ret == -1) {
		printk("store error.\n");
		return -1;
	}
	reg = ret << 4;

	ret = hex2dec(buf[1]);
	if (ret == -1) {
		printk("store error.\n");
		return -1;
	}
	reg |= (ret & 0xf);

	ret = hex2dec(buf[2]);
	if (ret == -1) {
		printk("store error.\n");
		return -1;
	}
	value = ret << 4;

	ret = hex2dec(buf[3]);
	if (ret == -1) {
		printk("store error.\n");
		return -1;
	}
	value |= (ret & 0xf);

	if (reg == 0xf1) { // path control
		set_registers(codec, value);
	} else if (reg >= 0xe0 && reg <= 0xe5)
		amp_set_register(reg - 0xe0, value);
	else
		ak4671_write(codec, reg, value);
	printk("Set  : reg = 0x%02x, value = 0x%02x\n", reg, value);
	printk("Read : reg = 0x%02x, value = 0x%02x\n", reg, ak4671_read(codec, reg));

	return size;
}