Alsa-Devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/3] ASoC: rt5640: Add RL6231 class device shared support for RT5640, RT5645 and RT5651
@ 2014-05-20  7:01 Oder Chiou
  2014-05-20  7:01 ` [PATCH 2/3] ASoC: rt5640: Add the function of the PLL clock calculation to RL6231 shared support Oder Chiou
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Oder Chiou @ 2014-05-20  7:01 UTC (permalink / raw)
  To: broonie, lgirdwood; +Cc: oder_chiou, bardliao, alsa-devel, flove

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
-- 
1.8.1.1.439.g50a6b54

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/3] ASoC: rt5640: Add the function of the PLL clock calculation to RL6231 shared support
  2014-05-20  7:01 [PATCH 1/3] ASoC: rt5640: Add RL6231 class device shared support for RT5640, RT5645 and RT5651 Oder Chiou
@ 2014-05-20  7:01 ` Oder Chiou
  2014-05-20  7:01 ` [PATCH 3/3] ASoC: rt5640: Add the function "get_clk_info" " Oder Chiou
  2014-06-01 19:04 ` [PATCH 1/3] ASoC: rt5640: Add RL6231 class device shared support for RT5640, RT5645 and RT5651 Mark Brown
  2 siblings, 0 replies; 4+ messages in thread
From: Oder Chiou @ 2014-05-20  7:01 UTC (permalink / raw)
  To: broonie, lgirdwood; +Cc: oder_chiou, bardliao, alsa-devel, flove

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;
-- 
1.8.1.1.439.g50a6b54

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 3/3] ASoC: rt5640: Add the function "get_clk_info" to RL6231 shared support
  2014-05-20  7:01 [PATCH 1/3] ASoC: rt5640: Add RL6231 class device shared support for RT5640, RT5645 and RT5651 Oder Chiou
  2014-05-20  7:01 ` [PATCH 2/3] ASoC: rt5640: Add the function of the PLL clock calculation to RL6231 shared support Oder Chiou
@ 2014-05-20  7:01 ` Oder Chiou
  2014-06-01 19:04 ` [PATCH 1/3] ASoC: rt5640: Add RL6231 class device shared support for RT5640, RT5645 and RT5651 Mark Brown
  2 siblings, 0 replies; 4+ messages in thread
From: Oder Chiou @ 2014-05-20  7:01 UTC (permalink / raw)
  To: broonie, lgirdwood; +Cc: oder_chiou, bardliao, alsa-devel, flove

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");
-- 
1.8.1.1.439.g50a6b54

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH 1/3] ASoC: rt5640: Add RL6231 class device shared support for RT5640, RT5645 and RT5651
  2014-05-20  7:01 [PATCH 1/3] ASoC: rt5640: Add RL6231 class device shared support for RT5640, RT5645 and RT5651 Oder Chiou
  2014-05-20  7:01 ` [PATCH 2/3] ASoC: rt5640: Add the function of the PLL clock calculation to RL6231 shared support Oder Chiou
  2014-05-20  7:01 ` [PATCH 3/3] ASoC: rt5640: Add the function "get_clk_info" " Oder Chiou
@ 2014-06-01 19:04 ` Mark Brown
  2 siblings, 0 replies; 4+ messages in thread
From: Mark Brown @ 2014-06-01 19:04 UTC (permalink / raw)
  To: Oder Chiou; +Cc: bardliao, alsa-devel, lgirdwood, flove


[-- Attachment #1.1: Type: text/plain, Size: 281 bytes --]

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!

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2014-06-01 19:05 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-05-20  7:01 [PATCH 1/3] ASoC: rt5640: Add RL6231 class device shared support for RT5640, RT5645 and RT5651 Oder Chiou
2014-05-20  7:01 ` [PATCH 2/3] ASoC: rt5640: Add the function of the PLL clock calculation to RL6231 shared support Oder Chiou
2014-05-20  7:01 ` [PATCH 3/3] ASoC: rt5640: Add the function "get_clk_info" " Oder Chiou
2014-06-01 19:04 ` [PATCH 1/3] ASoC: rt5640: Add RL6231 class device shared support for RT5640, RT5645 and RT5651 Mark Brown

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox