13337744aSKuninori Morimoto /* 23337744aSKuninori Morimoto * Renesas R-Car Gen1 SRU/SSI support 33337744aSKuninori Morimoto * 43337744aSKuninori Morimoto * Copyright (C) 2013 Renesas Solutions Corp. 53337744aSKuninori Morimoto * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> 63337744aSKuninori Morimoto * 73337744aSKuninori Morimoto * This program is free software; you can redistribute it and/or modify 83337744aSKuninori Morimoto * it under the terms of the GNU General Public License version 2 as 93337744aSKuninori Morimoto * published by the Free Software Foundation. 103337744aSKuninori Morimoto */ 11ace0eb1eSKuninori Morimoto 12ace0eb1eSKuninori Morimoto /* 13ace0eb1eSKuninori Morimoto * #define DEBUG 14ace0eb1eSKuninori Morimoto * 15ace0eb1eSKuninori Morimoto * you can also add below in 16ace0eb1eSKuninori Morimoto * ${LINUX}/drivers/base/regmap/regmap.c 17ace0eb1eSKuninori Morimoto * for regmap debug 18ace0eb1eSKuninori Morimoto * 19ace0eb1eSKuninori Morimoto * #define LOG_DEVICE "xxxx.rcar_sound" 20ace0eb1eSKuninori Morimoto */ 21ace0eb1eSKuninori Morimoto 223337744aSKuninori Morimoto #include "rsnd.h" 233337744aSKuninori Morimoto 243337744aSKuninori Morimoto struct rsnd_gen { 253337744aSKuninori Morimoto void __iomem *base[RSND_BASE_MAX]; 263337744aSKuninori Morimoto 273337744aSKuninori Morimoto struct rsnd_gen_ops *ops; 2855e5b6fdSKuninori Morimoto 29b8c63786SKuninori Morimoto struct regmap *regmap[RSND_BASE_MAX]; 3055e5b6fdSKuninori Morimoto struct regmap_field *regs[RSND_REG_MAX]; 31c5212b45SKuninori Morimoto phys_addr_t res[RSND_REG_MAX]; 323337744aSKuninori Morimoto }; 333337744aSKuninori Morimoto 343337744aSKuninori Morimoto #define rsnd_priv_to_gen(p) ((struct rsnd_gen *)(p)->gen) 353337744aSKuninori Morimoto 36b8c63786SKuninori Morimoto struct rsnd_regmap_field_conf { 37b8c63786SKuninori Morimoto int idx; 38b8c63786SKuninori Morimoto unsigned int reg_offset; 39b8c63786SKuninori Morimoto unsigned int id_offset; 40b8c63786SKuninori Morimoto }; 41b8c63786SKuninori Morimoto 42b8c63786SKuninori Morimoto #define RSND_REG_SET(id, offset, _id_offset) \ 43b8c63786SKuninori Morimoto { \ 44b8c63786SKuninori Morimoto .idx = id, \ 45b8c63786SKuninori Morimoto .reg_offset = offset, \ 4655e5b6fdSKuninori Morimoto .id_offset = _id_offset, \ 4755e5b6fdSKuninori Morimoto } 48b8c63786SKuninori Morimoto /* single address mapping */ 49b8c63786SKuninori Morimoto #define RSND_GEN_S_REG(id, offset) \ 50b8c63786SKuninori Morimoto RSND_REG_SET(RSND_REG_##id, offset, 0) 51b8c63786SKuninori Morimoto 52b8c63786SKuninori Morimoto /* multi address mapping */ 53b8c63786SKuninori Morimoto #define RSND_GEN_M_REG(id, offset, _id_offset) \ 54b8c63786SKuninori Morimoto RSND_REG_SET(RSND_REG_##id, offset, _id_offset) 5555e5b6fdSKuninori Morimoto 5655e5b6fdSKuninori Morimoto /* 5755e5b6fdSKuninori Morimoto * basic function 5855e5b6fdSKuninori Morimoto */ 5942ee5d22SKuninori Morimoto static int rsnd_is_accessible_reg(struct rsnd_priv *priv, 6042ee5d22SKuninori Morimoto struct rsnd_gen *gen, enum rsnd_reg reg) 6142ee5d22SKuninori Morimoto { 6242ee5d22SKuninori Morimoto if (!gen->regs[reg]) { 6342ee5d22SKuninori Morimoto struct device *dev = rsnd_priv_to_dev(priv); 6442ee5d22SKuninori Morimoto 6542ee5d22SKuninori Morimoto dev_err(dev, "unsupported register access %x\n", reg); 6642ee5d22SKuninori Morimoto return 0; 6742ee5d22SKuninori Morimoto } 6842ee5d22SKuninori Morimoto 6942ee5d22SKuninori Morimoto return 1; 7042ee5d22SKuninori Morimoto } 7142ee5d22SKuninori Morimoto 7255e5b6fdSKuninori Morimoto u32 rsnd_read(struct rsnd_priv *priv, 7355e5b6fdSKuninori Morimoto struct rsnd_mod *mod, enum rsnd_reg reg) 7455e5b6fdSKuninori Morimoto { 75b8c63786SKuninori Morimoto struct device *dev = rsnd_priv_to_dev(priv); 7655e5b6fdSKuninori Morimoto struct rsnd_gen *gen = rsnd_priv_to_gen(priv); 7755e5b6fdSKuninori Morimoto u32 val; 7855e5b6fdSKuninori Morimoto 7942ee5d22SKuninori Morimoto if (!rsnd_is_accessible_reg(priv, gen, reg)) 8042ee5d22SKuninori Morimoto return 0; 8142ee5d22SKuninori Morimoto 82c9b9638fSKuninori Morimoto regmap_fields_read(gen->regs[reg], rsnd_mod_id(mod), &val); 83c9b9638fSKuninori Morimoto 8430cc4fafSKuninori Morimoto dev_dbg(dev, "r %s[%d] - %4d : %08x\n", 85ace0eb1eSKuninori Morimoto rsnd_mod_name(mod), rsnd_mod_id(mod), reg, val); 8655e5b6fdSKuninori Morimoto 8755e5b6fdSKuninori Morimoto return val; 8855e5b6fdSKuninori Morimoto } 8955e5b6fdSKuninori Morimoto 9055e5b6fdSKuninori Morimoto void rsnd_write(struct rsnd_priv *priv, 9155e5b6fdSKuninori Morimoto struct rsnd_mod *mod, 9255e5b6fdSKuninori Morimoto enum rsnd_reg reg, u32 data) 9355e5b6fdSKuninori Morimoto { 94b8c63786SKuninori Morimoto struct device *dev = rsnd_priv_to_dev(priv); 9555e5b6fdSKuninori Morimoto struct rsnd_gen *gen = rsnd_priv_to_gen(priv); 9655e5b6fdSKuninori Morimoto 9742ee5d22SKuninori Morimoto if (!rsnd_is_accessible_reg(priv, gen, reg)) 9842ee5d22SKuninori Morimoto return; 9942ee5d22SKuninori Morimoto 10030cc4fafSKuninori Morimoto dev_dbg(dev, "w %s[%d] - %4d : %08x\n", 101ace0eb1eSKuninori Morimoto rsnd_mod_name(mod), rsnd_mod_id(mod), reg, data); 102b8c63786SKuninori Morimoto 103ace0eb1eSKuninori Morimoto regmap_fields_write(gen->regs[reg], rsnd_mod_id(mod), data); 10455e5b6fdSKuninori Morimoto } 10555e5b6fdSKuninori Morimoto 1067b47ab47SKuninori Morimoto void rsnd_force_write(struct rsnd_priv *priv, 1077b47ab47SKuninori Morimoto struct rsnd_mod *mod, 1087b47ab47SKuninori Morimoto enum rsnd_reg reg, u32 data) 1097b47ab47SKuninori Morimoto { 1107b47ab47SKuninori Morimoto struct device *dev = rsnd_priv_to_dev(priv); 1117b47ab47SKuninori Morimoto struct rsnd_gen *gen = rsnd_priv_to_gen(priv); 1127b47ab47SKuninori Morimoto 1137b47ab47SKuninori Morimoto if (!rsnd_is_accessible_reg(priv, gen, reg)) 1147b47ab47SKuninori Morimoto return; 1157b47ab47SKuninori Morimoto 1167b47ab47SKuninori Morimoto dev_dbg(dev, "w %s[%d] - %4d : %08x\n", 1177b47ab47SKuninori Morimoto rsnd_mod_name(mod), rsnd_mod_id(mod), reg, data); 1187b47ab47SKuninori Morimoto 1197b47ab47SKuninori Morimoto regmap_fields_force_write(gen->regs[reg], rsnd_mod_id(mod), data); 1207b47ab47SKuninori Morimoto } 1217b47ab47SKuninori Morimoto 12255e5b6fdSKuninori Morimoto void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, 12355e5b6fdSKuninori Morimoto enum rsnd_reg reg, u32 mask, u32 data) 12455e5b6fdSKuninori Morimoto { 1254f8f86aaSKuninori Morimoto struct device *dev = rsnd_priv_to_dev(priv); 12655e5b6fdSKuninori Morimoto struct rsnd_gen *gen = rsnd_priv_to_gen(priv); 12755e5b6fdSKuninori Morimoto 12842ee5d22SKuninori Morimoto if (!rsnd_is_accessible_reg(priv, gen, reg)) 12942ee5d22SKuninori Morimoto return; 13042ee5d22SKuninori Morimoto 13130cc4fafSKuninori Morimoto dev_dbg(dev, "b %s[%d] - %4d : %08x/%08x\n", 132ace0eb1eSKuninori Morimoto rsnd_mod_name(mod), rsnd_mod_id(mod), reg, data, mask); 133ace0eb1eSKuninori Morimoto 13455e5b6fdSKuninori Morimoto regmap_fields_update_bits(gen->regs[reg], rsnd_mod_id(mod), 13555e5b6fdSKuninori Morimoto mask, data); 13655e5b6fdSKuninori Morimoto } 13755e5b6fdSKuninori Morimoto 138c5212b45SKuninori Morimoto phys_addr_t rsnd_gen_get_phy_addr(struct rsnd_priv *priv, int reg_id) 139c5212b45SKuninori Morimoto { 140c5212b45SKuninori Morimoto struct rsnd_gen *gen = rsnd_priv_to_gen(priv); 141c5212b45SKuninori Morimoto 142c5212b45SKuninori Morimoto return gen->res[reg_id]; 143c5212b45SKuninori Morimoto } 144c5212b45SKuninori Morimoto 1457277911cSKuninori Morimoto #define rsnd_gen_regmap_init(priv, id_size, reg_id, name, conf) \ 1467277911cSKuninori Morimoto _rsnd_gen_regmap_init(priv, id_size, reg_id, name, conf, ARRAY_SIZE(conf)) 147b8c63786SKuninori Morimoto static int _rsnd_gen_regmap_init(struct rsnd_priv *priv, 148b8c63786SKuninori Morimoto int id_size, 149b8c63786SKuninori Morimoto int reg_id, 1507277911cSKuninori Morimoto const char *name, 151b8c63786SKuninori Morimoto struct rsnd_regmap_field_conf *conf, 152b8c63786SKuninori Morimoto int conf_size) 153c1e6cc5eSKuninori Morimoto { 154b8c63786SKuninori Morimoto struct platform_device *pdev = rsnd_priv_to_pdev(priv); 155b8c63786SKuninori Morimoto struct rsnd_gen *gen = rsnd_priv_to_gen(priv); 156c1e6cc5eSKuninori Morimoto struct device *dev = rsnd_priv_to_dev(priv); 157b8c63786SKuninori Morimoto struct resource *res; 158c1e6cc5eSKuninori Morimoto struct regmap_config regc; 159b8c63786SKuninori Morimoto struct regmap_field *regs; 160b8c63786SKuninori Morimoto struct regmap *regmap; 161b8c63786SKuninori Morimoto struct reg_field regf; 162b8c63786SKuninori Morimoto void __iomem *base; 163b8c63786SKuninori Morimoto int i; 164c1e6cc5eSKuninori Morimoto 165c1e6cc5eSKuninori Morimoto memset(®c, 0, sizeof(regc)); 166c1e6cc5eSKuninori Morimoto regc.reg_bits = 32; 167c1e6cc5eSKuninori Morimoto regc.val_bits = 32; 168b8c63786SKuninori Morimoto regc.reg_stride = 4; 169530b7b4aSKuninori Morimoto regc.name = name; 170c1e6cc5eSKuninori Morimoto 1717277911cSKuninori Morimoto res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name); 1727277911cSKuninori Morimoto if (!res) 173b8c63786SKuninori Morimoto res = platform_get_resource(pdev, IORESOURCE_MEM, reg_id); 174b8c63786SKuninori Morimoto if (!res) 175b8c63786SKuninori Morimoto return -ENODEV; 176c1e6cc5eSKuninori Morimoto 177b8c63786SKuninori Morimoto base = devm_ioremap_resource(dev, res); 178b8c63786SKuninori Morimoto if (IS_ERR(base)) 179b8c63786SKuninori Morimoto return PTR_ERR(base); 18042ee5d22SKuninori Morimoto 181b8c63786SKuninori Morimoto regmap = devm_regmap_init_mmio(dev, base, ®c); 182b8c63786SKuninori Morimoto if (IS_ERR(regmap)) 183b8c63786SKuninori Morimoto return PTR_ERR(regmap); 184c1e6cc5eSKuninori Morimoto 185b8c63786SKuninori Morimoto gen->base[reg_id] = base; 186b8c63786SKuninori Morimoto gen->regmap[reg_id] = regmap; 187c5212b45SKuninori Morimoto gen->res[reg_id] = res->start; 188b8c63786SKuninori Morimoto 189b8c63786SKuninori Morimoto for (i = 0; i < conf_size; i++) { 190b8c63786SKuninori Morimoto 191b8c63786SKuninori Morimoto regf.reg = conf[i].reg_offset; 192b8c63786SKuninori Morimoto regf.id_offset = conf[i].id_offset; 193b8c63786SKuninori Morimoto regf.lsb = 0; 194b8c63786SKuninori Morimoto regf.msb = 31; 195b8c63786SKuninori Morimoto regf.id_size = id_size; 196b8c63786SKuninori Morimoto 197b8c63786SKuninori Morimoto regs = devm_regmap_field_alloc(dev, regmap, regf); 198b8c63786SKuninori Morimoto if (IS_ERR(regs)) 199b8c63786SKuninori Morimoto return PTR_ERR(regs); 200b8c63786SKuninori Morimoto 201b8c63786SKuninori Morimoto gen->regs[conf[i].idx] = regs; 202c1e6cc5eSKuninori Morimoto } 203c1e6cc5eSKuninori Morimoto 204c1e6cc5eSKuninori Morimoto return 0; 205c1e6cc5eSKuninori Morimoto } 2063337744aSKuninori Morimoto 207994a9df1SKuninori Morimoto /* 208994a9df1SKuninori Morimoto * Gen2 209994a9df1SKuninori Morimoto */ 210507d466cSKuninori Morimoto static int rsnd_gen2_probe(struct platform_device *pdev, 211507d466cSKuninori Morimoto struct rsnd_priv *priv) 212507d466cSKuninori Morimoto { 213b8c63786SKuninori Morimoto struct rsnd_regmap_field_conf conf_ssiu[] = { 214b8c63786SKuninori Morimoto RSND_GEN_S_REG(SSI_MODE0, 0x800), 215b8c63786SKuninori Morimoto RSND_GEN_S_REG(SSI_MODE1, 0x804), 216b8c63786SKuninori Morimoto /* FIXME: it needs SSI_MODE2/3 in the future */ 217b8c63786SKuninori Morimoto RSND_GEN_M_REG(SSI_BUSIF_MODE, 0x0, 0x80), 218b8c63786SKuninori Morimoto RSND_GEN_M_REG(SSI_BUSIF_ADINR, 0x4, 0x80), 219cdde84d1SKuninori Morimoto RSND_GEN_M_REG(SSI_BUSIF_DALIGN,0x8, 0x80), 220b8c63786SKuninori Morimoto RSND_GEN_M_REG(SSI_CTRL, 0x10, 0x80), 221efa991dcSKuninori Morimoto RSND_GEN_M_REG(SSI_INT_ENABLE, 0x18, 0x80), 222b8c63786SKuninori Morimoto }; 223b8c63786SKuninori Morimoto struct rsnd_regmap_field_conf conf_scu[] = { 224b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_BUSIF_MODE, 0x0, 0x20), 2254689032bSKuninori Morimoto RSND_GEN_M_REG(SRC_BUSIF_DALIGN,0x8, 0x20), 226b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_ROUTE_MODE0, 0xc, 0x20), 227b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_CTRL, 0x10, 0x20), 228cfcefe01SKuninori Morimoto RSND_GEN_M_REG(SRC_INT_ENABLE0, 0x18, 0x20), 229b8c63786SKuninori Morimoto RSND_GEN_M_REG(CMD_ROUTE_SLCT, 0x18c, 0x20), 230b8c63786SKuninori Morimoto RSND_GEN_M_REG(CMD_CTRL, 0x190, 0x20), 231cfcefe01SKuninori Morimoto RSND_GEN_S_REG(SCU_SYS_STATUS0, 0x1c8), 232cfcefe01SKuninori Morimoto RSND_GEN_S_REG(SCU_SYS_INT_EN0, 0x1cc), 233cfcefe01SKuninori Morimoto RSND_GEN_S_REG(SCU_SYS_STATUS1, 0x1d0), 234cfcefe01SKuninori Morimoto RSND_GEN_S_REG(SCU_SYS_INT_EN1, 0x1c4), 235b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_SWRSR, 0x200, 0x40), 236b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_SRCIR, 0x204, 0x40), 237b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_ADINR, 0x214, 0x40), 238b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_IFSCR, 0x21c, 0x40), 239b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_IFSVR, 0x220, 0x40), 240b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_SRCCR, 0x224, 0x40), 241b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_BSDSR, 0x22c, 0x40), 242b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_BSISR, 0x238, 0x40), 2439269e3c3SKuninori Morimoto RSND_GEN_M_REG(CTU_CTUIR, 0x504, 0x100), 2449269e3c3SKuninori Morimoto RSND_GEN_M_REG(CTU_ADINR, 0x508, 0x100), 24570fb1052SKuninori Morimoto RSND_GEN_M_REG(MIX_SWRSR, 0xd00, 0x40), 24670fb1052SKuninori Morimoto RSND_GEN_M_REG(MIX_MIXIR, 0xd04, 0x40), 24770fb1052SKuninori Morimoto RSND_GEN_M_REG(MIX_ADINR, 0xd08, 0x40), 24870fb1052SKuninori Morimoto RSND_GEN_M_REG(MIX_MIXMR, 0xd10, 0x40), 24970fb1052SKuninori Morimoto RSND_GEN_M_REG(MIX_MVPDR, 0xd14, 0x40), 25070fb1052SKuninori Morimoto RSND_GEN_M_REG(MIX_MDBAR, 0xd18, 0x40), 25170fb1052SKuninori Morimoto RSND_GEN_M_REG(MIX_MDBBR, 0xd1c, 0x40), 25270fb1052SKuninori Morimoto RSND_GEN_M_REG(MIX_MDBCR, 0xd20, 0x40), 25370fb1052SKuninori Morimoto RSND_GEN_M_REG(MIX_MDBDR, 0xd24, 0x40), 25470fb1052SKuninori Morimoto RSND_GEN_M_REG(MIX_MDBER, 0xd28, 0x40), 255b8c63786SKuninori Morimoto RSND_GEN_M_REG(DVC_SWRSR, 0xe00, 0x100), 256b8c63786SKuninori Morimoto RSND_GEN_M_REG(DVC_DVUIR, 0xe04, 0x100), 257b8c63786SKuninori Morimoto RSND_GEN_M_REG(DVC_ADINR, 0xe08, 0x100), 258b8c63786SKuninori Morimoto RSND_GEN_M_REG(DVC_DVUCR, 0xe10, 0x100), 259b8c63786SKuninori Morimoto RSND_GEN_M_REG(DVC_ZCMCR, 0xe14, 0x100), 2603539cacfSKuninori Morimoto RSND_GEN_M_REG(DVC_VRCTR, 0xe18, 0x100), 2613539cacfSKuninori Morimoto RSND_GEN_M_REG(DVC_VRPDR, 0xe1c, 0x100), 2623539cacfSKuninori Morimoto RSND_GEN_M_REG(DVC_VRDBR, 0xe20, 0x100), 263b8c63786SKuninori Morimoto RSND_GEN_M_REG(DVC_VOL0R, 0xe28, 0x100), 264b8c63786SKuninori Morimoto RSND_GEN_M_REG(DVC_VOL1R, 0xe2c, 0x100), 265b8c63786SKuninori Morimoto RSND_GEN_M_REG(DVC_DVUER, 0xe48, 0x100), 266b8c63786SKuninori Morimoto }; 267b8c63786SKuninori Morimoto struct rsnd_regmap_field_conf conf_adg[] = { 268b8c63786SKuninori Morimoto RSND_GEN_S_REG(BRRA, 0x00), 269b8c63786SKuninori Morimoto RSND_GEN_S_REG(BRRB, 0x04), 270b8c63786SKuninori Morimoto RSND_GEN_S_REG(SSICKR, 0x08), 271b8c63786SKuninori Morimoto RSND_GEN_S_REG(AUDIO_CLK_SEL0, 0x0c), 272b8c63786SKuninori Morimoto RSND_GEN_S_REG(AUDIO_CLK_SEL1, 0x10), 273b8c63786SKuninori Morimoto RSND_GEN_S_REG(AUDIO_CLK_SEL2, 0x14), 274b8c63786SKuninori Morimoto RSND_GEN_S_REG(DIV_EN, 0x30), 275b8c63786SKuninori Morimoto RSND_GEN_S_REG(SRCIN_TIMSEL0, 0x34), 276b8c63786SKuninori Morimoto RSND_GEN_S_REG(SRCIN_TIMSEL1, 0x38), 277b8c63786SKuninori Morimoto RSND_GEN_S_REG(SRCIN_TIMSEL2, 0x3c), 278b8c63786SKuninori Morimoto RSND_GEN_S_REG(SRCIN_TIMSEL3, 0x40), 279b8c63786SKuninori Morimoto RSND_GEN_S_REG(SRCIN_TIMSEL4, 0x44), 280b8c63786SKuninori Morimoto RSND_GEN_S_REG(SRCOUT_TIMSEL0, 0x48), 281b8c63786SKuninori Morimoto RSND_GEN_S_REG(SRCOUT_TIMSEL1, 0x4c), 282b8c63786SKuninori Morimoto RSND_GEN_S_REG(SRCOUT_TIMSEL2, 0x50), 283b8c63786SKuninori Morimoto RSND_GEN_S_REG(SRCOUT_TIMSEL3, 0x54), 284b8c63786SKuninori Morimoto RSND_GEN_S_REG(SRCOUT_TIMSEL4, 0x58), 285b8c63786SKuninori Morimoto RSND_GEN_S_REG(CMDOUT_TIMSEL, 0x5c), 286b8c63786SKuninori Morimoto }; 287b8c63786SKuninori Morimoto struct rsnd_regmap_field_conf conf_ssi[] = { 288b8c63786SKuninori Morimoto RSND_GEN_M_REG(SSICR, 0x00, 0x40), 289b8c63786SKuninori Morimoto RSND_GEN_M_REG(SSISR, 0x04, 0x40), 290b8c63786SKuninori Morimoto RSND_GEN_M_REG(SSITDR, 0x08, 0x40), 291b8c63786SKuninori Morimoto RSND_GEN_M_REG(SSIRDR, 0x0c, 0x40), 292b8c63786SKuninori Morimoto RSND_GEN_M_REG(SSIWSR, 0x20, 0x40), 293b8c63786SKuninori Morimoto }; 294b8c63786SKuninori Morimoto int ret_ssiu; 295b8c63786SKuninori Morimoto int ret_scu; 296b8c63786SKuninori Morimoto int ret_adg; 297b8c63786SKuninori Morimoto int ret_ssi; 298507d466cSKuninori Morimoto 2997277911cSKuninori Morimoto ret_ssiu = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_SSIU, "ssiu", conf_ssiu); 3007277911cSKuninori Morimoto ret_scu = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_SCU, "scu", conf_scu); 3017277911cSKuninori Morimoto ret_adg = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_ADG, "adg", conf_adg); 3027277911cSKuninori Morimoto ret_ssi = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_SSI, "ssi", conf_ssi); 303b8c63786SKuninori Morimoto if (ret_ssiu < 0 || 304b8c63786SKuninori Morimoto ret_scu < 0 || 305b8c63786SKuninori Morimoto ret_adg < 0 || 306b8c63786SKuninori Morimoto ret_ssi < 0) 307b8c63786SKuninori Morimoto return ret_ssiu | ret_scu | ret_adg | ret_ssi; 308507d466cSKuninori Morimoto 309507d466cSKuninori Morimoto return 0; 310507d466cSKuninori Morimoto } 311507d466cSKuninori Morimoto 312994a9df1SKuninori Morimoto /* 313994a9df1SKuninori Morimoto * Gen1 314994a9df1SKuninori Morimoto */ 315994a9df1SKuninori Morimoto 3163337744aSKuninori Morimoto static int rsnd_gen1_probe(struct platform_device *pdev, 3173337744aSKuninori Morimoto struct rsnd_priv *priv) 3183337744aSKuninori Morimoto { 319b8c63786SKuninori Morimoto struct rsnd_regmap_field_conf conf_sru[] = { 320b8c63786SKuninori Morimoto RSND_GEN_S_REG(SRC_ROUTE_SEL, 0x00), 321b8c63786SKuninori Morimoto RSND_GEN_S_REG(SRC_TMG_SEL0, 0x08), 322b8c63786SKuninori Morimoto RSND_GEN_S_REG(SRC_TMG_SEL1, 0x0c), 323b8c63786SKuninori Morimoto RSND_GEN_S_REG(SRC_TMG_SEL2, 0x10), 324b8c63786SKuninori Morimoto RSND_GEN_S_REG(SRC_ROUTE_CTRL, 0xc0), 325b8c63786SKuninori Morimoto RSND_GEN_S_REG(SSI_MODE0, 0xD0), 326b8c63786SKuninori Morimoto RSND_GEN_S_REG(SSI_MODE1, 0xD4), 327b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_BUSIF_MODE, 0x20, 0x4), 328b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_ROUTE_MODE0, 0x50, 0x8), 329b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_SWRSR, 0x200, 0x40), 330b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_SRCIR, 0x204, 0x40), 331b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_ADINR, 0x214, 0x40), 332b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_IFSCR, 0x21c, 0x40), 333b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_IFSVR, 0x220, 0x40), 334b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_SRCCR, 0x224, 0x40), 335b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_MNFSR, 0x228, 0x40), 336cfcefe01SKuninori Morimoto /* 337cfcefe01SKuninori Morimoto * ADD US 338cfcefe01SKuninori Morimoto * 339cfcefe01SKuninori Morimoto * SRC_STATUS 340cfcefe01SKuninori Morimoto * SRC_INT_EN 341cfcefe01SKuninori Morimoto * SCU_SYS_STATUS0 342cfcefe01SKuninori Morimoto * SCU_SYS_STATUS1 343cfcefe01SKuninori Morimoto * SCU_SYS_INT_EN0 344cfcefe01SKuninori Morimoto * SCU_SYS_INT_EN1 345cfcefe01SKuninori Morimoto */ 346b8c63786SKuninori Morimoto }; 347b8c63786SKuninori Morimoto struct rsnd_regmap_field_conf conf_adg[] = { 348b8c63786SKuninori Morimoto RSND_GEN_S_REG(BRRA, 0x00), 349b8c63786SKuninori Morimoto RSND_GEN_S_REG(BRRB, 0x04), 350b8c63786SKuninori Morimoto RSND_GEN_S_REG(SSICKR, 0x08), 351b8c63786SKuninori Morimoto RSND_GEN_S_REG(AUDIO_CLK_SEL0, 0x0c), 352b8c63786SKuninori Morimoto RSND_GEN_S_REG(AUDIO_CLK_SEL1, 0x10), 353b8c63786SKuninori Morimoto RSND_GEN_S_REG(AUDIO_CLK_SEL3, 0x18), 354b8c63786SKuninori Morimoto RSND_GEN_S_REG(AUDIO_CLK_SEL4, 0x1c), 355b8c63786SKuninori Morimoto RSND_GEN_S_REG(AUDIO_CLK_SEL5, 0x20), 356b8c63786SKuninori Morimoto }; 357b8c63786SKuninori Morimoto struct rsnd_regmap_field_conf conf_ssi[] = { 358b8c63786SKuninori Morimoto RSND_GEN_M_REG(SSICR, 0x00, 0x40), 359b8c63786SKuninori Morimoto RSND_GEN_M_REG(SSISR, 0x04, 0x40), 360b8c63786SKuninori Morimoto RSND_GEN_M_REG(SSITDR, 0x08, 0x40), 361b8c63786SKuninori Morimoto RSND_GEN_M_REG(SSIRDR, 0x0c, 0x40), 362b8c63786SKuninori Morimoto RSND_GEN_M_REG(SSIWSR, 0x20, 0x40), 363b8c63786SKuninori Morimoto }; 364b8c63786SKuninori Morimoto int ret_sru; 365b8c63786SKuninori Morimoto int ret_adg; 366b8c63786SKuninori Morimoto int ret_ssi; 36707539c1dSKuninori Morimoto 3687277911cSKuninori Morimoto ret_sru = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_SRU, "sru", conf_sru); 3697277911cSKuninori Morimoto ret_adg = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_ADG, "adg", conf_adg); 3707277911cSKuninori Morimoto ret_ssi = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_SSI, "ssi", conf_ssi); 371b8c63786SKuninori Morimoto if (ret_sru < 0 || 372b8c63786SKuninori Morimoto ret_adg < 0 || 373b8c63786SKuninori Morimoto ret_ssi < 0) 374b8c63786SKuninori Morimoto return ret_sru | ret_adg | ret_ssi; 37507539c1dSKuninori Morimoto 3763337744aSKuninori Morimoto return 0; 3773337744aSKuninori Morimoto } 3783337744aSKuninori Morimoto 3793337744aSKuninori Morimoto /* 3803337744aSKuninori Morimoto * Gen 3813337744aSKuninori Morimoto */ 38290e8e50fSKuninori Morimoto static void rsnd_of_parse_gen(struct platform_device *pdev, 38390e8e50fSKuninori Morimoto const struct rsnd_of_data *of_data, 38490e8e50fSKuninori Morimoto struct rsnd_priv *priv) 38590e8e50fSKuninori Morimoto { 38690e8e50fSKuninori Morimoto struct rcar_snd_info *info = priv->info; 38790e8e50fSKuninori Morimoto 38890e8e50fSKuninori Morimoto if (!of_data) 38990e8e50fSKuninori Morimoto return; 39090e8e50fSKuninori Morimoto 39190e8e50fSKuninori Morimoto info->flags = of_data->flags; 39290e8e50fSKuninori Morimoto } 39390e8e50fSKuninori Morimoto 3943337744aSKuninori Morimoto int rsnd_gen_probe(struct platform_device *pdev, 39590e8e50fSKuninori Morimoto const struct rsnd_of_data *of_data, 3963337744aSKuninori Morimoto struct rsnd_priv *priv) 3973337744aSKuninori Morimoto { 3983337744aSKuninori Morimoto struct device *dev = rsnd_priv_to_dev(priv); 3993337744aSKuninori Morimoto struct rsnd_gen *gen; 400531eaf49SKuninori Morimoto int ret; 4013337744aSKuninori Morimoto 40290e8e50fSKuninori Morimoto rsnd_of_parse_gen(pdev, of_data, priv); 40390e8e50fSKuninori Morimoto 4043337744aSKuninori Morimoto gen = devm_kzalloc(dev, sizeof(*gen), GFP_KERNEL); 4053337744aSKuninori Morimoto if (!gen) { 4063337744aSKuninori Morimoto dev_err(dev, "GEN allocate failed\n"); 4073337744aSKuninori Morimoto return -ENOMEM; 4083337744aSKuninori Morimoto } 4093337744aSKuninori Morimoto 410531eaf49SKuninori Morimoto priv->gen = gen; 411072188b6SKuninori Morimoto 412507d466cSKuninori Morimoto ret = -ENODEV; 413507d466cSKuninori Morimoto if (rsnd_is_gen1(priv)) 4145da39cf3SKuninori Morimoto ret = rsnd_gen1_probe(pdev, priv); 415507d466cSKuninori Morimoto else if (rsnd_is_gen2(priv)) 4165da39cf3SKuninori Morimoto ret = rsnd_gen2_probe(pdev, priv); 417507d466cSKuninori Morimoto 418507d466cSKuninori Morimoto if (ret < 0) 419072188b6SKuninori Morimoto dev_err(dev, "unknown generation R-Car sound device\n"); 420072188b6SKuninori Morimoto 421531eaf49SKuninori Morimoto return ret; 4223337744aSKuninori Morimoto } 423