ASoC: rt5640: Add RL6231 class device shared support for RT5640, RT5645 and RT5651
Subsystems (3)
Oder Chiou
maintainerPATCH 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.
--- 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
sound/soc/codecs/Kconfig +9 -0
@@ -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
sound/soc/codecs/Makefile +2 -0
@@ -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
sound/soc/codecs/rl6231.c new file +67 -0
67 lines not on this page · raw message
sound/soc/codecs/rl6231.h new file +18 -0
@@ -0,0 +1,18 @@ +/* +* rl6231.h - RL6231 class device shared support +* +* Copyright 2014 Realtek Semiconductor Corp. +* +* Author: Oder Chiou <[email protected]> +* +* 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__ */
sound/soc/codecs/rt5640.c +5 -18
@@ -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
sound/soc/codecs/rt5645.c +4 -18
@@ -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" );
sound/soc/codecs/rt5651.c +5 -17
@@ -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
Signature · 1 line
1.8.1.1.439.g50a6b54
Oder Chiou
maintainerPATCH 2/3 ASoC: rt5640: Add the function of the PLL clock calculation to RL6231 shared support
The patch adds the function of the PLL clock calculation to RL6231 shared support.
--- 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(-)
sound/soc/codecs/rl6231.c +69 -0
@@ -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 <[email protected]>" );MODULE_LICENSE ("GPL v2" );
sound/soc/codecs/rl6231.h +15 -0
@@ -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__ */
sound/soc/codecs/rt5640.c +8 -60
93 lines not on this page · raw message
sound/soc/codecs/rt5640.h +0 -8
@@ -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;
sound/soc/codecs/rt5645.c +2 -70
89 lines not on this page · raw message
sound/soc/codecs/rt5645.h +0 -7
@@ -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;
sound/soc/codecs/rt5651.c +8 -60
93 lines not on this page · raw message
sound/soc/codecs/rt5651.h +0 -1
@@ -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;
Signature · 1 line
1.8.1.1.439.g50a6b54
Oder Chiou
maintainerPATCH 3/3 ASoC: rt5640: Add the function "get_clk_info" to RL6231 shared support
In reply to Oder ChiouThe patch adds the function "get_clk_info" to RL6231 shared support.
--- 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(-)
sound/soc/codecs/rl6231.c +16 -0
@@ -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 <[email protected]>" );MODULE_LICENSE ("GPL v2" );
sound/soc/codecs/rl6231.h +1 -0
@@ -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__ */
sound/soc/codecs/rt5640.c +1 -16
@@ -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);
sound/soc/codecs/rt5645.c +1 -16
@@ -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 ;
sound/soc/codecs/rt5651.c +1 -16
@@ -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" );
Signature · 1 line
1.8.1.1.439.g50a6b54
Quoted 3 lines · Oder Chiou
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!