Changeset c885a21 in mainline
- Timestamp:
- 2011-11-14T12:38:50Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 1269160
- Parents:
- 1b93658
- Location:
- uspace/drv/audio/sb16
- Files:
-
- 2 deleted
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/audio/sb16/Makefile
r1b93658 rc885a21 40 40 beep.c \ 41 41 dsp.c \ 42 dma_controller.c \43 42 main.c \ 44 43 mixer.c \ -
uspace/drv/audio/sb16/dsp.c
r1b93658 rc885a21 33 33 */ 34 34 35 #include <devman.h> 36 #include <device/hw_res.h> 35 37 #include <libarch/ddi.h> 36 38 #include <libarch/barrier.h> 37 39 #include <str_error.h> 40 #include <bool.h> 38 41 39 42 #include "dma.h" 40 #include "dma_controller.h"41 43 #include "ddf_log.h" 42 44 #include "dsp_commands.h" … … 51 53 52 54 #define DSP_RESET_RESPONSE 0xaa 53 #define SB_DMA_CHAN_16 554 #define SB_DMA_CHAN_8 155 55 56 56 #define AUTO_DMA_MODE … … 105 105 } 106 106 /*----------------------------------------------------------------------------*/ 107 static inline int sb_setup_dma(sb_dsp_t *dsp, uintptr_t pa, size_t size) 108 { 109 async_sess_t *sess = devman_parent_device_connect(EXCHANGE_ATOMIC, 110 dsp->sb_dev->handle, IPC_FLAG_BLOCKING); 111 if (!sess) 112 return ENOMEM; 113 114 const int ret = hw_res_dma_channel_setup(sess, 115 dsp->dma16_channel, pa, size, 116 DMA_MODE_READ | DMA_MODE_AUTO | DMA_MODE_ON_DEMAND); 117 async_hangup(sess); 118 return ret; 119 } 120 /*----------------------------------------------------------------------------*/ 107 121 static inline int sb_setup_buffer(sb_dsp_t *dsp) 108 122 { … … 117 131 assert(pa < (1 << 25)); 118 132 /* Set 16 bit channel */ 119 const int ret = dma_setup_channel(SB_DMA_CHAN_16, pa, BUFFER_SIZE, 120 DMA_MODE_READ | DMA_MODE_AUTO | DMA_MODE_ON_DEMAND); 133 const int ret = sb_setup_dma(dsp, pa, BUFFER_SIZE); 121 134 if (ret == EOK) { 122 135 dsp->buffer.data = buffer; … … 148 161 } 149 162 /*----------------------------------------------------------------------------*/ 150 int sb_dsp_init(sb_dsp_t *dsp, sb16_regs_t *regs) 163 int sb_dsp_init(sb_dsp_t *dsp, sb16_regs_t *regs, ddf_dev_t *dev, 164 int dma8, int dma16) 151 165 { 152 166 assert(dsp); 153 167 dsp->regs = regs; 168 dsp->dma8_channel = dma8; 169 dsp->dma16_channel = dma16; 170 dsp->sb_dev = dev; 154 171 sb_dsp_reset(dsp); 155 172 /* "DSP takes about 100 microseconds to initialize itself" */ -
uspace/drv/audio/sb16/dsp.h
r1b93658 rc885a21 35 35 #define DRV_AUDIO_SB16_DSP_H 36 36 37 #include <ddf/driver.h> 37 38 #include <libarch/ddi.h> 38 39 #include <errno.h> … … 42 43 typedef struct sb_dsp_t { 43 44 sb16_regs_t *regs; 45 int dma8_channel; 46 int dma16_channel; 44 47 struct { 45 48 uint8_t major; … … 57 60 uint8_t mode; 58 61 } playing; 62 ddf_dev_t *sb_dev; 59 63 } sb_dsp_t; 60 64 61 int sb_dsp_init(sb_dsp_t *dsp, sb16_regs_t *regs); 65 int sb_dsp_init(sb_dsp_t *dsp, sb16_regs_t *regs, ddf_dev_t *dev, 66 int dma8, int dma16); 62 67 void sb_dsp_interrupt(sb_dsp_t *dsp); 63 68 int sb_dsp_play_direct(sb_dsp_t *dsp, const uint8_t *data, size_t size, -
uspace/drv/audio/sb16/main.c
r1b93658 rc885a21 50 50 static int sb_add_device(ddf_dev_t *device); 51 51 static int sb_get_res(const ddf_dev_t *device, uintptr_t *sb_regs, 52 size_t *sb_regs_size, uintptr_t *mpu_regs, size_t *mpu_regs_size, int *irq); 52 size_t *sb_regs_size, uintptr_t *mpu_regs, size_t *mpu_regs_size, 53 int *irq, int *dma8, int *dma16); 53 54 static int sb_enable_interrupts(ddf_dev_t *device); 54 55 /*----------------------------------------------------------------------------*/ … … 81 82 { 82 83 assert(dev); 83 sb16_drv_t *sb = dev->driver_data; 84 assert(sb); 85 sb16_interrupt(sb); 84 assert(dev->driver_data); 85 sb16_interrupt(dev->driver_data); 86 86 } 87 87 /*----------------------------------------------------------------------------*/ … … 101 101 assert(device); 102 102 103 sb16_ drv_t *soft_state = ddf_dev_data_alloc(device, sizeof(sb16_drv_t));103 sb16_t *soft_state = ddf_dev_data_alloc(device, sizeof(sb16_t)); 104 104 int ret = soft_state ? EOK : ENOMEM; 105 105 CHECK_RET_RETURN(ret, "Failed to allocate sb16 structure.\n"); … … 107 107 uintptr_t sb_regs = 0, mpu_regs = 0; 108 108 size_t sb_regs_size = 0, mpu_regs_size = 0; 109 int irq = 0 ;109 int irq = 0, dma8 = 0, dma16 = 0; 110 110 111 111 ret = sb_get_res(device, &sb_regs, &sb_regs_size, &mpu_regs, 112 &mpu_regs_size, &irq );112 &mpu_regs_size, &irq, &dma8, &dma16); 113 113 CHECK_RET_RETURN(ret, 114 114 "Failed to get resources: %s.\n", str_error(ret)); … … 145 145 CHECK_RET_UNREG_DEST_RETURN(ret, "Failed to create mixer function."); 146 146 147 ret = sb16_init_sb16(soft_state, (void*)sb_regs, sb_regs_size); 147 ret = sb16_init_sb16( 148 soft_state, (void*)sb_regs, sb_regs_size, device, dma8, dma16); 148 149 CHECK_RET_UNREG_DEST_RETURN(ret, 149 150 "Failed to init sb16 driver: %s.\n", str_error(ret)); … … 183 184 /*----------------------------------------------------------------------------*/ 184 185 static int sb_get_res(const ddf_dev_t *device, uintptr_t *sb_regs, 185 size_t *sb_regs_size, uintptr_t *mpu_regs, size_t *mpu_regs_size, int *irq) 186 size_t *sb_regs_size, uintptr_t *mpu_regs, size_t *mpu_regs_size, 187 int *irq, int *dma8, int *dma16) 186 188 { 187 189 assert(device); … … 191 193 assert(mpu_regs_size); 192 194 assert(irq); 195 assert(dma8); 196 assert(dma16); 193 197 194 198 async_sess_t *parent_sess = … … 224 228 } 225 229 break; 230 case DMA_CHANNEL_16: 231 *dma16 = res->res.dma_channel.dma16; 232 ddf_log_debug("Found DMA16 channel: %d.\n", *dma16); 233 break; 234 case DMA_CHANNEL_8: 235 *dma8 = res->res.dma_channel.dma8; 236 ddf_log_debug("Found DMA8 channel: %d.\n", *dma8); 226 237 default: 227 238 break; -
uspace/drv/audio/sb16/sb16.c
r1b93658 rc885a21 40 40 static const irq_cmd_t irq_cmds[] = {{ .cmd = CMD_ACCEPT }}; 41 41 static const irq_code_t irq_code = 42 { .cmdcount = 1, .cmds = (irq_cmd_t*)irq_cmds }; 42 { .cmdcount = 1, .cmds = (irq_cmd_t*)irq_cmds }; // FIXME: Remove cast 43 43 44 44 static inline sb_mixer_type_t sb_mixer_type_by_dsp_version( … … 57 57 irq_code_t * sb16_irq_code(void) 58 58 { 59 // FIXME: Remove this cast 59 60 return (irq_code_t*)&irq_code; 60 61 } 61 62 /*----------------------------------------------------------------------------*/ 62 int sb16_init_sb16(sb16_drv_t *drv, void *regs, size_t size) 63 int sb16_init_sb16(sb16_t *sb, void *regs, size_t size, 64 ddf_dev_t *dev, int dma8, int dma16) 63 65 { 64 assert( drv);66 assert(sb); 65 67 /* Setup registers */ 66 int ret = pio_enable(regs, size, (void**)& drv->regs);68 int ret = pio_enable(regs, size, (void**)&sb->regs); 67 69 if (ret != EOK) 68 70 return ret; 69 ddf_log_debug("PIO registers at %p accessible.\n", drv->regs);71 ddf_log_debug("PIO registers at %p accessible.\n", sb->regs); 70 72 71 73 /* Initialize DSP */ 72 ret = sb_dsp_init(& drv->dsp, drv->regs);74 ret = sb_dsp_init(&sb->dsp, sb->regs, dev, dma8, dma16); 73 75 if (ret != EOK) { 74 76 ddf_log_error("Failed to initialize SB DSP: %s.\n", … … 77 79 } 78 80 ddf_log_note("Sound blaster DSP (%x.%x) initialized.\n", 79 drv->dsp.version.major, drv->dsp.version.minor);81 sb->dsp.version.major, sb->dsp.version.minor); 80 82 81 83 /* Initialize mixer */ 82 84 const sb_mixer_type_t mixer_type = sb_mixer_type_by_dsp_version( 83 drv->dsp.version.major, drv->dsp.version.minor);85 sb->dsp.version.major, sb->dsp.version.minor); 84 86 85 ret = sb_mixer_init(& drv->mixer, drv->regs, mixer_type);87 ret = sb_mixer_init(&sb->mixer, sb->regs, mixer_type); 86 88 if (ret != EOK) { 87 89 ddf_log_error("Failed to initialize SB mixer: %s.\n", … … 90 92 } 91 93 ddf_log_note("Initialized mixer: %s.\n", 92 sb_mixer_type_str( drv->mixer.type));94 sb_mixer_type_str(sb->mixer.type)); 93 95 94 96 ddf_log_note("Playing startup sound.\n"); 95 sb_dsp_play(& drv->dsp, beep, beep_size, 44100, 1, 8);97 sb_dsp_play(&sb->dsp, beep, beep_size, 44100, 1, 8); 96 98 97 99 return EOK; 98 100 } 99 101 /*----------------------------------------------------------------------------*/ 100 int sb16_init_mpu(sb16_ drv_t *drv, void *regs, size_t size)102 int sb16_init_mpu(sb16_t *sb, void *regs, size_t size) 101 103 { 102 drv->mpu_regs = NULL;104 sb->mpu_regs = NULL; 103 105 return ENOTSUP; 104 106 } 105 107 /*----------------------------------------------------------------------------*/ 106 void sb16_interrupt(sb16_ drv_t *drv)108 void sb16_interrupt(sb16_t *sb) 107 109 { 108 assert( drv);110 assert(sb); 109 111 /* The acknowledgment of interrupts on DSP version 4.xx is different; 110 112 * It can contain MPU-401 indicator and DMA16 transfers are acked 111 113 * differently */ 112 if ( drv->dsp.version.major >= 4) {113 pio_write_8(& drv->regs->mixer_address, MIXER_IRQ_STATUS_ADDRESS);114 const uint8_t irq_mask = pio_read_8(& drv->regs->mixer_data);114 if (sb->dsp.version.major >= 4) { 115 pio_write_8(&sb->regs->mixer_address, MIXER_IRQ_STATUS_ADDRESS); 116 const uint8_t irq_mask = pio_read_8(&sb->regs->mixer_data); 115 117 /* Third bit is MPU-401 interrupt */ 116 118 if (irq_mask & 0x4) { … … 120 122 ddf_log_debug("SB16 interrupt.\n"); 121 123 } 122 sb_dsp_interrupt(& drv->dsp);124 sb_dsp_interrupt(&sb->dsp); 123 125 } -
uspace/drv/audio/sb16/sb16.h
r1b93658 rc885a21 43 43 #include "registers.h" 44 44 45 typedef struct sb16 _drv{45 typedef struct sb16 { 46 46 sb16_regs_t *regs; 47 47 mpu_regs_t *mpu_regs; 48 48 sb_dsp_t dsp; 49 49 sb_mixer_t mixer; 50 } sb16_ drv_t;50 } sb16_t; 51 51 52 52 irq_code_t * sb16_irq_code(void); 53 int sb16_init_sb16(sb16_drv_t *drv, void *regs, size_t size); 54 int sb16_init_mpu(sb16_drv_t *drv, void *regs, size_t size); 55 void sb16_interrupt(sb16_drv_t *drv); 53 int sb16_init_sb16(sb16_t *sb, void *regs, size_t size, 54 ddf_dev_t *dev, int dma8, int dma16); 55 int sb16_init_mpu(sb16_t *sb, void *regs, size_t size); 56 void sb16_interrupt(sb16_t *sb); 56 57 57 58 #endif
Note:
See TracChangeset
for help on using the changeset viewer.