src.c (f36a82264d5a4ba90f093d397d65b7fdc763885a) src.c (e8e7b7bdc65c19f8d84c25f7e0d21176d598c870)
1/*
2 * Renesas R-Car SRC 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

--- 296 unchanged lines hidden (view full) ---

305
306static int rsnd_src_stop(struct rsnd_mod *mod)
307{
308 /* nothing to do */
309 return 0;
310}
311
312/*
1/*
2 * Renesas R-Car SRC 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

--- 296 unchanged lines hidden (view full) ---

305
306static int rsnd_src_stop(struct rsnd_mod *mod)
307{
308 /* nothing to do */
309 return 0;
310}
311
312/*
313 * Gen1 functions
314 */
315static int rsnd_src_set_route_gen1(struct rsnd_dai_stream *io,
316 struct rsnd_mod *mod)
317{
318 struct src_route_config {
319 u32 mask;
320 int shift;
321 } routes[] = {
322 { 0xF, 0, }, /* 0 */
323 { 0xF, 4, }, /* 1 */
324 { 0xF, 8, }, /* 2 */
325 { 0x7, 12, }, /* 3 */
326 { 0x7, 16, }, /* 4 */
327 { 0x7, 20, }, /* 5 */
328 { 0x7, 24, }, /* 6 */
329 { 0x3, 28, }, /* 7 */
330 { 0x3, 30, }, /* 8 */
331 };
332 u32 mask;
333 u32 val;
334 int id;
335
336 id = rsnd_mod_id(mod);
337 if (id < 0 || id >= ARRAY_SIZE(routes))
338 return -EIO;
339
340 /*
341 * SRC_ROUTE_SELECT
342 */
343 val = rsnd_io_is_play(io) ? 0x1 : 0x2;
344 val = val << routes[id].shift;
345 mask = routes[id].mask << routes[id].shift;
346
347 rsnd_mod_bset(mod, SRC_ROUTE_SEL, mask, val);
348
349 return 0;
350}
351
352static int rsnd_src_set_convert_timing_gen1(struct rsnd_dai_stream *io,
353 struct rsnd_mod *mod)
354{
355 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
356 struct rsnd_src *src = rsnd_mod_to_src(mod);
357 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
358 u32 convert_rate = rsnd_src_convert_rate(io, src);
359 u32 mask;
360 u32 val;
361 int shift;
362 int id = rsnd_mod_id(mod);
363 int ret;
364
365 /*
366 * SRC_TIMING_SELECT
367 */
368 shift = (id % 4) * 8;
369 mask = 0x1F << shift;
370
371 /*
372 * ADG is used as source clock if SRC was used,
373 * then, SSI WS is used as destination clock.
374 * SSI WS is used as source clock if SRC is not used
375 * (when playback, source/destination become reverse when capture)
376 */
377 ret = 0;
378 if (convert_rate) {
379 /* use ADG */
380 val = 0;
381 ret = rsnd_adg_set_convert_clk_gen1(priv, mod,
382 runtime->rate,
383 convert_rate);
384 } else if (8 == id) {
385 /* use SSI WS, but SRU8 is special */
386 val = id << shift;
387 } else {
388 /* use SSI WS */
389 val = (id + 1) << shift;
390 }
391
392 if (ret < 0)
393 return ret;
394
395 switch (id / 4) {
396 case 0:
397 rsnd_mod_bset(mod, SRC_TMG_SEL0, mask, val);
398 break;
399 case 1:
400 rsnd_mod_bset(mod, SRC_TMG_SEL1, mask, val);
401 break;
402 case 2:
403 rsnd_mod_bset(mod, SRC_TMG_SEL2, mask, val);
404 break;
405 }
406
407 return 0;
408}
409
410static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod,
411 struct rsnd_dai_stream *io)
412{
413 struct rsnd_src *src = rsnd_mod_to_src(mod);
414 int ret;
415
416 ret = rsnd_src_set_convert_rate(mod, io);
417 if (ret < 0)
418 return ret;
419
420 /* Select SRC mode (fixed value) */
421 rsnd_mod_write(mod, SRC_SRCCR, 0x00010110);
422
423 /* Set the restriction value of the FS ratio (98%) */
424 rsnd_mod_write(mod, SRC_MNFSR,
425 rsnd_mod_read(mod, SRC_IFSVR) / 100 * 98);
426
427 /* Gen1/Gen2 are not compatible */
428 if (rsnd_src_convert_rate(io, src))
429 rsnd_mod_write(mod, SRC_ROUTE_MODE0, 1);
430
431 /* no SRC_BFSSR settings, since SRC_SRCCR::BUFMD is 0 */
432
433 return 0;
434}
435
436static int rsnd_src_init_gen1(struct rsnd_mod *mod,
437 struct rsnd_dai_stream *io,
438 struct rsnd_priv *priv)
439{
440 int ret;
441
442 ret = rsnd_src_init(mod, priv);
443 if (ret < 0)
444 return ret;
445
446 ret = rsnd_src_set_route_gen1(io, mod);
447 if (ret < 0)
448 return ret;
449
450 ret = rsnd_src_set_convert_rate_gen1(mod, io);
451 if (ret < 0)
452 return ret;
453
454 ret = rsnd_src_set_convert_timing_gen1(io, mod);
455 if (ret < 0)
456 return ret;
457
458 return 0;
459}
460
461static int rsnd_src_start_gen1(struct rsnd_mod *mod,
462 struct rsnd_dai_stream *io,
463 struct rsnd_priv *priv)
464{
465 int id = rsnd_mod_id(mod);
466
467 rsnd_mod_bset(mod, SRC_ROUTE_CTRL, (1 << id), (1 << id));
468
469 return rsnd_src_start(mod);
470}
471
472static int rsnd_src_stop_gen1(struct rsnd_mod *mod,
473 struct rsnd_dai_stream *io,
474 struct rsnd_priv *priv)
475{
476 int id = rsnd_mod_id(mod);
477
478 rsnd_mod_bset(mod, SRC_ROUTE_CTRL, (1 << id), 0);
479
480 return rsnd_src_stop(mod);
481}
482
483static struct rsnd_mod_ops rsnd_src_gen1_ops = {
484 .name = SRC_NAME,
485 .dma_req = rsnd_src_dma_req,
486 .init = rsnd_src_init_gen1,
487 .quit = rsnd_src_quit,
488 .start = rsnd_src_start_gen1,
489 .stop = rsnd_src_stop_gen1,
490 .hw_params = rsnd_src_hw_params,
491};
492
493/*
494 * Gen2 functions
495 */
496#define rsnd_src_irq_enable_gen2(mod) rsnd_src_irq_ctrol_gen2(mod, 1)
497#define rsnd_src_irq_disable_gen2(mod) rsnd_src_irq_ctrol_gen2(mod, 0)
498static void rsnd_src_irq_ctrol_gen2(struct rsnd_mod *mod, int enable)
499{
500 struct rsnd_src *src = rsnd_mod_to_src(mod);
501 u32 sys_int_val, int_val, sys_int_mask;

--- 420 unchanged lines hidden (view full) ---

922
923int rsnd_src_probe(struct platform_device *pdev,
924 const struct rsnd_of_data *of_data,
925 struct rsnd_priv *priv)
926{
927 struct rcar_snd_info *info = rsnd_priv_to_info(priv);
928 struct device *dev = rsnd_priv_to_dev(priv);
929 struct rsnd_src *src;
313 * Gen2 functions
314 */
315#define rsnd_src_irq_enable_gen2(mod) rsnd_src_irq_ctrol_gen2(mod, 1)
316#define rsnd_src_irq_disable_gen2(mod) rsnd_src_irq_ctrol_gen2(mod, 0)
317static void rsnd_src_irq_ctrol_gen2(struct rsnd_mod *mod, int enable)
318{
319 struct rsnd_src *src = rsnd_mod_to_src(mod);
320 u32 sys_int_val, int_val, sys_int_mask;

--- 420 unchanged lines hidden (view full) ---

741
742int rsnd_src_probe(struct platform_device *pdev,
743 const struct rsnd_of_data *of_data,
744 struct rsnd_priv *priv)
745{
746 struct rcar_snd_info *info = rsnd_priv_to_info(priv);
747 struct device *dev = rsnd_priv_to_dev(priv);
748 struct rsnd_src *src;
930 struct rsnd_mod_ops *ops;
931 struct clk *clk;
932 char name[RSND_SRC_NAME_SIZE];
933 int i, nr, ret;
934
749 struct clk *clk;
750 char name[RSND_SRC_NAME_SIZE];
751 int i, nr, ret;
752
935 ops = NULL;
936 if (rsnd_is_gen1(priv)) {
937 ops = &rsnd_src_gen1_ops;
938 dev_warn(dev, "Gen1 support will be removed soon\n");
939 }
940 if (rsnd_is_gen2(priv))
941 ops = &rsnd_src_gen2_ops;
942 if (!ops) {
943 dev_err(dev, "unknown Generation\n");
944 return -EIO;
945 }
753 /* This driver doesn't support Gen1 at this point */
754 if (rsnd_is_gen1(priv))
755 return 0;
946
947 rsnd_of_parse_src(pdev, of_data, priv);
948
949 /*
950 * init SRC
951 */
952 nr = info->src_info_nr;
953 if (!nr)

--- 11 unchanged lines hidden (view full) ---

965 SRC_NAME, i);
966
967 clk = devm_clk_get(dev, name);
968 if (IS_ERR(clk))
969 return PTR_ERR(clk);
970
971 src->info = &info->src_info[i];
972
756
757 rsnd_of_parse_src(pdev, of_data, priv);
758
759 /*
760 * init SRC
761 */
762 nr = info->src_info_nr;
763 if (!nr)

--- 11 unchanged lines hidden (view full) ---

775 SRC_NAME, i);
776
777 clk = devm_clk_get(dev, name);
778 if (IS_ERR(clk))
779 return PTR_ERR(clk);
780
781 src->info = &info->src_info[i];
782
973 ret = rsnd_mod_init(priv, rsnd_mod_get(src), ops, clk, RSND_MOD_SRC, i);
783 ret = rsnd_mod_init(priv, rsnd_mod_get(src),
784 &rsnd_src_gen2_ops, clk, RSND_MOD_SRC, i);
974 if (ret)
975 return ret;
976 }
977
978 return 0;
979}
980
981void rsnd_src_remove(struct platform_device *pdev,
982 struct rsnd_priv *priv)
983{
984 struct rsnd_src *src;
985 int i;
986
987 for_each_rsnd_src(src, priv, i) {
988 rsnd_mod_quit(rsnd_mod_get(src));
989 }
990}
785 if (ret)
786 return ret;
787 }
788
789 return 0;
790}
791
792void rsnd_src_remove(struct platform_device *pdev,
793 struct rsnd_priv *priv)
794{
795 struct rsnd_src *src;
796 int i;
797
798 for_each_rsnd_src(src, priv, i) {
799 rsnd_mod_quit(rsnd_mod_get(src));
800 }
801}