• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

C++ snd_soc_read函数代码示例

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

本文整理汇总了C++中snd_soc_read函数的典型用法代码示例。如果您正苦于以下问题:C++ snd_soc_read函数的具体用法?C++ snd_soc_read怎么用?C++ snd_soc_read使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。



在下文中一共展示了snd_soc_read函数的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C++代码示例。

示例1: cs4270_hw_params

/*
 * Program the CS4270 with the given hardware parameters.
 *
 * The .dai_ops functions are used to provide board-specific data, like
 * input frequencies, to this driver.  This function takes that information,
 * combines it with the hardware parameters provided, and programs the
 * hardware accordingly.
 */
static int cs4270_hw_params(struct snd_pcm_substream *substream,
			    struct snd_pcm_hw_params *params)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_device *socdev = rtd->socdev;
	struct snd_soc_codec *codec = socdev->codec;
	struct cs4270_private *cs4270 = codec->private_data;
	unsigned int ret = 0;
	unsigned int i;
	unsigned int rate;
	unsigned int ratio;
	int reg;

	/* Figure out which MCLK/LRCK ratio to use */

	rate = params_rate(params);	/* Sampling rate, in Hz */
	ratio = cs4270->mclk / rate;	/* MCLK/LRCK ratio */

	for (i = 0; i < NUM_MCLK_RATIOS; i++) {
		if (mclk_ratios[i] == ratio)
			break;
	}

	if (i == NUM_MCLK_RATIOS) {
		/* We did not find a matching ratio */
		printk(KERN_ERR "cs4270: could not find matching ratio\n");
		return -EINVAL;
	}

	/* Freeze and power-down the codec */

	ret = snd_soc_write(codec, CS4270_PWRCTL, CS4270_PWRCTL_FREEZE |
			    CS4270_PWRCTL_PDN_ADC | CS4270_PWRCTL_PDN_DAC |
			    CS4270_PWRCTL_PDN);
	if (ret < 0) {
		printk(KERN_ERR "cs4270: I2C write failed\n");
		return ret;
	}

	/* Program the mode control register */

	reg = snd_soc_read(codec, CS4270_MODE);
	reg &= ~(CS4270_MODE_SPEED_MASK | CS4270_MODE_DIV_MASK);
	reg |= cs4270_mode_ratios[i].speed_mode | cs4270_mode_ratios[i].mclk;

	ret = snd_soc_write(codec, CS4270_MODE, reg);
	if (ret < 0) {
		printk(KERN_ERR "cs4270: I2C write failed\n");
		return ret;
	}

	/* Program the format register */

	reg = snd_soc_read(codec, CS4270_FORMAT);
	reg &= ~(CS4270_FORMAT_DAC_MASK | CS4270_FORMAT_ADC_MASK);

	switch (cs4270->mode) {
	case SND_SOC_DAIFMT_I2S:
		reg |= CS4270_FORMAT_DAC_I2S | CS4270_FORMAT_ADC_I2S;
		break;
	case SND_SOC_DAIFMT_LEFT_J:
		reg |= CS4270_FORMAT_DAC_LJ | CS4270_FORMAT_ADC_LJ;
		break;
	default:
		printk(KERN_ERR "cs4270: unknown format\n");
		return -EINVAL;
	}

	ret = snd_soc_write(codec, CS4270_FORMAT, reg);
	if (ret < 0) {
		printk(KERN_ERR "cs4270: I2C write failed\n");
		return ret;
	}

	/* Disable auto-mute.  This feature appears to be buggy, because in
	   some situations, auto-mute will not deactivate when it should. */

	reg = snd_soc_read(codec, CS4270_MUTE);
	reg &= ~CS4270_MUTE_AUTO;
	ret = snd_soc_write(codec, CS4270_MUTE, reg);
	if (ret < 0) {
		printk(KERN_ERR "cs4270: I2C write failed\n");
		return ret;
	}

	/* Thaw and power-up the codec */

	ret = snd_soc_write(codec, CS4270_PWRCTL, 0);
	if (ret < 0) {
		printk(KERN_ERR "cs4270: I2C write failed\n");
		return ret;
	}
//.........这里部分代码省略.........
开发者ID:acassis,项目名称:emlinux-ssd1935,代码行数:101,代码来源:cs4270.c


示例2: wm8961_hw_params

static int wm8961_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;
	struct wm8961_priv *wm8961 = snd_soc_codec_get_drvdata(codec);
	int i, best, target, fs;
	u16 reg;

	fs = params_rate(params);

	if (!wm8961->sysclk) {
		dev_err(codec->dev, "MCLK has not been specified\n");
		return -EINVAL;
	}

	
	best = 0;
	for (i = 0; i < ARRAY_SIZE(wm8961_srate); i++) {
		if (abs(wm8961_srate[i].rate - fs) <
		    abs(wm8961_srate[best].rate - fs))
			best = i;
	}
	reg = snd_soc_read(codec, WM8961_ADDITIONAL_CONTROL_3);
	reg &= ~WM8961_SAMPLE_RATE_MASK;
	reg |= wm8961_srate[best].val;
	snd_soc_write(codec, WM8961_ADDITIONAL_CONTROL_3, reg);
	dev_dbg(codec->dev, "Selected SRATE %dHz for %dHz\n",
		wm8961_srate[best].rate, fs);

	
	target = wm8961->sysclk / fs;

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && target < 64) {
		dev_err(codec->dev,
			"SYSCLK must be at least 64*fs for DAC\n");
		return -EINVAL;
	}
	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE && target < 256) {
		dev_err(codec->dev,
			"SYSCLK must be at least 256*fs for ADC\n");
		return -EINVAL;
	}

	for (i = 0; i < ARRAY_SIZE(wm8961_clk_sys_ratio); i++) {
		if (wm8961_clk_sys_ratio[i].ratio >= target)
			break;
	}
	if (i == ARRAY_SIZE(wm8961_clk_sys_ratio)) {
		dev_err(codec->dev, "Unable to generate CLK_SYS_RATE\n");
		return -EINVAL;
	}
	dev_dbg(codec->dev, "Selected CLK_SYS_RATE of %d for %d/%d=%d\n",
		wm8961_clk_sys_ratio[i].ratio, wm8961->sysclk, fs,
		wm8961->sysclk / fs);

	reg = snd_soc_read(codec, WM8961_CLOCKING_4);
	reg &= ~WM8961_CLK_SYS_RATE_MASK;
	reg |= wm8961_clk_sys_ratio[i].val << WM8961_CLK_SYS_RATE_SHIFT;
	snd_soc_write(codec, WM8961_CLOCKING_4, reg);

	reg = snd_soc_read(codec, WM8961_AUDIO_INTERFACE_0);
	reg &= ~WM8961_WL_MASK;
	switch (params_format(params)) {
	case SNDRV_PCM_FORMAT_S16_LE:
		break;
	case SNDRV_PCM_FORMAT_S20_3LE:
		reg |= 1 << WM8961_WL_SHIFT;
		break;
	case SNDRV_PCM_FORMAT_S24_LE:
		reg |= 2 << WM8961_WL_SHIFT;
		break;
	case SNDRV_PCM_FORMAT_S32_LE:
		reg |= 3 << WM8961_WL_SHIFT;
		break;
	default:
		return -EINVAL;
	}
	snd_soc_write(codec, WM8961_AUDIO_INTERFACE_0, reg);

	
	reg = snd_soc_read(codec, WM8961_ADC_DAC_CONTROL_2);
	if (fs <= 24000)
		reg |= WM8961_DACSLOPE;
	else
		reg &= ~WM8961_DACSLOPE;
	snd_soc_write(codec, WM8961_ADC_DAC_CONTROL_2, reg);

	return 0;
}
开发者ID:MiniBlu,项目名称:cm11_kernel_htc_msm8974a3ul,代码行数:90,代码来源:wm8961.c


示例3: wm9081_set_dai_fmt

static int wm9081_set_dai_fmt(struct snd_soc_dai *dai,
			      unsigned int fmt)
{
	struct snd_soc_codec *codec = dai->codec;
	struct wm9081_priv *wm9081 = codec->private_data;
	unsigned int aif2 = snd_soc_read(codec, WM9081_AUDIO_INTERFACE_2);

	aif2 &= ~(WM9081_AIF_BCLK_INV | WM9081_AIF_LRCLK_INV |
		  WM9081_BCLK_DIR | WM9081_LRCLK_DIR | WM9081_AIF_FMT_MASK);

	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
	case SND_SOC_DAIFMT_CBS_CFS:
		wm9081->master = 0;
		break;
	case SND_SOC_DAIFMT_CBS_CFM:
		aif2 |= WM9081_LRCLK_DIR;
		wm9081->master = 1;
		break;
	case SND_SOC_DAIFMT_CBM_CFS:
		aif2 |= WM9081_BCLK_DIR;
		wm9081->master = 1;
		break;
	case SND_SOC_DAIFMT_CBM_CFM:
		aif2 |= WM9081_LRCLK_DIR | WM9081_BCLK_DIR;
		wm9081->master = 1;
		break;
	default:
		return -EINVAL;
	}

	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
	case SND_SOC_DAIFMT_DSP_B:
		aif2 |= WM9081_AIF_LRCLK_INV;
	case SND_SOC_DAIFMT_DSP_A:
		aif2 |= 0x3;
		break;
	case SND_SOC_DAIFMT_I2S:
		aif2 |= 0x2;
		break;
	case SND_SOC_DAIFMT_RIGHT_J:
		break;
	case SND_SOC_DAIFMT_LEFT_J:
		aif2 |= 0x1;
		break;
	default:
		return -EINVAL;
	}

	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
	case SND_SOC_DAIFMT_DSP_A:
	case SND_SOC_DAIFMT_DSP_B:
		/* frame inversion not valid for DSP modes */
		switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
		case SND_SOC_DAIFMT_NB_NF:
			break;
		case SND_SOC_DAIFMT_IB_NF:
			aif2 |= WM9081_AIF_BCLK_INV;
			break;
		default:
			return -EINVAL;
		}
		break;

	case SND_SOC_DAIFMT_I2S:
	case SND_SOC_DAIFMT_RIGHT_J:
	case SND_SOC_DAIFMT_LEFT_J:
		switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
		case SND_SOC_DAIFMT_NB_NF:
			break;
		case SND_SOC_DAIFMT_IB_IF:
			aif2 |= WM9081_AIF_BCLK_INV | WM9081_AIF_LRCLK_INV;
			break;
		case SND_SOC_DAIFMT_IB_NF:
			aif2 |= WM9081_AIF_BCLK_INV;
			break;
		case SND_SOC_DAIFMT_NB_IF:
			aif2 |= WM9081_AIF_LRCLK_INV;
			break;
		default:
			return -EINVAL;
		}
		break;
	default:
		return -EINVAL;
	}

	snd_soc_write(codec, WM9081_AUDIO_INTERFACE_2, aif2);

	return 0;
}
开发者ID:A2109devs,项目名称:lenovo_a2109a_kernel,代码行数:90,代码来源:wm9081.c


示例4: sdp4430_twl6040_init

static int sdp4430_twl6040_init(struct snd_soc_pcm_runtime *rtd)
{
	struct snd_soc_codec *codec = rtd->codec;
	struct twl6040 *twl6040 = codec->control_data;
	struct snd_soc_dapm_context *dapm = &codec->dapm;
	int hsotrim, left_offset, right_offset, mode, ret;


	/* Add SDP4430 specific controls */
	ret = snd_soc_add_controls(codec, sdp4430_controls,
				ARRAY_SIZE(sdp4430_controls));
	if (ret)
		return ret;

	/* Add SDP4430 specific widgets */
	ret = snd_soc_dapm_new_controls(dapm, sdp4430_twl6040_dapm_widgets,
				ARRAY_SIZE(sdp4430_twl6040_dapm_widgets));
	if (ret)
		return ret;

	/* Set up SDP4430 specific audio path audio_map */
	snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));

	/* SDP4430 connected pins */
	snd_soc_dapm_enable_pin(dapm, "Ext Mic");
	snd_soc_dapm_enable_pin(dapm, "Ext Spk");
	snd_soc_dapm_enable_pin(dapm, "AFML");
	snd_soc_dapm_enable_pin(dapm, "AFMR");
	snd_soc_dapm_enable_pin(dapm, "Headset Mic");
	snd_soc_dapm_enable_pin(dapm, "Headset Stereophone");

	/* allow audio paths from the audio modem to run during suspend */
	snd_soc_dapm_ignore_suspend(dapm, "Ext Mic");
	snd_soc_dapm_ignore_suspend(dapm, "Ext Spk");
	snd_soc_dapm_ignore_suspend(dapm, "AFML");
	snd_soc_dapm_ignore_suspend(dapm, "AFMR");
	snd_soc_dapm_ignore_suspend(dapm, "Headset Mic");
	snd_soc_dapm_ignore_suspend(dapm, "Headset Stereophone");
	snd_soc_dapm_ignore_suspend(dapm, "Digital Mic 0");
	snd_soc_dapm_ignore_suspend(dapm, "Digital Mic 1");
	snd_soc_dapm_ignore_suspend(dapm, "Digital Mic 2");

	ret = snd_soc_dapm_sync(dapm);
	if (ret)
		return ret;

	/* Headset jack detection */
	ret = snd_soc_jack_new(codec, "Headset Jack",
				SND_JACK_HEADSET, &hs_jack);
	if (ret)
		return ret;

	ret = snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins),
				hs_jack_pins);

	if (machine_is_omap_4430sdp() || machine_is_omap_tabletblaze()
		|| machine_is_omap4_panda())
		twl6040_hs_jack_detect(codec, &hs_jack, SND_JACK_HEADSET);
	else
		snd_soc_jack_report(&hs_jack, SND_JACK_HEADSET, SND_JACK_HEADSET);

	/* DC offset cancellation computation */
	hsotrim = snd_soc_read(codec, TWL6040_REG_HSOTRIM);
	right_offset = (hsotrim & TWL6040_HSRO) >> TWL6040_HSRO_OFFSET;
	left_offset = hsotrim & TWL6040_HSLO;

	if (twl6040_get_icrev(twl6040) < TWL6040_REV_1_3)
		/* For ES under ES_1.3 HS step is 2 mV */
		mode = 2;
	else
		/* For ES_1.3 HS step is 1 mV */
		mode = 1;

	abe_dsp_set_hs_offset(left_offset, right_offset, mode);

	/* don't wait before switching of HS power */
	rtd->pmdown_time = 0;

	return ret;
}
开发者ID:Pesach85,项目名称:lge-kernel-omap4,代码行数:80,代码来源:sdp4430.c


示例5: cs4270_hw_params

/**
 * cs4270_hw_params - program the CS4270 with the given hardware parameters.
 * @substream: the audio stream
 * @params: the hardware parameters to set
 * @dai: the SOC DAI (ignored)
 *
 * This function programs the hardware with the values provided.
 * Specifically, the sample rate and the data format.
 *
 * The .ops functions are used to provide board-specific data, like input
 * frequencies, to this driver.  This function takes that information,
 * combines it with the hardware parameters provided, and programs the
 * hardware accordingly.
 */
static int cs4270_hw_params(struct snd_pcm_substream *substream,
			    struct snd_pcm_hw_params *params,
			    struct snd_soc_dai *dai)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_device *socdev = rtd->socdev;
	struct snd_soc_codec *codec = socdev->card->codec;
	struct cs4270_private *cs4270 = codec->private_data;
	int ret;
	unsigned int i;
	unsigned int rate;
	unsigned int ratio;
	int reg;

	/* Figure out which MCLK/LRCK ratio to use */

	rate = params_rate(params);	/* Sampling rate, in Hz */
	ratio = cs4270->mclk / rate;	/* MCLK/LRCK ratio */

	for (i = 0; i < NUM_MCLK_RATIOS; i++) {
		if (cs4270_mode_ratios[i].ratio == ratio)
			break;
	}

	if (i == NUM_MCLK_RATIOS) {
		/* We did not find a matching ratio */
		dev_err(codec->dev, "could not find matching ratio\n");
		return -EINVAL;
	}

	/* Set the sample rate */

	reg = snd_soc_read(codec, CS4270_MODE);
	reg &= ~(CS4270_MODE_SPEED_MASK | CS4270_MODE_DIV_MASK);
	reg |= cs4270_mode_ratios[i].mclk;

	if (cs4270->slave_mode)
		reg |= CS4270_MODE_SLAVE;
	else
		reg |= cs4270_mode_ratios[i].speed_mode;

	ret = snd_soc_write(codec, CS4270_MODE, reg);
	if (ret < 0) {
		dev_err(codec->dev, "i2c write failed\n");
		return ret;
	}

	/* Set the DAI format */

	reg = snd_soc_read(codec, CS4270_FORMAT);
	reg &= ~(CS4270_FORMAT_DAC_MASK | CS4270_FORMAT_ADC_MASK);

	switch (cs4270->mode) {
	case SND_SOC_DAIFMT_I2S:
		reg |= CS4270_FORMAT_DAC_I2S | CS4270_FORMAT_ADC_I2S;
		break;
	case SND_SOC_DAIFMT_LEFT_J:
		reg |= CS4270_FORMAT_DAC_LJ | CS4270_FORMAT_ADC_LJ;
		break;
	default:
		dev_err(codec->dev, "unknown dai format\n");
		return -EINVAL;
	}

	ret = snd_soc_write(codec, CS4270_FORMAT, reg);
	if (ret < 0) {
		dev_err(codec->dev, "i2c write failed\n");
		return ret;
	}

	return ret;
}
开发者ID:325116067,项目名称:semc-qsd8x50,代码行数:86,代码来源:cs4270.c


示例6: configure_clock

static int configure_clock(struct snd_soc_codec *codec)
{
	struct wm9081_priv *wm9081 = codec->private_data;
	int new_sysclk, i, target;
	unsigned int reg;
	int ret = 0;
	int mclkdiv = 0;
	int fll = 0;

	switch (wm9081->sysclk_source) {
	case WM9081_SYSCLK_MCLK:
		if (wm9081->mclk_rate > 12225000) {
			mclkdiv = 1;
			wm9081->sysclk_rate = wm9081->mclk_rate / 2;
		} else {
			wm9081->sysclk_rate = wm9081->mclk_rate;
		}
		wm9081_set_fll(codec, WM9081_SYSCLK_FLL_MCLK, 0, 0);
		break;

	case WM9081_SYSCLK_FLL_MCLK:
		/* If we have a sample rate calculate a CLK_SYS that
		 * gives us a suitable DAC configuration, plus BCLK.
		 * Ideally we would check to see if we can clock
		 * directly from MCLK and only use the FLL if this is
		 * not the case, though care must be taken with free
		 * running mode.
		 */
		if (wm9081->master && wm9081->bclk) {
			/* Make sure we can generate CLK_SYS and BCLK
			 * and that we've got 3MHz for optimal
			 * performance. */
			for (i = 0; i < ARRAY_SIZE(clk_sys_rates); i++) {
				target = wm9081->fs * clk_sys_rates[i].ratio;
				new_sysclk = target;
				if (target >= wm9081->bclk &&
				    target > 3000000)
					break;
			}

			if (i == ARRAY_SIZE(clk_sys_rates))
				return -EINVAL;

		} else if (wm9081->fs) {
			for (i = 0; i < ARRAY_SIZE(clk_sys_rates); i++) {
				new_sysclk = clk_sys_rates[i].ratio
					* wm9081->fs;
				if (new_sysclk > 3000000)
					break;
			}

			if (i == ARRAY_SIZE(clk_sys_rates))
				return -EINVAL;

		} else {
			new_sysclk = 12288000;
		}

		ret = wm9081_set_fll(codec, WM9081_SYSCLK_FLL_MCLK,
				     wm9081->mclk_rate, new_sysclk);
		if (ret == 0) {
			wm9081->sysclk_rate = new_sysclk;

			/* Switch SYSCLK over to FLL */
			fll = 1;
		} else {
			wm9081->sysclk_rate = wm9081->mclk_rate;
		}
		break;

	default:
		return -EINVAL;
	}

	reg = snd_soc_read(codec, WM9081_CLOCK_CONTROL_1);
	if (mclkdiv)
		reg |= WM9081_MCLKDIV2;
	else
		reg &= ~WM9081_MCLKDIV2;
	snd_soc_write(codec, WM9081_CLOCK_CONTROL_1, reg);

	reg = snd_soc_read(codec, WM9081_CLOCK_CONTROL_3);
	if (fll)
		reg |= WM9081_CLK_SRC_SEL;
	else
		reg &= ~WM9081_CLK_SRC_SEL;
	snd_soc_write(codec, WM9081_CLOCK_CONTROL_3, reg);

	dev_dbg(codec->dev, "CLK_SYS is %dHz\n", wm9081->sysclk_rate);

	return ret;
}
开发者ID:A2109devs,项目名称:lenovo_a2109a_kernel,代码行数:92,代码来源:wm9081.c


示例7: out_pga_event

static int out_pga_event(struct snd_soc_dapm_widget *w,
			 struct snd_kcontrol *kcontrol, int event)
{
	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
	struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
	int reg, val;
	int dcs_mask;
	int dcs_l, dcs_r;
	int dcs_l_reg, dcs_r_reg;
	int timeout;
	int pwr_reg;

	/* This code is shared between HP and LINEOUT; we do all our
	 * power management in stereo pairs to avoid latency issues so
	 * we reuse shift to identify which rather than strcmp() the
	 * name. */
	reg = w->shift;

	switch (reg) {
	case WM8904_ANALOGUE_HP_0:
		pwr_reg = WM8904_POWER_MANAGEMENT_2;
		dcs_mask = WM8904_DCS_ENA_CHAN_0 | WM8904_DCS_ENA_CHAN_1;
		dcs_r_reg = WM8904_DC_SERVO_8;
		dcs_l_reg = WM8904_DC_SERVO_9;
		dcs_l = 0;
		dcs_r = 1;
		break;
	case WM8904_ANALOGUE_LINEOUT_0:
		pwr_reg = WM8904_POWER_MANAGEMENT_3;
		dcs_mask = WM8904_DCS_ENA_CHAN_2 | WM8904_DCS_ENA_CHAN_3;
		dcs_r_reg = WM8904_DC_SERVO_6;
		dcs_l_reg = WM8904_DC_SERVO_7;
		dcs_l = 2;
		dcs_r = 3;
		break;
	default:
		WARN(1, "Invalid reg %d\n", reg);
		return -EINVAL;
	}

	switch (event) {
	case SND_SOC_DAPM_PRE_PMU:
		/* Power on the PGAs */
		snd_soc_update_bits(codec, pwr_reg,
				    WM8904_HPL_PGA_ENA | WM8904_HPR_PGA_ENA,
				    WM8904_HPL_PGA_ENA | WM8904_HPR_PGA_ENA);

		/* Power on the amplifier */
		snd_soc_update_bits(codec, reg,
				    WM8904_HPL_ENA | WM8904_HPR_ENA,
				    WM8904_HPL_ENA | WM8904_HPR_ENA);


		/* Enable the first stage */
		snd_soc_update_bits(codec, reg,
				    WM8904_HPL_ENA_DLY | WM8904_HPR_ENA_DLY,
				    WM8904_HPL_ENA_DLY | WM8904_HPR_ENA_DLY);

		/* Power up the DC servo */
		snd_soc_update_bits(codec, WM8904_DC_SERVO_0,
				    dcs_mask, dcs_mask);

		/* Either calibrate the DC servo or restore cached state
		 * if we have that.
		 */
		if (wm8904->dcs_state[dcs_l] || wm8904->dcs_state[dcs_r]) {
			dev_dbg(codec->dev, "Restoring DC servo state\n");

			snd_soc_write(codec, dcs_l_reg,
				      wm8904->dcs_state[dcs_l]);
			snd_soc_write(codec, dcs_r_reg,
				      wm8904->dcs_state[dcs_r]);

			snd_soc_write(codec, WM8904_DC_SERVO_1, dcs_mask);

			timeout = 20;
		} else {
			dev_dbg(codec->dev, "Calibrating DC servo\n");

			snd_soc_write(codec, WM8904_DC_SERVO_1,
				dcs_mask << WM8904_DCS_TRIG_STARTUP_0_SHIFT);

			timeout = 500;
		}

		/* Wait for DC servo to complete */
		dcs_mask <<= WM8904_DCS_CAL_COMPLETE_SHIFT;
		do {
			val = snd_soc_read(codec, WM8904_DC_SERVO_READBACK_0);
			if ((val & dcs_mask) == dcs_mask)
				break;

			msleep(1);
		} while (--timeout);

		if ((val & dcs_mask) != dcs_mask)
			dev_warn(codec->dev, "DC servo timed out\n");
		else
			dev_dbg(codec->dev, "DC servo ready\n");

//.........这里部分代码省略.........
开发者ID:rajat1994,项目名称:linux,代码行数:101,代码来源:wm8904.c


示例8: alc5632_set_dai_pll

static int alc5632_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
		int source, unsigned int freq_in, unsigned int freq_out)
{
	int i;
	struct snd_soc_codec *codec = codec_dai->codec;
	int gbl_clk = 0, pll_div = 0;
	u16 reg;

	if (pll_id < ALC5632_PLL_FR_MCLK || pll_id > ALC5632_PLL_FR_VBCLK)
		return -EINVAL;

	/*                   */
	snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
				ALC5632_PWR_ADD2_PLL1,
				0);
	snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
				ALC5632_PWR_ADD2_PLL2,
				0);

	/*                               */
	reg = snd_soc_read(codec, ALC5632_DAI_CONTROL);
	if (reg & ALC5632_DAI_SDP_SLAVE_MODE)
		return 0;

	if (!freq_in || !freq_out)
		return 0;

	switch (pll_id) {
	case ALC5632_PLL_FR_MCLK:
		for (i = 0; i < ARRAY_SIZE(codec_master_pll_div); i++) {
			if (codec_master_pll_div[i].pll_in == freq_in
			   && codec_master_pll_div[i].pll_out == freq_out) {
				/*                      */
				pll_div  = codec_master_pll_div[i].regvalue;
				break;
			}
		}
		break;
	case ALC5632_PLL_FR_BCLK:
		for (i = 0; i < ARRAY_SIZE(codec_slave_pll_div); i++) {
			if (codec_slave_pll_div[i].pll_in == freq_in
			   && codec_slave_pll_div[i].pll_out == freq_out) {
				/*                        */
				gbl_clk = ALC5632_PLL_FR_BCLK;
				pll_div = codec_slave_pll_div[i].regvalue;
				break;
			}
		}
		break;
	case ALC5632_PLL_FR_VBCLK:
		for (i = 0; i < ARRAY_SIZE(codec_slave_pll_div); i++) {
			if (codec_slave_pll_div[i].pll_in == freq_in
			   && codec_slave_pll_div[i].pll_out == freq_out) {
				/*                             */
				gbl_clk = ALC5632_PLL_FR_VBCLK;
				pll_div = codec_slave_pll_div[i].regvalue;
				break;
			}
		}
		break;
	default:
		return -EINVAL;
	}

	if (!pll_div)
		return -EINVAL;

	/*                        */
	snd_soc_write(codec, ALC5632_GPCR2, gbl_clk);
	/*                        */
	snd_soc_write(codec, ALC5632_PLL1_CTRL, pll_div);
	/*             */
	snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
				ALC5632_PWR_ADD2_PLL1,
				ALC5632_PWR_ADD2_PLL1);
	/*             */
	snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
				ALC5632_PWR_ADD2_PLL2,
				ALC5632_PWR_ADD2_PLL2);
	/*                         */
	snd_soc_update_bits(codec, ALC5632_GPCR1,
			ALC5632_GPCR1_CLK_SYS_SRC_SEL_PLL1,
			ALC5632_GPCR1_CLK_SYS_SRC_SEL_PLL1);

	return 0;
}
开发者ID:romanbb,项目名称:android_kernel_lge_d851,代码行数:86,代码来源:alc5632.c


示例9: rt_codec_hwdep_ioctl_common

static int rt_codec_hwdep_ioctl_common(struct snd_hwdep *hw,
		struct file *file, unsigned int cmd, unsigned long arg)
{
	struct snd_soc_codec *codec = hw->private_data;
	struct rt_codec_cmd __user *_rt_codec = (struct rt_codec_cmd *)arg;
	struct rt_codec_cmd rt_codec;
	int *buf, *p;

	if (copy_from_user(&rt_codec, _rt_codec, sizeof(rt_codec))) {
		dev_err(codec->dev, "copy_from_user faild\n");
		return -EFAULT;
	}
	dev_dbg(codec->dev, "%s(): rt_codec.number=%d, cmd=%d\n",
			__func__, rt_codec.number, cmd);
	buf = kmalloc(sizeof(*buf) * rt_codec.number, GFP_KERNEL);
	if (buf == NULL)
		return -ENOMEM;
	if (copy_from_user(buf, rt_codec.buf, sizeof(*buf) * rt_codec.number))
		goto err;

	switch (cmd) {
	case RT_READ_CODEC_REG_IOCTL:
		for (p = buf; p < buf + rt_codec.number / 2; p++)
			*(p + rt_codec.number / 2) = snd_soc_read(codec, *p);
		if (copy_to_user(rt_codec.buf, buf, sizeof(*buf) * rt_codec.number))
			goto err;
		break;
	case RT_WRITE_CODEC_REG_IOCTL:
		for (p = buf; p < buf + rt_codec.number / 2; p++)
			snd_soc_write(codec, *p, *(p + rt_codec.number / 2));
		break;
	case RT_READ_CODEC_INDEX_IOCTL:
		if (NULL == rt_codec_ioctl_ops.index_read)
			goto err;

		for (p = buf; p < buf + rt_codec.number / 2; p++)
			*(p+rt_codec.number / 2) = rt_codec_ioctl_ops.index_read(
							codec, *p);
		if (copy_to_user(rt_codec.buf, buf,
			sizeof(*buf) * rt_codec.number))
			goto err;
		break;

	case RT_WRITE_CODEC_INDEX_IOCTL:
		if (NULL == rt_codec_ioctl_ops.index_write)
			goto err;

		for (p = buf; p < buf + rt_codec.number / 2; p++) {
			dev_dbg(codec->dev, "%x , %x\n",
				*p, *(p+rt_codec.number / 2));
			rt_codec_ioctl_ops.index_write(codec, *p,
				*(p+rt_codec.number / 2));
		}
		break;

	default:
		if (NULL == rt_codec_ioctl_ops.ioctl_common)
			goto err;

		rt_codec_ioctl_ops.ioctl_common(hw, file, cmd, arg);
		break;
	}

	kfree(buf);
	return 0;

err:
	kfree(buf);
	return -EFAULT;
}
开发者ID:matheusgcdj,项目名称:android_kernel_asus_T00F,代码行数:70,代码来源:rt_codec_ioctl.c


示例10: sta32x_hw_params

/**
 * sta32x_hw_params - program the STA32X with the given hardware parameters.
 * @substream: the audio stream
 * @params: the hardware parameters to set
 * @dai: the SOC DAI (ignored)
 *
 * This function programs the hardware with the values provided.
 * Specifically, the sample rate and the data format.
 */
static int sta32x_hw_params(struct snd_pcm_substream *substream,
			    struct snd_pcm_hw_params *params,
			    struct snd_soc_dai *dai)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_codec *codec = rtd->codec;
	struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
	unsigned int rate;
	int i, mcs = -1, ir = -1;
	u8 confa, confb;

	rate = params_rate(params);
	pr_debug("rate: %u\n", rate);
	for (i = 0; i < ARRAY_SIZE(interpolation_ratios); i++)
		if (interpolation_ratios[i].fs == rate) {
			ir = interpolation_ratios[i].ir;
			break;
		}
	if (ir < 0)
		return -EINVAL;
	for (i = 0; mclk_ratios[ir][i].ratio; i++)
		if (mclk_ratios[ir][i].ratio * rate == sta32x->mclk) {
			mcs = mclk_ratios[ir][i].mcs;
			break;
		}
	if (mcs < 0)
		return -EINVAL;

	confa = snd_soc_read(codec, STA32X_CONFA);
	confa &= ~(STA32X_CONFA_MCS_MASK | STA32X_CONFA_IR_MASK);
	confa |= (ir << STA32X_CONFA_IR_SHIFT) | (mcs << STA32X_CONFA_MCS_SHIFT);

	confb = snd_soc_read(codec, STA32X_CONFB);
	confb &= ~(STA32X_CONFB_SAI_MASK | STA32X_CONFB_SAIFB);
	switch (params_format(params)) {
	case SNDRV_PCM_FORMAT_S24_LE:
	case SNDRV_PCM_FORMAT_S24_BE:
	case SNDRV_PCM_FORMAT_S24_3LE:
	case SNDRV_PCM_FORMAT_S24_3BE:
		pr_debug("24bit\n");
		/* fall through */
	case SNDRV_PCM_FORMAT_S32_LE:
	case SNDRV_PCM_FORMAT_S32_BE:
		pr_debug("24bit or 32bit\n");
		switch (sta32x->format) {
		case SND_SOC_DAIFMT_I2S:
			confb |= 0x0;
			break;
		case SND_SOC_DAIFMT_LEFT_J:
			confb |= 0x1;
			break;
		case SND_SOC_DAIFMT_RIGHT_J:
			confb |= 0x2;
			break;
		}

		break;
	case SNDRV_PCM_FORMAT_S20_3LE:
	case SNDRV_PCM_FORMAT_S20_3BE:
		pr_debug("20bit\n");
		switch (sta32x->format) {
		case SND_SOC_DAIFMT_I2S:
			confb |= 0x4;
			break;
		case SND_SOC_DAIFMT_LEFT_J:
			confb |= 0x5;
			break;
		case SND_SOC_DAIFMT_RIGHT_J:
			confb |= 0x6;
			break;
		}

		break;
	case SNDRV_PCM_FORMAT_S18_3LE:
	case SNDRV_PCM_FORMAT_S18_3BE:
		pr_debug("18bit\n");
		switch (sta32x->format) {
		case SND_SOC_DAIFMT_I2S:
			confb |= 0x8;
			break;
		case SND_SOC_DAIFMT_LEFT_J:
			confb |= 0x9;
			break;
		case SND_SOC_DAIFMT_RIGHT_J:
			confb |= 0xa;
			break;
		}

		break;
	case SNDRV_PCM_FORMAT_S16_LE:
	case SNDRV_PCM_FORMAT_S16_BE:
//.........这里部分代码省略.........
开发者ID:openube,项目名称:android_kernel_sony_c2305,代码行数:101,代码来源:sta32x.c


示例11: cs42l73_set_dai_fmt

static int cs42l73_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
{
	struct snd_soc_codec *codec = codec_dai->codec;
	struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec);
	u8 id = codec_dai->id;
	unsigned int inv, format;
	u8 spc, mmcc;

	spc = snd_soc_read(codec, CS42L73_SPC(id));
	mmcc = snd_soc_read(codec, CS42L73_MMCC(id));

	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
	case SND_SOC_DAIFMT_CBM_CFM:
		mmcc |= CS42L73_MS_MASTER;
		break;

	case SND_SOC_DAIFMT_CBS_CFS:
		mmcc &= ~CS42L73_MS_MASTER;
		break;

	default:
		return -EINVAL;
	}

	format = (fmt & SND_SOC_DAIFMT_FORMAT_MASK);
	inv = (fmt & SND_SOC_DAIFMT_INV_MASK);

	switch (format) {
	case SND_SOC_DAIFMT_I2S:
		spc &= ~CS42L73_SPDIF_PCM;
		break;
	case SND_SOC_DAIFMT_DSP_A:
	case SND_SOC_DAIFMT_DSP_B:
		if (mmcc & CS42L73_MS_MASTER) {
			dev_err(codec->dev,
				"PCM format in slave mode only\n");
			return -EINVAL;
		}
		if (id == CS42L73_ASP) {
			dev_err(codec->dev,
				"PCM format is not supported on ASP port\n");
			return -EINVAL;
		}
		spc |= CS42L73_SPDIF_PCM;
		break;
	default:
		return -EINVAL;
	}

	if (spc & CS42L73_SPDIF_PCM) {
		/* Clear PCM mode, clear PCM_BIT_ORDER bit for MSB->LSB */
		spc &= ~(CS42L73_PCM_MODE_MASK | CS42L73_PCM_BIT_ORDER);
		switch (format) {
		case SND_SOC_DAIFMT_DSP_B:
			if (inv == SND_SOC_DAIFMT_IB_IF)
				spc |= CS42L73_PCM_MODE0;
			if (inv == SND_SOC_DAIFMT_IB_NF)
				spc |= CS42L73_PCM_MODE1;
		break;
		case SND_SOC_DAIFMT_DSP_A:
			if (inv == SND_SOC_DAIFMT_IB_IF)
				spc |= CS42L73_PCM_MODE1;
			break;
		default:
			return -EINVAL;
		}
	}

	priv->config[id].spc = spc;
	priv->config[id].mmcc = mmcc;

	return 0;
}
开发者ID:acton393,项目名称:linux,代码行数:73,代码来源:cs42l73.c


示例12: most2120_codec_hw_params


//.........这里部分代码省略.........
        ddiv = WM8960_DAC_DIV_2;
        adiv = WM8960_ADC_DIV_2;
        bdiv = WM8960_BCLK_DIV_8;
        pll_out = 11289600;
        break;
      case 44100:
        ddiv = WM8960_DAC_DIV_1;
        adiv = WM8960_ADC_DIV_1;
        bdiv = WM8960_BCLK_DIV_4;
        pll_out = 11289600;
        break;
      default :
        ddiv = WM8960_DAC_DIV_1;
        adiv = WM8960_ADC_DIV_1;
        bdiv = WM8960_BCLK_DIV_4;
        pll_out = 11289600;
    }

    /* NEXELL's nxp2120 has limited clock generation function, so it would be better
       Nxp2120 only generate reference clock from PLL1, 192MHz / 16 = 12 MHz...
       And then let WM8960 generate required clock for itself. */

    /* set codec DAI configuration */
    ret = snd_soc_dai_set_fmt(codec_dai,
        SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
        SND_SOC_DAIFMT_CBM_CFM); /* Set master mode for generate bitclk and fs(lrclk) */
    if (ret < 0)
        return ret;

    /* set cpu DAI configuration */
    ret = snd_soc_dai_set_fmt(cpu_dai,
        SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
        SND_SOC_DAIFMT_CBS_CFS); /* Set slave mode for bitclk, and fs(lrclk) */
    if (ret < 0)
        return ret;

    /* set CPU generate reference clock for Codec's PLL. So Set PLL1 as clock source.  */
    ret = snd_soc_dai_set_sysclk(cpu_dai, NX_I2S_CLKSRC_0, NX_I2S_CLKSRC0_PLL1, SND_SOC_CLOCK_OUT);
    if (ret < 0)
        return ret;
    
    /* Our I2S is Slave, So Set to EXT_BIT.  */
    ret = snd_soc_dai_set_sysclk(cpu_dai, NX_I2S_CLKSRC_1, NX_I2S_CLKSRC1_EXT_BIT, SND_SOC_CLOCK_IN);
    if (ret < 0)
        return ret;
    
    /* Set prescaler set to 16 to generate 12MHz around clock */
    ret = snd_soc_dai_set_clkdiv(cpu_dai, NX_I2S_CLKDIV_0, 16 - 1); /* PLL1 192MHz -> 12MHz with 1/16 */
    if (ret < 0)
        return ret;
    
    /* Use Bitclk as Clock Source and no division. */
    ret = snd_soc_dai_set_clkdiv(cpu_dai, NX_I2S_CLKDIV_1, 1 - 1); /* No div as BITCLK */
    if (ret < 0)
        return ret;

    /* Set fs as 64fs(256fs). */
    ret = snd_soc_dai_set_clkdiv(cpu_dai, NX_I2S_CLKDIV_SYNC_PERIOD, NX_I2S_PERDIV_64);
    if (ret < 0)
        return ret;
   
    /* set codec sysclock from PLL source */
    ret = snd_soc_dai_set_clkdiv(codec_dai, WM8960_SYSCLKSEL, WM8960_SYSCLK_PLL);
    if (ret < 0)
        return ret;

    /* Now All the bit rate and rootclock should be set. */
    /* set codec sysclock from PLL source */
    ret = snd_soc_dai_set_pll(codec_dai, 0, 0, iis_clk / 16, pll_out);
    if (ret < 0)
        return ret;
   
    /* set codec speaker DCLK for SYSCLK/2. -> SYSCLK/16 */
    ret = snd_soc_dai_set_clkdiv(codec_dai, WM8960_DCLKDIV, WM8960_DCLK_DIV_16);
    if (ret < 0)
        return ret;

    /* set codec DAC div factor to ddiv. */
    ret = snd_soc_dai_set_clkdiv(codec_dai, WM8960_DACDIV, ddiv);
    if (ret < 0)
        return ret;
    
    /* set codec ADC div factor to adiv. */
    ret = snd_soc_dai_set_clkdiv(codec_dai, WM8960_ADCDIV, adiv);
    if (ret < 0)
        return ret;
    
    /* Bit Clock should be devided for NEXELL 256fs machine  */
    ret = snd_soc_dai_set_clkdiv(codec_dai, WM8960_BCLKDIV, bdiv);
    if (ret < 0)
        return ret;

    
#if MOST2120_WM8960_DEBUG
    for (i=0; i<56;i++) {
        printk("codec addr = 0x%x(%d) val= %x\n", i, i, snd_soc_read(codec_dai->codec, i));
    }
#endif
	return 0;
}
开发者ID:vlasenko,项目名称:kernel.rk,代码行数:101,代码来源:nexell-wm8960.c


示例13: wm8961_register

static int wm8961_register(struct wm8961_priv *wm8961)
{
	struct snd_soc_codec *codec = &wm8961->codec;
	int ret;
	u16 reg;

	if (wm8961_codec) {
		dev_err(codec->dev, "Another WM8961 is registered\n");
		ret = -EINVAL;
		goto err;
	}

	mutex_init(&codec->mutex);
	INIT_LIST_HEAD(&codec->dapm_widgets);
	INIT_LIST_HEAD(&codec->dapm_paths);

	snd_soc_codec_set_drvdata(codec, wm8961);
	codec->name = "WM8961";
	codec->owner = THIS_MODULE;
	codec->dai = &wm8961_dai;
	codec->num_dai = 1;
	codec->reg_cache_size = ARRAY_SIZE(wm8961->reg_cache);
	codec->reg_cache = &wm8961->reg_cache;
	codec->bias_level = SND_SOC_BIAS_OFF;
	codec->set_bias_level = wm8961_set_bias_level;
	codec->volatile_register = wm8961_volatile_register;

	memcpy(codec->reg_cache, wm8961_reg_defaults,
	       sizeof(wm8961_reg_defaults));

	ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
	if (ret != 0) {
		dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
		goto err;
	}

	reg = snd_soc_read(codec, WM8961_SOFTWARE_RESET);
	if (reg != 0x1801) {
		dev_err(codec->dev, "Device is not a WM8961: ID=0x%x\n", reg);
		ret = -EINVAL;
		goto err;
	}

	/* This isn't volatile - readback doesn't correspond to write */
	reg = codec->hw_read(codec, WM8961_RIGHT_INPUT_VOLUME);
	dev_info(codec->dev, "WM8961 family %d revision %c\n",
		 (reg & WM8961_DEVICE_ID_MASK) >> WM8961_DEVICE_ID_SHIFT,
		 ((reg & WM8961_CHIP_REV_MASK) >> WM8961_CHIP_REV_SHIFT)
		 + 'A');

	ret = wm8961_reset(codec);
	if (ret < 0) {
		dev_err(codec->dev, "Failed to issue reset\n");
		return ret;
	}

	/* Enable class W */
	reg = snd_soc_read(codec, WM8961_CHARGE_PUMP_B);
	reg |= WM8961_CP_DYN_PWR_MASK;
	snd_soc_write(codec, WM8961_CHARGE_PUMP_B, reg);

	/* Latch volume update bits (right channel only, we always
	 * write both out) and default ZC on. */
	reg = snd_soc_read(codec, WM8961_ROUT1_VOLUME);
	snd_soc_write(codec, WM8961_ROUT1_VOLUME,
		     reg | WM8961_LO1ZC | WM8961_OUT1VU);
	snd_soc_write(codec, WM8961_LOUT1_VOLUME, reg | WM8961_LO1ZC);
	reg = snd_soc_read(codec, WM8961_ROUT2_VOLUME);
	snd_soc_write(codec, WM8961_ROUT2_VOLUME,
		     reg | WM8961_SPKRZC | WM8961_SPKVU);
	snd_soc_write(codec, WM8961_LOUT2_VOLUME, reg | WM8961_SPKLZC);

	reg = snd_soc_read(codec, WM8961_RIGHT_ADC_VOLUME);
	snd_soc_write(codec, WM8961_RIGHT_ADC_VOLUME, reg | WM8961_ADCVU);
	reg = snd_soc_read(codec, WM8961_RIGHT_INPUT_VOLUME);
	snd_soc_write(codec, WM8961_RIGHT_INPUT_VOLUME, reg | WM8961_IPVU);

	/* Use soft mute by default */
	reg = snd_soc_read(codec, WM8961_ADC_DAC_CONTROL_2);
	reg |= WM8961_DACSMM;
	snd_soc_write(codec, WM8961_ADC_DAC_CONTROL_2, reg);

	/* Use automatic clocking mode by default; for now this is all
	 * we support.
	 */
	reg = snd_soc_read(codec, WM8961_CLOCKING_3);
	reg &= ~WM8961_MANUAL_MODE;
	snd_soc_write(codec, WM8961_CLOCKING_3, reg);

	wm8961_set_bias_level(codec, SND_SOC_BIAS_STANDBY);

	wm8961_dai.dev = codec->dev;

	wm8961_codec = codec;

	ret = snd_soc_register_codec(codec);
	if (ret != 0) {
		dev_err(codec->dev, "Failed to register codec: %d\n", ret);
		return ret;
	}
//.........这里部分代码省略.........
开发者ID:12rafael,项目名称:jellytimekernel,代码行数:101,代码来源:wm8961.c


示例14: wm8523_register

static int wm8523_register(struct wm8523_priv *wm8523,
			   enum snd_soc_control_type control)
{
	int ret;
	struct snd_soc_codec *codec = &wm8523->codec;
	int i;

	if (wm8523_codec) {
		dev_err(codec->dev, "Another WM8523 is registered\n");
		return -EINVAL;
	}

	mutex_init(&codec->mutex);
	INIT_LIST_HEAD(&codec->dapm_widgets);
	INIT_LIST_HEAD(&codec->dapm_paths);

	snd_soc_codec_set_drvdata(codec, wm8523);
	codec->name = "WM8523";
	codec->owner = THIS_MODULE;
	codec->bias_level = SND_SOC_BIAS_OFF;
	codec->set_bias_level = wm8523_set_bias_level;
	codec->dai = &wm8523_dai;
	codec->num_dai = 1;
	codec->reg_cache_size = WM8523_REGISTER_COUNT;
	codec->reg_cache = &wm8523->reg_cache;
	codec->volatile_register = wm8523_volatile_register;

	wm8523->rate_constraint.list = &wm8523->rate_constraint_list[0];
	wm8523->rate_constraint.count =
		ARRAY_SIZE(wm8523->rate_constraint_list);

	memcpy(codec->reg_cache, wm8523_reg, sizeof(wm8523_reg));

	ret = snd_soc_codec_set_cache_io(codec, 8, 16, control);
	if (ret != 0) {
		dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
		goto err;
	}

	for (i = 0; i < ARRAY_SIZE(wm8523->supplies); i++)
		wm8523->supplies[i].supply = wm8523_supply_names[i];

	ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8523->supplies),
				 wm8523->supplies);
	if (ret != 0) {
		dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
		goto err;
	}

	ret = regulator_bulk_enable(ARRAY_SIZE(wm8523->supplies),
				    wm8523->supplies);
	if (ret != 0) {
		dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
		goto err_get;
	}

	ret = snd_soc_read(codec, WM8523_DEVICE_ID);
	if (ret < 0) {
		dev_err(codec->dev, "Failed to read ID register\n");
		goto err_enable;
	}
	if (ret != wm8523_reg[WM8523_DEVICE_ID]) {
		dev_err(codec->dev, "Device is not a WM8523, ID is %x\n", ret);
		ret = -EINVAL;
		goto err_enable;
	}

	ret = snd_soc_read(codec, WM8523_REVISION);
	if (ret < 0) {
		dev_err(codec->dev, "Failed to read revision register\n");
		goto err_enable;
	}
	dev_info(codec->dev, "revision %c\n",
		 (ret & WM8523_CHIP_REV_MASK) + 'A');

	ret = wm8523_reset(codec);
	if (ret < 0) {
		dev_err(codec->dev, "Failed to issue reset\n");
		goto err_enable;
	}

	wm8523_dai.dev = codec->dev;

	/* Change some default settings - latch VU and enable ZC */
	wm8523->reg_cache[WM8523_DAC_GAINR] |= WM8523_DACR_VU;
	wm8523->reg_cache[WM8523_DAC_CTRL3] |= WM8523_ZC;

	wm8523_set_bias_level(codec, SND_SOC_BIAS_STANDBY);

	/* Bias level configuration will have done an extra enable */
	regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);

	wm8523_codec = codec;

	ret = snd_soc_register_codec(codec);
	if (ret != 0) {
		dev_err(codec->dev, "Failed to register codec: %d\n", ret);
		return ret;
	}

//.........这里部分代码省略.........
开发者ID:12rafael,项目名称:jellytimekernel,代码行数:101,代码来源:wm8523.c


示例15: wm8961_hp_event

/*
 * The headphone output supports special anti-pop sequences giving
 * silent power up and power down.
 */
static int wm8961_hp_event(struct snd_soc_dapm_widget *w,
			   struct snd_kcontrol *kcontrol, int event)
{
	struct snd_soc_codec *codec = w->codec;
	u16 hp_reg = snd_soc_read(codec, WM8961_ANALOGUE_HP_0);
	u16 cp_reg = snd_soc_read(codec, WM8961_CHARGE_PUMP_1);
	u16 pwr_reg = snd_soc_read(codec, WM8961_PWR_MGMT_2);
	u16 dcs_reg = snd_soc_read(codec, WM8961_DC_SERVO_1);
	int timeout = 500;

	if (event & SND_SOC_DAPM_POST_PMU) {
		/* Make sure the output is shorted */
		hp_reg &= ~(WM8961_HPR_RMV_SHORT | WM8961_HPL_RMV_SHORT);
		snd_soc_write(codec, WM8961_ANALOGUE_HP_0, hp_reg);

		/* Enable the charge pump */
		cp_reg |= WM8961_CP_ENA;
		snd_soc_write(codec, WM8961_CHARGE_PUMP_1, cp_reg);
		mdelay(5);

		/* Enable the PGA */
		pwr_reg |= WM8961_LOUT1_PGA | WM8961_ROUT1_PGA;
		snd_soc_write(codec, WM8961_PWR_MGMT_2, pwr_reg);

		/* Enable the amplifier */
		hp_reg |= WM8961_HPR_ENA | WM8961_HPL_ENA;
		snd_soc_write(codec, WM8961_ANALOGUE_HP_0, hp_reg);

		/* Second stage enable */
		hp_reg |= WM8961_HPR_ENA_DLY | WM8961_HPL_ENA_DLY;
		snd_soc_write(codec, WM8961_ANALOGUE_HP_0, hp_reg);

		/* Enable the DC servo & trigger startup */
		dcs_reg |=
			WM8961_DCS_ENA_CHAN_HPR | WM8961_DCS_TRIG_STARTUP_HPR |
			WM8961_DCS_ENA_CHAN_HPL | WM8961_DCS_TRIG_STARTUP_HPL;
		dev_dbg(codec->dev, "Enabling DC servo\n");

		snd_soc_write(codec, WM8961_DC_SERVO_1, dcs_reg);
		do {
			msleep(1);
			dcs_reg = snd_soc_read(codec, WM8961_DC_SERVO_1);
		} while (--timeout &&
			 dcs_reg & (WM8961_DCS_TRIG_STARTUP_HPR |
				WM8961_DCS_TRIG_STARTUP_HPL));
		if (dcs_reg & (WM8961_DCS_TRIG_STARTUP_HPR |
			       WM8961_DCS_TRIG_STARTUP_HPL))
			dev_err(codec->dev, "DC servo timed out\n");
		else
			dev_dbg(codec->dev, "DC servo startup complete\n");

		/* Enable the output stage */
		hp_reg |= WM8961_HPR_ENA_OUTP | WM8961_HPL_ENA_OUTP;
		snd_soc_write(codec, WM8961_ANALOGUE_HP_0, hp_reg);

		/* Remove the short on the output stage */
		hp_reg |= WM8961_HPR_RMV_SHORT | WM8961_HPL_RMV_SHORT;
		snd_soc_write(codec, WM8961_ANALOGUE_HP_0, hp_reg);
	}

	if (event & SND_SOC_DAPM_PRE_PMD) {
		/* Short the output */
		hp_reg &= ~(WM8961_HPR_RMV_SHORT | WM8961_HPL_RMV_SHORT);
		snd_soc_write(codec, WM8961_ANALOGUE_HP_0, hp_reg);

		/* Disable the output stage */
		hp_reg &= ~(WM8961_HPR_ENA_OUTP | WM8961_HPL_ENA_OUTP);
		snd_soc_write(codec, WM8961_ANALOGUE_HP_0, hp_reg);

		/* Disable DC offset cancellation */
		dcs_reg &= ~(WM8961_DCS_ENA_CHAN_HPR |
			     WM8961_DCS_ENA_CHAN_HPL);
		snd_soc_write(codec, WM8961_DC_SERVO_1, dcs_reg);

		/* Finish up */
		hp_reg &= ~(WM8961_HPR_ENA_DLY | WM8961_HPR_ENA |
			    WM8961_HPL_ENA_DLY | WM8961_HPL_ENA);
		snd_soc_write(codec, WM8961_ANALOGUE_HP_0, hp_reg);

		/* Disable the PGA */
		pwr_reg &= ~(WM8961_LOUT1_PGA | WM8961_ROUT1_PGA);
		snd_soc_write(codec, WM8961_PWR_MGMT_2, pwr_reg);

		/* Disable the charge pump */
		dev_dbg(codec->dev, "Disabling charge pump\n");
		snd_soc_write(codec, WM8961_CHARGE_PUMP_1,
			     cp_reg & ~WM8961_CP_ENA);
	}

	return 0;
}
开发者ID:12rafael,项目名称:jellytimekernel,代码行数:95,代码来源:wm8961.c


示例16: wm8900_hp_event

static int wm8900_hp_event(struct snd_soc_dapm_widget *w,
			   struct snd_kcontrol *kcontrol, int event)
{
	struct snd_soc_codec *codec = w->codec;
	u16 hpctl1 = snd_soc_read(codec, WM8900_REG_HPCTL1);

	switch (event) {
	case SND_SOC_DAPM_PRE_PMU:
		/* Clamp headphone outputs */
		hpctl1 = WM8900_REG_HPCTL1_HP_CLAMP_IP |
			WM8900_REG_HPCTL1_HP_CLAMP_OP;
		snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);
		break;

	case SND_SOC_DAPM_POST_PMU:
		/* Enable the input stage */
		hpctl1 &= ~WM8900_REG_HPCTL1_HP_CLAMP_IP;
		hpctl1 |= WM8900_REG_HPCTL1_HP_SHORT |
			WM8900_REG_HPCTL1_HP_SHORT2 |
			WM8900_REG_HPCTL1_HP_IPSTAGE_ENA;
		snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);

		msleep(400);

		/* Enable the output stage */
		hpctl1 &= ~WM8900_REG_HPCTL1_HP_CLAMP_OP;
		hpctl1 |= WM8900_REG_HPCTL1_HP_OPSTAGE_ENA;
		snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);

		/* Remove the shorts */
		hpctl1 &= ~WM8900_REG_HPCTL1_HP_SHORT2;
		snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);
		hpctl1 &= ~WM8900_REG_HPCTL1_HP_SHORT;
		snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);
		break;

	case SND_SOC_DAPM_PRE_PMD:
		/* Short the output */
		hpctl1 |= WM8900_REG_HPCTL1_HP_SHORT;
		snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);

		/* Disable the output stage */
		hpctl1 &= ~WM8900_REG_HPCTL1_HP_OPSTAGE_ENA;
		snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);

		/* Clamp the outputs and power down input */
		hpctl1 |= WM8900_REG_HPCTL1_HP_CLAMP_IP |
			WM8900_REG_HPCTL1_HP_CLAMP_OP;
		hpctl1 &= ~WM8900_REG_HPCTL1_HP_IPSTAGE_ENA;
		snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);
		break;

	case SND_SOC_DAPM_POST_PMD:
		/* Disable everything */
		snd_soc_write(codec, WM8900_REG_HPCTL1, 0);
		break;

	default:
		BUG();
	}

	return 0;
}
开发者ID:12rafael,项目名称:jellytimekernel,代码行数:63,代码来源:wm8900.c


示例17: wm9081_set_fll


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
C++ snd_soc_register_card函数代码示例发布时间:2022-05-30
下一篇:
C++ snd_soc_platform_get_drvdata函数代码示例发布时间:2022-05-30
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap