aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2015-09-10 02:40:19 -0400
committerMark Brown <broonie@kernel.org>2015-09-14 14:41:38 -0400
commit171a0138ab75fcbe1228c4af0442221efccfb197 (patch)
treeaf6f4ae0b127dd765245657bd5adfd542ce1e33a
parent2719a752b6e96b22ac6a0d5b9397c21c93abcd0f (diff)
ASoC: ak4642: enable to use MCKO as fixed rate output pin on DT
ak4642 chip can output clock via MCKO pin as audio reference clock. This patch supports it on DT Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--Documentation/devicetree/bindings/sound/ak4642.txt22
-rw-r--r--sound/soc/codecs/ak4642.c141
2 files changed, 114 insertions, 49 deletions
diff --git a/Documentation/devicetree/bindings/sound/ak4642.txt b/Documentation/devicetree/bindings/sound/ak4642.txt
index 623d4e70ae11..340784db6808 100644
--- a/Documentation/devicetree/bindings/sound/ak4642.txt
+++ b/Documentation/devicetree/bindings/sound/ak4642.txt
@@ -7,7 +7,14 @@ Required properties:
7 - compatible : "asahi-kasei,ak4642" or "asahi-kasei,ak4643" or "asahi-kasei,ak4648" 7 - compatible : "asahi-kasei,ak4642" or "asahi-kasei,ak4643" or "asahi-kasei,ak4648"
8 - reg : The chip select number on the I2C bus 8 - reg : The chip select number on the I2C bus
9 9
10Example: 10Optional properties:
11
12 - #clock-cells : common clock binding; shall be set to 0
13 - clocks : common clock binding; MCKI clock
14 - clock-frequency : common clock binding; frequency of MCKO
15 - clock-output-names : common clock binding; MCKO clock name
16
17Example 1:
11 18
12&i2c { 19&i2c {
13 ak4648: ak4648@0x12 { 20 ak4648: ak4648@0x12 {
@@ -15,3 +22,16 @@ Example:
15 reg = <0x12>; 22 reg = <0x12>;
16 }; 23 };
17}; 24};
25
26Example 2:
27
28&i2c {
29 ak4643: codec@12 {
30 compatible = "asahi-kasei,ak4643";
31 reg = <0x12>;
32 #clock-cells = <0>;
33 clocks = <&audio_clock>;
34 clock-frequency = <12288000>;
35 clock-output-names = "ak4643_mcko";
36 };
37};
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
index 9af06d30386b..b5c4981c9f4c 100644
--- a/sound/soc/codecs/ak4642.c
+++ b/sound/soc/codecs/ak4642.c
@@ -23,6 +23,8 @@
23 * AK4648 is tested. 23 * AK4648 is tested.
24 */ 24 */
25 25
26#include <linux/clk.h>
27#include <linux/clk-provider.h>
26#include <linux/delay.h> 28#include <linux/delay.h>
27#include <linux/i2c.h> 29#include <linux/i2c.h>
28#include <linux/slab.h> 30#include <linux/slab.h>
@@ -128,11 +130,8 @@
128#define I2S (3 << 0) 130#define I2S (3 << 0)
129 131
130/* MD_CTL2 */ 132/* MD_CTL2 */
131#define FS0 (1 << 0) 133#define FS(val) (((val & 0x7) << 0) | ((val & 0x8) << 2))
132#define FS1 (1 << 1) 134#define PS(val) ((val & 0x3) << 6)
133#define FS2 (1 << 2)
134#define FS3 (1 << 5)
135#define FS_MASK (FS0 | FS1 | FS2 | FS3)
136 135
137/* MD_CTL3 */ 136/* MD_CTL3 */
138#define BST1 (1 << 3) 137#define BST1 (1 << 3)
@@ -147,6 +146,7 @@ struct ak4642_drvdata {
147 146
148struct ak4642_priv { 147struct ak4642_priv {
149 const struct ak4642_drvdata *drvdata; 148 const struct ak4642_drvdata *drvdata;
149 struct clk *mcko;
150}; 150};
151 151
152/* 152/*
@@ -430,56 +430,55 @@ static int ak4642_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
430 return 0; 430 return 0;
431} 431}
432 432
433static int ak4642_set_mcko(struct snd_soc_codec *codec,
434 u32 frequency)
435{
436 u32 fs_list[] = {
437 [0] = 8000,
438 [1] = 12000,
439 [2] = 16000,
440 [3] = 24000,
441 [4] = 7350,
442 [5] = 11025,
443 [6] = 14700,
444 [7] = 22050,
445 [10] = 32000,
446 [11] = 48000,
447 [14] = 29400,
448 [15] = 44100,
449 };
450 u32 ps_list[] = {
451 [0] = 256,
452 [1] = 128,
453 [2] = 64,
454 [3] = 32
455 };
456 int ps, fs;
457
458 for (ps = 0; ps < ARRAY_SIZE(ps_list); ps++) {
459 for (fs = 0; fs < ARRAY_SIZE(fs_list); fs++) {
460 if (frequency == ps_list[ps] * fs_list[fs]) {
461 snd_soc_write(codec, MD_CTL2, PS(ps) | FS(fs));
462 return 0;
463 }
464 }
465 }
466
467 return 0;
468}
469
433static int ak4642_dai_hw_params(struct snd_pcm_substream *substream, 470static int ak4642_dai_hw_params(struct snd_pcm_substream *substream,
434 struct snd_pcm_hw_params *params, 471 struct snd_pcm_hw_params *params,
435 struct snd_soc_dai *dai) 472 struct snd_soc_dai *dai)
436{ 473{
437 struct snd_soc_codec *codec = dai->codec; 474 struct snd_soc_codec *codec = dai->codec;
438 u8 rate; 475 struct ak4642_priv *priv = snd_soc_codec_get_drvdata(codec);
476 u32 rate = clk_get_rate(priv->mcko);
439 477
440 switch (params_rate(params)) { 478 if (!rate)
441 case 7350: 479 rate = params_rate(params) * 256;
442 rate = FS2;
443 break;
444 case 8000:
445 rate = 0;
446 break;
447 case 11025:
448 rate = FS2 | FS0;
449 break;
450 case 12000:
451 rate = FS0;
452 break;
453 case 14700:
454 rate = FS2 | FS1;
455 break;
456 case 16000:
457 rate = FS1;
458 break;
459 case 22050:
460 rate = FS2 | FS1 | FS0;
461 break;
462 case 24000:
463 rate = FS1 | FS0;
464 break;
465 case 29400:
466 rate = FS3 | FS2 | FS1;
467 break;
468 case 32000:
469 rate = FS3 | FS1;
470 break;
471 case 44100:
472 rate = FS3 | FS2 | FS1 | FS0;
473 break;
474 case 48000:
475 rate = FS3 | FS1 | FS0;
476 break;
477 default:
478 return -EINVAL;
479 }
480 snd_soc_update_bits(codec, MD_CTL2, FS_MASK, rate);
481 480
482 return 0; 481 return ak4642_set_mcko(codec, rate);
483} 482}
484 483
485static int ak4642_set_bias_level(struct snd_soc_codec *codec, 484static int ak4642_set_bias_level(struct snd_soc_codec *codec,
@@ -532,7 +531,18 @@ static int ak4642_resume(struct snd_soc_codec *codec)
532 return 0; 531 return 0;
533} 532}
534 533
534static int ak4642_probe(struct snd_soc_codec *codec)
535{
536 struct ak4642_priv *priv = snd_soc_codec_get_drvdata(codec);
537
538 if (priv->mcko)
539 ak4642_set_mcko(codec, clk_get_rate(priv->mcko));
540
541 return 0;
542}
543
535static struct snd_soc_codec_driver soc_codec_dev_ak4642 = { 544static struct snd_soc_codec_driver soc_codec_dev_ak4642 = {
545 .probe = ak4642_probe,
536 .resume = ak4642_resume, 546 .resume = ak4642_resume,
537 .set_bias_level = ak4642_set_bias_level, 547 .set_bias_level = ak4642_set_bias_level,
538 .controls = ak4642_snd_controls, 548 .controls = ak4642_snd_controls,
@@ -580,6 +590,35 @@ static const struct ak4642_drvdata ak4648_drvdata = {
580 .extended_frequencies = 1, 590 .extended_frequencies = 1,
581}; 591};
582 592
593#ifdef CONFIG_COMMON_CLK
594static struct clk *ak4642_of_parse_mcko(struct device *dev)
595{
596 struct device_node *np = dev->of_node;
597 struct clk *clk;
598 const char *clk_name = np->name;
599 const char *parent_clk_name = NULL;
600 u32 rate;
601
602 if (of_property_read_u32(np, "clock-frequency", &rate))
603 return NULL;
604
605 if (of_property_read_bool(np, "clocks"))
606 parent_clk_name = of_clk_get_parent_name(np, 0);
607
608 of_property_read_string(np, "clock-output-names", &clk_name);
609
610 clk = clk_register_fixed_rate(dev, clk_name, parent_clk_name,
611 (parent_clk_name) ? 0 : CLK_IS_ROOT,
612 rate);
613 if (!IS_ERR(clk))
614 of_clk_add_provider(np, of_clk_src_simple_get, clk);
615
616 return clk;
617}
618#else
619#define ak4642_of_parse_mcko(d) 0
620#endif
621
583static const struct of_device_id ak4642_of_match[]; 622static const struct of_device_id ak4642_of_match[];
584static int ak4642_i2c_probe(struct i2c_client *i2c, 623static int ak4642_i2c_probe(struct i2c_client *i2c,
585 const struct i2c_device_id *id) 624 const struct i2c_device_id *id)
@@ -589,10 +628,15 @@ static int ak4642_i2c_probe(struct i2c_client *i2c,
589 const struct ak4642_drvdata *drvdata = NULL; 628 const struct ak4642_drvdata *drvdata = NULL;
590 struct regmap *regmap; 629 struct regmap *regmap;
591 struct ak4642_priv *priv; 630 struct ak4642_priv *priv;
631 struct clk *mcko = NULL;
592 632
593 if (np) { 633 if (np) {
594 const struct of_device_id *of_id; 634 const struct of_device_id *of_id;
595 635
636 mcko = ak4642_of_parse_mcko(dev);
637 if (IS_ERR(mcko))
638 mcko = NULL;
639
596 of_id = of_match_device(ak4642_of_match, dev); 640 of_id = of_match_device(ak4642_of_match, dev);
597 if (of_id) 641 if (of_id)
598 drvdata = of_id->data; 642 drvdata = of_id->data;
@@ -610,6 +654,7 @@ static int ak4642_i2c_probe(struct i2c_client *i2c,
610 return -ENOMEM; 654 return -ENOMEM;
611 655
612 priv->drvdata = drvdata; 656 priv->drvdata = drvdata;
657 priv->mcko = mcko;
613 658
614 i2c_set_clientdata(i2c, priv); 659 i2c_set_clientdata(i2c, priv);
615 660