]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - arch/arm/mach-omap2/board-n800-audio.c
ARM: OMAP: Remove io_p2v, use ioremap and XXX_IO_ADDRESS
[linux-2.6-omap-h63xx.git] / arch / arm / mach-omap2 / board-n800-audio.c
1 /*
2  * linux/arch/arm/mach-omap2/board-n800-audio.c
3  *
4  * Copyright (C) 2006 Nokia Corporation
5  * Contact: Juha Yrjola
6  *          Jarkko Nikula <jarkko.nikula@nokia.com>
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * version 2 as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20  * 02110-1301 USA
21  *
22  */
23
24 #include <linux/err.h>
25 #include <linux/clk.h>
26 #include <linux/platform_device.h>
27 #include <linux/spi/tsc2301.h>
28
29 #include <asm/io.h>
30 #include <mach/eac.h>
31
32 #include <mach/dsp_common.h>
33
34 #if defined(CONFIG_SPI_TSC2301_AUDIO) && defined(CONFIG_SND_OMAP24XX_EAC)
35 #define AUDIO_ENABLED
36
37 static struct clk *sys_clkout2;
38 static struct clk *sys_clkout2_src;
39 static struct clk *func96m_clk;
40 static struct device *eac_device;
41 static struct device *tsc2301_device;
42
43 static int enable_audio;
44 static int audio_ok;
45 static spinlock_t audio_lock;
46
47 /*
48  * Leaving EAC and sys_clkout2 pins multiplexed to those subsystems results
49  * in about 2 mA extra current leak when audios are powered down. The
50  * workaround is to multiplex them to protected mode (with pull-ups enabled)
51  * whenever audio is not being used.
52  */
53 static int eac_mux_disabled = 0;
54 static int clkout2_mux_disabled = 0;
55 static u32 saved_mux[2];
56
57 static void n800_enable_eac_mux(void)
58 {
59         if (!eac_mux_disabled)
60                 return;
61         __raw_writel(saved_mux[1], OMAP2_IO_ADDRESS(0x48000124));
62         eac_mux_disabled = 0;
63 }
64
65 static void n800_disable_eac_mux(void)
66 {
67         if (eac_mux_disabled) {
68                 WARN_ON(eac_mux_disabled);
69                 return;
70         }
71         saved_mux[1] = __raw_readl(OMAP2_IO_ADDRESS(0x48000124));
72         __raw_writel(0x1f1f1f1f, OMAP2_IO_ADDRESS(0x48000124));
73         eac_mux_disabled = 1;
74 }
75
76 static void n800_enable_clkout2_mux(void)
77 {
78         if (!clkout2_mux_disabled)
79                 return;
80         __raw_writel(saved_mux[0], OMAP2_IO_ADDRESS(0x480000e8));
81         clkout2_mux_disabled = 0;
82 }
83
84 static void n800_disable_clkout2_mux(void)
85 {
86         u32 l;
87
88         if (clkout2_mux_disabled) {
89                 WARN_ON(clkout2_mux_disabled);
90                 return;
91         }
92         saved_mux[0] = __raw_readl(OMAP2_IO_ADDRESS(0x480000e8));
93         l = saved_mux[0] & ~0xff;
94         l |= 0x1f;
95         __raw_writel(l, OMAP2_IO_ADDRESS(0x480000e8));
96         clkout2_mux_disabled = 1;
97 }
98
99 static int n800_eac_enable_ext_clocks(struct device *dev)
100 {
101         BUG_ON(tsc2301_device == NULL);
102         n800_enable_eac_mux();
103         tsc2301_mixer_enable_mclk(tsc2301_device);
104
105         return 0;
106 }
107
108 static void n800_eac_disable_ext_clocks(struct device *dev)
109 {
110         BUG_ON(tsc2301_device == NULL);
111         tsc2301_mixer_disable_mclk(tsc2301_device);
112         n800_disable_eac_mux();
113 }
114
115 static int n800_audio_set_power(void *pdata, int dac, int adc)
116 {
117         BUG_ON(pdata != tsc2301_device);
118         tsc2301_mixer_set_power(tsc2301_device, dac, adc);
119
120         return 0;
121 }
122
123 static int n800_audio_register_controls(void *pdata, struct snd_card *card)
124 {
125         BUG_ON(pdata != tsc2301_device);
126         return tsc2301_mixer_register_controls(tsc2301_device, card);
127 }
128
129 static struct eac_codec n800_eac_codec = {
130         .mclk_src = EAC_MCLK_EXT_2x12288000,
131         .codec_mode = EAC_CODEC_I2S_MASTER,
132         .codec_conf.i2s.polarity_changed_mode = 0,
133         .codec_conf.i2s.sync_delay_enable = 0,
134         .default_rate = 48000,
135         .set_power = n800_audio_set_power,
136         .register_controls = n800_audio_register_controls,
137         .short_name = "TSC2301",
138 };
139
140 static int n800_register_codec(void)
141 {
142         int r, do_enable = 0;
143         unsigned long flags;
144
145         n800_eac_codec.private_data = tsc2301_device;
146         r = eac_register_codec(eac_device, &n800_eac_codec);
147         if (r < 0)
148                 return r;
149         spin_lock_irqsave(&audio_lock, flags);
150         audio_ok = 1;
151         if (enable_audio)
152                 do_enable = 1;
153         spin_unlock_irqrestore(&audio_lock, flags);
154         if (do_enable)
155                 eac_set_mode(eac_device, 1, 1);
156         return 0;
157 }
158
159 static void n800_unregister_codec(void)
160 {
161         audio_ok = 0;
162         eac_unregister_codec(eac_device);
163         eac_set_mode(eac_device, 0, 0);
164 }
165
166 static int n800_eac_init(struct device *dev)
167 {
168         int r;
169
170         BUG_ON(eac_device != NULL);
171         eac_device = dev;
172         if (tsc2301_device != NULL) {
173                 r = n800_register_codec();
174                 if (r < 0)
175                         return r;
176         }
177
178         return 0;
179 }
180
181 static void n800_eac_cleanup(struct device *dev)
182 {
183         eac_device = NULL;
184         if (tsc2301_device != NULL)
185                 n800_unregister_codec();
186 }
187
188 static int n800_codec_get_clocks(struct device *dev)
189 {
190         sys_clkout2_src = clk_get(dev, "sys_clkout2_src");
191         if (IS_ERR(sys_clkout2_src)) {
192                 dev_err(dev, "Could not get sys_clkout2_src clock\n");
193                 return -ENODEV;
194         }
195         sys_clkout2 = clk_get(dev, "sys_clkout2");
196         if (IS_ERR(sys_clkout2)) {
197                 dev_err(dev, "Could not get sys_clkout2 clock\n");
198                 clk_put(sys_clkout2_src);
199                 return -ENODEV;
200         }
201         /* configure 12 MHz output on SYS_CLKOUT2. Therefore we must use
202          * 96 MHz as its parent in order to get 12 MHz */
203         func96m_clk = clk_get(dev, "func_96m_ck");
204         if (IS_ERR(func96m_clk)) {
205                 dev_err(dev, "Could not get func 96M clock\n");
206                 clk_put(sys_clkout2);
207                 clk_put(sys_clkout2_src);
208                 return -ENODEV;
209         }
210
211         clk_set_parent(sys_clkout2_src, func96m_clk);
212         clk_set_rate(sys_clkout2, 12000000);
213
214         return 0;
215 }
216
217 static void n800_codec_put_clocks(struct device *dev)
218 {
219         clk_put(func96m_clk);
220         clk_put(sys_clkout2);
221         clk_put(sys_clkout2_src);
222 }
223
224 static int n800_codec_enable_clock(struct device *dev)
225 {
226         n800_enable_clkout2_mux();
227         return clk_enable(sys_clkout2);
228 }
229
230 static void n800_codec_disable_clock(struct device *dev)
231 {
232         clk_disable(sys_clkout2);
233         n800_disable_clkout2_mux();
234 }
235
236 static int n800_codec_init(struct device *dev)
237 {
238         int r;
239
240         BUG_ON(tsc2301_device != NULL);
241         tsc2301_device = dev;
242         if ((r = n800_codec_get_clocks(dev)) < 0)
243                 return r;
244         if (eac_device != NULL) {
245                 r = n800_register_codec();
246                 if (r < 0) {
247                         n800_codec_put_clocks(dev);
248                         return r;
249                 }
250         }
251         return 0;
252 }
253
254 static void n800_codec_cleanup(struct device *dev)
255 {
256         tsc2301_device = NULL;
257         if (eac_device != NULL)
258                 n800_unregister_codec();
259         n800_codec_put_clocks(dev);
260 }
261
262 static struct eac_platform_data n800_eac_data = {
263         .init = n800_eac_init,
264         .cleanup = n800_eac_cleanup,
265         .enable_ext_clocks = n800_eac_enable_ext_clocks,
266         .disable_ext_clocks = n800_eac_disable_ext_clocks,
267 };
268
269 static const struct tsc2301_mixer_gpio n800_mixer_gpios[] = {
270         {
271                 .name                   = "Headset Amplifier",
272                 .gpio                   = 1,
273                 .deactivate_on_pd       = 1,
274         }, {
275                 .name                   = "Speaker Amplifier",
276                 .gpio                   = 2,
277                 .def_enable             = 1,
278                 .deactivate_on_pd       = 1,
279         }, {
280                 .name                   = "Headset Mic Select",
281                 .gpio                   = 3,
282         }
283 };
284
285 static struct platform_device retu_headset_device = {
286         .name           = "retu-headset",
287         .id             = -1,
288         .dev            = {
289                 .release        = NULL,
290         },
291 };
292
293 void __init n800_audio_init(struct tsc2301_platform_data *tc)
294 {
295         spin_lock_init(&audio_lock);
296
297         if (platform_device_register(&retu_headset_device) < 0)
298                 return;
299         omap_init_eac(&n800_eac_data);
300
301         tc->pll_pdc = 7;
302         tc->pll_a = 7;
303         tc->pll_n = 9;
304         tc->pll_output = 1;
305         tc->mclk_ratio = TSC2301_MCLK_256xFS;
306         tc->i2s_sample_rate = TSC2301_I2S_SR_48000;
307         tc->i2s_format = TSC2301_I2S_FORMAT0;
308         tc->power_down_blocks = TSC2301_REG_PD_MISC_MOPD;
309         tc->mixer_gpios = n800_mixer_gpios;
310         tc->n_mixer_gpios = ARRAY_SIZE(n800_mixer_gpios);
311         tc->codec_init = n800_codec_init;
312         tc->codec_cleanup = n800_codec_cleanup;
313         tc->enable_clock = n800_codec_enable_clock;
314         tc->disable_clock = n800_codec_disable_clock;
315 }
316
317 #else
318
319 void __init n800_audio_init(struct tsc2301_platform_data *tc)
320 {
321 }
322
323 #endif
324
325 #ifdef CONFIG_OMAP_DSP
326
327 int n800_audio_enable(struct dsp_kfunc_device *kdev, int stage)
328 {
329 #ifdef AUDIO_ENABLED
330         unsigned long flags;
331         int do_enable = 0;
332
333         spin_lock_irqsave(&audio_lock, flags);
334
335         pr_debug("DSP power up request (audio codec %sinitialized)\n",
336                  audio_ok ? "" : "not ");
337
338         if (enable_audio)
339                 goto out;
340         enable_audio = 1;
341         if (audio_ok)
342                 do_enable = 1;
343 out:
344         spin_unlock_irqrestore(&audio_lock, flags);
345         if (do_enable)
346                 eac_set_mode(eac_device, 1, 1);
347 #endif
348         return 0;
349 }
350
351 int n800_audio_disable(struct dsp_kfunc_device *kdev, int stage)
352 {
353 #ifdef AUDIO_ENABLED
354         unsigned long flags;
355         int do_disable = 0;
356
357         spin_lock_irqsave(&audio_lock, flags);
358
359         pr_debug("DSP power down request (audio codec %sinitialized)\n",
360                 audio_ok ? "" : "not ");
361
362         if (!enable_audio)
363                 goto out;
364         enable_audio = 0;
365         if (audio_ok)
366                 do_disable = 1;
367 out:
368         spin_unlock_irqrestore(&audio_lock, flags);
369         if (do_disable)
370                 eac_set_mode(eac_device, 0, 0);
371 #endif
372         return 0;
373 }
374
375 #endif /* CONFIG_OMAP_DSP */