sound updates for 4.11-rc1
here is the update of sound bits for 4.11: again at this time, no big changes in ALSA and ASoC core but only cosmetic changes like consitifaction. Meanwhile, quite a lot of developments are seen in a few driver side. ALSA Core: - Clean up, consitification of some ops HD-audio: - A slight behavior change of single_cmd option - Quirks for AmigaOne X1000, Samsung Ativ Book 8, Dell AiO, ALC221 HP, and fixes for Lewisburg controller - Realtek ALC299, ALC1220 codecs Others: - USB-audio: Tascam US-16x08 DSP mixer quirk - Intel HDMI LPE audio support for Baytrail / Cherrytrail; this contains some updates in drm/i915 for the new platform binding ASoC: - Lots of updates in Intel drivers, mostly for DisplayPort and HDMI on Skylake and onwards, as well as more Baytrail / Cherrytrail boards support - Channel mapping support for HDMI - Support for AllWinner A31 and A33, Everest Semiconductor ES8328, Nuvoton NAU8540. -----BEGIN PGP SIGNATURE----- iQJCBAABCAAsFiEECxfAB4MH3rD5mfB6bDGAVD0pKaQFAlivCQkOHHRpd2FpQHN1 c2UuZGUACgkQbDGAVD0pKaTA9xAAgMpLZ7K7vBRlPKQAObPLf7ufciA5gDj+L6Lt 5octKSAql5uuqU06nHyQd5BLXYmGj5Qe7+/fkfWJYNeOwUkHroi/G44DbGNIEG8s sXXStcEkOKdZw30G/fzMoDgoggqjWy6gAFgtSjhPkHwfnbmF1nFmeUJ9/so7y/Oc Q0l4Pdsg5t4fTZcejZyLHBLdFJ2EhsYWVoJpa1Wqrv2eChMvKq1s59i0EW0Gyw4u kHe/COcbMIHf0yZKEcxlsN6BsAe7ik7/mGZYozL05+9HfaOIdJfU7oqJmQyPV2hm BVDHVmhi9rMTJ//9WA4lOa8wwpojumoM2AMbzQGczBmGjQU1KguI2rS5FhGipz4c mYpAnEESpB19//pKdEK8oBNPldfZyCuyTOBFVAPFp8TpHvaJEoNOyEg1UAn1crpE f77OMok6/6DuOcapr76TxSHwg2ewWjsxRi8NrOUML/1uxaKTplSP1AsXBLCExQi1 YnHn4H0wZOlOfX/jfodBDW0n6+V8kyZuv/jXMEqBWsIVIHk5UUAlDJ9AR+5K3D9e pRDRRww7480byY5h2aXBJbI8JjePuYwhJQxbYfsz55QU5rvTBcQAAfN11wXmWGol wSKvDyYgR/Zw1c93+HLcNv9+Ff6Wl9sIJFXwufzYOo3hKIrVUbXHeV8GT0io39zv IwJoaTI= =1cdN -----END PGP SIGNATURE----- Merge tag 'sound-4.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound Pull sound updates from Takashi Iwai: "Here is the update of sound bits for 4.11: again at this time, no big changes in ALSA and ASoC core but only cosmetic changes like consitifaction. Meanwhile, quite a lot of developments are seen in a few driver side. ALSA Core: - Clean up, consitification of some ops HD-audio: - A slight behavior change of single_cmd option - Quirks for AmigaOne X1000, Samsung Ativ Book 8, Dell AiO, ALC221 HP, and fixes for Lewisburg controller - Realtek ALC299, ALC1220 codecs Others: - USB-audio: Tascam US-16x08 DSP mixer quirk - Intel HDMI LPE audio support for Baytrail / Cherrytrail; this contains some updates in drm/i915 for the new platform binding ASoC: - Lots of updates in Intel drivers, mostly for DisplayPort and HDMI on Skylake and onwards, as well as more Baytrail / Cherrytrail boards support - Channel mapping support for HDMI - Support for AllWinner A31 and A33, Everest Semiconductor ES8328, Nuvoton NAU8540. * tag 'sound-4.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (323 commits) ALSA: usb-audio: Tidy up mixer_us16x08.c ALSA: usb-audio: Fix memory leak and corruption in mixer_us16x08.c ALSA: usb-audio: purge needless variable length array ALSA: x86: hdmi: select CONFIG_SND_PCM ALSA: x86: Don't enable runtime PM as default ALSA: x86: Use runtime PM autosuspend ALSA: usb-audio: localize function without external linkage ALSA: usb-audio: localize one-referrer variable ALSA: usb-audio: Tascam US-16x08 DSP mixer quirk ALSA: emu10k1: constify snd_emux_operators structure ASoC: sun4i-spdif: drop unnessary snd_soc_unregister_component() ASoC: Intel: bxt: Add jack port initialize in bxt_rt298 machine ASoC: nau8825: automatic BCLK and LRC divde in master mode ASoC: hdac_hdmi: Add device id for Geminilake ASoC: Intel: Skylake: Add Geminlake IDs ASoC: rt298: Add DMI match for Geminilake reference platform ASoC: Intel: Skylake: Check device type to get endpoint configuration ASoC: Intel: bxt: Add jack port initialize in da7219_max98357a machine ASoC: Intel: Skylake: Add jack port initialize in nau88l25_ssm4567 machine ASoC: Intel: Skylake: Add jack port initialize in nau88l25_max98357a machine ...
This commit is contained in:
commit
28cbc335d2
|
@ -24,6 +24,8 @@ Optional properties:
|
|||
this parameter to choose where the clock from.
|
||||
- By default the clock is from TK pin, if the clock from RK pin, this
|
||||
property is needed.
|
||||
- #sound-dai-cells: Should contain <0>.
|
||||
- This property makes the SSC into an automatically registered DAI.
|
||||
|
||||
Examples:
|
||||
- PDC transfer:
|
||||
|
|
|
@ -2,8 +2,7 @@ Devicetree bindings for the Axentia TSE-850 audio complex
|
|||
|
||||
Required properties:
|
||||
- compatible: "axentia,tse850-pcm5142"
|
||||
- axentia,ssc-controller: The phandle of the atmel SSC controller used as
|
||||
cpu dai.
|
||||
- axentia,cpu-dai: The phandle of the cpu dai.
|
||||
- axentia,audio-codec: The phandle of the PCM5142 codec.
|
||||
- axentia,add-gpios: gpio specifier that controls the mixer.
|
||||
- axentia,loop1-gpios: gpio specifier that controls loop relays on channel 1.
|
||||
|
@ -43,6 +42,12 @@ the PCM5142 codec.
|
|||
|
||||
Example:
|
||||
|
||||
&ssc0 {
|
||||
#sound-dai-cells = <0>;
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&i2c {
|
||||
codec: pcm5142@4c {
|
||||
compatible = "ti,pcm5142";
|
||||
|
@ -77,7 +82,7 @@ Example:
|
|||
sound {
|
||||
compatible = "axentia,tse850-pcm5142";
|
||||
|
||||
axentia,ssc-controller = <&ssc0>;
|
||||
axentia,cpu-dai = <&ssc0>;
|
||||
axentia,audio-codec = <&codec>;
|
||||
|
||||
axentia,add-gpios = <&pioA 8 GPIO_ACTIVE_LOW>;
|
||||
|
|
|
@ -4,7 +4,7 @@ This device supports both I2C and SPI.
|
|||
|
||||
Required properties:
|
||||
|
||||
- compatible : "everest,es8328"
|
||||
- compatible : Should be "everest,es8328" or "everest,es8388"
|
||||
- DVDD-supply : Regulator providing digital core supply voltage 1.8 - 3.6V
|
||||
- AVDD-supply : Regulator providing analog supply voltage 3.3V
|
||||
- PVDD-supply : Regulator providing digital IO supply voltage 1.8 - 3.6V
|
||||
|
|
|
@ -4,6 +4,7 @@ Required properties:
|
|||
- compatible = "mediatek,mt2701-audio";
|
||||
- reg: register location and size
|
||||
- interrupts: Should contain AFE interrupt
|
||||
- power-domains: should define the power domain
|
||||
- clock-names: should have these clock names:
|
||||
"infra_sys_audio_clk",
|
||||
"top_audio_mux1_sel",
|
||||
|
@ -58,6 +59,7 @@ Example:
|
|||
<0 0x112A0000 0 0x20000>;
|
||||
interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_LOW>,
|
||||
<GIC_SPI 132 IRQ_TYPE_LEVEL_LOW>;
|
||||
power-domains = <&scpsys MT2701_POWER_DOMAIN_IFR_MSC>;
|
||||
clocks = <&infracfg CLK_INFRA_AUDIO>,
|
||||
<&topckgen CLK_TOP_AUD_MUX1_SEL>,
|
||||
<&topckgen CLK_TOP_AUD_MUX2_SEL>,
|
||||
|
|
16
Documentation/devicetree/bindings/sound/nau8540.txt
Normal file
16
Documentation/devicetree/bindings/sound/nau8540.txt
Normal file
|
@ -0,0 +1,16 @@
|
|||
NAU85L40 audio CODEC
|
||||
|
||||
This device supports I2C only.
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : "nuvoton,nau8540"
|
||||
|
||||
- reg : the I2C address of the device.
|
||||
|
||||
Example:
|
||||
|
||||
codec: nau8540@1c {
|
||||
compatible = "nuvoton,nau8540";
|
||||
reg = <0x1c>;
|
||||
};
|
|
@ -0,0 +1,36 @@
|
|||
ROCKCHIP RK3288 with HDMI and analog audio
|
||||
|
||||
Required properties:
|
||||
- compatible: "rockchip,rk3288-hdmi-analog"
|
||||
- rockchip,model: The user-visible name of this sound complex
|
||||
- rockchip,i2s-controller: The phandle of the Rockchip I2S controller that's
|
||||
connected to the CODEC
|
||||
- rockchip,audio-codec: The phandle of the analog audio codec.
|
||||
- rockchip,routing: A list of the connections between audio components.
|
||||
Each entry is a pair of strings, the first being the
|
||||
connection's sink, the second being the connection's
|
||||
source. For this driver the first string should always be
|
||||
"Analog".
|
||||
|
||||
Optionnal properties:
|
||||
- rockchip,hp-en-gpios = The phandle of the GPIO that power up/down the
|
||||
headphone (when the analog output is an headphone).
|
||||
- rockchip,hp-det-gpios = The phandle of the GPIO that detects the headphone
|
||||
(when the analog output is an headphone).
|
||||
- pinctrl-names, pinctrl-0: Please refer to pinctrl-bindings.txt
|
||||
|
||||
Example:
|
||||
|
||||
sound {
|
||||
compatible = "rockchip,rockchip-audio-es8388";
|
||||
rockchip,model = "Analog audio output";
|
||||
rockchip,i2s-controller = <&i2s>;
|
||||
rockchip,audio-codec = <&es8388>;
|
||||
rockchip,routing = "Analog", "LOUT2",
|
||||
"Analog", "ROUT2";
|
||||
rockchip,hp-en-gpios = <&gpio8 0 GPIO_ACTIVE_HIGH>;
|
||||
rockchip,hp-det-gpios = <&gpio7 7 GPIO_ACTIVE_HIGH>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&headphone>;
|
||||
};
|
||||
|
|
@ -7,6 +7,7 @@ Required properties:
|
|||
|
||||
- compatible: should be one of the followings
|
||||
- "allwinner,sun4i-a10-i2s"
|
||||
- "allwinner,sun6i-a31-i2s"
|
||||
- reg: physical base address of the controller and length of memory mapped
|
||||
region.
|
||||
- interrupts: should contain the I2S interrupt.
|
||||
|
@ -19,6 +20,10 @@ Required properties:
|
|||
- "mod" : module clock for the I2S controller
|
||||
- #sound-dai-cells : Must be equal to 0
|
||||
|
||||
Required properties for the following compatibles:
|
||||
- "allwinner,sun6i-a31-i2s"
|
||||
- resets: phandle to the reset line for this codec
|
||||
|
||||
Example:
|
||||
|
||||
i2s0: i2s@01c22400 {
|
||||
|
|
63
Documentation/devicetree/bindings/sound/sun8i-a33-codec.txt
Normal file
63
Documentation/devicetree/bindings/sound/sun8i-a33-codec.txt
Normal file
|
@ -0,0 +1,63 @@
|
|||
Allwinner SUN8I audio codec
|
||||
------------------------------------
|
||||
|
||||
On Sun8i-A33 SoCs, the audio is separated in different parts:
|
||||
- A DAI driver. It uses the "sun4i-i2s" driver which is
|
||||
documented here:
|
||||
Documentation/devicetree/bindings/sound/sun4i-i2s.txt
|
||||
- An analog part of the codec which is handled as PRCM registers.
|
||||
See Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
|
||||
- An digital part of the codec which is documented in this current
|
||||
binding documentation.
|
||||
- And finally, an audio card which links all the above components.
|
||||
The simple-audio card will be used.
|
||||
See Documentation/devicetree/bindings/sound/simple-card.txt
|
||||
|
||||
This bindings documentation exposes Sun8i codec (digital part).
|
||||
|
||||
Required properties:
|
||||
- compatible: must be "allwinner,sun8i-a33-codec"
|
||||
- reg: must contain the registers location and length
|
||||
- interrupts: must contain the codec interrupt
|
||||
- clocks: a list of phandle + clock-specifer pairs, one for each entry
|
||||
in clock-names.
|
||||
- clock-names: should contain followings:
|
||||
- "bus": the parent APB clock for this controller
|
||||
- "mod": the parent module clock
|
||||
|
||||
Here is an example to add a sound card and the codec binding on sun8i SoCs that
|
||||
are similar to A33 using simple-card:
|
||||
|
||||
sound {
|
||||
compatible = "simple-audio-card";
|
||||
simple-audio-card,name = "sun8i-a33-audio";
|
||||
simple-audio-card,format = "i2s";
|
||||
simple-audio-card,frame-master = <&link_codec>;
|
||||
simple-audio-card,bitclock-master = <&link_codec>;
|
||||
simple-audio-card,mclk-fs = <512>;
|
||||
simple-audio-card,aux-devs = <&codec_analog>;
|
||||
simple-audio-card,routing =
|
||||
"Left DAC", "Digital Left DAC",
|
||||
"Right DAC", "Digital Right DAC";
|
||||
|
||||
simple-audio-card,cpu {
|
||||
sound-dai = <&dai>;
|
||||
};
|
||||
|
||||
link_codec: simple-audio-card,codec {
|
||||
sound-dai = <&codec>;
|
||||
};
|
||||
|
||||
soc@01c00000 {
|
||||
[...]
|
||||
|
||||
audio-codec@1c22e00 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "allwinner,sun8i-a33-codec";
|
||||
reg = <0x01c22e00 0x400>;
|
||||
interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&ccu CLK_BUS_CODEC>, <&ccu CLK_AC_DIG>;
|
||||
clock-names = "bus", "mod";
|
||||
};
|
||||
};
|
||||
|
|
@ -10,6 +10,7 @@ Required properties:
|
|||
- compatible : should be one of the following:
|
||||
- "allwinner,sun4i-a10-spdif": for the Allwinner A10 SoC
|
||||
- "allwinner,sun6i-a31-spdif": for the Allwinner A31 SoC
|
||||
- "allwinner,sun8i-h3-spdif": for the Allwinner H3 SoC
|
||||
|
||||
- reg : Offset and length of the register set for the device.
|
||||
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
ZTE ZX296702 I2S controller
|
||||
|
||||
Required properties:
|
||||
- compatible : Must be "zte,zx296702-i2s"
|
||||
- compatible : Must be one of:
|
||||
"zte,zx296718-i2s", "zte,zx296702-i2s"
|
||||
"zte,zx296702-i2s"
|
||||
- reg : Must contain I2S core's registers location and length
|
||||
- clocks : Pairs of phandle and specifier referencing the controller's clocks.
|
||||
- clock-names: "tx" for the clock to the I2S interface.
|
||||
- clock-names: "wclk" for the wclk, "pclk" for the pclk to the I2S interface.
|
||||
- dmas: Pairs of phandle and specifier for the DMA channel that is used by
|
||||
the core. The core expects two dma channels for transmit.
|
||||
- dma-names : Must be "tx" and "rx"
|
||||
|
@ -16,12 +18,12 @@ please check:
|
|||
* dma/dma.txt
|
||||
|
||||
Example:
|
||||
i2s0: i2s0@0b005000 {
|
||||
i2s0: i2s@b005000 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "zte,zx296702-i2s";
|
||||
compatible = "zte,zx296718-i2s", "zte,zx296702-i2s";
|
||||
reg = <0x0b005000 0x1000>;
|
||||
clocks = <&lsp0clk ZX296702_I2S0_DIV>;
|
||||
clock-names = "tx";
|
||||
clocks = <&audiocrm AUDIO_I2S0_WCLK>, <&audiocrm AUDIO_I2S0_PCLK>;
|
||||
clock-names = "wclk", "pclk";
|
||||
interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
|
||||
dmas = <&dma 5>, <&dma 6>;
|
||||
dma-names = "tx", "rx";
|
||||
|
|
|
@ -144,6 +144,15 @@ High Definition Audio
|
|||
.. kernel-doc:: include/drm/i915_component.h
|
||||
:internal:
|
||||
|
||||
Intel HDMI LPE Audio Support
|
||||
----------------------------
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/i915/intel_lpe_audio.c
|
||||
:doc: LPE Audio integration for HDMI or DP playback
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/i915/intel_lpe_audio.c
|
||||
:internal:
|
||||
|
||||
Panel Self Refresh PSR (PSR/SRD)
|
||||
--------------------------------
|
||||
|
||||
|
|
|
@ -106,9 +106,7 @@ static struct s3c_audio_pdata i2sv4_pdata = {
|
|||
.dma_playback = DMACH_HSI_I2SV40_TX,
|
||||
.dma_capture = DMACH_HSI_I2SV40_RX,
|
||||
.type = {
|
||||
.i2s = {
|
||||
.quirks = QUIRK_PRI_6CHAN,
|
||||
},
|
||||
.quirks = QUIRK_PRI_6CHAN,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -122,6 +122,9 @@ i915-y += intel_gvt.o
|
|||
include $(src)/gvt/Makefile
|
||||
endif
|
||||
|
||||
# LPE Audio for VLV and CHT
|
||||
i915-y += intel_lpe_audio.o
|
||||
|
||||
obj-$(CONFIG_DRM_I915) += i915.o
|
||||
|
||||
CFLAGS_i915_trace_points.o := -I$(src)
|
||||
|
|
|
@ -1139,7 +1139,7 @@ static void i915_driver_register(struct drm_i915_private *dev_priv)
|
|||
if (IS_GEN5(dev_priv))
|
||||
intel_gpu_ips_init(dev_priv);
|
||||
|
||||
i915_audio_component_init(dev_priv);
|
||||
intel_audio_init(dev_priv);
|
||||
|
||||
/*
|
||||
* Some ports require correctly set-up hpd registers for detection to
|
||||
|
@ -1157,7 +1157,7 @@ static void i915_driver_register(struct drm_i915_private *dev_priv)
|
|||
*/
|
||||
static void i915_driver_unregister(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
i915_audio_component_cleanup(dev_priv);
|
||||
intel_audio_deinit(dev_priv);
|
||||
|
||||
intel_gpu_ips_teardown();
|
||||
acpi_video_unregister();
|
||||
|
|
|
@ -2140,6 +2140,12 @@ struct drm_i915_private {
|
|||
/* Used to save the pipe-to-encoder mapping for audio */
|
||||
struct intel_encoder *av_enc_map[I915_MAX_PIPES];
|
||||
|
||||
/* necessary resource sharing with HDMI LPE audio driver. */
|
||||
struct {
|
||||
struct platform_device *platdev;
|
||||
int irq;
|
||||
} lpe_audio;
|
||||
|
||||
/*
|
||||
* NOTE: This is the dri1/ums dungeon, don't add stuff here. Your patch
|
||||
* will be rejected. Instead look for a better place.
|
||||
|
@ -3387,6 +3393,14 @@ extern int i915_restore_state(struct drm_device *dev);
|
|||
void i915_setup_sysfs(struct drm_i915_private *dev_priv);
|
||||
void i915_teardown_sysfs(struct drm_i915_private *dev_priv);
|
||||
|
||||
/* intel_lpe_audio.c */
|
||||
int intel_lpe_audio_init(struct drm_i915_private *dev_priv);
|
||||
void intel_lpe_audio_teardown(struct drm_i915_private *dev_priv);
|
||||
void intel_lpe_audio_irq_handler(struct drm_i915_private *dev_priv);
|
||||
void intel_lpe_audio_notify(struct drm_i915_private *dev_priv,
|
||||
void *eld, int port, int pipe, int tmds_clk_speed,
|
||||
bool dp_output, int link_rate);
|
||||
|
||||
/* intel_i2c.c */
|
||||
extern int intel_setup_gmbus(struct drm_device *dev);
|
||||
extern void intel_teardown_gmbus(struct drm_device *dev);
|
||||
|
|
|
@ -1893,6 +1893,10 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg)
|
|||
* signalled in iir */
|
||||
valleyview_pipestat_irq_ack(dev_priv, iir, pipe_stats);
|
||||
|
||||
if (iir & (I915_LPE_PIPE_A_INTERRUPT |
|
||||
I915_LPE_PIPE_B_INTERRUPT))
|
||||
intel_lpe_audio_irq_handler(dev_priv);
|
||||
|
||||
/*
|
||||
* VLV_IIR is single buffered, and reflects the level
|
||||
* from PIPESTAT/PORT_HOTPLUG_STAT, hence clear it last.
|
||||
|
@ -1973,6 +1977,11 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg)
|
|||
* signalled in iir */
|
||||
valleyview_pipestat_irq_ack(dev_priv, iir, pipe_stats);
|
||||
|
||||
if (iir & (I915_LPE_PIPE_A_INTERRUPT |
|
||||
I915_LPE_PIPE_B_INTERRUPT |
|
||||
I915_LPE_PIPE_C_INTERRUPT))
|
||||
intel_lpe_audio_irq_handler(dev_priv);
|
||||
|
||||
/*
|
||||
* VLV_IIR is single buffered, and reflects the level
|
||||
* from PIPESTAT/PORT_HOTPLUG_STAT, hence clear it last.
|
||||
|
@ -2914,6 +2923,7 @@ static void vlv_display_irq_postinstall(struct drm_i915_private *dev_priv)
|
|||
u32 pipestat_mask;
|
||||
u32 enable_mask;
|
||||
enum pipe pipe;
|
||||
u32 val;
|
||||
|
||||
pipestat_mask = PLANE_FLIP_DONE_INT_STATUS_VLV |
|
||||
PIPE_CRC_DONE_INTERRUPT_STATUS;
|
||||
|
@ -2930,6 +2940,12 @@ static void vlv_display_irq_postinstall(struct drm_i915_private *dev_priv)
|
|||
|
||||
WARN_ON(dev_priv->irq_mask != ~0);
|
||||
|
||||
val = (I915_LPE_PIPE_A_INTERRUPT |
|
||||
I915_LPE_PIPE_B_INTERRUPT |
|
||||
I915_LPE_PIPE_C_INTERRUPT);
|
||||
|
||||
enable_mask |= val;
|
||||
|
||||
dev_priv->irq_mask = ~enable_mask;
|
||||
|
||||
GEN5_IRQ_INIT(VLV_, dev_priv->irq_mask, enable_mask);
|
||||
|
|
|
@ -2058,6 +2058,22 @@ enum skl_disp_power_wells {
|
|||
#define I915_ASLE_INTERRUPT (1<<0)
|
||||
#define I915_BSD_USER_INTERRUPT (1<<25)
|
||||
|
||||
#define I915_HDMI_LPE_AUDIO_BASE (VLV_DISPLAY_BASE + 0x65000)
|
||||
#define I915_HDMI_LPE_AUDIO_SIZE 0x1000
|
||||
|
||||
/* DisplayPort Audio w/ LPE */
|
||||
#define VLV_AUD_CHICKEN_BIT_REG _MMIO(VLV_DISPLAY_BASE + 0x62F38)
|
||||
#define VLV_CHICKEN_BIT_DBG_ENABLE (1 << 0)
|
||||
|
||||
#define _VLV_AUD_PORT_EN_B_DBG (VLV_DISPLAY_BASE + 0x62F20)
|
||||
#define _VLV_AUD_PORT_EN_C_DBG (VLV_DISPLAY_BASE + 0x62F30)
|
||||
#define _VLV_AUD_PORT_EN_D_DBG (VLV_DISPLAY_BASE + 0x62F34)
|
||||
#define VLV_AUD_PORT_EN_DBG(port) _MMIO_PORT3((port) - PORT_B, \
|
||||
_VLV_AUD_PORT_EN_B_DBG, \
|
||||
_VLV_AUD_PORT_EN_C_DBG, \
|
||||
_VLV_AUD_PORT_EN_D_DBG)
|
||||
#define VLV_AMP_MUTE (1 << 1)
|
||||
|
||||
#define GEN6_BSD_RNCID _MMIO(0x12198)
|
||||
|
||||
#define GEN7_FF_THREAD_MODE _MMIO(0x20a0)
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/component.h>
|
||||
#include <drm/i915_component.h>
|
||||
#include <drm/intel_lpe_audio.h>
|
||||
#include "intel_drv.h"
|
||||
|
||||
#include <drm/drmP.h>
|
||||
|
@ -623,13 +624,28 @@ void intel_audio_codec_enable(struct intel_encoder *intel_encoder,
|
|||
dev_priv->av_enc_map[pipe] = intel_encoder;
|
||||
mutex_unlock(&dev_priv->av_mutex);
|
||||
|
||||
/* audio drivers expect pipe = -1 to indicate Non-MST cases */
|
||||
if (intel_encoder->type != INTEL_OUTPUT_DP_MST)
|
||||
pipe = -1;
|
||||
|
||||
if (acomp && acomp->audio_ops && acomp->audio_ops->pin_eld_notify)
|
||||
if (acomp && acomp->audio_ops && acomp->audio_ops->pin_eld_notify) {
|
||||
/* audio drivers expect pipe = -1 to indicate Non-MST cases */
|
||||
if (intel_encoder->type != INTEL_OUTPUT_DP_MST)
|
||||
pipe = -1;
|
||||
acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr,
|
||||
(int) port, (int) pipe);
|
||||
}
|
||||
|
||||
switch (intel_encoder->type) {
|
||||
case INTEL_OUTPUT_HDMI:
|
||||
intel_lpe_audio_notify(dev_priv, connector->eld, port, pipe,
|
||||
crtc_state->port_clock,
|
||||
false, 0);
|
||||
break;
|
||||
case INTEL_OUTPUT_DP:
|
||||
intel_lpe_audio_notify(dev_priv, connector->eld, port, pipe,
|
||||
adjusted_mode->crtc_clock,
|
||||
true, crtc_state->port_clock);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -656,13 +672,15 @@ void intel_audio_codec_disable(struct intel_encoder *intel_encoder)
|
|||
dev_priv->av_enc_map[pipe] = NULL;
|
||||
mutex_unlock(&dev_priv->av_mutex);
|
||||
|
||||
/* audio drivers expect pipe = -1 to indicate Non-MST cases */
|
||||
if (intel_encoder->type != INTEL_OUTPUT_DP_MST)
|
||||
pipe = -1;
|
||||
|
||||
if (acomp && acomp->audio_ops && acomp->audio_ops->pin_eld_notify)
|
||||
if (acomp && acomp->audio_ops && acomp->audio_ops->pin_eld_notify) {
|
||||
/* audio drivers expect pipe = -1 to indicate Non-MST cases */
|
||||
if (intel_encoder->type != INTEL_OUTPUT_DP_MST)
|
||||
pipe = -1;
|
||||
acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr,
|
||||
(int) port, (int) pipe);
|
||||
}
|
||||
|
||||
intel_lpe_audio_notify(dev_priv, NULL, port, pipe, 0, false, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -931,3 +949,28 @@ void i915_audio_component_cleanup(struct drm_i915_private *dev_priv)
|
|||
component_del(dev_priv->drm.dev, &i915_audio_component_bind_ops);
|
||||
dev_priv->audio_component_registered = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_audio_init() - Initialize the audio driver either using
|
||||
* component framework or using lpe audio bridge
|
||||
* @dev_priv: the i915 drm device private data
|
||||
*
|
||||
*/
|
||||
void intel_audio_init(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
if (intel_lpe_audio_init(dev_priv) < 0)
|
||||
i915_audio_component_init(dev_priv);
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_audio_deinit() - deinitialize the audio driver
|
||||
* @dev_priv: the i915 drm device private data
|
||||
*
|
||||
*/
|
||||
void intel_audio_deinit(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
if ((dev_priv)->lpe_audio.platdev != NULL)
|
||||
intel_lpe_audio_teardown(dev_priv);
|
||||
else
|
||||
i915_audio_component_cleanup(dev_priv);
|
||||
}
|
||||
|
|
|
@ -1196,6 +1196,8 @@ void intel_audio_codec_enable(struct intel_encoder *encoder,
|
|||
void intel_audio_codec_disable(struct intel_encoder *encoder);
|
||||
void i915_audio_component_init(struct drm_i915_private *dev_priv);
|
||||
void i915_audio_component_cleanup(struct drm_i915_private *dev_priv);
|
||||
void intel_audio_init(struct drm_i915_private *dev_priv);
|
||||
void intel_audio_deinit(struct drm_i915_private *dev_priv);
|
||||
|
||||
/* intel_display.c */
|
||||
enum transcoder intel_crtc_pch_transcoder(struct intel_crtc *crtc);
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include <drm/drm_edid.h>
|
||||
#include "intel_drv.h"
|
||||
#include <drm/i915_drm.h>
|
||||
#include <drm/intel_lpe_audio.h>
|
||||
#include "i915_drv.h"
|
||||
|
||||
static struct drm_device *intel_hdmi_to_dev(struct intel_hdmi *intel_hdmi)
|
||||
|
|
392
drivers/gpu/drm/i915/intel_lpe_audio.c
Normal file
392
drivers/gpu/drm/i915/intel_lpe_audio.c
Normal file
|
@ -0,0 +1,392 @@
|
|||
/*
|
||||
* Copyright © 2016 Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*
|
||||
* Authors:
|
||||
* Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
|
||||
* Jerome Anand <jerome.anand@intel.com>
|
||||
* based on VED patches
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* DOC: LPE Audio integration for HDMI or DP playback
|
||||
*
|
||||
* Motivation:
|
||||
* Atom platforms (e.g. valleyview and cherryTrail) integrates a DMA-based
|
||||
* interface as an alternative to the traditional HDaudio path. While this
|
||||
* mode is unrelated to the LPE aka SST audio engine, the documentation refers
|
||||
* to this mode as LPE so we keep this notation for the sake of consistency.
|
||||
*
|
||||
* The interface is handled by a separate standalone driver maintained in the
|
||||
* ALSA subsystem for simplicity. To minimize the interaction between the two
|
||||
* subsystems, a bridge is setup between the hdmi-lpe-audio and i915:
|
||||
* 1. Create a platform device to share MMIO/IRQ resources
|
||||
* 2. Make the platform device child of i915 device for runtime PM.
|
||||
* 3. Create IRQ chip to forward the LPE audio irqs.
|
||||
* the hdmi-lpe-audio driver probes the lpe audio device and creates a new
|
||||
* sound card
|
||||
*
|
||||
* Threats:
|
||||
* Due to the restriction in Linux platform device model, user need manually
|
||||
* uninstall the hdmi-lpe-audio driver before uninstalling i915 module,
|
||||
* otherwise we might run into use-after-free issues after i915 removes the
|
||||
* platform device: even though hdmi-lpe-audio driver is released, the modules
|
||||
* is still in "installed" status.
|
||||
*
|
||||
* Implementation:
|
||||
* The MMIO/REG platform resources are created according to the registers
|
||||
* specification.
|
||||
* When forwarding LPE audio irqs, the flow control handler selection depends
|
||||
* on the platform, for example on valleyview handle_simple_irq is enough.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include <linux/delay.h>
|
||||
#include <drm/intel_lpe_audio.h>
|
||||
|
||||
#define HAS_LPE_AUDIO(dev_priv) ((dev_priv)->lpe_audio.platdev != NULL)
|
||||
|
||||
static struct platform_device *
|
||||
lpe_audio_platdev_create(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
int ret;
|
||||
struct drm_device *dev = &dev_priv->drm;
|
||||
struct platform_device_info pinfo = {};
|
||||
struct resource *rsc;
|
||||
struct platform_device *platdev;
|
||||
struct intel_hdmi_lpe_audio_pdata *pdata;
|
||||
|
||||
pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
|
||||
if (!pdata)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
rsc = kcalloc(2, sizeof(*rsc), GFP_KERNEL);
|
||||
if (!rsc) {
|
||||
kfree(pdata);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
rsc[0].start = rsc[0].end = dev_priv->lpe_audio.irq;
|
||||
rsc[0].flags = IORESOURCE_IRQ;
|
||||
rsc[0].name = "hdmi-lpe-audio-irq";
|
||||
|
||||
rsc[1].start = pci_resource_start(dev->pdev, 0) +
|
||||
I915_HDMI_LPE_AUDIO_BASE;
|
||||
rsc[1].end = pci_resource_start(dev->pdev, 0) +
|
||||
I915_HDMI_LPE_AUDIO_BASE + I915_HDMI_LPE_AUDIO_SIZE - 1;
|
||||
rsc[1].flags = IORESOURCE_MEM;
|
||||
rsc[1].name = "hdmi-lpe-audio-mmio";
|
||||
|
||||
pinfo.parent = dev->dev;
|
||||
pinfo.name = "hdmi-lpe-audio";
|
||||
pinfo.id = -1;
|
||||
pinfo.res = rsc;
|
||||
pinfo.num_res = 2;
|
||||
pinfo.data = pdata;
|
||||
pinfo.size_data = sizeof(*pdata);
|
||||
pinfo.dma_mask = DMA_BIT_MASK(32);
|
||||
|
||||
spin_lock_init(&pdata->lpe_audio_slock);
|
||||
|
||||
platdev = platform_device_register_full(&pinfo);
|
||||
if (IS_ERR(platdev)) {
|
||||
ret = PTR_ERR(platdev);
|
||||
DRM_ERROR("Failed to allocate LPE audio platform device\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
kfree(rsc);
|
||||
|
||||
return platdev;
|
||||
|
||||
err:
|
||||
kfree(rsc);
|
||||
kfree(pdata);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
static void lpe_audio_platdev_destroy(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
platform_device_unregister(dev_priv->lpe_audio.platdev);
|
||||
kfree(dev_priv->lpe_audio.platdev->dev.dma_mask);
|
||||
}
|
||||
|
||||
static void lpe_audio_irq_unmask(struct irq_data *d)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = d->chip_data;
|
||||
unsigned long irqflags;
|
||||
u32 val = (I915_LPE_PIPE_A_INTERRUPT |
|
||||
I915_LPE_PIPE_B_INTERRUPT);
|
||||
|
||||
if (IS_CHERRYVIEW(dev_priv))
|
||||
val |= I915_LPE_PIPE_C_INTERRUPT;
|
||||
|
||||
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
|
||||
|
||||
dev_priv->irq_mask &= ~val;
|
||||
I915_WRITE(VLV_IIR, val);
|
||||
I915_WRITE(VLV_IIR, val);
|
||||
I915_WRITE(VLV_IMR, dev_priv->irq_mask);
|
||||
POSTING_READ(VLV_IMR);
|
||||
|
||||
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
|
||||
}
|
||||
|
||||
static void lpe_audio_irq_mask(struct irq_data *d)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = d->chip_data;
|
||||
unsigned long irqflags;
|
||||
u32 val = (I915_LPE_PIPE_A_INTERRUPT |
|
||||
I915_LPE_PIPE_B_INTERRUPT);
|
||||
|
||||
if (IS_CHERRYVIEW(dev_priv))
|
||||
val |= I915_LPE_PIPE_C_INTERRUPT;
|
||||
|
||||
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
|
||||
|
||||
dev_priv->irq_mask |= val;
|
||||
I915_WRITE(VLV_IMR, dev_priv->irq_mask);
|
||||
I915_WRITE(VLV_IIR, val);
|
||||
I915_WRITE(VLV_IIR, val);
|
||||
POSTING_READ(VLV_IIR);
|
||||
|
||||
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
|
||||
}
|
||||
|
||||
static struct irq_chip lpe_audio_irqchip = {
|
||||
.name = "hdmi_lpe_audio_irqchip",
|
||||
.irq_mask = lpe_audio_irq_mask,
|
||||
.irq_unmask = lpe_audio_irq_unmask,
|
||||
};
|
||||
|
||||
static int lpe_audio_irq_init(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
int irq = dev_priv->lpe_audio.irq;
|
||||
|
||||
WARN_ON(!intel_irqs_enabled(dev_priv));
|
||||
irq_set_chip_and_handler_name(irq,
|
||||
&lpe_audio_irqchip,
|
||||
handle_simple_irq,
|
||||
"hdmi_lpe_audio_irq_handler");
|
||||
|
||||
return irq_set_chip_data(irq, dev_priv);
|
||||
}
|
||||
|
||||
static bool lpe_audio_detect(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
int lpe_present = false;
|
||||
|
||||
if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
|
||||
static const struct pci_device_id atom_hdaudio_ids[] = {
|
||||
/* Baytrail */
|
||||
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0f04)},
|
||||
/* Braswell */
|
||||
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2284)},
|
||||
{}
|
||||
};
|
||||
|
||||
if (!pci_dev_present(atom_hdaudio_ids)) {
|
||||
DRM_INFO("%s\n", "HDaudio controller not detected, using LPE audio instead\n");
|
||||
lpe_present = true;
|
||||
}
|
||||
}
|
||||
return lpe_present;
|
||||
}
|
||||
|
||||
static int lpe_audio_setup(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
dev_priv->lpe_audio.irq = irq_alloc_desc(0);
|
||||
if (dev_priv->lpe_audio.irq < 0) {
|
||||
DRM_ERROR("Failed to allocate IRQ desc: %d\n",
|
||||
dev_priv->lpe_audio.irq);
|
||||
ret = dev_priv->lpe_audio.irq;
|
||||
goto err;
|
||||
}
|
||||
|
||||
DRM_DEBUG("irq = %d\n", dev_priv->lpe_audio.irq);
|
||||
|
||||
ret = lpe_audio_irq_init(dev_priv);
|
||||
|
||||
if (ret) {
|
||||
DRM_ERROR("Failed to initialize irqchip for lpe audio: %d\n",
|
||||
ret);
|
||||
goto err_free_irq;
|
||||
}
|
||||
|
||||
dev_priv->lpe_audio.platdev = lpe_audio_platdev_create(dev_priv);
|
||||
|
||||
if (IS_ERR(dev_priv->lpe_audio.platdev)) {
|
||||
ret = PTR_ERR(dev_priv->lpe_audio.platdev);
|
||||
DRM_ERROR("Failed to create lpe audio platform device: %d\n",
|
||||
ret);
|
||||
goto err_free_irq;
|
||||
}
|
||||
|
||||
/* enable chicken bit; at least this is required for Dell Wyse 3040
|
||||
* with DP outputs (but only sometimes by some reason!)
|
||||
*/
|
||||
I915_WRITE(VLV_AUD_CHICKEN_BIT_REG, VLV_CHICKEN_BIT_DBG_ENABLE);
|
||||
|
||||
return 0;
|
||||
err_free_irq:
|
||||
irq_free_desc(dev_priv->lpe_audio.irq);
|
||||
err:
|
||||
dev_priv->lpe_audio.irq = -1;
|
||||
dev_priv->lpe_audio.platdev = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_lpe_audio_irq_handler() - forwards the LPE audio irq
|
||||
* @dev_priv: the i915 drm device private data
|
||||
*
|
||||
* the LPE Audio irq is forwarded to the irq handler registered by LPE audio
|
||||
* driver.
|
||||
*/
|
||||
void intel_lpe_audio_irq_handler(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!HAS_LPE_AUDIO(dev_priv))
|
||||
return;
|
||||
|
||||
ret = generic_handle_irq(dev_priv->lpe_audio.irq);
|
||||
if (ret)
|
||||
DRM_ERROR_RATELIMITED("error handling LPE audio irq: %d\n",
|
||||
ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_lpe_audio_init() - detect and setup the bridge between HDMI LPE Audio
|
||||
* driver and i915
|
||||
* @dev_priv: the i915 drm device private data
|
||||
*
|
||||
* Return: 0 if successful. non-zero if detection or
|
||||
* llocation/initialization fails
|
||||
*/
|
||||
int intel_lpe_audio_init(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
int ret = -ENODEV;
|
||||
|
||||
if (lpe_audio_detect(dev_priv)) {
|
||||
ret = lpe_audio_setup(dev_priv);
|
||||
if (ret < 0)
|
||||
DRM_ERROR("failed to setup LPE Audio bridge\n");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_lpe_audio_teardown() - destroy the bridge between HDMI LPE
|
||||
* audio driver and i915
|
||||
* @dev_priv: the i915 drm device private data
|
||||
*
|
||||
* release all the resources for LPE audio <-> i915 bridge.
|
||||
*/
|
||||
void intel_lpe_audio_teardown(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct irq_desc *desc;
|
||||
|
||||
if (!HAS_LPE_AUDIO(dev_priv))
|
||||
return;
|
||||
|
||||
desc = irq_to_desc(dev_priv->lpe_audio.irq);
|
||||
|
||||
lpe_audio_irq_mask(&desc->irq_data);
|
||||
|
||||
lpe_audio_platdev_destroy(dev_priv);
|
||||
|
||||
irq_free_desc(dev_priv->lpe_audio.irq);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* intel_lpe_audio_notify() - notify lpe audio event
|
||||
* audio driver and i915
|
||||
* @dev_priv: the i915 drm device private data
|
||||
* @eld : ELD data
|
||||
* @port: port id
|
||||
* @tmds_clk_speed: tmds clock frequency in Hz
|
||||
*
|
||||
* Notify lpe audio driver of eld change.
|
||||
*/
|
||||
void intel_lpe_audio_notify(struct drm_i915_private *dev_priv,
|
||||
void *eld, int port, int pipe, int tmds_clk_speed,
|
||||
bool dp_output, int link_rate)
|
||||
{
|
||||
unsigned long irq_flags;
|
||||
struct intel_hdmi_lpe_audio_pdata *pdata = NULL;
|
||||
u32 audio_enable;
|
||||
|
||||
if (!HAS_LPE_AUDIO(dev_priv))
|
||||
return;
|
||||
|
||||
pdata = dev_get_platdata(
|
||||
&(dev_priv->lpe_audio.platdev->dev));
|
||||
|
||||
spin_lock_irqsave(&pdata->lpe_audio_slock, irq_flags);
|
||||
|
||||
audio_enable = I915_READ(VLV_AUD_PORT_EN_DBG(port));
|
||||
|
||||
if (eld != NULL) {
|
||||
memcpy(pdata->eld.eld_data, eld,
|
||||
HDMI_MAX_ELD_BYTES);
|
||||
pdata->eld.port_id = port;
|
||||
pdata->eld.pipe_id = pipe;
|
||||
pdata->hdmi_connected = true;
|
||||
|
||||
pdata->dp_output = dp_output;
|
||||
if (tmds_clk_speed)
|
||||
pdata->tmds_clock_speed = tmds_clk_speed;
|
||||
if (link_rate)
|
||||
pdata->link_rate = link_rate;
|
||||
|
||||
/* Unmute the amp for both DP and HDMI */
|
||||
I915_WRITE(VLV_AUD_PORT_EN_DBG(port),
|
||||
audio_enable & ~VLV_AMP_MUTE);
|
||||
|
||||
} else {
|
||||
memset(pdata->eld.eld_data, 0,
|
||||
HDMI_MAX_ELD_BYTES);
|
||||
pdata->hdmi_connected = false;
|
||||
pdata->dp_output = false;
|
||||
|
||||
/* Mute the amp for both DP and HDMI */
|
||||
I915_WRITE(VLV_AUD_PORT_EN_DBG(port),
|
||||
audio_enable | VLV_AMP_MUTE);
|
||||
}
|
||||
|
||||
if (pdata->notify_audio_lpe)
|
||||
pdata->notify_audio_lpe(dev_priv->lpe_audio.platdev);
|
||||
else
|
||||
pdata->notify_pending = true;
|
||||
|
||||
spin_unlock_irqrestore(&pdata->lpe_audio_slock,
|
||||
irq_flags);
|
||||
}
|
|
@ -20,6 +20,8 @@
|
|||
|
||||
#include <linux/of.h>
|
||||
|
||||
#include "../../sound/soc/atmel/atmel_ssc_dai.h"
|
||||
|
||||
/* Serialize access to ssc_list and user count */
|
||||
static DEFINE_SPINLOCK(user_lock);
|
||||
static LIST_HEAD(ssc_list);
|
||||
|
@ -145,6 +147,49 @@ static inline const struct atmel_ssc_platform_data * __init
|
|||
platform_get_device_id(pdev)->driver_data;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SND_ATMEL_SOC_SSC
|
||||
static int ssc_sound_dai_probe(struct ssc_device *ssc)
|
||||
{
|
||||
struct device_node *np = ssc->pdev->dev.of_node;
|
||||
int ret;
|
||||
int id;
|
||||
|
||||
ssc->sound_dai = false;
|
||||
|
||||
if (!of_property_read_bool(np, "#sound-dai-cells"))
|
||||
return 0;
|
||||
|
||||
id = of_alias_get_id(np, "ssc");
|
||||
if (id < 0)
|
||||
return id;
|
||||
|
||||
ret = atmel_ssc_set_audio(id);
|
||||
ssc->sound_dai = !ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ssc_sound_dai_remove(struct ssc_device *ssc)
|
||||
{
|
||||
if (!ssc->sound_dai)
|
||||
return;
|
||||
|
||||
atmel_ssc_put_audio(of_alias_get_id(ssc->pdev->dev.of_node, "ssc"));
|
||||
}
|
||||
#else
|
||||
static inline int ssc_sound_dai_probe(struct ssc_device *ssc)
|
||||
{
|
||||
if (of_property_read_bool(ssc->pdev->dev.of_node, "#sound-dai-cells"))
|
||||
return -ENOTSUPP;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void ssc_sound_dai_remove(struct ssc_device *ssc)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
static int ssc_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *regs;
|
||||
|
@ -204,6 +249,9 @@ static int ssc_probe(struct platform_device *pdev)
|
|||
dev_info(&pdev->dev, "Atmel SSC device at 0x%p (irq %d)\n",
|
||||
ssc->regs, ssc->irq);
|
||||
|
||||
if (ssc_sound_dai_probe(ssc))
|
||||
dev_err(&pdev->dev, "failed to auto-setup ssc for audio\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -211,6 +259,8 @@ static int ssc_remove(struct platform_device *pdev)
|
|||
{
|
||||
struct ssc_device *ssc = platform_get_drvdata(pdev);
|
||||
|
||||
ssc_sound_dai_remove(ssc);
|
||||
|
||||
spin_lock(&user_lock);
|
||||
list_del(&ssc->list);
|
||||
spin_unlock(&user_lock);
|
||||
|
|
|
@ -248,6 +248,7 @@ struct detailed_timing {
|
|||
# define DRM_ELD_AUD_SYNCH_DELAY_MAX 0xfa /* 500 ms */
|
||||
|
||||
#define DRM_ELD_SPEAKER 7
|
||||
# define DRM_ELD_SPEAKER_MASK 0x7f
|
||||
# define DRM_ELD_SPEAKER_RLRC (1 << 6)
|
||||
# define DRM_ELD_SPEAKER_FLRC (1 << 5)
|
||||
# define DRM_ELD_SPEAKER_RC (1 << 4)
|
||||
|
@ -413,6 +414,18 @@ static inline int drm_eld_size(const uint8_t *eld)
|
|||
return DRM_ELD_HEADER_BLOCK_SIZE + eld[DRM_ELD_BASELINE_ELD_LEN] * 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_eld_get_spk_alloc - Get speaker allocation
|
||||
* @eld: pointer to an ELD memory structure
|
||||
*
|
||||
* The returned value is the speakers mask. User has to use %DRM_ELD_SPEAKER
|
||||
* field definitions to identify speakers.
|
||||
*/
|
||||
static inline u8 drm_eld_get_spk_alloc(const uint8_t *eld)
|
||||
{
|
||||
return eld[DRM_ELD_SPEAKER] & DRM_ELD_SPEAKER_MASK;
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_eld_get_conn_type - Get device type hdmi/dp connected
|
||||
* @eld: pointer to an ELD memory structure
|
||||
|
|
51
include/drm/intel_lpe_audio.h
Normal file
51
include/drm/intel_lpe_audio.h
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright © 2016 Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _INTEL_LPE_AUDIO_H_
|
||||
#define _INTEL_LPE_AUDIO_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/spinlock_types.h>
|
||||
|
||||
struct platform_device;
|
||||
|
||||
#define HDMI_MAX_ELD_BYTES 128
|
||||
|
||||
struct intel_hdmi_lpe_audio_eld {
|
||||
int port_id;
|
||||
int pipe_id;
|
||||
unsigned char eld_data[HDMI_MAX_ELD_BYTES];
|
||||
};
|
||||
|
||||
struct intel_hdmi_lpe_audio_pdata {
|
||||
bool notify_pending;
|
||||
int tmds_clock_speed;
|
||||
bool hdmi_connected;
|
||||
bool dp_output;
|
||||
int link_rate;
|
||||
struct intel_hdmi_lpe_audio_eld eld;
|
||||
void (*notify_audio_lpe)(struct platform_device *pdev);
|
||||
spinlock_t lpe_audio_slock;
|
||||
};
|
||||
|
||||
#endif /* _I915_LPE_AUDIO_H_ */
|
|
@ -20,6 +20,7 @@ struct ssc_device {
|
|||
int user;
|
||||
int irq;
|
||||
bool clk_from_rk_pin;
|
||||
bool sound_dai;
|
||||
};
|
||||
|
||||
struct ssc_device * __must_check ssc_request(unsigned int ssc_num);
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
extern void s3c64xx_ac97_setup_gpio(int);
|
||||
|
||||
struct samsung_i2s {
|
||||
struct samsung_i2s_type {
|
||||
/* If the Primary DAI has 5.1 Channels */
|
||||
#define QUIRK_PRI_6CHAN (1 << 0)
|
||||
/* If the I2S block has a Stereo Overlay Channel */
|
||||
|
@ -47,7 +47,5 @@ struct s3c_audio_pdata {
|
|||
void *dma_capture;
|
||||
void *dma_play_sec;
|
||||
void *dma_capture_mic;
|
||||
union {
|
||||
struct samsung_i2s i2s;
|
||||
} type;
|
||||
struct samsung_i2s_type type;
|
||||
};
|
||||
|
|
|
@ -71,6 +71,7 @@ struct dma_chan *snd_dmaengine_pcm_get_chan(struct snd_pcm_substream *substream)
|
|||
* @slave_id: Slave requester id for the DMA channel.
|
||||
* @filter_data: Custom DMA channel filter data, this will usually be used when
|
||||
* requesting the DMA channel.
|
||||
* @chan_name: Custom channel name to use when requesting DMA channel.
|
||||
* @fifo_size: FIFO size of the DAI controller in bytes
|
||||
* @flags: PCM_DAI flags, only SND_DMAENGINE_PCM_DAI_FLAG_PACK for now
|
||||
*/
|
||||
|
@ -80,6 +81,7 @@ struct snd_dmaengine_dai_dma_data {
|
|||
u32 maxburst;
|
||||
unsigned int slave_id;
|
||||
void *filter_data;
|
||||
const char *chan_name;
|
||||
unsigned int fifo_size;
|
||||
unsigned int flags;
|
||||
};
|
||||
|
@ -105,6 +107,10 @@ void snd_dmaengine_pcm_set_config_from_dai_data(
|
|||
* playback.
|
||||
*/
|
||||
#define SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX BIT(3)
|
||||
/*
|
||||
* The PCM streams have custom channel names specified.
|
||||
*/
|
||||
#define SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME BIT(4)
|
||||
|
||||
/**
|
||||
* struct snd_dmaengine_pcm_config - Configuration data for dmaengine based PCM
|
||||
|
|
|
@ -570,6 +570,15 @@ int snd_pcm_stop_xrun(struct snd_pcm_substream *substream);
|
|||
#ifdef CONFIG_PM
|
||||
int snd_pcm_suspend(struct snd_pcm_substream *substream);
|
||||
int snd_pcm_suspend_all(struct snd_pcm *pcm);
|
||||
#else
|
||||
static inline int snd_pcm_suspend(struct snd_pcm_substream *substream)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline int snd_pcm_suspend_all(struct snd_pcm *pcm)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream, unsigned int cmd, void *arg);
|
||||
int snd_pcm_open_substream(struct snd_pcm *pcm, int stream, struct file *file,
|
||||
|
|
|
@ -103,7 +103,7 @@ struct snd_rawmidi_substream {
|
|||
struct snd_rawmidi_runtime *runtime;
|
||||
struct pid *pid;
|
||||
/* hardware layer */
|
||||
struct snd_rawmidi_ops *ops;
|
||||
const struct snd_rawmidi_ops *ops;
|
||||
};
|
||||
|
||||
struct snd_rawmidi_file {
|
||||
|
@ -155,7 +155,7 @@ int snd_rawmidi_new(struct snd_card *card, char *id, int device,
|
|||
int output_count, int input_count,
|
||||
struct snd_rawmidi **rmidi);
|
||||
void snd_rawmidi_set_ops(struct snd_rawmidi *rmidi, int stream,
|
||||
struct snd_rawmidi_ops *ops);
|
||||
const struct snd_rawmidi_ops *ops);
|
||||
|
||||
/* callbacks */
|
||||
|
||||
|
|
|
@ -34,11 +34,12 @@ int asoc_simple_card_set_dailink_name(struct device *dev,
|
|||
int asoc_simple_card_parse_card_name(struct snd_soc_card *card,
|
||||
char *prefix);
|
||||
|
||||
#define asoc_simple_card_parse_clk_cpu(node, dai_link, simple_dai) \
|
||||
asoc_simple_card_parse_clk(node, dai_link->cpu_of_node, simple_dai)
|
||||
#define asoc_simple_card_parse_clk_codec(node, dai_link, simple_dai) \
|
||||
asoc_simple_card_parse_clk(node, dai_link->codec_of_node, simple_dai)
|
||||
int asoc_simple_card_parse_clk(struct device_node *node,
|
||||
#define asoc_simple_card_parse_clk_cpu(dev, node, dai_link, simple_dai) \
|
||||
asoc_simple_card_parse_clk(dev, node, dai_link->cpu_of_node, simple_dai)
|
||||
#define asoc_simple_card_parse_clk_codec(dev, node, dai_link, simple_dai) \
|
||||
asoc_simple_card_parse_clk(dev, node, dai_link->codec_of_node, simple_dai)
|
||||
int asoc_simple_card_parse_clk(struct device *dev,
|
||||
struct device_node *node,
|
||||
struct device_node *dai_of_node,
|
||||
struct asoc_simple_dai *simple_dai);
|
||||
|
||||
|
|
|
@ -37,8 +37,8 @@ struct _snd_wavefront_midi {
|
|||
#define MPU_ACK 0xFE
|
||||
#define UART_MODE_ON 0x3F
|
||||
|
||||
extern struct snd_rawmidi_ops snd_wavefront_midi_output;
|
||||
extern struct snd_rawmidi_ops snd_wavefront_midi_input;
|
||||
extern const struct snd_rawmidi_ops snd_wavefront_midi_output;
|
||||
extern const struct snd_rawmidi_ops snd_wavefront_midi_input;
|
||||
|
||||
extern void snd_wavefront_midi_enable_virtual (snd_wavefront_card_t *);
|
||||
extern void snd_wavefront_midi_disable_virtual (snd_wavefront_card_t *);
|
||||
|
|
|
@ -256,6 +256,9 @@ struct snd_soc_dai_driver {
|
|||
int (*resume)(struct snd_soc_dai *dai);
|
||||
/* compress dai */
|
||||
int (*compress_new)(struct snd_soc_pcm_runtime *rtd, int num);
|
||||
/* Optional Callback used at pcm creation*/
|
||||
int (*pcm_new)(struct snd_soc_pcm_runtime *rtd,
|
||||
struct snd_soc_dai *dai);
|
||||
/* DAI is also used for the control bus */
|
||||
bool bus_control;
|
||||
|
||||
|
|
|
@ -497,6 +497,8 @@ void snd_soc_runtime_deactivate(struct snd_soc_pcm_runtime *rtd, int stream);
|
|||
int snd_soc_runtime_set_dai_fmt(struct snd_soc_pcm_runtime *rtd,
|
||||
unsigned int dai_fmt);
|
||||
|
||||
int snd_soc_set_dmi_name(struct snd_soc_card *card, const char *flavour);
|
||||
|
||||
/* Utility functions to get clock rates from various things */
|
||||
int snd_soc_calc_frame_size(int sample_size, int channels, int tdm_slots);
|
||||
int snd_soc_params_to_frame_size(struct snd_pcm_hw_params *params);
|
||||
|
@ -507,9 +509,6 @@ int snd_soc_params_to_bclk(struct snd_pcm_hw_params *parms);
|
|||
int snd_soc_set_runtime_hwparams(struct snd_pcm_substream *substream,
|
||||
const struct snd_pcm_hardware *hw);
|
||||
|
||||
int snd_soc_platform_trigger(struct snd_pcm_substream *substream,
|
||||
int cmd, struct snd_soc_platform *platform);
|
||||
|
||||
int soc_dai_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params,
|
||||
struct snd_soc_dai *dai);
|
||||
|
@ -785,6 +784,10 @@ struct snd_soc_component_driver {
|
|||
int (*suspend)(struct snd_soc_component *);
|
||||
int (*resume)(struct snd_soc_component *);
|
||||
|
||||
/* pcm creation and destruction */
|
||||
int (*pcm_new)(struct snd_soc_pcm_runtime *);
|
||||
void (*pcm_free)(struct snd_pcm *);
|
||||
|
||||
/* DT */
|
||||
int (*of_xlate_dai_name)(struct snd_soc_component *component,
|
||||
struct of_phandle_args *args,
|
||||
|
@ -859,6 +862,8 @@ struct snd_soc_component {
|
|||
void (*remove)(struct snd_soc_component *);
|
||||
int (*suspend)(struct snd_soc_component *);
|
||||
int (*resume)(struct snd_soc_component *);
|
||||
int (*pcm_new)(struct snd_soc_pcm_runtime *);
|
||||
void (*pcm_free)(struct snd_pcm *);
|
||||
|
||||
/* machine specific init */
|
||||
int (*init)(struct snd_soc_component *component);
|
||||
|
@ -941,20 +946,11 @@ struct snd_soc_platform_driver {
|
|||
int (*pcm_new)(struct snd_soc_pcm_runtime *);
|
||||
void (*pcm_free)(struct snd_pcm *);
|
||||
|
||||
/*
|
||||
* For platform caused delay reporting.
|
||||
* Optional.
|
||||
*/
|
||||
snd_pcm_sframes_t (*delay)(struct snd_pcm_substream *,
|
||||
struct snd_soc_dai *);
|
||||
|
||||
/* platform stream pcm ops */
|
||||
const struct snd_pcm_ops *ops;
|
||||
|
||||
/* platform stream compress ops */
|
||||
const struct snd_compr_ops *compr_ops;
|
||||
|
||||
int (*bespoke_trigger)(struct snd_pcm_substream *, int);
|
||||
};
|
||||
|
||||
struct snd_soc_dai_link_component {
|
||||
|
@ -1099,6 +1095,8 @@ struct snd_soc_card {
|
|||
const char *name;
|
||||
const char *long_name;
|
||||
const char *driver_name;
|
||||
char dmi_longname[80];
|
||||
|
||||
struct device *dev;
|
||||
struct snd_card *snd_card;
|
||||
struct module *owner;
|
||||
|
@ -1647,37 +1645,21 @@ static inline struct snd_soc_platform *snd_soc_kcontrol_platform(
|
|||
int snd_soc_util_init(void);
|
||||
void snd_soc_util_exit(void);
|
||||
|
||||
#define snd_soc_of_parse_card_name(card, propname) \
|
||||
snd_soc_of_parse_card_name_from_node(card, NULL, propname)
|
||||
int snd_soc_of_parse_card_name_from_node(struct snd_soc_card *card,
|
||||
struct device_node *np,
|
||||
const char *propname);
|
||||
#define snd_soc_of_parse_audio_simple_widgets(card, propname)\
|
||||
snd_soc_of_parse_audio_simple_widgets_from_node(card, NULL, propname)
|
||||
int snd_soc_of_parse_audio_simple_widgets_from_node(struct snd_soc_card *card,
|
||||
struct device_node *np,
|
||||
const char *propname);
|
||||
|
||||
int snd_soc_of_parse_card_name(struct snd_soc_card *card,
|
||||
const char *propname);
|
||||
int snd_soc_of_parse_audio_simple_widgets(struct snd_soc_card *card,
|
||||
const char *propname);
|
||||
int snd_soc_of_parse_tdm_slot(struct device_node *np,
|
||||
unsigned int *tx_mask,
|
||||
unsigned int *rx_mask,
|
||||
unsigned int *slots,
|
||||
unsigned int *slot_width);
|
||||
#define snd_soc_of_parse_audio_prefix(card, codec_conf, of_node, propname) \
|
||||
snd_soc_of_parse_audio_prefix_from_node(card, NULL, codec_conf, \
|
||||
of_node, propname)
|
||||
void snd_soc_of_parse_audio_prefix_from_node(struct snd_soc_card *card,
|
||||
struct device_node *np,
|
||||
void snd_soc_of_parse_audio_prefix(struct snd_soc_card *card,
|
||||
struct snd_soc_codec_conf *codec_conf,
|
||||
struct device_node *of_node,
|
||||
const char *propname);
|
||||
|
||||
#define snd_soc_of_parse_audio_routing(card, propname) \
|
||||
snd_soc_of_parse_audio_routing_from_node(card, NULL, propname)
|
||||
int snd_soc_of_parse_audio_routing_from_node(struct snd_soc_card *card,
|
||||
struct device_node *np,
|
||||
const char *propname);
|
||||
|
||||
int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
|
||||
const char *propname);
|
||||
unsigned int snd_soc_of_parse_daifmt(struct device_node *np,
|
||||
const char *prefix,
|
||||
struct device_node **bitclkmaster,
|
||||
|
|
|
@ -108,6 +108,8 @@ source "sound/parisc/Kconfig"
|
|||
|
||||
source "sound/soc/Kconfig"
|
||||
|
||||
source "sound/x86/Kconfig"
|
||||
|
||||
endif # SND
|
||||
|
||||
menuconfig SOUND_PRIME
|
||||
|
|
|
@ -5,7 +5,7 @@ obj-$(CONFIG_SOUND) += soundcore.o
|
|||
obj-$(CONFIG_SOUND_PRIME) += oss/
|
||||
obj-$(CONFIG_DMASOUND) += oss/
|
||||
obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ sh/ synth/ usb/ \
|
||||
firewire/ sparc/ spi/ parisc/ pcmcia/ mips/ soc/ atmel/ hda/
|
||||
firewire/ sparc/ spi/ parisc/ pcmcia/ mips/ soc/ atmel/ hda/ x86/
|
||||
obj-$(CONFIG_SND_AOA) += aoa/
|
||||
|
||||
# This one must be compilable even if sound is configured out
|
||||
|
|
|
@ -1749,7 +1749,7 @@ static int snd_rawmidi_dev_disconnect(struct snd_device *device)
|
|||
* Sets the rawmidi operators for the given stream direction.
|
||||
*/
|
||||
void snd_rawmidi_set_ops(struct snd_rawmidi *rmidi, int stream,
|
||||
struct snd_rawmidi_ops *ops)
|
||||
const struct snd_rawmidi_ops *ops)
|
||||
{
|
||||
struct snd_rawmidi_substream *substream;
|
||||
|
||||
|
|
|
@ -349,13 +349,13 @@ static int snd_virmidi_unuse(void *private_data,
|
|||
* Register functions
|
||||
*/
|
||||
|
||||
static struct snd_rawmidi_ops snd_virmidi_input_ops = {
|
||||
static const struct snd_rawmidi_ops snd_virmidi_input_ops = {
|
||||
.open = snd_virmidi_input_open,
|
||||
.close = snd_virmidi_input_close,
|
||||
.trigger = snd_virmidi_input_trigger,
|
||||
};
|
||||
|
||||
static struct snd_rawmidi_ops snd_virmidi_output_ops = {
|
||||
static const struct snd_rawmidi_ops snd_virmidi_output_ops = {
|
||||
.open = snd_virmidi_output_open,
|
||||
.close = snd_virmidi_output_close,
|
||||
.trigger = snd_virmidi_output_trigger,
|
||||
|
|
|
@ -481,14 +481,14 @@ snd_mpu401_uart_output_trigger(struct snd_rawmidi_substream *substream, int up)
|
|||
|
||||
*/
|
||||
|
||||
static struct snd_rawmidi_ops snd_mpu401_uart_output =
|
||||
static const struct snd_rawmidi_ops snd_mpu401_uart_output =
|
||||
{
|
||||
.open = snd_mpu401_uart_output_open,
|
||||
.close = snd_mpu401_uart_output_close,
|
||||
.trigger = snd_mpu401_uart_output_trigger,
|
||||
};
|
||||
|
||||
static struct snd_rawmidi_ops snd_mpu401_uart_input =
|
||||
static const struct snd_rawmidi_ops snd_mpu401_uart_input =
|
||||
{
|
||||
.open = snd_mpu401_uart_input_open,
|
||||
.close = snd_mpu401_uart_input_close,
|
||||
|
|
|
@ -600,13 +600,13 @@ static int snd_mtpav_get_ISA(struct mtpav *mcard)
|
|||
/*
|
||||
*/
|
||||
|
||||
static struct snd_rawmidi_ops snd_mtpav_output = {
|
||||
static const struct snd_rawmidi_ops snd_mtpav_output = {
|
||||
.open = snd_mtpav_output_open,
|
||||
.close = snd_mtpav_output_close,
|
||||
.trigger = snd_mtpav_output_trigger,
|
||||
};
|
||||
|
||||
static struct snd_rawmidi_ops snd_mtpav_input = {
|
||||
static const struct snd_rawmidi_ops snd_mtpav_input = {
|
||||
.open = snd_mtpav_input_open,
|
||||
.close = snd_mtpav_input_close,
|
||||
.trigger = snd_mtpav_input_trigger,
|
||||
|
|
|
@ -749,13 +749,13 @@ static void snd_mts64_rawmidi_input_trigger(struct snd_rawmidi_substream *substr
|
|||
spin_unlock_irqrestore(&mts->lock, flags);
|
||||
}
|
||||
|
||||
static struct snd_rawmidi_ops snd_mts64_rawmidi_output_ops = {
|
||||
static const struct snd_rawmidi_ops snd_mts64_rawmidi_output_ops = {
|
||||
.open = snd_mts64_rawmidi_open,
|
||||
.close = snd_mts64_rawmidi_close,
|
||||
.trigger = snd_mts64_rawmidi_output_trigger
|
||||
};
|
||||
|
||||
static struct snd_rawmidi_ops snd_mts64_rawmidi_input_ops = {
|
||||
static const struct snd_rawmidi_ops snd_mts64_rawmidi_input_ops = {
|
||||
.open = snd_mts64_rawmidi_open,
|
||||
.close = snd_mts64_rawmidi_close,
|
||||
.trigger = snd_mts64_rawmidi_input_trigger
|
||||
|
|
|
@ -546,13 +546,13 @@ static void snd_portman_midi_output_trigger(struct snd_rawmidi_substream *substr
|
|||
spin_unlock_irqrestore(&pm->reg_lock, flags);
|
||||
}
|
||||
|
||||
static struct snd_rawmidi_ops snd_portman_midi_output = {
|
||||
static const struct snd_rawmidi_ops snd_portman_midi_output = {
|
||||
.open = snd_portman_midi_open,
|
||||
.close = snd_portman_midi_close,
|
||||
.trigger = snd_portman_midi_output_trigger,
|
||||
};
|
||||
|
||||
static struct snd_rawmidi_ops snd_portman_midi_input = {
|
||||
static const struct snd_rawmidi_ops snd_portman_midi_input = {
|
||||
.open = snd_portman_midi_open,
|
||||
.close = snd_portman_midi_close,
|
||||
.trigger = snd_portman_midi_input_trigger,
|
||||
|
|
|
@ -752,14 +752,14 @@ static void snd_uart16550_output_trigger(struct snd_rawmidi_substream *substream
|
|||
snd_uart16550_output_write(substream);
|
||||
}
|
||||
|
||||
static struct snd_rawmidi_ops snd_uart16550_output =
|
||||
static const struct snd_rawmidi_ops snd_uart16550_output =
|
||||
{
|
||||
.open = snd_uart16550_output_open,
|
||||
.close = snd_uart16550_output_close,
|
||||
.trigger = snd_uart16550_output_trigger,
|
||||
};
|
||||
|
||||
static struct snd_rawmidi_ops snd_uart16550_input =
|
||||
static const struct snd_rawmidi_ops snd_uart16550_input =
|
||||
{
|
||||
.open = snd_uart16550_input_open,
|
||||
.close = snd_uart16550_input_close,
|
||||
|
|
|
@ -1015,7 +1015,7 @@ static void vx_pcm_capture_update(struct vx_core *chip, struct snd_pcm_substream
|
|||
int size, space, count;
|
||||
struct snd_pcm_runtime *runtime = subs->runtime;
|
||||
|
||||
if (! pipe->prepared || (chip->chip_status & VX_STAT_IS_STALE))
|
||||
if (!pipe->running || (chip->chip_status & VX_STAT_IS_STALE))
|
||||
return;
|
||||
|
||||
size = runtime->buffer_size - snd_pcm_capture_avail(runtime);
|
||||
|
@ -1048,8 +1048,10 @@ static void vx_pcm_capture_update(struct vx_core *chip, struct snd_pcm_substream
|
|||
/* ok, let's accelerate! */
|
||||
int align = pipe->align * 3;
|
||||
space = (count / align) * align;
|
||||
vx_pseudo_dma_read(chip, runtime, pipe, space);
|
||||
count -= space;
|
||||
if (space > 0) {
|
||||
vx_pseudo_dma_read(chip, runtime, pipe, space);
|
||||
count -= space;
|
||||
}
|
||||
}
|
||||
/* read the rest of bytes */
|
||||
while (count > 0) {
|
||||
|
|
|
@ -34,6 +34,7 @@ config SND_OXFW
|
|||
* LaCie Firewire Speakers
|
||||
* Behringer F-Control Audio 202
|
||||
* Mackie(Loud) Onyx-i series (former models)
|
||||
* Mackie(Loud) Onyx 1640i (former model)
|
||||
* Mackie(Loud) Onyx Satellite
|
||||
* Mackie(Loud) Tapco Link.Firewire
|
||||
* Mackie(Loud) d.2 pro/d.4 pro
|
||||
|
|
|
@ -172,16 +172,15 @@ hwdep_compat_ioctl(struct snd_hwdep *hwdep, struct file *file,
|
|||
#define hwdep_compat_ioctl NULL
|
||||
#endif
|
||||
|
||||
static const struct snd_hwdep_ops hwdep_ops = {
|
||||
.read = hwdep_read,
|
||||
.release = hwdep_release,
|
||||
.poll = hwdep_poll,
|
||||
.ioctl = hwdep_ioctl,
|
||||
.ioctl_compat = hwdep_compat_ioctl,
|
||||
};
|
||||
|
||||
int snd_bebob_create_hwdep_device(struct snd_bebob *bebob)
|
||||
{
|
||||
static const struct snd_hwdep_ops ops = {
|
||||
.read = hwdep_read,
|
||||
.release = hwdep_release,
|
||||
.poll = hwdep_poll,
|
||||
.ioctl = hwdep_ioctl,
|
||||
.ioctl_compat = hwdep_compat_ioctl,
|
||||
};
|
||||
struct snd_hwdep *hwdep;
|
||||
int err;
|
||||
|
||||
|
@ -190,7 +189,7 @@ int snd_bebob_create_hwdep_device(struct snd_bebob *bebob)
|
|||
goto end;
|
||||
strcpy(hwdep->name, "BeBoB");
|
||||
hwdep->iface = SNDRV_HWDEP_IFACE_FW_BEBOB;
|
||||
hwdep->ops = hwdep_ops;
|
||||
hwdep->ops = ops;
|
||||
hwdep->private_data = bebob;
|
||||
hwdep->exclusive = true;
|
||||
end:
|
||||
|
|
|
@ -106,18 +106,6 @@ static void midi_playback_trigger(struct snd_rawmidi_substream *substrm, int up)
|
|||
spin_unlock_irqrestore(&bebob->lock, flags);
|
||||
}
|
||||
|
||||
static struct snd_rawmidi_ops midi_capture_ops = {
|
||||
.open = midi_capture_open,
|
||||
.close = midi_capture_close,
|
||||
.trigger = midi_capture_trigger,
|
||||
};
|
||||
|
||||
static struct snd_rawmidi_ops midi_playback_ops = {
|
||||
.open = midi_playback_open,
|
||||
.close = midi_playback_close,
|
||||
.trigger = midi_playback_trigger,
|
||||
};
|
||||
|
||||
static void set_midi_substream_names(struct snd_bebob *bebob,
|
||||
struct snd_rawmidi_str *str)
|
||||
{
|
||||
|
@ -132,6 +120,16 @@ static void set_midi_substream_names(struct snd_bebob *bebob,
|
|||
|
||||
int snd_bebob_create_midi_devices(struct snd_bebob *bebob)
|
||||
{
|
||||
static const struct snd_rawmidi_ops capture_ops = {
|
||||
.open = midi_capture_open,
|
||||
.close = midi_capture_close,
|
||||
.trigger = midi_capture_trigger,
|
||||
};
|
||||
static const struct snd_rawmidi_ops playback_ops = {
|
||||
.open = midi_playback_open,
|
||||
.close = midi_playback_close,
|
||||
.trigger = midi_playback_trigger,
|
||||
};
|
||||
struct snd_rawmidi *rmidi;
|
||||
struct snd_rawmidi_str *str;
|
||||
int err;
|
||||
|
@ -151,7 +149,7 @@ int snd_bebob_create_midi_devices(struct snd_bebob *bebob)
|
|||
rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT;
|
||||
|
||||
snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT,
|
||||
&midi_capture_ops);
|
||||
&capture_ops);
|
||||
|
||||
str = &rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT];
|
||||
|
||||
|
@ -162,7 +160,7 @@ int snd_bebob_create_midi_devices(struct snd_bebob *bebob)
|
|||
rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT;
|
||||
|
||||
snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
|
||||
&midi_playback_ops);
|
||||
&playback_ops);
|
||||
|
||||
str = &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT];
|
||||
|
||||
|
|
|
@ -359,32 +359,31 @@ pcm_playback_pointer(struct snd_pcm_substream *sbstrm)
|
|||
return amdtp_stream_pcm_pointer(&bebob->rx_stream);
|
||||
}
|
||||
|
||||
static const struct snd_pcm_ops pcm_capture_ops = {
|
||||
.open = pcm_open,
|
||||
.close = pcm_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
.hw_params = pcm_capture_hw_params,
|
||||
.hw_free = pcm_capture_hw_free,
|
||||
.prepare = pcm_capture_prepare,
|
||||
.trigger = pcm_capture_trigger,
|
||||
.pointer = pcm_capture_pointer,
|
||||
.page = snd_pcm_lib_get_vmalloc_page,
|
||||
};
|
||||
static const struct snd_pcm_ops pcm_playback_ops = {
|
||||
.open = pcm_open,
|
||||
.close = pcm_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
.hw_params = pcm_playback_hw_params,
|
||||
.hw_free = pcm_playback_hw_free,
|
||||
.prepare = pcm_playback_prepare,
|
||||
.trigger = pcm_playback_trigger,
|
||||
.pointer = pcm_playback_pointer,
|
||||
.page = snd_pcm_lib_get_vmalloc_page,
|
||||
.mmap = snd_pcm_lib_mmap_vmalloc,
|
||||
};
|
||||
|
||||
int snd_bebob_create_pcm_devices(struct snd_bebob *bebob)
|
||||
{
|
||||
static const struct snd_pcm_ops capture_ops = {
|
||||
.open = pcm_open,
|
||||
.close = pcm_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
.hw_params = pcm_capture_hw_params,
|
||||
.hw_free = pcm_capture_hw_free,
|
||||
.prepare = pcm_capture_prepare,
|
||||
.trigger = pcm_capture_trigger,
|
||||
.pointer = pcm_capture_pointer,
|
||||
.page = snd_pcm_lib_get_vmalloc_page,
|
||||
};
|
||||
static const struct snd_pcm_ops playback_ops = {
|
||||
.open = pcm_open,
|
||||
.close = pcm_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
.hw_params = pcm_playback_hw_params,
|
||||
.hw_free = pcm_playback_hw_free,
|
||||
.prepare = pcm_playback_prepare,
|
||||
.trigger = pcm_playback_trigger,
|
||||
.pointer = pcm_playback_pointer,
|
||||
.page = snd_pcm_lib_get_vmalloc_page,
|
||||
.mmap = snd_pcm_lib_mmap_vmalloc,
|
||||
};
|
||||
struct snd_pcm *pcm;
|
||||
int err;
|
||||
|
||||
|
@ -395,8 +394,8 @@ int snd_bebob_create_pcm_devices(struct snd_bebob *bebob)
|
|||
pcm->private_data = bebob;
|
||||
snprintf(pcm->name, sizeof(pcm->name),
|
||||
"%s PCM", bebob->card->shortname);
|
||||
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &pcm_playback_ops);
|
||||
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &pcm_capture_ops);
|
||||
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &playback_ops);
|
||||
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &capture_ops);
|
||||
end:
|
||||
return err;
|
||||
}
|
||||
|
|
|
@ -251,6 +251,7 @@
|
|||
|
||||
/*
|
||||
* The speed at which the packets are sent, SCODE_100-_400; read/write.
|
||||
* SCODE_800 is only available in Dice III.
|
||||
*/
|
||||
#define TX_SPEED 0x014
|
||||
|
||||
|
|
|
@ -78,18 +78,6 @@ static void midi_playback_trigger(struct snd_rawmidi_substream *substrm, int up)
|
|||
spin_unlock_irqrestore(&dice->lock, flags);
|
||||
}
|
||||
|
||||
static struct snd_rawmidi_ops capture_ops = {
|
||||
.open = midi_open,
|
||||
.close = midi_close,
|
||||
.trigger = midi_capture_trigger,
|
||||
};
|
||||
|
||||
static struct snd_rawmidi_ops playback_ops = {
|
||||
.open = midi_open,
|
||||
.close = midi_close,
|
||||
.trigger = midi_playback_trigger,
|
||||
};
|
||||
|
||||
static void set_midi_substream_names(struct snd_dice *dice,
|
||||
struct snd_rawmidi_str *str)
|
||||
{
|
||||
|
@ -103,6 +91,16 @@ static void set_midi_substream_names(struct snd_dice *dice,
|
|||
|
||||
int snd_dice_create_midi(struct snd_dice *dice)
|
||||
{
|
||||
static const struct snd_rawmidi_ops capture_ops = {
|
||||
.open = midi_open,
|
||||
.close = midi_close,
|
||||
.trigger = midi_capture_trigger,
|
||||
};
|
||||
static const struct snd_rawmidi_ops playback_ops = {
|
||||
.open = midi_open,
|
||||
.close = midi_close,
|
||||
.trigger = midi_playback_trigger,
|
||||
};
|
||||
__be32 reg;
|
||||
struct snd_rawmidi *rmidi;
|
||||
struct snd_rawmidi_str *str;
|
||||
|
|
|
@ -195,6 +195,7 @@ static int start_streams(struct snd_dice *dice, enum amdtp_stream_direction dir,
|
|||
unsigned int i, pcm_chs, midi_ports;
|
||||
struct amdtp_stream *streams;
|
||||
struct fw_iso_resources *resources;
|
||||
struct fw_device *fw_dev = fw_parent_device(dice->unit);
|
||||
int err = 0;
|
||||
|
||||
if (dir == AMDTP_IN_STREAM) {
|
||||
|
@ -237,8 +238,17 @@ static int start_streams(struct snd_dice *dice, enum amdtp_stream_direction dir,
|
|||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (dir == AMDTP_IN_STREAM) {
|
||||
reg[0] = cpu_to_be32(fw_dev->max_speed);
|
||||
err = snd_dice_transaction_write_tx(dice,
|
||||
params->size * i + TX_SPEED,
|
||||
reg, sizeof(reg[0]));
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
||||
err = amdtp_stream_start(&streams[i], resources[i].channel,
|
||||
fw_parent_device(dice->unit)->max_speed);
|
||||
fw_dev->max_speed);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
|
|
@ -173,16 +173,15 @@ static int hwdep_compat_ioctl(struct snd_hwdep *hwdep, struct file *file,
|
|||
#define hwdep_compat_ioctl NULL
|
||||
#endif
|
||||
|
||||
static const struct snd_hwdep_ops hwdep_ops = {
|
||||
.read = hwdep_read,
|
||||
.release = hwdep_release,
|
||||
.poll = hwdep_poll,
|
||||
.ioctl = hwdep_ioctl,
|
||||
.ioctl_compat = hwdep_compat_ioctl,
|
||||
};
|
||||
|
||||
int snd_dg00x_create_hwdep_device(struct snd_dg00x *dg00x)
|
||||
{
|
||||
static const struct snd_hwdep_ops ops = {
|
||||
.read = hwdep_read,
|
||||
.release = hwdep_release,
|
||||
.poll = hwdep_poll,
|
||||
.ioctl = hwdep_ioctl,
|
||||
.ioctl_compat = hwdep_compat_ioctl,
|
||||
};
|
||||
struct snd_hwdep *hwdep;
|
||||
int err;
|
||||
|
||||
|
@ -192,7 +191,7 @@ int snd_dg00x_create_hwdep_device(struct snd_dg00x *dg00x)
|
|||
|
||||
strcpy(hwdep->name, "Digi00x");
|
||||
hwdep->iface = SNDRV_HWDEP_IFACE_FW_DIGI00X;
|
||||
hwdep->ops = hwdep_ops;
|
||||
hwdep->ops = ops;
|
||||
hwdep->private_data = dg00x;
|
||||
hwdep->exclusive = true;
|
||||
|
||||
|
|
|
@ -76,18 +76,6 @@ static void midi_phys_playback_trigger(struct snd_rawmidi_substream *substream,
|
|||
spin_unlock_irqrestore(&dg00x->lock, flags);
|
||||
}
|
||||
|
||||
static struct snd_rawmidi_ops midi_phys_capture_ops = {
|
||||
.open = midi_phys_open,
|
||||
.close = midi_phys_close,
|
||||
.trigger = midi_phys_capture_trigger,
|
||||
};
|
||||
|
||||
static struct snd_rawmidi_ops midi_phys_playback_ops = {
|
||||
.open = midi_phys_open,
|
||||
.close = midi_phys_close,
|
||||
.trigger = midi_phys_playback_trigger,
|
||||
};
|
||||
|
||||
static int midi_ctl_open(struct snd_rawmidi_substream *substream)
|
||||
{
|
||||
/* Do nothing. */
|
||||
|
@ -139,18 +127,6 @@ static void midi_ctl_playback_trigger(struct snd_rawmidi_substream *substream,
|
|||
spin_unlock_irqrestore(&dg00x->lock, flags);
|
||||
}
|
||||
|
||||
static struct snd_rawmidi_ops midi_ctl_capture_ops = {
|
||||
.open = midi_ctl_open,
|
||||
.close = midi_ctl_capture_close,
|
||||
.trigger = midi_ctl_capture_trigger,
|
||||
};
|
||||
|
||||
static struct snd_rawmidi_ops midi_ctl_playback_ops = {
|
||||
.open = midi_ctl_open,
|
||||
.close = midi_ctl_playback_close,
|
||||
.trigger = midi_ctl_playback_trigger,
|
||||
};
|
||||
|
||||
static void set_midi_substream_names(struct snd_dg00x *dg00x,
|
||||
struct snd_rawmidi_str *str,
|
||||
bool is_ctl)
|
||||
|
@ -172,6 +148,26 @@ static void set_midi_substream_names(struct snd_dg00x *dg00x,
|
|||
|
||||
int snd_dg00x_create_midi_devices(struct snd_dg00x *dg00x)
|
||||
{
|
||||
static const struct snd_rawmidi_ops phys_capture_ops = {
|
||||
.open = midi_phys_open,
|
||||
.close = midi_phys_close,
|
||||
.trigger = midi_phys_capture_trigger,
|
||||
};
|
||||
static const struct snd_rawmidi_ops phys_playback_ops = {
|
||||
.open = midi_phys_open,
|
||||
.close = midi_phys_close,
|
||||
.trigger = midi_phys_playback_trigger,
|
||||
};
|
||||
static const struct snd_rawmidi_ops ctl_capture_ops = {
|
||||
.open = midi_ctl_open,
|
||||
.close = midi_ctl_capture_close,
|
||||
.trigger = midi_ctl_capture_trigger,
|
||||
};
|
||||
static const struct snd_rawmidi_ops ctl_playback_ops = {
|
||||
.open = midi_ctl_open,
|
||||
.close = midi_ctl_playback_close,
|
||||
.trigger = midi_ctl_playback_trigger,
|
||||
};
|
||||
struct snd_rawmidi *rmidi[2];
|
||||
struct snd_rawmidi_str *str;
|
||||
unsigned int i;
|
||||
|
@ -187,9 +183,9 @@ int snd_dg00x_create_midi_devices(struct snd_dg00x *dg00x)
|
|||
"%s MIDI", dg00x->card->shortname);
|
||||
|
||||
snd_rawmidi_set_ops(rmidi[0], SNDRV_RAWMIDI_STREAM_INPUT,
|
||||
&midi_phys_capture_ops);
|
||||
&phys_capture_ops);
|
||||
snd_rawmidi_set_ops(rmidi[0], SNDRV_RAWMIDI_STREAM_OUTPUT,
|
||||
&midi_phys_playback_ops);
|
||||
&phys_playback_ops);
|
||||
|
||||
/* Add a pair of control midi ports. */
|
||||
err = snd_rawmidi_new(dg00x->card, dg00x->card->driver, 1,
|
||||
|
@ -201,9 +197,9 @@ int snd_dg00x_create_midi_devices(struct snd_dg00x *dg00x)
|
|||
"%s control", dg00x->card->shortname);
|
||||
|
||||
snd_rawmidi_set_ops(rmidi[1], SNDRV_RAWMIDI_STREAM_INPUT,
|
||||
&midi_ctl_capture_ops);
|
||||
&ctl_capture_ops);
|
||||
snd_rawmidi_set_ops(rmidi[1], SNDRV_RAWMIDI_STREAM_OUTPUT,
|
||||
&midi_ctl_playback_ops);
|
||||
&ctl_playback_ops);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(rmidi); i++) {
|
||||
rmidi[i]->private_data = dg00x;
|
||||
|
|
|
@ -329,33 +329,31 @@ static snd_pcm_uframes_t pcm_playback_pointer(struct snd_pcm_substream *sbstrm)
|
|||
return amdtp_stream_pcm_pointer(&dg00x->rx_stream);
|
||||
}
|
||||
|
||||
static const struct snd_pcm_ops pcm_capture_ops = {
|
||||
.open = pcm_open,
|
||||
.close = pcm_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
.hw_params = pcm_capture_hw_params,
|
||||
.hw_free = pcm_capture_hw_free,
|
||||
.prepare = pcm_capture_prepare,
|
||||
.trigger = pcm_capture_trigger,
|
||||
.pointer = pcm_capture_pointer,
|
||||
.page = snd_pcm_lib_get_vmalloc_page,
|
||||
};
|
||||
|
||||
static const struct snd_pcm_ops pcm_playback_ops = {
|
||||
.open = pcm_open,
|
||||
.close = pcm_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
.hw_params = pcm_playback_hw_params,
|
||||
.hw_free = pcm_playback_hw_free,
|
||||
.prepare = pcm_playback_prepare,
|
||||
.trigger = pcm_playback_trigger,
|
||||
.pointer = pcm_playback_pointer,
|
||||
.page = snd_pcm_lib_get_vmalloc_page,
|
||||
.mmap = snd_pcm_lib_mmap_vmalloc,
|
||||
};
|
||||
|
||||
int snd_dg00x_create_pcm_devices(struct snd_dg00x *dg00x)
|
||||
{
|
||||
static const struct snd_pcm_ops capture_ops = {
|
||||
.open = pcm_open,
|
||||
.close = pcm_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
.hw_params = pcm_capture_hw_params,
|
||||
.hw_free = pcm_capture_hw_free,
|
||||
.prepare = pcm_capture_prepare,
|
||||
.trigger = pcm_capture_trigger,
|
||||
.pointer = pcm_capture_pointer,
|
||||
.page = snd_pcm_lib_get_vmalloc_page,
|
||||
};
|
||||
static const struct snd_pcm_ops playback_ops = {
|
||||
.open = pcm_open,
|
||||
.close = pcm_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
.hw_params = pcm_playback_hw_params,
|
||||
.hw_free = pcm_playback_hw_free,
|
||||
.prepare = pcm_playback_prepare,
|
||||
.trigger = pcm_playback_trigger,
|
||||
.pointer = pcm_playback_pointer,
|
||||
.page = snd_pcm_lib_get_vmalloc_page,
|
||||
.mmap = snd_pcm_lib_mmap_vmalloc,
|
||||
};
|
||||
struct snd_pcm *pcm;
|
||||
int err;
|
||||
|
||||
|
@ -366,8 +364,8 @@ int snd_dg00x_create_pcm_devices(struct snd_dg00x *dg00x)
|
|||
pcm->private_data = dg00x;
|
||||
snprintf(pcm->name, sizeof(pcm->name),
|
||||
"%s PCM", dg00x->card->shortname);
|
||||
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &pcm_playback_ops);
|
||||
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &pcm_capture_ops);
|
||||
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &playback_ops);
|
||||
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &capture_ops);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -303,17 +303,16 @@ hwdep_compat_ioctl(struct snd_hwdep *hwdep, struct file *file,
|
|||
#define hwdep_compat_ioctl NULL
|
||||
#endif
|
||||
|
||||
static const struct snd_hwdep_ops hwdep_ops = {
|
||||
.read = hwdep_read,
|
||||
.write = hwdep_write,
|
||||
.release = hwdep_release,
|
||||
.poll = hwdep_poll,
|
||||
.ioctl = hwdep_ioctl,
|
||||
.ioctl_compat = hwdep_compat_ioctl,
|
||||
};
|
||||
|
||||
int snd_efw_create_hwdep_device(struct snd_efw *efw)
|
||||
{
|
||||
static const struct snd_hwdep_ops ops = {
|
||||
.read = hwdep_read,
|
||||
.write = hwdep_write,
|
||||
.release = hwdep_release,
|
||||
.poll = hwdep_poll,
|
||||
.ioctl = hwdep_ioctl,
|
||||
.ioctl_compat = hwdep_compat_ioctl,
|
||||
};
|
||||
struct snd_hwdep *hwdep;
|
||||
int err;
|
||||
|
||||
|
@ -322,7 +321,7 @@ int snd_efw_create_hwdep_device(struct snd_efw *efw)
|
|||
goto end;
|
||||
strcpy(hwdep->name, "Fireworks");
|
||||
hwdep->iface = SNDRV_HWDEP_IFACE_FW_FIREWORKS;
|
||||
hwdep->ops = hwdep_ops;
|
||||
hwdep->ops = ops;
|
||||
hwdep->private_data = efw;
|
||||
hwdep->exclusive = true;
|
||||
end:
|
||||
|
|
|
@ -107,18 +107,6 @@ static void midi_playback_trigger(struct snd_rawmidi_substream *substrm, int up)
|
|||
spin_unlock_irqrestore(&efw->lock, flags);
|
||||
}
|
||||
|
||||
static struct snd_rawmidi_ops midi_capture_ops = {
|
||||
.open = midi_capture_open,
|
||||
.close = midi_capture_close,
|
||||
.trigger = midi_capture_trigger,
|
||||
};
|
||||
|
||||
static struct snd_rawmidi_ops midi_playback_ops = {
|
||||
.open = midi_playback_open,
|
||||
.close = midi_playback_close,
|
||||
.trigger = midi_playback_trigger,
|
||||
};
|
||||
|
||||
static void set_midi_substream_names(struct snd_efw *efw,
|
||||
struct snd_rawmidi_str *str)
|
||||
{
|
||||
|
@ -132,6 +120,16 @@ static void set_midi_substream_names(struct snd_efw *efw,
|
|||
|
||||
int snd_efw_create_midi_devices(struct snd_efw *efw)
|
||||
{
|
||||
static const struct snd_rawmidi_ops capture_ops = {
|
||||
.open = midi_capture_open,
|
||||
.close = midi_capture_close,
|
||||
.trigger = midi_capture_trigger,
|
||||
};
|
||||
static const struct snd_rawmidi_ops playback_ops = {
|
||||
.open = midi_playback_open,
|
||||
.close = midi_playback_close,
|
||||
.trigger = midi_playback_trigger,
|
||||
};
|
||||
struct snd_rawmidi *rmidi;
|
||||
struct snd_rawmidi_str *str;
|
||||
int err;
|
||||
|
@ -151,7 +149,7 @@ int snd_efw_create_midi_devices(struct snd_efw *efw)
|
|||
rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT;
|
||||
|
||||
snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT,
|
||||
&midi_capture_ops);
|
||||
&capture_ops);
|
||||
|
||||
str = &rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT];
|
||||
|
||||
|
@ -162,7 +160,7 @@ int snd_efw_create_midi_devices(struct snd_efw *efw)
|
|||
rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT;
|
||||
|
||||
snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
|
||||
&midi_playback_ops);
|
||||
&playback_ops);
|
||||
|
||||
str = &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT];
|
||||
|
||||
|
|
|
@ -383,33 +383,31 @@ static snd_pcm_uframes_t pcm_playback_pointer(struct snd_pcm_substream *sbstrm)
|
|||
return amdtp_stream_pcm_pointer(&efw->rx_stream);
|
||||
}
|
||||
|
||||
static const struct snd_pcm_ops pcm_capture_ops = {
|
||||
.open = pcm_open,
|
||||
.close = pcm_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
.hw_params = pcm_capture_hw_params,
|
||||
.hw_free = pcm_capture_hw_free,
|
||||
.prepare = pcm_capture_prepare,
|
||||
.trigger = pcm_capture_trigger,
|
||||
.pointer = pcm_capture_pointer,
|
||||
.page = snd_pcm_lib_get_vmalloc_page,
|
||||
};
|
||||
|
||||
static const struct snd_pcm_ops pcm_playback_ops = {
|
||||
.open = pcm_open,
|
||||
.close = pcm_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
.hw_params = pcm_playback_hw_params,
|
||||
.hw_free = pcm_playback_hw_free,
|
||||
.prepare = pcm_playback_prepare,
|
||||
.trigger = pcm_playback_trigger,
|
||||
.pointer = pcm_playback_pointer,
|
||||
.page = snd_pcm_lib_get_vmalloc_page,
|
||||
.mmap = snd_pcm_lib_mmap_vmalloc,
|
||||
};
|
||||
|
||||
int snd_efw_create_pcm_devices(struct snd_efw *efw)
|
||||
{
|
||||
static const struct snd_pcm_ops capture_ops = {
|
||||
.open = pcm_open,
|
||||
.close = pcm_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
.hw_params = pcm_capture_hw_params,
|
||||
.hw_free = pcm_capture_hw_free,
|
||||
.prepare = pcm_capture_prepare,
|
||||
.trigger = pcm_capture_trigger,
|
||||
.pointer = pcm_capture_pointer,
|
||||
.page = snd_pcm_lib_get_vmalloc_page,
|
||||
};
|
||||
static const struct snd_pcm_ops playback_ops = {
|
||||
.open = pcm_open,
|
||||
.close = pcm_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
.hw_params = pcm_playback_hw_params,
|
||||
.hw_free = pcm_playback_hw_free,
|
||||
.prepare = pcm_playback_prepare,
|
||||
.trigger = pcm_playback_trigger,
|
||||
.pointer = pcm_playback_pointer,
|
||||
.page = snd_pcm_lib_get_vmalloc_page,
|
||||
.mmap = snd_pcm_lib_mmap_vmalloc,
|
||||
};
|
||||
struct snd_pcm *pcm;
|
||||
int err;
|
||||
|
||||
|
@ -419,8 +417,8 @@ int snd_efw_create_pcm_devices(struct snd_efw *efw)
|
|||
|
||||
pcm->private_data = efw;
|
||||
snprintf(pcm->name, sizeof(pcm->name), "%s PCM", efw->card->shortname);
|
||||
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &pcm_playback_ops);
|
||||
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &pcm_capture_ops);
|
||||
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &playback_ops);
|
||||
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &capture_ops);
|
||||
end:
|
||||
return err;
|
||||
}
|
||||
|
|
|
@ -116,18 +116,6 @@ static void midi_playback_trigger(struct snd_rawmidi_substream *substrm, int up)
|
|||
spin_unlock_irqrestore(&oxfw->lock, flags);
|
||||
}
|
||||
|
||||
static struct snd_rawmidi_ops midi_capture_ops = {
|
||||
.open = midi_capture_open,
|
||||
.close = midi_capture_close,
|
||||
.trigger = midi_capture_trigger,
|
||||
};
|
||||
|
||||
static struct snd_rawmidi_ops midi_playback_ops = {
|
||||
.open = midi_playback_open,
|
||||
.close = midi_playback_close,
|
||||
.trigger = midi_playback_trigger,
|
||||
};
|
||||
|
||||
static void set_midi_substream_names(struct snd_oxfw *oxfw,
|
||||
struct snd_rawmidi_str *str)
|
||||
{
|
||||
|
@ -142,6 +130,16 @@ static void set_midi_substream_names(struct snd_oxfw *oxfw,
|
|||
|
||||
int snd_oxfw_create_midi(struct snd_oxfw *oxfw)
|
||||
{
|
||||
static const struct snd_rawmidi_ops capture_ops = {
|
||||
.open = midi_capture_open,
|
||||
.close = midi_capture_close,
|
||||
.trigger = midi_capture_trigger,
|
||||
};
|
||||
static const struct snd_rawmidi_ops playback_ops = {
|
||||
.open = midi_playback_open,
|
||||
.close = midi_playback_close,
|
||||
.trigger = midi_playback_trigger,
|
||||
};
|
||||
struct snd_rawmidi *rmidi;
|
||||
struct snd_rawmidi_str *str;
|
||||
int err;
|
||||
|
@ -164,7 +162,7 @@ int snd_oxfw_create_midi(struct snd_oxfw *oxfw)
|
|||
rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT;
|
||||
|
||||
snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT,
|
||||
&midi_capture_ops);
|
||||
&capture_ops);
|
||||
|
||||
str = &rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT];
|
||||
|
||||
|
@ -175,7 +173,7 @@ int snd_oxfw_create_midi(struct snd_oxfw *oxfw)
|
|||
rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT;
|
||||
|
||||
snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
|
||||
&midi_playback_ops);
|
||||
&playback_ops);
|
||||
|
||||
str = &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT];
|
||||
|
||||
|
|
|
@ -297,7 +297,7 @@ static void midi_capture_trigger(struct snd_rawmidi_substream *stream, int up)
|
|||
}
|
||||
}
|
||||
|
||||
static struct snd_rawmidi_ops midi_capture_ops = {
|
||||
static const struct snd_rawmidi_ops midi_capture_ops = {
|
||||
.open = midi_capture_open,
|
||||
.close = midi_capture_close,
|
||||
.trigger = midi_capture_trigger,
|
||||
|
@ -338,12 +338,6 @@ static void midi_playback_drain(struct snd_rawmidi_substream *stream)
|
|||
wait_event(scs->idle_wait, scs->output_idle);
|
||||
}
|
||||
|
||||
static struct snd_rawmidi_ops midi_playback_ops = {
|
||||
.open = midi_playback_open,
|
||||
.close = midi_playback_close,
|
||||
.trigger = midi_playback_trigger,
|
||||
.drain = midi_playback_drain,
|
||||
};
|
||||
static int register_address(struct snd_oxfw *oxfw)
|
||||
{
|
||||
struct fw_scs1x *scs = oxfw->spec;
|
||||
|
@ -369,6 +363,12 @@ void snd_oxfw_scs1x_update(struct snd_oxfw *oxfw)
|
|||
|
||||
int snd_oxfw_scs1x_add(struct snd_oxfw *oxfw)
|
||||
{
|
||||
static const struct snd_rawmidi_ops midi_playback_ops = {
|
||||
.open = midi_playback_open,
|
||||
.close = midi_playback_close,
|
||||
.trigger = midi_playback_trigger,
|
||||
.drain = midi_playback_drain,
|
||||
};
|
||||
struct snd_rawmidi *rmidi;
|
||||
struct fw_scs1x *scs;
|
||||
int err;
|
||||
|
|
|
@ -43,6 +43,7 @@ static bool detect_loud_models(struct fw_unit *unit)
|
|||
const char *const models[] = {
|
||||
"Onyxi",
|
||||
"Onyx-i",
|
||||
"Onyx 1640i",
|
||||
"d.Pro",
|
||||
"Mackie Onyx Satellite",
|
||||
"Tapco LINK.firewire 4x6",
|
||||
|
|
|
@ -163,16 +163,15 @@ static int hwdep_compat_ioctl(struct snd_hwdep *hwdep, struct file *file,
|
|||
#define hwdep_compat_ioctl NULL
|
||||
#endif
|
||||
|
||||
static const struct snd_hwdep_ops hwdep_ops = {
|
||||
.read = hwdep_read,
|
||||
.release = hwdep_release,
|
||||
.poll = hwdep_poll,
|
||||
.ioctl = hwdep_ioctl,
|
||||
.ioctl_compat = hwdep_compat_ioctl,
|
||||
};
|
||||
|
||||
int snd_tscm_create_hwdep_device(struct snd_tscm *tscm)
|
||||
{
|
||||
static const struct snd_hwdep_ops ops = {
|
||||
.read = hwdep_read,
|
||||
.release = hwdep_release,
|
||||
.poll = hwdep_poll,
|
||||
.ioctl = hwdep_ioctl,
|
||||
.ioctl_compat = hwdep_compat_ioctl,
|
||||
};
|
||||
struct snd_hwdep *hwdep;
|
||||
int err;
|
||||
|
||||
|
@ -182,7 +181,7 @@ int snd_tscm_create_hwdep_device(struct snd_tscm *tscm)
|
|||
|
||||
strcpy(hwdep->name, "Tascam");
|
||||
hwdep->iface = SNDRV_HWDEP_IFACE_FW_TASCAM;
|
||||
hwdep->ops = hwdep_ops;
|
||||
hwdep->ops = ops;
|
||||
hwdep->private_data = tscm;
|
||||
hwdep->exclusive = true;
|
||||
|
||||
|
|
|
@ -68,20 +68,18 @@ static void midi_playback_trigger(struct snd_rawmidi_substream *substrm, int up)
|
|||
spin_unlock_irqrestore(&tscm->lock, flags);
|
||||
}
|
||||
|
||||
static struct snd_rawmidi_ops midi_capture_ops = {
|
||||
.open = midi_capture_open,
|
||||
.close = midi_capture_close,
|
||||
.trigger = midi_capture_trigger,
|
||||
};
|
||||
|
||||
static struct snd_rawmidi_ops midi_playback_ops = {
|
||||
.open = midi_playback_open,
|
||||
.close = midi_playback_close,
|
||||
.trigger = midi_playback_trigger,
|
||||
};
|
||||
|
||||
int snd_tscm_create_midi_devices(struct snd_tscm *tscm)
|
||||
{
|
||||
static const struct snd_rawmidi_ops capture_ops = {
|
||||
.open = midi_capture_open,
|
||||
.close = midi_capture_close,
|
||||
.trigger = midi_capture_trigger,
|
||||
};
|
||||
static const struct snd_rawmidi_ops playback_ops = {
|
||||
.open = midi_playback_open,
|
||||
.close = midi_playback_close,
|
||||
.trigger = midi_playback_trigger,
|
||||
};
|
||||
struct snd_rawmidi *rmidi;
|
||||
struct snd_rawmidi_str *stream;
|
||||
struct snd_rawmidi_substream *subs;
|
||||
|
@ -100,7 +98,7 @@ int snd_tscm_create_midi_devices(struct snd_tscm *tscm)
|
|||
|
||||
rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT;
|
||||
snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT,
|
||||
&midi_capture_ops);
|
||||
&capture_ops);
|
||||
stream = &rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT];
|
||||
|
||||
/* Set port names for MIDI input. */
|
||||
|
@ -116,7 +114,7 @@ int snd_tscm_create_midi_devices(struct snd_tscm *tscm)
|
|||
|
||||
rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT;
|
||||
snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
|
||||
&midi_playback_ops);
|
||||
&playback_ops);
|
||||
stream = &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT];
|
||||
|
||||
/* Set port names for MIDI ourput. */
|
||||
|
|
|
@ -268,33 +268,31 @@ static snd_pcm_uframes_t pcm_playback_pointer(struct snd_pcm_substream *sbstrm)
|
|||
return amdtp_stream_pcm_pointer(&tscm->rx_stream);
|
||||
}
|
||||
|
||||
static const struct snd_pcm_ops pcm_capture_ops = {
|
||||
.open = pcm_open,
|
||||
.close = pcm_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
.hw_params = pcm_capture_hw_params,
|
||||
.hw_free = pcm_capture_hw_free,
|
||||
.prepare = pcm_capture_prepare,
|
||||
.trigger = pcm_capture_trigger,
|
||||
.pointer = pcm_capture_pointer,
|
||||
.page = snd_pcm_lib_get_vmalloc_page,
|
||||
};
|
||||
|
||||
static const struct snd_pcm_ops pcm_playback_ops = {
|
||||
.open = pcm_open,
|
||||
.close = pcm_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
.hw_params = pcm_playback_hw_params,
|
||||
.hw_free = pcm_playback_hw_free,
|
||||
.prepare = pcm_playback_prepare,
|
||||
.trigger = pcm_playback_trigger,
|
||||
.pointer = pcm_playback_pointer,
|
||||
.page = snd_pcm_lib_get_vmalloc_page,
|
||||
.mmap = snd_pcm_lib_mmap_vmalloc,
|
||||
};
|
||||
|
||||
int snd_tscm_create_pcm_devices(struct snd_tscm *tscm)
|
||||
{
|
||||
static const struct snd_pcm_ops capture_ops = {
|
||||
.open = pcm_open,
|
||||
.close = pcm_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
.hw_params = pcm_capture_hw_params,
|
||||
.hw_free = pcm_capture_hw_free,
|
||||
.prepare = pcm_capture_prepare,
|
||||
.trigger = pcm_capture_trigger,
|
||||
.pointer = pcm_capture_pointer,
|
||||
.page = snd_pcm_lib_get_vmalloc_page,
|
||||
};
|
||||
static const struct snd_pcm_ops playback_ops = {
|
||||
.open = pcm_open,
|
||||
.close = pcm_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
.hw_params = pcm_playback_hw_params,
|
||||
.hw_free = pcm_playback_hw_free,
|
||||
.prepare = pcm_playback_prepare,
|
||||
.trigger = pcm_playback_trigger,
|
||||
.pointer = pcm_playback_pointer,
|
||||
.page = snd_pcm_lib_get_vmalloc_page,
|
||||
.mmap = snd_pcm_lib_mmap_vmalloc,
|
||||
};
|
||||
struct snd_pcm *pcm;
|
||||
int err;
|
||||
|
||||
|
@ -305,8 +303,8 @@ int snd_tscm_create_pcm_devices(struct snd_tscm *tscm)
|
|||
pcm->private_data = tscm;
|
||||
snprintf(pcm->name, sizeof(pcm->name),
|
||||
"%s PCM", tscm->card->shortname);
|
||||
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &pcm_playback_ops);
|
||||
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &pcm_capture_ops);
|
||||
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &playback_ops);
|
||||
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &capture_ops);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -128,14 +128,17 @@ void snd_hdac_ext_stream_decouple(struct hdac_ext_bus *ebus,
|
|||
{
|
||||
struct hdac_stream *hstream = &stream->hstream;
|
||||
struct hdac_bus *bus = &ebus->bus;
|
||||
u32 val;
|
||||
int mask = AZX_PPCTL_PROCEN(hstream->index);
|
||||
|
||||
spin_lock_irq(&bus->reg_lock);
|
||||
if (decouple)
|
||||
snd_hdac_updatel(bus->ppcap, AZX_REG_PP_PPCTL, 0,
|
||||
AZX_PPCTL_PROCEN(hstream->index));
|
||||
else
|
||||
snd_hdac_updatel(bus->ppcap, AZX_REG_PP_PPCTL,
|
||||
AZX_PPCTL_PROCEN(hstream->index), 0);
|
||||
val = readw(bus->ppcap + AZX_REG_PP_PPCTL) & mask;
|
||||
|
||||
if (decouple && !val)
|
||||
snd_hdac_updatel(bus->ppcap, AZX_REG_PP_PPCTL, mask, mask);
|
||||
else if (!decouple && val)
|
||||
snd_hdac_updatel(bus->ppcap, AZX_REG_PP_PPCTL, mask, 0);
|
||||
|
||||
stream->decoupled = decouple;
|
||||
spin_unlock_irq(&bus->reg_lock);
|
||||
}
|
||||
|
|
|
@ -227,14 +227,14 @@ static void snd_gf1_uart_output_trigger(struct snd_rawmidi_substream *substream,
|
|||
spin_unlock_irqrestore(&gus->uart_cmd_lock, flags);
|
||||
}
|
||||
|
||||
static struct snd_rawmidi_ops snd_gf1_uart_output =
|
||||
static const struct snd_rawmidi_ops snd_gf1_uart_output =
|
||||
{
|
||||
.open = snd_gf1_uart_output_open,
|
||||
.close = snd_gf1_uart_output_close,
|
||||
.trigger = snd_gf1_uart_output_trigger,
|
||||
};
|
||||
|
||||
static struct snd_rawmidi_ops snd_gf1_uart_input =
|
||||
static const struct snd_rawmidi_ops snd_gf1_uart_input =
|
||||
{
|
||||
.open = snd_gf1_uart_input_open,
|
||||
.close = snd_gf1_uart_input_close,
|
||||
|
|
|
@ -142,7 +142,7 @@ void snd_msndmidi_input_read(void *mpuv)
|
|||
}
|
||||
EXPORT_SYMBOL(snd_msndmidi_input_read);
|
||||
|
||||
static struct snd_rawmidi_ops snd_msndmidi_input = {
|
||||
static const struct snd_rawmidi_ops snd_msndmidi_input = {
|
||||
.open = snd_msndmidi_input_open,
|
||||
.close = snd_msndmidi_input_close,
|
||||
.trigger = snd_msndmidi_input_trigger,
|
||||
|
|
|
@ -247,14 +247,14 @@ static void snd_sb8dsp_midi_output_trigger(struct snd_rawmidi_substream *substre
|
|||
snd_sb8dsp_midi_output_write(substream);
|
||||
}
|
||||
|
||||
static struct snd_rawmidi_ops snd_sb8dsp_midi_output =
|
||||
static const struct snd_rawmidi_ops snd_sb8dsp_midi_output =
|
||||
{
|
||||
.open = snd_sb8dsp_midi_output_open,
|
||||
.close = snd_sb8dsp_midi_output_close,
|
||||
.trigger = snd_sb8dsp_midi_output_trigger,
|
||||
};
|
||||
|
||||
static struct snd_rawmidi_ops snd_sb8dsp_midi_input =
|
||||
static const struct snd_rawmidi_ops snd_sb8dsp_midi_input =
|
||||
{
|
||||
.open = snd_sb8dsp_midi_input_open,
|
||||
.close = snd_sb8dsp_midi_input_close,
|
||||
|
|
|
@ -559,14 +559,14 @@ snd_wavefront_midi_start (snd_wavefront_card_t *card)
|
|||
return 0;
|
||||
}
|
||||
|
||||
struct snd_rawmidi_ops snd_wavefront_midi_output =
|
||||
const struct snd_rawmidi_ops snd_wavefront_midi_output =
|
||||
{
|
||||
.open = snd_wavefront_midi_output_open,
|
||||
.close = snd_wavefront_midi_output_close,
|
||||
.trigger = snd_wavefront_midi_output_trigger,
|
||||
};
|
||||
|
||||
struct snd_rawmidi_ops snd_wavefront_midi_input =
|
||||
const struct snd_rawmidi_ops snd_wavefront_midi_input =
|
||||
{
|
||||
.open = snd_wavefront_midi_input_open,
|
||||
.close = snd_wavefront_midi_input_close,
|
||||
|
|
|
@ -219,6 +219,8 @@ static int hal2_gain_get(struct snd_kcontrol *kcontrol,
|
|||
l = (tmp >> H2I_C2_L_GAIN_SHIFT) & 15;
|
||||
r = (tmp >> H2I_C2_R_GAIN_SHIFT) & 15;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
ucontrol->value.integer.value[0] = l;
|
||||
ucontrol->value.integer.value[1] = r;
|
||||
|
@ -256,6 +258,8 @@ static int hal2_gain_put(struct snd_kcontrol *kcontrol,
|
|||
new |= (r << H2I_C2_R_GAIN_SHIFT);
|
||||
hal2_i_write32(hal2, H2I_ADC_C2, new);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
return old != new;
|
||||
}
|
||||
|
|
|
@ -121,11 +121,6 @@ static bool deskpro_xl;
|
|||
static bool deskpro_m;
|
||||
static bool soundpro;
|
||||
|
||||
static volatile signed char irq2dev[17] = {
|
||||
-1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1
|
||||
};
|
||||
|
||||
#ifndef EXCLUDE_TIMERS
|
||||
static int timer_installed = -1;
|
||||
#endif
|
||||
|
@ -2060,7 +2055,7 @@ int ad1848_init (char *name, struct resource *ports, int irq, int dma_playback,
|
|||
else
|
||||
devc->irq_ok = 1; /* Couldn't test. assume it's OK */
|
||||
} else if (irq < 0)
|
||||
irq2dev[-irq] = devc->dev_no = my_dev;
|
||||
devc->dev_no = my_dev;
|
||||
|
||||
#ifndef EXCLUDE_TIMERS
|
||||
if ((capabilities[devc->model].flags & CAP_F_TIMER) &&
|
||||
|
|
|
@ -255,14 +255,14 @@ static void ca_midi_output_trigger(struct snd_rawmidi_substream *substream, int
|
|||
}
|
||||
}
|
||||
|
||||
static struct snd_rawmidi_ops ca_midi_output =
|
||||
static const struct snd_rawmidi_ops ca_midi_output =
|
||||
{
|
||||
.open = ca_midi_output_open,
|
||||
.close = ca_midi_output_close,
|
||||
.trigger = ca_midi_output_trigger,
|
||||
};
|
||||
|
||||
static struct snd_rawmidi_ops ca_midi_input =
|
||||
static const struct snd_rawmidi_ops ca_midi_input =
|
||||
{
|
||||
.open = ca_midi_input_open,
|
||||
.close = ca_midi_input_close,
|
||||
|
|
|
@ -1767,14 +1767,14 @@ static void snd_cs4281_midi_output_trigger(struct snd_rawmidi_substream *substre
|
|||
spin_unlock_irqrestore(&chip->reg_lock, flags);
|
||||
}
|
||||
|
||||
static struct snd_rawmidi_ops snd_cs4281_midi_output =
|
||||
static const struct snd_rawmidi_ops snd_cs4281_midi_output =
|
||||
{
|
||||
.open = snd_cs4281_midi_output_open,
|
||||
.close = snd_cs4281_midi_output_close,
|
||||
.trigger = snd_cs4281_midi_output_trigger,
|
||||
};
|
||||
|
||||
static struct snd_rawmidi_ops snd_cs4281_midi_input =
|
||||
static const struct snd_rawmidi_ops snd_cs4281_midi_input =
|
||||
{
|
||||
.open = snd_cs4281_midi_input_open,
|
||||
.close = snd_cs4281_midi_input_close,
|
||||
|
|
|
@ -72,18 +72,18 @@
|
|||
static void amp_voyetra(struct snd_cs46xx *chip, int change);
|
||||
|
||||
#ifdef CONFIG_SND_CS46XX_NEW_DSP
|
||||
static struct snd_pcm_ops snd_cs46xx_playback_rear_ops;
|
||||
static struct snd_pcm_ops snd_cs46xx_playback_indirect_rear_ops;
|
||||
static struct snd_pcm_ops snd_cs46xx_playback_clfe_ops;
|
||||
static struct snd_pcm_ops snd_cs46xx_playback_indirect_clfe_ops;
|
||||
static struct snd_pcm_ops snd_cs46xx_playback_iec958_ops;
|
||||
static struct snd_pcm_ops snd_cs46xx_playback_indirect_iec958_ops;
|
||||
static const struct snd_pcm_ops snd_cs46xx_playback_rear_ops;
|
||||
static const struct snd_pcm_ops snd_cs46xx_playback_indirect_rear_ops;
|
||||
static const struct snd_pcm_ops snd_cs46xx_playback_clfe_ops;
|
||||
static const struct snd_pcm_ops snd_cs46xx_playback_indirect_clfe_ops;
|
||||
static const struct snd_pcm_ops snd_cs46xx_playback_iec958_ops;
|
||||
static const struct snd_pcm_ops snd_cs46xx_playback_indirect_iec958_ops;
|
||||
#endif
|
||||
|
||||
static struct snd_pcm_ops snd_cs46xx_playback_ops;
|
||||
static struct snd_pcm_ops snd_cs46xx_playback_indirect_ops;
|
||||
static struct snd_pcm_ops snd_cs46xx_capture_ops;
|
||||
static struct snd_pcm_ops snd_cs46xx_capture_indirect_ops;
|
||||
static const struct snd_pcm_ops snd_cs46xx_playback_ops;
|
||||
static const struct snd_pcm_ops snd_cs46xx_playback_indirect_ops;
|
||||
static const struct snd_pcm_ops snd_cs46xx_capture_ops;
|
||||
static const struct snd_pcm_ops snd_cs46xx_capture_indirect_ops;
|
||||
|
||||
static unsigned short snd_cs46xx_codec_read(struct snd_cs46xx *chip,
|
||||
unsigned short reg,
|
||||
|
@ -1654,7 +1654,7 @@ static int snd_cs46xx_capture_close(struct snd_pcm_substream *substream)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_SND_CS46XX_NEW_DSP
|
||||
static struct snd_pcm_ops snd_cs46xx_playback_rear_ops = {
|
||||
static const struct snd_pcm_ops snd_cs46xx_playback_rear_ops = {
|
||||
.open = snd_cs46xx_playback_open_rear,
|
||||
.close = snd_cs46xx_playback_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
|
@ -1665,7 +1665,7 @@ static struct snd_pcm_ops snd_cs46xx_playback_rear_ops = {
|
|||
.pointer = snd_cs46xx_playback_direct_pointer,
|
||||
};
|
||||
|
||||
static struct snd_pcm_ops snd_cs46xx_playback_indirect_rear_ops = {
|
||||
static const struct snd_pcm_ops snd_cs46xx_playback_indirect_rear_ops = {
|
||||
.open = snd_cs46xx_playback_open_rear,
|
||||
.close = snd_cs46xx_playback_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
|
@ -1677,7 +1677,7 @@ static struct snd_pcm_ops snd_cs46xx_playback_indirect_rear_ops = {
|
|||
.ack = snd_cs46xx_playback_transfer,
|
||||
};
|
||||
|
||||
static struct snd_pcm_ops snd_cs46xx_playback_clfe_ops = {
|
||||
static const struct snd_pcm_ops snd_cs46xx_playback_clfe_ops = {
|
||||
.open = snd_cs46xx_playback_open_clfe,
|
||||
.close = snd_cs46xx_playback_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
|
@ -1688,7 +1688,7 @@ static struct snd_pcm_ops snd_cs46xx_playback_clfe_ops = {
|
|||
.pointer = snd_cs46xx_playback_direct_pointer,
|
||||
};
|
||||
|
||||
static struct snd_pcm_ops snd_cs46xx_playback_indirect_clfe_ops = {
|
||||
static const struct snd_pcm_ops snd_cs46xx_playback_indirect_clfe_ops = {
|
||||
.open = snd_cs46xx_playback_open_clfe,
|
||||
.close = snd_cs46xx_playback_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
|
@ -1700,7 +1700,7 @@ static struct snd_pcm_ops snd_cs46xx_playback_indirect_clfe_ops = {
|
|||
.ack = snd_cs46xx_playback_transfer,
|
||||
};
|
||||
|
||||
static struct snd_pcm_ops snd_cs46xx_playback_iec958_ops = {
|
||||
static const struct snd_pcm_ops snd_cs46xx_playback_iec958_ops = {
|
||||
.open = snd_cs46xx_playback_open_iec958,
|
||||
.close = snd_cs46xx_playback_close_iec958,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
|
@ -1711,7 +1711,7 @@ static struct snd_pcm_ops snd_cs46xx_playback_iec958_ops = {
|
|||
.pointer = snd_cs46xx_playback_direct_pointer,
|
||||
};
|
||||
|
||||
static struct snd_pcm_ops snd_cs46xx_playback_indirect_iec958_ops = {
|
||||
static const struct snd_pcm_ops snd_cs46xx_playback_indirect_iec958_ops = {
|
||||
.open = snd_cs46xx_playback_open_iec958,
|
||||
.close = snd_cs46xx_playback_close_iec958,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
|
@ -1725,7 +1725,7 @@ static struct snd_pcm_ops snd_cs46xx_playback_indirect_iec958_ops = {
|
|||
|
||||
#endif
|
||||
|
||||
static struct snd_pcm_ops snd_cs46xx_playback_ops = {
|
||||
static const struct snd_pcm_ops snd_cs46xx_playback_ops = {
|
||||
.open = snd_cs46xx_playback_open,
|
||||
.close = snd_cs46xx_playback_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
|
@ -1736,7 +1736,7 @@ static struct snd_pcm_ops snd_cs46xx_playback_ops = {
|
|||
.pointer = snd_cs46xx_playback_direct_pointer,
|
||||
};
|
||||
|
||||
static struct snd_pcm_ops snd_cs46xx_playback_indirect_ops = {
|
||||
static const struct snd_pcm_ops snd_cs46xx_playback_indirect_ops = {
|
||||
.open = snd_cs46xx_playback_open,
|
||||
.close = snd_cs46xx_playback_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
|
@ -1748,7 +1748,7 @@ static struct snd_pcm_ops snd_cs46xx_playback_indirect_ops = {
|
|||
.ack = snd_cs46xx_playback_transfer,
|
||||
};
|
||||
|
||||
static struct snd_pcm_ops snd_cs46xx_capture_ops = {
|
||||
static const struct snd_pcm_ops snd_cs46xx_capture_ops = {
|
||||
.open = snd_cs46xx_capture_open,
|
||||
.close = snd_cs46xx_capture_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
|
@ -1759,7 +1759,7 @@ static struct snd_pcm_ops snd_cs46xx_capture_ops = {
|
|||
.pointer = snd_cs46xx_capture_direct_pointer,
|
||||
};
|
||||
|
||||
static struct snd_pcm_ops snd_cs46xx_capture_indirect_ops = {
|
||||
static const struct snd_pcm_ops snd_cs46xx_capture_indirect_ops = {
|
||||
.open = snd_cs46xx_capture_open,
|
||||
.close = snd_cs46xx_capture_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
|
@ -2683,14 +2683,14 @@ static void snd_cs46xx_midi_output_trigger(struct snd_rawmidi_substream *substre
|
|||
spin_unlock_irqrestore(&chip->reg_lock, flags);
|
||||
}
|
||||
|
||||
static struct snd_rawmidi_ops snd_cs46xx_midi_output =
|
||||
static const struct snd_rawmidi_ops snd_cs46xx_midi_output =
|
||||
{
|
||||
.open = snd_cs46xx_midi_output_open,
|
||||
.close = snd_cs46xx_midi_output_close,
|
||||
.trigger = snd_cs46xx_midi_output_trigger,
|
||||
};
|
||||
|
||||
static struct snd_rawmidi_ops snd_cs46xx_midi_input =
|
||||
static const struct snd_rawmidi_ops snd_cs46xx_midi_input =
|
||||
{
|
||||
.open = snd_cs46xx_midi_input_open,
|
||||
.close = snd_cs46xx_midi_input_close,
|
||||
|
|
|
@ -55,7 +55,7 @@ static void snd_cs5535audio_stop_hardware(struct cs5535audio *cs5535au)
|
|||
|
||||
}
|
||||
|
||||
static int snd_cs5535audio_suspend(struct device *dev)
|
||||
static int __maybe_unused snd_cs5535audio_suspend(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct cs5535audio *cs5535au = card->private_data;
|
||||
|
@ -74,7 +74,7 @@ static int snd_cs5535audio_suspend(struct device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int snd_cs5535audio_resume(struct device *dev)
|
||||
static int __maybe_unused snd_cs5535audio_resume(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct cs5535audio *cs5535au = card->private_data;
|
||||
|
|
|
@ -288,13 +288,13 @@ static int snd_echo_midi_output_close(struct snd_rawmidi_substream *substream)
|
|||
|
||||
|
||||
|
||||
static struct snd_rawmidi_ops snd_echo_midi_input = {
|
||||
static const struct snd_rawmidi_ops snd_echo_midi_input = {
|
||||
.open = snd_echo_midi_input_open,
|
||||
.close = snd_echo_midi_input_close,
|
||||
.trigger = snd_echo_midi_input_trigger,
|
||||
};
|
||||
|
||||
static struct snd_rawmidi_ops snd_echo_midi_output = {
|
||||
static const struct snd_rawmidi_ops snd_echo_midi_output = {
|
||||
.open = snd_echo_midi_output_open,
|
||||
.close = snd_echo_midi_output_close,
|
||||
.trigger = snd_echo_midi_output_trigger,
|
||||
|
|
|
@ -61,7 +61,7 @@ static void set_filterQ(struct snd_emu10k1 *hw, struct snd_emux_voice *vp);
|
|||
/*
|
||||
* set up operators
|
||||
*/
|
||||
static struct snd_emux_operators emu10k1_ops = {
|
||||
static const struct snd_emux_operators emu10k1_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.get_voice = get_voice,
|
||||
.prepare = start_voice,
|
||||
|
|
|
@ -1486,14 +1486,14 @@ static void snd_emu10k1x_midi_output_trigger(struct snd_rawmidi_substream *subst
|
|||
|
||||
*/
|
||||
|
||||
static struct snd_rawmidi_ops snd_emu10k1x_midi_output =
|
||||
static const struct snd_rawmidi_ops snd_emu10k1x_midi_output =
|
||||
{
|
||||
.open = snd_emu10k1x_midi_output_open,
|
||||
.close = snd_emu10k1x_midi_output_close,
|
||||
.trigger = snd_emu10k1x_midi_output_trigger,
|
||||
};
|
||||
|
||||
static struct snd_rawmidi_ops snd_emu10k1x_midi_input =
|
||||
static const struct snd_rawmidi_ops snd_emu10k1x_midi_input =
|
||||
{
|
||||
.open = snd_emu10k1x_midi_input_open,
|
||||
.close = snd_emu10k1x_midi_input_close,
|
||||
|
|
|
@ -308,14 +308,14 @@ static void snd_emu10k1_midi_output_trigger(struct snd_rawmidi_substream *substr
|
|||
|
||||
*/
|
||||
|
||||
static struct snd_rawmidi_ops snd_emu10k1_midi_output =
|
||||
static const struct snd_rawmidi_ops snd_emu10k1_midi_output =
|
||||
{
|
||||
.open = snd_emu10k1_midi_output_open,
|
||||
.close = snd_emu10k1_midi_output_close,
|
||||
.trigger = snd_emu10k1_midi_output_trigger,
|
||||
};
|
||||
|
||||
static struct snd_rawmidi_ops snd_emu10k1_midi_input =
|
||||
static const struct snd_rawmidi_ops snd_emu10k1_midi_input =
|
||||
{
|
||||
.open = snd_emu10k1_midi_input_open,
|
||||
.close = snd_emu10k1_midi_input_close,
|
||||
|
|
|
@ -2317,14 +2317,14 @@ static void snd_ensoniq_midi_output_trigger(struct snd_rawmidi_substream *substr
|
|||
spin_unlock_irqrestore(&ensoniq->reg_lock, flags);
|
||||
}
|
||||
|
||||
static struct snd_rawmidi_ops snd_ensoniq_midi_output =
|
||||
static const struct snd_rawmidi_ops snd_ensoniq_midi_output =
|
||||
{
|
||||
.open = snd_ensoniq_midi_output_open,
|
||||
.close = snd_ensoniq_midi_output_close,
|
||||
.trigger = snd_ensoniq_midi_output_trigger,
|
||||
};
|
||||
|
||||
static struct snd_rawmidi_ops snd_ensoniq_midi_input =
|
||||
static const struct snd_rawmidi_ops snd_ensoniq_midi_input =
|
||||
{
|
||||
.open = snd_ensoniq_midi_input_open,
|
||||
.close = snd_ensoniq_midi_input_close,
|
||||
|
|
|
@ -861,6 +861,10 @@ static int azx_rirb_get_response(struct hdac_bus *bus, unsigned int addr,
|
|||
return -EIO;
|
||||
}
|
||||
|
||||
/* no fallback mechanism? */
|
||||
if (!chip->fallback_to_single_cmd)
|
||||
return -EIO;
|
||||
|
||||
/* a fatal communication error; need either to reset or to fallback
|
||||
* to the single_cmd mode
|
||||
*/
|
||||
|
|
|
@ -150,6 +150,7 @@ struct azx {
|
|||
int bdl_pos_adj;
|
||||
int poll_count;
|
||||
unsigned int running:1;
|
||||
unsigned int fallback_to_single_cmd:1;
|
||||
unsigned int single_cmd:1;
|
||||
unsigned int polling_mode:1;
|
||||
unsigned int msi:1;
|
||||
|
|
|
@ -128,7 +128,7 @@ static int bdl_pos_adj[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1};
|
|||
static int probe_mask[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1};
|
||||
static int probe_only[SNDRV_CARDS];
|
||||
static int jackpoll_ms[SNDRV_CARDS];
|
||||
static bool single_cmd;
|
||||
static int single_cmd = -1;
|
||||
static int enable_msi = -1;
|
||||
#ifdef CONFIG_SND_HDA_PATCH_LOADER
|
||||
static char *patch[SNDRV_CARDS];
|
||||
|
@ -157,7 +157,7 @@ module_param_array(probe_only, int, NULL, 0444);
|
|||
MODULE_PARM_DESC(probe_only, "Only probing and no codec initialization.");
|
||||
module_param_array(jackpoll_ms, int, NULL, 0444);
|
||||
MODULE_PARM_DESC(jackpoll_ms, "Ms between polling for jack events (default = 0, using unsol events only)");
|
||||
module_param(single_cmd, bool, 0444);
|
||||
module_param(single_cmd, bint, 0444);
|
||||
MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs "
|
||||
"(for debugging only).");
|
||||
module_param(enable_msi, bint, 0444);
|
||||
|
@ -1596,7 +1596,11 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,
|
|||
|
||||
check_probe_mask(chip, dev);
|
||||
|
||||
chip->single_cmd = single_cmd;
|
||||
if (single_cmd < 0) /* allow fallback to single_cmd at errors */
|
||||
chip->fallback_to_single_cmd = 1;
|
||||
else /* explicitly set to single_cmd or not */
|
||||
chip->single_cmd = single_cmd;
|
||||
|
||||
azx_check_snoop_available(chip);
|
||||
|
||||
if (bdl_pos_adj[dev] < 0)
|
||||
|
@ -1774,6 +1778,14 @@ static int azx_first_init(struct azx *chip)
|
|||
chip->playback_index_offset = chip->capture_streams;
|
||||
chip->num_streams = chip->playback_streams + chip->capture_streams;
|
||||
|
||||
/* sanity check for the SDxCTL.STRM field overflow */
|
||||
if (chip->num_streams > 15 &&
|
||||
(chip->driver_caps & AZX_DCAPS_SEPARATE_STREAM_TAG) == 0) {
|
||||
dev_warn(chip->card->dev, "number of I/O streams is %d, "
|
||||
"forcing separate stream tags", chip->num_streams);
|
||||
chip->driver_caps |= AZX_DCAPS_SEPARATE_STREAM_TAG;
|
||||
}
|
||||
|
||||
/* initialize streams */
|
||||
err = azx_init_streams(chip);
|
||||
if (err < 0)
|
||||
|
@ -2155,7 +2167,20 @@ static void azx_remove(struct pci_dev *pci)
|
|||
/* cancel the pending probing work */
|
||||
chip = card->private_data;
|
||||
hda = container_of(chip, struct hda_intel, chip);
|
||||
/* FIXME: below is an ugly workaround.
|
||||
* Both device_release_driver() and driver_probe_device()
|
||||
* take *both* the device's and its parent's lock before
|
||||
* calling the remove() and probe() callbacks. The codec
|
||||
* probe takes the locks of both the codec itself and its
|
||||
* parent, i.e. the PCI controller dev. Meanwhile, when
|
||||
* the PCI controller is unbound, it takes its lock, too
|
||||
* ==> ouch, a deadlock!
|
||||
* As a workaround, we unlock temporarily here the controller
|
||||
* device during cancel_work_sync() call.
|
||||
*/
|
||||
device_unlock(&pci->dev);
|
||||
cancel_work_sync(&hda->probe_work);
|
||||
device_lock(&pci->dev);
|
||||
|
||||
snd_card_free(card);
|
||||
}
|
||||
|
@ -2197,9 +2222,9 @@ static const struct pci_device_id azx_ids[] = {
|
|||
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
|
||||
/* Lewisburg */
|
||||
{ PCI_DEVICE(0x8086, 0xa1f0),
|
||||
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
|
||||
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_SKYLAKE },
|
||||
{ PCI_DEVICE(0x8086, 0xa270),
|
||||
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
|
||||
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_SKYLAKE },
|
||||
/* Lynx Point-LP */
|
||||
{ PCI_DEVICE(0x8086, 0x9c20),
|
||||
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
|
||||
|
|
|
@ -1482,6 +1482,9 @@ static int dspio_scp(struct hda_codec *codec,
|
|||
} else if (ret_size != reply_data_size) {
|
||||
codec_dbg(codec, "RetLen and HdrLen .NE.\n");
|
||||
return -EINVAL;
|
||||
} else if (!reply) {
|
||||
codec_dbg(codec, "NULL reply\n");
|
||||
return -EINVAL;
|
||||
} else {
|
||||
*reply_len = ret_size*sizeof(unsigned int);
|
||||
memcpy(reply, scp_reply.data, *reply_len);
|
||||
|
|
|
@ -337,6 +337,7 @@ static void alc_fill_eapd_coef(struct hda_codec *codec)
|
|||
case 0x10ec0288:
|
||||
case 0x10ec0295:
|
||||
case 0x10ec0298:
|
||||
case 0x10ec0299:
|
||||
alc_update_coef_idx(codec, 0x10, 1<<9, 0);
|
||||
break;
|
||||
case 0x10ec0285:
|
||||
|
@ -379,6 +380,7 @@ static void alc_fill_eapd_coef(struct hda_codec *codec)
|
|||
break;
|
||||
case 0x10ec0899:
|
||||
case 0x10ec0900:
|
||||
case 0x10ec1220:
|
||||
alc_update_coef_idx(codec, 0x7, 1<<1, 0);
|
||||
break;
|
||||
}
|
||||
|
@ -912,6 +914,7 @@ static struct alc_codec_rename_pci_table rename_pci_tbl[] = {
|
|||
{ 0x10ec0256, 0x1028, 0, "ALC3246" },
|
||||
{ 0x10ec0225, 0x1028, 0, "ALC3253" },
|
||||
{ 0x10ec0295, 0x1028, 0, "ALC3254" },
|
||||
{ 0x10ec0299, 0x1028, 0, "ALC3271" },
|
||||
{ 0x10ec0670, 0x1025, 0, "ALC669X" },
|
||||
{ 0x10ec0676, 0x1025, 0, "ALC679X" },
|
||||
{ 0x10ec0282, 0x1043, 0, "ALC3229" },
|
||||
|
@ -2309,6 +2312,7 @@ static int patch_alc882(struct hda_codec *codec)
|
|||
case 0x10ec0882:
|
||||
case 0x10ec0885:
|
||||
case 0x10ec0900:
|
||||
case 0x10ec1220:
|
||||
break;
|
||||
default:
|
||||
/* ALC883 and variants */
|
||||
|
@ -3717,6 +3721,7 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec)
|
|||
break;
|
||||
case 0x10ec0225:
|
||||
case 0x10ec0295:
|
||||
case 0x10ec0299:
|
||||
alc_process_coef_fw(codec, coef0225);
|
||||
break;
|
||||
case 0x10ec0867:
|
||||
|
@ -3812,6 +3817,7 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,
|
|||
case 0x10ec0867:
|
||||
alc_update_coefex_idx(codec, 0x57, 0x5, 0, 1<<14);
|
||||
/* fallthru */
|
||||
case 0x10ec0221:
|
||||
case 0x10ec0662:
|
||||
snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
|
||||
snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
|
||||
|
@ -3824,6 +3830,7 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,
|
|||
break;
|
||||
case 0x10ec0225:
|
||||
case 0x10ec0295:
|
||||
case 0x10ec0299:
|
||||
alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x31<<10);
|
||||
snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
|
||||
alc_process_coef_fw(codec, coef0225);
|
||||
|
@ -3882,6 +3889,7 @@ static void alc_headset_mode_default(struct hda_codec *codec)
|
|||
switch (codec->core.vendor_id) {
|
||||
case 0x10ec0225:
|
||||
case 0x10ec0295:
|
||||
case 0x10ec0299:
|
||||
alc_process_coef_fw(codec, coef0225);
|
||||
break;
|
||||
case 0x10ec0255:
|
||||
|
@ -3997,6 +4005,7 @@ static void alc_headset_mode_ctia(struct hda_codec *codec)
|
|||
break;
|
||||
case 0x10ec0225:
|
||||
case 0x10ec0295:
|
||||
case 0x10ec0299:
|
||||
alc_process_coef_fw(codec, coef0225);
|
||||
break;
|
||||
case 0x10ec0867:
|
||||
|
@ -4090,6 +4099,7 @@ static void alc_headset_mode_omtp(struct hda_codec *codec)
|
|||
break;
|
||||
case 0x10ec0225:
|
||||
case 0x10ec0295:
|
||||
case 0x10ec0299:
|
||||
alc_process_coef_fw(codec, coef0225);
|
||||
break;
|
||||
}
|
||||
|
@ -4174,6 +4184,7 @@ static void alc_determine_headset_type(struct hda_codec *codec)
|
|||
break;
|
||||
case 0x10ec0225:
|
||||
case 0x10ec0295:
|
||||
case 0x10ec0299:
|
||||
alc_process_coef_fw(codec, coef0225);
|
||||
msleep(800);
|
||||
val = alc_read_coef_idx(codec, 0x46);
|
||||
|
@ -4401,7 +4412,7 @@ static void alc_no_shutup(struct hda_codec *codec)
|
|||
static void alc_fixup_no_shutup(struct hda_codec *codec,
|
||||
const struct hda_fixup *fix, int action)
|
||||
{
|
||||
if (action == HDA_FIXUP_ACT_PRE_PROBE) {
|
||||
if (action == HDA_FIXUP_ACT_PROBE) {
|
||||
struct alc_spec *spec = codec->spec;
|
||||
spec->shutup = alc_no_shutup;
|
||||
}
|
||||
|
@ -4857,6 +4868,8 @@ enum {
|
|||
ALC292_FIXUP_TPT460,
|
||||
ALC298_FIXUP_SPK_VOLUME,
|
||||
ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER,
|
||||
ALC269_FIXUP_ATIV_BOOK_8,
|
||||
ALC221_FIXUP_HP_MIC_NO_PRESENCE,
|
||||
};
|
||||
|
||||
static const struct hda_fixup alc269_fixups[] = {
|
||||
|
@ -5529,6 +5542,22 @@ static const struct hda_fixup alc269_fixups[] = {
|
|||
.chained = true,
|
||||
.chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
|
||||
},
|
||||
[ALC269_FIXUP_ATIV_BOOK_8] = {
|
||||
.type = HDA_FIXUP_FUNC,
|
||||
.v.func = alc_fixup_auto_mute_via_amp,
|
||||
.chained = true,
|
||||
.chain_id = ALC269_FIXUP_NO_SHUTUP
|
||||
},
|
||||
[ALC221_FIXUP_HP_MIC_NO_PRESENCE] = {
|
||||
.type = HDA_FIXUP_PINS,
|
||||
.v.pins = (const struct hda_pintbl[]) {
|
||||
{ 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
|
||||
{ 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
|
||||
{ }
|
||||
},
|
||||
.chained = true,
|
||||
.chain_id = ALC269_FIXUP_HEADSET_MODE
|
||||
},
|
||||
};
|
||||
|
||||
static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
||||
|
@ -5639,6 +5668,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
|||
SND_PCI_QUIRK(0x103c, 0x2337, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
||||
SND_PCI_QUIRK(0x103c, 0x221c, "HP EliteBook 755 G2", ALC280_FIXUP_HP_HEADSET_MIC),
|
||||
SND_PCI_QUIRK(0x103c, 0x8256, "HP", ALC221_FIXUP_HP_FRONT_MIC),
|
||||
SND_PCI_QUIRK(0x103c, 0x82bf, "HP", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x103c, 0x82c0, "HP", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
|
||||
SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
|
||||
SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
|
||||
|
@ -5665,6 +5696,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
|||
SND_PCI_QUIRK(0x10cf, 0x1757, "Lifebook E752", ALC269_FIXUP_LIFEBOOK_HP_PIN),
|
||||
SND_PCI_QUIRK(0x10cf, 0x1845, "Lifebook U904", ALC269_FIXUP_LIFEBOOK_EXTMIC),
|
||||
SND_PCI_QUIRK(0x144d, 0xc109, "Samsung Ativ book 9 (NP900X3G)", ALC269_FIXUP_INV_DMIC),
|
||||
SND_PCI_QUIRK(0x144d, 0xc740, "Samsung Ativ book 8 (NP870Z5G)", ALC269_FIXUP_ATIV_BOOK_8),
|
||||
SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_HEADSET_MIC),
|
||||
SND_PCI_QUIRK(0x1462, 0xb120, "MSI Cubi MS-B120", ALC283_FIXUP_HEADSET_MIC),
|
||||
SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
|
||||
|
@ -6065,6 +6097,12 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
|
|||
SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
|
||||
ALC298_STANDARD_PINS,
|
||||
{0x17, 0x90170150}),
|
||||
SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_SPK_VOLUME,
|
||||
{0x12, 0xb7a60140},
|
||||
{0x13, 0xb7a60150},
|
||||
{0x17, 0x90170110},
|
||||
{0x1a, 0x03011020},
|
||||
{0x21, 0x03211030}),
|
||||
{}
|
||||
};
|
||||
|
||||
|
@ -6212,6 +6250,7 @@ static int patch_alc269(struct hda_codec *codec)
|
|||
break;
|
||||
case 0x10ec0225:
|
||||
case 0x10ec0295:
|
||||
case 0x10ec0299:
|
||||
spec->codec_variant = ALC269_TYPE_ALC225;
|
||||
break;
|
||||
case 0x10ec0234:
|
||||
|
@ -7250,6 +7289,7 @@ static const struct hda_device_id snd_hda_id_realtek[] = {
|
|||
HDA_CODEC_ENTRY(0x10ec0294, "ALC294", patch_alc269),
|
||||
HDA_CODEC_ENTRY(0x10ec0295, "ALC295", patch_alc269),
|
||||
HDA_CODEC_ENTRY(0x10ec0298, "ALC298", patch_alc269),
|
||||
HDA_CODEC_ENTRY(0x10ec0299, "ALC299", patch_alc269),
|
||||
HDA_CODEC_REV_ENTRY(0x10ec0861, 0x100340, "ALC660", patch_alc861),
|
||||
HDA_CODEC_ENTRY(0x10ec0660, "ALC660-VD", patch_alc861vd),
|
||||
HDA_CODEC_ENTRY(0x10ec0861, "ALC861", patch_alc861),
|
||||
|
@ -7281,6 +7321,7 @@ static const struct hda_device_id snd_hda_id_realtek[] = {
|
|||
HDA_CODEC_ENTRY(0x10ec0892, "ALC892", patch_alc662),
|
||||
HDA_CODEC_ENTRY(0x10ec0899, "ALC898", patch_alc882),
|
||||
HDA_CODEC_ENTRY(0x10ec0900, "ALC1150", patch_alc882),
|
||||
HDA_CODEC_ENTRY(0x10ec1220, "ALC1220", patch_alc882),
|
||||
{} /* terminator */
|
||||
};
|
||||
MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_realtek);
|
||||
|
|
|
@ -166,6 +166,7 @@ enum {
|
|||
STAC_D965_VERBS,
|
||||
STAC_DELL_3ST,
|
||||
STAC_DELL_BIOS,
|
||||
STAC_NEMO_DEFAULT,
|
||||
STAC_DELL_BIOS_AMIC,
|
||||
STAC_DELL_BIOS_SPDIF,
|
||||
STAC_927X_DELL_DMIC,
|
||||
|
@ -1360,6 +1361,27 @@ static const struct hda_pintbl oqo9200_pin_configs[] = {
|
|||
{}
|
||||
};
|
||||
|
||||
/*
|
||||
* STAC 92HD700
|
||||
* 18881000 Amigaone X1000
|
||||
*/
|
||||
static const struct hda_pintbl nemo_pin_configs[] = {
|
||||
{ 0x0a, 0x02214020 }, /* Front panel HP socket */
|
||||
{ 0x0b, 0x02a19080 }, /* Front Mic */
|
||||
{ 0x0c, 0x0181304e }, /* Line in */
|
||||
{ 0x0d, 0x01014010 }, /* Line out */
|
||||
{ 0x0e, 0x01a19040 }, /* Rear Mic */
|
||||
{ 0x0f, 0x01011012 }, /* Rear speakers */
|
||||
{ 0x10, 0x01016011 }, /* Center speaker */
|
||||
{ 0x11, 0x01012014 }, /* Side speakers (7.1) */
|
||||
{ 0x12, 0x103301f0 }, /* Motherboard CD line in connector */
|
||||
{ 0x13, 0x411111f0 }, /* Unused */
|
||||
{ 0x14, 0x411111f0 }, /* Unused */
|
||||
{ 0x21, 0x01442170 }, /* S/PDIF line out */
|
||||
{ 0x22, 0x411111f0 }, /* Unused */
|
||||
{ 0x23, 0x411111f0 }, /* Unused */
|
||||
{}
|
||||
};
|
||||
|
||||
static void stac9200_fixup_panasonic(struct hda_codec *codec,
|
||||
const struct hda_fixup *fix, int action)
|
||||
|
@ -3883,6 +3905,10 @@ static const struct hda_fixup stac927x_fixups[] = {
|
|||
.type = HDA_FIXUP_PINS,
|
||||
.v.pins = d965_5st_no_fp_pin_configs,
|
||||
},
|
||||
[STAC_NEMO_DEFAULT] = {
|
||||
.type = HDA_FIXUP_PINS,
|
||||
.v.pins = nemo_pin_configs,
|
||||
},
|
||||
[STAC_DELL_3ST] = {
|
||||
.type = HDA_FIXUP_PINS,
|
||||
.v.pins = dell_3st_pin_configs,
|
||||
|
@ -3939,6 +3965,7 @@ static const struct hda_model_fixup stac927x_models[] = {
|
|||
{ .id = STAC_D965_5ST_NO_FP, .name = "5stack-no-fp" },
|
||||
{ .id = STAC_DELL_3ST, .name = "dell-3stack" },
|
||||
{ .id = STAC_DELL_BIOS, .name = "dell-bios" },
|
||||
{ .id = STAC_NEMO_DEFAULT, .name = "nemo-default" },
|
||||
{ .id = STAC_DELL_BIOS_AMIC, .name = "dell-bios-amic" },
|
||||
{ .id = STAC_927X_VOLKNOB, .name = "volknob" },
|
||||
{}
|
||||
|
@ -3977,6 +4004,8 @@ static const struct snd_pci_quirk stac927x_fixup_tbl[] = {
|
|||
"Intel D965", STAC_D965_5ST),
|
||||
SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2500,
|
||||
"Intel D965", STAC_D965_5ST),
|
||||
/* Nemo */
|
||||
SND_PCI_QUIRK(0x1888, 0x1000, "AmigaOne X1000", STAC_NEMO_DEFAULT),
|
||||
/* volume-knob fixes */
|
||||
SND_PCI_QUIRK_VENDOR(0x10cf, "FSC", STAC_927X_VOLKNOB),
|
||||
{} /* terminator */
|
||||
|
@ -5036,6 +5065,7 @@ static const struct hda_device_id snd_hda_id_sigmatel[] = {
|
|||
HDA_CODEC_ENTRY(0x83847683, "STAC9221D A2", patch_stac922x),
|
||||
HDA_CODEC_ENTRY(0x83847618, "STAC9227", patch_stac927x),
|
||||
HDA_CODEC_ENTRY(0x83847619, "STAC9227", patch_stac927x),
|
||||
HDA_CODEC_ENTRY(0x83847638, "STAC92HD700", patch_stac927x),
|
||||
HDA_CODEC_ENTRY(0x83847616, "STAC9228", patch_stac927x),
|
||||
HDA_CODEC_ENTRY(0x83847617, "STAC9228", patch_stac927x),
|
||||
HDA_CODEC_ENTRY(0x83847614, "STAC9229", patch_stac927x),
|
||||
|
|
|
@ -367,7 +367,7 @@ static void vt1724_midi_output_drain(struct snd_rawmidi_substream *s)
|
|||
} while (time_after(timeout, jiffies));
|
||||
}
|
||||
|
||||
static struct snd_rawmidi_ops vt1724_midi_output_ops = {
|
||||
static const struct snd_rawmidi_ops vt1724_midi_output_ops = {
|
||||
.open = vt1724_midi_output_open,
|
||||
.close = vt1724_midi_output_close,
|
||||
.trigger = vt1724_midi_output_trigger,
|
||||
|
@ -402,7 +402,7 @@ static void vt1724_midi_input_trigger(struct snd_rawmidi_substream *s, int up)
|
|||
spin_unlock_irqrestore(&ice->reg_lock, flags);
|
||||
}
|
||||
|
||||
static struct snd_rawmidi_ops vt1724_midi_input_ops = {
|
||||
static const struct snd_rawmidi_ops vt1724_midi_input_ops = {
|
||||
.open = vt1724_midi_input_open,
|
||||
.close = vt1724_midi_input_close,
|
||||
.trigger = vt1724_midi_input_trigger,
|
||||
|
|
|
@ -86,7 +86,7 @@ struct mixart_mgr {
|
|||
u32 msg_fifo[MSG_FIFO_SIZE];
|
||||
int msg_fifo_readptr;
|
||||
int msg_fifo_writeptr;
|
||||
atomic_t msg_processed; /* number of messages to be processed in takslet */
|
||||
atomic_t msg_processed; /* number of messages to be processed in tasklet */
|
||||
|
||||
struct mutex lock; /* interrupt lock */
|
||||
struct mutex msg_lock; /* mailbox lock */
|
||||
|
|
|
@ -1510,14 +1510,14 @@ static int snd_hdsp_midi_output_close(struct snd_rawmidi_substream *substream)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct snd_rawmidi_ops snd_hdsp_midi_output =
|
||||
static const struct snd_rawmidi_ops snd_hdsp_midi_output =
|
||||
{
|
||||
.open = snd_hdsp_midi_output_open,
|
||||
.close = snd_hdsp_midi_output_close,
|
||||
.trigger = snd_hdsp_midi_output_trigger,
|
||||
};
|
||||
|
||||
static struct snd_rawmidi_ops snd_hdsp_midi_input =
|
||||
static const struct snd_rawmidi_ops snd_hdsp_midi_input =
|
||||
{
|
||||
.open = snd_hdsp_midi_input_open,
|
||||
.close = snd_hdsp_midi_input_close,
|
||||
|
|
|
@ -2043,14 +2043,14 @@ static int snd_hdspm_midi_output_close(struct snd_rawmidi_substream *substream)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct snd_rawmidi_ops snd_hdspm_midi_output =
|
||||
static const struct snd_rawmidi_ops snd_hdspm_midi_output =
|
||||
{
|
||||
.open = snd_hdspm_midi_output_open,
|
||||
.close = snd_hdspm_midi_output_close,
|
||||
.trigger = snd_hdspm_midi_output_trigger,
|
||||
};
|
||||
|
||||
static struct snd_rawmidi_ops snd_hdspm_midi_input =
|
||||
static const struct snd_rawmidi_ops snd_hdspm_midi_input =
|
||||
{
|
||||
.open = snd_hdspm_midi_input_open,
|
||||
.close = snd_hdspm_midi_input_close,
|
||||
|
|
|
@ -269,12 +269,12 @@ static void vx2_dma_write(struct vx_core *chip, struct snd_pcm_runtime *runtime,
|
|||
|
||||
/* Transfer using pseudo-dma.
|
||||
*/
|
||||
if (offset + count > pipe->buffer_bytes) {
|
||||
if (offset + count >= pipe->buffer_bytes) {
|
||||
int length = pipe->buffer_bytes - offset;
|
||||
count -= length;
|
||||
length >>= 2; /* in 32bit words */
|
||||
/* Transfer using pseudo-dma. */
|
||||
while (length-- > 0) {
|
||||
for (; length > 0; length--) {
|
||||
outl(cpu_to_le32(*addr), port);
|
||||
addr++;
|
||||
}
|
||||
|
@ -284,7 +284,7 @@ static void vx2_dma_write(struct vx_core *chip, struct snd_pcm_runtime *runtime,
|
|||
pipe->hw_ptr += count;
|
||||
count >>= 2; /* in 32bit words */
|
||||
/* Transfer using pseudo-dma. */
|
||||
while (count-- > 0) {
|
||||
for (; count > 0; count--) {
|
||||
outl(cpu_to_le32(*addr), port);
|
||||
addr++;
|
||||
}
|
||||
|
@ -307,12 +307,12 @@ static void vx2_dma_read(struct vx_core *chip, struct snd_pcm_runtime *runtime,
|
|||
vx2_setup_pseudo_dma(chip, 0);
|
||||
/* Transfer using pseudo-dma.
|
||||
*/
|
||||
if (offset + count > pipe->buffer_bytes) {
|
||||
if (offset + count >= pipe->buffer_bytes) {
|
||||
int length = pipe->buffer_bytes - offset;
|
||||
count -= length;
|
||||
length >>= 2; /* in 32bit words */
|
||||
/* Transfer using pseudo-dma. */
|
||||
while (length-- > 0)
|
||||
for (; length > 0; length--)
|
||||
*addr++ = le32_to_cpu(inl(port));
|
||||
addr = (u32 *)runtime->dma_area;
|
||||
pipe->hw_ptr = 0;
|
||||
|
@ -320,7 +320,7 @@ static void vx2_dma_read(struct vx_core *chip, struct snd_pcm_runtime *runtime,
|
|||
pipe->hw_ptr += count;
|
||||
count >>= 2; /* in 32bit words */
|
||||
/* Transfer using pseudo-dma. */
|
||||
while (count-- > 0)
|
||||
for (; count > 0; count--)
|
||||
*addr++ = le32_to_cpu(inl(port));
|
||||
|
||||
vx2_release_pseudo_dma(chip);
|
||||
|
|
|
@ -369,12 +369,12 @@ static void vxp_dma_write(struct vx_core *chip, struct snd_pcm_runtime *runtime,
|
|||
unsigned short *addr = (unsigned short *)(runtime->dma_area + offset);
|
||||
|
||||
vx_setup_pseudo_dma(chip, 1);
|
||||
if (offset + count > pipe->buffer_bytes) {
|
||||
if (offset + count >= pipe->buffer_bytes) {
|
||||
int length = pipe->buffer_bytes - offset;
|
||||
count -= length;
|
||||
length >>= 1; /* in 16bit words */
|
||||
/* Transfer using pseudo-dma. */
|
||||
while (length-- > 0) {
|
||||
for (; length > 0; length--) {
|
||||
outw(cpu_to_le16(*addr), port);
|
||||
addr++;
|
||||
}
|
||||
|
@ -384,7 +384,7 @@ static void vxp_dma_write(struct vx_core *chip, struct snd_pcm_runtime *runtime,
|
|||
pipe->hw_ptr += count;
|
||||
count >>= 1; /* in 16bit words */
|
||||
/* Transfer using pseudo-dma. */
|
||||
while (count-- > 0) {
|
||||
for (; count > 0; count--) {
|
||||
outw(cpu_to_le16(*addr), port);
|
||||
addr++;
|
||||
}
|
||||
|
@ -411,12 +411,12 @@ static void vxp_dma_read(struct vx_core *chip, struct snd_pcm_runtime *runtime,
|
|||
if (snd_BUG_ON(count % 2))
|
||||
return;
|
||||
vx_setup_pseudo_dma(chip, 0);
|
||||
if (offset + count > pipe->buffer_bytes) {
|
||||
if (offset + count >= pipe->buffer_bytes) {
|
||||
int length = pipe->buffer_bytes - offset;
|
||||
count -= length;
|
||||
length >>= 1; /* in 16bit words */
|
||||
/* Transfer using pseudo-dma. */
|
||||
while (length-- > 0)
|
||||
for (; length > 0; length--)
|
||||
*addr++ = le16_to_cpu(inw(port));
|
||||
addr = (unsigned short *)runtime->dma_area;
|
||||
pipe->hw_ptr = 0;
|
||||
|
@ -424,7 +424,7 @@ static void vxp_dma_read(struct vx_core *chip, struct snd_pcm_runtime *runtime,
|
|||
pipe->hw_ptr += count;
|
||||
count >>= 1; /* in 16bit words */
|
||||
/* Transfer using pseudo-dma. */
|
||||
while (count-- > 1)
|
||||
for (; count > 1; count--)
|
||||
*addr++ = le16_to_cpu(inw(port));
|
||||
/* Disable DMA */
|
||||
pchip->regDIALOG &= ~VXP_DLG_DMAREAD_SEL_MASK;
|
||||
|
|
|
@ -670,13 +670,10 @@ static int acp_dma_hw_params(struct snd_pcm_substream *substream,
|
|||
{
|
||||
int status;
|
||||
uint64_t size;
|
||||
struct snd_dma_buffer *dma_buffer;
|
||||
struct page *pg;
|
||||
struct snd_pcm_runtime *runtime;
|
||||
struct audio_substream_data *rtd;
|
||||
|
||||
dma_buffer = &substream->dma_buffer;
|
||||
|
||||
runtime = substream->runtime;
|
||||
rtd = runtime->private_data;
|
||||
|
||||
|
|
|
@ -51,11 +51,7 @@
|
|||
#include <sound/soc.h>
|
||||
#include <sound/pcm_params.h>
|
||||
|
||||
#include "atmel_ssc_dai.h"
|
||||
|
||||
struct tse850_priv {
|
||||
int ssc_id;
|
||||
|
||||
struct gpio_desc *add;
|
||||
struct gpio_desc *loop1;
|
||||
struct gpio_desc *loop2;
|
||||
|
@ -329,23 +325,20 @@ static int tse850_dt_init(struct platform_device *pdev)
|
|||
{
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct device_node *codec_np, *cpu_np;
|
||||
struct snd_soc_card *card = &tse850_card;
|
||||
struct snd_soc_dai_link *dailink = &tse850_dailink;
|
||||
struct tse850_priv *tse850 = snd_soc_card_get_drvdata(card);
|
||||
|
||||
if (!np) {
|
||||
dev_err(&pdev->dev, "only device tree supported\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
cpu_np = of_parse_phandle(np, "axentia,ssc-controller", 0);
|
||||
cpu_np = of_parse_phandle(np, "axentia,cpu-dai", 0);
|
||||
if (!cpu_np) {
|
||||
dev_err(&pdev->dev, "failed to get dai and pcm info\n");
|
||||
dev_err(&pdev->dev, "failed to get cpu dai\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
dailink->cpu_of_node = cpu_np;
|
||||
dailink->platform_of_node = cpu_np;
|
||||
tse850->ssc_id = of_alias_get_id(cpu_np, "ssc");
|
||||
of_node_put(cpu_np);
|
||||
|
||||
codec_np = of_parse_phandle(np, "axentia,audio-codec", 0);
|
||||
|
@ -415,23 +408,14 @@ static int tse850_probe(struct platform_device *pdev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
ret = atmel_ssc_set_audio(tse850->ssc_id);
|
||||
if (ret != 0) {
|
||||
dev_err(dev,
|
||||
"failed to set SSC %d for audio\n", tse850->ssc_id);
|
||||
goto err_disable_ana;
|
||||
}
|
||||
|
||||
ret = snd_soc_register_card(card);
|
||||
if (ret) {
|
||||
dev_err(dev, "snd_soc_register_card failed\n");
|
||||
goto err_put_audio;
|
||||
goto err_disable_ana;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_put_audio:
|
||||
atmel_ssc_put_audio(tse850->ssc_id);
|
||||
err_disable_ana:
|
||||
regulator_disable(tse850->ana);
|
||||
return ret;
|
||||
|
@ -443,7 +427,6 @@ static int tse850_remove(struct platform_device *pdev)
|
|||
struct tse850_priv *tse850 = snd_soc_card_get_drvdata(card);
|
||||
|
||||
snd_soc_unregister_card(card);
|
||||
atmel_ssc_put_audio(tse850->ssc_id);
|
||||
regulator_disable(tse850->ana);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -45,7 +45,7 @@ config SND_SOC_ALL_CODECS
|
|||
select SND_SOC_ALC5623 if I2C
|
||||
select SND_SOC_ALC5632 if I2C
|
||||
select SND_SOC_BT_SCO
|
||||
select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC
|
||||
select SND_SOC_CQ0093VC
|
||||
select SND_SOC_CS35L32 if I2C
|
||||
select SND_SOC_CS35L33 if I2C
|
||||
select SND_SOC_CS35L34 if I2C
|
||||
|
@ -95,6 +95,7 @@ config SND_SOC_ALL_CODECS
|
|||
select SND_SOC_MAX9877 if I2C
|
||||
select SND_SOC_MC13783 if MFD_MC13XXX
|
||||
select SND_SOC_ML26124 if I2C
|
||||
select SND_SOC_NAU8540 if I2C
|
||||
select SND_SOC_NAU8810 if I2C
|
||||
select SND_SOC_NAU8825 if I2C
|
||||
select SND_SOC_HDMI_CODEC
|
||||
|
@ -117,8 +118,8 @@ config SND_SOC_ALL_CODECS
|
|||
select SND_SOC_RT5651 if I2C
|
||||
select SND_SOC_RT5659 if I2C
|
||||
select SND_SOC_RT5660 if I2C
|
||||
select SND_SOC_RT5665 if I2C
|
||||
select SND_SOC_RT5663 if I2C
|
||||
select SND_SOC_RT5665 if I2C
|
||||
select SND_SOC_RT5670 if I2C
|
||||
select SND_SOC_RT5677 if I2C && SPI_MASTER
|
||||
select SND_SOC_SGTL5000 if I2C
|
||||
|
@ -525,14 +526,16 @@ config SND_SOC_HDMI_CODEC
|
|||
select HDMI
|
||||
|
||||
config SND_SOC_ES8328
|
||||
tristate "Everest Semi ES8328 CODEC"
|
||||
tristate
|
||||
|
||||
config SND_SOC_ES8328_I2C
|
||||
tristate
|
||||
tristate "Everest Semi ES8328 CODEC (I2C)"
|
||||
depends on I2C
|
||||
select SND_SOC_ES8328
|
||||
|
||||
config SND_SOC_ES8328_SPI
|
||||
tristate
|
||||
tristate "Everest Semi ES8328 CODEC (SPI)"
|
||||
depends on SPI_MASTER
|
||||
select SND_SOC_ES8328
|
||||
|
||||
config SND_SOC_GTM601
|
||||
|
@ -668,8 +671,8 @@ config SND_SOC_RL6231
|
|||
default y if SND_SOC_RT5651=y
|
||||
default y if SND_SOC_RT5659=y
|
||||
default y if SND_SOC_RT5660=y
|
||||
default y if SND_SOC_RT5665=y
|
||||
default y if SND_SOC_RT5663=y
|
||||
default y if SND_SOC_RT5665=y
|
||||
default y if SND_SOC_RT5670=y
|
||||
default y if SND_SOC_RT5677=y
|
||||
default m if SND_SOC_RT5514=m
|
||||
|
@ -679,8 +682,8 @@ config SND_SOC_RL6231
|
|||
default m if SND_SOC_RT5651=m
|
||||
default m if SND_SOC_RT5659=m
|
||||
default m if SND_SOC_RT5660=m
|
||||
default m if SND_SOC_RT5665=m
|
||||
default m if SND_SOC_RT5663=m
|
||||
default m if SND_SOC_RT5665=m
|
||||
default m if SND_SOC_RT5670=m
|
||||
default m if SND_SOC_RT5677=m
|
||||
|
||||
|
@ -728,10 +731,10 @@ config SND_SOC_RT5659
|
|||
config SND_SOC_RT5660
|
||||
tristate
|
||||
|
||||
config SND_SOC_RT5665
|
||||
config SND_SOC_RT5663
|
||||
tristate
|
||||
|
||||
config SND_SOC_RT5663
|
||||
config SND_SOC_RT5665
|
||||
tristate
|
||||
|
||||
config SND_SOC_RT5670
|
||||
|
@ -1105,6 +1108,10 @@ config SND_SOC_MC13783
|
|||
config SND_SOC_ML26124
|
||||
tristate
|
||||
|
||||
config SND_SOC_NAU8540
|
||||
tristate "Nuvoton Technology Corporation NAU85L40 CODEC"
|
||||
depends on I2C
|
||||
|
||||
config SND_SOC_NAU8810
|
||||
tristate "Nuvoton Technology Corporation NAU88C10 CODEC"
|
||||
depends on I2C
|
||||
|
|
|
@ -90,6 +90,7 @@ snd-soc-mc13783-objs := mc13783.o
|
|||
snd-soc-ml26124-objs := ml26124.o
|
||||
snd-soc-msm8916-analog-objs := msm8916-wcd-analog.o
|
||||
snd-soc-msm8916-digital-objs := msm8916-wcd-digital.o
|
||||
snd-soc-nau8540-objs := nau8540.o
|
||||
snd-soc-nau8810-objs := nau8810.o
|
||||
snd-soc-nau8825-objs := nau8825.o
|
||||
snd-soc-hdmi-codec-objs := hdmi-codec.o
|
||||
|
@ -118,8 +119,8 @@ snd-soc-rt5645-objs := rt5645.o
|
|||
snd-soc-rt5651-objs := rt5651.o
|
||||
snd-soc-rt5659-objs := rt5659.o
|
||||
snd-soc-rt5660-objs := rt5660.o
|
||||
snd-soc-rt5665-objs := rt5665.o
|
||||
snd-soc-rt5663-objs := rt5663.o
|
||||
snd-soc-rt5665-objs := rt5665.o
|
||||
snd-soc-rt5670-objs := rt5670.o
|
||||
snd-soc-rt5677-objs := rt5677.o
|
||||
snd-soc-rt5677-spi-objs := rt5677-spi.o
|
||||
|
@ -318,6 +319,7 @@ obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o
|
|||
obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o
|
||||
obj-$(CONFIG_SND_SOC_MSM8916_WCD_ANALOG) +=snd-soc-msm8916-analog.o
|
||||
obj-$(CONFIG_SND_SOC_MSM8916_WCD_DIGITAL) +=snd-soc-msm8916-digital.o
|
||||
obj-$(CONFIG_SND_SOC_NAU8540) += snd-soc-nau8540.o
|
||||
obj-$(CONFIG_SND_SOC_NAU8810) += snd-soc-nau8810.o
|
||||
obj-$(CONFIG_SND_SOC_NAU8825) += snd-soc-nau8825.o
|
||||
obj-$(CONFIG_SND_SOC_HDMI_CODEC) += snd-soc-hdmi-codec.o
|
||||
|
@ -346,8 +348,8 @@ obj-$(CONFIG_SND_SOC_RT5645) += snd-soc-rt5645.o
|
|||
obj-$(CONFIG_SND_SOC_RT5651) += snd-soc-rt5651.o
|
||||
obj-$(CONFIG_SND_SOC_RT5659) += snd-soc-rt5659.o
|
||||
obj-$(CONFIG_SND_SOC_RT5660) += snd-soc-rt5660.o
|
||||
obj-$(CONFIG_SND_SOC_RT5665) += snd-soc-rt5665.o
|
||||
obj-$(CONFIG_SND_SOC_RT5663) += snd-soc-rt5663.o
|
||||
obj-$(CONFIG_SND_SOC_RT5665) += snd-soc-rt5665.o
|
||||
obj-$(CONFIG_SND_SOC_RT5670) += snd-soc-rt5670.o
|
||||
obj-$(CONFIG_SND_SOC_RT5677) += snd-soc-rt5677.o
|
||||
obj-$(CONFIG_SND_SOC_RT5677_SPI) += snd-soc-rt5677-spi.o
|
||||
|
|
|
@ -65,7 +65,6 @@ static int adau17x1_pll_event(struct snd_soc_dapm_widget *w,
|
|||
{
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct adau *adau = snd_soc_codec_get_drvdata(codec);
|
||||
int ret;
|
||||
|
||||
if (SND_SOC_DAPM_EVENT_ON(event)) {
|
||||
adau->pll_regs[5] = 1;
|
||||
|
@ -78,7 +77,7 @@ static int adau17x1_pll_event(struct snd_soc_dapm_widget *w,
|
|||
}
|
||||
|
||||
/* The PLL register is 6 bytes long and can only be written at once. */
|
||||
ret = regmap_raw_write(adau->regmap, ADAU17X1_PLL_CONTROL,
|
||||
regmap_raw_write(adau->regmap, ADAU17X1_PLL_CONTROL,
|
||||
adau->pll_regs, ARRAY_SIZE(adau->pll_regs));
|
||||
|
||||
if (SND_SOC_DAPM_EVENT_ON(event)) {
|
||||
|
|
|
@ -189,7 +189,7 @@ static int ak4642_lout_event(struct snd_soc_dapm_widget *w,
|
|||
case SND_SOC_DAPM_POST_PMU:
|
||||
case SND_SOC_DAPM_POST_PMD:
|
||||
/* Power save mode OFF */
|
||||
mdelay(300);
|
||||
msleep(300);
|
||||
snd_soc_update_bits(codec, SG_SL2, LOPS, 0);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -192,6 +192,7 @@ extern unsigned int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS];
|
|||
#define ARIZONA_DSP_ROUTES(name) \
|
||||
{ name, NULL, name " Preloader"}, \
|
||||
{ name " Preloader", NULL, "SYSCLK" }, \
|
||||
{ name " Preload", NULL, name " Preloader"}, \
|
||||
{ name, NULL, name " Aux 1" }, \
|
||||
{ name, NULL, name " Aux 2" }, \
|
||||
{ name, NULL, name " Aux 3" }, \
|
||||
|
|
|
@ -173,6 +173,9 @@ SOC_ENUM("ISRC2 FSH", arizona_isrc_fsh[1]),
|
|||
SOC_ENUM("ISRC3 FSH", arizona_isrc_fsh[2]),
|
||||
SOC_ENUM("ASRC RATE 1", arizona_asrc_rate1),
|
||||
|
||||
WM_ADSP2_PRELOAD_SWITCH("DSP2", 2),
|
||||
WM_ADSP2_PRELOAD_SWITCH("DSP3", 3),
|
||||
|
||||
ARIZONA_MIXER_CONTROLS("DSP2L", ARIZONA_DSP2LMIX_INPUT_1_SOURCE),
|
||||
ARIZONA_MIXER_CONTROLS("DSP2R", ARIZONA_DSP2RMIX_INPUT_1_SOURCE),
|
||||
ARIZONA_MIXER_CONTROLS("DSP3L", ARIZONA_DSP3LMIX_INPUT_1_SOURCE),
|
||||
|
@ -1121,7 +1124,10 @@ static int cs47l24_codec_probe(struct snd_soc_codec *codec)
|
|||
|
||||
priv->core.arizona->dapm = dapm;
|
||||
|
||||
arizona_init_spk(codec);
|
||||
ret = arizona_init_spk(codec);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
arizona_init_gpio(codec);
|
||||
arizona_init_mono(codec);
|
||||
arizona_init_notifiers(codec);
|
||||
|
|
|
@ -1634,7 +1634,8 @@ static const struct snd_soc_dapm_widget da7218_dapm_widgets[] = {
|
|||
SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
|
||||
|
||||
/* DAI */
|
||||
SND_SOC_DAPM_AIF_OUT("DAIOUT", "Capture", 0, SND_SOC_NOPM, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("DAIOUT", "Capture", 0, DA7218_DAI_TDM_CTRL,
|
||||
DA7218_DAI_OE_SHIFT, DA7218_NO_INVERT),
|
||||
SND_SOC_DAPM_AIF_IN("DAIIN", "Playback", 0, SND_SOC_NOPM, 0, 0),
|
||||
|
||||
/* Output Mixers */
|
||||
|
|
|
@ -20,12 +20,14 @@
|
|||
|
||||
static const struct i2c_device_id es8328_id[] = {
|
||||
{ "es8328", 0 },
|
||||
{ "es8388", 0 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, es8328_id);
|
||||
|
||||
static const struct of_device_id es8328_of_match[] = {
|
||||
{ .compatible = "everest,es8328", },
|
||||
{ .compatible = "everest,es8388", },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, es8328_of_match);
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue