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
Kirill Smelkov
linux
Commits
5f9c510e
Commit
5f9c510e
authored
Apr 06, 2009
by
Takashi Iwai
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'topic/atmel' into for-linus
parents
c707e950
fa075ed2
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
119 additions
and
27 deletions
+119
-27
sound/atmel/abdac.c
sound/atmel/abdac.c
+2
-2
sound/atmel/ac97c.c
sound/atmel/ac97c.c
+109
-19
sound/atmel/ac97c.h
sound/atmel/ac97c.h
+8
-6
No files found.
sound/atmel/abdac.c
View file @
5f9c510e
...
...
@@ -165,7 +165,7 @@ static struct snd_pcm_hardware atmel_abdac_hw = {
.
buffer_bytes_max
=
64
*
4096
,
.
period_bytes_min
=
4096
,
.
period_bytes_max
=
4096
,
.
periods_min
=
4
,
.
periods_min
=
6
,
.
periods_max
=
64
,
};
...
...
@@ -502,7 +502,7 @@ static int __devinit atmel_abdac_probe(struct platform_device *pdev)
platform_set_drvdata
(
pdev
,
card
);
dev_info
(
&
pdev
->
dev
,
"Atmel ABDAC at 0x%p using %s
\n
"
,
dac
->
regs
,
d
ac
->
dma
.
chan
->
dev
->
device
.
bus_id
);
dac
->
regs
,
d
ev_name
(
&
dac
->
dma
.
chan
->
dev
->
device
)
);
return
retval
;
...
...
sound/atmel/ac97c.c
View file @
5f9c510e
/*
* Driver for
the Atmel AC97C controller
* Driver for
Atmel AC97C
*
* Copyright (C) 2005-2009 Atmel Corporation
*
...
...
@@ -10,6 +10,7 @@
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/bitmap.h>
#include <linux/device.h>
#include <linux/dmaengine.h>
#include <linux/dma-mapping.h>
#include <linux/init.h>
...
...
@@ -65,6 +66,7 @@ struct atmel_ac97c {
/* Serialize access to opened variable */
spinlock_t
lock
;
void
__iomem
*
regs
;
int
irq
;
int
opened
;
int
reset_pin
;
};
...
...
@@ -150,10 +152,10 @@ static struct snd_pcm_hardware atmel_ac97c_hw = {
.
rate_max
=
48000
,
.
channels_min
=
1
,
.
channels_max
=
2
,
.
buffer_bytes_max
=
64
*
4096
,
.
buffer_bytes_max
=
2
*
2
*
64
*
2048
,
.
period_bytes_min
=
4096
,
.
period_bytes_max
=
4096
,
.
periods_min
=
4
,
.
periods_min
=
6
,
.
periods_max
=
64
,
};
...
...
@@ -297,9 +299,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
;
unsigned
long
word
=
0
;
unsigned
long
word
=
ac97c_readl
(
chip
,
OCA
)
;
int
retval
;
word
&=
~
(
AC97C_CH_MASK
(
PCM_LEFT
)
|
AC97C_CH_MASK
(
PCM_RIGHT
));
/* assign channels to AC97C channel A */
switch
(
runtime
->
channels
)
{
case
1
:
...
...
@@ -312,7 +316,6 @@ static int atmel_ac97c_playback_prepare(struct snd_pcm_substream *substream)
default:
/* TODO: support more than two channels */
return
-
EINVAL
;
break
;
}
ac97c_writel
(
chip
,
OCA
,
word
);
...
...
@@ -324,13 +327,25 @@ static int atmel_ac97c_playback_prepare(struct snd_pcm_substream *substream)
word
|=
AC97C_CMR_CEM_LITTLE
;
break
;
case
SNDRV_PCM_FORMAT_S16_BE
:
/* fall through */
default:
word
&=
~
(
AC97C_CMR_CEM_LITTLE
);
break
;
default:
word
=
ac97c_readl
(
chip
,
OCA
);
word
&=
~
(
AC97C_CH_MASK
(
PCM_LEFT
)
|
AC97C_CH_MASK
(
PCM_RIGHT
));
ac97c_writel
(
chip
,
OCA
,
word
);
return
-
EINVAL
;
}
/* Enable underrun interrupt on channel A */
word
|=
AC97C_CSR_UNRUN
;
ac97c_writel
(
chip
,
CAMR
,
word
);
/* Enable channel A event interrupt */
word
=
ac97c_readl
(
chip
,
IMR
);
word
|=
AC97C_SR_CAEVT
;
ac97c_writel
(
chip
,
IER
,
word
);
/* set variable rate if needed */
if
(
runtime
->
rate
!=
48000
)
{
word
=
ac97c_readl
(
chip
,
MR
);
...
...
@@ -359,9 +374,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
;
unsigned
long
word
=
0
;
unsigned
long
word
=
ac97c_readl
(
chip
,
ICA
)
;
int
retval
;
word
&=
~
(
AC97C_CH_MASK
(
PCM_LEFT
)
|
AC97C_CH_MASK
(
PCM_RIGHT
));
/* assign channels to AC97C channel A */
switch
(
runtime
->
channels
)
{
case
1
:
...
...
@@ -374,7 +391,6 @@ static int atmel_ac97c_capture_prepare(struct snd_pcm_substream *substream)
default:
/* TODO: support more than two channels */
return
-
EINVAL
;
break
;
}
ac97c_writel
(
chip
,
ICA
,
word
);
...
...
@@ -386,13 +402,25 @@ static int atmel_ac97c_capture_prepare(struct snd_pcm_substream *substream)
word
|=
AC97C_CMR_CEM_LITTLE
;
break
;
case
SNDRV_PCM_FORMAT_S16_BE
:
/* fall through */
default:
word
&=
~
(
AC97C_CMR_CEM_LITTLE
);
break
;
default:
word
=
ac97c_readl
(
chip
,
ICA
);
word
&=
~
(
AC97C_CH_MASK
(
PCM_LEFT
)
|
AC97C_CH_MASK
(
PCM_RIGHT
));
ac97c_writel
(
chip
,
ICA
,
word
);
return
-
EINVAL
;
}
/* Enable overrun interrupt on channel A */
word
|=
AC97C_CSR_OVRUN
;
ac97c_writel
(
chip
,
CAMR
,
word
);
/* Enable channel A event interrupt */
word
=
ac97c_readl
(
chip
,
IMR
);
word
|=
AC97C_SR_CAEVT
;
ac97c_writel
(
chip
,
IER
,
word
);
/* set variable rate if needed */
if
(
runtime
->
rate
!=
48000
)
{
word
=
ac97c_readl
(
chip
,
MR
);
...
...
@@ -543,6 +571,43 @@ static struct snd_pcm_ops atmel_ac97_capture_ops = {
.
pointer
=
atmel_ac97c_capture_pointer
,
};
static
irqreturn_t
atmel_ac97c_interrupt
(
int
irq
,
void
*
dev
)
{
struct
atmel_ac97c
*
chip
=
(
struct
atmel_ac97c
*
)
dev
;
irqreturn_t
retval
=
IRQ_NONE
;
u32
sr
=
ac97c_readl
(
chip
,
SR
);
u32
casr
=
ac97c_readl
(
chip
,
CASR
);
u32
cosr
=
ac97c_readl
(
chip
,
COSR
);
if
(
sr
&
AC97C_SR_CAEVT
)
{
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"
:
""
,
casr
&
AC97C_CSR_UNRUN
?
" UNRUN"
:
""
,
casr
&
AC97C_CSR_TXEMPTY
?
" TXEMPTY"
:
""
,
casr
&
AC97C_CSR_TXRDY
?
" TXRDY"
:
""
,
!
casr
?
" NONE"
:
""
);
retval
=
IRQ_HANDLED
;
}
if
(
sr
&
AC97C_SR_COEVT
)
{
dev_info
(
&
chip
->
pdev
->
dev
,
"codec channel event%s%s%s%s%s
\n
"
,
cosr
&
AC97C_CSR_OVRUN
?
" OVRUN"
:
""
,
cosr
&
AC97C_CSR_RXRDY
?
" RXRDY"
:
""
,
cosr
&
AC97C_CSR_TXEMPTY
?
" TXEMPTY"
:
""
,
cosr
&
AC97C_CSR_TXRDY
?
" TXRDY"
:
""
,
!
cosr
?
" NONE"
:
""
);
retval
=
IRQ_HANDLED
;
}
if
(
retval
==
IRQ_NONE
)
{
dev_err
(
&
chip
->
pdev
->
dev
,
"spurious interrupt sr 0x%08x "
"casr 0x%08x cosr 0x%08x
\n
"
,
sr
,
casr
,
cosr
);
}
return
retval
;
}
static
int
__devinit
atmel_ac97c_pcm_new
(
struct
atmel_ac97c
*
chip
)
{
struct
snd_pcm
*
pcm
;
...
...
@@ -665,17 +730,17 @@ static bool filter(struct dma_chan *chan, void *slave)
static
void
atmel_ac97c_reset
(
struct
atmel_ac97c
*
chip
)
{
ac97c_writel
(
chip
,
MR
,
AC97C_MR_WRST
);
ac97c_writel
(
chip
,
MR
,
0
);
ac97c_writel
(
chip
,
MR
,
AC97C_MR_ENA
);
ac97c_writel
(
chip
,
CAMR
,
0
);
ac97c_writel
(
chip
,
COMR
,
0
);
if
(
gpio_is_valid
(
chip
->
reset_pin
))
{
gpio_set_value
(
chip
->
reset_pin
,
0
);
/* AC97 v2.2 specifications says minimum 1 us. */
udelay
(
10
);
udelay
(
2
);
gpio_set_value
(
chip
->
reset_pin
,
1
);
}
udelay
(
1
);
ac97c_writel
(
chip
,
MR
,
AC97C_MR_ENA
);
}
static
int
__devinit
atmel_ac97c_probe
(
struct
platform_device
*
pdev
)
...
...
@@ -690,6 +755,7 @@ static int __devinit atmel_ac97c_probe(struct platform_device *pdev)
.
read
=
atmel_ac97c_read
,
};
int
retval
;
int
irq
;
regs
=
platform_get_resource
(
pdev
,
IORESOURCE_MEM
,
0
);
if
(
!
regs
)
{
...
...
@@ -703,6 +769,12 @@ static int __devinit atmel_ac97c_probe(struct platform_device *pdev)
return
-
ENXIO
;
}
irq
=
platform_get_irq
(
pdev
,
0
);
if
(
irq
<
0
)
{
dev_dbg
(
&
pdev
->
dev
,
"could not get irq
\n
"
);
return
-
ENXIO
;
}
pclk
=
clk_get
(
&
pdev
->
dev
,
"pclk"
);
if
(
IS_ERR
(
pclk
))
{
dev_dbg
(
&
pdev
->
dev
,
"no peripheral clock
\n
"
);
...
...
@@ -719,6 +791,13 @@ static int __devinit atmel_ac97c_probe(struct platform_device *pdev)
chip
=
get_chip
(
card
);
retval
=
request_irq
(
irq
,
atmel_ac97c_interrupt
,
0
,
"AC97C"
,
chip
);
if
(
retval
)
{
dev_dbg
(
&
pdev
->
dev
,
"unable to request irq %d
\n
"
,
irq
);
goto
err_request_irq
;
}
chip
->
irq
=
irq
;
spin_lock_init
(
&
chip
->
lock
);
strcpy
(
card
->
driver
,
"Atmel AC97C"
);
...
...
@@ -747,14 +826,18 @@ static int __devinit atmel_ac97c_probe(struct platform_device *pdev)
snd_card_set_dev
(
card
,
&
pdev
->
dev
);
atmel_ac97c_reset
(
chip
);
/* Enable overrun interrupt from codec channel */
ac97c_writel
(
chip
,
COMR
,
AC97C_CSR_OVRUN
);
ac97c_writel
(
chip
,
IER
,
ac97c_readl
(
chip
,
IMR
)
|
AC97C_SR_COEVT
);
retval
=
snd_ac97_bus
(
card
,
0
,
&
ops
,
chip
,
&
chip
->
ac97_bus
);
if
(
retval
)
{
dev_dbg
(
&
pdev
->
dev
,
"could not register on ac97 bus
\n
"
);
goto
err_ac97_bus
;
}
atmel_ac97c_reset
(
chip
);
retval
=
atmel_ac97c_mixer_new
(
chip
);
if
(
retval
)
{
dev_dbg
(
&
pdev
->
dev
,
"could not register ac97 mixer
\n
"
);
...
...
@@ -773,7 +856,7 @@ static int __devinit atmel_ac97c_probe(struct platform_device *pdev)
chip
->
dma
.
rx_chan
=
dma_request_channel
(
mask
,
filter
,
dws
);
dev_info
(
&
chip
->
pdev
->
dev
,
"using %s for DMA RX
\n
"
,
chip
->
dma
.
rx_chan
->
dev
->
device
.
bus_id
);
dev_name
(
&
chip
->
dma
.
rx_chan
->
dev
->
device
)
);
set_bit
(
DMA_RX_CHAN_PRESENT
,
&
chip
->
flags
);
}
...
...
@@ -789,7 +872,7 @@ static int __devinit atmel_ac97c_probe(struct platform_device *pdev)
chip
->
dma
.
tx_chan
=
dma_request_channel
(
mask
,
filter
,
dws
);
dev_info
(
&
chip
->
pdev
->
dev
,
"using %s for DMA TX
\n
"
,
chip
->
dma
.
tx_chan
->
dev
->
device
.
bus_id
);
dev_name
(
&
chip
->
dma
.
tx_chan
->
dev
->
device
)
);
set_bit
(
DMA_TX_CHAN_PRESENT
,
&
chip
->
flags
);
}
...
...
@@ -809,7 +892,7 @@ static int __devinit atmel_ac97c_probe(struct platform_device *pdev)
retval
=
snd_card_register
(
card
);
if
(
retval
)
{
dev_dbg
(
&
pdev
->
dev
,
"could not register sound card
\n
"
);
goto
err_
ac97_bus
;
goto
err_
dma
;
}
platform_set_drvdata
(
pdev
,
card
);
...
...
@@ -836,6 +919,8 @@ static int __devinit atmel_ac97c_probe(struct platform_device *pdev)
iounmap
(
chip
->
regs
);
err_ioremap:
free_irq
(
irq
,
chip
);
err_request_irq:
snd_card_free
(
card
);
err_snd_card_new:
clk_disable
(
pclk
);
...
...
@@ -884,9 +969,14 @@ static int __devexit atmel_ac97c_remove(struct platform_device *pdev)
if
(
gpio_is_valid
(
chip
->
reset_pin
))
gpio_free
(
chip
->
reset_pin
);
ac97c_writel
(
chip
,
CAMR
,
0
);
ac97c_writel
(
chip
,
COMR
,
0
);
ac97c_writel
(
chip
,
MR
,
0
);
clk_disable
(
chip
->
pclk
);
clk_put
(
chip
->
pclk
);
iounmap
(
chip
->
regs
);
free_irq
(
chip
->
irq
,
chip
);
if
(
test_bit
(
DMA_RX_CHAN_PRESENT
,
&
chip
->
flags
))
dma_release_channel
(
chip
->
dma
.
rx_chan
);
...
...
sound/atmel/ac97c.h
View file @
5f9c510e
/*
* Register definitions for
the Atmel AC97C controller
* Register definitions for
Atmel AC97C
*
* Copyright (C) 2005-2009 Atmel Corporation
*
...
...
@@ -17,10 +17,6 @@
#define AC97C_CATHR 0x24
#define AC97C_CASR 0x28
#define AC97C_CAMR 0x2c
#define AC97C_CBRHR 0x30
#define AC97C_CBTHR 0x34
#define AC97C_CBSR 0x38
#define AC97C_CBMR 0x3c
#define AC97C_CORHR 0x40
#define AC97C_COTHR 0x44
#define AC97C_COSR 0x48
...
...
@@ -46,8 +42,10 @@
#define AC97C_MR_VRA (1 << 2)
#define AC97C_CSR_TXRDY (1 << 0)
#define AC97C_CSR_TXEMPTY (1 << 1)
#define AC97C_CSR_UNRUN (1 << 2)
#define AC97C_CSR_RXRDY (1 << 4)
#define AC97C_CSR_OVRUN (1 << 5)
#define AC97C_CSR_ENDTX (1 << 10)
#define AC97C_CSR_ENDRX (1 << 14)
...
...
@@ -61,11 +59,15 @@
#define AC97C_CMR_DMAEN (1 << 22)
#define AC97C_SR_CAEVT (1 << 3)
#define AC97C_SR_COEVT (1 << 2)
#define AC97C_SR_WKUP (1 << 1)
#define AC97C_SR_SOF (1 << 0)
#define AC97C_CH_MASK(slot) \
(0x7 << (3 * (AC97_SLOT_##slot - 3)))
#define AC97C_CH_ASSIGN(slot, channel) \
(AC97C_CHANNEL_##channel << (3 * (AC97_SLOT_##slot - 3)))
#define AC97C_CHANNEL_NONE 0x0
#define AC97C_CHANNEL_A 0x1
#define AC97C_CHANNEL_B 0x2
#endif
/* __SOUND_ATMEL_AC97C_H */
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