~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/oss/harmony.c

Version: ~ [ linux-5.2-rc1 ] ~ [ linux-5.1.2 ] ~ [ linux-5.0.16 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.43 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.119 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.176 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.179 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.139 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.67 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.39.4 ] ~ [ linux-2.6.38.8 ] ~ [ linux-2.6.37.6 ] ~ [ linux-2.6.36.4 ] ~ [ linux-2.6.35.14 ] ~ [ linux-2.6.34.15 ] ~ [ linux-2.6.33.20 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2         drivers/sound/harmony.c 
  3 
  4         This is a sound driver for ASP's and Lasi's Harmony sound chip
  5         and is unlikely to be used for anything other than on a HP PA-RISC.
  6 
  7         Harmony is found in HP 712s, 715/new and many other GSC based machines.
  8         On older 715 machines you'll find the technically identical chip 
  9         called 'Vivace'. Both Harmony and Vicace are supported by this driver.
 10 
 11         Copyright 2000 (c) Linuxcare Canada, Alex deVries <alex@linuxcare.com>
 12         Copyright 2000-2002 (c) Helge Deller <deller@gmx.de>
 13         Copyright 2001 (c) Matthieu Delahaye <delahaym@esiee.fr>
 14         Copyright 2001 (c) Jean-Christophe Vaugeois <vaugeoij@esiee.fr>
 15 
 16                                 
 17 TODO:
 18         - fix SNDCTL_DSP_GETOSPACE and SNDCTL_DSP_GETISPACE ioctls to
 19                 return the real values
 20         - add private ioctl for selecting line- or microphone input
 21                 (only one of them is available at the same time)
 22         - add module parameters
 23         - implement mmap functionality
 24         - implement gain meter ?
 25         - ...
 26 */
 27 
 28 #include <linux/delay.h>
 29 #include <linux/errno.h>
 30 #include <linux/init.h>
 31 #include <linux/interrupt.h>
 32 #include <linux/ioport.h>
 33 #include <linux/types.h>
 34 #include <linux/mm.h>
 35 #include <linux/pci.h>
 36 
 37 #include <asm/parisc-device.h>
 38 #include <asm/io.h>
 39 
 40 #include "sound_config.h"
 41 
 42 
 43 #define PFX "harmony: "
 44 #define HARMONY_VERSION "V0.9a"
 45 
 46 #undef DEBUG
 47 #ifdef DEBUG
 48 # define DPRINTK printk 
 49 #else
 50 # define DPRINTK(x,...)
 51 #endif
 52 
 53 
 54 #define MAX_BUFS 10             /* maximum number of rotating buffers */
 55 #define HARMONY_BUF_SIZE 4096   /* needs to be a multiple of PAGE_SIZE (4096)! */
 56 
 57 #define CNTL_C          0x80000000
 58 #define CNTL_ST         0x00000020
 59 #define CNTL_44100      0x00000015      /* HARMONY_SR_44KHZ */
 60 #define CNTL_8000       0x00000008      /* HARMONY_SR_8KHZ */
 61 
 62 #define GAINCTL_HE      0x08000000
 63 #define GAINCTL_LE      0x04000000
 64 #define GAINCTL_SE      0x02000000
 65 
 66 #define DSTATUS_PN      0x00000200
 67 #define DSTATUS_RN      0x00000002
 68 
 69 #define DSTATUS_IE      0x80000000
 70 
 71 #define HARMONY_DF_16BIT_LINEAR 0
 72 #define HARMONY_DF_8BIT_ULAW    1
 73 #define HARMONY_DF_8BIT_ALAW    2
 74 
 75 #define HARMONY_SS_MONO         0
 76 #define HARMONY_SS_STEREO       1
 77 
 78 #define HARMONY_SR_8KHZ         0x08
 79 #define HARMONY_SR_16KHZ        0x09
 80 #define HARMONY_SR_27KHZ        0x0A
 81 #define HARMONY_SR_32KHZ        0x0B
 82 #define HARMONY_SR_48KHZ        0x0E
 83 #define HARMONY_SR_9KHZ         0x0F
 84 #define HARMONY_SR_5KHZ         0x10
 85 #define HARMONY_SR_11KHZ        0x11
 86 #define HARMONY_SR_18KHZ        0x12
 87 #define HARMONY_SR_22KHZ        0x13
 88 #define HARMONY_SR_37KHZ        0x14
 89 #define HARMONY_SR_44KHZ        0x15
 90 #define HARMONY_SR_33KHZ        0x16
 91 #define HARMONY_SR_6KHZ         0x17
 92 
 93 /*
 94  * Some magics numbers used to auto-detect file formats
 95  */
 96 
 97 #define HARMONY_MAGIC_8B_ULAW   1
 98 #define HARMONY_MAGIC_8B_ALAW   27
 99 #define HARMONY_MAGIC_16B_LINEAR 3
100 #define HARMONY_MAGIC_MONO      1
101 #define HARMONY_MAGIC_STEREO    2
102 
103 /*
104  * Channels Positions in mixer register
105  */
106 
107 #define GAIN_HE_SHIFT   27
108 #define GAIN_HE_MASK    ( 1 << GAIN_HE_SHIFT) 
109 #define GAIN_LE_SHIFT   26
110 #define GAIN_LE_MASK    ( 1 << GAIN_LE_SHIFT) 
111 #define GAIN_SE_SHIFT   25
112 #define GAIN_SE_MASK    ( 1 << GAIN_SE_SHIFT) 
113 #define GAIN_IS_SHIFT   24
114 #define GAIN_IS_MASK    ( 1 << GAIN_IS_SHIFT) 
115 #define GAIN_MA_SHIFT   20
116 #define GAIN_MA_MASK    ( 0x0f << GAIN_MA_SHIFT) 
117 #define GAIN_LI_SHIFT   16
118 #define GAIN_LI_MASK    ( 0x0f << GAIN_LI_SHIFT) 
119 #define GAIN_RI_SHIFT   12
120 #define GAIN_RI_MASK    ( 0x0f << GAIN_RI_SHIFT) 
121 #define GAIN_LO_SHIFT   6
122 #define GAIN_LO_MASK    ( 0x3f << GAIN_LO_SHIFT) 
123 #define GAIN_RO_SHIFT   0
124 #define GAIN_RO_MASK    ( 0x3f << GAIN_RO_SHIFT) 
125 
126 
127 #define MAX_OUTPUT_LEVEL (GAIN_RO_MASK >> GAIN_RO_SHIFT)
128 #define MAX_INPUT_LEVEL  (GAIN_RI_MASK >> GAIN_RI_SHIFT)
129 #define MAX_VOLUME_LEVEL (GAIN_MA_MASK >> GAIN_MA_SHIFT)
130 
131 /*
132  * Channels Mask in mixer register
133  */
134 
135 #define GAIN_TOTAL_SILENCE 0x00F00FFF
136 #define GAIN_DEFAULT       0x0FF00000
137 
138 
139 struct harmony_hpa {
140         u8      unused000;
141         u8      id;
142         u8      teleshare_id;
143         u8      unused003;
144         u32     reset;
145         u32     cntl;
146         u32     gainctl;
147         u32     pnxtadd;
148         u32     pcuradd;
149         u32     rnxtadd;
150         u32     rcuradd;
151         u32     dstatus;
152         u32     ov;
153         u32     pio;
154         u32     unused02c;
155         u32     unused030[3];
156         u32     diag;
157 };
158 
159 struct harmony_dev {
160         int irq;
161         struct harmony_hpa *hpa;
162         u32 current_gain;
163         u8 data_format;         /* HARMONY_DF_xx_BIT_xxx */
164         u8 sample_rate;         /* HARMONY_SR_xx_KHZ */
165         u8 stereo_select;       /* HARMONY_SS_MONO or HARMONY_SS_STEREO */
166         int format_initialized;
167         u32 dac_rate;           /* 8000 ... 48000 (Hz) */
168         int suspended_playing;
169         int suspended_recording;
170         
171         int blocked_playing;
172         int blocked_recording;
173         
174         wait_queue_head_t wq_play, wq_record;
175         int first_filled_play;  /* first buffer containing data (next to play) */
176         int nb_filled_play; 
177         int play_offset;
178         int first_filled_record;
179         int nb_filled_record;
180                 
181         int audio_open, mixer_open;
182         int dsp_unit, mixer_unit;
183 
184         struct pci_dev *fake_pci_dev; /* The fake pci_dev needed for 
185                                         pci_* functions under ccio. */
186 };
187 
188 
189 static struct harmony_dev harmony;
190 
191 
192 /*
193  * Dynamic sound buffer allocation and DMA memory
194  */
195 
196 struct harmony_buffer {
197         unsigned char *addr;
198         dma_addr_t dma_handle;
199         int dma_consistent;     /* Zero if pci_alloc_consistent() fails */
200         int len;
201 };
202 
203 /*
204  * Harmony memory buffers
205  */
206 
207 static struct harmony_buffer played_buf, recorded_buf, silent, graveyard;
208 
209 
210 #define CHECK_WBACK_INV_OFFSET(b,offset,len) \
211         do { if (!b.dma_consistent) \
212                 dma_cache_wback_inv((unsigned long)b.addr+offset,len); \
213         } while (0) 
214 
215         
216 static int __init harmony_alloc_buffer(struct harmony_buffer *b, 
217                 int buffer_count)
218 {
219         b->len = buffer_count * HARMONY_BUF_SIZE;
220         b->addr = pci_alloc_consistent(harmony.fake_pci_dev, 
221                           b->len, &b->dma_handle);
222         if (b->addr && b->dma_handle) {
223                 b->dma_consistent = 1;
224                 DPRINTK(KERN_INFO PFX "consistent memory: 0x%lx, played_buf: 0x%lx\n",
225                                 (unsigned long)b->dma_handle, (unsigned long)b->addr);
226         } else {
227                 b->dma_consistent = 0;
228                 /* kmalloc()ed memory will HPMC on ccio machines ! */
229                 b->addr = kmalloc(b->len, GFP_KERNEL);
230                 if (!b->addr) {
231                         printk(KERN_ERR PFX "couldn't allocate memory\n");
232                         return -EBUSY;
233                 }
234                 b->dma_handle = __pa(b->addr);
235         }
236         return 0;
237 }
238 
239 static void __exit harmony_free_buffer(struct harmony_buffer *b)
240 {
241         if (!b->addr)
242                 return;
243 
244         if (b->dma_consistent)
245                 pci_free_consistent(harmony.fake_pci_dev,
246                                 b->len, b->addr, b->dma_handle);
247         else
248                 kfree(b->addr);
249 
250         memset(b, 0, sizeof(*b));
251 }
252 
253 
254 
255 /*
256  * Low-Level sound-chip programming
257  */
258 
259 static void __inline__ harmony_wait_CNTL(void)
260 {
261         /* Wait until we're out of control mode */
262         while (gsc_readl(&harmony.hpa->cntl) & CNTL_C)
263                 /* wait */ ;
264 }
265 
266 
267 static void harmony_update_control(void) 
268 {
269         u32 default_cntl;
270         
271         /* Set CNTL */
272         default_cntl = (CNTL_C |                /* The C bit */
273                 (harmony.data_format << 6) |    /* Set the data format */
274                 (harmony.stereo_select << 5) |  /* Stereo select */
275                 (harmony.sample_rate));         /* Set sample rate */
276         harmony.format_initialized = 1;
277         
278         /* initialize CNTL */
279         gsc_writel(default_cntl, &harmony.hpa->cntl);
280 }
281 
282 static void harmony_set_control(u8 data_format, u8 sample_rate, u8 stereo_select) 
283 {
284         harmony.sample_rate = sample_rate;
285         harmony.data_format = data_format;
286         harmony.stereo_select = stereo_select;
287         harmony_update_control();
288 }
289 
290 static void harmony_set_rate(u8 data_rate) 
291 {
292         harmony.sample_rate = data_rate;
293         harmony_update_control();
294 }
295 
296 static int harmony_detect_rate(int *freq)
297 {
298         int newrate;
299         switch (*freq) {
300         case 8000:      newrate = HARMONY_SR_8KHZ;      break;
301         case 16000:     newrate = HARMONY_SR_16KHZ;     break; 
302         case 27428:     newrate = HARMONY_SR_27KHZ;     break; 
303         case 32000:     newrate = HARMONY_SR_32KHZ;     break; 
304         case 48000:     newrate = HARMONY_SR_48KHZ;     break; 
305         case 9600:      newrate = HARMONY_SR_9KHZ;      break; 
306         case 5125:      newrate = HARMONY_SR_5KHZ;      break; 
307         case 11025:     newrate = HARMONY_SR_11KHZ;     break; 
308         case 18900:     newrate = HARMONY_SR_18KHZ;     break; 
309         case 22050:     newrate = HARMONY_SR_22KHZ;     break; 
310         case 37800:     newrate = HARMONY_SR_37KHZ;     break; 
311         case 44100:     newrate = HARMONY_SR_44KHZ;     break; 
312         case 33075:     newrate = HARMONY_SR_33KHZ;     break; 
313         case 6615:      newrate = HARMONY_SR_6KHZ;      break; 
314         default:        newrate = HARMONY_SR_8KHZ; 
315                         *freq = 8000;                   break;
316         }
317         return newrate;
318 }
319 
320 static void harmony_set_format(u8 data_format) 
321 {
322         harmony.data_format = data_format;
323         harmony_update_control();
324 }
325 
326 static void harmony_set_stereo(u8 stereo_select) 
327 {
328         harmony.stereo_select = stereo_select;
329         harmony_update_control();
330 }
331 
332 static void harmony_disable_interrupts(void) 
333 {
334         harmony_wait_CNTL();
335         gsc_writel(0, &harmony.hpa->dstatus); 
336 }
337 
338 static void harmony_enable_interrupts(void) 
339 {
340         harmony_wait_CNTL();
341         gsc_writel(DSTATUS_IE, &harmony.hpa->dstatus); 
342 }
343 
344 /*
345  * harmony_silence()
346  *
347  * This subroutine fills in a buffer starting at location start and
348  * silences for length bytes.  This references the current
349  * configuration of the audio format.
350  *
351  */
352 
353 static void harmony_silence(struct harmony_buffer *buffer, int start, int length) 
354 {
355         u8 silence_char;
356 
357         /* Despite what you hear, silence is different in
358            different audio formats.  */
359         switch (harmony.data_format) {
360                 case HARMONY_DF_8BIT_ULAW:      silence_char = 0x55; break;
361                 case HARMONY_DF_8BIT_ALAW:      silence_char = 0xff; break;
362                 case HARMONY_DF_16BIT_LINEAR:   /* fall through */
363                 default:                        silence_char = 0;
364         }
365 
366         memset(buffer->addr+start, silence_char, length);
367 }
368 
369 
370 static int harmony_audio_open(struct inode *inode, struct file *file)
371 {
372         if (harmony.audio_open) 
373                 return -EBUSY;
374         
375         harmony.audio_open++;
376         harmony.suspended_playing = harmony.suspended_recording = 1;
377         harmony.blocked_playing   = harmony.blocked_recording   = 0;
378         harmony.first_filled_play = harmony.first_filled_record = 0;
379         harmony.nb_filled_play    = harmony.nb_filled_record    = 0;
380         harmony.play_offset = 0;
381         init_waitqueue_head(&harmony.wq_play);
382         init_waitqueue_head(&harmony.wq_record);
383         
384         /* Start off in a balanced mode. */
385         harmony_set_control(HARMONY_DF_8BIT_ULAW, HARMONY_SR_8KHZ, HARMONY_SS_MONO);
386         harmony_update_control();
387         harmony.format_initialized = 0;
388 
389         /* Clear out all the buffers and flush to cache */
390         harmony_silence(&played_buf, 0, HARMONY_BUF_SIZE*MAX_BUFS);
391         CHECK_WBACK_INV_OFFSET(played_buf, 0, HARMONY_BUF_SIZE*MAX_BUFS);
392         
393         return 0;
394 }
395 
396 /*
397  * Release (close) the audio device.
398  */
399 
400 static int harmony_audio_release(struct inode *inode, struct file *file)
401 {
402         if (!harmony.audio_open) 
403                 return -EBUSY;
404         
405         harmony.audio_open--;
406 
407         return 0;
408 }
409 
410 /*
411  * Read recorded data off the audio device.
412  */
413 
414 static ssize_t harmony_audio_read(struct file *file,
415                                 char *buffer,
416                                 size_t size_count,
417                                 loff_t *ppos)
418 {
419         int total_count = (int) size_count;
420         int count = 0;
421         int buf_to_read;
422 
423         while (count<total_count) {
424                 /* Wait until we're out of control mode */
425                 harmony_wait_CNTL();
426                 
427                 /* Figure out which buffer to fill in */
428                 if (harmony.nb_filled_record <= 2) {
429                         harmony.blocked_recording = 1;
430                         if (harmony.suspended_recording) {
431                                 harmony.suspended_recording = 0;
432                                 harmony_enable_interrupts();
433                         }
434                                                         
435                         interruptible_sleep_on(&harmony.wq_record);
436                         harmony.blocked_recording = 0;
437                 }
438                 
439                 if (harmony.nb_filled_record < 2)
440                         return -EBUSY;
441                 
442                 buf_to_read = harmony.first_filled_record;
443 
444                 /* Copy the page to an aligned buffer */
445                 if (copy_to_user(buffer+count, recorded_buf.addr +
446                                  (HARMONY_BUF_SIZE*buf_to_read),
447                                  HARMONY_BUF_SIZE)) {
448                         count = -EFAULT;
449                         break;
450                 }
451                 
452                 harmony.nb_filled_record--;
453                 harmony.first_filled_record++;
454                 harmony.first_filled_record %= MAX_BUFS;
455                                 
456                 count += HARMONY_BUF_SIZE;
457         }
458         return count;
459 }
460 
461 
462 
463 
464 /*
465  * Here is the place where we try to recognize file format.
466  * Sun/NeXT .au files begin with the string .snd
467  * At offset 12 is specified the encoding.
468  * At offset 16 is specified speed rate
469  * At Offset 20 is specified the numbers of voices
470  */
471 
472 #define four_bytes_to_u32(start) (file_header[start] << 24)|\
473                                   (file_header[start+1] << 16)|\
474                                   (file_header[start+2] << 8)|\
475                                   (file_header[start+3]);
476 
477 #define test_rate(tested,real_value,harmony_value) if ((tested)<=(real_value))\
478                                                     
479 
480 static int harmony_format_auto_detect(const char *buffer, int block_size)
481 {
482         u8 file_header[24];
483         u32 start_string;
484         int ret = 0;
485         
486         if (block_size>24) {
487                 if (copy_from_user(file_header, buffer, sizeof(file_header)))
488                         ret = -EFAULT;
489                         
490                 start_string = four_bytes_to_u32(0);
491                 
492                 if ((file_header[4]==0) && (start_string==0x2E736E64)) {
493                         u32 format;
494                         u32 nb_voices;
495                         u32 speed;
496                         
497                         format = four_bytes_to_u32(12);
498                         nb_voices = four_bytes_to_u32(20);
499                         speed = four_bytes_to_u32(16);
500                         
501                         switch (format) {
502                         case HARMONY_MAGIC_8B_ULAW:
503                                 harmony.data_format = HARMONY_DF_8BIT_ULAW;
504                                 break;
505                         case HARMONY_MAGIC_8B_ALAW:
506                                 harmony.data_format = HARMONY_DF_8BIT_ALAW;
507                                 break;
508                         case HARMONY_MAGIC_16B_LINEAR:
509                                 harmony.data_format = HARMONY_DF_16BIT_LINEAR;
510                                 break;
511                         default:
512                                 harmony_set_control(HARMONY_DF_16BIT_LINEAR,
513                                                 HARMONY_SR_44KHZ, HARMONY_SS_STEREO);
514                                 goto out;
515                         }
516                         switch (nb_voices) {
517                         case HARMONY_MAGIC_MONO:
518                                 harmony.stereo_select = HARMONY_SS_MONO;
519                                 break;
520                         case HARMONY_MAGIC_STEREO:
521                                 harmony.stereo_select = HARMONY_SS_STEREO;
522                                 break;
523                         default:
524                                 harmony.stereo_select = HARMONY_SS_MONO;
525                                 break;
526                         }
527                         harmony_set_rate(harmony_detect_rate(&speed));
528                         harmony.dac_rate = speed;
529                         goto out;
530                 }
531         }
532         harmony_set_control(HARMONY_DF_8BIT_ULAW, HARMONY_SR_8KHZ, HARMONY_SS_MONO);
533 out:
534         return ret;
535 }
536 #undef four_bytes_to_u32
537 
538 
539 static ssize_t harmony_audio_write(struct file *file,
540                                  const char *buffer,
541                                  size_t size_count,
542                                  loff_t *ppos)
543 {
544         int total_count = (int) size_count;
545         int count = 0;
546         int frame_size;
547         int buf_to_fill;
548 
549         if (!harmony.format_initialized) {
550                 if (harmony_format_auto_detect(buffer, total_count))
551                         return -EFAULT;
552         }
553         
554         while (count<total_count) {
555                 /* Wait until we're out of control mode */
556                 harmony_wait_CNTL();
557 
558                 /* Figure out which buffer to fill in */
559                 if (harmony.nb_filled_play+2 >= MAX_BUFS && !harmony.play_offset) {
560                         harmony.blocked_playing = 1;
561                         interruptible_sleep_on(&harmony.wq_play);
562                         harmony.blocked_playing = 0;
563                 }
564                 if (harmony.nb_filled_play+2 >= MAX_BUFS && !harmony.play_offset)
565                         return -EBUSY;
566                 
567                 
568                 buf_to_fill = (harmony.first_filled_play+harmony.nb_filled_play); 
569                 if (harmony.play_offset)
570                         buf_to_fill--;
571                 buf_to_fill %= MAX_BUFS;
572 
573                 /* Figure out the size of the frame */
574                 if ((total_count-count) > HARMONY_BUF_SIZE - harmony.play_offset) {
575                         frame_size = HARMONY_BUF_SIZE - harmony.play_offset;
576                 } else {
577                         frame_size = total_count - count;
578                         /* Clear out the buffer, since there we'll only be 
579                            overlaying part of the old buffer with the new one */
580                         harmony_silence(&played_buf, 
581                                 HARMONY_BUF_SIZE*buf_to_fill+frame_size+harmony.play_offset,
582                                 HARMONY_BUF_SIZE-frame_size-harmony.play_offset);
583                 }
584 
585                 /* Copy the page to an aligned buffer */
586                 if (copy_from_user(played_buf.addr +(HARMONY_BUF_SIZE*buf_to_fill) + harmony.play_offset, 
587                                    buffer+count, frame_size))
588                         return -EFAULT;
589                 CHECK_WBACK_INV_OFFSET(played_buf, (HARMONY_BUF_SIZE*buf_to_fill + harmony.play_offset), 
590                                 frame_size);
591         
592                 if (!harmony.play_offset)
593                         harmony.nb_filled_play++;
594                 
595                 count += frame_size;
596                 harmony.play_offset += frame_size;
597                 harmony.play_offset %= HARMONY_BUF_SIZE;
598                 if (harmony.suspended_playing && (harmony.nb_filled_play>=4))
599                         harmony_enable_interrupts();
600         }
601         
602         return count;
603 }
604 
605 static unsigned int harmony_audio_poll(struct file *file,
606                                      struct poll_table_struct *wait)
607 {
608         unsigned int mask = 0;
609         
610         if (file->f_mode & FMODE_READ) {
611                 if (!harmony.suspended_recording)
612                         poll_wait(file, &harmony.wq_record, wait);
613                 if (harmony.nb_filled_record)
614                         mask |= POLLIN | POLLRDNORM;
615         }
616 
617         if (file->f_mode & FMODE_WRITE) {
618                 if (!harmony.suspended_playing)
619                         poll_wait(file, &harmony.wq_play, wait);
620                 if (harmony.nb_filled_play)
621                         mask |= POLLOUT | POLLWRNORM;
622         }
623 
624         return mask;
625 }
626 
627 static int harmony_audio_ioctl(struct inode *inode,
628                                 struct file *file,
629                                 unsigned int cmd,
630                                 unsigned long arg)
631 {
632         int ival, new_format;
633         int frag_size, frag_buf;
634         struct audio_buf_info info;
635         
636         switch (cmd) {
637         case OSS_GETVERSION:
638                 return put_user(SOUND_VERSION, (int *) arg);
639 
640         case SNDCTL_DSP_GETCAPS:
641                 ival = DSP_CAP_DUPLEX;
642                 return put_user(ival, (int *) arg);
643 
644         case SNDCTL_DSP_GETFMTS:
645                 ival = (AFMT_S16_BE | AFMT_MU_LAW | AFMT_A_LAW ); 
646                 return put_user(ival, (int *) arg);
647         
648         case SNDCTL_DSP_SETFMT:
649                 if (get_user(ival, (int *) arg)) 
650                         return -EFAULT;
651                 if (ival != AFMT_QUERY) {
652                         switch (ival) {
653                         case AFMT_MU_LAW:       new_format = HARMONY_DF_8BIT_ULAW; break;
654                         case AFMT_A_LAW:        new_format = HARMONY_DF_8BIT_ALAW; break;
655                         case AFMT_S16_LE:       /* fall through, but not really supported */
656                         case AFMT_S16_BE:       new_format = HARMONY_DF_16BIT_LINEAR;
657                                                 ival = AFMT_S16_BE;
658                                                 break; 
659                         default: {
660                                 DPRINTK(KERN_WARNING PFX 
661                                         "unsupported sound format 0x%04x requested.\n",
662                                         ival);
663                                 return -EINVAL;
664                         }
665                         }
666                         harmony_set_format(new_format);
667                 } else {
668                         switch (harmony.data_format) {
669                         case HARMONY_DF_8BIT_ULAW:      ival = AFMT_MU_LAW; break;
670                         case HARMONY_DF_8BIT_ALAW:      ival = AFMT_A_LAW;  break;
671                         case HARMONY_DF_16BIT_LINEAR:   ival = AFMT_U16_BE; break;
672                         default: ival = 0;
673                         }
674                 }
675                 return put_user(ival, (int *) arg);
676 
677         case SOUND_PCM_READ_RATE:
678                 ival = harmony.dac_rate;
679                 return put_user(ival, (int *) arg);
680 
681         case SNDCTL_DSP_SPEED:
682                 if (get_user(ival, (int *) arg))
683                         return -EFAULT;
684                 harmony_set_rate(harmony_detect_rate(&ival));
685                 harmony.dac_rate = ival;
686                 return put_user(ival, (int*) arg);
687 
688         case SNDCTL_DSP_STEREO:
689                 if (get_user(ival, (int *) arg))
690                         return -EFAULT;
691                 if (ival != 0 && ival != 1)
692                         return -EINVAL;
693                 harmony_set_stereo(ival);
694                 return put_user(ival, (int *) arg);
695 
696         case SNDCTL_DSP_GETBLKSIZE:
697                 ival = HARMONY_BUF_SIZE;
698                 return put_user(ival, (int *) arg);
699                 
700         case SNDCTL_DSP_NONBLOCK:
701                 file->f_flags |= O_NONBLOCK;
702                 return 0;
703 
704         case SNDCTL_DSP_RESET:
705                 if (!harmony.suspended_recording) {
706                         /* TODO: stop_recording() */
707                 }
708                 return 0;
709 
710         case SNDCTL_DSP_SETFRAGMENT:
711                 if (get_user(ival, (int *)arg))
712                         return -EFAULT;
713                 frag_size = ival & 0xffff;
714                 frag_buf = (ival>>16) & 0xffff;
715                 /* TODO: We use hardcoded fragment sizes and numbers for now */
716                 frag_size = 12;  /* 4096 == 2^12 */
717                 frag_buf  = MAX_BUFS;
718                 ival = (frag_buf << 16) + frag_size;
719                 return put_user(ival, (int *) arg);
720                 
721         case SNDCTL_DSP_GETOSPACE:
722                 if (!(file->f_mode & FMODE_WRITE))
723                         return -EINVAL;
724                 info.fragstotal = MAX_BUFS;
725                 info.fragments = MAX_BUFS - harmony.nb_filled_play;
726                 info.fragsize = HARMONY_BUF_SIZE;
727                 info.bytes = info.fragments * info.fragsize;
728                 return copy_to_user((void *)arg, &info, sizeof(info)) ? -EFAULT : 0;
729 
730         case SNDCTL_DSP_GETISPACE:
731                 if (!(file->f_mode & FMODE_READ))
732                         return -EINVAL;
733                 info.fragstotal = MAX_BUFS;
734                 info.fragments = /*MAX_BUFS-*/ harmony.nb_filled_record;
735                 info.fragsize = HARMONY_BUF_SIZE;
736                 info.bytes = info.fragments * info.fragsize;
737                 return copy_to_user((void *)arg, &info, sizeof(info)) ? -EFAULT : 0;
738         
739         case SNDCTL_DSP_SYNC:
740                 return 0;
741         }
742         
743         return -EINVAL;
744 }
745 
746 
747 /*
748  * harmony_interrupt()
749  *
750  * harmony interruption service routine
751  * 
752  */
753 
754 static irqreturn_t harmony_interrupt(int irq, void *dev, struct pt_regs *regs)
755 {
756         u32 dstatus;
757         struct harmony_hpa *hpa;
758 
759         /* Setup the hpa */
760         hpa = ((struct harmony_dev *)dev)->hpa;
761         harmony_wait_CNTL();
762 
763         /* Read dstatus and pcuradd (the current address) */
764         dstatus = gsc_readl(&hpa->dstatus);
765         
766         /* Turn off interrupts */
767         harmony_disable_interrupts();
768         
769         /* Check if this is a request to get the next play buffer */
770         if (dstatus & DSTATUS_PN) {
771                 if (!harmony.nb_filled_play) {
772                         harmony.suspended_playing = 1;
773                         gsc_writel((unsigned long)silent.dma_handle, &hpa->pnxtadd);
774                                                 
775                         if (!harmony.suspended_recording)
776                                 harmony_enable_interrupts();
777                 } else {
778                         harmony.suspended_playing = 0;
779                         gsc_writel((unsigned long)played_buf.dma_handle + 
780                                         (HARMONY_BUF_SIZE*harmony.first_filled_play),
781                                         &hpa->pnxtadd);
782                         harmony.first_filled_play++;
783                         harmony.first_filled_play %= MAX_BUFS;
784                         harmony.nb_filled_play--;
785                         
786                         harmony_enable_interrupts();
787                 }
788                 
789                 if (harmony.blocked_playing)
790                         wake_up_interruptible(&harmony.wq_play);
791         }
792         
793         /* Check if we're being asked to fill in a recording buffer */
794         if (dstatus & DSTATUS_RN) {
795                 if((harmony.nb_filled_record+2>=MAX_BUFS) || harmony.suspended_recording)
796                 {
797                         harmony.nb_filled_record = 0;
798                         harmony.first_filled_record = 0;
799                         harmony.suspended_recording = 1;
800                         gsc_writel((unsigned long)graveyard.dma_handle, &hpa->rnxtadd);
801                         if (!harmony.suspended_playing)
802                                 harmony_enable_interrupts();
803                 } else {
804                         int buf_to_fill;
805                         buf_to_fill = (harmony.first_filled_record+harmony.nb_filled_record) % MAX_BUFS;
806                         CHECK_WBACK_INV_OFFSET(recorded_buf, HARMONY_BUF_SIZE*buf_to_fill, HARMONY_BUF_SIZE);
807                         gsc_writel((unsigned long)recorded_buf.dma_handle +
808                                         HARMONY_BUF_SIZE*buf_to_fill,
809                                         &hpa->rnxtadd);
810                         harmony.nb_filled_record++;
811                         harmony_enable_interrupts();
812                 }
813 
814                 if (harmony.blocked_recording && harmony.nb_filled_record>3)
815                         wake_up_interruptible(&harmony.wq_record);
816         }
817         return IRQ_HANDLED;
818 }
819 
820 /*
821  * Sound playing functions
822  */
823 
824 static struct file_operations harmony_audio_fops = {
825         .owner          = THIS_MODULE,
826         .llseek         = no_llseek,
827         .read           = harmony_audio_read,
828         .write          = harmony_audio_write,
829         .poll           = harmony_audio_poll,
830         .ioctl          = harmony_audio_ioctl,
831         .open           = harmony_audio_open,
832         .release        = harmony_audio_release,
833 };
834 
835 static int harmony_audio_init(void)
836 {
837         /* Request that IRQ */
838         if (request_irq(harmony.irq, harmony_interrupt, 0 ,"harmony", &harmony)) {
839                 printk(KERN_ERR PFX "Error requesting irq %d.\n", harmony.irq);
840                 return -EFAULT;
841         }
842 
843         harmony.dsp_unit = register_sound_dsp(&harmony_audio_fops, -1);
844         if (harmony.dsp_unit < 0) {
845                 printk(KERN_ERR PFX "Error registering dsp\n");
846                 free_irq(harmony.irq, &harmony);
847                 return -EFAULT;
848         }
849         
850         /* Clear the buffers so you don't end up with crap in the buffers. */ 
851         harmony_silence(&played_buf, 0, HARMONY_BUF_SIZE*MAX_BUFS);
852 
853         /* Make sure this makes it to cache */
854         CHECK_WBACK_INV_OFFSET(played_buf, 0, HARMONY_BUF_SIZE*MAX_BUFS);
855 
856         /* Clear out the silent buffer and flush to cache */
857         harmony_silence(&silent, 0, HARMONY_BUF_SIZE);
858         CHECK_WBACK_INV_OFFSET(silent, 0, HARMONY_BUF_SIZE);
859         
860         harmony.audio_open = 0;
861         
862         return 0;
863 }
864 
865 
866 /*
867  * mixer functions 
868  */
869 
870 static void harmony_mixer_set_gain(void)
871 {
872         harmony_wait_CNTL();
873         gsc_writel(harmony.current_gain, &harmony.hpa->gainctl);
874 }
875 
876 /* 
877  *  Read gain of selected channel.
878  *  The OSS rate is from 0 (silent) to 100 -> need some conversions
879  *
880  *  The harmony gain are attenuation for output and monitor gain.
881  *                   is amplifaction for input gain
882  */
883 #define to_harmony_level(level,max) ((level)*max/100)
884 #define to_oss_level(level,max) ((level)*100/max)
885 
886 static int harmony_mixer_get_level(int channel)
887 {
888         int left_level;
889         int right_level;
890 
891         switch (channel) {
892                 case SOUND_MIXER_OGAIN:
893                         left_level  = (harmony.current_gain & GAIN_LO_MASK) >> GAIN_LO_SHIFT;
894                         right_level = (harmony.current_gain & GAIN_RO_MASK) >> GAIN_RO_SHIFT;
895                         left_level  = to_oss_level(MAX_OUTPUT_LEVEL - left_level, MAX_OUTPUT_LEVEL);
896                         right_level = to_oss_level(MAX_OUTPUT_LEVEL - right_level, MAX_OUTPUT_LEVEL);
897                         return (right_level << 8)+left_level;
898                         
899                 case SOUND_MIXER_IGAIN:
900                         left_level = (harmony.current_gain & GAIN_LI_MASK) >> GAIN_LI_SHIFT;
901                         right_level= (harmony.current_gain & GAIN_RI_MASK) >> GAIN_RI_SHIFT;
902                         left_level = to_oss_level(left_level, MAX_INPUT_LEVEL);
903                         right_level= to_oss_level(right_level, MAX_INPUT_LEVEL);
904                         return (right_level << 8)+left_level;
905                         
906                 case SOUND_MIXER_VOLUME:
907                         left_level = (harmony.current_gain & GAIN_MA_MASK) >> GAIN_MA_SHIFT;
908                         left_level = to_oss_level(MAX_VOLUME_LEVEL-left_level, MAX_VOLUME_LEVEL);
909                         return left_level;
910         }
911         return -EINVAL;
912 }
913 
914 
915 
916 /*
917  * Some conversions for the same reasons.
918  * We give back the new real value(s) due to
919  * the rescale.
920  */
921 
922 static int harmony_mixer_set_level(int channel, int value)
923 {
924         int left_level;
925         int right_level;
926         int new_left_level;
927         int new_right_level;
928 
929         right_level = (value & 0x0000ff00) >> 8;
930         left_level = value & 0x000000ff;
931   
932         switch (channel) {
933                 case SOUND_MIXER_OGAIN:
934                         right_level = to_harmony_level(100-right_level, MAX_OUTPUT_LEVEL);
935                         left_level  = to_harmony_level(100-left_level, MAX_OUTPUT_LEVEL);
936                         new_right_level = to_oss_level(MAX_OUTPUT_LEVEL - right_level, MAX_OUTPUT_LEVEL);
937                         new_left_level  = to_oss_level(MAX_OUTPUT_LEVEL - left_level, MAX_OUTPUT_LEVEL);
938                         harmony.current_gain = (harmony.current_gain & ~(GAIN_LO_MASK | GAIN_RO_MASK)) 
939                                         | (left_level << GAIN_LO_SHIFT) | (right_level << GAIN_RO_SHIFT);
940                         harmony_mixer_set_gain();
941                         return (new_right_level << 8) + new_left_level;
942                         
943                 case SOUND_MIXER_IGAIN:
944                         right_level = to_harmony_level(right_level, MAX_INPUT_LEVEL);
945                         left_level  = to_harmony_level(left_level, MAX_INPUT_LEVEL);
946                         new_right_level = to_oss_level(right_level, MAX_INPUT_LEVEL);
947                         new_left_level  = to_oss_level(left_level, MAX_INPUT_LEVEL);
948                         harmony.current_gain = (harmony.current_gain & ~(GAIN_LI_MASK | GAIN_RI_MASK))
949                                         | (left_level << GAIN_LI_SHIFT) | (right_level << GAIN_RI_SHIFT);
950                         harmony_mixer_set_gain();
951                         return (new_right_level << 8) + new_left_level;
952         
953                 case SOUND_MIXER_VOLUME:
954                         left_level = to_harmony_level(100-left_level, MAX_VOLUME_LEVEL);
955                         new_left_level = to_oss_level(MAX_VOLUME_LEVEL-left_level, MAX_VOLUME_LEVEL);
956                         harmony.current_gain = (harmony.current_gain & ~GAIN_MA_MASK)| (left_level << GAIN_MA_SHIFT);
957                         harmony_mixer_set_gain();
958                         return new_left_level;
959         }
960 
961         return -EINVAL;
962 }
963 
964 #undef to_harmony_level
965 #undef to_oss_level
966 
967 /* 
968  * Return the selected input device (mic or line)
969  */
970 
971 static int harmony_mixer_get_recmask(void) 
972 {
973         int current_input_line;
974         
975         current_input_line = (harmony.current_gain & GAIN_IS_MASK) 
976                                     >> GAIN_IS_SHIFT;
977         if (current_input_line) 
978                 return SOUND_MASK_MIC;
979 
980         return SOUND_MASK_LINE;
981 }
982 
983 /*
984  * Set the input (only one at time, arbitrary priority to line in)
985  */
986 
987 static int harmony_mixer_set_recmask(int recmask)
988 {
989         int new_input_line;
990         int new_input_mask;
991 
992         if ((recmask & SOUND_MASK_LINE)) {
993                 new_input_line = 0;
994                 new_input_mask = SOUND_MASK_LINE;
995         } else  {
996                 new_input_line = 1;
997                 new_input_mask = SOUND_MASK_MIC;
998         }
999         harmony.current_gain = ((harmony.current_gain & ~GAIN_IS_MASK) | 
1000                                 (new_input_line << GAIN_IS_SHIFT ));
1001         harmony_mixer_set_gain();
1002         return new_input_mask;
1003 }
1004 
1005 
1006 /* 
1007  * give the active outlines
1008  */
1009 
1010 static int harmony_mixer_get_outmask(void)
1011 {
1012         int outmask = 0;
1013         
1014         if (harmony.current_gain & GAIN_HE_MASK) outmask |=SOUND_MASK_PHONEOUT;
1015         if (harmony.current_gain & GAIN_LE_MASK) outmask |=SOUND_MASK_LINE;
1016         if (harmony.current_gain & GAIN_SE_MASK) outmask |=SOUND_MASK_SPEAKER;
1017         
1018         return outmask;
1019 }
1020 
1021 
1022 static int harmony_mixer_set_outmask(int outmask)
1023 {
1024         if (outmask & SOUND_MASK_PHONEOUT) 
1025                 harmony.current_gain |= GAIN_HE_MASK; 
1026         else 
1027                 harmony.current_gain &= ~GAIN_HE_MASK;
1028         
1029         if (outmask & SOUND_MASK_LINE) 
1030                 harmony.current_gain |= GAIN_LE_MASK;
1031         else 
1032                 harmony.current_gain &= ~GAIN_LE_MASK;
1033         
1034         if (outmask & SOUND_MASK_SPEAKER) 
1035                 harmony.current_gain |= GAIN_SE_MASK;
1036         else 
1037                 harmony.current_gain &= ~GAIN_SE_MASK;
1038         
1039         harmony_mixer_set_gain();
1040 
1041         return (outmask & (SOUND_MASK_PHONEOUT | SOUND_MASK_LINE | SOUND_MASK_SPEAKER));
1042 }
1043 
1044 /*
1045  * This code is inspired from sb_mixer.c
1046  */
1047 
1048 static int harmony_mixer_ioctl(struct inode * inode, struct file * file,
1049                 unsigned int cmd, unsigned long arg)
1050 {
1051         int val;
1052         int ret;
1053 
1054         if (cmd == SOUND_MIXER_INFO) {
1055                 mixer_info info;
1056                 memset(&info, 0, sizeof(info));
1057                 strncpy(info.id, "harmony", sizeof(info.id)-1);
1058                 strncpy(info.name, "Harmony audio", sizeof(info.name)-1);
1059                 info.modify_counter = 1; /* ? */
1060                 if (copy_to_user((void *)arg, &info, sizeof(info)))
1061                         return -EFAULT;
1062                 return 0;
1063         }
1064         
1065         if (cmd == OSS_GETVERSION)
1066                 return put_user(SOUND_VERSION, (int *)arg);
1067 
1068         /* read */
1069         val = 0;
1070         if (_SIOC_DIR(cmd) & _SIOC_WRITE)
1071                 if (get_user(val, (int *)arg))
1072                         return -EFAULT;
1073 
1074         switch (cmd) {
1075         case MIXER_READ(SOUND_MIXER_CAPS):
1076                 ret = SOUND_CAP_EXCL_INPUT;
1077                 break;
1078         case MIXER_READ(SOUND_MIXER_STEREODEVS):
1079                 ret = SOUND_MASK_IGAIN | SOUND_MASK_OGAIN;
1080                 break;
1081                 
1082         case MIXER_READ(SOUND_MIXER_RECMASK):
1083                 ret = SOUND_MASK_MIC | SOUND_MASK_LINE;
1084                 break;
1085         case MIXER_READ(SOUND_MIXER_DEVMASK):
1086                 ret = SOUND_MASK_OGAIN | SOUND_MASK_IGAIN |
1087                         SOUND_MASK_VOLUME;
1088                 break;
1089         case MIXER_READ(SOUND_MIXER_OUTMASK):
1090                 ret = SOUND_MASK_SPEAKER | SOUND_MASK_LINE |
1091                         SOUND_MASK_PHONEOUT;
1092                 break;
1093                 
1094         case MIXER_WRITE(SOUND_MIXER_RECSRC):
1095                 ret = harmony_mixer_set_recmask(val);
1096                 break;
1097         case MIXER_READ(SOUND_MIXER_RECSRC):
1098                 ret = harmony_mixer_get_recmask();
1099                 break;
1100               
1101         case MIXER_WRITE(SOUND_MIXER_OUTSRC):
1102                 ret = harmony_mixer_set_outmask(val);
1103                 break;
1104         case MIXER_READ(SOUND_MIXER_OUTSRC):
1105                 ret = harmony_mixer_get_outmask();
1106                 break;
1107         
1108         case MIXER_WRITE(SOUND_MIXER_OGAIN):
1109         case MIXER_WRITE(SOUND_MIXER_IGAIN):
1110         case MIXER_WRITE(SOUND_MIXER_VOLUME):
1111                 ret = harmony_mixer_set_level(cmd & 0xff, val);
1112                 break;
1113 
1114         case MIXER_READ(SOUND_MIXER_OGAIN):
1115         case MIXER_READ(SOUND_MIXER_IGAIN):
1116         case MIXER_READ(SOUND_MIXER_VOLUME):
1117                 ret = harmony_mixer_get_level(cmd & 0xff);
1118                 break;
1119 
1120         default:
1121                 return -EINVAL;
1122         }
1123 
1124         if (put_user(ret, (int *)arg))
1125                 return -EFAULT;
1126         return 0;
1127 }
1128 
1129 
1130 static int harmony_mixer_open(struct inode *inode, struct file *file)
1131 {
1132         if (harmony.mixer_open) 
1133                 return -EBUSY;
1134         harmony.mixer_open++;
1135         return 0;
1136 }
1137 
1138 static int harmony_mixer_release(struct inode *inode, struct file *file)
1139 {
1140         if (!harmony.mixer_open) 
1141                 return -EBUSY;
1142         harmony.mixer_open--;
1143         return 0;
1144 }
1145 
1146 static struct file_operations harmony_mixer_fops = {
1147         .owner          = THIS_MODULE,
1148         .llseek         = no_llseek,
1149         .open           = harmony_mixer_open,
1150         .release        = harmony_mixer_release,
1151         .ioctl          = harmony_mixer_ioctl,
1152 };
1153 
1154 
1155 /*
1156  * Mute all the output and reset Harmony.
1157  */
1158 
1159 static void __init harmony_mixer_reset(void)
1160 {
1161         harmony.current_gain = GAIN_TOTAL_SILENCE;
1162         harmony_mixer_set_gain();
1163         harmony_wait_CNTL();
1164         gsc_writel(1, &harmony.hpa->reset);
1165         mdelay(50);             /* wait 50 ms */
1166         gsc_writel(0, &harmony.hpa->reset);
1167         harmony.current_gain = GAIN_DEFAULT;
1168         harmony_mixer_set_gain();
1169 }
1170 
1171 static int __init harmony_mixer_init(void)
1172 {
1173         /* Register the device file operations */
1174         harmony.mixer_unit = register_sound_mixer(&harmony_mixer_fops, -1);
1175         if (harmony.mixer_unit < 0) {
1176                 printk(KERN_WARNING PFX "Error Registering Mixer Driver\n");
1177                 return -EFAULT;
1178         }
1179   
1180         harmony_mixer_reset();
1181         harmony.mixer_open = 0;
1182         
1183         return 0;
1184 }
1185 
1186 
1187 
1188 /* 
1189  * This is the callback that's called by the inventory hardware code 
1190  * if it finds a match to the registered driver. 
1191  */
1192 static int __init
1193 harmony_driver_callback(struct parisc_device *dev)
1194 {
1195         u8      id;
1196         u8      rev;
1197         u32     cntl;
1198         int     ret;
1199 
1200         if (harmony.hpa) {
1201                 /* We only support one Harmony at this time */
1202                 printk(KERN_ERR PFX "driver already registered\n");
1203                 return -EBUSY;
1204         }
1205 
1206         /* Set the HPA of harmony */
1207         harmony.hpa = (struct harmony_hpa *)dev->hpa;
1208 
1209         harmony.irq = dev->irq;
1210         if (!harmony.irq) {
1211                 printk(KERN_ERR PFX "no irq found\n");
1212                 return -ENODEV;
1213         }
1214 
1215         /* Grab the ID and revision from the device */
1216         id = gsc_readb(&harmony.hpa->id);
1217         if ((id | 1) != 0x15) {
1218                 printk(KERN_WARNING PFX "wrong harmony id 0x%02x\n", id);
1219                 return -EBUSY;
1220         }
1221         cntl = gsc_readl(&harmony.hpa->cntl);
1222         rev = (cntl>>20) & 0xff;
1223 
1224         printk(KERN_INFO "Lasi Harmony Audio driver " HARMONY_VERSION ", "
1225                         "h/w id %i, rev. %i at 0x%lx, IRQ %i\n",
1226                         id, rev, dev->hpa, harmony.irq);
1227         
1228         /* Make sure the control bit isn't set, although I don't think it 
1229            ever is. */
1230         if (cntl & CNTL_C) {
1231                 printk(KERN_WARNING PFX "CNTL busy\n");
1232                 harmony.hpa = 0;
1233                 return -EBUSY;
1234         }
1235 
1236         /* a fake pci_dev is needed for pci_* functions under ccio */
1237         harmony.fake_pci_dev = ccio_get_fake(dev);
1238         
1239         /* Initialize the memory buffers */
1240         if (harmony_alloc_buffer(&played_buf, MAX_BUFS) || 
1241             harmony_alloc_buffer(&recorded_buf, MAX_BUFS) ||
1242             harmony_alloc_buffer(&graveyard, 1) ||
1243             harmony_alloc_buffer(&silent, 1)) {
1244                 ret = -EBUSY;
1245                 goto out_err;
1246         }
1247 
1248         /* Initialize /dev/mixer and /dev/audio  */
1249         if ((ret=harmony_mixer_init())) 
1250                 goto out_err;
1251         if ((ret=harmony_audio_init())) 
1252                 goto out_err;
1253 
1254         return 0;
1255 
1256 out_err:
1257         harmony.hpa = 0;
1258         harmony_free_buffer(&played_buf);
1259         harmony_free_buffer(&recorded_buf);
1260         harmony_free_buffer(&graveyard);
1261         harmony_free_buffer(&silent);
1262         return ret;
1263 }
1264 
1265 
1266 static struct parisc_device_id harmony_tbl[] = {
1267  /* { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007A }, Bushmaster/Flounder */
1268  { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007B }, /* 712/715 Audio */
1269  { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007E }, /* Pace Audio */
1270  { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007F }, /* Outfield / Coral II */
1271  { 0, }
1272 };
1273 
1274 MODULE_DEVICE_TABLE(parisc, harmony_tbl);
1275 
1276 static struct parisc_driver harmony_driver = {
1277         .name           = "Lasi Harmony",
1278         .id_table       = harmony_tbl,
1279         .probe          = harmony_driver_callback,
1280 };
1281 
1282 static int __init init_harmony(void)
1283 {
1284         return register_parisc_driver(&harmony_driver);
1285 }
1286 
1287 static void __exit cleanup_harmony(void)
1288 {
1289         free_irq(harmony.irq, &harmony);
1290         unregister_sound_mixer(harmony.mixer_unit);
1291         unregister_sound_dsp(harmony.dsp_unit);
1292         harmony_free_buffer(&played_buf);
1293         harmony_free_buffer(&recorded_buf);
1294         harmony_free_buffer(&graveyard);
1295         harmony_free_buffer(&silent);
1296         unregister_parisc_driver(&harmony_driver);
1297 }
1298 
1299 
1300 MODULE_AUTHOR("Alex DeVries <alex@linuxcare.com>");
1301 MODULE_DESCRIPTION("Harmony sound driver");
1302 MODULE_LICENSE("GPL");
1303 
1304 module_init(init_harmony);
1305 module_exit(cleanup_harmony);
1306 
1307 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp