]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - sound/oss/omap-audio-tsc2101.c
Merge current mainline tree into linux-omap tree
[linux-2.6-omap-h63xx.git] / sound / oss / omap-audio-tsc2101.c
1 /*
2  * linux/sound/oss/omap-audio-tsc2101.c
3  *
4  * Glue driver for TSC2101 for OMAP processors
5  *
6  * Copyright (C) 2004 Texas Instruments, Inc.
7  *
8  * This package is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundation.
11  *
12  * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
13  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
14  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
15  *
16  * History:
17  *  -------
18  *  2004-08-12 Nishanth Menon - Modified to integrate Audio requirements on 1610,1710 platforms.
19  *  2004-09-14 Sriram Kannan - Added /proc support for asynchronous starting/stopping the codec
20  *              (without affecting the normal driver flow).
21  *  2004-11-04 Nishanth Menon - Support for power management
22  *  2004-11-07 Nishanth Menon - Support for Common TSC access b/w Touchscreen and audio drivers
23  */
24
25 /***************************** INCLUDES ************************************/
26
27 #include <linux/module.h>
28 #include <linux/init.h>
29 #include <linux/types.h>
30 #include <linux/fs.h>
31 #include <linux/delay.h>
32 #include <linux/pm.h>
33 #include <linux/errno.h>
34 #include <linux/sound.h>
35 #include <linux/soundcard.h>
36 #include <linux/mutex.h>
37
38 #include <asm/uaccess.h>
39 #include <mach/hardware.h>
40 #include <mach/dma.h>
41 #include <asm/io.h>
42 #include <mach/hardware.h>
43
44 #include <mach/mux.h>
45 #include <mach/io.h>
46 #include <asm/mach-types.h>
47
48 #include "omap-audio.h"
49 #include "omap-audio-dma-intfc.h"
50 #include <mach/mcbsp.h>
51 #ifdef CONFIG_ARCH_OMAP16XX
52 #include <../drivers/ssi/omap-uwire.h>
53 #include <mach/dsp_common.h>
54 #elif defined(CONFIG_ARCH_OMAP24XX)
55 #else
56 #error "Unsupported configuration"
57 #endif
58
59 #include <asm/hardware/tsc2101.h>
60 #include <../drivers/ssi/omap-tsc2101.h>
61
62 /***************************** MACROS ************************************/
63
64 #define PROC_SUPPORT
65
66 #ifdef PROC_SUPPORT
67 #include <linux/proc_fs.h>
68 #define PROC_START_FILE "driver/tsc2101-audio-start"
69 #define PROC_STOP_FILE  "driver/tsc2101-audio-stop"
70 #endif
71
72 #define CODEC_NAME               "TSC2101"
73
74 #ifdef CONFIG_ARCH_OMAP16XX
75 #define PLATFORM_NAME "OMAP16XX"
76 #elif defined(CONFIG_ARCH_OMAP24XX)
77 #define PLATFORM_NAME "OMAP2"
78 #endif
79
80 /* Define to set the tsc as the master w.r.t McBSP */
81 #define TSC_MASTER
82
83 /*
84  * AUDIO related MACROS
85  */
86 #define DEFAULT_BITPERSAMPLE          16
87 #define AUDIO_RATE_DEFAULT                44100
88 #define PAGE2_AUDIO_CODEC_REGISTERS   (2)
89 #define LEAVE_CS                                  0x80
90
91 /* Select the McBSP For Audio */
92 /* 16XX is MCBSP1 and 24XX is MCBSP2*/
93 /* see include/asm-arm/arch-omap/mcbsp.h */
94 #ifndef AUDIO_MCBSP
95 #error "UnSupported Configuration"
96 #endif
97
98 #define REC_MASK                                  (SOUND_MASK_LINE | SOUND_MASK_MIC)
99 #define DEV_MASK                                  (REC_MASK | SOUND_MASK_VOLUME)
100
101 #define SET_VOLUME                                1
102 #define SET_LINE                                  2
103 #define SET_MIC       3
104 #define SET_RECSRC            4
105
106 #define DEFAULT_VOLUME                93
107 #define DEFAULT_INPUT_VOLUME      20    /* An minimal volume */
108
109 /* Tsc Audio Specific */
110 #define NUMBER_SAMPLE_RATES_SUPPORTED 16
111 #define OUTPUT_VOLUME_MIN 0x7F
112 #define OUTPUT_VOLUME_MAX 0x32
113 #define OUTPUT_VOLUME_RANGE           (OUTPUT_VOLUME_MIN - OUTPUT_VOLUME_MAX)
114 #define OUTPUT_VOLUME_MASK            OUTPUT_VOLUME_MIN
115 #define DEFAULT_VOLUME_LEVEL          OUTPUT_VOLUME_MAX
116
117 /* use input vol of 75 for 0dB gain */
118 #define INPUT_VOLUME_MIN                      0x0
119 #define INPUT_VOLUME_MAX         0x7D
120 #define INPUT_VOLUME_RANGE                    (INPUT_VOLUME_MAX - INPUT_VOLUME_MIN)
121 #define INPUT_VOLUME_MASK                     INPUT_VOLUME_MAX
122
123 /*********** Debug Macros ********/
124 /* To Generate a rather shrill tone -test the entire path */
125 //#define TONE_GEN
126 /* To Generate a tone for each keyclick - test the tsc,spi paths*/
127 //#define TEST_KEYCLICK
128 /* To dump the tsc registers for debug */
129 //#define TSC_DUMP_REGISTERS
130
131 #ifdef DPRINTK
132 #undef DPRINTK
133 #endif
134 #undef DEBUG
135
136 //#define DEBUG
137 #ifdef DEBUG
138 #define DPRINTK(ARGS...)  printk(KERN_INFO "<%s>: ",__FUNCTION__);printk(ARGS)
139 #define FN_IN printk(KERN_INFO "[%s]: start\n", __FUNCTION__)
140 #define FN_OUT(n) printk(KERN_INFO "[%s]: end(%u)\n",__FUNCTION__, n)
141 #else
142 #define DPRINTK( x... )
143 #define FN_IN
144 #define FN_OUT(n)
145 #endif
146
147 /***************************** Data Structures **********************************/
148
149 static int audio_ifc_start(void)
150 {
151         omap_mcbsp_start(AUDIO_MCBSP);
152         return 0;
153 }
154
155 static int audio_ifc_stop(void)
156 {
157         omap_mcbsp_stop(AUDIO_MCBSP);
158         return 0;
159 }
160
161 static audio_stream_t output_stream = {
162         .id                     = "TSC2101 out",
163         .dma_dev                = AUDIO_DMA_TX,
164         .input_or_output        = FMODE_WRITE,
165         .hw_start               = audio_ifc_start,
166         .hw_stop                = audio_ifc_stop,
167 };
168
169 static audio_stream_t input_stream = {
170         .id                     = "TSC2101 in",
171         .dma_dev                = AUDIO_DMA_RX,
172         .input_or_output        = FMODE_READ,
173         .hw_start               = audio_ifc_start,
174         .hw_stop                = audio_ifc_stop,
175 };
176
177 static int audio_dev_id, mixer_dev_id;
178
179 typedef struct {
180         u8      volume;
181         u8      line;
182         u8      mic;
183         int     recsrc;
184         int     mod_cnt;
185 } tsc2101_local_info;
186
187 static tsc2101_local_info tsc2101_local = {
188         volume:         DEFAULT_VOLUME,
189         line:           DEFAULT_INPUT_VOLUME,
190         mic:            DEFAULT_INPUT_VOLUME,
191         recsrc:         SOUND_MASK_LINE,
192         mod_cnt:        0
193 };
194
195 struct sample_rate_reg_info {
196         u16 sample_rate;
197         u8  divisor;
198         u8  fs_44kHz;           /* if 0 48 khz, if 1 44.1 khz fsref */
199 };
200
201 /* To Store the default sample rate */
202 static long audio_samplerate = AUDIO_RATE_DEFAULT;
203
204 static const struct sample_rate_reg_info
205  reg_info[NUMBER_SAMPLE_RATES_SUPPORTED] = {
206         /* Div 1 */
207         {48000, 0, 0},
208         {44100, 0, 1},
209         /* Div 1.5 */
210         {32000, 1, 0},
211         {29400, 1, 1},
212         /* Div 2 */
213         {24000, 2, 0},
214         {22050, 2, 1},
215         /* Div 3 */
216         {16000, 3, 0},
217         {14700, 3, 1},
218         /* Div 4 */
219         {12000, 4, 0},
220         {11025, 4, 1},
221         /* Div 5 */
222         {9600, 5, 0},
223         {8820, 5, 1},
224         /* Div 5.5 */
225         {8727, 6, 0},
226         {8018, 6, 1},
227         /* Div 6 */
228         {8000, 7, 0},
229         {7350, 7, 1},
230 };
231
232 static struct omap_mcbsp_reg_cfg initial_config = {
233         .spcr2 = FREE | FRST | GRST | XRST | XINTM(3),
234         .spcr1 = RINTM(3) | RRST,
235         .rcr2  = RPHASE | RFRLEN2(OMAP_MCBSP_WORD_8) |
236                  RWDLEN2(OMAP_MCBSP_WORD_16) | RDATDLY(1),
237         .rcr1  = RFRLEN1(OMAP_MCBSP_WORD_8) | RWDLEN1(OMAP_MCBSP_WORD_16),
238         .xcr2  = XPHASE | XFRLEN2(OMAP_MCBSP_WORD_8) |
239                  XWDLEN2(OMAP_MCBSP_WORD_16) | XDATDLY(1) | XFIG,
240         .xcr1  = XFRLEN1(OMAP_MCBSP_WORD_8) | XWDLEN1(OMAP_MCBSP_WORD_16),
241         .srgr1 = FWID(15),
242         .srgr2 = GSYNC | CLKSP | FSGM | FPER(31),
243
244         /* platform specific initialization */
245 #ifdef CONFIG_MACH_OMAP_H2
246         .pcr0  = CLKXM | CLKRM | FSXP | FSRP | CLKXP | CLKRP,
247 #elif defined(CONFIG_MACH_OMAP_H3) || defined(CONFIG_MACH_OMAP_H4) || defined(CONFIG_MACH_OMAP_APOLLON)
248
249 #ifndef TSC_MASTER
250         .pcr0  = FSXM | FSRM | CLKXM | CLKRM | CLKXP | CLKRP,
251 #else
252         .pcr0  = CLKRM | SCLKME | FSXP | FSRP | CLKXP | CLKRP,
253 #endif                          /* tsc Master defs */
254
255 #endif                          /* platform specific inits */
256 };
257
258 /***************************** MODULES SPECIFIC FUNCTION PROTOTYPES ********************/
259
260 static void omap_tsc2101_initialize(void *dummy);
261
262 static void omap_tsc2101_shutdown(void *dummy);
263
264 static int  omap_tsc2101_ioctl(struct inode *inode, struct file *file,
265                                uint cmd, ulong arg);
266
267 static int  omap_tsc2101_probe(void);
268
269 static void omap_tsc2101_remove(void);
270
271 static int  omap_tsc2101_suspend(void);
272
273 static int  omap_tsc2101_resume(void);
274
275 static void tsc2101_configure(void);
276
277 static int  mixer_open(struct inode *inode, struct file *file);
278
279 static int  mixer_release(struct inode *inode, struct file *file);
280
281 static int  mixer_ioctl(struct inode *inode, struct file *file, uint cmd,
282                         ulong arg);
283
284 #ifdef TEST_KEYCLICK
285 void tsc2101_testkeyclick(void);
286 #endif
287
288 #ifdef TONE_GEN
289 void toneGen(void);
290 #endif
291
292 #ifdef TSC_DUMP_REGISTERS
293 static void tsc2101_dumpRegisters(void);
294 #endif
295
296 #ifdef PROC_SUPPORT
297 static int codec_start(char *buf, char **start, off_t offset, int count,
298                        int *eof, void *data);
299
300 static int codec_stop(char *buf, char **start, off_t offset, int count,
301                       int *eof, void *data);
302
303 static void tsc2101_start(void);
304 #endif
305
306 /******************** DATA STRUCTURES USING FUNCTION POINTERS **************************/
307
308 /* File Op structure for mixer */
309 static struct file_operations omap_mixer_fops = {
310         .open           = mixer_open,
311         .release        = mixer_release,
312         .ioctl          = mixer_ioctl,
313         .owner          = THIS_MODULE
314 };
315
316 /* To store characteristic info regarding the codec for the audio driver */
317 static audio_state_t tsc2101_state = {
318         .output_stream  = &output_stream,
319         .input_stream   = &input_stream,
320 /*      .need_tx_for_rx = 1, //Once the Full Duplex works  */
321         .need_tx_for_rx = 0,
322         .hw_init        = omap_tsc2101_initialize,
323         .hw_shutdown    = omap_tsc2101_shutdown,
324         .client_ioctl   = omap_tsc2101_ioctl,
325         .hw_probe       = omap_tsc2101_probe,
326         .hw_remove      = omap_tsc2101_remove,
327         .hw_suspend     = omap_tsc2101_suspend,
328         .hw_resume      = omap_tsc2101_resume,
329 };
330
331 /* This will be defined in the Audio.h */
332 static struct file_operations *omap_audio_fops;
333
334 /***************************** MODULES SPECIFIC FUNCTIONs *******************************/
335
336 /*********************************************************************************
337  *
338  * Simplified write for tsc Audio
339  *
340  *********************************************************************************/
341 static __inline__ void audio_tsc2101_write(u8 address, u16 data)
342 {
343         omap_tsc2101_write(PAGE2_AUDIO_CODEC_REGISTERS, address, data);
344 }
345
346 /*********************************************************************************
347  *
348  * Simplified read for tsc  Audio
349  *
350  *********************************************************************************/
351 static __inline__ u16 audio_tsc2101_read(u8 address)
352 {
353         return (omap_tsc2101_read(PAGE2_AUDIO_CODEC_REGISTERS, address));
354 }
355
356 /*********************************************************************************
357  *
358  * tsc2101_update()
359  * Volume Adj etc
360  *
361  ********************************************************************************/
362 static int tsc2101_update(int flag, int val)
363 {
364         u16 volume;
365         u16 data;
366
367         FN_IN;
368         switch (flag) {
369         case SET_VOLUME:
370                 if (val < 0 || val > 100) {
371                         printk(KERN_ERR "Trying a bad volume value(%d)!\n", val);
372                         return -EPERM;
373                 }
374                 /* Convert 0 -> 100 volume to 0x7F(min) -> y(max) volume range */
375                 volume =
376                     ((val * OUTPUT_VOLUME_RANGE) / 100) + OUTPUT_VOLUME_MAX;
377                 /* invert the value for getting the proper range 0 min and 100 max */
378                 volume = OUTPUT_VOLUME_MIN - volume;
379                 data = audio_tsc2101_read(TSC2101_DAC_GAIN_CTRL);
380                 data &=
381                     ~(DGC_DALVL(OUTPUT_VOLUME_MIN) |
382                       DGC_DARVL(OUTPUT_VOLUME_MIN));
383                 data |= DGC_DALVL(volume) | DGC_DARVL(volume);
384                 audio_tsc2101_write(TSC2101_DAC_GAIN_CTRL, data);
385                 data = audio_tsc2101_read(TSC2101_DAC_GAIN_CTRL);
386
387                 break;
388
389         case SET_LINE:
390                 if (val < 0 || val > 100) {
391                         printk(KERN_ERR "Trying a bad volume value(%d)!\n", val);
392                         return -EPERM;
393                 }
394                 /* Convert 0 -> 100 volume to 0x0(min) -> 0x7D(max) volume range */
395                 /* NOTE: 0 is minimum volume and not mute */
396                 volume = ((val * INPUT_VOLUME_RANGE) / 100) + INPUT_VOLUME_MIN;
397                 /* Handset Input not muted, AGC for Handset In off */
398                 audio_tsc2101_write(TSC2101_HEADSET_GAIN_CTRL,
399         HGC_ADPGA_HED(volume));
400                 break;
401
402         case SET_MIC:
403                 if (val < 0 || val > 100) {
404                         printk(KERN_ERR "Trying a bad volume value(%d)!\n", val);
405                         return -EPERM;
406                 }
407                 /* Convert 0 -> 100 volume to 0x0(min) -> 0x7D(max) volume range */
408                 /* NOTE: 0 is minimum volume and not mute */
409                 volume = ((val * INPUT_VOLUME_RANGE) / 100) + INPUT_VOLUME_MIN;
410                 /* Handset Input not muted, AGC for Handset In off */
411                 audio_tsc2101_write(TSC2101_HANDSET_GAIN_CTRL,
412         HNGC_ADPGA_HND(volume));
413                 break;
414
415         case SET_RECSRC:
416                 /*
417                  * If more than one recording device selected,
418                  * disable the device that is currently in use.
419                  */
420                 if (hweight32(val) > 1)
421                         val &= ~tsc2101_local.recsrc;
422
423                 data = audio_tsc2101_read(TSC2101_MIXER_PGA_CTRL);
424                 data &= ~MPC_MICSEL(7); /* clear all MICSEL bits */
425
426                 if (val == SOUND_MASK_MIC) {
427                         data |=  MPC_MICSEL(1);
428                         audio_tsc2101_write(TSC2101_MIXER_PGA_CTRL, data);
429                 }
430                 else if (val == SOUND_MASK_LINE) {
431                         data |=  MPC_MICSEL(0);
432                         audio_tsc2101_write(TSC2101_MIXER_PGA_CTRL, data);
433                 }
434                 else {
435                         printk(KERN_WARNING "omap1610-tsc2101: Wrong RECSRC"
436          " value specified\n");
437                         return -EINVAL;
438                 }
439                 tsc2101_local.recsrc = val;
440                 break;
441         default:
442                 printk(KERN_WARNING "omap1610-tsc2101: Wrong tsc2101_update "
443         "flag specified\n");
444                 break;
445         }
446
447         FN_OUT(0);
448         return 0;
449 }
450
451 /*********************************************************************************
452  *
453  * mixer_open()
454  *
455  ********************************************************************************/
456 static int mixer_open(struct inode *inode, struct file *file)
457 {
458         /* Any mixer specific initialization */
459
460         /* Initalize the tsc2101 */
461         omap_tsc2101_enable();
462
463         return 0;
464 }
465
466 /*********************************************************************************
467  *
468  * mixer_release()
469  *
470  ********************************************************************************/
471 static int mixer_release(struct inode *inode, struct file *file)
472 {
473         /* Any mixer specific Un-initialization */
474         omap_tsc2101_disable();
475
476         return 0;
477 }
478
479 /*********************************************************************************
480  *
481  * mixer_ioctl()
482  *
483  ********************************************************************************/
484 static int
485 mixer_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
486 {
487         int val;
488         int gain;
489         int ret = 0;
490         int nr = _IOC_NR(cmd);
491
492         /*
493          * We only accept mixer (type 'M') ioctls.
494          */
495         FN_IN;
496         if (_IOC_TYPE(cmd) != 'M')
497                 return -EINVAL;
498
499         DPRINTK(" 0x%08x\n", cmd);
500
501         if (cmd == SOUND_MIXER_INFO) {
502                 struct mixer_info mi;
503
504                 strncpy(mi.id, "TSC2101", sizeof(mi.id));
505                 strncpy(mi.name, "TI TSC2101", sizeof(mi.name));
506                 mi.modify_counter = tsc2101_local.mod_cnt;
507                 FN_OUT(1);
508                 return copy_to_user((void __user *)arg, &mi, sizeof(mi));
509         }
510
511         if (_IOC_DIR(cmd) & _IOC_WRITE) {
512                 ret = get_user(val, (int __user *)arg);
513                 if (ret)
514                         goto out;
515
516                 /* Ignore separate left/right channel for now,
517                  * even the codec does support it.
518                  */
519                 gain = val & 255;
520
521                 switch (nr) {
522                 case SOUND_MIXER_VOLUME:
523                         tsc2101_local.volume = val;
524                         tsc2101_local.mod_cnt++;
525                         ret = tsc2101_update(SET_VOLUME, gain);
526                         break;
527
528                 case SOUND_MIXER_LINE:
529                         tsc2101_local.line = val;
530                         tsc2101_local.mod_cnt++;
531                         ret = tsc2101_update(SET_LINE, gain);
532                         break;
533
534                 case SOUND_MIXER_MIC:
535                         tsc2101_local.mic = val;
536                         tsc2101_local.mod_cnt++;
537                         ret = tsc2101_update(SET_MIC, gain);
538                         break;
539
540                 case SOUND_MIXER_RECSRC:
541                         if ((val & SOUND_MASK_LINE) ||
542                             (val & SOUND_MASK_MIC)) {
543                                 if (tsc2101_local.recsrc != val) {
544                                         tsc2101_local.mod_cnt++;
545                                         tsc2101_update(SET_RECSRC, val);
546                                 }
547                         }
548                         else {
549                                 ret = -EINVAL;
550                         }
551                         break;
552
553                 default:
554                         ret = -EINVAL;
555                 }
556         }
557
558         if (ret == 0 && _IOC_DIR(cmd) & _IOC_READ) {
559                 ret = 0;
560
561                 switch (nr) {
562                 case SOUND_MIXER_VOLUME:
563                         val = tsc2101_local.volume;
564                         val = (tsc2101_local.volume << 8) |
565           tsc2101_local.volume;
566                         break;
567                 case SOUND_MIXER_LINE:
568                         val = (tsc2101_local.line << 8) |
569           tsc2101_local.line;
570                         break;
571                 case SOUND_MIXER_MIC:
572                         val = (tsc2101_local.mic << 8) |
573           tsc2101_local.mic;
574                         break;
575                 case SOUND_MIXER_RECSRC:
576                         val = tsc2101_local.recsrc;
577                         break;
578                 case SOUND_MIXER_RECMASK:
579                         val = REC_MASK;
580                         break;
581                 case SOUND_MIXER_DEVMASK:
582                         val = DEV_MASK;
583                         break;
584                 case SOUND_MIXER_CAPS:
585                         val = 0;
586                         break;
587                 case SOUND_MIXER_STEREODEVS:
588                         val = SOUND_MASK_VOLUME;
589                         break;
590                 default:
591                         val = 0;
592                         printk(KERN_WARNING "omap1610-tsc2101: unknown mixer "
593          "read ioctl flag specified\n");
594                         ret = -EINVAL;
595                         break;
596                 }
597
598                 if (ret == 0)
599                         ret = put_user(val, (int __user *)arg);
600         }
601       out:
602         FN_OUT(0);
603         return ret;
604
605 }
606
607 /*********************************************************************************
608  *
609  * omap_set_samplerate()
610  *
611  ********************************************************************************/
612 static int omap_set_samplerate(long sample_rate)
613 {
614         u8 count = 0;
615         u16 data = 0;
616         int clkgdv = 0;
617         /* wait for any frame to complete */
618         udelay(125);
619
620         /* Search for the right sample rate */
621         while ((reg_info[count].sample_rate != sample_rate) &&
622                (count < NUMBER_SAMPLE_RATES_SUPPORTED)) {
623                 count++;
624         }
625         if (count == NUMBER_SAMPLE_RATES_SUPPORTED) {
626                 printk(KERN_ERR "Invalid Sample Rate %d requested\n",
627                        (int)sample_rate);
628                 return -EPERM;
629         }
630
631         /* Set AC1 */
632         data = audio_tsc2101_read(TSC2101_AUDIO_CTRL_1);
633         /*Clear prev settings */
634         data &= ~(AC1_DACFS(0x07) | AC1_ADCFS(0x07));
635         data |=
636             AC1_DACFS(reg_info[count].divisor) | AC1_ADCFS(reg_info[count].
637                                                            divisor);
638         audio_tsc2101_write(TSC2101_AUDIO_CTRL_1, data);
639
640         /* Set the AC3 */
641         data = audio_tsc2101_read(TSC2101_AUDIO_CTRL_3);
642         /*Clear prev settings */
643         data &= ~(AC3_REFFS | AC3_SLVMS);
644         data |= (reg_info[count].fs_44kHz) ? AC3_REFFS : 0;
645 #ifdef TSC_MASTER
646         data |= AC3_SLVMS;
647 #endif                          /* #ifdef TSC_MASTER */
648         audio_tsc2101_write(TSC2101_AUDIO_CTRL_3, data);
649
650         /* program the PLLs */
651         if (reg_info[count].fs_44kHz) {
652                 /* 44.1 khz - 12 MHz Mclk */
653                 audio_tsc2101_write(TSC2101_PLL_PROG_1, PLL1_PLLSEL | PLL1_PVAL(1) | PLL1_I_VAL(7));    /* PVAL 1; I_VAL 7 */
654                 audio_tsc2101_write(TSC2101_PLL_PROG_2, PLL2_D_VAL(0x1490));    /* D_VAL 5264 */
655         } else {
656                 /* 48 khz - 12 Mhz Mclk */
657                 audio_tsc2101_write(TSC2101_PLL_PROG_1, PLL1_PLLSEL | PLL1_PVAL(1) | PLL1_I_VAL(8));    /* PVAL 1; I_VAL 8 */
658                 audio_tsc2101_write(TSC2101_PLL_PROG_2, PLL2_D_VAL(0x780));     /* D_VAL 1920 */
659         }
660
661         audio_samplerate = sample_rate;
662
663         /* Set the sample rate */
664 #ifndef TSC_MASTER
665         clkgdv =
666             DEFAULT_MCBSP_CLOCK / (sample_rate *
667                                    (DEFAULT_BITPERSAMPLE * 2 - 1));
668         if (clkgdv)
669                 initial_config.srgr1 =
670                     (FWID(DEFAULT_BITPERSAMPLE - 1) | CLKGDV(clkgdv));
671         else
672                 return (1);
673
674         /* Stereo Mode */
675         initial_config.srgr2 =
676             (CLKSM | FSGM | FPER(DEFAULT_BITPERSAMPLE * 2 - 1));
677 #else
678         initial_config.srgr1 =
679             (FWID(DEFAULT_BITPERSAMPLE - 1) | CLKGDV(clkgdv));
680         initial_config.srgr2 =
681             ((GSYNC | CLKSP | FSGM | FPER(DEFAULT_BITPERSAMPLE * 2 - 1)));
682
683 #endif                          /* end of #ifdef TSC_MASTER */
684         omap_mcbsp_config(AUDIO_MCBSP, &initial_config);
685
686         return 0;
687 }
688
689 /*********************************************************************************
690  *
691  * omap_tsc2101_initialize() [hw_init() ]
692  *
693  ********************************************************************************/
694 static void omap_tsc2101_initialize(void *dummy)
695 {
696
697         DPRINTK("omap_tsc2101_initialize entry\n");
698
699         /* initialize with default sample rate */
700         audio_samplerate = AUDIO_RATE_DEFAULT;
701
702         omap_mcbsp_request(AUDIO_MCBSP);
703
704         /* if configured, then stop mcbsp */
705         omap_mcbsp_stop(AUDIO_MCBSP);
706
707         omap_tsc2101_enable();
708
709         omap_mcbsp_config(AUDIO_MCBSP, &initial_config);
710         omap_mcbsp_start(AUDIO_MCBSP);
711         tsc2101_configure();
712
713 #ifdef TEST_KEYCLICK
714         tsc2101_testkeyclick();
715 #endif
716
717 #ifdef TONE_GEN
718         toneGen();
719 #endif
720
721         DPRINTK("omap_tsc2101_initialize exit\n");
722 }
723
724 /*********************************************************************************
725  *
726  * omap_tsc2101_shutdown() [hw_shutdown() ]
727  *
728  ********************************************************************************/
729 static void omap_tsc2101_shutdown(void *dummy)
730 {
731         /*
732            Turn off codec after it is done.
733            Can't do it immediately, since it may still have
734            buffered data.
735
736            Wait 20ms (arbitrary value) and then turn it off.
737          */
738
739         FN_IN;
740         set_current_state(TASK_INTERRUPTIBLE);
741         schedule_timeout(2);
742
743         omap_mcbsp_stop(AUDIO_MCBSP);
744         omap_mcbsp_free(AUDIO_MCBSP);
745
746         audio_tsc2101_write(TSC2101_CODEC_POWER_CTRL,
747                             ~(CPC_SP1PWDN | CPC_SP2PWDN | CPC_BASSBC));
748
749         omap_tsc2101_disable();
750
751         FN_OUT(0);
752 }
753
754 /*********************************************************************************
755  *
756  * tsc2101_configure
757  *
758  ********************************************************************************/
759 static void tsc2101_configure(void)
760 {
761         FN_IN;
762
763         audio_tsc2101_write(TSC2101_CODEC_POWER_CTRL, 0x0000);
764
765         /*Mute Analog Sidetone */
766         /*Select MIC_INHED input for headset */
767         /*Cell Phone In not connected */
768         audio_tsc2101_write(TSC2101_MIXER_PGA_CTRL,
769                             MPC_ASTMU | MPC_ASTG(0x40) | MPC_MICADC);
770
771         /* Set record source */
772         tsc2101_update(SET_RECSRC, tsc2101_local.recsrc);
773
774         /* ADC, DAC, Analog Sidetone, cellphone, buzzer softstepping enabled */
775         /* 1dB AGC hysteresis */
776         /* MICes bias 2V */
777         audio_tsc2101_write(TSC2101_AUDIO_CTRL_4, AC4_MB_HED(0));
778
779         /* Set codec output volume */
780         audio_tsc2101_write(TSC2101_DAC_GAIN_CTRL, 0x0000);
781
782         /* DAC left and right routed to SPK2 */
783         /* SPK1/2 unmuted */
784         audio_tsc2101_write(TSC2101_AUDIO_CTRL_5,
785                             AC5_DAC2SPK1(3) | AC5_AST2SPK1 | AC5_KCL2SPK1 |
786                             AC5_DAC2SPK2(3) | AC5_AST2SPK2 | AC5_KCL2SPK2 |
787                             AC5_HDSCPTC);
788
789         /* OUT8P/N muted, CPOUT muted */
790
791         audio_tsc2101_write(TSC2101_AUDIO_CTRL_6,
792                             AC6_MUTLSPK | AC6_MUTSPK2 | AC6_LDSCPTC |
793                             AC6_VGNDSCPTC);
794
795         /* Headset/Hook switch detect disabled */
796         audio_tsc2101_write(TSC2101_AUDIO_CTRL_7, 0x0000);
797
798         /* Left line input volume control */
799         tsc2101_update(SET_LINE, tsc2101_local.line);
800
801         /* mic input volume control */
802         tsc2101_update(SET_MIC, tsc2101_local.mic);
803
804         /* Left/Right headphone channel volume control */
805         /* Zero-cross detect on */
806         tsc2101_update(SET_VOLUME, tsc2101_local.volume);
807
808         /* clock configuration */
809         omap_set_samplerate(audio_samplerate);
810
811 #ifdef TSC_DUMP_REGISTERS
812         tsc2101_dumpRegisters();
813 #endif
814
815         FN_OUT(0);
816 }
817
818 #ifdef PROC_SUPPORT
819 static void tsc2101_start(void)
820 {
821         FN_IN;
822
823         audio_tsc2101_write(TSC2101_CODEC_POWER_CTRL, 0x0000);
824
825         /*Mute Analog Sidetone */
826         /*Select MIC_INHED input for headset */
827         /*Cell Phone In not connected */
828         audio_tsc2101_write(TSC2101_MIXER_PGA_CTRL,
829                             MPC_ASTMU | MPC_ASTG(0x40) | MPC_MICADC);
830
831         /* Set record source */
832         tsc2101_update(SET_RECSRC, tsc2101_local.recsrc);
833
834         /* ADC, DAC, Analog Sidetone, cellphone, buzzer softstepping enabled */
835         /* 1dB AGC hysteresis */
836         /* MICes bias 2V */
837         audio_tsc2101_write(TSC2101_AUDIO_CTRL_4, AC4_MB_HED(0));
838
839         /* Set codec output volume */
840         audio_tsc2101_write(TSC2101_DAC_GAIN_CTRL, 0x0000);
841
842         /* DAC left and right routed to SPK2 */
843         /* SPK1/2 unmuted */
844         audio_tsc2101_write(TSC2101_AUDIO_CTRL_5,
845                             AC5_DAC2SPK1(3) | AC5_AST2SPK1 | AC5_KCL2SPK1 |
846                             AC5_DAC2SPK2(3) | AC5_AST2SPK2 | AC5_KCL2SPK2 |
847                             AC5_HDSCPTC);
848
849         /* OUT8P/N muted, CPOUT muted */
850
851         audio_tsc2101_write(TSC2101_AUDIO_CTRL_6,
852                             AC6_MUTLSPK | AC6_MUTSPK2 | AC6_LDSCPTC |
853                             AC6_VGNDSCPTC);
854
855         /* Headset/Hook switch detect disabled */
856         audio_tsc2101_write(TSC2101_AUDIO_CTRL_7, 0x0000);
857
858         /* Left line input volume control */
859         tsc2101_update(SET_LINE, tsc2101_local.line);
860
861         /* mic input volume control */
862         tsc2101_update(SET_MIC, tsc2101_local.mic);
863
864         /* Left/Right headphone channel volume control */
865         /* Zero-cross detect on */
866         tsc2101_update(SET_VOLUME, tsc2101_local.volume);
867
868         FN_OUT(0);
869
870 }
871 #endif
872
873 /******************************************************************************************
874  *
875  * All generic ioctl's are handled by audio_ioctl() [File: omap-audio.c]. This
876  * routine handles some platform specific ioctl's
877  *
878  ******************************************************************************************/
879 static int
880 omap_tsc2101_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
881 {
882         long val;
883         int ret = 0;
884
885         DPRINTK(" 0x%08x\n", cmd);
886
887         /*
888          * These are platform dependent ioctls which are not handled by the
889          * generic omap-audio module.
890          */
891         switch (cmd) {
892         case SNDCTL_DSP_STEREO:
893                 ret = get_user(val, (int __user *)arg);
894                 if (ret)
895                         return ret;
896                 /* the AIC23 is stereo only */
897                 ret = (val == 0) ? -EINVAL : 1;
898                 FN_OUT(1);
899                 return put_user(ret, (int __user *)arg);
900
901         case SNDCTL_DSP_CHANNELS:
902         case SOUND_PCM_READ_CHANNELS:
903                 /* the AIC23 is stereo only */
904                 FN_OUT(2);
905                 return put_user(2, (long __user *)arg);
906
907         case SNDCTL_DSP_SPEED:
908                 ret = get_user(val, (long __user *)arg);
909                 if (ret)
910                         break;
911                 ret = omap_set_samplerate(val);
912                 if (ret)
913                         break;
914                 /* fall through */
915
916         case SOUND_PCM_READ_RATE:
917                 FN_OUT(3);
918                 return put_user(audio_samplerate, (long __user *)arg);
919
920         case SOUND_PCM_READ_BITS:
921         case SNDCTL_DSP_SETFMT:
922         case SNDCTL_DSP_GETFMTS:
923                 /* we can do 16-bit only */
924                 FN_OUT(4);
925                 return put_user(AFMT_S16_LE, (long __user *)arg);
926
927         default:
928                 /* Maybe this is meant for the mixer (As per OSS Docs) */
929                 FN_OUT(5);
930                 return mixer_ioctl(inode, file, cmd, arg);
931         }
932
933         FN_OUT(0);
934         return ret;
935 }
936
937 /*********************************************************************************
938  *
939  * module_probe for TSC2101
940  *
941  ********************************************************************************/
942 static int omap_tsc2101_probe(void)
943 {
944         FN_IN;
945
946         /* Get the fops from audio oss driver */
947         if (!(omap_audio_fops = audio_get_fops())) {
948                 printk(KERN_ERR "Unable to Get the FOPs of Audio OSS driver\n");
949                 audio_unregister_codec(&tsc2101_state);
950                 return -EPERM;
951         }
952
953         /* register devices */
954         audio_dev_id = register_sound_dsp(omap_audio_fops, -1);
955         mixer_dev_id = register_sound_mixer(&omap_mixer_fops, -1);
956
957 #ifdef PROC_SUPPORT
958         create_proc_read_entry(PROC_START_FILE, 0 /* default mode */ ,
959                                NULL /* parent dir */ ,
960                                codec_start, NULL /* client data */ );
961
962         create_proc_read_entry(PROC_STOP_FILE, 0 /* default mode */ ,
963                                NULL /* parent dir */ ,
964                                codec_stop, NULL /* client data */ );
965 #endif
966
967         /* Announcement Time */
968         printk(KERN_INFO PLATFORM_NAME " " CODEC_NAME
969                " Audio support initialized\n");
970
971         FN_OUT(0);
972         return 0;
973 }
974
975 /*********************************************************************************
976  *
977  * Module Remove for TSC2101
978  *
979  ********************************************************************************/
980 static void omap_tsc2101_remove(void)
981 {
982         FN_IN;
983         /* Un-Register the codec with the audio driver */
984         unregister_sound_dsp(audio_dev_id);
985         unregister_sound_mixer(mixer_dev_id);
986
987 #ifdef PROC_SUPPORT
988         remove_proc_entry(PROC_START_FILE, NULL);
989         remove_proc_entry(PROC_STOP_FILE, NULL);
990 #endif
991         FN_OUT(0);
992
993 }
994
995 /*********************************************************************************
996  *
997  * Module Suspend for TSC2101
998  *
999  ********************************************************************************/
1000 static int omap_tsc2101_suspend(void)
1001 {
1002
1003         FN_OUT(0);
1004         return 0;
1005 }
1006
1007 /*********************************************************************************
1008  *
1009  * Module Resume for TSC2101
1010  *
1011  ********************************************************************************/
1012 static int omap_tsc2101_resume(void)
1013 {
1014
1015         FN_OUT(0);
1016         return 0;
1017 }
1018
1019 /*********************************************************************************
1020  *
1021  * module_init for TSC2101
1022  *
1023  ********************************************************************************/
1024 static int __init audio_tsc2101_init(void)
1025 {
1026
1027         int err = 0;
1028         FN_IN;
1029
1030         if (machine_is_omap_osk() || machine_is_omap_innovator())
1031                 return -ENODEV;
1032
1033         mutex_init(&tsc2101_state.mutex);
1034
1035         /* register the codec with the audio driver */
1036         if ((err = audio_register_codec(&tsc2101_state))) {
1037                 printk(KERN_ERR
1038                        "Failed to register TSC driver with Audio OSS Driver\n");
1039         }
1040         FN_OUT(err);
1041         return err;
1042 }
1043
1044 /*********************************************************************************
1045  *
1046  * module_exit for TSC2101
1047  *
1048  ********************************************************************************/
1049 static void __exit audio_tsc2101_exit(void)
1050 {
1051
1052         FN_IN;
1053         (void)audio_unregister_codec(&tsc2101_state);
1054         FN_OUT(0);
1055         return;
1056 }
1057
1058 /**************************** DEBUG FUNCTIONS ***********************************/
1059
1060 /*********************************************************************************
1061  * TEST_KEYCLICK:
1062  * This is a test to generate various keyclick sound on tsc.
1063  * verifies if the tsc and the spi interfaces are operational.
1064  *
1065  ********************************************************************************/
1066 #ifdef TEST_KEYCLICK
1067 void tsc2101_testkeyclick(void)
1068 {
1069         u8 freq = 0;
1070         u16 old_reg_val, reg_val;
1071         u32 uDummyVal = 0;
1072         u32 uTryVal = 0;
1073
1074         old_reg_val = audio_tsc2101_read(TSC2101_AUDIO_CTRL_2);
1075
1076         /* Keyclick active, max amplitude and longest key click len(32 period) */
1077         printk(KERN_INFO " TESTING KEYCLICK\n Listen carefully NOW....\n");
1078         printk(KERN_INFO " OLD REG VAL=0x%x\n", old_reg_val);
1079         /* try all frequencies */
1080         for (; freq < 8; freq++) {
1081                 /* Keyclick active, max amplitude and longest key click len(32 period) */
1082                 reg_val = old_reg_val | AC2_KCLAC(0x7) | AC2_KCLLN(0xF);
1083                 uDummyVal = 0;
1084                 uTryVal = 0;
1085                 printk(KERN_INFO "\n\nTrying frequency %d reg val= 0x%x\n",
1086                        freq, reg_val | AC2_KCLFRQ(freq) | AC2_KCLEN);
1087                 audio_tsc2101_write(TSC2101_AUDIO_CTRL_2,
1088                                     reg_val | AC2_KCLFRQ(freq) | AC2_KCLEN);
1089                 printk("DONE. Wait 10 ms ...\n");
1090                 /* wait till the kclk bit is auto cleared! time out also to be considered. */
1091                 while (audio_tsc2101_read(TSC2101_AUDIO_CTRL_2) & AC2_KCLEN) {
1092                         udelay(3);
1093                         uTryVal++;
1094                         if (uTryVal > 2000) {
1095                                 printk(KERN_ERR
1096                                        "KEYCLICK TIMED OUT! freq val=%d, POSSIBLE ERROR!\n",
1097                                        freq);
1098                                 printk(KERN_INFO
1099                                        "uTryVal == %d: Read back new reg val= 0x%x\n",
1100                                        uTryVal,
1101                                        audio_tsc2101_read
1102                                        (TSC2101_AUDIO_CTRL_2));
1103                                 /* clear */
1104                                 audio_tsc2101_write(TSC2101_AUDIO_CTRL_2, 0x00);
1105                                 break;
1106                         }
1107                 }
1108         }
1109         /* put the old value back */
1110         audio_tsc2101_write(TSC2101_AUDIO_CTRL_2, old_reg_val);
1111         printk(KERN_INFO " KEYCLICK TEST COMPLETE\n");
1112
1113 }                               /* End of tsc2101_testkeyclick */
1114
1115 #endif                          /* TEST_KEYCLICK */
1116
1117 /*********************************************************************************
1118  * TONEGEN:
1119  * This is a test to generate a rather unpleasant sound..
1120  * verifies if the mcbsp is active (requires MCBSP_DIRECT_RW to be active on McBSP)
1121  *
1122  ********************************************************************************/
1123 #ifdef TONE_GEN
1124 /* Generates a shrill tone */
1125 u16 tone[] = {
1126         0x0ce4, 0x0ce4, 0x1985, 0x1985, 0x25A1, 0x25A1, 0x30FD, 0x30FE,
1127         0x3B56, 0x3B55, 0x447A, 0x447A, 0x4C3B, 0x4C3C, 0x526D, 0x526C,
1128         0x56F1, 0x56F1, 0x59B1, 0x59B1, 0x5A9E, 0x5A9D, 0x59B1, 0x59B2,
1129         0x56F3, 0x56F2, 0x526D, 0x526D, 0x4C3B, 0x4C3B, 0x447C, 0x447C,
1130         0x3B5A, 0x3B59, 0x30FE, 0x30FE, 0x25A5, 0x25A6, 0x1989, 0x198A,
1131         0x0CE5, 0x0CE3, 0x0000, 0x0000, 0xF31C, 0xF31C, 0xE677, 0xE676,
1132         0xDA5B, 0xDA5B, 0xCF03, 0xCF03, 0xC4AA, 0xC4AA, 0xBB83, 0xBB83,
1133         0xB3C5, 0xB3C5, 0xAD94, 0xAD94, 0xA90D, 0xA90E, 0xA64F, 0xA64E,
1134         0xA562, 0xA563, 0xA64F, 0xA64F, 0xA910, 0xA90F, 0xAD93, 0xAD94,
1135         0xB3C4, 0xB3C4, 0xBB87, 0xBB86, 0xC4AB, 0xC4AB, 0xCF03, 0xCF03,
1136         0xDA5B, 0xDA5A, 0xE67B, 0xE67B, 0xF31B, 0xF3AC, 0x0000, 0x0000,
1137         0x0CE4, 0x0CE4, 0x1985, 0x1985, 0x25A1, 0x25A1, 0x30FD, 0x30FE,
1138         0x3B56, 0x3B55, 0x447A, 0x447A, 0x4C3B, 0x4C3C, 0x526D, 0x526C,
1139         0x56F1, 0x56F1, 0x59B1, 0x59B1, 0x5A9E, 0x5A9D, 0x59B1, 0x59B2,
1140         0x56F3, 0x56F2, 0x526D, 0x526D, 0x4C3B, 0x4C3B, 0x447C, 0x447C,
1141         0x3B5A, 0x3B59, 0x30FE, 0x30FE, 0x25A5, 0x25A6, 0x1989, 0x198A,
1142         0x0CE5, 0x0CE3, 0x0000, 0x0000, 0xF31C, 0xF31C, 0xE677, 0xE676,
1143         0xDA5B, 0xDA5B, 0xCF03, 0xCF03, 0xC4AA, 0xC4AA, 0xBB83, 0xBB83,
1144         0xB3C5, 0xB3C5, 0xAD94, 0xAD94, 0xA90D, 0xA90E, 0xA64F, 0xA64E,
1145         0xA562, 0xA563, 0xA64F, 0xA64F, 0xA910, 0xA90F, 0xAD93, 0xAD94,
1146         0xB3C4, 0xB3C4, 0xBB87, 0xBB86, 0xC4AB, 0xC4AB, 0xCF03, 0xCF03,
1147         0xDA5B, 0xDA5A, 0xE67B, 0xE67B, 0xF31B, 0xF3AC, 0x0000, 0x0000,
1148         0x0CE4, 0x0CE4, 0x1985, 0x1985, 0x25A1, 0x25A1, 0x30FD, 0x30FE,
1149         0x3B56, 0x3B55, 0x447A, 0x447A, 0x4C3B, 0x4C3C, 0x526D, 0x526C,
1150         0x56F1, 0x56F1, 0x59B1, 0x59B1, 0x5A9E, 0x5A9D, 0x59B1, 0x59B2,
1151         0x56F3, 0x56F2, 0x526D, 0x526D, 0x4C3B, 0x4C3B, 0x447C, 0x447C,
1152         0x3B5A, 0x3B59, 0x30FE, 0x30FE, 0x25A5, 0x25A6, 0x1989, 0x198A,
1153         0x0CE5, 0x0CE3, 0x0000, 0x0000, 0xF31C, 0xF31C, 0xE677, 0xE676,
1154         0xDA5B, 0xDA5B, 0xCF03, 0xCF03, 0xC4AA, 0xC4AA, 0xBB83, 0xBB83,
1155         0xB3C5, 0xB3C5, 0xAD94, 0xAD94, 0xA90D, 0xA90E, 0xA64F, 0xA64E,
1156         0xA562, 0xA563, 0xA64F, 0xA64F, 0xA910, 0xA90F, 0xAD93, 0xAD94,
1157         0xB3C4, 0xB3C4, 0xBB87, 0xBB86, 0xC4AB, 0xC4AB, 0xCF03, 0xCF03,
1158         0xDA5B, 0xDA5A, 0xE67B, 0xE67B, 0xF31B, 0xF3AC, 0x0000, 0x0000
1159 };
1160
1161 void toneGen(void)
1162 {
1163         int count = 0;
1164         int ret = 0;
1165         printk(KERN_INFO "TONE GEN TEST :");
1166
1167         for (count = 0; count < 5000; count++) {
1168                 int bytes;
1169                 for (bytes = 0; bytes < sizeof(tone) / 2; bytes++) {
1170                         ret = omap_mcbsp_pollwrite(AUDIO_MCBSP, tone[bytes]);
1171                         if (ret == -1) {
1172                                 /* retry */
1173                                 bytes--;
1174                         } else if (ret == -2) {
1175                                 printk(KERN_INFO "ERROR:bytes=%d\n", bytes);
1176                                 return;
1177                         }
1178                 }
1179         }
1180         printk(KERN_INFO "SUCCESS\n");
1181 }
1182
1183 #endif                          /* End of TONE_GEN */
1184
1185 /*********************************************************************************
1186  *
1187  * TSC_DUMP_REGISTERS:
1188  * This will dump the entire register set of Page 2 tsc2101. 
1189  * Useful for major goof ups
1190  *
1191  ********************************************************************************/
1192 #ifdef TSC_DUMP_REGISTERS
1193 static void tsc2101_dumpRegisters(void)
1194 {
1195         int i = 0;
1196         u16 data = 0;
1197         printk("TSC 2101 Register dump for Page 2 \n");
1198         for (i = 0; i < 0x27; i++) {
1199                 data = audio_tsc2101_read(i);
1200                 printk(KERN_INFO "Register[%x]=0x%04x\n", i, data);
1201
1202         }
1203 }
1204 #endif                          /* End of #ifdef TSC_DUMP_REGISTERS */
1205
1206 #ifdef PROC_SUPPORT
1207 static int codec_start(char *buf, char **start, off_t offset, int count,
1208                        int *eof, void *data)
1209 {
1210         omap_tsc2101_enable();
1211         tsc2101_start();
1212         printk("Codec initialization done.\n");
1213         return 0;
1214 }
1215 static int codec_stop(char *buf, char **start, off_t offset, int count,
1216                       int *eof, void *data)
1217 {
1218
1219         omap_tsc2101_disable();
1220         audio_tsc2101_write(TSC2101_CODEC_POWER_CTRL,
1221                             ~(CPC_SP1PWDN | CPC_SP2PWDN | CPC_BASSBC));
1222         printk("Codec shutdown.\n");
1223         return 0;
1224 }
1225 #endif
1226
1227 /*********************************************************************************
1228  *
1229  * Other misc management, registration etc
1230  *
1231  ********************************************************************************/
1232 module_init(audio_tsc2101_init);
1233 module_exit(audio_tsc2101_exit);
1234
1235 MODULE_AUTHOR("Texas Instruments");
1236 MODULE_DESCRIPTION
1237     ("Glue audio driver for the TI OMAP1610/OMAP1710 TSC2101 codec.");
1238 MODULE_LICENSE("GPL");