mirror of
https://git.proxmox.com/git/mirror_ubuntu-kernels.git
synced 2025-11-19 17:46:02 +00:00
All SoC has reg-name, no need to support getting resource from ID any more. Remove it. To get physical address for DMA settings, it still need to know the index, but it is no longer fixed. This patch tidyup it. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Link: https://msgid.link/r/87zfuca4e6.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown <broonie@kernel.org>
496 lines
15 KiB
C
496 lines
15 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
//
|
|
// Renesas R-Car Gen1 SRU/SSI support
|
|
//
|
|
// Copyright (C) 2013 Renesas Solutions Corp.
|
|
// Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
|
|
|
|
/*
|
|
* #define DEBUG
|
|
*
|
|
* you can also add below in
|
|
* ${LINUX}/drivers/base/regmap/regmap.c
|
|
* for regmap debug
|
|
*
|
|
* #define LOG_DEVICE "xxxx.rcar_sound"
|
|
*/
|
|
|
|
#include "rsnd.h"
|
|
|
|
struct rsnd_gen {
|
|
struct rsnd_gen_ops *ops;
|
|
|
|
/* RSND_BASE_MAX base */
|
|
void __iomem *base[RSND_BASE_MAX];
|
|
phys_addr_t res[RSND_BASE_MAX];
|
|
struct regmap *regmap[RSND_BASE_MAX];
|
|
|
|
/* RSND_REG_MAX base */
|
|
struct regmap_field *regs[REG_MAX];
|
|
const char *reg_name[REG_MAX];
|
|
};
|
|
|
|
#define rsnd_priv_to_gen(p) ((struct rsnd_gen *)(p)->gen)
|
|
#define rsnd_reg_name(gen, id) ((gen)->reg_name[id])
|
|
|
|
struct rsnd_regmap_field_conf {
|
|
int idx;
|
|
unsigned int reg_offset;
|
|
unsigned int id_offset;
|
|
const char *reg_name;
|
|
};
|
|
|
|
#define RSND_REG_SET(id, offset, _id_offset, n) \
|
|
{ \
|
|
.idx = id, \
|
|
.reg_offset = offset, \
|
|
.id_offset = _id_offset, \
|
|
.reg_name = n, \
|
|
}
|
|
/* single address mapping */
|
|
#define RSND_GEN_S_REG(id, offset) \
|
|
RSND_REG_SET(id, offset, 0, #id)
|
|
|
|
/* multi address mapping */
|
|
#define RSND_GEN_M_REG(id, offset, _id_offset) \
|
|
RSND_REG_SET(id, offset, _id_offset, #id)
|
|
|
|
/*
|
|
* basic function
|
|
*/
|
|
static int rsnd_is_accessible_reg(struct rsnd_priv *priv,
|
|
struct rsnd_gen *gen, enum rsnd_reg reg)
|
|
{
|
|
if (!gen->regs[reg]) {
|
|
struct device *dev = rsnd_priv_to_dev(priv);
|
|
|
|
dev_err(dev, "unsupported register access %x\n", reg);
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int rsnd_mod_id_cmd(struct rsnd_mod *mod)
|
|
{
|
|
if (mod->ops->id_cmd)
|
|
return mod->ops->id_cmd(mod);
|
|
|
|
return rsnd_mod_id(mod);
|
|
}
|
|
|
|
u32 rsnd_mod_read(struct rsnd_mod *mod, enum rsnd_reg reg)
|
|
{
|
|
struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
|
|
struct device *dev = rsnd_priv_to_dev(priv);
|
|
struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
|
|
u32 val;
|
|
|
|
if (!rsnd_is_accessible_reg(priv, gen, reg))
|
|
return 0;
|
|
|
|
regmap_fields_read(gen->regs[reg], rsnd_mod_id_cmd(mod), &val);
|
|
|
|
dev_dbg(dev, "r %s - %-18s (%4d) : %08x\n",
|
|
rsnd_mod_name(mod),
|
|
rsnd_reg_name(gen, reg), reg, val);
|
|
|
|
return val;
|
|
}
|
|
|
|
void rsnd_mod_write(struct rsnd_mod *mod,
|
|
enum rsnd_reg reg, u32 data)
|
|
{
|
|
struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
|
|
struct device *dev = rsnd_priv_to_dev(priv);
|
|
struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
|
|
|
|
if (!rsnd_is_accessible_reg(priv, gen, reg))
|
|
return;
|
|
|
|
regmap_fields_force_write(gen->regs[reg], rsnd_mod_id_cmd(mod), data);
|
|
|
|
dev_dbg(dev, "w %s - %-18s (%4d) : %08x\n",
|
|
rsnd_mod_name(mod),
|
|
rsnd_reg_name(gen, reg), reg, data);
|
|
}
|
|
|
|
void rsnd_mod_bset(struct rsnd_mod *mod,
|
|
enum rsnd_reg reg, u32 mask, u32 data)
|
|
{
|
|
struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
|
|
struct device *dev = rsnd_priv_to_dev(priv);
|
|
struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
|
|
|
|
if (!rsnd_is_accessible_reg(priv, gen, reg))
|
|
return;
|
|
|
|
regmap_fields_force_update_bits(gen->regs[reg],
|
|
rsnd_mod_id_cmd(mod), mask, data);
|
|
|
|
dev_dbg(dev, "b %s - %-18s (%4d) : %08x/%08x\n",
|
|
rsnd_mod_name(mod),
|
|
rsnd_reg_name(gen, reg), reg, data, mask);
|
|
|
|
}
|
|
|
|
phys_addr_t rsnd_gen_get_phy_addr(struct rsnd_priv *priv, int reg_id)
|
|
{
|
|
struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
|
|
|
|
return gen->res[reg_id];
|
|
}
|
|
|
|
#ifdef CONFIG_DEBUG_FS
|
|
void __iomem *rsnd_gen_get_base_addr(struct rsnd_priv *priv, int reg_id)
|
|
{
|
|
struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
|
|
|
|
return gen->base[reg_id];
|
|
}
|
|
#endif
|
|
|
|
#define rsnd_gen_regmap_init(priv, id_size, reg_id, name, conf) \
|
|
_rsnd_gen_regmap_init(priv, id_size, reg_id, name, conf, ARRAY_SIZE(conf))
|
|
static int _rsnd_gen_regmap_init(struct rsnd_priv *priv,
|
|
int id_size,
|
|
int reg_id,
|
|
const char *name,
|
|
const struct rsnd_regmap_field_conf *conf,
|
|
int conf_size)
|
|
{
|
|
struct platform_device *pdev = rsnd_priv_to_pdev(priv);
|
|
struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
|
|
struct device *dev = rsnd_priv_to_dev(priv);
|
|
struct resource *res;
|
|
struct regmap_config regc;
|
|
struct regmap_field *regs;
|
|
struct regmap *regmap;
|
|
struct reg_field regf;
|
|
void __iomem *base;
|
|
int i;
|
|
|
|
memset(®c, 0, sizeof(regc));
|
|
regc.reg_bits = 32;
|
|
regc.val_bits = 32;
|
|
regc.reg_stride = 4;
|
|
regc.name = name;
|
|
|
|
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name);
|
|
if (!res)
|
|
return -ENODEV;
|
|
|
|
base = devm_ioremap_resource(dev, res);
|
|
if (IS_ERR(base))
|
|
return PTR_ERR(base);
|
|
|
|
regmap = devm_regmap_init_mmio(dev, base, ®c);
|
|
if (IS_ERR(regmap))
|
|
return PTR_ERR(regmap);
|
|
|
|
/* RSND_BASE_MAX base */
|
|
gen->base[reg_id] = base;
|
|
gen->regmap[reg_id] = regmap;
|
|
gen->res[reg_id] = res->start;
|
|
|
|
for (i = 0; i < conf_size; i++) {
|
|
|
|
regf.reg = conf[i].reg_offset;
|
|
regf.id_offset = conf[i].id_offset;
|
|
regf.lsb = 0;
|
|
regf.msb = 31;
|
|
regf.id_size = id_size;
|
|
|
|
regs = devm_regmap_field_alloc(dev, regmap, regf);
|
|
if (IS_ERR(regs))
|
|
return PTR_ERR(regs);
|
|
|
|
/* RSND_REG_MAX base */
|
|
gen->regs[conf[i].idx] = regs;
|
|
gen->reg_name[conf[i].idx] = conf[i].reg_name;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* (A) : Gen4 is 0xa0c, but it is not used.
|
|
* see
|
|
* rsnd_ssiu_init()
|
|
*/
|
|
static const struct rsnd_regmap_field_conf conf_common_ssiu[] = {
|
|
RSND_GEN_S_REG(SSI_MODE0, 0x800),
|
|
RSND_GEN_S_REG(SSI_MODE1, 0x804),
|
|
RSND_GEN_S_REG(SSI_MODE2, 0x808), // (A)
|
|
RSND_GEN_S_REG(SSI_CONTROL, 0x810),
|
|
RSND_GEN_S_REG(SSI_SYS_STATUS0, 0x840),
|
|
RSND_GEN_S_REG(SSI_SYS_STATUS1, 0x844),
|
|
RSND_GEN_S_REG(SSI_SYS_STATUS2, 0x848),
|
|
RSND_GEN_S_REG(SSI_SYS_STATUS3, 0x84c),
|
|
RSND_GEN_S_REG(SSI_SYS_STATUS4, 0x880),
|
|
RSND_GEN_S_REG(SSI_SYS_STATUS5, 0x884),
|
|
RSND_GEN_S_REG(SSI_SYS_STATUS6, 0x888),
|
|
RSND_GEN_S_REG(SSI_SYS_STATUS7, 0x88c),
|
|
RSND_GEN_S_REG(SSI_SYS_INT_ENABLE0, 0x850),
|
|
RSND_GEN_S_REG(SSI_SYS_INT_ENABLE1, 0x854),
|
|
RSND_GEN_S_REG(SSI_SYS_INT_ENABLE2, 0x858),
|
|
RSND_GEN_S_REG(SSI_SYS_INT_ENABLE3, 0x85c),
|
|
RSND_GEN_S_REG(SSI_SYS_INT_ENABLE4, 0x890),
|
|
RSND_GEN_S_REG(SSI_SYS_INT_ENABLE5, 0x894),
|
|
RSND_GEN_S_REG(SSI_SYS_INT_ENABLE6, 0x898),
|
|
RSND_GEN_S_REG(SSI_SYS_INT_ENABLE7, 0x89c),
|
|
RSND_GEN_S_REG(HDMI0_SEL, 0x9e0),
|
|
RSND_GEN_S_REG(HDMI1_SEL, 0x9e4),
|
|
RSND_GEN_M_REG(SSI_BUSIF0_MODE, 0x0, 0x80),
|
|
RSND_GEN_M_REG(SSI_BUSIF0_ADINR, 0x4, 0x80),
|
|
RSND_GEN_M_REG(SSI_BUSIF0_DALIGN, 0x8, 0x80),
|
|
RSND_GEN_M_REG(SSI_BUSIF1_MODE, 0x20, 0x80),
|
|
RSND_GEN_M_REG(SSI_BUSIF1_ADINR, 0x24, 0x80),
|
|
RSND_GEN_M_REG(SSI_BUSIF1_DALIGN, 0x28, 0x80),
|
|
RSND_GEN_M_REG(SSI_BUSIF2_MODE, 0x40, 0x80),
|
|
RSND_GEN_M_REG(SSI_BUSIF2_ADINR, 0x44, 0x80),
|
|
RSND_GEN_M_REG(SSI_BUSIF2_DALIGN, 0x48, 0x80),
|
|
RSND_GEN_M_REG(SSI_BUSIF3_MODE, 0x60, 0x80),
|
|
RSND_GEN_M_REG(SSI_BUSIF3_ADINR, 0x64, 0x80),
|
|
RSND_GEN_M_REG(SSI_BUSIF3_DALIGN, 0x68, 0x80),
|
|
RSND_GEN_M_REG(SSI_BUSIF4_MODE, 0x500, 0x80),
|
|
RSND_GEN_M_REG(SSI_BUSIF4_ADINR, 0x504, 0x80),
|
|
RSND_GEN_M_REG(SSI_BUSIF4_DALIGN, 0x508, 0x80),
|
|
RSND_GEN_M_REG(SSI_BUSIF5_MODE, 0x520, 0x80),
|
|
RSND_GEN_M_REG(SSI_BUSIF5_ADINR, 0x524, 0x80),
|
|
RSND_GEN_M_REG(SSI_BUSIF5_DALIGN, 0x528, 0x80),
|
|
RSND_GEN_M_REG(SSI_BUSIF6_MODE, 0x540, 0x80),
|
|
RSND_GEN_M_REG(SSI_BUSIF6_ADINR, 0x544, 0x80),
|
|
RSND_GEN_M_REG(SSI_BUSIF6_DALIGN, 0x548, 0x80),
|
|
RSND_GEN_M_REG(SSI_BUSIF7_MODE, 0x560, 0x80),
|
|
RSND_GEN_M_REG(SSI_BUSIF7_ADINR, 0x564, 0x80),
|
|
RSND_GEN_M_REG(SSI_BUSIF7_DALIGN, 0x568, 0x80),
|
|
RSND_GEN_M_REG(SSI_MODE, 0xc, 0x80),
|
|
RSND_GEN_M_REG(SSI_CTRL, 0x10, 0x80),
|
|
RSND_GEN_M_REG(SSI_INT_ENABLE, 0x18, 0x80),
|
|
RSND_GEN_S_REG(SSI9_BUSIF0_MODE, 0x48c),
|
|
RSND_GEN_S_REG(SSI9_BUSIF0_ADINR, 0x484),
|
|
RSND_GEN_S_REG(SSI9_BUSIF0_DALIGN, 0x488),
|
|
RSND_GEN_S_REG(SSI9_BUSIF1_MODE, 0x4a0),
|
|
RSND_GEN_S_REG(SSI9_BUSIF1_ADINR, 0x4a4),
|
|
RSND_GEN_S_REG(SSI9_BUSIF1_DALIGN, 0x4a8),
|
|
RSND_GEN_S_REG(SSI9_BUSIF2_MODE, 0x4c0),
|
|
RSND_GEN_S_REG(SSI9_BUSIF2_ADINR, 0x4c4),
|
|
RSND_GEN_S_REG(SSI9_BUSIF2_DALIGN, 0x4c8),
|
|
RSND_GEN_S_REG(SSI9_BUSIF3_MODE, 0x4e0),
|
|
RSND_GEN_S_REG(SSI9_BUSIF3_ADINR, 0x4e4),
|
|
RSND_GEN_S_REG(SSI9_BUSIF3_DALIGN, 0x4e8),
|
|
RSND_GEN_S_REG(SSI9_BUSIF4_MODE, 0xd80),
|
|
RSND_GEN_S_REG(SSI9_BUSIF4_ADINR, 0xd84),
|
|
RSND_GEN_S_REG(SSI9_BUSIF4_DALIGN, 0xd88),
|
|
RSND_GEN_S_REG(SSI9_BUSIF5_MODE, 0xda0),
|
|
RSND_GEN_S_REG(SSI9_BUSIF5_ADINR, 0xda4),
|
|
RSND_GEN_S_REG(SSI9_BUSIF5_DALIGN, 0xda8),
|
|
RSND_GEN_S_REG(SSI9_BUSIF6_MODE, 0xdc0),
|
|
RSND_GEN_S_REG(SSI9_BUSIF6_ADINR, 0xdc4),
|
|
RSND_GEN_S_REG(SSI9_BUSIF6_DALIGN, 0xdc8),
|
|
RSND_GEN_S_REG(SSI9_BUSIF7_MODE, 0xde0),
|
|
RSND_GEN_S_REG(SSI9_BUSIF7_ADINR, 0xde4),
|
|
RSND_GEN_S_REG(SSI9_BUSIF7_DALIGN, 0xde8),
|
|
};
|
|
|
|
static const struct rsnd_regmap_field_conf conf_common_scu[] = {
|
|
RSND_GEN_M_REG(SRC_I_BUSIF_MODE, 0x0, 0x20),
|
|
RSND_GEN_M_REG(SRC_O_BUSIF_MODE, 0x4, 0x20),
|
|
RSND_GEN_M_REG(SRC_BUSIF_DALIGN, 0x8, 0x20),
|
|
RSND_GEN_M_REG(SRC_ROUTE_MODE0, 0xc, 0x20),
|
|
RSND_GEN_M_REG(SRC_CTRL, 0x10, 0x20),
|
|
RSND_GEN_M_REG(SRC_INT_ENABLE0, 0x18, 0x20),
|
|
RSND_GEN_M_REG(CMD_BUSIF_MODE, 0x184, 0x20),
|
|
RSND_GEN_M_REG(CMD_BUSIF_DALIGN, 0x188, 0x20),
|
|
RSND_GEN_M_REG(CMD_ROUTE_SLCT, 0x18c, 0x20),
|
|
RSND_GEN_M_REG(CMD_CTRL, 0x190, 0x20),
|
|
RSND_GEN_S_REG(SCU_SYS_STATUS0, 0x1c8),
|
|
RSND_GEN_S_REG(SCU_SYS_INT_EN0, 0x1cc),
|
|
RSND_GEN_S_REG(SCU_SYS_STATUS1, 0x1d0),
|
|
RSND_GEN_S_REG(SCU_SYS_INT_EN1, 0x1d4),
|
|
RSND_GEN_M_REG(SRC_SWRSR, 0x200, 0x40),
|
|
RSND_GEN_M_REG(SRC_SRCIR, 0x204, 0x40),
|
|
RSND_GEN_M_REG(SRC_ADINR, 0x214, 0x40),
|
|
RSND_GEN_M_REG(SRC_IFSCR, 0x21c, 0x40),
|
|
RSND_GEN_M_REG(SRC_IFSVR, 0x220, 0x40),
|
|
RSND_GEN_M_REG(SRC_SRCCR, 0x224, 0x40),
|
|
RSND_GEN_M_REG(SRC_BSDSR, 0x22c, 0x40),
|
|
RSND_GEN_M_REG(SRC_BSISR, 0x238, 0x40),
|
|
RSND_GEN_M_REG(CTU_SWRSR, 0x500, 0x100),
|
|
RSND_GEN_M_REG(CTU_CTUIR, 0x504, 0x100),
|
|
RSND_GEN_M_REG(CTU_ADINR, 0x508, 0x100),
|
|
RSND_GEN_M_REG(CTU_CPMDR, 0x510, 0x100),
|
|
RSND_GEN_M_REG(CTU_SCMDR, 0x514, 0x100),
|
|
RSND_GEN_M_REG(CTU_SV00R, 0x518, 0x100),
|
|
RSND_GEN_M_REG(CTU_SV01R, 0x51c, 0x100),
|
|
RSND_GEN_M_REG(CTU_SV02R, 0x520, 0x100),
|
|
RSND_GEN_M_REG(CTU_SV03R, 0x524, 0x100),
|
|
RSND_GEN_M_REG(CTU_SV04R, 0x528, 0x100),
|
|
RSND_GEN_M_REG(CTU_SV05R, 0x52c, 0x100),
|
|
RSND_GEN_M_REG(CTU_SV06R, 0x530, 0x100),
|
|
RSND_GEN_M_REG(CTU_SV07R, 0x534, 0x100),
|
|
RSND_GEN_M_REG(CTU_SV10R, 0x538, 0x100),
|
|
RSND_GEN_M_REG(CTU_SV11R, 0x53c, 0x100),
|
|
RSND_GEN_M_REG(CTU_SV12R, 0x540, 0x100),
|
|
RSND_GEN_M_REG(CTU_SV13R, 0x544, 0x100),
|
|
RSND_GEN_M_REG(CTU_SV14R, 0x548, 0x100),
|
|
RSND_GEN_M_REG(CTU_SV15R, 0x54c, 0x100),
|
|
RSND_GEN_M_REG(CTU_SV16R, 0x550, 0x100),
|
|
RSND_GEN_M_REG(CTU_SV17R, 0x554, 0x100),
|
|
RSND_GEN_M_REG(CTU_SV20R, 0x558, 0x100),
|
|
RSND_GEN_M_REG(CTU_SV21R, 0x55c, 0x100),
|
|
RSND_GEN_M_REG(CTU_SV22R, 0x560, 0x100),
|
|
RSND_GEN_M_REG(CTU_SV23R, 0x564, 0x100),
|
|
RSND_GEN_M_REG(CTU_SV24R, 0x568, 0x100),
|
|
RSND_GEN_M_REG(CTU_SV25R, 0x56c, 0x100),
|
|
RSND_GEN_M_REG(CTU_SV26R, 0x570, 0x100),
|
|
RSND_GEN_M_REG(CTU_SV27R, 0x574, 0x100),
|
|
RSND_GEN_M_REG(CTU_SV30R, 0x578, 0x100),
|
|
RSND_GEN_M_REG(CTU_SV31R, 0x57c, 0x100),
|
|
RSND_GEN_M_REG(CTU_SV32R, 0x580, 0x100),
|
|
RSND_GEN_M_REG(CTU_SV33R, 0x584, 0x100),
|
|
RSND_GEN_M_REG(CTU_SV34R, 0x588, 0x100),
|
|
RSND_GEN_M_REG(CTU_SV35R, 0x58c, 0x100),
|
|
RSND_GEN_M_REG(CTU_SV36R, 0x590, 0x100),
|
|
RSND_GEN_M_REG(CTU_SV37R, 0x594, 0x100),
|
|
RSND_GEN_M_REG(MIX_SWRSR, 0xd00, 0x40),
|
|
RSND_GEN_M_REG(MIX_MIXIR, 0xd04, 0x40),
|
|
RSND_GEN_M_REG(MIX_ADINR, 0xd08, 0x40),
|
|
RSND_GEN_M_REG(MIX_MIXMR, 0xd10, 0x40),
|
|
RSND_GEN_M_REG(MIX_MVPDR, 0xd14, 0x40),
|
|
RSND_GEN_M_REG(MIX_MDBAR, 0xd18, 0x40),
|
|
RSND_GEN_M_REG(MIX_MDBBR, 0xd1c, 0x40),
|
|
RSND_GEN_M_REG(MIX_MDBCR, 0xd20, 0x40),
|
|
RSND_GEN_M_REG(MIX_MDBDR, 0xd24, 0x40),
|
|
RSND_GEN_M_REG(MIX_MDBER, 0xd28, 0x40),
|
|
RSND_GEN_M_REG(DVC_SWRSR, 0xe00, 0x100),
|
|
RSND_GEN_M_REG(DVC_DVUIR, 0xe04, 0x100),
|
|
RSND_GEN_M_REG(DVC_ADINR, 0xe08, 0x100),
|
|
RSND_GEN_M_REG(DVC_DVUCR, 0xe10, 0x100),
|
|
RSND_GEN_M_REG(DVC_ZCMCR, 0xe14, 0x100),
|
|
RSND_GEN_M_REG(DVC_VRCTR, 0xe18, 0x100),
|
|
RSND_GEN_M_REG(DVC_VRPDR, 0xe1c, 0x100),
|
|
RSND_GEN_M_REG(DVC_VRDBR, 0xe20, 0x100),
|
|
RSND_GEN_M_REG(DVC_VOL0R, 0xe28, 0x100),
|
|
RSND_GEN_M_REG(DVC_VOL1R, 0xe2c, 0x100),
|
|
RSND_GEN_M_REG(DVC_VOL2R, 0xe30, 0x100),
|
|
RSND_GEN_M_REG(DVC_VOL3R, 0xe34, 0x100),
|
|
RSND_GEN_M_REG(DVC_VOL4R, 0xe38, 0x100),
|
|
RSND_GEN_M_REG(DVC_VOL5R, 0xe3c, 0x100),
|
|
RSND_GEN_M_REG(DVC_VOL6R, 0xe40, 0x100),
|
|
RSND_GEN_M_REG(DVC_VOL7R, 0xe44, 0x100),
|
|
RSND_GEN_M_REG(DVC_DVUER, 0xe48, 0x100),
|
|
};
|
|
|
|
static const struct rsnd_regmap_field_conf conf_common_adg[] = {
|
|
RSND_GEN_S_REG(BRRA, 0x00),
|
|
RSND_GEN_S_REG(BRRB, 0x04),
|
|
RSND_GEN_S_REG(BRGCKR, 0x08),
|
|
RSND_GEN_S_REG(AUDIO_CLK_SEL0, 0x0c),
|
|
RSND_GEN_S_REG(AUDIO_CLK_SEL1, 0x10),
|
|
RSND_GEN_S_REG(AUDIO_CLK_SEL2, 0x14),
|
|
RSND_GEN_S_REG(DIV_EN, 0x30),
|
|
RSND_GEN_S_REG(SRCIN_TIMSEL0, 0x34),
|
|
RSND_GEN_S_REG(SRCIN_TIMSEL1, 0x38),
|
|
RSND_GEN_S_REG(SRCIN_TIMSEL2, 0x3c),
|
|
RSND_GEN_S_REG(SRCIN_TIMSEL3, 0x40),
|
|
RSND_GEN_S_REG(SRCIN_TIMSEL4, 0x44),
|
|
RSND_GEN_S_REG(SRCOUT_TIMSEL0, 0x48),
|
|
RSND_GEN_S_REG(SRCOUT_TIMSEL1, 0x4c),
|
|
RSND_GEN_S_REG(SRCOUT_TIMSEL2, 0x50),
|
|
RSND_GEN_S_REG(SRCOUT_TIMSEL3, 0x54),
|
|
RSND_GEN_S_REG(SRCOUT_TIMSEL4, 0x58),
|
|
RSND_GEN_S_REG(CMDOUT_TIMSEL, 0x5c),
|
|
};
|
|
|
|
static const struct rsnd_regmap_field_conf conf_common_ssi[] = {
|
|
RSND_GEN_M_REG(SSICR, 0x00, 0x40),
|
|
RSND_GEN_M_REG(SSISR, 0x04, 0x40),
|
|
RSND_GEN_M_REG(SSITDR, 0x08, 0x40),
|
|
RSND_GEN_M_REG(SSIRDR, 0x0c, 0x40),
|
|
RSND_GEN_M_REG(SSIWSR, 0x20, 0x40),
|
|
};
|
|
|
|
/*
|
|
* Gen4
|
|
*/
|
|
static int rsnd_gen4_probe(struct rsnd_priv *priv)
|
|
{
|
|
struct rsnd_regmap_field_conf conf_null[] = { };
|
|
|
|
/*
|
|
* ssiu: SSIU0
|
|
* ssi : SSI0
|
|
*/
|
|
int ret_ssiu = rsnd_gen_regmap_init(priv, 1, RSND_BASE_SSIU, "ssiu", conf_common_ssiu);
|
|
int ret_ssi = rsnd_gen_regmap_init(priv, 1, RSND_BASE_SSI, "ssi", conf_common_ssi);
|
|
int ret_adg = rsnd_gen_regmap_init(priv, 1, RSND_BASE_ADG, "adg", conf_common_adg);
|
|
int ret_sdmc = rsnd_gen_regmap_init(priv, 1, RSND_BASE_SDMC, "sdmc", conf_null);
|
|
|
|
return ret_adg | ret_ssiu | ret_ssi | ret_sdmc;
|
|
}
|
|
|
|
/*
|
|
* Gen2
|
|
*/
|
|
static int rsnd_gen2_probe(struct rsnd_priv *priv)
|
|
{
|
|
/*
|
|
* ssi : SSI0 - SSI9
|
|
* ssiu: SSIU0 - SSIU9
|
|
* scu : SRC0 - SRC9 etc
|
|
*/
|
|
int ret_ssi = rsnd_gen_regmap_init(priv, 10, RSND_BASE_SSI, "ssi", conf_common_ssi);
|
|
int ret_ssiu = rsnd_gen_regmap_init(priv, 10, RSND_BASE_SSIU, "ssiu", conf_common_ssiu);
|
|
int ret_scu = rsnd_gen_regmap_init(priv, 10, RSND_BASE_SCU, "scu", conf_common_scu);
|
|
int ret_adg = rsnd_gen_regmap_init(priv, 1, RSND_BASE_ADG, "adg", conf_common_adg);
|
|
|
|
return ret_ssi | ret_ssiu | ret_scu | ret_adg;
|
|
}
|
|
|
|
/*
|
|
* Gen1
|
|
*/
|
|
|
|
static int rsnd_gen1_probe(struct rsnd_priv *priv)
|
|
{
|
|
/*
|
|
* ssi : SSI0 - SSI8
|
|
*/
|
|
int ret_ssi = rsnd_gen_regmap_init(priv, 9, RSND_BASE_SSI, "ssi", conf_common_ssi);
|
|
int ret_adg = rsnd_gen_regmap_init(priv, 1, RSND_BASE_ADG, "adg", conf_common_adg);
|
|
|
|
return ret_adg | ret_ssi;
|
|
}
|
|
|
|
/*
|
|
* Gen
|
|
*/
|
|
int rsnd_gen_probe(struct rsnd_priv *priv)
|
|
{
|
|
struct device *dev = rsnd_priv_to_dev(priv);
|
|
struct rsnd_gen *gen;
|
|
int ret;
|
|
|
|
gen = devm_kzalloc(dev, sizeof(*gen), GFP_KERNEL);
|
|
if (!gen)
|
|
return -ENOMEM;
|
|
|
|
priv->gen = gen;
|
|
|
|
ret = -ENODEV;
|
|
if (rsnd_is_gen1(priv))
|
|
ret = rsnd_gen1_probe(priv);
|
|
else if (rsnd_is_gen2(priv) ||
|
|
rsnd_is_gen3(priv))
|
|
ret = rsnd_gen2_probe(priv);
|
|
else if (rsnd_is_gen4(priv))
|
|
ret = rsnd_gen4_probe(priv);
|
|
|
|
if (ret < 0)
|
|
dev_err(dev, "unknown generation R-Car sound device\n");
|
|
|
|
return ret;
|
|
}
|