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} |