Exemplo n.º 1
0
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;
}
Exemplo n.º 2
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;
}
Exemplo n.º 3
0
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;

}
Exemplo n.º 4
0
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;

}
Exemplo n.º 6
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;
}
Exemplo n.º 7
0
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;
}
Exemplo n.º 9
0
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;
}