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; }
/* * 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; }