Skip to content

Commit

Permalink
Merge remote-tracking branch 'asoc/topic/twl' into asoc-next
Browse files Browse the repository at this point in the history
  • Loading branch information
Mark Brown committed Feb 11, 2013
2 parents b363bca + 85becda commit efad6ee
Show file tree
Hide file tree
Showing 9 changed files with 313 additions and 600 deletions.
46 changes: 46 additions & 0 deletions Documentation/devicetree/bindings/sound/omap-twl4030.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
85 changes: 50 additions & 35 deletions sound/soc/codecs/twl4030.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -348,19 +353,32 @@ 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)) {
int ret;

if (!pdata->hs_extmute_gpio)
dev_warn(codec->dev,
"Extmute GPIO is 0 is this correct?\n");

ret = gpio_request_one(pdata->hs_extmute_gpio,
GPIOF_OUT_INIT_LOW, "hs_extmute");
if (ret) {
dev_err(codec->dev, "Failed to get hs_extmute GPIO\n");
pdata->hs_extmute_gpio = -1;
if (pdata && pdata->hs_extmute) {
if (gpio_is_valid(pdata->hs_extmute_gpio)) {
int ret;

if (!pdata->hs_extmute_gpio)
dev_warn(codec->dev,
"Extmute GPIO is 0 is this correct?\n");

ret = gpio_request_one(pdata->hs_extmute_gpio,
GPIOF_OUT_INIT_LOW,
"hs_extmute");
if (ret) {
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);
}
}

Expand Down Expand Up @@ -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),
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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[] = {
Expand All @@ -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"},
Expand All @@ -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"},
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand Down
62 changes: 9 additions & 53 deletions sound/soc/codecs/twl6040.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};

Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand All @@ -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;
}
Expand Down
19 changes: 2 additions & 17 deletions sound/soc/omap/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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"
Expand Down Expand Up @@ -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.
4 changes: 0 additions & 4 deletions sound/soc/omap/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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

0 comments on commit efad6ee

Please sign in to comment.