summaryrefslogtreecommitdiff
path: root/sound/soc/sh/rcar
diff options
context:
space:
mode:
authorOlof Johansson <olof@lixom.net>2019-12-05 13:16:58 -0800
committerOlof Johansson <olof@lixom.net>2019-12-05 13:18:54 -0800
commit942e6f8a8314e5550e254519dfba4ccd5170421d (patch)
tree75ec655b440fbc1c454247af38b5596dd8c78de9 /sound/soc/sh/rcar
parent336bab731be76a90291697e51d2aed0ad67d7cb5 (diff)
parentb08baef02b26cf7c2123e4a24a2fa1fb7a593ffb (diff)
Merge mainline/master into arm/fixes
This brings in the mainline tree right after armsoc contents was merged this release cycle, so that we can re-run savedefconfig, etc. Signed-off-by: Olof Johansson <olof@lixom.net>
Diffstat (limited to 'sound/soc/sh/rcar')
-rw-r--r--sound/soc/sh/rcar/core.c55
-rw-r--r--sound/soc/sh/rcar/dma.c34
2 files changed, 69 insertions, 20 deletions
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index bda5b958d0dc..399dc6e9bde5 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -302,7 +302,7 @@ int rsnd_runtime_channel_after_ctu_with_params(struct rsnd_dai_stream *io,
int rsnd_channel_normalization(int chan)
{
- if ((chan > 8) || (chan < 0))
+ if (WARN_ON((chan > 8) || (chan < 0)))
return 0;
/* TDM Extend Mode needs 8ch */
@@ -376,6 +376,17 @@ u32 rsnd_get_adinr_bit(struct rsnd_mod *mod, struct rsnd_dai_stream *io)
*/
u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io)
{
+ static const u32 dalign_values[8][2] = {
+ {0x76543210, 0x67452301},
+ {0x00000032, 0x00000023},
+ {0x00007654, 0x00006745},
+ {0x00000076, 0x00000067},
+ {0xfedcba98, 0xefcdab89},
+ {0x000000ba, 0x000000ab},
+ {0x0000fedc, 0x0000efcd},
+ {0x000000fe, 0x000000ef},
+ };
+ int id = 0, inv;
struct rsnd_mod *ssiu = rsnd_io_to_mod_ssiu(io);
struct rsnd_mod *target;
struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
@@ -411,13 +422,18 @@ u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io)
target = cmd ? cmd : ssiu;
}
+ if (mod == ssiu)
+ id = rsnd_mod_id_sub(mod);
+
/* Non target mod or non 16bit needs normal DALIGN */
if ((snd_pcm_format_width(runtime->format) != 16) ||
(mod != target))
- return 0x76543210;
+ inv = 0;
/* Target mod needs inverted DALIGN when 16bit */
else
- return 0x67452301;
+ inv = 1;
+
+ return dalign_values[id][inv];
}
u32 rsnd_get_busif_shift(struct rsnd_dai_stream *io, struct rsnd_mod *mod)
@@ -761,6 +777,7 @@ static int rsnd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
}
/* set format */
+ rdai->bit_clk_inv = 0;
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
case SND_SOC_DAIFMT_I2S:
rdai->sys_delay = 0;
@@ -1075,7 +1092,10 @@ static void rsnd_parse_tdm_split_mode(struct rsnd_priv *priv,
j++;
}
+ of_node_put(node);
}
+
+ of_node_put(ssiu_np);
}
static void rsnd_parse_connect_simple(struct rsnd_priv *priv,
@@ -1093,11 +1113,13 @@ static void rsnd_parse_connect_graph(struct rsnd_priv *priv,
struct device_node *endpoint)
{
struct device *dev = rsnd_priv_to_dev(priv);
- struct device_node *remote_node = of_graph_get_remote_port_parent(endpoint);
+ struct device_node *remote_node;
if (!rsnd_io_to_mod_ssi(io))
return;
+ remote_node = of_graph_get_remote_port_parent(endpoint);
+
/* HDMI0 */
if (strstr(remote_node->full_name, "hdmi@fead0000")) {
rsnd_flags_set(io, RSND_STREAM_HDMI0);
@@ -1111,6 +1133,8 @@ static void rsnd_parse_connect_graph(struct rsnd_priv *priv,
}
rsnd_parse_tdm_split_mode(priv, io, endpoint);
+
+ of_node_put(remote_node);
}
void rsnd_parse_connect_common(struct rsnd_dai *rdai,
@@ -1373,8 +1397,9 @@ static int rsnd_dai_probe(struct rsnd_priv *priv)
/*
* pcm ops
*/
-static int rsnd_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
+static int rsnd_hw_params(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *hw_params)
{
struct snd_soc_dai *dai = rsnd_substream_to_dai(substream);
struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai);
@@ -1421,7 +1446,8 @@ static int rsnd_hw_params(struct snd_pcm_substream *substream,
params_buffer_bytes(hw_params));
}
-static int rsnd_hw_free(struct snd_pcm_substream *substream)
+static int rsnd_hw_free(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream)
{
struct snd_soc_dai *dai = rsnd_substream_to_dai(substream);
struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai);
@@ -1435,7 +1461,8 @@ static int rsnd_hw_free(struct snd_pcm_substream *substream)
return snd_pcm_lib_free_pages(substream);
}
-static snd_pcm_uframes_t rsnd_pointer(struct snd_pcm_substream *substream)
+static snd_pcm_uframes_t rsnd_pointer(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream)
{
struct snd_soc_dai *dai = rsnd_substream_to_dai(substream);
struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai);
@@ -1447,13 +1474,6 @@ static snd_pcm_uframes_t rsnd_pointer(struct snd_pcm_substream *substream)
return pointer;
}
-static const struct snd_pcm_ops rsnd_pcm_ops = {
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = rsnd_hw_params,
- .hw_free = rsnd_hw_free,
- .pointer = rsnd_pointer,
-};
-
/*
* snd_kcontrol
*/
@@ -1647,8 +1667,11 @@ int rsnd_kctrl_new(struct rsnd_mod *mod,
* snd_soc_component
*/
static const struct snd_soc_component_driver rsnd_soc_component = {
- .ops = &rsnd_pcm_ops,
.name = "rsnd",
+ .ioctl = snd_soc_pcm_lib_ioctl,
+ .hw_params = rsnd_hw_params,
+ .hw_free = rsnd_hw_free,
+ .pointer = rsnd_pointer,
};
static int rsnd_rdai_continuance_probe(struct rsnd_priv *priv,
diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c
index 0324a5c39619..95aa26d62e4f 100644
--- a/sound/soc/sh/rcar/dma.c
+++ b/sound/soc/sh/rcar/dma.c
@@ -165,14 +165,40 @@ static int rsnd_dmaen_start(struct rsnd_mod *mod,
struct device *dev = rsnd_priv_to_dev(priv);
struct dma_async_tx_descriptor *desc;
struct dma_slave_config cfg = {};
+ enum dma_slave_buswidth buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
int is_play = rsnd_io_is_play(io);
int ret;
+ /*
+ * in case of monaural data writing or reading through Audio-DMAC
+ * data is always in Left Justified format, so both src and dst
+ * DMA Bus width need to be set equal to physical data width.
+ */
+ if (rsnd_runtime_channel_original(io) == 1) {
+ struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
+ int bits = snd_pcm_format_physical_width(runtime->format);
+
+ switch (bits) {
+ case 8:
+ buswidth = DMA_SLAVE_BUSWIDTH_1_BYTE;
+ break;
+ case 16:
+ buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;
+ break;
+ case 32:
+ buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
+ break;
+ default:
+ dev_err(dev, "invalid format width %d\n", bits);
+ return -EINVAL;
+ }
+ }
+
cfg.direction = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM;
cfg.src_addr = dma->src_addr;
cfg.dst_addr = dma->dst_addr;
- cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
- cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+ cfg.src_addr_width = buswidth;
+ cfg.dst_addr_width = buswidth;
dev_dbg(dev, "%s %pad -> %pad\n",
rsnd_mod_name(mod),
@@ -508,10 +534,10 @@ static struct rsnd_mod_ops rsnd_dmapp_ops = {
#define RDMA_SSI_I_N(addr, i) (addr ##_reg - 0x00300000 + (0x40 * i) + 0x8)
#define RDMA_SSI_O_N(addr, i) (addr ##_reg - 0x00300000 + (0x40 * i) + 0xc)
-#define RDMA_SSIU_I_N(addr, i, j) (addr ##_reg - 0x00441000 + (0x1000 * (i)) + (((j) / 4) * 0xA000) + (((j) % 4) * 0x400))
+#define RDMA_SSIU_I_N(addr, i, j) (addr ##_reg - 0x00441000 + (0x1000 * (i)) + (((j) / 4) * 0xA000) + (((j) % 4) * 0x400) - (0x4000 * ((i) / 9) * ((j) / 4)))
#define RDMA_SSIU_O_N(addr, i, j) RDMA_SSIU_I_N(addr, i, j)
-#define RDMA_SSIU_I_P(addr, i, j) (addr ##_reg - 0x00141000 + (0x1000 * (i)) + (((j) / 4) * 0xA000) + (((j) % 4) * 0x400))
+#define RDMA_SSIU_I_P(addr, i, j) (addr ##_reg - 0x00141000 + (0x1000 * (i)) + (((j) / 4) * 0xA000) + (((j) % 4) * 0x400) - (0x4000 * ((i) / 9) * ((j) / 4)))
#define RDMA_SSIU_O_P(addr, i, j) RDMA_SSIU_I_P(addr, i, j)
#define RDMA_SRC_I_N(addr, i) (addr ##_reg - 0x00500000 + (0x400 * i))