Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
3374cd1a
Commit
3374cd1a
authored
May 20, 2010
by
Takashi Iwai
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'topic/core-cleanup' into for-linus
parents
e40152ee
670ff6ab
Changes
26
Hide whitespace changes
Inline
Side-by-side
Showing
26 changed files
with
829 additions
and
492 deletions
+829
-492
Documentation/DocBook/writing-an-alsa-driver.tmpl
Documentation/DocBook/writing-an-alsa-driver.tmpl
+17
-10
include/sound/info.h
include/sound/info.h
+12
-12
sound/atmel/Kconfig
sound/atmel/Kconfig
+1
-1
sound/atmel/ac97c.c
sound/atmel/ac97c.c
+266
-89
sound/core/control.c
sound/core/control.c
+5
-0
sound/core/info.c
sound/core/info.c
+43
-31
sound/core/oss/mixer_oss.c
sound/core/oss/mixer_oss.c
+5
-0
sound/core/oss/pcm_oss.c
sound/core/oss/pcm_oss.c
+5
-0
sound/core/pcm_native.c
sound/core/pcm_native.c
+10
-9
sound/core/rawmidi.c
sound/core/rawmidi.c
+5
-0
sound/core/seq/seq_clientmgr.c
sound/core/seq/seq_clientmgr.c
+6
-0
sound/core/sound.c
sound/core/sound.c
+38
-35
sound/core/timer.c
sound/core/timer.c
+6
-0
sound/drivers/opl4/opl4_proc.c
sound/drivers/opl4/opl4_proc.c
+25
-58
sound/isa/gus/gus_mem_proc.c
sound/isa/gus/gus_mem_proc.c
+8
-40
sound/pci/cs4281.c
sound/pci/cs4281.c
+14
-26
sound/pci/cs46xx/cs46xx_lib.c
sound/pci/cs46xx/cs46xx_lib.c
+7
-12
sound/pci/emu10k1/emuproc.c
sound/pci/emu10k1/emuproc.c
+24
-27
sound/pci/ice1712/aureon.c
sound/pci/ice1712/aureon.c
+64
-25
sound/pci/mixart/mixart.c
sound/pci/mixart/mixart.c
+8
-71
sound/ppc/tumbler.c
sound/ppc/tumbler.c
+11
-1
sound/usb/Kconfig
sound/usb/Kconfig
+1
-0
sound/usb/caiaq/control.c
sound/usb/caiaq/control.c
+78
-21
sound/usb/caiaq/device.c
sound/usb/caiaq/device.c
+7
-1
sound/usb/caiaq/device.h
sound/usb/caiaq/device.h
+14
-10
sound/usb/caiaq/input.c
sound/usb/caiaq/input.c
+149
-13
No files found.
Documentation/DocBook/writing-an-alsa-driver.tmpl
View file @
3374cd1a
...
...
@@ -5518,34 +5518,41 @@ struct _snd_pcm_runtime {
]]>
</programlisting>
</informalexample>
For the raw data,
<structfield>
size
</structfield>
field must be
set properly. This specifies the maximum size of the proc file access.
</para>
<para>
The
callback is much more complicated than the text-file
version.
You need to use a low-level I/O functions such as
The
read/write callbacks of raw mode are more direct than the text mode.
You need to use a low-level I/O functions such as
<function>
copy_from/to_user()
</function>
to transfer the
data.
<informalexample>
<programlisting>
<![CDATA[
static
long
my_file_io_read(struct snd_info_entry *entry,
static
ssize_t
my_file_io_read(struct snd_info_entry *entry,
void *file_private_data,
struct file *file,
char *buf,
unsigned long
count,
unsigned long
pos)
size_t
count,
loff_t
pos)
{
long size = count;
if (pos + size >
local_max_size)
size = local_max_size - pos;
if (copy_to_user(buf, local_data + pos, size))
if (copy_to_user(buf, local_data + pos, count))
return -EFAULT;
return
size
;
return
count
;
}
]]>
</programlisting>
</informalexample>
If the size of the info entry has been set up properly,
<structfield>
count
</structfield>
and
<structfield>
pos
</structfield>
are
guaranteed to fit within 0 and the given size.
You don't have to check the range in the callbacks unless any
other condition is required.
</para>
</chapter>
...
...
include/sound/info.h
View file @
3374cd1a
...
...
@@ -51,18 +51,18 @@ struct snd_info_entry_ops {
unsigned
short
mode
,
void
**
file_private_data
);
int
(
*
release
)(
struct
snd_info_entry
*
entry
,
unsigned
short
mode
,
void
*
file_private_data
);
long
(
*
read
)(
struct
snd_info_entry
*
entry
,
void
*
file_private_data
,
struct
file
*
file
,
char
__user
*
buf
,
unsigned
long
count
,
unsigned
long
pos
);
long
(
*
write
)(
struct
snd_info_entry
*
entry
,
void
*
file_private_data
,
struct
file
*
file
,
const
char
__user
*
buf
,
unsigned
long
count
,
unsigned
long
pos
);
lo
ng
long
(
*
llseek
)(
struct
snd_info_entry
*
entry
,
void
*
file_private_data
,
struct
file
*
file
,
long
long
offset
,
int
orig
);
unsigned
int
(
*
poll
)(
struct
snd_info_entry
*
entry
,
void
*
file_private_data
,
struct
file
*
file
,
poll_table
*
wait
);
ssize_t
(
*
read
)(
struct
snd_info_entry
*
entry
,
void
*
file_private_data
,
struct
file
*
file
,
char
__user
*
buf
,
size_t
count
,
loff_t
pos
);
ssize_t
(
*
write
)(
struct
snd_info_entry
*
entry
,
void
*
file_private_data
,
struct
file
*
file
,
const
char
__user
*
buf
,
size_t
count
,
loff_t
pos
);
lo
ff_t
(
*
llseek
)(
struct
snd_info_entry
*
entry
,
void
*
file_private_data
,
struct
file
*
file
,
loff_t
offset
,
int
orig
);
unsigned
int
(
*
poll
)(
struct
snd_info_entry
*
entry
,
void
*
file_private_data
,
struct
file
*
file
,
poll_table
*
wait
);
int
(
*
ioctl
)(
struct
snd_info_entry
*
entry
,
void
*
file_private_data
,
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
);
int
(
*
mmap
)(
struct
snd_info_entry
*
entry
,
void
*
file_private_data
,
...
...
sound/atmel/Kconfig
View file @
3374cd1a
...
...
@@ -12,7 +12,7 @@ config SND_ATMEL_AC97C
tristate "Atmel AC97 Controller (AC97C) driver"
select SND_PCM
select SND_AC97_CODEC
depends on
DW_DMAC && AVR32
depends on
(DW_DMAC && AVR32) || ARCH_AT91
help
ALSA sound driver for the Atmel AC97 controller.
...
...
sound/atmel/ac97c.c
View file @
3374cd1a
...
...
@@ -13,6 +13,7 @@
#include <linux/device.h>
#include <linux/dmaengine.h>
#include <linux/dma-mapping.h>
#include <linux/atmel_pdc.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/module.h>
...
...
@@ -31,6 +32,10 @@
#include <linux/dw_dmac.h>
#include <mach/cpu.h>
#include <mach/hardware.h>
#include <mach/gpio.h>
#include "ac97c.h"
enum
{
...
...
@@ -63,6 +68,7 @@ struct atmel_ac97c {
u64
cur_format
;
unsigned
int
cur_rate
;
unsigned
long
flags
;
int
playback_period
,
capture_period
;
/* Serialize access to opened variable */
spinlock_t
lock
;
void
__iomem
*
regs
;
...
...
@@ -242,10 +248,12 @@ static int atmel_ac97c_playback_hw_params(struct snd_pcm_substream *substream,
if
(
retval
<
0
)
return
retval
;
/* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */
if
(
retval
==
1
)
if
(
test_and_clear_bit
(
DMA_TX_READY
,
&
chip
->
flags
))
dw_dma_cyclic_free
(
chip
->
dma
.
tx_chan
);
if
(
cpu_is_at32ap7000
())
{
/* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */
if
(
retval
==
1
)
if
(
test_and_clear_bit
(
DMA_TX_READY
,
&
chip
->
flags
))
dw_dma_cyclic_free
(
chip
->
dma
.
tx_chan
);
}
/* Set restrictions to params. */
mutex_lock
(
&
opened_mutex
);
chip
->
cur_rate
=
params_rate
(
hw_params
);
...
...
@@ -266,9 +274,14 @@ static int atmel_ac97c_capture_hw_params(struct snd_pcm_substream *substream,
if
(
retval
<
0
)
return
retval
;
/* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */
if
(
retval
==
1
)
if
(
test_and_clear_bit
(
DMA_RX_READY
,
&
chip
->
flags
))
dw_dma_cyclic_free
(
chip
->
dma
.
rx_chan
);
if
(
cpu_is_at32ap7000
())
{
if
(
retval
<
0
)
return
retval
;
/* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */
if
(
retval
==
1
)
if
(
test_and_clear_bit
(
DMA_RX_READY
,
&
chip
->
flags
))
dw_dma_cyclic_free
(
chip
->
dma
.
rx_chan
);
}
/* Set restrictions to params. */
mutex_lock
(
&
opened_mutex
);
...
...
@@ -282,16 +295,20 @@ static int atmel_ac97c_capture_hw_params(struct snd_pcm_substream *substream,
static
int
atmel_ac97c_playback_hw_free
(
struct
snd_pcm_substream
*
substream
)
{
struct
atmel_ac97c
*
chip
=
snd_pcm_substream_chip
(
substream
);
if
(
test_and_clear_bit
(
DMA_TX_READY
,
&
chip
->
flags
))
dw_dma_cyclic_free
(
chip
->
dma
.
tx_chan
);
if
(
cpu_is_at32ap7000
())
{
if
(
test_and_clear_bit
(
DMA_TX_READY
,
&
chip
->
flags
))
dw_dma_cyclic_free
(
chip
->
dma
.
tx_chan
);
}
return
snd_pcm_lib_free_pages
(
substream
);
}
static
int
atmel_ac97c_capture_hw_free
(
struct
snd_pcm_substream
*
substream
)
{
struct
atmel_ac97c
*
chip
=
snd_pcm_substream_chip
(
substream
);
if
(
test_and_clear_bit
(
DMA_RX_READY
,
&
chip
->
flags
))
dw_dma_cyclic_free
(
chip
->
dma
.
rx_chan
);
if
(
cpu_is_at32ap7000
())
{
if
(
test_and_clear_bit
(
DMA_RX_READY
,
&
chip
->
flags
))
dw_dma_cyclic_free
(
chip
->
dma
.
rx_chan
);
}
return
snd_pcm_lib_free_pages
(
substream
);
}
...
...
@@ -299,9 +316,11 @@ static int atmel_ac97c_playback_prepare(struct snd_pcm_substream *substream)
{
struct
atmel_ac97c
*
chip
=
snd_pcm_substream_chip
(
substream
);
struct
snd_pcm_runtime
*
runtime
=
substream
->
runtime
;
int
block_size
=
frames_to_bytes
(
runtime
,
runtime
->
period_size
);
unsigned
long
word
=
ac97c_readl
(
chip
,
OCA
);
int
retval
;
chip
->
playback_period
=
0
;
word
&=
~
(
AC97C_CH_MASK
(
PCM_LEFT
)
|
AC97C_CH_MASK
(
PCM_RIGHT
));
/* assign channels to AC97C channel A */
...
...
@@ -320,11 +339,16 @@ static int atmel_ac97c_playback_prepare(struct snd_pcm_substream *substream)
ac97c_writel
(
chip
,
OCA
,
word
);
/* configure sample format and size */
word
=
AC97C_CMR_DMAEN
|
AC97C_CMR_SIZE_16
;
word
=
ac97c_readl
(
chip
,
CAMR
);
if
(
chip
->
opened
<=
1
)
word
=
AC97C_CMR_DMAEN
|
AC97C_CMR_SIZE_16
;
else
word
|=
AC97C_CMR_DMAEN
|
AC97C_CMR_SIZE_16
;
switch
(
runtime
->
format
)
{
case
SNDRV_PCM_FORMAT_S16_LE
:
word
|=
AC97C_CMR_CEM_LITTLE
;
if
(
cpu_is_at32ap7000
())
word
|=
AC97C_CMR_CEM_LITTLE
;
break
;
case
SNDRV_PCM_FORMAT_S16_BE
:
/* fall through */
word
&=
~
(
AC97C_CMR_CEM_LITTLE
);
...
...
@@ -363,9 +387,18 @@ static int atmel_ac97c_playback_prepare(struct snd_pcm_substream *substream)
dev_dbg
(
&
chip
->
pdev
->
dev
,
"could not set rate %d Hz
\n
"
,
runtime
->
rate
);
if
(
!
test_bit
(
DMA_TX_READY
,
&
chip
->
flags
))
retval
=
atmel_ac97c_prepare_dma
(
chip
,
substream
,
DMA_TO_DEVICE
);
if
(
cpu_is_at32ap7000
())
{
if
(
!
test_bit
(
DMA_TX_READY
,
&
chip
->
flags
))
retval
=
atmel_ac97c_prepare_dma
(
chip
,
substream
,
DMA_TO_DEVICE
);
}
else
{
/* Initialize and start the PDC */
writel
(
runtime
->
dma_addr
,
chip
->
regs
+
ATMEL_PDC_TPR
);
writel
(
block_size
/
2
,
chip
->
regs
+
ATMEL_PDC_TCR
);
writel
(
runtime
->
dma_addr
+
block_size
,
chip
->
regs
+
ATMEL_PDC_TNPR
);
writel
(
block_size
/
2
,
chip
->
regs
+
ATMEL_PDC_TNCR
);
}
return
retval
;
}
...
...
@@ -374,9 +407,11 @@ static int atmel_ac97c_capture_prepare(struct snd_pcm_substream *substream)
{
struct
atmel_ac97c
*
chip
=
snd_pcm_substream_chip
(
substream
);
struct
snd_pcm_runtime
*
runtime
=
substream
->
runtime
;
int
block_size
=
frames_to_bytes
(
runtime
,
runtime
->
period_size
);
unsigned
long
word
=
ac97c_readl
(
chip
,
ICA
);
int
retval
;
chip
->
capture_period
=
0
;
word
&=
~
(
AC97C_CH_MASK
(
PCM_LEFT
)
|
AC97C_CH_MASK
(
PCM_RIGHT
));
/* assign channels to AC97C channel A */
...
...
@@ -395,11 +430,16 @@ static int atmel_ac97c_capture_prepare(struct snd_pcm_substream *substream)
ac97c_writel
(
chip
,
ICA
,
word
);
/* configure sample format and size */
word
=
AC97C_CMR_DMAEN
|
AC97C_CMR_SIZE_16
;
word
=
ac97c_readl
(
chip
,
CAMR
);
if
(
chip
->
opened
<=
1
)
word
=
AC97C_CMR_DMAEN
|
AC97C_CMR_SIZE_16
;
else
word
|=
AC97C_CMR_DMAEN
|
AC97C_CMR_SIZE_16
;
switch
(
runtime
->
format
)
{
case
SNDRV_PCM_FORMAT_S16_LE
:
word
|=
AC97C_CMR_CEM_LITTLE
;
if
(
cpu_is_at32ap7000
())
word
|=
AC97C_CMR_CEM_LITTLE
;
break
;
case
SNDRV_PCM_FORMAT_S16_BE
:
/* fall through */
word
&=
~
(
AC97C_CMR_CEM_LITTLE
);
...
...
@@ -438,9 +478,18 @@ static int atmel_ac97c_capture_prepare(struct snd_pcm_substream *substream)
dev_dbg
(
&
chip
->
pdev
->
dev
,
"could not set rate %d Hz
\n
"
,
runtime
->
rate
);
if
(
!
test_bit
(
DMA_RX_READY
,
&
chip
->
flags
))
retval
=
atmel_ac97c_prepare_dma
(
chip
,
substream
,
DMA_FROM_DEVICE
);
if
(
cpu_is_at32ap7000
())
{
if
(
!
test_bit
(
DMA_RX_READY
,
&
chip
->
flags
))
retval
=
atmel_ac97c_prepare_dma
(
chip
,
substream
,
DMA_FROM_DEVICE
);
}
else
{
/* Initialize and start the PDC */
writel
(
runtime
->
dma_addr
,
chip
->
regs
+
ATMEL_PDC_RPR
);
writel
(
block_size
/
2
,
chip
->
regs
+
ATMEL_PDC_RCR
);
writel
(
runtime
->
dma_addr
+
block_size
,
chip
->
regs
+
ATMEL_PDC_RNPR
);
writel
(
block_size
/
2
,
chip
->
regs
+
ATMEL_PDC_RNCR
);
}
return
retval
;
}
...
...
@@ -449,7 +498,7 @@ static int
atmel_ac97c_playback_trigger
(
struct
snd_pcm_substream
*
substream
,
int
cmd
)
{
struct
atmel_ac97c
*
chip
=
snd_pcm_substream_chip
(
substream
);
unsigned
long
camr
;
unsigned
long
camr
,
ptcr
=
0
;
int
retval
=
0
;
camr
=
ac97c_readl
(
chip
,
CAMR
);
...
...
@@ -458,15 +507,22 @@ atmel_ac97c_playback_trigger(struct snd_pcm_substream *substream, int cmd)
case
SNDRV_PCM_TRIGGER_PAUSE_RELEASE
:
/* fall through */
case
SNDRV_PCM_TRIGGER_RESUME
:
/* fall through */
case
SNDRV_PCM_TRIGGER_START
:
retval
=
dw_dma_cyclic_start
(
chip
->
dma
.
tx_chan
);
if
(
retval
)
goto
out
;
camr
|=
AC97C_CMR_CENA
;
if
(
cpu_is_at32ap7000
())
{
retval
=
dw_dma_cyclic_start
(
chip
->
dma
.
tx_chan
);
if
(
retval
)
goto
out
;
}
else
{
ptcr
=
ATMEL_PDC_TXTEN
;
}
camr
|=
AC97C_CMR_CENA
|
AC97C_CSR_ENDTX
;
break
;
case
SNDRV_PCM_TRIGGER_PAUSE_PUSH
:
/* fall through */
case
SNDRV_PCM_TRIGGER_SUSPEND
:
/* fall through */
case
SNDRV_PCM_TRIGGER_STOP
:
dw_dma_cyclic_stop
(
chip
->
dma
.
tx_chan
);
if
(
cpu_is_at32ap7000
())
dw_dma_cyclic_stop
(
chip
->
dma
.
tx_chan
);
else
ptcr
|=
ATMEL_PDC_TXTDIS
;
if
(
chip
->
opened
<=
1
)
camr
&=
~
AC97C_CMR_CENA
;
break
;
...
...
@@ -476,6 +532,8 @@ atmel_ac97c_playback_trigger(struct snd_pcm_substream *substream, int cmd)
}
ac97c_writel
(
chip
,
CAMR
,
camr
);
if
(
!
cpu_is_at32ap7000
())
writel
(
ptcr
,
chip
->
regs
+
ATMEL_PDC_PTCR
);
out:
return
retval
;
}
...
...
@@ -484,24 +542,32 @@ static int
atmel_ac97c_capture_trigger
(
struct
snd_pcm_substream
*
substream
,
int
cmd
)
{
struct
atmel_ac97c
*
chip
=
snd_pcm_substream_chip
(
substream
);
unsigned
long
camr
;
unsigned
long
camr
,
ptcr
=
0
;
int
retval
=
0
;
camr
=
ac97c_readl
(
chip
,
CAMR
);
ptcr
=
readl
(
chip
->
regs
+
ATMEL_PDC_PTSR
);
switch
(
cmd
)
{
case
SNDRV_PCM_TRIGGER_PAUSE_RELEASE
:
/* fall through */
case
SNDRV_PCM_TRIGGER_RESUME
:
/* fall through */
case
SNDRV_PCM_TRIGGER_START
:
retval
=
dw_dma_cyclic_start
(
chip
->
dma
.
rx_chan
);
if
(
retval
)
goto
out
;
camr
|=
AC97C_CMR_CENA
;
if
(
cpu_is_at32ap7000
())
{
retval
=
dw_dma_cyclic_start
(
chip
->
dma
.
rx_chan
);
if
(
retval
)
goto
out
;
}
else
{
ptcr
=
ATMEL_PDC_RXTEN
;
}
camr
|=
AC97C_CMR_CENA
|
AC97C_CSR_ENDRX
;
break
;
case
SNDRV_PCM_TRIGGER_PAUSE_PUSH
:
/* fall through */
case
SNDRV_PCM_TRIGGER_SUSPEND
:
/* fall through */
case
SNDRV_PCM_TRIGGER_STOP
:
dw_dma_cyclic_stop
(
chip
->
dma
.
rx_chan
);
if
(
cpu_is_at32ap7000
())
dw_dma_cyclic_stop
(
chip
->
dma
.
rx_chan
);
else
ptcr
|=
(
ATMEL_PDC_RXTDIS
);
if
(
chip
->
opened
<=
1
)
camr
&=
~
AC97C_CMR_CENA
;
break
;
...
...
@@ -511,6 +577,8 @@ atmel_ac97c_capture_trigger(struct snd_pcm_substream *substream, int cmd)
}
ac97c_writel
(
chip
,
CAMR
,
camr
);
if
(
!
cpu_is_at32ap7000
())
writel
(
ptcr
,
chip
->
regs
+
ATMEL_PDC_PTCR
);
out:
return
retval
;
}
...
...
@@ -523,7 +591,10 @@ atmel_ac97c_playback_pointer(struct snd_pcm_substream *substream)
snd_pcm_uframes_t
frames
;
unsigned
long
bytes
;
bytes
=
dw_dma_get_src_addr
(
chip
->
dma
.
tx_chan
);
if
(
cpu_is_at32ap7000
())
bytes
=
dw_dma_get_src_addr
(
chip
->
dma
.
tx_chan
);
else
bytes
=
readl
(
chip
->
regs
+
ATMEL_PDC_TPR
);
bytes
-=
runtime
->
dma_addr
;
frames
=
bytes_to_frames
(
runtime
,
bytes
);
...
...
@@ -540,7 +611,10 @@ atmel_ac97c_capture_pointer(struct snd_pcm_substream *substream)
snd_pcm_uframes_t
frames
;
unsigned
long
bytes
;
bytes
=
dw_dma_get_dst_addr
(
chip
->
dma
.
rx_chan
);
if
(
cpu_is_at32ap7000
())
bytes
=
dw_dma_get_dst_addr
(
chip
->
dma
.
rx_chan
);
else
bytes
=
readl
(
chip
->
regs
+
ATMEL_PDC_RPR
);
bytes
-=
runtime
->
dma_addr
;
frames
=
bytes_to_frames
(
runtime
,
bytes
);
...
...
@@ -578,8 +652,11 @@ static irqreturn_t atmel_ac97c_interrupt(int irq, void *dev)
u32
sr
=
ac97c_readl
(
chip
,
SR
);
u32
casr
=
ac97c_readl
(
chip
,
CASR
);
u32
cosr
=
ac97c_readl
(
chip
,
COSR
);
u32
camr
=
ac97c_readl
(
chip
,
CAMR
);
if
(
sr
&
AC97C_SR_CAEVT
)
{
struct
snd_pcm_runtime
*
runtime
;
int
offset
,
next_period
,
block_size
;
dev_info
(
&
chip
->
pdev
->
dev
,
"channel A event%s%s%s%s%s%s
\n
"
,
casr
&
AC97C_CSR_OVRUN
?
" OVRUN"
:
""
,
casr
&
AC97C_CSR_RXRDY
?
" RXRDY"
:
""
,
...
...
@@ -587,6 +664,50 @@ static irqreturn_t atmel_ac97c_interrupt(int irq, void *dev)
casr
&
AC97C_CSR_TXEMPTY
?
" TXEMPTY"
:
""
,
casr
&
AC97C_CSR_TXRDY
?
" TXRDY"
:
""
,
!
casr
?
" NONE"
:
""
);
if
(
!
cpu_is_at32ap7000
())
{
if
((
casr
&
camr
)
&
AC97C_CSR_ENDTX
)
{
runtime
=
chip
->
playback_substream
->
runtime
;
block_size
=
frames_to_bytes
(
runtime
,
runtime
->
period_size
);
chip
->
playback_period
++
;
if
(
chip
->
playback_period
==
runtime
->
periods
)
chip
->
playback_period
=
0
;
next_period
=
chip
->
playback_period
+
1
;
if
(
next_period
==
runtime
->
periods
)
next_period
=
0
;
offset
=
block_size
*
next_period
;
writel
(
runtime
->
dma_addr
+
offset
,
chip
->
regs
+
ATMEL_PDC_TNPR
);
writel
(
block_size
/
2
,
chip
->
regs
+
ATMEL_PDC_TNCR
);
snd_pcm_period_elapsed
(
chip
->
playback_substream
);
}
if
((
casr
&
camr
)
&
AC97C_CSR_ENDRX
)
{
runtime
=
chip
->
capture_substream
->
runtime
;
block_size
=
frames_to_bytes
(
runtime
,
runtime
->
period_size
);
chip
->
capture_period
++
;
if
(
chip
->
capture_period
==
runtime
->
periods
)
chip
->
capture_period
=
0
;
next_period
=
chip
->
capture_period
+
1
;
if
(
next_period
==
runtime
->
periods
)
next_period
=
0
;
offset
=
block_size
*
next_period
;
writel
(
runtime
->
dma_addr
+
offset
,
chip
->
regs
+
ATMEL_PDC_RNPR
);
writel
(
block_size
/
2
,
chip
->
regs
+
ATMEL_PDC_RNCR
);
snd_pcm_period_elapsed
(
chip
->
capture_substream
);
}
}
retval
=
IRQ_HANDLED
;
}
...
...
@@ -608,15 +729,50 @@ static irqreturn_t atmel_ac97c_interrupt(int irq, void *dev)
return
retval
;
}
static
struct
ac97_pcm
at91_ac97_pcm_defs
[]
__devinitdata
=
{
/* Playback */
{
.
exclusive
=
1
,
.
r
=
{
{
.
slots
=
((
1
<<
AC97_SLOT_PCM_LEFT
)
|
(
1
<<
AC97_SLOT_PCM_RIGHT
)),
}
},
},
/* PCM in */
{
.
stream
=
1
,
.
exclusive
=
1
,
.
r
=
{
{
.
slots
=
((
1
<<
AC97_SLOT_PCM_LEFT
)
|
(
1
<<
AC97_SLOT_PCM_RIGHT
)),
}
}
},
/* Mic in */
{
.
stream
=
1
,
.
exclusive
=
1
,
.
r
=
{
{
.
slots
=
(
1
<<
AC97_SLOT_MIC
),
}
}
},
};
static
int
__devinit
atmel_ac97c_pcm_new
(
struct
atmel_ac97c
*
chip
)
{
struct
snd_pcm
*
pcm
;
struct
snd_pcm_hardware
hw
=
atmel_ac97c_hw
;
int
capture
,
playback
,
retval
;
int
capture
,
playback
,
retval
,
err
;
capture
=
test_bit
(
DMA_RX_CHAN_PRESENT
,
&
chip
->
flags
);
playback
=
test_bit
(
DMA_TX_CHAN_PRESENT
,
&
chip
->
flags
);
if
(
!
cpu_is_at32ap7000
())
{
err
=
snd_ac97_pcm_assign
(
chip
->
ac97_bus
,
ARRAY_SIZE
(
at91_ac97_pcm_defs
),
at91_ac97_pcm_defs
);
if
(
err
)
return
err
;
}
retval
=
snd_pcm_new
(
chip
->
card
,
chip
->
card
->
shortname
,
chip
->
pdev
->
id
,
playback
,
capture
,
&
pcm
);
if
(
retval
)
...
...
@@ -775,7 +931,12 @@ static int __devinit atmel_ac97c_probe(struct platform_device *pdev)
return
-
ENXIO
;
}
pclk
=
clk_get
(
&
pdev
->
dev
,
"pclk"
);
if
(
cpu_is_at32ap7000
())
{
pclk
=
clk_get
(
&
pdev
->
dev
,
"pclk"
);
}
else
{
pclk
=
clk_get
(
&
pdev
->
dev
,
"ac97_clk"
);
}
if
(
IS_ERR
(
pclk
))
{
dev_dbg
(
&
pdev
->
dev
,
"no peripheral clock
\n
"
);
return
PTR_ERR
(
pclk
);
...
...
@@ -844,43 +1005,52 @@ static int __devinit atmel_ac97c_probe(struct platform_device *pdev)
goto
err_ac97_bus
;
}
if
(
pdata
->
rx_dws
.
dma_dev
)
{
struct
dw_dma_slave
*
dws
=
&
pdata
->
rx_dws
;
dma_cap_mask_t
mask
;
if
(
cpu_is_at32ap7000
())
{
if
(
pdata
->
rx_dws
.
dma_dev
)
{
struct
dw_dma_slave
*
dws
=
&
pdata
->
rx_dws
;
dma_cap_mask_t
mask
;
dws
->
rx_reg
=
regs
->
start
+
AC97C_CARHR
+
2
;
dws
->
rx_reg
=
regs
->
start
+
AC97C_CARHR
+
2
;
dma_cap_zero
(
mask
);
dma_cap_set
(
DMA_SLAVE
,
mask
);
dma_cap_zero
(
mask
);
dma_cap_set
(
DMA_SLAVE
,
mask
);
chip
->
dma
.
rx_chan
=
dma_request_channel
(
mask
,
filter
,
dws
);
chip
->
dma
.
rx_chan
=
dma_request_channel
(
mask
,
filter
,
dws
);
dev_info
(
&
chip
->
pdev
->
dev
,
"using %s for DMA RX
\n
"
,
dev_info
(
&
chip
->
pdev
->
dev
,
"using %s for DMA RX
\n
"
,
dev_name
(
&
chip
->
dma
.
rx_chan
->
dev
->
device
));
set_bit
(
DMA_RX_CHAN_PRESENT
,
&
chip
->
flags
);
}
set_bit
(
DMA_RX_CHAN_PRESENT
,
&
chip
->
flags
);
}
if
(
pdata
->
tx_dws
.
dma_dev
)
{
struct
dw_dma_slave
*
dws
=
&
pdata
->
tx_dws
;
dma_cap_mask_t
mask
;
if
(
pdata
->
tx_dws
.
dma_dev
)
{
struct
dw_dma_slave
*
dws
=
&
pdata
->
tx_dws
;
dma_cap_mask_t
mask
;
dws
->
tx_reg
=
regs
->
start
+
AC97C_CATHR
+
2
;
dws
->
tx_reg
=
regs
->
start
+
AC97C_CATHR
+
2
;
dma_cap_zero
(
mask
);
dma_cap_set
(
DMA_SLAVE
,
mask
);
dma_cap_zero
(
mask
);
dma_cap_set
(
DMA_SLAVE
,
mask
);
chip
->
dma
.
tx_chan
=
dma_request_channel
(
mask
,
filter
,
dws
);
chip
->
dma
.
tx_chan
=
dma_request_channel
(
mask
,
filter
,
dws
);
dev_info
(
&
chip
->
pdev
->
dev
,
"using %s for DMA TX
\n
"
,
dev_info
(
&
chip
->
pdev
->
dev
,
"using %s for DMA TX
\n
"
,
dev_name
(
&
chip
->
dma
.
tx_chan
->
dev
->
device
));
set_bit
(
DMA_TX_CHAN_PRESENT
,
&
chip
->
flags
);
}
set_bit
(
DMA_TX_CHAN_PRESENT
,
&
chip
->
flags
);
}
if
(
!
test_bit
(
DMA_RX_CHAN_PRESENT
,
&
chip
->
flags
)
&&
!
test_bit
(
DMA_TX_CHAN_PRESENT
,
&
chip
->
flags
))
{
dev_dbg
(
&
pdev
->
dev
,
"DMA not available
\n
"
);
retval
=
-
ENODEV
;
goto
err_dma
;
if
(
!
test_bit
(
DMA_RX_CHAN_PRESENT
,
&
chip
->
flags
)
&&
!
test_bit
(
DMA_TX_CHAN_PRESENT
,
&
chip
->
flags
))
{
dev_dbg
(
&
pdev
->
dev
,
"DMA not available
\n
"
);
retval
=
-
ENODEV
;
goto
err_dma
;
}
}
else
{
/* Just pretend that we have DMA channel(for at91 i is actually
* the PDC) */
set_bit
(
DMA_RX_CHAN_PRESENT
,
&
chip
->
flags
);
set_bit
(
DMA_TX_CHAN_PRESENT
,
&
chip
->
flags
);
}
retval
=
atmel_ac97c_pcm_new
(
chip
);
...
...
@@ -897,20 +1067,22 @@ static int __devinit atmel_ac97c_probe(struct platform_device *pdev)
platform_set_drvdata
(
pdev
,
card
);
dev_info
(
&
pdev
->
dev
,
"Atmel AC97 controller at 0x%p
\n
"
,
chip
->
regs
);
dev_info
(
&
pdev
->
dev
,
"Atmel AC97 controller at 0x%p
, irq = %d
\n
"
,
chip
->
regs
,
irq
);
return
0
;
err_dma:
if
(
test_bit
(
DMA_RX_CHAN_PRESENT
,
&
chip
->
flags
))
dma_release_channel
(
chip
->
dma
.
rx_chan
);
if
(
test_bit
(
DMA_TX_CHAN_PRESENT
,
&
chip
->
flags
))
dma_release_channel
(
chip
->
dma
.
tx_chan
);
clear_bit
(
DMA_RX_CHAN_PRESENT
,
&
chip
->
flags
);
clear_bit
(
DMA_TX_CHAN_PRESENT
,
&
chip
->
flags
);
chip
->
dma
.
rx_chan
=
NULL
;
chip
->
dma
.
tx_chan
=
NULL
;
if
(
cpu_is_at32ap7000
())
{
if
(
test_bit
(
DMA_RX_CHAN_PRESENT
,
&
chip
->
flags
))
dma_release_channel
(
chip
->
dma
.
rx_chan
);
if
(
test_bit
(
DMA_TX_CHAN_PRESENT
,
&
chip
->
flags
))
dma_release_channel
(
chip
->
dma
.
tx_chan
);
clear_bit
(
DMA_RX_CHAN_PRESENT
,
&
chip
->
flags
);
clear_bit
(
DMA_TX_CHAN_PRESENT
,
&
chip
->
flags
);
chip
->
dma
.
rx_chan
=
NULL
;
chip
->
dma
.
tx_chan
=
NULL
;
}
err_ac97_bus:
snd_card_set_dev
(
card
,
NULL
);
...
...
@@ -934,10 +1106,12 @@ static int atmel_ac97c_suspend(struct platform_device *pdev, pm_message_t msg)
struct
snd_card
*
card
=
platform_get_drvdata
(
pdev
);
struct
atmel_ac97c
*
chip
=
card
->
private_data
;
if
(
test_bit
(
DMA_RX_READY
,
&
chip
->
flags
))
dw_dma_cyclic_stop
(
chip
->
dma
.
rx_chan
);
if
(
test_bit
(
DMA_TX_READY
,
&
chip
->
flags
))
dw_dma_cyclic_stop
(
chip
->
dma
.
tx_chan
);
if
(
cpu_is_at32ap7000
())
{
if
(
test_bit
(
DMA_RX_READY
,
&
chip
->
flags
))
dw_dma_cyclic_stop
(
chip
->
dma
.
rx_chan
);
if
(
test_bit
(
DMA_TX_READY
,
&
chip
->
flags
))
dw_dma_cyclic_stop
(
chip
->
dma
.
tx_chan
);
}
clk_disable
(
chip
->
pclk
);
return
0
;
...
...
@@ -949,11 +1123,12 @@ static int atmel_ac97c_resume(struct platform_device *pdev)
struct
atmel_ac97c
*
chip
=
card
->
private_data
;
clk_enable
(
chip
->
pclk
);
if
(
test_bit
(
DMA_RX_READY
,
&
chip
->
flags
))
dw_dma_cyclic_start
(
chip
->
dma
.
rx_chan
);
if
(
test_bit
(
DMA_TX_READY
,
&
chip
->
flags
))
dw_dma_cyclic_start
(
chip
->
dma
.
tx_chan
);
if
(
cpu_is_at32ap7000
())
{
if
(
test_bit
(
DMA_RX_READY
,
&
chip
->
flags
))
dw_dma_cyclic_start
(
chip
->
dma
.
rx_chan
);
if
(
test_bit
(
DMA_TX_READY
,
&
chip
->
flags
))
dw_dma_cyclic_start
(
chip
->
dma
.
tx_chan
);
}
return
0
;
}
#else
...
...
@@ -978,14 +1153,16 @@ static int __devexit atmel_ac97c_remove(struct platform_device *pdev)
iounmap
(
chip
->
regs
);
free_irq
(
chip
->
irq
,
chip
);
if
(
test_bit
(
DMA_RX_CHAN_PRESENT
,
&
chip
->
flags
))
dma_release_channel
(
chip
->
dma
.
rx_chan
);
if
(
test_bit
(
DMA_TX_CHAN_PRESENT
,
&
chip
->
flags
))
dma_release_channel
(
chip
->
dma
.
tx_chan
);
clear_bit
(
DMA_RX_CHAN_PRESENT
,
&
chip
->
flags
);
clear_bit
(
DMA_TX_CHAN_PRESENT
,
&
chip
->
flags
);
chip
->
dma
.
rx_chan
=
NULL
;
chip
->
dma
.
tx_chan
=
NULL
;
if
(
cpu_is_at32ap7000
())
{
if
(
test_bit
(
DMA_RX_CHAN_PRESENT
,
&
chip
->
flags
))
dma_release_channel
(
chip
->
dma
.
rx_chan
);
if
(
test_bit
(
DMA_TX_CHAN_PRESENT
,
&
chip
->
flags
))
dma_release_channel
(
chip
->
dma
.
tx_chan
);
clear_bit
(
DMA_RX_CHAN_PRESENT
,
&
chip
->
flags
);
clear_bit
(
DMA_TX_CHAN_PRESENT
,
&
chip
->
flags
);
chip
->
dma
.
rx_chan
=
NULL
;
chip
->
dma
.
tx_chan
=
NULL
;
}
snd_card_set_dev
(
card
,
NULL
);
snd_card_free
(
card
);
...
...
sound/core/control.c
View file @
3374cd1a
...
...
@@ -50,6 +50,10 @@ static int snd_ctl_open(struct inode *inode, struct file *file)
struct
snd_ctl_file
*
ctl
;
int
err
;
err
=
nonseekable_open
(
inode
,
file
);
if
(
err
<
0
)
return
err
;
card
=
snd_lookup_minor_data
(
iminor
(
inode
),
SNDRV_DEVICE_TYPE_CONTROL
);
if
(
!
card
)
{
err
=
-
ENODEV
;
...
...
@@ -1388,6 +1392,7 @@ static const struct file_operations snd_ctl_f_ops =
.
read
=
snd_ctl_read
,
.
open
=
snd_ctl_open
,
.
release
=
snd_ctl_release
,
.
llseek
=
no_llseek
,
.
poll
=
snd_ctl_poll
,
.
unlocked_ioctl
=
snd_ctl_ioctl
,
.
compat_ioctl
=
snd_ctl_ioctl_compat
,
...
...
sound/core/info.c
View file @
3374cd1a
...
...
@@ -164,40 +164,44 @@ static loff_t snd_info_entry_llseek(struct file *file, loff_t offset, int orig)
{
struct
snd_info_private_data
*
data
;
struct
snd_info_entry
*
entry
;
loff_t
ret
;
loff_t
ret
=
-
EINVAL
,
size
;
data
=
file
->
private_data
;
entry
=
data
->
entry
;
lock_kernel
();
switch
(
entry
->
content
)
{
case
SNDRV_INFO_CONTENT_TEXT
:
switch
(
orig
)
{
case
SEEK_SET
:
file
->
f_pos
=
offset
;
ret
=
file
->
f_pos
;
goto
out
;
case
SEEK_CUR
:
file
->
f_pos
+=
offset
;
ret
=
file
->
f_pos
;
goto
out
;
case
SEEK_END
:
default:
ret
=
-
EINVAL
;
goto
out
;
}
mutex_lock
(
&
entry
->
access
);
if
(
entry
->
content
==
SNDRV_INFO_CONTENT_DATA
&&
entry
->
c
.
ops
->
llseek
)
{
offset
=
entry
->
c
.
ops
->
llseek
(
entry
,
data
->
file_private_data
,
file
,
offset
,
orig
);
goto
out
;
}
if
(
entry
->
content
==
SNDRV_INFO_CONTENT_DATA
)
size
=
entry
->
size
;
else
size
=
0
;
switch
(
orig
)
{
case
SEEK_SET
:
break
;
case
S
NDRV_INFO_CONTENT_DATA
:
if
(
entry
->
c
.
ops
->
llseek
)
{
ret
=
entry
->
c
.
ops
->
llseek
(
entry
,
data
->
file_private_data
,
file
,
offset
,
orig
);
case
S
EEK_CUR
:
offset
+=
file
->
f_pos
;
break
;
case
SEEK_END
:
if
(
!
size
)
goto
out
;
}
offset
+=
size
;
break
;
}
ret
=
-
ENXIO
;
out:
unlock_kernel
();
default:
goto
out
;
}
if
(
offset
<
0
)
goto
out
;
if
(
size
&&
offset
>
size
)
offset
=
size
;
file
->
f_pos
=
offset
;
ret
=
offset
;
out:
mutex_unlock
(
&
entry
->
access
);
return
ret
;
}
...
...
@@ -232,10 +236,15 @@ static ssize_t snd_info_entry_read(struct file *file, char __user *buffer,
return
-
EFAULT
;
break
;
case
SNDRV_INFO_CONTENT_DATA
:
if
(
entry
->
c
.
ops
->
read
)
if
(
pos
>=
entry
->
size
)
return
0
;
if
(
entry
->
c
.
ops
->
read
)
{
size
=
entry
->
size
-
pos
;
size
=
min
(
count
,
size
);
size
=
entry
->
c
.
ops
->
read
(
entry
,
data
->
file_private_data
,
file
,
buffer
,
count
,
pos
);
file
,
buffer
,
size
,
pos
);
}
break
;
}
if
((
ssize_t
)
size
>
0
)
...
...
@@ -282,10 +291,13 @@ static ssize_t snd_info_entry_write(struct file *file, const char __user *buffer
size
=
count
;
break
;
case
SNDRV_INFO_CONTENT_DATA
:
if
(
entry
->
c
.
ops
->
write
)
if
(
entry
->
c
.
ops
->
write
&&
count
>
0
)
{
size_t
maxsize
=
entry
->
size
-
pos
;
count
=
min
(
count
,
maxsize
);
size
=
entry
->
c
.
ops
->
write
(
entry
,
data
->
file_private_data
,
file
,
buffer
,
count
,
pos
);
}
break
;
}
if
((
ssize_t
)
size
>
0
)
...
...
sound/core/oss/mixer_oss.c
View file @
3374cd1a
...
...
@@ -43,6 +43,10 @@ static int snd_mixer_oss_open(struct inode *inode, struct file *file)
struct
snd_mixer_oss_file
*
fmixer
;
int
err
;
err
=
nonseekable_open
(
inode
,
file
);
if
(
err
<
0
)
return
err
;
card
=
snd_lookup_oss_minor_data
(
iminor
(
inode
),
SNDRV_OSS_DEVICE_TYPE_MIXER
);
if
(
card
==
NULL
)
...
...
@@ -397,6 +401,7 @@ static const struct file_operations snd_mixer_oss_f_ops =
.
owner
=
THIS_MODULE
,
.
open
=
snd_mixer_oss_open
,
.
release
=
snd_mixer_oss_release
,
.
llseek
=
no_llseek
,
.
unlocked_ioctl
=
snd_mixer_oss_ioctl
,
.
compat_ioctl
=
snd_mixer_oss_ioctl_compat
,
};
...
...
sound/core/oss/pcm_oss.c
View file @
3374cd1a
...
...
@@ -2379,6 +2379,10 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file)
int
nonblock
;
wait_queue_t
wait
;
err
=
nonseekable_open
(
inode
,
file
);
if
(
err
<
0
)
return
err
;
pcm
=
snd_lookup_oss_minor_data
(
iminor
(
inode
),
SNDRV_OSS_DEVICE_TYPE_PCM
);
if
(
pcm
==
NULL
)
{
...
...
@@ -2977,6 +2981,7 @@ static const struct file_operations snd_pcm_oss_f_reg =
.
write
=
snd_pcm_oss_write
,
.
open
=
snd_pcm_oss_open
,
.
release
=
snd_pcm_oss_release
,
.
llseek
=
no_llseek
,
.
poll
=
snd_pcm_oss_poll
,
.
unlocked_ioctl
=
snd_pcm_oss_ioctl
,
.
compat_ioctl
=
snd_pcm_oss_ioctl_compat
,
...
...
sound/core/pcm_native.c
View file @
3374cd1a
...
...
@@ -2110,7 +2110,9 @@ static int snd_pcm_open_file(struct file *file,
static
int
snd_pcm_playback_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
struct
snd_pcm
*
pcm
;
int
err
=
nonseekable_open
(
inode
,
file
);
if
(
err
<
0
)
return
err
;
pcm
=
snd_lookup_minor_data
(
iminor
(
inode
),
SNDRV_DEVICE_TYPE_PCM_PLAYBACK
);
return
snd_pcm_open
(
file
,
pcm
,
SNDRV_PCM_STREAM_PLAYBACK
);
...
...
@@ -2119,7 +2121,9 @@ static int snd_pcm_playback_open(struct inode *inode, struct file *file)
static
int
snd_pcm_capture_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
struct
snd_pcm
*
pcm
;
int
err
=
nonseekable_open
(
inode
,
file
);
if
(
err
<
0
)
return
err
;
pcm
=
snd_lookup_minor_data
(
iminor
(
inode
),
SNDRV_DEVICE_TYPE_PCM_CAPTURE
);
return
snd_pcm_open
(
file
,
pcm
,
SNDRV_PCM_STREAM_CAPTURE
);
...
...
@@ -3310,18 +3314,13 @@ static int snd_pcm_fasync(int fd, struct file * file, int on)
struct
snd_pcm_file
*
pcm_file
;
struct
snd_pcm_substream
*
substream
;
struct
snd_pcm_runtime
*
runtime
;
int
err
=
-
ENXIO
;
lock_kernel
();
pcm_file
=
file
->
private_data
;
substream
=
pcm_file
->
substream
;
if
(
PCM_RUNTIME_CHECK
(
substream
))
goto
out
;
return
-
ENXIO
;
runtime
=
substream
->
runtime
;
err
=
fasync_helper
(
fd
,
file
,
on
,
&
runtime
->
fasync
);
out:
unlock_kernel
();
return
err
;
return
fasync_helper
(
fd
,
file
,
on
,
&
runtime
->
fasync
);
}
/*
...
...
@@ -3462,6 +3461,7 @@ const struct file_operations snd_pcm_f_ops[2] = {
.
aio_write
=
snd_pcm_aio_write
,
.
open
=
snd_pcm_playback_open
,
.
release
=
snd_pcm_release
,
.
llseek
=
no_llseek
,
.
poll
=
snd_pcm_playback_poll
,
.
unlocked_ioctl
=
snd_pcm_playback_ioctl
,
.
compat_ioctl
=
snd_pcm_ioctl_compat
,
...
...
@@ -3475,6 +3475,7 @@ const struct file_operations snd_pcm_f_ops[2] = {
.
aio_read
=
snd_pcm_aio_read
,
.
open
=
snd_pcm_capture_open
,
.
release
=
snd_pcm_release
,
.
llseek
=
no_llseek
,
.
poll
=
snd_pcm_capture_poll
,
.
unlocked_ioctl
=
snd_pcm_capture_ioctl
,
.
compat_ioctl
=
snd_pcm_ioctl_compat
,
...
...
sound/core/rawmidi.c
View file @
3374cd1a
...
...
@@ -376,6 +376,10 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
if
((
file
->
f_flags
&
O_APPEND
)
&&
!
(
file
->
f_flags
&
O_NONBLOCK
))
return
-
EINVAL
;
/* invalid combination */
err
=
nonseekable_open
(
inode
,
file
);
if
(
err
<
0
)
return
err
;
if
(
maj
==
snd_major
)
{
rmidi
=
snd_lookup_minor_data
(
iminor
(
inode
),
SNDRV_DEVICE_TYPE_RAWMIDI
);
...
...
@@ -1391,6 +1395,7 @@ static const struct file_operations snd_rawmidi_f_ops =
.
write
=
snd_rawmidi_write
,
.
open
=
snd_rawmidi_open
,
.
release
=
snd_rawmidi_release
,
.
llseek
=
no_llseek
,
.
poll
=
snd_rawmidi_poll
,
.
unlocked_ioctl
=
snd_rawmidi_ioctl
,
.
compat_ioctl
=
snd_rawmidi_ioctl_compat
,
...
...
sound/core/seq/seq_clientmgr.c
View file @
3374cd1a
...
...
@@ -318,6 +318,11 @@ static int snd_seq_open(struct inode *inode, struct file *file)
int
c
,
mode
;
/* client id */
struct
snd_seq_client
*
client
;
struct
snd_seq_user_client
*
user
;
int
err
;
err
=
nonseekable_open
(
inode
,
file
);
if
(
err
<
0
)
return
err
;
if
(
mutex_lock_interruptible
(
&
register_mutex
))
return
-
ERESTARTSYS
;
...
...
@@ -2550,6 +2555,7 @@ static const struct file_operations snd_seq_f_ops =
.
write
=
snd_seq_write
,
.
open
=
snd_seq_open
,
.
release
=
snd_seq_release
,
.
llseek
=
no_llseek
,
.
poll
=
snd_seq_poll
,
.
unlocked_ioctl
=
snd_seq_ioctl
,
.
compat_ioctl
=
snd_seq_ioctl_compat
,
...
...
sound/core/sound.c
View file @
3374cd1a
...
...
@@ -120,7 +120,29 @@ void *snd_lookup_minor_data(unsigned int minor, int type)
EXPORT_SYMBOL
(
snd_lookup_minor_data
);
static
int
__snd_open
(
struct
inode
*
inode
,
struct
file
*
file
)
#ifdef CONFIG_MODULES
static
struct
snd_minor
*
autoload_device
(
unsigned
int
minor
)
{
int
dev
;
mutex_unlock
(
&
sound_mutex
);
/* release lock temporarily */
dev
=
SNDRV_MINOR_DEVICE
(
minor
);
if
(
dev
==
SNDRV_MINOR_CONTROL
)
{
/* /dev/aloadC? */
int
card
=
SNDRV_MINOR_CARD
(
minor
);
if
(
snd_cards
[
card
]
==
NULL
)
snd_request_card
(
card
);
}
else
if
(
dev
==
SNDRV_MINOR_GLOBAL
)
{
/* /dev/aloadSEQ */
snd_request_other
(
minor
);
}
mutex_lock
(
&
sound_mutex
);
/* reacuire lock */
return
snd_minors
[
minor
];
}
#else
/* !CONFIG_MODULES */
#define autoload_device(minor) NULL
#endif
/* CONFIG_MODULES */
static
int
snd_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
unsigned
int
minor
=
iminor
(
inode
);
struct
snd_minor
*
mptr
=
NULL
;
...
...
@@ -129,55 +151,36 @@ static int __snd_open(struct inode *inode, struct file *file)
if
(
minor
>=
ARRAY_SIZE
(
snd_minors
))
return
-
ENODEV
;
mutex_lock
(
&
sound_mutex
);
mptr
=
snd_minors
[
minor
];
if
(
mptr
==
NULL
)
{
#ifdef CONFIG_MODULES
int
dev
=
SNDRV_MINOR_DEVICE
(
minor
);
if
(
dev
==
SNDRV_MINOR_CONTROL
)
{
/* /dev/aloadC? */
int
card
=
SNDRV_MINOR_CARD
(
minor
);
if
(
snd_cards
[
card
]
==
NULL
)
snd_request_card
(
card
);
}
else
if
(
dev
==
SNDRV_MINOR_GLOBAL
)
{
/* /dev/aloadSEQ */
snd_request_other
(
minor
);
}
#ifndef CONFIG_SND_DYNAMIC_MINORS
/* /dev/snd/{controlC?,seq} */
mptr
=
snd_minors
[
minor
];
if
(
mptr
==
NULL
)
#endif
#endif
mptr
=
autoload_device
(
minor
);
if
(
!
mptr
)
{
mutex_unlock
(
&
sound_mutex
);
return
-
ENODEV
;
}
}
old_fops
=
file
->
f_op
;
file
->
f_op
=
fops_get
(
mptr
->
f_ops
);
if
(
file
->
f_op
==
NULL
)
{
file
->
f_op
=
old_fops
;
return
-
ENODEV
;
err
=
-
ENODEV
;
}
if
(
file
->
f_op
->
open
)
mutex_unlock
(
&
sound_mutex
);
if
(
err
<
0
)
return
err
;
if
(
file
->
f_op
->
open
)
{
err
=
file
->
f_op
->
open
(
inode
,
file
);
if
(
err
)
{
fops_put
(
file
->
f_op
);
file
->
f_op
=
fops_get
(
old_fops
);
if
(
err
)
{
fops_put
(
file
->
f_op
);
file
->
f_op
=
fops_get
(
old_fops
);
}
}
fops_put
(
old_fops
);
return
err
;
}
/* BKL pushdown: nasty #ifdef avoidance wrapper */
static
int
snd_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
int
ret
;
lock_kernel
();
ret
=
__snd_open
(
inode
,
file
);
unlock_kernel
();
return
ret
;
}
static
const
struct
file_operations
snd_fops
=
{
.
owner
=
THIS_MODULE
,
...
...
sound/core/timer.c
View file @
3374cd1a
...
...
@@ -1238,6 +1238,11 @@ static void snd_timer_user_tinterrupt(struct snd_timer_instance *timeri,
static
int
snd_timer_user_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
struct
snd_timer_user
*
tu
;
int
err
;
err
=
nonseekable_open
(
inode
,
file
);
if
(
err
<
0
)
return
err
;
tu
=
kzalloc
(
sizeof
(
*
tu
),
GFP_KERNEL
);
if
(
tu
==
NULL
)
...
...
@@ -1922,6 +1927,7 @@ static const struct file_operations snd_timer_f_ops =
.
read
=
snd_timer_user_read
,
.
open
=
snd_timer_user_open
,
.
release
=
snd_timer_user_release
,
.
llseek
=
no_llseek
,
.
poll
=
snd_timer_user_poll
,
.
unlocked_ioctl
=
snd_timer_user_ioctl
,
.
compat_ioctl
=
snd_timer_user_ioctl_compat
,
...
...
sound/drivers/opl4/opl4_proc.c
View file @
3374cd1a
...
...
@@ -49,77 +49,45 @@ static int snd_opl4_mem_proc_release(struct snd_info_entry *entry,
return
0
;
}
static
long
snd_opl4_mem_proc_read
(
struct
snd_info_entry
*
entry
,
void
*
file_private_data
,
struct
file
*
file
,
char
__user
*
_buf
,
unsigned
long
count
,
unsigned
long
pos
)
static
ssize_t
snd_opl4_mem_proc_read
(
struct
snd_info_entry
*
entry
,
void
*
file_private_data
,
struct
file
*
file
,
char
__user
*
_buf
,
size_t
count
,
loff_t
pos
)
{
struct
snd_opl4
*
opl4
=
entry
->
private_data
;
long
size
;
char
*
buf
;
size
=
count
;
if
(
pos
+
size
>
entry
->
size
)
size
=
entry
->
size
-
pos
;
if
(
size
>
0
)
{
buf
=
vmalloc
(
size
);
if
(
!
buf
)
return
-
ENOMEM
;
snd_opl4_read_memory
(
opl4
,
buf
,
pos
,
size
);
if
(
copy_to_user
(
_buf
,
buf
,
size
))
{
vfree
(
buf
);
return
-
EFAULT
;
}
buf
=
vmalloc
(
count
);
if
(
!
buf
)
return
-
ENOMEM
;
snd_opl4_read_memory
(
opl4
,
buf
,
pos
,
count
);
if
(
copy_to_user
(
_buf
,
buf
,
count
))
{
vfree
(
buf
);
return
size
;
return
-
EFAULT
;
}
return
0
;
vfree
(
buf
);
return
count
;
}
static
long
snd_opl4_mem_proc_write
(
struct
snd_info_entry
*
entry
,
void
*
file_private_data
,
struct
file
*
file
,
const
char
__user
*
_buf
,
unsigned
long
count
,
unsigned
long
pos
)
static
ssize_t
snd_opl4_mem_proc_write
(
struct
snd_info_entry
*
entry
,
void
*
file_private_data
,
struct
file
*
file
,
const
char
__user
*
_buf
,
size_t
count
,
loff_t
pos
)
{
struct
snd_opl4
*
opl4
=
entry
->
private_data
;
long
size
;
char
*
buf
;
size
=
count
;
if
(
pos
+
size
>
entry
->
size
)
size
=
entry
->
size
-
pos
;
if
(
size
>
0
)
{
buf
=
vmalloc
(
size
);
if
(
!
buf
)
return
-
ENOMEM
;
if
(
copy_from_user
(
buf
,
_buf
,
size
))
{
vfree
(
buf
);
return
-
EFAULT
;
}
snd_opl4_write_memory
(
opl4
,
buf
,
pos
,
size
);
buf
=
vmalloc
(
count
);
if
(
!
buf
)
return
-
ENOMEM
;
if
(
copy_from_user
(
buf
,
_buf
,
count
))
{
vfree
(
buf
);
return
size
;
}
return
0
;
}
static
long
long
snd_opl4_mem_proc_llseek
(
struct
snd_info_entry
*
entry
,
void
*
file_private_data
,
struct
file
*
file
,
long
long
offset
,
int
orig
)
{
switch
(
orig
)
{
case
SEEK_SET
:
file
->
f_pos
=
offset
;
break
;
case
SEEK_CUR
:
file
->
f_pos
+=
offset
;
break
;
case
SEEK_END
:
/* offset is negative */
file
->
f_pos
=
entry
->
size
+
offset
;
break
;
default:
return
-
EINVAL
;
return
-
EFAULT
;
}
if
(
file
->
f_pos
>
entry
->
size
)
file
->
f_pos
=
entry
->
size
;
return
file
->
f_pos
;
snd_opl4_write_memory
(
opl4
,
buf
,
pos
,
count
);
vfree
(
buf
)
;
return
count
;
}
static
struct
snd_info_entry_ops
snd_opl4_mem_proc_ops
=
{
...
...
@@ -127,7 +95,6 @@ static struct snd_info_entry_ops snd_opl4_mem_proc_ops = {
.
release
=
snd_opl4_mem_proc_release
,
.
read
=
snd_opl4_mem_proc_read
,
.
write
=
snd_opl4_mem_proc_write
,
.
llseek
=
snd_opl4_mem_proc_llseek
,
};
int
snd_opl4_create_proc
(
struct
snd_opl4
*
opl4
)
...
...
sound/isa/gus/gus_mem_proc.c
View file @
3374cd1a
...
...
@@ -31,52 +31,21 @@ struct gus_proc_private {
struct
snd_gus_card
*
gus
;
};
static
long
snd_gf1_mem_proc_dump
(
struct
snd_info_entry
*
entry
,
void
*
file_private_data
,
struct
file
*
file
,
char
__user
*
buf
,
unsigned
long
count
,
unsigned
long
pos
)
static
ssize_t
snd_gf1_mem_proc_dump
(
struct
snd_info_entry
*
entry
,
void
*
file_private_data
,
struct
file
*
file
,
char
__user
*
buf
,
size_t
count
,
loff_t
pos
)
{
long
size
;
struct
gus_proc_private
*
priv
=
entry
->
private_data
;
struct
snd_gus_card
*
gus
=
priv
->
gus
;
int
err
;
size
=
count
;
if
(
pos
+
size
>
priv
->
size
)
size
=
(
long
)
priv
->
size
-
pos
;
if
(
size
>
0
)
{
if
((
err
=
snd_gus_dram_read
(
gus
,
buf
,
pos
,
size
,
priv
->
rom
))
<
0
)
return
err
;
return
size
;
}
return
0
;
err
=
snd_gus_dram_read
(
gus
,
buf
,
pos
,
count
,
priv
->
rom
);
if
(
err
<
0
)
return
err
;
return
count
;
}
static
long
long
snd_gf1_mem_proc_llseek
(
struct
snd_info_entry
*
entry
,
void
*
private_file_data
,
struct
file
*
file
,
long
long
offset
,
int
orig
)
{
struct
gus_proc_private
*
priv
=
entry
->
private_data
;
switch
(
orig
)
{
case
SEEK_SET
:
file
->
f_pos
=
offset
;
break
;
case
SEEK_CUR
:
file
->
f_pos
+=
offset
;
break
;
case
SEEK_END
:
/* offset is negative */
file
->
f_pos
=
priv
->
size
+
offset
;
break
;
default:
return
-
EINVAL
;
}
if
(
file
->
f_pos
>
priv
->
size
)
file
->
f_pos
=
priv
->
size
;
return
file
->
f_pos
;
}
static
void
snd_gf1_mem_proc_free
(
struct
snd_info_entry
*
entry
)
{
struct
gus_proc_private
*
priv
=
entry
->
private_data
;
...
...
@@ -85,7 +54,6 @@ static void snd_gf1_mem_proc_free(struct snd_info_entry *entry)
static
struct
snd_info_entry_ops
snd_gf1_mem_proc_ops
=
{
.
read
=
snd_gf1_mem_proc_dump
,
.
llseek
=
snd_gf1_mem_proc_llseek
,
};
int
snd_gf1_mem_proc_init
(
struct
snd_gus_card
*
gus
)
...
...
sound/pci/cs4281.c
View file @
3374cd1a
...
...
@@ -1139,40 +1139,28 @@ static void snd_cs4281_proc_read(struct snd_info_entry *entry,
snd_iprintf
(
buffer
,
"Spurious end IRQs : %u
\n
"
,
chip
->
spurious_dtc_irq
);
}
static
long
snd_cs4281_BA0_read
(
struct
snd_info_entry
*
entry
,
void
*
file_private_data
,
struct
file
*
file
,
char
__user
*
buf
,
unsigned
long
count
,
unsigned
long
pos
)
static
ssize_t
snd_cs4281_BA0_read
(
struct
snd_info_entry
*
entry
,
void
*
file_private_data
,
struct
file
*
file
,
char
__user
*
buf
,
size_t
count
,
loff_t
pos
)
{
long
size
;
struct
cs4281
*
chip
=
entry
->
private_data
;
size
=
count
;
if
(
pos
+
size
>
CS4281_BA0_SIZE
)
size
=
(
long
)
CS4281_BA0_SIZE
-
pos
;
if
(
size
>
0
)
{
if
(
copy_to_user_fromio
(
buf
,
chip
->
ba0
+
pos
,
size
))
return
-
EFAULT
;
}
return
size
;
if
(
copy_to_user_fromio
(
buf
,
chip
->
ba0
+
pos
,
count
))
return
-
EFAULT
;
return
count
;
}
static
long
snd_cs4281_BA1_read
(
struct
snd_info_entry
*
entry
,
void
*
file_private_data
,
struct
file
*
file
,
char
__user
*
buf
,
unsigned
long
count
,
unsigned
long
pos
)
static
ssize_t
snd_cs4281_BA1_read
(
struct
snd_info_entry
*
entry
,
void
*
file_private_data
,
struct
file
*
file
,
char
__user
*
buf
,
size_t
count
,
loff_t
pos
)
{
long
size
;
struct
cs4281
*
chip
=
entry
->
private_data
;
size
=
count
;
if
(
pos
+
size
>
CS4281_BA1_SIZE
)
size
=
(
long
)
CS4281_BA1_SIZE
-
pos
;
if
(
size
>
0
)
{
if
(
copy_to_user_fromio
(
buf
,
chip
->
ba1
+
pos
,
size
))
return
-
EFAULT
;
}
return
size
;
if
(
copy_to_user_fromio
(
buf
,
chip
->
ba1
+
pos
,
count
))
return
-
EFAULT
;
return
count
;
}
static
struct
snd_info_entry_ops
snd_cs4281_proc_ops_BA0
=
{
...
...
sound/pci/cs46xx/cs46xx_lib.c
View file @
3374cd1a
...
...
@@ -2657,21 +2657,16 @@ static inline void snd_cs46xx_remove_gameport(struct snd_cs46xx *chip) { }
* proc interface
*/
static
long
snd_cs46xx_io_read
(
struct
snd_info_entry
*
entry
,
void
*
file_private_data
,
struct
file
*
file
,
char
__user
*
buf
,
unsigned
long
count
,
unsigned
long
pos
)
static
ssize_t
snd_cs46xx_io_read
(
struct
snd_info_entry
*
entry
,
void
*
file_private_data
,
struct
file
*
file
,
char
__user
*
buf
,
size_t
count
,
loff_t
pos
)
{
long
size
;
struct
snd_cs46xx_region
*
region
=
entry
->
private_data
;
size
=
count
;
if
(
pos
+
(
size_t
)
size
>
region
->
size
)
size
=
region
->
size
-
pos
;
if
(
size
>
0
)
{
if
(
copy_to_user_fromio
(
buf
,
region
->
remap_addr
+
pos
,
size
))
return
-
EFAULT
;
}
return
size
;
if
(
copy_to_user_fromio
(
buf
,
region
->
remap_addr
+
pos
,
count
))
return
-
EFAULT
;
return
count
;
}
static
struct
snd_info_entry_ops
snd_cs46xx_proc_io_ops
=
{
...
...
sound/pci/emu10k1/emuproc.c
View file @
3374cd1a
...
...
@@ -341,15 +341,17 @@ static void snd_emu10k1_proc_acode_read(struct snd_info_entry *entry,
#define TOTAL_SIZE_CODE (0x200*8)
#define A_TOTAL_SIZE_CODE (0x400*8)
static
long
snd_emu10k1_fx8010_read
(
struct
snd_info_entry
*
entry
,
void
*
file_private_data
,
struct
file
*
file
,
char
__user
*
buf
,
unsigned
long
count
,
unsigned
long
pos
)
static
ssize_t
snd_emu10k1_fx8010_read
(
struct
snd_info_entry
*
entry
,
void
*
file_private_data
,
struct
file
*
file
,
char
__user
*
buf
,
size_t
count
,
loff_t
pos
)
{
long
size
;
struct
snd_emu10k1
*
emu
=
entry
->
private_data
;
unsigned
int
offset
;
int
tram_addr
=
0
;
unsigned
int
*
tmp
;
long
res
;
unsigned
int
idx
;
if
(
!
strcmp
(
entry
->
name
,
"fx8010_tram_addr"
))
{
offset
=
TANKMEMADDRREGBASE
;
...
...
@@ -361,30 +363,25 @@ static long snd_emu10k1_fx8010_read(struct snd_info_entry *entry,
}
else
{
offset
=
emu
->
audigy
?
A_FXGPREGBASE
:
FXGPREGBASE
;
}
size
=
count
;
if
(
pos
+
size
>
entry
->
size
)
size
=
(
long
)
entry
->
size
-
pos
;
if
(
size
>
0
)
{
unsigned
int
*
tmp
;
long
res
;
unsigned
int
idx
;
if
((
tmp
=
kmalloc
(
size
+
8
,
GFP_KERNEL
))
==
NULL
)
return
-
ENOMEM
;
for
(
idx
=
0
;
idx
<
((
pos
&
3
)
+
size
+
3
)
>>
2
;
idx
++
)
if
(
tram_addr
&&
emu
->
audigy
)
{
tmp
[
idx
]
=
snd_emu10k1_ptr_read
(
emu
,
offset
+
idx
+
(
pos
>>
2
),
0
)
>>
11
;
tmp
[
idx
]
|=
snd_emu10k1_ptr_read
(
emu
,
0x100
+
idx
+
(
pos
>>
2
),
0
)
<<
20
;
}
else
tmp
[
idx
]
=
snd_emu10k1_ptr_read
(
emu
,
offset
+
idx
+
(
pos
>>
2
),
0
);
if
(
copy_to_user
(
buf
,
((
char
*
)
tmp
)
+
(
pos
&
3
),
size
))
res
=
-
EFAULT
;
else
{
res
=
size
;
tmp
=
kmalloc
(
count
+
8
,
GFP_KERNEL
);
if
(
!
tmp
)
return
-
ENOMEM
;
for
(
idx
=
0
;
idx
<
((
pos
&
3
)
+
count
+
3
)
>>
2
;
idx
++
)
{
unsigned
int
val
;
val
=
snd_emu10k1_ptr_read
(
emu
,
offset
+
idx
+
(
pos
>>
2
),
0
);
if
(
tram_addr
&&
emu
->
audigy
)
{
val
>>=
11
;
val
|=
snd_emu10k1_ptr_read
(
emu
,
0x100
+
idx
+
(
pos
>>
2
),
0
)
<<
20
;
}
kfree
(
tmp
);
return
res
;
tmp
[
idx
]
=
val
;
}
return
0
;
if
(
copy_to_user
(
buf
,
((
char
*
)
tmp
)
+
(
pos
&
3
),
count
))
res
=
-
EFAULT
;
else
res
=
count
;
kfree
(
tmp
);
return
res
;
}
static
void
snd_emu10k1_proc_voices_read
(
struct
snd_info_entry
*
entry
,
...
...
sound/pci/ice1712/aureon.c
View file @
3374cd1a
...
...
@@ -1956,11 +1956,10 @@ static int __devinit aureon_add_controls(struct snd_ice1712 *ice)
return
0
;
}
/*
*
initialize
the chip
*
reset
the chip
*/
static
int
__devinit
aureon_ini
t
(
struct
snd_ice1712
*
ice
)
static
int
aureon_rese
t
(
struct
snd_ice1712
*
ice
)
{
static
const
unsigned
short
wm_inits_aureon
[]
=
{
/* These come first to reduce init pop noise */
...
...
@@ -2047,30 +2046,10 @@ static int __devinit aureon_init(struct snd_ice1712 *ice)
0x0605
,
/* slave, 24bit, MSB on second OSCLK, SDOUT for right channel when OLRCK is high */
(
unsigned
short
)
-
1
};
struct
aureon_spec
*
spec
;
unsigned
int
tmp
;
const
unsigned
short
*
p
;
int
err
,
i
;
spec
=
kzalloc
(
sizeof
(
*
spec
),
GFP_KERNEL
);
if
(
!
spec
)
return
-
ENOMEM
;
ice
->
spec
=
spec
;
if
(
ice
->
eeprom
.
subvendor
==
VT1724_SUBDEVICE_AUREON51_SKY
)
{
ice
->
num_total_dacs
=
6
;
ice
->
num_total_adcs
=
2
;
}
else
{
/* aureon 7.1 and prodigy 7.1 */
ice
->
num_total_dacs
=
8
;
ice
->
num_total_adcs
=
2
;
}
/* to remeber the register values of CS8415 */
ice
->
akm
=
kzalloc
(
sizeof
(
struct
snd_akm4xxx
),
GFP_KERNEL
);
if
(
!
ice
->
akm
)
return
-
ENOMEM
;
ice
->
akm_codecs
=
1
;
int
err
;
struct
aureon_spec
*
spec
=
ice
->
spec
;
err
=
aureon_ac97_init
(
ice
);
if
(
err
!=
0
)
...
...
@@ -2118,6 +2097,61 @@ static int __devinit aureon_init(struct snd_ice1712 *ice)
/* initialize PCA9554 pin directions & set default input */
aureon_pca9554_write
(
ice
,
PCA9554_DIR
,
0x00
);
aureon_pca9554_write
(
ice
,
PCA9554_OUT
,
0x00
);
/* internal AUX */
return
0
;
}
/*
* suspend/resume
*/
#ifdef CONFIG_PM
static
int
aureon_resume
(
struct
snd_ice1712
*
ice
)
{
struct
aureon_spec
*
spec
=
ice
->
spec
;
int
err
,
i
;
err
=
aureon_reset
(
ice
);
if
(
err
!=
0
)
return
err
;
/* workaround for poking volume with alsamixer after resume:
* just set stored volume again */
for
(
i
=
0
;
i
<
ice
->
num_total_dacs
;
i
++
)
wm_set_vol
(
ice
,
i
,
spec
->
vol
[
i
],
spec
->
master
[
i
%
2
]);
return
0
;
}
#endif
/*
* initialize the chip
*/
static
int
__devinit
aureon_init
(
struct
snd_ice1712
*
ice
)
{
struct
aureon_spec
*
spec
;
int
i
,
err
;
spec
=
kzalloc
(
sizeof
(
*
spec
),
GFP_KERNEL
);
if
(
!
spec
)
return
-
ENOMEM
;
ice
->
spec
=
spec
;
if
(
ice
->
eeprom
.
subvendor
==
VT1724_SUBDEVICE_AUREON51_SKY
)
{
ice
->
num_total_dacs
=
6
;
ice
->
num_total_adcs
=
2
;
}
else
{
/* aureon 7.1 and prodigy 7.1 */
ice
->
num_total_dacs
=
8
;
ice
->
num_total_adcs
=
2
;
}
/* to remeber the register values of CS8415 */
ice
->
akm
=
kzalloc
(
sizeof
(
struct
snd_akm4xxx
),
GFP_KERNEL
);
if
(
!
ice
->
akm
)
return
-
ENOMEM
;
ice
->
akm_codecs
=
1
;
err
=
aureon_reset
(
ice
);
if
(
err
!=
0
)
return
err
;
spec
->
master
[
0
]
=
WM_VOL_MUTE
;
spec
->
master
[
1
]
=
WM_VOL_MUTE
;
...
...
@@ -2126,6 +2160,11 @@ static int __devinit aureon_init(struct snd_ice1712 *ice)
wm_set_vol
(
ice
,
i
,
spec
->
vol
[
i
],
spec
->
master
[
i
%
2
]);
}
#ifdef CONFIG_PM
ice
->
pm_resume
=
aureon_resume
;
ice
->
pm_suspend_enabled
=
1
;
#endif
return
0
;
}
...
...
sound/pci/mixart/mixart.c
View file @
3374cd1a
...
...
@@ -1102,73 +1102,17 @@ static int snd_mixart_free(struct mixart_mgr *mgr)
/*
* proc interface
*/
static
long
long
snd_mixart_BA0_llseek
(
struct
snd_info_entry
*
entry
,
void
*
private_file_data
,
struct
file
*
file
,
long
long
offset
,
int
orig
)
{
offset
=
offset
&
~
3
;
/* 4 bytes aligned */
switch
(
orig
)
{
case
SEEK_SET
:
file
->
f_pos
=
offset
;
break
;
case
SEEK_CUR
:
file
->
f_pos
+=
offset
;
break
;
case
SEEK_END
:
/* offset is negative */
file
->
f_pos
=
MIXART_BA0_SIZE
+
offset
;
break
;
default:
return
-
EINVAL
;
}
if
(
file
->
f_pos
>
MIXART_BA0_SIZE
)
file
->
f_pos
=
MIXART_BA0_SIZE
;
return
file
->
f_pos
;
}
static
long
long
snd_mixart_BA1_llseek
(
struct
snd_info_entry
*
entry
,
void
*
private_file_data
,
struct
file
*
file
,
long
long
offset
,
int
orig
)
{
offset
=
offset
&
~
3
;
/* 4 bytes aligned */
switch
(
orig
)
{
case
SEEK_SET
:
file
->
f_pos
=
offset
;
break
;
case
SEEK_CUR
:
file
->
f_pos
+=
offset
;
break
;
case
SEEK_END
:
/* offset is negative */
file
->
f_pos
=
MIXART_BA1_SIZE
+
offset
;
break
;
default:
return
-
EINVAL
;
}
if
(
file
->
f_pos
>
MIXART_BA1_SIZE
)
file
->
f_pos
=
MIXART_BA1_SIZE
;
return
file
->
f_pos
;
}
/*
mixart_BA0 proc interface for BAR 0 - read callback
*/
static
long
snd_mixart_BA0_read
(
struct
snd_info_entry
*
entry
,
void
*
file_private_data
,
struct
file
*
file
,
char
__user
*
buf
,
unsigned
long
count
,
unsigned
long
pos
)
static
ssize_t
snd_mixart_BA0_read
(
struct
snd_info_entry
*
entry
,
void
*
file_private_data
,
struct
file
*
file
,
char
__user
*
buf
,
size_t
count
,
loff_t
pos
)
{
struct
mixart_mgr
*
mgr
=
entry
->
private_data
;
unsigned
long
maxsize
;
if
(
pos
>=
MIXART_BA0_SIZE
)
return
0
;
maxsize
=
MIXART_BA0_SIZE
-
pos
;
if
(
count
>
maxsize
)
count
=
maxsize
;
count
=
count
&
~
3
;
/* make sure the read size is a multiple of 4 bytes */
if
(
copy_to_user_fromio
(
buf
,
MIXART_MEM
(
mgr
,
pos
),
count
))
return
-
EFAULT
;
...
...
@@ -1178,18 +1122,13 @@ static long snd_mixart_BA0_read(struct snd_info_entry *entry, void *file_private
/*
mixart_BA1 proc interface for BAR 1 - read callback
*/
static
long
snd_mixart_BA1_read
(
struct
snd_info_entry
*
entry
,
void
*
file_private_data
,
struct
file
*
file
,
char
__user
*
buf
,
unsigned
long
count
,
unsigned
long
pos
)
static
ssize_t
snd_mixart_BA1_read
(
struct
snd_info_entry
*
entry
,
void
*
file_private_data
,
struct
file
*
file
,
char
__user
*
buf
,
size_t
count
,
loff_t
pos
)
{
struct
mixart_mgr
*
mgr
=
entry
->
private_data
;
unsigned
long
maxsize
;
if
(
pos
>
MIXART_BA1_SIZE
)
return
0
;
maxsize
=
MIXART_BA1_SIZE
-
pos
;
if
(
count
>
maxsize
)
count
=
maxsize
;
count
=
count
&
~
3
;
/* make sure the read size is a multiple of 4 bytes */
if
(
copy_to_user_fromio
(
buf
,
MIXART_REG
(
mgr
,
pos
),
count
))
return
-
EFAULT
;
...
...
@@ -1198,12 +1137,10 @@ static long snd_mixart_BA1_read(struct snd_info_entry *entry, void *file_private
static
struct
snd_info_entry_ops
snd_mixart_proc_ops_BA0
=
{
.
read
=
snd_mixart_BA0_read
,
.
llseek
=
snd_mixart_BA0_llseek
};
static
struct
snd_info_entry_ops
snd_mixart_proc_ops_BA1
=
{
.
read
=
snd_mixart_BA1_read
,
.
llseek
=
snd_mixart_BA1_llseek
};
...
...
sound/ppc/tumbler.c
View file @
3374cd1a
...
...
@@ -30,6 +30,7 @@
#include <linux/kmod.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/string.h>
#include <sound/core.h>
#include <asm/io.h>
#include <asm/irq.h>
...
...
@@ -46,6 +47,8 @@
#define DBG(fmt...)
#endif
#define IS_G4DA (of_machine_is_compatible("PowerMac3,4"))
/* i2c address for tumbler */
#define TAS_I2C_ADDR 0x34
...
...
@@ -243,6 +246,7 @@ static int tumbler_set_master_volume(struct pmac_tumbler *mix)
snd_printk
(
KERN_ERR
"failed to set volume
\n
"
);
return
-
EINVAL
;
}
DBG
(
"(I) succeeded to set volume (%u, %u)
\n
"
,
left_vol
,
right_vol
);
return
0
;
}
...
...
@@ -353,6 +357,7 @@ static int tumbler_set_drc(struct pmac_tumbler *mix)
snd_printk
(
KERN_ERR
"failed to set DRC
\n
"
);
return
-
EINVAL
;
}
DBG
(
"(I) succeeded to set DRC (%u, %u)
\n
"
,
val
[
0
],
val
[
1
]);
return
0
;
}
...
...
@@ -389,6 +394,7 @@ static int snapper_set_drc(struct pmac_tumbler *mix)
snd_printk
(
KERN_ERR
"failed to set DRC
\n
"
);
return
-
EINVAL
;
}
DBG
(
"(I) succeeded to set DRC (%u, %u)
\n
"
,
val
[
0
],
val
[
1
]);
return
0
;
}
...
...
@@ -1134,7 +1140,8 @@ static long tumbler_find_device(const char *device, const char *platform,
gp
->
inactive_val
=
(
*
base
)
?
0x4
:
0x5
;
}
else
{
const
u32
*
prop
=
NULL
;
gp
->
active_state
=
0
;
gp
->
active_state
=
IS_G4DA
&&
!
strncmp
(
device
,
"keywest-gpio1"
,
13
);
gp
->
active_val
=
0x4
;
gp
->
inactive_val
=
0x5
;
/* Here are some crude hacks to extract the GPIO polarity and
...
...
@@ -1312,6 +1319,9 @@ static int __devinit tumbler_init(struct snd_pmac *chip)
if
(
irq
<=
NO_IRQ
)
irq
=
tumbler_find_device
(
"line-output-detect"
,
NULL
,
&
mix
->
line_detect
,
1
);
if
(
IS_G4DA
&&
irq
<=
NO_IRQ
)
irq
=
tumbler_find_device
(
"keywest-gpio16"
,
NULL
,
&
mix
->
line_detect
,
1
);
mix
->
lineout_irq
=
irq
;
tumbler_reset_audio
(
chip
);
...
...
sound/usb/Kconfig
View file @
3374cd1a
...
...
@@ -65,6 +65,7 @@ config SND_USB_CAIAQ
* Native Instruments Audio 8 DJ
* Native Instruments Guitar Rig Session I/O
* Native Instruments Guitar Rig mobile
* Native Instruments Traktor Kontrol X1
To compile this driver as a module, choose M here: the module
will be called snd-usb-caiaq.
...
...
sound/usb/caiaq/control.c
View file @
3374cd1a
...
...
@@ -35,33 +35,41 @@ static int control_info(struct snd_kcontrol *kcontrol,
struct
snd_usb_caiaqdev
*
dev
=
caiaqdev
(
chip
->
card
);
int
pos
=
kcontrol
->
private_value
;
int
is_intval
=
pos
&
CNT_INTVAL
;
unsigned
int
id
=
dev
->
chip
.
usb_id
;
int
maxval
=
63
;
uinfo
->
count
=
1
;
pos
&=
~
CNT_INTVAL
;
if
(
id
==
USB_ID
(
USB_VID_NATIVEINSTRUMENTS
,
USB_PID_AUDIO8DJ
)
&&
(
pos
==
0
))
{
/* current input mode of A8DJ */
uinfo
->
type
=
SNDRV_CTL_ELEM_TYPE_INTEGER
;
uinfo
->
value
.
integer
.
min
=
0
;
uinfo
->
value
.
integer
.
max
=
2
;
return
0
;
}
switch
(
dev
->
chip
.
usb_id
)
{
case
USB_ID
(
USB_VID_NATIVEINSTRUMENTS
,
USB_PID_AUDIO8DJ
):
if
(
pos
==
0
)
{
/* current input mode of A8DJ */
uinfo
->
type
=
SNDRV_CTL_ELEM_TYPE_INTEGER
;
uinfo
->
value
.
integer
.
min
=
0
;
uinfo
->
value
.
integer
.
max
=
2
;
return
0
;
}
break
;
if
(
id
==
USB_ID
(
USB_VID_NATIVEINSTRUMENTS
,
USB_PID_AUDIO4DJ
)
&&
(
pos
==
0
))
{
/* current input mode of A4DJ */
uinfo
->
type
=
SNDRV_CTL_ELEM_TYPE_INTEGER
;
uinfo
->
value
.
integer
.
min
=
0
;
uinfo
->
value
.
integer
.
max
=
1
;
return
0
;
case
USB_ID
(
USB_VID_NATIVEINSTRUMENTS
,
USB_PID_AUDIO4DJ
):
if
(
pos
==
0
)
{
/* current input mode of A4DJ */
uinfo
->
type
=
SNDRV_CTL_ELEM_TYPE_INTEGER
;
uinfo
->
value
.
integer
.
min
=
0
;
uinfo
->
value
.
integer
.
max
=
1
;
return
0
;
}
break
;
case
USB_ID
(
USB_VID_NATIVEINSTRUMENTS
,
USB_PID_TRAKTORKONTROLX1
):
maxval
=
127
;
break
;
}
if
(
is_intval
)
{
uinfo
->
type
=
SNDRV_CTL_ELEM_TYPE_INTEGER
;
uinfo
->
value
.
integer
.
min
=
0
;
uinfo
->
value
.
integer
.
max
=
64
;
uinfo
->
value
.
integer
.
max
=
maxval
;
}
else
{
uinfo
->
type
=
SNDRV_CTL_ELEM_TYPE_BOOLEAN
;
uinfo
->
value
.
integer
.
min
=
0
;
...
...
@@ -102,9 +110,10 @@ static int control_put(struct snd_kcontrol *kcontrol,
struct
snd_usb_audio
*
chip
=
snd_kcontrol_chip
(
kcontrol
);
struct
snd_usb_caiaqdev
*
dev
=
caiaqdev
(
chip
->
card
);
int
pos
=
kcontrol
->
private_value
;
unsigned
char
cmd
=
EP1_CMD_WRITE_IO
;
if
(
dev
->
chip
.
usb_id
==
USB_ID
(
USB_VID_NATIVEINSTRUMENTS
,
USB_PID_AUDIO4DJ
))
{
switch
(
dev
->
chip
.
usb_id
)
{
case
USB_ID
(
USB_VID_NATIVEINSTRUMENTS
,
USB_PID_AUDIO4DJ
):
{
/* A4DJ has only one control */
/* do not expose hardware input mode 0 */
dev
->
control_state
[
0
]
=
ucontrol
->
value
.
integer
.
value
[
0
]
+
1
;
...
...
@@ -113,10 +122,15 @@ static int control_put(struct snd_kcontrol *kcontrol,
return
1
;
}
case
USB_ID
(
USB_VID_NATIVEINSTRUMENTS
,
USB_PID_TRAKTORKONTROLX1
):
cmd
=
EP1_CMD_DIMM_LEDS
;
break
;
}
if
(
pos
&
CNT_INTVAL
)
{
dev
->
control_state
[
pos
&
~
CNT_INTVAL
]
=
ucontrol
->
value
.
integer
.
value
[
0
];
snd_usb_caiaq_send_command
(
dev
,
EP1_CMD_WRITE_IO
,
snd_usb_caiaq_send_command
(
dev
,
cmd
,
dev
->
control_state
,
sizeof
(
dev
->
control_state
));
}
else
{
if
(
ucontrol
->
value
.
integer
.
value
[
0
])
...
...
@@ -124,7 +138,7 @@ static int control_put(struct snd_kcontrol *kcontrol,
else
dev
->
control_state
[
pos
/
8
]
&=
~
(
1
<<
(
pos
%
8
));
snd_usb_caiaq_send_command
(
dev
,
EP1_CMD_WRITE_IO
,
snd_usb_caiaq_send_command
(
dev
,
cmd
,
dev
->
control_state
,
sizeof
(
dev
->
control_state
));
}
...
...
@@ -273,6 +287,43 @@ static struct caiaq_controller a4dj_controller[] = {
{
"Current input mode"
,
0
|
CNT_INTVAL
}
};
static
struct
caiaq_controller
kontrolx1_controller
[]
=
{
{
"LED FX A: ON"
,
7
|
CNT_INTVAL
},
{
"LED FX A: 1"
,
6
|
CNT_INTVAL
},
{
"LED FX A: 2"
,
5
|
CNT_INTVAL
},
{
"LED FX A: 3"
,
4
|
CNT_INTVAL
},
{
"LED FX B: ON"
,
3
|
CNT_INTVAL
},
{
"LED FX B: 1"
,
2
|
CNT_INTVAL
},
{
"LED FX B: 2"
,
1
|
CNT_INTVAL
},
{
"LED FX B: 3"
,
0
|
CNT_INTVAL
},
{
"LED Hotcue"
,
28
|
CNT_INTVAL
},
{
"LED Shift (white)"
,
29
|
CNT_INTVAL
},
{
"LED Shift (green)"
,
30
|
CNT_INTVAL
},
{
"LED Deck A: FX1"
,
24
|
CNT_INTVAL
},
{
"LED Deck A: FX2"
,
25
|
CNT_INTVAL
},
{
"LED Deck A: IN"
,
17
|
CNT_INTVAL
},
{
"LED Deck A: OUT"
,
16
|
CNT_INTVAL
},
{
"LED Deck A: < BEAT"
,
19
|
CNT_INTVAL
},
{
"LED Deck A: BEAT >"
,
18
|
CNT_INTVAL
},
{
"LED Deck A: CUE/ABS"
,
21
|
CNT_INTVAL
},
{
"LED Deck A: CUP/REL"
,
20
|
CNT_INTVAL
},
{
"LED Deck A: PLAY"
,
23
|
CNT_INTVAL
},
{
"LED Deck A: SYNC"
,
22
|
CNT_INTVAL
},
{
"LED Deck B: FX1"
,
26
|
CNT_INTVAL
},
{
"LED Deck B: FX2"
,
27
|
CNT_INTVAL
},
{
"LED Deck B: IN"
,
15
|
CNT_INTVAL
},
{
"LED Deck B: OUT"
,
14
|
CNT_INTVAL
},
{
"LED Deck B: < BEAT"
,
13
|
CNT_INTVAL
},
{
"LED Deck B: BEAT >"
,
12
|
CNT_INTVAL
},
{
"LED Deck B: CUE/ABS"
,
11
|
CNT_INTVAL
},
{
"LED Deck B: CUP/REL"
,
10
|
CNT_INTVAL
},
{
"LED Deck B: PLAY"
,
9
|
CNT_INTVAL
},
{
"LED Deck B: SYNC"
,
8
|
CNT_INTVAL
},
};
static
int
__devinit
add_controls
(
struct
caiaq_controller
*
c
,
int
num
,
struct
snd_usb_caiaqdev
*
dev
)
{
...
...
@@ -321,10 +372,16 @@ int __devinit snd_usb_caiaq_control_init(struct snd_usb_caiaqdev *dev)
ret
=
add_controls
(
a8dj_controller
,
ARRAY_SIZE
(
a8dj_controller
),
dev
);
break
;
case
USB_ID
(
USB_VID_NATIVEINSTRUMENTS
,
USB_PID_AUDIO4DJ
):
ret
=
add_controls
(
a4dj_controller
,
ARRAY_SIZE
(
a4dj_controller
),
dev
);
break
;
case
USB_ID
(
USB_VID_NATIVEINSTRUMENTS
,
USB_PID_TRAKTORKONTROLX1
):
ret
=
add_controls
(
kontrolx1_controller
,
ARRAY_SIZE
(
kontrolx1_controller
),
dev
);
break
;
}
return
ret
;
...
...
sound/usb/caiaq/device.c
View file @
3374cd1a
...
...
@@ -47,7 +47,8 @@ MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2},"
"{Native Instruments, Audio 4 DJ},"
"{Native Instruments, Audio 8 DJ},"
"{Native Instruments, Session I/O},"
"{Native Instruments, GuitarRig mobile}"
);
"{Native Instruments, GuitarRig mobile}"
"{Native Instruments, Traktor Kontrol X1}"
);
static
int
index
[
SNDRV_CARDS
]
=
SNDRV_DEFAULT_IDX
;
/* Index 0-max */
static
char
*
id
[
SNDRV_CARDS
]
=
SNDRV_DEFAULT_STR
;
/* Id for this card */
...
...
@@ -128,6 +129,11 @@ static struct usb_device_id snd_usb_id_table[] = {
.
idVendor
=
USB_VID_NATIVEINSTRUMENTS
,
.
idProduct
=
USB_PID_AUDIO2DJ
},
{
.
match_flags
=
USB_DEVICE_ID_MATCH_DEVICE
,
.
idVendor
=
USB_VID_NATIVEINSTRUMENTS
,
.
idProduct
=
USB_PID_TRAKTORKONTROLX1
},
{
/* terminator */
}
};
...
...
sound/usb/caiaq/device.h
View file @
3374cd1a
...
...
@@ -5,18 +5,20 @@
#define USB_VID_NATIVEINSTRUMENTS 0x17cc
#define USB_PID_RIGKONTROL2 0x1969
#define USB_PID_RIGKONTROL3 0x1940
#define USB_PID_KORECONTROLLER 0x4711
#define USB_PID_KORECONTROLLER2 0x4712
#define USB_PID_AK1 0x0815
#define USB_PID_AUDIO2DJ 0x041c
#define USB_PID_AUDIO4DJ 0x0839
#define USB_PID_AUDIO8DJ 0x1978
#define USB_PID_SESSIONIO 0x1915
#define USB_PID_GUITARRIGMOBILE 0x0d8d
#define USB_PID_RIGKONTROL2 0x1969
#define USB_PID_RIGKONTROL3 0x1940
#define USB_PID_KORECONTROLLER 0x4711
#define USB_PID_KORECONTROLLER2 0x4712
#define USB_PID_AK1 0x0815
#define USB_PID_AUDIO2DJ 0x041c
#define USB_PID_AUDIO4DJ 0x0839
#define USB_PID_AUDIO8DJ 0x1978
#define USB_PID_SESSIONIO 0x1915
#define USB_PID_GUITARRIGMOBILE 0x0d8d
#define USB_PID_TRAKTORKONTROLX1 0x2305
#define EP1_BUFSIZE 64
#define EP4_BUFSIZE 512
#define CAIAQ_USB_STR_LEN 0xff
#define MAX_STREAMS 32
...
...
@@ -104,6 +106,8 @@ struct snd_usb_caiaqdev {
struct
input_dev
*
input_dev
;
char
phys
[
64
];
/* physical device path */
unsigned
short
keycode
[
64
];
struct
urb
*
ep4_in_urb
;
unsigned
char
ep4_in_buf
[
EP4_BUFSIZE
];
#endif
/* ALSA */
...
...
sound/usb/caiaq/input.c
View file @
3374cd1a
...
...
@@ -19,6 +19,7 @@
#include <linux/init.h>
#include <linux/usb.h>
#include <linux/usb/input.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include "device.h"
...
...
@@ -65,6 +66,8 @@ static unsigned short keycode_kore[] = {
KEY_BRL_DOT5
};
#define KONTROLX1_INPUTS 40
#define DEG90 (range / 2)
#define DEG180 (range)
#define DEG270 (DEG90 + DEG180)
...
...
@@ -162,6 +165,17 @@ static void snd_caiaq_input_read_analog(struct snd_usb_caiaqdev *dev,
input_report_abs
(
input_dev
,
ABS_Z
,
(
buf
[
4
]
<<
8
)
|
buf
[
5
]);
input_sync
(
input_dev
);
break
;
case
USB_ID
(
USB_VID_NATIVEINSTRUMENTS
,
USB_PID_TRAKTORKONTROLX1
):
input_report_abs
(
input_dev
,
ABS_HAT0X
,
(
buf
[
8
]
<<
8
)
|
buf
[
9
]);
input_report_abs
(
input_dev
,
ABS_HAT0Y
,
(
buf
[
4
]
<<
8
)
|
buf
[
5
]);
input_report_abs
(
input_dev
,
ABS_HAT1X
,
(
buf
[
12
]
<<
8
)
|
buf
[
13
]);
input_report_abs
(
input_dev
,
ABS_HAT1Y
,
(
buf
[
2
]
<<
8
)
|
buf
[
3
]);
input_report_abs
(
input_dev
,
ABS_HAT2X
,
(
buf
[
15
]
<<
8
)
|
buf
[
15
]);
input_report_abs
(
input_dev
,
ABS_HAT2Y
,
(
buf
[
0
]
<<
8
)
|
buf
[
1
]);
input_report_abs
(
input_dev
,
ABS_HAT3X
,
(
buf
[
10
]
<<
8
)
|
buf
[
11
]);
input_report_abs
(
input_dev
,
ABS_HAT3Y
,
(
buf
[
6
]
<<
8
)
|
buf
[
7
]);
input_sync
(
input_dev
);
break
;
}
}
...
...
@@ -201,7 +215,7 @@ static void snd_caiaq_input_read_erp(struct snd_usb_caiaqdev *dev,
}
static
void
snd_caiaq_input_read_io
(
struct
snd_usb_caiaqdev
*
dev
,
char
*
buf
,
unsigned
int
len
)
unsigned
char
*
buf
,
unsigned
int
len
)
{
struct
input_dev
*
input_dev
=
dev
->
input_dev
;
unsigned
short
*
keycode
=
input_dev
->
keycode
;
...
...
@@ -218,15 +232,84 @@ static void snd_caiaq_input_read_io(struct snd_usb_caiaqdev *dev,
input_report_key
(
input_dev
,
keycode
[
i
],
buf
[
i
/
8
]
&
(
1
<<
(
i
%
8
)));
if
(
dev
->
chip
.
usb_id
==
USB_ID
(
USB_VID_NATIVEINSTRUMENTS
,
USB_PID_KORECONTROLLER
)
||
dev
->
chip
.
usb_id
==
USB_ID
(
USB_VID_NATIVEINSTRUMENTS
,
USB_PID_KORECONTROLLER2
))
switch
(
dev
->
chip
.
usb_id
)
{
case
USB_ID
(
USB_VID_NATIVEINSTRUMENTS
,
USB_PID_KORECONTROLLER
):
case
USB_ID
(
USB_VID_NATIVEINSTRUMENTS
,
USB_PID_KORECONTROLLER2
):
input_report_abs
(
dev
->
input_dev
,
ABS_MISC
,
255
-
buf
[
4
]);
break
;
case
USB_ID
(
USB_VID_NATIVEINSTRUMENTS
,
USB_PID_TRAKTORKONTROLX1
):
/* rotary encoders */
input_report_abs
(
dev
->
input_dev
,
ABS_X
,
buf
[
5
]
&
0xf
);
input_report_abs
(
dev
->
input_dev
,
ABS_Y
,
buf
[
5
]
>>
4
);
input_report_abs
(
dev
->
input_dev
,
ABS_Z
,
buf
[
6
]
&
0xf
);
input_report_abs
(
dev
->
input_dev
,
ABS_MISC
,
buf
[
6
]
>>
4
);
break
;
}
input_sync
(
input_dev
);
}
static
void
snd_usb_caiaq_ep4_reply_dispatch
(
struct
urb
*
urb
)
{
struct
snd_usb_caiaqdev
*
dev
=
urb
->
context
;
unsigned
char
*
buf
=
urb
->
transfer_buffer
;
int
ret
;
if
(
urb
->
status
||
!
dev
||
urb
!=
dev
->
ep4_in_urb
)
return
;
if
(
urb
->
actual_length
<
24
)
goto
requeue
;
switch
(
dev
->
chip
.
usb_id
)
{
case
USB_ID
(
USB_VID_NATIVEINSTRUMENTS
,
USB_PID_TRAKTORKONTROLX1
):
if
(
buf
[
0
]
&
0x3
)
snd_caiaq_input_read_io
(
dev
,
buf
+
1
,
7
);
if
(
buf
[
0
]
&
0x4
)
snd_caiaq_input_read_analog
(
dev
,
buf
+
8
,
16
);
break
;
}
requeue:
dev
->
ep4_in_urb
->
actual_length
=
0
;
ret
=
usb_submit_urb
(
dev
->
ep4_in_urb
,
GFP_ATOMIC
);
if
(
ret
<
0
)
log
(
"unable to submit urb. OOM!?
\n
"
);
}
static
int
snd_usb_caiaq_input_open
(
struct
input_dev
*
idev
)
{
struct
snd_usb_caiaqdev
*
dev
=
input_get_drvdata
(
idev
);
if
(
!
dev
)
return
-
EINVAL
;
switch
(
dev
->
chip
.
usb_id
)
{
case
USB_ID
(
USB_VID_NATIVEINSTRUMENTS
,
USB_PID_TRAKTORKONTROLX1
):
if
(
usb_submit_urb
(
dev
->
ep4_in_urb
,
GFP_KERNEL
)
!=
0
)
return
-
EIO
;
break
;
}
return
0
;
}
static
void
snd_usb_caiaq_input_close
(
struct
input_dev
*
idev
)
{
struct
snd_usb_caiaqdev
*
dev
=
input_get_drvdata
(
idev
);
if
(
!
dev
)
return
;
switch
(
dev
->
chip
.
usb_id
)
{
case
USB_ID
(
USB_VID_NATIVEINSTRUMENTS
,
USB_PID_TRAKTORKONTROLX1
):
usb_kill_urb
(
dev
->
ep4_in_urb
);
break
;
}
}
void
snd_usb_caiaq_input_dispatch
(
struct
snd_usb_caiaqdev
*
dev
,
char
*
buf
,
unsigned
int
len
)
...
...
@@ -251,7 +334,7 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev)
{
struct
usb_device
*
usb_dev
=
dev
->
chip
.
dev
;
struct
input_dev
*
input
;
int
i
,
ret
;
int
i
,
ret
=
0
;
input
=
input_allocate_device
();
if
(
!
input
)
...
...
@@ -265,7 +348,9 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev)
usb_to_input_id
(
usb_dev
,
&
input
->
id
);
input
->
dev
.
parent
=
&
usb_dev
->
dev
;
switch
(
dev
->
chip
.
usb_id
)
{
input_set_drvdata
(
input
,
dev
);
switch
(
dev
->
chip
.
usb_id
)
{
case
USB_ID
(
USB_VID_NATIVEINSTRUMENTS
,
USB_PID_RIGKONTROL2
):
input
->
evbit
[
0
]
=
BIT_MASK
(
EV_KEY
)
|
BIT_MASK
(
EV_ABS
);
input
->
absbit
[
0
]
=
BIT_MASK
(
ABS_X
)
|
BIT_MASK
(
ABS_Y
)
|
...
...
@@ -325,26 +410,73 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev)
input_set_abs_params
(
input
,
ABS_Z
,
0
,
4096
,
0
,
10
);
input_set_abs_params
(
input
,
ABS_MISC
,
0
,
255
,
0
,
1
);
snd_usb_caiaq_set_auto_msg
(
dev
,
1
,
10
,
5
);
break
;
case
USB_ID
(
USB_VID_NATIVEINSTRUMENTS
,
USB_PID_TRAKTORKONTROLX1
):
input
->
evbit
[
0
]
=
BIT_MASK
(
EV_KEY
)
|
BIT_MASK
(
EV_ABS
);
input
->
absbit
[
0
]
=
BIT_MASK
(
ABS_HAT0X
)
|
BIT_MASK
(
ABS_HAT0Y
)
|
BIT_MASK
(
ABS_HAT1X
)
|
BIT_MASK
(
ABS_HAT1Y
)
|
BIT_MASK
(
ABS_HAT2X
)
|
BIT_MASK
(
ABS_HAT2Y
)
|
BIT_MASK
(
ABS_HAT3X
)
|
BIT_MASK
(
ABS_HAT3Y
)
|
BIT_MASK
(
ABS_X
)
|
BIT_MASK
(
ABS_Y
)
|
BIT_MASK
(
ABS_Z
);
input
->
absbit
[
BIT_WORD
(
ABS_MISC
)]
|=
BIT_MASK
(
ABS_MISC
);
BUILD_BUG_ON
(
sizeof
(
dev
->
keycode
)
<
KONTROLX1_INPUTS
);
for
(
i
=
0
;
i
<
KONTROLX1_INPUTS
;
i
++
)
dev
->
keycode
[
i
]
=
BTN_MISC
+
i
;
input
->
keycodemax
=
KONTROLX1_INPUTS
;
/* analog potentiometers */
input_set_abs_params
(
input
,
ABS_HAT0X
,
0
,
4096
,
0
,
10
);
input_set_abs_params
(
input
,
ABS_HAT0Y
,
0
,
4096
,
0
,
10
);
input_set_abs_params
(
input
,
ABS_HAT1X
,
0
,
4096
,
0
,
10
);
input_set_abs_params
(
input
,
ABS_HAT1Y
,
0
,
4096
,
0
,
10
);
input_set_abs_params
(
input
,
ABS_HAT2X
,
0
,
4096
,
0
,
10
);
input_set_abs_params
(
input
,
ABS_HAT2Y
,
0
,
4096
,
0
,
10
);
input_set_abs_params
(
input
,
ABS_HAT3X
,
0
,
4096
,
0
,
10
);
input_set_abs_params
(
input
,
ABS_HAT3Y
,
0
,
4096
,
0
,
10
);
/* rotary encoders */
input_set_abs_params
(
input
,
ABS_X
,
0
,
0xf
,
0
,
1
);
input_set_abs_params
(
input
,
ABS_Y
,
0
,
0xf
,
0
,
1
);
input_set_abs_params
(
input
,
ABS_Z
,
0
,
0xf
,
0
,
1
);
input_set_abs_params
(
input
,
ABS_MISC
,
0
,
0xf
,
0
,
1
);
dev
->
ep4_in_urb
=
usb_alloc_urb
(
0
,
GFP_KERNEL
);
if
(
!
dev
->
ep4_in_urb
)
{
ret
=
-
ENOMEM
;
goto
exit_free_idev
;
}
usb_fill_bulk_urb
(
dev
->
ep4_in_urb
,
usb_dev
,
usb_rcvbulkpipe
(
usb_dev
,
0x4
),
dev
->
ep4_in_buf
,
EP4_BUFSIZE
,
snd_usb_caiaq_ep4_reply_dispatch
,
dev
);
snd_usb_caiaq_set_auto_msg
(
dev
,
1
,
10
,
5
);
break
;
default:
/* no input methods supported on this device */
input_free_device
(
input
);
return
0
;
goto
exit_free_idev
;
}
input
->
open
=
snd_usb_caiaq_input_open
;
input
->
close
=
snd_usb_caiaq_input_close
;
input
->
keycode
=
dev
->
keycode
;
input
->
keycodesize
=
sizeof
(
unsigned
short
);
for
(
i
=
0
;
i
<
input
->
keycodemax
;
i
++
)
__set_bit
(
dev
->
keycode
[
i
],
input
->
keybit
);
ret
=
input_register_device
(
input
);
if
(
ret
<
0
)
{
input_free_device
(
input
);
return
ret
;
}
if
(
ret
<
0
)
goto
exit_free_idev
;
dev
->
input_dev
=
input
;
return
0
;
exit_free_idev:
input_free_device
(
input
);
return
ret
;
}
void
snd_usb_caiaq_input_free
(
struct
snd_usb_caiaqdev
*
dev
)
...
...
@@ -352,6 +484,10 @@ void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *dev)
if
(
!
dev
||
!
dev
->
input_dev
)
return
;
usb_kill_urb
(
dev
->
ep4_in_urb
);
usb_free_urb
(
dev
->
ep4_in_urb
);
dev
->
ep4_in_urb
=
NULL
;
input_unregister_device
(
dev
->
input_dev
);
dev
->
input_dev
=
NULL
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment