root/sound/pci/ctxfi/ctdaio.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. daio_master
  2. daio_index
  3. daio_out_next_conj
  4. daio_in_next_conj_20k1
  5. daio_in_next_conj_20k2
  6. daio_device_index
  7. dao_spdif_get_spos
  8. dao_spdif_set_spos
  9. dao_commit_write
  10. dao_set_left_input
  11. dao_set_right_input
  12. dao_clear_left_input
  13. dao_clear_right_input
  14. dai_set_srt_srcl
  15. dai_set_srt_srcr
  16. dai_set_srt_msr
  17. dai_set_enb_src
  18. dai_set_enb_srt
  19. dai_commit_write
  20. daio_rsc_init
  21. daio_rsc_uninit
  22. dao_rsc_init
  23. dao_rsc_uninit
  24. dao_rsc_reinit
  25. dai_rsc_init
  26. dai_rsc_uninit
  27. daio_mgr_get_rsc
  28. daio_mgr_put_rsc
  29. get_daio_rsc
  30. put_daio_rsc
  31. daio_mgr_enb_daio
  32. daio_mgr_dsb_daio
  33. daio_map_op
  34. daio_imap_add
  35. daio_imap_delete
  36. daio_mgr_commit_write
  37. daio_mgr_create
  38. daio_mgr_destroy

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /**
   3  * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
   4  *
   5  * @File        ctdaio.c
   6  *
   7  * @Brief
   8  * This file contains the implementation of Digital Audio Input Output
   9  * resource management object.
  10  *
  11  * @Author      Liu Chun
  12  * @Date        May 23 2008
  13  */
  14 
  15 #include "ctdaio.h"
  16 #include "cthardware.h"
  17 #include "ctimap.h"
  18 #include <linux/slab.h>
  19 #include <linux/kernel.h>
  20 
  21 #define DAIO_OUT_MAX            SPDIFOO
  22 
  23 struct daio_usage {
  24         unsigned short data;
  25 };
  26 
  27 struct daio_rsc_idx {
  28         unsigned short left;
  29         unsigned short right;
  30 };
  31 
  32 static struct daio_rsc_idx idx_20k1[NUM_DAIOTYP] = {
  33         [LINEO1] = {.left = 0x00, .right = 0x01},
  34         [LINEO2] = {.left = 0x18, .right = 0x19},
  35         [LINEO3] = {.left = 0x08, .right = 0x09},
  36         [LINEO4] = {.left = 0x10, .right = 0x11},
  37         [LINEIM] = {.left = 0x1b5, .right = 0x1bd},
  38         [SPDIFOO] = {.left = 0x20, .right = 0x21},
  39         [SPDIFIO] = {.left = 0x15, .right = 0x1d},
  40         [SPDIFI1] = {.left = 0x95, .right = 0x9d},
  41 };
  42 
  43 static struct daio_rsc_idx idx_20k2[NUM_DAIOTYP] = {
  44         [LINEO1] = {.left = 0x40, .right = 0x41},
  45         [LINEO2] = {.left = 0x60, .right = 0x61},
  46         [LINEO3] = {.left = 0x50, .right = 0x51},
  47         [LINEO4] = {.left = 0x70, .right = 0x71},
  48         [LINEIM] = {.left = 0x45, .right = 0xc5},
  49         [MIC]    = {.left = 0x55, .right = 0xd5},
  50         [SPDIFOO] = {.left = 0x00, .right = 0x01},
  51         [SPDIFIO] = {.left = 0x05, .right = 0x85},
  52 };
  53 
  54 static int daio_master(struct rsc *rsc)
  55 {
  56         /* Actually, this is not the resource index of DAIO.
  57          * For DAO, it is the input mapper index. And, for DAI,
  58          * it is the output time-slot index. */
  59         return rsc->conj = rsc->idx;
  60 }
  61 
  62 static int daio_index(const struct rsc *rsc)
  63 {
  64         return rsc->conj;
  65 }
  66 
  67 static int daio_out_next_conj(struct rsc *rsc)
  68 {
  69         return rsc->conj += 2;
  70 }
  71 
  72 static int daio_in_next_conj_20k1(struct rsc *rsc)
  73 {
  74         return rsc->conj += 0x200;
  75 }
  76 
  77 static int daio_in_next_conj_20k2(struct rsc *rsc)
  78 {
  79         return rsc->conj += 0x100;
  80 }
  81 
  82 static const struct rsc_ops daio_out_rsc_ops = {
  83         .master         = daio_master,
  84         .next_conj      = daio_out_next_conj,
  85         .index          = daio_index,
  86         .output_slot    = NULL,
  87 };
  88 
  89 static const struct rsc_ops daio_in_rsc_ops_20k1 = {
  90         .master         = daio_master,
  91         .next_conj      = daio_in_next_conj_20k1,
  92         .index          = NULL,
  93         .output_slot    = daio_index,
  94 };
  95 
  96 static const struct rsc_ops daio_in_rsc_ops_20k2 = {
  97         .master         = daio_master,
  98         .next_conj      = daio_in_next_conj_20k2,
  99         .index          = NULL,
 100         .output_slot    = daio_index,
 101 };
 102 
 103 static unsigned int daio_device_index(enum DAIOTYP type, struct hw *hw)
 104 {
 105         switch (hw->chip_type) {
 106         case ATC20K1:
 107                 switch (type) {
 108                 case SPDIFOO:   return 0;
 109                 case SPDIFIO:   return 0;
 110                 case SPDIFI1:   return 1;
 111                 case LINEO1:    return 4;
 112                 case LINEO2:    return 7;
 113                 case LINEO3:    return 5;
 114                 case LINEO4:    return 6;
 115                 case LINEIM:    return 7;
 116                 default:        return -EINVAL;
 117                 }
 118         case ATC20K2:
 119                 switch (type) {
 120                 case SPDIFOO:   return 0;
 121                 case SPDIFIO:   return 0;
 122                 case LINEO1:    return 4;
 123                 case LINEO2:    return 7;
 124                 case LINEO3:    return 5;
 125                 case LINEO4:    return 6;
 126                 case LINEIM:    return 4;
 127                 case MIC:       return 5;
 128                 default:        return -EINVAL;
 129                 }
 130         default:
 131                 return -EINVAL;
 132         }
 133 }
 134 
 135 static int dao_rsc_reinit(struct dao *dao, const struct dao_desc *desc);
 136 
 137 static int dao_spdif_get_spos(struct dao *dao, unsigned int *spos)
 138 {
 139         dao->hw->dao_get_spos(dao->ctrl_blk, spos);
 140         return 0;
 141 }
 142 
 143 static int dao_spdif_set_spos(struct dao *dao, unsigned int spos)
 144 {
 145         dao->hw->dao_set_spos(dao->ctrl_blk, spos);
 146         return 0;
 147 }
 148 
 149 static int dao_commit_write(struct dao *dao)
 150 {
 151         dao->hw->dao_commit_write(dao->hw,
 152                 daio_device_index(dao->daio.type, dao->hw), dao->ctrl_blk);
 153         return 0;
 154 }
 155 
 156 static int dao_set_left_input(struct dao *dao, struct rsc *input)
 157 {
 158         struct imapper *entry;
 159         struct daio *daio = &dao->daio;
 160         int i;
 161 
 162         entry = kzalloc((sizeof(*entry) * daio->rscl.msr), GFP_KERNEL);
 163         if (!entry)
 164                 return -ENOMEM;
 165 
 166         dao->ops->clear_left_input(dao);
 167         /* Program master and conjugate resources */
 168         input->ops->master(input);
 169         daio->rscl.ops->master(&daio->rscl);
 170         for (i = 0; i < daio->rscl.msr; i++, entry++) {
 171                 entry->slot = input->ops->output_slot(input);
 172                 entry->user = entry->addr = daio->rscl.ops->index(&daio->rscl);
 173                 dao->mgr->imap_add(dao->mgr, entry);
 174                 dao->imappers[i] = entry;
 175 
 176                 input->ops->next_conj(input);
 177                 daio->rscl.ops->next_conj(&daio->rscl);
 178         }
 179         input->ops->master(input);
 180         daio->rscl.ops->master(&daio->rscl);
 181 
 182         return 0;
 183 }
 184 
 185 static int dao_set_right_input(struct dao *dao, struct rsc *input)
 186 {
 187         struct imapper *entry;
 188         struct daio *daio = &dao->daio;
 189         int i;
 190 
 191         entry = kzalloc((sizeof(*entry) * daio->rscr.msr), GFP_KERNEL);
 192         if (!entry)
 193                 return -ENOMEM;
 194 
 195         dao->ops->clear_right_input(dao);
 196         /* Program master and conjugate resources */
 197         input->ops->master(input);
 198         daio->rscr.ops->master(&daio->rscr);
 199         for (i = 0; i < daio->rscr.msr; i++, entry++) {
 200                 entry->slot = input->ops->output_slot(input);
 201                 entry->user = entry->addr = daio->rscr.ops->index(&daio->rscr);
 202                 dao->mgr->imap_add(dao->mgr, entry);
 203                 dao->imappers[daio->rscl.msr + i] = entry;
 204 
 205                 input->ops->next_conj(input);
 206                 daio->rscr.ops->next_conj(&daio->rscr);
 207         }
 208         input->ops->master(input);
 209         daio->rscr.ops->master(&daio->rscr);
 210 
 211         return 0;
 212 }
 213 
 214 static int dao_clear_left_input(struct dao *dao)
 215 {
 216         struct imapper *entry;
 217         struct daio *daio = &dao->daio;
 218         int i;
 219 
 220         if (!dao->imappers[0])
 221                 return 0;
 222 
 223         entry = dao->imappers[0];
 224         dao->mgr->imap_delete(dao->mgr, entry);
 225         /* Program conjugate resources */
 226         for (i = 1; i < daio->rscl.msr; i++) {
 227                 entry = dao->imappers[i];
 228                 dao->mgr->imap_delete(dao->mgr, entry);
 229                 dao->imappers[i] = NULL;
 230         }
 231 
 232         kfree(dao->imappers[0]);
 233         dao->imappers[0] = NULL;
 234 
 235         return 0;
 236 }
 237 
 238 static int dao_clear_right_input(struct dao *dao)
 239 {
 240         struct imapper *entry;
 241         struct daio *daio = &dao->daio;
 242         int i;
 243 
 244         if (!dao->imappers[daio->rscl.msr])
 245                 return 0;
 246 
 247         entry = dao->imappers[daio->rscl.msr];
 248         dao->mgr->imap_delete(dao->mgr, entry);
 249         /* Program conjugate resources */
 250         for (i = 1; i < daio->rscr.msr; i++) {
 251                 entry = dao->imappers[daio->rscl.msr + i];
 252                 dao->mgr->imap_delete(dao->mgr, entry);
 253                 dao->imappers[daio->rscl.msr + i] = NULL;
 254         }
 255 
 256         kfree(dao->imappers[daio->rscl.msr]);
 257         dao->imappers[daio->rscl.msr] = NULL;
 258 
 259         return 0;
 260 }
 261 
 262 static const struct dao_rsc_ops dao_ops = {
 263         .set_spos               = dao_spdif_set_spos,
 264         .commit_write           = dao_commit_write,
 265         .get_spos               = dao_spdif_get_spos,
 266         .reinit                 = dao_rsc_reinit,
 267         .set_left_input         = dao_set_left_input,
 268         .set_right_input        = dao_set_right_input,
 269         .clear_left_input       = dao_clear_left_input,
 270         .clear_right_input      = dao_clear_right_input,
 271 };
 272 
 273 static int dai_set_srt_srcl(struct dai *dai, struct rsc *src)
 274 {
 275         src->ops->master(src);
 276         dai->hw->dai_srt_set_srcm(dai->ctrl_blk, src->ops->index(src));
 277         return 0;
 278 }
 279 
 280 static int dai_set_srt_srcr(struct dai *dai, struct rsc *src)
 281 {
 282         src->ops->master(src);
 283         dai->hw->dai_srt_set_srco(dai->ctrl_blk, src->ops->index(src));
 284         return 0;
 285 }
 286 
 287 static int dai_set_srt_msr(struct dai *dai, unsigned int msr)
 288 {
 289         unsigned int rsr;
 290 
 291         for (rsr = 0; msr > 1; msr >>= 1)
 292                 rsr++;
 293 
 294         dai->hw->dai_srt_set_rsr(dai->ctrl_blk, rsr);
 295         return 0;
 296 }
 297 
 298 static int dai_set_enb_src(struct dai *dai, unsigned int enb)
 299 {
 300         dai->hw->dai_srt_set_ec(dai->ctrl_blk, enb);
 301         return 0;
 302 }
 303 
 304 static int dai_set_enb_srt(struct dai *dai, unsigned int enb)
 305 {
 306         dai->hw->dai_srt_set_et(dai->ctrl_blk, enb);
 307         return 0;
 308 }
 309 
 310 static int dai_commit_write(struct dai *dai)
 311 {
 312         dai->hw->dai_commit_write(dai->hw,
 313                 daio_device_index(dai->daio.type, dai->hw), dai->ctrl_blk);
 314         return 0;
 315 }
 316 
 317 static const struct dai_rsc_ops dai_ops = {
 318         .set_srt_srcl           = dai_set_srt_srcl,
 319         .set_srt_srcr           = dai_set_srt_srcr,
 320         .set_srt_msr            = dai_set_srt_msr,
 321         .set_enb_src            = dai_set_enb_src,
 322         .set_enb_srt            = dai_set_enb_srt,
 323         .commit_write           = dai_commit_write,
 324 };
 325 
 326 static int daio_rsc_init(struct daio *daio,
 327                          const struct daio_desc *desc,
 328                          struct hw *hw)
 329 {
 330         int err;
 331         unsigned int idx_l, idx_r;
 332 
 333         switch (hw->chip_type) {
 334         case ATC20K1:
 335                 idx_l = idx_20k1[desc->type].left;
 336                 idx_r = idx_20k1[desc->type].right;
 337                 break;
 338         case ATC20K2:
 339                 idx_l = idx_20k2[desc->type].left;
 340                 idx_r = idx_20k2[desc->type].right;
 341                 break;
 342         default:
 343                 return -EINVAL;
 344         }
 345         err = rsc_init(&daio->rscl, idx_l, DAIO, desc->msr, hw);
 346         if (err)
 347                 return err;
 348 
 349         err = rsc_init(&daio->rscr, idx_r, DAIO, desc->msr, hw);
 350         if (err)
 351                 goto error1;
 352 
 353         /* Set daio->rscl/r->ops to daio specific ones */
 354         if (desc->type <= DAIO_OUT_MAX) {
 355                 daio->rscl.ops = daio->rscr.ops = &daio_out_rsc_ops;
 356         } else {
 357                 switch (hw->chip_type) {
 358                 case ATC20K1:
 359                         daio->rscl.ops = daio->rscr.ops = &daio_in_rsc_ops_20k1;
 360                         break;
 361                 case ATC20K2:
 362                         daio->rscl.ops = daio->rscr.ops = &daio_in_rsc_ops_20k2;
 363                         break;
 364                 default:
 365                         break;
 366                 }
 367         }
 368         daio->type = desc->type;
 369 
 370         return 0;
 371 
 372 error1:
 373         rsc_uninit(&daio->rscl);
 374         return err;
 375 }
 376 
 377 static int daio_rsc_uninit(struct daio *daio)
 378 {
 379         rsc_uninit(&daio->rscl);
 380         rsc_uninit(&daio->rscr);
 381 
 382         return 0;
 383 }
 384 
 385 static int dao_rsc_init(struct dao *dao,
 386                         const struct daio_desc *desc,
 387                         struct daio_mgr *mgr)
 388 {
 389         struct hw *hw = mgr->mgr.hw;
 390         unsigned int conf;
 391         int err;
 392 
 393         err = daio_rsc_init(&dao->daio, desc, mgr->mgr.hw);
 394         if (err)
 395                 return err;
 396 
 397         dao->imappers = kzalloc(array3_size(sizeof(void *), desc->msr, 2),
 398                                 GFP_KERNEL);
 399         if (!dao->imappers) {
 400                 err = -ENOMEM;
 401                 goto error1;
 402         }
 403         dao->ops = &dao_ops;
 404         dao->mgr = mgr;
 405         dao->hw = hw;
 406         err = hw->dao_get_ctrl_blk(&dao->ctrl_blk);
 407         if (err)
 408                 goto error2;
 409 
 410         hw->daio_mgr_dsb_dao(mgr->mgr.ctrl_blk,
 411                         daio_device_index(dao->daio.type, hw));
 412         hw->daio_mgr_commit_write(hw, mgr->mgr.ctrl_blk);
 413 
 414         conf = (desc->msr & 0x7) | (desc->passthru << 3);
 415         hw->daio_mgr_dao_init(mgr->mgr.ctrl_blk,
 416                         daio_device_index(dao->daio.type, hw), conf);
 417         hw->daio_mgr_enb_dao(mgr->mgr.ctrl_blk,
 418                         daio_device_index(dao->daio.type, hw));
 419         hw->daio_mgr_commit_write(hw, mgr->mgr.ctrl_blk);
 420 
 421         return 0;
 422 
 423 error2:
 424         kfree(dao->imappers);
 425         dao->imappers = NULL;
 426 error1:
 427         daio_rsc_uninit(&dao->daio);
 428         return err;
 429 }
 430 
 431 static int dao_rsc_uninit(struct dao *dao)
 432 {
 433         if (dao->imappers) {
 434                 if (dao->imappers[0])
 435                         dao_clear_left_input(dao);
 436 
 437                 if (dao->imappers[dao->daio.rscl.msr])
 438                         dao_clear_right_input(dao);
 439 
 440                 kfree(dao->imappers);
 441                 dao->imappers = NULL;
 442         }
 443         dao->hw->dao_put_ctrl_blk(dao->ctrl_blk);
 444         dao->hw = dao->ctrl_blk = NULL;
 445         daio_rsc_uninit(&dao->daio);
 446 
 447         return 0;
 448 }
 449 
 450 static int dao_rsc_reinit(struct dao *dao, const struct dao_desc *desc)
 451 {
 452         struct daio_mgr *mgr = dao->mgr;
 453         struct daio_desc dsc = {0};
 454 
 455         dsc.type = dao->daio.type;
 456         dsc.msr = desc->msr;
 457         dsc.passthru = desc->passthru;
 458         dao_rsc_uninit(dao);
 459         return dao_rsc_init(dao, &dsc, mgr);
 460 }
 461 
 462 static int dai_rsc_init(struct dai *dai,
 463                         const struct daio_desc *desc,
 464                         struct daio_mgr *mgr)
 465 {
 466         int err;
 467         struct hw *hw = mgr->mgr.hw;
 468         unsigned int rsr, msr;
 469 
 470         err = daio_rsc_init(&dai->daio, desc, mgr->mgr.hw);
 471         if (err)
 472                 return err;
 473 
 474         dai->ops = &dai_ops;
 475         dai->hw = mgr->mgr.hw;
 476         err = hw->dai_get_ctrl_blk(&dai->ctrl_blk);
 477         if (err)
 478                 goto error1;
 479 
 480         for (rsr = 0, msr = desc->msr; msr > 1; msr >>= 1)
 481                 rsr++;
 482 
 483         hw->dai_srt_set_rsr(dai->ctrl_blk, rsr);
 484         hw->dai_srt_set_drat(dai->ctrl_blk, 0);
 485         /* default to disabling control of a SRC */
 486         hw->dai_srt_set_ec(dai->ctrl_blk, 0);
 487         hw->dai_srt_set_et(dai->ctrl_blk, 0); /* default to disabling SRT */
 488         hw->dai_commit_write(hw,
 489                 daio_device_index(dai->daio.type, dai->hw), dai->ctrl_blk);
 490 
 491         return 0;
 492 
 493 error1:
 494         daio_rsc_uninit(&dai->daio);
 495         return err;
 496 }
 497 
 498 static int dai_rsc_uninit(struct dai *dai)
 499 {
 500         dai->hw->dai_put_ctrl_blk(dai->ctrl_blk);
 501         dai->hw = dai->ctrl_blk = NULL;
 502         daio_rsc_uninit(&dai->daio);
 503         return 0;
 504 }
 505 
 506 static int daio_mgr_get_rsc(struct rsc_mgr *mgr, enum DAIOTYP type)
 507 {
 508         if (((struct daio_usage *)mgr->rscs)->data & (0x1 << type))
 509                 return -ENOENT;
 510 
 511         ((struct daio_usage *)mgr->rscs)->data |= (0x1 << type);
 512 
 513         return 0;
 514 }
 515 
 516 static int daio_mgr_put_rsc(struct rsc_mgr *mgr, enum DAIOTYP type)
 517 {
 518         ((struct daio_usage *)mgr->rscs)->data &= ~(0x1 << type);
 519 
 520         return 0;
 521 }
 522 
 523 static int get_daio_rsc(struct daio_mgr *mgr,
 524                         const struct daio_desc *desc,
 525                         struct daio **rdaio)
 526 {
 527         int err;
 528         unsigned long flags;
 529 
 530         *rdaio = NULL;
 531 
 532         /* Check whether there are sufficient daio resources to meet request. */
 533         spin_lock_irqsave(&mgr->mgr_lock, flags);
 534         err = daio_mgr_get_rsc(&mgr->mgr, desc->type);
 535         spin_unlock_irqrestore(&mgr->mgr_lock, flags);
 536         if (err) {
 537                 dev_err(mgr->card->dev,
 538                         "Can't meet DAIO resource request!\n");
 539                 return err;
 540         }
 541 
 542         err = -ENOMEM;
 543         /* Allocate mem for daio resource */
 544         if (desc->type <= DAIO_OUT_MAX) {
 545                 struct dao *dao = kzalloc(sizeof(*dao), GFP_KERNEL);
 546                 if (!dao)
 547                         goto error;
 548 
 549                 err = dao_rsc_init(dao, desc, mgr);
 550                 if (err) {
 551                         kfree(dao);
 552                         goto error;
 553                 }
 554 
 555                 *rdaio = &dao->daio;
 556         } else {
 557                 struct dai *dai = kzalloc(sizeof(*dai), GFP_KERNEL);
 558                 if (!dai)
 559                         goto error;
 560 
 561                 err = dai_rsc_init(dai, desc, mgr);
 562                 if (err) {
 563                         kfree(dai);
 564                         goto error;
 565                 }
 566 
 567                 *rdaio = &dai->daio;
 568         }
 569 
 570         mgr->daio_enable(mgr, *rdaio);
 571         mgr->commit_write(mgr);
 572 
 573         return 0;
 574 
 575 error:
 576         spin_lock_irqsave(&mgr->mgr_lock, flags);
 577         daio_mgr_put_rsc(&mgr->mgr, desc->type);
 578         spin_unlock_irqrestore(&mgr->mgr_lock, flags);
 579         return err;
 580 }
 581 
 582 static int put_daio_rsc(struct daio_mgr *mgr, struct daio *daio)
 583 {
 584         unsigned long flags;
 585 
 586         mgr->daio_disable(mgr, daio);
 587         mgr->commit_write(mgr);
 588 
 589         spin_lock_irqsave(&mgr->mgr_lock, flags);
 590         daio_mgr_put_rsc(&mgr->mgr, daio->type);
 591         spin_unlock_irqrestore(&mgr->mgr_lock, flags);
 592 
 593         if (daio->type <= DAIO_OUT_MAX) {
 594                 dao_rsc_uninit(container_of(daio, struct dao, daio));
 595                 kfree(container_of(daio, struct dao, daio));
 596         } else {
 597                 dai_rsc_uninit(container_of(daio, struct dai, daio));
 598                 kfree(container_of(daio, struct dai, daio));
 599         }
 600 
 601         return 0;
 602 }
 603 
 604 static int daio_mgr_enb_daio(struct daio_mgr *mgr, struct daio *daio)
 605 {
 606         struct hw *hw = mgr->mgr.hw;
 607 
 608         if (DAIO_OUT_MAX >= daio->type) {
 609                 hw->daio_mgr_enb_dao(mgr->mgr.ctrl_blk,
 610                                 daio_device_index(daio->type, hw));
 611         } else {
 612                 hw->daio_mgr_enb_dai(mgr->mgr.ctrl_blk,
 613                                 daio_device_index(daio->type, hw));
 614         }
 615         return 0;
 616 }
 617 
 618 static int daio_mgr_dsb_daio(struct daio_mgr *mgr, struct daio *daio)
 619 {
 620         struct hw *hw = mgr->mgr.hw;
 621 
 622         if (DAIO_OUT_MAX >= daio->type) {
 623                 hw->daio_mgr_dsb_dao(mgr->mgr.ctrl_blk,
 624                                 daio_device_index(daio->type, hw));
 625         } else {
 626                 hw->daio_mgr_dsb_dai(mgr->mgr.ctrl_blk,
 627                                 daio_device_index(daio->type, hw));
 628         }
 629         return 0;
 630 }
 631 
 632 static int daio_map_op(void *data, struct imapper *entry)
 633 {
 634         struct rsc_mgr *mgr = &((struct daio_mgr *)data)->mgr;
 635         struct hw *hw = mgr->hw;
 636 
 637         hw->daio_mgr_set_imaparc(mgr->ctrl_blk, entry->slot);
 638         hw->daio_mgr_set_imapnxt(mgr->ctrl_blk, entry->next);
 639         hw->daio_mgr_set_imapaddr(mgr->ctrl_blk, entry->addr);
 640         hw->daio_mgr_commit_write(mgr->hw, mgr->ctrl_blk);
 641 
 642         return 0;
 643 }
 644 
 645 static int daio_imap_add(struct daio_mgr *mgr, struct imapper *entry)
 646 {
 647         unsigned long flags;
 648         int err;
 649 
 650         spin_lock_irqsave(&mgr->imap_lock, flags);
 651         if (!entry->addr && mgr->init_imap_added) {
 652                 input_mapper_delete(&mgr->imappers, mgr->init_imap,
 653                                                         daio_map_op, mgr);
 654                 mgr->init_imap_added = 0;
 655         }
 656         err = input_mapper_add(&mgr->imappers, entry, daio_map_op, mgr);
 657         spin_unlock_irqrestore(&mgr->imap_lock, flags);
 658 
 659         return err;
 660 }
 661 
 662 static int daio_imap_delete(struct daio_mgr *mgr, struct imapper *entry)
 663 {
 664         unsigned long flags;
 665         int err;
 666 
 667         spin_lock_irqsave(&mgr->imap_lock, flags);
 668         err = input_mapper_delete(&mgr->imappers, entry, daio_map_op, mgr);
 669         if (list_empty(&mgr->imappers)) {
 670                 input_mapper_add(&mgr->imappers, mgr->init_imap,
 671                                                         daio_map_op, mgr);
 672                 mgr->init_imap_added = 1;
 673         }
 674         spin_unlock_irqrestore(&mgr->imap_lock, flags);
 675 
 676         return err;
 677 }
 678 
 679 static int daio_mgr_commit_write(struct daio_mgr *mgr)
 680 {
 681         struct hw *hw = mgr->mgr.hw;
 682 
 683         hw->daio_mgr_commit_write(hw, mgr->mgr.ctrl_blk);
 684         return 0;
 685 }
 686 
 687 int daio_mgr_create(struct hw *hw, struct daio_mgr **rdaio_mgr)
 688 {
 689         int err, i;
 690         struct daio_mgr *daio_mgr;
 691         struct imapper *entry;
 692 
 693         *rdaio_mgr = NULL;
 694         daio_mgr = kzalloc(sizeof(*daio_mgr), GFP_KERNEL);
 695         if (!daio_mgr)
 696                 return -ENOMEM;
 697 
 698         err = rsc_mgr_init(&daio_mgr->mgr, DAIO, NUM_DAIOTYP, hw);
 699         if (err)
 700                 goto error1;
 701 
 702         spin_lock_init(&daio_mgr->mgr_lock);
 703         spin_lock_init(&daio_mgr->imap_lock);
 704         INIT_LIST_HEAD(&daio_mgr->imappers);
 705         entry = kzalloc(sizeof(*entry), GFP_KERNEL);
 706         if (!entry) {
 707                 err = -ENOMEM;
 708                 goto error2;
 709         }
 710         entry->slot = entry->addr = entry->next = entry->user = 0;
 711         list_add(&entry->list, &daio_mgr->imappers);
 712         daio_mgr->init_imap = entry;
 713         daio_mgr->init_imap_added = 1;
 714 
 715         daio_mgr->get_daio = get_daio_rsc;
 716         daio_mgr->put_daio = put_daio_rsc;
 717         daio_mgr->daio_enable = daio_mgr_enb_daio;
 718         daio_mgr->daio_disable = daio_mgr_dsb_daio;
 719         daio_mgr->imap_add = daio_imap_add;
 720         daio_mgr->imap_delete = daio_imap_delete;
 721         daio_mgr->commit_write = daio_mgr_commit_write;
 722         daio_mgr->card = hw->card;
 723 
 724         for (i = 0; i < 8; i++) {
 725                 hw->daio_mgr_dsb_dao(daio_mgr->mgr.ctrl_blk, i);
 726                 hw->daio_mgr_dsb_dai(daio_mgr->mgr.ctrl_blk, i);
 727         }
 728         hw->daio_mgr_commit_write(hw, daio_mgr->mgr.ctrl_blk);
 729 
 730         *rdaio_mgr = daio_mgr;
 731 
 732         return 0;
 733 
 734 error2:
 735         rsc_mgr_uninit(&daio_mgr->mgr);
 736 error1:
 737         kfree(daio_mgr);
 738         return err;
 739 }
 740 
 741 int daio_mgr_destroy(struct daio_mgr *daio_mgr)
 742 {
 743         unsigned long flags;
 744 
 745         /* free daio input mapper list */
 746         spin_lock_irqsave(&daio_mgr->imap_lock, flags);
 747         free_input_mapper_list(&daio_mgr->imappers);
 748         spin_unlock_irqrestore(&daio_mgr->imap_lock, flags);
 749 
 750         rsc_mgr_uninit(&daio_mgr->mgr);
 751         kfree(daio_mgr);
 752 
 753         return 0;
 754 }
 755 

/* [<][>][^][v][top][bottom][index][help] */