提交 a9c86d42 编写于 作者: L 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: (377 commits)
  ASoC: au1x: PSC-AC97 bugfixes
  ALSA: dummy - Increase MAX_PCM_SUBSTREAMS to 128
  ALSA: dummy - Add debug proc file
  ALSA: Add const prefix to proc helper functions
  ALSA: Re-export snd_pcm_format_name() function
  ALSA: hda - Use auto model for HP laptops with ALC268 codec
  ALSA: cs46xx - Fix minimum period size
  ASoC: Fix WM835x Out4 capture enumeration
  ALSA: Remove unneeded ifdef from sound/core.h
  ALSA: Remove struct snd_monitor_file from public sound/core.h
  ASoC: Remove unuused hw_read_t
  sound: oxygen: work around MCE when changing volume
  ALSA: dummy - Fake buffer allocations
  ALSA: hda/realtek: Added support for CLEVO M540R subsystem, 6 channel + digital
  ASoC: fix pxa2xx-ac97.c breakage
  ALSA: dummy - Fix the timer calculation in systimer mode
  ALSA: dummy - Add more description
  ALSA: dummy - Better jiffies handling
  ALSA: dummy - Support high-res timer mode
  ALSA: Release v1.0.21
  ...
...@@ -468,3 +468,27 @@ Why: cpu_policy_rwsem has a new cleaner definition making it local to ...@@ -468,3 +468,27 @@ Why: cpu_policy_rwsem has a new cleaner definition making it local to
cpufreq core and contained inside cpufreq.c. Other dependent cpufreq core and contained inside cpufreq.c. Other dependent
drivers should not use it in order to safely avoid lockdep issues. drivers should not use it in order to safely avoid lockdep issues.
Who: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com> Who: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
----------------------------
What: sound-slot/service-* module aliases and related clutters in
sound/sound_core.c
When: August 2010
Why: OSS sound_core grabs all legacy minors (0-255) of SOUND_MAJOR
(14) and requests modules using custom sound-slot/service-*
module aliases. The only benefit of doing this is allowing
use of custom module aliases which might as well be considered
a bug at this point. This preemptive claiming prevents
alternative OSS implementations.
Till the feature is removed, the kernel will be requesting
both sound-slot/service-* and the standard char-major-* module
aliases and allow turning off the pre-claiming selectively via
CONFIG_SOUND_OSS_CORE_PRECLAIM and soundcore.preclaim_oss
kernel parameter.
After the transition phase is complete, both the custom module
aliases and switches to disable it will go away. This removal
will also allow making ALSA OSS emulation independent of
sound_core. The dependency will be broken then too.
Who: Tejun Heo <tj@kernel.org>
...@@ -60,6 +60,12 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. ...@@ -60,6 +60,12 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
slots - Reserve the slot index for the given driver. slots - Reserve the slot index for the given driver.
This option takes multiple strings. This option takes multiple strings.
See "Module Autoloading Support" section for details. See "Module Autoloading Support" section for details.
debug - Specifies the debug message level
(0 = disable debug prints, 1 = normal debug messages,
2 = verbose debug messages)
This option appears only when CONFIG_SND_DEBUG=y.
This option can be dynamically changed via sysfs
/sys/modules/snd/parameters/debug file.
Module snd-pcm-oss Module snd-pcm-oss
------------------ ------------------
...@@ -513,6 +519,26 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. ...@@ -513,6 +519,26 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
or input, but you may use this module for any application which or input, but you may use this module for any application which
requires a sound card (like RealPlayer). requires a sound card (like RealPlayer).
pcm_devs - Number of PCM devices assigned to each card
(default = 1, up to 4)
pcm_substreams - Number of PCM substreams assigned to each PCM
(default = 8, up to 16)
hrtimer - Use hrtimer (=1, default) or system timer (=0)
fake_buffer - Fake buffer allocations (default = 1)
When multiple PCM devices are created, snd-dummy gives different
behavior to each PCM device:
0 = interleaved with mmap support
1 = non-interleaved with mmap support
2 = interleaved without mmap
3 = non-interleaved without mmap
As default, snd-dummy drivers doesn't allocate the real buffers
but either ignores read/write or mmap a single dummy page to all
buffer pages, in order to save the resouces. If your apps need
the read/ written buffer data to be consistent, pass fake_buffer=0
option.
The power-management is supported. The power-management is supported.
Module snd-echo3g Module snd-echo3g
...@@ -768,6 +794,10 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. ...@@ -768,6 +794,10 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
bdl_pos_adj - Specifies the DMA IRQ timing delay in samples. bdl_pos_adj - Specifies the DMA IRQ timing delay in samples.
Passing -1 will make the driver to choose the appropriate Passing -1 will make the driver to choose the appropriate
value based on the controller chip. value based on the controller chip.
patch - Specifies the early "patch" files to modify the HD-audio
setup before initializing the codecs. This option is
available only when CONFIG_SND_HDA_PATCH_LOADER=y is set.
See HD-Audio.txt for details.
[Single (global) options] [Single (global) options]
single_cmd - Use single immediate commands to communicate with single_cmd - Use single immediate commands to communicate with
......
...@@ -114,8 +114,8 @@ ALC662/663/272 ...@@ -114,8 +114,8 @@ ALC662/663/272
samsung-nc10 Samsung NC10 mini notebook samsung-nc10 Samsung NC10 mini notebook
auto auto-config reading BIOS (default) auto auto-config reading BIOS (default)
ALC882/885 ALC882/883/885/888/889
========== ======================
3stack-dig 3-jack with SPDIF I/O 3stack-dig 3-jack with SPDIF I/O
6stack-dig 6-jack digital with SPDIF I/O 6stack-dig 6-jack digital with SPDIF I/O
arima Arima W820Di1 arima Arima W820Di1
...@@ -127,12 +127,8 @@ ALC882/885 ...@@ -127,12 +127,8 @@ ALC882/885
mbp3 Macbook Pro rev3 mbp3 Macbook Pro rev3
imac24 iMac 24'' with jack detection imac24 iMac 24'' with jack detection
w2jc ASUS W2JC w2jc ASUS W2JC
auto auto-config reading BIOS (default) 3stack-2ch-dig 3-jack with SPDIF I/O (ALC883)
alc883-6stack-dig 6-jack digital with SPDIF I/O (ALC883)
ALC883/888
==========
3stack-dig 3-jack with SPDIF I/O
6stack-dig 6-jack digital with SPDIF I/O
3stack-6ch 3-jack 6-channel 3stack-6ch 3-jack 6-channel
3stack-6ch-dig 3-jack 6-channel with SPDIF I/O 3stack-6ch-dig 3-jack 6-channel with SPDIF I/O
6stack-dig-demo 6-jack digital for Intel demo board 6stack-dig-demo 6-jack digital for Intel demo board
...@@ -140,6 +136,7 @@ ALC883/888 ...@@ -140,6 +136,7 @@ ALC883/888
acer-aspire Acer Aspire 9810 acer-aspire Acer Aspire 9810
acer-aspire-4930g Acer Aspire 4930G acer-aspire-4930g Acer Aspire 4930G
acer-aspire-6530g Acer Aspire 6530G acer-aspire-6530g Acer Aspire 6530G
acer-aspire-7730g Acer Aspire 7730G
acer-aspire-8930g Acer Aspire 8930G acer-aspire-8930g Acer Aspire 8930G
medion Medion Laptops medion Medion Laptops
medion-md2 Medion MD2 medion-md2 Medion MD2
...@@ -155,10 +152,13 @@ ALC883/888 ...@@ -155,10 +152,13 @@ ALC883/888
3stack-hp HP machines with 3stack (Lucknow, Samba boards) 3stack-hp HP machines with 3stack (Lucknow, Samba boards)
6stack-dell Dell machines with 6stack (Inspiron 530) 6stack-dell Dell machines with 6stack (Inspiron 530)
mitac Mitac 8252D mitac Mitac 8252D
clevo-m540r Clevo M540R (6ch + digital)
clevo-m720 Clevo M720 laptop series clevo-m720 Clevo M720 laptop series
fujitsu-pi2515 Fujitsu AMILO Pi2515 fujitsu-pi2515 Fujitsu AMILO Pi2515
fujitsu-xa3530 Fujitsu AMILO XA3530 fujitsu-xa3530 Fujitsu AMILO XA3530
3stack-6ch-intel Intel DG33* boards 3stack-6ch-intel Intel DG33* boards
intel-alc889a Intel IbexPeak with ALC889A
intel-x58 Intel DX58 with ALC889
asus-p5q ASUS P5Q-EM boards asus-p5q ASUS P5Q-EM boards
mb31 MacBook 3,1 mb31 MacBook 3,1
sony-vaio-tt Sony VAIO TT sony-vaio-tt Sony VAIO TT
...@@ -229,7 +229,7 @@ AD1984 ...@@ -229,7 +229,7 @@ AD1984
====== ======
basic default configuration basic default configuration
thinkpad Lenovo Thinkpad T61/X61 thinkpad Lenovo Thinkpad T61/X61
dell Dell T3400 dell_desktop Dell T3400
AD1986A AD1986A
======= =======
...@@ -258,6 +258,7 @@ Conexant 5045 ...@@ -258,6 +258,7 @@ Conexant 5045
laptop-micsense Laptop with Mic sense (old model fujitsu) laptop-micsense Laptop with Mic sense (old model fujitsu)
laptop-hpmicsense Laptop with HP and Mic senses laptop-hpmicsense Laptop with HP and Mic senses
benq Benq R55E benq Benq R55E
laptop-hp530 HP 530 laptop
test for testing/debugging purpose, almost all controls test for testing/debugging purpose, almost all controls
can be adjusted. Appearing only when compiled with can be adjusted. Appearing only when compiled with
$CONFIG_SND_DEBUG=y $CONFIG_SND_DEBUG=y
...@@ -278,9 +279,16 @@ Conexant 5051 ...@@ -278,9 +279,16 @@ Conexant 5051
hp-dv6736 HP dv6736 hp-dv6736 HP dv6736
lenovo-x200 Lenovo X200 laptop lenovo-x200 Lenovo X200 laptop
Conexant 5066
=============
laptop Basic Laptop config (default)
dell-laptop Dell laptops
olpc-xo-1_5 OLPC XO 1.5
STAC9200 STAC9200
======== ========
ref Reference board ref Reference board
oqo OQO Model 2
dell-d21 Dell (unknown) dell-d21 Dell (unknown)
dell-d22 Dell (unknown) dell-d22 Dell (unknown)
dell-d23 Dell (unknown) dell-d23 Dell (unknown)
...@@ -368,10 +376,12 @@ STAC92HD73* ...@@ -368,10 +376,12 @@ STAC92HD73*
=========== ===========
ref Reference board ref Reference board
no-jd BIOS setup but without jack-detection no-jd BIOS setup but without jack-detection
intel Intel DG45* mobos
dell-m6-amic Dell desktops/laptops with analog mics dell-m6-amic Dell desktops/laptops with analog mics
dell-m6-dmic Dell desktops/laptops with digital mics dell-m6-dmic Dell desktops/laptops with digital mics
dell-m6 Dell desktops/laptops with both type of mics dell-m6 Dell desktops/laptops with both type of mics
dell-eq Dell desktops/laptops dell-eq Dell desktops/laptops
alienware Alienware M17x
auto BIOS setup (default) auto BIOS setup (default)
STAC92HD83* STAC92HD83*
...@@ -385,3 +395,8 @@ STAC9872 ...@@ -385,3 +395,8 @@ STAC9872
======== ========
vaio VAIO laptop without SPDIF vaio VAIO laptop without SPDIF
auto BIOS setup (default) auto BIOS setup (default)
Cirrus Logic CS4206/4207
========================
mbp55 MacBook Pro 5,5
auto BIOS setup (default)
...@@ -138,6 +138,10 @@ override the BIOS setup or to provide more comprehensive features. ...@@ -138,6 +138,10 @@ override the BIOS setup or to provide more comprehensive features.
The driver checks PCI SSID and looks through the static configuration The driver checks PCI SSID and looks through the static configuration
table until any matching entry is found. If you have a new machine, table until any matching entry is found. If you have a new machine,
you may see a message like below: you may see a message like below:
------------------------------------------------------------------------
hda_codec: ALC880: BIOS auto-probing.
------------------------------------------------------------------------
Meanwhile, in the earlier versions, you would see a message like:
------------------------------------------------------------------------ ------------------------------------------------------------------------
hda_codec: Unknown model for ALC880, trying auto-probe from BIOS... hda_codec: Unknown model for ALC880, trying auto-probe from BIOS...
------------------------------------------------------------------------ ------------------------------------------------------------------------
...@@ -403,6 +407,66 @@ re-configure based on that state, run like below: ...@@ -403,6 +407,66 @@ re-configure based on that state, run like below:
------------------------------------------------------------------------ ------------------------------------------------------------------------
Early Patching
~~~~~~~~~~~~~~
When CONFIG_SND_HDA_PATCH_LOADER=y is set, you can pass a "patch" as a
firmware file for modifying the HD-audio setup before initializing the
codec. This can work basically like the reconfiguration via sysfs in
the above, but it does it before the first codec configuration.
A patch file is a plain text file which looks like below:
------------------------------------------------------------------------
[codec]
0x12345678 0xabcd1234 2
[model]
auto
[pincfg]
0x12 0x411111f0
[verb]
0x20 0x500 0x03
0x20 0x400 0xff
[hint]
hp_detect = yes
------------------------------------------------------------------------
The file needs to have a line `[codec]`. The next line should contain
three numbers indicating the codec vendor-id (0x12345678 in the
example), the codec subsystem-id (0xabcd1234) and the address (2) of
the codec. The rest patch entries are applied to this specified codec
until another codec entry is given.
The `[model]` line allows to change the model name of the each codec.
In the example above, it will be changed to model=auto.
Note that this overrides the module option.
After the `[pincfg]` line, the contents are parsed as the initial
default pin-configurations just like `user_pin_configs` sysfs above.
The values can be shown in user_pin_configs sysfs file, too.
Similarly, the lines after `[verb]` are parsed as `init_verbs`
sysfs entries, and the lines after `[hint]` are parsed as `hints`
sysfs entries, respectively.
The hd-audio driver reads the file via request_firmware(). Thus,
a patch file has to be located on the appropriate firmware path,
typically, /lib/firmware. For example, when you pass the option
`patch=hda-init.fw`, the file /lib/firmware/hda-init-fw must be
present.
The patch module option is specific to each card instance, and you
need to give one file name for each instance, separated by commas.
For example, if you have two cards, one for an on-board analog and one
for an HDMI video board, you may pass patch option like below:
------------------------------------------------------------------------
options snd-hda-intel patch=on-board-patch,hdmi-patch
------------------------------------------------------------------------
Power-Saving Power-Saving
~~~~~~~~~~~~ ~~~~~~~~~~~~
The power-saving is a kind of auto-suspend of the device. When the The power-saving is a kind of auto-suspend of the device. When the
......
...@@ -128,6 +128,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = { ...@@ -128,6 +128,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
.rx_irq = INT_24XX_MCBSP1_IRQ_RX, .rx_irq = INT_24XX_MCBSP1_IRQ_RX,
.tx_irq = INT_24XX_MCBSP1_IRQ_TX, .tx_irq = INT_24XX_MCBSP1_IRQ_TX,
.ops = &omap2_mcbsp_ops, .ops = &omap2_mcbsp_ops,
.buffer_size = 0x6F,
}, },
{ {
.phys_base = OMAP34XX_MCBSP2_BASE, .phys_base = OMAP34XX_MCBSP2_BASE,
...@@ -136,6 +137,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = { ...@@ -136,6 +137,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
.rx_irq = INT_24XX_MCBSP2_IRQ_RX, .rx_irq = INT_24XX_MCBSP2_IRQ_RX,
.tx_irq = INT_24XX_MCBSP2_IRQ_TX, .tx_irq = INT_24XX_MCBSP2_IRQ_TX,
.ops = &omap2_mcbsp_ops, .ops = &omap2_mcbsp_ops,
.buffer_size = 0x3FF,
}, },
{ {
.phys_base = OMAP34XX_MCBSP3_BASE, .phys_base = OMAP34XX_MCBSP3_BASE,
...@@ -144,6 +146,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = { ...@@ -144,6 +146,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
.rx_irq = INT_24XX_MCBSP3_IRQ_RX, .rx_irq = INT_24XX_MCBSP3_IRQ_RX,
.tx_irq = INT_24XX_MCBSP3_IRQ_TX, .tx_irq = INT_24XX_MCBSP3_IRQ_TX,
.ops = &omap2_mcbsp_ops, .ops = &omap2_mcbsp_ops,
.buffer_size = 0x6F,
}, },
{ {
.phys_base = OMAP34XX_MCBSP4_BASE, .phys_base = OMAP34XX_MCBSP4_BASE,
...@@ -152,6 +155,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = { ...@@ -152,6 +155,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
.rx_irq = INT_24XX_MCBSP4_IRQ_RX, .rx_irq = INT_24XX_MCBSP4_IRQ_RX,
.tx_irq = INT_24XX_MCBSP4_IRQ_TX, .tx_irq = INT_24XX_MCBSP4_IRQ_TX,
.ops = &omap2_mcbsp_ops, .ops = &omap2_mcbsp_ops,
.buffer_size = 0x6F,
}, },
{ {
.phys_base = OMAP34XX_MCBSP5_BASE, .phys_base = OMAP34XX_MCBSP5_BASE,
...@@ -160,6 +164,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = { ...@@ -160,6 +164,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
.rx_irq = INT_24XX_MCBSP5_IRQ_RX, .rx_irq = INT_24XX_MCBSP5_IRQ_RX,
.tx_irq = INT_24XX_MCBSP5_IRQ_TX, .tx_irq = INT_24XX_MCBSP5_IRQ_TX,
.ops = &omap2_mcbsp_ops, .ops = &omap2_mcbsp_ops,
.buffer_size = 0x6F,
}, },
}; };
#define OMAP34XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap34xx_mcbsp_pdata) #define OMAP34XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap34xx_mcbsp_pdata)
......
...@@ -3,10 +3,12 @@ ...@@ -3,10 +3,12 @@
#include <sound/core.h> #include <sound/core.h>
#include <sound/pcm.h> #include <sound/pcm.h>
#include <sound/ac97_codec.h>
/* /*
* @reset_gpio: AC97 reset gpio (normally gpio113 or gpio95) * @reset_gpio: AC97 reset gpio (normally gpio113 or gpio95)
* a -1 value means no gpio will be used for reset * a -1 value means no gpio will be used for reset
* @codec_pdata: AC97 codec platform_data
* reset_gpio should only be specified for pxa27x CPUs where a silicon * reset_gpio should only be specified for pxa27x CPUs where a silicon
* bug prevents correct operation of the reset line. If not specified, * bug prevents correct operation of the reset line. If not specified,
...@@ -20,6 +22,7 @@ typedef struct { ...@@ -20,6 +22,7 @@ typedef struct {
void (*resume)(void *); void (*resume)(void *);
void *priv; void *priv;
int reset_gpio; int reset_gpio;
void *codec_pdata[AC97_BUS_MAX_DEVICES];
} pxa2xx_audio_ops_t; } pxa2xx_audio_ops_t;
extern void pxa_set_ac97_info(pxa2xx_audio_ops_t *ops); extern void pxa_set_ac97_info(pxa2xx_audio_ops_t *ops);
......
...@@ -1127,6 +1127,11 @@ int omap_dma_running(void) ...@@ -1127,6 +1127,11 @@ int omap_dma_running(void)
void omap_dma_link_lch(int lch_head, int lch_queue) void omap_dma_link_lch(int lch_head, int lch_queue)
{ {
if (omap_dma_in_1510_mode()) { if (omap_dma_in_1510_mode()) {
if (lch_head == lch_queue) {
dma_write(dma_read(CCR(lch_head)) | (3 << 8),
CCR(lch_head));
return;
}
printk(KERN_ERR "DMA linking is not supported in 1510 mode\n"); printk(KERN_ERR "DMA linking is not supported in 1510 mode\n");
BUG(); BUG();
return; return;
...@@ -1149,6 +1154,11 @@ EXPORT_SYMBOL(omap_dma_link_lch); ...@@ -1149,6 +1154,11 @@ EXPORT_SYMBOL(omap_dma_link_lch);
void omap_dma_unlink_lch(int lch_head, int lch_queue) void omap_dma_unlink_lch(int lch_head, int lch_queue)
{ {
if (omap_dma_in_1510_mode()) { if (omap_dma_in_1510_mode()) {
if (lch_head == lch_queue) {
dma_write(dma_read(CCR(lch_head)) & ~(3 << 8),
CCR(lch_head));
return;
}
printk(KERN_ERR "DMA linking is not supported in 1510 mode\n"); printk(KERN_ERR "DMA linking is not supported in 1510 mode\n");
BUG(); BUG();
return; return;
......
...@@ -134,6 +134,11 @@ ...@@ -134,6 +134,11 @@
#define OMAP_MCBSP_REG_XCERG 0x74 #define OMAP_MCBSP_REG_XCERG 0x74
#define OMAP_MCBSP_REG_XCERH 0x78 #define OMAP_MCBSP_REG_XCERH 0x78
#define OMAP_MCBSP_REG_SYSCON 0x8C #define OMAP_MCBSP_REG_SYSCON 0x8C
#define OMAP_MCBSP_REG_THRSH2 0x90
#define OMAP_MCBSP_REG_THRSH1 0x94
#define OMAP_MCBSP_REG_IRQST 0xA0
#define OMAP_MCBSP_REG_IRQEN 0xA4
#define OMAP_MCBSP_REG_WAKEUPEN 0xA8
#define OMAP_MCBSP_REG_XCCR 0xAC #define OMAP_MCBSP_REG_XCCR 0xAC
#define OMAP_MCBSP_REG_RCCR 0xB0 #define OMAP_MCBSP_REG_RCCR 0xB0
...@@ -249,8 +254,27 @@ ...@@ -249,8 +254,27 @@
#define RDISABLE 0x0001 #define RDISABLE 0x0001
/********************** McBSP SYSCONFIG bit definitions ********************/ /********************** McBSP SYSCONFIG bit definitions ********************/
#define CLOCKACTIVITY(value) ((value)<<8)
#define SIDLEMODE(value) ((value)<<3)
#define ENAWAKEUP 0x0004
#define SOFTRST 0x0002 #define SOFTRST 0x0002
/********************** McBSP DMA operating modes **************************/
#define MCBSP_DMA_MODE_ELEMENT 0
#define MCBSP_DMA_MODE_THRESHOLD 1
#define MCBSP_DMA_MODE_FRAME 2
/********************** McBSP WAKEUPEN bit definitions *********************/
#define XEMPTYEOFEN 0x4000
#define XRDYEN 0x0400
#define XEOFEN 0x0200
#define XFSXEN 0x0100
#define XSYNCERREN 0x0080
#define RRDYEN 0x0008
#define REOFEN 0x0004
#define RFSREN 0x0002
#define RSYNCERREN 0x0001
/* we don't do multichannel for now */ /* we don't do multichannel for now */
struct omap_mcbsp_reg_cfg { struct omap_mcbsp_reg_cfg {
u16 spcr2; u16 spcr2;
...@@ -344,6 +368,9 @@ struct omap_mcbsp_platform_data { ...@@ -344,6 +368,9 @@ struct omap_mcbsp_platform_data {
u8 dma_rx_sync, dma_tx_sync; u8 dma_rx_sync, dma_tx_sync;
u16 rx_irq, tx_irq; u16 rx_irq, tx_irq;
struct omap_mcbsp_ops *ops; struct omap_mcbsp_ops *ops;
#ifdef CONFIG_ARCH_OMAP34XX
u16 buffer_size;
#endif
}; };
struct omap_mcbsp { struct omap_mcbsp {
...@@ -377,6 +404,11 @@ struct omap_mcbsp { ...@@ -377,6 +404,11 @@ struct omap_mcbsp {
struct omap_mcbsp_platform_data *pdata; struct omap_mcbsp_platform_data *pdata;
struct clk *iclk; struct clk *iclk;
struct clk *fclk; struct clk *fclk;
#ifdef CONFIG_ARCH_OMAP34XX
int dma_op_mode;
u16 max_tx_thres;
u16 max_rx_thres;
#endif
}; };
extern struct omap_mcbsp **mcbsp_ptr; extern struct omap_mcbsp **mcbsp_ptr;
extern int omap_mcbsp_count; extern int omap_mcbsp_count;
...@@ -385,10 +417,25 @@ int omap_mcbsp_init(void); ...@@ -385,10 +417,25 @@ int omap_mcbsp_init(void);
void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config, void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config,
int size); int size);
void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg * config); void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg * config);
#ifdef CONFIG_ARCH_OMAP34XX
void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold);
void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold);
u16 omap_mcbsp_get_max_tx_threshold(unsigned int id);
u16 omap_mcbsp_get_max_rx_threshold(unsigned int id);
int omap_mcbsp_get_dma_op_mode(unsigned int id);
#else
static inline void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold)
{ }
static inline void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold)
{ }
static inline u16 omap_mcbsp_get_max_tx_threshold(unsigned int id) { return 0; }
static inline u16 omap_mcbsp_get_max_rx_threshold(unsigned int id) { return 0; }
static inline int omap_mcbsp_get_dma_op_mode(unsigned int id) { return 0; }
#endif
int omap_mcbsp_request(unsigned int id); int omap_mcbsp_request(unsigned int id);
void omap_mcbsp_free(unsigned int id); void omap_mcbsp_free(unsigned int id);
void omap_mcbsp_start(unsigned int id); void omap_mcbsp_start(unsigned int id, int tx, int rx);
void omap_mcbsp_stop(unsigned int id); void omap_mcbsp_stop(unsigned int id, int tx, int rx);
void omap_mcbsp_xmit_word(unsigned int id, u32 word); void omap_mcbsp_xmit_word(unsigned int id, u32 word);
u32 omap_mcbsp_recv_word(unsigned int id); u32 omap_mcbsp_recv_word(unsigned int id);
......
...@@ -198,6 +198,170 @@ void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg *config) ...@@ -198,6 +198,170 @@ void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg *config)
} }
EXPORT_SYMBOL(omap_mcbsp_config); EXPORT_SYMBOL(omap_mcbsp_config);
#ifdef CONFIG_ARCH_OMAP34XX
/*
* omap_mcbsp_set_tx_threshold configures how to deal
* with transmit threshold. the threshold value and handler can be
* configure in here.
*/
void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold)
{
struct omap_mcbsp *mcbsp;
void __iomem *io_base;
if (!cpu_is_omap34xx())
return;
if (!omap_mcbsp_check_valid_id(id)) {
printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
return;
}
mcbsp = id_to_mcbsp_ptr(id);
io_base = mcbsp->io_base;
OMAP_MCBSP_WRITE(io_base, THRSH2, threshold);
}
EXPORT_SYMBOL(omap_mcbsp_set_tx_threshold);
/*
* omap_mcbsp_set_rx_threshold configures how to deal
* with receive threshold. the threshold value and handler can be
* configure in here.
*/
void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold)
{
struct omap_mcbsp *mcbsp;
void __iomem *io_base;
if (!cpu_is_omap34xx())
return;
if (!omap_mcbsp_check_valid_id(id)) {
printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
return;
}
mcbsp = id_to_mcbsp_ptr(id);
io_base = mcbsp->io_base;
OMAP_MCBSP_WRITE(io_base, THRSH1, threshold);
}
EXPORT_SYMBOL(omap_mcbsp_set_rx_threshold);
/*
* omap_mcbsp_get_max_tx_thres just return the current configured
* maximum threshold for transmission
*/
u16 omap_mcbsp_get_max_tx_threshold(unsigned int id)
{
struct omap_mcbsp *mcbsp;
if (!omap_mcbsp_check_valid_id(id)) {
printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
return -ENODEV;
}
mcbsp = id_to_mcbsp_ptr(id);
return mcbsp->max_tx_thres;
}
EXPORT_SYMBOL(omap_mcbsp_get_max_tx_threshold);
/*
* omap_mcbsp_get_max_rx_thres just return the current configured
* maximum threshold for reception
*/
u16 omap_mcbsp_get_max_rx_threshold(unsigned int id)
{
struct omap_mcbsp *mcbsp;
if (!omap_mcbsp_check_valid_id(id)) {
printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
return -ENODEV;
}
mcbsp = id_to_mcbsp_ptr(id);
return mcbsp->max_rx_thres;
}
EXPORT_SYMBOL(omap_mcbsp_get_max_rx_threshold);
/*
* omap_mcbsp_get_dma_op_mode just return the current configured
* operating mode for the mcbsp channel
*/
int omap_mcbsp_get_dma_op_mode(unsigned int id)
{
struct omap_mcbsp *mcbsp;
int dma_op_mode;
if (!omap_mcbsp_check_valid_id(id)) {
printk(KERN_ERR "%s: Invalid id (%u)\n", __func__, id + 1);
return -ENODEV;
}
mcbsp = id_to_mcbsp_ptr(id);
spin_lock_irq(&mcbsp->lock);
dma_op_mode = mcbsp->dma_op_mode;
spin_unlock_irq(&mcbsp->lock);
return dma_op_mode;
}
EXPORT_SYMBOL(omap_mcbsp_get_dma_op_mode);
static inline void omap34xx_mcbsp_request(struct omap_mcbsp *mcbsp)
{
/*
* Enable wakup behavior, smart idle and all wakeups
* REVISIT: some wakeups may be unnecessary
*/
if (cpu_is_omap34xx()) {
u16 syscon;
syscon = OMAP_MCBSP_READ(mcbsp->io_base, SYSCON);
syscon &= ~(ENAWAKEUP | SIDLEMODE(0x03) | CLOCKACTIVITY(0x03));
spin_lock_irq(&mcbsp->lock);
if (mcbsp->dma_op_mode == MCBSP_DMA_MODE_THRESHOLD) {
syscon |= (ENAWAKEUP | SIDLEMODE(0x02) |
CLOCKACTIVITY(0x02));
OMAP_MCBSP_WRITE(mcbsp->io_base, WAKEUPEN,
XRDYEN | RRDYEN);
} else {
syscon |= SIDLEMODE(0x01);
}
spin_unlock_irq(&mcbsp->lock);
OMAP_MCBSP_WRITE(mcbsp->io_base, SYSCON, syscon);
}
}
static inline void omap34xx_mcbsp_free(struct omap_mcbsp *mcbsp)
{
/*
* Disable wakup behavior, smart idle and all wakeups
*/
if (cpu_is_omap34xx()) {
u16 syscon;
syscon = OMAP_MCBSP_READ(mcbsp->io_base, SYSCON);
syscon &= ~(ENAWAKEUP | SIDLEMODE(0x03) | CLOCKACTIVITY(0x03));
/*
* HW bug workaround - If no_idle mode is taken, we need to
* go to smart_idle before going to always_idle, or the
* device will not hit retention anymore.
*/
syscon |= SIDLEMODE(0x02);
OMAP_MCBSP_WRITE(mcbsp->io_base, SYSCON, syscon);
syscon &= ~(SIDLEMODE(0x03));
OMAP_MCBSP_WRITE(mcbsp->io_base, SYSCON, syscon);
OMAP_MCBSP_WRITE(mcbsp->io_base, WAKEUPEN, 0);
}
}
#else
static inline void omap34xx_mcbsp_request(struct omap_mcbsp *mcbsp) {}
static inline void omap34xx_mcbsp_free(struct omap_mcbsp *mcbsp) {}
#endif
/* /*
* We can choose between IRQ based or polled IO. * We can choose between IRQ based or polled IO.
* This needs to be called before omap_mcbsp_request(). * This needs to be called before omap_mcbsp_request().
...@@ -257,6 +421,9 @@ int omap_mcbsp_request(unsigned int id) ...@@ -257,6 +421,9 @@ int omap_mcbsp_request(unsigned int id)
clk_enable(mcbsp->iclk); clk_enable(mcbsp->iclk);
clk_enable(mcbsp->fclk); clk_enable(mcbsp->fclk);
/* Do procedure specific to omap34xx arch, if applicable */
omap34xx_mcbsp_request(mcbsp);
/* /*
* Make sure that transmitter, receiver and sample-rate generator are * Make sure that transmitter, receiver and sample-rate generator are
* not running before activating IRQs. * not running before activating IRQs.
...@@ -305,6 +472,9 @@ void omap_mcbsp_free(unsigned int id) ...@@ -305,6 +472,9 @@ void omap_mcbsp_free(unsigned int id)
if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->free) if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->free)
mcbsp->pdata->ops->free(id); mcbsp->pdata->ops->free(id);
/* Do procedure specific to omap34xx arch, if applicable */
omap34xx_mcbsp_free(mcbsp);
clk_disable(mcbsp->fclk); clk_disable(mcbsp->fclk);
clk_disable(mcbsp->iclk); clk_disable(mcbsp->iclk);
...@@ -328,14 +498,15 @@ void omap_mcbsp_free(unsigned int id) ...@@ -328,14 +498,15 @@ void omap_mcbsp_free(unsigned int id)
EXPORT_SYMBOL(omap_mcbsp_free); EXPORT_SYMBOL(omap_mcbsp_free);
/* /*
* Here we start the McBSP, by enabling the sample * Here we start the McBSP, by enabling transmitter, receiver or both.
* generator, both transmitter and receivers, * If no transmitter or receiver is active prior calling, then sample-rate
* and the frame sync. * generator and frame sync are started.
*/ */
void omap_mcbsp_start(unsigned int id) void omap_mcbsp_start(unsigned int id, int tx, int rx)
{ {
struct omap_mcbsp *mcbsp; struct omap_mcbsp *mcbsp;
void __iomem *io_base; void __iomem *io_base;
int idle;
u16 w; u16 w;
if (!omap_mcbsp_check_valid_id(id)) { if (!omap_mcbsp_check_valid_id(id)) {
...@@ -348,32 +519,58 @@ void omap_mcbsp_start(unsigned int id) ...@@ -348,32 +519,58 @@ void omap_mcbsp_start(unsigned int id)
mcbsp->rx_word_length = (OMAP_MCBSP_READ(io_base, RCR1) >> 5) & 0x7; mcbsp->rx_word_length = (OMAP_MCBSP_READ(io_base, RCR1) >> 5) & 0x7;
mcbsp->tx_word_length = (OMAP_MCBSP_READ(io_base, XCR1) >> 5) & 0x7; mcbsp->tx_word_length = (OMAP_MCBSP_READ(io_base, XCR1) >> 5) & 0x7;
/* Start the sample generator */ idle = !((OMAP_MCBSP_READ(io_base, SPCR2) |
w = OMAP_MCBSP_READ(io_base, SPCR2); OMAP_MCBSP_READ(io_base, SPCR1)) & 1);
OMAP_MCBSP_WRITE(io_base, SPCR2, w | (1 << 6));
if (idle) {
/* Start the sample generator */
w = OMAP_MCBSP_READ(io_base, SPCR2);
OMAP_MCBSP_WRITE(io_base, SPCR2, w | (1 << 6));
}
/* Enable transmitter and receiver */ /* Enable transmitter and receiver */
tx &= 1;
w = OMAP_MCBSP_READ(io_base, SPCR2); w = OMAP_MCBSP_READ(io_base, SPCR2);
OMAP_MCBSP_WRITE(io_base, SPCR2, w | 1); OMAP_MCBSP_WRITE(io_base, SPCR2, w | tx);
rx &= 1;
w = OMAP_MCBSP_READ(io_base, SPCR1); w = OMAP_MCBSP_READ(io_base, SPCR1);
OMAP_MCBSP_WRITE(io_base, SPCR1, w | 1); OMAP_MCBSP_WRITE(io_base, SPCR1, w | rx);
udelay(100); /*
* Worst case: CLKSRG*2 = 8000khz: (1/8000) * 2 * 2 usec
* REVISIT: 100us may give enough time for two CLKSRG, however
* due to some unknown PM related, clock gating etc. reason it
* is now at 500us.
*/
udelay(500);
/* Start frame sync */ if (idle) {
w = OMAP_MCBSP_READ(io_base, SPCR2); /* Start frame sync */
OMAP_MCBSP_WRITE(io_base, SPCR2, w | (1 << 7)); w = OMAP_MCBSP_READ(io_base, SPCR2);
OMAP_MCBSP_WRITE(io_base, SPCR2, w | (1 << 7));
}
if (cpu_is_omap2430() || cpu_is_omap34xx()) {
/* Release the transmitter and receiver */
w = OMAP_MCBSP_READ(io_base, XCCR);
w &= ~(tx ? XDISABLE : 0);
OMAP_MCBSP_WRITE(io_base, XCCR, w);
w = OMAP_MCBSP_READ(io_base, RCCR);
w &= ~(rx ? RDISABLE : 0);
OMAP_MCBSP_WRITE(io_base, RCCR, w);
}
/* Dump McBSP Regs */ /* Dump McBSP Regs */
omap_mcbsp_dump_reg(id); omap_mcbsp_dump_reg(id);
} }
EXPORT_SYMBOL(omap_mcbsp_start); EXPORT_SYMBOL(omap_mcbsp_start);
void omap_mcbsp_stop(unsigned int id) void omap_mcbsp_stop(unsigned int id, int tx, int rx)
{ {
struct omap_mcbsp *mcbsp; struct omap_mcbsp *mcbsp;
void __iomem *io_base; void __iomem *io_base;
int idle;
u16 w; u16 w;
if (!omap_mcbsp_check_valid_id(id)) { if (!omap_mcbsp_check_valid_id(id)) {
...@@ -385,16 +582,33 @@ void omap_mcbsp_stop(unsigned int id) ...@@ -385,16 +582,33 @@ void omap_mcbsp_stop(unsigned int id)
io_base = mcbsp->io_base; io_base = mcbsp->io_base;
/* Reset transmitter */ /* Reset transmitter */
tx &= 1;
if (cpu_is_omap2430() || cpu_is_omap34xx()) {
w = OMAP_MCBSP_READ(io_base, XCCR);
w |= (tx ? XDISABLE : 0);
OMAP_MCBSP_WRITE(io_base, XCCR, w);
}
w = OMAP_MCBSP_READ(io_base, SPCR2); w = OMAP_MCBSP_READ(io_base, SPCR2);
OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~(1)); OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~tx);
/* Reset receiver */ /* Reset receiver */
rx &= 1;
if (cpu_is_omap2430() || cpu_is_omap34xx()) {
w = OMAP_MCBSP_READ(io_base, RCCR);
w |= (tx ? RDISABLE : 0);
OMAP_MCBSP_WRITE(io_base, RCCR, w);
}
w = OMAP_MCBSP_READ(io_base, SPCR1); w = OMAP_MCBSP_READ(io_base, SPCR1);
OMAP_MCBSP_WRITE(io_base, SPCR1, w & ~(1)); OMAP_MCBSP_WRITE(io_base, SPCR1, w & ~rx);
/* Reset the sample rate generator */ idle = !((OMAP_MCBSP_READ(io_base, SPCR2) |
w = OMAP_MCBSP_READ(io_base, SPCR2); OMAP_MCBSP_READ(io_base, SPCR1)) & 1);
OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~(1 << 6));
if (idle) {
/* Reset the sample rate generator */
w = OMAP_MCBSP_READ(io_base, SPCR2);
OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~(1 << 6));
}
} }
EXPORT_SYMBOL(omap_mcbsp_stop); EXPORT_SYMBOL(omap_mcbsp_stop);
...@@ -883,6 +1097,149 @@ void omap_mcbsp_set_spi_mode(unsigned int id, ...@@ -883,6 +1097,149 @@ void omap_mcbsp_set_spi_mode(unsigned int id,
} }
EXPORT_SYMBOL(omap_mcbsp_set_spi_mode); EXPORT_SYMBOL(omap_mcbsp_set_spi_mode);
#ifdef CONFIG_ARCH_OMAP34XX
#define max_thres(m) (mcbsp->pdata->buffer_size)
#define valid_threshold(m, val) ((val) <= max_thres(m))
#define THRESHOLD_PROP_BUILDER(prop) \
static ssize_t prop##_show(struct device *dev, \
struct device_attribute *attr, char *buf) \
{ \
struct omap_mcbsp *mcbsp = dev_get_drvdata(dev); \
\
return sprintf(buf, "%u\n", mcbsp->prop); \
} \
\
static ssize_t prop##_store(struct device *dev, \
struct device_attribute *attr, \
const char *buf, size_t size) \
{ \
struct omap_mcbsp *mcbsp = dev_get_drvdata(dev); \
unsigned long val; \
int status; \
\
status = strict_strtoul(buf, 0, &val); \
if (status) \
return status; \
\
if (!valid_threshold(mcbsp, val)) \
return -EDOM; \
\
mcbsp->prop = val; \
return size; \
} \
\
static DEVICE_ATTR(prop, 0644, prop##_show, prop##_store);
THRESHOLD_PROP_BUILDER(max_tx_thres);
THRESHOLD_PROP_BUILDER(max_rx_thres);
static const char *dma_op_modes[] = {
"element", "threshold", "frame",
};
static ssize_t dma_op_mode_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct omap_mcbsp *mcbsp = dev_get_drvdata(dev);
int dma_op_mode, i = 0;
ssize_t len = 0;
const char * const *s;
spin_lock_irq(&mcbsp->lock);
dma_op_mode = mcbsp->dma_op_mode;
spin_unlock_irq(&mcbsp->lock);
for (s = &dma_op_modes[i]; i < ARRAY_SIZE(dma_op_modes); s++, i++) {
if (dma_op_mode == i)
len += sprintf(buf + len, "[%s] ", *s);
else
len += sprintf(buf + len, "%s ", *s);
}
len += sprintf(buf + len, "\n");
return len;
}
static ssize_t dma_op_mode_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t size)
{
struct omap_mcbsp *mcbsp = dev_get_drvdata(dev);
const char * const *s;
int i = 0;
for (s = &dma_op_modes[i]; i < ARRAY_SIZE(dma_op_modes); s++, i++)
if (sysfs_streq(buf, *s))
break;
if (i == ARRAY_SIZE(dma_op_modes))
return -EINVAL;
spin_lock_irq(&mcbsp->lock);
if (!mcbsp->free) {
size = -EBUSY;
goto unlock;
}
mcbsp->dma_op_mode = i;
unlock:
spin_unlock_irq(&mcbsp->lock);
return size;
}
static DEVICE_ATTR(dma_op_mode, 0644, dma_op_mode_show, dma_op_mode_store);
static const struct attribute *additional_attrs[] = {
&dev_attr_max_tx_thres.attr,
&dev_attr_max_rx_thres.attr,
&dev_attr_dma_op_mode.attr,
NULL,
};
static const struct attribute_group additional_attr_group = {
.attrs = (struct attribute **)additional_attrs,
};
static inline int __devinit omap_additional_add(struct device *dev)
{
return sysfs_create_group(&dev->kobj, &additional_attr_group);
}
static inline void __devexit omap_additional_remove(struct device *dev)
{
sysfs_remove_group(&dev->kobj, &additional_attr_group);
}
static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp)
{
mcbsp->dma_op_mode = MCBSP_DMA_MODE_ELEMENT;
if (cpu_is_omap34xx()) {
mcbsp->max_tx_thres = max_thres(mcbsp);
mcbsp->max_rx_thres = max_thres(mcbsp);
/*
* REVISIT: Set dmap_op_mode to THRESHOLD as default
* for mcbsp2 instances.
*/
if (omap_additional_add(mcbsp->dev))
dev_warn(mcbsp->dev,
"Unable to create additional controls\n");
} else {
mcbsp->max_tx_thres = -EINVAL;
mcbsp->max_rx_thres = -EINVAL;
}
}
static inline void __devexit omap34xx_device_exit(struct omap_mcbsp *mcbsp)
{
if (cpu_is_omap34xx())
omap_additional_remove(mcbsp->dev);
}
#else
static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp) {}
static inline void __devexit omap34xx_device_exit(struct omap_mcbsp *mcbsp) {}
#endif /* CONFIG_ARCH_OMAP34XX */
/* /*
* McBSP1 and McBSP3 are directly mapped on 1610 and 1510. * McBSP1 and McBSP3 are directly mapped on 1610 and 1510.
* 730 has only 2 McBSP, and both of them are MPU peripherals. * 730 has only 2 McBSP, and both of them are MPU peripherals.
...@@ -953,6 +1310,10 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev) ...@@ -953,6 +1310,10 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev)
mcbsp->dev = &pdev->dev; mcbsp->dev = &pdev->dev;
mcbsp_ptr[id] = mcbsp; mcbsp_ptr[id] = mcbsp;
platform_set_drvdata(pdev, mcbsp); platform_set_drvdata(pdev, mcbsp);
/* Initialize mcbsp properties for OMAP34XX if needed / applicable */
omap34xx_device_init(mcbsp);
return 0; return 0;
err_fclk: err_fclk:
...@@ -976,6 +1337,8 @@ static int __devexit omap_mcbsp_remove(struct platform_device *pdev) ...@@ -976,6 +1337,8 @@ static int __devexit omap_mcbsp_remove(struct platform_device *pdev)
mcbsp->pdata->ops->free) mcbsp->pdata->ops->free)
mcbsp->pdata->ops->free(mcbsp->id); mcbsp->pdata->ops->free(mcbsp->id);
omap34xx_device_exit(mcbsp);
clk_disable(mcbsp->fclk); clk_disable(mcbsp->fclk);
clk_disable(mcbsp->iclk); clk_disable(mcbsp->iclk);
clk_put(mcbsp->fclk); clk_put(mcbsp->fclk);
......
/* arch/arm/plat-s3c/include/plat/audio-simtec.h
*
* Copyright 2008 Simtec Electronics
* http://armlinux.simtec.co.uk/
* Ben Dooks <ben@simtec.co.uk>
*
* 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.
*
* Simtec Audio support.
*/
/**
* struct s3c24xx_audio_simtec_pdata - platform data for simtec audio
* @use_mpllin: Select codec clock from MPLLin
* @output_cdclk: Need to output CDCLK to the codec
* @have_mic: Set if we have a MIC socket
* @have_lout: Set if we have a LineOut socket
* @amp_gpio: GPIO pin to enable the AMP
* @amp_gain: Option GPIO to control AMP gain
*/
struct s3c24xx_audio_simtec_pdata {
unsigned int use_mpllin:1;
unsigned int output_cdclk:1;
unsigned int have_mic:1;
unsigned int have_lout:1;
int amp_gpio;
int amp_gain[2];
void (*startup)(void);
};
extern int simtec_audio_add(const char *codec_name,
struct s3c24xx_audio_simtec_pdata *pdata);
...@@ -33,6 +33,11 @@ ...@@ -33,6 +33,11 @@
#define S3C2412_IISCON_RXDMA_ACTIVE (1 << 1) #define S3C2412_IISCON_RXDMA_ACTIVE (1 << 1)
#define S3C2412_IISCON_IIS_ACTIVE (1 << 0) #define S3C2412_IISCON_IIS_ACTIVE (1 << 0)
#define S3C64XX_IISMOD_BLC_16BIT (0 << 13)
#define S3C64XX_IISMOD_BLC_8BIT (1 << 13)
#define S3C64XX_IISMOD_BLC_24BIT (2 << 13)
#define S3C64XX_IISMOD_BLC_MASK (3 << 13)
#define S3C64XX_IISMOD_IMS_PCLK (0 << 10) #define S3C64XX_IISMOD_IMS_PCLK (0 << 10)
#define S3C64XX_IISMOD_IMS_SYSMUX (1 << 10) #define S3C64XX_IISMOD_IMS_SYSMUX (1 << 10)
......
...@@ -238,8 +238,10 @@ int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, ...@@ -238,8 +238,10 @@ int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count,
} }
/** /**
* register_chrdev() - Register a major number for character devices. * __register_chrdev() - create and register a cdev occupying a range of minors
* @major: major device number or 0 for dynamic allocation * @major: major device number or 0 for dynamic allocation
* @baseminor: first of the requested range of minor numbers
* @count: the number of minor numbers required
* @name: name of this range of devices * @name: name of this range of devices
* @fops: file operations associated with this devices * @fops: file operations associated with this devices
* *
...@@ -255,19 +257,17 @@ int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, ...@@ -255,19 +257,17 @@ int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count,
* /dev. It only helps to keep track of the different owners of devices. If * /dev. It only helps to keep track of the different owners of devices. If
* your module name has only one type of devices it's ok to use e.g. the name * your module name has only one type of devices it's ok to use e.g. the name
* of the module here. * of the module here.
*
* This function registers a range of 256 minor numbers. The first minor number
* is 0.
*/ */
int register_chrdev(unsigned int major, const char *name, int __register_chrdev(unsigned int major, unsigned int baseminor,
const struct file_operations *fops) unsigned int count, const char *name,
const struct file_operations *fops)
{ {
struct char_device_struct *cd; struct char_device_struct *cd;
struct cdev *cdev; struct cdev *cdev;
char *s; char *s;
int err = -ENOMEM; int err = -ENOMEM;
cd = __register_chrdev_region(major, 0, 256, name); cd = __register_chrdev_region(major, baseminor, count, name);
if (IS_ERR(cd)) if (IS_ERR(cd))
return PTR_ERR(cd); return PTR_ERR(cd);
...@@ -281,7 +281,7 @@ int register_chrdev(unsigned int major, const char *name, ...@@ -281,7 +281,7 @@ int register_chrdev(unsigned int major, const char *name,
for (s = strchr(kobject_name(&cdev->kobj),'/'); s; s = strchr(s, '/')) for (s = strchr(kobject_name(&cdev->kobj),'/'); s; s = strchr(s, '/'))
*s = '!'; *s = '!';
err = cdev_add(cdev, MKDEV(cd->major, 0), 256); err = cdev_add(cdev, MKDEV(cd->major, baseminor), count);
if (err) if (err)
goto out; goto out;
...@@ -291,7 +291,7 @@ int register_chrdev(unsigned int major, const char *name, ...@@ -291,7 +291,7 @@ int register_chrdev(unsigned int major, const char *name,
out: out:
kobject_put(&cdev->kobj); kobject_put(&cdev->kobj);
out2: out2:
kfree(__unregister_chrdev_region(cd->major, 0, 256)); kfree(__unregister_chrdev_region(cd->major, baseminor, count));
return err; return err;
} }
...@@ -317,10 +317,23 @@ void unregister_chrdev_region(dev_t from, unsigned count) ...@@ -317,10 +317,23 @@ void unregister_chrdev_region(dev_t from, unsigned count)
} }
} }
void unregister_chrdev(unsigned int major, const char *name) /**
* __unregister_chrdev - unregister and destroy a cdev
* @major: major device number
* @baseminor: first of the range of minor numbers
* @count: the number of minor numbers this cdev is occupying
* @name: name of this range of devices
*
* Unregister and destroy the cdev occupying the region described by
* @major, @baseminor and @count. This function undoes what
* __register_chrdev() did.
*/
void __unregister_chrdev(unsigned int major, unsigned int baseminor,
unsigned int count, const char *name)
{ {
struct char_device_struct *cd; struct char_device_struct *cd;
cd = __unregister_chrdev_region(major, 0, 256);
cd = __unregister_chrdev_region(major, baseminor, count);
if (cd && cd->cdev) if (cd && cd->cdev)
cdev_del(cd->cdev); cdev_del(cd->cdev);
kfree(cd); kfree(cd);
...@@ -569,6 +582,6 @@ EXPORT_SYMBOL(cdev_alloc); ...@@ -569,6 +582,6 @@ EXPORT_SYMBOL(cdev_alloc);
EXPORT_SYMBOL(cdev_del); EXPORT_SYMBOL(cdev_del);
EXPORT_SYMBOL(cdev_add); EXPORT_SYMBOL(cdev_add);
EXPORT_SYMBOL(cdev_index); EXPORT_SYMBOL(cdev_index);
EXPORT_SYMBOL(register_chrdev); EXPORT_SYMBOL(__register_chrdev);
EXPORT_SYMBOL(unregister_chrdev); EXPORT_SYMBOL(__unregister_chrdev);
EXPORT_SYMBOL(directly_mappable_cdev_bdi); EXPORT_SYMBOL(directly_mappable_cdev_bdi);
...@@ -1997,12 +1997,25 @@ extern void bd_release_from_disk(struct block_device *, struct gendisk *); ...@@ -1997,12 +1997,25 @@ extern void bd_release_from_disk(struct block_device *, struct gendisk *);
#define CHRDEV_MAJOR_HASH_SIZE 255 #define CHRDEV_MAJOR_HASH_SIZE 255
extern int alloc_chrdev_region(dev_t *, unsigned, unsigned, const char *); extern int alloc_chrdev_region(dev_t *, unsigned, unsigned, const char *);
extern int register_chrdev_region(dev_t, unsigned, const char *); extern int register_chrdev_region(dev_t, unsigned, const char *);
extern int register_chrdev(unsigned int, const char *, extern int __register_chrdev(unsigned int major, unsigned int baseminor,
const struct file_operations *); unsigned int count, const char *name,
extern void unregister_chrdev(unsigned int, const char *); const struct file_operations *fops);
extern void __unregister_chrdev(unsigned int major, unsigned int baseminor,
unsigned int count, const char *name);
extern void unregister_chrdev_region(dev_t, unsigned); extern void unregister_chrdev_region(dev_t, unsigned);
extern void chrdev_show(struct seq_file *,off_t); extern void chrdev_show(struct seq_file *,off_t);
static inline int register_chrdev(unsigned int major, const char *name,
const struct file_operations *fops)
{
return __register_chrdev(major, 0, 256, name, fops);
}
static inline void unregister_chrdev(unsigned int major, const char *name)
{
__unregister_chrdev(major, 0, 256, name);
}
/* fs/block_dev.c */ /* fs/block_dev.c */
#define BDEVNAME_SIZE 32 /* Largest string for a blockdev identifier */ #define BDEVNAME_SIZE 32 /* Largest string for a blockdev identifier */
#define BDEVT_SIZE 10 /* Largest string for MAJ:MIN for blkdev */ #define BDEVT_SIZE 10 /* Largest string for MAJ:MIN for blkdev */
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
*/ */
#define NR_UNIX98_PTY_DEFAULT 4096 /* Default maximum for Unix98 ptys */ #define NR_UNIX98_PTY_DEFAULT 4096 /* Default maximum for Unix98 ptys */
#define NR_UNIX98_PTY_MAX (1 << MINORBITS) /* Absolute limit */ #define NR_UNIX98_PTY_MAX (1 << MINORBITS) /* Absolute limit */
#define NR_LDISCS 19 #define NR_LDISCS 20
/* line disciplines */ /* line disciplines */
#define N_TTY 0 #define N_TTY 0
...@@ -47,6 +47,8 @@ ...@@ -47,6 +47,8 @@
#define N_SLCAN 17 /* Serial / USB serial CAN Adaptors */ #define N_SLCAN 17 /* Serial / USB serial CAN Adaptors */
#define N_PPS 18 /* Pulse per Second */ #define N_PPS 18 /* Pulse per Second */
#define N_V253 19 /* Codec control over voice modem */
/* /*
* This character is the same as _POSIX_VDISABLE: it cannot be used as * This character is the same as _POSIX_VDISABLE: it cannot be used as
* a c_cc[] character, but indicates that a particular special character * a c_cc[] character, but indicates that a particular special character
......
...@@ -32,6 +32,9 @@ ...@@ -32,6 +32,9 @@
#include "control.h" #include "control.h"
#include "info.h" #include "info.h"
/* maximum number of devices on the AC97 bus */
#define AC97_BUS_MAX_DEVICES 4
/* /*
* AC'97 codec registers * AC'97 codec registers
*/ */
...@@ -642,4 +645,10 @@ int snd_ac97_pcm_double_rate_rules(struct snd_pcm_runtime *runtime); ...@@ -642,4 +645,10 @@ int snd_ac97_pcm_double_rate_rules(struct snd_pcm_runtime *runtime);
/* ad hoc AC97 device driver access */ /* ad hoc AC97 device driver access */
extern struct bus_type ac97_bus_type; extern struct bus_type ac97_bus_type;
/* AC97 platform_data adding function */
static inline void snd_ac97_dev_add_pdata(struct snd_ac97 *ac97, void *data)
{
ac97->dev.platform_data = data;
}
#endif /* __SOUND_AC97_CODEC_H */ #endif /* __SOUND_AC97_CODEC_H */
...@@ -138,7 +138,7 @@ struct snd_hwdep_dsp_image { ...@@ -138,7 +138,7 @@ struct snd_hwdep_dsp_image {
* * * *
*****************************************************************************/ *****************************************************************************/
#define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 9) #define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 10)
typedef unsigned long snd_pcm_uframes_t; typedef unsigned long snd_pcm_uframes_t;
typedef signed long snd_pcm_sframes_t; typedef signed long snd_pcm_sframes_t;
......
...@@ -93,15 +93,6 @@ struct snd_device { ...@@ -93,15 +93,6 @@ struct snd_device {
#define snd_device(n) list_entry(n, struct snd_device, list) #define snd_device(n) list_entry(n, struct snd_device, list)
/* monitor files for graceful shutdown (hotplug) */
struct snd_monitor_file {
struct file *file;
const struct file_operations *disconnected_f_op;
struct list_head shutdown_list; /* still need to shutdown */
struct list_head list; /* link of monitor files */
};
/* main structure for soundcard */ /* main structure for soundcard */
struct snd_card { struct snd_card {
...@@ -311,9 +302,7 @@ int snd_component_add(struct snd_card *card, const char *component); ...@@ -311,9 +302,7 @@ int snd_component_add(struct snd_card *card, const char *component);
int snd_card_file_add(struct snd_card *card, struct file *file); int snd_card_file_add(struct snd_card *card, struct file *file);
int snd_card_file_remove(struct snd_card *card, struct file *file); int snd_card_file_remove(struct snd_card *card, struct file *file);
#ifndef snd_card_set_dev
#define snd_card_set_dev(card, devptr) ((card)->dev = (devptr)) #define snd_card_set_dev(card, devptr) ((card)->dev = (devptr))
#endif
/* device.c */ /* device.c */
...@@ -340,18 +329,17 @@ unsigned int snd_dma_pointer(unsigned long dma, unsigned int size); ...@@ -340,18 +329,17 @@ unsigned int snd_dma_pointer(unsigned long dma, unsigned int size);
struct resource; struct resource;
void release_and_free_resource(struct resource *res); void release_and_free_resource(struct resource *res);
#ifdef CONFIG_SND_VERBOSE_PRINTK
void snd_verbose_printk(const char *file, int line, const char *format, ...)
__attribute__ ((format (printf, 3, 4)));
#endif
#if defined(CONFIG_SND_DEBUG) && defined(CONFIG_SND_VERBOSE_PRINTK)
void snd_verbose_printd(const char *file, int line, const char *format, ...)
__attribute__ ((format (printf, 3, 4)));
#endif
/* --- */ /* --- */
#ifdef CONFIG_SND_VERBOSE_PRINTK #if defined(CONFIG_SND_DEBUG) || defined(CONFIG_SND_VERBOSE_PRINTK)
void __snd_printk(unsigned int level, const char *file, int line,
const char *format, ...)
__attribute__ ((format (printf, 4, 5)));
#else
#define __snd_printk(level, file, line, format, args...) \
printk(format, ##args)
#endif
/** /**
* snd_printk - printk wrapper * snd_printk - printk wrapper
* @fmt: format string * @fmt: format string
...@@ -360,15 +348,9 @@ void snd_verbose_printd(const char *file, int line, const char *format, ...) ...@@ -360,15 +348,9 @@ void snd_verbose_printd(const char *file, int line, const char *format, ...)
* when configured with CONFIG_SND_VERBOSE_PRINTK. * when configured with CONFIG_SND_VERBOSE_PRINTK.
*/ */
#define snd_printk(fmt, args...) \ #define snd_printk(fmt, args...) \
snd_verbose_printk(__FILE__, __LINE__, fmt ,##args) __snd_printk(0, __FILE__, __LINE__, fmt, ##args)
#else
#define snd_printk(fmt, args...) \
printk(fmt ,##args)
#endif
#ifdef CONFIG_SND_DEBUG #ifdef CONFIG_SND_DEBUG
#ifdef CONFIG_SND_VERBOSE_PRINTK
/** /**
* snd_printd - debug printk * snd_printd - debug printk
* @fmt: format string * @fmt: format string
...@@ -377,11 +359,7 @@ void snd_verbose_printd(const char *file, int line, const char *format, ...) ...@@ -377,11 +359,7 @@ void snd_verbose_printd(const char *file, int line, const char *format, ...)
* Ignored when CONFIG_SND_DEBUG is not set. * Ignored when CONFIG_SND_DEBUG is not set.
*/ */
#define snd_printd(fmt, args...) \ #define snd_printd(fmt, args...) \
snd_verbose_printd(__FILE__, __LINE__, fmt ,##args) __snd_printk(1, __FILE__, __LINE__, fmt, ##args)
#else
#define snd_printd(fmt, args...) \
printk(fmt ,##args)
#endif
/** /**
* snd_BUG - give a BUG warning message and stack trace * snd_BUG - give a BUG warning message and stack trace
...@@ -428,9 +406,10 @@ static inline int __snd_bug_on(int cond) ...@@ -428,9 +406,10 @@ static inline int __snd_bug_on(int cond)
* Works like snd_printk() for debugging purposes. * Works like snd_printk() for debugging purposes.
* Ignored when CONFIG_SND_DEBUG_VERBOSE is not set. * Ignored when CONFIG_SND_DEBUG_VERBOSE is not set.
*/ */
#define snd_printdd(format, args...) snd_printk(format, ##args) #define snd_printdd(format, args...) \
__snd_printk(2, __FILE__, __LINE__, format, ##args)
#else #else
#define snd_printdd(format, args...) /* nothing */ #define snd_printdd(format, args...) do { } while (0)
#endif #endif
...@@ -438,12 +417,10 @@ static inline int __snd_bug_on(int cond) ...@@ -438,12 +417,10 @@ static inline int __snd_bug_on(int cond)
/* for easier backward-porting */ /* for easier backward-porting */
#if defined(CONFIG_GAMEPORT) || defined(CONFIG_GAMEPORT_MODULE) #if defined(CONFIG_GAMEPORT) || defined(CONFIG_GAMEPORT_MODULE)
#ifndef gameport_set_dev_parent
#define gameport_set_dev_parent(gp,xdev) ((gp)->dev.parent = (xdev)) #define gameport_set_dev_parent(gp,xdev) ((gp)->dev.parent = (xdev))
#define gameport_set_port_data(gp,r) ((gp)->port_data = (r)) #define gameport_set_port_data(gp,r) ((gp)->port_data = (r))
#define gameport_get_port_data(gp) (gp)->port_data #define gameport_get_port_data(gp) (gp)->port_data
#endif #endif
#endif
/* PCI quirk list helper */ /* PCI quirk list helper */
struct snd_pci_quirk { struct snd_pci_quirk {
......
...@@ -110,13 +110,13 @@ void snd_card_info_read_oss(struct snd_info_buffer *buffer); ...@@ -110,13 +110,13 @@ void snd_card_info_read_oss(struct snd_info_buffer *buffer);
static inline void snd_card_info_read_oss(struct snd_info_buffer *buffer) {} static inline void snd_card_info_read_oss(struct snd_info_buffer *buffer) {}
#endif #endif
int snd_iprintf(struct snd_info_buffer *buffer, char *fmt, ...) \ int snd_iprintf(struct snd_info_buffer *buffer, const char *fmt, ...) \
__attribute__ ((format (printf, 2, 3))); __attribute__ ((format (printf, 2, 3)));
int snd_info_init(void); int snd_info_init(void);
int snd_info_done(void); int snd_info_done(void);
int snd_info_get_line(struct snd_info_buffer *buffer, char *line, int len); int snd_info_get_line(struct snd_info_buffer *buffer, char *line, int len);
char *snd_info_get_str(char *dest, char *src, int len); const char *snd_info_get_str(char *dest, const char *src, int len);
struct snd_info_entry *snd_info_create_module_entry(struct module *module, struct snd_info_entry *snd_info_create_module_entry(struct module *module,
const char *name, const char *name,
struct snd_info_entry *parent); struct snd_info_entry *parent);
......
...@@ -47,7 +47,11 @@ struct snd_dma_device { ...@@ -47,7 +47,11 @@ struct snd_dma_device {
#define SNDRV_DMA_TYPE_UNKNOWN 0 /* not defined */ #define SNDRV_DMA_TYPE_UNKNOWN 0 /* not defined */
#define SNDRV_DMA_TYPE_CONTINUOUS 1 /* continuous no-DMA memory */ #define SNDRV_DMA_TYPE_CONTINUOUS 1 /* continuous no-DMA memory */
#define SNDRV_DMA_TYPE_DEV 2 /* generic device continuous */ #define SNDRV_DMA_TYPE_DEV 2 /* generic device continuous */
#ifdef CONFIG_SND_DMA_SGBUF
#define SNDRV_DMA_TYPE_DEV_SG 3 /* generic device SG-buffer */ #define SNDRV_DMA_TYPE_DEV_SG 3 /* generic device SG-buffer */
#else
#define SNDRV_DMA_TYPE_DEV_SG SNDRV_DMA_TYPE_DEV /* no SG-buf support */
#endif
/* /*
* info for buffer allocation * info for buffer allocation
...@@ -60,6 +64,7 @@ struct snd_dma_buffer { ...@@ -60,6 +64,7 @@ struct snd_dma_buffer {
void *private_data; /* private for allocator; don't touch */ void *private_data; /* private for allocator; don't touch */
}; };
#ifdef CONFIG_SND_DMA_SGBUF
/* /*
* Scatter-Gather generic device pages * Scatter-Gather generic device pages
*/ */
...@@ -107,6 +112,7 @@ static inline void *snd_sgbuf_get_ptr(struct snd_sg_buf *sgbuf, size_t offset) ...@@ -107,6 +112,7 @@ 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; return sgbuf->table[offset >> PAGE_SHIFT].buf + offset % PAGE_SIZE;
} }
#endif /* CONFIG_SND_DMA_SGBUF */
/* allocate/release a buffer */ /* allocate/release a buffer */
int snd_dma_alloc_pages(int type, struct device *dev, size_t size, int snd_dma_alloc_pages(int type, struct device *dev, size_t size,
......
...@@ -902,6 +902,7 @@ int snd_pcm_lib_preallocate_pages_for_all(struct snd_pcm *pcm, ...@@ -902,6 +902,7 @@ 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_malloc_pages(struct snd_pcm_substream *substream, size_t size);
int snd_pcm_lib_free_pages(struct snd_pcm_substream *substream); int snd_pcm_lib_free_pages(struct snd_pcm_substream *substream);
#ifdef CONFIG_SND_DMA_SGBUF
/* /*
* SG-buffer handling * SG-buffer handling
*/ */
...@@ -927,6 +928,28 @@ struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream, ...@@ -927,6 +928,28 @@ struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream,
unsigned int snd_pcm_sgbuf_get_chunk_size(struct snd_pcm_substream *substream, unsigned int snd_pcm_sgbuf_get_chunk_size(struct snd_pcm_substream *substream,
unsigned int ofs, unsigned int size); unsigned int ofs, unsigned int size);
#else /* !SND_DMA_SGBUF */
/*
* fake using a continuous buffer
*/
static inline dma_addr_t
snd_pcm_sgbuf_get_addr(struct snd_pcm_substream *substream, unsigned int ofs)
{
return substream->runtime->dma_addr + ofs;
}
static inline void *
snd_pcm_sgbuf_get_ptr(struct snd_pcm_substream *substream, unsigned int ofs)
{
return substream->runtime->dma_area + ofs;
}
#define snd_pcm_sgbuf_ops_page NULL
#define snd_pcm_sgbuf_get_chunk_size(subs, ofs, size) (size)
#endif /* SND_DMA_SGBUF */
/* handle mmap counter - PCM mmap callback should handle this counter properly */ /* handle mmap counter - PCM mmap callback should handle this counter properly */
static inline void snd_pcm_mmap_data_open(struct vm_area_struct *area) static inline void snd_pcm_mmap_data_open(struct vm_area_struct *area)
{ {
...@@ -965,4 +988,6 @@ static inline void snd_pcm_limit_isa_dma_size(int dma, size_t *max) ...@@ -965,4 +988,6 @@ static inline void snd_pcm_limit_isa_dma_size(int dma, size_t *max)
#define PCM_RUNTIME_CHECK(sub) snd_BUG_ON(!(sub) || !(sub)->runtime) #define PCM_RUNTIME_CHECK(sub) snd_BUG_ON(!(sub) || !(sub)->runtime)
const char *snd_pcm_format_name(snd_pcm_format_t format);
#endif /* __SOUND_PCM_H */ #endif /* __SOUND_PCM_H */
#ifndef __SOUND_FSI_H
#define __SOUND_FSI_H
/*
* Fifo-attached Serial Interface (FSI) support for SH7724
*
* Copyright (C) 2009 Renesas Solutions Corp.
* Kuninori Morimoto <morimoto.kuninori@renesas.com>
*
* 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.
*/
/* flags format
* 0xABCDEEFF
*
* A: channel size for TDM (input)
* B: channel size for TDM (ooutput)
* C: inversion
* D: mode
* E: input format
* F: output format
*/
#include <linux/clk.h>
#include <sound/soc.h>
/* TDM channel */
#define SH_FSI_SET_CH_I(x) ((x & 0xF) << 28)
#define SH_FSI_SET_CH_O(x) ((x & 0xF) << 24)
#define SH_FSI_CH_IMASK 0xF0000000
#define SH_FSI_CH_OMASK 0x0F000000
#define SH_FSI_GET_CH_I(x) ((x & SH_FSI_CH_IMASK) >> 28)
#define SH_FSI_GET_CH_O(x) ((x & SH_FSI_CH_OMASK) >> 24)
/* clock inversion */
#define SH_FSI_INVERSION_MASK 0x00F00000
#define SH_FSI_LRM_INV (1 << 20)
#define SH_FSI_BRM_INV (1 << 21)
#define SH_FSI_LRS_INV (1 << 22)
#define SH_FSI_BRS_INV (1 << 23)
/* mode */
#define SH_FSI_MODE_MASK 0x000F0000
#define SH_FSI_IN_SLAVE_MODE (1 << 16) /* default master mode */
#define SH_FSI_OUT_SLAVE_MODE (1 << 17) /* default master mode */
/* DI format */
#define SH_FSI_FMT_MASK 0x000000FF
#define SH_FSI_IFMT(x) (((SH_FSI_FMT_ ## x) & SH_FSI_FMT_MASK) << 8)
#define SH_FSI_OFMT(x) (((SH_FSI_FMT_ ## x) & SH_FSI_FMT_MASK) << 0)
#define SH_FSI_GET_IFMT(x) ((x >> 8) & SH_FSI_FMT_MASK)
#define SH_FSI_GET_OFMT(x) ((x >> 0) & SH_FSI_FMT_MASK)
#define SH_FSI_FMT_MONO (1 << 0)
#define SH_FSI_FMT_MONO_DELAY (1 << 1)
#define SH_FSI_FMT_PCM (1 << 2)
#define SH_FSI_FMT_I2S (1 << 3)
#define SH_FSI_FMT_TDM (1 << 4)
#define SH_FSI_FMT_TDM_DELAY (1 << 5)
#define SH_FSI_IFMT_TDM_CH(x) \
(SH_FSI_IFMT(TDM) | SH_FSI_SET_CH_I(x))
#define SH_FSI_IFMT_TDM_DELAY_CH(x) \
(SH_FSI_IFMT(TDM_DELAY) | SH_FSI_SET_CH_I(x))
#define SH_FSI_OFMT_TDM_CH(x) \
(SH_FSI_OFMT(TDM) | SH_FSI_SET_CH_O(x))
#define SH_FSI_OFMT_TDM_DELAY_CH(x) \
(SH_FSI_OFMT(TDM_DELAY) | SH_FSI_SET_CH_O(x))
struct sh_fsi_platform_info {
unsigned long porta_flags;
unsigned long portb_flags;
};
extern struct snd_soc_dai fsi_soc_dai[2];
extern struct snd_soc_platform fsi_soc_platform;
#endif /* __SOUND_FSI_H */
...@@ -27,8 +27,8 @@ struct snd_pcm_substream; ...@@ -27,8 +27,8 @@ struct snd_pcm_substream;
#define SND_SOC_DAIFMT_I2S 0 /* I2S mode */ #define SND_SOC_DAIFMT_I2S 0 /* I2S mode */
#define SND_SOC_DAIFMT_RIGHT_J 1 /* Right Justified mode */ #define SND_SOC_DAIFMT_RIGHT_J 1 /* Right Justified mode */
#define SND_SOC_DAIFMT_LEFT_J 2 /* Left Justified mode */ #define SND_SOC_DAIFMT_LEFT_J 2 /* Left Justified mode */
#define SND_SOC_DAIFMT_DSP_A 3 /* L data msb after FRM LRC */ #define SND_SOC_DAIFMT_DSP_A 3 /* L data MSB after FRM LRC */
#define SND_SOC_DAIFMT_DSP_B 4 /* L data msb during FRM LRC */ #define SND_SOC_DAIFMT_DSP_B 4 /* L data MSB during FRM LRC */
#define SND_SOC_DAIFMT_AC97 5 /* AC97 */ #define SND_SOC_DAIFMT_AC97 5 /* AC97 */
/* left and right justified also known as MSB and LSB respectively */ /* left and right justified also known as MSB and LSB respectively */
...@@ -38,7 +38,7 @@ struct snd_pcm_substream; ...@@ -38,7 +38,7 @@ struct snd_pcm_substream;
/* /*
* DAI Clock gating. * DAI Clock gating.
* *
* DAI bit clocks can be be gated (disabled) when not the DAI is not * DAI bit clocks can be be gated (disabled) when the DAI is not
* sending or receiving PCM data in a frame. This can be used to save power. * sending or receiving PCM data in a frame. This can be used to save power.
*/ */
#define SND_SOC_DAIFMT_CONT (0 << 4) /* continuous clock */ #define SND_SOC_DAIFMT_CONT (0 << 4) /* continuous clock */
...@@ -51,21 +51,21 @@ struct snd_pcm_substream; ...@@ -51,21 +51,21 @@ struct snd_pcm_substream;
* format. * format.
*/ */
#define SND_SOC_DAIFMT_NB_NF (0 << 8) /* normal bit clock + frame */ #define SND_SOC_DAIFMT_NB_NF (0 << 8) /* normal bit clock + frame */
#define SND_SOC_DAIFMT_NB_IF (1 << 8) /* normal bclk + inv frm */ #define SND_SOC_DAIFMT_NB_IF (1 << 8) /* normal BCLK + inv FRM */
#define SND_SOC_DAIFMT_IB_NF (2 << 8) /* invert bclk + nor frm */ #define SND_SOC_DAIFMT_IB_NF (2 << 8) /* invert BCLK + nor FRM */
#define SND_SOC_DAIFMT_IB_IF (3 << 8) /* invert bclk + frm */ #define SND_SOC_DAIFMT_IB_IF (3 << 8) /* invert BCLK + FRM */
/* /*
* DAI hardware clock masters. * DAI hardware clock masters.
* *
* This is wrt the codec, the inverse is true for the interface * This is wrt the codec, the inverse is true for the interface
* i.e. if the codec is clk and frm master then the interface is * i.e. if the codec is clk and FRM master then the interface is
* clk and frame slave. * clk and frame slave.
*/ */
#define SND_SOC_DAIFMT_CBM_CFM (0 << 12) /* codec clk & frm master */ #define SND_SOC_DAIFMT_CBM_CFM (0 << 12) /* codec clk & FRM master */
#define SND_SOC_DAIFMT_CBS_CFM (1 << 12) /* codec clk slave & frm master */ #define SND_SOC_DAIFMT_CBS_CFM (1 << 12) /* codec clk slave & FRM master */
#define SND_SOC_DAIFMT_CBM_CFS (2 << 12) /* codec clk master & frame slave */ #define SND_SOC_DAIFMT_CBM_CFS (2 << 12) /* codec clk master & frame slave */
#define SND_SOC_DAIFMT_CBS_CFS (3 << 12) /* codec clk & frm slave */ #define SND_SOC_DAIFMT_CBS_CFS (3 << 12) /* codec clk & FRM slave */
#define SND_SOC_DAIFMT_FORMAT_MASK 0x000f #define SND_SOC_DAIFMT_FORMAT_MASK 0x000f
#define SND_SOC_DAIFMT_CLOCK_MASK 0x00f0 #define SND_SOC_DAIFMT_CLOCK_MASK 0x00f0
...@@ -78,7 +78,13 @@ struct snd_pcm_substream; ...@@ -78,7 +78,13 @@ struct snd_pcm_substream;
#define SND_SOC_CLOCK_IN 0 #define SND_SOC_CLOCK_IN 0
#define SND_SOC_CLOCK_OUT 1 #define SND_SOC_CLOCK_OUT 1
#define SND_SOC_STD_AC97_FMTS (SNDRV_PCM_FMTBIT_S16_LE |\ #define SND_SOC_STD_AC97_FMTS (SNDRV_PCM_FMTBIT_S8 |\
SNDRV_PCM_FMTBIT_S16_LE |\
SNDRV_PCM_FMTBIT_S16_BE |\
SNDRV_PCM_FMTBIT_S20_3LE |\
SNDRV_PCM_FMTBIT_S20_3BE |\
SNDRV_PCM_FMTBIT_S24_3LE |\
SNDRV_PCM_FMTBIT_S24_3BE |\
SNDRV_PCM_FMTBIT_S32_LE |\ SNDRV_PCM_FMTBIT_S32_LE |\
SNDRV_PCM_FMTBIT_S32_BE) SNDRV_PCM_FMTBIT_S32_BE)
...@@ -106,7 +112,7 @@ int snd_soc_dai_set_pll(struct snd_soc_dai *dai, ...@@ -106,7 +112,7 @@ int snd_soc_dai_set_pll(struct snd_soc_dai *dai,
int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt); int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt);
int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai, int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai,
unsigned int mask, int slots); unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width);
int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate); int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate);
...@@ -116,12 +122,12 @@ int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute); ...@@ -116,12 +122,12 @@ int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute);
/* /*
* Digital Audio Interface. * Digital Audio Interface.
* *
* Describes the Digital Audio Interface in terms of it's ALSA, DAI and AC97 * Describes the Digital Audio Interface in terms of its ALSA, DAI and AC97
* operations an capabilities. Codec and platfom drivers will register a this * operations and capabilities. Codec and platform drivers will register this
* structure for every DAI they have. * structure for every DAI they have.
* *
* This structure covers the clocking, formating and ALSA operations for each * This structure covers the clocking, formating and ALSA operations for each
* interface a * interface.
*/ */
struct snd_soc_dai_ops { struct snd_soc_dai_ops {
/* /*
...@@ -140,7 +146,8 @@ struct snd_soc_dai_ops { ...@@ -140,7 +146,8 @@ struct snd_soc_dai_ops {
*/ */
int (*set_fmt)(struct snd_soc_dai *dai, unsigned int fmt); int (*set_fmt)(struct snd_soc_dai *dai, unsigned int fmt);
int (*set_tdm_slot)(struct snd_soc_dai *dai, int (*set_tdm_slot)(struct snd_soc_dai *dai,
unsigned int mask, int slots); unsigned int tx_mask, unsigned int rx_mask,
int slots, int slot_width);
int (*set_tristate)(struct snd_soc_dai *dai, int tristate); int (*set_tristate)(struct snd_soc_dai *dai, int tristate);
/* /*
...@@ -179,6 +186,7 @@ struct snd_soc_dai { ...@@ -179,6 +186,7 @@ struct snd_soc_dai {
int ac97_control; int ac97_control;
struct device *dev; struct device *dev;
void *ac97_pdata; /* platform_data for the ac97 codec */
/* DAI callbacks */ /* DAI callbacks */
int (*probe)(struct platform_device *pdev, int (*probe)(struct platform_device *pdev,
......
...@@ -137,6 +137,12 @@ ...@@ -137,6 +137,12 @@
.event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD} .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD}
/* stream domain */ /* stream domain */
#define SND_SOC_DAPM_AIF_IN(wname, stname, wslot, wreg, wshift, winvert) \
{ .id = snd_soc_dapm_aif_in, .name = wname, .sname = stname, \
.reg = wreg, .shift = wshift, .invert = winvert }
#define SND_SOC_DAPM_AIF_OUT(wname, stname, wslot, wreg, wshift, winvert) \
{ .id = snd_soc_dapm_aif_out, .name = wname, .sname = stname, \
.reg = wreg, .shift = wshift, .invert = winvert }
#define SND_SOC_DAPM_DAC(wname, stname, wreg, wshift, winvert) \ #define SND_SOC_DAPM_DAC(wname, stname, wreg, wshift, winvert) \
{ .id = snd_soc_dapm_dac, .name = wname, .sname = stname, .reg = wreg, \ { .id = snd_soc_dapm_dac, .name = wname, .sname = stname, .reg = wreg, \
.shift = wshift, .invert = winvert} .shift = wshift, .invert = winvert}
...@@ -279,9 +285,11 @@ int snd_soc_dapm_add_routes(struct snd_soc_codec *codec, ...@@ -279,9 +285,11 @@ int snd_soc_dapm_add_routes(struct snd_soc_codec *codec,
/* dapm events */ /* dapm events */
int snd_soc_dapm_stream_event(struct snd_soc_codec *codec, char *stream, int snd_soc_dapm_stream_event(struct snd_soc_codec *codec, char *stream,
int event); int event);
void snd_soc_dapm_shutdown(struct snd_soc_device *socdev);
/* dapm sys fs - used by the core */ /* dapm sys fs - used by the core */
int snd_soc_dapm_sys_add(struct device *dev); int snd_soc_dapm_sys_add(struct device *dev);
void snd_soc_dapm_debugfs_init(struct snd_soc_codec *codec);
/* dapm audio pin control and status */ /* dapm audio pin control and status */
int snd_soc_dapm_enable_pin(struct snd_soc_codec *codec, const char *pin); int snd_soc_dapm_enable_pin(struct snd_soc_codec *codec, const char *pin);
...@@ -311,6 +319,8 @@ enum snd_soc_dapm_type { ...@@ -311,6 +319,8 @@ enum snd_soc_dapm_type {
snd_soc_dapm_pre, /* machine specific pre widget - exec first */ snd_soc_dapm_pre, /* machine specific pre widget - exec first */
snd_soc_dapm_post, /* machine specific post widget - exec last */ snd_soc_dapm_post, /* machine specific post widget - exec last */
snd_soc_dapm_supply, /* power/clock supply */ snd_soc_dapm_supply, /* power/clock supply */
snd_soc_dapm_aif_in, /* audio interface input */
snd_soc_dapm_aif_out, /* audio interface output */
}; };
/* /*
......
...@@ -135,6 +135,28 @@ ...@@ -135,6 +135,28 @@
.info = snd_soc_info_volsw, \ .info = snd_soc_info_volsw, \
.get = xhandler_get, .put = xhandler_put, \ .get = xhandler_get, .put = xhandler_put, \
.private_value = SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) } .private_value = SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) }
#define SOC_DOUBLE_EXT_TLV(xname, xreg, shift_left, shift_right, xmax, xinvert,\
xhandler_get, xhandler_put, 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 = 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_DOUBLE_R_EXT_TLV(xname, reg_left, reg_right, xshift, xmax, xinvert,\
xhandler_get, xhandler_put, 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 = xhandler_get, .put = xhandler_put, \
.private_value = (unsigned long)&(struct soc_mixer_control) \
{.reg = reg_left, .rreg = reg_right, .shift = xshift, \
.max = xmax, .invert = xinvert} }
#define SOC_SINGLE_BOOL_EXT(xname, xdata, xhandler_get, xhandler_put) \ #define SOC_SINGLE_BOOL_EXT(xname, xdata, xhandler_get, xhandler_put) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
.info = snd_soc_info_bool_ext, \ .info = snd_soc_info_bool_ext, \
...@@ -183,14 +205,28 @@ struct snd_soc_jack_gpio; ...@@ -183,14 +205,28 @@ struct snd_soc_jack_gpio;
#endif #endif
typedef int (*hw_write_t)(void *,const char* ,int); typedef int (*hw_write_t)(void *,const char* ,int);
typedef int (*hw_read_t)(void *,char* ,int);
extern struct snd_ac97_bus_ops soc_ac97_ops; extern struct snd_ac97_bus_ops soc_ac97_ops;
enum snd_soc_control_type {
SND_SOC_CUSTOM,
SND_SOC_I2C,
SND_SOC_SPI,
};
int snd_soc_register_platform(struct snd_soc_platform *platform); int snd_soc_register_platform(struct snd_soc_platform *platform);
void snd_soc_unregister_platform(struct snd_soc_platform *platform); void snd_soc_unregister_platform(struct snd_soc_platform *platform);
int snd_soc_register_codec(struct snd_soc_codec *codec); int snd_soc_register_codec(struct snd_soc_codec *codec);
void snd_soc_unregister_codec(struct snd_soc_codec *codec); void snd_soc_unregister_codec(struct snd_soc_codec *codec);
int snd_soc_codec_volatile_register(struct snd_soc_codec *codec, int reg);
int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
int addr_bits, int data_bits,
enum snd_soc_control_type control);
#ifdef CONFIG_PM
int snd_soc_suspend_device(struct device *dev);
int snd_soc_resume_device(struct device *dev);
#endif
/* pcm <-> DAI connect */ /* pcm <-> DAI connect */
void snd_soc_free_pcms(struct snd_soc_device *socdev); void snd_soc_free_pcms(struct snd_soc_device *socdev);
...@@ -216,9 +252,9 @@ void snd_soc_jack_free_gpios(struct snd_soc_jack *jack, int count, ...@@ -216,9 +252,9 @@ void snd_soc_jack_free_gpios(struct snd_soc_jack *jack, int count,
/* codec register bit access */ /* codec register bit access */
int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg, int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg,
unsigned short mask, unsigned short value); unsigned int mask, unsigned int value);
int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned short reg, int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned short reg,
unsigned short mask, unsigned short value); unsigned int mask, unsigned int value);
int snd_soc_new_ac97_codec(struct snd_soc_codec *codec, int snd_soc_new_ac97_codec(struct snd_soc_codec *codec,
struct snd_ac97_bus_ops *ops, int num); struct snd_ac97_bus_ops *ops, int num);
...@@ -356,8 +392,10 @@ struct snd_soc_codec { ...@@ -356,8 +392,10 @@ struct snd_soc_codec {
int (*write)(struct snd_soc_codec *, unsigned int, unsigned int); int (*write)(struct snd_soc_codec *, unsigned int, unsigned int);
int (*display_register)(struct snd_soc_codec *, char *, int (*display_register)(struct snd_soc_codec *, char *,
size_t, unsigned int); size_t, unsigned int);
int (*volatile_register)(unsigned int);
int (*readable_register)(unsigned int);
hw_write_t hw_write; hw_write_t hw_write;
hw_read_t hw_read; unsigned int (*hw_read)(struct snd_soc_codec *, unsigned int);
void *reg_cache; void *reg_cache;
short reg_cache_size; short reg_cache_size;
short reg_cache_step; short reg_cache_step;
...@@ -369,8 +407,6 @@ struct snd_soc_codec { ...@@ -369,8 +407,6 @@ struct snd_soc_codec {
enum snd_soc_bias_level bias_level; enum snd_soc_bias_level bias_level;
enum snd_soc_bias_level suspend_bias_level; enum snd_soc_bias_level suspend_bias_level;
struct delayed_work delayed_work; struct delayed_work delayed_work;
struct list_head up_list;
struct list_head down_list;
/* codec DAI's */ /* codec DAI's */
struct snd_soc_dai *dai; struct snd_soc_dai *dai;
...@@ -379,6 +415,7 @@ struct snd_soc_codec { ...@@ -379,6 +415,7 @@ struct snd_soc_codec {
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS
struct dentry *debugfs_reg; struct dentry *debugfs_reg;
struct dentry *debugfs_pop_time; struct dentry *debugfs_pop_time;
struct dentry *debugfs_dapm;
#endif #endif
}; };
......
...@@ -35,6 +35,8 @@ ...@@ -35,6 +35,8 @@
#define SNDRV_CTL_TLVT_DB_SCALE 1 /* dB scale */ #define SNDRV_CTL_TLVT_DB_SCALE 1 /* dB scale */
#define SNDRV_CTL_TLVT_DB_LINEAR 2 /* linear volume */ #define SNDRV_CTL_TLVT_DB_LINEAR 2 /* linear volume */
#define SNDRV_CTL_TLVT_DB_RANGE 3 /* dB range container */ #define SNDRV_CTL_TLVT_DB_RANGE 3 /* dB range container */
#define SNDRV_CTL_TLVT_DB_MINMAX 4 /* dB scale with min/max */
#define SNDRV_CTL_TLVT_DB_MINMAX_MUTE 5 /* dB scale with min/max with mute */
#define TLV_DB_SCALE_ITEM(min, step, mute) \ #define TLV_DB_SCALE_ITEM(min, step, mute) \
SNDRV_CTL_TLVT_DB_SCALE, 2 * sizeof(unsigned int), \ SNDRV_CTL_TLVT_DB_SCALE, 2 * sizeof(unsigned int), \
...@@ -42,6 +44,18 @@ ...@@ -42,6 +44,18 @@
#define DECLARE_TLV_DB_SCALE(name, min, step, mute) \ #define DECLARE_TLV_DB_SCALE(name, min, step, mute) \
unsigned int name[] = { TLV_DB_SCALE_ITEM(min, step, mute) } unsigned int name[] = { TLV_DB_SCALE_ITEM(min, step, mute) }
/* dB scale specified with min/max values instead of step */
#define TLV_DB_MINMAX_ITEM(min_dB, max_dB) \
SNDRV_CTL_TLVT_DB_MINMAX, 2 * sizeof(unsigned int), \
(min_dB), (max_dB)
#define TLV_DB_MINMAX_MUTE_ITEM(min_dB, max_dB) \
SNDRV_CTL_TLVT_DB_MINMAX_MUTE, 2 * sizeof(unsigned int), \
(min_dB), (max_dB)
#define DECLARE_TLV_DB_MINMAX(name, min_dB, max_dB) \
unsigned int name[] = { TLV_DB_MINMAX_ITEM(min_dB, max_dB) }
#define DECLARE_TLV_DB_MINMAX_MUTE(name, min_dB, max_dB) \
unsigned int name[] = { TLV_DB_MINMAX_MUTE_ITEM(min_dB, max_dB) }
/* linear volume between min_dB and max_dB (.01dB unit) */ /* linear volume between min_dB and max_dB (.01dB unit) */
#define TLV_DB_LINEAR_ITEM(min_dB, max_dB) \ #define TLV_DB_LINEAR_ITEM(min_dB, max_dB) \
SNDRV_CTL_TLVT_DB_LINEAR, 2 * sizeof(unsigned int), \ SNDRV_CTL_TLVT_DB_LINEAR, 2 * sizeof(unsigned int), \
......
/*
* UDA1380 ALSA SoC Codec driver
*
* Copyright 2009 Philipp Zabel
*
* 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 __UDA1380_H
#define __UDA1380_H
struct uda1380_platform_data {
int gpio_power;
int gpio_reset;
int dac_clk;
#define UDA1380_DAC_CLK_SYSCLK 0
#define UDA1380_DAC_CLK_WSPLL 1
};
#endif /* __UDA1380_H */
/* include/version.h */ /* include/version.h */
#define CONFIG_SND_VERSION "1.0.20" #define CONFIG_SND_VERSION "1.0.21"
#define CONFIG_SND_DATE "" #define CONFIG_SND_DATE ""
/*
* linux/sound/wm8993.h -- Platform data for WM8993
*
* 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_WM8993_H
#define __LINUX_SND_WM8993_H
/* Note that EQ1 only contains the enable/disable bit so will be
ignored but is included for simplicity.
*/
struct wm8993_retune_mobile_setting {
const char *name;
unsigned int rate;
u16 config[24];
};
struct wm8993_platform_data {
struct wm8993_retune_mobile_setting *retune_configs;
int num_retune_configs;
/* LINEOUT can be differential or single ended */
unsigned int lineout1_diff:1;
unsigned int lineout2_diff:1;
/* Common mode feedback */
unsigned int lineout1fb:1;
unsigned int lineout2fb:1;
/* Microphone biases: 0=0.9*AVDD1 1=0.65*AVVD1 */
unsigned int micbias1_lvl:1;
unsigned int micbias2_lvl:1;
/* Jack detect threashold levels, see datasheet for values */
unsigned int jd_scthr:2;
unsigned int jd_thr:2;
};
#endif
...@@ -331,6 +331,7 @@ struct snd_ymfpci { ...@@ -331,6 +331,7 @@ struct snd_ymfpci {
struct snd_ac97 *ac97; struct snd_ac97 *ac97;
struct snd_rawmidi *rawmidi; struct snd_rawmidi *rawmidi;
struct snd_timer *timer; struct snd_timer *timer;
unsigned int timer_ticks;
struct pci_dev *pci; struct pci_dev *pci;
struct snd_card *card; struct snd_card *card;
......
...@@ -32,6 +32,34 @@ config SOUND_OSS_CORE ...@@ -32,6 +32,34 @@ config SOUND_OSS_CORE
bool bool
default n default n
config SOUND_OSS_CORE_PRECLAIM
bool "Preclaim OSS device numbers"
depends on SOUND_OSS_CORE
default y
help
With this option enabled, the kernel will claim all OSS device
numbers if any OSS support (native or emulation) is enabled
whether the respective module is loaded or not and try to load the
appropriate module using sound-slot/service-* and char-major-*
module aliases when one of the device numbers is opened. With
this option disabled, kernel will only claim actually in-use
device numbers and opening a missing device will generate only the
standard char-major-* aliases.
The only visible difference is use of additional module aliases
and whether OSS sound devices appear multiple times in
/proc/devices. sound-slot/service-* module aliases are scheduled
to be removed (ie. PRECLAIM won't be available) and this option is
to make the transition easier. This option can be overridden
during boot using the kernel parameter soundcore.preclaim_oss.
Disabling this allows alternative OSS implementations.
Please read Documentation/feature-removal-schedule.txt for
details.
If unusre, say Y.
source "sound/oss/dmasound/Kconfig" source "sound/oss/dmasound/Kconfig"
if !M68K if !M68K
......
...@@ -170,6 +170,13 @@ static int __devinit pxa2xx_ac97_probe(struct platform_device *dev) ...@@ -170,6 +170,13 @@ static int __devinit pxa2xx_ac97_probe(struct platform_device *dev)
struct snd_ac97_bus *ac97_bus; struct snd_ac97_bus *ac97_bus;
struct snd_ac97_template ac97_template; struct snd_ac97_template ac97_template;
int ret; int ret;
pxa2xx_audio_ops_t *pdata = dev->dev.platform_data;
if (dev->id >= 0) {
dev_err(&dev->dev, "PXA2xx has only one AC97 port.\n");
ret = -ENXIO;
goto err_dev;
}
ret = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, ret = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
THIS_MODULE, 0, &card); THIS_MODULE, 0, &card);
...@@ -200,6 +207,8 @@ static int __devinit pxa2xx_ac97_probe(struct platform_device *dev) ...@@ -200,6 +207,8 @@ static int __devinit pxa2xx_ac97_probe(struct platform_device *dev)
snprintf(card->longname, sizeof(card->longname), snprintf(card->longname, sizeof(card->longname),
"%s (%s)", dev->dev.driver->name, card->mixername); "%s (%s)", dev->dev.driver->name, card->mixername);
if (pdata && pdata->codec_pdata[0])
snd_ac97_dev_add_pdata(ac97_bus->codec[0], pdata->codec_pdata[0]);
snd_card_set_dev(card, &dev->dev); snd_card_set_dev(card, &dev->dev);
ret = snd_card_register(card); ret = snd_card_register(card);
if (ret == 0) { if (ret == 0) {
...@@ -212,6 +221,7 @@ static int __devinit pxa2xx_ac97_probe(struct platform_device *dev) ...@@ -212,6 +221,7 @@ static int __devinit pxa2xx_ac97_probe(struct platform_device *dev)
err: err:
if (card) if (card)
snd_card_free(card); snd_card_free(card);
err_dev:
return ret; return ret;
} }
......
...@@ -136,6 +136,9 @@ int __pxa2xx_pcm_prepare(struct snd_pcm_substream *substream) ...@@ -136,6 +136,9 @@ int __pxa2xx_pcm_prepare(struct snd_pcm_substream *substream)
{ {
struct pxa2xx_runtime_data *prtd = substream->runtime->private_data; struct pxa2xx_runtime_data *prtd = substream->runtime->private_data;
if (!prtd || !prtd->params)
return 0;
DCSR(prtd->dma_ch) &= ~DCSR_RUN; DCSR(prtd->dma_ch) &= ~DCSR_RUN;
DCSR(prtd->dma_ch) = 0; DCSR(prtd->dma_ch) = 0;
DCMD(prtd->dma_ch) = 0; DCMD(prtd->dma_ch) = 0;
......
...@@ -206,4 +206,8 @@ config SND_PCM_XRUN_DEBUG ...@@ -206,4 +206,8 @@ config SND_PCM_XRUN_DEBUG
config SND_VMASTER config SND_VMASTER
bool bool
config SND_DMA_SGBUF
def_bool y
depends on X86
source "sound/core/seq/Kconfig" source "sound/core/seq/Kconfig"
...@@ -13,7 +13,7 @@ snd-pcm-objs := pcm.o pcm_native.o pcm_lib.o pcm_timer.o pcm_misc.o \ ...@@ -13,7 +13,7 @@ snd-pcm-objs := pcm.o pcm_native.o pcm_lib.o pcm_timer.o pcm_misc.o \
pcm_memory.o pcm_memory.o
snd-page-alloc-y := memalloc.o snd-page-alloc-y := memalloc.o
snd-page-alloc-$(CONFIG_HAS_DMA) += sgbuf.o snd-page-alloc-$(CONFIG_SND_DMA_SGBUF) += sgbuf.o
snd-rawmidi-objs := rawmidi.o snd-rawmidi-objs := rawmidi.o
snd-timer-objs := timer.o snd-timer-objs := timer.o
......
...@@ -414,7 +414,7 @@ int snd_ctl_remove_id(struct snd_card *card, struct snd_ctl_elem_id *id) ...@@ -414,7 +414,7 @@ int snd_ctl_remove_id(struct snd_card *card, struct snd_ctl_elem_id *id)
EXPORT_SYMBOL(snd_ctl_remove_id); EXPORT_SYMBOL(snd_ctl_remove_id);
/** /**
* snd_ctl_remove_unlocked_id - remove the unlocked control of the given id and release it * snd_ctl_remove_user_ctl - remove and release the unlocked user control
* @file: active control handle * @file: active control handle
* @id: the control id to remove * @id: the control id to remove
* *
...@@ -423,8 +423,8 @@ EXPORT_SYMBOL(snd_ctl_remove_id); ...@@ -423,8 +423,8 @@ EXPORT_SYMBOL(snd_ctl_remove_id);
* *
* Returns 0 if successful, or a negative error code on failure. * Returns 0 if successful, or a negative error code on failure.
*/ */
static int snd_ctl_remove_unlocked_id(struct snd_ctl_file * file, static int snd_ctl_remove_user_ctl(struct snd_ctl_file * file,
struct snd_ctl_elem_id *id) struct snd_ctl_elem_id *id)
{ {
struct snd_card *card = file->card; struct snd_card *card = file->card;
struct snd_kcontrol *kctl; struct snd_kcontrol *kctl;
...@@ -433,15 +433,23 @@ static int snd_ctl_remove_unlocked_id(struct snd_ctl_file * file, ...@@ -433,15 +433,23 @@ static int snd_ctl_remove_unlocked_id(struct snd_ctl_file * file,
down_write(&card->controls_rwsem); down_write(&card->controls_rwsem);
kctl = snd_ctl_find_id(card, id); kctl = snd_ctl_find_id(card, id);
if (kctl == NULL) { if (kctl == NULL) {
up_write(&card->controls_rwsem); ret = -ENOENT;
return -ENOENT; goto error;
}
if (!(kctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_USER)) {
ret = -EINVAL;
goto error;
} }
for (idx = 0; idx < kctl->count; idx++) for (idx = 0; idx < kctl->count; idx++)
if (kctl->vd[idx].owner != NULL && kctl->vd[idx].owner != file) { if (kctl->vd[idx].owner != NULL && kctl->vd[idx].owner != file) {
up_write(&card->controls_rwsem); ret = -EBUSY;
return -EBUSY; goto error;
} }
ret = snd_ctl_remove(card, kctl); ret = snd_ctl_remove(card, kctl);
if (ret < 0)
goto error;
card->user_ctl_count--;
error:
up_write(&card->controls_rwsem); up_write(&card->controls_rwsem);
return ret; return ret;
} }
...@@ -951,7 +959,7 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file, ...@@ -951,7 +959,7 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
if (card->user_ctl_count >= MAX_USER_CONTROLS) if (card->user_ctl_count >= MAX_USER_CONTROLS)
return -ENOMEM; return -ENOMEM;
if (info->count > 1024) if (info->count < 1)
return -EINVAL; return -EINVAL;
access = info->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE : access = info->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE :
(info->access & (SNDRV_CTL_ELEM_ACCESS_READWRITE| (info->access & (SNDRV_CTL_ELEM_ACCESS_READWRITE|
...@@ -1052,18 +1060,10 @@ static int snd_ctl_elem_remove(struct snd_ctl_file *file, ...@@ -1052,18 +1060,10 @@ static int snd_ctl_elem_remove(struct snd_ctl_file *file,
struct snd_ctl_elem_id __user *_id) struct snd_ctl_elem_id __user *_id)
{ {
struct snd_ctl_elem_id id; struct snd_ctl_elem_id id;
int err;
if (copy_from_user(&id, _id, sizeof(id))) if (copy_from_user(&id, _id, sizeof(id)))
return -EFAULT; return -EFAULT;
err = snd_ctl_remove_unlocked_id(file, &id); return snd_ctl_remove_user_ctl(file, &id);
if (! err) {
struct snd_card *card = file->card;
down_write(&card->controls_rwsem);
card->user_ctl_count--;
up_write(&card->controls_rwsem);
}
return err;
} }
static int snd_ctl_subscribe_events(struct snd_ctl_file *file, int __user *ptr) static int snd_ctl_subscribe_events(struct snd_ctl_file *file, int __user *ptr)
......
...@@ -88,12 +88,10 @@ static int resize_info_buffer(struct snd_info_buffer *buffer, ...@@ -88,12 +88,10 @@ static int resize_info_buffer(struct snd_info_buffer *buffer,
char *nbuf; char *nbuf;
nsize = PAGE_ALIGN(nsize); nsize = PAGE_ALIGN(nsize);
nbuf = kmalloc(nsize, GFP_KERNEL); nbuf = krealloc(buffer->buffer, nsize, GFP_KERNEL);
if (! nbuf) if (! nbuf)
return -ENOMEM; return -ENOMEM;
memcpy(nbuf, buffer->buffer, buffer->len);
kfree(buffer->buffer);
buffer->buffer = nbuf; buffer->buffer = nbuf;
buffer->len = nsize; buffer->len = nsize;
return 0; return 0;
...@@ -108,7 +106,7 @@ static int resize_info_buffer(struct snd_info_buffer *buffer, ...@@ -108,7 +106,7 @@ static int resize_info_buffer(struct snd_info_buffer *buffer,
* *
* Returns the size of output string. * Returns the size of output string.
*/ */
int snd_iprintf(struct snd_info_buffer *buffer, char *fmt,...) int snd_iprintf(struct snd_info_buffer *buffer, const char *fmt, ...)
{ {
va_list args; va_list args;
int len, res; int len, res;
...@@ -727,7 +725,7 @@ EXPORT_SYMBOL(snd_info_get_line); ...@@ -727,7 +725,7 @@ EXPORT_SYMBOL(snd_info_get_line);
* Returns the updated pointer of the original string so that * Returns the updated pointer of the original string so that
* it can be used for the next call. * it can be used for the next call.
*/ */
char *snd_info_get_str(char *dest, char *src, int len) const char *snd_info_get_str(char *dest, const char *src, int len)
{ {
int c; int c;
......
...@@ -31,6 +31,14 @@ ...@@ -31,6 +31,14 @@
#include <sound/control.h> #include <sound/control.h>
#include <sound/info.h> #include <sound/info.h>
/* monitor files for graceful shutdown (hotplug) */
struct snd_monitor_file {
struct file *file;
const struct file_operations *disconnected_f_op;
struct list_head shutdown_list; /* still need to shutdown */
struct list_head list; /* link of monitor files */
};
static DEFINE_SPINLOCK(shutdown_lock); static DEFINE_SPINLOCK(shutdown_lock);
static LIST_HEAD(shutdown_files); static LIST_HEAD(shutdown_files);
......
...@@ -199,6 +199,8 @@ int snd_dma_alloc_pages(int type, struct device *device, size_t size, ...@@ -199,6 +199,8 @@ int snd_dma_alloc_pages(int type, struct device *device, size_t size,
case SNDRV_DMA_TYPE_DEV: case SNDRV_DMA_TYPE_DEV:
dmab->area = snd_malloc_dev_pages(device, size, &dmab->addr); dmab->area = snd_malloc_dev_pages(device, size, &dmab->addr);
break; break;
#endif
#ifdef CONFIG_SND_DMA_SGBUF
case SNDRV_DMA_TYPE_DEV_SG: case SNDRV_DMA_TYPE_DEV_SG:
snd_malloc_sgbuf_pages(device, size, dmab, NULL); snd_malloc_sgbuf_pages(device, size, dmab, NULL);
break; break;
...@@ -269,6 +271,8 @@ void snd_dma_free_pages(struct snd_dma_buffer *dmab) ...@@ -269,6 +271,8 @@ void snd_dma_free_pages(struct snd_dma_buffer *dmab)
case SNDRV_DMA_TYPE_DEV: case SNDRV_DMA_TYPE_DEV:
snd_free_dev_pages(dmab->dev.dev, dmab->bytes, dmab->area, dmab->addr); snd_free_dev_pages(dmab->dev.dev, dmab->bytes, dmab->area, dmab->addr);
break; break;
#endif
#ifdef CONFIG_SND_DMA_SGBUF
case SNDRV_DMA_TYPE_DEV_SG: case SNDRV_DMA_TYPE_DEV_SG:
snd_free_sgbuf_pages(dmab); snd_free_sgbuf_pages(dmab);
break; break;
......
...@@ -24,6 +24,20 @@ ...@@ -24,6 +24,20 @@
#include <linux/ioport.h> #include <linux/ioport.h>
#include <sound/core.h> #include <sound/core.h>
#ifdef CONFIG_SND_DEBUG
#ifdef CONFIG_SND_DEBUG_VERBOSE
#define DEFAULT_DEBUG_LEVEL 2
#else
#define DEFAULT_DEBUG_LEVEL 1
#endif
static int debug = DEFAULT_DEBUG_LEVEL;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Debug level (0 = disable)");
#endif /* CONFIG_SND_DEBUG */
void release_and_free_resource(struct resource *res) void release_and_free_resource(struct resource *res)
{ {
if (res) { if (res) {
...@@ -35,46 +49,53 @@ void release_and_free_resource(struct resource *res) ...@@ -35,46 +49,53 @@ void release_and_free_resource(struct resource *res)
EXPORT_SYMBOL(release_and_free_resource); EXPORT_SYMBOL(release_and_free_resource);
#ifdef CONFIG_SND_VERBOSE_PRINTK #ifdef CONFIG_SND_VERBOSE_PRINTK
void snd_verbose_printk(const char *file, int line, const char *format, ...) /* strip the leading path if the given path is absolute */
static const char *sanity_file_name(const char *path)
{ {
va_list args; if (*path == '/')
return strrchr(path, '/') + 1;
if (format[0] == '<' && format[1] >= '0' && format[1] <= '7' && format[2] == '>') { else
char tmp[] = "<0>"; return path;
}
/* print file and line with a certain printk prefix */
static int print_snd_pfx(unsigned int level, const char *path, int line,
const char *format)
{
const char *file = sanity_file_name(path);
char tmp[] = "<0>";
const char *pfx = level ? KERN_DEBUG : KERN_DEFAULT;
int ret = 0;
if (format[0] == '<' && format[2] == '>') {
tmp[1] = format[1]; tmp[1] = format[1];
printk("%sALSA %s:%d: ", tmp, file, line); pfx = tmp;
format += 3; ret = 1;
} else {
printk("ALSA %s:%d: ", file, line);
} }
va_start(args, format); printk("%sALSA %s:%d: ", pfx, file, line);
vprintk(format, args); return ret;
va_end(args);
} }
#else
EXPORT_SYMBOL(snd_verbose_printk); #define print_snd_pfx(level, path, line, format) 0
#endif #endif
#if defined(CONFIG_SND_DEBUG) && defined(CONFIG_SND_VERBOSE_PRINTK) #if defined(CONFIG_SND_DEBUG) || defined(CONFIG_SND_VERBOSE_PRINTK)
void snd_verbose_printd(const char *file, int line, const char *format, ...) void __snd_printk(unsigned int level, const char *path, int line,
const char *format, ...)
{ {
va_list args; va_list args;
if (format[0] == '<' && format[1] >= '0' && format[1] <= '7' && format[2] == '>') { #ifdef CONFIG_SND_DEBUG
char tmp[] = "<0>"; if (debug < level)
tmp[1] = format[1]; return;
printk("%sALSA %s:%d: ", tmp, file, line); #endif
format += 3;
} else {
printk(KERN_DEBUG "ALSA %s:%d: ", file, line);
}
va_start(args, format); va_start(args, format);
if (print_snd_pfx(level, path, line, format))
format += 3; /* skip the printk level-prefix */
vprintk(format, args); vprintk(format, args);
va_end(args); va_end(args);
} }
EXPORT_SYMBOL_GPL(__snd_printk);
EXPORT_SYMBOL(snd_verbose_printd);
#endif #endif
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
......
...@@ -1154,7 +1154,8 @@ static void snd_mixer_oss_proc_write(struct snd_info_entry *entry, ...@@ -1154,7 +1154,8 @@ static void snd_mixer_oss_proc_write(struct snd_info_entry *entry,
struct snd_info_buffer *buffer) struct snd_info_buffer *buffer)
{ {
struct snd_mixer_oss *mixer = entry->private_data; struct snd_mixer_oss *mixer = entry->private_data;
char line[128], str[32], idxstr[16], *cptr; char line[128], str[32], idxstr[16];
const char *cptr;
int ch, idx; int ch, idx;
struct snd_mixer_oss_assign_table *tbl; struct snd_mixer_oss_assign_table *tbl;
struct slot *slot; struct slot *slot;
......
...@@ -1043,10 +1043,15 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream) ...@@ -1043,10 +1043,15 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream)
runtime->oss.channels = params_channels(params); runtime->oss.channels = params_channels(params);
runtime->oss.rate = params_rate(params); runtime->oss.rate = params_rate(params);
runtime->oss.params = 0;
runtime->oss.prepare = 1;
vfree(runtime->oss.buffer); vfree(runtime->oss.buffer);
runtime->oss.buffer = vmalloc(runtime->oss.period_bytes); runtime->oss.buffer = vmalloc(runtime->oss.period_bytes);
if (!runtime->oss.buffer) {
err = -ENOMEM;
goto failure;
}
runtime->oss.params = 0;
runtime->oss.prepare = 1;
runtime->oss.buffer_used = 0; runtime->oss.buffer_used = 0;
if (runtime->dma_area) if (runtime->dma_area)
snd_pcm_format_set_silence(runtime->format, runtime->dma_area, bytes_to_samples(runtime, runtime->dma_bytes)); snd_pcm_format_set_silence(runtime->format, runtime->dma_area, bytes_to_samples(runtime, runtime->dma_bytes));
...@@ -2836,7 +2841,8 @@ static void snd_pcm_oss_proc_write(struct snd_info_entry *entry, ...@@ -2836,7 +2841,8 @@ static void snd_pcm_oss_proc_write(struct snd_info_entry *entry,
struct snd_info_buffer *buffer) struct snd_info_buffer *buffer)
{ {
struct snd_pcm_str *pstr = entry->private_data; struct snd_pcm_str *pstr = entry->private_data;
char line[128], str[32], task_name[32], *ptr; char line[128], str[32], task_name[32];
const char *ptr;
int idx1; int idx1;
struct snd_pcm_oss_setup *setup, *setup1, template; struct snd_pcm_oss_setup *setup, *setup1, template;
......
...@@ -162,18 +162,7 @@ static int snd_pcm_control_ioctl(struct snd_card *card, ...@@ -162,18 +162,7 @@ static int snd_pcm_control_ioctl(struct snd_card *card,
return -ENOIOCTLCMD; return -ENOIOCTLCMD;
} }
#ifdef CONFIG_SND_VERBOSE_PROCFS
#define STATE(v) [SNDRV_PCM_STATE_##v] = #v
#define STREAM(v) [SNDRV_PCM_STREAM_##v] = #v
#define READY(v) [SNDRV_PCM_READY_##v] = #v
#define XRUN(v) [SNDRV_PCM_XRUN_##v] = #v
#define SILENCE(v) [SNDRV_PCM_SILENCE_##v] = #v
#define TSTAMP(v) [SNDRV_PCM_TSTAMP_##v] = #v
#define ACCESS(v) [SNDRV_PCM_ACCESS_##v] = #v
#define START(v) [SNDRV_PCM_START_##v] = #v
#define FORMAT(v) [SNDRV_PCM_FORMAT_##v] = #v #define FORMAT(v) [SNDRV_PCM_FORMAT_##v] = #v
#define SUBFORMAT(v) [SNDRV_PCM_SUBFORMAT_##v] = #v
static char *snd_pcm_format_names[] = { static char *snd_pcm_format_names[] = {
FORMAT(S8), FORMAT(S8),
...@@ -216,10 +205,23 @@ static char *snd_pcm_format_names[] = { ...@@ -216,10 +205,23 @@ static char *snd_pcm_format_names[] = {
FORMAT(U18_3BE), FORMAT(U18_3BE),
}; };
static const char *snd_pcm_format_name(snd_pcm_format_t format) const char *snd_pcm_format_name(snd_pcm_format_t format)
{ {
return snd_pcm_format_names[format]; return snd_pcm_format_names[format];
} }
EXPORT_SYMBOL_GPL(snd_pcm_format_name);
#ifdef CONFIG_SND_VERBOSE_PROCFS
#define STATE(v) [SNDRV_PCM_STATE_##v] = #v
#define STREAM(v) [SNDRV_PCM_STREAM_##v] = #v
#define READY(v) [SNDRV_PCM_READY_##v] = #v
#define XRUN(v) [SNDRV_PCM_XRUN_##v] = #v
#define SILENCE(v) [SNDRV_PCM_SILENCE_##v] = #v
#define TSTAMP(v) [SNDRV_PCM_TSTAMP_##v] = #v
#define ACCESS(v) [SNDRV_PCM_ACCESS_##v] = #v
#define START(v) [SNDRV_PCM_START_##v] = #v
#define SUBFORMAT(v) [SNDRV_PCM_SUBFORMAT_##v] = #v
static char *snd_pcm_stream_names[] = { static char *snd_pcm_stream_names[] = {
STREAM(PLAYBACK), STREAM(PLAYBACK),
......
...@@ -197,12 +197,16 @@ static int snd_pcm_update_hw_ptr_post(struct snd_pcm_substream *substream, ...@@ -197,12 +197,16 @@ static int snd_pcm_update_hw_ptr_post(struct snd_pcm_substream *substream,
avail = snd_pcm_capture_avail(runtime); avail = snd_pcm_capture_avail(runtime);
if (avail > runtime->avail_max) if (avail > runtime->avail_max)
runtime->avail_max = avail; runtime->avail_max = avail;
if (avail >= runtime->stop_threshold) { if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) {
if (substream->runtime->status->state == SNDRV_PCM_STATE_DRAINING) if (avail >= runtime->buffer_size) {
snd_pcm_drain_done(substream); snd_pcm_drain_done(substream);
else return -EPIPE;
}
} else {
if (avail >= runtime->stop_threshold) {
xrun(substream); xrun(substream);
return -EPIPE; return -EPIPE;
}
} }
if (avail >= runtime->control->avail_min) if (avail >= runtime->control->avail_min)
wake_up(&runtime->sleep); wake_up(&runtime->sleep);
......
...@@ -304,6 +304,7 @@ int snd_pcm_lib_preallocate_pages_for_all(struct snd_pcm *pcm, ...@@ -304,6 +304,7 @@ int snd_pcm_lib_preallocate_pages_for_all(struct snd_pcm *pcm,
EXPORT_SYMBOL(snd_pcm_lib_preallocate_pages_for_all); EXPORT_SYMBOL(snd_pcm_lib_preallocate_pages_for_all);
#ifdef CONFIG_SND_DMA_SGBUF
/** /**
* snd_pcm_sgbuf_ops_page - get the page struct at the given offset * snd_pcm_sgbuf_ops_page - get the page struct at the given offset
* @substream: the pcm substream instance * @substream: the pcm substream instance
...@@ -349,6 +350,7 @@ unsigned int snd_pcm_sgbuf_get_chunk_size(struct snd_pcm_substream *substream, ...@@ -349,6 +350,7 @@ unsigned int snd_pcm_sgbuf_get_chunk_size(struct snd_pcm_substream *substream,
return size; return size;
} }
EXPORT_SYMBOL(snd_pcm_sgbuf_get_chunk_size); EXPORT_SYMBOL(snd_pcm_sgbuf_get_chunk_size);
#endif /* CONFIG_SND_DMA_SGBUF */
/** /**
* snd_pcm_lib_malloc_pages - allocate the DMA buffer * snd_pcm_lib_malloc_pages - allocate the DMA buffer
......
...@@ -1343,8 +1343,6 @@ static int snd_pcm_prepare(struct snd_pcm_substream *substream, ...@@ -1343,8 +1343,6 @@ static int snd_pcm_prepare(struct snd_pcm_substream *substream,
static int snd_pcm_pre_drain_init(struct snd_pcm_substream *substream, int state) static int snd_pcm_pre_drain_init(struct snd_pcm_substream *substream, int state)
{ {
if (substream->f_flags & O_NONBLOCK)
return -EAGAIN;
substream->runtime->trigger_master = substream; substream->runtime->trigger_master = substream;
return 0; return 0;
} }
...@@ -1392,7 +1390,6 @@ static struct action_ops snd_pcm_action_drain_init = { ...@@ -1392,7 +1390,6 @@ static struct action_ops snd_pcm_action_drain_init = {
struct drain_rec { struct drain_rec {
struct snd_pcm_substream *substream; struct snd_pcm_substream *substream;
wait_queue_t wait; wait_queue_t wait;
snd_pcm_uframes_t stop_threshold;
}; };
static int snd_pcm_drop(struct snd_pcm_substream *substream); static int snd_pcm_drop(struct snd_pcm_substream *substream);
...@@ -1404,13 +1401,15 @@ static int snd_pcm_drop(struct snd_pcm_substream *substream); ...@@ -1404,13 +1401,15 @@ static int snd_pcm_drop(struct snd_pcm_substream *substream);
* After this call, all streams are supposed to be either SETUP or DRAINING * After this call, all streams are supposed to be either SETUP or DRAINING
* (capture only) state. * (capture only) state.
*/ */
static int snd_pcm_drain(struct snd_pcm_substream *substream) static int snd_pcm_drain(struct snd_pcm_substream *substream,
struct file *file)
{ {
struct snd_card *card; struct snd_card *card;
struct snd_pcm_runtime *runtime; struct snd_pcm_runtime *runtime;
struct snd_pcm_substream *s; struct snd_pcm_substream *s;
int result = 0; int result = 0;
int i, num_drecs; int i, num_drecs;
int nonblock = 0;
struct drain_rec *drec, drec_tmp, *d; struct drain_rec *drec, drec_tmp, *d;
card = substream->pcm->card; card = substream->pcm->card;
...@@ -1428,6 +1427,15 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream) ...@@ -1428,6 +1427,15 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream)
} }
} }
if (file) {
if (file->f_flags & O_NONBLOCK)
nonblock = 1;
} else if (substream->f_flags & O_NONBLOCK)
nonblock = 1;
if (nonblock)
goto lock; /* no need to allocate waitqueues */
/* allocate temporary record for drain sync */ /* allocate temporary record for drain sync */
down_read(&snd_pcm_link_rwsem); down_read(&snd_pcm_link_rwsem);
if (snd_pcm_stream_linked(substream)) { if (snd_pcm_stream_linked(substream)) {
...@@ -1449,16 +1457,11 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream) ...@@ -1449,16 +1457,11 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream)
d->substream = s; d->substream = s;
init_waitqueue_entry(&d->wait, current); init_waitqueue_entry(&d->wait, current);
add_wait_queue(&runtime->sleep, &d->wait); add_wait_queue(&runtime->sleep, &d->wait);
/* stop_threshold fixup to avoid endless loop when
* stop_threshold > buffer_size
*/
d->stop_threshold = runtime->stop_threshold;
if (runtime->stop_threshold > runtime->buffer_size)
runtime->stop_threshold = runtime->buffer_size;
} }
} }
up_read(&snd_pcm_link_rwsem); up_read(&snd_pcm_link_rwsem);
lock:
snd_pcm_stream_lock_irq(substream); snd_pcm_stream_lock_irq(substream);
/* resume pause */ /* resume pause */
if (substream->runtime->status->state == SNDRV_PCM_STATE_PAUSED) if (substream->runtime->status->state == SNDRV_PCM_STATE_PAUSED)
...@@ -1466,9 +1469,12 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream) ...@@ -1466,9 +1469,12 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream)
/* pre-start/stop - all running streams are changed to DRAINING state */ /* pre-start/stop - all running streams are changed to DRAINING state */
result = snd_pcm_action(&snd_pcm_action_drain_init, substream, 0); result = snd_pcm_action(&snd_pcm_action_drain_init, substream, 0);
if (result < 0) { if (result < 0)
snd_pcm_stream_unlock_irq(substream); goto unlock;
goto _error; /* in non-blocking, we don't wait in ioctl but let caller poll */
if (nonblock) {
result = -EAGAIN;
goto unlock;
} }
for (;;) { for (;;) {
...@@ -1504,18 +1510,18 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream) ...@@ -1504,18 +1510,18 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream)
} }
} }
unlock:
snd_pcm_stream_unlock_irq(substream); snd_pcm_stream_unlock_irq(substream);
_error: if (!nonblock) {
for (i = 0; i < num_drecs; i++) { for (i = 0; i < num_drecs; i++) {
d = &drec[i]; d = &drec[i];
runtime = d->substream->runtime; runtime = d->substream->runtime;
remove_wait_queue(&runtime->sleep, &d->wait); remove_wait_queue(&runtime->sleep, &d->wait);
runtime->stop_threshold = d->stop_threshold; }
if (drec != &drec_tmp)
kfree(drec);
} }
if (drec != &drec_tmp)
kfree(drec);
snd_power_unlock(card); snd_power_unlock(card);
return result; return result;
...@@ -2208,6 +2214,9 @@ static snd_pcm_sframes_t snd_pcm_playback_rewind(struct snd_pcm_substream *subst ...@@ -2208,6 +2214,9 @@ static snd_pcm_sframes_t snd_pcm_playback_rewind(struct snd_pcm_substream *subst
case SNDRV_PCM_STATE_XRUN: case SNDRV_PCM_STATE_XRUN:
ret = -EPIPE; ret = -EPIPE;
goto __end; goto __end;
case SNDRV_PCM_STATE_SUSPENDED:
ret = -ESTRPIPE;
goto __end;
default: default:
ret = -EBADFD; ret = -EBADFD;
goto __end; goto __end;
...@@ -2253,6 +2262,9 @@ static snd_pcm_sframes_t snd_pcm_capture_rewind(struct snd_pcm_substream *substr ...@@ -2253,6 +2262,9 @@ static snd_pcm_sframes_t snd_pcm_capture_rewind(struct snd_pcm_substream *substr
case SNDRV_PCM_STATE_XRUN: case SNDRV_PCM_STATE_XRUN:
ret = -EPIPE; ret = -EPIPE;
goto __end; goto __end;
case SNDRV_PCM_STATE_SUSPENDED:
ret = -ESTRPIPE;
goto __end;
default: default:
ret = -EBADFD; ret = -EBADFD;
goto __end; goto __end;
...@@ -2299,6 +2311,9 @@ static snd_pcm_sframes_t snd_pcm_playback_forward(struct snd_pcm_substream *subs ...@@ -2299,6 +2311,9 @@ static snd_pcm_sframes_t snd_pcm_playback_forward(struct snd_pcm_substream *subs
case SNDRV_PCM_STATE_XRUN: case SNDRV_PCM_STATE_XRUN:
ret = -EPIPE; ret = -EPIPE;
goto __end; goto __end;
case SNDRV_PCM_STATE_SUSPENDED:
ret = -ESTRPIPE;
goto __end;
default: default:
ret = -EBADFD; ret = -EBADFD;
goto __end; goto __end;
...@@ -2345,6 +2360,9 @@ static snd_pcm_sframes_t snd_pcm_capture_forward(struct snd_pcm_substream *subst ...@@ -2345,6 +2360,9 @@ static snd_pcm_sframes_t snd_pcm_capture_forward(struct snd_pcm_substream *subst
case SNDRV_PCM_STATE_XRUN: case SNDRV_PCM_STATE_XRUN:
ret = -EPIPE; ret = -EPIPE;
goto __end; goto __end;
case SNDRV_PCM_STATE_SUSPENDED:
ret = -ESTRPIPE;
goto __end;
default: default:
ret = -EBADFD; ret = -EBADFD;
goto __end; goto __end;
...@@ -2544,7 +2562,7 @@ static int snd_pcm_common_ioctl1(struct file *file, ...@@ -2544,7 +2562,7 @@ static int snd_pcm_common_ioctl1(struct file *file,
return snd_pcm_hw_params_old_user(substream, arg); return snd_pcm_hw_params_old_user(substream, arg);
#endif #endif
case SNDRV_PCM_IOCTL_DRAIN: case SNDRV_PCM_IOCTL_DRAIN:
return snd_pcm_drain(substream); return snd_pcm_drain(substream, file);
case SNDRV_PCM_IOCTL_DROP: case SNDRV_PCM_IOCTL_DROP:
return snd_pcm_drop(substream); return snd_pcm_drop(substream);
case SNDRV_PCM_IOCTL_PAUSE: case SNDRV_PCM_IOCTL_PAUSE:
......
...@@ -274,7 +274,7 @@ static int open_substream(struct snd_rawmidi *rmidi, ...@@ -274,7 +274,7 @@ static int open_substream(struct snd_rawmidi *rmidi,
return err; return err;
substream->opened = 1; substream->opened = 1;
if (substream->use_count++ == 0) if (substream->use_count++ == 0)
substream->active_sensing = 1; substream->active_sensing = 0;
if (mode & SNDRV_RAWMIDI_LFLG_APPEND) if (mode & SNDRV_RAWMIDI_LFLG_APPEND)
substream->append = 1; substream->append = 1;
rmidi->streams[substream->stream].substream_opened++; rmidi->streams[substream->stream].substream_opened++;
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#include <sound/asoundef.h>
#include "seq_oss_midi.h" #include "seq_oss_midi.h"
#include "seq_oss_readq.h" #include "seq_oss_readq.h"
#include "seq_oss_timer.h" #include "seq_oss_timer.h"
...@@ -476,19 +477,20 @@ snd_seq_oss_midi_reset(struct seq_oss_devinfo *dp, int dev) ...@@ -476,19 +477,20 @@ snd_seq_oss_midi_reset(struct seq_oss_devinfo *dp, int dev)
ev.source.port = dp->port; ev.source.port = dp->port;
if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_SYNTH) { if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_SYNTH) {
ev.type = SNDRV_SEQ_EVENT_SENSING; ev.type = SNDRV_SEQ_EVENT_SENSING;
snd_seq_oss_dispatch(dp, &ev, 0, 0); /* active sensing */ snd_seq_oss_dispatch(dp, &ev, 0, 0);
} }
for (c = 0; c < 16; c++) { for (c = 0; c < 16; c++) {
ev.type = SNDRV_SEQ_EVENT_CONTROLLER; ev.type = SNDRV_SEQ_EVENT_CONTROLLER;
ev.data.control.channel = c; ev.data.control.channel = c;
ev.data.control.param = 123; ev.data.control.param = MIDI_CTL_ALL_NOTES_OFF;
snd_seq_oss_dispatch(dp, &ev, 0, 0); /* all notes off */ snd_seq_oss_dispatch(dp, &ev, 0, 0);
if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_MUSIC) { if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_MUSIC) {
ev.data.control.param = 121; ev.data.control.param =
snd_seq_oss_dispatch(dp, &ev, 0, 0); /* reset all controllers */ MIDI_CTL_RESET_CONTROLLERS;
snd_seq_oss_dispatch(dp, &ev, 0, 0);
ev.type = SNDRV_SEQ_EVENT_PITCHBEND; ev.type = SNDRV_SEQ_EVENT_PITCHBEND;
ev.data.control.value = 0; ev.data.control.value = 0;
snd_seq_oss_dispatch(dp, &ev, 0, 0); /* bender off */ snd_seq_oss_dispatch(dp, &ev, 0, 0);
} }
} }
} }
......
...@@ -120,7 +120,8 @@ static int dump_midi(struct snd_rawmidi_substream *substream, const char *buf, i ...@@ -120,7 +120,8 @@ static int dump_midi(struct snd_rawmidi_substream *substream, const char *buf, i
return -EINVAL; return -EINVAL;
runtime = substream->runtime; runtime = substream->runtime;
if ((tmp = runtime->avail) < count) { if ((tmp = runtime->avail) < count) {
snd_printd("warning, output event was lost (count = %i, available = %i)\n", count, tmp); if (printk_ratelimit())
snd_printk(KERN_ERR "MIDI output buffer overrun\n");
return -ENOMEM; return -ENOMEM;
} }
if (snd_rawmidi_kernel_write(substream, buf, count) < count) if (snd_rawmidi_kernel_write(substream, buf, count) < count)
...@@ -236,6 +237,7 @@ static int midisynth_use(void *private_data, struct snd_seq_port_subscribe *info ...@@ -236,6 +237,7 @@ static int midisynth_use(void *private_data, struct snd_seq_port_subscribe *info
memset(&params, 0, sizeof(params)); memset(&params, 0, sizeof(params));
params.avail_min = 1; params.avail_min = 1;
params.buffer_size = output_buffer_size; params.buffer_size = output_buffer_size;
params.no_active_sensing = 1;
if ((err = snd_rawmidi_output_params(msynth->output_rfile.output, &params)) < 0) { if ((err = snd_rawmidi_output_params(msynth->output_rfile.output, &params)) < 0) {
snd_rawmidi_kernel_release(&msynth->output_rfile); snd_rawmidi_kernel_release(&msynth->output_rfile);
return err; return err;
...@@ -248,12 +250,9 @@ static int midisynth_use(void *private_data, struct snd_seq_port_subscribe *info ...@@ -248,12 +250,9 @@ static int midisynth_use(void *private_data, struct snd_seq_port_subscribe *info
static int midisynth_unuse(void *private_data, struct snd_seq_port_subscribe *info) static int midisynth_unuse(void *private_data, struct snd_seq_port_subscribe *info)
{ {
struct seq_midisynth *msynth = private_data; struct seq_midisynth *msynth = private_data;
unsigned char buf = 0xff; /* MIDI reset */
if (snd_BUG_ON(!msynth->output_rfile.output)) if (snd_BUG_ON(!msynth->output_rfile.output))
return -EINVAL; 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); snd_rawmidi_drain_output(msynth->output_rfile.output);
return snd_rawmidi_kernel_release(&msynth->output_rfile); return snd_rawmidi_kernel_release(&msynth->output_rfile);
} }
......
...@@ -353,7 +353,8 @@ static void master_free(struct snd_kcontrol *kcontrol) ...@@ -353,7 +353,8 @@ static void master_free(struct snd_kcontrol *kcontrol)
* *
* The optional argument @tlv can be used to specify the TLV information * The optional argument @tlv can be used to specify the TLV information
* for dB scale of the master control. It should be a single element * for dB scale of the master control. It should be a single element
* with #SNDRV_CTL_TLVT_DB_SCALE type, and should be the max 0dB. * with #SNDRV_CTL_TLVT_DB_SCALE, #SNDRV_CTL_TLV_DB_MINMAX or
* #SNDRV_CTL_TLVT_DB_MINMAX_MUTE type, and should be the max 0dB.
*/ */
struct snd_kcontrol *snd_ctl_make_virtual_master(char *name, struct snd_kcontrol *snd_ctl_make_virtual_master(char *name,
const unsigned int *tlv) const unsigned int *tlv)
...@@ -384,7 +385,10 @@ struct snd_kcontrol *snd_ctl_make_virtual_master(char *name, ...@@ -384,7 +385,10 @@ struct snd_kcontrol *snd_ctl_make_virtual_master(char *name,
kctl->private_free = master_free; kctl->private_free = master_free;
/* additional (constant) TLV read */ /* additional (constant) TLV read */
if (tlv && tlv[0] == SNDRV_CTL_TLVT_DB_SCALE) { if (tlv &&
(tlv[0] == SNDRV_CTL_TLVT_DB_SCALE ||
tlv[0] == SNDRV_CTL_TLVT_DB_MINMAX ||
tlv[0] == SNDRV_CTL_TLVT_DB_MINMAX_MUTE)) {
kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ; kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
memcpy(master->tlv, tlv, sizeof(master->tlv)); memcpy(master->tlv, tlv, sizeof(master->tlv));
kctl->tlv.p = master->tlv; kctl->tlv.p = master->tlv;
......
此差异已折叠。
/* /*
* Driver for C-Media's CMI8330 soundcards. * Driver for C-Media's CMI8330 and CMI8329 soundcards.
* Copyright (c) by George Talusan <gstalusan@uwaterloo.ca> * Copyright (c) by George Talusan <gstalusan@uwaterloo.ca>
* http://www.undergrad.math.uwaterloo.ca/~gstalusa * http://www.undergrad.math.uwaterloo.ca/~gstalusa
* *
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
* *
* This card has two mixers and two PCM devices. I've cheesed it such * This card has two mixers and two PCM devices. I've cheesed it such
* that recording and playback can be done through the same device. * that recording and playback can be done through the same device.
* The driver "magically" routes the capturing to the CMI8330 codec, * The driver "magically" routes the capturing to the AD1848 codec,
* and playback to the SB16 codec. This allows for full-duplex mode * and playback to the SB16 codec. This allows for full-duplex mode
* to some extent. * to some extent.
* The utilities in alsa-utils are aware of both devices, so passing * The utilities in alsa-utils are aware of both devices, so passing
...@@ -64,7 +64,7 @@ ...@@ -64,7 +64,7 @@
/* /*
*/ */
MODULE_AUTHOR("George Talusan <gstalusan@uwaterloo.ca>"); MODULE_AUTHOR("George Talusan <gstalusan@uwaterloo.ca>");
MODULE_DESCRIPTION("C-Media CMI8330"); MODULE_DESCRIPTION("C-Media CMI8330/CMI8329");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{C-Media,CMI8330,isapnp:{CMI0001,@@@0001,@X@0001}}}"); MODULE_SUPPORTED_DEVICE("{{C-Media,CMI8330,isapnp:{CMI0001,@@@0001,@X@0001}}}");
...@@ -86,38 +86,38 @@ static long mpuport[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; ...@@ -86,38 +86,38 @@ static long mpuport[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
static int mpuirq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; static int mpuirq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
module_param_array(index, int, NULL, 0444); module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for CMI8330 soundcard."); MODULE_PARM_DESC(index, "Index value for CMI8330/CMI8329 soundcard.");
module_param_array(id, charp, NULL, 0444); module_param_array(id, charp, NULL, 0444);
MODULE_PARM_DESC(id, "ID string for CMI8330 soundcard."); MODULE_PARM_DESC(id, "ID string for CMI8330/CMI8329 soundcard.");
module_param_array(enable, bool, NULL, 0444); module_param_array(enable, bool, NULL, 0444);
MODULE_PARM_DESC(enable, "Enable CMI8330 soundcard."); MODULE_PARM_DESC(enable, "Enable CMI8330/CMI8329 soundcard.");
#ifdef CONFIG_PNP #ifdef CONFIG_PNP
module_param_array(isapnp, bool, NULL, 0444); module_param_array(isapnp, bool, NULL, 0444);
MODULE_PARM_DESC(isapnp, "PnP detection for specified soundcard."); MODULE_PARM_DESC(isapnp, "PnP detection for specified soundcard.");
#endif #endif
module_param_array(sbport, long, NULL, 0444); module_param_array(sbport, long, NULL, 0444);
MODULE_PARM_DESC(sbport, "Port # for CMI8330 SB driver."); MODULE_PARM_DESC(sbport, "Port # for CMI8330/CMI8329 SB driver.");
module_param_array(sbirq, int, NULL, 0444); module_param_array(sbirq, int, NULL, 0444);
MODULE_PARM_DESC(sbirq, "IRQ # for CMI8330 SB driver."); MODULE_PARM_DESC(sbirq, "IRQ # for CMI8330/CMI8329 SB driver.");
module_param_array(sbdma8, int, NULL, 0444); module_param_array(sbdma8, int, NULL, 0444);
MODULE_PARM_DESC(sbdma8, "DMA8 for CMI8330 SB driver."); MODULE_PARM_DESC(sbdma8, "DMA8 for CMI8330/CMI8329 SB driver.");
module_param_array(sbdma16, int, NULL, 0444); module_param_array(sbdma16, int, NULL, 0444);
MODULE_PARM_DESC(sbdma16, "DMA16 for CMI8330 SB driver."); MODULE_PARM_DESC(sbdma16, "DMA16 for CMI8330/CMI8329 SB driver.");
module_param_array(wssport, long, NULL, 0444); module_param_array(wssport, long, NULL, 0444);
MODULE_PARM_DESC(wssport, "Port # for CMI8330 WSS driver."); MODULE_PARM_DESC(wssport, "Port # for CMI8330/CMI8329 WSS driver.");
module_param_array(wssirq, int, NULL, 0444); module_param_array(wssirq, int, NULL, 0444);
MODULE_PARM_DESC(wssirq, "IRQ # for CMI8330 WSS driver."); MODULE_PARM_DESC(wssirq, "IRQ # for CMI8330/CMI8329 WSS driver.");
module_param_array(wssdma, int, NULL, 0444); module_param_array(wssdma, int, NULL, 0444);
MODULE_PARM_DESC(wssdma, "DMA for CMI8330 WSS driver."); MODULE_PARM_DESC(wssdma, "DMA for CMI8330/CMI8329 WSS driver.");
module_param_array(fmport, long, NULL, 0444); module_param_array(fmport, long, NULL, 0444);
MODULE_PARM_DESC(fmport, "FM port # for CMI8330 driver."); MODULE_PARM_DESC(fmport, "FM port # for CMI8330/CMI8329 driver.");
module_param_array(mpuport, long, NULL, 0444); module_param_array(mpuport, long, NULL, 0444);
MODULE_PARM_DESC(mpuport, "MPU-401 port # for CMI8330 driver."); MODULE_PARM_DESC(mpuport, "MPU-401 port # for CMI8330/CMI8329 driver.");
module_param_array(mpuirq, int, NULL, 0444); module_param_array(mpuirq, int, NULL, 0444);
MODULE_PARM_DESC(mpuirq, "IRQ # for CMI8330 MPU-401 port."); MODULE_PARM_DESC(mpuirq, "IRQ # for CMI8330/CMI8329 MPU-401 port.");
#ifdef CONFIG_PNP #ifdef CONFIG_PNP
static int isa_registered; static int isa_registered;
static int pnp_registered; static int pnp_registered;
...@@ -156,6 +156,11 @@ static unsigned char snd_cmi8330_image[((CMI8330_CDINGAIN)-16) + 1] = ...@@ -156,6 +156,11 @@ static unsigned char snd_cmi8330_image[((CMI8330_CDINGAIN)-16) + 1] =
typedef int (*snd_pcm_open_callback_t)(struct snd_pcm_substream *); typedef int (*snd_pcm_open_callback_t)(struct snd_pcm_substream *);
enum card_type {
CMI8330,
CMI8329
};
struct snd_cmi8330 { struct snd_cmi8330 {
#ifdef CONFIG_PNP #ifdef CONFIG_PNP
struct pnp_dev *cap; struct pnp_dev *cap;
...@@ -172,11 +177,14 @@ struct snd_cmi8330 { ...@@ -172,11 +177,14 @@ struct snd_cmi8330 {
snd_pcm_open_callback_t open; snd_pcm_open_callback_t open;
void *private_data; /* sb or wss */ void *private_data; /* sb or wss */
} streams[2]; } streams[2];
enum card_type type;
}; };
#ifdef CONFIG_PNP #ifdef CONFIG_PNP
static struct pnp_card_device_id snd_cmi8330_pnpids[] = { static struct pnp_card_device_id snd_cmi8330_pnpids[] = {
{ .id = "CMI0001", .devs = { { "@X@0001" }, { "@@@0001" }, { "@H@0001" }, { "A@@0001" } } },
{ .id = "CMI0001", .devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" } } }, { .id = "CMI0001", .devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" } } },
{ .id = "" } { .id = "" }
}; };
...@@ -304,7 +312,7 @@ static int __devinit snd_cmi8330_mixer(struct snd_card *card, struct snd_cmi8330 ...@@ -304,7 +312,7 @@ static int __devinit snd_cmi8330_mixer(struct snd_card *card, struct snd_cmi8330
unsigned int idx; unsigned int idx;
int err; int err;
strcpy(card->mixername, "CMI8330/C3D"); strcpy(card->mixername, (acard->type == CMI8329) ? "CMI8329" : "CMI8330/C3D");
for (idx = 0; idx < ARRAY_SIZE(snd_cmi8330_controls); idx++) { for (idx = 0; idx < ARRAY_SIZE(snd_cmi8330_controls); idx++) {
err = snd_ctl_add(card, err = snd_ctl_add(card,
...@@ -329,6 +337,9 @@ static int __devinit snd_cmi8330_pnp(int dev, struct snd_cmi8330 *acard, ...@@ -329,6 +337,9 @@ static int __devinit snd_cmi8330_pnp(int dev, struct snd_cmi8330 *acard,
struct pnp_dev *pdev; struct pnp_dev *pdev;
int err; int err;
/* CMI8329 has a device with ID A@@0001, CMI8330 does not */
acard->type = (id->devs[3].id[0]) ? CMI8329 : CMI8330;
acard->cap = pnp_request_card_device(card, id->devs[0].id, NULL); acard->cap = pnp_request_card_device(card, id->devs[0].id, NULL);
if (acard->cap == NULL) if (acard->cap == NULL)
return -EBUSY; return -EBUSY;
...@@ -345,38 +356,45 @@ static int __devinit snd_cmi8330_pnp(int dev, struct snd_cmi8330 *acard, ...@@ -345,38 +356,45 @@ static int __devinit snd_cmi8330_pnp(int dev, struct snd_cmi8330 *acard,
err = pnp_activate_dev(pdev); err = pnp_activate_dev(pdev);
if (err < 0) { if (err < 0) {
snd_printk(KERN_ERR "CMI8330/C3D PnP configure failure\n"); snd_printk(KERN_ERR "AD1848 PnP configure failure\n");
return -EBUSY; return -EBUSY;
} }
wssport[dev] = pnp_port_start(pdev, 0); wssport[dev] = pnp_port_start(pdev, 0);
wssdma[dev] = pnp_dma(pdev, 0); wssdma[dev] = pnp_dma(pdev, 0);
wssirq[dev] = pnp_irq(pdev, 0); wssirq[dev] = pnp_irq(pdev, 0);
fmport[dev] = pnp_port_start(pdev, 1); if (pnp_port_start(pdev, 1))
fmport[dev] = pnp_port_start(pdev, 1);
/* allocate SB16 resources */ /* allocate SB16 resources */
pdev = acard->play; pdev = acard->play;
err = pnp_activate_dev(pdev); err = pnp_activate_dev(pdev);
if (err < 0) { if (err < 0) {
snd_printk(KERN_ERR "CMI8330/C3D (SB16) PnP configure failure\n"); snd_printk(KERN_ERR "SB16 PnP configure failure\n");
return -EBUSY; return -EBUSY;
} }
sbport[dev] = pnp_port_start(pdev, 0); sbport[dev] = pnp_port_start(pdev, 0);
sbdma8[dev] = pnp_dma(pdev, 0); sbdma8[dev] = pnp_dma(pdev, 0);
sbdma16[dev] = pnp_dma(pdev, 1); sbdma16[dev] = pnp_dma(pdev, 1);
sbirq[dev] = pnp_irq(pdev, 0); sbirq[dev] = pnp_irq(pdev, 0);
/* On CMI8239, the OPL3 port might be present in SB16 PnP resources */
if (fmport[dev] == SNDRV_AUTO_PORT) {
if (pnp_port_start(pdev, 1))
fmport[dev] = pnp_port_start(pdev, 1);
else
fmport[dev] = 0x388; /* Or hardwired */
}
/* allocate MPU-401 resources */ /* allocate MPU-401 resources */
pdev = acard->mpu; pdev = acard->mpu;
err = pnp_activate_dev(pdev); err = pnp_activate_dev(pdev);
if (err < 0) { if (err < 0)
snd_printk(KERN_ERR snd_printk(KERN_ERR "MPU-401 PnP configure failure: will be disabled\n");
"CMI8330/C3D (MPU-401) PnP configure failure\n"); else {
return -EBUSY; mpuport[dev] = pnp_port_start(pdev, 0);
mpuirq[dev] = pnp_irq(pdev, 0);
} }
mpuport[dev] = pnp_port_start(pdev, 0);
mpuirq[dev] = pnp_irq(pdev, 0);
return 0; return 0;
} }
#endif #endif
...@@ -430,9 +448,9 @@ static int __devinit snd_cmi8330_pcm(struct snd_card *card, struct snd_cmi8330 * ...@@ -430,9 +448,9 @@ static int __devinit snd_cmi8330_pcm(struct snd_card *card, struct snd_cmi8330 *
snd_cmi8330_capture_open snd_cmi8330_capture_open
}; };
if ((err = snd_pcm_new(card, "CMI8330", 0, 1, 1, &pcm)) < 0) if ((err = snd_pcm_new(card, (chip->type == CMI8329) ? "CMI8329" : "CMI8330", 0, 1, 1, &pcm)) < 0)
return err; return err;
strcpy(pcm->name, "CMI8330"); strcpy(pcm->name, (chip->type == CMI8329) ? "CMI8329" : "CMI8330");
pcm->private_data = chip; pcm->private_data = chip;
/* SB16 */ /* SB16 */
...@@ -527,11 +545,11 @@ static int __devinit snd_cmi8330_probe(struct snd_card *card, int dev) ...@@ -527,11 +545,11 @@ static int __devinit snd_cmi8330_probe(struct snd_card *card, int dev)
wssdma[dev], -1, wssdma[dev], -1,
WSS_HW_DETECT, 0, &acard->wss); WSS_HW_DETECT, 0, &acard->wss);
if (err < 0) { if (err < 0) {
snd_printk(KERN_ERR PFX "(CMI8330) device busy??\n"); snd_printk(KERN_ERR PFX "AD1848 device busy??\n");
return err; return err;
} }
if (acard->wss->hardware != WSS_HW_CMI8330) { if (acard->wss->hardware != WSS_HW_CMI8330) {
snd_printk(KERN_ERR PFX "(CMI8330) not found during probe\n"); snd_printk(KERN_ERR PFX "AD1848 not found during probe\n");
return -ENODEV; return -ENODEV;
} }
...@@ -541,11 +559,11 @@ static int __devinit snd_cmi8330_probe(struct snd_card *card, int dev) ...@@ -541,11 +559,11 @@ static int __devinit snd_cmi8330_probe(struct snd_card *card, int dev)
sbdma8[dev], sbdma8[dev],
sbdma16[dev], sbdma16[dev],
SB_HW_AUTO, &acard->sb)) < 0) { SB_HW_AUTO, &acard->sb)) < 0) {
snd_printk(KERN_ERR PFX "(SB16) device busy??\n"); snd_printk(KERN_ERR PFX "SB16 device busy??\n");
return err; return err;
} }
if (acard->sb->hardware != SB_HW_16) { if (acard->sb->hardware != SB_HW_16) {
snd_printk(KERN_ERR PFX "(SB16) not found during probe\n"); snd_printk(KERN_ERR PFX "SB16 not found during probe\n");
return err; return err;
} }
...@@ -585,8 +603,8 @@ static int __devinit snd_cmi8330_probe(struct snd_card *card, int dev) ...@@ -585,8 +603,8 @@ static int __devinit snd_cmi8330_probe(struct snd_card *card, int dev)
mpuport[dev]); mpuport[dev]);
} }
strcpy(card->driver, "CMI8330/C3D"); strcpy(card->driver, (acard->type == CMI8329) ? "CMI8329" : "CMI8330/C3D");
strcpy(card->shortname, "C-Media CMI8330/C3D"); strcpy(card->shortname, (acard->type == CMI8329) ? "C-Media CMI8329" : "C-Media CMI8330/C3D");
sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d", sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d",
card->shortname, card->shortname,
acard->wss->port, acard->wss->port,
......
...@@ -127,15 +127,16 @@ static void midi_poll(unsigned long dummy) ...@@ -127,15 +127,16 @@ static void midi_poll(unsigned long dummy)
for (dev = 0; dev < num_midis; dev++) for (dev = 0; dev < num_midis; dev++)
if (midi_devs[dev] != NULL && midi_out_buf[dev] != NULL) if (midi_devs[dev] != NULL && midi_out_buf[dev] != NULL)
{ {
int ok = 1; while (DATA_AVAIL(midi_out_buf[dev]))
while (DATA_AVAIL(midi_out_buf[dev]) && ok)
{ {
int ok;
int c = midi_out_buf[dev]->queue[midi_out_buf[dev]->head]; int c = midi_out_buf[dev]->queue[midi_out_buf[dev]->head];
spin_unlock_irqrestore(&lock,flags);/* Give some time to others */ spin_unlock_irqrestore(&lock,flags);/* Give some time to others */
ok = midi_devs[dev]->outputc(dev, c); ok = midi_devs[dev]->outputc(dev, c);
spin_lock_irqsave(&lock, flags); spin_lock_irqsave(&lock, flags);
if (!ok)
break;
midi_out_buf[dev]->head = (midi_out_buf[dev]->head + 1) % MAX_QUEUE_SIZE; midi_out_buf[dev]->head = (midi_out_buf[dev]->head + 1) % MAX_QUEUE_SIZE;
midi_out_buf[dev]->len--; midi_out_buf[dev]->len--;
} }
......
...@@ -628,7 +628,7 @@ static void li_setup_dma(dma_chan_t *chan, ...@@ -628,7 +628,7 @@ static void li_setup_dma(dma_chan_t *chan,
ASSERT(!(buffer_paddr & 0xFF)); ASSERT(!(buffer_paddr & 0xFF));
chan->baseval = (buffer_paddr >> 8) | 1 << (37 - 8); chan->baseval = (buffer_paddr >> 8) | 1 << (37 - 8);
chan->cfgval = (!LI_CCFG_LOCK | chan->cfgval = ((chan->cfgval & ~LI_CCFG_LOCK) |
SHIFT_FIELD(desc->ad1843_slot, LI_CCFG_SLOT) | SHIFT_FIELD(desc->ad1843_slot, LI_CCFG_SLOT) |
desc->direction | desc->direction |
mode | mode |
...@@ -638,9 +638,9 @@ static void li_setup_dma(dma_chan_t *chan, ...@@ -638,9 +638,9 @@ static void li_setup_dma(dma_chan_t *chan,
tmask = 13 - fragshift; /* See Lithium DMA Notes above. */ tmask = 13 - fragshift; /* See Lithium DMA Notes above. */
ASSERT(size >= 2 && size <= 7); ASSERT(size >= 2 && size <= 7);
ASSERT(tmask >= 1 && tmask <= 7); ASSERT(tmask >= 1 && tmask <= 7);
chan->ctlval = (!LI_CCTL_RESET | chan->ctlval = ((chan->ctlval & ~LI_CCTL_RESET) |
SHIFT_FIELD(size, LI_CCTL_SIZE) | SHIFT_FIELD(size, LI_CCTL_SIZE) |
!LI_CCTL_DMA_ENABLE | (chan->ctlval & ~LI_CCTL_DMA_ENABLE) |
SHIFT_FIELD(tmask, LI_CCTL_TMASK) | SHIFT_FIELD(tmask, LI_CCTL_TMASK) |
SHIFT_FIELD(0, LI_CCTL_TPTR)); SHIFT_FIELD(0, LI_CCTL_TPTR));
......
...@@ -135,11 +135,11 @@ config SND_AW2 ...@@ -135,11 +135,11 @@ config SND_AW2
config SND_AZT3328 config SND_AZT3328
tristate "Aztech AZF3328 / PCI168 (EXPERIMENTAL)" tristate "Aztech AZF3328 / PCI168"
depends on EXPERIMENTAL
select SND_OPL3_LIB select SND_OPL3_LIB
select SND_MPU401_UART select SND_MPU401_UART
select SND_PCM select SND_PCM
select SND_RAWMIDI
help help
Say Y here to include support for Aztech AZF3328 (PCI168) Say Y here to include support for Aztech AZF3328 (PCI168)
soundcards. soundcards.
......
...@@ -478,45 +478,6 @@ static int snd_ali_reset_5451(struct snd_ali *codec) ...@@ -478,45 +478,6 @@ static int snd_ali_reset_5451(struct snd_ali *codec)
return 0; return 0;
} }
#ifdef CODEC_RESET
static int snd_ali_reset_codec(struct snd_ali *codec)
{
struct pci_dev *pci_dev;
unsigned char bVal;
unsigned int dwVal;
unsigned short wCount, wReg;
pci_dev = codec->pci_m1533;
pci_read_config_dword(pci_dev, 0x7c, &dwVal);
pci_write_config_dword(pci_dev, 0x7c, dwVal | 0x08000000);
udelay(5000);
pci_read_config_dword(pci_dev, 0x7c, &dwVal);
pci_write_config_dword(pci_dev, 0x7c, dwVal & 0xf7ffffff);
udelay(5000);
bVal = inb(ALI_REG(codec,ALI_SCTRL));
bVal |= 0x02;
outb(ALI_REG(codec,ALI_SCTRL),bVal);
udelay(5000);
bVal = inb(ALI_REG(codec,ALI_SCTRL));
bVal &= 0xfd;
outb(ALI_REG(codec,ALI_SCTRL),bVal);
udelay(15000);
wCount = 200;
while (wCount--) {
wReg = snd_ali_codec_read(codec->ac97, AC97_POWERDOWN);
if ((wReg & 0x000f) == 0x000f)
return 0;
udelay(5000);
}
return -1;
}
#endif
/* /*
* ALI 5451 Controller * ALI 5451 Controller
*/ */
...@@ -561,22 +522,6 @@ static void snd_ali_disable_address_interrupt(struct snd_ali *codec) ...@@ -561,22 +522,6 @@ static void snd_ali_disable_address_interrupt(struct snd_ali *codec)
outl(gc, ALI_REG(codec, ALI_GC_CIR)); outl(gc, ALI_REG(codec, ALI_GC_CIR));
} }
#if 0 /* not used */
static void snd_ali_enable_voice_irq(struct snd_ali *codec,
unsigned int channel)
{
unsigned int mask;
struct snd_ali_channel_control *pchregs = &(codec->chregs);
snd_ali_printk("enable_voice_irq channel=%d\n",channel);
mask = 1 << (channel & 0x1f);
pchregs->data.ainten = inl(ALI_REG(codec, pchregs->regs.ainten));
pchregs->data.ainten |= mask;
outl(pchregs->data.ainten, ALI_REG(codec, pchregs->regs.ainten));
}
#endif
static void snd_ali_disable_voice_irq(struct snd_ali *codec, static void snd_ali_disable_voice_irq(struct snd_ali *codec,
unsigned int channel) unsigned int channel)
{ {
...@@ -677,16 +622,6 @@ static void snd_ali_free_channel_pcm(struct snd_ali *codec, int channel) ...@@ -677,16 +622,6 @@ static void snd_ali_free_channel_pcm(struct snd_ali *codec, int channel)
} }
} }
#if 0 /* not used */
static void snd_ali_start_voice(struct snd_ali *codec, unsigned int channel)
{
unsigned int mask = 1 << (channel & 0x1f);
snd_ali_printk("start_voice: channel=%d\n",channel);
outl(mask, ALI_REG(codec,codec->chregs.regs.start));
}
#endif
static void snd_ali_stop_voice(struct snd_ali *codec, unsigned int channel) static void snd_ali_stop_voice(struct snd_ali *codec, unsigned int channel)
{ {
unsigned int mask = 1 << (channel & 0x1f); unsigned int mask = 1 << (channel & 0x1f);
......
此差异已折叠。
...@@ -6,50 +6,59 @@ ...@@ -6,50 +6,59 @@
/*** main I/O area port indices ***/ /*** main I/O area port indices ***/
/* (only 0x70 of 0x80 bytes saved/restored by Windows driver) */ /* (only 0x70 of 0x80 bytes saved/restored by Windows driver) */
#define AZF_IO_SIZE_CODEC 0x80 #define AZF_IO_SIZE_CTRL 0x80
#define AZF_IO_SIZE_CODEC_PM 0x70 #define AZF_IO_SIZE_CTRL_PM 0x70
/* the driver initialisation suggests a layout of 4 main areas: /* the driver initialisation suggests a layout of 4 areas
* from 0x00 (playback), from 0x20 (recording) and from 0x40 (maybe MPU401??). * within the main card control I/O:
* from 0x00 (playback codec), from 0x20 (recording codec)
* and from 0x40 (most certainly I2S out codec).
* And another area from 0x60 to 0x6f (DirectX timer, IRQ management, * And another area from 0x60 to 0x6f (DirectX timer, IRQ management,
* power management etc.???). */ * power management etc.???). */
/** playback area **/ #define AZF_IO_OFFS_CODEC_PLAYBACK 0x00
#define IDX_IO_PLAY_FLAGS 0x00 /* PU:0x0000 */ #define AZF_IO_OFFS_CODEC_CAPTURE 0x20
#define AZF_IO_OFFS_CODEC_I2S_OUT 0x40
#define IDX_IO_CODEC_DMA_FLAGS 0x00 /* PU:0x0000 */
/* able to reactivate output after output muting due to 8/16bit /* able to reactivate output after output muting due to 8/16bit
* output change, just like 0x0002. * output change, just like 0x0002.
* 0x0001 is the only bit that's able to start the DMA counter */ * 0x0001 is the only bit that's able to start the DMA counter */
#define DMA_RESUME 0x0001 /* paused if cleared ? */ #define DMA_RESUME 0x0001 /* paused if cleared? */
/* 0x0002 *temporarily* set during DMA stopping. hmm /* 0x0002 *temporarily* set during DMA stopping. hmm
* both 0x0002 and 0x0004 set in playback setup. */ * both 0x0002 and 0x0004 set in playback setup. */
/* able to reactivate output after output muting due to 8/16bit /* able to reactivate output after output muting due to 8/16bit
* output change, just like 0x0001. */ * output change, just like 0x0001. */
#define DMA_PLAY_SOMETHING1 0x0002 /* \ alternated (toggled) */ #define DMA_RUN_SOMETHING1 0x0002 /* \ alternated (toggled) */
/* 0x0004: NOT able to reactivate output */ /* 0x0004: NOT able to reactivate output */
#define DMA_PLAY_SOMETHING2 0x0004 /* / bits */ #define DMA_RUN_SOMETHING2 0x0004 /* / bits */
#define SOMETHING_ALMOST_ALWAYS_SET 0x0008 /* ???; can be modified */ #define SOMETHING_ALMOST_ALWAYS_SET 0x0008 /* ???; can be modified */
#define DMA_EPILOGUE_SOMETHING 0x0010 #define DMA_EPILOGUE_SOMETHING 0x0010
#define DMA_SOMETHING_ELSE 0x0020 /* ??? */ #define DMA_SOMETHING_ELSE 0x0020 /* ??? */
#define SOMETHING_UNMODIFIABLE 0xffc0 /* unused ? not modifiable */ #define SOMETHING_UNMODIFIABLE 0xffc0 /* unused? not modifiable */
#define IDX_IO_PLAY_IRQTYPE 0x02 /* PU:0x0001 */ #define IDX_IO_CODEC_IRQTYPE 0x02 /* PU:0x0001 */
/* write back to flags in case flags are set, in order to ACK IRQ in handler /* write back to flags in case flags are set, in order to ACK IRQ in handler
* (bit 1 of port 0x64 indicates interrupt for one of these three types) * (bit 1 of port 0x64 indicates interrupt for one of these three types)
* sometimes in this case it just writes 0xffff to globally ACK all IRQs * sometimes in this case it just writes 0xffff to globally ACK all IRQs
* settings written are not reflected when reading back, though. * settings written are not reflected when reading back, though.
* seems to be IRQ, too (frequently used: port |= 0x07 !), but who knows ? */ * seems to be IRQ, too (frequently used: port |= 0x07 !), but who knows? */
#define IRQ_PLAY_SOMETHING 0x0001 /* something & ACK */ #define IRQ_SOMETHING 0x0001 /* something & ACK */
#define IRQ_FINISHED_PLAYBUF_1 0x0002 /* 1st dmabuf finished & ACK */ #define IRQ_FINISHED_DMABUF_1 0x0002 /* 1st dmabuf finished & ACK */
#define IRQ_FINISHED_PLAYBUF_2 0x0004 /* 2nd dmabuf finished & ACK */ #define IRQ_FINISHED_DMABUF_2 0x0004 /* 2nd dmabuf finished & ACK */
#define IRQMASK_SOME_STATUS_1 0x0008 /* \ related bits */ #define IRQMASK_SOME_STATUS_1 0x0008 /* \ related bits */
#define IRQMASK_SOME_STATUS_2 0x0010 /* / (checked together in loop) */ #define IRQMASK_SOME_STATUS_2 0x0010 /* / (checked together in loop) */
#define IRQMASK_UNMODIFIABLE 0xffe0 /* unused ? not modifiable */ #define IRQMASK_UNMODIFIABLE 0xffe0 /* unused? not modifiable */
#define IDX_IO_PLAY_DMA_START_1 0x04 /* start address of 1st DMA play area, PU:0x00000000 */ /* start address of 1st DMA transfer area, PU:0x00000000 */
#define IDX_IO_PLAY_DMA_START_2 0x08 /* start address of 2nd DMA play area, PU:0x00000000 */ #define IDX_IO_CODEC_DMA_START_1 0x04
#define IDX_IO_PLAY_DMA_LEN_1 0x0c /* length of 1st DMA play area, PU:0x0000 */ /* start address of 2nd DMA transfer area, PU:0x00000000 */
#define IDX_IO_PLAY_DMA_LEN_2 0x0e /* length of 2nd DMA play area, PU:0x0000 */ #define IDX_IO_CODEC_DMA_START_2 0x08
#define IDX_IO_PLAY_DMA_CURRPOS 0x10 /* current DMA position, PU:0x00000000 */ /* both lengths of DMA transfer areas, PU:0x00000000
#define IDX_IO_PLAY_DMA_CURROFS 0x14 /* offset within current DMA play area, PU:0x0000 */ length1: offset 0x0c, length2: offset 0x0e */
#define IDX_IO_PLAY_SOUNDFORMAT 0x16 /* PU:0x0010 */ #define IDX_IO_CODEC_DMA_LENGTHS 0x0c
#define IDX_IO_CODEC_DMA_CURRPOS 0x10 /* current DMA position, PU:0x00000000 */
/* offset within current DMA transfer area, PU:0x0000 */
#define IDX_IO_CODEC_DMA_CURROFS 0x14
#define IDX_IO_CODEC_SOUNDFORMAT 0x16 /* PU:0x0010 */
/* all unspecified bits can't be modified */ /* all unspecified bits can't be modified */
#define SOUNDFORMAT_FREQUENCY_MASK 0x000f #define SOUNDFORMAT_FREQUENCY_MASK 0x000f
#define SOUNDFORMAT_XTAL1 0x00 #define SOUNDFORMAT_XTAL1 0x00
...@@ -76,6 +85,7 @@ ...@@ -76,6 +85,7 @@
#define SOUNDFORMAT_FLAG_16BIT 0x0010 #define SOUNDFORMAT_FLAG_16BIT 0x0010
#define SOUNDFORMAT_FLAG_2CHANNELS 0x0020 #define SOUNDFORMAT_FLAG_2CHANNELS 0x0020
/* define frequency helpers, for maximum value safety */ /* define frequency helpers, for maximum value safety */
enum azf_freq_t { enum azf_freq_t {
#define AZF_FREQ(rate) AZF_FREQ_##rate = rate #define AZF_FREQ(rate) AZF_FREQ_##rate = rate
...@@ -96,29 +106,6 @@ enum azf_freq_t { ...@@ -96,29 +106,6 @@ enum azf_freq_t {
#undef AZF_FREQ #undef AZF_FREQ
}; };
/** recording area (see also: playback bit flag definitions) **/
#define IDX_IO_REC_FLAGS 0x20 /* ??, PU:0x0000 */
#define IDX_IO_REC_IRQTYPE 0x22 /* ??, PU:0x0000 */
#define IRQ_REC_SOMETHING 0x0001 /* something & ACK */
#define IRQ_FINISHED_RECBUF_1 0x0002 /* 1st dmabuf finished & ACK */
#define IRQ_FINISHED_RECBUF_2 0x0004 /* 2nd dmabuf finished & ACK */
/* hmm, maybe these are just the corresponding *recording* flags ?
* but OTOH they are most likely at port 0x22 instead */
#define IRQMASK_SOME_STATUS_1 0x0008 /* \ related bits */
#define IRQMASK_SOME_STATUS_2 0x0010 /* / (checked together in loop) */
#define IDX_IO_REC_DMA_START_1 0x24 /* PU:0x00000000 */
#define IDX_IO_REC_DMA_START_2 0x28 /* PU:0x00000000 */
#define IDX_IO_REC_DMA_LEN_1 0x2c /* PU:0x0000 */
#define IDX_IO_REC_DMA_LEN_2 0x2e /* PU:0x0000 */
#define IDX_IO_REC_DMA_CURRPOS 0x30 /* PU:0x00000000 */
#define IDX_IO_REC_DMA_CURROFS 0x34 /* PU:0x00000000 */
#define IDX_IO_REC_SOUNDFORMAT 0x36 /* PU:0x0000 */
/** hmm, what is this I/O area for? MPU401?? or external DAC via I2S?? (after playback, recording, ???, timer) **/
#define IDX_IO_SOMETHING_FLAGS 0x40 /* gets set to 0x34 just like port 0x0 and 0x20 on card init, PU:0x0000 */
/* general */
#define IDX_IO_42H 0x42 /* PU:0x0001 */
/** DirectX timer, main interrupt area (FIXME: and something else?) **/ /** DirectX timer, main interrupt area (FIXME: and something else?) **/
#define IDX_IO_TIMER_VALUE 0x60 /* found this timer area by pure luck :-) */ #define IDX_IO_TIMER_VALUE 0x60 /* found this timer area by pure luck :-) */
/* timer countdown value; triggers IRQ when timer is finished */ /* timer countdown value; triggers IRQ when timer is finished */
...@@ -133,17 +120,19 @@ enum azf_freq_t { ...@@ -133,17 +120,19 @@ enum azf_freq_t {
#define IDX_IO_IRQSTATUS 0x64 #define IDX_IO_IRQSTATUS 0x64
/* some IRQ bit in here might also be used to signal a power-management timer /* some IRQ bit in here might also be used to signal a power-management timer
* timeout, to request shutdown of the chip (e.g. AD1815JS has such a thing). * timeout, to request shutdown of the chip (e.g. AD1815JS has such a thing).
* Some OPL3 hardware (e.g. in LM4560) has some special timer hardware which * OPL3 hardware contains several timers which confusingly in most cases
* can trigger an OPL3 timer IRQ, so maybe there's such a thing as well... */ * are NOT routed to an IRQ, but some designs (e.g. LM4560) DO support that,
* so I wouldn't be surprised at all to discover that AZF3328
* supports that thing as well... */
#define IRQ_PLAYBACK 0x0001 #define IRQ_PLAYBACK 0x0001
#define IRQ_RECORDING 0x0002 #define IRQ_RECORDING 0x0002
#define IRQ_UNKNOWN1 0x0004 /* most probably I2S port */ #define IRQ_I2S_OUT 0x0004 /* this IS I2S, right!? (untested) */
#define IRQ_GAMEPORT 0x0008 /* Interrupt of Digital(ly) Enhanced Game Port */ #define IRQ_GAMEPORT 0x0008 /* Interrupt of Digital(ly) Enhanced Game Port */
#define IRQ_MPU401 0x0010 #define IRQ_MPU401 0x0010
#define IRQ_TIMER 0x0020 /* DirectX timer */ #define IRQ_TIMER 0x0020 /* DirectX timer */
#define IRQ_UNKNOWN2 0x0040 /* probably unused, or possibly I2S port? */ #define IRQ_UNKNOWN2 0x0040 /* probably unused, or possibly OPL3 timer? */
#define IRQ_UNKNOWN3 0x0080 /* probably unused, or possibly I2S port? */ #define IRQ_UNKNOWN3 0x0080 /* probably unused, or possibly OPL3 timer? */
#define IDX_IO_66H 0x66 /* writing 0xffff returns 0x0000 */ #define IDX_IO_66H 0x66 /* writing 0xffff returns 0x0000 */
/* this is set to e.g. 0x3ff or 0x300, and writable; /* this is set to e.g. 0x3ff or 0x300, and writable;
* maybe some buffer limit, but I couldn't find out more, PU:0x00ff: */ * maybe some buffer limit, but I couldn't find out more, PU:0x00ff: */
...@@ -206,7 +195,7 @@ enum azf_freq_t { ...@@ -206,7 +195,7 @@ enum azf_freq_t {
/*** Gameport area port indices ***/ /*** Gameport area port indices ***/
/* (only 0x06 of 0x08 bytes saved/restored by Windows driver) */ /* (only 0x06 of 0x08 bytes saved/restored by Windows driver) */
#define AZF_IO_SIZE_GAME 0x08 #define AZF_IO_SIZE_GAME 0x08
#define AZF_IO_SIZE_GAME_PM 0x06 #define AZF_IO_SIZE_GAME_PM 0x06
enum { enum {
AZF_GAME_LEGACY_IO_PORT = 0x200 AZF_GAME_LEGACY_IO_PORT = 0x200
...@@ -272,6 +261,12 @@ enum { ...@@ -272,6 +261,12 @@ enum {
* 11 --> 1/200: */ * 11 --> 1/200: */
#define GAME_HWCFG_ADC_COUNTER_FREQ_MASK 0x06 #define GAME_HWCFG_ADC_COUNTER_FREQ_MASK 0x06
/* FIXME: these values might be reversed... */
#define GAME_HWCFG_ADC_COUNTER_FREQ_STD 0
#define GAME_HWCFG_ADC_COUNTER_FREQ_1_2 1
#define GAME_HWCFG_ADC_COUNTER_FREQ_1_20 2
#define GAME_HWCFG_ADC_COUNTER_FREQ_1_200 3
/* enable gameport legacy I/O address (0x200) /* enable gameport legacy I/O address (0x200)
* I was unable to locate any configurability for a different address: */ * I was unable to locate any configurability for a different address: */
#define GAME_HWCFG_LEGACY_ADDRESS_ENABLE 0x08 #define GAME_HWCFG_LEGACY_ADDRESS_ENABLE 0x08
...@@ -281,6 +276,7 @@ enum { ...@@ -281,6 +276,7 @@ enum {
#define AZF_IO_SIZE_MPU_PM 0x04 #define AZF_IO_SIZE_MPU_PM 0x04
/*** OPL3 synth ***/ /*** OPL3 synth ***/
/* (only 0x06 of 0x08 bytes saved/restored by Windows driver) */
#define AZF_IO_SIZE_OPL3 0x08 #define AZF_IO_SIZE_OPL3 0x08
#define AZF_IO_SIZE_OPL3_PM 0x06 #define AZF_IO_SIZE_OPL3_PM 0x06
/* hmm, given that a standard OPL3 has 4 registers only, /* hmm, given that a standard OPL3 has 4 registers only,
...@@ -340,4 +336,7 @@ enum { ...@@ -340,4 +336,7 @@ enum {
#define SET_CHAN_LEFT 1 #define SET_CHAN_LEFT 1
#define SET_CHAN_RIGHT 2 #define SET_CHAN_RIGHT 2
/* helper macro to align I/O port ranges to 32bit I/O width */
#define AZF_ALIGN(x) (((x) + 3) & (~3))
#endif /* __SOUND_AZT3328_H */ #endif /* __SOUND_AZT3328_H */
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
#ifdef CONFIG_SND_CS46XX_NEW_DSP #ifdef CONFIG_SND_CS46XX_NEW_DSP
#define CS46XX_MIN_PERIOD_SIZE 1 #define CS46XX_MIN_PERIOD_SIZE 64
#define CS46XX_MAX_PERIOD_SIZE 1024*1024 #define CS46XX_MAX_PERIOD_SIZE 1024*1024
#else #else
#define CS46XX_MIN_PERIOD_SIZE 2048 #define CS46XX_MIN_PERIOD_SIZE 2048
......
...@@ -11,9 +11,12 @@ ...@@ -11,9 +11,12 @@
/* Timer Registers */ /* Timer Registers */
#define TIMER_TIMR 0x1B7004 #define WC 0x1b7000
#define INTERRUPT_GIP 0x1B7010 #define TIMR 0x1b7004
#define INTERRUPT_GIE 0x1B7014 # define TIMR_IE (1<<15)
# define TIMR_IP (1<<14)
#define GIP 0x1b7010
#define GIE 0x1b7014
/* I2C Registers */ /* I2C Registers */
#define I2C_IF_ADDRESS 0x1B9000 #define I2C_IF_ADDRESS 0x1B9000
......
...@@ -63,7 +63,7 @@ static int amixer_set_input(struct amixer *amixer, struct rsc *rsc) ...@@ -63,7 +63,7 @@ static int amixer_set_input(struct amixer *amixer, struct rsc *rsc)
hw = amixer->rsc.hw; hw = amixer->rsc.hw;
hw->amixer_set_mode(amixer->rsc.ctrl_blk, AMIXER_Y_IMMEDIATE); hw->amixer_set_mode(amixer->rsc.ctrl_blk, AMIXER_Y_IMMEDIATE);
amixer->input = rsc; amixer->input = rsc;
if (NULL == rsc) if (!rsc)
hw->amixer_set_x(amixer->rsc.ctrl_blk, BLANK_SLOT); hw->amixer_set_x(amixer->rsc.ctrl_blk, BLANK_SLOT);
else else
hw->amixer_set_x(amixer->rsc.ctrl_blk, hw->amixer_set_x(amixer->rsc.ctrl_blk,
...@@ -99,7 +99,7 @@ static int amixer_set_sum(struct amixer *amixer, struct sum *sum) ...@@ -99,7 +99,7 @@ static int amixer_set_sum(struct amixer *amixer, struct sum *sum)
hw = amixer->rsc.hw; hw = amixer->rsc.hw;
amixer->sum = sum; amixer->sum = sum;
if (NULL == sum) { if (!sum) {
hw->amixer_set_se(amixer->rsc.ctrl_blk, 0); hw->amixer_set_se(amixer->rsc.ctrl_blk, 0);
} else { } else {
hw->amixer_set_se(amixer->rsc.ctrl_blk, 1); hw->amixer_set_se(amixer->rsc.ctrl_blk, 1);
...@@ -124,20 +124,20 @@ static int amixer_commit_write(struct amixer *amixer) ...@@ -124,20 +124,20 @@ static int amixer_commit_write(struct amixer *amixer)
/* Program master and conjugate resources */ /* Program master and conjugate resources */
amixer->rsc.ops->master(&amixer->rsc); amixer->rsc.ops->master(&amixer->rsc);
if (NULL != input) if (input)
input->ops->master(input); input->ops->master(input);
if (NULL != sum) if (sum)
sum->rsc.ops->master(&sum->rsc); sum->rsc.ops->master(&sum->rsc);
for (i = 0; i < amixer->rsc.msr; i++) { for (i = 0; i < amixer->rsc.msr; i++) {
hw->amixer_set_dirty_all(amixer->rsc.ctrl_blk); hw->amixer_set_dirty_all(amixer->rsc.ctrl_blk);
if (NULL != input) { if (input) {
hw->amixer_set_x(amixer->rsc.ctrl_blk, hw->amixer_set_x(amixer->rsc.ctrl_blk,
input->ops->output_slot(input)); input->ops->output_slot(input));
input->ops->next_conj(input); input->ops->next_conj(input);
} }
if (NULL != sum) { if (sum) {
hw->amixer_set_sadr(amixer->rsc.ctrl_blk, hw->amixer_set_sadr(amixer->rsc.ctrl_blk,
sum->rsc.ops->index(&sum->rsc)); sum->rsc.ops->index(&sum->rsc));
sum->rsc.ops->next_conj(&sum->rsc); sum->rsc.ops->next_conj(&sum->rsc);
...@@ -147,10 +147,10 @@ static int amixer_commit_write(struct amixer *amixer) ...@@ -147,10 +147,10 @@ static int amixer_commit_write(struct amixer *amixer)
amixer->rsc.ops->next_conj(&amixer->rsc); amixer->rsc.ops->next_conj(&amixer->rsc);
} }
amixer->rsc.ops->master(&amixer->rsc); amixer->rsc.ops->master(&amixer->rsc);
if (NULL != input) if (input)
input->ops->master(input); input->ops->master(input);
if (NULL != sum) if (sum)
sum->rsc.ops->master(&sum->rsc); sum->rsc.ops->master(&sum->rsc);
return 0; return 0;
...@@ -303,7 +303,7 @@ int amixer_mgr_create(void *hw, struct amixer_mgr **ramixer_mgr) ...@@ -303,7 +303,7 @@ int amixer_mgr_create(void *hw, struct amixer_mgr **ramixer_mgr)
*ramixer_mgr = NULL; *ramixer_mgr = NULL;
amixer_mgr = kzalloc(sizeof(*amixer_mgr), GFP_KERNEL); amixer_mgr = kzalloc(sizeof(*amixer_mgr), GFP_KERNEL);
if (NULL == amixer_mgr) if (!amixer_mgr)
return -ENOMEM; return -ENOMEM;
err = rsc_mgr_init(&amixer_mgr->mgr, AMIXER, AMIXER_RESOURCE_NUM, hw); err = rsc_mgr_init(&amixer_mgr->mgr, AMIXER, AMIXER_RESOURCE_NUM, hw);
...@@ -456,7 +456,7 @@ int sum_mgr_create(void *hw, struct sum_mgr **rsum_mgr) ...@@ -456,7 +456,7 @@ int sum_mgr_create(void *hw, struct sum_mgr **rsum_mgr)
*rsum_mgr = NULL; *rsum_mgr = NULL;
sum_mgr = kzalloc(sizeof(*sum_mgr), GFP_KERNEL); sum_mgr = kzalloc(sizeof(*sum_mgr), GFP_KERNEL);
if (NULL == sum_mgr) if (!sum_mgr)
return -ENOMEM; return -ENOMEM;
err = rsc_mgr_init(&sum_mgr->mgr, SUM, SUM_RESOURCE_NUM, hw); err = rsc_mgr_init(&sum_mgr->mgr, SUM, SUM_RESOURCE_NUM, hw);
......
...@@ -136,7 +136,7 @@ static int ct_map_audio_buffer(struct ct_atc *atc, struct ct_atc_pcm *apcm) ...@@ -136,7 +136,7 @@ static int ct_map_audio_buffer(struct ct_atc *atc, struct ct_atc_pcm *apcm)
struct snd_pcm_runtime *runtime; struct snd_pcm_runtime *runtime;
struct ct_vm *vm; struct ct_vm *vm;
if (NULL == apcm->substream) if (!apcm->substream)
return 0; return 0;
runtime = apcm->substream->runtime; runtime = apcm->substream->runtime;
...@@ -144,7 +144,7 @@ static int ct_map_audio_buffer(struct ct_atc *atc, struct ct_atc_pcm *apcm) ...@@ -144,7 +144,7 @@ static int ct_map_audio_buffer(struct ct_atc *atc, struct ct_atc_pcm *apcm)
apcm->vm_block = vm->map(vm, apcm->substream, runtime->dma_bytes); apcm->vm_block = vm->map(vm, apcm->substream, runtime->dma_bytes);
if (NULL == apcm->vm_block) if (!apcm->vm_block)
return -ENOENT; return -ENOENT;
return 0; return 0;
...@@ -154,7 +154,7 @@ static void ct_unmap_audio_buffer(struct ct_atc *atc, struct ct_atc_pcm *apcm) ...@@ -154,7 +154,7 @@ static void ct_unmap_audio_buffer(struct ct_atc *atc, struct ct_atc_pcm *apcm)
{ {
struct ct_vm *vm; struct ct_vm *vm;
if (NULL == apcm->vm_block) if (!apcm->vm_block)
return; return;
vm = atc->vm; vm = atc->vm;
...@@ -231,16 +231,16 @@ atc_get_pitch(unsigned int input_rate, unsigned int output_rate) ...@@ -231,16 +231,16 @@ atc_get_pitch(unsigned int input_rate, unsigned int output_rate)
static int select_rom(unsigned int pitch) static int select_rom(unsigned int pitch)
{ {
if ((pitch > 0x00428f5c) && (pitch < 0x01b851ec)) { if (pitch > 0x00428f5c && pitch < 0x01b851ec) {
/* 0.26 <= pitch <= 1.72 */ /* 0.26 <= pitch <= 1.72 */
return 1; return 1;
} else if ((0x01d66666 == pitch) || (0x01d66667 == pitch)) { } else if (pitch == 0x01d66666 || pitch == 0x01d66667) {
/* pitch == 1.8375 */ /* pitch == 1.8375 */
return 2; return 2;
} else if (0x02000000 == pitch) { } else if (pitch == 0x02000000) {
/* pitch == 2 */ /* pitch == 2 */
return 3; return 3;
} else if ((pitch >= 0x0) && (pitch <= 0x08000000)) { } else if (pitch >= 0x0 && pitch <= 0x08000000) {
/* 0 <= pitch <= 8 */ /* 0 <= pitch <= 8 */
return 0; return 0;
} else { } else {
...@@ -283,7 +283,7 @@ static int atc_pcm_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm) ...@@ -283,7 +283,7 @@ static int atc_pcm_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm)
/* Get AMIXER resource */ /* Get AMIXER resource */
n_amixer = (n_amixer < 2) ? 2 : n_amixer; n_amixer = (n_amixer < 2) ? 2 : n_amixer;
apcm->amixers = kzalloc(sizeof(void *)*n_amixer, GFP_KERNEL); apcm->amixers = kzalloc(sizeof(void *)*n_amixer, GFP_KERNEL);
if (NULL == apcm->amixers) { if (!apcm->amixers) {
err = -ENOMEM; err = -ENOMEM;
goto error1; goto error1;
} }
...@@ -311,7 +311,7 @@ static int atc_pcm_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm) ...@@ -311,7 +311,7 @@ static int atc_pcm_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm)
INIT_VOL, atc->pcm[i+device*2]); INIT_VOL, atc->pcm[i+device*2]);
mutex_unlock(&atc->atc_mutex); mutex_unlock(&atc->atc_mutex);
src = src->ops->next_interleave(src); src = src->ops->next_interleave(src);
if (NULL == src) if (!src)
src = apcm->src; src = apcm->src;
} }
...@@ -334,7 +334,7 @@ atc_pcm_release_resources(struct ct_atc *atc, struct ct_atc_pcm *apcm) ...@@ -334,7 +334,7 @@ atc_pcm_release_resources(struct ct_atc *atc, struct ct_atc_pcm *apcm)
struct srcimp *srcimp; struct srcimp *srcimp;
int i; int i;
if (NULL != apcm->srcimps) { if (apcm->srcimps) {
for (i = 0; i < apcm->n_srcimp; i++) { for (i = 0; i < apcm->n_srcimp; i++) {
srcimp = apcm->srcimps[i]; srcimp = apcm->srcimps[i];
srcimp->ops->unmap(srcimp); srcimp->ops->unmap(srcimp);
...@@ -345,7 +345,7 @@ atc_pcm_release_resources(struct ct_atc *atc, struct ct_atc_pcm *apcm) ...@@ -345,7 +345,7 @@ atc_pcm_release_resources(struct ct_atc *atc, struct ct_atc_pcm *apcm)
apcm->srcimps = NULL; apcm->srcimps = NULL;
} }
if (NULL != apcm->srccs) { if (apcm->srccs) {
for (i = 0; i < apcm->n_srcc; i++) { for (i = 0; i < apcm->n_srcc; i++) {
src_mgr->put_src(src_mgr, apcm->srccs[i]); src_mgr->put_src(src_mgr, apcm->srccs[i]);
apcm->srccs[i] = NULL; apcm->srccs[i] = NULL;
...@@ -354,7 +354,7 @@ atc_pcm_release_resources(struct ct_atc *atc, struct ct_atc_pcm *apcm) ...@@ -354,7 +354,7 @@ atc_pcm_release_resources(struct ct_atc *atc, struct ct_atc_pcm *apcm)
apcm->srccs = NULL; apcm->srccs = NULL;
} }
if (NULL != apcm->amixers) { if (apcm->amixers) {
for (i = 0; i < apcm->n_amixer; i++) { for (i = 0; i < apcm->n_amixer; i++) {
amixer_mgr->put_amixer(amixer_mgr, apcm->amixers[i]); amixer_mgr->put_amixer(amixer_mgr, apcm->amixers[i]);
apcm->amixers[i] = NULL; apcm->amixers[i] = NULL;
...@@ -363,17 +363,17 @@ atc_pcm_release_resources(struct ct_atc *atc, struct ct_atc_pcm *apcm) ...@@ -363,17 +363,17 @@ atc_pcm_release_resources(struct ct_atc *atc, struct ct_atc_pcm *apcm)
apcm->amixers = NULL; apcm->amixers = NULL;
} }
if (NULL != apcm->mono) { if (apcm->mono) {
sum_mgr->put_sum(sum_mgr, apcm->mono); sum_mgr->put_sum(sum_mgr, apcm->mono);
apcm->mono = NULL; apcm->mono = NULL;
} }
if (NULL != apcm->src) { if (apcm->src) {
src_mgr->put_src(src_mgr, apcm->src); src_mgr->put_src(src_mgr, apcm->src);
apcm->src = NULL; apcm->src = NULL;
} }
if (NULL != apcm->vm_block) { if (apcm->vm_block) {
/* Undo device virtual mem map */ /* Undo device virtual mem map */
ct_unmap_audio_buffer(atc, apcm); ct_unmap_audio_buffer(atc, apcm);
apcm->vm_block = NULL; apcm->vm_block = NULL;
...@@ -419,7 +419,7 @@ static int atc_pcm_stop(struct ct_atc *atc, struct ct_atc_pcm *apcm) ...@@ -419,7 +419,7 @@ static int atc_pcm_stop(struct ct_atc *atc, struct ct_atc_pcm *apcm)
src->ops->set_state(src, SRC_STATE_OFF); src->ops->set_state(src, SRC_STATE_OFF);
src->ops->commit_write(src); src->ops->commit_write(src);
if (NULL != apcm->srccs) { if (apcm->srccs) {
for (i = 0; i < apcm->n_srcc; i++) { for (i = 0; i < apcm->n_srcc; i++) {
src = apcm->srccs[i]; src = apcm->srccs[i];
src->ops->set_bm(src, 0); src->ops->set_bm(src, 0);
...@@ -544,18 +544,18 @@ atc_pcm_capture_get_resources(struct ct_atc *atc, struct ct_atc_pcm *apcm) ...@@ -544,18 +544,18 @@ atc_pcm_capture_get_resources(struct ct_atc *atc, struct ct_atc_pcm *apcm)
if (n_srcc) { if (n_srcc) {
apcm->srccs = kzalloc(sizeof(void *)*n_srcc, GFP_KERNEL); apcm->srccs = kzalloc(sizeof(void *)*n_srcc, GFP_KERNEL);
if (NULL == apcm->srccs) if (!apcm->srccs)
return -ENOMEM; return -ENOMEM;
} }
if (n_amixer) { if (n_amixer) {
apcm->amixers = kzalloc(sizeof(void *)*n_amixer, GFP_KERNEL); apcm->amixers = kzalloc(sizeof(void *)*n_amixer, GFP_KERNEL);
if (NULL == apcm->amixers) { if (!apcm->amixers) {
err = -ENOMEM; err = -ENOMEM;
goto error1; goto error1;
} }
} }
apcm->srcimps = kzalloc(sizeof(void *)*n_srcimp, GFP_KERNEL); apcm->srcimps = kzalloc(sizeof(void *)*n_srcimp, GFP_KERNEL);
if (NULL == apcm->srcimps) { if (!apcm->srcimps) {
err = -ENOMEM; err = -ENOMEM;
goto error1; goto error1;
} }
...@@ -818,7 +818,7 @@ static int spdif_passthru_playback_get_resources(struct ct_atc *atc, ...@@ -818,7 +818,7 @@ static int spdif_passthru_playback_get_resources(struct ct_atc *atc,
/* Get AMIXER resource */ /* Get AMIXER resource */
n_amixer = (n_amixer < 2) ? 2 : n_amixer; n_amixer = (n_amixer < 2) ? 2 : n_amixer;
apcm->amixers = kzalloc(sizeof(void *)*n_amixer, GFP_KERNEL); apcm->amixers = kzalloc(sizeof(void *)*n_amixer, GFP_KERNEL);
if (NULL == apcm->amixers) { if (!apcm->amixers) {
err = -ENOMEM; err = -ENOMEM;
goto error1; goto error1;
} }
...@@ -919,7 +919,7 @@ spdif_passthru_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm) ...@@ -919,7 +919,7 @@ spdif_passthru_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm)
amixer = apcm->amixers[i]; amixer = apcm->amixers[i];
amixer->ops->setup(amixer, &src->rsc, INIT_VOL, NULL); amixer->ops->setup(amixer, &src->rsc, INIT_VOL, NULL);
src = src->ops->next_interleave(src); src = src->ops->next_interleave(src);
if (NULL == src) if (!src)
src = apcm->src; src = apcm->src;
} }
/* Connect to SPDIFOO */ /* Connect to SPDIFOO */
...@@ -1121,7 +1121,7 @@ static int atc_release_resources(struct ct_atc *atc) ...@@ -1121,7 +1121,7 @@ static int atc_release_resources(struct ct_atc *atc)
struct ct_mixer *mixer = NULL; struct ct_mixer *mixer = NULL;
/* disconnect internal mixer objects */ /* disconnect internal mixer objects */
if (NULL != atc->mixer) { if (atc->mixer) {
mixer = atc->mixer; mixer = atc->mixer;
mixer->set_input_left(mixer, MIX_LINE_IN, NULL); mixer->set_input_left(mixer, MIX_LINE_IN, NULL);
mixer->set_input_right(mixer, MIX_LINE_IN, NULL); mixer->set_input_right(mixer, MIX_LINE_IN, NULL);
...@@ -1131,7 +1131,7 @@ static int atc_release_resources(struct ct_atc *atc) ...@@ -1131,7 +1131,7 @@ static int atc_release_resources(struct ct_atc *atc)
mixer->set_input_right(mixer, MIX_SPDIF_IN, NULL); mixer->set_input_right(mixer, MIX_SPDIF_IN, NULL);
} }
if (NULL != atc->daios) { if (atc->daios) {
daio_mgr = (struct daio_mgr *)atc->rsc_mgrs[DAIO]; daio_mgr = (struct daio_mgr *)atc->rsc_mgrs[DAIO];
for (i = 0; i < atc->n_daio; i++) { for (i = 0; i < atc->n_daio; i++) {
daio = atc->daios[i]; daio = atc->daios[i];
...@@ -1149,7 +1149,7 @@ static int atc_release_resources(struct ct_atc *atc) ...@@ -1149,7 +1149,7 @@ static int atc_release_resources(struct ct_atc *atc)
atc->daios = NULL; atc->daios = NULL;
} }
if (NULL != atc->pcm) { if (atc->pcm) {
sum_mgr = atc->rsc_mgrs[SUM]; sum_mgr = atc->rsc_mgrs[SUM];
for (i = 0; i < atc->n_pcm; i++) for (i = 0; i < atc->n_pcm; i++)
sum_mgr->put_sum(sum_mgr, atc->pcm[i]); sum_mgr->put_sum(sum_mgr, atc->pcm[i]);
...@@ -1158,7 +1158,7 @@ static int atc_release_resources(struct ct_atc *atc) ...@@ -1158,7 +1158,7 @@ static int atc_release_resources(struct ct_atc *atc)
atc->pcm = NULL; atc->pcm = NULL;
} }
if (NULL != atc->srcs) { if (atc->srcs) {
src_mgr = atc->rsc_mgrs[SRC]; src_mgr = atc->rsc_mgrs[SRC];
for (i = 0; i < atc->n_src; i++) for (i = 0; i < atc->n_src; i++)
src_mgr->put_src(src_mgr, atc->srcs[i]); src_mgr->put_src(src_mgr, atc->srcs[i]);
...@@ -1167,7 +1167,7 @@ static int atc_release_resources(struct ct_atc *atc) ...@@ -1167,7 +1167,7 @@ static int atc_release_resources(struct ct_atc *atc)
atc->srcs = NULL; atc->srcs = NULL;
} }
if (NULL != atc->srcimps) { if (atc->srcimps) {
srcimp_mgr = atc->rsc_mgrs[SRCIMP]; srcimp_mgr = atc->rsc_mgrs[SRCIMP];
for (i = 0; i < atc->n_srcimp; i++) { for (i = 0; i < atc->n_srcimp; i++) {
srcimp = atc->srcimps[i]; srcimp = atc->srcimps[i];
...@@ -1185,7 +1185,7 @@ static int ct_atc_destroy(struct ct_atc *atc) ...@@ -1185,7 +1185,7 @@ static int ct_atc_destroy(struct ct_atc *atc)
{ {
int i = 0; int i = 0;
if (NULL == atc) if (!atc)
return 0; return 0;
if (atc->timer) { if (atc->timer) {
...@@ -1196,21 +1196,20 @@ static int ct_atc_destroy(struct ct_atc *atc) ...@@ -1196,21 +1196,20 @@ static int ct_atc_destroy(struct ct_atc *atc)
atc_release_resources(atc); atc_release_resources(atc);
/* Destroy internal mixer objects */ /* Destroy internal mixer objects */
if (NULL != atc->mixer) if (atc->mixer)
ct_mixer_destroy(atc->mixer); ct_mixer_destroy(atc->mixer);
for (i = 0; i < NUM_RSCTYP; i++) { for (i = 0; i < NUM_RSCTYP; i++) {
if ((NULL != rsc_mgr_funcs[i].destroy) && if (rsc_mgr_funcs[i].destroy && atc->rsc_mgrs[i])
(NULL != atc->rsc_mgrs[i]))
rsc_mgr_funcs[i].destroy(atc->rsc_mgrs[i]); rsc_mgr_funcs[i].destroy(atc->rsc_mgrs[i]);
} }
if (NULL != atc->hw) if (atc->hw)
destroy_hw_obj((struct hw *)atc->hw); destroy_hw_obj((struct hw *)atc->hw);
/* Destroy device virtual memory manager object */ /* Destroy device virtual memory manager object */
if (NULL != atc->vm) { if (atc->vm) {
ct_vm_destroy(atc->vm); ct_vm_destroy(atc->vm);
atc->vm = NULL; atc->vm = NULL;
} }
...@@ -1275,7 +1274,7 @@ int __devinit ct_atc_create_alsa_devs(struct ct_atc *atc) ...@@ -1275,7 +1274,7 @@ int __devinit ct_atc_create_alsa_devs(struct ct_atc *atc)
alsa_dev_funcs[MIXER].public_name = atc->chip_name; alsa_dev_funcs[MIXER].public_name = atc->chip_name;
for (i = 0; i < NUM_CTALSADEVS; i++) { for (i = 0; i < NUM_CTALSADEVS; i++) {
if (NULL == alsa_dev_funcs[i].create) if (!alsa_dev_funcs[i].create)
continue; continue;
err = alsa_dev_funcs[i].create(atc, i, err = alsa_dev_funcs[i].create(atc, i,
...@@ -1312,7 +1311,7 @@ static int __devinit atc_create_hw_devs(struct ct_atc *atc) ...@@ -1312,7 +1311,7 @@ static int __devinit atc_create_hw_devs(struct ct_atc *atc)
return err; return err;
for (i = 0; i < NUM_RSCTYP; i++) { for (i = 0; i < NUM_RSCTYP; i++) {
if (NULL == rsc_mgr_funcs[i].create) if (!rsc_mgr_funcs[i].create)
continue; continue;
err = rsc_mgr_funcs[i].create(atc->hw, &atc->rsc_mgrs[i]); err = rsc_mgr_funcs[i].create(atc->hw, &atc->rsc_mgrs[i]);
...@@ -1339,19 +1338,19 @@ static int atc_get_resources(struct ct_atc *atc) ...@@ -1339,19 +1338,19 @@ static int atc_get_resources(struct ct_atc *atc)
int err, i; int err, i;
atc->daios = kzalloc(sizeof(void *)*(DAIONUM), GFP_KERNEL); atc->daios = kzalloc(sizeof(void *)*(DAIONUM), GFP_KERNEL);
if (NULL == atc->daios) if (!atc->daios)
return -ENOMEM; return -ENOMEM;
atc->srcs = kzalloc(sizeof(void *)*(2*2), GFP_KERNEL); atc->srcs = kzalloc(sizeof(void *)*(2*2), GFP_KERNEL);
if (NULL == atc->srcs) if (!atc->srcs)
return -ENOMEM; return -ENOMEM;
atc->srcimps = kzalloc(sizeof(void *)*(2*2), GFP_KERNEL); atc->srcimps = kzalloc(sizeof(void *)*(2*2), GFP_KERNEL);
if (NULL == atc->srcimps) if (!atc->srcimps)
return -ENOMEM; return -ENOMEM;
atc->pcm = kzalloc(sizeof(void *)*(2*4), GFP_KERNEL); atc->pcm = kzalloc(sizeof(void *)*(2*4), GFP_KERNEL);
if (NULL == atc->pcm) if (!atc->pcm)
return -ENOMEM; return -ENOMEM;
daio_mgr = (struct daio_mgr *)atc->rsc_mgrs[DAIO]; daio_mgr = (struct daio_mgr *)atc->rsc_mgrs[DAIO];
...@@ -1648,7 +1647,7 @@ int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci, ...@@ -1648,7 +1647,7 @@ int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci,
*ratc = NULL; *ratc = NULL;
atc = kzalloc(sizeof(*atc), GFP_KERNEL); atc = kzalloc(sizeof(*atc), GFP_KERNEL);
if (NULL == atc) if (!atc)
return -ENOMEM; return -ENOMEM;
/* Set operations */ /* Set operations */
......
...@@ -173,7 +173,7 @@ static int dao_set_left_input(struct dao *dao, struct rsc *input) ...@@ -173,7 +173,7 @@ static int dao_set_left_input(struct dao *dao, struct rsc *input)
int i; int i;
entry = kzalloc((sizeof(*entry) * daio->rscl.msr), GFP_KERNEL); entry = kzalloc((sizeof(*entry) * daio->rscl.msr), GFP_KERNEL);
if (NULL == entry) if (!entry)
return -ENOMEM; return -ENOMEM;
/* Program master and conjugate resources */ /* Program master and conjugate resources */
...@@ -201,7 +201,7 @@ static int dao_set_right_input(struct dao *dao, struct rsc *input) ...@@ -201,7 +201,7 @@ static int dao_set_right_input(struct dao *dao, struct rsc *input)
int i; int i;
entry = kzalloc((sizeof(*entry) * daio->rscr.msr), GFP_KERNEL); entry = kzalloc((sizeof(*entry) * daio->rscr.msr), GFP_KERNEL);
if (NULL == entry) if (!entry)
return -ENOMEM; return -ENOMEM;
/* Program master and conjugate resources */ /* Program master and conjugate resources */
...@@ -228,7 +228,7 @@ static int dao_clear_left_input(struct dao *dao) ...@@ -228,7 +228,7 @@ static int dao_clear_left_input(struct dao *dao)
struct daio *daio = &dao->daio; struct daio *daio = &dao->daio;
int i; int i;
if (NULL == dao->imappers[0]) if (!dao->imappers[0])
return 0; return 0;
entry = dao->imappers[0]; entry = dao->imappers[0];
...@@ -252,7 +252,7 @@ static int dao_clear_right_input(struct dao *dao) ...@@ -252,7 +252,7 @@ static int dao_clear_right_input(struct dao *dao)
struct daio *daio = &dao->daio; struct daio *daio = &dao->daio;
int i; int i;
if (NULL == dao->imappers[daio->rscl.msr]) if (!dao->imappers[daio->rscl.msr])
return 0; return 0;
entry = dao->imappers[daio->rscl.msr]; entry = dao->imappers[daio->rscl.msr];
...@@ -408,7 +408,7 @@ static int dao_rsc_init(struct dao *dao, ...@@ -408,7 +408,7 @@ static int dao_rsc_init(struct dao *dao,
return err; return err;
dao->imappers = kzalloc(sizeof(void *)*desc->msr*2, GFP_KERNEL); dao->imappers = kzalloc(sizeof(void *)*desc->msr*2, GFP_KERNEL);
if (NULL == dao->imappers) { if (!dao->imappers) {
err = -ENOMEM; err = -ENOMEM;
goto error1; goto error1;
} }
...@@ -442,11 +442,11 @@ static int dao_rsc_init(struct dao *dao, ...@@ -442,11 +442,11 @@ static int dao_rsc_init(struct dao *dao,
static int dao_rsc_uninit(struct dao *dao) static int dao_rsc_uninit(struct dao *dao)
{ {
if (NULL != dao->imappers) { if (dao->imappers) {
if (NULL != dao->imappers[0]) if (dao->imappers[0])
dao_clear_left_input(dao); dao_clear_left_input(dao);
if (NULL != dao->imappers[dao->daio.rscl.msr]) if (dao->imappers[dao->daio.rscl.msr])
dao_clear_right_input(dao); dao_clear_right_input(dao);
kfree(dao->imappers); kfree(dao->imappers);
...@@ -555,7 +555,7 @@ static int get_daio_rsc(struct daio_mgr *mgr, ...@@ -555,7 +555,7 @@ static int get_daio_rsc(struct daio_mgr *mgr,
/* Allocate mem for daio resource */ /* Allocate mem for daio resource */
if (desc->type <= DAIO_OUT_MAX) { if (desc->type <= DAIO_OUT_MAX) {
dao = kzalloc(sizeof(*dao), GFP_KERNEL); dao = kzalloc(sizeof(*dao), GFP_KERNEL);
if (NULL == dao) { if (!dao) {
err = -ENOMEM; err = -ENOMEM;
goto error; goto error;
} }
...@@ -566,7 +566,7 @@ static int get_daio_rsc(struct daio_mgr *mgr, ...@@ -566,7 +566,7 @@ static int get_daio_rsc(struct daio_mgr *mgr,
*rdaio = &dao->daio; *rdaio = &dao->daio;
} else { } else {
dai = kzalloc(sizeof(*dai), GFP_KERNEL); dai = kzalloc(sizeof(*dai), GFP_KERNEL);
if (NULL == dai) { if (!dai) {
err = -ENOMEM; err = -ENOMEM;
goto error; goto error;
} }
...@@ -583,9 +583,9 @@ static int get_daio_rsc(struct daio_mgr *mgr, ...@@ -583,9 +583,9 @@ static int get_daio_rsc(struct daio_mgr *mgr,
return 0; return 0;
error: error:
if (NULL != dao) if (dao)
kfree(dao); kfree(dao);
else if (NULL != dai) else if (dai)
kfree(dai); kfree(dai);
spin_lock_irqsave(&mgr->mgr_lock, flags); spin_lock_irqsave(&mgr->mgr_lock, flags);
...@@ -663,7 +663,7 @@ static int daio_imap_add(struct daio_mgr *mgr, struct imapper *entry) ...@@ -663,7 +663,7 @@ static int daio_imap_add(struct daio_mgr *mgr, struct imapper *entry)
int err; int err;
spin_lock_irqsave(&mgr->imap_lock, flags); spin_lock_irqsave(&mgr->imap_lock, flags);
if ((0 == entry->addr) && (mgr->init_imap_added)) { if (!entry->addr && mgr->init_imap_added) {
input_mapper_delete(&mgr->imappers, mgr->init_imap, input_mapper_delete(&mgr->imappers, mgr->init_imap,
daio_map_op, mgr); daio_map_op, mgr);
mgr->init_imap_added = 0; mgr->init_imap_added = 0;
...@@ -707,7 +707,7 @@ int daio_mgr_create(void *hw, struct daio_mgr **rdaio_mgr) ...@@ -707,7 +707,7 @@ int daio_mgr_create(void *hw, struct daio_mgr **rdaio_mgr)
*rdaio_mgr = NULL; *rdaio_mgr = NULL;
daio_mgr = kzalloc(sizeof(*daio_mgr), GFP_KERNEL); daio_mgr = kzalloc(sizeof(*daio_mgr), GFP_KERNEL);
if (NULL == daio_mgr) if (!daio_mgr)
return -ENOMEM; return -ENOMEM;
err = rsc_mgr_init(&daio_mgr->mgr, DAIO, DAIO_RESOURCE_NUM, hw); err = rsc_mgr_init(&daio_mgr->mgr, DAIO, DAIO_RESOURCE_NUM, hw);
...@@ -718,7 +718,7 @@ int daio_mgr_create(void *hw, struct daio_mgr **rdaio_mgr) ...@@ -718,7 +718,7 @@ int daio_mgr_create(void *hw, struct daio_mgr **rdaio_mgr)
spin_lock_init(&daio_mgr->imap_lock); spin_lock_init(&daio_mgr->imap_lock);
INIT_LIST_HEAD(&daio_mgr->imappers); INIT_LIST_HEAD(&daio_mgr->imappers);
entry = kzalloc(sizeof(*entry), GFP_KERNEL); entry = kzalloc(sizeof(*entry), GFP_KERNEL);
if (NULL == entry) { if (!entry) {
err = -ENOMEM; err = -ENOMEM;
goto error2; goto error2;
} }
......
...@@ -168,7 +168,7 @@ static int src_get_rsc_ctrl_blk(void **rblk) ...@@ -168,7 +168,7 @@ static int src_get_rsc_ctrl_blk(void **rblk)
*rblk = NULL; *rblk = NULL;
blk = kzalloc(sizeof(*blk), GFP_KERNEL); blk = kzalloc(sizeof(*blk), GFP_KERNEL);
if (NULL == blk) if (!blk)
return -ENOMEM; return -ENOMEM;
*rblk = blk; *rblk = blk;
...@@ -494,7 +494,7 @@ static int src_mgr_get_ctrl_blk(void **rblk) ...@@ -494,7 +494,7 @@ static int src_mgr_get_ctrl_blk(void **rblk)
*rblk = NULL; *rblk = NULL;
blk = kzalloc(sizeof(*blk), GFP_KERNEL); blk = kzalloc(sizeof(*blk), GFP_KERNEL);
if (NULL == blk) if (!blk)
return -ENOMEM; return -ENOMEM;
*rblk = blk; *rblk = blk;
...@@ -515,7 +515,7 @@ static int srcimp_mgr_get_ctrl_blk(void **rblk) ...@@ -515,7 +515,7 @@ static int srcimp_mgr_get_ctrl_blk(void **rblk)
*rblk = NULL; *rblk = NULL;
blk = kzalloc(sizeof(*blk), GFP_KERNEL); blk = kzalloc(sizeof(*blk), GFP_KERNEL);
if (NULL == blk) if (!blk)
return -ENOMEM; return -ENOMEM;
*rblk = blk; *rblk = blk;
...@@ -702,7 +702,7 @@ static int amixer_rsc_get_ctrl_blk(void **rblk) ...@@ -702,7 +702,7 @@ static int amixer_rsc_get_ctrl_blk(void **rblk)
*rblk = NULL; *rblk = NULL;
blk = kzalloc(sizeof(*blk), GFP_KERNEL); blk = kzalloc(sizeof(*blk), GFP_KERNEL);
if (NULL == blk) if (!blk)
return -ENOMEM; return -ENOMEM;
*rblk = blk; *rblk = blk;
...@@ -723,7 +723,7 @@ static int amixer_mgr_get_ctrl_blk(void **rblk) ...@@ -723,7 +723,7 @@ static int amixer_mgr_get_ctrl_blk(void **rblk)
*rblk = NULL; *rblk = NULL;
/*blk = kzalloc(sizeof(*blk), GFP_KERNEL); /*blk = kzalloc(sizeof(*blk), GFP_KERNEL);
if (NULL == blk) if (!blk)
return -ENOMEM; return -ENOMEM;
*rblk = blk;*/ *rblk = blk;*/
...@@ -909,7 +909,7 @@ static int dai_get_ctrl_blk(void **rblk) ...@@ -909,7 +909,7 @@ static int dai_get_ctrl_blk(void **rblk)
*rblk = NULL; *rblk = NULL;
blk = kzalloc(sizeof(*blk), GFP_KERNEL); blk = kzalloc(sizeof(*blk), GFP_KERNEL);
if (NULL == blk) if (!blk)
return -ENOMEM; return -ENOMEM;
*rblk = blk; *rblk = blk;
...@@ -958,7 +958,7 @@ static int dao_get_ctrl_blk(void **rblk) ...@@ -958,7 +958,7 @@ static int dao_get_ctrl_blk(void **rblk)
*rblk = NULL; *rblk = NULL;
blk = kzalloc(sizeof(*blk), GFP_KERNEL); blk = kzalloc(sizeof(*blk), GFP_KERNEL);
if (NULL == blk) if (!blk)
return -ENOMEM; return -ENOMEM;
*rblk = blk; *rblk = blk;
...@@ -1152,7 +1152,7 @@ static int daio_mgr_get_ctrl_blk(struct hw *hw, void **rblk) ...@@ -1152,7 +1152,7 @@ static int daio_mgr_get_ctrl_blk(struct hw *hw, void **rblk)
*rblk = NULL; *rblk = NULL;
blk = kzalloc(sizeof(*blk), GFP_KERNEL); blk = kzalloc(sizeof(*blk), GFP_KERNEL);
if (NULL == blk) if (!blk)
return -ENOMEM; return -ENOMEM;
blk->i2sctl = hw_read_20kx(hw, I2SCTL); blk->i2sctl = hw_read_20kx(hw, I2SCTL);
...@@ -1808,7 +1808,7 @@ static int uaa_to_xfi(struct pci_dev *pci) ...@@ -1808,7 +1808,7 @@ static int uaa_to_xfi(struct pci_dev *pci)
/* By default, Hendrix card UAA Bar0 should be using memory... */ /* By default, Hendrix card UAA Bar0 should be using memory... */
io_base = pci_resource_start(pci, 0); io_base = pci_resource_start(pci, 0);
mem_base = ioremap(io_base, pci_resource_len(pci, 0)); mem_base = ioremap(io_base, pci_resource_len(pci, 0));
if (NULL == mem_base) if (!mem_base)
return -ENOENT; return -ENOENT;
/* Read current mode from Mode Change Register */ /* Read current mode from Mode Change Register */
...@@ -1977,7 +1977,7 @@ static int hw_card_shutdown(struct hw *hw) ...@@ -1977,7 +1977,7 @@ static int hw_card_shutdown(struct hw *hw)
hw->irq = -1; hw->irq = -1;
if (NULL != ((void *)hw->mem_base)) if (hw->mem_base)
iounmap((void *)hw->mem_base); iounmap((void *)hw->mem_base);
hw->mem_base = (unsigned long)NULL; hw->mem_base = (unsigned long)NULL;
...@@ -2274,7 +2274,7 @@ int __devinit create_20k1_hw_obj(struct hw **rhw) ...@@ -2274,7 +2274,7 @@ int __devinit create_20k1_hw_obj(struct hw **rhw)
*rhw = NULL; *rhw = NULL;
hw20k1 = kzalloc(sizeof(*hw20k1), GFP_KERNEL); hw20k1 = kzalloc(sizeof(*hw20k1), GFP_KERNEL);
if (NULL == hw20k1) if (!hw20k1)
return -ENOMEM; return -ENOMEM;
spin_lock_init(&hw20k1->reg_20k1_lock); spin_lock_init(&hw20k1->reg_20k1_lock);
......
...@@ -166,7 +166,7 @@ static int src_get_rsc_ctrl_blk(void **rblk) ...@@ -166,7 +166,7 @@ static int src_get_rsc_ctrl_blk(void **rblk)
*rblk = NULL; *rblk = NULL;
blk = kzalloc(sizeof(*blk), GFP_KERNEL); blk = kzalloc(sizeof(*blk), GFP_KERNEL);
if (NULL == blk) if (!blk)
return -ENOMEM; return -ENOMEM;
*rblk = blk; *rblk = blk;
...@@ -492,7 +492,7 @@ static int src_mgr_get_ctrl_blk(void **rblk) ...@@ -492,7 +492,7 @@ static int src_mgr_get_ctrl_blk(void **rblk)
*rblk = NULL; *rblk = NULL;
blk = kzalloc(sizeof(*blk), GFP_KERNEL); blk = kzalloc(sizeof(*blk), GFP_KERNEL);
if (NULL == blk) if (!blk)
return -ENOMEM; return -ENOMEM;
*rblk = blk; *rblk = blk;
...@@ -513,7 +513,7 @@ static int srcimp_mgr_get_ctrl_blk(void **rblk) ...@@ -513,7 +513,7 @@ static int srcimp_mgr_get_ctrl_blk(void **rblk)
*rblk = NULL; *rblk = NULL;
blk = kzalloc(sizeof(*blk), GFP_KERNEL); blk = kzalloc(sizeof(*blk), GFP_KERNEL);
if (NULL == blk) if (!blk)
return -ENOMEM; return -ENOMEM;
*rblk = blk; *rblk = blk;
...@@ -702,7 +702,7 @@ static int amixer_rsc_get_ctrl_blk(void **rblk) ...@@ -702,7 +702,7 @@ static int amixer_rsc_get_ctrl_blk(void **rblk)
*rblk = NULL; *rblk = NULL;
blk = kzalloc(sizeof(*blk), GFP_KERNEL); blk = kzalloc(sizeof(*blk), GFP_KERNEL);
if (NULL == blk) if (!blk)
return -ENOMEM; return -ENOMEM;
*rblk = blk; *rblk = blk;
...@@ -891,7 +891,7 @@ static int dai_get_ctrl_blk(void **rblk) ...@@ -891,7 +891,7 @@ static int dai_get_ctrl_blk(void **rblk)
*rblk = NULL; *rblk = NULL;
blk = kzalloc(sizeof(*blk), GFP_KERNEL); blk = kzalloc(sizeof(*blk), GFP_KERNEL);
if (NULL == blk) if (!blk)
return -ENOMEM; return -ENOMEM;
*rblk = blk; *rblk = blk;
...@@ -941,7 +941,7 @@ static int dao_get_ctrl_blk(void **rblk) ...@@ -941,7 +941,7 @@ static int dao_get_ctrl_blk(void **rblk)
*rblk = NULL; *rblk = NULL;
blk = kzalloc(sizeof(*blk), GFP_KERNEL); blk = kzalloc(sizeof(*blk), GFP_KERNEL);
if (NULL == blk) if (!blk)
return -ENOMEM; return -ENOMEM;
*rblk = blk; *rblk = blk;
...@@ -1092,7 +1092,7 @@ static int daio_mgr_get_ctrl_blk(struct hw *hw, void **rblk) ...@@ -1092,7 +1092,7 @@ static int daio_mgr_get_ctrl_blk(struct hw *hw, void **rblk)
*rblk = NULL; *rblk = NULL;
blk = kzalloc(sizeof(*blk), GFP_KERNEL); blk = kzalloc(sizeof(*blk), GFP_KERNEL);
if (NULL == blk) if (!blk)
return -ENOMEM; return -ENOMEM;
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
...@@ -1112,6 +1112,26 @@ static int daio_mgr_put_ctrl_blk(void *blk) ...@@ -1112,6 +1112,26 @@ static int daio_mgr_put_ctrl_blk(void *blk)
return 0; return 0;
} }
/* Timer interrupt */
static int set_timer_irq(struct hw *hw, int enable)
{
hw_write_20kx(hw, GIE, enable ? IT_INT : 0);
return 0;
}
static int set_timer_tick(struct hw *hw, unsigned int ticks)
{
if (ticks)
ticks |= TIMR_IE | TIMR_IP;
hw_write_20kx(hw, TIMR, ticks);
return 0;
}
static unsigned int get_wc(struct hw *hw)
{
return hw_read_20kx(hw, WC);
}
/* Card hardware initialization block */ /* Card hardware initialization block */
struct dac_conf { struct dac_conf {
unsigned int msr; /* master sample rate in rsrs */ unsigned int msr; /* master sample rate in rsrs */
...@@ -1841,6 +1861,22 @@ static int hw_have_digit_io_switch(struct hw *hw) ...@@ -1841,6 +1861,22 @@ static int hw_have_digit_io_switch(struct hw *hw)
return 0; return 0;
} }
static irqreturn_t ct_20k2_interrupt(int irq, void *dev_id)
{
struct hw *hw = dev_id;
unsigned int status;
status = hw_read_20kx(hw, GIP);
if (!status)
return IRQ_NONE;
if (hw->irq_callback)
hw->irq_callback(hw->irq_callback_data, status);
hw_write_20kx(hw, GIP, status);
return IRQ_HANDLED;
}
static int hw_card_start(struct hw *hw) static int hw_card_start(struct hw *hw)
{ {
int err = 0; int err = 0;
...@@ -1868,7 +1904,7 @@ static int hw_card_start(struct hw *hw) ...@@ -1868,7 +1904,7 @@ static int hw_card_start(struct hw *hw)
hw->io_base = pci_resource_start(hw->pci, 2); hw->io_base = pci_resource_start(hw->pci, 2);
hw->mem_base = (unsigned long)ioremap(hw->io_base, hw->mem_base = (unsigned long)ioremap(hw->io_base,
pci_resource_len(hw->pci, 2)); pci_resource_len(hw->pci, 2));
if (NULL == (void *)hw->mem_base) { if (!hw->mem_base) {
err = -ENOENT; err = -ENOENT;
goto error2; goto error2;
} }
...@@ -1879,12 +1915,15 @@ static int hw_card_start(struct hw *hw) ...@@ -1879,12 +1915,15 @@ static int hw_card_start(struct hw *hw)
set_field(&gctl, GCTL_UAA, 0); set_field(&gctl, GCTL_UAA, 0);
hw_write_20kx(hw, GLOBAL_CNTL_GCTL, gctl); hw_write_20kx(hw, GLOBAL_CNTL_GCTL, gctl);
/*if ((err = request_irq(pci->irq, ct_atc_interrupt, IRQF_SHARED, if (hw->irq < 0) {
atc->chip_details->nm_card, hw))) { err = request_irq(pci->irq, ct_20k2_interrupt, IRQF_SHARED,
goto error3; "ctxfi", hw);
if (err < 0) {
printk(KERN_ERR "XFi: Cannot get irq %d\n", pci->irq);
goto error2;
}
hw->irq = pci->irq;
} }
hw->irq = pci->irq;
*/
pci_set_master(pci); pci_set_master(pci);
...@@ -1923,7 +1962,7 @@ static int hw_card_shutdown(struct hw *hw) ...@@ -1923,7 +1962,7 @@ static int hw_card_shutdown(struct hw *hw)
hw->irq = -1; hw->irq = -1;
if (NULL != ((void *)hw->mem_base)) if (hw->mem_base)
iounmap((void *)hw->mem_base); iounmap((void *)hw->mem_base);
hw->mem_base = (unsigned long)NULL; hw->mem_base = (unsigned long)NULL;
...@@ -1972,7 +2011,7 @@ static int hw_card_init(struct hw *hw, struct card_conf *info) ...@@ -1972,7 +2011,7 @@ static int hw_card_init(struct hw *hw, struct card_conf *info)
hw_write_20kx(hw, GLOBAL_CNTL_GCTL, gctl); hw_write_20kx(hw, GLOBAL_CNTL_GCTL, gctl);
/* Reset all global pending interrupts */ /* Reset all global pending interrupts */
hw_write_20kx(hw, INTERRUPT_GIE, 0); hw_write_20kx(hw, GIE, 0);
/* Reset all SRC pending interrupts */ /* Reset all SRC pending interrupts */
hw_write_20kx(hw, SRC_IP, 0); hw_write_20kx(hw, SRC_IP, 0);
...@@ -2149,6 +2188,10 @@ static struct hw ct20k2_preset __devinitdata = { ...@@ -2149,6 +2188,10 @@ static struct hw ct20k2_preset __devinitdata = {
.daio_mgr_set_imapnxt = daio_mgr_set_imapnxt, .daio_mgr_set_imapnxt = daio_mgr_set_imapnxt,
.daio_mgr_set_imapaddr = daio_mgr_set_imapaddr, .daio_mgr_set_imapaddr = daio_mgr_set_imapaddr,
.daio_mgr_commit_write = daio_mgr_commit_write, .daio_mgr_commit_write = daio_mgr_commit_write,
.set_timer_irq = set_timer_irq,
.set_timer_tick = set_timer_tick,
.get_wc = get_wc,
}; };
int __devinit create_20k2_hw_obj(struct hw **rhw) int __devinit create_20k2_hw_obj(struct hw **rhw)
......
...@@ -654,7 +654,7 @@ ct_mixer_kcontrol_new(struct ct_mixer *mixer, struct snd_kcontrol_new *new) ...@@ -654,7 +654,7 @@ ct_mixer_kcontrol_new(struct ct_mixer *mixer, struct snd_kcontrol_new *new)
int err; int err;
kctl = snd_ctl_new1(new, mixer->atc); kctl = snd_ctl_new1(new, mixer->atc);
if (NULL == kctl) if (!kctl)
return -ENOMEM; return -ENOMEM;
if (SNDRV_CTL_ELEM_IFACE_PCM == kctl->id.iface) if (SNDRV_CTL_ELEM_IFACE_PCM == kctl->id.iface)
...@@ -837,17 +837,17 @@ static int ct_mixer_get_mem(struct ct_mixer **rmixer) ...@@ -837,17 +837,17 @@ static int ct_mixer_get_mem(struct ct_mixer **rmixer)
*rmixer = NULL; *rmixer = NULL;
/* Allocate mem for mixer obj */ /* Allocate mem for mixer obj */
mixer = kzalloc(sizeof(*mixer), GFP_KERNEL); mixer = kzalloc(sizeof(*mixer), GFP_KERNEL);
if (NULL == mixer) if (!mixer)
return -ENOMEM; return -ENOMEM;
mixer->amixers = kzalloc(sizeof(void *)*(NUM_CT_AMIXERS*CHN_NUM), mixer->amixers = kzalloc(sizeof(void *)*(NUM_CT_AMIXERS*CHN_NUM),
GFP_KERNEL); GFP_KERNEL);
if (NULL == mixer->amixers) { if (!mixer->amixers) {
err = -ENOMEM; err = -ENOMEM;
goto error1; goto error1;
} }
mixer->sums = kzalloc(sizeof(void *)*(NUM_CT_SUMS*CHN_NUM), GFP_KERNEL); mixer->sums = kzalloc(sizeof(void *)*(NUM_CT_SUMS*CHN_NUM), GFP_KERNEL);
if (NULL == mixer->sums) { if (!mixer->sums) {
err = -ENOMEM; err = -ENOMEM;
goto error2; goto error2;
} }
......
...@@ -97,7 +97,7 @@ static void ct_atc_pcm_interrupt(struct ct_atc_pcm *atc_pcm) ...@@ -97,7 +97,7 @@ static void ct_atc_pcm_interrupt(struct ct_atc_pcm *atc_pcm)
{ {
struct ct_atc_pcm *apcm = atc_pcm; struct ct_atc_pcm *apcm = atc_pcm;
if (NULL == apcm->substream) if (!apcm->substream)
return; return;
snd_pcm_period_elapsed(apcm->substream); snd_pcm_period_elapsed(apcm->substream);
...@@ -123,7 +123,7 @@ static int ct_pcm_playback_open(struct snd_pcm_substream *substream) ...@@ -123,7 +123,7 @@ static int ct_pcm_playback_open(struct snd_pcm_substream *substream)
int err; int err;
apcm = kzalloc(sizeof(*apcm), GFP_KERNEL); apcm = kzalloc(sizeof(*apcm), GFP_KERNEL);
if (NULL == apcm) if (!apcm)
return -ENOMEM; return -ENOMEM;
apcm->substream = substream; apcm->substream = substream;
...@@ -271,7 +271,7 @@ static int ct_pcm_capture_open(struct snd_pcm_substream *substream) ...@@ -271,7 +271,7 @@ static int ct_pcm_capture_open(struct snd_pcm_substream *substream)
int err; int err;
apcm = kzalloc(sizeof(*apcm), GFP_KERNEL); apcm = kzalloc(sizeof(*apcm), GFP_KERNEL);
if (NULL == apcm) if (!apcm)
return -ENOMEM; return -ENOMEM;
apcm->started = 0; apcm->started = 0;
......
...@@ -144,7 +144,7 @@ int rsc_init(struct rsc *rsc, u32 idx, enum RSCTYP type, u32 msr, void *hw) ...@@ -144,7 +144,7 @@ int rsc_init(struct rsc *rsc, u32 idx, enum RSCTYP type, u32 msr, void *hw)
rsc->msr = msr; rsc->msr = msr;
rsc->hw = hw; rsc->hw = hw;
rsc->ops = &rsc_generic_ops; rsc->ops = &rsc_generic_ops;
if (NULL == hw) { if (!hw) {
rsc->ctrl_blk = NULL; rsc->ctrl_blk = NULL;
return 0; return 0;
} }
...@@ -216,7 +216,7 @@ int rsc_mgr_init(struct rsc_mgr *mgr, enum RSCTYP type, ...@@ -216,7 +216,7 @@ int rsc_mgr_init(struct rsc_mgr *mgr, enum RSCTYP type,
mgr->type = NUM_RSCTYP; mgr->type = NUM_RSCTYP;
mgr->rscs = kzalloc(((amount + 8 - 1) / 8), GFP_KERNEL); mgr->rscs = kzalloc(((amount + 8 - 1) / 8), GFP_KERNEL);
if (NULL == mgr->rscs) if (!mgr->rscs)
return -ENOMEM; return -ENOMEM;
switch (type) { switch (type) {
......
...@@ -441,7 +441,7 @@ get_src_rsc(struct src_mgr *mgr, const struct src_desc *desc, struct src **rsrc) ...@@ -441,7 +441,7 @@ get_src_rsc(struct src_mgr *mgr, const struct src_desc *desc, struct src **rsrc)
else else
src = kzalloc(sizeof(*src), GFP_KERNEL); src = kzalloc(sizeof(*src), GFP_KERNEL);
if (NULL == src) { if (!src) {
err = -ENOMEM; err = -ENOMEM;
goto error1; goto error1;
} }
...@@ -550,7 +550,7 @@ int src_mgr_create(void *hw, struct src_mgr **rsrc_mgr) ...@@ -550,7 +550,7 @@ int src_mgr_create(void *hw, struct src_mgr **rsrc_mgr)
*rsrc_mgr = NULL; *rsrc_mgr = NULL;
src_mgr = kzalloc(sizeof(*src_mgr), GFP_KERNEL); src_mgr = kzalloc(sizeof(*src_mgr), GFP_KERNEL);
if (NULL == src_mgr) if (!src_mgr)
return -ENOMEM; return -ENOMEM;
err = rsc_mgr_init(&src_mgr->mgr, SRC, SRC_RESOURCE_NUM, hw); err = rsc_mgr_init(&src_mgr->mgr, SRC, SRC_RESOURCE_NUM, hw);
...@@ -679,7 +679,7 @@ static int srcimp_rsc_init(struct srcimp *srcimp, ...@@ -679,7 +679,7 @@ static int srcimp_rsc_init(struct srcimp *srcimp,
/* Reserve memory for imapper nodes */ /* Reserve memory for imapper nodes */
srcimp->imappers = kzalloc(sizeof(struct imapper)*desc->msr, srcimp->imappers = kzalloc(sizeof(struct imapper)*desc->msr,
GFP_KERNEL); GFP_KERNEL);
if (NULL == srcimp->imappers) { if (!srcimp->imappers) {
err = -ENOMEM; err = -ENOMEM;
goto error1; goto error1;
} }
...@@ -833,7 +833,7 @@ int srcimp_mgr_create(void *hw, struct srcimp_mgr **rsrcimp_mgr) ...@@ -833,7 +833,7 @@ int srcimp_mgr_create(void *hw, struct srcimp_mgr **rsrcimp_mgr)
*rsrcimp_mgr = NULL; *rsrcimp_mgr = NULL;
srcimp_mgr = kzalloc(sizeof(*srcimp_mgr), GFP_KERNEL); srcimp_mgr = kzalloc(sizeof(*srcimp_mgr), GFP_KERNEL);
if (NULL == srcimp_mgr) if (!srcimp_mgr)
return -ENOMEM; return -ENOMEM;
err = rsc_mgr_init(&srcimp_mgr->mgr, SRCIMP, SRCIMP_RESOURCE_NUM, hw); err = rsc_mgr_init(&srcimp_mgr->mgr, SRCIMP, SRCIMP_RESOURCE_NUM, hw);
...@@ -844,7 +844,7 @@ int srcimp_mgr_create(void *hw, struct srcimp_mgr **rsrcimp_mgr) ...@@ -844,7 +844,7 @@ int srcimp_mgr_create(void *hw, struct srcimp_mgr **rsrcimp_mgr)
spin_lock_init(&srcimp_mgr->imap_lock); spin_lock_init(&srcimp_mgr->imap_lock);
INIT_LIST_HEAD(&srcimp_mgr->imappers); INIT_LIST_HEAD(&srcimp_mgr->imappers);
entry = kzalloc(sizeof(*entry), GFP_KERNEL); entry = kzalloc(sizeof(*entry), GFP_KERNEL);
if (NULL == entry) { if (!entry) {
err = -ENOMEM; err = -ENOMEM;
goto error2; goto error2;
} }
......
...@@ -60,7 +60,7 @@ get_vm_block(struct ct_vm *vm, unsigned int size) ...@@ -60,7 +60,7 @@ get_vm_block(struct ct_vm *vm, unsigned int size)
} }
block = kzalloc(sizeof(*block), GFP_KERNEL); block = kzalloc(sizeof(*block), GFP_KERNEL);
if (NULL == block) if (!block)
goto out; goto out;
block->addr = entry->addr; block->addr = entry->addr;
...@@ -181,7 +181,7 @@ int ct_vm_create(struct ct_vm **rvm) ...@@ -181,7 +181,7 @@ int ct_vm_create(struct ct_vm **rvm)
*rvm = NULL; *rvm = NULL;
vm = kzalloc(sizeof(*vm), GFP_KERNEL); vm = kzalloc(sizeof(*vm), GFP_KERNEL);
if (NULL == vm) if (!vm)
return -ENOMEM; return -ENOMEM;
mutex_init(&vm->lock); mutex_init(&vm->lock);
...@@ -189,7 +189,7 @@ int ct_vm_create(struct ct_vm **rvm) ...@@ -189,7 +189,7 @@ int ct_vm_create(struct ct_vm **rvm)
/* Allocate page table pages */ /* Allocate page table pages */
for (i = 0; i < CT_PTP_NUM; i++) { for (i = 0; i < CT_PTP_NUM; i++) {
vm->ptp[i] = kmalloc(PAGE_SIZE, GFP_KERNEL); vm->ptp[i] = kmalloc(PAGE_SIZE, GFP_KERNEL);
if (NULL == vm->ptp[i]) if (!vm->ptp[i])
break; break;
} }
if (!i) { if (!i) {
......
...@@ -46,6 +46,20 @@ config SND_HDA_INPUT_JACK ...@@ -46,6 +46,20 @@ config SND_HDA_INPUT_JACK
Say Y here to enable the jack plugging notification via Say Y here to enable the jack plugging notification via
input layer. input layer.
config SND_HDA_PATCH_LOADER
bool "Support initialization patch loading for HD-audio"
depends on EXPERIMENTAL
select FW_LOADER
select SND_HDA_HWDEP
select SND_HDA_RECONFIG
help
Say Y here to allow the HD-audio driver to load a pseudo
firmware file ("patch") for overriding the BIOS setup at
start up. The "patch" file can be specified via patch module
option, such as patch=hda-init.
This option turns on hwdep and reconfig features automatically.
config SND_HDA_CODEC_REALTEK config SND_HDA_CODEC_REALTEK
bool "Build Realtek HD-audio codec support" bool "Build Realtek HD-audio codec support"
default y default y
...@@ -134,6 +148,19 @@ config SND_HDA_ELD ...@@ -134,6 +148,19 @@ config SND_HDA_ELD
def_bool y def_bool y
depends on SND_HDA_CODEC_INTELHDMI depends on SND_HDA_CODEC_INTELHDMI
config SND_HDA_CODEC_CIRRUS
bool "Build Cirrus Logic codec support"
depends on SND_HDA_INTEL
default y
help
Say Y here to include Cirrus Logic codec support in
snd-hda-intel driver, such as CS4206.
When the HD-audio driver is built as a module, the codec
support code is also built as another module,
snd-hda-codec-cirrus.
This module is automatically loaded at probing.
config SND_HDA_CODEC_CONEXANT config SND_HDA_CODEC_CONEXANT
bool "Build Conexant HD-audio codec support" bool "Build Conexant HD-audio codec support"
default y default y
......
...@@ -13,6 +13,7 @@ snd-hda-codec-analog-objs := patch_analog.o ...@@ -13,6 +13,7 @@ snd-hda-codec-analog-objs := patch_analog.o
snd-hda-codec-idt-objs := patch_sigmatel.o snd-hda-codec-idt-objs := patch_sigmatel.o
snd-hda-codec-si3054-objs := patch_si3054.o snd-hda-codec-si3054-objs := patch_si3054.o
snd-hda-codec-atihdmi-objs := patch_atihdmi.o snd-hda-codec-atihdmi-objs := patch_atihdmi.o
snd-hda-codec-cirrus-objs := patch_cirrus.o
snd-hda-codec-ca0110-objs := patch_ca0110.o snd-hda-codec-ca0110-objs := patch_ca0110.o
snd-hda-codec-conexant-objs := patch_conexant.o snd-hda-codec-conexant-objs := patch_conexant.o
snd-hda-codec-via-objs := patch_via.o snd-hda-codec-via-objs := patch_via.o
...@@ -41,6 +42,9 @@ endif ...@@ -41,6 +42,9 @@ endif
ifdef CONFIG_SND_HDA_CODEC_ATIHDMI ifdef CONFIG_SND_HDA_CODEC_ATIHDMI
obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-atihdmi.o obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-atihdmi.o
endif endif
ifdef CONFIG_SND_HDA_CODEC_CIRRUS
obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-cirrus.o
endif
ifdef CONFIG_SND_HDA_CODEC_CA0110 ifdef CONFIG_SND_HDA_CODEC_CA0110
obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-ca0110.o obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-ca0110.o
endif endif
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <sound/core.h> #include <sound/core.h>
#include "hda_beep.h" #include "hda_beep.h"
#include "hda_local.h"
enum { enum {
DIGBEEP_HZ_STEP = 46875, /* 46.875 Hz */ DIGBEEP_HZ_STEP = 46875, /* 46.875 Hz */
...@@ -118,6 +119,9 @@ int snd_hda_attach_beep_device(struct hda_codec *codec, int nid) ...@@ -118,6 +119,9 @@ int snd_hda_attach_beep_device(struct hda_codec *codec, int nid)
struct hda_beep *beep; struct hda_beep *beep;
int err; int err;
if (!snd_hda_get_bool_hint(codec, "beep"))
return 0; /* disabled explicitly */
beep = kzalloc(sizeof(*beep), GFP_KERNEL); beep = kzalloc(sizeof(*beep), GFP_KERNEL);
if (beep == NULL) if (beep == NULL)
return -ENOMEM; return -ENOMEM;
......
...@@ -44,6 +44,7 @@ struct hda_vendor_id { ...@@ -44,6 +44,7 @@ struct hda_vendor_id {
/* codec vendor labels */ /* codec vendor labels */
static struct hda_vendor_id hda_vendor_ids[] = { static struct hda_vendor_id hda_vendor_ids[] = {
{ 0x1002, "ATI" }, { 0x1002, "ATI" },
{ 0x1013, "Cirrus Logic" },
{ 0x1057, "Motorola" }, { 0x1057, "Motorola" },
{ 0x1095, "Silicon Image" }, { 0x1095, "Silicon Image" },
{ 0x10de, "Nvidia" }, { 0x10de, "Nvidia" },
...@@ -150,7 +151,14 @@ make_codec_cmd(struct hda_codec *codec, hda_nid_t nid, int direct, ...@@ -150,7 +151,14 @@ make_codec_cmd(struct hda_codec *codec, hda_nid_t nid, int direct,
{ {
u32 val; u32 val;
val = (u32)(codec->addr & 0x0f) << 28; if ((codec->addr & ~0xf) || (direct & ~1) || (nid & ~0x7f) ||
(verb & ~0xfff) || (parm & ~0xffff)) {
printk(KERN_ERR "hda-codec: out of range cmd %x:%x:%x:%x:%x\n",
codec->addr, direct, nid, verb, parm);
return ~0;
}
val = (u32)codec->addr << 28;
val |= (u32)direct << 27; val |= (u32)direct << 27;
val |= (u32)nid << 20; val |= (u32)nid << 20;
val |= verb << 8; val |= verb << 8;
...@@ -167,6 +175,9 @@ static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd, ...@@ -167,6 +175,9 @@ static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd,
struct hda_bus *bus = codec->bus; struct hda_bus *bus = codec->bus;
int err; int err;
if (cmd == ~0)
return -1;
if (res) if (res)
*res = -1; *res = -1;
again: again:
...@@ -291,11 +302,20 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, ...@@ -291,11 +302,20 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
unsigned int parm; unsigned int parm;
int i, conn_len, conns; int i, conn_len, conns;
unsigned int shift, num_elems, mask; unsigned int shift, num_elems, mask;
unsigned int wcaps;
hda_nid_t prev_nid; hda_nid_t prev_nid;
if (snd_BUG_ON(!conn_list || max_conns <= 0)) if (snd_BUG_ON(!conn_list || max_conns <= 0))
return -EINVAL; return -EINVAL;
wcaps = get_wcaps(codec, nid);
if (!(wcaps & AC_WCAP_CONN_LIST) &&
get_wcaps_type(wcaps) != AC_WID_VOL_KNB) {
snd_printk(KERN_WARNING "hda_codec: "
"connection list not available for 0x%x\n", nid);
return -EINVAL;
}
parm = snd_hda_param_read(codec, nid, AC_PAR_CONNLIST_LEN); parm = snd_hda_param_read(codec, nid, AC_PAR_CONNLIST_LEN);
if (parm & AC_CLIST_LONG) { if (parm & AC_CLIST_LONG) {
/* long form */ /* long form */
...@@ -316,6 +336,8 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, ...@@ -316,6 +336,8 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
/* single connection */ /* single connection */
parm = snd_hda_codec_read(codec, nid, 0, parm = snd_hda_codec_read(codec, nid, 0,
AC_VERB_GET_CONNECT_LIST, 0); AC_VERB_GET_CONNECT_LIST, 0);
if (parm == -1 && codec->bus->rirb_error)
return -EIO;
conn_list[0] = parm & mask; conn_list[0] = parm & mask;
return 1; return 1;
} }
...@@ -327,9 +349,12 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, ...@@ -327,9 +349,12 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
int range_val; int range_val;
hda_nid_t val, n; hda_nid_t val, n;
if (i % num_elems == 0) if (i % num_elems == 0) {
parm = snd_hda_codec_read(codec, nid, 0, parm = snd_hda_codec_read(codec, nid, 0,
AC_VERB_GET_CONNECT_LIST, i); AC_VERB_GET_CONNECT_LIST, i);
if (parm == -1 && codec->bus->rirb_error)
return -EIO;
}
range_val = !!(parm & (1 << (shift-1))); /* ranges */ range_val = !!(parm & (1 << (shift-1))); /* ranges */
val = parm & mask; val = parm & mask;
if (val == 0) { if (val == 0) {
...@@ -727,8 +752,7 @@ static int read_pin_defaults(struct hda_codec *codec) ...@@ -727,8 +752,7 @@ static int read_pin_defaults(struct hda_codec *codec)
for (i = 0; i < codec->num_nodes; i++, nid++) { for (i = 0; i < codec->num_nodes; i++, nid++) {
struct hda_pincfg *pin; struct hda_pincfg *pin;
unsigned int wcaps = get_wcaps(codec, nid); unsigned int wcaps = get_wcaps(codec, nid);
unsigned int wid_type = (wcaps & AC_WCAP_TYPE) >> unsigned int wid_type = get_wcaps_type(wcaps);
AC_WCAP_TYPE_SHIFT;
if (wid_type != AC_WID_PIN) if (wid_type != AC_WID_PIN)
continue; continue;
pin = snd_array_new(&codec->init_pins); pin = snd_array_new(&codec->init_pins);
...@@ -891,7 +915,7 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg, ...@@ -891,7 +915,7 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
* Returns 0 if successful, or a negative error code. * Returns 0 if successful, or a negative error code.
*/ */
int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
int do_init, struct hda_codec **codecp) struct hda_codec **codecp)
{ {
struct hda_codec *codec; struct hda_codec *codec;
char component[31]; char component[31];
...@@ -984,11 +1008,6 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr ...@@ -984,11 +1008,6 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr
codec->afg ? codec->afg : codec->mfg, codec->afg ? codec->afg : codec->mfg,
AC_PWRST_D0); AC_PWRST_D0);
if (do_init) {
err = snd_hda_codec_configure(codec);
if (err < 0)
goto error;
}
snd_hda_codec_proc_new(codec); snd_hda_codec_proc_new(codec);
snd_hda_create_hwdep(codec); snd_hda_create_hwdep(codec);
...@@ -1042,6 +1061,7 @@ int snd_hda_codec_configure(struct hda_codec *codec) ...@@ -1042,6 +1061,7 @@ int snd_hda_codec_configure(struct hda_codec *codec)
err = init_unsol_queue(codec->bus); err = init_unsol_queue(codec->bus);
return err; return err;
} }
EXPORT_SYMBOL_HDA(snd_hda_codec_configure);
/** /**
* snd_hda_codec_setup_stream - set up the codec for streaming * snd_hda_codec_setup_stream - set up the codec for streaming
...@@ -2356,16 +2376,20 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg, ...@@ -2356,16 +2376,20 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
hda_nid_t nid; hda_nid_t nid;
int i; int i;
snd_hda_codec_write(codec, fg, 0, AC_VERB_SET_POWER_STATE, /* this delay seems necessary to avoid click noise at power-down */
if (power_state == AC_PWRST_D3)
msleep(100);
snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE,
power_state); power_state);
msleep(10); /* partial workaround for "azx_get_response timeout" */ /* partial workaround for "azx_get_response timeout" */
if (power_state == AC_PWRST_D0)
msleep(10);
nid = codec->start_nid; nid = codec->start_nid;
for (i = 0; i < codec->num_nodes; i++, nid++) { for (i = 0; i < codec->num_nodes; i++, nid++) {
unsigned int wcaps = get_wcaps(codec, nid); unsigned int wcaps = get_wcaps(codec, nid);
if (wcaps & AC_WCAP_POWER) { if (wcaps & AC_WCAP_POWER) {
unsigned int wid_type = (wcaps & AC_WCAP_TYPE) >> unsigned int wid_type = get_wcaps_type(wcaps);
AC_WCAP_TYPE_SHIFT;
if (power_state == AC_PWRST_D3 && if (power_state == AC_PWRST_D3 &&
wid_type == AC_WID_PIN) { wid_type == AC_WID_PIN) {
unsigned int pincap; unsigned int pincap;
...@@ -2573,7 +2597,7 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate, ...@@ -2573,7 +2597,7 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate,
case 20: case 20:
case 24: case 24:
case 32: case 32:
if (maxbps >= 32) if (maxbps >= 32 || format == SNDRV_PCM_FORMAT_FLOAT_LE)
val |= 0x40; val |= 0x40;
else if (maxbps >= 24) else if (maxbps >= 24)
val |= 0x30; val |= 0x30;
...@@ -2700,11 +2724,12 @@ static int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, ...@@ -2700,11 +2724,12 @@ static int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
bps = 20; bps = 20;
} }
} }
else if (streams == AC_SUPFMT_FLOAT32) { if (streams & AC_SUPFMT_FLOAT32) {
/* should be exclusive */
formats |= SNDRV_PCM_FMTBIT_FLOAT_LE; formats |= SNDRV_PCM_FMTBIT_FLOAT_LE;
bps = 32; if (!bps)
} else if (streams == AC_SUPFMT_AC3) { bps = 32;
}
if (streams == AC_SUPFMT_AC3) {
/* should be exclusive */ /* should be exclusive */
/* temporary hack: we have still no proper support /* temporary hack: we have still no proper support
* for the direct AC3 stream... * for the direct AC3 stream...
...@@ -3102,7 +3127,7 @@ int snd_hda_check_board_codec_sid_config(struct hda_codec *codec, ...@@ -3102,7 +3127,7 @@ int snd_hda_check_board_codec_sid_config(struct hda_codec *codec,
tbl = q; tbl = q;
if (tbl->value >= 0 && tbl->value < num_configs) { if (tbl->value >= 0 && tbl->value < num_configs) {
#ifdef CONFIG_SND_DEBUG_DETECT #ifdef CONFIG_SND_DEBUG_VERBOSE
char tmp[10]; char tmp[10];
const char *model = NULL; const char *model = NULL;
if (models) if (models)
...@@ -3655,8 +3680,7 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, ...@@ -3655,8 +3680,7 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
end_nid = codec->start_nid + codec->num_nodes; end_nid = codec->start_nid + codec->num_nodes;
for (nid = codec->start_nid; nid < end_nid; nid++) { for (nid = codec->start_nid; nid < end_nid; nid++) {
unsigned int wid_caps = get_wcaps(codec, nid); unsigned int wid_caps = get_wcaps(codec, nid);
unsigned int wid_type = unsigned int wid_type = get_wcaps_type(wid_caps);
(wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
unsigned int def_conf; unsigned int def_conf;
short assoc, loc; short assoc, loc;
......
...@@ -830,7 +830,8 @@ enum { ...@@ -830,7 +830,8 @@ enum {
int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp, int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp,
struct hda_bus **busp); struct hda_bus **busp);
int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
int do_init, struct hda_codec **codecp); struct hda_codec **codecp);
int snd_hda_codec_configure(struct hda_codec *codec);
/* /*
* low level functions * low level functions
...@@ -938,6 +939,13 @@ static inline void snd_hda_power_down(struct hda_codec *codec) {} ...@@ -938,6 +939,13 @@ static inline void snd_hda_power_down(struct hda_codec *codec) {}
#define snd_hda_codec_needs_resume(codec) 1 #define snd_hda_codec_needs_resume(codec) 1
#endif #endif
#ifdef CONFIG_SND_HDA_PATCH_LOADER
/*
* patch firmware
*/
int snd_hda_load_patch(struct hda_bus *bus, const char *patch);
#endif
/* /*
* Codec modularization * Codec modularization
*/ */
......
...@@ -121,11 +121,17 @@ static int add_new_node(struct hda_codec *codec, struct hda_gspec *spec, hda_nid ...@@ -121,11 +121,17 @@ static int add_new_node(struct hda_codec *codec, struct hda_gspec *spec, hda_nid
if (node == NULL) if (node == NULL)
return -ENOMEM; return -ENOMEM;
node->nid = nid; node->nid = nid;
nconns = snd_hda_get_connections(codec, nid, conn_list, node->wid_caps = get_wcaps(codec, nid);
HDA_MAX_CONNECTIONS); node->type = get_wcaps_type(node->wid_caps);
if (nconns < 0) { if (node->wid_caps & AC_WCAP_CONN_LIST) {
kfree(node); nconns = snd_hda_get_connections(codec, nid, conn_list,
return nconns; HDA_MAX_CONNECTIONS);
if (nconns < 0) {
kfree(node);
return nconns;
}
} else {
nconns = 0;
} }
if (nconns <= ARRAY_SIZE(node->slist)) if (nconns <= ARRAY_SIZE(node->slist))
node->conn_list = node->slist; node->conn_list = node->slist;
...@@ -140,8 +146,6 @@ static int add_new_node(struct hda_codec *codec, struct hda_gspec *spec, hda_nid ...@@ -140,8 +146,6 @@ static int add_new_node(struct hda_codec *codec, struct hda_gspec *spec, hda_nid
} }
memcpy(node->conn_list, conn_list, nconns * sizeof(hda_nid_t)); memcpy(node->conn_list, conn_list, nconns * sizeof(hda_nid_t));
node->nconns = nconns; node->nconns = nconns;
node->wid_caps = get_wcaps(codec, nid);
node->type = (node->wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
if (node->type == AC_WID_PIN) { if (node->type == AC_WID_PIN) {
node->pin_caps = snd_hda_query_pin_caps(codec, node->nid); node->pin_caps = snd_hda_query_pin_caps(codec, node->nid);
......
此差异已折叠。
此差异已折叠。
...@@ -99,7 +99,6 @@ struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec, ...@@ -99,7 +99,6 @@ struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec,
int snd_hda_add_vmaster(struct hda_codec *codec, char *name, int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
unsigned int *tlv, const char **slaves); unsigned int *tlv, const char **slaves);
int snd_hda_codec_reset(struct hda_codec *codec); int snd_hda_codec_reset(struct hda_codec *codec);
int snd_hda_codec_configure(struct hda_codec *codec);
/* amp value bits */ /* amp value bits */
#define HDA_AMP_MUTE 0x80 #define HDA_AMP_MUTE 0x80
...@@ -408,6 +407,19 @@ static inline u32 get_wcaps(struct hda_codec *codec, hda_nid_t nid) ...@@ -408,6 +407,19 @@ static inline u32 get_wcaps(struct hda_codec *codec, hda_nid_t nid)
return codec->wcaps[nid - codec->start_nid]; return codec->wcaps[nid - codec->start_nid];
} }
/* get the widget type from widget capability bits */
#define get_wcaps_type(wcaps) (((wcaps) & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT)
static inline unsigned int get_wcaps_channels(u32 wcaps)
{
unsigned int chans;
chans = (wcaps & AC_WCAP_CHAN_CNT_EXT) >> 13;
chans = ((chans << 1) | 1) + 1;
return chans;
}
u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction); u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction);
int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir, int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
unsigned int caps); unsigned int caps);
......
...@@ -508,17 +508,14 @@ static void print_codec_info(struct snd_info_entry *entry, ...@@ -508,17 +508,14 @@ static void print_codec_info(struct snd_info_entry *entry,
unsigned int wid_caps = unsigned int wid_caps =
snd_hda_param_read(codec, nid, snd_hda_param_read(codec, nid,
AC_PAR_AUDIO_WIDGET_CAP); AC_PAR_AUDIO_WIDGET_CAP);
unsigned int wid_type = unsigned int wid_type = get_wcaps_type(wid_caps);
(wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
hda_nid_t conn[HDA_MAX_CONNECTIONS]; hda_nid_t conn[HDA_MAX_CONNECTIONS];
int conn_len = 0; int conn_len = 0;
snd_iprintf(buffer, "Node 0x%02x [%s] wcaps 0x%x:", nid, snd_iprintf(buffer, "Node 0x%02x [%s] wcaps 0x%x:", nid,
get_wid_type_name(wid_type), wid_caps); get_wid_type_name(wid_type), wid_caps);
if (wid_caps & AC_WCAP_STEREO) { if (wid_caps & AC_WCAP_STEREO) {
unsigned int chans; unsigned int chans = get_wcaps_channels(wid_caps);
chans = (wid_caps & AC_WCAP_CHAN_CNT_EXT) >> 13;
chans = ((chans << 1) | 1) + 1;
if (chans == 2) if (chans == 2)
snd_iprintf(buffer, " Stereo"); snd_iprintf(buffer, " Stereo");
else else
......
此差异已折叠。
...@@ -141,8 +141,7 @@ static int atihdmi_build_pcms(struct hda_codec *codec) ...@@ -141,8 +141,7 @@ static int atihdmi_build_pcms(struct hda_codec *codec)
/* FIXME: we must check ELD and change the PCM parameters dynamically /* FIXME: we must check ELD and change the PCM parameters dynamically
*/ */
chans = get_wcaps(codec, CVT_NID); chans = get_wcaps(codec, CVT_NID);
chans = (chans & AC_WCAP_CHAN_CNT_EXT) >> 13; chans = get_wcaps_channels(chans);
chans = ((chans << 1) | 1) + 1;
info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = chans; info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = chans;
return 0; return 0;
......
...@@ -459,8 +459,7 @@ static void parse_input(struct hda_codec *codec) ...@@ -459,8 +459,7 @@ static void parse_input(struct hda_codec *codec)
nid = codec->start_nid; nid = codec->start_nid;
for (i = 0; i < codec->num_nodes; i++, nid++) { for (i = 0; i < codec->num_nodes; i++, nid++) {
unsigned int wcaps = get_wcaps(codec, nid); unsigned int wcaps = get_wcaps(codec, nid);
unsigned int type = (wcaps & AC_WCAP_TYPE) >> unsigned int type = get_wcaps_type(wcaps);
AC_WCAP_TYPE_SHIFT;
if (type != AC_WID_AUD_IN) if (type != AC_WID_AUD_IN)
continue; continue;
if (snd_hda_get_connections(codec, nid, &pin, 1) != 1) if (snd_hda_get_connections(codec, nid, &pin, 1) != 1)
......
此差异已折叠。
...@@ -635,7 +635,8 @@ static int patch_cmi9880(struct hda_codec *codec) ...@@ -635,7 +635,8 @@ static int patch_cmi9880(struct hda_codec *codec)
cmi9880_models, cmi9880_models,
cmi9880_cfg_tbl); cmi9880_cfg_tbl);
if (spec->board_config < 0) { if (spec->board_config < 0) {
snd_printdd(KERN_INFO "hda_codec: Unknown model for CMI9880\n"); snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
codec->chip_name);
spec->board_config = CMI_AUTO; /* try everything */ spec->board_config = CMI_AUTO; /* try everything */
} }
......
此差异已折叠。
此差异已折叠。
...@@ -377,6 +377,7 @@ static int patch_nvhdmi_2ch(struct hda_codec *codec) ...@@ -377,6 +377,7 @@ static int patch_nvhdmi_2ch(struct hda_codec *codec)
*/ */
static struct hda_codec_preset snd_hda_preset_nvhdmi[] = { static struct hda_codec_preset snd_hda_preset_nvhdmi[] = {
{ .id = 0x10de0002, .name = "MCP78 HDMI", .patch = patch_nvhdmi_8ch }, { .id = 0x10de0002, .name = "MCP78 HDMI", .patch = patch_nvhdmi_8ch },
{ .id = 0x10de0003, .name = "MCP78 HDMI", .patch = patch_nvhdmi_8ch },
{ .id = 0x10de0006, .name = "MCP78 HDMI", .patch = patch_nvhdmi_8ch }, { .id = 0x10de0006, .name = "MCP78 HDMI", .patch = patch_nvhdmi_8ch },
{ .id = 0x10de0007, .name = "MCP7A HDMI", .patch = patch_nvhdmi_8ch }, { .id = 0x10de0007, .name = "MCP7A HDMI", .patch = patch_nvhdmi_8ch },
{ .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch }, { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch },
...@@ -385,6 +386,7 @@ static struct hda_codec_preset snd_hda_preset_nvhdmi[] = { ...@@ -385,6 +386,7 @@ static struct hda_codec_preset snd_hda_preset_nvhdmi[] = {
}; };
MODULE_ALIAS("snd-hda-codec-id:10de0002"); MODULE_ALIAS("snd-hda-codec-id:10de0002");
MODULE_ALIAS("snd-hda-codec-id:10de0003");
MODULE_ALIAS("snd-hda-codec-id:10de0006"); MODULE_ALIAS("snd-hda-codec-id:10de0006");
MODULE_ALIAS("snd-hda-codec-id:10de0007"); MODULE_ALIAS("snd-hda-codec-id:10de0007");
MODULE_ALIAS("snd-hda-codec-id:10de0067"); MODULE_ALIAS("snd-hda-codec-id:10de0067");
......
此差异已折叠。
此差异已折叠。
...@@ -1339,8 +1339,7 @@ static int get_mux_nids(struct hda_codec *codec) ...@@ -1339,8 +1339,7 @@ static int get_mux_nids(struct hda_codec *codec)
for (i = 0; i < spec->num_adc_nids; i++) { for (i = 0; i < spec->num_adc_nids; i++) {
nid = spec->adc_nids[i]; nid = spec->adc_nids[i];
while (nid) { while (nid) {
type = (get_wcaps(codec, nid) & AC_WCAP_TYPE) type = get_wcaps_type(get_wcaps(codec, nid));
>> AC_WCAP_TYPE_SHIFT;
if (type == AC_WID_PIN) if (type == AC_WID_PIN)
break; break;
n = snd_hda_get_connections(codec, nid, conn, n = snd_hda_get_connections(codec, nid, conn,
......
...@@ -379,6 +379,15 @@ struct snd_ice1712 { ...@@ -379,6 +379,15 @@ struct snd_ice1712 {
unsigned char (*set_mclk)(struct snd_ice1712 *ice, unsigned int rate); unsigned char (*set_mclk)(struct snd_ice1712 *ice, unsigned int rate);
void (*set_spdif_clock)(struct snd_ice1712 *ice); void (*set_spdif_clock)(struct snd_ice1712 *ice);
#ifdef CONFIG_PM
int (*pm_suspend)(struct snd_ice1712 *);
int (*pm_resume)(struct snd_ice1712 *);
int pm_suspend_enabled:1;
int pm_saved_is_spdif_master:1;
unsigned int pm_saved_spdif_ctrl;
unsigned char pm_saved_spdif_cfg;
unsigned int pm_saved_route;
#endif
}; };
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
...@@ -29,6 +29,7 @@ source "sound/soc/au1x/Kconfig" ...@@ -29,6 +29,7 @@ source "sound/soc/au1x/Kconfig"
source "sound/soc/blackfin/Kconfig" source "sound/soc/blackfin/Kconfig"
source "sound/soc/davinci/Kconfig" source "sound/soc/davinci/Kconfig"
source "sound/soc/fsl/Kconfig" source "sound/soc/fsl/Kconfig"
source "sound/soc/imx/Kconfig"
source "sound/soc/omap/Kconfig" source "sound/soc/omap/Kconfig"
source "sound/soc/pxa/Kconfig" source "sound/soc/pxa/Kconfig"
source "sound/soc/s3c24xx/Kconfig" source "sound/soc/s3c24xx/Kconfig"
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册