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