sound updates for 5.12
A relatively calm release at this time, and no massive code changes are found in the stats, while a wide range of code refactoring and cleanup have been done. Note that this update includes the tree-wide trivial changes for dropping the return value from ISA remove callbacks, too. Below lists up some highlight: * ALSA Core: - Support for the software jack injection via debugfs - Fixes for sync_stop PCM operations * HD-audio and USB-audio: - A few usual HD-audio device quirks - Updates for Tegra HD-audio - More quirks for Pioneer and other USB-audio devices - Stricter state checks at USB-audio disconnection * ASoC: - Continued code refactoring, cleanup and fixes in ASoC core API - A KUnit testsuite for the topology code - Lots of ASoC Intel driver Realtek codec updates, quirk additions and fixes - Support for Ingenic JZ4760(B), Intel AlderLake-P, DT configured nVidia cards, Qualcomm lpass-rx-macro and lpass-tx-macro - Removal of obsolete SIRF prima/atlas, Txx9 and ZTE zx drivers * Others: - Drop return value from ISA driver remove callback - Cleanup with DIV_ROUND_UP() macro - FireWire updates, HDSP output loopback support -----BEGIN PGP SIGNATURE----- iQJCBAABCAAsFiEEIXTw5fNLNI7mMiVaLtJE4w1nLE8FAmAvhXoOHHRpd2FpQHN1 c2UuZGUACgkQLtJE4w1nLE9XGA/+MmRBSMipHpZBj6AB2mxbsam2dbPHuycKz1Dd 7W4Rx9QdQcCF2BQ909HKSaE76mTrxkaYc3Ubn8uyfeKz7tB9YpqY5HfIiWRz8iyU FJK/INbkeunLhS61wjKbb8x+pP5M2ZXBTGSRkgVROCgMq4osM+J17c/5wSPE5BoG BGTXUk8LcDE+Iq/6bt2OrXgEBhHCXw7eB/wRWw5v0sIc2cnrexXYUZmHaRj1L3Dd ukpteFEmemOdbowitV+GPSlsnrCD6zselYWms/MLvwLMvTqT4W2SRfsGF5VvGKJC AJsHTWQ5JRKfLt2LJkDs3ymHrKdhnDCWjCUAFNEXd7IRG0Qsk/S+wXsyl3oEhgeQ ND9RoE5pSGG/2Y3Zvt3OevAuVenzQW04/2hFIoAyQg5s/DSom8lNtAsmXkc5dWNI GZJHnvPrdKgzZ0lI9TAbG0v48lnyiQB2sD0FAatWpv3NHcRt0u3fowZgc6Bb3JHK 7cv3upNa1CY7mDSYiT0k3sIHJMrCdoWTPSiewEOxrmLFM1r5O5gHX3dpXhSfh5WJ MI1a93N7sK6WHm6KpeNcHnjrIbP14vOjatOHN+0stuFhLcOGygDX/L0Lu07+15aJ Fxicp23RRwNsb57JcTZTw/+nZhrndSeG3eHYZG2QvQJCv6Ph1tEJ+WAM+tlj85GT feGP0jg= =QgvS -----END PGP SIGNATURE----- Merge tag 'sound-5.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound Pull sound updates from Takashi Iwai: "A relatively calm release at this time, and no massive code changes are found in the stats, while a wide range of code refactoring and cleanup have been done. Note that this update includes the tree-wide trivial changes for dropping the return value from ISA remove callbacks, too. Below lists up some highlight: ALSA Core: - Support for the software jack injection via debugfs - Fixes for sync_stop PCM operations HD-audio and USB-audio: - A few usual HD-audio device quirks - Updates for Tegra HD-audio - More quirks for Pioneer and other USB-audio devices - Stricter state checks at USB-audio disconnection ASoC: - Continued code refactoring, cleanup and fixes in ASoC core API - A KUnit testsuite for the topology code - Lots of ASoC Intel driver Realtek codec updates, quirk additions and fixes - Support for Ingenic JZ4760(B), Intel AlderLake-P, DT configured nVidia cards, Qualcomm lpass-rx-macro and lpass-tx-macro - Removal of obsolete SIRF prima/atlas, Txx9 and ZTE zx drivers Others: - Drop return value from ISA driver remove callback - Cleanup with DIV_ROUND_UP() macro - FireWire updates, HDSP output loopback support" * tag 'sound-5.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (322 commits) ALSA: hda: intel-dsp-config: add Alder Lake support ASoC: soc-pcm: fix hw param limits calculation for multi-DAI ASoC: Intel: bytcr_rt5640: Add quirk for the Acer One S1002 tablet ASoC: Intel: bytcr_rt5651: Add quirk for the Jumper EZpad 7 tablet ASoC: Intel: bytcr_rt5640: Add quirk for the Voyo Winpad A15 tablet ASoC: Intel: bytcr_rt5640: Add quirk for the Estar Beauty HD MID 7316R tablet ASoC: soc-pcm: fix hwparams min/max init for dpcm ALSA: hda/realtek: Quirk for HP Spectre x360 14 amp setup ALSA: usb-audio: Add implicit fb quirk for BOSS GP-10 ALSA: hda: Add another CometLake-H PCI ID ASoC: soc-pcm: add soc_pcm_hw_update_format() ASoC: soc-pcm: add soc_pcm_hw_update_chan() ASoC: soc-pcm: add soc_pcm_hw_update_rate() ASoC: wm_adsp: Remove unused control callback structure ASoC: SOF: relax ABI checks and avoid unnecessary warnings ASoC: codecs: lpass-tx-macro: add dapm widgets and route ASoC: codecs: lpass-tx-macro: add support for lpass tx macro ASoC: qcom: dt-bindings: add bindings for lpass tx macro codec ASoC: codecs: lpass-rx-macro: add iir widgets ASoC: codecs: lpass-rx-macro: add dapm widgets and route ...
This commit is contained in:
commit
10e2ec8ede
|
@ -71,9 +71,6 @@ properties:
|
|||
description: CPU to Codec rate channels.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
|
||||
required:
|
||||
- remote-endpoint
|
||||
|
||||
ports:
|
||||
description: multi OF-Graph subnode
|
||||
type: object
|
||||
|
|
|
@ -15,9 +15,14 @@ properties:
|
|||
|
||||
compatible:
|
||||
oneOf:
|
||||
- const: ingenic,jz4770-codec
|
||||
- const: ingenic,jz4725b-codec
|
||||
- const: ingenic,jz4740-codec
|
||||
- enum:
|
||||
- ingenic,jz4770-codec
|
||||
- ingenic,jz4760-codec
|
||||
- ingenic,jz4725b-codec
|
||||
- ingenic,jz4740-codec
|
||||
- items:
|
||||
- const: ingenic,jz4760b-codec
|
||||
- const: ingenic,jz4760-codec
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
|
|
@ -18,6 +18,7 @@ properties:
|
|||
enum:
|
||||
- intel,keembay-i2s
|
||||
- intel,keembay-tdm
|
||||
- intel,keembay-hdmi-i2s
|
||||
|
||||
"#sound-dai-cells":
|
||||
const: 0
|
||||
|
@ -45,6 +46,16 @@ properties:
|
|||
- const: osc
|
||||
- const: apb_clk
|
||||
|
||||
dmas:
|
||||
items:
|
||||
- description: DMA TX channel
|
||||
- description: DMA RX channel
|
||||
|
||||
dma-names:
|
||||
items:
|
||||
- const: tx
|
||||
- const: rx
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- "#sound-dai-cells"
|
||||
|
@ -70,4 +81,6 @@ examples:
|
|||
interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clock-names = "osc", "apb_clk";
|
||||
clocks = <&scmi_clk KEEM_BAY_PSS_AUX_I2S3>, <&scmi_clk KEEM_BAY_PSS_I2S3>;
|
||||
dmas = <&axi_dma0 29 &axi_dma0 33>;
|
||||
dma-names = "tx", "rx";
|
||||
};
|
||||
|
|
|
@ -23,6 +23,10 @@ properties:
|
|||
$ref: "/schemas/types.yaml#/definitions/phandle"
|
||||
description: The phandle of MT8192 ASoC platform.
|
||||
|
||||
mediatek,hdmi-codec:
|
||||
$ref: "/schemas/types.yaml#/definitions/phandle"
|
||||
description: The phandle of HDMI codec.
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
|
@ -35,6 +39,7 @@ examples:
|
|||
sound: mt8192-sound {
|
||||
compatible = "mediatek,mt8192_mt6359_rt1015_rt5682";
|
||||
mediatek,platform = <&afe>;
|
||||
mediatek,hdmi-codec = <&anx_bridge_dp>;
|
||||
pinctrl-names = "aud_clk_mosi_off",
|
||||
"aud_clk_mosi_on";
|
||||
pinctrl-0 = <&aud_clk_mosi_off>;
|
||||
|
|
|
@ -0,0 +1,190 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/nvidia,tegra-audio-graph-card.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Audio Graph based Tegra sound card driver
|
||||
|
||||
description: |
|
||||
This is based on generic audio graph card driver along with additional
|
||||
customizations for Tegra platforms. It uses the same bindings with
|
||||
additional standard clock DT bindings required for Tegra.
|
||||
|
||||
maintainers:
|
||||
- Jon Hunter <jonathanh@nvidia.com>
|
||||
- Sameer Pujar <spujar@nvidia.com>
|
||||
|
||||
allOf:
|
||||
- $ref: audio-graph.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- nvidia,tegra210-audio-graph-card
|
||||
- nvidia,tegra186-audio-graph-card
|
||||
|
||||
clocks:
|
||||
minItems: 2
|
||||
|
||||
clock-names:
|
||||
minItems: 2
|
||||
items:
|
||||
- const: pll_a
|
||||
- const: plla_out0
|
||||
|
||||
assigned-clocks:
|
||||
minItems: 1
|
||||
maxItems: 3
|
||||
|
||||
assigned-clock-parents:
|
||||
minItems: 1
|
||||
maxItems: 3
|
||||
|
||||
assigned-clock-rates:
|
||||
minItems: 1
|
||||
maxItems: 3
|
||||
|
||||
iommus:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- clocks
|
||||
- clock-names
|
||||
- assigned-clocks
|
||||
- assigned-clock-parents
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include<dt-bindings/clock/tegra210-car.h>
|
||||
|
||||
tegra_sound {
|
||||
compatible = "nvidia,tegra210-audio-graph-card";
|
||||
|
||||
clocks = <&tegra_car TEGRA210_CLK_PLL_A>,
|
||||
<&tegra_car TEGRA210_CLK_PLL_A_OUT0>;
|
||||
clock-names = "pll_a", "plla_out0";
|
||||
|
||||
assigned-clocks = <&tegra_car TEGRA210_CLK_PLL_A>,
|
||||
<&tegra_car TEGRA210_CLK_PLL_A_OUT0>,
|
||||
<&tegra_car TEGRA210_CLK_EXTERN1>;
|
||||
assigned-clock-parents = <0>, <0>, <&tegra_car TEGRA210_CLK_PLL_A_OUT0>;
|
||||
assigned-clock-rates = <368640000>, <49152000>, <12288000>;
|
||||
|
||||
dais = /* FE */
|
||||
<&admaif1_port>,
|
||||
/* Router */
|
||||
<&xbar_i2s1_port>,
|
||||
/* I/O DAP Ports */
|
||||
<&i2s1_port>;
|
||||
|
||||
label = "jetson-tx1-ape";
|
||||
};
|
||||
|
||||
// The ports are defined for AHUB and its child devices.
|
||||
ahub@702d0800 {
|
||||
compatible = "nvidia,tegra210-ahub";
|
||||
reg = <0x702d0800 0x800>;
|
||||
clocks = <&tegra_car TEGRA210_CLK_D_AUDIO>;
|
||||
clock-names = "ahub";
|
||||
assigned-clocks = <&tegra_car TEGRA210_CLK_D_AUDIO>;
|
||||
assigned-clock-parents = <&tegra_car TEGRA210_CLK_PLL_A_OUT0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges = <0x702d0000 0x702d0000 0x0000e400>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0x0>;
|
||||
xbar_admaif1_ep: endpoint {
|
||||
remote-endpoint = <&admaif1_ep>;
|
||||
};
|
||||
};
|
||||
|
||||
// ...
|
||||
|
||||
xbar_i2s1_port: port@a {
|
||||
reg = <0xa>;
|
||||
xbar_i2s1_ep: endpoint {
|
||||
remote-endpoint = <&i2s1_cif_ep>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
admaif@702d0000 {
|
||||
compatible = "nvidia,tegra210-admaif";
|
||||
reg = <0x702d0000 0x800>;
|
||||
dmas = <&adma 1>, <&adma 1>,
|
||||
<&adma 2>, <&adma 2>,
|
||||
<&adma 3>, <&adma 3>,
|
||||
<&adma 4>, <&adma 4>,
|
||||
<&adma 5>, <&adma 5>,
|
||||
<&adma 6>, <&adma 6>,
|
||||
<&adma 7>, <&adma 7>,
|
||||
<&adma 8>, <&adma 8>,
|
||||
<&adma 9>, <&adma 9>,
|
||||
<&adma 10>, <&adma 10>;
|
||||
dma-names = "rx1", "tx1",
|
||||
"rx2", "tx2",
|
||||
"rx3", "tx3",
|
||||
"rx4", "tx4",
|
||||
"rx5", "tx5",
|
||||
"rx6", "tx6",
|
||||
"rx7", "tx7",
|
||||
"rx8", "tx8",
|
||||
"rx9", "tx9",
|
||||
"rx10", "tx10";
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
admaif1_port: port@0 {
|
||||
reg = <0x0>;
|
||||
admaif1_ep: endpoint {
|
||||
remote-endpoint = <&xbar_admaif1_ep>;
|
||||
};
|
||||
};
|
||||
|
||||
// More ADMAIF ports to follow
|
||||
};
|
||||
};
|
||||
|
||||
i2s@702d1000 {
|
||||
compatible = "nvidia,tegra210-i2s";
|
||||
clocks = <&tegra_car TEGRA210_CLK_I2S0>;
|
||||
clock-names = "i2s";
|
||||
assigned-clocks = <&tegra_car TEGRA210_CLK_I2S0>;
|
||||
assigned-clock-parents = <&tegra_car TEGRA210_CLK_PLL_A_OUT0>;
|
||||
assigned-clock-rates = <1536000>;
|
||||
reg = <0x702d1000 0x100>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0x0>;
|
||||
|
||||
i2s1_cif_ep: endpoint {
|
||||
remote-endpoint = <&xbar_i2s1_ep>;
|
||||
};
|
||||
};
|
||||
|
||||
i2s1_port: port@1 {
|
||||
reg = <0x1>;
|
||||
|
||||
i2s1_dap: endpoint {
|
||||
dai-format = "i2s";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
...
|
|
@ -17,6 +17,9 @@ maintainers:
|
|||
- Jon Hunter <jonathanh@nvidia.com>
|
||||
- Sameer Pujar <spujar@nvidia.com>
|
||||
|
||||
allOf:
|
||||
- $ref: audio-graph-port.yaml#
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "^dspk@[0-9a-f]*$"
|
||||
|
@ -55,6 +58,19 @@ properties:
|
|||
The name can be "DSPK1" or "DSPKx", where x depends on the maximum
|
||||
available instances on a Tegra SoC.
|
||||
|
||||
ports:
|
||||
type: object
|
||||
properties:
|
||||
port@0:
|
||||
description: |
|
||||
DSPK ACIF (Audio Client Interface) port connected to the
|
||||
corresponding AHUB (Audio Hub) ACIF port.
|
||||
|
||||
port@1:
|
||||
description: |
|
||||
DSPK DAP (Digital Audio Port) interface which can be connected
|
||||
to external audio codec for playback.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
@ -64,7 +80,7 @@ required:
|
|||
- assigned-clock-parents
|
||||
- sound-name-prefix
|
||||
|
||||
additionalProperties: false
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
|
|
|
@ -17,6 +17,9 @@ maintainers:
|
|||
- Jon Hunter <jonathanh@nvidia.com>
|
||||
- Sameer Pujar <spujar@nvidia.com>
|
||||
|
||||
allOf:
|
||||
- $ref: audio-graph-port.yaml#
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "^admaif@[0-9a-f]*$"
|
||||
|
@ -37,6 +40,14 @@ properties:
|
|||
|
||||
dma-names: true
|
||||
|
||||
ports:
|
||||
description: |
|
||||
Contains list of ACIF (Audio CIF) port nodes for ADMAIF channels.
|
||||
The number of port nodes depends on the number of ADMAIF channels
|
||||
that SoC may have. These are interfaced with respective ACIF ports
|
||||
in AHUB (Audio Hub). Each port is capable of data transfers in
|
||||
both directions.
|
||||
|
||||
if:
|
||||
properties:
|
||||
compatible:
|
||||
|
@ -81,7 +92,7 @@ required:
|
|||
- dmas
|
||||
- dma-names
|
||||
|
||||
additionalProperties: false
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
|
|
|
@ -17,6 +17,9 @@ maintainers:
|
|||
- Jon Hunter <jonathanh@nvidia.com>
|
||||
- Sameer Pujar <spujar@nvidia.com>
|
||||
|
||||
allOf:
|
||||
- $ref: audio-graph-port.yaml#
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "^ahub@[0-9a-f]*$"
|
||||
|
@ -56,6 +59,13 @@ properties:
|
|||
|
||||
ranges: true
|
||||
|
||||
ports:
|
||||
description: |
|
||||
Contains list of ACIF (Audio CIF) port nodes for AHUB (Audio Hub).
|
||||
These are connected to ACIF interfaces of AHUB clients. Thus the
|
||||
number of port nodes depend on the number of clients that AHUB may
|
||||
have depending on the SoC revision.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
@ -67,8 +77,7 @@ required:
|
|||
- "#size-cells"
|
||||
- ranges
|
||||
|
||||
additionalProperties:
|
||||
type: object
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
|
|
|
@ -16,6 +16,9 @@ maintainers:
|
|||
- Jon Hunter <jonathanh@nvidia.com>
|
||||
- Sameer Pujar <spujar@nvidia.com>
|
||||
|
||||
allOf:
|
||||
- $ref: audio-graph-port.yaml#
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "^dmic@[0-9a-f]*$"
|
||||
|
@ -56,6 +59,19 @@ properties:
|
|||
The name can be "DMIC1" or "DMIC2" ... "DMICx", where x depends
|
||||
on the maximum available instances on a Tegra SoC.
|
||||
|
||||
ports:
|
||||
type: object
|
||||
properties:
|
||||
port@0:
|
||||
description: |
|
||||
DMIC ACIF (Audio Client Interface) port connected to the
|
||||
corresponding AHUB (Audio Hub) ACIF port.
|
||||
|
||||
port@1:
|
||||
description: |
|
||||
DMIC DAP (Digital Audio Port) interface which can be connected
|
||||
to external audio codec for capture.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
@ -64,7 +80,7 @@ required:
|
|||
- assigned-clocks
|
||||
- assigned-clock-parents
|
||||
|
||||
additionalProperties: false
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
|
|
|
@ -16,6 +16,9 @@ maintainers:
|
|||
- Jon Hunter <jonathanh@nvidia.com>
|
||||
- Sameer Pujar <spujar@nvidia.com>
|
||||
|
||||
allOf:
|
||||
- $ref: audio-graph-port.yaml#
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "^i2s@[0-9a-f]*$"
|
||||
|
@ -74,6 +77,19 @@ properties:
|
|||
The name can be "I2S1" or "I2S2" ... "I2Sx", where x depends
|
||||
on the maximum available instances on a Tegra SoC.
|
||||
|
||||
ports:
|
||||
type: object
|
||||
properties:
|
||||
port@0:
|
||||
description: |
|
||||
I2S ACIF (Audio Client Interface) port connected to the
|
||||
corresponding AHUB (Audio Hub) ACIF port.
|
||||
|
||||
port@1:
|
||||
description: |
|
||||
I2S DAP (Digital Audio Port) interface which can be connected
|
||||
to external audio codec for playback or capture.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
@ -82,7 +98,7 @@ required:
|
|||
- assigned-clocks
|
||||
- assigned-clock-parents
|
||||
|
||||
additionalProperties: false
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/qcom,lpass-rx-macro.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: LPASS(Low Power Audio Subsystem) RX Macro audio codec DT bindings
|
||||
|
||||
maintainers:
|
||||
- Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sm8250-lpass-rx-macro
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
"#sound-dai-cells":
|
||||
const: 1
|
||||
|
||||
'#clock-cells':
|
||||
const: 0
|
||||
|
||||
clocks:
|
||||
maxItems: 5
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: mclk
|
||||
- const: npl
|
||||
- const: macro
|
||||
- const: dcodec
|
||||
- const: fsgen
|
||||
|
||||
clock-output-names:
|
||||
items:
|
||||
- const: mclk
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- "#sound-dai-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/sound/qcom,q6afe.h>
|
||||
codec@3200000 {
|
||||
compatible = "qcom,sm8250-lpass-rx-macro";
|
||||
reg = <0x3200000 0x1000>;
|
||||
#sound-dai-cells = <1>;
|
||||
#clock-cells = <0>;
|
||||
clocks = <&audiocc 0>,
|
||||
<&audiocc 1>,
|
||||
<&q6afecc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
|
||||
<&q6afecc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
|
||||
<&vamacro>;
|
||||
clock-names = "mclk", "npl", "macro", "dcodec", "fsgen";
|
||||
clock-output-names = "mclk";
|
||||
};
|
|
@ -0,0 +1,67 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/qcom,lpass-tx-macro.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: LPASS(Low Power Audio Subsystem) TX Macro audio codec DT bindings
|
||||
|
||||
maintainers:
|
||||
- Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sm8250-lpass-tx-macro
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
"#sound-dai-cells":
|
||||
const: 1
|
||||
|
||||
'#clock-cells':
|
||||
const: 0
|
||||
|
||||
clocks:
|
||||
maxItems: 5
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: mclk
|
||||
- const: npl
|
||||
- const: macro
|
||||
- const: dcodec
|
||||
- const: fsgen
|
||||
|
||||
clock-output-names:
|
||||
items:
|
||||
- const: mclk
|
||||
|
||||
qcom,dmic-sample-rate:
|
||||
description: dmic sample rate
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- "#sound-dai-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/sound/qcom,q6afe.h>
|
||||
codec@3220000 {
|
||||
compatible = "qcom,sm8250-lpass-tx-macro";
|
||||
reg = <0x3220000 0x1000>;
|
||||
#sound-dai-cells = <1>;
|
||||
#clock-cells = <0>;
|
||||
clocks = <&aoncc 0>,
|
||||
<&aoncc 1>,
|
||||
<&q6afecc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
|
||||
<&q6afecc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
|
||||
<&vamacro>;
|
||||
clock-names = "mclk", "npl", "macro", "dcodec", "fsgen";
|
||||
clock-output-names = "mclk";
|
||||
qcom,dmic-sample-rate = <600000>;
|
||||
};
|
|
@ -404,7 +404,7 @@ examples:
|
|||
/* DAI base */
|
||||
rcar_sound,dai {
|
||||
dai0 {
|
||||
playback = <&ssi5 &src5>;
|
||||
playback = <&ssi5>, <&src5>;
|
||||
capture = <&ssi6>;
|
||||
};
|
||||
dai1 {
|
||||
|
@ -430,8 +430,8 @@ examples:
|
|||
bitclock-master = <&rsnd_endpoint0>;
|
||||
frame-master = <&rsnd_endpoint0>;
|
||||
|
||||
playback = <&ssi0 &src0 &dvc0>;
|
||||
capture = <&ssi1 &src1 &dvc1>;
|
||||
playback = <&ssi0>, <&src0>, <&dvc0>;
|
||||
capture = <&ssi1>, <&src1>, <&dvc1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -37,10 +37,21 @@ Optional properties:
|
|||
- realtek,jd-src
|
||||
0: No JD is used
|
||||
1: using JD3 as JD source
|
||||
2: JD source for Intel HDA header
|
||||
|
||||
- realtek,ldo1-en-gpios : The GPIO that controls the CODEC's LDO1_EN pin.
|
||||
- realtek,reset-gpios : The GPIO that controls the CODEC's RESET pin.
|
||||
|
||||
- sound-name-prefix: Please refer to name-prefix.txt
|
||||
|
||||
- ports: A Codec may have a single or multiple I2S interfaces. These
|
||||
interfaces on Codec side can be described under 'ports' or 'port'.
|
||||
When the SoC or host device is connected to multiple interfaces of
|
||||
the Codec, the connectivity can be described using 'ports' property.
|
||||
If a single interface is used, then 'port' can be used. The usage
|
||||
depends on the platform or board design.
|
||||
Please refer to Documentation/devicetree/bindings/graph.txt
|
||||
|
||||
Pins on the device (for linking into audio routes) for RT5659/RT5658:
|
||||
|
||||
* DMIC L1
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
SiRF internal audio CODEC
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : "sirf,atlas6-audio-codec" or "sirf,prima2-audio-codec"
|
||||
|
||||
- reg : the register address of the device.
|
||||
|
||||
- clocks: the clock of SiRF internal audio codec
|
||||
|
||||
Example:
|
||||
|
||||
audiocodec: audiocodec@b0040000 {
|
||||
compatible = "sirf,atlas6-audio-codec";
|
||||
reg = <0xb0040000 0x10000>;
|
||||
clocks = <&clks 27>;
|
||||
};
|
|
@ -1,27 +0,0 @@
|
|||
* SiRF SoC USP module
|
||||
|
||||
Required properties:
|
||||
- compatible: "sirf,prima2-usp-pcm"
|
||||
- reg: Base address and size entries:
|
||||
- dmas: List of DMA controller phandle and DMA request line ordered pairs.
|
||||
- dma-names: Identifier string for each DMA request line in the dmas property.
|
||||
These strings correspond 1:1 with the ordered pairs in dmas.
|
||||
|
||||
One of the DMA channels will be responsible for transmission (should be
|
||||
named "tx") and one for reception (should be named "rx").
|
||||
|
||||
- clocks: USP controller clock source
|
||||
- pinctrl-names: Must contain a "default" entry.
|
||||
- pinctrl-NNN: One property must exist for each entry in pinctrl-names.
|
||||
|
||||
Example:
|
||||
usp0: usp@b0080000 {
|
||||
compatible = "sirf,prima2-usp-pcm";
|
||||
reg = <0xb0080000 0x10000>;
|
||||
clocks = <&clks 28>;
|
||||
dmas = <&dmac1 1>, <&dmac1 2>;
|
||||
dma-names = "rx", "tx";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&usp0_only_utfs_pins_a>;
|
||||
};
|
||||
|
|
@ -54,6 +54,10 @@ properties:
|
|||
resets:
|
||||
maxItems: 1
|
||||
|
||||
"#clock-cells":
|
||||
description: Configure the I2S device as MCLK clock provider.
|
||||
const: 0
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- "#sound-dai-cells"
|
||||
|
|
|
@ -9,6 +9,9 @@ Required properties:
|
|||
- reg : the I2C address of the device.
|
||||
|
||||
Optional properties:
|
||||
|
||||
- clocks : The clock source of the mclk
|
||||
|
||||
- spk-mono: This is a boolean property. If present, the SPK_MONO bit
|
||||
of R51 (Class D Control 2) gets set, indicating that the speaker is
|
||||
in mono mode.
|
||||
|
@ -27,6 +30,7 @@ Example:
|
|||
wm8962: codec@1a {
|
||||
compatible = "wlf,wm8962";
|
||||
reg = <0x1a>;
|
||||
clocks = <&clks IMX6QDL_CLK_CKO>;
|
||||
|
||||
gpio-cfg = <
|
||||
0x0000 /* 0:Default */
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
ZTE TDM DAI driver
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : should be one of the following.
|
||||
* zte,zx296718-tdm
|
||||
- reg : physical base address of the controller and length of memory mapped
|
||||
region.
|
||||
- clocks : Pairs of phandle and specifier referencing the controller's clocks.
|
||||
- clock-names: "wclk" for the wclk.
|
||||
"pclk" for the pclk.
|
||||
-#clock-cells: should be 1.
|
||||
- zte,tdm-dma-sysctrl : Reference to the sysctrl controller controlling
|
||||
the dma. includes:
|
||||
phandle of sysctrl.
|
||||
register offset in sysctrl for control dma.
|
||||
mask of the register that be written to sysctrl.
|
||||
|
||||
Example:
|
||||
|
||||
tdm: tdm@1487000 {
|
||||
compatible = "zte,zx296718-tdm";
|
||||
reg = <0x01487000 0x1000>;
|
||||
clocks = <&audiocrm AUDIO_TDM_WCLK>, <&audiocrm AUDIO_TDM_PCLK>;
|
||||
clock-names = "wclk", "pclk";
|
||||
#clock-cells = <1>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&tdm_global_pin>;
|
||||
zte,tdm-dma-sysctrl = <&sysctrl 0x10c 4>;
|
||||
};
|
|
@ -1,24 +0,0 @@
|
|||
ZTE ZX AUD96P22 Audio Codec
|
||||
|
||||
Required properties:
|
||||
- compatible: Must be "zte,zx-aud96p22"
|
||||
- #sound-dai-cells: Should be 0
|
||||
- reg: I2C bus slave address of AUD96P22
|
||||
|
||||
Example:
|
||||
|
||||
i2c0: i2c@1486000 {
|
||||
compatible = "zte,zx296718-i2c";
|
||||
reg = <0x01486000 0x1000>;
|
||||
interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
clocks = <&audiocrm AUDIO_I2C0_WCLK>;
|
||||
clock-frequency = <1600000>;
|
||||
|
||||
aud96p22: codec@22 {
|
||||
compatible = "zte,zx-aud96p22";
|
||||
#sound-dai-cells = <0>;
|
||||
reg = <0x22>;
|
||||
};
|
||||
};
|
|
@ -1,45 +0,0 @@
|
|||
ZTE ZX296702 I2S controller
|
||||
|
||||
Required properties:
|
||||
- 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: "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"
|
||||
|
||||
For more details on the 'dma', 'dma-names', 'clock' and 'clock-names' properties
|
||||
please check:
|
||||
* resource-names.txt
|
||||
* clock/clock-bindings.txt
|
||||
* dma/dma.txt
|
||||
|
||||
Example:
|
||||
i2s0: i2s@b005000 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "zte,zx296718-i2s", "zte,zx296702-i2s";
|
||||
reg = <0x0b005000 0x1000>;
|
||||
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";
|
||||
};
|
||||
|
||||
sound {
|
||||
compatible = "simple-audio-card";
|
||||
simple-audio-card,name = "zx296702_snd";
|
||||
simple-audio-card,format = "left_j";
|
||||
simple-audio-card,bitclock-master = <&sndcodec>;
|
||||
simple-audio-card,frame-master = <&sndcodec>;
|
||||
sndcpu: simple-audio-card,cpu {
|
||||
sound-dai = <&i2s0>;
|
||||
};
|
||||
|
||||
sndcodec: simple-audio-card,codec {
|
||||
sound-dai = <&acodec>;
|
||||
};
|
||||
};
|
|
@ -1,27 +0,0 @@
|
|||
ZTE ZX296702 SPDIF controller
|
||||
|
||||
Required properties:
|
||||
- compatible : Must be "zte,zx296702-spdif"
|
||||
- reg : Must contain SPDIF 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 SPDIF interface.
|
||||
- dmas: Pairs of phandle and specifier for the DMA channel that is used by
|
||||
the core. The core expects one dma channel for transmit.
|
||||
- dma-names : Must be "tx"
|
||||
|
||||
For more details on the 'dma', 'dma-names', 'clock' and 'clock-names' properties
|
||||
please check:
|
||||
* resource-names.txt
|
||||
* clock/clock-bindings.txt
|
||||
* dma/dma.txt
|
||||
|
||||
Example:
|
||||
spdif0: spdif0@b004000 {
|
||||
compatible = "zte,zx296702-spdif";
|
||||
reg = <0x0b004000 0x1000>;
|
||||
clocks = <&lsp0clk ZX296702_SPDIF0_DIV>;
|
||||
clock-names = "tx";
|
||||
interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
|
||||
dmas = <&dma 4>;
|
||||
dma-names = "tx";
|
||||
};
|
|
@ -14,3 +14,4 @@ Designs and Implementations
|
|||
powersave
|
||||
oss-emulation
|
||||
seq-oss
|
||||
jack-injection
|
||||
|
|
|
@ -0,0 +1,166 @@
|
|||
============================
|
||||
ALSA Jack Software Injection
|
||||
============================
|
||||
|
||||
Simple Introduction On Jack Injection
|
||||
=====================================
|
||||
|
||||
Here jack injection means users could inject plugin or plugout events
|
||||
to the audio jacks through debugfs interface, it is helpful to
|
||||
validate ALSA userspace changes. For example, we change the audio
|
||||
profile switching code in the pulseaudio, and we want to verify if the
|
||||
change works as expected and if the change introduce the regression,
|
||||
in this case, we could inject plugin or plugout events to an audio
|
||||
jack or to some audio jacks, we don't need to physically access the
|
||||
machine and plug/unplug physical devices to the audio jack.
|
||||
|
||||
In this design, an audio jack doesn't equal to a physical audio jack.
|
||||
Sometimes a physical audio jack contains multi functions, and the
|
||||
ALSA driver creates multi ``jack_kctl`` for a ``snd_jack``, here the
|
||||
``snd_jack`` represents a physical audio jack and the ``jack_kctl``
|
||||
represents a function, for example a physical jack has two functions:
|
||||
headphone and mic_in, the ALSA ASoC driver will build 2 ``jack_kctl``
|
||||
for this jack. The jack injection is implemented based on the
|
||||
``jack_kctl`` instead of ``snd_jack``.
|
||||
|
||||
To inject events to audio jacks, we need to enable the jack injection
|
||||
via ``sw_inject_enable`` first, once it is enabled, this jack will not
|
||||
change the state by hardware events anymore, we could inject plugin or
|
||||
plugout events via ``jackin_inject`` and check the jack state via
|
||||
``status``, after we finish our test, we need to disable the jack
|
||||
injection via ``sw_inject_enable`` too, once it is disabled, the jack
|
||||
state will be restored according to the last reported hardware events
|
||||
and will change by future hardware events.
|
||||
|
||||
The Layout of Jack Injection Interface
|
||||
======================================
|
||||
|
||||
If users enable the SND_JACK_INJECTION_DEBUG in the kernel, the audio
|
||||
jack injection interface will be created as below:
|
||||
::
|
||||
|
||||
$debugfs_mount_dir/sound
|
||||
|-- card0
|
||||
|-- |-- HDMI_DP_pcm_10_Jack
|
||||
|-- |-- |-- jackin_inject
|
||||
|-- |-- |-- kctl_id
|
||||
|-- |-- |-- mask_bits
|
||||
|-- |-- |-- status
|
||||
|-- |-- |-- sw_inject_enable
|
||||
|-- |-- |-- type
|
||||
...
|
||||
|-- |-- HDMI_DP_pcm_9_Jack
|
||||
|-- |-- jackin_inject
|
||||
|-- |-- kctl_id
|
||||
|-- |-- mask_bits
|
||||
|-- |-- status
|
||||
|-- |-- sw_inject_enable
|
||||
|-- |-- type
|
||||
|-- card1
|
||||
|-- HDMI_DP_pcm_5_Jack
|
||||
|-- |-- jackin_inject
|
||||
|-- |-- kctl_id
|
||||
|-- |-- mask_bits
|
||||
|-- |-- status
|
||||
|-- |-- sw_inject_enable
|
||||
|-- |-- type
|
||||
...
|
||||
|-- Headphone_Jack
|
||||
|-- |-- jackin_inject
|
||||
|-- |-- kctl_id
|
||||
|-- |-- mask_bits
|
||||
|-- |-- status
|
||||
|-- |-- sw_inject_enable
|
||||
|-- |-- type
|
||||
|-- Headset_Mic_Jack
|
||||
|-- jackin_inject
|
||||
|-- kctl_id
|
||||
|-- mask_bits
|
||||
|-- status
|
||||
|-- sw_inject_enable
|
||||
|-- type
|
||||
|
||||
The Explanation Of The Nodes
|
||||
======================================
|
||||
|
||||
kctl_id
|
||||
read-only, get jack_kctl->kctl's id
|
||||
::
|
||||
|
||||
sound/card1/Headphone_Jack# cat kctl_id
|
||||
Headphone Jack
|
||||
|
||||
mask_bits
|
||||
read-only, get jack_kctl's supported events mask_bits
|
||||
::
|
||||
|
||||
sound/card1/Headphone_Jack# cat mask_bits
|
||||
0x0001 HEADPHONE(0x0001)
|
||||
|
||||
status
|
||||
read-only, get jack_kctl's current status
|
||||
|
||||
- headphone unplugged:
|
||||
|
||||
::
|
||||
|
||||
sound/card1/Headphone_Jack# cat status
|
||||
Unplugged
|
||||
|
||||
- headphone plugged:
|
||||
|
||||
::
|
||||
|
||||
sound/card1/Headphone_Jack# cat status
|
||||
Plugged
|
||||
|
||||
type
|
||||
read-only, get snd_jack's supported events from type (all supported events on the physical audio jack)
|
||||
::
|
||||
|
||||
sound/card1/Headphone_Jack# cat type
|
||||
0x7803 HEADPHONE(0x0001) MICROPHONE(0x0002) BTN_3(0x0800) BTN_2(0x1000) BTN_1(0x2000) BTN_0(0x4000)
|
||||
|
||||
sw_inject_enable
|
||||
read-write, enable or disable injection
|
||||
|
||||
- injection disabled:
|
||||
|
||||
::
|
||||
|
||||
sound/card1/Headphone_Jack# cat sw_inject_enable
|
||||
Jack: Headphone Jack Inject Enabled: 0
|
||||
|
||||
- injection enabled:
|
||||
|
||||
::
|
||||
|
||||
sound/card1/Headphone_Jack# cat sw_inject_enable
|
||||
Jack: Headphone Jack Inject Enabled: 1
|
||||
|
||||
- to enable jack injection:
|
||||
|
||||
::
|
||||
|
||||
sound/card1/Headphone_Jack# echo 1 > sw_inject_enable
|
||||
|
||||
- to disable jack injection:
|
||||
|
||||
::
|
||||
|
||||
sound/card1/Headphone_Jack# echo 0 > sw_inject_enable
|
||||
|
||||
jackin_inject
|
||||
write-only, inject plugin or plugout
|
||||
|
||||
- to inject plugin:
|
||||
|
||||
::
|
||||
|
||||
sound/card1/Headphone_Jack# echo 1 > jackin_inject
|
||||
|
||||
- to inject plugout:
|
||||
|
||||
::
|
||||
|
||||
sound/card1/Headphone_Jack# echo 0 > jackin_inject
|
|
@ -51,7 +51,7 @@ static int isa_bus_remove(struct device *dev)
|
|||
struct isa_driver *isa_driver = dev->platform_data;
|
||||
|
||||
if (isa_driver && isa_driver->remove)
|
||||
return isa_driver->remove(dev, to_isa_dev(dev)->id);
|
||||
isa_driver->remove(dev, to_isa_dev(dev)->id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -282,7 +282,7 @@ static int elektor_probe(struct device *dev, unsigned int id)
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
static int elektor_remove(struct device *dev, unsigned int id)
|
||||
static void elektor_remove(struct device *dev, unsigned int id)
|
||||
{
|
||||
i2c_del_adapter(&pcf_isa_ops);
|
||||
|
||||
|
@ -298,8 +298,6 @@ static int elektor_remove(struct device *dev, unsigned int id)
|
|||
iounmap(base_iomem);
|
||||
release_mem_region(base, 2);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct isa_driver i2c_elektor_driver = {
|
||||
|
|
|
@ -161,7 +161,7 @@ static int pca_isa_probe(struct device *dev, unsigned int id)
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
static int pca_isa_remove(struct device *dev, unsigned int id)
|
||||
static void pca_isa_remove(struct device *dev, unsigned int id)
|
||||
{
|
||||
i2c_del_adapter(&pca_isa_ops);
|
||||
|
||||
|
@ -170,8 +170,6 @@ static int pca_isa_remove(struct device *dev, unsigned int id)
|
|||
free_irq(irq, &pca_isa_ops);
|
||||
}
|
||||
release_region(base, IO_SIZE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct isa_driver pca_isa_driver = {
|
||||
|
|
|
@ -171,7 +171,7 @@ static int htcpen_isa_probe(struct device *dev, unsigned int id)
|
|||
return err;
|
||||
}
|
||||
|
||||
static int htcpen_isa_remove(struct device *dev, unsigned int id)
|
||||
static void htcpen_isa_remove(struct device *dev, unsigned int id)
|
||||
{
|
||||
struct input_dev *htcpen_dev = dev_get_drvdata(dev);
|
||||
|
||||
|
@ -182,8 +182,6 @@ static int htcpen_isa_remove(struct device *dev, unsigned int id)
|
|||
release_region(HTCPEN_PORT_INDEX, 2);
|
||||
release_region(HTCPEN_PORT_INIT, 1);
|
||||
release_region(HTCPEN_PORT_IRQ_CLEAR, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
|
|
@ -273,8 +273,8 @@ err_dev_reg:
|
|||
return res;
|
||||
}
|
||||
|
||||
static int radio_isa_common_remove(struct radio_isa_card *isa,
|
||||
unsigned region_size)
|
||||
static void radio_isa_common_remove(struct radio_isa_card *isa,
|
||||
unsigned region_size)
|
||||
{
|
||||
const struct radio_isa_ops *ops = isa->drv->ops;
|
||||
|
||||
|
@ -285,7 +285,6 @@ static int radio_isa_common_remove(struct radio_isa_card *isa,
|
|||
release_region(isa->io, region_size);
|
||||
v4l2_info(&isa->v4l2_dev, "Removed radio card %s\n", isa->drv->card);
|
||||
kfree(isa);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int radio_isa_probe(struct device *pdev, unsigned int dev)
|
||||
|
@ -338,11 +337,11 @@ int radio_isa_probe(struct device *pdev, unsigned int dev)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(radio_isa_probe);
|
||||
|
||||
int radio_isa_remove(struct device *pdev, unsigned int dev)
|
||||
void radio_isa_remove(struct device *pdev, unsigned int dev)
|
||||
{
|
||||
struct radio_isa_card *isa = dev_get_drvdata(pdev);
|
||||
|
||||
return radio_isa_common_remove(isa, isa->drv->region_size);
|
||||
radio_isa_common_remove(isa, isa->drv->region_size);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(radio_isa_remove);
|
||||
|
||||
|
|
|
@ -91,7 +91,7 @@ struct radio_isa_driver {
|
|||
|
||||
int radio_isa_match(struct device *pdev, unsigned int dev);
|
||||
int radio_isa_probe(struct device *pdev, unsigned int dev);
|
||||
int radio_isa_remove(struct device *pdev, unsigned int dev);
|
||||
void radio_isa_remove(struct device *pdev, unsigned int dev);
|
||||
#ifdef CONFIG_PNP
|
||||
int radio_isa_pnp_probe(struct pnp_dev *dev,
|
||||
const struct pnp_device_id *dev_id);
|
||||
|
|
|
@ -293,11 +293,9 @@ static void fmr2_remove(struct fmr2 *fmr2)
|
|||
kfree(fmr2);
|
||||
}
|
||||
|
||||
static int fmr2_isa_remove(struct device *pdev, unsigned int ndev)
|
||||
static void fmr2_isa_remove(struct device *pdev, unsigned int ndev)
|
||||
{
|
||||
fmr2_remove(dev_get_drvdata(pdev));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void fmr2_pnp_remove(struct pnp_dev *pdev)
|
||||
|
|
|
@ -797,17 +797,6 @@ const struct dev_pm_ops arizona_pm_ops = {
|
|||
EXPORT_SYMBOL_GPL(arizona_pm_ops);
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
unsigned long arizona_of_get_type(struct device *dev)
|
||||
{
|
||||
const struct of_device_id *id = of_match_device(arizona_of_match, dev);
|
||||
|
||||
if (id)
|
||||
return (unsigned long)id->data;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(arizona_of_get_type);
|
||||
|
||||
static int arizona_of_get_core_pdata(struct arizona *arizona)
|
||||
{
|
||||
struct arizona_pdata *pdata = &arizona->pdata;
|
||||
|
|
|
@ -23,14 +23,16 @@
|
|||
static int arizona_i2c_probe(struct i2c_client *i2c,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
const void *match_data;
|
||||
struct arizona *arizona;
|
||||
const struct regmap_config *regmap_config = NULL;
|
||||
unsigned long type;
|
||||
unsigned long type = 0;
|
||||
int ret;
|
||||
|
||||
if (i2c->dev.of_node)
|
||||
type = arizona_of_get_type(&i2c->dev);
|
||||
else
|
||||
match_data = device_get_match_data(&i2c->dev);
|
||||
if (match_data)
|
||||
type = (unsigned long)match_data;
|
||||
else if (id)
|
||||
type = id->driver_data;
|
||||
|
||||
switch (type) {
|
||||
|
@ -115,6 +117,7 @@ static struct i2c_driver arizona_i2c_driver = {
|
|||
|
||||
module_i2c_driver(arizona_i2c_driver);
|
||||
|
||||
MODULE_SOFTDEP("pre: arizona_ldo1");
|
||||
MODULE_DESCRIPTION("Arizona I2C bus interface");
|
||||
MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
@ -7,7 +7,10 @@
|
|||
* Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/gpio/machine.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/regmap.h>
|
||||
|
@ -15,22 +18,141 @@
|
|||
#include <linux/slab.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/of.h>
|
||||
#include <uapi/linux/input-event-codes.h>
|
||||
|
||||
#include <linux/mfd/arizona/core.h>
|
||||
|
||||
#include "arizona.h"
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
const struct acpi_gpio_params reset_gpios = { 1, 0, false };
|
||||
const struct acpi_gpio_params ldoena_gpios = { 2, 0, false };
|
||||
|
||||
static const struct acpi_gpio_mapping arizona_acpi_gpios[] = {
|
||||
{ "reset-gpios", &reset_gpios, 1, },
|
||||
{ "wlf,ldoena-gpios", &ldoena_gpios, 1 },
|
||||
{ }
|
||||
};
|
||||
|
||||
/*
|
||||
* The ACPI resources for the device only describe external GPIO-s. They do
|
||||
* not provide mappings for the GPIO-s coming from the Arizona codec itself.
|
||||
*/
|
||||
static const struct gpiod_lookup arizona_soc_gpios[] = {
|
||||
{ "arizona", 2, "wlf,spkvdd-ena", 0, GPIO_ACTIVE_HIGH },
|
||||
{ "arizona", 4, "wlf,micd-pol", 0, GPIO_ACTIVE_LOW },
|
||||
};
|
||||
|
||||
/*
|
||||
* The AOSP 3.5 mm Headset: Accessory Specification gives the following values:
|
||||
* Function A Play/Pause: 0 ohm
|
||||
* Function D Voice assistant: 135 ohm
|
||||
* Function B Volume Up 240 ohm
|
||||
* Function C Volume Down 470 ohm
|
||||
* Minimum Mic DC resistance 1000 ohm
|
||||
* Minimum Ear speaker impedance 16 ohm
|
||||
* Note the first max value below must be less then the min. speaker impedance,
|
||||
* to allow CTIA/OMTP detection to work. The other max values are the closest
|
||||
* value from extcon-arizona.c:arizona_micd_levels halfway 2 button resistances.
|
||||
*/
|
||||
static const struct arizona_micd_range arizona_micd_aosp_ranges[] = {
|
||||
{ .max = 11, .key = KEY_PLAYPAUSE },
|
||||
{ .max = 186, .key = KEY_VOICECOMMAND },
|
||||
{ .max = 348, .key = KEY_VOLUMEUP },
|
||||
{ .max = 752, .key = KEY_VOLUMEDOWN },
|
||||
};
|
||||
|
||||
static void arizona_spi_acpi_remove_lookup(void *lookup)
|
||||
{
|
||||
gpiod_remove_lookup_table(lookup);
|
||||
}
|
||||
|
||||
static int arizona_spi_acpi_probe(struct arizona *arizona)
|
||||
{
|
||||
struct gpiod_lookup_table *lookup;
|
||||
acpi_status status;
|
||||
int ret;
|
||||
|
||||
/* Add mappings for the 2 ACPI declared GPIOs used for reset and ldo-ena */
|
||||
devm_acpi_dev_add_driver_gpios(arizona->dev, arizona_acpi_gpios);
|
||||
|
||||
/* Add lookups for the SoCs own GPIOs used for micdet-polarity and spkVDD-enable */
|
||||
lookup = devm_kzalloc(arizona->dev,
|
||||
struct_size(lookup, table, ARRAY_SIZE(arizona_soc_gpios) + 1),
|
||||
GFP_KERNEL);
|
||||
if (!lookup)
|
||||
return -ENOMEM;
|
||||
|
||||
lookup->dev_id = dev_name(arizona->dev);
|
||||
memcpy(lookup->table, arizona_soc_gpios, sizeof(arizona_soc_gpios));
|
||||
|
||||
gpiod_add_lookup_table(lookup);
|
||||
ret = devm_add_action_or_reset(arizona->dev, arizona_spi_acpi_remove_lookup, lookup);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Enable 32KHz clock from SoC to codec for jack-detect */
|
||||
status = acpi_evaluate_object(ACPI_HANDLE(arizona->dev), "CLKE", NULL, NULL);
|
||||
if (ACPI_FAILURE(status))
|
||||
dev_warn(arizona->dev, "Failed to enable 32KHz clk ACPI error %d\n", status);
|
||||
|
||||
/*
|
||||
* Some DSDTs wrongly declare the IRQ trigger-type as IRQF_TRIGGER_FALLING
|
||||
* The IRQ line will stay low when a new IRQ event happens between reading
|
||||
* the IRQ status flags and acknowledging them. When the IRQ line stays
|
||||
* low like this the IRQ will never trigger again when its type is set
|
||||
* to IRQF_TRIGGER_FALLING. Correct the IRQ trigger-type to fix this.
|
||||
*
|
||||
* Note theoretically it is possible that some boards are not capable
|
||||
* of handling active low level interrupts. In that case setting the
|
||||
* flag to IRQF_TRIGGER_FALLING would not be a bug (and we would need
|
||||
* to work around this) but so far all known usages of IRQF_TRIGGER_FALLING
|
||||
* are a bug in the board's DSDT.
|
||||
*/
|
||||
arizona->pdata.irq_flags = IRQF_TRIGGER_LOW;
|
||||
|
||||
/* Wait 200 ms after jack insertion */
|
||||
arizona->pdata.micd_detect_debounce = 200;
|
||||
|
||||
/* Use standard AOSP values for headset-button mappings */
|
||||
arizona->pdata.micd_ranges = arizona_micd_aosp_ranges;
|
||||
arizona->pdata.num_micd_ranges = ARRAY_SIZE(arizona_micd_aosp_ranges);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct acpi_device_id arizona_acpi_match[] = {
|
||||
{
|
||||
.id = "WM510204",
|
||||
.driver_data = WM5102,
|
||||
},
|
||||
{
|
||||
.id = "WM510205",
|
||||
.driver_data = WM5102,
|
||||
},
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, arizona_acpi_match);
|
||||
#else
|
||||
static int arizona_spi_acpi_probe(struct arizona *arizona)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int arizona_spi_probe(struct spi_device *spi)
|
||||
{
|
||||
const struct spi_device_id *id = spi_get_device_id(spi);
|
||||
const void *match_data;
|
||||
struct arizona *arizona;
|
||||
const struct regmap_config *regmap_config = NULL;
|
||||
unsigned long type;
|
||||
unsigned long type = 0;
|
||||
int ret;
|
||||
|
||||
if (spi->dev.of_node)
|
||||
type = arizona_of_get_type(&spi->dev);
|
||||
else
|
||||
match_data = device_get_match_data(&spi->dev);
|
||||
if (match_data)
|
||||
type = (unsigned long)match_data;
|
||||
else if (id)
|
||||
type = id->driver_data;
|
||||
|
||||
switch (type) {
|
||||
|
@ -75,6 +197,12 @@ static int arizona_spi_probe(struct spi_device *spi)
|
|||
arizona->dev = &spi->dev;
|
||||
arizona->irq = spi->irq;
|
||||
|
||||
if (has_acpi_companion(&spi->dev)) {
|
||||
ret = arizona_spi_acpi_probe(arizona);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return arizona_dev_init(arizona);
|
||||
}
|
||||
|
||||
|
@ -102,6 +230,7 @@ static struct spi_driver arizona_spi_driver = {
|
|||
.name = "arizona",
|
||||
.pm = &arizona_pm_ops,
|
||||
.of_match_table = of_match_ptr(arizona_of_match),
|
||||
.acpi_match_table = ACPI_PTR(arizona_acpi_match),
|
||||
},
|
||||
.probe = arizona_spi_probe,
|
||||
.remove = arizona_spi_remove,
|
||||
|
@ -110,6 +239,7 @@ static struct spi_driver arizona_spi_driver = {
|
|||
|
||||
module_spi_driver(arizona_spi_driver);
|
||||
|
||||
MODULE_SOFTDEP("pre: arizona_ldo1");
|
||||
MODULE_DESCRIPTION("Arizona SPI bus interface");
|
||||
MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
@ -50,13 +50,4 @@ int arizona_dev_exit(struct arizona *arizona);
|
|||
int arizona_irq_init(struct arizona *arizona);
|
||||
int arizona_irq_exit(struct arizona *arizona);
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
unsigned long arizona_of_get_type(struct device *dev);
|
||||
#else
|
||||
static inline unsigned long arizona_of_get_type(struct device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -159,7 +159,7 @@ static int tscan1_probe(struct device *dev, unsigned id)
|
|||
return -ENXIO;
|
||||
}
|
||||
|
||||
static int tscan1_remove(struct device *dev, unsigned id /*unused*/)
|
||||
static void tscan1_remove(struct device *dev, unsigned id /*unused*/)
|
||||
{
|
||||
struct net_device *netdev;
|
||||
struct sja1000_priv *priv;
|
||||
|
@ -179,8 +179,6 @@ static int tscan1_remove(struct device *dev, unsigned id /*unused*/)
|
|||
release_region(pld_base, TSCAN1_PLD_SIZE);
|
||||
|
||||
free_sja1000dev(netdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct isa_driver tscan1_isa_driver = {
|
||||
|
|
|
@ -335,12 +335,11 @@ static int el3_isa_match(struct device *pdev, unsigned int ndev)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int el3_isa_remove(struct device *pdev,
|
||||
static void el3_isa_remove(struct device *pdev,
|
||||
unsigned int ndev)
|
||||
{
|
||||
el3_device_remove(pdev);
|
||||
dev_set_drvdata(pdev, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
|
|
@ -11459,12 +11459,11 @@ static int advansys_isa_probe(struct device *dev, unsigned int id)
|
|||
return err;
|
||||
}
|
||||
|
||||
static int advansys_isa_remove(struct device *dev, unsigned int id)
|
||||
static void advansys_isa_remove(struct device *dev, unsigned int id)
|
||||
{
|
||||
int ioport = _asc_def_iop_base[id];
|
||||
advansys_release(dev_get_drvdata(dev));
|
||||
release_region(ioport, ASC_IOADR_GAP);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct isa_driver advansys_isa_driver = {
|
||||
|
|
|
@ -1025,12 +1025,11 @@ static int aha1542_isa_match(struct device *pdev, unsigned int ndev)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int aha1542_isa_remove(struct device *pdev,
|
||||
static void aha1542_isa_remove(struct device *pdev,
|
||||
unsigned int ndev)
|
||||
{
|
||||
aha1542_release(dev_get_drvdata(pdev));
|
||||
dev_set_drvdata(pdev, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct isa_driver aha1542_isa_driver = {
|
||||
|
|
|
@ -175,7 +175,7 @@ static int fdomain_isa_param_match(struct device *dev, unsigned int ndev)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int fdomain_isa_remove(struct device *dev, unsigned int ndev)
|
||||
static void fdomain_isa_remove(struct device *dev, unsigned int ndev)
|
||||
{
|
||||
struct Scsi_Host *sh = dev_get_drvdata(dev);
|
||||
int base = sh->io_port;
|
||||
|
@ -183,7 +183,6 @@ static int fdomain_isa_remove(struct device *dev, unsigned int ndev)
|
|||
fdomain_destroy(sh);
|
||||
release_region(base, FDOMAIN_REGION_SIZE);
|
||||
dev_set_drvdata(dev, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct isa_driver fdomain_isa_driver = {
|
||||
|
|
|
@ -720,12 +720,11 @@ static int generic_NCR5380_isa_match(struct device *pdev, unsigned int ndev)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int generic_NCR5380_isa_remove(struct device *pdev,
|
||||
unsigned int ndev)
|
||||
static void generic_NCR5380_isa_remove(struct device *pdev,
|
||||
unsigned int ndev)
|
||||
{
|
||||
generic_NCR5380_release_resources(dev_get_drvdata(pdev));
|
||||
dev_set_drvdata(pdev, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct isa_driver generic_NCR5380_isa_driver = {
|
||||
|
|
|
@ -951,14 +951,11 @@ error_request_region:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int pcwd_isa_remove(struct device *dev, unsigned int id)
|
||||
static void pcwd_isa_remove(struct device *dev, unsigned int id)
|
||||
{
|
||||
if (debug >= DEBUG)
|
||||
pr_debug("pcwd_isa_remove id=%d\n", id);
|
||||
|
||||
if (!pcwd_private.io_addr)
|
||||
return 1;
|
||||
|
||||
/* Disable the board */
|
||||
if (!nowayout)
|
||||
pcwd_stop();
|
||||
|
@ -971,8 +968,6 @@ static int pcwd_isa_remove(struct device *dev, unsigned int id)
|
|||
(pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4);
|
||||
pcwd_private.io_addr = 0x0000;
|
||||
cards_found--;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pcwd_isa_shutdown(struct device *dev, unsigned int id)
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
struct isa_driver {
|
||||
int (*match)(struct device *, unsigned int);
|
||||
int (*probe)(struct device *, unsigned int);
|
||||
int (*remove)(struct device *, unsigned int);
|
||||
void (*remove)(struct device *, unsigned int);
|
||||
void (*shutdown)(struct device *, unsigned int);
|
||||
int (*suspend)(struct device *, unsigned int, pm_message_t);
|
||||
int (*resume)(struct device *, unsigned int);
|
||||
|
|
|
@ -4610,6 +4610,7 @@ enum ec_codec_i2s_rx_subcmd {
|
|||
EC_CODEC_I2S_RX_SET_SAMPLE_DEPTH = 0x2,
|
||||
EC_CODEC_I2S_RX_SET_DAIFMT = 0x3,
|
||||
EC_CODEC_I2S_RX_SET_BCLK = 0x4,
|
||||
EC_CODEC_I2S_RX_RESET = 0x5,
|
||||
EC_CODEC_I2S_RX_SUBCMD_COUNT,
|
||||
};
|
||||
|
||||
|
|
|
@ -122,6 +122,9 @@ struct snd_card {
|
|||
|
||||
size_t total_pcm_alloc_bytes; /* total amount of allocated buffers */
|
||||
struct mutex memory_mutex; /* protection for the above */
|
||||
#ifdef CONFIG_SND_DEBUG
|
||||
struct dentry *debugfs_root; /* debugfs root for card */
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
unsigned int power_state; /* power state */
|
||||
|
@ -180,6 +183,9 @@ static inline struct device *snd_card_get_device_link(struct snd_card *card)
|
|||
extern int snd_major;
|
||||
extern int snd_ecards_limit;
|
||||
extern struct class *sound_class;
|
||||
#ifdef CONFIG_SND_DEBUG
|
||||
extern struct dentry *sound_debugfs_root;
|
||||
#endif
|
||||
|
||||
void snd_request_card(int card);
|
||||
|
||||
|
|
|
@ -66,6 +66,9 @@ struct dma_chan *snd_dmaengine_pcm_get_chan(struct snd_pcm_substream *substream)
|
|||
* @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
|
||||
* @peripheral_config: peripheral configuration for programming peripheral
|
||||
* for dmaengine transfer
|
||||
* @peripheral_size: peripheral configuration buffer size
|
||||
*/
|
||||
struct snd_dmaengine_dai_dma_data {
|
||||
dma_addr_t addr;
|
||||
|
@ -76,6 +79,8 @@ struct snd_dmaengine_dai_dma_data {
|
|||
const char *chan_name;
|
||||
unsigned int fifo_size;
|
||||
unsigned int flags;
|
||||
void *peripheral_config;
|
||||
size_t peripheral_size;
|
||||
};
|
||||
|
||||
void snd_dmaengine_pcm_set_config_from_dai_data(
|
||||
|
|
|
@ -9,8 +9,10 @@
|
|||
|
||||
#include <sound/simple_card_utils.h>
|
||||
|
||||
int graph_card_probe(struct snd_soc_card *card);
|
||||
int audio_graph_card_probe(struct snd_soc_card *card);
|
||||
|
||||
int graph_parse_of(struct asoc_simple_priv *priv, struct device *dev);
|
||||
int audio_graph_parse_of(struct asoc_simple_priv *priv, struct device *dev);
|
||||
|
||||
int audio_graph_remove(struct platform_device *pdev);
|
||||
|
||||
#endif /* __GRAPH_CARD_H */
|
||||
|
|
|
@ -241,6 +241,8 @@ struct hdac_bus_ops {
|
|||
/* get a response from the last command */
|
||||
int (*get_response)(struct hdac_bus *bus, unsigned int addr,
|
||||
unsigned int *res);
|
||||
/* notify of codec link power-up/down */
|
||||
void (*link_power)(struct hdac_device *hdev, bool enable);
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -378,15 +380,8 @@ void snd_hdac_bus_exit(struct hdac_bus *bus);
|
|||
int snd_hdac_bus_exec_verb_unlocked(struct hdac_bus *bus, unsigned int addr,
|
||||
unsigned int cmd, unsigned int *res);
|
||||
|
||||
static inline void snd_hdac_codec_link_up(struct hdac_device *codec)
|
||||
{
|
||||
set_bit(codec->addr, &codec->bus->codec_powered);
|
||||
}
|
||||
|
||||
static inline void snd_hdac_codec_link_down(struct hdac_device *codec)
|
||||
{
|
||||
clear_bit(codec->addr, &codec->bus->codec_powered);
|
||||
}
|
||||
void snd_hdac_codec_link_up(struct hdac_device *codec);
|
||||
void snd_hdac_codec_link_down(struct hdac_device *codec);
|
||||
|
||||
int snd_hdac_bus_send_cmd(struct hdac_bus *bus, unsigned int val);
|
||||
int snd_hdac_bus_get_response(struct hdac_bus *bus, unsigned int addr,
|
||||
|
@ -400,6 +395,7 @@ void snd_hdac_bus_stop_cmd_io(struct hdac_bus *bus);
|
|||
void snd_hdac_bus_enter_link_reset(struct hdac_bus *bus);
|
||||
void snd_hdac_bus_exit_link_reset(struct hdac_bus *bus);
|
||||
int snd_hdac_bus_reset_link(struct hdac_bus *bus, bool full_reset);
|
||||
void snd_hdac_bus_link_power(struct hdac_device *hdev, bool enable);
|
||||
|
||||
void snd_hdac_bus_update_rirb(struct hdac_bus *bus);
|
||||
int snd_hdac_bus_handle_stream_irq(struct hdac_bus *bus, unsigned int status,
|
||||
|
|
|
@ -131,6 +131,8 @@ void snd_hdac_ext_link_clear_stream_id(struct hdac_ext_link *link,
|
|||
int snd_hdac_ext_bus_link_get(struct hdac_bus *bus, struct hdac_ext_link *link);
|
||||
int snd_hdac_ext_bus_link_put(struct hdac_bus *bus, struct hdac_ext_link *link);
|
||||
|
||||
void snd_hdac_ext_bus_link_power(struct hdac_device *codec, bool enable);
|
||||
|
||||
/* update register macro */
|
||||
#define snd_hdac_updatel(addr, reg, mask, val) \
|
||||
writel(((readl(addr + reg) & ~(mask)) | (val)), \
|
||||
|
|
|
@ -34,6 +34,11 @@ struct hdmi_codec_daifmt {
|
|||
unsigned int frame_clk_inv:1;
|
||||
unsigned int bit_clk_master:1;
|
||||
unsigned int frame_clk_master:1;
|
||||
/* bit_fmt could be standard PCM format or
|
||||
* IEC958 encoded format. ALSA IEC958 plugin will pass
|
||||
* IEC958_SUBFRAME format to the underneath driver.
|
||||
*/
|
||||
snd_pcm_format_t bit_fmt;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -67,6 +67,7 @@ struct snd_jack {
|
|||
char name[100];
|
||||
unsigned int key[6]; /* Keep in sync with definitions above */
|
||||
#endif /* CONFIG_SND_JACK_INPUT_DEV */
|
||||
int hw_status_cache;
|
||||
void *private_data;
|
||||
void (*private_free)(struct snd_jack *);
|
||||
};
|
||||
|
|
|
@ -22,6 +22,8 @@ struct rt5645_platform_data {
|
|||
bool level_trigger_irq;
|
||||
/* Invert JD1_1 status polarity */
|
||||
bool inv_jd1_1;
|
||||
/* Invert HP detect status polarity */
|
||||
bool inv_hp_pol;
|
||||
|
||||
/* Value to asign to snd_soc_card.long_name */
|
||||
const char *long_name;
|
||||
|
|
|
@ -353,6 +353,12 @@ int snd_soc_component_test_bits(struct snd_soc_component *component,
|
|||
unsigned int reg, unsigned int mask,
|
||||
unsigned int value);
|
||||
|
||||
unsigned int snd_soc_component_read_field(struct snd_soc_component *component,
|
||||
unsigned int reg, unsigned int mask);
|
||||
int snd_soc_component_write_field(struct snd_soc_component *component,
|
||||
unsigned int reg, unsigned int mask,
|
||||
unsigned int val);
|
||||
|
||||
/* component wide operations */
|
||||
int snd_soc_component_set_sysclk(struct snd_soc_component *component,
|
||||
int clk_id, int source,
|
||||
|
|
|
@ -353,9 +353,9 @@ struct snd_soc_dai_driver {
|
|||
/* DAI capabilities */
|
||||
struct snd_soc_pcm_stream capture;
|
||||
struct snd_soc_pcm_stream playback;
|
||||
unsigned int symmetric_rates:1;
|
||||
unsigned int symmetric_rate:1;
|
||||
unsigned int symmetric_channels:1;
|
||||
unsigned int symmetric_samplebits:1;
|
||||
unsigned int symmetric_sample_bits:1;
|
||||
|
||||
/* probe ordering - for components with runtime dependencies */
|
||||
int probe_order;
|
||||
|
|
|
@ -685,9 +685,9 @@ struct snd_soc_dai_link {
|
|||
unsigned int ignore_suspend:1;
|
||||
|
||||
/* Symmetry requirements */
|
||||
unsigned int symmetric_rates:1;
|
||||
unsigned int symmetric_rate:1;
|
||||
unsigned int symmetric_channels:1;
|
||||
unsigned int symmetric_samplebits:1;
|
||||
unsigned int symmetric_sample_bits:1;
|
||||
|
||||
/* Do not create a PCM for this DAI link (Backend link) */
|
||||
unsigned int no_pcm:1;
|
||||
|
|
|
@ -58,9 +58,9 @@ struct sof_ext_man_header {
|
|||
/* Extended manifest elements types */
|
||||
enum sof_ext_man_elem_type {
|
||||
SOF_EXT_MAN_ELEM_FW_VERSION = 0,
|
||||
SOF_EXT_MAN_ELEM_WINDOW = SOF_IPC_EXT_WINDOW,
|
||||
SOF_EXT_MAN_ELEM_CC_VERSION = SOF_IPC_EXT_CC_INFO,
|
||||
SOF_EXT_MAN_ELEM_DBG_ABI = SOF_IPC_EXT_USER_ABI_INFO,
|
||||
SOF_EXT_MAN_ELEM_WINDOW = 1,
|
||||
SOF_EXT_MAN_ELEM_CC_VERSION = 2,
|
||||
SOF_EXT_MAN_ELEM_DBG_ABI = 4,
|
||||
SOF_EXT_MAN_ELEM_CONFIG_DATA = 5, /**< ABI3.17 */
|
||||
SOF_EXT_MAN_ELEM_PLATFORM_CONFIG_DATA = 6,
|
||||
};
|
||||
|
|
|
@ -273,7 +273,7 @@ static struct attribute *ac97_controller_device_attrs[] = {
|
|||
NULL
|
||||
};
|
||||
|
||||
static struct attribute_group ac97_adapter_attr_group = {
|
||||
static const struct attribute_group ac97_adapter_attr_group = {
|
||||
.name = "ac97_operations",
|
||||
.attrs = ac97_controller_device_attrs,
|
||||
};
|
||||
|
|
|
@ -1013,7 +1013,7 @@ static int onyx_i2c_probe(struct i2c_client *client,
|
|||
goto fail;
|
||||
}
|
||||
|
||||
strlcpy(onyx->codec.name, "onyx", MAX_CODEC_NAME_LEN);
|
||||
strscpy(onyx->codec.name, "onyx", MAX_CODEC_NAME_LEN);
|
||||
onyx->codec.owner = THIS_MODULE;
|
||||
onyx->codec.init = onyx_init_codec;
|
||||
onyx->codec.exit = onyx_exit_codec;
|
||||
|
|
|
@ -894,7 +894,7 @@ static int tas_i2c_probe(struct i2c_client *client,
|
|||
/* seems that half is a saner default */
|
||||
tas->drc_range = TAS3004_DRC_MAX / 2;
|
||||
|
||||
strlcpy(tas->codec.name, "tas", MAX_CODEC_NAME_LEN);
|
||||
strscpy(tas->codec.name, "tas", MAX_CODEC_NAME_LEN);
|
||||
tas->codec.owner = THIS_MODULE;
|
||||
tas->codec.init = tas_init_codec;
|
||||
tas->codec.exit = tas_exit_codec;
|
||||
|
|
|
@ -126,7 +126,7 @@ static int __init toonie_init(void)
|
|||
if (!toonie)
|
||||
return -ENOMEM;
|
||||
|
||||
strlcpy(toonie->codec.name, "toonie", sizeof(toonie->codec.name));
|
||||
strscpy(toonie->codec.name, "toonie", sizeof(toonie->codec.name));
|
||||
toonie->codec.owner = THIS_MODULE;
|
||||
toonie->codec.init = toonie_init_codec;
|
||||
toonie->codec.exit = toonie_exit_codec;
|
||||
|
|
|
@ -28,10 +28,10 @@ int aoa_alsa_init(char *name, struct module *mod, struct device *dev)
|
|||
return err;
|
||||
aoa_card = alsa_card->private_data;
|
||||
aoa_card->alsa_card = alsa_card;
|
||||
strlcpy(alsa_card->driver, "AppleOnbdAudio", sizeof(alsa_card->driver));
|
||||
strlcpy(alsa_card->shortname, name, sizeof(alsa_card->shortname));
|
||||
strlcpy(alsa_card->longname, name, sizeof(alsa_card->longname));
|
||||
strlcpy(alsa_card->mixername, name, sizeof(alsa_card->mixername));
|
||||
strscpy(alsa_card->driver, "AppleOnbdAudio", sizeof(alsa_card->driver));
|
||||
strscpy(alsa_card->shortname, name, sizeof(alsa_card->shortname));
|
||||
strscpy(alsa_card->longname, name, sizeof(alsa_card->longname));
|
||||
strscpy(alsa_card->mixername, name, sizeof(alsa_card->mixername));
|
||||
err = snd_card_register(aoa_card->alsa_card);
|
||||
if (err < 0) {
|
||||
printk(KERN_ERR "snd-aoa: couldn't register alsa card\n");
|
||||
|
|
|
@ -948,7 +948,7 @@ static void layout_attached_codec(struct aoa_codec *codec)
|
|||
ldev->gpio.methods->set_lineout(codec->gpio, 1);
|
||||
ctl = snd_ctl_new1(&lineout_ctl, codec->gpio);
|
||||
if (cc->connected & CC_LINEOUT_LABELLED_HEADPHONE)
|
||||
strlcpy(ctl->id.name,
|
||||
strscpy(ctl->id.name,
|
||||
"Headphone Switch", sizeof(ctl->id.name));
|
||||
ldev->lineout_ctrl = ctl;
|
||||
aoa_snd_ctl_add(ctl);
|
||||
|
@ -962,14 +962,14 @@ static void layout_attached_codec(struct aoa_codec *codec)
|
|||
ctl = snd_ctl_new1(&lineout_detect_choice,
|
||||
ldev);
|
||||
if (cc->connected & CC_LINEOUT_LABELLED_HEADPHONE)
|
||||
strlcpy(ctl->id.name,
|
||||
strscpy(ctl->id.name,
|
||||
"Headphone Detect Autoswitch",
|
||||
sizeof(ctl->id.name));
|
||||
aoa_snd_ctl_add(ctl);
|
||||
ctl = snd_ctl_new1(&lineout_detected,
|
||||
ldev);
|
||||
if (cc->connected & CC_LINEOUT_LABELLED_HEADPHONE)
|
||||
strlcpy(ctl->id.name,
|
||||
strscpy(ctl->id.name,
|
||||
"Headphone Detected",
|
||||
sizeof(ctl->id.name));
|
||||
ldev->lineout_detected_ctrl = ctl;
|
||||
|
|
|
@ -13,7 +13,7 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
|
|||
int length;
|
||||
|
||||
if (*sdev->modalias) {
|
||||
strlcpy(buf, sdev->modalias, sizeof(sdev->modalias) + 1);
|
||||
strscpy(buf, sdev->modalias, sizeof(sdev->modalias) + 1);
|
||||
strcat(buf, "\n");
|
||||
length = strlen(buf);
|
||||
} else {
|
||||
|
|
|
@ -890,8 +890,8 @@ static struct aaci *aaci_init_card(struct amba_device *dev)
|
|||
|
||||
card->private_free = aaci_free_card;
|
||||
|
||||
strlcpy(card->driver, DRIVER_NAME, sizeof(card->driver));
|
||||
strlcpy(card->shortname, "ARM AC'97 Interface", sizeof(card->shortname));
|
||||
strscpy(card->driver, DRIVER_NAME, sizeof(card->driver));
|
||||
strscpy(card->shortname, "ARM AC'97 Interface", sizeof(card->shortname));
|
||||
snprintf(card->longname, sizeof(card->longname),
|
||||
"%s PL%03x rev%u at 0x%08llx, irq %d",
|
||||
card->shortname, amba_part(dev), amba_rev(dev),
|
||||
|
@ -921,7 +921,7 @@ static int aaci_init_pcm(struct aaci *aaci)
|
|||
pcm->private_data = aaci;
|
||||
pcm->info_flags = 0;
|
||||
|
||||
strlcpy(pcm->name, DRIVER_NAME, sizeof(pcm->name));
|
||||
strscpy(pcm->name, DRIVER_NAME, sizeof(pcm->name));
|
||||
|
||||
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &aaci_playback_ops);
|
||||
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &aaci_capture_ops);
|
||||
|
|
|
@ -235,7 +235,7 @@ static int pxa2xx_ac97_probe(struct platform_device *dev)
|
|||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
strlcpy(card->driver, dev->dev.driver->name, sizeof(card->driver));
|
||||
strscpy(card->driver, dev->dev.driver->name, sizeof(card->driver));
|
||||
|
||||
ret = pxa2xx_ac97_pcm_new(card);
|
||||
if (ret)
|
||||
|
|
|
@ -187,6 +187,15 @@ config SND_CTL_VALIDATION
|
|||
from the driver are in the proper ranges or the check of the invalid
|
||||
access at out-of-array areas.
|
||||
|
||||
config SND_JACK_INJECTION_DEBUG
|
||||
bool "Sound jack injection interface via debugfs"
|
||||
depends on SND_JACK && SND_DEBUG && DEBUG_FS
|
||||
help
|
||||
This option can be used to enable or disable sound jack
|
||||
software injection.
|
||||
Say Y if you are debugging via jack injection interface.
|
||||
If unsure select "N".
|
||||
|
||||
config SND_VMASTER
|
||||
bool
|
||||
|
||||
|
|
|
@ -1132,7 +1132,7 @@ static void snd_compress_proc_done(struct snd_compr *compr)
|
|||
|
||||
static inline void snd_compress_set_id(struct snd_compr *compr, const char *id)
|
||||
{
|
||||
strlcpy(compr->id, id, sizeof(compr->id));
|
||||
strscpy(compr->id, id, sizeof(compr->id));
|
||||
}
|
||||
#else
|
||||
static inline int snd_compress_proc_init(struct snd_compr *compr)
|
||||
|
|
|
@ -261,7 +261,7 @@ struct snd_kcontrol *snd_ctl_new1(const struct snd_kcontrol_new *ncontrol,
|
|||
kctl->id.device = ncontrol->device;
|
||||
kctl->id.subdevice = ncontrol->subdevice;
|
||||
if (ncontrol->name) {
|
||||
strlcpy(kctl->id.name, ncontrol->name, sizeof(kctl->id.name));
|
||||
strscpy(kctl->id.name, ncontrol->name, sizeof(kctl->id.name));
|
||||
if (strcmp(ncontrol->name, kctl->id.name) != 0)
|
||||
pr_warn("ALSA: Control name '%s' truncated to '%s'\n",
|
||||
ncontrol->name, kctl->id.name);
|
||||
|
@ -701,12 +701,12 @@ static int snd_ctl_card_info(struct snd_card *card, struct snd_ctl_file * ctl,
|
|||
return -ENOMEM;
|
||||
down_read(&snd_ioctl_rwsem);
|
||||
info->card = card->number;
|
||||
strlcpy(info->id, card->id, sizeof(info->id));
|
||||
strlcpy(info->driver, card->driver, sizeof(info->driver));
|
||||
strlcpy(info->name, card->shortname, sizeof(info->name));
|
||||
strlcpy(info->longname, card->longname, sizeof(info->longname));
|
||||
strlcpy(info->mixername, card->mixername, sizeof(info->mixername));
|
||||
strlcpy(info->components, card->components, sizeof(info->components));
|
||||
strscpy(info->id, card->id, sizeof(info->id));
|
||||
strscpy(info->driver, card->driver, sizeof(info->driver));
|
||||
strscpy(info->name, card->shortname, sizeof(info->name));
|
||||
strscpy(info->longname, card->longname, sizeof(info->longname));
|
||||
strscpy(info->mixername, card->mixername, sizeof(info->mixername));
|
||||
strscpy(info->components, card->components, sizeof(info->components));
|
||||
up_read(&snd_ioctl_rwsem);
|
||||
if (copy_to_user(arg, info, sizeof(struct snd_ctl_card_info))) {
|
||||
kfree(info);
|
||||
|
@ -836,7 +836,7 @@ static void fill_remaining_elem_value(struct snd_ctl_elem_value *control,
|
|||
{
|
||||
size_t offset = value_sizes[info->type] * info->count;
|
||||
|
||||
offset = (offset + sizeof(u32) - 1) / sizeof(u32);
|
||||
offset = DIV_ROUND_UP(offset, sizeof(u32));
|
||||
memset32((u32 *)control->value.bytes.data + offset, pattern,
|
||||
sizeof(control->value) / sizeof(u32) - offset);
|
||||
}
|
||||
|
@ -928,7 +928,7 @@ static int sanity_check_elem_value(struct snd_card *card,
|
|||
|
||||
/* check whether the remaining area kept untouched */
|
||||
offset = value_sizes[info->type] * info->count;
|
||||
offset = (offset + sizeof(u32) - 1) / sizeof(u32);
|
||||
offset = DIV_ROUND_UP(offset, sizeof(u32));
|
||||
p = (u32 *)control->value.bytes.data + offset;
|
||||
for (; offset < sizeof(control->value) / sizeof(u32); offset++, p++) {
|
||||
if (*p != pattern) {
|
||||
|
@ -2137,7 +2137,7 @@ int snd_ctl_enum_info(struct snd_ctl_elem_info *info, unsigned int channels,
|
|||
WARN(strlen(names[info->value.enumerated.item]) >= sizeof(info->value.enumerated.name),
|
||||
"ALSA: too long item name '%s'\n",
|
||||
names[info->value.enumerated.item]);
|
||||
strlcpy(info->value.enumerated.name,
|
||||
strscpy(info->value.enumerated.name,
|
||||
names[info->value.enumerated.item],
|
||||
sizeof(info->value.enumerated.name));
|
||||
return 0;
|
||||
|
|
|
@ -35,7 +35,7 @@ static int get_available_index(struct snd_card *card, const char *name)
|
|||
|
||||
sid.index = 0;
|
||||
sid.iface = SNDRV_CTL_ELEM_IFACE_CARD;
|
||||
strlcpy(sid.name, name, sizeof(sid.name));
|
||||
strscpy(sid.name, name, sizeof(sid.name));
|
||||
|
||||
while (snd_ctl_find_id(card, &sid)) {
|
||||
sid.index++;
|
||||
|
|
|
@ -177,8 +177,8 @@ static int snd_hwdep_info(struct snd_hwdep *hw,
|
|||
|
||||
memset(&info, 0, sizeof(info));
|
||||
info.card = hw->card->number;
|
||||
strlcpy(info.id, hw->id, sizeof(info.id));
|
||||
strlcpy(info.name, hw->name, sizeof(info.name));
|
||||
strscpy(info.id, hw->id, sizeof(info.id));
|
||||
strscpy(info.name, hw->name, sizeof(info.name));
|
||||
info.iface = hw->iface;
|
||||
if (copy_to_user(_info, &info, sizeof(info)))
|
||||
return -EFAULT;
|
||||
|
@ -379,7 +379,7 @@ int snd_hwdep_new(struct snd_card *card, char *id, int device,
|
|||
hwdep->card = card;
|
||||
hwdep->device = device;
|
||||
if (id)
|
||||
strlcpy(hwdep->id, id, sizeof(hwdep->id));
|
||||
strscpy(hwdep->id, id, sizeof(hwdep->id));
|
||||
|
||||
snd_device_initialize(&hwdep->dev, card);
|
||||
hwdep->dev.release = release_hwdep_device;
|
||||
|
|
|
@ -13,7 +13,9 @@
|
|||
#include <linux/time.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include <sound/core.h>
|
||||
#include <sound/control.h>
|
||||
|
@ -161,6 +163,9 @@ int snd_card_new(struct device *parent, int idx, const char *xid,
|
|||
{
|
||||
struct snd_card *card;
|
||||
int err;
|
||||
#ifdef CONFIG_SND_DEBUG
|
||||
char name[8];
|
||||
#endif
|
||||
|
||||
if (snd_BUG_ON(!card_ret))
|
||||
return -EINVAL;
|
||||
|
@ -174,7 +179,7 @@ int snd_card_new(struct device *parent, int idx, const char *xid,
|
|||
if (extra_size > 0)
|
||||
card->private_data = (char *)card + sizeof(struct snd_card);
|
||||
if (xid)
|
||||
strlcpy(card->id, xid, sizeof(card->id));
|
||||
strscpy(card->id, xid, sizeof(card->id));
|
||||
err = 0;
|
||||
mutex_lock(&snd_card_mutex);
|
||||
if (idx < 0) /* first check the matching module-name slot */
|
||||
|
@ -244,6 +249,12 @@ int snd_card_new(struct device *parent, int idx, const char *xid,
|
|||
dev_err(parent, "unable to create card info\n");
|
||||
goto __error_ctl;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SND_DEBUG
|
||||
sprintf(name, "card%d", idx);
|
||||
card->debugfs_root = debugfs_create_dir(name, sound_debugfs_root);
|
||||
#endif
|
||||
|
||||
*card_ret = card;
|
||||
return 0;
|
||||
|
||||
|
@ -416,6 +427,9 @@ int snd_card_disconnect(struct snd_card *card)
|
|||
/* notify all devices that we are disconnected */
|
||||
snd_device_disconnect_all(card);
|
||||
|
||||
if (card->sync_irq > 0)
|
||||
synchronize_irq(card->sync_irq);
|
||||
|
||||
snd_info_card_disconnect(card);
|
||||
if (card->registered) {
|
||||
device_del(&card->card_dev);
|
||||
|
@ -477,6 +491,10 @@ static int snd_card_do_free(struct snd_card *card)
|
|||
dev_warn(card->dev, "unable to free card info\n");
|
||||
/* Not fatal error */
|
||||
}
|
||||
#ifdef CONFIG_SND_DEBUG
|
||||
debugfs_remove(card->debugfs_root);
|
||||
card->debugfs_root = NULL;
|
||||
#endif
|
||||
if (card->release_completion)
|
||||
complete(card->release_completion);
|
||||
kfree(card);
|
||||
|
@ -526,6 +544,7 @@ int snd_card_free(struct snd_card *card)
|
|||
return ret;
|
||||
/* wait, until all devices are ready for the free operation */
|
||||
wait_for_completion(&released);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(snd_card_free);
|
||||
|
@ -623,7 +642,7 @@ static void snd_card_set_id_no_lock(struct snd_card *card, const char *src,
|
|||
/* last resort... */
|
||||
dev_err(card->dev, "unable to set card id (%s)\n", id);
|
||||
if (card->proc_root->name)
|
||||
strlcpy(card->id, card->proc_root->name, sizeof(card->id));
|
||||
strscpy(card->id, card->proc_root->name, sizeof(card->id));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -8,6 +8,9 @@
|
|||
#include <linux/input.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <sound/jack.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/control.h>
|
||||
|
@ -16,6 +19,11 @@ struct snd_jack_kctl {
|
|||
struct snd_kcontrol *kctl;
|
||||
struct list_head list; /* list of controls belong to the same jack */
|
||||
unsigned int mask_bits; /* only masked status bits are reported via kctl */
|
||||
struct snd_jack *jack; /* pointer to struct snd_jack */
|
||||
bool sw_inject_enable; /* allow to inject plug event via debugfs */
|
||||
#ifdef CONFIG_SND_JACK_INJECTION_DEBUG
|
||||
struct dentry *jack_debugfs_root; /* jack_kctl debugfs root */
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef CONFIG_SND_JACK_INPUT_DEV
|
||||
|
@ -109,12 +117,291 @@ static int snd_jack_dev_register(struct snd_device *device)
|
|||
}
|
||||
#endif /* CONFIG_SND_JACK_INPUT_DEV */
|
||||
|
||||
#ifdef CONFIG_SND_JACK_INJECTION_DEBUG
|
||||
static void snd_jack_inject_report(struct snd_jack_kctl *jack_kctl, int status)
|
||||
{
|
||||
struct snd_jack *jack;
|
||||
#ifdef CONFIG_SND_JACK_INPUT_DEV
|
||||
int i;
|
||||
#endif
|
||||
if (!jack_kctl)
|
||||
return;
|
||||
|
||||
jack = jack_kctl->jack;
|
||||
|
||||
if (jack_kctl->sw_inject_enable)
|
||||
snd_kctl_jack_report(jack->card, jack_kctl->kctl,
|
||||
status & jack_kctl->mask_bits);
|
||||
|
||||
#ifdef CONFIG_SND_JACK_INPUT_DEV
|
||||
if (!jack->input_dev)
|
||||
return;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(jack->key); i++) {
|
||||
int testbit = ((SND_JACK_BTN_0 >> i) & jack_kctl->mask_bits);
|
||||
|
||||
if (jack->type & testbit)
|
||||
input_report_key(jack->input_dev, jack->key[i],
|
||||
status & testbit);
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(jack_switch_types); i++) {
|
||||
int testbit = ((1 << i) & jack_kctl->mask_bits);
|
||||
|
||||
if (jack->type & testbit)
|
||||
input_report_switch(jack->input_dev,
|
||||
jack_switch_types[i],
|
||||
status & testbit);
|
||||
}
|
||||
|
||||
input_sync(jack->input_dev);
|
||||
#endif /* CONFIG_SND_JACK_INPUT_DEV */
|
||||
}
|
||||
|
||||
static ssize_t sw_inject_enable_read(struct file *file,
|
||||
char __user *to, size_t count, loff_t *ppos)
|
||||
{
|
||||
struct snd_jack_kctl *jack_kctl = file->private_data;
|
||||
int len, ret;
|
||||
char buf[128];
|
||||
|
||||
len = scnprintf(buf, sizeof(buf), "%s: %s\t\t%s: %i\n", "Jack", jack_kctl->kctl->id.name,
|
||||
"Inject Enabled", jack_kctl->sw_inject_enable);
|
||||
ret = simple_read_from_buffer(to, count, ppos, buf, len);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t sw_inject_enable_write(struct file *file,
|
||||
const char __user *from, size_t count, loff_t *ppos)
|
||||
{
|
||||
struct snd_jack_kctl *jack_kctl = file->private_data;
|
||||
int ret, err;
|
||||
unsigned long enable;
|
||||
char buf[8] = { 0 };
|
||||
|
||||
ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, from, count);
|
||||
err = kstrtoul(buf, 0, &enable);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (jack_kctl->sw_inject_enable == (!!enable))
|
||||
return ret;
|
||||
|
||||
jack_kctl->sw_inject_enable = !!enable;
|
||||
|
||||
if (!jack_kctl->sw_inject_enable)
|
||||
snd_jack_report(jack_kctl->jack, jack_kctl->jack->hw_status_cache);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t jackin_inject_write(struct file *file,
|
||||
const char __user *from, size_t count, loff_t *ppos)
|
||||
{
|
||||
struct snd_jack_kctl *jack_kctl = file->private_data;
|
||||
int ret, err;
|
||||
unsigned long enable;
|
||||
char buf[8] = { 0 };
|
||||
|
||||
if (!jack_kctl->sw_inject_enable)
|
||||
return -EINVAL;
|
||||
|
||||
ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, from, count);
|
||||
err = kstrtoul(buf, 0, &enable);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
snd_jack_inject_report(jack_kctl, !!enable ? jack_kctl->mask_bits : 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t jack_kctl_id_read(struct file *file,
|
||||
char __user *to, size_t count, loff_t *ppos)
|
||||
{
|
||||
struct snd_jack_kctl *jack_kctl = file->private_data;
|
||||
char buf[64];
|
||||
int len, ret;
|
||||
|
||||
len = scnprintf(buf, sizeof(buf), "%s\n", jack_kctl->kctl->id.name);
|
||||
ret = simple_read_from_buffer(to, count, ppos, buf, len);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* the bit definition is aligned with snd_jack_types in jack.h */
|
||||
static const char * const jack_events_name[] = {
|
||||
"HEADPHONE(0x0001)", "MICROPHONE(0x0002)", "LINEOUT(0x0004)",
|
||||
"MECHANICAL(0x0008)", "VIDEOOUT(0x0010)", "LINEIN(0x0020)",
|
||||
"", "", "", "BTN_5(0x0200)", "BTN_4(0x0400)", "BTN_3(0x0800)",
|
||||
"BTN_2(0x1000)", "BTN_1(0x2000)", "BTN_0(0x4000)", "",
|
||||
};
|
||||
|
||||
/* the recommended buffer size is 256 */
|
||||
static int parse_mask_bits(unsigned int mask_bits, char *buf, size_t buf_size)
|
||||
{
|
||||
int i;
|
||||
|
||||
scnprintf(buf, buf_size, "0x%04x", mask_bits);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(jack_events_name); i++)
|
||||
if (mask_bits & (1 << i)) {
|
||||
strlcat(buf, " ", buf_size);
|
||||
strlcat(buf, jack_events_name[i], buf_size);
|
||||
}
|
||||
strlcat(buf, "\n", buf_size);
|
||||
|
||||
return strlen(buf);
|
||||
}
|
||||
|
||||
static ssize_t jack_kctl_mask_bits_read(struct file *file,
|
||||
char __user *to, size_t count, loff_t *ppos)
|
||||
{
|
||||
struct snd_jack_kctl *jack_kctl = file->private_data;
|
||||
char buf[256];
|
||||
int len, ret;
|
||||
|
||||
len = parse_mask_bits(jack_kctl->mask_bits, buf, sizeof(buf));
|
||||
ret = simple_read_from_buffer(to, count, ppos, buf, len);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t jack_kctl_status_read(struct file *file,
|
||||
char __user *to, size_t count, loff_t *ppos)
|
||||
{
|
||||
struct snd_jack_kctl *jack_kctl = file->private_data;
|
||||
char buf[16];
|
||||
int len, ret;
|
||||
|
||||
len = scnprintf(buf, sizeof(buf), "%s\n", jack_kctl->kctl->private_value ?
|
||||
"Plugged" : "Unplugged");
|
||||
ret = simple_read_from_buffer(to, count, ppos, buf, len);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SND_JACK_INPUT_DEV
|
||||
static ssize_t jack_type_read(struct file *file,
|
||||
char __user *to, size_t count, loff_t *ppos)
|
||||
{
|
||||
struct snd_jack_kctl *jack_kctl = file->private_data;
|
||||
char buf[256];
|
||||
int len, ret;
|
||||
|
||||
len = parse_mask_bits(jack_kctl->jack->type, buf, sizeof(buf));
|
||||
ret = simple_read_from_buffer(to, count, ppos, buf, len);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct file_operations jack_type_fops = {
|
||||
.open = simple_open,
|
||||
.read = jack_type_read,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
#endif
|
||||
|
||||
static const struct file_operations sw_inject_enable_fops = {
|
||||
.open = simple_open,
|
||||
.read = sw_inject_enable_read,
|
||||
.write = sw_inject_enable_write,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
static const struct file_operations jackin_inject_fops = {
|
||||
.open = simple_open,
|
||||
.write = jackin_inject_write,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
static const struct file_operations jack_kctl_id_fops = {
|
||||
.open = simple_open,
|
||||
.read = jack_kctl_id_read,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
static const struct file_operations jack_kctl_mask_bits_fops = {
|
||||
.open = simple_open,
|
||||
.read = jack_kctl_mask_bits_read,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
static const struct file_operations jack_kctl_status_fops = {
|
||||
.open = simple_open,
|
||||
.read = jack_kctl_status_read,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
static int snd_jack_debugfs_add_inject_node(struct snd_jack *jack,
|
||||
struct snd_jack_kctl *jack_kctl)
|
||||
{
|
||||
char *tname;
|
||||
int i;
|
||||
|
||||
/* Don't create injection interface for Phantom jacks */
|
||||
if (strstr(jack_kctl->kctl->id.name, "Phantom"))
|
||||
return 0;
|
||||
|
||||
tname = kstrdup(jack_kctl->kctl->id.name, GFP_KERNEL);
|
||||
if (!tname)
|
||||
return -ENOMEM;
|
||||
|
||||
/* replace the chars which are not suitable for folder's name with _ */
|
||||
for (i = 0; tname[i]; i++)
|
||||
if (!isalnum(tname[i]))
|
||||
tname[i] = '_';
|
||||
|
||||
jack_kctl->jack_debugfs_root = debugfs_create_dir(tname, jack->card->debugfs_root);
|
||||
kfree(tname);
|
||||
|
||||
debugfs_create_file("sw_inject_enable", 0644, jack_kctl->jack_debugfs_root, jack_kctl,
|
||||
&sw_inject_enable_fops);
|
||||
|
||||
debugfs_create_file("jackin_inject", 0200, jack_kctl->jack_debugfs_root, jack_kctl,
|
||||
&jackin_inject_fops);
|
||||
|
||||
debugfs_create_file("kctl_id", 0444, jack_kctl->jack_debugfs_root, jack_kctl,
|
||||
&jack_kctl_id_fops);
|
||||
|
||||
debugfs_create_file("mask_bits", 0444, jack_kctl->jack_debugfs_root, jack_kctl,
|
||||
&jack_kctl_mask_bits_fops);
|
||||
|
||||
debugfs_create_file("status", 0444, jack_kctl->jack_debugfs_root, jack_kctl,
|
||||
&jack_kctl_status_fops);
|
||||
|
||||
#ifdef CONFIG_SND_JACK_INPUT_DEV
|
||||
debugfs_create_file("type", 0444, jack_kctl->jack_debugfs_root, jack_kctl,
|
||||
&jack_type_fops);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void snd_jack_debugfs_clear_inject_node(struct snd_jack_kctl *jack_kctl)
|
||||
{
|
||||
debugfs_remove(jack_kctl->jack_debugfs_root);
|
||||
jack_kctl->jack_debugfs_root = NULL;
|
||||
}
|
||||
#else /* CONFIG_SND_JACK_INJECTION_DEBUG */
|
||||
static int snd_jack_debugfs_add_inject_node(struct snd_jack *jack,
|
||||
struct snd_jack_kctl *jack_kctl)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void snd_jack_debugfs_clear_inject_node(struct snd_jack_kctl *jack_kctl)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_SND_JACK_INJECTION_DEBUG */
|
||||
|
||||
static void snd_jack_kctl_private_free(struct snd_kcontrol *kctl)
|
||||
{
|
||||
struct snd_jack_kctl *jack_kctl;
|
||||
|
||||
jack_kctl = kctl->private_data;
|
||||
if (jack_kctl) {
|
||||
snd_jack_debugfs_clear_inject_node(jack_kctl);
|
||||
list_del(&jack_kctl->list);
|
||||
kfree(jack_kctl);
|
||||
}
|
||||
|
@ -122,7 +409,9 @@ static void snd_jack_kctl_private_free(struct snd_kcontrol *kctl)
|
|||
|
||||
static void snd_jack_kctl_add(struct snd_jack *jack, struct snd_jack_kctl *jack_kctl)
|
||||
{
|
||||
jack_kctl->jack = jack;
|
||||
list_add_tail(&jack_kctl->list, &jack->kctl_list);
|
||||
snd_jack_debugfs_add_inject_node(jack, jack_kctl);
|
||||
}
|
||||
|
||||
static struct snd_jack_kctl * snd_jack_kctl_new(struct snd_card *card, const char *name, unsigned int mask)
|
||||
|
@ -340,6 +629,7 @@ EXPORT_SYMBOL(snd_jack_set_key);
|
|||
void snd_jack_report(struct snd_jack *jack, int status)
|
||||
{
|
||||
struct snd_jack_kctl *jack_kctl;
|
||||
unsigned int mask_bits = 0;
|
||||
#ifdef CONFIG_SND_JACK_INPUT_DEV
|
||||
int i;
|
||||
#endif
|
||||
|
@ -347,16 +637,21 @@ void snd_jack_report(struct snd_jack *jack, int status)
|
|||
if (!jack)
|
||||
return;
|
||||
|
||||
jack->hw_status_cache = status;
|
||||
|
||||
list_for_each_entry(jack_kctl, &jack->kctl_list, list)
|
||||
snd_kctl_jack_report(jack->card, jack_kctl->kctl,
|
||||
status & jack_kctl->mask_bits);
|
||||
if (jack_kctl->sw_inject_enable)
|
||||
mask_bits |= jack_kctl->mask_bits;
|
||||
else
|
||||
snd_kctl_jack_report(jack->card, jack_kctl->kctl,
|
||||
status & jack_kctl->mask_bits);
|
||||
|
||||
#ifdef CONFIG_SND_JACK_INPUT_DEV
|
||||
if (!jack->input_dev)
|
||||
return;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(jack->key); i++) {
|
||||
int testbit = SND_JACK_BTN_0 >> i;
|
||||
int testbit = ((SND_JACK_BTN_0 >> i) & ~mask_bits);
|
||||
|
||||
if (jack->type & testbit)
|
||||
input_report_key(jack->input_dev, jack->key[i],
|
||||
|
@ -364,7 +659,8 @@ void snd_jack_report(struct snd_jack *jack, int status)
|
|||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(jack_switch_types); i++) {
|
||||
int testbit = 1 << i;
|
||||
int testbit = ((1 << i) & ~mask_bits);
|
||||
|
||||
if (jack->type & testbit)
|
||||
input_report_switch(jack->input_dev,
|
||||
jack_switch_types[i],
|
||||
|
|
|
@ -87,8 +87,8 @@ static int snd_mixer_oss_info(struct snd_mixer_oss_file *fmixer,
|
|||
struct mixer_info info;
|
||||
|
||||
memset(&info, 0, sizeof(info));
|
||||
strlcpy(info.id, mixer && mixer->id[0] ? mixer->id : card->driver, sizeof(info.id));
|
||||
strlcpy(info.name, mixer && mixer->name[0] ? mixer->name : card->mixername, sizeof(info.name));
|
||||
strscpy(info.id, mixer && mixer->id[0] ? mixer->id : card->driver, sizeof(info.id));
|
||||
strscpy(info.name, mixer && mixer->name[0] ? mixer->name : card->mixername, sizeof(info.name));
|
||||
info.modify_counter = card->mixer_oss_change_count;
|
||||
if (copy_to_user(_info, &info, sizeof(info)))
|
||||
return -EFAULT;
|
||||
|
@ -103,8 +103,8 @@ static int snd_mixer_oss_info_obsolete(struct snd_mixer_oss_file *fmixer,
|
|||
_old_mixer_info info;
|
||||
|
||||
memset(&info, 0, sizeof(info));
|
||||
strlcpy(info.id, mixer && mixer->id[0] ? mixer->id : card->driver, sizeof(info.id));
|
||||
strlcpy(info.name, mixer && mixer->name[0] ? mixer->name : card->mixername, sizeof(info.name));
|
||||
strscpy(info.id, mixer && mixer->id[0] ? mixer->id : card->driver, sizeof(info.id));
|
||||
strscpy(info.name, mixer && mixer->name[0] ? mixer->name : card->mixername, sizeof(info.name));
|
||||
if (copy_to_user(_info, &info, sizeof(info)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
|
@ -418,7 +418,7 @@ static long snd_mixer_oss_conv(long val, long omin, long omax, long nmin, long n
|
|||
|
||||
if (orange == 0)
|
||||
return 0;
|
||||
return ((nrange * (val - omin)) + (orange / 2)) / orange + nmin;
|
||||
return DIV_ROUND_CLOSEST(nrange * (val - omin), orange) + nmin;
|
||||
}
|
||||
|
||||
/* convert from alsa native to oss values (0-100) */
|
||||
|
@ -499,7 +499,7 @@ static struct snd_kcontrol *snd_mixer_oss_test_id(struct snd_mixer_oss *mixer, c
|
|||
|
||||
memset(&id, 0, sizeof(id));
|
||||
id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
|
||||
strlcpy(id.name, name, sizeof(id.name));
|
||||
strscpy(id.name, name, sizeof(id.name));
|
||||
id.index = index;
|
||||
return snd_ctl_find_id(card, &id);
|
||||
}
|
||||
|
@ -1355,7 +1355,7 @@ static int snd_mixer_oss_notify_handler(struct snd_card *card, int cmd)
|
|||
mixer->oss_dev_alloc = 1;
|
||||
mixer->card = card;
|
||||
if (*card->mixername)
|
||||
strlcpy(mixer->name, card->mixername, sizeof(mixer->name));
|
||||
strscpy(mixer->name, card->mixername, sizeof(mixer->name));
|
||||
else
|
||||
snprintf(mixer->name, sizeof(mixer->name),
|
||||
"mixer%i", card->number);
|
||||
|
|
|
@ -193,7 +193,7 @@ static snd_pcm_sframes_t rate_src_frames(struct snd_pcm_plugin *plugin, snd_pcm_
|
|||
if (plugin->src_format.rate < plugin->dst_format.rate) {
|
||||
res = (((frames * data->pitch) + (BITS/2)) >> SHIFT);
|
||||
} else {
|
||||
res = (((frames << SHIFT) + (data->pitch / 2)) / data->pitch);
|
||||
res = DIV_ROUND_CLOSEST(frames << SHIFT, data->pitch);
|
||||
}
|
||||
if (data->old_src_frames > 0) {
|
||||
snd_pcm_sframes_t frames1 = frames, res1 = data->old_dst_frames;
|
||||
|
@ -224,7 +224,7 @@ static snd_pcm_sframes_t rate_dst_frames(struct snd_pcm_plugin *plugin, snd_pcm_
|
|||
return 0;
|
||||
data = (struct rate_priv *)plugin->extra_data;
|
||||
if (plugin->src_format.rate < plugin->dst_format.rate) {
|
||||
res = (((frames << SHIFT) + (data->pitch / 2)) / data->pitch);
|
||||
res = DIV_ROUND_CLOSEST(frames << SHIFT, data->pitch);
|
||||
} else {
|
||||
res = (((frames * data->pitch) + (BITS/2)) >> SHIFT);
|
||||
}
|
||||
|
|
|
@ -729,7 +729,7 @@ static int _snd_pcm_new(struct snd_card *card, const char *id, int device,
|
|||
init_waitqueue_head(&pcm->open_wait);
|
||||
INIT_LIST_HEAD(&pcm->list);
|
||||
if (id)
|
||||
strlcpy(pcm->id, id, sizeof(pcm->id));
|
||||
strscpy(pcm->id, id, sizeof(pcm->id));
|
||||
|
||||
err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_PLAYBACK,
|
||||
playback_count);
|
||||
|
@ -1095,22 +1095,23 @@ static int snd_pcm_dev_disconnect(struct snd_device *device)
|
|||
mutex_lock(&pcm->open_mutex);
|
||||
wake_up(&pcm->open_wait);
|
||||
list_del_init(&pcm->list);
|
||||
for (cidx = 0; cidx < 2; cidx++) {
|
||||
for (substream = pcm->streams[cidx].substream; substream; substream = substream->next) {
|
||||
snd_pcm_stream_lock_irq(substream);
|
||||
if (substream->runtime) {
|
||||
if (snd_pcm_running(substream))
|
||||
snd_pcm_stop(substream,
|
||||
SNDRV_PCM_STATE_DISCONNECTED);
|
||||
/* to be sure, set the state unconditionally */
|
||||
substream->runtime->status->state = SNDRV_PCM_STATE_DISCONNECTED;
|
||||
wake_up(&substream->runtime->sleep);
|
||||
wake_up(&substream->runtime->tsleep);
|
||||
}
|
||||
snd_pcm_stream_unlock_irq(substream);
|
||||
|
||||
for_each_pcm_substream(pcm, cidx, substream) {
|
||||
snd_pcm_stream_lock_irq(substream);
|
||||
if (substream->runtime) {
|
||||
if (snd_pcm_running(substream))
|
||||
snd_pcm_stop(substream, SNDRV_PCM_STATE_DISCONNECTED);
|
||||
/* to be sure, set the state unconditionally */
|
||||
substream->runtime->status->state = SNDRV_PCM_STATE_DISCONNECTED;
|
||||
wake_up(&substream->runtime->sleep);
|
||||
wake_up(&substream->runtime->tsleep);
|
||||
}
|
||||
snd_pcm_stream_unlock_irq(substream);
|
||||
}
|
||||
|
||||
for_each_pcm_substream(pcm, cidx, substream)
|
||||
snd_pcm_sync_stop(substream, false);
|
||||
|
||||
pcm_call_notify(pcm, n_disconnect);
|
||||
for (cidx = 0; cidx < 2; cidx++) {
|
||||
snd_unregister_device(&pcm->streams[cidx].dev);
|
||||
|
|
|
@ -125,6 +125,8 @@ void snd_dmaengine_pcm_set_config_from_dai_data(
|
|||
}
|
||||
|
||||
slave_config->slave_id = dma_data->slave_id;
|
||||
slave_config->peripheral_config = dma_data->peripheral_config;
|
||||
slave_config->peripheral_size = dma_data->peripheral_size;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_set_config_from_dai_data);
|
||||
|
||||
|
|
|
@ -63,6 +63,7 @@ static inline void snd_pcm_timer_done(struct snd_pcm_substream *substream) {}
|
|||
|
||||
void __snd_pcm_xrun(struct snd_pcm_substream *substream);
|
||||
void snd_pcm_group_init(struct snd_pcm_group *group);
|
||||
void snd_pcm_sync_stop(struct snd_pcm_substream *substream, bool sync_irq);
|
||||
|
||||
#ifdef CONFIG_SND_DMA_SGBUF
|
||||
struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream,
|
||||
|
@ -71,4 +72,10 @@ struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream,
|
|||
|
||||
#define PCM_RUNTIME_CHECK(sub) snd_BUG_ON(!(sub) || !(sub)->runtime)
|
||||
|
||||
/* loop over all PCM substreams */
|
||||
#define for_each_pcm_substream(pcm, str, subs) \
|
||||
for ((str) = 0; (str) < 2; (str)++) \
|
||||
for ((subs) = (pcm)->streams[str].substream; (subs); \
|
||||
(subs) = (subs)->next)
|
||||
|
||||
#endif /* __SOUND_CORE_PCM_LOCAL_H */
|
||||
|
|
|
@ -111,9 +111,8 @@ void snd_pcm_lib_preallocate_free_for_all(struct snd_pcm *pcm)
|
|||
struct snd_pcm_substream *substream;
|
||||
int stream;
|
||||
|
||||
for (stream = 0; stream < 2; stream++)
|
||||
for (substream = pcm->streams[stream].substream; substream; substream = substream->next)
|
||||
snd_pcm_lib_preallocate_free(substream);
|
||||
for_each_pcm_substream(pcm, stream, substream)
|
||||
snd_pcm_lib_preallocate_free(substream);
|
||||
}
|
||||
EXPORT_SYMBOL(snd_pcm_lib_preallocate_free_for_all);
|
||||
|
||||
|
@ -246,11 +245,8 @@ static void preallocate_pages_for_all(struct snd_pcm *pcm, int type,
|
|||
struct snd_pcm_substream *substream;
|
||||
int stream;
|
||||
|
||||
for (stream = 0; stream < 2; stream++)
|
||||
for (substream = pcm->streams[stream].substream; substream;
|
||||
substream = substream->next)
|
||||
preallocate_pages(substream, type, data, size, max,
|
||||
managed);
|
||||
for_each_pcm_substream(pcm, stream, substream)
|
||||
preallocate_pages(substream, type, data, size, max, managed);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -209,13 +209,13 @@ int snd_pcm_info(struct snd_pcm_substream *substream, struct snd_pcm_info *info)
|
|||
info->device = pcm->device;
|
||||
info->stream = substream->stream;
|
||||
info->subdevice = substream->number;
|
||||
strlcpy(info->id, pcm->id, sizeof(info->id));
|
||||
strlcpy(info->name, pcm->name, sizeof(info->name));
|
||||
strscpy(info->id, pcm->id, sizeof(info->id));
|
||||
strscpy(info->name, pcm->name, sizeof(info->name));
|
||||
info->dev_class = pcm->dev_class;
|
||||
info->dev_subclass = pcm->dev_subclass;
|
||||
info->subdevices_count = pstr->substream_count;
|
||||
info->subdevices_avail = pstr->substream_count - pstr->substream_opened;
|
||||
strlcpy(info->subname, substream->name, sizeof(info->subname));
|
||||
strscpy(info->subname, substream->name, sizeof(info->subname));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -583,13 +583,13 @@ static inline void snd_pcm_timer_notify(struct snd_pcm_substream *substream,
|
|||
#endif
|
||||
}
|
||||
|
||||
static void snd_pcm_sync_stop(struct snd_pcm_substream *substream)
|
||||
void snd_pcm_sync_stop(struct snd_pcm_substream *substream, bool sync_irq)
|
||||
{
|
||||
if (substream->runtime->stop_operating) {
|
||||
if (substream->runtime && substream->runtime->stop_operating) {
|
||||
substream->runtime->stop_operating = false;
|
||||
if (substream->ops->sync_stop)
|
||||
if (substream->ops && substream->ops->sync_stop)
|
||||
substream->ops->sync_stop(substream);
|
||||
else if (substream->pcm->card->sync_irq > 0)
|
||||
else if (sync_irq && substream->pcm->card->sync_irq > 0)
|
||||
synchronize_irq(substream->pcm->card->sync_irq);
|
||||
}
|
||||
}
|
||||
|
@ -686,7 +686,7 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
|
|||
if (atomic_read(&substream->mmap_count))
|
||||
return -EBADFD;
|
||||
|
||||
snd_pcm_sync_stop(substream);
|
||||
snd_pcm_sync_stop(substream, true);
|
||||
|
||||
params->rmask = ~0U;
|
||||
err = snd_pcm_hw_refine(substream, params);
|
||||
|
@ -809,7 +809,7 @@ static int do_hw_free(struct snd_pcm_substream *substream)
|
|||
{
|
||||
int result = 0;
|
||||
|
||||
snd_pcm_sync_stop(substream);
|
||||
snd_pcm_sync_stop(substream, true);
|
||||
if (substream->ops->hw_free)
|
||||
result = substream->ops->hw_free(substream);
|
||||
if (substream->managed_buffer_alloc)
|
||||
|
@ -1421,8 +1421,10 @@ static int snd_pcm_do_stop(struct snd_pcm_substream *substream,
|
|||
snd_pcm_state_t state)
|
||||
{
|
||||
if (substream->runtime->trigger_master == substream &&
|
||||
snd_pcm_running(substream))
|
||||
snd_pcm_running(substream)) {
|
||||
substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_STOP);
|
||||
substream->runtime->stop_operating = true;
|
||||
}
|
||||
return 0; /* unconditonally stop all substreams */
|
||||
}
|
||||
|
||||
|
@ -1435,7 +1437,6 @@ static void snd_pcm_post_stop(struct snd_pcm_substream *substream,
|
|||
runtime->status->state = state;
|
||||
snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MSTOP);
|
||||
}
|
||||
runtime->stop_operating = true;
|
||||
wake_up(&runtime->sleep);
|
||||
wake_up(&runtime->tsleep);
|
||||
}
|
||||
|
@ -1615,6 +1616,7 @@ static int snd_pcm_do_suspend(struct snd_pcm_substream *substream,
|
|||
if (! snd_pcm_running(substream))
|
||||
return 0;
|
||||
substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_SUSPEND);
|
||||
runtime->stop_operating = true;
|
||||
return 0; /* suspend unconditionally */
|
||||
}
|
||||
|
||||
|
@ -1672,25 +1674,26 @@ int snd_pcm_suspend_all(struct snd_pcm *pcm)
|
|||
if (! pcm)
|
||||
return 0;
|
||||
|
||||
for (stream = 0; stream < 2; stream++) {
|
||||
for (substream = pcm->streams[stream].substream;
|
||||
substream; substream = substream->next) {
|
||||
/* FIXME: the open/close code should lock this as well */
|
||||
if (substream->runtime == NULL)
|
||||
continue;
|
||||
for_each_pcm_substream(pcm, stream, substream) {
|
||||
/* FIXME: the open/close code should lock this as well */
|
||||
if (!substream->runtime)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Skip BE dai link PCM's that are internal and may
|
||||
* not have their substream ops set.
|
||||
*/
|
||||
if (!substream->ops)
|
||||
continue;
|
||||
/*
|
||||
* Skip BE dai link PCM's that are internal and may
|
||||
* not have their substream ops set.
|
||||
*/
|
||||
if (!substream->ops)
|
||||
continue;
|
||||
|
||||
err = snd_pcm_suspend(substream);
|
||||
if (err < 0 && err != -EBUSY)
|
||||
return err;
|
||||
}
|
||||
err = snd_pcm_suspend(substream);
|
||||
if (err < 0 && err != -EBUSY)
|
||||
return err;
|
||||
}
|
||||
|
||||
for_each_pcm_substream(pcm, stream, substream)
|
||||
snd_pcm_sync_stop(substream, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(snd_pcm_suspend_all);
|
||||
|
@ -1736,7 +1739,6 @@ static void snd_pcm_post_resume(struct snd_pcm_substream *substream,
|
|||
snd_pcm_trigger_tstamp(substream);
|
||||
runtime->status->state = runtime->status->suspended_state;
|
||||
snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MRESUME);
|
||||
snd_pcm_sync_stop(substream);
|
||||
}
|
||||
|
||||
static const struct action_ops snd_pcm_action_resume = {
|
||||
|
@ -1866,7 +1868,7 @@ static int snd_pcm_do_prepare(struct snd_pcm_substream *substream,
|
|||
snd_pcm_state_t state)
|
||||
{
|
||||
int err;
|
||||
snd_pcm_sync_stop(substream);
|
||||
snd_pcm_sync_stop(substream, true);
|
||||
err = substream->ops->prepare(substream);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
|
|
@ -1686,7 +1686,7 @@ int snd_rawmidi_new(struct snd_card *card, char *id, int device,
|
|||
INIT_LIST_HEAD(&rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams);
|
||||
|
||||
if (id != NULL)
|
||||
strlcpy(rmidi->id, id, sizeof(rmidi->id));
|
||||
strscpy(rmidi->id, id, sizeof(rmidi->id));
|
||||
|
||||
snd_device_initialize(&rmidi->dev, card);
|
||||
rmidi->dev.release = release_rawmidi_device;
|
||||
|
|
|
@ -173,7 +173,7 @@ snd_seq_oss_midi_check_new_port(struct snd_seq_port_info *pinfo)
|
|||
snd_use_lock_init(&mdev->use_lock);
|
||||
|
||||
/* copy and truncate the name of synth device */
|
||||
strlcpy(mdev->name, pinfo->name, sizeof(mdev->name));
|
||||
strscpy(mdev->name, pinfo->name, sizeof(mdev->name));
|
||||
|
||||
/* create MIDI coder */
|
||||
if (snd_midi_event_new(MAX_MIDI_EVENT_BUF, &mdev->coder) < 0) {
|
||||
|
@ -647,7 +647,7 @@ snd_seq_oss_midi_make_info(struct seq_oss_devinfo *dp, int dev, struct midi_info
|
|||
inf->device = dev;
|
||||
inf->dev_type = 0; /* FIXME: ?? */
|
||||
inf->capabilities = 0; /* FIXME: ?? */
|
||||
strlcpy(inf->name, mdev->name, sizeof(inf->name));
|
||||
strscpy(inf->name, mdev->name, sizeof(inf->name));
|
||||
snd_use_lock_free(&mdev->use_lock);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -107,7 +107,7 @@ snd_seq_oss_synth_probe(struct device *_dev)
|
|||
snd_use_lock_init(&rec->use_lock);
|
||||
|
||||
/* copy and truncate the name of synth device */
|
||||
strlcpy(rec->name, dev->name, sizeof(rec->name));
|
||||
strscpy(rec->name, dev->name, sizeof(rec->name));
|
||||
|
||||
/* registration */
|
||||
spin_lock_irqsave(®ister_lock, flags);
|
||||
|
@ -617,7 +617,7 @@ snd_seq_oss_synth_make_info(struct seq_oss_devinfo *dp, int dev, struct synth_in
|
|||
inf->synth_subtype = 0;
|
||||
inf->nr_voices = 16;
|
||||
inf->device = dev;
|
||||
strlcpy(inf->name, minf.name, sizeof(inf->name));
|
||||
strscpy(inf->name, minf.name, sizeof(inf->name));
|
||||
} else {
|
||||
if ((rec = get_synthdev(dp, dev)) == NULL)
|
||||
return -ENXIO;
|
||||
|
@ -625,7 +625,7 @@ snd_seq_oss_synth_make_info(struct seq_oss_devinfo *dp, int dev, struct synth_in
|
|||
inf->synth_subtype = rec->synth_subtype;
|
||||
inf->nr_voices = rec->nr_voices;
|
||||
inf->device = dev;
|
||||
strlcpy(inf->name, rec->name, sizeof(inf->name));
|
||||
strscpy(inf->name, rec->name, sizeof(inf->name));
|
||||
snd_use_lock_free(&rec->use_lock);
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -1584,7 +1584,7 @@ static int snd_seq_ioctl_get_queue_info(struct snd_seq_client *client,
|
|||
info->queue = q->queue;
|
||||
info->owner = q->owner;
|
||||
info->locked = q->locked;
|
||||
strlcpy(info->name, q->name, sizeof(info->name));
|
||||
strscpy(info->name, q->name, sizeof(info->name));
|
||||
queuefree(q);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -290,7 +290,7 @@ int snd_seq_event_dup(struct snd_seq_pool *pool, struct snd_seq_event *event,
|
|||
extlen = 0;
|
||||
if (snd_seq_ev_is_variable(event)) {
|
||||
extlen = event->data.ext.len & ~SNDRV_SEQ_EXT_MASK;
|
||||
ncells = (extlen + sizeof(struct snd_seq_event) - 1) / sizeof(struct snd_seq_event);
|
||||
ncells = DIV_ROUND_UP(extlen, sizeof(struct snd_seq_event));
|
||||
}
|
||||
if (ncells >= pool->total_elements)
|
||||
return -ENOMEM;
|
||||
|
|
|
@ -327,7 +327,7 @@ int snd_seq_set_port_info(struct snd_seq_client_port * port,
|
|||
|
||||
/* set port name */
|
||||
if (info->name[0])
|
||||
strlcpy(port->name, info->name, sizeof(port->name));
|
||||
strscpy(port->name, info->name, sizeof(port->name));
|
||||
|
||||
/* set capabilities */
|
||||
port->capability = info->capability;
|
||||
|
@ -356,7 +356,7 @@ int snd_seq_get_port_info(struct snd_seq_client_port * port,
|
|||
return -EINVAL;
|
||||
|
||||
/* get port name */
|
||||
strlcpy(info->name, port->name, sizeof(info->name));
|
||||
strscpy(info->name, port->name, sizeof(info->name));
|
||||
|
||||
/* get capabilities */
|
||||
info->capability = port->capability;
|
||||
|
@ -654,7 +654,7 @@ int snd_seq_event_port_attach(int client,
|
|||
/* Set up the port */
|
||||
memset(&portinfo, 0, sizeof(portinfo));
|
||||
portinfo.addr.client = client;
|
||||
strlcpy(portinfo.name, portname ? portname : "Unnamed port",
|
||||
strscpy(portinfo.name, portname ? portname : "Unnamed port",
|
||||
sizeof(portinfo.name));
|
||||
|
||||
portinfo.capability = cap;
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <linux/time.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/minors.h>
|
||||
#include <sound/info.h>
|
||||
|
@ -39,6 +40,11 @@ MODULE_ALIAS_CHARDEV_MAJOR(CONFIG_SND_MAJOR);
|
|||
int snd_ecards_limit;
|
||||
EXPORT_SYMBOL(snd_ecards_limit);
|
||||
|
||||
#ifdef CONFIG_SND_DEBUG
|
||||
struct dentry *sound_debugfs_root;
|
||||
EXPORT_SYMBOL_GPL(sound_debugfs_root);
|
||||
#endif
|
||||
|
||||
static struct snd_minor *snd_minors[SNDRV_OS_MINORS];
|
||||
static DEFINE_MUTEX(sound_mutex);
|
||||
|
||||
|
@ -337,6 +343,8 @@ static const char *snd_device_type_name(int type)
|
|||
return "sequencer";
|
||||
case SNDRV_DEVICE_TYPE_TIMER:
|
||||
return "timer";
|
||||
case SNDRV_DEVICE_TYPE_COMPRESS:
|
||||
return "compress";
|
||||
default:
|
||||
return "?";
|
||||
}
|
||||
|
@ -395,6 +403,10 @@ static int __init alsa_sound_init(void)
|
|||
unregister_chrdev(major, "alsa");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SND_DEBUG
|
||||
sound_debugfs_root = debugfs_create_dir("sound", NULL);
|
||||
#endif
|
||||
#ifndef MODULE
|
||||
pr_info("Advanced Linux Sound Architecture Driver Initialized.\n");
|
||||
#endif
|
||||
|
@ -403,6 +415,9 @@ static int __init alsa_sound_init(void)
|
|||
|
||||
static void __exit alsa_sound_exit(void)
|
||||
{
|
||||
#ifdef CONFIG_SND_DEBUG
|
||||
debugfs_remove(sound_debugfs_root);
|
||||
#endif
|
||||
snd_info_done();
|
||||
unregister_chrdev(major, "alsa");
|
||||
}
|
||||
|
|
|
@ -959,7 +959,7 @@ int snd_timer_new(struct snd_card *card, char *id, struct snd_timer_id *tid,
|
|||
timer->tmr_device = tid->device;
|
||||
timer->tmr_subdevice = tid->subdevice;
|
||||
if (id)
|
||||
strlcpy(timer->id, id, sizeof(timer->id));
|
||||
strscpy(timer->id, id, sizeof(timer->id));
|
||||
timer->sticks = 1;
|
||||
INIT_LIST_HEAD(&timer->device_list);
|
||||
INIT_LIST_HEAD(&timer->open_list_head);
|
||||
|
@ -1659,8 +1659,8 @@ static int snd_timer_user_ginfo(struct file *file,
|
|||
ginfo->card = t->card ? t->card->number : -1;
|
||||
if (t->hw.flags & SNDRV_TIMER_HW_SLAVE)
|
||||
ginfo->flags |= SNDRV_TIMER_FLG_SLAVE;
|
||||
strlcpy(ginfo->id, t->id, sizeof(ginfo->id));
|
||||
strlcpy(ginfo->name, t->name, sizeof(ginfo->name));
|
||||
strscpy(ginfo->id, t->id, sizeof(ginfo->id));
|
||||
strscpy(ginfo->name, t->name, sizeof(ginfo->name));
|
||||
ginfo->resolution = t->hw.resolution;
|
||||
if (t->hw.resolution_min > 0) {
|
||||
ginfo->resolution_min = t->hw.resolution_min;
|
||||
|
@ -1814,8 +1814,8 @@ static int snd_timer_user_info(struct file *file,
|
|||
info->card = t->card ? t->card->number : -1;
|
||||
if (t->hw.flags & SNDRV_TIMER_HW_SLAVE)
|
||||
info->flags |= SNDRV_TIMER_FLG_SLAVE;
|
||||
strlcpy(info->id, t->id, sizeof(info->id));
|
||||
strlcpy(info->name, t->name, sizeof(info->name));
|
||||
strscpy(info->id, t->id, sizeof(info->id));
|
||||
strscpy(info->name, t->name, sizeof(info->name));
|
||||
info->resolution = t->hw.resolution;
|
||||
if (copy_to_user(_info, info, sizeof(*_info)))
|
||||
err = -EFAULT;
|
||||
|
|
|
@ -61,8 +61,8 @@ static int snd_timer_user_info_compat(struct file *file,
|
|||
info.card = t->card ? t->card->number : -1;
|
||||
if (t->hw.flags & SNDRV_TIMER_HW_SLAVE)
|
||||
info.flags |= SNDRV_TIMER_FLG_SLAVE;
|
||||
strlcpy(info.id, t->id, sizeof(info.id));
|
||||
strlcpy(info.name, t->name, sizeof(info.name));
|
||||
strscpy(info.id, t->id, sizeof(info.id));
|
||||
strscpy(info.name, t->name, sizeof(info.name));
|
||||
info.resolution = t->hw.resolution;
|
||||
if (copy_to_user(_info, &info, sizeof(*_info)))
|
||||
return -EFAULT;
|
||||
|
|
|
@ -219,7 +219,7 @@ static int loopback_jiffies_timer_start(struct loopback_pcm *dpcm)
|
|||
dpcm->period_update_pending = 1;
|
||||
}
|
||||
tick = dpcm->period_size_frac - dpcm->irq_pos;
|
||||
tick = (tick + dpcm->pcm_bps - 1) / dpcm->pcm_bps;
|
||||
tick = DIV_ROUND_UP(tick, dpcm->pcm_bps);
|
||||
mod_timer(&dpcm->timer, jiffies + tick);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -236,7 +236,7 @@ struct dummy_systimer_pcm {
|
|||
static void dummy_systimer_rearm(struct dummy_systimer_pcm *dpcm)
|
||||
{
|
||||
mod_timer(&dpcm->timer, jiffies +
|
||||
(dpcm->frac_period_rest + dpcm->rate - 1) / dpcm->rate);
|
||||
DIV_ROUND_UP(dpcm->frac_period_rest, dpcm->rate));
|
||||
}
|
||||
|
||||
static void dummy_systimer_update(struct dummy_systimer_pcm *dpcm)
|
||||
|
|
|
@ -97,7 +97,7 @@ void snd_opl3_init_seq_oss(struct snd_opl3 *opl3, char *name)
|
|||
return;
|
||||
|
||||
opl3->oss_seq_dev = dev;
|
||||
strlcpy(dev->name, name, sizeof(dev->name));
|
||||
strscpy(dev->name, name, sizeof(dev->name));
|
||||
arg = SNDRV_SEQ_DEVICE_ARGPTR(dev);
|
||||
arg->type = SYNTH_TYPE_FM;
|
||||
if (opl3->hardware < OPL3_HW_OPL3) {
|
||||
|
|
|
@ -290,7 +290,7 @@ int snd_opl3_load_patch(struct snd_opl3 *opl3,
|
|||
}
|
||||
|
||||
if (name)
|
||||
strlcpy(patch->name, name, sizeof(patch->name));
|
||||
strscpy(patch->name, name, sizeof(patch->name));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1154,8 +1154,7 @@ static int vx_init_audio_io(struct vx_core *chip)
|
|||
chip->ibl.size = 0;
|
||||
vx_set_ibl(chip, &chip->ibl); /* query the info */
|
||||
if (preferred > 0) {
|
||||
chip->ibl.size = ((preferred + chip->ibl.granularity - 1) /
|
||||
chip->ibl.granularity) * chip->ibl.granularity;
|
||||
chip->ibl.size = roundup(preferred, chip->ibl.granularity);
|
||||
if (chip->ibl.size > chip->ibl.max_size)
|
||||
chip->ibl.size = chip->ibl.max_size;
|
||||
} else
|
||||
|
|
|
@ -37,11 +37,9 @@ hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count,
|
|||
|
||||
memset(&event, 0, sizeof(event));
|
||||
count = min_t(long, count, sizeof(event.lock_status));
|
||||
if (bebob->dev_lock_changed) {
|
||||
event.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS;
|
||||
event.lock_status.status = (bebob->dev_lock_count > 0);
|
||||
bebob->dev_lock_changed = false;
|
||||
}
|
||||
event.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS;
|
||||
event.lock_status.status = (bebob->dev_lock_count > 0);
|
||||
bebob->dev_lock_changed = false;
|
||||
|
||||
spin_unlock_irq(&bebob->lock);
|
||||
|
||||
|
@ -80,7 +78,7 @@ hwdep_get_info(struct snd_bebob *bebob, void __user *arg)
|
|||
info.card = dev->card->index;
|
||||
*(__be32 *)&info.guid[0] = cpu_to_be32(dev->config_rom[3]);
|
||||
*(__be32 *)&info.guid[4] = cpu_to_be32(dev->config_rom[4]);
|
||||
strlcpy(info.device_name, dev_name(&dev->device),
|
||||
strscpy(info.device_name, dev_name(&dev->device),
|
||||
sizeof(info.device_name));
|
||||
|
||||
if (copy_to_user(arg, &info, sizeof(info)))
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
snd-dice-objs := dice-transaction.o dice-stream.o dice-proc.o dice-midi.o \
|
||||
dice-pcm.o dice-hwdep.o dice.o dice-tcelectronic.o \
|
||||
dice-alesis.o dice-extension.o dice-mytek.o dice-presonus.o
|
||||
dice-alesis.o dice-extension.o dice-mytek.o dice-presonus.o \
|
||||
dice-harman.o
|
||||
obj-$(CONFIG_SND_DICE) += snd-dice.o
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
// dice-harman.c - a part of driver for DICE based devices
|
||||
//
|
||||
// Copyright (c) 2021 Takashi Sakamoto
|
||||
//
|
||||
// Licensed under the terms of the GNU General Public License, version 2.
|
||||
|
||||
#include "dice.h"
|
||||
|
||||
int snd_dice_detect_harman_formats(struct snd_dice *dice)
|
||||
{
|
||||
int i;
|
||||
|
||||
// Lexicon I-ONYX FW810s supports sampling transfer frequency up to
|
||||
// 96.0 kHz, 12 PCM channels and 1 MIDI channel in its first tx stream
|
||||
// , 10 PCM channels and 1 MIDI channel in its first rx stream for all
|
||||
// of the frequencies.
|
||||
for (i = 0; i < 2; ++i) {
|
||||
dice->tx_pcm_chs[0][i] = 12;
|
||||
dice->tx_midi_ports[0] = 1;
|
||||
dice->rx_pcm_chs[0][i] = 10;
|
||||
dice->rx_midi_ports[0] = 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -79,7 +79,7 @@ static int hwdep_get_info(struct snd_dice *dice, void __user *arg)
|
|||
info.card = dev->card->index;
|
||||
*(__be32 *)&info.guid[0] = cpu_to_be32(dev->config_rom[3]);
|
||||
*(__be32 *)&info.guid[4] = cpu_to_be32(dev->config_rom[4]);
|
||||
strlcpy(info.device_name, dev_name(&dev->device),
|
||||
strscpy(info.device_name, dev_name(&dev->device),
|
||||
sizeof(info.device_name));
|
||||
|
||||
if (copy_to_user(arg, &info, sizeof(info)))
|
||||
|
|
|
@ -20,10 +20,12 @@ MODULE_LICENSE("GPL v2");
|
|||
#define OUI_MYTEK 0x001ee8
|
||||
#define OUI_SSL 0x0050c2 // Actually ID reserved by IEEE.
|
||||
#define OUI_PRESONUS 0x000a92
|
||||
#define OUI_HARMAN 0x000fd7
|
||||
|
||||
#define DICE_CATEGORY_ID 0x04
|
||||
#define WEISS_CATEGORY_ID 0x00
|
||||
#define LOUD_CATEGORY_ID 0x10
|
||||
#define HARMAN_CATEGORY_ID 0x20
|
||||
|
||||
#define MODEL_ALESIS_IO_BOTH 0x000001
|
||||
|
||||
|
@ -56,6 +58,8 @@ static int check_dice_category(struct fw_unit *unit)
|
|||
category = WEISS_CATEGORY_ID;
|
||||
else if (vendor == OUI_LOUD)
|
||||
category = LOUD_CATEGORY_ID;
|
||||
else if (vendor == OUI_HARMAN)
|
||||
category = HARMAN_CATEGORY_ID;
|
||||
else
|
||||
category = DICE_CATEGORY_ID;
|
||||
if (device->config_rom[3] != ((vendor << 8) | category) ||
|
||||
|
@ -388,6 +392,14 @@ static const struct ieee1394_device_id dice_id_table[] = {
|
|||
.model_id = 0x000008,
|
||||
.driver_data = (kernel_ulong_t)snd_dice_detect_presonus_formats,
|
||||
},
|
||||
// Lexicon I-ONYX FW810S.
|
||||
{
|
||||
.match_flags = IEEE1394_MATCH_VENDOR_ID |
|
||||
IEEE1394_MATCH_MODEL_ID,
|
||||
.vendor_id = OUI_HARMAN,
|
||||
.model_id = 0x000001,
|
||||
.driver_data = (kernel_ulong_t)snd_dice_detect_harman_formats,
|
||||
},
|
||||
{
|
||||
.match_flags = IEEE1394_MATCH_VERSION,
|
||||
.version = DICE_INTERFACE,
|
||||
|
|
|
@ -233,5 +233,6 @@ int snd_dice_detect_alesis_mastercontrol_formats(struct snd_dice *dice);
|
|||
int snd_dice_detect_extension_formats(struct snd_dice *dice);
|
||||
int snd_dice_detect_mytek_formats(struct snd_dice *dice);
|
||||
int snd_dice_detect_presonus_formats(struct snd_dice *dice);
|
||||
int snd_dice_detect_harman_formats(struct snd_dice *dice);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -87,7 +87,7 @@ static int hwdep_get_info(struct snd_dg00x *dg00x, void __user *arg)
|
|||
info.card = dev->card->index;
|
||||
*(__be32 *)&info.guid[0] = cpu_to_be32(dev->config_rom[3]);
|
||||
*(__be32 *)&info.guid[4] = cpu_to_be32(dev->config_rom[4]);
|
||||
strlcpy(info.device_name, dev_name(&dev->device),
|
||||
strscpy(info.device_name, dev_name(&dev->device),
|
||||
sizeof(info.device_name));
|
||||
|
||||
if (copy_to_user(arg, &info, sizeof(info)))
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue