2018-06-12 13:58:38 +08:00
|
|
|
// SPDX-License-Identifier: GPL-2.0
|
|
|
|
//
|
|
|
|
// Renesas R-Car
|
|
|
|
//
|
|
|
|
// Copyright (C) 2013 Renesas Solutions Corp.
|
|
|
|
// Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
|
|
|
|
|
2013-07-22 12:35:52 +08:00
|
|
|
#ifndef RSND_H
|
|
|
|
#define RSND_H
|
|
|
|
|
|
|
|
#include <linux/clk.h>
|
|
|
|
#include <linux/device.h>
|
2013-07-29 09:58:50 +08:00
|
|
|
#include <linux/dma-mapping.h>
|
2013-07-22 12:35:52 +08:00
|
|
|
#include <linux/io.h>
|
|
|
|
#include <linux/list.h>
|
|
|
|
#include <linux/module.h>
|
2014-03-18 10:29:55 +08:00
|
|
|
#include <linux/of_device.h>
|
2017-05-18 09:27:48 +08:00
|
|
|
#include <linux/of_graph.h>
|
2014-03-18 10:29:55 +08:00
|
|
|
#include <linux/of_irq.h>
|
2013-07-29 09:58:50 +08:00
|
|
|
#include <linux/sh_dma.h>
|
|
|
|
#include <linux/workqueue.h>
|
2013-07-22 12:35:52 +08:00
|
|
|
#include <sound/soc.h>
|
|
|
|
#include <sound/pcm_params.h>
|
|
|
|
|
2015-11-10 13:13:53 +08:00
|
|
|
#define RSND_GEN1_SRU 0
|
|
|
|
#define RSND_GEN1_ADG 1
|
|
|
|
#define RSND_GEN1_SSI 2
|
|
|
|
|
|
|
|
#define RSND_GEN2_SCU 0
|
|
|
|
#define RSND_GEN2_ADG 1
|
|
|
|
#define RSND_GEN2_SSIU 2
|
|
|
|
#define RSND_GEN2_SSI 3
|
|
|
|
|
|
|
|
#define RSND_BASE_MAX 4
|
2015-10-07 18:42:22 +08:00
|
|
|
|
2013-07-22 12:35:52 +08:00
|
|
|
/*
|
|
|
|
* pseudo register
|
|
|
|
*
|
|
|
|
* The register address offsets SRU/SCU/SSIU on Gen1/Gen2 are very different.
|
|
|
|
* This driver uses pseudo register in order to hide it.
|
|
|
|
* see gen1/gen2 for detail
|
|
|
|
*/
|
2013-07-22 12:36:21 +08:00
|
|
|
enum rsnd_reg {
|
2016-10-26 12:28:06 +08:00
|
|
|
/* SCU (MIX/CTU/DVC) */
|
2015-11-30 16:50:08 +08:00
|
|
|
RSND_REG_SRC_I_BUSIF_MODE,
|
|
|
|
RSND_REG_SRC_O_BUSIF_MODE,
|
2013-12-20 11:28:51 +08:00
|
|
|
RSND_REG_SRC_ROUTE_MODE0,
|
|
|
|
RSND_REG_SRC_SWRSR,
|
|
|
|
RSND_REG_SRC_SRCIR,
|
2013-12-20 11:27:03 +08:00
|
|
|
RSND_REG_SRC_ADINR,
|
2013-12-20 11:28:51 +08:00
|
|
|
RSND_REG_SRC_IFSCR,
|
|
|
|
RSND_REG_SRC_IFSVR,
|
|
|
|
RSND_REG_SRC_SRCCR,
|
2016-10-26 12:27:22 +08:00
|
|
|
RSND_REG_SRC_CTRL,
|
|
|
|
RSND_REG_SRC_BSDSR,
|
|
|
|
RSND_REG_SRC_BSISR,
|
|
|
|
RSND_REG_SRC_INT_ENABLE0,
|
|
|
|
RSND_REG_SRC_BUSIF_DALIGN,
|
|
|
|
RSND_REG_SRCIN_TIMSEL0,
|
|
|
|
RSND_REG_SRCIN_TIMSEL1,
|
|
|
|
RSND_REG_SRCIN_TIMSEL2,
|
|
|
|
RSND_REG_SRCIN_TIMSEL3,
|
|
|
|
RSND_REG_SRCIN_TIMSEL4,
|
|
|
|
RSND_REG_SRCOUT_TIMSEL0,
|
|
|
|
RSND_REG_SRCOUT_TIMSEL1,
|
|
|
|
RSND_REG_SRCOUT_TIMSEL2,
|
|
|
|
RSND_REG_SRCOUT_TIMSEL3,
|
|
|
|
RSND_REG_SRCOUT_TIMSEL4,
|
2015-01-08 09:52:36 +08:00
|
|
|
RSND_REG_SCU_SYS_STATUS0,
|
2016-10-26 12:27:22 +08:00
|
|
|
RSND_REG_SCU_SYS_STATUS1,
|
2015-01-08 09:52:36 +08:00
|
|
|
RSND_REG_SCU_SYS_INT_EN0,
|
2016-10-26 12:27:22 +08:00
|
|
|
RSND_REG_SCU_SYS_INT_EN1,
|
|
|
|
RSND_REG_CMD_CTRL,
|
2017-05-16 09:51:41 +08:00
|
|
|
RSND_REG_CMD_BUSIF_MODE,
|
2016-10-26 12:27:22 +08:00
|
|
|
RSND_REG_CMD_BUSIF_DALIGN,
|
2014-05-09 08:44:49 +08:00
|
|
|
RSND_REG_CMD_ROUTE_SLCT,
|
2016-10-26 12:27:22 +08:00
|
|
|
RSND_REG_CMDOUT_TIMSEL,
|
2016-01-21 09:58:53 +08:00
|
|
|
RSND_REG_CTU_SWRSR,
|
2015-07-15 15:17:17 +08:00
|
|
|
RSND_REG_CTU_CTUIR,
|
|
|
|
RSND_REG_CTU_ADINR,
|
2016-01-21 09:59:33 +08:00
|
|
|
RSND_REG_CTU_CPMDR,
|
|
|
|
RSND_REG_CTU_SCMDR,
|
|
|
|
RSND_REG_CTU_SV00R,
|
|
|
|
RSND_REG_CTU_SV01R,
|
|
|
|
RSND_REG_CTU_SV02R,
|
|
|
|
RSND_REG_CTU_SV03R,
|
|
|
|
RSND_REG_CTU_SV04R,
|
|
|
|
RSND_REG_CTU_SV05R,
|
|
|
|
RSND_REG_CTU_SV06R,
|
|
|
|
RSND_REG_CTU_SV07R,
|
|
|
|
RSND_REG_CTU_SV10R,
|
|
|
|
RSND_REG_CTU_SV11R,
|
|
|
|
RSND_REG_CTU_SV12R,
|
|
|
|
RSND_REG_CTU_SV13R,
|
|
|
|
RSND_REG_CTU_SV14R,
|
|
|
|
RSND_REG_CTU_SV15R,
|
|
|
|
RSND_REG_CTU_SV16R,
|
|
|
|
RSND_REG_CTU_SV17R,
|
|
|
|
RSND_REG_CTU_SV20R,
|
|
|
|
RSND_REG_CTU_SV21R,
|
|
|
|
RSND_REG_CTU_SV22R,
|
|
|
|
RSND_REG_CTU_SV23R,
|
|
|
|
RSND_REG_CTU_SV24R,
|
|
|
|
RSND_REG_CTU_SV25R,
|
|
|
|
RSND_REG_CTU_SV26R,
|
|
|
|
RSND_REG_CTU_SV27R,
|
|
|
|
RSND_REG_CTU_SV30R,
|
|
|
|
RSND_REG_CTU_SV31R,
|
|
|
|
RSND_REG_CTU_SV32R,
|
|
|
|
RSND_REG_CTU_SV33R,
|
|
|
|
RSND_REG_CTU_SV34R,
|
|
|
|
RSND_REG_CTU_SV35R,
|
|
|
|
RSND_REG_CTU_SV36R,
|
|
|
|
RSND_REG_CTU_SV37R,
|
2015-07-15 15:17:36 +08:00
|
|
|
RSND_REG_MIX_SWRSR,
|
|
|
|
RSND_REG_MIX_MIXIR,
|
|
|
|
RSND_REG_MIX_ADINR,
|
|
|
|
RSND_REG_MIX_MIXMR,
|
|
|
|
RSND_REG_MIX_MVPDR,
|
|
|
|
RSND_REG_MIX_MDBAR,
|
|
|
|
RSND_REG_MIX_MDBBR,
|
|
|
|
RSND_REG_MIX_MDBCR,
|
|
|
|
RSND_REG_MIX_MDBDR,
|
|
|
|
RSND_REG_MIX_MDBER,
|
2014-05-09 08:44:49 +08:00
|
|
|
RSND_REG_DVC_SWRSR,
|
|
|
|
RSND_REG_DVC_DVUIR,
|
|
|
|
RSND_REG_DVC_ADINR,
|
|
|
|
RSND_REG_DVC_DVUCR,
|
|
|
|
RSND_REG_DVC_ZCMCR,
|
|
|
|
RSND_REG_DVC_VOL0R,
|
|
|
|
RSND_REG_DVC_VOL1R,
|
2015-11-30 16:53:44 +08:00
|
|
|
RSND_REG_DVC_VOL2R,
|
|
|
|
RSND_REG_DVC_VOL3R,
|
|
|
|
RSND_REG_DVC_VOL4R,
|
|
|
|
RSND_REG_DVC_VOL5R,
|
|
|
|
RSND_REG_DVC_VOL6R,
|
|
|
|
RSND_REG_DVC_VOL7R,
|
2014-05-09 08:44:49 +08:00
|
|
|
RSND_REG_DVC_DVUER,
|
2016-10-26 12:27:22 +08:00
|
|
|
RSND_REG_DVC_VRCTR,
|
|
|
|
RSND_REG_DVC_VRPDR,
|
|
|
|
RSND_REG_DVC_VRDBR,
|
2013-07-22 12:36:35 +08:00
|
|
|
|
2013-07-22 12:36:46 +08:00
|
|
|
/* ADG */
|
|
|
|
RSND_REG_BRRA,
|
|
|
|
RSND_REG_BRRB,
|
2016-10-28 12:12:40 +08:00
|
|
|
RSND_REG_BRGCKR,
|
2016-10-26 12:27:22 +08:00
|
|
|
RSND_REG_DIV_EN,
|
2013-07-22 12:36:46 +08:00
|
|
|
RSND_REG_AUDIO_CLK_SEL0,
|
|
|
|
RSND_REG_AUDIO_CLK_SEL1,
|
2016-10-26 12:27:22 +08:00
|
|
|
RSND_REG_AUDIO_CLK_SEL2,
|
2013-07-22 12:36:46 +08:00
|
|
|
|
2016-10-26 12:28:06 +08:00
|
|
|
/* SSIU */
|
|
|
|
RSND_REG_SSI_MODE,
|
|
|
|
RSND_REG_SSI_MODE0,
|
|
|
|
RSND_REG_SSI_MODE1,
|
|
|
|
RSND_REG_SSI_MODE2,
|
|
|
|
RSND_REG_SSI_CONTROL,
|
|
|
|
RSND_REG_SSI_CTRL,
|
|
|
|
RSND_REG_SSI_BUSIF_MODE,
|
|
|
|
RSND_REG_SSI_BUSIF_ADINR,
|
|
|
|
RSND_REG_SSI_BUSIF_DALIGN,
|
|
|
|
RSND_REG_SSI_INT_ENABLE,
|
2016-10-26 12:29:21 +08:00
|
|
|
RSND_REG_SSI_SYS_STATUS0,
|
|
|
|
RSND_REG_SSI_SYS_STATUS1,
|
|
|
|
RSND_REG_SSI_SYS_STATUS2,
|
|
|
|
RSND_REG_SSI_SYS_STATUS3,
|
|
|
|
RSND_REG_SSI_SYS_STATUS4,
|
|
|
|
RSND_REG_SSI_SYS_STATUS5,
|
|
|
|
RSND_REG_SSI_SYS_STATUS6,
|
|
|
|
RSND_REG_SSI_SYS_STATUS7,
|
2017-05-18 09:28:22 +08:00
|
|
|
RSND_REG_HDMI0_SEL,
|
|
|
|
RSND_REG_HDMI1_SEL,
|
2016-10-26 12:28:06 +08:00
|
|
|
|
2013-07-22 12:36:57 +08:00
|
|
|
/* SSI */
|
|
|
|
RSND_REG_SSICR,
|
|
|
|
RSND_REG_SSISR,
|
|
|
|
RSND_REG_SSITDR,
|
|
|
|
RSND_REG_SSIRDR,
|
|
|
|
RSND_REG_SSIWSR,
|
|
|
|
|
2013-07-22 12:36:21 +08:00
|
|
|
RSND_REG_MAX,
|
|
|
|
};
|
|
|
|
|
2013-07-22 12:35:52 +08:00
|
|
|
struct rsnd_priv;
|
2013-07-22 12:36:03 +08:00
|
|
|
struct rsnd_mod;
|
2013-07-22 12:35:52 +08:00
|
|
|
struct rsnd_dai;
|
|
|
|
struct rsnd_dai_stream;
|
|
|
|
|
2013-07-22 12:36:21 +08:00
|
|
|
/*
|
|
|
|
* R-Car basic functions
|
|
|
|
*/
|
|
|
|
#define rsnd_mod_read(m, r) \
|
|
|
|
rsnd_read(rsnd_mod_to_priv(m), m, RSND_REG_##r)
|
|
|
|
#define rsnd_mod_write(m, r, d) \
|
|
|
|
rsnd_write(rsnd_mod_to_priv(m), m, RSND_REG_##r, d)
|
|
|
|
#define rsnd_mod_bset(m, r, s, d) \
|
|
|
|
rsnd_bset(rsnd_mod_to_priv(m), m, RSND_REG_##r, s, d)
|
|
|
|
|
|
|
|
u32 rsnd_read(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg);
|
|
|
|
void rsnd_write(struct rsnd_priv *priv, struct rsnd_mod *mod,
|
|
|
|
enum rsnd_reg reg, u32 data);
|
2015-06-16 16:53:11 +08:00
|
|
|
void rsnd_force_write(struct rsnd_priv *priv, struct rsnd_mod *mod,
|
|
|
|
enum rsnd_reg reg, u32 data);
|
2013-07-22 12:36:21 +08:00
|
|
|
void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg,
|
|
|
|
u32 mask, u32 data);
|
2015-07-15 15:14:05 +08:00
|
|
|
u32 rsnd_get_adinr_bit(struct rsnd_mod *mod, struct rsnd_dai_stream *io);
|
2015-07-15 15:14:47 +08:00
|
|
|
u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io);
|
2017-05-16 09:51:41 +08:00
|
|
|
u32 rsnd_get_busif_shift(struct rsnd_dai_stream *io, struct rsnd_mod *mod);
|
2013-07-22 12:36:21 +08:00
|
|
|
|
2013-07-29 09:58:50 +08:00
|
|
|
/*
|
|
|
|
* R-Car DMA
|
|
|
|
*/
|
2016-01-21 09:58:33 +08:00
|
|
|
int rsnd_dma_attach(struct rsnd_dai_stream *io,
|
2016-10-25 08:36:13 +08:00
|
|
|
struct rsnd_mod *mod, struct rsnd_mod **dma_mod);
|
2015-11-10 13:14:12 +08:00
|
|
|
int rsnd_dma_probe(struct rsnd_priv *priv);
|
ASoC: rsnd: 1st DMAC dma-names cares subnode
Renesas R-Car sound (= rsnd) needs 2 DMAC which are called as
Audio DMAC (= 1st DMAC) and Audio DMAC peri peri (2nd DMAC).
And rsnd had assumed that 1st / 2nd DMACs are implemented as DMAEngine.
But, in result of DMA ML discussion, 2nd DMAC was concluded that it is
not a general purpose DMAC (2nd DMAC is for Device to Device inside
sound system). Additionally, current DMAEngine can't support Device to
Device, and we don't have correct DT bindings for it at this point.
So the easiest solution for it is that move it from DMAEngine to rsnd
driver.
dma-names on DT was implemented as no difference between 1st / 2nd
DMAC's, since rsnd had assumed that both DMACs are implemented as
DMAEngine. That style was "src_dst". But now, 2nd DMAC was implemented
as non DMAEngine, and it doesn't need dma-names anymore. So, this
dma-names rule is no longer needed.
And additionally, dma-names was assumed that it has all
(= SSI/SSIU/SRC/DVC) nodes under sound node.
In upstream code, no SoC/platform is supporting DMA for rsnd driver yet.
This means there is no compatible issue if this patch changes
dma-names's rule of DT.
This patch assumes dma-names for 1st DMAC are tx/rx base, and listed
in each SSI/SRC/DVC subnode
ex)
rcar_sound,dvc {
dvc0: dvc@0 {
dmas = <&audma0 0xbc>;
dma-names = "tx";
};
...
rcar_sound,src {
src0: src@0 {
...
dmas = <&audma0 0x85>, <&audma1 0x9a>;
dma-names = "rx", "tx";
};
...
rcar_sound,ssi {
ssi0: ssi@0 {
...
dmas = <&audma0 0x01>, <&audma1 0x02>, <&audma0 0x15>, <&audma1 0x16>;
dma-names = "rx", "tx", "rxu", "txu";
};
...
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
2015-02-20 18:31:23 +08:00
|
|
|
struct dma_chan *rsnd_dma_request_channel(struct device_node *of_node,
|
|
|
|
struct rsnd_mod *mod, char *name);
|
2013-07-29 09:58:50 +08:00
|
|
|
|
2013-07-22 12:36:03 +08:00
|
|
|
/*
|
|
|
|
* R-Car sound mod
|
|
|
|
*/
|
2014-03-03 15:42:55 +08:00
|
|
|
enum rsnd_mod_type {
|
2015-10-26 16:42:25 +08:00
|
|
|
RSND_MOD_AUDMAPP,
|
|
|
|
RSND_MOD_AUDMA,
|
|
|
|
RSND_MOD_DVC,
|
2015-07-15 15:17:36 +08:00
|
|
|
RSND_MOD_MIX,
|
2015-07-15 15:17:17 +08:00
|
|
|
RSND_MOD_CTU,
|
2015-10-26 16:43:21 +08:00
|
|
|
RSND_MOD_CMD,
|
2015-01-15 16:09:44 +08:00
|
|
|
RSND_MOD_SRC,
|
2015-12-17 11:00:10 +08:00
|
|
|
RSND_MOD_SSIM3, /* SSI multi 3 */
|
|
|
|
RSND_MOD_SSIM2, /* SSI multi 2 */
|
|
|
|
RSND_MOD_SSIM1, /* SSI multi 1 */
|
|
|
|
RSND_MOD_SSIP, /* SSI parent */
|
2014-03-03 15:42:55 +08:00
|
|
|
RSND_MOD_SSI,
|
2015-12-17 10:55:25 +08:00
|
|
|
RSND_MOD_SSIU,
|
2014-03-03 15:42:55 +08:00
|
|
|
RSND_MOD_MAX,
|
|
|
|
};
|
2013-07-22 12:36:03 +08:00
|
|
|
|
|
|
|
struct rsnd_mod_ops {
|
|
|
|
char *name;
|
2015-06-15 14:26:25 +08:00
|
|
|
struct dma_chan* (*dma_req)(struct rsnd_dai_stream *io,
|
|
|
|
struct rsnd_mod *mod);
|
2014-03-04 12:50:33 +08:00
|
|
|
int (*probe)(struct rsnd_mod *mod,
|
2015-06-15 14:25:20 +08:00
|
|
|
struct rsnd_dai_stream *io,
|
2015-01-15 16:07:47 +08:00
|
|
|
struct rsnd_priv *priv);
|
2014-03-04 12:50:33 +08:00
|
|
|
int (*remove)(struct rsnd_mod *mod,
|
2015-06-15 14:25:20 +08:00
|
|
|
struct rsnd_dai_stream *io,
|
2015-01-15 16:07:47 +08:00
|
|
|
struct rsnd_priv *priv);
|
2013-07-22 12:36:03 +08:00
|
|
|
int (*init)(struct rsnd_mod *mod,
|
2015-06-15 14:25:20 +08:00
|
|
|
struct rsnd_dai_stream *io,
|
2015-01-15 16:07:47 +08:00
|
|
|
struct rsnd_priv *priv);
|
2013-07-22 12:36:03 +08:00
|
|
|
int (*quit)(struct rsnd_mod *mod,
|
2015-06-15 14:25:20 +08:00
|
|
|
struct rsnd_dai_stream *io,
|
2015-01-15 16:07:47 +08:00
|
|
|
struct rsnd_priv *priv);
|
2013-07-22 12:36:03 +08:00
|
|
|
int (*start)(struct rsnd_mod *mod,
|
2015-06-15 14:25:20 +08:00
|
|
|
struct rsnd_dai_stream *io,
|
2015-01-15 16:07:47 +08:00
|
|
|
struct rsnd_priv *priv);
|
2013-07-22 12:36:03 +08:00
|
|
|
int (*stop)(struct rsnd_mod *mod,
|
2015-06-15 14:25:20 +08:00
|
|
|
struct rsnd_dai_stream *io,
|
2015-01-15 16:07:47 +08:00
|
|
|
struct rsnd_priv *priv);
|
2016-01-26 12:56:57 +08:00
|
|
|
int (*irq)(struct rsnd_mod *mod,
|
|
|
|
struct rsnd_dai_stream *io,
|
|
|
|
struct rsnd_priv *priv, int enable);
|
2014-05-09 08:44:49 +08:00
|
|
|
int (*pcm_new)(struct rsnd_mod *mod,
|
2015-06-15 14:25:20 +08:00
|
|
|
struct rsnd_dai_stream *io,
|
2014-05-09 08:44:49 +08:00
|
|
|
struct snd_soc_pcm_runtime *rtd);
|
2015-03-26 12:02:51 +08:00
|
|
|
int (*hw_params)(struct rsnd_mod *mod,
|
2015-06-15 14:25:20 +08:00
|
|
|
struct rsnd_dai_stream *io,
|
2015-03-26 12:02:51 +08:00
|
|
|
struct snd_pcm_substream *substream,
|
|
|
|
struct snd_pcm_hw_params *hw_params);
|
2017-06-07 08:20:01 +08:00
|
|
|
int (*pointer)(struct rsnd_mod *mod,
|
|
|
|
struct rsnd_dai_stream *io,
|
|
|
|
snd_pcm_uframes_t *pointer);
|
2014-11-27 16:02:43 +08:00
|
|
|
int (*fallback)(struct rsnd_mod *mod,
|
2015-06-15 14:25:20 +08:00
|
|
|
struct rsnd_dai_stream *io,
|
2015-01-15 16:07:47 +08:00
|
|
|
struct rsnd_priv *priv);
|
2016-10-25 08:37:35 +08:00
|
|
|
int (*nolock_start)(struct rsnd_mod *mod,
|
|
|
|
struct rsnd_dai_stream *io,
|
|
|
|
struct rsnd_priv *priv);
|
|
|
|
int (*nolock_stop)(struct rsnd_mod *mod,
|
|
|
|
struct rsnd_dai_stream *io,
|
|
|
|
struct rsnd_priv *priv);
|
2013-07-22 12:36:03 +08:00
|
|
|
};
|
|
|
|
|
2014-01-24 10:41:44 +08:00
|
|
|
struct rsnd_dai_stream;
|
2013-07-22 12:36:03 +08:00
|
|
|
struct rsnd_mod {
|
|
|
|
int id;
|
2014-03-03 15:42:55 +08:00
|
|
|
enum rsnd_mod_type type;
|
2013-07-22 12:36:03 +08:00
|
|
|
struct rsnd_mod_ops *ops;
|
2015-06-15 14:24:54 +08:00
|
|
|
struct rsnd_priv *priv;
|
2015-01-15 16:03:22 +08:00
|
|
|
struct clk *clk;
|
2016-01-21 09:58:07 +08:00
|
|
|
u32 *(*get_status)(struct rsnd_dai_stream *io,
|
|
|
|
struct rsnd_mod *mod,
|
|
|
|
enum rsnd_mod_type type);
|
|
|
|
u32 status;
|
2013-07-22 12:36:03 +08:00
|
|
|
};
|
2014-11-27 16:02:55 +08:00
|
|
|
/*
|
|
|
|
* status
|
|
|
|
*
|
2016-10-25 08:37:35 +08:00
|
|
|
* 0xH0000CBA
|
2015-03-26 12:02:51 +08:00
|
|
|
*
|
2016-10-25 08:37:35 +08:00
|
|
|
* A 0: nolock_start 1: nolock_stop
|
2015-06-15 14:24:34 +08:00
|
|
|
* B 0: init 1: quit
|
|
|
|
* C 0: start 1: stop
|
|
|
|
*
|
|
|
|
* H is always called (see __rsnd_mod_call)
|
2016-01-21 09:56:59 +08:00
|
|
|
* H 0: probe 1: remove
|
2015-06-15 14:24:34 +08:00
|
|
|
* H 0: pcm_new
|
|
|
|
* H 0: fallback
|
|
|
|
* H 0: hw_params
|
2017-06-07 08:20:01 +08:00
|
|
|
* H 0: pointer
|
2014-11-27 16:02:55 +08:00
|
|
|
*/
|
2016-10-25 08:37:35 +08:00
|
|
|
#define __rsnd_mod_shift_nolock_start 0
|
|
|
|
#define __rsnd_mod_shift_nolock_stop 0
|
2015-06-15 14:24:34 +08:00
|
|
|
#define __rsnd_mod_shift_init 4
|
|
|
|
#define __rsnd_mod_shift_quit 4
|
|
|
|
#define __rsnd_mod_shift_start 8
|
|
|
|
#define __rsnd_mod_shift_stop 8
|
2016-10-19 11:56:26 +08:00
|
|
|
#define __rsnd_mod_shift_probe 28 /* always called */
|
|
|
|
#define __rsnd_mod_shift_remove 28 /* always called */
|
2016-01-26 12:56:57 +08:00
|
|
|
#define __rsnd_mod_shift_irq 28 /* always called */
|
2015-06-15 14:24:34 +08:00
|
|
|
#define __rsnd_mod_shift_pcm_new 28 /* always called */
|
|
|
|
#define __rsnd_mod_shift_fallback 28 /* always called */
|
|
|
|
#define __rsnd_mod_shift_hw_params 28 /* always called */
|
2017-06-07 08:20:01 +08:00
|
|
|
#define __rsnd_mod_shift_pointer 28 /* always called */
|
2015-06-15 14:24:34 +08:00
|
|
|
|
2016-10-19 11:56:26 +08:00
|
|
|
#define __rsnd_mod_add_probe 0
|
|
|
|
#define __rsnd_mod_add_remove 0
|
2016-10-25 08:37:35 +08:00
|
|
|
#define __rsnd_mod_add_nolock_start 1
|
|
|
|
#define __rsnd_mod_add_nolock_stop -1
|
2015-06-15 14:24:34 +08:00
|
|
|
#define __rsnd_mod_add_init 1
|
|
|
|
#define __rsnd_mod_add_quit -1
|
|
|
|
#define __rsnd_mod_add_start 1
|
|
|
|
#define __rsnd_mod_add_stop -1
|
2016-01-26 12:56:57 +08:00
|
|
|
#define __rsnd_mod_add_irq 0
|
2015-06-15 14:24:34 +08:00
|
|
|
#define __rsnd_mod_add_pcm_new 0
|
|
|
|
#define __rsnd_mod_add_fallback 0
|
|
|
|
#define __rsnd_mod_add_hw_params 0
|
2017-06-07 08:20:01 +08:00
|
|
|
#define __rsnd_mod_add_pointer 0
|
2014-11-27 16:02:55 +08:00
|
|
|
|
|
|
|
#define __rsnd_mod_call_probe 0
|
2016-10-19 11:56:26 +08:00
|
|
|
#define __rsnd_mod_call_remove 0
|
2014-11-27 16:02:55 +08:00
|
|
|
#define __rsnd_mod_call_init 0
|
|
|
|
#define __rsnd_mod_call_quit 1
|
|
|
|
#define __rsnd_mod_call_start 0
|
|
|
|
#define __rsnd_mod_call_stop 1
|
2016-01-26 12:56:57 +08:00
|
|
|
#define __rsnd_mod_call_irq 0
|
2014-11-27 16:02:55 +08:00
|
|
|
#define __rsnd_mod_call_pcm_new 0
|
|
|
|
#define __rsnd_mod_call_fallback 0
|
2015-03-26 12:02:51 +08:00
|
|
|
#define __rsnd_mod_call_hw_params 0
|
2017-06-07 08:20:01 +08:00
|
|
|
#define __rsnd_mod_call_pointer 0
|
2016-10-25 08:37:35 +08:00
|
|
|
#define __rsnd_mod_call_nolock_start 0
|
|
|
|
#define __rsnd_mod_call_nolock_stop 1
|
2013-07-22 12:36:03 +08:00
|
|
|
|
ASoC: rsnd: remove NULL check from rsnd_mod_name()/rsnd_mod_id()
Current rsnd driver has rsnd_mod_id() which returns mod ID,
and it returns -1 if mod was NULL.
In the same time, this driver has rsnd_mod_name() which returns mod
name, and it returns "unknown" if mod or mod->ops was NULL.
Basically these "mod" never be NULL, but the reason why rsnd driver
has such behavior is that DMA path finder is assuming memory as
"mod == NULL".
Thus, current DMA path debug code prints like below.
Here "unknown[-1]" means it was memory.
...
rcar_sound ec500000.sound: unknown[-1] from
rcar_sound ec500000.sound: src[0] to
rcar_sound ec500000.sound: ctu[2]
rcar_sound ec500000.sound: mix[0]
rcar_sound ec500000.sound: dvc[0]
rcar_sound ec500000.sound: ssi[0]
rcar_sound ec500000.sound: audmac[0] unknown[-1] -> src[0]
...
1st issue is that it is confusable for user.
2nd issue is rsnd driver has something like below code.
mask |= 1 << rsnd_mod_id(mod);
Because of this kind of code, some statically code checker will
reports "Shifting by a negative value is undefined behaviour".
But this "mod" never be NULL, thus negative shift never happen.
To avoid these issues, this patch adds new dummy "mem" to
indicate memory, and use it to indicate debug information,
and, remove unneeded "NULL mod" behavior from rsnd_mod_id() and
rsnd_mod_name().
The debug information will be like below by this patch
...
rcar_sound ec500000.sound: mem[0] from
rcar_sound ec500000.sound: src[0] to
rcar_sound ec500000.sound: ctu[2]
rcar_sound ec500000.sound: mix[0]
rcar_sound ec500000.sound: dvc[0]
rcar_sound ec500000.sound: ssi[0]
rcar_sound ec500000.sound: audmac[0] mem[0] -> src[0]
...
Reported-by: Hiroyuki Yokoyama <hiroyuki.yokoyama.vx@renesas.com>
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
2017-11-01 15:17:34 +08:00
|
|
|
#define rsnd_mod_to_priv(mod) ((mod)->priv)
|
|
|
|
#define rsnd_mod_name(mod) ((mod)->ops->name)
|
|
|
|
#define rsnd_mod_id(mod) ((mod)->id)
|
2015-10-22 11:15:04 +08:00
|
|
|
#define rsnd_mod_power_on(mod) clk_enable((mod)->clk)
|
|
|
|
#define rsnd_mod_power_off(mod) clk_disable((mod)->clk)
|
2015-09-10 15:02:21 +08:00
|
|
|
#define rsnd_mod_get(ip) (&(ip)->mod)
|
2013-07-22 12:36:03 +08:00
|
|
|
|
2015-06-15 14:24:54 +08:00
|
|
|
int rsnd_mod_init(struct rsnd_priv *priv,
|
|
|
|
struct rsnd_mod *mod,
|
2016-01-21 09:58:07 +08:00
|
|
|
struct rsnd_mod_ops *ops,
|
|
|
|
struct clk *clk,
|
|
|
|
u32* (*get_status)(struct rsnd_dai_stream *io,
|
|
|
|
struct rsnd_mod *mod,
|
|
|
|
enum rsnd_mod_type type),
|
|
|
|
enum rsnd_mod_type type,
|
|
|
|
int id);
|
2015-03-26 12:02:09 +08:00
|
|
|
void rsnd_mod_quit(struct rsnd_mod *mod);
|
2015-06-15 14:26:25 +08:00
|
|
|
struct dma_chan *rsnd_mod_dma_req(struct rsnd_dai_stream *io,
|
|
|
|
struct rsnd_mod *mod);
|
2015-06-15 14:25:48 +08:00
|
|
|
void rsnd_mod_interrupt(struct rsnd_mod *mod,
|
|
|
|
void (*callback)(struct rsnd_mod *mod,
|
|
|
|
struct rsnd_dai_stream *io));
|
2016-01-21 09:58:07 +08:00
|
|
|
u32 *rsnd_mod_get_status(struct rsnd_dai_stream *io,
|
|
|
|
struct rsnd_mod *mod,
|
|
|
|
enum rsnd_mod_type type);
|
2016-10-19 11:56:46 +08:00
|
|
|
struct rsnd_mod *rsnd_mod_next(int *iterator,
|
|
|
|
struct rsnd_dai_stream *io,
|
|
|
|
enum rsnd_mod_type *array,
|
|
|
|
int array_size);
|
|
|
|
#define for_each_rsnd_mod(iterator, pos, io) \
|
|
|
|
for (iterator = 0; \
|
2017-01-20 12:23:29 +08:00
|
|
|
(pos = rsnd_mod_next(&iterator, io, NULL, 0)); iterator++)
|
2016-10-19 11:56:46 +08:00
|
|
|
#define for_each_rsnd_mod_arrays(iterator, pos, io, array, size) \
|
|
|
|
for (iterator = 0; \
|
2017-01-20 12:23:29 +08:00
|
|
|
(pos = rsnd_mod_next(&iterator, io, array, size)); iterator++)
|
2016-10-19 11:56:46 +08:00
|
|
|
#define for_each_rsnd_mod_array(iterator, pos, io, array) \
|
|
|
|
for_each_rsnd_mod_arrays(iterator, pos, io, array, ARRAY_SIZE(array))
|
2016-01-21 09:58:07 +08:00
|
|
|
|
2015-12-17 10:58:14 +08:00
|
|
|
void rsnd_parse_connect_common(struct rsnd_dai *rdai,
|
|
|
|
struct rsnd_mod* (*mod_get)(struct rsnd_priv *priv, int id),
|
|
|
|
struct device_node *node,
|
|
|
|
struct device_node *playback,
|
|
|
|
struct device_node *capture);
|
2013-07-22 12:36:03 +08:00
|
|
|
|
2017-11-29 11:07:51 +08:00
|
|
|
#define rsnd_runtime_channel_original(io) \
|
|
|
|
rsnd_runtime_channel_original_with_params(io, NULL)
|
|
|
|
int rsnd_runtime_channel_original_with_params(struct rsnd_dai_stream *io,
|
|
|
|
struct snd_pcm_hw_params *params);
|
|
|
|
#define rsnd_runtime_channel_after_ctu(io) \
|
|
|
|
rsnd_runtime_channel_after_ctu_with_params(io, NULL)
|
|
|
|
int rsnd_runtime_channel_after_ctu_with_params(struct rsnd_dai_stream *io,
|
|
|
|
struct snd_pcm_hw_params *params);
|
|
|
|
#define rsnd_runtime_channel_for_ssi(io) \
|
|
|
|
rsnd_runtime_channel_for_ssi_with_params(io, NULL)
|
|
|
|
int rsnd_runtime_channel_for_ssi_with_params(struct rsnd_dai_stream *io,
|
|
|
|
struct snd_pcm_hw_params *params);
|
2016-02-25 13:54:58 +08:00
|
|
|
int rsnd_runtime_is_ssi_multi(struct rsnd_dai_stream *io);
|
|
|
|
int rsnd_runtime_is_ssi_tdm(struct rsnd_dai_stream *io);
|
|
|
|
|
2016-10-19 11:57:47 +08:00
|
|
|
/*
|
|
|
|
* DT
|
|
|
|
*/
|
|
|
|
#define rsnd_parse_of_node(priv, node) \
|
|
|
|
of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, node)
|
|
|
|
#define RSND_NODE_DAI "rcar_sound,dai"
|
|
|
|
#define RSND_NODE_SSI "rcar_sound,ssi"
|
|
|
|
#define RSND_NODE_SRC "rcar_sound,src"
|
|
|
|
#define RSND_NODE_CTU "rcar_sound,ctu"
|
|
|
|
#define RSND_NODE_MIX "rcar_sound,mix"
|
|
|
|
#define RSND_NODE_DVC "rcar_sound,dvc"
|
|
|
|
|
2013-07-22 12:35:52 +08:00
|
|
|
/*
|
|
|
|
* R-Car sound DAI
|
|
|
|
*/
|
|
|
|
#define RSND_DAI_NAME_SIZE 16
|
|
|
|
struct rsnd_dai_stream {
|
2015-03-19 12:15:18 +08:00
|
|
|
char name[RSND_DAI_NAME_SIZE];
|
2013-07-22 12:35:52 +08:00
|
|
|
struct snd_pcm_substream *substream;
|
2014-03-03 15:42:55 +08:00
|
|
|
struct rsnd_mod *mod[RSND_MOD_MAX];
|
2015-01-15 16:06:24 +08:00
|
|
|
struct rsnd_dai *rdai;
|
2018-04-16 13:14:01 +08:00
|
|
|
struct device *dmac_dev; /* for IPMMU */
|
2016-01-21 09:58:07 +08:00
|
|
|
u32 parent_ssi_status;
|
2013-07-22 12:35:52 +08:00
|
|
|
};
|
2015-07-15 15:16:19 +08:00
|
|
|
#define rsnd_io_to_mod(io, i) ((i) < RSND_MOD_MAX ? (io)->mod[(i)] : NULL)
|
|
|
|
#define rsnd_io_to_mod_ssi(io) rsnd_io_to_mod((io), RSND_MOD_SSI)
|
2016-12-02 10:44:23 +08:00
|
|
|
#define rsnd_io_to_mod_ssiu(io) rsnd_io_to_mod((io), RSND_MOD_SSIU)
|
2015-10-26 16:43:57 +08:00
|
|
|
#define rsnd_io_to_mod_ssip(io) rsnd_io_to_mod((io), RSND_MOD_SSIP)
|
2015-07-15 15:16:19 +08:00
|
|
|
#define rsnd_io_to_mod_src(io) rsnd_io_to_mod((io), RSND_MOD_SRC)
|
2015-07-15 15:17:17 +08:00
|
|
|
#define rsnd_io_to_mod_ctu(io) rsnd_io_to_mod((io), RSND_MOD_CTU)
|
2015-07-15 15:17:36 +08:00
|
|
|
#define rsnd_io_to_mod_mix(io) rsnd_io_to_mod((io), RSND_MOD_MIX)
|
2015-07-15 15:16:19 +08:00
|
|
|
#define rsnd_io_to_mod_dvc(io) rsnd_io_to_mod((io), RSND_MOD_DVC)
|
2015-12-08 13:38:23 +08:00
|
|
|
#define rsnd_io_to_mod_cmd(io) rsnd_io_to_mod((io), RSND_MOD_CMD)
|
2015-01-15 16:06:24 +08:00
|
|
|
#define rsnd_io_to_rdai(io) ((io)->rdai)
|
2015-01-15 16:08:34 +08:00
|
|
|
#define rsnd_io_to_priv(io) (rsnd_rdai_to_priv(rsnd_io_to_rdai(io)))
|
2015-01-15 16:06:49 +08:00
|
|
|
#define rsnd_io_is_play(io) (&rsnd_io_to_rdai(io)->playback == io)
|
2015-01-15 16:02:40 +08:00
|
|
|
#define rsnd_io_to_runtime(io) ((io)->substream ? \
|
|
|
|
(io)->substream->runtime : NULL)
|
2015-06-15 14:27:47 +08:00
|
|
|
int rsnd_io_is_working(struct rsnd_dai_stream *io);
|
2015-01-15 16:06:49 +08:00
|
|
|
|
2013-07-22 12:35:52 +08:00
|
|
|
struct rsnd_dai {
|
|
|
|
char name[RSND_DAI_NAME_SIZE];
|
|
|
|
struct rsnd_dai_stream playback;
|
|
|
|
struct rsnd_dai_stream capture;
|
2015-01-15 16:08:34 +08:00
|
|
|
struct rsnd_priv *priv;
|
2017-06-15 08:50:19 +08:00
|
|
|
struct snd_pcm_hw_constraint_list constraint;
|
2013-07-22 12:35:52 +08:00
|
|
|
|
2017-06-15 08:49:27 +08:00
|
|
|
int max_channels; /* 2ch - 16ch */
|
|
|
|
int ssi_lane; /* 1lane - 4lane */
|
2015-11-30 16:53:27 +08:00
|
|
|
|
2013-11-08 17:46:53 +08:00
|
|
|
unsigned int clk_master:1;
|
|
|
|
unsigned int bit_clk_inv:1;
|
|
|
|
unsigned int frm_clk_inv:1;
|
|
|
|
unsigned int sys_delay:1;
|
|
|
|
unsigned int data_alignment:1;
|
2013-07-22 12:35:52 +08:00
|
|
|
};
|
|
|
|
|
2014-02-25 14:15:18 +08:00
|
|
|
#define rsnd_rdai_nr(priv) ((priv)->rdai_nr)
|
2015-01-15 16:04:51 +08:00
|
|
|
#define rsnd_rdai_is_clk_master(rdai) ((rdai)->clk_master)
|
2015-01-15 16:08:34 +08:00
|
|
|
#define rsnd_rdai_to_priv(rdai) ((rdai)->priv)
|
2013-07-22 12:35:52 +08:00
|
|
|
#define for_each_rsnd_dai(rdai, priv, i) \
|
2014-02-12 09:15:51 +08:00
|
|
|
for (i = 0; \
|
2014-02-25 14:15:18 +08:00
|
|
|
(i < rsnd_rdai_nr(priv)) && \
|
2015-01-15 16:03:38 +08:00
|
|
|
((rdai) = rsnd_rdai_get(priv, i)); \
|
2014-02-12 09:15:51 +08:00
|
|
|
i++)
|
2013-07-22 12:35:52 +08:00
|
|
|
|
2015-01-15 16:03:38 +08:00
|
|
|
struct rsnd_dai *rsnd_rdai_get(struct rsnd_priv *priv, int id);
|
|
|
|
|
2017-06-15 08:49:27 +08:00
|
|
|
#define rsnd_rdai_channels_set(rdai, max_channels) \
|
|
|
|
rsnd_rdai_channels_ctrl(rdai, max_channels)
|
|
|
|
#define rsnd_rdai_channels_get(rdai) \
|
|
|
|
rsnd_rdai_channels_ctrl(rdai, 0)
|
|
|
|
int rsnd_rdai_channels_ctrl(struct rsnd_dai *rdai,
|
|
|
|
int max_channels);
|
|
|
|
|
|
|
|
#define rsnd_rdai_ssi_lane_set(rdai, ssi_lane) \
|
|
|
|
rsnd_rdai_ssi_lane_ctrl(rdai, ssi_lane)
|
|
|
|
#define rsnd_rdai_ssi_lane_get(rdai) \
|
|
|
|
rsnd_rdai_ssi_lane_ctrl(rdai, 0)
|
|
|
|
int rsnd_rdai_ssi_lane_ctrl(struct rsnd_dai *rdai,
|
|
|
|
int ssi_lane);
|
|
|
|
|
2015-06-15 14:21:15 +08:00
|
|
|
void rsnd_dai_period_elapsed(struct rsnd_dai_stream *io);
|
2015-10-26 16:39:41 +08:00
|
|
|
int rsnd_dai_connect(struct rsnd_mod *mod,
|
|
|
|
struct rsnd_dai_stream *io,
|
|
|
|
enum rsnd_mod_type type);
|
2013-07-22 12:35:52 +08:00
|
|
|
|
2013-07-22 12:36:21 +08:00
|
|
|
/*
|
|
|
|
* R-Car Gen1/Gen2
|
|
|
|
*/
|
2015-11-10 13:14:12 +08:00
|
|
|
int rsnd_gen_probe(struct rsnd_priv *priv);
|
2013-07-22 12:36:21 +08:00
|
|
|
void __iomem *rsnd_gen_reg_get(struct rsnd_priv *priv,
|
|
|
|
struct rsnd_mod *mod,
|
|
|
|
enum rsnd_reg reg);
|
2015-02-20 18:25:27 +08:00
|
|
|
phys_addr_t rsnd_gen_get_phy_addr(struct rsnd_priv *priv, int reg_id);
|
2014-05-23 14:25:54 +08:00
|
|
|
|
2013-07-22 12:36:46 +08:00
|
|
|
/*
|
|
|
|
* R-Car ADG
|
|
|
|
*/
|
ASoC: rsnd: add rsnd_adg_clk_query()
Current Renesas sound driver is assuming that all Sampling rate and
channles are possible to use, but these are depends on inputed clock
and SSI connection situation.
For example, if it is using 1 SSI, enabled TDM mode and has 12288000
input clock, 2ch output can support until 192000Hz, but 6ch output can
support until 64000Hz, 8ch can support 48000Hz.
To control these situation correctly, it needs to support
hw_constraints / refine feature.
To support such feature, it needs SSI clock query feature, and it needs
ADG clock query feature. Current ADG has rsnd_adg_ssi_clk_try_start()
and it is doing similar things, but it try to setup ADG register in
same time. This is not needed.
This patch adds new rsnd_adg_clk_query() and separates query feature
and register setting feature in adg.c
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Tested-by: Hiroyuki Yokoyama <hiroyuki.yokoyama.vx@renesas.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
2017-06-15 08:49:43 +08:00
|
|
|
int rsnd_adg_clk_query(struct rsnd_priv *priv, unsigned int rate);
|
2013-07-22 12:36:46 +08:00
|
|
|
int rsnd_adg_ssi_clk_stop(struct rsnd_mod *mod);
|
|
|
|
int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *mod, unsigned int rate);
|
2015-11-10 13:14:12 +08:00
|
|
|
int rsnd_adg_probe(struct rsnd_priv *priv);
|
|
|
|
void rsnd_adg_remove(struct rsnd_priv *priv);
|
2016-03-07 13:09:14 +08:00
|
|
|
int rsnd_adg_set_src_timesel_gen2(struct rsnd_mod *src_mod,
|
2014-01-24 10:42:00 +08:00
|
|
|
struct rsnd_dai_stream *io,
|
2016-03-07 13:09:14 +08:00
|
|
|
unsigned int in_rate,
|
|
|
|
unsigned int out_rate);
|
2015-01-15 16:07:19 +08:00
|
|
|
int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_mod *mod,
|
2014-05-09 08:44:49 +08:00
|
|
|
struct rsnd_dai_stream *io);
|
2016-12-07 08:29:02 +08:00
|
|
|
#define rsnd_adg_clk_enable(priv) rsnd_adg_clk_control(priv, 1)
|
|
|
|
#define rsnd_adg_clk_disable(priv) rsnd_adg_clk_control(priv, 0)
|
|
|
|
void rsnd_adg_clk_control(struct rsnd_priv *priv, int enable);
|
2013-07-22 12:36:46 +08:00
|
|
|
|
2013-07-22 12:35:52 +08:00
|
|
|
/*
|
|
|
|
* R-Car sound priv
|
|
|
|
*/
|
|
|
|
struct rsnd_priv {
|
|
|
|
|
2014-05-23 14:25:30 +08:00
|
|
|
struct platform_device *pdev;
|
2013-07-22 12:35:52 +08:00
|
|
|
spinlock_t lock;
|
2015-11-19 12:22:56 +08:00
|
|
|
unsigned long flags;
|
2015-11-10 13:13:53 +08:00
|
|
|
#define RSND_GEN_MASK (0xF << 0)
|
|
|
|
#define RSND_GEN1 (1 << 0)
|
|
|
|
#define RSND_GEN2 (2 << 0)
|
2018-04-11 10:10:29 +08:00
|
|
|
#define RSND_GEN3 (3 << 0)
|
2013-07-22 12:35:52 +08:00
|
|
|
|
2013-07-22 12:36:21 +08:00
|
|
|
/*
|
|
|
|
* below value will be filled on rsnd_gen_probe()
|
|
|
|
*/
|
|
|
|
void *gen;
|
|
|
|
|
2013-07-22 12:36:46 +08:00
|
|
|
/*
|
|
|
|
* below value will be filled on rsnd_adg_probe()
|
|
|
|
*/
|
|
|
|
void *adg;
|
|
|
|
|
2015-02-20 18:27:42 +08:00
|
|
|
/*
|
|
|
|
* below value will be filled on rsnd_dma_probe()
|
|
|
|
*/
|
|
|
|
void *dma;
|
|
|
|
|
2013-07-22 12:36:57 +08:00
|
|
|
/*
|
|
|
|
* below value will be filled on rsnd_ssi_probe()
|
|
|
|
*/
|
2014-01-24 10:39:40 +08:00
|
|
|
void *ssi;
|
|
|
|
int ssi_nr;
|
2013-07-22 12:36:57 +08:00
|
|
|
|
2015-10-26 16:43:41 +08:00
|
|
|
/*
|
|
|
|
* below value will be filled on rsnd_ssiu_probe()
|
|
|
|
*/
|
|
|
|
void *ssiu;
|
|
|
|
int ssiu_nr;
|
|
|
|
|
2015-07-15 15:16:37 +08:00
|
|
|
/*
|
|
|
|
* below value will be filled on rsnd_src_probe()
|
|
|
|
*/
|
|
|
|
void *src;
|
|
|
|
int src_nr;
|
|
|
|
|
2015-07-15 15:17:17 +08:00
|
|
|
/*
|
|
|
|
* below value will be filled on rsnd_ctu_probe()
|
|
|
|
*/
|
|
|
|
void *ctu;
|
|
|
|
int ctu_nr;
|
|
|
|
|
2015-07-15 15:17:36 +08:00
|
|
|
/*
|
|
|
|
* below value will be filled on rsnd_mix_probe()
|
|
|
|
*/
|
|
|
|
void *mix;
|
|
|
|
int mix_nr;
|
|
|
|
|
2014-05-09 08:44:49 +08:00
|
|
|
/*
|
|
|
|
* below value will be filled on rsnd_dvc_probe()
|
|
|
|
*/
|
|
|
|
void *dvc;
|
|
|
|
int dvc_nr;
|
|
|
|
|
2015-10-26 16:43:21 +08:00
|
|
|
/*
|
|
|
|
* below value will be filled on rsnd_cmd_probe()
|
|
|
|
*/
|
|
|
|
void *cmd;
|
|
|
|
int cmd_nr;
|
|
|
|
|
2013-07-22 12:35:52 +08:00
|
|
|
/*
|
|
|
|
* below value will be filled on rsnd_dai_probe()
|
|
|
|
*/
|
|
|
|
struct snd_soc_dai_driver *daidrv;
|
|
|
|
struct rsnd_dai *rdai;
|
2014-02-25 14:15:18 +08:00
|
|
|
int rdai_nr;
|
2013-07-22 12:35:52 +08:00
|
|
|
};
|
|
|
|
|
2014-05-23 14:25:30 +08:00
|
|
|
#define rsnd_priv_to_pdev(priv) ((priv)->pdev)
|
|
|
|
#define rsnd_priv_to_dev(priv) (&(rsnd_priv_to_pdev(priv)->dev))
|
2013-07-22 12:35:52 +08:00
|
|
|
|
2015-11-10 13:13:12 +08:00
|
|
|
#define rsnd_is_gen1(priv) (((priv)->flags & RSND_GEN_MASK) == RSND_GEN1)
|
|
|
|
#define rsnd_is_gen2(priv) (((priv)->flags & RSND_GEN_MASK) == RSND_GEN2)
|
2018-04-11 10:10:29 +08:00
|
|
|
#define rsnd_is_gen3(priv) (((priv)->flags & RSND_GEN_MASK) == RSND_GEN3)
|
2015-11-10 13:13:12 +08:00
|
|
|
|
2017-10-02 07:47:50 +08:00
|
|
|
#define rsnd_flags_has(p, f) ((p)->flags & (f))
|
|
|
|
#define rsnd_flags_set(p, f) ((p)->flags |= (f))
|
|
|
|
#define rsnd_flags_del(p, f) ((p)->flags &= ~(f))
|
|
|
|
|
2014-11-27 16:06:14 +08:00
|
|
|
/*
|
|
|
|
* rsnd_kctrl
|
|
|
|
*/
|
|
|
|
struct rsnd_kctrl_cfg {
|
|
|
|
unsigned int max;
|
|
|
|
unsigned int size;
|
|
|
|
u32 *val;
|
|
|
|
const char * const *texts;
|
2017-06-07 08:11:48 +08:00
|
|
|
int (*accept)(struct rsnd_dai_stream *io);
|
2015-06-15 14:27:28 +08:00
|
|
|
void (*update)(struct rsnd_dai_stream *io, struct rsnd_mod *mod);
|
|
|
|
struct rsnd_dai_stream *io;
|
2015-02-02 12:53:53 +08:00
|
|
|
struct snd_card *card;
|
|
|
|
struct snd_kcontrol *kctrl;
|
2017-07-24 09:45:59 +08:00
|
|
|
struct rsnd_mod *mod;
|
2014-11-27 16:06:14 +08:00
|
|
|
};
|
|
|
|
|
2016-02-18 16:13:13 +08:00
|
|
|
#define RSND_MAX_CHANNELS 8
|
2014-11-27 16:06:14 +08:00
|
|
|
struct rsnd_kctrl_cfg_m {
|
|
|
|
struct rsnd_kctrl_cfg cfg;
|
2016-02-18 16:13:13 +08:00
|
|
|
u32 val[RSND_MAX_CHANNELS];
|
2014-11-27 16:06:14 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
struct rsnd_kctrl_cfg_s {
|
|
|
|
struct rsnd_kctrl_cfg cfg;
|
|
|
|
u32 val;
|
|
|
|
};
|
2017-10-11 12:42:34 +08:00
|
|
|
#define rsnd_kctrl_size(x) ((x).cfg.size)
|
|
|
|
#define rsnd_kctrl_max(x) ((x).cfg.max)
|
|
|
|
#define rsnd_kctrl_valm(x, i) ((x).val[i]) /* = (x).cfg.val[i] */
|
|
|
|
#define rsnd_kctrl_vals(x) ((x).val) /* = (x).cfg.val[0] */
|
2014-11-27 16:06:14 +08:00
|
|
|
|
2017-06-07 08:11:48 +08:00
|
|
|
int rsnd_kctrl_accept_anytime(struct rsnd_dai_stream *io);
|
|
|
|
int rsnd_kctrl_accept_runtime(struct rsnd_dai_stream *io);
|
2017-04-06 15:25:13 +08:00
|
|
|
struct rsnd_kctrl_cfg *rsnd_kctrl_init_m(struct rsnd_kctrl_cfg_m *cfg);
|
|
|
|
struct rsnd_kctrl_cfg *rsnd_kctrl_init_s(struct rsnd_kctrl_cfg_s *cfg);
|
|
|
|
int rsnd_kctrl_new(struct rsnd_mod *mod,
|
|
|
|
struct rsnd_dai_stream *io,
|
|
|
|
struct snd_soc_pcm_runtime *rtd,
|
|
|
|
const unsigned char *name,
|
2017-06-07 08:11:48 +08:00
|
|
|
int (*accept)(struct rsnd_dai_stream *io),
|
2017-04-06 15:25:13 +08:00
|
|
|
void (*update)(struct rsnd_dai_stream *io,
|
|
|
|
struct rsnd_mod *mod),
|
|
|
|
struct rsnd_kctrl_cfg *cfg,
|
|
|
|
const char * const *texts,
|
|
|
|
int size,
|
|
|
|
u32 max);
|
|
|
|
|
2017-06-07 08:11:48 +08:00
|
|
|
#define rsnd_kctrl_new_m(mod, io, rtd, name, accept, update, cfg, size, max) \
|
|
|
|
rsnd_kctrl_new(mod, io, rtd, name, accept, update, rsnd_kctrl_init_m(cfg), \
|
2017-04-06 15:25:13 +08:00
|
|
|
NULL, size, max)
|
|
|
|
|
2017-06-07 08:11:48 +08:00
|
|
|
#define rsnd_kctrl_new_s(mod, io, rtd, name, accept, update, cfg, max) \
|
|
|
|
rsnd_kctrl_new(mod, io, rtd, name, accept, update, rsnd_kctrl_init_s(cfg), \
|
2017-04-06 15:25:13 +08:00
|
|
|
NULL, 1, max)
|
|
|
|
|
2017-10-02 07:49:03 +08:00
|
|
|
#define rsnd_kctrl_new_e(mod, io, rtd, name, accept, update, cfg, texts, size) \
|
2017-06-07 08:11:48 +08:00
|
|
|
rsnd_kctrl_new(mod, io, rtd, name, accept, update, rsnd_kctrl_init_s(cfg), \
|
2017-10-02 07:49:03 +08:00
|
|
|
texts, 1, size)
|
|
|
|
|
|
|
|
extern const char * const volume_ramp_rate[];
|
|
|
|
#define VOLUME_RAMP_MAX_DVC (0x17 + 1)
|
2017-10-02 07:49:18 +08:00
|
|
|
#define VOLUME_RAMP_MAX_MIX (0x0a + 1)
|
2014-11-27 16:06:14 +08:00
|
|
|
|
2015-07-15 15:16:37 +08:00
|
|
|
/*
|
|
|
|
* R-Car SSI
|
|
|
|
*/
|
2015-11-10 13:14:12 +08:00
|
|
|
int rsnd_ssi_probe(struct rsnd_priv *priv);
|
|
|
|
void rsnd_ssi_remove(struct rsnd_priv *priv);
|
2015-07-15 15:16:37 +08:00
|
|
|
struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id);
|
|
|
|
int rsnd_ssi_is_dma_mode(struct rsnd_mod *mod);
|
2015-10-22 11:15:46 +08:00
|
|
|
int rsnd_ssi_use_busif(struct rsnd_dai_stream *io);
|
2016-02-18 16:18:54 +08:00
|
|
|
u32 rsnd_ssi_multi_slaves_runtime(struct rsnd_dai_stream *io);
|
2015-10-22 11:15:46 +08:00
|
|
|
|
2017-05-18 09:28:22 +08:00
|
|
|
#define RSND_SSI_HDMI_PORT0 0xf0
|
|
|
|
#define RSND_SSI_HDMI_PORT1 0xf1
|
|
|
|
int rsnd_ssi_hdmi_port(struct rsnd_dai_stream *io);
|
|
|
|
void rsnd_ssi_parse_hdmi_connection(struct rsnd_priv *priv,
|
|
|
|
struct device_node *endpoint,
|
|
|
|
int dai_i);
|
|
|
|
|
2015-10-22 11:15:46 +08:00
|
|
|
#define rsnd_ssi_is_pin_sharing(io) \
|
|
|
|
__rsnd_ssi_is_pin_sharing(rsnd_io_to_mod_ssi(io))
|
|
|
|
int __rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod);
|
2015-07-15 15:16:37 +08:00
|
|
|
|
2016-10-19 11:57:47 +08:00
|
|
|
#define rsnd_ssi_of_node(priv) rsnd_parse_of_node(priv, RSND_NODE_SSI)
|
2015-12-17 11:00:10 +08:00
|
|
|
void rsnd_parse_connect_ssi(struct rsnd_dai *rdai,
|
|
|
|
struct device_node *playback,
|
|
|
|
struct device_node *capture);
|
2017-06-16 08:02:59 +08:00
|
|
|
unsigned int rsnd_ssi_clk_query(struct rsnd_priv *priv,
|
2017-06-15 08:50:02 +08:00
|
|
|
int param1, int param2, int *idx);
|
2015-11-10 13:11:18 +08:00
|
|
|
|
2015-10-26 16:43:41 +08:00
|
|
|
/*
|
|
|
|
* R-Car SSIU
|
|
|
|
*/
|
|
|
|
int rsnd_ssiu_attach(struct rsnd_dai_stream *io,
|
|
|
|
struct rsnd_mod *mod);
|
2015-11-10 13:14:12 +08:00
|
|
|
int rsnd_ssiu_probe(struct rsnd_priv *priv);
|
|
|
|
void rsnd_ssiu_remove(struct rsnd_priv *priv);
|
2015-10-26 16:43:41 +08:00
|
|
|
|
2013-07-22 12:36:35 +08:00
|
|
|
/*
|
2014-03-04 12:51:21 +08:00
|
|
|
* R-Car SRC
|
2013-07-22 12:36:35 +08:00
|
|
|
*/
|
2015-11-10 13:14:12 +08:00
|
|
|
int rsnd_src_probe(struct rsnd_priv *priv);
|
|
|
|
void rsnd_src_remove(struct rsnd_priv *priv);
|
2014-03-04 12:51:21 +08:00
|
|
|
struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id);
|
2016-03-07 13:08:33 +08:00
|
|
|
|
|
|
|
#define rsnd_src_get_in_rate(priv, io) rsnd_src_get_rate(priv, io, 1)
|
|
|
|
#define rsnd_src_get_out_rate(priv, io) rsnd_src_get_rate(priv, io, 0)
|
|
|
|
unsigned int rsnd_src_get_rate(struct rsnd_priv *priv,
|
|
|
|
struct rsnd_dai_stream *io,
|
|
|
|
int is_in);
|
|
|
|
|
2016-10-19 11:57:47 +08:00
|
|
|
#define rsnd_src_of_node(priv) rsnd_parse_of_node(priv, RSND_NODE_SRC)
|
2015-12-17 10:58:14 +08:00
|
|
|
#define rsnd_parse_connect_src(rdai, playback, capture) \
|
|
|
|
rsnd_parse_connect_common(rdai, rsnd_src_mod_get, \
|
|
|
|
rsnd_src_of_node(rsnd_rdai_to_priv(rdai)), \
|
|
|
|
playback, capture)
|
2013-12-20 11:28:51 +08:00
|
|
|
|
2015-07-15 15:17:17 +08:00
|
|
|
/*
|
|
|
|
* R-Car CTU
|
|
|
|
*/
|
2015-11-10 13:14:12 +08:00
|
|
|
int rsnd_ctu_probe(struct rsnd_priv *priv);
|
|
|
|
void rsnd_ctu_remove(struct rsnd_priv *priv);
|
2016-02-25 13:53:00 +08:00
|
|
|
int rsnd_ctu_converted_channel(struct rsnd_mod *mod);
|
2015-07-15 15:17:17 +08:00
|
|
|
struct rsnd_mod *rsnd_ctu_mod_get(struct rsnd_priv *priv, int id);
|
2016-10-19 11:57:47 +08:00
|
|
|
#define rsnd_ctu_of_node(priv) rsnd_parse_of_node(priv, RSND_NODE_CTU)
|
2015-12-17 10:58:14 +08:00
|
|
|
#define rsnd_parse_connect_ctu(rdai, playback, capture) \
|
|
|
|
rsnd_parse_connect_common(rdai, rsnd_ctu_mod_get, \
|
|
|
|
rsnd_ctu_of_node(rsnd_rdai_to_priv(rdai)), \
|
|
|
|
playback, capture)
|
2015-07-15 15:17:17 +08:00
|
|
|
|
2015-07-15 15:17:36 +08:00
|
|
|
/*
|
|
|
|
* R-Car MIX
|
|
|
|
*/
|
2015-11-10 13:14:12 +08:00
|
|
|
int rsnd_mix_probe(struct rsnd_priv *priv);
|
|
|
|
void rsnd_mix_remove(struct rsnd_priv *priv);
|
2015-07-15 15:17:36 +08:00
|
|
|
struct rsnd_mod *rsnd_mix_mod_get(struct rsnd_priv *priv, int id);
|
2016-10-19 11:57:47 +08:00
|
|
|
#define rsnd_mix_of_node(priv) rsnd_parse_of_node(priv, RSND_NODE_MIX)
|
2015-12-17 10:58:14 +08:00
|
|
|
#define rsnd_parse_connect_mix(rdai, playback, capture) \
|
|
|
|
rsnd_parse_connect_common(rdai, rsnd_mix_mod_get, \
|
|
|
|
rsnd_mix_of_node(rsnd_rdai_to_priv(rdai)), \
|
|
|
|
playback, capture)
|
2015-07-15 15:17:36 +08:00
|
|
|
|
2014-05-09 08:44:49 +08:00
|
|
|
/*
|
|
|
|
* R-Car DVC
|
|
|
|
*/
|
2015-11-10 13:14:12 +08:00
|
|
|
int rsnd_dvc_probe(struct rsnd_priv *priv);
|
|
|
|
void rsnd_dvc_remove(struct rsnd_priv *priv);
|
2014-05-09 08:44:49 +08:00
|
|
|
struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id);
|
2016-10-19 11:57:47 +08:00
|
|
|
#define rsnd_dvc_of_node(priv) rsnd_parse_of_node(priv, RSND_NODE_DVC)
|
2015-12-17 10:58:14 +08:00
|
|
|
#define rsnd_parse_connect_dvc(rdai, playback, capture) \
|
|
|
|
rsnd_parse_connect_common(rdai, rsnd_dvc_mod_get, \
|
|
|
|
rsnd_dvc_of_node(rsnd_rdai_to_priv(rdai)), \
|
|
|
|
playback, capture)
|
2014-05-09 08:44:49 +08:00
|
|
|
|
2015-10-26 16:43:21 +08:00
|
|
|
/*
|
|
|
|
* R-Car CMD
|
|
|
|
*/
|
2015-11-10 13:14:12 +08:00
|
|
|
int rsnd_cmd_probe(struct rsnd_priv *priv);
|
|
|
|
void rsnd_cmd_remove(struct rsnd_priv *priv);
|
2015-10-26 16:43:21 +08:00
|
|
|
int rsnd_cmd_attach(struct rsnd_dai_stream *io, int id);
|
|
|
|
|
2015-09-10 15:03:08 +08:00
|
|
|
void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type);
|
2017-04-19 08:41:24 +08:00
|
|
|
#ifdef DEBUG
|
2015-09-10 15:03:08 +08:00
|
|
|
#define rsnd_mod_confirm_ssi(mssi) rsnd_mod_make_sure(mssi, RSND_MOD_SSI)
|
|
|
|
#define rsnd_mod_confirm_src(msrc) rsnd_mod_make_sure(msrc, RSND_MOD_SRC)
|
|
|
|
#define rsnd_mod_confirm_dvc(mdvc) rsnd_mod_make_sure(mdvc, RSND_MOD_DVC)
|
|
|
|
#else
|
|
|
|
#define rsnd_mod_confirm_ssi(mssi)
|
|
|
|
#define rsnd_mod_confirm_src(msrc)
|
|
|
|
#define rsnd_mod_confirm_dvc(mdvc)
|
|
|
|
#endif
|
|
|
|
|
2018-02-13 10:08:53 +08:00
|
|
|
/*
|
|
|
|
* If you don't need interrupt status debug message,
|
|
|
|
* define RSND_DEBUG_NO_IRQ_STATUS as 1 on top of src.c/ssi.c
|
|
|
|
*
|
|
|
|
* #define RSND_DEBUG_NO_IRQ_STATUS 1
|
|
|
|
*/
|
|
|
|
#define rsnd_dbg_irq_status(dev, param...) \
|
|
|
|
if (!IS_BUILTIN(RSND_DEBUG_NO_IRQ_STATUS)) \
|
|
|
|
dev_dbg(dev, param)
|
|
|
|
|
2018-02-13 10:09:14 +08:00
|
|
|
/*
|
|
|
|
* If you don't need rsnd_dai_call debug message,
|
|
|
|
* define RSND_DEBUG_NO_DAI_CALL as 1 on top of core.c
|
|
|
|
*
|
|
|
|
* #define RSND_DEBUG_NO_DAI_CALL 1
|
|
|
|
*/
|
|
|
|
#define rsnd_dbg_dai_call(dev, param...) \
|
|
|
|
if (!IS_BUILTIN(RSND_DEBUG_NO_DAI_CALL)) \
|
|
|
|
dev_dbg(dev, param)
|
|
|
|
|
2013-07-22 12:35:52 +08:00
|
|
|
#endif
|