xref: /haiku/src/add-ons/kernel/drivers/audio/ac97/geode/driver.h (revision dd2a1e350b303b855a50fd64e6cb55618be1ae6a)
1 /*
2  * Copyright 2009, Haiku, Inc. All Rights Reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *	Jérôme Duval (korli@users.berlios.de)
7  */
8 #ifndef _DRIVER_H_
9 #define _DRIVER_H_
10 
11 #include <KernelExport.h>
12 #include <Drivers.h>
13 #include <PCI.h>
14 
15 #include <string.h>
16 #include <stdlib.h>
17 
18 #define DEVFS_PATH_FORMAT "audio/hmulti/geode/%" B_PRIu32
19 #include <hmulti_audio.h>
20 
21 #include "ac97.h"
22 #include "gcscaudioreg.h"
23 
24 #define MAX_CARDS				4
25 #define GEODE_MAX_STREAMS			4
26 #define STREAM_MAX_BUFFERS			4
27 #define STREAM_MIN_BUFFERS			2
28 
29 #define DEFAULT_FRAMES_PER_BUFFER	2048
30 
31 
32 #define AMD_VENDOR_ID			0x1022
33 #define AMD_CS5536_AUDIO_DEVICE_ID	0x2093
34 
35 #define NS_VENDOR_ID			0x100b
36 #define NS_CS5535_AUDIO_DEVICE_ID	0x002e
37 
38 enum {
39 	STREAM_PLAYBACK,
40 	STREAM_RECORD
41 };
42 
43 struct geode_stream;
44 struct geode_multi;
45 extern pci_module_info* gPci;
46 
47 /*!	This structure describes a controller.
48 */
49 struct geode_controller {
50 	struct pci_info	pci_info;
51 	int32			opened;
52 	const char*		devfs_path;
53 
54 	uint32			nabmbar;
55 	uint32			irq;
56 
57 	uint32			num_streams;
58 	geode_stream*		streams[GEODE_MAX_STREAMS];
59 
60 	/* Multi Audio API data */
61 	geode_stream*		playback_stream;
62 	geode_stream*		record_stream;
63 
64 	geode_multi*		multi;
65 
66 	ac97_dev *		ac97;
67 
68 	uint8 Read8(uint32 reg)
69 	{
70 		return gPci->read_io_8(nabmbar + reg);
71 	}
72 
73 	uint16 Read16(uint32 reg)
74 	{
75 		return gPci->read_io_16(nabmbar + reg);
76 	}
77 
78 	uint32 Read32(uint32 reg)
79 	{
80 		return gPci->read_io_32(nabmbar + reg);
81 	}
82 
83 	void Write8(uint32 reg, uint8 value)
84 	{
85 		gPci->write_io_8(nabmbar + reg, value);
86 	}
87 
88 	void Write16(uint32 reg, uint16 value)
89 	{
90 		gPci->write_io_16(nabmbar + reg, value);
91 	}
92 
93 	void Write32(uint32 reg, uint32 value)
94 	{
95 		gPci->write_io_32(nabmbar + reg, value);
96 	}
97 };
98 
99 /*!	This structure describes a single stream of audio data,
100 	which is can have multiple channels (for stereo or better).
101 */
102 struct geode_stream {
103 	uint16		status;				/* Interrupt status */
104 	uint8		offset;				/* Stream offset */
105 	uint8		dma_offset;				/* Stream dma offset */
106 	uint16		ac97_rate_reg;			/* AC97 rate register */
107 	bool		running;
108 	spinlock	lock;				/* Write lock */
109 	uint32		type;
110 
111 	geode_controller* controller;
112 
113 	uint32		sample_rate;
114 	uint32		sample_format;
115 
116 	uint32		num_buffers;
117 	uint32		num_channels;
118 	uint32		buffer_length;		/* size of buffer in samples */
119 	uint32		sample_size;
120 	uint8*		buffers[STREAM_MAX_BUFFERS];
121 					/* Virtual addresses for buffer */
122 	uint32		physical_buffers[STREAM_MAX_BUFFERS];
123 					/* Physical addresses for buffer */
124 	sem_id		buffer_ready_sem;
125 	bigtime_t	real_time;
126 	uint64		frames_count;
127 	int32		buffer_cycle;
128 
129 	uint32		rate;			/* Samplerate */
130 
131 	area_id		buffer_area;
132 	area_id		buffer_descriptors_area;
133 	uint32		physical_buffer_descriptors;	/* BDL physical address */
134 
135 	uint8 Read8(uint32 reg)
136 	{
137 		return controller->Read8(ACC_BM0_CMD + offset + reg);
138 	}
139 
140 	uint16 Read16(uint32 reg)
141 	{
142 		return controller->Read16(ACC_BM0_CMD + offset + reg);
143 	}
144 
145 	uint32 Read32(uint32 reg)
146 	{
147 		return controller->Read32(ACC_BM0_CMD + offset + reg);
148 	}
149 
150 	void Write8(uint32 reg, uint8 value)
151 	{
152 		controller->Write8(ACC_BM0_CMD + offset + reg, value);
153 	}
154 
155 	void Write16(uint32 reg, uint16 value)
156 	{
157 		controller->Write16(ACC_BM0_CMD + offset + reg, value);
158 	}
159 
160 	void Write32(uint32 reg, uint32 value)
161 	{
162 		controller->Write32(ACC_BM0_CMD + offset + reg, value);
163 	}
164 };
165 
166 #define MULTI_CONTROL_FIRSTID	1024
167 #define MULTI_CONTROL_MASTERID	0
168 #define MULTI_MAX_CONTROLS 128
169 #define MULTI_MAX_CHANNELS 128
170 
171 struct multi_mixer_control {
172 	geode_multi	*multi;
173 	void	(*get) (geode_controller *card, const void *cookie, int32 type, float *values);
174 	void	(*set) (geode_controller *card, const void *cookie, int32 type, float *values);
175 	const void    *cookie;
176 	int32 type;
177 	multi_mix_control	mix_control;
178 };
179 
180 
181 struct geode_multi {
182 	geode_controller *controller;
183 	multi_mixer_control controls[MULTI_MAX_CONTROLS];
184 	uint32 control_count;
185 
186 	multi_channel_info chans[MULTI_MAX_CHANNELS];
187 	uint32 output_channel_count;
188 	uint32 input_channel_count;
189 	uint32 output_bus_channel_count;
190 	uint32 input_bus_channel_count;
191 	uint32 aux_bus_channel_count;
192 };
193 
194 
195 /* driver.cpp */
196 extern device_hooks gDriverHooks;
197 extern geode_controller gCards[MAX_CARDS];
198 extern uint32 gNumCards;
199 
200 /* geode_multi.cpp */
201 status_t multi_audio_control(geode_controller* controller, uint32 op, void* arg, size_t length);
202 
203 /* geode_controller.cpp: Basic controller support */
204 status_t geode_hw_init(geode_controller* controller);
205 void geode_hw_stop(geode_controller* controller);
206 void geode_hw_uninit(geode_controller* controller);
207 
208 uint16 geode_codec_read(geode_controller *controller, uint8 regno);
209 void geode_codec_write(geode_controller *controller, uint8 regno, uint16 value);
210 
211 /* geode_controller.cpp: Stream support */
212 geode_stream* geode_stream_new(geode_controller* controller, int type);
213 void geode_stream_delete(geode_stream* stream);
214 status_t geode_stream_setup_buffers(geode_stream* stream, const char* desc);
215 status_t geode_stream_start(geode_stream* stream);
216 status_t geode_stream_stop(geode_stream* stream);
217 
218 #endif	/* _DRIVER_H_ */
219