rsnd.h 11.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/*
 * Renesas R-Car
 *
 * Copyright (C) 2013 Renesas Solutions Corp.
 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
#ifndef RSND_H
#define RSND_H

#include <linux/clk.h>
#include <linux/device.h>
16
#include <linux/dma-mapping.h>
17 18 19
#include <linux/io.h>
#include <linux/list.h>
#include <linux/module.h>
20 21
#include <linux/of_device.h>
#include <linux/of_irq.h>
22 23
#include <linux/sh_dma.h>
#include <linux/workqueue.h>
24 25 26 27 28 29 30 31 32 33 34
#include <sound/rcar_snd.h>
#include <sound/soc.h>
#include <sound/pcm_params.h>

/*
 *	pseudo register
 *
 * The register address offsets SRU/SCU/SSIU on Gen1/Gen2 are very different.
 * This driver uses pseudo register in order to hide it.
 * see gen1/gen2 for detail
 */
35
enum rsnd_reg {
36
	/* SRU/SCU/SSIU */
37 38
	RSND_REG_SSI_MODE0,
	RSND_REG_SSI_MODE1,
39
	RSND_REG_SRC_BUSIF_MODE,
40 41 42
	RSND_REG_SRC_ROUTE_MODE0,
	RSND_REG_SRC_SWRSR,
	RSND_REG_SRC_SRCIR,
43
	RSND_REG_SRC_ADINR,
44 45 46
	RSND_REG_SRC_IFSCR,
	RSND_REG_SRC_IFSVR,
	RSND_REG_SRC_SRCCR,
K
Kuninori Morimoto 已提交
47 48 49 50 51 52 53 54 55
	RSND_REG_CMD_ROUTE_SLCT,
	RSND_REG_DVC_SWRSR,
	RSND_REG_DVC_DVUIR,
	RSND_REG_DVC_ADINR,
	RSND_REG_DVC_DVUCR,
	RSND_REG_DVC_ZCMCR,
	RSND_REG_DVC_VOL0R,
	RSND_REG_DVC_VOL1R,
	RSND_REG_DVC_DVUER,
56

57 58 59 60 61 62 63
	/* ADG */
	RSND_REG_BRRA,
	RSND_REG_BRRB,
	RSND_REG_SSICKR,
	RSND_REG_AUDIO_CLK_SEL0,
	RSND_REG_AUDIO_CLK_SEL1,

64 65 66 67 68 69 70
	/* SSI */
	RSND_REG_SSICR,
	RSND_REG_SSISR,
	RSND_REG_SSITDR,
	RSND_REG_SSIRDR,
	RSND_REG_SSIWSR,

71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
	/* SHARE see below */
	RSND_REG_SHARE01,
	RSND_REG_SHARE02,
	RSND_REG_SHARE03,
	RSND_REG_SHARE04,
	RSND_REG_SHARE05,
	RSND_REG_SHARE06,
	RSND_REG_SHARE07,
	RSND_REG_SHARE08,
	RSND_REG_SHARE09,
	RSND_REG_SHARE10,
	RSND_REG_SHARE11,
	RSND_REG_SHARE12,
	RSND_REG_SHARE13,
	RSND_REG_SHARE14,
	RSND_REG_SHARE15,
	RSND_REG_SHARE16,
	RSND_REG_SHARE17,
	RSND_REG_SHARE18,
	RSND_REG_SHARE19,
K
Kuninori Morimoto 已提交
91 92
	RSND_REG_SHARE20,
	RSND_REG_SHARE21,
93
	RSND_REG_SHARE22,
94 95 96
	RSND_REG_SHARE23,
	RSND_REG_SHARE24,
	RSND_REG_SHARE25,
97

98 99 100
	RSND_REG_MAX,
};

101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
/* Gen1 only */
#define RSND_REG_SRC_ROUTE_SEL		RSND_REG_SHARE01
#define RSND_REG_SRC_TMG_SEL0		RSND_REG_SHARE02
#define RSND_REG_SRC_TMG_SEL1		RSND_REG_SHARE03
#define RSND_REG_SRC_TMG_SEL2		RSND_REG_SHARE04
#define RSND_REG_SRC_ROUTE_CTRL		RSND_REG_SHARE05
#define RSND_REG_SRC_MNFSR		RSND_REG_SHARE06
#define RSND_REG_AUDIO_CLK_SEL3		RSND_REG_SHARE07
#define RSND_REG_AUDIO_CLK_SEL4		RSND_REG_SHARE08
#define RSND_REG_AUDIO_CLK_SEL5		RSND_REG_SHARE09

/* Gen2 only */
#define RSND_REG_SRC_CTRL		RSND_REG_SHARE01
#define RSND_REG_SSI_CTRL		RSND_REG_SHARE02
#define RSND_REG_SSI_BUSIF_MODE		RSND_REG_SHARE03
#define RSND_REG_SSI_BUSIF_ADINR	RSND_REG_SHARE04
#define RSND_REG_INT_ENABLE		RSND_REG_SHARE05
#define RSND_REG_SRC_BSDSR		RSND_REG_SHARE06
#define RSND_REG_SRC_BSISR		RSND_REG_SHARE07
#define RSND_REG_DIV_EN			RSND_REG_SHARE08
#define RSND_REG_SRCIN_TIMSEL0		RSND_REG_SHARE09
#define RSND_REG_SRCIN_TIMSEL1		RSND_REG_SHARE10
#define RSND_REG_SRCIN_TIMSEL2		RSND_REG_SHARE11
#define RSND_REG_SRCIN_TIMSEL3		RSND_REG_SHARE12
#define RSND_REG_SRCIN_TIMSEL4		RSND_REG_SHARE13
#define RSND_REG_SRCOUT_TIMSEL0		RSND_REG_SHARE14
#define RSND_REG_SRCOUT_TIMSEL1		RSND_REG_SHARE15
#define RSND_REG_SRCOUT_TIMSEL2		RSND_REG_SHARE16
#define RSND_REG_SRCOUT_TIMSEL3		RSND_REG_SHARE17
#define RSND_REG_SRCOUT_TIMSEL4		RSND_REG_SHARE18
#define RSND_REG_AUDIO_CLK_SEL2		RSND_REG_SHARE19
K
Kuninori Morimoto 已提交
132 133
#define RSND_REG_CMD_CTRL		RSND_REG_SHARE20
#define RSND_REG_CMDOUT_TIMSEL		RSND_REG_SHARE21
134
#define RSND_REG_BUSIF_DALIGN		RSND_REG_SHARE22
135 136 137
#define RSND_REG_DVC_VRCTR		RSND_REG_SHARE23
#define RSND_REG_DVC_VRPDR		RSND_REG_SHARE24
#define RSND_REG_DVC_VRDBR		RSND_REG_SHARE25
138

139
struct rsnd_of_data;
140
struct rsnd_priv;
141
struct rsnd_mod;
142 143 144
struct rsnd_dai;
struct rsnd_dai_stream;

145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
/*
 *	R-Car basic functions
 */
#define rsnd_mod_read(m, r) \
	rsnd_read(rsnd_mod_to_priv(m), m, RSND_REG_##r)
#define rsnd_mod_write(m, r, d) \
	rsnd_write(rsnd_mod_to_priv(m), m, RSND_REG_##r, d)
#define rsnd_mod_bset(m, r, s, d) \
	rsnd_bset(rsnd_mod_to_priv(m), m, RSND_REG_##r, s, d)

u32 rsnd_read(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg);
void rsnd_write(struct rsnd_priv *priv, struct rsnd_mod *mod,
		enum rsnd_reg reg, u32 data);
void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg,
		    u32 mask, u32 data);
160
u32 rsnd_get_adinr(struct rsnd_mod *mod);
161

162 163 164 165 166 167
/*
 *	R-Car DMA
 */
struct rsnd_dma {
	struct sh_dmae_slave	slave;
	struct dma_chan		*chan;
168
	enum dma_transfer_direction dir;
169
	dma_addr_t		addr;
170 171 172 173 174 175
};

void rsnd_dma_start(struct rsnd_dma *dma);
void rsnd_dma_stop(struct rsnd_dma *dma);
int rsnd_dma_available(struct rsnd_dma *dma);
int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma,
176
	int is_play, int id);
177 178 179 180
void  rsnd_dma_quit(struct rsnd_priv *priv,
		    struct rsnd_dma *dma);


181 182 183
/*
 *	R-Car sound mod
 */
184
enum rsnd_mod_type {
185
	RSND_MOD_SRC = 0,
186
	RSND_MOD_SSI,
K
Kuninori Morimoto 已提交
187
	RSND_MOD_DVC,
188 189
	RSND_MOD_MAX,
};
190 191 192

struct rsnd_mod_ops {
	char *name;
193
	char* (*dma_name)(struct rsnd_mod *mod);
194
	int (*probe)(struct rsnd_mod *mod,
195
		     struct rsnd_dai *rdai);
196
	int (*remove)(struct rsnd_mod *mod,
197
		      struct rsnd_dai *rdai);
198
	int (*init)(struct rsnd_mod *mod,
199
		    struct rsnd_dai *rdai);
200
	int (*quit)(struct rsnd_mod *mod,
201
		    struct rsnd_dai *rdai);
202
	int (*start)(struct rsnd_mod *mod,
203
		     struct rsnd_dai *rdai);
204
	int (*stop)(struct rsnd_mod *mod,
205
		    struct rsnd_dai *rdai);
K
Kuninori Morimoto 已提交
206 207 208
	int (*pcm_new)(struct rsnd_mod *mod,
		       struct rsnd_dai *rdai,
		       struct snd_soc_pcm_runtime *rtd);
209 210
	int (*fallback)(struct rsnd_mod *mod,
			struct rsnd_dai *rdai);
211 212
};

213
struct rsnd_dai_stream;
214 215
struct rsnd_mod {
	int id;
216
	enum rsnd_mod_type type;
217 218
	struct rsnd_priv *priv;
	struct rsnd_mod_ops *ops;
219
	struct rsnd_dma dma;
220
	struct rsnd_dai_stream *io;
221 222 223
};

#define rsnd_mod_to_priv(mod) ((mod)->priv)
224 225
#define rsnd_mod_to_dma(mod) (&(mod)->dma)
#define rsnd_dma_to_mod(_dma) container_of((_dma), struct rsnd_mod, dma)
226
#define rsnd_mod_to_io(mod) ((mod)->io)
227 228 229 230 231
#define rsnd_mod_id(mod) ((mod)->id)

void rsnd_mod_init(struct rsnd_priv *priv,
		   struct rsnd_mod *mod,
		   struct rsnd_mod_ops *ops,
232
		   enum rsnd_mod_type type,
233 234
		   int id);
char *rsnd_mod_name(struct rsnd_mod *mod);
235
char *rsnd_mod_dma_name(struct rsnd_mod *mod);
236

237 238 239 240 241 242
/*
 *	R-Car sound DAI
 */
#define RSND_DAI_NAME_SIZE	16
struct rsnd_dai_stream {
	struct snd_pcm_substream *substream;
243
	struct rsnd_mod *mod[RSND_MOD_MAX];
244
	struct rsnd_dai_path_info *info; /* rcar_snd.h */
245 246 247 248 249
	int byte_pos;
	int period_pos;
	int byte_per_period;
	int next_period_byte;
};
250
#define rsnd_io_to_mod_ssi(io)	((io)->mod[RSND_MOD_SSI])
251
#define rsnd_io_to_mod_src(io)	((io)->mod[RSND_MOD_SRC])
K
Kuninori Morimoto 已提交
252
#define rsnd_io_to_mod_dvc(io)	((io)->mod[RSND_MOD_DVC])
253 254 255 256 257 258 259

struct rsnd_dai {
	char name[RSND_DAI_NAME_SIZE];
	struct rsnd_dai_platform_info *info; /* rcar_snd.h */
	struct rsnd_dai_stream playback;
	struct rsnd_dai_stream capture;

260 261 262 263 264
	unsigned int clk_master:1;
	unsigned int bit_clk_inv:1;
	unsigned int frm_clk_inv:1;
	unsigned int sys_delay:1;
	unsigned int data_alignment:1;
265 266
};

267
#define rsnd_rdai_nr(priv) ((priv)->rdai_nr)
268
#define for_each_rsnd_dai(rdai, priv, i)		\
269
	for (i = 0;					\
270
	     (i < rsnd_rdai_nr(priv)) &&		\
271 272
	     ((rdai) = rsnd_dai_get(priv, i));		\
	     i++)
273 274 275

struct rsnd_dai *rsnd_dai_get(struct rsnd_priv *priv, int id);
int rsnd_dai_is_play(struct rsnd_dai *rdai, struct rsnd_dai_stream *io);
276
int rsnd_dai_id(struct rsnd_priv *priv, struct rsnd_dai *rdai);
277
#define rsnd_dai_get_platform_info(rdai) ((rdai)->info)
278
#define rsnd_io_to_runtime(io) ((io)->substream->runtime)
279 280 281

void rsnd_dai_pointer_update(struct rsnd_dai_stream *io, int cnt);
int rsnd_dai_pointer_offset(struct rsnd_dai_stream *io, int additional);
282
#define rsnd_dai_is_clk_master(rdai) ((rdai)->clk_master)
283

284 285 286 287
/*
 *	R-Car Gen1/Gen2
 */
int rsnd_gen_probe(struct platform_device *pdev,
288
		   const struct rsnd_of_data *of_data,
289 290 291 292
		   struct rsnd_priv *priv);
void __iomem *rsnd_gen_reg_get(struct rsnd_priv *priv,
			       struct rsnd_mod *mod,
			       enum rsnd_reg reg);
293 294 295
dma_addr_t rsnd_gen_dma_addr(struct rsnd_priv *priv,
		       struct rsnd_mod *mod,
		       int is_play,  int is_from);
296

297 298
#define rsnd_is_gen1(s)		(((s)->info->flags & RSND_GEN_MASK) == RSND_GEN1)
#define rsnd_is_gen2(s)		(((s)->info->flags & RSND_GEN_MASK) == RSND_GEN2)
299

300 301 302 303 304 305
/*
 *	R-Car ADG
 */
int rsnd_adg_ssi_clk_stop(struct rsnd_mod *mod);
int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *mod, unsigned int rate);
int rsnd_adg_probe(struct platform_device *pdev,
306
		   const struct rsnd_of_data *of_data,
307
		   struct rsnd_priv *priv);
308 309 310 311
int rsnd_adg_set_convert_clk_gen1(struct rsnd_priv *priv,
				  struct rsnd_mod *mod,
				  unsigned int src_rate,
				  unsigned int dst_rate);
312 313 314 315 316 317 318 319
int rsnd_adg_set_convert_clk_gen2(struct rsnd_mod *mod,
				  struct rsnd_dai *rdai,
				  struct rsnd_dai_stream *io,
				  unsigned int src_rate,
				  unsigned int dst_rate);
int rsnd_adg_set_convert_timing_gen2(struct rsnd_mod *mod,
				     struct rsnd_dai *rdai,
				     struct rsnd_dai_stream *io);
K
Kuninori Morimoto 已提交
320 321 322
int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_dai *rdai,
				 struct rsnd_mod *mod,
				 struct rsnd_dai_stream *io);
323

324 325 326
/*
 *	R-Car sound priv
 */
327 328 329 330
struct rsnd_of_data {
	u32 flags;
};

331 332
struct rsnd_priv {

333
	struct platform_device *pdev;
334 335 336
	struct rcar_snd_info *info;
	spinlock_t lock;

337 338 339 340 341
	/*
	 * below value will be filled on rsnd_gen_probe()
	 */
	void *gen;

342
	/*
343
	 * below value will be filled on rsnd_src_probe()
344
	 */
345 346
	void *src;
	int src_nr;
347

348 349 350 351 352
	/*
	 * below value will be filled on rsnd_adg_probe()
	 */
	void *adg;

353 354 355
	/*
	 * below value will be filled on rsnd_ssi_probe()
	 */
356 357
	void *ssi;
	int ssi_nr;
358

K
Kuninori Morimoto 已提交
359 360 361 362 363 364
	/*
	 * below value will be filled on rsnd_dvc_probe()
	 */
	void *dvc;
	int dvc_nr;

365 366 367 368 369
	/*
	 * below value will be filled on rsnd_dai_probe()
	 */
	struct snd_soc_dai_driver *daidrv;
	struct rsnd_dai *rdai;
370
	int rdai_nr;
371 372
};

373 374
#define rsnd_priv_to_pdev(priv)	((priv)->pdev)
#define rsnd_priv_to_dev(priv)	(&(rsnd_priv_to_pdev(priv)->dev))
375
#define rsnd_priv_to_info(priv)	((priv)->info)
376 377 378
#define rsnd_lock(priv, flags) spin_lock_irqsave(&priv->lock, flags)
#define rsnd_unlock(priv, flags) spin_unlock_irqrestore(&priv->lock, flags)

379 380 381 382 383 384 385 386 387 388 389 390 391
#define rsnd_info_is_playback(priv, type)				\
({									\
	struct rcar_snd_info *info = rsnd_priv_to_info(priv);		\
	int i, is_play = 0;						\
	for (i = 0; i < info->dai_info_nr; i++) {			\
		if (info->dai_info[i].playback.type == (type)->info) {	\
			is_play = 1;					\
			break;						\
		}							\
	}								\
	is_play;							\
})

392
/*
393
 *	R-Car SRC
394
 */
395
int rsnd_src_probe(struct platform_device *pdev,
396
		   const struct rsnd_of_data *of_data,
397
		   struct rsnd_priv *priv);
398 399
struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id);
unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv,
400
				   struct rsnd_dai_stream *io,
401
				   struct snd_pcm_runtime *runtime);
402 403 404 405 406 407
int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod,
			struct rsnd_dai *rdai,
			int use_busif);
int rsnd_src_ssiu_stop(struct rsnd_mod *ssi_mod,
		       struct rsnd_dai *rdai,
		       int use_busif);
408
int rsnd_src_enable_ssi_irq(struct rsnd_mod *ssi_mod,
409
			    struct rsnd_dai *rdai);
410

411
#define rsnd_src_nr(priv) ((priv)->src_nr)
412

413 414 415 416
/*
 *	R-Car SSI
 */
int rsnd_ssi_probe(struct platform_device *pdev,
417
		   const struct rsnd_of_data *of_data,
418 419
		   struct rsnd_priv *priv);
struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id);
420
int rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod);
421

K
Kuninori Morimoto 已提交
422 423 424 425 426 427 428 429 430 431 432 433 434
/*
 *	R-Car DVC
 */
int rsnd_dvc_probe(struct platform_device *pdev,
		   const struct rsnd_of_data *of_data,
		   struct rsnd_priv *priv);
void rsnd_dvc_remove(struct platform_device *pdev,
		     struct rsnd_priv *priv);
struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id);

#define rsnd_dvc_nr(priv) ((priv)->dvc_nr)


435
#endif