Changeset d2134da in mainline
- Timestamp:
- 2011-10-03T19:18:53Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- aa5ae788
- Parents:
- dea75c04
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/audio/sb16/dma_controller.c
rdea75c04 rd2134da 34 34 #include <assert.h> 35 35 #include <errno.h> 36 #include <ddi.h> 37 #include <libarch/ddi.h> 36 38 37 39 #include "dma_controller.h" 38 40 39 #define DMA_CONTROLLER_FIRST_BASE 0x041 #define DMA_CONTROLLER_FIRST_BASE ((void*)0x0) 40 42 typedef struct dma_controller_regs_first { 41 43 uint8_t channel_start0; … … 56 58 uint8_t request; /* Memory to memory transfers, NOT implemented on PCs*/ 57 59 uint8_t single_mask; 58 #define DMA_SINGLE_MASK_CHAN_SELECT_MASK (0x3) 59 #define DMA_SINGLE_MASK_CHAN_SELECT_SHIFT (0) 60 #define DMA_SINGLE_MASK_MASK_ON_FLAG (1 << 2) 60 #define DMA_SINGLE_MASK_CHAN_SEL_MASK (0x3) 61 #define DMA_SINGLE_MASK_CHAN_SEL_SHIFT (0) 62 #define DMA_SINGLE_MASK_CHAN_TO_REG(x) \ 63 (((x % 4) & DMA_SINGLE_MASK_CHAN_SEL_MASK) << DMA_SINGLE_MASK_CHAN_SEL_SHIFT) 64 #define DMA_SINGLE_MASK_MASKED_FLAG (1 << 2) 61 65 62 66 uint8_t mode; … … 87 91 } dma_controller_regs_first_t; 88 92 89 #define DMA_CONTROLLER_SECOND_BASE 0xc093 #define DMA_CONTROLLER_SECOND_BASE ((void*)0xc0) 90 94 /* See dma_controller_regs_first_t for register values */ 91 95 typedef struct dma_controller_regs_second { … … 121 125 } dma_controller_regs_second_t; 122 126 123 #define DMA_CONTROLLER_PAGE_BASE 0x81127 #define DMA_CONTROLLER_PAGE_BASE ((void*)0x81) 124 128 typedef struct dma_page_regs { 125 129 uint8_t channel2; … … 141 145 142 146 typedef struct dma_channel { 143 uint8_t offset_reg_address;144 uint8_t size_reg_address;145 uint8_t page_reg_address;147 uint8_t *offset_reg_address; 148 uint8_t *size_reg_address; 149 uint8_t *page_reg_address; 146 150 } dma_channel_t; 147 151 … … 155 159 dma_controller_t controller_8237 = { 156 160 .channel = { 157 { 0x00, 0x01, 0x87 }, { 0x02, 0x03, 0x83 }, 158 { 0x04, 0x05, 0x81 }, { 0x06, 0x07, 0x82 }, 159 { 0xc0, 0xc2, 0x8f }, { 0xc4, 0xc6, 0x8b }, 160 { 0xc8, 0xca, 0x89 }, { 0xcc, 0xce, 0x8a } }, 161 { (uint8_t*)0x00, (uint8_t*)0x01, (uint8_t*)0x87 }, 162 { (uint8_t*)0x02, (uint8_t*)0x03, (uint8_t*)0x83 }, 163 { (uint8_t*)0x04, (uint8_t*)0x05, (uint8_t*)0x81 }, 164 { (uint8_t*)0x06, (uint8_t*)0x07, (uint8_t*)0x82 }, 165 { (uint8_t*)0xc0, (uint8_t*)0xc2, (uint8_t*)0x8f }, 166 { (uint8_t*)0xc4, (uint8_t*)0xc6, (uint8_t*)0x8b }, 167 { (uint8_t*)0xc8, (uint8_t*)0xca, (uint8_t*)0x89 }, 168 { (uint8_t*)0xcc, (uint8_t*)0xce, (uint8_t*)0x8a } }, 161 169 .page_table = NULL, 162 170 .first = NULL, … … 166 174 static inline dma_controller_t *dma_controller_init() 167 175 { 168 return NULL; 176 int ret = pio_enable(DMA_CONTROLLER_PAGE_BASE, sizeof(dma_page_regs_t), 177 (void**)&controller_8237.page_table); 178 if (ret != EOK) 179 return NULL; 180 181 ret = pio_enable(DMA_CONTROLLER_FIRST_BASE, 182 sizeof(dma_controller_regs_first_t), 183 (void**)&controller_8237.first); 184 if (ret != EOK) 185 return NULL; 186 187 ret = pio_enable(DMA_CONTROLLER_SECOND_BASE, 188 sizeof(dma_controller_regs_second_t), 189 (void**)&controller_8237.second); 190 if (ret != EOK) 191 return NULL; 192 return &controller_8237; 193 } 194 /*----------------------------------------------------------------------------*/ 195 static int dma_setup_channel_8bit(dma_controller_t *controller, 196 unsigned channel, uint32_t pa, uint16_t size) 197 { 198 if (channel == 0 || channel > 3) 199 return ENOTSUP; 200 assert(controller); 201 /* Mask DMA request */ 202 uint8_t value = DMA_SINGLE_MASK_CHAN_TO_REG(channel) 203 | DMA_SINGLE_MASK_MASKED_FLAG; 204 pio_write_8(&controller->first->single_mask, value); 205 206 /* Set address -- reset flip-flop*/ 207 pio_write_8(&controller->first->flip_flop, 1); 208 209 /* Low byte */ 210 value = pa & 0xff; 211 pio_write_8(controller->channel[channel].offset_reg_address, value); 212 213 /* High byte */ 214 value = (pa >> 8) & 0xff; 215 pio_write_8(controller->channel[channel].offset_reg_address, value); 216 217 /* Page address - third byte */ 218 value = (pa >> 16) & 0xff; 219 pio_write_8(controller->channel[channel].offset_reg_address, value); 220 221 /* Set size -- reset flip-flop */ 222 pio_write_8(&controller->first->flip_flop, 1); 223 224 /* Low byte */ 225 value = size & 0xff; 226 pio_write_8(controller->channel[channel].offset_reg_address, value); 227 228 /* High byte */ 229 value = (size >> 8) & 0xff; 230 pio_write_8(controller->channel[channel].offset_reg_address, value); 231 232 /* Unmask DMA request */ 233 value = DMA_SINGLE_MASK_CHAN_TO_REG(channel); 234 pio_write_8(&controller->first->single_mask, value); 235 236 return EOK; 237 } 238 /*----------------------------------------------------------------------------*/ 239 static int dma_setup_channel_16bit(dma_controller_t *controller, 240 unsigned channel, uintptr_t pa, size_t size) 241 { 242 if (channel == 4 || channel > 7) 243 return ENOTSUP; 244 assert(controller); 245 /* Mask DMA request */ 246 uint8_t value = DMA_SINGLE_MASK_CHAN_TO_REG(channel) 247 | DMA_SINGLE_MASK_MASKED_FLAG; 248 pio_write_8(&controller->second->single_mask, value); 249 250 /* Set address -- reset flip-flop*/ 251 pio_write_8(&controller->second->flip_flop, 1); 252 253 /* Low byte */ 254 value = pa & 0xff; 255 pio_write_8(controller->channel[channel].offset_reg_address, value); 256 257 /* High byte */ 258 value = (pa >> 8) & 0xff; 259 pio_write_8(controller->channel[channel].offset_reg_address, value); 260 261 /* Page address - third byte */ 262 value = (pa >> 16) & 0xff; 263 pio_write_8(controller->channel[channel].offset_reg_address, value); 264 265 /* Set size -- reset flip-flop */ 266 pio_write_8(&controller->second->flip_flop, 1); 267 268 /* Low byte */ 269 value = size & 0xff; 270 pio_write_8(controller->channel[channel].offset_reg_address, value); 271 272 /* High byte */ 273 value = (size >> 8) & 0xff; 274 pio_write_8(controller->channel[channel].offset_reg_address, value); 275 276 /* Unmask DMA request */ 277 value = DMA_SINGLE_MASK_CHAN_TO_REG(channel); 278 pio_write_8(&controller->second->single_mask, value); 279 280 return EOK; 169 281 } 170 282 /*----------------------------------------------------------------------------*/ … … 173 285 static dma_controller_t *controller = NULL; 174 286 if (!controller) 287 controller = dma_controller_init(); 288 if (!controller) 175 289 return EIO; 176 return ENOTSUP; 290 if (channel <= 4) 291 return dma_setup_channel_8bit(controller, channel, pa, size); 292 else 293 return dma_setup_channel_16bit(controller, channel, pa, size); 177 294 } 178 295 /**
Note:
See TracChangeset
for help on using the changeset viewer.