[alsa-devel] [PATCH 1/3] ASoC: rt5640: Add RL6231 class device shared support for RT5640, RT5645 and RT5651
The patch adds the RL6231 class device shared support for RT5640, RT5645 and RT5651. The function of the DMIC clock calculation can be shared by RL6231 shared support.
Signed-off-by: Oder Chiou oder_chiou@realtek.com --- sound/soc/codecs/Kconfig | 9 +++++++ sound/soc/codecs/Makefile | 2 ++ sound/soc/codecs/rl6231.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++ sound/soc/codecs/rl6231.h | 18 +++++++++++++ sound/soc/codecs/rt5640.c | 23 ++++------------ sound/soc/codecs/rt5645.c | 22 +++------------- sound/soc/codecs/rt5651.c | 22 ++++------------ 7 files changed, 110 insertions(+), 53 deletions(-) create mode 100644 sound/soc/codecs/rl6231.c create mode 100644 sound/soc/codecs/rl6231.h
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 4f96b97..6951381 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -402,6 +402,15 @@ config SND_SOC_PCM512x_SPI select SND_SOC_PCM512x select REGMAP_SPI
+config SND_SOC_RL6231 + tristate + default y if SND_SOC_RT5640=y + default y if SND_SOC_RT5645=y + default y if SND_SOC_RT5651=y + default m if SND_SOC_RT5640=m + default m if SND_SOC_RT5645=m + default m if SND_SOC_RT5651=m + config SND_SOC_RT5631 tristate
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 1ccdaf0..d1e913a 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -60,6 +60,7 @@ snd-soc-pcm3008-objs := pcm3008.o snd-soc-pcm512x-objs := pcm512x.o snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o snd-soc-pcm512x-spi-objs := pcm512x-spi.o +snd-soc-rl6231-objs := rl6231.o snd-soc-rt5631-objs := rt5631.o snd-soc-rt5640-objs := rt5640.o snd-soc-rt5645-objs := rt5645.o @@ -216,6 +217,7 @@ obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o obj-$(CONFIG_SND_SOC_PCM512x) += snd-soc-pcm512x.o obj-$(CONFIG_SND_SOC_PCM512x_I2C) += snd-soc-pcm512x-i2c.o obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o +obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o obj-$(CONFIG_SND_SOC_RT5645) += snd-soc-rt5645.o diff --git a/sound/soc/codecs/rl6231.c b/sound/soc/codecs/rl6231.c new file mode 100644 index 0000000..13ac551 --- /dev/null +++ b/sound/soc/codecs/rl6231.c @@ -0,0 +1,67 @@ +/* + * rl6231.c - RL6231 class device shared support + * + * Copyright 2014 Realtek Semiconductor Corp. + * + * Author: Oder Chiou oder_chiou@realtek.com + * + * 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> +#include <linux/moduleparam.h> +#include <linux/init.h> +#include <linux/delay.h> +#include <linux/pm.h> +#include <linux/gpio.h> +#include <linux/i2c.h> +#include <linux/regmap.h> +#include <linux/of.h> +#include <linux/of_gpio.h> +#include <linux/platform_device.h> +#include <linux/spi/spi.h> +#include <linux/acpi.h> +#include <sound/core.h> +#include <sound/pcm.h> +#include <sound/pcm_params.h> +#include <sound/soc.h> +#include <sound/soc-dapm.h> +#include <sound/initval.h> +#include <sound/tlv.h> + +#include "rl6231.h" + +/** + * rl6231_calc_dmic_clk - Calculate the parameter of dmic. + * + * @rate: base clock rate. + * + * Choose dmic clock between 1MHz and 3MHz. + * It is better for clock to approximate 3MHz. + */ +int rl6231_calc_dmic_clk(int rate) +{ + int div[] = {2, 3, 4, 6, 8, 12}, idx = -EINVAL; + int i, red, bound, temp; + + red = 3000000 * 12; + for (i = 0; i < ARRAY_SIZE(div); i++) { + bound = div[i] * 3000000; + if (rate > bound) + continue; + temp = bound - rate; + if (temp < red) { + red = temp; + idx = i; + } + } + + return idx; +} +EXPORT_SYMBOL_GPL(rl6231_calc_dmic_clk); + +MODULE_DESCRIPTION("RL6231 class device shared support"); +MODULE_AUTHOR("Oder Chiou oder_chiou@realtek.com"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/rl6231.h b/sound/soc/codecs/rl6231.h new file mode 100644 index 0000000..00032db --- /dev/null +++ b/sound/soc/codecs/rl6231.h @@ -0,0 +1,18 @@ +/* + * rl6231.h - RL6231 class device shared support + * + * Copyright 2014 Realtek Semiconductor Corp. + * + * Author: Oder Chiou oder_chiou@realtek.com + * + * 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. + */ + +#ifndef __RL6231_H__ +#define __RL6231_H__ + +int rl6231_calc_dmic_clk(int rate); + +#endif /* __RL6231_H__ */ diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index 9e0d48f..0cefc16 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c @@ -31,6 +31,7 @@ #include <sound/initval.h> #include <sound/tlv.h>
+#include "rl6231.h" #include "rt5640.h"
#define RT5640_DEVICE_ID 0x6231 @@ -453,30 +454,16 @@ static const struct snd_kcontrol_new rt5640_specific_snd_controls[] = { * @kcontrol: The kcontrol of this widget. * @event: Event id. * - * Choose dmic clock between 1MHz and 3MHz. - * It is better for clock to approximate 3MHz. */ static int set_dmic_clk(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { struct snd_soc_codec *codec = w->codec; struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec); - int div[] = {2, 3, 4, 6, 8, 12}; - int idx = -EINVAL, i; - int rate, red, bound, temp; - - rate = rt5640->sysclk; - red = 3000000 * 12; - for (i = 0; i < ARRAY_SIZE(div); i++) { - bound = div[i] * 3000000; - if (rate > bound) - continue; - temp = bound - rate; - if (temp < red) { - red = temp; - idx = i; - } - } + int idx = -EINVAL; + + idx = rl6231_calc_dmic_clk(rt5640->sysclk); + if (idx < 0) dev_err(codec->dev, "Failed to set DMIC clock\n"); else diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index ab97d72..caa5519 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -26,6 +26,7 @@ #include <sound/initval.h> #include <sound/tlv.h>
+#include "rl6231.h" #include "rt5645.h"
#define RT5645_DEVICE_ID 0x6308 @@ -519,30 +520,15 @@ static const struct snd_kcontrol_new rt5645_snd_controls[] = { * @kcontrol: The kcontrol of this widget. * @event: Event id. * - * Choose dmic clock between 1MHz and 3MHz. - * It is better for clock to approximate 3MHz. */ static int set_dmic_clk(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { struct snd_soc_codec *codec = w->codec; struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); - int div[] = {2, 3, 4, 6, 8, 12}; - int idx = -EINVAL, i; - int rate, red, bound, temp; - - rate = rt5645->sysclk; - red = 3000000 * 12; - for (i = 0; i < ARRAY_SIZE(div); i++) { - bound = div[i] * 3000000; - if (rate > bound) - continue; - temp = bound - rate; - if (temp < red) { - red = temp; - idx = i; - } - } + int idx = -EINVAL; + + idx = rl6231_calc_dmic_clk(rt5645->sysclk);
if (idx < 0) dev_err(codec->dev, "Failed to set DMIC clock\n"); diff --git a/sound/soc/codecs/rt5651.c b/sound/soc/codecs/rt5651.c index 9c88d89..7a7bec6 100644 --- a/sound/soc/codecs/rt5651.c +++ b/sound/soc/codecs/rt5651.c @@ -26,6 +26,7 @@ #include <sound/initval.h> #include <sound/tlv.h>
+#include "rl6231.h" #include "rt5651.h"
#define RT5651_DEVICE_ID_VALUE 0x6281 @@ -371,29 +372,16 @@ static const struct snd_kcontrol_new rt5651_snd_controls[] = { * @kcontrol: The kcontrol of this widget. * @event: Event id. * - * Choose dmic clock between 1MHz and 3MHz. - * It is better for clock to approximate 3MHz. */ static int set_dmic_clk(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { struct snd_soc_codec *codec = w->codec; struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec); - int div[] = {2, 3, 4, 6, 8, 12}, idx = -EINVAL; - int i, rate, red, bound, temp; - - rate = rt5651->sysclk; - red = 3000000 * 12; - for (i = 0; i < ARRAY_SIZE(div); i++) { - bound = div[i] * 3000000; - if (rate > bound) - continue; - temp = bound - rate; - if (temp < red) { - red = temp; - idx = i; - } - } + int idx = -EINVAL; + + idx = rl6231_calc_dmic_clk(rt5651->sysclk); + if (idx < 0) dev_err(codec->dev, "Failed to set DMIC clock\n"); else
The patch adds the function of the PLL clock calculation to RL6231 shared support.
Signed-off-by: Oder Chiou oder_chiou@realtek.com --- sound/soc/codecs/rl6231.c | 69 +++++++++++++++++++++++++++++++++++++++++++++ sound/soc/codecs/rl6231.h | 15 ++++++++++ sound/soc/codecs/rt5640.c | 68 ++++++-------------------------------------- sound/soc/codecs/rt5640.h | 8 ------ sound/soc/codecs/rt5645.c | 72 ++--------------------------------------------- sound/soc/codecs/rt5645.h | 7 ----- sound/soc/codecs/rt5651.c | 68 ++++++-------------------------------------- sound/soc/codecs/rt5651.h | 1 - 8 files changed, 102 insertions(+), 206 deletions(-)
diff --git a/sound/soc/codecs/rl6231.c b/sound/soc/codecs/rl6231.c index 13ac551..289024b 100644 --- a/sound/soc/codecs/rl6231.c +++ b/sound/soc/codecs/rl6231.c @@ -62,6 +62,75 @@ int rl6231_calc_dmic_clk(int rate) } EXPORT_SYMBOL_GPL(rl6231_calc_dmic_clk);
+/** + * rl6231_pll_calc - Calcualte PLL M/N/K code. + * @freq_in: external clock provided to codec. + * @freq_out: target clock which codec works on. + * @pll_code: Pointer to structure with M, N, K and bypass flag. + * + * Calcualte M/N/K code to configure PLL for codec. + * + * Returns 0 for success or negative error code. + */ +int rl6231_pll_calc(const unsigned int freq_in, + const unsigned int freq_out, struct rl6231_pll_code *pll_code) +{ + int max_n = RL6231_PLL_N_MAX, max_m = RL6231_PLL_M_MAX; + int k, red, n_t, pll_out, in_t, out_t; + int n = 0, m = 0, m_t = 0; + int red_t = abs(freq_out - freq_in); + bool bypass = false; + + if (RL6231_PLL_INP_MAX < freq_in || RL6231_PLL_INP_MIN > freq_in) + return -EINVAL; + + k = 100000000 / freq_out - 2; + if (k > RL6231_PLL_K_MAX) + k = RL6231_PLL_K_MAX; + for (n_t = 0; n_t <= max_n; n_t++) { + in_t = freq_in / (k + 2); + pll_out = freq_out / (n_t + 2); + if (in_t < 0) + continue; + if (in_t == pll_out) { + bypass = true; + n = n_t; + goto code_find; + } + red = abs(in_t - pll_out); + if (red < red_t) { + bypass = true; + n = n_t; + m = m_t; + if (red == 0) + goto code_find; + red_t = red; + } + for (m_t = 0; m_t <= max_m; m_t++) { + out_t = in_t / (m_t + 2); + red = abs(out_t - pll_out); + if (red < red_t) { + bypass = false; + n = n_t; + m = m_t; + if (red == 0) + goto code_find; + red_t = red; + } + } + } + pr_debug("Only get approximation about PLL\n"); + +code_find: + + pll_code->m_bp = bypass; + pll_code->m_code = m; + pll_code->n_code = n; + pll_code->k_code = k; + return 0; +} +EXPORT_SYMBOL_GPL(rl6231_pll_calc); + MODULE_DESCRIPTION("RL6231 class device shared support"); MODULE_AUTHOR("Oder Chiou oder_chiou@realtek.com"); MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/rl6231.h b/sound/soc/codecs/rl6231.h index 00032db..efdfc86 100644 --- a/sound/soc/codecs/rl6231.h +++ b/sound/soc/codecs/rl6231.h @@ -13,6 +13,21 @@ #ifndef __RL6231_H__ #define __RL6231_H__
+#define RL6231_PLL_INP_MAX 40000000 +#define RL6231_PLL_INP_MIN 256000 +#define RL6231_PLL_N_MAX 0x1ff +#define RL6231_PLL_K_MAX 0x1f +#define RL6231_PLL_M_MAX 0xf + +struct rl6231_pll_code { + bool m_bp; /* Indicates bypass m code or not. */ + int m_code; + int n_code; + int k_code; +}; + int rl6231_calc_dmic_clk(int rate); +int rl6231_pll_calc(const unsigned int freq_in, + const unsigned int freq_out, struct rl6231_pll_code *pll_code);
#endif /* __RL6231_H__ */ diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index 0cefc16..bdc1a94 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c @@ -1807,65 +1807,12 @@ static int rt5640_set_dai_sysclk(struct snd_soc_dai *dai, return 0; }
-/** - * rt5640_pll_calc - Calculate PLL M/N/K code. - * @freq_in: external clock provided to codec. - * @freq_out: target clock which codec works on. - * @pll_code: Pointer to structure with M, N, K and bypass flag. - * - * Calculate M/N/K code to configure PLL for codec. And K is assigned to 2 - * which make calculation more efficiently. - * - * Returns 0 for success or negative error code. - */ -static int rt5640_pll_calc(const unsigned int freq_in, - const unsigned int freq_out, struct rt5640_pll_code *pll_code) -{ - int max_n = RT5640_PLL_N_MAX, max_m = RT5640_PLL_M_MAX; - int n = 0, m = 0, red, n_t, m_t, in_t, out_t; - int red_t = abs(freq_out - freq_in); - bool bypass = false; - - if (RT5640_PLL_INP_MAX < freq_in || RT5640_PLL_INP_MIN > freq_in) - return -EINVAL; - - for (n_t = 0; n_t <= max_n; n_t++) { - in_t = (freq_in >> 1) + (freq_in >> 2) * n_t; - if (in_t < 0) - continue; - if (in_t == freq_out) { - bypass = true; - n = n_t; - goto code_find; - } - for (m_t = 0; m_t <= max_m; m_t++) { - out_t = in_t / (m_t + 2); - red = abs(out_t - freq_out); - if (red < red_t) { - n = n_t; - m = m_t; - if (red == 0) - goto code_find; - red_t = red; - } - } - } - pr_debug("Only get approximation about PLL\n"); - -code_find: - pll_code->m_bp = bypass; - pll_code->m_code = m; - pll_code->n_code = n; - pll_code->k_code = 2; - return 0; -} - static int rt5640_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source, unsigned int freq_in, unsigned int freq_out) { struct snd_soc_codec *codec = dai->codec; struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec); - struct rt5640_pll_code *pll_code = &rt5640->pll_code; + struct rl6231_pll_code pll_code; int ret, dai_sel;
if (source == rt5640->pll_src && freq_in == rt5640->pll_in && @@ -1909,20 +1856,21 @@ static int rt5640_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source, return -EINVAL; }
- ret = rt5640_pll_calc(freq_in, freq_out, pll_code); + ret = rl6231_pll_calc(freq_in, freq_out, &pll_code); if (ret < 0) { dev_err(codec->dev, "Unsupport input clock %d\n", freq_in); return ret; }
- dev_dbg(codec->dev, "bypass=%d m=%d n=%d k=2\n", pll_code->m_bp, - (pll_code->m_bp ? 0 : pll_code->m_code), pll_code->n_code); + dev_dbg(codec->dev, "bypass=%d m=%d n=%d k=%d\n", + pll_code.m_bp, (pll_code.m_bp ? 0 : pll_code.m_code), + pll_code.n_code, pll_code.k_code);
snd_soc_write(codec, RT5640_PLL_CTRL1, - pll_code->n_code << RT5640_PLL_N_SFT | pll_code->k_code); + pll_code.n_code << RT5640_PLL_N_SFT | pll_code.k_code); snd_soc_write(codec, RT5640_PLL_CTRL2, - (pll_code->m_bp ? 0 : pll_code->m_code) << RT5640_PLL_M_SFT | - pll_code->m_bp << RT5640_PLL_M_BP_SFT); + (pll_code.m_bp ? 0 : pll_code.m_code) << RT5640_PLL_M_SFT | + pll_code.m_bp << RT5640_PLL_M_BP_SFT);
rt5640->pll_in = freq_in; rt5640->pll_out = freq_out; diff --git a/sound/soc/codecs/rt5640.h b/sound/soc/codecs/rt5640.h index 895ca14..58ebe96 100644 --- a/sound/soc/codecs/rt5640.h +++ b/sound/soc/codecs/rt5640.h @@ -2079,13 +2079,6 @@ enum { RT5640_DMIC2, };
-struct rt5640_pll_code { - bool m_bp; /* Indicates bypass m code or not. */ - int m_code; - int n_code; - int k_code; -}; - struct rt5640_priv { struct snd_soc_codec *codec; struct rt5640_platform_data pdata; @@ -2097,7 +2090,6 @@ struct rt5640_priv { int bclk[RT5640_AIFS]; int master[RT5640_AIFS];
- struct rt5640_pll_code pll_code; int pll_src; int pll_in; int pll_out; diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index caa5519..ee6db7c 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -1964,80 +1964,12 @@ static int rt5645_set_dai_sysclk(struct snd_soc_dai *dai, return 0; }
-/** - * rt5645_pll_calc - Calcualte PLL M/N/K code. - * @freq_in: external clock provided to codec. - * @freq_out: target clock which codec works on. - * @pll_code: Pointer to structure with M, N, K and bypass flag. - * - * Calcualte M/N/K code to configure PLL for codec. And K is assigned to 2 - * which make calculation more efficiently. - * - * Returns 0 for success or negative error code. - */ -static int rt5645_pll_calc(const unsigned int freq_in, - const unsigned int freq_out, struct rt5645_pll_code *pll_code) -{ - int max_n = RT5645_PLL_N_MAX, max_m = RT5645_PLL_M_MAX; - int k, n = 0, m = 0, red, n_t, m_t, pll_out, in_t, out_t; - int red_t = abs(freq_out - freq_in); - bool bypass = false; - - if (RT5645_PLL_INP_MAX < freq_in || RT5645_PLL_INP_MIN > freq_in) - return -EINVAL; - - k = 100000000 / freq_out - 2; - if (k > RT5645_PLL_K_MAX) - k = RT5645_PLL_K_MAX; - for (n_t = 0; n_t <= max_n; n_t++) { - in_t = freq_in / (k + 2); - pll_out = freq_out / (n_t + 2); - if (in_t < 0) - continue; - if (in_t == pll_out) { - bypass = true; - n = n_t; - goto code_find; - } - red = abs(in_t - pll_out); - if (red < red_t) { - bypass = true; - n = n_t; - m = m_t; - if (red == 0) - goto code_find; - red_t = red; - } - for (m_t = 0; m_t <= max_m; m_t++) { - out_t = in_t / (m_t + 2); - red = abs(out_t - pll_out); - if (red < red_t) { - bypass = false; - n = n_t; - m = m_t; - if (red == 0) - goto code_find; - red_t = red; - } - } - } - pr_debug("Only get approximation about PLL\n"); - -code_find: - - pll_code->m_bp = bypass; - pll_code->m_code = m; - pll_code->n_code = n; - pll_code->k_code = k; - return 0; -} - static int rt5645_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source, unsigned int freq_in, unsigned int freq_out) { struct snd_soc_codec *codec = dai->codec; struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); - struct rt5645_pll_code pll_code; + struct rl6231_pll_code pll_code; int ret;
if (source == rt5645->pll_src && freq_in == rt5645->pll_in && @@ -2080,7 +2012,7 @@ static int rt5645_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source, return -EINVAL; }
- ret = rt5645_pll_calc(freq_in, freq_out, &pll_code); + ret = rl6231_pll_calc(freq_in, freq_out, &pll_code); if (ret < 0) { dev_err(codec->dev, "Unsupport input clock %d\n", freq_in); return ret; diff --git a/sound/soc/codecs/rt5645.h b/sound/soc/codecs/rt5645.h index 345aa3f..355b7e9 100644 --- a/sound/soc/codecs/rt5645.h +++ b/sound/soc/codecs/rt5645.h @@ -2162,13 +2162,6 @@ enum { RT5645_DMIC_DATA_GPIO11, };
-struct rt5645_pll_code { - bool m_bp; /* Indicates bypass m code or not. */ - int m_code; - int n_code; - int k_code; -}; - struct rt5645_priv { struct snd_soc_codec *codec; struct rt5645_platform_data pdata; diff --git a/sound/soc/codecs/rt5651.c b/sound/soc/codecs/rt5651.c index 7a7bec6..a627a1f 100644 --- a/sound/soc/codecs/rt5651.c +++ b/sound/soc/codecs/rt5651.c @@ -1516,65 +1516,12 @@ static int rt5651_set_dai_sysclk(struct snd_soc_dai *dai, return 0; }
-/** - * rt5651_pll_calc - Calcualte PLL M/N/K code. - * @freq_in: external clock provided to codec. - * @freq_out: target clock which codec works on. - * @pll_code: Pointer to structure with M, N, K and bypass flag. - * - * Calcualte M/N/K code to configure PLL for codec. And K is assigned to 2 - * which make calculation more efficiently. - * - * Returns 0 for success or negative error code. - */ -static int rt5651_pll_calc(const unsigned int freq_in, - const unsigned int freq_out, struct rt5651_pll_code *pll_code) -{ - int max_n = RT5651_PLL_N_MAX, max_m = RT5651_PLL_M_MAX; - int n = 0, m = 0, red, n_t, m_t, in_t, out_t; - int red_t = abs(freq_out - freq_in); - bool bypass = false; - - if (RT5651_PLL_INP_MAX < freq_in || RT5651_PLL_INP_MIN > freq_in) - return -EINVAL; - - for (n_t = 0; n_t <= max_n; n_t++) { - in_t = (freq_in >> 1) + (freq_in >> 2) * n_t; - if (in_t < 0) - continue; - if (in_t == freq_out) { - bypass = true; - n = n_t; - goto code_find; - } - for (m_t = 0; m_t <= max_m; m_t++) { - out_t = in_t / (m_t + 2); - red = abs(out_t - freq_out); - if (red < red_t) { - n = n_t; - m = m_t; - if (red == 0) - goto code_find; - red_t = red; - } - } - } - pr_debug("Only get approximation about PLL\n"); - -code_find: - pll_code->m_bp = bypass; - pll_code->m_code = m; - pll_code->n_code = n; - pll_code->k_code = 2; - return 0; -} - static int rt5651_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source, unsigned int freq_in, unsigned int freq_out) { struct snd_soc_codec *codec = dai->codec; struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec); - struct rt5651_pll_code *pll_code = &rt5651->pll_code; + struct rl6231_pll_code pll_code; int ret;
if (source == rt5651->pll_src && freq_in == rt5651->pll_in && @@ -1609,20 +1556,21 @@ static int rt5651_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source, return -EINVAL; }
- ret = rt5651_pll_calc(freq_in, freq_out, pll_code); + ret = rl6231_pll_calc(freq_in, freq_out, &pll_code); if (ret < 0) { dev_err(codec->dev, "Unsupport input clock %d\n", freq_in); return ret; }
- dev_dbg(codec->dev, "bypass=%d m=%d n=%d k=2\n", pll_code->m_bp, - (pll_code->m_bp ? 0 : pll_code->m_code), pll_code->n_code); + dev_dbg(codec->dev, "bypass=%d m=%d n=%d k=%d\n", + pll_code.m_bp, (pll_code.m_bp ? 0 : pll_code.m_code), + pll_code.n_code, pll_code.k_code);
snd_soc_write(codec, RT5651_PLL_CTRL1, - pll_code->n_code << RT5651_PLL_N_SFT | pll_code->k_code); + pll_code.n_code << RT5651_PLL_N_SFT | pll_code.k_code); snd_soc_write(codec, RT5651_PLL_CTRL2, - (pll_code->m_bp ? 0 : pll_code->m_code) << RT5651_PLL_M_SFT | - pll_code->m_bp << RT5651_PLL_M_BP_SFT); + (pll_code.m_bp ? 0 : pll_code.m_code) << RT5651_PLL_M_SFT | + pll_code.m_bp << RT5651_PLL_M_BP_SFT);
rt5651->pll_in = freq_in; rt5651->pll_out = freq_out; diff --git a/sound/soc/codecs/rt5651.h b/sound/soc/codecs/rt5651.h index a28bd0c..1bd33cf 100644 --- a/sound/soc/codecs/rt5651.h +++ b/sound/soc/codecs/rt5651.h @@ -2069,7 +2069,6 @@ struct rt5651_priv { int bclk[RT5651_AIFS]; int master[RT5651_AIFS];
- struct rt5651_pll_code pll_code; int pll_src; int pll_in; int pll_out;
The patch adds the function "get_clk_info" to RL6231 shared support.
Signed-off-by: Oder Chiou oder_chiou@realtek.com --- sound/soc/codecs/rl6231.c | 16 ++++++++++++++++ sound/soc/codecs/rl6231.h | 1 + sound/soc/codecs/rt5640.c | 17 +---------------- sound/soc/codecs/rt5645.c | 17 +---------------- sound/soc/codecs/rt5651.c | 17 +---------------- 5 files changed, 20 insertions(+), 48 deletions(-)
diff --git a/sound/soc/codecs/rl6231.c b/sound/soc/codecs/rl6231.c index 289024b..7b82fbe 100644 --- a/sound/soc/codecs/rl6231.c +++ b/sound/soc/codecs/rl6231.c @@ -131,6 +131,22 @@ code_find: } EXPORT_SYMBOL_GPL(rl6231_pll_calc);
+int rl6231_get_clk_info(int sclk, int rate) +{ + int i, pd[] = {1, 2, 3, 4, 6, 8, 12, 16}; + + if (sclk <= 0 || rate <= 0) + return -EINVAL; + + rate = rate << 8; + for (i = 0; i < ARRAY_SIZE(pd); i++) + if (sclk == rate * pd[i]) + return i; + + return -EINVAL; +} +EXPORT_SYMBOL_GPL(rl6231_get_clk_info); + MODULE_DESCRIPTION("RL6231 class device shared support"); MODULE_AUTHOR("Oder Chiou oder_chiou@realtek.com"); MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/rl6231.h b/sound/soc/codecs/rl6231.h index efdfc86..0f7b057 100644 --- a/sound/soc/codecs/rl6231.h +++ b/sound/soc/codecs/rl6231.h @@ -29,5 +29,6 @@ struct rl6231_pll_code { int rl6231_calc_dmic_clk(int rate); int rl6231_pll_calc(const unsigned int freq_in, const unsigned int freq_out, struct rl6231_pll_code *pll_code); +int rl6231_get_clk_info(int sclk, int rate);
#endif /* __RL6231_H__ */ diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index bdc1a94..de80e89 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c @@ -1626,21 +1626,6 @@ static int get_sdp_info(struct snd_soc_codec *codec, int dai_id) return ret; }
-static int get_clk_info(int sclk, int rate) -{ - int i, pd[] = {1, 2, 3, 4, 6, 8, 12, 16}; - - if (sclk <= 0 || rate <= 0) - return -EINVAL; - - rate = rate << 8; - for (i = 0; i < ARRAY_SIZE(pd); i++) - if (sclk == rate * pd[i]) - return i; - - return -EINVAL; -} - static int rt5640_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { @@ -1650,7 +1635,7 @@ static int rt5640_hw_params(struct snd_pcm_substream *substream, int dai_sel, pre_div, bclk_ms, frame_size;
rt5640->lrck[dai->id] = params_rate(params); - pre_div = get_clk_info(rt5640->sysclk, rt5640->lrck[dai->id]); + pre_div = rl6231_get_clk_info(rt5640->sysclk, rt5640->lrck[dai->id]); if (pre_div < 0) { dev_err(codec->dev, "Unsupported clock setting %d for DAI %d\n", rt5640->lrck[dai->id], dai->id); diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index ee6db7c..02147be 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -1786,21 +1786,6 @@ static const struct snd_soc_dapm_route rt5645_dapm_routes[] = { { "SPOR", NULL, "SPK amp" }, };
-static int get_clk_info(int sclk, int rate) -{ - int i, pd[] = {1, 2, 3, 4, 6, 8, 12, 16}; - - if (sclk <= 0 || rate <= 0) - return -EINVAL; - - rate = rate << 8; - for (i = 0; i < ARRAY_SIZE(pd); i++) - if (sclk == rate * pd[i]) - return i; - - return -EINVAL; -} - static int rt5645_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { @@ -1810,7 +1795,7 @@ static int rt5645_hw_params(struct snd_pcm_substream *substream, int pre_div, bclk_ms, frame_size;
rt5645->lrck[dai->id] = params_rate(params); - pre_div = get_clk_info(rt5645->sysclk, rt5645->lrck[dai->id]); + pre_div = rl6231_get_clk_info(rt5645->sysclk, rt5645->lrck[dai->id]); if (pre_div < 0) { dev_err(codec->dev, "Unsupported clock setting\n"); return -EINVAL; diff --git a/sound/soc/codecs/rt5651.c b/sound/soc/codecs/rt5651.c index a627a1f..ea4b1c6 100644 --- a/sound/soc/codecs/rt5651.c +++ b/sound/soc/codecs/rt5651.c @@ -1338,21 +1338,6 @@ static const struct snd_soc_dapm_route rt5651_dapm_routes[] = { {"PDMR", NULL, "PDM R Mux"}, };
-static int get_clk_info(int sclk, int rate) -{ - int i, pd[] = {1, 2, 3, 4, 6, 8, 12, 16}; - - if (sclk <= 0 || rate <= 0) - return -EINVAL; - - rate = rate << 8; - for (i = 0; i < ARRAY_SIZE(pd); i++) - if (sclk == rate * pd[i]) - return i; - - return -EINVAL; -} - static int rt5651_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { @@ -1362,7 +1347,7 @@ static int rt5651_hw_params(struct snd_pcm_substream *substream, int pre_div, bclk_ms, frame_size;
rt5651->lrck[dai->id] = params_rate(params); - pre_div = get_clk_info(rt5651->sysclk, rt5651->lrck[dai->id]); + pre_div = rl6231_get_clk_info(rt5651->sysclk, rt5651->lrck[dai->id]);
if (pre_div < 0) { dev_err(codec->dev, "Unsupported clock setting\n");
On Tue, May 20, 2014 at 03:01:53PM +0800, Oder Chiou wrote:
The patch adds the RL6231 class device shared support for RT5640, RT5645 and RT5651. The function of the DMIC clock calculation can be shared by RL6231 shared support.
Applied all, thanks - this is a nice cleanup!
participants (2)
-
Mark Brown
-
Oder Chiou