Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit efad6eed authored by Mark Brown's avatar Mark Brown
Browse files

Merge remote-tracking branch 'asoc/topic/twl' into asoc-next

parents b363bcaf 85becda6
Loading
Loading
Loading
Loading
+46 −0
Original line number Diff line number Diff line
@@ -6,6 +6,52 @@ Required properties:
- ti,mcbsp: phandle for the McBSP node
- ti,codec: phandle for the twl4030 audio node

Optional properties:
- ti,mcbsp-voice: phandle for the McBSP node connected to the voice port of twl
- ti, jack-det-gpio: Jack detect GPIO
- ti,audio-routing: List of connections between audio components.
  Each entry is a pair of strings, the first being the connection's sink,
  the second being the connection's source.
  If the routing is not provided all possible connection will be available

Available audio endpoints for the audio-routing table:

Board connectors:
 * Headset Stereophone
 * Earpiece Spk
 * Handsfree Spk
 * Ext Spk
 * Main Mic
 * Sub Mic
 * Headset Mic
 * Carkit Mic
 * Digital0 Mic
 * Digital1 Mic
 * Line In

twl4030 pins:
 * HSOL
 * HSOR
 * EARPIECE
 * HFL
 * HFR
 * PREDRIVEL
 * PREDRIVER
 * CARKITL
 * CARKITR
 * MAINMIC
 * SUBMIC
 * HSMIC
 * DIGIMIC0
 * DIGIMIC1
 * CARKITMIC
 * AUXL
 * AUXR

 * Headset Mic Bias
 * Mic Bias 1 /* Used for Main Mic or Digimic0 */
 * Mic Bias 2 /* Used for Sub Mic or Digimic1 */

Example:

sound {
+50 −35
Original line number Diff line number Diff line
@@ -41,6 +41,11 @@
/* Register descriptions are here */
#include <linux/mfd/twl4030-audio.h>

/* TWL4030 PMBR1 Register */
#define TWL4030_PMBR1_REG		0x0D
/* TWL4030 PMBR1 Register GPIO6 mux bits */
#define TWL4030_GPIO6_PWM0_MUTE(value)	((value & 0x03) << 2)

/* Shadow register used by the audio driver */
#define TWL4030_REG_SW_SHADOW		0x4A
#define TWL4030_CACHEREGNUM	(TWL4030_REG_SW_SHADOW + 1)
@@ -348,8 +353,8 @@ static void twl4030_init_chip(struct snd_soc_codec *codec)

	pdata = twl4030_get_pdata(codec);

	if (pdata && pdata->hs_extmute &&
	    gpio_is_valid(pdata->hs_extmute_gpio)) {
	if (pdata && pdata->hs_extmute) {
		if (gpio_is_valid(pdata->hs_extmute_gpio)) {
			int ret;

			if (!pdata->hs_extmute_gpio)
@@ -357,11 +362,24 @@ static void twl4030_init_chip(struct snd_soc_codec *codec)
					"Extmute GPIO is 0 is this correct?\n");

			ret = gpio_request_one(pdata->hs_extmute_gpio,
				       GPIOF_OUT_INIT_LOW, "hs_extmute");
					       GPIOF_OUT_INIT_LOW,
					       "hs_extmute");
			if (ret) {
			dev_err(codec->dev, "Failed to get hs_extmute GPIO\n");
				dev_err(codec->dev,
					"Failed to get hs_extmute GPIO\n");
				pdata->hs_extmute_gpio = -1;
			}
		} else {
			u8 pin_mux;

			/* Set TWL4030 GPIO6 as EXTMUTE signal */
			twl_i2c_read_u8(TWL4030_MODULE_INTBR, &pin_mux,
					TWL4030_PMBR1_REG);
			pin_mux &= ~TWL4030_GPIO6_PWM0_MUTE(0x03);
			pin_mux |= TWL4030_GPIO6_PWM0_MUTE(0x02);
			twl_i2c_write_u8(TWL4030_MODULE_INTBR, pin_mux,
					 TWL4030_PMBR1_REG);
		}
	}

	/* Check defaults, if instructed before anything else */
@@ -1306,6 +1324,9 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
	SND_SOC_DAPM_DAC("DAC Left2", NULL, SND_SOC_NOPM, 0, 0),
	SND_SOC_DAPM_DAC("DAC Voice", NULL, SND_SOC_NOPM, 0, 0),

	SND_SOC_DAPM_AIF_IN("VAIFIN", "Voice Playback", 0,
			    TWL4030_REG_VOICE_IF, 6, 0),

	/* Analog bypasses */
	SND_SOC_DAPM_SWITCH("Right1 Analog Loopback", SND_SOC_NOPM, 0, 0,
			&twl4030_dapm_abypassr1_control),
@@ -1438,6 +1459,9 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
	SND_SOC_DAPM_ADC("ADC Virtual Left2", NULL, SND_SOC_NOPM, 0, 0),
	SND_SOC_DAPM_ADC("ADC Virtual Right2", NULL, SND_SOC_NOPM, 0, 0),

	SND_SOC_DAPM_AIF_OUT("VAIFOUT", "Voice Capture", 0,
			     TWL4030_REG_VOICE_IF, 5, 0),

	/* Analog/Digital mic path selection.
	   TX1 Left/Right: either analog Left/Right or Digimic0
	   TX2 Left/Right: either analog Left/Right or Digimic1 */
@@ -1473,10 +1497,15 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
	SND_SOC_DAPM_SUPPLY("micbias2 select", TWL4030_REG_MICBIAS_CTL, 6, 0,
			    NULL, 0),

	SND_SOC_DAPM_MICBIAS("Mic Bias 1", TWL4030_REG_MICBIAS_CTL, 0, 0),
	SND_SOC_DAPM_MICBIAS("Mic Bias 2", TWL4030_REG_MICBIAS_CTL, 1, 0),
	SND_SOC_DAPM_MICBIAS("Headset Mic Bias", TWL4030_REG_MICBIAS_CTL, 2, 0),
	/* Microphone bias */
	SND_SOC_DAPM_SUPPLY("Mic Bias 1",
			    TWL4030_REG_MICBIAS_CTL, 0, 0, NULL, 0),
	SND_SOC_DAPM_SUPPLY("Mic Bias 2",
			    TWL4030_REG_MICBIAS_CTL, 1, 0, NULL, 0),
	SND_SOC_DAPM_SUPPLY("Headset Mic Bias",
			    TWL4030_REG_MICBIAS_CTL, 2, 0, NULL, 0),

	SND_SOC_DAPM_SUPPLY("VIF Enable", TWL4030_REG_VOICE_IF, 0, 0, NULL, 0),
};

static const struct snd_soc_dapm_route intercon[] = {
@@ -1485,17 +1514,16 @@ static const struct snd_soc_dapm_route intercon[] = {
	{"DAC Left1", NULL, "HiFi Playback"},
	{"DAC Right2", NULL, "HiFi Playback"},
	{"DAC Left2", NULL, "HiFi Playback"},
	{"DAC Voice", NULL, "Voice Playback"},
	{"DAC Voice", NULL, "VAIFIN"},

	/* ADC -> Stream mapping */
	{"HiFi Capture", NULL, "ADC Virtual Left1"},
	{"HiFi Capture", NULL, "ADC Virtual Right1"},
	{"HiFi Capture", NULL, "ADC Virtual Left2"},
	{"HiFi Capture", NULL, "ADC Virtual Right2"},
	{"Voice Capture", NULL, "ADC Virtual Left1"},
	{"Voice Capture", NULL, "ADC Virtual Right1"},
	{"Voice Capture", NULL, "ADC Virtual Left2"},
	{"Voice Capture", NULL, "ADC Virtual Right2"},
	{"VAIFOUT", NULL, "ADC Virtual Left2"},
	{"VAIFOUT", NULL, "ADC Virtual Right2"},
	{"VAIFOUT", NULL, "VIF Enable"},

	{"Digital L1 Playback Mixer", NULL, "DAC Left1"},
	{"Digital R1 Playback Mixer", NULL, "DAC Right1"},
@@ -1510,6 +1538,7 @@ static const struct snd_soc_dapm_route intercon[] = {
	{"DAC Right1", NULL, "AIF Enable"},
	{"DAC Left2", NULL, "AIF Enable"},
	{"DAC Right1", NULL, "AIF Enable"},
	{"DAC Voice", NULL, "VIF Enable"},

	{"Digital R2 Playback Mixer", NULL, "AIF Enable"},
	{"Digital L2 Playback Mixer", NULL, "AIF Enable"},
@@ -2267,18 +2296,6 @@ static struct snd_soc_dai_driver twl4030_dai[] = {
},
};

static int twl4030_soc_suspend(struct snd_soc_codec *codec)
{
	twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF);
	return 0;
}

static int twl4030_soc_resume(struct snd_soc_codec *codec)
{
	twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
	return 0;
}

static int twl4030_soc_probe(struct snd_soc_codec *codec)
{
	struct twl4030_priv *twl4030;
@@ -2316,8 +2333,6 @@ static int twl4030_soc_remove(struct snd_soc_codec *codec)
static struct snd_soc_codec_driver soc_codec_dev_twl4030 = {
	.probe = twl4030_soc_probe,
	.remove = twl4030_soc_remove,
	.suspend = twl4030_soc_suspend,
	.resume = twl4030_soc_resume,
	.read = twl4030_read_reg_cache,
	.write = twl4030_write,
	.set_bias_level = twl4030_set_bias_level,
+9 −53
Original line number Diff line number Diff line
@@ -69,13 +69,8 @@ struct twl6040_data {
	int hs_power_mode_locked;
	unsigned int clk_in;
	unsigned int sysclk;
	u16 hs_left_step;
	u16 hs_right_step;
	u16 hf_left_step;
	u16 hf_right_step;
	struct twl6040_jack_data hs_jack;
	struct snd_soc_codec *codec;
	struct workqueue_struct *workqueue;
	struct mutex mutex;
};

@@ -404,8 +399,7 @@ static irqreturn_t twl6040_audio_handler(int irq, void *data)
	struct snd_soc_codec *codec = data;
	struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);

	queue_delayed_work(priv->workqueue, &priv->hs_jack.work,
			   msecs_to_jiffies(200));
	schedule_delayed_work(&priv->hs_jack.work, msecs_to_jiffies(200));

	return IRQ_HANDLED;
}
@@ -1115,7 +1109,6 @@ static int twl6040_suspend(struct snd_soc_codec *codec)
static int twl6040_resume(struct snd_soc_codec *codec)
{
	twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
	twl6040_set_bias_level(codec, codec->dapm.suspend_bias_level);

	return 0;
}
@@ -1127,83 +1120,46 @@ static int twl6040_resume(struct snd_soc_codec *codec)
static int twl6040_probe(struct snd_soc_codec *codec)
{
	struct twl6040_data *priv;
	struct twl6040_codec_data *pdata = dev_get_platdata(codec->dev);
	struct platform_device *pdev = container_of(codec->dev,
						   struct platform_device, dev);
	int ret = 0;

	priv = kzalloc(sizeof(struct twl6040_data), GFP_KERNEL);
	priv = devm_kzalloc(codec->dev, sizeof(*priv), GFP_KERNEL);
	if (priv == NULL)
		return -ENOMEM;

	snd_soc_codec_set_drvdata(codec, priv);

	priv->codec = codec;
	codec->control_data = dev_get_drvdata(codec->dev->parent);

	if (pdata && pdata->hs_left_step && pdata->hs_right_step) {
		priv->hs_left_step = pdata->hs_left_step;
		priv->hs_right_step = pdata->hs_right_step;
	} else {
		priv->hs_left_step = 1;
		priv->hs_right_step = 1;
	}

	if (pdata && pdata->hf_left_step && pdata->hf_right_step) {
		priv->hf_left_step = pdata->hf_left_step;
		priv->hf_right_step = pdata->hf_right_step;
	} else {
		priv->hf_left_step = 1;
		priv->hf_right_step = 1;
	}

	priv->plug_irq = platform_get_irq(pdev, 0);
	if (priv->plug_irq < 0) {
		dev_err(codec->dev, "invalid irq\n");
		ret = -EINVAL;
		goto work_err;
	}

	priv->workqueue = alloc_workqueue("twl6040-codec", 0, 0);
	if (!priv->workqueue) {
		ret = -ENOMEM;
		goto work_err;
		return -EINVAL;
	}

	INIT_DELAYED_WORK(&priv->hs_jack.work, twl6040_accessory_work);

	mutex_init(&priv->mutex);

	ret = request_threaded_irq(priv->plug_irq, NULL, twl6040_audio_handler,
				   0, "twl6040_irq_plug", codec);
	ret = devm_request_threaded_irq(codec->dev, priv->plug_irq, NULL,
					twl6040_audio_handler, IRQF_NO_SUSPEND,
					"twl6040_irq_plug", codec);
	if (ret) {
		dev_err(codec->dev, "PLUG IRQ request failed: %d\n", ret);
		goto plugirq_err;
		return ret;
	}

	twl6040_init_chip(codec);

	/* power on device */
	ret = twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
	if (!ret)
		return 0;

	/* Error path */
	free_irq(priv->plug_irq, codec);
plugirq_err:
	destroy_workqueue(priv->workqueue);
work_err:
	kfree(priv);
	return ret;
	return twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
}

static int twl6040_remove(struct snd_soc_codec *codec)
{
	struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);

	twl6040_set_bias_level(codec, SND_SOC_BIAS_OFF);
	free_irq(priv->plug_irq, codec);
	destroy_workqueue(priv->workqueue);
	kfree(priv);

	return 0;
}
+2 −17
Original line number Diff line number Diff line
@@ -70,15 +70,6 @@ config SND_OMAP_SOC_AM3517EVM
	  Say Y if you want to add support for SoC audio on the OMAP3517 / AM3517
	  EVM.

config SND_OMAP_SOC_SDP3430
	tristate "SoC Audio support for Texas Instruments SDP3430"
	depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP_3430SDP
	select SND_OMAP_SOC_MCBSP
	select SND_SOC_TWL4030
	help
	  Say Y if you want to add support for SoC audio on Texas Instruments
	  SDP3430.

config SND_OMAP_SOC_OMAP_TWL4030
	tristate "SoC Audio support for TI SoC based boards with twl4030 codec"
	depends on TWL4030_CORE && SND_OMAP_SOC
@@ -91,6 +82,8 @@ config SND_OMAP_SOC_OMAP_TWL4030
	  - Gumstix Overo or CompuLab CM-T35/CM-T3730
	  - IGEP v2
	  - OMAP3EVM
	  - SDP3430
	  - Zoom2

config SND_OMAP_SOC_OMAP_ABE_TWL6040
	tristate "SoC Audio support for OMAP boards using ABE and twl6040 codec"
@@ -123,11 +116,3 @@ config SND_OMAP_SOC_OMAP3_PANDORA
	select SND_SOC_TWL4030
	help
	  Say Y if you want to add support for SoC audio on the OMAP3 Pandora.

config SND_OMAP_SOC_ZOOM2
	tristate "SoC Audio support for Zoom2"
	depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP_ZOOM2
	select SND_OMAP_SOC_MCBSP
	select SND_SOC_TWL4030
	help
	  Say Y if you want to add support for Soc audio on Zoom2 board.
+0 −4
Original line number Diff line number Diff line
@@ -17,11 +17,9 @@ snd-soc-rx51-objs := rx51.o
snd-soc-ams-delta-objs := ams-delta.o
snd-soc-osk5912-objs := osk5912.o
snd-soc-am3517evm-objs := am3517evm.o
snd-soc-sdp3430-objs := sdp3430.o
snd-soc-omap-abe-twl6040-objs := omap-abe-twl6040.o
snd-soc-omap-twl4030-objs := omap-twl4030.o
snd-soc-omap3pandora-objs := omap3pandora.o
snd-soc-zoom2-objs := zoom2.o
snd-soc-omap-hdmi-card-objs := omap-hdmi-card.o

obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o
@@ -30,9 +28,7 @@ obj-$(CONFIG_SND_OMAP_SOC_AMS_DELTA) += snd-soc-ams-delta.o
obj-$(CONFIG_SND_OMAP_SOC_OSK5912) += snd-soc-osk5912.o
obj-$(CONFIG_SND_OMAP_SOC_OMAP2EVM) += snd-soc-omap2evm.o
obj-$(CONFIG_SND_OMAP_SOC_AM3517EVM) += snd-soc-am3517evm.o
obj-$(CONFIG_SND_OMAP_SOC_SDP3430) += snd-soc-sdp3430.o
obj-$(CONFIG_SND_OMAP_SOC_OMAP_ABE_TWL6040) += snd-soc-omap-abe-twl6040.o
obj-$(CONFIG_SND_OMAP_SOC_OMAP_TWL4030) += snd-soc-omap-twl4030.o
obj-$(CONFIG_SND_OMAP_SOC_OMAP3_PANDORA) += snd-soc-omap3pandora.o
obj-$(CONFIG_SND_OMAP_SOC_ZOOM2) += snd-soc-zoom2.o
obj-$(CONFIG_SND_OMAP_SOC_OMAP_HDMI) += snd-soc-omap-hdmi-card.o
Loading