Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/audio/sb16/main.c

    r7de1988c re941bf8  
    4949
    5050static int sb_add_device(ddf_dev_t *device);
    51 static int sb_get_res(ddf_dev_t *device, addr_range_t **pp_sb_regs,
    52     addr_range_t **pp_mpu_regs, int *irq, int *dma8, int *dma16);
     51static 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,
     53    int *irq, int *dma8, int *dma16);
    5354static int sb_enable_interrupts(ddf_dev_t *device);
    54 
     55/*----------------------------------------------------------------------------*/
    5556static driver_ops_t sb_driver_ops = {
    5657        .dev_add = sb_add_device,
    5758};
    58 
     59/*----------------------------------------------------------------------------*/
    5960static driver_t sb_driver = {
    6061        .name = NAME,
    6162        .driver_ops = &sb_driver_ops
    6263};
    63 
    64 /** Initialize global driver structures (NONE).
     64//static ddf_dev_ops_t sb_ops = {};
     65/*----------------------------------------------------------------------------*/
     66/** Initializes global driver structures (NONE).
    6567 *
    6668 * @param[in] argc Nmber of arguments in argv vector (ignored).
     
    7375{
    7476        printf(NAME": HelenOS SB16 audio driver.\n");
    75         ddf_log_init(NAME);
     77        ddf_log_init(NAME, LVL_DEBUG2);
    7678        return ddf_driver_main(&sb_driver);
    7779}
     
    7981static void irq_handler(ddf_dev_t *dev, ipc_callid_t iid, ipc_call_t *call)
    8082{
    81         sb16_t *sb16_dev = ddf_dev_data_get(dev);
    82         sb16_interrupt(sb16_dev);
    83 }
    84 
    85 /** Initialize new SB16 driver instance.
     83        assert(dev);
     84        assert(dev->driver_data);
     85        sb16_interrupt(dev->driver_data);
     86}
     87
     88/** Initializes a new ddf driver instance of SB16.
    8689 *
    8790 * @param[in] device DDF instance of the device to initialize.
     
    9093static int sb_add_device(ddf_dev_t *device)
    9194{
    92         bool handler_regd = false;
     95#define CHECK_RET_RETURN(ret, msg...) \
     96if (ret != EOK) { \
     97        ddf_log_error(msg); \
     98        return ret; \
     99} else (void)0
     100
     101        assert(device);
     102
     103        sb16_t *soft_state = ddf_dev_data_alloc(device, sizeof(sb16_t));
     104        int ret = soft_state ? EOK : ENOMEM;
     105        CHECK_RET_RETURN(ret, "Failed to allocate sb16 structure.");
     106
     107        uintptr_t sb_regs = 0, mpu_regs = 0;
     108        size_t sb_regs_size = 0, mpu_regs_size = 0;
     109        int irq = 0, dma8 = 0, dma16 = 0;
     110
     111        ret = sb_get_res(device, &sb_regs, &sb_regs_size, &mpu_regs,
     112            &mpu_regs_size, &irq, &dma8, &dma16);
     113        CHECK_RET_RETURN(ret, "Failed to get resources: %s.", str_error(ret));
     114
    93115        const size_t irq_cmd_count = sb16_irq_code_size();
    94116        irq_cmd_t irq_cmds[irq_cmd_count];
    95117        irq_pio_range_t irq_ranges[1];
    96 
    97         sb16_t *soft_state = ddf_dev_data_alloc(device, sizeof(sb16_t));
    98         int rc = soft_state ? EOK : ENOMEM;
    99         if (rc != EOK) {
    100                 ddf_log_error("Failed to allocate sb16 structure.");
    101                 goto error;
    102         }
    103 
    104         addr_range_t sb_regs;
    105         addr_range_t *p_sb_regs = &sb_regs;
    106         addr_range_t mpu_regs;
    107         addr_range_t *p_mpu_regs = &mpu_regs;
    108         int irq = 0, dma8 = 0, dma16 = 0;
    109 
    110         rc = sb_get_res(device, &p_sb_regs, &p_mpu_regs, &irq, &dma8, &dma16);
    111         if (rc != EOK) {
    112                 ddf_log_error("Failed to get resources: %s.", str_error(rc));
    113                 goto error;
    114         }
    115 
    116         sb16_irq_code(p_sb_regs, dma8, dma16, irq_cmds, irq_ranges);
     118        sb16_irq_code((void*)sb_regs, dma8, dma16, irq_cmds, irq_ranges);
    117119
    118120        irq_code_t irq_code = {
     
    123125        };
    124126
    125         rc = register_interrupt_handler(device, irq, irq_handler, &irq_code);
    126         if (rc != EOK) {
    127                 ddf_log_error("Failed to register irq handler: %s.",
    128                     str_error(rc));
    129                 goto error;
    130         }
    131 
    132         handler_regd = true;
    133 
    134         rc = sb_enable_interrupts(device);
    135         if (rc != EOK) {
    136                 ddf_log_error("Failed to enable interrupts: %s.",
    137                     str_error(rc));
    138                 goto error;
    139         }
    140 
    141         rc = sb16_init_sb16(soft_state, p_sb_regs, device, dma8, dma16);
    142         if (rc != EOK) {
    143                 ddf_log_error("Failed to init sb16 driver: %s.",
    144                     str_error(rc));
    145                 goto error;
    146         }
    147 
    148         rc = sb16_init_mpu(soft_state, p_mpu_regs);
    149         if (rc == EOK) {
     127        ret = register_interrupt_handler(device, irq, irq_handler, &irq_code);
     128        CHECK_RET_RETURN(ret,
     129            "Failed to register irq handler: %s.", str_error(ret));
     130
     131#define CHECK_RET_UNREG_DEST_RETURN(ret, msg...) \
     132if (ret != EOK) { \
     133        ddf_log_error(msg); \
     134        unregister_interrupt_handler(device, irq); \
     135        return ret; \
     136} else (void)0
     137
     138        ret = sb_enable_interrupts(device);
     139        CHECK_RET_UNREG_DEST_RETURN(ret, "Failed to enable interrupts: %s.",
     140            str_error(ret));
     141
     142        ret = sb16_init_sb16(
     143            soft_state, (void*)sb_regs, sb_regs_size, device, dma8, dma16);
     144        CHECK_RET_UNREG_DEST_RETURN(ret,
     145            "Failed to init sb16 driver: %s.", str_error(ret));
     146
     147        ret = sb16_init_mpu(soft_state, (void*)mpu_regs, mpu_regs_size);
     148        if (ret == EOK) {
    150149                ddf_fun_t *mpu_fun =
    151150                    ddf_fun_create(device, fun_exposed, "midi");
    152151                if (mpu_fun) {
    153                         rc = ddf_fun_bind(mpu_fun);
    154                         if (rc != EOK)
     152                        ret = ddf_fun_bind(mpu_fun);
     153                        if (ret != EOK)
    155154                                ddf_log_error(
    156155                                    "Failed to bind midi function: %s.",
    157                                     str_error(rc));
     156                                    str_error(ret));
    158157                } else {
    159158                        ddf_log_error("Failed to create midi function.");
    160159                }
    161160        } else {
    162                 ddf_log_warning("Failed to init mpu driver: %s.",
    163                     str_error(rc));
     161            ddf_log_warning("Failed to init mpu driver: %s.", str_error(ret));
    164162        }
    165163
    166164        /* MPU state does not matter */
    167165        return EOK;
    168 error:
    169         if (handler_regd)
    170                 unregister_interrupt_handler(device, irq);
    171         return rc;
    172 }
    173 
    174 static int sb_get_res(ddf_dev_t *device, addr_range_t **pp_sb_regs,
    175     addr_range_t **pp_mpu_regs, int *irq, int *dma8, int *dma16)
     166}
     167
     168static int sb_get_res(const ddf_dev_t *device, uintptr_t *sb_regs,
     169    size_t *sb_regs_size, uintptr_t *mpu_regs, size_t *mpu_regs_size,
     170    int *irq, int *dma8, int *dma16)
    176171{
    177172        assert(device);
    178173
    179         async_sess_t *parent_sess = devman_parent_device_connect(
    180             EXCHANGE_SERIALIZE, ddf_dev_get_handle(device), IPC_FLAG_BLOCKING);
     174        async_sess_t *parent_sess =
     175            devman_parent_device_connect(EXCHANGE_SERIALIZE, device->handle,
     176            IPC_FLAG_BLOCKING);
    181177        if (!parent_sess)
    182178                return ENOMEM;
     
    223219        }
    224220
     221
    225222        if (hw_res.io_ranges.count == 1) {
    226                 if (pp_sb_regs && *pp_sb_regs)
    227                         **pp_sb_regs = hw_res.io_ranges.ranges[0];
    228                 if (pp_mpu_regs)
    229                         *pp_mpu_regs = NULL;
     223                if (sb_regs)
     224                        *sb_regs = hw_res.io_ranges.ranges[0].address;
     225                if (sb_regs_size)
     226                        *sb_regs_size = hw_res.io_ranges.ranges[0].size;
    230227        } else {
    231228                const int sb =
    232229                    (hw_res.io_ranges.ranges[0].size >= sizeof(sb16_regs_t))
    233                         ? 0 : 1;
     230                        ? 1 : 0;
    234231                const int mpu = 1 - sb;
    235                 if (pp_sb_regs && *pp_sb_regs)
    236                         **pp_sb_regs = hw_res.io_ranges.ranges[sb];
    237                 if (pp_mpu_regs && *pp_mpu_regs)
    238                         **pp_mpu_regs = hw_res.io_ranges.ranges[mpu];
     232                if (sb_regs)
     233                        *sb_regs = hw_res.io_ranges.ranges[sb].address;
     234                if (sb_regs_size)
     235                        *sb_regs_size = hw_res.io_ranges.ranges[sb].size;
     236                if (mpu_regs)
     237                        *sb_regs = hw_res.io_ranges.ranges[mpu].address;
     238                if (mpu_regs_size)
     239                        *sb_regs_size = hw_res.io_ranges.ranges[mpu].size;
    239240        }
    240241
     
    244245int sb_enable_interrupts(ddf_dev_t *device)
    245246{
    246         async_sess_t *parent_sess = devman_parent_device_connect(
    247             EXCHANGE_SERIALIZE, ddf_dev_get_handle(device), IPC_FLAG_BLOCKING);
     247        async_sess_t *parent_sess =
     248            devman_parent_device_connect(EXCHANGE_SERIALIZE, device->handle,
     249            IPC_FLAG_BLOCKING);
    248250        if (!parent_sess)
    249251                return ENOMEM;
     
    254256        return enabled ? EOK : EIO;
    255257}
    256 
    257258/**
    258259 * @}
Note: See TracChangeset for help on using the changeset viewer.