blob: 8cc36416da25ccec910dad709b21de9a0c75bd25 [file] [log] [blame]
Kuninori Morimoto1536a962013-07-21 21:35:52 -07001/*
2 * Renesas R-Car
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#ifndef RSND_H
12#define RSND_H
13
14#include <linux/clk.h>
15#include <linux/device.h>
16#include <linux/io.h>
17#include <linux/list.h>
18#include <linux/module.h>
19#include <sound/rcar_snd.h>
20#include <sound/soc.h>
21#include <sound/pcm_params.h>
22
23/*
24 * pseudo register
25 *
26 * The register address offsets SRU/SCU/SSIU on Gen1/Gen2 are very different.
27 * This driver uses pseudo register in order to hide it.
28 * see gen1/gen2 for detail
29 */
Kuninori Morimoto33377442013-07-21 21:36:21 -070030enum rsnd_reg {
31 RSND_REG_MAX,
32};
33
Kuninori Morimoto1536a962013-07-21 21:35:52 -070034struct rsnd_priv;
Kuninori Morimotocdaa3cd2013-07-21 21:36:03 -070035struct rsnd_mod;
Kuninori Morimoto1536a962013-07-21 21:35:52 -070036struct rsnd_dai;
37struct rsnd_dai_stream;
38
39/*
Kuninori Morimoto33377442013-07-21 21:36:21 -070040 * R-Car basic functions
41 */
42#define rsnd_mod_read(m, r) \
43 rsnd_read(rsnd_mod_to_priv(m), m, RSND_REG_##r)
44#define rsnd_mod_write(m, r, d) \
45 rsnd_write(rsnd_mod_to_priv(m), m, RSND_REG_##r, d)
46#define rsnd_mod_bset(m, r, s, d) \
47 rsnd_bset(rsnd_mod_to_priv(m), m, RSND_REG_##r, s, d)
48
49#define rsnd_priv_read(p, r) rsnd_read(p, NULL, RSND_REG_##r)
50#define rsnd_priv_write(p, r, d) rsnd_write(p, NULL, RSND_REG_##r, d)
51#define rsnd_priv_bset(p, r, s, d) rsnd_bset(p, NULL, RSND_REG_##r, s, d)
52
53u32 rsnd_read(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg);
54void rsnd_write(struct rsnd_priv *priv, struct rsnd_mod *mod,
55 enum rsnd_reg reg, u32 data);
56void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg,
57 u32 mask, u32 data);
58
59/*
Kuninori Morimotocdaa3cd2013-07-21 21:36:03 -070060 * R-Car sound mod
61 */
62
63struct rsnd_mod_ops {
64 char *name;
65 int (*init)(struct rsnd_mod *mod,
66 struct rsnd_dai *rdai,
67 struct rsnd_dai_stream *io);
68 int (*quit)(struct rsnd_mod *mod,
69 struct rsnd_dai *rdai,
70 struct rsnd_dai_stream *io);
71 int (*start)(struct rsnd_mod *mod,
72 struct rsnd_dai *rdai,
73 struct rsnd_dai_stream *io);
74 int (*stop)(struct rsnd_mod *mod,
75 struct rsnd_dai *rdai,
76 struct rsnd_dai_stream *io);
77};
78
79struct rsnd_mod {
80 int id;
81 struct rsnd_priv *priv;
82 struct rsnd_mod_ops *ops;
83 struct list_head list; /* connect to rsnd_dai playback/capture */
84};
85
86#define rsnd_mod_to_priv(mod) ((mod)->priv)
87#define rsnd_mod_id(mod) ((mod)->id)
88#define for_each_rsnd_mod(pos, n, io) \
89 list_for_each_entry_safe(pos, n, &(io)->head, list)
90#define rsnd_mod_call(mod, func, rdai, io) \
91 (!(mod) ? -ENODEV : \
92 !((mod)->ops->func) ? 0 : \
93 (mod)->ops->func(mod, rdai, io))
94
95void rsnd_mod_init(struct rsnd_priv *priv,
96 struct rsnd_mod *mod,
97 struct rsnd_mod_ops *ops,
98 int id);
99char *rsnd_mod_name(struct rsnd_mod *mod);
100
101/*
Kuninori Morimoto1536a962013-07-21 21:35:52 -0700102 * R-Car sound DAI
103 */
104#define RSND_DAI_NAME_SIZE 16
105struct rsnd_dai_stream {
106 struct list_head head; /* head of rsnd_mod list */
107 struct snd_pcm_substream *substream;
108 int byte_pos;
109 int period_pos;
110 int byte_per_period;
111 int next_period_byte;
112};
113
114struct rsnd_dai {
115 char name[RSND_DAI_NAME_SIZE];
116 struct rsnd_dai_platform_info *info; /* rcar_snd.h */
117 struct rsnd_dai_stream playback;
118 struct rsnd_dai_stream capture;
119
120 int clk_master:1;
121 int bit_clk_inv:1;
122 int frm_clk_inv:1;
123 int sys_delay:1;
124 int data_alignment:1;
125};
126
127#define rsnd_dai_nr(priv) ((priv)->dai_nr)
128#define for_each_rsnd_dai(rdai, priv, i) \
129 for (i = 0, (rdai) = rsnd_dai_get(priv, i); \
130 i < rsnd_dai_nr(priv); \
131 i++, (rdai) = rsnd_dai_get(priv, i))
132
133struct rsnd_dai *rsnd_dai_get(struct rsnd_priv *priv, int id);
Kuninori Morimotocdaa3cd2013-07-21 21:36:03 -0700134int rsnd_dai_disconnect(struct rsnd_mod *mod);
135int rsnd_dai_connect(struct rsnd_dai *rdai, struct rsnd_mod *mod,
136 struct rsnd_dai_stream *io);
Kuninori Morimoto1536a962013-07-21 21:35:52 -0700137int rsnd_dai_is_play(struct rsnd_dai *rdai, struct rsnd_dai_stream *io);
138#define rsnd_dai_get_platform_info(rdai) ((rdai)->info)
139
140void rsnd_dai_pointer_update(struct rsnd_dai_stream *io, int cnt);
141int rsnd_dai_pointer_offset(struct rsnd_dai_stream *io, int additional);
142
143/*
Kuninori Morimoto33377442013-07-21 21:36:21 -0700144 * R-Car Gen1/Gen2
145 */
146int rsnd_gen_probe(struct platform_device *pdev,
147 struct rcar_snd_info *info,
148 struct rsnd_priv *priv);
149void rsnd_gen_remove(struct platform_device *pdev,
150 struct rsnd_priv *priv);
151int rsnd_gen_path_init(struct rsnd_priv *priv,
152 struct rsnd_dai *rdai,
153 struct rsnd_dai_stream *io);
154int rsnd_gen_path_exit(struct rsnd_priv *priv,
155 struct rsnd_dai *rdai,
156 struct rsnd_dai_stream *io);
157void __iomem *rsnd_gen_reg_get(struct rsnd_priv *priv,
158 struct rsnd_mod *mod,
159 enum rsnd_reg reg);
160
161/*
Kuninori Morimoto1536a962013-07-21 21:35:52 -0700162 * R-Car sound priv
163 */
164struct rsnd_priv {
165
166 struct device *dev;
167 struct rcar_snd_info *info;
168 spinlock_t lock;
169
170 /*
Kuninori Morimoto33377442013-07-21 21:36:21 -0700171 * below value will be filled on rsnd_gen_probe()
172 */
173 void *gen;
174
175 /*
Kuninori Morimoto1536a962013-07-21 21:35:52 -0700176 * below value will be filled on rsnd_dai_probe()
177 */
178 struct snd_soc_dai_driver *daidrv;
179 struct rsnd_dai *rdai;
180 int dai_nr;
181};
182
183#define rsnd_priv_to_dev(priv) ((priv)->dev)
184#define rsnd_lock(priv, flags) spin_lock_irqsave(&priv->lock, flags)
185#define rsnd_unlock(priv, flags) spin_unlock_irqrestore(&priv->lock, flags)
186
187#endif