Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
3374cd1a
K
Kernel
项目概览
openeuler
/
Kernel
接近 2 年 前同步成功
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
3374cd1a
编写于
5月 20, 2010
作者:
T
Takashi Iwai
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'topic/core-cleanup' into for-linus
上级
e40152ee
670ff6ab
变更
26
隐藏空白更改
内联
并排
Showing
26 changed file
with
829 addition
and
492 deletion
+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
未找到文件。
Documentation/DocBook/writing-an-alsa-driver.tmpl
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
;
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录