~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/soc/sh/rcar/gen.c

Version: ~ [ linux-5.11-rc3 ] ~ [ linux-5.10.7 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.89 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.167 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.215 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.251 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.251 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.85 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * Renesas R-Car Gen1 SRU/SSI support
  3  *
  4  * Copyright (C) 2013 Renesas Solutions Corp.
  5  * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
  6  *
  7  * This program is free software; you can redistribute it and/or modify
  8  * it under the terms of the GNU General Public License version 2 as
  9  * published by the Free Software Foundation.
 10  */
 11 #include "rsnd.h"
 12 
 13 struct rsnd_gen {
 14         void __iomem *base[RSND_BASE_MAX];
 15 
 16         struct rsnd_gen_ops *ops;
 17 
 18         struct regmap *regmap;
 19         struct regmap_field *regs[RSND_REG_MAX];
 20 };
 21 
 22 #define rsnd_priv_to_gen(p)     ((struct rsnd_gen *)(p)->gen)
 23 
 24 #define RSND_REG_SET(gen, id, reg_id, offset, _id_offset, _id_size)     \
 25         [id] = {                                                        \
 26                 .reg = (unsigned int)gen->base[reg_id] + offset,        \
 27                 .lsb = 0,                                               \
 28                 .msb = 31,                                              \
 29                 .id_size = _id_size,                                    \
 30                 .id_offset = _id_offset,                                \
 31         }
 32 
 33 /*
 34  *              basic function
 35  */
 36 static int rsnd_regmap_write32(void *context, const void *_data, size_t count)
 37 {
 38         struct rsnd_priv *priv = context;
 39         struct device *dev = rsnd_priv_to_dev(priv);
 40         u32 *data = (u32 *)_data;
 41         u32 val = data[1];
 42         void __iomem *reg = (void *)data[0];
 43 
 44         iowrite32(val, reg);
 45 
 46         dev_dbg(dev, "w %p : %08x\n", reg, val);
 47 
 48         return 0;
 49 }
 50 
 51 static int rsnd_regmap_read32(void *context,
 52                               const void *_data, size_t reg_size,
 53                               void *_val, size_t val_size)
 54 {
 55         struct rsnd_priv *priv = context;
 56         struct device *dev = rsnd_priv_to_dev(priv);
 57         u32 *data = (u32 *)_data;
 58         u32 *val = (u32 *)_val;
 59         void __iomem *reg = (void *)data[0];
 60 
 61         *val = ioread32(reg);
 62 
 63         dev_dbg(dev, "r %p : %08x\n", reg, *val);
 64 
 65         return 0;
 66 }
 67 
 68 static struct regmap_bus rsnd_regmap_bus = {
 69         .write                          = rsnd_regmap_write32,
 70         .read                           = rsnd_regmap_read32,
 71         .reg_format_endian_default      = REGMAP_ENDIAN_NATIVE,
 72         .val_format_endian_default      = REGMAP_ENDIAN_NATIVE,
 73 };
 74 
 75 static int rsnd_is_accessible_reg(struct rsnd_priv *priv,
 76                                   struct rsnd_gen *gen, enum rsnd_reg reg)
 77 {
 78         if (!gen->regs[reg]) {
 79                 struct device *dev = rsnd_priv_to_dev(priv);
 80 
 81                 dev_err(dev, "unsupported register access %x\n", reg);
 82                 return 0;
 83         }
 84 
 85         return 1;
 86 }
 87 
 88 u32 rsnd_read(struct rsnd_priv *priv,
 89               struct rsnd_mod *mod, enum rsnd_reg reg)
 90 {
 91         struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
 92         u32 val;
 93 
 94         if (!rsnd_is_accessible_reg(priv, gen, reg))
 95                 return 0;
 96 
 97         regmap_fields_read(gen->regs[reg], rsnd_mod_id(mod), &val);
 98 
 99         return val;
100 }
101 
102 void rsnd_write(struct rsnd_priv *priv,
103                 struct rsnd_mod *mod,
104                 enum rsnd_reg reg, u32 data)
105 {
106         struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
107 
108         if (!rsnd_is_accessible_reg(priv, gen, reg))
109                 return;
110 
111         regmap_fields_write(gen->regs[reg], rsnd_mod_id(mod), data);
112 }
113 
114 void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod,
115                enum rsnd_reg reg, u32 mask, u32 data)
116 {
117         struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
118 
119         if (!rsnd_is_accessible_reg(priv, gen, reg))
120                 return;
121 
122         regmap_fields_update_bits(gen->regs[reg], rsnd_mod_id(mod),
123                                   mask, data);
124 }
125 
126 static int rsnd_gen_regmap_init(struct rsnd_priv *priv,
127                                 struct rsnd_gen  *gen,
128                                 struct reg_field *regf)
129 {
130         int i;
131         struct device *dev = rsnd_priv_to_dev(priv);
132         struct regmap_config regc;
133 
134         memset(&regc, 0, sizeof(regc));
135         regc.reg_bits = 32;
136         regc.val_bits = 32;
137 
138         gen->regmap = devm_regmap_init(dev, &rsnd_regmap_bus, priv, &regc);
139         if (IS_ERR(gen->regmap)) {
140                 dev_err(dev, "regmap error %ld\n", PTR_ERR(gen->regmap));
141                 return PTR_ERR(gen->regmap);
142         }
143 
144         for (i = 0; i < RSND_REG_MAX; i++) {
145                 gen->regs[i] = NULL;
146                 if (!regf[i].reg)
147                         continue;
148 
149                 gen->regs[i] = devm_regmap_field_alloc(dev, gen->regmap, regf[i]);
150                 if (IS_ERR(gen->regs[i]))
151                         return PTR_ERR(gen->regs[i]);
152 
153         }
154 
155         return 0;
156 }
157 
158 /*
159  *      DMA read/write register offset
160  *
161  *      RSND_xxx_I_N    for Audio DMAC input
162  *      RSND_xxx_O_N    for Audio DMAC output
163  *      RSND_xxx_I_P    for Audio DMAC peri peri input
164  *      RSND_xxx_O_P    for Audio DMAC peri peri output
165  *
166  *      ex) R-Car H2 case
167  *            mod        / DMAC in    / DMAC out   / DMAC PP in / DMAC pp out
168  *      SSI : 0xec541000 / 0xec241008 / 0xec24100c / 0xec400000 / 0xec400000
169  *      SCU : 0xec500000 / 0xec000000 / 0xec004000 / 0xec300000 / 0xec304000
170  *      CMD : 0xec500000 / 0xec008000                             0xec308000
171  */
172 #define RDMA_SSI_I_N(addr, i)   (addr ##_reg - 0x00300000 + (0x40 * i) + 0x8)
173 #define RDMA_SSI_O_N(addr, i)   (addr ##_reg - 0x00300000 + (0x40 * i) + 0xc)
174 
175 #define RDMA_SSI_I_P(addr, i)   (addr ##_reg - 0x00141000 + (0x1000 * i))
176 #define RDMA_SSI_O_P(addr, i)   (addr ##_reg - 0x00141000 + (0x1000 * i))
177 
178 #define RDMA_SRC_I_N(addr, i)   (addr ##_reg - 0x00500000 + (0x400 * i))
179 #define RDMA_SRC_O_N(addr, i)   (addr ##_reg - 0x004fc000 + (0x400 * i))
180 
181 #define RDMA_SRC_I_P(addr, i)   (addr ##_reg - 0x00200000 + (0x400 * i))
182 #define RDMA_SRC_O_P(addr, i)   (addr ##_reg - 0x001fc000 + (0x400 * i))
183 
184 #define RDMA_CMD_O_N(addr, i)   (addr ##_reg - 0x004f8000 + (0x400 * i))
185 #define RDMA_CMD_O_P(addr, i)   (addr ##_reg - 0x001f8000 + (0x400 * i))
186 
187 void rsnd_gen_dma_addr(struct rsnd_priv *priv,
188                        struct rsnd_dma *dma,
189                        struct dma_slave_config *cfg,
190                        int is_play, int slave_id)
191 {
192         struct platform_device *pdev = rsnd_priv_to_pdev(priv);
193         struct device *dev = rsnd_priv_to_dev(priv);
194         struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
195         struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
196         dma_addr_t ssi_reg = platform_get_resource(pdev,
197                                 IORESOURCE_MEM, RSND_GEN2_SSI)->start;
198         dma_addr_t src_reg = platform_get_resource(pdev,
199                                 IORESOURCE_MEM, RSND_GEN2_SCU)->start;
200         int is_ssi = !!(rsnd_io_to_mod_ssi(io) == mod);
201         int use_src = !!rsnd_io_to_mod_src(io);
202         int use_dvc = !!rsnd_io_to_mod_dvc(io);
203         int id = rsnd_mod_id(mod);
204         struct dma_addr {
205                 dma_addr_t src_addr;
206                 dma_addr_t dst_addr;
207         } dma_addrs[2][2][3] = {
208                 { /* SRC */
209                         /* Capture */
210                         {{ 0,                           0 },
211                          { RDMA_SRC_O_N(src, id),       0 },
212                          { RDMA_CMD_O_N(src, id),       0 }},
213                         /* Playback */
214                         {{ 0,                           0, },
215                          { 0,                           RDMA_SRC_I_N(src, id) },
216                          { 0,                           RDMA_SRC_I_N(src, id) }}
217                 }, { /* SSI */
218                         /* Capture */
219                         {{ RDMA_SSI_O_N(ssi, id),       0 },
220                          { RDMA_SSI_O_P(ssi, id),       RDMA_SRC_I_P(src, id) },
221                          { RDMA_SSI_O_P(ssi, id),       RDMA_SRC_I_P(src, id) }},
222                         /* Playback */
223                         {{ 0,                           RDMA_SSI_I_N(ssi, id) },
224                          { RDMA_SRC_O_P(src, id),       RDMA_SSI_I_P(ssi, id) },
225                          { RDMA_CMD_O_P(src, id),       RDMA_SSI_I_P(ssi, id) }}
226                 }
227         };
228 
229         cfg->slave_id   = slave_id;
230         cfg->src_addr   = 0;
231         cfg->dst_addr   = 0;
232         cfg->direction  = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM;
233 
234         /*
235          * gen1 uses default DMA addr
236          */
237         if (rsnd_is_gen1(priv))
238                 return;
239 
240         /* it shouldn't happen */
241         if (use_dvc & !use_src) {
242                 dev_err(dev, "DVC is selected without SRC\n");
243                 return;
244         }
245 
246         cfg->src_addr = dma_addrs[is_ssi][is_play][use_src + use_dvc].src_addr;
247         cfg->dst_addr = dma_addrs[is_ssi][is_play][use_src + use_dvc].dst_addr;
248 
249         dev_dbg(dev, "dma%d addr - src : %x / dst : %x\n",
250                 id, cfg->src_addr, cfg->dst_addr);
251 }
252 
253 /*
254  *              Gen2
255  */
256 
257 /* single address mapping */
258 #define RSND_GEN2_S_REG(gen, reg, id, offset)                           \
259         RSND_REG_SET(gen, RSND_REG_##id, RSND_GEN2_##reg, offset, 0, 10)
260 
261 /* multi address mapping */
262 #define RSND_GEN2_M_REG(gen, reg, id, offset, _id_offset)               \
263         RSND_REG_SET(gen, RSND_REG_##id, RSND_GEN2_##reg, offset, _id_offset, 10)
264 
265 static int rsnd_gen2_regmap_init(struct rsnd_priv *priv, struct rsnd_gen *gen)
266 {
267         struct reg_field regf[RSND_REG_MAX] = {
268                 RSND_GEN2_S_REG(gen, SSIU,      SSI_MODE0,      0x800),
269                 RSND_GEN2_S_REG(gen, SSIU,      SSI_MODE1,      0x804),
270                 /* FIXME: it needs SSI_MODE2/3 in the future */
271                 RSND_GEN2_M_REG(gen, SSIU,      SSI_BUSIF_MODE, 0x0,    0x80),
272                 RSND_GEN2_M_REG(gen, SSIU,      SSI_BUSIF_ADINR,0x4,    0x80),
273                 RSND_GEN2_M_REG(gen, SSIU,      SSI_CTRL,       0x10,   0x80),
274                 RSND_GEN2_M_REG(gen, SSIU,      INT_ENABLE,     0x18,   0x80),
275 
276                 RSND_GEN2_M_REG(gen, SCU,       SRC_BUSIF_MODE, 0x0,    0x20),
277                 RSND_GEN2_M_REG(gen, SCU,       SRC_ROUTE_MODE0,0xc,    0x20),
278                 RSND_GEN2_M_REG(gen, SCU,       SRC_CTRL,       0x10,   0x20),
279                 RSND_GEN2_M_REG(gen, SCU,       CMD_ROUTE_SLCT, 0x18c,  0x20),
280                 RSND_GEN2_M_REG(gen, SCU,       CMD_CTRL,       0x190,  0x20),
281                 RSND_GEN2_M_REG(gen, SCU,       SRC_SWRSR,      0x200,  0x40),
282                 RSND_GEN2_M_REG(gen, SCU,       SRC_SRCIR,      0x204,  0x40),
283                 RSND_GEN2_M_REG(gen, SCU,       SRC_ADINR,      0x214,  0x40),
284                 RSND_GEN2_M_REG(gen, SCU,       SRC_IFSCR,      0x21c,  0x40),
285                 RSND_GEN2_M_REG(gen, SCU,       SRC_IFSVR,      0x220,  0x40),
286                 RSND_GEN2_M_REG(gen, SCU,       SRC_SRCCR,      0x224,  0x40),
287                 RSND_GEN2_M_REG(gen, SCU,       SRC_BSDSR,      0x22c,  0x40),
288                 RSND_GEN2_M_REG(gen, SCU,       SRC_BSISR,      0x238,  0x40),
289                 RSND_GEN2_M_REG(gen, SCU,       DVC_SWRSR,      0xe00,  0x100),
290                 RSND_GEN2_M_REG(gen, SCU,       DVC_DVUIR,      0xe04,  0x100),
291                 RSND_GEN2_M_REG(gen, SCU,       DVC_ADINR,      0xe08,  0x100),
292                 RSND_GEN2_M_REG(gen, SCU,       DVC_DVUCR,      0xe10,  0x100),
293                 RSND_GEN2_M_REG(gen, SCU,       DVC_ZCMCR,      0xe14,  0x100),
294                 RSND_GEN2_M_REG(gen, SCU,       DVC_VOL0R,      0xe28,  0x100),
295                 RSND_GEN2_M_REG(gen, SCU,       DVC_VOL1R,      0xe2c,  0x100),
296                 RSND_GEN2_M_REG(gen, SCU,       DVC_DVUER,      0xe48,  0x100),
297 
298                 RSND_GEN2_S_REG(gen, ADG,       BRRA,           0x00),
299                 RSND_GEN2_S_REG(gen, ADG,       BRRB,           0x04),
300                 RSND_GEN2_S_REG(gen, ADG,       SSICKR,         0x08),
301                 RSND_GEN2_S_REG(gen, ADG,       AUDIO_CLK_SEL0, 0x0c),
302                 RSND_GEN2_S_REG(gen, ADG,       AUDIO_CLK_SEL1, 0x10),
303                 RSND_GEN2_S_REG(gen, ADG,       AUDIO_CLK_SEL2, 0x14),
304                 RSND_GEN2_S_REG(gen, ADG,       DIV_EN,         0x30),
305                 RSND_GEN2_S_REG(gen, ADG,       SRCIN_TIMSEL0,  0x34),
306                 RSND_GEN2_S_REG(gen, ADG,       SRCIN_TIMSEL1,  0x38),
307                 RSND_GEN2_S_REG(gen, ADG,       SRCIN_TIMSEL2,  0x3c),
308                 RSND_GEN2_S_REG(gen, ADG,       SRCIN_TIMSEL3,  0x40),
309                 RSND_GEN2_S_REG(gen, ADG,       SRCIN_TIMSEL4,  0x44),
310                 RSND_GEN2_S_REG(gen, ADG,       SRCOUT_TIMSEL0, 0x48),
311                 RSND_GEN2_S_REG(gen, ADG,       SRCOUT_TIMSEL1, 0x4c),
312                 RSND_GEN2_S_REG(gen, ADG,       SRCOUT_TIMSEL2, 0x50),
313                 RSND_GEN2_S_REG(gen, ADG,       SRCOUT_TIMSEL3, 0x54),
314                 RSND_GEN2_S_REG(gen, ADG,       SRCOUT_TIMSEL4, 0x58),
315                 RSND_GEN2_S_REG(gen, ADG,       CMDOUT_TIMSEL,  0x5c),
316 
317                 RSND_GEN2_M_REG(gen, SSI,       SSICR,          0x00,   0x40),
318                 RSND_GEN2_M_REG(gen, SSI,       SSISR,          0x04,   0x40),
319                 RSND_GEN2_M_REG(gen, SSI,       SSITDR,         0x08,   0x40),
320                 RSND_GEN2_M_REG(gen, SSI,       SSIRDR,         0x0c,   0x40),
321                 RSND_GEN2_M_REG(gen, SSI,       SSIWSR,         0x20,   0x40),
322         };
323 
324         return rsnd_gen_regmap_init(priv, gen, regf);
325 }
326 
327 static int rsnd_gen2_probe(struct platform_device *pdev,
328                            struct rsnd_priv *priv)
329 {
330         struct device *dev = rsnd_priv_to_dev(priv);
331         struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
332         struct resource *scu_res;
333         struct resource *adg_res;
334         struct resource *ssiu_res;
335         struct resource *ssi_res;
336         int ret;
337 
338         /*
339          * map address
340          */
341         scu_res  = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN2_SCU);
342         adg_res  = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN2_ADG);
343         ssiu_res = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN2_SSIU);
344         ssi_res  = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN2_SSI);
345 
346         gen->base[RSND_GEN2_SCU]  = devm_ioremap_resource(dev, scu_res);
347         gen->base[RSND_GEN2_ADG]  = devm_ioremap_resource(dev, adg_res);
348         gen->base[RSND_GEN2_SSIU] = devm_ioremap_resource(dev, ssiu_res);
349         gen->base[RSND_GEN2_SSI]  = devm_ioremap_resource(dev, ssi_res);
350         if (IS_ERR(gen->base[RSND_GEN2_SCU])  ||
351             IS_ERR(gen->base[RSND_GEN2_ADG])  ||
352             IS_ERR(gen->base[RSND_GEN2_SSIU]) ||
353             IS_ERR(gen->base[RSND_GEN2_SSI]))
354                 return -ENODEV;
355 
356         ret = rsnd_gen2_regmap_init(priv, gen);
357         if (ret < 0)
358                 return ret;
359 
360         dev_dbg(dev, "Gen2 device probed\n");
361         dev_dbg(dev, "SCU  : %pap => %p\n", &scu_res->start,
362                 gen->base[RSND_GEN2_SCU]);
363         dev_dbg(dev, "ADG  : %pap => %p\n", &adg_res->start,
364                 gen->base[RSND_GEN2_ADG]);
365         dev_dbg(dev, "SSIU : %pap => %p\n", &ssiu_res->start,
366                 gen->base[RSND_GEN2_SSIU]);
367         dev_dbg(dev, "SSI  : %pap => %p\n", &ssi_res->start,
368                 gen->base[RSND_GEN2_SSI]);
369 
370         return 0;
371 }
372 
373 /*
374  *              Gen1
375  */
376 
377 /* single address mapping */
378 #define RSND_GEN1_S_REG(gen, reg, id, offset)   \
379         RSND_REG_SET(gen, RSND_REG_##id, RSND_GEN1_##reg, offset, 0, 9)
380 
381 /* multi address mapping */
382 #define RSND_GEN1_M_REG(gen, reg, id, offset, _id_offset)       \
383         RSND_REG_SET(gen, RSND_REG_##id, RSND_GEN1_##reg, offset, _id_offset, 9)
384 
385 static int rsnd_gen1_regmap_init(struct rsnd_priv *priv, struct rsnd_gen *gen)
386 {
387         struct reg_field regf[RSND_REG_MAX] = {
388                 RSND_GEN1_S_REG(gen, SRU,       SRC_ROUTE_SEL,  0x00),
389                 RSND_GEN1_S_REG(gen, SRU,       SRC_TMG_SEL0,   0x08),
390                 RSND_GEN1_S_REG(gen, SRU,       SRC_TMG_SEL1,   0x0c),
391                 RSND_GEN1_S_REG(gen, SRU,       SRC_TMG_SEL2,   0x10),
392                 RSND_GEN1_S_REG(gen, SRU,       SRC_ROUTE_CTRL, 0xc0),
393                 RSND_GEN1_S_REG(gen, SRU,       SSI_MODE0,      0xD0),
394                 RSND_GEN1_S_REG(gen, SRU,       SSI_MODE1,      0xD4),
395                 RSND_GEN1_M_REG(gen, SRU,       SRC_BUSIF_MODE, 0x20,   0x4),
396                 RSND_GEN1_M_REG(gen, SRU,       SRC_ROUTE_MODE0,0x50,   0x8),
397                 RSND_GEN1_M_REG(gen, SRU,       SRC_SWRSR,      0x200,  0x40),
398                 RSND_GEN1_M_REG(gen, SRU,       SRC_SRCIR,      0x204,  0x40),
399                 RSND_GEN1_M_REG(gen, SRU,       SRC_ADINR,      0x214,  0x40),
400                 RSND_GEN1_M_REG(gen, SRU,       SRC_IFSCR,      0x21c,  0x40),
401                 RSND_GEN1_M_REG(gen, SRU,       SRC_IFSVR,      0x220,  0x40),
402                 RSND_GEN1_M_REG(gen, SRU,       SRC_SRCCR,      0x224,  0x40),
403                 RSND_GEN1_M_REG(gen, SRU,       SRC_MNFSR,      0x228,  0x40),
404 
405                 RSND_GEN1_S_REG(gen, ADG,       BRRA,           0x00),
406                 RSND_GEN1_S_REG(gen, ADG,       BRRB,           0x04),
407                 RSND_GEN1_S_REG(gen, ADG,       SSICKR,         0x08),
408                 RSND_GEN1_S_REG(gen, ADG,       AUDIO_CLK_SEL0, 0x0c),
409                 RSND_GEN1_S_REG(gen, ADG,       AUDIO_CLK_SEL1, 0x10),
410                 RSND_GEN1_S_REG(gen, ADG,       AUDIO_CLK_SEL3, 0x18),
411                 RSND_GEN1_S_REG(gen, ADG,       AUDIO_CLK_SEL4, 0x1c),
412                 RSND_GEN1_S_REG(gen, ADG,       AUDIO_CLK_SEL5, 0x20),
413 
414                 RSND_GEN1_M_REG(gen, SSI,       SSICR,          0x00,   0x40),
415                 RSND_GEN1_M_REG(gen, SSI,       SSISR,          0x04,   0x40),
416                 RSND_GEN1_M_REG(gen, SSI,       SSITDR,         0x08,   0x40),
417                 RSND_GEN1_M_REG(gen, SSI,       SSIRDR,         0x0c,   0x40),
418                 RSND_GEN1_M_REG(gen, SSI,       SSIWSR,         0x20,   0x40),
419         };
420 
421         return rsnd_gen_regmap_init(priv, gen, regf);
422 }
423 
424 static int rsnd_gen1_probe(struct platform_device *pdev,
425                            struct rsnd_priv *priv)
426 {
427         struct device *dev = rsnd_priv_to_dev(priv);
428         struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
429         struct resource *sru_res;
430         struct resource *adg_res;
431         struct resource *ssi_res;
432         int ret;
433 
434         /*
435          * map address
436          */
437         sru_res = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN1_SRU);
438         adg_res = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN1_ADG);
439         ssi_res = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN1_SSI);
440 
441         gen->base[RSND_GEN1_SRU] = devm_ioremap_resource(dev, sru_res);
442         gen->base[RSND_GEN1_ADG] = devm_ioremap_resource(dev, adg_res);
443         gen->base[RSND_GEN1_SSI] = devm_ioremap_resource(dev, ssi_res);
444         if (IS_ERR(gen->base[RSND_GEN1_SRU]) ||
445             IS_ERR(gen->base[RSND_GEN1_ADG]) ||
446             IS_ERR(gen->base[RSND_GEN1_SSI]))
447                 return -ENODEV;
448 
449         ret = rsnd_gen1_regmap_init(priv, gen);
450         if (ret < 0)
451                 return ret;
452 
453         dev_dbg(dev, "Gen1 device probed\n");
454         dev_dbg(dev, "SRU : %pap => %p\n",      &sru_res->start,
455                                                 gen->base[RSND_GEN1_SRU]);
456         dev_dbg(dev, "ADG : %pap => %p\n",      &adg_res->start,
457                                                 gen->base[RSND_GEN1_ADG]);
458         dev_dbg(dev, "SSI : %pap => %p\n",      &ssi_res->start,
459                                                 gen->base[RSND_GEN1_SSI]);
460 
461         return 0;
462 
463 }
464 
465 /*
466  *              Gen
467  */
468 static void rsnd_of_parse_gen(struct platform_device *pdev,
469                               const struct rsnd_of_data *of_data,
470                               struct rsnd_priv *priv)
471 {
472         struct rcar_snd_info *info = priv->info;
473 
474         if (!of_data)
475                 return;
476 
477         info->flags = of_data->flags;
478 }
479 
480 int rsnd_gen_probe(struct platform_device *pdev,
481                    const struct rsnd_of_data *of_data,
482                    struct rsnd_priv *priv)
483 {
484         struct device *dev = rsnd_priv_to_dev(priv);
485         struct rsnd_gen *gen;
486         int ret;
487 
488         rsnd_of_parse_gen(pdev, of_data, priv);
489 
490         gen = devm_kzalloc(dev, sizeof(*gen), GFP_KERNEL);
491         if (!gen) {
492                 dev_err(dev, "GEN allocate failed\n");
493                 return -ENOMEM;
494         }
495 
496         priv->gen = gen;
497 
498         ret = -ENODEV;
499         if (rsnd_is_gen1(priv))
500                 ret = rsnd_gen1_probe(pdev, priv);
501         else if (rsnd_is_gen2(priv))
502                 ret = rsnd_gen2_probe(pdev, priv);
503 
504         if (ret < 0)
505                 dev_err(dev, "unknown generation R-Car sound device\n");
506 
507         return ret;
508 }
509 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp