Loading include/sound/soc.h +20 −2 Original line number Diff line number Diff line Loading @@ -452,6 +452,9 @@ int snd_soc_jack_get_type(struct snd_soc_jack *jack, int micbias_voltage); #ifdef CONFIG_GPIOLIB int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count, struct snd_soc_jack_gpio *gpios); int snd_soc_jack_add_gpiods(struct device *gpiod_dev, struct snd_soc_jack *jack, int count, struct snd_soc_jack_gpio *gpios); void snd_soc_jack_free_gpios(struct snd_soc_jack *jack, int count, struct snd_soc_jack_gpio *gpios); #else Loading @@ -461,6 +464,14 @@ static inline int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count, return 0; } static inline int snd_soc_jack_add_gpiods(struct device *gpiod_dev, struct snd_soc_jack *jack, int count, struct snd_soc_jack_gpio *gpios) { return 0; } static inline void snd_soc_jack_free_gpios(struct snd_soc_jack *jack, int count, struct snd_soc_jack_gpio *gpios) { Loading Loading @@ -587,8 +598,12 @@ struct snd_soc_jack_zone { /** * struct snd_soc_jack_gpio - Describes a gpio pin for jack detection * * @gpio: gpio number * @name: gpio name * @gpio: legacy gpio number * @idx: gpio descriptor index within the function of the GPIO * consumer device * @gpiod_dev GPIO consumer device * @name: gpio name. Also as connection ID for the GPIO consumer * device function name lookup * @report: value to report when jack detected * @invert: report presence in low state * @debouce_time: debouce time in ms Loading @@ -599,6 +614,8 @@ struct snd_soc_jack_zone { */ struct snd_soc_jack_gpio { unsigned int gpio; unsigned int idx; struct device *gpiod_dev; const char *name; int report; int invert; Loading @@ -607,6 +624,7 @@ struct snd_soc_jack_gpio { struct snd_soc_jack *jack; struct delayed_work work; struct gpio_desc *desc; void *data; int (*jack_status_check)(void *data); Loading sound/soc/intel/Kconfig +9 −0 Original line number Diff line number Diff line Loading @@ -49,3 +49,12 @@ config SND_SOC_INTEL_BYT_RT5640_MACH help This adds audio driver for Intel Baytrail platform based boards with the RT5640 audio codec. config SND_SOC_INTEL_BYT_MAX98090_MACH tristate "ASoC Audio driver for Intel Baytrail with MAX98090 codec" depends on SND_SOC_INTEL_SST && X86_INTEL_LPSS && I2C select SND_SOC_INTEL_BAYTRAIL select SND_SOC_MAX98090 help This adds audio driver for Intel Baytrail platform based boards with the MAX98090 audio codec. sound/soc/intel/Makefile +2 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,8 @@ obj-$(CONFIG_SND_SOC_INTEL_BAYTRAIL) += snd-soc-sst-baytrail-pcm.o # Machine support snd-soc-sst-haswell-objs := haswell.o snd-soc-sst-byt-rt5640-mach-objs := byt-rt5640.o snd-soc-sst-byt-max98090-mach-objs := byt-max98090.o obj-$(CONFIG_SND_SOC_INTEL_HASWELL_MACH) += snd-soc-sst-haswell.o obj-$(CONFIG_SND_SOC_INTEL_BYT_RT5640_MACH) += snd-soc-sst-byt-rt5640-mach.o obj-$(CONFIG_SND_SOC_INTEL_BYT_MAX98090_MACH) += snd-soc-sst-byt-max98090-mach.o sound/soc/intel/byt-max98090.c 0 → 100644 +203 −0 Original line number Diff line number Diff line /* * Intel Baytrail SST MAX98090 machine driver * Copyright (c) 2014, Intel Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. * * This program is distributed in the hope it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. */ #include <linux/init.h> #include <linux/module.h> #include <linux/platform_device.h> #include <linux/acpi.h> #include <linux/device.h> #include <linux/gpio.h> #include <linux/gpio/consumer.h> #include <linux/slab.h> #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> #include <sound/jack.h> #include "../codecs/max98090.h" struct byt_max98090_private { struct snd_soc_jack jack; }; static const struct snd_soc_dapm_widget byt_max98090_widgets[] = { SND_SOC_DAPM_HP("Headphone", NULL), SND_SOC_DAPM_MIC("Headset Mic", NULL), SND_SOC_DAPM_MIC("Int Mic", NULL), SND_SOC_DAPM_SPK("Ext Spk", NULL), }; static const struct snd_soc_dapm_route byt_max98090_audio_map[] = { {"IN34", NULL, "Headset Mic"}, {"IN34", NULL, "MICBIAS"}, {"MICBIAS", NULL, "Headset Mic"}, {"DMICL", NULL, "Int Mic"}, {"Headphone", NULL, "HPL"}, {"Headphone", NULL, "HPR"}, {"Ext Spk", NULL, "SPKL"}, {"Ext Spk", NULL, "SPKR"}, }; static const struct snd_kcontrol_new byt_max98090_controls[] = { SOC_DAPM_PIN_SWITCH("Headphone"), SOC_DAPM_PIN_SWITCH("Headset Mic"), SOC_DAPM_PIN_SWITCH("Int Mic"), SOC_DAPM_PIN_SWITCH("Ext Spk"), }; static struct snd_soc_jack_pin hs_jack_pins[] = { { .pin = "Headphone", .mask = SND_JACK_HEADPHONE, }, { .pin = "Headset Mic", .mask = SND_JACK_MICROPHONE, }, { .pin = "Ext Spk", .mask = SND_JACK_LINEOUT, }, { .pin = "Int Mic", .mask = SND_JACK_LINEIN, }, }; static struct snd_soc_jack_gpio hs_jack_gpios[] = { { .name = "hp-gpio", .idx = 0, .report = SND_JACK_HEADPHONE | SND_JACK_LINEOUT, .debounce_time = 200, }, { .name = "mic-gpio", .idx = 1, .report = SND_JACK_MICROPHONE | SND_JACK_LINEIN, .debounce_time = 200, }, }; static int byt_max98090_init(struct snd_soc_pcm_runtime *runtime) { int ret; struct snd_soc_codec *codec = runtime->codec; struct snd_soc_card *card = runtime->card; struct byt_max98090_private *drv = snd_soc_card_get_drvdata(card); struct snd_soc_jack *jack = &drv->jack; card->dapm.idle_bias_off = true; ret = snd_soc_dai_set_sysclk(runtime->codec_dai, M98090_REG_SYSTEM_CLOCK, 25000000, SND_SOC_CLOCK_IN); if (ret < 0) { dev_err(card->dev, "Can't set codec clock %d\n", ret); return ret; } /* Enable jack detection */ ret = snd_soc_jack_new(codec, "Headphone", SND_JACK_HEADPHONE, jack); if (ret) return ret; ret = snd_soc_jack_add_pins(jack, ARRAY_SIZE(hs_jack_pins), hs_jack_pins); if (ret) return ret; ret = snd_soc_jack_add_gpiods(card->dev->parent, jack, ARRAY_SIZE(hs_jack_gpios), hs_jack_gpios); if (ret) return ret; return max98090_mic_detect(codec, jack); } static struct snd_soc_dai_link byt_max98090_dais[] = { { .name = "Baytrail Audio", .stream_name = "Audio", .cpu_dai_name = "baytrail-pcm-audio", .codec_dai_name = "HiFi", .codec_name = "i2c-193C9890:00", .platform_name = "baytrail-pcm-audio", .init = byt_max98090_init, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS, }, }; static struct snd_soc_card byt_max98090_card = { .name = "byt-max98090", .dai_link = byt_max98090_dais, .num_links = ARRAY_SIZE(byt_max98090_dais), .dapm_widgets = byt_max98090_widgets, .num_dapm_widgets = ARRAY_SIZE(byt_max98090_widgets), .dapm_routes = byt_max98090_audio_map, .num_dapm_routes = ARRAY_SIZE(byt_max98090_audio_map), .controls = byt_max98090_controls, .num_controls = ARRAY_SIZE(byt_max98090_controls), }; static int byt_max98090_probe(struct platform_device *pdev) { int ret_val = 0; struct byt_max98090_private *priv; priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_ATOMIC); if (!priv) { dev_err(&pdev->dev, "allocation failed\n"); return -ENOMEM; } byt_max98090_card.dev = &pdev->dev; snd_soc_card_set_drvdata(&byt_max98090_card, priv); ret_val = devm_snd_soc_register_card(&pdev->dev, &byt_max98090_card); if (ret_val) { dev_err(&pdev->dev, "snd_soc_register_card failed %d\n", ret_val); return ret_val; } return ret_val; } static int byt_max98090_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); struct byt_max98090_private *priv = snd_soc_card_get_drvdata(card); snd_soc_jack_free_gpios(&priv->jack, ARRAY_SIZE(hs_jack_gpios), hs_jack_gpios); return 0; } static struct platform_driver byt_max98090_driver = { .probe = byt_max98090_probe, .remove = byt_max98090_remove, .driver = { .name = "byt-max98090", .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, }, }; module_platform_driver(byt_max98090_driver) MODULE_DESCRIPTION("ASoC Intel(R) Baytrail Machine driver"); MODULE_AUTHOR("Omair Md Abdullah, Jarkko Nikula"); MODULE_LICENSE("GPL v2"); MODULE_ALIAS("platform:byt-max98090"); sound/soc/intel/byt-rt5640.c +2 −25 Original line number Diff line number Diff line Loading @@ -132,43 +132,20 @@ static struct snd_soc_card byt_rt5640_card = { .num_dapm_routes = ARRAY_SIZE(byt_rt5640_audio_map), }; #ifdef CONFIG_PM_SLEEP static const struct dev_pm_ops byt_rt5640_pm_ops = { .suspend = snd_soc_suspend, .resume = snd_soc_resume, }; #define BYT_RT5640_PM_OPS (&byt_rt5640_pm_ops) #else #define BYT_RT5640_PM_OPS NULL #endif static int byt_rt5640_probe(struct platform_device *pdev) { struct snd_soc_card *card = &byt_rt5640_card; struct device *dev = &pdev->dev; card->dev = &pdev->dev; dev_set_drvdata(dev, card); return snd_soc_register_card(card); } static int byt_rt5640_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); snd_soc_unregister_card(card); return 0; return devm_snd_soc_register_card(&pdev->dev, card); } static struct platform_driver byt_rt5640_audio = { .probe = byt_rt5640_probe, .remove = byt_rt5640_remove, .driver = { .name = "byt-rt5640", .owner = THIS_MODULE, .pm = BYT_RT5640_PM_OPS, .pm = &snd_soc_pm_ops, }, }; module_platform_driver(byt_rt5640_audio) Loading Loading
include/sound/soc.h +20 −2 Original line number Diff line number Diff line Loading @@ -452,6 +452,9 @@ int snd_soc_jack_get_type(struct snd_soc_jack *jack, int micbias_voltage); #ifdef CONFIG_GPIOLIB int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count, struct snd_soc_jack_gpio *gpios); int snd_soc_jack_add_gpiods(struct device *gpiod_dev, struct snd_soc_jack *jack, int count, struct snd_soc_jack_gpio *gpios); void snd_soc_jack_free_gpios(struct snd_soc_jack *jack, int count, struct snd_soc_jack_gpio *gpios); #else Loading @@ -461,6 +464,14 @@ static inline int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count, return 0; } static inline int snd_soc_jack_add_gpiods(struct device *gpiod_dev, struct snd_soc_jack *jack, int count, struct snd_soc_jack_gpio *gpios) { return 0; } static inline void snd_soc_jack_free_gpios(struct snd_soc_jack *jack, int count, struct snd_soc_jack_gpio *gpios) { Loading Loading @@ -587,8 +598,12 @@ struct snd_soc_jack_zone { /** * struct snd_soc_jack_gpio - Describes a gpio pin for jack detection * * @gpio: gpio number * @name: gpio name * @gpio: legacy gpio number * @idx: gpio descriptor index within the function of the GPIO * consumer device * @gpiod_dev GPIO consumer device * @name: gpio name. Also as connection ID for the GPIO consumer * device function name lookup * @report: value to report when jack detected * @invert: report presence in low state * @debouce_time: debouce time in ms Loading @@ -599,6 +614,8 @@ struct snd_soc_jack_zone { */ struct snd_soc_jack_gpio { unsigned int gpio; unsigned int idx; struct device *gpiod_dev; const char *name; int report; int invert; Loading @@ -607,6 +624,7 @@ struct snd_soc_jack_gpio { struct snd_soc_jack *jack; struct delayed_work work; struct gpio_desc *desc; void *data; int (*jack_status_check)(void *data); Loading
sound/soc/intel/Kconfig +9 −0 Original line number Diff line number Diff line Loading @@ -49,3 +49,12 @@ config SND_SOC_INTEL_BYT_RT5640_MACH help This adds audio driver for Intel Baytrail platform based boards with the RT5640 audio codec. config SND_SOC_INTEL_BYT_MAX98090_MACH tristate "ASoC Audio driver for Intel Baytrail with MAX98090 codec" depends on SND_SOC_INTEL_SST && X86_INTEL_LPSS && I2C select SND_SOC_INTEL_BAYTRAIL select SND_SOC_MAX98090 help This adds audio driver for Intel Baytrail platform based boards with the MAX98090 audio codec.
sound/soc/intel/Makefile +2 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,8 @@ obj-$(CONFIG_SND_SOC_INTEL_BAYTRAIL) += snd-soc-sst-baytrail-pcm.o # Machine support snd-soc-sst-haswell-objs := haswell.o snd-soc-sst-byt-rt5640-mach-objs := byt-rt5640.o snd-soc-sst-byt-max98090-mach-objs := byt-max98090.o obj-$(CONFIG_SND_SOC_INTEL_HASWELL_MACH) += snd-soc-sst-haswell.o obj-$(CONFIG_SND_SOC_INTEL_BYT_RT5640_MACH) += snd-soc-sst-byt-rt5640-mach.o obj-$(CONFIG_SND_SOC_INTEL_BYT_MAX98090_MACH) += snd-soc-sst-byt-max98090-mach.o
sound/soc/intel/byt-max98090.c 0 → 100644 +203 −0 Original line number Diff line number Diff line /* * Intel Baytrail SST MAX98090 machine driver * Copyright (c) 2014, Intel Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. * * This program is distributed in the hope it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. */ #include <linux/init.h> #include <linux/module.h> #include <linux/platform_device.h> #include <linux/acpi.h> #include <linux/device.h> #include <linux/gpio.h> #include <linux/gpio/consumer.h> #include <linux/slab.h> #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> #include <sound/jack.h> #include "../codecs/max98090.h" struct byt_max98090_private { struct snd_soc_jack jack; }; static const struct snd_soc_dapm_widget byt_max98090_widgets[] = { SND_SOC_DAPM_HP("Headphone", NULL), SND_SOC_DAPM_MIC("Headset Mic", NULL), SND_SOC_DAPM_MIC("Int Mic", NULL), SND_SOC_DAPM_SPK("Ext Spk", NULL), }; static const struct snd_soc_dapm_route byt_max98090_audio_map[] = { {"IN34", NULL, "Headset Mic"}, {"IN34", NULL, "MICBIAS"}, {"MICBIAS", NULL, "Headset Mic"}, {"DMICL", NULL, "Int Mic"}, {"Headphone", NULL, "HPL"}, {"Headphone", NULL, "HPR"}, {"Ext Spk", NULL, "SPKL"}, {"Ext Spk", NULL, "SPKR"}, }; static const struct snd_kcontrol_new byt_max98090_controls[] = { SOC_DAPM_PIN_SWITCH("Headphone"), SOC_DAPM_PIN_SWITCH("Headset Mic"), SOC_DAPM_PIN_SWITCH("Int Mic"), SOC_DAPM_PIN_SWITCH("Ext Spk"), }; static struct snd_soc_jack_pin hs_jack_pins[] = { { .pin = "Headphone", .mask = SND_JACK_HEADPHONE, }, { .pin = "Headset Mic", .mask = SND_JACK_MICROPHONE, }, { .pin = "Ext Spk", .mask = SND_JACK_LINEOUT, }, { .pin = "Int Mic", .mask = SND_JACK_LINEIN, }, }; static struct snd_soc_jack_gpio hs_jack_gpios[] = { { .name = "hp-gpio", .idx = 0, .report = SND_JACK_HEADPHONE | SND_JACK_LINEOUT, .debounce_time = 200, }, { .name = "mic-gpio", .idx = 1, .report = SND_JACK_MICROPHONE | SND_JACK_LINEIN, .debounce_time = 200, }, }; static int byt_max98090_init(struct snd_soc_pcm_runtime *runtime) { int ret; struct snd_soc_codec *codec = runtime->codec; struct snd_soc_card *card = runtime->card; struct byt_max98090_private *drv = snd_soc_card_get_drvdata(card); struct snd_soc_jack *jack = &drv->jack; card->dapm.idle_bias_off = true; ret = snd_soc_dai_set_sysclk(runtime->codec_dai, M98090_REG_SYSTEM_CLOCK, 25000000, SND_SOC_CLOCK_IN); if (ret < 0) { dev_err(card->dev, "Can't set codec clock %d\n", ret); return ret; } /* Enable jack detection */ ret = snd_soc_jack_new(codec, "Headphone", SND_JACK_HEADPHONE, jack); if (ret) return ret; ret = snd_soc_jack_add_pins(jack, ARRAY_SIZE(hs_jack_pins), hs_jack_pins); if (ret) return ret; ret = snd_soc_jack_add_gpiods(card->dev->parent, jack, ARRAY_SIZE(hs_jack_gpios), hs_jack_gpios); if (ret) return ret; return max98090_mic_detect(codec, jack); } static struct snd_soc_dai_link byt_max98090_dais[] = { { .name = "Baytrail Audio", .stream_name = "Audio", .cpu_dai_name = "baytrail-pcm-audio", .codec_dai_name = "HiFi", .codec_name = "i2c-193C9890:00", .platform_name = "baytrail-pcm-audio", .init = byt_max98090_init, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS, }, }; static struct snd_soc_card byt_max98090_card = { .name = "byt-max98090", .dai_link = byt_max98090_dais, .num_links = ARRAY_SIZE(byt_max98090_dais), .dapm_widgets = byt_max98090_widgets, .num_dapm_widgets = ARRAY_SIZE(byt_max98090_widgets), .dapm_routes = byt_max98090_audio_map, .num_dapm_routes = ARRAY_SIZE(byt_max98090_audio_map), .controls = byt_max98090_controls, .num_controls = ARRAY_SIZE(byt_max98090_controls), }; static int byt_max98090_probe(struct platform_device *pdev) { int ret_val = 0; struct byt_max98090_private *priv; priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_ATOMIC); if (!priv) { dev_err(&pdev->dev, "allocation failed\n"); return -ENOMEM; } byt_max98090_card.dev = &pdev->dev; snd_soc_card_set_drvdata(&byt_max98090_card, priv); ret_val = devm_snd_soc_register_card(&pdev->dev, &byt_max98090_card); if (ret_val) { dev_err(&pdev->dev, "snd_soc_register_card failed %d\n", ret_val); return ret_val; } return ret_val; } static int byt_max98090_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); struct byt_max98090_private *priv = snd_soc_card_get_drvdata(card); snd_soc_jack_free_gpios(&priv->jack, ARRAY_SIZE(hs_jack_gpios), hs_jack_gpios); return 0; } static struct platform_driver byt_max98090_driver = { .probe = byt_max98090_probe, .remove = byt_max98090_remove, .driver = { .name = "byt-max98090", .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, }, }; module_platform_driver(byt_max98090_driver) MODULE_DESCRIPTION("ASoC Intel(R) Baytrail Machine driver"); MODULE_AUTHOR("Omair Md Abdullah, Jarkko Nikula"); MODULE_LICENSE("GPL v2"); MODULE_ALIAS("platform:byt-max98090");
sound/soc/intel/byt-rt5640.c +2 −25 Original line number Diff line number Diff line Loading @@ -132,43 +132,20 @@ static struct snd_soc_card byt_rt5640_card = { .num_dapm_routes = ARRAY_SIZE(byt_rt5640_audio_map), }; #ifdef CONFIG_PM_SLEEP static const struct dev_pm_ops byt_rt5640_pm_ops = { .suspend = snd_soc_suspend, .resume = snd_soc_resume, }; #define BYT_RT5640_PM_OPS (&byt_rt5640_pm_ops) #else #define BYT_RT5640_PM_OPS NULL #endif static int byt_rt5640_probe(struct platform_device *pdev) { struct snd_soc_card *card = &byt_rt5640_card; struct device *dev = &pdev->dev; card->dev = &pdev->dev; dev_set_drvdata(dev, card); return snd_soc_register_card(card); } static int byt_rt5640_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); snd_soc_unregister_card(card); return 0; return devm_snd_soc_register_card(&pdev->dev, card); } static struct platform_driver byt_rt5640_audio = { .probe = byt_rt5640_probe, .remove = byt_rt5640_remove, .driver = { .name = "byt-rt5640", .owner = THIS_MODULE, .pm = BYT_RT5640_PM_OPS, .pm = &snd_soc_pm_ops, }, }; module_platform_driver(byt_rt5640_audio) Loading