···77 - model - the user-visible name of this sound complex88 - clocks - should contain entries matching clock names in the clock-names99 property1010- - clock-names - should contain following entries:1111- - "epll" - indicating the EPLL output clock1212- - "i2s_rclk" - indicating the RCLK (root) clock of the I2S0 controller1310 - samsung,audio-widgets - this property specifies off-codec audio elements1411 like headphones or speakers, for details see widgets.txt1512 - samsung,audio-routing - a list of the connections between audio···4245 "Headphone Jack", "HPR",4346 "IN1", "Mic Jack",4447 "Mic Jack", "MICBIAS";4545-4646- clocks = <&clock CLK_FOUT_EPLL>, <&i2s0 CLK_I2S_RCLK_SRC>;4747- clock-names = "epll", "sclk_i2s";48484949 cpu {5050 sound-dai = <&i2s0 0>;
-45
include/sound/rt5677.h
···11-/*22- * linux/sound/rt5677.h -- Platform data for RT567733- *44- * Copyright 2013 Realtek Semiconductor Corp.55- * Author: Oder Chiou <oder_chiou@realtek.com>66- *77- * This program is free software; you can redistribute it and/or modify88- * it under the terms of the GNU General Public License version 2 as99- * published by the Free Software Foundation.1010- */1111-1212-#ifndef __LINUX_SND_RT5677_H1313-#define __LINUX_SND_RT5677_H1414-1515-enum rt5677_dmic2_clk {1616- RT5677_DMIC_CLK1 = 0,1717- RT5677_DMIC_CLK2 = 1,1818-};1919-2020-2121-struct rt5677_platform_data {2222- /* IN1/IN2/LOUT1/LOUT2/LOUT3 can optionally be differential */2323- bool in1_diff;2424- bool in2_diff;2525- bool lout1_diff;2626- bool lout2_diff;2727- bool lout3_diff;2828- /* DMIC2 clock source selection */2929- enum rt5677_dmic2_clk dmic2_clk_pin;3030-3131- /* configures GPIO, 0 - floating, 1 - pulldown, 2 - pullup */3232- u8 gpio_config[6];3333-3434- /* jd1 can select 0 ~ 3 as OFF, GPIO1, GPIO2 and GPIO3 respectively */3535- unsigned int jd1_gpio;3636- /* jd2 and jd3 can select 0 ~ 3 as3737- OFF, GPIO4, GPIO5 and GPIO6 respectively */3838- unsigned int jd2_gpio;3939- unsigned int jd3_gpio;4040-4141- /* Set MICBIAS1 VDD 1v8 or 3v3 */4242- bool micbias1_vdd_3v3;4343-};4444-4545-#endif
···1919 struct snd_soc_card card;2020 struct snd_soc_dai_link dai_link;21212222- struct clk *pll;2323- struct clk *rclk;2222+ struct clk *clk_i2s_bus;2323+ struct clk *sclk_i2s;2424};25252626static int odroid_card_startup(struct snd_pcm_substream *substream)···5858 return -EINVAL;5959 }60606161- ret = clk_set_rate(priv->pll, pll_freq + 1);6161+ ret = clk_set_rate(priv->clk_i2s_bus, pll_freq / 2 + 1);6262 if (ret < 0)6363 return ret;64646565- rclk_freq = params_rate(params) * 256 * 4;6565+ /*6666+ * We add 1 to the rclk_freq value in order to avoid too low clock6767+ * frequency values due to the EPLL output frequency not being exact6868+ * multiple of the audio sampling rate.6969+ */7070+ rclk_freq = params_rate(params) * 256 + 1;66716767- ret = clk_set_rate(priv->rclk, rclk_freq);7272+ ret = clk_set_rate(priv->sclk_i2s, rclk_freq);6873 if (ret < 0)6974 return ret;7075···123118124119 snd_soc_card_set_drvdata(card, priv);125120126126- priv->pll = devm_clk_get(dev, "epll");127127- if (IS_ERR(priv->pll))128128- return PTR_ERR(priv->pll);129129-130130- priv->rclk = devm_clk_get(dev, "i2s_rclk");131131- if (IS_ERR(priv->rclk))132132- return PTR_ERR(priv->rclk);133133-134121 ret = snd_soc_of_parse_card_name(card, "model");135122 if (ret < 0)136123 return ret;···168171 link->name = "Primary";169172 link->stream_name = link->name;170173174174+175175+ priv->sclk_i2s = of_clk_get_by_name(link->cpu_of_node, "i2s_opclk1");176176+ if (IS_ERR(priv->sclk_i2s)) {177177+ ret = PTR_ERR(priv->sclk_i2s);178178+ goto err_put_i2s_n;179179+ }180180+181181+ priv->clk_i2s_bus = of_clk_get_by_name(link->cpu_of_node, "iis");182182+ if (IS_ERR(priv->clk_i2s_bus)) {183183+ ret = PTR_ERR(priv->clk_i2s_bus);184184+ goto err_put_sclk;185185+ }186186+171187 ret = devm_snd_soc_register_card(dev, card);172188 if (ret < 0) {173189 dev_err(dev, "snd_soc_register_card() failed: %d\n", ret);174174- goto err_put_i2s_n;190190+ goto err_put_clk_i2s;175191 }176192177193 return 0;178194195195+err_put_clk_i2s:196196+ clk_put(priv->clk_i2s_bus);197197+err_put_sclk:198198+ clk_put(priv->sclk_i2s);179199err_put_i2s_n:180200 of_node_put(link->cpu_of_node);181201err_put_codec_n:···206192207193 of_node_put(priv->dai_link.cpu_of_node);208194 odroid_put_codec_of_nodes(&priv->dai_link);195195+ clk_put(priv->sclk_i2s);196196+ clk_put(priv->clk_i2s_bus);209197210198 return 0;211199}
+6-2
sound/soc/samsung/pcm.c
···522522 dev_err(&pdev->dev, "failed to get audio-bus clock\n");523523 return PTR_ERR(pcm->cclk);524524 }525525- clk_prepare_enable(pcm->cclk);525525+ ret = clk_prepare_enable(pcm->cclk);526526+ if (ret)527527+ return ret;526528527529 /* record our pcm structure for later use in the callbacks */528530 dev_set_drvdata(&pdev->dev, pcm);···535533 ret = PTR_ERR(pcm->pclk);536534 goto err_dis_cclk;537535 }538538- clk_prepare_enable(pcm->pclk);536536+ ret = clk_prepare_enable(pcm->pclk);537537+ if (ret)538538+ goto err_dis_cclk;539539540540 s3c_pcm_stereo_in[pdev->id].addr = mem_res->start + S3C_PCM_RXFIFO;541541 s3c_pcm_stereo_out[pdev->id].addr = mem_res->start + S3C_PCM_TXFIFO;
+11-3
sound/soc/samsung/s3c-i2s-v2.c
···27272828#undef S3C_IIS_V2_SUPPORTED29293030-#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413) \3030+#if defined(CONFIG_CPU_S3C2412) \3131 || defined(CONFIG_ARCH_S3C64XX) || defined(CONFIG_CPU_S5PV210)3232#define S3C_IIS_V2_SUPPORTED3333#endif···634634 i2s->iis_pclk = clk_get(dev, "iis");635635 if (IS_ERR(i2s->iis_pclk)) {636636 dev_err(dev, "failed to get iis_clock\n");637637- iounmap(i2s->regs);638637 return -ENOENT;639638 }640639641641- clk_enable(i2s->iis_pclk);640640+ clk_prepare_enable(i2s->iis_pclk);642641643642 /* Mark ourselves as in TXRX mode so we can run through our cleanup644643 * process without warnings. */···650651 return 0;651652}652653EXPORT_SYMBOL_GPL(s3c_i2sv2_probe);654654+655655+void s3c_i2sv2_cleanup(struct snd_soc_dai *dai,656656+ struct s3c_i2sv2_info *i2s)657657+{658658+ clk_disable_unprepare(i2s->iis_pclk);659659+ clk_put(i2s->iis_pclk);660660+ i2s->iis_pclk = NULL;661661+}662662+EXPORT_SYMBOL_GPL(s3c_i2sv2_cleanup);653663654664#ifdef CONFIG_PM655665static int s3c2412_i2s_suspend(struct snd_soc_dai *dai)
+7
sound/soc/samsung/s3c-i2s-v2.h
···9292 unsigned long base);93939494/**9595+ * s3c_i2sv2_cleanup - cleanup resources allocated in s3c_i2sv2_probe9696+ * @dai: The ASoC DAI structure supplied to the original probe.9797+ * @i2s: Our local i2s structure to fill in.9898+ */9999+extern void s3c_i2sv2_cleanup(struct snd_soc_dai *dai,100100+ struct s3c_i2sv2_info *i2s);101101+/**95102 * s3c_i2sv2_register_component - register component and dai with soc core96103 * @dev: DAI device97104 * @id: DAI ID
+11-4
sound/soc/samsung/s3c2412-i2s.c
···6565 s3c2412_i2s.iis_cclk = devm_clk_get(dai->dev, "i2sclk");6666 if (IS_ERR(s3c2412_i2s.iis_cclk)) {6767 pr_err("failed to get i2sclk clock\n");6868- return PTR_ERR(s3c2412_i2s.iis_cclk);6868+ ret = PTR_ERR(s3c2412_i2s.iis_cclk);6969+ goto err;6970 }70717172 /* Set MPLL as the source for IIS CLK */72737374 clk_set_parent(s3c2412_i2s.iis_cclk, clk_get(NULL, "mpll"));7474- clk_prepare_enable(s3c2412_i2s.iis_cclk);7575-7676- s3c2412_i2s.iis_cclk = s3c2412_i2s.iis_pclk;7575+ ret = clk_prepare_enable(s3c2412_i2s.iis_cclk);7676+ if (ret)7777+ goto err;77787879 /* Configure the I2S pins (GPE0...GPE4) in correct mode */7980 s3c_gpio_cfgall_range(S3C2410_GPE(0), 5, S3C_GPIO_SFN(2),8081 S3C_GPIO_PULL_NONE);81828283 return 0;8484+8585+err:8686+ s3c_i2sv2_cleanup(dai, &s3c2412_i2s);8787+8888+ return ret;8389}84908591static int s3c2412_i2s_remove(struct snd_soc_dai *dai)8692{8793 clk_disable_unprepare(s3c2412_i2s.iis_cclk);9494+ s3c_i2sv2_cleanup(dai, &s3c2412_i2s);88958996 return 0;9097}
+9-2
sound/soc/samsung/s3c24xx-i2s.c
···340340341341static int s3c24xx_i2s_probe(struct snd_soc_dai *dai)342342{343343+ int ret;343344 snd_soc_dai_init_dma_data(dai, &s3c24xx_i2s_pcm_stereo_out,344345 &s3c24xx_i2s_pcm_stereo_in);345346···349348 pr_err("failed to get iis_clock\n");350349 return PTR_ERR(s3c24xx_i2s.iis_clk);351350 }352352- clk_prepare_enable(s3c24xx_i2s.iis_clk);351351+ ret = clk_prepare_enable(s3c24xx_i2s.iis_clk);352352+ if (ret)353353+ return ret;353354354355 /* Configure the I2S pins (GPE0...GPE4) in correct mode */355356 s3c_gpio_cfgall_range(S3C2410_GPE(0), 5, S3C_GPIO_SFN(2),···380377381378static int s3c24xx_i2s_resume(struct snd_soc_dai *cpu_dai)382379{383383- clk_prepare_enable(s3c24xx_i2s.iis_clk);380380+ int ret;381381+382382+ ret = clk_prepare_enable(s3c24xx_i2s.iis_clk);383383+ if (ret)384384+ return ret;384385385386 writel(s3c24xx_i2s.iiscon, s3c24xx_i2s.regs + S3C2410_IISCON);386387 writel(s3c24xx_i2s.iismod, s3c24xx_i2s.regs + S3C2410_IISMOD);
···391391 ret = -ENOENT;392392 goto err0;393393 }394394- clk_prepare_enable(spdif->pclk);394394+ ret = clk_prepare_enable(spdif->pclk);395395+ if (ret)396396+ goto err0;395397396398 spdif->sclk = devm_clk_get(&pdev->dev, "sclk_spdif");397399 if (IS_ERR(spdif->sclk)) {···401399 ret = -ENOENT;402400 goto err1;403401 }404404- clk_prepare_enable(spdif->sclk);402402+ ret = clk_prepare_enable(spdif->sclk);403403+ if (ret)404404+ goto err1;405405406406 /* Request S/PDIF Register's memory region */407407 if (!request_mem_region(mem_res->start,