[alsa-devel] [PATCHv2 0/9] DT support for N900 soundcard (rx51-audio)
Hi,
This patchset adds DT support in rx51-audio. I tested it on my Nokia N900 and was able to play a wav file using aplay. I have not tested the whole functionality, but output via speakers, headphones and the related enable controls seem to work.
Changes since PATCHv1 [0]: * drop "ASoC: tlv320aic3x: fix shared reset pin for DT" (already applied) * drop "ASoC: RX-51: Convert to table based DAPM setup" (similar patch was applied to -next) * remove useless "card->dev = NULL;" from first patch * split patches from into smaller chunks * introduce new patch, which fixes a checkpatch warning * use gpiod API, which reduces the DT specific bits of the driver * rebase to newer -next checkout
[0] https://lkml.org/lkml/2014/4/5/92
-- Sebastian
Sebastian Reichel (9): ASoC: omap: rx51: Use static const char * const arrays ASoC: omap: rx51: Add module alias ASoC: omap: rx51: Use devm_snd_soc_register_card ASoC: Allow Aux Codecs to be specified using DT ASoC: omap: rx51: omap_mcbsp_st_add_controls: add id parameter ASoC: omap: rx51: get GPIO numbers via gpiod API ASoC: omap: rx51: Add some error messages ASoC: omap: rx51: Add DT support DTS: OMAP3-N900: Add sound support
.../devicetree/bindings/sound/nokia,rx51.txt | 27 +++ arch/arm/boot/dts/omap3-n900.dts | 17 ++ include/sound/soc.h | 13 +- sound/soc/omap/omap-mcbsp.c | 5 +- sound/soc/omap/omap-mcbsp.h | 2 +- sound/soc/omap/rx51.c | 226 +++++++++++++++------ sound/soc/soc-core.c | 68 ++++--- 7 files changed, 271 insertions(+), 87 deletions(-) create mode 100644 Documentation/devicetree/bindings/sound/nokia,rx51.txt
Mark the array and the string const by using "static const char * const foo[]" instead of "static const char* foo[]".
Signed-off-by: Sebastian Reichel sre@kernel.org --- sound/soc/omap/rx51.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c index add0047..1a3f05c 100644 --- a/sound/soc/omap/rx51.c +++ b/sound/soc/omap/rx51.c @@ -258,9 +258,11 @@ static const struct snd_soc_dapm_route audio_map[] = { {"b Mic Bias", NULL, "HS Mic"} };
-static const char *spk_function[] = {"Off", "On"}; -static const char *input_function[] = {"ADC", "Digital Mic"}; -static const char *jack_function[] = {"Off", "TV-OUT", "Headphone", "Headset"}; +static const char * const spk_function[] = {"Off", "On"}; +static const char * const input_function[] = {"ADC", "Digital Mic"}; +static const char * const jack_function[] = { + "Off", "TV-OUT", "Headphone", "Headset" +};
static const struct soc_enum rx51_enum[] = { SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spk_function), spk_function),
On Mon, Apr 28, 2014 at 04:07:19PM +0200, Sebastian Reichel wrote:
Mark the array and the string const by using "static const char * const foo[]" instead of "static const char* foo[]".
Applied, thanks.
Add module alias to support driver autoloading.
Signed-off-by: Pali Rohár pali.rohar@gmail.com Signed-off-by: Sebastian Reichel sre@kernel.org --- sound/soc/omap/rx51.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c index 1a3f05c..55713d0 100644 --- a/sound/soc/omap/rx51.c +++ b/sound/soc/omap/rx51.c @@ -421,3 +421,4 @@ module_exit(rx51_soc_exit); MODULE_AUTHOR("Nokia Corporation"); MODULE_DESCRIPTION("ALSA SoC Nokia RX-51"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:rx51-audio");
This patch converts the rx51 ASoC module to use devm_snd_soc_register_card.
Signed-off-by: Pali Rohár pali.rohar@gmail.com Signed-off-by: Sebastian Reichel sre@kernel.org --- sound/soc/omap/rx51.c | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-)
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c index 55713d0..bbe3a66 100644 --- a/sound/soc/omap/rx51.c +++ b/sound/soc/omap/rx51.c @@ -363,10 +363,9 @@ static struct snd_soc_card rx51_sound_card = { .num_dapm_routes = ARRAY_SIZE(audio_map), };
-static struct platform_device *rx51_snd_device; - -static int __init rx51_soc_init(void) +static int rx51_soc_probe(struct platform_device *pdev) { + struct snd_soc_card *card = &rx51_sound_card; int err;
if (!machine_is_nokia_rx51() && !of_machine_is_compatible("nokia,omap3-n900")) @@ -381,22 +380,16 @@ static int __init rx51_soc_init(void) if (err) goto err_gpio_eci_sw;
- rx51_snd_device = platform_device_alloc("soc-audio", -1); - if (!rx51_snd_device) { - err = -ENOMEM; - goto err1; - } - - platform_set_drvdata(rx51_snd_device, &rx51_sound_card); + card->dev = &pdev->dev;
- err = platform_device_add(rx51_snd_device); - if (err) - goto err2; + err = devm_snd_soc_register_card(card->dev, card); + if (err) { + dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", err); + goto err_snd; + }
return 0; -err2: - platform_device_put(rx51_snd_device); -err1: +err_snd: gpio_free(RX51_ECI_SW_GPIO); err_gpio_eci_sw: gpio_free(RX51_TVOUT_SEL_GPIO); @@ -405,18 +398,27 @@ err_gpio_tvout_sel: return err; }
-static void __exit rx51_soc_exit(void) +static int rx51_soc_remove(struct platform_device *pdev) { snd_soc_jack_free_gpios(&rx51_av_jack, ARRAY_SIZE(rx51_av_jack_gpios), rx51_av_jack_gpios);
- platform_device_unregister(rx51_snd_device); gpio_free(RX51_ECI_SW_GPIO); gpio_free(RX51_TVOUT_SEL_GPIO); + + return 0; }
-module_init(rx51_soc_init); -module_exit(rx51_soc_exit); +static struct platform_driver rx51_soc_driver = { + .driver = { + .name = "rx51-audio", + .owner = THIS_MODULE, + }, + .probe = rx51_soc_probe, + .remove = rx51_soc_remove, +}; + +module_platform_driver(rx51_soc_driver);
MODULE_AUTHOR("Nokia Corporation"); MODULE_DESCRIPTION("ALSA SoC Nokia RX-51");
This patch adds support for specifying auxiliary codecs and codec configuration via device tree phandles.
This change adds new fields to snd_soc_aux_dev and snd_soc_codec_conf and adds support for the changes to SoC core methods.
Signed-off-by: Pavel Machek pavel@ucw.cz Signed-off-by: Sebastian Reichel sre@kernel.org --- include/sound/soc.h | 13 +++++++++- sound/soc/soc-core.c | 68 ++++++++++++++++++++++++++++++++-------------------- 2 files changed, 54 insertions(+), 27 deletions(-)
diff --git a/include/sound/soc.h b/include/sound/soc.h index 0fadb3c..22dfaef 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -923,7 +923,12 @@ struct snd_soc_dai_link { };
struct snd_soc_codec_conf { + /* + * specify device either by device name, or by + * DT/OF node, but not both. + */ const char *dev_name; + const struct device_node *of_node;
/* * optional map of kcontrol, widget and path name prefixes that are @@ -934,7 +939,13 @@ struct snd_soc_codec_conf {
struct snd_soc_aux_dev { const char *name; /* Codec name */ - const char *codec_name; /* for multi-codec */ + + /* + * specify multi-codec either by device name, or by + * DT/OF node, but not both. + */ + const char *codec_name; + const struct device_node *codec_of_node;
/* codec/machine specific init - e.g. add machine controls */ int (*init)(struct snd_soc_dapm_context *dapm); diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index f18112a..39f6c04 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1119,10 +1119,12 @@ static void soc_set_name_prefix(struct snd_soc_card *card,
for (i = 0; i < card->num_configs; i++) { struct snd_soc_codec_conf *map = &card->codec_conf[i]; - if (map->dev_name && !strcmp(codec->name, map->dev_name)) { - codec->name_prefix = map->name_prefix; - break; - } + if (map->of_node && codec->dev->of_node != map->of_node) + continue; + if (map->dev_name && strcmp(codec->name, map->dev_name)) + continue; + codec->name_prefix = map->name_prefix; + break; } }
@@ -1652,52 +1654,66 @@ static void soc_unregister_ac97_dai_link(struct snd_soc_pcm_runtime *rtd) } #endif
-static int soc_check_aux_dev(struct snd_soc_card *card, int num) +struct snd_soc_codec *soc_find_matching_codec(struct snd_soc_card *card, int num) { struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num]; struct snd_soc_codec *codec;
- /* find CODEC from registered CODECs*/ + /* find CODEC from registered CODECs */ list_for_each_entry(codec, &codec_list, list) { - if (!strcmp(codec->name, aux_dev->codec_name)) - return 0; + if (aux_dev->codec_of_node && + (codec->dev->of_node != aux_dev->codec_of_node)) + continue; + if (aux_dev->codec_name && strcmp(codec->name, aux_dev->codec_name)) + continue; + return codec; }
- dev_err(card->dev, "ASoC: %s not registered\n", aux_dev->codec_name); + return NULL; +} + +static int soc_check_aux_dev(struct snd_soc_card *card, int num) +{ + struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num]; + const char *codecname = aux_dev->codec_name; + struct snd_soc_codec *codec = soc_find_matching_codec(card, num);
+ if (codec) + return 0; + if (aux_dev->codec_of_node) + codecname = of_node_full_name(aux_dev->codec_of_node); + + dev_err(card->dev, "ASoC: %s not registered\n", codecname); return -EPROBE_DEFER; }
static int soc_probe_aux_dev(struct snd_soc_card *card, int num) { struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num]; - struct snd_soc_codec *codec; + const char *codecname = aux_dev->codec_name; int ret = -ENODEV; + struct snd_soc_codec *codec = soc_find_matching_codec(card, num);
- /* find CODEC from registered CODECs*/ - list_for_each_entry(codec, &codec_list, list) { - if (!strcmp(codec->name, aux_dev->codec_name)) { - if (codec->probed) { - dev_err(codec->dev, - "ASoC: codec already probed"); - ret = -EBUSY; - goto out; - } - goto found; - } + if (!codec) { + if (aux_dev->codec_of_node) + codecname = of_node_full_name(aux_dev->codec_of_node); + + /* codec not found */ + dev_err(card->dev, "ASoC: codec %s not found", codecname); + return -EPROBE_DEFER; + } + + if (codec->probed) { + dev_err(codec->dev, "ASoC: codec already probed"); + return -EBUSY; } - /* codec not found */ - dev_err(card->dev, "ASoC: codec %s not found", aux_dev->codec_name); - return -EPROBE_DEFER;
-found: ret = soc_probe_codec(card, codec); if (ret < 0) return ret;
ret = soc_post_component_init(card, codec, num, 1);
-out: return ret; }
On Mon, Apr 28, 2014 at 04:07:22PM +0200, Sebastian Reichel wrote:
This patch adds support for specifying auxiliary codecs and codec configuration via device tree phandles.
Applied, thanks.
This is a preparation for DT based booting where the McBSP id is set to -1 for all McBSP instances.
Signed-off-by: Sebastian Reichel sre@kernel.org --- sound/soc/omap/omap-mcbsp.c | 5 +++-- sound/soc/omap/omap-mcbsp.h | 2 +- sound/soc/omap/rx51.c | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c index af2764a..71d2266 100644 --- a/sound/soc/omap/omap-mcbsp.c +++ b/sound/soc/omap/omap-mcbsp.c @@ -693,7 +693,7 @@ OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP" #port " Sidetone Channel 1 Volume", \ OMAP_MCBSP_ST_CONTROLS(2); OMAP_MCBSP_ST_CONTROLS(3);
-int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd) +int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd, int port_id) { struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); @@ -703,7 +703,7 @@ int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd) return 0; }
- switch (mcbsp->id) { + switch (port_id) { case 2: /* McBSP 2 */ return snd_soc_add_dai_controls(cpu_dai, omap_mcbsp2_st_controls, @@ -713,6 +713,7 @@ int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd) omap_mcbsp3_st_controls, ARRAY_SIZE(omap_mcbsp3_st_controls)); default: + dev_err(mcbsp->dev, "Port %d not supported\n", port_id); break; }
diff --git a/sound/soc/omap/omap-mcbsp.h b/sound/soc/omap/omap-mcbsp.h index ba8386a..2e3369c 100644 --- a/sound/soc/omap/omap-mcbsp.h +++ b/sound/soc/omap/omap-mcbsp.h @@ -39,6 +39,6 @@ enum omap_mcbsp_div { OMAP_MCBSP_CLKGDV, /* Sample rate generator divider */ };
-int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd); +int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd, int port_id);
#endif diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c index bbe3a66..e140b1b 100644 --- a/sound/soc/omap/rx51.c +++ b/sound/soc/omap/rx51.c @@ -297,7 +297,7 @@ static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd) return err; snd_soc_limit_volume(codec, "TPA6130A2 Headphone Playback Volume", 42);
- err = omap_mcbsp_st_add_controls(rtd); + err = omap_mcbsp_st_add_controls(rtd, 2); if (err < 0) return err;
On Mon, Apr 28, 2014 at 04:07:23PM +0200, Sebastian Reichel wrote:
This is a preparation for DT based booting where the McBSP id is set to -1 for all McBSP instances.
Applied, thanks.
On Mon 2014-04-28 16:07:23, Sebastian Reichel wrote:
This is a preparation for DT based booting where the McBSP id is set to -1 for all McBSP instances.
Signed-off-by: Sebastian Reichel sre@kernel.org
Acked-by: Pavel Machek pavel@ucw.cz
Update the driver to get GPIO numbers from the devm gpiod API instead of requesting hardcoded GPIO numbers.
Signed-off-by: Sebastian Reichel sre@kernel.org --- sound/soc/omap/rx51.c | 114 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 79 insertions(+), 35 deletions(-)
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c index e140b1b..30cfac0 100644 --- a/sound/soc/omap/rx51.c +++ b/sound/soc/omap/rx51.c @@ -26,6 +26,7 @@ #include <linux/delay.h> #include <linux/gpio.h> #include <linux/platform_device.h> +#include <linux/gpio/consumer.h> #include <linux/module.h> #include <sound/core.h> #include <sound/jack.h> @@ -38,15 +39,6 @@
#include "omap-mcbsp.h"
-#define RX51_TVOUT_SEL_GPIO 40 -#define RX51_JACK_DETECT_GPIO 177 -#define RX51_ECI_SW_GPIO 182 -/* - * REVISIT: TWL4030 GPIO base in RX-51. Now statically defined to 192. This - * gpio is reserved in arch/arm/mach-omap2/board-rx51-peripherals.c - */ -#define RX51_SPEAKER_AMP_TWL_GPIO (192 + 7) - enum { RX51_JACK_DISABLED, RX51_JACK_TVOUT, /* tv-out with stereo output */ @@ -54,12 +46,21 @@ enum { RX51_JACK_HS, /* headset: stereo output with mic */ };
+struct rx51_audio_pdata { + struct gpio_desc *tvout_selection_gpio; + struct gpio_desc *jack_detection_gpio; + struct gpio_desc *eci_sw_gpio; + struct gpio_desc *speaker_amp_gpio; +}; + static int rx51_spk_func; static int rx51_dmic_func; static int rx51_jack_func;
static void rx51_ext_control(struct snd_soc_dapm_context *dapm) { + struct snd_soc_card *card = dapm->card; + struct rx51_audio_pdata *pdata = snd_soc_card_get_drvdata(card); int hp = 0, hs = 0, tvout = 0;
switch (rx51_jack_func) { @@ -93,7 +94,7 @@ static void rx51_ext_control(struct snd_soc_dapm_context *dapm) else snd_soc_dapm_disable_pin_unlocked(dapm, "HS Mic");
- gpio_set_value(RX51_TVOUT_SEL_GPIO, tvout); + gpiod_set_value(pdata->tvout_selection_gpio, tvout);
snd_soc_dapm_sync_unlocked(dapm);
@@ -154,10 +155,12 @@ static int rx51_set_spk(struct snd_kcontrol *kcontrol, static int rx51_spk_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event) { - if (SND_SOC_DAPM_EVENT_ON(event)) - gpio_set_value_cansleep(RX51_SPEAKER_AMP_TWL_GPIO, 1); - else - gpio_set_value_cansleep(RX51_SPEAKER_AMP_TWL_GPIO, 0); + struct snd_soc_dapm_context *dapm = w->dapm; + struct snd_soc_card *card = dapm->card; + struct rx51_audio_pdata *pdata = snd_soc_card_get_drvdata(card); + + gpiod_set_raw_value_cansleep(pdata->speaker_amp_gpio, + !!SND_SOC_DAPM_EVENT_ON(event));
return 0; } @@ -223,7 +226,6 @@ static struct snd_soc_jack rx51_av_jack;
static struct snd_soc_jack_gpio rx51_av_jack_gpios[] = { { - .gpio = RX51_JACK_DETECT_GPIO, .name = "avdet-gpio", .report = SND_JACK_HEADSET, .invert = 1, @@ -284,6 +286,9 @@ static const struct snd_kcontrol_new aic34_rx51_controls[] = { static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_card *card = codec->card; + struct rx51_audio_pdata *pdata = snd_soc_card_get_drvdata(card); + struct snd_soc_dapm_context *dapm = &codec->dapm; int err;
@@ -307,6 +312,11 @@ static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd) &rx51_av_jack); if (err) return err; + + /* prepare gpio for snd_soc_jack_add_gpios */ + rx51_av_jack_gpios[0].gpio = desc_to_gpio(pdata->jack_detection_gpio); + devm_gpiod_put(card->dev, pdata->jack_detection_gpio); + err = snd_soc_jack_add_gpios(&rx51_av_jack, ARRAY_SIZE(rx51_av_jack_gpios), rx51_av_jack_gpios); @@ -365,37 +375,74 @@ static struct snd_soc_card rx51_sound_card = {
static int rx51_soc_probe(struct platform_device *pdev) { + struct rx51_audio_pdata *pdata; struct snd_soc_card *card = &rx51_sound_card; int err;
if (!machine_is_nokia_rx51() && !of_machine_is_compatible("nokia,omap3-n900")) return -ENODEV;
- err = gpio_request_one(RX51_TVOUT_SEL_GPIO, - GPIOF_DIR_OUT | GPIOF_INIT_LOW, "tvout_sel"); - if (err) - goto err_gpio_tvout_sel; - err = gpio_request_one(RX51_ECI_SW_GPIO, - GPIOF_DIR_OUT | GPIOF_INIT_HIGH, "eci_sw"); - if (err) - goto err_gpio_eci_sw; - card->dev = &pdev->dev;
+ pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); + if (pdata == NULL) { + dev_err(card->dev, "failed to create private data\n"); + return -ENOMEM; + } + snd_soc_card_set_drvdata(card, pdata); + + pdata->tvout_selection_gpio = devm_gpiod_get(card->dev, + "tvout-selection"); + if (IS_ERR(pdata->tvout_selection_gpio)) { + dev_err(card->dev, "could not get tvout selection gpio\n"); + return PTR_ERR(pdata->tvout_selection_gpio); + } + + err = gpiod_direction_output(pdata->tvout_selection_gpio, 0); + if (err) { + dev_err(card->dev, "could not setup tvout selection gpio\n"); + return err; + } + + pdata->jack_detection_gpio = devm_gpiod_get(card->dev, + "jack-detection"); + if (IS_ERR(pdata->jack_detection_gpio)) { + dev_err(card->dev, "could not get jack detection gpio\n"); + return PTR_ERR(pdata->jack_detection_gpio); + } + + pdata->eci_sw_gpio = devm_gpiod_get(card->dev, "eci-switch"); + if (IS_ERR(pdata->eci_sw_gpio)) { + dev_err(card->dev, "could not get eci switch gpio\n"); + return PTR_ERR(pdata->eci_sw_gpio); + } + + err = gpiod_direction_output(pdata->eci_sw_gpio, 1); + if (err) { + dev_err(card->dev, "could not setup eci switch gpio\n"); + return err; + } + + pdata->speaker_amp_gpio = devm_gpiod_get(card->dev, + "speaker-amplifier"); + if (IS_ERR(pdata->speaker_amp_gpio)) { + dev_err(card->dev, "could not get speaker enable gpio\n"); + return PTR_ERR(pdata->speaker_amp_gpio); + } + + err = gpiod_direction_output(pdata->speaker_amp_gpio, 0); + if (err) { + dev_err(card->dev, "could not setup speaker enable gpio\n"); + return err; + } + err = devm_snd_soc_register_card(card->dev, card); if (err) { dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", err); - goto err_snd; + return err; }
return 0; -err_snd: - gpio_free(RX51_ECI_SW_GPIO); -err_gpio_eci_sw: - gpio_free(RX51_TVOUT_SEL_GPIO); -err_gpio_tvout_sel: - - return err; }
static int rx51_soc_remove(struct platform_device *pdev) @@ -403,9 +450,6 @@ static int rx51_soc_remove(struct platform_device *pdev) snd_soc_jack_free_gpios(&rx51_av_jack, ARRAY_SIZE(rx51_av_jack_gpios), rx51_av_jack_gpios);
- gpio_free(RX51_ECI_SW_GPIO); - gpio_free(RX51_TVOUT_SEL_GPIO); - return 0; }
On Mon, Apr 28, 2014 at 04:07:24PM +0200, Sebastian Reichel wrote:
Update the driver to get GPIO numbers from the devm gpiod API instead of requesting hardcoded GPIO numbers.
Applied, thanks.
On Mon 2014-04-28 16:07:24, Sebastian Reichel wrote:
Update the driver to get GPIO numbers from the devm gpiod API instead of requesting hardcoded GPIO numbers.
Signed-off-by: Sebastian Reichel sre@kernel.org
Acked-by: Pavel Machek pavel@ucw.cz
Add more error messages making it easier to identify problems.
Signed-off-by: Sebastian Reichel sre@kernel.org --- sound/soc/omap/rx51.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c index 30cfac0..110deca 100644 --- a/sound/soc/omap/rx51.c +++ b/sound/soc/omap/rx51.c @@ -298,20 +298,26 @@ static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd) snd_soc_dapm_nc_pin(dapm, "LINE1R");
err = tpa6130a2_add_controls(codec); - if (err < 0) + if (err < 0) { + dev_err(card->dev, "Failed to add TPA6130A2 controls\n"); return err; + } snd_soc_limit_volume(codec, "TPA6130A2 Headphone Playback Volume", 42);
err = omap_mcbsp_st_add_controls(rtd, 2); - if (err < 0) + if (err < 0) { + dev_err(card->dev, "Failed to add MCBSP controls\n"); return err; + }
/* AV jack detection */ err = snd_soc_jack_new(codec, "AV Jack", SND_JACK_HEADSET | SND_JACK_VIDEOOUT, &rx51_av_jack); - if (err) + if (err) { + dev_err(card->dev, "Failed to add AV Jack\n"); return err; + }
/* prepare gpio for snd_soc_jack_add_gpios */ rx51_av_jack_gpios[0].gpio = desc_to_gpio(pdata->jack_detection_gpio); @@ -320,6 +326,10 @@ static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd) err = snd_soc_jack_add_gpios(&rx51_av_jack, ARRAY_SIZE(rx51_av_jack_gpios), rx51_av_jack_gpios); + if (err) { + dev_err(card->dev, "Failed to add GPIOs\n"); + return err; + }
return err; }
Hi!
Add more error messages making it easier to identify problems.
Signed-off-by: Sebastian Reichel sre@kernel.org
sound/soc/omap/rx51.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-)
if (err) {
dev_err(card->dev, "Failed to add GPIOs\n");
return err;
}
return err;
}
As you'll return err, anyway, you don't need to do it inside the if()... OTOH it does not hurt.
Acked-by: Pavel Machek pavel@ucw.cz
This patch adds device tree support to the Nokia N900 audio driver and adds documentation for the DT binding.
Signed-off-by: Sebastian Reichel sre@kernel.org --- .../devicetree/bindings/sound/nokia,rx51.txt | 27 +++++++++++ sound/soc/omap/rx51.c | 53 ++++++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/nokia,rx51.txt
diff --git a/Documentation/devicetree/bindings/sound/nokia,rx51.txt b/Documentation/devicetree/bindings/sound/nokia,rx51.txt new file mode 100644 index 0000000..72f93d9 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/nokia,rx51.txt @@ -0,0 +1,27 @@ +* Nokia N900 audio setup + +Required properties: +- compatible: Should contain "nokia,n900-audio" +- nokia,cpu-dai: phandle for the McBSP node +- nokia,audio-codec: phandles for the main TLV320AIC3X node and the + auxiliary TLV320AIC3X node (in this order) +- nokia,headphone-amplifier: phandle for the TPA6130A2 node +- tvout-selection-gpios: GPIO for tvout selection +- jack-detection-gpios: GPIO for jack detection +- eci-switch-gpios: GPIO for ECI (Enhancement Control Interface) switch +- speaker-amplifier-gpios: GPIO for speaker amplifier + +Example: + +sound { + compatible = "nokia,n900-audio"; + + nokia,cpu-dai = <&mcbsp2>; + nokia,audio-codec = <&tlv320aic3x>, <&tlv320aic3x_aux>; + nokia,headphone-amplifier = <&tpa6130a2>; + + tvout-selection-gpios = <&gpio2 8 GPIO_ACTIVE_HIGH>; /* 40 */ + jack-detection-gpios = <&gpio6 17 GPIO_ACTIVE_HIGH>; /* 177 */ + eci-switch-gpios = <&gpio6 22 GPIO_ACTIVE_HIGH>; /* 182 */ + speaker-amplifier-gpios = <&twl_gpio 7 GPIO_ACTIVE_HIGH>; +}; diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c index 110deca..866578b 100644 --- a/sound/soc/omap/rx51.c +++ b/sound/soc/omap/rx51.c @@ -386,6 +386,7 @@ static struct snd_soc_card rx51_sound_card = { static int rx51_soc_probe(struct platform_device *pdev) { struct rx51_audio_pdata *pdata; + struct device_node *np = pdev->dev.of_node; struct snd_soc_card *card = &rx51_sound_card; int err;
@@ -394,6 +395,49 @@ static int rx51_soc_probe(struct platform_device *pdev)
card->dev = &pdev->dev;
+ if (np) { + struct device_node *dai_node; + + dai_node = of_parse_phandle(np, "nokia,cpu-dai", 0); + if (!dai_node) { + dev_err(&pdev->dev, "McBSP node is not provided\n"); + return -EINVAL; + } + rx51_dai[0].cpu_dai_name = NULL; + rx51_dai[0].platform_name = NULL; + rx51_dai[0].cpu_of_node = dai_node; + rx51_dai[0].platform_of_node = dai_node; + + dai_node = of_parse_phandle(np, "nokia,audio-codec", 0); + if (!dai_node) { + dev_err(&pdev->dev, "Codec node is not provided\n"); + return -EINVAL; + } + rx51_dai[0].codec_name = NULL; + rx51_dai[0].codec_of_node = dai_node; + + dai_node = of_parse_phandle(np, "nokia,audio-codec", 1); + if (!dai_node) { + dev_err(&pdev->dev, "Auxiliary Codec node is not provided\n"); + return -EINVAL; + } + rx51_aux_dev[0].codec_name = NULL; + rx51_aux_dev[0].codec_of_node = dai_node; + rx51_codec_conf[0].dev_name = NULL; + rx51_codec_conf[0].of_node = dai_node; + + dai_node = of_parse_phandle(np, "nokia,headphone-amplifier", 0); + if (!dai_node) { + dev_err(&pdev->dev, "Headphone amplifier node is not provided\n"); + return -EINVAL; + } + + /* TODO: tpa6130a2a driver supports only a single instance, so + * this driver ignores the headphone-amplifier node for now. + * It's already mandatory in the DT binding to be future proof. + */ + } + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); if (pdata == NULL) { dev_err(card->dev, "failed to create private data\n"); @@ -463,10 +507,19 @@ static int rx51_soc_remove(struct platform_device *pdev) return 0; }
+#if defined(CONFIG_OF) +static const struct of_device_id rx51_audio_of_match[] = { + { .compatible = "nokia,n900-audio", }, + {}, +}; +MODULE_DEVICE_TABLE(of, rx51_audio_of_match); +#endif + static struct platform_driver rx51_soc_driver = { .driver = { .name = "rx51-audio", .owner = THIS_MODULE, + .of_match_table = of_match_ptr(rx51_audio_of_match), }, .probe = rx51_soc_probe, .remove = rx51_soc_remove,
On Mon 2014-04-28 16:07:26, Sebastian Reichel wrote:
This patch adds device tree support to the Nokia N900 audio driver and adds documentation for the DT binding.
Signed-off-by: Sebastian Reichel sre@kernel.org
Acked-by: Pavel Machek pavel@ucw.cz
Pavel
This patch adds support for the Nokia N900's sound system.
Signed-off-by: Sebastian Reichel sre@kernel.org --- arch/arm/boot/dts/omap3-n900.dts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts index 6bc8100..5701f91 100644 --- a/arch/arm/boot/dts/omap3-n900.dts +++ b/arch/arm/boot/dts/omap3-n900.dts @@ -90,6 +90,19 @@ }; }; }; + + sound: n900-audio { + compatible = "nokia,n900-audio"; + + nokia,cpu-dai = <&mcbsp2>; + nokia,audio-codec = <&tlv320aic3x>, <&tlv320aic3x_aux>; + nokia,headphone-amplifier = <&tpa6130a2>; + + tvout-selection-gpios = <&gpio2 8 GPIO_ACTIVE_HIGH>; /* 40 */ + jack-detection-gpios = <&gpio6 17 GPIO_ACTIVE_HIGH>; /* 177 */ + eci-switch-gpios = <&gpio6 22 GPIO_ACTIVE_HIGH>; /* 182 */ + speaker-amplifier-gpios = <&twl_gpio 7 GPIO_ACTIVE_HIGH>; + }; };
&omap3_pmx_core { @@ -662,3 +675,7 @@ }; }; }; + +&mcbsp2 { + status = "ok"; +};
On Mon, Apr 28, 2014 at 04:07:27PM +0200, Sebastian Reichel wrote:
This patch adds support for the Nokia N900's sound system.
Reviewed-by: Mark Brown broonie@linaro.org
* Mark Brown broonie@kernel.org [140501 11:41]:
On Mon, Apr 28, 2014 at 04:07:27PM +0200, Sebastian Reichel wrote:
This patch adds support for the Nokia N900's sound system.
Reviewed-by: Mark Brown broonie@linaro.org
Applying the last patch into omap-for-v3.16/dt branch thanks.
Tony
On Mon 2014-04-28 16:07:27, Sebastian Reichel wrote:
This patch adds support for the Nokia N900's sound system.
Signed-off-by: Sebastian Reichel sre@kernel.org
Acked-by: Pavel Machek pavel@ucw.cz
participants (4)
-
Mark Brown
-
Pavel Machek
-
Sebastian Reichel
-
Tony Lindgren