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 Read8geode_controller68 uint8 Read8(uint32 reg) 69 { 70 return gPci->read_io_8(nabmbar + reg); 71 } 72 Read16geode_controller73 uint16 Read16(uint32 reg) 74 { 75 return gPci->read_io_16(nabmbar + reg); 76 } 77 Read32geode_controller78 uint32 Read32(uint32 reg) 79 { 80 return gPci->read_io_32(nabmbar + reg); 81 } 82 Write8geode_controller83 void Write8(uint32 reg, uint8 value) 84 { 85 gPci->write_io_8(nabmbar + reg, value); 86 } 87 Write16geode_controller88 void Write16(uint32 reg, uint16 value) 89 { 90 gPci->write_io_16(nabmbar + reg, value); 91 } 92 Write32geode_controller93 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 Read8geode_stream135 uint8 Read8(uint32 reg) 136 { 137 return controller->Read8(ACC_BM0_CMD + offset + reg); 138 } 139 Read16geode_stream140 uint16 Read16(uint32 reg) 141 { 142 return controller->Read16(ACC_BM0_CMD + offset + reg); 143 } 144 Read32geode_stream145 uint32 Read32(uint32 reg) 146 { 147 return controller->Read32(ACC_BM0_CMD + offset + reg); 148 } 149 Write8geode_stream150 void Write8(uint32 reg, uint8 value) 151 { 152 controller->Write8(ACC_BM0_CMD + offset + reg, value); 153 } 154 Write16geode_stream155 void Write16(uint32 reg, uint16 value) 156 { 157 controller->Write16(ACC_BM0_CMD + offset + reg, value); 158 } 159 Write32geode_stream160 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