static int imx_3stack_bt_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_soc_pcm_link *pcm_link = substream->private_data; struct mxc_audio_platform_data *dev_data = pcm_link->machine->private_data; struct snd_soc_dai *cpu_dai = pcm_link->cpu_dai; unsigned int channels = params_channels(params); u32 dai_format; imx_3stack_init_dam(dev_data->src_port, dev_data->ext_port); #if BT_SSI_MASTER dai_format = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBM_CFM | SND_SOC_DAIFMT_SYNC; #else dai_format = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBS_CFS | SND_SOC_DAIFMT_SYNC; #endif if (channels == 2) dai_format |= SND_SOC_DAIFMT_TDM; /* set cpu DAI configuration */ cpu_dai->ops->set_fmt(cpu_dai, dai_format); /* set i.MX active slot mask */ cpu_dai->ops->set_tdm_slot(cpu_dai, channels == 1 ? 0xfffffffe : 0xfffffffc, channels); /* set the SSI system clock as input (unused) */ cpu_dai->ops->set_sysclk(cpu_dai, IMX_SSP_SYS_CLK, 0, SND_SOC_CLOCK_IN); return 0; }
/* * This function will register the snd_soc_pcm_link drivers. * It also registers devices for platform DMA, I2S, SSP and registers an * I2C driver to probe the codec. */ static int __init imx_3stack_ak4647_probe(struct platform_device *pdev) { struct mxc_audio_platform_data *dev_data = pdev->dev.platform_data; struct imx_3stack_priv *priv = &card_priv; struct snd_soc_dai *ak4647_cpu_dai; int ret = 0; dev_data->init(); if (dev_data->src_port == 1) ak4647_cpu_dai = imx_ssi_dai[0]; else ak4647_cpu_dai = imx_ssi_dai[2]; imx_3stack_dai.cpu_dai = ak4647_cpu_dai; imx_3stack_init_dam(dev_data->src_port, dev_data->ext_port); ret = request_irq(dev_data->intr_id_hp, imx_headphone_detect_handler, 0, "headphone", NULL); if (ret < 0) goto err; ret = driver_create_file(pdev->dev.driver, &driver_attr_headphone); if (ret < 0) goto sysfs_err; priv->pdev = pdev; return ret; sysfs_err: free_irq(dev_data->intr_id_hp, NULL); err: return ret; }
static int __devinit imx_wm1808_audio_probe(struct platform_device *pdev) { struct snd_soc_machine **machine = platform_get_drvdata(pdev); struct snd_soc_pcm_link *hifi; struct mxc_audio_platform_data *tmp; int ret, hp_status; dbg("%s: pdev->name=%s, machine->pcm_links=%d", __func__, pdev->name, (*machine)->pcm_links); (*machine)->owner = THIS_MODULE; (*machine)->pdev = pdev; (*machine)->name = "i.MX_SAMSUNG"; (*machine)->longname = "WM1808"; (*machine)->ops = &machine_ops; /* register card */ ret = snd_soc_new_card(*machine, 1, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); if (ret < 0) { err("%s: failed to create pcms\n", __func__); return ret; } /* WM1808 hifi interface */ ret = -ENODEV; tmp = pdev->dev.platform_data; if (tmp->src_port == 2) hifi = snd_soc_pcm_link_new(*machine, "imx_3stack-hifi", &imx_3stack_pcm_ops, imx_pcm, wm1808_codec, wm1808_hifi_dai, imx_ssi_3); else hifi = snd_soc_pcm_link_new(*machine, "imx_3stack-hifi", &imx_3stack_pcm_ops, imx_pcm, wm1808_codec, wm1808_hifi_dai, imx_ssi_1); if (hifi == NULL) { dbg("failed to create HiFi PCM link"); snd_soc_machine_free(*machine); return ret; } ret = snd_soc_pcm_link_attach(hifi); if (ret < 0) { dbg("%s: failed to attach hifi pcm", __func__); snd_soc_machine_free(*machine); return ret; } gpio_activate_audio_ports(); imx_3stack_init_dam(tmp->src_port, tmp->ext_port); return ret; }
static int __devinit imx_3stack_wm8350_probe(struct platform_device *pdev) { struct mxc_audio_platform_data *plat = pdev->dev.platform_data; struct imx_3stack_priv *priv = &machine_priv; struct wm8350 *wm8350 = plat->priv; struct snd_soc_dai *wm8350_cpu_dai; int ret = 0; u16 reg; priv->pdev = pdev; priv->wm8350 = wm8350; gpio_activate_audio_ports(); imx_3stack_init_dam(plat->src_port, plat->ext_port); if (plat->src_port == 2) wm8350_cpu_dai = imx_ssi_dai[2]; else wm8350_cpu_dai = imx_ssi_dai[0]; imx_3stack_dai.cpu_dai = wm8350_cpu_dai; ret = driver_create_file(pdev->dev.driver, &driver_attr_headphone); if (ret < 0) { pr_err("%s:failed to create driver_attr_headphone\n", __func__); return ret; } /* enable slow clock gen for jack detect */ reg = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_4); wm8350_reg_write(wm8350, WM8350_POWER_MGMT_4, reg | WM8350_TOCLK_ENA); /* enable jack detect */ reg = wm8350_reg_read(wm8350, WM8350_JACK_DETECT); wm8350_reg_write(wm8350, WM8350_JACK_DETECT, reg | WM8350_JDR_ENA); wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R, imx_3stack_jack_handler, NULL); wm8350_unmask_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R); wm8350_jack_func = 1; wm8350_spk_func = 1; return 0; }
/* * This function will register the snd_soc_pcm_link drivers. * It also registers devices for platform DMA, I2S, SSP and registers an * I2C driver to probe the codec. */ static int __init imx_3stack_bt_probe(struct platform_device *pdev) { struct mxc_audio_platform_data *dev_data = pdev->dev.platform_data; struct imx_3stack_priv *priv = &machine_priv; struct snd_soc_dai *cpu_dai; /* imx_3stack bt interface */ imx_ssi_dai_init(&imx_3stack_cpu_dai); imx_3stack_cpu_dai.private_data = dev_data; if (dev_data->src_port == 1) imx_3stack_cpu_dai.name = "imx-ssi-1"; else imx_3stack_cpu_dai.name = "imx-ssi-3"; /* Configure audio port */ imx_3stack_init_dam(dev_data->src_port, dev_data->ext_port); priv->pdev = pdev; priv->active = 0; return 0; }
static int mach_probe(struct snd_soc_machine *machine) { struct snd_soc_codec *codec; struct snd_soc_dai *codec_dai; struct snd_soc_pcm_link *pcm_link; struct platform_device *pdev = machine->pdev; struct mxc_sgtl5000_platform_data *plat = pdev->dev.platform_data; struct sgtl5000_platform_data *codec_data; struct imx_3stack_priv *priv; struct regulator *reg; int i, ret; pcm_link = list_first_entry(&machine->active_list, struct snd_soc_pcm_link, active_list); sgtl5000_3stack_pcm_link = pcm_link; codec = pcm_link->codec; codec_dai = pcm_link->codec_dai; codec_dai->ops->set_sysclk(codec_dai, 0, plat->sysclk, 0); priv = kzalloc(sizeof(struct imx_3stack_priv), GFP_KERNEL); if (!priv) return -ENOMEM; codec_data = kzalloc(sizeof(struct sgtl5000_platform_data), GFP_KERNEL); if (!codec_data) { ret = -ENOMEM; goto err_codec_data; } ret = -EINVAL; if (plat->init && plat->init()) goto err_plat_init; if (plat->vddio_reg) { reg = regulator_get(&pdev->dev, plat->vddio_reg); if (IS_ERR(reg)) goto err_reg_vddio; priv->reg_vddio = reg; } if (plat->vdda_reg) { reg = regulator_get(&pdev->dev, plat->vdda_reg); if (IS_ERR(reg)) goto err_reg_vdda; priv->reg_vdda = reg; } if (plat->vddd_reg) { reg = regulator_get(&pdev->dev, plat->vddd_reg); if (IS_ERR(reg)) goto err_reg_vddd; priv->reg_vddd = reg; } machine->platform_data = priv; if (priv->reg_vdda) { ret = regulator_set_voltage(priv->reg_vdda, plat->vdda); regulator_enable(priv->reg_vdda); } if (priv->reg_vddio) { regulator_set_voltage(priv->reg_vddio, plat->vddio); regulator_enable(priv->reg_vddio); } if (priv->reg_vddd) { regulator_set_voltage(priv->reg_vddd, plat->vddd); regulator_enable(priv->reg_vddd); } /* The SGTL5000 has an internal reset that is deasserted 8 SYS_MCLK cycles after all power rails have been brought up. After this time communication can start */ msleep(1); codec_data->vddio = plat->vddio / 1000; /* uV to mV */ codec_data->vdda = plat->vdda / 1000; codec_data->vddd = plat->vddd / 1000; codec->platform_data = codec_data; ret = codec->ops->io_probe(codec, machine); if (ret < 0) goto err_card_reg; gpio_activate_audio_ports(); imx_3stack_init_dam(plat->src_port, plat->ext_port); /* Add imx_3stack specific widgets */ for (i = 0; i < ARRAY_SIZE(imx_3stack_dapm_widgets); i++) { snd_soc_dapm_new_control(machine, codec, &imx_3stack_dapm_widgets[i]); } /* set up imx_3stack specific audio path audio map */ for (i = 0; audio_map[i][0] != NULL; i++) { snd_soc_dapm_connect_input(machine, audio_map[i][0], audio_map[i][1], audio_map[i][2]); } /* connect and enable all imx_3stack SGTL5000 jacks (for now) */ snd_soc_dapm_set_endpoint(machine, "Line In Jack", 1); snd_soc_dapm_set_endpoint(machine, "Mic Jack", 1); snd_soc_dapm_set_endpoint(machine, "Line Out Jack", 1); snd_soc_dapm_set_endpoint(machine, "Headphone Jack", 1); sgtl5000_jack_func = 1; sgtl5000_spk_func = 1; snd_soc_dapm_set_policy(machine, SND_SOC_DAPM_POLICY_STREAM); snd_soc_dapm_sync_endpoints(machine); for (i = 0; i < ARRAY_SIZE(sgtl5000_machine_controls); i++) { ret = snd_ctl_add(machine->card, snd_soc_cnew(&sgtl5000_machine_controls[i], codec, NULL)); if (ret < 0) goto err_card_reg; } /* register card with ALSA upper layers */ ret = snd_soc_register_card(machine); if (ret < 0) { pr_err("%s: failed to register sound card\n", __func__); goto err_card_reg; } if (plat->hp_status()) ret = request_irq(plat->hp_irq, imx_headphone_detect_handler, IRQT_FALLING, pdev->name, machine); else ret = request_irq(plat->hp_irq, imx_headphone_detect_handler, IRQT_RISING, pdev->name, machine); if (ret < 0) { pr_err("%s: request irq failed\n", __func__); goto err_card_reg; } return 0; err_card_reg: if (priv->reg_vddd) regulator_put(priv->reg_vddd, &pdev->dev); err_reg_vddd: if (priv->reg_vdda) regulator_put(priv->reg_vdda, &pdev->dev); err_reg_vdda: if (priv->reg_vddio) regulator_put(priv->reg_vddio, &pdev->dev); err_reg_vddio: if (plat->finit) plat->finit(); err_plat_init: kfree(codec_data); codec->platform_data = NULL; err_codec_data: kfree(priv); machine->platform_data = NULL; return ret; }
static int __init imx_3stack_audio_probe(struct platform_device *pdev) { struct snd_soc_machine *machine; struct mxc_audio_platform_data *dev_data = pdev->dev.platform_data; struct snd_soc_pcm_link *hifi; const char *ssi_port; int ret; machine = kzalloc(sizeof(struct snd_soc_machine), GFP_KERNEL); if (machine == NULL) return -ENOMEM; machine->owner = THIS_MODULE; machine->pdev = pdev; machine->name = "i.MX_3STACK"; machine->longname = "WM8903"; machine->ops = &imx_3stack_mach_ops; pdev->dev.driver_data = machine; /* register card */ imx_3stack_mach = machine; ret = snd_soc_new_card(machine, 1, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); if (ret < 0) { pr_err("%s: failed to create stereo sound card\n", __func__); goto err; } if (dev_data->src_port == 2) ssi_port = imx_ssi_3; else ssi_port = imx_ssi_1; hifi = snd_soc_pcm_link_new(machine, "imx_3stack-hifi", &imx_3stack_pcm_ops, imx_pcm, "wm8903-codec", "wm8903-hifi-dai", ssi_port); if (hifi == NULL) { pr_err("Failed to create HiFi PCM link\n"); snd_soc_machine_free(machine); goto err; } ret = snd_soc_pcm_link_attach(hifi); hifi->private_data = dev_data; if (ret < 0) goto link_err; imx_3stack_init_dam(dev_data->src_port, dev_data->ext_port); ret = driver_create_file(pdev->dev.driver, &driver_attr_headphone); if (ret < 0) goto sysfs_err; return ret; sysfs_err: driver_remove_file(pdev->dev.driver, &driver_attr_headphone); link_err: snd_soc_machine_free(machine); err: kfree(machine); return ret; }
static int __devinit imx_3stack_alc5623_probe(struct platform_device *pdev) { struct mxc_audio_platform_data *plat = pdev->dev.platform_data; struct imx_3stack_priv *priv = &card_priv; struct snd_soc_dai *alc5623_cpu_dai; struct alc5623_setup_data *setup; int ret = 0; priv->pdev = pdev; gpio_activate_audio_ports(); imx_3stack_init_dam(plat->src_port, plat->ext_port); if (plat->src_port == 2) alc5623_cpu_dai = imx_ssi_dai[2]; else if (plat->src_port == 1) alc5623_cpu_dai = imx_ssi_dai[0]; else if (plat->src_port == 7) alc5623_cpu_dai = imx_ssi_dai[4]; imx_3stack_dai.cpu_dai = alc5623_cpu_dai; ret = driver_create_file(pdev->dev.driver, &driver_attr_headphone); if (ret < 0) { pr_err("%s:failed to create driver_attr_headphone\n", __func__); goto sysfs_err; } ret = -EINVAL; if (plat->init && plat->init()) goto err_plat_init; priv->sysclk = plat->sysclk; /* The ALC5623 has an internal reset that is deasserted 8 SYS_MCLK cycles after all power rails have been brought up. After this time communication can start */ setup = kzalloc(sizeof(struct alc5623_setup_data), GFP_KERNEL); if (!setup) { pr_err("%s: kzalloc alc5623_setup_data failed\n", __func__); goto err_card_reg; } setup->clock_enable = plat->clock_enable; imx_3stack_snd_devdata.codec_data = setup; alc5623_jack_func = 1; alc5623_spk_func = 1; alc5623_line_in_func = 0; return 0; err_card_reg: if (plat->finit) plat->finit(); err_plat_init: driver_remove_file(pdev->dev.driver, &driver_attr_headphone); sysfs_err: return ret; }
static int __devinit imx_3stack_rt5621_probe(struct platform_device *pdev) { struct mxc_audio_platform_data *plat = pdev->dev.platform_data; struct imx_3stack_priv *priv = &card_priv; struct snd_soc_dai *rt5621_cpu_dai = 0; int ret = 0; priv->pdev = pdev; gpio_activate_audio_ports(); imx_3stack_init_dam(plat->src_port, plat->ext_port); if (plat->src_port == 2) rt5621_cpu_dai = imx_ssi_dai[2]; else if (plat->src_port == 1) rt5621_cpu_dai = imx_ssi_dai[0]; else if (plat->src_port == 7) rt5621_cpu_dai = imx_ssi_dai[4]; imx_3stack_dai.cpu_dai = rt5621_cpu_dai; ret = driver_create_file(pdev->dev.driver, &driver_attr_headphone); if (ret < 0) { pr_err("%s:failed to create driver_attr_headphone\n", __func__); goto sysfs_err; } ret = -EINVAL; if (plat->init && plat->init()) goto err_plat_init; priv->sysclk = plat->sysclk; /* The RT5621 has an internal reset that is deasserted 8 SYS_MCLK cycles after all power rails have been brought up. After this time communication can start */ if (plat->hp_status()) ret = request_irq(plat->hp_irq, imx_headphone_detect_handler, IRQ_TYPE_EDGE_FALLING, pdev->name, priv); else ret = request_irq(plat->hp_irq, imx_headphone_detect_handler, IRQ_TYPE_EDGE_RISING, pdev->name, priv); if (ret < 0) { pr_err("%s: request irq failed\n", __func__); goto err_card_reg; } rt5621_jack_func = 1; rt5621_spk_func = 1; rt5621_line_in_func = 0; return 0; err_card_reg: if (plat->finit) plat->finit(); err_plat_init: driver_remove_file(pdev->dev.driver, &driver_attr_headphone); sysfs_err: return ret; }