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.
|
description: CPU to Codec rate channels.
|
||||||
$ref: /schemas/types.yaml#/definitions/uint32
|
$ref: /schemas/types.yaml#/definitions/uint32
|
||||||
|
|
||||||
required:
|
|
||||||
- remote-endpoint
|
|
||||||
|
|
||||||
ports:
|
ports:
|
||||||
description: multi OF-Graph subnode
|
description: multi OF-Graph subnode
|
||||||
type: object
|
type: object
|
||||||
|
@ -15,9 +15,14 @@ properties:
|
|||||||
|
|
||||||
compatible:
|
compatible:
|
||||||
oneOf:
|
oneOf:
|
||||||
- const: ingenic,jz4770-codec
|
- enum:
|
||||||
- const: ingenic,jz4725b-codec
|
- ingenic,jz4770-codec
|
||||||
- const: ingenic,jz4740-codec
|
- ingenic,jz4760-codec
|
||||||
|
- ingenic,jz4725b-codec
|
||||||
|
- ingenic,jz4740-codec
|
||||||
|
- items:
|
||||||
|
- const: ingenic,jz4760b-codec
|
||||||
|
- const: ingenic,jz4760-codec
|
||||||
|
|
||||||
reg:
|
reg:
|
||||||
maxItems: 1
|
maxItems: 1
|
||||||
|
@ -18,6 +18,7 @@ properties:
|
|||||||
enum:
|
enum:
|
||||||
- intel,keembay-i2s
|
- intel,keembay-i2s
|
||||||
- intel,keembay-tdm
|
- intel,keembay-tdm
|
||||||
|
- intel,keembay-hdmi-i2s
|
||||||
|
|
||||||
"#sound-dai-cells":
|
"#sound-dai-cells":
|
||||||
const: 0
|
const: 0
|
||||||
@ -45,6 +46,16 @@ properties:
|
|||||||
- const: osc
|
- const: osc
|
||||||
- const: apb_clk
|
- const: apb_clk
|
||||||
|
|
||||||
|
dmas:
|
||||||
|
items:
|
||||||
|
- description: DMA TX channel
|
||||||
|
- description: DMA RX channel
|
||||||
|
|
||||||
|
dma-names:
|
||||||
|
items:
|
||||||
|
- const: tx
|
||||||
|
- const: rx
|
||||||
|
|
||||||
required:
|
required:
|
||||||
- compatible
|
- compatible
|
||||||
- "#sound-dai-cells"
|
- "#sound-dai-cells"
|
||||||
@ -70,4 +81,6 @@ examples:
|
|||||||
interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
|
interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
clock-names = "osc", "apb_clk";
|
clock-names = "osc", "apb_clk";
|
||||||
clocks = <&scmi_clk KEEM_BAY_PSS_AUX_I2S3>, <&scmi_clk KEEM_BAY_PSS_I2S3>;
|
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"
|
$ref: "/schemas/types.yaml#/definitions/phandle"
|
||||||
description: The phandle of MT8192 ASoC platform.
|
description: The phandle of MT8192 ASoC platform.
|
||||||
|
|
||||||
|
mediatek,hdmi-codec:
|
||||||
|
$ref: "/schemas/types.yaml#/definitions/phandle"
|
||||||
|
description: The phandle of HDMI codec.
|
||||||
|
|
||||||
additionalProperties: false
|
additionalProperties: false
|
||||||
|
|
||||||
required:
|
required:
|
||||||
@ -35,6 +39,7 @@ examples:
|
|||||||
sound: mt8192-sound {
|
sound: mt8192-sound {
|
||||||
compatible = "mediatek,mt8192_mt6359_rt1015_rt5682";
|
compatible = "mediatek,mt8192_mt6359_rt1015_rt5682";
|
||||||
mediatek,platform = <&afe>;
|
mediatek,platform = <&afe>;
|
||||||
|
mediatek,hdmi-codec = <&anx_bridge_dp>;
|
||||||
pinctrl-names = "aud_clk_mosi_off",
|
pinctrl-names = "aud_clk_mosi_off",
|
||||||
"aud_clk_mosi_on";
|
"aud_clk_mosi_on";
|
||||||
pinctrl-0 = <&aud_clk_mosi_off>;
|
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>
|
- Jon Hunter <jonathanh@nvidia.com>
|
||||||
- Sameer Pujar <spujar@nvidia.com>
|
- Sameer Pujar <spujar@nvidia.com>
|
||||||
|
|
||||||
|
allOf:
|
||||||
|
- $ref: audio-graph-port.yaml#
|
||||||
|
|
||||||
properties:
|
properties:
|
||||||
$nodename:
|
$nodename:
|
||||||
pattern: "^dspk@[0-9a-f]*$"
|
pattern: "^dspk@[0-9a-f]*$"
|
||||||
@ -55,6 +58,19 @@ properties:
|
|||||||
The name can be "DSPK1" or "DSPKx", where x depends on the maximum
|
The name can be "DSPK1" or "DSPKx", where x depends on the maximum
|
||||||
available instances on a Tegra SoC.
|
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:
|
required:
|
||||||
- compatible
|
- compatible
|
||||||
- reg
|
- reg
|
||||||
@ -64,7 +80,7 @@ required:
|
|||||||
- assigned-clock-parents
|
- assigned-clock-parents
|
||||||
- sound-name-prefix
|
- sound-name-prefix
|
||||||
|
|
||||||
additionalProperties: false
|
unevaluatedProperties: false
|
||||||
|
|
||||||
examples:
|
examples:
|
||||||
- |
|
- |
|
||||||
|
@ -17,6 +17,9 @@ maintainers:
|
|||||||
- Jon Hunter <jonathanh@nvidia.com>
|
- Jon Hunter <jonathanh@nvidia.com>
|
||||||
- Sameer Pujar <spujar@nvidia.com>
|
- Sameer Pujar <spujar@nvidia.com>
|
||||||
|
|
||||||
|
allOf:
|
||||||
|
- $ref: audio-graph-port.yaml#
|
||||||
|
|
||||||
properties:
|
properties:
|
||||||
$nodename:
|
$nodename:
|
||||||
pattern: "^admaif@[0-9a-f]*$"
|
pattern: "^admaif@[0-9a-f]*$"
|
||||||
@ -37,6 +40,14 @@ properties:
|
|||||||
|
|
||||||
dma-names: true
|
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:
|
if:
|
||||||
properties:
|
properties:
|
||||||
compatible:
|
compatible:
|
||||||
@ -81,7 +92,7 @@ required:
|
|||||||
- dmas
|
- dmas
|
||||||
- dma-names
|
- dma-names
|
||||||
|
|
||||||
additionalProperties: false
|
unevaluatedProperties: false
|
||||||
|
|
||||||
examples:
|
examples:
|
||||||
- |
|
- |
|
||||||
|
@ -17,6 +17,9 @@ maintainers:
|
|||||||
- Jon Hunter <jonathanh@nvidia.com>
|
- Jon Hunter <jonathanh@nvidia.com>
|
||||||
- Sameer Pujar <spujar@nvidia.com>
|
- Sameer Pujar <spujar@nvidia.com>
|
||||||
|
|
||||||
|
allOf:
|
||||||
|
- $ref: audio-graph-port.yaml#
|
||||||
|
|
||||||
properties:
|
properties:
|
||||||
$nodename:
|
$nodename:
|
||||||
pattern: "^ahub@[0-9a-f]*$"
|
pattern: "^ahub@[0-9a-f]*$"
|
||||||
@ -56,6 +59,13 @@ properties:
|
|||||||
|
|
||||||
ranges: true
|
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:
|
required:
|
||||||
- compatible
|
- compatible
|
||||||
- reg
|
- reg
|
||||||
@ -67,8 +77,7 @@ required:
|
|||||||
- "#size-cells"
|
- "#size-cells"
|
||||||
- ranges
|
- ranges
|
||||||
|
|
||||||
additionalProperties:
|
unevaluatedProperties: false
|
||||||
type: object
|
|
||||||
|
|
||||||
examples:
|
examples:
|
||||||
- |
|
- |
|
||||||
|
@ -16,6 +16,9 @@ maintainers:
|
|||||||
- Jon Hunter <jonathanh@nvidia.com>
|
- Jon Hunter <jonathanh@nvidia.com>
|
||||||
- Sameer Pujar <spujar@nvidia.com>
|
- Sameer Pujar <spujar@nvidia.com>
|
||||||
|
|
||||||
|
allOf:
|
||||||
|
- $ref: audio-graph-port.yaml#
|
||||||
|
|
||||||
properties:
|
properties:
|
||||||
$nodename:
|
$nodename:
|
||||||
pattern: "^dmic@[0-9a-f]*$"
|
pattern: "^dmic@[0-9a-f]*$"
|
||||||
@ -56,6 +59,19 @@ properties:
|
|||||||
The name can be "DMIC1" or "DMIC2" ... "DMICx", where x depends
|
The name can be "DMIC1" or "DMIC2" ... "DMICx", where x depends
|
||||||
on the maximum available instances on a Tegra SoC.
|
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:
|
required:
|
||||||
- compatible
|
- compatible
|
||||||
- reg
|
- reg
|
||||||
@ -64,7 +80,7 @@ required:
|
|||||||
- assigned-clocks
|
- assigned-clocks
|
||||||
- assigned-clock-parents
|
- assigned-clock-parents
|
||||||
|
|
||||||
additionalProperties: false
|
unevaluatedProperties: false
|
||||||
|
|
||||||
examples:
|
examples:
|
||||||
- |
|
- |
|
||||||
|
@ -16,6 +16,9 @@ maintainers:
|
|||||||
- Jon Hunter <jonathanh@nvidia.com>
|
- Jon Hunter <jonathanh@nvidia.com>
|
||||||
- Sameer Pujar <spujar@nvidia.com>
|
- Sameer Pujar <spujar@nvidia.com>
|
||||||
|
|
||||||
|
allOf:
|
||||||
|
- $ref: audio-graph-port.yaml#
|
||||||
|
|
||||||
properties:
|
properties:
|
||||||
$nodename:
|
$nodename:
|
||||||
pattern: "^i2s@[0-9a-f]*$"
|
pattern: "^i2s@[0-9a-f]*$"
|
||||||
@ -74,6 +77,19 @@ properties:
|
|||||||
The name can be "I2S1" or "I2S2" ... "I2Sx", where x depends
|
The name can be "I2S1" or "I2S2" ... "I2Sx", where x depends
|
||||||
on the maximum available instances on a Tegra SoC.
|
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:
|
required:
|
||||||
- compatible
|
- compatible
|
||||||
- reg
|
- reg
|
||||||
@ -82,7 +98,7 @@ required:
|
|||||||
- assigned-clocks
|
- assigned-clocks
|
||||||
- assigned-clock-parents
|
- assigned-clock-parents
|
||||||
|
|
||||||
additionalProperties: false
|
unevaluatedProperties: false
|
||||||
|
|
||||||
examples:
|
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 */
|
/* DAI base */
|
||||||
rcar_sound,dai {
|
rcar_sound,dai {
|
||||||
dai0 {
|
dai0 {
|
||||||
playback = <&ssi5 &src5>;
|
playback = <&ssi5>, <&src5>;
|
||||||
capture = <&ssi6>;
|
capture = <&ssi6>;
|
||||||
};
|
};
|
||||||
dai1 {
|
dai1 {
|
||||||
@ -430,8 +430,8 @@ examples:
|
|||||||
bitclock-master = <&rsnd_endpoint0>;
|
bitclock-master = <&rsnd_endpoint0>;
|
||||||
frame-master = <&rsnd_endpoint0>;
|
frame-master = <&rsnd_endpoint0>;
|
||||||
|
|
||||||
playback = <&ssi0 &src0 &dvc0>;
|
playback = <&ssi0>, <&src0>, <&dvc0>;
|
||||||
capture = <&ssi1 &src1 &dvc1>;
|
capture = <&ssi1>, <&src1>, <&dvc1>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -37,10 +37,21 @@ Optional properties:
|
|||||||
- realtek,jd-src
|
- realtek,jd-src
|
||||||
0: No JD is used
|
0: No JD is used
|
||||||
1: using JD3 as JD source
|
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,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.
|
- 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:
|
Pins on the device (for linking into audio routes) for RT5659/RT5658:
|
||||||
|
|
||||||
* DMIC L1
|
* 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:
|
resets:
|
||||||
maxItems: 1
|
maxItems: 1
|
||||||
|
|
||||||
|
"#clock-cells":
|
||||||
|
description: Configure the I2S device as MCLK clock provider.
|
||||||
|
const: 0
|
||||||
|
|
||||||
required:
|
required:
|
||||||
- compatible
|
- compatible
|
||||||
- "#sound-dai-cells"
|
- "#sound-dai-cells"
|
||||||
|
@ -9,6 +9,9 @@ Required properties:
|
|||||||
- reg : the I2C address of the device.
|
- reg : the I2C address of the device.
|
||||||
|
|
||||||
Optional properties:
|
Optional properties:
|
||||||
|
|
||||||
|
- clocks : The clock source of the mclk
|
||||||
|
|
||||||
- spk-mono: This is a boolean property. If present, the SPK_MONO bit
|
- 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
|
of R51 (Class D Control 2) gets set, indicating that the speaker is
|
||||||
in mono mode.
|
in mono mode.
|
||||||
@ -27,6 +30,7 @@ Example:
|
|||||||
wm8962: codec@1a {
|
wm8962: codec@1a {
|
||||||
compatible = "wlf,wm8962";
|
compatible = "wlf,wm8962";
|
||||||
reg = <0x1a>;
|
reg = <0x1a>;
|
||||||
|
clocks = <&clks IMX6QDL_CLK_CKO>;
|
||||||
|
|
||||||
gpio-cfg = <
|
gpio-cfg = <
|
||||||
0x0000 /* 0:Default */
|
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
|
powersave
|
||||||
oss-emulation
|
oss-emulation
|
||||||
seq-oss
|
seq-oss
|
||||||
|
jack-injection
|
||||||
|
166
Documentation/sound/designs/jack-injection.rst
Normal file
166
Documentation/sound/designs/jack-injection.rst
Normal file
@ -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;
|
struct isa_driver *isa_driver = dev->platform_data;
|
||||||
|
|
||||||
if (isa_driver && isa_driver->remove)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -282,7 +282,7 @@ static int elektor_probe(struct device *dev, unsigned int id)
|
|||||||
return -ENODEV;
|
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);
|
i2c_del_adapter(&pcf_isa_ops);
|
||||||
|
|
||||||
@ -298,8 +298,6 @@ static int elektor_remove(struct device *dev, unsigned int id)
|
|||||||
iounmap(base_iomem);
|
iounmap(base_iomem);
|
||||||
release_mem_region(base, 2);
|
release_mem_region(base, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct isa_driver i2c_elektor_driver = {
|
static struct isa_driver i2c_elektor_driver = {
|
||||||
|
@ -161,7 +161,7 @@ static int pca_isa_probe(struct device *dev, unsigned int id)
|
|||||||
return -ENODEV;
|
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);
|
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);
|
free_irq(irq, &pca_isa_ops);
|
||||||
}
|
}
|
||||||
release_region(base, IO_SIZE);
|
release_region(base, IO_SIZE);
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct isa_driver pca_isa_driver = {
|
static struct isa_driver pca_isa_driver = {
|
||||||
|
@ -171,7 +171,7 @@ static int htcpen_isa_probe(struct device *dev, unsigned int id)
|
|||||||
return err;
|
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);
|
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_INDEX, 2);
|
||||||
release_region(HTCPEN_PORT_INIT, 1);
|
release_region(HTCPEN_PORT_INIT, 1);
|
||||||
release_region(HTCPEN_PORT_IRQ_CLEAR, 1);
|
release_region(HTCPEN_PORT_IRQ_CLEAR, 1);
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
|
@ -273,8 +273,8 @@ err_dev_reg:
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int radio_isa_common_remove(struct radio_isa_card *isa,
|
static void radio_isa_common_remove(struct radio_isa_card *isa,
|
||||||
unsigned region_size)
|
unsigned region_size)
|
||||||
{
|
{
|
||||||
const struct radio_isa_ops *ops = isa->drv->ops;
|
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);
|
release_region(isa->io, region_size);
|
||||||
v4l2_info(&isa->v4l2_dev, "Removed radio card %s\n", isa->drv->card);
|
v4l2_info(&isa->v4l2_dev, "Removed radio card %s\n", isa->drv->card);
|
||||||
kfree(isa);
|
kfree(isa);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int radio_isa_probe(struct device *pdev, unsigned int dev)
|
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);
|
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);
|
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);
|
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_match(struct device *pdev, unsigned int dev);
|
||||||
int radio_isa_probe(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
|
#ifdef CONFIG_PNP
|
||||||
int radio_isa_pnp_probe(struct pnp_dev *dev,
|
int radio_isa_pnp_probe(struct pnp_dev *dev,
|
||||||
const struct pnp_device_id *dev_id);
|
const struct pnp_device_id *dev_id);
|
||||||
|
@ -293,11 +293,9 @@ static void fmr2_remove(struct fmr2 *fmr2)
|
|||||||
kfree(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));
|
fmr2_remove(dev_get_drvdata(pdev));
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fmr2_pnp_remove(struct pnp_dev *pdev)
|
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);
|
EXPORT_SYMBOL_GPL(arizona_pm_ops);
|
||||||
|
|
||||||
#ifdef CONFIG_OF
|
#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)
|
static int arizona_of_get_core_pdata(struct arizona *arizona)
|
||||||
{
|
{
|
||||||
struct arizona_pdata *pdata = &arizona->pdata;
|
struct arizona_pdata *pdata = &arizona->pdata;
|
||||||
|
@ -23,14 +23,16 @@
|
|||||||
static int arizona_i2c_probe(struct i2c_client *i2c,
|
static int arizona_i2c_probe(struct i2c_client *i2c,
|
||||||
const struct i2c_device_id *id)
|
const struct i2c_device_id *id)
|
||||||
{
|
{
|
||||||
|
const void *match_data;
|
||||||
struct arizona *arizona;
|
struct arizona *arizona;
|
||||||
const struct regmap_config *regmap_config = NULL;
|
const struct regmap_config *regmap_config = NULL;
|
||||||
unsigned long type;
|
unsigned long type = 0;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (i2c->dev.of_node)
|
match_data = device_get_match_data(&i2c->dev);
|
||||||
type = arizona_of_get_type(&i2c->dev);
|
if (match_data)
|
||||||
else
|
type = (unsigned long)match_data;
|
||||||
|
else if (id)
|
||||||
type = id->driver_data;
|
type = id->driver_data;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
@ -115,6 +117,7 @@ static struct i2c_driver arizona_i2c_driver = {
|
|||||||
|
|
||||||
module_i2c_driver(arizona_i2c_driver);
|
module_i2c_driver(arizona_i2c_driver);
|
||||||
|
|
||||||
|
MODULE_SOFTDEP("pre: arizona_ldo1");
|
||||||
MODULE_DESCRIPTION("Arizona I2C bus interface");
|
MODULE_DESCRIPTION("Arizona I2C bus interface");
|
||||||
MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
|
MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
@ -7,7 +7,10 @@
|
|||||||
* Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
|
* Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <linux/acpi.h>
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
|
#include <linux/gpio/consumer.h>
|
||||||
|
#include <linux/gpio/machine.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/pm_runtime.h>
|
#include <linux/pm_runtime.h>
|
||||||
#include <linux/regmap.h>
|
#include <linux/regmap.h>
|
||||||
@ -15,22 +18,141 @@
|
|||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/spi/spi.h>
|
#include <linux/spi/spi.h>
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
|
#include <uapi/linux/input-event-codes.h>
|
||||||
|
|
||||||
#include <linux/mfd/arizona/core.h>
|
#include <linux/mfd/arizona/core.h>
|
||||||
|
|
||||||
#include "arizona.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)
|
static int arizona_spi_probe(struct spi_device *spi)
|
||||||
{
|
{
|
||||||
const struct spi_device_id *id = spi_get_device_id(spi);
|
const struct spi_device_id *id = spi_get_device_id(spi);
|
||||||
|
const void *match_data;
|
||||||
struct arizona *arizona;
|
struct arizona *arizona;
|
||||||
const struct regmap_config *regmap_config = NULL;
|
const struct regmap_config *regmap_config = NULL;
|
||||||
unsigned long type;
|
unsigned long type = 0;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (spi->dev.of_node)
|
match_data = device_get_match_data(&spi->dev);
|
||||||
type = arizona_of_get_type(&spi->dev);
|
if (match_data)
|
||||||
else
|
type = (unsigned long)match_data;
|
||||||
|
else if (id)
|
||||||
type = id->driver_data;
|
type = id->driver_data;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
@ -75,6 +197,12 @@ static int arizona_spi_probe(struct spi_device *spi)
|
|||||||
arizona->dev = &spi->dev;
|
arizona->dev = &spi->dev;
|
||||||
arizona->irq = spi->irq;
|
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);
|
return arizona_dev_init(arizona);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,6 +230,7 @@ static struct spi_driver arizona_spi_driver = {
|
|||||||
.name = "arizona",
|
.name = "arizona",
|
||||||
.pm = &arizona_pm_ops,
|
.pm = &arizona_pm_ops,
|
||||||
.of_match_table = of_match_ptr(arizona_of_match),
|
.of_match_table = of_match_ptr(arizona_of_match),
|
||||||
|
.acpi_match_table = ACPI_PTR(arizona_acpi_match),
|
||||||
},
|
},
|
||||||
.probe = arizona_spi_probe,
|
.probe = arizona_spi_probe,
|
||||||
.remove = arizona_spi_remove,
|
.remove = arizona_spi_remove,
|
||||||
@ -110,6 +239,7 @@ static struct spi_driver arizona_spi_driver = {
|
|||||||
|
|
||||||
module_spi_driver(arizona_spi_driver);
|
module_spi_driver(arizona_spi_driver);
|
||||||
|
|
||||||
|
MODULE_SOFTDEP("pre: arizona_ldo1");
|
||||||
MODULE_DESCRIPTION("Arizona SPI bus interface");
|
MODULE_DESCRIPTION("Arizona SPI bus interface");
|
||||||
MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
|
MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
@ -50,13 +50,4 @@ int arizona_dev_exit(struct arizona *arizona);
|
|||||||
int arizona_irq_init(struct arizona *arizona);
|
int arizona_irq_init(struct arizona *arizona);
|
||||||
int arizona_irq_exit(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
|
#endif
|
||||||
|
@ -159,7 +159,7 @@ static int tscan1_probe(struct device *dev, unsigned id)
|
|||||||
return -ENXIO;
|
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 net_device *netdev;
|
||||||
struct sja1000_priv *priv;
|
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);
|
release_region(pld_base, TSCAN1_PLD_SIZE);
|
||||||
|
|
||||||
free_sja1000dev(netdev);
|
free_sja1000dev(netdev);
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct isa_driver tscan1_isa_driver = {
|
static struct isa_driver tscan1_isa_driver = {
|
||||||
|
@ -335,12 +335,11 @@ static int el3_isa_match(struct device *pdev, unsigned int ndev)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int el3_isa_remove(struct device *pdev,
|
static void el3_isa_remove(struct device *pdev,
|
||||||
unsigned int ndev)
|
unsigned int ndev)
|
||||||
{
|
{
|
||||||
el3_device_remove(pdev);
|
el3_device_remove(pdev);
|
||||||
dev_set_drvdata(pdev, NULL);
|
dev_set_drvdata(pdev, NULL);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
|
@ -11459,12 +11459,11 @@ static int advansys_isa_probe(struct device *dev, unsigned int id)
|
|||||||
return err;
|
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];
|
int ioport = _asc_def_iop_base[id];
|
||||||
advansys_release(dev_get_drvdata(dev));
|
advansys_release(dev_get_drvdata(dev));
|
||||||
release_region(ioport, ASC_IOADR_GAP);
|
release_region(ioport, ASC_IOADR_GAP);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct isa_driver advansys_isa_driver = {
|
static struct isa_driver advansys_isa_driver = {
|
||||||
|
@ -1025,12 +1025,11 @@ static int aha1542_isa_match(struct device *pdev, unsigned int ndev)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int aha1542_isa_remove(struct device *pdev,
|
static void aha1542_isa_remove(struct device *pdev,
|
||||||
unsigned int ndev)
|
unsigned int ndev)
|
||||||
{
|
{
|
||||||
aha1542_release(dev_get_drvdata(pdev));
|
aha1542_release(dev_get_drvdata(pdev));
|
||||||
dev_set_drvdata(pdev, NULL);
|
dev_set_drvdata(pdev, NULL);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct isa_driver aha1542_isa_driver = {
|
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;
|
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);
|
struct Scsi_Host *sh = dev_get_drvdata(dev);
|
||||||
int base = sh->io_port;
|
int base = sh->io_port;
|
||||||
@ -183,7 +183,6 @@ static int fdomain_isa_remove(struct device *dev, unsigned int ndev)
|
|||||||
fdomain_destroy(sh);
|
fdomain_destroy(sh);
|
||||||
release_region(base, FDOMAIN_REGION_SIZE);
|
release_region(base, FDOMAIN_REGION_SIZE);
|
||||||
dev_set_drvdata(dev, NULL);
|
dev_set_drvdata(dev, NULL);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct isa_driver fdomain_isa_driver = {
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int generic_NCR5380_isa_remove(struct device *pdev,
|
static void generic_NCR5380_isa_remove(struct device *pdev,
|
||||||
unsigned int ndev)
|
unsigned int ndev)
|
||||||
{
|
{
|
||||||
generic_NCR5380_release_resources(dev_get_drvdata(pdev));
|
generic_NCR5380_release_resources(dev_get_drvdata(pdev));
|
||||||
dev_set_drvdata(pdev, NULL);
|
dev_set_drvdata(pdev, NULL);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct isa_driver generic_NCR5380_isa_driver = {
|
static struct isa_driver generic_NCR5380_isa_driver = {
|
||||||
|
@ -951,14 +951,11 @@ error_request_region:
|
|||||||
return ret;
|
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)
|
if (debug >= DEBUG)
|
||||||
pr_debug("pcwd_isa_remove id=%d\n", id);
|
pr_debug("pcwd_isa_remove id=%d\n", id);
|
||||||
|
|
||||||
if (!pcwd_private.io_addr)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
/* Disable the board */
|
/* Disable the board */
|
||||||
if (!nowayout)
|
if (!nowayout)
|
||||||
pcwd_stop();
|
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.revision == PCWD_REVISION_A) ? 2 : 4);
|
||||||
pcwd_private.io_addr = 0x0000;
|
pcwd_private.io_addr = 0x0000;
|
||||||
cards_found--;
|
cards_found--;
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pcwd_isa_shutdown(struct device *dev, unsigned int id)
|
static void pcwd_isa_shutdown(struct device *dev, unsigned int id)
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
struct isa_driver {
|
struct isa_driver {
|
||||||
int (*match)(struct device *, unsigned int);
|
int (*match)(struct device *, unsigned int);
|
||||||
int (*probe)(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);
|
void (*shutdown)(struct device *, unsigned int);
|
||||||
int (*suspend)(struct device *, unsigned int, pm_message_t);
|
int (*suspend)(struct device *, unsigned int, pm_message_t);
|
||||||
int (*resume)(struct device *, unsigned int);
|
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_SAMPLE_DEPTH = 0x2,
|
||||||
EC_CODEC_I2S_RX_SET_DAIFMT = 0x3,
|
EC_CODEC_I2S_RX_SET_DAIFMT = 0x3,
|
||||||
EC_CODEC_I2S_RX_SET_BCLK = 0x4,
|
EC_CODEC_I2S_RX_SET_BCLK = 0x4,
|
||||||
|
EC_CODEC_I2S_RX_RESET = 0x5,
|
||||||
EC_CODEC_I2S_RX_SUBCMD_COUNT,
|
EC_CODEC_I2S_RX_SUBCMD_COUNT,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -122,6 +122,9 @@ struct snd_card {
|
|||||||
|
|
||||||
size_t total_pcm_alloc_bytes; /* total amount of allocated buffers */
|
size_t total_pcm_alloc_bytes; /* total amount of allocated buffers */
|
||||||
struct mutex memory_mutex; /* protection for the above */
|
struct mutex memory_mutex; /* protection for the above */
|
||||||
|
#ifdef CONFIG_SND_DEBUG
|
||||||
|
struct dentry *debugfs_root; /* debugfs root for card */
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
unsigned int power_state; /* power state */
|
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_major;
|
||||||
extern int snd_ecards_limit;
|
extern int snd_ecards_limit;
|
||||||
extern struct class *sound_class;
|
extern struct class *sound_class;
|
||||||
|
#ifdef CONFIG_SND_DEBUG
|
||||||
|
extern struct dentry *sound_debugfs_root;
|
||||||
|
#endif
|
||||||
|
|
||||||
void snd_request_card(int card);
|
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.
|
* @chan_name: Custom channel name to use when requesting DMA channel.
|
||||||
* @fifo_size: FIFO size of the DAI controller in bytes
|
* @fifo_size: FIFO size of the DAI controller in bytes
|
||||||
* @flags: PCM_DAI flags, only SND_DMAENGINE_PCM_DAI_FLAG_PACK for now
|
* @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 {
|
struct snd_dmaengine_dai_dma_data {
|
||||||
dma_addr_t addr;
|
dma_addr_t addr;
|
||||||
@ -76,6 +79,8 @@ struct snd_dmaengine_dai_dma_data {
|
|||||||
const char *chan_name;
|
const char *chan_name;
|
||||||
unsigned int fifo_size;
|
unsigned int fifo_size;
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
|
void *peripheral_config;
|
||||||
|
size_t peripheral_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
void snd_dmaengine_pcm_set_config_from_dai_data(
|
void snd_dmaengine_pcm_set_config_from_dai_data(
|
||||||
|
@ -9,8 +9,10 @@
|
|||||||
|
|
||||||
#include <sound/simple_card_utils.h>
|
#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 */
|
#endif /* __GRAPH_CARD_H */
|
||||||
|
@ -241,6 +241,8 @@ struct hdac_bus_ops {
|
|||||||
/* get a response from the last command */
|
/* get a response from the last command */
|
||||||
int (*get_response)(struct hdac_bus *bus, unsigned int addr,
|
int (*get_response)(struct hdac_bus *bus, unsigned int addr,
|
||||||
unsigned int *res);
|
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,
|
int snd_hdac_bus_exec_verb_unlocked(struct hdac_bus *bus, unsigned int addr,
|
||||||
unsigned int cmd, unsigned int *res);
|
unsigned int cmd, unsigned int *res);
|
||||||
|
|
||||||
static inline void snd_hdac_codec_link_up(struct hdac_device *codec)
|
void snd_hdac_codec_link_up(struct hdac_device *codec);
|
||||||
{
|
void snd_hdac_codec_link_down(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);
|
|
||||||
}
|
|
||||||
|
|
||||||
int snd_hdac_bus_send_cmd(struct hdac_bus *bus, unsigned int val);
|
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,
|
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_enter_link_reset(struct hdac_bus *bus);
|
||||||
void snd_hdac_bus_exit_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);
|
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);
|
void snd_hdac_bus_update_rirb(struct hdac_bus *bus);
|
||||||
int snd_hdac_bus_handle_stream_irq(struct hdac_bus *bus, unsigned int status,
|
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_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);
|
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 */
|
/* update register macro */
|
||||||
#define snd_hdac_updatel(addr, reg, mask, val) \
|
#define snd_hdac_updatel(addr, reg, mask, val) \
|
||||||
writel(((readl(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 frame_clk_inv:1;
|
||||||
unsigned int bit_clk_master:1;
|
unsigned int bit_clk_master:1;
|
||||||
unsigned int frame_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];
|
char name[100];
|
||||||
unsigned int key[6]; /* Keep in sync with definitions above */
|
unsigned int key[6]; /* Keep in sync with definitions above */
|
||||||
#endif /* CONFIG_SND_JACK_INPUT_DEV */
|
#endif /* CONFIG_SND_JACK_INPUT_DEV */
|
||||||
|
int hw_status_cache;
|
||||||
void *private_data;
|
void *private_data;
|
||||||
void (*private_free)(struct snd_jack *);
|
void (*private_free)(struct snd_jack *);
|
||||||
};
|
};
|
||||||
|
@ -22,6 +22,8 @@ struct rt5645_platform_data {
|
|||||||
bool level_trigger_irq;
|
bool level_trigger_irq;
|
||||||
/* Invert JD1_1 status polarity */
|
/* Invert JD1_1 status polarity */
|
||||||
bool inv_jd1_1;
|
bool inv_jd1_1;
|
||||||
|
/* Invert HP detect status polarity */
|
||||||
|
bool inv_hp_pol;
|
||||||
|
|
||||||
/* Value to asign to snd_soc_card.long_name */
|
/* Value to asign to snd_soc_card.long_name */
|
||||||
const char *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 reg, unsigned int mask,
|
||||||
unsigned int value);
|
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 */
|
/* component wide operations */
|
||||||
int snd_soc_component_set_sysclk(struct snd_soc_component *component,
|
int snd_soc_component_set_sysclk(struct snd_soc_component *component,
|
||||||
int clk_id, int source,
|
int clk_id, int source,
|
||||||
|
@ -353,9 +353,9 @@ struct snd_soc_dai_driver {
|
|||||||
/* DAI capabilities */
|
/* DAI capabilities */
|
||||||
struct snd_soc_pcm_stream capture;
|
struct snd_soc_pcm_stream capture;
|
||||||
struct snd_soc_pcm_stream playback;
|
struct snd_soc_pcm_stream playback;
|
||||||
unsigned int symmetric_rates:1;
|
unsigned int symmetric_rate:1;
|
||||||
unsigned int symmetric_channels:1;
|
unsigned int symmetric_channels:1;
|
||||||
unsigned int symmetric_samplebits:1;
|
unsigned int symmetric_sample_bits:1;
|
||||||
|
|
||||||
/* probe ordering - for components with runtime dependencies */
|
/* probe ordering - for components with runtime dependencies */
|
||||||
int probe_order;
|
int probe_order;
|
||||||
|
@ -685,9 +685,9 @@ struct snd_soc_dai_link {
|
|||||||
unsigned int ignore_suspend:1;
|
unsigned int ignore_suspend:1;
|
||||||
|
|
||||||
/* Symmetry requirements */
|
/* Symmetry requirements */
|
||||||
unsigned int symmetric_rates:1;
|
unsigned int symmetric_rate:1;
|
||||||
unsigned int symmetric_channels: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) */
|
/* Do not create a PCM for this DAI link (Backend link) */
|
||||||
unsigned int no_pcm:1;
|
unsigned int no_pcm:1;
|
||||||
|
@ -58,9 +58,9 @@ struct sof_ext_man_header {
|
|||||||
/* Extended manifest elements types */
|
/* Extended manifest elements types */
|
||||||
enum sof_ext_man_elem_type {
|
enum sof_ext_man_elem_type {
|
||||||
SOF_EXT_MAN_ELEM_FW_VERSION = 0,
|
SOF_EXT_MAN_ELEM_FW_VERSION = 0,
|
||||||
SOF_EXT_MAN_ELEM_WINDOW = SOF_IPC_EXT_WINDOW,
|
SOF_EXT_MAN_ELEM_WINDOW = 1,
|
||||||
SOF_EXT_MAN_ELEM_CC_VERSION = SOF_IPC_EXT_CC_INFO,
|
SOF_EXT_MAN_ELEM_CC_VERSION = 2,
|
||||||
SOF_EXT_MAN_ELEM_DBG_ABI = SOF_IPC_EXT_USER_ABI_INFO,
|
SOF_EXT_MAN_ELEM_DBG_ABI = 4,
|
||||||
SOF_EXT_MAN_ELEM_CONFIG_DATA = 5, /**< ABI3.17 */
|
SOF_EXT_MAN_ELEM_CONFIG_DATA = 5, /**< ABI3.17 */
|
||||||
SOF_EXT_MAN_ELEM_PLATFORM_CONFIG_DATA = 6,
|
SOF_EXT_MAN_ELEM_PLATFORM_CONFIG_DATA = 6,
|
||||||
};
|
};
|
||||||
|
@ -273,7 +273,7 @@ static struct attribute *ac97_controller_device_attrs[] = {
|
|||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct attribute_group ac97_adapter_attr_group = {
|
static const struct attribute_group ac97_adapter_attr_group = {
|
||||||
.name = "ac97_operations",
|
.name = "ac97_operations",
|
||||||
.attrs = ac97_controller_device_attrs,
|
.attrs = ac97_controller_device_attrs,
|
||||||
};
|
};
|
||||||
|
@ -1013,7 +1013,7 @@ static int onyx_i2c_probe(struct i2c_client *client,
|
|||||||
goto fail;
|
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.owner = THIS_MODULE;
|
||||||
onyx->codec.init = onyx_init_codec;
|
onyx->codec.init = onyx_init_codec;
|
||||||
onyx->codec.exit = onyx_exit_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 */
|
/* seems that half is a saner default */
|
||||||
tas->drc_range = TAS3004_DRC_MAX / 2;
|
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.owner = THIS_MODULE;
|
||||||
tas->codec.init = tas_init_codec;
|
tas->codec.init = tas_init_codec;
|
||||||
tas->codec.exit = tas_exit_codec;
|
tas->codec.exit = tas_exit_codec;
|
||||||
|
@ -126,7 +126,7 @@ static int __init toonie_init(void)
|
|||||||
if (!toonie)
|
if (!toonie)
|
||||||
return -ENOMEM;
|
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.owner = THIS_MODULE;
|
||||||
toonie->codec.init = toonie_init_codec;
|
toonie->codec.init = toonie_init_codec;
|
||||||
toonie->codec.exit = toonie_exit_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;
|
return err;
|
||||||
aoa_card = alsa_card->private_data;
|
aoa_card = alsa_card->private_data;
|
||||||
aoa_card->alsa_card = alsa_card;
|
aoa_card->alsa_card = alsa_card;
|
||||||
strlcpy(alsa_card->driver, "AppleOnbdAudio", sizeof(alsa_card->driver));
|
strscpy(alsa_card->driver, "AppleOnbdAudio", sizeof(alsa_card->driver));
|
||||||
strlcpy(alsa_card->shortname, name, sizeof(alsa_card->shortname));
|
strscpy(alsa_card->shortname, name, sizeof(alsa_card->shortname));
|
||||||
strlcpy(alsa_card->longname, name, sizeof(alsa_card->longname));
|
strscpy(alsa_card->longname, name, sizeof(alsa_card->longname));
|
||||||
strlcpy(alsa_card->mixername, name, sizeof(alsa_card->mixername));
|
strscpy(alsa_card->mixername, name, sizeof(alsa_card->mixername));
|
||||||
err = snd_card_register(aoa_card->alsa_card);
|
err = snd_card_register(aoa_card->alsa_card);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
printk(KERN_ERR "snd-aoa: couldn't register alsa card\n");
|
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);
|
ldev->gpio.methods->set_lineout(codec->gpio, 1);
|
||||||
ctl = snd_ctl_new1(&lineout_ctl, codec->gpio);
|
ctl = snd_ctl_new1(&lineout_ctl, codec->gpio);
|
||||||
if (cc->connected & CC_LINEOUT_LABELLED_HEADPHONE)
|
if (cc->connected & CC_LINEOUT_LABELLED_HEADPHONE)
|
||||||
strlcpy(ctl->id.name,
|
strscpy(ctl->id.name,
|
||||||
"Headphone Switch", sizeof(ctl->id.name));
|
"Headphone Switch", sizeof(ctl->id.name));
|
||||||
ldev->lineout_ctrl = ctl;
|
ldev->lineout_ctrl = ctl;
|
||||||
aoa_snd_ctl_add(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,
|
ctl = snd_ctl_new1(&lineout_detect_choice,
|
||||||
ldev);
|
ldev);
|
||||||
if (cc->connected & CC_LINEOUT_LABELLED_HEADPHONE)
|
if (cc->connected & CC_LINEOUT_LABELLED_HEADPHONE)
|
||||||
strlcpy(ctl->id.name,
|
strscpy(ctl->id.name,
|
||||||
"Headphone Detect Autoswitch",
|
"Headphone Detect Autoswitch",
|
||||||
sizeof(ctl->id.name));
|
sizeof(ctl->id.name));
|
||||||
aoa_snd_ctl_add(ctl);
|
aoa_snd_ctl_add(ctl);
|
||||||
ctl = snd_ctl_new1(&lineout_detected,
|
ctl = snd_ctl_new1(&lineout_detected,
|
||||||
ldev);
|
ldev);
|
||||||
if (cc->connected & CC_LINEOUT_LABELLED_HEADPHONE)
|
if (cc->connected & CC_LINEOUT_LABELLED_HEADPHONE)
|
||||||
strlcpy(ctl->id.name,
|
strscpy(ctl->id.name,
|
||||||
"Headphone Detected",
|
"Headphone Detected",
|
||||||
sizeof(ctl->id.name));
|
sizeof(ctl->id.name));
|
||||||
ldev->lineout_detected_ctrl = ctl;
|
ldev->lineout_detected_ctrl = ctl;
|
||||||
|
@ -13,7 +13,7 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
|
|||||||
int length;
|
int length;
|
||||||
|
|
||||||
if (*sdev->modalias) {
|
if (*sdev->modalias) {
|
||||||
strlcpy(buf, sdev->modalias, sizeof(sdev->modalias) + 1);
|
strscpy(buf, sdev->modalias, sizeof(sdev->modalias) + 1);
|
||||||
strcat(buf, "\n");
|
strcat(buf, "\n");
|
||||||
length = strlen(buf);
|
length = strlen(buf);
|
||||||
} else {
|
} else {
|
||||||
|
@ -890,8 +890,8 @@ static struct aaci *aaci_init_card(struct amba_device *dev)
|
|||||||
|
|
||||||
card->private_free = aaci_free_card;
|
card->private_free = aaci_free_card;
|
||||||
|
|
||||||
strlcpy(card->driver, DRIVER_NAME, sizeof(card->driver));
|
strscpy(card->driver, DRIVER_NAME, sizeof(card->driver));
|
||||||
strlcpy(card->shortname, "ARM AC'97 Interface", sizeof(card->shortname));
|
strscpy(card->shortname, "ARM AC'97 Interface", sizeof(card->shortname));
|
||||||
snprintf(card->longname, sizeof(card->longname),
|
snprintf(card->longname, sizeof(card->longname),
|
||||||
"%s PL%03x rev%u at 0x%08llx, irq %d",
|
"%s PL%03x rev%u at 0x%08llx, irq %d",
|
||||||
card->shortname, amba_part(dev), amba_rev(dev),
|
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->private_data = aaci;
|
||||||
pcm->info_flags = 0;
|
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_PLAYBACK, &aaci_playback_ops);
|
||||||
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &aaci_capture_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)
|
if (ret < 0)
|
||||||
goto err;
|
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);
|
ret = pxa2xx_ac97_pcm_new(card);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@ -187,6 +187,15 @@ config SND_CTL_VALIDATION
|
|||||||
from the driver are in the proper ranges or the check of the invalid
|
from the driver are in the proper ranges or the check of the invalid
|
||||||
access at out-of-array areas.
|
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
|
config SND_VMASTER
|
||||||
bool
|
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)
|
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
|
#else
|
||||||
static inline int snd_compress_proc_init(struct snd_compr *compr)
|
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.device = ncontrol->device;
|
||||||
kctl->id.subdevice = ncontrol->subdevice;
|
kctl->id.subdevice = ncontrol->subdevice;
|
||||||
if (ncontrol->name) {
|
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)
|
if (strcmp(ncontrol->name, kctl->id.name) != 0)
|
||||||
pr_warn("ALSA: Control name '%s' truncated to '%s'\n",
|
pr_warn("ALSA: Control name '%s' truncated to '%s'\n",
|
||||||
ncontrol->name, kctl->id.name);
|
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;
|
return -ENOMEM;
|
||||||
down_read(&snd_ioctl_rwsem);
|
down_read(&snd_ioctl_rwsem);
|
||||||
info->card = card->number;
|
info->card = card->number;
|
||||||
strlcpy(info->id, card->id, sizeof(info->id));
|
strscpy(info->id, card->id, sizeof(info->id));
|
||||||
strlcpy(info->driver, card->driver, sizeof(info->driver));
|
strscpy(info->driver, card->driver, sizeof(info->driver));
|
||||||
strlcpy(info->name, card->shortname, sizeof(info->name));
|
strscpy(info->name, card->shortname, sizeof(info->name));
|
||||||
strlcpy(info->longname, card->longname, sizeof(info->longname));
|
strscpy(info->longname, card->longname, sizeof(info->longname));
|
||||||
strlcpy(info->mixername, card->mixername, sizeof(info->mixername));
|
strscpy(info->mixername, card->mixername, sizeof(info->mixername));
|
||||||
strlcpy(info->components, card->components, sizeof(info->components));
|
strscpy(info->components, card->components, sizeof(info->components));
|
||||||
up_read(&snd_ioctl_rwsem);
|
up_read(&snd_ioctl_rwsem);
|
||||||
if (copy_to_user(arg, info, sizeof(struct snd_ctl_card_info))) {
|
if (copy_to_user(arg, info, sizeof(struct snd_ctl_card_info))) {
|
||||||
kfree(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;
|
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,
|
memset32((u32 *)control->value.bytes.data + offset, pattern,
|
||||||
sizeof(control->value) / sizeof(u32) - offset);
|
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 */
|
/* check whether the remaining area kept untouched */
|
||||||
offset = value_sizes[info->type] * info->count;
|
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;
|
p = (u32 *)control->value.bytes.data + offset;
|
||||||
for (; offset < sizeof(control->value) / sizeof(u32); offset++, p++) {
|
for (; offset < sizeof(control->value) / sizeof(u32); offset++, p++) {
|
||||||
if (*p != pattern) {
|
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),
|
WARN(strlen(names[info->value.enumerated.item]) >= sizeof(info->value.enumerated.name),
|
||||||
"ALSA: too long item name '%s'\n",
|
"ALSA: too long item name '%s'\n",
|
||||||
names[info->value.enumerated.item]);
|
names[info->value.enumerated.item]);
|
||||||
strlcpy(info->value.enumerated.name,
|
strscpy(info->value.enumerated.name,
|
||||||
names[info->value.enumerated.item],
|
names[info->value.enumerated.item],
|
||||||
sizeof(info->value.enumerated.name));
|
sizeof(info->value.enumerated.name));
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -35,7 +35,7 @@ static int get_available_index(struct snd_card *card, const char *name)
|
|||||||
|
|
||||||
sid.index = 0;
|
sid.index = 0;
|
||||||
sid.iface = SNDRV_CTL_ELEM_IFACE_CARD;
|
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)) {
|
while (snd_ctl_find_id(card, &sid)) {
|
||||||
sid.index++;
|
sid.index++;
|
||||||
|
@ -177,8 +177,8 @@ static int snd_hwdep_info(struct snd_hwdep *hw,
|
|||||||
|
|
||||||
memset(&info, 0, sizeof(info));
|
memset(&info, 0, sizeof(info));
|
||||||
info.card = hw->card->number;
|
info.card = hw->card->number;
|
||||||
strlcpy(info.id, hw->id, sizeof(info.id));
|
strscpy(info.id, hw->id, sizeof(info.id));
|
||||||
strlcpy(info.name, hw->name, sizeof(info.name));
|
strscpy(info.name, hw->name, sizeof(info.name));
|
||||||
info.iface = hw->iface;
|
info.iface = hw->iface;
|
||||||
if (copy_to_user(_info, &info, sizeof(info)))
|
if (copy_to_user(_info, &info, sizeof(info)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
@ -379,7 +379,7 @@ int snd_hwdep_new(struct snd_card *card, char *id, int device,
|
|||||||
hwdep->card = card;
|
hwdep->card = card;
|
||||||
hwdep->device = device;
|
hwdep->device = device;
|
||||||
if (id)
|
if (id)
|
||||||
strlcpy(hwdep->id, id, sizeof(hwdep->id));
|
strscpy(hwdep->id, id, sizeof(hwdep->id));
|
||||||
|
|
||||||
snd_device_initialize(&hwdep->dev, card);
|
snd_device_initialize(&hwdep->dev, card);
|
||||||
hwdep->dev.release = release_hwdep_device;
|
hwdep->dev.release = release_hwdep_device;
|
||||||
|
@ -13,7 +13,9 @@
|
|||||||
#include <linux/time.h>
|
#include <linux/time.h>
|
||||||
#include <linux/ctype.h>
|
#include <linux/ctype.h>
|
||||||
#include <linux/pm.h>
|
#include <linux/pm.h>
|
||||||
|
#include <linux/debugfs.h>
|
||||||
#include <linux/completion.h>
|
#include <linux/completion.h>
|
||||||
|
#include <linux/interrupt.h>
|
||||||
|
|
||||||
#include <sound/core.h>
|
#include <sound/core.h>
|
||||||
#include <sound/control.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;
|
struct snd_card *card;
|
||||||
int err;
|
int err;
|
||||||
|
#ifdef CONFIG_SND_DEBUG
|
||||||
|
char name[8];
|
||||||
|
#endif
|
||||||
|
|
||||||
if (snd_BUG_ON(!card_ret))
|
if (snd_BUG_ON(!card_ret))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -174,7 +179,7 @@ int snd_card_new(struct device *parent, int idx, const char *xid,
|
|||||||
if (extra_size > 0)
|
if (extra_size > 0)
|
||||||
card->private_data = (char *)card + sizeof(struct snd_card);
|
card->private_data = (char *)card + sizeof(struct snd_card);
|
||||||
if (xid)
|
if (xid)
|
||||||
strlcpy(card->id, xid, sizeof(card->id));
|
strscpy(card->id, xid, sizeof(card->id));
|
||||||
err = 0;
|
err = 0;
|
||||||
mutex_lock(&snd_card_mutex);
|
mutex_lock(&snd_card_mutex);
|
||||||
if (idx < 0) /* first check the matching module-name slot */
|
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");
|
dev_err(parent, "unable to create card info\n");
|
||||||
goto __error_ctl;
|
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;
|
*card_ret = card;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -416,6 +427,9 @@ int snd_card_disconnect(struct snd_card *card)
|
|||||||
/* notify all devices that we are disconnected */
|
/* notify all devices that we are disconnected */
|
||||||
snd_device_disconnect_all(card);
|
snd_device_disconnect_all(card);
|
||||||
|
|
||||||
|
if (card->sync_irq > 0)
|
||||||
|
synchronize_irq(card->sync_irq);
|
||||||
|
|
||||||
snd_info_card_disconnect(card);
|
snd_info_card_disconnect(card);
|
||||||
if (card->registered) {
|
if (card->registered) {
|
||||||
device_del(&card->card_dev);
|
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");
|
dev_warn(card->dev, "unable to free card info\n");
|
||||||
/* Not fatal error */
|
/* Not fatal error */
|
||||||
}
|
}
|
||||||
|
#ifdef CONFIG_SND_DEBUG
|
||||||
|
debugfs_remove(card->debugfs_root);
|
||||||
|
card->debugfs_root = NULL;
|
||||||
|
#endif
|
||||||
if (card->release_completion)
|
if (card->release_completion)
|
||||||
complete(card->release_completion);
|
complete(card->release_completion);
|
||||||
kfree(card);
|
kfree(card);
|
||||||
@ -526,6 +544,7 @@ int snd_card_free(struct snd_card *card)
|
|||||||
return ret;
|
return ret;
|
||||||
/* wait, until all devices are ready for the free operation */
|
/* wait, until all devices are ready for the free operation */
|
||||||
wait_for_completion(&released);
|
wait_for_completion(&released);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(snd_card_free);
|
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... */
|
/* last resort... */
|
||||||
dev_err(card->dev, "unable to set card id (%s)\n", id);
|
dev_err(card->dev, "unable to set card id (%s)\n", id);
|
||||||
if (card->proc_root->name)
|
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/input.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
#include <linux/ctype.h>
|
||||||
|
#include <linux/mm.h>
|
||||||
|
#include <linux/debugfs.h>
|
||||||
#include <sound/jack.h>
|
#include <sound/jack.h>
|
||||||
#include <sound/core.h>
|
#include <sound/core.h>
|
||||||
#include <sound/control.h>
|
#include <sound/control.h>
|
||||||
@ -16,6 +19,11 @@ struct snd_jack_kctl {
|
|||||||
struct snd_kcontrol *kctl;
|
struct snd_kcontrol *kctl;
|
||||||
struct list_head list; /* list of controls belong to the same jack */
|
struct list_head list; /* list of controls belong to the same jack */
|
||||||
unsigned int mask_bits; /* only masked status bits are reported via kctl */
|
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
|
#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 */
|
#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)
|
static void snd_jack_kctl_private_free(struct snd_kcontrol *kctl)
|
||||||
{
|
{
|
||||||
struct snd_jack_kctl *jack_kctl;
|
struct snd_jack_kctl *jack_kctl;
|
||||||
|
|
||||||
jack_kctl = kctl->private_data;
|
jack_kctl = kctl->private_data;
|
||||||
if (jack_kctl) {
|
if (jack_kctl) {
|
||||||
|
snd_jack_debugfs_clear_inject_node(jack_kctl);
|
||||||
list_del(&jack_kctl->list);
|
list_del(&jack_kctl->list);
|
||||||
kfree(jack_kctl);
|
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)
|
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);
|
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)
|
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)
|
void snd_jack_report(struct snd_jack *jack, int status)
|
||||||
{
|
{
|
||||||
struct snd_jack_kctl *jack_kctl;
|
struct snd_jack_kctl *jack_kctl;
|
||||||
|
unsigned int mask_bits = 0;
|
||||||
#ifdef CONFIG_SND_JACK_INPUT_DEV
|
#ifdef CONFIG_SND_JACK_INPUT_DEV
|
||||||
int i;
|
int i;
|
||||||
#endif
|
#endif
|
||||||
@ -347,16 +637,21 @@ void snd_jack_report(struct snd_jack *jack, int status)
|
|||||||
if (!jack)
|
if (!jack)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
jack->hw_status_cache = status;
|
||||||
|
|
||||||
list_for_each_entry(jack_kctl, &jack->kctl_list, list)
|
list_for_each_entry(jack_kctl, &jack->kctl_list, list)
|
||||||
snd_kctl_jack_report(jack->card, jack_kctl->kctl,
|
if (jack_kctl->sw_inject_enable)
|
||||||
status & jack_kctl->mask_bits);
|
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
|
#ifdef CONFIG_SND_JACK_INPUT_DEV
|
||||||
if (!jack->input_dev)
|
if (!jack->input_dev)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(jack->key); i++) {
|
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)
|
if (jack->type & testbit)
|
||||||
input_report_key(jack->input_dev, jack->key[i],
|
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++) {
|
for (i = 0; i < ARRAY_SIZE(jack_switch_types); i++) {
|
||||||
int testbit = 1 << i;
|
int testbit = ((1 << i) & ~mask_bits);
|
||||||
|
|
||||||
if (jack->type & testbit)
|
if (jack->type & testbit)
|
||||||
input_report_switch(jack->input_dev,
|
input_report_switch(jack->input_dev,
|
||||||
jack_switch_types[i],
|
jack_switch_types[i],
|
||||||
|
@ -87,8 +87,8 @@ static int snd_mixer_oss_info(struct snd_mixer_oss_file *fmixer,
|
|||||||
struct mixer_info info;
|
struct mixer_info info;
|
||||||
|
|
||||||
memset(&info, 0, sizeof(info));
|
memset(&info, 0, sizeof(info));
|
||||||
strlcpy(info.id, mixer && mixer->id[0] ? mixer->id : card->driver, sizeof(info.id));
|
strscpy(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.name, mixer && mixer->name[0] ? mixer->name : card->mixername, sizeof(info.name));
|
||||||
info.modify_counter = card->mixer_oss_change_count;
|
info.modify_counter = card->mixer_oss_change_count;
|
||||||
if (copy_to_user(_info, &info, sizeof(info)))
|
if (copy_to_user(_info, &info, sizeof(info)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
@ -103,8 +103,8 @@ static int snd_mixer_oss_info_obsolete(struct snd_mixer_oss_file *fmixer,
|
|||||||
_old_mixer_info info;
|
_old_mixer_info info;
|
||||||
|
|
||||||
memset(&info, 0, sizeof(info));
|
memset(&info, 0, sizeof(info));
|
||||||
strlcpy(info.id, mixer && mixer->id[0] ? mixer->id : card->driver, sizeof(info.id));
|
strscpy(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.name, mixer && mixer->name[0] ? mixer->name : card->mixername, sizeof(info.name));
|
||||||
if (copy_to_user(_info, &info, sizeof(info)))
|
if (copy_to_user(_info, &info, sizeof(info)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
return 0;
|
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)
|
if (orange == 0)
|
||||||
return 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) */
|
/* 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));
|
memset(&id, 0, sizeof(id));
|
||||||
id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
|
id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
|
||||||
strlcpy(id.name, name, sizeof(id.name));
|
strscpy(id.name, name, sizeof(id.name));
|
||||||
id.index = index;
|
id.index = index;
|
||||||
return snd_ctl_find_id(card, &id);
|
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->oss_dev_alloc = 1;
|
||||||
mixer->card = card;
|
mixer->card = card;
|
||||||
if (*card->mixername)
|
if (*card->mixername)
|
||||||
strlcpy(mixer->name, card->mixername, sizeof(mixer->name));
|
strscpy(mixer->name, card->mixername, sizeof(mixer->name));
|
||||||
else
|
else
|
||||||
snprintf(mixer->name, sizeof(mixer->name),
|
snprintf(mixer->name, sizeof(mixer->name),
|
||||||
"mixer%i", card->number);
|
"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) {
|
if (plugin->src_format.rate < plugin->dst_format.rate) {
|
||||||
res = (((frames * data->pitch) + (BITS/2)) >> SHIFT);
|
res = (((frames * data->pitch) + (BITS/2)) >> SHIFT);
|
||||||
} else {
|
} else {
|
||||||
res = (((frames << SHIFT) + (data->pitch / 2)) / data->pitch);
|
res = DIV_ROUND_CLOSEST(frames << SHIFT, data->pitch);
|
||||||
}
|
}
|
||||||
if (data->old_src_frames > 0) {
|
if (data->old_src_frames > 0) {
|
||||||
snd_pcm_sframes_t frames1 = frames, res1 = data->old_dst_frames;
|
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;
|
return 0;
|
||||||
data = (struct rate_priv *)plugin->extra_data;
|
data = (struct rate_priv *)plugin->extra_data;
|
||||||
if (plugin->src_format.rate < plugin->dst_format.rate) {
|
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 {
|
} else {
|
||||||
res = (((frames * data->pitch) + (BITS/2)) >> SHIFT);
|
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_waitqueue_head(&pcm->open_wait);
|
||||||
INIT_LIST_HEAD(&pcm->list);
|
INIT_LIST_HEAD(&pcm->list);
|
||||||
if (id)
|
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,
|
err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_PLAYBACK,
|
||||||
playback_count);
|
playback_count);
|
||||||
@ -1095,22 +1095,23 @@ static int snd_pcm_dev_disconnect(struct snd_device *device)
|
|||||||
mutex_lock(&pcm->open_mutex);
|
mutex_lock(&pcm->open_mutex);
|
||||||
wake_up(&pcm->open_wait);
|
wake_up(&pcm->open_wait);
|
||||||
list_del_init(&pcm->list);
|
list_del_init(&pcm->list);
|
||||||
for (cidx = 0; cidx < 2; cidx++) {
|
|
||||||
for (substream = pcm->streams[cidx].substream; substream; substream = substream->next) {
|
for_each_pcm_substream(pcm, cidx, substream) {
|
||||||
snd_pcm_stream_lock_irq(substream);
|
snd_pcm_stream_lock_irq(substream);
|
||||||
if (substream->runtime) {
|
if (substream->runtime) {
|
||||||
if (snd_pcm_running(substream))
|
if (snd_pcm_running(substream))
|
||||||
snd_pcm_stop(substream,
|
snd_pcm_stop(substream, SNDRV_PCM_STATE_DISCONNECTED);
|
||||||
SNDRV_PCM_STATE_DISCONNECTED);
|
/* to be sure, set the state unconditionally */
|
||||||
/* to be sure, set the state unconditionally */
|
substream->runtime->status->state = SNDRV_PCM_STATE_DISCONNECTED;
|
||||||
substream->runtime->status->state = SNDRV_PCM_STATE_DISCONNECTED;
|
wake_up(&substream->runtime->sleep);
|
||||||
wake_up(&substream->runtime->sleep);
|
wake_up(&substream->runtime->tsleep);
|
||||||
wake_up(&substream->runtime->tsleep);
|
|
||||||
}
|
|
||||||
snd_pcm_stream_unlock_irq(substream);
|
|
||||||
}
|
}
|
||||||
|
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);
|
pcm_call_notify(pcm, n_disconnect);
|
||||||
for (cidx = 0; cidx < 2; cidx++) {
|
for (cidx = 0; cidx < 2; cidx++) {
|
||||||
snd_unregister_device(&pcm->streams[cidx].dev);
|
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->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);
|
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_xrun(struct snd_pcm_substream *substream);
|
||||||
void snd_pcm_group_init(struct snd_pcm_group *group);
|
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
|
#ifdef CONFIG_SND_DMA_SGBUF
|
||||||
struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream,
|
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)
|
#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 */
|
#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;
|
struct snd_pcm_substream *substream;
|
||||||
int stream;
|
int stream;
|
||||||
|
|
||||||
for (stream = 0; stream < 2; stream++)
|
for_each_pcm_substream(pcm, stream, substream)
|
||||||
for (substream = pcm->streams[stream].substream; substream; substream = substream->next)
|
snd_pcm_lib_preallocate_free(substream);
|
||||||
snd_pcm_lib_preallocate_free(substream);
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(snd_pcm_lib_preallocate_free_for_all);
|
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;
|
struct snd_pcm_substream *substream;
|
||||||
int stream;
|
int stream;
|
||||||
|
|
||||||
for (stream = 0; stream < 2; stream++)
|
for_each_pcm_substream(pcm, stream, substream)
|
||||||
for (substream = pcm->streams[stream].substream; substream;
|
preallocate_pages(substream, type, data, size, max, managed);
|
||||||
substream = substream->next)
|
|
||||||
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->device = pcm->device;
|
||||||
info->stream = substream->stream;
|
info->stream = substream->stream;
|
||||||
info->subdevice = substream->number;
|
info->subdevice = substream->number;
|
||||||
strlcpy(info->id, pcm->id, sizeof(info->id));
|
strscpy(info->id, pcm->id, sizeof(info->id));
|
||||||
strlcpy(info->name, pcm->name, sizeof(info->name));
|
strscpy(info->name, pcm->name, sizeof(info->name));
|
||||||
info->dev_class = pcm->dev_class;
|
info->dev_class = pcm->dev_class;
|
||||||
info->dev_subclass = pcm->dev_subclass;
|
info->dev_subclass = pcm->dev_subclass;
|
||||||
info->subdevices_count = pstr->substream_count;
|
info->subdevices_count = pstr->substream_count;
|
||||||
info->subdevices_avail = pstr->substream_count - pstr->substream_opened;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -583,13 +583,13 @@ static inline void snd_pcm_timer_notify(struct snd_pcm_substream *substream,
|
|||||||
#endif
|
#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;
|
substream->runtime->stop_operating = false;
|
||||||
if (substream->ops->sync_stop)
|
if (substream->ops && substream->ops->sync_stop)
|
||||||
substream->ops->sync_stop(substream);
|
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);
|
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))
|
if (atomic_read(&substream->mmap_count))
|
||||||
return -EBADFD;
|
return -EBADFD;
|
||||||
|
|
||||||
snd_pcm_sync_stop(substream);
|
snd_pcm_sync_stop(substream, true);
|
||||||
|
|
||||||
params->rmask = ~0U;
|
params->rmask = ~0U;
|
||||||
err = snd_pcm_hw_refine(substream, params);
|
err = snd_pcm_hw_refine(substream, params);
|
||||||
@ -809,7 +809,7 @@ static int do_hw_free(struct snd_pcm_substream *substream)
|
|||||||
{
|
{
|
||||||
int result = 0;
|
int result = 0;
|
||||||
|
|
||||||
snd_pcm_sync_stop(substream);
|
snd_pcm_sync_stop(substream, true);
|
||||||
if (substream->ops->hw_free)
|
if (substream->ops->hw_free)
|
||||||
result = substream->ops->hw_free(substream);
|
result = substream->ops->hw_free(substream);
|
||||||
if (substream->managed_buffer_alloc)
|
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)
|
snd_pcm_state_t state)
|
||||||
{
|
{
|
||||||
if (substream->runtime->trigger_master == substream &&
|
if (substream->runtime->trigger_master == substream &&
|
||||||
snd_pcm_running(substream))
|
snd_pcm_running(substream)) {
|
||||||
substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_STOP);
|
substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_STOP);
|
||||||
|
substream->runtime->stop_operating = true;
|
||||||
|
}
|
||||||
return 0; /* unconditonally stop all substreams */
|
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;
|
runtime->status->state = state;
|
||||||
snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MSTOP);
|
snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MSTOP);
|
||||||
}
|
}
|
||||||
runtime->stop_operating = true;
|
|
||||||
wake_up(&runtime->sleep);
|
wake_up(&runtime->sleep);
|
||||||
wake_up(&runtime->tsleep);
|
wake_up(&runtime->tsleep);
|
||||||
}
|
}
|
||||||
@ -1615,6 +1616,7 @@ static int snd_pcm_do_suspend(struct snd_pcm_substream *substream,
|
|||||||
if (! snd_pcm_running(substream))
|
if (! snd_pcm_running(substream))
|
||||||
return 0;
|
return 0;
|
||||||
substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_SUSPEND);
|
substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_SUSPEND);
|
||||||
|
runtime->stop_operating = true;
|
||||||
return 0; /* suspend unconditionally */
|
return 0; /* suspend unconditionally */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1672,25 +1674,26 @@ int snd_pcm_suspend_all(struct snd_pcm *pcm)
|
|||||||
if (! pcm)
|
if (! pcm)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
for (stream = 0; stream < 2; stream++) {
|
for_each_pcm_substream(pcm, stream, substream) {
|
||||||
for (substream = pcm->streams[stream].substream;
|
/* FIXME: the open/close code should lock this as well */
|
||||||
substream; substream = substream->next) {
|
if (!substream->runtime)
|
||||||
/* FIXME: the open/close code should lock this as well */
|
continue;
|
||||||
if (substream->runtime == NULL)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Skip BE dai link PCM's that are internal and may
|
* Skip BE dai link PCM's that are internal and may
|
||||||
* not have their substream ops set.
|
* not have their substream ops set.
|
||||||
*/
|
*/
|
||||||
if (!substream->ops)
|
if (!substream->ops)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
err = snd_pcm_suspend(substream);
|
err = snd_pcm_suspend(substream);
|
||||||
if (err < 0 && err != -EBUSY)
|
if (err < 0 && err != -EBUSY)
|
||||||
return err;
|
return err;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for_each_pcm_substream(pcm, stream, substream)
|
||||||
|
snd_pcm_sync_stop(substream, false);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(snd_pcm_suspend_all);
|
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);
|
snd_pcm_trigger_tstamp(substream);
|
||||||
runtime->status->state = runtime->status->suspended_state;
|
runtime->status->state = runtime->status->suspended_state;
|
||||||
snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MRESUME);
|
snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MRESUME);
|
||||||
snd_pcm_sync_stop(substream);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct action_ops snd_pcm_action_resume = {
|
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)
|
snd_pcm_state_t state)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
snd_pcm_sync_stop(substream);
|
snd_pcm_sync_stop(substream, true);
|
||||||
err = substream->ops->prepare(substream);
|
err = substream->ops->prepare(substream);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
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);
|
INIT_LIST_HEAD(&rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams);
|
||||||
|
|
||||||
if (id != NULL)
|
if (id != NULL)
|
||||||
strlcpy(rmidi->id, id, sizeof(rmidi->id));
|
strscpy(rmidi->id, id, sizeof(rmidi->id));
|
||||||
|
|
||||||
snd_device_initialize(&rmidi->dev, card);
|
snd_device_initialize(&rmidi->dev, card);
|
||||||
rmidi->dev.release = release_rawmidi_device;
|
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);
|
snd_use_lock_init(&mdev->use_lock);
|
||||||
|
|
||||||
/* copy and truncate the name of synth device */
|
/* 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 */
|
/* create MIDI coder */
|
||||||
if (snd_midi_event_new(MAX_MIDI_EVENT_BUF, &mdev->coder) < 0) {
|
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->device = dev;
|
||||||
inf->dev_type = 0; /* FIXME: ?? */
|
inf->dev_type = 0; /* FIXME: ?? */
|
||||||
inf->capabilities = 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);
|
snd_use_lock_free(&mdev->use_lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -107,7 +107,7 @@ snd_seq_oss_synth_probe(struct device *_dev)
|
|||||||
snd_use_lock_init(&rec->use_lock);
|
snd_use_lock_init(&rec->use_lock);
|
||||||
|
|
||||||
/* copy and truncate the name of synth device */
|
/* 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 */
|
/* registration */
|
||||||
spin_lock_irqsave(®ister_lock, flags);
|
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->synth_subtype = 0;
|
||||||
inf->nr_voices = 16;
|
inf->nr_voices = 16;
|
||||||
inf->device = dev;
|
inf->device = dev;
|
||||||
strlcpy(inf->name, minf.name, sizeof(inf->name));
|
strscpy(inf->name, minf.name, sizeof(inf->name));
|
||||||
} else {
|
} else {
|
||||||
if ((rec = get_synthdev(dp, dev)) == NULL)
|
if ((rec = get_synthdev(dp, dev)) == NULL)
|
||||||
return -ENXIO;
|
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->synth_subtype = rec->synth_subtype;
|
||||||
inf->nr_voices = rec->nr_voices;
|
inf->nr_voices = rec->nr_voices;
|
||||||
inf->device = dev;
|
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);
|
snd_use_lock_free(&rec->use_lock);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1584,7 +1584,7 @@ static int snd_seq_ioctl_get_queue_info(struct snd_seq_client *client,
|
|||||||
info->queue = q->queue;
|
info->queue = q->queue;
|
||||||
info->owner = q->owner;
|
info->owner = q->owner;
|
||||||
info->locked = q->locked;
|
info->locked = q->locked;
|
||||||
strlcpy(info->name, q->name, sizeof(info->name));
|
strscpy(info->name, q->name, sizeof(info->name));
|
||||||
queuefree(q);
|
queuefree(q);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -290,7 +290,7 @@ int snd_seq_event_dup(struct snd_seq_pool *pool, struct snd_seq_event *event,
|
|||||||
extlen = 0;
|
extlen = 0;
|
||||||
if (snd_seq_ev_is_variable(event)) {
|
if (snd_seq_ev_is_variable(event)) {
|
||||||
extlen = event->data.ext.len & ~SNDRV_SEQ_EXT_MASK;
|
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)
|
if (ncells >= pool->total_elements)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@ -327,7 +327,7 @@ int snd_seq_set_port_info(struct snd_seq_client_port * port,
|
|||||||
|
|
||||||
/* set port name */
|
/* set port name */
|
||||||
if (info->name[0])
|
if (info->name[0])
|
||||||
strlcpy(port->name, info->name, sizeof(port->name));
|
strscpy(port->name, info->name, sizeof(port->name));
|
||||||
|
|
||||||
/* set capabilities */
|
/* set capabilities */
|
||||||
port->capability = info->capability;
|
port->capability = info->capability;
|
||||||
@ -356,7 +356,7 @@ int snd_seq_get_port_info(struct snd_seq_client_port * port,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/* get port name */
|
/* get port name */
|
||||||
strlcpy(info->name, port->name, sizeof(info->name));
|
strscpy(info->name, port->name, sizeof(info->name));
|
||||||
|
|
||||||
/* get capabilities */
|
/* get capabilities */
|
||||||
info->capability = port->capability;
|
info->capability = port->capability;
|
||||||
@ -654,7 +654,7 @@ int snd_seq_event_port_attach(int client,
|
|||||||
/* Set up the port */
|
/* Set up the port */
|
||||||
memset(&portinfo, 0, sizeof(portinfo));
|
memset(&portinfo, 0, sizeof(portinfo));
|
||||||
portinfo.addr.client = client;
|
portinfo.addr.client = client;
|
||||||
strlcpy(portinfo.name, portname ? portname : "Unnamed port",
|
strscpy(portinfo.name, portname ? portname : "Unnamed port",
|
||||||
sizeof(portinfo.name));
|
sizeof(portinfo.name));
|
||||||
|
|
||||||
portinfo.capability = cap;
|
portinfo.capability = cap;
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include <linux/time.h>
|
#include <linux/time.h>
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
#include <linux/debugfs.h>
|
||||||
#include <sound/core.h>
|
#include <sound/core.h>
|
||||||
#include <sound/minors.h>
|
#include <sound/minors.h>
|
||||||
#include <sound/info.h>
|
#include <sound/info.h>
|
||||||
@ -39,6 +40,11 @@ MODULE_ALIAS_CHARDEV_MAJOR(CONFIG_SND_MAJOR);
|
|||||||
int snd_ecards_limit;
|
int snd_ecards_limit;
|
||||||
EXPORT_SYMBOL(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 struct snd_minor *snd_minors[SNDRV_OS_MINORS];
|
||||||
static DEFINE_MUTEX(sound_mutex);
|
static DEFINE_MUTEX(sound_mutex);
|
||||||
|
|
||||||
@ -337,6 +343,8 @@ static const char *snd_device_type_name(int type)
|
|||||||
return "sequencer";
|
return "sequencer";
|
||||||
case SNDRV_DEVICE_TYPE_TIMER:
|
case SNDRV_DEVICE_TYPE_TIMER:
|
||||||
return "timer";
|
return "timer";
|
||||||
|
case SNDRV_DEVICE_TYPE_COMPRESS:
|
||||||
|
return "compress";
|
||||||
default:
|
default:
|
||||||
return "?";
|
return "?";
|
||||||
}
|
}
|
||||||
@ -395,6 +403,10 @@ static int __init alsa_sound_init(void)
|
|||||||
unregister_chrdev(major, "alsa");
|
unregister_chrdev(major, "alsa");
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_SND_DEBUG
|
||||||
|
sound_debugfs_root = debugfs_create_dir("sound", NULL);
|
||||||
|
#endif
|
||||||
#ifndef MODULE
|
#ifndef MODULE
|
||||||
pr_info("Advanced Linux Sound Architecture Driver Initialized.\n");
|
pr_info("Advanced Linux Sound Architecture Driver Initialized.\n");
|
||||||
#endif
|
#endif
|
||||||
@ -403,6 +415,9 @@ static int __init alsa_sound_init(void)
|
|||||||
|
|
||||||
static void __exit alsa_sound_exit(void)
|
static void __exit alsa_sound_exit(void)
|
||||||
{
|
{
|
||||||
|
#ifdef CONFIG_SND_DEBUG
|
||||||
|
debugfs_remove(sound_debugfs_root);
|
||||||
|
#endif
|
||||||
snd_info_done();
|
snd_info_done();
|
||||||
unregister_chrdev(major, "alsa");
|
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_device = tid->device;
|
||||||
timer->tmr_subdevice = tid->subdevice;
|
timer->tmr_subdevice = tid->subdevice;
|
||||||
if (id)
|
if (id)
|
||||||
strlcpy(timer->id, id, sizeof(timer->id));
|
strscpy(timer->id, id, sizeof(timer->id));
|
||||||
timer->sticks = 1;
|
timer->sticks = 1;
|
||||||
INIT_LIST_HEAD(&timer->device_list);
|
INIT_LIST_HEAD(&timer->device_list);
|
||||||
INIT_LIST_HEAD(&timer->open_list_head);
|
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;
|
ginfo->card = t->card ? t->card->number : -1;
|
||||||
if (t->hw.flags & SNDRV_TIMER_HW_SLAVE)
|
if (t->hw.flags & SNDRV_TIMER_HW_SLAVE)
|
||||||
ginfo->flags |= SNDRV_TIMER_FLG_SLAVE;
|
ginfo->flags |= SNDRV_TIMER_FLG_SLAVE;
|
||||||
strlcpy(ginfo->id, t->id, sizeof(ginfo->id));
|
strscpy(ginfo->id, t->id, sizeof(ginfo->id));
|
||||||
strlcpy(ginfo->name, t->name, sizeof(ginfo->name));
|
strscpy(ginfo->name, t->name, sizeof(ginfo->name));
|
||||||
ginfo->resolution = t->hw.resolution;
|
ginfo->resolution = t->hw.resolution;
|
||||||
if (t->hw.resolution_min > 0) {
|
if (t->hw.resolution_min > 0) {
|
||||||
ginfo->resolution_min = t->hw.resolution_min;
|
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;
|
info->card = t->card ? t->card->number : -1;
|
||||||
if (t->hw.flags & SNDRV_TIMER_HW_SLAVE)
|
if (t->hw.flags & SNDRV_TIMER_HW_SLAVE)
|
||||||
info->flags |= SNDRV_TIMER_FLG_SLAVE;
|
info->flags |= SNDRV_TIMER_FLG_SLAVE;
|
||||||
strlcpy(info->id, t->id, sizeof(info->id));
|
strscpy(info->id, t->id, sizeof(info->id));
|
||||||
strlcpy(info->name, t->name, sizeof(info->name));
|
strscpy(info->name, t->name, sizeof(info->name));
|
||||||
info->resolution = t->hw.resolution;
|
info->resolution = t->hw.resolution;
|
||||||
if (copy_to_user(_info, info, sizeof(*_info)))
|
if (copy_to_user(_info, info, sizeof(*_info)))
|
||||||
err = -EFAULT;
|
err = -EFAULT;
|
||||||
|
@ -61,8 +61,8 @@ static int snd_timer_user_info_compat(struct file *file,
|
|||||||
info.card = t->card ? t->card->number : -1;
|
info.card = t->card ? t->card->number : -1;
|
||||||
if (t->hw.flags & SNDRV_TIMER_HW_SLAVE)
|
if (t->hw.flags & SNDRV_TIMER_HW_SLAVE)
|
||||||
info.flags |= SNDRV_TIMER_FLG_SLAVE;
|
info.flags |= SNDRV_TIMER_FLG_SLAVE;
|
||||||
strlcpy(info.id, t->id, sizeof(info.id));
|
strscpy(info.id, t->id, sizeof(info.id));
|
||||||
strlcpy(info.name, t->name, sizeof(info.name));
|
strscpy(info.name, t->name, sizeof(info.name));
|
||||||
info.resolution = t->hw.resolution;
|
info.resolution = t->hw.resolution;
|
||||||
if (copy_to_user(_info, &info, sizeof(*_info)))
|
if (copy_to_user(_info, &info, sizeof(*_info)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
@ -219,7 +219,7 @@ static int loopback_jiffies_timer_start(struct loopback_pcm *dpcm)
|
|||||||
dpcm->period_update_pending = 1;
|
dpcm->period_update_pending = 1;
|
||||||
}
|
}
|
||||||
tick = dpcm->period_size_frac - dpcm->irq_pos;
|
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);
|
mod_timer(&dpcm->timer, jiffies + tick);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -236,7 +236,7 @@ struct dummy_systimer_pcm {
|
|||||||
static void dummy_systimer_rearm(struct dummy_systimer_pcm *dpcm)
|
static void dummy_systimer_rearm(struct dummy_systimer_pcm *dpcm)
|
||||||
{
|
{
|
||||||
mod_timer(&dpcm->timer, jiffies +
|
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)
|
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;
|
return;
|
||||||
|
|
||||||
opl3->oss_seq_dev = dev;
|
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 = SNDRV_SEQ_DEVICE_ARGPTR(dev);
|
||||||
arg->type = SYNTH_TYPE_FM;
|
arg->type = SYNTH_TYPE_FM;
|
||||||
if (opl3->hardware < OPL3_HW_OPL3) {
|
if (opl3->hardware < OPL3_HW_OPL3) {
|
||||||
|
@ -290,7 +290,7 @@ int snd_opl3_load_patch(struct snd_opl3 *opl3,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (name)
|
if (name)
|
||||||
strlcpy(patch->name, name, sizeof(patch->name));
|
strscpy(patch->name, name, sizeof(patch->name));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1154,8 +1154,7 @@ static int vx_init_audio_io(struct vx_core *chip)
|
|||||||
chip->ibl.size = 0;
|
chip->ibl.size = 0;
|
||||||
vx_set_ibl(chip, &chip->ibl); /* query the info */
|
vx_set_ibl(chip, &chip->ibl); /* query the info */
|
||||||
if (preferred > 0) {
|
if (preferred > 0) {
|
||||||
chip->ibl.size = ((preferred + chip->ibl.granularity - 1) /
|
chip->ibl.size = roundup(preferred, chip->ibl.granularity);
|
||||||
chip->ibl.granularity) * chip->ibl.granularity;
|
|
||||||
if (chip->ibl.size > chip->ibl.max_size)
|
if (chip->ibl.size > chip->ibl.max_size)
|
||||||
chip->ibl.size = chip->ibl.max_size;
|
chip->ibl.size = chip->ibl.max_size;
|
||||||
} else
|
} else
|
||||||
|
@ -37,11 +37,9 @@ hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count,
|
|||||||
|
|
||||||
memset(&event, 0, sizeof(event));
|
memset(&event, 0, sizeof(event));
|
||||||
count = min_t(long, count, sizeof(event.lock_status));
|
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.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS;
|
event.lock_status.status = (bebob->dev_lock_count > 0);
|
||||||
event.lock_status.status = (bebob->dev_lock_count > 0);
|
bebob->dev_lock_changed = false;
|
||||||
bebob->dev_lock_changed = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_unlock_irq(&bebob->lock);
|
spin_unlock_irq(&bebob->lock);
|
||||||
|
|
||||||
@ -80,7 +78,7 @@ hwdep_get_info(struct snd_bebob *bebob, void __user *arg)
|
|||||||
info.card = dev->card->index;
|
info.card = dev->card->index;
|
||||||
*(__be32 *)&info.guid[0] = cpu_to_be32(dev->config_rom[3]);
|
*(__be32 *)&info.guid[0] = cpu_to_be32(dev->config_rom[3]);
|
||||||
*(__be32 *)&info.guid[4] = cpu_to_be32(dev->config_rom[4]);
|
*(__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));
|
sizeof(info.device_name));
|
||||||
|
|
||||||
if (copy_to_user(arg, &info, sizeof(info)))
|
if (copy_to_user(arg, &info, sizeof(info)))
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0-only
|
# SPDX-License-Identifier: GPL-2.0-only
|
||||||
snd-dice-objs := dice-transaction.o dice-stream.o dice-proc.o dice-midi.o \
|
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-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
|
obj-$(CONFIG_SND_DICE) += snd-dice.o
|
||||||
|
26
sound/firewire/dice/dice-harman.c
Normal file
26
sound/firewire/dice/dice-harman.c
Normal file
@ -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;
|
info.card = dev->card->index;
|
||||||
*(__be32 *)&info.guid[0] = cpu_to_be32(dev->config_rom[3]);
|
*(__be32 *)&info.guid[0] = cpu_to_be32(dev->config_rom[3]);
|
||||||
*(__be32 *)&info.guid[4] = cpu_to_be32(dev->config_rom[4]);
|
*(__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));
|
sizeof(info.device_name));
|
||||||
|
|
||||||
if (copy_to_user(arg, &info, sizeof(info)))
|
if (copy_to_user(arg, &info, sizeof(info)))
|
||||||
|
@ -20,10 +20,12 @@ MODULE_LICENSE("GPL v2");
|
|||||||
#define OUI_MYTEK 0x001ee8
|
#define OUI_MYTEK 0x001ee8
|
||||||
#define OUI_SSL 0x0050c2 // Actually ID reserved by IEEE.
|
#define OUI_SSL 0x0050c2 // Actually ID reserved by IEEE.
|
||||||
#define OUI_PRESONUS 0x000a92
|
#define OUI_PRESONUS 0x000a92
|
||||||
|
#define OUI_HARMAN 0x000fd7
|
||||||
|
|
||||||
#define DICE_CATEGORY_ID 0x04
|
#define DICE_CATEGORY_ID 0x04
|
||||||
#define WEISS_CATEGORY_ID 0x00
|
#define WEISS_CATEGORY_ID 0x00
|
||||||
#define LOUD_CATEGORY_ID 0x10
|
#define LOUD_CATEGORY_ID 0x10
|
||||||
|
#define HARMAN_CATEGORY_ID 0x20
|
||||||
|
|
||||||
#define MODEL_ALESIS_IO_BOTH 0x000001
|
#define MODEL_ALESIS_IO_BOTH 0x000001
|
||||||
|
|
||||||
@ -56,6 +58,8 @@ static int check_dice_category(struct fw_unit *unit)
|
|||||||
category = WEISS_CATEGORY_ID;
|
category = WEISS_CATEGORY_ID;
|
||||||
else if (vendor == OUI_LOUD)
|
else if (vendor == OUI_LOUD)
|
||||||
category = LOUD_CATEGORY_ID;
|
category = LOUD_CATEGORY_ID;
|
||||||
|
else if (vendor == OUI_HARMAN)
|
||||||
|
category = HARMAN_CATEGORY_ID;
|
||||||
else
|
else
|
||||||
category = DICE_CATEGORY_ID;
|
category = DICE_CATEGORY_ID;
|
||||||
if (device->config_rom[3] != ((vendor << 8) | category) ||
|
if (device->config_rom[3] != ((vendor << 8) | category) ||
|
||||||
@ -388,6 +392,14 @@ static const struct ieee1394_device_id dice_id_table[] = {
|
|||||||
.model_id = 0x000008,
|
.model_id = 0x000008,
|
||||||
.driver_data = (kernel_ulong_t)snd_dice_detect_presonus_formats,
|
.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,
|
.match_flags = IEEE1394_MATCH_VERSION,
|
||||||
.version = DICE_INTERFACE,
|
.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_extension_formats(struct snd_dice *dice);
|
||||||
int snd_dice_detect_mytek_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_presonus_formats(struct snd_dice *dice);
|
||||||
|
int snd_dice_detect_harman_formats(struct snd_dice *dice);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -87,7 +87,7 @@ static int hwdep_get_info(struct snd_dg00x *dg00x, void __user *arg)
|
|||||||
info.card = dev->card->index;
|
info.card = dev->card->index;
|
||||||
*(__be32 *)&info.guid[0] = cpu_to_be32(dev->config_rom[3]);
|
*(__be32 *)&info.guid[0] = cpu_to_be32(dev->config_rom[3]);
|
||||||
*(__be32 *)&info.guid[4] = cpu_to_be32(dev->config_rom[4]);
|
*(__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));
|
sizeof(info.device_name));
|
||||||
|
|
||||||
if (copy_to_user(arg, &info, sizeof(info)))
|
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
Block a user