Ignore:
File:
1 edited

Legend:

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

    re941bf8 r7de1988c  
    4949
    5050static int sb_add_device(ddf_dev_t *device);
    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,
    53     int *irq, int *dma8, int *dma16);
     51static 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);
    5453static int sb_enable_interrupts(ddf_dev_t *device);
    55 /*----------------------------------------------------------------------------*/
     54
    5655static driver_ops_t sb_driver_ops = {
    5756        .dev_add = sb_add_device,
    5857};
    59 /*----------------------------------------------------------------------------*/
     58
    6059static driver_t sb_driver = {
    6160        .name = NAME,
    6261        .driver_ops = &sb_driver_ops
    6362};
    64 //static ddf_dev_ops_t sb_ops = {};
    65 /*----------------------------------------------------------------------------*/
    66 /** Initializes global driver structures (NONE).
     63
     64/** Initialize global driver structures (NONE).
    6765 *
    6866 * @param[in] argc Nmber of arguments in argv vector (ignored).
     
    7573{
    7674        printf(NAME": HelenOS SB16 audio driver.\n");
    77         ddf_log_init(NAME, LVL_DEBUG2);
     75        ddf_log_init(NAME);
    7876        return ddf_driver_main(&sb_driver);
    7977}
     
    8179static void irq_handler(ddf_dev_t *dev, ipc_callid_t iid, ipc_call_t *call)
    8280{
    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.
     81        sb16_t *sb16_dev = ddf_dev_data_get(dev);
     82        sb16_interrupt(sb16_dev);
     83}
     84
     85/** Initialize new SB16 driver instance.
    8986 *
    9087 * @param[in] device DDF instance of the device to initialize.
     
    9390static int sb_add_device(ddf_dev_t *device)
    9491{
    95 #define CHECK_RET_RETURN(ret, msg...) \
    96 if (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 
     92        bool handler_regd = false;
    11593        const size_t irq_cmd_count = sb16_irq_code_size();
    11694        irq_cmd_t irq_cmds[irq_cmd_count];
    11795        irq_pio_range_t irq_ranges[1];
    118         sb16_irq_code((void*)sb_regs, dma8, dma16, irq_cmds, irq_ranges);
     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);
    119117
    120118        irq_code_t irq_code = {
     
    125123        };
    126124
    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...) \
    132 if (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) {
     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) {
    149150                ddf_fun_t *mpu_fun =
    150151                    ddf_fun_create(device, fun_exposed, "midi");
    151152                if (mpu_fun) {
    152                         ret = ddf_fun_bind(mpu_fun);
    153                         if (ret != EOK)
     153                        rc = ddf_fun_bind(mpu_fun);
     154                        if (rc != EOK)
    154155                                ddf_log_error(
    155156                                    "Failed to bind midi function: %s.",
    156                                     str_error(ret));
     157                                    str_error(rc));
    157158                } else {
    158159                        ddf_log_error("Failed to create midi function.");
    159160                }
    160161        } else {
    161             ddf_log_warning("Failed to init mpu driver: %s.", str_error(ret));
     162                ddf_log_warning("Failed to init mpu driver: %s.",
     163                    str_error(rc));
    162164        }
    163165
    164166        /* MPU state does not matter */
    165167        return EOK;
    166 }
    167 
    168 static 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)
     168error:
     169        if (handler_regd)
     170                unregister_interrupt_handler(device, irq);
     171        return rc;
     172}
     173
     174static 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)
    171176{
    172177        assert(device);
    173178
    174         async_sess_t *parent_sess =
    175             devman_parent_device_connect(EXCHANGE_SERIALIZE, device->handle,
    176             IPC_FLAG_BLOCKING);
     179        async_sess_t *parent_sess = devman_parent_device_connect(
     180            EXCHANGE_SERIALIZE, ddf_dev_get_handle(device), IPC_FLAG_BLOCKING);
    177181        if (!parent_sess)
    178182                return ENOMEM;
     
    219223        }
    220224
    221 
    222225        if (hw_res.io_ranges.count == 1) {
    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;
     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;
    227230        } else {
    228231                const int sb =
    229232                    (hw_res.io_ranges.ranges[0].size >= sizeof(sb16_regs_t))
    230                         ? 1 : 0;
     233                        ? 0 : 1;
    231234                const int mpu = 1 - sb;
    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;
     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];
    240239        }
    241240
     
    245244int sb_enable_interrupts(ddf_dev_t *device)
    246245{
    247         async_sess_t *parent_sess =
    248             devman_parent_device_connect(EXCHANGE_SERIALIZE, device->handle,
    249             IPC_FLAG_BLOCKING);
     246        async_sess_t *parent_sess = devman_parent_device_connect(
     247            EXCHANGE_SERIALIZE, ddf_dev_get_handle(device), IPC_FLAG_BLOCKING);
    250248        if (!parent_sess)
    251249                return ENOMEM;
     
    256254        return enabled ? EOK : EIO;
    257255}
     256
    258257/**
    259258 * @}
Note: See TracChangeset for help on using the changeset viewer.