linux/sound/soc/sh/rcar/gen.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2//
   3// Renesas R-Car Gen1 SRU/SSI support
   4//
   5// Copyright (C) 2013 Renesas Solutions Corp.
   6// Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
   7
   8/*
   9 * #define DEBUG
  10 *
  11 * you can also add below in
  12 * ${LINUX}/drivers/base/regmap/regmap.c
  13 * for regmap debug
  14 *
  15 * #define LOG_DEVICE "xxxx.rcar_sound"
  16 */
  17
  18#include "rsnd.h"
  19
  20struct rsnd_gen {
  21        struct rsnd_gen_ops *ops;
  22
  23        /* RSND_BASE_MAX base */
  24        void __iomem *base[RSND_BASE_MAX];
  25        phys_addr_t res[RSND_BASE_MAX];
  26        struct regmap *regmap[RSND_BASE_MAX];
  27
  28        /* RSND_REG_MAX base */
  29        struct regmap_field *regs[REG_MAX];
  30        const char *reg_name[REG_MAX];
  31};
  32
  33#define rsnd_priv_to_gen(p)     ((struct rsnd_gen *)(p)->gen)
  34#define rsnd_reg_name(gen, id)  ((gen)->reg_name[id])
  35
  36struct rsnd_regmap_field_conf {
  37        int idx;
  38        unsigned int reg_offset;
  39        unsigned int id_offset;
  40        const char *reg_name;
  41};
  42
  43#define RSND_REG_SET(id, offset, _id_offset, n) \
  44{                                               \
  45        .idx = id,                              \
  46        .reg_offset = offset,                   \
  47        .id_offset = _id_offset,                \
  48        .reg_name = n,                          \
  49}
  50/* single address mapping */
  51#define RSND_GEN_S_REG(id, offset)      \
  52        RSND_REG_SET(id, offset, 0, #id)
  53
  54/* multi address mapping */
  55#define RSND_GEN_M_REG(id, offset, _id_offset)  \
  56        RSND_REG_SET(id, offset, _id_offset, #id)
  57
  58/*
  59 *              basic function
  60 */
  61static int rsnd_is_accessible_reg(struct rsnd_priv *priv,
  62                                  struct rsnd_gen *gen, enum rsnd_reg reg)
  63{
  64        if (!gen->regs[reg]) {
  65                struct device *dev = rsnd_priv_to_dev(priv);
  66
  67                dev_err(dev, "unsupported register access %x\n", reg);
  68                return 0;
  69        }
  70
  71        return 1;
  72}
  73
  74static int rsnd_mod_id_cmd(struct rsnd_mod *mod)
  75{
  76        if (mod->ops->id_cmd)
  77                return mod->ops->id_cmd(mod);
  78
  79        return rsnd_mod_id(mod);
  80}
  81
  82u32 rsnd_mod_read(struct rsnd_mod *mod, enum rsnd_reg reg)
  83{
  84        struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
  85        struct device *dev = rsnd_priv_to_dev(priv);
  86        struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
  87        u32 val;
  88
  89        if (!rsnd_is_accessible_reg(priv, gen, reg))
  90                return 0;
  91
  92        regmap_fields_read(gen->regs[reg], rsnd_mod_id_cmd(mod), &val);
  93
  94        dev_dbg(dev, "r %s - %-18s (%4d) : %08x\n",
  95                rsnd_mod_name(mod),
  96                rsnd_reg_name(gen, reg), reg, val);
  97
  98        return val;
  99}
 100
 101void rsnd_mod_write(struct rsnd_mod *mod,
 102                    enum rsnd_reg reg, u32 data)
 103{
 104        struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
 105        struct device *dev = rsnd_priv_to_dev(priv);
 106        struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
 107
 108        if (!rsnd_is_accessible_reg(priv, gen, reg))
 109                return;
 110
 111        regmap_fields_force_write(gen->regs[reg], rsnd_mod_id_cmd(mod), data);
 112
 113        dev_dbg(dev, "w %s - %-18s (%4d) : %08x\n",
 114                rsnd_mod_name(mod),
 115                rsnd_reg_name(gen, reg), reg, data);
 116}
 117
 118void rsnd_mod_bset(struct rsnd_mod *mod,
 119                   enum rsnd_reg reg, u32 mask, u32 data)
 120{
 121        struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
 122        struct device *dev = rsnd_priv_to_dev(priv);
 123        struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
 124
 125        if (!rsnd_is_accessible_reg(priv, gen, reg))
 126                return;
 127
 128        regmap_fields_force_update_bits(gen->regs[reg],
 129                                        rsnd_mod_id_cmd(mod), mask, data);
 130
 131        dev_dbg(dev, "b %s - %-18s (%4d) : %08x/%08x\n",
 132                rsnd_mod_name(mod),
 133                rsnd_reg_name(gen, reg), reg, data, mask);
 134
 135}
 136
 137phys_addr_t rsnd_gen_get_phy_addr(struct rsnd_priv *priv, int reg_id)
 138{
 139        struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
 140
 141        return  gen->res[reg_id];
 142}
 143
 144#define rsnd_gen_regmap_init(priv, id_size, reg_id, name, conf)         \
 145        _rsnd_gen_regmap_init(priv, id_size, reg_id, name, conf, ARRAY_SIZE(conf))
 146static int _rsnd_gen_regmap_init(struct rsnd_priv *priv,
 147                                 int id_size,
 148                                 int reg_id,
 149                                 const char *name,
 150                                 const struct rsnd_regmap_field_conf *conf,
 151                                 int conf_size)
 152{
 153        struct platform_device *pdev = rsnd_priv_to_pdev(priv);
 154        struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
 155        struct device *dev = rsnd_priv_to_dev(priv);
 156        struct resource *res;
 157        struct regmap_config regc;
 158        struct regmap_field *regs;
 159        struct regmap *regmap;
 160        struct reg_field regf;
 161        void __iomem *base;
 162        int i;
 163
 164        memset(&regc, 0, sizeof(regc));
 165        regc.reg_bits = 32;
 166        regc.val_bits = 32;
 167        regc.reg_stride = 4;
 168        regc.name = name;
 169
 170        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name);
 171        if (!res)
 172                res = platform_get_resource(pdev, IORESOURCE_MEM, reg_id);
 173        if (!res)
 174                return -ENODEV;
 175
 176        base = devm_ioremap_resource(dev, res);
 177        if (IS_ERR(base))
 178                return PTR_ERR(base);
 179
 180        regmap = devm_regmap_init_mmio(dev, base, &regc);
 181        if (IS_ERR(regmap))
 182                return PTR_ERR(regmap);
 183
 184        /* RSND_BASE_MAX base */
 185        gen->base[reg_id] = base;
 186        gen->regmap[reg_id] = regmap;
 187        gen->res[reg_id] = res->start;
 188
 189        for (i = 0; i < conf_size; i++) {
 190
 191                regf.reg        = conf[i].reg_offset;
 192                regf.id_offset  = conf[i].id_offset;
 193                regf.lsb        = 0;
 194                regf.msb        = 31;
 195                regf.id_size    = id_size;
 196
 197                regs = devm_regmap_field_alloc(dev, regmap, regf);
 198                if (IS_ERR(regs))
 199                        return PTR_ERR(regs);
 200
 201                /* RSND_REG_MAX base */
 202                gen->regs[conf[i].idx] = regs;
 203                gen->reg_name[conf[i].idx] = conf[i].reg_name;
 204        }
 205
 206        return 0;
 207}
 208
 209/*
 210 *              Gen2
 211 */
 212static int rsnd_gen2_probe(struct rsnd_priv *priv)
 213{
 214        static const struct rsnd_regmap_field_conf conf_ssiu[] = {
 215                RSND_GEN_S_REG(SSI_MODE0,       0x800),
 216                RSND_GEN_S_REG(SSI_MODE1,       0x804),
 217                RSND_GEN_S_REG(SSI_MODE2,       0x808),
 218                RSND_GEN_S_REG(SSI_CONTROL,     0x810),
 219                RSND_GEN_S_REG(SSI_SYS_STATUS0, 0x840),
 220                RSND_GEN_S_REG(SSI_SYS_STATUS1, 0x844),
 221                RSND_GEN_S_REG(SSI_SYS_STATUS2, 0x848),
 222                RSND_GEN_S_REG(SSI_SYS_STATUS3, 0x84c),
 223                RSND_GEN_S_REG(SSI_SYS_STATUS4, 0x880),
 224                RSND_GEN_S_REG(SSI_SYS_STATUS5, 0x884),
 225                RSND_GEN_S_REG(SSI_SYS_STATUS6, 0x888),
 226                RSND_GEN_S_REG(SSI_SYS_STATUS7, 0x88c),
 227                RSND_GEN_S_REG(HDMI0_SEL,       0x9e0),
 228                RSND_GEN_S_REG(HDMI1_SEL,       0x9e4),
 229
 230                /* FIXME: it needs SSI_MODE2/3 in the future */
 231                RSND_GEN_M_REG(SSI_BUSIF0_MODE,         0x0,    0x80),
 232                RSND_GEN_M_REG(SSI_BUSIF0_ADINR,        0x4,    0x80),
 233                RSND_GEN_M_REG(SSI_BUSIF0_DALIGN,       0x8,    0x80),
 234                RSND_GEN_M_REG(SSI_BUSIF1_MODE,         0x20,   0x80),
 235                RSND_GEN_M_REG(SSI_BUSIF1_ADINR,        0x24,   0x80),
 236                RSND_GEN_M_REG(SSI_BUSIF1_DALIGN,       0x28,   0x80),
 237                RSND_GEN_M_REG(SSI_BUSIF2_MODE,         0x40,   0x80),
 238                RSND_GEN_M_REG(SSI_BUSIF2_ADINR,        0x44,   0x80),
 239                RSND_GEN_M_REG(SSI_BUSIF2_DALIGN,       0x48,   0x80),
 240                RSND_GEN_M_REG(SSI_BUSIF3_MODE,         0x60,   0x80),
 241                RSND_GEN_M_REG(SSI_BUSIF3_ADINR,        0x64,   0x80),
 242                RSND_GEN_M_REG(SSI_BUSIF3_DALIGN,       0x68,   0x80),
 243                RSND_GEN_M_REG(SSI_BUSIF4_MODE,         0x500,  0x80),
 244                RSND_GEN_M_REG(SSI_BUSIF4_ADINR,        0x504,  0x80),
 245                RSND_GEN_M_REG(SSI_BUSIF4_DALIGN,       0x508,  0x80),
 246                RSND_GEN_M_REG(SSI_BUSIF5_MODE,         0x520,  0x80),
 247                RSND_GEN_M_REG(SSI_BUSIF5_ADINR,        0x524,  0x80),
 248                RSND_GEN_M_REG(SSI_BUSIF5_DALIGN,       0x528,  0x80),
 249                RSND_GEN_M_REG(SSI_BUSIF6_MODE,         0x540,  0x80),
 250                RSND_GEN_M_REG(SSI_BUSIF6_ADINR,        0x544,  0x80),
 251                RSND_GEN_M_REG(SSI_BUSIF6_DALIGN,       0x548,  0x80),
 252                RSND_GEN_M_REG(SSI_BUSIF7_MODE,         0x560,  0x80),
 253                RSND_GEN_M_REG(SSI_BUSIF7_ADINR,        0x564,  0x80),
 254                RSND_GEN_M_REG(SSI_BUSIF7_DALIGN,       0x568,  0x80),
 255                RSND_GEN_M_REG(SSI_MODE,                0xc,    0x80),
 256                RSND_GEN_M_REG(SSI_CTRL,                0x10,   0x80),
 257                RSND_GEN_M_REG(SSI_INT_ENABLE,          0x18,   0x80),
 258                RSND_GEN_S_REG(SSI9_BUSIF0_MODE,        0x48c),
 259                RSND_GEN_S_REG(SSI9_BUSIF0_ADINR,       0x484),
 260                RSND_GEN_S_REG(SSI9_BUSIF0_DALIGN,      0x488),
 261                RSND_GEN_S_REG(SSI9_BUSIF1_MODE,        0x4a0),
 262                RSND_GEN_S_REG(SSI9_BUSIF1_ADINR,       0x4a4),
 263                RSND_GEN_S_REG(SSI9_BUSIF1_DALIGN,      0x4a8),
 264                RSND_GEN_S_REG(SSI9_BUSIF2_MODE,        0x4c0),
 265                RSND_GEN_S_REG(SSI9_BUSIF2_ADINR,       0x4c4),
 266                RSND_GEN_S_REG(SSI9_BUSIF2_DALIGN,      0x4c8),
 267                RSND_GEN_S_REG(SSI9_BUSIF3_MODE,        0x4e0),
 268                RSND_GEN_S_REG(SSI9_BUSIF3_ADINR,       0x4e4),
 269                RSND_GEN_S_REG(SSI9_BUSIF3_DALIGN,      0x4e8),
 270                RSND_GEN_S_REG(SSI9_BUSIF4_MODE,        0xd80),
 271                RSND_GEN_S_REG(SSI9_BUSIF4_ADINR,       0xd84),
 272                RSND_GEN_S_REG(SSI9_BUSIF4_DALIGN,      0xd88),
 273                RSND_GEN_S_REG(SSI9_BUSIF5_MODE,        0xda0),
 274                RSND_GEN_S_REG(SSI9_BUSIF5_ADINR,       0xda4),
 275                RSND_GEN_S_REG(SSI9_BUSIF5_DALIGN,      0xda8),
 276                RSND_GEN_S_REG(SSI9_BUSIF6_MODE,        0xdc0),
 277                RSND_GEN_S_REG(SSI9_BUSIF6_ADINR,       0xdc4),
 278                RSND_GEN_S_REG(SSI9_BUSIF6_DALIGN,      0xdc8),
 279                RSND_GEN_S_REG(SSI9_BUSIF7_MODE,        0xde0),
 280                RSND_GEN_S_REG(SSI9_BUSIF7_ADINR,       0xde4),
 281                RSND_GEN_S_REG(SSI9_BUSIF7_DALIGN,      0xde8),
 282        };
 283
 284        static const struct rsnd_regmap_field_conf conf_scu[] = {
 285                RSND_GEN_M_REG(SRC_I_BUSIF_MODE,0x0,    0x20),
 286                RSND_GEN_M_REG(SRC_O_BUSIF_MODE,0x4,    0x20),
 287                RSND_GEN_M_REG(SRC_BUSIF_DALIGN,0x8,    0x20),
 288                RSND_GEN_M_REG(SRC_ROUTE_MODE0, 0xc,    0x20),
 289                RSND_GEN_M_REG(SRC_CTRL,        0x10,   0x20),
 290                RSND_GEN_M_REG(SRC_INT_ENABLE0, 0x18,   0x20),
 291                RSND_GEN_M_REG(CMD_BUSIF_MODE,  0x184,  0x20),
 292                RSND_GEN_M_REG(CMD_BUSIF_DALIGN,0x188,  0x20),
 293                RSND_GEN_M_REG(CMD_ROUTE_SLCT,  0x18c,  0x20),
 294                RSND_GEN_M_REG(CMD_CTRL,        0x190,  0x20),
 295                RSND_GEN_S_REG(SCU_SYS_STATUS0, 0x1c8),
 296                RSND_GEN_S_REG(SCU_SYS_INT_EN0, 0x1cc),
 297                RSND_GEN_S_REG(SCU_SYS_STATUS1, 0x1d0),
 298                RSND_GEN_S_REG(SCU_SYS_INT_EN1, 0x1d4),
 299                RSND_GEN_M_REG(SRC_SWRSR,       0x200,  0x40),
 300                RSND_GEN_M_REG(SRC_SRCIR,       0x204,  0x40),
 301                RSND_GEN_M_REG(SRC_ADINR,       0x214,  0x40),
 302                RSND_GEN_M_REG(SRC_IFSCR,       0x21c,  0x40),
 303                RSND_GEN_M_REG(SRC_IFSVR,       0x220,  0x40),
 304                RSND_GEN_M_REG(SRC_SRCCR,       0x224,  0x40),
 305                RSND_GEN_M_REG(SRC_BSDSR,       0x22c,  0x40),
 306                RSND_GEN_M_REG(SRC_BSISR,       0x238,  0x40),
 307                RSND_GEN_M_REG(CTU_SWRSR,       0x500,  0x100),
 308                RSND_GEN_M_REG(CTU_CTUIR,       0x504,  0x100),
 309                RSND_GEN_M_REG(CTU_ADINR,       0x508,  0x100),
 310                RSND_GEN_M_REG(CTU_CPMDR,       0x510,  0x100),
 311                RSND_GEN_M_REG(CTU_SCMDR,       0x514,  0x100),
 312                RSND_GEN_M_REG(CTU_SV00R,       0x518,  0x100),
 313                RSND_GEN_M_REG(CTU_SV01R,       0x51c,  0x100),
 314                RSND_GEN_M_REG(CTU_SV02R,       0x520,  0x100),
 315                RSND_GEN_M_REG(CTU_SV03R,       0x524,  0x100),
 316                RSND_GEN_M_REG(CTU_SV04R,       0x528,  0x100),
 317                RSND_GEN_M_REG(CTU_SV05R,       0x52c,  0x100),
 318                RSND_GEN_M_REG(CTU_SV06R,       0x530,  0x100),
 319                RSND_GEN_M_REG(CTU_SV07R,       0x534,  0x100),
 320                RSND_GEN_M_REG(CTU_SV10R,       0x538,  0x100),
 321                RSND_GEN_M_REG(CTU_SV11R,       0x53c,  0x100),
 322                RSND_GEN_M_REG(CTU_SV12R,       0x540,  0x100),
 323                RSND_GEN_M_REG(CTU_SV13R,       0x544,  0x100),
 324                RSND_GEN_M_REG(CTU_SV14R,       0x548,  0x100),
 325                RSND_GEN_M_REG(CTU_SV15R,       0x54c,  0x100),
 326                RSND_GEN_M_REG(CTU_SV16R,       0x550,  0x100),
 327                RSND_GEN_M_REG(CTU_SV17R,       0x554,  0x100),
 328                RSND_GEN_M_REG(CTU_SV20R,       0x558,  0x100),
 329                RSND_GEN_M_REG(CTU_SV21R,       0x55c,  0x100),
 330                RSND_GEN_M_REG(CTU_SV22R,       0x560,  0x100),
 331                RSND_GEN_M_REG(CTU_SV23R,       0x564,  0x100),
 332                RSND_GEN_M_REG(CTU_SV24R,       0x568,  0x100),
 333                RSND_GEN_M_REG(CTU_SV25R,       0x56c,  0x100),
 334                RSND_GEN_M_REG(CTU_SV26R,       0x570,  0x100),
 335                RSND_GEN_M_REG(CTU_SV27R,       0x574,  0x100),
 336                RSND_GEN_M_REG(CTU_SV30R,       0x578,  0x100),
 337                RSND_GEN_M_REG(CTU_SV31R,       0x57c,  0x100),
 338                RSND_GEN_M_REG(CTU_SV32R,       0x580,  0x100),
 339                RSND_GEN_M_REG(CTU_SV33R,       0x584,  0x100),
 340                RSND_GEN_M_REG(CTU_SV34R,       0x588,  0x100),
 341                RSND_GEN_M_REG(CTU_SV35R,       0x58c,  0x100),
 342                RSND_GEN_M_REG(CTU_SV36R,       0x590,  0x100),
 343                RSND_GEN_M_REG(CTU_SV37R,       0x594,  0x100),
 344                RSND_GEN_M_REG(MIX_SWRSR,       0xd00,  0x40),
 345                RSND_GEN_M_REG(MIX_MIXIR,       0xd04,  0x40),
 346                RSND_GEN_M_REG(MIX_ADINR,       0xd08,  0x40),
 347                RSND_GEN_M_REG(MIX_MIXMR,       0xd10,  0x40),
 348                RSND_GEN_M_REG(MIX_MVPDR,       0xd14,  0x40),
 349                RSND_GEN_M_REG(MIX_MDBAR,       0xd18,  0x40),
 350                RSND_GEN_M_REG(MIX_MDBBR,       0xd1c,  0x40),
 351                RSND_GEN_M_REG(MIX_MDBCR,       0xd20,  0x40),
 352                RSND_GEN_M_REG(MIX_MDBDR,       0xd24,  0x40),
 353                RSND_GEN_M_REG(MIX_MDBER,       0xd28,  0x40),
 354                RSND_GEN_M_REG(DVC_SWRSR,       0xe00,  0x100),
 355                RSND_GEN_M_REG(DVC_DVUIR,       0xe04,  0x100),
 356                RSND_GEN_M_REG(DVC_ADINR,       0xe08,  0x100),
 357                RSND_GEN_M_REG(DVC_DVUCR,       0xe10,  0x100),
 358                RSND_GEN_M_REG(DVC_ZCMCR,       0xe14,  0x100),
 359                RSND_GEN_M_REG(DVC_VRCTR,       0xe18,  0x100),
 360                RSND_GEN_M_REG(DVC_VRPDR,       0xe1c,  0x100),
 361                RSND_GEN_M_REG(DVC_VRDBR,       0xe20,  0x100),
 362                RSND_GEN_M_REG(DVC_VOL0R,       0xe28,  0x100),
 363                RSND_GEN_M_REG(DVC_VOL1R,       0xe2c,  0x100),
 364                RSND_GEN_M_REG(DVC_VOL2R,       0xe30,  0x100),
 365                RSND_GEN_M_REG(DVC_VOL3R,       0xe34,  0x100),
 366                RSND_GEN_M_REG(DVC_VOL4R,       0xe38,  0x100),
 367                RSND_GEN_M_REG(DVC_VOL5R,       0xe3c,  0x100),
 368                RSND_GEN_M_REG(DVC_VOL6R,       0xe40,  0x100),
 369                RSND_GEN_M_REG(DVC_VOL7R,       0xe44,  0x100),
 370                RSND_GEN_M_REG(DVC_DVUER,       0xe48,  0x100),
 371        };
 372        static const struct rsnd_regmap_field_conf conf_adg[] = {
 373                RSND_GEN_S_REG(BRRA,            0x00),
 374                RSND_GEN_S_REG(BRRB,            0x04),
 375                RSND_GEN_S_REG(BRGCKR,          0x08),
 376                RSND_GEN_S_REG(AUDIO_CLK_SEL0,  0x0c),
 377                RSND_GEN_S_REG(AUDIO_CLK_SEL1,  0x10),
 378                RSND_GEN_S_REG(AUDIO_CLK_SEL2,  0x14),
 379                RSND_GEN_S_REG(DIV_EN,          0x30),
 380                RSND_GEN_S_REG(SRCIN_TIMSEL0,   0x34),
 381                RSND_GEN_S_REG(SRCIN_TIMSEL1,   0x38),
 382                RSND_GEN_S_REG(SRCIN_TIMSEL2,   0x3c),
 383                RSND_GEN_S_REG(SRCIN_TIMSEL3,   0x40),
 384                RSND_GEN_S_REG(SRCIN_TIMSEL4,   0x44),
 385                RSND_GEN_S_REG(SRCOUT_TIMSEL0,  0x48),
 386                RSND_GEN_S_REG(SRCOUT_TIMSEL1,  0x4c),
 387                RSND_GEN_S_REG(SRCOUT_TIMSEL2,  0x50),
 388                RSND_GEN_S_REG(SRCOUT_TIMSEL3,  0x54),
 389                RSND_GEN_S_REG(SRCOUT_TIMSEL4,  0x58),
 390                RSND_GEN_S_REG(CMDOUT_TIMSEL,   0x5c),
 391        };
 392        static const struct rsnd_regmap_field_conf conf_ssi[] = {
 393                RSND_GEN_M_REG(SSICR,           0x00,   0x40),
 394                RSND_GEN_M_REG(SSISR,           0x04,   0x40),
 395                RSND_GEN_M_REG(SSITDR,          0x08,   0x40),
 396                RSND_GEN_M_REG(SSIRDR,          0x0c,   0x40),
 397                RSND_GEN_M_REG(SSIWSR,          0x20,   0x40),
 398        };
 399        int ret_ssiu;
 400        int ret_scu;
 401        int ret_adg;
 402        int ret_ssi;
 403
 404        ret_ssiu = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_SSIU, "ssiu", conf_ssiu);
 405        ret_scu  = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_SCU,  "scu",  conf_scu);
 406        ret_adg  = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_ADG,  "adg",  conf_adg);
 407        ret_ssi  = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_SSI,  "ssi",  conf_ssi);
 408        if (ret_ssiu < 0 ||
 409            ret_scu  < 0 ||
 410            ret_adg  < 0 ||
 411            ret_ssi  < 0)
 412                return ret_ssiu | ret_scu | ret_adg | ret_ssi;
 413
 414        return 0;
 415}
 416
 417/*
 418 *              Gen1
 419 */
 420
 421static int rsnd_gen1_probe(struct rsnd_priv *priv)
 422{
 423        static const struct rsnd_regmap_field_conf conf_adg[] = {
 424                RSND_GEN_S_REG(BRRA,            0x00),
 425                RSND_GEN_S_REG(BRRB,            0x04),
 426                RSND_GEN_S_REG(BRGCKR,          0x08),
 427                RSND_GEN_S_REG(AUDIO_CLK_SEL0,  0x0c),
 428                RSND_GEN_S_REG(AUDIO_CLK_SEL1,  0x10),
 429        };
 430        static const struct rsnd_regmap_field_conf conf_ssi[] = {
 431                RSND_GEN_M_REG(SSICR,           0x00,   0x40),
 432                RSND_GEN_M_REG(SSISR,           0x04,   0x40),
 433                RSND_GEN_M_REG(SSITDR,          0x08,   0x40),
 434                RSND_GEN_M_REG(SSIRDR,          0x0c,   0x40),
 435                RSND_GEN_M_REG(SSIWSR,          0x20,   0x40),
 436        };
 437        int ret_adg;
 438        int ret_ssi;
 439
 440        ret_adg  = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_ADG, "adg", conf_adg);
 441        ret_ssi  = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_SSI, "ssi", conf_ssi);
 442        if (ret_adg  < 0 ||
 443            ret_ssi  < 0)
 444                return ret_adg | ret_ssi;
 445
 446        return 0;
 447}
 448
 449/*
 450 *              Gen
 451 */
 452int rsnd_gen_probe(struct rsnd_priv *priv)
 453{
 454        struct device *dev = rsnd_priv_to_dev(priv);
 455        struct rsnd_gen *gen;
 456        int ret;
 457
 458        gen = devm_kzalloc(dev, sizeof(*gen), GFP_KERNEL);
 459        if (!gen)
 460                return -ENOMEM;
 461
 462        priv->gen = gen;
 463
 464        ret = -ENODEV;
 465        if (rsnd_is_gen1(priv))
 466                ret = rsnd_gen1_probe(priv);
 467        else if (rsnd_is_gen2(priv) ||
 468                 rsnd_is_gen3(priv))
 469                ret = rsnd_gen2_probe(priv);
 470
 471        if (ret < 0)
 472                dev_err(dev, "unknown generation R-Car sound device\n");
 473
 474        return ret;
 475}
 476