void __iomem *rsnd_gen_reg_get(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg) { struct rsnd_gen *gen = rsnd_priv_to_gen(priv); struct device *dev = rsnd_priv_to_dev(priv); int index; u32 offset_id, offset_adr; if (reg >= RSND_REG_MAX) { dev_err(dev, "rsnd_reg reg error\n"); return NULL; } index = gen->reg_map[reg].index; offset_id = gen->reg_map[reg].offset_id; offset_adr = gen->reg_map[reg].offset_adr; if (index < 0) { dev_err(dev, "unsupported reg access %d\n", reg); return NULL; } if (offset_id && mod) offset_id *= rsnd_mod_id(mod); /* * index/offset were set on gen1/gen2 */ return gen->base[index] + offset_id + offset_adr; }
int rsnd_gen_path_exit(struct rsnd_priv *priv, struct rsnd_dai *rdai, struct rsnd_dai_stream *io) { struct rsnd_gen *gen = rsnd_priv_to_gen(priv); return gen->ops->path_exit(priv, rdai, io); }
void rsnd_write(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg, u32 data) { 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; dev_dbg(dev, "w %s[%d] - %4d : %08x\n", rsnd_mod_name(mod), rsnd_mod_id(mod), reg, data); regmap_fields_write(gen->regs[reg], rsnd_mod_id(mod), data); }
void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg, u32 mask, u32 data) { 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_update_bits(gen->regs[reg], rsnd_mod_id(mod), mask, data); dev_dbg(dev, "b %s[%d] - %-18s (%4d) : %08x/%08x\n", rsnd_mod_name(mod), rsnd_mod_id(mod), rsnd_reg_name(gen, reg), reg, data, mask); }
u32 rsnd_read(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg) { 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(mod), &val); dev_dbg(dev, "r %s[%d] - %4d : %08x\n", rsnd_mod_name(mod), rsnd_mod_id(mod), reg, val); return val; }
static int rsnd_gen1_probe(struct platform_device *pdev, struct rcar_snd_info *info, struct rsnd_priv *priv) { struct device *dev = rsnd_priv_to_dev(priv); struct rsnd_gen *gen = rsnd_priv_to_gen(priv); struct resource *sru_res; struct resource *adg_res; struct resource *ssi_res; /* * map address */ sru_res = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN1_SRU); adg_res = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN1_ADG); ssi_res = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN1_SSI); gen->base[RSND_GEN1_SRU] = devm_ioremap_resource(dev, sru_res); gen->base[RSND_GEN1_ADG] = devm_ioremap_resource(dev, adg_res); gen->base[RSND_GEN1_SSI] = devm_ioremap_resource(dev, ssi_res); if (IS_ERR(gen->base[RSND_GEN1_SRU]) || IS_ERR(gen->base[RSND_GEN1_ADG]) || IS_ERR(gen->base[RSND_GEN1_SSI])) return -ENODEV; gen->ops = &rsnd_gen1_ops; rsnd_gen1_reg_map_init(gen); dev_dbg(dev, "Gen1 device probed\n"); dev_dbg(dev, "SRU : %08x => %p\n", sru_res->start, gen->base[RSND_GEN1_SRU]); dev_dbg(dev, "ADG : %08x => %p\n", adg_res->start, gen->base[RSND_GEN1_ADG]); dev_dbg(dev, "SSI : %08x => %p\n", ssi_res->start, gen->base[RSND_GEN1_SSI]); return 0; }
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) res = platform_get_resource(pdev, IORESOURCE_MEM, reg_id); 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; }
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]; }