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 /* 159ad32d0c7SKuninori Morimoto * DMA read/write register offset 160ad32d0c7SKuninori Morimoto * 161ad32d0c7SKuninori Morimoto * RSND_xxx_I_N for Audio DMAC input 162ad32d0c7SKuninori Morimoto * RSND_xxx_O_N for Audio DMAC output 163ad32d0c7SKuninori Morimoto * RSND_xxx_I_P for Audio DMAC peri peri input 164ad32d0c7SKuninori Morimoto * RSND_xxx_O_P for Audio DMAC peri peri output 165ad32d0c7SKuninori Morimoto * 166ad32d0c7SKuninori Morimoto * ex) R-Car H2 case 167ad32d0c7SKuninori Morimoto * mod / DMAC in / DMAC out / DMAC PP in / DMAC pp out 168ad32d0c7SKuninori Morimoto * SSI : 0xec541000 / 0xec241008 / 0xec24100c / 0xec400000 / 0xec400000 169ad32d0c7SKuninori Morimoto * SCU : 0xec500000 / 0xec000000 / 0xec004000 / 0xec300000 / 0xec304000 170ad32d0c7SKuninori Morimoto * CMD : 0xec500000 / 0xec008000 0xec308000 171ad32d0c7SKuninori Morimoto */ 172ad32d0c7SKuninori Morimoto #define RDMA_SSI_I_N(addr, i) (addr ##_reg - 0x00300000 + (0x40 * i) + 0x8) 173ad32d0c7SKuninori Morimoto #define RDMA_SSI_O_N(addr, i) (addr ##_reg - 0x00300000 + (0x40 * i) + 0xc) 174ad32d0c7SKuninori Morimoto 175ad32d0c7SKuninori Morimoto #define RDMA_SSI_I_P(addr, i) (addr ##_reg - 0x00141000 + (0x1000 * i)) 176ad32d0c7SKuninori Morimoto #define RDMA_SSI_O_P(addr, i) (addr ##_reg - 0x00141000 + (0x1000 * i)) 177ad32d0c7SKuninori Morimoto 178ad32d0c7SKuninori Morimoto #define RDMA_SRC_I_N(addr, i) (addr ##_reg - 0x00500000 + (0x400 * i)) 179ad32d0c7SKuninori Morimoto #define RDMA_SRC_O_N(addr, i) (addr ##_reg - 0x004fc000 + (0x400 * i)) 180ad32d0c7SKuninori Morimoto 181ad32d0c7SKuninori Morimoto #define RDMA_SRC_I_P(addr, i) (addr ##_reg - 0x00200000 + (0x400 * i)) 182ad32d0c7SKuninori Morimoto #define RDMA_SRC_O_P(addr, i) (addr ##_reg - 0x001fc000 + (0x400 * i)) 183ad32d0c7SKuninori Morimoto 184ad32d0c7SKuninori Morimoto #define RDMA_CMD_O_N(addr, i) (addr ##_reg - 0x004f8000 + (0x400 * i)) 185ad32d0c7SKuninori Morimoto #define RDMA_CMD_O_P(addr, i) (addr ##_reg - 0x001f8000 + (0x400 * i)) 186ad32d0c7SKuninori Morimoto 187ad32d0c7SKuninori Morimoto void rsnd_gen_dma_addr(struct rsnd_priv *priv, 188ad32d0c7SKuninori Morimoto struct rsnd_dma *dma, 189ad32d0c7SKuninori Morimoto struct dma_slave_config *cfg, 190ad32d0c7SKuninori Morimoto int is_play, int slave_id) 191ad32d0c7SKuninori Morimoto { 192ad32d0c7SKuninori Morimoto struct platform_device *pdev = rsnd_priv_to_pdev(priv); 193ad32d0c7SKuninori Morimoto struct device *dev = rsnd_priv_to_dev(priv); 194ad32d0c7SKuninori Morimoto struct rsnd_mod *mod = rsnd_dma_to_mod(dma); 195ad32d0c7SKuninori Morimoto struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); 196ad32d0c7SKuninori Morimoto dma_addr_t ssi_reg = platform_get_resource(pdev, 197ad32d0c7SKuninori Morimoto IORESOURCE_MEM, RSND_GEN2_SSI)->start; 198ad32d0c7SKuninori Morimoto dma_addr_t src_reg = platform_get_resource(pdev, 199ad32d0c7SKuninori Morimoto IORESOURCE_MEM, RSND_GEN2_SCU)->start; 200ad32d0c7SKuninori Morimoto int is_ssi = !!(rsnd_io_to_mod_ssi(io) == mod); 201ad32d0c7SKuninori Morimoto int use_src = !!rsnd_io_to_mod_src(io); 202ad32d0c7SKuninori Morimoto int use_dvc = !!rsnd_io_to_mod_dvc(io); 203ad32d0c7SKuninori Morimoto int id = rsnd_mod_id(mod); 204ad32d0c7SKuninori Morimoto struct dma_addr { 205ad32d0c7SKuninori Morimoto dma_addr_t src_addr; 206ad32d0c7SKuninori Morimoto dma_addr_t dst_addr; 207ad32d0c7SKuninori Morimoto } dma_addrs[2][2][3] = { 208ad32d0c7SKuninori Morimoto { /* SRC */ 209ad32d0c7SKuninori Morimoto /* Capture */ 210ad32d0c7SKuninori Morimoto {{ 0, 0 }, 211ad32d0c7SKuninori Morimoto { RDMA_SRC_O_N(src, id), 0 }, 212ad32d0c7SKuninori Morimoto { RDMA_CMD_O_N(src, id), 0 }}, 213ad32d0c7SKuninori Morimoto /* Playback */ 214ad32d0c7SKuninori Morimoto {{ 0, 0, }, 215ad32d0c7SKuninori Morimoto { 0, RDMA_SRC_I_N(src, id) }, 216ad32d0c7SKuninori Morimoto { 0, RDMA_SRC_I_N(src, id) }} 217ad32d0c7SKuninori Morimoto }, { /* SSI */ 218ad32d0c7SKuninori Morimoto /* Capture */ 219ad32d0c7SKuninori Morimoto {{ RDMA_SSI_O_N(ssi, id), 0 }, 220ad32d0c7SKuninori Morimoto { RDMA_SSI_O_P(ssi, id), RDMA_SRC_I_P(src, id) }, 221ad32d0c7SKuninori Morimoto { RDMA_SSI_O_P(ssi, id), RDMA_SRC_I_P(src, id) }}, 222ad32d0c7SKuninori Morimoto /* Playback */ 223ad32d0c7SKuninori Morimoto {{ 0, RDMA_SSI_I_N(ssi, id) }, 224ad32d0c7SKuninori Morimoto { RDMA_SRC_O_P(src, id), RDMA_SSI_I_P(ssi, id) }, 225ad32d0c7SKuninori Morimoto { RDMA_CMD_O_P(src, id), RDMA_SSI_I_P(ssi, id) }} 226ad32d0c7SKuninori Morimoto } 227ad32d0c7SKuninori Morimoto }; 228ad32d0c7SKuninori Morimoto 229ad32d0c7SKuninori Morimoto cfg->slave_id = slave_id; 230ad32d0c7SKuninori Morimoto cfg->src_addr = 0; 231ad32d0c7SKuninori Morimoto cfg->dst_addr = 0; 232ad32d0c7SKuninori Morimoto cfg->direction = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM; 233ad32d0c7SKuninori Morimoto 234ad32d0c7SKuninori Morimoto /* 235ad32d0c7SKuninori Morimoto * gen1 uses default DMA addr 236ad32d0c7SKuninori Morimoto */ 237ad32d0c7SKuninori Morimoto if (rsnd_is_gen1(priv)) 238ad32d0c7SKuninori Morimoto return; 239ad32d0c7SKuninori Morimoto 240ad32d0c7SKuninori Morimoto /* it shouldn't happen */ 241ad32d0c7SKuninori Morimoto if (use_dvc & !use_src) { 242ad32d0c7SKuninori Morimoto dev_err(dev, "DVC is selected without SRC\n"); 243ad32d0c7SKuninori Morimoto return; 244ad32d0c7SKuninori Morimoto } 245ad32d0c7SKuninori Morimoto 246ad32d0c7SKuninori Morimoto cfg->src_addr = dma_addrs[is_ssi][is_play][use_src + use_dvc].src_addr; 247ad32d0c7SKuninori Morimoto cfg->dst_addr = dma_addrs[is_ssi][is_play][use_src + use_dvc].dst_addr; 248ad32d0c7SKuninori Morimoto 249ad32d0c7SKuninori Morimoto dev_dbg(dev, "dma%d addr - src : %x / dst : %x\n", 250ad32d0c7SKuninori Morimoto id, cfg->src_addr, cfg->dst_addr); 251ad32d0c7SKuninori Morimoto } 252ad32d0c7SKuninori Morimoto 253ad32d0c7SKuninori Morimoto /* 254994a9df1SKuninori Morimoto * Gen2 255994a9df1SKuninori Morimoto */ 256994a9df1SKuninori Morimoto 257507d466cSKuninori Morimoto /* single address mapping */ 258507d466cSKuninori Morimoto #define RSND_GEN2_S_REG(gen, reg, id, offset) \ 2591a1c75a7SKuninori Morimoto RSND_REG_SET(gen, RSND_REG_##id, RSND_GEN2_##reg, offset, 0, 10) 260507d466cSKuninori Morimoto 261507d466cSKuninori Morimoto /* multi address mapping */ 262507d466cSKuninori Morimoto #define RSND_GEN2_M_REG(gen, reg, id, offset, _id_offset) \ 2631a1c75a7SKuninori Morimoto RSND_REG_SET(gen, RSND_REG_##id, RSND_GEN2_##reg, offset, _id_offset, 10) 264507d466cSKuninori Morimoto 265507d466cSKuninori Morimoto static int rsnd_gen2_regmap_init(struct rsnd_priv *priv, struct rsnd_gen *gen) 266507d466cSKuninori Morimoto { 267507d466cSKuninori Morimoto struct reg_field regf[RSND_REG_MAX] = { 268507d466cSKuninori Morimoto RSND_GEN2_S_REG(gen, SSIU, SSI_MODE0, 0x800), 269507d466cSKuninori Morimoto RSND_GEN2_S_REG(gen, SSIU, SSI_MODE1, 0x804), 270507d466cSKuninori Morimoto /* FIXME: it needs SSI_MODE2/3 in the future */ 271629509c5SKuninori Morimoto RSND_GEN2_M_REG(gen, SSIU, SSI_BUSIF_MODE, 0x0, 0x80), 272629509c5SKuninori Morimoto RSND_GEN2_M_REG(gen, SSIU, SSI_BUSIF_ADINR,0x4, 0x80), 273629509c5SKuninori Morimoto RSND_GEN2_M_REG(gen, SSIU, SSI_CTRL, 0x10, 0x80), 274507d466cSKuninori Morimoto RSND_GEN2_M_REG(gen, SSIU, INT_ENABLE, 0x18, 0x80), 275507d466cSKuninori Morimoto 276629509c5SKuninori Morimoto RSND_GEN2_M_REG(gen, SCU, SRC_BUSIF_MODE, 0x0, 0x20), 277629509c5SKuninori Morimoto RSND_GEN2_M_REG(gen, SCU, SRC_ROUTE_MODE0,0xc, 0x20), 278629509c5SKuninori Morimoto RSND_GEN2_M_REG(gen, SCU, SRC_CTRL, 0x10, 0x20), 279bff58ea4SKuninori Morimoto RSND_GEN2_M_REG(gen, SCU, CMD_ROUTE_SLCT, 0x18c, 0x20), 280bff58ea4SKuninori Morimoto RSND_GEN2_M_REG(gen, SCU, CMD_CTRL, 0x190, 0x20), 281629509c5SKuninori Morimoto RSND_GEN2_M_REG(gen, SCU, SRC_SWRSR, 0x200, 0x40), 282629509c5SKuninori Morimoto RSND_GEN2_M_REG(gen, SCU, SRC_SRCIR, 0x204, 0x40), 283629509c5SKuninori Morimoto RSND_GEN2_M_REG(gen, SCU, SRC_ADINR, 0x214, 0x40), 284629509c5SKuninori Morimoto RSND_GEN2_M_REG(gen, SCU, SRC_IFSCR, 0x21c, 0x40), 285629509c5SKuninori Morimoto RSND_GEN2_M_REG(gen, SCU, SRC_IFSVR, 0x220, 0x40), 286629509c5SKuninori Morimoto RSND_GEN2_M_REG(gen, SCU, SRC_SRCCR, 0x224, 0x40), 287629509c5SKuninori Morimoto RSND_GEN2_M_REG(gen, SCU, SRC_BSDSR, 0x22c, 0x40), 288629509c5SKuninori Morimoto RSND_GEN2_M_REG(gen, SCU, SRC_BSISR, 0x238, 0x40), 289bff58ea4SKuninori Morimoto RSND_GEN2_M_REG(gen, SCU, DVC_SWRSR, 0xe00, 0x100), 290bff58ea4SKuninori Morimoto RSND_GEN2_M_REG(gen, SCU, DVC_DVUIR, 0xe04, 0x100), 291bff58ea4SKuninori Morimoto RSND_GEN2_M_REG(gen, SCU, DVC_ADINR, 0xe08, 0x100), 292bff58ea4SKuninori Morimoto RSND_GEN2_M_REG(gen, SCU, DVC_DVUCR, 0xe10, 0x100), 293bff58ea4SKuninori Morimoto RSND_GEN2_M_REG(gen, SCU, DVC_ZCMCR, 0xe14, 0x100), 294bff58ea4SKuninori Morimoto RSND_GEN2_M_REG(gen, SCU, DVC_VOL0R, 0xe28, 0x100), 295bff58ea4SKuninori Morimoto RSND_GEN2_M_REG(gen, SCU, DVC_VOL1R, 0xe2c, 0x100), 296bff58ea4SKuninori Morimoto RSND_GEN2_M_REG(gen, SCU, DVC_DVUER, 0xe48, 0x100), 297629509c5SKuninori Morimoto 298507d466cSKuninori Morimoto RSND_GEN2_S_REG(gen, ADG, BRRA, 0x00), 299507d466cSKuninori Morimoto RSND_GEN2_S_REG(gen, ADG, BRRB, 0x04), 300507d466cSKuninori Morimoto RSND_GEN2_S_REG(gen, ADG, SSICKR, 0x08), 301507d466cSKuninori Morimoto RSND_GEN2_S_REG(gen, ADG, AUDIO_CLK_SEL0, 0x0c), 302507d466cSKuninori Morimoto RSND_GEN2_S_REG(gen, ADG, AUDIO_CLK_SEL1, 0x10), 303507d466cSKuninori Morimoto RSND_GEN2_S_REG(gen, ADG, AUDIO_CLK_SEL2, 0x14), 304ee2c828dSKuninori Morimoto RSND_GEN2_S_REG(gen, ADG, DIV_EN, 0x30), 305629509c5SKuninori Morimoto RSND_GEN2_S_REG(gen, ADG, SRCIN_TIMSEL0, 0x34), 306629509c5SKuninori Morimoto RSND_GEN2_S_REG(gen, ADG, SRCIN_TIMSEL1, 0x38), 307629509c5SKuninori Morimoto RSND_GEN2_S_REG(gen, ADG, SRCIN_TIMSEL2, 0x3c), 308629509c5SKuninori Morimoto RSND_GEN2_S_REG(gen, ADG, SRCIN_TIMSEL3, 0x40), 309629509c5SKuninori Morimoto RSND_GEN2_S_REG(gen, ADG, SRCIN_TIMSEL4, 0x44), 310629509c5SKuninori Morimoto RSND_GEN2_S_REG(gen, ADG, SRCOUT_TIMSEL0, 0x48), 311629509c5SKuninori Morimoto RSND_GEN2_S_REG(gen, ADG, SRCOUT_TIMSEL1, 0x4c), 312629509c5SKuninori Morimoto RSND_GEN2_S_REG(gen, ADG, SRCOUT_TIMSEL2, 0x50), 313629509c5SKuninori Morimoto RSND_GEN2_S_REG(gen, ADG, SRCOUT_TIMSEL3, 0x54), 314629509c5SKuninori Morimoto RSND_GEN2_S_REG(gen, ADG, SRCOUT_TIMSEL4, 0x58), 315bff58ea4SKuninori Morimoto RSND_GEN2_S_REG(gen, ADG, CMDOUT_TIMSEL, 0x5c), 316507d466cSKuninori Morimoto 317507d466cSKuninori Morimoto RSND_GEN2_M_REG(gen, SSI, SSICR, 0x00, 0x40), 318507d466cSKuninori Morimoto RSND_GEN2_M_REG(gen, SSI, SSISR, 0x04, 0x40), 319507d466cSKuninori Morimoto RSND_GEN2_M_REG(gen, SSI, SSITDR, 0x08, 0x40), 320507d466cSKuninori Morimoto RSND_GEN2_M_REG(gen, SSI, SSIRDR, 0x0c, 0x40), 321507d466cSKuninori Morimoto RSND_GEN2_M_REG(gen, SSI, SSIWSR, 0x20, 0x40), 322507d466cSKuninori Morimoto }; 323507d466cSKuninori Morimoto 324507d466cSKuninori Morimoto return rsnd_gen_regmap_init(priv, gen, regf); 325507d466cSKuninori Morimoto } 326507d466cSKuninori Morimoto 327507d466cSKuninori Morimoto static int rsnd_gen2_probe(struct platform_device *pdev, 328507d466cSKuninori Morimoto struct rsnd_priv *priv) 329507d466cSKuninori Morimoto { 330507d466cSKuninori Morimoto struct device *dev = rsnd_priv_to_dev(priv); 331507d466cSKuninori Morimoto struct rsnd_gen *gen = rsnd_priv_to_gen(priv); 332507d466cSKuninori Morimoto struct resource *scu_res; 333507d466cSKuninori Morimoto struct resource *adg_res; 334507d466cSKuninori Morimoto struct resource *ssiu_res; 335507d466cSKuninori Morimoto struct resource *ssi_res; 336507d466cSKuninori Morimoto int ret; 337507d466cSKuninori Morimoto 338507d466cSKuninori Morimoto /* 339507d466cSKuninori Morimoto * map address 340507d466cSKuninori Morimoto */ 341507d466cSKuninori Morimoto scu_res = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN2_SCU); 342507d466cSKuninori Morimoto adg_res = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN2_ADG); 343507d466cSKuninori Morimoto ssiu_res = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN2_SSIU); 344507d466cSKuninori Morimoto ssi_res = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN2_SSI); 345507d466cSKuninori Morimoto 346507d466cSKuninori Morimoto gen->base[RSND_GEN2_SCU] = devm_ioremap_resource(dev, scu_res); 347507d466cSKuninori Morimoto gen->base[RSND_GEN2_ADG] = devm_ioremap_resource(dev, adg_res); 348507d466cSKuninori Morimoto gen->base[RSND_GEN2_SSIU] = devm_ioremap_resource(dev, ssiu_res); 349507d466cSKuninori Morimoto gen->base[RSND_GEN2_SSI] = devm_ioremap_resource(dev, ssi_res); 350507d466cSKuninori Morimoto if (IS_ERR(gen->base[RSND_GEN2_SCU]) || 351507d466cSKuninori Morimoto IS_ERR(gen->base[RSND_GEN2_ADG]) || 352507d466cSKuninori Morimoto IS_ERR(gen->base[RSND_GEN2_SSIU]) || 353507d466cSKuninori Morimoto IS_ERR(gen->base[RSND_GEN2_SSI])) 354507d466cSKuninori Morimoto return -ENODEV; 355507d466cSKuninori Morimoto 356507d466cSKuninori Morimoto ret = rsnd_gen2_regmap_init(priv, gen); 357507d466cSKuninori Morimoto if (ret < 0) 358507d466cSKuninori Morimoto return ret; 359507d466cSKuninori Morimoto 360507d466cSKuninori Morimoto dev_dbg(dev, "Gen2 device probed\n"); 361e6b0d896SLaurent Pinchart dev_dbg(dev, "SCU : %pap => %p\n", &scu_res->start, 362507d466cSKuninori Morimoto gen->base[RSND_GEN2_SCU]); 363e6b0d896SLaurent Pinchart dev_dbg(dev, "ADG : %pap => %p\n", &adg_res->start, 364507d466cSKuninori Morimoto gen->base[RSND_GEN2_ADG]); 365e6b0d896SLaurent Pinchart dev_dbg(dev, "SSIU : %pap => %p\n", &ssiu_res->start, 366507d466cSKuninori Morimoto gen->base[RSND_GEN2_SSIU]); 367e6b0d896SLaurent Pinchart dev_dbg(dev, "SSI : %pap => %p\n", &ssi_res->start, 368507d466cSKuninori Morimoto gen->base[RSND_GEN2_SSI]); 369507d466cSKuninori Morimoto 370507d466cSKuninori Morimoto return 0; 371507d466cSKuninori Morimoto } 372507d466cSKuninori Morimoto 373994a9df1SKuninori Morimoto /* 374994a9df1SKuninori Morimoto * Gen1 375994a9df1SKuninori Morimoto */ 376994a9df1SKuninori Morimoto 37755e5b6fdSKuninori Morimoto /* single address mapping */ 37855e5b6fdSKuninori Morimoto #define RSND_GEN1_S_REG(gen, reg, id, offset) \ 37955e5b6fdSKuninori Morimoto RSND_REG_SET(gen, RSND_REG_##id, RSND_GEN1_##reg, offset, 0, 9) 38007539c1dSKuninori Morimoto 38155e5b6fdSKuninori Morimoto /* multi address mapping */ 38255e5b6fdSKuninori Morimoto #define RSND_GEN1_M_REG(gen, reg, id, offset, _id_offset) \ 38355e5b6fdSKuninori Morimoto RSND_REG_SET(gen, RSND_REG_##id, RSND_GEN1_##reg, offset, _id_offset, 9) 38455e5b6fdSKuninori Morimoto 38555e5b6fdSKuninori Morimoto static int rsnd_gen1_regmap_init(struct rsnd_priv *priv, struct rsnd_gen *gen) 38607539c1dSKuninori Morimoto { 38755e5b6fdSKuninori Morimoto struct reg_field regf[RSND_REG_MAX] = { 38855e5b6fdSKuninori Morimoto RSND_GEN1_S_REG(gen, SRU, SRC_ROUTE_SEL, 0x00), 38955e5b6fdSKuninori Morimoto RSND_GEN1_S_REG(gen, SRU, SRC_TMG_SEL0, 0x08), 39055e5b6fdSKuninori Morimoto RSND_GEN1_S_REG(gen, SRU, SRC_TMG_SEL1, 0x0c), 39155e5b6fdSKuninori Morimoto RSND_GEN1_S_REG(gen, SRU, SRC_TMG_SEL2, 0x10), 392690ef81eSKuninori Morimoto RSND_GEN1_S_REG(gen, SRU, SRC_ROUTE_CTRL, 0xc0), 39355e5b6fdSKuninori Morimoto RSND_GEN1_S_REG(gen, SRU, SSI_MODE0, 0xD0), 39455e5b6fdSKuninori Morimoto RSND_GEN1_S_REG(gen, SRU, SSI_MODE1, 0xD4), 3950290d2a4SKuninori Morimoto RSND_GEN1_M_REG(gen, SRU, SRC_BUSIF_MODE, 0x20, 0x4), 396ef749400SKuninori Morimoto RSND_GEN1_M_REG(gen, SRU, SRC_ROUTE_MODE0,0x50, 0x8), 397ef749400SKuninori Morimoto RSND_GEN1_M_REG(gen, SRU, SRC_SWRSR, 0x200, 0x40), 398ef749400SKuninori Morimoto RSND_GEN1_M_REG(gen, SRU, SRC_SRCIR, 0x204, 0x40), 399690ef81eSKuninori Morimoto RSND_GEN1_M_REG(gen, SRU, SRC_ADINR, 0x214, 0x40), 400ef749400SKuninori Morimoto RSND_GEN1_M_REG(gen, SRU, SRC_IFSCR, 0x21c, 0x40), 401ef749400SKuninori Morimoto RSND_GEN1_M_REG(gen, SRU, SRC_IFSVR, 0x220, 0x40), 402ef749400SKuninori Morimoto RSND_GEN1_M_REG(gen, SRU, SRC_SRCCR, 0x224, 0x40), 403ef749400SKuninori Morimoto RSND_GEN1_M_REG(gen, SRU, SRC_MNFSR, 0x228, 0x40), 404dfc9403bSKuninori Morimoto 40555e5b6fdSKuninori Morimoto RSND_GEN1_S_REG(gen, ADG, BRRA, 0x00), 40655e5b6fdSKuninori Morimoto RSND_GEN1_S_REG(gen, ADG, BRRB, 0x04), 40755e5b6fdSKuninori Morimoto RSND_GEN1_S_REG(gen, ADG, SSICKR, 0x08), 40855e5b6fdSKuninori Morimoto RSND_GEN1_S_REG(gen, ADG, AUDIO_CLK_SEL0, 0x0c), 40955e5b6fdSKuninori Morimoto RSND_GEN1_S_REG(gen, ADG, AUDIO_CLK_SEL1, 0x10), 410ef749400SKuninori Morimoto RSND_GEN1_S_REG(gen, ADG, AUDIO_CLK_SEL3, 0x18), 411ef749400SKuninori Morimoto RSND_GEN1_S_REG(gen, ADG, AUDIO_CLK_SEL4, 0x1c), 412ef749400SKuninori Morimoto RSND_GEN1_S_REG(gen, ADG, AUDIO_CLK_SEL5, 0x20), 413ae5c3223SKuninori Morimoto 41455e5b6fdSKuninori Morimoto RSND_GEN1_M_REG(gen, SSI, SSICR, 0x00, 0x40), 41555e5b6fdSKuninori Morimoto RSND_GEN1_M_REG(gen, SSI, SSISR, 0x04, 0x40), 41655e5b6fdSKuninori Morimoto RSND_GEN1_M_REG(gen, SSI, SSITDR, 0x08, 0x40), 41755e5b6fdSKuninori Morimoto RSND_GEN1_M_REG(gen, SSI, SSIRDR, 0x0c, 0x40), 41855e5b6fdSKuninori Morimoto RSND_GEN1_M_REG(gen, SSI, SSIWSR, 0x20, 0x40), 41955e5b6fdSKuninori Morimoto }; 42055e5b6fdSKuninori Morimoto 421c1e6cc5eSKuninori Morimoto return rsnd_gen_regmap_init(priv, gen, regf); 42207539c1dSKuninori Morimoto } 42307539c1dSKuninori Morimoto 4243337744aSKuninori Morimoto static int rsnd_gen1_probe(struct platform_device *pdev, 4253337744aSKuninori Morimoto struct rsnd_priv *priv) 4263337744aSKuninori Morimoto { 42707539c1dSKuninori Morimoto struct device *dev = rsnd_priv_to_dev(priv); 42807539c1dSKuninori Morimoto struct rsnd_gen *gen = rsnd_priv_to_gen(priv); 42907539c1dSKuninori Morimoto struct resource *sru_res; 430dfc9403bSKuninori Morimoto struct resource *adg_res; 431ae5c3223SKuninori Morimoto struct resource *ssi_res; 43255e5b6fdSKuninori Morimoto int ret; 43307539c1dSKuninori Morimoto 43407539c1dSKuninori Morimoto /* 43507539c1dSKuninori Morimoto * map address 43607539c1dSKuninori Morimoto */ 43707539c1dSKuninori Morimoto sru_res = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN1_SRU); 438dfc9403bSKuninori Morimoto adg_res = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN1_ADG); 439ae5c3223SKuninori Morimoto ssi_res = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN1_SSI); 44007539c1dSKuninori Morimoto 44107539c1dSKuninori Morimoto gen->base[RSND_GEN1_SRU] = devm_ioremap_resource(dev, sru_res); 442dfc9403bSKuninori Morimoto gen->base[RSND_GEN1_ADG] = devm_ioremap_resource(dev, adg_res); 443ae5c3223SKuninori Morimoto gen->base[RSND_GEN1_SSI] = devm_ioremap_resource(dev, ssi_res); 44470263cb4SWei Yongjun if (IS_ERR(gen->base[RSND_GEN1_SRU]) || 44570263cb4SWei Yongjun IS_ERR(gen->base[RSND_GEN1_ADG]) || 44670263cb4SWei Yongjun IS_ERR(gen->base[RSND_GEN1_SSI])) 44707539c1dSKuninori Morimoto return -ENODEV; 44807539c1dSKuninori Morimoto 44955e5b6fdSKuninori Morimoto ret = rsnd_gen1_regmap_init(priv, gen); 45055e5b6fdSKuninori Morimoto if (ret < 0) 45155e5b6fdSKuninori Morimoto return ret; 45207539c1dSKuninori Morimoto 45307539c1dSKuninori Morimoto dev_dbg(dev, "Gen1 device probed\n"); 454e6b0d896SLaurent Pinchart dev_dbg(dev, "SRU : %pap => %p\n", &sru_res->start, 45507539c1dSKuninori Morimoto gen->base[RSND_GEN1_SRU]); 456e6b0d896SLaurent Pinchart dev_dbg(dev, "ADG : %pap => %p\n", &adg_res->start, 457dfc9403bSKuninori Morimoto gen->base[RSND_GEN1_ADG]); 458e6b0d896SLaurent Pinchart dev_dbg(dev, "SSI : %pap => %p\n", &ssi_res->start, 459ae5c3223SKuninori Morimoto gen->base[RSND_GEN1_SSI]); 46007539c1dSKuninori Morimoto 4613337744aSKuninori Morimoto return 0; 462ae5c3223SKuninori Morimoto 4633337744aSKuninori Morimoto } 4643337744aSKuninori Morimoto 4653337744aSKuninori Morimoto /* 4663337744aSKuninori Morimoto * Gen 4673337744aSKuninori Morimoto */ 46890e8e50fSKuninori Morimoto static void rsnd_of_parse_gen(struct platform_device *pdev, 46990e8e50fSKuninori Morimoto const struct rsnd_of_data *of_data, 47090e8e50fSKuninori Morimoto struct rsnd_priv *priv) 47190e8e50fSKuninori Morimoto { 47290e8e50fSKuninori Morimoto struct rcar_snd_info *info = priv->info; 47390e8e50fSKuninori Morimoto 47490e8e50fSKuninori Morimoto if (!of_data) 47590e8e50fSKuninori Morimoto return; 47690e8e50fSKuninori Morimoto 47790e8e50fSKuninori Morimoto info->flags = of_data->flags; 47890e8e50fSKuninori Morimoto } 47990e8e50fSKuninori Morimoto 4803337744aSKuninori Morimoto int rsnd_gen_probe(struct platform_device *pdev, 48190e8e50fSKuninori Morimoto const struct rsnd_of_data *of_data, 4823337744aSKuninori Morimoto struct rsnd_priv *priv) 4833337744aSKuninori Morimoto { 4843337744aSKuninori Morimoto struct device *dev = rsnd_priv_to_dev(priv); 4853337744aSKuninori Morimoto struct rsnd_gen *gen; 486531eaf49SKuninori Morimoto int ret; 4873337744aSKuninori Morimoto 48890e8e50fSKuninori Morimoto rsnd_of_parse_gen(pdev, of_data, priv); 48990e8e50fSKuninori Morimoto 4903337744aSKuninori Morimoto gen = devm_kzalloc(dev, sizeof(*gen), GFP_KERNEL); 4913337744aSKuninori Morimoto if (!gen) { 4923337744aSKuninori Morimoto dev_err(dev, "GEN allocate failed\n"); 4933337744aSKuninori Morimoto return -ENOMEM; 4943337744aSKuninori Morimoto } 4953337744aSKuninori Morimoto 496531eaf49SKuninori Morimoto priv->gen = gen; 497072188b6SKuninori Morimoto 498507d466cSKuninori Morimoto ret = -ENODEV; 499507d466cSKuninori Morimoto if (rsnd_is_gen1(priv)) 5005da39cf3SKuninori Morimoto ret = rsnd_gen1_probe(pdev, priv); 501507d466cSKuninori Morimoto else if (rsnd_is_gen2(priv)) 5025da39cf3SKuninori Morimoto ret = rsnd_gen2_probe(pdev, priv); 503507d466cSKuninori Morimoto 504507d466cSKuninori Morimoto if (ret < 0) 505072188b6SKuninori Morimoto dev_err(dev, "unknown generation R-Car sound device\n"); 506072188b6SKuninori Morimoto 507531eaf49SKuninori Morimoto return ret; 5083337744aSKuninori Morimoto } 509