Skip to content

Commit

Permalink
Merge remote-tracking branches 'asoc/topic/omap' and 'asoc/topic/rcar…
Browse files Browse the repository at this point in the history
…' into asoc-next
  • Loading branch information
Mark Brown committed Jun 3, 2014
3 parents b12a190 + 87c1936 + ad32d0c commit 440a528
Show file tree
Hide file tree
Showing 13 changed files with 265 additions and 36 deletions.
1 change: 1 addition & 0 deletions Documentation/devicetree/bindings/sound/renesas,rsnd.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Required properties:
SSI subnode properties:
- interrupts : Should contain SSI interrupt for PIO transfer
- shared-pin : if shared clock pin
- pio-transfer : use PIO transfer mode

SRC subnode properties:
no properties at this point
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion sound/soc/davinci/davinci-mcasp.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@
#include <sound/initval.h>
#include <sound/soc.h>
#include <sound/dmaengine_pcm.h>
#include <sound/omap-pcm.h>

#include "davinci-pcm.h"
#include "davinci-mcasp.h"
#include "../omap/omap-pcm.h"

#define MCASP_MAX_AFIFO_DEPTH 64

Expand Down
2 changes: 1 addition & 1 deletion sound/soc/omap/omap-dmic.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@
#include <sound/initval.h>
#include <sound/soc.h>
#include <sound/dmaengine_pcm.h>
#include <sound/omap-pcm.h>

#include "omap-dmic.h"
#include "omap-pcm.h"

struct omap_dmic {
struct device *dev;
Expand Down
2 changes: 1 addition & 1 deletion sound/soc/omap/omap-hdmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@
#include <sound/asoundef.h>
#include <sound/dmaengine_pcm.h>
#include <video/omapdss.h>
#include <sound/omap-pcm.h>

#include "omap-hdmi.h"
#include "omap-pcm.h"

#define DRV_NAME "omap-hdmi-audio-dai"

Expand Down
2 changes: 1 addition & 1 deletion sound/soc/omap/omap-mcbsp.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@
#include <sound/initval.h>
#include <sound/soc.h>
#include <sound/dmaengine_pcm.h>
#include <sound/omap-pcm.h>

#include <linux/platform_data/asoc-ti-mcbsp.h>
#include "mcbsp.h"
#include "omap-mcbsp.h"
#include "omap-pcm.h"

#define OMAP_MCBSP_RATES (SNDRV_PCM_RATE_8000_96000)

Expand Down
2 changes: 1 addition & 1 deletion sound/soc/omap/omap-mcpdm.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/dmaengine_pcm.h>
#include <sound/omap-pcm.h>

#include "omap-mcpdm.h"
#include "omap-pcm.h"

struct mcpdm_link_config {
u32 link_mask; /* channel mask for the direction */
Expand Down
87 changes: 81 additions & 6 deletions sound/soc/sh/rcar/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -255,11 +255,81 @@ int rsnd_dma_available(struct rsnd_dma *dma)
return !!dma->chan;
}

#define DMA_NAME_SIZE 16
#define MOD_MAX 4 /* MEM/SSI/SRC/DVC */
static int _rsnd_dma_of_name(char *dma_name, struct rsnd_mod *mod)
{
if (mod)
return snprintf(dma_name, DMA_NAME_SIZE / 2, "%s%d",
rsnd_mod_name(mod), rsnd_mod_id(mod));
else
return snprintf(dma_name, DMA_NAME_SIZE / 2, "mem");

}

static void rsnd_dma_of_name(struct rsnd_dma *dma,
int is_play, char *dma_name)
{
struct rsnd_mod *this = rsnd_dma_to_mod(dma);
struct rsnd_dai_stream *io = rsnd_mod_to_io(this);
struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io);
struct rsnd_mod *src = rsnd_io_to_mod_src(io);
struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io);
struct rsnd_mod *mod[MOD_MAX];
struct rsnd_mod *src_mod, *dst_mod;
int i, index;


for (i = 0; i < MOD_MAX; i++)
mod[i] = NULL;

/*
* in play case...
*
* src -> dst
*
* mem -> SSI
* mem -> SRC -> SSI
* mem -> SRC -> DVC -> SSI
*/
mod[0] = NULL; /* for "mem" */
index = 1;
for (i = 1; i < MOD_MAX; i++) {
if (!src) {
mod[i] = ssi;
break;
} else if (!dvc) {
mod[i] = src;
src = NULL;
} else {
mod[i] = dvc;
dvc = NULL;
}

if (mod[i] == this)
index = i;
}

if (is_play) {
src_mod = mod[index - 1];
dst_mod = mod[index];
} else {
src_mod = mod[index];
dst_mod = mod[index + 1];
}

index = 0;
index = _rsnd_dma_of_name(dma_name + index, src_mod);
*(dma_name + index++) = '_';
index = _rsnd_dma_of_name(dma_name + index, dst_mod);
}

int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma,
int is_play, int id)
{
struct device *dev = rsnd_priv_to_dev(priv);
struct dma_slave_config cfg;
char dma_name[DMA_NAME_SIZE];
dma_cap_mask_t mask;
int ret;

Expand All @@ -271,18 +341,23 @@ int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma,
dma_cap_zero(mask);
dma_cap_set(DMA_SLAVE, mask);

if (dev->of_node)
rsnd_dma_of_name(dma, is_play, dma_name);
else
snprintf(dma_name, DMA_NAME_SIZE,
is_play ? "tx" : "rx");

dev_dbg(dev, "dma name : %s\n", dma_name);

dma->chan = dma_request_slave_channel_compat(mask, shdma_chan_filter,
(void *)id, dev,
is_play ? "tx" : "rx");
dma_name);
if (!dma->chan) {
dev_err(dev, "can't get dma channel\n");
return -EIO;
}

cfg.slave_id = id;
cfg.dst_addr = 0; /* use default addr when playback */
cfg.src_addr = 0; /* use default addr when capture */
cfg.direction = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM;
rsnd_gen_dma_addr(priv, dma, &cfg, is_play, id);

ret = dmaengine_slave_config(dma->chan, &cfg);
if (ret < 0)
Expand Down Expand Up @@ -956,7 +1031,7 @@ static int rsnd_probe(struct platform_device *pdev)
return -ENODEV;
}

priv->dev = dev;
priv->pdev = pdev;
priv->info = info;
spin_lock_init(&priv->lock);

Expand Down
20 changes: 18 additions & 2 deletions sound/soc/sh/rcar/dvc.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
#define RSND_DVC_NAME_SIZE 16
#define RSND_DVC_VOLUME_MAX 100
#define RSND_DVC_VOLUME_NUM 2

#define DVC_NAME "dvc"

struct rsnd_dvc {
struct rsnd_dvc_platform_info *info; /* rcar_snd.h */
struct rsnd_mod mod;
Expand Down Expand Up @@ -43,6 +46,17 @@ static void rsnd_dvc_volume_update(struct rsnd_mod *mod)
rsnd_mod_write(mod, DVC_VOL1R, vol[1]);
}

static int rsnd_dvc_probe_gen2(struct rsnd_mod *mod,
struct rsnd_dai *rdai)
{
struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
struct device *dev = rsnd_priv_to_dev(priv);

dev_dbg(dev, "%s (Gen2) is probed\n", rsnd_mod_name(mod));

return 0;
}

static int rsnd_dvc_init(struct rsnd_mod *dvc_mod,
struct rsnd_dai *rdai)
{
Expand Down Expand Up @@ -208,7 +222,8 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod,
}

static struct rsnd_mod_ops rsnd_dvc_ops = {
.name = "dvc (gen2)",
.name = DVC_NAME,
.probe = rsnd_dvc_probe_gen2,
.init = rsnd_dvc_init,
.quit = rsnd_dvc_quit,
.start = rsnd_dvc_start,
Expand Down Expand Up @@ -255,7 +270,8 @@ int rsnd_dvc_probe(struct platform_device *pdev,
priv->dvc = dvc;

for_each_rsnd_dvc(dvc, priv, i) {
snprintf(name, RSND_DVC_NAME_SIZE, "dvc.%d", i);
snprintf(name, RSND_DVC_NAME_SIZE, "%s.%d",
DVC_NAME, i);

clk = devm_clk_get(dev, name);
if (IS_ERR(clk))
Expand Down
95 changes: 95 additions & 0 deletions sound/soc/sh/rcar/gen.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,101 @@ static int rsnd_gen_regmap_init(struct rsnd_priv *priv,
return 0;
}

/*
* DMA read/write register offset
*
* RSND_xxx_I_N for Audio DMAC input
* RSND_xxx_O_N for Audio DMAC output
* RSND_xxx_I_P for Audio DMAC peri peri input
* RSND_xxx_O_P for Audio DMAC peri peri output
*
* ex) R-Car H2 case
* mod / DMAC in / DMAC out / DMAC PP in / DMAC pp out
* SSI : 0xec541000 / 0xec241008 / 0xec24100c / 0xec400000 / 0xec400000
* SCU : 0xec500000 / 0xec000000 / 0xec004000 / 0xec300000 / 0xec304000
* CMD : 0xec500000 / 0xec008000 0xec308000
*/
#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_SSI_I_P(addr, i) (addr ##_reg - 0x00141000 + (0x1000 * i))
#define RDMA_SSI_O_P(addr, i) (addr ##_reg - 0x00141000 + (0x1000 * i))

#define RDMA_SRC_I_N(addr, i) (addr ##_reg - 0x00500000 + (0x400 * i))
#define RDMA_SRC_O_N(addr, i) (addr ##_reg - 0x004fc000 + (0x400 * i))

#define RDMA_SRC_I_P(addr, i) (addr ##_reg - 0x00200000 + (0x400 * i))
#define RDMA_SRC_O_P(addr, i) (addr ##_reg - 0x001fc000 + (0x400 * i))

#define RDMA_CMD_O_N(addr, i) (addr ##_reg - 0x004f8000 + (0x400 * i))
#define RDMA_CMD_O_P(addr, i) (addr ##_reg - 0x001f8000 + (0x400 * i))

void rsnd_gen_dma_addr(struct rsnd_priv *priv,
struct rsnd_dma *dma,
struct dma_slave_config *cfg,
int is_play, int slave_id)
{
struct platform_device *pdev = rsnd_priv_to_pdev(priv);
struct device *dev = rsnd_priv_to_dev(priv);
struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
dma_addr_t ssi_reg = platform_get_resource(pdev,
IORESOURCE_MEM, RSND_GEN2_SSI)->start;
dma_addr_t src_reg = platform_get_resource(pdev,
IORESOURCE_MEM, RSND_GEN2_SCU)->start;
int is_ssi = !!(rsnd_io_to_mod_ssi(io) == mod);
int use_src = !!rsnd_io_to_mod_src(io);
int use_dvc = !!rsnd_io_to_mod_dvc(io);
int id = rsnd_mod_id(mod);
struct dma_addr {
dma_addr_t src_addr;
dma_addr_t dst_addr;
} dma_addrs[2][2][3] = {
{ /* SRC */
/* Capture */
{{ 0, 0 },
{ RDMA_SRC_O_N(src, id), 0 },
{ RDMA_CMD_O_N(src, id), 0 }},
/* Playback */
{{ 0, 0, },
{ 0, RDMA_SRC_I_N(src, id) },
{ 0, RDMA_SRC_I_N(src, id) }}
}, { /* SSI */
/* Capture */
{{ RDMA_SSI_O_N(ssi, id), 0 },
{ RDMA_SSI_O_P(ssi, id), RDMA_SRC_I_P(src, id) },
{ RDMA_SSI_O_P(ssi, id), RDMA_SRC_I_P(src, id) }},
/* Playback */
{{ 0, RDMA_SSI_I_N(ssi, id) },
{ RDMA_SRC_O_P(src, id), RDMA_SSI_I_P(ssi, id) },
{ RDMA_CMD_O_P(src, id), RDMA_SSI_I_P(ssi, id) }}
}
};

cfg->slave_id = slave_id;
cfg->src_addr = 0;
cfg->dst_addr = 0;
cfg->direction = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM;

/*
* gen1 uses default DMA addr
*/
if (rsnd_is_gen1(priv))
return;

/* it shouldn't happen */
if (use_dvc & !use_src) {
dev_err(dev, "DVC is selected without SRC\n");
return;
}

cfg->src_addr = dma_addrs[is_ssi][is_play][use_src + use_dvc].src_addr;
cfg->dst_addr = dma_addrs[is_ssi][is_play][use_src + use_dvc].dst_addr;

dev_dbg(dev, "dma%d addr - src : %x / dst : %x\n",
id, cfg->src_addr, cfg->dst_addr);
}

/*
* Gen2
*/
Expand Down
10 changes: 8 additions & 2 deletions sound/soc/sh/rcar/rsnd.h
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,11 @@ int rsnd_gen_probe(struct platform_device *pdev,
void __iomem *rsnd_gen_reg_get(struct rsnd_priv *priv,
struct rsnd_mod *mod,
enum rsnd_reg reg);
void rsnd_gen_dma_addr(struct rsnd_priv *priv,
struct rsnd_dma *dma,
struct dma_slave_config *cfg,
int is_play, int slave_id);

#define rsnd_is_gen1(s) (((s)->info->flags & RSND_GEN_MASK) == RSND_GEN1)
#define rsnd_is_gen2(s) (((s)->info->flags & RSND_GEN_MASK) == RSND_GEN2)

Expand Down Expand Up @@ -317,7 +322,7 @@ struct rsnd_of_data {

struct rsnd_priv {

struct device *dev;
struct platform_device *pdev;
struct rcar_snd_info *info;
spinlock_t lock;

Expand Down Expand Up @@ -357,7 +362,8 @@ struct rsnd_priv {
int rdai_nr;
};

#define rsnd_priv_to_dev(priv) ((priv)->dev)
#define rsnd_priv_to_pdev(priv) ((priv)->pdev)
#define rsnd_priv_to_dev(priv) (&(rsnd_priv_to_pdev(priv)->dev))
#define rsnd_priv_to_info(priv) ((priv)->info)
#define rsnd_lock(priv, flags) spin_lock_irqsave(&priv->lock, flags)
#define rsnd_unlock(priv, flags) spin_unlock_irqrestore(&priv->lock, flags)
Expand Down
Loading

0 comments on commit 440a528

Please sign in to comment.