diff options
author | Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | 2015-09-10 02:40:19 -0400 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2015-09-14 14:41:38 -0400 |
commit | 171a0138ab75fcbe1228c4af0442221efccfb197 (patch) | |
tree | af6f4ae0b127dd765245657bd5adfd542ce1e33a | |
parent | 2719a752b6e96b22ac6a0d5b9397c21c93abcd0f (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.txt | 22 | ||||
-rw-r--r-- | sound/soc/codecs/ak4642.c | 141 |
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 | ||
10 | Example: | 10 | Optional 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 | |||
17 | Example 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 | |||
26 | Example 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 | ||
148 | struct ak4642_priv { | 147 | struct 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 | ||
433 | static 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 | |||
433 | static int ak4642_dai_hw_params(struct snd_pcm_substream *substream, | 470 | static 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 | ||
485 | static int ak4642_set_bias_level(struct snd_soc_codec *codec, | 484 | static 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 | ||
534 | static 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 | |||
535 | static struct snd_soc_codec_driver soc_codec_dev_ak4642 = { | 544 | static 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 | ||
594 | static 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 | |||
583 | static const struct of_device_id ak4642_of_match[]; | 622 | static const struct of_device_id ak4642_of_match[]; |
584 | static int ak4642_i2c_probe(struct i2c_client *i2c, | 623 | static 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 | ||