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 8230cc4fafSKuninori Morimoto dev_dbg(dev, "r %s[%d] - %4d : %08x\n", 83ace0eb1eSKuninori Morimoto rsnd_mod_name(mod), rsnd_mod_id(mod), reg, val); 8455e5b6fdSKuninori Morimoto 85ace0eb1eSKuninori Morimoto regmap_fields_read(gen->regs[reg], rsnd_mod_id(mod), &val); 86b8c63786SKuninori 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), 225b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_ROUTE_MODE0, 0xc, 0x20), 226b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_CTRL, 0x10, 0x20), 227cfcefe01SKuninori Morimoto RSND_GEN_M_REG(SRC_INT_ENABLE0, 0x18, 0x20), 228b8c63786SKuninori Morimoto RSND_GEN_M_REG(CMD_ROUTE_SLCT, 0x18c, 0x20), 229b8c63786SKuninori Morimoto RSND_GEN_M_REG(CMD_CTRL, 0x190, 0x20), 230cfcefe01SKuninori Morimoto RSND_GEN_S_REG(SCU_SYS_STATUS0, 0x1c8), 231cfcefe01SKuninori Morimoto RSND_GEN_S_REG(SCU_SYS_INT_EN0, 0x1cc), 232cfcefe01SKuninori Morimoto RSND_GEN_S_REG(SCU_SYS_STATUS1, 0x1d0), 233cfcefe01SKuninori Morimoto RSND_GEN_S_REG(SCU_SYS_INT_EN1, 0x1c4), 234b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_SWRSR, 0x200, 0x40), 235b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_SRCIR, 0x204, 0x40), 236b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_ADINR, 0x214, 0x40), 237b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_IFSCR, 0x21c, 0x40), 238b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_IFSVR, 0x220, 0x40), 239b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_SRCCR, 0x224, 0x40), 240b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_BSDSR, 0x22c, 0x40), 241b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_BSISR, 0x238, 0x40), 242b8c63786SKuninori Morimoto RSND_GEN_M_REG(DVC_SWRSR, 0xe00, 0x100), 243b8c63786SKuninori Morimoto RSND_GEN_M_REG(DVC_DVUIR, 0xe04, 0x100), 244b8c63786SKuninori Morimoto RSND_GEN_M_REG(DVC_ADINR, 0xe08, 0x100), 245b8c63786SKuninori Morimoto RSND_GEN_M_REG(DVC_DVUCR, 0xe10, 0x100), 246b8c63786SKuninori Morimoto RSND_GEN_M_REG(DVC_ZCMCR, 0xe14, 0x100), 2473539cacfSKuninori Morimoto RSND_GEN_M_REG(DVC_VRCTR, 0xe18, 0x100), 2483539cacfSKuninori Morimoto RSND_GEN_M_REG(DVC_VRPDR, 0xe1c, 0x100), 2493539cacfSKuninori Morimoto RSND_GEN_M_REG(DVC_VRDBR, 0xe20, 0x100), 250b8c63786SKuninori Morimoto RSND_GEN_M_REG(DVC_VOL0R, 0xe28, 0x100), 251b8c63786SKuninori Morimoto RSND_GEN_M_REG(DVC_VOL1R, 0xe2c, 0x100), 252b8c63786SKuninori Morimoto RSND_GEN_M_REG(DVC_DVUER, 0xe48, 0x100), 253b8c63786SKuninori Morimoto }; 254b8c63786SKuninori Morimoto struct rsnd_regmap_field_conf conf_adg[] = { 255b8c63786SKuninori Morimoto RSND_GEN_S_REG(BRRA, 0x00), 256b8c63786SKuninori Morimoto RSND_GEN_S_REG(BRRB, 0x04), 257b8c63786SKuninori Morimoto RSND_GEN_S_REG(SSICKR, 0x08), 258b8c63786SKuninori Morimoto RSND_GEN_S_REG(AUDIO_CLK_SEL0, 0x0c), 259b8c63786SKuninori Morimoto RSND_GEN_S_REG(AUDIO_CLK_SEL1, 0x10), 260b8c63786SKuninori Morimoto RSND_GEN_S_REG(AUDIO_CLK_SEL2, 0x14), 261b8c63786SKuninori Morimoto RSND_GEN_S_REG(DIV_EN, 0x30), 262b8c63786SKuninori Morimoto RSND_GEN_S_REG(SRCIN_TIMSEL0, 0x34), 263b8c63786SKuninori Morimoto RSND_GEN_S_REG(SRCIN_TIMSEL1, 0x38), 264b8c63786SKuninori Morimoto RSND_GEN_S_REG(SRCIN_TIMSEL2, 0x3c), 265b8c63786SKuninori Morimoto RSND_GEN_S_REG(SRCIN_TIMSEL3, 0x40), 266b8c63786SKuninori Morimoto RSND_GEN_S_REG(SRCIN_TIMSEL4, 0x44), 267b8c63786SKuninori Morimoto RSND_GEN_S_REG(SRCOUT_TIMSEL0, 0x48), 268b8c63786SKuninori Morimoto RSND_GEN_S_REG(SRCOUT_TIMSEL1, 0x4c), 269b8c63786SKuninori Morimoto RSND_GEN_S_REG(SRCOUT_TIMSEL2, 0x50), 270b8c63786SKuninori Morimoto RSND_GEN_S_REG(SRCOUT_TIMSEL3, 0x54), 271b8c63786SKuninori Morimoto RSND_GEN_S_REG(SRCOUT_TIMSEL4, 0x58), 272b8c63786SKuninori Morimoto RSND_GEN_S_REG(CMDOUT_TIMSEL, 0x5c), 273b8c63786SKuninori Morimoto }; 274b8c63786SKuninori Morimoto struct rsnd_regmap_field_conf conf_ssi[] = { 275b8c63786SKuninori Morimoto RSND_GEN_M_REG(SSICR, 0x00, 0x40), 276b8c63786SKuninori Morimoto RSND_GEN_M_REG(SSISR, 0x04, 0x40), 277b8c63786SKuninori Morimoto RSND_GEN_M_REG(SSITDR, 0x08, 0x40), 278b8c63786SKuninori Morimoto RSND_GEN_M_REG(SSIRDR, 0x0c, 0x40), 279b8c63786SKuninori Morimoto RSND_GEN_M_REG(SSIWSR, 0x20, 0x40), 280b8c63786SKuninori Morimoto }; 281b8c63786SKuninori Morimoto int ret_ssiu; 282b8c63786SKuninori Morimoto int ret_scu; 283b8c63786SKuninori Morimoto int ret_adg; 284b8c63786SKuninori Morimoto int ret_ssi; 285507d466cSKuninori Morimoto 2867277911cSKuninori Morimoto ret_ssiu = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_SSIU, "ssiu", conf_ssiu); 2877277911cSKuninori Morimoto ret_scu = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_SCU, "scu", conf_scu); 2887277911cSKuninori Morimoto ret_adg = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_ADG, "adg", conf_adg); 2897277911cSKuninori Morimoto ret_ssi = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_SSI, "ssi", conf_ssi); 290b8c63786SKuninori Morimoto if (ret_ssiu < 0 || 291b8c63786SKuninori Morimoto ret_scu < 0 || 292b8c63786SKuninori Morimoto ret_adg < 0 || 293b8c63786SKuninori Morimoto ret_ssi < 0) 294b8c63786SKuninori Morimoto return ret_ssiu | ret_scu | ret_adg | ret_ssi; 295507d466cSKuninori Morimoto 296507d466cSKuninori Morimoto return 0; 297507d466cSKuninori Morimoto } 298507d466cSKuninori Morimoto 299994a9df1SKuninori Morimoto /* 300994a9df1SKuninori Morimoto * Gen1 301994a9df1SKuninori Morimoto */ 302994a9df1SKuninori Morimoto 3033337744aSKuninori Morimoto static int rsnd_gen1_probe(struct platform_device *pdev, 3043337744aSKuninori Morimoto struct rsnd_priv *priv) 3053337744aSKuninori Morimoto { 306b8c63786SKuninori Morimoto struct rsnd_regmap_field_conf conf_sru[] = { 307b8c63786SKuninori Morimoto RSND_GEN_S_REG(SRC_ROUTE_SEL, 0x00), 308b8c63786SKuninori Morimoto RSND_GEN_S_REG(SRC_TMG_SEL0, 0x08), 309b8c63786SKuninori Morimoto RSND_GEN_S_REG(SRC_TMG_SEL1, 0x0c), 310b8c63786SKuninori Morimoto RSND_GEN_S_REG(SRC_TMG_SEL2, 0x10), 311b8c63786SKuninori Morimoto RSND_GEN_S_REG(SRC_ROUTE_CTRL, 0xc0), 312b8c63786SKuninori Morimoto RSND_GEN_S_REG(SSI_MODE0, 0xD0), 313b8c63786SKuninori Morimoto RSND_GEN_S_REG(SSI_MODE1, 0xD4), 314b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_BUSIF_MODE, 0x20, 0x4), 315b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_ROUTE_MODE0, 0x50, 0x8), 316b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_SWRSR, 0x200, 0x40), 317b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_SRCIR, 0x204, 0x40), 318b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_ADINR, 0x214, 0x40), 319b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_IFSCR, 0x21c, 0x40), 320b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_IFSVR, 0x220, 0x40), 321b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_SRCCR, 0x224, 0x40), 322b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_MNFSR, 0x228, 0x40), 323cfcefe01SKuninori Morimoto /* 324cfcefe01SKuninori Morimoto * ADD US 325cfcefe01SKuninori Morimoto * 326cfcefe01SKuninori Morimoto * SRC_STATUS 327cfcefe01SKuninori Morimoto * SRC_INT_EN 328cfcefe01SKuninori Morimoto * SCU_SYS_STATUS0 329cfcefe01SKuninori Morimoto * SCU_SYS_STATUS1 330cfcefe01SKuninori Morimoto * SCU_SYS_INT_EN0 331cfcefe01SKuninori Morimoto * SCU_SYS_INT_EN1 332cfcefe01SKuninori Morimoto */ 333b8c63786SKuninori Morimoto }; 334b8c63786SKuninori Morimoto struct rsnd_regmap_field_conf conf_adg[] = { 335b8c63786SKuninori Morimoto RSND_GEN_S_REG(BRRA, 0x00), 336b8c63786SKuninori Morimoto RSND_GEN_S_REG(BRRB, 0x04), 337b8c63786SKuninori Morimoto RSND_GEN_S_REG(SSICKR, 0x08), 338b8c63786SKuninori Morimoto RSND_GEN_S_REG(AUDIO_CLK_SEL0, 0x0c), 339b8c63786SKuninori Morimoto RSND_GEN_S_REG(AUDIO_CLK_SEL1, 0x10), 340b8c63786SKuninori Morimoto RSND_GEN_S_REG(AUDIO_CLK_SEL3, 0x18), 341b8c63786SKuninori Morimoto RSND_GEN_S_REG(AUDIO_CLK_SEL4, 0x1c), 342b8c63786SKuninori Morimoto RSND_GEN_S_REG(AUDIO_CLK_SEL5, 0x20), 343b8c63786SKuninori Morimoto }; 344b8c63786SKuninori Morimoto struct rsnd_regmap_field_conf conf_ssi[] = { 345b8c63786SKuninori Morimoto RSND_GEN_M_REG(SSICR, 0x00, 0x40), 346b8c63786SKuninori Morimoto RSND_GEN_M_REG(SSISR, 0x04, 0x40), 347b8c63786SKuninori Morimoto RSND_GEN_M_REG(SSITDR, 0x08, 0x40), 348b8c63786SKuninori Morimoto RSND_GEN_M_REG(SSIRDR, 0x0c, 0x40), 349b8c63786SKuninori Morimoto RSND_GEN_M_REG(SSIWSR, 0x20, 0x40), 350b8c63786SKuninori Morimoto }; 351b8c63786SKuninori Morimoto int ret_sru; 352b8c63786SKuninori Morimoto int ret_adg; 353b8c63786SKuninori Morimoto int ret_ssi; 35407539c1dSKuninori Morimoto 3557277911cSKuninori Morimoto ret_sru = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_SRU, "sru", conf_sru); 3567277911cSKuninori Morimoto ret_adg = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_ADG, "adg", conf_adg); 3577277911cSKuninori Morimoto ret_ssi = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_SSI, "ssi", conf_ssi); 358b8c63786SKuninori Morimoto if (ret_sru < 0 || 359b8c63786SKuninori Morimoto ret_adg < 0 || 360b8c63786SKuninori Morimoto ret_ssi < 0) 361b8c63786SKuninori Morimoto return ret_sru | ret_adg | ret_ssi; 36207539c1dSKuninori Morimoto 3633337744aSKuninori Morimoto return 0; 3643337744aSKuninori Morimoto } 3653337744aSKuninori Morimoto 3663337744aSKuninori Morimoto /* 3673337744aSKuninori Morimoto * Gen 3683337744aSKuninori Morimoto */ 36990e8e50fSKuninori Morimoto static void rsnd_of_parse_gen(struct platform_device *pdev, 37090e8e50fSKuninori Morimoto const struct rsnd_of_data *of_data, 37190e8e50fSKuninori Morimoto struct rsnd_priv *priv) 37290e8e50fSKuninori Morimoto { 37390e8e50fSKuninori Morimoto struct rcar_snd_info *info = priv->info; 37490e8e50fSKuninori Morimoto 37590e8e50fSKuninori Morimoto if (!of_data) 37690e8e50fSKuninori Morimoto return; 37790e8e50fSKuninori Morimoto 37890e8e50fSKuninori Morimoto info->flags = of_data->flags; 37990e8e50fSKuninori Morimoto } 38090e8e50fSKuninori Morimoto 3813337744aSKuninori Morimoto int rsnd_gen_probe(struct platform_device *pdev, 38290e8e50fSKuninori Morimoto const struct rsnd_of_data *of_data, 3833337744aSKuninori Morimoto struct rsnd_priv *priv) 3843337744aSKuninori Morimoto { 3853337744aSKuninori Morimoto struct device *dev = rsnd_priv_to_dev(priv); 3863337744aSKuninori Morimoto struct rsnd_gen *gen; 387531eaf49SKuninori Morimoto int ret; 3883337744aSKuninori Morimoto 38990e8e50fSKuninori Morimoto rsnd_of_parse_gen(pdev, of_data, priv); 39090e8e50fSKuninori Morimoto 3913337744aSKuninori Morimoto gen = devm_kzalloc(dev, sizeof(*gen), GFP_KERNEL); 3923337744aSKuninori Morimoto if (!gen) { 3933337744aSKuninori Morimoto dev_err(dev, "GEN allocate failed\n"); 3943337744aSKuninori Morimoto return -ENOMEM; 3953337744aSKuninori Morimoto } 3963337744aSKuninori Morimoto 397531eaf49SKuninori Morimoto priv->gen = gen; 398072188b6SKuninori Morimoto 399507d466cSKuninori Morimoto ret = -ENODEV; 400507d466cSKuninori Morimoto if (rsnd_is_gen1(priv)) 4015da39cf3SKuninori Morimoto ret = rsnd_gen1_probe(pdev, priv); 402507d466cSKuninori Morimoto else if (rsnd_is_gen2(priv)) 4035da39cf3SKuninori Morimoto ret = rsnd_gen2_probe(pdev, priv); 404507d466cSKuninori Morimoto 405507d466cSKuninori Morimoto if (ret < 0) 406072188b6SKuninori Morimoto dev_err(dev, "unknown generation R-Car sound device\n"); 407072188b6SKuninori Morimoto 408531eaf49SKuninori Morimoto return ret; 4093337744aSKuninori Morimoto } 410