diff options
Diffstat (limited to 'sound/pci/ctxfi/ctdaio.c')
| -rw-r--r-- | sound/pci/ctxfi/ctdaio.c | 117 |
1 files changed, 43 insertions, 74 deletions
diff --git a/sound/pci/ctxfi/ctdaio.c b/sound/pci/ctxfi/ctdaio.c index 7fc720046ce2..1c8f8efd836c 100644 --- a/sound/pci/ctxfi/ctdaio.c +++ b/sound/pci/ctxfi/ctdaio.c @@ -18,8 +18,6 @@ #include <linux/slab.h> #include <linux/kernel.h> -#define DAIO_OUT_MAX SPDIFOO - struct daio_usage { unsigned short data; }; @@ -47,6 +45,7 @@ static const struct daio_rsc_idx idx_20k2[NUM_DAIOTYP] = { [LINEO4] = {.left = 0x70, .right = 0x71}, [LINEIM] = {.left = 0x45, .right = 0xc5}, [MIC] = {.left = 0x55, .right = 0xd5}, + [RCA] = {.left = 0x30, .right = 0x31}, [SPDIFOO] = {.left = 0x00, .right = 0x01}, [SPDIFIO] = {.left = 0x05, .right = 0x85}, }; @@ -125,6 +124,7 @@ static unsigned int daio_device_index(enum DAIOTYP type, struct hw *hw) case LINEO4: return 6; case LINEIM: return 4; case MIC: return 5; + case RCA: return 3; default: return -EINVAL; } default: @@ -159,7 +159,7 @@ static int dao_set_left_input(struct dao *dao, struct rsc *input) struct daio *daio = &dao->daio; int i; - entry = kzalloc((sizeof(*entry) * daio->rscl.msr), GFP_KERNEL); + entry = kcalloc(daio->rscl.msr, sizeof(*entry), GFP_KERNEL); if (!entry) return -ENOMEM; @@ -188,7 +188,7 @@ static int dao_set_right_input(struct dao *dao, struct rsc *input) struct daio *daio = &dao->daio; int i; - entry = kzalloc((sizeof(*entry) * daio->rscr.msr), GFP_KERNEL); + entry = kcalloc(daio->rscr.msr, sizeof(*entry), GFP_KERNEL); if (!entry) return -ENOMEM; @@ -211,52 +211,30 @@ static int dao_set_right_input(struct dao *dao, struct rsc *input) return 0; } -static int dao_clear_left_input(struct dao *dao) +static int dao_clear_input(struct dao *dao, unsigned int start, unsigned int end) { - struct imapper *entry; - struct daio *daio = &dao->daio; - int i; + unsigned int i; - if (!dao->imappers[0]) + if (!dao->imappers[start]) return 0; - - entry = dao->imappers[0]; - dao->mgr->imap_delete(dao->mgr, entry); - /* Program conjugate resources */ - for (i = 1; i < daio->rscl.msr; i++) { - entry = dao->imappers[i]; - dao->mgr->imap_delete(dao->mgr, entry); + for (i = start; i < end; i++) { + dao->mgr->imap_delete(dao->mgr, dao->imappers[i]); dao->imappers[i] = NULL; } - kfree(dao->imappers[0]); - dao->imappers[0] = NULL; - return 0; } -static int dao_clear_right_input(struct dao *dao) -{ - struct imapper *entry; - struct daio *daio = &dao->daio; - int i; - - if (!dao->imappers[daio->rscl.msr]) - return 0; - - entry = dao->imappers[daio->rscl.msr]; - dao->mgr->imap_delete(dao->mgr, entry); - /* Program conjugate resources */ - for (i = 1; i < daio->rscr.msr; i++) { - entry = dao->imappers[daio->rscl.msr + i]; - dao->mgr->imap_delete(dao->mgr, entry); - dao->imappers[daio->rscl.msr + i] = NULL; - } - kfree(dao->imappers[daio->rscl.msr]); - dao->imappers[daio->rscl.msr] = NULL; +static int dao_clear_left_input(struct dao *dao) +{ + return dao_clear_input(dao, 0, dao->daio.rscl.msr); +} - return 0; +static int dao_clear_right_input(struct dao *dao) +{ + return dao_clear_input(dao, dao->daio.rscl.msr, + dao->daio.rscl.msr + dao->daio.rscr.msr); } static const struct dao_rsc_ops dao_ops = { @@ -351,7 +329,7 @@ static int daio_rsc_init(struct daio *daio, goto error1; /* Set daio->rscl/r->ops to daio specific ones */ - if (desc->type <= DAIO_OUT_MAX) { + if (desc->output) { daio->rscl.ops = daio->rscr.ops = &daio_out_rsc_ops; } else { switch (hw->chip_type) { @@ -366,6 +344,7 @@ static int daio_rsc_init(struct daio *daio, } } daio->type = desc->type; + daio->output = desc->output; return 0; @@ -412,7 +391,7 @@ static int dao_rsc_init(struct dao *dao, hw->daio_mgr_commit_write(hw, mgr->mgr.ctrl_blk); conf = (desc->msr & 0x7) | (desc->passthru << 3); - hw->daio_mgr_dao_init(mgr->mgr.ctrl_blk, + hw->daio_mgr_dao_init(hw, mgr->mgr.ctrl_blk, daio_device_index(dao->daio.type, hw), conf); hw->daio_mgr_enb_dao(mgr->mgr.ctrl_blk, daio_device_index(dao->daio.type, hw)); @@ -455,6 +434,7 @@ static int dao_rsc_reinit(struct dao *dao, const struct dao_desc *desc) dsc.type = dao->daio.type; dsc.msr = desc->msr; dsc.passthru = desc->passthru; + dsc.output = dao->daio.output; dao_rsc_uninit(dao); return dao_rsc_init(dao, &dsc, mgr); } @@ -525,14 +505,13 @@ static int get_daio_rsc(struct daio_mgr *mgr, struct daio **rdaio) { int err; - unsigned long flags; *rdaio = NULL; /* Check whether there are sufficient daio resources to meet request. */ - spin_lock_irqsave(&mgr->mgr_lock, flags); - err = daio_mgr_get_rsc(&mgr->mgr, desc->type); - spin_unlock_irqrestore(&mgr->mgr_lock, flags); + scoped_guard(spinlock_irqsave, &mgr->mgr_lock) { + err = daio_mgr_get_rsc(&mgr->mgr, desc->type); + } if (err) { dev_err(mgr->card->dev, "Can't meet DAIO resource request!\n"); @@ -541,7 +520,7 @@ static int get_daio_rsc(struct daio_mgr *mgr, err = -ENOMEM; /* Allocate mem for daio resource */ - if (desc->type <= DAIO_OUT_MAX) { + if (desc->output) { struct dao *dao = kzalloc(sizeof(*dao), GFP_KERNEL); if (!dao) goto error; @@ -573,24 +552,22 @@ static int get_daio_rsc(struct daio_mgr *mgr, return 0; error: - spin_lock_irqsave(&mgr->mgr_lock, flags); - daio_mgr_put_rsc(&mgr->mgr, desc->type); - spin_unlock_irqrestore(&mgr->mgr_lock, flags); + scoped_guard(spinlock_irqsave, &mgr->mgr_lock) { + daio_mgr_put_rsc(&mgr->mgr, desc->type); + } return err; } static int put_daio_rsc(struct daio_mgr *mgr, struct daio *daio) { - unsigned long flags; - mgr->daio_disable(mgr, daio); mgr->commit_write(mgr); - spin_lock_irqsave(&mgr->mgr_lock, flags); - daio_mgr_put_rsc(&mgr->mgr, daio->type); - spin_unlock_irqrestore(&mgr->mgr_lock, flags); + scoped_guard(spinlock_irqsave, &mgr->mgr_lock) { + daio_mgr_put_rsc(&mgr->mgr, daio->type); + } - if (daio->type <= DAIO_OUT_MAX) { + if (daio->output) { dao_rsc_uninit(container_of(daio, struct dao, daio)); kfree(container_of(daio, struct dao, daio)); } else { @@ -605,7 +582,7 @@ static int daio_mgr_enb_daio(struct daio_mgr *mgr, struct daio *daio) { struct hw *hw = mgr->mgr.hw; - if (DAIO_OUT_MAX >= daio->type) { + if (daio->output) { hw->daio_mgr_enb_dao(mgr->mgr.ctrl_blk, daio_device_index(daio->type, hw)); } else { @@ -619,7 +596,7 @@ static int daio_mgr_dsb_daio(struct daio_mgr *mgr, struct daio *daio) { struct hw *hw = mgr->mgr.hw; - if (DAIO_OUT_MAX >= daio->type) { + if (daio->output) { hw->daio_mgr_dsb_dao(mgr->mgr.ctrl_blk, daio_device_index(daio->type, hw)); } else { @@ -644,34 +621,26 @@ static int daio_map_op(void *data, struct imapper *entry) static int daio_imap_add(struct daio_mgr *mgr, struct imapper *entry) { - unsigned long flags; - int err; - - spin_lock_irqsave(&mgr->imap_lock, flags); + guard(spinlock_irqsave)(&mgr->imap_lock); if (!entry->addr && mgr->init_imap_added) { input_mapper_delete(&mgr->imappers, mgr->init_imap, daio_map_op, mgr); mgr->init_imap_added = 0; } - err = input_mapper_add(&mgr->imappers, entry, daio_map_op, mgr); - spin_unlock_irqrestore(&mgr->imap_lock, flags); - - return err; + return input_mapper_add(&mgr->imappers, entry, daio_map_op, mgr); } static int daio_imap_delete(struct daio_mgr *mgr, struct imapper *entry) { - unsigned long flags; int err; - spin_lock_irqsave(&mgr->imap_lock, flags); + guard(spinlock_irqsave)(&mgr->imap_lock); err = input_mapper_delete(&mgr->imappers, entry, daio_map_op, mgr); if (list_empty(&mgr->imappers)) { input_mapper_add(&mgr->imappers, mgr->init_imap, daio_map_op, mgr); mgr->init_imap_added = 1; } - spin_unlock_irqrestore(&mgr->imap_lock, flags); return err; } @@ -684,7 +653,7 @@ static int daio_mgr_commit_write(struct daio_mgr *mgr) return 0; } -int daio_mgr_create(struct hw *hw, struct daio_mgr **rdaio_mgr) +int daio_mgr_create(struct hw *hw, void **rdaio_mgr) { int err, i; struct daio_mgr *daio_mgr; @@ -738,14 +707,14 @@ error1: return err; } -int daio_mgr_destroy(struct daio_mgr *daio_mgr) +int daio_mgr_destroy(void *ptr) { - unsigned long flags; + struct daio_mgr *daio_mgr = ptr; /* free daio input mapper list */ - spin_lock_irqsave(&daio_mgr->imap_lock, flags); - free_input_mapper_list(&daio_mgr->imappers); - spin_unlock_irqrestore(&daio_mgr->imap_lock, flags); + scoped_guard(spinlock_irqsave, &daio_mgr->imap_lock) { + free_input_mapper_list(&daio_mgr->imappers); + } rsc_mgr_uninit(&daio_mgr->mgr); kfree(daio_mgr); |
