summaryrefslogtreecommitdiffstats
path: root/drivers/sound/vidc.c
blob: 04fcd34134e8aa7a6e7b06813ae1332af388e97a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*
 *	drivers/sound/vidc.c
 *
 *	Detection routine for the VIDC.
 *
 *	Copyright (C) 1997 by Russell King <rmk@arm.uk.linux.org>
 */

#include <linux/module.h>
#include <linux/kernel.h>

#include <asm/io.h>
#include <asm/dma.h>
#include "sound_config.h"
#include "soundmodule.h"
#include "vidc.h"

int vidc_busy;

void vidc_update_filler(int format, int channels)
{
	int fillertype;

#define TYPE(fmt,ch) (((fmt)<<2) | ((ch)&3))

	fillertype = TYPE(format, channels);

	switch (fillertype)
	{
		default:
		case TYPE(AFMT_U8, 1):
			vidc_filler = vidc_fill_1x8_u;
			break;

		case TYPE(AFMT_U8, 2):
			vidc_filler = vidc_fill_2x8_u;
			break;

		case TYPE(AFMT_S8, 1):
			vidc_filler = vidc_fill_1x8_s;
			break;

		case TYPE(AFMT_S8, 2):
			vidc_filler = vidc_fill_2x8_s;
			break;

		case TYPE(AFMT_S16_LE, 1):
			vidc_filler = vidc_fill_1x16_s;
			break;

		case TYPE(AFMT_S16_LE, 2):
			vidc_filler = vidc_fill_2x16_s;
			break;
	}
}

void attach_vidc(struct address_info *hw_config)
{
	char name[32];
	int i;

	sprintf(name, "VIDC %d-bit sound", hw_config->card_subtype);
	conf_printf(name, hw_config);
	memset(dma_buf, 0, sizeof(dma_buf));

	for (i = 0; i < 2; i++)
	{
		dma_buf[i] = get_free_page(GFP_KERNEL);
		if (!dma_buf[i])
			goto nomem;
		dma_pbuf[i] = virt_to_phys(dma_buf[i]);
	}

	if (sound_alloc_dma(hw_config->dma, "VIDCsound"))
	{
		printk(KERN_ERR "VIDCsound: can't allocate virtual DMA channel\n");
		return;
	}
	if (request_irq(hw_config->irq, vidc_sound_dma_irq, 0, "VIDCsound", &dma_start))
	{
		printk(KERN_ERR "VIDCsound: can't allocate DMA interrupt\n");
		return;
	}

//	vidc_synth_init(hw_config);
	vidc_audio_init(hw_config);
	vidc_mixer_init(hw_config);
	return;

nomem:
	for (i = 0; i < 2; i++)
		free_page(dma_buf[i]);
	printk(KERN_ERR "VIDCsound: can't allocate required buffers\n");
}

int probe_vidc(struct address_info *hw_config)
{
	hw_config->irq = IRQ_DMAS0;
	hw_config->dma = DMA_VIRTUAL_SOUND;
	hw_config->dma2 = -1;
	hw_config->card_subtype = 16;
	return 1;
}

void unload_vidc(struct address_info *hw_config)
{
	int i;

	free_irq(hw_config->irq, NULL);
	sound_free_dma(hw_config->dma);

	for (i = 0; i < 2; i++)
		free_page(dma_buf[i]);
}

#ifdef MODULE
static struct address_info config;

int init_module(void)
{
	if (probe_vidc(&config) == 0)
		return -ENODEV;
	printk("VIDC 16-bit serial sound\n");
	SOUND_LOCK;
	attach_vidc(&config);
	return 0;
}

void cleanup_module(void)
{
	unload_vidc(&config);
	SOUND_LOCK_END;
}

#endif