2 * sound/arm/omap/omap-alsa-tsc2101.c
4 * Alsa codec Driver for TSC2101 chip for OMAP platform boards.
5 * Code obtained from oss omap drivers
7 * Copyright (C) 2004 Texas Instruments, Inc.
8 * Written by Nishanth Menon and Sriram Kannan
10 * Copyright (C) 2006 Instituto Nokia de Tecnologia - INdT - Manaus Brazil
11 * Alsa modularization by Daniel Petrini (d.pensator@gmail.com)
13 * Copyright (C) 2006 Mika Laitio <lamikr@cc.jyu.fi>
15 * This program is free software; you can redistribute it and/or modify it
16 * under the terms of the GNU General Public License as published by the
17 * Free Software Foundation; either version 2 of the License, or (at your
18 * option) any later version.
21 #include <linux/delay.h>
22 #include <linux/soundcard.h>
23 #include <linux/platform_device.h>
24 #include <linux/clk.h>
25 #include <linux/spi/tsc2101.h>
27 #include <linux/slab.h>
32 #include <asm/mach-types.h>
33 #include <asm/arch/dma.h>
34 #include <asm/arch/clock.h>
35 #include <asm/arch/mcbsp.h>
36 #include <asm/hardware/tsc2101.h>
37 #include <asm/arch/omap-alsa.h>
39 #include "omap-alsa-tsc2101.h"
41 struct mcbsp_dev_info mcbsp_dev;
43 static struct clk *tsc2101_mclk;
45 /* #define DUMP_TSC2101_AUDIO_REGISTERS */
46 #undef DUMP_TSC2101_AUDIO_REGISTERS
49 * Hardware capabilities
53 * DAC USB-mode sampling rates (MCLK = 12 MHz)
54 * The rates and rate_reg_into MUST be in the same order
56 static unsigned int rates[] = {
57 7350, 8000, 8018, 8727,
58 8820, 9600, 11025, 12000,
59 14700, 16000, 22050, 24000,
60 29400, 32000, 44100, 48000,
63 static struct snd_pcm_hw_constraint_list tsc2101_hw_constraints_rates = {
64 .count = ARRAY_SIZE(rates),
69 static const struct tsc2101_samplerate_reg_info
70 rate_reg_info[NUMBER_SAMPLE_RATES_SUPPORTED] = {
97 static struct snd_pcm_hardware tsc2101_snd_omap_alsa_playback = {
98 .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
99 SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID,
100 #ifdef CONFIG_MACH_OMAP_H6300
101 .formats = SNDRV_PCM_FMTBIT_S8,
103 .formats = SNDRV_PCM_FMTBIT_S16_LE,
105 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
106 SNDRV_PCM_RATE_16000 |
107 SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 |
108 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
114 .buffer_bytes_max = 128 * 1024,
115 .period_bytes_min = 32,
116 .period_bytes_max = 8 * 1024,
122 static struct snd_pcm_hardware tsc2101_snd_omap_alsa_capture = {
123 .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
124 SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID,
125 .formats = SNDRV_PCM_FMTBIT_S16_LE,
126 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
127 SNDRV_PCM_RATE_16000 |
128 SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 |
129 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
135 .buffer_bytes_max = 128 * 1024,
136 .period_bytes_min = 32,
137 .period_bytes_max = 8 * 1024,
144 * Simplified write for tsc2101 audio registers.
146 inline void tsc2101_audio_write(u8 address, u16 data)
148 tsc2101_write_sync(mcbsp_dev.tsc2101_dev, PAGE2_AUDIO_CODEC_REGISTERS,
153 * Simplified read for tsc2101 audio registers.
155 inline u16 tsc2101_audio_read(u8 address)
157 return (tsc2101_read_sync(mcbsp_dev.tsc2101_dev,
158 PAGE2_AUDIO_CODEC_REGISTERS, address));
161 #ifdef DUMP_TSC2101_AUDIO_REGISTERS
162 void dump_tsc2101_audio_reg(void)
164 dev_dbg(&mcbsp_dev.mcbsp_dev->dev,
165 "TSC2101_AUDIO_CTRL_1 = 0x%04x\n",
166 tsc2101_audio_read(TSC2101_AUDIO_CTRL_1));
167 dev_dbg(&mcbsp_dev.mcbsp_dev->dev,
168 "TSC2101_HEADSET_GAIN_CTRL = 0x%04x\n",
169 tsc2101_audio_read(TSC2101_HEADSET_GAIN_CTRL));
170 dev_dbg(&mcbsp_dev.mcbsp_dev->dev,
171 "TSC2101_DAC_GAIN_CTRL = 0x%04x\n",
172 tsc2101_audio_read(TSC2101_DAC_GAIN_CTRL));
173 dev_dbg(&mcbsp_dev.mcbsp_dev->dev,
174 "TSC2101_MIXER_PGA_CTRL = 0x%04x\n",
175 tsc2101_audio_read(TSC2101_MIXER_PGA_CTRL));
176 dev_dbg(&mcbsp_dev.mcbsp_dev->dev,
177 "TSC2101_AUDIO_CTRL_2 = 0x%04x\n",
178 tsc2101_audio_read(TSC2101_AUDIO_CTRL_2));
179 dev_dbg(&mcbsp_dev.mcbsp_dev->dev,
180 "TSC2101_CODEC_POWER_CTRL = 0x%04x\n",
181 tsc2101_audio_read(TSC2101_CODEC_POWER_CTRL));
182 dev_dbg(&mcbsp_dev.mcbsp_dev->dev,
183 "TSC2101_AUDIO_CTRL_3 = 0x%04x\n",
184 tsc2101_audio_read(TSC2101_AUDIO_CTRL_3));
185 dev_dbg(&mcbsp_dev.mcbsp_dev->dev,
186 "TSC2101_LCH_BASS_BOOST_N0 = 0x%04x\n",
187 tsc2101_audio_read(TSC2101_LCH_BASS_BOOST_N0));
188 dev_dbg(&mcbsp_dev.mcbsp_dev->dev,
189 "TSC2101_LCH_BASS_BOOST_N1 = 0x%04x\n",
190 tsc2101_audio_read(TSC2101_LCH_BASS_BOOST_N1));
191 dev_dbg(&mcbsp_dev.mcbsp_dev->dev,
192 "TSC2101_LCH_BASS_BOOST_N2 = 0x%04x\n",
193 tsc2101_audio_read(TSC2101_LCH_BASS_BOOST_N2));
194 dev_dbg(&mcbsp_dev.mcbsp_dev->dev,
195 "TSC2101_LCH_BASS_BOOST_N3 = 0x%04x\n",
196 tsc2101_audio_read(TSC2101_LCH_BASS_BOOST_N3));
197 dev_dbg(&mcbsp_dev.mcbsp_dev->dev,
198 "TSC2101_LCH_BASS_BOOST_N4 = 0x%04x\n",
199 tsc2101_audio_read(TSC2101_LCH_BASS_BOOST_N4));
200 dev_dbg(&mcbsp_dev.mcbsp_dev->dev,
201 "TSC2101_LCH_BASS_BOOST_N5 = 0x%04x\n",
202 tsc2101_audio_read(TSC2101_LCH_BASS_BOOST_N5));
203 dev_dbg(&mcbsp_dev.mcbsp_dev->dev,
204 "TSC2101_LCH_BASS_BOOST_D1 = 0x%04x\n",
205 tsc2101_audio_read(TSC2101_LCH_BASS_BOOST_D1));
206 dev_dbg(&mcbsp_dev.mcbsp_dev->dev,
207 "TSC2101_LCH_BASS_BOOST_D2 = 0x%04x\n",
208 tsc2101_audio_read(TSC2101_LCH_BASS_BOOST_D2));
209 dev_dbg(&mcbsp_dev.mcbsp_dev->dev,
210 "TSC2101_LCH_BASS_BOOST_D4 = 0x%04x\n",
211 tsc2101_audio_read(TSC2101_LCH_BASS_BOOST_D4));
212 dev_dbg(&mcbsp_dev.mcbsp_dev->dev,
213 "TSC2101_LCH_BASS_BOOST_D5 = 0x%04x\n",
214 tsc2101_audio_read(TSC2101_LCH_BASS_BOOST_D5));
216 dev_dbg(&mcbsp_dev.mcbsp_dev->dev,
217 "TSC2101_RCH_BASS_BOOST_N0 = 0x%04x\n",
218 tsc2101_audio_read(TSC2101_RCH_BASS_BOOST_N0));
219 dev_dbg(&mcbsp_dev.mcbsp_dev->dev,
220 "TSC2101_RCH_BASS_BOOST_N1 = 0x%04x\n",
221 tsc2101_audio_read(TSC2101_RCH_BASS_BOOST_N1));
222 dev_dbg(&mcbsp_dev.mcbsp_dev->dev,
223 "TSC2101_RCH_BASS_BOOST_N2 = 0x%04x\n",
224 tsc2101_audio_read(TSC2101_RCH_BASS_BOOST_N2));
225 dev_dbg(&mcbsp_dev.mcbsp_dev->dev,
226 "TSC2101_RCH_BASS_BOOST_N3 = 0x%04x\n",
227 tsc2101_audio_read(TSC2101_RCH_BASS_BOOST_N3));
228 dev_dbg(&mcbsp_dev.mcbsp_dev->dev,
229 "TSC2101_RCH_BASS_BOOST_N4 = 0x%04x\n",
230 tsc2101_audio_read(TSC2101_RCH_BASS_BOOST_N4));
231 dev_dbg(&mcbsp_dev.mcbsp_dev->dev,
232 "TSC2101_RCH_BASS_BOOST_N5 = 0x%04x\n",
233 tsc2101_audio_read(TSC2101_RCH_BASS_BOOST_N5));
234 dev_dbg(&mcbsp_dev.mcbsp_dev->dev,
235 "TSC2101_RCH_BASS_BOOST_D1 = 0x%04x\n",
236 tsc2101_audio_read(TSC2101_RCH_BASS_BOOST_D1));
237 dev_dbg(&mcbsp_dev.mcbsp_dev->dev,
238 "TSC2101_RCH_BASS_BOOST_D2 = 0x%04x\n",
239 tsc2101_audio_read(TSC2101_RCH_BASS_BOOST_D2));
240 dev_dbg(&mcbsp_dev.mcbsp_dev->dev,
241 "TSC2101_RCH_BASS_BOOST_D4 = 0x%04x\n",
242 tsc2101_audio_read(TSC2101_RCH_BASS_BOOST_D4));
243 dev_dbg(&mcbsp_dev.mcbsp_dev->dev,
244 "TSC2101_RCH_BASS_BOOST_D5 = 0x%04x\n",
245 tsc2101_audio_read(TSC2101_RCH_BASS_BOOST_D5));
247 dev_dbg(&mcbsp_dev.mcbsp_dev->dev,
248 "TSC2101_PLL_PROG_1 = 0x%04x\n",
249 tsc2101_audio_read(TSC2101_PLL_PROG_1));
250 dev_dbg(&mcbsp_dev.mcbsp_dev->dev,
251 "TSC2101_PLL_PROG_1 = 0x%04x\n",
252 tsc2101_audio_read(TSC2101_PLL_PROG_2));
253 dev_dbg(&mcbsp_dev.mcbsp_dev->dev,
254 "TSC2101_AUDIO_CTRL_4 = 0x%04x\n",
255 tsc2101_audio_read(TSC2101_AUDIO_CTRL_4));
256 dev_dbg(&mcbsp_dev.mcbsp_dev->dev,
257 "TSC2101_HANDSET_GAIN_CTRL = 0x%04x\n",
258 tsc2101_audio_read(TSC2101_HANDSET_GAIN_CTRL));
259 dev_dbg(&mcbsp_dev.mcbsp_dev->dev,
260 "TSC2101_BUZZER_GAIN_CTRL = 0x%04x\n",
261 tsc2101_audio_read(TSC2101_BUZZER_GAIN_CTRL));
262 dev_dbg(&mcbsp_dev.mcbsp_dev->dev,
263 "TSC2101_AUDIO_CTRL_5 = 0x%04x\n",
264 tsc2101_audio_read(TSC2101_AUDIO_CTRL_5));
265 dev_dbg(&mcbsp_dev.mcbsp_dev->dev,
266 "TSC2101_AUDIO_CTRL_6 = 0x%04x\n",
267 tsc2101_audio_read(TSC2101_AUDIO_CTRL_6));
268 dev_dbg(&mcbsp_dev.mcbsp_dev->dev,
269 "TSC2101_AUDIO_CTRL_7 = 0x%04x\n",
270 tsc2101_audio_read(TSC2101_AUDIO_CTRL_7));
271 dev_dbg(&mcbsp_dev.mcbsp_dev->dev,
272 "TSC2101_GPIO_CTRL = 0x%04x\n",
273 tsc2101_audio_read(TSC2101_GPIO_CTRL));
274 dev_dbg(&mcbsp_dev.mcbsp_dev->dev,
275 "TSC2101_AGC_CTRL = 0x%04x\n",
276 tsc2101_audio_read(TSC2101_AGC_CTRL));
277 dev_dbg(&mcbsp_dev.mcbsp_dev->dev,
278 "TSC2101_POWERDOWN_STS = 0x%04x\n",
279 tsc2101_audio_read(TSC2101_POWERDOWN_STS));
280 dev_dbg(&mcbsp_dev.mcbsp_dev->dev,
281 "TSC2101_MIC_AGC_CONTROL = 0x%04x\n",
282 tsc2101_audio_read(TSC2101_MIC_AGC_CONTROL));
283 dev_dbg(&mcbsp_dev.mcbsp_dev->dev,
284 "TSC2101_CELL_AGC_CONTROL = 0x%04x\n",
285 tsc2101_audio_read(TSC2101_CELL_AGC_CONTROL));
290 * ALSA operations according to board file
294 * Sample rate changing
296 void tsc2101_set_samplerate(long sample_rate)
303 /* wait for any frame to complete */
307 sample_rate = sample_rate;
308 /* Search for the right sample rate */
309 while ((rate_reg_info[count].sample_rate != sample_rate) &&
310 (count < NUMBER_SAMPLE_RATES_SUPPORTED)) {
313 if (count == NUMBER_SAMPLE_RATES_SUPPORTED) {
314 printk(KERN_ERR "Invalid Sample Rate %d requested\n",
320 data = tsc2101_audio_read(TSC2101_AUDIO_CTRL_1);
321 /* Clear prev settings */
322 data &= ~(AC1_DACFS(0x07) | AC1_ADCFS(0x07));
323 data |= AC1_DACFS(rate_reg_info[count].divisor) |
324 AC1_ADCFS(rate_reg_info[count].divisor);
325 tsc2101_audio_write(TSC2101_AUDIO_CTRL_1, data);
328 data = tsc2101_audio_read(TSC2101_AUDIO_CTRL_3);
329 /*Clear prev settings */
330 data &= ~(AC3_REFFS | AC3_SLVMS);
331 data |= (rate_reg_info[count].fs_44kHz) ? AC3_REFFS : 0;
334 #endif /* #ifdef TSC_MASTER */
335 tsc2101_audio_write(TSC2101_AUDIO_CTRL_3, data);
338 * Program the PLLs. This code assumes that the 12 Mhz MCLK is in use.
339 * If MCLK rate is something else, these values must be changed.
340 * See the tsc2101 specification for the details.
342 if (rate_reg_info[count].fs_44kHz) {
343 /* samplerate = (44.1kHZ / x), where x is int. */
344 tsc2101_audio_write(TSC2101_PLL_PROG_1, PLL1_PLLSEL |
345 /* PVAL 1; I_VAL 7 */
346 PLL1_PVAL(1) | PLL1_I_VAL(7));
348 tsc2101_audio_write(TSC2101_PLL_PROG_2, PLL2_D_VAL(0x1490));
350 /* samplerate = (48.kHZ / x), where x is int. */
351 tsc2101_audio_write(TSC2101_PLL_PROG_1, PLL1_PLLSEL |
352 /* PVAL 1; I_VAL 8 */
353 PLL1_PVAL(1) | PLL1_I_VAL(8));
355 tsc2101_audio_write(TSC2101_PLL_PROG_2, PLL2_D_VAL(0x780));
358 /* Set the sample rate */
360 clkgdv = CODEC_CLOCK / (sample_rate * (DEFAULT_BITPERSAMPLE * 2 - 1));
362 srgr1 = (FWID(DEFAULT_BITPERSAMPLE - 1) | CLKGDV(clkgdv));
367 srgr2 = (CLKSM | FSGM | FPER(DEFAULT_BITPERSAMPLE * 2 - 1));
369 srgr1 = (FWID(DEFAULT_BITPERSAMPLE - 1) | CLKGDV(clkgdv));
370 srgr2 = ((GSYNC | CLKSP | FSGM | FPER(DEFAULT_BITPERSAMPLE * 2 - 1)));
372 #endif /* end of #ifdef TSC_MASTER */
373 OMAP_MCBSP_WRITE(OMAP1610_MCBSP1_BASE, SRGR2, srgr2);
374 OMAP_MCBSP_WRITE(OMAP1610_MCBSP1_BASE, SRGR1, srgr1);
377 void tsc2101_configure(void)
382 * Omap MCBSP clock and Power Management configuration
384 * Here we have some functions that allows clock to be enabled and
385 * disabled only when needed. Besides doing clock configuration
386 * it allows turn on/turn off audio when necessary.
390 * Do clock framework mclk search
392 void tsc2101_clock_setup(void)
394 tsc2101_mclk = clk_get(0, "mclk");
398 * Do some sanity check, set clock rate, starts it and turn codec audio on
400 int tsc2101_clock_on(void)
406 curUseCount = clk_get_usecount(tsc2101_mclk);
407 DPRINTK("clock use count = %d\n", curUseCount);
408 if (curUseCount > 0) {
409 /* MCLK is already in use */
411 "MCLK already in use at %d Hz. We change it to %d Hz\n",
412 (uint) clk_get_rate(tsc2101_mclk),
415 curRate = (uint)clk_get_rate(tsc2101_mclk);
416 if (curRate != CODEC_CLOCK) {
417 err = clk_set_rate(tsc2101_mclk, CODEC_CLOCK);
419 printk(KERN_WARNING "Cannot set MCLK clock rate for "
420 "TSC2101 CODEC, error code = %d\n", err);
424 err = clk_enable(tsc2101_mclk);
425 curRate = (uint)clk_get_rate(tsc2101_mclk);
426 curUseCount = clk_get_usecount(tsc2101_mclk);
427 DPRINTK("MCLK = %d [%d], usecount = %d, clk_enable retval = %d\n",
433 /* Now turn the audio on */
434 tsc2101_write_sync(mcbsp_dev.tsc2101_dev, PAGE2_AUDIO_CODEC_REGISTERS,
435 TSC2101_CODEC_POWER_CTRL,
441 * Do some sanity check, turn clock off and then turn codec audio off
443 int tsc2101_clock_off(void)
448 curUseCount = clk_get_usecount(tsc2101_mclk);
449 DPRINTK("clock use count = %d\n", curUseCount);
450 if (curUseCount > 0) {
451 curRate = clk_get_rate(tsc2101_mclk);
452 DPRINTK("clock rate = %d\n", curRate);
453 if (curRate != CODEC_CLOCK) {
455 "MCLK for audio should be %d Hz. But is %d Hz\n",
456 (uint) clk_get_rate(tsc2101_mclk),
459 clk_disable(tsc2101_mclk);
460 DPRINTK("clock disabled\n");
462 tsc2101_audio_write(TSC2101_CODEC_POWER_CTRL,
463 ~(CPC_SP1PWDN | CPC_SP2PWDN | CPC_BASSBC));
464 DPRINTK("audio codec off\n");
468 int tsc2101_get_default_samplerate(void)
470 return DEFAULT_SAMPLE_RATE;
473 static int __devinit snd_omap_alsa_tsc2101_probe(struct platform_device *pdev)
475 struct spi_device *tsc2101;
477 struct omap_alsa_codec_config *codec_cfg;
479 tsc2101 = dev_get_drvdata(&pdev->dev);
480 if (tsc2101 == NULL) {
481 dev_err(&pdev->dev, "no platform data\n");
484 if (strncmp(tsc2101->modalias, "tsc2101", 8) != 0) {
485 dev_err(&pdev->dev, "tsc2101 not found\n");
488 mcbsp_dev.mcbsp_dev = pdev;
489 mcbsp_dev.tsc2101_dev = tsc2101;
491 codec_cfg = pdev->dev.platform_data;
492 if (codec_cfg != NULL) {
493 codec_cfg->hw_constraints_rates =
494 &tsc2101_hw_constraints_rates;
495 codec_cfg->snd_omap_alsa_playback =
496 &tsc2101_snd_omap_alsa_playback;
497 codec_cfg->snd_omap_alsa_capture =
498 &tsc2101_snd_omap_alsa_capture;
499 codec_cfg->codec_configure_dev = tsc2101_configure;
500 codec_cfg->codec_set_samplerate = tsc2101_set_samplerate;
501 codec_cfg->codec_clock_setup = tsc2101_clock_setup;
502 codec_cfg->codec_clock_on = tsc2101_clock_on;
503 codec_cfg->codec_clock_off = tsc2101_clock_off;
504 codec_cfg->get_default_samplerate =
505 tsc2101_get_default_samplerate;
506 ret = snd_omap_alsa_post_probe(pdev, codec_cfg);
512 static struct platform_driver omap_alsa_driver = {
513 .probe = snd_omap_alsa_tsc2101_probe,
514 .remove = snd_omap_alsa_remove,
515 .suspend = snd_omap_alsa_suspend,
516 .resume = snd_omap_alsa_resume,
518 .name = "omap_alsa_mcbsp",
522 static int __init omap_alsa_tsc2101_init(void)
525 #ifdef DUMP_TSC2101_AUDIO_REGISTERS
526 printk(KERN_INFO "omap_alsa_tsc2101_init()\n");
527 dump_tsc2101_audio_reg();
529 return platform_driver_register(&omap_alsa_driver);
532 static void __exit omap_alsa_tsc2101_exit(void)
535 #ifdef DUMP_TSC2101_AUDIO_REGISTERS
536 printk(KERN_INFO "omap_alsa_tsc2101_exit()\n");
537 dump_tsc2101_audio_reg();
539 platform_driver_unregister(&omap_alsa_driver);
542 module_init(omap_alsa_tsc2101_init);
543 module_exit(omap_alsa_tsc2101_exit);