Changeset c885a21 in mainline


Ignore:
Timestamp:
2011-11-14T12:38:50Z (12 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
1269160
Parents:
1b93658
Message:

sb16: Switch to new ISA bus provided DMA controller access.

Location:
uspace/drv/audio/sb16
Files:
2 deleted
6 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/audio/sb16/Makefile

    r1b93658 rc885a21  
    4040        beep.c \
    4141        dsp.c \
    42         dma_controller.c \
    4342        main.c \
    4443        mixer.c \
  • uspace/drv/audio/sb16/dsp.c

    r1b93658 rc885a21  
    3333 */
    3434
     35#include <devman.h>
     36#include <device/hw_res.h>
    3537#include <libarch/ddi.h>
    3638#include <libarch/barrier.h>
    3739#include <str_error.h>
     40#include <bool.h>
    3841
    3942#include "dma.h"
    40 #include "dma_controller.h"
    4143#include "ddf_log.h"
    4244#include "dsp_commands.h"
     
    5153
    5254#define DSP_RESET_RESPONSE 0xaa
    53 #define SB_DMA_CHAN_16 5
    54 #define SB_DMA_CHAN_8 1
    5555
    5656#define AUTO_DMA_MODE
     
    105105}
    106106/*----------------------------------------------------------------------------*/
     107static 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/*----------------------------------------------------------------------------*/
    107121static inline int sb_setup_buffer(sb_dsp_t *dsp)
    108122{
     
    117131        assert(pa < (1 << 25));
    118132        /* 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);
    121134        if (ret == EOK) {
    122135                dsp->buffer.data = buffer;
     
    148161}
    149162/*----------------------------------------------------------------------------*/
    150 int sb_dsp_init(sb_dsp_t *dsp, sb16_regs_t *regs)
     163int sb_dsp_init(sb_dsp_t *dsp, sb16_regs_t *regs, ddf_dev_t *dev,
     164    int dma8, int dma16)
    151165{
    152166        assert(dsp);
    153167        dsp->regs = regs;
     168        dsp->dma8_channel = dma8;
     169        dsp->dma16_channel = dma16;
     170        dsp->sb_dev = dev;
    154171        sb_dsp_reset(dsp);
    155172        /* "DSP takes about 100 microseconds to initialize itself" */
  • uspace/drv/audio/sb16/dsp.h

    r1b93658 rc885a21  
    3535#define DRV_AUDIO_SB16_DSP_H
    3636
     37#include <ddf/driver.h>
    3738#include <libarch/ddi.h>
    3839#include <errno.h>
     
    4243typedef struct sb_dsp_t {
    4344        sb16_regs_t *regs;
     45        int dma8_channel;
     46        int dma16_channel;
    4447        struct {
    4548                uint8_t major;
     
    5760                uint8_t mode;
    5861        } playing;
     62        ddf_dev_t *sb_dev;
    5963} sb_dsp_t;
    6064
    61 int sb_dsp_init(sb_dsp_t *dsp, sb16_regs_t *regs);
     65int sb_dsp_init(sb_dsp_t *dsp, sb16_regs_t *regs, ddf_dev_t *dev,
     66    int dma8, int dma16);
    6267void sb_dsp_interrupt(sb_dsp_t *dsp);
    6368int sb_dsp_play_direct(sb_dsp_t *dsp, const uint8_t *data, size_t size,
  • uspace/drv/audio/sb16/main.c

    r1b93658 rc885a21  
    5050static int sb_add_device(ddf_dev_t *device);
    5151static 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);
    5354static int sb_enable_interrupts(ddf_dev_t *device);
    5455/*----------------------------------------------------------------------------*/
     
    8182{
    8283        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);
    8686}
    8787/*----------------------------------------------------------------------------*/
     
    101101        assert(device);
    102102
    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));
    104104        int ret = soft_state ? EOK : ENOMEM;
    105105        CHECK_RET_RETURN(ret, "Failed to allocate sb16 structure.\n");
     
    107107        uintptr_t sb_regs = 0, mpu_regs = 0;
    108108        size_t sb_regs_size = 0, mpu_regs_size = 0;
    109         int irq = 0;
     109        int irq = 0, dma8 = 0, dma16 = 0;
    110110
    111111        ret = sb_get_res(device, &sb_regs, &sb_regs_size, &mpu_regs,
    112             &mpu_regs_size, &irq);
     112            &mpu_regs_size, &irq, &dma8, &dma16);
    113113        CHECK_RET_RETURN(ret,
    114114            "Failed to get resources: %s.\n", str_error(ret));
     
    145145        CHECK_RET_UNREG_DEST_RETURN(ret, "Failed to create mixer function.");
    146146
    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);
    148149        CHECK_RET_UNREG_DEST_RETURN(ret,
    149150            "Failed to init sb16 driver: %s.\n", str_error(ret));
     
    183184/*----------------------------------------------------------------------------*/
    184185static 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)
    186188{
    187189        assert(device);
     
    191193        assert(mpu_regs_size);
    192194        assert(irq);
     195        assert(dma8);
     196        assert(dma16);
    193197
    194198        async_sess_t *parent_sess =
     
    224228                        }
    225229                        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);
    226237                default:
    227238                        break;
  • uspace/drv/audio/sb16/sb16.c

    r1b93658 rc885a21  
    4040static const irq_cmd_t irq_cmds[] = {{ .cmd = CMD_ACCEPT }};
    4141static 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
    4343
    4444static inline sb_mixer_type_t sb_mixer_type_by_dsp_version(
     
    5757irq_code_t * sb16_irq_code(void)
    5858{
     59        // FIXME: Remove this cast
    5960        return (irq_code_t*)&irq_code;
    6061}
    6162/*----------------------------------------------------------------------------*/
    62 int sb16_init_sb16(sb16_drv_t *drv, void *regs, size_t size)
     63int sb16_init_sb16(sb16_t *sb, void *regs, size_t size,
     64    ddf_dev_t *dev, int dma8, int dma16)
    6365{
    64         assert(drv);
     66        assert(sb);
    6567        /* Setup registers */
    66         int ret = pio_enable(regs, size, (void**)&drv->regs);
     68        int ret = pio_enable(regs, size, (void**)&sb->regs);
    6769        if (ret != EOK)
    6870                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);
    7072
    7173        /* Initialize DSP */
    72         ret = sb_dsp_init(&drv->dsp, drv->regs);
     74        ret = sb_dsp_init(&sb->dsp, sb->regs, dev, dma8, dma16);
    7375        if (ret != EOK) {
    7476                ddf_log_error("Failed to initialize SB DSP: %s.\n",
     
    7779        }
    7880        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);
    8082
    8183        /* Initialize mixer */
    8284        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);
    8486
    85         ret = sb_mixer_init(&drv->mixer, drv->regs, mixer_type);
     87        ret = sb_mixer_init(&sb->mixer, sb->regs, mixer_type);
    8688        if (ret != EOK) {
    8789                ddf_log_error("Failed to initialize SB mixer: %s.\n",
     
    9092        }
    9193        ddf_log_note("Initialized mixer: %s.\n",
    92             sb_mixer_type_str(drv->mixer.type));
     94            sb_mixer_type_str(sb->mixer.type));
    9395
    9496        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);
    9698
    9799        return EOK;
    98100}
    99101/*----------------------------------------------------------------------------*/
    100 int sb16_init_mpu(sb16_drv_t *drv, void *regs, size_t size)
     102int sb16_init_mpu(sb16_t *sb, void *regs, size_t size)
    101103{
    102         drv->mpu_regs = NULL;
     104        sb->mpu_regs = NULL;
    103105        return ENOTSUP;
    104106}
    105107/*----------------------------------------------------------------------------*/
    106 void sb16_interrupt(sb16_drv_t *drv)
     108void sb16_interrupt(sb16_t *sb)
    107109{
    108         assert(drv);
     110        assert(sb);
    109111        /* The acknowledgment of interrupts on DSP version 4.xx is different;
    110112         * It can contain MPU-401 indicator and DMA16 transfers are acked
    111113         * 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);
    115117                /* Third bit is MPU-401 interrupt */
    116118                if (irq_mask & 0x4) {
     
    120122                ddf_log_debug("SB16 interrupt.\n");
    121123        }
    122         sb_dsp_interrupt(&drv->dsp);
     124        sb_dsp_interrupt(&sb->dsp);
    123125}
  • uspace/drv/audio/sb16/sb16.h

    r1b93658 rc885a21  
    4343#include "registers.h"
    4444
    45 typedef struct sb16_drv {
     45typedef struct sb16 {
    4646        sb16_regs_t *regs;
    4747        mpu_regs_t *mpu_regs;
    4848        sb_dsp_t dsp;
    4949        sb_mixer_t mixer;
    50 } sb16_drv_t;
     50} sb16_t;
    5151
    5252irq_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);
     53int sb16_init_sb16(sb16_t *sb, void *regs, size_t size,
     54    ddf_dev_t *dev, int dma8, int dma16);
     55int sb16_init_mpu(sb16_t *sb, void *regs, size_t size);
     56void sb16_interrupt(sb16_t *sb);
    5657
    5758#endif
Note: See TracChangeset for help on using the changeset viewer.