diff options
Diffstat (limited to 'sound/soc/pxa/palm27x.c')
| -rw-r--r-- | sound/soc/pxa/palm27x.c | 204 | 
1 files changed, 73 insertions, 131 deletions
diff --git a/sound/soc/pxa/palm27x.c b/sound/soc/pxa/palm27x.c index e6102fda0a7..1f96e3227be 100644 --- a/sound/soc/pxa/palm27x.c +++ b/sound/soc/pxa/palm27x.c @@ -17,13 +17,12 @@  #include <linux/moduleparam.h>  #include <linux/device.h>  #include <linux/gpio.h> -#include <linux/interrupt.h> -#include <linux/irq.h>  #include <sound/core.h>  #include <sound/pcm.h>  #include <sound/soc.h>  #include <sound/soc-dapm.h> +#include <sound/jack.h>  #include <asm/mach-types.h>  #include <mach/audio.h> @@ -33,90 +32,31 @@  #include "pxa2xx-pcm.h"  #include "pxa2xx-ac97.h" -static int palm27x_jack_func = 1; -static int palm27x_spk_func = 1; -static int palm27x_ep_gpio = -1; +static struct snd_soc_jack hs_jack; -static void palm27x_ext_control(struct snd_soc_codec *codec) -{ -	if (!palm27x_spk_func) -		snd_soc_dapm_enable_pin(codec, "Speaker"); -	else -		snd_soc_dapm_disable_pin(codec, "Speaker"); - -	if (!palm27x_jack_func) -		snd_soc_dapm_enable_pin(codec, "Headphone Jack"); -	else -		snd_soc_dapm_disable_pin(codec, "Headphone Jack"); - -	snd_soc_dapm_sync(codec); -} - -static int palm27x_startup(struct snd_pcm_substream *substream) -{ -	struct snd_soc_pcm_runtime *rtd = substream->private_data; -	struct snd_soc_codec *codec = rtd->socdev->card->codec; - -	/* check the jack status at stream startup */ -	palm27x_ext_control(codec); -	return 0; -} - -static struct snd_soc_ops palm27x_ops = { -	.startup = palm27x_startup, +/* Headphones jack detection DAPM pins */ +static struct snd_soc_jack_pin hs_jack_pins[] = { +	{ +		.pin    = "Headphone Jack", +		.mask   = SND_JACK_HEADPHONE, +	},  }; -static irqreturn_t palm27x_interrupt(int irq, void *v) -{ -	palm27x_spk_func = gpio_get_value(palm27x_ep_gpio); -	palm27x_jack_func = !palm27x_spk_func; -	return IRQ_HANDLED; -} - -static int palm27x_get_jack(struct snd_kcontrol *kcontrol, -	struct snd_ctl_elem_value *ucontrol) -{ -	ucontrol->value.integer.value[0] = palm27x_jack_func; -	return 0; -} - -static int palm27x_set_jack(struct snd_kcontrol *kcontrol, -	struct snd_ctl_elem_value *ucontrol) -{ -	struct snd_soc_codec *codec =  snd_kcontrol_chip(kcontrol); - -	if (palm27x_jack_func == ucontrol->value.integer.value[0]) -		return 0; - -	palm27x_jack_func = ucontrol->value.integer.value[0]; -	palm27x_ext_control(codec); -	return 1; -} - -static int palm27x_get_spk(struct snd_kcontrol *kcontrol, -	struct snd_ctl_elem_value *ucontrol) -{ -	ucontrol->value.integer.value[0] = palm27x_spk_func; -	return 0; -} - -static int palm27x_set_spk(struct snd_kcontrol *kcontrol, -	struct snd_ctl_elem_value *ucontrol) -{ -	struct snd_soc_codec *codec =  snd_kcontrol_chip(kcontrol); - -	if (palm27x_spk_func == ucontrol->value.integer.value[0]) -		return 0; - -	palm27x_spk_func = ucontrol->value.integer.value[0]; -	palm27x_ext_control(codec); -	return 1; -} +/* Headphones jack detection gpios */ +static struct snd_soc_jack_gpio hs_jack_gpios[] = { +	[0] = { +		/* gpio is set on per-platform basis */ +		.name           = "hp-gpio", +		.report         = SND_JACK_HEADPHONE, +		.debounce_time	= 200, +	}, +}; -/* PalmTX machine dapm widgets */ +/* Palm27x machine dapm widgets */  static const struct snd_soc_dapm_widget palm27x_dapm_widgets[] = {  	SND_SOC_DAPM_HP("Headphone Jack", NULL), -	SND_SOC_DAPM_SPK("Speaker", NULL), +	SND_SOC_DAPM_SPK("Ext. Speaker", NULL), +	SND_SOC_DAPM_MIC("Ext. Microphone", NULL),  };  /* PalmTX audio map */ @@ -126,46 +66,66 @@ static const struct snd_soc_dapm_route audio_map[] = {  	{"Headphone Jack", NULL, "HPOUTR"},  	/* ext speaker connected to ROUT2, LOUT2 */ -	{"Speaker", NULL, "LOUT2"}, -	{"Speaker", NULL, "ROUT2"}, -}; +	{"Ext. Speaker", NULL, "LOUT2"}, +	{"Ext. Speaker", NULL, "ROUT2"}, -static const char *jack_function[] = {"Headphone", "Off"}; -static const char *spk_function[] = {"On", "Off"}; -static const struct soc_enum palm27x_enum[] = { -	SOC_ENUM_SINGLE_EXT(2, jack_function), -	SOC_ENUM_SINGLE_EXT(2, spk_function), +	/* mic connected to MIC1 */ +	{"Ext. Microphone", NULL, "MIC1"},  }; -static const struct snd_kcontrol_new palm27x_controls[] = { -	SOC_ENUM_EXT("Jack Function", palm27x_enum[0], palm27x_get_jack, -		palm27x_set_jack), -	SOC_ENUM_EXT("Speaker Function", palm27x_enum[1], palm27x_get_spk, -		palm27x_set_spk), -}; +static struct snd_soc_card palm27x_asoc;  static int palm27x_ac97_init(struct snd_soc_codec *codec)  {  	int err; +	/* add palm27x specific widgets */ +	err = snd_soc_dapm_new_controls(codec, palm27x_dapm_widgets, +				ARRAY_SIZE(palm27x_dapm_widgets)); +	if (err) +		return err; + +	/* set up palm27x specific audio path audio_map */ +	err = snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); +	if (err) +		return err; + +	/* connected pins */ +	if (machine_is_palmld()) +		snd_soc_dapm_enable_pin(codec, "MIC1"); +	snd_soc_dapm_enable_pin(codec, "HPOUTL"); +	snd_soc_dapm_enable_pin(codec, "HPOUTR"); +	snd_soc_dapm_enable_pin(codec, "LOUT2"); +	snd_soc_dapm_enable_pin(codec, "ROUT2"); + +	/* not connected pins */  	snd_soc_dapm_nc_pin(codec, "OUT3");  	snd_soc_dapm_nc_pin(codec, "MONOOUT"); +	snd_soc_dapm_nc_pin(codec, "LINEINL"); +	snd_soc_dapm_nc_pin(codec, "LINEINR"); +	snd_soc_dapm_nc_pin(codec, "PCBEEP"); +	snd_soc_dapm_nc_pin(codec, "PHONE"); +	snd_soc_dapm_nc_pin(codec, "MIC2"); -	/* add palm27x specific controls */ -	err = snd_soc_add_controls(codec, palm27x_controls, -				ARRAY_SIZE(palm27x_controls)); -	if (err < 0) +	err = snd_soc_dapm_sync(codec); +	if (err)  		return err; -	/* add palm27x specific widgets */ -	snd_soc_dapm_new_controls(codec, palm27x_dapm_widgets, -				ARRAY_SIZE(palm27x_dapm_widgets)); +	/* Jack detection API stuff */ +	err = snd_soc_jack_new(&palm27x_asoc, "Headphone Jack", +				SND_JACK_HEADPHONE, &hs_jack); +	if (err) +		return err; -	/* set up palm27x specific audio path audio_map */ -	snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); +	err = snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins), +				hs_jack_pins); +	if (err) +		return err; -	snd_soc_dapm_sync(codec); -	return 0; +	err = snd_soc_jack_add_gpios(&hs_jack, ARRAY_SIZE(hs_jack_gpios), +				hs_jack_gpios); + +	return err;  }  static struct snd_soc_dai_link palm27x_dai[] = { @@ -175,14 +135,12 @@ static struct snd_soc_dai_link palm27x_dai[] = {  	.cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI],  	.codec_dai = &wm9712_dai[WM9712_DAI_AC97_HIFI],  	.init = palm27x_ac97_init, -	.ops = &palm27x_ops,  },  {  	.name = "AC97 Aux",  	.stream_name = "AC97 Aux",  	.cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX],  	.codec_dai = &wm9712_dai[WM9712_DAI_AC97_AUX], -	.ops = &palm27x_ops,  },  }; @@ -208,27 +166,17 @@ static int palm27x_asoc_probe(struct platform_device *pdev)  		machine_is_palmld() || machine_is_palmte2()))  		return -ENODEV; -	if (pdev->dev.platform_data) -		palm27x_ep_gpio = ((struct palm27x_asoc_info *) -			(pdev->dev.platform_data))->jack_gpio; - -	ret = gpio_request(palm27x_ep_gpio, "Headphone Jack"); -	if (ret) -		return ret; -	ret = gpio_direction_input(palm27x_ep_gpio); -	if (ret) -		goto err_alloc; +	if (!pdev->dev.platform_data) { +		dev_err(&pdev->dev, "please supply platform_data\n"); +		return -ENODEV; +	} -	if (request_irq(gpio_to_irq(palm27x_ep_gpio), palm27x_interrupt, -			IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, -			"Headphone jack", NULL)) -		goto err_alloc; +	hs_jack_gpios[0].gpio = ((struct palm27x_asoc_info *) +			(pdev->dev.platform_data))->jack_gpio;  	palm27x_snd_device = platform_device_alloc("soc-audio", -1); -	if (!palm27x_snd_device) { -		ret = -ENOMEM; -		goto err_dev; -	} +	if (!palm27x_snd_device) +		return -ENOMEM;  	platform_set_drvdata(palm27x_snd_device, &palm27x_snd_devdata);  	palm27x_snd_devdata.dev = &palm27x_snd_device->dev; @@ -241,18 +189,12 @@ static int palm27x_asoc_probe(struct platform_device *pdev)  put_device:  	platform_device_put(palm27x_snd_device); -err_dev: -	free_irq(gpio_to_irq(palm27x_ep_gpio), NULL); -err_alloc: -	gpio_free(palm27x_ep_gpio);  	return ret;  }  static int __devexit palm27x_asoc_remove(struct platform_device *pdev)  { -	free_irq(gpio_to_irq(palm27x_ep_gpio), NULL); -	gpio_free(palm27x_ep_gpio);  	platform_device_unregister(palm27x_snd_device);  	return 0;  }  |