6 * Copyright (C) 1997-2000 by Russell King <rmk@arm.linux.org.uk>
8 * The VIDC20 sound hardware consists of the VIDC20 itself, a DAC and a DMA
9 * engine. The DMA transfers fixed-format (16-bit little-endian linear)
10 * samples to the VIDC20, which then transfers this data serially to the
11 * DACs. The samplerate is controlled by the VIDC.
13 * We currently support a mixer device, but it is currently non-functional.
16 #include <linux/config.h>
17 #include <linux/init.h>
18 #include <linux/module.h>
19 #include <linux/kernel.h>
21 #include <asm/hardware.h>
25 #include <asm/system.h>
27 #include "sound_config.h"
28 #include "soundmodule.h"
32 #define _SIOC_TYPE(x) _IOC_TYPE(x)
35 #define _SIOC_NR(x) _IOC_NR(x)
38 #define VIDC_SOUND_CLOCK (250000)
41 * When using SERIAL SOUND mode (external DAC), the number of physical
42 * channels is fixed at 2.
46 static int vidc_audio_rate
;
47 static char vidc_audio_format
;
48 static char vidc_audio_channels
;
50 static unsigned char vidc_level_l
[SOUND_MIXER_NRDEVICES
] = {
63 static unsigned char vidc_level_r
[SOUND_MIXER_NRDEVICES
] = {
76 static unsigned int vidc_audio_volume_l
; /* left PCM vol, 0 - 65536 */
77 static unsigned int vidc_audio_volume_r
; /* right PCM vol, 0 - 65536 */
79 static void (*old_mksound
)(unsigned int hz
, unsigned int ticks
);
80 extern void (*kd_mksound
)(unsigned int hz
, unsigned int ticks
);
81 extern void vidc_update_filler(int bits
, int channels
);
82 extern int softoss_dev
;
85 vidc_mksound(unsigned int hz
, unsigned int ticks
)
87 printk("BEEP - %d %d!\n", hz
, ticks
);
91 vidc_mixer_set(int mdev
, unsigned int level
)
93 unsigned int lev_l
= level
& 0x007f;
94 unsigned int lev_r
= (level
& 0x7f00) >> 8;
95 unsigned int mlev_l
, mlev_r
;
102 #define SCALE(lev,master) ((lev) * (master) * 65536 / 10000)
104 mlev_l
= vidc_level_l
[SOUND_MIXER_VOLUME
];
105 mlev_r
= vidc_level_r
[SOUND_MIXER_VOLUME
];
108 case SOUND_MIXER_VOLUME
:
109 case SOUND_MIXER_PCM
:
110 vidc_level_l
[mdev
] = lev_l
;
111 vidc_level_r
[mdev
] = lev_r
;
113 vidc_audio_volume_l
= SCALE(lev_l
, mlev_l
);
114 vidc_audio_volume_r
= SCALE(lev_r
, mlev_r
);
115 /*printk("VIDC: PCM vol %05X %05X\n", vidc_audio_volume_l, vidc_audio_volume_r);*/
121 static int vidc_mixer_ioctl(int dev
, unsigned int cmd
, caddr_t arg
)
126 if (_SIOC_TYPE(cmd
) != 'M')
129 mdev
= _SIOC_NR(cmd
);
131 if (_SIOC_DIR(cmd
) & _SIOC_WRITE
) {
132 if (get_user(val
, (unsigned int *)arg
))
135 if (mdev
< SOUND_MIXER_NRDEVICES
)
136 vidc_mixer_set(mdev
, val
);
145 case SOUND_MIXER_RECSRC
:
149 case SOUND_MIXER_DEVMASK
:
150 val
= SOUND_MASK_VOLUME
| SOUND_MASK_PCM
| SOUND_MASK_SYNTH
;
153 case SOUND_MIXER_STEREODEVS
:
154 val
= SOUND_MASK_VOLUME
| SOUND_MASK_PCM
| SOUND_MASK_SYNTH
;
157 case SOUND_MIXER_RECMASK
:
161 case SOUND_MIXER_CAPS
:
166 if (mdev
< SOUND_MIXER_NRDEVICES
)
167 val
= vidc_level_l
[mdev
] | vidc_level_r
[mdev
] << 8;
172 return put_user(val
, (unsigned int *)arg
) ? -EFAULT
: 0;
175 static unsigned int vidc_audio_set_format(int dev
, unsigned int fmt
)
183 vidc_audio_format
= fmt
;
184 vidc_update_filler(vidc_audio_format
, vidc_audio_channels
);
188 return vidc_audio_format
;
191 static int vidc_audio_set_speed(int dev
, int rate
)
194 unsigned int hwctrl
, hwrate
;
195 unsigned int newsize
, new2size
;
198 * If we have selected 44.1kHz, use the DAC clock.
200 if (0 && rate
== 44100) {
206 hwrate
= (((VIDC_SOUND_CLOCK
* 2) / rate
) + 1) >> 1;
212 rate
= VIDC_SOUND_CLOCK
/ hwrate
;
215 outl(0xb0000000 | (hwrate
- 2), IO_VIDC_BASE
);
216 outl(0xb1000000 | hwctrl
, IO_VIDC_BASE
);
218 newsize
= (10000 / hwrate
) & ~3;
223 for (new2size
= 128; new2size
< newsize
; new2size
<<= 1);
224 if (new2size
- newsize
> newsize
- (new2size
>> 1))
226 if (new2size
> 4096) {
227 printk(KERN_ERR
"VIDC: error: dma buffer (%d) %d > 4K\n",
231 dma_bufsize
= new2size
;
232 vidc_audio_rate
= rate
;
234 return vidc_audio_rate
;
237 static short vidc_audio_set_channels(int dev
, short channels
)
244 vidc_audio_channels
= channels
;
245 vidc_update_filler(vidc_audio_format
, vidc_audio_channels
);
249 return vidc_audio_channels
;
255 static int vidc_audio_open(int dev
, int mode
)
257 /* This audio device does not have recording capability */
258 if (mode
== OPEN_READ
)
271 static void vidc_audio_close(int dev
)
277 * Output a block via DMA to sound device.
279 * We just set the DMA start and count; the DMA interrupt routine
280 * will take care of formatting the samples (via the appropriate
281 * vidc_filler routine), and flag via vidc_audio_dma_interrupt when
282 * more data is required.
285 vidc_audio_output_block(int dev
, unsigned long buf
, int total_count
, int one
)
287 struct dma_buffparms
*dmap
= audio_devs
[dev
]->dmap_out
;
290 save_flags_cli(flags
);
291 dma_start
= buf
- (unsigned long)dmap
->raw_buf_phys
+ (unsigned long)dmap
->raw_buf
;
292 dma_count
= total_count
;
293 restore_flags(flags
);
297 vidc_audio_start_input(int dev
, unsigned long buf
, int count
, int intrflag
)
301 static int vidc_audio_prepare_for_input(int dev
, int bsize
, int bcount
)
306 static void vidc_audio_dma_interrupt(void)
308 DMAbuf_outputintr(vidc_adev
, 1);
312 * Prepare for outputting samples.
314 * Each buffer that will be passed will be `bsize' bytes long,
315 * with a total of `bcount' buffers.
317 static int vidc_audio_prepare_for_output(int dev
, int bsize
, int bcount
)
319 struct audio_operations
*adev
= audio_devs
[dev
];
321 dma_interrupt
= NULL
;
322 adev
->dmap_out
->flags
|= DMA_NODMA
;
328 * Stop our current operation.
330 static void vidc_audio_reset(int dev
)
332 dma_interrupt
= NULL
;
335 static int vidc_audio_local_qlen(int dev
)
337 return /*dma_count !=*/ 0;
340 static void vidc_audio_trigger(int dev
, int enable_bits
)
342 struct audio_operations
*adev
= audio_devs
[dev
];
344 if (enable_bits
& PCM_ENABLE_OUTPUT
) {
345 if (!(adev
->flags
& DMA_ACTIVE
)) {
348 save_flags_cli(flags
);
350 /* prevent recusion */
351 adev
->flags
|= DMA_ACTIVE
;
353 dma_interrupt
= vidc_audio_dma_interrupt
;
354 vidc_sound_dma_irq(0, NULL
, NULL
);
355 outb(DMA_CR_E
| 0x10, IOMD_SD0CR
);
357 restore_flags(flags
);
362 static struct audio_driver vidc_audio_driver
=
364 open
: vidc_audio_open
,
365 close
: vidc_audio_close
,
366 output_block
: vidc_audio_output_block
,
367 start_input
: vidc_audio_start_input
,
368 prepare_for_input
: vidc_audio_prepare_for_input
,
369 prepare_for_output
: vidc_audio_prepare_for_output
,
370 halt_io
: vidc_audio_reset
,
371 local_qlen
: vidc_audio_local_qlen
,
372 trigger
: vidc_audio_trigger
,
373 set_speed
: vidc_audio_set_speed
,
374 set_bits
: vidc_audio_set_format
,
375 set_channels
: vidc_audio_set_channels
378 static struct mixer_operations vidc_mixer_operations
= {
381 ioctl
: vidc_mixer_ioctl
384 void vidc_update_filler(int format
, int channels
)
386 #define TYPE(fmt,ch) (((fmt)<<2) | ((ch)&3))
388 switch (TYPE(format
, channels
)) {
390 case TYPE(AFMT_U8
, 1):
391 vidc_filler
= vidc_fill_1x8_u
;
394 case TYPE(AFMT_U8
, 2):
395 vidc_filler
= vidc_fill_2x8_u
;
398 case TYPE(AFMT_S8
, 1):
399 vidc_filler
= vidc_fill_1x8_s
;
402 case TYPE(AFMT_S8
, 2):
403 vidc_filler
= vidc_fill_2x8_s
;
406 case TYPE(AFMT_S16_LE
, 1):
407 vidc_filler
= vidc_fill_1x16_s
;
410 case TYPE(AFMT_S16_LE
, 2):
411 vidc_filler
= vidc_fill_2x16_s
;
416 static void __init
attach_vidc(struct address_info
*hw_config
)
421 sprintf(name
, "VIDC %d-bit sound", hw_config
->card_subtype
);
422 conf_printf(name
, hw_config
);
423 memset(dma_buf
, 0, sizeof(dma_buf
));
425 adev
= sound_install_audiodrv(AUDIO_DRIVER_VERSION
, name
,
426 &vidc_audio_driver
, sizeof(vidc_audio_driver
),
427 DMA_AUTOMODE
, AFMT_U8
| AFMT_S8
| AFMT_S16_LE
,
428 NULL
, hw_config
->dma
, hw_config
->dma2
);
434 * 1024 bytes => 64 buffers
436 audio_devs
[adev
]->min_fragment
= 10;
437 audio_devs
[adev
]->mixer_dev
= num_mixers
;
439 audio_devs
[adev
]->mixer_dev
=
440 sound_install_mixer(MIXER_DRIVER_VERSION
,
441 name
, &vidc_mixer_operations
,
442 sizeof(vidc_mixer_operations
), NULL
);
444 if (audio_devs
[adev
]->mixer_dev
< 0)
447 for (i
= 0; i
< 2; i
++) {
448 dma_buf
[i
] = get_free_page(GFP_KERNEL
);
450 printk(KERN_ERR
"%s: can't allocate required buffers\n",
454 dma_pbuf
[i
] = virt_to_phys((void *)dma_buf
[i
]);
457 if (sound_alloc_dma(hw_config
->dma
, hw_config
->name
)) {
458 printk(KERN_ERR
"%s: DMA %d is in use\n", name
, hw_config
->dma
);
462 if (request_irq(hw_config
->irq
, vidc_sound_dma_irq
, 0,
463 hw_config
->name
, &dma_start
)) {
464 printk(KERN_ERR
"%s: IRQ %d is in use\n", name
, hw_config
->irq
);
467 old_mksound
= kd_mksound
;
468 kd_mksound
= vidc_mksound
;
470 vidc_mixer_set(SOUND_MIXER_VOLUME
, (85 | 85 << 8));
472 #if defined(CONFIG_SOUND_SOFTOSS) || defined(CONFIG_SOUND_SOFTOSS_MODULE)
478 sound_free_dma(hw_config
->dma
);
481 for (i
= 0; i
< 2; i
++)
482 free_page(dma_buf
[i
]);
483 sound_unload_mixerdev(audio_devs
[adev
]->mixer_dev
);
485 sound_unload_audiodev(adev
);
490 static int __init
probe_vidc(struct address_info
*hw_config
)
492 hw_config
->irq
= IRQ_DMAS0
;
493 hw_config
->dma
= DMA_VIRTUAL_SOUND
;
494 hw_config
->dma2
= -1;
495 hw_config
->card_subtype
= 16;
496 hw_config
->name
= "VIDC20";
500 static void __exit
unload_vidc(struct address_info
*hw_config
)
502 int i
, adev
= vidc_adev
;
507 kd_mksound
= old_mksound
;
509 free_irq(hw_config
->irq
, &dma_start
);
510 sound_free_dma(hw_config
->dma
);
513 sound_unload_mixerdev(audio_devs
[adev
]->mixer_dev
);
514 sound_unload_audiodev(adev
);
515 for (i
= 0; i
< 2; i
++)
516 free_page(dma_buf
[i
]);
520 static struct address_info cfg
;
522 * Note! Module use count is handled by SOUNDLOCK/SOUND_LOCK_END
525 static int __init
init_vidc(void)
527 if (probe_vidc(&cfg
) == 0)
536 static void __exit
cleanup_vidc(void)
542 module_init(init_vidc
);
543 module_exit(cleanup_vidc
);