static int sdp4430_mcpdm_startup(struct snd_pcm_substream *substream)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_codec *codec = rtd->codec;
	struct snd_soc_dai *codec_dai = rtd->codec_dai;
	struct twl6040 *twl6040 = codec->control_data;
	int clk_id, freq, ret;

	/* TWL6040 supplies McPDM PAD_CLKS */
	ret = twl6040_enable(twl6040);
	if (ret) {
		printk(KERN_ERR "failed to enable TWL6040\n");
		return ret;
	}

	if (twl6040_power_mode) {
		clk_id = TWL6040_HPPLL_ID;
		/*freq = 38400000;*/
		freq = 26000000;

		/*
		 * TWL6040 requires MCLK to be active as long as
		 * high-performance mode is in use. Glitch-free mux
		 * cannot tolerate MCLK gating
		 */
		ret = cdc_tcxo_set_req_int(CDC_TCXO_CLK2, 1);
		if (ret) {
			printk(KERN_ERR "failed to enable twl6040 MCLK\n");
			goto err;
		}
	} else {
		clk_id = TWL6040_LPPLL_ID;
		freq = 32768;
	}

	/* set the codec mclk */
	ret = snd_soc_dai_set_sysclk(codec_dai, clk_id, freq,
				SND_SOC_CLOCK_IN);
	if (ret) {
		printk(KERN_ERR "can't set codec system clock\n");
		goto err;
	}

	/* low-power mode uses 32k clock, MCLK is not required */
	if (!twl6040_power_mode) {
		ret = cdc_tcxo_set_req_int(CDC_TCXO_CLK2, 0);
		if (ret)
			printk(KERN_ERR "failed to disable twl6040 MCLK\n");
	}

	return 0;

err:
	twl6040_disable(twl6040);
	return ret;
}
Example #2
0
static void __exit sdp4430_soc_exit(void)
{
#if 0 //Ti patch
	regulator_put(av_switch_reg);
	cdc_tcxo_set_req_int(CDC_TCXO_CLK2, 0);
	cdc_tcxo_set_req_prio(CDC_TCXO_CLK2, CDC_TCXO_PRIO_REQINT);
#else
	cdc_tcxo_set_req_int(CDC_TCXO_CLK3, 0);
	cdc_tcxo_set_req_prio(CDC_TCXO_CLK3, CDC_TCXO_PRIO_REQINT);
#endif
	platform_device_unregister(sdp4430_snd_device);
	snd_soc_unregister_dais(&sdp4430_snd_device->dev, ARRAY_SIZE(dai));
}
Example #3
0
static int sdp4430_mcpdm_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;
	int clk_id, freq;
	int ret = 0;

	if (twl6040_power_mode) {
		clk_id = TWL6040_SYSCLK_SEL_HPPLL;
		freq = 38400000;
		/*
		 * TWL6040 requires MCLK to be active as long as
		 * high-performance mode is in use. Glitch-free mux
		 * cannot tolerate MCLK gating
		 */
		ret = cdc_tcxo_set_req_int(CDC_TCXO_CLK2, 1);
		if (ret) {
			printk(KERN_ERR "failed to enable twl6040 MCLK\n");
			return ret;
		}
	} else {
		clk_id = TWL6040_SYSCLK_SEL_LPPLL;
		freq = 32768;
	}

	/* set the codec mclk */
	ret = snd_soc_dai_set_sysclk(codec_dai, clk_id, freq,
				SND_SOC_CLOCK_IN);
	if (ret) {
		printk(KERN_ERR "can't set codec system clock\n");
		return ret;
	}

	/* low-power mode uses 32k clock, MCLK is not required */
	if (!twl6040_power_mode) {
		ret = cdc_tcxo_set_req_int(CDC_TCXO_CLK2, 0);
		if (ret) {
			printk(KERN_ERR "failed to disable twl6040 MCLK\n");
			return ret;
		}
	}

	if (rtd->current_fe == ABE_FRONTEND_DAI_MODEM) {
		/* set Modem McBSP configuration  */
		ret = sdp4430_modem_mcbsp_configure(substream, params, 1);
	}

	return ret;
}
Example #4
0
static int __init sdp4430_soc_init(void)
{
	int ret = 0;

	if (!machine_is_omap_4430sdp() &&
		!machine_is_omap_tabletblaze()) {
		pr_debug("Not SDP4430 or BlazeTablet\n");
		return -ENODEV;
	}
	printk(KERN_INFO "SDP4430 SoC init\n");

	sdp4430_snd_device = platform_device_alloc("soc-audio", -1);
	if (!sdp4430_snd_device) {
		printk(KERN_ERR "Platform device allocation failed\n");
		return -ENOMEM;
	}

	snd_soc_register_dais(&sdp4430_snd_device->dev, dai, ARRAY_SIZE(dai));

	platform_set_drvdata(sdp4430_snd_device, &snd_soc_sdp4430);

	ret = platform_device_add(sdp4430_snd_device);
	if (ret)
		goto plat_err;

	av_switch_reg = regulator_get(&sdp4430_snd_device->dev, "av-switch");
	if (IS_ERR(av_switch_reg)) {
		ret = PTR_ERR(av_switch_reg);
		printk(KERN_ERR "couldn't get AV Switch regulator %d\n",
			ret);
		goto reg_err;
	}

	/* Default mode is low-power, MCLK not required */
	twl6040_power_mode = 0;
	cdc_tcxo_set_req_int(CDC_TCXO_CLK2, 0);

	/*
	 * CDC CLK2 supplies TWL6040 MCLK, drive it from REQ2INT to
	 * have full control of MCLK gating
	 */
	cdc_tcxo_set_req_prio(CDC_TCXO_CLK2, CDC_TCXO_PRIO_REQINT);

	return ret;

reg_err:
	platform_device_del(sdp4430_snd_device);
plat_err:
	printk(KERN_ERR "Unable to add platform device\n");
	platform_device_put(sdp4430_snd_device);
	return ret;
}
Example #5
0
static int __init cosmopolitan_soc_init(void)
{
	int ret;

	if (!machine_is_cosmopolitan()) {
		pr_debug("Not COSMOPOLITAN!\n");
		return -ENODEV;
	}
	printk(KERN_INFO "COSMOPOLITAN SoC init\n");

	sdp4430_snd_device = platform_device_alloc("soc-audio", -1);
	if (!sdp4430_snd_device) {
		printk(KERN_ERR "Platform device allocation failed\n");
		return -ENOMEM;
	}

	snd_soc_register_dais(&sdp4430_snd_device->dev, dai, ARRAY_SIZE(dai));

	platform_set_drvdata(sdp4430_snd_device, &snd_soc_sdp4430);

	ret = platform_device_add(sdp4430_snd_device);
	if (ret)
		goto plat_err;

	/* Default mode is low-power, MCLK not required */
	twl6040_power_mode = 0;
	cdc_tcxo_set_req_int(CDC_TCXO_CLK2, 0);

	/*
	 * CDC CLK2 supplies TWL6040 MCLK, drive it from REQ2INT to
	 * have full control of MCLK gating
	 */
	cdc_tcxo_set_req_prio(CDC_TCXO_CLK2, CDC_TCXO_PRIO_REQINT);

	return ret;

plat_err:
	printk(KERN_ERR "Unable to add platform device\n");
	platform_device_put(sdp4430_snd_device);
	return ret;
}
Example #6
0
static int twl6040_probe(struct snd_soc_codec *codec)
{
	struct twl4030_codec_audio_data *twl_codec = codec->dev->platform_data;
	struct twl6040_data *priv;
	struct twl6040_jack_data *jack;
	int audpwron, naudint;
	struct input_dev *ip_dev;

#if defined(CONFIG_MACH_LGE_COSMO_REV_A)
	unsigned hsjack_gpio, hsjack_irq;
	int err;
#endif
	int ret = 0;
	u8 icrev = 0, intmr = TWL6040_ALLINT_MSK;
	int idx;

	for( idx = 0 ; idx < TWL6040_MUTE_DATA_MAX ; idx++ )
	{
		s_mute_data[idx].dai = 0;
		s_mute_data[idx].mute = 0;
	}
	
	priv = kzalloc(sizeof(struct twl6040_data), GFP_KERNEL);
	if (priv == NULL)
		return -ENOMEM;
	snd_soc_codec_set_drvdata(codec, priv);

	priv->codec = codec;
	priv->dl_active = 0;
	priv->ul_active = 0;

	twl6040_i2c_read(TWL6040_REG_ASICREV, &icrev);

	if (twl_codec && (icrev > 0))
		audpwron = twl_codec->audpwron_gpio;
	else
		audpwron = -EINVAL;

#if defined(CONFIG_MACH_LGE_COSMO_REV_A)
	if (twl_codec){
		naudint = twl_codec->naudint_irq;
		hsjack_gpio = twl_codec->hsjack_gpio;
		hsjack_irq = twl_codec->hsjack_irq;
	}
	else {
		naudint = 0;
		hsjack_gpio = 0;
		hsjack_irq = 0;
	}
#else
	if (twl_codec)
		naudint = twl_codec->naudint_irq;
	else
		naudint = 0;
#endif

	priv->audpwron = audpwron;
	priv->naudint = naudint;
	
#if defined(CONFIG_MACH_LGE_COSMO_REV_A)
	priv->hsjack_gpio = hsjack_gpio;
	priv->hsjack_irq = hsjack_irq;
#endif
	init_completion(&priv->ready);

	/* Disable safe mode in SYS_NIRQ PAD */
//	omap_writew(0x0118, 0x4A1001A0);

	INIT_DELAYED_WORK(&priv->hsdet_dwork, twl6040_hs_jack_detect_dwork);
	INIT_DELAYED_WORK(&priv->hook_work, twl6040_hs_hook_detect_work);

#ifndef CONFIG_MACH_LGE_COSMOPOLITAN
	INIT_WORK(&priv->audint_work, twl6040_audint_work);
#endif

	ip_dev	= input_allocate_device();
	if(!ip_dev){
		dev_err(codec->dev, "failed to allocation hook input device");
		goto switch_err;
	}
	__set_bit(EV_KEY, ip_dev->evbit);
	__set_bit(EV_SYN, ip_dev->evbit);
	__set_bit(KEY_HOOK, ip_dev->keybit);
	ip_dev->name = "headset_hook";
	ip_dev->phys = "headset_hook/input0";
	priv->hs_jack.headset_input = ip_dev;
	input_register_device(priv->hs_jack.headset_input);

	/* switch-class based headset detection */
	jack = &priv->hs_jack;
	jack->sdev.name = "h2w";
	ret = switch_dev_register(&jack->sdev);
	if (ret) {
		dev_err(codec->dev, "error registering switch device %d\n", ret);
		goto switch_err;
	}
#if defined(CONFIG_MACH_LGE_COSMO_REV_A)
	/* GPIO request and direction set */
	if(gpio_is_valid(hsjack_gpio)) {
		err = gpio_request(hsjack_gpio, "ear_sense");
		if (err) {
			printk(KERN_ERR "%s: failed to request GPIO_%d\n",
				   __func__, hsjack_gpio);
			goto err_hs_gpio_request;
		}
		err = gpio_direction_input(hsjack_gpio);
		if (err) {
			printk(KERN_ERR "%s: failed to set direction GPIO_%d\n",
				   __func__, hsjack_gpio);
			goto err_hs_gpio_direction;
		}
	}

	/* IRQ request */
	err = request_irq(hsjack_irq,
					  hsjack_irq_handler,
					  IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
					  "headset_detect",
					  codec);
	if (err) {
		printk(KERN_ERR "%s: failed to request irq (%d)\n",
			   __func__, hsjack_irq);
		goto err_hs_request_irq;
	}
#endif

	if (gpio_is_valid(audpwron)) {
		ret = gpio_request(audpwron, "audpwron");
		if (ret)
			goto gpio1_err;

		ret = gpio_direction_output(audpwron, 0);
		if (ret)
			goto gpio2_err;

		priv->codec_powered = 0;

		/* enable only codec ready interrupt */
		intmr &= ~(TWL6040_READYMSK | TWL6040_PLUGMSK );
		priv->intmask = intmr; 

		/* reset interrupt status to allow correct power up sequence */
		twl6040_read_reg_volatile(codec, TWL6040_REG_INTID);
	}
	twl6040_write(codec, TWL6040_REG_INTMR, intmr);

	if (naudint) {
		/* audio interrupt */
		ret = request_threaded_irq(naudint, NULL,
				twl6040_naudint_handler,
				IRQF_TRIGGER_LOW | IRQF_ONESHOT,
				"twl6040_codec", codec);
		if (ret)
			goto gpio2_err;
	}

	/* init vio registers */
	twl6040_init_vio_regs(codec);

	/* power on device */
	ret = twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
	if (ret)
		goto bias_err;

	snd_soc_add_controls(codec, twl6040_snd_controls,
				ARRAY_SIZE(twl6040_snd_controls));
	twl6040_add_widgets(codec);

	wake_lock_init(&priv->wake_lock, WAKE_LOCK_SUSPEND, "twl6040");

	cdc_tcxo_set_req_int(CDC_TCXO_CLK3, 0);

	/* TODO: read HS jack insertion status */

	return 0;

bias_err:
	if (naudint)
		free_irq(naudint, codec);
#if defined(CONFIG_MACH_LGE_COSMO_REV_A)
err_hs_request_irq:
err_hs_gpio_direction:
	if (gpio_is_valid(hsjack_gpio))
		gpio_free(hsjack_gpio);
err_hs_gpio_request:
#endif
gpio2_err:
	if (gpio_is_valid(audpwron))
		gpio_free(audpwron);
gpio1_err:
	switch_dev_unregister(&jack->sdev);
switch_err:
	kfree(priv);
	return ret;
}
static int __init sdp4430_soc_init(void)
{
	int ret;

	if (!machine_is_omap_4430sdp() && !machine_is_omap4_panda() &&
		!machine_is_omap_tabletblaze()) {
		pr_debug("Not SDP4430, BlazeTablet or PandaBoard!\n");
		return -ENODEV;
	}
	printk(KERN_INFO "SDP4430 SoC init\n");
	if (machine_is_omap_4430sdp())
		snd_soc_sdp4430.name = "SDP4430";
	else if (machine_is_omap4_panda())
		snd_soc_sdp4430.name = "Panda";
	else if (machine_is_omap_tabletblaze())
		snd_soc_sdp4430.name = "Tablet44xx";

	sdp4430_snd_device = platform_device_alloc("soc-audio", -1);
	if (!sdp4430_snd_device) {
		printk(KERN_ERR "Platform device allocation failed\n");
		return -ENOMEM;
	}

	ret = snd_soc_register_dais(&sdp4430_snd_device->dev, dai, ARRAY_SIZE(dai));
	if (ret < 0)
		goto err;
	platform_set_drvdata(sdp4430_snd_device, &snd_soc_sdp4430);

	ret = platform_device_add(sdp4430_snd_device);
	if (ret)
		goto err_dev;

	twl6040_codec = snd_soc_card_get_codec(&snd_soc_sdp4430,
					"twl6040-codec");
	if(twl6040_codec <= 0) {
		printk(KERN_ERR "sdp4430: could not find `twl6040-codec`\n");
		ret = -ENODEV;
		goto err_dev;
	}

	/*av_switch_reg = regulator_get(&sdp4430_snd_device->dev, "av-switch");
	if (IS_ERR(av_switch_reg)) {
		ret = PTR_ERR(av_switch_reg);
		printk(KERN_ERR "couldn't get AV Switch regulator %d\n",
			ret);
		goto err_dev;
	}*/

	/* Default mode is low-power, MCLK not required */
	twl6040_power_mode = 0;
	cdc_tcxo_set_req_int(CDC_TCXO_CLK2, 0);

	/*
	 * CDC CLK2 supplies TWL6040 MCLK, drive it from REQ2INT to
	 * have full control of MCLK gating
	 */
	cdc_tcxo_set_req_prio(CDC_TCXO_CLK2, CDC_TCXO_PRIO_REQINT);

	return ret;

err_dev:
	snd_soc_unregister_dais(&sdp4430_snd_device->dev, ARRAY_SIZE(dai));
err:
	platform_device_put(sdp4430_snd_device);
	return ret;
}
Example #8
0
static int __init sdp4430_soc_init(void)
{
	u8 gpoctl;
	int ret;

//  Need Fix
//	if (!machine_is_p2() && !machine_is_lghdk() && !machine_is_iff() && !machine_is_u2) {
//		printk("Not Supported Sound Device\n");
//		return -ENODEV;
//	}
	printk(KERN_INFO "LG SoC init\n");
	if (machine_is_lghdk())
                snd_soc_sdp4430.name = "lghdk";
        else if(machine_is_p2())
                snd_soc_sdp4430.name = "p2";
        else if(machine_is_iff())
                snd_soc_sdp4430.name = "iff";
// Need Fix
	else
		snd_soc_sdp4430.name = "u2";

	sdp4430_snd_device = platform_device_alloc("soc-audio", -1);
	if (!sdp4430_snd_device) {
		printk(KERN_ERR "Platform device allocation failed\n");
		return -ENOMEM;
	}

	ret = snd_soc_register_dais(&sdp4430_snd_device->dev, dai, ARRAY_SIZE(dai));
	if (ret < 0)
		goto err;
	platform_set_drvdata(sdp4430_snd_device, &snd_soc_sdp4430);

	ret = platform_device_add(sdp4430_snd_device);
	if (ret)
		goto err_dev;

	twl6040_codec = snd_soc_card_get_codec(&snd_soc_sdp4430,
					"twl6040-codec");
	if(twl6040_codec <= 0) {
		printk(KERN_ERR "sdp4430: could not find `twl6040-codec`\n");
		ret = -ENODEV;
		goto err_dev;
	}

#if 0 //Ti patch
	av_switch_reg = regulator_get(&sdp4430_snd_device->dev, "av-switch");
	if (IS_ERR(av_switch_reg)) {
		ret = PTR_ERR(av_switch_reg);
		printk(KERN_ERR "couldn't get AV Switch regulator %d\n",
			ret);
		goto err_dev;
	}

	/* Default mode is low-power, MCLK not required */
	twl6040_power_mode = 0;
	cdc_tcxo_set_req_int(CDC_TCXO_CLK2, 0);

	/*
	 * CDC CLK2 supplies TWL6040 MCLK, drive it from REQ2INT to
	 * have full control of MCLK gating
	 */
	cdc_tcxo_set_req_prio(CDC_TCXO_CLK2, CDC_TCXO_PRIO_REQINT);

	return ret;
#else //                                              

	/* Default mode is low-power, MCLK not required */
	twl6040_power_mode = 0;	//  Set Default mode is High-Performace power

	//                                                                                        
	//cdc_tcxo_set_req_int(CDC_TCXO_CLK3, 0);
	cdc_tcxo_set_req_int(CDC_TCXO_CLK3, 1);
	//                                                                                      

	/*
	 * CDC CLK2 supplies TWL6040 MCLK, drive it from REQ2INT to
	 * have full control of MCLK gating
	 */
	cdc_tcxo_set_req_prio(CDC_TCXO_CLK3, CDC_TCXO_PRIO_REQINT);

	return 0;
#endif

err_dev:
	snd_soc_unregister_dais(&sdp4430_snd_device->dev, ARRAY_SIZE(dai));
err:
	platform_device_put(sdp4430_snd_device);
	return ret;
}