Esempio n. 1
0
static void amp_path_control(int mode)
{
	int amp_path;
	/* SPK <- HP */
	if((mode & 0xf) == MM_AUDIO_OUT_SPK)
	{
		amp_path = AK4671_AMP_PATH_SPK;
	}

	/* SPK -> HP */
	if((mode & 0xf) == MM_AUDIO_OUT_HP)
	{ 
		amp_path = AK4671_AMP_PATH_HP;
	}

	/* SPK & HP */
	if(((mode & 0xf) == MM_AUDIO_OUT_SPK_HP) || ((mode & 0xf) == MM_AUDIO_OUT_RING_SPK_HP))
	{ 
		amp_path = AK4671_AMP_PATH_SPK_HP;
	}

	if((mode & 0xf0) == MM_AUDIO_VOICEMEMO)
	{
		if((mode & 0xf) == MM_AUDIO_OUT_HP)
			amp_path = AK4671_AMP_PATH_HP;
		else
			amp_path = AK4671_AMP_PATH_SPK;
	}

	if (ak4671_amp_path != amp_path && ak4671_path != mode) 
	{
		amp_set_path(amp_path);
		ak4671_amp_path = amp_path;
	} 
}
Esempio n. 2
0
static int ak4671_probe(struct platform_device *pdev)
{
	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
	struct ak4671_setup_data *setup;
	struct snd_soc_codec *codec;
	struct ak4671_priv *ak4671;
	int ret = 0;

	printk(KERN_INFO "AK4671 Audio Codec %s", AK4671_VERSION);

	/* Board Specific function */
	audio_init();
	if (amp_init() < 0)
		printk("amp init failed.\n");
	audio_power(1);
	ak4671_power = 1;
	amp_set_path(AK4671_AMP_PATH_SPK);
	mic_set_path(AK4671_MIC_PATH_MAIN);

	ret = device_create_file(&pdev->dev, &dev_attr_ak4671_control);

	setup = socdev->codec_data;
	codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
	if (codec == NULL)
		return -ENOMEM;

	ak4671 = kzalloc(sizeof(struct ak4671_priv), GFP_KERNEL);
	if (ak4671 == NULL) {
		kfree(codec);
		return -ENOMEM;
	}

	codec->private_data = ak4671;
	socdev->codec = codec;
	mutex_init(&codec->mutex);
	INIT_LIST_HEAD(&codec->dapm_widgets);
	INIT_LIST_HEAD(&codec->dapm_paths);

	ak4671_socdev = socdev;

#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
	if (setup->i2c_address) {
		normal_i2c[0] = setup->i2c_address;
		codec->hw_write = (hw_write_t)i2c_master_send;
		codec->hw_read = (hw_read_t)i2c_master_recv;
		ret = i2c_add_driver(&ak4671_i2c_driver);
		if (ret != 0)
			printk(KERN_ERR "can't add i2c driver");
	}
#else
	/* Add other interfaces here */
#endif

	if (ret != 0) {
		kfree(codec->private_data);
		kfree(codec);
	}
	return ret;
}
Esempio n. 3
0
int path_change(struct snd_soc_codec *codec, int to_mode, int from_mode)
{
	int ret = 1;

	/* Set Bias */
	set_bias(codec, to_mode);

	switch (to_mode) {
		case MM_AUDIO_PLAYBACK_SPK :
		case MM_AUDIO_PLAYBACK_HP :
			switch (from_mode) {
				case MM_AUDIO_VOICEMEMO_MAIN :
				case MM_AUDIO_VOICEMEMO_SUB :
				case MM_AUDIO_VOICEMEMO_EAR :
					P("VOICEMEMO->PLAYBACK");
					set_codec_gain(codec, to_mode);
					if (to_mode == MM_AUDIO_PLAYBACK_SPK) 
						amp_set_path(AK4671_AMP_PATH_SPK);
					else
						amp_set_path(AK4671_AMP_PATH_HP);
				
					codec->write(codec, 0x00, 0xC1);        // DAC Enable, ADC Disable, MicAMP Disable
					break;
				default :
					ret = -1;
					break;
			}
			break;

		case MM_AUDIO_PLAYBACK_RCV :
		case MM_AUDIO_PLAYBACK_SPK_HP :
		case MM_AUDIO_PLAYBACK_RING_SPK_HP :
		case MM_AUDIO_PLAYBACK_BT :
		case MM_AUDIO_VOICECALL_RCV :
		case MM_AUDIO_VOICECALL_SPK :
		case MM_AUDIO_VOICECALL_HP :
		case MM_AUDIO_VOICECALL_BT :
			ret = -1;
			break;
		case MM_AUDIO_VOICEMEMO_MAIN :
			switch (from_mode) {
				case MM_AUDIO_PLAYBACK_SPK :
					P("PLAYBACK_SPK->VOICEMEMO_MAIN");
					mic_set_path(AK4671_MIC_PATH_MAIN);
					set_codec_gain(codec, to_mode);
					codec->write(codec, 0x04, 0x14); 		// => MIC-AMP Lch=IN1+/-
					codec->write(codec, 0x00, 0xD5); 		// D/A power-up
					break;
				case MM_AUDIO_VOICEMEMO_EAR :
					P("VOICEMEMO_EAR->VOICEMEMO_MAIN");
					mic_set_path(AK4671_MIC_PATH_MAIN);
					set_codec_gain(codec, to_mode);
					codec->write(codec, 0x04, 0x14); 		// => MIC-AMP Lch=IN1+/-
					amp_set_path(AK4671_AMP_PATH_SPK);
					break;

				default :
					ret = -1;
					break;
			}
			break;

		case MM_AUDIO_VOICEMEMO_SUB :
			switch (from_mode) {
				case MM_AUDIO_PLAYBACK_SPK :
					P("PLAYBACK_SPK->VOICEMEMO_SUB");
					mic_set_path(AK4671_MIC_PATH_MAIN);
					set_codec_gain(codec, to_mode);
					codec->write(codec, 0x04, 0x14); 		// => MIC-AMP Lch=IN1+/-
					codec->write(codec, 0x00, 0xD5); 		// D/A power-up
					break;
				case MM_AUDIO_VOICEMEMO_EAR :
				     	P("VOICEMEMO_EAR->VOICEMEMO_MAIN");
					mic_set_path(AK4671_MIC_PATH_MAIN);
					set_codec_gain(codec, to_mode);
					codec->write(codec, 0x04, 0x14); 		// => MIC-AMP Lch=IN1+/-
					amp_set_path(AK4671_AMP_PATH_SPK);
					break;

				default :
					ret = -1;
					break;
			}
			break;

		case MM_AUDIO_VOICEMEMO_EAR :
			switch (from_mode) {
				case MM_AUDIO_PLAYBACK_HP :
				case MM_AUDIO_VOICEMEMO_MAIN :
				case MM_AUDIO_VOICEMEMO_SUB :
					P("VOICEMEMO_MAIN&SUB&PLAYBACK_HP->VOICEMEMO_EAR");
					if (from_mode != MM_AUDIO_PLAYBACK_HP)
						amp_set_path(AK4671_AMP_PATH_HP);
					if (get_headset_status()) 
					{
				     		P("VOICEMEMO_4POLE_EAR");
						set_codec_gain(codec, to_mode);
						codec->write(codec, 0x04, 0x42); 		// => MIC-AMP Lch=IN3+/-
						codec->write(codec, 0x00, 0xD5); 		// D/A power-up
					}
			        	else
			        	{
						P("VOICEMEMO_3POLE_EAR");
						mic_set_path(AK4671_MIC_PATH_MAIN);
						to_mode = MM_AUDIO_VOICEMEMO_MAIN;
				    		set_codec_gain(codec, to_mode);
				    		codec->write(codec, 0x04, 0x14); 		// => MIC-AMP Lch=IN1+/-
				    		codec->write(codec, 0x00, 0xD5); 		// D/A power-up	
			        	}
					break;

				default :
					ret = -1;
					break;
			}
			break;

		default :
			ret = -1;
			break;
	}

	return ret;
}