adg.c 10.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/*
 * Helper routines for R-Car sound ADG.
 *
 *  Copyright (C) 2013  Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 */
#include "rsnd.h"

#define CLKA	0
#define CLKB	1
#define CLKC	2
#define CLKI	3
#define CLKMAX	4

18 19 20 21
static struct rsnd_mod_ops adg_ops = {
	.name = "adg",
};

22 23
struct rsnd_adg {
	struct clk *clk[CLKMAX];
24
	struct rsnd_mod mod;
25

26 27
	int rbga_rate_for_441khz_div_6;	/* RBGA */
	int rbgb_rate_for_48khz_div_6;	/* RBGB */
28 29 30
};

#define for_each_rsnd_clk(pos, adg, i)		\
31 32 33 34
	for (i = 0;				\
	     (i < CLKMAX) &&			\
	     ((pos) = adg->clk[i]);		\
	     i++)
35 36
#define rsnd_priv_to_adg(priv) ((struct rsnd_adg *)(priv)->adg)

37

38
static u32 rsnd_adg_ssi_ws_timing_gen2(struct rsnd_dai_stream *io)
39
{
40
	struct rsnd_mod *mod = rsnd_io_to_mod_ssi(io);
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
	int id = rsnd_mod_id(mod);
	int ws = id;

	if (rsnd_ssi_is_pin_sharing(rsnd_ssi_mod_get(priv, id))) {
		switch (id) {
		case 1:
		case 2:
			ws = 0;
			break;
		case 4:
			ws = 3;
			break;
		case 8:
			ws = 7;
			break;
		}
	}

	return (0x6 + ws) << 8;
}

63
int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_mod *mod,
K
Kuninori Morimoto 已提交
64 65
				 struct rsnd_dai_stream *io)
{
66 67 68
	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
	struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
	struct rsnd_mod *adg_mod = rsnd_mod_get(adg);
K
Kuninori Morimoto 已提交
69 70 71 72 73 74 75 76 77
	int id = rsnd_mod_id(mod);
	int shift = (id % 2) ? 16 : 0;
	u32 mask, val;

	val = rsnd_adg_ssi_ws_timing_gen2(io);

	val  = val	<< shift;
	mask = 0xffff	<< shift;

78
	rsnd_mod_bset(adg_mod, CMDOUT_TIMSEL, mask, val);
K
Kuninori Morimoto 已提交
79 80 81 82

	return 0;
}

83
static int rsnd_adg_set_src_timsel_gen2(struct rsnd_mod *src_mod,
84 85 86
					struct rsnd_dai_stream *io,
					u32 timsel)
{
87
	struct rsnd_priv *priv = rsnd_mod_to_priv(src_mod);
88 89
	struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
	struct rsnd_mod *adg_mod = rsnd_mod_get(adg);
90
	int is_play = rsnd_io_is_play(io);
91
	int id = rsnd_mod_id(src_mod);
92 93 94 95
	int shift = (id % 2) ? 16 : 0;
	u32 mask, ws;
	u32 in, out;

96 97
	rsnd_mod_confirm_src(src_mod);

98
	ws = rsnd_adg_ssi_ws_timing_gen2(io);
99 100 101 102 103 104 105 106 107 108

	in  = (is_play) ? timsel : ws;
	out = (is_play) ? ws     : timsel;

	in   = in	<< shift;
	out  = out	<< shift;
	mask = 0xffff	<< shift;

	switch (id / 2) {
	case 0:
109 110
		rsnd_mod_bset(adg_mod, SRCIN_TIMSEL0,  mask, in);
		rsnd_mod_bset(adg_mod, SRCOUT_TIMSEL0, mask, out);
111 112
		break;
	case 1:
113 114
		rsnd_mod_bset(adg_mod, SRCIN_TIMSEL1,  mask, in);
		rsnd_mod_bset(adg_mod, SRCOUT_TIMSEL1, mask, out);
115 116
		break;
	case 2:
117 118
		rsnd_mod_bset(adg_mod, SRCIN_TIMSEL2,  mask, in);
		rsnd_mod_bset(adg_mod, SRCOUT_TIMSEL2, mask, out);
119 120
		break;
	case 3:
121 122
		rsnd_mod_bset(adg_mod, SRCIN_TIMSEL3,  mask, in);
		rsnd_mod_bset(adg_mod, SRCOUT_TIMSEL3, mask, out);
123 124
		break;
	case 4:
125 126
		rsnd_mod_bset(adg_mod, SRCIN_TIMSEL4,  mask, in);
		rsnd_mod_bset(adg_mod, SRCOUT_TIMSEL4, mask, out);
127 128 129 130 131 132
		break;
	}

	return 0;
}

133
int rsnd_adg_set_convert_clk_gen2(struct rsnd_mod *src_mod,
134 135 136 137
				  struct rsnd_dai_stream *io,
				  unsigned int src_rate,
				  unsigned int dst_rate)
{
138
	struct rsnd_priv *priv = rsnd_mod_to_priv(src_mod);
139
	struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
140
	struct rsnd_mod *adg_mod = rsnd_mod_get(adg);
141
	struct device *dev = rsnd_priv_to_dev(priv);
142 143
	int idx, sel, div, step, ret;
	u32 val, en;
144 145 146 147 148 149 150 151 152
	unsigned int min, diff;
	unsigned int sel_rate [] = {
		clk_get_rate(adg->clk[CLKA]),	/* 0000: CLKA */
		clk_get_rate(adg->clk[CLKB]),	/* 0001: CLKB */
		clk_get_rate(adg->clk[CLKC]),	/* 0010: CLKC */
		adg->rbga_rate_for_441khz_div_6,/* 0011: RBGA */
		adg->rbgb_rate_for_48khz_div_6,	/* 0100: RBGB */
	};

153 154
	rsnd_mod_confirm_src(src_mod);

155 156
	min = ~0;
	val = 0;
157
	en = 0;
158 159 160 161 162 163 164 165 166 167 168 169
	for (sel = 0; sel < ARRAY_SIZE(sel_rate); sel++) {
		idx = 0;
		step = 2;

		if (!sel_rate[sel])
			continue;

		for (div = 2; div <= 98304; div += step) {
			diff = abs(src_rate - sel_rate[sel] / div);
			if (min > diff) {
				val = (sel << 8) | idx;
				min = diff;
170
				en = 1 << (sel + 1); /* fixme */
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
			}

			/*
			 * step of 0_0000 / 0_0001 / 0_1101
			 * are out of order
			 */
			if ((idx > 2) && (idx % 2))
				step *= 2;
			if (idx == 0x1c) {
				div += step;
				step *= 2;
			}
			idx++;
		}
	}

	if (min == ~0) {
		dev_err(dev, "no Input clock\n");
		return -EIO;
	}

192
	ret = rsnd_adg_set_src_timsel_gen2(src_mod, io, val);
193 194 195 196 197
	if (ret < 0) {
		dev_err(dev, "timsel error\n");
		return ret;
	}

198
	rsnd_mod_bset(adg_mod, DIV_EN, en, en);
199

200 201
	dev_dbg(dev, "convert rate %d <-> %d\n", src_rate, dst_rate);

202
	return 0;
203 204
}

205
int rsnd_adg_set_convert_timing_gen2(struct rsnd_mod *src_mod,
206 207
				     struct rsnd_dai_stream *io)
{
208
	u32 val = rsnd_adg_ssi_ws_timing_gen2(io);
209

210 211 212
	rsnd_mod_confirm_src(src_mod);

	return rsnd_adg_set_src_timsel_gen2(src_mod, io, val);
213 214
}

215 216 217 218
int rsnd_adg_set_convert_clk_gen1(struct rsnd_priv *priv,
				  struct rsnd_mod *mod,
				  unsigned int src_rate,
				  unsigned int dst_rate)
219 220
{
	struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
221
	struct rsnd_mod *adg_mod = rsnd_mod_get(adg);
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257
	struct device *dev = rsnd_priv_to_dev(priv);
	int idx, sel, div, shift;
	u32 mask, val;
	int id = rsnd_mod_id(mod);
	unsigned int sel_rate [] = {
		clk_get_rate(adg->clk[CLKA]),	/* 000: CLKA */
		clk_get_rate(adg->clk[CLKB]),	/* 001: CLKB */
		clk_get_rate(adg->clk[CLKC]),	/* 010: CLKC */
		0,				/* 011: MLBCLK (not used) */
		adg->rbga_rate_for_441khz_div_6,/* 100: RBGA */
		adg->rbgb_rate_for_48khz_div_6,	/* 101: RBGB */
	};

	/* find div (= 1/128, 1/256, 1/512, 1/1024, 1/2048 */
	for (sel = 0; sel < ARRAY_SIZE(sel_rate); sel++) {
		for (div  = 128,	idx = 0;
		     div <= 2048;
		     div *= 2,		idx++) {
			if (src_rate == sel_rate[sel] / div) {
				val = (idx << 4) | sel;
				goto find_rate;
			}
		}
	}
	dev_err(dev, "can't find convert src clk\n");
	return -EINVAL;

find_rate:
	shift	= (id % 4) * 8;
	mask	= 0xFF << shift;
	val	= val << shift;

	dev_dbg(dev, "adg convert src clk = %02x\n", val);

	switch (id / 4) {
	case 0:
258
		rsnd_mod_bset(adg_mod, AUDIO_CLK_SEL3, mask, val);
259 260
		break;
	case 1:
261
		rsnd_mod_bset(adg_mod, AUDIO_CLK_SEL4, mask, val);
262 263
		break;
	case 2:
264
		rsnd_mod_bset(adg_mod, AUDIO_CLK_SEL5, mask, val);
265 266 267 268 269 270 271 272 273 274 275 276
		break;
	}

	/*
	 * Gen1 doesn't need dst_rate settings,
	 * since it uses SSI WS pin.
	 * see also rsnd_src_set_route_if_gen1()
	 */

	return 0;
}

277
static void rsnd_adg_set_ssi_clk(struct rsnd_mod *ssi_mod, u32 val)
278
{
279
	struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod);
280 281
	struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
	struct rsnd_mod *adg_mod = rsnd_mod_get(adg);
282
	int id = rsnd_mod_id(ssi_mod);
283 284 285
	int shift = (id % 4) * 8;
	u32 mask = 0xFF << shift;

286 287
	rsnd_mod_confirm_ssi(ssi_mod);

288
	val = val << shift;
289 290 291 292 293 294

	/*
	 * SSI 8 is not connected to ADG.
	 * it works with SSI 7
	 */
	if (id == 8)
295 296 297 298
		return;

	switch (id / 4) {
	case 0:
299
		rsnd_mod_bset(adg_mod, AUDIO_CLK_SEL0, mask, val);
300 301
		break;
	case 1:
302
		rsnd_mod_bset(adg_mod, AUDIO_CLK_SEL1, mask, val);
303 304
		break;
	case 2:
305
		rsnd_mod_bset(adg_mod, AUDIO_CLK_SEL2, mask, val);
306 307
		break;
	}
308 309 310 311 312 313 314 315
}

int rsnd_adg_ssi_clk_stop(struct rsnd_mod *mod)
{
	/*
	 * "mod" = "ssi" here.
	 * we can get "ssi id" from mod
	 */
316
	rsnd_adg_set_ssi_clk(mod, 0);
317 318 319 320 321 322 323 324 325 326

	return 0;
}

int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *mod, unsigned int rate)
{
	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
	struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
	struct device *dev = rsnd_priv_to_dev(priv);
	struct clk *clk;
327
	int i;
328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352
	u32 data;
	int sel_table[] = {
		[CLKA] = 0x1,
		[CLKB] = 0x2,
		[CLKC] = 0x3,
		[CLKI] = 0x0,
	};

	dev_dbg(dev, "request clock = %d\n", rate);

	/*
	 * find suitable clock from
	 * AUDIO_CLKA/AUDIO_CLKB/AUDIO_CLKC/AUDIO_CLKI.
	 */
	data = 0;
	for_each_rsnd_clk(clk, adg, i) {
		if (rate == clk_get_rate(clk)) {
			data = sel_table[i];
			goto found_clock;
		}
	}

	/*
	 * find 1/6 clock from BRGA/BRGB
	 */
353
	if (rate == adg->rbga_rate_for_441khz_div_6) {
354 355 356 357
		data = 0x10;
		goto found_clock;
	}

358
	if (rate == adg->rbgb_rate_for_48khz_div_6) {
359 360 361 362 363 364 365 366 367 368 369 370
		data = 0x20;
		goto found_clock;
	}

	return -EIO;

found_clock:

	/*
	 * This "mod" = "ssi" here.
	 * we can get "ssi id" from mod
	 */
371
	rsnd_adg_set_ssi_clk(mod, data);
372

373 374
	dev_dbg(dev, "ADG: ssi%d selects clk%d = %d",
		rsnd_mod_id(mod), i, rate);
375 376 377 378 379 380 381

	return 0;
}

static void rsnd_adg_ssi_clk_init(struct rsnd_priv *priv, struct rsnd_adg *adg)
{
	struct clk *clk;
382
	struct rsnd_mod *adg_mod = rsnd_mod_get(adg);
383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401
	unsigned long rate;
	u32 ckr;
	int i;
	int brg_table[] = {
		[CLKA] = 0x0,
		[CLKB] = 0x1,
		[CLKC] = 0x4,
		[CLKI] = 0x2,
	};

	/*
	 * This driver is assuming that AUDIO_CLKA/AUDIO_CLKB/AUDIO_CLKC
	 * have 44.1kHz or 48kHz base clocks for now.
	 *
	 * SSI itself can divide parent clock by 1/1 - 1/16
	 * So,  BRGA outputs 44.1kHz base parent clock 1/32,
	 * and, BRGB outputs 48.0kHz base parent clock 1/32 here.
	 * see
	 *	rsnd_adg_ssi_clk_try_start()
402
	 *	rsnd_ssi_master_clk_start()
403 404
	 */
	ckr = 0;
405 406
	adg->rbga_rate_for_441khz_div_6 = 0;
	adg->rbgb_rate_for_48khz_div_6  = 0;
407 408 409 410 411 412 413
	for_each_rsnd_clk(clk, adg, i) {
		rate = clk_get_rate(clk);

		if (0 == rate) /* not used */
			continue;

		/* RBGA */
414 415
		if (!adg->rbga_rate_for_441khz_div_6 && (0 == rate % 44100)) {
			adg->rbga_rate_for_441khz_div_6 = rate / 6;
416 417 418 419
			ckr |= brg_table[i] << 20;
		}

		/* RBGB */
420 421
		if (!adg->rbgb_rate_for_48khz_div_6 && (0 == rate % 48000)) {
			adg->rbgb_rate_for_48khz_div_6 = rate / 6;
422 423 424 425
			ckr |= brg_table[i] << 16;
		}
	}

426 427 428
	rsnd_mod_bset(adg_mod, SSICKR, 0x00FF0000, ckr);
	rsnd_mod_write(adg_mod, BRRA,  0x00000002); /* 1/6 */
	rsnd_mod_write(adg_mod, BRRB,  0x00000002); /* 1/6 */
429 430 431
}

int rsnd_adg_probe(struct platform_device *pdev,
432
		   const struct rsnd_of_data *of_data,
433 434 435 436
		   struct rsnd_priv *priv)
{
	struct rsnd_adg *adg;
	struct device *dev = rsnd_priv_to_dev(priv);
437
	struct clk *clk;
438 439 440 441 442 443 444 445
	int i;

	adg = devm_kzalloc(dev, sizeof(*adg), GFP_KERNEL);
	if (!adg) {
		dev_err(dev, "ADG allocate failed\n");
		return -ENOMEM;
	}

446 447 448 449 450 451 452 453
	/*
	 * ADG is special module.
	 * Use ADG mod without rsnd_mod_init() to make debug easy
	 * for rsnd_write/rsnd_read
	 */
	adg->mod.ops = &adg_ops;
	adg->mod.priv = priv;

454 455 456 457
	adg->clk[CLKA]	= devm_clk_get(dev, "clk_a");
	adg->clk[CLKB]	= devm_clk_get(dev, "clk_b");
	adg->clk[CLKC]	= devm_clk_get(dev, "clk_c");
	adg->clk[CLKI]	= devm_clk_get(dev, "clk_i");
458

459
	for_each_rsnd_clk(clk, adg, i)
460
		dev_dbg(dev, "clk %d : %p : %ld\n", i, clk, clk_get_rate(clk));
461 462 463 464 465 466 467

	rsnd_adg_ssi_clk_init(priv, adg);

	priv->adg = adg;

	return 0;
}