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