Merge branch 'for-linus' of git://git.alsa-project.org/alsa-kernel
* 'for-linus' of git://git.alsa-project.org/alsa-kernel: (258 commits) ALSA: hda: VREF powerdown for headphones ALSA: hda: STAC_HP_M4 ALSA: ASoC: Check for machine type in GTA01 machine driver ALSA: mtpav - Fix race in probe ALSA: usb-audio: dynamic detection of MIDI interfaces in uaxx-quirk ALSA: Add a note on dependency of RTC stuff ALSA: ASoC: add new param mux to dapm_mux_update_power ALSA: Increase components array size ALSA: ASoC: Correct inverted Mic PGA Switch control in wm8510 driver ALSA: hda: comment typo fix ALSA: hda: comment typo fix ALSA: hda - Fix PCI SSID for ASROCK K18N78FullHD-hSLI ALSA: snd-usb-audio: support for Edirol UA-4FX device ALSA: usb - Fix possible Oops at USB-MIDI disconnection ALSA: hda - Fix another ALC889A (rev 0x100101) ALSA: hda: add more board-specific information for Realtek ALC662 rev1 ALSA: Correct Vladimir Barinov's e-mail address ALSA: cs46xx: Add PCI IDs for TerraTec and Hercules cards ALSA: hda: SPDIF stream muting support ALSA: hda: appletv support ...
This commit is contained in:
commit
d3570a5a7b
|
@ -746,8 +746,10 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
|||
Module snd-hda-intel
|
||||
--------------------
|
||||
|
||||
Module for Intel HD Audio (ICH6, ICH6M, ESB2, ICH7, ICH8),
|
||||
ATI SB450, SB600, RS600,
|
||||
Module for Intel HD Audio (ICH6, ICH6M, ESB2, ICH7, ICH8, ICH9, ICH10,
|
||||
PCH, SCH),
|
||||
ATI SB450, SB600, R600, RS600, RS690, RS780, RV610, RV620,
|
||||
RV630, RV635, RV670, RV770,
|
||||
VIA VT8251/VT8237A,
|
||||
SIS966, ULI M5461
|
||||
|
||||
|
@ -807,6 +809,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
|||
ALC260
|
||||
hp HP machines
|
||||
hp-3013 HP machines (3013-variant)
|
||||
hp-dc7600 HP DC7600
|
||||
fujitsu Fujitsu S7020
|
||||
acer Acer TravelMate
|
||||
will Will laptops (PB V7900)
|
||||
|
@ -828,8 +831,11 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
|||
hippo Hippo (ATI) with jack detection, Sony UX-90s
|
||||
hippo_1 Hippo (Benq) with jack detection
|
||||
sony-assamd Sony ASSAMD
|
||||
toshiba-s06 Toshiba S06
|
||||
toshiba-rx1 Toshiba RX1
|
||||
ultra Samsung Q1 Ultra Vista model
|
||||
lenovo-3000 Lenovo 3000 y410
|
||||
nec NEC Versa S9100
|
||||
basic fixed pin assignment w/o SPDIF
|
||||
auto auto-config reading BIOS (default)
|
||||
|
||||
|
@ -838,6 +844,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
|||
3stack 3-stack model
|
||||
toshiba Toshiba A205
|
||||
acer Acer laptops
|
||||
acer-aspire Acer Aspire One
|
||||
dell Dell OEM laptops (Vostro 1200)
|
||||
zepto Zepto laptops
|
||||
test for testing/debugging purpose, almost all controls can
|
||||
|
@ -847,6 +854,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
|||
|
||||
ALC269
|
||||
basic Basic preset
|
||||
quanta Quanta FL1
|
||||
eeepc-p703 ASUS Eeepc P703 P900A
|
||||
eeepc-p901 ASUS Eeepc P901 S101
|
||||
|
||||
ALC662/663
|
||||
3stack-dig 3-stack (2-channel) with SPDIF
|
||||
|
@ -856,10 +866,17 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
|||
lenovo-101e Lenovo laptop
|
||||
eeepc-p701 ASUS Eeepc P701
|
||||
eeepc-ep20 ASUS Eeepc EP20
|
||||
ecs ECS/Foxconn mobo
|
||||
m51va ASUS M51VA
|
||||
g71v ASUS G71V
|
||||
h13 ASUS H13
|
||||
g50v ASUS G50V
|
||||
asus-mode1 ASUS
|
||||
asus-mode2 ASUS
|
||||
asus-mode3 ASUS
|
||||
asus-mode4 ASUS
|
||||
asus-mode5 ASUS
|
||||
asus-mode6 ASUS
|
||||
auto auto-config reading BIOS (default)
|
||||
|
||||
ALC882/885
|
||||
|
@ -891,12 +908,14 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
|||
lenovo-101e Lenovo 101E
|
||||
lenovo-nb0763 Lenovo NB0763
|
||||
lenovo-ms7195-dig Lenovo MS7195
|
||||
lenovo-sky Lenovo Sky
|
||||
haier-w66 Haier W66
|
||||
3stack-hp HP machines with 3stack (Lucknow, Samba boards)
|
||||
6stack-dell Dell machines with 6stack (Inspiron 530)
|
||||
mitac Mitac 8252D
|
||||
clevo-m720 Clevo M720 laptop series
|
||||
fujitsu-pi2515 Fujitsu AMILO Pi2515
|
||||
3stack-6ch-intel Intel DG33* boards
|
||||
auto auto-config reading BIOS (default)
|
||||
|
||||
ALC861/660
|
||||
|
@ -929,7 +948,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
|||
allout 5-jack in back, 2-jack in front, SPDIF out
|
||||
auto auto-config reading BIOS (default)
|
||||
|
||||
AD1882
|
||||
AD1882 / AD1882A
|
||||
3stack 3-stack mode (default)
|
||||
6stack 6-stack mode
|
||||
|
||||
|
@ -1079,7 +1098,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
|||
register value without FIFO size correction as the current
|
||||
DMA pointer. position_fix=2 will make the driver to use
|
||||
the position buffer instead of reading SD_LPIB register.
|
||||
(Usually SD_LPLIB register is more accurate than the
|
||||
(Usually SD_LPIB register is more accurate than the
|
||||
position buffer.)
|
||||
|
||||
NB: If you get many "azx_get_response timeout" messages at
|
||||
|
@ -1166,6 +1185,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
|||
* Event Electronics, EZ8
|
||||
* Digigram VX442
|
||||
* Lionstracs, Mediastaton
|
||||
* Terrasoniq TS 88
|
||||
|
||||
model - Use the given board model, one of the following:
|
||||
delta1010, dio2496, delta66, delta44, audiophile, delta410,
|
||||
|
@ -1200,7 +1220,10 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
|||
* TerraTec Phase 22
|
||||
* TerraTec Phase 28
|
||||
* AudioTrak Prodigy 7.1
|
||||
* AudioTrak Prodigy 7.1LT
|
||||
* AudioTrak Prodigy 7.1 LT
|
||||
* AudioTrak Prodigy 7.1 XT
|
||||
* AudioTrak Prodigy 7.1 HIFI
|
||||
* AudioTrak Prodigy 7.1 HD2
|
||||
* AudioTrak Prodigy 192
|
||||
* Pontis MS300
|
||||
* Albatron K8X800 Pro II
|
||||
|
@ -1211,12 +1234,16 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
|||
* Shuttle SN25P
|
||||
* Onkyo SE-90PCI
|
||||
* Onkyo SE-200PCI
|
||||
* ESI Juli@
|
||||
* Hercules Fortissimo IV
|
||||
* EGO-SYS WaveTerminal 192M
|
||||
|
||||
model - Use the given board model, one of the following:
|
||||
revo51, revo71, amp2000, prodigy71, prodigy71lt,
|
||||
prodigy192, aureon51, aureon71, universe, ap192,
|
||||
k8x800, phase22, phase28, ms300, av710, se200pci,
|
||||
se90pci
|
||||
prodigy71xt, prodigy71hifi, prodigyhd2, prodigy192,
|
||||
juli, aureon51, aureon71, universe, ap192, k8x800,
|
||||
phase22, phase28, ms300, av710, se200pci, se90pci,
|
||||
fortissimo4, sn25p, WT192M
|
||||
|
||||
This module supports multiple cards and autoprobe.
|
||||
|
||||
|
@ -1255,7 +1282,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
|||
|
||||
Module for AC'97 motherboards from Intel and compatibles.
|
||||
* Intel i810/810E, i815, i820, i830, i84x, MX440
|
||||
ICH5, ICH6, ICH7, ESB2
|
||||
ICH5, ICH6, ICH7, 6300ESB, ESB2
|
||||
* SiS 7012 (SiS 735)
|
||||
* NVidia NForce, NForce2, NForce3, MCP04, CK804
|
||||
CK8, CK8S, MCP501
|
||||
|
@ -1951,6 +1978,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
|||
* CHIC True Sound 4Dwave
|
||||
* Shark Predator4D-PCI
|
||||
* Jaton SonicWave 4D
|
||||
* SiS SI7018 PCI Audio
|
||||
* Hoontech SoundTrack Digital 4DWave NX
|
||||
|
||||
pcm_channels - max channels (voices) reserved for PCM
|
||||
wavetable_size - max wavetable size in kB (4-?kb)
|
||||
|
@ -1966,12 +1995,25 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
|||
|
||||
vid - Vendor ID for the device (optional)
|
||||
pid - Product ID for the device (optional)
|
||||
nrpacks - Max. number of packets per URB (default: 8)
|
||||
async_unlink - Use async unlink mode (default: yes)
|
||||
device_setup - Device specific magic number (optional)
|
||||
- Influence depends on the device
|
||||
- Default: 0x0000
|
||||
ignore_ctl_error - Ignore any USB-controller regarding mixer
|
||||
interface (default: no)
|
||||
|
||||
This module supports multiple devices, autoprobe and hotplugging.
|
||||
|
||||
NB: nrpacks parameter can be modified dynamically via sysfs.
|
||||
Don't put the value over 20. Changing via sysfs has no sanity
|
||||
check.
|
||||
NB: async_unlink=0 would cause Oops. It remains just for
|
||||
debugging purpose (if any).
|
||||
NB: ignore_ctl_error=1 may help when you get an error at accessing
|
||||
the mixer element such as URB error -22. This happens on some
|
||||
buggy USB device or the controller.
|
||||
|
||||
Module snd-usb-caiaq
|
||||
--------------------
|
||||
|
||||
|
@ -2078,7 +2120,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
|||
-------------------
|
||||
|
||||
Module for sound cards based on the Asus AV100/AV200 chips,
|
||||
i.e., Xonar D1, DX, D2 and D2X.
|
||||
i.e., Xonar D1, DX, D2, D2X and HDAV1.3 (Deluxe).
|
||||
|
||||
This module supports autoprobe and multiple cards.
|
||||
|
||||
|
|
|
@ -6135,44 +6135,58 @@ struct _snd_pcm_runtime {
|
|||
</para>
|
||||
</section>
|
||||
|
||||
<section id="useful-functions-snd-assert">
|
||||
<title><function>snd_assert()</function></title>
|
||||
<para>
|
||||
<function>snd_assert()</function> macro is similar with the
|
||||
normal <function>assert()</function> macro. For example,
|
||||
|
||||
<informalexample>
|
||||
<programlisting>
|
||||
<![CDATA[
|
||||
snd_assert(pointer != NULL, return -EINVAL);
|
||||
]]>
|
||||
</programlisting>
|
||||
</informalexample>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The first argument is the expression to evaluate, and the
|
||||
second argument is the action if it fails. When
|
||||
<constant>CONFIG_SND_DEBUG</constant>, is set, it will show an
|
||||
error message such as <computeroutput>BUG? (xxx)</computeroutput>
|
||||
together with stack trace.
|
||||
</para>
|
||||
<para>
|
||||
When no debug flag is set, this macro is ignored.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="useful-functions-snd-bug">
|
||||
<title><function>snd_BUG()</function></title>
|
||||
<para>
|
||||
It shows the <computeroutput>BUG?</computeroutput> message and
|
||||
stack trace as well as <function>snd_assert</function> at the point.
|
||||
stack trace as well as <function>snd_BUG_ON</function> at the point.
|
||||
It's useful to show that a fatal error happens there.
|
||||
</para>
|
||||
<para>
|
||||
When no debug flag is set, this macro is ignored.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="useful-functions-snd-bug-on">
|
||||
<title><function>snd_BUG_ON()</function></title>
|
||||
<para>
|
||||
<function>snd_BUG_ON()</function> macro is similar with
|
||||
<function>WARN_ON()</function> macro. For example,
|
||||
|
||||
<informalexample>
|
||||
<programlisting>
|
||||
<![CDATA[
|
||||
snd_BUG_ON(!pointer);
|
||||
]]>
|
||||
</programlisting>
|
||||
</informalexample>
|
||||
|
||||
or it can be used as the condition,
|
||||
<informalexample>
|
||||
<programlisting>
|
||||
<![CDATA[
|
||||
if (snd_BUG_ON(non_zero_is_bug))
|
||||
return -EINVAL;
|
||||
]]>
|
||||
</programlisting>
|
||||
</informalexample>
|
||||
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The macro takes an conditional expression to evaluate.
|
||||
When <constant>CONFIG_SND_DEBUG</constant>, is set, the
|
||||
expression is actually evaluated. If it's non-zero, it shows
|
||||
the warning message such as
|
||||
<computeroutput>BUG? (xxx)</computeroutput>
|
||||
normally followed by stack trace. It returns the evaluated
|
||||
value.
|
||||
When no <constant>CONFIG_SND_DEBUG</constant> is set, this
|
||||
macro always returns zero.
|
||||
</para>
|
||||
|
||||
</section>
|
||||
|
||||
</chapter>
|
||||
|
||||
|
||||
|
|
|
@ -3828,6 +3828,8 @@ S: Maintained
|
|||
SOUND
|
||||
P: Jaroslav Kysela
|
||||
M: perex@perex.cz
|
||||
P: Takashi Iwai
|
||||
M: tiwai@suse.de
|
||||
L: alsa-devel@alsa-project.org (subscribers-only)
|
||||
S: Maintained
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Do not include this file directly. It's included from linux/mtd/xip.h
|
||||
*
|
||||
* Author: Vladimir Barinov <vbarinov@ru.mvista.com>
|
||||
* Author: Vladimir Barinov <vbarinov@embeddedalley.com>
|
||||
*
|
||||
* (c) 2005 MontaVista Software, Inc. This file is licensed under the
|
||||
* terms of the GNU General Public License version 2. This program is
|
||||
|
|
|
@ -203,6 +203,10 @@ config SOUND
|
|||
tristate
|
||||
default UML_SOUND
|
||||
|
||||
config SOUND_OSS_CORE
|
||||
bool
|
||||
default UML_SOUND
|
||||
|
||||
config HOSTAUDIO
|
||||
tristate
|
||||
default UML_SOUND
|
||||
|
|
|
@ -488,10 +488,12 @@ static int snd_card_saa7134_hw_params(struct snd_pcm_substream * substream,
|
|||
period_size = params_period_bytes(hw_params);
|
||||
periods = params_periods(hw_params);
|
||||
|
||||
snd_assert(period_size >= 0x100 && period_size <= 0x10000,
|
||||
return -EINVAL);
|
||||
snd_assert(periods >= 4, return -EINVAL);
|
||||
snd_assert(period_size * periods <= 1024 * 1024, return -EINVAL);
|
||||
if (period_size < 0x100 || period_size > 0x10000)
|
||||
return -EINVAL;
|
||||
if (periods < 4)
|
||||
return -EINVAL;
|
||||
if (period_size * periods > 1024 * 1024)
|
||||
return -EINVAL;
|
||||
|
||||
dev = saa7134->dev;
|
||||
|
||||
|
@ -942,7 +944,8 @@ static int snd_card_saa7134_new_mixer(snd_card_saa7134_t * chip)
|
|||
unsigned int idx;
|
||||
int err;
|
||||
|
||||
snd_assert(chip != NULL, return -EINVAL);
|
||||
if (snd_BUG_ON(!chip))
|
||||
return -EINVAL;
|
||||
strcpy(card->mixername, "SAA7134 Mixer");
|
||||
|
||||
for (idx = 0; idx < ARRAY_SIZE(snd_saa7134_controls); idx++) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* IXP4XX EHCI Host Controller Driver
|
||||
*
|
||||
* Author: Vladimir Barinov <vbarinov@ru.mvista.com>
|
||||
* Author: Vladimir Barinov <vbarinov@embeddedalley.com>
|
||||
*
|
||||
* Based on "ehci-fsl.c" by Randy Vinson <rvinson@mvista.com>
|
||||
*
|
||||
|
|
|
@ -1,218 +0,0 @@
|
|||
#ifndef __SOUND_AD1848_H
|
||||
#define __SOUND_AD1848_H
|
||||
|
||||
/*
|
||||
* Copyright (c) by Jaroslav Kysela <perex@perex.cz>
|
||||
* Definitions for AD1847/AD1848/CS4248 chips
|
||||
*
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pcm.h"
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
/* IO ports */
|
||||
|
||||
#define AD1848P( chip, x ) ( (chip) -> port + c_d_c_AD1848##x )
|
||||
|
||||
#define c_d_c_AD1848REGSEL 0
|
||||
#define c_d_c_AD1848REG 1
|
||||
#define c_d_c_AD1848STATUS 2
|
||||
#define c_d_c_AD1848PIO 3
|
||||
|
||||
/* codec registers */
|
||||
|
||||
#define AD1848_LEFT_INPUT 0x00 /* left input control */
|
||||
#define AD1848_RIGHT_INPUT 0x01 /* right input control */
|
||||
#define AD1848_AUX1_LEFT_INPUT 0x02 /* left AUX1 input control */
|
||||
#define AD1848_AUX1_RIGHT_INPUT 0x03 /* right AUX1 input control */
|
||||
#define AD1848_AUX2_LEFT_INPUT 0x04 /* left AUX2 input control */
|
||||
#define AD1848_AUX2_RIGHT_INPUT 0x05 /* right AUX2 input control */
|
||||
#define AD1848_LEFT_OUTPUT 0x06 /* left output control register */
|
||||
#define AD1848_RIGHT_OUTPUT 0x07 /* right output control register */
|
||||
#define AD1848_DATA_FORMAT 0x08 /* clock and data format - playback/capture - bits 7-0 MCE */
|
||||
#define AD1848_IFACE_CTRL 0x09 /* interface control - bits 7-2 MCE */
|
||||
#define AD1848_PIN_CTRL 0x0a /* pin control */
|
||||
#define AD1848_TEST_INIT 0x0b /* test and initialization */
|
||||
#define AD1848_MISC_INFO 0x0c /* miscellaneous information */
|
||||
#define AD1848_LOOPBACK 0x0d /* loopback control */
|
||||
#define AD1848_DATA_UPR_CNT 0x0e /* playback/capture upper base count */
|
||||
#define AD1848_DATA_LWR_CNT 0x0f /* playback/capture lower base count */
|
||||
|
||||
/* definitions for codec register select port - CODECP( REGSEL ) */
|
||||
|
||||
#define AD1848_INIT 0x80 /* CODEC is initializing */
|
||||
#define AD1848_MCE 0x40 /* mode change enable */
|
||||
#define AD1848_TRD 0x20 /* transfer request disable */
|
||||
|
||||
/* definitions for codec status register - CODECP( STATUS ) */
|
||||
|
||||
#define AD1848_GLOBALIRQ 0x01 /* IRQ is active */
|
||||
|
||||
/* definitions for AD1848_LEFT_INPUT and AD1848_RIGHT_INPUT registers */
|
||||
|
||||
#define AD1848_ENABLE_MIC_GAIN 0x20
|
||||
|
||||
#define AD1848_MIXS_LINE1 0x00
|
||||
#define AD1848_MIXS_AUX1 0x40
|
||||
#define AD1848_MIXS_LINE2 0x80
|
||||
#define AD1848_MIXS_ALL 0xc0
|
||||
|
||||
/* definitions for clock and data format register - AD1848_PLAYBK_FORMAT */
|
||||
|
||||
#define AD1848_LINEAR_8 0x00 /* 8-bit unsigned data */
|
||||
#define AD1848_ALAW_8 0x60 /* 8-bit A-law companded */
|
||||
#define AD1848_ULAW_8 0x20 /* 8-bit U-law companded */
|
||||
#define AD1848_LINEAR_16 0x40 /* 16-bit twos complement data - little endian */
|
||||
#define AD1848_STEREO 0x10 /* stereo mode */
|
||||
/* bits 3-1 define frequency divisor */
|
||||
#define AD1848_XTAL1 0x00 /* 24.576 crystal */
|
||||
#define AD1848_XTAL2 0x01 /* 16.9344 crystal */
|
||||
|
||||
/* definitions for interface control register - AD1848_IFACE_CTRL */
|
||||
|
||||
#define AD1848_CAPTURE_PIO 0x80 /* capture PIO enable */
|
||||
#define AD1848_PLAYBACK_PIO 0x40 /* playback PIO enable */
|
||||
#define AD1848_CALIB_MODE 0x18 /* calibration mode bits */
|
||||
#define AD1848_AUTOCALIB 0x08 /* auto calibrate */
|
||||
#define AD1848_SINGLE_DMA 0x04 /* use single DMA channel */
|
||||
#define AD1848_CAPTURE_ENABLE 0x02 /* capture enable */
|
||||
#define AD1848_PLAYBACK_ENABLE 0x01 /* playback enable */
|
||||
|
||||
/* definitions for pin control register - AD1848_PIN_CTRL */
|
||||
|
||||
#define AD1848_IRQ_ENABLE 0x02 /* enable IRQ */
|
||||
#define AD1848_XCTL1 0x40 /* external control #1 */
|
||||
#define AD1848_XCTL0 0x80 /* external control #0 */
|
||||
|
||||
/* definitions for test and init register - AD1848_TEST_INIT */
|
||||
|
||||
#define AD1848_CALIB_IN_PROGRESS 0x20 /* auto calibrate in progress */
|
||||
#define AD1848_DMA_REQUEST 0x10 /* DMA request in progress */
|
||||
|
||||
/* defines for codec.mode */
|
||||
|
||||
#define AD1848_MODE_NONE 0x0000
|
||||
#define AD1848_MODE_PLAY 0x0001
|
||||
#define AD1848_MODE_CAPTURE 0x0002
|
||||
#define AD1848_MODE_TIMER 0x0004
|
||||
#define AD1848_MODE_OPEN (AD1848_MODE_PLAY|AD1848_MODE_CAPTURE|AD1848_MODE_TIMER)
|
||||
#define AD1848_MODE_RUNNING 0x0010
|
||||
|
||||
/* defines for codec.hardware */
|
||||
|
||||
#define AD1848_HW_DETECT 0x0000 /* let AD1848 driver detect chip */
|
||||
#define AD1848_HW_AD1847 0x0001 /* AD1847 chip */
|
||||
#define AD1848_HW_AD1848 0x0002 /* AD1848 chip */
|
||||
#define AD1848_HW_CS4248 0x0003 /* CS4248 chip */
|
||||
#define AD1848_HW_CMI8330 0x0004 /* CMI8330 chip */
|
||||
#define AD1848_HW_THINKPAD 0x0005 /* Thinkpad 360/750/755 */
|
||||
|
||||
/* IBM Thinkpad specific stuff */
|
||||
#define AD1848_THINKPAD_CTL_PORT1 0x15e8
|
||||
#define AD1848_THINKPAD_CTL_PORT2 0x15e9
|
||||
#define AD1848_THINKPAD_CS4248_ENABLE_BIT 0x02
|
||||
|
||||
struct snd_ad1848 {
|
||||
unsigned long port; /* i/o port */
|
||||
struct resource *res_port;
|
||||
int irq; /* IRQ line */
|
||||
int dma; /* data DMA */
|
||||
unsigned short version; /* version of CODEC chip */
|
||||
unsigned short mode; /* see to AD1848_MODE_XXXX */
|
||||
unsigned short hardware; /* see to AD1848_HW_XXXX */
|
||||
unsigned short single_dma:1; /* forced single DMA mode (GUS 16-bit daughter board) or dma1 == dma2 */
|
||||
|
||||
struct snd_pcm *pcm;
|
||||
struct snd_pcm_substream *playback_substream;
|
||||
struct snd_pcm_substream *capture_substream;
|
||||
struct snd_card *card;
|
||||
|
||||
unsigned char image[32]; /* SGalaxy needs an access to extended registers */
|
||||
int mce_bit;
|
||||
int calibrate_mute;
|
||||
int dma_size;
|
||||
int thinkpad_flag; /* Thinkpad CS4248 needs some extra help */
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
void (*suspend)(struct snd_ad1848 *chip);
|
||||
void (*resume)(struct snd_ad1848 *chip);
|
||||
#endif
|
||||
|
||||
spinlock_t reg_lock;
|
||||
};
|
||||
|
||||
/* exported functions */
|
||||
|
||||
void snd_ad1848_out(struct snd_ad1848 *chip, unsigned char reg, unsigned char value);
|
||||
|
||||
int snd_ad1848_create(struct snd_card *card,
|
||||
unsigned long port,
|
||||
int irq, int dma,
|
||||
unsigned short hardware,
|
||||
struct snd_ad1848 ** chip);
|
||||
|
||||
int snd_ad1848_pcm(struct snd_ad1848 * chip, int device, struct snd_pcm **rpcm);
|
||||
const struct snd_pcm_ops *snd_ad1848_get_pcm_ops(int direction);
|
||||
int snd_ad1848_mixer(struct snd_ad1848 * chip);
|
||||
|
||||
/* exported mixer stuffs */
|
||||
enum { AD1848_MIX_SINGLE, AD1848_MIX_DOUBLE, AD1848_MIX_CAPTURE };
|
||||
|
||||
#define AD1848_MIXVAL_SINGLE(reg, shift, mask, invert) \
|
||||
((reg) | ((shift) << 8) | ((mask) << 16) | ((invert) << 24))
|
||||
#define AD1848_MIXVAL_DOUBLE(left_reg, right_reg, shift_left, shift_right, mask, invert) \
|
||||
((left_reg) | ((right_reg) << 8) | ((shift_left) << 16) | ((shift_right) << 19) | ((mask) << 24) | ((invert) << 22))
|
||||
|
||||
/* for ease of use */
|
||||
struct ad1848_mix_elem {
|
||||
const char *name;
|
||||
int index;
|
||||
int type;
|
||||
unsigned long private_value;
|
||||
const unsigned int *tlv;
|
||||
};
|
||||
|
||||
#define AD1848_SINGLE(xname, xindex, reg, shift, mask, invert) \
|
||||
{ .name = xname, \
|
||||
.index = xindex, \
|
||||
.type = AD1848_MIX_SINGLE, \
|
||||
.private_value = AD1848_MIXVAL_SINGLE(reg, shift, mask, invert) }
|
||||
|
||||
#define AD1848_SINGLE_TLV(xname, xindex, reg, shift, mask, invert, xtlv) \
|
||||
{ .name = xname, \
|
||||
.index = xindex, \
|
||||
.type = AD1848_MIX_SINGLE, \
|
||||
.private_value = AD1848_MIXVAL_SINGLE(reg, shift, mask, invert), \
|
||||
.tlv = xtlv }
|
||||
|
||||
#define AD1848_DOUBLE(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert) \
|
||||
{ .name = xname, \
|
||||
.index = xindex, \
|
||||
.type = AD1848_MIX_DOUBLE, \
|
||||
.private_value = AD1848_MIXVAL_DOUBLE(left_reg, right_reg, shift_left, shift_right, mask, invert) }
|
||||
|
||||
#define AD1848_DOUBLE_TLV(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert, xtlv) \
|
||||
{ .name = xname, \
|
||||
.index = xindex, \
|
||||
.type = AD1848_MIX_DOUBLE, \
|
||||
.private_value = AD1848_MIXVAL_DOUBLE(left_reg, right_reg, shift_left, shift_right, mask, invert), \
|
||||
.tlv = xtlv }
|
||||
|
||||
int snd_ad1848_add_ctl_elem(struct snd_ad1848 *chip, const struct ad1848_mix_elem *c);
|
||||
|
||||
#endif /* __SOUND_AD1848_H */
|
|
@ -93,9 +93,10 @@ enum {
|
|||
SNDRV_HWDEP_IFACE_PCXHR, /* Digigram PCXHR */
|
||||
SNDRV_HWDEP_IFACE_SB_RC, /* SB Extigy/Audigy2NX remote control */
|
||||
SNDRV_HWDEP_IFACE_HDA, /* HD-audio */
|
||||
SNDRV_HWDEP_IFACE_USB_STREAM, /* direct access to usb stream */
|
||||
|
||||
/* Don't forget to change the following: */
|
||||
SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_HDA
|
||||
SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_USB_STREAM
|
||||
};
|
||||
|
||||
struct snd_hwdep_info {
|
||||
|
@ -296,29 +297,39 @@ struct snd_pcm_info {
|
|||
unsigned char reserved[64]; /* reserved for future... */
|
||||
};
|
||||
|
||||
typedef int __bitwise snd_pcm_hw_param_t;
|
||||
#define SNDRV_PCM_HW_PARAM_ACCESS ((__force snd_pcm_hw_param_t) 0) /* Access type */
|
||||
#define SNDRV_PCM_HW_PARAM_FORMAT ((__force snd_pcm_hw_param_t) 1) /* Format */
|
||||
#define SNDRV_PCM_HW_PARAM_SUBFORMAT ((__force snd_pcm_hw_param_t) 2) /* Subformat */
|
||||
typedef int snd_pcm_hw_param_t;
|
||||
#define SNDRV_PCM_HW_PARAM_ACCESS 0 /* Access type */
|
||||
#define SNDRV_PCM_HW_PARAM_FORMAT 1 /* Format */
|
||||
#define SNDRV_PCM_HW_PARAM_SUBFORMAT 2 /* Subformat */
|
||||
#define SNDRV_PCM_HW_PARAM_FIRST_MASK SNDRV_PCM_HW_PARAM_ACCESS
|
||||
#define SNDRV_PCM_HW_PARAM_LAST_MASK SNDRV_PCM_HW_PARAM_SUBFORMAT
|
||||
|
||||
#define SNDRV_PCM_HW_PARAM_SAMPLE_BITS ((__force snd_pcm_hw_param_t) 8) /* Bits per sample */
|
||||
#define SNDRV_PCM_HW_PARAM_FRAME_BITS ((__force snd_pcm_hw_param_t) 9) /* Bits per frame */
|
||||
#define SNDRV_PCM_HW_PARAM_CHANNELS ((__force snd_pcm_hw_param_t) 10) /* Channels */
|
||||
#define SNDRV_PCM_HW_PARAM_RATE ((__force snd_pcm_hw_param_t) 11) /* Approx rate */
|
||||
#define SNDRV_PCM_HW_PARAM_PERIOD_TIME ((__force snd_pcm_hw_param_t) 12) /* Approx distance between interrupts in us */
|
||||
#define SNDRV_PCM_HW_PARAM_PERIOD_SIZE ((__force snd_pcm_hw_param_t) 13) /* Approx frames between interrupts */
|
||||
#define SNDRV_PCM_HW_PARAM_PERIOD_BYTES ((__force snd_pcm_hw_param_t) 14) /* Approx bytes between interrupts */
|
||||
#define SNDRV_PCM_HW_PARAM_PERIODS ((__force snd_pcm_hw_param_t) 15) /* Approx interrupts per buffer */
|
||||
#define SNDRV_PCM_HW_PARAM_BUFFER_TIME ((__force snd_pcm_hw_param_t) 16) /* Approx duration of buffer in us */
|
||||
#define SNDRV_PCM_HW_PARAM_BUFFER_SIZE ((__force snd_pcm_hw_param_t) 17) /* Size of buffer in frames */
|
||||
#define SNDRV_PCM_HW_PARAM_BUFFER_BYTES ((__force snd_pcm_hw_param_t) 18) /* Size of buffer in bytes */
|
||||
#define SNDRV_PCM_HW_PARAM_TICK_TIME ((__force snd_pcm_hw_param_t) 19) /* Approx tick duration in us */
|
||||
#define SNDRV_PCM_HW_PARAM_SAMPLE_BITS 8 /* Bits per sample */
|
||||
#define SNDRV_PCM_HW_PARAM_FRAME_BITS 9 /* Bits per frame */
|
||||
#define SNDRV_PCM_HW_PARAM_CHANNELS 10 /* Channels */
|
||||
#define SNDRV_PCM_HW_PARAM_RATE 11 /* Approx rate */
|
||||
#define SNDRV_PCM_HW_PARAM_PERIOD_TIME 12 /* Approx distance between
|
||||
* interrupts in us
|
||||
*/
|
||||
#define SNDRV_PCM_HW_PARAM_PERIOD_SIZE 13 /* Approx frames between
|
||||
* interrupts
|
||||
*/
|
||||
#define SNDRV_PCM_HW_PARAM_PERIOD_BYTES 14 /* Approx bytes between
|
||||
* interrupts
|
||||
*/
|
||||
#define SNDRV_PCM_HW_PARAM_PERIODS 15 /* Approx interrupts per
|
||||
* buffer
|
||||
*/
|
||||
#define SNDRV_PCM_HW_PARAM_BUFFER_TIME 16 /* Approx duration of buffer
|
||||
* in us
|
||||
*/
|
||||
#define SNDRV_PCM_HW_PARAM_BUFFER_SIZE 17 /* Size of buffer in frames */
|
||||
#define SNDRV_PCM_HW_PARAM_BUFFER_BYTES 18 /* Size of buffer in bytes */
|
||||
#define SNDRV_PCM_HW_PARAM_TICK_TIME 19 /* Approx tick duration in us */
|
||||
#define SNDRV_PCM_HW_PARAM_FIRST_INTERVAL SNDRV_PCM_HW_PARAM_SAMPLE_BITS
|
||||
#define SNDRV_PCM_HW_PARAM_LAST_INTERVAL SNDRV_PCM_HW_PARAM_TICK_TIME
|
||||
|
||||
#define SNDRV_PCM_HW_PARAMS_NORESAMPLE (1<<0) /* avoid rate resampling */
|
||||
#define SNDRV_PCM_HW_PARAMS_NORESAMPLE (1<<0) /* avoid rate resampling */
|
||||
|
||||
struct snd_interval {
|
||||
unsigned int min, max;
|
||||
|
@ -696,7 +707,7 @@ struct snd_timer_tread {
|
|||
* *
|
||||
****************************************************************************/
|
||||
|
||||
#define SNDRV_CTL_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 5)
|
||||
#define SNDRV_CTL_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 6)
|
||||
|
||||
struct snd_ctl_card_info {
|
||||
int card; /* card number */
|
||||
|
@ -707,8 +718,7 @@ struct snd_ctl_card_info {
|
|||
unsigned char longname[80]; /* name + info text about soundcard */
|
||||
unsigned char reserved_[16]; /* reserved for future (was ID of mixer) */
|
||||
unsigned char mixername[80]; /* visual mixer identification */
|
||||
unsigned char components[80]; /* card components / fine identification, delimited with one space (AC97 etc..) */
|
||||
unsigned char reserved[48]; /* reserved for future */
|
||||
unsigned char components[128]; /* card components / fine identification, delimited with one space (AC97 etc..) */
|
||||
};
|
||||
|
||||
typedef int __bitwise snd_ctl_elem_type_t;
|
||||
|
|
|
@ -60,35 +60,56 @@
|
|||
#define IEC958_AES1_PRO_USERBITS_UDEF (12<<4) /* user defined application */
|
||||
#define IEC958_AES1_CON_CATEGORY 0x7f
|
||||
#define IEC958_AES1_CON_GENERAL 0x00
|
||||
#define IEC958_AES1_CON_EXPERIMENTAL 0x40
|
||||
#define IEC958_AES1_CON_SOLIDMEM_MASK 0x0f
|
||||
#define IEC958_AES1_CON_SOLIDMEM_ID 0x08
|
||||
#define IEC958_AES1_CON_BROADCAST1_MASK 0x07
|
||||
#define IEC958_AES1_CON_BROADCAST1_ID 0x04
|
||||
#define IEC958_AES1_CON_DIGDIGCONV_MASK 0x07
|
||||
#define IEC958_AES1_CON_DIGDIGCONV_ID 0x02
|
||||
#define IEC958_AES1_CON_ADC_COPYRIGHT_MASK 0x1f
|
||||
#define IEC958_AES1_CON_ADC_COPYRIGHT_ID 0x06
|
||||
#define IEC958_AES1_CON_ADC_MASK 0x1f
|
||||
#define IEC958_AES1_CON_ADC_ID 0x16
|
||||
#define IEC958_AES1_CON_BROADCAST2_MASK 0x0f
|
||||
#define IEC958_AES1_CON_BROADCAST2_ID 0x0e
|
||||
#define IEC958_AES1_CON_LASEROPT_MASK 0x07
|
||||
#define IEC958_AES1_CON_LASEROPT_ID 0x01
|
||||
#define IEC958_AES1_CON_MUSICAL_MASK 0x07
|
||||
#define IEC958_AES1_CON_MUSICAL_ID 0x05
|
||||
#define IEC958_AES1_CON_MAGNETIC_MASK 0x07
|
||||
#define IEC958_AES1_CON_MAGNETIC_ID 0x03
|
||||
#define IEC958_AES1_CON_IEC908_CD (IEC958_AES1_CON_LASEROPT_ID|0x00)
|
||||
#define IEC958_AES1_CON_NON_IEC908_CD (IEC958_AES1_CON_LASEROPT_ID|0x08)
|
||||
#define IEC958_AES1_CON_MINI_DISC (IEC958_AES1_CON_LASEROPT_ID|0x48)
|
||||
#define IEC958_AES1_CON_DVD (IEC958_AES1_CON_LASEROPT_ID|0x18)
|
||||
#define IEC958_AES1_CON_LASTEROPT_OTHER (IEC958_AES1_CON_LASEROPT_ID|0x78)
|
||||
#define IEC958_AES1_CON_DIGDIGCONV_MASK 0x07
|
||||
#define IEC958_AES1_CON_DIGDIGCONV_ID 0x02
|
||||
#define IEC958_AES1_CON_PCM_CODER (IEC958_AES1_CON_DIGDIGCONV_ID|0x00)
|
||||
#define IEC958_AES1_CON_SAMPLER (IEC958_AES1_CON_DIGDIGCONV_ID|0x20)
|
||||
#define IEC958_AES1_CON_MIXER (IEC958_AES1_CON_DIGDIGCONV_ID|0x10)
|
||||
#define IEC958_AES1_CON_RATE_CONVERTER (IEC958_AES1_CON_DIGDIGCONV_ID|0x18)
|
||||
#define IEC958_AES1_CON_SYNTHESIZER (IEC958_AES1_CON_MUSICAL_ID|0x00)
|
||||
#define IEC958_AES1_CON_MICROPHONE (IEC958_AES1_CON_MUSICAL_ID|0x08)
|
||||
#define IEC958_AES1_CON_SAMPLER (IEC958_AES1_CON_DIGDIGCONV_ID|0x20)
|
||||
#define IEC958_AES1_CON_DSP (IEC958_AES1_CON_DIGDIGCONV_ID|0x28)
|
||||
#define IEC958_AES1_CON_DIGDIGCONV_OTHER (IEC958_AES1_CON_DIGDIGCONV_ID|0x78)
|
||||
#define IEC958_AES1_CON_MAGNETIC_MASK 0x07
|
||||
#define IEC958_AES1_CON_MAGNETIC_ID 0x03
|
||||
#define IEC958_AES1_CON_DAT (IEC958_AES1_CON_MAGNETIC_ID|0x00)
|
||||
#define IEC958_AES1_CON_VCR (IEC958_AES1_CON_MAGNETIC_ID|0x08)
|
||||
#define IEC958_AES1_CON_DCC (IEC958_AES1_CON_MAGNETIC_ID|0x40)
|
||||
#define IEC958_AES1_CON_MAGNETIC_DISC (IEC958_AES1_CON_MAGNETIC_ID|0x18)
|
||||
#define IEC958_AES1_CON_MAGNETIC_OTHER (IEC958_AES1_CON_MAGNETIC_ID|0x78)
|
||||
#define IEC958_AES1_CON_BROADCAST1_MASK 0x07
|
||||
#define IEC958_AES1_CON_BROADCAST1_ID 0x04
|
||||
#define IEC958_AES1_CON_DAB_JAPAN (IEC958_AES1_CON_BROADCAST1_ID|0x00)
|
||||
#define IEC958_AES1_CON_DAB_EUROPE (IEC958_AES1_CON_BROADCAST1_ID|0x08)
|
||||
#define IEC958_AES1_CON_DAB_USA (IEC958_AES1_CON_BROADCAST1_ID|0x60)
|
||||
#define IEC958_AES1_CON_SOFTWARE (IEC958_AES1_CON_BROADCAST1_ID|0x40)
|
||||
#define IEC958_AES1_CON_IEC62105 (IEC958_AES1_CON_BROADCAST1_ID|0x20)
|
||||
#define IEC958_AES1_CON_BROADCAST1_OTHER (IEC958_AES1_CON_BROADCAST1_ID|0x78)
|
||||
#define IEC958_AES1_CON_BROADCAST2_MASK 0x0f
|
||||
#define IEC958_AES1_CON_BROADCAST2_ID 0x0e
|
||||
#define IEC958_AES1_CON_MUSICAL_MASK 0x07
|
||||
#define IEC958_AES1_CON_MUSICAL_ID 0x05
|
||||
#define IEC958_AES1_CON_SYNTHESIZER (IEC958_AES1_CON_MUSICAL_ID|0x00)
|
||||
#define IEC958_AES1_CON_MICROPHONE (IEC958_AES1_CON_MUSICAL_ID|0x08)
|
||||
#define IEC958_AES1_CON_MUSICAL_OTHER (IEC958_AES1_CON_MUSICAL_ID|0x78)
|
||||
#define IEC958_AES1_CON_ADC_MASK 0x1f
|
||||
#define IEC958_AES1_CON_ADC_ID 0x06
|
||||
#define IEC958_AES1_CON_ADC (IEC958_AES1_CON_ADC_ID|0x00)
|
||||
#define IEC958_AES1_CON_ADC_OTHER (IEC958_AES1_CON_ADC_ID|0x60)
|
||||
#define IEC958_AES1_CON_ADC_COPYRIGHT_MASK 0x1f
|
||||
#define IEC958_AES1_CON_ADC_COPYRIGHT_ID 0x16
|
||||
#define IEC958_AES1_CON_ADC_COPYRIGHT (IEC958_AES1_CON_ADC_COPYRIGHT_ID|0x00)
|
||||
#define IEC958_AES1_CON_ADC_COPYRIGHT_OTHER (IEC958_AES1_CON_ADC_COPYRIGHT_ID|0x60)
|
||||
#define IEC958_AES1_CON_SOLIDMEM_MASK 0x0f
|
||||
#define IEC958_AES1_CON_SOLIDMEM_ID 0x08
|
||||
#define IEC958_AES1_CON_SOLIDMEM_DIGITAL_RECORDER_PLAYER (IEC958_AES1_CON_SOLIDMEM_ID|0x00)
|
||||
#define IEC958_AES1_CON_SOLIDMEM_OTHER (IEC958_AES1_CON_SOLIDMEM_ID|0x70)
|
||||
#define IEC958_AES1_CON_EXPERIMENTAL 0x40
|
||||
#define IEC958_AES1_CON_ORIGINAL (1<<7) /* this bits depends on the category code */
|
||||
#define IEC958_AES2_PRO_SBITS (7<<0) /* mask - sample bits */
|
||||
#define IEC958_AES2_PRO_SBITS_20 (2<<0) /* 20-bit - coordination */
|
||||
|
@ -106,8 +127,16 @@
|
|||
#define IEC958_AES2_CON_CHANNEL_UNSPEC (0<<4) /* unspecified */
|
||||
#define IEC958_AES3_CON_FS (15<<0) /* mask - sample frequency */
|
||||
#define IEC958_AES3_CON_FS_44100 (0<<0) /* 44.1kHz */
|
||||
#define IEC958_AES3_CON_FS_NOTID (1<<0) /* non indicated */
|
||||
#define IEC958_AES3_CON_FS_48000 (2<<0) /* 48kHz */
|
||||
#define IEC958_AES3_CON_FS_32000 (3<<0) /* 32kHz */
|
||||
#define IEC958_AES3_CON_FS_22050 (4<<0) /* 22.05kHz */
|
||||
#define IEC958_AES3_CON_FS_24000 (6<<0) /* 24kHz */
|
||||
#define IEC958_AES3_CON_FS_88200 (8<<0) /* 88.2kHz */
|
||||
#define IEC958_AES3_CON_FS_768000 (9<<0) /* 768kHz */
|
||||
#define IEC958_AES3_CON_FS_96000 (10<<0) /* 96kHz */
|
||||
#define IEC958_AES3_CON_FS_176400 (12<<0) /* 176.4kHz */
|
||||
#define IEC958_AES3_CON_FS_192000 (14<<0) /* 192kHz */
|
||||
#define IEC958_AES3_CON_CLOCK (3<<4) /* mask - clock accuracy */
|
||||
#define IEC958_AES3_CON_CLOCK_1000PPM (0<<4) /* 1000 ppm */
|
||||
#define IEC958_AES3_CON_CLOCK_50PPM (1<<4) /* 50 ppm */
|
||||
|
@ -120,6 +149,26 @@
|
|||
#define IEC958_AES4_CON_WORDLEN_23_19 (4<<1) /* 23-bit or 19-bit */
|
||||
#define IEC958_AES4_CON_WORDLEN_24_20 (5<<1) /* 24-bit or 20-bit */
|
||||
#define IEC958_AES4_CON_WORDLEN_21_17 (6<<1) /* 21-bit or 17-bit */
|
||||
#define IEC958_AES4_CON_ORIGFS (15<<4) /* mask - original sample frequency */
|
||||
#define IEC958_AES4_CON_ORIGFS_NOTID (0<<4) /* not indicated */
|
||||
#define IEC958_AES4_CON_ORIGFS_192000 (1<<4) /* 192kHz */
|
||||
#define IEC958_AES4_CON_ORIGFS_12000 (2<<4) /* 12kHz */
|
||||
#define IEC958_AES4_CON_ORIGFS_176400 (3<<4) /* 176.4kHz */
|
||||
#define IEC958_AES4_CON_ORIGFS_96000 (5<<4) /* 96kHz */
|
||||
#define IEC958_AES4_CON_ORIGFS_8000 (6<<4) /* 8kHz */
|
||||
#define IEC958_AES4_CON_ORIGFS_88200 (7<<4) /* 88.2kHz */
|
||||
#define IEC958_AES4_CON_ORIGFS_16000 (8<<4) /* 16kHz */
|
||||
#define IEC958_AES4_CON_ORIGFS_24000 (9<<4) /* 24kHz */
|
||||
#define IEC958_AES4_CON_ORIGFS_11025 (10<<4) /* 11.025kHz */
|
||||
#define IEC958_AES4_CON_ORIGFS_22050 (11<<4) /* 22.05kHz */
|
||||
#define IEC958_AES4_CON_ORIGFS_32000 (12<<4) /* 32kHz */
|
||||
#define IEC958_AES4_CON_ORIGFS_48000 (13<<4) /* 48kHz */
|
||||
#define IEC958_AES4_CON_ORIGFS_44100 (15<<4) /* 44.1kHz */
|
||||
#define IEC958_AES5_CON_CGMSA (3<<0) /* mask - CGMS-A */
|
||||
#define IEC958_AES5_CON_CGMSA_COPYFREELY (0<<0) /* copying is permitted without restriction */
|
||||
#define IEC958_AES5_CON_CGMSA_COPYONCE (1<<0) /* one generation of copies may be made */
|
||||
#define IEC958_AES5_CON_CGMSA_COPYNOMORE (2<<0) /* condition not be used */
|
||||
#define IEC958_AES5_CON_CGMSA_COPYNEVER (3<<0) /* no copying is permitted */
|
||||
|
||||
/*****************************************************************************
|
||||
* *
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <linux/rwsem.h> /* struct rw_semaphore */
|
||||
#include <linux/pm.h> /* pm_message_t */
|
||||
#include <linux/device.h>
|
||||
#include <linux/stringify.h>
|
||||
|
||||
/* number of supported soundcards */
|
||||
#ifdef CONFIG_SND_DYNAMIC_MINORS
|
||||
|
@ -63,6 +64,7 @@ typedef int __bitwise snd_device_type_t;
|
|||
#define SNDRV_DEV_INFO ((__force snd_device_type_t) 0x1006)
|
||||
#define SNDRV_DEV_BUS ((__force snd_device_type_t) 0x1007)
|
||||
#define SNDRV_DEV_CODEC ((__force snd_device_type_t) 0x1008)
|
||||
#define SNDRV_DEV_JACK ((__force snd_device_type_t) 0x1009)
|
||||
#define SNDRV_DEV_LOWLEVEL ((__force snd_device_type_t) 0x2000)
|
||||
|
||||
typedef int __bitwise snd_device_state_t;
|
||||
|
@ -114,7 +116,7 @@ struct snd_card {
|
|||
char shortname[32]; /* short name of this soundcard */
|
||||
char longname[80]; /* name of this soundcard */
|
||||
char mixername[80]; /* mixer name */
|
||||
char components[80]; /* card components delimited with
|
||||
char components[128]; /* card components delimited with
|
||||
space */
|
||||
struct module *module; /* top-level module */
|
||||
|
||||
|
@ -366,8 +368,6 @@ void snd_verbose_printd(const char *file, int line, const char *format, ...)
|
|||
|
||||
#ifdef CONFIG_SND_DEBUG
|
||||
|
||||
#define __ASTRING__(x) #x
|
||||
|
||||
#ifdef CONFIG_SND_VERBOSE_PRINTK
|
||||
/**
|
||||
* snd_printd - debug printk
|
||||
|
@ -382,33 +382,15 @@ void snd_verbose_printd(const char *file, int line, const char *format, ...)
|
|||
#define snd_printd(fmt, args...) \
|
||||
printk(fmt ,##args)
|
||||
#endif
|
||||
/**
|
||||
* snd_assert - run-time assertion macro
|
||||
* @expr: expression
|
||||
*
|
||||
* This macro checks the expression in run-time and invokes the commands
|
||||
* given in the rest arguments if the assertion is failed.
|
||||
* When CONFIG_SND_DEBUG is not set, the expression is executed but
|
||||
* not checked.
|
||||
*/
|
||||
#define snd_assert(expr, args...) do { \
|
||||
if (unlikely(!(expr))) { \
|
||||
snd_printk(KERN_ERR "BUG? (%s)\n", __ASTRING__(expr)); \
|
||||
dump_stack(); \
|
||||
args; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define snd_BUG() do { \
|
||||
snd_printk(KERN_ERR "BUG?\n"); \
|
||||
dump_stack(); \
|
||||
} while (0)
|
||||
#define snd_BUG() WARN(1, "BUG?\n")
|
||||
#define snd_BUG_ON(cond) WARN((cond), "BUG? (%s)\n", __stringify(cond))
|
||||
|
||||
#else /* !CONFIG_SND_DEBUG */
|
||||
|
||||
#define snd_printd(fmt, args...) /* nothing */
|
||||
#define snd_assert(expr, args...) (void)(expr)
|
||||
#define snd_BUG() /* nothing */
|
||||
#define snd_BUG_ON(cond) ({/*(void)(cond);*/ 0;}) /* always false */
|
||||
|
||||
#endif /* CONFIG_SND_DEBUG */
|
||||
|
||||
|
|
|
@ -1,175 +0,0 @@
|
|||
#ifndef __SOUND_CS4231_H
|
||||
#define __SOUND_CS4231_H
|
||||
|
||||
/*
|
||||
* Copyright (c) by Jaroslav Kysela <perex@perex.cz>
|
||||
* Definitions for CS4231 & InterWave chips & compatible chips
|
||||
*
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
#include "control.h"
|
||||
#include "pcm.h"
|
||||
#include "timer.h"
|
||||
|
||||
#include "cs4231-regs.h"
|
||||
|
||||
/* defines for codec.mode */
|
||||
|
||||
#define CS4231_MODE_NONE 0x0000
|
||||
#define CS4231_MODE_PLAY 0x0001
|
||||
#define CS4231_MODE_RECORD 0x0002
|
||||
#define CS4231_MODE_TIMER 0x0004
|
||||
#define CS4231_MODE_OPEN (CS4231_MODE_PLAY|CS4231_MODE_RECORD|CS4231_MODE_TIMER)
|
||||
|
||||
/* defines for codec.hardware */
|
||||
|
||||
#define CS4231_HW_DETECT 0x0000 /* let CS4231 driver detect chip */
|
||||
#define CS4231_HW_DETECT3 0x0001 /* allow mode 3 */
|
||||
#define CS4231_HW_TYPE_MASK 0xff00 /* type mask */
|
||||
#define CS4231_HW_CS4231_MASK 0x0100 /* CS4231 serie */
|
||||
#define CS4231_HW_CS4231 0x0100 /* CS4231 chip */
|
||||
#define CS4231_HW_CS4231A 0x0101 /* CS4231A chip */
|
||||
#define CS4231_HW_AD1845 0x0102 /* AD1845 chip */
|
||||
#define CS4231_HW_CS4232_MASK 0x0200 /* CS4232 serie (has control ports) */
|
||||
#define CS4231_HW_CS4232 0x0200 /* CS4232 */
|
||||
#define CS4231_HW_CS4232A 0x0201 /* CS4232A */
|
||||
#define CS4231_HW_CS4236 0x0202 /* CS4236 */
|
||||
#define CS4231_HW_CS4236B_MASK 0x0400 /* CS4236B serie (has extended control regs) */
|
||||
#define CS4231_HW_CS4235 0x0400 /* CS4235 - Crystal Clear (tm) stereo enhancement */
|
||||
#define CS4231_HW_CS4236B 0x0401 /* CS4236B */
|
||||
#define CS4231_HW_CS4237B 0x0402 /* CS4237B - SRS 3D */
|
||||
#define CS4231_HW_CS4238B 0x0403 /* CS4238B - QSOUND 3D */
|
||||
#define CS4231_HW_CS4239 0x0404 /* CS4239 - Crystal Clear (tm) stereo enhancement */
|
||||
/* compatible, but clones */
|
||||
#define CS4231_HW_INTERWAVE 0x1000 /* InterWave chip */
|
||||
#define CS4231_HW_OPL3SA2 0x1101 /* OPL3-SA2 chip, similar to cs4231 */
|
||||
#define CS4231_HW_OPTI93X 0x1102 /* Opti 930/931/933 */
|
||||
|
||||
/* defines for codec.hwshare */
|
||||
#define CS4231_HWSHARE_IRQ (1<<0)
|
||||
#define CS4231_HWSHARE_DMA1 (1<<1)
|
||||
#define CS4231_HWSHARE_DMA2 (1<<2)
|
||||
|
||||
struct snd_cs4231 {
|
||||
unsigned long port; /* base i/o port */
|
||||
struct resource *res_port;
|
||||
unsigned long cport; /* control base i/o port (CS4236) */
|
||||
struct resource *res_cport;
|
||||
int irq; /* IRQ line */
|
||||
int dma1; /* playback DMA */
|
||||
int dma2; /* record DMA */
|
||||
unsigned short version; /* version of CODEC chip */
|
||||
unsigned short mode; /* see to CS4231_MODE_XXXX */
|
||||
unsigned short hardware; /* see to CS4231_HW_XXXX */
|
||||
unsigned short hwshare; /* shared resources */
|
||||
unsigned short single_dma:1, /* forced single DMA mode (GUS 16-bit daughter board) or dma1 == dma2 */
|
||||
ebus_flag:1; /* SPARC: EBUS present */
|
||||
|
||||
struct snd_card *card;
|
||||
struct snd_pcm *pcm;
|
||||
struct snd_pcm_substream *playback_substream;
|
||||
struct snd_pcm_substream *capture_substream;
|
||||
struct snd_timer *timer;
|
||||
|
||||
unsigned char image[32]; /* registers image */
|
||||
unsigned char eimage[32]; /* extended registers image */
|
||||
unsigned char cimage[16]; /* control registers image */
|
||||
int mce_bit;
|
||||
int calibrate_mute;
|
||||
int sw_3d_bit;
|
||||
unsigned int p_dma_size;
|
||||
unsigned int c_dma_size;
|
||||
|
||||
spinlock_t reg_lock;
|
||||
struct mutex mce_mutex;
|
||||
struct mutex open_mutex;
|
||||
|
||||
int (*rate_constraint) (struct snd_pcm_runtime *runtime);
|
||||
void (*set_playback_format) (struct snd_cs4231 *chip, struct snd_pcm_hw_params *hw_params, unsigned char pdfr);
|
||||
void (*set_capture_format) (struct snd_cs4231 *chip, struct snd_pcm_hw_params *hw_params, unsigned char cdfr);
|
||||
void (*trigger) (struct snd_cs4231 *chip, unsigned int what, int start);
|
||||
#ifdef CONFIG_PM
|
||||
void (*suspend) (struct snd_cs4231 *chip);
|
||||
void (*resume) (struct snd_cs4231 *chip);
|
||||
#endif
|
||||
void *dma_private_data;
|
||||
int (*claim_dma) (struct snd_cs4231 *chip, void *dma_private_data, int dma);
|
||||
int (*release_dma) (struct snd_cs4231 *chip, void *dma_private_data, int dma);
|
||||
};
|
||||
|
||||
/* exported functions */
|
||||
|
||||
void snd_cs4231_out(struct snd_cs4231 *chip, unsigned char reg, unsigned char val);
|
||||
unsigned char snd_cs4231_in(struct snd_cs4231 *chip, unsigned char reg);
|
||||
void snd_cs4236_ext_out(struct snd_cs4231 *chip, unsigned char reg, unsigned char val);
|
||||
unsigned char snd_cs4236_ext_in(struct snd_cs4231 *chip, unsigned char reg);
|
||||
void snd_cs4231_mce_up(struct snd_cs4231 *chip);
|
||||
void snd_cs4231_mce_down(struct snd_cs4231 *chip);
|
||||
|
||||
void snd_cs4231_overrange(struct snd_cs4231 *chip);
|
||||
|
||||
irqreturn_t snd_cs4231_interrupt(int irq, void *dev_id);
|
||||
|
||||
const char *snd_cs4231_chip_id(struct snd_cs4231 *chip);
|
||||
|
||||
int snd_cs4231_create(struct snd_card *card,
|
||||
unsigned long port,
|
||||
unsigned long cport,
|
||||
int irq, int dma1, int dma2,
|
||||
unsigned short hardware,
|
||||
unsigned short hwshare,
|
||||
struct snd_cs4231 ** rchip);
|
||||
int snd_cs4231_pcm(struct snd_cs4231 * chip, int device, struct snd_pcm **rpcm);
|
||||
int snd_cs4231_timer(struct snd_cs4231 * chip, int device, struct snd_timer **rtimer);
|
||||
int snd_cs4231_mixer(struct snd_cs4231 * chip);
|
||||
|
||||
int snd_cs4236_create(struct snd_card *card,
|
||||
unsigned long port,
|
||||
unsigned long cport,
|
||||
int irq, int dma1, int dma2,
|
||||
unsigned short hardware,
|
||||
unsigned short hwshare,
|
||||
struct snd_cs4231 ** rchip);
|
||||
int snd_cs4236_pcm(struct snd_cs4231 * chip, int device, struct snd_pcm **rpcm);
|
||||
int snd_cs4236_mixer(struct snd_cs4231 * chip);
|
||||
|
||||
/*
|
||||
* mixer library
|
||||
*/
|
||||
|
||||
#define CS4231_SINGLE(xname, xindex, reg, shift, mask, invert) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
|
||||
.info = snd_cs4231_info_single, \
|
||||
.get = snd_cs4231_get_single, .put = snd_cs4231_put_single, \
|
||||
.private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) }
|
||||
|
||||
int snd_cs4231_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo);
|
||||
int snd_cs4231_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
|
||||
int snd_cs4231_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
|
||||
|
||||
#define CS4231_DOUBLE(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
|
||||
.info = snd_cs4231_info_double, \
|
||||
.get = snd_cs4231_get_double, .put = snd_cs4231_put_double, \
|
||||
.private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) }
|
||||
|
||||
int snd_cs4231_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo);
|
||||
int snd_cs4231_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
|
||||
int snd_cs4231_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
|
||||
|
||||
#endif /* __SOUND_CS4231_H */
|
75
include/sound/jack.h
Normal file
75
include/sound/jack.h
Normal file
|
@ -0,0 +1,75 @@
|
|||
#ifndef __SOUND_JACK_H
|
||||
#define __SOUND_JACK_H
|
||||
|
||||
/*
|
||||
* Jack abstraction layer
|
||||
*
|
||||
* Copyright 2008 Wolfson Microelectronics plc
|
||||
*
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sound/core.h>
|
||||
|
||||
struct input_dev;
|
||||
|
||||
/**
|
||||
* Jack types which can be reported. These values are used as a
|
||||
* bitmask.
|
||||
*/
|
||||
enum snd_jack_types {
|
||||
SND_JACK_HEADPHONE = 0x0001,
|
||||
SND_JACK_MICROPHONE = 0x0002,
|
||||
SND_JACK_HEADSET = SND_JACK_HEADPHONE | SND_JACK_MICROPHONE,
|
||||
};
|
||||
|
||||
struct snd_jack {
|
||||
struct input_dev *input_dev;
|
||||
int registered;
|
||||
int type;
|
||||
const char *id;
|
||||
char name[100];
|
||||
};
|
||||
|
||||
#ifdef CONFIG_SND_JACK
|
||||
|
||||
int snd_jack_new(struct snd_card *card, const char *id, int type,
|
||||
struct snd_jack **jack);
|
||||
void snd_jack_set_parent(struct snd_jack *jack, struct device *parent);
|
||||
|
||||
void snd_jack_report(struct snd_jack *jack, int status);
|
||||
|
||||
#else
|
||||
|
||||
static inline int snd_jack_new(struct snd_card *card, const char *id, int type,
|
||||
struct snd_jack **jack)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void snd_jack_set_parent(struct snd_jack *jack,
|
||||
struct device *parent)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void snd_jack_report(struct snd_jack *jack, int status)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -65,6 +65,11 @@ struct snd_dma_buffer {
|
|||
/*
|
||||
* Scatter-Gather generic device pages
|
||||
*/
|
||||
void *snd_malloc_sgbuf_pages(struct device *device,
|
||||
size_t size, struct snd_dma_buffer *dmab,
|
||||
size_t *res_size);
|
||||
int snd_free_sgbuf_pages(struct snd_dma_buffer *dmab);
|
||||
|
||||
struct snd_sg_page {
|
||||
void *buf;
|
||||
dma_addr_t addr;
|
||||
|
@ -92,9 +97,18 @@ static inline unsigned int snd_sgbuf_aligned_pages(size_t size)
|
|||
*/
|
||||
static inline dma_addr_t snd_sgbuf_get_addr(struct snd_sg_buf *sgbuf, size_t offset)
|
||||
{
|
||||
return sgbuf->table[offset >> PAGE_SHIFT].addr + offset % PAGE_SIZE;
|
||||
dma_addr_t addr = sgbuf->table[offset >> PAGE_SHIFT].addr;
|
||||
addr &= PAGE_MASK;
|
||||
return addr + offset % PAGE_SIZE;
|
||||
}
|
||||
|
||||
/*
|
||||
* return the virtual address at the corresponding offset
|
||||
*/
|
||||
static inline void *snd_sgbuf_get_ptr(struct snd_sg_buf *sgbuf, size_t offset)
|
||||
{
|
||||
return sgbuf->table[offset >> PAGE_SHIFT].buf + offset % PAGE_SIZE;
|
||||
}
|
||||
|
||||
/* allocate/release a buffer */
|
||||
int snd_dma_alloc_pages(int type, struct device *dev, size_t size,
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#define SNDRV_OS_MINORS 256
|
||||
|
||||
#define SNDRV_MINOR_DEVICES 32
|
||||
#define SNDRV_MINOR_CARD(minor) ((minor) >> 5)
|
||||
#define SNDRV_MINOR_DEVICE(minor) ((minor) & 0x001f)
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include <sound/asound.h>
|
||||
#include <sound/memalloc.h>
|
||||
#include <sound/minors.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/bitops.h>
|
||||
|
@ -84,7 +85,11 @@ struct snd_pcm_ops {
|
|||
*
|
||||
*/
|
||||
|
||||
#define SNDRV_PCM_DEVICES 8
|
||||
#if defined(CONFIG_SND_DYNAMIC_MINORS)
|
||||
#define SNDRV_PCM_DEVICES (SNDRV_OS_MINORS-2)
|
||||
#else
|
||||
#define SNDRV_PCM_DEVICES 8
|
||||
#endif
|
||||
|
||||
#define SNDRV_PCM_IOCTL1_FALSE ((void *)0)
|
||||
#define SNDRV_PCM_IOCTL1_TRUE ((void *)1)
|
||||
|
@ -416,7 +421,7 @@ struct snd_pcm_str {
|
|||
struct snd_pcm {
|
||||
struct snd_card *card;
|
||||
struct list_head list;
|
||||
unsigned int device; /* device number */
|
||||
int device; /* device number */
|
||||
unsigned int info_flags;
|
||||
unsigned short dev_class;
|
||||
unsigned short dev_subclass;
|
||||
|
@ -969,10 +974,30 @@ int snd_pcm_lib_preallocate_pages_for_all(struct snd_pcm *pcm,
|
|||
int snd_pcm_lib_malloc_pages(struct snd_pcm_substream *substream, size_t size);
|
||||
int snd_pcm_lib_free_pages(struct snd_pcm_substream *substream);
|
||||
|
||||
#define snd_pcm_substream_sgbuf(substream) ((substream)->runtime->dma_buffer_p->private_data)
|
||||
#define snd_pcm_sgbuf_pages(size) snd_sgbuf_aligned_pages(size)
|
||||
#define snd_pcm_sgbuf_get_addr(sgbuf,ofs) snd_sgbuf_get_addr(sgbuf,ofs)
|
||||
struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream, unsigned long offset);
|
||||
/*
|
||||
* SG-buffer handling
|
||||
*/
|
||||
#define snd_pcm_substream_sgbuf(substream) \
|
||||
((substream)->runtime->dma_buffer_p->private_data)
|
||||
|
||||
static inline dma_addr_t
|
||||
snd_pcm_sgbuf_get_addr(struct snd_pcm_substream *substream, unsigned int ofs)
|
||||
{
|
||||
struct snd_sg_buf *sg = snd_pcm_substream_sgbuf(substream);
|
||||
return snd_sgbuf_get_addr(sg, ofs);
|
||||
}
|
||||
|
||||
static inline void *
|
||||
snd_pcm_sgbuf_get_ptr(struct snd_pcm_substream *substream, unsigned int ofs)
|
||||
{
|
||||
struct snd_sg_buf *sg = snd_pcm_substream_sgbuf(substream);
|
||||
return snd_sgbuf_get_ptr(sg, ofs);
|
||||
}
|
||||
|
||||
struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream,
|
||||
unsigned long offset);
|
||||
unsigned int snd_pcm_sgbuf_get_chunk_size(struct snd_pcm_substream *substream,
|
||||
unsigned int ofs, unsigned int size);
|
||||
|
||||
/* handle mmap counter - PCM mmap callback should handle this counter properly */
|
||||
static inline void snd_pcm_mmap_data_open(struct vm_area_struct *area)
|
||||
|
@ -1010,4 +1035,6 @@ static inline void snd_pcm_limit_isa_dma_size(int dma, size_t *max)
|
|||
(IEC958_AES1_CON_PCM_CODER<<8)|\
|
||||
(IEC958_AES3_CON_FS_48000<<24))
|
||||
|
||||
#define PCM_RUNTIME_CHECK(sub) snd_BUG_ON(!(sub) || !(sub)->runtime)
|
||||
|
||||
#endif /* __SOUND_PCM_H */
|
||||
|
|
45
include/sound/pxa2xx-lib.h
Normal file
45
include/sound/pxa2xx-lib.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
#ifndef PXA2XX_LIB_H
|
||||
#define PXA2XX_LIB_H
|
||||
|
||||
#include <linux/platform_device.h>
|
||||
#include <sound/ac97_codec.h>
|
||||
|
||||
/* PCM */
|
||||
|
||||
struct pxa2xx_pcm_dma_params {
|
||||
char *name; /* stream identifier */
|
||||
u32 dcmd; /* DMA descriptor dcmd field */
|
||||
volatile u32 *drcmr; /* the DMA request channel to use */
|
||||
u32 dev_addr; /* device physical address for DMA */
|
||||
};
|
||||
|
||||
extern int __pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params);
|
||||
extern int __pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream);
|
||||
extern int pxa2xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd);
|
||||
extern snd_pcm_uframes_t pxa2xx_pcm_pointer(struct snd_pcm_substream *substream);
|
||||
extern int __pxa2xx_pcm_prepare(struct snd_pcm_substream *substream);
|
||||
extern void pxa2xx_pcm_dma_irq(int dma_ch, void *dev_id);
|
||||
extern int __pxa2xx_pcm_open(struct snd_pcm_substream *substream);
|
||||
extern int __pxa2xx_pcm_close(struct snd_pcm_substream *substream);
|
||||
extern int pxa2xx_pcm_mmap(struct snd_pcm_substream *substream,
|
||||
struct vm_area_struct *vma);
|
||||
extern int pxa2xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream);
|
||||
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 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 int pxa2xx_ac97_hw_suspend(void);
|
||||
extern int pxa2xx_ac97_hw_resume(void);
|
||||
|
||||
extern int pxa2xx_ac97_hw_probe(struct platform_device *dev);
|
||||
extern void pxa2xx_ac97_hw_remove(struct platform_device *dev);
|
||||
|
||||
#endif
|
|
@ -240,11 +240,15 @@ struct snd_sb {
|
|||
#define SB_DT019X_CAP_MAIN 0x07
|
||||
|
||||
#define SB_ALS4000_MONO_IO_CTRL 0x4b
|
||||
#define SB_ALS4000_OUT_MIXER_CTRL_2 0x4c
|
||||
#define SB_ALS4000_MIC_IN_GAIN 0x4d
|
||||
#define SB_ALS4000_ANALOG_REFRNC_VOLT_CTRL 0x4e
|
||||
#define SB_ALS4000_FMDAC 0x4f
|
||||
#define SB_ALS4000_3D_SND_FX 0x50
|
||||
#define SB_ALS4000_3D_TIME_DELAY 0x51
|
||||
#define SB_ALS4000_3D_AUTO_MUTE 0x52
|
||||
#define SB_ALS4000_ANALOG_BLOCK_CTRL 0x53
|
||||
#define SB_ALS4000_3D_DELAYLINE_PATTERN 0x54
|
||||
#define SB_ALS4000_QSOUND 0xdb
|
||||
|
||||
/* IRQ setting bitmap */
|
||||
|
@ -257,6 +261,7 @@ struct snd_sb {
|
|||
#define SB_IRQTYPE_8BIT 0x01
|
||||
#define SB_IRQTYPE_16BIT 0x02
|
||||
#define SB_IRQTYPE_MPUIN 0x04
|
||||
#define ALS4K_IRQTYPE_CR1E_DMA 0x20
|
||||
|
||||
/* DMA setting bitmap */
|
||||
#define SB_DMASETUP_DMA0 0x01
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#ifndef __SOUND_SND_WAVEFRONT_H__
|
||||
#define __SOUND_SND_WAVEFRONT_H__
|
||||
|
||||
#include "cs4231.h"
|
||||
#include "mpu401.h"
|
||||
#include "hwdep.h"
|
||||
#include "rawmidi.h"
|
||||
|
|
25
include/sound/soc-of-simple.h
Normal file
25
include/sound/soc-of-simple.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* OF helpers for ALSA SoC
|
||||
*
|
||||
* Copyright (C) 2008, Secret Lab Technologies Ltd.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_SOC_OF_H_
|
||||
#define _INCLUDE_SOC_OF_H_
|
||||
|
||||
#if defined(CONFIG_SND_SOC_OF_SIMPLE) || defined(CONFIG_SND_SOC_OF_SIMPLE_MODULE)
|
||||
|
||||
#include <linux/of.h>
|
||||
#include <sound/soc.h>
|
||||
|
||||
int of_snd_soc_register_codec(struct snd_soc_codec_device *codec_dev,
|
||||
void *codec_data, struct snd_soc_dai *dai,
|
||||
struct device_node *node);
|
||||
|
||||
int of_snd_soc_register_platform(struct snd_soc_platform *platform,
|
||||
struct device_node *node,
|
||||
struct snd_soc_dai *cpu_dai);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _INCLUDE_SOC_OF_H_ */
|
|
@ -26,10 +26,12 @@
|
|||
/*
|
||||
* Convenience kcontrol builders
|
||||
*/
|
||||
#define SOC_SINGLE_VALUE(reg, shift, max, invert) ((reg) | ((shift) << 8) |\
|
||||
((shift) << 12) | ((max) << 16) | ((invert) << 24))
|
||||
#define SOC_SINGLE_VALUE_EXT(reg, max, invert) ((reg) | ((max) << 16) |\
|
||||
((invert) << 31))
|
||||
#define SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) \
|
||||
((unsigned long)&(struct soc_mixer_control) \
|
||||
{.reg = xreg, .shift = xshift, .max = xmax, .invert = xinvert})
|
||||
#define SOC_SINGLE_VALUE_EXT(xreg, xmax, xinvert) \
|
||||
((unsigned long)&(struct soc_mixer_control) \
|
||||
{.reg = xreg, .max = xmax, .invert = xinvert})
|
||||
#define SOC_SINGLE(xname, reg, shift, max, invert) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
|
||||
.info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\
|
||||
|
@ -43,64 +45,68 @@
|
|||
.info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\
|
||||
.put = snd_soc_put_volsw, \
|
||||
.private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
|
||||
#define SOC_DOUBLE(xname, reg, shift_left, shift_right, max, invert) \
|
||||
#define SOC_DOUBLE(xname, xreg, shift_left, shift_right, xmax, xinvert) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
|
||||
.info = snd_soc_info_volsw, .get = snd_soc_get_volsw, \
|
||||
.put = snd_soc_put_volsw, \
|
||||
.private_value = (reg) | ((shift_left) << 8) | \
|
||||
((shift_right) << 12) | ((max) << 16) | ((invert) << 24) }
|
||||
#define SOC_DOUBLE_R(xname, reg_left, reg_right, shift, max, invert) \
|
||||
.private_value = (unsigned long)&(struct soc_mixer_control) \
|
||||
{.reg = xreg, .shift = shift_left, .rshift = shift_right, \
|
||||
.max = xmax, .invert = xinvert} }
|
||||
#define SOC_DOUBLE_R(xname, reg_left, reg_right, xshift, xmax, xinvert) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
|
||||
.info = snd_soc_info_volsw_2r, \
|
||||
.get = snd_soc_get_volsw_2r, .put = snd_soc_put_volsw_2r, \
|
||||
.private_value = (reg_left) | ((shift) << 8) | \
|
||||
((max) << 12) | ((invert) << 20) | ((reg_right) << 24) }
|
||||
#define SOC_DOUBLE_TLV(xname, reg, shift_left, shift_right, max, invert, tlv_array) \
|
||||
.private_value = (unsigned long)&(struct soc_mixer_control) \
|
||||
{.reg = reg_left, .rreg = reg_right, .shift = xshift, \
|
||||
.max = xmax, .invert = xinvert} }
|
||||
#define SOC_DOUBLE_TLV(xname, xreg, shift_left, shift_right, xmax, xinvert, tlv_array) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
|
||||
SNDRV_CTL_ELEM_ACCESS_READWRITE,\
|
||||
.tlv.p = (tlv_array), \
|
||||
.info = snd_soc_info_volsw, .get = snd_soc_get_volsw, \
|
||||
.put = snd_soc_put_volsw, \
|
||||
.private_value = (reg) | ((shift_left) << 8) | \
|
||||
((shift_right) << 12) | ((max) << 16) | ((invert) << 24) }
|
||||
#define SOC_DOUBLE_R_TLV(xname, reg_left, reg_right, shift, max, invert, tlv_array) \
|
||||
.private_value = (unsigned long)&(struct soc_mixer_control) \
|
||||
{.reg = xreg, .shift = shift_left, .rshift = shift_right,\
|
||||
.max = xmax, .invert = xinvert} }
|
||||
#define SOC_DOUBLE_R_TLV(xname, reg_left, reg_right, xshift, xmax, xinvert, tlv_array) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
|
||||
SNDRV_CTL_ELEM_ACCESS_READWRITE,\
|
||||
.tlv.p = (tlv_array), \
|
||||
.info = snd_soc_info_volsw_2r, \
|
||||
.get = snd_soc_get_volsw_2r, .put = snd_soc_put_volsw_2r, \
|
||||
.private_value = (reg_left) | ((shift) << 8) | \
|
||||
((max) << 12) | ((invert) << 20) | ((reg_right) << 24) }
|
||||
#define SOC_DOUBLE_S8_TLV(xname, reg, min, max, tlv_array) \
|
||||
.private_value = (unsigned long)&(struct soc_mixer_control) \
|
||||
{.reg = reg_left, .rreg = reg_right, .shift = xshift, \
|
||||
.max = xmax, .invert = xinvert} }
|
||||
#define SOC_DOUBLE_S8_TLV(xname, xreg, xmin, xmax, tlv_array) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
|
||||
SNDRV_CTL_ELEM_ACCESS_READWRITE, \
|
||||
.tlv.p = (tlv_array), \
|
||||
.info = snd_soc_info_volsw_s8, .get = snd_soc_get_volsw_s8, \
|
||||
.put = snd_soc_put_volsw_s8, \
|
||||
.private_value = (reg) | (((signed char)max) << 16) | \
|
||||
(((signed char)min) << 24) }
|
||||
#define SOC_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xtexts) \
|
||||
.private_value = (unsigned long)&(struct soc_mixer_control) \
|
||||
{.reg = xreg, .min = xmin, .max = xmax} }
|
||||
#define SOC_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmax, xtexts) \
|
||||
{ .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \
|
||||
.mask = xmask, .texts = xtexts }
|
||||
#define SOC_ENUM_SINGLE(xreg, xshift, xmask, xtexts) \
|
||||
SOC_ENUM_DOUBLE(xreg, xshift, xshift, xmask, xtexts)
|
||||
#define SOC_ENUM_SINGLE_EXT(xmask, xtexts) \
|
||||
{ .mask = xmask, .texts = xtexts }
|
||||
.max = xmax, .texts = xtexts }
|
||||
#define SOC_ENUM_SINGLE(xreg, xshift, xmax, xtexts) \
|
||||
SOC_ENUM_DOUBLE(xreg, xshift, xshift, xmax, xtexts)
|
||||
#define SOC_ENUM_SINGLE_EXT(xmax, xtexts) \
|
||||
{ .max = xmax, .texts = xtexts }
|
||||
#define SOC_ENUM(xname, xenum) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,\
|
||||
.info = snd_soc_info_enum_double, \
|
||||
.get = snd_soc_get_enum_double, .put = snd_soc_put_enum_double, \
|
||||
.private_value = (unsigned long)&xenum }
|
||||
#define SOC_SINGLE_EXT(xname, xreg, xshift, xmask, xinvert,\
|
||||
#define SOC_SINGLE_EXT(xname, xreg, xshift, xmax, xinvert,\
|
||||
xhandler_get, xhandler_put) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
|
||||
.info = snd_soc_info_volsw, \
|
||||
.get = xhandler_get, .put = xhandler_put, \
|
||||
.private_value = SOC_SINGLE_VALUE(xreg, xshift, xmask, xinvert) }
|
||||
#define SOC_SINGLE_EXT_TLV(xname, xreg, xshift, xmask, xinvert,\
|
||||
.private_value = SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) }
|
||||
#define SOC_SINGLE_EXT_TLV(xname, xreg, xshift, xmax, xinvert,\
|
||||
xhandler_get, xhandler_put, tlv_array) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
|
||||
|
@ -108,7 +114,7 @@
|
|||
.tlv.p = (tlv_array), \
|
||||
.info = snd_soc_info_volsw, \
|
||||
.get = xhandler_get, .put = xhandler_put, \
|
||||
.private_value = SOC_SINGLE_VALUE(xreg, xshift, xmask, xinvert) }
|
||||
.private_value = SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) }
|
||||
#define SOC_SINGLE_BOOL_EXT(xname, xdata, xhandler_get, xhandler_put) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
|
||||
.info = snd_soc_info_bool_ext, \
|
||||
|
@ -410,6 +416,8 @@ struct snd_soc_codec {
|
|||
void *control_data; /* codec control (i2c/3wire) data */
|
||||
unsigned int (*read)(struct snd_soc_codec *, unsigned int);
|
||||
int (*write)(struct snd_soc_codec *, unsigned int, unsigned int);
|
||||
int (*display_register)(struct snd_soc_codec *, char *,
|
||||
size_t, unsigned int);
|
||||
hw_write_t hw_write;
|
||||
hw_read_t hw_read;
|
||||
void *reg_cache;
|
||||
|
@ -516,13 +524,19 @@ struct snd_soc_pcm_runtime {
|
|||
struct snd_soc_device *socdev;
|
||||
};
|
||||
|
||||
/* mixer control */
|
||||
struct soc_mixer_control {
|
||||
int min, max;
|
||||
unsigned int reg, rreg, shift, rshift, invert;
|
||||
};
|
||||
|
||||
/* enumerated kcontrol */
|
||||
struct soc_enum {
|
||||
unsigned short reg;
|
||||
unsigned short reg2;
|
||||
unsigned char shift_l;
|
||||
unsigned char shift_r;
|
||||
unsigned int mask;
|
||||
unsigned int max;
|
||||
const char **texts;
|
||||
void *dapm;
|
||||
};
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
/* include/version.h */
|
||||
#define CONFIG_SND_VERSION "1.0.17"
|
||||
#define CONFIG_SND_VERSION "1.0.18rc3"
|
||||
#define CONFIG_SND_DATE ""
|
||||
|
|
|
@ -235,37 +235,31 @@ irqreturn_t snd_vx_irq_handler(int irq, void *dev);
|
|||
*/
|
||||
static inline int vx_test_and_ack(struct vx_core *chip)
|
||||
{
|
||||
snd_assert(chip->ops->test_and_ack, return -ENXIO);
|
||||
return chip->ops->test_and_ack(chip);
|
||||
}
|
||||
|
||||
static inline void vx_validate_irq(struct vx_core *chip, int enable)
|
||||
{
|
||||
snd_assert(chip->ops->validate_irq, return);
|
||||
chip->ops->validate_irq(chip, enable);
|
||||
}
|
||||
|
||||
static inline unsigned char snd_vx_inb(struct vx_core *chip, int reg)
|
||||
{
|
||||
snd_assert(chip->ops->in8, return 0);
|
||||
return chip->ops->in8(chip, reg);
|
||||
}
|
||||
|
||||
static inline unsigned int snd_vx_inl(struct vx_core *chip, int reg)
|
||||
{
|
||||
snd_assert(chip->ops->in32, return 0);
|
||||
return chip->ops->in32(chip, reg);
|
||||
}
|
||||
|
||||
static inline void snd_vx_outb(struct vx_core *chip, int reg, unsigned char val)
|
||||
{
|
||||
snd_assert(chip->ops->out8, return);
|
||||
chip->ops->out8(chip, reg, val);
|
||||
}
|
||||
|
||||
static inline void snd_vx_outl(struct vx_core *chip, int reg, unsigned int val)
|
||||
{
|
||||
snd_assert(chip->ops->out32, return);
|
||||
chip->ops->out32(chip, reg, val);
|
||||
}
|
||||
|
||||
|
@ -276,7 +270,6 @@ static inline void snd_vx_outl(struct vx_core *chip, int reg, unsigned int val)
|
|||
|
||||
static inline void vx_reset_dsp(struct vx_core *chip)
|
||||
{
|
||||
snd_assert(chip->ops->reset_dsp, return);
|
||||
chip->ops->reset_dsp(chip);
|
||||
}
|
||||
|
||||
|
@ -304,14 +297,12 @@ int snd_vx_check_reg_bit(struct vx_core *chip, int reg, int mask, int bit, int t
|
|||
static inline void vx_pseudo_dma_write(struct vx_core *chip, struct snd_pcm_runtime *runtime,
|
||||
struct vx_pipe *pipe, int count)
|
||||
{
|
||||
snd_assert(chip->ops->dma_write, return);
|
||||
chip->ops->dma_write(chip, runtime, pipe, count);
|
||||
}
|
||||
|
||||
static inline void vx_pseudo_dma_read(struct vx_core *chip, struct snd_pcm_runtime *runtime,
|
||||
struct vx_pipe *pipe, int count)
|
||||
{
|
||||
snd_assert(chip->ops->dma_read, return);
|
||||
chip->ops->dma_read(chip, runtime, pipe, count);
|
||||
}
|
||||
|
||||
|
|
235
include/sound/wss.h
Normal file
235
include/sound/wss.h
Normal file
|
@ -0,0 +1,235 @@
|
|||
#ifndef __SOUND_WSS_H
|
||||
#define __SOUND_WSS_H
|
||||
|
||||
/*
|
||||
* Copyright (c) by Jaroslav Kysela <perex@perex.cz>
|
||||
* Definitions for CS4231 & InterWave chips & compatible chips
|
||||
*
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
#include "control.h"
|
||||
#include "pcm.h"
|
||||
#include "timer.h"
|
||||
|
||||
#include "cs4231-regs.h"
|
||||
|
||||
/* defines for codec.mode */
|
||||
|
||||
#define WSS_MODE_NONE 0x0000
|
||||
#define WSS_MODE_PLAY 0x0001
|
||||
#define WSS_MODE_RECORD 0x0002
|
||||
#define WSS_MODE_TIMER 0x0004
|
||||
#define WSS_MODE_OPEN (WSS_MODE_PLAY|WSS_MODE_RECORD|WSS_MODE_TIMER)
|
||||
|
||||
/* defines for codec.hardware */
|
||||
|
||||
#define WSS_HW_DETECT 0x0000 /* let CS4231 driver detect chip */
|
||||
#define WSS_HW_DETECT3 0x0001 /* allow mode 3 */
|
||||
#define WSS_HW_TYPE_MASK 0xff00 /* type mask */
|
||||
#define WSS_HW_CS4231_MASK 0x0100 /* CS4231 serie */
|
||||
#define WSS_HW_CS4231 0x0100 /* CS4231 chip */
|
||||
#define WSS_HW_CS4231A 0x0101 /* CS4231A chip */
|
||||
#define WSS_HW_AD1845 0x0102 /* AD1845 chip */
|
||||
#define WSS_HW_CS4232_MASK 0x0200 /* CS4232 serie (has control ports) */
|
||||
#define WSS_HW_CS4232 0x0200 /* CS4232 */
|
||||
#define WSS_HW_CS4232A 0x0201 /* CS4232A */
|
||||
#define WSS_HW_CS4236 0x0202 /* CS4236 */
|
||||
#define WSS_HW_CS4236B_MASK 0x0400 /* CS4236B serie (has extended control regs) */
|
||||
#define WSS_HW_CS4235 0x0400 /* CS4235 - Crystal Clear (tm) stereo enhancement */
|
||||
#define WSS_HW_CS4236B 0x0401 /* CS4236B */
|
||||
#define WSS_HW_CS4237B 0x0402 /* CS4237B - SRS 3D */
|
||||
#define WSS_HW_CS4238B 0x0403 /* CS4238B - QSOUND 3D */
|
||||
#define WSS_HW_CS4239 0x0404 /* CS4239 - Crystal Clear (tm) stereo enhancement */
|
||||
#define WSS_HW_AD1848_MASK 0x0800 /* AD1848 serie (half duplex) */
|
||||
#define WSS_HW_AD1847 0x0801 /* AD1847 chip */
|
||||
#define WSS_HW_AD1848 0x0802 /* AD1848 chip */
|
||||
#define WSS_HW_CS4248 0x0803 /* CS4248 chip */
|
||||
#define WSS_HW_CMI8330 0x0804 /* CMI8330 chip */
|
||||
#define WSS_HW_THINKPAD 0x0805 /* Thinkpad 360/750/755 */
|
||||
/* compatible, but clones */
|
||||
#define WSS_HW_INTERWAVE 0x1000 /* InterWave chip */
|
||||
#define WSS_HW_OPL3SA2 0x1101 /* OPL3-SA2 chip, similar to cs4231 */
|
||||
#define WSS_HW_OPTI93X 0x1102 /* Opti 930/931/933 */
|
||||
|
||||
/* defines for codec.hwshare */
|
||||
#define WSS_HWSHARE_IRQ (1<<0)
|
||||
#define WSS_HWSHARE_DMA1 (1<<1)
|
||||
#define WSS_HWSHARE_DMA2 (1<<2)
|
||||
|
||||
/* IBM Thinkpad specific stuff */
|
||||
#define AD1848_THINKPAD_CTL_PORT1 0x15e8
|
||||
#define AD1848_THINKPAD_CTL_PORT2 0x15e9
|
||||
#define AD1848_THINKPAD_CS4248_ENABLE_BIT 0x02
|
||||
|
||||
struct snd_wss {
|
||||
unsigned long port; /* base i/o port */
|
||||
struct resource *res_port;
|
||||
unsigned long cport; /* control base i/o port (CS4236) */
|
||||
struct resource *res_cport;
|
||||
int irq; /* IRQ line */
|
||||
int dma1; /* playback DMA */
|
||||
int dma2; /* record DMA */
|
||||
unsigned short version; /* version of CODEC chip */
|
||||
unsigned short mode; /* see to WSS_MODE_XXXX */
|
||||
unsigned short hardware; /* see to WSS_HW_XXXX */
|
||||
unsigned short hwshare; /* shared resources */
|
||||
unsigned short single_dma:1, /* forced single DMA mode (GUS 16-bit */
|
||||
/* daughter board) or dma1 == dma2 */
|
||||
ebus_flag:1, /* SPARC: EBUS present */
|
||||
thinkpad_flag:1; /* Thinkpad CS4248 needs extra help */
|
||||
|
||||
struct snd_card *card;
|
||||
struct snd_pcm *pcm;
|
||||
struct snd_pcm_substream *playback_substream;
|
||||
struct snd_pcm_substream *capture_substream;
|
||||
struct snd_timer *timer;
|
||||
|
||||
unsigned char image[32]; /* registers image */
|
||||
unsigned char eimage[32]; /* extended registers image */
|
||||
unsigned char cimage[16]; /* control registers image */
|
||||
int mce_bit;
|
||||
int calibrate_mute;
|
||||
int sw_3d_bit;
|
||||
unsigned int p_dma_size;
|
||||
unsigned int c_dma_size;
|
||||
|
||||
spinlock_t reg_lock;
|
||||
struct mutex mce_mutex;
|
||||
struct mutex open_mutex;
|
||||
|
||||
int (*rate_constraint) (struct snd_pcm_runtime *runtime);
|
||||
void (*set_playback_format) (struct snd_wss *chip,
|
||||
struct snd_pcm_hw_params *hw_params,
|
||||
unsigned char pdfr);
|
||||
void (*set_capture_format) (struct snd_wss *chip,
|
||||
struct snd_pcm_hw_params *hw_params,
|
||||
unsigned char cdfr);
|
||||
void (*trigger) (struct snd_wss *chip, unsigned int what, int start);
|
||||
#ifdef CONFIG_PM
|
||||
void (*suspend) (struct snd_wss *chip);
|
||||
void (*resume) (struct snd_wss *chip);
|
||||
#endif
|
||||
void *dma_private_data;
|
||||
int (*claim_dma) (struct snd_wss *chip,
|
||||
void *dma_private_data, int dma);
|
||||
int (*release_dma) (struct snd_wss *chip,
|
||||
void *dma_private_data, int dma);
|
||||
};
|
||||
|
||||
/* exported functions */
|
||||
|
||||
void snd_wss_out(struct snd_wss *chip, unsigned char reg, unsigned char val);
|
||||
unsigned char snd_wss_in(struct snd_wss *chip, unsigned char reg);
|
||||
void snd_cs4236_ext_out(struct snd_wss *chip,
|
||||
unsigned char reg, unsigned char val);
|
||||
unsigned char snd_cs4236_ext_in(struct snd_wss *chip, unsigned char reg);
|
||||
void snd_wss_mce_up(struct snd_wss *chip);
|
||||
void snd_wss_mce_down(struct snd_wss *chip);
|
||||
|
||||
void snd_wss_overrange(struct snd_wss *chip);
|
||||
|
||||
irqreturn_t snd_wss_interrupt(int irq, void *dev_id);
|
||||
|
||||
const char *snd_wss_chip_id(struct snd_wss *chip);
|
||||
|
||||
int snd_wss_create(struct snd_card *card,
|
||||
unsigned long port,
|
||||
unsigned long cport,
|
||||
int irq, int dma1, int dma2,
|
||||
unsigned short hardware,
|
||||
unsigned short hwshare,
|
||||
struct snd_wss **rchip);
|
||||
int snd_wss_pcm(struct snd_wss *chip, int device, struct snd_pcm **rpcm);
|
||||
int snd_wss_timer(struct snd_wss *chip, int device, struct snd_timer **rtimer);
|
||||
int snd_wss_mixer(struct snd_wss *chip);
|
||||
|
||||
const struct snd_pcm_ops *snd_wss_get_pcm_ops(int direction);
|
||||
|
||||
int snd_cs4236_create(struct snd_card *card,
|
||||
unsigned long port,
|
||||
unsigned long cport,
|
||||
int irq, int dma1, int dma2,
|
||||
unsigned short hardware,
|
||||
unsigned short hwshare,
|
||||
struct snd_wss **rchip);
|
||||
int snd_cs4236_pcm(struct snd_wss *chip, int device, struct snd_pcm **rpcm);
|
||||
int snd_cs4236_mixer(struct snd_wss *chip);
|
||||
|
||||
/*
|
||||
* mixer library
|
||||
*/
|
||||
|
||||
#define WSS_SINGLE(xname, xindex, reg, shift, mask, invert) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
|
||||
.name = xname, \
|
||||
.index = xindex, \
|
||||
.info = snd_wss_info_single, \
|
||||
.get = snd_wss_get_single, \
|
||||
.put = snd_wss_put_single, \
|
||||
.private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) }
|
||||
|
||||
int snd_wss_info_single(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_info *uinfo);
|
||||
int snd_wss_get_single(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
int snd_wss_put_single(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
|
||||
#define WSS_DOUBLE(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
|
||||
.name = xname, \
|
||||
.index = xindex, \
|
||||
.info = snd_wss_info_double, \
|
||||
.get = snd_wss_get_double, \
|
||||
.put = snd_wss_put_double, \
|
||||
.private_value = left_reg | (right_reg << 8) | (shift_left << 16) | \
|
||||
(shift_right << 19) | (mask << 24) | (invert << 22) }
|
||||
|
||||
#define WSS_SINGLE_TLV(xname, xindex, reg, shift, mask, invert, xtlv) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
|
||||
.name = xname, \
|
||||
.index = xindex, \
|
||||
.info = snd_wss_info_single, \
|
||||
.get = snd_wss_get_single, \
|
||||
.put = snd_wss_put_single, \
|
||||
.private_value = reg | (shift << 8) | (mask << 16) | (invert << 24), \
|
||||
.tlv = { .p = (xtlv) } }
|
||||
|
||||
#define WSS_DOUBLE_TLV(xname, xindex, left_reg, right_reg, \
|
||||
shift_left, shift_right, mask, invert, xtlv) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
|
||||
.name = xname, \
|
||||
.index = xindex, \
|
||||
.info = snd_wss_info_double, \
|
||||
.get = snd_wss_get_double, \
|
||||
.put = snd_wss_put_double, \
|
||||
.private_value = left_reg | (right_reg << 8) | (shift_left << 16) | \
|
||||
(shift_right << 19) | (mask << 24) | (invert << 22), \
|
||||
.tlv = { .p = (xtlv) } }
|
||||
|
||||
|
||||
int snd_wss_info_double(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_info *uinfo);
|
||||
int snd_wss_get_double(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
int snd_wss_put_double(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
|
||||
#endif /* __SOUND_WSS_H */
|
|
@ -28,6 +28,10 @@ menuconfig SOUND
|
|||
|
||||
if SOUND
|
||||
|
||||
config SOUND_OSS_CORE
|
||||
bool
|
||||
default n
|
||||
|
||||
source "sound/oss/dmasound/Kconfig"
|
||||
|
||||
if !M68K
|
||||
|
@ -80,6 +84,7 @@ endif # SND
|
|||
|
||||
menuconfig SOUND_PRIME
|
||||
tristate "Open Sound System (DEPRECATED)"
|
||||
select SOUND_OSS_CORE
|
||||
help
|
||||
Say 'Y' or 'M' to enable Open Sound System drivers.
|
||||
|
||||
|
|
|
@ -654,15 +654,13 @@ static struct snd_kcontrol_new bass_control = {
|
|||
static struct transfer_info tas_transfers[] = {
|
||||
{
|
||||
/* input */
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_BE | SNDRV_PCM_FMTBIT_S16_BE |
|
||||
SNDRV_PCM_FMTBIT_S24_BE | SNDRV_PCM_FMTBIT_S24_BE,
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_BE | SNDRV_PCM_FMTBIT_S24_BE,
|
||||
.rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
|
||||
.transfer_in = 1,
|
||||
},
|
||||
{
|
||||
/* output */
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_BE | SNDRV_PCM_FMTBIT_S16_BE |
|
||||
SNDRV_PCM_FMTBIT_S24_BE | SNDRV_PCM_FMTBIT_S24_BE,
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_BE | SNDRV_PCM_FMTBIT_S24_BE,
|
||||
.rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
|
||||
.transfer_in = 0,
|
||||
},
|
||||
|
|
|
@ -32,11 +32,20 @@ config SND_PXA2XX_PCM
|
|||
tristate
|
||||
select SND_PCM
|
||||
|
||||
config SND_PXA2XX_LIB
|
||||
tristate
|
||||
select SND_AC97_CODEC if SND_PXA2XX_LIB_AC97
|
||||
|
||||
config SND_PXA2XX_LIB_AC97
|
||||
bool
|
||||
|
||||
config SND_PXA2XX_AC97
|
||||
tristate "AC97 driver for the Intel PXA2xx chip"
|
||||
depends on ARCH_PXA
|
||||
select SND_PXA2XX_PCM
|
||||
select SND_AC97_CODEC
|
||||
select SND_PXA2XX_LIB
|
||||
select SND_PXA2XX_LIB_AC97
|
||||
help
|
||||
Say Y or M if you want to support any AC97 codec attached to
|
||||
the PXA2xx AC97 interface.
|
||||
|
|
|
@ -11,5 +11,9 @@ snd-aaci-objs := aaci.o devdma.o
|
|||
obj-$(CONFIG_SND_PXA2XX_PCM) += snd-pxa2xx-pcm.o
|
||||
snd-pxa2xx-pcm-objs := pxa2xx-pcm.o
|
||||
|
||||
obj-$(CONFIG_SND_PXA2XX_LIB) += snd-pxa2xx-lib.o
|
||||
snd-pxa2xx-lib-y := pxa2xx-pcm-lib.o
|
||||
snd-pxa2xx-lib-$(CONFIG_SND_PXA2XX_LIB_AC97) += pxa2xx-ac97-lib.o
|
||||
|
||||
obj-$(CONFIG_SND_PXA2XX_AC97) += snd-pxa2xx-ac97.o
|
||||
snd-pxa2xx-ac97-objs := pxa2xx-ac97.o
|
||||
|
|
|
@ -999,7 +999,7 @@ static struct aaci * __devinit aaci_init_card(struct amba_device *dev)
|
|||
card = snd_card_new(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
|
||||
THIS_MODULE, sizeof(struct aaci));
|
||||
if (card == NULL)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
return NULL;
|
||||
|
||||
card->private_free = aaci_free_card;
|
||||
|
||||
|
@ -1083,8 +1083,8 @@ static int __devinit aaci_probe(struct amba_device *dev, void *id)
|
|||
return ret;
|
||||
|
||||
aaci = aaci_init_card(dev);
|
||||
if (IS_ERR(aaci)) {
|
||||
ret = PTR_ERR(aaci);
|
||||
if (!aaci) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
384
sound/arm/pxa2xx-ac97-lib.c
Normal file
384
sound/arm/pxa2xx-ac97-lib.c
Normal file
|
@ -0,0 +1,384 @@
|
|||
/*
|
||||
* Based on sound/arm/pxa2xx-ac97.c and sound/soc/pxa/pxa2xx-ac97.c
|
||||
* which contain:
|
||||
*
|
||||
* Author: Nicolas Pitre
|
||||
* Created: Dec 02, 2004
|
||||
* Copyright: MontaVista Software Inc.
|
||||
*
|
||||
* 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/kernel.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include <sound/ac97_codec.h>
|
||||
#include <sound/pxa2xx-lib.h>
|
||||
|
||||
#include <asm/irq.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/pxa-regs.h>
|
||||
#include <mach/pxa2xx-gpio.h>
|
||||
#include <mach/audio.h>
|
||||
|
||||
static DEFINE_MUTEX(car_mutex);
|
||||
static DECLARE_WAIT_QUEUE_HEAD(gsr_wq);
|
||||
static volatile long gsr_bits;
|
||||
static struct clk *ac97_clk;
|
||||
static struct clk *ac97conf_clk;
|
||||
|
||||
/*
|
||||
* Beware PXA27x bugs:
|
||||
*
|
||||
* o Slot 12 read from modem space will hang controller.
|
||||
* o CDONE, SDONE interrupt fails after any slot 12 IO.
|
||||
*
|
||||
* We therefore have an hybrid approach for waiting on SDONE (interrupt or
|
||||
* 1 jiffy timeout if interrupt never comes).
|
||||
*/
|
||||
|
||||
unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
|
||||
{
|
||||
unsigned short val = -1;
|
||||
volatile u32 *reg_addr;
|
||||
|
||||
mutex_lock(&car_mutex);
|
||||
|
||||
/* set up primary or secondary codec space */
|
||||
if ((cpu_is_pxa21x() || cpu_is_pxa25x()) && reg == AC97_GPIO_STATUS)
|
||||
reg_addr = ac97->num ? &SMC_REG_BASE : &PMC_REG_BASE;
|
||||
else
|
||||
reg_addr = ac97->num ? &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;
|
||||
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;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* valid data now */
|
||||
GSR = GSR_CDONE | GSR_SDONE;
|
||||
gsr_bits = 0;
|
||||
val = *reg_addr;
|
||||
/* but we've just started another cycle... */
|
||||
wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1);
|
||||
|
||||
out: mutex_unlock(&car_mutex);
|
||||
return val;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pxa2xx_ac97_read);
|
||||
|
||||
void pxa2xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
|
||||
unsigned short val)
|
||||
{
|
||||
volatile u32 *reg_addr;
|
||||
|
||||
mutex_lock(&car_mutex);
|
||||
|
||||
/* set up primary or secondary codec space */
|
||||
if ((cpu_is_pxa21x() || cpu_is_pxa25x()) && reg == AC97_GPIO_STATUS)
|
||||
reg_addr = ac97->num ? &SMC_REG_BASE : &PMC_REG_BASE;
|
||||
else
|
||||
reg_addr = ac97->num ? &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))
|
||||
printk(KERN_ERR "%s: write error (ac97_reg=%d GSR=%#lx)\n",
|
||||
__func__, reg, GSR | gsr_bits);
|
||||
|
||||
mutex_unlock(&car_mutex);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pxa2xx_ac97_write);
|
||||
|
||||
#ifdef CONFIG_PXA25x
|
||||
static inline void pxa_ac97_warm_pxa25x(void)
|
||||
{
|
||||
gsr_bits = 0;
|
||||
|
||||
GCR |= GCR_WARM_RST | GCR_PRIRDY_IEN | GCR_SECRDY_IEN;
|
||||
wait_event_timeout(gsr_wq, gsr_bits & (GSR_PCR | GSR_SCR), 1);
|
||||
}
|
||||
|
||||
static inline void pxa_ac97_cold_pxa25x(void)
|
||||
{
|
||||
GCR &= GCR_COLD_RST; /* clear everything but nCRST */
|
||||
GCR &= ~GCR_COLD_RST; /* then assert nCRST */
|
||||
|
||||
gsr_bits = 0;
|
||||
|
||||
GCR = GCR_COLD_RST;
|
||||
GCR |= GCR_CDONE_IE|GCR_SDONE_IE;
|
||||
wait_event_timeout(gsr_wq, gsr_bits & (GSR_PCR | GSR_SCR), 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PXA27x
|
||||
static inline void pxa_ac97_warm_pxa27x(void)
|
||||
{
|
||||
gsr_bits = 0;
|
||||
|
||||
/* warm reset broken on Bulverde,
|
||||
so manually keep AC97 reset high */
|
||||
pxa_gpio_mode(113 | GPIO_OUT | GPIO_DFLT_HIGH);
|
||||
udelay(10);
|
||||
GCR |= GCR_WARM_RST;
|
||||
pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT);
|
||||
udelay(500);
|
||||
}
|
||||
|
||||
static inline void pxa_ac97_cold_pxa27x(void)
|
||||
{
|
||||
GCR &= GCR_COLD_RST; /* clear everything but nCRST */
|
||||
GCR &= ~GCR_COLD_RST; /* then assert nCRST */
|
||||
|
||||
gsr_bits = 0;
|
||||
|
||||
/* PXA27x Developers Manual section 13.5.2.2.1 */
|
||||
clk_enable(ac97conf_clk);
|
||||
udelay(5);
|
||||
clk_disable(ac97conf_clk);
|
||||
GCR = GCR_COLD_RST;
|
||||
udelay(50);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PXA3xx
|
||||
static inline void pxa_ac97_warm_pxa3xx(void)
|
||||
{
|
||||
int timeout = 100;
|
||||
|
||||
gsr_bits = 0;
|
||||
|
||||
/* Can't use interrupts */
|
||||
GCR |= GCR_WARM_RST;
|
||||
while (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR)) && timeout--)
|
||||
mdelay(1);
|
||||
}
|
||||
|
||||
static inline void pxa_ac97_cold_pxa3xx(void)
|
||||
{
|
||||
int timeout = 1000;
|
||||
|
||||
/* Hold CLKBPB for 100us */
|
||||
GCR = 0;
|
||||
GCR = GCR_CLKBPB;
|
||||
udelay(100);
|
||||
GCR = 0;
|
||||
|
||||
GCR &= GCR_COLD_RST; /* clear everything but nCRST */
|
||||
GCR &= ~GCR_COLD_RST; /* then assert nCRST */
|
||||
|
||||
gsr_bits = 0;
|
||||
|
||||
/* Can't use interrupts on PXA3xx */
|
||||
GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN);
|
||||
|
||||
GCR = GCR_WARM_RST | GCR_COLD_RST;
|
||||
while (!(GSR & (GSR_PCR | GSR_SCR)) && timeout--)
|
||||
mdelay(10);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool pxa2xx_ac97_try_warm_reset(struct snd_ac97 *ac97)
|
||||
{
|
||||
#ifdef CONFIG_PXA25x
|
||||
if (cpu_is_pxa21x() || cpu_is_pxa25x())
|
||||
pxa_ac97_warm_pxa25x();
|
||||
else
|
||||
#endif
|
||||
#ifdef CONFIG_PXA27x
|
||||
if (cpu_is_pxa27x())
|
||||
pxa_ac97_warm_pxa27x();
|
||||
else
|
||||
#endif
|
||||
#ifdef CONFIG_PXA3xx
|
||||
if (cpu_is_pxa3xx())
|
||||
pxa_ac97_warm_pxa3xx();
|
||||
else
|
||||
#endif
|
||||
BUG();
|
||||
|
||||
if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR))) {
|
||||
printk(KERN_INFO "%s: warm reset timeout (GSR=%#lx)\n",
|
||||
__func__, gsr_bits);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pxa2xx_ac97_try_warm_reset);
|
||||
|
||||
bool pxa2xx_ac97_try_cold_reset(struct snd_ac97 *ac97)
|
||||
{
|
||||
#ifdef CONFIG_PXA25x
|
||||
if (cpu_is_pxa21x() || cpu_is_pxa25x())
|
||||
pxa_ac97_cold_pxa25x();
|
||||
else
|
||||
#endif
|
||||
#ifdef CONFIG_PXA27x
|
||||
if (cpu_is_pxa27x())
|
||||
pxa_ac97_cold_pxa27x();
|
||||
else
|
||||
#endif
|
||||
#ifdef CONFIG_PXA3xx
|
||||
if (cpu_is_pxa3xx())
|
||||
pxa_ac97_cold_pxa3xx();
|
||||
else
|
||||
#endif
|
||||
BUG();
|
||||
|
||||
if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR))) {
|
||||
printk(KERN_INFO "%s: cold reset timeout (GSR=%#lx)\n",
|
||||
__func__, gsr_bits);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pxa2xx_ac97_try_cold_reset);
|
||||
|
||||
|
||||
void pxa2xx_ac97_finish_reset(struct snd_ac97 *ac97)
|
||||
{
|
||||
GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN);
|
||||
GCR |= GCR_SDONE_IE|GCR_CDONE_IE;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pxa2xx_ac97_finish_reset);
|
||||
|
||||
static irqreturn_t pxa2xx_ac97_irq(int irq, void *dev_id)
|
||||
{
|
||||
long status;
|
||||
|
||||
status = GSR;
|
||||
if (status) {
|
||||
GSR = status;
|
||||
gsr_bits |= status;
|
||||
wake_up(&gsr_wq);
|
||||
|
||||
/* Although we don't use those we still need to clear them
|
||||
since they tend to spuriously trigger when MMC is used
|
||||
(hardware bug? go figure)... */
|
||||
if (cpu_is_pxa27x()) {
|
||||
MISR = MISR_EOC;
|
||||
PISR = PISR_EOC;
|
||||
MCSR = MCSR_EOC;
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
int pxa2xx_ac97_hw_suspend(void)
|
||||
{
|
||||
GCR |= GCR_ACLINK_OFF;
|
||||
clk_disable(ac97_clk);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_suspend);
|
||||
|
||||
int pxa2xx_ac97_hw_resume(void)
|
||||
{
|
||||
if (cpu_is_pxa21x() || cpu_is_pxa25x() || cpu_is_pxa27x()) {
|
||||
pxa_gpio_mode(GPIO31_SYNC_AC97_MD);
|
||||
pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD);
|
||||
pxa_gpio_mode(GPIO28_BITCLK_AC97_MD);
|
||||
pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD);
|
||||
}
|
||||
if (cpu_is_pxa27x()) {
|
||||
/* Use GPIO 113 as AC97 Reset on Bulverde */
|
||||
pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT);
|
||||
}
|
||||
clk_enable(ac97_clk);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_resume);
|
||||
#endif
|
||||
|
||||
int __devinit pxa2xx_ac97_hw_probe(struct platform_device *dev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = request_irq(IRQ_AC97, pxa2xx_ac97_irq, 0, "AC97", NULL);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
if (cpu_is_pxa21x() || cpu_is_pxa25x() || cpu_is_pxa27x()) {
|
||||
pxa_gpio_mode(GPIO31_SYNC_AC97_MD);
|
||||
pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD);
|
||||
pxa_gpio_mode(GPIO28_BITCLK_AC97_MD);
|
||||
pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD);
|
||||
}
|
||||
|
||||
if (cpu_is_pxa27x()) {
|
||||
/* Use GPIO 113 as AC97 Reset on Bulverde */
|
||||
pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT);
|
||||
ac97conf_clk = clk_get(&dev->dev, "AC97CONFCLK");
|
||||
if (IS_ERR(ac97conf_clk)) {
|
||||
ret = PTR_ERR(ac97conf_clk);
|
||||
ac97conf_clk = NULL;
|
||||
goto err_irq;
|
||||
}
|
||||
}
|
||||
|
||||
ac97_clk = clk_get(&dev->dev, "AC97CLK");
|
||||
if (IS_ERR(ac97_clk)) {
|
||||
ret = PTR_ERR(ac97_clk);
|
||||
ac97_clk = NULL;
|
||||
goto err_irq;
|
||||
}
|
||||
|
||||
return clk_enable(ac97_clk);
|
||||
|
||||
err_irq:
|
||||
GCR |= GCR_ACLINK_OFF;
|
||||
if (ac97conf_clk) {
|
||||
clk_put(ac97conf_clk);
|
||||
ac97conf_clk = NULL;
|
||||
}
|
||||
free_irq(IRQ_AC97, NULL);
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_probe);
|
||||
|
||||
void pxa2xx_ac97_hw_remove(struct platform_device *dev)
|
||||
{
|
||||
GCR |= GCR_ACLINK_OFF;
|
||||
free_irq(IRQ_AC97, NULL);
|
||||
if (ac97conf_clk) {
|
||||
clk_put(ac97conf_clk);
|
||||
ac97conf_clk = NULL;
|
||||
}
|
||||
clk_disable(ac97_clk);
|
||||
clk_put(ac97_clk);
|
||||
ac97_clk = NULL;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_remove);
|
||||
|
||||
MODULE_AUTHOR("Nicolas Pitre");
|
||||
MODULE_DESCRIPTION("Intel/Marvell PXA sound library");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
@ -12,198 +12,27 @@
|
|||
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include <sound/core.h>
|
||||
#include <sound/pcm.h>
|
||||
#include <sound/ac97_codec.h>
|
||||
#include <sound/initval.h>
|
||||
#include <sound/pxa2xx-lib.h>
|
||||
|
||||
#include <asm/irq.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/pxa-regs.h>
|
||||
#include <mach/pxa2xx-gpio.h>
|
||||
#include <mach/audio.h>
|
||||
|
||||
#include "pxa2xx-pcm.h"
|
||||
|
||||
|
||||
static DEFINE_MUTEX(car_mutex);
|
||||
static DECLARE_WAIT_QUEUE_HEAD(gsr_wq);
|
||||
static volatile long gsr_bits;
|
||||
static struct clk *ac97_clk;
|
||||
#ifdef CONFIG_PXA27x
|
||||
static struct clk *ac97conf_clk;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Beware PXA27x bugs:
|
||||
*
|
||||
* o Slot 12 read from modem space will hang controller.
|
||||
* o CDONE, SDONE interrupt fails after any slot 12 IO.
|
||||
*
|
||||
* We therefore have an hybrid approach for waiting on SDONE (interrupt or
|
||||
* 1 jiffy timeout if interrupt never comes).
|
||||
*/
|
||||
|
||||
static unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
|
||||
{
|
||||
unsigned short val = -1;
|
||||
volatile u32 *reg_addr;
|
||||
|
||||
mutex_lock(&car_mutex);
|
||||
|
||||
/* set up primary or secondary codec space */
|
||||
reg_addr = (ac97->num & 1) ? &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;
|
||||
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;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* valid data now */
|
||||
GSR = GSR_CDONE | GSR_SDONE;
|
||||
gsr_bits = 0;
|
||||
val = *reg_addr;
|
||||
/* but we've just started another cycle... */
|
||||
wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1);
|
||||
|
||||
out: mutex_unlock(&car_mutex);
|
||||
return val;
|
||||
}
|
||||
|
||||
static void pxa2xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val)
|
||||
{
|
||||
volatile u32 *reg_addr;
|
||||
|
||||
mutex_lock(&car_mutex);
|
||||
|
||||
/* set up primary or secondary codec space */
|
||||
reg_addr = (ac97->num & 1) ? &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))
|
||||
printk(KERN_ERR "%s: write error (ac97_reg=%d GSR=%#lx)\n",
|
||||
__func__, reg, GSR | gsr_bits);
|
||||
|
||||
mutex_unlock(&car_mutex);
|
||||
}
|
||||
|
||||
static void pxa2xx_ac97_reset(struct snd_ac97 *ac97)
|
||||
{
|
||||
/* First, try cold reset */
|
||||
#ifdef CONFIG_PXA3xx
|
||||
int timeout;
|
||||
|
||||
/* Hold CLKBPB for 100us */
|
||||
GCR = 0;
|
||||
GCR = GCR_CLKBPB;
|
||||
udelay(100);
|
||||
GCR = 0;
|
||||
#endif
|
||||
|
||||
GCR &= GCR_COLD_RST; /* clear everything but nCRST */
|
||||
GCR &= ~GCR_COLD_RST; /* then assert nCRST */
|
||||
|
||||
gsr_bits = 0;
|
||||
#ifdef CONFIG_PXA27x
|
||||
/* PXA27x Developers Manual section 13.5.2.2.1 */
|
||||
clk_enable(ac97conf_clk);
|
||||
udelay(5);
|
||||
clk_disable(ac97conf_clk);
|
||||
GCR = GCR_COLD_RST;
|
||||
udelay(50);
|
||||
#elif defined(CONFIG_PXA3xx)
|
||||
timeout = 1000;
|
||||
/* Can't use interrupts on PXA3xx */
|
||||
GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN);
|
||||
|
||||
GCR = GCR_WARM_RST | GCR_COLD_RST;
|
||||
while (!(GSR & (GSR_PCR | GSR_SCR)) && timeout--)
|
||||
mdelay(10);
|
||||
#else
|
||||
GCR = GCR_COLD_RST;
|
||||
GCR |= GCR_CDONE_IE|GCR_SDONE_IE;
|
||||
wait_event_timeout(gsr_wq, gsr_bits & (GSR_PCR | GSR_SCR), 1);
|
||||
#endif
|
||||
|
||||
if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR))) {
|
||||
printk(KERN_INFO "%s: cold reset timeout (GSR=%#lx)\n",
|
||||
__func__, gsr_bits);
|
||||
|
||||
/* let's try warm reset */
|
||||
gsr_bits = 0;
|
||||
#ifdef CONFIG_PXA27x
|
||||
/* warm reset broken on Bulverde,
|
||||
so manually keep AC97 reset high */
|
||||
pxa_gpio_mode(113 | GPIO_OUT | GPIO_DFLT_HIGH);
|
||||
udelay(10);
|
||||
GCR |= GCR_WARM_RST;
|
||||
pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT);
|
||||
udelay(500);
|
||||
#elif defined(CONFIG_PXA3xx)
|
||||
timeout = 100;
|
||||
/* Can't use interrupts */
|
||||
GCR |= GCR_WARM_RST;
|
||||
while (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR)) && timeout--)
|
||||
mdelay(1);
|
||||
#else
|
||||
GCR |= GCR_WARM_RST|GCR_PRIRDY_IEN|GCR_SECRDY_IEN;
|
||||
wait_event_timeout(gsr_wq, gsr_bits & (GSR_PCR | GSR_SCR), 1);
|
||||
#endif
|
||||
|
||||
if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR)))
|
||||
printk(KERN_INFO "%s: warm reset timeout (GSR=%#lx)\n",
|
||||
__func__, gsr_bits);
|
||||
if (!pxa2xx_ac97_try_cold_reset(ac97)) {
|
||||
pxa2xx_ac97_try_warm_reset(ac97);
|
||||
}
|
||||
|
||||
GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN);
|
||||
GCR |= GCR_SDONE_IE|GCR_CDONE_IE;
|
||||
}
|
||||
|
||||
static irqreturn_t pxa2xx_ac97_irq(int irq, void *dev_id)
|
||||
{
|
||||
long status;
|
||||
|
||||
status = GSR;
|
||||
if (status) {
|
||||
GSR = status;
|
||||
gsr_bits |= status;
|
||||
wake_up(&gsr_wq);
|
||||
|
||||
#ifdef CONFIG_PXA27x
|
||||
/* Although we don't use those we still need to clear them
|
||||
since they tend to spuriously trigger when MMC is used
|
||||
(hardware bug? go figure)... */
|
||||
MISR = MISR_EOC;
|
||||
PISR = PISR_EOC;
|
||||
MCSR = MCSR_EOC;
|
||||
#endif
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
return IRQ_NONE;
|
||||
pxa2xx_ac97_finish_reset(ac97);
|
||||
}
|
||||
|
||||
static struct snd_ac97_bus_ops pxa2xx_ac97_ops = {
|
||||
|
@ -288,17 +117,19 @@ static int pxa2xx_ac97_do_suspend(struct snd_card *card, pm_message_t state)
|
|||
snd_ac97_suspend(pxa2xx_ac97_ac97);
|
||||
if (platform_ops && platform_ops->suspend)
|
||||
platform_ops->suspend(platform_ops->priv);
|
||||
GCR |= GCR_ACLINK_OFF;
|
||||
clk_disable(ac97_clk);
|
||||
|
||||
return 0;
|
||||
return pxa2xx_ac97_hw_suspend();
|
||||
}
|
||||
|
||||
static int pxa2xx_ac97_do_resume(struct snd_card *card)
|
||||
{
|
||||
pxa2xx_audio_ops_t *platform_ops = card->dev->platform_data;
|
||||
int rc;
|
||||
|
||||
rc = pxa2xx_ac97_hw_resume();
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
clk_enable(ac97_clk);
|
||||
if (platform_ops && platform_ops->resume)
|
||||
platform_ops->resume(platform_ops->priv);
|
||||
snd_ac97_resume(pxa2xx_ac97_ac97);
|
||||
|
@ -354,40 +185,17 @@ static int __devinit pxa2xx_ac97_probe(struct platform_device *dev)
|
|||
if (ret)
|
||||
goto err;
|
||||
|
||||
ret = request_irq(IRQ_AC97, pxa2xx_ac97_irq, 0, "AC97", NULL);
|
||||
if (ret < 0)
|
||||
ret = pxa2xx_ac97_hw_probe(dev);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
pxa_gpio_mode(GPIO31_SYNC_AC97_MD);
|
||||
pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD);
|
||||
pxa_gpio_mode(GPIO28_BITCLK_AC97_MD);
|
||||
pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD);
|
||||
#ifdef CONFIG_PXA27x
|
||||
/* Use GPIO 113 as AC97 Reset on Bulverde */
|
||||
pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT);
|
||||
ac97conf_clk = clk_get(&dev->dev, "AC97CONFCLK");
|
||||
if (IS_ERR(ac97conf_clk)) {
|
||||
ret = PTR_ERR(ac97conf_clk);
|
||||
ac97conf_clk = NULL;
|
||||
goto err;
|
||||
}
|
||||
#endif
|
||||
|
||||
ac97_clk = clk_get(&dev->dev, "AC97CLK");
|
||||
if (IS_ERR(ac97_clk)) {
|
||||
ret = PTR_ERR(ac97_clk);
|
||||
ac97_clk = NULL;
|
||||
goto err;
|
||||
}
|
||||
clk_enable(ac97_clk);
|
||||
|
||||
ret = snd_ac97_bus(card, 0, &pxa2xx_ac97_ops, NULL, &ac97_bus);
|
||||
if (ret)
|
||||
goto err;
|
||||
goto err_remove;
|
||||
memset(&ac97_template, 0, sizeof(ac97_template));
|
||||
ret = snd_ac97_mixer(ac97_bus, &ac97_template, &pxa2xx_ac97_ac97);
|
||||
if (ret)
|
||||
goto err;
|
||||
goto err_remove;
|
||||
|
||||
snprintf(card->shortname, sizeof(card->shortname),
|
||||
"%s", snd_ac97_get_short_name(pxa2xx_ac97_ac97));
|
||||
|
@ -401,22 +209,11 @@ static int __devinit pxa2xx_ac97_probe(struct platform_device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
err:
|
||||
err_remove:
|
||||
pxa2xx_ac97_hw_remove(dev);
|
||||
err:
|
||||
if (card)
|
||||
snd_card_free(card);
|
||||
if (ac97_clk) {
|
||||
GCR |= GCR_ACLINK_OFF;
|
||||
free_irq(IRQ_AC97, NULL);
|
||||
clk_disable(ac97_clk);
|
||||
clk_put(ac97_clk);
|
||||
ac97_clk = NULL;
|
||||
}
|
||||
#ifdef CONFIG_PXA27x
|
||||
if (ac97conf_clk) {
|
||||
clk_put(ac97conf_clk);
|
||||
ac97conf_clk = NULL;
|
||||
}
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -427,15 +224,7 @@ static int __devexit pxa2xx_ac97_remove(struct platform_device *dev)
|
|||
if (card) {
|
||||
snd_card_free(card);
|
||||
platform_set_drvdata(dev, NULL);
|
||||
GCR |= GCR_ACLINK_OFF;
|
||||
free_irq(IRQ_AC97, NULL);
|
||||
clk_disable(ac97_clk);
|
||||
clk_put(ac97_clk);
|
||||
ac97_clk = NULL;
|
||||
#ifdef CONFIG_PXA27x
|
||||
clk_put(ac97conf_clk);
|
||||
ac97conf_clk = NULL;
|
||||
#endif
|
||||
pxa2xx_ac97_hw_remove(dev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
278
sound/arm/pxa2xx-pcm-lib.c
Normal file
278
sound/arm/pxa2xx-pcm-lib.c
Normal file
|
@ -0,0 +1,278 @@
|
|||
/*
|
||||
* 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/dma-mapping.h>
|
||||
|
||||
#include <sound/core.h>
|
||||
#include <sound/pcm.h>
|
||||
#include <sound/pcm_params.h>
|
||||
#include <sound/pxa2xx-lib.h>
|
||||
|
||||
#include <asm/dma.h>
|
||||
#include <mach/pxa-regs.h>
|
||||
|
||||
#include "pxa2xx-pcm.h"
|
||||
|
||||
static const struct snd_pcm_hardware pxa2xx_pcm_hardware = {
|
||||
.info = SNDRV_PCM_INFO_MMAP |
|
||||
SNDRV_PCM_INFO_MMAP_VALID |
|
||||
SNDRV_PCM_INFO_INTERLEAVED |
|
||||
SNDRV_PCM_INFO_PAUSE |
|
||||
SNDRV_PCM_INFO_RESUME,
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_LE |
|
||||
SNDRV_PCM_FMTBIT_S24_LE |
|
||||
SNDRV_PCM_FMTBIT_S32_LE,
|
||||
.period_bytes_min = 32,
|
||||
.period_bytes_max = 8192 - 32,
|
||||
.periods_min = 1,
|
||||
.periods_max = PAGE_SIZE/sizeof(pxa_dma_desc),
|
||||
.buffer_bytes_max = 128 * 1024,
|
||||
.fifo_size = 32,
|
||||
};
|
||||
|
||||
int __pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params)
|
||||
{
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
struct pxa2xx_runtime_data *rtd = runtime->private_data;
|
||||
size_t totsize = params_buffer_bytes(params);
|
||||
size_t period = params_period_bytes(params);
|
||||
pxa_dma_desc *dma_desc;
|
||||
dma_addr_t dma_buff_phys, next_desc_phys;
|
||||
|
||||
snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
|
||||
runtime->dma_bytes = totsize;
|
||||
|
||||
dma_desc = rtd->dma_desc_array;
|
||||
next_desc_phys = rtd->dma_desc_array_phys;
|
||||
dma_buff_phys = runtime->dma_addr;
|
||||
do {
|
||||
next_desc_phys += sizeof(pxa_dma_desc);
|
||||
dma_desc->ddadr = next_desc_phys;
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
dma_desc->dsadr = dma_buff_phys;
|
||||
dma_desc->dtadr = rtd->params->dev_addr;
|
||||
} else {
|
||||
dma_desc->dsadr = rtd->params->dev_addr;
|
||||
dma_desc->dtadr = dma_buff_phys;
|
||||
}
|
||||
if (period > totsize)
|
||||
period = totsize;
|
||||
dma_desc->dcmd = rtd->params->dcmd | period | DCMD_ENDIRQEN;
|
||||
dma_desc++;
|
||||
dma_buff_phys += period;
|
||||
} while (totsize -= period);
|
||||
dma_desc[-1].ddadr = rtd->dma_desc_array_phys;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(__pxa2xx_pcm_hw_params);
|
||||
|
||||
int __pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct pxa2xx_runtime_data *rtd = substream->runtime->private_data;
|
||||
|
||||
if (rtd && rtd->params)
|
||||
*rtd->params->drcmr = 0;
|
||||
|
||||
snd_pcm_set_runtime_buffer(substream, NULL);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(__pxa2xx_pcm_hw_free);
|
||||
|
||||
int pxa2xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
|
||||
{
|
||||
struct pxa2xx_runtime_data *prtd = substream->runtime->private_data;
|
||||
int ret = 0;
|
||||
|
||||
switch (cmd) {
|
||||
case SNDRV_PCM_TRIGGER_START:
|
||||
DDADR(prtd->dma_ch) = prtd->dma_desc_array_phys;
|
||||
DCSR(prtd->dma_ch) = DCSR_RUN;
|
||||
break;
|
||||
|
||||
case SNDRV_PCM_TRIGGER_STOP:
|
||||
case SNDRV_PCM_TRIGGER_SUSPEND:
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
|
||||
DCSR(prtd->dma_ch) &= ~DCSR_RUN;
|
||||
break;
|
||||
|
||||
case SNDRV_PCM_TRIGGER_RESUME:
|
||||
DCSR(prtd->dma_ch) |= DCSR_RUN;
|
||||
break;
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
|
||||
DDADR(prtd->dma_ch) = prtd->dma_desc_array_phys;
|
||||
DCSR(prtd->dma_ch) |= DCSR_RUN;
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(pxa2xx_pcm_trigger);
|
||||
|
||||
snd_pcm_uframes_t
|
||||
pxa2xx_pcm_pointer(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
struct pxa2xx_runtime_data *prtd = runtime->private_data;
|
||||
|
||||
dma_addr_t ptr = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
|
||||
DSADR(prtd->dma_ch) : DTADR(prtd->dma_ch);
|
||||
snd_pcm_uframes_t x = bytes_to_frames(runtime, ptr - runtime->dma_addr);
|
||||
|
||||
if (x == runtime->buffer_size)
|
||||
x = 0;
|
||||
return x;
|
||||
}
|
||||
EXPORT_SYMBOL(pxa2xx_pcm_pointer);
|
||||
|
||||
int __pxa2xx_pcm_prepare(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct pxa2xx_runtime_data *prtd = substream->runtime->private_data;
|
||||
|
||||
DCSR(prtd->dma_ch) &= ~DCSR_RUN;
|
||||
DCSR(prtd->dma_ch) = 0;
|
||||
DCMD(prtd->dma_ch) = 0;
|
||||
*prtd->params->drcmr = prtd->dma_ch | DRCMR_MAPVLD;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(__pxa2xx_pcm_prepare);
|
||||
|
||||
void pxa2xx_pcm_dma_irq(int dma_ch, void *dev_id)
|
||||
{
|
||||
struct snd_pcm_substream *substream = dev_id;
|
||||
struct pxa2xx_runtime_data *rtd = substream->runtime->private_data;
|
||||
int dcsr;
|
||||
|
||||
dcsr = DCSR(dma_ch);
|
||||
DCSR(dma_ch) = dcsr & ~DCSR_STOPIRQEN;
|
||||
|
||||
if (dcsr & DCSR_ENDINTR) {
|
||||
snd_pcm_period_elapsed(substream);
|
||||
} else {
|
||||
printk(KERN_ERR "%s: DMA error on channel %d (DCSR=%#x)\n",
|
||||
rtd->params->name, dma_ch, dcsr);
|
||||
snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(pxa2xx_pcm_dma_irq);
|
||||
|
||||
int __pxa2xx_pcm_open(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
struct pxa2xx_runtime_data *rtd;
|
||||
int ret;
|
||||
|
||||
runtime->hw = pxa2xx_pcm_hardware;
|
||||
|
||||
/*
|
||||
* For mysterious reasons (and despite what the manual says)
|
||||
* playback samples are lost if the DMA count is not a multiple
|
||||
* of the DMA burst size. Let's add a rule to enforce that.
|
||||
*/
|
||||
ret = snd_pcm_hw_constraint_step(runtime, 0,
|
||||
SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 32);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = snd_pcm_hw_constraint_step(runtime, 0,
|
||||
SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 32);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = snd_pcm_hw_constraint_integer(runtime,
|
||||
SNDRV_PCM_HW_PARAM_PERIODS);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
ret = -ENOMEM;
|
||||
rtd = kmalloc(sizeof(*rtd), GFP_KERNEL);
|
||||
if (!rtd)
|
||||
goto out;
|
||||
rtd->dma_desc_array =
|
||||
dma_alloc_writecombine(substream->pcm->card->dev, PAGE_SIZE,
|
||||
&rtd->dma_desc_array_phys, GFP_KERNEL);
|
||||
if (!rtd->dma_desc_array)
|
||||
goto err1;
|
||||
|
||||
runtime->private_data = rtd;
|
||||
return 0;
|
||||
|
||||
err1:
|
||||
kfree(rtd);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(__pxa2xx_pcm_open);
|
||||
|
||||
int __pxa2xx_pcm_close(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
struct pxa2xx_runtime_data *rtd = runtime->private_data;
|
||||
|
||||
dma_free_writecombine(substream->pcm->card->dev, PAGE_SIZE,
|
||||
rtd->dma_desc_array, rtd->dma_desc_array_phys);
|
||||
kfree(rtd);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(__pxa2xx_pcm_close);
|
||||
|
||||
int pxa2xx_pcm_mmap(struct snd_pcm_substream *substream,
|
||||
struct vm_area_struct *vma)
|
||||
{
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
return dma_mmap_writecombine(substream->pcm->card->dev, vma,
|
||||
runtime->dma_area,
|
||||
runtime->dma_addr,
|
||||
runtime->dma_bytes);
|
||||
}
|
||||
EXPORT_SYMBOL(pxa2xx_pcm_mmap);
|
||||
|
||||
int pxa2xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
|
||||
{
|
||||
struct snd_pcm_substream *substream = pcm->streams[stream].substream;
|
||||
struct snd_dma_buffer *buf = &substream->dma_buffer;
|
||||
size_t size = pxa2xx_pcm_hardware.buffer_bytes_max;
|
||||
buf->dev.type = SNDRV_DMA_TYPE_DEV;
|
||||
buf->dev.dev = pcm->card->dev;
|
||||
buf->private_data = NULL;
|
||||
buf->area = dma_alloc_writecombine(pcm->card->dev, size,
|
||||
&buf->addr, GFP_KERNEL);
|
||||
if (!buf->area)
|
||||
return -ENOMEM;
|
||||
buf->bytes = size;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(pxa2xx_pcm_preallocate_dma_buffer);
|
||||
|
||||
void pxa2xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
|
||||
{
|
||||
struct snd_pcm_substream *substream;
|
||||
struct snd_dma_buffer *buf;
|
||||
int stream;
|
||||
|
||||
for (stream = 0; stream < 2; stream++) {
|
||||
substream = pcm->streams[stream].substream;
|
||||
if (!substream)
|
||||
continue;
|
||||
buf = &substream->dma_buffer;
|
||||
if (!buf->area)
|
||||
continue;
|
||||
dma_free_writecombine(pcm->card->dev, buf->bytes,
|
||||
buf->area, buf->addr);
|
||||
buf->area = NULL;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(pxa2xx_pcm_free_dma_buffers);
|
||||
|
||||
MODULE_AUTHOR("Nicolas Pitre");
|
||||
MODULE_DESCRIPTION("Intel PXA2xx sound library");
|
||||
MODULE_LICENSE("GPL");
|
|
@ -10,183 +10,20 @@
|
|||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
|
||||
#include <sound/core.h>
|
||||
#include <sound/pcm.h>
|
||||
#include <sound/pcm_params.h>
|
||||
|
||||
#include <asm/dma.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/pxa-regs.h>
|
||||
#include <sound/pxa2xx-lib.h>
|
||||
|
||||
#include "pxa2xx-pcm.h"
|
||||
|
||||
|
||||
static const struct snd_pcm_hardware pxa2xx_pcm_hardware = {
|
||||
.info = SNDRV_PCM_INFO_MMAP |
|
||||
SNDRV_PCM_INFO_MMAP_VALID |
|
||||
SNDRV_PCM_INFO_INTERLEAVED |
|
||||
SNDRV_PCM_INFO_PAUSE,
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_LE,
|
||||
.period_bytes_min = 32,
|
||||
.period_bytes_max = 8192 - 32,
|
||||
.periods_min = 1,
|
||||
.periods_max = PAGE_SIZE/sizeof(pxa_dma_desc),
|
||||
.buffer_bytes_max = 128 * 1024,
|
||||
.fifo_size = 32,
|
||||
};
|
||||
|
||||
struct pxa2xx_runtime_data {
|
||||
int dma_ch;
|
||||
struct pxa2xx_pcm_dma_params *params;
|
||||
pxa_dma_desc *dma_desc_array;
|
||||
dma_addr_t dma_desc_array_phys;
|
||||
};
|
||||
|
||||
static int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params)
|
||||
{
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
struct pxa2xx_runtime_data *rtd = runtime->private_data;
|
||||
size_t totsize = params_buffer_bytes(params);
|
||||
size_t period = params_period_bytes(params);
|
||||
pxa_dma_desc *dma_desc;
|
||||
dma_addr_t dma_buff_phys, next_desc_phys;
|
||||
|
||||
snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
|
||||
runtime->dma_bytes = totsize;
|
||||
|
||||
dma_desc = rtd->dma_desc_array;
|
||||
next_desc_phys = rtd->dma_desc_array_phys;
|
||||
dma_buff_phys = runtime->dma_addr;
|
||||
do {
|
||||
next_desc_phys += sizeof(pxa_dma_desc);
|
||||
dma_desc->ddadr = next_desc_phys;
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
dma_desc->dsadr = dma_buff_phys;
|
||||
dma_desc->dtadr = rtd->params->dev_addr;
|
||||
} else {
|
||||
dma_desc->dsadr = rtd->params->dev_addr;
|
||||
dma_desc->dtadr = dma_buff_phys;
|
||||
}
|
||||
if (period > totsize)
|
||||
period = totsize;
|
||||
dma_desc->dcmd = rtd->params->dcmd | period | DCMD_ENDIRQEN;
|
||||
dma_desc++;
|
||||
dma_buff_phys += period;
|
||||
} while (totsize -= period);
|
||||
dma_desc[-1].ddadr = rtd->dma_desc_array_phys;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct pxa2xx_runtime_data *rtd = substream->runtime->private_data;
|
||||
|
||||
*rtd->params->drcmr = 0;
|
||||
snd_pcm_set_runtime_buffer(substream, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pxa2xx_pcm_prepare(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct pxa2xx_pcm_client *client = substream->private_data;
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
struct pxa2xx_runtime_data *rtd = runtime->private_data;
|
||||
|
||||
DCSR(rtd->dma_ch) &= ~DCSR_RUN;
|
||||
DCSR(rtd->dma_ch) = 0;
|
||||
DCMD(rtd->dma_ch) = 0;
|
||||
*rtd->params->drcmr = rtd->dma_ch | DRCMR_MAPVLD;
|
||||
__pxa2xx_pcm_prepare(substream);
|
||||
|
||||
return client->prepare(substream);
|
||||
}
|
||||
|
||||
static int pxa2xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
|
||||
{
|
||||
struct pxa2xx_runtime_data *rtd = substream->runtime->private_data;
|
||||
int ret = 0;
|
||||
|
||||
switch (cmd) {
|
||||
case SNDRV_PCM_TRIGGER_START:
|
||||
DDADR(rtd->dma_ch) = rtd->dma_desc_array_phys;
|
||||
DCSR(rtd->dma_ch) = DCSR_RUN;
|
||||
break;
|
||||
|
||||
case SNDRV_PCM_TRIGGER_STOP:
|
||||
case SNDRV_PCM_TRIGGER_SUSPEND:
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
|
||||
DCSR(rtd->dma_ch) &= ~DCSR_RUN;
|
||||
break;
|
||||
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
|
||||
DCSR(rtd->dma_ch) |= DCSR_RUN;
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void pxa2xx_pcm_dma_irq(int dma_ch, void *dev_id)
|
||||
{
|
||||
struct snd_pcm_substream *substream = dev_id;
|
||||
struct pxa2xx_runtime_data *rtd = substream->runtime->private_data;
|
||||
int dcsr;
|
||||
|
||||
dcsr = DCSR(dma_ch);
|
||||
DCSR(dma_ch) = dcsr & ~DCSR_STOPIRQEN;
|
||||
|
||||
if (dcsr & DCSR_ENDINTR) {
|
||||
snd_pcm_period_elapsed(substream);
|
||||
} else {
|
||||
printk( KERN_ERR "%s: DMA error on channel %d (DCSR=%#x)\n",
|
||||
rtd->params->name, dma_ch, dcsr );
|
||||
snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
|
||||
}
|
||||
}
|
||||
|
||||
static snd_pcm_uframes_t pxa2xx_pcm_pointer(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
struct pxa2xx_runtime_data *rtd = runtime->private_data;
|
||||
dma_addr_t ptr = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
|
||||
DSADR(rtd->dma_ch) : DTADR(rtd->dma_ch);
|
||||
snd_pcm_uframes_t x = bytes_to_frames(runtime, ptr - runtime->dma_addr);
|
||||
if (x == runtime->buffer_size)
|
||||
x = 0;
|
||||
return x;
|
||||
}
|
||||
|
||||
static int
|
||||
pxa2xx_pcm_hw_rule_mult32(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule)
|
||||
{
|
||||
struct snd_interval *i = hw_param_interval(params, rule->var);
|
||||
int changed = 0;
|
||||
|
||||
if (i->min & 31) {
|
||||
i->min = (i->min & ~31) + 32;
|
||||
i->openmin = 0;
|
||||
changed = 1;
|
||||
}
|
||||
|
||||
if (i->max & 31) {
|
||||
i->max &= ~31;
|
||||
i->openmax = 0;
|
||||
changed = 1;
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
static int pxa2xx_pcm_open(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct pxa2xx_pcm_client *client = substream->private_data;
|
||||
|
@ -194,33 +31,11 @@ static int pxa2xx_pcm_open(struct snd_pcm_substream *substream)
|
|||
struct pxa2xx_runtime_data *rtd;
|
||||
int ret;
|
||||
|
||||
runtime->hw = pxa2xx_pcm_hardware;
|
||||
|
||||
/*
|
||||
* For mysterious reasons (and despite what the manual says)
|
||||
* playback samples are lost if the DMA count is not a multiple
|
||||
* of the DMA burst size. Let's add a rule to enforce that.
|
||||
*/
|
||||
ret = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
|
||||
pxa2xx_pcm_hw_rule_mult32, NULL,
|
||||
SNDRV_PCM_HW_PARAM_PERIOD_BYTES, -1);
|
||||
if (ret)
|
||||
goto out;
|
||||
ret = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
|
||||
pxa2xx_pcm_hw_rule_mult32, NULL,
|
||||
SNDRV_PCM_HW_PARAM_BUFFER_BYTES, -1);
|
||||
ret = __pxa2xx_pcm_open(substream);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = -ENOMEM;
|
||||
rtd = kmalloc(sizeof(*rtd), GFP_KERNEL);
|
||||
if (!rtd)
|
||||
goto out;
|
||||
rtd->dma_desc_array =
|
||||
dma_alloc_writecombine(substream->pcm->card->dev, PAGE_SIZE,
|
||||
&rtd->dma_desc_array_phys, GFP_KERNEL);
|
||||
if (!rtd->dma_desc_array)
|
||||
goto err1;
|
||||
rtd = runtime->private_data;
|
||||
|
||||
rtd->params = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
|
||||
client->playback_params : client->capture_params;
|
||||
|
@ -230,17 +45,13 @@ static int pxa2xx_pcm_open(struct snd_pcm_substream *substream)
|
|||
goto err2;
|
||||
rtd->dma_ch = ret;
|
||||
|
||||
runtime->private_data = rtd;
|
||||
ret = client->startup(substream);
|
||||
if (!ret)
|
||||
goto out;
|
||||
|
||||
pxa_free_dma(rtd->dma_ch);
|
||||
err2:
|
||||
dma_free_writecombine(substream->pcm->card->dev, PAGE_SIZE,
|
||||
rtd->dma_desc_array, rtd->dma_desc_array_phys);
|
||||
err1:
|
||||
kfree(rtd);
|
||||
__pxa2xx_pcm_close(substream);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
@ -252,69 +63,22 @@ static int pxa2xx_pcm_close(struct snd_pcm_substream *substream)
|
|||
|
||||
pxa_free_dma(rtd->dma_ch);
|
||||
client->shutdown(substream);
|
||||
dma_free_writecombine(substream->pcm->card->dev, PAGE_SIZE,
|
||||
rtd->dma_desc_array, rtd->dma_desc_array_phys);
|
||||
kfree(rtd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pxa2xx_pcm_mmap(struct snd_pcm_substream *substream, struct vm_area_struct *vma)
|
||||
{
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
return dma_mmap_writecombine(substream->pcm->card->dev, vma,
|
||||
runtime->dma_area,
|
||||
runtime->dma_addr,
|
||||
runtime->dma_bytes);
|
||||
return __pxa2xx_pcm_close(substream);
|
||||
}
|
||||
|
||||
static struct snd_pcm_ops pxa2xx_pcm_ops = {
|
||||
.open = pxa2xx_pcm_open,
|
||||
.close = pxa2xx_pcm_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
.hw_params = pxa2xx_pcm_hw_params,
|
||||
.hw_free = pxa2xx_pcm_hw_free,
|
||||
.hw_params = __pxa2xx_pcm_hw_params,
|
||||
.hw_free = __pxa2xx_pcm_hw_free,
|
||||
.prepare = pxa2xx_pcm_prepare,
|
||||
.trigger = pxa2xx_pcm_trigger,
|
||||
.pointer = pxa2xx_pcm_pointer,
|
||||
.mmap = pxa2xx_pcm_mmap,
|
||||
};
|
||||
|
||||
static int pxa2xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
|
||||
{
|
||||
struct snd_pcm_substream *substream = pcm->streams[stream].substream;
|
||||
struct snd_dma_buffer *buf = &substream->dma_buffer;
|
||||
size_t size = pxa2xx_pcm_hardware.buffer_bytes_max;
|
||||
buf->dev.type = SNDRV_DMA_TYPE_DEV;
|
||||
buf->dev.dev = pcm->card->dev;
|
||||
buf->private_data = NULL;
|
||||
buf->area = dma_alloc_writecombine(pcm->card->dev, size,
|
||||
&buf->addr, GFP_KERNEL);
|
||||
if (!buf->area)
|
||||
return -ENOMEM;
|
||||
buf->bytes = size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pxa2xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
|
||||
{
|
||||
struct snd_pcm_substream *substream;
|
||||
struct snd_dma_buffer *buf;
|
||||
int stream;
|
||||
|
||||
for (stream = 0; stream < 2; stream++) {
|
||||
substream = pcm->streams[stream].substream;
|
||||
if (!substream)
|
||||
continue;
|
||||
buf = &substream->dma_buffer;
|
||||
if (!buf->area)
|
||||
continue;
|
||||
dma_free_writecombine(pcm->card->dev, buf->bytes,
|
||||
buf->area, buf->addr);
|
||||
buf->area = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static u64 pxa2xx_pcm_dmamask = 0xffffffff;
|
||||
|
||||
int pxa2xx_pcm_new(struct snd_card *card, struct pxa2xx_pcm_client *client,
|
||||
|
|
|
@ -9,14 +9,15 @@
|
|||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#include <asm/dma.h>
|
||||
|
||||
struct pxa2xx_pcm_dma_params {
|
||||
char *name; /* stream identifier */
|
||||
u32 dcmd; /* DMA descriptor dcmd field */
|
||||
volatile u32 *drcmr; /* the DMA request channel to use */
|
||||
u32 dev_addr; /* device physical address for DMA */
|
||||
struct pxa2xx_runtime_data {
|
||||
int dma_ch;
|
||||
struct pxa2xx_pcm_dma_params *params;
|
||||
pxa_dma_desc *dma_desc_array;
|
||||
dma_addr_t dma_desc_array_phys;
|
||||
};
|
||||
|
||||
|
||||
struct pxa2xx_pcm_client {
|
||||
struct pxa2xx_pcm_dma_params *playback_params;
|
||||
struct pxa2xx_pcm_dma_params *capture_params;
|
||||
|
|
|
@ -442,7 +442,8 @@ static void audio_process_dma(struct audio_stream *s)
|
|||
|
||||
/* we are requested to process synchronization DMA transfer */
|
||||
if (s->tx_spin) {
|
||||
snd_assert(s->stream_id == SNDRV_PCM_STREAM_PLAYBACK, return);
|
||||
if (snd_BUG_ON(s->stream_id != SNDRV_PCM_STREAM_PLAYBACK))
|
||||
return;
|
||||
/* fill the xmit dma buffers and return */
|
||||
#ifdef HH_VERSION
|
||||
sa1100_dma_set_spin(s->dmach, FORCE_CLOCK_ADDR, FORCE_CLOCK_SIZE);
|
||||
|
@ -472,7 +473,7 @@ static void audio_process_dma(struct audio_stream *s)
|
|||
continue; /* special case */
|
||||
} else {
|
||||
offset = dma_size * s->period;
|
||||
snd_assert(dma_size <= DMA_BUF_SIZE, );
|
||||
snd_BUG_ON(dma_size > DMA_BUF_SIZE);
|
||||
}
|
||||
#ifdef HH_VERSION
|
||||
ret = sa1100_dma_queue_buffer(s->dmach, s, runtime->dma_addr + offset, dma_size);
|
||||
|
@ -879,7 +880,7 @@ void snd_sa11xx_uda1341_free(struct snd_card *card)
|
|||
audio_dma_free(&chip->s[SNDRV_PCM_STREAM_CAPTURE]);
|
||||
}
|
||||
|
||||
static int __init sa11xx_uda1341_probe(struct platform_device *devptr)
|
||||
static int __devinit sa11xx_uda1341_probe(struct platform_device *devptr)
|
||||
{
|
||||
int err;
|
||||
struct snd_card *card;
|
||||
|
|
|
@ -12,6 +12,12 @@ config SND_HWDEP
|
|||
config SND_RAWMIDI
|
||||
tristate
|
||||
|
||||
# To be effective this also requires INPUT - users should say:
|
||||
# select SND_JACK if INPUT=y || INPUT=SND
|
||||
# to avoid having to force INPUT on.
|
||||
config SND_JACK
|
||||
bool
|
||||
|
||||
config SND_SEQUENCER
|
||||
tristate "Sequencer support"
|
||||
select SND_TIMER
|
||||
|
@ -38,6 +44,7 @@ config SND_SEQ_DUMMY
|
|||
will be called snd-seq-dummy.
|
||||
|
||||
config SND_OSSEMUL
|
||||
select SOUND_OSS_CORE
|
||||
bool
|
||||
|
||||
config SND_MIXER_OSS
|
||||
|
@ -101,6 +108,9 @@ config SND_RTCTIMER
|
|||
To compile this driver as a module, choose M here: the module
|
||||
will be called snd-rtctimer.
|
||||
|
||||
Note that this option is exclusive with the new RTC drivers
|
||||
(CONFIG_RTC_CLASS) since this requires the old API.
|
||||
|
||||
config SND_SEQ_RTCTIMER_DEFAULT
|
||||
bool "Use RTC as default sequencer timer"
|
||||
depends on SND_RTCTIMER && SND_SEQUENCER
|
||||
|
|
|
@ -7,6 +7,7 @@ snd-y := sound.o init.o memory.o info.o control.o misc.o device.o
|
|||
snd-$(CONFIG_ISA_DMA_API) += isadma.o
|
||||
snd-$(CONFIG_SND_OSSEMUL) += sound_oss.o info_oss.o
|
||||
snd-$(CONFIG_SND_VMASTER) += vmaster.o
|
||||
snd-$(CONFIG_SND_JACK) += jack.o
|
||||
|
||||
snd-pcm-objs := pcm.o pcm_native.o pcm_lib.o pcm_timer.o pcm_misc.o \
|
||||
pcm_memory.o
|
||||
|
|
|
@ -139,7 +139,8 @@ void snd_ctl_notify(struct snd_card *card, unsigned int mask,
|
|||
struct snd_ctl_file *ctl;
|
||||
struct snd_kctl_event *ev;
|
||||
|
||||
snd_assert(card != NULL && id != NULL, return);
|
||||
if (snd_BUG_ON(!card || !id))
|
||||
return;
|
||||
read_lock(&card->ctl_files_rwlock);
|
||||
#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
|
||||
card->mixer_oss_change_count++;
|
||||
|
@ -188,8 +189,8 @@ static struct snd_kcontrol *snd_ctl_new(struct snd_kcontrol *control,
|
|||
struct snd_kcontrol *kctl;
|
||||
unsigned int idx;
|
||||
|
||||
snd_assert(control != NULL, return NULL);
|
||||
snd_assert(control->count > 0, return NULL);
|
||||
if (snd_BUG_ON(!control || !control->count))
|
||||
return NULL;
|
||||
kctl = kzalloc(sizeof(*kctl) + sizeof(struct snd_kcontrol_volatile) * control->count, GFP_KERNEL);
|
||||
if (kctl == NULL) {
|
||||
snd_printk(KERN_ERR "Cannot allocate control instance\n");
|
||||
|
@ -218,8 +219,8 @@ struct snd_kcontrol *snd_ctl_new1(const struct snd_kcontrol_new *ncontrol,
|
|||
struct snd_kcontrol kctl;
|
||||
unsigned int access;
|
||||
|
||||
snd_assert(ncontrol != NULL, return NULL);
|
||||
snd_assert(ncontrol->info != NULL, return NULL);
|
||||
if (snd_BUG_ON(!ncontrol || !ncontrol->info))
|
||||
return NULL;
|
||||
memset(&kctl, 0, sizeof(kctl));
|
||||
kctl.id.iface = ncontrol->iface;
|
||||
kctl.id.device = ncontrol->device;
|
||||
|
@ -315,8 +316,8 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol)
|
|||
|
||||
if (! kcontrol)
|
||||
return err;
|
||||
snd_assert(card != NULL, goto error);
|
||||
snd_assert(kcontrol->info != NULL, goto error);
|
||||
if (snd_BUG_ON(!card || !kcontrol->info))
|
||||
goto error;
|
||||
id = kcontrol->id;
|
||||
down_write(&card->controls_rwsem);
|
||||
if (snd_ctl_find_id(card, &id)) {
|
||||
|
@ -367,7 +368,8 @@ int snd_ctl_remove(struct snd_card *card, struct snd_kcontrol *kcontrol)
|
|||
struct snd_ctl_elem_id id;
|
||||
unsigned int idx;
|
||||
|
||||
snd_assert(card != NULL && kcontrol != NULL, return -EINVAL);
|
||||
if (snd_BUG_ON(!card || !kcontrol))
|
||||
return -EINVAL;
|
||||
list_del(&kcontrol->list);
|
||||
card->controls_count -= kcontrol->count;
|
||||
id = kcontrol->id;
|
||||
|
@ -487,7 +489,8 @@ struct snd_kcontrol *snd_ctl_find_numid(struct snd_card *card, unsigned int numi
|
|||
{
|
||||
struct snd_kcontrol *kctl;
|
||||
|
||||
snd_assert(card != NULL && numid != 0, return NULL);
|
||||
if (snd_BUG_ON(!card || !numid))
|
||||
return NULL;
|
||||
list_for_each_entry(kctl, &card->controls, list) {
|
||||
if (kctl->id.numid <= numid && kctl->id.numid + kctl->count > numid)
|
||||
return kctl;
|
||||
|
@ -514,7 +517,8 @@ struct snd_kcontrol *snd_ctl_find_id(struct snd_card *card,
|
|||
{
|
||||
struct snd_kcontrol *kctl;
|
||||
|
||||
snd_assert(card != NULL && id != NULL, return NULL);
|
||||
if (snd_BUG_ON(!card || !id))
|
||||
return NULL;
|
||||
if (id->numid != 0)
|
||||
return snd_ctl_find_numid(card, id->numid);
|
||||
list_for_each_entry(kctl, &card->controls, list) {
|
||||
|
@ -647,7 +651,7 @@ static int snd_ctl_elem_info(struct snd_ctl_file *ctl,
|
|||
#endif
|
||||
result = kctl->info(kctl, info);
|
||||
if (result >= 0) {
|
||||
snd_assert(info->access == 0, );
|
||||
snd_BUG_ON(info->access);
|
||||
index_offset = snd_ctl_get_ioff(kctl, &info->id);
|
||||
vd = &kctl->vd[index_offset];
|
||||
snd_ctl_build_ioff(&info->id, kctl, index_offset);
|
||||
|
@ -1160,7 +1164,8 @@ static long snd_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg
|
|||
|
||||
ctl = file->private_data;
|
||||
card = ctl->card;
|
||||
snd_assert(card != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!card))
|
||||
return -ENXIO;
|
||||
switch (cmd) {
|
||||
case SNDRV_CTL_IOCTL_PVERSION:
|
||||
return put_user(SNDRV_CTL_VERSION, ip) ? -EFAULT : 0;
|
||||
|
@ -1222,7 +1227,8 @@ static ssize_t snd_ctl_read(struct file *file, char __user *buffer,
|
|||
ssize_t result = 0;
|
||||
|
||||
ctl = file->private_data;
|
||||
snd_assert(ctl != NULL && ctl->card != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!ctl || !ctl->card))
|
||||
return -ENXIO;
|
||||
if (!ctl->subscribed)
|
||||
return -EBADFD;
|
||||
if (count < sizeof(struct snd_ctl_event))
|
||||
|
@ -1328,7 +1334,8 @@ static int _snd_ctl_unregister_ioctl(snd_kctl_ioctl_func_t fcn,
|
|||
{
|
||||
struct snd_kctl_ioctl *p;
|
||||
|
||||
snd_assert(fcn != NULL, return -EINVAL);
|
||||
if (snd_BUG_ON(!fcn))
|
||||
return -EINVAL;
|
||||
down_write(&snd_ioctl_rwsem);
|
||||
list_for_each_entry(p, lists, list) {
|
||||
if (p->fioctl == fcn) {
|
||||
|
@ -1404,9 +1411,11 @@ static int snd_ctl_dev_register(struct snd_device *device)
|
|||
int err, cardnum;
|
||||
char name[16];
|
||||
|
||||
snd_assert(card != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!card))
|
||||
return -ENXIO;
|
||||
cardnum = card->number;
|
||||
snd_assert(cardnum >= 0 && cardnum < SNDRV_CARDS, return -ENXIO);
|
||||
if (snd_BUG_ON(cardnum < 0 || cardnum >= SNDRV_CARDS))
|
||||
return -ENXIO;
|
||||
sprintf(name, "controlC%i", cardnum);
|
||||
if ((err = snd_register_device(SNDRV_DEVICE_TYPE_CONTROL, card, -1,
|
||||
&snd_ctl_f_ops, card, name)) < 0)
|
||||
|
@ -1423,16 +1432,18 @@ static int snd_ctl_dev_disconnect(struct snd_device *device)
|
|||
struct snd_ctl_file *ctl;
|
||||
int err, cardnum;
|
||||
|
||||
snd_assert(card != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!card))
|
||||
return -ENXIO;
|
||||
cardnum = card->number;
|
||||
snd_assert(cardnum >= 0 && cardnum < SNDRV_CARDS, return -ENXIO);
|
||||
if (snd_BUG_ON(cardnum < 0 || cardnum >= SNDRV_CARDS))
|
||||
return -ENXIO;
|
||||
|
||||
down_read(&card->controls_rwsem);
|
||||
read_lock(&card->ctl_files_rwlock);
|
||||
list_for_each_entry(ctl, &card->ctl_files, list) {
|
||||
wake_up(&ctl->change_sleep);
|
||||
kill_fasync(&ctl->fasync, SIGIO, POLL_ERR);
|
||||
}
|
||||
up_read(&card->controls_rwsem);
|
||||
read_unlock(&card->ctl_files_rwlock);
|
||||
|
||||
if ((err = snd_unregister_device(SNDRV_DEVICE_TYPE_CONTROL,
|
||||
card, -1)) < 0)
|
||||
|
@ -1469,7 +1480,8 @@ int snd_ctl_create(struct snd_card *card)
|
|||
.dev_disconnect = snd_ctl_dev_disconnect,
|
||||
};
|
||||
|
||||
snd_assert(card != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!card))
|
||||
return -ENXIO;
|
||||
return snd_device_new(card, SNDRV_DEV_CONTROL, card, &ops);
|
||||
}
|
||||
|
||||
|
|
|
@ -398,7 +398,8 @@ static inline long snd_ctl_ioctl_compat(struct file *file, unsigned int cmd, uns
|
|||
int err;
|
||||
|
||||
ctl = file->private_data;
|
||||
snd_assert(ctl && ctl->card, return -ENXIO);
|
||||
if (snd_BUG_ON(!ctl || !ctl->card))
|
||||
return -ENXIO;
|
||||
|
||||
switch (cmd) {
|
||||
case SNDRV_CTL_IOCTL_PVERSION:
|
||||
|
|
|
@ -45,9 +45,8 @@ int snd_device_new(struct snd_card *card, snd_device_type_t type,
|
|||
{
|
||||
struct snd_device *dev;
|
||||
|
||||
snd_assert(card != NULL, return -ENXIO);
|
||||
snd_assert(device_data != NULL, return -ENXIO);
|
||||
snd_assert(ops != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!card || !device_data || !ops))
|
||||
return -ENXIO;
|
||||
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
|
||||
if (dev == NULL) {
|
||||
snd_printk(KERN_ERR "Cannot allocate device\n");
|
||||
|
@ -80,8 +79,8 @@ int snd_device_free(struct snd_card *card, void *device_data)
|
|||
{
|
||||
struct snd_device *dev;
|
||||
|
||||
snd_assert(card != NULL, return -ENXIO);
|
||||
snd_assert(device_data != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!card || !device_data))
|
||||
return -ENXIO;
|
||||
list_for_each_entry(dev, &card->devices, list) {
|
||||
if (dev->device_data != device_data)
|
||||
continue;
|
||||
|
@ -123,8 +122,8 @@ int snd_device_disconnect(struct snd_card *card, void *device_data)
|
|||
{
|
||||
struct snd_device *dev;
|
||||
|
||||
snd_assert(card != NULL, return -ENXIO);
|
||||
snd_assert(device_data != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!card || !device_data))
|
||||
return -ENXIO;
|
||||
list_for_each_entry(dev, &card->devices, list) {
|
||||
if (dev->device_data != device_data)
|
||||
continue;
|
||||
|
@ -159,8 +158,8 @@ int snd_device_register(struct snd_card *card, void *device_data)
|
|||
struct snd_device *dev;
|
||||
int err;
|
||||
|
||||
snd_assert(card != NULL, return -ENXIO);
|
||||
snd_assert(device_data != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!card || !device_data))
|
||||
return -ENXIO;
|
||||
list_for_each_entry(dev, &card->devices, list) {
|
||||
if (dev->device_data != device_data)
|
||||
continue;
|
||||
|
@ -188,7 +187,8 @@ int snd_device_register_all(struct snd_card *card)
|
|||
struct snd_device *dev;
|
||||
int err;
|
||||
|
||||
snd_assert(card != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!card))
|
||||
return -ENXIO;
|
||||
list_for_each_entry(dev, &card->devices, list) {
|
||||
if (dev->state == SNDRV_DEV_BUILD && dev->ops->dev_register) {
|
||||
if ((err = dev->ops->dev_register(dev)) < 0)
|
||||
|
@ -208,7 +208,8 @@ int snd_device_disconnect_all(struct snd_card *card)
|
|||
struct snd_device *dev;
|
||||
int err = 0;
|
||||
|
||||
snd_assert(card != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!card))
|
||||
return -ENXIO;
|
||||
list_for_each_entry(dev, &card->devices, list) {
|
||||
if (snd_device_disconnect(card, dev->device_data) < 0)
|
||||
err = -ENXIO;
|
||||
|
@ -226,7 +227,8 @@ int snd_device_free_all(struct snd_card *card, snd_device_cmd_t cmd)
|
|||
int err;
|
||||
unsigned int range_low, range_high;
|
||||
|
||||
snd_assert(card != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!card))
|
||||
return -ENXIO;
|
||||
range_low = cmd * SNDRV_DEV_TYPE_RANGE_SIZE;
|
||||
range_high = range_low + SNDRV_DEV_TYPE_RANGE_SIZE - 1;
|
||||
__again:
|
||||
|
|
|
@ -353,9 +353,10 @@ int snd_hwdep_new(struct snd_card *card, char *id, int device,
|
|||
.dev_disconnect = snd_hwdep_dev_disconnect,
|
||||
};
|
||||
|
||||
snd_assert(rhwdep != NULL, return -EINVAL);
|
||||
*rhwdep = NULL;
|
||||
snd_assert(card != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!card))
|
||||
return -ENXIO;
|
||||
if (rhwdep)
|
||||
*rhwdep = NULL;
|
||||
hwdep = kzalloc(sizeof(*hwdep), GFP_KERNEL);
|
||||
if (hwdep == NULL) {
|
||||
snd_printk(KERN_ERR "hwdep: cannot allocate\n");
|
||||
|
@ -374,13 +375,15 @@ int snd_hwdep_new(struct snd_card *card, char *id, int device,
|
|||
}
|
||||
init_waitqueue_head(&hwdep->open_wait);
|
||||
mutex_init(&hwdep->open_mutex);
|
||||
*rhwdep = hwdep;
|
||||
if (rhwdep)
|
||||
*rhwdep = hwdep;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_hwdep_free(struct snd_hwdep *hwdep)
|
||||
{
|
||||
snd_assert(hwdep != NULL, return -ENXIO);
|
||||
if (!hwdep)
|
||||
return 0;
|
||||
if (hwdep->private_free)
|
||||
hwdep->private_free(hwdep);
|
||||
kfree(hwdep);
|
||||
|
@ -440,7 +443,8 @@ static int snd_hwdep_dev_disconnect(struct snd_device *device)
|
|||
{
|
||||
struct snd_hwdep *hwdep = device->device_data;
|
||||
|
||||
snd_assert(hwdep != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!hwdep))
|
||||
return -ENXIO;
|
||||
mutex_lock(®ister_mutex);
|
||||
if (snd_hwdep_search(hwdep->card, hwdep->device) != hwdep) {
|
||||
mutex_unlock(®ister_mutex);
|
||||
|
|
|
@ -217,7 +217,8 @@ static ssize_t snd_info_entry_read(struct file *file, char __user *buffer,
|
|||
loff_t pos;
|
||||
|
||||
data = file->private_data;
|
||||
snd_assert(data != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!data))
|
||||
return -ENXIO;
|
||||
pos = *offset;
|
||||
if (pos < 0 || (long) pos != pos || (ssize_t) count < 0)
|
||||
return -EIO;
|
||||
|
@ -258,7 +259,8 @@ static ssize_t snd_info_entry_write(struct file *file, const char __user *buffer
|
|||
loff_t pos;
|
||||
|
||||
data = file->private_data;
|
||||
snd_assert(data != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!data))
|
||||
return -ENXIO;
|
||||
entry = data->entry;
|
||||
pos = *offset;
|
||||
if (pos < 0 || (long) pos != pos || (ssize_t) count < 0)
|
||||
|
@ -614,7 +616,8 @@ int snd_info_card_create(struct snd_card *card)
|
|||
char str[8];
|
||||
struct snd_info_entry *entry;
|
||||
|
||||
snd_assert(card != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!card))
|
||||
return -ENXIO;
|
||||
|
||||
sprintf(str, "card%i", card->number);
|
||||
if ((entry = snd_info_create_module_entry(card->module, str, NULL)) == NULL)
|
||||
|
@ -636,7 +639,8 @@ int snd_info_card_register(struct snd_card *card)
|
|||
{
|
||||
struct proc_dir_entry *p;
|
||||
|
||||
snd_assert(card != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!card))
|
||||
return -ENXIO;
|
||||
|
||||
if (!strcmp(card->id, card->proc_root->name))
|
||||
return 0;
|
||||
|
@ -654,7 +658,8 @@ int snd_info_card_register(struct snd_card *card)
|
|||
*/
|
||||
void snd_info_card_disconnect(struct snd_card *card)
|
||||
{
|
||||
snd_assert(card != NULL, return);
|
||||
if (!card)
|
||||
return;
|
||||
mutex_lock(&info_mutex);
|
||||
if (card->proc_root_link) {
|
||||
snd_remove_proc_entry(snd_proc_root, card->proc_root_link);
|
||||
|
@ -671,7 +676,8 @@ void snd_info_card_disconnect(struct snd_card *card)
|
|||
*/
|
||||
int snd_info_card_free(struct snd_card *card)
|
||||
{
|
||||
snd_assert(card != NULL, return -ENXIO);
|
||||
if (!card)
|
||||
return 0;
|
||||
snd_info_free_entry(card->proc_root);
|
||||
card->proc_root = NULL;
|
||||
return 0;
|
||||
|
@ -849,7 +855,7 @@ static void snd_info_disconnect(struct snd_info_entry *entry)
|
|||
return;
|
||||
list_del_init(&entry->list);
|
||||
root = entry->parent == NULL ? snd_proc_root : entry->parent->p;
|
||||
snd_assert(root, return);
|
||||
snd_BUG_ON(!root);
|
||||
snd_remove_proc_entry(root, entry->p);
|
||||
entry->p = NULL;
|
||||
}
|
||||
|
@ -947,7 +953,8 @@ int snd_info_register(struct snd_info_entry * entry)
|
|||
{
|
||||
struct proc_dir_entry *root, *p = NULL;
|
||||
|
||||
snd_assert(entry != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!entry))
|
||||
return -ENXIO;
|
||||
root = entry->parent == NULL ? snd_proc_root : entry->parent->p;
|
||||
mutex_lock(&info_mutex);
|
||||
p = snd_create_proc_entry(entry->name, entry->mode, root);
|
||||
|
|
|
@ -43,8 +43,10 @@ int snd_oss_info_register(int dev, int num, char *string)
|
|||
{
|
||||
char *x;
|
||||
|
||||
snd_assert(dev >= 0 && dev < SNDRV_OSS_INFO_DEV_COUNT, return -ENXIO);
|
||||
snd_assert(num >= 0 && num < SNDRV_CARDS, return -ENXIO);
|
||||
if (snd_BUG_ON(dev < 0 || dev >= SNDRV_OSS_INFO_DEV_COUNT))
|
||||
return -ENXIO;
|
||||
if (snd_BUG_ON(num < 0 || num >= SNDRV_CARDS))
|
||||
return -ENXIO;
|
||||
mutex_lock(&strings);
|
||||
if (string == NULL) {
|
||||
if ((x = snd_sndstat_strings[num][dev]) != NULL) {
|
||||
|
|
|
@ -545,7 +545,8 @@ int snd_card_register(struct snd_card *card)
|
|||
{
|
||||
int err;
|
||||
|
||||
snd_assert(card != NULL, return -EINVAL);
|
||||
if (snd_BUG_ON(!card))
|
||||
return -EINVAL;
|
||||
#ifndef CONFIG_SYSFS_DEPRECATED
|
||||
if (!card->card_dev) {
|
||||
card->card_dev = device_create_drvdata(sound_class, card->dev,
|
||||
|
|
163
sound/core/jack.c
Normal file
163
sound/core/jack.c
Normal file
|
@ -0,0 +1,163 @@
|
|||
/*
|
||||
* Jack abstraction layer
|
||||
*
|
||||
* Copyright 2008 Wolfson Microelectronics
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/input.h>
|
||||
#include <sound/jack.h>
|
||||
#include <sound/core.h>
|
||||
|
||||
static int snd_jack_dev_free(struct snd_device *device)
|
||||
{
|
||||
struct snd_jack *jack = device->device_data;
|
||||
|
||||
/* If the input device is registered with the input subsystem
|
||||
* then we need to use a different deallocator. */
|
||||
if (jack->registered)
|
||||
input_unregister_device(jack->input_dev);
|
||||
else
|
||||
input_free_device(jack->input_dev);
|
||||
|
||||
kfree(jack);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_jack_dev_register(struct snd_device *device)
|
||||
{
|
||||
struct snd_jack *jack = device->device_data;
|
||||
struct snd_card *card = device->card;
|
||||
int err;
|
||||
|
||||
snprintf(jack->name, sizeof(jack->name), "%s %s",
|
||||
card->longname, jack->id);
|
||||
jack->input_dev->name = jack->name;
|
||||
|
||||
/* Default to the sound card device. */
|
||||
if (!jack->input_dev->dev.parent)
|
||||
jack->input_dev->dev.parent = card->dev;
|
||||
|
||||
err = input_register_device(jack->input_dev);
|
||||
if (err == 0)
|
||||
jack->registered = 1;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_jack_new - Create a new jack
|
||||
* @card: the card instance
|
||||
* @id: an identifying string for this jack
|
||||
* @type: a bitmask of enum snd_jack_type values that can be detected by
|
||||
* this jack
|
||||
* @jjack: Used to provide the allocated jack object to the caller.
|
||||
*
|
||||
* Creates a new jack object.
|
||||
*
|
||||
* Returns zero if successful, or a negative error code on failure.
|
||||
* On success jjack will be initialised.
|
||||
*/
|
||||
int snd_jack_new(struct snd_card *card, const char *id, int type,
|
||||
struct snd_jack **jjack)
|
||||
{
|
||||
struct snd_jack *jack;
|
||||
int err;
|
||||
static struct snd_device_ops ops = {
|
||||
.dev_free = snd_jack_dev_free,
|
||||
.dev_register = snd_jack_dev_register,
|
||||
};
|
||||
|
||||
jack = kzalloc(sizeof(struct snd_jack), GFP_KERNEL);
|
||||
if (jack == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
jack->id = id;
|
||||
|
||||
jack->input_dev = input_allocate_device();
|
||||
if (jack->input_dev == NULL) {
|
||||
err = -ENOMEM;
|
||||
goto fail_input;
|
||||
}
|
||||
|
||||
jack->input_dev->phys = "ALSA";
|
||||
|
||||
jack->type = type;
|
||||
|
||||
if (type & SND_JACK_HEADPHONE)
|
||||
input_set_capability(jack->input_dev, EV_SW,
|
||||
SW_HEADPHONE_INSERT);
|
||||
if (type & SND_JACK_MICROPHONE)
|
||||
input_set_capability(jack->input_dev, EV_SW,
|
||||
SW_MICROPHONE_INSERT);
|
||||
|
||||
err = snd_device_new(card, SNDRV_DEV_JACK, jack, &ops);
|
||||
if (err < 0)
|
||||
goto fail_input;
|
||||
|
||||
*jjack = jack;
|
||||
|
||||
return 0;
|
||||
|
||||
fail_input:
|
||||
input_free_device(jack->input_dev);
|
||||
kfree(jack);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL(snd_jack_new);
|
||||
|
||||
/**
|
||||
* snd_jack_set_parent - Set the parent device for a jack
|
||||
*
|
||||
* @jack: The jack to configure
|
||||
* @parent: The device to set as parent for the jack.
|
||||
*
|
||||
* Set the parent for the jack input device in the device tree. This
|
||||
* function is only valid prior to registration of the jack. If no
|
||||
* parent is configured then the parent device will be the sound card.
|
||||
*/
|
||||
void snd_jack_set_parent(struct snd_jack *jack, struct device *parent)
|
||||
{
|
||||
WARN_ON(jack->registered);
|
||||
|
||||
jack->input_dev->dev.parent = parent;
|
||||
}
|
||||
EXPORT_SYMBOL(snd_jack_set_parent);
|
||||
|
||||
/**
|
||||
* snd_jack_report - Report the current status of a jack
|
||||
*
|
||||
* @jack: The jack to report status for
|
||||
* @status: The current status of the jack
|
||||
*/
|
||||
void snd_jack_report(struct snd_jack *jack, int status)
|
||||
{
|
||||
if (jack->type & SND_JACK_HEADPHONE)
|
||||
input_report_switch(jack->input_dev, SW_HEADPHONE_INSERT,
|
||||
status & SND_JACK_HEADPHONE);
|
||||
if (jack->type & SND_JACK_MICROPHONE)
|
||||
input_report_switch(jack->input_dev, SW_MICROPHONE_INSERT,
|
||||
status & SND_JACK_MICROPHONE);
|
||||
|
||||
input_sync(jack->input_dev);
|
||||
}
|
||||
EXPORT_SYMBOL(snd_jack_report);
|
||||
|
||||
MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
|
||||
MODULE_DESCRIPTION("Jack detection support for ALSA");
|
||||
MODULE_LICENSE("GPL");
|
|
@ -43,14 +43,6 @@ MODULE_DESCRIPTION("Memory allocator for ALSA system.");
|
|||
MODULE_LICENSE("GPL");
|
||||
|
||||
|
||||
/*
|
||||
*/
|
||||
|
||||
void *snd_malloc_sgbuf_pages(struct device *device,
|
||||
size_t size, struct snd_dma_buffer *dmab,
|
||||
size_t *res_size);
|
||||
int snd_free_sgbuf_pages(struct snd_dma_buffer *dmab);
|
||||
|
||||
/*
|
||||
*/
|
||||
|
||||
|
@ -67,18 +59,6 @@ struct snd_mem_list {
|
|||
/* id for pre-allocated buffers */
|
||||
#define SNDRV_DMA_DEVICE_UNUSED (unsigned int)-1
|
||||
|
||||
#ifdef CONFIG_SND_DEBUG
|
||||
#define __ASTRING__(x) #x
|
||||
#define snd_assert(expr, args...) do {\
|
||||
if (!(expr)) {\
|
||||
printk(KERN_ERR "snd-malloc: BUG? (%s) (called from %p)\n", __ASTRING__(expr), __builtin_return_address(0));\
|
||||
args;\
|
||||
}\
|
||||
} while (0)
|
||||
#else
|
||||
#define snd_assert(expr, args...) /**/
|
||||
#endif
|
||||
|
||||
/*
|
||||
*
|
||||
* Generic memory allocators
|
||||
|
@ -111,8 +91,10 @@ void *snd_malloc_pages(size_t size, gfp_t gfp_flags)
|
|||
int pg;
|
||||
void *res;
|
||||
|
||||
snd_assert(size > 0, return NULL);
|
||||
snd_assert(gfp_flags != 0, return NULL);
|
||||
if (WARN_ON(!size))
|
||||
return NULL;
|
||||
if (WARN_ON(!gfp_flags))
|
||||
return NULL;
|
||||
gfp_flags |= __GFP_COMP; /* compound page lets parts be mapped */
|
||||
pg = get_order(size);
|
||||
if ((res = (void *) __get_free_pages(gfp_flags, pg)) != NULL)
|
||||
|
@ -152,8 +134,8 @@ static void *snd_malloc_dev_pages(struct device *dev, size_t size, dma_addr_t *d
|
|||
void *res;
|
||||
gfp_t gfp_flags;
|
||||
|
||||
snd_assert(size > 0, return NULL);
|
||||
snd_assert(dma != NULL, return NULL);
|
||||
if (WARN_ON(!dma))
|
||||
return NULL;
|
||||
pg = get_order(size);
|
||||
gfp_flags = GFP_KERNEL
|
||||
| __GFP_COMP /* compound page lets parts be mapped */
|
||||
|
@ -189,8 +171,8 @@ static void *snd_malloc_sbus_pages(struct device *dev, size_t size,
|
|||
int pg;
|
||||
void *res;
|
||||
|
||||
snd_assert(size > 0, return NULL);
|
||||
snd_assert(dma_addr != NULL, return NULL);
|
||||
if (WARN_ON(!dma_addr))
|
||||
return NULL;
|
||||
pg = get_order(size);
|
||||
res = sbus_alloc_consistent(sdev, PAGE_SIZE * (1 << pg), dma_addr);
|
||||
if (res != NULL)
|
||||
|
@ -236,8 +218,10 @@ static void snd_free_sbus_pages(struct device *dev, size_t size,
|
|||
int snd_dma_alloc_pages(int type, struct device *device, size_t size,
|
||||
struct snd_dma_buffer *dmab)
|
||||
{
|
||||
snd_assert(size > 0, return -ENXIO);
|
||||
snd_assert(dmab != NULL, return -ENXIO);
|
||||
if (WARN_ON(!size))
|
||||
return -ENXIO;
|
||||
if (WARN_ON(!dmab))
|
||||
return -ENXIO;
|
||||
|
||||
dmab->dev.type = type;
|
||||
dmab->dev.dev = device;
|
||||
|
@ -292,15 +276,17 @@ int snd_dma_alloc_pages_fallback(int type, struct device *device, size_t size,
|
|||
{
|
||||
int err;
|
||||
|
||||
snd_assert(size > 0, return -ENXIO);
|
||||
snd_assert(dmab != NULL, return -ENXIO);
|
||||
|
||||
while ((err = snd_dma_alloc_pages(type, device, size, dmab)) < 0) {
|
||||
size_t aligned_size;
|
||||
if (err != -ENOMEM)
|
||||
return err;
|
||||
size >>= 1;
|
||||
if (size <= PAGE_SIZE)
|
||||
return -ENOMEM;
|
||||
aligned_size = PAGE_SIZE << get_order(size);
|
||||
if (size != aligned_size)
|
||||
size = aligned_size;
|
||||
else
|
||||
size >>= 1;
|
||||
}
|
||||
if (! dmab->area)
|
||||
return -ENOMEM;
|
||||
|
@ -353,7 +339,8 @@ size_t snd_dma_get_reserved_buf(struct snd_dma_buffer *dmab, unsigned int id)
|
|||
{
|
||||
struct snd_mem_list *mem;
|
||||
|
||||
snd_assert(dmab, return 0);
|
||||
if (WARN_ON(!dmab))
|
||||
return 0;
|
||||
|
||||
mutex_lock(&list_mutex);
|
||||
list_for_each_entry(mem, &mem_list_head, list) {
|
||||
|
@ -387,7 +374,8 @@ int snd_dma_reserve_buf(struct snd_dma_buffer *dmab, unsigned int id)
|
|||
{
|
||||
struct snd_mem_list *mem;
|
||||
|
||||
snd_assert(dmab, return -EINVAL);
|
||||
if (WARN_ON(!dmab))
|
||||
return -EINVAL;
|
||||
mem = kmalloc(sizeof(*mem), GFP_KERNEL);
|
||||
if (! mem)
|
||||
return -ENOMEM;
|
||||
|
|
|
@ -32,17 +32,18 @@ static snd_pcm_sframes_t copy_transfer(struct snd_pcm_plugin *plugin,
|
|||
unsigned int channel;
|
||||
unsigned int nchannels;
|
||||
|
||||
snd_assert(plugin != NULL && src_channels != NULL && dst_channels != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!plugin || !src_channels || !dst_channels))
|
||||
return -ENXIO;
|
||||
if (frames == 0)
|
||||
return 0;
|
||||
nchannels = plugin->src_format.channels;
|
||||
for (channel = 0; channel < nchannels; channel++) {
|
||||
snd_assert(src_channels->area.first % 8 == 0 &&
|
||||
src_channels->area.step % 8 == 0,
|
||||
return -ENXIO);
|
||||
snd_assert(dst_channels->area.first % 8 == 0 &&
|
||||
dst_channels->area.step % 8 == 0,
|
||||
return -ENXIO);
|
||||
if (snd_BUG_ON(src_channels->area.first % 8 ||
|
||||
src_channels->area.step % 8))
|
||||
return -ENXIO;
|
||||
if (snd_BUG_ON(dst_channels->area.first % 8 ||
|
||||
dst_channels->area.step % 8))
|
||||
return -ENXIO;
|
||||
if (!src_channels->enabled) {
|
||||
if (dst_channels->wanted)
|
||||
snd_pcm_area_silence(&dst_channels->area, 0, frames, plugin->dst_format.format);
|
||||
|
@ -66,15 +67,20 @@ int snd_pcm_plugin_build_copy(struct snd_pcm_substream *plug,
|
|||
struct snd_pcm_plugin *plugin;
|
||||
int width;
|
||||
|
||||
snd_assert(r_plugin != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!r_plugin))
|
||||
return -ENXIO;
|
||||
*r_plugin = NULL;
|
||||
|
||||
snd_assert(src_format->format == dst_format->format, return -ENXIO);
|
||||
snd_assert(src_format->rate == dst_format->rate, return -ENXIO);
|
||||
snd_assert(src_format->channels == dst_format->channels, return -ENXIO);
|
||||
if (snd_BUG_ON(src_format->format != dst_format->format))
|
||||
return -ENXIO;
|
||||
if (snd_BUG_ON(src_format->rate != dst_format->rate))
|
||||
return -ENXIO;
|
||||
if (snd_BUG_ON(src_format->channels != dst_format->channels))
|
||||
return -ENXIO;
|
||||
|
||||
width = snd_pcm_format_physical_width(src_format->format);
|
||||
snd_assert(width > 0, return -ENXIO);
|
||||
if (snd_BUG_ON(width <= 0))
|
||||
return -ENXIO;
|
||||
|
||||
err = snd_pcm_plugin_build(plug, "copy", src_format, dst_format,
|
||||
0, &plugin);
|
||||
|
|
|
@ -39,14 +39,17 @@ static snd_pcm_sframes_t io_playback_transfer(struct snd_pcm_plugin *plugin,
|
|||
struct snd_pcm_plugin_channel *dst_channels,
|
||||
snd_pcm_uframes_t frames)
|
||||
{
|
||||
snd_assert(plugin != NULL, return -ENXIO);
|
||||
snd_assert(src_channels != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!plugin))
|
||||
return -ENXIO;
|
||||
if (snd_BUG_ON(!src_channels))
|
||||
return -ENXIO;
|
||||
if (plugin->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED) {
|
||||
return pcm_write(plugin->plug, src_channels->area.addr, frames);
|
||||
} else {
|
||||
int channel, channels = plugin->dst_format.channels;
|
||||
void **bufs = (void**)plugin->extra_data;
|
||||
snd_assert(bufs != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!bufs))
|
||||
return -ENXIO;
|
||||
for (channel = 0; channel < channels; channel++) {
|
||||
if (src_channels[channel].enabled)
|
||||
bufs[channel] = src_channels[channel].area.addr;
|
||||
|
@ -62,14 +65,17 @@ static snd_pcm_sframes_t io_capture_transfer(struct snd_pcm_plugin *plugin,
|
|||
struct snd_pcm_plugin_channel *dst_channels,
|
||||
snd_pcm_uframes_t frames)
|
||||
{
|
||||
snd_assert(plugin != NULL, return -ENXIO);
|
||||
snd_assert(dst_channels != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!plugin))
|
||||
return -ENXIO;
|
||||
if (snd_BUG_ON(!dst_channels))
|
||||
return -ENXIO;
|
||||
if (plugin->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED) {
|
||||
return pcm_read(plugin->plug, dst_channels->area.addr, frames);
|
||||
} else {
|
||||
int channel, channels = plugin->dst_format.channels;
|
||||
void **bufs = (void**)plugin->extra_data;
|
||||
snd_assert(bufs != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!bufs))
|
||||
return -ENXIO;
|
||||
for (channel = 0; channel < channels; channel++) {
|
||||
if (dst_channels[channel].enabled)
|
||||
bufs[channel] = dst_channels[channel].area.addr;
|
||||
|
@ -107,9 +113,11 @@ int snd_pcm_plugin_build_io(struct snd_pcm_substream *plug,
|
|||
struct snd_pcm_plugin_format format;
|
||||
struct snd_pcm_plugin *plugin;
|
||||
|
||||
snd_assert(r_plugin != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!r_plugin))
|
||||
return -ENXIO;
|
||||
*r_plugin = NULL;
|
||||
snd_assert(plug != NULL && params != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!plug || !params))
|
||||
return -ENXIO;
|
||||
format.format = params_format(params);
|
||||
format.rate = params_rate(params);
|
||||
format.channels = params_channels(params);
|
||||
|
|
|
@ -92,7 +92,8 @@ static snd_pcm_sframes_t linear_transfer(struct snd_pcm_plugin *plugin,
|
|||
{
|
||||
struct linear_priv *data;
|
||||
|
||||
snd_assert(plugin != NULL && src_channels != NULL && dst_channels != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!plugin || !src_channels || !dst_channels))
|
||||
return -ENXIO;
|
||||
data = (struct linear_priv *)plugin->extra_data;
|
||||
if (frames == 0)
|
||||
return 0;
|
||||
|
@ -100,12 +101,12 @@ static snd_pcm_sframes_t linear_transfer(struct snd_pcm_plugin *plugin,
|
|||
{
|
||||
unsigned int channel;
|
||||
for (channel = 0; channel < plugin->src_format.channels; channel++) {
|
||||
snd_assert(src_channels[channel].area.first % 8 == 0 &&
|
||||
src_channels[channel].area.step % 8 == 0,
|
||||
return -ENXIO);
|
||||
snd_assert(dst_channels[channel].area.first % 8 == 0 &&
|
||||
dst_channels[channel].area.step % 8 == 0,
|
||||
return -ENXIO);
|
||||
if (snd_BUG_ON(src_channels[channel].area.first % 8 ||
|
||||
src_channels[channel].area.step % 8))
|
||||
return -ENXIO;
|
||||
if (snd_BUG_ON(dst_channels[channel].area.first % 8 ||
|
||||
dst_channels[channel].area.step % 8))
|
||||
return -ENXIO;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -154,13 +155,17 @@ int snd_pcm_plugin_build_linear(struct snd_pcm_substream *plug,
|
|||
struct linear_priv *data;
|
||||
struct snd_pcm_plugin *plugin;
|
||||
|
||||
snd_assert(r_plugin != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!r_plugin))
|
||||
return -ENXIO;
|
||||
*r_plugin = NULL;
|
||||
|
||||
snd_assert(src_format->rate == dst_format->rate, return -ENXIO);
|
||||
snd_assert(src_format->channels == dst_format->channels, return -ENXIO);
|
||||
snd_assert(snd_pcm_format_linear(src_format->format) &&
|
||||
snd_pcm_format_linear(dst_format->format), return -ENXIO);
|
||||
if (snd_BUG_ON(src_format->rate != dst_format->rate))
|
||||
return -ENXIO;
|
||||
if (snd_BUG_ON(src_format->channels != dst_format->channels))
|
||||
return -ENXIO;
|
||||
if (snd_BUG_ON(!snd_pcm_format_linear(src_format->format) ||
|
||||
!snd_pcm_format_linear(dst_format->format)))
|
||||
return -ENXIO;
|
||||
|
||||
err = snd_pcm_plugin_build(plug, "linear format conversion",
|
||||
src_format, dst_format,
|
||||
|
|
|
@ -257,8 +257,10 @@ static int snd_mixer_oss_get_volume(struct snd_mixer_oss_file *fmixer, int slot)
|
|||
result = pslot->get_volume(fmixer, pslot, &left, &right);
|
||||
if (!pslot->stereo)
|
||||
right = left;
|
||||
snd_assert(left >= 0 && left <= 100, return -EIO);
|
||||
snd_assert(right >= 0 && right <= 100, return -EIO);
|
||||
if (snd_BUG_ON(left < 0 || left > 100))
|
||||
return -EIO;
|
||||
if (snd_BUG_ON(right < 0 || right > 100))
|
||||
return -EIO;
|
||||
if (result >= 0) {
|
||||
pslot->volume[0] = left;
|
||||
pslot->volume[1] = right;
|
||||
|
@ -298,7 +300,8 @@ static int snd_mixer_oss_ioctl1(struct snd_mixer_oss_file *fmixer, unsigned int
|
|||
int __user *p = argp;
|
||||
int tmp;
|
||||
|
||||
snd_assert(fmixer != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!fmixer))
|
||||
return -ENXIO;
|
||||
if (((cmd >> 8) & 0xff) == 'M') {
|
||||
switch (cmd) {
|
||||
case SOUND_MIXER_INFO:
|
||||
|
@ -368,7 +371,8 @@ int snd_mixer_oss_ioctl_card(struct snd_card *card, unsigned int cmd, unsigned l
|
|||
{
|
||||
struct snd_mixer_oss_file fmixer;
|
||||
|
||||
snd_assert(card != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!card))
|
||||
return -ENXIO;
|
||||
if (card->mixer_oss == NULL)
|
||||
return -ENXIO;
|
||||
memset(&fmixer, 0, sizeof(fmixer));
|
||||
|
@ -1284,9 +1288,11 @@ static int snd_mixer_oss_free1(void *private)
|
|||
struct snd_card *card;
|
||||
int idx;
|
||||
|
||||
snd_assert(mixer != NULL, return -ENXIO);
|
||||
if (!mixer)
|
||||
return 0;
|
||||
card = mixer->card;
|
||||
snd_assert(mixer == card->mixer_oss, return -ENXIO);
|
||||
if (snd_BUG_ON(mixer != card->mixer_oss))
|
||||
return -ENXIO;
|
||||
card->mixer_oss = NULL;
|
||||
for (idx = 0; idx < SNDRV_OSS_MAX_MIXERS; idx++) {
|
||||
struct snd_mixer_oss_slot *chn = &mixer->slots[idx];
|
||||
|
|
|
@ -252,19 +252,20 @@ static snd_pcm_sframes_t mulaw_transfer(struct snd_pcm_plugin *plugin,
|
|||
{
|
||||
struct mulaw_priv *data;
|
||||
|
||||
snd_assert(plugin != NULL && src_channels != NULL && dst_channels != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!plugin || !src_channels || !dst_channels))
|
||||
return -ENXIO;
|
||||
if (frames == 0)
|
||||
return 0;
|
||||
#ifdef CONFIG_SND_DEBUG
|
||||
{
|
||||
unsigned int channel;
|
||||
for (channel = 0; channel < plugin->src_format.channels; channel++) {
|
||||
snd_assert(src_channels[channel].area.first % 8 == 0 &&
|
||||
src_channels[channel].area.step % 8 == 0,
|
||||
return -ENXIO);
|
||||
snd_assert(dst_channels[channel].area.first % 8 == 0 &&
|
||||
dst_channels[channel].area.step % 8 == 0,
|
||||
return -ENXIO);
|
||||
if (snd_BUG_ON(src_channels[channel].area.first % 8 ||
|
||||
src_channels[channel].area.step % 8))
|
||||
return -ENXIO;
|
||||
if (snd_BUG_ON(dst_channels[channel].area.first % 8 ||
|
||||
dst_channels[channel].area.step % 8))
|
||||
return -ENXIO;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -305,11 +306,14 @@ int snd_pcm_plugin_build_mulaw(struct snd_pcm_substream *plug,
|
|||
struct snd_pcm_plugin_format *format;
|
||||
mulaw_f func;
|
||||
|
||||
snd_assert(r_plugin != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!r_plugin))
|
||||
return -ENXIO;
|
||||
*r_plugin = NULL;
|
||||
|
||||
snd_assert(src_format->rate == dst_format->rate, return -ENXIO);
|
||||
snd_assert(src_format->channels == dst_format->channels, return -ENXIO);
|
||||
if (snd_BUG_ON(src_format->rate != dst_format->rate))
|
||||
return -ENXIO;
|
||||
if (snd_BUG_ON(src_format->channels != dst_format->channels))
|
||||
return -ENXIO;
|
||||
|
||||
if (dst_format->format == SNDRV_PCM_FORMAT_MU_LAW) {
|
||||
format = src_format;
|
||||
|
@ -323,7 +327,8 @@ int snd_pcm_plugin_build_mulaw(struct snd_pcm_substream *plug,
|
|||
snd_BUG();
|
||||
return -EINVAL;
|
||||
}
|
||||
snd_assert(snd_pcm_format_linear(format->format) != 0, return -ENXIO);
|
||||
if (snd_BUG_ON(!snd_pcm_format_linear(format->format)))
|
||||
return -ENXIO;
|
||||
|
||||
err = snd_pcm_plugin_build(plug, "Mu-Law<->linear conversion",
|
||||
src_format, dst_format,
|
||||
|
|
|
@ -452,7 +452,8 @@ static int snd_pcm_hw_param_near(struct snd_pcm_substream *pcm,
|
|||
} else {
|
||||
*params = *save;
|
||||
max = snd_pcm_hw_param_max(pcm, params, var, max, &maxdir);
|
||||
snd_assert(max >= 0, return -EINVAL);
|
||||
if (max < 0)
|
||||
return max;
|
||||
last = 1;
|
||||
}
|
||||
_end:
|
||||
|
@ -461,7 +462,7 @@ static int snd_pcm_hw_param_near(struct snd_pcm_substream *pcm,
|
|||
v = snd_pcm_hw_param_last(pcm, params, var, dir);
|
||||
else
|
||||
v = snd_pcm_hw_param_first(pcm, params, var, dir);
|
||||
snd_assert(v >= 0, return -EINVAL);
|
||||
snd_BUG_ON(v < 0);
|
||||
return v;
|
||||
}
|
||||
|
||||
|
@ -778,7 +779,8 @@ static int snd_pcm_oss_period_size(struct snd_pcm_substream *substream,
|
|||
while (oss_period_size * oss_periods > oss_buffer_size)
|
||||
oss_period_size /= 2;
|
||||
|
||||
snd_assert(oss_period_size >= 16, return -EINVAL);
|
||||
if (oss_period_size < 16)
|
||||
return -EINVAL;
|
||||
runtime->oss.period_bytes = oss_period_size;
|
||||
runtime->oss.period_frames = 1;
|
||||
runtime->oss.periods = oss_periods;
|
||||
|
@ -895,7 +897,8 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream)
|
|||
}
|
||||
}
|
||||
err = _snd_pcm_hw_param_set(sparams, SNDRV_PCM_HW_PARAM_FORMAT, sformat, 0);
|
||||
snd_assert(err >= 0, goto failure);
|
||||
if (err < 0)
|
||||
goto failure;
|
||||
|
||||
if (direct) {
|
||||
memcpy(params, sparams, sizeof(*params));
|
||||
|
@ -958,11 +961,13 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream)
|
|||
|
||||
n = snd_pcm_plug_slave_size(substream, runtime->oss.period_bytes / oss_frame_size);
|
||||
err = snd_pcm_hw_param_near(substream, sparams, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, n, NULL);
|
||||
snd_assert(err >= 0, goto failure);
|
||||
if (err < 0)
|
||||
goto failure;
|
||||
|
||||
err = snd_pcm_hw_param_near(substream, sparams, SNDRV_PCM_HW_PARAM_PERIODS,
|
||||
runtime->oss.periods, NULL);
|
||||
snd_assert(err >= 0, goto failure);
|
||||
if (err < 0)
|
||||
goto failure;
|
||||
|
||||
snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL);
|
||||
|
||||
|
@ -1006,7 +1011,10 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream)
|
|||
|
||||
runtime->oss.periods = params_periods(sparams);
|
||||
oss_period_size = snd_pcm_plug_client_size(substream, params_period_size(sparams));
|
||||
snd_assert(oss_period_size >= 0, err = -EINVAL; goto failure);
|
||||
if (oss_period_size < 0) {
|
||||
err = -EINVAL;
|
||||
goto failure;
|
||||
}
|
||||
#ifdef CONFIG_SND_PCM_OSS_PLUGINS
|
||||
if (runtime->oss.plugin_first) {
|
||||
err = snd_pcm_plug_alloc(substream, oss_period_size);
|
||||
|
@ -1017,7 +1025,10 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream)
|
|||
oss_period_size *= oss_frame_size;
|
||||
|
||||
oss_buffer_size = oss_period_size * runtime->oss.periods;
|
||||
snd_assert(oss_buffer_size >= 0, err = -EINVAL; goto failure);
|
||||
if (oss_buffer_size < 0) {
|
||||
err = -EINVAL;
|
||||
goto failure;
|
||||
}
|
||||
|
||||
runtime->oss.period_bytes = oss_period_size;
|
||||
runtime->oss.buffer_bytes = oss_buffer_size;
|
||||
|
@ -1069,7 +1080,8 @@ static int snd_pcm_oss_get_active_substream(struct snd_pcm_oss_file *pcm_oss_fil
|
|||
return err;
|
||||
}
|
||||
}
|
||||
snd_assert(asubstream != NULL, return -EIO);
|
||||
if (!asubstream)
|
||||
return -EIO;
|
||||
if (r_substream)
|
||||
*r_substream = asubstream;
|
||||
return 0;
|
||||
|
@ -1764,7 +1776,8 @@ static int snd_pcm_oss_get_formats(struct snd_pcm_oss_file *pcm_oss_file)
|
|||
err = snd_pcm_hw_refine(substream, params);
|
||||
format_mask = *hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
|
||||
kfree(params);
|
||||
snd_assert(err >= 0, return err);
|
||||
if (err < 0)
|
||||
return err;
|
||||
for (fmt = 0; fmt < 32; ++fmt) {
|
||||
if (snd_mask_test(&format_mask, fmt)) {
|
||||
int f = snd_pcm_oss_format_to(fmt);
|
||||
|
@ -2250,7 +2263,8 @@ static void snd_pcm_oss_init_substream(struct snd_pcm_substream *substream,
|
|||
static int snd_pcm_oss_release_file(struct snd_pcm_oss_file *pcm_oss_file)
|
||||
{
|
||||
int cidx;
|
||||
snd_assert(pcm_oss_file != NULL, return -ENXIO);
|
||||
if (!pcm_oss_file)
|
||||
return 0;
|
||||
for (cidx = 0; cidx < 2; ++cidx) {
|
||||
struct snd_pcm_substream *substream = pcm_oss_file->streams[cidx];
|
||||
if (substream)
|
||||
|
@ -2271,8 +2285,8 @@ static int snd_pcm_oss_open_file(struct file *file,
|
|||
struct snd_pcm_substream *substream;
|
||||
unsigned int f_mode = file->f_mode;
|
||||
|
||||
snd_assert(rpcm_oss_file != NULL, return -EINVAL);
|
||||
*rpcm_oss_file = NULL;
|
||||
if (rpcm_oss_file)
|
||||
*rpcm_oss_file = NULL;
|
||||
|
||||
pcm_oss_file = kzalloc(sizeof(*pcm_oss_file), GFP_KERNEL);
|
||||
if (pcm_oss_file == NULL)
|
||||
|
@ -2312,7 +2326,8 @@ static int snd_pcm_oss_open_file(struct file *file,
|
|||
}
|
||||
|
||||
file->private_data = pcm_oss_file;
|
||||
*rpcm_oss_file = pcm_oss_file;
|
||||
if (rpcm_oss_file)
|
||||
*rpcm_oss_file = pcm_oss_file;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2321,7 +2336,8 @@ static int snd_task_name(struct task_struct *task, char *name, size_t size)
|
|||
{
|
||||
unsigned int idx;
|
||||
|
||||
snd_assert(task != NULL && name != NULL && size >= 2, return -EINVAL);
|
||||
if (snd_BUG_ON(!task || !name || size < 2))
|
||||
return -EINVAL;
|
||||
for (idx = 0; idx < sizeof(task->comm) && idx + 1 < size; idx++)
|
||||
name[idx] = task->comm[idx];
|
||||
name[idx] = '\0';
|
||||
|
@ -2415,7 +2431,8 @@ static int snd_pcm_oss_release(struct inode *inode, struct file *file)
|
|||
substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK];
|
||||
if (substream == NULL)
|
||||
substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE];
|
||||
snd_assert(substream != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!substream))
|
||||
return -ENXIO;
|
||||
pcm = substream->pcm;
|
||||
if (!pcm->card->shutdown)
|
||||
snd_pcm_oss_sync(pcm_oss_file);
|
||||
|
@ -2448,7 +2465,8 @@ static long snd_pcm_oss_ioctl(struct file *file, unsigned int cmd, unsigned long
|
|||
if (substream != NULL)
|
||||
break;
|
||||
}
|
||||
snd_assert(substream != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(idx >= 2))
|
||||
return -ENXIO;
|
||||
return snd_mixer_oss_ioctl_card(substream->pcm->card, cmd, arg);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -62,7 +62,8 @@ static int snd_pcm_plugin_alloc(struct snd_pcm_plugin *plugin, snd_pcm_uframes_t
|
|||
if ((width = snd_pcm_format_physical_width(format->format)) < 0)
|
||||
return width;
|
||||
size = frames * format->channels * width;
|
||||
snd_assert((size % 8) == 0, return -ENXIO);
|
||||
if (snd_BUG_ON(size % 8))
|
||||
return -ENXIO;
|
||||
size /= 8;
|
||||
if (plugin->buf_frames < frames) {
|
||||
vfree(plugin->buf);
|
||||
|
@ -84,7 +85,8 @@ static int snd_pcm_plugin_alloc(struct snd_pcm_plugin *plugin, snd_pcm_uframes_t
|
|||
c->area.step = format->channels * width;
|
||||
}
|
||||
} else if (plugin->access == SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) {
|
||||
snd_assert((size % format->channels) == 0,);
|
||||
if (snd_BUG_ON(size % format->channels))
|
||||
return -EINVAL;
|
||||
size /= format->channels;
|
||||
for (channel = 0; channel < format->channels; channel++, c++) {
|
||||
c->frames = frames;
|
||||
|
@ -102,13 +104,15 @@ static int snd_pcm_plugin_alloc(struct snd_pcm_plugin *plugin, snd_pcm_uframes_t
|
|||
int snd_pcm_plug_alloc(struct snd_pcm_substream *plug, snd_pcm_uframes_t frames)
|
||||
{
|
||||
int err;
|
||||
snd_assert(snd_pcm_plug_first(plug) != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!snd_pcm_plug_first(plug)))
|
||||
return -ENXIO;
|
||||
if (snd_pcm_plug_stream(plug) == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
struct snd_pcm_plugin *plugin = snd_pcm_plug_first(plug);
|
||||
while (plugin->next) {
|
||||
if (plugin->dst_frames)
|
||||
frames = plugin->dst_frames(plugin, frames);
|
||||
snd_assert(frames > 0, return -ENXIO);
|
||||
if (snd_BUG_ON(frames <= 0))
|
||||
return -ENXIO;
|
||||
plugin = plugin->next;
|
||||
err = snd_pcm_plugin_alloc(plugin, frames);
|
||||
if (err < 0)
|
||||
|
@ -119,7 +123,8 @@ int snd_pcm_plug_alloc(struct snd_pcm_substream *plug, snd_pcm_uframes_t frames)
|
|||
while (plugin->prev) {
|
||||
if (plugin->src_frames)
|
||||
frames = plugin->src_frames(plugin, frames);
|
||||
snd_assert(frames > 0, return -ENXIO);
|
||||
if (snd_BUG_ON(frames <= 0))
|
||||
return -ENXIO;
|
||||
plugin = plugin->prev;
|
||||
err = snd_pcm_plugin_alloc(plugin, frames);
|
||||
if (err < 0)
|
||||
|
@ -148,8 +153,10 @@ int snd_pcm_plugin_build(struct snd_pcm_substream *plug,
|
|||
struct snd_pcm_plugin *plugin;
|
||||
unsigned int channels;
|
||||
|
||||
snd_assert(plug != NULL, return -ENXIO);
|
||||
snd_assert(src_format != NULL && dst_format != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!plug))
|
||||
return -ENXIO;
|
||||
if (snd_BUG_ON(!src_format || !dst_format))
|
||||
return -ENXIO;
|
||||
plugin = kzalloc(sizeof(*plugin) + extra, GFP_KERNEL);
|
||||
if (plugin == NULL)
|
||||
return -ENOMEM;
|
||||
|
@ -159,10 +166,10 @@ int snd_pcm_plugin_build(struct snd_pcm_substream *plug,
|
|||
plugin->access = SNDRV_PCM_ACCESS_RW_INTERLEAVED;
|
||||
plugin->src_format = *src_format;
|
||||
plugin->src_width = snd_pcm_format_physical_width(src_format->format);
|
||||
snd_assert(plugin->src_width > 0, );
|
||||
snd_BUG_ON(plugin->src_width <= 0);
|
||||
plugin->dst_format = *dst_format;
|
||||
plugin->dst_width = snd_pcm_format_physical_width(dst_format->format);
|
||||
snd_assert(plugin->dst_width > 0, );
|
||||
snd_BUG_ON(plugin->dst_width <= 0);
|
||||
if (plugin->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
channels = src_format->channels;
|
||||
else
|
||||
|
@ -194,7 +201,8 @@ snd_pcm_sframes_t snd_pcm_plug_client_size(struct snd_pcm_substream *plug, snd_p
|
|||
struct snd_pcm_plugin *plugin, *plugin_prev, *plugin_next;
|
||||
int stream = snd_pcm_plug_stream(plug);
|
||||
|
||||
snd_assert(plug != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!plug))
|
||||
return -ENXIO;
|
||||
if (drv_frames == 0)
|
||||
return 0;
|
||||
if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
|
@ -224,7 +232,8 @@ snd_pcm_sframes_t snd_pcm_plug_slave_size(struct snd_pcm_substream *plug, snd_pc
|
|||
snd_pcm_sframes_t frames;
|
||||
int stream = snd_pcm_plug_stream(plug);
|
||||
|
||||
snd_assert(plug != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!plug))
|
||||
return -ENXIO;
|
||||
if (clt_frames == 0)
|
||||
return 0;
|
||||
frames = clt_frames;
|
||||
|
@ -540,7 +549,8 @@ snd_pcm_sframes_t snd_pcm_plug_client_channels_buf(struct snd_pcm_substream *plu
|
|||
int width, nchannels, channel;
|
||||
int stream = snd_pcm_plug_stream(plug);
|
||||
|
||||
snd_assert(buf != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!buf))
|
||||
return -ENXIO;
|
||||
if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
plugin = snd_pcm_plug_first(plug);
|
||||
format = &plugin->src_format;
|
||||
|
@ -553,7 +563,9 @@ snd_pcm_sframes_t snd_pcm_plug_client_channels_buf(struct snd_pcm_substream *plu
|
|||
if ((width = snd_pcm_format_physical_width(format->format)) < 0)
|
||||
return width;
|
||||
nchannels = format->channels;
|
||||
snd_assert(plugin->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED || format->channels <= 1, return -ENXIO);
|
||||
if (snd_BUG_ON(plugin->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED &&
|
||||
format->channels > 1))
|
||||
return -ENXIO;
|
||||
for (channel = 0; channel < nchannels; channel++, v++) {
|
||||
v->frames = count;
|
||||
v->enabled = 1;
|
||||
|
|
|
@ -185,7 +185,8 @@ static snd_pcm_sframes_t rate_src_frames(struct snd_pcm_plugin *plugin, snd_pcm_
|
|||
struct rate_priv *data;
|
||||
snd_pcm_sframes_t res;
|
||||
|
||||
snd_assert(plugin != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!plugin))
|
||||
return -ENXIO;
|
||||
if (frames == 0)
|
||||
return 0;
|
||||
data = (struct rate_priv *)plugin->extra_data;
|
||||
|
@ -217,7 +218,8 @@ static snd_pcm_sframes_t rate_dst_frames(struct snd_pcm_plugin *plugin, snd_pcm_
|
|||
struct rate_priv *data;
|
||||
snd_pcm_sframes_t res;
|
||||
|
||||
snd_assert(plugin != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!plugin))
|
||||
return -ENXIO;
|
||||
if (frames == 0)
|
||||
return 0;
|
||||
data = (struct rate_priv *)plugin->extra_data;
|
||||
|
@ -252,19 +254,20 @@ static snd_pcm_sframes_t rate_transfer(struct snd_pcm_plugin *plugin,
|
|||
snd_pcm_uframes_t dst_frames;
|
||||
struct rate_priv *data;
|
||||
|
||||
snd_assert(plugin != NULL && src_channels != NULL && dst_channels != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!plugin || !src_channels || !dst_channels))
|
||||
return -ENXIO;
|
||||
if (frames == 0)
|
||||
return 0;
|
||||
#ifdef CONFIG_SND_DEBUG
|
||||
{
|
||||
unsigned int channel;
|
||||
for (channel = 0; channel < plugin->src_format.channels; channel++) {
|
||||
snd_assert(src_channels[channel].area.first % 8 == 0 &&
|
||||
src_channels[channel].area.step % 8 == 0,
|
||||
return -ENXIO);
|
||||
snd_assert(dst_channels[channel].area.first % 8 == 0 &&
|
||||
dst_channels[channel].area.step % 8 == 0,
|
||||
return -ENXIO);
|
||||
if (snd_BUG_ON(src_channels[channel].area.first % 8 ||
|
||||
src_channels[channel].area.step % 8))
|
||||
return -ENXIO;
|
||||
if (snd_BUG_ON(dst_channels[channel].area.first % 8 ||
|
||||
dst_channels[channel].area.step % 8))
|
||||
return -ENXIO;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -281,7 +284,8 @@ static int rate_action(struct snd_pcm_plugin *plugin,
|
|||
enum snd_pcm_plugin_action action,
|
||||
unsigned long udata)
|
||||
{
|
||||
snd_assert(plugin != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!plugin))
|
||||
return -ENXIO;
|
||||
switch (action) {
|
||||
case INIT:
|
||||
case PREPARE:
|
||||
|
@ -302,14 +306,20 @@ int snd_pcm_plugin_build_rate(struct snd_pcm_substream *plug,
|
|||
struct rate_priv *data;
|
||||
struct snd_pcm_plugin *plugin;
|
||||
|
||||
snd_assert(r_plugin != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!r_plugin))
|
||||
return -ENXIO;
|
||||
*r_plugin = NULL;
|
||||
|
||||
snd_assert(src_format->channels == dst_format->channels, return -ENXIO);
|
||||
snd_assert(src_format->channels > 0, return -ENXIO);
|
||||
snd_assert(src_format->format == SNDRV_PCM_FORMAT_S16, return -ENXIO);
|
||||
snd_assert(dst_format->format == SNDRV_PCM_FORMAT_S16, return -ENXIO);
|
||||
snd_assert(src_format->rate != dst_format->rate, return -ENXIO);
|
||||
if (snd_BUG_ON(src_format->channels != dst_format->channels))
|
||||
return -ENXIO;
|
||||
if (snd_BUG_ON(src_format->channels <= 0))
|
||||
return -ENXIO;
|
||||
if (snd_BUG_ON(src_format->format != SNDRV_PCM_FORMAT_S16))
|
||||
return -ENXIO;
|
||||
if (snd_BUG_ON(dst_format->format != SNDRV_PCM_FORMAT_S16))
|
||||
return -ENXIO;
|
||||
if (snd_BUG_ON(src_format->rate == dst_format->rate))
|
||||
return -ENXIO;
|
||||
|
||||
err = snd_pcm_plugin_build(plug, "rate conversion",
|
||||
src_format, dst_format,
|
||||
|
|
|
@ -54,7 +54,8 @@ static snd_pcm_sframes_t route_transfer(struct snd_pcm_plugin *plugin,
|
|||
struct snd_pcm_plugin_channel *dvp;
|
||||
int format;
|
||||
|
||||
snd_assert(plugin != NULL && src_channels != NULL && dst_channels != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!plugin || !src_channels || !dst_channels))
|
||||
return -ENXIO;
|
||||
if (frames == 0)
|
||||
return 0;
|
||||
|
||||
|
@ -90,10 +91,13 @@ int snd_pcm_plugin_build_route(struct snd_pcm_substream *plug,
|
|||
struct snd_pcm_plugin *plugin;
|
||||
int err;
|
||||
|
||||
snd_assert(r_plugin != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!r_plugin))
|
||||
return -ENXIO;
|
||||
*r_plugin = NULL;
|
||||
snd_assert(src_format->rate == dst_format->rate, return -ENXIO);
|
||||
snd_assert(src_format->format == dst_format->format, return -ENXIO);
|
||||
if (snd_BUG_ON(src_format->rate != dst_format->rate))
|
||||
return -ENXIO;
|
||||
if (snd_BUG_ON(src_format->format != dst_format->format))
|
||||
return -ENXIO;
|
||||
|
||||
err = snd_pcm_plugin_build(plug, "route conversion",
|
||||
src_format, dst_format, 0, &plugin);
|
||||
|
|
|
@ -42,7 +42,7 @@ static int snd_pcm_dev_free(struct snd_device *device);
|
|||
static int snd_pcm_dev_register(struct snd_device *device);
|
||||
static int snd_pcm_dev_disconnect(struct snd_device *device);
|
||||
|
||||
static struct snd_pcm *snd_pcm_search(struct snd_card *card, int device)
|
||||
static struct snd_pcm *snd_pcm_get(struct snd_card *card, int device)
|
||||
{
|
||||
struct snd_pcm *pcm;
|
||||
|
||||
|
@ -53,6 +53,37 @@ static struct snd_pcm *snd_pcm_search(struct snd_card *card, int device)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static int snd_pcm_next(struct snd_card *card, int device)
|
||||
{
|
||||
struct snd_pcm *pcm;
|
||||
|
||||
list_for_each_entry(pcm, &snd_pcm_devices, list) {
|
||||
if (pcm->card == card && pcm->device > device)
|
||||
return pcm->device;
|
||||
else if (pcm->card->number > card->number)
|
||||
return -1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int snd_pcm_add(struct snd_pcm *newpcm)
|
||||
{
|
||||
struct snd_pcm *pcm;
|
||||
|
||||
list_for_each_entry(pcm, &snd_pcm_devices, list) {
|
||||
if (pcm->card == newpcm->card && pcm->device == newpcm->device)
|
||||
return -EBUSY;
|
||||
if (pcm->card->number > newpcm->card->number ||
|
||||
(pcm->card == newpcm->card &&
|
||||
pcm->device > newpcm->device)) {
|
||||
list_add(&newpcm->list, pcm->list.prev);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
list_add_tail(&newpcm->list, &snd_pcm_devices);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_pcm_control_ioctl(struct snd_card *card,
|
||||
struct snd_ctl_file *control,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
|
@ -65,14 +96,7 @@ static int snd_pcm_control_ioctl(struct snd_card *card,
|
|||
if (get_user(device, (int __user *)arg))
|
||||
return -EFAULT;
|
||||
mutex_lock(®ister_mutex);
|
||||
device = device < 0 ? 0 : device + 1;
|
||||
while (device < SNDRV_PCM_DEVICES) {
|
||||
if (snd_pcm_search(card, device))
|
||||
break;
|
||||
device++;
|
||||
}
|
||||
if (device == SNDRV_PCM_DEVICES)
|
||||
device = -1;
|
||||
device = snd_pcm_next(card, device);
|
||||
mutex_unlock(®ister_mutex);
|
||||
if (put_user(device, (int __user *)arg))
|
||||
return -EFAULT;
|
||||
|
@ -98,7 +122,7 @@ static int snd_pcm_control_ioctl(struct snd_card *card,
|
|||
if (get_user(subdevice, &info->subdevice))
|
||||
return -EFAULT;
|
||||
mutex_lock(®ister_mutex);
|
||||
pcm = snd_pcm_search(card, device);
|
||||
pcm = snd_pcm_get(card, device);
|
||||
if (pcm == NULL) {
|
||||
err = -ENXIO;
|
||||
goto _error;
|
||||
|
@ -232,7 +256,6 @@ static char *snd_pcm_tstamp_mode_names[] = {
|
|||
|
||||
static const char *snd_pcm_stream_name(int stream)
|
||||
{
|
||||
snd_assert(stream <= SNDRV_PCM_STREAM_LAST, return NULL);
|
||||
return snd_pcm_stream_names[stream];
|
||||
}
|
||||
|
||||
|
@ -248,7 +271,6 @@ static const char *snd_pcm_subformat_name(snd_pcm_subformat_t subformat)
|
|||
|
||||
static const char *snd_pcm_tstamp_mode_name(int mode)
|
||||
{
|
||||
snd_assert(mode <= SNDRV_PCM_TSTAMP_LAST, return NULL);
|
||||
return snd_pcm_tstamp_mode_names[mode];
|
||||
}
|
||||
|
||||
|
@ -682,9 +704,10 @@ int snd_pcm_new(struct snd_card *card, char *id, int device,
|
|||
.dev_disconnect = snd_pcm_dev_disconnect,
|
||||
};
|
||||
|
||||
snd_assert(rpcm != NULL, return -EINVAL);
|
||||
*rpcm = NULL;
|
||||
snd_assert(card != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!card))
|
||||
return -ENXIO;
|
||||
if (rpcm)
|
||||
*rpcm = NULL;
|
||||
pcm = kzalloc(sizeof(*pcm), GFP_KERNEL);
|
||||
if (pcm == NULL) {
|
||||
snd_printk(KERN_ERR "Cannot allocate PCM\n");
|
||||
|
@ -708,7 +731,8 @@ int snd_pcm_new(struct snd_card *card, char *id, int device,
|
|||
snd_pcm_free(pcm);
|
||||
return err;
|
||||
}
|
||||
*rpcm = pcm;
|
||||
if (rpcm)
|
||||
*rpcm = pcm;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -742,7 +766,8 @@ static int snd_pcm_free(struct snd_pcm *pcm)
|
|||
{
|
||||
struct snd_pcm_notify *notify;
|
||||
|
||||
snd_assert(pcm != NULL, return -ENXIO);
|
||||
if (!pcm)
|
||||
return 0;
|
||||
list_for_each_entry(notify, &snd_pcm_notify_list, list) {
|
||||
notify->n_unregister(pcm);
|
||||
}
|
||||
|
@ -773,9 +798,9 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
|
|||
int prefer_subdevice = -1;
|
||||
size_t size;
|
||||
|
||||
snd_assert(rsubstream != NULL, return -EINVAL);
|
||||
if (snd_BUG_ON(!pcm || !rsubstream))
|
||||
return -ENXIO;
|
||||
*rsubstream = NULL;
|
||||
snd_assert(pcm != NULL, return -ENXIO);
|
||||
pstr = &pcm->streams[stream];
|
||||
if (pstr->substream == NULL || pstr->substream_count == 0)
|
||||
return -ENODEV;
|
||||
|
@ -883,8 +908,9 @@ void snd_pcm_detach_substream(struct snd_pcm_substream *substream)
|
|||
{
|
||||
struct snd_pcm_runtime *runtime;
|
||||
|
||||
if (PCM_RUNTIME_CHECK(substream))
|
||||
return;
|
||||
runtime = substream->runtime;
|
||||
snd_assert(runtime != NULL, return);
|
||||
if (runtime->private_free != NULL)
|
||||
runtime->private_free(runtime);
|
||||
snd_free_pages((void*)runtime->status,
|
||||
|
@ -929,13 +955,14 @@ static int snd_pcm_dev_register(struct snd_device *device)
|
|||
struct snd_pcm *pcm = device->device_data;
|
||||
struct device *dev;
|
||||
|
||||
snd_assert(pcm != NULL && device != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!pcm || !device))
|
||||
return -ENXIO;
|
||||
mutex_lock(®ister_mutex);
|
||||
if (snd_pcm_search(pcm->card, pcm->device)) {
|
||||
err = snd_pcm_add(pcm);
|
||||
if (err) {
|
||||
mutex_unlock(®ister_mutex);
|
||||
return -EBUSY;
|
||||
return err;
|
||||
}
|
||||
list_add_tail(&pcm->list, &snd_pcm_devices);
|
||||
for (cidx = 0; cidx < 2; cidx++) {
|
||||
int devtype = -1;
|
||||
if (pcm->streams[cidx].substream == NULL)
|
||||
|
@ -1019,10 +1046,11 @@ int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree)
|
|||
{
|
||||
struct snd_pcm *pcm;
|
||||
|
||||
snd_assert(notify != NULL &&
|
||||
notify->n_register != NULL &&
|
||||
notify->n_unregister != NULL &&
|
||||
notify->n_disconnect, return -EINVAL);
|
||||
if (snd_BUG_ON(!notify ||
|
||||
!notify->n_register ||
|
||||
!notify->n_unregister ||
|
||||
!notify->n_disconnect))
|
||||
return -EINVAL;
|
||||
mutex_lock(®ister_mutex);
|
||||
if (nfree) {
|
||||
list_del(¬ify->list);
|
||||
|
|
|
@ -397,7 +397,8 @@ static int snd_pcm_ioctl_sync_ptr_compat(struct snd_pcm_substream *substream,
|
|||
snd_pcm_uframes_t boundary;
|
||||
int err;
|
||||
|
||||
snd_assert(runtime, return -EINVAL);
|
||||
if (snd_BUG_ON(!runtime))
|
||||
return -EINVAL;
|
||||
|
||||
if (get_user(sflags, &src->flags) ||
|
||||
get_user(scontrol.appl_ptr, &src->c.control.appl_ptr) ||
|
||||
|
|
|
@ -85,7 +85,8 @@ void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_ufram
|
|||
}
|
||||
frames = runtime->buffer_size - runtime->silence_filled;
|
||||
}
|
||||
snd_assert(frames <= runtime->buffer_size, return);
|
||||
if (snd_BUG_ON(frames > runtime->buffer_size))
|
||||
return;
|
||||
if (frames == 0)
|
||||
return;
|
||||
ofs = runtime->silence_start % runtime->buffer_size;
|
||||
|
@ -96,7 +97,7 @@ void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_ufram
|
|||
if (substream->ops->silence) {
|
||||
int err;
|
||||
err = substream->ops->silence(substream, -1, ofs, transfer);
|
||||
snd_assert(err >= 0, );
|
||||
snd_BUG_ON(err < 0);
|
||||
} else {
|
||||
char *hwbuf = runtime->dma_area + frames_to_bytes(runtime, ofs);
|
||||
snd_pcm_format_set_silence(runtime->format, hwbuf, transfer * runtime->channels);
|
||||
|
@ -108,7 +109,7 @@ void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_ufram
|
|||
for (c = 0; c < channels; ++c) {
|
||||
int err;
|
||||
err = substream->ops->silence(substream, c, ofs, transfer);
|
||||
snd_assert(err >= 0, );
|
||||
snd_BUG_ON(err < 0);
|
||||
}
|
||||
} else {
|
||||
size_t dma_csize = runtime->dma_bytes / channels;
|
||||
|
@ -354,7 +355,7 @@ static inline unsigned int muldiv32(unsigned int a, unsigned int b,
|
|||
{
|
||||
u_int64_t n = (u_int64_t) a * b;
|
||||
if (c == 0) {
|
||||
snd_assert(n > 0, );
|
||||
snd_BUG_ON(!n);
|
||||
*r = 0;
|
||||
return UINT_MAX;
|
||||
}
|
||||
|
@ -380,7 +381,8 @@ static inline unsigned int muldiv32(unsigned int a, unsigned int b,
|
|||
int snd_interval_refine(struct snd_interval *i, const struct snd_interval *v)
|
||||
{
|
||||
int changed = 0;
|
||||
snd_assert(!snd_interval_empty(i), return -EINVAL);
|
||||
if (snd_BUG_ON(snd_interval_empty(i)))
|
||||
return -EINVAL;
|
||||
if (i->min < v->min) {
|
||||
i->min = v->min;
|
||||
i->openmin = v->openmin;
|
||||
|
@ -423,7 +425,8 @@ EXPORT_SYMBOL(snd_interval_refine);
|
|||
|
||||
static int snd_interval_refine_first(struct snd_interval *i)
|
||||
{
|
||||
snd_assert(!snd_interval_empty(i), return -EINVAL);
|
||||
if (snd_BUG_ON(snd_interval_empty(i)))
|
||||
return -EINVAL;
|
||||
if (snd_interval_single(i))
|
||||
return 0;
|
||||
i->max = i->min;
|
||||
|
@ -435,7 +438,8 @@ static int snd_interval_refine_first(struct snd_interval *i)
|
|||
|
||||
static int snd_interval_refine_last(struct snd_interval *i)
|
||||
{
|
||||
snd_assert(!snd_interval_empty(i), return -EINVAL);
|
||||
if (snd_BUG_ON(snd_interval_empty(i)))
|
||||
return -EINVAL;
|
||||
if (snd_interval_single(i))
|
||||
return 0;
|
||||
i->min = i->max;
|
||||
|
@ -889,7 +893,8 @@ int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, unsigned int cond,
|
|||
c->private = private;
|
||||
k = 0;
|
||||
while (1) {
|
||||
snd_assert(k < ARRAY_SIZE(c->deps), return -EINVAL);
|
||||
if (snd_BUG_ON(k >= ARRAY_SIZE(c->deps)))
|
||||
return -EINVAL;
|
||||
c->deps[k++] = dep;
|
||||
if (dep < 0)
|
||||
break;
|
||||
|
@ -1285,7 +1290,8 @@ int snd_pcm_hw_param_first(struct snd_pcm_substream *pcm,
|
|||
return changed;
|
||||
if (params->rmask) {
|
||||
int err = snd_pcm_hw_refine(pcm, params);
|
||||
snd_assert(err >= 0, return err);
|
||||
if (snd_BUG_ON(err < 0))
|
||||
return err;
|
||||
}
|
||||
return snd_pcm_hw_param_value(params, var, dir);
|
||||
}
|
||||
|
@ -1330,7 +1336,8 @@ int snd_pcm_hw_param_last(struct snd_pcm_substream *pcm,
|
|||
return changed;
|
||||
if (params->rmask) {
|
||||
int err = snd_pcm_hw_refine(pcm, params);
|
||||
snd_assert(err >= 0, return err);
|
||||
if (snd_BUG_ON(err < 0))
|
||||
return err;
|
||||
}
|
||||
return snd_pcm_hw_param_value(params, var, dir);
|
||||
}
|
||||
|
@ -1368,7 +1375,8 @@ int snd_pcm_hw_params_choose(struct snd_pcm_substream *pcm,
|
|||
err = snd_pcm_hw_param_first(pcm, params, *v, NULL);
|
||||
else
|
||||
err = snd_pcm_hw_param_last(pcm, params, *v, NULL);
|
||||
snd_assert(err >= 0, return err);
|
||||
if (snd_BUG_ON(err < 0))
|
||||
return err;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -1466,9 +1474,9 @@ void snd_pcm_period_elapsed(struct snd_pcm_substream *substream)
|
|||
struct snd_pcm_runtime *runtime;
|
||||
unsigned long flags;
|
||||
|
||||
snd_assert(substream != NULL, return);
|
||||
if (PCM_RUNTIME_CHECK(substream))
|
||||
return;
|
||||
runtime = substream->runtime;
|
||||
snd_assert(runtime != NULL, return);
|
||||
|
||||
if (runtime->transfer_ack_begin)
|
||||
runtime->transfer_ack_begin(substream);
|
||||
|
@ -1567,7 +1575,6 @@ static int snd_pcm_lib_write_transfer(struct snd_pcm_substream *substream,
|
|||
return err;
|
||||
} else {
|
||||
char *hwbuf = runtime->dma_area + frames_to_bytes(runtime, hwoff);
|
||||
snd_assert(runtime->dma_area, return -EFAULT);
|
||||
if (copy_from_user(hwbuf, buf, frames_to_bytes(runtime, frames)))
|
||||
return -EFAULT;
|
||||
}
|
||||
|
@ -1629,7 +1636,10 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream,
|
|||
cont = runtime->buffer_size - runtime->control->appl_ptr % runtime->buffer_size;
|
||||
if (frames > cont)
|
||||
frames = cont;
|
||||
snd_assert(frames != 0, snd_pcm_stream_unlock_irq(substream); return -EINVAL);
|
||||
if (snd_BUG_ON(!frames)) {
|
||||
snd_pcm_stream_unlock_irq(substream);
|
||||
return -EINVAL;
|
||||
}
|
||||
appl_ptr = runtime->control->appl_ptr;
|
||||
appl_ofs = appl_ptr % runtime->buffer_size;
|
||||
snd_pcm_stream_unlock_irq(substream);
|
||||
|
@ -1669,18 +1679,30 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream,
|
|||
return xfer > 0 ? (snd_pcm_sframes_t)xfer : err;
|
||||
}
|
||||
|
||||
/* sanity-check for read/write methods */
|
||||
static int pcm_sanity_check(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_pcm_runtime *runtime;
|
||||
if (PCM_RUNTIME_CHECK(substream))
|
||||
return -ENXIO;
|
||||
runtime = substream->runtime;
|
||||
if (snd_BUG_ON(!substream->ops->copy && !runtime->dma_area))
|
||||
return -EINVAL;
|
||||
if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
|
||||
return -EBADFD;
|
||||
return 0;
|
||||
}
|
||||
|
||||
snd_pcm_sframes_t snd_pcm_lib_write(struct snd_pcm_substream *substream, const void __user *buf, snd_pcm_uframes_t size)
|
||||
{
|
||||
struct snd_pcm_runtime *runtime;
|
||||
int nonblock;
|
||||
int err;
|
||||
|
||||
snd_assert(substream != NULL, return -ENXIO);
|
||||
err = pcm_sanity_check(substream);
|
||||
if (err < 0)
|
||||
return err;
|
||||
runtime = substream->runtime;
|
||||
snd_assert(runtime != NULL, return -ENXIO);
|
||||
snd_assert(substream->ops->copy != NULL || runtime->dma_area != NULL, return -EINVAL);
|
||||
if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
|
||||
return -EBADFD;
|
||||
|
||||
nonblock = !!(substream->f_flags & O_NONBLOCK);
|
||||
|
||||
if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED &&
|
||||
|
@ -1703,7 +1725,8 @@ static int snd_pcm_lib_writev_transfer(struct snd_pcm_substream *substream,
|
|||
int channels = runtime->channels;
|
||||
int c;
|
||||
if (substream->ops->copy) {
|
||||
snd_assert(substream->ops->silence != NULL, return -EINVAL);
|
||||
if (snd_BUG_ON(!substream->ops->silence))
|
||||
return -EINVAL;
|
||||
for (c = 0; c < channels; ++c, ++bufs) {
|
||||
if (*bufs == NULL) {
|
||||
if ((err = substream->ops->silence(substream, c, hwoff, frames)) < 0)
|
||||
|
@ -1717,7 +1740,6 @@ static int snd_pcm_lib_writev_transfer(struct snd_pcm_substream *substream,
|
|||
} else {
|
||||
/* default transfer behaviour */
|
||||
size_t dma_csize = runtime->dma_bytes / channels;
|
||||
snd_assert(runtime->dma_area, return -EFAULT);
|
||||
for (c = 0; c < channels; ++c, ++bufs) {
|
||||
char *hwbuf = runtime->dma_area + (c * dma_csize) + samples_to_bytes(runtime, hwoff);
|
||||
if (*bufs == NULL) {
|
||||
|
@ -1738,14 +1760,12 @@ snd_pcm_sframes_t snd_pcm_lib_writev(struct snd_pcm_substream *substream,
|
|||
{
|
||||
struct snd_pcm_runtime *runtime;
|
||||
int nonblock;
|
||||
int err;
|
||||
|
||||
snd_assert(substream != NULL, return -ENXIO);
|
||||
err = pcm_sanity_check(substream);
|
||||
if (err < 0)
|
||||
return err;
|
||||
runtime = substream->runtime;
|
||||
snd_assert(runtime != NULL, return -ENXIO);
|
||||
snd_assert(substream->ops->copy != NULL || runtime->dma_area != NULL, return -EINVAL);
|
||||
if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
|
||||
return -EBADFD;
|
||||
|
||||
nonblock = !!(substream->f_flags & O_NONBLOCK);
|
||||
|
||||
if (runtime->access != SNDRV_PCM_ACCESS_RW_NONINTERLEAVED)
|
||||
|
@ -1769,7 +1789,6 @@ static int snd_pcm_lib_read_transfer(struct snd_pcm_substream *substream,
|
|||
return err;
|
||||
} else {
|
||||
char *hwbuf = runtime->dma_area + frames_to_bytes(runtime, hwoff);
|
||||
snd_assert(runtime->dma_area, return -EFAULT);
|
||||
if (copy_to_user(buf, hwbuf, frames_to_bytes(runtime, frames)))
|
||||
return -EFAULT;
|
||||
}
|
||||
|
@ -1841,7 +1860,10 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream,
|
|||
cont = runtime->buffer_size - runtime->control->appl_ptr % runtime->buffer_size;
|
||||
if (frames > cont)
|
||||
frames = cont;
|
||||
snd_assert(frames != 0, snd_pcm_stream_unlock_irq(substream); return -EINVAL);
|
||||
if (snd_BUG_ON(!frames)) {
|
||||
snd_pcm_stream_unlock_irq(substream);
|
||||
return -EINVAL;
|
||||
}
|
||||
appl_ptr = runtime->control->appl_ptr;
|
||||
appl_ofs = appl_ptr % runtime->buffer_size;
|
||||
snd_pcm_stream_unlock_irq(substream);
|
||||
|
@ -1879,14 +1901,12 @@ snd_pcm_sframes_t snd_pcm_lib_read(struct snd_pcm_substream *substream, void __u
|
|||
{
|
||||
struct snd_pcm_runtime *runtime;
|
||||
int nonblock;
|
||||
int err;
|
||||
|
||||
snd_assert(substream != NULL, return -ENXIO);
|
||||
err = pcm_sanity_check(substream);
|
||||
if (err < 0)
|
||||
return err;
|
||||
runtime = substream->runtime;
|
||||
snd_assert(runtime != NULL, return -ENXIO);
|
||||
snd_assert(substream->ops->copy != NULL || runtime->dma_area != NULL, return -EINVAL);
|
||||
if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
|
||||
return -EBADFD;
|
||||
|
||||
nonblock = !!(substream->f_flags & O_NONBLOCK);
|
||||
if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED)
|
||||
return -EINVAL;
|
||||
|
@ -1916,7 +1936,6 @@ static int snd_pcm_lib_readv_transfer(struct snd_pcm_substream *substream,
|
|||
}
|
||||
} else {
|
||||
snd_pcm_uframes_t dma_csize = runtime->dma_bytes / channels;
|
||||
snd_assert(runtime->dma_area, return -EFAULT);
|
||||
for (c = 0; c < channels; ++c, ++bufs) {
|
||||
char *hwbuf;
|
||||
char __user *buf;
|
||||
|
@ -1938,11 +1957,12 @@ snd_pcm_sframes_t snd_pcm_lib_readv(struct snd_pcm_substream *substream,
|
|||
{
|
||||
struct snd_pcm_runtime *runtime;
|
||||
int nonblock;
|
||||
int err;
|
||||
|
||||
snd_assert(substream != NULL, return -ENXIO);
|
||||
err = pcm_sanity_check(substream);
|
||||
if (err < 0)
|
||||
return err;
|
||||
runtime = substream->runtime;
|
||||
snd_assert(runtime != NULL, return -ENXIO);
|
||||
snd_assert(substream->ops->copy != NULL || runtime->dma_area != NULL, return -EINVAL);
|
||||
if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
|
||||
return -EBADFD;
|
||||
|
||||
|
|
|
@ -50,8 +50,6 @@ static int preallocate_pcm_pages(struct snd_pcm_substream *substream, size_t siz
|
|||
struct snd_dma_buffer *dmab = &substream->dma_buffer;
|
||||
int err;
|
||||
|
||||
snd_assert(size > 0, return -EINVAL);
|
||||
|
||||
/* already reserved? */
|
||||
if (snd_dma_get_reserved_buf(dmab, substream->dma_buf_id) > 0) {
|
||||
if (dmab->bytes >= size)
|
||||
|
@ -326,6 +324,32 @@ struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream, unsigne
|
|||
|
||||
EXPORT_SYMBOL(snd_pcm_sgbuf_ops_page);
|
||||
|
||||
/*
|
||||
* compute the max chunk size with continuous pages on sg-buffer
|
||||
*/
|
||||
unsigned int snd_pcm_sgbuf_get_chunk_size(struct snd_pcm_substream *substream,
|
||||
unsigned int ofs, unsigned int size)
|
||||
{
|
||||
struct snd_sg_buf *sg = snd_pcm_substream_sgbuf(substream);
|
||||
unsigned int start, end, pg;
|
||||
|
||||
start = ofs >> PAGE_SHIFT;
|
||||
end = (ofs + size - 1) >> PAGE_SHIFT;
|
||||
/* check page continuity */
|
||||
pg = sg->table[start].addr >> PAGE_SHIFT;
|
||||
for (;;) {
|
||||
start++;
|
||||
if (start > end)
|
||||
break;
|
||||
pg++;
|
||||
if ((sg->table[start].addr >> PAGE_SHIFT) != pg)
|
||||
return (start << PAGE_SHIFT) - ofs;
|
||||
}
|
||||
/* ok, all on continuous pages */
|
||||
return size;
|
||||
}
|
||||
EXPORT_SYMBOL(snd_pcm_sgbuf_get_chunk_size);
|
||||
|
||||
/**
|
||||
* snd_pcm_lib_malloc_pages - allocate the DMA buffer
|
||||
* @substream: the substream to allocate the DMA buffer to
|
||||
|
@ -342,10 +366,12 @@ int snd_pcm_lib_malloc_pages(struct snd_pcm_substream *substream, size_t size)
|
|||
struct snd_pcm_runtime *runtime;
|
||||
struct snd_dma_buffer *dmab = NULL;
|
||||
|
||||
snd_assert(substream->dma_buffer.dev.type != SNDRV_DMA_TYPE_UNKNOWN, return -EINVAL);
|
||||
snd_assert(substream != NULL, return -EINVAL);
|
||||
if (PCM_RUNTIME_CHECK(substream))
|
||||
return -EINVAL;
|
||||
if (snd_BUG_ON(substream->dma_buffer.dev.type ==
|
||||
SNDRV_DMA_TYPE_UNKNOWN))
|
||||
return -EINVAL;
|
||||
runtime = substream->runtime;
|
||||
snd_assert(runtime != NULL, return -EINVAL);
|
||||
|
||||
if (runtime->dma_buffer_p) {
|
||||
/* perphaps, we might free the large DMA memory region
|
||||
|
@ -391,9 +417,9 @@ int snd_pcm_lib_free_pages(struct snd_pcm_substream *substream)
|
|||
{
|
||||
struct snd_pcm_runtime *runtime;
|
||||
|
||||
snd_assert(substream != NULL, return -EINVAL);
|
||||
if (PCM_RUNTIME_CHECK(substream))
|
||||
return -EINVAL;
|
||||
runtime = substream->runtime;
|
||||
snd_assert(runtime != NULL, return -EINVAL);
|
||||
if (runtime->dma_area == NULL)
|
||||
return 0;
|
||||
if (runtime->dma_buffer_p != &substream->dma_buffer) {
|
||||
|
|
|
@ -95,7 +95,6 @@ int snd_pcm_info(struct snd_pcm_substream *substream, struct snd_pcm_info *info)
|
|||
struct snd_pcm *pcm = substream->pcm;
|
||||
struct snd_pcm_str *pstr = substream->pstr;
|
||||
|
||||
snd_assert(substream != NULL, return -ENXIO);
|
||||
memset(info, 0, sizeof(*info));
|
||||
info->card = pcm->card->number;
|
||||
info->device = pcm->device;
|
||||
|
@ -370,9 +369,9 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
|
|||
unsigned int bits;
|
||||
snd_pcm_uframes_t frames;
|
||||
|
||||
snd_assert(substream != NULL, return -ENXIO);
|
||||
if (PCM_RUNTIME_CHECK(substream))
|
||||
return -ENXIO;
|
||||
runtime = substream->runtime;
|
||||
snd_assert(runtime != NULL, return -ENXIO);
|
||||
snd_pcm_stream_lock_irq(substream);
|
||||
switch (runtime->status->state) {
|
||||
case SNDRV_PCM_STATE_OPEN:
|
||||
|
@ -490,9 +489,9 @@ static int snd_pcm_hw_free(struct snd_pcm_substream *substream)
|
|||
struct snd_pcm_runtime *runtime;
|
||||
int result = 0;
|
||||
|
||||
snd_assert(substream != NULL, return -ENXIO);
|
||||
if (PCM_RUNTIME_CHECK(substream))
|
||||
return -ENXIO;
|
||||
runtime = substream->runtime;
|
||||
snd_assert(runtime != NULL, return -ENXIO);
|
||||
snd_pcm_stream_lock_irq(substream);
|
||||
switch (runtime->status->state) {
|
||||
case SNDRV_PCM_STATE_SETUP:
|
||||
|
@ -518,9 +517,9 @@ static int snd_pcm_sw_params(struct snd_pcm_substream *substream,
|
|||
{
|
||||
struct snd_pcm_runtime *runtime;
|
||||
|
||||
snd_assert(substream != NULL, return -ENXIO);
|
||||
if (PCM_RUNTIME_CHECK(substream))
|
||||
return -ENXIO;
|
||||
runtime = substream->runtime;
|
||||
snd_assert(runtime != NULL, return -ENXIO);
|
||||
snd_pcm_stream_lock_irq(substream);
|
||||
if (runtime->status->state == SNDRV_PCM_STATE_OPEN) {
|
||||
snd_pcm_stream_unlock_irq(substream);
|
||||
|
@ -622,11 +621,8 @@ static int snd_pcm_status_user(struct snd_pcm_substream *substream,
|
|||
struct snd_pcm_status __user * _status)
|
||||
{
|
||||
struct snd_pcm_status status;
|
||||
struct snd_pcm_runtime *runtime;
|
||||
int res;
|
||||
|
||||
snd_assert(substream != NULL, return -ENXIO);
|
||||
runtime = substream->runtime;
|
||||
memset(&status, 0, sizeof(status));
|
||||
res = snd_pcm_status(substream, &status);
|
||||
if (res < 0)
|
||||
|
@ -642,7 +638,6 @@ static int snd_pcm_channel_info(struct snd_pcm_substream *substream,
|
|||
struct snd_pcm_runtime *runtime;
|
||||
unsigned int channel;
|
||||
|
||||
snd_assert(substream != NULL, return -ENXIO);
|
||||
channel = info->channel;
|
||||
runtime = substream->runtime;
|
||||
snd_pcm_stream_lock_irq(substream);
|
||||
|
@ -1250,7 +1245,6 @@ static int snd_pcm_do_reset(struct snd_pcm_substream *substream, int state)
|
|||
int err = substream->ops->ioctl(substream, SNDRV_PCM_IOCTL1_RESET, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
// snd_assert(runtime->status->hw_ptr < runtime->buffer_size, );
|
||||
runtime->hw_ptr_base = 0;
|
||||
runtime->hw_ptr_interrupt = runtime->status->hw_ptr -
|
||||
runtime->status->hw_ptr % runtime->period_size;
|
||||
|
@ -1421,7 +1415,6 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream)
|
|||
int i, num_drecs;
|
||||
struct drain_rec *drec, drec_tmp, *d;
|
||||
|
||||
snd_assert(substream != NULL, return -ENXIO);
|
||||
card = substream->pcm->card;
|
||||
runtime = substream->runtime;
|
||||
|
||||
|
@ -1541,7 +1534,8 @@ static int snd_pcm_drop(struct snd_pcm_substream *substream)
|
|||
struct snd_card *card;
|
||||
int result = 0;
|
||||
|
||||
snd_assert(substream != NULL, return -ENXIO);
|
||||
if (PCM_RUNTIME_CHECK(substream))
|
||||
return -ENXIO;
|
||||
runtime = substream->runtime;
|
||||
card = substream->pcm->card;
|
||||
|
||||
|
@ -1934,33 +1928,41 @@ int snd_pcm_hw_constraints_complete(struct snd_pcm_substream *substream)
|
|||
mask |= 1 << SNDRV_PCM_ACCESS_MMAP_COMPLEX;
|
||||
}
|
||||
err = snd_pcm_hw_constraint_mask(runtime, SNDRV_PCM_HW_PARAM_ACCESS, mask);
|
||||
snd_assert(err >= 0, return -EINVAL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = snd_pcm_hw_constraint_mask64(runtime, SNDRV_PCM_HW_PARAM_FORMAT, hw->formats);
|
||||
snd_assert(err >= 0, return -EINVAL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = snd_pcm_hw_constraint_mask(runtime, SNDRV_PCM_HW_PARAM_SUBFORMAT, 1 << SNDRV_PCM_SUBFORMAT_STD);
|
||||
snd_assert(err >= 0, return -EINVAL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_CHANNELS,
|
||||
hw->channels_min, hw->channels_max);
|
||||
snd_assert(err >= 0, return -EINVAL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_RATE,
|
||||
hw->rate_min, hw->rate_max);
|
||||
snd_assert(err >= 0, return -EINVAL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
|
||||
hw->period_bytes_min, hw->period_bytes_max);
|
||||
snd_assert(err >= 0, return -EINVAL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIODS,
|
||||
hw->periods_min, hw->periods_max);
|
||||
snd_assert(err >= 0, return -EINVAL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
|
||||
hw->period_bytes_min, hw->buffer_bytes_max);
|
||||
snd_assert(err >= 0, return -EINVAL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
|
||||
snd_pcm_hw_rule_buffer_bytes_max, substream,
|
||||
|
@ -1971,7 +1973,8 @@ int snd_pcm_hw_constraints_complete(struct snd_pcm_substream *substream)
|
|||
/* FIXME: remove */
|
||||
if (runtime->dma_bytes) {
|
||||
err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 0, runtime->dma_bytes);
|
||||
snd_assert(err >= 0, return -EINVAL);
|
||||
if (err < 0)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!(hw->rates & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))) {
|
||||
|
@ -2067,8 +2070,8 @@ static int snd_pcm_open_file(struct file *file,
|
|||
struct snd_pcm_str *str;
|
||||
int err;
|
||||
|
||||
snd_assert(rpcm_file != NULL, return -EINVAL);
|
||||
*rpcm_file = NULL;
|
||||
if (rpcm_file)
|
||||
*rpcm_file = NULL;
|
||||
|
||||
err = snd_pcm_open_substream(pcm, stream, file, &substream);
|
||||
if (err < 0)
|
||||
|
@ -2086,7 +2089,8 @@ static int snd_pcm_open_file(struct file *file,
|
|||
substream->pcm_release = pcm_release_private;
|
||||
}
|
||||
file->private_data = pcm_file;
|
||||
*rpcm_file = pcm_file;
|
||||
if (rpcm_file)
|
||||
*rpcm_file = pcm_file;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2170,7 +2174,8 @@ static int snd_pcm_release(struct inode *inode, struct file *file)
|
|||
|
||||
pcm_file = file->private_data;
|
||||
substream = pcm_file->substream;
|
||||
snd_assert(substream != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!substream))
|
||||
return -ENXIO;
|
||||
pcm = substream->pcm;
|
||||
fasync_helper(-1, file, 0, &substream->runtime->fasync);
|
||||
mutex_lock(&pcm->open_mutex);
|
||||
|
@ -2493,8 +2498,6 @@ static int snd_pcm_common_ioctl1(struct file *file,
|
|||
struct snd_pcm_substream *substream,
|
||||
unsigned int cmd, void __user *arg)
|
||||
{
|
||||
snd_assert(substream != NULL, return -ENXIO);
|
||||
|
||||
switch (cmd) {
|
||||
case SNDRV_PCM_IOCTL_PVERSION:
|
||||
return put_user(SNDRV_PCM_VERSION, (int __user *)arg) ? -EFAULT : 0;
|
||||
|
@ -2563,8 +2566,10 @@ static int snd_pcm_playback_ioctl1(struct file *file,
|
|||
struct snd_pcm_substream *substream,
|
||||
unsigned int cmd, void __user *arg)
|
||||
{
|
||||
snd_assert(substream != NULL, return -ENXIO);
|
||||
snd_assert(substream->stream == SNDRV_PCM_STREAM_PLAYBACK, return -EINVAL);
|
||||
if (snd_BUG_ON(!substream))
|
||||
return -ENXIO;
|
||||
if (snd_BUG_ON(substream->stream != SNDRV_PCM_STREAM_PLAYBACK))
|
||||
return -EINVAL;
|
||||
switch (cmd) {
|
||||
case SNDRV_PCM_IOCTL_WRITEI_FRAMES:
|
||||
{
|
||||
|
@ -2643,8 +2648,10 @@ static int snd_pcm_capture_ioctl1(struct file *file,
|
|||
struct snd_pcm_substream *substream,
|
||||
unsigned int cmd, void __user *arg)
|
||||
{
|
||||
snd_assert(substream != NULL, return -ENXIO);
|
||||
snd_assert(substream->stream == SNDRV_PCM_STREAM_CAPTURE, return -EINVAL);
|
||||
if (snd_BUG_ON(!substream))
|
||||
return -ENXIO;
|
||||
if (snd_BUG_ON(substream->stream != SNDRV_PCM_STREAM_CAPTURE))
|
||||
return -EINVAL;
|
||||
switch (cmd) {
|
||||
case SNDRV_PCM_IOCTL_READI_FRAMES:
|
||||
{
|
||||
|
@ -2783,7 +2790,8 @@ static ssize_t snd_pcm_read(struct file *file, char __user *buf, size_t count,
|
|||
|
||||
pcm_file = file->private_data;
|
||||
substream = pcm_file->substream;
|
||||
snd_assert(substream != NULL, return -ENXIO);
|
||||
if (PCM_RUNTIME_CHECK(substream))
|
||||
return -ENXIO;
|
||||
runtime = substream->runtime;
|
||||
if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
|
||||
return -EBADFD;
|
||||
|
@ -2806,21 +2814,17 @@ static ssize_t snd_pcm_write(struct file *file, const char __user *buf,
|
|||
|
||||
pcm_file = file->private_data;
|
||||
substream = pcm_file->substream;
|
||||
snd_assert(substream != NULL, result = -ENXIO; goto end);
|
||||
if (PCM_RUNTIME_CHECK(substream))
|
||||
return -ENXIO;
|
||||
runtime = substream->runtime;
|
||||
if (runtime->status->state == SNDRV_PCM_STATE_OPEN) {
|
||||
result = -EBADFD;
|
||||
goto end;
|
||||
}
|
||||
if (!frame_aligned(runtime, count)) {
|
||||
result = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
|
||||
return -EBADFD;
|
||||
if (!frame_aligned(runtime, count))
|
||||
return -EINVAL;
|
||||
count = bytes_to_frames(runtime, count);
|
||||
result = snd_pcm_lib_write(substream, buf, count);
|
||||
if (result > 0)
|
||||
result = frames_to_bytes(runtime, result);
|
||||
end:
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -2838,7 +2842,8 @@ static ssize_t snd_pcm_aio_read(struct kiocb *iocb, const struct iovec *iov,
|
|||
|
||||
pcm_file = iocb->ki_filp->private_data;
|
||||
substream = pcm_file->substream;
|
||||
snd_assert(substream != NULL, return -ENXIO);
|
||||
if (PCM_RUNTIME_CHECK(substream))
|
||||
return -ENXIO;
|
||||
runtime = substream->runtime;
|
||||
if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
|
||||
return -EBADFD;
|
||||
|
@ -2872,17 +2877,14 @@ static ssize_t snd_pcm_aio_write(struct kiocb *iocb, const struct iovec *iov,
|
|||
|
||||
pcm_file = iocb->ki_filp->private_data;
|
||||
substream = pcm_file->substream;
|
||||
snd_assert(substream != NULL, result = -ENXIO; goto end);
|
||||
if (PCM_RUNTIME_CHECK(substream))
|
||||
return -ENXIO;
|
||||
runtime = substream->runtime;
|
||||
if (runtime->status->state == SNDRV_PCM_STATE_OPEN) {
|
||||
result = -EBADFD;
|
||||
goto end;
|
||||
}
|
||||
if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
|
||||
return -EBADFD;
|
||||
if (nr_segs > 128 || nr_segs != runtime->channels ||
|
||||
!frame_aligned(runtime, iov->iov_len)) {
|
||||
result = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
!frame_aligned(runtime, iov->iov_len))
|
||||
return -EINVAL;
|
||||
frames = bytes_to_samples(runtime, iov->iov_len);
|
||||
bufs = kmalloc(sizeof(void *) * nr_segs, GFP_KERNEL);
|
||||
if (bufs == NULL)
|
||||
|
@ -2893,7 +2895,6 @@ static ssize_t snd_pcm_aio_write(struct kiocb *iocb, const struct iovec *iov,
|
|||
if (result > 0)
|
||||
result = frames_to_bytes(runtime, result);
|
||||
kfree(bufs);
|
||||
end:
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -2908,7 +2909,8 @@ static unsigned int snd_pcm_playback_poll(struct file *file, poll_table * wait)
|
|||
pcm_file = file->private_data;
|
||||
|
||||
substream = pcm_file->substream;
|
||||
snd_assert(substream != NULL, return -ENXIO);
|
||||
if (PCM_RUNTIME_CHECK(substream))
|
||||
return -ENXIO;
|
||||
runtime = substream->runtime;
|
||||
|
||||
poll_wait(file, &runtime->sleep, wait);
|
||||
|
@ -2946,7 +2948,8 @@ static unsigned int snd_pcm_capture_poll(struct file *file, poll_table * wait)
|
|||
pcm_file = file->private_data;
|
||||
|
||||
substream = pcm_file->substream;
|
||||
snd_assert(substream != NULL, return -ENXIO);
|
||||
if (PCM_RUNTIME_CHECK(substream))
|
||||
return -ENXIO;
|
||||
runtime = substream->runtime;
|
||||
|
||||
poll_wait(file, &runtime->sleep, wait);
|
||||
|
@ -3016,7 +3019,6 @@ static int snd_pcm_mmap_status(struct snd_pcm_substream *substream, struct file
|
|||
if (!(area->vm_flags & VM_READ))
|
||||
return -EINVAL;
|
||||
runtime = substream->runtime;
|
||||
snd_assert(runtime != NULL, return -EAGAIN);
|
||||
size = area->vm_end - area->vm_start;
|
||||
if (size != PAGE_ALIGN(sizeof(struct snd_pcm_mmap_status)))
|
||||
return -EINVAL;
|
||||
|
@ -3056,7 +3058,6 @@ static int snd_pcm_mmap_control(struct snd_pcm_substream *substream, struct file
|
|||
if (!(area->vm_flags & VM_READ))
|
||||
return -EINVAL;
|
||||
runtime = substream->runtime;
|
||||
snd_assert(runtime != NULL, return -EAGAIN);
|
||||
size = area->vm_end - area->vm_start;
|
||||
if (size != PAGE_ALIGN(sizeof(struct snd_pcm_mmap_control)))
|
||||
return -EINVAL;
|
||||
|
@ -3188,7 +3189,6 @@ int snd_pcm_mmap_data(struct snd_pcm_substream *substream, struct file *file,
|
|||
return -EINVAL;
|
||||
}
|
||||
runtime = substream->runtime;
|
||||
snd_assert(runtime != NULL, return -EAGAIN);
|
||||
if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
|
||||
return -EBADFD;
|
||||
if (!(runtime->info & SNDRV_PCM_INFO_MMAP))
|
||||
|
@ -3220,7 +3220,8 @@ static int snd_pcm_mmap(struct file *file, struct vm_area_struct *area)
|
|||
|
||||
pcm_file = file->private_data;
|
||||
substream = pcm_file->substream;
|
||||
snd_assert(substream != NULL, return -ENXIO);
|
||||
if (PCM_RUNTIME_CHECK(substream))
|
||||
return -ENXIO;
|
||||
|
||||
offset = area->vm_pgoff << PAGE_SHIFT;
|
||||
switch (offset) {
|
||||
|
@ -3248,9 +3249,9 @@ static int snd_pcm_fasync(int fd, struct file * file, int on)
|
|||
lock_kernel();
|
||||
pcm_file = file->private_data;
|
||||
substream = pcm_file->substream;
|
||||
snd_assert(substream != NULL, goto out);
|
||||
if (PCM_RUNTIME_CHECK(substream))
|
||||
goto out;
|
||||
runtime = substream->runtime;
|
||||
|
||||
err = fasync_helper(fd, file, on, &runtime->fasync);
|
||||
out:
|
||||
unlock_kernel();
|
||||
|
@ -3384,6 +3385,17 @@ out:
|
|||
}
|
||||
#endif /* CONFIG_SND_SUPPORT_OLD_API */
|
||||
|
||||
#ifndef CONFIG_MMU
|
||||
unsigned long dummy_get_unmapped_area(struct file *file, unsigned long addr,
|
||||
unsigned long len, unsigned long pgoff,
|
||||
unsigned long flags)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
# define dummy_get_unmapped_area NULL
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Register section
|
||||
*/
|
||||
|
@ -3400,6 +3412,7 @@ const struct file_operations snd_pcm_f_ops[2] = {
|
|||
.compat_ioctl = snd_pcm_ioctl_compat,
|
||||
.mmap = snd_pcm_mmap,
|
||||
.fasync = snd_pcm_fasync,
|
||||
.get_unmapped_area = dummy_get_unmapped_area,
|
||||
},
|
||||
{
|
||||
.owner = THIS_MODULE,
|
||||
|
@ -3412,5 +3425,6 @@ const struct file_operations snd_pcm_f_ops[2] = {
|
|||
.compat_ioctl = snd_pcm_ioctl_compat,
|
||||
.mmap = snd_pcm_mmap,
|
||||
.fasync = snd_pcm_fasync,
|
||||
.get_unmapped_area = dummy_get_unmapped_area,
|
||||
}
|
||||
};
|
||||
|
|
|
@ -51,12 +51,14 @@ void snd_pcm_timer_resolution_change(struct snd_pcm_substream *substream)
|
|||
|
||||
mult = 1000000000;
|
||||
rate = runtime->rate;
|
||||
snd_assert(rate != 0, return);
|
||||
if (snd_BUG_ON(!rate))
|
||||
return;
|
||||
l = gcd(mult, rate);
|
||||
mult /= l;
|
||||
rate /= l;
|
||||
fsize = runtime->period_size;
|
||||
snd_assert(fsize != 0, return);
|
||||
if (snd_BUG_ON(!fsize))
|
||||
return;
|
||||
l = gcd(rate, fsize);
|
||||
rate /= l;
|
||||
fsize /= l;
|
||||
|
|
|
@ -470,8 +470,8 @@ int snd_rawmidi_kernel_release(struct snd_rawmidi_file * rfile)
|
|||
struct snd_rawmidi_substream *substream;
|
||||
struct snd_rawmidi_runtime *runtime;
|
||||
|
||||
snd_assert(rfile != NULL, return -ENXIO);
|
||||
snd_assert(rfile->input != NULL || rfile->output != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!rfile))
|
||||
return -ENXIO;
|
||||
rmidi = rfile->rmidi;
|
||||
mutex_lock(&rmidi->open_mutex);
|
||||
if (rfile->input != NULL) {
|
||||
|
@ -1100,7 +1100,7 @@ int snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream, int count)
|
|||
return -EINVAL;
|
||||
}
|
||||
spin_lock_irqsave(&runtime->lock, flags);
|
||||
snd_assert(runtime->avail + count <= runtime->buffer_size, );
|
||||
snd_BUG_ON(runtime->avail + count > runtime->buffer_size);
|
||||
runtime->hw_ptr += count;
|
||||
runtime->hw_ptr %= runtime->buffer_size;
|
||||
runtime->avail += count;
|
||||
|
@ -1141,8 +1141,10 @@ static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream,
|
|||
long count1, result;
|
||||
struct snd_rawmidi_runtime *runtime = substream->runtime;
|
||||
|
||||
snd_assert(kernelbuf != NULL || userbuf != NULL, return -EINVAL);
|
||||
snd_assert(runtime->buffer != NULL, return -EINVAL);
|
||||
if (snd_BUG_ON(!kernelbuf && !userbuf))
|
||||
return -EINVAL;
|
||||
if (snd_BUG_ON(!runtime->buffer))
|
||||
return -EINVAL;
|
||||
|
||||
result = 0;
|
||||
spin_lock_irqsave(&runtime->lock, flags);
|
||||
|
@ -1420,9 +1422,10 @@ int snd_rawmidi_new(struct snd_card *card, char *id, int device,
|
|||
.dev_disconnect = snd_rawmidi_dev_disconnect,
|
||||
};
|
||||
|
||||
snd_assert(rrawmidi != NULL, return -EINVAL);
|
||||
*rrawmidi = NULL;
|
||||
snd_assert(card != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!card))
|
||||
return -ENXIO;
|
||||
if (rrawmidi)
|
||||
*rrawmidi = NULL;
|
||||
rmidi = kzalloc(sizeof(*rmidi), GFP_KERNEL);
|
||||
if (rmidi == NULL) {
|
||||
snd_printk(KERN_ERR "rawmidi: cannot allocate\n");
|
||||
|
@ -1455,7 +1458,8 @@ int snd_rawmidi_new(struct snd_card *card, char *id, int device,
|
|||
snd_rawmidi_free(rmidi);
|
||||
return err;
|
||||
}
|
||||
*rrawmidi = rmidi;
|
||||
if (rrawmidi)
|
||||
*rrawmidi = rmidi;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1472,7 +1476,8 @@ static void snd_rawmidi_free_substreams(struct snd_rawmidi_str *stream)
|
|||
|
||||
static int snd_rawmidi_free(struct snd_rawmidi *rmidi)
|
||||
{
|
||||
snd_assert(rmidi != NULL, return -ENXIO);
|
||||
if (!rmidi)
|
||||
return 0;
|
||||
|
||||
snd_info_free_entry(rmidi->proc_entry);
|
||||
rmidi->proc_entry = NULL;
|
||||
|
|
|
@ -91,7 +91,8 @@ static int
|
|||
rtctimer_start(struct snd_timer *timer)
|
||||
{
|
||||
rtc_task_t *rtc = timer->private_data;
|
||||
snd_assert(rtc != NULL, return -EINVAL);
|
||||
if (snd_BUG_ON(!rtc))
|
||||
return -EINVAL;
|
||||
rtc_control(rtc, RTC_IRQP_SET, rtctimer_freq);
|
||||
rtc_control(rtc, RTC_PIE_ON, 0);
|
||||
return 0;
|
||||
|
@ -101,7 +102,8 @@ static int
|
|||
rtctimer_stop(struct snd_timer *timer)
|
||||
{
|
||||
rtc_task_t *rtc = timer->private_data;
|
||||
snd_assert(rtc != NULL, return -EINVAL);
|
||||
if (snd_BUG_ON(!rtc))
|
||||
return -EINVAL;
|
||||
rtc_control(rtc, RTC_PIE_OFF, 0);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -164,7 +164,8 @@ odev_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
|
|||
{
|
||||
struct seq_oss_devinfo *dp;
|
||||
dp = file->private_data;
|
||||
snd_assert(dp != NULL, return -EIO);
|
||||
if (snd_BUG_ON(!dp))
|
||||
return -ENXIO;
|
||||
return snd_seq_oss_read(dp, buf, count);
|
||||
}
|
||||
|
||||
|
@ -174,7 +175,8 @@ odev_write(struct file *file, const char __user *buf, size_t count, loff_t *offs
|
|||
{
|
||||
struct seq_oss_devinfo *dp;
|
||||
dp = file->private_data;
|
||||
snd_assert(dp != NULL, return -EIO);
|
||||
if (snd_BUG_ON(!dp))
|
||||
return -ENXIO;
|
||||
return snd_seq_oss_write(dp, buf, count, file);
|
||||
}
|
||||
|
||||
|
@ -183,7 +185,8 @@ odev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
|||
{
|
||||
struct seq_oss_devinfo *dp;
|
||||
dp = file->private_data;
|
||||
snd_assert(dp != NULL, return -EIO);
|
||||
if (snd_BUG_ON(!dp))
|
||||
return -ENXIO;
|
||||
return snd_seq_oss_ioctl(dp, cmd, arg);
|
||||
}
|
||||
|
||||
|
@ -198,7 +201,8 @@ odev_poll(struct file *file, poll_table * wait)
|
|||
{
|
||||
struct seq_oss_devinfo *dp;
|
||||
dp = file->private_data;
|
||||
snd_assert(dp != NULL, return 0);
|
||||
if (snd_BUG_ON(!dp))
|
||||
return -ENXIO;
|
||||
return snd_seq_oss_poll(dp, file, wait);
|
||||
}
|
||||
|
||||
|
|
|
@ -308,7 +308,8 @@ snd_seq_oss_synth_cleanup(struct seq_oss_devinfo *dp)
|
|||
struct seq_oss_synth *rec;
|
||||
struct seq_oss_synthinfo *info;
|
||||
|
||||
snd_assert(dp->max_synthdev <= SNDRV_SEQ_OSS_MAX_SYNTH_DEVS, return);
|
||||
if (snd_BUG_ON(dp->max_synthdev >= SNDRV_SEQ_OSS_MAX_SYNTH_DEVS))
|
||||
return;
|
||||
for (i = 0; i < dp->max_synthdev; i++) {
|
||||
info = &dp->synths[i];
|
||||
if (! info->opened)
|
||||
|
@ -402,7 +403,8 @@ snd_seq_oss_synth_reset(struct seq_oss_devinfo *dp, int dev)
|
|||
struct seq_oss_synth *rec;
|
||||
struct seq_oss_synthinfo *info;
|
||||
|
||||
snd_assert(dev >= 0 && dev < dp->max_synthdev, return);
|
||||
if (snd_BUG_ON(dev < 0 || dev >= dp->max_synthdev))
|
||||
return;
|
||||
info = &dp->synths[dev];
|
||||
if (! info->opened)
|
||||
return;
|
||||
|
|
|
@ -266,7 +266,8 @@ static int seq_free_client1(struct snd_seq_client *client)
|
|||
{
|
||||
unsigned long flags;
|
||||
|
||||
snd_assert(client != NULL, return -EINVAL);
|
||||
if (!client)
|
||||
return 0;
|
||||
snd_seq_delete_all_ports(client);
|
||||
snd_seq_queue_client_leave(client->number);
|
||||
spin_lock_irqsave(&clients_lock, flags);
|
||||
|
@ -403,7 +404,8 @@ static ssize_t snd_seq_read(struct file *file, char __user *buf, size_t count,
|
|||
return -EFAULT;
|
||||
|
||||
/* check client structures are in place */
|
||||
snd_assert(client != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!client))
|
||||
return -ENXIO;
|
||||
|
||||
if (!client->accept_input || (fifo = client->data.user.fifo) == NULL)
|
||||
return -ENXIO;
|
||||
|
@ -825,7 +827,8 @@ int snd_seq_dispatch_event(struct snd_seq_event_cell *cell, int atomic, int hop)
|
|||
struct snd_seq_client *client;
|
||||
int result;
|
||||
|
||||
snd_assert(cell != NULL, return -EINVAL);
|
||||
if (snd_BUG_ON(!cell))
|
||||
return -EINVAL;
|
||||
|
||||
client = snd_seq_client_use_ptr(cell->event.source.client);
|
||||
if (client == NULL) {
|
||||
|
@ -994,7 +997,8 @@ static ssize_t snd_seq_write(struct file *file, const char __user *buf,
|
|||
return -ENXIO;
|
||||
|
||||
/* check client structures are in place */
|
||||
snd_assert(client != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!client))
|
||||
return -ENXIO;
|
||||
|
||||
if (!client->accept_output || client->pool == NULL)
|
||||
return -ENXIO;
|
||||
|
@ -1076,7 +1080,8 @@ static unsigned int snd_seq_poll(struct file *file, poll_table * wait)
|
|||
unsigned int mask = 0;
|
||||
|
||||
/* check client structures are in place */
|
||||
snd_assert(client != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!client))
|
||||
return -ENXIO;
|
||||
|
||||
if ((snd_seq_file_flags(file) & SNDRV_SEQ_LFLG_INPUT) &&
|
||||
client->data.user.fifo) {
|
||||
|
@ -2195,7 +2200,8 @@ static long snd_seq_ioctl(struct file *file, unsigned int cmd, unsigned long arg
|
|||
{
|
||||
struct snd_seq_client *client = file->private_data;
|
||||
|
||||
snd_assert(client != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!client))
|
||||
return -ENXIO;
|
||||
|
||||
return snd_seq_do_ioctl(client, cmd, (void __user *) arg);
|
||||
}
|
||||
|
@ -2216,7 +2222,8 @@ int snd_seq_create_kernel_client(struct snd_card *card, int client_index,
|
|||
struct snd_seq_client *client;
|
||||
va_list args;
|
||||
|
||||
snd_assert(! in_interrupt(), return -EBUSY);
|
||||
if (snd_BUG_ON(in_interrupt()))
|
||||
return -EBUSY;
|
||||
|
||||
if (card && client_index >= SNDRV_SEQ_CLIENTS_PER_CARD)
|
||||
return -EINVAL;
|
||||
|
@ -2265,7 +2272,8 @@ int snd_seq_delete_kernel_client(int client)
|
|||
{
|
||||
struct snd_seq_client *ptr;
|
||||
|
||||
snd_assert(! in_interrupt(), return -EBUSY);
|
||||
if (snd_BUG_ON(in_interrupt()))
|
||||
return -EBUSY;
|
||||
|
||||
ptr = clientptr(client);
|
||||
if (ptr == NULL)
|
||||
|
@ -2288,7 +2296,8 @@ static int kernel_client_enqueue(int client, struct snd_seq_event *ev,
|
|||
struct snd_seq_client *cptr;
|
||||
int result;
|
||||
|
||||
snd_assert(ev != NULL, return -EINVAL);
|
||||
if (snd_BUG_ON(!ev))
|
||||
return -EINVAL;
|
||||
|
||||
if (ev->type == SNDRV_SEQ_EVENT_NONE)
|
||||
return 0; /* ignore this */
|
||||
|
@ -2354,7 +2363,8 @@ int snd_seq_kernel_client_dispatch(int client, struct snd_seq_event * ev,
|
|||
struct snd_seq_client *cptr;
|
||||
int result;
|
||||
|
||||
snd_assert(ev != NULL, return -EINVAL);
|
||||
if (snd_BUG_ON(!ev))
|
||||
return -EINVAL;
|
||||
|
||||
/* fill in client number */
|
||||
ev->queue = SNDRV_SEQ_QUEUE_DIRECT;
|
||||
|
|
|
@ -92,7 +92,8 @@ static long snd_seq_ioctl_compat(struct file *file, unsigned int cmd, unsigned l
|
|||
struct snd_seq_client *client = file->private_data;
|
||||
void __user *argp = compat_ptr(arg);
|
||||
|
||||
snd_assert(client != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!client))
|
||||
return -ENXIO;
|
||||
|
||||
switch (cmd) {
|
||||
case SNDRV_SEQ_IOCTL_PVERSION:
|
||||
|
|
|
@ -187,7 +187,8 @@ int snd_seq_device_new(struct snd_card *card, int device, char *id, int argsize,
|
|||
if (result)
|
||||
*result = NULL;
|
||||
|
||||
snd_assert(id != NULL, return -EINVAL);
|
||||
if (snd_BUG_ON(!id))
|
||||
return -EINVAL;
|
||||
|
||||
ops = find_driver(id, 1);
|
||||
if (ops == NULL)
|
||||
|
@ -232,7 +233,8 @@ static int snd_seq_device_free(struct snd_seq_device *dev)
|
|||
{
|
||||
struct ops_list *ops;
|
||||
|
||||
snd_assert(dev != NULL, return -EINVAL);
|
||||
if (snd_BUG_ON(!dev))
|
||||
return -EINVAL;
|
||||
|
||||
ops = find_driver(dev->id, 0);
|
||||
if (ops == NULL)
|
||||
|
|
|
@ -65,9 +65,11 @@ void snd_seq_fifo_delete(struct snd_seq_fifo **fifo)
|
|||
{
|
||||
struct snd_seq_fifo *f;
|
||||
|
||||
snd_assert(fifo != NULL, return);
|
||||
if (snd_BUG_ON(!fifo))
|
||||
return;
|
||||
f = *fifo;
|
||||
snd_assert(f != NULL, return);
|
||||
if (snd_BUG_ON(!f))
|
||||
return;
|
||||
*fifo = NULL;
|
||||
|
||||
snd_seq_fifo_clear(f);
|
||||
|
@ -116,7 +118,8 @@ int snd_seq_fifo_event_in(struct snd_seq_fifo *f,
|
|||
unsigned long flags;
|
||||
int err;
|
||||
|
||||
snd_assert(f != NULL, return -EINVAL);
|
||||
if (snd_BUG_ON(!f))
|
||||
return -EINVAL;
|
||||
|
||||
snd_use_lock_use(&f->use_lock);
|
||||
err = snd_seq_event_dup(f->pool, event, &cell, 1, NULL); /* always non-blocking */
|
||||
|
@ -174,7 +177,8 @@ int snd_seq_fifo_cell_out(struct snd_seq_fifo *f,
|
|||
unsigned long flags;
|
||||
wait_queue_t wait;
|
||||
|
||||
snd_assert(f != NULL, return -EINVAL);
|
||||
if (snd_BUG_ON(!f))
|
||||
return -EINVAL;
|
||||
|
||||
*cellp = NULL;
|
||||
init_waitqueue_entry(&wait, current);
|
||||
|
@ -233,7 +237,8 @@ int snd_seq_fifo_resize(struct snd_seq_fifo *f, int poolsize)
|
|||
struct snd_seq_pool *newpool, *oldpool;
|
||||
struct snd_seq_event_cell *cell, *next, *oldhead;
|
||||
|
||||
snd_assert(f != NULL && f->pool != NULL, return -EINVAL);
|
||||
if (snd_BUG_ON(!f || !f->pool))
|
||||
return -EINVAL;
|
||||
|
||||
/* allocate new pool */
|
||||
newpool = snd_seq_pool_new(poolsize);
|
||||
|
|
|
@ -187,9 +187,11 @@ void snd_seq_cell_free(struct snd_seq_event_cell * cell)
|
|||
unsigned long flags;
|
||||
struct snd_seq_pool *pool;
|
||||
|
||||
snd_assert(cell != NULL, return);
|
||||
if (snd_BUG_ON(!cell))
|
||||
return;
|
||||
pool = cell->pool;
|
||||
snd_assert(pool != NULL, return);
|
||||
if (snd_BUG_ON(!pool))
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&pool->lock, flags);
|
||||
free_cell(pool, cell);
|
||||
|
@ -378,7 +380,8 @@ int snd_seq_pool_init(struct snd_seq_pool *pool)
|
|||
struct snd_seq_event_cell *cellptr;
|
||||
unsigned long flags;
|
||||
|
||||
snd_assert(pool != NULL, return -EINVAL);
|
||||
if (snd_BUG_ON(!pool))
|
||||
return -EINVAL;
|
||||
if (pool->ptr) /* should be atomic? */
|
||||
return 0;
|
||||
|
||||
|
@ -414,7 +417,8 @@ int snd_seq_pool_done(struct snd_seq_pool *pool)
|
|||
struct snd_seq_event_cell *ptr;
|
||||
int max_count = 5 * HZ;
|
||||
|
||||
snd_assert(pool != NULL, return -EINVAL);
|
||||
if (snd_BUG_ON(!pool))
|
||||
return -EINVAL;
|
||||
|
||||
/* wait for closing all threads */
|
||||
spin_lock_irqsave(&pool->lock, flags);
|
||||
|
|
|
@ -116,7 +116,8 @@ static int dump_midi(struct snd_rawmidi_substream *substream, const char *buf, i
|
|||
struct snd_rawmidi_runtime *runtime;
|
||||
int tmp;
|
||||
|
||||
snd_assert(substream != NULL || buf != NULL, return -EINVAL);
|
||||
if (snd_BUG_ON(!substream || !buf))
|
||||
return -EINVAL;
|
||||
runtime = substream->runtime;
|
||||
if ((tmp = runtime->avail) < count) {
|
||||
snd_printd("warning, output event was lost (count = %i, available = %i)\n", count, tmp);
|
||||
|
@ -135,7 +136,8 @@ static int event_process_midi(struct snd_seq_event *ev, int direct,
|
|||
struct snd_rawmidi_substream *substream;
|
||||
int len;
|
||||
|
||||
snd_assert(msynth != NULL, return -EINVAL);
|
||||
if (snd_BUG_ON(!msynth))
|
||||
return -EINVAL;
|
||||
substream = msynth->output_rfile.output;
|
||||
if (substream == NULL)
|
||||
return -ENODEV;
|
||||
|
@ -210,7 +212,8 @@ static int midisynth_unsubscribe(void *private_data, struct snd_seq_port_subscri
|
|||
int err;
|
||||
struct seq_midisynth *msynth = private_data;
|
||||
|
||||
snd_assert(msynth->input_rfile.input != NULL, return -EINVAL);
|
||||
if (snd_BUG_ON(!msynth->input_rfile.input))
|
||||
return -EINVAL;
|
||||
err = snd_rawmidi_kernel_release(&msynth->input_rfile);
|
||||
return err;
|
||||
}
|
||||
|
@ -247,7 +250,8 @@ static int midisynth_unuse(void *private_data, struct snd_seq_port_subscribe *in
|
|||
struct seq_midisynth *msynth = private_data;
|
||||
unsigned char buf = 0xff; /* MIDI reset */
|
||||
|
||||
snd_assert(msynth->output_rfile.output != NULL, return -EINVAL);
|
||||
if (snd_BUG_ON(!msynth->output_rfile.output))
|
||||
return -EINVAL;
|
||||
/* sending single MIDI reset message to shut the device up */
|
||||
snd_rawmidi_kernel_write(msynth->output_rfile.output, &buf, 1);
|
||||
snd_rawmidi_drain_output(msynth->output_rfile.output);
|
||||
|
@ -285,7 +289,8 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev)
|
|||
int device = dev->device;
|
||||
unsigned int input_count = 0, output_count = 0;
|
||||
|
||||
snd_assert(card != NULL && device >= 0 && device < SNDRV_RAWMIDI_DEVICES, return -EINVAL);
|
||||
if (snd_BUG_ON(!card || device < 0 || device >= SNDRV_RAWMIDI_DEVICES))
|
||||
return -EINVAL;
|
||||
info = kmalloc(sizeof(*info), GFP_KERNEL);
|
||||
if (! info)
|
||||
return -ENOMEM;
|
||||
|
|
|
@ -130,7 +130,8 @@ struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client,
|
|||
int num = -1;
|
||||
|
||||
/* sanity check */
|
||||
snd_assert(client, return NULL);
|
||||
if (snd_BUG_ON(!client))
|
||||
return NULL;
|
||||
|
||||
if (client->num_ports >= SNDRV_SEQ_MAX_PORTS - 1) {
|
||||
snd_printk(KERN_WARNING "too many ports for client %d\n", client->number);
|
||||
|
@ -268,8 +269,8 @@ static int port_delete(struct snd_seq_client *client,
|
|||
if (port->private_free)
|
||||
port->private_free(port->private_data);
|
||||
|
||||
snd_assert(port->c_src.count == 0,);
|
||||
snd_assert(port->c_dest.count == 0,);
|
||||
snd_BUG_ON(port->c_src.count != 0);
|
||||
snd_BUG_ON(port->c_dest.count != 0);
|
||||
|
||||
kfree(port);
|
||||
return 0;
|
||||
|
@ -336,7 +337,8 @@ int snd_seq_delete_all_ports(struct snd_seq_client *client)
|
|||
int snd_seq_set_port_info(struct snd_seq_client_port * port,
|
||||
struct snd_seq_port_info * info)
|
||||
{
|
||||
snd_assert(port && info, return -EINVAL);
|
||||
if (snd_BUG_ON(!port || !info))
|
||||
return -EINVAL;
|
||||
|
||||
/* set port name */
|
||||
if (info->name[0])
|
||||
|
@ -365,7 +367,8 @@ int snd_seq_set_port_info(struct snd_seq_client_port * port,
|
|||
int snd_seq_get_port_info(struct snd_seq_client_port * port,
|
||||
struct snd_seq_port_info * info)
|
||||
{
|
||||
snd_assert(port && info, return -EINVAL);
|
||||
if (snd_BUG_ON(!port || !info))
|
||||
return -EINVAL;
|
||||
|
||||
/* get port name */
|
||||
strlcpy(info->name, port->name, sizeof(info->name));
|
||||
|
|
|
@ -153,8 +153,8 @@ int snd_seq_prioq_cell_in(struct snd_seq_prioq * f,
|
|||
int count;
|
||||
int prior;
|
||||
|
||||
snd_assert(f, return -EINVAL);
|
||||
snd_assert(cell, return -EINVAL);
|
||||
if (snd_BUG_ON(!f || !cell))
|
||||
return -EINVAL;
|
||||
|
||||
/* check flags */
|
||||
prior = (cell->event.flags & SNDRV_SEQ_PRIORITY_MASK);
|
||||
|
|
|
@ -315,7 +315,8 @@ int snd_seq_enqueue_event(struct snd_seq_event_cell *cell, int atomic, int hop)
|
|||
int dest, err;
|
||||
struct snd_seq_queue *q;
|
||||
|
||||
snd_assert(cell != NULL, return -EINVAL);
|
||||
if (snd_BUG_ON(!cell))
|
||||
return -EINVAL;
|
||||
dest = cell->event.queue; /* destination queue */
|
||||
q = queueptr(dest);
|
||||
if (q == NULL)
|
||||
|
@ -734,7 +735,8 @@ int snd_seq_control_queue(struct snd_seq_event *ev, int atomic, int hop)
|
|||
{
|
||||
struct snd_seq_queue *q;
|
||||
|
||||
snd_assert(ev != NULL, return -EINVAL);
|
||||
if (snd_BUG_ON(!ev))
|
||||
return -EINVAL;
|
||||
q = queueptr(ev->data.queue.queue);
|
||||
|
||||
if (q == NULL)
|
||||
|
|
|
@ -173,7 +173,8 @@ int snd_seq_timer_set_tempo(struct snd_seq_timer * tmr, int tempo)
|
|||
{
|
||||
unsigned long flags;
|
||||
|
||||
snd_assert(tmr, return -EINVAL);
|
||||
if (snd_BUG_ON(!tmr))
|
||||
return -EINVAL;
|
||||
if (tempo <= 0)
|
||||
return -EINVAL;
|
||||
spin_lock_irqsave(&tmr->lock, flags);
|
||||
|
@ -190,7 +191,8 @@ int snd_seq_timer_set_ppq(struct snd_seq_timer * tmr, int ppq)
|
|||
{
|
||||
unsigned long flags;
|
||||
|
||||
snd_assert(tmr, return -EINVAL);
|
||||
if (snd_BUG_ON(!tmr))
|
||||
return -EINVAL;
|
||||
if (ppq <= 0)
|
||||
return -EINVAL;
|
||||
spin_lock_irqsave(&tmr->lock, flags);
|
||||
|
@ -214,7 +216,8 @@ int snd_seq_timer_set_position_tick(struct snd_seq_timer *tmr,
|
|||
{
|
||||
unsigned long flags;
|
||||
|
||||
snd_assert(tmr, return -EINVAL);
|
||||
if (snd_BUG_ON(!tmr))
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock_irqsave(&tmr->lock, flags);
|
||||
tmr->tick.cur_tick = position;
|
||||
|
@ -229,7 +232,8 @@ int snd_seq_timer_set_position_time(struct snd_seq_timer *tmr,
|
|||
{
|
||||
unsigned long flags;
|
||||
|
||||
snd_assert(tmr, return -EINVAL);
|
||||
if (snd_BUG_ON(!tmr))
|
||||
return -EINVAL;
|
||||
|
||||
snd_seq_sanity_real_time(&position);
|
||||
spin_lock_irqsave(&tmr->lock, flags);
|
||||
|
@ -244,7 +248,8 @@ int snd_seq_timer_set_skew(struct snd_seq_timer *tmr, unsigned int skew,
|
|||
{
|
||||
unsigned long flags;
|
||||
|
||||
snd_assert(tmr, return -EINVAL);
|
||||
if (snd_BUG_ON(!tmr))
|
||||
return -EINVAL;
|
||||
|
||||
/* FIXME */
|
||||
if (base != SKEW_BASE) {
|
||||
|
@ -265,7 +270,8 @@ int snd_seq_timer_open(struct snd_seq_queue *q)
|
|||
int err;
|
||||
|
||||
tmr = q->timer;
|
||||
snd_assert(tmr != NULL, return -EINVAL);
|
||||
if (snd_BUG_ON(!tmr))
|
||||
return -EINVAL;
|
||||
if (tmr->timeri)
|
||||
return -EBUSY;
|
||||
sprintf(str, "sequencer queue %i", q->queue);
|
||||
|
@ -302,7 +308,8 @@ int snd_seq_timer_close(struct snd_seq_queue *q)
|
|||
struct snd_seq_timer *tmr;
|
||||
|
||||
tmr = q->timer;
|
||||
snd_assert(tmr != NULL, return -EINVAL);
|
||||
if (snd_BUG_ON(!tmr))
|
||||
return -EINVAL;
|
||||
if (tmr->timeri) {
|
||||
snd_timer_stop(tmr->timeri);
|
||||
snd_timer_close(tmr->timeri);
|
||||
|
@ -328,7 +335,8 @@ static int initialize_timer(struct snd_seq_timer *tmr)
|
|||
unsigned long freq;
|
||||
|
||||
t = tmr->timeri->timer;
|
||||
snd_assert(t, return -EINVAL);
|
||||
if (snd_BUG_ON(!t))
|
||||
return -EINVAL;
|
||||
|
||||
freq = tmr->preferred_resolution;
|
||||
if (!freq)
|
||||
|
|
|
@ -41,9 +41,11 @@ int snd_free_sgbuf_pages(struct snd_dma_buffer *dmab)
|
|||
tmpb.dev.type = SNDRV_DMA_TYPE_DEV;
|
||||
tmpb.dev.dev = sgbuf->dev;
|
||||
for (i = 0; i < sgbuf->pages; i++) {
|
||||
if (!(sgbuf->table[i].addr & ~PAGE_MASK))
|
||||
continue; /* continuous pages */
|
||||
tmpb.area = sgbuf->table[i].buf;
|
||||
tmpb.addr = sgbuf->table[i].addr;
|
||||
tmpb.bytes = PAGE_SIZE;
|
||||
tmpb.addr = sgbuf->table[i].addr & PAGE_MASK;
|
||||
tmpb.bytes = (sgbuf->table[i].addr & ~PAGE_MASK) << PAGE_SHIFT;
|
||||
snd_dma_free_pages(&tmpb);
|
||||
}
|
||||
if (dmab->area)
|
||||
|
@ -58,13 +60,17 @@ int snd_free_sgbuf_pages(struct snd_dma_buffer *dmab)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#define MAX_ALLOC_PAGES 32
|
||||
|
||||
void *snd_malloc_sgbuf_pages(struct device *device,
|
||||
size_t size, struct snd_dma_buffer *dmab,
|
||||
size_t *res_size)
|
||||
{
|
||||
struct snd_sg_buf *sgbuf;
|
||||
unsigned int i, pages;
|
||||
unsigned int i, pages, chunk, maxpages;
|
||||
struct snd_dma_buffer tmpb;
|
||||
struct snd_sg_page *table;
|
||||
struct page **pgtable;
|
||||
|
||||
dmab->area = NULL;
|
||||
dmab->addr = 0;
|
||||
|
@ -74,31 +80,55 @@ void *snd_malloc_sgbuf_pages(struct device *device,
|
|||
sgbuf->dev = device;
|
||||
pages = snd_sgbuf_aligned_pages(size);
|
||||
sgbuf->tblsize = sgbuf_align_table(pages);
|
||||
sgbuf->table = kcalloc(sgbuf->tblsize, sizeof(*sgbuf->table), GFP_KERNEL);
|
||||
if (! sgbuf->table)
|
||||
table = kcalloc(sgbuf->tblsize, sizeof(*table), GFP_KERNEL);
|
||||
if (!table)
|
||||
goto _failed;
|
||||
sgbuf->page_table = kcalloc(sgbuf->tblsize, sizeof(*sgbuf->page_table), GFP_KERNEL);
|
||||
if (! sgbuf->page_table)
|
||||
sgbuf->table = table;
|
||||
pgtable = kcalloc(sgbuf->tblsize, sizeof(*pgtable), GFP_KERNEL);
|
||||
if (!pgtable)
|
||||
goto _failed;
|
||||
sgbuf->page_table = pgtable;
|
||||
|
||||
/* allocate each page */
|
||||
for (i = 0; i < pages; i++) {
|
||||
if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, device, PAGE_SIZE, &tmpb) < 0) {
|
||||
if (res_size == NULL)
|
||||
/* allocate pages */
|
||||
maxpages = MAX_ALLOC_PAGES;
|
||||
while (pages > 0) {
|
||||
chunk = pages;
|
||||
/* don't be too eager to take a huge chunk */
|
||||
if (chunk > maxpages)
|
||||
chunk = maxpages;
|
||||
chunk <<= PAGE_SHIFT;
|
||||
if (snd_dma_alloc_pages_fallback(SNDRV_DMA_TYPE_DEV, device,
|
||||
chunk, &tmpb) < 0) {
|
||||
if (!sgbuf->pages)
|
||||
return NULL;
|
||||
if (!res_size)
|
||||
goto _failed;
|
||||
*res_size = size = sgbuf->pages * PAGE_SIZE;
|
||||
size = sgbuf->pages * PAGE_SIZE;
|
||||
break;
|
||||
}
|
||||
sgbuf->table[i].buf = tmpb.area;
|
||||
sgbuf->table[i].addr = tmpb.addr;
|
||||
sgbuf->page_table[i] = virt_to_page(tmpb.area);
|
||||
sgbuf->pages++;
|
||||
chunk = tmpb.bytes >> PAGE_SHIFT;
|
||||
for (i = 0; i < chunk; i++) {
|
||||
table->buf = tmpb.area;
|
||||
table->addr = tmpb.addr;
|
||||
if (!i)
|
||||
table->addr |= chunk; /* mark head */
|
||||
table++;
|
||||
*pgtable++ = virt_to_page(tmpb.area);
|
||||
tmpb.area += PAGE_SIZE;
|
||||
tmpb.addr += PAGE_SIZE;
|
||||
}
|
||||
sgbuf->pages += chunk;
|
||||
pages -= chunk;
|
||||
if (chunk < maxpages)
|
||||
maxpages = chunk;
|
||||
}
|
||||
|
||||
sgbuf->size = size;
|
||||
dmab->area = vmap(sgbuf->page_table, sgbuf->pages, VM_MAP, PAGE_KERNEL);
|
||||
if (! dmab->area)
|
||||
goto _failed;
|
||||
if (res_size)
|
||||
*res_size = sgbuf->size;
|
||||
return dmab->area;
|
||||
|
||||
_failed:
|
||||
|
|
|
@ -34,8 +34,6 @@
|
|||
#include <linux/kmod.h>
|
||||
#include <linux/mutex.h>
|
||||
|
||||
#define SNDRV_OS_MINORS 256
|
||||
|
||||
static int major = CONFIG_SND_MAJOR;
|
||||
int snd_major;
|
||||
EXPORT_SYMBOL(snd_major);
|
||||
|
@ -208,20 +206,23 @@ static int snd_kernel_minor(int type, struct snd_card *card, int dev)
|
|||
minor = type;
|
||||
break;
|
||||
case SNDRV_DEVICE_TYPE_CONTROL:
|
||||
snd_assert(card != NULL, return -EINVAL);
|
||||
if (snd_BUG_ON(!card))
|
||||
return -EINVAL;
|
||||
minor = SNDRV_MINOR(card->number, type);
|
||||
break;
|
||||
case SNDRV_DEVICE_TYPE_HWDEP:
|
||||
case SNDRV_DEVICE_TYPE_RAWMIDI:
|
||||
case SNDRV_DEVICE_TYPE_PCM_PLAYBACK:
|
||||
case SNDRV_DEVICE_TYPE_PCM_CAPTURE:
|
||||
snd_assert(card != NULL, return -EINVAL);
|
||||
if (snd_BUG_ON(!card))
|
||||
return -EINVAL;
|
||||
minor = SNDRV_MINOR(card->number, type + dev);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
snd_assert(minor >= 0 && minor < SNDRV_OS_MINORS, return -EINVAL);
|
||||
if (snd_BUG_ON(minor < 0 || minor >= SNDRV_OS_MINORS))
|
||||
return -EINVAL;
|
||||
return minor;
|
||||
}
|
||||
#endif
|
||||
|
@ -249,7 +250,8 @@ int snd_register_device_for_dev(int type, struct snd_card *card, int dev,
|
|||
int minor;
|
||||
struct snd_minor *preg;
|
||||
|
||||
snd_assert(name, return -EINVAL);
|
||||
if (snd_BUG_ON(!name))
|
||||
return -EINVAL;
|
||||
preg = kmalloc(sizeof *preg, GFP_KERNEL);
|
||||
if (preg == NULL)
|
||||
return -ENOMEM;
|
||||
|
|
|
@ -64,7 +64,8 @@ static int snd_oss_kernel_minor(int type, struct snd_card *card, int dev)
|
|||
|
||||
switch (type) {
|
||||
case SNDRV_OSS_DEVICE_TYPE_MIXER:
|
||||
snd_assert(card != NULL && dev <= 1, return -EINVAL);
|
||||
if (snd_BUG_ON(!card || dev < 0 || dev > 1))
|
||||
return -EINVAL;
|
||||
minor = SNDRV_MINOR_OSS(card->number, (dev ? SNDRV_MINOR_OSS_MIXER1 : SNDRV_MINOR_OSS_MIXER));
|
||||
break;
|
||||
case SNDRV_OSS_DEVICE_TYPE_SEQUENCER:
|
||||
|
@ -74,11 +75,13 @@ static int snd_oss_kernel_minor(int type, struct snd_card *card, int dev)
|
|||
minor = SNDRV_MINOR_OSS_MUSIC;
|
||||
break;
|
||||
case SNDRV_OSS_DEVICE_TYPE_PCM:
|
||||
snd_assert(card != NULL && dev <= 1, return -EINVAL);
|
||||
if (snd_BUG_ON(!card || dev < 0 || dev > 1))
|
||||
return -EINVAL;
|
||||
minor = SNDRV_MINOR_OSS(card->number, (dev ? SNDRV_MINOR_OSS_PCM1 : SNDRV_MINOR_OSS_PCM));
|
||||
break;
|
||||
case SNDRV_OSS_DEVICE_TYPE_MIDI:
|
||||
snd_assert(card != NULL && dev <= 1, return -EINVAL);
|
||||
if (snd_BUG_ON(!card || dev < 0 || dev > 1))
|
||||
return -EINVAL;
|
||||
minor = SNDRV_MINOR_OSS(card->number, (dev ? SNDRV_MINOR_OSS_MIDI1 : SNDRV_MINOR_OSS_MIDI));
|
||||
break;
|
||||
case SNDRV_OSS_DEVICE_TYPE_DMFM:
|
||||
|
@ -90,7 +93,8 @@ static int snd_oss_kernel_minor(int type, struct snd_card *card, int dev)
|
|||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
snd_assert(minor >= 0 && minor < SNDRV_OSS_MINORS, return -EINVAL);
|
||||
if (snd_BUG_ON(minor < 0 || minor >= SNDRV_OSS_MINORS))
|
||||
return -EINVAL;
|
||||
return minor;
|
||||
}
|
||||
|
||||
|
|
|
@ -306,7 +306,8 @@ int snd_timer_close(struct snd_timer_instance *timeri)
|
|||
struct snd_timer *timer = NULL;
|
||||
struct snd_timer_instance *slave, *tmp;
|
||||
|
||||
snd_assert(timeri != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!timeri))
|
||||
return -ENXIO;
|
||||
|
||||
/* force to stop the timer */
|
||||
snd_timer_stop(timeri);
|
||||
|
@ -385,8 +386,9 @@ static void snd_timer_notify1(struct snd_timer_instance *ti, int event)
|
|||
do_posix_clock_monotonic_gettime(&tstamp);
|
||||
else
|
||||
getnstimeofday(&tstamp);
|
||||
snd_assert(event >= SNDRV_TIMER_EVENT_START &&
|
||||
event <= SNDRV_TIMER_EVENT_PAUSE, return);
|
||||
if (snd_BUG_ON(event < SNDRV_TIMER_EVENT_START ||
|
||||
event > SNDRV_TIMER_EVENT_PAUSE))
|
||||
return;
|
||||
if (event == SNDRV_TIMER_EVENT_START ||
|
||||
event == SNDRV_TIMER_EVENT_CONTINUE)
|
||||
resolution = snd_timer_resolution(ti);
|
||||
|
@ -474,7 +476,8 @@ static int _snd_timer_stop(struct snd_timer_instance * timeri,
|
|||
struct snd_timer *timer;
|
||||
unsigned long flags;
|
||||
|
||||
snd_assert(timeri != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!timeri))
|
||||
return -ENXIO;
|
||||
|
||||
if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) {
|
||||
if (!keep_flag) {
|
||||
|
@ -758,9 +761,10 @@ int snd_timer_new(struct snd_card *card, char *id, struct snd_timer_id *tid,
|
|||
.dev_disconnect = snd_timer_dev_disconnect,
|
||||
};
|
||||
|
||||
snd_assert(tid != NULL, return -EINVAL);
|
||||
snd_assert(rtimer != NULL, return -EINVAL);
|
||||
*rtimer = NULL;
|
||||
if (snd_BUG_ON(!tid))
|
||||
return -EINVAL;
|
||||
if (rtimer)
|
||||
*rtimer = NULL;
|
||||
timer = kzalloc(sizeof(*timer), GFP_KERNEL);
|
||||
if (timer == NULL) {
|
||||
snd_printk(KERN_ERR "timer: cannot allocate\n");
|
||||
|
@ -788,13 +792,15 @@ int snd_timer_new(struct snd_card *card, char *id, struct snd_timer_id *tid,
|
|||
return err;
|
||||
}
|
||||
}
|
||||
*rtimer = timer;
|
||||
if (rtimer)
|
||||
*rtimer = timer;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_timer_free(struct snd_timer *timer)
|
||||
{
|
||||
snd_assert(timer != NULL, return -ENXIO);
|
||||
if (!timer)
|
||||
return 0;
|
||||
|
||||
mutex_lock(®ister_mutex);
|
||||
if (! list_empty(&timer->open_list_head)) {
|
||||
|
@ -827,8 +833,8 @@ static int snd_timer_dev_register(struct snd_device *dev)
|
|||
struct snd_timer *timer = dev->device_data;
|
||||
struct snd_timer *timer1;
|
||||
|
||||
snd_assert(timer != NULL && timer->hw.start != NULL &&
|
||||
timer->hw.stop != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!timer || !timer->hw.start || !timer->hw.stop))
|
||||
return -ENXIO;
|
||||
if (!(timer->hw.flags & SNDRV_TIMER_HW_SLAVE) &&
|
||||
!timer->hw.resolution && timer->hw.c_resolution == NULL)
|
||||
return -EINVAL;
|
||||
|
@ -879,8 +885,9 @@ void snd_timer_notify(struct snd_timer *timer, int event, struct timespec *tstam
|
|||
|
||||
if (! (timer->hw.flags & SNDRV_TIMER_HW_SLAVE))
|
||||
return;
|
||||
snd_assert(event >= SNDRV_TIMER_EVENT_MSTART &&
|
||||
event <= SNDRV_TIMER_EVENT_MRESUME, return);
|
||||
if (snd_BUG_ON(event < SNDRV_TIMER_EVENT_MSTART ||
|
||||
event > SNDRV_TIMER_EVENT_MRESUME))
|
||||
return;
|
||||
spin_lock_irqsave(&timer->lock, flags);
|
||||
if (event == SNDRV_TIMER_EVENT_MSTART ||
|
||||
event == SNDRV_TIMER_EVENT_MCONTINUE ||
|
||||
|
|
|
@ -40,9 +40,11 @@ static int snd_timer_user_info_compat(struct file *file,
|
|||
struct snd_timer *t;
|
||||
|
||||
tu = file->private_data;
|
||||
snd_assert(tu->timeri != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!tu->timeri))
|
||||
return -ENXIO;
|
||||
t = tu->timeri->timer;
|
||||
snd_assert(t != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!t))
|
||||
return -ENXIO;
|
||||
memset(&info, 0, sizeof(info));
|
||||
info.card = t->card ? t->card->number : -1;
|
||||
if (t->hw.flags & SNDRV_TIMER_HW_SLAVE)
|
||||
|
@ -71,7 +73,8 @@ static int snd_timer_user_status_compat(struct file *file,
|
|||
struct snd_timer_status status;
|
||||
|
||||
tu = file->private_data;
|
||||
snd_assert(tu->timeri != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!tu->timeri))
|
||||
return -ENXIO;
|
||||
memset(&status, 0, sizeof(status));
|
||||
status.tstamp = tu->tstamp;
|
||||
status.resolution = snd_timer_resolution(tu->timeri);
|
||||
|
|
|
@ -47,9 +47,11 @@ MODULE_SUPPORTED_DEVICE("{{ALSA,Dummy soundcard}}");
|
|||
static int emu10k1_playback_constraints(struct snd_pcm_runtime *runtime)
|
||||
{
|
||||
int err;
|
||||
if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
|
||||
err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
|
||||
if (err < 0)
|
||||
return err;
|
||||
if ((err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 256, UINT_MAX)) < 0)
|
||||
err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 256, UINT_MAX);
|
||||
if (err) < 0)
|
||||
return err;
|
||||
return 0;
|
||||
}
|
||||
|
@ -354,6 +356,7 @@ static int snd_card_dummy_playback_open(struct snd_pcm_substream *substream)
|
|||
if ((dpcm = new_pcm_stream(substream)) == NULL)
|
||||
return -ENOMEM;
|
||||
runtime->private_data = dpcm;
|
||||
/* makes the infrastructure responsible for freeing dpcm */
|
||||
runtime->private_free = snd_card_dummy_runtime_free;
|
||||
runtime->hw = snd_card_dummy_playback;
|
||||
if (substream->pcm->device & 1) {
|
||||
|
@ -362,10 +365,9 @@ static int snd_card_dummy_playback_open(struct snd_pcm_substream *substream)
|
|||
}
|
||||
if (substream->pcm->device & 2)
|
||||
runtime->hw.info &= ~(SNDRV_PCM_INFO_MMAP|SNDRV_PCM_INFO_MMAP_VALID);
|
||||
if ((err = add_playback_constraints(runtime)) < 0) {
|
||||
kfree(dpcm);
|
||||
err = add_playback_constraints(runtime);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -379,6 +381,7 @@ static int snd_card_dummy_capture_open(struct snd_pcm_substream *substream)
|
|||
if ((dpcm = new_pcm_stream(substream)) == NULL)
|
||||
return -ENOMEM;
|
||||
runtime->private_data = dpcm;
|
||||
/* makes the infrastructure responsible for freeing dpcm */
|
||||
runtime->private_free = snd_card_dummy_runtime_free;
|
||||
runtime->hw = snd_card_dummy_capture;
|
||||
if (substream->pcm->device == 1) {
|
||||
|
@ -387,10 +390,9 @@ static int snd_card_dummy_capture_open(struct snd_pcm_substream *substream)
|
|||
}
|
||||
if (substream->pcm->device & 2)
|
||||
runtime->hw.info &= ~(SNDRV_PCM_INFO_MMAP|SNDRV_PCM_INFO_MMAP_VALID);
|
||||
if ((err = add_capture_constraints(runtime)) < 0) {
|
||||
kfree(dpcm);
|
||||
err = add_capture_constraints(runtime);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -433,8 +435,9 @@ static int __devinit snd_card_dummy_pcm(struct snd_dummy *dummy, int device,
|
|||
struct snd_pcm *pcm;
|
||||
int err;
|
||||
|
||||
if ((err = snd_pcm_new(dummy->card, "Dummy PCM", device,
|
||||
substreams, substreams, &pcm)) < 0)
|
||||
err = snd_pcm_new(dummy->card, "Dummy PCM", device,
|
||||
substreams, substreams, &pcm);
|
||||
if (err < 0)
|
||||
return err;
|
||||
dummy->pcm = pcm;
|
||||
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_card_dummy_playback_ops);
|
||||
|
@ -565,12 +568,14 @@ static int __devinit snd_card_dummy_new_mixer(struct snd_dummy *dummy)
|
|||
unsigned int idx;
|
||||
int err;
|
||||
|
||||
snd_assert(dummy != NULL, return -EINVAL);
|
||||
if (snd_BUG_ON(!dummy))
|
||||
return -EINVAL;
|
||||
spin_lock_init(&dummy->mixer_lock);
|
||||
strcpy(card->mixername, "Dummy Mixer");
|
||||
|
||||
for (idx = 0; idx < ARRAY_SIZE(snd_dummy_controls); idx++) {
|
||||
if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_dummy_controls[idx], dummy))) < 0)
|
||||
err = snd_ctl_add(card, snd_ctl_new1(&snd_dummy_controls[idx], dummy));
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
return 0;
|
||||
|
@ -594,10 +599,12 @@ static int __devinit snd_dummy_probe(struct platform_device *devptr)
|
|||
pcm_substreams[dev] = 1;
|
||||
if (pcm_substreams[dev] > MAX_PCM_SUBSTREAMS)
|
||||
pcm_substreams[dev] = MAX_PCM_SUBSTREAMS;
|
||||
if ((err = snd_card_dummy_pcm(dummy, idx, pcm_substreams[dev])) < 0)
|
||||
err = snd_card_dummy_pcm(dummy, idx, pcm_substreams[dev]);
|
||||
if (err < 0)
|
||||
goto __nodev;
|
||||
}
|
||||
if ((err = snd_card_dummy_new_mixer(dummy)) < 0)
|
||||
err = snd_card_dummy_new_mixer(dummy);
|
||||
if (err < 0)
|
||||
goto __nodev;
|
||||
strcpy(card->driver, "Dummy");
|
||||
strcpy(card->shortname, "Dummy");
|
||||
|
@ -605,7 +612,8 @@ static int __devinit snd_dummy_probe(struct platform_device *devptr)
|
|||
|
||||
snd_card_set_dev(card, &devptr->dev);
|
||||
|
||||
if ((err = snd_card_register(card)) == 0) {
|
||||
err = snd_card_register(card);
|
||||
if (err == 0) {
|
||||
platform_set_drvdata(devptr, card);
|
||||
return 0;
|
||||
}
|
||||
|
@ -668,7 +676,8 @@ static int __init alsa_card_dummy_init(void)
|
|||
{
|
||||
int i, cards, err;
|
||||
|
||||
if ((err = platform_driver_register(&snd_dummy_driver)) < 0)
|
||||
err = platform_driver_register(&snd_dummy_driver);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
cards = 0;
|
||||
|
|
|
@ -715,6 +715,10 @@ static int __devinit snd_mtpav_probe(struct platform_device *dev)
|
|||
|
||||
card->private_free = snd_mtpav_free;
|
||||
|
||||
err = snd_mtpav_get_RAWMIDI(mtp_card);
|
||||
if (err < 0)
|
||||
goto __error;
|
||||
|
||||
err = snd_mtpav_get_ISA(mtp_card);
|
||||
if (err < 0)
|
||||
goto __error;
|
||||
|
@ -724,10 +728,6 @@ static int __devinit snd_mtpav_probe(struct platform_device *dev)
|
|||
snprintf(card->longname, sizeof(card->longname),
|
||||
"MTPAV on parallel port at 0x%lx", port);
|
||||
|
||||
err = snd_mtpav_get_RAWMIDI(mtp_card);
|
||||
if (err < 0)
|
||||
goto __error;
|
||||
|
||||
snd_mtpav_portscan(mtp_card);
|
||||
|
||||
snd_card_set_dev(card, &dev->dev);
|
||||
|
|
|
@ -139,7 +139,8 @@ static int snd_opl3_detect(struct snd_opl3 * opl3)
|
|||
* If we had an OPL4 chip, opl3->hardware would have been set
|
||||
* by the OPL4 driver; so we can assume OPL3 here.
|
||||
*/
|
||||
snd_assert(opl3->r_port != 0, return -ENODEV);
|
||||
if (snd_BUG_ON(!opl3->r_port))
|
||||
return -ENODEV;
|
||||
opl3->hardware = OPL3_HW_OPL3;
|
||||
}
|
||||
return 0;
|
||||
|
@ -324,7 +325,8 @@ EXPORT_SYMBOL(snd_opl3_interrupt);
|
|||
|
||||
static int snd_opl3_free(struct snd_opl3 *opl3)
|
||||
{
|
||||
snd_assert(opl3 != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!opl3))
|
||||
return -ENXIO;
|
||||
if (opl3->private_free)
|
||||
opl3->private_free(opl3);
|
||||
snd_opl3_clear_patches(opl3);
|
||||
|
|
|
@ -617,7 +617,8 @@ static void snd_opl3_kill_voice(struct snd_opl3 *opl3, int voice)
|
|||
|
||||
struct snd_opl3_voice *vp, *vp2;
|
||||
|
||||
snd_assert(voice < MAX_OPL3_VOICES, return);
|
||||
if (snd_BUG_ON(voice >= MAX_OPL3_VOICES))
|
||||
return;
|
||||
|
||||
vp = &opl3->voices[voice];
|
||||
if (voice < MAX_OPL2_VOICES) {
|
||||
|
@ -737,7 +738,8 @@ static void snd_opl3_update_pitch(struct snd_opl3 *opl3, int voice)
|
|||
|
||||
struct snd_opl3_voice *vp;
|
||||
|
||||
snd_assert(voice < MAX_OPL3_VOICES, return);
|
||||
if (snd_BUG_ON(voice >= MAX_OPL3_VOICES))
|
||||
return;
|
||||
|
||||
vp = &opl3->voices[voice];
|
||||
if (vp->chan == NULL)
|
||||
|
|
|
@ -162,7 +162,8 @@ static int snd_opl3_open_seq_oss(struct snd_seq_oss_arg *arg, void *closure)
|
|||
struct snd_opl3 *opl3 = closure;
|
||||
int err;
|
||||
|
||||
snd_assert(arg != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!arg))
|
||||
return -ENXIO;
|
||||
|
||||
if ((err = snd_opl3_synth_setup(opl3)) < 0)
|
||||
return err;
|
||||
|
@ -184,7 +185,8 @@ static int snd_opl3_close_seq_oss(struct snd_seq_oss_arg *arg)
|
|||
{
|
||||
struct snd_opl3 *opl3;
|
||||
|
||||
snd_assert(arg != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!arg))
|
||||
return -ENXIO;
|
||||
opl3 = arg->private_data;
|
||||
|
||||
snd_opl3_synth_cleanup(opl3);
|
||||
|
@ -206,7 +208,8 @@ static int snd_opl3_load_patch_seq_oss(struct snd_seq_oss_arg *arg, int format,
|
|||
char name[32];
|
||||
int err, type;
|
||||
|
||||
snd_assert(arg != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!arg))
|
||||
return -ENXIO;
|
||||
opl3 = arg->private_data;
|
||||
|
||||
if (format == FM_PATCH)
|
||||
|
@ -246,7 +249,8 @@ static int snd_opl3_ioctl_seq_oss(struct snd_seq_oss_arg *arg, unsigned int cmd,
|
|||
{
|
||||
struct snd_opl3 *opl3;
|
||||
|
||||
snd_assert(arg != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!arg))
|
||||
return -ENXIO;
|
||||
opl3 = arg->private_data;
|
||||
switch (cmd) {
|
||||
case SNDCTL_FM_LOAD_INSTR:
|
||||
|
@ -271,7 +275,8 @@ static int snd_opl3_reset_seq_oss(struct snd_seq_oss_arg *arg)
|
|||
{
|
||||
struct snd_opl3 *opl3;
|
||||
|
||||
snd_assert(arg != NULL, return -ENXIO);
|
||||
if (snd_BUG_ON(!arg))
|
||||
return -ENXIO;
|
||||
opl3 = arg->private_data;
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -92,7 +92,8 @@ int snd_opl3_ioctl(struct snd_hwdep * hw, struct file *file,
|
|||
struct snd_opl3 *opl3 = hw->private_data;
|
||||
void __user *argp = (void __user *)arg;
|
||||
|
||||
snd_assert(opl3 != NULL, return -EINVAL);
|
||||
if (snd_BUG_ON(!opl3))
|
||||
return -EINVAL;
|
||||
|
||||
switch (cmd) {
|
||||
/* get information */
|
||||
|
|
|
@ -467,7 +467,7 @@ static struct opl4_voice *snd_opl4_get_voice(struct snd_opl4 *opl4)
|
|||
if (!list_empty(&opl4->off_voices))
|
||||
return list_entry(opl4->off_voices.next, struct opl4_voice, list);
|
||||
/* then get the oldest key-on voice */
|
||||
snd_assert(!list_empty(&opl4->on_voices), );
|
||||
snd_BUG_ON(list_empty(&opl4->on_voices));
|
||||
return list_entry(opl4->on_voices.next, struct opl4_voice, list);
|
||||
}
|
||||
|
||||
|
|
|
@ -99,7 +99,8 @@ static struct vx_cmd_info vx_dsp_cmds[] = {
|
|||
*/
|
||||
void vx_init_rmh(struct vx_rmh *rmh, unsigned int cmd)
|
||||
{
|
||||
snd_assert(cmd < CMD_LAST_INDEX, return);
|
||||
if (snd_BUG_ON(cmd >= CMD_LAST_INDEX))
|
||||
return;
|
||||
rmh->LgCmd = vx_dsp_cmds[cmd].length;
|
||||
rmh->LgStat = vx_dsp_cmds[cmd].st_length;
|
||||
rmh->DspStat = vx_dsp_cmds[cmd].st_type;
|
||||
|
|
|
@ -205,7 +205,8 @@ static int vx_read_status(struct vx_core *chip, struct vx_rmh *rmh)
|
|||
|
||||
if (size < 1)
|
||||
return 0;
|
||||
snd_assert(size <= SIZE_MAX_STATUS, return -EINVAL);
|
||||
if (snd_BUG_ON(size > SIZE_MAX_STATUS))
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 1; i <= size; i++) {
|
||||
/* trigger an irq MESS_WRITE_NEXT */
|
||||
|
@ -425,13 +426,16 @@ int snd_vx_load_boot_image(struct vx_core *chip, const struct firmware *boot)
|
|||
int no_fillup = vx_has_new_dsp(chip);
|
||||
|
||||
/* check the length of boot image */
|
||||
snd_assert(boot->size > 0, return -EINVAL);
|
||||
snd_assert(boot->size % 3 == 0, return -EINVAL);
|
||||
if (boot->size <= 0)
|
||||
return -EINVAL;
|
||||
if (boot->size % 3)
|
||||
return -EINVAL;
|
||||
#if 0
|
||||
{
|
||||
/* more strict check */
|
||||
unsigned int c = ((u32)boot->data[0] << 16) | ((u32)boot->data[1] << 8) | boot->data[2];
|
||||
snd_assert(boot->size == (c + 2) * 3, return -EINVAL);
|
||||
if (boot->size != (c + 2) * 3)
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -554,7 +558,8 @@ EXPORT_SYMBOL(snd_vx_irq_handler);
|
|||
*/
|
||||
static void vx_reset_board(struct vx_core *chip, int cold_reset)
|
||||
{
|
||||
snd_assert(chip->ops->reset_board, return);
|
||||
if (snd_BUG_ON(!chip->ops->reset_board))
|
||||
return;
|
||||
|
||||
/* current source, later sync'ed with target */
|
||||
chip->audio_source = VX_AUDIO_SRC_LINE;
|
||||
|
@ -673,7 +678,8 @@ int snd_vx_dsp_load(struct vx_core *chip, const struct firmware *dsp)
|
|||
unsigned int csum = 0;
|
||||
const unsigned char *image, *cptr;
|
||||
|
||||
snd_assert(dsp->size % 3 == 0, return -EINVAL);
|
||||
if (dsp->size % 3)
|
||||
return -EINVAL;
|
||||
|
||||
vx_toggle_dac_mute(chip, 1);
|
||||
|
||||
|
@ -775,7 +781,8 @@ struct vx_core *snd_vx_create(struct snd_card *card, struct snd_vx_hardware *hw,
|
|||
{
|
||||
struct vx_core *chip;
|
||||
|
||||
snd_assert(card && hw && ops, return NULL);
|
||||
if (snd_BUG_ON(!card || !hw || !ops))
|
||||
return NULL;
|
||||
|
||||
chip = kzalloc(sizeof(*chip) + extra_size, GFP_KERNEL);
|
||||
if (! chip) {
|
||||
|
|
|
@ -141,7 +141,8 @@ static int vx_hwdep_dsp_status(struct snd_hwdep *hw,
|
|||
};
|
||||
struct vx_core *vx = hw->private_data;
|
||||
|
||||
snd_assert(type_ids[vx->type], return -EINVAL);
|
||||
if (snd_BUG_ON(!type_ids[vx->type]))
|
||||
return -EINVAL;
|
||||
strcpy(info->id, type_ids[vx->type]);
|
||||
if (vx_is_pcmcia(vx))
|
||||
info->num_dsps = 4;
|
||||
|
@ -168,7 +169,8 @@ static int vx_hwdep_dsp_load(struct snd_hwdep *hw,
|
|||
int index, err;
|
||||
struct firmware *fw;
|
||||
|
||||
snd_assert(vx->ops->load_dsp, return -ENXIO);
|
||||
if (snd_BUG_ON(!vx->ops->load_dsp))
|
||||
return -ENXIO;
|
||||
|
||||
fw = kmalloc(sizeof(*fw), GFP_KERNEL);
|
||||
if (! fw) {
|
||||
|
|
|
@ -34,7 +34,8 @@ static void vx_write_codec_reg(struct vx_core *chip, int codec, unsigned int dat
|
|||
{
|
||||
unsigned long flags;
|
||||
|
||||
snd_assert(chip->ops->write_codec, return);
|
||||
if (snd_BUG_ON(!chip->ops->write_codec))
|
||||
return;
|
||||
|
||||
if (chip->chip_status & VX_STAT_IS_STALE)
|
||||
return;
|
||||
|
|
|
@ -587,7 +587,8 @@ static int vx_pcm_playback_open(struct snd_pcm_substream *subs)
|
|||
return -EBUSY;
|
||||
|
||||
audio = subs->pcm->device * 2;
|
||||
snd_assert(audio < chip->audio_outs, return -EINVAL);
|
||||
if (snd_BUG_ON(audio >= chip->audio_outs))
|
||||
return -EINVAL;
|
||||
|
||||
/* playback pipe may have been already allocated for monitoring */
|
||||
pipe = chip->playback_pipes[audio];
|
||||
|
@ -996,7 +997,8 @@ static int vx_pcm_capture_open(struct snd_pcm_substream *subs)
|
|||
return -EBUSY;
|
||||
|
||||
audio = subs->pcm->device * 2;
|
||||
snd_assert(audio < chip->audio_ins, return -EINVAL);
|
||||
if (snd_BUG_ON(audio >= chip->audio_ins))
|
||||
return -EINVAL;
|
||||
err = vx_alloc_pipe(chip, 1, audio, 2, &pipe);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
@ -1214,7 +1216,8 @@ void vx_pcm_update_intr(struct vx_core *chip, unsigned int events)
|
|||
}
|
||||
if (capture)
|
||||
continue;
|
||||
snd_assert(p >= 0 && (unsigned int)p < chip->audio_outs,);
|
||||
if (snd_BUG_ON(p < 0 || p >= chip->audio_outs))
|
||||
continue;
|
||||
pipe = chip->playback_pipes[p];
|
||||
if (pipe && pipe->substream) {
|
||||
vx_pcm_playback_update(chip, pipe->substream, pipe);
|
||||
|
|
|
@ -163,13 +163,15 @@ static int vx_calc_clock_from_freq(struct vx_core *chip, int freq)
|
|||
{
|
||||
int hexfreq;
|
||||
|
||||
snd_assert(freq > 0, return 0);
|
||||
if (snd_BUG_ON(freq <= 0))
|
||||
return 0;
|
||||
|
||||
hexfreq = (28224000 * 10) / freq;
|
||||
hexfreq = (hexfreq + 5) / 10;
|
||||
|
||||
/* max freq = 55125 Hz */
|
||||
snd_assert(hexfreq > 0x00000200, return 0);
|
||||
if (snd_BUG_ON(hexfreq <= 0x00000200))
|
||||
return 0;
|
||||
|
||||
if (hexfreq <= 0x03ff)
|
||||
return hexfreq - 0x00000201;
|
||||
|
|
|
@ -314,7 +314,8 @@ static void snd_cs8427_reset(struct snd_i2c_device *cs8427)
|
|||
unsigned long end_time;
|
||||
int data, aes3input = 0;
|
||||
|
||||
snd_assert(cs8427, return);
|
||||
if (snd_BUG_ON(!cs8427))
|
||||
return;
|
||||
chip = cs8427->private_data;
|
||||
snd_i2c_lock(cs8427->bus);
|
||||
if ((chip->regmap[CS8427_REG_CLOCKSOURCE] & CS8427_RXDAES3INPUT) ==
|
||||
|
@ -526,7 +527,8 @@ int snd_cs8427_iec958_build(struct snd_i2c_device *cs8427,
|
|||
unsigned int idx;
|
||||
int err;
|
||||
|
||||
snd_assert(play_substream && cap_substream, return -EINVAL);
|
||||
if (snd_BUG_ON(!play_substream || !cap_substream))
|
||||
return -EINVAL;
|
||||
for (idx = 0; idx < ARRAY_SIZE(snd_cs8427_iec958_controls); idx++) {
|
||||
kctl = snd_ctl_new1(&snd_cs8427_iec958_controls[idx], cs8427);
|
||||
if (kctl == NULL)
|
||||
|
@ -543,7 +545,8 @@ int snd_cs8427_iec958_build(struct snd_i2c_device *cs8427,
|
|||
|
||||
chip->playback.substream = play_substream;
|
||||
chip->capture.substream = cap_substream;
|
||||
snd_assert(chip->playback.pcm_ctl, return -EIO);
|
||||
if (snd_BUG_ON(!chip->playback.pcm_ctl))
|
||||
return -EIO;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -553,7 +556,8 @@ int snd_cs8427_iec958_active(struct snd_i2c_device *cs8427, int active)
|
|||
{
|
||||
struct cs8427 *chip;
|
||||
|
||||
snd_assert(cs8427, return -ENXIO);
|
||||
if (snd_BUG_ON(!cs8427))
|
||||
return -ENXIO;
|
||||
chip = cs8427->private_data;
|
||||
if (active)
|
||||
memcpy(chip->playback.pcm_status,
|
||||
|
@ -573,7 +577,8 @@ int snd_cs8427_iec958_pcm(struct snd_i2c_device *cs8427, unsigned int rate)
|
|||
char *status;
|
||||
int err, reset;
|
||||
|
||||
snd_assert(cs8427, return -ENXIO);
|
||||
if (snd_BUG_ON(!cs8427))
|
||||
return -ENXIO;
|
||||
chip = cs8427->private_data;
|
||||
status = chip->playback.pcm_status;
|
||||
snd_i2c_lock(cs8427->bus);
|
||||
|
|
|
@ -49,7 +49,8 @@ static int snd_i2c_bus_free(struct snd_i2c_bus *bus)
|
|||
struct snd_i2c_bus *slave;
|
||||
struct snd_i2c_device *device;
|
||||
|
||||
snd_assert(bus != NULL, return -EINVAL);
|
||||
if (snd_BUG_ON(!bus))
|
||||
return -EINVAL;
|
||||
while (!list_empty(&bus->devices)) {
|
||||
device = snd_i2c_device(bus->devices.next);
|
||||
snd_i2c_device_free(device);
|
||||
|
@ -113,7 +114,8 @@ int snd_i2c_device_create(struct snd_i2c_bus *bus, const char *name,
|
|||
struct snd_i2c_device *device;
|
||||
|
||||
*rdevice = NULL;
|
||||
snd_assert(bus != NULL, return -EINVAL);
|
||||
if (snd_BUG_ON(!bus))
|
||||
return -EINVAL;
|
||||
device = kzalloc(sizeof(*device), GFP_KERNEL);
|
||||
if (device == NULL)
|
||||
return -ENOMEM;
|
||||
|
|
|
@ -771,7 +771,8 @@ int __init snd_chip_uda1341_mixer_new(struct snd_card *card, struct l3_client **
|
|||
struct l3_client *clnt;
|
||||
int idx, err;
|
||||
|
||||
snd_assert(card != NULL, return -EINVAL);
|
||||
if (snd_BUG_ON(!card))
|
||||
return -EINVAL;
|
||||
|
||||
clnt = kzalloc(sizeof(*clnt), GFP_KERNEL);
|
||||
if (clnt == NULL)
|
||||
|
|
|
@ -475,7 +475,8 @@ int snd_ak4114_build(struct ak4114 *ak4114,
|
|||
unsigned int idx;
|
||||
int err;
|
||||
|
||||
snd_assert(cap_substream, return -EINVAL);
|
||||
if (snd_BUG_ON(!cap_substream))
|
||||
return -EINVAL;
|
||||
ak4114->playback_substream = ply_substream;
|
||||
ak4114->capture_substream = cap_substream;
|
||||
for (idx = 0; idx < AK4114_CONTROLS; idx++) {
|
||||
|
|
|
@ -431,7 +431,8 @@ int snd_ak4117_build(struct ak4117 *ak4117, struct snd_pcm_substream *cap_substr
|
|||
unsigned int idx;
|
||||
int err;
|
||||
|
||||
snd_assert(cap_substream, return -EINVAL);
|
||||
if (snd_BUG_ON(!cap_substream))
|
||||
return -EINVAL;
|
||||
ak4117->substream = cap_substream;
|
||||
for (idx = 0; idx < AK4117_CONTROLS; idx++) {
|
||||
kctl = snd_ctl_new1(&snd_ak4117_iec958_controls[idx], ak4117);
|
||||
|
|
|
@ -233,8 +233,8 @@ void snd_akm4xxx_init(struct snd_akm4xxx *ak)
|
|||
0x01, 0x02, /* 1: reset and soft-mute */
|
||||
0x00, 0x06, /* 0: mode3(i2s), disable auto-clock detect,
|
||||
* disable DZF, sharp roll-off, RSTN#=0 */
|
||||
0x02, 0x0e, /* 2: DA's power up, normal speed, RSTN#=0 */
|
||||
// 0x02, 0x2e, /* quad speed */
|
||||
0x02, 0x4e, /* 2: DA's power up, normal speed, RSTN#=0 */
|
||||
/* 0x02, 0x6e,*/ /* quad speed */
|
||||
0x03, 0x01, /* 3: de-emphasis off */
|
||||
0x04, 0x00, /* 4: LOUT1 volume muted */
|
||||
0x05, 0x00, /* 5: ROUT1 volume muted */
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
# ALSA ISA drivers
|
||||
|
||||
config SND_AD1848_LIB
|
||||
tristate
|
||||
select SND_PCM
|
||||
|
||||
config SND_CS4231_LIB
|
||||
config SND_WSS_LIB
|
||||
tristate
|
||||
select SND_PCM
|
||||
|
||||
|
@ -55,7 +51,7 @@ config SND_AD1816A
|
|||
|
||||
config SND_AD1848
|
||||
tristate "Generic AD1848/CS4248 driver"
|
||||
select SND_AD1848_LIB
|
||||
select SND_WSS_LIB
|
||||
help
|
||||
Say Y here to include support for AD1848 (Analog Devices) or
|
||||
CS4248 (Cirrus Logic - Crystal Semiconductors) chips.
|
||||
|
@ -86,7 +82,7 @@ config SND_AZT2320
|
|||
select ISAPNP
|
||||
select SND_OPL3_LIB
|
||||
select SND_MPU401_UART
|
||||
select SND_CS4231_LIB
|
||||
select SND_WSS_LIB
|
||||
help
|
||||
Say Y here to include support for soundcards based on the
|
||||
Aztech Systems AZT2320 chip.
|
||||
|
@ -96,7 +92,7 @@ config SND_AZT2320
|
|||
|
||||
config SND_CMI8330
|
||||
tristate "C-Media CMI8330"
|
||||
select SND_AD1848_LIB
|
||||
select SND_WSS_LIB
|
||||
select SND_SB16_DSP
|
||||
help
|
||||
Say Y here to include support for soundcards based on the
|
||||
|
@ -108,7 +104,7 @@ config SND_CMI8330
|
|||
config SND_CS4231
|
||||
tristate "Generic Cirrus Logic CS4231 driver"
|
||||
select SND_MPU401_UART
|
||||
select SND_CS4231_LIB
|
||||
select SND_WSS_LIB
|
||||
help
|
||||
Say Y here to include support for CS4231 chips from Cirrus
|
||||
Logic - Crystal Semiconductors.
|
||||
|
@ -120,7 +116,7 @@ config SND_CS4232
|
|||
tristate "Generic Cirrus Logic CS4232 driver"
|
||||
select SND_OPL3_LIB
|
||||
select SND_MPU401_UART
|
||||
select SND_CS4231_LIB
|
||||
select SND_WSS_LIB
|
||||
help
|
||||
Say Y here to include support for CS4232 chips from Cirrus
|
||||
Logic - Crystal Semiconductors.
|
||||
|
@ -132,7 +128,7 @@ config SND_CS4236
|
|||
tristate "Generic Cirrus Logic CS4236+ driver"
|
||||
select SND_OPL3_LIB
|
||||
select SND_MPU401_UART
|
||||
select SND_CS4231_LIB
|
||||
select SND_WSS_LIB
|
||||
help
|
||||
Say Y to include support for CS4235,CS4236,CS4237B,CS4238B,
|
||||
CS4239 chips from Cirrus Logic - Crystal Semiconductors.
|
||||
|
@ -192,7 +188,7 @@ config SND_ES18XX
|
|||
config SND_SC6000
|
||||
tristate "Gallant SC-6000, Audio Excel DSP 16"
|
||||
depends on HAS_IOPORT
|
||||
select SND_AD1848_LIB
|
||||
select SND_WSS_LIB
|
||||
select SND_OPL3_LIB
|
||||
select SND_MPU401_UART
|
||||
help
|
||||
|
@ -228,7 +224,7 @@ config SND_GUSEXTREME
|
|||
config SND_GUSMAX
|
||||
tristate "Gravis UltraSound MAX"
|
||||
select SND_RAWMIDI
|
||||
select SND_CS4231_LIB
|
||||
select SND_WSS_LIB
|
||||
help
|
||||
Say Y here to include support for Gravis UltraSound MAX
|
||||
soundcards.
|
||||
|
@ -240,7 +236,7 @@ config SND_INTERWAVE
|
|||
tristate "AMD InterWave, Gravis UltraSound PnP"
|
||||
depends on PNP
|
||||
select SND_RAWMIDI
|
||||
select SND_CS4231_LIB
|
||||
select SND_WSS_LIB
|
||||
help
|
||||
Say Y here to include support for AMD InterWave based
|
||||
soundcards (Gravis UltraSound Plug & Play, STB SoundRage32,
|
||||
|
@ -253,7 +249,7 @@ config SND_INTERWAVE_STB
|
|||
tristate "AMD InterWave + TEA6330T (UltraSound 32-Pro)"
|
||||
depends on PNP
|
||||
select SND_RAWMIDI
|
||||
select SND_CS4231_LIB
|
||||
select SND_WSS_LIB
|
||||
help
|
||||
Say Y here to include support for AMD InterWave based
|
||||
soundcards with a TEA6330T bass and treble regulator
|
||||
|
@ -266,7 +262,7 @@ config SND_OPL3SA2
|
|||
tristate "Yamaha OPL3-SA2/SA3"
|
||||
select SND_OPL3_LIB
|
||||
select SND_MPU401_UART
|
||||
select SND_CS4231_LIB
|
||||
select SND_WSS_LIB
|
||||
help
|
||||
Say Y here to include support for Yamaha OPL3-SA2 and OPL3-SA3
|
||||
chips.
|
||||
|
@ -279,7 +275,7 @@ config SND_OPTI92X_AD1848
|
|||
select SND_OPL3_LIB
|
||||
select SND_OPL4_LIB
|
||||
select SND_MPU401_UART
|
||||
select SND_AD1848_LIB
|
||||
select SND_WSS_LIB
|
||||
help
|
||||
Say Y here to include support for soundcards based on Opti
|
||||
82C92x or OTI-601 chips and using an AD1848 codec.
|
||||
|
@ -292,7 +288,7 @@ config SND_OPTI92X_CS4231
|
|||
select SND_OPL3_LIB
|
||||
select SND_OPL4_LIB
|
||||
select SND_MPU401_UART
|
||||
select SND_CS4231_LIB
|
||||
select SND_WSS_LIB
|
||||
help
|
||||
Say Y here to include support for soundcards based on Opti
|
||||
82C92x chips and using a CS4231 codec.
|
||||
|
@ -304,7 +300,7 @@ config SND_OPTI93X
|
|||
tristate "OPTi 82C93x"
|
||||
select SND_OPL3_LIB
|
||||
select SND_MPU401_UART
|
||||
select SND_CS4231_LIB
|
||||
select SND_WSS_LIB
|
||||
help
|
||||
Say Y here to include support for soundcards based on Opti
|
||||
82C93x chips.
|
||||
|
@ -315,7 +311,7 @@ config SND_OPTI93X
|
|||
config SND_MIRO
|
||||
tristate "Miro miroSOUND PCM1pro/PCM12/PCM20radio driver"
|
||||
select SND_OPL4_LIB
|
||||
select SND_CS4231_LIB
|
||||
select SND_WSS_LIB
|
||||
select SND_MPU401_UART
|
||||
select SND_PCM
|
||||
help
|
||||
|
@ -364,7 +360,7 @@ config SND_SBAWE
|
|||
config SND_SB16_CSP
|
||||
bool "Sound Blaster 16/AWE CSP support"
|
||||
depends on (SND_SB16 || SND_SBAWE) && (BROKEN || !PPC)
|
||||
select FW_LOADER if !SND_SB16_CSP_FIRMWARE_IN_KERNEL
|
||||
select FW_LOADER
|
||||
help
|
||||
Say Y here to include support for the CSP core. This special
|
||||
coprocessor can do variable tasks like various compression and
|
||||
|
@ -372,7 +368,7 @@ config SND_SB16_CSP
|
|||
|
||||
config SND_SGALAXY
|
||||
tristate "Aztech Sound Galaxy"
|
||||
select SND_AD1848_LIB
|
||||
select SND_WSS_LIB
|
||||
help
|
||||
Say Y here to include support for Aztech Sound Galaxy
|
||||
soundcards.
|
||||
|
@ -384,7 +380,7 @@ config SND_SSCAPE
|
|||
tristate "Ensoniq SoundScape PnP driver"
|
||||
select SND_HWDEP
|
||||
select SND_MPU401_UART
|
||||
select SND_CS4231_LIB
|
||||
select SND_WSS_LIB
|
||||
help
|
||||
Say Y here to include support for Ensoniq SoundScape PnP
|
||||
soundcards.
|
||||
|
@ -397,7 +393,7 @@ config SND_WAVEFRONT
|
|||
select FW_LOADER
|
||||
select SND_OPL3_LIB
|
||||
select SND_MPU401_UART
|
||||
select SND_CS4231_LIB
|
||||
select SND_WSS_LIB
|
||||
help
|
||||
Say Y here to include support for Turtle Beach Maui, Tropez
|
||||
and Tropez+ soundcards based on the Wavefront chip.
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue