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/%lu" 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 vint32 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