Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
067e4a5d
Commit
067e4a5d
authored
Apr 13, 2010
by
Takashi Iwai
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'topic/bkl' into topic/core-cleanup
parents
0d0fb0f9
4cf19b84
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
633 additions
and
205 deletions
+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
No files found.
sound/atmel/Kconfig
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment