示例#1
0
static int jzcodec_soc_dev_setup(struct snd_soc_device *socdev, struct snd_soc_codec *codec)
{
	int ret;

	u16 reg_val;

	socdev->card->codec = codec;
	mutex_init(&codec->mutex);

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

	/* power on device */
	jzcodec_dapm_event(codec, SNDRV_CTL_POWER_D3hot);
  
	/* clear suspend bit of jz4740 internal codec */
	reg_val = jzcodec_read_reg_cache(codec, ICODEC_1_LOW);
	reg_val = reg_val & ~(0x2);
	jzcodec_write(codec, ICODEC_1_LOW, reg_val);
	/* set vol bits */
	reg_val = jzcodec_read_reg_cache(codec, ICODEC_2_LOW);
	reg_val = reg_val | 0x3;
	jzcodec_write(codec, ICODEC_2_LOW, reg_val);
	/* set line in capture gain bits */
	reg_val = jzcodec_read_reg_cache(codec, ICODEC_2_HIGH);
	reg_val = reg_val | 0x1f;
	jzcodec_write(codec, ICODEC_2_HIGH, reg_val);
	/* set mic boost gain bits */
	reg_val = jzcodec_read_reg_cache(codec, ICODEC_2_LOW);
	reg_val = reg_val | (0x3 << 4);
	jzcodec_write(codec, ICODEC_2_LOW, reg_val);
	mdelay(5);
	reg_val = 0x3300;
	jzcodec_write(codec, ICODEC_1_LOW, reg_val);
	reg_val = 0x0003;
	jzcodec_write(codec, ICODEC_1_HIGH, reg_val);
	jzcodec_add_controls(codec);
	jzcodec_add_widgets(codec);

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

card_err:
	snd_soc_free_pcms(socdev);
	snd_soc_dapm_free(socdev);
	
	return ret;
}
示例#2
0
static int jzcodec_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;

	jzcodec_reg_pm[ICODEC_1_LOW] = jzcodec_read_reg_cache(codec, ICODEC_1_LOW);
	jzcodec_reg_pm[ICODEC_1_HIGH] = jzcodec_read_reg_cache(codec, ICODEC_1_HIGH);
	jzcodec_reg_pm[ICODEC_2_LOW] = jzcodec_read_reg_cache(codec, ICODEC_2_LOW);
	jzcodec_reg_pm[ICODEC_2_HIGH] = jzcodec_read_reg_cache(codec, ICODEC_2_HIGH);

	jzcodec_dapm_event(codec, SNDRV_CTL_POWER_D3cold);
	return 0;
}
示例#3
0
static int jzcodec_reset(struct snd_soc_codec *codec)
{
	u16 val;

	val = jzcodec_read_reg_cache(codec, ICODEC_1_LOW);
	val = val | 0x1;
	jzcodec_write(codec, ICODEC_1_LOW, val);
	mdelay(1);
	
	val = jzcodec_read_reg_cache(codec, ICODEC_1_LOW);
	val = val & ~0x1;
	jzcodec_write(codec, ICODEC_1_LOW, val);
	mdelay(1);

	return 0;
}
示例#4
0
static int jzcodec_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;
	u16 reg_val = jzcodec_read_reg_cache(codec, ICODEC_2_LOW);

	/* bit size. codec side */
	switch (params_format(params)) {
	case SNDRV_PCM_FORMAT_S16_LE:
		break;
	}
	/* sample rate */
	reg_val = reg_val & ~(0xf << 8);

	switch (params_rate(params)) {
	case 8000:
		reg_val |= (0x0 << 8);
		break;
	case 11025:
		reg_val |= (0x1 << 8);
		break;
	case 12000:
		reg_val |= (0x2 << 8);
		break;
	case 16000:
		reg_val |= (0x3 << 8);
		break;
	case 22050:
		reg_val |= (0x4 << 8);
		break;
	case 24000:
		reg_val |= (0x5 << 8);
		break;
	case 32000:
		reg_val |= (0x6 << 8);
		break;
	case 44100:
		reg_val |= (0x7 << 8);
		break;
	case 48000:
		reg_val |= (0x8 << 8);
		break;
	default:
		printk(" invalid rate :0x%08x\n",params_rate(params));
	}

        jzcodec_write(codec, ICODEC_2_LOW, reg_val);
	return 0;
}
示例#5
0
static int jzcodec_mute(struct snd_soc_dai *dai, int mute)
{
	struct snd_soc_codec *codec = dai->codec;
	u16 reg_val = jzcodec_read_reg_cache(codec, ICODEC_1_LOW);

	if (mute != 0) 
		mute = 1;
	if (mute)
		reg_val = reg_val | (0x1 << 14);
	else
		reg_val = reg_val & ~(0x1 << 14);
	
	jzcodec_write(codec, ICODEC_1_LOW, reg_val);
	return 0;
}
示例#6
0
/*
 * initialise the JZCODEC driver
 * register the mixer and dsp interfaces with the kernel
 */
static int jzcodec_init(struct snd_soc_device *socdev)
{
	struct snd_soc_codec *codec = socdev->codec;
	int reg, ret = 0;
	u16 reg_val;

	for (reg = 0; reg < JZCODEC_CACHEREGNUM / 2; reg++) {
		switch (reg) {
		case 0:
			jzcodec_reg[reg] = REG_ICDC_CDCCR1;
			jzcodec_reg_LH[ICODEC_1_LOW] = jzcodec_reg[reg] & 0xffff;
			jzcodec_reg_LH[ICODEC_1_HIGH] = (jzcodec_reg[reg] & 0xffff0000) >> 16;
			break;
		case 1:
			jzcodec_reg[reg] = REG_ICDC_CDCCR2;
			jzcodec_reg_LH[ICODEC_2_LOW] = jzcodec_reg[reg] & 0xffff;
			jzcodec_reg_LH[ICODEC_2_HIGH] = (jzcodec_reg[reg] & 0xffff0000) >> 16;
			break;
		}
	}

	codec->name = "JZCODEC";
	codec->owner = THIS_MODULE;
	codec->read = jzcodec_read_reg_cache;
	codec->write = jzcodec_write;
	codec->dapm_event = jzcodec_dapm_event;
	codec->dai = &jzcodec_dai;
	codec->num_dai = 1;
	codec->reg_cache_size = sizeof(jzcodec_reg_LH);
	codec->reg_cache = kmemdup(jzcodec_reg_LH, sizeof(jzcodec_reg_LH), GFP_KERNEL);
	if (codec->reg_cache == NULL)
		return -ENOMEM;
       
	jzcodec_reset(codec);
	/* register pcms */
	ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
	if (ret < 0) {
		printk(KERN_ERR "jzcodec: failed to create pcms\n");
		goto pcm_err;
	}

	/* power on device */
	jzcodec_dapm_event(codec, SNDRV_CTL_POWER_D3hot);
  
	/* clear suspend bit of jz4740 internal codec */
	reg_val = jzcodec_read_reg_cache(codec, ICODEC_1_LOW);
	reg_val = reg_val & ~(0x2);
	jzcodec_write(codec, ICODEC_1_LOW, reg_val);
	/* set vol bits */
	reg_val = jzcodec_read_reg_cache(codec, ICODEC_2_LOW);
	reg_val = reg_val | 0x3;
	jzcodec_write(codec, ICODEC_2_LOW, reg_val);
	/* set line in capture gain bits */
	reg_val = jzcodec_read_reg_cache(codec, ICODEC_2_HIGH);
	reg_val = reg_val | 0x1f;
	jzcodec_write(codec, ICODEC_2_HIGH, reg_val);
	/* set mic boost gain bits */
	reg_val = jzcodec_read_reg_cache(codec, ICODEC_2_LOW);
	reg_val = reg_val | (0x3 << 4);
	jzcodec_write(codec, ICODEC_2_LOW, reg_val);
	mdelay(5);
	reg_val = 0x3300;
	jzcodec_write(codec, ICODEC_1_LOW, reg_val);
	reg_val = 0x0003;
	jzcodec_write(codec, ICODEC_1_HIGH, reg_val);
	jzcodec_add_controls(codec);
	jzcodec_add_widgets(codec);

	ret = snd_soc_register_card(socdev);
	if (ret < 0) {
		printk(KERN_ERR "jzcodec: 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;
}