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
38enum {
39	STREAM_PLAYBACK,
40	STREAM_RECORD
41};
42
43struct geode_stream;
44struct geode_multi;
45extern pci_module_info* gPci;
46
47/*!	This structure describes a controller.
48*/
49struct 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*/
102struct 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
171struct 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
181struct 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 */
196extern device_hooks gDriverHooks;
197extern geode_controller gCards[MAX_CARDS];
198extern uint32 gNumCards;
199
200/* geode_multi.cpp */
201status_t multi_audio_control(geode_controller* controller, uint32 op, void* arg, size_t length);
202
203/* geode_controller.cpp: Basic controller support */
204status_t geode_hw_init(geode_controller* controller);
205void geode_hw_stop(geode_controller* controller);
206void geode_hw_uninit(geode_controller* controller);
207
208uint16 geode_codec_read(geode_controller *controller, uint8 regno);
209void geode_codec_write(geode_controller *controller, uint8 regno, uint16 value);
210
211/* geode_controller.cpp: Stream support */
212geode_stream* geode_stream_new(geode_controller* controller, int type);
213void geode_stream_delete(geode_stream* stream);
214status_t geode_stream_setup_buffers(geode_stream* stream, const char* desc);
215status_t geode_stream_start(geode_stream* stream);
216status_t geode_stream_stop(geode_stream* stream);
217
218#endif	/* _DRIVER_H_ */
219