From b22da3d8526a935aa31e086e63f60ff3246cb61c Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Sat, 09 Dec 2023 07:24:11 +0000
Subject: [PATCH] add stmac read mac form eeprom
---
kernel/sound/soc/rockchip/rockchip_pdm.c | 195 +++++++++++++++++++++++-------------------------
1 files changed, 94 insertions(+), 101 deletions(-)
diff --git a/kernel/sound/soc/rockchip/rockchip_pdm.c b/kernel/sound/soc/rockchip/rockchip_pdm.c
index 1a8ee0f..ae529a6 100644
--- a/kernel/sound/soc/rockchip/rockchip_pdm.c
+++ b/kernel/sound/soc/rockchip/rockchip_pdm.c
@@ -1,17 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Rockchip PDM ALSA SoC Digital Audio Interface(DAI) driver
*
* Copyright (C) 2017 Fuzhou Rockchip Electronics Co., Ltd
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
*/
#include <linux/module.h>
@@ -29,20 +20,23 @@
#include "rockchip_pdm.h"
#define PDM_DMA_BURST_SIZE (8) /* size * width: 8*4 = 32 bytes */
-#define PDM_SIGNOFF_CLK_RATE (100000000)
+#define PDM_SIGNOFF_CLK_100M (100000000)
+#define PDM_SIGNOFF_CLK_300M (300000000)
#define PDM_PATH_MAX (4)
-#define CLK_PPM_MIN (-1000)
-#define CLK_PPM_MAX (1000)
#define PDM_DEFAULT_RATE (48000)
#define PDM_START_DELAY_MS_DEFAULT (20)
#define PDM_START_DELAY_MS_MIN (0)
#define PDM_START_DELAY_MS_MAX (1000)
#define PDM_FILTER_DELAY_MS_MIN (20)
#define PDM_FILTER_DELAY_MS_MAX (1000)
+#define PDM_CLK_SHIFT_PPM_MAX (1000000) /* 1 ppm */
+#define CLK_PPM_MIN (-1000)
+#define CLK_PPM_MAX (1000)
enum rk_pdm_version {
+ RK_PDM_RK3229,
RK_PDM_RK3308,
- RK_PDM_RK3328,
+ RK_PDM_RK3588,
RK_PDM_RV1126,
};
@@ -101,9 +95,10 @@
};
static unsigned int get_pdm_clk(struct rk_pdm_dev *pdm, unsigned int sr,
- unsigned int *clk_src, unsigned int *clk_out)
+ unsigned int *clk_src, unsigned int *clk_out,
+ unsigned int signoff)
{
- unsigned int i, count, clk, div, rate;
+ unsigned int i, count, clk, div, rate, delta;
clk = 0;
if (!sr)
@@ -122,7 +117,9 @@
break;
}
rate = clk_round_rate(pdm->clk, clkref[i].clk);
- if (rate != clkref[i].clk)
+ delta = clkref[i].clk / PDM_CLK_SHIFT_PPM_MAX;
+ if (rate < clkref[i].clk - delta ||
+ rate > clkref[i].clk + delta)
continue;
clk = clkref[i].clk;
*clk_src = clkref[i].clk;
@@ -131,7 +128,7 @@
}
if (!clk) {
- clk = clk_round_rate(pdm->clk, PDM_SIGNOFF_CLK_RATE);
+ clk = clk_round_rate(pdm->clk, signoff);
*clk_src = clk;
}
return clk;
@@ -277,18 +274,20 @@
return ret;
}
-static int rockchip_pdm_set_samplerate(struct rk_pdm_dev *pdm,
- unsigned int samplerate)
+static int rockchip_pdm_set_samplerate(struct rk_pdm_dev *pdm, unsigned int samplerate)
{
- unsigned int clk_rate, clk_div;
- unsigned int clk_src, clk_out = 0;
- unsigned int val = 0, div = 0, rate, delta;
+
+ unsigned int val = 0, div = 0;
+ unsigned int clk_rate, clk_div, rate, delta;
+ unsigned int clk_src = 0, clk_out = 0, signoff = PDM_SIGNOFF_CLK_100M;
unsigned long m, n;
uint64_t ppm;
- int ret;
bool change;
+ int ret;
- clk_rate = get_pdm_clk(pdm, samplerate, &clk_src, &clk_out);
+ if (pdm->version == RK_PDM_RK3588)
+ signoff = PDM_SIGNOFF_CLK_300M;
+ clk_rate = get_pdm_clk(pdm, samplerate, &clk_src, &clk_out, signoff);
if (!clk_rate)
return -EINVAL;
@@ -325,6 +324,7 @@
return ret;
if (pdm->version == RK_PDM_RK3308 ||
+ pdm->version == RK_PDM_RK3588 ||
pdm->version == RK_PDM_RV1126) {
rational_best_approximation(clk_out, clk_src,
GENMASK(16 - 1, 0),
@@ -354,7 +354,7 @@
val);
}
- if (pdm->version == RK_PDM_RV1126) {
+ if (pdm->version == RK_PDM_RK3588 || pdm->version == RK_PDM_RV1126) {
val = get_pdm_cic_ratio(clk_out);
regmap_update_bits(pdm->regmap, PDM_CLK_CTRL, PDM_CIC_RATIO_MSK, val);
val = samplerate_to_bit(samplerate);
@@ -364,10 +364,11 @@
val = get_pdm_ds_ratio(samplerate);
regmap_update_bits(pdm->regmap, PDM_CLK_CTRL, PDM_DS_RATIO_MSK, val);
}
- regmap_update_bits(pdm->regmap, PDM_HPF_CTRL, PDM_HPF_CF_MSK, PDM_HPF_60HZ);
+
+ regmap_update_bits(pdm->regmap, PDM_HPF_CTRL,
+ PDM_HPF_CF_MSK, PDM_HPF_60HZ);
regmap_update_bits(pdm->regmap, PDM_HPF_CTRL,
PDM_HPF_LE | PDM_HPF_RE, PDM_HPF_LE | PDM_HPF_RE);
-
return 0;
}
@@ -383,7 +384,7 @@
rockchip_pdm_set_samplerate(pdm, params_rate(params));
- if (pdm->version != RK_PDM_RK3328)
+ if (pdm->version != RK_PDM_RK3229)
regmap_update_bits(pdm->regmap, PDM_CTRL0,
PDM_MODE_MSK, PDM_MODE_LJ);
@@ -411,13 +412,13 @@
switch (params_channels(params)) {
case 8:
val |= PDM_PATH3_EN;
- /* fallthrough */
+ fallthrough;
case 6:
val |= PDM_PATH2_EN;
- /* fallthrough */
+ fallthrough;
case 4:
val |= PDM_PATH1_EN;
- /* fallthrough */
+ fallthrough;
case 2:
val |= PDM_PATH0_EN;
break;
@@ -489,51 +490,6 @@
return ret;
}
-static int rockchip_pdm_clk_compensation_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = CLK_PPM_MIN;
- uinfo->value.integer.max = CLK_PPM_MAX;
- uinfo->value.integer.step = 1;
-
- return 0;
-}
-
-static int rockchip_pdm_clk_compensation_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
- struct rk_pdm_dev *pdm = snd_soc_dai_get_drvdata(dai);
-
- ucontrol->value.integer.value[0] = pdm->clk_ppm;
-
- return 0;
-}
-
-static int rockchip_pdm_clk_compensation_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
- struct rk_pdm_dev *pdm = snd_soc_dai_get_drvdata(dai);
- int ppm = ucontrol->value.integer.value[0];
-
- if ((ucontrol->value.integer.value[0] < CLK_PPM_MIN) ||
- (ucontrol->value.integer.value[0] > CLK_PPM_MAX))
- return -EINVAL;
-
- return rockchip_pdm_clk_set_rate(pdm, pdm->clk_root, pdm->clk_root_rate, ppm);
-}
-
-static struct snd_kcontrol_new rockchip_pdm_compensation_control = {
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "PCM Clk Compensation In PPM",
- .info = rockchip_pdm_clk_compensation_info,
- .get = rockchip_pdm_clk_compensation_get,
- .put = rockchip_pdm_clk_compensation_put,
-};
-
static int rockchip_pdm_start_delay_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{
@@ -544,7 +500,6 @@
uinfo->value.integer.step = 1;
return 0;
-
}
static int rockchip_pdm_start_delay_get(struct snd_kcontrol *kcontrol,
@@ -628,16 +583,64 @@
},
};
+static int rockchip_pdm_clk_compensation_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = 1;
+ uinfo->value.integer.min = CLK_PPM_MIN;
+ uinfo->value.integer.max = CLK_PPM_MAX;
+ uinfo->value.integer.step = 1;
+
+ return 0;
+}
+
+
+static int rockchip_pdm_clk_compensation_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+
+{
+ struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
+ struct rk_pdm_dev *pdm = snd_soc_dai_get_drvdata(dai);
+
+ ucontrol->value.integer.value[0] = pdm->clk_ppm;
+
+ return 0;
+}
+
+static int rockchip_pdm_clk_compensation_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
+ struct rk_pdm_dev *pdm = snd_soc_dai_get_drvdata(dai);
+
+ int ppm = ucontrol->value.integer.value[0];
+
+ if ((ucontrol->value.integer.value[0] < CLK_PPM_MIN) ||
+ (ucontrol->value.integer.value[0] > CLK_PPM_MAX))
+ return -EINVAL;
+
+ return rockchip_pdm_clk_set_rate(pdm, pdm->clk_root, pdm->clk_root_rate, ppm);
+}
+
+static struct snd_kcontrol_new rockchip_pdm_compensation_control = {
+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,
+ .name = "PDM PCM Clk Compensation In PPM",
+ .info = rockchip_pdm_clk_compensation_info,
+ .get = rockchip_pdm_clk_compensation_get,
+ .put = rockchip_pdm_clk_compensation_put,
+
+};
+
static int rockchip_pdm_dai_probe(struct snd_soc_dai *dai)
{
struct rk_pdm_dev *pdm = to_info(dai);
dai->capture_dma_data = &pdm->capture_dma_data;
-
- if (pdm->clk_calibrate)
- snd_soc_add_dai_controls(dai, &rockchip_pdm_compensation_control, 1);
snd_soc_add_dai_controls(dai, rockchip_pdm_controls,
ARRAY_SIZE(rockchip_pdm_controls));
+ if (pdm->clk_calibrate)
+ snd_soc_add_dai_controls(dai, &rockchip_pdm_compensation_control, 1);
return 0;
}
@@ -748,6 +751,7 @@
return ret;
}
+ rockchip_pdm_rxctrl(pdm, 0);
regcache_cache_only(pdm->regmap, false);
regcache_mark_dirty(pdm->regmap);
ret = regcache_sync(pdm->regmap);
@@ -844,31 +848,21 @@
.cache_type = REGCACHE_FLAT,
};
-static const struct of_device_id rockchip_pdm_match[] = {
-#ifdef CONFIG_CPU_PX30
+static const struct of_device_id rockchip_pdm_match[] __maybe_unused = {
+ { .compatible = "rockchip,pdm",
+ .data = (void *)RK_PDM_RK3229 },
{ .compatible = "rockchip,px30-pdm",
.data = (void *)RK_PDM_RK3308 },
-#endif
-#ifdef CONFIG_CPU_RK1808
{ .compatible = "rockchip,rk1808-pdm",
.data = (void *)RK_PDM_RK3308 },
-#endif
-#ifdef CONFIG_CPU_RK3308
{ .compatible = "rockchip,rk3308-pdm",
.data = (void *)RK_PDM_RK3308 },
-#endif
-#ifdef CONFIG_CPU_RK3328
- { .compatible = "rockchip,rk3328-pdm",
- .data = (void *)RK_PDM_RK3328 },
-#endif
-#ifdef CONFIG_CPU_RK3568
{ .compatible = "rockchip,rk3568-pdm",
.data = (void *)RK_PDM_RV1126 },
-#endif
-#ifdef CONFIG_CPU_RV1126
+ { .compatible = "rockchip,rk3588-pdm",
+ .data = (void *)RK_PDM_RK3588 },
{ .compatible = "rockchip,rv1126-pdm",
.data = (void *)RK_PDM_RV1126 },
-#endif
{},
};
MODULE_DEVICE_TABLE(of, rockchip_pdm_match);
@@ -923,8 +917,7 @@
return PTR_ERR(pdm->reset);
}
- 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);
@@ -940,6 +933,9 @@
pdm->dev = &pdev->dev;
dev_set_drvdata(&pdev->dev, pdm);
+ pdm->start_delay_ms = PDM_START_DELAY_MS_DEFAULT;
+ pdm->filter_delay_ms = PDM_FILTER_DELAY_MS_MIN;
+
pdm->clk_calibrate =
of_property_read_bool(node, "rockchip,mclk-calibrate");
if (pdm->clk_calibrate) {
@@ -950,9 +946,6 @@
pdm->clk_root_initial_rate = clk_get_rate(pdm->clk_root);
pdm->clk_root_rate = pdm->clk_root_initial_rate;
}
-
- pdm->start_delay_ms = PDM_START_DELAY_MS_DEFAULT;
- pdm->filter_delay_ms = PDM_FILTER_DELAY_MS_MIN;
pdm->clk = devm_clk_get(&pdev->dev, "pdm_clk");
if (IS_ERR(pdm->clk))
--
Gitblit v1.6.2