diff options
author | Stephen Warren <swarren@nvidia.com> | 2011-01-28 16:26:40 -0500 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2011-01-31 08:16:29 -0500 |
commit | d64e57cef0436833cfc9620e350ec6f5b041c9a9 (patch) | |
tree | 173c1f1bf2b87dfdc3bd7da379b9cf67e07b7906 | |
parent | c244d477b7a5e0060b05d6ef90b7b29ef72a2188 (diff) |
ASoC: Tegra: utils: Don't use global variables
Instead, have the machine driver provide storage for the utility data
somehow.
For Harmony in particular, store this within struct tegra_harmony, itself
referenced by snd_soc_card's drvdata.
Signed-off-by: Stephen Warren <swarren@nvidia.com>
Acked-by: Liam Girdwood <lrg@slimlogic.co.uk>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
-rw-r--r-- | sound/soc/tegra/harmony.c | 11 | ||||
-rw-r--r-- | sound/soc/tegra/tegra_asoc_utils.c | 91 | ||||
-rw-r--r-- | sound/soc/tegra/tegra_asoc_utils.h | 20 |
3 files changed, 68 insertions, 54 deletions
diff --git a/sound/soc/tegra/harmony.c b/sound/soc/tegra/harmony.c index 76793a93c133..d1faa63af034 100644 --- a/sound/soc/tegra/harmony.c +++ b/sound/soc/tegra/harmony.c | |||
@@ -50,6 +50,7 @@ | |||
50 | #define DRV_NAME "tegra-snd-harmony" | 50 | #define DRV_NAME "tegra-snd-harmony" |
51 | 51 | ||
52 | struct tegra_harmony { | 52 | struct tegra_harmony { |
53 | struct tegra_asoc_utils_data util_data; | ||
53 | struct harmony_audio_platform_data *pdata; | 54 | struct harmony_audio_platform_data *pdata; |
54 | int gpio_spkr_en_requested; | 55 | int gpio_spkr_en_requested; |
55 | }; | 56 | }; |
@@ -62,6 +63,7 @@ static int harmony_asoc_hw_params(struct snd_pcm_substream *substream, | |||
62 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | 63 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; |
63 | struct snd_soc_codec *codec = rtd->codec; | 64 | struct snd_soc_codec *codec = rtd->codec; |
64 | struct snd_soc_card *card = codec->card; | 65 | struct snd_soc_card *card = codec->card; |
66 | struct tegra_harmony *harmony = snd_soc_card_get_drvdata(card); | ||
65 | int srate, mclk, mclk_change; | 67 | int srate, mclk, mclk_change; |
66 | int err; | 68 | int err; |
67 | 69 | ||
@@ -80,7 +82,8 @@ static int harmony_asoc_hw_params(struct snd_pcm_substream *substream, | |||
80 | while (mclk < 6000000) | 82 | while (mclk < 6000000) |
81 | mclk *= 2; | 83 | mclk *= 2; |
82 | 84 | ||
83 | err = tegra_asoc_utils_set_rate(srate, mclk, &mclk_change); | 85 | err = tegra_asoc_utils_set_rate(&harmony->util_data, srate, mclk, |
86 | &mclk_change); | ||
84 | if (err < 0) { | 87 | if (err < 0) { |
85 | dev_err(card->dev, "Can't configure clocks\n"); | 88 | dev_err(card->dev, "Can't configure clocks\n"); |
86 | return err; | 89 | return err; |
@@ -226,7 +229,7 @@ static __devinit int tegra_snd_harmony_probe(struct platform_device *pdev) | |||
226 | 229 | ||
227 | harmony->pdata = pdata; | 230 | harmony->pdata = pdata; |
228 | 231 | ||
229 | ret = tegra_asoc_utils_init(); | 232 | ret = tegra_asoc_utils_init(&harmony->util_data, &pdev->dev); |
230 | if (ret) | 233 | if (ret) |
231 | goto err_free_harmony; | 234 | goto err_free_harmony; |
232 | 235 | ||
@@ -247,7 +250,7 @@ err_clear_drvdata: | |||
247 | snd_soc_card_set_drvdata(card, NULL); | 250 | snd_soc_card_set_drvdata(card, NULL); |
248 | platform_set_drvdata(pdev, NULL); | 251 | platform_set_drvdata(pdev, NULL); |
249 | card->dev = NULL; | 252 | card->dev = NULL; |
250 | tegra_asoc_utils_fini(); | 253 | tegra_asoc_utils_fini(&harmony->util_data); |
251 | err_free_harmony: | 254 | err_free_harmony: |
252 | kfree(harmony); | 255 | kfree(harmony); |
253 | return ret; | 256 | return ret; |
@@ -265,7 +268,7 @@ static int __devexit tegra_snd_harmony_remove(struct platform_device *pdev) | |||
265 | platform_set_drvdata(pdev, NULL); | 268 | platform_set_drvdata(pdev, NULL); |
266 | card->dev = NULL; | 269 | card->dev = NULL; |
267 | 270 | ||
268 | tegra_asoc_utils_fini(); | 271 | tegra_asoc_utils_fini(&harmony->util_data); |
269 | 272 | ||
270 | if (harmony->gpio_spkr_en_requested) | 273 | if (harmony->gpio_spkr_en_requested) |
271 | gpio_free(pdata->gpio_spkr_en); | 274 | gpio_free(pdata->gpio_spkr_en); |
diff --git a/sound/soc/tegra/tegra_asoc_utils.c b/sound/soc/tegra/tegra_asoc_utils.c index cfe2ea890dc0..cb4fc13c7d22 100644 --- a/sound/soc/tegra/tegra_asoc_utils.c +++ b/sound/soc/tegra/tegra_asoc_utils.c | |||
@@ -21,20 +21,14 @@ | |||
21 | */ | 21 | */ |
22 | 22 | ||
23 | #include <linux/clk.h> | 23 | #include <linux/clk.h> |
24 | #include <linux/device.h> | ||
24 | #include <linux/err.h> | 25 | #include <linux/err.h> |
25 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
26 | 27 | ||
27 | #include "tegra_asoc_utils.h" | 28 | #include "tegra_asoc_utils.h" |
28 | 29 | ||
29 | #define PREFIX "ASoC Tegra: " | 30 | int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate, |
30 | 31 | int mclk, int *mclk_change) | |
31 | static struct clk *clk_pll_a; | ||
32 | static struct clk *clk_pll_a_out0; | ||
33 | static struct clk *clk_cdev1; | ||
34 | |||
35 | static int set_baseclock, set_mclk; | ||
36 | |||
37 | int tegra_asoc_utils_set_rate(int srate, int mclk, int *mclk_change) | ||
38 | { | 32 | { |
39 | int new_baseclock; | 33 | int new_baseclock; |
40 | int err; | 34 | int err; |
@@ -58,95 +52,98 @@ int tegra_asoc_utils_set_rate(int srate, int mclk, int *mclk_change) | |||
58 | return -EINVAL; | 52 | return -EINVAL; |
59 | } | 53 | } |
60 | 54 | ||
61 | *mclk_change = ((new_baseclock != set_baseclock) || | 55 | *mclk_change = ((new_baseclock != data->set_baseclock) || |
62 | (mclk != set_mclk)); | 56 | (mclk != data->set_mclk)); |
63 | if (!*mclk_change) | 57 | if (!*mclk_change) |
64 | return 0; | 58 | return 0; |
65 | 59 | ||
66 | set_baseclock = 0; | 60 | data->set_baseclock = 0; |
67 | set_mclk = 0; | 61 | data->set_mclk = 0; |
68 | 62 | ||
69 | clk_disable(clk_cdev1); | 63 | clk_disable(data->clk_cdev1); |
70 | clk_disable(clk_pll_a_out0); | 64 | clk_disable(data->clk_pll_a_out0); |
71 | clk_disable(clk_pll_a); | 65 | clk_disable(data->clk_pll_a); |
72 | 66 | ||
73 | err = clk_set_rate(clk_pll_a, new_baseclock); | 67 | err = clk_set_rate(data->clk_pll_a, new_baseclock); |
74 | if (err) { | 68 | if (err) { |
75 | pr_err(PREFIX "Can't set pll_a rate: %d\n", err); | 69 | dev_err(data->dev, "Can't set pll_a rate: %d\n", err); |
76 | return err; | 70 | return err; |
77 | } | 71 | } |
78 | 72 | ||
79 | err = clk_set_rate(clk_pll_a_out0, mclk); | 73 | err = clk_set_rate(data->clk_pll_a_out0, mclk); |
80 | if (err) { | 74 | if (err) { |
81 | pr_err(PREFIX "Can't set pll_a_out0 rate: %d\n", err); | 75 | dev_err(data->dev, "Can't set pll_a_out0 rate: %d\n", err); |
82 | return err; | 76 | return err; |
83 | } | 77 | } |
84 | 78 | ||
85 | /* Don't set cdev1 rate; its locked to pll_a_out0 */ | 79 | /* Don't set cdev1 rate; its locked to pll_a_out0 */ |
86 | 80 | ||
87 | err = clk_enable(clk_pll_a); | 81 | err = clk_enable(data->clk_pll_a); |
88 | if (err) { | 82 | if (err) { |
89 | pr_err(PREFIX "Can't enable pll_a: %d\n", err); | 83 | dev_err(data->dev, "Can't enable pll_a: %d\n", err); |
90 | return err; | 84 | return err; |
91 | } | 85 | } |
92 | 86 | ||
93 | err = clk_enable(clk_pll_a_out0); | 87 | err = clk_enable(data->clk_pll_a_out0); |
94 | if (err) { | 88 | if (err) { |
95 | pr_err(PREFIX "Can't enable pll_a_out0: %d\n", err); | 89 | dev_err(data->dev, "Can't enable pll_a_out0: %d\n", err); |
96 | return err; | 90 | return err; |
97 | } | 91 | } |
98 | 92 | ||
99 | err = clk_enable(clk_cdev1); | 93 | err = clk_enable(data->clk_cdev1); |
100 | if (err) { | 94 | if (err) { |
101 | pr_err(PREFIX "Can't enable cdev1: %d\n", err); | 95 | dev_err(data->dev, "Can't enable cdev1: %d\n", err); |
102 | return err; | 96 | return err; |
103 | } | 97 | } |
104 | 98 | ||
105 | set_baseclock = new_baseclock; | 99 | data->set_baseclock = new_baseclock; |
106 | set_mclk = mclk; | 100 | data->set_mclk = mclk; |
107 | 101 | ||
108 | return 0; | 102 | return 0; |
109 | } | 103 | } |
110 | 104 | ||
111 | int tegra_asoc_utils_init(void) | 105 | int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data, |
106 | struct device *dev) | ||
112 | { | 107 | { |
113 | int ret; | 108 | int ret; |
114 | 109 | ||
115 | clk_pll_a = clk_get_sys(NULL, "pll_a"); | 110 | data->dev = dev; |
116 | if (IS_ERR(clk_pll_a)) { | 111 | |
117 | pr_err(PREFIX "Can't retrieve clk pll_a\n"); | 112 | data->clk_pll_a = clk_get_sys(NULL, "pll_a"); |
118 | ret = PTR_ERR(clk_pll_a); | 113 | if (IS_ERR(data->clk_pll_a)) { |
114 | dev_err(data->dev, "Can't retrieve clk pll_a\n"); | ||
115 | ret = PTR_ERR(data->clk_pll_a); | ||
119 | goto err; | 116 | goto err; |
120 | } | 117 | } |
121 | 118 | ||
122 | clk_pll_a_out0 = clk_get_sys(NULL, "pll_a_out0"); | 119 | data->clk_pll_a_out0 = clk_get_sys(NULL, "pll_a_out0"); |
123 | if (IS_ERR(clk_pll_a_out0)) { | 120 | if (IS_ERR(data->clk_pll_a_out0)) { |
124 | pr_err(PREFIX "Can't retrieve clk pll_a_out0\n"); | 121 | dev_err(data->dev, "Can't retrieve clk pll_a_out0\n"); |
125 | ret = PTR_ERR(clk_pll_a_out0); | 122 | ret = PTR_ERR(data->clk_pll_a_out0); |
126 | goto err_put_pll_a; | 123 | goto err_put_pll_a; |
127 | } | 124 | } |
128 | 125 | ||
129 | clk_cdev1 = clk_get_sys(NULL, "cdev1"); | 126 | data->clk_cdev1 = clk_get_sys(NULL, "cdev1"); |
130 | if (IS_ERR(clk_cdev1)) { | 127 | if (IS_ERR(data->clk_cdev1)) { |
131 | pr_err(PREFIX "Can't retrieve clk cdev1\n"); | 128 | dev_err(data->dev, "Can't retrieve clk cdev1\n"); |
132 | ret = PTR_ERR(clk_cdev1); | 129 | ret = PTR_ERR(data->clk_cdev1); |
133 | goto err_put_pll_a_out0; | 130 | goto err_put_pll_a_out0; |
134 | } | 131 | } |
135 | 132 | ||
136 | return 0; | 133 | return 0; |
137 | 134 | ||
138 | err_put_pll_a_out0: | 135 | err_put_pll_a_out0: |
139 | clk_put(clk_pll_a_out0); | 136 | clk_put(data->clk_pll_a_out0); |
140 | err_put_pll_a: | 137 | err_put_pll_a: |
141 | clk_put(clk_pll_a); | 138 | clk_put(data->clk_pll_a); |
142 | err: | 139 | err: |
143 | return ret; | 140 | return ret; |
144 | } | 141 | } |
145 | 142 | ||
146 | void tegra_asoc_utils_fini(void) | 143 | void tegra_asoc_utils_fini(struct tegra_asoc_utils_data *data) |
147 | { | 144 | { |
148 | clk_put(clk_cdev1); | 145 | clk_put(data->clk_cdev1); |
149 | clk_put(clk_pll_a_out0); | 146 | clk_put(data->clk_pll_a_out0); |
150 | clk_put(clk_pll_a); | 147 | clk_put(data->clk_pll_a); |
151 | } | 148 | } |
152 | 149 | ||
diff --git a/sound/soc/tegra/tegra_asoc_utils.h b/sound/soc/tegra/tegra_asoc_utils.h index 855f8f6e44ca..bbba7afdfc2c 100644 --- a/sound/soc/tegra/tegra_asoc_utils.h +++ b/sound/soc/tegra/tegra_asoc_utils.h | |||
@@ -23,9 +23,23 @@ | |||
23 | #ifndef __TEGRA_ASOC_UTILS_H__ | 23 | #ifndef __TEGRA_ASOC_UTILS_H__ |
24 | #define __TEGRA_ASOC_UTILS_H_ | 24 | #define __TEGRA_ASOC_UTILS_H_ |
25 | 25 | ||
26 | int tegra_asoc_utils_set_rate(int srate, int mclk_rate, int *mclk_change); | 26 | struct clk; |
27 | int tegra_asoc_utils_init(void); | 27 | struct device; |
28 | void tegra_asoc_utils_fini(void); | 28 | |
29 | struct tegra_asoc_utils_data { | ||
30 | struct device *dev; | ||
31 | struct clk *clk_pll_a; | ||
32 | struct clk *clk_pll_a_out0; | ||
33 | struct clk *clk_cdev1; | ||
34 | int set_baseclock; | ||
35 | int set_mclk; | ||
36 | }; | ||
37 | |||
38 | int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate, | ||
39 | int mclk, int *mclk_change); | ||
40 | int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data, | ||
41 | struct device *dev); | ||
42 | void tegra_asoc_utils_fini(struct tegra_asoc_utils_data *data); | ||
29 | 43 | ||
30 | #endif | 44 | #endif |
31 | 45 | ||