static int tegra_max98095_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dapm_context *dapm = &codec->dapm; struct snd_soc_card *card = codec->card; struct tegra_max98095 *machine = snd_soc_card_get_drvdata(card); struct tegra_asoc_platform_data *pdata = machine->pdata; #ifndef CONFIG_ARCH_TEGRA_2x_SOC struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(rtd->cpu_dai); #endif int ret; #ifndef CONFIG_ARCH_TEGRA_2x_SOC if (machine->codec_info[BASEBAND].i2s_id != -1) i2s->is_dam_used = true; #endif if (machine->init_done) return 0; machine->init_done = true; if (gpio_is_valid(pdata->gpio_spkr_en)) { ret = gpio_request(pdata->gpio_spkr_en, "spkr_en"); if (ret) { dev_err(card->dev, "cannot get spkr_en gpio\n"); return ret; } machine->gpio_requested |= GPIO_SPKR_EN; gpio_direction_output(pdata->gpio_spkr_en, 0); } if (gpio_is_valid(pdata->gpio_hp_mute)) { ret = gpio_request(pdata->gpio_hp_mute, "hp_mute"); if (ret) { dev_err(card->dev, "cannot get hp_mute gpio\n"); return ret; } machine->gpio_requested |= GPIO_HP_MUTE; gpio_direction_output(pdata->gpio_hp_mute, 0); } if (gpio_is_valid(pdata->gpio_int_mic_en)) { ret = gpio_request(pdata->gpio_int_mic_en, "int_mic_en"); if (ret) { dev_err(card->dev, "cannot get int_mic_en gpio\n"); return ret; } machine->gpio_requested |= GPIO_INT_MIC_EN; /* Disable int mic; enable signal is active-high */ gpio_direction_output(pdata->gpio_int_mic_en, 0); } if (gpio_is_valid(pdata->gpio_ext_mic_en)) { ret = gpio_request(pdata->gpio_ext_mic_en, "ext_mic_en"); if (ret) { dev_err(card->dev, "cannot get ext_mic_en gpio\n"); return ret; } machine->gpio_requested |= GPIO_EXT_MIC_EN; /* Enable ext mic; enable signal is active-low */ gpio_direction_output(pdata->gpio_ext_mic_en, 0); } ret = snd_soc_add_controls(codec, tegra_max98095_controls, ARRAY_SIZE(tegra_max98095_controls)); if (ret < 0) return ret; snd_soc_dapm_new_controls(dapm, tegra_max98095_dapm_widgets, ARRAY_SIZE(tegra_max98095_dapm_widgets)); snd_soc_dapm_add_routes(dapm, enterprise_audio_map, ARRAY_SIZE(enterprise_audio_map)); ret = snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET, &tegra_max98095_hp_jack); if (ret < 0) return ret; #ifdef CONFIG_SWITCH snd_soc_jack_notifier_register(&tegra_max98095_hp_jack, &headset_switch_nb); #else /*gpio based headset detection*/ snd_soc_jack_add_pins(&tegra_max98095_hp_jack, ARRAY_SIZE(tegra_max98095_hp_jack_pins), tegra_max98095_hp_jack_pins); #endif ret = tegra_asoc_utils_register_ctls(&machine->util_data); if (ret < 0) return ret; /* max98095_headset_detect(codec, &tegra_max98095_hp_jack, SND_JACK_HEADSET); */ snd_soc_dapm_nc_pin(dapm, "INA1"); snd_soc_dapm_nc_pin(dapm, "INA2"); snd_soc_dapm_nc_pin(dapm, "INB1"); snd_soc_dapm_nc_pin(dapm, "INB2"); snd_soc_dapm_sync(dapm); return 0; }
static int tegra_aic326x_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dapm_context *dapm = &codec->dapm; struct snd_soc_card *card = codec->card; struct tegra_aic326x *machine = snd_soc_card_get_drvdata(card); struct tegra_asoc_platform_data *pdata = machine->pdata; #ifndef CONFIG_ARCH_TEGRA_2x_SOC struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(rtd->cpu_dai); #endif int ret; #ifndef CONFIG_ARCH_TEGRA_2x_SOC if (machine->codec_info[BASEBAND].i2s_id != -1) i2s->is_dam_used = true; #endif if (machine->init_done) return 0; machine->init_done = true; #ifndef CONFIG_ARCH_TEGRA_2x_SOC machine->pcard = card; #endif if (machine_is_whistler()) { machine->audio_reg = regulator_get(NULL, "avddio_audio"); if (IS_ERR(machine->audio_reg)) { dev_err(card->dev, "cannot get avddio_audio reg\n"); ret = PTR_ERR(machine->audio_reg); return ret; } ret = regulator_enable(machine->audio_reg); if (ret) { dev_err(card->dev, "cannot enable avddio_audio reg\n"); regulator_put(machine->audio_reg); machine->audio_reg = NULL; return ret; } } if (gpio_is_valid(pdata->gpio_spkr_en)) { ret = gpio_request(pdata->gpio_spkr_en, "spkr_en"); if (ret) { dev_err(card->dev, "cannot get spkr_en gpio\n"); return ret; } machine->gpio_requested |= GPIO_SPKR_EN; gpio_direction_output(pdata->gpio_spkr_en, 0); } if (gpio_is_valid(pdata->gpio_hp_mute)) { ret = gpio_request(pdata->gpio_hp_mute, "hp_mute"); if (ret) { dev_err(card->dev, "cannot get hp_mute gpio\n"); return ret; } machine->gpio_requested |= GPIO_HP_MUTE; gpio_direction_output(pdata->gpio_hp_mute, 0); } if (gpio_is_valid(pdata->gpio_int_mic_en)) { ret = gpio_request(pdata->gpio_int_mic_en, "int_mic_en"); if (ret) { dev_err(card->dev, "cannot get int_mic_en gpio\n"); return ret; } machine->gpio_requested |= GPIO_INT_MIC_EN; /* Disable int mic; enable signal is active-high */ gpio_direction_output(pdata->gpio_int_mic_en, 0); } if (gpio_is_valid(pdata->gpio_ext_mic_en)) { ret = gpio_request(pdata->gpio_ext_mic_en, "ext_mic_en"); if (ret) { dev_err(card->dev, "cannot get ext_mic_en gpio\n"); return ret; } machine->gpio_requested |= GPIO_EXT_MIC_EN; /* Enable ext mic; enable signal is active-low */ gpio_direction_output(pdata->gpio_ext_mic_en, 0); } ret = snd_soc_add_card_controls(card, tegra_aic326x_controls, ARRAY_SIZE(tegra_aic326x_controls)); if (ret < 0) return ret; snd_soc_dapm_new_controls(dapm, tegra_aic326x_dapm_widgets, ARRAY_SIZE(tegra_aic326x_dapm_widgets)); snd_soc_dapm_add_routes(dapm, aic326x_audio_map, ARRAY_SIZE(aic326x_audio_map)); ret = snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET, &tegra_aic326x_hp_jack); if (ret < 0) return ret; if (gpio_is_valid(pdata->gpio_hp_det)) { /* Headphone detection */ tegra_aic326x_hp_jack_gpio.gpio = pdata->gpio_hp_det; snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADSET, &tegra_aic326x_hp_jack); #ifndef CONFIG_SWITCH snd_soc_jack_add_pins(&tegra_aic326x_hp_jack, ARRAY_SIZE(tegra_aic326x_hp_jack_pins), tegra_aic326x_hp_jack_pins); #else snd_soc_jack_notifier_register(&tegra_aic326x_hp_jack, &aic326x_headset_switch_nb); #endif snd_soc_jack_add_gpios(&tegra_aic326x_hp_jack, 1, &tegra_aic326x_hp_jack_gpio); machine->gpio_requested |= GPIO_HP_DET; } #ifndef CONFIG_ARCH_TEGRA_11x_SOC /* update jack status during boot */ aic3262_hs_jack_detect(codec, &tegra_aic326x_hp_jack, SND_JACK_HEADSET); #endif /* Add call mode switch control */ ret = snd_ctl_add(codec->card->snd_card, snd_ctl_new1(&tegra_aic326x_call_mode_control, machine)); if (ret < 0) return ret; ret = tegra_asoc_utils_register_ctls(&machine->util_data); if (ret < 0) return ret; return 0; }
int ctp_init(struct snd_soc_pcm_runtime *runtime) { int ret; struct snd_soc_codec *codec = runtime->codec; struct snd_soc_dapm_context *dapm = &codec->dapm; struct snd_soc_card *card = runtime->card; struct ctp_mc_private *ctx = snd_soc_card_get_drvdata(runtime->card); //#ifndef UART_DEBUG // static int hp_enable; //#endif pr_debug("%s\n", __func__); /* Set codec bias level */ ctp_set_bias_level(card, dapm, SND_SOC_BIAS_OFF); card->dapm.idle_bias_off = true; /* Add Jack specific widgets */ ret = snd_soc_dapm_new_controls(dapm, ctp_dapm_widgets, ARRAY_SIZE(ctp_dapm_widgets)); if (ret) return ret; /* Set up Jack specific audio path audio_map */ snd_soc_dapm_add_routes(dapm, ctp_audio_map, ARRAY_SIZE(ctp_audio_map)); /* Add Comms specefic controls */ ctx->comms_ctl.ssp_bt_sco_master_mode = false; /* Set ssp_voip to master mode by default */ #if 0 ctx->comms_ctl.ssp_voip_master_mode = false; #else ctx->comms_ctl.ssp_voip_master_mode = true; pr_debug("ctp_init ssp_voip_master_mode %d\n", ctx->comms_ctl.ssp_voip_master_mode); #endif ctx->comms_ctl.ssp_modem_master_mode = false; ret = snd_soc_add_card_controls(card, ssp_comms_controls, ARRAY_SIZE(ssp_comms_controls)); if (ret) { pr_err("Add Comms Controls failed %d", ret); return ret; } /* Keep the voice call paths active during suspend. Mark the end points ignore_suspend */ snd_soc_dapm_ignore_suspend(dapm, "HPOL"); snd_soc_dapm_ignore_suspend(dapm, "HPOR"); snd_soc_dapm_ignore_suspend(dapm, "SPOL"); snd_soc_dapm_ignore_suspend(dapm, "SPOR"); snd_soc_dapm_ignore_suspend(dapm, "AIF2 Playback"); snd_soc_dapm_ignore_suspend(dapm, "AIF2 Capture"); snd_soc_dapm_ignore_suspend(dapm, "AIF2TX"); snd_soc_dapm_ignore_suspend(dapm, "AIF2RX"); snd_soc_dapm_ignore_suspend(dapm, "MonoP"); snd_soc_dapm_ignore_suspend(dapm, "MonoN"); snd_soc_dapm_ignore_suspend(dapm, "Headset Mic"); snd_soc_dapm_ignore_suspend(dapm, "Headphone"); snd_soc_dapm_ignore_suspend(dapm, "Ext Spk"); snd_soc_dapm_ignore_suspend(dapm, "Int Mic"); snd_soc_dapm_ignore_suspend(dapm, "Receiver"); snd_soc_dapm_ignore_suspend(dapm, "DMIC L2"); snd_soc_dapm_ignore_suspend(dapm, "DMIC R2"); snd_soc_dapm_ignore_suspend(dapm, "IN1P"); snd_soc_dapm_ignore_suspend(dapm, "IN1N"); snd_soc_dapm_ignore_suspend(dapm, "IN2P"); snd_soc_dapm_ignore_suspend(dapm, "IN2N"); snd_soc_dapm_enable_pin(dapm, "Headset Mic"); snd_soc_dapm_enable_pin(dapm, "Headphone"); snd_soc_dapm_enable_pin(dapm, "Ext Spk"); snd_soc_dapm_enable_pin(dapm, "Int Mic"); snd_soc_dapm_enable_pin(dapm, "Receiver"); mutex_lock(&codec->mutex); snd_soc_dapm_sync(dapm); mutex_unlock(&codec->mutex); /*Register switch Control as misc driver*/ ret = misc_register(&switch_ctrl); if (ret) pr_err("%s: couldn't register control device\n", __func__); rt5647_codec = codec; //#ifndef UART_DEBUG // /* use hard-coded GPIO value before IFWI ready */ // /* hp_enable = get_gpio_by_name("AUDIO_DEBUG"); */ // hp_enable = 172; // if (hp_enable > 0) { // pr_info("Get AUDIO_DEBUG name!\n"); // ret = gpio_request_one(hp_enable, GPIOF_DIR_OUT, "AUDIO_DEBUG"); // if (ret) // pr_err("gpio_request AUDIO_DEBUG failed!\n"); // // /*Set GPIO O(H) to default => Low:UART; High:headset */ // gpio_direction_output(hp_enable, 1); // pr_info("AUDIO_DEBUG value = %d\n", gpio_get_value(hp_enable)); // } else // pr_err("get_gpio AUDIO_DEBUG failed!\n"); //#endif return ret; }
static int aml_asoc_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; struct snd_soc_codec *codec = rtd->codec; //struct snd_soc_dai *codec_dai = rtd->codec_dai; struct snd_soc_dapm_context *dapm = &codec->dapm; struct aml_audio_private_data * p_aml_audio; int ret = 0; printk(KERN_DEBUG "enter %s \n", __func__); p_aml_audio = snd_soc_card_get_drvdata(card); /* Add specific widgets */ // snd_soc_dapm_new_controls(dapm, aml_asoc_dapm_widgets, // ARRAY_SIZE(aml_asoc_dapm_widgets)); /* set ADCLRC/GPIO1 Pin Function Select */ snd_soc_update_bits(codec, WM8960_IFACE2, (1 << 6), (1 << 6)); /* not connected */ snd_soc_dapm_nc_pin(dapm, "LINPUT3"); snd_soc_dapm_nc_pin(dapm, "RINPUT3"); snd_soc_dapm_nc_pin(dapm, "OUT3"); /* always connected */ snd_soc_dapm_enable_pin(dapm, "Ext Spk"); snd_soc_dapm_enable_pin(dapm, "Mic"); /* disable connected */ snd_soc_dapm_disable_pin(dapm, "HP"); snd_soc_dapm_sync(dapm); ret = snd_soc_jack_new(codec, "hp switch", SND_JACK_HEADPHONE, &p_aml_audio->jack); if (ret) { printk(KERN_WARNING "Failed to alloc resource for hp switch\n"); } else { ret = snd_soc_jack_add_pins(&p_aml_audio->jack, ARRAY_SIZE(jack_pins), jack_pins); if (ret) { printk(KERN_WARNING "Failed to setup hp pins\n"); } } #if HP_IRQ p_aml_audio->gpio_hp_det = of_get_named_gpio(card->dev->of_node,"wm8960_gpio",0); if (gpio_is_valid(p_aml_audio->gpio_hp_det)) { aml_audio_hp_jack_gpio.gpio = p_aml_audio->gpio_hp_det; snd_soc_jack_add_gpios(&p_aml_audio->jack, 1, &aml_audio_hp_jack_gpio); } #endif #if HP_DET init_timer(&p_aml_audio->timer); p_aml_audio->timer.function = aml_asoc_timer_func; p_aml_audio->timer.data = (unsigned long)p_aml_audio; p_aml_audio->data= (void*)card; INIT_WORK(&p_aml_audio->work, aml_asoc_work_func); mutex_init(&p_aml_audio->lock); mutex_lock(&p_aml_audio->lock); if (!p_aml_audio->timer_en) { aml_audio_start_timer(p_aml_audio, msecs_to_jiffies(100)); } mutex_unlock(&p_aml_audio->lock); #endif //p_aml_audio->dis_hp_det = of_property_read_bool(card->dev->of_node,"dis_hp_det"); ret = of_property_read_u32(card->dev->of_node,"dis_hp_det",(u32 *)&p_aml_audio->dis_hp_det); printk("******p_aml_audio->dis_hp_det=%d***\n",p_aml_audio->dis_hp_det); if(ret){ printk("don't find match dis_hp_det\n"); goto out1; } if(!p_aml_audio->dis_hp_det){ printk("****mm**p_aml_audio->dis_hp_det\n"); //JD2 as headphone detect snd_soc_update_bits(codec,27, 0x008, 0x008);// OUT3 buffer Enabled and disabled with HPL and HPR jack detect //INSERT_DELAY [1] mdelay(1); ///GPIO1 output the "jack detect output" snd_soc_update_bits(codec,48, 0x03A, 0x03A);// JD2 used for Jack Detect Input, GPIO function = jack detect output snd_soc_update_bits(codec,24, 0x040, 0x040);// HPDETECT LOW = Speaker snd_soc_update_bits(codec, 23, 0x1D1, 0x1D1); mdelay(500); } out1: return 0; }
static int ctp_comms_dai_link_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_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_card *soc_card = rtd->card; struct ctp_mc_private *ctx = snd_soc_card_get_drvdata(soc_card); struct comms_mc_private *ctl = &(ctx->comms_ctl); int ret = 0; unsigned int tx_mask, rx_mask; unsigned int nb_slot = 0; unsigned int slot_width = 0; unsigned int tristate_offset = 0; unsigned int device = substream->pcm->device; pr_debug("ssp_bt_sco_master_mode %d\n", ctl->ssp_bt_sco_master_mode); pr_debug("ssp_voip_master_mode %d\n", ctl->ssp_voip_master_mode); pr_debug("ssp_modem_master_mode %d\n", ctl->ssp_modem_master_mode); switch (device) { case CTP_HT_COMMS_VOIP_DEV: /* * set cpu DAI configuration * frame_format = PSP_FORMAT * ssp_serial_clk_mode = SSP_CLK_MODE_0 * ssp_frmsync_pol_bit = SSP_FRMS_ACTIVE_LOW */ ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | SSP_DAI_SCMODE_0 | SND_SOC_DAIFMT_NB_IF | (ctl->ssp_voip_master_mode ? SND_SOC_DAIFMT_CBM_CFM : SND_SOC_DAIFMT_CBS_CFS)); if (ret < 0) { pr_err("MFLD Comms Machine: Set FMT Fails %d\n", ret); return -EINVAL; } /* * MSIC VOIP SSP Config * ssp_active_tx_slots_map = 0x01 * ssp_active_rx_slots_map = 0x01 * frame_rate_divider_control = 1 * data_size = 32 * tristate = 1 * ssp_frmsync_timing_bit = 0, for SLAVE * (NEXT_FRMS_ASS_AFTER_END_OF_T4) * ssp_frmsync_timing_bit = 1, for MASTER * (NEXT_FRMS_ASS_WITH_LSB_PREVIOUS_FRM) * * */ nb_slot = SSP_VOIP_SLOT_NB_SLOT; slot_width = SSP_VOIP_SLOT_WIDTH; tx_mask = SSP_VOIP_SLOT_TX_MASK; rx_mask = SSP_VOIP_SLOT_RX_MASK; tristate_offset = BIT(TRISTATE_BIT); break; default: pr_err("CTP Comms Machine: bad PCM Device ID = %d\n", device); return -EINVAL; } ret = snd_soc_dai_set_tdm_slot(cpu_dai, tx_mask, rx_mask, nb_slot, slot_width); if (ret < 0) { pr_err("CTP Comms Machine: Set TDM Slot Fails %d\n", ret); return -EINVAL; } ret = snd_soc_dai_set_tristate(cpu_dai, tristate_offset); if (ret < 0) { pr_err("CTP Comms Machine: Set Tristate Fails %d\n", ret); return -EINVAL; } if (device == CTP_HT_COMMS_VOIP_DEV) { pr_debug("Call ctp_wm5102_hw_params to enable the PLL Codec\n"); ctp_wm5102_hw_params(substream, params); } pr_debug("CTP Comms Machine: slot_width = %d\n", slot_width); pr_debug("CTP Comms Machine: tx_mask = %d\n", tx_mask); pr_debug("CTP Comms Machine: rx_mask = %d\n", rx_mask); pr_debug("CTP Comms Machine: tristate_offset = %d\n", tristate_offset); return 0; } /* ctp_comms_dai_link_hw_params*/
static int apq8016_sbc_dai_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_component *component; struct snd_soc_dai_link *dai_link = rtd->dai_link; struct snd_soc_card *card = rtd->card; struct apq8016_sbc_data *pdata = snd_soc_card_get_drvdata(card); int i, rval; switch (cpu_dai->id) { case MI2S_PRIMARY: writel(readl(pdata->spkr_iomux) | SPKR_CTL_PRI_WS_SLAVE_SEL_11, pdata->spkr_iomux); break; case MI2S_QUATERNARY: /* Configure the Quat MI2S to TLMM */ writel(readl(pdata->mic_iomux) | MIC_CTRL_QUA_WS_SLAVE_SEL_10 | MIC_CTRL_TLMM_SCLK_EN, pdata->mic_iomux); break; case MI2S_TERTIARY: writel(readl(pdata->mic_iomux) | MIC_CTRL_TER_WS_SLAVE_SEL | MIC_CTRL_TLMM_SCLK_EN, pdata->mic_iomux); break; default: dev_err(card->dev, "unsupported cpu dai configuration\n"); return -EINVAL; } if (!pdata->jack_setup) { struct snd_jack *jack; rval = snd_soc_card_jack_new(card, "Headset Jack", SND_JACK_HEADSET | SND_JACK_HEADPHONE | SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2 | SND_JACK_BTN_3 | SND_JACK_BTN_4, &pdata->jack, NULL, 0); if (rval < 0) { dev_err(card->dev, "Unable to add Headphone Jack\n"); return rval; } jack = pdata->jack.jack; snd_jack_set_key(jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); snd_jack_set_key(jack, SND_JACK_BTN_1, KEY_VOICECOMMAND); snd_jack_set_key(jack, SND_JACK_BTN_2, KEY_VOLUMEUP); snd_jack_set_key(jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); pdata->jack_setup = true; } for (i = 0 ; i < dai_link->num_codecs; i++) { struct snd_soc_dai *dai = rtd->codec_dais[i]; component = dai->component; /* Set default mclk for internal codec */ rval = snd_soc_component_set_sysclk(component, 0, 0, DEFAULT_MCLK_RATE, SND_SOC_CLOCK_IN); if (rval != 0 && rval != -ENOTSUPP) { dev_warn(card->dev, "Failed to set mclk: %d\n", rval); return rval; } rval = snd_soc_component_set_jack(component, &pdata->jack, NULL); if (rval != 0 && rval != -ENOTSUPP) { dev_warn(card->dev, "Failed to set jack: %d\n", rval); return rval; } } return 0; }
static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dapm_context *dapm = &codec->dapm; struct snd_soc_card *card = codec->card; struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); struct tegra_wm8903_platform_data *pdata = machine->pdata; int ret; machine->bias_level = SND_SOC_BIAS_STANDBY; ///Eric Mycodec = codec; ///Eric if (gpio_is_valid(pdata->gpio_spkr_en)) { ret = gpio_request(pdata->gpio_spkr_en, "spkr_en"); if (ret) { dev_err(card->dev, "cannot get spkr_en gpio\n"); return ret; } machine->gpio_requested |= GPIO_SPKR_EN; gpio_direction_output(pdata->gpio_spkr_en, 0); } if (gpio_is_valid(pdata->gpio_hp_mute)) { ret = gpio_request(pdata->gpio_hp_mute, "hp_mute"); if (ret) { dev_err(card->dev, "cannot get hp_mute gpio\n"); return ret; } machine->gpio_requested |= GPIO_HP_MUTE; gpio_direction_output(pdata->gpio_hp_mute, 0); } if (gpio_is_valid(pdata->gpio_int_mic_en)) { ret = gpio_request(pdata->gpio_int_mic_en, "int_mic_en"); if (ret) { dev_err(card->dev, "cannot get int_mic_en gpio\n"); return ret; } machine->gpio_requested |= GPIO_INT_MIC_EN; /* Disable int mic; enable signal is active-high */ gpio_direction_output(pdata->gpio_int_mic_en, 0); } if (gpio_is_valid(pdata->gpio_ext_mic_en)) { ret = gpio_request(pdata->gpio_ext_mic_en, "ext_mic_en"); if (ret) { dev_err(card->dev, "cannot get ext_mic_en gpio\n"); return ret; } machine->gpio_requested |= GPIO_EXT_MIC_EN; /* Enable ext mic; enable signal is active-low */ gpio_direction_output(pdata->gpio_ext_mic_en, 0); } if (machine_is_cardhu() || machine_is_ventana()) { ret = snd_soc_add_controls(codec, cardhu_controls, ARRAY_SIZE(cardhu_controls)); if (ret < 0) return ret; snd_soc_dapm_new_controls(dapm, cardhu_dapm_widgets, ARRAY_SIZE(cardhu_dapm_widgets)); } else { ret = snd_soc_add_controls(codec, tegra_wm8903_default_controls, ARRAY_SIZE(tegra_wm8903_default_controls)); if (ret < 0) return ret; snd_soc_dapm_new_controls(dapm, tegra_wm8903_default_dapm_widgets, ARRAY_SIZE(tegra_wm8903_default_dapm_widgets)); } if (machine_is_harmony()) { snd_soc_dapm_add_routes(dapm, harmony_audio_map, ARRAY_SIZE(harmony_audio_map)); } else if (machine_is_cardhu() || machine_is_ventana()) { snd_soc_dapm_add_routes(dapm, cardhu_audio_map, ARRAY_SIZE(cardhu_audio_map)); } else if (machine_is_seaboard()) { snd_soc_dapm_add_routes(dapm, seaboard_audio_map, ARRAY_SIZE(seaboard_audio_map)); } else if (machine_is_kaen()) { snd_soc_dapm_add_routes(dapm, kaen_audio_map, ARRAY_SIZE(kaen_audio_map)); } else { snd_soc_dapm_add_routes(dapm, aebl_audio_map, ARRAY_SIZE(aebl_audio_map)); } if (gpio_is_valid(pdata->gpio_hp_det)) { tegra_wm8903_hp_jack_gpio.gpio = pdata->gpio_hp_det; snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE, &tegra_wm8903_hp_jack); #ifndef CONFIG_SWITCH snd_soc_jack_add_pins(&tegra_wm8903_hp_jack, ARRAY_SIZE(tegra_wm8903_hp_jack_pins), tegra_wm8903_hp_jack_pins); #else snd_soc_jack_notifier_register(&tegra_wm8903_hp_jack, &tegra_wm8903_jack_detect_nb); #endif snd_soc_jack_add_gpios(&tegra_wm8903_hp_jack, 1, &tegra_wm8903_hp_jack_gpio); machine->gpio_requested |= GPIO_HP_DET; } snd_soc_jack_new(codec, "Mic Jack", SND_JACK_MICROPHONE, &tegra_wm8903_mic_jack); #ifndef CONFIG_SWITCH snd_soc_jack_add_pins(&tegra_wm8903_mic_jack, ARRAY_SIZE(tegra_wm8903_mic_jack_pins), tegra_wm8903_mic_jack_pins); #else snd_soc_jack_notifier_register(&tegra_wm8903_mic_jack, &tegra_wm8903_jack_detect_nb); #endif wm8903_mic_detect(codec, &tegra_wm8903_mic_jack, SND_JACK_MICROPHONE, machine_is_cardhu() ? SND_JACK_MICROPHONE : 0); snd_soc_dapm_force_enable_pin(dapm, "Mic Bias"); /* FIXME: Calculate automatically based on DAPM routes? */ /* if (!machine_is_harmony() && !machine_is_ventana() && !machine_is_cardhu()) snd_soc_dapm_nc_pin(dapm, "IN1L"); if (!machine_is_seaboard() && !machine_is_aebl() && !machine_is_cardhu()) snd_soc_dapm_nc_pin(dapm, "IN1R"); snd_soc_dapm_nc_pin(dapm, "IN2L"); if (!machine_is_kaen()) snd_soc_dapm_nc_pin(dapm, "IN2R");*/ ///Eric snd_soc_dapm_nc_pin(dapm, "IN1L"); snd_soc_dapm_nc_pin(dapm, "IN1R"); ///Eric snd_soc_dapm_nc_pin(dapm, "IN3L"); snd_soc_dapm_nc_pin(dapm, "IN3R"); if (machine_is_aebl()) { snd_soc_dapm_nc_pin(dapm, "LON"); snd_soc_dapm_nc_pin(dapm, "RON"); snd_soc_dapm_nc_pin(dapm, "ROP"); snd_soc_dapm_nc_pin(dapm, "LOP"); } else { snd_soc_dapm_nc_pin(dapm, "LINEOUTR"); snd_soc_dapm_nc_pin(dapm, "LINEOUTL"); } snd_soc_dapm_sync(dapm); return 0; }
static int byt_rt5651_init(struct snd_soc_pcm_runtime *runtime) { struct snd_soc_card *card = runtime->card; struct snd_soc_component *codec = runtime->codec_dai->component; struct byt_rt5651_private *priv = snd_soc_card_get_drvdata(card); const struct snd_soc_dapm_route *custom_map; int num_routes; int ret; card->dapm.idle_bias_off = true; /* Start with RC clk for jack-detect (we disable MCLK below) */ if (byt_rt5651_quirk & BYT_RT5651_MCLK_EN) snd_soc_component_update_bits(codec, RT5651_GLB_CLK, RT5651_SCLK_SRC_MASK, RT5651_SCLK_SRC_RCCLK); switch (BYT_RT5651_MAP(byt_rt5651_quirk)) { case BYT_RT5651_IN1_MAP: custom_map = byt_rt5651_intmic_in1_map; num_routes = ARRAY_SIZE(byt_rt5651_intmic_in1_map); break; case BYT_RT5651_IN2_MAP: custom_map = byt_rt5651_intmic_in2_map; num_routes = ARRAY_SIZE(byt_rt5651_intmic_in2_map); break; case BYT_RT5651_IN1_IN2_MAP: custom_map = byt_rt5651_intmic_in1_in2_map; num_routes = ARRAY_SIZE(byt_rt5651_intmic_in1_in2_map); break; default: custom_map = byt_rt5651_intmic_dmic_map; num_routes = ARRAY_SIZE(byt_rt5651_intmic_dmic_map); } ret = snd_soc_dapm_add_routes(&card->dapm, custom_map, num_routes); if (ret) return ret; if (byt_rt5651_quirk & BYT_RT5651_SSP2_AIF2) { ret = snd_soc_dapm_add_routes(&card->dapm, byt_rt5651_ssp2_aif2_map, ARRAY_SIZE(byt_rt5651_ssp2_aif2_map)); } else if (byt_rt5651_quirk & BYT_RT5651_SSP0_AIF1) { ret = snd_soc_dapm_add_routes(&card->dapm, byt_rt5651_ssp0_aif1_map, ARRAY_SIZE(byt_rt5651_ssp0_aif1_map)); } else if (byt_rt5651_quirk & BYT_RT5651_SSP0_AIF2) { ret = snd_soc_dapm_add_routes(&card->dapm, byt_rt5651_ssp0_aif2_map, ARRAY_SIZE(byt_rt5651_ssp0_aif2_map)); } else { ret = snd_soc_dapm_add_routes(&card->dapm, byt_rt5651_ssp2_aif1_map, ARRAY_SIZE(byt_rt5651_ssp2_aif1_map)); } if (ret) return ret; ret = snd_soc_add_card_controls(card, byt_rt5651_controls, ARRAY_SIZE(byt_rt5651_controls)); if (ret) { dev_err(card->dev, "unable to add card controls\n"); return ret; } snd_soc_dapm_ignore_suspend(&card->dapm, "Headphone"); snd_soc_dapm_ignore_suspend(&card->dapm, "Speaker"); if (byt_rt5651_quirk & BYT_RT5651_MCLK_EN) { /* * The firmware might enable the clock at * boot (this information may or may not * be reflected in the enable clock register). * To change the rate we must disable the clock * first to cover these cases. Due to common * clock framework restrictions that do not allow * to disable a clock that has not been enabled, * we need to enable the clock first. */ ret = clk_prepare_enable(priv->mclk); if (!ret) clk_disable_unprepare(priv->mclk); if (byt_rt5651_quirk & BYT_RT5651_MCLK_25MHZ) ret = clk_set_rate(priv->mclk, 25000000); else ret = clk_set_rate(priv->mclk, 19200000); if (ret) dev_err(card->dev, "unable to set MCLK rate\n"); } if (BYT_RT5651_JDSRC(byt_rt5651_quirk)) { ret = snd_soc_card_jack_new(runtime->card, "Headset", SND_JACK_HEADSET | SND_JACK_BTN_0, &priv->jack, bytcr_jack_pins, ARRAY_SIZE(bytcr_jack_pins)); if (ret) { dev_err(runtime->dev, "jack creation failed %d\n", ret); return ret; } snd_jack_set_key(priv->jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); ret = snd_soc_component_set_jack(codec, &priv->jack, NULL); if (ret) return ret; } return 0; }
static int tegra_rt5631_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_dai *codec_dai = rtd->codec_dai; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_codec *codec = rtd->codec; struct snd_soc_card *card = codec->card; struct tegra_rt5631 *machine = snd_soc_card_get_drvdata(card); int srate, mclk, i2s_daifmt; int err; srate = params_rate(params); switch (srate) { case 64000: case 88200: case 96000: mclk = 128 * srate; break; default: mclk = 384 * srate; break; } /* FIXME: Codec only requires >= 3MHz if OSR==0 */ while (mclk < 6000000) mclk *= 2; err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk); if (err < 0) { dev_err(card->dev, "Can't configure clocks\n"); return err; } i2s_daifmt = SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS; /* Use DSP mode for mono on Tegra20 */ if ((params_channels(params) != 2) && (machine_is_ventana() || machine_is_harmony() || machine_is_kaen() || machine_is_aebl())) i2s_daifmt |= SND_SOC_DAIFMT_DSP_A; else i2s_daifmt |= SND_SOC_DAIFMT_I2S; err = snd_soc_dai_set_fmt(codec_dai, i2s_daifmt); if (err < 0) { dev_err(card->dev, "codec_dai fmt not set\n"); return err; } err = snd_soc_dai_set_fmt(cpu_dai, i2s_daifmt); if (err < 0) { dev_err(card->dev, "cpu_dai fmt not set\n"); return err; } err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk, SND_SOC_CLOCK_IN); if (err < 0) { dev_err(card->dev, "codec_dai clock not set\n"); return err; } return 0; }
static int tegra_aic326x_voice_call_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_dai *codec_dai = rtd->codec_dai; struct snd_soc_codec *codec = rtd->codec; struct snd_soc_card *card = codec->card; struct tegra_aic326x *machine = snd_soc_card_get_drvdata(card); struct tegra_asoc_platform_data *pdata = machine->pdata; int srate, mclk, rate, i2s_daifmt; int err, pcmdiv, vxclkdiv; srate = params_rate(params); mclk = tegra_aic326x_get_mclk(srate); if (mclk < 0) return mclk; i2s_daifmt = SND_SOC_DAIFMT_NB_NF; i2s_daifmt |= pdata->i2s_param[VOICE_CODEC].is_i2s_master ? SND_SOC_DAIFMT_CBS_CFS : SND_SOC_DAIFMT_CBM_CFM; switch (pdata->i2s_param[VOICE_CODEC].i2s_mode) { case TEGRA_DAIFMT_I2S: i2s_daifmt |= SND_SOC_DAIFMT_I2S; break; case TEGRA_DAIFMT_DSP_A: i2s_daifmt |= SND_SOC_DAIFMT_DSP_A; break; case TEGRA_DAIFMT_DSP_B: i2s_daifmt |= SND_SOC_DAIFMT_DSP_B; break; case TEGRA_DAIFMT_LEFT_J: i2s_daifmt |= SND_SOC_DAIFMT_LEFT_J; break; case TEGRA_DAIFMT_RIGHT_J: i2s_daifmt |= SND_SOC_DAIFMT_RIGHT_J; break; default: dev_err(card->dev, "Can't configure i2s format\n"); return -EINVAL; } err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk); if (err < 0) { if (!(machine->util_data.set_mclk % mclk)) mclk = machine->util_data.set_mclk; else { dev_err(card->dev, "Can't configure clocks\n"); return err; } } tegra_asoc_utils_lock_clk_rate(&machine->util_data, 1); rate = clk_get_rate(machine->util_data.clk_cdev1); err = snd_soc_dai_set_fmt(codec_dai, i2s_daifmt); if (err < 0) { dev_err(card->dev, "codec_dai fmt not set\n"); return err; } err = snd_soc_dai_set_pll(codec_dai, 0, AIC3262_PLL_CLKIN_MCLK1 , rate, params_rate(params)); if (err < 0) { dev_err(card->dev, "codec_dai PLL clock not set\n"); return err; } if (!machine_is_tegra_enterprise()) { if (params_rate(params) == 8000) { /* Change these Settings for 8KHz*/ pcmdiv = 1; /* BB expecting 2048Khz bclk */ vxclkdiv = 27; } else if (params_rate(params) == 16000) { pcmdiv = 1; /* BB expecting 2048Khz bclk */ vxclkdiv = 27; } else { dev_err(card->dev, "codec_dai unsupported voice rate\n"); return -EINVAL; } } //snd_soc_dai_set_clkdiv(codec_dai, ASI2_BCLK_N, vxclkdiv); //snd_soc_dai_set_clkdiv(codec_dai, ASI2_WCLK_N, pcmdiv); #ifndef CONFIG_ARCH_TEGRA_2x_SOC /* codec configuration */ machine->codec_info[VOICE_CODEC].rate = params_rate(params); machine->codec_info[VOICE_CODEC].channels = params_channels(params); #endif machine->is_device_bt = 0; return 0; }
static int aml_asoc_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dapm_context *dapm = &codec->dapm; struct aml_audio_private_data * p_aml_audio; int ret = 0; int hp_paraments[5]; printk(KERN_DEBUG "enter %s \n", __func__); p_aml_audio = snd_soc_card_get_drvdata(card); ret = snd_soc_add_card_controls(codec->card, aml_m8_controls, ARRAY_SIZE(aml_m8_controls)); if (ret) return ret; /* Add specific widgets */ snd_soc_dapm_new_controls(dapm, aml_asoc_dapm_widgets, ARRAY_SIZE(aml_asoc_dapm_widgets)); if (ret) return ret; #if HP_DET p_aml_audio->sdev.name = "h2w";//for report headphone to android ret = switch_dev_register(&p_aml_audio->sdev); if (ret < 0){ printk(KERN_ERR "ASoC: register hp switch dev failed\n"); return ret; } p_aml_audio->mic_sdev.name = "mic_dev";//for micphone detect ret = switch_dev_register(&p_aml_audio->mic_sdev); if (ret < 0){ printk(KERN_ERR "ASoC: register mic switch dev failed\n"); return ret; } ret = snd_soc_jack_new(codec, "hp switch", SND_JACK_HEADPHONE, &p_aml_audio->jack); if (ret < 0) { printk(KERN_WARNING "Failed to alloc resource for hp switch\n"); } else { ret = snd_soc_jack_add_pins(&p_aml_audio->jack, ARRAY_SIZE(jack_pins), jack_pins); if (ret < 0) { printk(KERN_WARNING "Failed to setup hp pins\n"); } } p_aml_audio->mic_det = of_property_read_bool(card->dev->of_node,"mic_det"); printk("entern %s : mic_det=%d \n",__func__,p_aml_audio->mic_det); ret = of_property_read_u32_array(card->dev->of_node, "hp_paraments", &hp_paraments[0], 5); if(ret){ printk("falied to get hp detect paraments from dts file\n"); }else{ p_aml_audio->hp_val_h = hp_paraments[0]; // hp adc value higher base, hp unplugged p_aml_audio->hp_val_l = hp_paraments[1]; // hp adc value low base, 3 section hp plugged. p_aml_audio->mic_val = hp_paraments[2]; // hp adc value mic detect value. p_aml_audio->hp_detal = hp_paraments[3]; // hp adc value test toerance p_aml_audio->hp_adc_ch = hp_paraments[4]; // get adc value from which adc port for hp detect printk("hp detect paraments: h=%d,l=%d,mic=%d,det=%d,ch=%d \n",p_aml_audio->hp_val_h,p_aml_audio->hp_val_l, p_aml_audio->mic_val,p_aml_audio->hp_detal,p_aml_audio->hp_adc_ch); } init_timer(&p_aml_audio->timer); p_aml_audio->timer.function = aml_asoc_timer_func; p_aml_audio->timer.data = (unsigned long)p_aml_audio; p_aml_audio->data= (void*)card; INIT_WORK(&p_aml_audio->work, aml_asoc_work_func); mutex_init(&p_aml_audio->lock); mutex_lock(&p_aml_audio->lock); if (!p_aml_audio->timer_en) { aml_audio_start_timer(p_aml_audio, msecs_to_jiffies(100)); } mutex_unlock(&p_aml_audio->lock); #endif return 0; }
static int tegra_aic326x_startup(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(cpu_dai); struct tegra_aic326x *machine = snd_soc_card_get_drvdata(rtd->card); struct codec_config *codec_info; struct codec_config *bb_info; struct codec_config *hifi_info; int codec_index; if (!i2s->is_dam_used) return 0; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { /* *make apbif tx to i2s rx connection if this is the only client *using i2s for playback */ if (i2s->playback_ref_count == 1) { tegra30_ahub_set_rx_cif_source( TEGRA30_AHUB_RXCIF_I2S0_RX0 + i2s->id, i2s->txcif); tegra30_ahub_enable_clocks(); } } else { i2s->is_call_mode_rec = machine->is_call_mode; if (!i2s->is_call_mode_rec) return 0; if (machine->is_device_bt) codec_index = BT_SCO; else codec_index = VOICE_CODEC; codec_info = &machine->codec_info[codec_index]; bb_info = &machine->codec_info[BASEBAND]; hifi_info = &machine->codec_info[HIFI_CODEC]; /* allocate a dams for voice call recording */ i2s->call_record_dam_ifc = tegra30_dam_allocate_controller(); if (i2s->call_record_dam_ifc < 0) return i2s->call_record_dam_ifc; tegra30_dam_allocate_channel(i2s->call_record_dam_ifc, TEGRA30_DAM_CHIN0_SRC); tegra30_dam_allocate_channel(i2s->call_record_dam_ifc, TEGRA30_DAM_CHIN1); tegra30_dam_enable_clock(i2s->call_record_dam_ifc); i2s->call_record_dam_ifc2 = tegra30_dam_allocate_controller(); if (i2s->call_record_dam_ifc2 < 0) return i2s->call_record_dam_ifc2; tegra30_dam_allocate_channel(i2s->call_record_dam_ifc2, TEGRA30_DAM_CHIN0_SRC); tegra30_dam_allocate_channel(i2s->call_record_dam_ifc2, TEGRA30_DAM_CHIN1); tegra30_dam_enable_clock(i2s->call_record_dam_ifc2); /* configure the dams */ /* DAM0 SRC bb rate to hifi rate */ tegra_aic326x_set_dam_cif(i2s->call_record_dam_ifc, codec_info->rate, codec_info->channels, codec_info->bitsize, 1, hifi_info->rate, hifi_info->channels, hifi_info->bitsize); /* DAM1 UL + DL Mix */ tegra_aic326x_set_dam_cif(i2s->call_record_dam_ifc2, codec_info->rate, codec_info->channels, codec_info->bitsize, 1, bb_info->rate, bb_info->channels, bb_info->bitsize); /* setup the connections for voice call record */ tegra30_ahub_unset_rx_cif_source(i2s->rxcif); tegra30_ahub_set_rx_cif_source(TEGRA30_AHUB_RXCIF_DAM0_RX0 + (i2s->call_record_dam_ifc2*2), TEGRA30_AHUB_TXCIF_I2S0_TX0 + bb_info->i2s_id); tegra30_ahub_set_rx_cif_source(TEGRA30_AHUB_RXCIF_DAM0_RX1 + (i2s->call_record_dam_ifc2*2), TEGRA30_AHUB_TXCIF_I2S0_TX0 + codec_info->i2s_id); tegra30_ahub_set_rx_cif_source(TEGRA30_AHUB_RXCIF_DAM0_RX0 + (i2s->call_record_dam_ifc*2), TEGRA30_AHUB_TXCIF_DAM0_TX0 + i2s->call_record_dam_ifc2); tegra30_ahub_set_rx_cif_source(i2s->rxcif, TEGRA30_AHUB_TXCIF_DAM0_TX0 + i2s->call_record_dam_ifc); #ifndef CONFIG_ARCH_TEGRA_3x_SOC /* Configure DAM0 for SRC */ if (bb_info->rate != hifi_info->rate) { tegra30_dam_write_coeff_ram(i2s->call_record_dam_ifc, bb_info->rate, hifi_info->rate); tegra30_dam_set_farrow_param(i2s->call_record_dam_ifc, bb_info->rate, hifi_info->rate); tegra30_dam_set_biquad_fixed_coef( i2s->call_record_dam_ifc); tegra30_dam_enable_coeff_ram(i2s->call_record_dam_ifc); tegra30_dam_set_filter_stages(i2s->call_record_dam_ifc, bb_info->rate, hifi_info->rate); } #endif /* enable the dam */ tegra30_dam_enable(i2s->call_record_dam_ifc, TEGRA30_DAM_ENABLE, TEGRA30_DAM_CHIN1); tegra30_dam_enable(i2s->call_record_dam_ifc, TEGRA30_DAM_ENABLE, TEGRA30_DAM_CHIN0_SRC); tegra30_dam_enable(i2s->call_record_dam_ifc2, TEGRA30_DAM_ENABLE, TEGRA30_DAM_CHIN1); tegra30_dam_enable(i2s->call_record_dam_ifc2, TEGRA30_DAM_ENABLE, TEGRA30_DAM_CHIN0_SRC); } return 0; }
static int tegra_aic326x_bt_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_card *card = rtd->card; struct tegra_aic326x *machine = snd_soc_card_get_drvdata(card); struct tegra_asoc_platform_data *pdata = machine->pdata; int err, srate, mclk, min_mclk, sample_size, i2s_daifmt; #ifndef CONFIG_ARCH_TEGRA_2x_SOC struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(rtd->cpu_dai); #endif switch (params_format(params)) { case SNDRV_PCM_FORMAT_S16_LE: sample_size = 16; break; default: return -EINVAL; } srate = params_rate(params); mclk = tegra_aic326x_get_mclk(srate); if (mclk < 0) return mclk; min_mclk = 64 * srate; err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk); if (err < 0) { if (!(machine->util_data.set_mclk % min_mclk)) mclk = machine->util_data.set_mclk; else { dev_err(card->dev, "Can't configure clocks\n"); return err; } } tegra_asoc_utils_lock_clk_rate(&machine->util_data, 1); i2s_daifmt = SND_SOC_DAIFMT_NB_NF; i2s_daifmt |= pdata->i2s_param[BT_SCO].is_i2s_master ? SND_SOC_DAIFMT_CBS_CFS : SND_SOC_DAIFMT_CBM_CFM; switch (pdata->i2s_param[BT_SCO].i2s_mode) { case TEGRA_DAIFMT_I2S : i2s_daifmt |= SND_SOC_DAIFMT_I2S; break; case TEGRA_DAIFMT_DSP_A : i2s_daifmt |= SND_SOC_DAIFMT_DSP_A; break; case TEGRA_DAIFMT_DSP_B : i2s_daifmt |= SND_SOC_DAIFMT_DSP_B; break; case TEGRA_DAIFMT_LEFT_J : i2s_daifmt |= SND_SOC_DAIFMT_LEFT_J; break; case TEGRA_DAIFMT_RIGHT_J : i2s_daifmt |= SND_SOC_DAIFMT_RIGHT_J; break; default : dev_err(card->dev, "Can't configure i2s format\n"); return -EINVAL; } err = snd_soc_dai_set_fmt(rtd->cpu_dai, i2s_daifmt); if (err < 0) { dev_err(rtd->codec->card->dev, "cpu_dai fmt not set\n"); return err; } #ifdef CONFIG_ARCH_TEGRA_2x_SOC err = tegra20_das_connect_dac_to_dap(TEGRA20_DAS_DAP_SEL_DAC2, TEGRA20_DAS_DAP_ID_4); if (err < 0) { dev_err(card->dev, "failed to set dac-dap path\n"); return err; } err = tegra20_das_connect_dap_to_dac(TEGRA20_DAS_DAP_ID_4, TEGRA20_DAS_DAP_SEL_DAC2); if (err < 0) { dev_err(card->dev, "failed to set dac-dap path\n"); return err; } #else if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && i2s->is_dam_used) tegra_aic326x_set_dam_cif(i2s->dam_ifc, params_rate(params), params_channels(params), sample_size, 0, 0, 0, 0); #endif return 0; }
static int tegra_aic326x_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_dai *codec_dai = rtd->codec_dai; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_codec *codec = rtd->codec; struct snd_soc_card *card = codec->card; struct tegra_aic326x *machine = snd_soc_card_get_drvdata(card); struct tegra_asoc_platform_data *pdata = machine->pdata; int srate, mclk, sample_size, i2s_daifmt; int err, rate; switch (params_format(params)) { case SNDRV_PCM_FORMAT_S16_LE: sample_size = 16; break; default: return -EINVAL; } srate = params_rate(params); mclk = tegra_aic326x_get_mclk(srate); if (mclk < 0) return mclk; i2s_daifmt = SND_SOC_DAIFMT_NB_NF; i2s_daifmt |= pdata->i2s_param[HIFI_CODEC].is_i2s_master ? SND_SOC_DAIFMT_CBS_CFS : SND_SOC_DAIFMT_CBM_CFM; switch (pdata->i2s_param[HIFI_CODEC].i2s_mode) { case TEGRA_DAIFMT_I2S : i2s_daifmt |= SND_SOC_DAIFMT_I2S; break; case TEGRA_DAIFMT_DSP_A : i2s_daifmt |= SND_SOC_DAIFMT_DSP_A; break; case TEGRA_DAIFMT_DSP_B : i2s_daifmt |= SND_SOC_DAIFMT_DSP_B; break; case TEGRA_DAIFMT_LEFT_J : i2s_daifmt |= SND_SOC_DAIFMT_LEFT_J; break; case TEGRA_DAIFMT_RIGHT_J : i2s_daifmt |= SND_SOC_DAIFMT_RIGHT_J; break; default : dev_err(card->dev, "Can't configure i2s format\n"); return -EINVAL; } err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk); if (err < 0) { if (!(machine->util_data.set_mclk % mclk)) mclk = machine->util_data.set_mclk; else { dev_err(card->dev, "Can't configure clocks\n"); return err; } } tegra_asoc_utils_lock_clk_rate(&machine->util_data, 1); rate = clk_get_rate(machine->util_data.clk_cdev1); err = snd_soc_dai_set_fmt(codec_dai, i2s_daifmt); if (err < 0) { dev_err(card->dev, "codec_dai fmt not set\n"); return err; } err = snd_soc_dai_set_fmt(cpu_dai, i2s_daifmt); if (err < 0) { dev_err(card->dev, "cpu_dai fmt not set\n"); return err; } err = snd_soc_dai_set_pll(codec_dai, 0, AIC3262_PLL_CLKIN_MCLK1 , rate, params_rate(params)); #ifdef CONFIG_ARCH_TEGRA_2x_SOC err = tegra20_das_connect_dac_to_dap(TEGRA20_DAS_DAP_SEL_DAC1, TEGRA20_DAS_DAP_ID_1); if (err < 0) { dev_err(card->dev, "failed to set dap-dac path\n"); return err; } err = tegra20_das_connect_dap_to_dac(TEGRA20_DAS_DAP_ID_1, TEGRA20_DAS_DAP_SEL_DAC1); if (err < 0) { dev_err(card->dev, "failed to set dac-dap path\n"); return err; } #endif return 0; }
static int sdm845_snd_startup(struct snd_pcm_substream *substream) { unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS; unsigned int codec_dai_fmt = SND_SOC_DAIFMT_CBS_CFS; struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_card *card = rtd->card; struct sdm845_snd_data *data = snd_soc_card_get_drvdata(card); struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_dai *codec_dai = rtd->codec_dai; int j; int ret; switch (cpu_dai->id) { case PRIMARY_MI2S_RX: case PRIMARY_MI2S_TX: codec_dai_fmt |= SND_SOC_DAIFMT_NB_NF; if (++(data->pri_mi2s_clk_count) == 1) { snd_soc_dai_set_sysclk(cpu_dai, Q6AFE_LPASS_CLK_ID_MCLK_1, DEFAULT_MCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK); snd_soc_dai_set_sysclk(cpu_dai, Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT, MI2S_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK); } snd_soc_dai_set_fmt(cpu_dai, fmt); snd_soc_dai_set_fmt(codec_dai, codec_dai_fmt); break; case SECONDARY_MI2S_TX: if (++(data->sec_mi2s_clk_count) == 1) { snd_soc_dai_set_sysclk(cpu_dai, Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT, MI2S_BCLK_RATE, SNDRV_PCM_STREAM_CAPTURE); } snd_soc_dai_set_fmt(cpu_dai, fmt); break; case QUATERNARY_TDM_RX_0: case QUATERNARY_TDM_TX_0: if (++(data->quat_tdm_clk_count) == 1) { snd_soc_dai_set_sysclk(cpu_dai, Q6AFE_LPASS_CLK_ID_QUAD_TDM_IBIT, TDM_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK); } codec_dai_fmt |= SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_DSP_B; for (j = 0; j < rtd->num_codecs; j++) { codec_dai = rtd->codec_dais[j]; if (!strcmp(codec_dai->component->name_prefix, "Left")) { ret = snd_soc_dai_set_fmt( codec_dai, codec_dai_fmt); if (ret < 0) { dev_err(rtd->dev, "Left TDM fmt err:%d\n", ret); return ret; } } if (!strcmp(codec_dai->component->name_prefix, "Right")) { ret = snd_soc_dai_set_fmt( codec_dai, codec_dai_fmt); if (ret < 0) { dev_err(rtd->dev, "Right TDM slot err:%d\n", ret); return ret; } } } break; default: pr_err("%s: invalid dai id 0x%x\n", __func__, cpu_dai->id); break; } return 0; }
static int tegra_max98088_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_dai *codec_dai = rtd->codec_dai; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_codec *codec = rtd->codec; struct snd_soc_card *card = codec->card; struct tegra_max98088 *machine = snd_soc_card_get_drvdata(card); #ifndef CONFIG_ARCH_TEGRA_2x_SOC struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(cpu_dai); #endif int srate, mclk, sample_size, i2s_daifmt; int err; struct clk *clk; int rate; switch (params_format(params)) { case SNDRV_PCM_FORMAT_S16_LE: sample_size = 16; break; default: return -EINVAL; } srate = params_rate(params); switch (srate) { case 8000: case 16000: case 24000: case 32000: case 48000: case 64000: case 96000: mclk = 12288000; break; case 11025: case 22050: case 44100: case 88200: mclk = 11289600; break; default: mclk = 12000000; break; } #if defined(CONFIG_ARCH_TEGRA_2x_SOC) clk = clk_get_sys(NULL, "cdev1"); #else clk = clk_get_sys("extern1", NULL); #endif if (IS_ERR(clk)) { dev_err(card->dev, "Can't retrieve clk cdev1\n"); err = PTR_ERR(clk); return err; } rate = clk_get_rate(clk); printk("extern1 rate=%d\n",rate); #if TEGRA30_I2S_MASTER_PLAYBACK i2s_daifmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS; #else i2s_daifmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM; mclk = rate; #endif err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk); if (err < 0) { if (!(machine->util_data.set_mclk % mclk)) mclk = machine->util_data.set_mclk; else { dev_err(card->dev, "Can't configure clocks\n"); return err; } } tegra_asoc_utils_lock_clk_rate(&machine->util_data, 1); err = snd_soc_dai_set_fmt(codec_dai,i2s_daifmt); if (err < 0) { dev_err(card->dev, "codec_dai fmt not set\n"); return err; } err = snd_soc_dai_set_fmt(cpu_dai, i2s_daifmt); if (err < 0) { dev_err(card->dev, "cpu_dai fmt not set\n"); return err; } err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk, SND_SOC_CLOCK_IN); if (err < 0) { dev_err(card->dev, "codec_dai clock not set\n"); return err; } #ifndef CONFIG_ARCH_TEGRA_2x_SOC if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) tegra_max98088_set_dam_cif(i2s->dam_ifc, srate, params_channels(params), sample_size, 0, 0, 0, 0); #endif return 0; }
static int fsl_asoc_card_set_bias_level(struct snd_soc_card *card, struct snd_soc_dapm_context *dapm, enum snd_soc_bias_level level) { struct fsl_asoc_card_priv *priv = snd_soc_card_get_drvdata(card); struct snd_soc_pcm_runtime *rtd; struct snd_soc_dai *codec_dai; struct codec_priv *codec_priv = &priv->codec_priv; struct device *dev = card->dev; unsigned int pll_out; int ret; rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name); codec_dai = rtd->codec_dai; if (dapm->dev != codec_dai->dev) return 0; switch (level) { case SND_SOC_BIAS_PREPARE: if (dapm->bias_level != SND_SOC_BIAS_STANDBY) break; if (priv->sample_format == SNDRV_PCM_FORMAT_S24_LE) pll_out = priv->sample_rate * 384; else pll_out = priv->sample_rate * 256; ret = snd_soc_dai_set_pll(codec_dai, codec_priv->pll_id, codec_priv->mclk_id, codec_priv->mclk_freq, pll_out); if (ret) { dev_err(dev, "failed to start FLL: %d\n", ret); return ret; } ret = snd_soc_dai_set_sysclk(codec_dai, codec_priv->fll_id, pll_out, SND_SOC_CLOCK_IN); if (ret) { dev_err(dev, "failed to set SYSCLK: %d\n", ret); return ret; } break; case SND_SOC_BIAS_STANDBY: if (dapm->bias_level != SND_SOC_BIAS_PREPARE) break; ret = snd_soc_dai_set_sysclk(codec_dai, codec_priv->mclk_id, codec_priv->mclk_freq, SND_SOC_CLOCK_IN); if (ret) { dev_err(dev, "failed to switch away from FLL: %d\n", ret); return ret; } ret = snd_soc_dai_set_pll(codec_dai, codec_priv->pll_id, 0, 0, 0); if (ret) { dev_err(dev, "failed to stop FLL: %d\n", ret); return ret; } break; default: break; } return 0; }
static int tegra_bt_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *rtd = substream->private_data; #ifndef CONFIG_ARCH_TEGRA_2x_SOC struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(rtd->cpu_dai); #endif struct snd_soc_card *card = rtd->card; struct tegra_max98088 *machine = snd_soc_card_get_drvdata(card); int err, srate, mclk, min_mclk, sample_size; switch (params_format(params)) { case SNDRV_PCM_FORMAT_S16_LE: sample_size = 16; break; default: return -EINVAL; } srate = params_rate(params); switch (srate) { case 11025: case 22050: case 44100: case 88200: mclk = 11289600; break; case 8000: case 16000: case 32000: case 48000: case 64000: case 96000: mclk = 12288000; break; default: return -EINVAL; } min_mclk = 64 * srate; err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk); if (err < 0) { if (!(machine->util_data.set_mclk % min_mclk)) mclk = machine->util_data.set_mclk; else { dev_err(card->dev, "Can't configure clocks\n"); return err; } } tegra_asoc_utils_lock_clk_rate(&machine->util_data, 1); err = snd_soc_dai_set_fmt(rtd->cpu_dai, SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); if (err < 0) { dev_err(rtd->codec->card->dev, "cpu_dai fmt not set\n"); return err; } #ifndef CONFIG_ARCH_TEGRA_2x_SOC if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) tegra_max98088_set_dam_cif(i2s->dam_ifc, params_rate(params), params_channels(params), sample_size, 0, 0, 0, 0); #endif return 0; }
static int tegra_bt_sco_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_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_card *card = rtd->card; struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); int srate, mclk, min_mclk; int err; srate = params_rate(params); switch (srate) { case 11025: case 22050: case 44100: case 88200: mclk = 11289600; break; case 8000: case 16000: case 32000: case 48000: case 64000: case 96000: mclk = 12288000; break; default: return -EINVAL; } min_mclk = 64 * srate; err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk); if (err < 0) { if (!(machine->util_data.set_mclk % min_mclk)) mclk = machine->util_data.set_mclk; else { dev_err(card->dev, "Can't configure clocks\n"); return err; } } tegra_asoc_utils_lock_clk_rate(&machine->util_data, 1); err = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); if (err < 0) { dev_err(card->dev, "cpu_dai fmt not set\n"); return err; } #ifdef CONFIG_ARCH_TEGRA_2x_SOC err = tegra20_das_connect_dac_to_dap(TEGRA20_DAS_DAP_SEL_DAC2, TEGRA20_DAS_DAP_ID_4); if (err < 0) { dev_err(card->dev, "failed to set dac-dap path\n"); return err; } err = tegra20_das_connect_dap_to_dac(TEGRA20_DAS_DAP_ID_4, TEGRA20_DAS_DAP_SEL_DAC2); if (err < 0) { dev_err(card->dev, "failed to set dac-dap path\n"); return err; } #endif return 0; }
static int tegra_max98088_startup(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(cpu_dai); struct tegra_max98088 *machine = snd_soc_card_get_drvdata(rtd->card); struct codec_config *codec_info; struct codec_config *bb_info; int codec_index; if (!i2s->is_dam_used) return 0; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { /*dam configuration*/ if (!i2s->dam_ch_refcount) i2s->dam_ifc = tegra30_dam_allocate_controller(); tegra30_dam_allocate_channel(i2s->dam_ifc, TEGRA30_DAM_CHIN1); i2s->dam_ch_refcount++; tegra30_dam_enable_clock(i2s->dam_ifc); tegra30_ahub_set_rx_cif_source(TEGRA30_AHUB_RXCIF_DAM0_RX1 + (i2s->dam_ifc*2), i2s->txcif); /* *make the dam tx to i2s rx connection if this is the only client *using i2s for playback */ if (i2s->playback_ref_count == 1) tegra30_ahub_set_rx_cif_source( TEGRA30_AHUB_RXCIF_I2S0_RX0 + i2s->id, TEGRA30_AHUB_TXCIF_DAM0_TX0 + i2s->dam_ifc); /* enable the dam*/ tegra30_dam_enable(i2s->dam_ifc, TEGRA30_DAM_ENABLE, TEGRA30_DAM_CHIN1); } else { i2s->is_call_mode_rec = machine->is_call_mode; if (!i2s->is_call_mode_rec) return 0; if (machine->is_device_bt) codec_index = BT_SCO; else codec_index = HIFI_CODEC; codec_info = &machine->codec_info[codec_index]; bb_info = &machine->codec_info[BASEBAND]; /* allocate a dam for voice call recording */ i2s->call_record_dam_ifc = tegra30_dam_allocate_controller(); tegra30_dam_allocate_channel(i2s->call_record_dam_ifc, TEGRA30_DAM_CHIN0_SRC); tegra30_dam_allocate_channel(i2s->call_record_dam_ifc, TEGRA30_DAM_CHIN1); tegra30_dam_enable_clock(i2s->call_record_dam_ifc); /* configure the dam */ tegra_max98088_set_dam_cif(i2s->call_record_dam_ifc, codec_info->rate, codec_info->channels, codec_info->bitsize, 1, bb_info->rate, bb_info->channels, bb_info->bitsize); /* setup the connections for voice call record */ tegra30_ahub_unset_rx_cif_source(i2s->rxcif); tegra30_ahub_set_rx_cif_source(TEGRA30_AHUB_RXCIF_DAM0_RX0 + (i2s->call_record_dam_ifc*2), TEGRA30_AHUB_TXCIF_I2S0_TX0 + bb_info->i2s_id); tegra30_ahub_set_rx_cif_source(TEGRA30_AHUB_RXCIF_DAM0_RX1 + (i2s->call_record_dam_ifc*2), TEGRA30_AHUB_TXCIF_I2S0_TX0 + codec_info->i2s_id); tegra30_ahub_set_rx_cif_source(i2s->rxcif, TEGRA30_AHUB_TXCIF_DAM0_TX0 + i2s->call_record_dam_ifc); /* enable the dam*/ tegra30_dam_enable(i2s->call_record_dam_ifc, TEGRA30_DAM_ENABLE, TEGRA30_DAM_CHIN1); tegra30_dam_enable(i2s->call_record_dam_ifc, TEGRA30_DAM_ENABLE, TEGRA30_DAM_CHIN0_SRC); } return 0; }
static int tegra_wm8903_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_dai *codec_dai = rtd->codec_dai; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_codec *codec = rtd->codec; struct snd_soc_card *card = codec->card; struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); int srate, mclk, i2s_daifmt; int err; struct clk *clk_m; int rate; srate = params_rate(params); switch (srate) { case 64000: case 88200: case 96000: mclk = 128 * srate; break; default: mclk = 256 * srate; break; } clk_m = clk_get_sys(NULL, "clk_m"); if (IS_ERR(clk_m)) { dev_err(card->dev, "Can't retrieve clk clk_m\n"); err = PTR_ERR(clk_m); return err; } rate = clk_get_rate(clk_m); printk("extern1 rate=%d\n",rate); #if TEGRA30_I2S_MASTER_PLAYBACK /* FIXME: Codec only requires >= 3MHz if OSR==0 */ while (mclk < 6000000) mclk *= 2; i2s_daifmt = SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS; #else mclk = rate; i2s_daifmt = SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM; #endif err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk); if (err < 0) { if (!(machine->util_data.set_mclk % mclk)) mclk = machine->util_data.set_mclk; else { dev_err(card->dev, "Can't configure clocks\n"); return err; } } tegra_asoc_utils_lock_clk_rate(&machine->util_data, 1); /* Use DSP mode for mono on Tegra20 */ if ((params_channels(params) != 2) && (machine_is_ventana() || machine_is_harmony() || machine_is_kaen() || machine_is_aebl())) i2s_daifmt |= SND_SOC_DAIFMT_DSP_A; else i2s_daifmt |= SND_SOC_DAIFMT_I2S; err = snd_soc_dai_set_fmt(codec_dai, i2s_daifmt); if (err < 0) { dev_err(card->dev, "codec_dai fmt not set\n"); return err; } err = snd_soc_dai_set_fmt(cpu_dai, i2s_daifmt); if (err < 0) { dev_err(card->dev, "cpu_dai fmt not set\n"); return err; } err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk, SND_SOC_CLOCK_IN); if (err < 0) { dev_err(card->dev, "codec_dai clock not set\n"); return err; } ///Eric //Webber increase drc gain 9db snd_soc_write(codec, WM8903_DRC_0, 0x89BF); snd_soc_write(codec, WM8903_DRC_1, 0x149F); snd_soc_write(codec, WM8903_DRC_2, 0x0010); snd_soc_write(codec, WM8903_DRC_3, 0x0180); //Webber snd_soc_write(codec, WM8903_ANALOGUE_OUT1_LEFT, 0xb0); snd_soc_write(codec, WM8903_ANALOGUE_OUT1_RIGHT, 0xb0); snd_soc_write(codec, WM8903_ANALOGUE_OUT2_LEFT, 0x33); snd_soc_write(codec, WM8903_ANALOGUE_OUT2_RIGHT, 0xB3); ///Eric #ifdef CONFIG_ARCH_TEGRA_2x_SOC err = tegra20_das_connect_dac_to_dap(TEGRA20_DAS_DAP_SEL_DAC1, TEGRA20_DAS_DAP_ID_1); if (err < 0) { dev_err(card->dev, "failed to set dap-dac path\n"); return err; } err = tegra20_das_connect_dap_to_dac(TEGRA20_DAS_DAP_ID_1, TEGRA20_DAS_DAP_SEL_DAC1); if (err < 0) { dev_err(card->dev, "failed to set dac-dap path\n"); return err; } #endif return 0; }
static int tegra_voice_call_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_dai *codec_dai = rtd->codec_dai; struct snd_soc_codec *codec = rtd->codec; struct snd_soc_card *card = codec->card; struct tegra_max98088 *machine = snd_soc_card_get_drvdata(card); int srate, mclk; int err; srate = params_rate(params); switch (srate) { case 8000: case 16000: case 24000: case 32000: case 48000: case 64000: case 96000: mclk = 12288000; break; case 11025: case 22050: case 44100: case 88200: mclk = 11289600; break; default: return -EINVAL; break; } err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk); if (err < 0) { if (!(machine->util_data.set_mclk % mclk)) mclk = machine->util_data.set_mclk; else { dev_err(card->dev, "Can't configure clocks\n"); return err; } } tegra_asoc_utils_lock_clk_rate(&machine->util_data, 1); err = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); if (err < 0) { dev_err(card->dev, "codec_dai fmt not set\n"); return err; } err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk, SND_SOC_CLOCK_IN); if (err < 0) { dev_err(card->dev, "codec_dai clock not set\n"); return err; } #ifndef CONFIG_ARCH_TEGRA_2x_SOC /* codec configuration */ machine->codec_info[HIFI_CODEC].rate = params_rate(params); machine->codec_info[HIFI_CODEC].channels = params_channels(params); machine->codec_info[HIFI_CODEC].bitsize = 16; machine->codec_info[HIFI_CODEC].is_i2smaster = 1; machine->codec_info[HIFI_CODEC].is_format_dsp = 0; /* baseband configuration */ machine->codec_info[BASEBAND].bitsize = 16; machine->codec_info[BASEBAND].is_i2smaster = 1; machine->codec_info[BASEBAND].is_format_dsp = 1; #endif machine->is_device_bt = 0; return 0; }
static int t0_wm1811_init_paiftx(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; struct wm1811_machine_priv *wm1811 = snd_soc_card_get_drvdata(codec->card); struct snd_soc_dai *aif1_dai = rtd->codec_dai; struct wm8994 *control = codec->control_data; struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); int ret; midas_snd_set_mclk(true, false); rtd->codec_dai->driver->playback.channels_max = rtd->cpu_dai->driver->playback.channels_max; ret = snd_soc_add_controls(codec, t0_controls, ARRAY_SIZE(t0_controls)); ret = snd_soc_dapm_new_controls(&codec->dapm, t0_dapm_widgets, ARRAY_SIZE(t0_dapm_widgets)); if (ret != 0) dev_err(codec->dev, "Failed to add DAPM widgets: %d\n", ret); ret = snd_soc_dapm_add_routes(&codec->dapm, t0_dapm_routes, ARRAY_SIZE(t0_dapm_routes)); if (ret != 0) dev_err(codec->dev, "Failed to add DAPM routes: %d\n", ret); ret = snd_soc_dai_set_sysclk(aif1_dai, WM8994_SYSCLK_MCLK2, MIDAS_DEFAULT_MCLK2, SND_SOC_CLOCK_IN); if (ret < 0) dev_err(codec->dev, "Failed to boot clocking\n"); /* Force AIF1CLK on as it will be master for jack detection */ if (wm8994->revision > 1) { ret = snd_soc_dapm_force_enable_pin(&codec->dapm, "AIF1CLK"); if (ret < 0) dev_err(codec->dev, "Failed to enable AIF1CLK: %d\n", ret); } ret = snd_soc_dapm_disable_pin(&codec->dapm, "S5P RP"); if (ret < 0) dev_err(codec->dev, "Failed to disable S5P RP: %d\n", ret); snd_soc_dapm_ignore_suspend(&codec->dapm, "RCV"); snd_soc_dapm_ignore_suspend(&codec->dapm, "SPK"); snd_soc_dapm_ignore_suspend(&codec->dapm, "HP"); snd_soc_dapm_ignore_suspend(&codec->dapm, "Headset Mic"); snd_soc_dapm_ignore_suspend(&codec->dapm, "Sub Mic"); snd_soc_dapm_ignore_suspend(&codec->dapm, "Main Mic"); snd_soc_dapm_ignore_suspend(&codec->dapm, "AIF1DACDAT"); snd_soc_dapm_ignore_suspend(&codec->dapm, "AIF2DACDAT"); snd_soc_dapm_ignore_suspend(&codec->dapm, "AIF3DACDAT"); snd_soc_dapm_ignore_suspend(&codec->dapm, "AIF1ADCDAT"); snd_soc_dapm_ignore_suspend(&codec->dapm, "AIF2ADCDAT"); snd_soc_dapm_ignore_suspend(&codec->dapm, "AIF3ADCDAT"); snd_soc_dapm_ignore_suspend(&codec->dapm, "FM In"); snd_soc_dapm_ignore_suspend(&codec->dapm, "LINE"); snd_soc_dapm_ignore_suspend(&codec->dapm, "HDMI"); wm1811->codec = codec; t0_micd_set_rate(codec); #ifdef CONFIG_SEC_DEV_JACK /* By default use idle_bias_off, will override for WM8994 */ codec->dapm.idle_bias_off = 0; #else /* CONFIG_SEC_DEV_JACK */ wm1811->jack.status = 0; ret = snd_soc_jack_new(codec, "T0 Jack", SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2, &wm1811->jack); if (ret < 0) dev_err(codec->dev, "Failed to create jack: %d\n", ret); ret = snd_jack_set_key(wm1811->jack.jack, SND_JACK_BTN_0, KEY_MEDIA); if (ret < 0) dev_err(codec->dev, "Failed to set KEY_MEDIA: %d\n", ret); ret = snd_jack_set_key(wm1811->jack.jack, SND_JACK_BTN_1, KEY_VOLUMEDOWN); if (ret < 0) dev_err(codec->dev, "Failed to set KEY_VOLUMEUP: %d\n", ret); ret = snd_jack_set_key(wm1811->jack.jack, SND_JACK_BTN_2, KEY_VOLUMEUP); if (ret < 0) dev_err(codec->dev, "Failed to set KEY_VOLUMEDOWN: %d\n", ret); if (wm8994->revision > 1) { dev_info(codec->dev, "wm1811: Rev %c support mic detection\n", 'A' + wm8994->revision); ret = wm8958_mic_detect(codec, &wm1811->jack, t0_micdet, wm1811); if (ret < 0) dev_err(codec->dev, "Failed start detection: %d\n", ret); } else { dev_info(codec->dev, "wm1811: Rev %c doesn't support mic detection\n", 'A' + wm8994->revision); codec->dapm.idle_bias_off = 0; } /* To wakeup for earjack event in suspend mode */ enable_irq_wake(control->irq); wake_lock_init(&wm1811->jackdet_wake_lock, WAKE_LOCK_SUSPEND, "T0_jackdet"); /* To support PBA function test */ jack_class = class_create(THIS_MODULE, "audio"); if (IS_ERR(jack_class)) pr_err("Failed to create class\n"); jack_dev = device_create(jack_class, NULL, 0, codec, "earjack"); if (device_create_file(jack_dev, &dev_attr_select_jack) < 0) pr_err("Failed to create device file (%s)!\n", dev_attr_select_jack.attr.name); if (device_create_file(jack_dev, &dev_attr_key_state) < 0) pr_err("Failed to create device file (%s)!\n", dev_attr_key_state.attr.name); if (device_create_file(jack_dev, &dev_attr_state) < 0) pr_err("Failed to create device file (%s)!\n", dev_attr_state.attr.name); if (device_create_file(jack_dev, &dev_attr_reselect_jack) < 0) pr_err("Failed to create device file (%s)!\n", dev_attr_reselect_jack.attr.name); #endif /* CONFIG_SEC_DEV_JACK */ return snd_soc_dapm_sync(&codec->dapm); }
static int tegra_rt5640_jack_notifier(struct notifier_block *self, unsigned long action, void *dev) { struct snd_soc_jack *jack = dev; struct snd_soc_codec *codec = jack->codec; struct snd_soc_card *card = codec->card; struct tegra_rt5640 *machine = snd_soc_card_get_drvdata(card); struct tegra_rt5640_platform_data *pdata = machine->pdata; enum headset_state state = BIT_NO_HEADSET; unsigned char status_jack; #if 0 if (jack == &tegra_rt5640_hp_jack) { if (action) { /* Enable ext mic; enable signal is active-low */ gpio_direction_output(pdata->gpio_ext_mic_en, 0); if (!strncmp(machine->pdata->codec_name, "rt5639", 6)) status_jack = rt5639_headset_detect(codec, 1); else if (!strncmp(machine->pdata->codec_name, "rt5640", 6)) status_jack = rt5640_headset_detect(codec, 1); machine->jack_status &= ~SND_JACK_HEADPHONE; machine->jack_status &= ~SND_JACK_MICROPHONE; if (status_jack == RT5639_HEADPHO_DET || status_jack == RT5640_HEADPHO_DET) machine->jack_status |= SND_JACK_HEADPHONE; else if (status_jack == RT5639_HEADSET_DET || status_jack == RT5640_HEADSET_DET) { machine->jack_status |= SND_JACK_HEADPHONE; machine->jack_status |= SND_JACK_MICROPHONE; } } else { /* Disable ext mic; enable signal is active-low */ gpio_direction_output(pdata->gpio_ext_mic_en, 1); if (!strncmp(machine->pdata->codec_name, "rt5639", 6)) rt5639_headset_detect(codec, 0); else if (!strncmp(machine->pdata->codec_name, "rt5640", 6)) rt5640_headset_detect(codec, 0); machine->jack_status &= ~SND_JACK_HEADPHONE; machine->jack_status &= ~SND_JACK_MICROPHONE; } } #endif switch (machine->jack_status) { case SND_JACK_HEADPHONE: state = BIT_HEADSET_NO_MIC; break; case SND_JACK_HEADSET: state = BIT_HEADSET; break; case SND_JACK_MICROPHONE: /* mic: would not report */ default: state = BIT_NO_HEADSET; } switch_set_state(&tegra_rt5640_headset_switch, state); return NOTIFY_OK; }
static int ctp_wm5102_init(struct snd_soc_pcm_runtime *runtime) { int ret; struct snd_soc_card *card = runtime->card; struct ctp_mc_private *ctx = snd_soc_card_get_drvdata(runtime->card); struct snd_soc_codec *codec; struct snd_soc_dapm_context *dapm; codec = ctp_get_codec(card, "wm5102-codec"); if (!codec) return -EIO; dapm = &codec->dapm; /* Set codec bias level */ ctp_set_bias_level(card, dapm, SND_SOC_BIAS_OFF); card->dapm.idle_bias_off = true; /* Disable MICBIAS3 bypass mode and set CAP mode. * Capacitors are connected to DMIC on 1525-EV1 board */ snd_soc_update_bits(codec, ARIZONA_MIC_BIAS_CTRL_3, ARIZONA_MICB1_BYPASS_MASK | ARIZONA_MICB1_EXT_CAP_MASK, ARIZONA_MICB1_EXT_CAP); /* Set codec clock */ ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_SYSCLK, ARIZONA_CLK_SRC_FLL1, SYSCLK_RATE, SND_SOC_CLOCK_IN); if (ret != 0) { pr_err("failed: %d\n", ret); return ret; } /* Add Jack specific widgets */ ret = snd_soc_dapm_new_controls(dapm, ctp_dapm_widgets, ARRAY_SIZE(ctp_dapm_widgets)); if (ret) return ret; /* Set up Jack specific audio path audio_map */ snd_soc_dapm_add_routes(dapm, ctp_audio_map, ARRAY_SIZE(ctp_audio_map)); /* Add Comms specefic controls */ ctx->comms_ctl.ssp_bt_sco_master_mode = false; ctx->comms_ctl.ssp_voip_master_mode = false; ctx->comms_ctl.ssp_modem_master_mode = false; ret = snd_soc_add_card_controls(card, ssp_comms_controls, ARRAY_SIZE(ssp_comms_controls)); if (ret) { pr_err("Add Comms Controls failed %d", ret); return ret; } /* Keep the voice call paths active during suspend. Mark the end points ignore_suspend */ snd_soc_dapm_ignore_suspend(dapm, "HPOUT1R"); snd_soc_dapm_ignore_suspend(dapm, "HPOUT1L"); snd_soc_dapm_disable_pin(dapm, "MICBIAS1"); snd_soc_dapm_disable_pin(dapm, "SPKOUTLP"); snd_soc_dapm_disable_pin(dapm, "SPKOUTLN"); snd_soc_dapm_ignore_suspend(dapm, "SPKOUTRP"); snd_soc_dapm_ignore_suspend(dapm, "SPKOUTRN"); mutex_lock(&codec->mutex); snd_soc_dapm_sync(dapm); mutex_unlock(&codec->mutex); return ret; }
static int tegra_p1852_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_dai *codec_dai = rtd->codec_dai; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_codec *codec = rtd->codec; struct snd_soc_card *card = codec->card; struct tegra_p1852 *machine = snd_soc_card_get_drvdata(card); int srate, mclk; int i2s_daifmt = 0; int err; struct tegra_p1852_platform_data *pdata; int codec_id = codec_dai->id; pdata = machine->pdata; srate = params_rate(params); switch (srate) { case 64000: case 88200: case 96000: mclk = 128 * srate; break; default: mclk = 256 * srate; break; } err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk); if (err < 0) { if (!(machine->util_data.set_mclk % mclk)) mclk = machine->util_data.set_mclk; else { dev_err(card->dev, "Can't configure clocks\n"); return err; } } tegra_asoc_utils_lock_clk_rate(&machine->util_data, 1); if (pdata->codec_info[codec_id].master) i2s_daifmt |= SND_SOC_DAIFMT_CBM_CFM; else i2s_daifmt |= SND_SOC_DAIFMT_CBS_CFS; switch (pdata->codec_info[codec_id].i2s_format) { case format_tdm: i2s_daifmt |= SND_SOC_DAIFMT_DSP_A; break; case format_i2s: i2s_daifmt |= SND_SOC_DAIFMT_I2S; break; case format_rjm: i2s_daifmt |= SND_SOC_DAIFMT_RIGHT_J; break; case format_ljm: i2s_daifmt |= SND_SOC_DAIFMT_LEFT_J; break; default: break; } err = snd_soc_dai_set_fmt(codec_dai, i2s_daifmt); if (err < 0) dev_info(card->dev, "codec_dai fmt not set\n"); err = snd_soc_dai_set_fmt(cpu_dai, i2s_daifmt); if (err < 0) { dev_err(card->dev, "cpu_dai fmt not set\n"); return err; } err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk, SND_SOC_CLOCK_IN); if (err < 0) dev_info(card->dev, "codec_dai clock not set\n"); return 0; }