ASoC: pxa: remove unused board support
Most PXA/MMP boards were removed, so the board specific ASoC support is no longer needed, leaving only support for DT based ones, as well as the "gumstix" and "spitz" machines that may get converted to DT later. Cc: Ian Molton <spyro@f2s.com> Cc: Ken McGuire <kenm@desertweyr.com> Cc: Marek Vasut <marek.vasut@gmail.com> Cc: Mike Rapoport <rppt@kernel.org> Cc: Liam Girdwood <lgirdwood@gmail.com> Cc: Mark Brown <broonie@kernel.org> Cc: Jaroslav Kysela <perex@perex.cz> Cc: Takashi Iwai <tiwai@suse.com> Cc: alsa-devel@alsa-project.org Acked-by: Robert Jarzmik <robert.jarzmik@free.fr> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
Родитель
7aeffbf2dd
Коммит
b401d1fd80
|
@ -1,9 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _INCLUDE_PALMASOC_H_
|
||||
#define _INCLUDE_PALMASOC_H_
|
||||
|
||||
struct palm27x_asoc_info {
|
||||
int jack_gpio;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,16 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __LINUX_PLATFORM_DATA_POODLE_AUDIO
|
||||
#define __LINUX_PLATFORM_DATA_POODLE_AUDIO
|
||||
|
||||
/* locomo is not a proper gpio driver, and uses its own api */
|
||||
struct poodle_audio_platform_data {
|
||||
struct device *locomo_dev;
|
||||
|
||||
int gpio_amp_on;
|
||||
int gpio_mute_l;
|
||||
int gpio_mute_r;
|
||||
int gpio_232vcc_on;
|
||||
int gpio_jk_b;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,18 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* MMP Platform AUDIO Management
|
||||
*
|
||||
* Copyright (c) 2011 Marvell Semiconductors Inc.
|
||||
*/
|
||||
|
||||
#ifndef MMP_AUDIO_H
|
||||
#define MMP_AUDIO_H
|
||||
|
||||
struct mmp_audio_platdata {
|
||||
u32 period_max_capture;
|
||||
u32 buffer_max_capture;
|
||||
u32 period_max_playback;
|
||||
u32 buffer_max_playback;
|
||||
};
|
||||
|
||||
#endif /* MMP_AUDIO_H */
|
|
@ -8,10 +8,6 @@ config SND_PXA2XX_SOC
|
|||
the PXA2xx AC97, I2S or SSP interface. You will also need
|
||||
to select the audio interfaces to support below.
|
||||
|
||||
config SND_MMP_SOC
|
||||
bool
|
||||
select MMP_SRAM
|
||||
|
||||
config SND_PXA2XX_AC97
|
||||
tristate
|
||||
|
||||
|
@ -41,15 +37,6 @@ config SND_MMP_SOC_SSPA
|
|||
Say Y if you want to add support for codecs attached to
|
||||
the MMP SSPA interface.
|
||||
|
||||
config SND_PXA2XX_SOC_CORGI
|
||||
tristate "SoC Audio support for Sharp Zaurus SL-C7x0"
|
||||
depends on SND_PXA2XX_SOC && PXA_SHARP_C7xx && I2C
|
||||
select SND_PXA2XX_SOC_I2S
|
||||
select SND_SOC_WM8731_I2C
|
||||
help
|
||||
Say Y if you want to add support for SoC audio on Sharp
|
||||
Zaurus SL-C7x0 models (Corgi, Shepherd, Husky).
|
||||
|
||||
config SND_PXA2XX_SOC_SPITZ
|
||||
tristate "SoC Audio support for Sharp Zaurus SL-Cxx00"
|
||||
depends on SND_PXA2XX_SOC && PXA_SHARP_Cxx00 && I2C
|
||||
|
@ -59,101 +46,6 @@ config SND_PXA2XX_SOC_SPITZ
|
|||
Say Y if you want to add support for SoC audio on Sharp
|
||||
Zaurus SL-Cxx00 models (Spitz, Borzoi and Akita).
|
||||
|
||||
config SND_PXA2XX_SOC_Z2
|
||||
tristate "SoC Audio support for Zipit Z2"
|
||||
depends on SND_PXA2XX_SOC && MACH_ZIPIT2 && I2C
|
||||
select SND_PXA2XX_SOC_I2S
|
||||
select SND_SOC_WM8750
|
||||
help
|
||||
Say Y if you want to add support for SoC audio on Zipit Z2.
|
||||
|
||||
config SND_PXA2XX_SOC_POODLE
|
||||
tristate "SoC Audio support for Poodle"
|
||||
depends on SND_PXA2XX_SOC && MACH_POODLE && I2C
|
||||
select SND_PXA2XX_SOC_I2S
|
||||
select SND_SOC_WM8731_I2C
|
||||
help
|
||||
Say Y if you want to add support for SoC audio on Sharp
|
||||
Zaurus SL-5600 model (Poodle).
|
||||
|
||||
config SND_PXA2XX_SOC_TOSA
|
||||
tristate "SoC AC97 Audio support for Tosa"
|
||||
depends on SND_PXA2XX_SOC && MACH_TOSA
|
||||
depends on MFD_TC6393XB
|
||||
depends on AC97_BUS=n
|
||||
select REGMAP
|
||||
select AC97_BUS_NEW
|
||||
select AC97_BUS_COMPAT
|
||||
select SND_PXA2XX_SOC_AC97
|
||||
select SND_SOC_WM9712
|
||||
help
|
||||
Say Y if you want to add support for SoC audio on Sharp
|
||||
Zaurus SL-C6000x models (Tosa).
|
||||
|
||||
config SND_PXA2XX_SOC_E740
|
||||
tristate "SoC AC97 Audio support for e740"
|
||||
depends on SND_PXA2XX_SOC && MACH_E740
|
||||
depends on AC97_BUS=n
|
||||
select REGMAP
|
||||
select AC97_BUS_NEW
|
||||
select AC97_BUS_COMPAT
|
||||
select SND_SOC_WM9705
|
||||
select SND_PXA2XX_SOC_AC97
|
||||
help
|
||||
Say Y if you want to add support for SoC audio on the
|
||||
toshiba e740 PDA
|
||||
|
||||
config SND_PXA2XX_SOC_E750
|
||||
tristate "SoC AC97 Audio support for e750"
|
||||
depends on SND_PXA2XX_SOC && MACH_E750
|
||||
depends on AC97_BUS=n
|
||||
select REGMAP
|
||||
select SND_SOC_WM9705
|
||||
select SND_PXA2XX_SOC_AC97
|
||||
help
|
||||
Say Y if you want to add support for SoC audio on the
|
||||
toshiba e750 PDA
|
||||
|
||||
config SND_PXA2XX_SOC_E800
|
||||
tristate "SoC AC97 Audio support for e800"
|
||||
depends on SND_PXA2XX_SOC && MACH_E800
|
||||
depends on AC97_BUS=n
|
||||
select REGMAP
|
||||
select SND_SOC_WM9712
|
||||
select AC97_BUS_NEW
|
||||
select AC97_BUS_COMPAT
|
||||
select SND_PXA2XX_SOC_AC97
|
||||
help
|
||||
Say Y if you want to add support for SoC audio on the
|
||||
Toshiba e800 PDA
|
||||
|
||||
config SND_PXA2XX_SOC_EM_X270
|
||||
tristate "SoC Audio support for CompuLab CM-X300"
|
||||
depends on SND_PXA2XX_SOC && MACH_CM_X300
|
||||
depends on AC97_BUS=n
|
||||
select REGMAP
|
||||
select AC97_BUS_NEW
|
||||
select AC97_BUS_COMPAT
|
||||
select SND_PXA2XX_SOC_AC97
|
||||
select SND_SOC_WM9712
|
||||
help
|
||||
Say Y if you want to add support for SoC audio on
|
||||
CompuLab EM-x270, eXeda and CM-X300 machines.
|
||||
|
||||
config SND_PXA2XX_SOC_PALM27X
|
||||
bool "SoC Audio support for Palm T|X, T5, E2 and LifeDrive"
|
||||
depends on SND_PXA2XX_SOC && (MACH_PALMLD || MACH_PALMTX || \
|
||||
MACH_PALMT5 || MACH_PALMTE2)
|
||||
depends on AC97_BUS=n
|
||||
select REGMAP
|
||||
select AC97_BUS_NEW
|
||||
select AC97_BUS_COMPAT
|
||||
select SND_PXA2XX_SOC_AC97
|
||||
select SND_SOC_WM9712
|
||||
help
|
||||
Say Y if you want to add support for SoC audio on
|
||||
Palm T|X, T5, E2 or LifeDrive handheld computer.
|
||||
|
||||
config SND_PXA910_SOC
|
||||
tristate "SoC Audio for Marvell PXA910 chip"
|
||||
depends on ARCH_MMP && SND
|
||||
|
@ -161,71 +53,3 @@ config SND_PXA910_SOC
|
|||
help
|
||||
Say Y if you want to add support for SoC audio on the
|
||||
Marvell PXA910 reference platform.
|
||||
|
||||
config SND_SOC_TTC_DKB
|
||||
tristate "SoC Audio support for TTC DKB"
|
||||
depends on SND_PXA910_SOC && MACH_TTC_DKB && I2C=y
|
||||
select PXA_SSP
|
||||
select SND_PXA_SOC_SSP
|
||||
select SND_MMP_SOC
|
||||
select MFD_88PM860X
|
||||
select SND_SOC_88PM860X
|
||||
help
|
||||
Say Y if you want to add support for SoC audio on TTC DKB
|
||||
|
||||
|
||||
config SND_SOC_ZYLONITE
|
||||
tristate "SoC Audio support for Marvell Zylonite"
|
||||
depends on SND_PXA2XX_SOC && MACH_ZYLONITE
|
||||
depends on AC97_BUS=n
|
||||
select AC97_BUS_NEW
|
||||
select AC97_BUS_COMPAT
|
||||
select SND_PXA2XX_SOC_AC97
|
||||
select REGMAP
|
||||
select SND_PXA_SOC_SSP
|
||||
select SND_SOC_WM9713
|
||||
help
|
||||
Say Y if you want to add support for SoC audio on the
|
||||
Marvell Zylonite reference platform.
|
||||
|
||||
config SND_PXA2XX_SOC_HX4700
|
||||
tristate "SoC Audio support for HP iPAQ hx4700"
|
||||
depends on SND_PXA2XX_SOC && MACH_H4700 && I2C
|
||||
select SND_PXA2XX_SOC_I2S
|
||||
select SND_SOC_AK4641
|
||||
help
|
||||
Say Y if you want to add support for SoC audio on the
|
||||
HP iPAQ hx4700.
|
||||
|
||||
config SND_PXA2XX_SOC_MAGICIAN
|
||||
tristate "SoC Audio support for HTC Magician"
|
||||
depends on SND_PXA2XX_SOC && MACH_MAGICIAN && I2C
|
||||
select SND_PXA2XX_SOC_I2S
|
||||
select SND_PXA_SOC_SSP
|
||||
select SND_SOC_UDA1380
|
||||
help
|
||||
Say Y if you want to add support for SoC audio on the
|
||||
HTC Magician.
|
||||
|
||||
config SND_PXA2XX_SOC_MIOA701
|
||||
tristate "SoC Audio support for MIO A701"
|
||||
depends on SND_PXA2XX_SOC && MACH_MIOA701
|
||||
depends on AC97_BUS=n
|
||||
select REGMAP
|
||||
select AC97_BUS_NEW
|
||||
select AC97_BUS_COMPAT
|
||||
select SND_PXA2XX_SOC_AC97
|
||||
select SND_SOC_WM9713
|
||||
help
|
||||
Say Y if you want to add support for SoC audio on the
|
||||
MIO A701.
|
||||
|
||||
config SND_MMP_SOC_BROWNSTONE
|
||||
tristate "SoC Audio support for Marvell Brownstone"
|
||||
depends on SND_MMP_SOC_SSPA && MACH_BROWNSTONE && I2C
|
||||
select SND_MMP_SOC
|
||||
select MFD_WM8994
|
||||
select SND_SOC_WM8994
|
||||
help
|
||||
Say Y if you want to add support for SoC audio on the
|
||||
Marvell Brownstone reference platform.
|
||||
|
|
|
@ -4,47 +4,14 @@ snd-soc-pxa2xx-objs := pxa2xx-pcm.o
|
|||
snd-soc-pxa2xx-ac97-objs := pxa2xx-ac97.o
|
||||
snd-soc-pxa2xx-i2s-objs := pxa2xx-i2s.o
|
||||
snd-soc-pxa-ssp-objs := pxa-ssp.o
|
||||
snd-soc-mmp-objs := mmp-pcm.o
|
||||
snd-soc-mmp-sspa-objs := mmp-sspa.o
|
||||
|
||||
obj-$(CONFIG_SND_PXA2XX_SOC) += snd-soc-pxa2xx.o
|
||||
obj-$(CONFIG_SND_PXA2XX_SOC_AC97) += snd-soc-pxa2xx-ac97.o
|
||||
obj-$(CONFIG_SND_PXA2XX_SOC_I2S) += snd-soc-pxa2xx-i2s.o
|
||||
obj-$(CONFIG_SND_PXA_SOC_SSP) += snd-soc-pxa-ssp.o
|
||||
obj-$(CONFIG_SND_MMP_SOC) += snd-soc-mmp.o
|
||||
obj-$(CONFIG_SND_MMP_SOC_SSPA) += snd-soc-mmp-sspa.o
|
||||
|
||||
# PXA Machine Support
|
||||
snd-soc-corgi-objs := corgi.o
|
||||
snd-soc-poodle-objs := poodle.o
|
||||
snd-soc-tosa-objs := tosa.o
|
||||
snd-soc-e740-objs := e740_wm9705.o
|
||||
snd-soc-e750-objs := e750_wm9705.o
|
||||
snd-soc-e800-objs := e800_wm9712.o
|
||||
snd-soc-spitz-objs := spitz.o
|
||||
snd-soc-em-x270-objs := em-x270.o
|
||||
snd-soc-palm27x-objs := palm27x.o
|
||||
snd-soc-zylonite-objs := zylonite.o
|
||||
snd-soc-hx4700-objs := hx4700.o
|
||||
snd-soc-magician-objs := magician.o
|
||||
snd-soc-mioa701-objs := mioa701_wm9713.o
|
||||
snd-soc-z2-objs := z2.o
|
||||
snd-soc-brownstone-objs := brownstone.o
|
||||
snd-soc-ttc-dkb-objs := ttc-dkb.o
|
||||
|
||||
obj-$(CONFIG_SND_PXA2XX_SOC_CORGI) += snd-soc-corgi.o
|
||||
obj-$(CONFIG_SND_PXA2XX_SOC_POODLE) += snd-soc-poodle.o
|
||||
obj-$(CONFIG_SND_PXA2XX_SOC_TOSA) += snd-soc-tosa.o
|
||||
obj-$(CONFIG_SND_PXA2XX_SOC_E740) += snd-soc-e740.o
|
||||
obj-$(CONFIG_SND_PXA2XX_SOC_E750) += snd-soc-e750.o
|
||||
obj-$(CONFIG_SND_PXA2XX_SOC_E800) += snd-soc-e800.o
|
||||
obj-$(CONFIG_SND_PXA2XX_SOC_SPITZ) += snd-soc-spitz.o
|
||||
obj-$(CONFIG_SND_PXA2XX_SOC_EM_X270) += snd-soc-em-x270.o
|
||||
obj-$(CONFIG_SND_PXA2XX_SOC_PALM27X) += snd-soc-palm27x.o
|
||||
obj-$(CONFIG_SND_PXA2XX_SOC_HX4700) += snd-soc-hx4700.o
|
||||
obj-$(CONFIG_SND_PXA2XX_SOC_MAGICIAN) += snd-soc-magician.o
|
||||
obj-$(CONFIG_SND_PXA2XX_SOC_MIOA701) += snd-soc-mioa701.o
|
||||
obj-$(CONFIG_SND_PXA2XX_SOC_Z2) += snd-soc-z2.o
|
||||
obj-$(CONFIG_SND_SOC_ZYLONITE) += snd-soc-zylonite.o
|
||||
obj-$(CONFIG_SND_MMP_SOC_BROWNSTONE) += snd-soc-brownstone.o
|
||||
obj-$(CONFIG_SND_SOC_TTC_DKB) += snd-soc-ttc-dkb.o
|
||||
|
|
|
@ -1,133 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* linux/sound/soc/pxa/brownstone.c
|
||||
*
|
||||
* Copyright (C) 2011 Marvell International Ltd.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/pcm.h>
|
||||
#include <sound/soc.h>
|
||||
#include <sound/jack.h>
|
||||
|
||||
#include "../codecs/wm8994.h"
|
||||
#include "mmp-sspa.h"
|
||||
|
||||
static const struct snd_kcontrol_new brownstone_dapm_control[] = {
|
||||
SOC_DAPM_PIN_SWITCH("Ext Spk"),
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_widget brownstone_dapm_widgets[] = {
|
||||
SND_SOC_DAPM_SPK("Ext Spk", NULL),
|
||||
SND_SOC_DAPM_HP("Headset Stereophone", NULL),
|
||||
SND_SOC_DAPM_MIC("Headset Mic", NULL),
|
||||
SND_SOC_DAPM_MIC("Main Mic", NULL),
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_route brownstone_audio_map[] = {
|
||||
{"Ext Spk", NULL, "SPKOUTLP"},
|
||||
{"Ext Spk", NULL, "SPKOUTLN"},
|
||||
{"Ext Spk", NULL, "SPKOUTRP"},
|
||||
{"Ext Spk", NULL, "SPKOUTRN"},
|
||||
|
||||
{"Headset Stereophone", NULL, "HPOUT1L"},
|
||||
{"Headset Stereophone", NULL, "HPOUT1R"},
|
||||
|
||||
{"IN1RN", NULL, "Headset Mic"},
|
||||
|
||||
{"DMIC1DAT", NULL, "MICBIAS1"},
|
||||
{"MICBIAS1", NULL, "Main Mic"},
|
||||
};
|
||||
|
||||
static int brownstone_wm8994_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
|
||||
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
|
||||
struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
|
||||
int freq_out, sspa_mclk, sysclk;
|
||||
|
||||
if (params_rate(params) > 11025) {
|
||||
freq_out = params_rate(params) * 512;
|
||||
sysclk = params_rate(params) * 256;
|
||||
sspa_mclk = params_rate(params) * 64;
|
||||
} else {
|
||||
freq_out = params_rate(params) * 1024;
|
||||
sysclk = params_rate(params) * 512;
|
||||
sspa_mclk = params_rate(params) * 64;
|
||||
}
|
||||
|
||||
snd_soc_dai_set_sysclk(cpu_dai, MMP_SSPA_CLK_AUDIO, freq_out, 0);
|
||||
snd_soc_dai_set_pll(cpu_dai, MMP_SYSCLK, 0, freq_out, sysclk);
|
||||
snd_soc_dai_set_pll(cpu_dai, MMP_SSPA_CLK, 0, freq_out, sspa_mclk);
|
||||
|
||||
/* set wm8994 sysclk */
|
||||
snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_MCLK1, sysclk, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* machine stream operations */
|
||||
static const struct snd_soc_ops brownstone_ops = {
|
||||
.hw_params = brownstone_wm8994_hw_params,
|
||||
};
|
||||
|
||||
SND_SOC_DAILINK_DEFS(wm8994,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("mmp-sspa-dai.0")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("wm8994-codec", "wm8994-aif1")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("mmp-pcm-audio")));
|
||||
|
||||
static struct snd_soc_dai_link brownstone_wm8994_dai[] = {
|
||||
{
|
||||
.name = "WM8994",
|
||||
.stream_name = "WM8994 HiFi",
|
||||
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
|
||||
SND_SOC_DAIFMT_CBS_CFS,
|
||||
.ops = &brownstone_ops,
|
||||
SND_SOC_DAILINK_REG(wm8994),
|
||||
},
|
||||
};
|
||||
|
||||
/* audio machine driver */
|
||||
static struct snd_soc_card brownstone = {
|
||||
.name = "brownstone",
|
||||
.owner = THIS_MODULE,
|
||||
.dai_link = brownstone_wm8994_dai,
|
||||
.num_links = ARRAY_SIZE(brownstone_wm8994_dai),
|
||||
|
||||
.controls = brownstone_dapm_control,
|
||||
.num_controls = ARRAY_SIZE(brownstone_dapm_control),
|
||||
.dapm_widgets = brownstone_dapm_widgets,
|
||||
.num_dapm_widgets = ARRAY_SIZE(brownstone_dapm_widgets),
|
||||
.dapm_routes = brownstone_audio_map,
|
||||
.num_dapm_routes = ARRAY_SIZE(brownstone_audio_map),
|
||||
.fully_routed = true,
|
||||
};
|
||||
|
||||
static int brownstone_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
brownstone.dev = &pdev->dev;
|
||||
ret = devm_snd_soc_register_card(&pdev->dev, &brownstone);
|
||||
if (ret)
|
||||
dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct platform_driver mmp_driver = {
|
||||
.driver = {
|
||||
.name = "brownstone-audio",
|
||||
.pm = &snd_soc_pm_ops,
|
||||
},
|
||||
.probe = brownstone_probe,
|
||||
};
|
||||
|
||||
module_platform_driver(mmp_driver);
|
||||
|
||||
MODULE_AUTHOR("Leo Yan <leoy@marvell.com>");
|
||||
MODULE_DESCRIPTION("ALSA SoC Brownstone");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("platform:brownstone-audio");
|
|
@ -1,332 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* corgi.c -- SoC audio for Corgi
|
||||
*
|
||||
* Copyright 2005 Wolfson Microelectronics PLC.
|
||||
* Copyright 2005 Openedhand Ltd.
|
||||
*
|
||||
* Authors: Liam Girdwood <lrg@slimlogic.co.uk>
|
||||
* Richard Purdie <richard@openedhand.com>
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/pcm.h>
|
||||
#include <sound/soc.h>
|
||||
|
||||
#include <asm/mach-types.h>
|
||||
#include <linux/platform_data/asoc-pxa.h>
|
||||
|
||||
#include "../codecs/wm8731.h"
|
||||
#include "pxa2xx-i2s.h"
|
||||
|
||||
#define CORGI_HP 0
|
||||
#define CORGI_MIC 1
|
||||
#define CORGI_LINE 2
|
||||
#define CORGI_HEADSET 3
|
||||
#define CORGI_HP_OFF 4
|
||||
#define CORGI_SPK_ON 0
|
||||
#define CORGI_SPK_OFF 1
|
||||
|
||||
/* audio clock in Hz - rounded from 12.235MHz */
|
||||
#define CORGI_AUDIO_CLOCK 12288000
|
||||
|
||||
static int corgi_jack_func;
|
||||
static int corgi_spk_func;
|
||||
|
||||
static struct gpio_desc *gpiod_mute_l, *gpiod_mute_r,
|
||||
*gpiod_apm_on, *gpiod_mic_bias;
|
||||
|
||||
static void corgi_ext_control(struct snd_soc_dapm_context *dapm)
|
||||
{
|
||||
snd_soc_dapm_mutex_lock(dapm);
|
||||
|
||||
/* set up jack connection */
|
||||
switch (corgi_jack_func) {
|
||||
case CORGI_HP:
|
||||
/* set = unmute headphone */
|
||||
gpiod_set_value(gpiod_mute_l, 1);
|
||||
gpiod_set_value(gpiod_mute_r, 1);
|
||||
snd_soc_dapm_disable_pin_unlocked(dapm, "Mic Jack");
|
||||
snd_soc_dapm_disable_pin_unlocked(dapm, "Line Jack");
|
||||
snd_soc_dapm_enable_pin_unlocked(dapm, "Headphone Jack");
|
||||
snd_soc_dapm_disable_pin_unlocked(dapm, "Headset Jack");
|
||||
break;
|
||||
case CORGI_MIC:
|
||||
/* reset = mute headphone */
|
||||
gpiod_set_value(gpiod_mute_l, 0);
|
||||
gpiod_set_value(gpiod_mute_r, 0);
|
||||
snd_soc_dapm_enable_pin_unlocked(dapm, "Mic Jack");
|
||||
snd_soc_dapm_disable_pin_unlocked(dapm, "Line Jack");
|
||||
snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack");
|
||||
snd_soc_dapm_disable_pin_unlocked(dapm, "Headset Jack");
|
||||
break;
|
||||
case CORGI_LINE:
|
||||
gpiod_set_value(gpiod_mute_l, 0);
|
||||
gpiod_set_value(gpiod_mute_r, 0);
|
||||
snd_soc_dapm_disable_pin_unlocked(dapm, "Mic Jack");
|
||||
snd_soc_dapm_enable_pin_unlocked(dapm, "Line Jack");
|
||||
snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack");
|
||||
snd_soc_dapm_disable_pin_unlocked(dapm, "Headset Jack");
|
||||
break;
|
||||
case CORGI_HEADSET:
|
||||
gpiod_set_value(gpiod_mute_l, 0);
|
||||
gpiod_set_value(gpiod_mute_r, 1);
|
||||
snd_soc_dapm_enable_pin_unlocked(dapm, "Mic Jack");
|
||||
snd_soc_dapm_disable_pin_unlocked(dapm, "Line Jack");
|
||||
snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack");
|
||||
snd_soc_dapm_enable_pin_unlocked(dapm, "Headset Jack");
|
||||
break;
|
||||
}
|
||||
|
||||
if (corgi_spk_func == CORGI_SPK_ON)
|
||||
snd_soc_dapm_enable_pin_unlocked(dapm, "Ext Spk");
|
||||
else
|
||||
snd_soc_dapm_disable_pin_unlocked(dapm, "Ext Spk");
|
||||
|
||||
/* signal a DAPM event */
|
||||
snd_soc_dapm_sync_unlocked(dapm);
|
||||
|
||||
snd_soc_dapm_mutex_unlock(dapm);
|
||||
}
|
||||
|
||||
static int corgi_startup(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
|
||||
|
||||
/* check the jack status at stream startup */
|
||||
corgi_ext_control(&rtd->card->dapm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* we need to unmute the HP at shutdown as the mute burns power on corgi */
|
||||
static void corgi_shutdown(struct snd_pcm_substream *substream)
|
||||
{
|
||||
/* set = unmute headphone */
|
||||
gpiod_set_value(gpiod_mute_l, 1);
|
||||
gpiod_set_value(gpiod_mute_r, 1);
|
||||
}
|
||||
|
||||
static int corgi_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
|
||||
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
|
||||
struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
|
||||
unsigned int clk = 0;
|
||||
int ret = 0;
|
||||
|
||||
switch (params_rate(params)) {
|
||||
case 8000:
|
||||
case 16000:
|
||||
case 48000:
|
||||
case 96000:
|
||||
clk = 12288000;
|
||||
break;
|
||||
case 11025:
|
||||
case 22050:
|
||||
case 44100:
|
||||
clk = 11289600;
|
||||
break;
|
||||
}
|
||||
|
||||
/* set the codec system clock for DAC and ADC */
|
||||
ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK_XTAL, clk,
|
||||
SND_SOC_CLOCK_IN);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* set the I2S system clock as input (unused) */
|
||||
ret = snd_soc_dai_set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, 0,
|
||||
SND_SOC_CLOCK_IN);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_soc_ops corgi_ops = {
|
||||
.startup = corgi_startup,
|
||||
.hw_params = corgi_hw_params,
|
||||
.shutdown = corgi_shutdown,
|
||||
};
|
||||
|
||||
static int corgi_get_jack(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
ucontrol->value.enumerated.item[0] = corgi_jack_func;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int corgi_set_jack(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
|
||||
|
||||
if (corgi_jack_func == ucontrol->value.enumerated.item[0])
|
||||
return 0;
|
||||
|
||||
corgi_jack_func = ucontrol->value.enumerated.item[0];
|
||||
corgi_ext_control(&card->dapm);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int corgi_get_spk(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
ucontrol->value.enumerated.item[0] = corgi_spk_func;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int corgi_set_spk(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
|
||||
|
||||
if (corgi_spk_func == ucontrol->value.enumerated.item[0])
|
||||
return 0;
|
||||
|
||||
corgi_spk_func = ucontrol->value.enumerated.item[0];
|
||||
corgi_ext_control(&card->dapm);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int corgi_amp_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *k, int event)
|
||||
{
|
||||
gpiod_set_value(gpiod_apm_on, SND_SOC_DAPM_EVENT_ON(event));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int corgi_mic_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *k, int event)
|
||||
{
|
||||
gpiod_set_value(gpiod_mic_bias, SND_SOC_DAPM_EVENT_ON(event));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* corgi machine dapm widgets */
|
||||
static const struct snd_soc_dapm_widget wm8731_dapm_widgets[] = {
|
||||
SND_SOC_DAPM_HP("Headphone Jack", NULL),
|
||||
SND_SOC_DAPM_MIC("Mic Jack", corgi_mic_event),
|
||||
SND_SOC_DAPM_SPK("Ext Spk", corgi_amp_event),
|
||||
SND_SOC_DAPM_LINE("Line Jack", NULL),
|
||||
SND_SOC_DAPM_HP("Headset Jack", NULL),
|
||||
};
|
||||
|
||||
/* Corgi machine audio map (connections to the codec pins) */
|
||||
static const struct snd_soc_dapm_route corgi_audio_map[] = {
|
||||
|
||||
/* headset Jack - in = micin, out = LHPOUT*/
|
||||
{"Headset Jack", NULL, "LHPOUT"},
|
||||
|
||||
/* headphone connected to LHPOUT1, RHPOUT1 */
|
||||
{"Headphone Jack", NULL, "LHPOUT"},
|
||||
{"Headphone Jack", NULL, "RHPOUT"},
|
||||
|
||||
/* speaker connected to LOUT, ROUT */
|
||||
{"Ext Spk", NULL, "ROUT"},
|
||||
{"Ext Spk", NULL, "LOUT"},
|
||||
|
||||
/* mic is connected to MICIN (via right channel of headphone jack) */
|
||||
{"MICIN", NULL, "Mic Jack"},
|
||||
|
||||
/* Same as the above but no mic bias for line signals */
|
||||
{"MICIN", NULL, "Line Jack"},
|
||||
};
|
||||
|
||||
static const char * const jack_function[] = {"Headphone", "Mic", "Line",
|
||||
"Headset", "Off"};
|
||||
static const char * const spk_function[] = {"On", "Off"};
|
||||
static const struct soc_enum corgi_enum[] = {
|
||||
SOC_ENUM_SINGLE_EXT(5, jack_function),
|
||||
SOC_ENUM_SINGLE_EXT(2, spk_function),
|
||||
};
|
||||
|
||||
static const struct snd_kcontrol_new wm8731_corgi_controls[] = {
|
||||
SOC_ENUM_EXT("Jack Function", corgi_enum[0], corgi_get_jack,
|
||||
corgi_set_jack),
|
||||
SOC_ENUM_EXT("Speaker Function", corgi_enum[1], corgi_get_spk,
|
||||
corgi_set_spk),
|
||||
};
|
||||
|
||||
/* corgi digital audio interface glue - connects codec <--> CPU */
|
||||
SND_SOC_DAILINK_DEFS(wm8731,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("pxa2xx-i2s")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("wm8731.0-001b", "wm8731-hifi")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio")));
|
||||
|
||||
static struct snd_soc_dai_link corgi_dai = {
|
||||
.name = "WM8731",
|
||||
.stream_name = "WM8731",
|
||||
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
|
||||
SND_SOC_DAIFMT_CBS_CFS,
|
||||
.ops = &corgi_ops,
|
||||
SND_SOC_DAILINK_REG(wm8731),
|
||||
};
|
||||
|
||||
/* corgi audio machine driver */
|
||||
static struct snd_soc_card corgi = {
|
||||
.name = "Corgi",
|
||||
.owner = THIS_MODULE,
|
||||
.dai_link = &corgi_dai,
|
||||
.num_links = 1,
|
||||
|
||||
.controls = wm8731_corgi_controls,
|
||||
.num_controls = ARRAY_SIZE(wm8731_corgi_controls),
|
||||
.dapm_widgets = wm8731_dapm_widgets,
|
||||
.num_dapm_widgets = ARRAY_SIZE(wm8731_dapm_widgets),
|
||||
.dapm_routes = corgi_audio_map,
|
||||
.num_dapm_routes = ARRAY_SIZE(corgi_audio_map),
|
||||
.fully_routed = true,
|
||||
};
|
||||
|
||||
static int corgi_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct snd_soc_card *card = &corgi;
|
||||
int ret;
|
||||
|
||||
card->dev = &pdev->dev;
|
||||
|
||||
gpiod_mute_l = devm_gpiod_get(&pdev->dev, "mute-l", GPIOD_OUT_HIGH);
|
||||
if (IS_ERR(gpiod_mute_l))
|
||||
return PTR_ERR(gpiod_mute_l);
|
||||
gpiod_mute_r = devm_gpiod_get(&pdev->dev, "mute-r", GPIOD_OUT_HIGH);
|
||||
if (IS_ERR(gpiod_mute_r))
|
||||
return PTR_ERR(gpiod_mute_r);
|
||||
gpiod_apm_on = devm_gpiod_get(&pdev->dev, "apm-on", GPIOD_OUT_LOW);
|
||||
if (IS_ERR(gpiod_apm_on))
|
||||
return PTR_ERR(gpiod_apm_on);
|
||||
gpiod_mic_bias = devm_gpiod_get(&pdev->dev, "mic-bias", GPIOD_OUT_LOW);
|
||||
if (IS_ERR(gpiod_mic_bias))
|
||||
return PTR_ERR(gpiod_mic_bias);
|
||||
|
||||
ret = devm_snd_soc_register_card(&pdev->dev, card);
|
||||
if (ret)
|
||||
dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct platform_driver corgi_driver = {
|
||||
.driver = {
|
||||
.name = "corgi-audio",
|
||||
.pm = &snd_soc_pm_ops,
|
||||
},
|
||||
.probe = corgi_probe,
|
||||
};
|
||||
|
||||
module_platform_driver(corgi_driver);
|
||||
|
||||
/* Module information */
|
||||
MODULE_AUTHOR("Richard Purdie");
|
||||
MODULE_DESCRIPTION("ALSA SoC Corgi");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("platform:corgi-audio");
|
|
@ -1,168 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* e740-wm9705.c -- SoC audio for e740
|
||||
*
|
||||
* Copyright 2007 (c) Ian Molton <spyro@f2s.com>
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
|
||||
#include <sound/core.h>
|
||||
#include <sound/pcm.h>
|
||||
#include <sound/soc.h>
|
||||
|
||||
#include <linux/platform_data/asoc-pxa.h>
|
||||
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
static struct gpio_desc *gpiod_output_amp, *gpiod_input_amp;
|
||||
static struct gpio_desc *gpiod_audio_power;
|
||||
|
||||
#define E740_AUDIO_OUT 1
|
||||
#define E740_AUDIO_IN 2
|
||||
|
||||
static int e740_audio_power;
|
||||
|
||||
static void e740_sync_audio_power(int status)
|
||||
{
|
||||
gpiod_set_value(gpiod_audio_power, !status);
|
||||
gpiod_set_value(gpiod_output_amp, (status & E740_AUDIO_OUT) ? 1 : 0);
|
||||
gpiod_set_value(gpiod_input_amp, (status & E740_AUDIO_IN) ? 1 : 0);
|
||||
}
|
||||
|
||||
static int e740_mic_amp_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
if (event & SND_SOC_DAPM_PRE_PMU)
|
||||
e740_audio_power |= E740_AUDIO_IN;
|
||||
else if (event & SND_SOC_DAPM_POST_PMD)
|
||||
e740_audio_power &= ~E740_AUDIO_IN;
|
||||
|
||||
e740_sync_audio_power(e740_audio_power);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int e740_output_amp_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
if (event & SND_SOC_DAPM_PRE_PMU)
|
||||
e740_audio_power |= E740_AUDIO_OUT;
|
||||
else if (event & SND_SOC_DAPM_POST_PMD)
|
||||
e740_audio_power &= ~E740_AUDIO_OUT;
|
||||
|
||||
e740_sync_audio_power(e740_audio_power);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_soc_dapm_widget e740_dapm_widgets[] = {
|
||||
SND_SOC_DAPM_HP("Headphone Jack", NULL),
|
||||
SND_SOC_DAPM_SPK("Speaker", NULL),
|
||||
SND_SOC_DAPM_MIC("Mic (Internal)", NULL),
|
||||
SND_SOC_DAPM_PGA_E("Output Amp", SND_SOC_NOPM, 0, 0, NULL, 0,
|
||||
e740_output_amp_event, SND_SOC_DAPM_PRE_PMU |
|
||||
SND_SOC_DAPM_POST_PMD),
|
||||
SND_SOC_DAPM_PGA_E("Mic Amp", SND_SOC_NOPM, 0, 0, NULL, 0,
|
||||
e740_mic_amp_event, SND_SOC_DAPM_PRE_PMU |
|
||||
SND_SOC_DAPM_POST_PMD),
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_route audio_map[] = {
|
||||
{"Output Amp", NULL, "LOUT"},
|
||||
{"Output Amp", NULL, "ROUT"},
|
||||
{"Output Amp", NULL, "MONOOUT"},
|
||||
|
||||
{"Speaker", NULL, "Output Amp"},
|
||||
{"Headphone Jack", NULL, "Output Amp"},
|
||||
|
||||
{"MIC1", NULL, "Mic Amp"},
|
||||
{"Mic Amp", NULL, "Mic (Internal)"},
|
||||
};
|
||||
|
||||
SND_SOC_DAILINK_DEFS(ac97,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("pxa2xx-ac97")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("wm9705-codec", "wm9705-hifi")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio")));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(ac97_aux,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("pxa2xx-ac97-aux")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("wm9705-codec", "wm9705-aux")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio")));
|
||||
|
||||
static struct snd_soc_dai_link e740_dai[] = {
|
||||
{
|
||||
.name = "AC97",
|
||||
.stream_name = "AC97 HiFi",
|
||||
SND_SOC_DAILINK_REG(ac97),
|
||||
},
|
||||
{
|
||||
.name = "AC97 Aux",
|
||||
.stream_name = "AC97 Aux",
|
||||
SND_SOC_DAILINK_REG(ac97_aux),
|
||||
},
|
||||
};
|
||||
|
||||
static struct snd_soc_card e740 = {
|
||||
.name = "Toshiba e740",
|
||||
.owner = THIS_MODULE,
|
||||
.dai_link = e740_dai,
|
||||
.num_links = ARRAY_SIZE(e740_dai),
|
||||
|
||||
.dapm_widgets = e740_dapm_widgets,
|
||||
.num_dapm_widgets = ARRAY_SIZE(e740_dapm_widgets),
|
||||
.dapm_routes = audio_map,
|
||||
.num_dapm_routes = ARRAY_SIZE(audio_map),
|
||||
.fully_routed = true,
|
||||
};
|
||||
|
||||
static int e740_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct snd_soc_card *card = &e740;
|
||||
int ret;
|
||||
|
||||
gpiod_input_amp = devm_gpiod_get(&pdev->dev, "Mic amp", GPIOD_OUT_LOW);
|
||||
ret = PTR_ERR_OR_ZERO(gpiod_input_amp);
|
||||
if (ret)
|
||||
return ret;
|
||||
gpiod_output_amp = devm_gpiod_get(&pdev->dev, "Output amp", GPIOD_OUT_LOW);
|
||||
ret = PTR_ERR_OR_ZERO(gpiod_output_amp);
|
||||
if (ret)
|
||||
return ret;
|
||||
gpiod_audio_power = devm_gpiod_get(&pdev->dev, "Audio power", GPIOD_OUT_HIGH);
|
||||
ret = PTR_ERR_OR_ZERO(gpiod_audio_power);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
card->dev = &pdev->dev;
|
||||
|
||||
ret = devm_snd_soc_register_card(&pdev->dev, card);
|
||||
if (ret)
|
||||
dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int e740_remove(struct platform_device *pdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver e740_driver = {
|
||||
.driver = {
|
||||
.name = "e740-audio",
|
||||
.pm = &snd_soc_pm_ops,
|
||||
},
|
||||
.probe = e740_probe,
|
||||
.remove = e740_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(e740_driver);
|
||||
|
||||
/* Module information */
|
||||
MODULE_AUTHOR("Ian Molton <spyro@f2s.com>");
|
||||
MODULE_DESCRIPTION("ALSA SoC driver for e740");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_ALIAS("platform:e740-audio");
|
|
@ -1,147 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* e750-wm9705.c -- SoC audio for e750
|
||||
*
|
||||
* Copyright 2007 (c) Ian Molton <spyro@f2s.com>
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
|
||||
#include <sound/core.h>
|
||||
#include <sound/pcm.h>
|
||||
#include <sound/soc.h>
|
||||
|
||||
#include <linux/platform_data/asoc-pxa.h>
|
||||
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
static struct gpio_desc *gpiod_spk_amp, *gpiod_hp_amp;
|
||||
|
||||
static int e750_spk_amp_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
if (event & SND_SOC_DAPM_PRE_PMU)
|
||||
gpiod_set_value(gpiod_spk_amp, 1);
|
||||
else if (event & SND_SOC_DAPM_POST_PMD)
|
||||
gpiod_set_value(gpiod_spk_amp, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int e750_hp_amp_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
if (event & SND_SOC_DAPM_PRE_PMU)
|
||||
gpiod_set_value(gpiod_hp_amp, 1);
|
||||
else if (event & SND_SOC_DAPM_POST_PMD)
|
||||
gpiod_set_value(gpiod_hp_amp, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_soc_dapm_widget e750_dapm_widgets[] = {
|
||||
SND_SOC_DAPM_HP("Headphone Jack", NULL),
|
||||
SND_SOC_DAPM_SPK("Speaker", NULL),
|
||||
SND_SOC_DAPM_MIC("Mic (Internal)", NULL),
|
||||
SND_SOC_DAPM_PGA_E("Headphone Amp", SND_SOC_NOPM, 0, 0, NULL, 0,
|
||||
e750_hp_amp_event, SND_SOC_DAPM_PRE_PMU |
|
||||
SND_SOC_DAPM_POST_PMD),
|
||||
SND_SOC_DAPM_PGA_E("Speaker Amp", SND_SOC_NOPM, 0, 0, NULL, 0,
|
||||
e750_spk_amp_event, SND_SOC_DAPM_PRE_PMU |
|
||||
SND_SOC_DAPM_POST_PMD),
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_route audio_map[] = {
|
||||
{"Headphone Amp", NULL, "HPOUTL"},
|
||||
{"Headphone Amp", NULL, "HPOUTR"},
|
||||
{"Headphone Jack", NULL, "Headphone Amp"},
|
||||
|
||||
{"Speaker Amp", NULL, "MONOOUT"},
|
||||
{"Speaker", NULL, "Speaker Amp"},
|
||||
|
||||
{"MIC1", NULL, "Mic (Internal)"},
|
||||
};
|
||||
|
||||
SND_SOC_DAILINK_DEFS(ac97,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("pxa2xx-ac97")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("wm9705-codec", "wm9705-hifi")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio")));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(ac97_aux,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("pxa2xx-ac97-aux")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("wm9705-codec", "wm9705-aux")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio")));
|
||||
|
||||
static struct snd_soc_dai_link e750_dai[] = {
|
||||
{
|
||||
.name = "AC97",
|
||||
.stream_name = "AC97 HiFi",
|
||||
SND_SOC_DAILINK_REG(ac97),
|
||||
/* use ops to check startup state */
|
||||
},
|
||||
{
|
||||
.name = "AC97 Aux",
|
||||
.stream_name = "AC97 Aux",
|
||||
SND_SOC_DAILINK_REG(ac97_aux),
|
||||
},
|
||||
};
|
||||
|
||||
static struct snd_soc_card e750 = {
|
||||
.name = "Toshiba e750",
|
||||
.owner = THIS_MODULE,
|
||||
.dai_link = e750_dai,
|
||||
.num_links = ARRAY_SIZE(e750_dai),
|
||||
|
||||
.dapm_widgets = e750_dapm_widgets,
|
||||
.num_dapm_widgets = ARRAY_SIZE(e750_dapm_widgets),
|
||||
.dapm_routes = audio_map,
|
||||
.num_dapm_routes = ARRAY_SIZE(audio_map),
|
||||
.fully_routed = true,
|
||||
};
|
||||
|
||||
static int e750_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct snd_soc_card *card = &e750;
|
||||
int ret;
|
||||
|
||||
gpiod_hp_amp = devm_gpiod_get(&pdev->dev, "Headphone amp", GPIOD_OUT_LOW);
|
||||
ret = PTR_ERR_OR_ZERO(gpiod_hp_amp);
|
||||
if (ret)
|
||||
return ret;
|
||||
gpiod_spk_amp = devm_gpiod_get(&pdev->dev, "Speaker amp", GPIOD_OUT_LOW);
|
||||
ret = PTR_ERR_OR_ZERO(gpiod_spk_amp);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
card->dev = &pdev->dev;
|
||||
|
||||
ret = devm_snd_soc_register_card(&pdev->dev, card);
|
||||
if (ret)
|
||||
dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int e750_remove(struct platform_device *pdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver e750_driver = {
|
||||
.driver = {
|
||||
.name = "e750-audio",
|
||||
.pm = &snd_soc_pm_ops,
|
||||
},
|
||||
.probe = e750_probe,
|
||||
.remove = e750_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(e750_driver);
|
||||
|
||||
/* Module information */
|
||||
MODULE_AUTHOR("Ian Molton <spyro@f2s.com>");
|
||||
MODULE_DESCRIPTION("ALSA SoC driver for e750");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_ALIAS("platform:e750-audio");
|
|
@ -1,147 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* e800-wm9712.c -- SoC audio for e800
|
||||
*
|
||||
* Copyright 2007 (c) Ian Molton <spyro@f2s.com>
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
|
||||
#include <sound/core.h>
|
||||
#include <sound/pcm.h>
|
||||
#include <sound/soc.h>
|
||||
|
||||
#include <asm/mach-types.h>
|
||||
#include <linux/platform_data/asoc-pxa.h>
|
||||
|
||||
static struct gpio_desc *gpiod_spk_amp, *gpiod_hp_amp;
|
||||
|
||||
static int e800_spk_amp_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
if (event & SND_SOC_DAPM_PRE_PMU)
|
||||
gpiod_set_value(gpiod_spk_amp, 1);
|
||||
else if (event & SND_SOC_DAPM_POST_PMD)
|
||||
gpiod_set_value(gpiod_spk_amp, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int e800_hp_amp_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
if (event & SND_SOC_DAPM_PRE_PMU)
|
||||
gpiod_set_value(gpiod_hp_amp, 1);
|
||||
else if (event & SND_SOC_DAPM_POST_PMD)
|
||||
gpiod_set_value(gpiod_hp_amp, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_soc_dapm_widget e800_dapm_widgets[] = {
|
||||
SND_SOC_DAPM_HP("Headphone Jack", NULL),
|
||||
SND_SOC_DAPM_MIC("Mic (Internal1)", NULL),
|
||||
SND_SOC_DAPM_MIC("Mic (Internal2)", NULL),
|
||||
SND_SOC_DAPM_SPK("Speaker", NULL),
|
||||
SND_SOC_DAPM_PGA_E("Headphone Amp", SND_SOC_NOPM, 0, 0, NULL, 0,
|
||||
e800_hp_amp_event, SND_SOC_DAPM_PRE_PMU |
|
||||
SND_SOC_DAPM_POST_PMD),
|
||||
SND_SOC_DAPM_PGA_E("Speaker Amp", SND_SOC_NOPM, 0, 0, NULL, 0,
|
||||
e800_spk_amp_event, SND_SOC_DAPM_PRE_PMU |
|
||||
SND_SOC_DAPM_POST_PMD),
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_route audio_map[] = {
|
||||
{"Headphone Jack", NULL, "HPOUTL"},
|
||||
{"Headphone Jack", NULL, "HPOUTR"},
|
||||
{"Headphone Jack", NULL, "Headphone Amp"},
|
||||
|
||||
{"Speaker Amp", NULL, "MONOOUT"},
|
||||
{"Speaker", NULL, "Speaker Amp"},
|
||||
|
||||
{"MIC1", NULL, "Mic (Internal1)"},
|
||||
{"MIC2", NULL, "Mic (Internal2)"},
|
||||
};
|
||||
|
||||
|
||||
SND_SOC_DAILINK_DEFS(ac97,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("pxa2xx-ac97")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("wm9712-codec", "wm9712-hifi")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio")));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(ac97_aux,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("pxa2xx-ac97-aux")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("wm9712-codec", "wm9712-aux")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio")));
|
||||
|
||||
static struct snd_soc_dai_link e800_dai[] = {
|
||||
{
|
||||
.name = "AC97",
|
||||
.stream_name = "AC97 HiFi",
|
||||
SND_SOC_DAILINK_REG(ac97),
|
||||
},
|
||||
{
|
||||
.name = "AC97 Aux",
|
||||
.stream_name = "AC97 Aux",
|
||||
SND_SOC_DAILINK_REG(ac97_aux),
|
||||
},
|
||||
};
|
||||
|
||||
static struct snd_soc_card e800 = {
|
||||
.name = "Toshiba e800",
|
||||
.owner = THIS_MODULE,
|
||||
.dai_link = e800_dai,
|
||||
.num_links = ARRAY_SIZE(e800_dai),
|
||||
|
||||
.dapm_widgets = e800_dapm_widgets,
|
||||
.num_dapm_widgets = ARRAY_SIZE(e800_dapm_widgets),
|
||||
.dapm_routes = audio_map,
|
||||
.num_dapm_routes = ARRAY_SIZE(audio_map),
|
||||
};
|
||||
|
||||
static int e800_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct snd_soc_card *card = &e800;
|
||||
int ret;
|
||||
|
||||
gpiod_hp_amp = devm_gpiod_get(&pdev->dev, "Headphone amp", GPIOD_OUT_LOW);
|
||||
ret = PTR_ERR_OR_ZERO(gpiod_hp_amp);
|
||||
if (ret)
|
||||
return ret;
|
||||
gpiod_spk_amp = devm_gpiod_get(&pdev->dev, "Speaker amp", GPIOD_OUT_LOW);
|
||||
ret = PTR_ERR_OR_ZERO(gpiod_spk_amp);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
card->dev = &pdev->dev;
|
||||
|
||||
ret = devm_snd_soc_register_card(&pdev->dev, card);
|
||||
if (ret)
|
||||
dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int e800_remove(struct platform_device *pdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver e800_driver = {
|
||||
.driver = {
|
||||
.name = "e800-audio",
|
||||
.pm = &snd_soc_pm_ops,
|
||||
},
|
||||
.probe = e800_probe,
|
||||
.remove = e800_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(e800_driver);
|
||||
|
||||
/* Module information */
|
||||
MODULE_AUTHOR("Ian Molton <spyro@f2s.com>");
|
||||
MODULE_DESCRIPTION("ALSA SoC driver for e800");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_ALIAS("platform:e800-audio");
|
|
@ -1,92 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* SoC audio driver for EM-X270, eXeda and CM-X300
|
||||
*
|
||||
* Copyright 2007, 2009 CompuLab, Ltd.
|
||||
*
|
||||
* Author: Mike Rapoport <mike@compulab.co.il>
|
||||
*
|
||||
* Copied from tosa.c:
|
||||
* Copyright 2005 Wolfson Microelectronics PLC.
|
||||
* Copyright 2005 Openedhand Ltd.
|
||||
*
|
||||
* Authors: Liam Girdwood <lrg@slimlogic.co.uk>
|
||||
* Richard Purdie <richard@openedhand.com>
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/device.h>
|
||||
|
||||
#include <sound/core.h>
|
||||
#include <sound/pcm.h>
|
||||
#include <sound/soc.h>
|
||||
|
||||
#include <asm/mach-types.h>
|
||||
#include <linux/platform_data/asoc-pxa.h>
|
||||
|
||||
SND_SOC_DAILINK_DEFS(ac97,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("pxa2xx-ac97")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("wm9712-codec", "wm9712-hifi")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio")));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(ac97_aux,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("pxa2xx-ac97-aux")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("wm9712-codec", "wm9712-aux")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio")));
|
||||
|
||||
static struct snd_soc_dai_link em_x270_dai[] = {
|
||||
{
|
||||
.name = "AC97",
|
||||
.stream_name = "AC97 HiFi",
|
||||
SND_SOC_DAILINK_REG(ac97),
|
||||
},
|
||||
{
|
||||
.name = "AC97 Aux",
|
||||
.stream_name = "AC97 Aux",
|
||||
SND_SOC_DAILINK_REG(ac97_aux),
|
||||
},
|
||||
};
|
||||
|
||||
static struct snd_soc_card em_x270 = {
|
||||
.name = "EM-X270",
|
||||
.owner = THIS_MODULE,
|
||||
.dai_link = em_x270_dai,
|
||||
.num_links = ARRAY_SIZE(em_x270_dai),
|
||||
};
|
||||
|
||||
static struct platform_device *em_x270_snd_device;
|
||||
|
||||
static int __init em_x270_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!(machine_is_em_x270() || machine_is_exeda()
|
||||
|| machine_is_cm_x300()))
|
||||
return -ENODEV;
|
||||
|
||||
em_x270_snd_device = platform_device_alloc("soc-audio", -1);
|
||||
if (!em_x270_snd_device)
|
||||
return -ENOMEM;
|
||||
|
||||
platform_set_drvdata(em_x270_snd_device, &em_x270);
|
||||
ret = platform_device_add(em_x270_snd_device);
|
||||
|
||||
if (ret)
|
||||
platform_device_put(em_x270_snd_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit em_x270_exit(void)
|
||||
{
|
||||
platform_device_unregister(em_x270_snd_device);
|
||||
}
|
||||
|
||||
module_init(em_x270_init);
|
||||
module_exit(em_x270_exit);
|
||||
|
||||
/* Module information */
|
||||
MODULE_AUTHOR("Mike Rapoport");
|
||||
MODULE_DESCRIPTION("ALSA SoC EM-X270, eXeda and CM-X300");
|
||||
MODULE_LICENSE("GPL");
|
|
@ -1,207 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* SoC audio for HP iPAQ hx4700
|
||||
*
|
||||
* Copyright (c) 2009 Philipp Zabel
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
|
||||
#include <sound/core.h>
|
||||
#include <sound/jack.h>
|
||||
#include <sound/pcm.h>
|
||||
#include <sound/pcm_params.h>
|
||||
#include <sound/soc.h>
|
||||
|
||||
#include <asm/mach-types.h>
|
||||
#include "pxa2xx-i2s.h"
|
||||
|
||||
static struct gpio_desc *gpiod_hp_driver, *gpiod_spk_sd;
|
||||
static struct snd_soc_jack hs_jack;
|
||||
|
||||
/* Headphones jack detection DAPM pin */
|
||||
static struct snd_soc_jack_pin hs_jack_pin[] = {
|
||||
{
|
||||
.pin = "Headphone Jack",
|
||||
.mask = SND_JACK_HEADPHONE,
|
||||
.invert = 1,
|
||||
},
|
||||
{
|
||||
.pin = "Speaker",
|
||||
/* disable speaker when hp jack is inserted */
|
||||
.mask = SND_JACK_HEADPHONE,
|
||||
},
|
||||
};
|
||||
|
||||
/* Headphones jack detection GPIO */
|
||||
static struct snd_soc_jack_gpio hs_jack_gpio = {
|
||||
.name = "earphone-det",
|
||||
.report = SND_JACK_HEADPHONE,
|
||||
.debounce_time = 200,
|
||||
};
|
||||
|
||||
/*
|
||||
* iPAQ hx4700 uses I2S for capture and playback.
|
||||
*/
|
||||
static int hx4700_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
|
||||
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
|
||||
struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
|
||||
int ret = 0;
|
||||
|
||||
/* set the I2S system clock as output */
|
||||
ret = snd_soc_dai_set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, 0,
|
||||
SND_SOC_CLOCK_OUT);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* inform codec driver about clock freq *
|
||||
* (PXA I2S always uses divider 256) */
|
||||
ret = snd_soc_dai_set_sysclk(codec_dai, 0, 256 * params_rate(params),
|
||||
SND_SOC_CLOCK_IN);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_soc_ops hx4700_ops = {
|
||||
.hw_params = hx4700_hw_params,
|
||||
};
|
||||
|
||||
static int hx4700_spk_power(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *k, int event)
|
||||
{
|
||||
gpiod_set_value(gpiod_spk_sd, !SND_SOC_DAPM_EVENT_ON(event));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hx4700_hp_power(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *k, int event)
|
||||
{
|
||||
gpiod_set_value(gpiod_hp_driver, !!SND_SOC_DAPM_EVENT_ON(event));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* hx4700 machine dapm widgets */
|
||||
static const struct snd_soc_dapm_widget hx4700_dapm_widgets[] = {
|
||||
SND_SOC_DAPM_HP("Headphone Jack", hx4700_hp_power),
|
||||
SND_SOC_DAPM_SPK("Speaker", hx4700_spk_power),
|
||||
SND_SOC_DAPM_MIC("Built-in Microphone", NULL),
|
||||
};
|
||||
|
||||
/* hx4700 machine audio_map */
|
||||
static const struct snd_soc_dapm_route hx4700_audio_map[] = {
|
||||
|
||||
/* Headphone connected to LOUT, ROUT */
|
||||
{"Headphone Jack", NULL, "LOUT"},
|
||||
{"Headphone Jack", NULL, "ROUT"},
|
||||
|
||||
/* Speaker connected to MOUT2 */
|
||||
{"Speaker", NULL, "MOUT2"},
|
||||
|
||||
/* Microphone connected to MICIN */
|
||||
{"MICIN", NULL, "Built-in Microphone"},
|
||||
{"AIN", NULL, "MICOUT"},
|
||||
};
|
||||
|
||||
/*
|
||||
* Logic for a ak4641 as connected on a HP iPAQ hx4700
|
||||
*/
|
||||
static int hx4700_ak4641_init(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
int err;
|
||||
|
||||
/* Jack detection API stuff */
|
||||
err = snd_soc_card_jack_new_pins(rtd->card, "Headphone Jack",
|
||||
SND_JACK_HEADPHONE, &hs_jack,
|
||||
hs_jack_pin, ARRAY_SIZE(hs_jack_pin));
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = snd_soc_jack_add_gpios(&hs_jack, 1, &hs_jack_gpio);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* hx4700 digital audio interface glue - connects codec <--> CPU */
|
||||
SND_SOC_DAILINK_DEFS(ak4641,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("pxa2xx-i2s")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("ak4641.0-0012", "ak4641-hifi")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio")));
|
||||
|
||||
static struct snd_soc_dai_link hx4700_dai = {
|
||||
.name = "ak4641",
|
||||
.stream_name = "AK4641",
|
||||
.init = hx4700_ak4641_init,
|
||||
.dai_fmt = SND_SOC_DAIFMT_MSB | SND_SOC_DAIFMT_NB_NF |
|
||||
SND_SOC_DAIFMT_CBS_CFS,
|
||||
.ops = &hx4700_ops,
|
||||
SND_SOC_DAILINK_REG(ak4641),
|
||||
};
|
||||
|
||||
/* hx4700 audio machine driver */
|
||||
static struct snd_soc_card snd_soc_card_hx4700 = {
|
||||
.name = "iPAQ hx4700",
|
||||
.owner = THIS_MODULE,
|
||||
.dai_link = &hx4700_dai,
|
||||
.num_links = 1,
|
||||
.dapm_widgets = hx4700_dapm_widgets,
|
||||
.num_dapm_widgets = ARRAY_SIZE(hx4700_dapm_widgets),
|
||||
.dapm_routes = hx4700_audio_map,
|
||||
.num_dapm_routes = ARRAY_SIZE(hx4700_audio_map),
|
||||
.fully_routed = true,
|
||||
};
|
||||
|
||||
static int hx4700_audio_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!machine_is_h4700())
|
||||
return -ENODEV;
|
||||
|
||||
gpiod_hp_driver = devm_gpiod_get(&pdev->dev, "hp-driver", GPIOD_ASIS);
|
||||
ret = PTR_ERR_OR_ZERO(gpiod_hp_driver);
|
||||
if (ret)
|
||||
return ret;
|
||||
gpiod_spk_sd = devm_gpiod_get(&pdev->dev, "spk-sd", GPIOD_ASIS);
|
||||
ret = PTR_ERR_OR_ZERO(gpiod_spk_sd);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
hs_jack_gpio.gpiod_dev = &pdev->dev;
|
||||
snd_soc_card_hx4700.dev = &pdev->dev;
|
||||
ret = devm_snd_soc_register_card(&pdev->dev, &snd_soc_card_hx4700);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int hx4700_audio_remove(struct platform_device *pdev)
|
||||
{
|
||||
gpiod_set_value(gpiod_hp_driver, 0);
|
||||
gpiod_set_value(gpiod_spk_sd, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver hx4700_audio_driver = {
|
||||
.driver = {
|
||||
.name = "hx4700-audio",
|
||||
.pm = &snd_soc_pm_ops,
|
||||
},
|
||||
.probe = hx4700_audio_probe,
|
||||
.remove = hx4700_audio_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(hx4700_audio_driver);
|
||||
|
||||
MODULE_AUTHOR("Philipp Zabel");
|
||||
MODULE_DESCRIPTION("ALSA SoC iPAQ hx4700");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("platform:hx4700-audio");
|
|
@ -1,366 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* SoC audio for HTC Magician
|
||||
*
|
||||
* Copyright (c) 2006 Philipp Zabel <philipp.zabel@gmail.com>
|
||||
*
|
||||
* based on spitz.c,
|
||||
* Authors: Liam Girdwood <lrg@slimlogic.co.uk>
|
||||
* Richard Purdie <richard@openedhand.com>
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/i2c.h>
|
||||
|
||||
#include <sound/core.h>
|
||||
#include <sound/pcm.h>
|
||||
#include <sound/pcm_params.h>
|
||||
#include <sound/soc.h>
|
||||
|
||||
#include <asm/mach-types.h>
|
||||
#include "../codecs/uda1380.h"
|
||||
#include "pxa2xx-i2s.h"
|
||||
#include "pxa-ssp.h"
|
||||
|
||||
#define MAGICIAN_MIC 0
|
||||
#define MAGICIAN_MIC_EXT 1
|
||||
|
||||
static int magician_hp_switch;
|
||||
static int magician_spk_switch = 1;
|
||||
static int magician_in_sel = MAGICIAN_MIC;
|
||||
|
||||
static struct gpio_desc *gpiod_spk_power, *gpiod_ep_power, *gpiod_mic_power;
|
||||
static struct gpio_desc *gpiod_in_sel0, *gpiod_in_sel1;
|
||||
|
||||
static void magician_ext_control(struct snd_soc_dapm_context *dapm)
|
||||
{
|
||||
|
||||
snd_soc_dapm_mutex_lock(dapm);
|
||||
|
||||
if (magician_spk_switch)
|
||||
snd_soc_dapm_enable_pin_unlocked(dapm, "Speaker");
|
||||
else
|
||||
snd_soc_dapm_disable_pin_unlocked(dapm, "Speaker");
|
||||
if (magician_hp_switch)
|
||||
snd_soc_dapm_enable_pin_unlocked(dapm, "Headphone Jack");
|
||||
else
|
||||
snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack");
|
||||
|
||||
switch (magician_in_sel) {
|
||||
case MAGICIAN_MIC:
|
||||
snd_soc_dapm_disable_pin_unlocked(dapm, "Headset Mic");
|
||||
snd_soc_dapm_enable_pin_unlocked(dapm, "Call Mic");
|
||||
break;
|
||||
case MAGICIAN_MIC_EXT:
|
||||
snd_soc_dapm_disable_pin_unlocked(dapm, "Call Mic");
|
||||
snd_soc_dapm_enable_pin_unlocked(dapm, "Headset Mic");
|
||||
break;
|
||||
}
|
||||
|
||||
snd_soc_dapm_sync_unlocked(dapm);
|
||||
|
||||
snd_soc_dapm_mutex_unlock(dapm);
|
||||
}
|
||||
|
||||
static int magician_startup(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
|
||||
|
||||
/* check the jack status at stream startup */
|
||||
magician_ext_control(&rtd->card->dapm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Magician uses SSP port for playback.
|
||||
*/
|
||||
static int magician_playback_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
|
||||
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
|
||||
struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
|
||||
unsigned int width;
|
||||
int ret = 0;
|
||||
|
||||
/* set codec DAI configuration */
|
||||
ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_MSB |
|
||||
SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_BC_FC);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* set cpu DAI configuration */
|
||||
ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A |
|
||||
SND_SOC_DAIFMT_NB_IF | SND_SOC_DAIFMT_BP_FP);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
width = snd_pcm_format_physical_width(params_format(params));
|
||||
ret = snd_soc_dai_set_tdm_slot(cpu_dai, 1, 0, 1, width);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* set audio clock as clock source */
|
||||
ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_AUDIO, 0,
|
||||
SND_SOC_CLOCK_OUT);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Magician uses I2S for capture.
|
||||
*/
|
||||
static int magician_capture_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
|
||||
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
|
||||
struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
|
||||
int ret = 0;
|
||||
|
||||
/* set codec DAI configuration */
|
||||
ret = snd_soc_dai_set_fmt(codec_dai,
|
||||
SND_SOC_DAIFMT_MSB | SND_SOC_DAIFMT_NB_NF |
|
||||
SND_SOC_DAIFMT_BC_FC);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* set cpu DAI configuration */
|
||||
ret = snd_soc_dai_set_fmt(cpu_dai,
|
||||
SND_SOC_DAIFMT_MSB | SND_SOC_DAIFMT_NB_NF |
|
||||
SND_SOC_DAIFMT_BP_FP);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* set the I2S system clock as output */
|
||||
ret = snd_soc_dai_set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, 0,
|
||||
SND_SOC_CLOCK_OUT);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_soc_ops magician_capture_ops = {
|
||||
.startup = magician_startup,
|
||||
.hw_params = magician_capture_hw_params,
|
||||
};
|
||||
|
||||
static const struct snd_soc_ops magician_playback_ops = {
|
||||
.startup = magician_startup,
|
||||
.hw_params = magician_playback_hw_params,
|
||||
};
|
||||
|
||||
static int magician_get_hp(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
ucontrol->value.integer.value[0] = magician_hp_switch;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int magician_set_hp(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
|
||||
|
||||
if (magician_hp_switch == ucontrol->value.integer.value[0])
|
||||
return 0;
|
||||
|
||||
magician_hp_switch = ucontrol->value.integer.value[0];
|
||||
magician_ext_control(&card->dapm);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int magician_get_spk(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
ucontrol->value.integer.value[0] = magician_spk_switch;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int magician_set_spk(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
|
||||
|
||||
if (magician_spk_switch == ucontrol->value.integer.value[0])
|
||||
return 0;
|
||||
|
||||
magician_spk_switch = ucontrol->value.integer.value[0];
|
||||
magician_ext_control(&card->dapm);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int magician_get_input(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
ucontrol->value.enumerated.item[0] = magician_in_sel;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int magician_set_input(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
if (magician_in_sel == ucontrol->value.enumerated.item[0])
|
||||
return 0;
|
||||
|
||||
magician_in_sel = ucontrol->value.enumerated.item[0];
|
||||
|
||||
switch (magician_in_sel) {
|
||||
case MAGICIAN_MIC:
|
||||
gpiod_set_value(gpiod_in_sel1, 1);
|
||||
break;
|
||||
case MAGICIAN_MIC_EXT:
|
||||
gpiod_set_value(gpiod_in_sel1, 0);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int magician_spk_power(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *k, int event)
|
||||
{
|
||||
gpiod_set_value(gpiod_spk_power, SND_SOC_DAPM_EVENT_ON(event));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int magician_hp_power(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *k, int event)
|
||||
{
|
||||
gpiod_set_value(gpiod_ep_power, SND_SOC_DAPM_EVENT_ON(event));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int magician_mic_bias(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *k, int event)
|
||||
{
|
||||
gpiod_set_value(gpiod_mic_power, SND_SOC_DAPM_EVENT_ON(event));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* magician machine dapm widgets */
|
||||
static const struct snd_soc_dapm_widget uda1380_dapm_widgets[] = {
|
||||
SND_SOC_DAPM_HP("Headphone Jack", magician_hp_power),
|
||||
SND_SOC_DAPM_SPK("Speaker", magician_spk_power),
|
||||
SND_SOC_DAPM_MIC("Call Mic", magician_mic_bias),
|
||||
SND_SOC_DAPM_MIC("Headset Mic", magician_mic_bias),
|
||||
};
|
||||
|
||||
/* magician machine audio_map */
|
||||
static const struct snd_soc_dapm_route audio_map[] = {
|
||||
|
||||
/* Headphone connected to VOUTL, VOUTR */
|
||||
{"Headphone Jack", NULL, "VOUTL"},
|
||||
{"Headphone Jack", NULL, "VOUTR"},
|
||||
|
||||
/* Speaker connected to VOUTL, VOUTR */
|
||||
{"Speaker", NULL, "VOUTL"},
|
||||
{"Speaker", NULL, "VOUTR"},
|
||||
|
||||
/* Mics are connected to VINM */
|
||||
{"VINM", NULL, "Headset Mic"},
|
||||
{"VINM", NULL, "Call Mic"},
|
||||
};
|
||||
|
||||
static const char * const input_select[] = {"Call Mic", "Headset Mic"};
|
||||
static const struct soc_enum magician_in_sel_enum =
|
||||
SOC_ENUM_SINGLE_EXT(2, input_select);
|
||||
|
||||
static const struct snd_kcontrol_new uda1380_magician_controls[] = {
|
||||
SOC_SINGLE_BOOL_EXT("Headphone Switch",
|
||||
(unsigned long)&magician_hp_switch,
|
||||
magician_get_hp, magician_set_hp),
|
||||
SOC_SINGLE_BOOL_EXT("Speaker Switch",
|
||||
(unsigned long)&magician_spk_switch,
|
||||
magician_get_spk, magician_set_spk),
|
||||
SOC_ENUM_EXT("Input Select", magician_in_sel_enum,
|
||||
magician_get_input, magician_set_input),
|
||||
};
|
||||
|
||||
/* magician digital audio interface glue - connects codec <--> CPU */
|
||||
SND_SOC_DAILINK_DEFS(playback,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("pxa-ssp-dai.0")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("uda1380-codec.0-0018",
|
||||
"uda1380-hifi-playback")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio")));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(capture,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("pxa2xx-i2s")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("uda1380-codec.0-0018",
|
||||
"uda1380-hifi-capture")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio")));
|
||||
|
||||
static struct snd_soc_dai_link magician_dai[] = {
|
||||
{
|
||||
.name = "uda1380",
|
||||
.stream_name = "UDA1380 Playback",
|
||||
.ops = &magician_playback_ops,
|
||||
SND_SOC_DAILINK_REG(playback),
|
||||
},
|
||||
{
|
||||
.name = "uda1380",
|
||||
.stream_name = "UDA1380 Capture",
|
||||
.ops = &magician_capture_ops,
|
||||
SND_SOC_DAILINK_REG(capture),
|
||||
}
|
||||
};
|
||||
|
||||
/* magician audio machine driver */
|
||||
static struct snd_soc_card snd_soc_card_magician = {
|
||||
.name = "Magician",
|
||||
.owner = THIS_MODULE,
|
||||
.dai_link = magician_dai,
|
||||
.num_links = ARRAY_SIZE(magician_dai),
|
||||
|
||||
.controls = uda1380_magician_controls,
|
||||
.num_controls = ARRAY_SIZE(uda1380_magician_controls),
|
||||
.dapm_widgets = uda1380_dapm_widgets,
|
||||
.num_dapm_widgets = ARRAY_SIZE(uda1380_dapm_widgets),
|
||||
.dapm_routes = audio_map,
|
||||
.num_dapm_routes = ARRAY_SIZE(audio_map),
|
||||
.fully_routed = true,
|
||||
};
|
||||
|
||||
static int magician_audio_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
|
||||
gpiod_spk_power = devm_gpiod_get(dev, "SPK_POWER", GPIOD_OUT_LOW);
|
||||
if (IS_ERR(gpiod_spk_power))
|
||||
return PTR_ERR(gpiod_spk_power);
|
||||
gpiod_ep_power = devm_gpiod_get(dev, "EP_POWER", GPIOD_OUT_LOW);
|
||||
if (IS_ERR(gpiod_ep_power))
|
||||
return PTR_ERR(gpiod_ep_power);
|
||||
gpiod_mic_power = devm_gpiod_get(dev, "MIC_POWER", GPIOD_OUT_LOW);
|
||||
if (IS_ERR(gpiod_mic_power))
|
||||
return PTR_ERR(gpiod_mic_power);
|
||||
gpiod_in_sel0 = devm_gpiod_get(dev, "IN_SEL0", GPIOD_OUT_HIGH);
|
||||
if (IS_ERR(gpiod_in_sel0))
|
||||
return PTR_ERR(gpiod_in_sel0);
|
||||
gpiod_in_sel1 = devm_gpiod_get(dev, "IN_SEL1", GPIOD_OUT_LOW);
|
||||
if (IS_ERR(gpiod_in_sel1))
|
||||
return PTR_ERR(gpiod_in_sel1);
|
||||
|
||||
snd_soc_card_magician.dev = &pdev->dev;
|
||||
return devm_snd_soc_register_card(&pdev->dev, &snd_soc_card_magician);
|
||||
}
|
||||
|
||||
static struct platform_driver magician_audio_driver = {
|
||||
.driver.name = "magician-audio",
|
||||
.driver.pm = &snd_soc_pm_ops,
|
||||
.probe = magician_audio_probe,
|
||||
};
|
||||
module_platform_driver(magician_audio_driver);
|
||||
|
||||
MODULE_AUTHOR("Philipp Zabel");
|
||||
MODULE_DESCRIPTION("ALSA SoC Magician");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("platform:magician-audio");
|
|
@ -1,201 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Handles the Mitac mioa701 SoC system
|
||||
*
|
||||
* Copyright (C) 2008 Robert Jarzmik
|
||||
*
|
||||
* This is a little schema of the sound interconnections :
|
||||
*
|
||||
* Sagem X200 Wolfson WM9713
|
||||
* +--------+ +-------------------+ Rear Speaker
|
||||
* | | | | /-+
|
||||
* | +--->----->---+MONOIN SPKL+--->----+-+ |
|
||||
* | GSM | | | | | |
|
||||
* | +--->----->---+PCBEEP SPKR+--->----+-+ |
|
||||
* | CHIP | | | \-+
|
||||
* | +---<-----<---+MONO |
|
||||
* | | | | Front Speaker
|
||||
* +--------+ | | /-+
|
||||
* | HPL+--->----+-+ |
|
||||
* | | | | |
|
||||
* | OUT3+--->----+-+ |
|
||||
* | | \-+
|
||||
* | |
|
||||
* | | Front Micro
|
||||
* | | +
|
||||
* | MIC1+-----<--+o+
|
||||
* | | +
|
||||
* +-------------------+ ---
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include <asm/mach-types.h>
|
||||
#include <linux/platform_data/asoc-pxa.h>
|
||||
|
||||
#include <sound/core.h>
|
||||
#include <sound/pcm.h>
|
||||
#include <sound/soc.h>
|
||||
#include <sound/initval.h>
|
||||
#include <sound/ac97_codec.h>
|
||||
|
||||
#include "../codecs/wm9713.h"
|
||||
|
||||
#define AC97_GPIO_PULL 0x58
|
||||
|
||||
/* Use GPIO8 for rear speaker amplifier */
|
||||
static int rear_amp_power(struct snd_soc_component *component, int power)
|
||||
{
|
||||
unsigned short reg;
|
||||
|
||||
if (power) {
|
||||
reg = snd_soc_component_read(component, AC97_GPIO_CFG);
|
||||
snd_soc_component_write(component, AC97_GPIO_CFG, reg | 0x0100);
|
||||
reg = snd_soc_component_read(component, AC97_GPIO_PULL);
|
||||
snd_soc_component_write(component, AC97_GPIO_PULL, reg | (1<<15));
|
||||
} else {
|
||||
reg = snd_soc_component_read(component, AC97_GPIO_CFG);
|
||||
snd_soc_component_write(component, AC97_GPIO_CFG, reg & ~0x0100);
|
||||
reg = snd_soc_component_read(component, AC97_GPIO_PULL);
|
||||
snd_soc_component_write(component, AC97_GPIO_PULL, reg & ~(1<<15));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rear_amp_event(struct snd_soc_dapm_widget *widget,
|
||||
struct snd_kcontrol *kctl, int event)
|
||||
{
|
||||
struct snd_soc_card *card = widget->dapm->card;
|
||||
struct snd_soc_pcm_runtime *rtd;
|
||||
struct snd_soc_component *component;
|
||||
|
||||
rtd = snd_soc_get_pcm_runtime(card, &card->dai_link[0]);
|
||||
component = asoc_rtd_to_codec(rtd, 0)->component;
|
||||
return rear_amp_power(component, SND_SOC_DAPM_EVENT_ON(event));
|
||||
}
|
||||
|
||||
/* mioa701 machine dapm widgets */
|
||||
static const struct snd_soc_dapm_widget mioa701_dapm_widgets[] = {
|
||||
SND_SOC_DAPM_SPK("Front Speaker", NULL),
|
||||
SND_SOC_DAPM_SPK("Rear Speaker", rear_amp_event),
|
||||
SND_SOC_DAPM_MIC("Headset", NULL),
|
||||
SND_SOC_DAPM_LINE("GSM Line Out", NULL),
|
||||
SND_SOC_DAPM_LINE("GSM Line In", NULL),
|
||||
SND_SOC_DAPM_MIC("Headset Mic", NULL),
|
||||
SND_SOC_DAPM_MIC("Front Mic", NULL),
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_route audio_map[] = {
|
||||
/* Call Mic */
|
||||
{"Mic Bias", NULL, "Front Mic"},
|
||||
{"MIC1", NULL, "Mic Bias"},
|
||||
|
||||
/* Headset Mic */
|
||||
{"LINEL", NULL, "Headset Mic"},
|
||||
{"LINER", NULL, "Headset Mic"},
|
||||
|
||||
/* GSM Module */
|
||||
{"MONOIN", NULL, "GSM Line Out"},
|
||||
{"PCBEEP", NULL, "GSM Line Out"},
|
||||
{"GSM Line In", NULL, "MONO"},
|
||||
|
||||
/* headphone connected to HPL, HPR */
|
||||
{"Headset", NULL, "HPL"},
|
||||
{"Headset", NULL, "HPR"},
|
||||
|
||||
/* front speaker connected to HPL, OUT3 */
|
||||
{"Front Speaker", NULL, "HPL"},
|
||||
{"Front Speaker", NULL, "OUT3"},
|
||||
|
||||
/* rear speaker connected to SPKL, SPKR */
|
||||
{"Rear Speaker", NULL, "SPKL"},
|
||||
{"Rear Speaker", NULL, "SPKR"},
|
||||
};
|
||||
|
||||
static int mioa701_wm9713_init(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
|
||||
|
||||
/* Prepare GPIO8 for rear speaker amplifier */
|
||||
snd_soc_component_update_bits(component, AC97_GPIO_CFG, 0x100, 0x100);
|
||||
|
||||
/* Prepare MIC input */
|
||||
snd_soc_component_update_bits(component, AC97_3D_CONTROL, 0xc000, 0xc000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct snd_soc_ops mioa701_ops;
|
||||
|
||||
SND_SOC_DAILINK_DEFS(ac97,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("pxa2xx-ac97")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("wm9713-codec", "wm9713-hifi")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio")));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(ac97_aux,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("pxa2xx-ac97-aux")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("wm9713-codec", "wm9713-aux")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio")));
|
||||
|
||||
static struct snd_soc_dai_link mioa701_dai[] = {
|
||||
{
|
||||
.name = "AC97",
|
||||
.stream_name = "AC97 HiFi",
|
||||
.init = mioa701_wm9713_init,
|
||||
.ops = &mioa701_ops,
|
||||
SND_SOC_DAILINK_REG(ac97),
|
||||
},
|
||||
{
|
||||
.name = "AC97 Aux",
|
||||
.stream_name = "AC97 Aux",
|
||||
.ops = &mioa701_ops,
|
||||
SND_SOC_DAILINK_REG(ac97_aux),
|
||||
},
|
||||
};
|
||||
|
||||
static struct snd_soc_card mioa701 = {
|
||||
.name = "MioA701",
|
||||
.owner = THIS_MODULE,
|
||||
.dai_link = mioa701_dai,
|
||||
.num_links = ARRAY_SIZE(mioa701_dai),
|
||||
|
||||
.dapm_widgets = mioa701_dapm_widgets,
|
||||
.num_dapm_widgets = ARRAY_SIZE(mioa701_dapm_widgets),
|
||||
.dapm_routes = audio_map,
|
||||
.num_dapm_routes = ARRAY_SIZE(audio_map),
|
||||
};
|
||||
|
||||
static int mioa701_wm9713_probe(struct platform_device *pdev)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (!machine_is_mioa701())
|
||||
return -ENODEV;
|
||||
|
||||
mioa701.dev = &pdev->dev;
|
||||
rc = devm_snd_soc_register_card(&pdev->dev, &mioa701);
|
||||
if (!rc)
|
||||
dev_warn(&pdev->dev, "Be warned that incorrect mixers/muxes setup will "
|
||||
"lead to overheating and possible destruction of your device."
|
||||
" Do not use without a good knowledge of mio's board design!\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
static struct platform_driver mioa701_wm9713_driver = {
|
||||
.probe = mioa701_wm9713_probe,
|
||||
.driver = {
|
||||
.name = "mioa701-wm9713",
|
||||
.pm = &snd_soc_pm_ops,
|
||||
},
|
||||
};
|
||||
|
||||
module_platform_driver(mioa701_wm9713_driver);
|
||||
|
||||
/* Module information */
|
||||
MODULE_AUTHOR("Robert Jarzmik (rjarzmik@free.fr)");
|
||||
MODULE_DESCRIPTION("ALSA SoC WM9713 MIO A701");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("platform:mioa701-wm9713");
|
|
@ -1,267 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* linux/sound/soc/pxa/mmp-pcm.c
|
||||
*
|
||||
* Copyright (C) 2011 Marvell International Ltd.
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/dmaengine.h>
|
||||
#include <linux/platform_data/dma-mmp_tdma.h>
|
||||
#include <linux/platform_data/mmp_audio.h>
|
||||
|
||||
#include <sound/pxa2xx-lib.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/pcm.h>
|
||||
#include <sound/pcm_params.h>
|
||||
#include <sound/soc.h>
|
||||
#include <sound/dmaengine_pcm.h>
|
||||
|
||||
#define DRV_NAME "mmp-pcm"
|
||||
|
||||
struct mmp_dma_data {
|
||||
int ssp_id;
|
||||
struct resource *dma_res;
|
||||
};
|
||||
|
||||
#define MMP_PCM_INFO (SNDRV_PCM_INFO_MMAP | \
|
||||
SNDRV_PCM_INFO_MMAP_VALID | \
|
||||
SNDRV_PCM_INFO_INTERLEAVED | \
|
||||
SNDRV_PCM_INFO_PAUSE | \
|
||||
SNDRV_PCM_INFO_RESUME | \
|
||||
SNDRV_PCM_INFO_NO_PERIOD_WAKEUP)
|
||||
|
||||
static struct snd_pcm_hardware mmp_pcm_hardware[] = {
|
||||
{
|
||||
.info = MMP_PCM_INFO,
|
||||
.period_bytes_min = 1024,
|
||||
.period_bytes_max = 2048,
|
||||
.periods_min = 2,
|
||||
.periods_max = 32,
|
||||
.buffer_bytes_max = 4096,
|
||||
.fifo_size = 32,
|
||||
},
|
||||
{
|
||||
.info = MMP_PCM_INFO,
|
||||
.period_bytes_min = 1024,
|
||||
.period_bytes_max = 2048,
|
||||
.periods_min = 2,
|
||||
.periods_max = 32,
|
||||
.buffer_bytes_max = 4096,
|
||||
.fifo_size = 32,
|
||||
},
|
||||
};
|
||||
|
||||
static int mmp_pcm_hw_params(struct snd_soc_component *component,
|
||||
struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params)
|
||||
{
|
||||
struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream);
|
||||
struct dma_slave_config slave_config;
|
||||
int ret;
|
||||
|
||||
ret =
|
||||
snd_dmaengine_pcm_prepare_slave_config(substream, params,
|
||||
&slave_config);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = dmaengine_slave_config(chan, &slave_config);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mmp_pcm_trigger(struct snd_soc_component *component,
|
||||
struct snd_pcm_substream *substream, int cmd)
|
||||
{
|
||||
return snd_dmaengine_pcm_trigger(substream, cmd);
|
||||
}
|
||||
|
||||
static snd_pcm_uframes_t mmp_pcm_pointer(struct snd_soc_component *component,
|
||||
struct snd_pcm_substream *substream)
|
||||
{
|
||||
return snd_dmaengine_pcm_pointer(substream);
|
||||
}
|
||||
|
||||
static bool filter(struct dma_chan *chan, void *param)
|
||||
{
|
||||
struct mmp_dma_data *dma_data = param;
|
||||
bool found = false;
|
||||
char *devname;
|
||||
|
||||
devname = kasprintf(GFP_KERNEL, "%s.%d", dma_data->dma_res->name,
|
||||
dma_data->ssp_id);
|
||||
if (devname && (strcmp(dev_name(chan->device->dev), devname) == 0) &&
|
||||
(chan->chan_id == dma_data->dma_res->start)) {
|
||||
found = true;
|
||||
}
|
||||
|
||||
kfree(devname);
|
||||
return found;
|
||||
}
|
||||
|
||||
static int mmp_pcm_open(struct snd_soc_component *component,
|
||||
struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
|
||||
struct platform_device *pdev = to_platform_device(component->dev);
|
||||
struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
|
||||
struct mmp_dma_data dma_data;
|
||||
struct resource *r;
|
||||
|
||||
r = platform_get_resource(pdev, IORESOURCE_DMA, substream->stream);
|
||||
if (!r)
|
||||
return -EBUSY;
|
||||
|
||||
snd_soc_set_runtime_hwparams(substream,
|
||||
&mmp_pcm_hardware[substream->stream]);
|
||||
|
||||
dma_data.dma_res = r;
|
||||
dma_data.ssp_id = cpu_dai->id;
|
||||
|
||||
return snd_dmaengine_pcm_open_request_chan(substream, filter,
|
||||
&dma_data);
|
||||
}
|
||||
|
||||
static int mmp_pcm_close(struct snd_soc_component *component,
|
||||
struct snd_pcm_substream *substream)
|
||||
{
|
||||
return snd_dmaengine_pcm_close_release_chan(substream);
|
||||
}
|
||||
|
||||
static int mmp_pcm_mmap(struct snd_soc_component *component,
|
||||
struct snd_pcm_substream *substream,
|
||||
struct vm_area_struct *vma)
|
||||
{
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
unsigned long off = vma->vm_pgoff;
|
||||
|
||||
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
|
||||
return remap_pfn_range(vma, vma->vm_start,
|
||||
__phys_to_pfn(runtime->dma_addr) + off,
|
||||
vma->vm_end - vma->vm_start, vma->vm_page_prot);
|
||||
}
|
||||
|
||||
static void mmp_pcm_free_dma_buffers(struct snd_soc_component *component,
|
||||
struct snd_pcm *pcm)
|
||||
{
|
||||
struct snd_pcm_substream *substream;
|
||||
struct snd_dma_buffer *buf;
|
||||
int stream;
|
||||
struct gen_pool *gpool;
|
||||
|
||||
gpool = sram_get_gpool("asram");
|
||||
if (!gpool)
|
||||
return;
|
||||
|
||||
for (stream = 0; stream < 2; stream++) {
|
||||
size_t size = mmp_pcm_hardware[stream].buffer_bytes_max;
|
||||
|
||||
substream = pcm->streams[stream].substream;
|
||||
if (!substream)
|
||||
continue;
|
||||
|
||||
buf = &substream->dma_buffer;
|
||||
if (!buf->area)
|
||||
continue;
|
||||
gen_pool_free(gpool, (unsigned long)buf->area, size);
|
||||
buf->area = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static int mmp_pcm_preallocate_dma_buffer(struct snd_pcm_substream *substream,
|
||||
int stream)
|
||||
{
|
||||
struct snd_dma_buffer *buf = &substream->dma_buffer;
|
||||
size_t size = mmp_pcm_hardware[stream].buffer_bytes_max;
|
||||
struct gen_pool *gpool;
|
||||
|
||||
buf->dev.type = SNDRV_DMA_TYPE_DEV;
|
||||
buf->dev.dev = substream->pcm->card->dev;
|
||||
buf->private_data = NULL;
|
||||
|
||||
gpool = sram_get_gpool("asram");
|
||||
if (!gpool)
|
||||
return -ENOMEM;
|
||||
|
||||
buf->area = gen_pool_dma_alloc(gpool, size, &buf->addr);
|
||||
if (!buf->area)
|
||||
return -ENOMEM;
|
||||
buf->bytes = size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mmp_pcm_new(struct snd_soc_component *component,
|
||||
struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
struct snd_pcm_substream *substream;
|
||||
struct snd_pcm *pcm = rtd->pcm;
|
||||
int ret, stream;
|
||||
|
||||
for (stream = 0; stream < 2; stream++) {
|
||||
substream = pcm->streams[stream].substream;
|
||||
|
||||
ret = mmp_pcm_preallocate_dma_buffer(substream, stream);
|
||||
if (ret)
|
||||
goto err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
mmp_pcm_free_dma_buffers(component, pcm);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct snd_soc_component_driver mmp_soc_component = {
|
||||
.name = DRV_NAME,
|
||||
.open = mmp_pcm_open,
|
||||
.close = mmp_pcm_close,
|
||||
.hw_params = mmp_pcm_hw_params,
|
||||
.trigger = mmp_pcm_trigger,
|
||||
.pointer = mmp_pcm_pointer,
|
||||
.mmap = mmp_pcm_mmap,
|
||||
.pcm_construct = mmp_pcm_new,
|
||||
.pcm_destruct = mmp_pcm_free_dma_buffers,
|
||||
};
|
||||
|
||||
static int mmp_pcm_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct mmp_audio_platdata *pdata = pdev->dev.platform_data;
|
||||
|
||||
if (pdata) {
|
||||
mmp_pcm_hardware[SNDRV_PCM_STREAM_PLAYBACK].buffer_bytes_max =
|
||||
pdata->buffer_max_playback;
|
||||
mmp_pcm_hardware[SNDRV_PCM_STREAM_PLAYBACK].period_bytes_max =
|
||||
pdata->period_max_playback;
|
||||
mmp_pcm_hardware[SNDRV_PCM_STREAM_CAPTURE].buffer_bytes_max =
|
||||
pdata->buffer_max_capture;
|
||||
mmp_pcm_hardware[SNDRV_PCM_STREAM_CAPTURE].period_bytes_max =
|
||||
pdata->period_max_capture;
|
||||
}
|
||||
return devm_snd_soc_register_component(&pdev->dev, &mmp_soc_component,
|
||||
NULL, 0);
|
||||
}
|
||||
|
||||
static struct platform_driver mmp_pcm_driver = {
|
||||
.driver = {
|
||||
.name = "mmp-pcm-audio",
|
||||
},
|
||||
|
||||
.probe = mmp_pcm_probe,
|
||||
};
|
||||
|
||||
module_platform_driver(mmp_pcm_driver);
|
||||
|
||||
MODULE_AUTHOR("Leo Yan <leoy@marvell.com>");
|
||||
MODULE_DESCRIPTION("MMP Soc Audio DMA module");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("platform:mmp-pcm-audio");
|
|
@ -1,162 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* linux/sound/soc/pxa/palm27x.c
|
||||
*
|
||||
* SoC Audio driver for Palm T|X, T5 and LifeDrive
|
||||
*
|
||||
* based on tosa.c
|
||||
*
|
||||
* Copyright (C) 2008 Marek Vasut <marek.vasut@gmail.com>
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/gpio.h>
|
||||
|
||||
#include <sound/core.h>
|
||||
#include <sound/pcm.h>
|
||||
#include <sound/soc.h>
|
||||
#include <sound/jack.h>
|
||||
|
||||
#include <asm/mach-types.h>
|
||||
#include <linux/platform_data/asoc-pxa.h>
|
||||
#include <linux/platform_data/asoc-palm27x.h>
|
||||
|
||||
static struct snd_soc_jack hs_jack;
|
||||
|
||||
/* Headphones jack detection DAPM pins */
|
||||
static struct snd_soc_jack_pin hs_jack_pins[] = {
|
||||
{
|
||||
.pin = "Headphone Jack",
|
||||
.mask = SND_JACK_HEADPHONE,
|
||||
},
|
||||
};
|
||||
|
||||
/* 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,
|
||||
},
|
||||
};
|
||||
|
||||
/* 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("Ext. Speaker", NULL),
|
||||
SND_SOC_DAPM_MIC("Ext. Microphone", NULL),
|
||||
};
|
||||
|
||||
/* PalmTX audio map */
|
||||
static const struct snd_soc_dapm_route audio_map[] = {
|
||||
/* headphone connected to HPOUTL, HPOUTR */
|
||||
{"Headphone Jack", NULL, "HPOUTL"},
|
||||
{"Headphone Jack", NULL, "HPOUTR"},
|
||||
|
||||
/* ext speaker connected to ROUT2, LOUT2 */
|
||||
{"Ext. Speaker", NULL, "LOUT2"},
|
||||
{"Ext. Speaker", NULL, "ROUT2"},
|
||||
|
||||
/* mic connected to MIC1 */
|
||||
{"MIC1", NULL, "Ext. Microphone"},
|
||||
};
|
||||
|
||||
static struct snd_soc_card palm27x_asoc;
|
||||
|
||||
static int palm27x_ac97_init(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
int err;
|
||||
|
||||
/* Jack detection API stuff */
|
||||
err = snd_soc_card_jack_new_pins(rtd->card, "Headphone Jack",
|
||||
SND_JACK_HEADPHONE, &hs_jack,
|
||||
hs_jack_pins,
|
||||
ARRAY_SIZE(hs_jack_pins));
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = snd_soc_jack_add_gpios(&hs_jack, ARRAY_SIZE(hs_jack_gpios),
|
||||
hs_jack_gpios);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
SND_SOC_DAILINK_DEFS(hifi,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("pxa2xx-ac97")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("wm9712-codec", "wm9712-hifi")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio")));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(aux,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("pxa2xx-ac97-aux")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("wm9712-codec", "wm9712-aux")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio")));
|
||||
|
||||
static struct snd_soc_dai_link palm27x_dai[] = {
|
||||
{
|
||||
.name = "AC97 HiFi",
|
||||
.stream_name = "AC97 HiFi",
|
||||
.init = palm27x_ac97_init,
|
||||
SND_SOC_DAILINK_REG(hifi),
|
||||
},
|
||||
{
|
||||
.name = "AC97 Aux",
|
||||
.stream_name = "AC97 Aux",
|
||||
SND_SOC_DAILINK_REG(aux),
|
||||
},
|
||||
};
|
||||
|
||||
static struct snd_soc_card palm27x_asoc = {
|
||||
.name = "Palm/PXA27x",
|
||||
.owner = THIS_MODULE,
|
||||
.dai_link = palm27x_dai,
|
||||
.num_links = ARRAY_SIZE(palm27x_dai),
|
||||
.dapm_widgets = palm27x_dapm_widgets,
|
||||
.num_dapm_widgets = ARRAY_SIZE(palm27x_dapm_widgets),
|
||||
.dapm_routes = audio_map,
|
||||
.num_dapm_routes = ARRAY_SIZE(audio_map),
|
||||
.fully_routed = true,
|
||||
};
|
||||
|
||||
static int palm27x_asoc_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!(machine_is_palmtx() || machine_is_palmt5() ||
|
||||
machine_is_palmld() || machine_is_palmte2()))
|
||||
return -ENODEV;
|
||||
|
||||
if (!pdev->dev.platform_data) {
|
||||
dev_err(&pdev->dev, "please supply platform_data\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
hs_jack_gpios[0].gpio = ((struct palm27x_asoc_info *)
|
||||
(pdev->dev.platform_data))->jack_gpio;
|
||||
|
||||
palm27x_asoc.dev = &pdev->dev;
|
||||
|
||||
ret = devm_snd_soc_register_card(&pdev->dev, &palm27x_asoc);
|
||||
if (ret)
|
||||
dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct platform_driver palm27x_wm9712_driver = {
|
||||
.probe = palm27x_asoc_probe,
|
||||
.driver = {
|
||||
.name = "palm27x-asoc",
|
||||
.pm = &snd_soc_pm_ops,
|
||||
},
|
||||
};
|
||||
|
||||
module_platform_driver(palm27x_wm9712_driver);
|
||||
|
||||
/* Module information */
|
||||
MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
|
||||
MODULE_DESCRIPTION("ALSA SoC Palm T|X, T5 and LifeDrive");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("platform:palm27x-asoc");
|
|
@ -1,291 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* poodle.c -- SoC audio for Poodle
|
||||
*
|
||||
* Copyright 2005 Wolfson Microelectronics PLC.
|
||||
* Copyright 2005 Openedhand Ltd.
|
||||
*
|
||||
* Authors: Liam Girdwood <lrg@slimlogic.co.uk>
|
||||
* Richard Purdie <richard@openedhand.com>
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/pcm.h>
|
||||
#include <sound/soc.h>
|
||||
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/hardware/locomo.h>
|
||||
#include <linux/platform_data/asoc-pxa.h>
|
||||
#include <linux/platform_data/asoc-poodle.h>
|
||||
|
||||
#include "../codecs/wm8731.h"
|
||||
#include "pxa2xx-i2s.h"
|
||||
|
||||
#define POODLE_HP 1
|
||||
#define POODLE_HP_OFF 0
|
||||
#define POODLE_SPK_ON 1
|
||||
#define POODLE_SPK_OFF 0
|
||||
|
||||
/* audio clock in Hz - rounded from 12.235MHz */
|
||||
#define POODLE_AUDIO_CLOCK 12288000
|
||||
|
||||
static int poodle_jack_func;
|
||||
static int poodle_spk_func;
|
||||
|
||||
static struct poodle_audio_platform_data *poodle_pdata;
|
||||
|
||||
static void poodle_ext_control(struct snd_soc_dapm_context *dapm)
|
||||
{
|
||||
/* set up jack connection */
|
||||
if (poodle_jack_func == POODLE_HP) {
|
||||
/* set = unmute headphone */
|
||||
locomo_gpio_write(poodle_pdata->locomo_dev,
|
||||
poodle_pdata->gpio_mute_l, 1);
|
||||
locomo_gpio_write(poodle_pdata->locomo_dev,
|
||||
poodle_pdata->gpio_mute_r, 1);
|
||||
snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
|
||||
} else {
|
||||
locomo_gpio_write(poodle_pdata->locomo_dev,
|
||||
poodle_pdata->gpio_mute_l, 0);
|
||||
locomo_gpio_write(poodle_pdata->locomo_dev,
|
||||
poodle_pdata->gpio_mute_r, 0);
|
||||
snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
|
||||
}
|
||||
|
||||
/* set the endpoints to their new connection states */
|
||||
if (poodle_spk_func == POODLE_SPK_ON)
|
||||
snd_soc_dapm_enable_pin(dapm, "Ext Spk");
|
||||
else
|
||||
snd_soc_dapm_disable_pin(dapm, "Ext Spk");
|
||||
|
||||
/* signal a DAPM event */
|
||||
snd_soc_dapm_sync(dapm);
|
||||
}
|
||||
|
||||
static int poodle_startup(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
|
||||
|
||||
/* check the jack status at stream startup */
|
||||
poodle_ext_control(&rtd->card->dapm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* we need to unmute the HP at shutdown as the mute burns power on poodle */
|
||||
static void poodle_shutdown(struct snd_pcm_substream *substream)
|
||||
{
|
||||
/* set = unmute headphone */
|
||||
locomo_gpio_write(poodle_pdata->locomo_dev,
|
||||
poodle_pdata->gpio_mute_l, 1);
|
||||
locomo_gpio_write(poodle_pdata->locomo_dev,
|
||||
poodle_pdata->gpio_mute_r, 1);
|
||||
}
|
||||
|
||||
static int poodle_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
|
||||
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
|
||||
struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
|
||||
unsigned int clk = 0;
|
||||
int ret = 0;
|
||||
|
||||
switch (params_rate(params)) {
|
||||
case 8000:
|
||||
case 16000:
|
||||
case 48000:
|
||||
case 96000:
|
||||
clk = 12288000;
|
||||
break;
|
||||
case 11025:
|
||||
case 22050:
|
||||
case 44100:
|
||||
clk = 11289600;
|
||||
break;
|
||||
}
|
||||
|
||||
/* set the codec system clock for DAC and ADC */
|
||||
ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK_XTAL, clk,
|
||||
SND_SOC_CLOCK_IN);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* set the I2S system clock as input (unused) */
|
||||
ret = snd_soc_dai_set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, 0,
|
||||
SND_SOC_CLOCK_IN);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_soc_ops poodle_ops = {
|
||||
.startup = poodle_startup,
|
||||
.hw_params = poodle_hw_params,
|
||||
.shutdown = poodle_shutdown,
|
||||
};
|
||||
|
||||
static int poodle_get_jack(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
ucontrol->value.enumerated.item[0] = poodle_jack_func;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int poodle_set_jack(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
|
||||
|
||||
if (poodle_jack_func == ucontrol->value.enumerated.item[0])
|
||||
return 0;
|
||||
|
||||
poodle_jack_func = ucontrol->value.enumerated.item[0];
|
||||
poodle_ext_control(&card->dapm);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int poodle_get_spk(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
ucontrol->value.enumerated.item[0] = poodle_spk_func;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int poodle_set_spk(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
|
||||
|
||||
if (poodle_spk_func == ucontrol->value.enumerated.item[0])
|
||||
return 0;
|
||||
|
||||
poodle_spk_func = ucontrol->value.enumerated.item[0];
|
||||
poodle_ext_control(&card->dapm);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int poodle_amp_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *k, int event)
|
||||
{
|
||||
if (SND_SOC_DAPM_EVENT_ON(event))
|
||||
locomo_gpio_write(poodle_pdata->locomo_dev,
|
||||
poodle_pdata->gpio_amp_on, 0);
|
||||
else
|
||||
locomo_gpio_write(poodle_pdata->locomo_dev,
|
||||
poodle_pdata->gpio_amp_on, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* poodle machine dapm widgets */
|
||||
static const struct snd_soc_dapm_widget wm8731_dapm_widgets[] = {
|
||||
SND_SOC_DAPM_HP("Headphone Jack", NULL),
|
||||
SND_SOC_DAPM_SPK("Ext Spk", poodle_amp_event),
|
||||
SND_SOC_DAPM_MIC("Microphone", NULL),
|
||||
};
|
||||
|
||||
/* Corgi machine connections to the codec pins */
|
||||
static const struct snd_soc_dapm_route poodle_audio_map[] = {
|
||||
|
||||
/* headphone connected to LHPOUT1, RHPOUT1 */
|
||||
{"Headphone Jack", NULL, "LHPOUT"},
|
||||
{"Headphone Jack", NULL, "RHPOUT"},
|
||||
|
||||
/* speaker connected to LOUT, ROUT */
|
||||
{"Ext Spk", NULL, "ROUT"},
|
||||
{"Ext Spk", NULL, "LOUT"},
|
||||
|
||||
{"MICIN", NULL, "Microphone"},
|
||||
};
|
||||
|
||||
static const char * const jack_function[] = {"Off", "Headphone"};
|
||||
static const char * const spk_function[] = {"Off", "On"};
|
||||
static const struct soc_enum poodle_enum[] = {
|
||||
SOC_ENUM_SINGLE_EXT(2, jack_function),
|
||||
SOC_ENUM_SINGLE_EXT(2, spk_function),
|
||||
};
|
||||
|
||||
static const struct snd_kcontrol_new wm8731_poodle_controls[] = {
|
||||
SOC_ENUM_EXT("Jack Function", poodle_enum[0], poodle_get_jack,
|
||||
poodle_set_jack),
|
||||
SOC_ENUM_EXT("Speaker Function", poodle_enum[1], poodle_get_spk,
|
||||
poodle_set_spk),
|
||||
};
|
||||
|
||||
/* poodle digital audio interface glue - connects codec <--> CPU */
|
||||
SND_SOC_DAILINK_DEFS(wm8731,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("pxa2xx-i2s")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("wm8731.0-001b", "wm8731-hifi")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio")));
|
||||
|
||||
static struct snd_soc_dai_link poodle_dai = {
|
||||
.name = "WM8731",
|
||||
.stream_name = "WM8731",
|
||||
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
|
||||
SND_SOC_DAIFMT_CBS_CFS,
|
||||
.ops = &poodle_ops,
|
||||
SND_SOC_DAILINK_REG(wm8731),
|
||||
};
|
||||
|
||||
/* poodle audio machine driver */
|
||||
static struct snd_soc_card poodle = {
|
||||
.name = "Poodle",
|
||||
.dai_link = &poodle_dai,
|
||||
.num_links = 1,
|
||||
.owner = THIS_MODULE,
|
||||
|
||||
.controls = wm8731_poodle_controls,
|
||||
.num_controls = ARRAY_SIZE(wm8731_poodle_controls),
|
||||
.dapm_widgets = wm8731_dapm_widgets,
|
||||
.num_dapm_widgets = ARRAY_SIZE(wm8731_dapm_widgets),
|
||||
.dapm_routes = poodle_audio_map,
|
||||
.num_dapm_routes = ARRAY_SIZE(poodle_audio_map),
|
||||
.fully_routed = true,
|
||||
};
|
||||
|
||||
static int poodle_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct snd_soc_card *card = &poodle;
|
||||
int ret;
|
||||
|
||||
poodle_pdata = pdev->dev.platform_data;
|
||||
locomo_gpio_set_dir(poodle_pdata->locomo_dev,
|
||||
poodle_pdata->gpio_amp_on, 0);
|
||||
/* should we mute HP at startup - burning power ?*/
|
||||
locomo_gpio_set_dir(poodle_pdata->locomo_dev,
|
||||
poodle_pdata->gpio_mute_l, 0);
|
||||
locomo_gpio_set_dir(poodle_pdata->locomo_dev,
|
||||
poodle_pdata->gpio_mute_r, 0);
|
||||
|
||||
card->dev = &pdev->dev;
|
||||
|
||||
ret = devm_snd_soc_register_card(&pdev->dev, card);
|
||||
if (ret)
|
||||
dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct platform_driver poodle_driver = {
|
||||
.driver = {
|
||||
.name = "poodle-audio",
|
||||
.pm = &snd_soc_pm_ops,
|
||||
},
|
||||
.probe = poodle_probe,
|
||||
};
|
||||
|
||||
module_platform_driver(poodle_driver);
|
||||
|
||||
/* Module information */
|
||||
MODULE_AUTHOR("Richard Purdie");
|
||||
MODULE_DESCRIPTION("ALSA SoC Poodle");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("platform:poodle-audio");
|
|
@ -1,255 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* tosa.c -- SoC audio for Tosa
|
||||
*
|
||||
* Copyright 2005 Wolfson Microelectronics PLC.
|
||||
* Copyright 2005 Openedhand Ltd.
|
||||
*
|
||||
* Authors: Liam Girdwood <lrg@slimlogic.co.uk>
|
||||
* Richard Purdie <richard@openedhand.com>
|
||||
*
|
||||
* GPIO's
|
||||
* 1 - Jack Insertion
|
||||
* 5 - Hookswitch (headset answer/hang up switch)
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
|
||||
#include <sound/core.h>
|
||||
#include <sound/pcm.h>
|
||||
#include <sound/soc.h>
|
||||
|
||||
#include <asm/mach-types.h>
|
||||
#include <linux/platform_data/asoc-pxa.h>
|
||||
|
||||
#define TOSA_HP 0
|
||||
#define TOSA_MIC_INT 1
|
||||
#define TOSA_HEADSET 2
|
||||
#define TOSA_HP_OFF 3
|
||||
#define TOSA_SPK_ON 0
|
||||
#define TOSA_SPK_OFF 1
|
||||
|
||||
static struct gpio_desc *tosa_mute;
|
||||
static int tosa_jack_func;
|
||||
static int tosa_spk_func;
|
||||
|
||||
static void tosa_ext_control(struct snd_soc_dapm_context *dapm)
|
||||
{
|
||||
|
||||
snd_soc_dapm_mutex_lock(dapm);
|
||||
|
||||
/* set up jack connection */
|
||||
switch (tosa_jack_func) {
|
||||
case TOSA_HP:
|
||||
snd_soc_dapm_disable_pin_unlocked(dapm, "Mic (Internal)");
|
||||
snd_soc_dapm_enable_pin_unlocked(dapm, "Headphone Jack");
|
||||
snd_soc_dapm_disable_pin_unlocked(dapm, "Headset Jack");
|
||||
break;
|
||||
case TOSA_MIC_INT:
|
||||
snd_soc_dapm_enable_pin_unlocked(dapm, "Mic (Internal)");
|
||||
snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack");
|
||||
snd_soc_dapm_disable_pin_unlocked(dapm, "Headset Jack");
|
||||
break;
|
||||
case TOSA_HEADSET:
|
||||
snd_soc_dapm_disable_pin_unlocked(dapm, "Mic (Internal)");
|
||||
snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack");
|
||||
snd_soc_dapm_enable_pin_unlocked(dapm, "Headset Jack");
|
||||
break;
|
||||
}
|
||||
|
||||
if (tosa_spk_func == TOSA_SPK_ON)
|
||||
snd_soc_dapm_enable_pin_unlocked(dapm, "Speaker");
|
||||
else
|
||||
snd_soc_dapm_disable_pin_unlocked(dapm, "Speaker");
|
||||
|
||||
snd_soc_dapm_sync_unlocked(dapm);
|
||||
|
||||
snd_soc_dapm_mutex_unlock(dapm);
|
||||
}
|
||||
|
||||
static int tosa_startup(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
|
||||
|
||||
/* check the jack status at stream startup */
|
||||
tosa_ext_control(&rtd->card->dapm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_soc_ops tosa_ops = {
|
||||
.startup = tosa_startup,
|
||||
};
|
||||
|
||||
static int tosa_get_jack(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
ucontrol->value.enumerated.item[0] = tosa_jack_func;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tosa_set_jack(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
|
||||
|
||||
if (tosa_jack_func == ucontrol->value.enumerated.item[0])
|
||||
return 0;
|
||||
|
||||
tosa_jack_func = ucontrol->value.enumerated.item[0];
|
||||
tosa_ext_control(&card->dapm);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int tosa_get_spk(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
ucontrol->value.enumerated.item[0] = tosa_spk_func;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tosa_set_spk(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
|
||||
|
||||
if (tosa_spk_func == ucontrol->value.enumerated.item[0])
|
||||
return 0;
|
||||
|
||||
tosa_spk_func = ucontrol->value.enumerated.item[0];
|
||||
tosa_ext_control(&card->dapm);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* tosa dapm event handlers */
|
||||
static int tosa_hp_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *k, int event)
|
||||
{
|
||||
gpiod_set_value(tosa_mute, SND_SOC_DAPM_EVENT_ON(event) ? 1 : 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* tosa machine dapm widgets */
|
||||
static const struct snd_soc_dapm_widget tosa_dapm_widgets[] = {
|
||||
SND_SOC_DAPM_HP("Headphone Jack", tosa_hp_event),
|
||||
SND_SOC_DAPM_HP("Headset Jack", NULL),
|
||||
SND_SOC_DAPM_MIC("Mic (Internal)", NULL),
|
||||
SND_SOC_DAPM_SPK("Speaker", NULL),
|
||||
};
|
||||
|
||||
/* tosa audio map */
|
||||
static const struct snd_soc_dapm_route audio_map[] = {
|
||||
|
||||
/* headphone connected to HPOUTL, HPOUTR */
|
||||
{"Headphone Jack", NULL, "HPOUTL"},
|
||||
{"Headphone Jack", NULL, "HPOUTR"},
|
||||
|
||||
/* ext speaker connected to LOUT2, ROUT2 */
|
||||
{"Speaker", NULL, "LOUT2"},
|
||||
{"Speaker", NULL, "ROUT2"},
|
||||
|
||||
/* internal mic is connected to mic1, mic2 differential - with bias */
|
||||
{"MIC1", NULL, "Mic Bias"},
|
||||
{"MIC2", NULL, "Mic Bias"},
|
||||
{"Mic Bias", NULL, "Mic (Internal)"},
|
||||
|
||||
/* headset is connected to HPOUTR, and LINEINR with bias */
|
||||
{"Headset Jack", NULL, "HPOUTR"},
|
||||
{"LINEINR", NULL, "Mic Bias"},
|
||||
{"Mic Bias", NULL, "Headset Jack"},
|
||||
};
|
||||
|
||||
static const char * const jack_function[] = {"Headphone", "Mic", "Line",
|
||||
"Headset", "Off"};
|
||||
static const char * const spk_function[] = {"On", "Off"};
|
||||
static const struct soc_enum tosa_enum[] = {
|
||||
SOC_ENUM_SINGLE_EXT(5, jack_function),
|
||||
SOC_ENUM_SINGLE_EXT(2, spk_function),
|
||||
};
|
||||
|
||||
static const struct snd_kcontrol_new tosa_controls[] = {
|
||||
SOC_ENUM_EXT("Jack Function", tosa_enum[0], tosa_get_jack,
|
||||
tosa_set_jack),
|
||||
SOC_ENUM_EXT("Speaker Function", tosa_enum[1], tosa_get_spk,
|
||||
tosa_set_spk),
|
||||
};
|
||||
|
||||
SND_SOC_DAILINK_DEFS(ac97,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("pxa2xx-ac97")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("wm9712-codec", "wm9712-hifi")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio")));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(ac97_aux,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("pxa2xx-ac97-aux")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("wm9712-codec", "wm9712-aux")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio")));
|
||||
|
||||
static struct snd_soc_dai_link tosa_dai[] = {
|
||||
{
|
||||
.name = "AC97",
|
||||
.stream_name = "AC97 HiFi",
|
||||
.ops = &tosa_ops,
|
||||
SND_SOC_DAILINK_REG(ac97),
|
||||
},
|
||||
{
|
||||
.name = "AC97 Aux",
|
||||
.stream_name = "AC97 Aux",
|
||||
.ops = &tosa_ops,
|
||||
SND_SOC_DAILINK_REG(ac97_aux),
|
||||
},
|
||||
};
|
||||
|
||||
static struct snd_soc_card tosa = {
|
||||
.name = "Tosa",
|
||||
.owner = THIS_MODULE,
|
||||
.dai_link = tosa_dai,
|
||||
.num_links = ARRAY_SIZE(tosa_dai),
|
||||
|
||||
.controls = tosa_controls,
|
||||
.num_controls = ARRAY_SIZE(tosa_controls),
|
||||
.dapm_widgets = tosa_dapm_widgets,
|
||||
.num_dapm_widgets = ARRAY_SIZE(tosa_dapm_widgets),
|
||||
.dapm_routes = audio_map,
|
||||
.num_dapm_routes = ARRAY_SIZE(audio_map),
|
||||
.fully_routed = true,
|
||||
};
|
||||
|
||||
static int tosa_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct snd_soc_card *card = ⤩
|
||||
int ret;
|
||||
|
||||
tosa_mute = devm_gpiod_get(&pdev->dev, NULL, GPIOD_OUT_LOW);
|
||||
if (IS_ERR(tosa_mute))
|
||||
return dev_err_probe(&pdev->dev, PTR_ERR(tosa_mute),
|
||||
"failed to get L_MUTE GPIO\n");
|
||||
gpiod_set_consumer_name(tosa_mute, "Headphone Jack");
|
||||
|
||||
card->dev = &pdev->dev;
|
||||
|
||||
ret = devm_snd_soc_register_card(&pdev->dev, card);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
|
||||
ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct platform_driver tosa_driver = {
|
||||
.driver = {
|
||||
.name = "tosa-audio",
|
||||
.pm = &snd_soc_pm_ops,
|
||||
},
|
||||
.probe = tosa_probe,
|
||||
};
|
||||
|
||||
module_platform_driver(tosa_driver);
|
||||
|
||||
/* Module information */
|
||||
MODULE_AUTHOR("Richard Purdie");
|
||||
MODULE_DESCRIPTION("ALSA SoC Tosa");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("platform:tosa-audio");
|
|
@ -1,143 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* linux/sound/soc/pxa/ttc_dkb.c
|
||||
*
|
||||
* Copyright (C) 2012 Marvell International Ltd.
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/pcm.h>
|
||||
#include <sound/soc.h>
|
||||
#include <sound/jack.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <sound/pcm_params.h>
|
||||
#include "../codecs/88pm860x-codec.h"
|
||||
|
||||
static struct snd_soc_jack hs_jack, mic_jack;
|
||||
|
||||
static struct snd_soc_jack_pin hs_jack_pins[] = {
|
||||
{ .pin = "Headset Stereophone", .mask = SND_JACK_HEADPHONE, },
|
||||
};
|
||||
|
||||
static struct snd_soc_jack_pin mic_jack_pins[] = {
|
||||
{ .pin = "Headset Mic 2", .mask = SND_JACK_MICROPHONE, },
|
||||
};
|
||||
|
||||
/* ttc machine dapm widgets */
|
||||
static const struct snd_soc_dapm_widget ttc_dapm_widgets[] = {
|
||||
SND_SOC_DAPM_HP("Headset Stereophone", NULL),
|
||||
SND_SOC_DAPM_LINE("Lineout Out 1", NULL),
|
||||
SND_SOC_DAPM_LINE("Lineout Out 2", NULL),
|
||||
SND_SOC_DAPM_SPK("Ext Speaker", NULL),
|
||||
SND_SOC_DAPM_MIC("Ext Mic 1", NULL),
|
||||
SND_SOC_DAPM_MIC("Headset Mic 2", NULL),
|
||||
SND_SOC_DAPM_MIC("Ext Mic 3", NULL),
|
||||
};
|
||||
|
||||
/* ttc machine audio map */
|
||||
static const struct snd_soc_dapm_route ttc_audio_map[] = {
|
||||
{"Headset Stereophone", NULL, "HS1"},
|
||||
{"Headset Stereophone", NULL, "HS2"},
|
||||
|
||||
{"Ext Speaker", NULL, "LSP"},
|
||||
{"Ext Speaker", NULL, "LSN"},
|
||||
|
||||
{"Lineout Out 1", NULL, "LINEOUT1"},
|
||||
{"Lineout Out 2", NULL, "LINEOUT2"},
|
||||
|
||||
{"MIC1P", NULL, "Mic1 Bias"},
|
||||
{"MIC1N", NULL, "Mic1 Bias"},
|
||||
{"Mic1 Bias", NULL, "Ext Mic 1"},
|
||||
|
||||
{"MIC2P", NULL, "Mic1 Bias"},
|
||||
{"MIC2N", NULL, "Mic1 Bias"},
|
||||
{"Mic1 Bias", NULL, "Headset Mic 2"},
|
||||
|
||||
{"MIC3P", NULL, "Mic3 Bias"},
|
||||
{"MIC3N", NULL, "Mic3 Bias"},
|
||||
{"Mic3 Bias", NULL, "Ext Mic 3"},
|
||||
};
|
||||
|
||||
static int ttc_pm860x_init(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
|
||||
|
||||
/* Headset jack detection */
|
||||
snd_soc_card_jack_new_pins(rtd->card, "Headphone Jack",
|
||||
SND_JACK_HEADPHONE | SND_JACK_BTN_0 |
|
||||
SND_JACK_BTN_1 | SND_JACK_BTN_2,
|
||||
&hs_jack,
|
||||
hs_jack_pins, ARRAY_SIZE(hs_jack_pins));
|
||||
snd_soc_card_jack_new_pins(rtd->card, "Microphone Jack",
|
||||
SND_JACK_MICROPHONE, &mic_jack,
|
||||
mic_jack_pins, ARRAY_SIZE(mic_jack_pins));
|
||||
|
||||
/* headphone, microphone detection & headset short detection */
|
||||
pm860x_hs_jack_detect(component, &hs_jack, SND_JACK_HEADPHONE,
|
||||
SND_JACK_BTN_0, SND_JACK_BTN_1, SND_JACK_BTN_2);
|
||||
pm860x_mic_jack_detect(component, &hs_jack, SND_JACK_MICROPHONE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ttc/td-dkb digital audio interface glue - connects codec <--> CPU */
|
||||
SND_SOC_DAILINK_DEFS(i2s,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("pxa-ssp-dai.1")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("88pm860x-codec", "88pm860x-i2s")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("mmp-pcm-audio")));
|
||||
|
||||
static struct snd_soc_dai_link ttc_pm860x_hifi_dai[] = {
|
||||
{
|
||||
.name = "88pm860x i2s",
|
||||
.stream_name = "audio playback",
|
||||
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
|
||||
SND_SOC_DAIFMT_CBM_CFM,
|
||||
.init = ttc_pm860x_init,
|
||||
SND_SOC_DAILINK_REG(i2s),
|
||||
},
|
||||
};
|
||||
|
||||
/* ttc/td audio machine driver */
|
||||
static struct snd_soc_card ttc_dkb_card = {
|
||||
.name = "ttc-dkb-hifi",
|
||||
.owner = THIS_MODULE,
|
||||
.dai_link = ttc_pm860x_hifi_dai,
|
||||
.num_links = ARRAY_SIZE(ttc_pm860x_hifi_dai),
|
||||
|
||||
.dapm_widgets = ttc_dapm_widgets,
|
||||
.num_dapm_widgets = ARRAY_SIZE(ttc_dapm_widgets),
|
||||
.dapm_routes = ttc_audio_map,
|
||||
.num_dapm_routes = ARRAY_SIZE(ttc_audio_map),
|
||||
};
|
||||
|
||||
static int ttc_dkb_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct snd_soc_card *card = &ttc_dkb_card;
|
||||
int ret;
|
||||
|
||||
card->dev = &pdev->dev;
|
||||
|
||||
ret = devm_snd_soc_register_card(&pdev->dev, card);
|
||||
if (ret)
|
||||
dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
|
||||
ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct platform_driver ttc_dkb_driver = {
|
||||
.driver = {
|
||||
.name = "ttc-dkb-audio",
|
||||
.pm = &snd_soc_pm_ops,
|
||||
},
|
||||
.probe = ttc_dkb_probe,
|
||||
};
|
||||
|
||||
module_platform_driver(ttc_dkb_driver);
|
||||
|
||||
/* Module information */
|
||||
MODULE_AUTHOR("Qiao Zhou, <zhouqiao@marvell.com>");
|
||||
MODULE_DESCRIPTION("ALSA SoC TTC DKB");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("platform:ttc-dkb-audio");
|
|
@ -1,218 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* linux/sound/soc/pxa/z2.c
|
||||
*
|
||||
* SoC Audio driver for Aeronix Zipit Z2
|
||||
*
|
||||
* Copyright (C) 2009 Ken McGuire <kenm@desertweyr.com>
|
||||
* Copyright (C) 2010 Marek Vasut <marek.vasut@gmail.com>
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
|
||||
#include <sound/core.h>
|
||||
#include <sound/pcm.h>
|
||||
#include <sound/soc.h>
|
||||
#include <sound/jack.h>
|
||||
|
||||
#include <asm/mach-types.h>
|
||||
#include <linux/platform_data/asoc-pxa.h>
|
||||
|
||||
#include "../codecs/wm8750.h"
|
||||
#include "pxa2xx-i2s.h"
|
||||
|
||||
static struct snd_soc_card snd_soc_z2;
|
||||
|
||||
static int z2_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
|
||||
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
|
||||
struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
|
||||
unsigned int clk = 0;
|
||||
int ret = 0;
|
||||
|
||||
switch (params_rate(params)) {
|
||||
case 8000:
|
||||
case 16000:
|
||||
case 48000:
|
||||
case 96000:
|
||||
clk = 12288000;
|
||||
break;
|
||||
case 11025:
|
||||
case 22050:
|
||||
case 44100:
|
||||
clk = 11289600;
|
||||
break;
|
||||
}
|
||||
|
||||
/* set the codec system clock for DAC and ADC */
|
||||
ret = snd_soc_dai_set_sysclk(codec_dai, WM8750_SYSCLK, clk,
|
||||
SND_SOC_CLOCK_IN);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* set the I2S system clock as input (unused) */
|
||||
ret = snd_soc_dai_set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, 0,
|
||||
SND_SOC_CLOCK_IN);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct snd_soc_jack hs_jack;
|
||||
|
||||
/* Headset jack detection DAPM pins */
|
||||
static struct snd_soc_jack_pin hs_jack_pins[] = {
|
||||
{
|
||||
.pin = "Mic Jack",
|
||||
.mask = SND_JACK_MICROPHONE,
|
||||
},
|
||||
{
|
||||
.pin = "Headphone Jack",
|
||||
.mask = SND_JACK_HEADPHONE,
|
||||
},
|
||||
{
|
||||
.pin = "Ext Spk",
|
||||
.mask = SND_JACK_HEADPHONE,
|
||||
.invert = 1
|
||||
},
|
||||
};
|
||||
|
||||
/* Headset jack detection gpios */
|
||||
static struct snd_soc_jack_gpio hs_jack_gpios[] = {
|
||||
{
|
||||
.name = "hsdet-gpio",
|
||||
.report = SND_JACK_HEADSET,
|
||||
.debounce_time = 200,
|
||||
.invert = 1,
|
||||
},
|
||||
};
|
||||
|
||||
/* z2 machine dapm widgets */
|
||||
static const struct snd_soc_dapm_widget wm8750_dapm_widgets[] = {
|
||||
SND_SOC_DAPM_HP("Headphone Jack", NULL),
|
||||
SND_SOC_DAPM_MIC("Mic Jack", NULL),
|
||||
SND_SOC_DAPM_SPK("Ext Spk", NULL),
|
||||
|
||||
/* headset is a mic and mono headphone */
|
||||
SND_SOC_DAPM_HP("Headset Jack", NULL),
|
||||
};
|
||||
|
||||
/* Z2 machine audio_map */
|
||||
static const struct snd_soc_dapm_route z2_audio_map[] = {
|
||||
|
||||
/* headphone connected to LOUT1, ROUT1 */
|
||||
{"Headphone Jack", NULL, "LOUT1"},
|
||||
{"Headphone Jack", NULL, "ROUT1"},
|
||||
|
||||
/* ext speaker connected to LOUT2, ROUT2 */
|
||||
{"Ext Spk", NULL, "ROUT2"},
|
||||
{"Ext Spk", NULL, "LOUT2"},
|
||||
|
||||
/* mic is connected to R input 2 - with bias */
|
||||
{"RINPUT2", NULL, "Mic Bias"},
|
||||
{"Mic Bias", NULL, "Mic Jack"},
|
||||
};
|
||||
|
||||
/*
|
||||
* Logic for a wm8750 as connected on a Z2 Device
|
||||
*/
|
||||
static int z2_wm8750_init(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Jack detection API stuff */
|
||||
ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack",
|
||||
SND_JACK_HEADSET, &hs_jack,
|
||||
hs_jack_pins,
|
||||
ARRAY_SIZE(hs_jack_pins));
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
ret = snd_soc_jack_add_gpios(&hs_jack, ARRAY_SIZE(hs_jack_gpios),
|
||||
hs_jack_gpios);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct snd_soc_ops z2_ops = {
|
||||
.hw_params = z2_hw_params,
|
||||
};
|
||||
|
||||
/* z2 digital audio interface glue - connects codec <--> CPU */
|
||||
SND_SOC_DAILINK_DEFS(wm8750,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("pxa2xx-i2s")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("wm8750.0-001b", "wm8750-hifi")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio")));
|
||||
|
||||
static struct snd_soc_dai_link z2_dai = {
|
||||
.name = "wm8750",
|
||||
.stream_name = "WM8750",
|
||||
.init = z2_wm8750_init,
|
||||
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
|
||||
SND_SOC_DAIFMT_CBS_CFS,
|
||||
.ops = &z2_ops,
|
||||
SND_SOC_DAILINK_REG(wm8750),
|
||||
};
|
||||
|
||||
/* z2 audio machine driver */
|
||||
static struct snd_soc_card snd_soc_z2 = {
|
||||
.name = "Z2",
|
||||
.owner = THIS_MODULE,
|
||||
.dai_link = &z2_dai,
|
||||
.num_links = 1,
|
||||
|
||||
.dapm_widgets = wm8750_dapm_widgets,
|
||||
.num_dapm_widgets = ARRAY_SIZE(wm8750_dapm_widgets),
|
||||
.dapm_routes = z2_audio_map,
|
||||
.num_dapm_routes = ARRAY_SIZE(z2_audio_map),
|
||||
.fully_routed = true,
|
||||
};
|
||||
|
||||
static struct platform_device *z2_snd_device;
|
||||
|
||||
static int __init z2_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!machine_is_zipit2())
|
||||
return -ENODEV;
|
||||
|
||||
z2_snd_device = platform_device_alloc("soc-audio", -1);
|
||||
if (!z2_snd_device)
|
||||
return -ENOMEM;
|
||||
|
||||
hs_jack_gpios[0].gpiod_dev = &z2_snd_device->dev;
|
||||
platform_set_drvdata(z2_snd_device, &snd_soc_z2);
|
||||
ret = platform_device_add(z2_snd_device);
|
||||
|
||||
if (ret)
|
||||
platform_device_put(z2_snd_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit z2_exit(void)
|
||||
{
|
||||
platform_device_unregister(z2_snd_device);
|
||||
}
|
||||
|
||||
module_init(z2_init);
|
||||
module_exit(z2_exit);
|
||||
|
||||
MODULE_AUTHOR("Ken McGuire <kenm@desertweyr.com>, "
|
||||
"Marek Vasut <marek.vasut@gmail.com>");
|
||||
MODULE_DESCRIPTION("ALSA SoC ZipitZ2");
|
||||
MODULE_LICENSE("GPL");
|
|
@ -1,266 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* zylonite.c -- SoC audio for Zylonite
|
||||
*
|
||||
* Copyright 2008 Wolfson Microelectronics PLC.
|
||||
* Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/pcm.h>
|
||||
#include <sound/pcm_params.h>
|
||||
#include <sound/soc.h>
|
||||
|
||||
#include "../codecs/wm9713.h"
|
||||
#include "pxa-ssp.h"
|
||||
|
||||
/*
|
||||
* There is a physical switch SW15 on the board which changes the MCLK
|
||||
* for the WM9713 between the standard AC97 master clock and the
|
||||
* output of the CLK_POUT signal from the PXA.
|
||||
*/
|
||||
static int clk_pout;
|
||||
module_param(clk_pout, int, 0);
|
||||
MODULE_PARM_DESC(clk_pout, "Use CLK_POUT as WM9713 MCLK (SW15 on board).");
|
||||
|
||||
static struct clk *pout;
|
||||
|
||||
static struct snd_soc_card zylonite;
|
||||
|
||||
static const struct snd_soc_dapm_widget zylonite_dapm_widgets[] = {
|
||||
SND_SOC_DAPM_HP("Headphone", NULL),
|
||||
SND_SOC_DAPM_MIC("Headset Microphone", NULL),
|
||||
SND_SOC_DAPM_MIC("Handset Microphone", NULL),
|
||||
SND_SOC_DAPM_SPK("Multiactor", NULL),
|
||||
SND_SOC_DAPM_SPK("Headset Earpiece", NULL),
|
||||
};
|
||||
|
||||
/* Currently supported audio map */
|
||||
static const struct snd_soc_dapm_route audio_map[] = {
|
||||
|
||||
/* Headphone output connected to HPL/HPR */
|
||||
{ "Headphone", NULL, "HPL" },
|
||||
{ "Headphone", NULL, "HPR" },
|
||||
|
||||
/* On-board earpiece */
|
||||
{ "Headset Earpiece", NULL, "OUT3" },
|
||||
|
||||
/* Headphone mic */
|
||||
{ "MIC2A", NULL, "Mic Bias" },
|
||||
{ "Mic Bias", NULL, "Headset Microphone" },
|
||||
|
||||
/* On-board mic */
|
||||
{ "MIC1", NULL, "Mic Bias" },
|
||||
{ "Mic Bias", NULL, "Handset Microphone" },
|
||||
|
||||
/* Multiactor differentially connected over SPKL/SPKR */
|
||||
{ "Multiactor", NULL, "SPKL" },
|
||||
{ "Multiactor", NULL, "SPKR" },
|
||||
};
|
||||
|
||||
static int zylonite_wm9713_init(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
if (clk_pout)
|
||||
snd_soc_dai_set_pll(asoc_rtd_to_codec(rtd, 0), 0, 0,
|
||||
clk_get_rate(pout), 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int zylonite_voice_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
|
||||
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
|
||||
struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
|
||||
unsigned int wm9713_div = 0;
|
||||
int ret = 0;
|
||||
int rate = params_rate(params);
|
||||
|
||||
/* Only support ratios that we can generate neatly from the AC97
|
||||
* based master clock - in particular, this excludes 44.1kHz.
|
||||
* In most applications the voice DAC will be used for telephony
|
||||
* data so multiples of 8kHz will be the common case.
|
||||
*/
|
||||
switch (rate) {
|
||||
case 8000:
|
||||
wm9713_div = 12;
|
||||
break;
|
||||
case 16000:
|
||||
wm9713_div = 6;
|
||||
break;
|
||||
case 48000:
|
||||
wm9713_div = 2;
|
||||
break;
|
||||
default:
|
||||
/* Don't support OSS emulation */
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_AUDIO, 0, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (clk_pout)
|
||||
ret = snd_soc_dai_set_clkdiv(codec_dai, WM9713_PCMCLK_PLL_DIV,
|
||||
WM9713_PCMDIV(wm9713_div));
|
||||
else
|
||||
ret = snd_soc_dai_set_clkdiv(codec_dai, WM9713_PCMCLK_DIV,
|
||||
WM9713_PCMDIV(wm9713_div));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_soc_ops zylonite_voice_ops = {
|
||||
.hw_params = zylonite_voice_hw_params,
|
||||
};
|
||||
|
||||
SND_SOC_DAILINK_DEFS(ac97,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("pxa2xx-ac97")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("wm9713-codec", "wm9713-hifi")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio")));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(ac97_aux,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("pxa2xx-ac97-aux")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("wm9713-codec", "wm9713-aux")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio")));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(voice,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("pxa-ssp-dai.2")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("wm9713-codec", "wm9713-voice")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio")));
|
||||
|
||||
static struct snd_soc_dai_link zylonite_dai[] = {
|
||||
{
|
||||
.name = "AC97",
|
||||
.stream_name = "AC97 HiFi",
|
||||
.init = zylonite_wm9713_init,
|
||||
SND_SOC_DAILINK_REG(ac97),
|
||||
},
|
||||
{
|
||||
.name = "AC97 Aux",
|
||||
.stream_name = "AC97 Aux",
|
||||
SND_SOC_DAILINK_REG(ac97_aux),
|
||||
},
|
||||
{
|
||||
.name = "WM9713 Voice",
|
||||
.stream_name = "WM9713 Voice",
|
||||
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
|
||||
SND_SOC_DAIFMT_CBS_CFS,
|
||||
.ops = &zylonite_voice_ops,
|
||||
SND_SOC_DAILINK_REG(voice),
|
||||
},
|
||||
};
|
||||
|
||||
static int zylonite_probe(struct snd_soc_card *card)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (clk_pout) {
|
||||
pout = clk_get(NULL, "CLK_POUT");
|
||||
if (IS_ERR(pout)) {
|
||||
dev_err(card->dev, "Unable to obtain CLK_POUT: %ld\n",
|
||||
PTR_ERR(pout));
|
||||
return PTR_ERR(pout);
|
||||
}
|
||||
|
||||
ret = clk_enable(pout);
|
||||
if (ret != 0) {
|
||||
dev_err(card->dev, "Unable to enable CLK_POUT: %d\n",
|
||||
ret);
|
||||
clk_put(pout);
|
||||
return ret;
|
||||
}
|
||||
|
||||
dev_dbg(card->dev, "MCLK enabled at %luHz\n",
|
||||
clk_get_rate(pout));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int zylonite_remove(struct snd_soc_card *card)
|
||||
{
|
||||
if (clk_pout) {
|
||||
clk_disable(pout);
|
||||
clk_put(pout);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int zylonite_suspend_post(struct snd_soc_card *card)
|
||||
{
|
||||
if (clk_pout)
|
||||
clk_disable(pout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int zylonite_resume_pre(struct snd_soc_card *card)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (clk_pout) {
|
||||
ret = clk_enable(pout);
|
||||
if (ret != 0)
|
||||
dev_err(card->dev, "Unable to enable CLK_POUT: %d\n",
|
||||
ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct snd_soc_card zylonite = {
|
||||
.name = "Zylonite",
|
||||
.owner = THIS_MODULE,
|
||||
.probe = &zylonite_probe,
|
||||
.remove = &zylonite_remove,
|
||||
.suspend_post = &zylonite_suspend_post,
|
||||
.resume_pre = &zylonite_resume_pre,
|
||||
.dai_link = zylonite_dai,
|
||||
.num_links = ARRAY_SIZE(zylonite_dai),
|
||||
|
||||
.dapm_widgets = zylonite_dapm_widgets,
|
||||
.num_dapm_widgets = ARRAY_SIZE(zylonite_dapm_widgets),
|
||||
.dapm_routes = audio_map,
|
||||
.num_dapm_routes = ARRAY_SIZE(audio_map),
|
||||
};
|
||||
|
||||
static struct platform_device *zylonite_snd_ac97_device;
|
||||
|
||||
static int __init zylonite_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
zylonite_snd_ac97_device = platform_device_alloc("soc-audio", -1);
|
||||
if (!zylonite_snd_ac97_device)
|
||||
return -ENOMEM;
|
||||
|
||||
platform_set_drvdata(zylonite_snd_ac97_device, &zylonite);
|
||||
|
||||
ret = platform_device_add(zylonite_snd_ac97_device);
|
||||
if (ret != 0)
|
||||
platform_device_put(zylonite_snd_ac97_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit zylonite_exit(void)
|
||||
{
|
||||
platform_device_unregister(zylonite_snd_ac97_device);
|
||||
}
|
||||
|
||||
module_init(zylonite_init);
|
||||
module_exit(zylonite_exit);
|
||||
|
||||
MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
|
||||
MODULE_DESCRIPTION("ALSA SoC WM9713 Zylonite");
|
||||
MODULE_LICENSE("GPL");
|
Загрузка…
Ссылка в новой задаче