]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - arch/arm/mach-omap2/board-n800-audio.c
Merge current mainline tree into linux-omap tree
[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 #define MUX_EAC_IOP2V(x)                (__force void __iomem *)io_p2v(x)
58
59 static void n800_enable_eac_mux(void)
60 {
61         if (!eac_mux_disabled)
62                 return;
63         __raw_writel(saved_mux[1], MUX_EAC_IOP2V(0x48000124));
64         eac_mux_disabled = 0;
65 }
66
67 static void n800_disable_eac_mux(void)
68 {
69         if (eac_mux_disabled) {
70                 WARN_ON(eac_mux_disabled);
71                 return;
72         }
73         saved_mux[1] = __raw_readl(MUX_EAC_IOP2V(0x48000124));
74         __raw_writel(0x1f1f1f1f, MUX_EAC_IOP2V(0x48000124));
75         eac_mux_disabled = 1;
76 }
77
78 static void n800_enable_clkout2_mux(void)
79 {
80         if (!clkout2_mux_disabled)
81                 return;
82         __raw_writel(saved_mux[0], MUX_EAC_IOP2V(0x480000e8));
83         clkout2_mux_disabled = 0;
84 }
85
86 static void n800_disable_clkout2_mux(void)
87 {
88         u32 l;
89
90         if (clkout2_mux_disabled) {
91                 WARN_ON(clkout2_mux_disabled);
92                 return;
93         }
94         saved_mux[0] = __raw_readl(MUX_EAC_IOP2V(0x480000e8));
95         l = saved_mux[0] & ~0xff;
96         l |= 0x1f;
97         __raw_writel(l, MUX_EAC_IOP2V(0x480000e8));
98         clkout2_mux_disabled = 1;
99 }
100
101 static int n800_eac_enable_ext_clocks(struct device *dev)
102 {
103         BUG_ON(tsc2301_device == NULL);
104         n800_enable_eac_mux();
105         tsc2301_mixer_enable_mclk(tsc2301_device);
106
107         return 0;
108 }
109
110 static void n800_eac_disable_ext_clocks(struct device *dev)
111 {
112         BUG_ON(tsc2301_device == NULL);
113         tsc2301_mixer_disable_mclk(tsc2301_device);
114         n800_disable_eac_mux();
115 }
116
117 static int n800_audio_set_power(void *pdata, int dac, int adc)
118 {
119         BUG_ON(pdata != tsc2301_device);
120         tsc2301_mixer_set_power(tsc2301_device, dac, adc);
121
122         return 0;
123 }
124
125 static int n800_audio_register_controls(void *pdata, struct snd_card *card)
126 {
127         BUG_ON(pdata != tsc2301_device);
128         return tsc2301_mixer_register_controls(tsc2301_device, card);
129 }
130
131 static struct eac_codec n800_eac_codec = {
132         .mclk_src = EAC_MCLK_EXT_2x12288000,
133         .codec_mode = EAC_CODEC_I2S_MASTER,
134         .codec_conf.i2s.polarity_changed_mode = 0,
135         .codec_conf.i2s.sync_delay_enable = 0,
136         .default_rate = 48000,
137         .set_power = n800_audio_set_power,
138         .register_controls = n800_audio_register_controls,
139         .short_name = "TSC2301",
140 };
141
142 static int n800_register_codec(void)
143 {
144         int r, do_enable = 0;
145         unsigned long flags;
146
147         n800_eac_codec.private_data = tsc2301_device;
148         r = eac_register_codec(eac_device, &n800_eac_codec);
149         if (r < 0)
150                 return r;
151         spin_lock_irqsave(&audio_lock, flags);
152         audio_ok = 1;
153         if (enable_audio)
154                 do_enable = 1;
155         spin_unlock_irqrestore(&audio_lock, flags);
156         if (do_enable)
157                 eac_set_mode(eac_device, 1, 1);
158         return 0;
159 }
160
161 static void n800_unregister_codec(void)
162 {
163         audio_ok = 0;
164         eac_unregister_codec(eac_device);
165         eac_set_mode(eac_device, 0, 0);
166 }
167
168 static int n800_eac_init(struct device *dev)
169 {
170         int r;
171
172         BUG_ON(eac_device != NULL);
173         eac_device = dev;
174         if (tsc2301_device != NULL) {
175                 r = n800_register_codec();
176                 if (r < 0)
177                         return r;
178         }
179
180         return 0;
181 }
182
183 static void n800_eac_cleanup(struct device *dev)
184 {
185         eac_device = NULL;
186         if (tsc2301_device != NULL)
187                 n800_unregister_codec();
188 }
189
190 static int n800_codec_get_clocks(struct device *dev)
191 {
192         sys_clkout2_src = clk_get(dev, "sys_clkout2_src");
193         if (IS_ERR(sys_clkout2_src)) {
194                 dev_err(dev, "Could not get sys_clkout2_src clock\n");
195                 return -ENODEV;
196         }
197         sys_clkout2 = clk_get(dev, "sys_clkout2");
198         if (IS_ERR(sys_clkout2)) {
199                 dev_err(dev, "Could not get sys_clkout2 clock\n");
200                 clk_put(sys_clkout2_src);
201                 return -ENODEV;
202         }
203         /* configure 12 MHz output on SYS_CLKOUT2. Therefore we must use
204          * 96 MHz as its parent in order to get 12 MHz */
205         func96m_clk = clk_get(dev, "func_96m_ck");
206         if (IS_ERR(func96m_clk)) {
207                 dev_err(dev, "Could not get func 96M clock\n");
208                 clk_put(sys_clkout2);
209                 clk_put(sys_clkout2_src);
210                 return -ENODEV;
211         }
212
213         clk_set_parent(sys_clkout2_src, func96m_clk);
214         clk_set_rate(sys_clkout2, 12000000);
215
216         return 0;
217 }
218
219 static void n800_codec_put_clocks(struct device *dev)
220 {
221         clk_put(func96m_clk);
222         clk_put(sys_clkout2);
223         clk_put(sys_clkout2_src);
224 }
225
226 static int n800_codec_enable_clock(struct device *dev)
227 {
228         n800_enable_clkout2_mux();
229         return clk_enable(sys_clkout2);
230 }
231
232 static void n800_codec_disable_clock(struct device *dev)
233 {
234         clk_disable(sys_clkout2);
235         n800_disable_clkout2_mux();
236 }
237
238 static int n800_codec_init(struct device *dev)
239 {
240         int r;
241
242         BUG_ON(tsc2301_device != NULL);
243         tsc2301_device = dev;
244         if ((r = n800_codec_get_clocks(dev)) < 0)
245                 return r;
246         if (eac_device != NULL) {
247                 r = n800_register_codec();
248                 if (r < 0) {
249                         n800_codec_put_clocks(dev);
250                         return r;
251                 }
252         }
253         return 0;
254 }
255
256 static void n800_codec_cleanup(struct device *dev)
257 {
258         tsc2301_device = NULL;
259         if (eac_device != NULL)
260                 n800_unregister_codec();
261         n800_codec_put_clocks(dev);
262 }
263
264 static struct eac_platform_data n800_eac_data = {
265         .init = n800_eac_init,
266         .cleanup = n800_eac_cleanup,
267         .enable_ext_clocks = n800_eac_enable_ext_clocks,
268         .disable_ext_clocks = n800_eac_disable_ext_clocks,
269 };
270
271 static const struct tsc2301_mixer_gpio n800_mixer_gpios[] = {
272         {
273                 .name                   = "Headset Amplifier",
274                 .gpio                   = 1,
275                 .deactivate_on_pd       = 1,
276         }, {
277                 .name                   = "Speaker Amplifier",
278                 .gpio                   = 2,
279                 .def_enable             = 1,
280                 .deactivate_on_pd       = 1,
281         }, {
282                 .name                   = "Headset Mic Select",
283                 .gpio                   = 3,
284         }
285 };
286
287 static struct platform_device retu_headset_device = {
288         .name           = "retu-headset",
289         .id             = -1,
290         .dev            = {
291                 .release        = NULL,
292         },
293 };
294
295 void __init n800_audio_init(struct tsc2301_platform_data *tc)
296 {
297         spin_lock_init(&audio_lock);
298
299         if (platform_device_register(&retu_headset_device) < 0)
300                 return;
301         omap_init_eac(&n800_eac_data);
302
303         tc->pll_pdc = 7;
304         tc->pll_a = 7;
305         tc->pll_n = 9;
306         tc->pll_output = 1;
307         tc->mclk_ratio = TSC2301_MCLK_256xFS;
308         tc->i2s_sample_rate = TSC2301_I2S_SR_48000;
309         tc->i2s_format = TSC2301_I2S_FORMAT0;
310         tc->power_down_blocks = TSC2301_REG_PD_MISC_MOPD;
311         tc->mixer_gpios = n800_mixer_gpios;
312         tc->n_mixer_gpios = ARRAY_SIZE(n800_mixer_gpios);
313         tc->codec_init = n800_codec_init;
314         tc->codec_cleanup = n800_codec_cleanup;
315         tc->enable_clock = n800_codec_enable_clock;
316         tc->disable_clock = n800_codec_disable_clock;
317 }
318
319 #else
320
321 void __init n800_audio_init(struct tsc2301_platform_data *tc)
322 {
323 }
324
325 #endif
326
327 #ifdef CONFIG_OMAP_DSP
328
329 int n800_audio_enable(struct dsp_kfunc_device *kdev, int stage)
330 {
331 #ifdef AUDIO_ENABLED
332         unsigned long flags;
333         int do_enable = 0;
334
335         spin_lock_irqsave(&audio_lock, flags);
336
337         pr_debug("DSP power up request (audio codec %sinitialized)\n",
338                  audio_ok ? "" : "not ");
339
340         if (enable_audio)
341                 goto out;
342         enable_audio = 1;
343         if (audio_ok)
344                 do_enable = 1;
345 out:
346         spin_unlock_irqrestore(&audio_lock, flags);
347         if (do_enable)
348                 eac_set_mode(eac_device, 1, 1);
349 #endif
350         return 0;
351 }
352
353 int n800_audio_disable(struct dsp_kfunc_device *kdev, int stage)
354 {
355 #ifdef AUDIO_ENABLED
356         unsigned long flags;
357         int do_disable = 0;
358
359         spin_lock_irqsave(&audio_lock, flags);
360
361         pr_debug("DSP power down request (audio codec %sinitialized)\n",
362                 audio_ok ? "" : "not ");
363
364         if (!enable_audio)
365                 goto out;
366         enable_audio = 0;
367         if (audio_ok)
368                 do_disable = 1;
369 out:
370         spin_unlock_irqrestore(&audio_lock, flags);
371         if (do_disable)
372                 eac_set_mode(eac_device, 0, 0);
373 #endif
374         return 0;
375 }
376
377 #endif /* CONFIG_OMAP_DSP */