// Copyright 2018 The Fuchsia Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include #include #include #include #include #include #include #include #include #include "sdmmc.h" #include "sdio.h" zx_status_t sdio_enable_interrupt(void *ctx, uint8_t fn_idx) { zx_status_t st = ZX_OK; sdmmc_device_t *dev = ctx; if (!sdio_fn_idx_valid(fn_idx)) { return ZX_ERR_INVALID_ARGS; } sdio_function_t *func = &(dev->sdio_dev.funcs[fn_idx]); if (func->intr_enabled) { return ZX_OK; } uint8_t intr_byte; st = sdio_io_rw_direct(dev, false, 0, SDIO_CIA_CCCR_IEN_INTR_EN_ADDR, 0, &intr_byte); if (st != ZX_OK) { zxlogf(ERROR, "sdio_enable_interrupt: Failed to enable interrupt for fn: %d status: %d\n", fn_idx, st); return st; } // Enable fn intr intr_byte |= 1 << fn_idx; // Enable master intr intr_byte |= 1; st = sdio_io_rw_direct(dev, true, 0, SDIO_CIA_CCCR_IEN_INTR_EN_ADDR, intr_byte, NULL); if (st != ZX_OK) { zxlogf(ERROR, "sdio_enable_interrupt: Failed to enable interrupt for fn: %d status: %d\n", fn_idx, st); return st; } func->intr_enabled = true; zxlogf(TRACE, "sdio_enable_interrupt: Interrupt enabled for fn %d\n", fn_idx); return ZX_OK; } zx_status_t sdio_disable_interrupt(void *ctx, uint8_t fn_idx) { zx_status_t st = ZX_OK; sdmmc_device_t *dev = ctx; if (!sdio_fn_idx_valid(fn_idx)) { return ZX_ERR_INVALID_ARGS; } sdio_function_t *func = &(dev->sdio_dev.funcs[fn_idx]); if (!(func->intr_enabled)) { zxlogf(ERROR, "sdio_disable_interrupt: Interrupt is not enabled for %d\n", fn_idx); return ZX_ERR_BAD_STATE; } uint8_t intr_byte; st = sdio_io_rw_direct(dev, false, 0, SDIO_CIA_CCCR_IEN_INTR_EN_ADDR, 0, &intr_byte); if (st != ZX_OK) { zxlogf(ERROR, "sdio_disable_interrupt: Failed reading intr enable reg." " func: %d status: %d\n", fn_idx, st); return st; } intr_byte &= ~(1 << fn_idx); if (!(intr_byte & SDIO_ALL_INTR_ENABLED_MASK)) { //disable master as well intr_byte = 0; } st = sdio_io_rw_direct(dev, true, 0, SDIO_CIA_CCCR_IEN_INTR_EN_ADDR, intr_byte, NULL); if (st != ZX_OK) { zxlogf(ERROR, "sdio_disable_interrupt: Error writing to intr enable reg." " func: %d status: %d\n", fn_idx, st); return st; } func->intr_enabled = false; zxlogf(TRACE, "sdio_enable_interrupt: Interrupt disabled for fn %d\n", fn_idx); return ZX_OK; }