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#ifdef CONFIG_DEBUG_FS
 145void __iomem *rsnd_gen_get_base_addr(struct rsnd_priv *priv, int reg_id)
 146{
 147        struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
 148
 149        return  gen->base[reg_id];
 150}
 151#endif
 152
 153#define rsnd_gen_regmap_init(priv, id_size, reg_id, name, conf)         \
 154        _rsnd_gen_regmap_init(priv, id_size, reg_id, name, conf, ARRAY_SIZE(conf))
 155static int _rsnd_gen_regmap_init(struct rsnd_priv *priv,
 156                                 int id_size,
 157                                 int reg_id,
 158                                 const char *name,
 159                                 const struct rsnd_regmap_field_conf *conf,
 160                                 int conf_size)
 161{
 162        struct platform_device *pdev = rsnd_priv_to_pdev(priv);
 163        struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
 164        struct device *dev = rsnd_priv_to_dev(priv);
 165        struct resource *res;
 166        struct regmap_config regc;
 167        struct regmap_field *regs;
 168        struct regmap *regmap;
 169        struct reg_field regf;
 170        void __iomem *base;
 171        int i;
 172
 173        memset(&regc, 0, sizeof(regc));
 174        regc.reg_bits = 32;
 175        regc.val_bits = 32;
 176        regc.reg_stride = 4;
 177        regc.name = name;
 178
 179        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name);
 180        if (!res)
 181                res = platform_get_resource(pdev, IORESOURCE_MEM, reg_id);
 182        if (!res)
 183                return -ENODEV;
 184
 185        base = devm_ioremap_resource(dev, res);
 186        if (IS_ERR(base))
 187                return PTR_ERR(base);
 188
 189        regmap = devm_regmap_init_mmio(dev, base, &regc);
 190        if (IS_ERR(regmap))
 191                return PTR_ERR(regmap);
 192
 193        /* RSND_BASE_MAX base */
 194        gen->base[reg_id] = base;
 195        gen->regmap[reg_id] = regmap;
 196        gen->res[reg_id] = res->start;
 197
 198        for (i = 0; i < conf_size; i++) {
 199
 200                regf.reg        = conf[i].reg_offset;
 201                regf.id_offset  = conf[i].id_offset;
 202                regf.lsb        = 0;
 203                regf.msb        = 31;
 204                regf.id_size    = id_size;
 205
 206                regs = devm_regmap_field_alloc(dev, regmap, regf);
 207                if (IS_ERR(regs))
 208                        return PTR_ERR(regs);
 209
 210                /* RSND_REG_MAX base */
 211                gen->regs[conf[i].idx] = regs;
 212                gen->reg_name[conf[i].idx] = conf[i].reg_name;
 213        }
 214
 215        return 0;
 216}
 217
 218/*
 219 *              Gen2
 220 */
 221static int rsnd_gen2_probe(struct rsnd_priv *priv)
 222{
 223        static const struct rsnd_regmap_field_conf conf_ssiu[] = {
 224                RSND_GEN_S_REG(SSI_MODE0,       0x800),
 225                RSND_GEN_S_REG(SSI_MODE1,       0x804),
 226                RSND_GEN_S_REG(SSI_MODE2,       0x808),
 227                RSND_GEN_S_REG(SSI_CONTROL,     0x810),
 228                RSND_GEN_S_REG(SSI_SYS_STATUS0, 0x840),
 229                RSND_GEN_S_REG(SSI_SYS_STATUS1, 0x844),
 230                RSND_GEN_S_REG(SSI_SYS_STATUS2, 0x848),
 231                RSND_GEN_S_REG(SSI_SYS_STATUS3, 0x84c),
 232                RSND_GEN_S_REG(SSI_SYS_STATUS4, 0x880),
 233                RSND_GEN_S_REG(SSI_SYS_STATUS5, 0x884),
 234                RSND_GEN_S_REG(SSI_SYS_STATUS6, 0x888),
 235                RSND_GEN_S_REG(SSI_SYS_STATUS7, 0x88c),
 236                RSND_GEN_S_REG(SSI_SYS_INT_ENABLE0, 0x850),
 237                RSND_GEN_S_REG(SSI_SYS_INT_ENABLE1, 0x854),
 238                RSND_GEN_S_REG(SSI_SYS_INT_ENABLE2, 0x858),
 239                RSND_GEN_S_REG(SSI_SYS_INT_ENABLE3, 0x85c),
 240                RSND_GEN_S_REG(SSI_SYS_INT_ENABLE4, 0x890),
 241                RSND_GEN_S_REG(SSI_SYS_INT_ENABLE5, 0x894),
 242                RSND_GEN_S_REG(SSI_SYS_INT_ENABLE6, 0x898),
 243                RSND_GEN_S_REG(SSI_SYS_INT_ENABLE7, 0x89c),
 244                RSND_GEN_S_REG(HDMI0_SEL,       0x9e0),
 245                RSND_GEN_S_REG(HDMI1_SEL,       0x9e4),
 246
 247                /* FIXME: it needs SSI_MODE2/3 in the future */
 248                RSND_GEN_M_REG(SSI_BUSIF0_MODE,         0x0,    0x80),
 249                RSND_GEN_M_REG(SSI_BUSIF0_ADINR,        0x4,    0x80),
 250                RSND_GEN_M_REG(SSI_BUSIF0_DALIGN,       0x8,    0x80),
 251                RSND_GEN_M_REG(SSI_BUSIF1_MODE,         0x20,   0x80),
 252                RSND_GEN_M_REG(SSI_BUSIF1_ADINR,        0x24,   0x80),
 253                RSND_GEN_M_REG(SSI_BUSIF1_DALIGN,       0x28,   0x80),
 254                RSND_GEN_M_REG(SSI_BUSIF2_MODE,         0x40,   0x80),
 255                RSND_GEN_M_REG(SSI_BUSIF2_ADINR,        0x44,   0x80),
 256                RSND_GEN_M_REG(SSI_BUSIF2_DALIGN,       0x48,   0x80),
 257                RSND_GEN_M_REG(SSI_BUSIF3_MODE,         0x60,   0x80),
 258                RSND_GEN_M_REG(SSI_BUSIF3_ADINR,        0x64,   0x80),
 259                RSND_GEN_M_REG(SSI_BUSIF3_DALIGN,       0x68,   0x80),
 260                RSND_GEN_M_REG(SSI_BUSIF4_MODE,         0x500,  0x80),
 261                RSND_GEN_M_REG(SSI_BUSIF4_ADINR,        0x504,  0x80),
 262                RSND_GEN_M_REG(SSI_BUSIF4_DALIGN,       0x508,  0x80),
 263                RSND_GEN_M_REG(SSI_BUSIF5_MODE,         0x520,  0x80),
 264                RSND_GEN_M_REG(SSI_BUSIF5_ADINR,        0x524,  0x80),
 265                RSND_GEN_M_REG(SSI_BUSIF5_DALIGN,       0x528,  0x80),
 266                RSND_GEN_M_REG(SSI_BUSIF6_MODE,         0x540,  0x80),
 267                RSND_GEN_M_REG(SSI_BUSIF6_ADINR,        0x544,  0x80),
 268                RSND_GEN_M_REG(SSI_BUSIF6_DALIGN,       0x548,  0x80),
 269                RSND_GEN_M_REG(SSI_BUSIF7_MODE,         0x560,  0x80),
 270                RSND_GEN_M_REG(SSI_BUSIF7_ADINR,        0x564,  0x80),
 271                RSND_GEN_M_REG(SSI_BUSIF7_DALIGN,       0x568,  0x80),
 272                RSND_GEN_M_REG(SSI_MODE,                0xc,    0x80),
 273                RSND_GEN_M_REG(SSI_CTRL,                0x10,   0x80),
 274                RSND_GEN_M_REG(SSI_INT_ENABLE,          0x18,   0x80),
 275                RSND_GEN_S_REG(SSI9_BUSIF0_MODE,        0x48c),
 276                RSND_GEN_S_REG(SSI9_BUSIF0_ADINR,       0x484),
 277                RSND_GEN_S_REG(SSI9_BUSIF0_DALIGN,      0x488),
 278                RSND_GEN_S_REG(SSI9_BUSIF1_MODE,        0x4a0),
 279                RSND_GEN_S_REG(SSI9_BUSIF1_ADINR,       0x4a4),
 280                RSND_GEN_S_REG(SSI9_BUSIF1_DALIGN,      0x4a8),
 281                RSND_GEN_S_REG(SSI9_BUSIF2_MODE,        0x4c0),
 282                RSND_GEN_S_REG(SSI9_BUSIF2_ADINR,       0x4c4),
 283                RSND_GEN_S_REG(SSI9_BUSIF2_DALIGN,      0x4c8),
 284                RSND_GEN_S_REG(SSI9_BUSIF3_MODE,        0x4e0),
 285                RSND_GEN_S_REG(SSI9_BUSIF3_ADINR,       0x4e4),
 286                RSND_GEN_S_REG(SSI9_BUSIF3_DALIGN,      0x4e8),
 287                RSND_GEN_S_REG(SSI9_BUSIF4_MODE,        0xd80),
 288                RSND_GEN_S_REG(SSI9_BUSIF4_ADINR,       0xd84),
 289                RSND_GEN_S_REG(SSI9_BUSIF4_DALIGN,      0xd88),
 290                RSND_GEN_S_REG(SSI9_BUSIF5_MODE,        0xda0),
 291                RSND_GEN_S_REG(SSI9_BUSIF5_ADINR,       0xda4),
 292                RSND_GEN_S_REG(SSI9_BUSIF5_DALIGN,      0xda8),
 293                RSND_GEN_S_REG(SSI9_BUSIF6_MODE,        0xdc0),
 294                RSND_GEN_S_REG(SSI9_BUSIF6_ADINR,       0xdc4),
 295                RSND_GEN_S_REG(SSI9_BUSIF6_DALIGN,      0xdc8),
 296                RSND_GEN_S_REG(SSI9_BUSIF7_MODE,        0xde0),
 297                RSND_GEN_S_REG(SSI9_BUSIF7_ADINR,       0xde4),
 298                RSND_GEN_S_REG(SSI9_BUSIF7_DALIGN,      0xde8),
 299        };
 300
 301        static const struct rsnd_regmap_field_conf conf_scu[] = {
 302                RSND_GEN_M_REG(SRC_I_BUSIF_MODE,0x0,    0x20),
 303                RSND_GEN_M_REG(SRC_O_BUSIF_MODE,0x4,    0x20),
 304                RSND_GEN_M_REG(SRC_BUSIF_DALIGN,0x8,    0x20),
 305                RSND_GEN_M_REG(SRC_ROUTE_MODE0, 0xc,    0x20),
 306                RSND_GEN_M_REG(SRC_CTRL,        0x10,   0x20),
 307                RSND_GEN_M_REG(SRC_INT_ENABLE0, 0x18,   0x20),
 308                RSND_GEN_M_REG(CMD_BUSIF_MODE,  0x184,  0x20),
 309                RSND_GEN_M_REG(CMD_BUSIF_DALIGN,0x188,  0x20),
 310                RSND_GEN_M_REG(CMD_ROUTE_SLCT,  0x18c,  0x20),
 311                RSND_GEN_M_REG(CMD_CTRL,        0x190,  0x20),
 312                RSND_GEN_S_REG(SCU_SYS_STATUS0, 0x1c8),
 313                RSND_GEN_S_REG(SCU_SYS_INT_EN0, 0x1cc),
 314                RSND_GEN_S_REG(SCU_SYS_STATUS1, 0x1d0),
 315                RSND_GEN_S_REG(SCU_SYS_INT_EN1, 0x1d4),
 316                RSND_GEN_M_REG(SRC_SWRSR,       0x200,  0x40),
 317                RSND_GEN_M_REG(SRC_SRCIR,       0x204,  0x40),
 318                RSND_GEN_M_REG(SRC_ADINR,       0x214,  0x40),
 319                RSND_GEN_M_REG(SRC_IFSCR,       0x21c,  0x40),
 320                RSND_GEN_M_REG(SRC_IFSVR,       0x220,  0x40),
 321                RSND_GEN_M_REG(SRC_SRCCR,       0x224,  0x40),
 322                RSND_GEN_M_REG(SRC_BSDSR,       0x22c,  0x40),
 323                RSND_GEN_M_REG(SRC_BSISR,       0x238,  0x40),
 324                RSND_GEN_M_REG(CTU_SWRSR,       0x500,  0x100),
 325                RSND_GEN_M_REG(CTU_CTUIR,       0x504,  0x100),
 326                RSND_GEN_M_REG(CTU_ADINR,       0x508,  0x100),
 327                RSND_GEN_M_REG(CTU_CPMDR,       0x510,  0x100),
 328                RSND_GEN_M_REG(CTU_SCMDR,       0x514,  0x100),
 329                RSND_GEN_M_REG(CTU_SV00R,       0x518,  0x100),
 330                RSND_GEN_M_REG(CTU_SV01R,       0x51c,  0x100),
 331                RSND_GEN_M_REG(CTU_SV02R,       0x520,  0x100),
 332                RSND_GEN_M_REG(CTU_SV03R,       0x524,  0x100),
 333                RSND_GEN_M_REG(CTU_SV04R,       0x528,  0x100),
 334                RSND_GEN_M_REG(CTU_SV05R,       0x52c,  0x100),
 335                RSND_GEN_M_REG(CTU_SV06R,       0x530,  0x100),
 336                RSND_GEN_M_REG(CTU_SV07R,       0x534,  0x100),
 337                RSND_GEN_M_REG(CTU_SV10R,       0x538,  0x100),
 338                RSND_GEN_M_REG(CTU_SV11R,       0x53c,  0x100),
 339                RSND_GEN_M_REG(CTU_SV12R,       0x540,  0x100),
 340                RSND_GEN_M_REG(CTU_SV13R,       0x544,  0x100),
 341                RSND_GEN_M_REG(CTU_SV14R,       0x548,  0x100),
 342                RSND_GEN_M_REG(CTU_SV15R,       0x54c,  0x100),
 343                RSND_GEN_M_REG(CTU_SV16R,       0x550,  0x100),
 344                RSND_GEN_M_REG(CTU_SV17R,       0x554,  0x100),
 345                RSND_GEN_M_REG(CTU_SV20R,       0x558,  0x100),
 346                RSND_GEN_M_REG(CTU_SV21R,       0x55c,  0x100),
 347                RSND_GEN_M_REG(CTU_SV22R,       0x560,  0x100),
 348                RSND_GEN_M_REG(CTU_SV23R,       0x564,  0x100),
 349                RSND_GEN_M_REG(CTU_SV24R,       0x568,  0x100),
 350                RSND_GEN_M_REG(CTU_SV25R,       0x56c,  0x100),
 351                RSND_GEN_M_REG(CTU_SV26R,       0x570,  0x100),
 352                RSND_GEN_M_REG(CTU_SV27R,       0x574,  0x100),
 353                RSND_GEN_M_REG(CTU_SV30R,       0x578,  0x100),
 354                RSND_GEN_M_REG(CTU_SV31R,       0x57c,  0x100),
 355                RSND_GEN_M_REG(CTU_SV32R,       0x580,  0x100),
 356                RSND_GEN_M_REG(CTU_SV33R,       0x584,  0x100),
 357                RSND_GEN_M_REG(CTU_SV34R,       0x588,  0x100),
 358                RSND_GEN_M_REG(CTU_SV35R,       0x58c,  0x100),
 359                RSND_GEN_M_REG(CTU_SV36R,       0x590,  0x100),
 360                RSND_GEN_M_REG(CTU_SV37R,       0x594,  0x100),
 361                RSND_GEN_M_REG(MIX_SWRSR,       0xd00,  0x40),
 362                RSND_GEN_M_REG(MIX_MIXIR,       0xd04,  0x40),
 363                RSND_GEN_M_REG(MIX_ADINR,       0xd08,  0x40),
 364                RSND_GEN_M_REG(MIX_MIXMR,       0xd10,  0x40),
 365                RSND_GEN_M_REG(MIX_MVPDR,       0xd14,  0x40),
 366                RSND_GEN_M_REG(MIX_MDBAR,       0xd18,  0x40),
 367                RSND_GEN_M_REG(MIX_MDBBR,       0xd1c,  0x40),
 368                RSND_GEN_M_REG(MIX_MDBCR,       0xd20,  0x40),
 369                RSND_GEN_M_REG(MIX_MDBDR,       0xd24,  0x40),
 370                RSND_GEN_M_REG(MIX_MDBER,       0xd28,  0x40),
 371                RSND_GEN_M_REG(DVC_SWRSR,       0xe00,  0x100),
 372                RSND_GEN_M_REG(DVC_DVUIR,       0xe04,  0x100),
 373                RSND_GEN_M_REG(DVC_ADINR,       0xe08,  0x100),
 374                RSND_GEN_M_REG(DVC_DVUCR,       0xe10,  0x100),
 375                RSND_GEN_M_REG(DVC_ZCMCR,       0xe14,  0x100),
 376                RSND_GEN_M_REG(DVC_VRCTR,       0xe18,  0x100),
 377                RSND_GEN_M_REG(DVC_VRPDR,       0xe1c,  0x100),
 378                RSND_GEN_M_REG(DVC_VRDBR,       0xe20,  0x100),
 379                RSND_GEN_M_REG(DVC_VOL0R,       0xe28,  0x100),
 380                RSND_GEN_M_REG(DVC_VOL1R,       0xe2c,  0x100),
 381                RSND_GEN_M_REG(DVC_VOL2R,       0xe30,  0x100),
 382                RSND_GEN_M_REG(DVC_VOL3R,       0xe34,  0x100),
 383                RSND_GEN_M_REG(DVC_VOL4R,       0xe38,  0x100),
 384                RSND_GEN_M_REG(DVC_VOL5R,       0xe3c,  0x100),
 385                RSND_GEN_M_REG(DVC_VOL6R,       0xe40,  0x100),
 386                RSND_GEN_M_REG(DVC_VOL7R,       0xe44,  0x100),
 387                RSND_GEN_M_REG(DVC_DVUER,       0xe48,  0x100),
 388        };
 389        static const struct rsnd_regmap_field_conf conf_adg[] = {
 390                RSND_GEN_S_REG(BRRA,            0x00),
 391                RSND_GEN_S_REG(BRRB,            0x04),
 392                RSND_GEN_S_REG(BRGCKR,          0x08),
 393                RSND_GEN_S_REG(AUDIO_CLK_SEL0,  0x0c),
 394                RSND_GEN_S_REG(AUDIO_CLK_SEL1,  0x10),
 395                RSND_GEN_S_REG(AUDIO_CLK_SEL2,  0x14),
 396                RSND_GEN_S_REG(DIV_EN,          0x30),
 397                RSND_GEN_S_REG(SRCIN_TIMSEL0,   0x34),
 398                RSND_GEN_S_REG(SRCIN_TIMSEL1,   0x38),
 399                RSND_GEN_S_REG(SRCIN_TIMSEL2,   0x3c),
 400                RSND_GEN_S_REG(SRCIN_TIMSEL3,   0x40),
 401                RSND_GEN_S_REG(SRCIN_TIMSEL4,   0x44),
 402                RSND_GEN_S_REG(SRCOUT_TIMSEL0,  0x48),
 403                RSND_GEN_S_REG(SRCOUT_TIMSEL1,  0x4c),
 404                RSND_GEN_S_REG(SRCOUT_TIMSEL2,  0x50),
 405                RSND_GEN_S_REG(SRCOUT_TIMSEL3,  0x54),
 406                RSND_GEN_S_REG(SRCOUT_TIMSEL4,  0x58),
 407                RSND_GEN_S_REG(CMDOUT_TIMSEL,   0x5c),
 408        };
 409        static const struct rsnd_regmap_field_conf conf_ssi[] = {
 410                RSND_GEN_M_REG(SSICR,           0x00,   0x40),
 411                RSND_GEN_M_REG(SSISR,           0x04,   0x40),
 412                RSND_GEN_M_REG(SSITDR,          0x08,   0x40),
 413                RSND_GEN_M_REG(SSIRDR,          0x0c,   0x40),
 414                RSND_GEN_M_REG(SSIWSR,          0x20,   0x40),
 415        };
 416        int ret_ssiu;
 417        int ret_scu;
 418        int ret_adg;
 419        int ret_ssi;
 420
 421        ret_ssiu = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_SSIU, "ssiu", conf_ssiu);
 422        ret_scu  = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_SCU,  "scu",  conf_scu);
 423        ret_adg  = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_ADG,  "adg",  conf_adg);
 424        ret_ssi  = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_SSI,  "ssi",  conf_ssi);
 425        if (ret_ssiu < 0 ||
 426            ret_scu  < 0 ||
 427            ret_adg  < 0 ||
 428            ret_ssi  < 0)
 429                return ret_ssiu | ret_scu | ret_adg | ret_ssi;
 430
 431        return 0;
 432}
 433
 434/*
 435 *              Gen1
 436 */
 437
 438static int rsnd_gen1_probe(struct rsnd_priv *priv)
 439{
 440        static const struct rsnd_regmap_field_conf conf_adg[] = {
 441                RSND_GEN_S_REG(BRRA,            0x00),
 442                RSND_GEN_S_REG(BRRB,            0x04),
 443                RSND_GEN_S_REG(BRGCKR,          0x08),
 444                RSND_GEN_S_REG(AUDIO_CLK_SEL0,  0x0c),
 445                RSND_GEN_S_REG(AUDIO_CLK_SEL1,  0x10),
 446        };
 447        static const struct rsnd_regmap_field_conf conf_ssi[] = {
 448                RSND_GEN_M_REG(SSICR,           0x00,   0x40),
 449                RSND_GEN_M_REG(SSISR,           0x04,   0x40),
 450                RSND_GEN_M_REG(SSITDR,          0x08,   0x40),
 451                RSND_GEN_M_REG(SSIRDR,          0x0c,   0x40),
 452                RSND_GEN_M_REG(SSIWSR,          0x20,   0x40),
 453        };
 454        int ret_adg;
 455        int ret_ssi;
 456
 457        ret_adg  = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_ADG, "adg", conf_adg);
 458        ret_ssi  = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_SSI, "ssi", conf_ssi);
 459        if (ret_adg  < 0 ||
 460            ret_ssi  < 0)
 461                return ret_adg | ret_ssi;
 462
 463        return 0;
 464}
 465
 466/*
 467 *              Gen
 468 */
 469int rsnd_gen_probe(struct rsnd_priv *priv)
 470{
 471        struct device *dev = rsnd_priv_to_dev(priv);
 472        struct rsnd_gen *gen;
 473        int ret;
 474
 475        gen = devm_kzalloc(dev, sizeof(*gen), GFP_KERNEL);
 476        if (!gen)
 477                return -ENOMEM;
 478
 479        priv->gen = gen;
 480
 481        ret = -ENODEV;
 482        if (rsnd_is_gen1(priv))
 483                ret = rsnd_gen1_probe(priv);
 484        else if (rsnd_is_gen2(priv) ||
 485                 rsnd_is_gen3(priv))
 486                ret = rsnd_gen2_probe(priv);
 487
 488        if (ret < 0)
 489                dev_err(dev, "unknown generation R-Car sound device\n");
 490
 491        return ret;
 492}
 493