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