예제 #1
0
static int ak4671_probe(struct platform_device *pdev)
{
	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
	struct snd_soc_codec *codec;
	int ret = 0;

	if (ak4671_codec == NULL) {
		dev_err(&pdev->dev, "Codec device not registered\n");
		return -ENODEV;
	}

	socdev->card->codec = ak4671_codec;
	codec = ak4671_codec;

	/* register pcms */
	ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
	if (ret < 0) {
		dev_err(codec->dev, "failed to create pcms: %d\n", ret);
		goto pcm_err;
	}

	snd_soc_add_controls(codec, ak4671_snd_controls,
			     ARRAY_SIZE(ak4671_snd_controls));
	ak4671_add_widgets(codec);

	ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY);

	return ret;

pcm_err:
	return ret;
}
예제 #2
0
static int ak4671_probe(struct snd_soc_codec *codec)
{
	struct ak4671_priv *ak4671 = snd_soc_codec_get_drvdata(codec);
	struct ak4671_platform_data *pdata = codec->dev->platform_data;
	int ret;

	if (pdata) {
		if (gpio_is_valid(pdata->gpio_npdn)) {
			ret = gpio_request_one(pdata->gpio_npdn,
					GPIOF_OUT_INIT_LOW, "ak4671 npdn");
			if (ret)
				return ret;

			udelay(1); /* > 150 ns */
			gpio_set_value(pdata->gpio_npdn, 1);
		}
	}

	ret = snd_soc_codec_set_cache_io(codec, 8, 8, ak4671->control_type);
	if (ret < 0) {
		dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
		gpio_set_value(pdata->gpio_npdn, 0);
		return ret;
	}

	ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY);

	return 0;
}
예제 #3
0
static void ak4671_unregister(struct ak4671_priv *ak4671)
{
	ak4671_set_bias_level(&ak4671->codec, SND_SOC_BIAS_OFF);
	snd_soc_unregister_dai(&ak4671_dai);
	snd_soc_unregister_codec(&ak4671->codec);
	kfree(ak4671);
	ak4671_codec = NULL;
}
예제 #4
0
static int ak4671_resume(struct platform_device *pdev)
{
	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
	struct snd_soc_codec *codec = socdev->codec;
	P("");

	if ( (ak4671_path & 0xf0) != MM_AUDIO_VOICECALL && (ak4671_path & 0xf0) != MM_AUDIO_VOICEMEMO ) 
	{
		ak4671_sync(codec);
		ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
		ak4671_set_bias_level(codec, codec->suspend_bias_level);
	}

	mic_enable(1); /* MICBIAS Enable (SPH-M900 Only) */

	return 0;
}
예제 #5
0
/*
 * initialise the AK4671 driver
 * register the mixer and dsp interfaces with the kernel
 */
static int ak4671_init(struct snd_soc_device *socdev)
{
	struct snd_soc_codec *codec = socdev->codec;
	int ret = 0;

	memcpy(ak4671_reg_default, ak4671_reg, sizeof(ak4671_reg)); // copy ak4671 default register

	codec->dev = socdev->dev;
	codec->name = "AK4671";
	codec->owner = THIS_MODULE;
	codec->read = ak4671_read_reg_cache;
	codec->write = ak4671_write;
	codec->set_bias_level = ak4671_set_bias_level;
	codec->dai = &ak4671_dai;
	codec->num_dai = 1;
	codec->reg_cache_size = ARRAY_SIZE(ak4671_reg);
	codec->reg_cache = kmemdup(ak4671_reg, sizeof(ak4671_reg), GFP_KERNEL);

	if (codec->reg_cache == NULL)
		return -ENOMEM;

	/* register pcms */
	ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
	if (ret < 0) {
		printk(KERN_ERR "ak4671: failed to create pcms\n");
		goto pcm_err;
	}

	/* power on device */
	ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY);

	ak4671_add_controls(codec);
	ret = snd_soc_init_card(socdev);
	if (ret < 0) {
		printk(KERN_ERR "ak4671: failed to register card\n");
		goto card_err;
	}

	return ret;

card_err:
	snd_soc_free_pcms(socdev);
	snd_soc_dapm_free(socdev);
pcm_err:
	kfree(codec->reg_cache);

	return ret;
}
예제 #6
0
/* power down chip */
static int ak4671_remove(struct platform_device *pdev)
{
	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
	struct snd_soc_codec *codec = socdev->codec;

	if (codec->control_data)
		ak4671_set_bias_level(codec, SND_SOC_BIAS_OFF);

	snd_soc_free_pcms(socdev);
	snd_soc_dapm_free(socdev);
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
	i2c_del_driver(&ak4671_i2c_driver);
#endif
	kfree(codec->private_data);
	kfree(codec);

	return 0;
}
예제 #7
0
static int ak4671_probe(struct snd_soc_codec *codec)
{
	struct ak4671_priv *ak4671 = snd_soc_codec_get_drvdata(codec);
	int ret;

	codec->hw_write = (hw_write_t)i2c_master_send;

	ret = snd_soc_codec_set_cache_io(codec, 8, 8, ak4671->control_type);
	if (ret < 0) {
		dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
		return ret;
	}

	snd_soc_add_controls(codec, ak4671_snd_controls,
			     ARRAY_SIZE(ak4671_snd_controls));

	ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY);

	return ret;
}
예제 #8
0
static int ak4671_suspend(struct platform_device *pdev, pm_message_t state)
{
	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
	struct snd_soc_codec *codec = socdev->codec;
	P("");

	ak4671_set_bias_level(codec, SND_SOC_BIAS_OFF);

	if ( (ak4671_path & 0xf0) != MM_AUDIO_VOICECALL && (ak4671_path & 0xf0) != MM_AUDIO_VOICEMEMO ) 
	{
		path_disable(codec, ak4671_path);

		/* AUDIO_EN & MAX8906_AMP_EN Disable */
		amp_enable(0); /* Board Specific function */
		audio_power(0); /* Board Specific function */
		mic_enable(0); /* MICBIAS Disable (SPH-M900 Only) */
		ak4671_power = 0;
		ak4671_idle_mode = IDLE_POWER_DOWN_MODE_ON;
	}

	return 0;
}
예제 #9
0
static int ak4671_remove(struct snd_soc_codec *codec)
{
	ak4671_set_bias_level(codec, SND_SOC_BIAS_OFF);
	return 0;
}
예제 #10
0
static int ak4671_resume(struct snd_soc_codec *codec)
{
	ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
	return 0;
}
예제 #11
0
static int ak4671_suspend(struct snd_soc_codec *codec, pm_message_t state)
{
	ak4671_set_bias_level(codec, SND_SOC_BIAS_OFF);
	return 0;
}