From 1f93a7dfd1f8d5ff7a5c53246c7534fe2332d6f4 Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Mon, 11 Dec 2023 02:46:07 +0000 Subject: [PATCH] add audio --- kernel/sound/soc/rockchip/rockchip_spdif.c | 48 +++++++++++++++++++++++++++++------------------- 1 files changed, 29 insertions(+), 19 deletions(-) diff --git a/kernel/sound/soc/rockchip/rockchip_spdif.c b/kernel/sound/soc/rockchip/rockchip_spdif.c index 80a2df2..af5203b 100644 --- a/kernel/sound/soc/rockchip/rockchip_spdif.c +++ b/kernel/sound/soc/rockchip/rockchip_spdif.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* sound/soc/rockchip/rk_spdif.c * * ALSA SoC Audio Layer - Rockchip I2S Controller driver @@ -6,10 +7,6 @@ * Author: Jianqun <jay.xu@rock-chips.com> * Copyright (c) 2015 Collabora Ltd. * Author: Sjoerd Simons <sjoerd.simons@collabora.co.uk> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #include <linux/module.h> @@ -63,7 +60,7 @@ struct regmap *regmap; }; -static const struct of_device_id rk_spdif_match[] = { +static const struct of_device_id rk_spdif_match[] __maybe_unused = { { .compatible = "rockchip,rk3066-spdif", .data = (void *)RK_SPDIF_RK3066 }, { .compatible = "rockchip,rk3188-spdif", @@ -81,6 +78,8 @@ { .compatible = "rockchip,rk3399-spdif", .data = (void *)RK_SPDIF_RK3366 }, { .compatible = "rockchip,rk3568-spdif", + .data = (void *)RK_SPDIF_RK3366 }, + { .compatible = "rockchip,rk3588-spdif", .data = (void *)RK_SPDIF_RK3366 }, {}, }; @@ -132,8 +131,8 @@ { struct rk_spdif_dev *spdif = snd_soc_dai_get_drvdata(dai); unsigned int val = SPDIF_CFGR_HALFWORD_ENABLE; - int srate, mclk; - int ret, i; + unsigned int mclk_rate = clk_get_rate(spdif->mclk); + int bmc, div, ret, i; u8 cs[CS_BYTE]; u16 *fc = (u16 *)cs; @@ -147,8 +146,10 @@ regmap_update_bits(spdif->regmap, SPDIF_CFGR, SPDIF_CFGR_CSE_MASK, SPDIF_CFGR_CSE_EN); - srate = params_rate(params); - mclk = srate * 128; + /* bmc = 128fs */ + bmc = 128 * params_rate(params); + div = DIV_ROUND_CLOSEST(mclk_rate, bmc); + val |= SPDIF_CFGR_CLK_DIV(div); switch (params_format(params)) { case SNDRV_PCM_FORMAT_S16_LE: @@ -169,16 +170,9 @@ return -EINVAL; } - /* Set clock and calculate divider */ - ret = clk_set_rate(spdif->mclk, mclk); - if (ret != 0) { - dev_err(spdif->dev, "Failed to set module clock rate: %d\n", - ret); - return ret; - } - regmap_update_bits(spdif->regmap, SPDIF_CFGR, SPDIF_CFGR_CLR_MASK, SPDIF_CFGR_CLR_EN); + udelay(1); ret = regmap_update_bits(spdif->regmap, SPDIF_CFGR, SPDIF_CFGR_CLK_DIV_MASK | @@ -243,7 +237,24 @@ return 0; } +static int rk_spdif_set_sysclk(struct snd_soc_dai *dai, + int clk_id, unsigned int freq, int dir) +{ + struct rk_spdif_dev *spdif = snd_soc_dai_get_drvdata(dai); + int ret = 0; + + if (!freq) + return 0; + + ret = clk_set_rate(spdif->mclk, freq); + if (ret) + dev_err(spdif->dev, "Failed to set mclk: %d\n", ret); + + return ret; +} + static const struct snd_soc_dai_ops rk_spdif_dai_ops = { + .set_sysclk = rk_spdif_set_sysclk, .hw_params = rk_spdif_hw_params, .trigger = rk_spdif_trigger, }; @@ -363,8 +374,7 @@ if (IS_ERR(spdif->mclk)) return PTR_ERR(spdif->mclk); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - regs = devm_ioremap_resource(&pdev->dev, res); + regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res); if (IS_ERR(regs)) return PTR_ERR(regs); -- Gitblit v1.6.2