Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
067e4a5d
cloud-kernel
项目概览
openanolis
/
cloud-kernel
接近 2 年 前同步成功
通知
169
Star
36
Fork
7
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
10
列表
看板
标记
里程碑
合并请求
2
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
cloud-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
10
Issue
10
列表
看板
标记
里程碑
合并请求
2
合并请求
2
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
067e4a5d
编写于
4月 13, 2010
作者:
T
Takashi Iwai
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'topic/bkl' into topic/core-cleanup
上级
0d0fb0f9
4cf19b84
变更
12
隐藏空白更改
内联
并排
Showing
12 changed file
with
633 addition
and
205 deletion
+633
-205
sound/atmel/Kconfig
sound/atmel/Kconfig
+1
-1
sound/atmel/ac97c.c
sound/atmel/ac97c.c
+266
-89
sound/core/info.c
sound/core/info.c
+2
-2
sound/core/pcm_native.c
sound/core/pcm_native.c
+2
-7
sound/core/sound.c
sound/core/sound.c
+38
-35
sound/pci/ice1712/aureon.c
sound/pci/ice1712/aureon.c
+64
-25
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
未找到文件。
sound/atmel/Kconfig
浏览文件 @
067e4a5d
...
...
@@ -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
浏览文件 @
067e4a5d
...
...
@@ -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/info.c
浏览文件 @
067e4a5d
...
...
@@ -168,7 +168,7 @@ static loff_t snd_info_entry_llseek(struct file *file, loff_t offset, int orig)
data
=
file
->
private_data
;
entry
=
data
->
entry
;
lock_kernel
(
);
mutex_lock
(
&
entry
->
access
);
switch
(
entry
->
content
)
{
case
SNDRV_INFO_CONTENT_TEXT
:
switch
(
orig
)
{
...
...
@@ -197,7 +197,7 @@ static loff_t snd_info_entry_llseek(struct file *file, loff_t offset, int orig)
}
ret
=
-
ENXIO
;
out:
unlock_kernel
(
);
mutex_unlock
(
&
entry
->
access
);
return
ret
;
}
...
...
sound/core/pcm_native.c
浏览文件 @
067e4a5d
...
...
@@ -3303,18 +3303,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
);
}
/*
...
...
sound/core/sound.c
浏览文件 @
067e4a5d
...
...
@@ -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/pci/ice1712/aureon.c
浏览文件 @
067e4a5d
...
...
@@ -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/ppc/tumbler.c
浏览文件 @
067e4a5d
...
...
@@ -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
浏览文件 @
067e4a5d
...
...
@@ -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
浏览文件 @
067e4a5d
...
...
@@ -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
浏览文件 @
067e4a5d
...
...
@@ -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
浏览文件 @
067e4a5d
...
...
@@ -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
浏览文件 @
067e4a5d
...
...
@@ -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.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录