new mmc code update

This commit is contained in:
lzl
2021-05-18 02:27:10 +00:00
parent ada6c9e251
commit c6ce1a770e
27 changed files with 10121 additions and 0 deletions
@@ -0,0 +1,28 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#ifndef PLATFORM_H
#define PLATFORM_H
#include "platform_common.h"
#include "platform_device.h"
#include "platform_manager.h"
#include "platform_queue.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* __cplusplus */
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */
#endif /* PLATFORM_H */
@@ -0,0 +1,90 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#ifndef PLATFORM_COMMON_H
#define PLATFORM_COMMON_H
#include "hdf_base.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* __cplusplus */
enum PlatformModuleType {
PLATFORM_MODULE_GPIO,
PLATFORM_MODULE_I2C,
PLATFORM_MODULE_SPI,
PLATFORM_MODULE_PIN,
PLATFORM_MODULE_CLOCK,
PLATFORM_MODULE_REGULATOR,
PLATFORM_MODULE_MIPI_DSI,
PLATFORM_MODULE_UART,
PLATFORM_MODULE_SDIO,
PLATFORM_MODULE_MDIO,
PLATFORM_MODULE_APB,
PLATFORM_MODULE_PCIE,
PLATFORM_MODULE_PCM,
PLATFORM_MODULE_I2S,
PLATFORM_MODULE_PWM,
PLATFORM_MODULE_DMA,
PLATFORM_MODULE_ADC,
PLATFORM_MODULE_RTC,
PLATFORM_MODULE_WDT,
PLATFORM_MODULE_I3C,
PLATFORM_MODULE_CAN,
PLATFORM_MODULE_HDMI,
PLATFORM_MODULE_MMC,
PLATFORM_MODULE_MTD,
PLATFORM_MODULE_DEFAULT,
PLATFORM_MODULE_MAX,
};
struct PlatformModuleInfo {
enum PlatformModuleType moduleType;
const char *moduleName;
void *priv;
};
struct PlatformModuleInfo *PlatformModuleInfoGet(enum PlatformModuleType moduleType);
int32_t PlatformModuleInfoCount(void);
enum PlatformErrno {
#define HDF_PLT_ERR_START HDF_BSP_ERR_START /**< Error number start of platform. */
#define HDF_PLT_ERR_NUM(v) (HDF_PLT_ERR_START + (v))
HDF_PLT_ERR_OS_API = HDF_ERR_BSP_PLT_API_ERR,
HDF_PLT_ERR_OPEN_DEV = HDF_PAL_ERR_DEV_CREATE, /**< Failed to open a device. */
HDF_PLT_ERR_INNER = HDF_PAL_ERR_INNER, /**< Internal error of platform framework. */
HDF_PLT_ERR_NO_DEV = HDF_PLT_ERR_NUM(-5), /**< There is no device present. */
HDF_PLT_ERR_DEV_TYPE = HDF_PLT_ERR_NUM(-6), /**< invalid device type */
HDF_PLT_ERR_DEV_GET = HDF_PLT_ERR_NUM(-7), /**< err on device get */
HDF_PLT_ERR_DEV_ADD = HDF_PLT_ERR_NUM(-8), /**< err on device add */
HDF_PLT_ERR_DEV_FULL = HDF_PLT_ERR_NUM(-9), /**< id number conflict */
HDF_PLT_ERR_ID_REPEAT = HDF_PLT_ERR_NUM(-10), /**< id number conflict */
#define HDF_MMC_ERR_START (HDF_PLT_ERR_START - 50) /**< Error number start for mmc. */
#define HDF_MMC_ERR_NUM(v) (HDF_MMC_ERR_START + (v))
HDF_MMC_ERR_SWITCH_FAIL = HDF_MMC_ERR_NUM(-1),
HDF_MMC_ERR_OTHER_CMD_IS_RUNNING = HDF_MMC_ERR_NUM(-2),
HDF_MMC_ERR_ILLEGAL_SEQ = HDF_MMC_ERR_NUM(-3),
};
void PlatformGlobalLock(void);
void PlatformGlobalUnlock(void);
/* Os adapt */
bool PlatInIrqContext(void);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */
#endif /* PLATFORM_COMMON_H */
@@ -0,0 +1,170 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#ifndef PLATFORM_DEVICE_H
#define PLATFORM_DEVICE_H
#include "hdf_base.h"
#include "hdf_dlist.h"
#include "hdf_sref.h"
#include "osal_sem.h"
#include "osal_spinlock.h"
#include "platform_common.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* __cplusplus */
struct PlatformManager;
struct PlatformDevice {
struct HdfDeviceObject *hdfDev; /* releated to an hdf device object */
struct PlatformManager *manager; /* the platform manager it belongs to */
uint32_t magic; /* magic number of the device instance */
const char *name; /* name of the device instance */
struct HdfSRef ref; /* used for reference count */
struct DListHead node; /* linked to the list of a manager */
struct DListHead notifiers; /* list of notifier nodes */
bool ready; /* indicates whether initialized */
OsalSpinlock spin; /* for member protection */
struct OsalSem released; /* for death notification */
};
enum PlatformEventType {
PLAT_EVENT_DEAD = 0, /* a platform device going to die */
};
struct PlatformNotifier {
void *data; /* private data u can take */
/**
* @brief the event handle funciton of this notifier.
*
* make sure it can be called in irq context.
*
* @param device Indicates the pointer to the platform device.
* @param event Indicates the event type of this handling process.
*
* @since 1.0
*/
void (*handle)(struct PlatformDevice *device, enum PlatformEventType event, void *data);
};
struct PlatformNotifierNode {
struct DListHead node; /* link to notfifier node list */
struct PlatformNotifier *notifier; /* pointer to the notifier instance */
};
/**
* @brief Initialize a platform device.
*
* Initialize members of a platform device.
*
* @param device Indicates the pointer to the platform device.
*
* @since 1.0
*/
void PlatformDeviceInit(struct PlatformDevice *device);
/**
* @brief Uninitialize a platform device.
*
* Uninitialize members of a platform device.
*
* @param device Indicates the pointer to the platform device.
*
* @since 1.0
*/
void PlatformDeviceUninit(struct PlatformDevice *device);
/**
* @brief Increase reference count for a platform device.
*
* @param device Indicates the pointer to the platform device.
*
* @return Returns the pointer to the paltform device on success; returns NULL otherwise.
* @since 1.0
*/
struct PlatformDevice *PlatformDeviceGet(struct PlatformDevice *device);
/**
* @brief Decrease reference count for a platform device.
*
* @param device Indicates the pointer to the platform device.
*
* @since 1.0
*/
void PlatformDevicePut(struct PlatformDevice *device);
/**
* @brief Register a notifier to a platform device.
*
* Subscribe the events of a platform device by registering a notfier.
*
* @param device Indicates the pointer to the platform device.
* @param notifier Indicates the pointer to the platform notifier.
*
* @return Returns 0 if the notifier registered successfully; returns a negative value otherwise.
* @since 1.0
*/
int32_t PlatformDeviceRegNotifier(struct PlatformDevice *device, struct PlatformNotifier *notifier);
/**
* @brief Unregister a notifier to a platform device.
*
* Unsubscribe the events of a platform device by unregistering the notfier.
*
* @param device Indicates the pointer to the platform device.
* @param notifier Indicates the pointer to the platform notifier.
*
* @since 1.0
*/
void PlatformDeviceUnregNotifier(struct PlatformDevice *device, struct PlatformNotifier *notifier);
/**
* @brief Unregister all notifiers to a platform device.
*
* Unsubscribe all the events of a platform device by clearing the notfiers.
*
* @param device Indicates the pointer to the platform device.
*
* @since 1.0
*/
void PlatformDeviceClearNotifier(struct PlatformDevice *device);
/**
* @brief Add a platform device by module type.
*
* do not call in irq context cause can sleep
*
* @param device Indicates the pointer to the platform device.
*
* @return Returns 0 if add successfully; returns a negative value otherwise.
* @since 1.0
*/
int32_t PlatformDeviceAdd(struct PlatformDevice *device);
/**
* @brief Remove a platform device by module type.
*
* do not call in irq context cause can sleep
*
* @param device Indicates the pointer to the platform device.
*
* @since 1.0
*/
void PlatformDeviceDel(struct PlatformDevice *device);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */
#endif /* PLATFORM_DEVICE_H */
@@ -0,0 +1,46 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#ifndef PLATFORM_ERRNO_H
#define PLATFORM_ERRNO_H
#include "hdf_base.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* __cplusplus */
enum PlatformErrno {
#define HDF_PLT_ERR_START HDF_BSP_ERR_START /**< Error number start of platform. */
#define HDF_PLT_ERR_NUM(v) (HDF_PLT_ERR_START + (v))
HDF_PLT_ERR_OS_API = HDF_ERR_BSP_PLT_API_ERR,
HDF_PLT_ERR_OPEN_DEV = HDF_PAL_ERR_DEV_CREATE, /**< Failed to open a device. */
HDF_PLT_ERR_INNER = HDF_PAL_ERR_INNER, /**< Internal error of platform framework. */
HDF_PLT_ERR_NO_DEV = HDF_PLT_ERR_NUM(-5), /**< There is no device present. */
HDF_PLT_ERR_DEV_TYPE = HDF_PLT_ERR_NUM(-6), /**< invalid device type */
HDF_PLT_ERR_DEV_GET = HDF_PLT_ERR_NUM(-7), /**< err on device get */
HDF_PLT_ERR_DEV_ADD = HDF_PLT_ERR_NUM(-8), /**< err on device add */
HDF_PLT_ERR_DEV_FULL = HDF_PLT_ERR_NUM(-9), /**< id number conflict */
HDF_PLT_ERR_ID_REPEAT = HDF_PLT_ERR_NUM(-10), /**< id number conflict */
#define HDF_MMC_ERR_START (HDF_PLT_ERR_START - 50) /**< Error number start for mmc. */
#define HDF_MMC_ERR_NUM(v) (HDF_MMC_ERR_START + (v))
HDF_MMC_ERR_SWITCH_FAIL = HDF_MMC_ERR_NUM(-1),
HDF_MMC_ERR_OTHER_CMD_IS_RUNNING = HDF_MMC_ERR_NUM(-2),
HDF_MMC_ERR_ILLEGAL_SEQ = HDF_MMC_ERR_NUM(-3),
};
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */
#endif /* PLATFORM_ERRNO_H */
@@ -0,0 +1,112 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#ifndef PLATFORM_MANAGER_H
#define PLATFORM_MANAGER_H
#include "hdf_base.h"
#include "hdf_dlist.h"
#include "osal_spinlock.h"
#include "platform_device.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* __cplusplus */
struct PlatformManager {
const char *name; /* name of the manager */
struct DListHead devices; /* list to keep all it's device instances */
OsalSpinlock spin; /* for member protection */
};
/**
* @brief Create a platform manager.
*
* Create a platform manager with member initialized.
*
* @param name Indicates the name of the manager.
*
* @return Returns the pointer to the paltform manager on success; returns NULL otherwise.
* @since 1.0
*/
struct PlatformManager *PlatformManagerCreate(const char *name);
/**
* @brief Get a platform manager by module type.
*
* @param module Indicates the module type of the manager.
*
* @return Returns the pointer to the paltform manager on success; returns NULL otherwise.
* @since 1.0
*/
struct PlatformManager *PlatformManagerGet(enum PlatformModuleType module);
/**
* @brief Add a platform device to a platform manager.
*
* Add a platform device to make it managed by platform core.
*
* @param manager Indicates the pointer to the platform manager.
* @param device Indicates the pointer to the platform device.
*
* @return Returns 0 if the devcie added successfully; returns a negative value otherwise.
* @since 1.0
*/
int32_t PlatformManagerAddDevice(struct PlatformManager *manager, struct PlatformDevice *device);
/**
* @brief Remove a platform device from a platform manager.
*
* Remove a platform device to make it away from management of platform core.
*
* @param manager Indicates the pointer to the platform manager.
* @param device Indicates the pointer to the platform device.
*
* @since 1.0
*/
void PlatformManagerDelDevice(struct PlatformManager *manager, struct PlatformDevice *device);
/**
* @brief Find a particular device from the manager.
*
* Locate a particular device from the manager by a matching function, witch will be called for
* each device, untill it returns true indicatting a device is "found".
* The device found will be returned with reference count increased.
*
* @param manager Indicates the pointer to the platform manager.
* @param data Indicates the pointer to the data passed to match function.
* @param match Indicates the pointer to the match function.
*
* @return Returns the pointer to the paltform device on success; returns NULL otherwise.
* @since 1.0
*/
struct PlatformDevice *PlatformManagerFindDevice(struct PlatformManager *manager, void *data,
bool (*match)(struct PlatformDevice *pdevice, void *data));
/**
* @brief Get a platform device from the manager by magic.
*
* The device got will be returned with reference count increased.
*
* @param manager Indicates the pointer to the platform manager.
* @param magic Indicates the magic number of the target platform device.
*
* @return Returns the pointer to the paltform device on success; returns NULL otherwise.
* @since 1.0
*/
struct PlatformDevice *PlatformManagerGetDeviceByMagic(struct PlatformManager *manager, uint32_t magic);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */
#endif /* PLATFORM_MANAGER_H */
@@ -0,0 +1,61 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#ifndef PLATFORM_QUEUE_H
#define PLATFORM_QUEUE_H
#include "hdf_dlist.h"
#include "osal_thread.h"
#include "osal_sem.h"
#include "osal_spinlock.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* __cplusplus */
struct PlatformMsg;
struct PlatformQueue;
struct PlatformMsg {
struct DListHead node;
struct OsalSem sem;
int32_t code;
int32_t error;
bool block; /* whether need to block thread */
void *data;
};
int32_t PlatformMsgWait(struct PlatformMsg *msg);
typedef int32_t (*PlatformMsgHandle)(struct PlatformQueue *queue, struct PlatformMsg *msg);
struct PlatformQueue {
const char *name;
OsalSpinlock spin;
struct OsalSem sem;
struct DListHead msgs;
struct OsalThread thread; /* the worker thread of this queue */
PlatformMsgHandle handle;
void *data;
};
void PlatformQueueAddMsg(struct PlatformQueue *queue, struct PlatformMsg *msg);
struct PlatformQueue *PlatformQueueCreate(PlatformMsgHandle handle, const char *name, void *data);
void PlatformQueueDestroy(struct PlatformQueue *queue);
int32_t PlatformQueueStart(struct PlatformQueue *queue);
int32_t PlatformQueueSuspend(struct PlatformQueue *queue);
int32_t PlatformQueueResume(struct PlatformQueue *queue);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */
#endif /* PLATFORM_QUEUE_H */
+29
View File
@@ -0,0 +1,29 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#ifndef MMC_BLOCK_H
#define MMC_BLOCK_H
#include "mmc_corex.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* __cplusplus */
int32_t MmcBlockAdd(struct MmcDevice *mmc);
void MmcBlockDel(struct MmcDevice *mmc);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */
#endif /* MMC_BLOCK_H */
+104
View File
@@ -0,0 +1,104 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#ifndef MMC_CAPS_H
#define MMC_CAPS_H
#include "hdf_base.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* __cplusplus */
enum MmcVolt { VOLT_3V3 = 0, VOLT_1V8, VOLT_1V2 };
enum MmcPowerMode { MMC_POWER_MODE_POWER_OFF = 0, MMC_POWER_MODE_POWER_UP, MMC_POWER_MODE_POWER_ON };
enum MmcBusWidth { BUS_WIDTH1 = 0, BUS_WIDTH4 = 2, BUS_WIDTH8 = 3 };
enum MmcBusTiming {
BUS_TIMING_MMC_DS = 0,
BUS_TIMING_MMC_HS,
BUS_TIMING_SD_HS,
BUS_TIMING_UHS_SDR12,
BUS_TIMING_UHS_SDR25,
BUS_TIMING_UHS_SDR50,
BUS_TIMING_UHS_SDR104,
BUS_TIMING_UHS_DDR50,
BUS_TIMING_UHS_DDR52,
BUS_TIMING_MMC_HS200, /* for emmc */
BUS_TIMING_MMC_HS400, /* for emmc */
};
union MmcCaps {
uint32_t capsData;
struct CapsBitsData {
uint32_t cap4Bit : 1; /* bit:0 support 4 bit transfer */
uint32_t cap8Bit : 1; /* bit:1 support 8 bit transfer */
uint32_t highSpeed : 1; /* bit:2 support high-speed timing */
uint32_t sdioIrq : 1; /* bit:3 signal pending SDIO irqs */
uint32_t onlySpi : 1; /* bit:4 only support spi protocols */
uint32_t needPoll : 1; /* bit:5 need polling for card-detection */
uint32_t nonremovable : 1; /* bit:6 Nonremoveable eg. eMMC */
uint32_t waitWhileBusy : 1; /* bit:7 waits while card is busy */
uint32_t erase : 1; /* bit:8 allow erase */
uint32_t ddr1v8 : 1; /* bit:9 support ddr mode at 1.8V */
uint32_t ddr1v2 : 1; /* bit:10 support ddr mode at 1.2V */
uint32_t powerOffCard : 1; /* bit:11 support power off after boot */
uint32_t busWidthTest : 1; /* bit:12 CMD14/CMD19 bus width ok */
uint32_t uhsSdr12 : 1; /* bit:13 support UHS SDR12 mode */
uint32_t uhsSdr25 : 1; /* bit:14 support UHS SDR25 mode */
uint32_t uhsSdr50 : 1; /* bit:15 support UHS SDR50 mode */
uint32_t uhsSdr104 : 1; /* bit:16 support UHS SDR104 mode */
uint32_t uhsDdr50 : 1; /* bit:17 support UHS DDR50 mode */
uint32_t xpc330 : 1; /* bit:18 support >150mA current at 3.3V */
uint32_t xpc300 : 1; /* bit:19 support >150mA current at 3.0V */
uint32_t xpc180 : 1; /* bit:20 support >150mA current at 1.8V */
uint32_t driverTypeA : 1; /* bit:21 support driver type A */
uint32_t driverTypeC : 1; /* bit:22 support driver type C */
uint32_t driverTypeD : 1; /* bit:23 support driver type D */
uint32_t maxCurrentLimit200 : 1; /* bit:24 max current limit 200mA */
uint32_t maxCurrentLimit400 : 1; /* bit:25 max current limit 400mA */
uint32_t maxCurrentLimit600 : 1; /* bit:26 max current limit 600mA */
uint32_t maxCurrentLimit800 : 1; /* bit:27 max current limit 800mA */
uint32_t cmd23 : 1; /* bit:28 support CMD23 */
uint32_t hardwareReset : 1; /* bit:29 support hardware reset */
uint32_t sdSupportProtocol3 : 1; /* bit:30 SD support Protocol 3.0 */
uint32_t cmdStop : 1; /* bit:31 support cmd stop */
} bits;
};
union MmcCaps2 {
uint32_t caps2Data;
struct Caps2BitsData {
uint32_t bootPartNoAcc : 1; /* bit:0 boot partition no access */
uint32_t cacheCtrl : 1; /* bit:1 allow cache control */
uint32_t poweroffNotify : 1; /* bit:2 support notify power off */
uint32_t noMultiRead : 1; /* bit:3 not support multiblock read */
uint32_t noSleepCmd : 1; /* bit:4 not support sleep command */
uint32_t hs200Sdr1v8 : 1; /* bit:5 support hs200 sdr 1.8V */
uint32_t hs200Sdr1v2 : 1; /* bit:6 support sdr hs200 1.2V */
uint32_t brokenVoltage : 1; /* bit:7 use broken voltage */
uint32_t detectNoErr : 1; /* bit:8 I/O err check card removal */
uint32_t hcEraseSize : 1; /* bit:9 High-capacity erase size */
uint32_t hs400Support1v8 : 1; /* bit:10 support hs400 1.8V */
uint32_t hs400Support1v2 : 1; /* bit:11 support hs400 1.2V */
uint32_t hs400EnhancedStrobe : 1; /* bit:12 support hs400 enhanced strobe */
uint32_t reserved : 18; /* bits:13~31, reserved */
} bits;
};
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */
#endif /* _MMC_CAPS_H */
+318
View File
@@ -0,0 +1,318 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#ifndef MMC_CORE_H
#define MMC_CORE_H
#include "hdf_base.h"
#include "hdf_device_desc.h"
#include "hdf_log.h"
#include "mmc_caps.h"
#include "mmc_protocol.h"
#include "osal_mem.h"
#include "osal_mutex.h"
#include "osal_time.h"
#include "platform.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* __cplusplus */
#define MMC_CNTLR_NR_MAX 3
#define MMC_DEV_NR_MAX 3
#define MMC_SEC_SIZE 512
#define MMC_MIN(x, y) (((x) < (y)) ? (x) : (y))
#define MMC_MAX(x, y) (((x) < (y)) ? (y) : (x))
struct MmcCntlr;
struct MmcCntlrOps;
struct MmcDevice;
struct MmcMsg;
struct MmcData;
struct MmcCmd;
enum MmcMsgCode;
enum MmcCmdCode;
union MmcDevState;
enum MmcDevType {
MMC_DEV_EMMC = 0,
MMC_DEV_SD,
MMC_DEV_SDIO,
MMC_DEV_COMBO,
MMC_DEV_INVALID
};
struct MmcCntlr {
struct IDeviceIoService service;
struct HdfDeviceObject *hdfDevObj;
struct PlatformDevice device;
struct OsalMutex mutex;
struct OsalSem released;
uint32_t devType;
struct MmcDevice *curDev;
struct MmcCntlrOps *ops;
struct PlatformQueue *msgQueue;
uint16_t index;
uint16_t voltDef;
uint32_t vddBit;
uint32_t freqMin;
uint32_t freqMax;
uint32_t freqDef;
union MmcOcr ocrDef;
union MmcCaps caps;
union MmcCaps2 caps2;
uint32_t maxBlkNum;
uint32_t maxBlkSize;
uint32_t maxReqSize;
bool devPluged;
bool detecting;
void *priv;
};
struct MmcCntlrOps {
int32_t (*request)(struct MmcCntlr *cntlr, struct MmcCmd *cmd);
int32_t (*setClock)(struct MmcCntlr *cntlr, uint32_t clock);
int32_t (*setPowerMode)(struct MmcCntlr *cntlr, enum MmcPowerMode mode);
int32_t (*setBusWidth)(struct MmcCntlr *cntlr, enum MmcBusWidth width);
int32_t (*setBusTiming)(struct MmcCntlr *cntlr, enum MmcBusTiming timing);
int32_t (*setSdioIrq)(struct MmcCntlr *cntlr, bool enable);
int32_t (*hardwareReset)(struct MmcCntlr *cntlr);
int32_t (*systemInit)(struct MmcCntlr *cntlr);
int32_t (*setEnhanceSrobe)(struct MmcCntlr *cntlr, bool enable);
int32_t (*switchVoltage)(struct MmcCntlr *cntlr, enum MmcVolt volt);
bool (*devReadOnly)(struct MmcCntlr *cntlr);
bool (*devPluged)(struct MmcCntlr *cntlr);
bool (*devBusy)(struct MmcCntlr *cntlr);
int32_t (*tune)(struct MmcCntlr *cntlr, uint32_t cmdCode);
int32_t (*rescanSdioDev)(struct MmcCntlr *cntlr);
};
/* controller management */
int32_t MmcCntlrAdd(struct MmcCntlr *cntlr);
void MmcCntlrRemove(struct MmcCntlr *cntlr);
struct MmcDevice *MmcCntlrGetDevice(struct MmcCntlr *cntlr);
static inline struct MmcCntlr *MmcCntlrGet(struct MmcCntlr *cntlr)
{
if (cntlr != NULL && PlatformDeviceGet(&cntlr->device) != NULL) {
return cntlr;
}
return NULL;
}
static inline struct MmcCntlr *MmcCntlrGetByNr(uint16_t number)
{
struct PlatformDevice *device = PlatformManagerGetDeviceByMagic(PlatformManagerGet(PLATFORM_MODULE_MMC), number);
if (device == NULL) {
return NULL;
}
return CONTAINER_OF(device, struct MmcCntlr, device);
}
static inline void MmcCntlrPut(struct MmcCntlr *cntlr)
{
if (cntlr != NULL) {
PlatformDevicePut(&cntlr->device);
}
}
static inline bool MmcCntlrDevPresent(struct MmcCntlr *cntlr)
{
return (cntlr != NULL && cntlr->curDev != NULL);
}
static inline void MmcCntlrLock(struct MmcCntlr *cntlr)
{
if (cntlr != NULL) {
(void)OsalMutexLock(&cntlr->mutex);
}
}
static inline void MmcCntlrUnlock(struct MmcCntlr *cntlr)
{
if (cntlr != NULL) {
(void)OsalMutexUnlock(&cntlr->mutex);
}
}
/* controller common bussiness */
int32_t MmcCntlrDoRequest(struct MmcCntlr *cntlr, struct MmcCmd *cmd);
int32_t MmcCntlrAddMsgToQueue(struct MmcCntlr *cntlr, struct MmcCmd *cmd, int32_t code, bool block);
int32_t MmcCntlrAddRequestMsgToQueue(struct MmcCntlr *cntlr, struct MmcCmd *cmd);
int32_t MmcCntlrAddDetectMsgToQueue(struct MmcCntlr *cntlr);
int32_t MmcCntlrAddPlugMsgToQueue(struct MmcCntlr *cntlr);
int32_t MmcCntlrAddSdioRescanMsgToQueue(struct MmcCntlr *cntlr);
int32_t MmcCntlrParse(struct MmcCntlr *cntlr, struct HdfDeviceObject *obj);
int32_t MmcCntlrCreatSdioIrqThread(struct MmcCntlr *cntlr);
void MmcCntlrDestroySdioIrqThread(struct MmcCntlr *cntlr);
void MmcCntlrNotifySdioIrqThread(struct MmcCntlr *cntlr);
/* controller private bussiness */
void MmcCntlrSetClock(struct MmcCntlr *cntlr, uint32_t clock);
void MmcCntlrSetBusWidth(struct MmcCntlr *cntlr, enum MmcBusWidth width);
void MmcCntlrSetBusTiming(struct MmcCntlr *cntlr, enum MmcBusTiming timing);
void MmcCntlrSetEnhanceSrobe(struct MmcCntlr *cntlr, bool enable);
int32_t MmcCntlrSwitchVoltage(struct MmcCntlr *cntlr, enum MmcVolt voltage);
bool MmcCntlrDevReadOnly(struct MmcCntlr *cntlr);
bool MmcCntlrDevBusy(struct MmcCntlr *cntlr);
bool MmcCntlrDevPluged(struct MmcCntlr *cntlr);
int32_t MmcCntlrTune(struct MmcCntlr *cntlr, uint32_t cmdCode);
void MmcCntlrSelectWorkVoltage(struct MmcCntlr *cntlr, union MmcOcr *ocr);
void MmcCntlrPowerUp(struct MmcCntlr *cntlr);
void MmcCntlrPowerOff(struct MmcCntlr *cntlr);
int32_t MmcCntlrAllocDev(struct MmcCntlr *cntlr, enum MmcDevType devType);
void MmcCntlrFreeDev(struct MmcCntlr *cntlr);
bool MmcCntlrSupportUhs(struct MmcCntlr *cntlr);
bool MmcCntlrSupportHighSpeed400EnhancedStrobe(struct MmcCntlr *cntlr);
bool MmcCntlrSupportHighSpeed400(struct MmcCntlr *cntlr);
bool MmcCntlrSupportHighSpeed200(struct MmcCntlr *cntlr);
bool MmcCntlrSdSupportCmd23(struct MmcCntlr *cntlr);
bool MmcCntlrEmmcSupportCmd23(struct MmcCntlr *cntlr);
struct MmcDeviceWorkParam {
uint32_t clock;
enum MmcBusWidth width;
enum MmcBusTiming timing;
};
struct MmcRegister {
union MmcOcr ocr;
uint32_t rca;
uint32_t rawCid[CID_LEN];
uint32_t rawCsd[CSD_LEN];
struct MmcCid cid;
struct MmcCsd csd;
};
union MmcDevState {
uint32_t stateData;
struct StateBitsData {
uint32_t present : 1;
uint32_t readonly : 1;
uint32_t highSpeed : 1;
uint32_t blockAddr : 1;
uint32_t ddrMode : 1;
uint32_t highSpeedDdr : 1;
uint32_t uhs : 1;
uint32_t sdxc : 1;
uint32_t hs200 : 1;
uint32_t sleep : 1;
uint32_t removeable : 1;
uint32_t blkszForByteMode : 1;
uint32_t hs400 : 1;
uint32_t hs400es : 1;
uint32_t reserverd : 17;
} bits;
};
struct MmcDevice {
struct PlatformDevice device;
struct MmcCntlr *cntlr;
struct MmcRegister reg;
struct MmcDeviceWorkParam workPara;
union MmcDevState state;
enum MmcDevType type;
size_t secSize; // by bytes
size_t capacity; // by sectors
size_t eraseSize; // by sectors
struct StorageBlock *sb;
void *priv;
};
/* device management */
int32_t MmcDeviceAdd(struct MmcDevice *mmc);
void MmcDeviceAddOps(struct MmcDevice *mmc, void *ops);
void MmcDeviceRemove(struct MmcDevice *mmc);
struct MmcDevice *MmcDeviceGet(struct MmcDevice *mmc);
void MmcDevicePut(struct MmcDevice *mmc);
/* device business */
ssize_t MmcDeviceRead(struct MmcDevice *mmc, uint8_t *buf, size_t startSec, size_t nSec);
ssize_t MmcDeviceWrite(struct MmcDevice *mmc, uint8_t *buf, size_t startSec, size_t nSec);
ssize_t MmcDeviceErase(struct MmcDevice *mmc, size_t startSec, size_t nSec);
static inline bool MmcDeviceIsPresent(struct MmcDevice *mmc)
{
return (mmc != NULL && mmc->state.bits.present);
}
struct MmcCmd {
uint32_t cmdCode;
uint32_t argument;
uint32_t resp[MMC_CMD_RESP_SIZE];
uint32_t respType;
int32_t returnError;
struct MmcData *data;
};
#define DATA_WRITE (0x1 << 0)
#define DATA_READ (0x1 << 1)
#define DATA_STREAM (0x1 << 2)
struct MmcData {
uint32_t blockSize; /* data block size, byte */
uint32_t blockNum;
int32_t returnError;
uint8_t *dataBuffer;
void *scatter;
uint32_t scatterLen;
uint32_t dataFlags;
struct MmcCmd stopCmd; /* stop command */
bool sendStopCmd;
};
enum MmcMsgCode {
MMC_MSG_REQUEST,
MMC_MSG_PLUG,
MMC_MSG_UNPLUG,
MMC_MSG_SDIO_RESCAN,
};
struct MmcMsg {
struct PlatformMsg msg;
struct MmcCmd *mmcCmd;
};
struct MmcRwData {
uint8_t *buf;
bool writeFlag;
size_t startSector;
size_t sectors;
};
int32_t MmcDoDetect(struct MmcCntlr *cntlr);
void MmcDeleteDev(struct MmcCntlr *cntlr);
int32_t MmcSendStatus(struct MmcCntlr *cntlr, uint32_t *status);
int32_t MmcStopTransmission(struct MmcCntlr *cntlr, bool writeFlag, uint32_t *stopStatus);
int32_t MmcSendTuning(struct MmcCntlr *cntlr, uint32_t cmdCode, bool sendStop);
int32_t MmcSendErase(struct MmcCntlr *cntlr, uint32_t startSec, uint32_t nSec);
void MmcSetupReadWriteBlocksCmd(struct MmcDevice *mmc, struct MmcCmd *cmd, struct MmcRwData *info);
int32_t MmcSendReadWriteBlocks(struct MmcCntlr *cntlr, struct MmcRwData *info);
int32_t SdioReinit(struct MmcCntlr *cntlr);
int32_t SdioReadCccrIoEnable(struct MmcCntlr *cntlr, uint8_t *val);
int32_t SdioCccrIntEnable(struct MmcCntlr *cntlr);
int32_t SdioCccrIntDisable(struct MmcCntlr *cntlr);
int32_t SdioCccrIoEnable(struct MmcCntlr *cntlr);
int32_t SdioCccrIoDisable(struct MmcCntlr *cntlr);
int32_t SdioReadCccrIntPending(struct MmcCntlr *cntlr, uint8_t *val);
int32_t SdioReadCccrIoReady(struct MmcCntlr *cntlr, uint8_t *val);
int32_t SdioSetFbrIoBlockSize(struct MmcCntlr *cntlr, uint32_t blkSize);
int32_t SdioReadWriteByte(struct MmcCntlr *cntlr, bool writeFlag,
uint32_t funcNum, uint32_t addr, uint8_t *data);
int32_t SdioReadWriteBlock(struct MmcCntlr *cntlr, struct SdioRwBlockInfo *info);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */
#endif /* MMC_CORE_H */
@@ -0,0 +1,36 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#ifndef MMC_DISPATCH_H
#define MMC_DISPATCH_H
#ifndef __USER__
#include "devsvc_manager_clnt.h"
#endif
#ifdef __USER__
#include "hdf_io_service_if.h"
#endif
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* __cplusplus */
#ifndef __USER__
int32_t MmcIoDispatch(struct HdfDeviceIoClient *client, int cmd, struct HdfSBuf *data, struct HdfSBuf *reply);
#endif
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */
#endif /* MMC_DISPATCH_H */
+44
View File
@@ -0,0 +1,44 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#ifndef MMC_EMMC_H
#define MMC_EMMC_H
#include "emmc_if.h"
#include "mmc_corex.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* __cplusplus */
struct EmmcRegister {
struct EmmcExtCsd extCsd;
};
struct EmmcDevice {
struct MmcDevice mmc;
struct EmmcDeviceOps *emmcOps;
struct EmmcRegister emmcReg;
};
struct EmmcDeviceOps {
int32_t (*getCid)(struct EmmcDevice *, uint8_t *, uint32_t);
};
int32_t EmmcDeviceGetCid(struct EmmcDevice *dev, uint8_t *cid, uint32_t len);
void EmmcDeviceAddOps(struct EmmcDevice *dev, void *ops);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */
#endif /* MMC_EMMC_H */
File diff suppressed because it is too large Load Diff
+40
View File
@@ -0,0 +1,40 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#ifndef MMC_SD_H
#define MMC_SD_H
#include "mmc_corex.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* __cplusplus */
struct SdRegister {
uint32_t rawScr[SCR_LEN];
uint16_t rawDsr;
struct SdScr scr;
struct SdSsr ssr;
struct SdSwitchCaps swCaps;
};
struct SdDevice {
struct MmcDevice mmc;
enum SdBusSpeedMode busSpeedMode;
struct SdRegister reg;
};
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */
#endif /* MMC_SD_H */
+106
View File
@@ -0,0 +1,106 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#ifndef MMC_SDIO_H
#define MMC_SDIO_H
#include "mmc_sd.h"
#include "osal_thread.h"
#include "sdio_if.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* __cplusplus */
struct SdioFunction {
struct SdioDevice *dev;
uint32_t maxBlkSize;
uint32_t curBlkSize;
uint32_t funcNum;
uint8_t funcClass;
uint16_t vendorId;
uint16_t deviceId;
uint32_t timeOut;
SdioIrqHandler *irqHandler;
};
struct SdioRegister {
struct SdioCccr cccr;
struct SdioCis cis;
};
struct SdioDevice {
struct SdDevice sd;
struct SdioDeviceOps *sdioOps;
struct SdioRegister sdioReg;
uint32_t functions;
struct SdioFunction *sdioFunc[SDIO_MAX_FUNCTION_NUMBER];
struct SdioFunction *curFunction;
struct OsalThread thread; /* irq thread */
struct OsalSem sem;
bool irqPending;
bool threadRunning;
};
struct SdioDeviceOps {
int32_t (*incrAddrReadBytes)(struct SdioDevice *, uint8_t *, uint32_t, uint32_t);
int32_t (*incrAddrWriteBytes)(struct SdioDevice *, uint8_t *, uint32_t, uint32_t);
int32_t (*fixedAddrReadBytes)(struct SdioDevice *, uint8_t *, uint32_t, uint32_t, uint32_t);
int32_t (*fixedAddrWriteBytes)(struct SdioDevice *, uint8_t *, uint32_t, uint32_t, uint32_t);
int32_t (*func0ReadBytes)(struct SdioDevice *, uint8_t *, uint32_t, uint32_t);
int32_t (*func0WriteBytes)(struct SdioDevice *, uint8_t *, uint32_t, uint32_t);
int32_t (*setBlockSize)(struct SdioDevice *, uint32_t);
int32_t (*getCommonInfo)(struct SdioDevice *, SdioCommonInfo *, uint32_t);
int32_t (*setCommonInfo)(struct SdioDevice *, SdioCommonInfo *, uint32_t);
int32_t (*flushData)(struct SdioDevice *);
int32_t (*enableFunc)(struct SdioDevice *);
int32_t (*disableFunc)(struct SdioDevice *);
int32_t (*claimIrq)(struct SdioDevice *, SdioIrqHandler *);
int32_t (*releaseIrq)(struct SdioDevice *);
int32_t (*findFunc)(struct SdioDevice *, struct SdioFunctionConfig *);
int32_t (*claimHost)(struct SdioDevice *);
int32_t (*releaseHost)(struct SdioDevice *);
};
int32_t SdioDeviceFindFunction(struct SdioDevice *sdio, struct SdioFunctionConfig *config);
int32_t SdioDeviceIncrAddrReadBytes(struct SdioDevice *sdio,
uint8_t *data, uint32_t addr, uint32_t size);
int32_t SdioDeviceIncrAddrWriteBytes(struct SdioDevice *sdio,
uint8_t *data, uint32_t addr, uint32_t size);
int32_t SdioDeviceFixedAddrReadBytes(struct SdioDevice *sdio,
uint8_t *data, uint32_t addr, uint32_t size, uint32_t scatterLen);
int32_t SdioDeviceFixedAddrWriteBytes(struct SdioDevice *sdio,
uint8_t *data, uint32_t addr, uint32_t size, uint32_t scatterLen);
int32_t SdioDeviceFunc0ReadBytes(struct SdioDevice *sdio,
uint8_t *data, uint32_t addr, uint32_t size);
int32_t SdioDeviceFunc0WriteBytes(struct SdioDevice *sdio,
uint8_t *data, uint32_t addr, uint32_t size);
int32_t SdioDeviceSetBlockSize(struct SdioDevice *sdio, uint32_t blockSize);
int32_t SdioDeviceGetCommonInfo(struct SdioDevice *sdio,
SdioCommonInfo *info, SdioCommonInfoType infoType);
int32_t SdioDeviceSetCommonInfo(struct SdioDevice *sdio,
SdioCommonInfo *info, SdioCommonInfoType infoType);
int32_t SdioDeviceFlushData(struct SdioDevice *sdio);
int32_t SdioDeviceClaimHost(struct SdioDevice *sdio);
int32_t SdioDeviceReleaseHost(struct SdioDevice *sdio);
int32_t SdioDeviceEnableFunc(struct SdioDevice *sdio);
int32_t SdioDeviceDisableFunc(struct SdioDevice *sdio);
int32_t SdioDeviceClaimIrq(struct SdioDevice *sdio, SdioIrqHandler *irqHandler);
int32_t SdioDeviceReleaseIrq(struct SdioDevice *sdio);
void SdioDeviceAddOps(struct SdioDevice *sdio, void *ops);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */
#endif /* MMC_SDIO_H */
@@ -0,0 +1,196 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#include "hdf_log.h"
#include "osal_spinlock.h"
#include "platform_common.h"
static struct PlatformModuleInfo g_platformModules[] = {
#if defined(LOSCFG_DRIVERS_HDF_PLATFORM_GPIO) || defined(CONFIG_DRIVERS_HDF_PLATFORM_GPIO)
{
.moduleType = PLATFORM_MODULE_GPIO,
.moduleName = "PLATFORM_MODULE_GPIO",
},
#endif
#if defined(LOSCFG_DRIVERS_HDF_PLATFORM_I2C) || defined(CONFIG_DRIVERS_HDF_PLATFORM_I2C)
{
.moduleType = PLATFORM_MODULE_I2C,
.moduleName = "PLATFORM_MODULE_I2C",
},
#endif
#if defined(LOSCFG_DRIVERS_HDF_PLATFORM_SPI) || defined(CONFIG_DRIVERS_HDF_PLATFORM_SPI)
{
.moduleType = PLATFORM_MODULE_SPI,
.moduleName = "PLATFORM_MODULE_SPI",
},
#endif
#if defined(LOSCFG_DRIVERS_HDF_PLATFORM_PIN) || defined(CONFIG_DRIVERS_HDF_PLATFORM_PIN)
{
.moduleType = PLATFORM_MODULE_PIN,
.moduleName = "PLATFORM_MODULE_PIN",
},
#endif
#if defined(LOSCFG_DRIVERS_HDF_PLATFORM_CLOCK) || defined(CONFIG_DRIVERS_HDF_PLATFORM_CLOCK)
{
.moduleType = PLATFORM_MODULE_CLOCK,
.moduleName = "PLATFORM_MODULE_CLOCK",
},
#endif
#if defined(LOSCFG_DRIVERS_HDF_PLATFORM_REGULATOR) || defined(CONFIG_DRIVERS_HDF_PLATFORM_REGULATOR)
{
.moduleType = PLATFORM_MODULE_REGULATOR,
.moduleName = "PLATFORM_MODULE_REGULATOR",
},
#endif
#if defined(LOSCFG_DRIVERS_HDF_PLATFORM_MIPI_DSI) || defined(CONFIG_DRIVERS_HDF_PLATFORM_MIPI_DSI)
{
.moduleType = PLATFORM_MODULE_MIPI_DSI,
.moduleName = "PLATFORM_MODULE_MIPI_DSI",
},
#endif
#if defined(LOSCFG_DRIVERS_HDF_PLATFORM_UART) || defined(CONFIG_DRIVERS_HDF_PLATFORM_UART)
{
.moduleType = PLATFORM_MODULE_UART,
.moduleName = "PLATFORM_MODULE_UART",
},
#endif
#if defined(LOSCFG_DRIVERS_HDF_PLATFORM_SDIO) || defined(CONFIG_DRIVERS_HDF_PLATFORM_SDIO)
{
.moduleType = PLATFORM_MODULE_SDIO,
.moduleName = "PLATFORM_MODULE_SDIO",
},
#endif
#if defined(LOSCFG_DRIVERS_HDF_PLATFORM_MDIO) || defined(CONFIG_DRIVERS_HDF_PLATFORM_MDIO)
{
.moduleType = PLATFORM_MODULE_MDIO,
.moduleName = "PLATFORM_MODULE_MDIO",
},
#endif
#if defined(LOSCFG_DRIVERS_HDF_PLATFORM_APB) || defined(CONFIG_DRIVERS_HDF_PLATFORM_APB)
{
.moduleType = PLATFORM_MODULE_APB,
.moduleName = "PLATFORM_MODULE_APB",
},
#endif
#if defined(LOSCFG_DRIVERS_HDF_PLATFORM_PCIE) || defined(CONFIG_DRIVERS_HDF_PLATFORM_PCIE)
{
.moduleType = PLATFORM_MODULE_PCIE,
.moduleName = "PLATFORM_MODULE_PCIE",
},
#endif
#if defined(LOSCFG_DRIVERS_HDF_PLATFORM_PCM) || defined(CONFIG_DRIVERS_HDF_PLATFORM_PCM)
{
.moduleType = PLATFORM_MODULE_PCM,
.moduleName = "PLATFORM_MODULE_PCM",
},
#endif
#if defined(LOSCFG_DRIVERS_HDF_PLATFORM_I2S) || defined(CONFIG_DRIVERS_HDF_PLATFORM_I2S)
{
.moduleType = PLATFORM_MODULE_I2S,
.moduleName = "PLATFORM_MODULE_I2S",
},
#endif
#if defined(LOSCFG_DRIVERS_HDF_PLATFORM_PWM) || defined(CONFIG_DRIVERS_HDF_PLATFORM_PWM)
{
.moduleType = PLATFORM_MODULE_PWM,
.moduleName = "PLATFORM_MODULE_PWM",
},
#endif
#if defined(LOSCFG_DRIVERS_HDF_PLATFORM_DMA) || defined(CONFIG_DRIVERS_HDF_PLATFORM_DMA)
{
.moduleType = PLATFORM_MODULE_DMA,
.moduleName = "PLATFORM_MODULE_DMA",
},
#endif
#if defined(LOSCFG_DRIVERS_HDF_PLATFORM_ADC) || defined(CONFIG_DRIVERS_HDF_PLATFORM_ADC)
{
.moduleType = PLATFORM_MODULE_ADC,
.moduleName = "PLATFORM_MODULE_ADC",
},
#endif
#if defined(LOSCFG_DRIVERS_HDF_PLATFORM_RTC) || defined(CONFIG_DRIVERS_HDF_PLATFORM_RTC)
{
.moduleType = PLATFORM_MODULE_RTC,
.moduleName = "PLATFORM_MODULE_RTC",
},
#endif
#if defined(LOSCFG_DRIVERS_HDF_PLATFORM_WDT) || defined(CONFIG_DRIVERS_HDF_PLATFORM_WDT)
{
.moduleType = PLATFORM_MODULE_WDT,
.moduleName = "PLATFORM_MODULE_WDT",
},
#endif
#if defined(LOSCFG_DRIVERS_HDF_PLATFORM_I3C) || defined(CONFIG_DRIVERS_HDF_PLATFORM_I3C)
{
.moduleType = PLATFORM_MODULE_I3C,
.moduleName = "PLATFORM_MODULE_I3C",
},
#endif
#if defined(LOSCFG_DRIVERS_HDF_PLATFORM_CAN) || defined(CONFIG_DRIVERS_HDF_PLATFORM_CAN)
{
.moduleType = PLATFORM_MODULE_CAN,
.moduleName = "PLATFORM_MODULE_CAN",
},
#endif
#if defined(LOSCFG_DRIVERS_HDF_PLATFORM_HDMI) || defined(CONFIG_DRIVERS_HDF_PLATFORM_HDMI)
{
.moduleType = PLATFORM_MODULE_HDMI,
.moduleName = "PLATFORM_MODULE_HDMI",
},
#endif
#if defined(LOSCFG_DRIVERS_HDF_PLATFORM_MMC) || defined(CONFIG_DRIVERS_HDF_PLATFORM_MMC)
{
.moduleType = PLATFORM_MODULE_MMC,
.moduleName = "PLATFORM_MODULE_MMC",
},
#endif
#if defined(LOSCFG_DRIVERS_HDF_PLATFORM_MTD) || defined(CONFIG_DRIVERS_HDF_PLATFORM_MTD)
{
.moduleType = PLATFORM_MODULE_MTD,
.moduleName = "PLATFORM_MODULE_MTD",
},
#endif
{
.moduleType = PLATFORM_MODULE_DEFAULT,
.moduleName = "PLATFORM_MODULE_DEFAULT",
},
};
static OsalSpinlock g_platformSpin;
static bool g_platformReady;
void PlatformGlobalLock(void)
{
if (g_platformReady == false) {
(void)OsalSpinInit(&g_platformSpin);
g_platformReady = true;
}
(void)OsalSpinLock(&g_platformSpin);
}
void PlatformGlobalUnlock(void)
{
(void)OsalSpinUnlock(&g_platformSpin);
}
struct PlatformModuleInfo *PlatformModuleInfoGet(enum PlatformModuleType moduleType)
{
int32_t i;
for (i = 0; i < PlatformModuleInfoCount(); i++) {
if (g_platformModules[i].moduleType == moduleType) {
return &g_platformModules[i];
}
}
return NULL;
}
int32_t PlatformModuleInfoCount(void)
{
return sizeof(g_platformModules) / sizeof(g_platformModules[0]);
}
@@ -0,0 +1,217 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#include "hdf_log.h"
#include "osal_mem.h"
#include "platform_common.h"
#include "platform_device.h"
#include "platform_manager.h"
#define PLATFORM_DEV_NAME_DEFAULT "platform_device"
static void PlatformDeviceOnFirstGet(struct HdfSRef *sref)
{
(void)sref;
}
static void PlatformDeviceOnLastPut(struct HdfSRef *sref)
{
struct PlatformDevice *device = NULL;
struct PlatformNotifierNode *pos = NULL;
struct PlatformNotifierNode *tmp = NULL;
if (sref == NULL) {
return;
}
device = CONTAINER_OF(sref, struct PlatformDevice, ref);
if (device == NULL) {
HDF_LOGE("PlatformDeviceOnLastPut: get device is NULL!");
return;
}
(void)OsalSpinLock(&device->spin);
device->ready = false;
DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &device->notifiers, struct PlatformNotifierNode, node) {
if (pos != NULL && pos->notifier != NULL && pos->notifier->handle != NULL) {
pos->notifier->handle(device, PLAT_EVENT_DEAD, pos->notifier->data);
}
}
(void)OsalSpinUnlock(&device->spin);
}
struct IHdfSRefListener g_platObjListener = {
.OnFirstAcquire = PlatformDeviceOnFirstGet,
.OnLastRelease = PlatformDeviceOnLastPut,
};
static void PlatformEventHandle(struct PlatformDevice *device, enum PlatformEventType event, void *data)
{
if (device == NULL) {
return;
}
if (event == PLAT_EVENT_DEAD) {
(void)OsalSemPost(&device->released);
}
}
static struct PlatformNotifier g_platformEventNotifier = {
.data = NULL,
.handle = PlatformEventHandle,
};
void PlatformDeviceInit(struct PlatformDevice *device)
{
if (device == NULL) {
HDF_LOGW("PlatformDeviceInit: device is NULL");
return;
}
if (device->name == NULL) {
device->name = PLATFORM_DEV_NAME_DEFAULT;
}
(void)OsalSpinInit(&device->spin);
(void)OsalSemInit(&device->released, 0);
DListHeadInit(&device->node);
DListHeadInit(&device->notifiers);
HdfSRefConstruct(&device->ref, &g_platObjListener);
if (PlatformDeviceRegNotifier(device, &g_platformEventNotifier) != HDF_SUCCESS) {
HDF_LOGE("PlatformDeviceInit: reg notifier fail");
}
device->ready = true;
}
void PlatformDeviceUninit(struct PlatformDevice *device)
{
if (device == NULL) {
HDF_LOGW("PlatformDevice: device is NULL");
return;
}
device->ready = false;
/* make sure no reference anymore before exit. */
(void)OsalSemWait(&device->released, HDF_WAIT_FOREVER);
PlatformDeviceClearNotifier(device);
(void)OsalSemDestroy(&device->released);
(void)OsalSpinDestroy(&device->spin);
}
struct PlatformDevice *PlatformDeviceGet(struct PlatformDevice *device)
{
if (device == NULL) {
HDF_LOGE("PlatformDeviceGet: device is NULL");
return NULL;
}
HdfSRefAcquire(&device->ref);
return device;
}
void PlatformDevicePut(struct PlatformDevice *device)
{
if (device != NULL) {
HdfSRefRelease(&device->ref);
}
}
int32_t PlatformDeviceRegNotifier(struct PlatformDevice *device, struct PlatformNotifier *notifier)
{
struct PlatformNotifierNode *pNode = NULL;
if (device == NULL || notifier == NULL) {
return HDF_ERR_INVALID_OBJECT;
}
pNode = (struct PlatformNotifierNode *)OsalMemCalloc(sizeof(*pNode));
if (pNode == NULL) {
HDF_LOGE("PlatformDeviceRegNotifier: alloc pNode fail");
return HDF_ERR_MALLOC_FAIL;
}
pNode->notifier = notifier;
(void)OsalSpinLock(&device->spin);
DListInsertTail(&pNode->node, &device->notifiers);
(void)OsalSpinUnlock(&device->spin);
return HDF_SUCCESS;
}
static void PlatformDeviceRemoveNotifier(struct PlatformDevice *device, struct PlatformNotifier *notifier)
{
struct PlatformNotifierNode *pos = NULL;
struct PlatformNotifierNode *tmp = NULL;
if (device->notifiers.next == NULL || device->notifiers.prev == NULL) {
HDF_LOGD("PlatformDeviceRemoveNotifier: notifiers not init.");
return;
}
(void)OsalSpinLock(&device->spin);
DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &device->notifiers, struct PlatformNotifierNode, node) {
if (pos != NULL && pos->notifier != NULL) {
/* if notifier not set, we remove all the notifier nodes. */
if (notifier == NULL || notifier == pos->notifier) {
DListRemove(&pos->node);
OsalMemFree(pos);
}
if (notifier == pos->notifier) {
break;
}
}
}
(void)OsalSpinUnlock(&device->spin);
}
void PlatformDeviceUnregNotifier(struct PlatformDevice *device, struct PlatformNotifier *notifier)
{
if (device == NULL || notifier == NULL) {
return;
}
PlatformDeviceRemoveNotifier(device, notifier);
}
void PlatformDeviceClearNotifier(struct PlatformDevice *device)
{
if (device == NULL) {
return;
}
PlatformDeviceRemoveNotifier(device, NULL);
}
int32_t PlatformDeviceAdd(struct PlatformDevice *device)
{
struct PlatformManager *manager = NULL;
if (device == NULL) {
return HDF_ERR_INVALID_OBJECT;
}
PlatformDeviceInit(device);
manager = device->manager;
if (manager == NULL) {
manager = PlatformManagerGet(PLATFORM_MODULE_DEFAULT);
}
return PlatformManagerAddDevice(manager, device);
}
void PlatformDeviceDel(struct PlatformDevice *device)
{
struct PlatformManager *manager = NULL;
if (device == NULL) {
return;
}
manager = device->manager;
if (manager == NULL) {
manager = PlatformManagerGet(PLATFORM_MODULE_DEFAULT);
}
PlatformManagerDelDevice(manager, device);
PlatformDeviceUninit(device);
}
@@ -0,0 +1,155 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#include "hdf_log.h"
#include "osal_mem.h"
#include "osal_sem.h"
#include "platform_common.h"
#include "platform_device.h"
#include "platform_manager.h"
#define PLATFORM_MANAGER_NAME_DEFAULT "PlatformManagerDefault"
static void PlatformManagerInit(struct PlatformManager *manager)
{
if (manager->name == NULL) {
manager->name = PLATFORM_MANAGER_NAME_DEFAULT;
}
OsalSpinInit(&manager->spin);
DListHeadInit(&manager->devices);
}
struct PlatformManager *PlatformManagerCreate(const char *name)
{
struct PlatformManager *manager = NULL;
manager = (struct PlatformManager *)OsalMemCalloc(sizeof(*manager));
if (manager == NULL) {
HDF_LOGE("PlatformManagerCreate: malloc fail!");
return NULL;
}
manager->name = name;
PlatformManagerInit(manager);
return manager;
}
struct PlatformManager *PlatformManagerGet(enum PlatformModuleType module)
{
struct PlatformManager *manager = NULL;
struct PlatformModuleInfo *info = NULL;
info = PlatformModuleInfoGet(module);
if (info == NULL) {
HDF_LOGE("PlatformManagerGet: get module(%d) info failed", module);
return NULL;
}
PlatformGlobalLock();
if (info->priv == NULL) {
manager = PlatformManagerCreate(info->moduleName);
info->priv = manager;
} else {
manager = (struct PlatformManager *)info->priv;
}
PlatformGlobalUnlock();
return manager;
}
int32_t PlatformManagerAddDevice(struct PlatformManager *manager, struct PlatformDevice *device)
{
struct PlatformDevice *tmp = NULL;
bool repeatId = false;
if (manager == NULL || device == NULL) {
return HDF_ERR_INVALID_OBJECT;
}
device->manager = manager;
if (PlatformDeviceGet(device) == NULL) { // keep a reference by manager
return HDF_PLT_ERR_DEV_GET;
}
(void)OsalSpinLock(&manager->spin);
DLIST_FOR_EACH_ENTRY(tmp, &manager->devices, struct PlatformDevice, node) {
if (tmp != NULL && tmp->magic == device->magic) {
repeatId = true;
HDF_LOGE("PlatformManagerAddDevice: repeated magic:%u!", device->magic);
break;
}
}
if (!repeatId) {
DListInsertTail(&device->node, &manager->devices);
}
(void)OsalSpinUnlock(&manager->spin);
if (repeatId) {
PlatformDevicePut(device);
}
return repeatId ? HDF_PLT_ERR_ID_REPEAT : HDF_SUCCESS;
}
void PlatformManagerDelDevice(struct PlatformManager *manager, struct PlatformDevice *device)
{
if (manager == NULL || device == NULL) {
return;
}
if (device->manager != manager) {
HDF_LOGE("PlatformManagerDelDevice: manager mismatch!");
return;
}
(void)OsalSpinLock(&manager->spin);
if (!DListIsEmpty(&device->node)) {
DListRemove(&device->node);
}
(void)OsalSpinUnlock(&manager->spin);
PlatformDevicePut(device); // put the reference hold by manager
}
struct PlatformDevice *PlatformManagerFindDevice(struct PlatformManager *manager, void *data,
bool (*match)(struct PlatformDevice *pdevice, void *data))
{
struct PlatformDevice *tmp = NULL;
struct PlatformDevice *pdevice = NULL;
if (manager == NULL || match == NULL) {
return NULL;
}
if (manager->devices.prev == NULL || manager->devices.next == NULL) {
HDF_LOGD("PlatformManagerFindDevice: devices not init.");
return NULL;
}
(void)OsalSpinLock(&manager->spin);
DLIST_FOR_EACH_ENTRY(tmp, &manager->devices, struct PlatformDevice, node) {
if (tmp != NULL && match(tmp, data)) {
pdevice = PlatformDeviceGet(tmp);
}
}
(void)OsalSpinUnlock(&manager->spin);
return pdevice;
}
static bool PlatformDeviceMatchByMagic(struct PlatformDevice *device, void *data)
{
uint32_t magic = (uint32_t)(uintptr_t)data;
return (device != NULL && device->magic == magic);
}
struct PlatformDevice *PlatformManagerGetDeviceByMagic(struct PlatformManager *manager, uint32_t magic)
{
if (manager == NULL) {
return NULL;
}
return PlatformManagerFindDevice(manager, (void *)(uintptr_t)magic, PlatformDeviceMatchByMagic);
}
@@ -0,0 +1,157 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#include "platform_queue.h"
#include "hdf_log.h"
#include "osal_mem.h"
#include "osal_mutex.h"
#include "osal_thread.h"
#define MMC_QUEUE_THREAD_STAK 20000
static int32_t PlatformQueueThreadWorker(void *data)
{
int32_t ret;
struct PlatformQueue *queue = (struct PlatformQueue *)data;
struct PlatformMsg *msg = NULL;
while (true) {
/* wait envent */
ret = OsalSemWait(&queue->sem, HDF_WAIT_FOREVER);
if (ret != HDF_SUCCESS) {
continue;
}
(void)OsalSpinLock(&queue->spin);
if (DListIsEmpty(&queue->msgs)) {
msg = NULL;
} else {
msg = DLIST_FIRST_ENTRY(&queue->msgs, struct PlatformMsg, node);
DListRemove(&msg->node);
}
(void)OsalSpinUnlock(&queue->spin);
/* message process */
if (msg != NULL) {
(void)(queue->handle(queue, msg));
if (msg->block == true) {
(void)OsalSemPost(&msg->sem);
}
}
}
return HDF_SUCCESS;
}
struct PlatformQueue *PlatformQueueCreate(PlatformMsgHandle handle, const char *name, void *data)
{
int32_t ret;
struct PlatformQueue *queue = NULL;
if (handle == NULL) {
return NULL;
}
queue = (struct PlatformQueue *)OsalMemCalloc(sizeof(*queue));
if (queue == NULL) {
HDF_LOGE("PlatformQueueCreate: alloc queue fail!");
return NULL;
}
(void)OsalSpinInit(&queue->spin);
(void)OsalSemInit(&queue->sem, 0);
DListHeadInit(&queue->msgs);
ret = OsalThreadCreate(&queue->thread, (OsalThreadEntry)PlatformQueueThreadWorker, (void *)queue);
if (ret != HDF_SUCCESS) {
HDF_LOGE("PlatformQueueCreate: create thread fail!");
OsalMemFree(queue);
return NULL;
}
queue->name = (name == NULL) ? "PlatformWorkerThread" : name;
queue->handle = handle;
queue->data = data;
return queue;
}
void PlatformQueueDestroy(struct PlatformQueue *queue)
{
if (queue == NULL) {
return;
}
(void)OsalThreadDestroy(&queue->thread);
(void)OsalSemDestroy(&queue->sem);
(void)OsalSpinDestroy(&queue->spin);
OsalMemFree(queue);
}
int32_t PlatformQueueStart(struct PlatformQueue *queue)
{
int32_t ret;
struct OsalThreadParam cfg;
if (queue == NULL) {
return HDF_ERR_INVALID_OBJECT;
}
cfg.name = (char *)queue->name;
cfg.priority = OSAL_THREAD_PRI_HIGHEST;
cfg.stackSize = MMC_QUEUE_THREAD_STAK;
ret = OsalThreadStart(&queue->thread, &cfg);
if (ret != HDF_SUCCESS) {
HDF_LOGE("PlatformQueueStart: start thread fail:%d", ret);
return ret;
}
return HDF_SUCCESS;
}
int32_t PlatformQueueSuspend(struct PlatformQueue *queue)
{
if (queue == NULL) {
return HDF_ERR_INVALID_OBJECT;
}
return OsalThreadSuspend(&queue->thread);
}
int32_t PlatformQueueResume(struct PlatformQueue *queue)
{
if (queue == NULL) {
return HDF_ERR_INVALID_OBJECT;
}
return OsalThreadResume(&queue->thread);
}
void PlatformQueueAddMsg(struct PlatformQueue *queue, struct PlatformMsg *msg)
{
if (queue == NULL || msg == NULL) {
return;
}
if (msg->block == true) {
(void)OsalSemInit(&msg->sem, 0);
}
DListHeadInit(&msg->node);
msg->error = HDF_SUCCESS;
(void)OsalSpinLock(&queue->spin);
DListInsertTail(&msg->node, &queue->msgs);
(void)OsalSpinUnlock(&queue->spin);
/* notify the worker thread */
(void)OsalSemPost(&queue->sem);
}
int32_t PlatformMsgWait(struct PlatformMsg *msg)
{
if (msg == NULL) {
return HDF_ERR_INVALID_OBJECT;
}
if (msg->block == false) {
return HDF_SUCCESS;
}
return OsalSemWait(&msg->sem, HDF_WAIT_FOREVER);
}
+159
View File
@@ -0,0 +1,159 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#ifndef __USER__
#include "devsvc_manager_clnt.h"
#include "mmc_emmc.h"
#endif
#include "emmc_if.h"
#include "hdf_base.h"
#ifdef __USER__
#include "hdf_io_service_if.h"
#endif
#include "hdf_log.h"
#include "osal_mem.h"
#include "securec.h"
#define HDF_LOG_TAG emmc_if_c
#ifdef __USER__
static int32_t EmmcGetCidReadReplyData(struct HdfSBuf *reply, uint8_t *cid, uint32_t size)
{
uint32_t rLen;
const void *rBuf = NULL;
if (HdfSbufReadBuffer(reply, &rBuf, &rLen) == false) {
HDF_LOGE("EmmcGetCidReadReplyData: read rBuf fail!");
return HDF_ERR_IO;
}
if (size != rLen) {
HDF_LOGE("EmmcGetCidReadReplyData: err len:%u, rLen:%u", size, rLen);
if (rLen > size) {
rLen = size;
}
}
if (memcpy_s(cid, size, rBuf, rLen) != EOK) {
HDF_LOGE("EmmcGetCidReadReplyData: memcpy rBuf fail!");
return HDF_ERR_IO;
}
return HDF_SUCCESS;
}
int32_t EmmcServiceGetCid(struct HdfIoService *service, uint8_t *cid, uint32_t size)
{
int32_t ret;
struct HdfSBuf *reply = NULL;
reply = HdfSBufObtainDefaultSize();
if (reply == NULL) {
HDF_LOGE("EmmcServiceGetCid: failed to obtain reply!");
ret = HDF_ERR_MALLOC_FAIL;
goto __EXIT;
}
if (service->dispatcher == NULL || service->dispatcher->Dispatch == NULL) {
HDF_LOGE("EmmcServiceGetCid: dispatcher or Dispatch is NULL!");
ret = HDF_ERR_NOT_SUPPORT;
goto __EXIT;
}
ret = service->dispatcher->Dispatch(&service->object, EMMC_CMD_GET_CID, NULL, reply);
if (ret != HDF_SUCCESS) {
HDF_LOGE("EmmcServiceGetCid: failed to send service call:%d", ret);
goto __EXIT;
}
ret = EmmcGetCidReadReplyData(reply, cid, size);
if (ret != HDF_SUCCESS) {
goto __EXIT;
}
HDF_LOGD("EmmcServiceGetCid: success");
__EXIT:
if (reply != NULL) {
HdfSBufRecycle(reply);
}
return ret;
}
#else
static int32_t EmmcDeviceGetFromHandle(DevHandle handle, struct EmmcDevice **emmc)
{
struct MmcDevice *mmc = NULL;
if (handle == NULL) {
return HDF_ERR_INVALID_OBJECT;
}
if (emmc == NULL) {
return HDF_ERR_INVALID_PARAM;
}
mmc = MmcCntlrGetDevice((struct MmcCntlr *)handle);
if (mmc == NULL) {
return HDF_PLT_ERR_NO_DEV;
}
if (mmc->type != MMC_DEV_EMMC) {
MmcDevicePut(mmc);
return HDF_PLT_ERR_DEV_TYPE;
}
*emmc = (struct EmmcDevice *)mmc;
return HDF_SUCCESS;
}
#endif
int32_t EmmcGetCid(DevHandle handle, uint8_t *cid, uint32_t size)
{
if (handle == NULL) {
HDF_LOGE("EmmcGetCid: handle is NULL!");
return HDF_ERR_INVALID_OBJECT;
}
if (cid == NULL || size < EMMC_CID_LEN) {
HDF_LOGE("EmmcGetCid: error parms!");
return HDF_ERR_INVALID_PARAM;
}
#ifdef __USER__
return EmmcServiceGetCid((struct HdfIoService *)handle, cid, size);
#else
struct EmmcDevice *emmc = NULL;
int32_t ret;
if (EmmcDeviceGetFromHandle(handle, &emmc) != HDF_SUCCESS) {
return HDF_ERR_INVALID_OBJECT;
}
ret = EmmcDeviceGetCid(emmc, cid, size);
MmcDevicePut((struct MmcDevice *)emmc);
return ret;
#endif
}
void EmmcGetHuid(uint8_t *cid, uint32_t size)
{
DevHandle handle = NULL;
if (cid == NULL || size == 0) {
HDF_LOGE("EmmcGetUdid: error parms!");
return;
}
if (memset_s(cid, sizeof(uint8_t) * size, 0, sizeof(uint8_t) * size) != EOK) {
HDF_LOGE("EmmcGetUdid: memset_s fail!");
return;
}
handle = EmmcOpen(0);
if (handle == NULL) {
HDF_LOGD("EmmcGetUdid: open fail, use default value!");
return;
}
if (EmmcGetCid(handle, cid, size) != HDF_SUCCESS) {
HDF_LOGD("EmmcGetUdid: get fail, use default value!");
}
EmmcClose(handle);
}
+166
View File
@@ -0,0 +1,166 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#include "storage_block.h"
#include "hdf_base.h"
#include "hdf_log.h"
#include "mmc_corex.h"
#include "mmc_sd.h"
#include "osal_mem.h"
#include "securec.h"
static ssize_t MmcBlockRead(struct StorageBlock *sb, uint8_t *buf, size_t secStart, size_t nSec)
{
if (sb == NULL) {
return HDF_ERR_INVALID_OBJECT;
}
if (sb->type == MEDIA_MMC) {
return MmcDeviceRead((struct MmcDevice *)sb->media, buf, secStart, nSec);
}
return HDF_ERR_NOT_SUPPORT;
}
static ssize_t MmcBlockWrite(struct StorageBlock *sb, const uint8_t *buf, size_t secStart, size_t nSec)
{
if (sb == NULL) {
return HDF_ERR_INVALID_OBJECT;
}
if (sb->type == MEDIA_MMC) {
return MmcDeviceWrite((struct MmcDevice *)sb->media, (uint8_t *)buf, secStart, nSec);
}
return HDF_ERR_NOT_SUPPORT;
}
static ssize_t MmcBlockErase(struct StorageBlock *sb, size_t secStart, size_t nSec)
{
if (sb == NULL) {
return HDF_ERR_INVALID_OBJECT;
}
if (sb->type == MEDIA_MMC) {
return MmcDeviceErase((struct MmcDevice *)sb->media, secStart, nSec);
}
return HDF_ERR_NOT_SUPPORT;
}
static uint32_t MmcBlockGetAuSize(struct StorageBlock *sb)
{
struct MmcDevice *mmc = NULL;
struct SdDevice *sd = NULL;
if (sb == NULL || sb->media == NULL) {
HDF_LOGE("MmcBlockGetAuSize: invalid sb or media!");
return 0;
}
if (sb->type != MEDIA_MMC) {
HDF_LOGE("MmcBlockGetAuSize: media is not mmc!");
return 0;
}
mmc = (struct MmcDevice *)sb->media;
if (mmc->type != MMC_DEV_SD) {
HDF_LOGE("MmcBlockGetAuSize: media is not sd!");
return 0;
}
sd = (struct SdDevice *)mmc;
return sd->reg.ssr.auSize;
}
static bool MmcBlockIsPresent(struct StorageBlock *sb)
{
return (sb != NULL && sb->type == MEDIA_MMC &&
MmcDeviceIsPresent((struct MmcDevice *)sb->media));
}
static struct StorageBlockMethod g_mmcBlockOps = {
.read = MmcBlockRead,
.write = MmcBlockWrite,
.erase = MmcBlockErase,
.getAuSize = MmcBlockGetAuSize,
.isPresent = MmcBlockIsPresent,
};
static int32_t MmcBlockInit(struct StorageBlock *sb, struct MmcDevice *mmc)
{
int32_t ret;
size_t nameSize;
if (PlatformDeviceGet(&mmc->device) == NULL) {
return HDF_PLT_ERR_DEV_GET;
}
mmc->sb = sb;
sb->type = MEDIA_MMC;
sb->media = mmc;
sb->secSize = mmc->secSize;
sb->capacity = mmc->capacity;
sb->removeable = (mmc->state.bits.removeable == 0) ? false : true;
sb->ops = &g_mmcBlockOps;
nameSize = sizeof(sb->name);
ret = snprintf_s(sb->name, nameSize, nameSize - 1, "/dev/mmcblk%0d", mmc->cntlr->index);
if (ret <= 0) {
PlatformDevicePut(&mmc->device);
}
return HDF_SUCCESS;
}
static void MmcBlockUninit(struct StorageBlock *sb)
{
struct MmcDevice *mmc = (struct MmcDevice *)sb->media;
mmc->sb = NULL;
PlatformDevicePut(&mmc->device);
}
int32_t MmcBlockAdd(struct MmcDevice *mmc)
{
int32_t ret;
struct StorageBlock *sb = NULL;
if (mmc == NULL) {
return HDF_ERR_INVALID_OBJECT;
}
sb = (struct StorageBlock *)OsalMemCalloc(sizeof(*sb));
if (sb == NULL) {
return HDF_ERR_MALLOC_FAIL;
}
ret = MmcBlockInit(sb, mmc);
if (ret != HDF_SUCCESS) {
OsalMemFree(sb);
return ret;
}
ret = StorageBlockAdd(sb);
if (ret != HDF_SUCCESS) {
MmcBlockUninit(sb);
OsalMemFree(sb);
return ret;
}
return HDF_SUCCESS;
}
void MmcBlockDel(struct MmcDevice *mmc)
{
struct StorageBlock *sb = NULL;
if (mmc == NULL) {
return;
}
sb = mmc->sb;
if (sb == NULL) {
return;
}
StorageBlockDel(sb);
MmcBlockUninit(sb);
OsalMemFree(sb);
}
File diff suppressed because it is too large Load Diff
+118
View File
@@ -0,0 +1,118 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#include "mmc_dispatch.h"
#include "hdf_log.h"
#include "mmc_corex.h"
#include "mmc_emmc.h"
#include "mmc_sdio.h"
static int32_t MmcCmdDevPresent(struct MmcCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply)
{
(void)data;
if (reply == NULL) {
return HDF_ERR_INVALID_PARAM;
}
if (!HdfSbufWriteUint8(reply, MmcCntlrDevPresent(cntlr))) {
HDF_LOGE("MmcCmdDevPresent: write reply sbuf fail!");
return HDF_ERR_IO;
}
return HDF_SUCCESS;
}
static int32_t MmcDispatch(struct MmcCntlr *cntlr, int cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
{
int32_t ret;
switch (cmd) {
case MMC_CMD_DEV_PRESENT:
ret = MmcCmdDevPresent(cntlr, data, reply);
break;
default:
ret = HDF_ERR_NOT_SUPPORT;
break;
}
return ret;
}
static int32_t EmmcCmdGetCid(struct MmcCntlr *cntlr, struct HdfSBuf *reply)
{
int32_t ret;
uint8_t cid[EMMC_CID_LEN] = {0};
if (reply == NULL || cntlr == NULL) {
return HDF_ERR_INVALID_PARAM;
}
ret = EmmcDeviceGetCid((struct EmmcDevice *)cntlr->curDev, cid, EMMC_CID_LEN);
if (ret != HDF_SUCCESS) {
HDF_LOGE("MmcCmdGetCid: get cid fail!");
return ret;
}
if (HdfSbufWriteBuffer(reply, cid, EMMC_CID_LEN) == false) {
HDF_LOGE("MmcCmdGetCid: write back cid fail!");
return HDF_ERR_IO;
}
return HDF_SUCCESS;
}
static int32_t EmmcDispatch(struct MmcCntlr *cntlr, int cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
{
int32_t ret;
(void)data;
switch (cmd) {
case EMMC_CMD_GET_CID:
ret = EmmcCmdGetCid(cntlr, reply);
break;
default:
ret = HDF_ERR_NOT_SUPPORT;
break;
}
return ret;
}
static int32_t SdioDispatch(struct MmcCntlr *cntlr, int cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
{
(void)cntlr;
(void)cmd;
(void)data;
(void)reply;
return HDF_ERR_NOT_SUPPORT;
}
int32_t MmcIoDispatch(struct HdfDeviceIoClient *client, int cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
{
int32_t ret;
struct MmcCntlr *cntlr = NULL;
if (client == NULL || client->device == NULL) {
HDF_LOGE("MmcIoDispatch: client or hdf dev obj is NULL");
return HDF_ERR_INVALID_OBJECT;
}
cntlr = (struct MmcCntlr *)client->device->service;
if (cntlr == NULL) {
HDF_LOGE("MmcIoDispatch: service is NULL");
return HDF_ERR_INVALID_OBJECT;
}
if (cmd < MMC_CMD_MAX) {
ret = MmcDispatch(cntlr, cmd, data, reply);
} else if (cmd < EMMC_CMD_MAX) {
ret = EmmcDispatch(cntlr, cmd, data, reply);
} else if (cmd < SDIO_CMD_MAX) {
ret = SdioDispatch(cntlr, cmd, data, reply);
} else {
ret = HDF_ERR_NOT_SUPPORT;
}
return ret;
}
+57
View File
@@ -0,0 +1,57 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#include "mmc_emmc.h"
#include "securec.h"
#define HDF_LOG_TAG mmc_emmc_c
static int32_t EmmcDeviceDefaultGetCid(struct EmmcDevice *dev, uint8_t *cid, uint32_t len)
{
struct MmcDevice *mmc = (struct MmcDevice *)dev;
if (memcpy_s(cid, sizeof(uint8_t) * len, (uint8_t *)(mmc->reg.rawCid),
sizeof(mmc->reg.rawCid)) != EOK) {
HDF_LOGE("EmmcDeviceDefaultGetCid: memcpy_s fail, size = %d!", len);
return HDF_FAILURE;
}
return HDF_SUCCESS;
}
static struct EmmcDeviceOps g_emmcOps = {
.getCid = EmmcDeviceDefaultGetCid,
};
int32_t EmmcDeviceGetCid(struct EmmcDevice *dev, uint8_t *cid, uint32_t len)
{
if (dev == NULL) {
return HDF_ERR_INVALID_OBJECT;
}
if (cid == NULL || len == 0) {
return HDF_ERR_INVALID_PARAM;
}
if (dev->emmcOps == NULL || dev->emmcOps->getCid == NULL) {
HDF_LOGE("EmmcDeviceGetCid: ops or getCid is NULL.");
return HDF_ERR_INVALID_OBJECT;
}
return dev->emmcOps->getCid(dev, cid, len);
}
void EmmcDeviceAddOps(struct EmmcDevice *dev, void *ops)
{
if (dev == NULL) {
HDF_LOGE("EmmcDeviceAddOps: dev is NULL.");
return;
}
if (ops == NULL) {
dev->emmcOps = &g_emmcOps;
HDF_LOGD("EmmcDeviceAddOps: use default ops.");
} else {
dev->emmcOps = (struct EmmcDeviceOps *)ops;
}
}
+114
View File
@@ -0,0 +1,114 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#include "mmc_if.h"
#ifndef __USER__
#include "devsvc_manager_clnt.h"
#include "mmc_corex.h"
#endif
#include "hdf_base.h"
#ifdef __USER__
#include "hdf_io_service_if.h"
#endif
#include "hdf_log.h"
#include "osal_mem.h"
#include "securec.h"
#define HDF_LOG_TAG mmc_if_c
#define MMC_SVC_NAME_LEN 32
static void *MmcCntlrObjGetByNumber(int16_t id)
{
void *object = NULL;
char *serviceName = NULL;
if (id < 0) {
HDF_LOGE("MmcCntlrObjGetByNumber: invalid id:%d", id);
return NULL;
}
serviceName = OsalMemCalloc(MMC_SVC_NAME_LEN + 1);
if (serviceName == NULL) {
HDF_LOGE("MmcCntlrObjGetByNumber: OsalMemCalloc fail!");
return NULL;
}
if (snprintf_s(serviceName, MMC_SVC_NAME_LEN + 1, MMC_SVC_NAME_LEN,
"HDF_PLATFORM_MMC_%d", id) < 0) {
HDF_LOGE("MmcCntlrObjGetByNumber: format service name fail!");
goto __ERR;
}
#ifdef __USER__
object = (void *)HdfIoServiceBind(serviceName);
#else
object = (void *)MmcCntlrGetByNr(id);
#endif
if (object == NULL) {
HDF_LOGE("MmcCntlrObjGetByNumber: get service fail!");
} else {
HDF_LOGD("MmcCntlrObjGetByNumber: success");
}
__ERR:
OsalMemFree(serviceName);
return object;
}
DevHandle MmcOpen(int16_t id)
{
return (DevHandle)MmcCntlrObjGetByNumber(id);
}
void MmcClose(DevHandle handle)
{
if (handle != NULL) {
#ifdef __USER__
HdfIoServiceRecycle((struct HdfIoService *)handle);
#endif
}
}
bool MmcDevPresent(DevHandle handle)
{
if (handle == NULL) {
return false;
}
#ifdef __USER__
int32_t ret;
uint8_t present = 0;
struct HdfSBuf *reply = NULL;
struct HdfIoService *service = (struct HdfIoService *)handle;
reply = HdfSBufObtainDefaultSize();
if (reply == NULL) {
HDF_LOGE("MmcDevPresent: failed to obtain reply!");
return false;
}
if (service->dispatcher == NULL || service->dispatcher->Dispatch == NULL) {
HDF_LOGE("MmcDevPresent: dispatcher or Dispatch is NULL!");
goto __EXIT;
}
ret = service->dispatcher->Dispatch(&service->object, MMC_CMD_DEV_PRESENT,
NULL, reply);
if (ret != HDF_SUCCESS) {
HDF_LOGE("MmcDevPresent: failed to send service call:%d", ret);
goto __EXIT;
}
if (HdfSbufReadUint8(reply, &present) == false) {
HDF_LOGE("MmcDevPresent: read present fail!");
goto __EXIT;
}
__EXIT:
HdfSBufRecycle(reply);
return (present != 0);
#else
return MmcCntlrDevPresent((struct MmcCntlr *)handle);
#endif
}
File diff suppressed because it is too large Load Diff
+757
View File
@@ -0,0 +1,757 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#include "mmc_sdio.h"
#define HDF_LOG_TAG mmc_sdio_c
#define SDIO_READ_IO_READY_RETRY_TIMES 10000
static int32_t SdioDeviceDefaultIncrAddrReadBytes(struct SdioDevice *dev,
uint8_t *data, uint32_t addr, uint32_t size)
{
struct SdioFunction *func = dev->curFunction;
struct MmcCntlr *cntlr = NULL;
struct SdioRwBlockInfo info = {0};
if (func == NULL) {
HDF_LOGE("SdioDeviceDefaultIncrAddrReadBytes fail, func is NULL.");
return HDF_ERR_INVALID_OBJECT;
}
if (data == NULL) {
HDF_LOGE("SdioDeviceDefaultIncrAddrReadBytes fail, data is null.");
return HDF_ERR_INVALID_PARAM;
}
cntlr = dev->sd.mmc.cntlr;
if (cntlr == NULL) {
HDF_LOGE("SdioDeviceDefaultIncrAddrReadBytes fail, cntlr is null.");
return HDF_ERR_INVALID_OBJECT;
}
if (size == 1) {
return SdioReadWriteByte(cntlr, false, func->funcNum, addr, data);
} else if (size > 1) {
info.addr = addr;
info.buf = data;
info.incrAddrFlag = true;
info.size = size;
info.writeFlag = false;
return SdioReadWriteBlock(cntlr, &info);
}
HDF_LOGE("SdioDeviceDefaultIncrAddrReadBytes fail, data size is 0.");
return HDF_ERR_INVALID_PARAM;
}
static int32_t SdioDeviceDefaultIncrAddrWriteBytes(struct SdioDevice *dev,
uint8_t *data, uint32_t addr, uint32_t size)
{
struct SdioFunction *func = dev->curFunction;
struct MmcCntlr *cntlr = NULL;
struct SdioRwBlockInfo info = {0};
if (func == NULL) {
HDF_LOGE("SdioDeviceDefaultIncrAddrWriteBytes fail, func is NULL.");
return HDF_ERR_INVALID_OBJECT;
}
if (data == NULL) {
HDF_LOGE("SdioDeviceDefaultIncrAddrWriteBytes fail, data is null.");
return HDF_ERR_INVALID_PARAM;
}
cntlr = dev->sd.mmc.cntlr;
if (cntlr == NULL) {
HDF_LOGE("SdioDeviceDefaultIncrAddrWriteBytes fail, cntlr is null.");
return HDF_ERR_INVALID_OBJECT;
}
if (size == 1) {
return SdioReadWriteByte(cntlr, true, func->funcNum, addr, data);
} else if (size > 1) {
info.addr = addr;
info.buf = data;
info.incrAddrFlag = true;
info.size = size;
info.writeFlag = true;
return SdioReadWriteBlock(cntlr, &info);
}
HDF_LOGE("SdioDeviceDefaultIncrAddrWriteBytes fail, data size is 0.");
return HDF_ERR_INVALID_PARAM;
}
static int32_t SdioDeviceDefaultFixedAddrReadBytes(struct SdioDevice *dev,
uint8_t *data, uint32_t addr, uint32_t size, uint32_t scatterLen)
{
struct SdioFunction *func = dev->curFunction;
struct MmcCntlr *cntlr = NULL;
struct SdioRwBlockInfo info = {0};
if (func == NULL) {
HDF_LOGE("SdioDeviceDefaultFixedAddrReadBytes fail, func is NULL.");
return HDF_ERR_INVALID_OBJECT;
}
if (data == NULL || size == 0) {
HDF_LOGE("SdioDeviceDefaultFixedAddrReadBytes fail, param is invalid.");
return HDF_ERR_INVALID_PARAM;
}
cntlr = dev->sd.mmc.cntlr;
if (cntlr == NULL) {
HDF_LOGE("SdioDeviceDefaultFixedAddrReadBytes fail, cntlr is null.");
return HDF_ERR_INVALID_OBJECT;
}
info.addr = addr;
info.buf = data;
info.incrAddrFlag = false;
info.size = size;
info.writeFlag = false;
if (scatterLen > 0) {
info.scatterFlag = true;
info.scatterLen = scatterLen;
}
return SdioReadWriteBlock(cntlr, &info);
}
static int32_t SdioDeviceDefaultFixedAddrWriteBytes(struct SdioDevice *dev,
uint8_t *data, uint32_t addr, uint32_t size, uint32_t scatterLen)
{
struct SdioFunction *func = dev->curFunction;
struct MmcCntlr *cntlr = NULL;
struct SdioRwBlockInfo info = {0};
if (func == NULL) {
HDF_LOGE("SdioDeviceDefaultFixedAddrWriteBytes fail, func is NULL.");
return HDF_ERR_INVALID_OBJECT;
}
if (data == NULL || size == 0) {
HDF_LOGE("SdioDeviceDefaultFixedAddrWriteBytes fail, param is invalid.");
return HDF_ERR_INVALID_PARAM;
}
cntlr = dev->sd.mmc.cntlr;
if (cntlr == NULL) {
HDF_LOGE("SdioDeviceDefaultFixedAddrWriteBytes fail, cntlr is null.");
return HDF_ERR_INVALID_OBJECT;
}
info.addr = addr;
info.buf = data;
info.incrAddrFlag = false;
info.size = size;
info.writeFlag = true;
if (scatterLen > 0) {
info.scatterFlag = true;
info.scatterLen = scatterLen;
}
return SdioReadWriteBlock(cntlr, &info);
}
static int32_t SdioDeviceDefaultFunc0ReadBytes(struct SdioDevice *dev,
uint8_t *data, uint32_t addr, uint32_t size)
{
struct SdioFunction *func = dev->curFunction;
struct MmcCntlr *cntlr = NULL;
uint32_t i;
int32_t ret;
if (func == NULL) {
HDF_LOGE("SdioDeviceDefaultFunc0ReadBytes fail, func is NULL.");
return HDF_ERR_INVALID_OBJECT;
}
if (data == NULL) {
HDF_LOGE("SdioDeviceDefaultFunc0ReadBytes fail, data is null.");
return HDF_ERR_INVALID_PARAM;
}
cntlr = dev->sd.mmc.cntlr;
if (cntlr == NULL) {
HDF_LOGE("SdioDeviceDefaultFunc0ReadBytes fail, cntlr is null.");
return HDF_ERR_INVALID_OBJECT;
}
for (i = 0; i < size; i++) {
ret = SdioReadWriteByte(cntlr, false, 0, (addr + i), &data[i]);
if (ret != HDF_SUCCESS) {
HDF_LOGE("SdioDeviceDefaultFunc0ReadBytes fail, i = %d.", i);
return ret;
}
}
return HDF_SUCCESS;
}
static int32_t SdioDeviceDefaultFunc0WriteBytes(struct SdioDevice *dev,
uint8_t *data, uint32_t addr, uint32_t size)
{
struct SdioFunction *func = dev->curFunction;
struct MmcCntlr *cntlr = NULL;
int32_t ret;
uint32_t i;
if (func == NULL) {
HDF_LOGE("SdioDeviceDefaultFunc0WriteBytes fail, func is NULL.");
return HDF_ERR_INVALID_OBJECT;
}
if (data == NULL) {
HDF_LOGE("SdioDeviceDefaultFunc0WriteBytes fail, data is null.");
return HDF_ERR_INVALID_PARAM;
}
cntlr = dev->sd.mmc.cntlr;
if (cntlr == NULL) {
HDF_LOGE("SdioDeviceDefaultFunc0WriteBytes fail, cntlr is null.");
return HDF_ERR_INVALID_OBJECT;
}
for (i = 0; i < size; i++) {
ret = SdioReadWriteByte(cntlr, true, 0, (addr + i), &data[i]);
if (ret != HDF_SUCCESS) {
HDF_LOGE("SdioDeviceDefaultFunc0WriteBytes fail, i = %d.", i);
return ret;
}
}
return HDF_SUCCESS;
}
static int32_t SdioDeviceDefaultSetBlockSize(struct SdioDevice *dev, uint32_t blkSize)
{
struct SdioFunction *func = dev->curFunction;
struct MmcCntlr *cntlr = NULL;
uint32_t blockSize = blkSize;
int32_t ret;
if (func == NULL) {
HDF_LOGE("SdioDeviceDefaultSetBlockSize: func is NULL.");
return HDF_ERR_INVALID_OBJECT;
}
cntlr = dev->sd.mmc.cntlr;
if (blockSize == 0) {
blockSize = ((func->maxBlkSize < cntlr->maxBlkSize) ? func->maxBlkSize : cntlr->maxBlkSize);
}
blockSize = MMC_MIN(blockSize, MMC_SEC_SIZE);
ret = SdioSetFbrIoBlockSize(cntlr, blockSize);
if (ret == HDF_SUCCESS) {
func->curBlkSize = blockSize;
}
return ret;
}
static int32_t SdioDeviceDefaultGetCommonInfo(struct SdioDevice *dev,
SdioCommonInfo *info, SdioCommonInfoType infoType)
{
struct MmcCntlr *cntlr = NULL;
struct SdioFunction *func = dev->curFunction;
if (func == NULL) {
HDF_LOGE("SdioDeviceDefaultGetCommonInfo: func is NULL.");
return HDF_ERR_INVALID_OBJECT;
}
if (info == NULL) {
HDF_LOGE("SdioDeviceDefaultGetCommonInfo: info is null.");
return HDF_ERR_INVALID_PARAM;
}
if (infoType != SDIO_FUNC_INFO) {
HDF_LOGE("SdioDeviceDefaultGetCommonInfo: cur type %d is not support.", infoType);
return HDF_ERR_NOT_SUPPORT;
}
cntlr = dev->sd.mmc.cntlr;
if (cntlr == NULL) {
HDF_LOGE("SdioDeviceDefaultGetCommonInfo fail, cntlr is null.");
return HDF_ERR_INVALID_PARAM;
}
info->funcInfo.enTimeout = func->timeOut;
info->funcInfo.maxBlockNum = cntlr->maxBlkNum;
info->funcInfo.maxBlockSize = cntlr->maxBlkSize;
info->funcInfo.maxRequestSize = cntlr->maxReqSize;
info->funcInfo.funcNum = func->funcNum;
info->funcInfo.irqCap = cntlr->caps.bits.sdioIrq;
info->funcInfo.data = (void *)func;
return HDF_SUCCESS;
}
static int32_t SdioDeviceDefaultSetCommonInfo(struct SdioDevice *dev,
SdioCommonInfo *info, SdioCommonInfoType infoType)
{
struct MmcCntlr *cntlr = NULL;
struct SdioFunction *func = dev->curFunction;
if (func == NULL) {
HDF_LOGE("SdioDeviceDefaultSetCommonInfo: func is NULL.");
return HDF_ERR_INVALID_OBJECT;
}
if (info == NULL) {
HDF_LOGE("SdioDeviceDefaultSetCommonInfo: info is null.");
return HDF_ERR_INVALID_PARAM;
}
if (infoType != SDIO_FUNC_INFO) {
HDF_LOGE("SdioDeviceDefaultSetCommonInfo: cur type %d is not support.", infoType);
return HDF_ERR_NOT_SUPPORT;
}
cntlr = dev->sd.mmc.cntlr;
if (cntlr == NULL) {
HDF_LOGE("SdioDeviceDefaultSetCommonInfo fail, cntlr is null.");
return HDF_ERR_INVALID_PARAM;
}
func->timeOut = info->funcInfo.enTimeout;
cntlr->maxBlkNum = info->funcInfo.maxBlockNum;
cntlr->maxBlkSize = info->funcInfo.maxBlockSize;
cntlr->maxReqSize = info->funcInfo.maxRequestSize;
func->funcNum = info->funcInfo.funcNum;
return HDF_SUCCESS;
}
static int32_t SdioDeviceDefaultFlushData(struct SdioDevice *dev)
{
struct MmcCntlr *cntlr = NULL;
cntlr = dev->sd.mmc.cntlr;
if (cntlr == NULL) {
HDF_LOGE("SdioDeviceDefaultFlushData fail, cntlr is null.");
return HDF_ERR_INVALID_OBJECT;
}
return SdioReinit(cntlr);
}
static int32_t SdioDeviceDefaultEnableFunc(struct SdioDevice *dev)
{
struct SdioFunction *func = dev->curFunction;
int32_t ret;
uint32_t i;
uint8_t val;
if (func == NULL) {
HDF_LOGE("SdioDeviceDefaultEnableFunc: func is NULL.");
return HDF_ERR_INVALID_OBJECT;
}
ret = SdioCccrIoEnable(dev->sd.mmc.cntlr);
if (ret != HDF_SUCCESS) {
HDF_LOGE("SdioDeviceDefaultEnableFunc: Io Enable fail.");
return ret;
}
for (i = 0; i < SDIO_READ_IO_READY_RETRY_TIMES; i++) {
ret = SdioReadCccrIoReady(dev->sd.mmc.cntlr, &val);
if (ret != HDF_SUCCESS) {
HDF_LOGE("SdioDeviceDefaultEnableFunc: read Io Ready fail.");
return ret;
}
if ((val & (1 << func->funcNum)) > 0) {
return HDF_SUCCESS;
}
}
HDF_LOGE("SdioDeviceDefaultEnableFunc: Io not Ready.");
return HDF_ERR_TIMEOUT;
}
static int32_t SdioDeviceDefaultDisableFunc(struct SdioDevice *dev)
{
struct SdioFunction *func = dev->curFunction;
if (func == NULL) {
HDF_LOGE("SdioDeviceDefaultDisableFunc: func is NULL.");
return HDF_ERR_INVALID_OBJECT;
}
return SdioCccrIoDisable(dev->sd.mmc.cntlr);
}
static int32_t SdioDeviceDefaultClaimIrq(struct SdioDevice *dev, SdioIrqHandler *irqHandler)
{
struct SdioFunction *func = dev->curFunction;
struct MmcCntlr *cntlr = NULL;
int32_t ret;
if (func == NULL) {
HDF_LOGE("SdioDeviceDefaultClaimIrq: func is NULL.");
return HDF_ERR_INVALID_OBJECT;
}
if (func->irqHandler != NULL) {
HDF_LOGE("SdioDeviceDefaultClaimIrq: irq has been registered.");
return HDF_ERR_DEVICE_BUSY;
}
if (irqHandler == NULL) {
HDF_LOGE("SdioDeviceDefaultClaimIrq: irqHandler is NULL.");
return HDF_ERR_INVALID_PARAM;
}
cntlr = dev->sd.mmc.cntlr;
if (cntlr == NULL) {
HDF_LOGE("SdioDeviceDefaultClaimIrq: cntlr is NULL.");
return HDF_ERR_INVALID_OBJECT;
}
ret = SdioCccrIntEnable(cntlr);
if (ret != HDF_SUCCESS) {
return ret;
}
func->irqHandler = irqHandler;
if (cntlr->caps.bits.sdioIrq > 0) {
ret = MmcCntlrCreatSdioIrqThread(cntlr);
}
return ret;
}
static int32_t SdioDeviceDefaultReleaseIrq(struct SdioDevice *dev)
{
struct SdioFunction *func = dev->curFunction;
struct MmcCntlr *cntlr = NULL;
if (func == NULL) {
HDF_LOGE("SdioDeviceDefaultReleaseIrq: func is NULL.");
return HDF_ERR_INVALID_OBJECT;
}
cntlr = dev->sd.mmc.cntlr;
if (cntlr == NULL) {
HDF_LOGE("SdioDeviceDefaultReleaseIrq: cntlr is NULL.");
return HDF_ERR_INVALID_OBJECT;
}
if (func->irqHandler != NULL) {
func->irqHandler = NULL;
MmcCntlrDestroySdioIrqThread(cntlr);
}
if (cntlr->caps.bits.sdioIrq > 0 && cntlr->ops != NULL && cntlr->ops->setSdioIrq != NULL) {
(void)cntlr->ops->setSdioIrq(cntlr, false);
}
return SdioCccrIntDisable(cntlr);
}
static int32_t SdioDeviceDefaultFindFunc(struct SdioDevice *dev, struct SdioFunctionConfig *cfg)
{
uint32_t i;
struct SdioFunction *func = NULL;
if (dev->functions > SDIO_MAX_FUNCTION_NUMBER) {
HDF_LOGE("SdioDeviceDefaultFindFunc: functions = %d, error!", dev->functions);
return HDF_ERR_INVALID_PARAM;
}
for (i = 0; i < dev->functions; i++) {
func = dev->sdioFunc[i];
if (func == NULL) {
continue;
}
if (cfg->deviceId == func->deviceId &&
cfg->vendorId == func->vendorId &&
cfg->funcNr == func->funcNum) {
dev->curFunction = func;
return HDF_SUCCESS;
}
}
HDF_LOGE("SdioDeviceDefaultFindFunc: find func fail!");
return HDF_FAILURE;
}
static int32_t SdioDeviceDefaultClaimHost(struct SdioDevice *dev)
{
struct SdioFunction *func = dev->curFunction;
struct MmcCntlr *cntlr = NULL;
if (func == NULL) {
HDF_LOGE("SdioDeviceDefaultClaimHost: func is NULL.");
return HDF_ERR_INVALID_OBJECT;
}
cntlr = dev->sd.mmc.cntlr;
if (cntlr == NULL) {
HDF_LOGE("SdioDeviceDefaultClaimHost: cntlr is NULL.");
return HDF_ERR_INVALID_OBJECT;
}
MmcCntlrLock(cntlr);
return HDF_SUCCESS;
}
static int32_t SdioDeviceDefaultReleaseHost(struct SdioDevice *dev)
{
struct SdioFunction *func = dev->curFunction;
struct MmcCntlr *cntlr = NULL;
if (func == NULL) {
HDF_LOGE("SdioDeviceDefaultReleaseHost: func is NULL.");
return HDF_ERR_INVALID_OBJECT;
}
cntlr = dev->sd.mmc.cntlr;
if (cntlr == NULL) {
HDF_LOGE("SdioDeviceDefaultReleaseHost: cntlr is NULL.");
return HDF_ERR_INVALID_OBJECT;
}
MmcCntlrUnlock(cntlr);
return HDF_SUCCESS;
}
static struct SdioDeviceOps g_sdioDefaultOps = {
.incrAddrReadBytes = SdioDeviceDefaultIncrAddrReadBytes,
.incrAddrWriteBytes = SdioDeviceDefaultIncrAddrWriteBytes,
.fixedAddrReadBytes = SdioDeviceDefaultFixedAddrReadBytes,
.fixedAddrWriteBytes = SdioDeviceDefaultFixedAddrWriteBytes,
.func0ReadBytes = SdioDeviceDefaultFunc0ReadBytes,
.func0WriteBytes = SdioDeviceDefaultFunc0WriteBytes,
.setBlockSize = SdioDeviceDefaultSetBlockSize,
.getCommonInfo = SdioDeviceDefaultGetCommonInfo,
.setCommonInfo = SdioDeviceDefaultSetCommonInfo,
.flushData = SdioDeviceDefaultFlushData,
.enableFunc = SdioDeviceDefaultEnableFunc,
.disableFunc = SdioDeviceDefaultDisableFunc,
.claimIrq = SdioDeviceDefaultClaimIrq,
.releaseIrq = SdioDeviceDefaultReleaseIrq,
.findFunc = SdioDeviceDefaultFindFunc,
.claimHost = SdioDeviceDefaultClaimHost,
.releaseHost = SdioDeviceDefaultReleaseHost,
};
int32_t SdioDeviceFindFunction(struct SdioDevice *sdio, struct SdioFunctionConfig *config)
{
if (sdio->sdioOps == NULL) {
HDF_LOGE("SdioDeviceFindFunction: ops is NULL.");
return HDF_ERR_INVALID_OBJECT;
}
if (sdio->sdioOps->findFunc == NULL) {
HDF_LOGE("SdioDeviceFindFunction: func is NULL.");
return HDF_FAILURE;
}
return sdio->sdioOps->findFunc(sdio, config);
}
int32_t SdioDeviceIncrAddrReadBytes(struct SdioDevice *sdio,
uint8_t *data, uint32_t addr, uint32_t size)
{
if (sdio->sdioOps == NULL) {
HDF_LOGE("SdioDeviceIncrAddrReadBytes: ops is NULL.");
return HDF_ERR_INVALID_OBJECT;
}
if (sdio->sdioOps->incrAddrReadBytes == NULL) {
HDF_LOGE("SdioDeviceIncrAddrReadBytes: incrAddrReadBytes is NULL.");
return HDF_FAILURE;
}
return sdio->sdioOps->incrAddrReadBytes(sdio, data, addr, size);
}
int32_t SdioDeviceIncrAddrWriteBytes(struct SdioDevice *sdio,
uint8_t *data, uint32_t addr, uint32_t size)
{
if (sdio->sdioOps == NULL) {
HDF_LOGE("SdioDeviceIncrAddrWriteBytes: ops is NULL.");
return HDF_ERR_INVALID_OBJECT;
}
if (sdio->sdioOps->incrAddrWriteBytes == NULL) {
HDF_LOGE("SdioDeviceIncrAddrWriteBytes: incrAddrWriteBytes is NULL.");
return HDF_FAILURE;
}
return sdio->sdioOps->incrAddrWriteBytes(sdio, data, addr, size);
}
int32_t SdioDeviceFixedAddrReadBytes(struct SdioDevice *sdio,
uint8_t *data, uint32_t addr, uint32_t size, uint32_t scatterLen)
{
if (sdio->sdioOps == NULL) {
HDF_LOGE("SdioDeviceFixedAddrReadBytes: ops is NULL.");
return HDF_ERR_INVALID_OBJECT;
}
if (sdio->sdioOps->fixedAddrReadBytes == NULL) {
HDF_LOGE("SdioDeviceFixedAddrReadBytes: fixedAddrReadBytes is NULL.");
return HDF_FAILURE;
}
return sdio->sdioOps->fixedAddrReadBytes(sdio, data, addr, size, scatterLen);
}
int32_t SdioDeviceFixedAddrWriteBytes(struct SdioDevice *sdio,
uint8_t *data, uint32_t addr, uint32_t size, uint32_t scatterLen)
{
if (sdio->sdioOps == NULL) {
HDF_LOGE("SdioDeviceFixedAddrWriteBytes: ops is NULL.");
return HDF_ERR_INVALID_OBJECT;
}
if (sdio->sdioOps->fixedAddrWriteBytes == NULL) {
HDF_LOGE("SdioDeviceFixedAddrWriteBytes: fixedAddrWriteBytes is NULL.");
return HDF_FAILURE;
}
return sdio->sdioOps->fixedAddrWriteBytes(sdio, data, addr, size, scatterLen);
}
int32_t SdioDeviceFunc0ReadBytes(struct SdioDevice *sdio,
uint8_t *data, uint32_t addr, uint32_t size)
{
if (sdio->sdioOps == NULL) {
HDF_LOGE("SdioDeviceFunc0ReadBytes: ops is NULL.");
return HDF_ERR_INVALID_OBJECT;
}
if (sdio->sdioOps->func0ReadBytes == NULL) {
HDF_LOGE("SdioDeviceFunc0ReadBytes: func0ReadBytes is NULL.");
return HDF_FAILURE;
}
return sdio->sdioOps->func0ReadBytes(sdio, data, addr, size);
}
int32_t SdioDeviceFunc0WriteBytes(struct SdioDevice *sdio,
uint8_t *data, uint32_t addr, uint32_t size)
{
if (sdio->sdioOps == NULL) {
HDF_LOGE("SdioDeviceFunc0WriteBytes: ops is NULL.");
return HDF_ERR_INVALID_OBJECT;
}
if (sdio->sdioOps->func0WriteBytes == NULL) {
HDF_LOGE("SdioDeviceFunc0WriteBytes: func0WriteBytes is NULL.");
return HDF_FAILURE;
}
return sdio->sdioOps->func0WriteBytes(sdio, data, addr, size);
}
int32_t SdioDeviceSetBlockSize(struct SdioDevice *sdio, uint32_t blockSize)
{
if (sdio->sdioOps == NULL) {
HDF_LOGE("SdioDeviceSetBlockSize: ops is NULL.");
return HDF_ERR_INVALID_OBJECT;
}
if (sdio->sdioOps->setBlockSize == NULL) {
HDF_LOGE("SdioDeviceSetBlockSize: setBlockSize is NULL.");
return HDF_FAILURE;
}
return sdio->sdioOps->setBlockSize(sdio, blockSize);
}
int32_t SdioDeviceGetCommonInfo(struct SdioDevice *sdio,
SdioCommonInfo *info, SdioCommonInfoType infoType)
{
if (sdio->sdioOps == NULL) {
HDF_LOGE("SdioDeviceGetCommonInfo: ops is NULL.");
return HDF_ERR_INVALID_OBJECT;
}
if (sdio->sdioOps->getCommonInfo == NULL) {
HDF_LOGE("SdioDeviceGetCommonInfo: getCommonInfo is NULL.");
return HDF_FAILURE;
}
return sdio->sdioOps->getCommonInfo(sdio, info, infoType);
}
int32_t SdioDeviceSetCommonInfo(struct SdioDevice *sdio,
SdioCommonInfo *info, SdioCommonInfoType infoType)
{
if (sdio->sdioOps == NULL) {
HDF_LOGE("SdioDeviceSetCommonInfo: ops is NULL.");
return HDF_ERR_INVALID_OBJECT;
}
if (sdio->sdioOps->setCommonInfo == NULL) {
HDF_LOGE("SdioDeviceSetCommonInfo: setCommonInfo is NULL.");
return HDF_FAILURE;
}
return sdio->sdioOps->setCommonInfo(sdio, info, infoType);
}
int32_t SdioDeviceFlushData(struct SdioDevice *sdio)
{
if (sdio->sdioOps == NULL) {
HDF_LOGE("SdioDeviceFlushData: ops is NULL.");
return HDF_ERR_INVALID_OBJECT;
}
if (sdio->sdioOps->flushData == NULL) {
HDF_LOGE("SdioDeviceFlushData: flushData is NULL.");
return HDF_FAILURE;
}
return sdio->sdioOps->flushData(sdio);
}
int32_t SdioDeviceClaimHost(struct SdioDevice *sdio)
{
if (sdio->sdioOps == NULL) {
HDF_LOGE("SdioDeviceClaimHost: cntlr is NULL.");
return HDF_ERR_INVALID_OBJECT;
}
if (sdio->sdioOps->claimHost != NULL) {
return sdio->sdioOps->claimHost(sdio);
}
return HDF_SUCCESS;
}
int32_t SdioDeviceReleaseHost(struct SdioDevice *sdio)
{
if (sdio->sdioOps == NULL) {
HDF_LOGE("SdioDeviceReleaseHost: cntlr is NULL.");
return HDF_ERR_INVALID_OBJECT;
}
if (sdio->sdioOps->releaseHost != NULL) {
return sdio->sdioOps->releaseHost(sdio);
}
return HDF_SUCCESS;
}
int32_t SdioDeviceEnableFunc(struct SdioDevice *sdio)
{
if (sdio->sdioOps == NULL) {
HDF_LOGE("SdioDeviceEnableFunc: ops is NULL.");
return HDF_ERR_INVALID_OBJECT;
}
if (sdio->sdioOps->enableFunc == NULL) {
HDF_LOGE("SdioDeviceEnableFunc: enableFunc is NULL.");
return HDF_FAILURE;
}
return sdio->sdioOps->enableFunc(sdio);
}
int32_t SdioDeviceDisableFunc(struct SdioDevice *sdio)
{
if (sdio->sdioOps == NULL) {
HDF_LOGE("SdioDeviceDisableFunc: ops is NULL.");
return HDF_ERR_INVALID_OBJECT;
}
if (sdio->sdioOps->disableFunc == NULL) {
HDF_LOGE("SdioDeviceDisableFunc: disableFunc is NULL.");
return HDF_FAILURE;
}
return sdio->sdioOps->disableFunc(sdio);
}
int32_t SdioDeviceClaimIrq(struct SdioDevice *sdio, SdioIrqHandler *irqHandler)
{
if (sdio->sdioOps == NULL) {
HDF_LOGE("SdioDeviceClaimIrq: ops is NULL.");
return HDF_ERR_INVALID_OBJECT;
}
if (sdio->sdioOps->claimIrq == NULL) {
HDF_LOGE("SdioDeviceClaimIrq: claimIrq is NULL.");
return HDF_FAILURE;
}
return sdio->sdioOps->claimIrq(sdio, irqHandler);
}
int32_t SdioDeviceReleaseIrq(struct SdioDevice *sdio)
{
if (sdio->sdioOps == NULL) {
HDF_LOGE("SdioDeviceReleaseIrq: ops is NULL.");
return HDF_ERR_INVALID_OBJECT;
}
if (sdio->sdioOps->releaseIrq == NULL) {
HDF_LOGE("SdioDeviceReleaseIrq: releaseIrq is NULL.");
return HDF_FAILURE;
}
return sdio->sdioOps->releaseIrq(sdio);
}
void SdioDeviceAddOps(struct SdioDevice *sdio, void *ops)
{
if (sdio == NULL) {
HDF_LOGE("SdioDeviceAddOps: sdio is NULL.");
return;
}
if (ops == NULL) {
sdio->sdioOps = &g_sdioDefaultOps;
HDF_LOGD("SdioDeviceAddOps: use default ops.");
} else {
sdio->sdioOps = (struct SdioDeviceOps *)ops;
}
}
+336
View File
@@ -0,0 +1,336 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#include "sdio_if.h"
#include "hdf_base.h"
#include "hdf_log.h"
#include "mmc_sdio.h"
#include "osal_mem.h"
#include "securec.h"
#define HDF_LOG_TAG sdio_if_c
static int32_t SdioDeviceGetFromHandle(DevHandle handle, struct SdioDevice **sdio)
{
struct MmcDevice *mmc = NULL;
if (handle == NULL) {
return HDF_ERR_INVALID_OBJECT;
}
if (sdio == NULL) {
return HDF_ERR_INVALID_PARAM;
}
mmc = MmcCntlrGetDevice((struct MmcCntlr *)handle);
if (mmc == NULL) {
return HDF_PLT_ERR_NO_DEV;
}
if (mmc->type != MMC_DEV_SDIO && mmc->type != MMC_DEV_COMBO) {
MmcDevicePut(mmc);
return HDF_PLT_ERR_DEV_TYPE;
}
*sdio = (struct SdioDevice *)mmc;
return HDF_SUCCESS;
}
DevHandle SdioOpen(int16_t mmcBusNum, struct SdioFunctionConfig *config)
{
int32_t ret;
struct MmcCntlr *cntlr = NULL;
struct SdioDevice *sdio = NULL;
DevHandle handle = NULL;
if (config == NULL) {
HDF_LOGE("SdioOpen: config can't be null!");
return NULL;
}
handle = MmcOpen(mmcBusNum);
if (handle == NULL) {
HDF_LOGE("SdioOpen: SdioGetCntlrByBusNum fail!");
return NULL;
}
cntlr = (struct MmcCntlr *)handle;
if (cntlr != NULL && cntlr->ops != NULL && cntlr->ops->rescanSdioDev != NULL) {
ret = cntlr->ops->rescanSdioDev(cntlr);
if (ret != HDF_SUCCESS) {
HDF_LOGE("SdioOpen: sdio rescan fail!");
MmcClose(handle);
return NULL;
}
}
ret = SdioDeviceGetFromHandle(handle, &sdio);
if (ret != HDF_SUCCESS) {
HDF_LOGE("SdioOpen: get sdio dev fail!");
MmcClose(handle);
return NULL;
}
ret = SdioDeviceFindFunction(sdio, config);
MmcDevicePut((struct MmcDevice *)sdio);
if (ret != HDF_SUCCESS) {
HDF_LOGE("SdioOpen: set function fail!");
MmcClose(handle);
return NULL;
}
return (DevHandle)cntlr;
}
void SdioClose(DevHandle handle)
{
(void)handle;
}
int32_t SdioReadBytes(DevHandle handle, uint8_t *data, uint32_t addr, uint32_t size)
{
int32_t ret;
struct SdioDevice *sdio = NULL;
ret = SdioDeviceGetFromHandle(handle, &sdio);
if (ret != HDF_SUCCESS) {
HDF_LOGE("SdioReadBytes: get sdio dev fail!");
return ret;
}
ret = SdioDeviceIncrAddrReadBytes(sdio, data, addr, size);
MmcDevicePut((struct MmcDevice *)sdio);
return ret;
}
int32_t SdioWriteBytes(DevHandle handle, uint8_t *data, uint32_t addr, uint32_t size)
{
int32_t ret;
struct SdioDevice *sdio = NULL;
ret = SdioDeviceGetFromHandle(handle, &sdio);
if (ret != HDF_SUCCESS) {
HDF_LOGE("SdioWriteBytes: get sdio dev fail!");
return ret;
}
ret = SdioDeviceIncrAddrWriteBytes(sdio, data, addr, size);
MmcDevicePut((struct MmcDevice *)sdio);
return ret;
}
int32_t SdioReadBytesFromFixedAddr(DevHandle handle, uint8_t *data,
uint32_t addr, uint32_t size, uint32_t scatterLen)
{
int32_t ret;
struct SdioDevice *sdio = NULL;
ret = SdioDeviceGetFromHandle(handle, &sdio);
if (ret != HDF_SUCCESS) {
HDF_LOGE("SdioReadBytesFromFixedAddr: get sdio dev fail!");
return ret;
}
ret = SdioDeviceFixedAddrReadBytes(sdio, data, addr, size, scatterLen);
MmcDevicePut((struct MmcDevice *)sdio);
return ret;
}
int32_t SdioWriteBytesToFixedAddr(DevHandle handle, uint8_t *data,
uint32_t addr, uint32_t size, uint32_t scatterLen)
{
int32_t ret;
struct SdioDevice *sdio = NULL;
ret = SdioDeviceGetFromHandle(handle, &sdio);
if (ret != HDF_SUCCESS) {
HDF_LOGE("SdioWriteBytesToFixedAddr: get sdio dev fail!");
return ret;
}
ret = SdioDeviceFixedAddrWriteBytes(sdio, data, addr, size, scatterLen);
MmcDevicePut((struct MmcDevice *)sdio);
return ret;
}
int32_t SdioReadBytesFromFunc0(DevHandle handle, uint8_t *data, uint32_t addr, uint32_t size)
{
int32_t ret;
struct SdioDevice *sdio = NULL;
ret = SdioDeviceGetFromHandle(handle, &sdio);
if (ret != HDF_SUCCESS) {
HDF_LOGE("SdioReadBytesFromFunc0: get sdio dev fail!");
return ret;
}
ret = SdioDeviceFunc0ReadBytes(sdio, data, addr, size);
MmcDevicePut((struct MmcDevice *)sdio);
return ret;
}
int32_t SdioWriteBytesToFunc0(DevHandle handle, uint8_t *data, uint32_t addr, uint32_t size)
{
int32_t ret;
struct SdioDevice *sdio = NULL;
ret = SdioDeviceGetFromHandle(handle, &sdio);
if (ret != HDF_SUCCESS) {
HDF_LOGE("SdioWriteBytesToFunc0: get sdio dev fail!");
return ret;
}
ret = SdioDeviceFunc0WriteBytes(sdio, data, addr, size);
MmcDevicePut((struct MmcDevice *)sdio);
return ret;
}
int32_t SdioSetBlockSize(DevHandle handle, uint32_t blockSize)
{
int32_t ret;
struct SdioDevice *sdio = NULL;
ret = SdioDeviceGetFromHandle(handle, &sdio);
if (ret != HDF_SUCCESS) {
HDF_LOGE("SdioSetBlockSize: get sdio dev fail!");
return ret;
}
ret = SdioDeviceSetBlockSize(sdio, blockSize);
MmcDevicePut((struct MmcDevice *)sdio);
return ret;
}
int32_t SdioGetCommonInfo(DevHandle handle, SdioCommonInfo *info, SdioCommonInfoType infoType)
{
int32_t ret;
struct SdioDevice *sdio = NULL;
ret = SdioDeviceGetFromHandle(handle, &sdio);
if (ret != HDF_SUCCESS) {
HDF_LOGE("SdioGetCommonInfo: get sdio dev fail!");
return ret;
}
ret = SdioDeviceGetCommonInfo(sdio, info, infoType);
MmcDevicePut((struct MmcDevice *)sdio);
return ret;
}
int32_t SdioSetCommonInfo(DevHandle handle, SdioCommonInfo *info, SdioCommonInfoType infoType)
{
int32_t ret;
struct SdioDevice *sdio = NULL;
ret = SdioDeviceGetFromHandle(handle, &sdio);
if (ret != HDF_SUCCESS) {
HDF_LOGE("SdioSetCommonInfo: get sdio dev fail!");
return ret;
}
ret = SdioDeviceSetCommonInfo(sdio, info, infoType);
MmcDevicePut((struct MmcDevice *)sdio);
return ret;
}
int32_t SdioFlushData(DevHandle handle)
{
int32_t ret;
struct SdioDevice *sdio = NULL;
ret = SdioDeviceGetFromHandle(handle, &sdio);
if (ret != HDF_SUCCESS) {
HDF_LOGE("SdioFlushData: get sdio dev fail!");
return ret;
}
ret = SdioDeviceFlushData(sdio);
MmcDevicePut((struct MmcDevice *)sdio);
return ret;
}
void SdioClaimHost(DevHandle handle)
{
int32_t ret;
struct SdioDevice *sdio = NULL;
ret = SdioDeviceGetFromHandle(handle, &sdio);
if (ret != HDF_SUCCESS) {
HDF_LOGE("SdioClaimHost: get sdio dev fail!");
return;
}
ret = SdioDeviceClaimHost(sdio);
if (ret != HDF_SUCCESS) {
HDF_LOGE("SdioClaimHost: claim host fail!");
}
MmcDevicePut((struct MmcDevice *)sdio);
}
void SdioReleaseHost(DevHandle handle)
{
int32_t ret;
struct SdioDevice *sdio = NULL;
ret = SdioDeviceGetFromHandle(handle, &sdio);
if (ret != HDF_SUCCESS) {
HDF_LOGE("SdioReleaseHost: get sdio dev fail!");
return;
}
ret = SdioDeviceReleaseHost(sdio);
if (ret != HDF_SUCCESS) {
HDF_LOGE("SdioReleaseHost: claim host fail!");
}
MmcDevicePut((struct MmcDevice *)sdio);
}
int32_t SdioEnableFunc(DevHandle handle)
{
int32_t ret;
struct SdioDevice *sdio = NULL;
ret = SdioDeviceGetFromHandle(handle, &sdio);
if (ret != HDF_SUCCESS) {
HDF_LOGE("SdioEnableFunc: get sdio dev fail!");
return ret;
}
ret = SdioDeviceEnableFunc(sdio);
MmcDevicePut((struct MmcDevice *)sdio);
return ret;
}
int32_t SdioDisableFunc(DevHandle handle)
{
int32_t ret;
struct SdioDevice *sdio = NULL;
ret = SdioDeviceGetFromHandle(handle, &sdio);
if (ret != HDF_SUCCESS) {
HDF_LOGE("SdioDisableFunc: get sdio dev fail!");
return ret;
}
ret = SdioDeviceDisableFunc(sdio);
MmcDevicePut((struct MmcDevice *)sdio);
return ret;
}
int32_t SdioClaimIrq(DevHandle handle, SdioIrqHandler *irqHandler)
{
int32_t ret;
struct SdioDevice *sdio = NULL;
ret = SdioDeviceGetFromHandle(handle, &sdio);
if (ret != HDF_SUCCESS) {
HDF_LOGE("SdioClaimIrq: get sdio dev fail!");
return ret;
}
ret = SdioDeviceClaimIrq(sdio, irqHandler);
MmcDevicePut((struct MmcDevice *)sdio);
return ret;
}
int32_t SdioReleaseIrq(DevHandle handle)
{
int32_t ret;
struct SdioDevice *sdio = NULL;
ret = SdioDeviceGetFromHandle(handle, &sdio);
if (ret != HDF_SUCCESS) {
HDF_LOGE("SdioReleaseIrq: get sdio dev fail!");
return ret;
}
ret = SdioDeviceReleaseIrq(sdio);
MmcDevicePut((struct MmcDevice *)sdio);
return ret;
}