sound updates for 4.15-rc1

There are no big surprising changes in this cycle, yet not too
 boring, either.  The biggest change from diffstat POV is the removal
 of the legacy OSS driver codes that have been already disabled for a
 long time.  This will bring a few trivial merge conflicts.
 
 As new features in ASoC side, there are two things: a new AC97 bus
 implementation and AMD Stony platform support.  Both include the
 relevant changes shared with other subsystems, e.g. AC97 MFD changes
 and DRM AMD changes.
 
 Some other highlighted topics are:
 - A bunch of USB-audio drivers got the hardening against the malicious
   device accesses with a new helper code for endpoint sanity check.
 - Lots of cleanups for ASoC Intel platform code, including support for
   their open source audio firmware.
 - Continued ASoC core componentization works.
 - Support for scaling MCLK with sample rate in ASoC simple-card.
 - Stabler PCM hot-unplug capability, especially for ASoC usages.
 -----BEGIN PGP SIGNATURE-----
 
 iQJCBAABCAAsFiEECxfAB4MH3rD5mfB6bDGAVD0pKaQFAloLAk4OHHRpd2FpQHN1
 c2UuZGUACgkQbDGAVD0pKaSCjw/+LUcMsAtjsdjP/GojqxI3FwK5R5e1vLmg+3lD
 TvWbVH23DqASvMhuar9N1Z+yiBWVuU6qa7eElqgOUUopo0Wlyf/93drqwKhqmFgH
 PVYxa3zKu7otU7SghfBVvpivAtvTlsyUVKnSXfL4DQQwXlqvdToQj3+J4eckiqVP
 u02fxn+h7lviLdRFhB+5JAJIK5nupcol1GIxbHwtELBCeoMAXjTbXTz5QToJizPp
 lMuzYLb1tvp7QrpYI5PgZ6YnAfA2GL7cCPMwdx63d8NYGtiWJd+iCtc/fM1WkElm
 8Py0yNvy1gHrjgQpku6Db1mhXNYYbu1qCKfLLMS4W8VOFkZughLNKLLqPQ+Eev5p
 PoHgGZLrCJk2W+vgF6nvoaw5AkZKKmKxzKYH9/gvvFkWrR1BW21XdLLRBm+TOahF
 Bj/c5t1k5WX4FVxotd78h3JVLY9Te+3re5Ak5cb0eGYE5+LHWX9tbObM7zfeZGv2
 5kw8cGTekcYkrKhh/HrORw8mEUFBRJfXfbUn+pIde6P56nJRa43JpE6JhXqstUpL
 n22DxUSIH8DWGkzWXGOmoOSFBolfcsOqTuws2QcT5oRfLnGikRCMii5UeLoW899i
 zlMmxfYSXOgjyWPXhvNROV5vEYNQZDiypjCoq0qbt+uy/mGne+L5ZFCbdJf4rIS/
 rKW4ILU=
 =BCBK
 -----END PGP SIGNATURE-----

Merge tag 'sound-4.15-rc1' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/tiwai/sound

Pull sound updates from Takashi Iwai:
 "There are no big surprising changes in this cycle, yet not too boring,
  either. The biggest change from diffstat POV is the removal of the
  legacy OSS driver codes that have been already disabled for a long
  time. This will bring a few trivial merge conflicts.

  As new features in ASoC side, there are two things: a new AC97 bus
  implementation and AMD Stony platform support. Both include the
  relevant changes shared with other subsystems, e.g. AC97 MFD changes
  and DRM AMD changes.

  Some other highlighted topics are:

   - A bunch of USB-audio drivers got the hardening against the
     malicious device accesses with a new helper code for endpoint
     sanity check

   - Lots of cleanups for ASoC Intel platform code, including support
     for their open source audio firmware

   - Continued ASoC core componentization works

   - Support for scaling MCLK with sample rate in ASoC simple-card

   - Stabler PCM hot-unplug capability, especially for ASoC usages"

* tag 'sound-4.15-rc1' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (302 commits)
  Documentation: sound: hd-audio: notes.rst
  ASoC: bcm2835: Support left/right justified and DSP modes
  ASoC: bcm2835: Enforce full symmetry
  ASoC: bcm2835: Support additional samplerates up to 384kHz
  ASoC: bcm2835: Add support for TDM modes
  ASoC: add mclk-fs support to audio graph card
  ASoC: add mclk-fs to audio graph card binding
  ASoC: rt5514: work around link error
  ASoC: rt5514: mark PM functions as __maybe_unused
  ASoC: rt5663: Check the JD status in the button pushing
  ASoC: amd: Modified DMA transfer Mechanism for Playback
  ASoC: rt5645: Wait for 400msec before concluding on value of RT5645_VENDOR_ID2
  ASoC: sun4i-codec: fixed 32bit audio capture support for H3/H2+
  ASoC: da7213: add support for DSP modes
  ASoC: sun8i-codec: Add a comment on the LRCK inversion
  ASoC: sun8i-codec: Set the BCLK divider
  ASoC: rt5663: Delay and retry reading rt5663 ID register
  ASoC: amd: use do_div rather than 64 bit division to fix 32 bit builds
  ASoC: cs42l56: Fix reset GPIO name in example DT binding
  ASoC: rt5514-spi: check irq status to schedule data copy in resume function
  ...
This commit is contained in:
Linus Torvalds 2017-11-14 18:01:46 -08:00
commit 4e4510fec4
345 changed files with 9180 additions and 44421 deletions

View file

@ -65,45 +65,6 @@ Optional properties:
a value that is out of range for a 16 bit register then the chip default
will be used. If present exactly five values must be specified.
- wlf,inmode : A list of INn_MODE register values, where n is the number
of input signals. Valid values are 0 (Differential), 1 (Single-ended) and
2 (Digital Microphone). If absent, INn_MODE registers set to 0 by default.
If present, values must be specified less than or equal to the number of
input signals. If values less than the number of input signals, elements
that have not been specified are set to 0 by default. Entries are:
<IN1, IN2, IN3, IN4> (wm5102, wm5110, wm8280, wm8997)
<IN1A, IN2A, IN1B, IN2B> (wm8998, wm1814)
- wlf,out-mono : A list of boolean values indicating whether each output is
mono or stereo. Position within the list indicates the output affected
(eg. First entry in the list corresponds to output 1). A non-zero value
indicates a mono output. If present, the number of values should be less
than or equal to the number of outputs, if less values are supplied the
additional outputs will be treated as stereo.
- wlf,dmic-ref : DMIC reference voltage source for each input, can be
selected from either MICVDD or one of the MICBIAS's, defines
(ARIZONA_DMIC_xxxx) are provided in <dt-bindings/mfd/arizona.txt>. If
present, the number of values should be less than or equal to the
number of inputs, unspecified inputs will use the chip default.
- wlf,max-channels-clocked : The maximum number of channels to be clocked on
each AIF, useful for I2S systems with multiple data lines being mastered.
Specify one cell for each AIF to be configured, specify zero for AIFs that
should be handled normally.
If present, number of cells must be less than or equal to the number of
AIFs. If less than the number of AIFs, for cells that have not been
specified the corresponding AIFs will be treated as default setting.
- wlf,spk-fmt : PDM speaker data format, must contain 2 cells (OUT5 and OUT6).
See the datasheet for values.
The second cell is ignored for codecs that do not have OUT6 (wm5102, wm8997,
wm8998, wm1814)
- wlf,spk-mute : PDM speaker mute setting, must contain 2 cells (OUT5 and OUT6).
See the datasheet for values.
The second cell is ignored for codecs that do not have OUT6 (wm5102, wm8997,
wm8998, wm1814)
- DCVDD-supply, MICVDD-supply : Power supplies, only need to be specified if
they are being externally supplied. As covered in
Documentation/devicetree/bindings/regulator/regulator.txt
@ -112,6 +73,7 @@ Optional properties:
Also see child specific device properties:
Regulator - ../regulator/arizona-regulator.txt
Extcon - ../extcon/extcon-arizona.txt
Sound - ../sound/arizona.txt
Example:

View file

@ -17,6 +17,7 @@ Below are same as Simple-Card.
- bitclock-master
- bitclock-inversion
- frame-inversion
- mclk-fs
- dai-tdm-slot-num
- dai-tdm-slot-width
- clocks / system-clock-frequency

View file

@ -43,7 +43,7 @@ Example 1. Sampling Rate Conversion
label = "sound-card";
prefix = "codec";
routing = "codec Playback", "DAI0 Playback",
"codec Playback", "DAI1 Playback";
"DAI0 Capture", "codec Capture";
convert-rate = <48000>;
dais = <&cpu_port>;
@ -79,7 +79,8 @@ Example 2. 2 CPU 1 Codec (Mixing)
label = "sound-card";
prefix = "codec";
routing = "codec Playback", "DAI0 Playback",
"codec Playback", "DAI1 Playback";
"codec Playback", "DAI1 Playback",
"DAI0 Capture", "codec Capture";
convert-rate = <48000>;
dais = <&cpu_port0

View file

@ -55,7 +55,7 @@ Example:
codec: codec@4b {
compatible = "cirrus,cs42l56";
reg = <0x4b>;
gpio-reset = <&gpio 10 0>;
cirrus,gpio-nreset = <&gpio 10 0>;
cirrus,chgfreq-divisor = <0x05>;
cirrus.ain1_ref_cfg;
cirrus,micbias-lvl = <5>;

View file

@ -1,22 +1,27 @@
RT5514 audio CODEC
This device supports I2C only.
This device supports both I2C and SPI.
Required properties:
- compatible : "realtek,rt5514".
- reg : The I2C address of the device.
- reg : the I2C address of the device for I2C, the chip select
number for SPI.
Optional properties:
- clocks: The phandle of the master clock to the CODEC
- clock-names: Should be "mclk"
- realtek,dmic-init-delay-ms
Set the DMIC initial delay (ms) to wait it ready.
- interrupt-parent: The phandle for the interrupt controller.
- interrupts: The interrupt number to the cpu. The interrupt specifier format
depends on the interrupt controller.
Pins on the device (for linking into audio routes) for RT5514:
- realtek,dmic-init-delay-ms
Set the DMIC initial delay (ms) to wait it ready for I2C.
Pins on the device (for linking into audio routes) for I2C:
* DMIC1L
* DMIC1R

View file

@ -19,6 +19,22 @@ Optional properties:
Based on the different PCB layout, add the manual offset value to
compensate the DC offset for each L and R channel, and they are different
between headphone and headset.
- "realtek,impedance_sensing_num"
The matrix row number of the impedance sensing table.
If the value is 0, it means the impedance sensing is not supported.
- "realtek,impedance_sensing_table"
The matrix rows of the impedance sensing table are consisted by impedance
minimum, impedance maximun, volume, DC offset w/o and w/ mic of each L and
R channel accordingly. Example is shown as following.
< 0 300 7 0xffd160 0xffd1c0 0xff8a10 0xff8ab0
301 65535 4 0xffe470 0xffe470 0xffb8e0 0xffb8e0>
The first and second column are defined for the impedance range. If the
detected impedance value is in the range, then the volume value of the
third column will be set to codec. In our codec design, each volume value
should compensate different DC offset to avoid the pop sound, and it is
also different between headphone and headset. In the example, the
"realtek,impedance_sensing_num" is 2. It means that there are 2 ranges of
impedance in the impedance sensing function.
Pins on the device (for linking into audio routes) for RT5663:

View file

@ -37,7 +37,7 @@ VDDIO 1.8V 2.5V 3.3V
Example:
codec: sgtl5000@0a {
codec: sgtl5000@a {
compatible = "fsl,sgtl5000";
reg = <0x0a>;
clocks = <&clks 150>;

View file

@ -10,13 +10,21 @@ Required properties:
- reg: Base address and size of SAI common register set.
- clocks: Must contain phandle and clock specifier pairs for each entry
in clock-names.
- clock-names: Must contain "x8k" and "x11k"
- clock-names: Must contain "pclk" "x8k" and "x11k"
"pclk": Clock which feeds the peripheral bus interface.
Mandatory for "st,stm32h7-sai" compatible.
Not used for "st,stm32f4-sai" compatible.
"x8k": SAI parent clock for sampling rates multiple of 8kHz.
"x11k": SAI parent clock for sampling rates multiple of 11.025kHz.
- interrupts: cpu DAI interrupt line shared by SAI sub-blocks
Optional properties:
- resets: Reference to a reset controller asserting the SAI
- st,sync: specify synchronization mode.
By default SAI sub-block is in asynchronous mode.
This property sets SAI sub-block as slave of another SAI sub-block.
Must contain the phandle and index of the sai sub-block providing
the synchronization.
SAI subnodes:
Two subnodes corresponding to SAI sub-block instances A et B can be defined.
@ -52,8 +60,8 @@ sai1: sai1@40015800 {
#size-cells = <1>;
ranges = <0 0x40015800 0x400>;
reg = <0x40015800 0x4>;
clocks = <&rcc PLL1_Q>, <&rcc PLL2_P>;
clock-names = "x8k", "x11k";
clocks = <&rcc SAI1_CK>, <&rcc PLL1_Q>, <&rcc PLL2_P>;
clock-names = "pclk", "x8k", "x11k";
interrupts = <87>;
sai1a: audio-controller@40015804 {

View file

@ -0,0 +1,23 @@
NXP TFA9879 class-D audio amplifier
Required properties:
- compatible : "nxp,tfa9879"
- reg : the I2C address of the device
Example:
&i2c1 {
clock-frequency = <100000>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c1>;
status = "okay";
codec: tfa9879@6c {
#sound-dai-cells = <0>;
compatible = "nxp,tfa9879";
reg = <0x6c>;
};
};

View file

@ -0,0 +1,53 @@
Cirrus Logic Arizona class audio SoCs
These devices are audio SoCs with extensive digital capabilities and a range
of analogue I/O.
This document lists sound specific bindings, see the primary binding
document:
../mfd/arizona.txt
Optional properties:
- wlf,inmode : A list of INn_MODE register values, where n is the number
of input signals. Valid values are 0 (Differential), 1 (Single-ended) and
2 (Digital Microphone). If absent, INn_MODE registers set to 0 by default.
If present, values must be specified less than or equal to the number of
input signals. If values less than the number of input signals, elements
that have not been specified are set to 0 by default. Entries are:
<IN1, IN2, IN3, IN4> (wm5102, wm5110, wm8280, wm8997)
<IN1A, IN2A, IN1B, IN2B> (wm8998, wm1814)
- wlf,out-mono : A list of boolean values indicating whether each output is
mono or stereo. Position within the list indicates the output affected
(eg. First entry in the list corresponds to output 1). A non-zero value
indicates a mono output. If present, the number of values should be less
than or equal to the number of outputs, if less values are supplied the
additional outputs will be treated as stereo.
- wlf,dmic-ref : DMIC reference voltage source for each input, can be
selected from either MICVDD or one of the MICBIAS's, defines
(ARIZONA_DMIC_xxxx) are provided in <dt-bindings/mfd/arizona.txt>. If
present, the number of values should be less than or equal to the
number of inputs, unspecified inputs will use the chip default.
- wlf,max-channels-clocked : The maximum number of channels to be clocked on
each AIF, useful for I2S systems with multiple data lines being mastered.
Specify one cell for each AIF to be configured, specify zero for AIFs that
should be handled normally.
If present, number of cells must be less than or equal to the number of
AIFs. If less than the number of AIFs, for cells that have not been
specified the corresponding AIFs will be treated as default setting.
- wlf,spk-fmt : PDM speaker data format, must contain 2 cells (OUT5 and OUT6).
See the datasheet for values.
The second cell is ignored for codecs that do not have OUT6 (wm5102, wm8997,
wm8998, wm1814)
- wlf,spk-mute : PDM speaker mute setting, must contain 2 cells (OUT5 and OUT6).
See the datasheet for values.
The second cell is ignored for codecs that do not have OUT6 (wm5102, wm8997,
wm8998, wm1814)
- wlf,out-volume-limit : The volume limit value that should be applied to each
output channel. See the datasheet for exact values. Channels are specified
in the order OUT1L, OUT1R, OUT2L, OUT2R, etc.

View file

@ -82,6 +82,8 @@ tpt460
Lenovo Thinkpad T460/560 setup
dual-codecs
Lenovo laptops with dual codecs
alc700-ref
Intel reference board with ALC700 codec
ALC66x/67x/892
==============

View file

@ -1,66 +0,0 @@
ALS-007/ALS-100/ALS-200 based sound cards
=========================================
Support for sound cards based around the Avance Logic
ALS-007/ALS-100/ALS-200 chip is included. These chips are a single
chip PnP sound solution which is mostly hardware compatible with the
Sound Blaster 16 card, with most differences occurring in the use of
the mixer registers. For this reason the ALS code is integrated
as part of the Sound Blaster 16 driver (adding only 800 bytes to the
SB16 driver).
To use an ALS sound card under Linux, enable the following options as
modules in the sound configuration section of the kernel config:
- 100% Sound Blaster compatibles (SB16/32/64, ESS, Jazz16) support
- FM synthesizer (YM3812/OPL-3) support
- standalone MPU401 support may be required for some cards; for the
ALS-007, when using isapnptools, it is required
Since the ALS-007/100/200 are PnP cards, ISAPnP support should probably be
compiled in. If kernel level PnP support is not included, isapnptools will
be required to configure the card before the sound modules are loaded.
When using kernel level ISAPnP, the kernel should correctly identify and
configure all resources required by the card when the "sb" module is
inserted. Note that the ALS-007 does not have a 16 bit DMA channel and that
the MPU401 interface on this card uses a different interrupt to the audio
section. This should all be correctly configured by the kernel; if problems
with the MPU401 interface surface, try using the standalone MPU401 module,
passing "0" as the "sb" module's "mpu_io" module parameter to prevent the
soundblaster driver attempting to register the MPU401 itself. The onboard
synth device can be accessed using the "opl3" module.
If isapnptools is used to wake up the sound card (as in 2.2.x), the settings
of the card's resources should be passed to the kernel modules ("sb", "opl3"
and "mpu401") using the module parameters. When configuring an ALS-007, be
sure to specify different IRQs for the audio and MPU401 sections - this card
requires they be different. For "sb", "io", "irq" and "dma" should be set
to the same values used to configure the audio section of the card with
isapnp. "dma16" should be explicitly set to "-1" for an ALS-007 since this
card does not have a 16 bit dma channel; if not specified the kernel will
default to using channel 5 anyway which will cause audio not to work.
"mpu_io" should be set to 0. The "io" parameter of the "opl3" module should
also agree with the setting used by isapnp. To get the MPU401 interface
working on an ALS-007 card, the "mpu401" module will be required since this
card uses separate IRQs for the audio and MPU401 sections and there is no
parameter available to pass a different IRQ to the "sb" driver (whose
inbuilt MPU401 driver would otherwise be fine). Insert the mpu401 module
passing appropriate values using the "io" and "irq" parameters.
The resulting sound driver will provide the following capabilities:
- 8 and 16 bit audio playback
- 8 and 16 bit audio recording
- Software selection of record source (line in, CD, FM, mic, master)
- Record and playback of midi data via the external MPU-401
- Playback of midi data using inbuilt FM synthesizer
- Control of the ALS-007 mixer via any OSS-compatible mixer programs.
Controls available are Master (L&R), Line in (L&R), CD (L&R),
DSP/PCM/audio out (L&R), FM (L&R) and Mic in (mono).
Jonathan Woithe
jwoithe@just42.net
30 March 1998
Modified 2000-02-26 by Dave Forrest, drf5n@virginia.edu to add ALS100/ALS200
Modified 2000-04-10 by Paul Laufer, pelaufer@csupomona.edu to add ISAPnP info.
Modified 2000-11-19 by Jonathan Woithe, jwoithe@just42.net
- updated information for kernel 2.4.x.

View file

@ -1,101 +0,0 @@
Driver
------
Information about Audio Excel DSP 16 driver can be found in the source
file aedsp16.c
Please, read the head of the source before using it. It contain useful
information.
Configuration
-------------
The Audio Excel configuration, is now done with the standard Linux setup.
You have to configure the sound card (Sound Blaster or Microsoft Sound System)
and, if you want it, the Roland MPU-401 (do not use the Sound Blaster MPU-401,
SB-MPU401) in the main driver menu. Activate the lowlevel drivers then select
the Audio Excel hardware that you want to initialize. Check the IRQ/DMA/MIRQ
of the Audio Excel initialization: it must be the same as the SBPRO (or MSS)
setup. If the parameters are different, correct it.
I you own a Gallant's audio card based on SC-6600, activate the SC-6600 support.
If you want to change the configuration of the sound board, be sure to
check off all the configuration items before re-configure it.
Module parameters
-----------------
To use this driver as a module, you must configure some module parameters, to
set up I/O addresses, IRQ lines and DMA channels. Some parameters are
mandatory while some others are optional. Here a list of parameters you can
use with this module:
Name Description
==== ===========
MANDATORY
io I/O base address (0x220 or 0x240)
irq irq line (5, 7, 9, 10 or 11)
dma dma channel (0, 1 or 3)
OPTIONAL
mss_base I/O base address for activate MSS mode (default SBPRO)
(0x530 or 0xE80)
mpu_base I/O base address for activate MPU-401 mode
(0x300, 0x310, 0x320 or 0x330)
mpu_irq MPU-401 irq line (5, 7, 9, 10 or 0)
A configuration file in /etc/modprobe.d/ directory will have lines like this:
options opl3 io=0x388
options ad1848 io=0x530 irq=11 dma=3
options aedsp16 io=0x220 irq=11 dma=3 mss_base=0x530
Where the aedsp16 options are the options for this driver while opl3 and
ad1848 are the corresponding options for the MSS and OPL3 modules.
Loading MSS and OPL3 needs to pre load the aedsp16 module to set up correctly
the sound card. Installation dependencies must be written in configuration
files under /etc/modprobe.d/ directory:
softdep ad1848 pre: aedsp16
softdep opl3 pre: aedsp16
Then you must load the sound modules stack in this order:
sound -> aedsp16 -> [ ad1848, opl3 ]
With the above configuration, loading ad1848 or opl3 modules, will
automatically load all the sound stack.
Sound cards supported
---------------------
This driver supports the SC-6000 and SC-6600 based Gallant's sound card.
It don't support the Audio Excel DSP 16 III (try the SC-6600 code).
I'm working on the III version of the card: if someone have useful
information about it, please let me know.
For all the non-supported audio cards, you have to boot MS-DOS (or WIN95)
activating the audio card with the MS-DOS device driver, then you have to
<ctrl>-<alt>-<del> and boot Linux.
Follow these steps:
1) Compile Linux kernel with standard sound driver, using the emulation
you want, with the parameters of your audio card,
e.g. Microsoft Sound System irq10 dma3
2) Install your new kernel as the default boot kernel.
3) Boot MS-DOS and configure the audio card with the boot time device
driver, for MSS irq10 dma3 in our example.
4) <ctrl>-<alt>-<del> and boot Linux. This will maintain the DOS configuration
and will boot the new kernel with sound driver. The sound driver will find
the audio card and will recognize and attach it.
Reports on User successes
-------------------------
> Date: Mon, 29 Jul 1996 08:35:40 +0100
> From: Mr S J Greenaway <sjg95@unixfe.rl.ac.uk>
> To: riccardo@cdc8g5.cdc.polimi.it (Riccardo Facchetti)
> Subject: Re: Audio Excel DSP 16 initialization code
>
> Just to let you know got my Audio Excel (emulating a MSS) working
> with my original SB16, thanks for the driver!
Last revised: 20 August 1998
Riccardo Facchetti
fizban@tin.it

View file

@ -1,152 +0,0 @@
Documentation for CMI 8330 (SoundPRO)
-------------------------------------
Alessandro Zummo <azummo@ita.flashnet.it>
( Be sure to read Documentation/sound/oss/SoundPro too )
This adapter is now directly supported by the sb driver.
The only thing you have to do is to compile the kernel sound
support as a module and to enable kernel ISAPnP support,
as shown below.
CONFIG_SOUND=m
CONFIG_SOUND_SB=m
CONFIG_PNP=y
CONFIG_ISAPNP=y
and optionally:
CONFIG_SOUND_MPU401=m
for MPU401 support.
(I suggest you to use "make menuconfig" or "make xconfig"
for a more comfortable configuration editing)
Then you can do
modprobe sb
and everything will be (hopefully) configured.
You should get something similar in syslog:
sb: CMI8330 detected.
sb: CMI8330 sb base located at 0x220
sb: CMI8330 mpu base located at 0x330
sb: CMI8330 mail reports to Alessandro Zummo <azummo@ita.flashnet.it>
sb: ISAPnP reports CMI 8330 SoundPRO at i/o 0x220, irq 7, dma 1,5
The old documentation file follows for reference
purposes.
How to enable CMI 8330 (SOUNDPRO) soundchip on Linux
------------------------------------------
Stefan Laudat <Stefan.Laudat@asit.ro>
[Note: The CMI 8338 is unrelated and is supported by cmpci.o]
In order to use CMI8330 under Linux you just have to use a proper isapnp.conf, a good isapnp and a little bit of patience. I use isapnp 1.17, but
you may get a better one I guess at http://www.roestock.demon.co.uk/isapnptools/.
Of course you will have to compile kernel sound support as module, as shown below:
CONFIG_SOUND=m
CONFIG_SOUND_OSS=m
CONFIG_SOUND_SB=m
CONFIG_SOUND_ADLIB=m
CONFIG_SOUND_MPU401=m
# Mikro$chaft sound system (kinda useful here ;))
CONFIG_SOUND_MSS=m
The /etc/isapnp.conf file will be:
<snip below>
(READPORT 0x0203)
(ISOLATE PRESERVE)
(IDENTIFY *)
(VERBOSITY 2)
(CONFLICT (IO FATAL)(IRQ FATAL)(DMA FATAL)(MEM FATAL)) # or WARNING
(VERIFYLD N)
# WSS
(CONFIGURE CMI0001/16777472 (LD 0
(IO 0 (SIZE 8) (BASE 0x0530))
(IO 1 (SIZE 8) (BASE 0x0388))
(INT 0 (IRQ 7 (MODE +E)))
(DMA 0 (CHANNEL 0))
(NAME "CMI0001/16777472[0]{CMI8330/C3D Audio Adapter}")
(ACT Y)
))
# MPU
(CONFIGURE CMI0001/16777472 (LD 1
(IO 0 (SIZE 2) (BASE 0x0330))
(INT 0 (IRQ 11 (MODE +E)))
(NAME "CMI0001/16777472[1]{CMI8330/C3D Audio Adapter}")
(ACT Y)
))
# Joystick
(CONFIGURE CMI0001/16777472 (LD 2
(IO 0 (SIZE 8) (BASE 0x0200))
(NAME "CMI0001/16777472[2]{CMI8330/C3D Audio Adapter}")
(ACT Y)
))
# SoundBlaster
(CONFIGURE CMI0001/16777472 (LD 3
(IO 0 (SIZE 16) (BASE 0x0220))
(INT 0 (IRQ 5 (MODE +E)))
(DMA 0 (CHANNEL 1))
(DMA 1 (CHANNEL 5))
(NAME "CMI0001/16777472[3]{CMI8330/C3D Audio Adapter}")
(ACT Y)
))
(WAITFORKEY)
<end of snip>
The module sequence is trivial:
/sbin/insmod soundcore
/sbin/insmod sound
/sbin/insmod uart401
# insert this first
/sbin/insmod ad1848 io=0x530 irq=7 dma=0 soundpro=1
# The sb module is an alternative to the ad1848 (Microsoft Sound System)
# Anyhow, this is full duplex and has MIDI
/sbin/insmod sb io=0x220 dma=1 dma16=5 irq=5 mpu_io=0x330
Alma Chao <elysian@ethereal.torsion.org> suggests the following in
a /etc/modprobe.d/*conf file:
alias sound ad1848
alias synth0 opl3
options ad1848 io=0x530 irq=7 dma=0 soundpro=1
options opl3 io=0x388

View file

@ -1,34 +0,0 @@
Documentation for the ESS AudioDrive chips
In 2.4 kernels the SoundBlaster driver not only tries to detect an ESS chip, it
tries to detect the type of ESS chip too. The correct detection of the chip
doesn't always succeed however, so unless you use the kernel isapnp facilities
(and you chip is pnp capable) the default behaviour is 2.0 behaviour which
means: only detect ES688 and ES1688.
All ESS chips now have a recording level setting. This is a need-to-have for
people who want to use their ESS for recording sound.
Every chip that's detected as a later-than-es1688 chip has a 6 bits logarithmic
master volume control.
Every chip that's detected as a ES1887 now has Full Duplex support. Made a
little testprogram that shows that is works, haven't seen a real program that
needs this however.
For ESS chips an additional parameter "esstype" can be specified. This controls
the (auto) detection of the ESS chips. It can have 3 kinds of values:
-1 Act like 2.0 kernels: only detect ES688 or ES1688.
0 Try to auto-detect the chip (may fail for ES1688)
688 The chip will be treated as ES688
1688 ,, ,, ,, ,, ,, ,, ES1688
1868 ,, ,, ,, ,, ,, ,, ES1868
1869 ,, ,, ,, ,, ,, ,, ES1869
1788 ,, ,, ,, ,, ,, ,, ES1788
1887 ,, ,, ,, ,, ,, ,, ES1887
1888 ,, ,, ,, ,, ,, ,, ES1888
Because Full Duplex is supported for ES1887 you can specify a second DMA
channel by specifying module parameter dma16. It can be one of: 0, 1, 3 or 5.

View file

@ -1,55 +0,0 @@
Documentation for the ESS1868F AudioDrive PnP sound card
The ESS1868 sound card is a PnP ESS1688-compatible 16-bit sound card.
It should be automatically detected by the Linux Kernel isapnp support when you
load the sb.o module. Otherwise you should take care of:
* The ESS1868 does not allow use of a 16-bit DMA, thus DMA 0, 1, 2, and 3
may only be used.
* isapnptools version 1.14 does work with ESS1868. Earlier versions might
not.
* Sound support MUST be compiled as MODULES, not statically linked
into the kernel.
NOTE: this is only needed when not using the kernel isapnp support!
For configuring the sound card's I/O addresses, IRQ and DMA, here is a
sample copy of the isapnp.conf directives regarding the ESS1868:
(CONFIGURE ESS1868/-1 (LD 1
(IO 0 (BASE 0x0220))
(IO 1 (BASE 0x0388))
(IO 2 (BASE 0x0330))
(DMA 0 (CHANNEL 1))
(INT 0 (IRQ 5 (MODE +E)))
(ACT Y)
))
(for a full working isapnp.conf file, remember the
(ISOLATE)
(IDENTIFY *)
at the beginning and the
(WAITFORKEY)
at the end.)
In this setup, the main card I/O is 0x0220, FM synthesizer is 0x0388, and
the MPU-401 MIDI port is located at 0x0330. IRQ is IRQ 5, DMA is channel 1.
After configuring the sound card via isapnp, to use the card you must load
the sound modules with the proper I/O information. Here is my setup:
# ESS1868F AudioDrive initialization
/sbin/modprobe sound
/sbin/insmod uart401
/sbin/insmod sb io=0x220 irq=5 dma=1 dma16=-1
/sbin/insmod mpu401 io=0x330
/sbin/insmod opl3 io=0x388
/sbin/insmod v_midi
opl3 is the FM synthesizer
/sbin/insmod opl3 io=0x388

View file

@ -1,459 +0,0 @@
Introduction Notes on Modular Sound Drivers and Soundcore
Wade Hampton
2/14/2001
Purpose:
========
This document provides some general notes on the modular
sound drivers and their configuration, along with the
support modules sound.o and soundcore.o.
Note, some of this probably should be added to the Sound-HOWTO!
Note, soundlow.o was present with 2.2 kernels but is not
required for 2.4.x kernels. References have been removed
to this.
Copying:
========
none
History:
========
0.1.0 11/20/1998 First version, draft
1.0.0 11/1998 Alan Cox changes, incorporation in 2.2.0
as Documentation/sound/oss/Introduction
1.1.0 6/30/1999 Second version, added notes on making the drivers,
added info on multiple sound cards of similar types,]
added more diagnostics info, added info about esd.
added info on OSS and ALSA.
1.1.1 19991031 Added notes on sound-slot- and sound-service.
(Alan Cox)
1.1.2 20000920 Modified for Kernel 2.4 (Christoph Hellwig)
1.1.3 20010214 Minor notes and corrections (Wade Hampton)
Added examples of sound-slot-0, etc.
Modular Sound Drivers:
======================
Thanks to the GREAT work by Alan Cox (alan@lxorguk.ukuu.org.uk),
[And Oleg Drokin, Thomas Sailer, Andrew Veliath and more than a few
others - not to mention Hannu's original code being designed well
enough to cope with that kind of chopping up](Alan)
the standard Linux kernels support a modular sound driver. From
Alan's comments in linux/drivers/sound/README.FIRST:
The modular sound driver patches were funded by Red Hat Software
(www.redhat.com). The sound driver here is thus a modified version of
Hannu's code. Please bear that in mind when considering the appropriate
forums for bug reporting.
The modular sound drivers may be loaded via insmod or modprobe.
To support all the various sound modules, there are two general
support modules that must be loaded first:
soundcore.o: Top level handler for the sound system, provides
a set of functions for registration of devices
by type.
sound.o: Common sound functions required by all modules.
For the specific sound modules (e.g., sb.o for the Soundblaster),
read the documentation on that module to determine what options
are available, for example IRQ, address, DMA.
Warning, the options for different cards sometime use different names
for the same or a similar feature (dma1= versus dma16=). As a last
resort, inspect the code (search for module_param).
Notes:
1. There is a new OpenSource sound driver called ALSA which is
currently under development: http://www.alsa-project.org/
The ALSA drivers support some newer hardware that may not
be supported by this sound driver and also provide some
additional features.
2. The commercial OSS driver may be obtained from the site:
http://www.opensound.com. This may be used for cards that
are unsupported by the kernel driver, or may be used
by other operating systems.
3. The enlightenment sound daemon may be used for playing
multiple sounds at the same time via a single card, eliminating
some of the requirements for multiple sound card systems. For
more information, see: http://www.tux.org/~ricdude/EsounD.html
The "esd" program may be used with the real-player and mpeg
players like mpg123 and x11amp. The newer real-player
and some games even include built-in support for ESD!
Building the Modules:
=====================
This document does not provide full details on building the
kernel, etc. The notes below apply only to making the kernel
sound modules. If this conflicts with the kernel's README,
the README takes precedence.
1. To make the kernel sound modules, cd to your /usr/src/linux
directory (typically) and type make config, make menuconfig,
or make xconfig (to start the command line, dialog, or x-based
configuration tool).
2. Select the Sound option and a dialog will be displayed.
3. Select M (module) for "Sound card support".
4. Select your sound driver(s) as a module. For ProAudio, Sound
Blaster, etc., select M (module) for OSS sound modules.
[thanks to Marvin Stodolsky <stodolsk@erols.com>]A
5. Make the kernel (e.g., make bzImage), and install the kernel.
6. Make the modules and install them (make modules; make modules_install).
Note, for 2.5.x kernels, make sure you have the newer module-init-tools
installed or modules will not be loaded properly. 2.5.x requires an
updated module-init-tools.
Plug and Play (PnP:
===================
If the sound card is an ISA PnP card, isapnp may be used
to configure the card. See the file isapnp.txt in the
directory one level up (e.g., /usr/src/linux/Documentation).
Also the 2.4.x kernels provide PnP capabilities, see the
file NEWS in this directory.
PCI sound cards are highly recommended, as they are far
easier to configure and from what I have read, they use
less resources and are more CPU efficient.
INSMOD:
=======
If loading via insmod, the common modules must be loaded in the
order below BEFORE loading the other sound modules. The card-specific
modules may then be loaded (most require parameters). For example,
I use the following via a shell script to load my SoundBlaster:
SB_BASE=0x240
SB_IRQ=9
SB_DMA=3
SB_DMA2=5
SB_MPU=0x300
#
echo Starting sound
/sbin/insmod soundcore
/sbin/insmod sound
#
echo Starting sound blaster....
/sbin/insmod uart401
/sbin/insmod sb io=$SB_BASE irq=$SB_IRQ dma=$SB_DMA dma16=$SB_DMA2 mpu_io=$SB_MP
When using sound as a module, I typically put these commands
in a file such as /root/soundon.sh.
MODPROBE:
=========
If loading via modprobe, these common files are automatically loaded when
requested by modprobe. For example, my /etc/modprobe.d/oss.conf contains:
alias sound sb
options sb io=0x240 irq=9 dma=3 dma16=5 mpu_io=0x300
All you need to do to load the module is:
/sbin/modprobe sb
Sound Status:
=============
The status of sound may be read/checked by:
cat (anyfile).au >/dev/audio
[WWH: This may not work properly for SoundBlaster PCI 128 cards
such as the es1370/1 (see the es1370/1 files in this directory)
as they do not automatically support uLaw on /dev/audio.]
The status of the modules and which modules depend on
which other modules may be checked by:
/sbin/lsmod
/sbin/lsmod should show something like the following:
sb 26280 0
uart401 5640 0 [sb]
sound 57112 0 [sb uart401]
soundcore 1968 8 [sb sound]
Removing Sound:
===============
Sound may be removed by using /sbin/rmmod in the reverse order
in which you load the modules. Note, if a program has a sound device
open (e.g., xmixer), that module (and the modules on which it
depends) may not be unloaded.
For example, I use the following to remove my Soundblaster (rmmod
in the reverse order in which I loaded the modules):
/sbin/rmmod sb
/sbin/rmmod uart401
/sbin/rmmod sound
/sbin/rmmod soundcore
When using sound as a module, I typically put these commands
in a script such as /root/soundoff.sh.
Removing Sound for use with OSS:
================================
If you get really stuck or have a card that the kernel modules
will not support, you can get a commercial sound driver from
http://www.opensound.com. Before loading the commercial sound
driver, you should do the following:
1. remove sound modules (detailed above)
2. remove the sound modules from /etc/modprobe.d/*.conf
3. move the sound modules from /lib/modules/<kernel>/misc
(for example, I make a /lib/modules/<kernel>/misc/tmp
directory and copy the sound module files to that
directory).
Multiple Sound Cards:
=====================
The sound drivers will support multiple sound cards and there
are some great applications like multitrack that support them.
Typically, you need two sound cards of different types. Note, this
uses more precious interrupts and DMA channels and sometimes
can be a configuration nightmare. I have heard reports of 3-4
sound cards (typically I only use 2). You can sometimes use
multiple PCI sound cards of the same type.
On my machine I have two sound cards (cs4232 and Soundblaster Vibra
16). By loading sound as modules, I can control which is the first
sound device (/dev/dsp, /dev/audio, /dev/mixer) and which is
the second. Normally, the cs4232 (Dell sound on the motherboard)
would be the first sound device, but I prefer the Soundblaster.
All you have to do is to load the one you want as /dev/dsp
first (in my case "sb") and then load the other one
(in my case "cs4232").
If you have two cards of the same type that are jumpered
cards or different PnP revisions, you may load the same
module twice. For example, I have a SoundBlaster vibra 16
and an older SoundBlaster 16 (jumpers). To load the module
twice, you need to do the following:
1. Copy the sound modules to a new name. For example
sb.o could be copied (or symlinked) to sb1.o for the
second SoundBlaster.
2. Make a second entry in /etc/modprobe.d/*conf, for example,
sound1 or sb1. This second entry should refer to the
new module names for example sb1, and should include
the I/O, etc. for the second sound card.
3. Update your soundon.sh script, etc.
Warning: I have never been able to get two PnP sound cards of the
same type to load at the same time. I have tried this several times
with the Soundblaster Vibra 16 cards. OSS has indicated that this
is a PnP problem.... If anyone has any luck doing this, please
send me an E-MAIL. PCI sound cards should not have this problem.a
Since this was originally release, I have received a couple of
mails from people who have accomplished this!
NOTE: In Linux 2.4 the Sound Blaster driver (and only this one yet)
supports multiple cards with one module by default.
Read the file 'Soundblaster' in this directory for details.
Sound Problems:
===============
First RTFM (including the troubleshooting section
in the Sound-HOWTO).
1) If you are having problems loading the modules (for
example, if you get device conflict errors) try the
following:
A) If you have Win95 or NT on the same computer,
write down what addresses, IRQ, and DMA channels
those were using for the same hardware. You probably
can use these addresses, IRQs, and DMA channels.
You should really do this BEFORE attempting to get
sound working!
B) Check (cat) /proc/interrupts, /proc/ioports,
and /proc/dma. Are you trying to use an address,
IRQ or DMA port that another device is using?
C) Check (cat) /proc/isapnp
D) Inspect your /var/log/messages file. Often that will
indicate what IRQ or IO port could not be obtained.
E) Try another port or IRQ. Note this may involve
using the PnP tools to move the sound card to
another location. Sometimes this is the only way
and it is more or less trial and error.
2) If you get motor-boating (the same sound or part of a
sound clip repeated), you probably have either an IRQ
or DMA conflict. Move the card to another IRQ or DMA
port. This has happened to me when playing long files
when I had an IRQ conflict.
3. If you get dropouts or pauses when playing high sample
rate files such as using mpg123 or x11amp/xmms, you may
have too slow of a CPU and may have to use the options to
play the files at 1/2 speed. For example, you may use
the -2 or -4 option on mpg123. You may also get this
when trying to play mpeg files stored on a CD-ROM
(my Toshiba T8000 PII/366 sometimes has this problem).
4. If you get "cannot access device" errors, your /dev/dsp
files, etc. may be set to owner root, mode 600. You
may have to use the command:
chmod 666 /dev/dsp /dev/mixer /dev/audio
5. If you get "device busy" errors, another program has the
sound device open. For example, if using the Enlightenment
sound daemon "esd", the "esd" program has the sound device.
If using "esd", please RTFM the docs on ESD. For example,
esddsp <program> may be used to play files via a non-esd
aware program.
6) Ask for help on the sound list or send E-MAIL to the
sound driver author/maintainer.
7) Turn on debug in drivers/sound/sound_config.h (DEB, DDB, MDB).
8) If the system reports insufficient DMA memory then you may want to
load sound with the "dmabufs=1" option. Or in /etc/conf.modules add
preinstall sound dmabufs=1
This makes the sound system allocate its buffers and hang onto them.
You may also set persistent DMA when building a 2.4.x kernel.
Configuring Sound:
==================
There are several ways of configuring your sound:
1) On the kernel command line (when using the sound driver(s)
compiled in the kernel). Check the driver source and
documentation for details.
2) On the command line when using insmod or in a bash script
using command line calls to load sound.
3) In /etc/modprobe.d/*conf when using modprobe.
4) Via Red Hat's GPL'd /usr/sbin/sndconfig program (text based).
5) Via the OSS soundconf program (with the commercial version
of the OSS driver.
6) By just loading the module and let isapnp do everything relevant
for you. This works only with a few drivers yet and - of course -
only with isapnp hardware.
And I am sure, several other ways.
Anyone want to write a linuxconf module for configuring sound?
Module Loading:
===============
When a sound card is first referenced and sound is modular, the sound system
will ask for the sound devices to be loaded. Initially it requests that
the driver for the sound system is loaded. It then will ask for
sound-slot-0, where 0 is the first sound card. (sound-slot-1 the second and
so on). Thus you can do
alias sound-slot-0 sb
To load a soundblaster at this point. If the slot loading does not provide
the desired device - for example a soundblaster does not directly provide
a midi synth in all cases then it will request "sound-service-0-n" where n
is
0 Mixer
2 MIDI
3, 4 DSP audio
For example, I use the following to load my Soundblaster PCI 128
(ES 1371) card first, followed by my SoundBlaster Vibra 16 card,
then by my TV card:
# Load the Soundblaster PCI 128 as /dev/dsp, /dev/dsp1, /dev/mixer
alias sound-slot-0 es1371
# Load the Soundblaster Vibra 16 as /dev/dsp2, /dev/mixer1
alias sound-slot-1 sb
options sb io=0x240 irq=5 dma=1 dma16=5 mpu_io=0x330
# Load the BTTV (TV card) as /dev/mixer2
alias sound-slot-2 bttv
alias sound-service-2-0 tvmixer
pre-install bttv modprobe tuner ; modprobe tvmixer
pre-install tvmixer modprobe msp3400; modprobe tvaudio
options tuner debug=0 type=8
options bttv card=0 radio=0 pll=0
For More Information (RTFM):
============================
1) Information on kernel modules: manual pages for insmod and modprobe.
2) Information on PnP, RTFM manual pages for isapnp.
3) Sound-HOWTO and Sound-Playing-HOWTO.
4) OSS's WWW site at http://www.opensound.com.
5) All the files in Documentation/sound.
6) The comments and code in linux/drivers/sound.
7) The sndconfig and rhsound documentation from Red Hat.
8) The Linux-sound mailing list: sound-list@redhat.com.
9) Enlightenment documentation (for info on esd)
http://www.tux.org/~ricdude/EsounD.html.
10) ALSA home page: http://www.alsa-project.org/
Contact Information:
====================
Wade Hampton: (whampton@staffnet.com)

File diff suppressed because it is too large Load diff

View file

@ -1,6 +0,0 @@
A pure OPL3 card is nice and easy to configure. Simply do
insmod opl3 io=0x388
Change the I/O address in the very unlikely case this card is differently
configured

View file

@ -1,218 +0,0 @@
Support for the OPTi 82C931 chip
--------------------------------
Note: parts of this README file apply also to other
cards that use the mad16 driver.
Some items in this README file are based on features
added to the sound driver after Linux-2.1.91 was out.
By the time of writing this I do not know which official
kernel release will include these features.
Please do not report inconsistencies on older Linux
kernels.
The OPTi 82C931 is supported in its non-PnP mode.
Usually you do not need to set jumpers, etc. The sound driver
will check the card status and if it is required it will
force the card into a mode in which it can be programmed.
If you have another OS installed on your computer it is recommended
that Linux and the other OS use the same resources.
Also, it is recommended that resources specified in /etc/modprobe.d/*.conf
and resources specified in /etc/isapnp.conf agree.
Compiling the sound driver
--------------------------
I highly recommend that you build a modularized sound driver.
This document does not cover a sound-driver which is built in
the kernel.
Sound card support should be enabled as a module (chose m).
Answer 'm' for these items:
Generic OPL2/OPL3 FM synthesizer support (CONFIG_SOUND_ADLIB)
Microsoft Sound System support (CONFIG_SOUND_MSS)
Support for OPTi MAD16 and/or Mozart based cards (CONFIG_SOUND_MAD16)
FM synthesizer (YM3812/OPL-3) support (CONFIG_SOUND_YM3812)
The configuration menu may ask for addresses, IRQ lines or DMA
channels. If the card is used as a module the module loading
options will override these values.
For the OPTi 931 you can answer 'n' to:
Support MIDI in older MAD16 based cards (requires SB) (CONFIG_SOUND_MAD16_OLDCARD)
If you do need MIDI support in a Mozart or C928 based card you
need to answer 'm' to the above question. In that case you will
also need to answer 'm' to:
'100% Sound Blaster compatibles (SB16/32/64, ESS, Jazz16) support' (CONFIG_SOUND_SB)
Go on and compile your kernel and modules. Install the modules. Run depmod -a.
Using isapnptools
-----------------
In most systems with a PnP BIOS you do not need to use isapnp. The
initialization provided by the BIOS is sufficient for the driver
to pick up the card and continue initialization.
If that fails, or if you have other PnP cards, you need to use isapnp
to initialize the card.
This was tested with isapnptools-1.11 but I recommend that you use
isapnptools-1.13 (or newer). Run pnpdump to dump the information
about your PnP cards. Then edit the resulting file and select
the options of your choice. This file is normally installed as
/etc/isapnp.conf.
The driver has one limitation with respect to I/O port resources:
IO3 base must be 0x0E0C. Although isapnp allows other ports, this
address is hard-coded into the driver.
Using kmod and autoloading the sound driver
-------------------------------------------
Config files in '/etc/modprobe.d/' are used as below:
alias mixer0 mad16
alias audio0 mad16
alias midi0 mad16
alias synth0 opl3
options sb mad16=1
options mad16 irq=10 dma=0 dma16=1 io=0x530 joystick=1 cdtype=0
options opl3 io=0x388
install mad16 /sbin/modprobe -i mad16 && /sbin/ad1848_mixer_reroute 14 8 15 3 16 6
If you have an MPU daughtercard or onboard MPU you will want to add to the
"options mad16" line - eg
options mad16 irq=5 dma=0 dma16=3 io=0x530 mpu_io=0x330 mpu_irq=9
To set the I/O and IRQ of the MPU.
Explain:
alias mixer0 mad16
alias audio0 mad16
alias midi0 mad16
alias synth0 opl3
When any sound device is opened the kernel requests auto-loading
of char-major-14. There is a built-in alias that translates this
request to loading the main sound module.
The sound module in its turn will request loading of a sub-driver
for mixer, audio, midi or synthesizer device. The first 3 are
supported by the mad16 driver. The synth device is supported
by the opl3 driver.
There is currently no way to autoload the sound device driver
if more than one card is installed.
options sb mad16=1
This is left for historical reasons. If you enable the
config option 'Support MIDI in older MAD16 based cards (requires SB)'
or if you use an older mad16 driver it will force loading of the
SoundBlaster driver. This option tells the SB driver not to look
for a SB card but to wait for the mad16 driver.
options mad16 irq=10 dma=0 dma16=1 io=0x530 joystick=1 cdtype=0
options opl3 io=0x388
post-install mad16 /sbin/ad1848_mixer_reroute 14 8 15 3 16 6
This sets resources and options for the mad16 and opl3 drivers.
I use two DMA channels (only one is required) to enable full duplex.
joystick=1 enables the joystick port. cdtype=0 disables the cd port.
You can also set mpu_io and mpu_irq in the mad16 options for the
uart401 driver.
This tells modprobe to run /sbin/ad1848_mixer_reroute after
mad16 is successfully loaded and initialized. The source
for ad1848_mixer_reroute is appended to the end of this readme
file. It is impossible for the sound driver to know the actual
connections to the mixer. The 3 inputs intended for cd, synth
and line-in are mapped to the generic inputs line1, line2 and
line3. This program reroutes these mixer channels to their
right names (note the right mapping depends on the actual sound
card that you use).
The numeric parameters mean:
14=line1 8=cd - reroute line1 to the CD input.
15=line2 3=synth - reroute line2 to the synthesizer input.
16=line3 6=line - reroute line3 to the line input.
For reference on other input names look at the file
/usr/include/linux/soundcard.h.
Using a joystick
-----------------
You must enable a joystick in the mad16 options. (also
in /etc/isapnp.conf if you use it).
Tested with regular analog joysticks.
A CDROM drive connected to the sound card
-----------------------------------------
The 82C931 chip has support only for secondary ATAPI cdrom.
(cdtype=8). Loading the mad16 driver resets the C931 chip
and if a cdrom was already mounted it may cause a complete
system hang. Do not use the sound card if you have an alternative.
If you do use the sound card it is important that you load
the mad16 driver (use "modprobe mad16" to prevent auto-unloading)
before the cdrom is accessed the first time.
Using the sound driver built-in to the kernel may help here, but...
Most new systems have a PnP BIOS and also two IDE controllers.
The IDE controller on the sound card may be needed only on older
systems (which have only one IDE controller) but these systems
also do not have a PnP BIOS - requiring isapnptools and a modularized
driver.
Known problems
--------------
1. See the section on "A CDROM drive connected to the sound card".
2. On my system the codec cannot capture companded sound samples.
(eg., recording from /dev/audio). When any companded capture is
requested I get stereo-16 bit samples instead. Playback of
companded samples works well. Apparently this problem is not common
to all C931 based cards. I do not know how to identify cards that
have this problem.
Source for ad1848_mixer_reroute.c
---------------------------------
#include <stdio.h>
#include <fcntl.h>
#include <linux/soundcard.h>
static char *mixer_names[SOUND_MIXER_NRDEVICES] =
SOUND_DEVICE_LABELS;
int
main(int argc, char **argv) {
int val, from, to;
int i, fd;
fd = open("/dev/mixer", O_RDWR);
if(fd < 0) {
perror("/dev/mixer");
return 1;
}
for(i = 2; i < argc; i += 2) {
from = atoi(argv[i-1]);
to = atoi(argv[i]);
if(to == SOUND_MIXER_NONE)
fprintf(stderr, "%s: turning off mixer %s\n",
argv[0], mixer_names[to]);
else
fprintf(stderr, "%s: rerouting mixer %s to %s\n",
argv[0], mixer_names[from], mixer_names[to]);
val = from << 8 | to;
if(ioctl(fd, SOUND_MIXER_PRIVATE2, &val)) {
perror("AD1848 mixer reroute");
return 1;
}
}
return 0;
}

View file

@ -1,162 +0,0 @@
Pro Audio Spectrum 16 for 2.3.99 and later
=========================================
by Thomas Molina (tmolina@home.com)
last modified 3 Mar 2001
Acknowledgement to Axel Boldt (boldt@math.ucsb.edu) for stuff taken
from Configure.help, Riccardo Facchetti for stuff from README.OSS,
and others whose names I could not find.
This documentation is relevant for the PAS16 driver (pas2_card.c and
friends) under kernel version 2.3.99 and later. If you are
unfamiliar with configuring sound under Linux, please read the
Sound-HOWTO, Documentation/sound/oss/Introduction and other
relevant docs first.
The following information is relevant information from README.OSS
and legacy docs for the Pro Audio Spectrum 16 (PAS16):
==================================================================
The pas2_card.c driver supports the following cards --
Pro Audio Spectrum 16 (PAS16) and compatibles:
Pro Audio Spectrum 16
Pro Audio Studio 16
Logitech Sound Man 16
NOTE! The original Pro Audio Spectrum as well as the PAS+ are not
and will not be supported by the driver.
The sound driver configuration dialog
-------------------------------------
Sound configuration starts by making some yes/no questions. Be careful
when answering to these questions since answering y to a question may
prevent some later ones from being asked. For example don't answer y to
the question about (PAS16) if you don't really have a PAS16. Sound
configuration may also be made modular by answering m to configuration
options presented.
Note also that all questions may not be asked. The configuration program
may disable some questions depending on the earlier choices. It may also
select some options automatically as well.
"ProAudioSpectrum 16 support",
- Answer 'y'_ONLY_ if you have a Pro Audio Spectrum _16_,
Pro Audio Studio 16 or Logitech SoundMan 16 (be sure that
you read the above list correctly). Don't answer 'y' if you
have some other card made by Media Vision or Logitech since they
are not PAS16 compatible.
NOTE! Since 3.5-beta10 you need to enable SB support (next question)
if you want to use the SB emulation of PAS16. It's also possible to
the emulation if you want to use a true SB card together with PAS16
(there is another question about this that is asked later).
"Generic OPL2/OPL3 FM synthesizer support",
- Answer 'y' if your card has a FM chip made by Yamaha (OPL2/OPL3/OPL4).
The PAS16 has an OPL3-compatible FM chip.
With PAS16 you can use two audio device files at the same time. /dev/dsp (and
/dev/audio) is connected to the 8/16 bit native codec and the /dev/dsp1 (and
/dev/audio1) is connected to the SB emulation (8 bit mono only).
The new stuff for 2.3.99 and later
============================================================================
The following configuration options are relevant to configuring the PAS16:
Sound card support
CONFIG_SOUND
If you have a sound card in your computer, i.e. if it can say more
than an occasional beep, say Y. Be sure to have all the information
about your sound card and its configuration down (I/O port,
interrupt and DMA channel), because you will be asked for it.
You want to read the Sound-HOWTO, available from
http://www.tldp.org/docs.html#howto . General information
about the modular sound system is contained in the files
Documentation/sound/oss/Introduction. The file
Documentation/sound/oss/README.OSS contains some slightly outdated but
still useful information as well.
OSS sound modules
CONFIG_SOUND_OSS
OSS is the Open Sound System suite of sound card drivers. They make
sound programming easier since they provide a common API. Say Y or M
here (the module will be called sound.o) if you haven't found a
driver for your sound card above, then pick your driver from the
list below.
Persistent DMA buffers
CONFIG_SOUND_DMAP
Linux can often have problems allocating DMA buffers for ISA sound
cards on machines with more than 16MB of RAM. This is because ISA
DMA buffers must exist below the 16MB boundary and it is quite
possible that a large enough free block in this region cannot be
found after the machine has been running for a while. If you say Y
here the DMA buffers (64Kb) will be allocated at boot time and kept
until the shutdown. This option is only useful if you said Y to
"OSS sound modules", above. If you said M to "OSS sound modules"
then you can get the persistent DMA buffer functionality by passing
the command-line argument "dmabuf=1" to the sound.o module.
Say y here for PAS16.
ProAudioSpectrum 16 support
CONFIG_SOUND_PAS
Answer Y only if you have a Pro Audio Spectrum 16, ProAudio Studio
16 or Logitech SoundMan 16 sound card. Don't answer Y if you have
some other card made by Media Vision or Logitech since they are not
PAS16 compatible. It is not necessary to enable the separate
Sound Blaster support; it is included in the PAS driver.
If you compile the driver into the kernel, you have to add
"pas2=<io>,<irq>,<dma>,<dma2>,<sbio>,<sbirq>,<sbdma>,<sbdma2>
to the kernel command line.
FM Synthesizer (YM3812/OPL-3) support
CONFIG_SOUND_YM3812
Answer Y if your card has a FM chip made by Yamaha (OPL2/OPL3/OPL4).
Answering Y is usually a safe and recommended choice, however some
cards may have software (TSR) FM emulation. Enabling FM support with
these cards may cause trouble (I don't currently know of any such
cards, however).
Please read the file Documentation/sound/oss/OPL3 if your card has an
OPL3 chip.
If you compile the driver into the kernel, you have to add
"opl3=<io>" to the kernel command line.
If you compile your drivers into the kernel, you MUST configure
OPL3 support as a module for PAS16 support to work properly.
You can then get OPL3 functionality by issuing the command:
insmod opl3
In addition, you must either add the following line to
/etc/modprobe.d/*.conf:
options opl3 io=0x388
or else add the following line to /etc/lilo.conf:
opl3=0x388
EXAMPLES
===================================================================
To use the PAS16 in my computer I have enabled the following sound
configuration options:
CONFIG_SOUND=y
CONFIG_SOUND_OSS=y
CONFIG_SOUND_TRACEINIT=y
CONFIG_SOUND_DMAP=y
CONFIG_SOUND_PAS=y
CONFIG_SOUND_SB=n
CONFIG_SOUND_YM3812=m
I have also included the following append line in /etc/lilo.conf:
append="pas2=0x388,10,3,-1,0x220,5,1,-1 sb=0x220,5,1,-1 opl3=0x388"
The io address of 0x388 is default configuration on the PAS16. The
irq of 10 and dma of 3 may not match your installation. The above
configuration enables PAS16, 8-bit Soundblaster and OPL3
functionality. If Soundblaster functionality is not desired, the
following line would be appropriate:
append="pas2=0x388,10,3,-1,0,-1,-1,-1 opl3=0x388"
If sound is built totally modular, the above options may be
specified in /etc/modprobe.d/*.conf for pas2, sb and opl3
respectively.

View file

@ -1,41 +0,0 @@
The PSS cards and other ECHO based cards provide an onboard DSP with
downloadable programs and also has an AD1848 "Microsoft Sound System"
device. The PSS driver enables MSS and MPU401 modes of the card. SB
is not enabled since it doesn't work concurrently with MSS.
If you build this driver as a module then the driver takes the following
parameters
pss_io. The I/O base the PSS card is configured at (normally 0x220
or 0x240)
mss_io The base address of the Microsoft Sound System interface.
This is normally 0x530, but may be 0x604 or other addresses.
mss_irq The interrupt assigned to the Microsoft Sound System
emulation. IRQ's 3,5,7,9,10,11 and 12 are available. If you
get IRQ errors be sure to check the interrupt is set to
"ISA/Legacy" in the BIOS on modern machines.
mss_dma The DMA channel used by the Microsoft Sound System.
This can be 0, 1, or 3. DMA 0 is not available on older
machines and will cause a crash on them.
mpu_io The MPU emulation base address. This sets the base of the
synthesizer. It is typically 0x330 but can be altered.
mpu_irq The interrupt to use for the synthesizer. It must differ
from the IRQ used by the Microsoft Sound System port.
The mpu_io/mpu_irq fields are optional. If they are not specified the
synthesizer parts are not configured.
When the module is loaded it looks for a file called
/etc/sound/pss_synth. This is the firmware file from the DOS install disks.
This fil holds a general MIDI emulation. The file expected is called
genmidi.ld on newer DOS driver install disks and synth.ld on older ones.
You can also load alternative DSP algorithms into the card if you wish. One
alternative driver can be found at http://www.mpg123.de/

View file

@ -1,88 +0,0 @@
This file contains notes for users of PSS sound cards who wish to use the
newly added features of the newest version of this driver.
The major enhancements present in this new revision of this driver is the
addition of two new module parameters that allow you to take full advantage of
all the features present on your PSS sound card. These features include the
ability to enable both the builtin CDROM and joystick ports.
pss_enable_joystick
This parameter is basically a flag. A 0 will leave the joystick port
disabled, while a non-zero value would enable the joystick port. The default
setting is pss_enable_joystick=0 as this keeps this driver fully compatible
with systems that were using previous versions of this driver. If you wish to
enable the joystick port you will have to add pss_enable_joystick=1 as an
argument to the driver. To actually use the joystick port you will then have
to load the joystick driver itself. Just remember to load the joystick driver
AFTER the pss sound driver.
pss_cdrom_port
This parameter takes a port address as its parameter. Any available port
address can be specified to enable the CDROM port, except for 0x0 and -1 as
these values would leave the port disabled. Like the joystick port, the cdrom
port will require that an appropriate CDROM driver be loaded before you can make
use of the newly enabled CDROM port. Like the joystick port option above,
remember to load the CDROM driver AFTER the pss sound driver. While it may
differ on some PSS sound cards, all the PSS sound cards that I have seen have a
builtin Wearnes CDROM port. If this is the case with your PSS sound card you
should load aztcd with the appropriate port option that matches the port you
assigned to the CDROM port when you loaded your pss sound driver. (ex.
modprobe pss pss_cdrom_port=0x340 && modprobe aztcd aztcd=0x340) The default
setting of this parameter leaves the CDROM port disabled to maintain full
compatibility with systems using previous versions of this driver.
Other options have also been added for the added convenience and utility
of the user. These options are only available if this driver is loaded as a
module.
pss_no_sound
This module parameter is a flag that can be used to tell the driver to
just configure non-sound components. 0 configures all components, a non-0
value will only attempt to configure the CDROM and joystick ports. This
parameter can be used by a user who only wished to use the builtin joystick
and/or CDROM port(s) of his PSS sound card. If this driver is loaded with this
parameter and with the parameter below set to true then a user can safely unload
this driver with the following command "rmmod pss && rmmod ad1848 && rmmod
mpu401 && rmmod sound && rmmod soundcore" and retain the full functionality of
his CDROM and/or joystick port(s) while gaining back the memory previously used
by the sound drivers. This default setting of this parameter is 0 to retain
full behavioral compatibility with previous versions of this driver.
pss_keep_settings
This parameter can be used to specify whether you want the driver to reset
all emulations whenever its unloaded. This can be useful for those who are
sharing resources (io ports, IRQ's, DMA's) between different ISA cards. This
flag can also be useful in that future versions of this driver may reset all
emulations by default on the driver's unloading (as it probably should), so
specifying it now will ensure that all future versions of this driver will
continue to work as expected. The default value of this parameter is 1 to
retain full behavioral compatibility with previous versions of this driver.
pss_firmware
This parameter can be used to specify the file containing the firmware
code so that a user could tell the driver where that file is located instead
of having to put it in a predefined location with a predefined name. The
default setting of this parameter is "/etc/sound/pss_synth" as this was the
path and filename the hardcoded value in the previous versions of this driver.
Examples:
# Normal PSS sound card system, loading of drivers.
# Should be specified in an rc file (ex. Slackware uses /etc/rc.d/rc.modules).
/sbin/modprobe pss pss_io=0x220 mpu_io=0x338 mpu_irq=9 mss_io=0x530 mss_irq=10 mss_dma=1 pss_cdrom_port=0x340 pss_enable_joystick=1
/sbin/modprobe aztcd aztcd=0x340
/sbin/modprobe joystick
# System using the PSS sound card just for its CDROM and joystick ports.
# Should be specified in an rc file (ex. Slackware uses /etc/rc.d/rc.modules).
/sbin/modprobe pss pss_io=0x220 pss_cdrom_port=0x340 pss_enable_joystick=1 pss_no_sound=1
/sbin/rmmod pss && /sbin/rmmod ad1848 && /sbin/rmmod mpu401 && /sbin/rmmod sound && /sbin/rmmod soundcore # This line not needed, but saves memory.
/sbin/modprobe aztcd aztcd=0x340
/sbin/modprobe joystick

File diff suppressed because it is too large Load diff

View file

@ -1,106 +0,0 @@
Building a modular sound driver
================================
The following information is current as of linux-2.1.85. Check the other
readme files, especially README.OSS, for information not specific to
making sound modular.
First, configure your kernel. This is an idea of what you should be
setting in the sound section:
<M> Sound card support
<M> 100% Sound Blaster compatibles (SB16/32/64, ESS, Jazz16) support
I have SoundBlaster. Select your card from the list.
<M> Generic OPL2/OPL3 FM synthesizer support
<M> FM synthesizer (YM3812/OPL-3) support
If you don't set these, you will probably find you can play .wav files
but not .midi. As the help for them says, set them unless you know your
card does not use one of these chips for FM support.
Once you are configured, make zlilo, modules, modules_install; reboot.
Note that it is no longer necessary or possible to configure sound in the
drivers/sound dir. Now one simply configures and makes one's kernel and
modules in the usual way.
Then, add to your /etc/modprobe.d/oss.conf something like:
alias char-major-14-* sb
install sb /sbin/modprobe -i sb && /sbin/modprobe adlib_card
options sb io=0x220 irq=7 dma=1 dma16=5 mpu_io=0x330
options adlib_card io=0x388 # FM synthesizer
Alternatively, if you have compiled in kernel level ISAPnP support:
alias char-major-14 sb
softdep sb post: adlib_card
options adlib_card io=0x388
The effect of this is that the sound driver and all necessary bits and
pieces autoload on demand, assuming you use kerneld (a sound choice) and
autoclean when not in use. Also, options for the device drivers are
set. They will not work without them. Change as appropriate for your card.
If you are not yet using the very cool kerneld, you will have to "modprobe
-k sb" yourself to get things going. Eventually things may be fixed so
that this kludgery is not necessary; for the time being, it seems to work
well.
Replace 'sb' with the driver for your card, and give it the right
options. To find the filename of the driver, look in
/lib/modules/<kernel-version>/misc. Mine looks like:
adlib_card.o # This is the generic OPLx driver
opl3.o # The OPL3 driver
sb.o # <<The SoundBlaster driver. Yours may differ.>>
sound.o # The sound driver
uart401.o # Used by sb, maybe other cards
Whichever card you have, try feeding it the options that would be the
default if you were making the driver wired, not as modules. You can
look at function referred to by module_init() for the card to see what
args are expected.
Note that at present there is no way to configure the io, irq and other
parameters for the modular drivers as one does for the wired drivers.. One
needs to pass the modules the necessary parameters as arguments, either
with /etc/modprobe.d/*.conf or with command-line args to modprobe, e.g.
modprobe sb io=0x220 irq=7 dma=1 dma16=5 mpu_io=0x330
modprobe adlib_card io=0x388
recommend using /etc/modprobe.d/*.conf.
Persistent DMA Buffers:
The sound modules normally allocate DMA buffers during open() and
deallocate them during close(). Linux can often have problems allocating
DMA buffers for ISA cards on machines with more than 16MB RAM. This is
because ISA DMA buffers must exist below the 16MB boundary and it is quite
possible that we can't find a large enough free block in this region after
the machine has been running for any amount of time. The way to avoid this
problem is to allocate the DMA buffers during module load and deallocate
them when the module is unloaded. For this to be effective we need to load
the sound modules right after the kernel boots, either manually or by an
init script, and keep them around until we shut down. This is a little
wasteful of RAM, but it guarantees that sound always works.
To make the sound driver use persistent DMA buffers we need to pass the
sound.o module a "dmabuf=1" command-line argument. This is normally done
in /etc/modprobe.d/*.conf files like so:
options sound dmabuf=1
If you have 16MB or less RAM or a PCI sound card, this is wasteful and
unnecessary. It is possible that machine with 16MB or less RAM will find
this option useful, but if your machine is so memory-starved that it
cannot find a 64K block free, you will be wasting even more RAM by keeping
the sound modules loaded and the DMA buffers allocated when they are not
needed. The proper solution is to upgrade your RAM. But you do also have
this improper solution as well. Use it wisely.
I'm afraid I know nothing about anything but my setup, being more of a
text-mode guy anyway. If you have options for other cards or other helpful
hints, send them to me, Jim Bray, jb@as220.org, http://as220.org/jb.

View file

@ -1,107 +0,0 @@
Legacy audio driver for YMF7xx PCI cards.
FIRST OF ALL
============
This code references YAMAHA's sample codes and data sheets.
I respect and thank for all people they made open the information
about YMF7xx cards.
And this codes heavily based on Jeff Garzik <jgarzik@pobox.com>'s
old VIA 82Cxxx driver (via82cxxx.c). I also respect him.
DISCLIMER
=========
This driver is currently at early ALPHA stage. It may cause serious
damage to your computer when used.
PLEASE USE IT AT YOUR OWN RISK.
ABOUT THIS DRIVER
=================
This code enables you to use your YMF724[A-F], YMF740[A-C], YMF744, YMF754
cards. When enabled, your card acts as "SoundBlaster Pro" compatible card.
It can only play 22.05kHz / 8bit / Stereo samples, control external MIDI
port.
If you want to use your card as recent "16-bit" card, you should use
Alsa or OSS/Linux driver. Of course you can write native PCI driver for
your cards :)
USAGE
=====
# modprobe ymfsb (options)
OPTIONS FOR MODULE
==================
io : SB base address (0x220, 0x240, 0x260, 0x280)
synth_io : OPL3 base address (0x388, 0x398, 0x3a0, 0x3a8)
dma : DMA number (0,1,3)
master_volume: AC'97 PCM out Vol (0-100)
spdif_out : SPDIF-out flag (0:disable 1:enable)
These options will change in future...
FREQUENCY
=========
When playing sounds via this driver, you will hear its pitch is slightly
lower than original sounds. Since this driver recognizes your card acts
with 21.739kHz sample rates rather than 22.050kHz (I think it must be
hardware restriction). So many players become tone deafness.
To prevent this, you should express some options to your sound player
that specify correct sample frequency. For example, to play your MP3 file
correctly with mpg123, specify the frequency like following:
% mpg123 -r 21739 foo.mp3
SPDIF OUT
=========
With installing modules with option 'spdif_out=1', you can enjoy your
sounds from SPDIF-out of your card (if it had).
Its Fs is fixed to 48kHz (It never means the sample frequency become
up to 48kHz. All sounds via SPDIF-out also 22kHz samples). So your
digital-in capable components has to be able to handle 48kHz Fs.
COPYING
=======
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
TODO
====
* support for multiple cards
(set the different SB_IO,MPU_IO,OPL_IO for each cards)
* support for OPL (dmfm) : There will be no requirements... :-<
AUTHOR
======
Daisuke Nagano <breeze.nagano@nifty.ne.jp>

View file

@ -1,105 +0,0 @@
Documentation for the SoundPro CMI8330 extensions in the WSS driver (ad1848.o)
------------------------------------------------------------------------------
( Be sure to read Documentation/sound/oss/CMI8330 too )
Ion Badulescu, ionut@cs.columbia.edu
February 24, 1999
(derived from the OPL3-SA2 documentation by Scott Murray)
The SoundPro CMI8330 (ISA) is a chip usually found on some Taiwanese
motherboards. The official name in the documentation is CMI8330, SoundPro
is the nickname and the big inscription on the chip itself.
The chip emulates a WSS as well as a SB16, but it has certain differences
in the mixer section which require separate support. It also emulates an
MPU401 and an OPL3 synthesizer, so you probably want to enable support
for these, too.
The chip identifies itself as an AD1848, but its mixer is significantly
more advanced than the original AD1848 one. If your system works with
either WSS or SB16 and you are having problems with some mixer controls
(no CD audio, no line-in, etc), you might want to give this driver a try.
Detection should work, but it hasn't been widely tested, so it might still
mis-identify the chip. You can still force soundpro=1 in the modprobe
parameters for ad1848. Please let me know if it happens to you, so I can
adjust the detection routine.
The chip is capable of doing full-duplex, but since the driver sees it as an
AD1848, it cannot take advantage of this. Moreover, the full-duplex mode is
not achievable through the WSS interface, b/c it needs a dma16 line which is
assigned only to the SB16 subdevice (with isapnp). Windows documentation
says the user must use WSS Playback and SB16 Recording for full-duplex, so
it might be possible to do the same thing under Linux. You can try loading
up both ad1848 and sb then use one for playback and the other for
recording. I don't know if this works, b/c I haven't tested it. Anyway, if
you try it, be very careful: the SB16 mixer *mostly* works, but certain
settings can have unexpected effects. Use the WSS mixer for best results.
There is also a PCI SoundPro chip. I have not seen this chip, so I have
no idea if the driver will work with it. I suspect it won't.
As with PnP cards, some configuration is required. There are two ways
of doing this. The most common is to use the isapnptools package to
initialize the card, and use the kernel module form of the sound
subsystem and sound drivers. Alternatively, some BIOS's allow manual
configuration of installed PnP devices in a BIOS menu, which should
allow using the non-modular sound drivers, i.e. built into the kernel.
Since in this latter case you cannot use module parameters, you will
have to enable support for the SoundPro at compile time.
The IRQ and DMA values can be any that are considered acceptable for a
WSS. Assuming you've got isapnp all happy, then you should be able to
do something like the following (which *must* match the isapnp/BIOS
configuration):
modprobe ad1848 io=0x530 irq=11 dma=0 soundpro=1
-and maybe-
modprobe sb io=0x220 irq=5 dma=1 dma16=5
-then-
modprobe mpu401 io=0x330 irq=9
modprobe opl3 io=0x388
If all goes well and you see no error messages, you should be able to
start using the sound capabilities of your system. If you get an
error message while trying to insert the module(s), then make
sure that the values of the various arguments match what you specified
in your isapnp configuration file, and that there is no conflict with
another device for an I/O port or interrupt. Checking the contents of
/proc/ioports and /proc/interrupts can be useful to see if you're
butting heads with another device.
If you do not see the chipset version message, and none of the other
messages present in the system log are helpful, try adding 'debug=1'
to the ad1848 parameters, email me the syslog results and I'll do
my best to help.
Lastly, if you're using modules and want to set up automatic module
loading with kmod, the kernel module loader, here is the section I
currently use in my conf.modules file:
# Sound
post-install sound modprobe -k ad1848; modprobe -k mpu401; modprobe -k opl3
options ad1848 io=0x530 irq=11 dma=0
options sb io=0x220 irq=5 dma=1 dma16=5
options mpu401 io=0x330 irq=9
options opl3 io=0x388
The above ensures that ad1848 will be loaded whenever the sound system
is being used.
Good luck.
Ion
NOT REALLY TESTED:
- recording
- recording device selection
- full-duplex
TODO:
- implement mixer support for surround, loud, digital CD switches.
- come up with a scheme which allows recording volumes for each subdevice.
This is a major OSS API change.

View file

@ -1,53 +0,0 @@
modprobe sound
insmod uart401
insmod sb ...
This loads the driver for the Sound Blaster and assorted clones. Cards that
are covered by other drivers should not be using this driver.
The Sound Blaster module takes the following arguments
io I/O address of the Sound Blaster chip (0x220,0x240,0x260,0x280)
irq IRQ of the Sound Blaster chip (5,7,9,10)
dma 8-bit DMA channel for the Sound Blaster (0,1,3)
dma16 16-bit DMA channel for SB16 and equivalent cards (5,6,7)
mpu_io I/O for MPU chip if present (0x300,0x330)
sm_games=1 Set if you have a Logitech soundman games
acer=1 Set this to detect cards in some ACER notebooks
mwave_bug=1 Set if you are trying to use this driver with mwave (see on)
type Use this to specify a specific card type
The following arguments are taken if ISAPnP support is compiled in
isapnp=0 Set this to disable ISAPnP detection (use io=0xXXX etc. above)
multiple=0 Set to disable detection of multiple Soundblaster cards.
Consider it a bug if this option is needed, and send in a
report.
pnplegacy=1 Set this to be able to use a PnP card(s) along with a single
non-PnP (legacy) card. Above options for io, irq, etc. are
needed, and will apply only to the legacy card.
reverse=1 Reverses the order of the search in the PnP table.
uart401=1 Set to enable detection of mpu devices on some clones.
isapnpjump=n Jumps to slot n in the driver's PnP table. Use the source,
Luke.
You may well want to load the opl3 driver for synth music on most SB and
clone SB devices
insmod opl3 io=0x388
Using Mwave
To make this driver work with Mwave you must set mwave_bug. You also need
to warm boot from DOS/Windows with the required firmware loaded under this
OS. IBM are being difficult about documenting how to load this firmware.
Avance Logic ALS007
This card is supported; see the separate file ALS007 for full details.
Avance Logic ALS100
This card is supported; setup should be as for a standard Sound Blaster 16.
The driver will identify the audio device as a "Sound Blaster 16 (ALS-100)".

View file

@ -1,26 +0,0 @@
From: Paul Barton-Davis <pbd@op.net>
Here is the configuration I use with a Tropez+ and my modular
driver:
alias char-major-14 wavefront
alias synth0 wavefront
alias mixer0 cs4232
alias audio0 cs4232
pre-install wavefront modprobe "-k" "cs4232"
post-install wavefront modprobe "-k" "opl3"
options wavefront io=0x200 irq=9
options cs4232 synthirq=9 synthio=0x200 io=0x530 irq=5 dma=1 dma2=0
options opl3 io=0x388
Things to note:
the wavefront options "io" and "irq" ***MUST*** match the "synthio"
and "synthirq" cs4232 options.
you can do without the opl3 module if you don't
want to use the OPL/[34] synth on the soundcard
the opl3 io parameter is conventionally not adjustable.
Please see drivers/sound/README.wavefront for more details.

View file

@ -1,80 +0,0 @@
Sound Blaster 16X Vibra addendum
--------------------------------
by Marius Ilioaea <mariusi@protv.ro>
Stefan Laudat <stefan@asit.ro>
Sat Mar 6 23:55:27 EET 1999
Hello again,
Playing with a SB Vibra 16x soundcard we found it very difficult
to setup because the kernel reported a lot of DMA errors and wouldn't
simply play any sound.
A good starting point is that the vibra16x chip full-duplex facility
is neither still exploited by the sb driver found in the linux kernel
(tried it with a 2.2.2-ac7), nor in the commercial OSS package (it reports
it as half-duplex soundcard). Oh, I almost forgot, the RedHat sndconfig
failed detecting it ;)
So, the big problem still remains, because the sb module wants a
8-bit and a 16-bit dma, which we could not allocate for vibra... it supports
only two 8-bit dma channels, the second one will be passed to the module
as a 16 bit channel, the kernel will yield about that but everything will
be okay, trust us.
The only inconvenient you may find is that you will have
some sound playing jitters if you have HDD dma support enabled - but this
will happen with almost all soundcards...
A fully working isapnp.conf is just here:
<snip here>
(READPORT 0x0203)
(ISOLATE PRESERVE)
(IDENTIFY *)
(VERBOSITY 2)
(CONFLICT (IO FATAL)(IRQ FATAL)(DMA FATAL)(MEM FATAL)) # or WARNING
# SB 16 and OPL3 devices
(CONFIGURE CTL00f0/-1 (LD 0
(INT 0 (IRQ 5 (MODE +E)))
(DMA 0 (CHANNEL 1))
(DMA 1 (CHANNEL 3))
(IO 0 (SIZE 16) (BASE 0x0220))
(IO 2 (SIZE 4) (BASE 0x0388))
(NAME "CTL00f0/-1[0]{Audio }")
(ACT Y)
))
# Joystick device - only if you need it :-/
(CONFIGURE CTL00f0/-1 (LD 1
(IO 0 (SIZE 1) (BASE 0x0200))
(NAME "CTL00f0/-1[1]{Game }")
(ACT Y)
))
(WAITFORKEY)
<end of snipping>
So, after a good kernel modules compilation and a 'depmod -a kernel_ver'
you may want to:
modprobe sb io=0x220 irq=5 dma=1 dma16=3
Or, take the hard way:
modprobe soundcore
modprobe sound
modprobe uart401
modprobe sb io=0x220 irq=5 dma=1 dma16=3
# do you need MIDI?
modprobe opl3=0x388
Just in case, the kernel sound support should be:
CONFIG_SOUND=m
CONFIG_SOUND_OSS=m
CONFIG_SOUND_SB=m
Enjoy your new noisy Linux box! ;)

View file

@ -1,170 +0,0 @@
(the following is from the armlinux CVS)
WaveArtist mixer and volume levels can be accessed via these commands:
nn30 read registers nn, where nn = 00 - 09 for mixer settings
0a - 13 for channel volumes
mm31 write the volume setting in pairs, where mm = (nn - 10) / 2
rr32 write the mixer settings in pairs, where rr = nn/2
xx33 reset all settings to default
0y34 select mono source, y=0 = left, y=1 = right
bits
nn 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
00 | 0 | 0 0 1 1 | left line mixer gain | left aux1 mixer gain |lmute|
----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
01 | 0 | 0 1 0 1 | left aux2 mixer gain | right 2 left mic gain |mmute|
----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
02 | 0 | 0 1 1 1 | left mic mixer gain | left mic | left mixer gain |dith |
----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
03 | 0 | 1 0 0 1 | left mixer input select |lrfg | left ADC gain |
----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
04 | 0 | 1 0 1 1 | right line mixer gain | right aux1 mixer gain |rmute|
----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
05 | 0 | 1 1 0 1 | right aux2 mixer gain | left 2 right mic gain |test |
----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
06 | 0 | 1 1 1 1 | right mic mixer gain | right mic |right mixer gain |rbyps|
----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
07 | 1 | 0 0 0 1 | right mixer select |rrfg | right ADC gain |
----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
08 | 1 | 0 0 1 1 | mono mixer gain |right ADC mux sel|left ADC mux sel |
----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
09 | 1 | 0 1 0 1 |loopb|left linout|loop|ADCch|TxFch|OffCD|test |loopb|loopb|osamp|
----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
0a | 0 | left PCM channel volume |
----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
0b | 0 | right PCM channel volume |
----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
0c | 0 | left FM channel volume |
----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
0d | 0 | right FM channel volume |
----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
0e | 0 | left wavetable channel volume |
----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
0f | 0 | right wavetable channel volume |
----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
10 | 0 | left PCM expansion channel volume |
----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
11 | 0 | right PCM expansion channel volume |
----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
12 | 0 | left FM expansion channel volume |
----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
13 | 0 | right FM expansion channel volume |
----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
lmute: left mute
mmute: mono mute
dith: dithds
lrfg:
rmute: right mute
rbyps: right bypass
rrfg:
ADCch:
TxFch:
OffCD:
osamp:
And the following diagram is derived from the description in the CVS archive:
MIC L (mouthpiece)
+------+
-->PreAmp>-\
+--^---+ |
| |
r2b4-5 | +--------+
/----*-------------------------------->5 |
| | |
| /----------------------------------->4 |
| | | |
| | /--------------------------------->3 1of5 | +---+
| | | | mux >-->AMP>--> ADC L
| | | /------------------------------->2 | +-^-+
| | | | | | |
Line | | | | +----+ +------+ +---+ /---->1 | r3b3-0
------------*->mute>--> Gain >--> | | | |
L | | | +----+ +------+ | | | *->0 |
| | | | | | +---^----+
Aux2 | | | +----+ +------+ | | | |
----------*--->mute>--> Gain >--> M | | r8b0-2
L | | +----+ +------+ | | |
| | | | \------\
Aux1 | | +----+ +------+ | | |
--------*----->mute>--> Gain >--> I | |
L | +----+ +------+ | | |
| | | |
| +----+ +------+ | | +---+ |
*------->mute>--> Gain >--> X >-->AMP>--*
| +----+ +------+ | | +-^-+ |
| | | | |
| +----+ +------+ | | r2b1-3 |
| /----->mute>--> Gain >--> E | |
| | +----+ +------+ | | |
| | | | |
| | +----+ +------+ | | |
| | /--->mute>--> Gain >--> R | |
| | | +----+ +------+ | | |
| | | | | | r9b8-9
| | | +----+ +------+ | | | |
| | | /->mute>--> Gain >--> | | +---v---+
| | | | +----+ +------+ +---+ /-*->0 |
DAC | | | | | | |
------------*----------------------------------->? | +----+
L | | | | | Mux >-->mute>--> L output
| | | | /->? | +--^-+
| | | | | | | |
| | | /--------->? | r0b0
| | | | | | +-------+
| | | | | |
Mono | | | | | | +-------+
----------* | \---> | +----+
| | | | | | Mix >-->mute>--> Mono output
| | | | *-> | +--^-+
| | | | | +-------+ |
| | | | | r1b0
DAC | | | | | +-------+
------------*-------------------------*--------->1 | +----+
R | | | | | | Mux >-->mute>--> R output
| | | | +----+ +------+ +---+ *->0 | +--^-+
| | | \->mute>--> Gain >--> | | +---^---+ |
| | | +----+ +------+ | | | | r5b0
| | | | | | r6b0
| | | +----+ +------+ | | |
| | \--->mute>--> Gain >--> M | |
| | +----+ +------+ | | |
| | | | |
| | +----+ +------+ | | |
| *----->mute>--> Gain >--> I | |
| | +----+ +------+ | | |
| | | | |
| | +----+ +------+ | | +---+ |
\------->mute>--> Gain >--> X >-->AMP>--*
| +----+ +------+ | | +-^-+ |
/--/ | | | |
Aux1 | +----+ +------+ | | r6b1-3 |
-------*------>mute>--> Gain >--> E | |
R | | +----+ +------+ | | |
| | | | |
Aux2 | | +----+ +------+ | | /------/
---------*---->mute>--> Gain >--> R | |
R | | | +----+ +------+ | | |
| | | | | | +--------+
Line | | | +----+ +------+ | | | *->0 |
-----------*-->mute>--> Gain >--> | | | |
R | | | | +----+ +------+ +---+ \---->1 |
| | | | | |
| | | \-------------------------------->2 | +---+
| | | | Mux >-->AMP>--> ADC R
| | \---------------------------------->3 | +-^-+
| | | | |
| \------------------------------------>4 | r7b3-0
| | |
\-----*-------------------------------->5 |
| +---^----+
r6b4-5 | |
| | r8b3-5
+--v---+ |
-->PreAmp>-/
+------+
MIC R (electret mic)

View file

@ -1,92 +0,0 @@
Intro
=====
people start bugging me about this with questions, looks like I
should write up some documentation for this beast. That way I
don't have to answer that much mails I hope. Yes, I'm lazy...
You might have noticed that the bt878 grabber cards have actually
_two_ PCI functions:
$ lspci
[ ... ]
00:0a.0 Multimedia video controller: Brooktree Corporation Bt878 (rev 02)
00:0a.1 Multimedia controller: Brooktree Corporation Bt878 (rev 02)
[ ... ]
The first does video, it is backward compatible to the bt848. The second
does audio. btaudio is a driver for the second function. It's a sound
driver which can be used for recording sound (and _only_ recording, no
playback). As most TV cards come with a short cable which can be plugged
into your sound card's line-in you probably don't need this driver if all
you want to do is just watching TV...
Driver Status
=============
Still somewhat experimental. The driver should work stable, i.e. it
should'nt crash your box. It might not work as expected, have bugs,
not being fully OSS API compliant, ...
Latest versions are available from http://bytesex.org/bttv/, the
driver is in the bttv tarball. Kernel patches might be available too,
have a look at http://bytesex.org/bttv/listing.html.
The chip knows two different modes. btaudio registers two dsp
devices, one for each mode. They can not be used at the same time.
Digital audio mode
==================
The chip gives you 16 bit stereo sound. The sample rate depends on
the external source which feeds the bt878 with digital sound via I2S
interface. There is a insmod option (rate) to tell the driver which
sample rate the hardware uses (32000 is the default).
One possible source for digital sound is the msp34xx audio processor
chip which provides digital sound via I2S with 32 kHz sample rate. My
Hauppauge board works this way.
The Osprey-200 reportly gives you digital sound with 44100 Hz sample
rate. It is also possible that you get no sound at all.
analog mode (A/D)
=================
You can tell the driver to use this mode with the insmod option "analog=1".
The chip has three analog inputs. Consequently you'll get a mixer device
to control these.
The analog mode supports mono only. Both 8 + 16 bit. Both are _signed_
int, which is uncommon for the 8 bit case. Sample rate range is 119 kHz
to 448 kHz. Yes, the number of digits is correct. The driver supports
downsampling by powers of two, so you can ask for more usual sample rates
like 44 kHz too.
With my Hauppauge I get noisy sound on the second input (mapped to line2
by the mixer device). Others get a useable signal on line1.
some examples
=============
* read audio data from btaudio (dsp2), send to es1730 (dsp,dsp1):
$ sox -w -r 32000 -t ossdsp /dev/dsp2 -t ossdsp /dev/dsp
* read audio data from btaudio, send to esound daemon (which might be
running on another host):
$ sox -c 2 -w -r 32000 -t ossdsp /dev/dsp2 -t sw - | esdcat -r 32000
$ sox -c 1 -w -r 32000 -t ossdsp /dev/dsp2 -t sw - | esdcat -m -r 32000
Have fun,
Gerd
--
Gerd Knorr <kraxel@bytesex.org>

View file

@ -1,185 +0,0 @@
How to try to survive an IBM Mwave under Linux SB drivers
+ IBM have now released documentation of sorts and Torsten is busy
trying to make the Mwave work. This is not however a trivial task.
----------------------------------------------------------------------------
OK, first thing - the IRQ problem IS a problem, whether the test is bypassed or
not. It is NOT a Linux problem, but an MWAVE problem that is fixed with the
latest MWAVE patches. So, in other words, don't bypass the test for MWAVES!
I have Windows 95 on /dev/hda1, swap on /dev/hda2, and Red Hat 5 on /dev/hda3.
The steps, then:
Boot to Linux.
Mount Windows 95 file system (assume mount point = /dos95).
mkdir /dos95/linux
mkdir /dos95/linux/boot
mkdir /dos95/linux/boot/parms
Copy the kernel, any initrd image, and loadlin to /dos95/linux/boot/.
Reboot to Windows 95.
Edit C:/msdos.sys and add or change the following:
Logo=0
BootGUI=0
Note that msdos.sys is a text file but it needs to be made 'unhidden',
readable and writable before it can be edited. This can be done with
DOS' "attrib" command.
Edit config.sys to have multiple config menus. I have one for windows 95 and
five for Linux, like this:
------------
[menu]
menuitem=W95, Windows 95
menuitem=LINTP, Linux - ThinkPad
menuitem=LINTP3, Linux - ThinkPad Console
menuitem=LINDOC, Linux - Docked
menuitem=LINDOC3, Linux - Docked Console
menuitem=LIN1, Linux - Single User Mode
REM menudefault=W95,10
[W95]
[LINTP]
[LINDOC]
[LINTP3]
[LINDOC3]
[LIN1]
[COMMON]
FILES=30
REM Please read README.TXT in C:\MWW subdirectory before changing the DOS= statement.
DOS=HIGH,UMB
DEVICE=C:\MWW\MANAGER\MWD50430.EXE
SHELL=c:\command.com /e:2048
-------------------
The important things are the SHELL and DEVICE statements.
Then change autoexec.bat. Basically everything in there originally should be
done ONLY when Windows 95 is booted. Then you add new things specifically
for Linux. Mine is as follows
---------------
@ECHO OFF
if "%CONFIG%" == "W95" goto W95
REM
REM Linux stuff
REM
SET MWPATH=C:\MWW\DLL;C:\MWW\MWGAMES;C:\MWW\DSP
SET BLASTER=A220 I5 D1
SET MWROOT=C:\MWW
SET LIBPATH=C:\MWW\DLL
SET PATH=C:\WINDOWS;C:\MWW\DLL;
CALL MWAVE START NOSHOW
c:\linux\boot\loadlin.exe @c:\linux\boot\parms\%CONFIG%.par
:W95
REM
REM Windows 95 stuff
REM
c:\toolkit\guard
SET MSINPUT=C:\MSINPUT
SET MWPATH=C:\MWW\DLL;C:\MWW\MWGAMES;C:\MWW\DSP
REM The following is used by DOS games to recognize Sound Blaster hardware.
REM If hardware settings are changed, please change this line as well.
REM See the Mwave README file for instructions.
SET BLASTER=A220 I5 D1
SET MWROOT=C:\MWW
SET LIBPATH=C:\MWW\DLL
SET PATH=C:\WINDOWS;C:\WINDOWS\COMMAND;E:\ORAWIN95\BIN;f:\msdev\bin;e:\v30\bin.dbg;v:\devt\v30\bin;c:\JavaSDK\Bin;C:\MWW\DLL;
SET INCLUDE=f:\MSDEV\INCLUDE;F:\MSDEV\MFC\INCLUDE
SET LIB=F:\MSDEV\LIB;F:\MSDEV\MFC\LIB
win
------------------------
Now build a file in c:\linux\boot\parms for each Linux config that you have.
For example, my LINDOC3 config is for a docked Thinkpad at runlevel 3 with no
initrd image, and has a parameter file named LINDOC3.PAR in c:\linux\boot\parms:
-----------------------
# LOADLIN @param_file image=other_image root=/dev/other
#
# Linux Console in docking station
#
c:\linux\boot\zImage.krn # First value must be filename of Linux kernel.
root=/dev/hda3 # device which gets mounted as root FS
ro # Other kernel arguments go here.
apm=off
doc=yes
3
-----------------------
The doc=yes parameter is an environment variable used by my init scripts, not
a kernel argument.
However, the apm=off parameter IS a kernel argument! APM, at least in my setup,
causes the kernel to crash when loaded via loadlin (but NOT when loaded via
LILO). The APM stuff COULD be forced out of the kernel via the kernel compile
options. Instead, I got an unofficial patch to the APM drivers that allows them
to be dynamically deactivated via kernel arguments. Whatever you chose to
document, APM, it seems, MUST be off for setups like mine.
Now make sure C:\MWW\MWCONFIG.REF looks like this:
----------------------
[NativeDOS]
Default=SB1.5
SBInputSource=CD
SYNTH=FM
QSound=OFF
Reverb=OFF
Chorus=OFF
ReverbDepth=5
ChorusDepth=5
SBInputVolume=5
SBMainVolume=10
SBWaveVolume=10
SBSynthVolume=10
WaveTableVolume=10
AudioPowerDriver=ON
[FastCFG]
Show=No
HideOption=Off
-----------------------------
OR the Default= line COULD be
Default=SBPRO
Reboot to Windows 95 and choose Linux. When booted, use sndconfig to configure
the sound modules and voilà - ThinkPad sound with Linux.
Now the gotchas - you can either have CD sound OR Mixers but not both. That's a
problem with the SB1.5 (CD sound) or SBPRO (Mixers) settings. No one knows why
this is!
For some reason MPEG3 files, when played through mpg123, sound like they
are playing at 1/8th speed - not very useful! If you have ANY insight
on why this second thing might be happening, I would be grateful.
===========================================================
_/ _/_/_/_/
_/_/ _/_/ _/
_/ _/_/ _/_/_/_/ Martin John Bartlett
_/ _/ _/ _/ (martin@nitram.demon.co.uk)
_/ _/_/_/_/
_/
_/ _/
_/_/
===========================================================

View file

@ -1,51 +0,0 @@
OSS Kernel Parameters
~~~~~~~~~~~~~~~~~~~~~
See Documentation/admin-guide/kernel-parameters.rst for general information on
specifying module parameters.
This document may not be entirely up to date and comprehensive. The command
"modinfo -p ${modulename}" shows a current list of all parameters of a loadable
module. Loadable modules, after being loaded into the running kernel, also
reveal their parameters in /sys/module/${modulename}/parameters/. Some of these
parameters may be changed at runtime by the command
"echo -n ${value} > /sys/module/${modulename}/parameters/${parm}".
ad1848= [HW,OSS]
Format: <io>,<irq>,<dma>,<dma2>,<type>
aedsp16= [HW,OSS] Audio Excel DSP 16
Format: <io>,<irq>,<dma>,<mss_io>,<mpu_io>,<mpu_irq>
See also header of sound/oss/aedsp16.c.
dmasound= [HW,OSS] Sound subsystem buffers
mpu401= [HW,OSS]
Format: <io>,<irq>
opl3= [HW,OSS]
Format: <io>
pas2= [HW,OSS] Format:
<io>,<irq>,<dma>,<dma16>,<sb_io>,<sb_irq>,<sb_dma>,<sb_dma16>
pss= [HW,OSS] Personal Sound System (ECHO ESC614)
Format:
<io>,<mss_io>,<mss_irq>,<mss_dma>,<mpu_io>,<mpu_irq>
sscape= [HW,OSS]
Format: <io>,<irq>,<dma>,<mpu_io>,<mpu_irq>
trix= [HW,OSS] MediaTrix AudioTrix Pro
Format:
<io>,<irq>,<dma>,<dma2>,<sb_io>,<sb_irq>,<sb_dma>,<mpu_io>,<mpu_irq>
uart401= [HW,OSS]
Format: <io>,<irq>
uart6850= [HW,OSS]
Format: <io>,<irq>
waveartist= [HW,OSS]
Format: <io>,<irq>,<dma>,<dma2>

View file

@ -1,30 +0,0 @@
modprobe sound
insmod ad1848
insmod gus io=* irq=* dma=* ...
This loads the driver for the Gravis Ultrasound family of sound cards.
The gus module takes the following arguments
io I/O address of the Ultrasound card (eg. io=0x220)
irq IRQ of the Sound Blaster card
dma DMA channel for the Sound Blaster
dma16 2nd DMA channel, only needed for full duplex operation
type 1 for PnP card
gus16 1 for using 16 bit sampling daughter board
no_wave_dma Set to disable DMA usage for wavetable (see note)
db16 ???
no_wave_dma option
This option defaults to a value of 0, which allows the Ultrasound wavetable
DSP to use DMA for playback and downloading samples. This is the same
as the old behaviour. If set to 1, no DMA is needed for downloading samples,
and allows owners of a GUS MAX to make use of simultaneous digital audio
(/dev/dsp), MIDI, and wavetable playback.
If you have problems in recording with GUS MAX, you could try to use
just one 8 bit DMA channel. Recording will not work with one DMA
channel if it's a 16 bit one.

View file

@ -527,11 +527,6 @@ W: http://ez.analog.com/community/linux-device-drivers
S: Supported
F: drivers/input/misc/adxl34x.c
AEDSP16 DRIVER
M: Riccardo Facchetti <fizban@tin.it>
S: Maintained
F: sound/oss/aedsp16.c
AF9013 MEDIA DRIVER
M: Antti Palosaari <crope@iki.fi>
L: linux-media@vger.kernel.org
@ -9222,12 +9217,6 @@ F: include/linux/dt-bindings/mux/
F: include/linux/mux/
F: drivers/mux/
MULTISOUND SOUND DRIVER
M: Andrew Veliath <andrewtv@usa.net>
S: Maintained
F: Documentation/sound/oss/MultiSound
F: sound/oss/msnd*
MULTITECH MULTIPORT CARD (ISICOM)
S: Orphan
F: drivers/tty/isicom.c
@ -14638,6 +14627,7 @@ F: Documentation/devicetree/bindings/extcon/extcon-arizona.txt
F: Documentation/devicetree/bindings/regulator/arizona-regulator.txt
F: Documentation/devicetree/bindings/mfd/arizona.txt
F: Documentation/devicetree/bindings/mfd/wm831x.txt
F: Documentation/devicetree/bindings/sound/wlf,arizona.txt
F: arch/arm/mach-s3c64xx/mach-crag6410*
F: drivers/clk/clk-wm83*.c
F: drivers/extcon/extcon-arizona.c

View file

@ -371,6 +371,8 @@ static int acp_hw_init(void *handle)
adev->acp.acp_cell[0].name = "acp_audio_dma";
adev->acp.acp_cell[0].num_resources = 4;
adev->acp.acp_cell[0].resources = &adev->acp.acp_res[0];
adev->acp.acp_cell[0].platform_data = &adev->asic_type;
adev->acp.acp_cell[0].pdata_size = sizeof(adev->asic_type);
adev->acp.acp_cell[1].name = "designware-i2s";
adev->acp.acp_cell[1].num_resources = 1;

View file

@ -23,34 +23,9 @@
#ifndef __AMD_SHARED_H__
#define __AMD_SHARED_H__
#define AMD_MAX_USEC_TIMEOUT 200000 /* 200 ms */
#include <drm/amd_asic_type.h>
/*
* Supported ASIC types
*/
enum amd_asic_type {
CHIP_TAHITI = 0,
CHIP_PITCAIRN,
CHIP_VERDE,
CHIP_OLAND,
CHIP_HAINAN,
CHIP_BONAIRE,
CHIP_KAVERI,
CHIP_KABINI,
CHIP_HAWAII,
CHIP_MULLINS,
CHIP_TOPAZ,
CHIP_TONGA,
CHIP_FIJI,
CHIP_CARRIZO,
CHIP_STONEY,
CHIP_POLARIS10,
CHIP_POLARIS11,
CHIP_POLARIS12,
CHIP_VEGA10,
CHIP_RAVEN,
CHIP_LAST,
};
#define AMD_MAX_USEC_TIMEOUT 200000 /* 200 ms */
/*
* Chip flags

View file

@ -727,7 +727,7 @@ config TOUCHSCREEN_WM831X
config TOUCHSCREEN_WM97XX
tristate "Support for WM97xx AC97 touchscreen controllers"
depends on AC97_BUS
depends on AC97_BUS || AC97_BUS_NEW
help
Say Y here if you have a Wolfson Microelectronics WM97xx
touchscreen connected to your system. Note that this option

View file

@ -44,6 +44,7 @@
#include <linux/pm.h>
#include <linux/interrupt.h>
#include <linux/bitops.h>
#include <linux/mfd/wm97xx.h>
#include <linux/workqueue.h>
#include <linux/wm97xx.h>
#include <linux/uaccess.h>
@ -581,27 +582,85 @@ static void wm97xx_ts_input_close(struct input_dev *idev)
wm->codec->acc_enable(wm, 0);
}
static int wm97xx_probe(struct device *dev)
static int wm97xx_register_touch(struct wm97xx *wm)
{
struct wm97xx *wm;
struct wm97xx_pdata *pdata = dev_get_platdata(dev);
int ret = 0, id = 0;
struct wm97xx_pdata *pdata = dev_get_platdata(wm->dev);
int ret;
wm = kzalloc(sizeof(struct wm97xx), GFP_KERNEL);
if (!wm)
wm->input_dev = devm_input_allocate_device(wm->dev);
if (wm->input_dev == NULL)
return -ENOMEM;
mutex_init(&wm->codec_mutex);
wm->dev = dev;
dev_set_drvdata(dev, wm);
wm->ac97 = to_ac97_t(dev);
/* set up touch configuration */
wm->input_dev->name = "wm97xx touchscreen";
wm->input_dev->phys = "wm97xx";
wm->input_dev->open = wm97xx_ts_input_open;
wm->input_dev->close = wm97xx_ts_input_close;
__set_bit(EV_ABS, wm->input_dev->evbit);
__set_bit(EV_KEY, wm->input_dev->evbit);
__set_bit(BTN_TOUCH, wm->input_dev->keybit);
input_set_abs_params(wm->input_dev, ABS_X, abs_x[0], abs_x[1],
abs_x[2], 0);
input_set_abs_params(wm->input_dev, ABS_Y, abs_y[0], abs_y[1],
abs_y[2], 0);
input_set_abs_params(wm->input_dev, ABS_PRESSURE, abs_p[0], abs_p[1],
abs_p[2], 0);
input_set_drvdata(wm->input_dev, wm);
wm->input_dev->dev.parent = wm->dev;
ret = input_register_device(wm->input_dev);
if (ret)
return ret;
/*
* register our extended touch device (for machine specific
* extensions)
*/
wm->touch_dev = platform_device_alloc("wm97xx-touch", -1);
if (!wm->touch_dev) {
ret = -ENOMEM;
goto touch_err;
}
platform_set_drvdata(wm->touch_dev, wm);
wm->touch_dev->dev.parent = wm->dev;
wm->touch_dev->dev.platform_data = pdata;
ret = platform_device_add(wm->touch_dev);
if (ret < 0)
goto touch_reg_err;
return 0;
touch_reg_err:
platform_device_put(wm->touch_dev);
touch_err:
input_unregister_device(wm->input_dev);
wm->input_dev = NULL;
return ret;
}
static void wm97xx_unregister_touch(struct wm97xx *wm)
{
platform_device_unregister(wm->touch_dev);
input_unregister_device(wm->input_dev);
wm->input_dev = NULL;
}
static int _wm97xx_probe(struct wm97xx *wm)
{
int id = 0;
mutex_init(&wm->codec_mutex);
dev_set_drvdata(wm->dev, wm);
/* check that we have a supported codec */
id = wm97xx_reg_read(wm, AC97_VENDOR_ID1);
if (id != WM97XX_ID1) {
dev_err(dev, "Device with vendor %04x is not a wm97xx\n", id);
ret = -ENODEV;
goto alloc_err;
dev_err(wm->dev,
"Device with vendor %04x is not a wm97xx\n", id);
return -ENODEV;
}
wm->id = wm97xx_reg_read(wm, AC97_VENDOR_ID2);
@ -629,8 +688,7 @@ static int wm97xx_probe(struct device *dev)
default:
dev_err(wm->dev, "Support for wm97%02x not compiled in.\n",
wm->id & 0xff);
ret = -ENODEV;
goto alloc_err;
return -ENODEV;
}
/* set up physical characteristics */
@ -644,79 +702,58 @@ static int wm97xx_probe(struct device *dev)
wm->gpio[4] = wm97xx_reg_read(wm, AC97_GPIO_STATUS);
wm->gpio[5] = wm97xx_reg_read(wm, AC97_MISC_AFE);
wm->input_dev = input_allocate_device();
if (wm->input_dev == NULL) {
ret = -ENOMEM;
goto alloc_err;
}
return wm97xx_register_touch(wm);
}
/* set up touch configuration */
wm->input_dev->name = "wm97xx touchscreen";
wm->input_dev->phys = "wm97xx";
wm->input_dev->open = wm97xx_ts_input_open;
wm->input_dev->close = wm97xx_ts_input_close;
static void wm97xx_remove_battery(struct wm97xx *wm)
{
platform_device_unregister(wm->battery_dev);
}
__set_bit(EV_ABS, wm->input_dev->evbit);
__set_bit(EV_KEY, wm->input_dev->evbit);
__set_bit(BTN_TOUCH, wm->input_dev->keybit);
static int wm97xx_add_battery(struct wm97xx *wm,
struct wm97xx_batt_pdata *pdata)
{
int ret;
input_set_abs_params(wm->input_dev, ABS_X, abs_x[0], abs_x[1],
abs_x[2], 0);
input_set_abs_params(wm->input_dev, ABS_Y, abs_y[0], abs_y[1],
abs_y[2], 0);
input_set_abs_params(wm->input_dev, ABS_PRESSURE, abs_p[0], abs_p[1],
abs_p[2], 0);
input_set_drvdata(wm->input_dev, wm);
wm->input_dev->dev.parent = dev;
ret = input_register_device(wm->input_dev);
if (ret < 0)
goto dev_alloc_err;
/* register our battery device */
wm->battery_dev = platform_device_alloc("wm97xx-battery", -1);
if (!wm->battery_dev) {
ret = -ENOMEM;
goto batt_err;
}
platform_set_drvdata(wm->battery_dev, wm);
wm->battery_dev->dev.parent = dev;
wm->battery_dev->dev.platform_data = pdata ? pdata->batt_pdata : NULL;
ret = platform_device_add(wm->battery_dev);
if (ret < 0)
goto batt_reg_err;
if (!wm->battery_dev)
return -ENOMEM;
/* register our extended touch device (for machine specific
* extensions) */
wm->touch_dev = platform_device_alloc("wm97xx-touch", -1);
if (!wm->touch_dev) {
ret = -ENOMEM;
goto touch_err;
}
platform_set_drvdata(wm->touch_dev, wm);
wm->touch_dev->dev.parent = dev;
wm->touch_dev->dev.platform_data = pdata;
ret = platform_device_add(wm->touch_dev);
platform_set_drvdata(wm->battery_dev, wm);
wm->battery_dev->dev.parent = wm->dev;
wm->battery_dev->dev.platform_data = pdata;
ret = platform_device_add(wm->battery_dev);
if (ret)
platform_device_put(wm->battery_dev);
return ret;
}
static int wm97xx_probe(struct device *dev)
{
struct wm97xx *wm;
int ret;
struct wm97xx_pdata *pdata = dev_get_platdata(dev);
wm = devm_kzalloc(dev, sizeof(struct wm97xx), GFP_KERNEL);
if (!wm)
return -ENOMEM;
wm->dev = dev;
wm->ac97 = to_ac97_t(dev);
ret = _wm97xx_probe(wm);
if (ret)
return ret;
ret = wm97xx_add_battery(wm, pdata ? pdata->batt_pdata : NULL);
if (ret < 0)
goto touch_reg_err;
goto batt_err;
return ret;
touch_reg_err:
platform_device_put(wm->touch_dev);
touch_err:
platform_device_del(wm->battery_dev);
batt_reg_err:
platform_device_put(wm->battery_dev);
batt_err:
input_unregister_device(wm->input_dev);
wm->input_dev = NULL;
dev_alloc_err:
input_free_device(wm->input_dev);
alloc_err:
kfree(wm);
batt_err:
wm97xx_unregister_touch(wm);
return ret;
}
@ -724,14 +761,45 @@ static int wm97xx_remove(struct device *dev)
{
struct wm97xx *wm = dev_get_drvdata(dev);
platform_device_unregister(wm->battery_dev);
platform_device_unregister(wm->touch_dev);
input_unregister_device(wm->input_dev);
kfree(wm);
wm97xx_remove_battery(wm);
wm97xx_unregister_touch(wm);
return 0;
}
static int wm97xx_mfd_probe(struct platform_device *pdev)
{
struct wm97xx *wm;
struct wm97xx_platform_data *mfd_pdata = dev_get_platdata(&pdev->dev);
int ret;
wm = devm_kzalloc(&pdev->dev, sizeof(struct wm97xx), GFP_KERNEL);
if (!wm)
return -ENOMEM;
wm->dev = &pdev->dev;
wm->ac97 = mfd_pdata->ac97;
ret = _wm97xx_probe(wm);
if (ret)
return ret;
ret = wm97xx_add_battery(wm, mfd_pdata->batt_pdata);
if (ret < 0)
goto batt_err;
return ret;
batt_err:
wm97xx_unregister_touch(wm);
return ret;
}
static int wm97xx_mfd_remove(struct platform_device *pdev)
{
return wm97xx_remove(&pdev->dev);
}
static int __maybe_unused wm97xx_suspend(struct device *dev)
{
struct wm97xx *wm = dev_get_drvdata(dev);
@ -828,21 +896,41 @@ EXPORT_SYMBOL_GPL(wm97xx_unregister_mach_ops);
static struct device_driver wm97xx_driver = {
.name = "wm97xx-ts",
#ifdef CONFIG_AC97_BUS
.bus = &ac97_bus_type,
#endif
.owner = THIS_MODULE,
.probe = wm97xx_probe,
.remove = wm97xx_remove,
.pm = &wm97xx_pm_ops,
};
static struct platform_driver wm97xx_mfd_driver = {
.driver = {
.name = "wm97xx-ts",
.pm = &wm97xx_pm_ops,
},
.probe = wm97xx_mfd_probe,
.remove = wm97xx_mfd_remove,
};
static int __init wm97xx_init(void)
{
return driver_register(&wm97xx_driver);
int ret;
ret = platform_driver_register(&wm97xx_mfd_driver);
if (ret)
return ret;
if (IS_BUILTIN(CONFIG_AC97_BUS))
ret = driver_register(&wm97xx_driver);
return ret;
}
static void __exit wm97xx_exit(void)
{
driver_unregister(&wm97xx_driver);
platform_driver_unregister(&wm97xx_mfd_driver);
}
module_init(wm97xx_init);

View file

@ -1746,6 +1746,20 @@ config MFD_WM8994
core support for the WM8994, in order to use the actual
functionaltiy of the device other drivers must be enabled.
config MFD_WM97xx
tristate "Wolfson Microelectronics WM97xx"
select MFD_CORE
select REGMAP_AC97
select AC97_BUS_COMPAT
depends on AC97_BUS_NEW
help
The WM9705, WM9712 and WM9713 is a highly integrated hi-fi CODEC
designed for smartphone applications. As well as audio functionality
it has on board GPIO and a touchscreen functionality which is
supported via the relevant subsystems. This driver provides core
support for the WM97xx, in order to use the actual functionaltiy of
the device other drivers must be enabled.
config MFD_STW481X
tristate "Support for ST Microelectronics STw481x"
depends on I2C && (ARCH_NOMADIK || COMPILE_TEST)

View file

@ -74,6 +74,7 @@ obj-$(CONFIG_MFD_WM8350) += wm8350.o
obj-$(CONFIG_MFD_WM8350_I2C) += wm8350-i2c.o
wm8994-objs := wm8994-core.o wm8994-irq.o wm8994-regmap.o
obj-$(CONFIG_MFD_WM8994) += wm8994.o
obj-$(CONFIG_MFD_WM97xx) += wm97xx-core.o
obj-$(CONFIG_TPS6105X) += tps6105x.o
obj-$(CONFIG_TPS65010) += tps65010.o

View file

@ -797,12 +797,7 @@ EXPORT_SYMBOL_GPL(arizona_of_get_type);
static int arizona_of_get_core_pdata(struct arizona *arizona)
{
struct arizona_pdata *pdata = &arizona->pdata;
struct property *prop;
const __be32 *cur;
u32 val;
u32 pdm_val[ARIZONA_MAX_PDM_SPK];
int ret, i;
int count = 0;
pdata->reset = of_get_named_gpio(arizona->dev->of_node, "wlf,reset", 0);
if (pdata->reset == -EPROBE_DEFER) {
@ -836,64 +831,6 @@ static int arizona_of_get_core_pdata(struct arizona *arizona)
ret);
}
of_property_for_each_u32(arizona->dev->of_node, "wlf,inmode", prop,
cur, val) {
if (count == ARRAY_SIZE(pdata->inmode))
break;
pdata->inmode[count] = val;
count++;
}
count = 0;
of_property_for_each_u32(arizona->dev->of_node, "wlf,dmic-ref", prop,
cur, val) {
if (count == ARRAY_SIZE(pdata->dmic_ref))
break;
pdata->dmic_ref[count] = val;
count++;
}
count = 0;
of_property_for_each_u32(arizona->dev->of_node, "wlf,out-mono", prop,
cur, val) {
if (count == ARRAY_SIZE(pdata->out_mono))
break;
pdata->out_mono[count] = !!val;
count++;
}
count = 0;
of_property_for_each_u32(arizona->dev->of_node,
"wlf,max-channels-clocked",
prop, cur, val) {
if (count == ARRAY_SIZE(pdata->max_channels_clocked))
break;
pdata->max_channels_clocked[count] = val;
count++;
}
ret = of_property_read_u32_array(arizona->dev->of_node,
"wlf,spk-fmt",
pdm_val,
ARRAY_SIZE(pdm_val));
if (ret >= 0)
for (count = 0; count < ARRAY_SIZE(pdata->spk_fmt); ++count)
pdata->spk_fmt[count] = pdm_val[count];
ret = of_property_read_u32_array(arizona->dev->of_node,
"wlf,spk-mute",
pdm_val,
ARRAY_SIZE(pdm_val));
if (ret >= 0)
for (count = 0; count < ARRAY_SIZE(pdata->spk_mute); ++count)
pdata->spk_mute[count] = pdm_val[count];
return 0;
}
@ -1026,7 +963,7 @@ int arizona_dev_init(struct arizona *arizona)
const char * const mclk_name[] = { "mclk1", "mclk2" };
struct device *dev = arizona->dev;
const char *type_name = NULL;
unsigned int reg, val, mask;
unsigned int reg, val;
int (*apply_patch)(struct arizona *) = NULL;
const struct mfd_cell *subdevs = NULL;
int n_subdevs, ret, i;
@ -1429,73 +1366,6 @@ int arizona_dev_init(struct arizona *arizona)
ARIZONA_MICB1_RATE, val);
}
for (i = 0; i < ARIZONA_MAX_INPUT; i++) {
/* Default for both is 0 so noop with defaults */
val = arizona->pdata.dmic_ref[i]
<< ARIZONA_IN1_DMIC_SUP_SHIFT;
if (arizona->pdata.inmode[i] & ARIZONA_INMODE_DMIC)
val |= 1 << ARIZONA_IN1_MODE_SHIFT;
switch (arizona->type) {
case WM8998:
case WM1814:
regmap_update_bits(arizona->regmap,
ARIZONA_ADC_DIGITAL_VOLUME_1L + (i * 8),
ARIZONA_IN1L_SRC_SE_MASK,
(arizona->pdata.inmode[i] & ARIZONA_INMODE_SE)
<< ARIZONA_IN1L_SRC_SE_SHIFT);
regmap_update_bits(arizona->regmap,
ARIZONA_ADC_DIGITAL_VOLUME_1R + (i * 8),
ARIZONA_IN1R_SRC_SE_MASK,
(arizona->pdata.inmode[i] & ARIZONA_INMODE_SE)
<< ARIZONA_IN1R_SRC_SE_SHIFT);
mask = ARIZONA_IN1_DMIC_SUP_MASK |
ARIZONA_IN1_MODE_MASK;
break;
default:
if (arizona->pdata.inmode[i] & ARIZONA_INMODE_SE)
val |= 1 << ARIZONA_IN1_SINGLE_ENDED_SHIFT;
mask = ARIZONA_IN1_DMIC_SUP_MASK |
ARIZONA_IN1_MODE_MASK |
ARIZONA_IN1_SINGLE_ENDED_MASK;
break;
}
regmap_update_bits(arizona->regmap,
ARIZONA_IN1L_CONTROL + (i * 8),
mask, val);
}
for (i = 0; i < ARIZONA_MAX_OUTPUT; i++) {
/* Default is 0 so noop with defaults */
if (arizona->pdata.out_mono[i])
val = ARIZONA_OUT1_MONO;
else
val = 0;
regmap_update_bits(arizona->regmap,
ARIZONA_OUTPUT_PATH_CONFIG_1L + (i * 8),
ARIZONA_OUT1_MONO, val);
}
for (i = 0; i < ARIZONA_MAX_PDM_SPK; i++) {
if (arizona->pdata.spk_mute[i])
regmap_update_bits(arizona->regmap,
ARIZONA_PDM_SPK1_CTRL_1 + (i * 2),
ARIZONA_SPK1_MUTE_ENDIAN_MASK |
ARIZONA_SPK1_MUTE_SEQ1_MASK,
arizona->pdata.spk_mute[i]);
if (arizona->pdata.spk_fmt[i])
regmap_update_bits(arizona->regmap,
ARIZONA_PDM_SPK1_CTRL_2 + (i * 2),
ARIZONA_SPK1_FMT_MASK,
arizona->pdata.spk_fmt[i]);
}
pm_runtime_set_active(arizona->dev);
pm_runtime_enable(arizona->dev);

366
drivers/mfd/wm97xx-core.c Normal file
View file

@ -0,0 +1,366 @@
/*
* Wolfson WM97xx -- Core device
*
* Copyright (C) 2017 Robert Jarzmik
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Features:
* - an AC97 audio codec
* - a touchscreen driver
* - a GPIO block
*/
#include <linux/device.h>
#include <linux/mfd/core.h>
#include <linux/mfd/wm97xx.h>
#include <linux/module.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include <linux/wm97xx.h>
#include <sound/ac97/codec.h>
#include <sound/ac97/compat.h>
#define WM9705_VENDOR_ID 0x574d4c05
#define WM9712_VENDOR_ID 0x574d4c12
#define WM9713_VENDOR_ID 0x574d4c13
#define WM97xx_VENDOR_ID_MASK 0xffffffff
struct wm97xx_priv {
struct regmap *regmap;
struct snd_ac97 *ac97;
struct device *dev;
struct wm97xx_platform_data codec_pdata;
};
static bool wm97xx_readable_reg(struct device *dev, unsigned int reg)
{
switch (reg) {
case AC97_RESET ... AC97_PCM_SURR_DAC_RATE:
case AC97_PCM_LR_ADC_RATE:
case AC97_CENTER_LFE_MASTER:
case AC97_SPDIF ... AC97_LINE1_LEVEL:
case AC97_GPIO_CFG ... 0x5c:
case AC97_CODEC_CLASS_REV ... AC97_PCI_SID:
case 0x74 ... AC97_VENDOR_ID2:
return true;
default:
return false;
}
}
static bool wm97xx_writeable_reg(struct device *dev, unsigned int reg)
{
switch (reg) {
case AC97_VENDOR_ID1:
case AC97_VENDOR_ID2:
return false;
default:
return wm97xx_readable_reg(dev, reg);
}
}
static const struct reg_default wm9705_reg_defaults[] = {
{ 0x02, 0x8000 },
{ 0x04, 0x8000 },
{ 0x06, 0x8000 },
{ 0x0a, 0x8000 },
{ 0x0c, 0x8008 },
{ 0x0e, 0x8008 },
{ 0x10, 0x8808 },
{ 0x12, 0x8808 },
{ 0x14, 0x8808 },
{ 0x16, 0x8808 },
{ 0x18, 0x8808 },
{ 0x1a, 0x0000 },
{ 0x1c, 0x8000 },
{ 0x20, 0x0000 },
{ 0x22, 0x0000 },
{ 0x26, 0x000f },
{ 0x28, 0x0605 },
{ 0x2a, 0x0000 },
{ 0x2c, 0xbb80 },
{ 0x32, 0xbb80 },
{ 0x34, 0x2000 },
{ 0x5a, 0x0000 },
{ 0x5c, 0x0000 },
{ 0x72, 0x0808 },
{ 0x74, 0x0000 },
{ 0x76, 0x0006 },
{ 0x78, 0x0000 },
{ 0x7a, 0x0000 },
};
static const struct regmap_config wm9705_regmap_config = {
.reg_bits = 16,
.reg_stride = 2,
.val_bits = 16,
.max_register = 0x7e,
.cache_type = REGCACHE_RBTREE,
.reg_defaults = wm9705_reg_defaults,
.num_reg_defaults = ARRAY_SIZE(wm9705_reg_defaults),
.volatile_reg = regmap_ac97_default_volatile,
.readable_reg = wm97xx_readable_reg,
.writeable_reg = wm97xx_writeable_reg,
};
static struct mfd_cell wm9705_cells[] = {
{ .name = "wm9705-codec", },
{ .name = "wm97xx-ts", },
};
static bool wm9712_volatile_reg(struct device *dev, unsigned int reg)
{
switch (reg) {
case AC97_REC_GAIN:
return true;
default:
return regmap_ac97_default_volatile(dev, reg);
}
}
static const struct reg_default wm9712_reg_defaults[] = {
{ 0x02, 0x8000 },
{ 0x04, 0x8000 },
{ 0x06, 0x8000 },
{ 0x08, 0x0f0f },
{ 0x0a, 0xaaa0 },
{ 0x0c, 0xc008 },
{ 0x0e, 0x6808 },
{ 0x10, 0xe808 },
{ 0x12, 0xaaa0 },
{ 0x14, 0xad00 },
{ 0x16, 0x8000 },
{ 0x18, 0xe808 },
{ 0x1a, 0x3000 },
{ 0x1c, 0x8000 },
{ 0x20, 0x0000 },
{ 0x22, 0x0000 },
{ 0x26, 0x000f },
{ 0x28, 0x0605 },
{ 0x2a, 0x0410 },
{ 0x2c, 0xbb80 },
{ 0x2e, 0xbb80 },
{ 0x32, 0xbb80 },
{ 0x34, 0x2000 },
{ 0x4c, 0xf83e },
{ 0x4e, 0xffff },
{ 0x50, 0x0000 },
{ 0x52, 0x0000 },
{ 0x56, 0xf83e },
{ 0x58, 0x0008 },
{ 0x5c, 0x0000 },
{ 0x60, 0xb032 },
{ 0x62, 0x3e00 },
{ 0x64, 0x0000 },
{ 0x76, 0x0006 },
{ 0x78, 0x0001 },
{ 0x7a, 0x0000 },
};
static const struct regmap_config wm9712_regmap_config = {
.reg_bits = 16,
.reg_stride = 2,
.val_bits = 16,
.max_register = 0x7e,
.cache_type = REGCACHE_RBTREE,
.reg_defaults = wm9712_reg_defaults,
.num_reg_defaults = ARRAY_SIZE(wm9712_reg_defaults),
.volatile_reg = wm9712_volatile_reg,
.readable_reg = wm97xx_readable_reg,
.writeable_reg = wm97xx_writeable_reg,
};
static struct mfd_cell wm9712_cells[] = {
{ .name = "wm9712-codec", },
{ .name = "wm97xx-ts", },
};
static const struct reg_default wm9713_reg_defaults[] = {
{ 0x02, 0x8080 }, /* Speaker Output Volume */
{ 0x04, 0x8080 }, /* Headphone Output Volume */
{ 0x06, 0x8080 }, /* Out3/OUT4 Volume */
{ 0x08, 0xc880 }, /* Mono Volume */
{ 0x0a, 0xe808 }, /* LINEIN Volume */
{ 0x0c, 0xe808 }, /* DAC PGA Volume */
{ 0x0e, 0x0808 }, /* MIC PGA Volume */
{ 0x10, 0x00da }, /* MIC Routing Control */
{ 0x12, 0x8000 }, /* Record PGA Volume */
{ 0x14, 0xd600 }, /* Record Routing */
{ 0x16, 0xaaa0 }, /* PCBEEP Volume */
{ 0x18, 0xaaa0 }, /* VxDAC Volume */
{ 0x1a, 0xaaa0 }, /* AUXDAC Volume */
{ 0x1c, 0x0000 }, /* Output PGA Mux */
{ 0x1e, 0x0000 }, /* DAC 3D control */
{ 0x20, 0x0f0f }, /* DAC Tone Control*/
{ 0x22, 0x0040 }, /* MIC Input Select & Bias */
{ 0x24, 0x0000 }, /* Output Volume Mapping & Jack */
{ 0x26, 0x7f00 }, /* Powerdown Ctrl/Stat*/
{ 0x28, 0x0405 }, /* Extended Audio ID */
{ 0x2a, 0x0410 }, /* Extended Audio Start/Ctrl */
{ 0x2c, 0xbb80 }, /* Audio DACs Sample Rate */
{ 0x2e, 0xbb80 }, /* AUXDAC Sample Rate */
{ 0x32, 0xbb80 }, /* Audio ADCs Sample Rate */
{ 0x36, 0x4523 }, /* PCM codec control */
{ 0x3a, 0x2000 }, /* SPDIF control */
{ 0x3c, 0xfdff }, /* Powerdown 1 */
{ 0x3e, 0xffff }, /* Powerdown 2 */
{ 0x40, 0x0000 }, /* General Purpose */
{ 0x42, 0x0000 }, /* Fast Power-Up Control */
{ 0x44, 0x0080 }, /* MCLK/PLL Control */
{ 0x46, 0x0000 }, /* MCLK/PLL Control */
{ 0x4c, 0xfffe }, /* GPIO Pin Configuration */
{ 0x4e, 0xffff }, /* GPIO Pin Polarity / Type */
{ 0x50, 0x0000 }, /* GPIO Pin Sticky */
{ 0x52, 0x0000 }, /* GPIO Pin Wake-Up */
/* GPIO Pin Status */
{ 0x56, 0xfffe }, /* GPIO Pin Sharing */
{ 0x58, 0x4000 }, /* GPIO PullUp/PullDown */
{ 0x5a, 0x0000 }, /* Additional Functions 1 */
{ 0x5c, 0x0000 }, /* Additional Functions 2 */
{ 0x60, 0xb032 }, /* ALC Control */
{ 0x62, 0x3e00 }, /* ALC / Noise Gate Control */
{ 0x64, 0x0000 }, /* AUXDAC input control */
{ 0x74, 0x0000 }, /* Digitiser Reg 1 */
{ 0x76, 0x0006 }, /* Digitiser Reg 2 */
{ 0x78, 0x0001 }, /* Digitiser Reg 3 */
{ 0x7a, 0x0000 }, /* Digitiser Read Back */
};
static const struct regmap_config wm9713_regmap_config = {
.reg_bits = 16,
.reg_stride = 2,
.val_bits = 16,
.max_register = 0x7e,
.cache_type = REGCACHE_RBTREE,
.reg_defaults = wm9713_reg_defaults,
.num_reg_defaults = ARRAY_SIZE(wm9713_reg_defaults),
.volatile_reg = regmap_ac97_default_volatile,
.readable_reg = wm97xx_readable_reg,
.writeable_reg = wm97xx_writeable_reg,
};
static struct mfd_cell wm9713_cells[] = {
{ .name = "wm9713-codec", },
{ .name = "wm97xx-ts", },
};
static int wm97xx_ac97_probe(struct ac97_codec_device *adev)
{
struct wm97xx_priv *wm97xx;
const struct regmap_config *config;
struct wm97xx_platform_data *codec_pdata;
struct mfd_cell *cells;
int ret = -ENODEV, nb_cells, i;
struct wm97xx_pdata *pdata = snd_ac97_codec_get_platdata(adev);
wm97xx = devm_kzalloc(ac97_codec_dev2dev(adev),
sizeof(*wm97xx), GFP_KERNEL);
if (!wm97xx)
return -ENOMEM;
wm97xx->dev = ac97_codec_dev2dev(adev);
wm97xx->ac97 = snd_ac97_compat_alloc(adev);
if (IS_ERR(wm97xx->ac97))
return PTR_ERR(wm97xx->ac97);
ac97_set_drvdata(adev, wm97xx);
dev_info(wm97xx->dev, "wm97xx core found, id=0x%x\n",
adev->vendor_id);
codec_pdata = &wm97xx->codec_pdata;
codec_pdata->ac97 = wm97xx->ac97;
codec_pdata->batt_pdata = pdata->batt_pdata;
switch (adev->vendor_id) {
case WM9705_VENDOR_ID:
config = &wm9705_regmap_config;
cells = wm9705_cells;
nb_cells = ARRAY_SIZE(wm9705_cells);
break;
case WM9712_VENDOR_ID:
config = &wm9712_regmap_config;
cells = wm9712_cells;
nb_cells = ARRAY_SIZE(wm9712_cells);
break;
case WM9713_VENDOR_ID:
config = &wm9713_regmap_config;
cells = wm9713_cells;
nb_cells = ARRAY_SIZE(wm9713_cells);
break;
default:
goto err_free_compat;
}
for (i = 0; i < nb_cells; i++) {
cells[i].platform_data = codec_pdata;
cells[i].pdata_size = sizeof(*codec_pdata);
}
codec_pdata->regmap = devm_regmap_init_ac97(wm97xx->ac97, config);
if (IS_ERR(codec_pdata->regmap)) {
ret = PTR_ERR(codec_pdata->regmap);
goto err_free_compat;
}
ret = devm_mfd_add_devices(wm97xx->dev, PLATFORM_DEVID_NONE,
cells, nb_cells, NULL, 0, NULL);
if (ret)
goto err_free_compat;
return ret;
err_free_compat:
snd_ac97_compat_release(wm97xx->ac97);
return ret;
}
static int wm97xx_ac97_remove(struct ac97_codec_device *adev)
{
struct wm97xx_priv *wm97xx = ac97_get_drvdata(adev);
snd_ac97_compat_release(wm97xx->ac97);
return 0;
}
static const struct ac97_id wm97xx_ac97_ids[] = {
{ .id = WM9705_VENDOR_ID, .mask = WM97xx_VENDOR_ID_MASK },
{ .id = WM9712_VENDOR_ID, .mask = WM97xx_VENDOR_ID_MASK },
{ .id = WM9713_VENDOR_ID, .mask = WM97xx_VENDOR_ID_MASK },
{ }
};
static struct ac97_codec_driver wm97xx_ac97_driver = {
.driver = {
.name = "wm97xx-core",
},
.probe = wm97xx_ac97_probe,
.remove = wm97xx_ac97_remove,
.id_table = wm97xx_ac97_ids,
};
static int __init wm97xx_module_init(void)
{
return snd_ac97_codec_driver_register(&wm97xx_ac97_driver);
}
module_init(wm97xx_module_init);
static void __exit wm97xx_module_exit(void)
{
snd_ac97_codec_driver_unregister(&wm97xx_ac97_driver);
}
module_exit(wm97xx_module_exit);
MODULE_DESCRIPTION("WM9712, WM9713 core driver");
MODULE_AUTHOR("Robert Jarzmik <robert.jarzmik@free.fr>");
MODULE_LICENSE("GPL");

View file

@ -187,6 +187,31 @@ EXPORT_SYMBOL_GPL(usb_unanchor_urb);
/*-------------------------------------------------------------------*/
static const int pipetypes[4] = {
PIPE_CONTROL, PIPE_ISOCHRONOUS, PIPE_BULK, PIPE_INTERRUPT
};
/**
* usb_urb_ep_type_check - sanity check of endpoint in the given urb
* @urb: urb to be checked
*
* This performs a light-weight sanity check for the endpoint in the
* given urb. It returns 0 if the urb contains a valid endpoint, otherwise
* a negative error code.
*/
int usb_urb_ep_type_check(const struct urb *urb)
{
const struct usb_host_endpoint *ep;
ep = usb_pipe_endpoint(urb->dev, urb->pipe);
if (!ep)
return -EINVAL;
if (usb_pipetype(urb->pipe) != pipetypes[usb_endpoint_type(&ep->desc)])
return -EINVAL;
return 0;
}
EXPORT_SYMBOL_GPL(usb_urb_ep_type_check);
/**
* usb_submit_urb - issue an asynchronous transfer request for an endpoint
* @urb: pointer to the urb describing the request
@ -326,9 +351,6 @@ EXPORT_SYMBOL_GPL(usb_unanchor_urb);
*/
int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
{
static int pipetypes[4] = {
PIPE_CONTROL, PIPE_ISOCHRONOUS, PIPE_BULK, PIPE_INTERRUPT
};
int xfertype, max;
struct usb_device *dev;
struct usb_host_endpoint *ep;
@ -444,7 +466,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
*/
/* Check that the pipe's type matches the endpoint's type */
if (usb_pipetype(urb->pipe) != pipetypes[xfertype])
if (usb_urb_ep_type_check(urb))
dev_WARN(&dev->dev, "BOGUS urb xfer, pipe %x != type %x\n",
usb_pipetype(urb->pipe), pipetypes[xfertype]);

View file

@ -0,0 +1,52 @@
/*
* Copyright 2017 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef __AMD_ASIC_TYPE_H__
#define __AMD_ASIC_TYPE_H__
/*
* Supported ASIC types
*/
enum amd_asic_type {
CHIP_TAHITI = 0,
CHIP_PITCAIRN,
CHIP_VERDE,
CHIP_OLAND,
CHIP_HAINAN,
CHIP_BONAIRE,
CHIP_KAVERI,
CHIP_KABINI,
CHIP_HAWAII,
CHIP_MULLINS,
CHIP_TOPAZ,
CHIP_TONGA,
CHIP_FIJI,
CHIP_CARRIZO,
CHIP_STONEY,
CHIP_POLARIS10,
CHIP_POLARIS11,
CHIP_POLARIS12,
CHIP_VEGA10,
CHIP_RAVEN,
CHIP_LAST,
};
#endif /*__AMD_ASIC_TYPE_H__ */

View file

@ -174,6 +174,9 @@ struct arizona_pdata {
/** Mode for outputs */
int out_mono[ARIZONA_MAX_OUTPUT];
/** Limit output volumes */
unsigned int out_vol_limit[2 * ARIZONA_MAX_OUTPUT];
/** PDM speaker mute setting */
unsigned int spk_mute[ARIZONA_MAX_PDM_SPK];

View file

@ -0,0 +1,25 @@
/*
* wm97xx client interface
*
* Copyright (C) 2017 Robert Jarzmik
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#ifndef __LINUX_MFD_WM97XX_H
#define __LINUX_MFD_WM97XX_H
struct regmap;
struct wm97xx_batt_pdata;
struct snd_ac97;
struct wm97xx_platform_data {
struct snd_ac97 *ac97;
struct regmap *regmap;
struct wm97xx_batt_pdata *batt_pdata;
};
#endif

View file

@ -1729,6 +1729,8 @@ static inline int usb_urb_dir_out(struct urb *urb)
return (urb->transfer_flags & URB_DIR_MASK) == URB_DIR_OUT;
}
int usb_urb_ep_type_check(const struct urb *urb);
void *usb_alloc_coherent(struct usb_device *dev, size_t size,
gfp_t mem_flags, dma_addr_t *dma);
void usb_free_coherent(struct usb_device *dev, size_t size,

118
include/sound/ac97/codec.h Normal file
View file

@ -0,0 +1,118 @@
/*
* Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __SOUND_AC97_CODEC2_H
#define __SOUND_AC97_CODEC2_H
#include <linux/device.h>
#define AC97_ID(vendor_id1, vendor_id2) \
((((vendor_id1) & 0xffff) << 16) | ((vendor_id2) & 0xffff))
#define AC97_DRIVER_ID(vendor_id1, vendor_id2, mask_id1, mask_id2, _data) \
{ .id = (((vendor_id1) & 0xffff) << 16) | ((vendor_id2) & 0xffff), \
.mask = (((mask_id1) & 0xffff) << 16) | ((mask_id2) & 0xffff), \
.data = (_data) }
struct ac97_controller;
struct clk;
/**
* struct ac97_id - matches a codec device and driver on an ac97 bus
* @id: The significant bits if the codec vendor ID1 and ID2
* @mask: Bitmask specifying which bits of the id field are significant when
* matching. A driver binds to a device when :
* ((vendorID1 << 8 | vendorID2) & (mask_id1 << 8 | mask_id2)) == id.
* @data: Private data used by the driver.
*/
struct ac97_id {
unsigned int id;
unsigned int mask;
void *data;
};
/**
* ac97_codec_device - a ac97 codec
* @dev: the core device
* @vendor_id: the vendor_id of the codec, as sensed on the AC-link
* @num: the codec number, 0 is primary, 1 is first slave, etc ...
* @clk: the clock BIT_CLK provided by the codec
* @ac97_ctrl: ac97 digital controller on the same AC-link
*
* This is the device instantiated for each codec living on a AC-link. There are
* normally 0 to 4 codec devices per AC-link, and all of them are controlled by
* an AC97 digital controller.
*/
struct ac97_codec_device {
struct device dev;
unsigned int vendor_id;
unsigned int num;
struct clk *clk;
struct ac97_controller *ac97_ctrl;
};
/**
* ac97_codec_driver - a ac97 codec driver
* @driver: the device driver structure
* @probe: the function called when a ac97_codec_device is matched
* @remove: the function called when the device is unbound/removed
* @shutdown: shutdown function (might be NULL)
* @id_table: ac97 vendor_id match table, { } member terminated
*/
struct ac97_codec_driver {
struct device_driver driver;
int (*probe)(struct ac97_codec_device *);
int (*remove)(struct ac97_codec_device *);
void (*shutdown)(struct ac97_codec_device *);
const struct ac97_id *id_table;
};
static inline struct ac97_codec_device *to_ac97_device(struct device *d)
{
return container_of(d, struct ac97_codec_device, dev);
}
static inline struct ac97_codec_driver *to_ac97_driver(struct device_driver *d)
{
return container_of(d, struct ac97_codec_driver, driver);
}
#if IS_ENABLED(CONFIG_AC97_BUS_NEW)
int snd_ac97_codec_driver_register(struct ac97_codec_driver *drv);
void snd_ac97_codec_driver_unregister(struct ac97_codec_driver *drv);
#else
static inline int
snd_ac97_codec_driver_register(struct ac97_codec_driver *drv)
{
return 0;
}
static inline void
snd_ac97_codec_driver_unregister(struct ac97_codec_driver *drv)
{
}
#endif
static inline struct device *
ac97_codec_dev2dev(struct ac97_codec_device *adev)
{
return &adev->dev;
}
static inline void *ac97_get_drvdata(struct ac97_codec_device *adev)
{
return dev_get_drvdata(ac97_codec_dev2dev(adev));
}
static inline void ac97_set_drvdata(struct ac97_codec_device *adev,
void *data)
{
dev_set_drvdata(ac97_codec_dev2dev(adev), data);
}
void *snd_ac97_codec_get_platdata(const struct ac97_codec_device *adev);
#endif

View file

@ -0,0 +1,20 @@
/*
* Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This file is for backward compatibility with snd_ac97 structure and its
* multiple usages, such as the snd_ac97_bus and snd_ac97_build_ops.
*
*/
#ifndef AC97_COMPAT_H
#define AC97_COMPAT_H
#include <sound/ac97_codec.h>
struct snd_ac97 *snd_ac97_compat_alloc(struct ac97_codec_device *adev);
void snd_ac97_compat_release(struct snd_ac97 *ac97);
#endif

View file

@ -0,0 +1,85 @@
/*
* Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef AC97_CONTROLLER_H
#define AC97_CONTROLLER_H
#include <linux/device.h>
#include <linux/list.h>
#define AC97_BUS_MAX_CODECS 4
#define AC97_SLOTS_AVAILABLE_ALL 0xf
struct ac97_controller_ops;
/**
* struct ac97_controller - The AC97 controller of the AC-Link
* @ops: the AC97 operations.
* @controllers: linked list of all existing controllers.
* @adap: the shell device ac97-%d, ie. ac97 adapter
* @nr: the number of the shell device
* @slots_available: the mask of accessible/scanable codecs.
* @parent: the device providing the AC97 controller.
* @codecs: the 4 possible AC97 codecs (NULL if none found).
* @codecs_pdata: platform_data for each codec (NULL if no pdata).
*
* This structure is internal to AC97 bus, and should not be used by the
* controllers themselves, excepting for using @dev.
*/
struct ac97_controller {
const struct ac97_controller_ops *ops;
struct list_head controllers;
struct device adap;
int nr;
unsigned short slots_available;
struct device *parent;
struct ac97_codec_device *codecs[AC97_BUS_MAX_CODECS];
void *codecs_pdata[AC97_BUS_MAX_CODECS];
};
/**
* struct ac97_controller_ops - The AC97 operations
* @reset: Cold reset of the AC97 AC-Link.
* @warm_reset: Warm reset of the AC97 AC-Link.
* @read: Read of a single AC97 register.
* Returns the register value or a negative error code.
* @write: Write of a single AC97 register.
*
* These are the basic operation an AC97 controller must provide for an AC97
* access functions. Amongst these, all but the last 2 are mandatory.
* The slot number is also known as the AC97 codec number, between 0 and 3.
*/
struct ac97_controller_ops {
void (*reset)(struct ac97_controller *adrv);
void (*warm_reset)(struct ac97_controller *adrv);
int (*write)(struct ac97_controller *adrv, int slot,
unsigned short reg, unsigned short val);
int (*read)(struct ac97_controller *adrv, int slot, unsigned short reg);
};
#if IS_ENABLED(CONFIG_AC97_BUS_NEW)
struct ac97_controller *snd_ac97_controller_register(
const struct ac97_controller_ops *ops, struct device *dev,
unsigned short slots_available, void **codecs_pdata);
void snd_ac97_controller_unregister(struct ac97_controller *ac97_ctrl);
#else
static inline struct ac97_controller *
snd_ac97_controller_register(const struct ac97_controller_ops *ops,
struct device *dev,
unsigned short slots_available,
void **codecs_pdata)
{
return ERR_PTR(-ENODEV);
}
static inline void
snd_ac97_controller_unregister(struct ac97_controller *ac97_ctrl)
{
}
#endif
#endif

262
include/sound/ac97/regs.h Normal file
View file

@ -0,0 +1,262 @@
/*
* Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* Universal interface for Audio Codec '97
*
* For more details look to AC '97 component specification revision 2.1
* by Intel Corporation (http://developer.intel.com).
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
/*
* AC'97 codec registers
*/
#define AC97_RESET 0x00 /* Reset */
#define AC97_MASTER 0x02 /* Master Volume */
#define AC97_HEADPHONE 0x04 /* Headphone Volume (optional) */
#define AC97_MASTER_MONO 0x06 /* Master Volume Mono (optional) */
#define AC97_MASTER_TONE 0x08 /* Master Tone (Bass & Treble) (optional) */
#define AC97_PC_BEEP 0x0a /* PC Beep Volume (optinal) */
#define AC97_PHONE 0x0c /* Phone Volume (optional) */
#define AC97_MIC 0x0e /* MIC Volume */
#define AC97_LINE 0x10 /* Line In Volume */
#define AC97_CD 0x12 /* CD Volume */
#define AC97_VIDEO 0x14 /* Video Volume (optional) */
#define AC97_AUX 0x16 /* AUX Volume (optional) */
#define AC97_PCM 0x18 /* PCM Volume */
#define AC97_REC_SEL 0x1a /* Record Select */
#define AC97_REC_GAIN 0x1c /* Record Gain */
#define AC97_REC_GAIN_MIC 0x1e /* Record Gain MIC (optional) */
#define AC97_GENERAL_PURPOSE 0x20 /* General Purpose (optional) */
#define AC97_3D_CONTROL 0x22 /* 3D Control (optional) */
#define AC97_INT_PAGING 0x24 /* Audio Interrupt & Paging (AC'97 2.3) */
#define AC97_POWERDOWN 0x26 /* Powerdown control / status */
/* range 0x28-0x3a - AUDIO AC'97 2.0 extensions */
#define AC97_EXTENDED_ID 0x28 /* Extended Audio ID */
#define AC97_EXTENDED_STATUS 0x2a /* Extended Audio Status and Control */
#define AC97_PCM_FRONT_DAC_RATE 0x2c /* PCM Front DAC Rate */
#define AC97_PCM_SURR_DAC_RATE 0x2e /* PCM Surround DAC Rate */
#define AC97_PCM_LFE_DAC_RATE 0x30 /* PCM LFE DAC Rate */
#define AC97_PCM_LR_ADC_RATE 0x32 /* PCM LR ADC Rate */
#define AC97_PCM_MIC_ADC_RATE 0x34 /* PCM MIC ADC Rate */
#define AC97_CENTER_LFE_MASTER 0x36 /* Center + LFE Master Volume */
#define AC97_SURROUND_MASTER 0x38 /* Surround (Rear) Master Volume */
#define AC97_SPDIF 0x3a /* S/PDIF control */
/* range 0x3c-0x58 - MODEM */
#define AC97_EXTENDED_MID 0x3c /* Extended Modem ID */
#define AC97_EXTENDED_MSTATUS 0x3e /* Extended Modem Status and Control */
#define AC97_LINE1_RATE 0x40 /* Line1 DAC/ADC Rate */
#define AC97_LINE2_RATE 0x42 /* Line2 DAC/ADC Rate */
#define AC97_HANDSET_RATE 0x44 /* Handset DAC/ADC Rate */
#define AC97_LINE1_LEVEL 0x46 /* Line1 DAC/ADC Level */
#define AC97_LINE2_LEVEL 0x48 /* Line2 DAC/ADC Level */
#define AC97_HANDSET_LEVEL 0x4a /* Handset DAC/ADC Level */
#define AC97_GPIO_CFG 0x4c /* GPIO Configuration */
#define AC97_GPIO_POLARITY 0x4e /* GPIO Pin Polarity/Type, 0=low, 1=high active */
#define AC97_GPIO_STICKY 0x50 /* GPIO Pin Sticky, 0=not, 1=sticky */
#define AC97_GPIO_WAKEUP 0x52 /* GPIO Pin Wakeup, 0=no int, 1=yes int */
#define AC97_GPIO_STATUS 0x54 /* GPIO Pin Status, slot 12 */
#define AC97_MISC_AFE 0x56 /* Miscellaneous Modem AFE Status and Control */
/* range 0x5a-0x7b - Vendor Specific */
#define AC97_VENDOR_ID1 0x7c /* Vendor ID1 */
#define AC97_VENDOR_ID2 0x7e /* Vendor ID2 / revision */
/* range 0x60-0x6f (page 1) - extended codec registers */
#define AC97_CODEC_CLASS_REV 0x60 /* Codec Class/Revision */
#define AC97_PCI_SVID 0x62 /* PCI Subsystem Vendor ID */
#define AC97_PCI_SID 0x64 /* PCI Subsystem ID */
#define AC97_FUNC_SELECT 0x66 /* Function Select */
#define AC97_FUNC_INFO 0x68 /* Function Information */
#define AC97_SENSE_INFO 0x6a /* Sense Details */
/* volume controls */
#define AC97_MUTE_MASK_MONO 0x8000
#define AC97_MUTE_MASK_STEREO 0x8080
/* slot allocation */
#define AC97_SLOT_TAG 0
#define AC97_SLOT_CMD_ADDR 1
#define AC97_SLOT_CMD_DATA 2
#define AC97_SLOT_PCM_LEFT 3
#define AC97_SLOT_PCM_RIGHT 4
#define AC97_SLOT_MODEM_LINE1 5
#define AC97_SLOT_PCM_CENTER 6
#define AC97_SLOT_MIC 6 /* input */
#define AC97_SLOT_SPDIF_LEFT1 6
#define AC97_SLOT_PCM_SLEFT 7 /* surround left */
#define AC97_SLOT_PCM_LEFT_0 7 /* double rate operation */
#define AC97_SLOT_SPDIF_LEFT 7
#define AC97_SLOT_PCM_SRIGHT 8 /* surround right */
#define AC97_SLOT_PCM_RIGHT_0 8 /* double rate operation */
#define AC97_SLOT_SPDIF_RIGHT 8
#define AC97_SLOT_LFE 9
#define AC97_SLOT_SPDIF_RIGHT1 9
#define AC97_SLOT_MODEM_LINE2 10
#define AC97_SLOT_PCM_LEFT_1 10 /* double rate operation */
#define AC97_SLOT_SPDIF_LEFT2 10
#define AC97_SLOT_HANDSET 11 /* output */
#define AC97_SLOT_PCM_RIGHT_1 11 /* double rate operation */
#define AC97_SLOT_SPDIF_RIGHT2 11
#define AC97_SLOT_MODEM_GPIO 12 /* modem GPIO */
#define AC97_SLOT_PCM_CENTER_1 12 /* double rate operation */
/* basic capabilities (reset register) */
#define AC97_BC_DEDICATED_MIC 0x0001 /* Dedicated Mic PCM In Channel */
#define AC97_BC_RESERVED1 0x0002 /* Reserved (was Modem Line Codec support) */
#define AC97_BC_BASS_TREBLE 0x0004 /* Bass & Treble Control */
#define AC97_BC_SIM_STEREO 0x0008 /* Simulated stereo */
#define AC97_BC_HEADPHONE 0x0010 /* Headphone Out Support */
#define AC97_BC_LOUDNESS 0x0020 /* Loudness (bass boost) Support */
#define AC97_BC_16BIT_DAC 0x0000 /* 16-bit DAC resolution */
#define AC97_BC_18BIT_DAC 0x0040 /* 18-bit DAC resolution */
#define AC97_BC_20BIT_DAC 0x0080 /* 20-bit DAC resolution */
#define AC97_BC_DAC_MASK 0x00c0
#define AC97_BC_16BIT_ADC 0x0000 /* 16-bit ADC resolution */
#define AC97_BC_18BIT_ADC 0x0100 /* 18-bit ADC resolution */
#define AC97_BC_20BIT_ADC 0x0200 /* 20-bit ADC resolution */
#define AC97_BC_ADC_MASK 0x0300
#define AC97_BC_3D_TECH_ID_MASK 0x7c00 /* Per-vendor ID of 3D enhancement */
/* general purpose */
#define AC97_GP_DRSS_MASK 0x0c00 /* double rate slot select */
#define AC97_GP_DRSS_1011 0x0000 /* LR(C) 10+11(+12) */
#define AC97_GP_DRSS_78 0x0400 /* LR 7+8 */
/* powerdown bits */
#define AC97_PD_ADC_STATUS 0x0001 /* ADC status (RO) */
#define AC97_PD_DAC_STATUS 0x0002 /* DAC status (RO) */
#define AC97_PD_MIXER_STATUS 0x0004 /* Analog mixer status (RO) */
#define AC97_PD_VREF_STATUS 0x0008 /* Vref status (RO) */
#define AC97_PD_PR0 0x0100 /* Power down PCM ADCs and input MUX */
#define AC97_PD_PR1 0x0200 /* Power down PCM front DAC */
#define AC97_PD_PR2 0x0400 /* Power down Mixer (Vref still on) */
#define AC97_PD_PR3 0x0800 /* Power down Mixer (Vref off) */
#define AC97_PD_PR4 0x1000 /* Power down AC-Link */
#define AC97_PD_PR5 0x2000 /* Disable internal clock usage */
#define AC97_PD_PR6 0x4000 /* Headphone amplifier */
#define AC97_PD_EAPD 0x8000 /* External Amplifer Power Down (EAPD) */
/* extended audio ID bit defines */
#define AC97_EI_VRA 0x0001 /* Variable bit rate supported */
#define AC97_EI_DRA 0x0002 /* Double rate supported */
#define AC97_EI_SPDIF 0x0004 /* S/PDIF out supported */
#define AC97_EI_VRM 0x0008 /* Variable bit rate supported for MIC */
#define AC97_EI_DACS_SLOT_MASK 0x0030 /* DACs slot assignment */
#define AC97_EI_DACS_SLOT_SHIFT 4
#define AC97_EI_CDAC 0x0040 /* PCM Center DAC available */
#define AC97_EI_SDAC 0x0080 /* PCM Surround DACs available */
#define AC97_EI_LDAC 0x0100 /* PCM LFE DAC available */
#define AC97_EI_AMAP 0x0200 /* indicates optional slot/DAC mapping based on codec ID */
#define AC97_EI_REV_MASK 0x0c00 /* AC'97 revision mask */
#define AC97_EI_REV_22 0x0400 /* AC'97 revision 2.2 */
#define AC97_EI_REV_23 0x0800 /* AC'97 revision 2.3 */
#define AC97_EI_REV_SHIFT 10
#define AC97_EI_ADDR_MASK 0xc000 /* physical codec ID (address) */
#define AC97_EI_ADDR_SHIFT 14
/* extended audio status and control bit defines */
#define AC97_EA_VRA 0x0001 /* Variable bit rate enable bit */
#define AC97_EA_DRA 0x0002 /* Double-rate audio enable bit */
#define AC97_EA_SPDIF 0x0004 /* S/PDIF out enable bit */
#define AC97_EA_VRM 0x0008 /* Variable bit rate for MIC enable bit */
#define AC97_EA_SPSA_SLOT_MASK 0x0030 /* Mask for slot assignment bits */
#define AC97_EA_SPSA_SLOT_SHIFT 4
#define AC97_EA_SPSA_3_4 0x0000 /* Slot assigned to 3 & 4 */
#define AC97_EA_SPSA_7_8 0x0010 /* Slot assigned to 7 & 8 */
#define AC97_EA_SPSA_6_9 0x0020 /* Slot assigned to 6 & 9 */
#define AC97_EA_SPSA_10_11 0x0030 /* Slot assigned to 10 & 11 */
#define AC97_EA_CDAC 0x0040 /* PCM Center DAC is ready (Read only) */
#define AC97_EA_SDAC 0x0080 /* PCM Surround DACs are ready (Read only) */
#define AC97_EA_LDAC 0x0100 /* PCM LFE DAC is ready (Read only) */
#define AC97_EA_MDAC 0x0200 /* MIC ADC is ready (Read only) */
#define AC97_EA_SPCV 0x0400 /* S/PDIF configuration valid (Read only) */
#define AC97_EA_PRI 0x0800 /* Turns the PCM Center DAC off */
#define AC97_EA_PRJ 0x1000 /* Turns the PCM Surround DACs off */
#define AC97_EA_PRK 0x2000 /* Turns the PCM LFE DAC off */
#define AC97_EA_PRL 0x4000 /* Turns the MIC ADC off */
/* S/PDIF control bit defines */
#define AC97_SC_PRO 0x0001 /* Professional status */
#define AC97_SC_NAUDIO 0x0002 /* Non audio stream */
#define AC97_SC_COPY 0x0004 /* Copyright status */
#define AC97_SC_PRE 0x0008 /* Preemphasis status */
#define AC97_SC_CC_MASK 0x07f0 /* Category Code mask */
#define AC97_SC_CC_SHIFT 4
#define AC97_SC_L 0x0800 /* Generation Level status */
#define AC97_SC_SPSR_MASK 0x3000 /* S/PDIF Sample Rate bits */
#define AC97_SC_SPSR_SHIFT 12
#define AC97_SC_SPSR_44K 0x0000 /* Use 44.1kHz Sample rate */
#define AC97_SC_SPSR_48K 0x2000 /* Use 48kHz Sample rate */
#define AC97_SC_SPSR_32K 0x3000 /* Use 32kHz Sample rate */
#define AC97_SC_DRS 0x4000 /* Double Rate S/PDIF */
#define AC97_SC_V 0x8000 /* Validity status */
/* Interrupt and Paging bit defines (AC'97 2.3) */
#define AC97_PAGE_MASK 0x000f /* Page Selector */
#define AC97_PAGE_VENDOR 0 /* Vendor-specific registers */
#define AC97_PAGE_1 1 /* Extended Codec Registers page 1 */
#define AC97_INT_ENABLE 0x0800 /* Interrupt Enable */
#define AC97_INT_SENSE 0x1000 /* Sense Cycle */
#define AC97_INT_CAUSE_SENSE 0x2000 /* Sense Cycle Completed (RO) */
#define AC97_INT_CAUSE_GPIO 0x4000 /* GPIO bits changed (RO) */
#define AC97_INT_STATUS 0x8000 /* Interrupt Status */
/* extended modem ID bit defines */
#define AC97_MEI_LINE1 0x0001 /* Line1 present */
#define AC97_MEI_LINE2 0x0002 /* Line2 present */
#define AC97_MEI_HANDSET 0x0004 /* Handset present */
#define AC97_MEI_CID1 0x0008 /* caller ID decode for Line1 is supported */
#define AC97_MEI_CID2 0x0010 /* caller ID decode for Line2 is supported */
#define AC97_MEI_ADDR_MASK 0xc000 /* physical codec ID (address) */
#define AC97_MEI_ADDR_SHIFT 14
/* extended modem status and control bit defines */
#define AC97_MEA_GPIO 0x0001 /* GPIO is ready (ro) */
#define AC97_MEA_MREF 0x0002 /* Vref is up to nominal level (ro) */
#define AC97_MEA_ADC1 0x0004 /* ADC1 operational (ro) */
#define AC97_MEA_DAC1 0x0008 /* DAC1 operational (ro) */
#define AC97_MEA_ADC2 0x0010 /* ADC2 operational (ro) */
#define AC97_MEA_DAC2 0x0020 /* DAC2 operational (ro) */
#define AC97_MEA_HADC 0x0040 /* HADC operational (ro) */
#define AC97_MEA_HDAC 0x0080 /* HDAC operational (ro) */
#define AC97_MEA_PRA 0x0100 /* GPIO power down (high) */
#define AC97_MEA_PRB 0x0200 /* reserved */
#define AC97_MEA_PRC 0x0400 /* ADC1 power down (high) */
#define AC97_MEA_PRD 0x0800 /* DAC1 power down (high) */
#define AC97_MEA_PRE 0x1000 /* ADC2 power down (high) */
#define AC97_MEA_PRF 0x2000 /* DAC2 power down (high) */
#define AC97_MEA_PRG 0x4000 /* HADC power down (high) */
#define AC97_MEA_PRH 0x8000 /* HDAC power down (high) */
/* modem gpio status defines */
#define AC97_GPIO_LINE1_OH 0x0001 /* Off Hook Line1 */
#define AC97_GPIO_LINE1_RI 0x0002 /* Ring Detect Line1 */
#define AC97_GPIO_LINE1_CID 0x0004 /* Caller ID path enable Line1 */
#define AC97_GPIO_LINE1_LCS 0x0008 /* Loop Current Sense Line1 */
#define AC97_GPIO_LINE1_PULSE 0x0010 /* Opt./ Pulse Dial Line1 (out) */
#define AC97_GPIO_LINE1_HL1R 0x0020 /* Opt./ Handset to Line1 relay control (out) */
#define AC97_GPIO_LINE1_HOHD 0x0040 /* Opt./ Handset off hook detect Line1 (in) */
#define AC97_GPIO_LINE12_AC 0x0080 /* Opt./ Int.bit 1 / Line1/2 AC (out) */
#define AC97_GPIO_LINE12_DC 0x0100 /* Opt./ Int.bit 2 / Line1/2 DC (out) */
#define AC97_GPIO_LINE12_RS 0x0200 /* Opt./ Int.bit 3 / Line1/2 RS (out) */
#define AC97_GPIO_LINE2_OH 0x0400 /* Off Hook Line2 */
#define AC97_GPIO_LINE2_RI 0x0800 /* Ring Detect Line2 */
#define AC97_GPIO_LINE2_CID 0x1000 /* Caller ID path enable Line2 */
#define AC97_GPIO_LINE2_LCS 0x2000 /* Loop Current Sense Line2 */
#define AC97_GPIO_LINE2_PULSE 0x4000 /* Opt./ Pulse Dial Line2 (out) */
#define AC97_GPIO_LINE2_HL1R 0x8000 /* Opt./ Handset to Line2 relay control (out) */

View file

@ -28,6 +28,7 @@
#include <linux/bitops.h>
#include <linux/device.h>
#include <linux/workqueue.h>
#include <sound/ac97/regs.h>
#include <sound/pcm.h>
#include <sound/control.h>
#include <sound/info.h>
@ -35,244 +36,6 @@
/* maximum number of devices on the AC97 bus */
#define AC97_BUS_MAX_DEVICES 4
/*
* AC'97 codec registers
*/
#define AC97_RESET 0x00 /* Reset */
#define AC97_MASTER 0x02 /* Master Volume */
#define AC97_HEADPHONE 0x04 /* Headphone Volume (optional) */
#define AC97_MASTER_MONO 0x06 /* Master Volume Mono (optional) */
#define AC97_MASTER_TONE 0x08 /* Master Tone (Bass & Treble) (optional) */
#define AC97_PC_BEEP 0x0a /* PC Beep Volume (optinal) */
#define AC97_PHONE 0x0c /* Phone Volume (optional) */
#define AC97_MIC 0x0e /* MIC Volume */
#define AC97_LINE 0x10 /* Line In Volume */
#define AC97_CD 0x12 /* CD Volume */
#define AC97_VIDEO 0x14 /* Video Volume (optional) */
#define AC97_AUX 0x16 /* AUX Volume (optional) */
#define AC97_PCM 0x18 /* PCM Volume */
#define AC97_REC_SEL 0x1a /* Record Select */
#define AC97_REC_GAIN 0x1c /* Record Gain */
#define AC97_REC_GAIN_MIC 0x1e /* Record Gain MIC (optional) */
#define AC97_GENERAL_PURPOSE 0x20 /* General Purpose (optional) */
#define AC97_3D_CONTROL 0x22 /* 3D Control (optional) */
#define AC97_INT_PAGING 0x24 /* Audio Interrupt & Paging (AC'97 2.3) */
#define AC97_POWERDOWN 0x26 /* Powerdown control / status */
/* range 0x28-0x3a - AUDIO AC'97 2.0 extensions */
#define AC97_EXTENDED_ID 0x28 /* Extended Audio ID */
#define AC97_EXTENDED_STATUS 0x2a /* Extended Audio Status and Control */
#define AC97_PCM_FRONT_DAC_RATE 0x2c /* PCM Front DAC Rate */
#define AC97_PCM_SURR_DAC_RATE 0x2e /* PCM Surround DAC Rate */
#define AC97_PCM_LFE_DAC_RATE 0x30 /* PCM LFE DAC Rate */
#define AC97_PCM_LR_ADC_RATE 0x32 /* PCM LR ADC Rate */
#define AC97_PCM_MIC_ADC_RATE 0x34 /* PCM MIC ADC Rate */
#define AC97_CENTER_LFE_MASTER 0x36 /* Center + LFE Master Volume */
#define AC97_SURROUND_MASTER 0x38 /* Surround (Rear) Master Volume */
#define AC97_SPDIF 0x3a /* S/PDIF control */
/* range 0x3c-0x58 - MODEM */
#define AC97_EXTENDED_MID 0x3c /* Extended Modem ID */
#define AC97_EXTENDED_MSTATUS 0x3e /* Extended Modem Status and Control */
#define AC97_LINE1_RATE 0x40 /* Line1 DAC/ADC Rate */
#define AC97_LINE2_RATE 0x42 /* Line2 DAC/ADC Rate */
#define AC97_HANDSET_RATE 0x44 /* Handset DAC/ADC Rate */
#define AC97_LINE1_LEVEL 0x46 /* Line1 DAC/ADC Level */
#define AC97_LINE2_LEVEL 0x48 /* Line2 DAC/ADC Level */
#define AC97_HANDSET_LEVEL 0x4a /* Handset DAC/ADC Level */
#define AC97_GPIO_CFG 0x4c /* GPIO Configuration */
#define AC97_GPIO_POLARITY 0x4e /* GPIO Pin Polarity/Type, 0=low, 1=high active */
#define AC97_GPIO_STICKY 0x50 /* GPIO Pin Sticky, 0=not, 1=sticky */
#define AC97_GPIO_WAKEUP 0x52 /* GPIO Pin Wakeup, 0=no int, 1=yes int */
#define AC97_GPIO_STATUS 0x54 /* GPIO Pin Status, slot 12 */
#define AC97_MISC_AFE 0x56 /* Miscellaneous Modem AFE Status and Control */
/* range 0x5a-0x7b - Vendor Specific */
#define AC97_VENDOR_ID1 0x7c /* Vendor ID1 */
#define AC97_VENDOR_ID2 0x7e /* Vendor ID2 / revision */
/* range 0x60-0x6f (page 1) - extended codec registers */
#define AC97_CODEC_CLASS_REV 0x60 /* Codec Class/Revision */
#define AC97_PCI_SVID 0x62 /* PCI Subsystem Vendor ID */
#define AC97_PCI_SID 0x64 /* PCI Subsystem ID */
#define AC97_FUNC_SELECT 0x66 /* Function Select */
#define AC97_FUNC_INFO 0x68 /* Function Information */
#define AC97_SENSE_INFO 0x6a /* Sense Details */
/* volume controls */
#define AC97_MUTE_MASK_MONO 0x8000
#define AC97_MUTE_MASK_STEREO 0x8080
/* slot allocation */
#define AC97_SLOT_TAG 0
#define AC97_SLOT_CMD_ADDR 1
#define AC97_SLOT_CMD_DATA 2
#define AC97_SLOT_PCM_LEFT 3
#define AC97_SLOT_PCM_RIGHT 4
#define AC97_SLOT_MODEM_LINE1 5
#define AC97_SLOT_PCM_CENTER 6
#define AC97_SLOT_MIC 6 /* input */
#define AC97_SLOT_SPDIF_LEFT1 6
#define AC97_SLOT_PCM_SLEFT 7 /* surround left */
#define AC97_SLOT_PCM_LEFT_0 7 /* double rate operation */
#define AC97_SLOT_SPDIF_LEFT 7
#define AC97_SLOT_PCM_SRIGHT 8 /* surround right */
#define AC97_SLOT_PCM_RIGHT_0 8 /* double rate operation */
#define AC97_SLOT_SPDIF_RIGHT 8
#define AC97_SLOT_LFE 9
#define AC97_SLOT_SPDIF_RIGHT1 9
#define AC97_SLOT_MODEM_LINE2 10
#define AC97_SLOT_PCM_LEFT_1 10 /* double rate operation */
#define AC97_SLOT_SPDIF_LEFT2 10
#define AC97_SLOT_HANDSET 11 /* output */
#define AC97_SLOT_PCM_RIGHT_1 11 /* double rate operation */
#define AC97_SLOT_SPDIF_RIGHT2 11
#define AC97_SLOT_MODEM_GPIO 12 /* modem GPIO */
#define AC97_SLOT_PCM_CENTER_1 12 /* double rate operation */
/* basic capabilities (reset register) */
#define AC97_BC_DEDICATED_MIC 0x0001 /* Dedicated Mic PCM In Channel */
#define AC97_BC_RESERVED1 0x0002 /* Reserved (was Modem Line Codec support) */
#define AC97_BC_BASS_TREBLE 0x0004 /* Bass & Treble Control */
#define AC97_BC_SIM_STEREO 0x0008 /* Simulated stereo */
#define AC97_BC_HEADPHONE 0x0010 /* Headphone Out Support */
#define AC97_BC_LOUDNESS 0x0020 /* Loudness (bass boost) Support */
#define AC97_BC_16BIT_DAC 0x0000 /* 16-bit DAC resolution */
#define AC97_BC_18BIT_DAC 0x0040 /* 18-bit DAC resolution */
#define AC97_BC_20BIT_DAC 0x0080 /* 20-bit DAC resolution */
#define AC97_BC_DAC_MASK 0x00c0
#define AC97_BC_16BIT_ADC 0x0000 /* 16-bit ADC resolution */
#define AC97_BC_18BIT_ADC 0x0100 /* 18-bit ADC resolution */
#define AC97_BC_20BIT_ADC 0x0200 /* 20-bit ADC resolution */
#define AC97_BC_ADC_MASK 0x0300
#define AC97_BC_3D_TECH_ID_MASK 0x7c00 /* Per-vendor ID of 3D enhancement */
/* general purpose */
#define AC97_GP_DRSS_MASK 0x0c00 /* double rate slot select */
#define AC97_GP_DRSS_1011 0x0000 /* LR(C) 10+11(+12) */
#define AC97_GP_DRSS_78 0x0400 /* LR 7+8 */
/* powerdown bits */
#define AC97_PD_ADC_STATUS 0x0001 /* ADC status (RO) */
#define AC97_PD_DAC_STATUS 0x0002 /* DAC status (RO) */
#define AC97_PD_MIXER_STATUS 0x0004 /* Analog mixer status (RO) */
#define AC97_PD_VREF_STATUS 0x0008 /* Vref status (RO) */
#define AC97_PD_PR0 0x0100 /* Power down PCM ADCs and input MUX */
#define AC97_PD_PR1 0x0200 /* Power down PCM front DAC */
#define AC97_PD_PR2 0x0400 /* Power down Mixer (Vref still on) */
#define AC97_PD_PR3 0x0800 /* Power down Mixer (Vref off) */
#define AC97_PD_PR4 0x1000 /* Power down AC-Link */
#define AC97_PD_PR5 0x2000 /* Disable internal clock usage */
#define AC97_PD_PR6 0x4000 /* Headphone amplifier */
#define AC97_PD_EAPD 0x8000 /* External Amplifer Power Down (EAPD) */
/* extended audio ID bit defines */
#define AC97_EI_VRA 0x0001 /* Variable bit rate supported */
#define AC97_EI_DRA 0x0002 /* Double rate supported */
#define AC97_EI_SPDIF 0x0004 /* S/PDIF out supported */
#define AC97_EI_VRM 0x0008 /* Variable bit rate supported for MIC */
#define AC97_EI_DACS_SLOT_MASK 0x0030 /* DACs slot assignment */
#define AC97_EI_DACS_SLOT_SHIFT 4
#define AC97_EI_CDAC 0x0040 /* PCM Center DAC available */
#define AC97_EI_SDAC 0x0080 /* PCM Surround DACs available */
#define AC97_EI_LDAC 0x0100 /* PCM LFE DAC available */
#define AC97_EI_AMAP 0x0200 /* indicates optional slot/DAC mapping based on codec ID */
#define AC97_EI_REV_MASK 0x0c00 /* AC'97 revision mask */
#define AC97_EI_REV_22 0x0400 /* AC'97 revision 2.2 */
#define AC97_EI_REV_23 0x0800 /* AC'97 revision 2.3 */
#define AC97_EI_REV_SHIFT 10
#define AC97_EI_ADDR_MASK 0xc000 /* physical codec ID (address) */
#define AC97_EI_ADDR_SHIFT 14
/* extended audio status and control bit defines */
#define AC97_EA_VRA 0x0001 /* Variable bit rate enable bit */
#define AC97_EA_DRA 0x0002 /* Double-rate audio enable bit */
#define AC97_EA_SPDIF 0x0004 /* S/PDIF out enable bit */
#define AC97_EA_VRM 0x0008 /* Variable bit rate for MIC enable bit */
#define AC97_EA_SPSA_SLOT_MASK 0x0030 /* Mask for slot assignment bits */
#define AC97_EA_SPSA_SLOT_SHIFT 4
#define AC97_EA_SPSA_3_4 0x0000 /* Slot assigned to 3 & 4 */
#define AC97_EA_SPSA_7_8 0x0010 /* Slot assigned to 7 & 8 */
#define AC97_EA_SPSA_6_9 0x0020 /* Slot assigned to 6 & 9 */
#define AC97_EA_SPSA_10_11 0x0030 /* Slot assigned to 10 & 11 */
#define AC97_EA_CDAC 0x0040 /* PCM Center DAC is ready (Read only) */
#define AC97_EA_SDAC 0x0080 /* PCM Surround DACs are ready (Read only) */
#define AC97_EA_LDAC 0x0100 /* PCM LFE DAC is ready (Read only) */
#define AC97_EA_MDAC 0x0200 /* MIC ADC is ready (Read only) */
#define AC97_EA_SPCV 0x0400 /* S/PDIF configuration valid (Read only) */
#define AC97_EA_PRI 0x0800 /* Turns the PCM Center DAC off */
#define AC97_EA_PRJ 0x1000 /* Turns the PCM Surround DACs off */
#define AC97_EA_PRK 0x2000 /* Turns the PCM LFE DAC off */
#define AC97_EA_PRL 0x4000 /* Turns the MIC ADC off */
/* S/PDIF control bit defines */
#define AC97_SC_PRO 0x0001 /* Professional status */
#define AC97_SC_NAUDIO 0x0002 /* Non audio stream */
#define AC97_SC_COPY 0x0004 /* Copyright status */
#define AC97_SC_PRE 0x0008 /* Preemphasis status */
#define AC97_SC_CC_MASK 0x07f0 /* Category Code mask */
#define AC97_SC_CC_SHIFT 4
#define AC97_SC_L 0x0800 /* Generation Level status */
#define AC97_SC_SPSR_MASK 0x3000 /* S/PDIF Sample Rate bits */
#define AC97_SC_SPSR_SHIFT 12
#define AC97_SC_SPSR_44K 0x0000 /* Use 44.1kHz Sample rate */
#define AC97_SC_SPSR_48K 0x2000 /* Use 48kHz Sample rate */
#define AC97_SC_SPSR_32K 0x3000 /* Use 32kHz Sample rate */
#define AC97_SC_DRS 0x4000 /* Double Rate S/PDIF */
#define AC97_SC_V 0x8000 /* Validity status */
/* Interrupt and Paging bit defines (AC'97 2.3) */
#define AC97_PAGE_MASK 0x000f /* Page Selector */
#define AC97_PAGE_VENDOR 0 /* Vendor-specific registers */
#define AC97_PAGE_1 1 /* Extended Codec Registers page 1 */
#define AC97_INT_ENABLE 0x0800 /* Interrupt Enable */
#define AC97_INT_SENSE 0x1000 /* Sense Cycle */
#define AC97_INT_CAUSE_SENSE 0x2000 /* Sense Cycle Completed (RO) */
#define AC97_INT_CAUSE_GPIO 0x4000 /* GPIO bits changed (RO) */
#define AC97_INT_STATUS 0x8000 /* Interrupt Status */
/* extended modem ID bit defines */
#define AC97_MEI_LINE1 0x0001 /* Line1 present */
#define AC97_MEI_LINE2 0x0002 /* Line2 present */
#define AC97_MEI_HANDSET 0x0004 /* Handset present */
#define AC97_MEI_CID1 0x0008 /* caller ID decode for Line1 is supported */
#define AC97_MEI_CID2 0x0010 /* caller ID decode for Line2 is supported */
#define AC97_MEI_ADDR_MASK 0xc000 /* physical codec ID (address) */
#define AC97_MEI_ADDR_SHIFT 14
/* extended modem status and control bit defines */
#define AC97_MEA_GPIO 0x0001 /* GPIO is ready (ro) */
#define AC97_MEA_MREF 0x0002 /* Vref is up to nominal level (ro) */
#define AC97_MEA_ADC1 0x0004 /* ADC1 operational (ro) */
#define AC97_MEA_DAC1 0x0008 /* DAC1 operational (ro) */
#define AC97_MEA_ADC2 0x0010 /* ADC2 operational (ro) */
#define AC97_MEA_DAC2 0x0020 /* DAC2 operational (ro) */
#define AC97_MEA_HADC 0x0040 /* HADC operational (ro) */
#define AC97_MEA_HDAC 0x0080 /* HDAC operational (ro) */
#define AC97_MEA_PRA 0x0100 /* GPIO power down (high) */
#define AC97_MEA_PRB 0x0200 /* reserved */
#define AC97_MEA_PRC 0x0400 /* ADC1 power down (high) */
#define AC97_MEA_PRD 0x0800 /* DAC1 power down (high) */
#define AC97_MEA_PRE 0x1000 /* ADC2 power down (high) */
#define AC97_MEA_PRF 0x2000 /* DAC2 power down (high) */
#define AC97_MEA_PRG 0x4000 /* HADC power down (high) */
#define AC97_MEA_PRH 0x8000 /* HDAC power down (high) */
/* modem gpio status defines */
#define AC97_GPIO_LINE1_OH 0x0001 /* Off Hook Line1 */
#define AC97_GPIO_LINE1_RI 0x0002 /* Ring Detect Line1 */
#define AC97_GPIO_LINE1_CID 0x0004 /* Caller ID path enable Line1 */
#define AC97_GPIO_LINE1_LCS 0x0008 /* Loop Current Sense Line1 */
#define AC97_GPIO_LINE1_PULSE 0x0010 /* Opt./ Pulse Dial Line1 (out) */
#define AC97_GPIO_LINE1_HL1R 0x0020 /* Opt./ Handset to Line1 relay control (out) */
#define AC97_GPIO_LINE1_HOHD 0x0040 /* Opt./ Handset off hook detect Line1 (in) */
#define AC97_GPIO_LINE12_AC 0x0080 /* Opt./ Int.bit 1 / Line1/2 AC (out) */
#define AC97_GPIO_LINE12_DC 0x0100 /* Opt./ Int.bit 2 / Line1/2 DC (out) */
#define AC97_GPIO_LINE12_RS 0x0200 /* Opt./ Int.bit 3 / Line1/2 RS (out) */
#define AC97_GPIO_LINE2_OH 0x0400 /* Off Hook Line2 */
#define AC97_GPIO_LINE2_RI 0x0800 /* Ring Detect Line2 */
#define AC97_GPIO_LINE2_CID 0x1000 /* Caller ID path enable Line2 */
#define AC97_GPIO_LINE2_LCS 0x2000 /* Loop Current Sense Line2 */
#define AC97_GPIO_LINE2_PULSE 0x4000 /* Opt./ Pulse Dial Line2 (out) */
#define AC97_GPIO_LINE2_HL1R 0x8000 /* Opt./ Handset to Line2 relay control (out) */
/* specific - SigmaTel */
#define AC97_SIGMATEL_OUTSEL 0x64 /* Output Select, STAC9758 */
#define AC97_SIGMATEL_INSEL 0x66 /* Input Select, STAC9758 */

View file

@ -133,6 +133,7 @@ struct snd_card {
struct device card_dev; /* cardX object for sysfs */
const struct attribute_group *dev_groups[4]; /* assigned sysfs attr */
bool registered; /* card_dev is registered? */
wait_queue_head_t remove_sleep;
#ifdef CONFIG_PM
unsigned int power_state; /* power state */
@ -240,6 +241,7 @@ int snd_card_new(struct device *parent, int idx, const char *xid,
struct snd_card **card_ret);
int snd_card_disconnect(struct snd_card *card);
void snd_card_disconnect_sync(struct snd_card *card);
int snd_card_free(struct snd_card *card);
int snd_card_free_when_closed(struct snd_card *card);
void snd_card_set_id(struct snd_card *card, const char *id);

View file

@ -112,8 +112,7 @@ void snd_hdac_device_unregister(struct hdac_device *codec);
int snd_hdac_device_set_chip_name(struct hdac_device *codec, const char *name);
int snd_hdac_codec_modalias(struct hdac_device *hdac, char *buf, size_t size);
int snd_hdac_refresh_widgets(struct hdac_device *codec);
int snd_hdac_refresh_widget_sysfs(struct hdac_device *codec);
int snd_hdac_refresh_widgets(struct hdac_device *codec, bool sysfs);
unsigned int snd_hdac_make_cmd(struct hdac_device *codec, hda_nid_t nid,
unsigned int verb, unsigned int parm);

View file

@ -2,10 +2,13 @@
#ifndef PXA2XX_LIB_H
#define PXA2XX_LIB_H
#include <uapi/sound/asound.h>
#include <linux/platform_device.h>
#include <sound/ac97_codec.h>
/* PCM */
struct snd_pcm_substream;
struct snd_pcm_hw_params;
struct snd_pcm;
extern int __pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params);
@ -22,12 +25,12 @@ extern void pxa2xx_pcm_free_dma_buffers(struct snd_pcm *pcm);
/* AC97 */
extern unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97, unsigned short reg);
extern void pxa2xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val);
extern int pxa2xx_ac97_read(int slot, unsigned short reg);
extern int pxa2xx_ac97_write(int slot, unsigned short reg, unsigned short val);
extern bool pxa2xx_ac97_try_warm_reset(struct snd_ac97 *ac97);
extern bool pxa2xx_ac97_try_cold_reset(struct snd_ac97 *ac97);
extern void pxa2xx_ac97_finish_reset(struct snd_ac97 *ac97);
extern bool pxa2xx_ac97_try_warm_reset(void);
extern bool pxa2xx_ac97_try_cold_reset(void);
extern void pxa2xx_ac97_finish_reset(void);
extern int pxa2xx_ac97_hw_suspend(void);
extern int pxa2xx_ac97_hw_resume(void);

View file

@ -11,11 +11,19 @@
#ifndef __LINUX_SND_RT5651_H
#define __LINUX_SND_RT5651_H
enum rt5651_jd_src {
RT5651_JD_NULL,
RT5651_JD1_1,
RT5651_JD1_2,
RT5651_JD2,
};
struct rt5651_platform_data {
/* IN2 can optionally be differential */
bool in2_diff;
bool dmic_en;
enum rt5651_jd_src jd_src;
};
#endif

View file

@ -16,6 +16,9 @@ struct rt5663_platform_data {
unsigned int dc_offset_r_manual;
unsigned int dc_offset_l_manual_mic;
unsigned int dc_offset_r_manual_mic;
unsigned int impedance_sensing_num;
unsigned int *impedance_sensing_table;
};
#endif

View file

@ -29,6 +29,7 @@ struct _snd_wavefront_midi {
struct snd_rawmidi_substream *substream_output[2];
struct snd_rawmidi_substream *substream_input[2];
struct timer_list timer;
snd_wavefront_card_t *timer_card;
spinlock_t open;
spinlock_t virtual; /* protects isvirtual */
};

View file

@ -0,0 +1,32 @@
/*
* Copyright (C) 2017, Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version
* 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef __LINUX_SND_SOC_ACPI_INTEL_MATCH_H
#define __LINUX_SND_SOC_ACPI_INTEL_MATCH_H
#include <linux/stddef.h>
#include <linux/acpi.h>
/*
* these tables are not constants, some fields can be used for
* pdata or machine ops
*/
extern struct snd_soc_acpi_mach snd_soc_acpi_intel_haswell_machines[];
extern struct snd_soc_acpi_mach snd_soc_acpi_intel_broadwell_machines[];
extern struct snd_soc_acpi_mach snd_soc_acpi_intel_baytrail_legacy_machines[];
extern struct snd_soc_acpi_mach snd_soc_acpi_intel_baytrail_machines[];
extern struct snd_soc_acpi_mach snd_soc_acpi_intel_cherrytrail_machines[];
#endif

111
include/sound/soc-acpi.h Normal file
View file

@ -0,0 +1,111 @@
/*
* Copyright (C) 2013-15, Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version
* 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef __LINUX_SND_SOC_ACPI_H
#define __LINUX_SND_SOC_ACPI_H
#include <linux/stddef.h>
#include <linux/acpi.h>
struct snd_soc_acpi_package_context {
char *name; /* package name */
int length; /* number of elements */
struct acpi_buffer *format;
struct acpi_buffer *state;
bool data_valid;
};
#if IS_ENABLED(CONFIG_ACPI)
/* translation fron HID to I2C name, needed for DAI codec_name */
const char *snd_soc_acpi_find_name_from_hid(const u8 hid[ACPI_ID_LEN]);
bool snd_soc_acpi_find_package_from_hid(const u8 hid[ACPI_ID_LEN],
struct snd_soc_acpi_package_context *ctx);
#else
static inline const char *
snd_soc_acpi_find_name_from_hid(const u8 hid[ACPI_ID_LEN])
{
return NULL;
}
static inline bool
snd_soc_acpi_find_package_from_hid(const u8 hid[ACPI_ID_LEN],
struct snd_soc_acpi_package_context *ctx)
{
return false;
}
#endif
/* acpi match */
struct snd_soc_acpi_mach *
snd_soc_acpi_find_machine(struct snd_soc_acpi_mach *machines);
/* acpi check hid */
bool snd_soc_acpi_check_hid(const u8 hid[ACPI_ID_LEN]);
/**
* snd_soc_acpi_mach: ACPI-based machine descriptor. Most of the fields are
* related to the hardware, except for the firmware and topology file names.
* A platform supported by legacy and Sound Open Firmware (SOF) would expose
* all firmware/topology related fields.
*
* @id: ACPI ID (usually the codec's) used to find a matching machine driver.
* @drv_name: machine driver name
* @fw_filename: firmware file name. Used when SOF is not enabled.
* @board: board name
* @machine_quirk: pointer to quirk, usually based on DMI information when
* ACPI ID alone is not sufficient, wrong or misleading
* @quirk_data: data used to uniquely identify a machine, usually a list of
* audio codecs whose presence if checked with ACPI
* @pdata: intended for platform data or machine specific-ops. This structure
* is not constant since this field may be updated at run-time
* @sof_fw_filename: Sound Open Firmware file name, if enabled
* @sof_tplg_filename: Sound Open Firmware topology file name, if enabled
* @asoc_plat_name: ASoC platform name, used for binding machine drivers
* if non NULL
* @new_mach_data: machine driver private data fixup
*/
/* Descriptor for SST ASoC machine driver */
struct snd_soc_acpi_mach {
const u8 id[ACPI_ID_LEN];
const char *drv_name;
const char *fw_filename;
const char *board;
struct snd_soc_acpi_mach * (*machine_quirk)(void *arg);
const void *quirk_data;
void *pdata;
const char *sof_fw_filename;
const char *sof_tplg_filename;
const char *asoc_plat_name;
struct platform_device * (*new_mach_data)(void *pdata);
};
#define SND_SOC_ACPI_MAX_CODECS 3
/**
* struct snd_soc_acpi_codecs: Structure to hold secondary codec information
* apart from the matched one, this data will be passed to the quirk function
* to match with the ACPI detected devices
*
* @num_codecs: number of secondary codecs used in the platform
* @codecs: holds the codec IDs
*
*/
struct snd_soc_acpi_codecs {
int num_codecs;
u8 codecs[SND_SOC_ACPI_MAX_CODECS][ACPI_ID_LEN];
};
/* check all codecs */
struct snd_soc_acpi_mach *snd_soc_acpi_codec_list(void *arg);
#endif

View file

@ -468,6 +468,11 @@ int snd_soc_register_codec(struct device *dev,
const struct snd_soc_codec_driver *codec_drv,
struct snd_soc_dai_driver *dai_drv, int num_dai);
void snd_soc_unregister_codec(struct device *dev);
int snd_soc_add_component(struct device *dev,
struct snd_soc_component *component,
const struct snd_soc_component_driver *component_driver,
struct snd_soc_dai_driver *dai_drv,
int num_dai);
int snd_soc_register_component(struct device *dev,
const struct snd_soc_component_driver *component_driver,
struct snd_soc_dai_driver *dai_drv, int num_dai);
@ -475,6 +480,8 @@ int devm_snd_soc_register_component(struct device *dev,
const struct snd_soc_component_driver *component_driver,
struct snd_soc_dai_driver *dai_drv, int num_dai);
void snd_soc_unregister_component(struct device *dev);
struct snd_soc_component *snd_soc_lookup_component(struct device *dev,
const char *driver_name);
int snd_soc_cache_init(struct snd_soc_codec *codec);
int snd_soc_cache_exit(struct snd_soc_codec *codec);
@ -795,6 +802,10 @@ struct snd_soc_component_driver {
int (*suspend)(struct snd_soc_component *);
int (*resume)(struct snd_soc_component *);
/* pcm creation and destruction */
int (*pcm_new)(struct snd_soc_pcm_runtime *);
void (*pcm_free)(struct snd_pcm *);
/* component wide operations */
int (*set_sysclk)(struct snd_soc_component *component,
int clk_id, int source, unsigned int freq, int dir);
@ -812,10 +823,22 @@ struct snd_soc_component_driver {
void (*seq_notifier)(struct snd_soc_component *, enum snd_soc_dapm_type,
int subseq);
int (*stream_event)(struct snd_soc_component *, int event);
int (*set_bias_level)(struct snd_soc_component *component,
enum snd_soc_bias_level level);
const struct snd_pcm_ops *ops;
const struct snd_compr_ops *compr_ops;
/* probe ordering - for components with runtime dependencies */
int probe_order;
int remove_order;
/* bits */
unsigned int idle_bias_on:1;
unsigned int suspend_bias_off:1;
unsigned int pmdown_time:1; /* care pmdown_time at stop */
unsigned int endianness:1;
unsigned int non_legacy_dai_naming:1;
};
struct snd_soc_component {
@ -872,6 +895,8 @@ struct snd_soc_component {
void (*remove)(struct snd_soc_component *);
int (*suspend)(struct snd_soc_component *);
int (*resume)(struct snd_soc_component *);
int (*pcm_new)(struct snd_soc_component *, struct snd_soc_pcm_runtime *);
void (*pcm_free)(struct snd_soc_component *, struct snd_pcm *);
int (*set_sysclk)(struct snd_soc_component *component,
int clk_id, int source, unsigned int freq, int dir);
@ -879,6 +904,8 @@ struct snd_soc_component {
int source, unsigned int freq_in, unsigned int freq_out);
int (*set_jack)(struct snd_soc_component *component,
struct snd_soc_jack *jack, void *data);
int (*set_bias_level)(struct snd_soc_component *component,
enum snd_soc_bias_level level);
/* machine specific init */
int (*init)(struct snd_soc_component *component);
@ -1412,6 +1439,21 @@ static inline void snd_soc_codec_init_bias_level(struct snd_soc_codec *codec,
snd_soc_dapm_init_bias_level(snd_soc_codec_get_dapm(codec), level);
}
/**
* snd_soc_component_init_bias_level() - Initialize COMPONENT DAPM bias level
* @component: The COMPONENT for which to initialize the DAPM bias level
* @level: The DAPM level to initialize to
*
* Initializes the COMPONENT DAPM bias level. See snd_soc_dapm_init_bias_level().
*/
static inline void
snd_soc_component_init_bias_level(struct snd_soc_component *component,
enum snd_soc_bias_level level)
{
snd_soc_dapm_init_bias_level(
snd_soc_component_get_dapm(component), level);
}
/**
* snd_soc_dapm_get_bias_level() - Get current CODEC DAPM bias level
* @codec: The CODEC for which to get the DAPM bias level
@ -1424,6 +1466,19 @@ static inline enum snd_soc_bias_level snd_soc_codec_get_bias_level(
return snd_soc_dapm_get_bias_level(snd_soc_codec_get_dapm(codec));
}
/**
* snd_soc_component_get_bias_level() - Get current COMPONENT DAPM bias level
* @component: The COMPONENT for which to get the DAPM bias level
*
* Returns: The current DAPM bias level of the COMPONENT.
*/
static inline enum snd_soc_bias_level
snd_soc_component_get_bias_level(struct snd_soc_component *component)
{
return snd_soc_dapm_get_bias_level(
snd_soc_component_get_dapm(component));
}
/**
* snd_soc_codec_force_bias_level() - Set the CODEC DAPM bias level
* @codec: The CODEC for which to set the level
@ -1439,6 +1494,23 @@ static inline int snd_soc_codec_force_bias_level(struct snd_soc_codec *codec,
level);
}
/**
* snd_soc_component_force_bias_level() - Set the COMPONENT DAPM bias level
* @component: The COMPONENT for which to set the level
* @level: The level to set to
*
* Forces the COMPONENT bias level to a specific state. See
* snd_soc_dapm_force_bias_level().
*/
static inline int
snd_soc_component_force_bias_level(struct snd_soc_component *component,
enum snd_soc_bias_level level)
{
return snd_soc_dapm_force_bias_level(
snd_soc_component_get_dapm(component),
level);
}
/**
* snd_soc_dapm_kcontrol_codec() - Returns the codec associated to a kcontrol
* @kcontrol: The kcontrol
@ -1452,6 +1524,19 @@ static inline struct snd_soc_codec *snd_soc_dapm_kcontrol_codec(
return snd_soc_dapm_to_codec(snd_soc_dapm_kcontrol_dapm(kcontrol));
}
/**
* snd_soc_dapm_kcontrol_component() - Returns the component associated to a kcontrol
* @kcontrol: The kcontrol
*
* This function must only be used on DAPM contexts that are known to be part of
* a COMPONENT (e.g. in a COMPONENT driver). Otherwise the behavior is undefined.
*/
static inline struct snd_soc_component *snd_soc_dapm_kcontrol_component(
struct snd_kcontrol *kcontrol)
{
return snd_soc_dapm_to_component(snd_soc_dapm_kcontrol_dapm(kcontrol));
}
/* codec IO */
unsigned int snd_soc_read(struct snd_soc_codec *codec, unsigned int reg);
int snd_soc_write(struct snd_soc_codec *codec, unsigned int reg,
@ -1468,9 +1553,23 @@ static inline int snd_soc_cache_sync(struct snd_soc_codec *codec)
return regcache_sync(codec->component.regmap);
}
/**
* snd_soc_component_cache_sync() - Sync the register cache with the hardware
* @component: COMPONENT to sync
*
* Note: This function will call regcache_sync()
*/
static inline int snd_soc_component_cache_sync(
struct snd_soc_component *component)
{
return regcache_sync(component->regmap);
}
/* component IO */
int snd_soc_component_read(struct snd_soc_component *component,
unsigned int reg, unsigned int *val);
unsigned int snd_soc_component_read32(struct snd_soc_component *component,
unsigned int reg);
int snd_soc_component_write(struct snd_soc_component *component,
unsigned int reg, unsigned int val);
int snd_soc_component_update_bits(struct snd_soc_component *component,
@ -1487,6 +1586,8 @@ int snd_soc_component_set_sysclk(struct snd_soc_component *component,
int snd_soc_component_set_pll(struct snd_soc_component *component, int pll_id,
int source, unsigned int freq_in,
unsigned int freq_out);
int snd_soc_component_set_jack(struct snd_soc_component *component,
struct snd_soc_jack *jack, void *data);
#ifdef CONFIG_REGMAP
@ -1720,6 +1821,20 @@ struct snd_soc_dai *snd_soc_find_dai(
#include <sound/soc-dai.h>
static inline
struct snd_soc_dai *snd_soc_card_get_codec_dai(struct snd_soc_card *card,
const char *dai_name)
{
struct snd_soc_pcm_runtime *rtd;
list_for_each_entry(rtd, &card->rtd_list, list) {
if (!strcmp(rtd->codec_dai->name, dai_name))
return rtd->codec_dai;
}
return NULL;
}
#ifdef CONFIG_DEBUG_FS
extern struct dentry *snd_soc_debugfs_root;
#endif

View file

@ -3,25 +3,7 @@ menuconfig SOUND
depends on HAS_IOMEM
help
If you have a sound card in your computer, i.e. if it can say more
than an occasional beep, say Y. Be sure to have all the information
about your sound card and its configuration down (I/O port,
interrupt and DMA channel), because you will be asked for it.
You want to read the Sound-HOWTO, available from
<http://www.tldp.org/docs.html#howto>. General information about
the modular sound system is contained in the files
<file:Documentation/sound/oss/Introduction>. The file
<file:Documentation/sound/oss/README.OSS> contains some slightly
outdated but still useful information as well. Newer sound
driver documentation is found in <file:Documentation/sound/alsa/*>.
If you have a PnP sound card and you want to configure it at boot
time using the ISA PnP tools (read
<http://www.roestock.demon.co.uk/isapnptools/>), then you need to
compile the sound card support as a module and load that module
after the PnP configuration is finished. To do this, choose M here
and read <file:Documentation/sound/oss/README.modules>; the module
will be called soundcore.
than an occasional beep, say Y.
if SOUND
@ -80,6 +62,8 @@ source "sound/hda/Kconfig"
source "sound/ppc/Kconfig"
source "sound/ac97/Kconfig"
source "sound/aoa/Kconfig"
source "sound/arm/Kconfig"
@ -114,19 +98,6 @@ source "sound/synth/Kconfig"
endif # SND
menuconfig SOUND_PRIME
tristate "Open Sound System (DEPRECATED)"
select SOUND_OSS_CORE
depends on BROKEN
help
Say 'Y' or 'M' to enable Open Sound System drivers.
if SOUND_PRIME
source "sound/oss/Kconfig"
endif # SOUND_PRIME
endif # !UML
endif # SOUND

View file

@ -3,14 +3,14 @@
#
obj-$(CONFIG_SOUND) += soundcore.o
obj-$(CONFIG_SOUND_PRIME) += oss/
obj-$(CONFIG_DMASOUND) += oss/
obj-$(CONFIG_DMASOUND) += oss/dmasound/
obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ sh/ synth/ usb/ \
firewire/ sparc/ spi/ parisc/ pcmcia/ mips/ soc/ atmel/ hda/ x86/
obj-$(CONFIG_SND_AOA) += aoa/
# This one must be compilable even if sound is configured out
obj-$(CONFIG_AC97_BUS) += ac97_bus.o
obj-$(CONFIG_AC97_BUS_NEW) += ac97/
ifeq ($(CONFIG_SND),y)
obj-y += last.o

19
sound/ac97/Kconfig Normal file
View file

@ -0,0 +1,19 @@
#
# AC97 configuration
#
config AC97_BUS_NEW
tristate
select AC97
help
This is the new AC97 bus type, successor of AC97_BUS. The ported
drivers which benefit from the AC97 automatic probing should "select"
this instead of the AC97_BUS.
Say Y here if you want to have AC97 devices, which are sound oriented
devices around an AC-Link.
config AC97_BUS_COMPAT
bool
depends on AC97_BUS_NEW
depends on !AC97_BUS

8
sound/ac97/Makefile Normal file
View file

@ -0,0 +1,8 @@
#
# make for AC97 bus drivers
#
obj-$(CONFIG_AC97_BUS_NEW) += ac97.o
ac97-y += bus.o codec.o
ac97-$(CONFIG_AC97_BUS_COMPAT) += snd_ac97_compat.o

16
sound/ac97/ac97_core.h Normal file
View file

@ -0,0 +1,16 @@
/*
* Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
unsigned int snd_ac97_bus_scan_one(struct ac97_controller *ac97,
unsigned int codec_num);
static inline bool ac97_ids_match(unsigned int id1, unsigned int id2,
unsigned int mask)
{
return (id1 & mask) == (id2 & mask);
}

539
sound/ac97/bus.c Normal file
View file

@ -0,0 +1,539 @@
/*
* Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/module.h>
#include <linux/bitops.h>
#include <linux/clk.h>
#include <linux/device.h>
#include <linux/idr.h>
#include <linux/list.h>
#include <linux/mutex.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
#include <linux/slab.h>
#include <linux/sysfs.h>
#include <sound/ac97/codec.h>
#include <sound/ac97/controller.h>
#include <sound/ac97/regs.h>
#include "ac97_core.h"
/*
* Protects ac97_controllers and each ac97_controller structure.
*/
static DEFINE_MUTEX(ac97_controllers_mutex);
static DEFINE_IDR(ac97_adapter_idr);
static LIST_HEAD(ac97_controllers);
static struct bus_type ac97_bus_type;
static inline struct ac97_controller*
to_ac97_controller(struct device *ac97_adapter)
{
return container_of(ac97_adapter, struct ac97_controller, adap);
}
static int ac97_unbound_ctrl_write(struct ac97_controller *adrv, int slot,
unsigned short reg, unsigned short val)
{
return -ENODEV;
}
static int ac97_unbound_ctrl_read(struct ac97_controller *adrv, int slot,
unsigned short reg)
{
return -ENODEV;
}
static const struct ac97_controller_ops ac97_unbound_ctrl_ops = {
.write = ac97_unbound_ctrl_write,
.read = ac97_unbound_ctrl_read,
};
static struct ac97_controller ac97_unbound_ctrl = {
.ops = &ac97_unbound_ctrl_ops,
};
static struct ac97_codec_device *
ac97_codec_find(struct ac97_controller *ac97_ctrl, unsigned int codec_num)
{
if (codec_num >= AC97_BUS_MAX_CODECS)
return ERR_PTR(-EINVAL);
return ac97_ctrl->codecs[codec_num];
}
static void ac97_codec_release(struct device *dev)
{
struct ac97_codec_device *adev;
struct ac97_controller *ac97_ctrl;
adev = to_ac97_device(dev);
ac97_ctrl = adev->ac97_ctrl;
ac97_ctrl->codecs[adev->num] = NULL;
kfree(adev);
}
static int ac97_codec_add(struct ac97_controller *ac97_ctrl, int idx,
unsigned int vendor_id)
{
struct ac97_codec_device *codec;
int ret;
codec = kzalloc(sizeof(*codec), GFP_KERNEL);
if (!codec)
return -ENOMEM;
ac97_ctrl->codecs[idx] = codec;
codec->vendor_id = vendor_id;
codec->dev.release = ac97_codec_release;
codec->dev.bus = &ac97_bus_type;
codec->dev.parent = &ac97_ctrl->adap;
codec->num = idx;
codec->ac97_ctrl = ac97_ctrl;
device_initialize(&codec->dev);
dev_set_name(&codec->dev, "%s:%u", dev_name(ac97_ctrl->parent), idx);
ret = device_add(&codec->dev);
if (ret)
goto err_free_codec;
return 0;
err_free_codec:
put_device(&codec->dev);
kfree(codec);
ac97_ctrl->codecs[idx] = NULL;
return ret;
}
unsigned int snd_ac97_bus_scan_one(struct ac97_controller *adrv,
unsigned int codec_num)
{
unsigned short vid1, vid2;
int ret;
ret = adrv->ops->read(adrv, codec_num, AC97_VENDOR_ID1);
vid1 = (ret & 0xffff);
if (ret < 0)
return 0;
ret = adrv->ops->read(adrv, codec_num, AC97_VENDOR_ID2);
vid2 = (ret & 0xffff);
if (ret < 0)
return 0;
dev_dbg(&adrv->adap, "%s(codec_num=%u): vendor_id=0x%08x\n",
__func__, codec_num, AC97_ID(vid1, vid2));
return AC97_ID(vid1, vid2);
}
static int ac97_bus_scan(struct ac97_controller *ac97_ctrl)
{
int ret, i;
unsigned int vendor_id;
for (i = 0; i < AC97_BUS_MAX_CODECS; i++) {
if (ac97_codec_find(ac97_ctrl, i))
continue;
if (!(ac97_ctrl->slots_available & BIT(i)))
continue;
vendor_id = snd_ac97_bus_scan_one(ac97_ctrl, i);
if (!vendor_id)
continue;
ret = ac97_codec_add(ac97_ctrl, i, vendor_id);
if (ret < 0)
return ret;
}
return 0;
}
static int ac97_bus_reset(struct ac97_controller *ac97_ctrl)
{
ac97_ctrl->ops->reset(ac97_ctrl);
return 0;
}
/**
* snd_ac97_codec_driver_register - register an AC97 codec driver
* @dev: AC97 driver codec to register
*
* Register an AC97 codec driver to the ac97 bus driver, aka. the AC97 digital
* controller.
*
* Returns 0 on success or error code
*/
int snd_ac97_codec_driver_register(struct ac97_codec_driver *drv)
{
drv->driver.bus = &ac97_bus_type;
return driver_register(&drv->driver);
}
EXPORT_SYMBOL_GPL(snd_ac97_codec_driver_register);
/**
* snd_ac97_codec_driver_unregister - unregister an AC97 codec driver
* @dev: AC97 codec driver to unregister
*
* Unregister a previously registered ac97 codec driver.
*/
void snd_ac97_codec_driver_unregister(struct ac97_codec_driver *drv)
{
driver_unregister(&drv->driver);
}
EXPORT_SYMBOL_GPL(snd_ac97_codec_driver_unregister);
/**
* snd_ac97_codec_get_platdata - get platform_data
* @adev: the ac97 codec device
*
* For legacy platforms, in order to have platform_data in codec drivers
* available, while ac97 device are auto-created upon probe, this retrieves the
* platdata which was setup on ac97 controller registration.
*
* Returns the platform data pointer
*/
void *snd_ac97_codec_get_platdata(const struct ac97_codec_device *adev)
{
struct ac97_controller *ac97_ctrl = adev->ac97_ctrl;
return ac97_ctrl->codecs_pdata[adev->num];
}
EXPORT_SYMBOL_GPL(snd_ac97_codec_get_platdata);
static void ac97_ctrl_codecs_unregister(struct ac97_controller *ac97_ctrl)
{
int i;
for (i = 0; i < AC97_BUS_MAX_CODECS; i++)
if (ac97_ctrl->codecs[i]) {
ac97_ctrl->codecs[i]->ac97_ctrl = &ac97_unbound_ctrl;
device_unregister(&ac97_ctrl->codecs[i]->dev);
}
}
static ssize_t cold_reset_store(struct device *dev,
struct device_attribute *attr, const char *buf,
size_t len)
{
struct ac97_controller *ac97_ctrl;
mutex_lock(&ac97_controllers_mutex);
ac97_ctrl = to_ac97_controller(dev);
ac97_ctrl->ops->reset(ac97_ctrl);
mutex_unlock(&ac97_controllers_mutex);
return len;
}
static DEVICE_ATTR_WO(cold_reset);
static ssize_t warm_reset_store(struct device *dev,
struct device_attribute *attr, const char *buf,
size_t len)
{
struct ac97_controller *ac97_ctrl;
if (!dev)
return -ENODEV;
mutex_lock(&ac97_controllers_mutex);
ac97_ctrl = to_ac97_controller(dev);
ac97_ctrl->ops->warm_reset(ac97_ctrl);
mutex_unlock(&ac97_controllers_mutex);
return len;
}
static DEVICE_ATTR_WO(warm_reset);
static struct attribute *ac97_controller_device_attrs[] = {
&dev_attr_cold_reset.attr,
&dev_attr_warm_reset.attr,
NULL
};
static struct attribute_group ac97_adapter_attr_group = {
.name = "ac97_operations",
.attrs = ac97_controller_device_attrs,
};
static const struct attribute_group *ac97_adapter_groups[] = {
&ac97_adapter_attr_group,
NULL,
};
static void ac97_del_adapter(struct ac97_controller *ac97_ctrl)
{
mutex_lock(&ac97_controllers_mutex);
ac97_ctrl_codecs_unregister(ac97_ctrl);
list_del(&ac97_ctrl->controllers);
mutex_unlock(&ac97_controllers_mutex);
device_unregister(&ac97_ctrl->adap);
}
static void ac97_adapter_release(struct device *dev)
{
struct ac97_controller *ac97_ctrl;
ac97_ctrl = to_ac97_controller(dev);
idr_remove(&ac97_adapter_idr, ac97_ctrl->nr);
dev_dbg(&ac97_ctrl->adap, "adapter unregistered by %s\n",
dev_name(ac97_ctrl->parent));
}
static const struct device_type ac97_adapter_type = {
.groups = ac97_adapter_groups,
.release = ac97_adapter_release,
};
static int ac97_add_adapter(struct ac97_controller *ac97_ctrl)
{
int ret;
mutex_lock(&ac97_controllers_mutex);
ret = idr_alloc(&ac97_adapter_idr, ac97_ctrl, 0, 0, GFP_KERNEL);
ac97_ctrl->nr = ret;
if (ret >= 0) {
dev_set_name(&ac97_ctrl->adap, "ac97-%d", ret);
ac97_ctrl->adap.type = &ac97_adapter_type;
ac97_ctrl->adap.parent = ac97_ctrl->parent;
ret = device_register(&ac97_ctrl->adap);
if (ret)
put_device(&ac97_ctrl->adap);
}
if (!ret)
list_add(&ac97_ctrl->controllers, &ac97_controllers);
mutex_unlock(&ac97_controllers_mutex);
if (!ret)
dev_dbg(&ac97_ctrl->adap, "adapter registered by %s\n",
dev_name(ac97_ctrl->parent));
return ret;
}
/**
* snd_ac97_controller_register - register an ac97 controller
* @ops: the ac97 bus operations
* @dev: the device providing the ac97 DC function
* @slots_available: mask of the ac97 codecs that can be scanned and probed
* bit0 => codec 0, bit1 => codec 1 ... bit 3 => codec 3
*
* Register a digital controller which can control up to 4 ac97 codecs. This is
* the controller side of the AC97 AC-link, while the slave side are the codecs.
*
* Returns a valid controller upon success, negative pointer value upon error
*/
struct ac97_controller *snd_ac97_controller_register(
const struct ac97_controller_ops *ops, struct device *dev,
unsigned short slots_available, void **codecs_pdata)
{
struct ac97_controller *ac97_ctrl;
int ret, i;
ac97_ctrl = kzalloc(sizeof(*ac97_ctrl), GFP_KERNEL);
if (!ac97_ctrl)
return ERR_PTR(-ENOMEM);
for (i = 0; i < AC97_BUS_MAX_CODECS && codecs_pdata; i++)
ac97_ctrl->codecs_pdata[i] = codecs_pdata[i];
ac97_ctrl->ops = ops;
ac97_ctrl->slots_available = slots_available;
ac97_ctrl->parent = dev;
ret = ac97_add_adapter(ac97_ctrl);
if (ret)
goto err;
ac97_bus_reset(ac97_ctrl);
ac97_bus_scan(ac97_ctrl);
return ac97_ctrl;
err:
kfree(ac97_ctrl);
return ERR_PTR(ret);
}
EXPORT_SYMBOL_GPL(snd_ac97_controller_register);
/**
* snd_ac97_controller_unregister - unregister an ac97 controller
* @ac97_ctrl: the device previously provided to ac97_controller_register()
*
*/
void snd_ac97_controller_unregister(struct ac97_controller *ac97_ctrl)
{
ac97_del_adapter(ac97_ctrl);
}
EXPORT_SYMBOL_GPL(snd_ac97_controller_unregister);
#ifdef CONFIG_PM
static int ac97_pm_runtime_suspend(struct device *dev)
{
struct ac97_codec_device *codec = to_ac97_device(dev);
int ret = pm_generic_runtime_suspend(dev);
if (ret == 0 && dev->driver) {
if (pm_runtime_is_irq_safe(dev))
clk_disable(codec->clk);
else
clk_disable_unprepare(codec->clk);
}
return ret;
}
static int ac97_pm_runtime_resume(struct device *dev)
{
struct ac97_codec_device *codec = to_ac97_device(dev);
int ret;
if (dev->driver) {
if (pm_runtime_is_irq_safe(dev))
ret = clk_enable(codec->clk);
else
ret = clk_prepare_enable(codec->clk);
if (ret)
return ret;
}
return pm_generic_runtime_resume(dev);
}
#endif /* CONFIG_PM */
static const struct dev_pm_ops ac97_pm = {
.suspend = pm_generic_suspend,
.resume = pm_generic_resume,
.freeze = pm_generic_freeze,
.thaw = pm_generic_thaw,
.poweroff = pm_generic_poweroff,
.restore = pm_generic_restore,
SET_RUNTIME_PM_OPS(
ac97_pm_runtime_suspend,
ac97_pm_runtime_resume,
NULL)
};
static int ac97_get_enable_clk(struct ac97_codec_device *adev)
{
int ret;
adev->clk = clk_get(&adev->dev, "ac97_clk");
if (IS_ERR(adev->clk))
return PTR_ERR(adev->clk);
ret = clk_prepare_enable(adev->clk);
if (ret)
clk_put(adev->clk);
return ret;
}
static void ac97_put_disable_clk(struct ac97_codec_device *adev)
{
clk_disable_unprepare(adev->clk);
clk_put(adev->clk);
}
static ssize_t vendor_id_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct ac97_codec_device *codec = to_ac97_device(dev);
return sprintf(buf, "%08x", codec->vendor_id);
}
DEVICE_ATTR_RO(vendor_id);
static struct attribute *ac97_dev_attrs[] = {
&dev_attr_vendor_id.attr,
NULL,
};
ATTRIBUTE_GROUPS(ac97_dev);
static int ac97_bus_match(struct device *dev, struct device_driver *drv)
{
struct ac97_codec_device *adev = to_ac97_device(dev);
struct ac97_codec_driver *adrv = to_ac97_driver(drv);
const struct ac97_id *id = adrv->id_table;
int i = 0;
if (adev->vendor_id == 0x0 || adev->vendor_id == 0xffffffff)
return false;
do {
if (ac97_ids_match(id[i].id, adev->vendor_id, id[i].mask))
return true;
} while (id[i++].id);
return false;
}
static int ac97_bus_probe(struct device *dev)
{
struct ac97_codec_device *adev = to_ac97_device(dev);
struct ac97_codec_driver *adrv = to_ac97_driver(dev->driver);
int ret;
ret = ac97_get_enable_clk(adev);
if (ret)
return ret;
pm_runtime_get_noresume(dev);
pm_runtime_set_active(dev);
pm_runtime_enable(dev);
ret = adrv->probe(adev);
if (ret == 0)
return 0;
pm_runtime_disable(dev);
pm_runtime_set_suspended(dev);
pm_runtime_put_noidle(dev);
ac97_put_disable_clk(adev);
return ret;
}
static int ac97_bus_remove(struct device *dev)
{
struct ac97_codec_device *adev = to_ac97_device(dev);
struct ac97_codec_driver *adrv = to_ac97_driver(dev->driver);
int ret;
ret = pm_runtime_get_sync(dev);
if (ret)
return ret;
ret = adrv->remove(adev);
pm_runtime_put_noidle(dev);
if (ret == 0)
ac97_put_disable_clk(adev);
return ret;
}
static struct bus_type ac97_bus_type = {
.name = "ac97bus",
.dev_groups = ac97_dev_groups,
.match = ac97_bus_match,
.pm = &ac97_pm,
.probe = ac97_bus_probe,
.remove = ac97_bus_remove,
};
static int __init ac97_bus_init(void)
{
return bus_register(&ac97_bus_type);
}
subsys_initcall(ac97_bus_init);
static void __exit ac97_bus_exit(void)
{
bus_unregister(&ac97_bus_type);
}
module_exit(ac97_bus_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Robert Jarzmik <robert.jarzmik@free.fr>");

15
sound/ac97/codec.c Normal file
View file

@ -0,0 +1,15 @@
/*
* Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <sound/ac97_codec.h>
#include <sound/ac97/codec.h>
#include <sound/ac97/controller.h>
#include <linux/device.h>
#include <linux/slab.h>
#include <sound/soc.h> /* For compat_ac97_* */

View file

@ -0,0 +1,108 @@
/*
* Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/list.h>
#include <linux/slab.h>
#include <sound/ac97/codec.h>
#include <sound/ac97/compat.h>
#include <sound/ac97/controller.h>
#include <sound/soc.h>
#include "ac97_core.h"
static void compat_ac97_reset(struct snd_ac97 *ac97)
{
struct ac97_codec_device *adev = to_ac97_device(ac97->private_data);
struct ac97_controller *actrl = adev->ac97_ctrl;
if (actrl->ops->reset)
actrl->ops->reset(actrl);
}
static void compat_ac97_warm_reset(struct snd_ac97 *ac97)
{
struct ac97_codec_device *adev = to_ac97_device(ac97->private_data);
struct ac97_controller *actrl = adev->ac97_ctrl;
if (actrl->ops->warm_reset)
actrl->ops->warm_reset(actrl);
}
static void compat_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
unsigned short val)
{
struct ac97_codec_device *adev = to_ac97_device(ac97->private_data);
struct ac97_controller *actrl = adev->ac97_ctrl;
actrl->ops->write(actrl, ac97->num, reg, val);
}
static unsigned short compat_ac97_read(struct snd_ac97 *ac97,
unsigned short reg)
{
struct ac97_codec_device *adev = to_ac97_device(ac97->private_data);
struct ac97_controller *actrl = adev->ac97_ctrl;
return actrl->ops->read(actrl, ac97->num, reg);
}
static struct snd_ac97_bus_ops compat_snd_ac97_bus_ops = {
.reset = compat_ac97_reset,
.warm_reset = compat_ac97_warm_reset,
.write = compat_ac97_write,
.read = compat_ac97_read,
};
static struct snd_ac97_bus compat_soc_ac97_bus = {
.ops = &compat_snd_ac97_bus_ops,
};
struct snd_ac97 *snd_ac97_compat_alloc(struct ac97_codec_device *adev)
{
struct snd_ac97 *ac97;
ac97 = kzalloc(sizeof(struct snd_ac97), GFP_KERNEL);
if (ac97 == NULL)
return ERR_PTR(-ENOMEM);
ac97->dev = adev->dev;
ac97->private_data = adev;
ac97->bus = &compat_soc_ac97_bus;
return ac97;
}
EXPORT_SYMBOL_GPL(snd_ac97_compat_alloc);
void snd_ac97_compat_release(struct snd_ac97 *ac97)
{
kfree(ac97);
}
EXPORT_SYMBOL_GPL(snd_ac97_compat_release);
int snd_ac97_reset(struct snd_ac97 *ac97, bool try_warm, unsigned int id,
unsigned int id_mask)
{
struct ac97_codec_device *adev = to_ac97_device(ac97->private_data);
struct ac97_controller *actrl = adev->ac97_ctrl;
unsigned int scanned;
if (try_warm) {
compat_ac97_warm_reset(ac97);
scanned = snd_ac97_bus_scan_one(actrl, adev->num);
if (ac97_ids_match(scanned, adev->vendor_id, id_mask))
return 1;
}
compat_ac97_reset(ac97);
compat_ac97_warm_reset(ac97);
scanned = snd_ac97_bus_scan_one(actrl, adev->num);
if (ac97_ids_match(scanned, adev->vendor_id, id_mask))
return 0;
return -ENODEV;
}
EXPORT_SYMBOL_GPL(snd_ac97_reset);

View file

@ -20,7 +20,6 @@
#include <linux/io.h>
#include <linux/gpio.h>
#include <sound/ac97_codec.h>
#include <sound/pxa2xx-lib.h>
#include <mach/irqs.h>
@ -46,38 +45,41 @@ extern void pxa27x_configure_ac97reset(int reset_gpio, bool to_gpio);
* 1 jiffy timeout if interrupt never comes).
*/
unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
int pxa2xx_ac97_read(int slot, unsigned short reg)
{
unsigned short val = -1;
int val = -ENODEV;
volatile u32 *reg_addr;
if (slot > 0)
return -ENODEV;
mutex_lock(&car_mutex);
/* set up primary or secondary codec space */
if (cpu_is_pxa25x() && reg == AC97_GPIO_STATUS)
reg_addr = ac97->num ? &SMC_REG_BASE : &PMC_REG_BASE;
reg_addr = slot ? &SMC_REG_BASE : &PMC_REG_BASE;
else
reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE;
reg_addr = slot ? &SAC_REG_BASE : &PAC_REG_BASE;
reg_addr += (reg >> 1);
/* start read access across the ac97 link */
GSR = GSR_CDONE | GSR_SDONE;
gsr_bits = 0;
val = *reg_addr;
val = (*reg_addr & 0xffff);
if (reg == AC97_GPIO_STATUS)
goto out;
if (wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1) <= 0 &&
!((GSR | gsr_bits) & GSR_SDONE)) {
printk(KERN_ERR "%s: read error (ac97_reg=%d GSR=%#lx)\n",
__func__, reg, GSR | gsr_bits);
val = -1;
val = -ETIMEDOUT;
goto out;
}
/* valid data now */
GSR = GSR_CDONE | GSR_SDONE;
gsr_bits = 0;
val = *reg_addr;
val = (*reg_addr & 0xffff);
/* but we've just started another cycle... */
wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1);
@ -86,29 +88,32 @@ out: mutex_unlock(&car_mutex);
}
EXPORT_SYMBOL_GPL(pxa2xx_ac97_read);
void pxa2xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
unsigned short val)
int pxa2xx_ac97_write(int slot, unsigned short reg, unsigned short val)
{
volatile u32 *reg_addr;
int ret = 0;
mutex_lock(&car_mutex);
/* set up primary or secondary codec space */
if (cpu_is_pxa25x() && reg == AC97_GPIO_STATUS)
reg_addr = ac97->num ? &SMC_REG_BASE : &PMC_REG_BASE;
reg_addr = slot ? &SMC_REG_BASE : &PMC_REG_BASE;
else
reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE;
reg_addr = slot ? &SAC_REG_BASE : &PAC_REG_BASE;
reg_addr += (reg >> 1);
GSR = GSR_CDONE | GSR_SDONE;
gsr_bits = 0;
*reg_addr = val;
if (wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_CDONE, 1) <= 0 &&
!((GSR | gsr_bits) & GSR_CDONE))
!((GSR | gsr_bits) & GSR_CDONE)) {
printk(KERN_ERR "%s: write error (ac97_reg=%d GSR=%#lx)\n",
__func__, reg, GSR | gsr_bits);
ret = -EIO;
}
mutex_unlock(&car_mutex);
return ret;
}
EXPORT_SYMBOL_GPL(pxa2xx_ac97_write);
@ -188,7 +193,7 @@ static inline void pxa_ac97_cold_pxa3xx(void)
}
#endif
bool pxa2xx_ac97_try_warm_reset(struct snd_ac97 *ac97)
bool pxa2xx_ac97_try_warm_reset(void)
{
unsigned long gsr;
unsigned int timeout = 100;
@ -225,7 +230,7 @@ bool pxa2xx_ac97_try_warm_reset(struct snd_ac97 *ac97)
}
EXPORT_SYMBOL_GPL(pxa2xx_ac97_try_warm_reset);
bool pxa2xx_ac97_try_cold_reset(struct snd_ac97 *ac97)
bool pxa2xx_ac97_try_cold_reset(void)
{
unsigned long gsr;
unsigned int timeout = 1000;
@ -263,7 +268,7 @@ bool pxa2xx_ac97_try_cold_reset(struct snd_ac97 *ac97)
EXPORT_SYMBOL_GPL(pxa2xx_ac97_try_cold_reset);
void pxa2xx_ac97_finish_reset(struct snd_ac97 *ac97)
void pxa2xx_ac97_finish_reset(void)
{
GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN);
GCR |= GCR_SDONE_IE|GCR_CDONE_IE;

View file

@ -29,19 +29,38 @@
#include "pxa2xx-pcm.h"
static void pxa2xx_ac97_reset(struct snd_ac97 *ac97)
static void pxa2xx_ac97_legacy_reset(struct snd_ac97 *ac97)
{
if (!pxa2xx_ac97_try_cold_reset(ac97)) {
pxa2xx_ac97_try_warm_reset(ac97);
}
if (!pxa2xx_ac97_try_cold_reset())
pxa2xx_ac97_try_warm_reset();
pxa2xx_ac97_finish_reset(ac97);
pxa2xx_ac97_finish_reset();
}
static unsigned short pxa2xx_ac97_legacy_read(struct snd_ac97 *ac97,
unsigned short reg)
{
int ret;
ret = pxa2xx_ac97_read(ac97->num, reg);
if (ret < 0)
return 0;
else
return (unsigned short)(ret & 0xffff);
}
static void pxa2xx_ac97_legacy_write(struct snd_ac97 *ac97,
unsigned short reg, unsigned short val)
{
int __always_unused ret;
ret = pxa2xx_ac97_write(ac97->num, reg, val);
}
static struct snd_ac97_bus_ops pxa2xx_ac97_ops = {
.read = pxa2xx_ac97_read,
.write = pxa2xx_ac97_write,
.reset = pxa2xx_ac97_reset,
.read = pxa2xx_ac97_legacy_read,
.write = pxa2xx_ac97_legacy_write,
.reset = pxa2xx_ac97_legacy_reset,
};
static struct pxad_param pxa2xx_ac97_pcm_out_req = {

View file

@ -127,7 +127,7 @@ static int snd_hrtimer_stop(struct snd_timer *t)
return 0;
}
static struct snd_timer_hardware hrtimer_hw = {
static const struct snd_timer_hardware hrtimer_hw __initconst = {
.flags = SNDRV_TIMER_HW_AUTO | SNDRV_TIMER_HW_TASKLET,
.open = snd_hrtimer_open,
.close = snd_hrtimer_close,

View file

@ -228,6 +228,8 @@ static int snd_hwdep_dsp_load(struct snd_hwdep *hw,
memset(&info, 0, sizeof(info));
if (copy_from_user(&info, _info, sizeof(info)))
return -EFAULT;
if (info.index >= 32)
return -EINVAL;
/* check whether the dsp was already loaded */
if (hw->dsp_loaded & (1 << info.index))
return -EBUSY;

View file

@ -255,6 +255,7 @@ int snd_card_new(struct device *parent, int idx, const char *xid,
#ifdef CONFIG_PM
init_waitqueue_head(&card->power_sleep);
#endif
init_waitqueue_head(&card->remove_sleep);
device_initialize(&card->card_dev);
card->card_dev.parent = parent;
@ -452,6 +453,35 @@ int snd_card_disconnect(struct snd_card *card)
}
EXPORT_SYMBOL(snd_card_disconnect);
/**
* snd_card_disconnect_sync - disconnect card and wait until files get closed
* @card: card object to disconnect
*
* This calls snd_card_disconnect() for disconnecting all belonging components
* and waits until all pending files get closed.
* It assures that all accesses from user-space finished so that the driver
* can release its resources gracefully.
*/
void snd_card_disconnect_sync(struct snd_card *card)
{
int err;
err = snd_card_disconnect(card);
if (err < 0) {
dev_err(card->dev,
"snd_card_disconnect error (%d), skipping sync\n",
err);
return;
}
spin_lock_irq(&card->files_lock);
wait_event_lock_irq(card->remove_sleep,
list_empty(&card->files_list),
card->files_lock);
spin_unlock_irq(&card->files_lock);
}
EXPORT_SYMBOL_GPL(snd_card_disconnect_sync);
static int snd_card_do_free(struct snd_card *card)
{
#if IS_ENABLED(CONFIG_SND_MIXER_OSS)
@ -957,6 +987,8 @@ int snd_card_file_remove(struct snd_card *card, struct file *file)
break;
}
}
if (list_empty(&card->files_list))
wake_up_all(&card->remove_sleep);
spin_unlock(&card->files_lock);
if (!found) {
dev_err(card->dev, "card file remove problem (%p)\n", file);

View file

@ -310,7 +310,7 @@ EXPORT_SYMBOL(snd_jack_set_parent);
* @type: Jack report type for this key
* @keytype: Input layer key type to be reported
*
* Map a SND_JACK_BTN_ button type to an input layer key, allowing
* Map a SND_JACK_BTN_* button type to an input layer key, allowing
* reporting of keys on accessories via the jack abstraction. If no
* mapping is provided but keys are enabled in the jack type then
* BTN_n numeric buttons will be reported.

View file

@ -775,6 +775,9 @@ static int _snd_pcm_new(struct snd_card *card, const char *id, int device,
.dev_register = snd_pcm_dev_register,
.dev_disconnect = snd_pcm_dev_disconnect,
};
static struct snd_device_ops internal_ops = {
.dev_free = snd_pcm_dev_free,
};
if (snd_BUG_ON(!card))
return -ENXIO;
@ -801,7 +804,8 @@ static int _snd_pcm_new(struct snd_card *card, const char *id, int device,
if (err < 0)
goto free_pcm;
err = snd_device_new(card, SNDRV_DEV_PCM, pcm, &ops);
err = snd_device_new(card, SNDRV_DEV_PCM, pcm,
internal ? &internal_ops : &ops);
if (err < 0)
goto free_pcm;
@ -1099,8 +1103,6 @@ static int snd_pcm_dev_register(struct snd_device *device)
if (snd_BUG_ON(!device || !device->device_data))
return -ENXIO;
pcm = device->device_data;
if (pcm->internal)
return 0;
mutex_lock(&register_mutex);
err = snd_pcm_add(pcm);
@ -1152,6 +1154,10 @@ static int snd_pcm_dev_disconnect(struct snd_device *device)
for (substream = pcm->streams[cidx].substream; substream; substream = substream->next) {
snd_pcm_stream_lock_irq(substream);
if (substream->runtime) {
if (snd_pcm_running(substream))
snd_pcm_stop(substream,
SNDRV_PCM_STATE_DISCONNECTED);
/* to be sure, set the state unconditionally */
substream->runtime->status->state = SNDRV_PCM_STATE_DISCONNECTED;
wake_up(&substream->runtime->sleep);
wake_up(&substream->runtime->tsleep);
@ -1159,12 +1165,10 @@ static int snd_pcm_dev_disconnect(struct snd_device *device)
snd_pcm_stream_unlock_irq(substream);
}
}
if (!pcm->internal) {
pcm_call_notify(pcm, n_disconnect);
}
pcm_call_notify(pcm, n_disconnect);
for (cidx = 0; cidx < 2; cidx++) {
if (!pcm->internal)
snd_unregister_device(&pcm->streams[cidx].dev);
snd_unregister_device(&pcm->streams[cidx].dev);
free_chmap(&pcm->streams[cidx]);
}
mutex_unlock(&pcm->open_mutex);

View file

@ -195,7 +195,6 @@ EXPORT_SYMBOL_GPL(snd_pcm_stream_unlock_irqrestore);
int snd_pcm_info(struct snd_pcm_substream *substream, struct snd_pcm_info *info)
{
struct snd_pcm_runtime *runtime;
struct snd_pcm *pcm = substream->pcm;
struct snd_pcm_str *pstr = substream->pstr;
@ -211,7 +210,6 @@ int snd_pcm_info(struct snd_pcm_substream *substream, struct snd_pcm_info *info)
info->subdevices_count = pstr->substream_count;
info->subdevices_avail = pstr->substream_count - pstr->substream_opened;
strlcpy(info->subname, substream->name, sizeof(info->subname));
runtime = substream->runtime;
return 0;
}

View file

@ -802,6 +802,10 @@ static int snd_seq_deliver_event(struct snd_seq_client *client, struct snd_seq_e
return -EMLINK;
}
if (snd_seq_ev_is_variable(event) &&
snd_BUG_ON(atomic && (event->data.ext.len & SNDRV_SEQ_EXT_USRPTR)))
return -EINVAL;
if (event->queue == SNDRV_SEQ_ADDRESS_SUBSCRIBERS ||
event->dest.client == SNDRV_SEQ_ADDRESS_SUBSCRIBERS)
result = deliver_to_subscribers(client, event, atomic, hop);

View file

@ -1069,15 +1069,17 @@ EXPORT_SYMBOL(snd_timer_global_register);
struct snd_timer_system_private {
struct timer_list tlist;
struct snd_timer *snd_timer;
unsigned long last_expires;
unsigned long last_jiffies;
unsigned long correction;
};
static void snd_timer_s_function(unsigned long data)
static void snd_timer_s_function(struct timer_list *t)
{
struct snd_timer *timer = (struct snd_timer *)data;
struct snd_timer_system_private *priv = timer->private_data;
struct snd_timer_system_private *priv = from_timer(priv, t,
tlist);
struct snd_timer *timer = priv->snd_timer;
unsigned long jiff = jiffies;
if (time_after(jiff, priv->last_expires))
priv->correction += (long)jiff - (long)priv->last_expires;
@ -1159,7 +1161,8 @@ static int snd_timer_register_system(void)
snd_timer_free(timer);
return -ENOMEM;
}
setup_timer(&priv->tlist, snd_timer_s_function, (unsigned long) timer);
priv->snd_timer = timer;
timer_setup(&priv->tlist, snd_timer_s_function, 0);
timer->private_data = priv;
timer->private_free = snd_timer_free_system;
return snd_timer_global_register(timer);

View file

@ -529,9 +529,9 @@ static unsigned int loopback_pos_update(struct loopback_cable *cable)
return running;
}
static void loopback_timer_function(unsigned long data)
static void loopback_timer_function(struct timer_list *t)
{
struct loopback_pcm *dpcm = (struct loopback_pcm *)data;
struct loopback_pcm *dpcm = from_timer(dpcm, t, timer);
unsigned long flags;
spin_lock_irqsave(&dpcm->cable->lock, flags);
@ -675,8 +675,7 @@ static int loopback_open(struct snd_pcm_substream *substream)
}
dpcm->loopback = loopback;
dpcm->substream = substream;
setup_timer(&dpcm->timer, loopback_timer_function,
(unsigned long)dpcm);
timer_setup(&dpcm->timer, loopback_timer_function, 0);
cable = loopback->cables[substream->number][dev];
if (!cable) {

View file

@ -306,9 +306,9 @@ static int dummy_systimer_prepare(struct snd_pcm_substream *substream)
return 0;
}
static void dummy_systimer_callback(unsigned long data)
static void dummy_systimer_callback(struct timer_list *t)
{
struct dummy_systimer_pcm *dpcm = (struct dummy_systimer_pcm *)data;
struct dummy_systimer_pcm *dpcm = from_timer(dpcm, t, timer);
unsigned long flags;
int elapsed = 0;
@ -343,8 +343,7 @@ static int dummy_systimer_create(struct snd_pcm_substream *substream)
if (!dpcm)
return -ENOMEM;
substream->runtime->private_data = dpcm;
setup_timer(&dpcm->timer, dummy_systimer_callback,
(unsigned long) dpcm);
timer_setup(&dpcm->timer, dummy_systimer_callback, 0);
spin_lock_init(&dpcm->lock);
dpcm->substream = substream;
return 0;

View file

@ -169,9 +169,9 @@ EXPORT_SYMBOL(snd_mpu401_uart_interrupt_tx);
* timer callback
* reprogram the timer and call the interrupt job
*/
static void snd_mpu401_uart_timer(unsigned long data)
static void snd_mpu401_uart_timer(struct timer_list *t)
{
struct snd_mpu401 *mpu = (struct snd_mpu401 *)data;
struct snd_mpu401 *mpu = from_timer(mpu, t, timer);
unsigned long flags;
spin_lock_irqsave(&mpu->timer_lock, flags);
@ -191,8 +191,7 @@ static void snd_mpu401_uart_add_timer (struct snd_mpu401 *mpu, int input)
spin_lock_irqsave (&mpu->timer_lock, flags);
if (mpu->timer_invoked == 0) {
setup_timer(&mpu->timer, snd_mpu401_uart_timer,
(unsigned long)mpu);
timer_setup(&mpu->timer, snd_mpu401_uart_timer, 0);
mod_timer(&mpu->timer, 1 + jiffies);
}
mpu->timer_invoked |= input ? MPU401_MODE_INPUT_TIMER :

View file

@ -406,10 +406,10 @@ static void snd_mtpav_input_trigger(struct snd_rawmidi_substream *substream, int
* timer interrupt for outputs
*/
static void snd_mtpav_output_timer(unsigned long data)
static void snd_mtpav_output_timer(struct timer_list *t)
{
unsigned long flags;
struct mtpav *chip = (struct mtpav *)data;
struct mtpav *chip = from_timer(chip, t, timer);
int p;
spin_lock_irqsave(&chip->spinlock, flags);
@ -707,8 +707,7 @@ static int snd_mtpav_probe(struct platform_device *dev)
mtp_card->share_irq = 0;
mtp_card->inmidistate = 0;
mtp_card->outmidihwport = 0xffffffff;
setup_timer(&mtp_card->timer, snd_mtpav_output_timer,
(unsigned long) mtp_card);
timer_setup(&mtp_card->timer, snd_mtpav_output_timer, 0);
card->private_free = snd_mtpav_free;

View file

@ -238,10 +238,10 @@ static int opl3_get_voice(struct snd_opl3 *opl3, int instr_4op,
/*
* System timer interrupt function
*/
void snd_opl3_timer_func(unsigned long data)
void snd_opl3_timer_func(struct timer_list *t)
{
struct snd_opl3 *opl3 = (struct snd_opl3 *)data;
struct snd_opl3 *opl3 = from_timer(opl3, t, tlist);
unsigned long flags;
int again = 0;
int i;

View file

@ -248,7 +248,7 @@ static int snd_opl3_seq_probe(struct device *_dev)
}
/* setup system timer */
setup_timer(&opl3->tlist, snd_opl3_timer_func, (unsigned long) opl3);
timer_setup(&opl3->tlist, snd_opl3_timer_func, 0);
spin_lock_init(&opl3->sys_timer_lock);
opl3->sys_timer_status = 0;

View file

@ -37,7 +37,7 @@ void snd_opl3_nrpn(void *p, struct snd_midi_channel *chan, struct snd_midi_chann
void snd_opl3_sysex(void *p, unsigned char *buf, int len, int parsed, struct snd_midi_channel_set *chset);
void snd_opl3_calc_volume(unsigned char *reg, int vel, struct snd_midi_channel *chan);
void snd_opl3_timer_func(unsigned long data);
void snd_opl3_timer_func(struct timer_list *t);
/* Prototypes for opl3_drums.c */
void snd_opl3_load_drums(struct snd_opl3 *opl3);

View file

@ -309,12 +309,12 @@ static irqreturn_t snd_uart16550_interrupt(int irq, void *dev_id)
}
/* When the polling mode, this function calls snd_uart16550_io_loop. */
static void snd_uart16550_buffer_timer(unsigned long data)
static void snd_uart16550_buffer_timer(struct timer_list *t)
{
unsigned long flags;
struct snd_uart16550 *uart;
uart = (struct snd_uart16550 *)data;
uart = from_timer(uart, t, buffer_timer);
spin_lock_irqsave(&uart->open_lock, flags);
snd_uart16550_del_timer(uart);
snd_uart16550_io_loop(uart);
@ -828,8 +828,7 @@ static int snd_uart16550_create(struct snd_card *card,
uart->prev_in = 0;
uart->rstatus = 0;
memset(uart->prev_status, 0x80, sizeof(unsigned char) * SNDRV_SERIAL_MAX_OUTS);
setup_timer(&uart->buffer_timer, snd_uart16550_buffer_timer,
(unsigned long)uart);
timer_setup(&uart->buffer_timer, snd_uart16550_buffer_timer, 0);
uart->timer_running = 0;
/* Register device */

View file

@ -319,7 +319,8 @@ int snd_hdac_bus_parse_capabilities(struct hdac_bus *bus)
break;
default:
dev_dbg(bus->dev, "Unknown capability %d\n", cur_cap);
dev_err(bus->dev, "Unknown capability %d\n", cur_cap);
cur_cap = 0;
break;
}

View file

@ -87,7 +87,7 @@ int snd_hdac_device_init(struct hdac_device *codec, struct hdac_bus *bus,
fg = codec->afg ? codec->afg : codec->mfg;
err = snd_hdac_refresh_widgets(codec);
err = snd_hdac_refresh_widgets(codec, false);
if (err < 0)
goto error;
@ -388,11 +388,12 @@ static void setup_fg_nodes(struct hdac_device *codec)
/**
* snd_hdac_refresh_widgets - Reset the widget start/end nodes
* @codec: the codec object
* @sysfs: re-initialize sysfs tree, too
*/
int snd_hdac_refresh_widgets(struct hdac_device *codec)
int snd_hdac_refresh_widgets(struct hdac_device *codec, bool sysfs)
{
hda_nid_t start_nid;
int nums;
int nums, err;
nums = snd_hdac_get_sub_nodes(codec, codec->afg, &start_nid);
if (!start_nid || nums <= 0 || nums >= 0xff) {
@ -401,6 +402,12 @@ int snd_hdac_refresh_widgets(struct hdac_device *codec)
return -EINVAL;
}
if (sysfs) {
err = hda_widget_sysfs_reinit(codec, start_nid, nums);
if (err < 0)
return err;
}
codec->num_nodes = nums;
codec->start_nid = start_nid;
codec->end_nid = start_nid + nums;
@ -408,36 +415,6 @@ int snd_hdac_refresh_widgets(struct hdac_device *codec)
}
EXPORT_SYMBOL_GPL(snd_hdac_refresh_widgets);
/**
* snd_hdac_refresh_widget_sysfs - Reset the codec widgets and reinit the
* codec sysfs
* @codec: the codec object
*
* first we need to remove sysfs, then refresh widgets and lastly
* recreate it
*/
int snd_hdac_refresh_widget_sysfs(struct hdac_device *codec)
{
int ret;
if (device_is_registered(&codec->dev))
hda_widget_sysfs_exit(codec);
ret = snd_hdac_refresh_widgets(codec);
if (ret) {
dev_err(&codec->dev, "failed to refresh widget: %d\n", ret);
return ret;
}
if (device_is_registered(&codec->dev)) {
ret = hda_widget_sysfs_init(codec);
if (ret) {
dev_err(&codec->dev, "failed to init sysfs: %d\n", ret);
return ret;
}
}
return ret;
}
EXPORT_SYMBOL_GPL(snd_hdac_refresh_widget_sysfs);
/* return CONNLIST_LEN parameter of the given widget */
static unsigned int get_num_conns(struct hdac_device *codec, hda_nid_t nid)
{

View file

@ -415,3 +415,50 @@ void hda_widget_sysfs_exit(struct hdac_device *codec)
{
widget_tree_free(codec);
}
int hda_widget_sysfs_reinit(struct hdac_device *codec,
hda_nid_t start_nid, int num_nodes)
{
struct hdac_widget_tree *tree;
hda_nid_t end_nid = start_nid + num_nodes;
hda_nid_t nid;
int i;
if (!codec->widgets)
return hda_widget_sysfs_init(codec);
tree = kmemdup(codec->widgets, sizeof(*tree), GFP_KERNEL);
if (!tree)
return -ENOMEM;
tree->nodes = kcalloc(num_nodes + 1, sizeof(*tree->nodes), GFP_KERNEL);
if (!tree->nodes) {
kfree(tree);
return -ENOMEM;
}
/* prune non-existing nodes */
for (i = 0, nid = codec->start_nid; i < codec->num_nodes; i++, nid++) {
if (nid < start_nid || nid >= end_nid)
free_widget_node(codec->widgets->nodes[i],
&widget_node_group);
}
/* add new nodes */
for (i = 0, nid = start_nid; i < num_nodes; i++, nid++) {
if (nid < codec->start_nid || nid >= codec->end_nid)
add_widget_node(tree->root, nid, &widget_node_group,
&tree->nodes[i]);
else
tree->nodes[i] =
codec->widgets->nodes[nid - codec->start_nid];
}
/* replace with the new tree */
kfree(codec->widgets->nodes);
kfree(codec->widgets);
codec->widgets = tree;
kobject_uevent(tree->root, KOBJ_CHANGE);
return 0;
}

View file

@ -29,6 +29,8 @@ static inline unsigned int get_wcaps_channels(u32 wcaps)
extern const struct attribute_group *hdac_dev_attr_groups[];
int hda_widget_sysfs_init(struct hdac_device *codec);
int hda_widget_sysfs_reinit(struct hdac_device *codec, hda_nid_t start_nid,
int num_nodes);
void hda_widget_sysfs_exit(struct hdac_device *codec);
#endif /* __HDAC_LOCAL_H */

View file

@ -35,7 +35,7 @@ MODULE_LICENSE("GPL");
#define AK4117_ADDR 0x00 /* fixed address */
static void snd_ak4117_timer(unsigned long data);
static void snd_ak4117_timer(struct timer_list *t);
static void reg_write(struct ak4117 *ak4117, unsigned char reg, unsigned char val)
{
@ -91,7 +91,7 @@ int snd_ak4117_create(struct snd_card *card, ak4117_read_t *read, ak4117_write_t
chip->read = read;
chip->write = write;
chip->private_data = private_data;
setup_timer(&chip->timer, snd_ak4117_timer, (unsigned long)chip);
timer_setup(&chip->timer, snd_ak4117_timer, 0);
for (reg = 0; reg < 5; reg++)
chip->regmap[reg] = pgm[reg];
@ -529,9 +529,9 @@ int snd_ak4117_check_rate_and_errors(struct ak4117 *ak4117, unsigned int flags)
return res;
}
static void snd_ak4117_timer(unsigned long data)
static void snd_ak4117_timer(struct timer_list *t)
{
struct ak4117 *chip = (struct ak4117 *)data;
struct ak4117 *chip = from_timer(chip, t, timer);
if (chip->init)
return;

View file

@ -193,9 +193,9 @@ static inline int emu8k_get_curpos(struct snd_emu8k_pcm *rec, int ch)
* timer interrupt handler
* check the current position and update the period if necessary.
*/
static void emu8k_pcm_timer_func(unsigned long data)
static void emu8k_pcm_timer_func(struct timer_list *t)
{
struct snd_emu8k_pcm *rec = (struct snd_emu8k_pcm *)data;
struct snd_emu8k_pcm *rec = from_timer(rec, t, timer);
int ptr, delta;
spin_lock(&rec->timer_lock);
@ -241,7 +241,7 @@ static int emu8k_pcm_open(struct snd_pcm_substream *subs)
runtime->private_data = rec;
spin_lock_init(&rec->timer_lock);
setup_timer(&rec->timer, emu8k_pcm_timer_func, (unsigned long)rec);
timer_setup(&rec->timer, emu8k_pcm_timer_func, 0);
runtime->hw = emu8k_pcm_hw;
runtime->hw.buffer_bytes_max = emu->mem_size - LOOP_BLANK_SIZE * 3;

View file

@ -138,6 +138,7 @@ static int snd_sb8dsp_midi_output_close(struct snd_rawmidi_substream *substream)
struct snd_sb *chip;
chip = substream->rmidi->private_data;
del_timer_sync(&chip->midi_timer);
spin_lock_irqsave(&chip->open_lock, flags);
chip->open &= ~(SB_OPEN_MIDI_OUTPUT | SB_OPEN_MIDI_OUTPUT_TRIGGER);
chip->midi_substream_output = NULL;
@ -209,10 +210,10 @@ static void snd_sb8dsp_midi_output_write(struct snd_rawmidi_substream *substream
}
}
static void snd_sb8dsp_midi_output_timer(unsigned long data)
static void snd_sb8dsp_midi_output_timer(struct timer_list *t)
{
struct snd_rawmidi_substream *substream = (struct snd_rawmidi_substream *) data;
struct snd_sb * chip = substream->rmidi->private_data;
struct snd_sb *chip = from_timer(chip, t, midi_timer);
struct snd_rawmidi_substream *substream = chip->midi_substream_output;
unsigned long flags;
spin_lock_irqsave(&chip->open_lock, flags);
@ -230,9 +231,6 @@ static void snd_sb8dsp_midi_output_trigger(struct snd_rawmidi_substream *substre
spin_lock_irqsave(&chip->open_lock, flags);
if (up) {
if (!(chip->open & SB_OPEN_MIDI_OUTPUT_TRIGGER)) {
setup_timer(&chip->midi_timer,
snd_sb8dsp_midi_output_timer,
(unsigned long) substream);
mod_timer(&chip->midi_timer, 1 + jiffies);
chip->open |= SB_OPEN_MIDI_OUTPUT_TRIGGER;
}
@ -275,6 +273,7 @@ int snd_sb8dsp_midi(struct snd_sb *chip, int device)
if (chip->hardware >= SB_HW_20)
rmidi->info_flags |= SNDRV_RAWMIDI_INFO_DUPLEX;
rmidi->private_data = chip;
timer_setup(&chip->midi_timer, snd_sb8dsp_midi_output_timer, 0);
chip->rmidi = rmidi;
return 0;
}

View file

@ -349,10 +349,10 @@ static void snd_wavefront_midi_input_trigger(struct snd_rawmidi_substream *subst
spin_unlock_irqrestore (&midi->virtual, flags);
}
static void snd_wavefront_midi_output_timer(unsigned long data)
static void snd_wavefront_midi_output_timer(struct timer_list *t)
{
snd_wavefront_card_t *card = (snd_wavefront_card_t *)data;
snd_wavefront_midi_t *midi = &card->wavefront.midi;
snd_wavefront_midi_t *midi = from_timer(midi, t, timer);
snd_wavefront_card_t *card = midi->timer_card;
unsigned long flags;
spin_lock_irqsave (&midi->virtual, flags);
@ -383,9 +383,9 @@ static void snd_wavefront_midi_output_trigger(struct snd_rawmidi_substream *subs
if (up) {
if ((midi->mode[mpu] & MPU401_MODE_OUTPUT_TRIGGER) == 0) {
if (!midi->istimer) {
setup_timer(&midi->timer,
timer_setup(&midi->timer,
snd_wavefront_midi_output_timer,
(unsigned long) substream->rmidi->card->private_data);
0);
mod_timer(&midi->timer, 1 + jiffies);
}
midi->istimer++;

View file

@ -1,369 +0,0 @@
Note these changes relate to Hannu's code and don't include the changes
made outside of this for modularising the sound
Changelog for version 3.8o
--------------------------
Since 3.8h
- Included support for OPL3-SA1 and SoftOSS
Since 3.8
- Fixed SNDCTL_DSP_GETOSPACE
- Compatibility fixes for Linux 2.1.47
Since 3.8-beta21
- Fixed all known bugs (I think).
Since 3.8-beta8
- Lot of fixes to audio playback code in dmabuf.c
Since 3.8-beta6
- Fixed the famous Quake delay bug.
Since 3.8-beta5
- Fixed many bugs in audio playback.
Since 3.8-beta4
- Just minor changes.
Since 3.8-beta1
- Major rewrite of audio playback handling.
- Added AWE32 support by Takashi Iwai (in ./lowlevel/).
Since 3.7-beta#
- Passing of ioctl() parameters between soundcard.c and other modules has been
changed so that arg always points to kernel space.
- Some bugfixes.
Since 3.7-beta5
- Disabled MIDI input with GUS PnP (Interwave). There seems to be constant
stream of received 0x00 bytes when the MIDI receiver is enabled.
Since 3.5
- Changes almost everywhere.
- Support for OPTi 82C924-based sound cards.
Since 3.5.4-beta8
- Fixed a bug in handling of non-fragment sized writes in 16 bit/stereo mode
with GUS.
- Limited minimum fragment size with some audio devices (GUS=512 and
SB=32). These devices require more time to "recover" from processing
of each fragment.
Since 3.5.4-beta6/7
- There seems to be problems in the OPTi 82C930 so cards based on this
chip don't necessarily work yet. There are problems in detecting the
MIDI interface. Also mixer volumes may be seriously wrong on some systems.
You can safely use this driver version with C930 if it looks to work.
However please don't complain if you have problems with it. C930 support
should be fixed in future releases.
- Got initialization of GUS PnP to work. With this version GUS PnP should
work in GUS compatible mode after initialization using isapnptools.
- Fixed a bug in handling of full duplex cards in write only mode. This has
been causing "audio device opening" errors with RealAudio player.
Since 3.5.4.beta5
- Changes to OPTi 82C930 driver.
- Major changes to the Soundscape driver. The driver requires now just one
DMA channel. The extra audio/dsp device (the "Not functional" one) used
for code download in the earlier versions has been eliminated. There is now
just one /dev/dsp# device which is used both for code download and audio.
Since 3.5.4.beta4
- Minor changes.
Since 3.5.4-beta2
- Fixed silent playback with ESS 688/1688.
- Got SB16 to work without the 16 bit DMA channel (only the 8 bit one
is required for 8 and 16 bit modes).
- Added the "lowlevel" subdirectory for additional low level drivers that
are not part of USS core. See lowlevel/README for more info.
- Included support for ACI mixer (by Markus Kuhn). ACI is a mixer used in
miroPCM sound cards. See lowlevel/aci.readme for more info.
- Support for Aztech Washington chipset (AZT2316 ASIC).
Since 3.5.4-beta1
- Reduced clicking with AD1848.
- Support for OPTi 82C930. Only half duplex at this time. 16 bit playback
is sometimes just white noise (occurs randomly).
Since 3.5.2
- Major changes to the SB/Jazz16/ESS driver (most parts rewritten).
The most noticeable new feature is support for multiple SB cards at the same
time.
- Renamed sb16_midi.c to uart401.c. Also modified it to work also with
other MPU401 UART compatible cards than SB16/ESS/Jazz.
- Some changes which reduce clicking in audio playback.
- Copying policy is now GPL.
Since 3.5.1
- TB Maui initialization support
Since 3.5
- Improved handling of playback underrun situations.
Since 3.5-beta10
- Bug fixing
Since 3.5-beta9
- Fixed for compatibility with Linux 1.3.70 and later.
- Changed boot time passing of 16 bit DMA channel number to SB driver.
Since 3.5-beta8
- Minor changes
Since 3.5-beta7
- enhancements to configure program (by Jeff Tranter):
- prompts are in same format as 1.3.x Linux kernel config program
- on-line help for each question
- fixed some compile warnings detected by gcc/g++ -Wall
- minor grammatical changes to prompts
Since 3.5-beta6
- Fixed bugs in mmap() support.
- Minor changes to Maui driver.
Since 3.5-beta5
- Fixed crash after recording with ESS688. It's generally a good
idea to stop inbound DMA transfers before freeing the memory
buffer.
- Fixed handling of AD1845 codec (for example Shuttle Sound System).
- Few other fixes.
Since 3.5-beta4
- Fixed bug in handling of uninitialized instruments with GUS.
Since 3.5-beta3
- Few changes which decrease popping at end/beginning of audio playback.
Since 3.5-beta2
- Removed MAD16+CS4231 hack made in previous version since it didn't
help.
- Fixed the above bug in proper way and in proper place. Many thanks
to James Hightower.
Since 3.5-beta1
- Bug fixes.
- Full duplex audio with MAD16+CS4231 may work now. The driver configures
SB DMA of MAD16 so that it doesn't conflict with codec's DMA channels.
The side effect is that all 8 bit DMA channels (0,1,3) are populated in
duplex mode.
Since 3.5-alpha9
- Bug fixes (mostly in Jazz16 and ESS1688/688 supports).
- Temporarily disabled recording with ESS1688/688 since it causes crash.
- Changed audio buffer partitioning algorithm so that it selects
smaller fragment size than earlier. This improves real time capabilities
of the driver and makes recording to disk to work better. Unfortunately
this change breaks some programs which assume that fragments cannot be
shorter than 4096 bytes.
Since 3.5-alpha8
- Bug fixes
Since 3.5-alpha7
- Linux kernel compatible configuration (_EXPERIMENTAL_). Enable
using command "cd /linux/drivers/sound;make script" and then
just run kernel's make config normally.
- Minor fixes to the SB support. Hopefully the driver works with
all SB models now.
- Added support for ESS ES1688 "AudioDrive" based cards.
Since 3.5-alpha6
- SB Pro and SB16 supports are no longer separately selectable options.
Enabling SB enables them too.
- Changed all #ifndef EXCLUDE_xx stuff to #ifdef CONFIG_xx. Modified
configure to handle this.
- Removed initialization messages from the
modularized version. They can be enabled by using init_trace=1 in
the insmod command line (insmod sound init_trace=1).
- More AIX stuff.
- Added support for synchronizing dsp/audio devices with /dev/sequencer.
- mmap() support for dsp/audio devices.
Since 3.5-alpha5
- AIX port.
- Changed some xxx_PATCH macros in soundcard.h to work with
big endian machines.
Since 3.5-alpha4
- Removed the 'setfx' stuff from the version distributed with kernel
sources. Running 'setfx' is required again.
Since 3.5-alpha3
- Moved stuff from the 'setfx' program to the AudioTrix Pro driver.
Since 3.5-alpha2
- Modifications to makefile and configure.c. Unnecessary sources
are no longer compiled. Newly created local.h is also copied to
/etc/soundconf. "make oldconfig" reads /etc/soundconf and produces
new local.h which is compatible with current version of the driver.
- Some fixes to the SB16 support.
- Fixed random protection fault in gus_wave.c
Since 3.5-alpha1
- Modified to work with Linux-1.3.33 and later
- Some minor changes
Since 3.0.2
- Support for CS4232 based PnP cards (AcerMagic S23 etc).
- Full duplex support for some CS4231, CS4232 and AD1845 based cards
(GUS MAX, AudioTrix Pro, AcerMagic S23 and many MAD16/Mozart cards
having a codec mentioned above).
- Almost fully rewritten loadable modules support.
- Fixed some bugs.
- Huge amount of testing (more testing is still required).
- mmap() support (works with some cards). Requires much more testing.
- Sample/patch/program loading for TB Maui/Tropez. No initialization
since TB doesn't allow me to release that code.
- Using CS4231 compatible codecs as timer for /dev/music.
Since 3.0.1
- Added allocation of I/O ports, DMA channels and interrupts
to the initialization code. This may break modules support since
the driver may not free some resources on unload. Should be fixed soon.
Since 3.0
- Some important bug fixes.
- select() for /dev/dsp and /dev/audio (Linux only).
(To use select() with read, you have to call read() to start
the recording. Calling write() kills recording immediately so
use select() carefully when you are writing a half duplex app.
Full duplex mode is not implemented yet.) Select works also with
/dev/sequencer and /dev/music. Maybe with /dev/midi## too.
Since 3.0-beta2
- Minor fixes.
- Added Readme.cards
Since 3.0-beta1
- Minor fixes to the modules support.
- Eliminated call to sb_free_irq() in ad1848.c
- Rewritten MAD16&Mozart support (not tested with MAD16 Pro).
- Fix to DMA initialization of PSS cards.
- Some fixes to ad1848/cs42xx mixer support (GUS MAX, MSS, etc.)
- Fixed some bugs in the PSS driver which caused I/O errors with
the MSS mode (/dev/dsp).
Since 3.0-950506
- Recording with GUS MAX fixed. It works when the driver is configured
to use two DMA channels with GUS MAX (16 bit ones recommended).
Since 3.0-94xxxx
- Too many changes
Since 3.0-940818
- Fixes for Linux 1.1.4x.
- Disables Disney Sound System with SG NX Pro 16 (less noise).
Since 2.90-2
- Fixes to soundcard.h
- Non blocking mode to /dev/sequencer
- Experimental detection code for Ensoniq Soundscape.
Since 2.90
- Minor and major bug fixes
Since pre-3.0-940712
- GUS MAX support
- Partially working MSS/WSS support (could work with some cards).
- Hardware u-Law and A-Law support with AD1848/CS4248 and CS4231 codecs
(GUS MAX, GUS16, WSS etc). Hardware ADPCM is possible with GUS16 and
GUS MAX, but it doesn't work yet.
Since pre-3.0-940426
- AD1848/CS4248/CS4231 codec support (MSS, GUS MAX, Aztec, Orchid etc).
This codec chip is used in various sound cards. This version is developed
for the 16 bit daughtercard of GUS. It should work with other cards also
if the following requirements are met:
- The I/O, IRQ and DMA settings are jumper selectable or
the card is initialized by booting DOS before booting Linux (etc.).
- You add the IO, IRQ and DMA settings manually to the local.h.
(Just define GUS16_BASE, GUS16_IRQ and GUS16_DMA). Note that
the base address bust be the base address of the codec chip not the
card itself. For the GUS16 these are the same but most MSS compatible
cards have the codec located at card_base+4.
- Some minor changes
Since 2.5 (******* MAJOR REWRITE ***********)
This version is based on v2.3. I have tried to maintain two versions
together so that this one should have the same features than v2.5.
Something may still be missing. If you notice such things, please let me
know.
The Readme.v30 contains more details.
- /dev/midi## devices.
- /dev/sequencer2
Since 2.5-beta2
- Some fine tuning to the GUS v3.7 mixer code.
- Fixed speed limits for the plain SB (1.0 to 2.0).
Since 2.5-beta
- Fixed OPL-3 detection with SB. Caused problems with PAS16.
- GUS v3.7 mixer support.
Since 2.4
- Mixer support for Sound Galaxy NX Pro (define __SGNXPRO__ on your local.h).
- Fixed truncated sound on /dev/dsp when the device is closed.
- Linear volume mode for GUS
- Pitch bends larger than +/- 2 octaves.
- MIDI recording for SB and SB Pro. (Untested).
- Some other fixes.
- SB16 MIDI and DSP drivers only initialized if SB16 actually installed.
- Implemented better detection for OPL-3. This should be useful if you
have an old SB Pro (the non-OPL-3 one) or a SB 2.0 clone which has a OPL-3.
- SVR4.2 support by Ian Hartas. Initial ALPHA TEST version (untested).
Since 2.3b
- Fixed bug which made it impossible to make long recordings to disk.
Recording was not restarted after a buffer overflow situation.
- Limited mixer support for GUS.
- Numerous improvements to the GUS driver by Andrew Robinson. Including
some click removal etc.
Since 2.3
- Fixed some minor bugs in the SB16 driver.
Since 2.2b
- Full SB16 DSP support. 8/16 bit, mono/stereo
- The SCO and FreeBSD versions should be in sync now. There are some
problems with SB16 and GUS in the FreeBSD versions.
The DMA buffer allocation of the SCO version has been polished but
there could still be some problems. At least it hogs memory.
The DMA channel
configuration method used in the SCO/System is a hack.
- Support for the MPU emulation of the SB16.
- Some big arrays are now allocated boot time. This makes the BSS segment
smaller which makes it possible to use the full driver with
NetBSD. These arrays are not allocated if no suitable sound card is available.
- Fixed a bug in the compute_and_set_volume in gus_wave.c
- Fixed the too fast mono playback problem of SB Pro and PAS16.
Since 2.2
- Stereo recording for SB Pro. Somehow it was missing and nobody
had noticed it earlier.
- Minor polishing.
- Interpreting of boot time arguments (sound=) for Linux.
- Breakup of sb_dsp.c. Parts of the code has been moved to
sb_mixer.c and sb_midi.c
Since 2.1
- Preliminary support for SB16.
- The SB16 mixer is supported in its native mode.
- Digitized voice capability up to 44.1 kHz/8 bit/mono
(16 bit and stereo support coming in the next release).
- Fixed some bugs in the digitized voice driver for PAS16.
- Proper initialization of the SB emulation of latest PAS16 models.
- Significantly improved /dev/dsp and /dev/audio support.
- Now supports half duplex mode. It's now possible to record and
playback without closing and reopening the device.
- It's possible to use smaller buffers than earlier. There is a new
ioctl(fd, SNDCTL_DSP_SUBDIVIDE, &n) where n should be 1, 2 or 4.
This call instructs the driver to use smaller buffers. The default
buffer size (0.5 to 1.0 seconds) is divided by n. Should be called
immediately after opening the device.
Since 2.0
Just cosmetic changes.

View file

@ -1,533 +0,0 @@
# 18 Apr 1998, Michael Elizabeth Chastain, <mailto:mec@shout.net>
# More hacking for modularisation.
#
# Prompt user for primary drivers.
config SOUND_BCM_CS4297A
tristate "Crystal Sound CS4297a (for Swarm)"
depends on SIBYTE_SWARM
help
The BCM91250A has a Crystal CS4297a on synchronous serial
port B (in addition to the DB-9 serial port). Say Y or M
here to enable the sound chip instead of the UART. Also
note that CONFIG_KGDB should not be enabled at the same
time, since it also attempts to use this UART port.
config SOUND_MSNDCLAS
tristate "Support for Turtle Beach MultiSound Classic, Tahiti, Monterey"
depends on (m || !STANDALONE) && ISA
help
Say M here if you have a Turtle Beach MultiSound Classic, Tahiti or
Monterey (not for the Pinnacle or Fiji).
See <file:Documentation/sound/oss/MultiSound> for important information
about this driver. Note that it has been discontinued, but the
Voyetra Turtle Beach knowledge base entry for it is still available
at <http://www.turtlebeach.com/site/kb_ftp/790.asp>.
comment "Compiled-in MSND Classic support requires firmware during compilation."
depends on SOUND_PRIME && SOUND_MSNDCLAS=y
config MSNDCLAS_HAVE_BOOT
bool
depends on SOUND_MSNDCLAS=y && !STANDALONE
default y
config MSNDCLAS_INIT_FILE
string "Full pathname of MSNDINIT.BIN firmware file"
depends on SOUND_MSNDCLAS
default "/etc/sound/msndinit.bin"
help
The MultiSound cards have two firmware files which are required for
operation, and are not currently included. These files can be
obtained from Turtle Beach. See
<file:Documentation/sound/oss/MultiSound> for information on how to
obtain this.
config MSNDCLAS_PERM_FILE
string "Full pathname of MSNDPERM.BIN firmware file"
depends on SOUND_MSNDCLAS
default "/etc/sound/msndperm.bin"
help
The MultiSound cards have two firmware files which are required for
operation, and are not currently included. These files can be
obtained from Turtle Beach. See
<file:Documentation/sound/oss/MultiSound> for information on how to
obtain this.
config MSNDCLAS_IRQ
int "MSND Classic IRQ 5, 7, 9, 10, 11, 12"
depends on SOUND_MSNDCLAS=y
default "5"
help
Interrupt Request line for the MultiSound Classic and related cards.
config MSNDCLAS_MEM
hex "MSND Classic memory B0000, C8000, D0000, D8000, E0000, E8000"
depends on SOUND_MSNDCLAS=y
default "D0000"
help
Memory-mapped I/O base address for the MultiSound Classic and
related cards.
config MSNDCLAS_IO
hex "MSND Classic I/O 210, 220, 230, 240, 250, 260, 290, 3E0"
depends on SOUND_MSNDCLAS=y
default "290"
help
I/O port address for the MultiSound Classic and related cards.
config SOUND_MSNDPIN
tristate "Support for Turtle Beach MultiSound Pinnacle, Fiji"
depends on (m || !STANDALONE) && ISA
help
Say M here if you have a Turtle Beach MultiSound Pinnacle or Fiji.
See <file:Documentation/sound/oss/MultiSound> for important information
about this driver. Note that it has been discontinued, but the
Voyetra Turtle Beach knowledge base entry for it is still available
at <http://www.turtlebeach.com/site/kb_ftp/600.asp>.
comment "Compiled-in MSND Pinnacle support requires firmware during compilation."
depends on SOUND_PRIME && SOUND_MSNDPIN=y
config MSNDPIN_HAVE_BOOT
bool
depends on SOUND_MSNDPIN=y
default y
config MSNDPIN_INIT_FILE
string "Full pathname of PNDSPINI.BIN firmware file"
depends on SOUND_MSNDPIN
default "/etc/sound/pndspini.bin"
help
The MultiSound cards have two firmware files which are required
for operation, and are not currently included. These files can be
obtained from Turtle Beach. See
<file:Documentation/sound/oss/MultiSound> for information on how to
obtain this.
config MSNDPIN_PERM_FILE
string "Full pathname of PNDSPERM.BIN firmware file"
depends on SOUND_MSNDPIN
default "/etc/sound/pndsperm.bin"
help
The MultiSound cards have two firmware files which are required for
operation, and are not currently included. These files can be
obtained from Turtle Beach. See
<file:Documentation/sound/oss/MultiSound> for information on how to
obtain this.
config MSNDPIN_IRQ
int "MSND Pinnacle IRQ 5, 7, 9, 10, 11, 12"
depends on SOUND_MSNDPIN=y
default "5"
help
Interrupt request line for the primary synthesizer on MultiSound
Pinnacle and Fiji sound cards.
config MSNDPIN_MEM
hex "MSND Pinnacle memory B0000, C8000, D0000, D8000, E0000, E8000"
depends on SOUND_MSNDPIN=y
default "D0000"
help
Memory-mapped I/O base address for the primary synthesizer on
MultiSound Pinnacle and Fiji sound cards.
config MSNDPIN_IO
hex "MSND Pinnacle I/O 210, 220, 230, 240, 250, 260, 290, 3E0"
depends on SOUND_MSNDPIN=y
default "290"
help
Memory-mapped I/O base address for the primary synthesizer on
MultiSound Pinnacle and Fiji sound cards.
config MSNDPIN_DIGITAL
bool "MSND Pinnacle has S/PDIF I/O"
depends on SOUND_MSNDPIN=y
help
If you have the S/PDIF daughter board for the Pinnacle or Fiji,
answer Y here; otherwise, say N. If you have this, you will be able
to play and record from the S/PDIF port (digital signal). See
<file:Documentation/sound/oss/MultiSound> for information on how to make
use of this capability.
config MSNDPIN_NONPNP
bool "MSND Pinnacle non-PnP Mode"
depends on SOUND_MSNDPIN=y
help
The Pinnacle and Fiji card resources can be configured either with
PnP, or through a configuration port. Say Y here if your card is NOT
in PnP mode. For the Pinnacle, configuration in non-PnP mode allows
use of the IDE and joystick peripherals on the card as well; these
do not show up when the card is in PnP mode. Specifying zero for any
resource of a device will disable the device. If you are running the
card in PnP mode, you must say N here and use isapnptools to
configure the card's resources.
comment "MSND Pinnacle DSP section will be configured to above parameters."
depends on SOUND_MSNDPIN=y && MSNDPIN_NONPNP
config MSNDPIN_CFG
hex "MSND Pinnacle config port 250,260,270"
depends on MSNDPIN_NONPNP
default "250"
help
This is the port which the Pinnacle and Fiji uses to configure the
card's resources when not in PnP mode. If your card is in PnP mode,
then be sure to say N to the previous option, "MSND Pinnacle Non-PnP
Mode".
comment "Pinnacle-specific Device Configuration (0 disables)"
depends on SOUND_MSNDPIN=y && MSNDPIN_NONPNP
config MSNDPIN_MPU_IO
hex "MSND Pinnacle MPU I/O (e.g. 330)"
depends on MSNDPIN_NONPNP
default "0"
help
Memory-mapped I/O base address for the Kurzweil daughterboard
synthesizer on MultiSound Pinnacle and Fiji sound cards.
config MSNDPIN_MPU_IRQ
int "MSND Pinnacle MPU IRQ (e.g. 9)"
depends on MSNDPIN_NONPNP
default "0"
help
Interrupt request number for the Kurzweil daughterboard
synthesizer on MultiSound Pinnacle and Fiji sound cards.
config MSNDPIN_IDE_IO0
hex "MSND Pinnacle IDE I/O 0 (e.g. 170)"
depends on MSNDPIN_NONPNP
default "0"
help
CD-ROM drive 0 memory-mapped I/O base address for the MultiSound
Pinnacle and Fiji sound cards.
config MSNDPIN_IDE_IO1
hex "MSND Pinnacle IDE I/O 1 (e.g. 376)"
depends on MSNDPIN_NONPNP
default "0"
help
CD-ROM drive 1 memory-mapped I/O base address for the MultiSound
Pinnacle and Fiji sound cards.
config MSNDPIN_IDE_IRQ
int "MSND Pinnacle IDE IRQ (e.g. 15)"
depends on MSNDPIN_NONPNP
default "0"
help
Interrupt request number for the IDE CD-ROM interface on the
MultiSound Pinnacle and Fiji sound cards.
config MSNDPIN_JOYSTICK_IO
hex "MSND Pinnacle joystick I/O (e.g. 200)"
depends on MSNDPIN_NONPNP
default "0"
help
Memory-mapped I/O base address for the joystick port on MultiSound
Pinnacle and Fiji sound cards.
config MSND_FIFOSIZE
int "MSND buffer size (kB)"
depends on SOUND_MSNDPIN=y || SOUND_MSNDCLAS=y
default "128"
help
Configures the size of each audio buffer, in kilobytes, for
recording and playing in the MultiSound drivers (both the Classic
and Pinnacle). Larger values reduce the chance of data overruns at
the expense of overall latency. If unsure, use the default.
menuconfig SOUND_OSS
tristate "OSS sound modules"
depends on ISA_DMA_API && (VIRT_TO_BUS || ARCH_RPC || ARCH_NETWINDER)
depends on !GENERIC_ISA_DMA_SUPPORT_BROKEN
help
OSS is the Open Sound System suite of sound card drivers. They make
sound programming easier since they provide a common API. Say Y or
M here (the module will be called sound) if you haven't found a
driver for your sound card above, then pick your driver from the
list below.
if SOUND_OSS
config SOUND_TRACEINIT
bool "Verbose initialisation"
help
Verbose soundcard initialization -- affects the format of autoprobe
and initialization messages at boot time.
config SOUND_DMAP
bool "Persistent DMA buffers"
---help---
Linux can often have problems allocating DMA buffers for ISA sound
cards on machines with more than 16MB of RAM. This is because ISA
DMA buffers must exist below the 16MB boundary and it is quite
possible that a large enough free block in this region cannot be
found after the machine has been running for a while. If you say Y
here the DMA buffers (64Kb) will be allocated at boot time and kept
until the shutdown. This option is only useful if you said Y to
"OSS sound modules", above. If you said M to "OSS sound modules"
then you can get the persistent DMA buffer functionality by passing
the command-line argument "dmabuf=1" to the sound module.
Say Y unless you have 16MB or more RAM or a PCI sound card.
config SOUND_VMIDI
tristate "Loopback MIDI device support"
help
Support for MIDI loopback on port 1 or 2.
config SOUND_TRIX
tristate "MediaTrix AudioTrix Pro support"
help
Answer Y if you have the AudioTriX Pro sound card manufactured
by MediaTrix.
config TRIX_HAVE_BOOT
bool "Have TRXPRO.HEX firmware file"
depends on SOUND_TRIX=y && !STANDALONE
help
The MediaTrix AudioTrix Pro has an on-board microcontroller which
needs to be initialized by downloading the code from the file
TRXPRO.HEX in the DOS driver directory. If you don't have the
TRXPRO.HEX file handy you may skip this step. However, the SB and
MPU-401 modes of AudioTrix Pro will not work without this file!
config TRIX_BOOT_FILE
string "Full pathname of TRXPRO.HEX firmware file"
depends on TRIX_HAVE_BOOT
default "/etc/sound/trxpro.hex"
help
Enter the full pathname of your TRXPRO.HEX file, starting from /.
config SOUND_MSS
tristate "Microsoft Sound System support"
---help---
Again think carefully before answering Y to this question. It's
safe to answer Y if you have the original Windows Sound System card
made by Microsoft or Aztech SG 16 Pro (or NX16 Pro). Also you may
say Y in case your card is NOT among these:
ATI Stereo F/X, AdLib, Audio Excell DSP16, Cardinal DSP16,
Ensoniq SoundScape (and compatibles made by Reveal and Spea),
Gravis Ultrasound, Gravis Ultrasound ACE, Gravis Ultrasound Max,
Gravis Ultrasound with 16 bit option, Logitech Sound Man 16,
Logitech SoundMan Games, Logitech SoundMan Wave, MAD16 Pro (OPTi
82C929), Media Vision Jazz16, MediaTriX AudioTriX Pro, Microsoft
Windows Sound System (MSS/WSS), Mozart (OAK OTI-601), Orchid
SW32, Personal Sound System (PSS), Pro Audio Spectrum 16, Pro
Audio Studio 16, Pro Sonic 16, Roland MPU-401 MIDI interface,
Sound Blaster 1.0, Sound Blaster 16, Sound Blaster 16ASP, Sound
Blaster 2.0, Sound Blaster AWE32, Sound Blaster Pro, TI TM4000M
notebook, ThunderBoard, Turtle Beach Tropez, Yamaha FM
synthesizers (OPL2, OPL3 and OPL4), 6850 UART MIDI Interface.
For cards having native support in VoxWare, consult the card
specific instructions in <file:Documentation/sound/oss/README.OSS>.
Some drivers have their own MSS support and saying Y to this option
will cause a conflict.
If you compile the driver into the kernel, you have to add
"ad1848=<io>,<irq>,<dma>,<dma2>[,<type>]" to the kernel command
line.
config SOUND_MPU401
tristate "MPU-401 support (NOT for SB16)"
---help---
Be careful with this question. The MPU401 interface is supported by
all sound cards. However, some natively supported cards have their
own driver for MPU401. Enabling this MPU401 option with these cards
will cause a conflict. Also, enabling MPU401 on a system that
doesn't really have a MPU401 could cause some trouble. If your card
was in the list of supported cards, look at the card specific
instructions in the <file:Documentation/sound/oss/README.OSS> file. It
is safe to answer Y if you have a true MPU401 MIDI interface card.
If you compile the driver into the kernel, you have to add
"mpu401=<io>,<irq>" to the kernel command line.
config SOUND_PAS
tristate "ProAudioSpectrum 16 support"
---help---
Answer Y only if you have a Pro Audio Spectrum 16, ProAudio Studio
16 or Logitech SoundMan 16 sound card. Answer N if you have some
other card made by Media Vision or Logitech since those are not
PAS16 compatible. Please read <file:Documentation/sound/oss/PAS16>.
It is not necessary to add Sound Blaster support separately; it
is included in PAS support.
If you compile the driver into the kernel, you have to add
"pas2=<io>,<irq>,<dma>,<dma2>,<sbio>,<sbirq>,<sbdma>,<sbdma2>
to the kernel command line.
config PAS_JOYSTICK
bool "Enable PAS16 joystick port"
depends on SOUND_PAS=y
help
Say Y here to enable the Pro Audio Spectrum 16's auxiliary joystick
port.
config SOUND_PSS
tristate "PSS (AD1848, ADSP-2115, ESC614) support"
help
Answer Y or M if you have an Orchid SW32, Cardinal DSP16, Beethoven
ADSP-16 or some other card based on the PSS chipset (AD1848 codec +
ADSP-2115 DSP chip + Echo ESC614 ASIC CHIP). For more information on
how to compile it into the kernel or as a module see the file
<file:Documentation/sound/oss/PSS>.
If you compile the driver into the kernel, you have to add
"pss=<io>,<mssio>,<mssirq>,<mssdma>,<mpuio>,<mpuirq>" to the kernel
command line.
config PSS_MIXER
bool "Enable PSS mixer (Beethoven ADSP-16 and other compatible)"
depends on SOUND_PSS
help
Answer Y for Beethoven ADSP-16. You may try to say Y also for other
cards if they have master volume, bass, treble, and you can't
control it under Linux. If you answer N for Beethoven ADSP-16, you
can't control master volume, bass, treble and synth volume.
If you said M to "PSS support" above, you may enable or disable this
PSS mixer with the module parameter pss_mixer. For more information
see the file <file:Documentation/sound/oss/PSS>.
config PSS_HAVE_BOOT
bool "Have DSPxxx.LD firmware file"
depends on SOUND_PSS && !STANDALONE
help
If you have the DSPxxx.LD file or SYNTH.LD file for you card, say Y
to include this file. Without this file the synth device (OPL) may
not work.
config PSS_BOOT_FILE
string "Full pathname of DSPxxx.LD firmware file"
depends on PSS_HAVE_BOOT
default "/etc/sound/dsp001.ld"
help
Enter the full pathname of your DSPxxx.LD file or SYNTH.LD file,
starting from /.
config SOUND_SB
tristate "100% Sound Blaster compatibles (SB16/32/64, ESS, Jazz16) support"
---help---
Answer Y if you have an original Sound Blaster card made by Creative
Labs or a 100% hardware compatible clone (like the Thunderboard or
SM Games). For an unknown card you may answer Y if the card claims
to be Sound Blaster-compatible.
Please read the file <file:Documentation/sound/oss/Soundblaster>.
You should also say Y here for cards based on the Avance Logic
ALS-007 and ALS-1X0 chips (read <file:Documentation/sound/oss/ALS>) and
for cards based on ESS chips (read
<file:Documentation/sound/oss/ESS1868> and
<file:Documentation/sound/oss/ESS>). If you have an IBM Mwave
card, say Y here and read <file:Documentation/sound/oss/mwave>.
If you compile the driver into the kernel and don't want to use
isapnp, you have to add "sb=<io>,<irq>,<dma>,<dma2>" to the kernel
command line.
You can say M here to compile this driver as a module; the module is
called sb.
config SOUND_YM3812
tristate "Yamaha FM synthesizer (YM3812/OPL-3) support"
---help---
Answer Y if your card has a FM chip made by Yamaha (OPL2/OPL3/OPL4).
Answering Y is usually a safe and recommended choice, however some
cards may have software (TSR) FM emulation. Enabling FM support with
these cards may cause trouble (I don't currently know of any such
cards, however). Please read the file
<file:Documentation/sound/oss/OPL3> if your card has an OPL3 chip.
If you compile the driver into the kernel, you have to add
"opl3=<io>" to the kernel command line.
If unsure, say Y.
config SOUND_UART6850
tristate "6850 UART support"
help
This option enables support for MIDI interfaces based on the 6850
UART chip. This interface is rarely found on sound cards. It's safe
to answer N to this question.
If you compile the driver into the kernel, you have to add
"uart6850=<io>,<irq>" to the kernel command line.
config SOUND_AEDSP16
tristate "Gallant Audio Cards (SC-6000 and SC-6600 based)"
---help---
Answer Y if you have a Gallant's Audio Excel DSP 16 card. This
driver supports Audio Excel DSP 16 but not the III nor PnP versions
of this card.
The Gallant's Audio Excel DSP 16 card can emulate either an SBPro or
a Microsoft Sound System card, so you should have said Y to either
"100% Sound Blaster compatibles (SB16/32/64, ESS, Jazz16) support"
or "Microsoft Sound System support", above, and you need to answer
the "MSS emulation" and "SBPro emulation" questions below
accordingly. You should say Y to one and only one of these two
questions.
Read the <file:Documentation/sound/oss/README.OSS> file and the head of
<file:sound/oss/aedsp16.c> as well as
<file:Documentation/sound/oss/AudioExcelDSP16> to get more information
about this driver and its configuration.
config SC6600
bool "SC-6600 based audio cards (new Audio Excel DSP 16)"
depends on SOUND_AEDSP16
help
The SC6600 is the new version of DSP mounted on the Audio Excel DSP
16 cards. Find in the manual the FCC ID of your audio card and
answer Y if you have an SC6600 DSP.
config SC6600_JOY
bool "Activate SC-6600 Joystick Interface"
depends on SC6600
help
Say Y here in order to use the joystick interface of the Audio Excel
DSP 16 card.
config SC6600_CDROM
int "SC-6600 CDROM Interface (4=None, 3=IDE, 1=Panasonic, 0=?Sony?)"
depends on SC6600
default "4"
help
This is used to activate the CD-ROM interface of the Audio Excel
DSP 16 card. Enter: 0 for Sony, 1 for Panasonic, 2 for IDE, 4 for no
CD-ROM present.
config SC6600_CDROMBASE
hex "SC-6600 CDROM Interface I/O Address"
depends on SC6600
default "0"
help
Base I/O port address for the CD-ROM interface of the Audio Excel
DSP 16 card.
config SOUND_VIDC
tristate "VIDC 16-bit sound"
depends on ARM && ARCH_ACORN
help
16-bit support for the VIDC onboard sound hardware found on Acorn
machines.
config SOUND_WAVEARTIST
tristate "Netwinder WaveArtist"
depends on ARM && ARCH_NETWINDER
help
Say Y here to include support for the Rockwell WaveArtist sound
system. This driver is mainly for the NetWinder.
config SOUND_KAHLUA
tristate "XpressAudio Sound Blaster emulation"
depends on SOUND_SB
endif # SOUND_OSS

View file

@ -1,108 +0,0 @@
# SPDX-License-Identifier: GPL-2.0
# Makefile for the Linux sound card driver
#
# 18 Apr 1998, Michael Elizabeth Chastain, <mailto:mec@shout.net>
# Rewritten to use lists instead of if-statements.
# Each configuration option enables a list of files.
obj-$(CONFIG_SOUND_OSS) += sound.o
# Please leave it as is, cause the link order is significant !
obj-$(CONFIG_SOUND_AEDSP16) += aedsp16.o
obj-$(CONFIG_SOUND_PSS) += pss.o ad1848.o mpu401.o
obj-$(CONFIG_SOUND_TRIX) += trix.o ad1848.o sb_lib.o uart401.o
obj-$(CONFIG_SOUND_MSS) += ad1848.o
obj-$(CONFIG_SOUND_PAS) += pas2.o sb.o sb_lib.o uart401.o
obj-$(CONFIG_SOUND_SB) += sb.o sb_lib.o uart401.o
obj-$(CONFIG_SOUND_KAHLUA) += kahlua.o
obj-$(CONFIG_SOUND_MPU401) += mpu401.o
obj-$(CONFIG_SOUND_UART6850) += uart6850.o
obj-$(CONFIG_SOUND_YM3812) += opl3.o
obj-$(CONFIG_SOUND_VMIDI) += v_midi.o
obj-$(CONFIG_SOUND_VIDC) += vidc_mod.o
obj-$(CONFIG_SOUND_WAVEARTIST) += waveartist.o
obj-$(CONFIG_SOUND_MSNDCLAS) += msnd.o msnd_classic.o
obj-$(CONFIG_SOUND_MSNDPIN) += msnd.o msnd_pinnacle.o
obj-$(CONFIG_SOUND_BCM_CS4297A) += swarm_cs4297a.o
obj-$(CONFIG_DMASOUND) += dmasound/
# Declare multi-part drivers.
sound-objs := \
dev_table.o soundcard.o \
audio.o dmabuf.o \
midi_synth.o midibuf.o \
sequencer.o sound_timer.o sys_timer.o
pas2-objs := pas2_card.o pas2_midi.o pas2_mixer.o pas2_pcm.o
sb-objs := sb_card.o
sb_lib-objs := sb_common.o sb_audio.o sb_midi.o sb_mixer.o sb_ess.o
vidc_mod-objs := vidc.o vidc_fill.o
hostprogs-y := bin2hex hex2hex
# Files generated that shall be removed upon make clean
clean-files := msndperm.c msndinit.c pndsperm.c pndspini.c \
pss_boot.h trix_boot.h
# Firmware files that need translation
#
# The translated files are protected by a file that keeps track
# of what name was used to build them. If the name changes, they
# will be forced to be remade.
#
# Turtle Beach MultiSound
ifeq ($(CONFIG_MSNDCLAS_HAVE_BOOT),y)
$(obj)/msnd_classic.o: $(obj)/msndperm.c $(obj)/msndinit.c
$(obj)/msndperm.c: $(patsubst "%", %, $(CONFIG_MSNDCLAS_PERM_FILE)) $(obj)/bin2hex
$(obj)/bin2hex msndperm < $< > $@
$(obj)/msndinit.c: $(patsubst "%", %, $(CONFIG_MSNDCLAS_INIT_FILE)) $(obj)/bin2hex
$(obj)/bin2hex msndinit < $< > $@
endif
ifeq ($(CONFIG_MSNDPIN_HAVE_BOOT),y)
$(obj)/msnd_pinnacle.o: $(obj)/pndsperm.c $(obj)/pndspini.c
$(obj)/pndsperm.c: $(patsubst "%", %, $(CONFIG_MSNDPIN_PERM_FILE)) $(obj)/bin2hex
$(obj)/bin2hex pndsperm < $< > $@
$(obj)/pndspini.c: $(patsubst "%", %, $(CONFIG_MSNDPIN_INIT_FILE)) $(obj)/bin2hex
$(obj)/bin2hex pndspini < $< > $@
endif
# PSS (ECHO-ADI2111)
$(obj)/pss.o: $(obj)/pss_boot.h
ifeq ($(CONFIG_PSS_HAVE_BOOT),y)
$(obj)/pss_boot.h: $(patsubst "%", %, $(CONFIG_PSS_BOOT_FILE)) $(obj)/bin2hex
$(obj)/bin2hex pss_synth < $< > $@
else
$(obj)/pss_boot.h:
$(Q)( \
echo 'static unsigned char * pss_synth = NULL;'; \
echo 'static int pss_synthLen = 0;'; \
) > $@
endif
# MediaTrix AudioTrix Pro
$(obj)/trix.o: $(obj)/trix_boot.h
ifeq ($(CONFIG_TRIX_HAVE_BOOT),y)
$(obj)/trix_boot.h: $(patsubst "%", %, $(CONFIG_TRIX_BOOT_FILE)) $(obj)/hex2hex
$(obj)/hex2hex -i trix_boot < $< > $@
else
$(obj)/trix_boot.h:
$(Q)( \
echo 'static unsigned char * trix_boot = NULL;'; \
echo 'static int trix_boot_len = 0;'; \
) > $@
endif

Some files were not shown because too many files have changed in this diff Show more