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:
Linus Torvalds 2008-10-11 09:16:54 -07:00
commit d3570a5a7b
356 changed files with 28916 additions and 10684 deletions

View File

@ -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.

View File

@ -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>

View File

@ -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

View File

@ -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

View File

@ -203,6 +203,10 @@ config SOUND
tristate
default UML_SOUND
config SOUND_OSS_CORE
bool
default UML_SOUND
config HOSTAUDIO
tristate
default UML_SOUND

View File

@ -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++) {

View File

@ -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>
*

View File

@ -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 */

View File

@ -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,25 +297,35 @@ 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
@ -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;

View File

@ -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 */
/*****************************************************************************
* *

View File

@ -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 */

View File

@ -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
View 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

View File

@ -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,

View File

@ -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)

View File

@ -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 {
*
*/
#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 */

View 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

View File

@ -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

View File

@ -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"

View 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_ */

View File

@ -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;
};

View File

@ -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 ""

View File

@ -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
View 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 */

View File

@ -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.

View File

@ -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,
},

View File

@ -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.

View File

@ -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

View File

@ -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
View 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");

View File

@ -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
View 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");

View File

@ -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,

View File

@ -9,12 +9,13 @@
* 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 {

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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:

View File

@ -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:

View File

@ -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);
if (snd_BUG_ON(!card))
return -ENXIO;
if (rhwdep)
*rhwdep = NULL;
snd_assert(card != NULL, return -ENXIO);
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);
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(&register_mutex);
if (snd_hwdep_search(hwdep->card, hwdep->device) != hwdep) {
mutex_unlock(&register_mutex);

View File

@ -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);

View File

@ -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) {

View File

@ -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
View 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");

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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,

View File

@ -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];

View File

@ -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,

View File

@ -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,7 +2285,7 @@ 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);
if (rpcm_oss_file)
*rpcm_oss_file = NULL;
pcm_oss_file = kzalloc(sizeof(*pcm_oss_file), GFP_KERNEL);
@ -2312,6 +2326,7 @@ static int snd_pcm_oss_open_file(struct file *file,
}
file->private_data = 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

View File

@ -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;

View File

@ -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,

View File

@ -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);

View File

@ -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(&register_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(&register_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(&register_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);
if (snd_BUG_ON(!card))
return -ENXIO;
if (rpcm)
*rpcm = NULL;
snd_assert(card != NULL, return -ENXIO);
pcm = kzalloc(sizeof(*pcm), GFP_KERNEL);
if (pcm == NULL) {
snd_printk(KERN_ERR "Cannot allocate PCM\n");
@ -708,6 +731,7 @@ int snd_pcm_new(struct snd_card *card, char *id, int device,
snd_pcm_free(pcm);
return err;
}
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(&register_mutex);
if (snd_pcm_search(pcm->card, pcm->device)) {
err = snd_pcm_add(pcm);
if (err) {
mutex_unlock(&register_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(&register_mutex);
if (nfree) {
list_del(&notify->list);

View File

@ -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) ||

View File

@ -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;

View File

@ -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) {

View File

@ -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,7 +2070,7 @@ static int snd_pcm_open_file(struct file *file,
struct snd_pcm_str *str;
int err;
snd_assert(rpcm_file != NULL, return -EINVAL);
if (rpcm_file)
*rpcm_file = NULL;
err = snd_pcm_open_substream(pcm, stream, file, &substream);
@ -2086,6 +2089,7 @@ static int snd_pcm_open_file(struct file *file,
substream->pcm_release = pcm_release_private;
}
file->private_data = 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,
}
};

View File

@ -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;

View File

@ -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);
if (snd_BUG_ON(!card))
return -ENXIO;
if (rrawmidi)
*rrawmidi = NULL;
snd_assert(card != NULL, return -ENXIO);
rmidi = kzalloc(sizeof(*rmidi), GFP_KERNEL);
if (rmidi == NULL) {
snd_printk(KERN_ERR "rawmidi: cannot allocate\n");
@ -1455,6 +1458,7 @@ int snd_rawmidi_new(struct snd_card *card, char *id, int device,
snd_rawmidi_free(rmidi);
return err;
}
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;

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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;

View File

@ -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;

View File

@ -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:

View File

@ -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)

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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));

View File

@ -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);

View File

@ -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)

View File

@ -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)

View File

@ -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:

View File

@ -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;

View File

@ -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;
}

View File

@ -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,8 +761,9 @@ 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);
if (snd_BUG_ON(!tid))
return -EINVAL;
if (rtimer)
*rtimer = NULL;
timer = kzalloc(sizeof(*timer), GFP_KERNEL);
if (timer == NULL) {
@ -788,13 +792,15 @@ int snd_timer_new(struct snd_card *card, char *id, struct snd_timer_id *tid,
return err;
}
}
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(&register_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 ||

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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)

View File

@ -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;

View File

@ -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 */

View File

@ -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);
}

View File

@ -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;

View File

@ -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) {

View File

@ -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) {

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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)

View File

@ -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++) {

View File

@ -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);

View File

@ -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 */

View File

@ -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