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 */ 113337744aSKuninori Morimoto #include "rsnd.h" 123337744aSKuninori Morimoto 133337744aSKuninori Morimoto struct rsnd_gen { 143337744aSKuninori Morimoto void __iomem *base[RSND_BASE_MAX]; 153337744aSKuninori Morimoto 163337744aSKuninori Morimoto struct rsnd_gen_ops *ops; 1755e5b6fdSKuninori Morimoto 1855e5b6fdSKuninori Morimoto struct regmap *regmap; 1955e5b6fdSKuninori Morimoto struct regmap_field *regs[RSND_REG_MAX]; 203337744aSKuninori Morimoto }; 213337744aSKuninori Morimoto 223337744aSKuninori Morimoto #define rsnd_priv_to_gen(p) ((struct rsnd_gen *)(p)->gen) 233337744aSKuninori Morimoto 2455e5b6fdSKuninori Morimoto #define RSND_REG_SET(gen, id, reg_id, offset, _id_offset, _id_size) \ 2555e5b6fdSKuninori Morimoto [id] = { \ 2655e5b6fdSKuninori Morimoto .reg = (unsigned int)gen->base[reg_id] + offset, \ 2755e5b6fdSKuninori Morimoto .lsb = 0, \ 2855e5b6fdSKuninori Morimoto .msb = 31, \ 2955e5b6fdSKuninori Morimoto .id_size = _id_size, \ 3055e5b6fdSKuninori Morimoto .id_offset = _id_offset, \ 3155e5b6fdSKuninori Morimoto } 3255e5b6fdSKuninori Morimoto 3355e5b6fdSKuninori Morimoto /* 3455e5b6fdSKuninori Morimoto * basic function 3555e5b6fdSKuninori Morimoto */ 3655e5b6fdSKuninori Morimoto static int rsnd_regmap_write32(void *context, const void *_data, size_t count) 3755e5b6fdSKuninori Morimoto { 3855e5b6fdSKuninori Morimoto struct rsnd_priv *priv = context; 3955e5b6fdSKuninori Morimoto struct device *dev = rsnd_priv_to_dev(priv); 4055e5b6fdSKuninori Morimoto u32 *data = (u32 *)_data; 4155e5b6fdSKuninori Morimoto u32 val = data[1]; 4255e5b6fdSKuninori Morimoto void __iomem *reg = (void *)data[0]; 4355e5b6fdSKuninori Morimoto 4455e5b6fdSKuninori Morimoto iowrite32(val, reg); 4555e5b6fdSKuninori Morimoto 4655e5b6fdSKuninori Morimoto dev_dbg(dev, "w %p : %08x\n", reg, val); 4755e5b6fdSKuninori Morimoto 4855e5b6fdSKuninori Morimoto return 0; 4955e5b6fdSKuninori Morimoto } 5055e5b6fdSKuninori Morimoto 5155e5b6fdSKuninori Morimoto static int rsnd_regmap_read32(void *context, 5255e5b6fdSKuninori Morimoto const void *_data, size_t reg_size, 5355e5b6fdSKuninori Morimoto void *_val, size_t val_size) 5455e5b6fdSKuninori Morimoto { 5555e5b6fdSKuninori Morimoto struct rsnd_priv *priv = context; 5655e5b6fdSKuninori Morimoto struct device *dev = rsnd_priv_to_dev(priv); 5755e5b6fdSKuninori Morimoto u32 *data = (u32 *)_data; 5855e5b6fdSKuninori Morimoto u32 *val = (u32 *)_val; 5955e5b6fdSKuninori Morimoto void __iomem *reg = (void *)data[0]; 6055e5b6fdSKuninori Morimoto 6155e5b6fdSKuninori Morimoto *val = ioread32(reg); 6255e5b6fdSKuninori Morimoto 6355e5b6fdSKuninori Morimoto dev_dbg(dev, "r %p : %08x\n", reg, *val); 6455e5b6fdSKuninori Morimoto 6555e5b6fdSKuninori Morimoto return 0; 6655e5b6fdSKuninori Morimoto } 6755e5b6fdSKuninori Morimoto 6855e5b6fdSKuninori Morimoto static struct regmap_bus rsnd_regmap_bus = { 6955e5b6fdSKuninori Morimoto .write = rsnd_regmap_write32, 7055e5b6fdSKuninori Morimoto .read = rsnd_regmap_read32, 7155e5b6fdSKuninori Morimoto .reg_format_endian_default = REGMAP_ENDIAN_NATIVE, 7255e5b6fdSKuninori Morimoto .val_format_endian_default = REGMAP_ENDIAN_NATIVE, 7355e5b6fdSKuninori Morimoto }; 7455e5b6fdSKuninori Morimoto 7542ee5d22SKuninori Morimoto static int rsnd_is_accessible_reg(struct rsnd_priv *priv, 7642ee5d22SKuninori Morimoto struct rsnd_gen *gen, enum rsnd_reg reg) 7742ee5d22SKuninori Morimoto { 7842ee5d22SKuninori Morimoto if (!gen->regs[reg]) { 7942ee5d22SKuninori Morimoto struct device *dev = rsnd_priv_to_dev(priv); 8042ee5d22SKuninori Morimoto 8142ee5d22SKuninori Morimoto dev_err(dev, "unsupported register access %x\n", reg); 8242ee5d22SKuninori Morimoto return 0; 8342ee5d22SKuninori Morimoto } 8442ee5d22SKuninori Morimoto 8542ee5d22SKuninori Morimoto return 1; 8642ee5d22SKuninori Morimoto } 8742ee5d22SKuninori Morimoto 8855e5b6fdSKuninori Morimoto u32 rsnd_read(struct rsnd_priv *priv, 8955e5b6fdSKuninori Morimoto struct rsnd_mod *mod, enum rsnd_reg reg) 9055e5b6fdSKuninori Morimoto { 9155e5b6fdSKuninori Morimoto struct rsnd_gen *gen = rsnd_priv_to_gen(priv); 9255e5b6fdSKuninori Morimoto u32 val; 9355e5b6fdSKuninori Morimoto 9442ee5d22SKuninori Morimoto if (!rsnd_is_accessible_reg(priv, gen, reg)) 9542ee5d22SKuninori Morimoto return 0; 9642ee5d22SKuninori Morimoto 9755e5b6fdSKuninori Morimoto regmap_fields_read(gen->regs[reg], rsnd_mod_id(mod), &val); 9855e5b6fdSKuninori Morimoto 9955e5b6fdSKuninori Morimoto return val; 10055e5b6fdSKuninori Morimoto } 10155e5b6fdSKuninori Morimoto 10255e5b6fdSKuninori Morimoto void rsnd_write(struct rsnd_priv *priv, 10355e5b6fdSKuninori Morimoto struct rsnd_mod *mod, 10455e5b6fdSKuninori Morimoto enum rsnd_reg reg, u32 data) 10555e5b6fdSKuninori Morimoto { 10655e5b6fdSKuninori Morimoto struct rsnd_gen *gen = rsnd_priv_to_gen(priv); 10755e5b6fdSKuninori Morimoto 10842ee5d22SKuninori Morimoto if (!rsnd_is_accessible_reg(priv, gen, reg)) 10942ee5d22SKuninori Morimoto return; 11042ee5d22SKuninori Morimoto 11155e5b6fdSKuninori Morimoto regmap_fields_write(gen->regs[reg], rsnd_mod_id(mod), data); 11255e5b6fdSKuninori Morimoto } 11355e5b6fdSKuninori Morimoto 11455e5b6fdSKuninori Morimoto void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, 11555e5b6fdSKuninori Morimoto enum rsnd_reg reg, u32 mask, u32 data) 11655e5b6fdSKuninori Morimoto { 11755e5b6fdSKuninori Morimoto struct rsnd_gen *gen = rsnd_priv_to_gen(priv); 11855e5b6fdSKuninori Morimoto 11942ee5d22SKuninori Morimoto if (!rsnd_is_accessible_reg(priv, gen, reg)) 12042ee5d22SKuninori Morimoto return; 12142ee5d22SKuninori Morimoto 12255e5b6fdSKuninori Morimoto regmap_fields_update_bits(gen->regs[reg], rsnd_mod_id(mod), 12355e5b6fdSKuninori Morimoto mask, data); 12455e5b6fdSKuninori Morimoto } 12555e5b6fdSKuninori Morimoto 126c1e6cc5eSKuninori Morimoto static int rsnd_gen_regmap_init(struct rsnd_priv *priv, 127c1e6cc5eSKuninori Morimoto struct rsnd_gen *gen, 128c1e6cc5eSKuninori Morimoto struct reg_field *regf) 129c1e6cc5eSKuninori Morimoto { 130c1e6cc5eSKuninori Morimoto int i; 131c1e6cc5eSKuninori Morimoto struct device *dev = rsnd_priv_to_dev(priv); 132c1e6cc5eSKuninori Morimoto struct regmap_config regc; 133c1e6cc5eSKuninori Morimoto 134c1e6cc5eSKuninori Morimoto memset(®c, 0, sizeof(regc)); 135c1e6cc5eSKuninori Morimoto regc.reg_bits = 32; 136c1e6cc5eSKuninori Morimoto regc.val_bits = 32; 137c1e6cc5eSKuninori Morimoto 138c1e6cc5eSKuninori Morimoto gen->regmap = devm_regmap_init(dev, &rsnd_regmap_bus, priv, ®c); 139c1e6cc5eSKuninori Morimoto if (IS_ERR(gen->regmap)) { 140c1e6cc5eSKuninori Morimoto dev_err(dev, "regmap error %ld\n", PTR_ERR(gen->regmap)); 141c1e6cc5eSKuninori Morimoto return PTR_ERR(gen->regmap); 142c1e6cc5eSKuninori Morimoto } 143c1e6cc5eSKuninori Morimoto 144c1e6cc5eSKuninori Morimoto for (i = 0; i < RSND_REG_MAX; i++) { 14542ee5d22SKuninori Morimoto gen->regs[i] = NULL; 14642ee5d22SKuninori Morimoto if (!regf[i].reg) 14742ee5d22SKuninori Morimoto continue; 14842ee5d22SKuninori Morimoto 149c1e6cc5eSKuninori Morimoto gen->regs[i] = devm_regmap_field_alloc(dev, gen->regmap, regf[i]); 150c1e6cc5eSKuninori Morimoto if (IS_ERR(gen->regs[i])) 151c1e6cc5eSKuninori Morimoto return PTR_ERR(gen->regs[i]); 152c1e6cc5eSKuninori Morimoto 153c1e6cc5eSKuninori Morimoto } 154c1e6cc5eSKuninori Morimoto 155c1e6cc5eSKuninori Morimoto return 0; 156c1e6cc5eSKuninori Morimoto } 1573337744aSKuninori Morimoto 158994a9df1SKuninori Morimoto int rsnd_gen_path_init(struct rsnd_priv *priv, 15907539c1dSKuninori Morimoto struct rsnd_dai *rdai, 16007539c1dSKuninori Morimoto struct rsnd_dai_stream *io) 16107539c1dSKuninori Morimoto { 16207539c1dSKuninori Morimoto struct rsnd_mod *mod; 16307539c1dSKuninori Morimoto int ret; 16407539c1dSKuninori Morimoto int id; 16507539c1dSKuninori Morimoto 16607539c1dSKuninori Morimoto /* 16707539c1dSKuninori Morimoto * Gen1 is created by SRU/SSI, and this SRU is base module of 16807539c1dSKuninori Morimoto * Gen2's SCU/SSIU/SSI. (Gen2 SCU/SSIU came from SRU) 16907539c1dSKuninori Morimoto * 17007539c1dSKuninori Morimoto * Easy image is.. 17107539c1dSKuninori Morimoto * Gen1 SRU = Gen2 SCU + SSIU + etc 17207539c1dSKuninori Morimoto * 17307539c1dSKuninori Morimoto * Gen2 SCU path is very flexible, but, Gen1 SRU (SCU parts) is 17407539c1dSKuninori Morimoto * using fixed path. 17507539c1dSKuninori Morimoto * 17607539c1dSKuninori Morimoto * Then, SSI id = SCU id here 17707539c1dSKuninori Morimoto */ 17807539c1dSKuninori Morimoto 1794b4dab82SKuninori Morimoto /* get SSI's ID */ 1804b4dab82SKuninori Morimoto mod = rsnd_ssi_mod_get_frm_dai(priv, 1814b4dab82SKuninori Morimoto rsnd_dai_id(priv, rdai), 1824b4dab82SKuninori Morimoto rsnd_dai_is_play(rdai, io)); 1834b4dab82SKuninori Morimoto id = rsnd_mod_id(mod); 18407539c1dSKuninori Morimoto 185be213ac1SKuninori Morimoto /* SCU */ 186be213ac1SKuninori Morimoto mod = rsnd_scu_mod_get(priv, id); 187ae5c3223SKuninori Morimoto ret = rsnd_dai_connect(rdai, mod, io); 188ae5c3223SKuninori Morimoto if (ret < 0) 189ae5c3223SKuninori Morimoto return ret; 190ae5c3223SKuninori Morimoto 191be213ac1SKuninori Morimoto /* SSI */ 192be213ac1SKuninori Morimoto mod = rsnd_ssi_mod_get(priv, id); 19307539c1dSKuninori Morimoto ret = rsnd_dai_connect(rdai, mod, io); 19407539c1dSKuninori Morimoto 19507539c1dSKuninori Morimoto return ret; 19607539c1dSKuninori Morimoto } 19707539c1dSKuninori Morimoto 198994a9df1SKuninori Morimoto int rsnd_gen_path_exit(struct rsnd_priv *priv, 19907539c1dSKuninori Morimoto struct rsnd_dai *rdai, 20007539c1dSKuninori Morimoto struct rsnd_dai_stream *io) 20107539c1dSKuninori Morimoto { 20207539c1dSKuninori Morimoto struct rsnd_mod *mod, *n; 20307539c1dSKuninori Morimoto int ret = 0; 20407539c1dSKuninori Morimoto 20507539c1dSKuninori Morimoto /* 20607539c1dSKuninori Morimoto * remove all mod from rdai 20707539c1dSKuninori Morimoto */ 20807539c1dSKuninori Morimoto for_each_rsnd_mod(mod, n, io) 20907539c1dSKuninori Morimoto ret |= rsnd_dai_disconnect(mod); 21007539c1dSKuninori Morimoto 21107539c1dSKuninori Morimoto return ret; 21207539c1dSKuninori Morimoto } 21307539c1dSKuninori Morimoto 214994a9df1SKuninori Morimoto /* 215994a9df1SKuninori Morimoto * Gen2 216994a9df1SKuninori Morimoto */ 217994a9df1SKuninori Morimoto 218507d466cSKuninori Morimoto /* single address mapping */ 219507d466cSKuninori Morimoto #define RSND_GEN2_S_REG(gen, reg, id, offset) \ 2201a1c75a7SKuninori Morimoto RSND_REG_SET(gen, RSND_REG_##id, RSND_GEN2_##reg, offset, 0, 10) 221507d466cSKuninori Morimoto 222507d466cSKuninori Morimoto /* multi address mapping */ 223507d466cSKuninori Morimoto #define RSND_GEN2_M_REG(gen, reg, id, offset, _id_offset) \ 2241a1c75a7SKuninori Morimoto RSND_REG_SET(gen, RSND_REG_##id, RSND_GEN2_##reg, offset, _id_offset, 10) 225507d466cSKuninori Morimoto 226507d466cSKuninori Morimoto static int rsnd_gen2_regmap_init(struct rsnd_priv *priv, struct rsnd_gen *gen) 227507d466cSKuninori Morimoto { 228507d466cSKuninori Morimoto struct reg_field regf[RSND_REG_MAX] = { 229507d466cSKuninori Morimoto RSND_GEN2_S_REG(gen, SSIU, SSI_MODE0, 0x800), 230507d466cSKuninori Morimoto RSND_GEN2_S_REG(gen, SSIU, SSI_MODE1, 0x804), 231507d466cSKuninori Morimoto /* FIXME: it needs SSI_MODE2/3 in the future */ 232629509c5SKuninori Morimoto RSND_GEN2_S_REG(gen, SSIU, SSI_CONTROL, 0x810), 233629509c5SKuninori Morimoto RSND_GEN2_M_REG(gen, SSIU, SSI_BUSIF_MODE, 0x0, 0x80), 234629509c5SKuninori Morimoto RSND_GEN2_M_REG(gen, SSIU, SSI_BUSIF_ADINR,0x4, 0x80), 235629509c5SKuninori Morimoto RSND_GEN2_M_REG(gen, SSIU, SSI_CTRL, 0x10, 0x80), 236507d466cSKuninori Morimoto RSND_GEN2_M_REG(gen, SSIU, INT_ENABLE, 0x18, 0x80), 237507d466cSKuninori Morimoto 238629509c5SKuninori Morimoto RSND_GEN2_M_REG(gen, SCU, SRC_BUSIF_MODE, 0x0, 0x20), 239629509c5SKuninori Morimoto RSND_GEN2_M_REG(gen, SCU, SRC_ROUTE_MODE0,0xc, 0x20), 240629509c5SKuninori Morimoto RSND_GEN2_M_REG(gen, SCU, SRC_CTRL, 0x10, 0x20), 241629509c5SKuninori Morimoto RSND_GEN2_M_REG(gen, SCU, SRC_SWRSR, 0x200, 0x40), 242629509c5SKuninori Morimoto RSND_GEN2_M_REG(gen, SCU, SRC_SRCIR, 0x204, 0x40), 243629509c5SKuninori Morimoto RSND_GEN2_M_REG(gen, SCU, SRC_ADINR, 0x214, 0x40), 244629509c5SKuninori Morimoto RSND_GEN2_M_REG(gen, SCU, SRC_IFSCR, 0x21c, 0x40), 245629509c5SKuninori Morimoto RSND_GEN2_M_REG(gen, SCU, SRC_IFSVR, 0x220, 0x40), 246629509c5SKuninori Morimoto RSND_GEN2_M_REG(gen, SCU, SRC_SRCCR, 0x224, 0x40), 247629509c5SKuninori Morimoto RSND_GEN2_M_REG(gen, SCU, SRC_BSDSR, 0x22c, 0x40), 248629509c5SKuninori Morimoto RSND_GEN2_M_REG(gen, SCU, SRC_BSISR, 0x238, 0x40), 249629509c5SKuninori Morimoto 250507d466cSKuninori Morimoto RSND_GEN2_S_REG(gen, ADG, BRRA, 0x00), 251507d466cSKuninori Morimoto RSND_GEN2_S_REG(gen, ADG, BRRB, 0x04), 252507d466cSKuninori Morimoto RSND_GEN2_S_REG(gen, ADG, SSICKR, 0x08), 253507d466cSKuninori Morimoto RSND_GEN2_S_REG(gen, ADG, AUDIO_CLK_SEL0, 0x0c), 254507d466cSKuninori Morimoto RSND_GEN2_S_REG(gen, ADG, AUDIO_CLK_SEL1, 0x10), 255507d466cSKuninori Morimoto RSND_GEN2_S_REG(gen, ADG, AUDIO_CLK_SEL2, 0x14), 256ee2c828dSKuninori Morimoto RSND_GEN2_S_REG(gen, ADG, DIV_EN, 0x30), 257629509c5SKuninori Morimoto RSND_GEN2_S_REG(gen, ADG, SRCIN_TIMSEL0, 0x34), 258629509c5SKuninori Morimoto RSND_GEN2_S_REG(gen, ADG, SRCIN_TIMSEL1, 0x38), 259629509c5SKuninori Morimoto RSND_GEN2_S_REG(gen, ADG, SRCIN_TIMSEL2, 0x3c), 260629509c5SKuninori Morimoto RSND_GEN2_S_REG(gen, ADG, SRCIN_TIMSEL3, 0x40), 261629509c5SKuninori Morimoto RSND_GEN2_S_REG(gen, ADG, SRCIN_TIMSEL4, 0x44), 262629509c5SKuninori Morimoto RSND_GEN2_S_REG(gen, ADG, SRCOUT_TIMSEL0, 0x48), 263629509c5SKuninori Morimoto RSND_GEN2_S_REG(gen, ADG, SRCOUT_TIMSEL1, 0x4c), 264629509c5SKuninori Morimoto RSND_GEN2_S_REG(gen, ADG, SRCOUT_TIMSEL2, 0x50), 265629509c5SKuninori Morimoto RSND_GEN2_S_REG(gen, ADG, SRCOUT_TIMSEL3, 0x54), 266629509c5SKuninori Morimoto RSND_GEN2_S_REG(gen, ADG, SRCOUT_TIMSEL4, 0x58), 267507d466cSKuninori Morimoto 268507d466cSKuninori Morimoto RSND_GEN2_M_REG(gen, SSI, SSICR, 0x00, 0x40), 269507d466cSKuninori Morimoto RSND_GEN2_M_REG(gen, SSI, SSISR, 0x04, 0x40), 270507d466cSKuninori Morimoto RSND_GEN2_M_REG(gen, SSI, SSITDR, 0x08, 0x40), 271507d466cSKuninori Morimoto RSND_GEN2_M_REG(gen, SSI, SSIRDR, 0x0c, 0x40), 272507d466cSKuninori Morimoto RSND_GEN2_M_REG(gen, SSI, SSIWSR, 0x20, 0x40), 273507d466cSKuninori Morimoto }; 274507d466cSKuninori Morimoto 275507d466cSKuninori Morimoto return rsnd_gen_regmap_init(priv, gen, regf); 276507d466cSKuninori Morimoto } 277507d466cSKuninori Morimoto 278507d466cSKuninori Morimoto static int rsnd_gen2_probe(struct platform_device *pdev, 279507d466cSKuninori Morimoto struct rsnd_priv *priv) 280507d466cSKuninori Morimoto { 281507d466cSKuninori Morimoto struct device *dev = rsnd_priv_to_dev(priv); 282507d466cSKuninori Morimoto struct rsnd_gen *gen = rsnd_priv_to_gen(priv); 283507d466cSKuninori Morimoto struct resource *scu_res; 284507d466cSKuninori Morimoto struct resource *adg_res; 285507d466cSKuninori Morimoto struct resource *ssiu_res; 286507d466cSKuninori Morimoto struct resource *ssi_res; 287507d466cSKuninori Morimoto int ret; 288507d466cSKuninori Morimoto 289507d466cSKuninori Morimoto /* 290507d466cSKuninori Morimoto * map address 291507d466cSKuninori Morimoto */ 292507d466cSKuninori Morimoto scu_res = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN2_SCU); 293507d466cSKuninori Morimoto adg_res = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN2_ADG); 294507d466cSKuninori Morimoto ssiu_res = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN2_SSIU); 295507d466cSKuninori Morimoto ssi_res = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN2_SSI); 296507d466cSKuninori Morimoto 297507d466cSKuninori Morimoto gen->base[RSND_GEN2_SCU] = devm_ioremap_resource(dev, scu_res); 298507d466cSKuninori Morimoto gen->base[RSND_GEN2_ADG] = devm_ioremap_resource(dev, adg_res); 299507d466cSKuninori Morimoto gen->base[RSND_GEN2_SSIU] = devm_ioremap_resource(dev, ssiu_res); 300507d466cSKuninori Morimoto gen->base[RSND_GEN2_SSI] = devm_ioremap_resource(dev, ssi_res); 301507d466cSKuninori Morimoto if (IS_ERR(gen->base[RSND_GEN2_SCU]) || 302507d466cSKuninori Morimoto IS_ERR(gen->base[RSND_GEN2_ADG]) || 303507d466cSKuninori Morimoto IS_ERR(gen->base[RSND_GEN2_SSIU]) || 304507d466cSKuninori Morimoto IS_ERR(gen->base[RSND_GEN2_SSI])) 305507d466cSKuninori Morimoto return -ENODEV; 306507d466cSKuninori Morimoto 307507d466cSKuninori Morimoto ret = rsnd_gen2_regmap_init(priv, gen); 308507d466cSKuninori Morimoto if (ret < 0) 309507d466cSKuninori Morimoto return ret; 310507d466cSKuninori Morimoto 311507d466cSKuninori Morimoto dev_dbg(dev, "Gen2 device probed\n"); 31264de62b3SKuninori Morimoto dev_dbg(dev, "SCU : %08x => %p\n", scu_res->start, 313507d466cSKuninori Morimoto gen->base[RSND_GEN2_SCU]); 314507d466cSKuninori Morimoto dev_dbg(dev, "ADG : %08x => %p\n", adg_res->start, 315507d466cSKuninori Morimoto gen->base[RSND_GEN2_ADG]); 316507d466cSKuninori Morimoto dev_dbg(dev, "SSIU : %08x => %p\n", ssiu_res->start, 317507d466cSKuninori Morimoto gen->base[RSND_GEN2_SSIU]); 318507d466cSKuninori Morimoto dev_dbg(dev, "SSI : %08x => %p\n", ssi_res->start, 319507d466cSKuninori Morimoto gen->base[RSND_GEN2_SSI]); 320507d466cSKuninori Morimoto 321507d466cSKuninori Morimoto return 0; 322507d466cSKuninori Morimoto } 323507d466cSKuninori Morimoto 324994a9df1SKuninori Morimoto /* 325994a9df1SKuninori Morimoto * Gen1 326994a9df1SKuninori Morimoto */ 327994a9df1SKuninori Morimoto 32855e5b6fdSKuninori Morimoto /* single address mapping */ 32955e5b6fdSKuninori Morimoto #define RSND_GEN1_S_REG(gen, reg, id, offset) \ 33055e5b6fdSKuninori Morimoto RSND_REG_SET(gen, RSND_REG_##id, RSND_GEN1_##reg, offset, 0, 9) 33107539c1dSKuninori Morimoto 33255e5b6fdSKuninori Morimoto /* multi address mapping */ 33355e5b6fdSKuninori Morimoto #define RSND_GEN1_M_REG(gen, reg, id, offset, _id_offset) \ 33455e5b6fdSKuninori Morimoto RSND_REG_SET(gen, RSND_REG_##id, RSND_GEN1_##reg, offset, _id_offset, 9) 33555e5b6fdSKuninori Morimoto 33655e5b6fdSKuninori Morimoto static int rsnd_gen1_regmap_init(struct rsnd_priv *priv, struct rsnd_gen *gen) 33707539c1dSKuninori Morimoto { 33855e5b6fdSKuninori Morimoto struct reg_field regf[RSND_REG_MAX] = { 33955e5b6fdSKuninori Morimoto RSND_GEN1_S_REG(gen, SRU, SRC_ROUTE_SEL, 0x00), 34055e5b6fdSKuninori Morimoto RSND_GEN1_S_REG(gen, SRU, SRC_TMG_SEL0, 0x08), 34155e5b6fdSKuninori Morimoto RSND_GEN1_S_REG(gen, SRU, SRC_TMG_SEL1, 0x0c), 34255e5b6fdSKuninori Morimoto RSND_GEN1_S_REG(gen, SRU, SRC_TMG_SEL2, 0x10), 343690ef81eSKuninori Morimoto RSND_GEN1_S_REG(gen, SRU, SRC_ROUTE_CTRL, 0xc0), 34455e5b6fdSKuninori Morimoto RSND_GEN1_S_REG(gen, SRU, SSI_MODE0, 0xD0), 34555e5b6fdSKuninori Morimoto RSND_GEN1_S_REG(gen, SRU, SSI_MODE1, 0xD4), 3460290d2a4SKuninori Morimoto RSND_GEN1_M_REG(gen, SRU, SRC_BUSIF_MODE, 0x20, 0x4), 347ef749400SKuninori Morimoto RSND_GEN1_M_REG(gen, SRU, SRC_ROUTE_MODE0,0x50, 0x8), 348ef749400SKuninori Morimoto RSND_GEN1_M_REG(gen, SRU, SRC_SWRSR, 0x200, 0x40), 349ef749400SKuninori Morimoto RSND_GEN1_M_REG(gen, SRU, SRC_SRCIR, 0x204, 0x40), 350690ef81eSKuninori Morimoto RSND_GEN1_M_REG(gen, SRU, SRC_ADINR, 0x214, 0x40), 351ef749400SKuninori Morimoto RSND_GEN1_M_REG(gen, SRU, SRC_IFSCR, 0x21c, 0x40), 352ef749400SKuninori Morimoto RSND_GEN1_M_REG(gen, SRU, SRC_IFSVR, 0x220, 0x40), 353ef749400SKuninori Morimoto RSND_GEN1_M_REG(gen, SRU, SRC_SRCCR, 0x224, 0x40), 354ef749400SKuninori Morimoto RSND_GEN1_M_REG(gen, SRU, SRC_MNFSR, 0x228, 0x40), 355dfc9403bSKuninori Morimoto 35655e5b6fdSKuninori Morimoto RSND_GEN1_S_REG(gen, ADG, BRRA, 0x00), 35755e5b6fdSKuninori Morimoto RSND_GEN1_S_REG(gen, ADG, BRRB, 0x04), 35855e5b6fdSKuninori Morimoto RSND_GEN1_S_REG(gen, ADG, SSICKR, 0x08), 35955e5b6fdSKuninori Morimoto RSND_GEN1_S_REG(gen, ADG, AUDIO_CLK_SEL0, 0x0c), 36055e5b6fdSKuninori Morimoto RSND_GEN1_S_REG(gen, ADG, AUDIO_CLK_SEL1, 0x10), 361ef749400SKuninori Morimoto RSND_GEN1_S_REG(gen, ADG, AUDIO_CLK_SEL3, 0x18), 362ef749400SKuninori Morimoto RSND_GEN1_S_REG(gen, ADG, AUDIO_CLK_SEL4, 0x1c), 363ef749400SKuninori Morimoto RSND_GEN1_S_REG(gen, ADG, AUDIO_CLK_SEL5, 0x20), 364ae5c3223SKuninori Morimoto 36555e5b6fdSKuninori Morimoto RSND_GEN1_M_REG(gen, SSI, SSICR, 0x00, 0x40), 36655e5b6fdSKuninori Morimoto RSND_GEN1_M_REG(gen, SSI, SSISR, 0x04, 0x40), 36755e5b6fdSKuninori Morimoto RSND_GEN1_M_REG(gen, SSI, SSITDR, 0x08, 0x40), 36855e5b6fdSKuninori Morimoto RSND_GEN1_M_REG(gen, SSI, SSIRDR, 0x0c, 0x40), 36955e5b6fdSKuninori Morimoto RSND_GEN1_M_REG(gen, SSI, SSIWSR, 0x20, 0x40), 37055e5b6fdSKuninori Morimoto }; 37155e5b6fdSKuninori Morimoto 372c1e6cc5eSKuninori Morimoto return rsnd_gen_regmap_init(priv, gen, regf); 37307539c1dSKuninori Morimoto } 37407539c1dSKuninori Morimoto 3753337744aSKuninori Morimoto static int rsnd_gen1_probe(struct platform_device *pdev, 3763337744aSKuninori Morimoto struct rsnd_priv *priv) 3773337744aSKuninori Morimoto { 37807539c1dSKuninori Morimoto struct device *dev = rsnd_priv_to_dev(priv); 37907539c1dSKuninori Morimoto struct rsnd_gen *gen = rsnd_priv_to_gen(priv); 38007539c1dSKuninori Morimoto struct resource *sru_res; 381dfc9403bSKuninori Morimoto struct resource *adg_res; 382ae5c3223SKuninori Morimoto struct resource *ssi_res; 38355e5b6fdSKuninori Morimoto int ret; 38407539c1dSKuninori Morimoto 38507539c1dSKuninori Morimoto /* 38607539c1dSKuninori Morimoto * map address 38707539c1dSKuninori Morimoto */ 38807539c1dSKuninori Morimoto sru_res = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN1_SRU); 389dfc9403bSKuninori Morimoto adg_res = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN1_ADG); 390ae5c3223SKuninori Morimoto ssi_res = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN1_SSI); 39107539c1dSKuninori Morimoto 39207539c1dSKuninori Morimoto gen->base[RSND_GEN1_SRU] = devm_ioremap_resource(dev, sru_res); 393dfc9403bSKuninori Morimoto gen->base[RSND_GEN1_ADG] = devm_ioremap_resource(dev, adg_res); 394ae5c3223SKuninori Morimoto gen->base[RSND_GEN1_SSI] = devm_ioremap_resource(dev, ssi_res); 39570263cb4SWei Yongjun if (IS_ERR(gen->base[RSND_GEN1_SRU]) || 39670263cb4SWei Yongjun IS_ERR(gen->base[RSND_GEN1_ADG]) || 39770263cb4SWei Yongjun IS_ERR(gen->base[RSND_GEN1_SSI])) 39807539c1dSKuninori Morimoto return -ENODEV; 39907539c1dSKuninori Morimoto 40055e5b6fdSKuninori Morimoto ret = rsnd_gen1_regmap_init(priv, gen); 40155e5b6fdSKuninori Morimoto if (ret < 0) 40255e5b6fdSKuninori Morimoto return ret; 40307539c1dSKuninori Morimoto 40407539c1dSKuninori Morimoto dev_dbg(dev, "Gen1 device probed\n"); 40507539c1dSKuninori Morimoto dev_dbg(dev, "SRU : %08x => %p\n", sru_res->start, 40607539c1dSKuninori Morimoto gen->base[RSND_GEN1_SRU]); 407dfc9403bSKuninori Morimoto dev_dbg(dev, "ADG : %08x => %p\n", adg_res->start, 408dfc9403bSKuninori Morimoto gen->base[RSND_GEN1_ADG]); 409ae5c3223SKuninori Morimoto dev_dbg(dev, "SSI : %08x => %p\n", ssi_res->start, 410ae5c3223SKuninori Morimoto gen->base[RSND_GEN1_SSI]); 41107539c1dSKuninori Morimoto 4123337744aSKuninori Morimoto return 0; 413ae5c3223SKuninori Morimoto 4143337744aSKuninori Morimoto } 4153337744aSKuninori Morimoto 4163337744aSKuninori Morimoto /* 4173337744aSKuninori Morimoto * Gen 4183337744aSKuninori Morimoto */ 4193337744aSKuninori Morimoto int rsnd_gen_probe(struct platform_device *pdev, 4203337744aSKuninori Morimoto struct rsnd_priv *priv) 4213337744aSKuninori Morimoto { 4223337744aSKuninori Morimoto struct device *dev = rsnd_priv_to_dev(priv); 4233337744aSKuninori Morimoto struct rsnd_gen *gen; 424531eaf49SKuninori Morimoto int ret; 4253337744aSKuninori Morimoto 4263337744aSKuninori Morimoto gen = devm_kzalloc(dev, sizeof(*gen), GFP_KERNEL); 4273337744aSKuninori Morimoto if (!gen) { 4283337744aSKuninori Morimoto dev_err(dev, "GEN allocate failed\n"); 4293337744aSKuninori Morimoto return -ENOMEM; 4303337744aSKuninori Morimoto } 4313337744aSKuninori Morimoto 432531eaf49SKuninori Morimoto priv->gen = gen; 433072188b6SKuninori Morimoto 434507d466cSKuninori Morimoto ret = -ENODEV; 435507d466cSKuninori Morimoto if (rsnd_is_gen1(priv)) 4365da39cf3SKuninori Morimoto ret = rsnd_gen1_probe(pdev, priv); 437507d466cSKuninori Morimoto else if (rsnd_is_gen2(priv)) 4385da39cf3SKuninori Morimoto ret = rsnd_gen2_probe(pdev, priv); 439507d466cSKuninori Morimoto 440507d466cSKuninori Morimoto if (ret < 0) 441072188b6SKuninori Morimoto dev_err(dev, "unknown generation R-Car sound device\n"); 442072188b6SKuninori Morimoto 443531eaf49SKuninori Morimoto return ret; 4443337744aSKuninori Morimoto } 4453337744aSKuninori Morimoto 4463337744aSKuninori Morimoto void rsnd_gen_remove(struct platform_device *pdev, 4473337744aSKuninori Morimoto struct rsnd_priv *priv) 4483337744aSKuninori Morimoto { 4493337744aSKuninori Morimoto } 450