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
458bcee9
Commit
458bcee9
authored
Jun 17, 2013
by
Mark Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'asoc/topic/ux500' into asoc-next
parents
93d4c1e0
eef6473f
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
159 additions
and
205 deletions
+159
-205
sound/soc/codecs/ab8500-codec.c
sound/soc/codecs/ab8500-codec.c
+46
-33
sound/soc/codecs/ab8500-codec.h
sound/soc/codecs/ab8500-codec.h
+22
-20
sound/soc/ux500/mop500_ab8500.c
sound/soc/ux500/mop500_ab8500.c
+36
-0
sound/soc/ux500/ux500_msp_dai.c
sound/soc/ux500/ux500_msp_dai.c
+4
-7
sound/soc/ux500/ux500_msp_dai.h
sound/soc/ux500/ux500_msp_dai.h
+0
-4
sound/soc/ux500/ux500_msp_i2s.c
sound/soc/ux500/ux500_msp_i2s.c
+11
-77
sound/soc/ux500/ux500_msp_i2s.h
sound/soc/ux500/ux500_msp_i2s.h
+10
-64
sound/soc/ux500/ux500_pcm.c
sound/soc/ux500/ux500_pcm.c
+30
-0
No files found.
sound/soc/codecs/ab8500-codec.c
View file @
458bcee9
...
@@ -2236,7 +2236,7 @@ static int ab8500_codec_set_dai_tdm_slot(struct snd_soc_dai *dai,
...
@@ -2236,7 +2236,7 @@ static int ab8500_codec_set_dai_tdm_slot(struct snd_soc_dai *dai,
int
slots
,
int
slot_width
)
int
slots
,
int
slot_width
)
{
{
struct
snd_soc_codec
*
codec
=
dai
->
codec
;
struct
snd_soc_codec
*
codec
=
dai
->
codec
;
unsigned
int
val
,
mask
,
slots_active
;
unsigned
int
val
,
mask
,
slot
,
slot
s_active
;
mask
=
BIT
(
AB8500_DIGIFCONF2_IF0WL0
)
|
mask
=
BIT
(
AB8500_DIGIFCONF2_IF0WL0
)
|
BIT
(
AB8500_DIGIFCONF2_IF0WL1
);
BIT
(
AB8500_DIGIFCONF2_IF0WL1
);
...
@@ -2292,27 +2292,34 @@ static int ab8500_codec_set_dai_tdm_slot(struct snd_soc_dai *dai,
...
@@ -2292,27 +2292,34 @@ static int ab8500_codec_set_dai_tdm_slot(struct snd_soc_dai *dai,
snd_soc_update_bits
(
codec
,
AB8500_DIGIFCONF1
,
mask
,
val
);
snd_soc_update_bits
(
codec
,
AB8500_DIGIFCONF1
,
mask
,
val
);
/* Setup TDM DA according to active tx slots */
/* Setup TDM DA according to active tx slots */
if
(
tx_mask
&
~
0xff
)
return
-
EINVAL
;
mask
=
AB8500_DASLOTCONFX_SLTODAX_MASK
;
mask
=
AB8500_DASLOTCONFX_SLTODAX_MASK
;
tx_mask
=
tx_mask
<<
AB8500_DA_DATA0_OFFSET
;
slots_active
=
hweight32
(
tx_mask
);
slots_active
=
hweight32
(
tx_mask
);
dev_dbg
(
dai
->
codec
->
dev
,
"%s: Slots, active, TX: %d
\n
"
,
__func__
,
dev_dbg
(
dai
->
codec
->
dev
,
"%s: Slots, active, TX: %d
\n
"
,
__func__
,
slots_active
);
slots_active
);
switch
(
slots_active
)
{
switch
(
slots_active
)
{
case
0
:
case
0
:
break
;
break
;
case
1
:
case
1
:
/* Slot 9 -> DA_IN1 & DA_IN3 */
slot
=
find_first_bit
((
unsigned
long
*
)
&
tx_mask
,
32
);
snd_soc_update_bits
(
codec
,
AB8500_DASLOTCONF1
,
mask
,
11
);
snd_soc_update_bits
(
codec
,
AB8500_DASLOTCONF1
,
mask
,
slot
);
snd_soc_update_bits
(
codec
,
AB8500_DASLOTCONF3
,
mask
,
11
);
snd_soc_update_bits
(
codec
,
AB8500_DASLOTCONF3
,
mask
,
slot
);
snd_soc_update_bits
(
codec
,
AB8500_DASLOTCONF2
,
mask
,
11
);
snd_soc_update_bits
(
codec
,
AB8500_DASLOTCONF2
,
mask
,
slot
);
snd_soc_update_bits
(
codec
,
AB8500_DASLOTCONF4
,
mask
,
11
);
snd_soc_update_bits
(
codec
,
AB8500_DASLOTCONF4
,
mask
,
slot
);
break
;
break
;
case
2
:
case
2
:
/* Slot 9 -> DA_IN1 & DA_IN3, Slot 11 -> DA_IN2 & DA_IN4 */
slot
=
find_first_bit
((
unsigned
long
*
)
&
tx_mask
,
32
);
snd_soc_update_bits
(
codec
,
AB8500_DASLOTCONF1
,
mask
,
9
);
snd_soc_update_bits
(
codec
,
AB8500_DASLOTCONF1
,
mask
,
slot
);
snd_soc_update_bits
(
codec
,
AB8500_DASLOTCONF3
,
mask
,
9
);
snd_soc_update_bits
(
codec
,
AB8500_DASLOTCONF3
,
mask
,
slot
);
s
nd_soc_update_bits
(
codec
,
AB8500_DASLOTCONF2
,
mask
,
1
1
);
s
lot
=
find_next_bit
((
unsigned
long
*
)
&
tx_mask
,
32
,
slot
+
1
);
snd_soc_update_bits
(
codec
,
AB8500_DASLOTCONF
4
,
mask
,
11
);
snd_soc_update_bits
(
codec
,
AB8500_DASLOTCONF
2
,
mask
,
slot
);
snd_soc_update_bits
(
codec
,
AB8500_DASLOTCONF4
,
mask
,
slot
);
break
;
break
;
case
8
:
case
8
:
dev_dbg
(
dai
->
codec
->
dev
,
dev_dbg
(
dai
->
codec
->
dev
,
...
@@ -2327,25 +2334,36 @@ static int ab8500_codec_set_dai_tdm_slot(struct snd_soc_dai *dai,
...
@@ -2327,25 +2334,36 @@ static int ab8500_codec_set_dai_tdm_slot(struct snd_soc_dai *dai,
}
}
/* Setup TDM AD according to active RX-slots */
/* Setup TDM AD according to active RX-slots */
if
(
rx_mask
&
~
0xff
)
return
-
EINVAL
;
rx_mask
=
rx_mask
<<
AB8500_AD_DATA0_OFFSET
;
slots_active
=
hweight32
(
rx_mask
);
slots_active
=
hweight32
(
rx_mask
);
dev_dbg
(
dai
->
codec
->
dev
,
"%s: Slots, active, RX: %d
\n
"
,
__func__
,
dev_dbg
(
dai
->
codec
->
dev
,
"%s: Slots, active, RX: %d
\n
"
,
__func__
,
slots_active
);
slots_active
);
switch
(
slots_active
)
{
switch
(
slots_active
)
{
case
0
:
case
0
:
break
;
break
;
case
1
:
case
1
:
/* AD_OUT3 -> slot 0 & 1 */
slot
=
find_first_bit
((
unsigned
long
*
)
&
rx_mask
,
32
);
snd_soc_update_bits
(
codec
,
AB8500_ADSLOTSEL
1
,
AB8500_MASK_ALL
,
snd_soc_update_bits
(
codec
,
AB8500_ADSLOTSEL
(
slot
)
,
AB8500_
ADSLOTSELX_AD_OUT3_TO_SLOT_EVEN
|
AB8500_
MASK_SLOT
(
slot
),
AB8500_ADSLOTSELX_AD_OUT
3_TO_SLOT_ODD
);
AB8500_ADSLOTSELX_AD_OUT
_TO_SLOT
(
AB8500_AD_OUT3
,
slot
)
);
break
;
break
;
case
2
:
case
2
:
/* AD_OUT3 -> slot 0, AD_OUT2 -> slot 1 */
slot
=
find_first_bit
((
unsigned
long
*
)
&
rx_mask
,
32
);
snd_soc_update_bits
(
codec
,
AB8500_ADSLOTSEL
(
slot
),
AB8500_MASK_SLOT
(
slot
),
AB8500_ADSLOTSELX_AD_OUT_TO_SLOT
(
AB8500_AD_OUT3
,
slot
));
slot
=
find_next_bit
((
unsigned
long
*
)
&
rx_mask
,
32
,
slot
+
1
);
snd_soc_update_bits
(
codec
,
snd_soc_update_bits
(
codec
,
AB8500_ADSLOTSEL1
,
AB8500_ADSLOTSEL
(
slot
),
AB8500_MASK_ALL
,
AB8500_MASK_SLOT
(
slot
),
AB8500_ADSLOTSELX_AD_OUT3_TO_SLOT_EVEN
|
AB8500_ADSLOTSELX_AD_OUT_TO_SLOT
(
AB8500_AD_OUT2
,
slot
));
AB8500_ADSLOTSELX_AD_OUT2_TO_SLOT_ODD
);
break
;
break
;
case
8
:
case
8
:
dev_dbg
(
dai
->
codec
->
dev
,
dev_dbg
(
dai
->
codec
->
dev
,
...
@@ -2362,6 +2380,11 @@ static int ab8500_codec_set_dai_tdm_slot(struct snd_soc_dai *dai,
...
@@ -2362,6 +2380,11 @@ static int ab8500_codec_set_dai_tdm_slot(struct snd_soc_dai *dai,
return
0
;
return
0
;
}
}
static
const
struct
snd_soc_dai_ops
ab8500_codec_ops
=
{
.
set_fmt
=
ab8500_codec_set_dai_fmt
,
.
set_tdm_slot
=
ab8500_codec_set_dai_tdm_slot
,
};
static
struct
snd_soc_dai_driver
ab8500_codec_dai
[]
=
{
static
struct
snd_soc_dai_driver
ab8500_codec_dai
[]
=
{
{
{
.
name
=
"ab8500-codec-dai.0"
,
.
name
=
"ab8500-codec-dai.0"
,
...
@@ -2373,12 +2396,7 @@ static struct snd_soc_dai_driver ab8500_codec_dai[] = {
...
@@ -2373,12 +2396,7 @@ static struct snd_soc_dai_driver ab8500_codec_dai[] = {
.
rates
=
AB8500_SUPPORTED_RATE
,
.
rates
=
AB8500_SUPPORTED_RATE
,
.
formats
=
AB8500_SUPPORTED_FMT
,
.
formats
=
AB8500_SUPPORTED_FMT
,
},
},
.
ops
=
(
struct
snd_soc_dai_ops
[])
{
.
ops
=
&
ab8500_codec_ops
,
{
.
set_tdm_slot
=
ab8500_codec_set_dai_tdm_slot
,
.
set_fmt
=
ab8500_codec_set_dai_fmt
,
}
},
.
symmetric_rates
=
1
.
symmetric_rates
=
1
},
},
{
{
...
@@ -2391,12 +2409,7 @@ static struct snd_soc_dai_driver ab8500_codec_dai[] = {
...
@@ -2391,12 +2409,7 @@ static struct snd_soc_dai_driver ab8500_codec_dai[] = {
.
rates
=
AB8500_SUPPORTED_RATE
,
.
rates
=
AB8500_SUPPORTED_RATE
,
.
formats
=
AB8500_SUPPORTED_FMT
,
.
formats
=
AB8500_SUPPORTED_FMT
,
},
},
.
ops
=
(
struct
snd_soc_dai_ops
[])
{
.
ops
=
&
ab8500_codec_ops
,
{
.
set_tdm_slot
=
ab8500_codec_set_dai_tdm_slot
,
.
set_fmt
=
ab8500_codec_set_dai_fmt
,
}
},
.
symmetric_rates
=
1
.
symmetric_rates
=
1
}
}
};
};
...
...
sound/soc/codecs/ab8500-codec.h
View file @
458bcee9
...
@@ -24,6 +24,13 @@
...
@@ -24,6 +24,13 @@
#define AB8500_SUPPORTED_RATE (SNDRV_PCM_RATE_48000)
#define AB8500_SUPPORTED_RATE (SNDRV_PCM_RATE_48000)
#define AB8500_SUPPORTED_FMT (SNDRV_PCM_FMTBIT_S16_LE)
#define AB8500_SUPPORTED_FMT (SNDRV_PCM_FMTBIT_S16_LE)
/* AB8500 interface slot offset definitions */
#define AB8500_AD_DATA0_OFFSET 0
#define AB8500_DA_DATA0_OFFSET 8
#define AB8500_AD_DATA1_OFFSET 16
#define AB8500_DA_DATA1_OFFSET 24
/* AB8500 audio bank (0x0d) register definitions */
/* AB8500 audio bank (0x0d) register definitions */
#define AB8500_POWERUP 0x00
#define AB8500_POWERUP 0x00
...
@@ -73,6 +80,7 @@
...
@@ -73,6 +80,7 @@
#define AB8500_ADSLOTSEL14 0x2C
#define AB8500_ADSLOTSEL14 0x2C
#define AB8500_ADSLOTSEL15 0x2D
#define AB8500_ADSLOTSEL15 0x2D
#define AB8500_ADSLOTSEL16 0x2E
#define AB8500_ADSLOTSEL16 0x2E
#define AB8500_ADSLOTSEL(slot) (AB8500_ADSLOTSEL1 + (slot >> 1))
#define AB8500_ADSLOTHIZCTRL1 0x2F
#define AB8500_ADSLOTHIZCTRL1 0x2F
#define AB8500_ADSLOTHIZCTRL2 0x30
#define AB8500_ADSLOTHIZCTRL2 0x30
#define AB8500_ADSLOTHIZCTRL3 0x31
#define AB8500_ADSLOTHIZCTRL3 0x31
...
@@ -144,6 +152,7 @@
...
@@ -144,6 +152,7 @@
#define AB8500_CACHEREGNUM (AB8500_LAST_REG + 1)
#define AB8500_CACHEREGNUM (AB8500_LAST_REG + 1)
#define AB8500_MASK_ALL 0xFF
#define AB8500_MASK_ALL 0xFF
#define AB8500_MASK_SLOT(slot) ((slot & 1) ? 0xF0 : 0x0F)
#define AB8500_MASK_NONE 0x00
#define AB8500_MASK_NONE 0x00
/* AB8500_POWERUP */
/* AB8500_POWERUP */
...
@@ -347,28 +356,21 @@
...
@@ -347,28 +356,21 @@
#define AB8500_DIGIFCONF4_IF1WL0 0
#define AB8500_DIGIFCONF4_IF1WL0 0
/* AB8500_ADSLOTSELX */
/* AB8500_ADSLOTSELX */
#define AB8500_ADSLOTSELX_AD_OUT1_TO_SLOT_ODD 0x00
#define AB8500_AD_OUT1 0x0
#define AB8500_ADSLOTSELX_AD_OUT2_TO_SLOT_ODD 0x10
#define AB8500_AD_OUT2 0x1
#define AB8500_ADSLOTSELX_AD_OUT3_TO_SLOT_ODD 0x20
#define AB8500_AD_OUT3 0x2
#define AB8500_ADSLOTSELX_AD_OUT4_TO_SLOT_ODD 0x30
#define AB8500_AD_OUT4 0x3
#define AB8500_ADSLOTSELX_AD_OUT5_TO_SLOT_ODD 0x40
#define AB8500_AD_OUT5 0x4
#define AB8500_ADSLOTSELX_AD_OUT6_TO_SLOT_ODD 0x50
#define AB8500_AD_OUT6 0x5
#define AB8500_ADSLOTSELX_AD_OUT7_TO_SLOT_ODD 0x60
#define AB8500_AD_OUT7 0x6
#define AB8500_ADSLOTSELX_AD_OUT8_TO_SLOT_ODD 0x70
#define AB8500_AD_OUT8 0x7
#define AB8500_ADSLOTSELX_ZEROES_TO_SLOT_ODD 0x80
#define AB8500_ZEROES 0x8
#define AB8500_ADSLOTSELX_TRISTATE_TO_SLOT_ODD 0xF0
#define AB8500_TRISTATE 0xF
#define AB8500_ADSLOTSELX_AD_OUT1_TO_SLOT_EVEN 0x00
#define AB8500_ADSLOTSELX_AD_OUT2_TO_SLOT_EVEN 0x01
#define AB8500_ADSLOTSELX_AD_OUT3_TO_SLOT_EVEN 0x02
#define AB8500_ADSLOTSELX_AD_OUT4_TO_SLOT_EVEN 0x03
#define AB8500_ADSLOTSELX_AD_OUT5_TO_SLOT_EVEN 0x04
#define AB8500_ADSLOTSELX_AD_OUT6_TO_SLOT_EVEN 0x05
#define AB8500_ADSLOTSELX_AD_OUT7_TO_SLOT_EVEN 0x06
#define AB8500_ADSLOTSELX_AD_OUT8_TO_SLOT_EVEN 0x07
#define AB8500_ADSLOTSELX_ZEROES_TO_SLOT_EVEN 0x08
#define AB8500_ADSLOTSELX_TRISTATE_TO_SLOT_EVEN 0x0F
#define AB8500_ADSLOTSELX_EVEN_SHIFT 0
#define AB8500_ADSLOTSELX_EVEN_SHIFT 0
#define AB8500_ADSLOTSELX_ODD_SHIFT 4
#define AB8500_ADSLOTSELX_ODD_SHIFT 4
#define AB8500_ADSLOTSELX_AD_OUT_TO_SLOT(out, slot) \
((out) << (((slot) & 1) ? \
AB8500_ADSLOTSELX_ODD_SHIFT : AB8500_ADSLOTSELX_EVEN_SHIFT))
/* AB8500_ADSLOTHIZCTRL1 */
/* AB8500_ADSLOTHIZCTRL1 */
/* AB8500_ADSLOTHIZCTRL2 */
/* AB8500_ADSLOTHIZCTRL2 */
...
...
sound/soc/ux500/mop500_ab8500.c
View file @
458bcee9
...
@@ -16,6 +16,7 @@
...
@@ -16,6 +16,7 @@
#include <linux/device.h>
#include <linux/device.h>
#include <linux/io.h>
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/clk.h>
#include <linux/mutex.h>
#include <sound/soc.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>
#include <sound/soc-dapm.h>
...
@@ -24,6 +25,7 @@
...
@@ -24,6 +25,7 @@
#include "ux500_pcm.h"
#include "ux500_pcm.h"
#include "ux500_msp_dai.h"
#include "ux500_msp_dai.h"
#include "mop500_ab8500.h"
#include "../codecs/ab8500-codec.h"
#include "../codecs/ab8500-codec.h"
#define TX_SLOT_MONO 0x0008
#define TX_SLOT_MONO 0x0008
...
@@ -43,6 +45,12 @@
...
@@ -43,6 +45,12 @@
static
unsigned
int
tx_slots
=
DEF_TX_SLOTS
;
static
unsigned
int
tx_slots
=
DEF_TX_SLOTS
;
static
unsigned
int
rx_slots
=
DEF_RX_SLOTS
;
static
unsigned
int
rx_slots
=
DEF_RX_SLOTS
;
/* Configuration consistency parameters */
static
DEFINE_MUTEX
(
mop500_ab8500_params_lock
);
static
unsigned
long
mop500_ab8500_usage
;
static
int
mop500_ab8500_rate
;
static
int
mop500_ab8500_channels
;
/* Clocks */
/* Clocks */
static
const
char
*
const
enum_mclk
[]
=
{
static
const
char
*
const
enum_mclk
[]
=
{
"SYSCLK"
,
"SYSCLK"
,
...
@@ -230,6 +238,21 @@ static int mop500_ab8500_hw_params(struct snd_pcm_substream *substream,
...
@@ -230,6 +238,21 @@ static int mop500_ab8500_hw_params(struct snd_pcm_substream *substream,
substream
->
name
,
substream
->
name
,
substream
->
number
);
substream
->
number
);
/* Ensure configuration consistency between DAIs */
mutex_lock
(
&
mop500_ab8500_params_lock
);
if
(
mop500_ab8500_usage
)
{
if
(
mop500_ab8500_rate
!=
params_rate
(
params
)
||
mop500_ab8500_channels
!=
params_channels
(
params
))
{
mutex_unlock
(
&
mop500_ab8500_params_lock
);
return
-
EBUSY
;
}
}
else
{
mop500_ab8500_rate
=
params_rate
(
params
);
mop500_ab8500_channels
=
params_channels
(
params
);
}
__set_bit
(
cpu_dai
->
id
,
&
mop500_ab8500_usage
);
mutex_unlock
(
&
mop500_ab8500_params_lock
);
channels
=
params_channels
(
params
);
channels
=
params_channels
(
params
);
switch
(
params_format
(
params
))
{
switch
(
params_format
(
params
))
{
...
@@ -328,9 +351,22 @@ static int mop500_ab8500_hw_params(struct snd_pcm_substream *substream,
...
@@ -328,9 +351,22 @@ static int mop500_ab8500_hw_params(struct snd_pcm_substream *substream,
return
0
;
return
0
;
}
}
static
int
mop500_ab8500_hw_free
(
struct
snd_pcm_substream
*
substream
)
{
struct
snd_soc_pcm_runtime
*
rtd
=
substream
->
private_data
;
struct
snd_soc_dai
*
cpu_dai
=
rtd
->
cpu_dai
;
mutex_lock
(
&
mop500_ab8500_params_lock
);
__clear_bit
(
cpu_dai
->
id
,
&
mop500_ab8500_usage
);
mutex_unlock
(
&
mop500_ab8500_params_lock
);
return
0
;
}
struct
snd_soc_ops
mop500_ab8500_ops
[]
=
{
struct
snd_soc_ops
mop500_ab8500_ops
[]
=
{
{
{
.
hw_params
=
mop500_ab8500_hw_params
,
.
hw_params
=
mop500_ab8500_hw_params
,
.
hw_free
=
mop500_ab8500_hw_free
,
.
startup
=
mop500_ab8500_startup
,
.
startup
=
mop500_ab8500_startup
,
.
shutdown
=
mop500_ab8500_shutdown
,
.
shutdown
=
mop500_ab8500_shutdown
,
}
}
...
...
sound/soc/ux500/ux500_msp_dai.c
View file @
458bcee9
...
@@ -658,14 +658,11 @@ static int ux500_msp_dai_probe(struct snd_soc_dai *dai)
...
@@ -658,14 +658,11 @@ static int ux500_msp_dai_probe(struct snd_soc_dai *dai)
{
{
struct
ux500_msp_i2s_drvdata
*
drvdata
=
dev_get_drvdata
(
dai
->
dev
);
struct
ux500_msp_i2s_drvdata
*
drvdata
=
dev_get_drvdata
(
dai
->
dev
);
d
rvdata
->
playback_dma_data
.
dma_cfg
=
drvdata
->
msp
->
dma_cfg_tx
;
d
ai
->
playback_dma_data
=
&
drvdata
->
msp
->
playback_dma_data
;
d
rvdata
->
capture_dma_data
.
dma_cfg
=
drvdata
->
msp
->
dma_cfg_rx
;
d
ai
->
capture_dma_data
=
&
drvdata
->
msp
->
capture_dma_data
;
dai
->
playback_dma_data
=
&
drvdata
->
playback_dma_data
;
drvdata
->
msp
->
playback_dma_data
.
data_size
=
drvdata
->
slot_width
;
dai
->
capture_dma_data
=
&
drvdata
->
capture_dma_data
;
drvdata
->
msp
->
capture_dma_data
.
data_size
=
drvdata
->
slot_width
;
drvdata
->
playback_dma_data
.
data_size
=
drvdata
->
slot_width
;
drvdata
->
capture_dma_data
.
data_size
=
drvdata
->
slot_width
;
return
0
;
return
0
;
}
}
...
...
sound/soc/ux500/ux500_msp_dai.h
View file @
458bcee9
...
@@ -51,15 +51,11 @@ enum ux500_msp_clock_id {
...
@@ -51,15 +51,11 @@ enum ux500_msp_clock_id {
struct
ux500_msp_i2s_drvdata
{
struct
ux500_msp_i2s_drvdata
{
struct
ux500_msp
*
msp
;
struct
ux500_msp
*
msp
;
struct
regulator
*
reg_vape
;
struct
regulator
*
reg_vape
;
struct
ux500_msp_dma_params
playback_dma_data
;
struct
ux500_msp_dma_params
capture_dma_data
;
unsigned
int
fmt
;
unsigned
int
fmt
;
unsigned
int
tx_mask
;
unsigned
int
tx_mask
;
unsigned
int
rx_mask
;
unsigned
int
rx_mask
;
int
slots
;
int
slots
;
int
slot_width
;
int
slot_width
;
u8
configured
;
int
data_delay
;
/* Clocks */
/* Clocks */
unsigned
int
master_clk
;
unsigned
int
master_clk
;
...
...
sound/soc/ux500/ux500_msp_i2s.c
View file @
458bcee9
...
@@ -15,7 +15,6 @@
...
@@ -15,7 +15,6 @@
#include <linux/module.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/platform_device.h>
#include <linux/pinctrl/consumer.h>
#include <linux/delay.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <linux/io.h>
...
@@ -26,9 +25,6 @@
...
@@ -26,9 +25,6 @@
#include "ux500_msp_i2s.h"
#include "ux500_msp_i2s.h"
/* MSP1/3 Tx/Rx usage protection */
static
DEFINE_SPINLOCK
(
msp_rxtx_lock
);
/* Protocol desciptors */
/* Protocol desciptors */
static
const
struct
msp_protdesc
prot_descs
[]
=
{
static
const
struct
msp_protdesc
prot_descs
[]
=
{
{
/* I2S */
{
/* I2S */
...
@@ -356,24 +352,8 @@ static int configure_multichannel(struct ux500_msp *msp,
...
@@ -356,24 +352,8 @@ static int configure_multichannel(struct ux500_msp *msp,
static
int
enable_msp
(
struct
ux500_msp
*
msp
,
struct
ux500_msp_config
*
config
)
static
int
enable_msp
(
struct
ux500_msp
*
msp
,
struct
ux500_msp_config
*
config
)
{
{
int
status
=
0
,
retval
=
0
;
int
status
=
0
;
u32
reg_val_DMACR
,
reg_val_GCR
;
u32
reg_val_DMACR
,
reg_val_GCR
;
unsigned
long
flags
;
/* Check msp state whether in RUN or CONFIGURED Mode */
if
(
msp
->
msp_state
==
MSP_STATE_IDLE
)
{
spin_lock_irqsave
(
&
msp_rxtx_lock
,
flags
);
if
(
msp
->
pinctrl_rxtx_ref
==
0
&&
!
(
IS_ERR
(
msp
->
pinctrl_p
)
||
IS_ERR
(
msp
->
pinctrl_def
)))
{
retval
=
pinctrl_select_state
(
msp
->
pinctrl_p
,
msp
->
pinctrl_def
);
if
(
retval
)
pr_err
(
"could not set MSP defstate
\n
"
);
}
if
(
!
retval
)
msp
->
pinctrl_rxtx_ref
++
;
spin_unlock_irqrestore
(
&
msp_rxtx_lock
,
flags
);
}
/* Configure msp with protocol dependent settings */
/* Configure msp with protocol dependent settings */
configure_protocol
(
msp
,
config
);
configure_protocol
(
msp
,
config
);
...
@@ -387,12 +367,14 @@ static int enable_msp(struct ux500_msp *msp, struct ux500_msp_config *config)
...
@@ -387,12 +367,14 @@ static int enable_msp(struct ux500_msp *msp, struct ux500_msp_config *config)
}
}
/* Make sure the correct DMA-directions are configured */
/* Make sure the correct DMA-directions are configured */
if
((
config
->
direction
&
MSP_DIR_RX
)
&&
(
!
msp
->
dma_cfg_rx
))
{
if
((
config
->
direction
&
MSP_DIR_RX
)
&&
!
msp
->
capture_dma_data
.
dma_cfg
)
{
dev_err
(
msp
->
dev
,
"%s: ERROR: MSP RX-mode is not configured!"
,
dev_err
(
msp
->
dev
,
"%s: ERROR: MSP RX-mode is not configured!"
,
__func__
);
__func__
);
return
-
EINVAL
;
return
-
EINVAL
;
}
}
if
((
config
->
direction
==
MSP_DIR_TX
)
&&
(
!
msp
->
dma_cfg_tx
))
{
if
((
config
->
direction
==
MSP_DIR_TX
)
&&
!
msp
->
playback_dma_data
.
dma_cfg
)
{
dev_err
(
msp
->
dev
,
"%s: ERROR: MSP TX-mode is not configured!"
,
dev_err
(
msp
->
dev
,
"%s: ERROR: MSP TX-mode is not configured!"
,
__func__
);
__func__
);
return
-
EINVAL
;
return
-
EINVAL
;
...
@@ -630,8 +612,7 @@ int ux500_msp_i2s_trigger(struct ux500_msp *msp, int cmd, int direction)
...
@@ -630,8 +612,7 @@ int ux500_msp_i2s_trigger(struct ux500_msp *msp, int cmd, int direction)
int
ux500_msp_i2s_close
(
struct
ux500_msp
*
msp
,
unsigned
int
dir
)
int
ux500_msp_i2s_close
(
struct
ux500_msp
*
msp
,
unsigned
int
dir
)
{
{
int
status
=
0
,
retval
=
0
;
int
status
=
0
;
unsigned
long
flags
;
dev_dbg
(
msp
->
dev
,
"%s: Enter (dir = 0x%01x).
\n
"
,
__func__
,
dir
);
dev_dbg
(
msp
->
dev
,
"%s: Enter (dir = 0x%01x).
\n
"
,
__func__
,
dir
);
...
@@ -643,18 +624,6 @@ int ux500_msp_i2s_close(struct ux500_msp *msp, unsigned int dir)
...
@@ -643,18 +624,6 @@ int ux500_msp_i2s_close(struct ux500_msp *msp, unsigned int dir)
(
~
(
FRAME_GEN_ENABLE
|
SRG_ENABLE
))),
(
~
(
FRAME_GEN_ENABLE
|
SRG_ENABLE
))),
msp
->
registers
+
MSP_GCR
);
msp
->
registers
+
MSP_GCR
);
spin_lock_irqsave
(
&
msp_rxtx_lock
,
flags
);
WARN_ON
(
!
msp
->
pinctrl_rxtx_ref
);
msp
->
pinctrl_rxtx_ref
--
;
if
(
msp
->
pinctrl_rxtx_ref
==
0
&&
!
(
IS_ERR
(
msp
->
pinctrl_p
)
||
IS_ERR
(
msp
->
pinctrl_sleep
)))
{
retval
=
pinctrl_select_state
(
msp
->
pinctrl_p
,
msp
->
pinctrl_sleep
);
if
(
retval
)
pr_err
(
"could not set MSP sleepstate
\n
"
);
}
spin_unlock_irqrestore
(
&
msp_rxtx_lock
,
flags
);
writel
(
0
,
msp
->
registers
+
MSP_GCR
);
writel
(
0
,
msp
->
registers
+
MSP_GCR
);
writel
(
0
,
msp
->
registers
+
MSP_TCF
);
writel
(
0
,
msp
->
registers
+
MSP_TCF
);
writel
(
0
,
msp
->
registers
+
MSP_RCF
);
writel
(
0
,
msp
->
registers
+
MSP_RCF
);
...
@@ -682,7 +651,6 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,
...
@@ -682,7 +651,6 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,
struct
msp_i2s_platform_data
*
platform_data
)
struct
msp_i2s_platform_data
*
platform_data
)
{
{
struct
resource
*
res
=
NULL
;
struct
resource
*
res
=
NULL
;
struct
i2s_controller
*
i2s_cont
;
struct
device_node
*
np
=
pdev
->
dev
.
of_node
;
struct
device_node
*
np
=
pdev
->
dev
.
of_node
;
struct
ux500_msp
*
msp
;
struct
ux500_msp
*
msp
;
...
@@ -707,8 +675,8 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,
...
@@ -707,8 +675,8 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,
msp
->
id
=
platform_data
->
id
;
msp
->
id
=
platform_data
->
id
;
msp
->
dev
=
&
pdev
->
dev
;
msp
->
dev
=
&
pdev
->
dev
;
msp
->
dma_cfg_rx
=
platform_data
->
msp_i2s_dma_r
x
;
msp
->
playback_dma_data
.
dma_cfg
=
platform_data
->
msp_i2s_dma_t
x
;
msp
->
dma_cfg_tx
=
platform_data
->
msp_i2s_dma_t
x
;
msp
->
capture_dma_data
.
dma_cfg
=
platform_data
->
msp_i2s_dma_r
x
;
res
=
platform_get_resource
(
pdev
,
IORESOURCE_MEM
,
0
);
res
=
platform_get_resource
(
pdev
,
IORESOURCE_MEM
,
0
);
if
(
res
==
NULL
)
{
if
(
res
==
NULL
)
{
...
@@ -717,6 +685,9 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,
...
@@ -717,6 +685,9 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,
return
-
ENOMEM
;
return
-
ENOMEM
;
}
}
msp
->
playback_dma_data
.
tx_rx_addr
=
res
->
start
+
MSP_DR
;
msp
->
capture_dma_data
.
tx_rx_addr
=
res
->
start
+
MSP_DR
;
msp
->
registers
=
devm_ioremap
(
&
pdev
->
dev
,
res
->
start
,
msp
->
registers
=
devm_ioremap
(
&
pdev
->
dev
,
res
->
start
,
resource_size
(
res
));
resource_size
(
res
));
if
(
msp
->
registers
==
NULL
)
{
if
(
msp
->
registers
==
NULL
)
{
...
@@ -727,41 +698,6 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,
...
@@ -727,41 +698,6 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,
msp
->
msp_state
=
MSP_STATE_IDLE
;
msp
->
msp_state
=
MSP_STATE_IDLE
;
msp
->
loopback_enable
=
0
;
msp
->
loopback_enable
=
0
;
/* I2S-controller is allocated and added in I2S controller class. */
i2s_cont
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
i2s_cont
),
GFP_KERNEL
);
if
(
!
i2s_cont
)
{
dev_err
(
&
pdev
->
dev
,
"%s: ERROR: Failed to allocate I2S-controller!
\n
"
,
__func__
);
return
-
ENOMEM
;
}
i2s_cont
->
dev
.
parent
=
&
pdev
->
dev
;
i2s_cont
->
data
=
(
void
*
)
msp
;
i2s_cont
->
id
=
(
s16
)
msp
->
id
;
snprintf
(
i2s_cont
->
name
,
sizeof
(
i2s_cont
->
name
),
"ux500-msp-i2s.%04x"
,
msp
->
id
);
dev_dbg
(
&
pdev
->
dev
,
"I2S device-name: '%s'
\n
"
,
i2s_cont
->
name
);
msp
->
i2s_cont
=
i2s_cont
;
msp
->
pinctrl_p
=
pinctrl_get
(
msp
->
dev
);
if
(
IS_ERR
(
msp
->
pinctrl_p
))
dev_err
(
&
pdev
->
dev
,
"could not get MSP pinctrl
\n
"
);
else
{
msp
->
pinctrl_def
=
pinctrl_lookup_state
(
msp
->
pinctrl_p
,
PINCTRL_STATE_DEFAULT
);
if
(
IS_ERR
(
msp
->
pinctrl_def
))
{
dev_err
(
&
pdev
->
dev
,
"could not get MSP defstate (%li)
\n
"
,
PTR_ERR
(
msp
->
pinctrl_def
));
}
msp
->
pinctrl_sleep
=
pinctrl_lookup_state
(
msp
->
pinctrl_p
,
PINCTRL_STATE_SLEEP
);
if
(
IS_ERR
(
msp
->
pinctrl_sleep
))
dev_err
(
&
pdev
->
dev
,
"could not get MSP idlestate (%li)
\n
"
,
PTR_ERR
(
msp
->
pinctrl_def
));
}
return
0
;
return
0
;
}
}
...
@@ -769,8 +705,6 @@ void ux500_msp_i2s_cleanup_msp(struct platform_device *pdev,
...
@@ -769,8 +705,6 @@ void ux500_msp_i2s_cleanup_msp(struct platform_device *pdev,
struct
ux500_msp
*
msp
)
struct
ux500_msp
*
msp
)
{
{
dev_dbg
(
msp
->
dev
,
"%s: Enter (id = %d).
\n
"
,
__func__
,
msp
->
id
);
dev_dbg
(
msp
->
dev
,
"%s: Enter (id = %d).
\n
"
,
__func__
,
msp
->
id
);
device_unregister
(
&
msp
->
i2s_cont
->
dev
);
}
}
MODULE_LICENSE
(
"GPL v2"
);
MODULE_LICENSE
(
"GPL v2"
);
sound/soc/ux500/ux500_msp_i2s.h
View file @
458bcee9
...
@@ -16,6 +16,7 @@
...
@@ -16,6 +16,7 @@
#define UX500_MSP_I2S_H
#define UX500_MSP_I2S_H
#include <linux/platform_device.h>
#include <linux/platform_device.h>
#include <linux/platform_data/asoc-ux500-msp.h>
#define MSP_INPUT_FREQ_APB 48000000
#define MSP_INPUT_FREQ_APB 48000000
...
@@ -341,11 +342,6 @@ enum msp_compress_mode {
...
@@ -341,11 +342,6 @@ enum msp_compress_mode {
MSP_COMPRESS_MODE_A_LAW
=
3
MSP_COMPRESS_MODE_A_LAW
=
3
};
};
enum
msp_spi_burst_mode
{
MSP_SPI_BURST_MODE_DISABLE
=
0
,
MSP_SPI_BURST_MODE_ENABLE
=
1
};
enum
msp_expand_mode
{
enum
msp_expand_mode
{
MSP_EXPAND_MODE_LINEAR
=
0
,
MSP_EXPAND_MODE_LINEAR
=
0
,
MSP_EXPAND_MODE_LINEAR_SIGNED
=
1
,
MSP_EXPAND_MODE_LINEAR_SIGNED
=
1
,
...
@@ -370,13 +366,6 @@ enum msp_protocol {
...
@@ -370,13 +366,6 @@ enum msp_protocol {
*/
*/
#define MAX_MSP_BACKUP_REGS 36
#define MAX_MSP_BACKUP_REGS 36
enum
enum_i2s_controller
{
MSP_0_I2S_CONTROLLER
=
0
,
MSP_1_I2S_CONTROLLER
,
MSP_2_I2S_CONTROLLER
,
MSP_3_I2S_CONTROLLER
,
};
enum
i2s_direction_t
{
enum
i2s_direction_t
{
MSP_DIR_TX
=
0x01
,
MSP_DIR_TX
=
0x01
,
MSP_DIR_RX
=
0x02
,
MSP_DIR_RX
=
0x02
,
...
@@ -454,32 +443,6 @@ struct msp_protdesc {
...
@@ -454,32 +443,6 @@ struct msp_protdesc {
u32
clocks_per_frame
;
u32
clocks_per_frame
;
};
};
struct
i2s_message
{
enum
i2s_direction_t
i2s_direction
;
void
*
txdata
;
void
*
rxdata
;
size_t
txbytes
;
size_t
rxbytes
;
int
dma_flag
;
int
tx_offset
;
int
rx_offset
;
bool
cyclic_dma
;
dma_addr_t
buf_addr
;
size_t
buf_len
;
size_t
period_len
;
};
struct
i2s_controller
{
struct
module
*
owner
;
unsigned
int
id
;
unsigned
int
class
;
const
struct
i2s_algorithm
*
algo
;
/* the algorithm to access the bus */
void
*
data
;
struct
mutex
bus_lock
;
struct
device
dev
;
/* the controller device */
char
name
[
48
];
};
struct
ux500_msp_config
{
struct
ux500_msp_config
{
unsigned
int
f_inputclk
;
unsigned
int
f_inputclk
;
unsigned
int
rx_clk_sel
;
unsigned
int
rx_clk_sel
;
...
@@ -491,8 +454,6 @@ struct ux500_msp_config {
...
@@ -491,8 +454,6 @@ struct ux500_msp_config {
unsigned
int
tx_fsync_sel
;
unsigned
int
tx_fsync_sel
;
unsigned
int
rx_fifo_config
;
unsigned
int
rx_fifo_config
;
unsigned
int
tx_fifo_config
;
unsigned
int
tx_fifo_config
;
unsigned
int
spi_clk_mode
;
unsigned
int
spi_burst_mode
;
unsigned
int
loopback_enable
;
unsigned
int
loopback_enable
;
unsigned
int
tx_data_enable
;
unsigned
int
tx_data_enable
;
unsigned
int
default_protdesc
;
unsigned
int
default_protdesc
;
...
@@ -502,43 +463,28 @@ struct ux500_msp_config {
...
@@ -502,43 +463,28 @@ struct ux500_msp_config {
unsigned
int
direction
;
unsigned
int
direction
;
unsigned
int
protocol
;
unsigned
int
protocol
;
unsigned
int
frame_freq
;
unsigned
int
frame_freq
;
unsigned
int
frame_size
;
enum
msp_data_size
data_size
;
enum
msp_data_size
data_size
;
unsigned
int
def_elem_len
;
unsigned
int
def_elem_len
;
unsigned
int
iodelay
;
unsigned
int
iodelay
;
void
(
*
handler
)
(
void
*
data
);
};
void
*
tx_callback_data
;
void
*
rx_callback_data
;
struct
ux500_msp_dma_params
{
unsigned
int
data_size
;
dma_addr_t
tx_rx_addr
;
struct
stedma40_chan_cfg
*
dma_cfg
;
};
};
struct
ux500_msp
{
struct
ux500_msp
{
enum
enum_i2s_controller
id
;
enum
msp_i2s_id
id
;
void
__iomem
*
registers
;
void
__iomem
*
registers
;
struct
device
*
dev
;
struct
device
*
dev
;
struct
i2s_controller
*
i2s_cont
;
struct
ux500_msp_dma_params
playback_dma_data
;
struct
stedma40_chan_cfg
*
dma_cfg_rx
;
struct
ux500_msp_dma_params
capture_dma_data
;
struct
stedma40_chan_cfg
*
dma_cfg_tx
;
struct
dma_chan
*
tx_pipeid
;
struct
dma_chan
*
rx_pipeid
;
enum
msp_state
msp_state
;
enum
msp_state
msp_state
;
int
(
*
transfer
)
(
struct
ux500_msp
*
msp
,
struct
i2s_message
*
message
);
struct
timer_list
notify_timer
;
int
def_elem_len
;
int
def_elem_len
;
unsigned
int
dir_busy
;
unsigned
int
dir_busy
;
int
loopback_enable
;
int
loopback_enable
;
u32
backup_regs
[
MAX_MSP_BACKUP_REGS
];
unsigned
int
f_bitclk
;
unsigned
int
f_bitclk
;
/* Pin modes */
struct
pinctrl
*
pinctrl_p
;
struct
pinctrl_state
*
pinctrl_def
;
struct
pinctrl_state
*
pinctrl_sleep
;
/* Reference Count */
int
pinctrl_rxtx_ref
;
};
struct
ux500_msp_dma_params
{
unsigned
int
data_size
;
struct
stedma40_chan_cfg
*
dma_cfg
;
};
};
struct
msp_i2s_platform_data
;
struct
msp_i2s_platform_data
;
...
...
sound/soc/ux500/ux500_pcm.c
View file @
458bcee9
...
@@ -103,10 +103,40 @@ static struct dma_chan *ux500_pcm_request_chan(struct snd_soc_pcm_runtime *rtd,
...
@@ -103,10 +103,40 @@ static struct dma_chan *ux500_pcm_request_chan(struct snd_soc_pcm_runtime *rtd,
return
snd_dmaengine_pcm_request_channel
(
stedma40_filter
,
dma_cfg
);
return
snd_dmaengine_pcm_request_channel
(
stedma40_filter
,
dma_cfg
);
}
}
static
int
ux500_pcm_prepare_slave_config
(
struct
snd_pcm_substream
*
substream
,
struct
snd_pcm_hw_params
*
params
,
struct
dma_slave_config
*
slave_config
)
{
struct
snd_soc_pcm_runtime
*
rtd
=
substream
->
private_data
;
struct
ux500_msp_dma_params
*
dma_params
;
struct
stedma40_chan_cfg
*
dma_cfg
;
int
ret
;
dma_params
=
snd_soc_dai_get_dma_data
(
rtd
->
cpu_dai
,
substream
);
dma_cfg
=
dma_params
->
dma_cfg
;
ret
=
snd_hwparams_to_dma_slave_config
(
substream
,
params
,
slave_config
);
if
(
ret
)
return
ret
;
slave_config
->
dst_maxburst
=
4
;
slave_config
->
dst_addr_width
=
dma_cfg
->
dst_info
.
data_width
;
slave_config
->
src_maxburst
=
4
;
slave_config
->
src_addr_width
=
dma_cfg
->
src_info
.
data_width
;
if
(
substream
->
stream
==
SNDRV_PCM_STREAM_PLAYBACK
)
slave_config
->
dst_addr
=
dma_params
->
tx_rx_addr
;
else
slave_config
->
src_addr
=
dma_params
->
tx_rx_addr
;
return
0
;
}
static
const
struct
snd_dmaengine_pcm_config
ux500_dmaengine_pcm_config
=
{
static
const
struct
snd_dmaengine_pcm_config
ux500_dmaengine_pcm_config
=
{
.
pcm_hardware
=
&
ux500_pcm_hw
,
.
pcm_hardware
=
&
ux500_pcm_hw
,
.
compat_request_channel
=
ux500_pcm_request_chan
,
.
compat_request_channel
=
ux500_pcm_request_chan
,
.
prealloc_buffer_size
=
128
*
1024
,
.
prealloc_buffer_size
=
128
*
1024
,
.
prepare_slave_config
=
ux500_pcm_prepare_slave_config
,
};
};
int
ux500_pcm_register_platform
(
struct
platform_device
*
pdev
)
int
ux500_pcm_register_platform
(
struct
platform_device
*
pdev
)
...
...
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