Commit e349792a authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6: (290 commits)
  ALSA: pcm - Update document about xrun_debug proc file
  ALSA: lx6464es - support standard alsa module parameters
  ALSA: snd_usb_caiaq: set mixername
  ALSA: hda - add quirk for STAC92xx (SigmaTel STAC9205)
  ALSA: use card device as parent for jack input-devices
  ALSA: sound/ps3: Correct existing and add missing annotations
  ALSA: sound/ps3: Restructure driver source
  ALSA: sound/ps3: Fix checkpatch issues
  ASoC: Fix lm4857 control
  ALSA: ctxfi - Clear PCM resources at hw_params and hw_free
  ALSA: ctxfi - Check the presence of SRC instance in PCM pointer callbacks
  ALSA: ctxfi - Add missing start check in atc_pcm_playback_start()
  ALSA: ctxfi - Add use_system_timer module option
  ALSA: usb - Add boot quirk for C-Media 6206 USB Audio
  ALSA: ctxfi - Fix wrong model id for UAA
  ALSA: ctxfi - Clean up probe routines
  ALSA: hda - Fix the previous tagra-8ch patch
  ALSA: hda - Add 7.1 support for MSI GX620
  ALSA: pcm - A helper function to compose PCM stream name for debug prints
  ALSA: emu10k1 - Fix minimum periods for efx playback
  ...
parents 6d214918 e3f86d3d
......@@ -460,6 +460,25 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
The power-management is supported.
Module snd-ctxfi
----------------
Module for Creative Sound Blaster X-Fi boards (20k1 / 20k2 chips)
* Creative Sound Blaster X-Fi Titanium Fatal1ty Champion Series
* Creative Sound Blaster X-Fi Titanium Fatal1ty Professional Series
* Creative Sound Blaster X-Fi Titanium Professional Audio
* Creative Sound Blaster X-Fi Titanium
* Creative Sound Blaster X-Fi Elite Pro
* Creative Sound Blaster X-Fi Platinum
* Creative Sound Blaster X-Fi Fatal1ty
* Creative Sound Blaster X-Fi XtremeGamer
* Creative Sound Blaster X-Fi XtremeMusic
reference_rate - reference sample rate, 44100 or 48000 (default)
multiple - multiple to ref. sample rate, 1 or 2 (default)
This module supports multiple cards.
Module snd-darla20
------------------
......@@ -925,6 +944,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
* Onkyo SE-90PCI
* Onkyo SE-200PCI
* ESI Juli@
* ESI Maya44
* Hercules Fortissimo IV
* EGO-SYS WaveTerminal 192M
......@@ -933,7 +953,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
prodigy71xt, prodigy71hifi, prodigyhd2, prodigy192,
juli, aureon51, aureon71, universe, ap192, k8x800,
phase22, phase28, ms300, av710, se200pci, se90pci,
fortissimo4, sn25p, WT192M
fortissimo4, sn25p, WT192M, maya44
This module supports multiple cards and autoprobe.
......@@ -1093,6 +1113,13 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
This module supports multiple cards.
The driver requires the firmware loader support on kernel.
Module snd-lx6464es
-------------------
Module for Digigram LX6464ES boards
This module supports multiple cards.
Module snd-maestro3
-------------------
......@@ -1543,13 +1570,15 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
Module snd-sc6000
-----------------
Module for Gallant SC-6000 soundcard.
Module for Gallant SC-6000 soundcard and later models: SC-6600
and SC-7000.
port - Port # (0x220 or 0x240)
mss_port - MSS Port # (0x530 or 0xe80)
irq - IRQ # (5,7,9,10,11)
mpu_irq - MPU-401 IRQ # (5,7,9,10) ,0 - no MPU-401 irq
dma - DMA # (1,3,0)
joystick - Enable gameport - 0 = disable (default), 1 = enable
This module supports multiple cards.
......@@ -1859,7 +1888,8 @@ 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, D2X, HDAV1.3 (Deluxe), and Essence STX.
i.e., Xonar D1, DX, D2, D2X, HDAV1.3 (Deluxe), Essence ST
(Deluxe) and Essence STX.
This module supports autoprobe and multiple cards.
......
......@@ -36,6 +36,7 @@ ALC260
acer Acer TravelMate
will Will laptops (PB V7900)
replacer Replacer 672V
favorit100 Maxdata Favorit 100XS
basic fixed pin assignment (old default model)
test for testing/debugging purpose, almost all controls can
adjusted. Appearing only when compiled with
......@@ -85,10 +86,11 @@ ALC269
eeepc-p703 ASUS Eeepc P703 P900A
eeepc-p901 ASUS Eeepc P901 S101
fujitsu FSC Amilo
lifebook Fujitsu Lifebook S6420
auto auto-config reading BIOS (default)
ALC662/663
==========
ALC662/663/272
==============
3stack-dig 3-stack (2-channel) with SPDIF
3stack-6ch 3-stack (6-channel)
3stack-6ch-dig 3-stack (6-channel) with SPDIF
......@@ -107,6 +109,9 @@ ALC662/663
asus-mode4 ASUS
asus-mode5 ASUS
asus-mode6 ASUS
dell Dell with ALC272
dell-zm1 Dell ZM1 with ALC272
samsung-nc10 Samsung NC10 mini notebook
auto auto-config reading BIOS (default)
ALC882/885
......@@ -118,6 +123,7 @@ ALC882/885
asus-a7j ASUS A7J
asus-a7m ASUS A7M
macpro MacPro support
mb5 Macbook 5,1
mbp3 Macbook Pro rev3
imac24 iMac 24'' with jack detection
w2jc ASUS W2JC
......@@ -133,10 +139,12 @@ ALC883/888
acer Acer laptops (Travelmate 3012WTMi, Aspire 5600, etc)
acer-aspire Acer Aspire 9810
acer-aspire-4930g Acer Aspire 4930G
acer-aspire-8930g Acer Aspire 8930G
medion Medion Laptops
medion-md2 Medion MD2
targa-dig Targa/MSI
targa-2ch-dig Targs/MSI with 2-channel
targa-2ch-dig Targa/MSI with 2-channel
targa-8ch-dig Targa/MSI with 8-channel (MSI GX620)
laptop-eapd 3-jack with SPDIF I/O and EAPD (Clevo M540JE, M550JE)
lenovo-101e Lenovo 101E
lenovo-nb0763 Lenovo NB0763
......@@ -150,6 +158,9 @@ ALC883/888
fujitsu-pi2515 Fujitsu AMILO Pi2515
fujitsu-xa3530 Fujitsu AMILO XA3530
3stack-6ch-intel Intel DG33* boards
asus-p5q ASUS P5Q-EM boards
mb31 MacBook 3,1
sony-vaio-tt Sony VAIO TT
auto auto-config reading BIOS (default)
ALC861/660
......@@ -348,6 +359,7 @@ STAC92HD71B*
hp-m4 HP mini 1000
hp-dv5 HP dv series
hp-hdx HP HDX series
hp-dv4-1222nr HP dv4-1222nr (with LED support)
auto BIOS setup (default)
STAC92HD73*
......
......@@ -88,26 +88,34 @@ card*/pcm*/info
substreams, etc.
card*/pcm*/xrun_debug
This file appears when CONFIG_SND_DEBUG=y.
This shows the status of xrun (= buffer overrun/xrun) debug of
ALSA PCM middle layer, as an integer from 0 to 2. The value
can be changed by writing to this file, such as
# cat 2 > /proc/asound/card0/pcm0p/xrun_debug
When this value is greater than 0, the driver will show the
messages to kernel log when an xrun is detected. The debug
message is shown also when the invalid H/W pointer is detected
at the update of periods (usually called from the interrupt
This file appears when CONFIG_SND_DEBUG=y and
CONFIG_PCM_XRUN_DEBUG=y.
This shows the status of xrun (= buffer overrun/xrun) and
invalid PCM position debug/check of ALSA PCM middle layer.
It takes an integer value, can be changed by writing to this
file, such as
# cat 5 > /proc/asound/card0/pcm0p/xrun_debug
The value consists of the following bit flags:
bit 0 = Enable XRUN/jiffies debug messages
bit 1 = Show stack trace at XRUN / jiffies check
bit 2 = Enable additional jiffies check
When the bit 0 is set, the driver will show the messages to
kernel log when an xrun is detected. The debug message is
shown also when the invalid H/W pointer is detected at the
update of periods (usually called from the interrupt
handler).
When this value is greater than 1, the driver will show the
stack trace additionally. This may help the debugging.
When the bit 1 is set, the driver will show the stack trace
additionally. This may help the debugging.
Since 2.6.30, this option also enables the hwptr check using
Since 2.6.30, this option can enable the hwptr check using
jiffies. This detects spontaneous invalid pointer callback
values, but can be lead to too much corrections for a (mostly
buggy) hardware that doesn't give smooth pointer updates.
This feature is enabled via the bit 2.
card*/pcm*/sub*/info
The general information of this PCM sub-stream.
......
NOTE: The following is the original document of Rainer's patch that the
current maya44 code based on. Some contents might be obsoleted, but I
keep here as reference -- tiwai
----------------------------------------------------------------
STATE OF DEVELOPMENT:
This driver is being developed on the initiative of Piotr Makowski (oponek@gmail.com) and financed by Lars Bergmann.
Development is carried out by Rainer Zimmermann (mail@lightshed.de).
ESI provided a sample Maya44 card for the development work.
However, unfortunately it has turned out difficult to get detailed programming information, so I (Rainer Zimmermann) had to find out some card-specific information by experiment and conjecture. Some information (in particular, several GPIO bits) is still missing.
This is the first testing version of the Maya44 driver released to the alsa-devel mailing list (Feb 5, 2008).
The following functions work, as tested by Rainer Zimmermann and Piotr Makowski:
- playback and capture at all sampling rates
- input/output level
- crossmixing
- line/mic switch
- phantom power switch
- analogue monitor a.k.a bypass
The following functions *should* work, but are not fully tested:
- Channel 3+4 analogue - S/PDIF input switching
- S/PDIF output
- all inputs/outputs on the M/IO/DIO extension card
- internal/external clock selection
*In particular, we would appreciate testing of these functions by anyone who has access to an M/IO/DIO extension card.*
Things that do not seem to work:
- The level meters ("multi track") in 'alsamixer' do not seem to react to signals in (if this is a bug, it would probably be in the existing ICE1724 code).
- Ardour 2.1 seems to work only via JACK, not using ALSA directly or via OSS. This still needs to be tracked down.
DRIVER DETAILS:
the following files were added:
pci/ice1724/maya44.c - Maya44 specific code
pci/ice1724/maya44.h
pci/ice1724/ice1724.patch
pci/ice1724/ice1724.h.patch - PROPOSED patch to ice1724.h (see SAMPLING RATES)
i2c/other/wm8776.c - low-level access routines for Wolfson WM8776 codecs
include/wm8776.h
Note that the wm8776.c code is meant to be card-independent and does not actually register the codec with the ALSA infrastructure.
This is done in maya44.c, mainly because some of the WM8776 controls are used in Maya44-specific ways, and should be named appropriately.
the following files were created in pci/ice1724, simply #including the corresponding file from the alsa-kernel tree:
wtm.h
vt1720_mobo.h
revo.h
prodigy192.h
pontis.h
phase.h
maya44.h
juli.h
aureon.h
amp.h
envy24ht.h
se.h
prodigy_hifi.h
*I hope this is the correct way to do things.*
SAMPLING RATES:
The Maya44 card (or more exactly, the Wolfson WM8776 codecs) allow a maximum sampling rate of 192 kHz for playback and 92 kHz for capture.
As the ICE1724 chip only allows one global sampling rate, this is handled as follows:
* setting the sampling rate on any open PCM device on the maya44 card will always set the *global* sampling rate for all playback and capture channels.
* In the current state of the driver, setting rates of up to 192 kHz is permitted even for capture devices.
*AVOID CAPTURING AT RATES ABOVE 96kHz*, even though it may appear to work. The codec cannot actually capture at such rates, meaning poor quality.
I propose some additional code for limiting the sampling rate when setting on a capture pcm device. However because of the global sampling rate, this logic would be somewhat problematic.
The proposed code (currently deactivated) is in ice1712.h.patch, ice1724.c and maya44.c (in pci/ice1712).
SOUND DEVICES:
PCM devices correspond to inputs/outputs as follows (assuming Maya44 is card #0):
hw:0,0 input - stereo, analog input 1+2
hw:0,0 output - stereo, analog output 1+2
hw:0,1 input - stereo, analog input 3+4 OR S/PDIF input
hw:0,1 output - stereo, analog output 3+4 (and SPDIF out)
NAMING OF MIXER CONTROLS:
(for more information about the signal flow, please refer to the block diagram on p.24 of the ESI Maya44 manual, or in the ESI windows software).
PCM: (digital) output level for channel 1+2
PCM 1: same for channel 3+4
Mic Phantom+48V: switch for +48V phantom power for electrostatic microphones on input 1/2.
Make sure this is not turned on while any other source is connected to input 1/2.
It might damage the source and/or the maya44 card.
Mic/Line input: if switch is is on, input jack 1/2 is microphone input (mono), otherwise line input (stereo).
Bypass: analogue bypass from ADC input to output for channel 1+2. Same as "Monitor" in the windows driver.
Bypass 1: same for channel 3+4.
Crossmix: cross-mixer from channels 1+2 to channels 3+4
Crossmix 1: cross-mixer from channels 3+4 to channels 1+2
IEC958 Output: switch for S/PDIF output.
This is not supported by the ESI windows driver.
S/PDIF should output the same signal as channel 3+4. [untested!]
Digitial output selectors:
These switches allow a direct digital routing from the ADCs to the DACs.
Each switch determines where the digital input data to one of the DACs comes from.
They are not supported by the ESI windows driver.
For normal operation, they should all be set to "PCM out".
H/W: Output source channel 1
H/W 1: Output source channel 2
H/W 2: Output source channel 3
H/W 3: Output source channel 4
H/W 4 ... H/W 9: unknown function, left in to enable testing.
Possibly some of these control S/PDIF output(s).
If these turn out to be unused, they will go away in later driver versions.
Selectable values for each of the digital output selectors are:
"PCM out" -> DAC output of the corresponding channel (default setting)
"Input 1"...
"Input 4" -> direct routing from ADC output of the selected input channel
--------
Feb 14, 2008
Rainer Zimmermann
mail@lightshed.de
......@@ -62,6 +62,7 @@ Audio DAPM widgets fall into a number of types:-
o Mic - Mic (and optional Jack)
o Line - Line Input/Output (and optional Jack)
o Speaker - Speaker
o Supply - Power or clock supply widget used by other widgets.
o Pre - Special PRE widget (exec before all others)
o Post - Special POST widget (exec after all others)
......
......@@ -4603,7 +4603,8 @@ F: drivers/pcmcia/pxa2xx*
F: drivers/spi/pxa2xx*
F: drivers/usb/gadget/pxa2*
F: include/sound/pxa2xx-lib.h
F: sound/soc/pxa/pxa2xx*
F: sound/arm/pxa*
F: sound/soc/pxa
PXA168 SUPPORT
P: Eric Miao
......@@ -5331,11 +5332,12 @@ P: Liam Girdwood
M: lrg@slimlogic.co.uk
P: Mark Brown
M: broonie@opensource.wolfsonmicro.com
T: git git://opensource.wolfsonmicro.com/linux-2.6-asoc
T: git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound-2.6.git
L: alsa-devel@alsa-project.org (subscribers-only)
W: http://alsa-project.org/main/index.php/ASoC
S: Supported
F: sound/soc/
F: include/sound/soc*
SPARC + UltraSPARC (sparc/sparc64)
P: David S. Miller
......
......@@ -28,6 +28,10 @@
#define MPC52xx_PSC_MAXNUM 6
/* Programmable Serial Controller (PSC) status register bits */
#define MPC52xx_PSC_SR_UNEX_RX 0x0001
#define MPC52xx_PSC_SR_DATA_VAL 0x0002
#define MPC52xx_PSC_SR_DATA_OVR 0x0004
#define MPC52xx_PSC_SR_CMDSEND 0x0008
#define MPC52xx_PSC_SR_CDE 0x0080
#define MPC52xx_PSC_SR_RXRDY 0x0100
#define MPC52xx_PSC_SR_RXFULL 0x0200
......@@ -61,6 +65,12 @@
#define MPC52xx_PSC_RXTX_FIFO_EMPTY 0x0001
/* PSC interrupt status/mask bits */
#define MPC52xx_PSC_IMR_UNEX_RX_SLOT 0x0001
#define MPC52xx_PSC_IMR_DATA_VALID 0x0002
#define MPC52xx_PSC_IMR_DATA_OVR 0x0004
#define MPC52xx_PSC_IMR_CMD_SEND 0x0008
#define MPC52xx_PSC_IMR_ERROR 0x0040
#define MPC52xx_PSC_IMR_DEOF 0x0080
#define MPC52xx_PSC_IMR_TXRDY 0x0100
#define MPC52xx_PSC_IMR_RXRDY 0x0200
#define MPC52xx_PSC_IMR_DB 0x0400
......@@ -117,6 +127,7 @@
#define MPC52xx_PSC_SICR_SIM_FIR (0x6 << 24)
#define MPC52xx_PSC_SICR_SIM_CODEC_24 (0x7 << 24)
#define MPC52xx_PSC_SICR_SIM_CODEC_32 (0xf << 24)
#define MPC52xx_PSC_SICR_AWR (1 << 30)
#define MPC52xx_PSC_SICR_GENCLK (1 << 23)
#define MPC52xx_PSC_SICR_I2S (1 << 22)
#define MPC52xx_PSC_SICR_CLKPOL (1 << 21)
......
......@@ -1005,6 +1005,7 @@
#define PCI_DEVICE_ID_PLX_PCI200SYN 0x3196
#define PCI_DEVICE_ID_PLX_9030 0x9030
#define PCI_DEVICE_ID_PLX_9050 0x9050
#define PCI_DEVICE_ID_PLX_9056 0x9056
#define PCI_DEVICE_ID_PLX_9080 0x9080
#define PCI_DEVICE_ID_PLX_GTEK_SERIAL2 0xa001
......@@ -1314,6 +1315,13 @@
#define PCI_VENDOR_ID_CREATIVE 0x1102 /* duplicate: ECTIVA */
#define PCI_DEVICE_ID_CREATIVE_EMU10K1 0x0002
#define PCI_DEVICE_ID_CREATIVE_20K1 0x0005
#define PCI_DEVICE_ID_CREATIVE_20K2 0x000b
#define PCI_SUBDEVICE_ID_CREATIVE_SB0760 0x0024
#define PCI_SUBDEVICE_ID_CREATIVE_SB08801 0x0041
#define PCI_SUBDEVICE_ID_CREATIVE_SB08802 0x0042
#define PCI_SUBDEVICE_ID_CREATIVE_SB08803 0x0043
#define PCI_SUBDEVICE_ID_CREATIVE_HENDRIX 0x6000
#define PCI_VENDOR_ID_ECTIVA 0x1102 /* duplicate: CREATIVE */
#define PCI_DEVICE_ID_ECTIVA_EV1938 0x8938
......@@ -1847,6 +1855,10 @@
#define PCI_SUBDEVICE_ID_HYPERCOPE_METRO 0x0107
#define PCI_SUBDEVICE_ID_HYPERCOPE_CHAMP2 0x0108
#define PCI_VENDOR_ID_DIGIGRAM 0x1369
#define PCI_SUBDEVICE_ID_DIGIGRAM_LX6464ES_SERIAL_SUBSYSTEM 0xc001
#define PCI_SUBDEVICE_ID_DIGIGRAM_LX6464ES_CAE_SERIAL_SUBSYSTEM 0xc002
#define PCI_VENDOR_ID_KAWASAKI 0x136b
#define PCI_DEVICE_ID_MCHIP_KL5A72002 0xff01
......
......@@ -255,6 +255,7 @@ typedef int __bitwise snd_pcm_subformat_t;
#define SNDRV_PCM_INFO_HALF_DUPLEX 0x00100000 /* only half duplex */
#define SNDRV_PCM_INFO_JOINT_DUPLEX 0x00200000 /* playback and capture stream are somewhat correlated */
#define SNDRV_PCM_INFO_SYNC_START 0x00400000 /* pcm support some kind of sync go */
#define SNDRV_PCM_INFO_FIFO_IN_FRAMES 0x80000000 /* internal kernel flag - FIFO size is in frames */
typedef int __bitwise snd_pcm_state_t;
#define SNDRV_PCM_STATE_OPEN ((__force snd_pcm_state_t) 0) /* stream is open */
......
......@@ -300,19 +300,10 @@ int snd_card_create(int idx, const char *id,
struct module *module, int extra_size,
struct snd_card **card_ret);
static inline __deprecated
struct snd_card *snd_card_new(int idx, const char *id,
struct module *module, int extra_size)
{
struct snd_card *card;
if (snd_card_create(idx, id, module, extra_size, &card) < 0)
return NULL;
return card;
}
int snd_card_disconnect(struct snd_card *card);
int snd_card_free(struct snd_card *card);
int snd_card_free_when_closed(struct snd_card *card);
void snd_card_set_id(struct snd_card *card, const char *id);
int snd_card_register(struct snd_card *card);
int snd_card_info_init(void);
int snd_card_info_done(void);
......
#warning "This file is deprecated"
......@@ -98,6 +98,7 @@ struct snd_pcm_ops {
#define SNDRV_PCM_IOCTL1_INFO 1
#define SNDRV_PCM_IOCTL1_CHANNEL_INFO 2
#define SNDRV_PCM_IOCTL1_GSTATE 3
#define SNDRV_PCM_IOCTL1_FIFO_SIZE 4
#define SNDRV_PCM_TRIGGER_STOP 0
#define SNDRV_PCM_TRIGGER_START 1
......@@ -270,6 +271,7 @@ struct snd_pcm_runtime {
snd_pcm_uframes_t hw_ptr_base; /* Position at buffer restart */
snd_pcm_uframes_t hw_ptr_interrupt; /* Position at interrupt time */
unsigned long hw_ptr_jiffies; /* Time when hw_ptr is updated */
snd_pcm_sframes_t delay; /* extra delay; typically FIFO size */
/* -- HW params -- */
snd_pcm_access_t access; /* access mode */
......@@ -486,80 +488,6 @@ void snd_pcm_detach_substream(struct snd_pcm_substream *substream);
void snd_pcm_vma_notify_data(void *client, void *data);
int snd_pcm_mmap_data(struct snd_pcm_substream *substream, struct file *file, struct vm_area_struct *area);
#if BITS_PER_LONG >= 64
static inline void div64_32(u_int64_t *n, u_int32_t div, u_int32_t *rem)
{
*rem = *n % div;
*n /= div;
}
#elif defined(i386)
static inline void div64_32(u_int64_t *n, u_int32_t div, u_int32_t *rem)
{
u_int32_t low, high;
low = *n & 0xffffffff;
high = *n >> 32;
if (high) {
u_int32_t high1 = high % div;
high /= div;
asm("divl %2":"=a" (low), "=d" (*rem):"rm" (div), "a" (low), "d" (high1));
*n = (u_int64_t)high << 32 | low;
} else {
*n = low / div;
*rem = low % div;
}
}
#else
static inline void divl(u_int32_t high, u_int32_t low,
u_int32_t div,
u_int32_t *q, u_int32_t *r)
{
u_int64_t n = (u_int64_t)high << 32 | low;
u_int64_t d = (u_int64_t)div << 31;
u_int32_t q1 = 0;
int c = 32;
while (n > 0xffffffffU) {
q1 <<= 1;
if (n >= d) {
n -= d;
q1 |= 1;
}
d >>= 1;
c--;
}
q1 <<= c;
if (n) {
low = n;
*q = q1 | (low / div);
*r = low % div;
} else {
*r = 0;
*q = q1;
}
return;
}
static inline void div64_32(u_int64_t *n, u_int32_t div, u_int32_t *rem)
{
u_int32_t low, high;
low = *n & 0xffffffff;
high = *n >> 32;
if (high) {
u_int32_t high1 = high % div;
u_int32_t low1 = low;
high /= div;
divl(high1, low1, div, &low, rem);
*n = (u_int64_t)high << 32 | low;
} else {
*n = low / div;
*rem = low % div;
}
}
#endif
/*
* PCM library
*/
......
......@@ -44,24 +44,6 @@ struct snd_pcm_substream;
#define SND_SOC_DAIFMT_CONT (0 << 4) /* continuous clock */
#define SND_SOC_DAIFMT_GATED (1 << 4) /* clock is gated */
/*
* DAI Left/Right Clocks.
*
* Specifies whether the DAI can support different samples for similtanious
* playback and capture. This usually requires a seperate physical frame
* clock for playback and capture.
*/
#define SND_SOC_DAIFMT_SYNC (0 << 5) /* Tx FRM = Rx FRM */
#define SND_SOC_DAIFMT_ASYNC (1 << 5) /* Tx FRM ~ Rx FRM */
/*
* TDM
*
* Time Division Multiplexing. Allows PCM data to be multplexed with other
* data on the DAI.
*/
#define SND_SOC_DAIFMT_TDM (1 << 6)
/*
* DAI hardware signal inversions.
*
......@@ -96,6 +78,10 @@ struct snd_pcm_substream;
#define SND_SOC_CLOCK_IN 0
#define SND_SOC_CLOCK_OUT 1
#define SND_SOC_STD_AC97_FMTS (SNDRV_PCM_FMTBIT_S16_LE |\
SNDRV_PCM_FMTBIT_S32_LE |\
SNDRV_PCM_FMTBIT_S32_BE)
struct snd_soc_dai_ops;
struct snd_soc_dai;
struct snd_ac97_bus_ops;
......@@ -208,6 +194,7 @@ struct snd_soc_dai {
/* DAI capabilities */
struct snd_soc_pcm_stream capture;
struct snd_soc_pcm_stream playback;
unsigned int symmetric_rates:1;
/* DAI runtime info */
struct snd_pcm_runtime *runtime;
......@@ -219,11 +206,8 @@ struct snd_soc_dai {
/* DAI private data */
void *private_data;
/* parent codec/platform */
union {
struct snd_soc_codec *codec;
struct snd_soc_platform *platform;
};
/* parent platform */
struct snd_soc_platform *platform;
struct list_head list;
};
......
......@@ -140,16 +140,30 @@
#define SND_SOC_DAPM_DAC(wname, stname, wreg, wshift, winvert) \
{ .id = snd_soc_dapm_dac, .name = wname, .sname = stname, .reg = wreg, \
.shift = wshift, .invert = winvert}
#define SND_SOC_DAPM_DAC_E(wname, stname, wreg, wshift, winvert, \
wevent, wflags) \
{ .id = snd_soc_dapm_dac, .name = wname, .sname = stname, .reg = wreg, \
.shift = wshift, .invert = winvert, \
.event = wevent, .event_flags = wflags}
#define SND_SOC_DAPM_ADC(wname, stname, wreg, wshift, winvert) \
{ .id = snd_soc_dapm_adc, .name = wname, .sname = stname, .reg = wreg, \
.shift = wshift, .invert = winvert}
#define SND_SOC_DAPM_ADC_E(wname, stname, wreg, wshift, winvert, \
wevent, wflags) \
{ .id = snd_soc_dapm_adc, .name = wname, .sname = stname, .reg = wreg, \
.shift = wshift, .invert = winvert, \
.event = wevent, .event_flags = wflags}
/* generic register modifier widget */
/* generic widgets */
#define SND_SOC_DAPM_REG(wid, wname, wreg, wshift, wmask, won_val, woff_val) \
{ .id = wid, .name = wname, .kcontrols = NULL, .num_kcontrols = 0, \
.reg = -((wreg) + 1), .shift = wshift, .mask = wmask, \
.on_val = won_val, .off_val = woff_val, .event = dapm_reg_event, \
.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD}
#define SND_SOC_DAPM_SUPPLY(wname, wreg, wshift, winvert, wevent, wflags) \
{ .id = snd_soc_dapm_supply, .name = wname, .reg = wreg, \
.shift = wshift, .invert = winvert, .event = wevent, \
.event_flags = wflags}
/* dapm kcontrol types */
#define SOC_DAPM_SINGLE(xname, reg, shift, max, invert) \
......@@ -265,8 +279,6 @@ int snd_soc_dapm_add_routes(struct snd_soc_codec *codec,
/* dapm events */
int snd_soc_dapm_stream_event(struct snd_soc_codec *codec, char *stream,
int event);
int snd_soc_dapm_set_bias_level(struct snd_soc_device *socdev,
enum snd_soc_bias_level level);
/* dapm sys fs - used by the core */
int snd_soc_dapm_sys_add(struct device *dev);
......@@ -298,6 +310,7 @@ enum snd_soc_dapm_type {
snd_soc_dapm_vmid, /* codec bias/vmid - to minimise pops */
snd_soc_dapm_pre, /* machine specific pre widget - exec first */
snd_soc_dapm_post, /* machine specific post widget - exec last */
snd_soc_dapm_supply, /* power/clock supply */
};
/*
......@@ -357,6 +370,8 @@ struct snd_soc_dapm_widget {
unsigned char suspend:1; /* was active before suspend */
unsigned char pmdown:1; /* waiting for timeout */
int (*power_check)(struct snd_soc_dapm_widget *w);
/* external events */
unsigned short event_flags; /* flags to specify event types */
int (*event)(struct snd_soc_dapm_widget*, struct snd_kcontrol *, int);
......@@ -368,6 +383,9 @@ struct snd_soc_dapm_widget {
/* widget input and outputs */
struct list_head sources;
struct list_head sinks;
/* used during DAPM updates */
struct list_head power_list;
};
#endif
......@@ -118,6 +118,14 @@
.info = snd_soc_info_volsw, \
.get = xhandler_get, .put = xhandler_put, \
.private_value = SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) }
#define SOC_DOUBLE_EXT(xname, xreg, shift_left, shift_right, 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 = (unsigned long)&(struct soc_mixer_control) \
{.reg = xreg, .shift = shift_left, .rshift = shift_right, \
.max = xmax, .invert = 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, \
......@@ -206,10 +214,6 @@ void snd_soc_jack_free_gpios(struct snd_soc_jack *jack, int count,
struct snd_soc_jack_gpio *gpios);
#endif
/* codec IO */
#define snd_soc_read(codec, reg) codec->read(codec, reg)
#define snd_soc_write(codec, reg, value) codec->write(codec, reg, value)
/* codec register bit access */
int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg,
unsigned short mask, unsigned short value);
......@@ -331,6 +335,7 @@ struct snd_soc_codec {
struct module *owner;
struct mutex mutex;
struct device *dev;
struct snd_soc_device *socdev;
struct list_head list;
......@@ -364,6 +369,8 @@ struct snd_soc_codec {
enum snd_soc_bias_level bias_level;
enum snd_soc_bias_level suspend_bias_level;
struct delayed_work delayed_work;
struct list_head up_list;
struct list_head down_list;
/* codec DAI's */
struct snd_soc_dai *dai;
......@@ -417,6 +424,12 @@ struct snd_soc_dai_link {
/* codec/machine specific init - e.g. add machine controls */
int (*init)(struct snd_soc_codec *codec);
/* Symmetry requirements */
unsigned int symmetric_rates:1;
/* Symmetry data - only valid if symmetry is being enforced */
unsigned int rate;
/* DAI pcm */
struct snd_pcm *pcm;
};
......@@ -490,6 +503,19 @@ struct soc_enum {
void *dapm;
};
/* codec IO */
static inline unsigned int snd_soc_read(struct snd_soc_codec *codec,
unsigned int reg)
{
return codec->read(codec, reg);
}
static inline unsigned int snd_soc_write(struct snd_soc_codec *codec,
unsigned int reg, unsigned int val)
{
return codec->write(codec, reg, val);
}
#include <sound/soc-dai.h>
#endif
/*
* linux/sound/wm9081.h -- Platform data for WM9081
*
* Copyright 2009 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 version 2 as
* published by the Free Software Foundation.
*/
#ifndef __LINUX_SND_WM_9081_H
#define __LINUX_SND_WM_9081_H
struct wm9081_retune_mobile_setting {
const char *name;
unsigned int rate;
u16 config[20];
};
struct wm9081_retune_mobile_config {
struct wm9081_retune_mobile_setting *configs;
int num_configs;
};
#endif
......@@ -1037,7 +1037,7 @@ static int aoa_fabric_layout_probe(struct soundbus_dev *sdev)
}
ldev->selfptr_headphone.ptr = ldev;
ldev->selfptr_lineout.ptr = ldev;
sdev->ofdev.dev.driver_data = ldev;
dev_set_drvdata(&sdev->ofdev.dev, ldev);
list_add(&ldev->list, &layouts_list);
layouts_list_items++;
......@@ -1081,7 +1081,7 @@ static int aoa_fabric_layout_probe(struct soundbus_dev *sdev)
static int aoa_fabric_layout_remove(struct soundbus_dev *sdev)
{
struct layout_dev *ldev = sdev->ofdev.dev.driver_data;
struct layout_dev *ldev = dev_get_drvdata(&sdev->ofdev.dev);
int i;
for (i=0; i<MAX_CODECS_PER_BUS; i++) {
......@@ -1114,7 +1114,7 @@ static int aoa_fabric_layout_remove(struct soundbus_dev *sdev)
#ifdef CONFIG_PM
static int aoa_fabric_layout_suspend(struct soundbus_dev *sdev, pm_message_t state)
{
struct layout_dev *ldev = sdev->ofdev.dev.driver_data;
struct layout_dev *ldev = dev_get_drvdata(&sdev->ofdev.dev);
if (ldev->gpio.methods && ldev->gpio.methods->all_amps_off)
ldev->gpio.methods->all_amps_off(&ldev->gpio);
......@@ -1124,7 +1124,7 @@ static int aoa_fabric_layout_suspend(struct soundbus_dev *sdev, pm_message_t sta
static int aoa_fabric_layout_resume(struct soundbus_dev *sdev)
{
struct layout_dev *ldev = sdev->ofdev.dev.driver_data;
struct layout_dev *ldev = dev_get_drvdata(&sdev->ofdev.dev);
if (ldev->gpio.methods && ldev->gpio.methods->all_amps_off)
ldev->gpio.methods->all_amps_restore(&ldev->gpio);
......
......@@ -358,14 +358,14 @@ static int i2sbus_probe(struct macio_dev* dev, const struct of_device_id *match)
return -ENODEV;
}
dev->ofdev.dev.driver_data = control;
dev_set_drvdata(&dev->ofdev.dev, control);
return 0;
}
static int i2sbus_remove(struct macio_dev* dev)
{
struct i2sbus_control *control = dev->ofdev.dev.driver_data;
struct i2sbus_control *control = dev_get_drvdata(&dev->ofdev.dev);
struct i2sbus_dev *i2sdev, *tmp;
list_for_each_entry_safe(i2sdev, tmp, &control->list, item)
......@@ -377,7 +377,7 @@ static int i2sbus_remove(struct macio_dev* dev)
#ifdef CONFIG_PM
static int i2sbus_suspend(struct macio_dev* dev, pm_message_t state)
{
struct i2sbus_control *control = dev->ofdev.dev.driver_data;
struct i2sbus_control *control = dev_get_drvdata(&dev->ofdev.dev);
struct codec_info_item *cii;
struct i2sbus_dev* i2sdev;
int err, ret = 0;
......@@ -407,7 +407,7 @@ static int i2sbus_suspend(struct macio_dev* dev, pm_message_t state)
static int i2sbus_resume(struct macio_dev* dev)
{
struct i2sbus_control *control = dev->ofdev.dev.driver_data;
struct i2sbus_control *control = dev_get_drvdata(&dev->ofdev.dev);
struct codec_info_item *cii;
struct i2sbus_dev* i2sdev;
int err, ret = 0;
......
......@@ -205,3 +205,5 @@ config SND_PCM_XRUN_DEBUG
config SND_VMASTER
bool
source "sound/core/seq/Kconfig"
......@@ -152,15 +152,8 @@ int snd_card_create(int idx, const char *xid,
card = kzalloc(sizeof(*card) + extra_size, GFP_KERNEL);
if (!card)
return -ENOMEM;
if (xid) {
if (!snd_info_check_reserved_words(xid)) {
snd_printk(KERN_ERR
"given id string '%s' is reserved.\n", xid);
err = -EBUSY;
goto __error;
}
if (xid)
strlcpy(card->id, xid, sizeof(card->id));
}
err = 0;
mutex_lock(&snd_card_mutex);
if (idx < 0) {
......@@ -483,22 +476,28 @@ int snd_card_free(struct snd_card *card)
EXPORT_SYMBOL(snd_card_free);
static void choose_default_id(struct snd_card *card)
static void snd_card_set_id_no_lock(struct snd_card *card, const char *nid)
{
int i, len, idx_flag = 0, loops = SNDRV_CARDS;
char *id, *spos;
const char *spos, *src;
char *id;
id = spos = card->shortname;
while (*id != '\0') {
if (*id == ' ')
spos = id + 1;
id++;
if (nid == NULL) {
id = card->shortname;
spos = src = id;
while (*id != '\0') {
if (*id == ' ')
spos = id + 1;
id++;
}
} else {
spos = src = nid;
}
id = card->id;
while (*spos != '\0' && !isalnum(*spos))
spos++;
if (isdigit(*spos))
*id++ = isalpha(card->shortname[0]) ? card->shortname[0] : 'D';
*id++ = isalpha(src[0]) ? src[0] : 'D';
while (*spos != '\0' && (size_t)(id - card->id) < sizeof(card->id) - 1) {
if (isalnum(*spos))
*id++ = *spos;
......@@ -513,7 +512,7 @@ static void choose_default_id(struct snd_card *card)
while (1) {
if (loops-- == 0) {
snd_printk(KERN_ERR "unable to choose default card id (%s)\n", id);
snd_printk(KERN_ERR "unable to set card id (%s)\n", id);
strcpy(card->id, card->proc_root->name);
return;
}
......@@ -539,14 +538,33 @@ static void choose_default_id(struct snd_card *card)
spos = id + len - 2;
if ((size_t)len <= sizeof(card->id) - 2)
spos++;
*spos++ = '_';
*spos++ = '1';
*spos++ = '\0';
*(char *)spos++ = '_';
*(char *)spos++ = '1';
*(char *)spos++ = '\0';
idx_flag++;
}
}
}
/**
* snd_card_set_id - set card identification name
* @card: soundcard structure
* @nid: new identification string
*
* This function sets the card identification and checks for name
* collisions.
*/
void snd_card_set_id(struct snd_card *card, const char *nid)
{
/* check if user specified own card->id */
if (card->id[0] != '\0')
return;
mutex_lock(&snd_card_mutex);
snd_card_set_id_no_lock(card, nid);
mutex_unlock(&snd_card_mutex);
}
EXPORT_SYMBOL(snd_card_set_id);
#ifndef CONFIG_SYSFS_DEPRECATED
static ssize_t
card_id_show_attr(struct device *dev,
......@@ -640,8 +658,7 @@ int snd_card_register(struct snd_card *card)
mutex_unlock(&snd_card_mutex);
return 0;
}
if (card->id[0] == '\0')
choose_default_id(card);
snd_card_set_id_no_lock(card, card->id[0] == '\0' ? NULL : card->id);
snd_cards[card->number] = card;
mutex_unlock(&snd_card_mutex);
init_info_for_card(card);
......
......@@ -63,7 +63,7 @@ static int snd_jack_dev_register(struct snd_device *device)
/* Default to the sound card device. */
if (!jack->input_dev->dev.parent)
jack->input_dev->dev.parent = card->dev;
jack->input_dev->dev.parent = snd_card_get_device_link(card);
err = input_register_device(jack->input_dev);
if (err == 0)
......
......@@ -31,6 +31,7 @@
#include <linux/time.h>
#include <linux/vmalloc.h>
#include <linux/moduleparam.h>
#include <linux/math64.h>
#include <linux/string.h>
#include <sound/core.h>
#include <sound/minors.h>
......@@ -617,9 +618,7 @@ static long snd_pcm_oss_bytes(struct snd_pcm_substream *substream, long frames)
#else
{
u64 bsize = (u64)runtime->oss.buffer_bytes * (u64)bytes;
u32 rem;
div64_32(&bsize, buffer_size, &rem);
return (long)bsize;
return div_u64(bsize, buffer_size);
}
#endif
}
......
......@@ -22,6 +22,7 @@
#include <linux/slab.h>
#include <linux/time.h>
#include <linux/math64.h>
#include <sound/core.h>
#include <sound/control.h>
#include <sound/info.h>
......@@ -126,24 +127,37 @@ void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_ufram
}
#ifdef CONFIG_SND_PCM_XRUN_DEBUG
#define xrun_debug(substream) ((substream)->pstr->xrun_debug)
#define xrun_debug(substream, mask) ((substream)->pstr->xrun_debug & (mask))
#else
#define xrun_debug(substream) 0
#define xrun_debug(substream, mask) 0
#endif
#define dump_stack_on_xrun(substream) do { \
if (xrun_debug(substream) > 1) \
dump_stack(); \
#define dump_stack_on_xrun(substream) do { \
if (xrun_debug(substream, 2)) \
dump_stack(); \
} while (0)
static void pcm_debug_name(struct snd_pcm_substream *substream,
char *name, size_t len)
{
snprintf(name, len, "pcmC%dD%d%c:%d",
substream->pcm->card->number,
substream->pcm->device,
substream->stream ? 'c' : 'p',
substream->number);
}
static void xrun(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE)
snd_pcm_gettime(runtime, (struct timespec *)&runtime->status->tstamp);
snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
if (xrun_debug(substream)) {
snd_printd(KERN_DEBUG "XRUN: pcmC%dD%d%c\n",
substream->pcm->card->number,
substream->pcm->device,
substream->stream ? 'c' : 'p');
if (xrun_debug(substream, 1)) {
char name[16];
pcm_debug_name(substream, name, sizeof(name));
snd_printd(KERN_DEBUG "XRUN: %s\n", name);
dump_stack_on_xrun(substream);
}
}
......@@ -154,16 +168,16 @@ snd_pcm_update_hw_ptr_pos(struct snd_pcm_substream *substream,
{
snd_pcm_uframes_t pos;
if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE)
snd_pcm_gettime(runtime, (struct timespec *)&runtime->status->tstamp);
pos = substream->ops->pointer(substream);
if (pos == SNDRV_PCM_POS_XRUN)
return pos; /* XRUN */
if (pos >= runtime->buffer_size) {
if (printk_ratelimit()) {
snd_printd(KERN_ERR "BUG: stream = %i, pos = 0x%lx, "
char name[16];
pcm_debug_name(substream, name, sizeof(name));
snd_printd(KERN_ERR "BUG: %s, pos = 0x%lx, "
"buffer size = 0x%lx, period size = 0x%lx\n",
substream->stream, pos, runtime->buffer_size,
name, pos, runtime->buffer_size,
runtime->period_size);
}
pos = 0;
......@@ -197,7 +211,7 @@ static int snd_pcm_update_hw_ptr_post(struct snd_pcm_substream *substream,
#define hw_ptr_error(substream, fmt, args...) \
do { \
if (xrun_debug(substream)) { \
if (xrun_debug(substream, 1)) { \
if (printk_ratelimit()) { \
snd_printd("PCM: " fmt, ##args); \
} \
......@@ -251,7 +265,7 @@ static int snd_pcm_update_hw_ptr_interrupt(struct snd_pcm_substream *substream)
}
/* Do jiffies check only in xrun_debug mode */
if (!xrun_debug(substream))
if (!xrun_debug(substream, 4))
goto no_jiffies_check;
/* Skip the jiffies check for hardwares with BATCH flag.
......@@ -261,6 +275,9 @@ static int snd_pcm_update_hw_ptr_interrupt(struct snd_pcm_substream *substream)
if (runtime->hw.info & SNDRV_PCM_INFO_BATCH)
goto no_jiffies_check;
hdelta = new_hw_ptr - old_hw_ptr;
if (hdelta < runtime->delay)
goto no_jiffies_check;
hdelta -= runtime->delay;
jdelta = jiffies - runtime->hw_ptr_jiffies;
if (((hdelta * HZ) / runtime->rate) > jdelta + HZ/100) {
delta = jdelta /
......@@ -294,14 +311,20 @@ static int snd_pcm_update_hw_ptr_interrupt(struct snd_pcm_substream *substream)
hw_ptr_interrupt =
new_hw_ptr - new_hw_ptr % runtime->period_size;
}
runtime->hw_ptr_interrupt = hw_ptr_interrupt;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
runtime->silence_size > 0)
snd_pcm_playback_silence(substream, new_hw_ptr);
if (runtime->status->hw_ptr == new_hw_ptr)
return 0;
runtime->hw_ptr_base = hw_base;
runtime->status->hw_ptr = new_hw_ptr;
runtime->hw_ptr_jiffies = jiffies;
runtime->hw_ptr_interrupt = hw_ptr_interrupt;
if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE)
snd_pcm_gettime(runtime, (struct timespec *)&runtime->status->tstamp);
return snd_pcm_update_hw_ptr_post(substream, runtime);
}
......@@ -342,8 +365,12 @@ int snd_pcm_update_hw_ptr(struct snd_pcm_substream *substream)
new_hw_ptr = hw_base + pos;
}
/* Do jiffies check only in xrun_debug mode */
if (xrun_debug(substream) &&
((delta * HZ) / runtime->rate) > jdelta + HZ/100) {
if (!xrun_debug(substream, 4))
goto no_jiffies_check;
if (delta < runtime->delay)
goto no_jiffies_check;
delta -= runtime->delay;
if (((delta * HZ) / runtime->rate) > jdelta + HZ/100) {
hw_ptr_error(substream,
"hw_ptr skipping! "
"(pos=%ld, delta=%ld, period=%ld, jdelta=%lu/%lu)\n",
......@@ -352,13 +379,19 @@ int snd_pcm_update_hw_ptr(struct snd_pcm_substream *substream)
((delta * HZ) / runtime->rate));
return 0;
}
no_jiffies_check:
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
runtime->silence_size > 0)
snd_pcm_playback_silence(substream, new_hw_ptr);
if (runtime->status->hw_ptr == new_hw_ptr)
return 0;
runtime->hw_ptr_base = hw_base;
runtime->status->hw_ptr = new_hw_ptr;
runtime->hw_ptr_jiffies = jiffies;
if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE)
snd_pcm_gettime(runtime, (struct timespec *)&runtime->status->tstamp);
return snd_pcm_update_hw_ptr_post(substream, runtime);
}
......@@ -452,7 +485,7 @@ static inline unsigned int muldiv32(unsigned int a, unsigned int b,
*r = 0;
return UINT_MAX;
}
div64_32(&n, c, r);
n = div_u64_rem(n, c, r);
if (n >= UINT_MAX) {
*r = 0;
return UINT_MAX;
......@@ -1524,6 +1557,23 @@ static int snd_pcm_lib_ioctl_channel_info(struct snd_pcm_substream *substream,
return 0;
}
static int snd_pcm_lib_ioctl_fifo_size(struct snd_pcm_substream *substream,
void *arg)
{
struct snd_pcm_hw_params *params = arg;
snd_pcm_format_t format;
int channels, width;
params->fifo_size = substream->runtime->hw.fifo_size;
if (!(substream->runtime->hw.info & SNDRV_PCM_INFO_FIFO_IN_FRAMES)) {
format = params_format(params);
channels = params_channels(params);
width = snd_pcm_format_physical_width(format);
params->fifo_size /= width * channels;
}
return 0;
}
/**
* snd_pcm_lib_ioctl - a generic PCM ioctl callback
* @substream: the pcm substream instance
......@@ -1545,6 +1595,8 @@ int snd_pcm_lib_ioctl(struct snd_pcm_substream *substream,
return snd_pcm_lib_ioctl_reset(substream, arg);
case SNDRV_PCM_IOCTL1_CHANNEL_INFO:
return snd_pcm_lib_ioctl_channel_info(substream, arg);
case SNDRV_PCM_IOCTL1_FIFO_SIZE:
return snd_pcm_lib_ioctl_fifo_size(substream, arg);
}
return -ENXIO;
}
......
......@@ -312,9 +312,18 @@ int snd_pcm_hw_refine(struct snd_pcm_substream *substream,
hw = &substream->runtime->hw;
if (!params->info)
params->info = hw->info;
if (!params->fifo_size)
params->fifo_size = hw->fifo_size;
params->info = hw->info & ~SNDRV_PCM_INFO_FIFO_IN_FRAMES;
if (!params->fifo_size) {
if (snd_mask_min(&params->masks[SNDRV_PCM_HW_PARAM_FORMAT]) ==
snd_mask_max(&params->masks[SNDRV_PCM_HW_PARAM_FORMAT]) &&
snd_mask_min(&params->masks[SNDRV_PCM_HW_PARAM_CHANNELS]) ==
snd_mask_max(&params->masks[SNDRV_PCM_HW_PARAM_CHANNELS])) {
changed = substream->ops->ioctl(substream,
SNDRV_PCM_IOCTL1_FIFO_SIZE, params);
if (params < 0)
return changed;
}
}
params->rmask = 0;
return 0;
}
......@@ -587,14 +596,15 @@ int snd_pcm_status(struct snd_pcm_substream *substream,
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
status->avail = snd_pcm_playback_avail(runtime);
if (runtime->status->state == SNDRV_PCM_STATE_RUNNING ||
runtime->status->state == SNDRV_PCM_STATE_DRAINING)
runtime->status->state == SNDRV_PCM_STATE_DRAINING) {
status->delay = runtime->buffer_size - status->avail;
else
status->delay += runtime->delay;
} else
status->delay = 0;
} else {
status->avail = snd_pcm_capture_avail(runtime);
if (runtime->status->state == SNDRV_PCM_STATE_RUNNING)
status->delay = status->avail;
status->delay = status->avail + runtime->delay;
else
status->delay = 0;
}
......@@ -2410,6 +2420,7 @@ static int snd_pcm_delay(struct snd_pcm_substream *substream,
n = snd_pcm_playback_hw_avail(runtime);
else
n = snd_pcm_capture_avail(runtime);
n += runtime->delay;
break;
case SNDRV_PCM_STATE_XRUN:
err = -EPIPE;
......
# define SND_XXX_SEQ to min(SND_SEQUENCER,SND_XXX)
config SND_RAWMIDI_SEQ
def_tristate SND_SEQUENCER && SND_RAWMIDI
config SND_OPL3_LIB_SEQ
def_tristate SND_SEQUENCER && SND_OPL3_LIB
config SND_OPL4_LIB_SEQ
def_tristate SND_SEQUENCER && SND_OPL4_LIB
config SND_SBAWE_SEQ
def_tristate SND_SEQUENCER && SND_SBAWE
config SND_EMU10K1_SEQ
def_tristate SND_SEQUENCER && SND_EMU10K1
......@@ -17,14 +17,6 @@ snd-seq-midi-event-objs := seq_midi_event.o
snd-seq-dummy-objs := seq_dummy.o
snd-seq-virmidi-objs := seq_virmidi.o
#
# this function returns:
# "m" - CONFIG_SND_SEQUENCER is m
# <empty string> - CONFIG_SND_SEQUENCER is undefined
# otherwise parameter #1 value
#
sequencer = $(if $(subst y,,$(CONFIG_SND_SEQUENCER)),$(if $(1),m),$(if $(CONFIG_SND_SEQUENCER),$(1)))
obj-$(CONFIG_SND_SEQUENCER) += snd-seq.o snd-seq-device.o
ifeq ($(CONFIG_SND_SEQUENCER_OSS),y)
obj-$(CONFIG_SND_SEQUENCER) += snd-seq-midi-event.o
......@@ -33,8 +25,8 @@ obj-$(CONFIG_SND_SEQ_DUMMY) += snd-seq-dummy.o
# Toplevel Module Dependency
obj-$(CONFIG_SND_VIRMIDI) += snd-seq-virmidi.o snd-seq-midi-event.o
obj-$(call sequencer,$(CONFIG_SND_RAWMIDI)) += snd-seq-midi.o snd-seq-midi-event.o
obj-$(call sequencer,$(CONFIG_SND_OPL3_LIB)) += snd-seq-midi-event.o snd-seq-midi-emul.o
obj-$(call sequencer,$(CONFIG_SND_OPL4_LIB)) += snd-seq-midi-event.o snd-seq-midi-emul.o
obj-$(call sequencer,$(CONFIG_SND_SBAWE)) += snd-seq-midi-emul.o snd-seq-virmidi.o
obj-$(call sequencer,$(CONFIG_SND_EMU10K1)) += snd-seq-midi-emul.o snd-seq-virmidi.o
obj-$(CONFIG_SND_RAWMIDI_SEQ) += snd-seq-midi.o snd-seq-midi-event.o
obj-$(CONFIG_SND_OPL3_LIB_SEQ) += snd-seq-midi-event.o snd-seq-midi-emul.o
obj-$(CONFIG_SND_OPL4_LIB_SEQ) += snd-seq-midi-event.o snd-seq-midi-emul.o
obj-$(CONFIG_SND_SBAWE_SEQ) += snd-seq-midi-emul.o snd-seq-virmidi.o
obj-$(CONFIG_SND_EMU10K1_SEQ) += snd-seq-midi-emul.o snd-seq-virmidi.o
......@@ -7,14 +7,6 @@ snd-opl3-lib-objs := opl3_lib.o opl3_synth.o
snd-opl3-synth-y := opl3_seq.o opl3_midi.o opl3_drums.o
snd-opl3-synth-$(CONFIG_SND_SEQUENCER_OSS) += opl3_oss.o
#
# this function returns:
# "m" - CONFIG_SND_SEQUENCER is m
# <empty string> - CONFIG_SND_SEQUENCER is undefined
# otherwise parameter #1 value
#
sequencer = $(if $(subst y,,$(CONFIG_SND_SEQUENCER)),$(if $(1),m),$(if $(CONFIG_SND_SEQUENCER),$(1)))
obj-$(CONFIG_SND_OPL3_LIB) += snd-opl3-lib.o
obj-$(CONFIG_SND_OPL4_LIB) += snd-opl3-lib.o
obj-$(call sequencer,$(CONFIG_SND_OPL3_LIB)) += snd-opl3-synth.o
obj-$(CONFIG_SND_OPL3_LIB_SEQ) += snd-opl3-synth.o
......@@ -6,13 +6,5 @@
snd-opl4-lib-objs := opl4_lib.o opl4_mixer.o opl4_proc.o
snd-opl4-synth-objs := opl4_seq.o opl4_synth.o yrw801.o
#
# this function returns:
# "m" - CONFIG_SND_SEQUENCER is m
# <empty string> - CONFIG_SND_SEQUENCER is undefined
# otherwise parameter #1 value
#
sequencer = $(if $(subst y,,$(CONFIG_SND_SEQUENCER)),$(if $(1),m),$(if $(CONFIG_SND_SEQUENCER),$(1)))
obj-$(CONFIG_SND_OPL4_LIB) += snd-opl4-lib.o
obj-$(call sequencer,$(CONFIG_SND_OPL4_LIB)) += snd-opl4-synth.o
obj-$(CONFIG_SND_OPL4_LIB_SEQ) += snd-opl4-synth.o
......@@ -177,15 +177,18 @@ config SND_ES18XX
will be called snd-es18xx.
config SND_SC6000
tristate "Gallant SC-6000, Audio Excel DSP 16"
tristate "Gallant SC-6000/6600/7000 and Audio Excel DSP 16"
depends on HAS_IOPORT
select SND_WSS_LIB
select SND_OPL3_LIB
select SND_MPU401_UART
help
Say Y here to include support for Gallant SC-6000 card and clones:
Say Y here to include support for Gallant SC-6000, SC-6600, SC-7000
cards and clones:
Audio Excel DSP 16 and Zoltrix AV302.
These cards are based on CompuMedia ASC-9308 or ASC-9408 chips.
To compile this driver as a module, choose M here: the module
will be called snd-sc6000.
......
......@@ -193,7 +193,7 @@ static int __devexit snd_es1688_remove(struct device *dev, unsigned int n)
static struct isa_driver snd_es1688_driver = {
.match = snd_es1688_match,
.probe = snd_es1688_probe,
.remove = snd_es1688_remove,
.remove = __devexit_p(snd_es1688_remove),
#if 0 /* FIXME */
.suspend = snd_es1688_suspend,
.resume = snd_es1688_resume,
......
......@@ -348,7 +348,7 @@ static int __devexit snd_gusextreme_remove(struct device *dev, unsigned int n)
static struct isa_driver snd_gusextreme_driver = {
.match = snd_gusextreme_match,
.probe = snd_gusextreme_probe,
.remove = snd_gusextreme_remove,
.remove = __devexit_p(snd_gusextreme_remove),
#if 0 /* FIXME */
.suspend = snd_gusextreme_suspend,
.resume = snd_gusextreme_resume,
......
......@@ -13,14 +13,6 @@ snd-sbawe-objs := sbawe.o emu8000.o
snd-emu8000-synth-objs := emu8000_synth.o emu8000_callback.o emu8000_patch.o emu8000_pcm.o
snd-es968-objs := es968.o
#
# this function returns:
# "m" - CONFIG_SND_SEQUENCER is m
# <empty string> - CONFIG_SND_SEQUENCER is undefined
# otherwise parameter #1 value
#
sequencer = $(if $(subst y,,$(CONFIG_SND_SEQUENCER)),$(if $(1),m),$(if $(CONFIG_SND_SEQUENCER),$(1)))
# Toplevel Module Dependency
obj-$(CONFIG_SND_SB_COMMON) += snd-sb-common.o
obj-$(CONFIG_SND_SB16_DSP) += snd-sb16-dsp.o
......@@ -33,4 +25,4 @@ ifeq ($(CONFIG_SND_SB16_CSP),y)
obj-$(CONFIG_SND_SB16) += snd-sb16-csp.o
obj-$(CONFIG_SND_SBAWE) += snd-sb16-csp.o
endif
obj-$(call sequencer,$(CONFIG_SND_SBAWE)) += snd-emu8000-synth.o
obj-$(CONFIG_SND_SBAWE_SEQ) += snd-emu8000-synth.o
......@@ -2,6 +2,8 @@
* Driver for Gallant SC-6000 soundcard. This card is also known as
* Audio Excel DSP 16 or Zoltrix AV302.
* These cards use CompuMedia ASC-9308 chip + AD1848 codec.
* SC-6600 and SC-7000 cards are also supported. They are based on
* CompuMedia ASC-9408 chip and CS4231 codec.
*
* Copyright (C) 2007 Krzysztof Helt <krzysztof.h1@wp.pl>
*
......@@ -54,6 +56,7 @@ static long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
/* 0x300, 0x310, 0x320, 0x330 */
static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 5, 7, 9, 10, 0 */
static int dma[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0, 1, 3 */
static bool joystick[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = false };
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for sc-6000 based soundcard.");
......@@ -73,6 +76,8 @@ module_param_array(mpu_irq, int, NULL, 0444);
MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for sc-6000 driver.");
module_param_array(dma, int, NULL, 0444);
MODULE_PARM_DESC(dma, "DMA # for sc-6000 driver.");
module_param_array(joystick, bool, NULL, 0444);
MODULE_PARM_DESC(joystick, "Enable gameport.");
/*
* Commands of SC6000's DSP (SBPRO+special).
......@@ -191,7 +196,7 @@ static __devinit unsigned char sc6000_mpu_irq_to_softcfg(int mpu_irq)
return val;
}
static __devinit int sc6000_wait_data(char __iomem *vport)
static int sc6000_wait_data(char __iomem *vport)
{
int loop = 1000;
unsigned char val = 0;
......@@ -206,7 +211,7 @@ static __devinit int sc6000_wait_data(char __iomem *vport)
return -EAGAIN;
}
static __devinit int sc6000_read(char __iomem *vport)
static int sc6000_read(char __iomem *vport)
{
if (sc6000_wait_data(vport))
return -EBUSY;
......@@ -215,7 +220,7 @@ static __devinit int sc6000_read(char __iomem *vport)
}
static __devinit int sc6000_write(char __iomem *vport, int cmd)
static int sc6000_write(char __iomem *vport, int cmd)
{
unsigned char val;
int loop = 500000;
......@@ -276,8 +281,33 @@ static int __devinit sc6000_dsp_reset(char __iomem *vport)
}
/* detection and initialization */
static int __devinit sc6000_cfg_write(char __iomem *vport,
unsigned char softcfg)
static int __devinit sc6000_hw_cfg_write(char __iomem *vport, const int *cfg)
{
if (sc6000_write(vport, COMMAND_6C) < 0) {
snd_printk(KERN_WARNING "CMD 0x%x: failed!\n", COMMAND_6C);
return -EIO;
}
if (sc6000_write(vport, COMMAND_5C) < 0) {
snd_printk(KERN_ERR "CMD 0x%x: failed!\n", COMMAND_5C);
return -EIO;
}
if (sc6000_write(vport, cfg[0]) < 0) {
snd_printk(KERN_ERR "DATA 0x%x: failed!\n", cfg[0]);
return -EIO;
}
if (sc6000_write(vport, cfg[1]) < 0) {
snd_printk(KERN_ERR "DATA 0x%x: failed!\n", cfg[1]);
return -EIO;
}
if (sc6000_write(vport, COMMAND_C5) < 0) {
snd_printk(KERN_ERR "CMD 0x%x: failed!\n", COMMAND_C5);
return -EIO;
}
return 0;
}
static int sc6000_cfg_write(char __iomem *vport, unsigned char softcfg)
{
if (sc6000_write(vport, WRITE_MDIRQ_CFG)) {
......@@ -291,7 +321,7 @@ static int __devinit sc6000_cfg_write(char __iomem *vport,
return 0;
}
static int __devinit sc6000_setup_board(char __iomem *vport, int config)
static int sc6000_setup_board(char __iomem *vport, int config)
{
int loop = 10;
......@@ -334,16 +364,39 @@ static int __devinit sc6000_init_mss(char __iomem *vport, int config,
return 0;
}
static int __devinit sc6000_init_board(char __iomem *vport, int irq, int dma,
char __iomem *vmss_port, int mpu_irq)
static void __devinit sc6000_hw_cfg_encode(char __iomem *vport, int *cfg,
long xport, long xmpu,
long xmss_port, int joystick)
{
cfg[0] = 0;
cfg[1] = 0;
if (xport == 0x240)
cfg[0] |= 1;
if (xmpu != SNDRV_AUTO_PORT) {
cfg[0] |= (xmpu & 0x30) >> 2;
cfg[1] |= 0x20;
}
if (xmss_port == 0xe80)
cfg[0] |= 0x10;
cfg[0] |= 0x40; /* always set */
if (!joystick)
cfg[0] |= 0x02;
cfg[1] |= 0x80; /* enable WSS system */
cfg[1] &= ~0x40; /* disable IDE */
snd_printd("hw cfg %x, %x\n", cfg[0], cfg[1]);
}
static int __devinit sc6000_init_board(char __iomem *vport,
char __iomem *vmss_port, int dev)
{
char answer[15];
char version[2];
int mss_config = sc6000_irq_to_softcfg(irq) |
sc6000_dma_to_softcfg(dma);
int mss_config = sc6000_irq_to_softcfg(irq[dev]) |
sc6000_dma_to_softcfg(dma[dev]);
int config = mss_config |
sc6000_mpu_irq_to_softcfg(mpu_irq);
sc6000_mpu_irq_to_softcfg(mpu_irq[dev]);
int err;
int old = 0;
err = sc6000_dsp_reset(vport);
if (err < 0) {
......@@ -360,7 +413,6 @@ static int __devinit sc6000_init_board(char __iomem *vport, int irq, int dma,
/*
* My SC-6000 card return "SC-6000" in DSPCopyright, so
* if we have something different, we have to be warned.
* Mine returns "SC-6000A " - KH
*/
if (strncmp("SC-6000", answer, 7))
snd_printk(KERN_WARNING "Warning: non SC-6000 audio card!\n");
......@@ -372,13 +424,32 @@ static int __devinit sc6000_init_board(char __iomem *vport, int irq, int dma,
printk(KERN_INFO PFX "Detected model: %s, DSP version %d.%d\n",
answer, version[0], version[1]);
/*
* 0x0A == (IRQ 7, DMA 1, MIRQ 0)
*/
err = sc6000_cfg_write(vport, 0x0a);
/* set configuration */
sc6000_write(vport, COMMAND_5C);
if (sc6000_read(vport) < 0)
old = 1;
if (!old) {
int cfg[2];
sc6000_hw_cfg_encode(vport, &cfg[0], port[dev], mpu_port[dev],
mss_port[dev], joystick[dev]);
if (sc6000_hw_cfg_write(vport, cfg) < 0) {
snd_printk(KERN_ERR "sc6000_hw_cfg_write: failed!\n");
return -EIO;
}
}
err = sc6000_setup_board(vport, config);
if (err < 0) {
snd_printk(KERN_ERR "sc6000_cfg_write: failed!\n");
return -EFAULT;
snd_printk(KERN_ERR "sc6000_setup_board: failed!\n");
return -ENODEV;
}
sc6000_dsp_reset(vport);
if (!old) {
sc6000_write(vport, COMMAND_60);
sc6000_write(vport, 0x02);
sc6000_dsp_reset(vport);
}
err = sc6000_setup_board(vport, config);
......@@ -386,10 +457,9 @@ static int __devinit sc6000_init_board(char __iomem *vport, int irq, int dma,
snd_printk(KERN_ERR "sc6000_setup_board: failed!\n");
return -ENODEV;
}
err = sc6000_init_mss(vport, config, vmss_port, mss_config);
if (err < 0) {
snd_printk(KERN_ERR "Can not initialize "
snd_printk(KERN_ERR "Cannot initialize "
"Microsoft Sound System mode.\n");
return -ENODEV;
}
......@@ -485,14 +555,16 @@ static int __devinit snd_sc6000_probe(struct device *devptr, unsigned int dev)
struct snd_card *card;
struct snd_wss *chip;
struct snd_opl3 *opl3;
char __iomem *vport;
char __iomem **vport;
char __iomem *vmss_port;
err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
err = snd_card_create(index[dev], id[dev], THIS_MODULE, sizeof(vport),
&card);
if (err < 0)
return err;
vport = card->private_data;
if (xirq == SNDRV_AUTO_IRQ) {
xirq = snd_legacy_find_free_irq(possible_irqs);
if (xirq < 0) {
......@@ -517,8 +589,8 @@ static int __devinit snd_sc6000_probe(struct device *devptr, unsigned int dev)
err = -EBUSY;
goto err_exit;
}
vport = devm_ioport_map(devptr, port[dev], 0x10);
if (!vport) {
*vport = devm_ioport_map(devptr, port[dev], 0x10);
if (*vport == NULL) {
snd_printk(KERN_ERR PFX
"I/O port cannot be iomaped.\n");
err = -EBUSY;
......@@ -533,7 +605,7 @@ static int __devinit snd_sc6000_probe(struct device *devptr, unsigned int dev)
goto err_unmap1;
}
vmss_port = devm_ioport_map(devptr, mss_port[dev], 4);
if (!vport) {
if (!vmss_port) {
snd_printk(KERN_ERR PFX
"MSS port I/O cannot be iomaped.\n");
err = -EBUSY;
......@@ -544,7 +616,7 @@ static int __devinit snd_sc6000_probe(struct device *devptr, unsigned int dev)
port[dev], xirq, xdma,
mpu_irq[dev] == SNDRV_AUTO_IRQ ? 0 : mpu_irq[dev]);
err = sc6000_init_board(vport, xirq, xdma, vmss_port, mpu_irq[dev]);
err = sc6000_init_board(*vport, vmss_port, dev);
if (err < 0)
goto err_unmap2;
......@@ -552,7 +624,6 @@ static int __devinit snd_sc6000_probe(struct device *devptr, unsigned int dev)
WSS_HW_DETECT, 0, &chip);
if (err < 0)
goto err_unmap2;
card->private_data = chip;
err = snd_wss_pcm(chip, 0, NULL);
if (err < 0) {
......@@ -608,6 +679,7 @@ static int __devinit snd_sc6000_probe(struct device *devptr, unsigned int dev)
return 0;
err_unmap2:
sc6000_setup_board(*vport, 0);
release_region(mss_port[dev], 4);
err_unmap1:
release_region(port[dev], 0x10);
......@@ -618,11 +690,17 @@ static int __devinit snd_sc6000_probe(struct device *devptr, unsigned int dev)
static int __devexit snd_sc6000_remove(struct device *devptr, unsigned int dev)
{
struct snd_card *card = dev_get_drvdata(devptr);
char __iomem **vport = card->private_data;
if (sc6000_setup_board(*vport, 0) < 0)
snd_printk(KERN_WARNING "sc6000_setup_board failed on exit!\n");
release_region(port[dev], 0x10);
release_region(mss_port[dev], 4);
snd_card_free(dev_get_drvdata(devptr));
dev_set_drvdata(devptr, NULL);
snd_card_free(card);
return 0;
}
......
......@@ -619,8 +619,7 @@ static int snd_sgio2audio_pcm_hw_params(struct snd_pcm_substream *substream,
/* hw_free callback */
static int snd_sgio2audio_pcm_hw_free(struct snd_pcm_substream *substream)
{
if (substream->runtime->dma_area)
vfree(substream->runtime->dma_area);
vfree(substream->runtime->dma_area);
substream->runtime->dma_area = NULL;
return 0;
}
......
......@@ -935,7 +935,7 @@ snd_harmony_create(struct snd_card *card,
h->iobase = ioremap_nocache(padev->hpa.start, HARMONY_SIZE);
if (h->iobase == NULL) {
printk(KERN_ERR PFX "unable to remap hpa 0x%lx\n",
padev->hpa.start);
(unsigned long)padev->hpa.start);
err = -EBUSY;
goto free_and_ret;
}
......@@ -1020,7 +1020,7 @@ static struct parisc_driver snd_harmony_driver = {
.name = "harmony",
.id_table = snd_harmony_devtable,
.probe = snd_harmony_probe,
.remove = snd_harmony_remove,
.remove = __devexit_p(snd_harmony_remove),
};
static int __init
......
......@@ -275,6 +275,16 @@ config SND_CS5535AUDIO
To compile this driver as a module, choose M here: the module
will be called snd-cs5535audio.
config SND_CTXFI
tristate "Creative Sound Blaster X-Fi"
select SND_PCM
help
If you want to use soundcards based on Creative Sound Blastr X-Fi
boards with 20k1 or 20k2 chips, say Y here.
To compile this driver as a module, choose M here: the module
will be called snd-ctxfi.
config SND_DARLA20
tristate "(Echoaudio) Darla20"
select FW_LOADER
......@@ -532,6 +542,9 @@ config SND_HDSP
To compile this driver as a module, choose M here: the module
will be called snd-hdsp.
comment "Don't forget to add built-in firmwares for HDSP driver"
depends on SND_HDSP=y
config SND_HDSPM
tristate "RME Hammerfall DSP MADI"
select SND_HWDEP
......@@ -622,6 +635,16 @@ config SND_KORG1212
To compile this driver as a module, choose M here: the module
will be called snd-korg1212.
config SND_LX6464ES
tristate "Digigram LX6464ES"
select SND_PCM
help
Say Y here to include support for Digigram LX6464ES boards.
To compile this driver as a module, choose M here: the module
will be called snd-lx6464es.
config SND_MAESTRO3
tristate "ESS Allegro/Maestro3"
select SND_AC97_CODEC
......@@ -764,8 +787,8 @@ config SND_VIRTUOSO
select SND_OXYGEN_LIB
help
Say Y here to include support for sound cards based on the
Asus AV100/AV200 chips, i.e., Xonar D1, DX, D2, D2X, and
Essence STX.
Asus AV100/AV200 chips, i.e., Xonar D1, DX, D2, D2X,
Essence ST (Deluxe), and Essence STX.
Support for the HDAV1.3 (Deluxe) is very experimental.
To compile this driver as a module, choose M here: the module
......
......@@ -59,9 +59,11 @@ obj-$(CONFIG_SND) += \
ali5451/ \
au88x0/ \
aw2/ \
ctxfi/ \
ca0106/ \
cs46xx/ \
cs5535audio/ \
lx6464es/ \
echoaudio/ \
emu10k1/ \
hda/ \
......
......@@ -1255,8 +1255,8 @@ static int inline vortex_adbdma_getlinearpos(vortex_t * vortex, int adbdma)
int temp;
temp = hwread(vortex->mmio, VORTEX_ADBDMA_STAT + (adbdma << 2));
temp = (dma->period_virt * dma->period_bytes) + (temp & POS_MASK);
return (temp);
temp = (dma->period_virt * dma->period_bytes) + (temp & (dma->period_bytes - 1));
return temp;
}
static void vortex_adbdma_startfifo(vortex_t * vortex, int adbdma)
......@@ -1504,8 +1504,7 @@ static int inline vortex_wtdma_getlinearpos(vortex_t * vortex, int wtdma)
int temp;
temp = hwread(vortex->mmio, VORTEX_WTDMA_STAT + (wtdma << 2));
//temp = (temp & POS_MASK) + (((temp>>WT_SUBBUF_SHIFT) & WT_SUBBUF_MASK)*(dma->cfg0&POS_MASK));
temp = (temp & POS_MASK) + ((dma->period_virt) * (dma->period_bytes));
temp = (dma->period_virt * dma->period_bytes) + (temp & (dma->period_bytes - 1));
return temp;
}
......@@ -2441,7 +2440,8 @@ static irqreturn_t vortex_interrupt(int irq, void *dev_id)
spin_lock(&vortex->lock);
for (i = 0; i < NR_ADB; i++) {
if (vortex->dma_adb[i].fifo_status == FIFO_START) {
if (vortex_adbdma_bufshift(vortex, i)) ;
if (!vortex_adbdma_bufshift(vortex, i))
continue;
spin_unlock(&vortex->lock);
snd_pcm_period_elapsed(vortex->dma_adb[i].
substream);
......
......@@ -810,6 +810,8 @@ static struct pci_device_id snd_bt87x_ids[] = {
BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x107d, 0x6606, GENERIC),
/* Voodoo TV 200 */
BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x121a, 0x3000, GENERIC),
/* Askey Computer Corp. MagicTView'99 */
BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x144f, 0x3000, GENERIC),
/* AVerMedia Studio No. 103, 203, ...? */
BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1461, 0x0003, AVPHONE98),
/* Prolink PixelView PV-M4900 */
......
......@@ -1319,7 +1319,6 @@ static int __devinit snd_ca0106_pcm(struct snd_ca0106 *emu, int device)
}
pcm->info_flags = 0;
pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
strcpy(pcm->name, "CA0106");
for(substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
......
......@@ -739,7 +739,7 @@ static int __devinit rename_ctl(struct snd_card *card, const char *src, const ch
} while (0)
static __devinitdata
DECLARE_TLV_DB_SCALE(snd_ca0106_master_db_scale, -6375, 50, 1);
DECLARE_TLV_DB_SCALE(snd_ca0106_master_db_scale, -6375, 25, 1);
static char *slave_vols[] __devinitdata = {
"Analog Front Playback Volume",
......@@ -841,6 +841,9 @@ int __devinit snd_ca0106_mixer(struct snd_ca0106 *emu)
snd_ca0106_master_db_scale);
if (!vmaster)
return -ENOMEM;
err = snd_ctl_add(card, vmaster);
if (err < 0)
return err;
add_slaves(card, vmaster, slave_vols);
if (emu->details->spi_dac == 1) {
......@@ -848,8 +851,13 @@ int __devinit snd_ca0106_mixer(struct snd_ca0106 *emu)
NULL);
if (!vmaster)
return -ENOMEM;
err = snd_ctl_add(card, vmaster);
if (err < 0)
return err;
add_slaves(card, vmaster, slave_sws);
}
strcpy(card->mixername, "CA0106");
return 0;
}
......
snd-ctxfi-objs := xfi.o ctatc.o ctvmem.o ctpcm.o ctmixer.o ctresource.o \
ctsrc.o ctamixer.o ctdaio.o ctimap.o cthardware.o cttimer.o \
cthw20k2.o cthw20k1.o
obj-$(CONFIG_SND_CTXFI) += snd-ctxfi.o
This diff is collapsed.
/**
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
*
* This source file is released under GPL v2 license (no other versions).
* See the COPYING file included in the main directory of this source
* distribution for the license terms and conditions.
*/
#ifndef _20K2REGISTERS_H_
#define _20K2REGISTERS_H_
/* Timer Registers */
#define TIMER_TIMR 0x1B7004
#define INTERRUPT_GIP 0x1B7010
#define INTERRUPT_GIE 0x1B7014
/* I2C Registers */
#define I2C_IF_ADDRESS 0x1B9000
#define I2C_IF_WDATA 0x1B9004
#define I2C_IF_RDATA 0x1B9008
#define I2C_IF_STATUS 0x1B900C
#define I2C_IF_WLOCK 0x1B9010
/* Global Control Registers */
#define GLOBAL_CNTL_GCTL 0x1B7090
/* PLL Registers */
#define PLL_CTL 0x1B7080
#define PLL_STAT 0x1B7084
#define PLL_ENB 0x1B7088
/* SRC Registers */
#define SRC_CTL 0x1A0000 /* 0x1A0000 + (256 * Chn) */
#define SRC_CCR 0x1A0004 /* 0x1A0004 + (256 * Chn) */
#define SRC_IMAP 0x1A0008 /* 0x1A0008 + (256 * Chn) */
#define SRC_CA 0x1A0010 /* 0x1A0010 + (256 * Chn) */
#define SRC_CF 0x1A0014 /* 0x1A0014 + (256 * Chn) */
#define SRC_SA 0x1A0018 /* 0x1A0018 + (256 * Chn) */
#define SRC_LA 0x1A001C /* 0x1A001C + (256 * Chn) */
#define SRC_CTLSWR 0x1A0020 /* 0x1A0020 + (256 * Chn) */
#define SRC_CD 0x1A0080 /* 0x1A0080 + (256 * Chn) + (4 * Regn) */
#define SRC_MCTL 0x1A012C
#define SRC_IP 0x1A102C /* 0x1A102C + (256 * Regn) */
#define SRC_ENB 0x1A282C /* 0x1A282C + (256 * Regn) */
#define SRC_ENBSTAT 0x1A202C
#define SRC_ENBSA 0x1A232C
#define SRC_DN0Z 0x1A0030
#define SRC_DN1Z 0x1A0040
#define SRC_UPZ 0x1A0060
/* GPIO Registers */
#define GPIO_DATA 0x1B7020
#define GPIO_CTRL 0x1B7024
/* Virtual memory registers */
#define VMEM_PTPAL 0x1C6300 /* 0x1C6300 + (16 * Chn) */
#define VMEM_PTPAH 0x1C6304 /* 0x1C6304 + (16 * Chn) */
#define VMEM_CTL 0x1C7000
/* Transport Registers */
#define TRANSPORT_ENB 0x1B6000
#define TRANSPORT_CTL 0x1B6004
#define TRANSPORT_INT 0x1B6008
/* Audio IO */
#define AUDIO_IO_AIM 0x1B5000 /* 0x1B5000 + (0x04 * Chn) */
#define AUDIO_IO_TX_CTL 0x1B5400 /* 0x1B5400 + (0x40 * Chn) */
#define AUDIO_IO_TX_CSTAT_L 0x1B5408 /* 0x1B5408 + (0x40 * Chn) */
#define AUDIO_IO_TX_CSTAT_H 0x1B540C /* 0x1B540C + (0x40 * Chn) */
#define AUDIO_IO_RX_CTL 0x1B5410 /* 0x1B5410 + (0x40 * Chn) */
#define AUDIO_IO_RX_SRT_CTL 0x1B5420 /* 0x1B5420 + (0x40 * Chn) */
#define AUDIO_IO_MCLK 0x1B5600
#define AUDIO_IO_TX_BLRCLK 0x1B5604
#define AUDIO_IO_RX_BLRCLK 0x1B5608
/* Mixer */
#define MIXER_AMOPLO 0x130000 /* 0x130000 + (8 * Chn) [4095 : 0] */
#define MIXER_AMOPHI 0x130004 /* 0x130004 + (8 * Chn) [4095 : 0] */
#define MIXER_PRING_LO_HI 0x188000 /* 0x188000 + (4 * Chn) [4095 : 0] */
#define MIXER_PMOPLO 0x138000 /* 0x138000 + (8 * Chn) [4095 : 0] */
#define MIXER_PMOPHI 0x138004 /* 0x138004 + (8 * Chn) [4095 : 0] */
#define MIXER_AR_ENABLE 0x19000C
#endif
This diff is collapsed.
/**
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
*
* This source file is released under GPL v2 license (no other versions).
* See the COPYING file included in the main directory of this source
* distribution for the license terms and conditions.
*
* @File ctamixer.h
*
* @Brief
* This file contains the definition of the Audio Mixer
* resource management object.
*
* @Author Liu Chun
* @Date May 21 2008
*
*/
#ifndef CTAMIXER_H
#define CTAMIXER_H
#include "ctresource.h"
#include <linux/spinlock.h>
/* Define the descriptor of a summation node resource */
struct sum {
struct rsc rsc; /* Basic resource info */
unsigned char idx[8];
};
/* Define sum resource request description info */
struct sum_desc {
unsigned int msr;
};
struct sum_mgr {
struct rsc_mgr mgr; /* Basic resource manager info */
spinlock_t mgr_lock;
/* request one sum resource */
int (*get_sum)(struct sum_mgr *mgr,
const struct sum_desc *desc, struct sum **rsum);
/* return one sum resource */
int (*put_sum)(struct sum_mgr *mgr, struct sum *sum);
};
/* Constructor and destructor of daio resource manager */
int sum_mgr_create(void *hw, struct sum_mgr **rsum_mgr);
int sum_mgr_destroy(struct sum_mgr *sum_mgr);
/* Define the descriptor of a amixer resource */
struct amixer_rsc_ops;
struct amixer {
struct rsc rsc; /* Basic resource info */
unsigned char idx[8];
struct rsc *input; /* pointer to a resource acting as source */
struct sum *sum; /* Put amixer output to this summation node */
struct amixer_rsc_ops *ops; /* AMixer specific operations */
};
struct amixer_rsc_ops {
int (*set_input)(struct amixer *amixer, struct rsc *rsc);
int (*set_scale)(struct amixer *amixer, unsigned int scale);
int (*set_invalid_squash)(struct amixer *amixer, unsigned int iv);
int (*set_sum)(struct amixer *amixer, struct sum *sum);
int (*commit_write)(struct amixer *amixer);
/* Only for interleaved recording */
int (*commit_raw_write)(struct amixer *amixer);
int (*setup)(struct amixer *amixer, struct rsc *input,
unsigned int scale, struct sum *sum);
int (*get_scale)(struct amixer *amixer);
};
/* Define amixer resource request description info */
struct amixer_desc {
unsigned int msr;
};
struct amixer_mgr {
struct rsc_mgr mgr; /* Basic resource manager info */
spinlock_t mgr_lock;
/* request one amixer resource */
int (*get_amixer)(struct amixer_mgr *mgr,
const struct amixer_desc *desc,
struct amixer **ramixer);
/* return one amixer resource */
int (*put_amixer)(struct amixer_mgr *mgr, struct amixer *amixer);
};
/* Constructor and destructor of amixer resource manager */
int amixer_mgr_create(void *hw, struct amixer_mgr **ramixer_mgr);
int amixer_mgr_destroy(struct amixer_mgr *amixer_mgr);
#endif /* CTAMIXER_H */
This diff is collapsed.
/**
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
*
* This source file is released under GPL v2 license (no other versions).
* See the COPYING file included in the main directory of this source
* distribution for the license terms and conditions.
*
* @File ctatc.h
*
* @Brief
* This file contains the definition of the device resource management object.
*
* @Author Liu Chun
* @Date Mar 28 2008
*
*/
#ifndef CTATC_H
#define CTATC_H
#include <linux/types.h>
#include <linux/spinlock_types.h>
#include <linux/pci.h>
#include <linux/timer.h>
#include <sound/core.h>
#include "ctvmem.h"
#include "ctresource.h"
enum CTALSADEVS { /* Types of alsa devices */
FRONT,
SURROUND,
CLFE,
SIDE,
IEC958,
MIXER,
NUM_CTALSADEVS /* This should always be the last */
};
struct ct_atc_chip_sub_details {
u16 subsys;
const char *nm_model;
};
struct ct_atc_chip_details {
u16 vendor;
u16 device;
const struct ct_atc_chip_sub_details *sub_details;
const char *nm_card;
};
struct ct_atc;
struct ct_timer;
struct ct_timer_instance;
/* alsa pcm stream descriptor */
struct ct_atc_pcm {
struct snd_pcm_substream *substream;
void (*interrupt)(struct ct_atc_pcm *apcm);
struct ct_timer_instance *timer;
unsigned int started:1;
/* Only mono and interleaved modes are supported now. */
struct ct_vm_block *vm_block;
void *src; /* SRC for interacting with host memory */
void **srccs; /* SRCs for sample rate conversion */
void **srcimps; /* SRC Input Mappers */
void **amixers; /* AMIXERs for routing converted data */
void *mono; /* A SUM resource for mixing chs to one */
unsigned char n_srcc; /* Number of converting SRCs */
unsigned char n_srcimp; /* Number of SRC Input Mappers */
unsigned char n_amixer; /* Number of AMIXERs */
};
/* Chip resource management object */
struct ct_atc {
struct pci_dev *pci;
struct snd_card *card;
unsigned int rsr; /* reference sample rate in Hz */
unsigned int msr; /* master sample rate in rsr */
unsigned int pll_rate; /* current rate of Phase Lock Loop */
int chip_type;
int model;
const char *chip_name;
const char *model_name;
struct ct_vm *vm; /* device virtual memory manager for this card */
int (*map_audio_buffer)(struct ct_atc *atc, struct ct_atc_pcm *apcm);
void (*unmap_audio_buffer)(struct ct_atc *atc, struct ct_atc_pcm *apcm);
unsigned long (*get_ptp_phys)(struct ct_atc *atc, int index);
spinlock_t atc_lock;
int (*pcm_playback_prepare)(struct ct_atc *atc,
struct ct_atc_pcm *apcm);
int (*pcm_playback_start)(struct ct_atc *atc, struct ct_atc_pcm *apcm);
int (*pcm_playback_stop)(struct ct_atc *atc, struct ct_atc_pcm *apcm);
int (*pcm_playback_position)(struct ct_atc *atc,
struct ct_atc_pcm *apcm);
int (*spdif_passthru_playback_prepare)(struct ct_atc *atc,
struct ct_atc_pcm *apcm);
int (*pcm_capture_prepare)(struct ct_atc *atc, struct ct_atc_pcm *apcm);
int (*pcm_capture_start)(struct ct_atc *atc, struct ct_atc_pcm *apcm);
int (*pcm_capture_stop)(struct ct_atc *atc, struct ct_atc_pcm *apcm);
int (*pcm_capture_position)(struct ct_atc *atc,
struct ct_atc_pcm *apcm);
int (*pcm_release_resources)(struct ct_atc *atc,
struct ct_atc_pcm *apcm);
int (*select_line_in)(struct ct_atc *atc);
int (*select_mic_in)(struct ct_atc *atc);
int (*select_digit_io)(struct ct_atc *atc);
int (*line_front_unmute)(struct ct_atc *atc, unsigned char state);
int (*line_surround_unmute)(struct ct_atc *atc, unsigned char state);
int (*line_clfe_unmute)(struct ct_atc *atc, unsigned char state);
int (*line_rear_unmute)(struct ct_atc *atc, unsigned char state);
int (*line_in_unmute)(struct ct_atc *atc, unsigned char state);
int (*spdif_out_unmute)(struct ct_atc *atc, unsigned char state);
int (*spdif_in_unmute)(struct ct_atc *atc, unsigned char state);
int (*spdif_out_get_status)(struct ct_atc *atc, unsigned int *status);
int (*spdif_out_set_status)(struct ct_atc *atc, unsigned int status);
int (*spdif_out_passthru)(struct ct_atc *atc, unsigned char state);
int (*have_digit_io_switch)(struct ct_atc *atc);
/* Don't touch! Used for internal object. */
void *rsc_mgrs[NUM_RSCTYP]; /* chip resource managers */
void *mixer; /* internal mixer object */
void *hw; /* chip specific hardware access object */
void **daios; /* digital audio io resources */
void **pcm; /* SUMs for collecting all pcm stream */
void **srcs; /* Sample Rate Converters for input signal */
void **srcimps; /* input mappers for SRCs */
unsigned char n_daio;
unsigned char n_src;
unsigned char n_srcimp;
unsigned char n_pcm;
struct ct_timer *timer;
};
int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci,
unsigned int rsr, unsigned int msr, int chip_type,
struct ct_atc **ratc);
int __devinit ct_atc_create_alsa_devs(struct ct_atc *atc);
#endif /* CTATC_H */
This diff is collapsed.
/**
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
*
* This source file is released under GPL v2 license (no other versions).
* See the COPYING file included in the main directory of this source
* distribution for the license terms and conditions.
*
* @File ctdaio.h
*
* @Brief
* This file contains the definition of Digital Audio Input Output
* resource management object.
*
* @Author Liu Chun
* @Date May 23 2008
*
*/
#ifndef CTDAIO_H
#define CTDAIO_H
#include "ctresource.h"
#include "ctimap.h"
#include <linux/spinlock.h>
#include <linux/list.h>
/* Define the descriptor of a daio resource */
enum DAIOTYP {
LINEO1,
LINEO2,
LINEO3,
LINEO4,
SPDIFOO, /* S/PDIF Out (Flexijack/Optical) */
LINEIM,
SPDIFIO, /* S/PDIF In (Flexijack/Optical) on the card */
SPDIFI1, /* S/PDIF In on internal Drive Bay */
NUM_DAIOTYP
};
struct dao_rsc_ops;
struct dai_rsc_ops;
struct daio_mgr;
struct daio {
struct rsc rscl; /* Basic resource info for left TX/RX */
struct rsc rscr; /* Basic resource info for right TX/RX */
enum DAIOTYP type;
};
struct dao {
struct daio daio;
struct dao_rsc_ops *ops; /* DAO specific operations */
struct imapper **imappers;
struct daio_mgr *mgr;
void *hw;
void *ctrl_blk;
};
struct dai {
struct daio daio;
struct dai_rsc_ops *ops; /* DAI specific operations */
void *hw;
void *ctrl_blk;
};
struct dao_desc {
unsigned int msr:4;
unsigned int passthru:1;
};
struct dao_rsc_ops {
int (*set_spos)(struct dao *dao, unsigned int spos);
int (*commit_write)(struct dao *dao);
int (*get_spos)(struct dao *dao, unsigned int *spos);
int (*reinit)(struct dao *dao, const struct dao_desc *desc);
int (*set_left_input)(struct dao *dao, struct rsc *input);
int (*set_right_input)(struct dao *dao, struct rsc *input);
int (*clear_left_input)(struct dao *dao);
int (*clear_right_input)(struct dao *dao);
};
struct dai_rsc_ops {
int (*set_srt_srcl)(struct dai *dai, struct rsc *src);
int (*set_srt_srcr)(struct dai *dai, struct rsc *src);
int (*set_srt_msr)(struct dai *dai, unsigned int msr);
int (*set_enb_src)(struct dai *dai, unsigned int enb);
int (*set_enb_srt)(struct dai *dai, unsigned int enb);
int (*commit_write)(struct dai *dai);
};
/* Define daio resource request description info */
struct daio_desc {
unsigned int type:4;
unsigned int msr:4;
unsigned int passthru:1;
};
struct daio_mgr {
struct rsc_mgr mgr; /* Basic resource manager info */
spinlock_t mgr_lock;
spinlock_t imap_lock;
struct list_head imappers;
struct imapper *init_imap;
unsigned int init_imap_added;
/* request one daio resource */
int (*get_daio)(struct daio_mgr *mgr,
const struct daio_desc *desc, struct daio **rdaio);
/* return one daio resource */
int (*put_daio)(struct daio_mgr *mgr, struct daio *daio);
int (*daio_enable)(struct daio_mgr *mgr, struct daio *daio);
int (*daio_disable)(struct daio_mgr *mgr, struct daio *daio);
int (*imap_add)(struct daio_mgr *mgr, struct imapper *entry);
int (*imap_delete)(struct daio_mgr *mgr, struct imapper *entry);
int (*commit_write)(struct daio_mgr *mgr);
};
/* Constructor and destructor of daio resource manager */
int daio_mgr_create(void *hw, struct daio_mgr **rdaio_mgr);
int daio_mgr_destroy(struct daio_mgr *daio_mgr);
#endif /* CTDAIO_H */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/**
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
*
* This source file is released under GPL v2 license (no other versions).
* See the COPYING file included in the main directory of this source
* distribution for the license terms and conditions.
*
* @File cthw20k1.h
*
* @Brief
* This file contains the definition of hardware access methord.
*
* @Author Liu Chun
* @Date May 13 2008
*
*/
#ifndef CTHW20K1_H
#define CTHW20K1_H
#include "cthardware.h"
int create_20k1_hw_obj(struct hw **rhw);
int destroy_20k1_hw_obj(struct hw *hw);
#endif /* CTHW20K1_H */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -858,7 +858,6 @@ static int __devinit snd_emu10k1x_pcm(struct emu10k1x *emu, int device, struct s
}
pcm->info_flags = 0;
pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
switch(device) {
case 0:
strcpy(pcm->name, "EMU10K1X Front");
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
snd-lx6464es-objs := lx6464es.o lx_core.o
obj-$(CONFIG_SND_LX6464ES) += snd-lx6464es.o
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment