diff options
Diffstat (limited to 'sound')
51 files changed, 494 insertions, 288 deletions
diff --git a/sound/arm/pxa2xx-ac97.c b/sound/arm/pxa2xx-ac97.c index 5b3274b465e..199cca3366d 100644 --- a/sound/arm/pxa2xx-ac97.c +++ b/sound/arm/pxa2xx-ac97.c @@ -26,10 +26,10 @@ #include <asm/irq.h> #include <linux/mutex.h> -#include <asm/hardware.h> -#include <asm/arch/pxa-regs.h> -#include <asm/arch/pxa2xx-gpio.h> -#include <asm/arch/audio.h> +#include <mach/hardware.h> +#include <mach/pxa-regs.h> +#include <mach/pxa2xx-gpio.h> +#include <mach/audio.h> #include "pxa2xx-pcm.h" diff --git a/sound/arm/pxa2xx-pcm.c b/sound/arm/pxa2xx-pcm.c index 0ede9e4656a..381094aab23 100644 --- a/sound/arm/pxa2xx-pcm.c +++ b/sound/arm/pxa2xx-pcm.c @@ -21,8 +21,8 @@ #include <sound/pcm_params.h> #include <asm/dma.h> -#include <asm/hardware.h> -#include <asm/arch/pxa-regs.h> +#include <mach/hardware.h> +#include <mach/pxa-regs.h> #include "pxa2xx-pcm.h" diff --git a/sound/arm/sa11xx-uda1341.c b/sound/arm/sa11xx-uda1341.c index faeddf3eced..b9c51bf8cd7 100644 --- a/sound/arm/sa11xx-uda1341.c +++ b/sound/arm/sa11xx-uda1341.c @@ -71,8 +71,8 @@ #include <linux/pm.h> #endif -#include <asm/hardware.h> -#include <asm/arch/h3600.h> +#include <mach/hardware.h> +#include <mach/h3600.h> #include <asm/mach-types.h> #include <asm/dma.h> diff --git a/sound/core/seq/oss/seq_oss_synth.c b/sound/core/seq/oss/seq_oss_synth.c index 558dadbf45f..e024e4588b8 100644 --- a/sound/core/seq/oss/seq_oss_synth.c +++ b/sound/core/seq/oss/seq_oss_synth.c @@ -604,6 +604,9 @@ snd_seq_oss_synth_make_info(struct seq_oss_devinfo *dp, int dev, struct synth_in { struct seq_oss_synth *rec; + if (dev < 0 || dev >= dp->max_synthdev) + return -ENXIO; + if (dp->synths[dev].is_midi) { struct midi_info minf; snd_seq_oss_midi_make_info(dp, dp->synths[dev].midi_mapped, &minf); diff --git a/sound/mips/au1x00.c b/sound/mips/au1x00.c index ee0741f9eb5..fbef38a9604 100644 --- a/sound/mips/au1x00.c +++ b/sound/mips/au1x00.c @@ -38,7 +38,6 @@ #include <linux/interrupt.h> #include <linux/init.h> #include <linux/slab.h> -#include <linux/version.h> #include <sound/core.h> #include <sound/initval.h> #include <sound/pcm.h> diff --git a/sound/oss/vidc.c b/sound/oss/vidc.c index bb4a0969f46..725fef0f59a 100644 --- a/sound/oss/vidc.c +++ b/sound/oss/vidc.c @@ -22,7 +22,7 @@ #include <linux/kernel.h> #include <linux/interrupt.h> -#include <asm/hardware.h> +#include <mach/hardware.h> #include <asm/dma.h> #include <asm/io.h> #include <asm/hardware/iomd.h> diff --git a/sound/oss/vidc_fill.S b/sound/oss/vidc_fill.S index 01ccc074cc1..bed34921d17 100644 --- a/sound/oss/vidc_fill.S +++ b/sound/oss/vidc_fill.S @@ -11,7 +11,7 @@ */ #include <linux/linkage.h> #include <asm/assembler.h> -#include <asm/hardware.h> +#include <mach/hardware.h> #include <asm/hardware/iomd.h> .text diff --git a/sound/oss/waveartist.c b/sound/oss/waveartist.c index 88490418f93..c47842fad65 100644 --- a/sound/oss/waveartist.c +++ b/sound/oss/waveartist.c @@ -47,7 +47,7 @@ #include "waveartist.h" #ifdef CONFIG_ARM -#include <asm/hardware.h> +#include <mach/hardware.h> #include <asm/mach-types.h> #endif diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index f7d95b224a9..31f52d3fc21 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig @@ -845,7 +845,7 @@ config SND_VIRTUOSO select SND_OXYGEN_LIB help Say Y here to include support for sound cards based on the - Asus AV100/AV200 chips, i.e., Xonar D2, DX and D2X. + Asus AV100/AV200 chips, i.e., Xonar D1, DX, D2 and D2X. To compile this driver as a module, choose M here: the module will be called snd-virtuoso. diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c index 2f8b28add27..6abe8a3bd36 100644 --- a/sound/pci/ca0106/ca0106_main.c +++ b/sound/pci/ca0106/ca0106_main.c @@ -249,11 +249,12 @@ static struct snd_ca0106_details ca0106_chip_details[] = { .name = "MSI K8N Diamond MB [SB0438]", .gpio_type = 2, .i2c_adc = 1 } , - /* Another MSI K8N Diamond MB, which has apprently a different SSID */ + /* MSI K8N Diamond PLUS MB */ { .serial = 0x10091102, .name = "MSI K8N Diamond MB", .gpio_type = 2, - .i2c_adc = 1 } , + .i2c_adc = 1, + .spi_dac = 2 }, /* Shuttle XPC SD31P which has an onboard Creative Labs * Sound Blaster Live! 24-bit EAX * high-definition 7.1 audio processor". diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index ef9f072b47f..1c53e337ecb 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -101,6 +101,7 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6}," "{Intel, ICH8}," "{Intel, ICH9}," "{Intel, ICH10}," + "{Intel, PCH}," "{Intel, SCH}," "{ATI, SB450}," "{ATI, SB600}," @@ -277,6 +278,9 @@ enum { /* Defines for Nvidia HDA support */ #define NVIDIA_HDA_TRANSREG_ADDR 0x4e #define NVIDIA_HDA_ENABLE_COHBITS 0x0f +#define NVIDIA_HDA_ISTRM_COH 0x4d +#define NVIDIA_HDA_OSTRM_COH 0x4c +#define NVIDIA_HDA_ENABLE_COHBIT 0x01 /* Defines for Intel SCH HDA snoop control */ #define INTEL_SCH_HDA_DEVC 0x78 @@ -899,6 +903,12 @@ static void azx_init_pci(struct azx *chip) update_pci_byte(chip->pci, NVIDIA_HDA_TRANSREG_ADDR, 0x0f, NVIDIA_HDA_ENABLE_COHBITS); + update_pci_byte(chip->pci, + NVIDIA_HDA_ISTRM_COH, + 0x01, NVIDIA_HDA_ENABLE_COHBIT); + update_pci_byte(chip->pci, + NVIDIA_HDA_OSTRM_COH, + 0x01, NVIDIA_HDA_ENABLE_COHBIT); break; case AZX_DRIVER_SCH: pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop); @@ -2263,6 +2273,8 @@ static struct pci_device_id azx_ids[] = { { PCI_DEVICE(0x8086, 0x293f), .driver_data = AZX_DRIVER_ICH }, { PCI_DEVICE(0x8086, 0x3a3e), .driver_data = AZX_DRIVER_ICH }, { PCI_DEVICE(0x8086, 0x3a6e), .driver_data = AZX_DRIVER_ICH }, + /* PCH */ + { PCI_DEVICE(0x8086, 0x3b56), .driver_data = AZX_DRIVER_ICH }, /* SCH */ { PCI_DEVICE(0x8086, 0x811b), .driver_data = AZX_DRIVER_SCH }, /* ATI SB 450/600 */ @@ -2272,6 +2284,7 @@ static struct pci_device_id azx_ids[] = { { PCI_DEVICE(0x1002, 0x793b), .driver_data = AZX_DRIVER_ATIHDMI }, { PCI_DEVICE(0x1002, 0x7919), .driver_data = AZX_DRIVER_ATIHDMI }, { PCI_DEVICE(0x1002, 0x960f), .driver_data = AZX_DRIVER_ATIHDMI }, + { PCI_DEVICE(0x1002, 0x970f), .driver_data = AZX_DRIVER_ATIHDMI }, { PCI_DEVICE(0x1002, 0xaa00), .driver_data = AZX_DRIVER_ATIHDMI }, { PCI_DEVICE(0x1002, 0xaa08), .driver_data = AZX_DRIVER_ATIHDMI }, { PCI_DEVICE(0x1002, 0xaa10), .driver_data = AZX_DRIVER_ATIHDMI }, diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index add4e87e0b2..909f1c101c9 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -952,7 +952,7 @@ do_sku: tmp | 0x2010); break; case 0x10ec0888: - alc888_coef_init(codec); + /*alc888_coef_init(codec);*/ /* called in alc_init() */ break; case 0x10ec0267: case 0x10ec0268: @@ -2439,6 +2439,8 @@ static int alc_init(struct hda_codec *codec) unsigned int i; alc_fix_pll(codec); + if (codec->vendor_id == 0x10ec0888) + alc888_coef_init(codec); for (i = 0; i < spec->num_init_verbs; i++) snd_hda_sequence_write(codec, spec->init_verbs[i]); @@ -6437,6 +6439,39 @@ static void alc882_auto_init_analog_input(struct hda_codec *codec) } } +static void alc882_auto_init_input_src(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + const struct hda_input_mux *imux = spec->input_mux; + int c; + + for (c = 0; c < spec->num_adc_nids; c++) { + hda_nid_t conn_list[HDA_MAX_NUM_INPUTS]; + hda_nid_t nid = spec->capsrc_nids[c]; + int conns, mute, idx, item; + + conns = snd_hda_get_connections(codec, nid, conn_list, + ARRAY_SIZE(conn_list)); + if (conns < 0) + continue; + for (idx = 0; idx < conns; idx++) { + /* if the current connection is the selected one, + * unmute it as default - otherwise mute it + */ + mute = AMP_IN_MUTE(idx); + for (item = 0; item < imux->num_items; item++) { + if (imux->items[item].index == idx) { + if (spec->cur_mux[c] == item) + mute = AMP_IN_UNMUTE(idx); + break; + } + } + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_AMP_GAIN_MUTE, mute); + } + } +} + /* add mic boosts if needed */ static int alc_auto_add_mic_boost(struct hda_codec *codec) { @@ -6491,6 +6526,7 @@ static void alc882_auto_init(struct hda_codec *codec) alc882_auto_init_multi_out(codec); alc882_auto_init_hp_out(codec); alc882_auto_init_analog_input(codec); + alc882_auto_init_input_src(codec); if (spec->unsol_event) alc_sku_automute(codec); } @@ -8285,6 +8321,8 @@ static void alc883_auto_init_analog_input(struct hda_codec *codec) } } +#define alc883_auto_init_input_src alc882_auto_init_input_src + /* almost identical with ALC880 parser... */ static int alc883_parse_auto_config(struct hda_codec *codec) { @@ -8315,6 +8353,7 @@ static void alc883_auto_init(struct hda_codec *codec) alc883_auto_init_multi_out(codec); alc883_auto_init_hp_out(codec); alc883_auto_init_analog_input(codec); + alc883_auto_init_input_src(codec); if (spec->unsol_event) alc_sku_automute(codec); } @@ -8389,8 +8428,6 @@ static int patch_alc883(struct hda_codec *codec) codec->patch_ops = alc_patch_ops; if (board_config == ALC883_AUTO) spec->init_hook = alc883_auto_init; - else if (codec->vendor_id == 0x10ec0888) - spec->init_hook = alc888_coef_init; #ifdef CONFIG_SND_HDA_POWER_SAVE if (!spec->loopback.amplist) @@ -9663,6 +9700,7 @@ static int alc262_parse_auto_config(struct hda_codec *codec) #define alc262_auto_init_multi_out alc882_auto_init_multi_out #define alc262_auto_init_hp_out alc882_auto_init_hp_out #define alc262_auto_init_analog_input alc882_auto_init_analog_input +#define alc262_auto_init_input_src alc882_auto_init_input_src /* init callback for auto-configuration model -- overriding the default init */ @@ -9672,6 +9710,7 @@ static void alc262_auto_init(struct hda_codec *codec) alc262_auto_init_multi_out(codec); alc262_auto_init_hp_out(codec); alc262_auto_init_analog_input(codec); + alc262_auto_init_input_src(codec); if (spec->unsol_event) alc_sku_automute(codec); } @@ -13330,6 +13369,8 @@ static void alc861vd_auto_init_analog_input(struct hda_codec *codec) } } +#define alc861vd_auto_init_input_src alc882_auto_init_input_src + #define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02) #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c) @@ -13512,6 +13553,7 @@ static void alc861vd_auto_init(struct hda_codec *codec) alc861vd_auto_init_multi_out(codec); alc861vd_auto_init_hp_out(codec); alc861vd_auto_init_analog_input(codec); + alc861vd_auto_init_input_src(codec); if (spec->unsol_event) alc_sku_automute(codec); } @@ -14677,6 +14719,8 @@ static void alc662_auto_init_analog_input(struct hda_codec *codec) } } +#define alc662_auto_init_input_src alc882_auto_init_input_src + static int alc662_parse_auto_config(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; @@ -14733,6 +14777,7 @@ static void alc662_auto_init(struct hda_codec *codec) alc662_auto_init_multi_out(codec); alc662_auto_init_hp_out(codec); alc662_auto_init_analog_input(codec); + alc662_auto_init_input_src(codec); if (spec->unsol_event) alc_sku_automute(codec); } diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c index 6facac5aed9..05eb8994c14 100644 --- a/sound/pci/oxygen/oxygen_mixer.c +++ b/sound/pci/oxygen/oxygen_mixer.c @@ -512,9 +512,12 @@ static int ac97_switch_get(struct snd_kcontrol *ctl, static void mute_ac97_ctl(struct oxygen *chip, unsigned int control) { - unsigned int priv_idx = chip->controls[control]->private_value & 0xff; + unsigned int priv_idx; u16 value; + if (!chip->controls[control]) + return; + priv_idx = chip->controls[control]->private_value & 0xff; value = oxygen_read_ac97(chip, 0, priv_idx); if (!(value & 0x8000)) { oxygen_write_ac97(chip, 0, priv_idx, value | 0x8000); diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c index 9a2c16bf94e..01d7b75f918 100644 --- a/sound/pci/oxygen/virtuoso.c +++ b/sound/pci/oxygen/virtuoso.c @@ -36,15 +36,15 @@ */ /* - * Xonar DX - * -------- + * Xonar D1/DX + * ----------- * * CMI8788: * * I²C <-> CS4398 (front) * <-> CS4362A (surround, center/LFE, back) * - * GPI 0 <- external power present + * GPI 0 <- external power present (DX only) * * GPIO 0 -> enable output to speakers * GPIO 1 -> enable front panel I/O @@ -96,6 +96,7 @@ MODULE_PARM_DESC(enable, "enable card"); enum { MODEL_D2, MODEL_D2X, + MODEL_D1, MODEL_DX, }; @@ -103,6 +104,7 @@ static struct pci_device_id xonar_ids[] __devinitdata = { { OXYGEN_PCI_SUBID(0x1043, 0x8269), .driver_data = MODEL_D2 }, { OXYGEN_PCI_SUBID(0x1043, 0x8275), .driver_data = MODEL_DX }, { OXYGEN_PCI_SUBID(0x1043, 0x82b7), .driver_data = MODEL_D2X }, + { OXYGEN_PCI_SUBID(0x1043, 0x834f), .driver_data = MODEL_D1 }, { } }; MODULE_DEVICE_TABLE(pci, xonar_ids); @@ -313,15 +315,12 @@ static void cs43xx_init(struct oxygen *chip) cs4362a_write(chip, 0x01, CS4362A_CPEN); } -static void xonar_dx_init(struct oxygen *chip) +static void xonar_d1_init(struct oxygen *chip) { struct xonar_data *data = chip->model_data; data->anti_pop_delay = 800; data->output_enable_bit = GPIO_DX_OUTPUT_ENABLE; - data->ext_power_reg = OXYGEN_GPI_DATA; - data->ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK; - data->ext_power_bit = GPI_DX_EXT_POWER; data->cs4398_fm = CS4398_FM_SINGLE | CS4398_DEM_NONE | CS4398_DIF_LJUST; data->cs4362a_fm = CS4362A_FM_SINGLE | CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L; @@ -345,6 +344,16 @@ static void xonar_dx_init(struct oxygen *chip) snd_component_add(chip->card, "CS5361"); } +static void xonar_dx_init(struct oxygen *chip) +{ + struct xonar_data *data = chip->model_data; + + data->ext_power_reg = OXYGEN_GPI_DATA; + data->ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK; + data->ext_power_bit = GPI_DX_EXT_POWER; + xonar_d1_init(chip); +} + static void xonar_cleanup(struct oxygen *chip) { struct xonar_data *data = chip->model_data; @@ -352,7 +361,7 @@ static void xonar_cleanup(struct oxygen *chip) oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, data->output_enable_bit); } -static void xonar_dx_cleanup(struct oxygen *chip) +static void xonar_d1_cleanup(struct oxygen *chip) { xonar_cleanup(chip); cs4362a_write(chip, 0x01, CS4362A_PDN | CS4362A_CPEN); @@ -365,7 +374,7 @@ static void xonar_d2_resume(struct oxygen *chip) xonar_enable_output(chip); } -static void xonar_dx_resume(struct oxygen *chip) +static void xonar_d1_resume(struct oxygen *chip) { cs43xx_init(chip); xonar_enable_output(chip); @@ -513,7 +522,7 @@ static const struct snd_kcontrol_new front_panel_switch = { .put = front_panel_put, }; -static void xonar_dx_ac97_switch(struct oxygen *chip, +static void xonar_d1_ac97_switch(struct oxygen *chip, unsigned int reg, unsigned int mute) { if (reg == AC97_LINE) { @@ -536,7 +545,7 @@ static int xonar_d2_control_filter(struct snd_kcontrol_new *template) return 0; } -static int xonar_dx_control_filter(struct snd_kcontrol_new *template) +static int xonar_d1_control_filter(struct snd_kcontrol_new *template) { if (!strncmp(template->name, "CD Capture ", 11)) return 1; /* no CD input */ @@ -548,7 +557,7 @@ static int xonar_mixer_init(struct oxygen *chip) return snd_ctl_add(chip->card, snd_ctl_new1(&alt_switch, chip)); } -static int xonar_dx_mixer_init(struct oxygen *chip) +static int xonar_d1_mixer_init(struct oxygen *chip) { return snd_ctl_add(chip->card, snd_ctl_new1(&front_panel_switch, chip)); } @@ -615,23 +624,51 @@ static const struct oxygen_model xonar_models[] = { .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, }, + [MODEL_D1] = { + .shortname = "Xonar D1", + .longname = "Asus Virtuoso 100", + .chip = "AV200", + .owner = THIS_MODULE, + .init = xonar_d1_init, + .control_filter = xonar_d1_control_filter, + .mixer_init = xonar_d1_mixer_init, + .cleanup = xonar_d1_cleanup, + .suspend = xonar_d1_cleanup, + .resume = xonar_d1_resume, + .set_dac_params = set_cs43xx_params, + .set_adc_params = set_cs53x1_params, + .update_dac_volume = update_cs43xx_volume, + .update_dac_mute = update_cs43xx_mute, + .ac97_switch = xonar_d1_ac97_switch, + .dac_tlv = cs4362a_db_scale, + .model_data_size = sizeof(struct xonar_data), + .pcm_dev_cfg = PLAYBACK_0_TO_I2S | + PLAYBACK_1_TO_SPDIF | + CAPTURE_0_FROM_I2S_2, + .dac_channels = 8, + .dac_volume_min = 0, + .dac_volume_max = 127, + .function_flags = OXYGEN_FUNCTION_2WIRE, + .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, + .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, + }, [MODEL_DX] = { .shortname = "Xonar DX", .longname = "Asus Virtuoso 100", .chip = "AV200", .owner = THIS_MODULE, .init = xonar_dx_init, - .control_filter = xonar_dx_control_filter, - .mixer_init = xonar_dx_mixer_init, - .cleanup = xonar_dx_cleanup, - .suspend = xonar_dx_cleanup, - .resume = xonar_dx_resume, + .control_filter = xonar_d1_control_filter, + .mixer_init = xonar_d1_mixer_init, + .cleanup = xonar_d1_cleanup, + .suspend = xonar_d1_cleanup, + .resume = xonar_d1_resume, .set_dac_params = set_cs43xx_params, .set_adc_params = set_cs53x1_params, .update_dac_volume = update_cs43xx_volume, .update_dac_mute = update_cs43xx_mute, .gpio_changed = xonar_gpio_changed, - .ac97_switch = xonar_dx_ac97_switch, + .ac97_switch = xonar_d1_ac97_switch, .dac_tlv = cs4362a_db_scale, .model_data_size = sizeof(struct xonar_data), .pcm_dev_cfg = PLAYBACK_0_TO_I2S | diff --git a/sound/sh/aica.c b/sound/sh/aica.c index 9ca11332614..54df8baf916 100644 --- a/sound/sh/aica.c +++ b/sound/sh/aica.c @@ -42,7 +42,7 @@ #include <sound/info.h> #include <asm/io.h> #include <asm/dma.h> -#include <asm/dreamcast/sysasic.h> +#include <mach/sysasic.h> #include "aica.h" MODULE_AUTHOR("Adrian McMenamin <adrian@mcmen.demon.co.uk>"); diff --git a/sound/soc/at32/playpaq_wm8510.c b/sound/soc/at32/playpaq_wm8510.c index fee5f8e5895..3f326219f1e 100644 --- a/sound/soc/at32/playpaq_wm8510.c +++ b/sound/soc/at32/playpaq_wm8510.c @@ -36,8 +36,8 @@ #include <sound/soc.h> #include <sound/soc-dapm.h> -#include <asm/arch/at32ap700x.h> -#include <asm/arch/portmux.h> +#include <mach/at32ap700x.h> +#include <mach/portmux.h> #include "../codecs/wm8510.h" #include "at32-pcm.h" diff --git a/sound/soc/at91/at91-pcm.c b/sound/soc/at91/at91-pcm.c index d47492b2b6e..7ab48bd25e4 100644 --- a/sound/soc/at91/at91-pcm.c +++ b/sound/soc/at91/at91-pcm.c @@ -28,8 +28,8 @@ #include <sound/pcm_params.h> #include <sound/soc.h> -#include <asm/arch/hardware.h> -#include <asm/arch/at91_ssc.h> +#include <mach/hardware.h> +#include <mach/at91_ssc.h> #include "at91-pcm.h" diff --git a/sound/soc/at91/at91-pcm.h b/sound/soc/at91/at91-pcm.h index 58d0f00a07b..e5aada2cb10 100644 --- a/sound/soc/at91/at91-pcm.h +++ b/sound/soc/at91/at91-pcm.h @@ -19,7 +19,7 @@ #ifndef _AT91_PCM_H #define _AT91_PCM_H -#include <asm/arch/hardware.h> +#include <mach/hardware.h> struct at91_ssc_periph { void __iomem *base; diff --git a/sound/soc/at91/at91-ssc.c b/sound/soc/at91/at91-ssc.c index 090e607f869..5d44515e62e 100644 --- a/sound/soc/at91/at91-ssc.c +++ b/sound/soc/at91/at91-ssc.c @@ -28,9 +28,9 @@ #include <sound/initval.h> #include <sound/soc.h> -#include <asm/arch/hardware.h> -#include <asm/arch/at91_pmc.h> -#include <asm/arch/at91_ssc.h> +#include <mach/hardware.h> +#include <mach/at91_pmc.h> +#include <mach/at91_ssc.h> #include "at91-pcm.h" #include "at91-ssc.h" diff --git a/sound/soc/at91/eti_b1_wm8731.c b/sound/soc/at91/eti_b1_wm8731.c index d532de95424..b81d6b2cfa1 100644 --- a/sound/soc/at91/eti_b1_wm8731.c +++ b/sound/soc/at91/eti_b1_wm8731.c @@ -22,7 +22,6 @@ #include <linux/module.h> #include <linux/moduleparam.h> -#include <linux/version.h> #include <linux/kernel.h> #include <linux/clk.h> #include <linux/timer.h> @@ -33,8 +32,8 @@ #include <sound/soc.h> #include <sound/soc-dapm.h> -#include <asm/hardware.h> -#include <asm/arch/gpio.h> +#include <mach/hardware.h> +#include <mach/gpio.h> #include "../codecs/wm8731.h" #include "at91-pcm.h" diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c index b26003c4f3e..7da9f467b7b 100644 --- a/sound/soc/codecs/ak4535.c +++ b/sound/soc/codecs/ak4535.c @@ -562,10 +562,9 @@ static int ak4535_codec_probe(struct i2c_adapter *adap, int addr, int kind) client_template.addr = addr; i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL); - if (i2c == NULL) { - kfree(codec); + if (i2c == NULL) return -ENOMEM; - } + i2c_set_clientdata(i2c, codec); codec->control_data = i2c; @@ -583,7 +582,6 @@ static int ak4535_codec_probe(struct i2c_adapter *adap, int addr, int kind) return ret; err: - kfree(codec); kfree(i2c); return ret; } @@ -660,6 +658,11 @@ static int ak4535_probe(struct platform_device *pdev) #else /* Add other interfaces here */ #endif + + if (ret != 0) { + kfree(codec->private_data); + kfree(codec); + } return ret; } diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index b1dce5f459d..5f9abb19943 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -1199,10 +1199,9 @@ static int aic3x_codec_probe(struct i2c_adapter *adap, int addr, int kind) client_template.addr = addr; i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL); - if (i2c == NULL) { - kfree(codec); + if (i2c == NULL) return -ENOMEM; - } + i2c_set_clientdata(i2c, codec); codec->control_data = i2c; @@ -1221,7 +1220,6 @@ static int aic3x_codec_probe(struct i2c_adapter *adap, int addr, int kind) return ret; err: - kfree(codec); kfree(i2c); return ret; } @@ -1302,6 +1300,11 @@ static int aic3x_probe(struct platform_device *pdev) #else /* Add other interfaces here */ #endif + + if (ret != 0) { + kfree(codec->private_data); + kfree(codec); + } return ret; } diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c index a52d6d9e007..807318fbdc8 100644 --- a/sound/soc/codecs/uda1380.c +++ b/sound/soc/codecs/uda1380.c @@ -729,10 +729,9 @@ static int uda1380_codec_probe(struct i2c_adapter *adap, int addr, int kind) client_template.addr = addr; i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL); - if (i2c == NULL) { - kfree(codec); + if (i2c == NULL) return -ENOMEM; - } + i2c_set_clientdata(i2c, codec); codec->control_data = i2c; @@ -750,7 +749,6 @@ static int uda1380_codec_probe(struct i2c_adapter *adap, int addr, int kind) return ret; err: - kfree(codec); kfree(i2c); return ret; } @@ -817,6 +815,9 @@ static int uda1380_probe(struct platform_device *pdev) #else /* Add other interfaces here */ #endif + + if (ret != 0) + kfree(codec); return ret; } diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c index 67325fd9544..3d998e6a997 100644 --- a/sound/soc/codecs/wm8510.c +++ b/sound/soc/codecs/wm8510.c @@ -693,10 +693,9 @@ static int wm8510_codec_probe(struct i2c_adapter *adap, int addr, int kind) client_template.addr = addr; i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL); - if (i2c == NULL) { - kfree(codec); + if (i2c == NULL) return -ENOMEM; - } + i2c_set_clientdata(i2c, codec); codec->control_data = i2c; @@ -714,7 +713,6 @@ static int wm8510_codec_probe(struct i2c_adapter *adap, int addr, int kind) return ret; err: - kfree(codec); kfree(i2c); return ret; } @@ -782,6 +780,9 @@ static int wm8510_probe(struct platform_device *pdev) #else /* Add other interfaces here */ #endif + + if (ret != 0) + kfree(codec); return ret; } diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index 369d39c3f74..9402fcaf04f 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c @@ -596,10 +596,9 @@ static int wm8731_codec_probe(struct i2c_adapter *adap, int addr, int kind) client_template.addr = addr; i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL); - if (i2c == NULL) { - kfree(codec); + if (i2c == NULL) return -ENOMEM; - } + i2c_set_clientdata(i2c, codec); codec->control_data = i2c; @@ -617,7 +616,6 @@ static int wm8731_codec_probe(struct i2c_adapter *adap, int addr, int kind) return ret; err: - kfree(codec); kfree(i2c); return ret; } @@ -693,6 +691,11 @@ static int wm8731_probe(struct platform_device *pdev) #else /* Add other interfaces here */ #endif + + if (ret != 0) { + kfree(codec->private_data); + kfree(codec); + } return ret; } diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c index e23cb09f0d1..dd1f55404b2 100644 --- a/sound/soc/codecs/wm8750.c +++ b/sound/soc/codecs/wm8750.c @@ -348,8 +348,9 @@ static const struct snd_soc_dapm_widget wm8750_dapm_widgets[] = { SND_SOC_DAPM_OUTPUT("ROUT1"), SND_SOC_DAPM_OUTPUT("LOUT2"), SND_SOC_DAPM_OUTPUT("ROUT2"), - SND_SOC_DAPM_OUTPUT("MONO"), + SND_SOC_DAPM_OUTPUT("MONO1"), SND_SOC_DAPM_OUTPUT("OUT3"), + SND_SOC_DAPM_OUTPUT("VREF"), SND_SOC_DAPM_INPUT("LINPUT1"), SND_SOC_DAPM_INPUT("LINPUT2"), @@ -868,10 +869,9 @@ static int wm8750_codec_probe(struct i2c_adapter *adap, int addr, int kind) client_template.addr = addr; i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL); - if (i2c == NULL) { - kfree(codec); + if (i2c == NULL) return -ENOMEM; - } + i2c_set_clientdata(i2c, codec); codec->control_data = i2c; @@ -889,7 +889,6 @@ static int wm8750_codec_probe(struct i2c_adapter *adap, int addr, int kind) return ret; err: - kfree(codec); kfree(i2c); return ret; } @@ -965,6 +964,10 @@ static int wm8750_probe(struct platform_device *pdev) /* Add other interfaces here */ #endif + if (ret != 0) { + kfree(codec->private_data); + kfree(codec); + } return ret; } diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c index 8604809f0c3..5761164fe16 100644 --- a/sound/soc/codecs/wm8753.c +++ b/sound/soc/codecs/wm8753.c @@ -34,7 +34,6 @@ #include <linux/module.h> #include <linux/moduleparam.h> -#include <linux/version.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/delay.h> @@ -1661,10 +1660,9 @@ static int wm8753_codec_probe(struct i2c_adapter *adap, int addr, int kind) client_template.addr = addr; i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL); - if (!i2c) { - kfree(codec); + if (!i2c) return -ENOMEM; - } + i2c_set_clientdata(i2c, codec); codec->control_data = i2c; @@ -1683,7 +1681,6 @@ static int wm8753_codec_probe(struct i2c_adapter *adap, int addr, int kind) return ret; err: - kfree(codec); kfree(i2c); return ret; } @@ -1760,6 +1757,11 @@ static int wm8753_probe(struct platform_device *pdev) #else /* Add other interfaces here */ #endif + + if (ret != 0) { + kfree(codec->private_data); + kfree(codec); + } return ret; } diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c index 3ecce5168e9..dd995ef448b 100644 --- a/sound/soc/codecs/wm8990.c +++ b/sound/soc/codecs/wm8990.c @@ -82,7 +82,7 @@ static const u16 wm8990_reg[] = { 0x0003, /* R35 - ClassD1 */ 0x0000, /* R36 */ 0x0100, /* R37 - ClassD3 */ - 0x0000, /* R38 */ + 0x0079, /* R38 - ClassD4 */ 0x0000, /* R39 - Input Mixer1 */ 0x0000, /* R40 - Input Mixer2 */ 0x0000, /* R41 - Input Mixer3 */ @@ -311,11 +311,15 @@ SOC_SINGLE("Speaker Mode Switch", WM8990_CLASSD1, WM8990_CDMODE_BIT, 1, 0), SOC_SINGLE("Speaker Output Attenuation Volume", WM8990_SPEAKER_VOLUME, - WM8990_SPKVOL_SHIFT, WM8990_SPKVOL_MASK, 0), + WM8990_SPKATTN_SHIFT, WM8990_SPKATTN_MASK, 0), SOC_SINGLE("Speaker DC Boost Volume", WM8990_CLASSD3, WM8990_DCGAIN_SHIFT, WM8990_DCGAIN_MASK, 0), SOC_SINGLE("Speaker AC Boost Volume", WM8990_CLASSD3, WM8990_ACGAIN_SHIFT, WM8990_ACGAIN_MASK, 0), +SOC_SINGLE_TLV("Speaker Volume", WM8990_CLASSD4, + WM8990_SPKVOL_SHIFT, WM8990_SPKVOL_MASK, 0, out_pga_tlv), +SOC_SINGLE("Speaker ZC Switch", WM8990_CLASSD4, + WM8990_SPKZC_SHIFT, WM8990_SPKZC_MASK, 0), SOC_WM899X_OUTPGA_SINGLE_R_TLV("Left DAC Digital Volume", WM8990_LEFT_DAC_DIGITAL_VOLUME, @@ -920,7 +924,7 @@ static const struct snd_soc_dapm_route audio_map[] = { {"SPKMIX", "SPKMIX Left Mixer PGA Switch", "LOPGA"}, {"SPKMIX", "SPKMIX Right Mixer PGA Switch", "ROPGA"}, {"SPKMIX", "SPKMIX Right DAC Switch", "Right DAC"}, - {"SPKMIX", "SPKMIX Left DAC Switch", "Right DAC"}, + {"SPKMIX", "SPKMIX Left DAC Switch", "Left DAC"}, /* LONMIX */ {"LONMIX", "LONMIX Left Mixer PGA Switch", "LOPGA"}, @@ -1496,10 +1500,9 @@ static int wm8990_codec_probe(struct i2c_adapter *adap, int addr, int kind) client_template.addr = addr; i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL); - if (i2c == NULL) { - kfree(codec); + if (i2c == NULL) return -ENOMEM; - } + i2c_set_clientdata(i2c, codec); codec->control_data = i2c; @@ -1517,7 +1520,6 @@ static int wm8990_codec_probe(struct i2c_adapter *adap, int addr, int kind) return ret; err: - kfree(codec); kfree(i2c); return ret; } @@ -1591,6 +1593,11 @@ static int wm8990_probe(struct platform_device *pdev) #else /* Add other interfaces here */ #endif + + if (ret != 0) { + kfree(codec->private_data); + kfree(codec); + } return ret; } diff --git a/sound/soc/codecs/wm8990.h b/sound/soc/codecs/wm8990.h index 6bea5748528..0a08325d544 100644 --- a/sound/soc/codecs/wm8990.h +++ b/sound/soc/codecs/wm8990.h @@ -54,6 +54,7 @@ #define WM8990_SPEAKER_VOLUME 0x22 #define WM8990_CLASSD1 0x23 #define WM8990_CLASSD3 0x25 +#define WM8990_CLASSD4 0x26 #define WM8990_INPUT_MIXER1 0x27 #define WM8990_INPUT_MIXER2 0x28 #define WM8990_INPUT_MIXER3 0x29 @@ -528,8 +529,8 @@ /* * R34 (0x22) - Speaker Volume */ -#define WM8990_SPKVOL_MASK 0x0003 /* SPKVOL - [1:0] */ -#define WM8990_SPKVOL_SHIFT 0 +#define WM8990_SPKATTN_MASK 0x0003 /* SPKATTN - [1:0] */ +#define WM8990_SPKATTN_SHIFT 0 /* * R35 (0x23) - ClassD1 @@ -544,6 +545,15 @@ #define WM8990_DCGAIN_SHIFT 3 #define WM8990_ACGAIN_MASK 0x0007 /* ACGAIN - [2:0] */ #define WM8990_ACGAIN_SHIFT 0 + +/* + * R38 (0x26) - ClassD4 + */ +#define WM8990_SPKZC_MASK 0x0001 /* SPKZC */ +#define WM8990_SPKZC_SHIFT 7 /* SPKZC */ +#define WM8990_SPKVOL_MASK 0x007F /* SPKVOL - [6:0] */ +#define WM8990_SPKVOL_SHIFT 0 /* SPKVOL - [6:0] */ + /* * R39 (0x27) - Input Mixer1 */ diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index 1fb7f9a7aec..2f1c91b1d55 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c @@ -13,7 +13,6 @@ #include <linux/init.h> #include <linux/module.h> -#include <linux/version.h> #include <linux/kernel.h> #include <linux/device.h> #include <sound/core.h> diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c index 5e2c306399e..65fdbd81a37 100644 --- a/sound/soc/davinci/davinci-evm.c +++ b/sound/soc/davinci/davinci-evm.c @@ -19,9 +19,8 @@ #include <sound/soc.h> #include <sound/soc-dapm.h> -#include <asm/mach-types.h> #include <asm/dma.h> -#include <asm/arch/hardware.h> +#include <mach/hardware.h> #include "../codecs/tlv320aic3x.h" #include "davinci-pcm.h" diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c index da2bc590286..d2d3da9729f 100644 --- a/sound/soc/fsl/fsl_dma.c +++ b/sound/soc/fsl/fsl_dma.c @@ -132,12 +132,17 @@ struct fsl_dma_private { * Since each link descriptor has a 32-bit byte count field, we set * period_bytes_max to the largest 32-bit number. We also have no maximum * number of periods. + * + * Note that we specify SNDRV_PCM_INFO_JOINT_DUPLEX here, but only because a + * limitation in the SSI driver requires the sample rates for playback and + * capture to be the same. */ static const struct snd_pcm_hardware fsl_dma_hardware = { .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_MMAP_VALID, + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_JOINT_DUPLEX, .formats = FSLDMA_PCM_FORMATS, .rates = FSLDMA_PCM_RATES, .rate_min = 5512, @@ -322,14 +327,75 @@ static int fsl_dma_new(struct snd_card *card, struct snd_soc_dai *dai, * fsl_dma_open: open a new substream. * * Each substream has its own DMA buffer. + * + * ALSA divides the DMA buffer into N periods. We create NUM_DMA_LINKS link + * descriptors that ping-pong from one period to the next. For example, if + * there are six periods and two link descriptors, this is how they look + * before playback starts: + * + * The last link descriptor + * ____________ points back to the first + * | | + * V | + * ___ ___ | + * | |->| |->| + * |___| |___| + * | | + * | | + * V V + * _________________________________________ + * | | | | | | | The DMA buffer is + * | | | | | | | divided into 6 parts + * |______|______|______|______|______|______| + * + * and here's how they look after the first period is finished playing: + * + * ____________ + * | | + * V | + * ___ ___ | + * | |->| |->| + * |___| |___| + * | | + * |______________ + * | | + * V V + * _________________________________________ + * | | | | | | | + * | | | | | | | + * |______|______|______|______|______|______| + * + * The first link descriptor now points to the third period. The DMA + * controller is currently playing the second period. When it finishes, it + * will jump back to the first descriptor and play the third period. + * + * There are four reasons we do this: + * + * 1. The only way to get the DMA controller to automatically restart the + * transfer when it gets to the end of the buffer is to use chaining + * mode. Basic direct mode doesn't offer that feature. + * 2. We need to receive an interrupt at the end of every period. The DMA + * controller can generate an interrupt at the end of every link transfer + * (aka segment). Making each period into a DMA segment will give us the + * interrupts we need. + * 3. By creating only two link descriptors, regardless of the number of + * periods, we do not need to reallocate the link descriptors if the + * number of periods changes. + * 4. All of the audio data is still stored in a single, contiguous DMA + * buffer, which is what ALSA expects. We're just dividing it into + * contiguous parts, and creating a link descriptor for each one. */ static int fsl_dma_open(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct fsl_dma_private *dma_private; + struct ccsr_dma_channel __iomem *dma_channel; dma_addr_t ld_buf_phys; + u64 temp_link; /* Pointer to next link descriptor */ + u32 mr; unsigned int channel; int ret = 0; + unsigned int i; /* * Reject any DMA buffer whose size is not a multiple of the period @@ -390,68 +456,74 @@ static int fsl_dma_open(struct snd_pcm_substream *substream) snd_soc_set_runtime_hwparams(substream, &fsl_dma_hardware); runtime->private_data = dma_private; + /* Program the fixed DMA controller parameters */ + + dma_channel = dma_private->dma_channel; + + temp_link = dma_private->ld_buf_phys + + sizeof(struct fsl_dma_link_descriptor); + + for (i = 0; i < NUM_DMA_LINKS; i++) { + struct fsl_dma_link_descriptor *link = &dma_private->link[i]; + + link->source_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP); + link->dest_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP); + link->next = cpu_to_be64(temp_link); + + temp_link += sizeof(struct fsl_dma_link_descriptor); + } + /* The last link descriptor points to the first */ + dma_private->link[i - 1].next = cpu_to_be64(dma_private->ld_buf_phys); + + /* Tell the DMA controller where the first link descriptor is */ + out_be32(&dma_channel->clndar, + CCSR_DMA_CLNDAR_ADDR(dma_private->ld_buf_phys)); + out_be32(&dma_channel->eclndar, + CCSR_DMA_ECLNDAR_ADDR(dma_private->ld_buf_phys)); + + /* The manual says the BCR must be clear before enabling EMP */ + out_be32(&dma_channel->bcr, 0); + + /* + * Program the mode register for interrupts, external master control, + * and source/destination hold. Also clear the Channel Abort bit. + */ + mr = in_be32(&dma_channel->mr) & + ~(CCSR_DMA_MR_CA | CCSR_DMA_MR_DAHE | CCSR_DMA_MR_SAHE); + + /* + * We want External Master Start and External Master Pause enabled, + * because the SSI is controlling the DMA controller. We want the DMA + * controller to be set up in advance, and then we signal only the SSI + * to start transferring. + * + * We want End-Of-Segment Interrupts enabled, because this will generate + * an interrupt at the end of each segment (each link descriptor + * represents one segment). Each DMA segment is the same thing as an + * ALSA period, so this is how we get an interrupt at the end of every + * period. + * + * We want Error Interrupt enabled, so that we can get an error if + * the DMA controller is mis-programmed somehow. + */ + mr |= CCSR_DMA_MR_EOSIE | CCSR_DMA_MR_EIE | CCSR_DMA_MR_EMP_EN | + CCSR_DMA_MR_EMS_EN; + + /* For playback, we want the destination address to be held. For + capture, set the source address to be held. */ + mr |= (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? + CCSR_DMA_MR_DAHE : CCSR_DMA_MR_SAHE; + + out_be32(&dma_channel->mr, mr); + return 0; } /** - * fsl_dma_hw_params: allocate the DMA buffer and the DMA link descriptors. + * fsl_dma_hw_params: continue initializing the DMA links * - * ALSA divides the DMA buffer into N periods. We create NUM_DMA_LINKS link - * descriptors that ping-pong from one period to the next. For example, if - * there are six periods and two link descriptors, this is how they look - * before playback starts: - * - * The last link descriptor - * ____________ points back to the first - * | | - * V | - * ___ ___ | - * | |->| |->| - * |___| |___| - * | | - * | | - * V V - * _________________________________________ - * | | | | | | | The DMA buffer is - * | | | | | | | divided into 6 parts - * |______|______|______|______|______|______| - * - * and here's how they look after the first period is finished playing: - * - * ____________ - * | | - * V | - * ___ ___ | - * | |->| |->| - * |___| |___| - * | | - * |______________ - * | | - * V V - * _________________________________________ - * | | | | | | | - * | | | | | | | - * |______|______|______|______|______|______| - * - * The first link descriptor now points to the third period. The DMA - * controller is currently playing the second period. When it finishes, it - * will jump back to the first descriptor and play the third period. - * - * There are four reasons we do this: - * - * 1. The only way to get the DMA controller to automatically restart the - * transfer when it gets to the end of the buffer is to use chaining - * mode. Basic direct mode doesn't offer that feature. - * 2. We need to receive an interrupt at the end of every period. The DMA - * controller can generate an interrupt at the end of every link transfer - * (aka segment). Making each period into a DMA segment will give us the - * interrupts we need. - * 3. By creating only two link descriptors, regardless of the number of - * periods, we do not need to reallocate the link descriptors if the - * number of periods changes. - * 4. All of the audio data is still stored in a single, contiguous DMA - * buffer, which is what ALSA expects. We're just dividing it into - * contiguous parts, and creating a link descriptor for each one. + * This function obtains hardware parameters about the opened stream and + * programs the DMA controller accordingly. * * Note that due to a quirk of the SSI's STX register, the target address * for the DMA operations depends on the sample size. So we don't program @@ -463,11 +535,8 @@ static int fsl_dma_hw_params(struct snd_pcm_substream *substream, { struct snd_pcm_runtime *runtime = substream->runtime; struct fsl_dma_private *dma_private = runtime->private_data; - struct ccsr_dma_channel __iomem *dma_channel = dma_private->dma_channel; dma_addr_t temp_addr; /* Pointer to next period */ - u64 temp_link; /* Pointer to next link descriptor */ - u32 mr; /* Temporary variable for MR register */ unsigned int i; @@ -485,8 +554,6 @@ static int fsl_dma_hw_params(struct snd_pcm_substream *substream, dma_private->dma_buf_next = dma_private->dma_buf_phys; /* - * Initialize each link descriptor. - * * The actual address in STX0 (destination for playback, source for * capture) is based on the sample size, but we don't know the sample * size in this function, so we'll have to adjust that later. See @@ -502,16 +569,11 @@ static int fsl_dma_hw_params(struct snd_pcm_substream *substream, * buffer itself. */ temp_addr = substream->dma_buffer.addr; - temp_link = dma_private->ld_buf_phys + - sizeof(struct fsl_dma_link_descriptor); for (i = 0; i < NUM_DMA_LINKS; i++) { struct fsl_dma_link_descriptor *link = &dma_private->link[i]; link->count = cpu_to_be32(period_size); - link->source_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP); - link->dest_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP); - link->next = cpu_to_be64(temp_link); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) link->source_addr = cpu_to_be32(temp_addr); @@ -519,51 +581,7 @@ static int fsl_dma_hw_params(struct snd_pcm_substream *substream, link->dest_addr = cpu_to_be32(temp_addr); temp_addr += period_size; - temp_link += sizeof(struct fsl_dma_link_descriptor); } - /* The last link descriptor points to the first */ - dma_private->link[i - 1].next = cpu_to_be64(dma_private->ld_buf_phys); - - /* Tell the DMA controller where the first link descriptor is */ - out_be32(&dma_channel->clndar, - CCSR_DMA_CLNDAR_ADDR(dma_private->ld_buf_phys)); - out_be32(&dma_channel->eclndar, - CCSR_DMA_ECLNDAR_ADDR(dma_private->ld_buf_phys)); - - /* The manual says the BCR must be clear before enabling EMP */ - out_be32(&dma_channel->bcr, 0); - - /* - * Program the mode register for interrupts, external master control, - * and source/destination hold. Also clear the Channel Abort bit. - */ - mr = in_be32(&dma_channel->mr) & - ~(CCSR_DMA_MR_CA | CCSR_DMA_MR_DAHE | CCSR_DMA_MR_SAHE); - - /* - * We want External Master Start and External Master Pause enabled, - * because the SSI is controlling the DMA controller. We want the DMA - * controller to be set up in advance, and then we signal only the SSI - * to start transfering. - * - * We want End-Of-Segment Interrupts enabled, because this will generate - * an interrupt at the end of each segment (each link descriptor - * represents one segment). Each DMA segment is the same thing as an - * ALSA period, so this is how we get an interrupt at the end of every - * period. - * - * We want Error Interrupt enabled, so that we can get an error if - * the DMA controller is mis-programmed somehow. - */ - mr |= CCSR_DMA_MR_EOSIE | CCSR_DMA_MR_EIE | CCSR_DMA_MR_EMP_EN | - CCSR_DMA_MR_EMS_EN; - - /* For playback, we want the destination address to be held. For - capture, set the source address to be held. */ - mr |= (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? - CCSR_DMA_MR_DAHE : CCSR_DMA_MR_SAHE; - - out_be32(&dma_channel->mr, mr); return 0; } diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 71bff33f552..157a7895ffa 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -67,6 +67,8 @@ * @ssi: pointer to the SSI's registers * @ssi_phys: physical address of the SSI registers * @irq: IRQ of this SSI + * @first_stream: pointer to the stream that was opened first + * @second_stream: pointer to second stream * @dev: struct device pointer * @playback: the number of playback streams opened * @capture: the number of capture streams opened @@ -79,6 +81,8 @@ struct fsl_ssi_private { struct ccsr_ssi __iomem *ssi; dma_addr_t ssi_phys; unsigned int irq; + struct snd_pcm_substream *first_stream; + struct snd_pcm_substream *second_stream; struct device *dev; unsigned int playback; unsigned int capture; @@ -342,6 +346,49 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream) */ } + if (!ssi_private->first_stream) + ssi_private->first_stream = substream; + else { + /* This is the second stream open, so we need to impose sample + * rate and maybe sample size constraints. Note that this can + * cause a race condition if the second stream is opened before + * the first stream is fully initialized. + * + * We provide some protection by checking to make sure the first + * stream is initialized, but it's not perfect. ALSA sometimes + * re-initializes the driver with a different sample rate or + * size. If the second stream is opened before the first stream + * has received its final parameters, then the second stream may + * be constrained to the wrong sample rate or size. + * + * FIXME: This code does not handle opening and closing streams + * repeatedly. If you open two streams and then close the first + * one, you may not be able to open another stream until you + * close the second one as well. + */ + struct snd_pcm_runtime *first_runtime = + ssi_private->first_stream->runtime; + + if (!first_runtime->rate || !first_runtime->sample_bits) { + dev_err(substream->pcm->card->dev, + "set sample rate and size in %s stream first\n", + substream->stream == SNDRV_PCM_STREAM_PLAYBACK + ? "capture" : "playback"); + return -EAGAIN; + } + + snd_pcm_hw_constraint_minmax(substream->runtime, + SNDRV_PCM_HW_PARAM_RATE, + first_runtime->rate, first_runtime->rate); + + snd_pcm_hw_constraint_minmax(substream->runtime, + SNDRV_PCM_HW_PARAM_SAMPLE_BITS, + first_runtime->sample_bits, + first_runtime->sample_bits); + + ssi_private->second_stream = substream; + } + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ssi_private->playback++; @@ -371,18 +418,16 @@ static int fsl_ssi_prepare(struct snd_pcm_substream *substream) struct fsl_ssi_private *ssi_private = rtd->dai->cpu_dai->private_data; struct ccsr_ssi __iomem *ssi = ssi_private->ssi; - u32 wl; - wl = CCSR_SSI_SxCCR_WL(snd_pcm_format_width(runtime->format)); + if (substream == ssi_private->first_stream) { + u32 wl; - clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN); + /* The SSI should always be disabled at this points (SSIEN=0) */ + wl = CCSR_SSI_SxCCR_WL(snd_pcm_format_width(runtime->format)); - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + /* In synchronous mode, the SSI uses STCCR for capture */ clrsetbits_be32(&ssi->stccr, CCSR_SSI_SxCCR_WL_MASK, wl); - else - clrsetbits_be32(&ssi->srccr, CCSR_SSI_SxCCR_WL_MASK, wl); - - setbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN); + } return 0; } @@ -407,9 +452,13 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd) case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - setbits32(&ssi->scr, CCSR_SSI_SCR_TE); + clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN); + setbits32(&ssi->scr, + CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE); } else { - setbits32(&ssi->scr, CCSR_SSI_SCR_RE); + clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN); + setbits32(&ssi->scr, + CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_RE); /* * I think we need this delay to allow time for the SSI @@ -452,6 +501,11 @@ static void fsl_ssi_shutdown(struct snd_pcm_substream *substream) if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) ssi_private->capture--; + if (ssi_private->first_stream == substream) + ssi_private->first_stream = ssi_private->second_stream; + + ssi_private->second_stream = NULL; + /* * If this is the last active substream, disable the SSI and release * the IRQ. diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c index 02cec96859b..87d0ed01f65 100644 --- a/sound/soc/omap/n810.c +++ b/sound/soc/omap/n810.c @@ -29,9 +29,9 @@ #include <sound/soc-dapm.h> #include <asm/mach-types.h> -#include <asm/arch/hardware.h> +#include <mach/hardware.h> #include <linux/gpio.h> -#include <asm/arch/mcbsp.h> +#include <mach/mcbsp.h> #include "omap-mcbsp.h" #include "omap-pcm.h" @@ -329,12 +329,14 @@ static int __init n810_soc_init(void) sys_clkout2_src = clk_get(dev, "sys_clkout2_src"); if (IS_ERR(sys_clkout2_src)) { dev_err(dev, "Could not get sys_clkout2_src clock\n"); - return -ENODEV; + err = PTR_ERR(sys_clkout2_src); + goto err2; } sys_clkout2 = clk_get(dev, "sys_clkout2"); if (IS_ERR(sys_clkout2)) { dev_err(dev, "Could not get sys_clkout2\n"); - goto err1; + err = PTR_ERR(sys_clkout2); + goto err3; } /* * Configure 12 MHz output on SYS_CLKOUT2. Therefore we must use @@ -343,7 +345,8 @@ static int __init n810_soc_init(void) func96m_clk = clk_get(dev, "func_96m_ck"); if (IS_ERR(func96m_clk)) { dev_err(dev, "Could not get func 96M clock\n"); - goto err2; + err = PTR_ERR(func96m_clk); + goto err4; } clk_set_parent(sys_clkout2_src, func96m_clk); clk_set_rate(sys_clkout2, 12000000); @@ -356,20 +359,25 @@ static int __init n810_soc_init(void) gpio_direction_output(N810_SPEAKER_AMP_GPIO, 0); return 0; -err2: +err4: clk_put(sys_clkout2); +err3: + clk_put(sys_clkout2_src); +err2: platform_device_del(n810_snd_device); err1: platform_device_put(n810_snd_device); return err; - } static void __exit n810_soc_exit(void) { gpio_free(N810_SPEAKER_AMP_GPIO); gpio_free(N810_HEADSET_AMP_GPIO); + clk_put(sys_clkout2_src); + clk_put(sys_clkout2); + clk_put(func96m_clk); platform_device_unregister(n810_snd_device); } diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c index 00b0c9d73cd..35310e16d7f 100644 --- a/sound/soc/omap/omap-mcbsp.c +++ b/sound/soc/omap/omap-mcbsp.c @@ -30,9 +30,9 @@ #include <sound/initval.h> #include <sound/soc.h> -#include <asm/arch/control.h> -#include <asm/arch/dma.h> -#include <asm/arch/mcbsp.h> +#include <mach/control.h> +#include <mach/dma.h> +#include <mach/mcbsp.h> #include "omap-mcbsp.h" #include "omap-pcm.h" diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c index e092f3d836d..690bfeaec4a 100644 --- a/sound/soc/omap/omap-pcm.c +++ b/sound/soc/omap/omap-pcm.c @@ -27,7 +27,7 @@ #include <sound/pcm_params.h> #include <sound/soc.h> -#include <asm/arch/dma.h> +#include <mach/dma.h> #include "omap-pcm.h" static const struct snd_pcm_hardware omap_pcm_hardware = { diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c index c0294464a23..0a53f72077f 100644 --- a/sound/soc/pxa/corgi.c +++ b/sound/soc/pxa/corgi.c @@ -25,10 +25,10 @@ #include <asm/mach-types.h> #include <asm/hardware/scoop.h> -#include <asm/arch/pxa-regs.h> -#include <asm/arch/hardware.h> -#include <asm/arch/corgi.h> -#include <asm/arch/audio.h> +#include <mach/pxa-regs.h> +#include <mach/hardware.h> +#include <mach/corgi.h> +#include <mach/audio.h> #include "../codecs/wm8731.h" #include "pxa2xx-pcm.h" diff --git a/sound/soc/pxa/e800_wm9712.c b/sound/soc/pxa/e800_wm9712.c index 06e8afb2527..6781c5be242 100644 --- a/sound/soc/pxa/e800_wm9712.c +++ b/sound/soc/pxa/e800_wm9712.c @@ -21,9 +21,9 @@ #include <sound/soc-dapm.h> #include <asm/mach-types.h> -#include <asm/arch/pxa-regs.h> -#include <asm/arch/hardware.h> -#include <asm/arch/audio.h> +#include <mach/pxa-regs.h> +#include <mach/hardware.h> +#include <mach/audio.h> #include "../codecs/wm9712.h" #include "pxa2xx-pcm.h" diff --git a/sound/soc/pxa/em-x270.c b/sound/soc/pxa/em-x270.c index 02dcac39cdf..d9c3f7b28be 100644 --- a/sound/soc/pxa/em-x270.c +++ b/sound/soc/pxa/em-x270.c @@ -30,9 +30,9 @@ #include <sound/soc-dapm.h> #include <asm/mach-types.h> -#include <asm/arch/pxa-regs.h> -#include <asm/arch/hardware.h> -#include <asm/arch/audio.h> +#include <mach/pxa-regs.h> +#include <mach/hardware.h> +#include <mach/audio.h> #include "../codecs/wm9712.h" #include "pxa2xx-pcm.h" diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c index 65a4e9a8c39..a4697f7e292 100644 --- a/sound/soc/pxa/poodle.c +++ b/sound/soc/pxa/poodle.c @@ -26,10 +26,10 @@ #include <asm/mach-types.h> #include <asm/hardware/locomo.h> -#include <asm/arch/pxa-regs.h> -#include <asm/arch/hardware.h> -#include <asm/arch/poodle.h> -#include <asm/arch/audio.h> +#include <mach/pxa-regs.h> +#include <mach/hardware.h> +#include <mach/poodle.h> +#include <mach/audio.h> #include "../codecs/wm8731.h" #include "pxa2xx-pcm.h" @@ -85,17 +85,13 @@ static int poodle_startup(struct snd_pcm_substream *substream) } /* we need to unmute the HP at shutdown as the mute burns power on poodle */ -static int poodle_shutdown(struct snd_pcm_substream *substream) +static void poodle_shutdown(struct snd_pcm_substream *substream) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec *codec = rtd->socdev->codec; - /* set = unmute headphone */ locomo_gpio_write(&poodle_locomo_device.dev, POODLE_LOCOMO_GPIO_MUTE_L, 1); locomo_gpio_write(&poodle_locomo_device.dev, POODLE_LOCOMO_GPIO_MUTE_R, 1); - return 0; } static int poodle_hw_params(struct snd_pcm_substream *substream, @@ -232,7 +228,7 @@ static const struct soc_enum poodle_enum[] = { SOC_ENUM_SINGLE_EXT(2, spk_function), }; -static const snd_kcontrol_new_t wm8731_poodle_controls[] = { +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, diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c index 059af815ea0..d94a495bd6b 100644 --- a/sound/soc/pxa/pxa2xx-ac97.c +++ b/sound/soc/pxa/pxa2xx-ac97.c @@ -26,10 +26,10 @@ #include <asm/irq.h> #include <linux/mutex.h> -#include <asm/hardware.h> -#include <asm/arch/pxa-regs.h> -#include <asm/arch/pxa2xx-gpio.h> -#include <asm/arch/audio.h> +#include <mach/hardware.h> +#include <mach/pxa-regs.h> +#include <mach/pxa2xx-gpio.h> +#include <mach/audio.h> #include "pxa2xx-pcm.h" #include "pxa2xx-ac97.h" diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c index 8f96d87f7b4..8548818eea0 100644 --- a/sound/soc/pxa/pxa2xx-i2s.c +++ b/sound/soc/pxa/pxa2xx-i2s.c @@ -21,10 +21,10 @@ #include <sound/initval.h> #include <sound/soc.h> -#include <asm/hardware.h> -#include <asm/arch/pxa-regs.h> -#include <asm/arch/pxa2xx-gpio.h> -#include <asm/arch/audio.h> +#include <mach/hardware.h> +#include <mach/pxa-regs.h> +#include <mach/pxa2xx-gpio.h> +#include <mach/audio.h> #include "pxa2xx-pcm.h" #include "pxa2xx-i2s.h" diff --git a/sound/soc/pxa/pxa2xx-pcm.c b/sound/soc/pxa/pxa2xx-pcm.c index 2df03ee5819..4345f387fe4 100644 --- a/sound/soc/pxa/pxa2xx-pcm.c +++ b/sound/soc/pxa/pxa2xx-pcm.c @@ -22,9 +22,9 @@ #include <sound/soc.h> #include <asm/dma.h> -#include <asm/hardware.h> -#include <asm/arch/pxa-regs.h> -#include <asm/arch/audio.h> +#include <mach/hardware.h> +#include <mach/pxa-regs.h> +#include <mach/audio.h> #include "pxa2xx-pcm.h" diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c index 64385797da5..37cb768fc93 100644 --- a/sound/soc/pxa/spitz.c +++ b/sound/soc/pxa/spitz.c @@ -26,10 +26,10 @@ #include <asm/mach-types.h> #include <asm/hardware/scoop.h> -#include <asm/arch/pxa-regs.h> -#include <asm/arch/hardware.h> -#include <asm/arch/akita.h> -#include <asm/arch/spitz.h> +#include <mach/pxa-regs.h> +#include <mach/hardware.h> +#include <mach/akita.h> +#include <mach/spitz.h> #include "../codecs/wm8750.h" #include "pxa2xx-pcm.h" #include "pxa2xx-i2s.h" @@ -297,7 +297,7 @@ static int spitz_wm8750_init(struct snd_soc_codec *codec) snd_soc_dapm_disable_pin(codec, "LINPUT3"); snd_soc_dapm_disable_pin(codec, "RINPUT3"); snd_soc_dapm_disable_pin(codec, "OUT3"); - snd_soc_dapm_disable_pin(codec, "MONO"); + snd_soc_dapm_disable_pin(codec, "MONO1"); /* Add spitz specific controls */ for (i = 0; i < ARRAY_SIZE(wm8750_spitz_controls); i++) { diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c index fe6cca9c9e7..2baaa750f12 100644 --- a/sound/soc/pxa/tosa.c +++ b/sound/soc/pxa/tosa.c @@ -29,11 +29,10 @@ #include <sound/soc-dapm.h> #include <asm/mach-types.h> -#include <asm/arch/tosa.h> -#include <asm/arch/pxa-regs.h> -#include <asm/arch/hardware.h> -#include <asm/arch/audio.h> -#include <asm/arch/tosa.h> +#include <mach/tosa.h> +#include <mach/pxa-regs.h> +#include <mach/hardware.h> +#include <mach/audio.h> #include "../codecs/wm9712.h" #include "pxa2xx-pcm.h" diff --git a/sound/soc/s3c24xx/neo1973_wm8753.c b/sound/soc/s3c24xx/neo1973_wm8753.c index 4d7a9aa15f1..8089f8ee05c 100644 --- a/sound/soc/s3c24xx/neo1973_wm8753.c +++ b/sound/soc/s3c24xx/neo1973_wm8753.c @@ -24,14 +24,13 @@ #include <sound/soc-dapm.h> #include <sound/tlv.h> -#include <asm/mach-types.h> #include <asm/hardware/scoop.h> -#include <asm/arch/regs-clock.h> -#include <asm/arch/regs-gpio.h> -#include <asm/hardware.h> -#include <asm/arch/audio.h> +#include <mach/regs-clock.h> +#include <mach/regs-gpio.h> +#include <mach/hardware.h> +#include <mach/audio.h> #include <linux/io.h> -#include <asm/arch/spi-gpio.h> +#include <mach/spi-gpio.h> #include <asm/plat-s3c24xx/regs-iis.h> diff --git a/sound/soc/s3c24xx/s3c2412-i2s.c b/sound/soc/s3c24xx/s3c2412-i2s.c index ee4676ed128..ded7d995a92 100644 --- a/sound/soc/s3c24xx/s3c2412-i2s.c +++ b/sound/soc/s3c24xx/s3c2412-i2s.c @@ -28,16 +28,16 @@ #include <sound/pcm_params.h> #include <sound/initval.h> #include <sound/soc.h> -#include <asm/hardware.h> +#include <mach/hardware.h> #include <linux/io.h> #include <asm/dma.h> #include <asm/plat-s3c24xx/regs-s3c2412-iis.h> -#include <asm/arch/regs-gpio.h> -#include <asm/arch/audio.h> -#include <asm/arch/dma.h> +#include <mach/regs-gpio.h> +#include <mach/audio.h> +#include <mach/dma.h> #include "s3c24xx-pcm.h" #include "s3c2412-i2s.h" diff --git a/sound/soc/s3c24xx/s3c2443-ac97.c b/sound/soc/s3c24xx/s3c2443-ac97.c index 783349b7fed..19c5c3cf5d8 100644 --- a/sound/soc/s3c24xx/s3c2443-ac97.c +++ b/sound/soc/s3c24xx/s3c2443-ac97.c @@ -27,13 +27,13 @@ #include <sound/initval.h> #include <sound/soc.h> -#include <asm/hardware.h> +#include <mach/hardware.h> #include <asm/plat-s3c/regs-ac97.h> -#include <asm/arch/regs-gpio.h> -#include <asm/arch/regs-clock.h> -#include <asm/arch/audio.h> +#include <mach/regs-gpio.h> +#include <mach/regs-clock.h> +#include <mach/audio.h> #include <asm/dma.h> -#include <asm/arch/dma.h> +#include <mach/dma.h> #include "s3c24xx-pcm.h" #include "s3c24xx-ac97.h" diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.c b/sound/soc/s3c24xx/s3c24xx-i2s.c index 397524282b5..ba4476b55fb 100644 --- a/sound/soc/s3c24xx/s3c24xx-i2s.c +++ b/sound/soc/s3c24xx/s3c24xx-i2s.c @@ -27,12 +27,12 @@ #include <sound/initval.h> #include <sound/soc.h> -#include <asm/hardware.h> -#include <asm/arch/regs-gpio.h> -#include <asm/arch/regs-clock.h> -#include <asm/arch/audio.h> +#include <mach/hardware.h> +#include <mach/regs-gpio.h> +#include <mach/regs-clock.h> +#include <mach/audio.h> #include <asm/dma.h> -#include <asm/arch/dma.h> +#include <mach/dma.h> #include <asm/plat-s3c24xx/regs-iis.h> diff --git a/sound/soc/s3c24xx/s3c24xx-pcm.c b/sound/soc/s3c24xx/s3c24xx-pcm.c index cef79b34dc6..e13e614bada 100644 --- a/sound/soc/s3c24xx/s3c24xx-pcm.c +++ b/sound/soc/s3c24xx/s3c24xx-pcm.c @@ -27,9 +27,9 @@ #include <sound/soc.h> #include <asm/dma.h> -#include <asm/hardware.h> -#include <asm/arch/dma.h> -#include <asm/arch/audio.h> +#include <mach/hardware.h> +#include <mach/dma.h> +#include <mach/audio.h> #include "s3c24xx-pcm.h" diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 820347c9ae4..f9d100bc847 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -470,6 +470,7 @@ int dapm_reg_event(struct snd_soc_dapm_widget *w, return 0; } +EXPORT_SYMBOL_GPL(dapm_reg_event); /* * Scan each dapm widget for complete audio path. |