diff --git a/.gitignore b/.gitignore
index d1606884fa9fc2c49467d620e7c6d2317ebfa5b1..48fd83b28816e46bab4cba422a93d96e7174fb7d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1 @@
-*.o
-*.a
-*.d
-*.cmd
tools/hc-gen/build
diff --git a/OAT.xml b/OAT.xml
index 9877bc288ecde98e25a2308039db22553168d4b0..3b80ed211f30e0b960ea3d5b0ad38b288076ce75 100644
--- a/OAT.xml
+++ b/OAT.xml
@@ -92,7 +92,7 @@ Note:If the text contains special characters, please escape them according to th
-
+
diff --git a/README.md b/README.md
index e182839b0bc0c7b5c3c00b5dfc67e5a1e2048bcf..51ce80a2812ea9bcbc5ae6ddec3c0dc09400cc03 100644
--- a/README.md
+++ b/README.md
@@ -112,7 +112,7 @@ void SampleDriverRelease(struct HdfDeviceObject *deviceObject)
}
```
-For details, see [HDF Overview](https://gitee.com/openharmony/docs/blob/master/en/device-dev/driver/hdf.md).
+For details, see [HDF Overview](https://gitee.com/openharmony/docs/blob/master/en/device-dev/driver/driver-hdf.md).
### Sensor
@@ -121,7 +121,7 @@ The sensor driver module is developed based on the HDF and supports functions su
- APIs for implementing sensor driver module capabilities: Implement the capabilities of registering, loading, and deregistering sensor drivers as well as detecting sensor device depending on the HDF, normalize APIs for sensor devices of the same type, and offer APIs for parsing register configurations, abstract APIs for bus access, and abstract platform APIs.
- APIs to be implemented by developers: Based on the HDF Configuration Source \(HCS\), implement differentiated configuration for sensors of the same type and serialized configuration of sensor device parameters, and offer APIs for some sensor device operations to simplify the sensor driver development.
-For details, see [Sensor Driver Overview](https://gitee.com/openharmony/docs/blob/master/en/device-dev/driver/sensor.md).
+For details, see [Sensor Driver Overview](https://gitee.com/openharmony/docs/blob/master/en/device-dev/driver/driver-peripherals-sensor-des.md).
### Display
@@ -130,7 +130,7 @@ The display driver model that is developed based on the HDF shields the differen
- APIs for implementing display driver module capabilities: Implement the Hardware Driver Interfaces \(HDIs\) and their adaptation with the chip platform. In addition, the kernel-mode driver abstracts the common services of the panel driver and provides capabilities of initializing the panel, obtaining the panel configuration, powering on/off the panel, and implementing the backlight control.
- APIs to be implemented by developers: Complete the board-level HCS configuration and private data configuration of the panel, or offer differentiated APIs for some components to ensure efficient development of the display driver.
-For details, see [LCD Overview](https://gitee.com/openharmony/docs/blob/master/en/device-dev/driver/lcd.md).
+For details, see [LCD Overview](https://gitee.com/openharmony/docs/blob/master/en/device-dev/driver/driver-peripherals-lcd-des.md).
### Input
@@ -139,7 +139,7 @@ The input driver model is developed based on the HDF, provides unified driver AP
- APIs for implementing input driver module capabilities: Implement the HDIs and provide capabilities of managing devices, controlling services, and reporting data. Besides, the input driver model provides a unified driver for different input devices and the capabilities of registering/unregistering an input device, reporting event data, parsing configuration, and loading a common driver.
- APIs to be implemented by developers: Based on the provided platform driver, add the device descriptions as well as private configuration of the input device and implement differentiated APIs to greatly shorten the time required for developing input drivers.
-For details, see [Touchscreen Overview](https://gitee.com/openharmony/docs/blob/master/en/device-dev/driver/touchscreen.md).
+For details, see [Touchscreen Overview](https://gitee.com/openharmony/docs/blob/master/en/device-dev/driver/driver-peripherals-touch-des.md).
### WLAN
@@ -148,7 +148,7 @@ The WLAN module is developed based on the HDF and supports cross-OS migration, c
- APIs for implementing WLAN driver module capabilities: Implement the APIs of the WLAN HDI layer and provide capabilities of setting/obtaining the MAC address, obtaining the feature type, and setting the transmit power for upper-layer input services, as well as the capabilities of creating/releasing a **WifiModule**, connecting to/disconnecting from a WLAN hotspot, and applying for/releasing a **NetBuf** for developers.
- APIs to be implemented by developers: Based on the provided platform driver, complete the board-level HCS configuration as well as the differentiated WLAN configuration, and offer APIs for initializing, deregistering, enabling, and disabling a network device.
-For details, see [WLAN Overview](https://gitee.com/openharmony/docs/blob/master/en/device-dev/driver/wlan.md).
+For details, see [WLAN Overview](https://gitee.com/openharmony/docs/blob/master/en/device-dev/driver/driver-peripherals-external-des.md).
## Repositories Involved
diff --git a/README_zh.md b/README_zh.md
index ecc7f41f82764057c57d27e6ea2339efb02d3569..4d41fde4d49caf79028fbba77fd38872f5da155c 100644
--- a/README_zh.md
+++ b/README_zh.md
@@ -112,7 +112,7 @@ void SampleDriverRelease(struct HdfDeviceObject *deviceObject)
}
```
-HDF驱动框架详细开发请参考[驱动开发指南](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/driver/HDF%E9%A9%B1%E5%8A%A8%E6%A1%86%E6%9E%B6.md)。
+HDF驱动框架详细开发请参考[驱动开发指南](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/driver/driver-hdf.md)。
### Sensor框架模型说明
@@ -121,7 +121,7 @@ HDF驱动框架详细开发请参考[驱动开发指南](https://gitee.com/openh
- Sensor驱动模型基础能力部分:依赖HDF驱动框架实现Sensor器件驱动的注册,加载,去注册,器件探测等能力,提供同一类型Sensor器件驱动归一接口, 寄存器配置解析操作接口,总线访问抽象接口,平台抽象接口。
- 开发者实现的部分:依赖HDF驱动框架的HCS\(**H**DF **C**onfiguration **S**ource\)配置管理,根据同类型Sensor差异化配置,实现Sensor器件参数序列化配置和器件部分操作接口,简化Sensor器件驱动开发。
-基于Sensor驱动模型开发Sensor器件驱动请参考[Sensor驱动开发指南](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/driver/SENSOR.md)。
+基于Sensor驱动模型开发Sensor器件驱动请参考[Sensor驱动开发指南](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/driver/driver-peripherals-sensor-des.md)。
### Display框架模型说明
@@ -130,7 +130,7 @@ HDF驱动框架详细开发请参考[驱动开发指南](https://gitee.com/openh
- Display驱动模型基础能力部分:包括HDI(**H**ardware **D**river **I**nterfaces)接口的定义及其实现框架,以及芯片平台对HDI接口的适配实现;内核驱动部分抽象了Panel驱动的公共业务,提供基础的Panel初始化、器件配置信息获取、上下电、背光设置等公共流程。
- 驱动开发者实现的部分:需要完成板级的HCS配置及Panel私有数据配置,或者实现部分器件差异化接口,保证显示屏驱动开发高效便捷。
-基于Display驱动模型开发LCD器件驱动请参考[LCD驱动开发指南](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/driver/LCD.md)。
+基于Display驱动模型开发LCD器件驱动请参考[LCD驱动开发指南](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/driver/driver-peripherals-lcd-des.md)。
### Input框架模型说明
@@ -139,7 +139,7 @@ HDF驱动框架详细开发请参考[驱动开发指南](https://gitee.com/openh
- Input驱动模型基础能力部分:包括Input HDI层的接口定义及公共实现,对上层输入服务提供设备管理、业务控制、数据上报等驱动能力接口;而Input驱动模型提供不同类型Input设备的归一化驱动, 包括输入设备的注册和注销、event数据的上报通道、配置信息的解析、公共驱动的加载等能力。
- 开发者实现的部分:根据驱动模型提供的平台驱动,需要完成设备描述配置及器件私有配置,以及实现预留的器件差异化接口,借由此驱动模型,可大幅缩减Input设备驱动的开发周期。
-基于Input驱动模型开发Touchscreen器件驱动请参考[Touchscreen驱动开发指南](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/driver/TOUCHSCREEN.md)。
+基于Input驱动模型开发Touchscreen器件驱动请参考[Touchscreen驱动开发指南](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/driver/driver-peripherals-touch-des.md)。
### WLAN框架模型说明
@@ -148,7 +148,7 @@ HDF驱动框架详细开发请参考[驱动开发指南](https://gitee.com/openh
- WLAN驱动模型基础能力部分:包括WLAN HDI层的接口定义及公共实现,对上层输入服务提供如设置MAC地址,获取设备的MAC地址,获取特性的类型,设置发射功率等能力;对驱动开发者提供创建/释放WifiModule,关联/取消关联,申请/释放NetBuf等能力。
- 驱动开发者实现的部分:根据驱动模型提供的平台驱动,需要完成板级的HCS配置及WLAN芯片的私有配置,以及实现预留的初始化/注销网络设备、打开/关闭网络设备等相关接口。
-基于WLAN驱动模型开发WLAN器件驱动请参考[WLAN驱动开发指南](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/driver/WLAN.md)。
+基于WLAN驱动模型开发WLAN器件驱动请参考[WLAN驱动开发指南](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/driver/driver-peripherals-external-des.md)。
## 相关仓
diff --git a/core/adapter/syscall/include/hdf_syscall_adapter.h b/core/adapter/syscall/include/hdf_syscall_adapter.h
index cb83b3f98ad98c3bfe1f2c1e93e31523984ccb36..6ee33c9353ce5e7faa48f15d455d72e49b8b2fcb 100644
--- a/core/adapter/syscall/include/hdf_syscall_adapter.h
+++ b/core/adapter/syscall/include/hdf_syscall_adapter.h
@@ -22,6 +22,7 @@ enum HdfDevListenerThreadStatus {
LISTENER_UNINITED = 0,
LISTENER_INITED,
LISTENER_EXITED,
+ LISTENER_STARTED,
LISTENER_RUNNING,
LISTENER_WAITING,
};
diff --git a/core/adapter/syscall/src/hdf_syscall_adapter.c b/core/adapter/syscall/src/hdf_syscall_adapter.c
index 908022746acc9deadeb4d375bef721f9a1460772..2759120dc6fdacb63d7613ae8b2bec7ebdb8f693 100644
--- a/core/adapter/syscall/src/hdf_syscall_adapter.c
+++ b/core/adapter/syscall/src/hdf_syscall_adapter.c
@@ -28,6 +28,7 @@
#define EVENT_READ_BUFF_MAX (20 * 1024) // 20k
#define SYSCALL_INVALID_FD (-1)
#define HDF_PFD_GROW_SIZE 4
+#define TIMEOUT_US 100000 // 100ms
static bool HaveOnlyOneElement(const struct DListHead *head)
{
@@ -162,7 +163,7 @@ static int32_t HdfDevEventReadAndDispatch(struct HdfDevListenerThread *thread, i
if (ret == -HDF_DEV_ERR_NODATA) {
ret = HDF_SUCCESS;
} else {
- HDF_LOGE("%s:ioctl failed, errno=%d\n", __func__, ret);
+ HDF_LOGE("%s:ioctl failed, errno=%d", __func__, ret);
}
goto finish;
@@ -217,6 +218,7 @@ static int32_t HdfDevEventListenTask(void *para)
uint16_t pfdSize = 0;
int32_t pollCount = 0;
+ thread->status = LISTENER_RUNNING;
while (!thread->shouldStop) {
if (thread->pollChanged) {
pollCount = AssignPfds(thread, &pfds, &pfdSize);
@@ -239,7 +241,6 @@ static int32_t HdfDevEventListenTask(void *para)
goto exit;
} else if (((uint32_t)pfds[i].revents) & POLLHUP) {
HDF_LOGI("event listener task received exit event");
- thread->shouldStop = true;
goto exit;
} else if (((uint32_t)pfds[i].revents) & POLLNVAL) {
OsalMSleep(1); // polled closed fd, yield to sync
@@ -268,7 +269,7 @@ static int32_t HdfAdapterStartListenIoctl(int fd)
{
int32_t ret = ioctl(fd, HDF_LISTEN_EVENT_START, 0);
if (ret) {
- HDF_LOGE("%s: failed to notify drv(%d) of start %d %s", __func__, fd, errno, strerror(errno));
+ HDF_LOGE("%s: failed to notify drv(%d) of start %d %{public}s", __func__, fd, errno, strerror(errno));
return HDF_ERR_IO;
}
@@ -279,7 +280,7 @@ static int32_t HdfAdapterStopListenIoctl(int fd)
{
int32_t ret = ioctl(fd, HDF_LISTEN_EVENT_STOP, 0);
if (ret) {
- HDF_LOGE("%s: failed to notify drv(%d) of stop %d %s", __func__, fd, errno, strerror(errno));
+ HDF_LOGE("%s: failed to notify drv(%d) of stop %d %{public}s", __func__, fd, errno, strerror(errno));
return HDF_ERR_IO;
}
@@ -290,10 +291,10 @@ static int32_t HdfAdapterExitListenIoctl(int fd)
{
int32_t ret = ioctl(fd, HDF_LISTEN_EVENT_EXIT, 0);
if (ret) {
- HDF_LOGE("%s: failed to notify drv(%d) of exit %d %s", __func__, fd, errno, strerror(errno));
+ HDF_LOGE("%s: failed to notify drv(%d) of exit %d %{public}s", __func__, fd, errno, strerror(errno));
return HDF_ERR_IO;
}
-
+ HDF_LOGD("ioctl send poll thread(%d) exit event, ret=%d", fd, ret);
return HDF_SUCCESS;
}
@@ -322,6 +323,7 @@ static int32_t HdfDevListenerThreadDoInit(struct HdfDevListenerThread *thread)
static int32_t HdfDevListenerThreadInit(struct HdfDevListenerThread *thread)
{
switch (thread->status) {
+ case LISTENER_STARTED: // fall-through
case LISTENER_RUNNING: // fall-through
case LISTENER_INITED: // fall-through
case LISTENER_WAITING:
@@ -410,7 +412,7 @@ static int32_t HdfListenThreadInitPollFds(struct HdfDevListenerThread *thread)
static int32_t HdfDevListenerThreadStart(struct HdfDevListenerThread *thread)
{
- if (thread->status == LISTENER_RUNNING) {
+ if (thread->status >= LISTENER_STARTED) {
return HDF_SUCCESS;
}
@@ -440,12 +442,12 @@ static int32_t HdfDevListenerThreadStart(struct HdfDevListenerThread *thread)
.stackSize = 0,
};
+ thread->status = LISTENER_STARTED;
if (OsalThreadStart(&thread->thread, &config) != HDF_SUCCESS) {
HDF_LOGE("%s:OsalThreadStart failed", __func__);
ret = HDF_FAILURE;
break;
}
- thread->status = LISTENER_RUNNING;
return HDF_SUCCESS;
} while (0);
@@ -505,7 +507,7 @@ static int32_t HdfListenThreadPollAdd(struct HdfDevListenerThread *thread, struc
DListInsertTail(&adapter->listNode, thread->adapterListPtr);
- if (thread->status != LISTENER_RUNNING) {
+ if (thread->status < LISTENER_STARTED) {
OsalMutexUnlock(&thread->mutex);
return HDF_SUCCESS;
}
@@ -524,7 +526,7 @@ static int32_t HdfListenThreadPollAdd(struct HdfDevListenerThread *thread, struc
if (headAdapter != NULL) {
if (ioctl(headAdapter->fd, HDF_LISTEN_EVENT_WAKEUP, 0) != 0) {
- HDF_LOGE("%s: failed to wakeup drv to add poll %d %s", __func__, errno, strerror(errno));
+ HDF_LOGE("%s: failed to wakeup drv to add poll %d %{public}s", __func__, errno, strerror(errno));
thread->pfds[index].fd = SYSCALL_INVALID_FD;
ret = HDF_ERR_IO;
break;
@@ -562,10 +564,7 @@ static void HdfListenThreadPollDel(struct HdfDevListenerThread *thread, struct
}
}
- if (HdfAdapterStopListenIoctl(adapter->fd)) {
- HDF_LOGE("%s: failed to stop device report %d %s", __func__, errno, strerror(errno));
- }
-
+ HdfAdapterStopListenIoctl(adapter->fd);
if (ioctl(adapter->fd, HDF_LISTEN_EVENT_WAKEUP, 0) != 0) {
HDF_LOGE("%s: failed to wakeup drv to del poll %d %s", __func__, errno, strerror(errno));
}
@@ -591,6 +590,7 @@ static void HdfDevListenerThreadDestroy(struct HdfDevListenerThread *thread)
switch (thread->status) {
case LISTENER_RUNNING: {
+ int count = 0;
uint32_t stopCount = 0;
OsalMutexLock(&thread->mutex);
thread->adapter = NULL;
@@ -598,21 +598,34 @@ static void HdfDevListenerThreadDestroy(struct HdfDevListenerThread *thread)
thread->listenerListPtr = NULL;
OsalMutexUnlock(&thread->mutex);
for (int i = 0; i < thread->pfdSize; i++) {
- if (thread->pfds[i].fd == SYSCALL_INVALID_FD) {
- continue;
- }
- if (HdfAdapterExitListenIoctl(thread->pfds[i].fd) == HDF_SUCCESS) {
+ if (thread->pfds[i].fd != SYSCALL_INVALID_FD &&
+ HdfAdapterExitListenIoctl(thread->pfds[i].fd) == HDF_SUCCESS) {
stopCount++;
}
+ thread->pfds[i].fd = SYSCALL_INVALID_FD;
}
if (stopCount == 0) {
thread->shouldStop = true;
HDF_LOGE("%s:failed to exit listener thread with ioctl, will go async way", __func__);
+ return;
+ }
+ while (thread->status != LISTENER_EXITED && count <= TIMEOUT_US) {
+ OsalUSleep(1);
+ count++;
+ }
+ if (thread->status == LISTENER_EXITED) {
+ HDF_LOGI("poll thread exited");
+ HdfDevListenerThreadFree(thread);
+ } else {
+ thread->shouldStop = true;
+ HDF_LOGE("wait poll thread exit timeout, async exit");
}
-
return;
}
+ case LISTENER_STARTED:
+ thread->shouldStop = true;
+ break;
case LISTENER_EXITED: // fall-through
case LISTENER_INITED:
HdfDevListenerThreadFree(thread);
@@ -685,11 +698,11 @@ struct HdfIoService *HdfIoServiceAdapterObtain(const char *serviceName)
if (realpath(devNodePath, realPath) == NULL) {
if (HdfLoadDriverByServiceName(serviceName) != HDF_SUCCESS) {
- HDF_LOGE("%s: load %s driver failed", __func__, serviceName);
+ HDF_LOGE("%s: load %{public}s driver failed", __func__, serviceName);
goto out;
}
if (realpath(devNodePath, realPath) == NULL) {
- HDF_LOGE("%s: file name %s is invalid", __func__, devNodePath);
+ HDF_LOGE("%s: file name %{public}s is invalid", __func__, devNodePath);
goto out;
}
}
@@ -709,7 +722,7 @@ struct HdfIoService *HdfIoServiceAdapterObtain(const char *serviceName)
adapter->fd = open(realPath, O_RDWR);
if (adapter->fd < 0) {
- HDF_LOGE("Open file node %s failed, (%d)%s", realPath, errno, strerror(errno));
+ HDF_LOGE("Open file node %{public}s failed, (%d)%{public}s", realPath, errno, strerror(errno));
OsalMutexDestroy(&adapter->mutex);
OsalMemFree(adapter);
goto out;
@@ -910,7 +923,7 @@ int32_t HdfIoServiceGroupRegisterListener(struct HdfIoServiceGroup *group, struc
}
}
DListInsertTail(&listener->listNode, &adapterGroup->listenerList);
- if (!DListIsEmpty(&adapterGroup->adapterList) && listenerThread->status != LISTENER_RUNNING) {
+ if (!DListIsEmpty(&adapterGroup->adapterList) && listenerThread->status < LISTENER_STARTED) {
ret = HdfDevListenerThreadStart(listenerThread);
if (ret != HDF_SUCCESS) {
DListRemove(&listener->listNode);
@@ -1011,7 +1024,7 @@ int32_t HdfIoServiceGroupAddService(struct HdfIoServiceGroup *group, struct HdfI
OsalMutexLock(&listenerThread->mutex);
if ((!DListIsEmpty(&adapterGroup->listenerList) || !DListIsEmpty(&adapter->listenerList)) &&
- listenerThread->status != LISTENER_RUNNING) {
+ listenerThread->status < LISTENER_STARTED) {
ret = HdfDevListenerThreadStart(adapterGroup->thread);
if (ret != HDF_SUCCESS) {
HdfListenThreadPollDel(adapterGroup->thread, adapter);
@@ -1046,17 +1059,6 @@ void HdfIoServiceGroupRemoveService(struct HdfIoServiceGroup *group, struct HdfI
adapter->group = NULL;
}
-static int DlistGetCount(const struct DListHead *head)
-{
- struct DListHead *next = head->next;
- int count = 0;
- while (next != head) {
- next = next->next;
- count++;
- }
- return count;
-}
-
int HdfIoserviceGetListenerCount(const struct HdfIoService *service)
{
if (service == NULL) {
diff --git a/core/adapter/vnode/src/hdf_vnode_adapter.c b/core/adapter/vnode/src/hdf_vnode_adapter.c
index 4694f1c5cef8b6865e67a962031d298f194f743e..340054fb397e49eecaf521783d497e00e8b67b5a 100644
--- a/core/adapter/vnode/src/hdf_vnode_adapter.c
+++ b/core/adapter/vnode/src/hdf_vnode_adapter.c
@@ -524,7 +524,10 @@ static unsigned int HdfVNodeAdapterPoll(struct file *filep, poll_table *wait)
{
unsigned int mask = 0;
struct HdfVNodeAdapterClient *client = (struct HdfVNodeAdapterClient *)OsalGetFilePriv(filep);
-
+ if (client == NULL) {
+ mask |= POLLERR;
+ return mask;
+ }
poll_wait(filep, &client->pollWait, wait);
OsalMutexLock(&client->mutex);
if (client->status == VNODE_CLIENT_EXITED) {
@@ -536,18 +539,21 @@ static unsigned int HdfVNodeAdapterPoll(struct file *filep, poll_table *wait)
client->wakeup--;
}
OsalMutexUnlock(&client->mutex);
+
return mask;
}
static int HdfVNodeAdapterClose(struct OsalCdev *cdev, struct file *filep)
{
+ struct HdfVNodeAdapterClient *client = NULL;
(void)cdev;
- struct HdfVNodeAdapterClient *client = (struct HdfVNodeAdapterClient *)OsalGetFilePriv(filep);
+ client = (struct HdfVNodeAdapterClient *)OsalGetFilePriv(filep);
if (client->ioServiceClient.device != NULL && client->ioServiceClient.device->service != NULL &&
client->ioServiceClient.device->service->Release != NULL) {
client->ioServiceClient.device->service->Release(&client->ioServiceClient);
}
HdfDestoryVNodeAdapterClient(client);
+ OsalSetFilePriv(filep, NULL);
return HDF_SUCCESS;
}
diff --git a/core/common/src/devmgr_service_start.c b/core/common/src/devmgr_service_start.c
index 6dbaa0741a4a4f9a2218b1cab383f59c413d1828..a1ceba2eee5530107605b2490cad53e48d7d5c58 100644
--- a/core/common/src/devmgr_service_start.c
+++ b/core/common/src/devmgr_service_start.c
@@ -22,7 +22,6 @@ static int g_isQuickLoad = DEV_MGR_SLOW_LOAD;
static void GetDeviceServiceNameByClass(DeviceClass deviceClass, struct HdfSBuf *reply)
{
- struct HdfSListIterator itHost;
struct HdfSListIterator itDeviceInfo;
struct HdfDeviceInfo *deviceInfo = NULL;
struct DevHostServiceClnt *hostClnt = NULL;
@@ -32,9 +31,7 @@ static void GetDeviceServiceNameByClass(DeviceClass deviceClass, struct HdfSBuf
}
HdfSbufFlush(reply);
- HdfSListIteratorInit(&itHost, &devMgrSvc->hosts);
- while (HdfSListIteratorHasNext(&itHost)) {
- hostClnt = (struct DevHostServiceClnt *)HdfSListIteratorNext(&itHost);
+ DLIST_FOR_EACH_ENTRY(hostClnt, &devMgrSvc->hosts, struct DevHostServiceClnt, node) {
HdfSListIteratorInit(&itDeviceInfo, hostClnt->deviceInfos);
while (HdfSListIteratorHasNext(&itDeviceInfo)) {
deviceInfo = (struct HdfDeviceInfo *)HdfSListIteratorNext(&itDeviceInfo);
@@ -56,6 +53,10 @@ int DeviceManagerDispatch(struct HdfObject *stub, int code, struct HdfSBuf *data
int32_t deviceClass = 0;
const char *svcName = NULL;
struct DevmgrService *devMgrSvc = (struct DevmgrService *)stub;
+ static struct SubscriberCallback callback = {
+ .deviceObject = NULL,
+ .OnServiceConnected = NULL,
+ };
if (data == NULL || devMgrSvc == NULL) {
HDF_LOGE("%s: input param is invalid", __func__);
return ret;
@@ -68,10 +69,6 @@ int DeviceManagerDispatch(struct HdfObject *stub, int code, struct HdfSBuf *data
HDF_LOGE("%s: get svc name is null", __func__);
break;
}
- static struct SubscriberCallback callback = {
- .deviceObject = NULL,
- .OnServiceConnected = NULL,
- };
ret = DevSvcManagerClntSubscribeService(svcName, callback);
break;
case DEVMGR_UNLOAD_SERVICE:
@@ -110,13 +107,14 @@ int DeviceManagerIsQuickLoad(void)
int DeviceManagerStart(void)
{
+ struct HdfIoService *ioService = NULL;
struct IDevmgrService *instance = DevmgrServiceGetInstance();
if (instance == NULL || instance->StartService == NULL) {
HDF_LOGE("device manager start failed, service instance is null");
return HDF_FAILURE;
}
- struct HdfIoService *ioService = HdfIoServicePublish(DEV_MGR_NODE, DEV_MGR_NODE_PERM);
+ ioService = HdfIoServicePublish(DEV_MGR_NODE, DEV_MGR_NODE_PERM);
if (ioService != NULL) {
static struct HdfIoDispatcher dispatcher = {
.Dispatch = DeviceManagerDispatch,
@@ -129,11 +127,12 @@ int DeviceManagerStart(void)
int DeviceManagerStartStep2()
{
+ struct DevmgrService *devMgrSvc = NULL;
if (DeviceManagerIsQuickLoad() == DEV_MGR_SLOW_LOAD) {
HDF_LOGW("%s: device manager is not set to QuickLoad mode", __func__);
return HDF_SUCCESS;
}
- struct DevmgrService *devMgrSvc = (struct DevmgrService *)DevmgrServiceGetInstance();
+ devMgrSvc = (struct DevmgrService *)DevmgrServiceGetInstance();
return DevmgrServiceLoadLeftDriver(devMgrSvc);
}
diff --git a/core/common/src/hdf_attribute.c b/core/common/src/hdf_attribute.c
index 83b609fd2519574ba2e4a60e80d3eeadee3aea2d..b6af3fe7c35a15b3492f2b2690572ffebe62c8c7 100644
--- a/core/common/src/hdf_attribute.c
+++ b/core/common/src/hdf_attribute.c
@@ -18,6 +18,9 @@
#include "hdf_log.h"
#include "osal_mem.h"
#include "securec.h"
+#ifdef LOSCFG_DRIVERS_HDF_USB_PNP_NOTIFY
+#include "usb_pnp_manager.h"
+#endif
#define ATTR_HOST_NAME "hostName"
#define ATTR_DEV_POLICY "policy"
@@ -63,11 +66,13 @@ const struct DeviceResourceNode *HdfGetRootNode(void)
static bool HdfHostListCompare(struct HdfSListNode *listEntryFirst, struct HdfSListNode *listEntrySecond)
{
+ struct HdfHostInfo *attrFirst = NULL;
+ struct HdfHostInfo *attrSecond = NULL;
if (listEntryFirst == NULL || listEntrySecond == NULL) {
return false;
}
- struct HdfHostInfo *attrFirst = (struct HdfHostInfo *)listEntryFirst;
- struct HdfHostInfo *attrSecond = (struct HdfHostInfo *)listEntrySecond;
+ attrFirst = (struct HdfHostInfo *)listEntryFirst;
+ attrSecond = (struct HdfHostInfo *)listEntrySecond;
return attrFirst->priority <= attrSecond->priority;
}
@@ -135,11 +140,13 @@ bool HdfAttributeManagerGetHostList(struct HdfSList *hostList)
static bool HdfDeviceListCompare(struct HdfSListNode *listEntryFirst, struct HdfSListNode *listEntrySecond)
{
+ struct HdfDeviceInfo *attrFirst = NULL;
+ struct HdfDeviceInfo *attrSecond = NULL;
if (listEntryFirst == NULL || listEntrySecond == NULL) {
return false;
}
- struct HdfDeviceInfo *attrFirst = (struct HdfDeviceInfo *)listEntryFirst;
- struct HdfDeviceInfo *attrSecond = (struct HdfDeviceInfo *)listEntrySecond;
+ attrFirst = (struct HdfDeviceInfo *)listEntryFirst;
+ attrSecond = (struct HdfDeviceInfo *)listEntrySecond;
return attrFirst->priority <= attrSecond->priority;
}
@@ -241,14 +248,16 @@ struct HdfSList *HdfAttributeManagerGetDeviceList(uint16_t hostId, const char *h
{
uint16_t deviceIdx = 0;
const struct DeviceResourceNode *hostNode = GetHostNode(hostName);
+ struct HdfSList *deviceList = NULL;
+ const struct DeviceResourceNode *device = NULL;
if (hostNode == NULL) {
return NULL;
}
- struct HdfSList *deviceList = (struct HdfSList *)OsalMemCalloc(sizeof(struct HdfSList));
+ deviceList = (struct HdfSList *)OsalMemCalloc(sizeof(struct HdfSList));
if (deviceList == NULL) {
return NULL;
}
- const struct DeviceResourceNode *device = hostNode->child;
+ device = hostNode->child;
while (device != NULL) {
const struct DeviceResourceNode *deviceNode = device->child;
while (deviceNode != NULL) {
@@ -273,11 +282,10 @@ struct HdfSList *HdfAttributeManagerGetDeviceList(uint16_t hostId, const char *h
deviceNode = deviceNode->sibling;
continue;
}
- deviceNodeInfo->deviceId = deviceIdx;
+ deviceNodeInfo->deviceId = deviceIdx++;
deviceNode = deviceNode->sibling;
}
device = device->sibling;
- deviceIdx++;
}
if (HdfSListCount(deviceList) == 0) {
OsalMemFree(deviceList);
@@ -286,24 +294,23 @@ struct HdfSList *HdfAttributeManagerGetDeviceList(uint16_t hostId, const char *h
return deviceList;
}
-bool HdfDeviceListAdd(const char *moduleName, const char *serviceName)
+bool HdfDeviceListAdd(const char *moduleName, const char *serviceName, const void *privateData)
{
- struct HdfSListIterator itHost;
struct HdfSListIterator itDeviceInfo;
struct HdfDeviceInfo *deviceInfo = NULL;
struct DevHostServiceClnt *hostClnt = NULL;
struct DevmgrService *devMgrSvc = (struct DevmgrService *)DevmgrServiceGetInstance();
+ struct HdfDeviceInfo *deviceNodeInfo = NULL;
+ char *svcName = NULL;
if (devMgrSvc == NULL || moduleName == NULL || serviceName == NULL) {
return false;
}
- struct HdfDeviceInfo *deviceNodeInfo = HdfDeviceInfoNewInstance();
+ deviceNodeInfo = HdfDeviceInfoNewInstance();
if (deviceNodeInfo == NULL) {
return false;
}
- HdfSListIteratorInit(&itHost, &devMgrSvc->hosts);
- while (HdfSListIteratorHasNext(&itHost)) {
- hostClnt = (struct DevHostServiceClnt *)HdfSListIteratorNext(&itHost);
+ DLIST_FOR_EACH_ENTRY(hostClnt, &devMgrSvc->hosts, struct DevHostServiceClnt, node) {
HdfSListIteratorInit(&itDeviceInfo, hostClnt->deviceInfos);
while (HdfSListIteratorHasNext(&itDeviceInfo)) {
deviceInfo = (struct HdfDeviceInfo *)HdfSListIteratorNext(&itDeviceInfo);
@@ -320,7 +327,7 @@ bool HdfDeviceListAdd(const char *moduleName, const char *serviceName)
deviceNodeInfo->permission = deviceInfo->permission;
deviceNodeInfo->deviceMatchAttr = deviceInfo->deviceMatchAttr;
deviceNodeInfo->moduleName = deviceInfo->moduleName;
- char *svcName = OsalMemCalloc(strlen(serviceName) + 1);
+ svcName = OsalMemCalloc(strlen(serviceName) + 1);
if (svcName == NULL) {
break;
}
@@ -330,6 +337,11 @@ bool HdfDeviceListAdd(const char *moduleName, const char *serviceName)
break;
}
deviceNodeInfo->svcName = svcName;
+#ifdef LOSCFG_DRIVERS_HDF_USB_PNP_NOTIFY
+ if (!UsbPnpManagerAddPrivateData(deviceNodeInfo, privateData)) {
+ break;
+ }
+#endif
HdfSListAdd(hostClnt->deviceInfos, &deviceNodeInfo->node);
hostClnt->devCount++;
return true;
@@ -342,7 +354,6 @@ bool HdfDeviceListAdd(const char *moduleName, const char *serviceName)
void HdfDeviceListDel(const char *moduleName, const char *serviceName)
{
- struct HdfSListIterator itHost;
struct HdfSListIterator itDeviceInfo;
struct HdfDeviceInfo *deviceInfo = NULL;
struct DevHostServiceClnt *hostClnt = NULL;
@@ -351,9 +362,7 @@ void HdfDeviceListDel(const char *moduleName, const char *serviceName)
return;
}
- HdfSListIteratorInit(&itHost, &devMgrSvc->hosts);
- while (HdfSListIteratorHasNext(&itHost)) {
- hostClnt = (struct DevHostServiceClnt *)HdfSListIteratorNext(&itHost);
+ DLIST_FOR_EACH_ENTRY(hostClnt, &devMgrSvc->hosts, struct DevHostServiceClnt, node) {
HdfSListIteratorInit(&itDeviceInfo, hostClnt->deviceInfos);
while (HdfSListIteratorHasNext(&itDeviceInfo)) {
deviceInfo = (struct HdfDeviceInfo *)HdfSListIteratorNext(&itDeviceInfo);
diff --git a/core/common/src/hdf_device_node_ext.c b/core/common/src/hdf_device_node_ext.c
index a8143a44132b635657c5d68af71a6a559c725c79..c0eab0d70f701da1a424a29224a7e3189f191db2 100644
--- a/core/common/src/hdf_device_node_ext.c
+++ b/core/common/src/hdf_device_node_ext.c
@@ -22,12 +22,12 @@ static int DeviceNodeExtDispatch(struct HdfObject *stub, int code, struct HdfSBu
struct IDeviceIoService *deviceMethod = NULL;
const struct HdfDeviceInfo *deviceInfo = NULL;
struct HdfDeviceNode *devNode = NULL;
+ uint64_t ioClientPtr = 0;
if (stub == NULL) {
HDF_LOGE("device ext dispatch: stub is null");
return HDF_FAILURE;
}
- uint64_t ioClientPtr = 0;
if (!HdfSbufReadUint64(reply, &ioClientPtr) || ioClientPtr == 0) {
HDF_LOGE("device ext dispatch: input ioClient is null");
return HDF_FAILURE;
@@ -59,10 +59,11 @@ static int DeviceNodeExtPublishService(struct HdfDeviceNode *inst, const char *s
const struct HdfDeviceInfo *deviceInfo = NULL;
struct HdfDeviceObject *deviceObject = NULL;
struct DeviceNodeExt *devNodeExt = (struct DeviceNodeExt *)inst;
+ int ret;
if (devNodeExt == NULL) {
return HDF_FAILURE;
}
- int ret = HdfDeviceNodePublishPublicService(inst, serviceName);
+ ret = HdfDeviceNodePublishPublicService(inst, serviceName);
if (ret != HDF_SUCCESS) {
HDF_LOGE("failed to publish device service, ret is %d", ret);
return HDF_FAILURE;
@@ -77,10 +78,10 @@ static int DeviceNodeExtPublishService(struct HdfDeviceNode *inst, const char *s
if (deviceInfo->policy == SERVICE_POLICY_CAPACITY) {
devNodeExt->ioService = HdfIoServicePublish(serviceName, deviceInfo->permission);
if (devNodeExt->ioService != NULL) {
- devNodeExt->ioService->target = (struct HdfObject*)(&inst->deviceObject);
static struct HdfIoDispatcher dispatcher = {
.Dispatch = DeviceNodeExtDispatch
};
+ devNodeExt->ioService->target = (struct HdfObject*)(&inst->deviceObject);
devNodeExt->ioService->dispatcher = &dispatcher;
} else {
HDF_LOGE("Device remote service bind failed");
diff --git a/core/common/src/load_driver_entry.c b/core/common/src/load_driver_entry.c
index 9a42ecbdc2b7c98342481ec1d0f2758be1c5f73d..165a7840fa00fff5c551e2c3dbf934cddb8797ec 100644
--- a/core/common/src/load_driver_entry.c
+++ b/core/common/src/load_driver_entry.c
@@ -13,18 +13,20 @@
static struct HdfDriverEntry *HdfDriverEntryConstruct(int32_t *driverCount)
{
int i;
+ struct HdfDriverEntry *driverEntry = NULL;
+ size_t *addrBegin = NULL;
*driverCount = (int32_t)(((uint8_t *)(HDF_DRIVER_END()) - (uint8_t *)(HDF_DRIVER_BEGIN())) / sizeof(size_t));
if (*driverCount <= 0) {
HDF_LOGE("%s: failed to hdf get device counts", __func__);
return NULL;
}
- struct HdfDriverEntry *driverEntry = OsalMemCalloc(*driverCount * sizeof(struct HdfDriverEntry));
+ driverEntry = OsalMemCalloc(*driverCount * sizeof(struct HdfDriverEntry));
if (driverEntry == NULL) {
HDF_LOGE("%s: failed to alloc driver entry mem", __func__);
*driverCount = 0;
return NULL;
}
- size_t *addrBegin = (size_t *)(HDF_DRIVER_BEGIN());
+ addrBegin = (size_t *)(HDF_DRIVER_BEGIN());
for (i = 0; i < *driverCount; i++) {
driverEntry[i] = *(struct HdfDriverEntry *)(*addrBegin);
addrBegin++;
@@ -35,12 +37,12 @@ static struct HdfDriverEntry *HdfDriverEntryConstruct(int32_t *driverCount)
struct HdfDriverEntry *HdfDriverLoaderGetDriverEntry(const struct HdfDeviceInfo *deviceInfo)
{
int i;
+ static struct HdfDriverEntry *driverEntry = NULL;
+ static int32_t driverCount = 0;
if ((deviceInfo == NULL) || (deviceInfo->moduleName == NULL) || (deviceInfo->svcName == NULL)) {
HDF_LOGE("%s: failed to get device entry, input deviceInfo is NULL", __func__);
return NULL;
}
- static struct HdfDriverEntry *driverEntry = NULL;
- static int32_t driverCount = 0;
if (driverEntry == NULL) {
driverEntry = HdfDriverEntryConstruct(&driverCount);
if (driverEntry == NULL) {
diff --git a/core/host/include/devsvc_manager_clnt.h b/core/host/include/devsvc_manager_clnt.h
index e164d8ae94ee78b4f709841435f44467b3358d13..ec7f7bec7a6a1502e694a7d72d2ac5296b00bf90 100644
--- a/core/host/include/devsvc_manager_clnt.h
+++ b/core/host/include/devsvc_manager_clnt.h
@@ -21,7 +21,7 @@ int DevSvcManagerClntAddService(const char *svcName, struct HdfDeviceObject *ser
void DevSvcManagerClntRemoveService(const char *svcName);
int DevSvcManagerClntSubscribeService(const char *svcName, struct SubscriberCallback callback);
int DevSvcManagerClntUnsubscribeService(const char *svcName);
-struct HdfDeviceObject *HdfRegisterDevice(const char *moduleName, const char *serviceName);
+struct HdfDeviceObject *HdfRegisterDevice(const char *moduleName, const char *serviceName, const void *privateData);
void HdfUnregisterDevice(const char *moduleName, const char *serviceName);
#endif /* DEVSVC_MANAGER_CLNT_H */
diff --git a/core/host/include/hdf_device.h b/core/host/include/hdf_device.h
index e15132a1dbd045e6981b60d4fcc0a2aa5109f63f..25e2a065077b5426a1c2b4519d46d20a3e62edf2 100644
--- a/core/host/include/hdf_device.h
+++ b/core/host/include/hdf_device.h
@@ -28,7 +28,7 @@ struct IHdfDevice {
struct HdfDevice {
struct IHdfDevice super;
struct DListHead node;
- struct HdfSList services;
+ struct DListHead devNodes;
uint16_t deviceId;
uint16_t hostId;
};
diff --git a/core/host/include/hdf_device_node.h b/core/host/include/hdf_device_node.h
index 87b9da5f5cd6134eae7bba5ec3a689af682b42fb..475158eada8f93249a2fd0a333b4eefa10b5fe0f 100644
--- a/core/host/include/hdf_device_node.h
+++ b/core/host/include/hdf_device_node.h
@@ -12,6 +12,7 @@
#include "hdf_device.h"
#include "hdf_device_info.h"
#include "hdf_device_desc.h"
+#include "hdf_dlist.h"
#include "hdf_pm.h"
struct HdfDeviceNode;
@@ -25,7 +26,7 @@ struct IDeviceNode {
struct HdfDeviceNode {
struct IDeviceNode super;
- struct HdfSListNode entry;
+ struct DListHead entry;
struct PowerStateToken *powerToken;
struct DevHostService *hostService;
struct HdfDeviceObject deviceObject;
@@ -42,7 +43,7 @@ void HdfDeviceNodeConstruct(struct HdfDeviceNode *service);
void HdfDeviceNodeDestruct(struct HdfDeviceNode *service);
struct HdfDeviceNode *HdfDeviceNodeNewInstance(void);
void HdfDeviceNodeFreeInstance(struct HdfDeviceNode *service);
-void HdfDeviceNodeDelete(struct HdfSListNode *deviceEntry);
+void HdfDeviceNodeDelete(struct HdfDeviceNode *devNode);
int HdfDeviceNodePublishPublicService(struct HdfDeviceNode *service, const char *svcName);
void HdfDeviceNodeReclaimService(const char *svcName);
diff --git a/core/host/include/power_state_token.h b/core/host/include/power_state_token.h
index f82d0a222ae463d2613bb46a04500516adc44520..327564494f3065dd59814ac7db4a2020677f2868 100644
--- a/core/host/include/power_state_token.h
+++ b/core/host/include/power_state_token.h
@@ -18,12 +18,12 @@ struct PowerStateToken {
const struct IPowerEventListener *listener;
struct HdfDeviceObject *deviceObject;
struct HdfSRef wakeRef;
- HdfPowerState state;
+ HdfPsmState psmState;
uint32_t mode;
};
struct PowerStateToken *PowerStateTokenNewInstance(
struct HdfDeviceObject *deviceObject, const struct IPowerEventListener *listener);
void PowerStateTokenFreeInstance(struct PowerStateToken *stateToken);
-int PowerStateOnSysStateChange(struct PowerStateToken *stateToken, int32_t state);
+int PowerStateChange(struct PowerStateToken *stateToken, uint32_t pEvent);
#endif /* POWER_STATE_TOKEN_H */
\ No newline at end of file
diff --git a/core/host/src/devhost_service.c b/core/host/src/devhost_service.c
index 15ebde7a0a45e948b9764d889bec4dca97c04ac4..984f6e6c2b64bc9802c139d70c41bcb56f998d8d 100644
--- a/core/host/src/devhost_service.c
+++ b/core/host/src/devhost_service.c
@@ -14,18 +14,19 @@
#include "hdf_log.h"
#include "hdf_object_manager.h"
#include "osal_mem.h"
+#include "power_state_token.h"
#define HDF_LOG_TAG devhost_service
-static struct HdfDevice *DevHostServiceFindDevice(struct DevHostService *inst, uint16_t deviceId)
+static struct HdfDevice *DevHostServiceFindDevice(struct DevHostService *hostService, uint16_t deviceId)
{
struct HdfDevice *deviceNode = NULL;
- if (inst == NULL) {
- HDF_LOGE("failed to find driver, inst is null");
+ if (hostService == NULL) {
+ HDF_LOGE("failed to find driver, hostService is null");
return NULL;
}
- DLIST_FOR_EACH_ENTRY(deviceNode, &inst->devices, struct HdfDevice, node) {
+ DLIST_FOR_EACH_ENTRY(deviceNode, &hostService->devices, struct HdfDevice, node) {
if (deviceNode->deviceId == deviceId) {
return deviceNode;
}
@@ -33,12 +34,12 @@ static struct HdfDevice *DevHostServiceFindDevice(struct DevHostService *inst, u
return NULL;
}
-static void DevHostServiceFreeDevice(struct DevHostService *inst, uint16_t deviceId)
+static void DevHostServiceFreeDevice(struct DevHostService *hostService, uint16_t deviceId)
{
- struct HdfDevice *deviceNode = DevHostServiceFindDevice(inst, deviceId);
- if (deviceNode != NULL) {
- DListRemove(&deviceNode->node);
- HdfDeviceFreeInstance(deviceNode);
+ struct HdfDevice *device = DevHostServiceFindDevice(hostService, deviceId);
+ if (device != NULL) {
+ DListRemove(&device->node);
+ HdfDeviceFreeInstance(device);
}
}
@@ -63,16 +64,16 @@ int DevHostServiceAddDevice(struct IDevHostService *inst, const struct HdfDevice
int ret = HDF_FAILURE;
struct HdfDevice *device = NULL;
struct HdfDeviceNode *devNode = NULL;
- struct DevHostService *hostService = (struct DevHostService *)inst;
+ struct DevHostService *hostService = CONTAINER_OF(inst, struct DevHostService, super);
struct IDriverLoader *driverLoader = HdfDriverLoaderGetInstance();
- if ((deviceInfo == NULL) || (driverLoader == NULL) || (driverLoader->LoadNode == NULL)) {
+ if (inst == NULL || deviceInfo == NULL || driverLoader == NULL || driverLoader->LoadNode == NULL) {
HDF_LOGE("failed to add device, input param is null");
return ret;
}
device = DevHostServiceGetDevice(hostService, deviceInfo->deviceId);
- if ((device == NULL) || (device->super.Attach == NULL)) {
+ if (device == NULL || device->super.Attach == NULL) {
ret = HDF_DEV_ERR_NO_DEVICE;
goto error;
}
@@ -90,24 +91,18 @@ int DevHostServiceAddDevice(struct IDevHostService *inst, const struct HdfDevice
return HDF_SUCCESS;
error:
- if (DListIsEmpty(&hostService->devices)) {
- DevHostServiceFreeDevice(hostService, hostService->hostId);
- }
+ DevHostServiceFreeDevice(hostService, device->deviceId);
return ret;
}
-static struct HdfDeviceNode *DevHostServiceGetDeviceNode(struct HdfSList *deviceNodes,
+static struct HdfDeviceNode *DevHostServiceSeparateDeviceNode(struct DListHead *deviceNodes,
const struct HdfDeviceInfo *deviceInfo)
{
- struct HdfSListIterator it;
struct HdfDeviceNode *deviceNode = NULL;
- HdfSListIteratorInit(&it, deviceNodes);
- while (HdfSListIteratorHasNext(&it)) {
- deviceNode = HDF_SLIST_CONTAINER_OF(
- struct HdfSListNode, HdfSListIteratorNext(&it), struct HdfDeviceNode, entry);
+ DLIST_FOR_EACH_ENTRY(deviceNode, deviceNodes, struct HdfDeviceNode, entry) {
if (strcmp(deviceNode->deviceInfo->svcName, deviceInfo->svcName) == 0 &&
strcmp(deviceNode->deviceInfo->moduleName, deviceInfo->moduleName) == 0) {
- HdfSListRemove(deviceNodes, &deviceNode->entry);
+ DListRemove(&deviceNode->entry);
return deviceNode;
}
}
@@ -119,6 +114,7 @@ int DevHostServiceDelDevice(struct IDevHostService *inst, const struct HdfDevice
struct HdfDevice *device = NULL;
struct DevHostService *hostService = (struct DevHostService *)inst;
struct IDriverLoader *driverLoader = HdfDriverLoaderGetInstance();
+ struct HdfDeviceNode *devNode = NULL;
if ((deviceInfo == NULL) || (driverLoader == NULL) || (driverLoader->UnLoadNode == NULL)) {
HDF_LOGE("failed to del device, input param is null");
@@ -132,14 +128,14 @@ int DevHostServiceDelDevice(struct IDevHostService *inst, const struct HdfDevice
}
driverLoader->UnLoadNode(driverLoader, deviceInfo);
- struct HdfDeviceNode *devNode = DevHostServiceGetDeviceNode(&device->services, deviceInfo);
+ devNode = DevHostServiceSeparateDeviceNode(&device->devNodes, deviceInfo);
if (device->super.Detach != NULL) {
device->super.Detach(&device->super, devNode);
} else {
HdfDeviceNodeFreeInstance(devNode);
}
DevSvcManagerClntRemoveService(deviceInfo->svcName);
- if (HdfSListIsEmpty(&device->services)) {
+ if (DListIsEmpty(&device->devNodes)) {
DevHostServiceFreeDevice(hostService, device->deviceId);
}
return HDF_SUCCESS;
@@ -155,6 +151,64 @@ static int DevHostServiceStartService(struct IDevHostService *service)
return DevmgrServiceClntAttachDeviceHost(hostService->hostId, service);
}
+static int ApplyDevicesPowerState(struct HdfDevice *device, uint32_t state)
+{
+ struct HdfDeviceNode *deviceNode = NULL;
+ int ret = HDF_SUCCESS;
+
+ /* The power management strategy is to ignore devices that fail to
+ operate and avoid more devices that fail to sleep or wake up */
+ if (IsPowerWakeState(state)) {
+ DLIST_FOR_EACH_ENTRY(deviceNode, &device->devNodes, struct HdfDeviceNode, entry) {
+ if (deviceNode->powerToken != NULL) {
+ ret = PowerStateChange(deviceNode->powerToken, state);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("device %s failed to resume(%d)", deviceNode->driverEntry->moduleName, state);
+ }
+ }
+ }
+ } else {
+ DLIST_FOR_EACH_ENTRY_REVERSE(deviceNode, &device->devNodes, struct HdfDeviceNode, entry) {
+ if (deviceNode->powerToken != NULL) {
+ ret = PowerStateChange(deviceNode->powerToken, state);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("device %s failed to suspend(%d)", deviceNode->driverEntry->moduleName, state);
+ }
+ }
+ }
+ }
+
+ return HDF_SUCCESS;
+}
+
+static int DevHostServicePmNotify(struct IDevHostService *service, uint32_t state)
+{
+ struct HdfDevice *device = NULL;
+ int ret = HDF_SUCCESS;
+ struct DevHostService *hostService = CONTAINER_OF(service, struct DevHostService, super);
+ if (hostService == NULL) {
+ HDF_LOGE("failed to start device service, hostService is null");
+ return HDF_FAILURE;
+ }
+
+ HDF_LOGD("host(%s) set power state=%u", hostService->hostName, state);
+ if (IsPowerWakeState(state)) {
+ DLIST_FOR_EACH_ENTRY_REVERSE(device, &hostService->devices, struct HdfDevice, node) {
+ if (ApplyDevicesPowerState(device, state) != HDF_SUCCESS) {
+ ret = HDF_FAILURE;
+ }
+ }
+ } else {
+ DLIST_FOR_EACH_ENTRY(device, &hostService->devices, struct HdfDevice, node) {
+ if (ApplyDevicesPowerState(device, state) != HDF_SUCCESS) {
+ ret = HDF_FAILURE;
+ }
+ }
+ }
+
+ return ret;
+}
+
void DevHostServiceConstruct(struct DevHostService *service)
{
struct IDevHostService *hostServiceIf = &service->super;
@@ -162,6 +216,7 @@ void DevHostServiceConstruct(struct DevHostService *service)
hostServiceIf->AddDevice = DevHostServiceAddDevice;
hostServiceIf->DelDevice = DevHostServiceDelDevice;
hostServiceIf->StartService = DevHostServiceStartService;
+ hostServiceIf->PmNotify = DevHostServicePmNotify;
DListHeadInit(&service->devices);
HdfServiceObserverConstruct(&service->observer);
}
@@ -169,12 +224,12 @@ void DevHostServiceConstruct(struct DevHostService *service)
void DevHostServiceDestruct(struct DevHostService *service)
{
+ struct HdfDevice *device = NULL;
+ struct HdfDevice *tmp = NULL;
if (service == NULL) {
return;
}
- struct HdfDevice *device = NULL;
- struct HdfDevice *tmp = NULL;
DLIST_FOR_EACH_ENTRY_SAFE(device, tmp, &service->devices, struct HdfDevice, node) {
HdfDeviceFreeInstance(device);
}
@@ -216,4 +271,3 @@ void DevHostServiceFreeInstance(struct IDevHostService *service)
HdfObjectManagerFreeObject(&service->object);
}
}
-
diff --git a/core/host/src/devsvc_manager_clnt.c b/core/host/src/devsvc_manager_clnt.c
index 7dd4aef7f00542e47668be6a066ca84b4d3d8445..3cce4a59c66d4f008b12e92fb629adeb7a1c890c 100644
--- a/core/host/src/devsvc_manager_clnt.c
+++ b/core/host/src/devsvc_manager_clnt.c
@@ -19,12 +19,13 @@
int DevSvcManagerClntAddService(const char *svcName, struct HdfDeviceObject *service)
{
struct DevSvcManagerClnt *devSvcMgrClnt = DevSvcManagerClntGetInstance();
+ struct IDevSvcManager *serviceManager = NULL;
if (devSvcMgrClnt == NULL) {
HDF_LOGE("failed to add service, client is null");
return HDF_FAILURE;
}
- struct IDevSvcManager *serviceManager = devSvcMgrClnt->devSvcMgrIf;
+ serviceManager = devSvcMgrClnt->devSvcMgrIf;
if (serviceManager == NULL || serviceManager->AddService == NULL) {
HDF_LOGE("serviceManager AddService function is null");
return HDF_FAILURE;
@@ -35,12 +36,13 @@ int DevSvcManagerClntAddService(const char *svcName, struct HdfDeviceObject *ser
const struct HdfObject *DevSvcManagerClntGetService(const char *svcName)
{
struct DevSvcManagerClnt *devSvcMgrClnt = DevSvcManagerClntGetInstance();
+ struct IDevSvcManager *serviceManager = NULL;
if (devSvcMgrClnt == NULL) {
HDF_LOGE("failed to get service, client is null");
return NULL;
}
- struct IDevSvcManager *serviceManager = devSvcMgrClnt->devSvcMgrIf;
+ serviceManager = devSvcMgrClnt->devSvcMgrIf;
if (serviceManager == NULL || serviceManager->GetService == NULL) {
HDF_LOGE("serviceManager GetService function is null");
return NULL;
@@ -51,12 +53,13 @@ const struct HdfObject *DevSvcManagerClntGetService(const char *svcName)
struct HdfDeviceObject *DevSvcManagerClntGetDeviceObject(const char *svcName)
{
struct DevSvcManagerClnt *devSvcMgrClnt = DevSvcManagerClntGetInstance();
+ struct IDevSvcManager *serviceManager = NULL;
if (devSvcMgrClnt == NULL) {
HDF_LOGE("failed to get device object, client is null");
return NULL;
}
- struct IDevSvcManager *serviceManager = devSvcMgrClnt->devSvcMgrIf;
+ serviceManager = devSvcMgrClnt->devSvcMgrIf;
if (serviceManager == NULL || serviceManager->GetObject == NULL) {
HDF_LOGE("failed to get device object, method not implement");
return NULL;
@@ -64,10 +67,10 @@ struct HdfDeviceObject *DevSvcManagerClntGetDeviceObject(const char *svcName)
return serviceManager->GetObject(serviceManager, svcName);
}
-struct HdfDeviceObject *HdfRegisterDevice(const char *moduleName, const char *serviceName)
+struct HdfDeviceObject *HdfRegisterDevice(const char *moduleName, const char *serviceName, const void *privateData)
{
int ret;
- if (!HdfDeviceListAdd(moduleName, serviceName)) {
+ if (!HdfDeviceListAdd(moduleName, serviceName, privateData)) {
HDF_LOGE("%s device info add failed!", __func__);
return NULL;
}
@@ -91,12 +94,13 @@ void HdfUnregisterDevice(const char *moduleName, const char *serviceName)
int DevSvcManagerClntSubscribeService(const char *svcName, struct SubscriberCallback callback)
{
struct DevSvcManagerClnt *devSvcMgrClnt = DevSvcManagerClntGetInstance();
+ struct IDevSvcManager *serviceManager = NULL;
if (devSvcMgrClnt == NULL) {
HDF_LOGE("failed to subscribe service, client is null");
return HDF_FAILURE;
}
- struct IDevSvcManager *serviceManager = devSvcMgrClnt->devSvcMgrIf;
+ serviceManager = devSvcMgrClnt->devSvcMgrIf;
if (serviceManager == NULL || serviceManager->SubscribeService == NULL) {
HDF_LOGE("failed to subscribe service, method not implement");
return HDF_FAILURE;
@@ -107,12 +111,13 @@ int DevSvcManagerClntSubscribeService(const char *svcName, struct SubscriberCall
int DevSvcManagerClntUnsubscribeService(const char *svcName)
{
struct DevSvcManagerClnt *devSvcMgrClnt = DevSvcManagerClntGetInstance();
+ struct IDevSvcManager *serviceManager = NULL;
if (devSvcMgrClnt == NULL) {
HDF_LOGE("failed to unsubscribe service, client is null");
return HDF_FAILURE;
}
- struct IDevSvcManager *serviceManager = devSvcMgrClnt->devSvcMgrIf;
+ serviceManager = devSvcMgrClnt->devSvcMgrIf;
if (serviceManager == NULL || serviceManager->UnsubscribeService == NULL) {
HDF_LOGE("failed to unsubscribe service, method not implement");
return HDF_FAILURE;
@@ -123,12 +128,13 @@ int DevSvcManagerClntUnsubscribeService(const char *svcName)
void DevSvcManagerClntRemoveService(const char *svcName)
{
struct DevSvcManagerClnt *devSvcMgrClnt = DevSvcManagerClntGetInstance();
+ struct IDevSvcManager *serviceManager = NULL;
if (devSvcMgrClnt == NULL) {
HDF_LOGE("failed to remove service, devSvcMgrClnt is null");
return;
}
- struct IDevSvcManager *serviceManager = devSvcMgrClnt->devSvcMgrIf;
+ serviceManager = devSvcMgrClnt->devSvcMgrIf;
if (serviceManager == NULL || serviceManager->RemoveService == NULL) {
HDF_LOGE("failed to remove service, method not implement");
return;
diff --git a/core/host/src/hdf_device.c b/core/host/src/hdf_device.c
index 3fc557001957da4194cd749f200a7101bda60fa3..d61036007dacfdc41726ca361f5187fb5182b04a 100644
--- a/core/host/src/hdf_device.c
+++ b/core/host/src/hdf_device.c
@@ -26,19 +26,23 @@ static int HdfDeviceAttach(struct IHdfDevice *devInst, struct HdfDeviceNode *dev
HDF_LOGE("failed to attach device, input params invalid");
return HDF_ERR_INVALID_PARAM;
}
- HdfSListAdd(&device->services, &devNode->entry);
+ DListInsertTail(&devNode->entry, &device->devNodes);
return nodeIf->LaunchNode(devNode, devInst);
}
void HdfDeviceConstruct(struct HdfDevice *device)
{
device->super.Attach = HdfDeviceAttach;
- HdfSListInit(&device->services);
+ DListHeadInit(&device->devNodes);
}
void HdfDeviceDestruct(struct HdfDevice *device)
{
- HdfSListFlush(&device->services, HdfDeviceNodeDelete);
+ struct HdfDeviceNode *devNode = NULL;
+ DLIST_FOR_EACH_ENTRY(devNode, &device->devNodes, struct HdfDeviceNode, entry) {
+ HdfDeviceNodeDelete(devNode);
+ }
+ DListHeadInit(&device->devNodes);
}
struct HdfObject *HdfDeviceCreate()
@@ -68,7 +72,7 @@ struct HdfDevice *HdfDeviceNewInstance()
void HdfDeviceFreeInstance(struct HdfDevice *device)
{
if (device != NULL) {
- HdfObjectManagerFreeObject((struct HdfObject *)device);
+ HdfObjectManagerFreeObject(&device->super.object);
}
}
diff --git a/core/host/src/hdf_device_node.c b/core/host/src/hdf_device_node.c
index 793da0d6a3440ee0e9bc0d177a864da953986594..f08c2539410b908cd71d08ad90d7fc24b9133706 100644
--- a/core/host/src/hdf_device_node.c
+++ b/core/host/src/hdf_device_node.c
@@ -25,11 +25,12 @@ static int HdfDeviceNodePublishLocalService(
struct HdfDeviceNode *devNode, const struct HdfDeviceInfo *deviceInfo)
{
uint32_t matchId;
+ struct DevHostService *hostService = NULL;
if ((devNode == NULL) || (deviceInfo == NULL)) {
HDF_LOGE("failed to publish local service, device is null");
return HDF_FAILURE;
}
- struct DevHostService *hostService = devNode->hostService;
+ hostService = devNode->hostService;
if (hostService == NULL) {
HDF_LOGE("failed to publish local service, host service is null");
return HDF_FAILURE;
@@ -42,15 +43,16 @@ static int HdfDeviceNodePublishLocalService(
static int HdfDeviceNodePublishService(
struct HdfDeviceNode *devNode, const struct HdfDeviceInfo *deviceInfo, struct IHdfDevice *device)
{
- (void)device;
int status = HDF_SUCCESS;
+ struct IDeviceNode *nodeIf = NULL;
+ (void)device;
if ((deviceInfo->policy == SERVICE_POLICY_NONE) ||
((deviceInfo->svcName != NULL) && (strlen(deviceInfo->svcName) == 0))) {
HDF_LOGI("policy is %d", SERVICE_POLICY_NONE);
return status;
}
- struct IDeviceNode *nodeIf = &devNode->super;
+ nodeIf = &devNode->super;
if ((deviceInfo->policy == SERVICE_POLICY_PUBLIC) ||
(deviceInfo->policy == SERVICE_POLICY_CAPACITY)) {
if (nodeIf->PublishService != NULL) {
@@ -66,15 +68,17 @@ static int HdfDeviceNodePublishService(
int HdfDeviceLaunchNode(struct HdfDeviceNode *devNode, struct IHdfDevice *devInst)
{
struct HdfDevice *device = (struct HdfDevice *)devInst;
+ struct HdfDriverEntry *driverEntry = NULL;
+ const struct HdfDeviceInfo *deviceInfo = NULL;
+ struct IHdfDeviceToken *deviceToken = NULL;
+ int ret;
if (device == NULL || devNode == NULL) {
HDF_LOGE("failed to launch service, device or service is null");
return HDF_ERR_INVALID_PARAM;
}
- struct HdfDriverEntry *driverEntry = devNode->driverEntry;
- const struct HdfDeviceInfo *deviceInfo = devNode->deviceInfo;
- struct IHdfDeviceToken *deviceToken = NULL;
-
+ driverEntry = devNode->driverEntry;
+ deviceInfo = devNode->deviceInfo;
if (deviceInfo == NULL) {
HDF_LOGE("failed to launch service, deviceInfo is null");
return HDF_ERR_INVALID_PARAM;
@@ -84,26 +88,17 @@ int HdfDeviceLaunchNode(struct HdfDeviceNode *devNode, struct IHdfDevice *devIns
HDF_LOGE("failed to launch service, deviceEntry invalid");
return HDF_ERR_INVALID_PARAM;
}
- int ret = driverEntry->Init(&devNode->deviceObject);
+ ret = driverEntry->Init(&devNode->deviceObject);
if (ret != HDF_SUCCESS) {
- if (driverEntry->Release != NULL) {
- driverEntry->Release(&devNode->deviceObject);
- }
return HDF_DEV_ERR_DEV_INIT_FAIL;
}
ret = HdfDeviceNodePublishService(devNode, deviceInfo, devInst);
if (ret != HDF_SUCCESS) {
- if (driverEntry->Release != NULL) {
- driverEntry->Release(&devNode->deviceObject);
- }
return HDF_DEV_ERR_PUBLISH_FAIL;
}
deviceToken = devNode->token;
ret = DevmgrServiceClntAttachDevice(deviceInfo, deviceToken);
if (ret != HDF_SUCCESS) {
- if (driverEntry->Release != NULL) {
- driverEntry->Release(&devNode->deviceObject);
- }
return HDF_DEV_ERR_ATTACHDEV_FAIL;
}
return ret;
@@ -179,13 +174,15 @@ void HdfDeviceNodeFreeInstance(struct HdfDeviceNode *devNode)
HdfObjectManagerFreeObject((struct HdfObject *) devNode);
}
-void HdfDeviceNodeDelete(struct HdfSListNode *deviceEntry)
+void HdfDeviceNodeDelete(struct HdfDeviceNode *devNode)
{
- if (deviceEntry == NULL) {
+ if (devNode == NULL) {
return;
}
- struct HdfDeviceNode *devNode =
- HDF_SLIST_CONTAINER_OF(struct HdfSListNode, deviceEntry, struct HdfDeviceNode, entry);
+
+ if (devNode->driverEntry->Release != NULL) {
+ devNode->driverEntry->Release(&devNode->deviceObject);
+ }
HdfDeviceNodeFreeInstance(devNode);
}
diff --git a/core/host/src/hdf_device_object.c b/core/host/src/hdf_device_object.c
index 832b11d8e9fb2e308f928e40d1cca6df3a5d9baa..6ab710031a9dd1093ad659f23f67a2f6934f483b 100644
--- a/core/host/src/hdf_device_object.c
+++ b/core/host/src/hdf_device_object.c
@@ -22,11 +22,12 @@ int32_t HdfDeviceSubscribeService(
uint32_t matchId;
struct DevHostService *hostService = NULL;
const struct HdfDeviceInfo *deviceInfo = NULL;
+ struct HdfDeviceNode *devNode = NULL;
if (deviceObject == NULL || serviceName == NULL) {
HDF_LOGE("failed to subscribe service, deviceObject/serviceName is null");
return HDF_FAILURE;
}
- struct HdfDeviceNode *devNode = (struct HdfDeviceNode *)HDF_SLIST_CONTAINER_OF(
+ devNode = (struct HdfDeviceNode *)HDF_SLIST_CONTAINER_OF(
struct HdfDeviceObject, deviceObject, struct HdfDeviceNode, deviceObject);
hostService = devNode->hostService;
if (hostService == NULL) {
@@ -44,13 +45,15 @@ int32_t HdfDeviceSubscribeService(
const char *HdfDeviceGetServiceName(const struct HdfDeviceObject *deviceObject)
{
+ struct HdfDeviceNode *devNode = NULL;
+ const struct HdfDeviceInfo *deviceInfo = NULL;
if (deviceObject == NULL) {
HDF_LOGE("failed to get service name, deviceObject is invalid");
return NULL;
}
- struct HdfDeviceNode *devNode = (struct HdfDeviceNode *)HDF_SLIST_CONTAINER_OF(
+ devNode = (struct HdfDeviceNode *)HDF_SLIST_CONTAINER_OF(
struct HdfDeviceObject, deviceObject, struct HdfDeviceNode, deviceObject);
- const struct HdfDeviceInfo *deviceInfo = devNode->deviceInfo;
+ deviceInfo = devNode->deviceInfo;
if (deviceInfo == NULL) {
HDF_LOGE("failed to get service name, deviceInfo is null");
return NULL;
@@ -60,33 +63,37 @@ const char *HdfDeviceGetServiceName(const struct HdfDeviceObject *deviceObject)
int HdfPmRegisterPowerListener(struct HdfDeviceObject *deviceObject, const struct IPowerEventListener *listener)
{
+ struct HdfDeviceNode *devNode = NULL;
if (deviceObject == NULL) {
return HDF_ERR_INVALID_PARAM;
}
- struct HdfDeviceNode *devNode = (struct HdfDeviceNode *)HDF_SLIST_CONTAINER_OF(
+ devNode = (struct HdfDeviceNode *)HDF_SLIST_CONTAINER_OF(
struct HdfDeviceObject, deviceObject, struct HdfDeviceNode, deviceObject);
return HdfDeviceNodeAddPowerStateListener(devNode, listener);
}
void HdfPmUnregisterPowerListener(struct HdfDeviceObject *deviceObject, const struct IPowerEventListener *listener)
{
+ struct HdfDeviceNode *devNode = NULL;
if (deviceObject == NULL) {
return;
}
- struct HdfDeviceNode *devNode = (struct HdfDeviceNode *)HDF_SLIST_CONTAINER_OF(
+ devNode = (struct HdfDeviceNode *)HDF_SLIST_CONTAINER_OF(
struct HdfDeviceObject, deviceObject, struct HdfDeviceNode, deviceObject);
HdfDeviceNodeRemovePowerStateListener(devNode, listener);
}
void HdfPmAcquireDevice(struct HdfDeviceObject *deviceObject)
{
+ struct HdfDeviceNode *devNode = NULL;
+ struct IPowerStateToken *tokenIf = NULL;
if (deviceObject == NULL) {
HDF_LOGE("%s: input param is invalid", __func__);
return;
}
- struct HdfDeviceNode *devNode = (struct HdfDeviceNode *)HDF_SLIST_CONTAINER_OF(
+ devNode = (struct HdfDeviceNode *)HDF_SLIST_CONTAINER_OF(
struct HdfDeviceObject, deviceObject, struct HdfDeviceNode, deviceObject);
- struct IPowerStateToken *tokenIf = (struct IPowerStateToken *)devNode->powerToken;
+ tokenIf = (struct IPowerStateToken *)devNode->powerToken;
if ((tokenIf != NULL) && (tokenIf->AcquireWakeLock != NULL)) {
tokenIf->AcquireWakeLock(tokenIf);
}
@@ -94,13 +101,15 @@ void HdfPmAcquireDevice(struct HdfDeviceObject *deviceObject)
void HdfPmReleaseDevice(struct HdfDeviceObject *deviceObject)
{
+ struct HdfDeviceNode *devNode = NULL;
+ struct IPowerStateToken *tokenIf = NULL;
if (deviceObject == NULL) {
HDF_LOGE("%s: input param is invalid", __func__);
return;
}
- struct HdfDeviceNode *devNode = (struct HdfDeviceNode *)HDF_SLIST_CONTAINER_OF(
+ devNode = (struct HdfDeviceNode *)HDF_SLIST_CONTAINER_OF(
struct HdfDeviceObject, deviceObject, struct HdfDeviceNode, deviceObject);
- struct IPowerStateToken *tokenIf = (struct IPowerStateToken *)devNode->powerToken;
+ tokenIf = (struct IPowerStateToken *)devNode->powerToken;
if ((tokenIf != NULL) && (tokenIf->ReleaseWakeLock != NULL)) {
tokenIf->ReleaseWakeLock(tokenIf);
}
@@ -108,13 +117,15 @@ void HdfPmReleaseDevice(struct HdfDeviceObject *deviceObject)
void HdfPmSetMode(struct HdfDeviceObject *deviceObject, uint32_t mode)
{
+ struct HdfDeviceNode *devNode = NULL;
+ struct PowerStateToken *token = NULL;
if (deviceObject == NULL || mode > HDF_POWER_MODE_MAX) {
HDF_LOGE("%s: input param is invalid", __func__);
return;
}
- struct HdfDeviceNode *devNode = (struct HdfDeviceNode *)HDF_SLIST_CONTAINER_OF(
+ devNode = (struct HdfDeviceNode *)HDF_SLIST_CONTAINER_OF(
struct HdfDeviceObject, deviceObject, struct HdfDeviceNode, deviceObject);
- struct PowerStateToken *token = devNode->powerToken;
+ token = devNode->powerToken;
if (token != NULL) {
token->mode = mode;
}
diff --git a/core/host/src/hdf_driver_loader.c b/core/host/src/hdf_driver_loader.c
index 5ef03defe4abfcd29512c315638dcc4a2b2a6508..98cfbee6ced8669aa349eba5d482588d8f7d9e0e 100755
--- a/core/host/src/hdf_driver_loader.c
+++ b/core/host/src/hdf_driver_loader.c
@@ -42,7 +42,7 @@ struct HdfDeviceNode *HdfDriverLoaderLoadNode(
devNode->driverEntry = driverEntry;
devNode->deviceInfo = deviceInfo;
devNode->deviceObject.property = HcsGetNodeByMatchAttr(HdfGetRootNode(), deviceInfo->deviceMatchAttr);
-
+ devNode->deviceObject.priv = (void *)(deviceInfo->private);
if (devNode->deviceObject.property == NULL) {
HDF_LOGW("failed to load node, property is null, match attr is: %s", deviceInfo->deviceMatchAttr);
}
diff --git a/core/host/src/hdf_observer_record.c b/core/host/src/hdf_observer_record.c
index 645d7d54eea0bbd103f29464e079e7b2b15cd13a..574afecddf69fe60b94bd17cacb070750b7c7077 100644
--- a/core/host/src/hdf_observer_record.c
+++ b/core/host/src/hdf_observer_record.c
@@ -47,10 +47,11 @@ void HdfServiceObserverRecordRecycle(struct HdfServiceObserverRecord *observerRe
bool HdfServiceObserverRecordCompare(struct HdfSListNode *listEntry, uint32_t serviceKey)
{
+ struct HdfServiceObserverRecord *record = NULL;
if (listEntry == NULL) {
return false;
}
- struct HdfServiceObserverRecord *record = (struct HdfServiceObserverRecord *)listEntry;
+ record = (struct HdfServiceObserverRecord *)listEntry;
if (record->serviceKey == serviceKey) {
return true;
}
diff --git a/core/host/src/power_state_token.c b/core/host/src/power_state_token.c
index ab65bbf6895b2a9b6c56e4cbc3e28b4baf2deacc..f4abe072683aa86f776894c5f35acecc9edbaf12 100644
--- a/core/host/src/power_state_token.c
+++ b/core/host/src/power_state_token.c
@@ -11,94 +11,74 @@
#include "hdf_device_desc.h"
#include "hdf_slist.h"
#include "osal_mem.h"
-#include "osal_sysevent.h"
+#include "hdf_power_state.h"
static void PowerStateTokenOnFirstAcquire(struct HdfSRef *sref)
{
+ struct PowerStateToken *stateToken = NULL;
if (sref == NULL) {
return;
}
- struct PowerStateToken *stateToken = (struct PowerStateToken *)HDF_SLIST_CONTAINER_OF(
+ stateToken = (struct PowerStateToken *)HDF_SLIST_CONTAINER_OF(
struct HdfSRef, sref, struct PowerStateToken, wakeRef);
- if (stateToken->state == POWER_STATE_ACTIVE) {
+ if (stateToken->psmState == PSM_STATE_ACTIVE) {
return;
}
- struct IDevmgrService *devMgrSvcIf = NULL;
- struct DevmgrServiceClnt *inst = DevmgrServiceClntGetInstance();
- if (inst == NULL) {
- return;
- }
- devMgrSvcIf = (struct IDevmgrService *)inst->devMgrSvcIf;
- if (devMgrSvcIf != NULL && devMgrSvcIf->AcquireWakeLock != NULL) {
- devMgrSvcIf->AcquireWakeLock(devMgrSvcIf, &stateToken->super);
- }
-
- if (stateToken->state == POWER_STATE_INACTIVE || stateToken->state == POWER_STATE_IDLE) {
+ if (stateToken->psmState == PSM_STATE_INACTIVE || stateToken->psmState == PSM_STATE_IDLE) {
const struct IPowerEventListener *listener = stateToken->listener;
if ((listener != NULL) && (listener->Resume != NULL)) {
listener->Resume(stateToken->deviceObject);
}
}
- stateToken->state = POWER_STATE_ACTIVE;
+ stateToken->psmState = PSM_STATE_ACTIVE;
}
static void PowerStateTokenOnLastRelease(struct HdfSRef *sref)
{
+ struct PowerStateToken *stateToken = NULL;
+ const struct IPowerEventListener *listener = NULL;
if (sref == NULL) {
return;
}
- struct PowerStateToken *stateToken = (struct PowerStateToken *)HDF_SLIST_CONTAINER_OF(
+ stateToken = (struct PowerStateToken *)HDF_SLIST_CONTAINER_OF(
struct HdfSRef, sref, struct PowerStateToken, wakeRef);
- if (stateToken->state != POWER_STATE_ACTIVE && stateToken->state != POWER_STATE_IDLE) {
- return;
- }
-
- struct IDevmgrService *devMgrSvcIf = NULL;
- const struct IPowerEventListener *listener = stateToken->listener;
- struct DevmgrServiceClnt *inst = DevmgrServiceClntGetInstance();
- if (inst == NULL) {
+ if (stateToken->psmState != PSM_STATE_ACTIVE && stateToken->psmState != PSM_STATE_IDLE) {
return;
}
- if (stateToken->state == POWER_STATE_ACTIVE) {
- devMgrSvcIf = (struct IDevmgrService *)inst->devMgrSvcIf;
- if ((devMgrSvcIf != NULL) && (devMgrSvcIf->AcquireWakeLock != NULL)) {
- devMgrSvcIf->ReleaseWakeLock(devMgrSvcIf, &stateToken->super);
- }
- }
-
+ listener = stateToken->listener;
if ((listener != NULL) && (listener->Suspend != NULL)) {
listener->Suspend(stateToken->deviceObject);
}
- stateToken->state = POWER_STATE_INACTIVE;
+ stateToken->psmState = PSM_STATE_INACTIVE;
}
-int PowerStateOnSysStateChange(struct PowerStateToken *stateToken, int32_t state)
+int PowerStateChange(struct PowerStateToken *stateToken, uint32_t pEvent)
{
if (stateToken == NULL || stateToken->listener == NULL || stateToken->mode != HDF_POWER_SYS_CTRL) {
return HDF_SUCCESS;
}
- switch (state) {
- case KEVENT_POWER_SUSPEND:
+ switch (pEvent) {
+ case POWER_STATE_SUSPEND:
if (stateToken->listener->Suspend != NULL) {
return stateToken->listener->Suspend(stateToken->deviceObject);
}
break;
- case KEVENT_POWER_RESUME:
+ case POWER_STATE_RESUME:
if (stateToken->listener->Resume != NULL) {
return stateToken->listener->Resume(stateToken->deviceObject);
}
break;
- case KEVENT_POWER_DISPLAY_OFF:
+ case POWER_STATE_DOZE_SUSPEND:
if (stateToken->listener->DozeSuspend != NULL) {
return stateToken->listener->DozeSuspend(stateToken->deviceObject);
}
break;
- case KEVENT_POWER_DISPLAY_ON:
+ case POWER_STATE_DOZE_RESUME:
if (stateToken->listener->DozeResume != NULL) {
return stateToken->listener->DozeResume(stateToken->deviceObject);
}
@@ -158,7 +138,7 @@ static int32_t PowerStateTokenConstruct(struct PowerStateToken *powerStateToken,
srefListener->OnFirstAcquire = PowerStateTokenOnFirstAcquire;
srefListener->OnLastRelease = PowerStateTokenOnLastRelease;
- powerStateToken->state = POWER_STATE_IDLE;
+ powerStateToken->psmState = PSM_STATE_IDLE;
powerStateToken->listener = listener;
powerStateToken->deviceObject = deviceObject;
HdfSRefConstruct(&powerStateToken->wakeRef, srefListener);
diff --git a/core/manager/include/devhost_service_clnt.h b/core/manager/include/devhost_service_clnt.h
index c80f3b1c1f0c8940b06bf3f289217f6cdd0909c6..cbc34d64a598a72e3d30023370749f95b87ca803 100644
--- a/core/manager/include/devhost_service_clnt.h
+++ b/core/manager/include/devhost_service_clnt.h
@@ -14,7 +14,7 @@
#include "hdf_map.h"
struct DevHostServiceClnt {
- struct HdfSListNode node;
+ struct DListHead node;
struct HdfSList devices;
struct HdfSList *deviceInfos;
Map *deviceHashMap;
@@ -28,6 +28,6 @@ struct DevHostServiceClnt {
int DevHostServiceClntInstallDriver(struct DevHostServiceClnt *hostClnt);
struct DevHostServiceClnt *DevHostServiceClntNewInstance(uint16_t hostId, const char *hostName);
void DevHostServiceClntFreeInstance(struct DevHostServiceClnt *hostClnt);
-void DevHostServiceClntDelete(struct HdfSListNode *listEntry);
+void DevHostServiceClntDelete(struct DevHostServiceClnt *hostClnt);
#endif /* DEVHOST_SERVICE_CLNT_H */
diff --git a/core/manager/include/devmgr_service.h b/core/manager/include/devmgr_service.h
index 1d255d1893809bba1e7c8263ad07528106eca26b..56f0e02cc63870819c9b75f9d5c68b7fda9e8727 100644
--- a/core/manager/include/devmgr_service.h
+++ b/core/manager/include/devmgr_service.h
@@ -10,12 +10,12 @@
#define DEVICE_MANAGER_SERVICE_H
#include "devmgr_service_if.h"
-#include "hdf_slist.h"
+#include "hdf_dlist.h"
#include "osal_mutex.h"
struct DevmgrService {
struct IDevmgrService super;
- struct HdfSList hosts;
+ struct DListHead hosts;
struct OsalMutex devMgrMutex;
};
@@ -27,7 +27,5 @@ struct IDevmgrService *DevmgrServiceGetInstance(void);
int DevmgrServiceLoadDevice(const char *svcName);
int DevmgrServiceUnLoadDevice(const char *svcName);
int32_t DevmgrServiceLoadLeftDriver(struct DevmgrService *devMgrSvc);
-void DevmgrServiceAcquireWakeLock(struct IDevmgrService *inst, struct IPowerStateToken *tokenIf);
-void DevmgrServiceReleaseWakeLock(struct IDevmgrService *inst, struct IPowerStateToken *tokenIf);
#endif /* DEVICE_MANAGER_SERVICE_H */
diff --git a/core/manager/include/power_state_manager.h b/core/manager/include/power_state_manager.h
deleted file mode 100644
index 0cf87de32e2e78af68b28f1e61d6ea1205afa402..0000000000000000000000000000000000000000
--- a/core/manager/include/power_state_manager.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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 POWER_STATE_MANAGER_H
-#define POWER_STATE_MANAGER_H
-
-#include "hdf_sref.h"
-#include "hdf_slist.h"
-#include "power_state_token_if.h"
-
-struct PowerStateManager {
- struct HdfSRef wakeRef;
- struct HdfSList tokens;
- void (*AcquireWakeLock)(struct PowerStateManager *, struct IPowerStateToken *);
- void (*ReleaseWakeLock)(struct PowerStateManager *, struct IPowerStateToken *);
-};
-
-struct PowerStateManager *PowerStateManagerGetInstance(void);
-
-#endif /* POWER_STATE_MANAGER_H */
\ No newline at end of file
diff --git a/core/manager/include/power_state_token_clnt.h b/core/manager/include/power_state_token_clnt.h
index 1915a985e9be1b71c6f94b59f3eae9240c4f9680..64c2885abf6c1a9032444fc42bd5893f10f468eb 100644
--- a/core/manager/include/power_state_token_clnt.h
+++ b/core/manager/include/power_state_token_clnt.h
@@ -15,7 +15,7 @@
struct PowerStateTokenClnt {
struct HdfSListNode entry;
- HdfPowerState powerState;
+ HdfPsmState powerState;
struct IPowerStateToken *tokenIf;
};
diff --git a/core/manager/src/devhost_service_clnt.c b/core/manager/src/devhost_service_clnt.c
index 490cf04052ddbf85380339ad4898b2ab76e3291e..43b4f1ca901cdcdfa56b3a1e10f6c554954cd04a 100644
--- a/core/manager/src/devhost_service_clnt.c
+++ b/core/manager/src/devhost_service_clnt.c
@@ -84,9 +84,8 @@ void DevHostServiceClntFreeInstance(struct DevHostServiceClnt *hostClnt)
}
}
-void DevHostServiceClntDelete(struct HdfSListNode *listEntry)
+void DevHostServiceClntDelete(struct DevHostServiceClnt *hostClnt)
{
- struct DevHostServiceClnt *hostClnt = (struct DevHostServiceClnt *)listEntry;
if (hostClnt != NULL) {
DevHostServiceClntFreeInstance(hostClnt);
}
diff --git a/core/manager/src/devmgr_service.c b/core/manager/src/devmgr_service.c
index 5fa988a8acf5c34b6aa5388e53faf06a58382e0c..e11da3ed778c12901b77ff6965524efdcf17ddf2 100644
--- a/core/manager/src/devmgr_service.c
+++ b/core/manager/src/devmgr_service.c
@@ -15,11 +15,11 @@
#include "hdf_host_info.h"
#include "hdf_log.h"
#include "hdf_object_manager.h"
-#include "power_state_manager.h"
#define HDF_LOG_TAG devmgr_service
-static int DevmgrServiceActiveDevice(struct DevHostServiceClnt *hostClnt, struct HdfDeviceInfo *deviceInfo, bool isLoad)
+static int DevmgrServiceActiveDevice(struct DevHostServiceClnt *hostClnt,
+ struct HdfDeviceInfo *deviceInfo, bool isLoad)
{
struct IDevHostService *devHostSvcIf = (struct IDevHostService *)hostClnt->hostService;
if (devHostSvcIf == NULL) {
@@ -43,7 +43,6 @@ static int DevmgrServiceActiveDevice(struct DevHostServiceClnt *hostClnt, struct
static int DevmgrServiceFindAndActiveDevice(const char *svcName, bool isLoad)
{
- struct HdfSListIterator itHost;
struct HdfSListIterator itDeviceInfo;
struct HdfDeviceInfo *deviceInfo = NULL;
struct DevHostServiceClnt *hostClnt = NULL;
@@ -52,9 +51,7 @@ static int DevmgrServiceFindAndActiveDevice(const char *svcName, bool isLoad)
return HDF_ERR_INVALID_PARAM;
}
- HdfSListIteratorInit(&itHost, &devMgrSvc->hosts);
- while (HdfSListIteratorHasNext(&itHost)) {
- hostClnt = (struct DevHostServiceClnt *)HdfSListIteratorNext(&itHost);
+ DLIST_FOR_EACH_ENTRY(hostClnt, &devMgrSvc->hosts, struct DevHostServiceClnt, node) {
HdfSListIteratorInit(&itDeviceInfo, hostClnt->deviceInfos);
while (HdfSListIteratorHasNext(&itDeviceInfo)) {
deviceInfo = (struct HdfDeviceInfo *)HdfSListIteratorNext(&itDeviceInfo);
@@ -63,13 +60,13 @@ static int DevmgrServiceFindAndActiveDevice(const char *svcName, bool isLoad)
}
}
}
+
return HDF_FAILURE;
}
int32_t DevmgrServiceLoadLeftDriver(struct DevmgrService *devMgrSvc)
{
int32_t ret;
- struct HdfSListIterator itHost;
struct HdfSListIterator itDeviceInfo;
struct HdfDeviceInfo *deviceInfo = NULL;
struct DevHostServiceClnt *hostClnt = NULL;
@@ -77,9 +74,7 @@ int32_t DevmgrServiceLoadLeftDriver(struct DevmgrService *devMgrSvc)
return HDF_FAILURE;
}
- HdfSListIteratorInit(&itHost, &devMgrSvc->hosts);
- while (HdfSListIteratorHasNext(&itHost)) {
- hostClnt = (struct DevHostServiceClnt *)HdfSListIteratorNext(&itHost);
+ DLIST_FOR_EACH_ENTRY(hostClnt, &devMgrSvc->hosts, struct DevHostServiceClnt, node) {
HdfSListIteratorInit(&itDeviceInfo, hostClnt->deviceInfos);
while (HdfSListIteratorHasNext(&itDeviceInfo)) {
deviceInfo = (struct HdfDeviceInfo *)HdfSListIteratorNext(&itDeviceInfo);
@@ -106,16 +101,14 @@ int DevmgrServiceUnLoadDevice(const char *svcName)
static struct DevHostServiceClnt *DevmgrServiceFindDeviceHost(struct IDevmgrService *inst, uint16_t hostId)
{
- struct HdfSListIterator it;
struct DevHostServiceClnt *hostClnt = NULL;
struct DevmgrService *dmService = (struct DevmgrService *)inst;
if (dmService == NULL) {
HDF_LOGE("failed to find device host, dmService is null");
return NULL;
}
- HdfSListIteratorInit(&it, &dmService->hosts);
- while (HdfSListIteratorHasNext(&it)) {
- hostClnt = (struct DevHostServiceClnt *)HdfSListIteratorNext(&it);
+
+ DLIST_FOR_EACH_ENTRY(hostClnt, &dmService->hosts, struct DevHostServiceClnt, node) {
if (hostClnt->hostId == hostId) {
return hostClnt;
}
@@ -146,16 +139,18 @@ static void DevmgrServiceUpdateStatus(struct DevHostServiceClnt *hostClnt, uint1
static int DevmgrServiceAttachDevice(
struct IDevmgrService *inst, const struct HdfDeviceInfo *deviceInfo, struct IHdfDeviceToken *token)
{
+ struct DevHostServiceClnt *hostClnt = NULL;
+ struct DeviceTokenClnt *tokenClnt = NULL;
if (deviceInfo == NULL) {
HDF_LOGE("failed to attach device, deviceInfo is null");
return HDF_FAILURE;
}
- struct DevHostServiceClnt *hostClnt = DevmgrServiceFindDeviceHost(inst, deviceInfo->hostId);
+ hostClnt = DevmgrServiceFindDeviceHost(inst, deviceInfo->hostId);
if (hostClnt == NULL) {
HDF_LOGE("failed to attach device, hostClnt is null");
return HDF_FAILURE;
}
- struct DeviceTokenClnt *tokenClnt = DeviceTokenClntNewInstance(token);
+ tokenClnt = DeviceTokenClntNewInstance(token);
if (tokenClnt == NULL) {
HDF_LOGE("failed to attach device, tokenClnt is null");
return HDF_FAILURE;
@@ -198,7 +193,7 @@ static int DevmgrServiceStartDeviceHosts(struct DevmgrService *inst)
struct DevHostServiceClnt *hostClnt = NULL;
struct IDriverInstaller *installer = NULL;
installer = DriverInstallerGetInstance();
- if ((installer == NULL) || (installer->StartDeviceHost == NULL)) {
+ if (installer == NULL || installer->StartDeviceHost == NULL) {
HDF_LOGE("installer or installer->StartDeviceHost is null");
return HDF_FAILURE;
}
@@ -215,11 +210,11 @@ static int DevmgrServiceStartDeviceHosts(struct DevmgrService *inst)
HDF_LOGW("failed to create new device host client");
continue;
}
- HdfSListAdd(&inst->hosts, &hostClnt->node);
+ DListInsertTail(&hostClnt->node, &inst->hosts);
hostClnt->hostPid = installer->StartDeviceHost(hostAttr->hostId, hostAttr->hostName);
if (hostClnt->hostPid == HDF_FAILURE) {
HDF_LOGW("failed to start device host, host id is %u", hostAttr->hostId);
- HdfSListRemove(&inst->hosts, &hostClnt->node);
+ DListRemove(&hostClnt->node);
DevHostServiceClntFreeInstance(hostClnt);
}
}
@@ -237,20 +232,59 @@ int DevmgrServiceStartService(struct IDevmgrService *inst)
return DevmgrServiceStartDeviceHosts(dmService);
}
+int DevmgrServicePowerStateChange(struct IDevmgrService *devmgrService, enum HdfPowerState powerState)
+{
+ struct DevHostServiceClnt *hostClient = NULL;
+ struct DevmgrService *devmgr = NULL;
+ int result = HDF_SUCCESS;
+
+ if (devmgrService == NULL) {
+ return HDF_ERR_INVALID_OBJECT;
+ }
+
+ if (!IsValidPowerState(powerState)) {
+ HDF_LOGE("%s:invalid power event %u", __func__, powerState);
+ return HDF_ERR_INVALID_PARAM;
+ }
+ devmgr = CONTAINER_OF(devmgrService, struct DevmgrService, super);
+
+ if (IsPowerWakeState(powerState)) {
+ HDF_LOGI("%s:wake state %u", __func__, powerState);
+ DLIST_FOR_EACH_ENTRY(hostClient, &devmgr->hosts, struct DevHostServiceClnt, node) {
+ if (hostClient->hostService != NULL) {
+ if (hostClient->hostService->PmNotify(hostClient->hostService, powerState) != HDF_SUCCESS) {
+ result = HDF_FAILURE;
+ }
+ }
+ }
+ } else {
+ HDF_LOGI("%s:suspend state %u", __func__, powerState);
+ DLIST_FOR_EACH_ENTRY_REVERSE(hostClient, &devmgr->hosts, struct DevHostServiceClnt, node) {
+ if (hostClient->hostService != NULL) {
+ if (hostClient->hostService->PmNotify(hostClient->hostService, powerState) != HDF_SUCCESS) {
+ result = HDF_FAILURE;
+ }
+ }
+ }
+ }
+
+ return result;
+}
+
bool DevmgrServiceConstruct(struct DevmgrService *inst)
{
+ struct IDevmgrService *devMgrSvcIf = NULL;
if (OsalMutexInit(&inst->devMgrMutex) != HDF_SUCCESS) {
HDF_LOGE("%s:failed to mutex init ", __func__);
return false;
}
- struct IDevmgrService *devMgrSvcIf = (struct IDevmgrService *)inst;
+ devMgrSvcIf = (struct IDevmgrService *)inst;
if (devMgrSvcIf != NULL) {
devMgrSvcIf->AttachDevice = DevmgrServiceAttachDevice;
devMgrSvcIf->AttachDeviceHost = DevmgrServiceAttachDeviceHost;
devMgrSvcIf->StartService = DevmgrServiceStartService;
- devMgrSvcIf->AcquireWakeLock = DevmgrServiceAcquireWakeLock;
- devMgrSvcIf->ReleaseWakeLock = DevmgrServiceReleaseWakeLock;
- HdfSListInit(&inst->hosts);
+ devMgrSvcIf->PowerStateChange = DevmgrServicePowerStateChange;
+ DListHeadInit(&inst->hosts);
return true;
} else {
return false;
@@ -282,27 +316,15 @@ struct IDevmgrService *DevmgrServiceGetInstance()
void DevmgrServiceRelease(struct HdfObject *object)
{
struct DevmgrService *devmgrService = (struct DevmgrService *)object;
+ struct DevHostServiceClnt *hostClnt = NULL;
+ struct DevHostServiceClnt *hostClntTmp = NULL;
if (devmgrService == NULL) {
return;
}
- HdfSListFlush(&devmgrService->hosts, DevHostServiceClntDelete);
- OsalMutexDestroy(&devmgrService->devMgrMutex);
-}
-
-void DevmgrServiceAcquireWakeLock(struct IDevmgrService *inst, struct IPowerStateToken *tokenIf)
-{
- (void)inst;
- struct PowerStateManager *stateManager = PowerStateManagerGetInstance();
- if ((stateManager != NULL) && (stateManager->AcquireWakeLock != NULL)) {
- stateManager->AcquireWakeLock(stateManager, tokenIf);
+ DLIST_FOR_EACH_ENTRY_SAFE(hostClnt, hostClntTmp, &devmgrService->hosts, struct DevHostServiceClnt, node) {
+ DListRemove(&hostClnt->node);
+ DevHostServiceClntDelete(hostClnt);
}
-}
-void DevmgrServiceReleaseWakeLock(struct IDevmgrService *inst, struct IPowerStateToken *tokenIf)
-{
- (void)inst;
- struct PowerStateManager *stateManager = PowerStateManagerGetInstance();
- if ((stateManager != NULL) && (stateManager->ReleaseWakeLock != NULL)) {
- stateManager->ReleaseWakeLock(stateManager, tokenIf);
- }
+ OsalMutexDestroy(&devmgrService->devMgrMutex);
}
diff --git a/core/manager/src/devsvc_manager.c b/core/manager/src/devsvc_manager.c
index 1c7b765acab51ca905a08b1cd7bec17fba2c1fb8..d3f377bb0e8b32067375aa5a4338eb8e9af124fe 100644
--- a/core/manager/src/devsvc_manager.c
+++ b/core/manager/src/devsvc_manager.c
@@ -43,12 +43,13 @@ static struct DevSvcRecord *DevSvcManagerSearchService(struct IDevSvcManager *in
int DevSvcManagerAddService(struct IDevSvcManager *inst, const char *svcName, struct HdfDeviceObject *service)
{
struct DevSvcManager *devSvcManager = (struct DevSvcManager *)inst;
+ struct DevSvcRecord *record = NULL;
if ((devSvcManager == NULL) || (service == NULL) || (svcName == NULL)) {
HDF_LOGE("failed to add service, input param is null");
return HDF_FAILURE;
}
- struct DevSvcRecord *record = DevSvcRecordNewInstance();
+ record = DevSvcRecordNewInstance();
if (record == NULL) {
HDF_LOGE("failed to add service , record is null");
return HDF_FAILURE;
@@ -66,11 +67,12 @@ int DevSvcManagerSubscribeService(struct IDevSvcManager *inst, const char *svcNa
{
int ret = HDF_FAILURE;
struct DevSvcManager *devSvcMgr = (struct DevSvcManager *)inst;
+ struct HdfObject *deviceService = NULL;
if (svcName == NULL || devSvcMgr == NULL) {
return ret;
}
- struct HdfObject *deviceService = DevSvcManagerGetService(inst, svcName);
+ deviceService = DevSvcManagerGetService(inst, svcName);
if (deviceService != NULL) {
if (callBack.OnServiceConnected != NULL) {
callBack.OnServiceConnected(callBack.deviceObject, deviceService);
@@ -85,10 +87,11 @@ void DevSvcManagerRemoveService(struct IDevSvcManager *inst, const char *svcName
{
struct DevSvcManager *devSvcManager = (struct DevSvcManager *)inst;
uint32_t serviceKey = HdfStringMakeHashKey(svcName, 0);
+ struct DevSvcRecord *serviceRecord = NULL;
if (svcName == NULL || devSvcManager == NULL) {
return;
}
- struct DevSvcRecord *serviceRecord = DevSvcManagerSearchService(inst, serviceKey);
+ serviceRecord = DevSvcManagerSearchService(inst, serviceKey);
if (serviceRecord != NULL) {
OsalMutexLock(&devSvcManager->mutex);
HdfSListRemove(&devSvcManager->services, &serviceRecord->entry);
@@ -100,11 +103,12 @@ void DevSvcManagerRemoveService(struct IDevSvcManager *inst, const char *svcName
struct HdfDeviceObject *DevSvcManagerGetObject(struct IDevSvcManager *inst, const char *svcName)
{
uint32_t serviceKey = HdfStringMakeHashKey(svcName, 0);
+ struct DevSvcRecord *serviceRecord = NULL;
if (svcName == NULL) {
HDF_LOGE("Get service failed, svcName is null");
return NULL;
}
- struct DevSvcRecord *serviceRecord = DevSvcManagerSearchService(inst, serviceKey);
+ serviceRecord = DevSvcManagerSearchService(inst, serviceKey);
if (serviceRecord != NULL) {
return serviceRecord->value;
}
@@ -122,11 +126,12 @@ struct HdfObject *DevSvcManagerGetService(struct IDevSvcManager *inst, const cha
bool DevSvcManagerConstruct(struct DevSvcManager *inst)
{
+ struct IDevSvcManager *devSvcMgrIf = NULL;
if (inst == NULL) {
HDF_LOGE("%s: inst is null!", __func__);
return false;
}
- struct IDevSvcManager *devSvcMgrIf = &inst->super;
+ devSvcMgrIf = &inst->super;
devSvcMgrIf->AddService = DevSvcManagerAddService;
devSvcMgrIf->SubscribeService = DevSvcManagerSubscribeService;
devSvcMgrIf->UnsubscribeService = NULL;
diff --git a/core/manager/src/hdf_driver_installer.c b/core/manager/src/hdf_driver_installer.c
index 4071b2eec717d74b263b07bf5c4088b1544ad2e1..0ed60f47f292f9a6ab4f5609a322638f44ccbac9 100644
--- a/core/manager/src/hdf_driver_installer.c
+++ b/core/manager/src/hdf_driver_installer.c
@@ -17,11 +17,12 @@
static int DriverInstallerStartDeviceHost(uint32_t devHostId, const char *devHostName)
{
struct IDevHostService *hostServiceIf = DevHostServiceNewInstance(devHostId, devHostName);
+ int ret;
if ((hostServiceIf == NULL) || (hostServiceIf->StartService == NULL)) {
HDF_LOGE("hostServiceIf or hostServiceIf->StartService is null");
return HDF_FAILURE;
}
- int ret = hostServiceIf->StartService(hostServiceIf);
+ ret = hostServiceIf->StartService(hostServiceIf);
if (ret != HDF_SUCCESS) {
HDF_LOGE("failed to start host service, ret: %d", ret);
DevHostServiceFreeInstance(hostServiceIf);
diff --git a/core/manager/src/power_state_manager.c b/core/manager/src/power_state_manager.c
deleted file mode 100644
index 29dcc7b1cbf6970605c8781659b8e3663b2afc29..0000000000000000000000000000000000000000
--- a/core/manager/src/power_state_manager.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * 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 "power_state_manager.h"
-#include "hdf_object_manager.h"
-#include "power_state_token_clnt.h"
-
-static struct PowerStateTokenClnt *PowerStateManagerGetStateTokenClnt(
- struct PowerStateManager *inst, struct IPowerStateToken *tokenIf)
-{
- struct HdfSListIterator it;
- if (inst == NULL) {
- return NULL;
- }
- HdfSListIteratorInit(&it, &inst->tokens);
- while (HdfSListIteratorHasNext(&it)) {
- struct PowerStateTokenClnt *tokenClnt =
- (struct PowerStateTokenClnt *)HdfSListIteratorNext(&it);
- if (tokenClnt->tokenIf == tokenIf) {
- return tokenClnt;
- }
- }
- return NULL;
-}
-
-static void PowerStateManagerAcquireWakeLock(
- struct PowerStateManager *inst, struct IPowerStateToken *tokenIf)
-{
- if (inst == NULL) {
- return;
- }
- struct HdfSRef *sref = &inst->wakeRef;
- struct PowerStateTokenClnt *stateTokenClnt = PowerStateManagerGetStateTokenClnt(inst, tokenIf);
- if (stateTokenClnt == NULL) {
- return;
- }
- stateTokenClnt->powerState = POWER_STATE_ACTIVE;
- if (sref->Acquire != NULL) {
- sref->Acquire(sref);
- }
-}
-
-static void PowerStateManagerReleaseWakeLock(
- struct PowerStateManager *inst, struct IPowerStateToken *tokenIf)
-{
- struct HdfSRef *sref = NULL;
- struct PowerStateTokenClnt *stateTokenClnt = PowerStateManagerGetStateTokenClnt(inst, tokenIf);
- if (inst == NULL || stateTokenClnt == NULL) {
- return;
- }
- stateTokenClnt->powerState = POWER_STATE_INACTIVE;
- sref = &inst->wakeRef;
- if (sref->Release != NULL) {
- sref->Release(sref);
- }
-}
-
-static void PowerStateManagerConstruct(struct PowerStateManager *inst)
-{
- static struct IHdfSRefListener wakeLockRefListener = {
- .OnFirstAcquire = NULL,
- .OnLastRelease = NULL,
- };
-
- inst->AcquireWakeLock = PowerStateManagerAcquireWakeLock;
- inst->ReleaseWakeLock = PowerStateManagerReleaseWakeLock;
- HdfSListInit(&inst->tokens);
- HdfSRefConstruct(&inst->wakeRef, &wakeLockRefListener);
-}
-
-struct PowerStateManager *PowerStateManagerGetInstance()
-{
- static struct PowerStateManager powerStateManager = { 0 };
- if (powerStateManager.AcquireWakeLock == NULL) {
- PowerStateManagerConstruct(&powerStateManager);
- }
- return &powerStateManager;
-}
diff --git a/core/manager/src/power_state_token_clnt.c b/core/manager/src/power_state_token_clnt.c
index 31eedb88102e68221ad28136283b22b0b3483dcb..7bf1abd4af789b457a7879781b08db08dd5076fa 100644
--- a/core/manager/src/power_state_token_clnt.c
+++ b/core/manager/src/power_state_token_clnt.c
@@ -12,7 +12,7 @@
static void PowerStateTokenClntConstruct(struct PowerStateTokenClnt *clnt, struct IPowerStateToken *tokenIf)
{
clnt->tokenIf = tokenIf;
- clnt->powerState = POWER_STATE_INACTIVE;
+ clnt->powerState = PSM_STATE_INACTIVE;
}
struct PowerStateTokenClnt *PowerStateTokenClntNewInstance(struct IPowerStateToken *tokenIf)
diff --git a/core/manager/test/unittest/common/hdf_ioservice_test.cpp b/core/manager/test/unittest/common/hdf_ioservice_test.cpp
index 9057d7beb6dacb41d655fe58bffe38dcde6823e7..6dd938c08b888b982eae736c6eb797695dd39029 100644
--- a/core/manager/test/unittest/common/hdf_ioservice_test.cpp
+++ b/core/manager/test/unittest/common/hdf_ioservice_test.cpp
@@ -11,6 +11,7 @@
#include
#include
#include
+#include
#include
#include
#include "hdf_uhdf_test.h"
@@ -18,6 +19,7 @@
#include "osal_time.h"
#include "sample_driver_test.h"
#include "hdf_log.h"
+#include "hdf_power_state.h"
using namespace testing::ext;
@@ -38,7 +40,7 @@ public:
static struct Eventlistener listener0;
static struct Eventlistener listener1;
const char *testSvcName = SAMPLE_SERVICE;
- const int eventWaitTimeUs = (50 * 1000);
+ const int eventWaitTimeUs = (150 * 1000);
static int eventCount;
};
@@ -72,7 +74,7 @@ int IoServiceTest::OnDevEventReceived(struct HdfDevEventlistener *listener, stru
{
OsalTimespec time;
OsalGetTime(&time);
- HDF_LOGE("%s: received event[%d] from %s at %llu.%llu", (char *)listener->priv, eventCount++, (char *)service->priv,
+ HDF_LOGE("%s: received event[%d] from %s at %" PRIu64 ".%" PRIu64 "", (char *)listener->priv, eventCount++, (char *)service->priv,
time.sec, time.usec);
const char *string = HdfSbufReadString(data);
@@ -126,7 +128,7 @@ static int SendEvent(struct HdfIoService *serv, const char *eventData)
HDF_LOGE("service call reply check fail, replyData=0x%x", replyData);
ret = HDF_ERR_INVALID_OBJECT;
}
- HDF_LOGE("send event finish at %llu.%llu", time.sec, time.usec);
+ HDF_LOGE("send event finish at %" PRIu64 ".%" PRIu64 "", time.sec, time.usec);
} while (0);
HdfSBufRecycle(data);
@@ -596,3 +598,38 @@ HWTEST_F(IoServiceTest, HdfIoService012, TestSize.Level0)
HdfIoServiceRecycle(serv);
}
+
+/* *
+ * @tc.name: HdfIoService013
+ * @tc.desc: devmgr power state change test
+ * @tc.type: FUNC
+ */
+HWTEST_F(IoServiceTest, HdfIoService013, TestSize.Level0)
+{
+ struct HdfSBuf *data = HdfSBufObtainDefaultSize();
+ ASSERT_NE(data, nullptr);
+
+ struct HdfIoService *serv = HdfIoServiceBind(testSvcName);
+ ASSERT_NE(serv, nullptr);
+
+ HdfSbufWriteUint32(data, POWER_STATE_SUSPEND);
+ int ret = serv->dispatcher->Dispatch(&serv->object, SAMPLE_DRIVER_PM_STATE_INJECT, data, NULL);
+ ASSERT_EQ(ret, HDF_SUCCESS);
+
+ HdfSbufFlush(data);
+ HdfSbufWriteUint32(data, POWER_STATE_RESUME);
+ ret = serv->dispatcher->Dispatch(&serv->object, SAMPLE_DRIVER_PM_STATE_INJECT, data, NULL);
+ ASSERT_EQ(ret, HDF_SUCCESS);
+
+ HdfSbufFlush(data);
+ HdfSbufWriteUint32(data, POWER_STATE_DOZE_SUSPEND);
+ ret = serv->dispatcher->Dispatch(&serv->object, SAMPLE_DRIVER_PM_STATE_INJECT, data, NULL);
+ ASSERT_EQ(ret, HDF_SUCCESS);
+
+ HdfSbufFlush(data);
+ HdfSbufWriteUint32(data, POWER_STATE_DOZE_RESUME);
+ ret = serv->dispatcher->Dispatch(&serv->object, SAMPLE_DRIVER_PM_STATE_INJECT, data, NULL);
+ ASSERT_EQ(ret, HDF_SUCCESS);
+ HdfIoServiceRecycle(serv);
+ HdfSBufRecycle(data);
+}
diff --git a/core/manager/test/unittest/common/hdf_lite_manager_test.cpp b/core/manager/test/unittest/common/hdf_lite_manager_test.cpp
index 623e4eb425aa760866a2fa0c45e91bc8caf74c16..264a2fd74c1098f7ee271a20fa28bf35d8d16918 100644
--- a/core/manager/test/unittest/common/hdf_lite_manager_test.cpp
+++ b/core/manager/test/unittest/common/hdf_lite_manager_test.cpp
@@ -84,7 +84,7 @@ HWTEST_F(HdfManagerTest, HdfRegisterDevice001, TestSize.Level0)
int32_t ret = HDF_FAILURE;
struct HdfSBuf *data = NULL;
struct HdfIoService *ioService = HdfIoServiceBind(SAMPLE_SERVICE);
- EXPECT_TRUE(ioService != NULL);
+ ASSERT_TRUE(ioService != NULL);
data = HdfSBufObtainDefaultSize();
EXPECT_TRUE(data != NULL);
EXPECT_TRUE(HdfSbufWriteString(data, "sample_driver"));
@@ -118,7 +118,7 @@ HWTEST_F(HdfManagerTest, HdfRegisterDevice001, TestSize.Level0)
HWTEST_F(HdfManagerTest, HdfGetServiceNameByDeviceClass001, TestSize.Level0)
{
struct HdfSBuf *data = HdfSBufObtain(1000);
- EXPECT_TRUE(data != NULL);
+ ASSERT_TRUE(data != NULL);
int32_t ret = HdfGetServiceNameByDeviceClass(DEVICE_CLASS_DEFAULT, data);
EXPECT_TRUE(ret == HDF_SUCCESS);
bool flag = false;
diff --git a/core/shared/include/devhost_service_if.h b/core/shared/include/devhost_service_if.h
index 83e9d21aca764e2a879534e855e0efd770d4fa12..a1c22691577c2f837d5629204cda3a4816ca88eb 100644
--- a/core/shared/include/devhost_service_if.h
+++ b/core/shared/include/devhost_service_if.h
@@ -14,9 +14,10 @@
struct IDevHostService {
struct HdfObject object;
- int (*AddDevice)(struct IDevHostService *, const struct HdfDeviceInfo *);
- int (*DelDevice)(struct IDevHostService *, const struct HdfDeviceInfo *);
- int (*StartService)(struct IDevHostService *);
+ int (*AddDevice)(struct IDevHostService *hostService, const struct HdfDeviceInfo *devInfo);
+ int (*DelDevice)(struct IDevHostService *hostService, const struct HdfDeviceInfo *devInfo);
+ int (*StartService)(struct IDevHostService *hostService);
+ int (*PmNotify)(struct IDevHostService *service, uint32_t powerState);
};
#endif /* DEVHOST_SERVICE_IF_H */
diff --git a/core/shared/include/devmgr_service_if.h b/core/shared/include/devmgr_service_if.h
index 136f2832ad15ccd67cecb4a7bd917e828b17aaca..55df8e42633eae5438899ab97c318320c6f26978 100644
--- a/core/shared/include/devmgr_service_if.h
+++ b/core/shared/include/devmgr_service_if.h
@@ -13,6 +13,7 @@
#include "device_token_if.h"
#include "hdf_object.h"
#include "power_state_token_if.h"
+#include "hdf_power_state.h"
struct IDevmgrService {
struct HdfObject base;
@@ -20,8 +21,7 @@ struct IDevmgrService {
int (*AttachDeviceHost)(struct IDevmgrService *, uint16_t, struct IDevHostService *);
int (*AttachDevice)(struct IDevmgrService *, const struct HdfDeviceInfo *, struct IHdfDeviceToken *);
int (*StartService)(struct IDevmgrService *);
- void (*AcquireWakeLock)(struct IDevmgrService *, struct IPowerStateToken *);
- void (*ReleaseWakeLock)(struct IDevmgrService *, struct IPowerStateToken *);
+ int (*PowerStateChange)(struct IDevmgrService *, enum HdfPowerState pEvent);
};
#endif /* DEVMGR_SERVICE_IF_H */
diff --git a/core/shared/include/hdf_attribute_manager.h b/core/shared/include/hdf_attribute_manager.h
index ec90ee0179bc448c4f5dda79324fad032d9fb4fc..8138a5dbfcd54564f88a28779afb7f766f2b7673 100644
--- a/core/shared/include/hdf_attribute_manager.h
+++ b/core/shared/include/hdf_attribute_manager.h
@@ -14,7 +14,7 @@
const struct DeviceResourceNode *HdfGetRootNode(void);
bool HdfAttributeManagerGetHostList(struct HdfSList *hostList);
struct HdfSList *HdfAttributeManagerGetDeviceList(uint16_t hostId, const char *hostName);
-bool HdfDeviceListAdd(const char *moduleName, const char *serviceName);
+bool HdfDeviceListAdd(const char *moduleName, const char *serviceName, const void *privateData);
void HdfDeviceListDel(const char *moduleName, const char *serviceName);
#endif /* HDF_ATTRIBUTE_MANAGER_H */
diff --git a/core/shared/include/hdf_device_info.h b/core/shared/include/hdf_device_info.h
index de2f2984d8c95726ccf34531914a3ef98ba13683..8852e83062d400b9835400ae40c29be172ed14be 100755
--- a/core/shared/include/hdf_device_info.h
+++ b/core/shared/include/hdf_device_info.h
@@ -36,6 +36,12 @@ struct HdfDeviceInfo {
const char *moduleName;
const char *svcName;
const char *deviceMatchAttr;
+ const void *private;
+};
+
+struct HdfPrivateInfo {
+ uint32_t length;
+ const void *data;
};
struct HdfDeviceInfo *HdfDeviceInfoNewInstance(void);
diff --git a/core/shared/include/hdf_power_state.h b/core/shared/include/hdf_power_state.h
new file mode 100644
index 0000000000000000000000000000000000000000..d1055711319434642872863cb6ff434160740e4d
--- /dev/null
+++ b/core/shared/include/hdf_power_state.h
@@ -0,0 +1,30 @@
+/*
+ * 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 HDF_POWER_STATE_H
+#define HDF_POWER_STATE_H
+
+enum HdfPowerState {
+ POWER_STATE_DOZE_RESUME,
+ POWER_STATE_DOZE_SUSPEND,
+ POWER_STATE_RESUME,
+ POWER_STATE_SUSPEND,
+ POWER_STATE_MAX,
+};
+
+static inline bool IsPowerWakeState(uint32_t state)
+{
+ return state == POWER_STATE_DOZE_RESUME || state == POWER_STATE_RESUME;
+}
+
+static inline bool IsValidPowerState(uint32_t state)
+{
+ return state < POWER_STATE_MAX;
+}
+
+#endif /* HDF_POWER_STATE_H */
\ No newline at end of file
diff --git a/core/shared/include/hdf_usb_pnp_manage.h b/core/shared/include/hdf_usb_pnp_manage.h
new file mode 100755
index 0000000000000000000000000000000000000000..62ba214aad04bd5944dccd3065478ae5a0c02d19
--- /dev/null
+++ b/core/shared/include/hdf_usb_pnp_manage.h
@@ -0,0 +1,102 @@
+/*
+ * 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 HDF_USB_PNP_MANAGE_H
+#define HDF_USB_PNP_MANAGE_H
+
+#include "hdf_base.h"
+
+#define USB_PNP_NOTIFY_TEST_MODE false
+#define USB_PNP_INFO_MAX_INTERFACES 32
+
+enum UsbPnpNotifyServiceCmd {
+ USB_PNP_NOTIFY_ADD_INTERFACE,
+ USB_PNP_NOTIFY_REMOVE_INTERFACE,
+ USB_PNP_NOTIFY_REPORT_INTERFACE,
+ USB_PNP_NOTIFY_ADD_DEVICE,
+ USB_PNP_NOTIFY_REMOVE_DEVICE,
+ #if USB_PNP_NOTIFY_TEST_MODE == true
+ USB_PNP_NOTIFY_ADD_TEST,
+ USB_PNP_NOTIFY_REMOVE_TEST,
+ #endif
+ USB_PNP_DRIVER_REGISTER_DEVICE,
+ USB_PNP_DRIVER_UNREGISTER_DEVICE,
+};
+
+enum UsbPnpNotifyRemoveType {
+ USB_PNP_NOTIFY_REMOVE_BUS_DEV_NUM,
+ USB_PNP_NOTIFY_REMOVE_INTERFACE_NUM,
+};
+
+enum {
+ USB_PNP_NOTIFY_MATCH_VENDOR = 0x0001,
+ USB_PNP_NOTIFY_MATCH_PRODUCT = 0x0002,
+ USB_PNP_NOTIFY_MATCH_DEV_LOW = 0x0004,
+ USB_PNP_NOTIFY_MATCH_DEV_HIGH = 0x0008,
+ USB_PNP_NOTIFY_MATCH_DEV_CLASS = 0x0010,
+ USB_PNP_NOTIFY_MATCH_DEV_SUBCLASS = 0x0020,
+ USB_PNP_NOTIFY_MATCH_DEV_PROTOCOL = 0x0040,
+ USB_PNP_NOTIFY_MATCH_INT_CLASS = 0x0080,
+ USB_PNP_NOTIFY_MATCH_INT_SUBCLASS = 0x0100,
+ USB_PNP_NOTIFY_MATCH_INT_PROTOCOL = 0x0200,
+ USB_PNP_NOTIFY_MATCH_INT_NUMBER = 0x0400,
+};
+
+struct UsbPnpNotifyServiceInfo {
+ uint32_t length;
+
+ int32_t devNum;
+ int32_t busNum;
+
+ int32_t interfaceLength;
+ uint8_t interfaceNumber[USB_PNP_INFO_MAX_INTERFACES];
+} __attribute__ ((packed));
+
+struct UsbPnpNotifyInterfaceInfo {
+ uint8_t interfaceClass;
+ uint8_t interfaceSubClass;
+ uint8_t interfaceProtocol;
+
+ uint8_t interfaceNumber;
+};
+
+struct UsbPnpNotifyDeviceInfo {
+ uint16_t vendorId;
+ uint16_t productId;
+
+ uint16_t bcdDeviceLow;
+ uint16_t bcdDeviceHigh;
+
+ uint8_t deviceClass;
+ uint8_t deviceSubClass;
+ uint8_t deviceProtocol;
+};
+
+struct UsbPnpNotifyMatchInfoTable {
+ uintptr_t usbDevAddr;
+ int32_t devNum;
+ int32_t busNum;
+
+ struct UsbPnpNotifyDeviceInfo deviceInfo;
+
+ uint8_t removeType;
+ uint8_t numInfos;
+
+ struct UsbPnpNotifyInterfaceInfo interfaceInfo[USB_PNP_INFO_MAX_INTERFACES];
+};
+
+struct UsbPnpAddRemoveInfo {
+ int32_t devNum;
+ int32_t busNum;
+ uint8_t interfaceNumber;
+ uint8_t interfaceClass;
+ uint8_t interfaceSubClass;
+ uint8_t interfaceProtocol;
+};
+
+#endif /* HDF_USB_PNP_MANAGE_H */
diff --git a/core/shared/include/power_state_token_if.h b/core/shared/include/power_state_token_if.h
index fe828f1eba4d05bbabedd0c0858e4fc0294a083b..0e054c01ae1515669e6b829421d6e45363e09800 100644
--- a/core/shared/include/power_state_token_if.h
+++ b/core/shared/include/power_state_token_if.h
@@ -10,10 +10,10 @@
#define POWER_STATE_TOKEN_IF_H
typedef enum {
- POWER_STATE_IDLE, /* Idle state */
- POWER_STATE_ACTIVE, /* Activated state */
- POWER_STATE_INACTIVE, /* Error state */
-} HdfPowerState;
+ PSM_STATE_IDLE, /* Idle state */
+ PSM_STATE_ACTIVE, /* Activated state */
+ PSM_STATE_INACTIVE, /* Error state */
+} HdfPsmState;
struct IPowerStateToken {
void (*AcquireWakeLock)(struct IPowerStateToken *);
diff --git a/core/shared/src/hdf_device_info.c b/core/shared/src/hdf_device_info.c
index 9228d56fd698d87d332f02f5daf7cf9207fc76b2..1fc5ac93d3b05acd3206decacc3135904f7cf900 100755
--- a/core/shared/src/hdf_device_info.c
+++ b/core/shared/src/hdf_device_info.c
@@ -29,6 +29,7 @@ void HdfDeviceInfoConstruct(struct HdfDeviceInfo *deviceInfo)
deviceInfo->svcName = NULL;
deviceInfo->moduleName = NULL;
deviceInfo->deviceMatchAttr = NULL;
+ deviceInfo->private = NULL;
}
struct HdfDeviceInfo *HdfDeviceInfoNewInstance()
@@ -49,6 +50,9 @@ void HdfDeviceInfoFreeInstance(struct HdfDeviceInfo *deviceInfo)
if (deviceInfo->isDynamic && deviceInfo->svcName != NULL) {
OsalMemFree((void *)deviceInfo->svcName);
}
+ if (deviceInfo->private != NULL) {
+ OsalMemFree((void *)deviceInfo->private);
+ }
OsalMemFree(deviceInfo);
}
}
diff --git a/include/audio/audio_accessory_if.h b/include/audio/audio_accessory_if.h
new file mode 100755
index 0000000000000000000000000000000000000000..a86532d2d329b26642f974bd2dbb2b48d2df6a4a
--- /dev/null
+++ b/include/audio/audio_accessory_if.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 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 AUDIO_ACCESSORY_IF_H
+#define AUDIO_ACCESSORY_IF_H
+
+#include "audio_host.h"
+#include "audio_control.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif
+#endif /* __cplusplus */
+
+struct AccessoryDevice {
+ const char *devAccessoryName;
+ struct AccessoryData *devData;
+ struct HdfDeviceObject *device;
+ struct DListHead list;
+ struct OsalMutex mutex;
+};
+
+struct AudioAccessoryOps {
+ const char *devAccessoryName;
+ struct AccessoryData *devData;
+ struct HdfDeviceObject *device;
+ struct DListHead list;
+};
+
+/* Accessory host is defined in accessory driver */
+struct AccessoryHost {
+ struct IDeviceIoService service; // accessory service
+ struct HdfDeviceObject *device; // accessory deovce
+ void *priv; // accessory private data
+};
+
+struct AccessoryData {
+ const char *drvAccessoryName;
+ /* Accessory driver callbacks */
+ int32_t (*Init)(struct AudioCard *, const struct AccessoryDevice *device);
+ int32_t (*Read)(const struct AccessoryDevice *, uint32_t, uint32_t *);
+ int32_t (*Write)(const struct AccessoryDevice *, uint32_t, uint32_t);
+ int32_t (*AiaoRead)(const struct AccessoryDevice *, uint32_t, uint32_t *);
+ int32_t (*AiaoWrite)(const struct AccessoryDevice *, uint32_t, uint32_t);
+
+ const struct AudioKcontrol *controls;
+ int numControls;
+};
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif
+#endif /* __cplusplus */
+
+#endif
diff --git a/include/audio/audio_codec_if.h b/include/audio/audio_codec_if.h
new file mode 100755
index 0000000000000000000000000000000000000000..d0636abb4f266dd0f358612267a51dcc5a85ac79
--- /dev/null
+++ b/include/audio/audio_codec_if.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 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 AUDIO_CODEC_IF_H
+#define AUDIO_CODEC_IF_H
+
+#include "audio_host.h"
+#include "audio_control.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif
+#endif /* __cplusplus */
+
+#define AUDIODRV_CTL_ELEM_IFACE_DAC 0 /* virtual dac device */
+#define AUDIODRV_CTL_ELEM_IFACE_ADC 1 /* virtual adc device */
+#define AUDIODRV_CTL_ELEM_IFACE_GAIN 2 /* virtual adc device */
+#define AUDIODRV_CTL_ELEM_IFACE_MIXER 3 /* virtual mixer device */
+#define AUDIODRV_CTL_ELEM_IFACE_ACODEC 4 /* Acodec device */
+#define AUDIODRV_CTL_ELEM_IFACE_PGA 5 /* PGA device */
+#define AUDIODRV_CTL_ELEM_IFACE_AIAO 6 /* AIAO device */
+
+struct VirtualAddress {
+ unsigned long acodecVir;
+ unsigned long aiaoVir;
+};
+
+struct CodecDevice {
+ const char *devCodecName;
+ struct CodecData *devData;
+ struct HdfDeviceObject *device;
+ struct DListHead list;
+ struct OsalMutex mutex;
+};
+
+/* codec related definitions */
+struct CodecData {
+ const char *drvCodecName;
+ /* Codec driver callbacks */
+ int32_t (*Init)(struct AudioCard *, struct CodecDevice *);
+ int32_t (*Read)(const struct CodecDevice *, uint32_t, uint32_t *);
+ int32_t (*Write)(const struct CodecDevice *, uint32_t, uint32_t);
+ int32_t (*AiaoRead)(const struct CodecDevice *, uint32_t, uint32_t *);
+ int32_t (*AiaoWrite)(const struct CodecDevice *, uint32_t, uint32_t);
+ const struct AudioKcontrol *controls;
+ int numControls;
+ const struct AudioSapmComponent *sapmComponents;
+ int numSapmComponent;
+ const struct AudioSapmRoute *sapmRoutes;
+ int numSapmRoutes;
+};
+
+/* Codec host is defined in codec driver */
+struct CodecHost {
+ struct IDeviceIoService service;
+ struct HdfDeviceObject *device;
+ unsigned long priv;
+ unsigned long aiaoPriv;
+};
+
+enum AudioRegParams {
+ PLAYBACK_VOLUME = 0,
+ CAPTURE_VOLUME,
+ PLAYBACK_MUTE,
+ CAPTURE_MUTE,
+ LEFT_GAIN,
+ RIGHT_GAIN,
+ EXTERNAL_CODEC_ENABLE,
+ INTERNALLY_CODEC_ENABLE,
+ RENDER_CHANNEL_MODE,
+ CAPTRUE_CHANNEL_MODE,
+};
+
+enum SapmRegParams {
+ LPGA_MIC = 0,
+ RPGA_MIC,
+ DACL2DACR,
+ DACR2DACL,
+};
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif
+#endif /* __cplusplus */
+
+#endif /* CODEC_CORE_H */
diff --git a/include/audio/audio_dai_if.h b/include/audio/audio_dai_if.h
new file mode 100755
index 0000000000000000000000000000000000000000..f6e756edf903ea7a95e21f1da0d58a64f11f7561
--- /dev/null
+++ b/include/audio/audio_dai_if.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 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 AUDIO_DAI_IF_H
+#define AUDIO_DAI_IF_H
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif
+#endif /* __cplusplus */
+
+struct DaiDevice {
+ const char *devDaiName;
+ struct DaiData *devData;
+ struct HdfDeviceObject *device;
+ struct DListHead list;
+};
+
+struct AudioDaiOps {
+ int32_t (*Startup)(const struct AudioCard *, const struct DaiDevice *);
+ int32_t (*HwParams)(const struct AudioCard *, const struct AudioPcmHwParams *, const struct DaiDevice *);
+ int32_t (*Trigger)(const struct AudioCard *, int, const struct DaiDevice *);
+};
+
+struct DaiData {
+ const char *drvDaiName;
+ /* DAI driver callbacks */
+ int32_t (*DaiInit)(const struct AudioCard *, const struct DaiDevice *);
+ /* ops */
+ const struct AudioDaiOps *ops;
+};
+
+/* Dai host is defined in dai driver */
+struct DaiHost {
+ struct IDeviceIoService service;
+ struct HdfDeviceObject *device;
+ void *priv;
+ bool daiInitFlag;
+};
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif
+#endif /* __cplusplus */
+
+#endif
diff --git a/include/audio/audio_dsp_if.h b/include/audio/audio_dsp_if.h
new file mode 100755
index 0000000000000000000000000000000000000000..31d42a88e88890a3428a642d962fe0984959cbd8
--- /dev/null
+++ b/include/audio/audio_dsp_if.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 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 AUDIO_DSP_IF_H
+#define AUDIO_DSP_IF_H
+#include "audio_host.h"
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif
+#endif /* __cplusplus */
+
+struct DspDevice {
+ const char *devDspName;
+ struct DspData *devData;
+ struct HdfDeviceObject *device;
+ struct DListHead list;
+};
+
+struct AudioDspOps {
+ int32_t (*Startup)(const struct AudioCard *, const struct DspDevice *);
+ int32_t (*HwParams)(const struct AudioCard *, const struct AudioPcmHwParams *, const struct DspDevice *);
+ int32_t (*Trigger)(struct AudioCard *, int, struct DspDevice *);
+};
+
+/* Dsp host is defined in dsp driver */
+struct DspHost {
+ struct IDeviceIoService service; // dsp service
+ struct HdfDeviceObject *device; // dsp device
+ void *priv; // dsp private data
+};
+
+struct DspData {
+ const char *drvDspName;
+ /* dsp driver callbacks */
+ int32_t (*DspInit)(const struct DspDevice *device);
+ int32_t (*Read)(const struct DspDevice *, uint8_t *, uint32_t);
+ int32_t (*Write)(const struct DspDevice *, uint8_t *, uint32_t);
+ int32_t (*decode)(const struct AudioCard *, const uint8_t *, const struct DspDevice *);
+ int32_t (*encode)(const struct AudioCard *, const uint8_t *, const struct DspDevice *);
+ int32_t (*Equalizer)(const struct AudioCard *, const uint8_t *, const struct DspDevice *);
+};
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif
+#endif /* __cplusplus */
+#endif
diff --git a/include/audio/audio_platform_if.h b/include/audio/audio_platform_if.h
new file mode 100755
index 0000000000000000000000000000000000000000..c2cc766b839dbbe38d708e6049706371cd5ac015
--- /dev/null
+++ b/include/audio/audio_platform_if.h
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 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 AUDIO_PLATFORM_IF_H
+#define AUDIO_PLATFORM_IF_H
+
+#include "audio_host.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif
+#endif /* __cplusplus */
+
+#define I2S_IOCFG2_BASE1 0x0020
+#define I2S_IOCFG2_BASE2 0x0024
+#define I2S_IOCFG2_BASE3 0x0028
+#define I2S_IOCFG2_BASE4 0x002C
+#define I2S_IOCFG2_BASE5 0x0030
+
+#define I2S_IOCFG2_BASE1_VAL 0x663
+#define I2S_IOCFG2_BASE2_VAL 0x673
+#define I2S_IOCFG2_BASE3_VAL 0x573
+#define I2S_IOCFG2_BASE4_VAL 0x473
+#define I2S_IOCFG2_BASE5_VAL 0x433
+
+#define I2S_IOCFG3_BASE1 0x44
+#define I2S_IOCFG3_BASE1_VAL 0x0600
+
+#define GPIO_BASE1 0x2010
+#define GPIO_BASE2 0x2400
+#define GPIO_BASE3 0x2010
+
+#define GPIO_BASE2_VAL 0x000000ff
+#define GPIO_BASE3_VAL 0x00000000
+
+#define IOCFG2_BASE_ADDR 0x112F0000
+#define IOCFG3_BASE_ADDR 0x10FF0000
+#define GPIO_BASE_ADDR 0x120D0000
+#define BASE_ADDR_REMAP_SIZE 0x10000
+
+struct CircleBufInfo {
+ uint32_t cirBufSize;
+ uint32_t trafBufSize;
+ uint32_t period;
+ uint32_t periodSize;
+ uint32_t periodCount;
+ unsigned long phyAddr;
+ uint32_t *virtAddr;
+ uint32_t wbufOffSet;
+ uint32_t wptrOffSet;
+ uint32_t runStatus;
+ uint32_t chnId;
+ uint32_t enable;
+ struct OsalMutex buffMutex;
+ uint64_t framesPosition;
+};
+
+struct PcmInfo {
+ /* The number of channels in a frame */
+ uint32_t channels;
+ /* The number of frames per second */
+ uint32_t rate;
+ uint32_t bitWidth;
+ uint32_t frameSize;
+ bool isBigEndian;
+ bool isSignedData;
+ uint32_t startThreshold;
+ uint32_t stopThreshold;
+ uint32_t silenceThreshold;
+ uint32_t totalStreamSize;
+};
+
+/* platform related definitions */
+struct AudioPlatformOps {
+ int32_t (*HwParams)(const struct AudioCard *, const struct AudioPcmHwParams *);
+ int32_t (*RenderTrigger)(struct AudioCard *, int);
+ int32_t (*CaptureTrigger)(struct AudioCard *, int);
+ uint32_t (*Pointer)(struct AudioCard *);
+ int32_t (*Write)(const struct AudioCard *, struct AudioTxData *);
+ int32_t (*Read)(const struct AudioCard *, struct AudioRxData *);
+ int32_t (*MmapWrite)(const struct AudioCard *, const struct AudioTxMmapData *);
+ int32_t (*MmapRead)(const struct AudioCard *, const struct AudioRxMmapData *);
+ int32_t (*RenderPrepare)(const struct AudioCard *);
+ int32_t (*CapturePrepare)(const struct AudioCard *);
+ int32_t (*RenderStart)(struct AudioCard *);
+ int32_t (*CaptureStart)(struct AudioCard *);
+ int32_t (*RenderStop)(struct AudioCard *);
+ int32_t (*CaptureStop)(struct AudioCard *);
+ int32_t (*RenderPause)(struct AudioCard *);
+ int32_t (*CapturePause)(struct AudioCard *);
+ int32_t (*RenderResume)(struct AudioCard *);
+ int32_t (*CaptureResume)(struct AudioCard *);
+};
+
+struct PlatformDevice {
+ const char *devPlatformName;
+ struct PlatformData *devData;
+ struct HdfDeviceObject *device;
+ struct DListHead list;
+};
+
+struct PlatformData {
+ const char *drvPlatformName;
+ /* platform driver callbacks */
+ int32_t (*PlatformInit)(const struct AudioCard *, const struct PlatformDevice *);
+ /* pcm creation and destruction */
+ int32_t (*PcmNew)(struct PlatformDevice *);
+ void (*PcmFree)(struct PlatformDevice *);
+ /* platform stream ops */
+ struct AudioPlatformOps *ops;
+};
+
+/* Platform host is defined in platform driver */
+struct PlatformHost {
+ struct IDeviceIoService service;
+ struct HdfDeviceObject *device;
+ void *priv;
+ bool platformInitFlag;
+ struct CircleBufInfo renderBufInfo;
+ struct CircleBufInfo captureBufInfo;
+ struct PcmInfo pcmInfo;
+};
+
+static inline struct PlatformHost *PlatformHostFromDevice(struct HdfDeviceObject *device)
+{
+ return (device == NULL) ? NULL : (struct PlatformHost *)device->service;
+}
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif
+#endif /* __cplusplus */
+
+#endif
diff --git a/include/core/hdf_pm.h b/include/core/hdf_pm.h
index fbf6e3af407fd2f5a0a5213f3ddad6f29b19b795..1c8412fa46b9fc2d16deabedd3b3c03d9cf9f815 100644
--- a/include/core/hdf_pm.h
+++ b/include/core/hdf_pm.h
@@ -1,10 +1,10 @@
-/*
- * 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.
- */
+/*
+ * 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 HDF_POWER_MANAGEMENT_H
#define HDF_POWER_MANAGEMENT_H
@@ -34,11 +34,6 @@ struct IPowerEventListener {
int (*Suspend)(struct HdfDeviceObject *deviceObject);
};
-static inline bool HdfPmIsWakeEvent(int sysEvent)
-{
- return sysEvent >= KEVENT_POWER_RESUME && sysEvent <= KEVENT_POWER_DISPLAY_ON;
-}
-
int HdfPmRegisterPowerListener(struct HdfDeviceObject *deviceObject, const struct IPowerEventListener *listener);
void HdfPmUnregisterPowerListener(struct HdfDeviceObject *deviceObject, const struct IPowerEventListener *listener);
void HdfPmAcquireDevice(struct HdfDeviceObject *deviceObject);
diff --git a/include/ethernet/eth_chip_driver.h b/include/ethernet/eth_chip_driver.h
new file mode 100755
index 0000000000000000000000000000000000000000..2c2372f55bb26f91c02bccba3dd1ea162067f246
--- /dev/null
+++ b/include/ethernet/eth_chip_driver.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2021-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 ETH_CHIP_DRIVER_H
+#define ETH_CHIP_DRIVER_H
+
+#include "eth_device.h"
+#include "net_device.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MAX_CHIPDRIVER_COUNT 16
+
+struct EthMacOps {
+ void (*MacInit)(void);
+ int32_t (*PortReset)(struct EthDevice *ethDevice);
+ int32_t (*PortInit)(struct EthDevice *ethDevice);
+};
+
+struct HdfEthMacChipDriver {
+ struct EthMacOps *ethMacOps; /**< Ethernet Mac some basic methods */
+};
+
+struct HdfEthNetDeviceData {
+ struct HdfEthMacChipDriver *macChipDriver; /**< Mac ChipDriver */
+};
+
+struct HdfEthNetDeviceData *GetEthNetDeviceData(const struct NetDevice *netDev);
+
+struct HdfEthChipDriverFactory {
+ const char *driverName;
+ int32_t (*InitEthDriver)(struct EthDevice *ethDevice);
+ int32_t (*DeinitEthDriver)(struct EthDevice *ethDevice);
+ struct HdfEthMacChipDriver *(*BuildMacDriver)(void);
+ void (*ReleaseMacDriver)(struct HdfEthMacChipDriver *chipDriver);
+ void (*GetMacAddr)(unsigned char *addr, int len);
+};
+
+struct HdfEthChipDriverManager {
+ struct HdfEthChipDriverFactory **chipFactoryInsts;
+ int32_t (*RegChipDriver)(struct HdfEthChipDriverFactory *factoryInst);
+ struct HdfEthChipDriverFactory *(*GetEthChipDriverByName)(const char *name);
+};
+
+struct HdfEthChipDriverManager *HdfEthGetChipDriverMgr(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ETH_CHIP_DRIVER_H */
diff --git a/include/wifi/net_device.h b/include/net/net_device.h
old mode 100644
new mode 100755
similarity index 96%
rename from include/wifi/net_device.h
rename to include/net/net_device.h
index 9b1b5963422b43c009390b37597128e8a3a5867a..17b19ef4717042b7c6b9633e67f7f9bb6d4d51b8
--- a/include/wifi/net_device.h
+++ b/include/net/net_device.h
@@ -465,7 +465,7 @@ typedef struct NetDevice {
char name[IFNAMSIZ]; /**< Network device name {@link IFNAMSIZ} */
NetLinkType LinkLayerType; /**< Data link layer type */
IfType funType; /**< Network port type */
- unsigned char macAddr[MAC_ADDR_SIZE]; /**< MAC address {@link MAC_ADDR_SIZE} */
+ uint8_t macAddr[MAC_ADDR_SIZE]; /**< MAC address {@link MAC_ADDR_SIZE} */
uint32_t flags; /**< Network port status */
uint32_t mtu; /**< Maximum transmission unit */
int32_t watchdogTime; /**< Watchdog duration */
@@ -506,6 +506,9 @@ struct NetDeviceInterFace {
int32_t (*changeMtu)(struct NetDevice *netDev, int32_t newMtu); /**< Changes the maximum number of
* transmission units.
*/
+ void (*linkStatusChanged)(struct NetDevice *netDev); /**< Detects the change of
+ * the Ethernet port connection status.
+ */
ProcessingResult (*specialEtherTypeProcess)(const struct NetDevice *netDev, NetBuf *buff);
/**< Performs private processing without
* involving network-layer data.
@@ -517,6 +520,7 @@ struct NetDeviceInterFace {
*
* @param ifName Indicates the pointer to the network device name.
* @param len Indicates the length of the network device name.
+ * @param type Indicates the data link type.
* @param ifCategory Indicates the network port category.
*
* @return Returns the structure {@link NetDevice} for the initialized network device if the operation is successful;
@@ -525,7 +529,7 @@ struct NetDeviceInterFace {
* @since 1.0
* @version 1.0
*/
-struct NetDevice *NetDeviceInit(const char *ifName, uint32_t len, NetIfCategory ifCategory);
+struct NetDevice *NetDeviceInit(const char *ifName, uint32_t len, NetLinkType type, NetIfCategory ifCategory);
/**
* @brief Deletes a network device.
@@ -544,7 +548,6 @@ int32_t NetDeviceDeInit(struct NetDevice *netDevice);
* @brief Adds a network device to a protocol stack.
*
* @param netDevice Indicates the pointer to the network device structure obtained during initialization.
- * @param ifType Indicates the network port type, as enumerated in {@link Protocol80211IfType}.
*
* @return Returns 0 if the operation is successful; returns a negative value representing {@link HDF_STATUS}
* if the operation fails.
@@ -552,7 +555,7 @@ int32_t NetDeviceDeInit(struct NetDevice *netDevice);
* @since 1.0
* @version 1.0
*/
-int32_t NetDeviceAdd(struct NetDevice *netDevice, Protocol80211IfType ifType);
+int32_t NetDeviceAdd(struct NetDevice *netDevice);
/**
* @brief Deletes a network device from a protocol stack.
@@ -695,6 +698,19 @@ int32_t NetIfSetMacAddr(struct NetDevice *netDevice, const unsigned char *macAdd
*/
int32_t NetIfSetLinkStatus(const struct NetDevice *netDevice, NetIfLinkStatus status);
+/**
+ * @brief Get the netdevice data link layer status.
+ *
+ * @param netDevice Indicates the pointer to the network device obtained during initialization.
+ * @param status save link layer status, as enumerated in {@link NetIfLinkSatus}.
+ *
+ * @return Returns 0 if the operation is successful; returns a non-zero value otherwise.
+ *
+ * @since 1.0
+ * @version 1.0
+ */
+int32_t NetIfGetLinkStatus(const struct NetDevice *netDevice, NetIfLinkStatus *status);
+
/**
* @brief Transfers the input data packets from the network side to a protocol stack.
*
diff --git a/include/osal/osal_time.h b/include/osal/osal_time.h
index b7496227116eb8e4ca88623a4b96b1f67300a1c7..37290924dffa53119e7a7eb817bae0b361c7244e 100644
--- a/include/osal/osal_time.h
+++ b/include/osal/osal_time.h
@@ -67,6 +67,17 @@ void OsalSleep(uint32_t sec);
*/
void OsalMSleep(uint32_t ms);
+/**
+ * @brief Describes thread sleep, in microsecond.
+ *
+ * When a thread invokes this function, the CPU is released and the thread enters the sleep state.
+ *
+ * @param us Indicates the sleep time, in microsecond.
+ * @since 1.0
+ * @version 1.0
+ */
+void OsalUSleep(uint32_t us);
+
/**
* @brief Obtains the second and microsecond time.
*
diff --git a/include/platform/adc_if.h b/include/platform/adc_if.h
new file mode 100644
index 0000000000000000000000000000000000000000..79c06a0a0e4761a2e9dca1dea5bc59e4c2a4eb89
--- /dev/null
+++ b/include/platform/adc_if.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 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 ADC_IF_H
+#define ADC_IF_H
+
+#include "hdf_platform.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif
+#endif /* __cplusplus */
+
+struct AdcIoMsg {
+ uint32_t number;
+ uint32_t channel;
+};
+
+DevHandle AdcOpen(uint32_t num);
+
+void AdcClose(DevHandle handle);
+
+int32_t AdcRead(DevHandle handle, uint32_t channel, uint32_t *val);
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif
+#endif /* __cplusplus */
+
+#endif /* ADC_IF_H */
diff --git a/include/platform/i2s_if.h b/include/platform/i2s_if.h
new file mode 100644
index 0000000000000000000000000000000000000000..a5106c68911062982c678c1799168b1c7a7843e6
--- /dev/null
+++ b/include/platform/i2s_if.h
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 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.
+ */
+
+/**
+ * @addtogroup I2S
+ * @{
+ *
+ * @brief Defines standard APIs of the (I2S) capabilities.
+ *
+ * The I2S module abstracts the I2S capabilities of different system platforms to provide stable APIs
+ * for driver development.
+ * This module can create and destroy I2S device handles, read and write I2S data,
+ * and obtain and set configuration parameters.
+ *
+ * @since 1.0
+ */
+
+/**
+ * @file i2s_if.h
+ *
+ * @brief Defines standard I2S-specific interfaces for driver development.
+ *
+ * A driver needs to use the I2S-specific interfaces for data writing and reading
+ * before performing any operations on an I2S-compliant device.
+ *
+ * @since 1.0
+ */
+
+#ifndef I2S_IF_H
+#define I2S_IF_H
+
+#include "hdf_platform.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif
+#endif /* __cplusplus */
+
+/**
+ * @brief Defines the configuration of an I2S device.
+ *
+ * @attention The specific I2S controller determines which variables in this structure are supported.
+ *
+ * @since 1.0
+ */
+
+#define I2S_DATA_TRANSFER_PERIOD 20
+
+enum I2sSampleRate {
+ I2S_SAMPLE_RATE_8K = 8,
+ I2S_SAMPLE_RATE_16K = 16,
+ I2S_SAMPLE_RATE_32K = 32,
+ I2S_SAMPLE_RATE_48K = 48,
+ I2S_SAMPLE_RATE_44_1K = 441, // 44.1k
+ I2S_SAMPLE_RATE_96K = 96,
+ I2S_SAMPLE_RATE_192K = 192,
+};
+
+enum I2sWordWidth {
+ I2S_WORDWIDTH_8BIT = 8,
+ I2S_WORDWIDTH_16BIT = 16,
+ I2S_WORDWIDTH_18BIT = 18,
+ I2S_WORDWIDTH_20BIT = 20,
+ I2S_WORDWIDTH_24BIT = 24,
+ I2S_WORDWIDTH_32BIT = 32,
+};
+
+enum I2sMode {
+ I2S_MODE_MASTER_TX_MODE,
+ I2S_MODE_MASTER_RX_MODE,
+ I2S_MODE_SLAVE_TX_MODE,
+ I2S_MODE_SLAVE_RX_MODE,
+};
+
+enum I2sLoopMode {
+ I2S_NORMAL_MODE,
+ I2S_LOOPBACK_MODE,
+};
+
+enum I2sChannel {
+ I2S_CHANNEL_LOW_LEFT,
+ I2S_CHANNEL_LOW_RIGHT,
+};
+
+enum I2sFrameLen {
+ I2S_FRAME_LEN_32BIT = 32,
+ I2S_FRAME_LEN_64BIT = 64,
+};
+
+enum I2sProtocolType {
+ I2S_PROTOCOL_I2S_STD,
+ I2S_PROTOCOL_I2S_MSB,
+ I2S_PROTOCOL_I2S_LSB,
+ I2S_PROTOCOL_PCM_STD,
+ I2S_PROTOCOL_PCM_SHORT,
+ I2S_PROTOCOL_PCM_LONG,
+};
+
+enum I2sPcmFscDelay {
+ I2S_PCM_START_1_CYCLE_BEFORE_MSB, /**< PCM FSC starts one cycle before MSB bit */
+ I2S_PCM_START_SYNC_MSB, /**< PCM FSC starts at the same time as MSB bit */
+};
+
+enum I2sDataSel {
+ I2S_RISING_EDGE_TX,
+ I2S_RISING_EDGE_RX,
+ I2S_FALLING_EDGE_TX,
+ I2S_FALLING_EDGE_RX,
+};
+
+enum I2sChannelMode {
+ I2S_CHANNEL_MODE_STEREO,
+ I2S_CHANNEL_MODE_MONO,
+};
+
+enum I2sChannelIfMode {
+ I2S_CHANNEL_IF_MODE_I2S,
+ I2S_CHANNEL_IF_MODE_PCM,
+};
+
+enum I2sWriteChannel {
+ I2S_WRITE_CHANNEL_AUDIO,
+ I2S_WRITE_CHANNEL_OUTPUT,
+};
+
+enum I2slFsSel {
+ I2SL_FS_SEL_1024_FS,
+ I2SL_FS_SEL_512_FS,
+ I2SL_FS_SEL_320_FS,
+ I2SL_FS_SEL_256_FS,
+ I2SL_FS_SEL_128_FS,
+ I2SL_FS_SEL_64_FS,
+};
+
+
+struct I2sCfg {
+ enum I2sSampleRate sampleRate; /**< I2S sample rate, 8k,16k,32k... */
+ enum I2sWordWidth width; /**< I2S word width, 8bit,16bit,20bit,24bit... */
+ enum I2sMode mode; /**< I2S mode, master/slave, tx/rx */
+ enum I2sPcmFscDelay syncMode; /**< pcm mode, FSC starts location */
+ enum I2sLoopMode loopMode; /**< is loopback */
+ enum I2sProtocolType type; /**< I2S protocol type */
+ enum I2sChannel channel;
+ enum I2sFrameLen frameLen;
+ enum I2sDataSel dataSel;
+ enum I2sChannelMode channelMode; /**< I2S mode,data channel */
+ uint8_t samplePrecision; /**< bit */
+ enum I2sChannelIfMode channelIfMode;
+ uint32_t mclk; /**< KHZ */
+ uint32_t bclk; /**< KHZ */
+ enum I2sWriteChannel writeChannel;
+ enum I2slFsSel i2slFsSel;
+ uint8_t Reserved[2];
+};
+
+/**
+ * @brief Defines the custom I2S transfer message.
+ *
+ * @attention The specific I2S controller determines whether speed, delayUs,
+ * and csChange are supported.
+ *
+ * @since 1.0
+ */
+struct I2sMsg {
+ uint8_t *wbuf; /**< Address of the write buffer */
+ uint8_t *rbuf; /**< Address of the read buffer */
+ uint32_t len; /**< Length of the read and write buffers. The read buffer and the write
+ * buffer have the same length. */
+ uint32_t *pRlen;
+};
+
+
+/**
+ * @brief Obtains the handle of an I2S controller.
+ *
+ * You must call this function before accessing the I2S bus.
+ *
+ * @param number Indicates the I2S controller ID.
+ *
+ * @return Returns the pointer to the {@link DevHandle} of the I2S controller if the operation is successful;
+ * returns NULL otherwise.
+ * @since 1.0
+ */
+DevHandle I2sOpen(int16_t number);
+
+ /**
+ * @brief Releases the handle of an I2S controller.
+ *
+ * If you no longer need to access the I2S controller, you should call this function to close its handle so as
+ * to release unused memory resources.
+ *
+ * @param handle Indicates the pointer to the device handle of the I2S controller.
+ *
+ * @since 1.0
+ */
+void I2sClose(DevHandle handle);
+void I2sEnable(DevHandle handle);
+void I2sDisable(DevHandle handle);
+int32_t I2sWrite(DevHandle handle, uint8_t *buf, uint32_t len, uint32_t *pWlen);
+int32_t I2sRead(DevHandle handle, uint8_t *buf, uint32_t len, uint32_t *pRlen);
+void I2sStartWrite(DevHandle handle);
+void I2sStopWrite(DevHandle handle);
+void I2sStartRead(DevHandle handle);
+void I2sStopRead(DevHandle handle);
+void I2sSetCfg(DevHandle handle, struct I2sCfg *cfg);
+void I2sGetCfg(DevHandle handle, struct I2sCfg *cfg);
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif
+#endif /* __cplusplus */
+
+#endif /* I2S_IF_H */
+/** @} */
diff --git a/include/platform/mipi_csi_if.h b/include/platform/mipi_csi_if.h
new file mode 100755
index 0000000000000000000000000000000000000000..8562842923d7b321b3ece761ae04b572eae2f2db
--- /dev/null
+++ b/include/platform/mipi_csi_if.h
@@ -0,0 +1,545 @@
+/*
+ * Copyright (c) 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.
+ */
+
+/**
+ * @addtogroup MIPI CSI
+ * @{
+ *
+ * @brief Defines standard MIPI CSI APIs for display driver development.
+ *
+ * This MIPI CSI module abstracts MIPI CSI capabilities of different system platforms to provide stable APIs
+ * for display driver development. You can use this module to obtain/release the MIPI CSI device handle,
+ * initialize the MIPI CSI device, and send/receive commands that interact with display peripherals.
+ *
+ * @since 1.0
+ */
+
+/**
+ * @file mipi_csi_if.h
+ *
+ * @brief Declares standard MIPI CSI APIs for display driver development.
+ *
+ *
+ *
+ * @since 1.0
+ */
+
+#ifndef MIPI_CSI_IF_H
+#define MIPI_CSI_IF_H
+
+#include "hdf_platform.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif
+#endif /* __cplusplus */
+
+/**
+ * @brief Maximum number of lanes supported by MIPI RX's Mipi device.
+ *
+ * @since 1.0
+ */
+#define MIPI_LANE_NUM 4
+
+/**
+ * @brief The maximum number of lanes supported by the LVDS device of Mipi Rx.
+ *
+ * @since 1.0
+ */
+#define LVDS_LANE_NUM 4
+
+/**
+ * @brief Defines the maximum number of virtual channels supported.
+ *
+ * @since 1.0
+ */
+#define WDR_VC_NUM 4
+
+/**
+ * @brief Define the number of synchronization codes for each virtual channel of LVDS.
+ *
+ * @since 1.0
+ */
+#define SYNC_CODE_NUM 4
+
+/**
+ * @brief Maximum 3 groups of extended data types.
+ *
+ * @since 1.0
+ */
+#define MAX_EXT_DATA_TYPE_NUM 3
+
+/**
+ * @brief Lane distribution of Mipi Rx.
+ *
+ * @since 1.0
+ */
+typedef enum {
+ LANE_DIVIDE_MODE_0 = 0,
+ LANE_DIVIDE_MODE_1 = 1,
+ LANE_DIVIDE_MODE_BUTT
+} LaneDivideMode;
+
+/**
+ * @brief MIPI RX input interface type.
+ *
+ * @since 1.0
+ */
+typedef enum {
+ /** mipi */
+ INPUT_MODE_MIPI = 0x0,
+ /** SUB_LVDS */
+ INPUT_MODE_SUBLVDS = 0x1,
+ /** LVDS */
+ INPUT_MODE_LVDS = 0x2,
+ /* HISPI */
+ INPUT_MODE_HISPI = 0x3,
+ /** CMOS */
+ INPUT_MODE_CMOS = 0x4,
+ /** BT601 */
+ INPUT_MODE_BT601 = 0x5,
+ /** BT656 */
+ INPUT_MODE_BT656 = 0x6,
+ /** BT1120 */
+ INPUT_MODE_BT1120 = 0x7,
+ /** MIPI Bypass */
+ INPUT_MODE_BYPASS = 0x8,
+ INPUT_MODE_BUTT
+} InputMode;
+
+/**
+ * @brief Mipi Rx, SLVS input rate.
+ *
+ * @since 1.0
+ */
+typedef enum {
+ /** output 1 pixel per clock */
+ MIPI_DATA_RATE_X1 = 0,
+ /** output 2 pixel per clock */
+ MIPI_DATA_RATE_X2 = 1,
+ MIPI_DATA_RATE_BUTT
+} MipiDataRate;
+
+/**
+ * @brief Mipi crop area properties.
+ *
+ * @since 1.0
+ */
+typedef struct {
+ int x;
+ int y;
+ unsigned int width;
+ unsigned int height;
+} ImgRect;
+
+/**
+ * @brief Type of data transmitted.
+ *
+ * @since 1.0
+ */
+typedef enum {
+ DATA_TYPE_RAW_8BIT = 0,
+ DATA_TYPE_RAW_10BIT,
+ DATA_TYPE_RAW_12BIT,
+ DATA_TYPE_RAW_14BIT,
+ DATA_TYPE_RAW_16BIT,
+ DATA_TYPE_YUV420_8BIT_NORMAL,
+ DATA_TYPE_YUV420_8BIT_LEGACY,
+ DATA_TYPE_YUV422_8BIT,
+ /** yuv422 8bit transform user define 16bit raw */
+ DATA_TYPE_YUV422_PACKED,
+ DATA_TYPE_BUTT
+} DataType;
+
+/**
+ * @brief Define YUV and RAW data format and bit depth.
+ *
+ * @since 1.0
+ */
+typedef struct {
+ uint8_t devno;
+ unsigned int num;
+ unsigned int extDataBitWidth[MAX_EXT_DATA_TYPE_NUM];
+ unsigned int extDataType[MAX_EXT_DATA_TYPE_NUM];
+} ExtDataType;
+
+/**
+ * @brief MIPI D-PHY WDR MODE defines
+ *
+ * @since 1.0
+ */
+typedef enum {
+ HI_MIPI_WDR_MODE_NONE = 0x0,
+ /** Virtual Channel */
+ HI_MIPI_WDR_MODE_VC = 0x1,
+ /** Data Type */
+ HI_MIPI_WDR_MODE_DT = 0x2,
+ /** DOL Mode */
+ HI_MIPI_WDR_MODE_DOL = 0x3,
+ HI_MIPI_WDR_MODE_BUTT
+} MipiWdrMode;
+
+/**
+ * @brief Mipi device properties.
+ *
+ * @since 1.0
+ */
+typedef struct {
+ /** data type: 8/10/12/14/16 bit */
+ DataType inputDataType;
+ /** MIPI WDR mode */
+ MipiWdrMode wdrMode;
+ /** laneId: -1 - disable */
+ short laneId[MIPI_LANE_NUM];
+
+ union {
+ /** used by the HI_MIPI_WDR_MODE_DT */
+ short dataType[WDR_VC_NUM];
+ };
+} MipiDevAttr;
+
+/**
+ * @brief LVDS WDR mode.
+ *
+ * @since 1.0
+ */
+typedef enum {
+ HI_WDR_MODE_NONE = 0x0,
+ HI_WDR_MODE_2F = 0x1,
+ HI_WDR_MODE_3F = 0x2,
+ HI_WDR_MODE_4F = 0x3,
+ HI_WDR_MODE_DOL_2F = 0x4,
+ HI_WDR_MODE_DOL_3F = 0x5,
+ HI_WDR_MODE_DOL_4F = 0x6,
+ HI_WDR_MODE_BUTT
+} WdrMode;
+
+/**
+ * @brief LVDS synchronization mode.
+ *
+ * @since 1.0
+ */
+typedef enum {
+ /** sensor SOL, EOL, SOF, EOF */
+ LVDS_SYNC_MODE_SOF = 0,
+ /** SAV, EAV */
+ LVDS_SYNC_MODE_SAV,
+ LVDS_SYNC_MODE_BUTT
+} LvdsSyncMode;
+
+/**
+ * @brief LVDS Vsync type.
+ *
+ * @since 1.0
+ */
+typedef enum {
+ LVDS_VSYNC_NORMAL = 0x00,
+ LVDS_VSYNC_SHARE = 0x01,
+ LVDS_VSYNC_HCONNECT = 0x02,
+ LVDS_VSYNC_BUTT
+} LvdsVsyncType;
+
+/**
+ * @brief LVDS Vsync column synchronization parameters.
+ *
+ * @since 1.0
+ */
+typedef struct {
+ LvdsVsyncType syncType;
+
+ /* hconnect vsync blanking len, valid when the syncType is LVDS_VSYNC_HCONNECT */
+ unsigned short hblank1;
+ unsigned short hblank2;
+} LvdsVsyncAttr;
+
+/**
+ * @brief Frame ID type.
+ *
+ * @since 1.0
+ */
+typedef enum {
+ LVDS_FID_NONE = 0x00,
+ /** frame identification id in SAV 4th */
+ LVDS_FID_IN_SAV = 0x01,
+ /** frame identification id in first data */
+ LVDS_FID_IN_DATA = 0x02,
+ LVDS_FID_BUTT
+} LvdsFidType;
+
+/**
+ * @brief Frame ID configuration information.
+ *
+ * @since 1.0
+ */
+typedef struct {
+ LvdsFidType fidType;
+
+ /** Sony DOL has the Frame Information Line, in DOL H-Connection mode,
+ should configure this flag as false to disable output the Frame Information Line */
+ unsigned char outputFil;
+} LvdsFidAttr;
+
+/**
+ * @brief LVDS bit size end mode.
+ *
+ * @since 1.0
+ */
+typedef enum {
+ LVDS_ENDIAN_LITTLE = 0x0,
+ LVDS_ENDIAN_BIG = 0x1,
+ LVDS_ENDIAN_BUTT
+} LvdsBitEndian;
+
+/**
+ * @brief LVDS / SubLVDS / HiSPi device properties.
+ *
+ * @since 1.0
+ */
+typedef struct {
+ /** data type: 8/10/12/14 bit */
+ DataType inputDataType;
+ /** WDR mode */
+ WdrMode wdrMode;
+
+ /** sync mode: SOF, SAV */
+ LvdsSyncMode syncMode;
+ /** normal, share, hconnect */
+ LvdsVsyncAttr vsyncAttr;
+ /** frame identification code */
+ LvdsFidAttr fidAttr;
+
+ /** data endian: little/big */
+ LvdsBitEndian dataEndian;
+ /** sync code endian: little/big */
+ LvdsBitEndian syncCodeEndian;
+ /** laneId: -1 - disable */
+ short laneId[LVDS_LANE_NUM];
+
+ /** each vc has 4 params, syncCode[i]:
+ syncMode is SYNC_MODE_SOF: SOF, EOF, SOL, EOL
+ syncMode is SYNC_MODE_SAV: invalid sav, invalid eav, valid sav, valid eav */
+ unsigned short syncCode[LVDS_LANE_NUM][WDR_VC_NUM][SYNC_CODE_NUM];
+} LvdsDevAttr;
+
+/**
+ * @brief The attribute of the combo device.
+ *
+ * Since MIPI RX can interface with CSI-2, LVDS, HiSPi and other timing, Mipi Rx is called a combo device.
+ *
+ * @since 1.0
+ */
+typedef struct {
+ /** device number */
+ uint8_t devno;
+ /** input mode: MIPI/LVDS/SUBLVDS/HISPI/DC */
+ InputMode inputMode;
+ MipiDataRate dataRate;
+ /** MIPI Rx device crop area (corresponding to the oringnal sensor input image size) */
+ ImgRect imgRect;
+
+ union {
+ MipiDevAttr mipiAttr;
+ LvdsDevAttr lvdsAttr;
+ };
+} ComboDevAttr;
+
+/**
+ * @brief PHY common mode voltage mode.
+ *
+ * @since 1.0
+ */
+typedef enum {
+ PHY_CMV_GE1200MV = 0x00,
+ PHY_CMV_LT1200MV = 0x01,
+ PHY_CMV_BUTT
+} PhyCmvMode;
+
+/**
+ * @brief Obtains the MIPI CSI device handle with a specified channel ID.
+ *
+ * @param id Indicates the MIPI CSI channel ID.
+ *
+ * @return Returns the MIPI CSI device handle if the operation is successful; returns NULL otherwise.
+ *
+ * @since 1.0
+ */
+DevHandle MipiCsiOpen(uint8_t id);
+
+/**
+ * @brief Releases the MIPI CSI device handle.
+ *
+ * @param handle Indicates the MIPI CSI device handle obtained via {@link MipiCsiOpen}.
+ *
+ * @since 1.0
+ */
+void MipiCsiClose(DevHandle handle);
+
+/**
+ * @brief Set the parameters of Mipi, CMOS or LVDS camera to the controller.
+ *
+ * The parameters including working mode, image area, image depth, data rate and physical channel.
+ *
+ * @param handle Indicates the MIPI CSI device handle obtained via {@link MipiCsiOpen}.
+ * @param pAttr Indicates the pointer to the attribute.
+ *
+ * @return Returns 0 if the operation is successful; returns a negative value otherwise.
+ *
+ * @since 1.0
+ */
+int32_t MipiCsiSetComboDevAttr(DevHandle handle, ComboDevAttr *pAttr);
+
+/**
+ * @brief Set common mode voltage mode.
+ *
+ * @param handle Indicates the MIPI CSI device handle obtained via {@link MipiCsiOpen}.
+ * @param devno There are 2 device numbers in total, pointing to 0 or 1.
+ * @param cmvMode Common mode voltage mode parameters.
+ *
+ * @return Returns 0 if the operation is successful; returns a negative value otherwise.
+ *
+ * @since 1.0
+ */
+int32_t MipiCsiSetPhyCmvmode(DevHandle handle, uint8_t devno, PhyCmvMode cmvMode);
+
+/**
+ * @brief Reset sensor.
+ *
+ * @param handle Indicates the MIPI CSI device handle obtained via {@link MipiCsiOpen}.
+ * @param snsResetSource The reset signal line number of sensor is called the reset source of sensor in software.
+ * sns is the abbreviation of sensor.
+ *
+ * @return Returns 0 if the operation is successful; returns a negative value otherwise.
+ *
+ * @since 1.0
+ */
+int32_t MipiCsiResetSensor(DevHandle handle, uint8_t snsResetSource);
+
+/**
+ * @brief Unreset sensor.
+ *
+ * @param handle Indicates the MIPI CSI device handle obtained via {@link MipiCsiOpen}.
+ * @param snsResetSource The reset signal line number of sensor is called the reset source of sensor in software.
+ * sns is the abbreviation of sensor.
+ *
+ * @return Returns 0 if the operation is successful; returns a negative value otherwise.
+ *
+ * @since 1.0
+ */
+int32_t MipiCsiUnresetSensor(DevHandle handle, uint8_t snsResetSource);
+
+/**
+ * @brief Reset Mipi Rx.
+ *
+ * Different s32WorkingViNum have different enSnsType.
+ *
+ * @param handle Indicates the MIPI CSI device handle obtained via {@link MipiCsiOpen}.
+ * @param comboDev MIPI RX or LVDS device type.
+ *
+ * @return Returns 0 if the operation is successful; returns a negative value otherwise.
+ *
+ * @since 1.0
+ */
+int32_t MipiCsiResetRx(DevHandle handle, uint8_t comboDev);
+
+/**
+ * @brief Uneset MIPI RX.
+ *
+ * @param handle Indicates the MIPI CSI device handle obtained via {@link MipiCsiOpen}.
+ * @param comboDev MIPI RX or LVDS device type.
+ *
+ * @return Returns 0 if the operation is successful; returns a negative value otherwise.
+ *
+ * @since 1.0
+ */
+int32_t MipiCsiUnresetRx(DevHandle handle, uint8_t comboDev);
+
+/**
+ * @brief Set the lane distribution of Mipi Rx.
+ *
+ * Select the specific mode according to the form of hardware connection.
+ *
+ * @param handle Indicates the MIPI CSI device handle obtained via {@link MipiCsiOpen}.
+ * @param laneDivideMode Lane division mode parameters.
+ *
+ * @since 1.0
+ */
+int32_t MipiCsiSetHsMode(DevHandle handle, LaneDivideMode laneDivideMode);
+
+/**
+ * @brief Enable Mipi clock.
+ *
+ * Decide whether to use Mipi or LVDS according to the ensnstype parameter
+ * passed by the upper layer function.
+ *
+ * @param handle Indicates the MIPI CSI device handle obtained via {@link MipiCsiOpen}.
+ * @param comboDev MIPI RX or LVDS device type.
+ *
+ * @return Returns 0 if the operation is successful; returns a negative value otherwise.
+ *
+ * @since 1.0
+ */
+int32_t MipiCsiEnableClock(DevHandle handle, uint8_t comboDev);
+
+/**
+ * @brief Disable the clock of Mipi device.
+ *
+ * @param handle Indicates the MIPI CSI device handle obtained via {@link MipiCsiOpen}.
+ * @param comboDev MIPI RX or LVDS device type.
+ *
+ * @return Returns 0 if the operation is successful; returns a negative value otherwise.
+ *
+ * @since 1.0
+ */
+int32_t MipiCsiDisableClock(DevHandle handle, uint8_t comboDev);
+
+/**
+ * @brief Enable the sensor clock on Mipi.
+ *
+ * @param handle Indicates the MIPI CSI device handle obtained via {@link MipiCsiOpen}.
+ * @param snsClkSource The clock signal line number of sensor, which is called the clock source of sensor in software.
+ * sns is the abbreviation of sensor.
+ *
+ * @return Returns 0 if the operation is successful; returns a negative value otherwise.
+ *
+ * @since 1.0
+ */
+int32_t MipiCsiEnableSensorClock(DevHandle handle, uint8_t snsClkSource);
+
+/**
+ * @brief Disable the sensor clock.
+ *
+ * @param handle Indicates the MIPI CSI device handle obtained via {@link MipiCsiOpen}.
+ * @param snsClkSource The clock signal line number of sensor, which is called the clock source of sensor in software.
+ * sns is the abbreviation of sensor.
+ *
+ * @return Returns 0 if the operation is successful; returns a negative value otherwise.
+ *
+ * @since 1.0
+ */
+int32_t MipiCsiDisableSensorClock(DevHandle handle, uint8_t snsClkSource);
+
+/**
+ * @brief Set YUV and RAW data format and bit depth.
+ *
+ * @param handle Indicates the MIPI CSI device handle obtained via {@link MipiCsiOpen}.
+ * @param dataType Pointer to image data format.
+ *
+ * @return Returns 0 if the operation is successful; returns a negative value otherwise.
+ *
+ * @since 1.0
+ */
+int32_t MipiCsiSetExtDataType(DevHandle handle, ExtDataType* dataType);
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif
+#endif /* __cplusplus */
+
+#endif /* MIPI_CSI_IF_H */
diff --git a/include/platform/mipi_dsi_if.h b/include/platform/mipi_dsi_if.h
index 9e173de593c618793bed9d4e1ef47c8ab271c6da..f3c3e646764b5a86420cb1b103dcb724bdfc5675 100644
--- a/include/platform/mipi_dsi_if.h
+++ b/include/platform/mipi_dsi_if.h
@@ -210,6 +210,7 @@ DevHandle MipiDsiOpen(uint8_t id);
* @since 1.0
*/
void MipiDsiClose(DevHandle handle);
+
/**
* @brief Sets configuration parameters for a MIPI DSI device.
*
@@ -278,6 +279,30 @@ int32_t MipiDsiTx(DevHandle handle, struct DsiCmdDesc *cmd);
*/
int32_t MipiDsiRx(DevHandle handle, struct DsiCmdDesc *cmd, int32_t readLen, uint8_t *out);
+/**
+* @brief attach a DSI device to its DSI host
+ *
+ * @param handle Indicates the MIPI DSI device handle obtained via {@link MipiDsiOpen}.
+ * @param name Indicates the name of a peripheral.
+ *
+ * @return Returns 0 if the operation is successful; returns a negative value otherwise.
+ *
+ * @since 1.0
+ */
+int32_t MipiDsiAttach(DevHandle handle, uint8_t *name);
+
+/**
+ * @brief Sets additional parameters for a MIPI DSI device.
+ *
+ * @param handle Indicates the MIPI DSI device handle obtained via {@link MipiDsiOpen}.
+ * @param panelData Indicates the pointer to the additional parameters.
+ *
+ * @return Returns 0 if the operation is successful; returns a negative value otherwise.
+ *
+ * @since 1.0
+ */
+int32_t MipiDsiSetDrvData(DevHandle handle, DevHandle *panelData);
+
#ifdef __cplusplus
#if __cplusplus
}
diff --git a/include/config/device_resource_if.h b/include/utils/device_resource_if.h
similarity index 100%
rename from include/config/device_resource_if.h
rename to include/utils/device_resource_if.h
diff --git a/include/utils/hdf_dlist.h b/include/utils/hdf_dlist.h
index 369cb089fea3c96dedad4344171323318be36af9..196a4d2c847dcf00456f1d16cf3ec949d9d2e2fd 100644
--- a/include/utils/hdf_dlist.h
+++ b/include/utils/hdf_dlist.h
@@ -143,6 +143,17 @@ static inline void DListMerge(struct DListHead *list, struct DListHead *head)
DListHeadInit(list);
}
+
+static inline int DlistGetCount(const struct DListHead *head)
+{
+ struct DListHead *next = head->next;
+ int count = 0;
+ while (next != head) {
+ next = next->next;
+ count++;
+ }
+ return count;
+}
/**
* @brief Obtains the address of a structure variable from its member address.
*
diff --git a/ability/sbuf/include/hdf_sbuf.h b/include/utils/hdf_sbuf.h
similarity index 100%
rename from ability/sbuf/include/hdf_sbuf.h
rename to include/utils/hdf_sbuf.h
diff --git a/include/wifi/hdf_wifi_event.h b/include/wifi/hdf_wifi_event.h
index cfae47b1196f1caa733c350e92d162ee9052bc75..3cccdb6ef666658a83a21188bd9ac9c3623a99ec 100644
--- a/include/wifi/hdf_wifi_event.h
+++ b/include/wifi/hdf_wifi_event.h
@@ -474,7 +474,11 @@ int32_t HdfWifiEventEapolRecv(const char *name, void *context);
* @since 1.0
* @version 1.0
*/
-int32_t HdfWifiEventResetResult(const uint8_t chipId, int32_t resetStatus);
+int32_t HdfWifiEventResetResult(const uint8_t chipId, int32_t resetStatus, const char *ifName);
+
+int32_t HdfWifiEventRemainOnChannel(const struct NetDevice *netDev, uint32_t freq, uint32_t duration);
+
+int32_t HdfWifiEventCancelRemainOnChannel(const struct NetDevice *netDev, uint32_t freq);
#ifdef __cplusplus
#if __cplusplus
diff --git a/include/wifi/hdf_wlan_chipdriver_manager.h b/include/wifi/hdf_wlan_chipdriver_manager.h
index d4277387157ef821f9a5a7df04598a0e839a0ffd..a0f0199b86d55a6259ad7e60195e9e10f9fc905e 100644
--- a/include/wifi/hdf_wlan_chipdriver_manager.h
+++ b/include/wifi/hdf_wlan_chipdriver_manager.h
@@ -132,7 +132,7 @@ struct HdfChipDriverFactory {
* @brief Obtains the maximum number of interfaces of a specified HdfChipDriverFactory instance.
*
* @param factory Indicates the pointer to the HdfChipDriverFactory instance.
- * @return Returns 0 if the maximum number of interfaces is obtained; returns a negative value otherwise.
+ * @return Returns the maximum number of interfaces.
*
* @since 1.0
* @version 1.0
diff --git a/include/wifi/wifi_mac80211_ops.h b/include/wifi/wifi_mac80211_ops.h
index 4e1244bfb85bbfd160ac30945607ffdc22486bce..aa26a666d813fd88d0fb34e64104ece6b87fde5c 100644
--- a/include/wifi/wifi_mac80211_ops.h
+++ b/include/wifi/wifi_mac80211_ops.h
@@ -168,7 +168,14 @@ enum Ieee80211ChannelWidth {
*/
enum WlanWorkMode {
WLAN_WORKMODE_STA = 2, /**< STA mode */
- WLAN_WORKMODE_AP = 3 /**< AP mode */
+ WLAN_WORKMODE_AP = 3, /**< AP mode */
+ WLAN_WORKMODE_AP_VLAN,
+ WLAN_WORKMODE_WDS,
+ WLAN_WORKMODE_MONITOR,
+ WLAN_WORKMODE_MESH_POINT,
+ WLAN_WORKMODE_P2P_CLIENT,
+ WLAN_WORKMODE_P2P_GO,
+ WLAN_WORKMODE_P2P_DEVICE,
};
/**
@@ -302,7 +309,7 @@ struct WlanScanRequest {
uint8_t freqsCount; /**< Number of frequencies */
uint8_t *bssid; /**< BSSID to scan for */
struct WlanSSID *ssids; /**< SSIDs to scan for */
- uint16_t *freqs; /**< An array of frequencies */
+ uint32_t *freqs; /**< An array of frequencies */
uint32_t extraIEsLen; /**< Length of an extended information element (IE) */
uint8_t *extraIEs; /**< Extended IEs */
};
@@ -581,6 +588,24 @@ struct HdfMac80211BaseOps {
* @version 1.0
*/
int32_t (*GetHwCapability)(NetDevice *netDev, struct WlanHwCapability **capability);
+
+ int32_t (*RemainOnChannel)(NetDevice *netDev, WifiOnChannel *onChannel);
+
+ int32_t (*CancelRemainOnChannel)(NetDevice *netDev);
+
+ int32_t (*ProbeReqReport)(NetDevice *netDev, int32_t report);
+
+ int32_t (*AddIf)(NetDevice *netDev, WifiIfAdd *ifAdd);
+
+ int32_t (*RemoveIf)(NetDevice *netDev, WifiIfRemove *ifRemove);
+
+ int32_t (*SetApWpsP2pIe)(NetDevice *netDev, WifiAppIe *appIe);
+
+ int32_t (*GetDriverFlag)(struct NetDevice *netDev, WifiGetDrvFlags **params);
+
+ int32_t (*SendAction)(struct NetDevice *netDev, WifiActionData *actionData);
+
+ int32_t (*GetIftype)(struct NetDevice *netDev, uint8_t *iftype);
};
/**
diff --git a/model/audio/common/include/audio_accessory_base.h b/model/audio/common/include/audio_accessory_base.h
new file mode 100755
index 0000000000000000000000000000000000000000..ab0f94a06eb5bef64d733212169221c5fda576c7
--- /dev/null
+++ b/model/audio/common/include/audio_accessory_base.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 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 AUDIO_ACCESSORY_BASE_H
+#define AUDIO_ACCESSORY_BASE_H
+
+#include "audio_host.h"
+#include "audio_control.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif
+#endif /* __cplusplus */
+
+enum I2sFrequency {
+ I2S_SAMPLE_FREQUENCY_8000 = 8000, /* 8kHz sample_rate */
+ I2S_SAMPLE_FREQUENCY_11025 = 11025, /* 11.025kHz sample_rate */
+ I2S_SAMPLE_FREQUENCY_12000 = 12000, /* 12kHz sample_rate */
+ I2S_SAMPLE_FREQUENCY_16000 = 16000, /* 16kHz sample_rate */
+ I2S_SAMPLE_FREQUENCY_22050 = 22050, /* 22.050kHz sample_rate */
+ I2S_SAMPLE_FREQUENCY_24000 = 24000, /* 24kHz sample_rate */
+ I2S_SAMPLE_FREQUENCY_32000 = 32000, /* 32kHz sample_rate */
+ I2S_SAMPLE_FREQUENCY_44100 = 44100, /* 44.1kHz sample_rate */
+ I2S_SAMPLE_FREQUENCY_48000 = 48000, /* 48kHz sample_rate */
+ I2S_SAMPLE_FREQUENCY_64000 = 64000, /* 64kHz sample_rate */
+ I2S_SAMPLE_FREQUENCY_88200 = 88200, /* 88.2kHz sample_rate */
+ I2S_SAMPLE_FREQUENCY_96000 = 96000 /* 96kHz sample_rate */
+};
+
+enum I2sFrequencyRegVal {
+ I2S_SAMPLE_FREQUENCY_REG_VAL_8000 = 0x0, /* 8kHz sample_rate */
+ I2S_SAMPLE_FREQUENCY_REG_VAL_11025 = 0x1, /* 11.025kHz sample_rate */
+ I2S_SAMPLE_FREQUENCY_REG_VAL_12000 = 0x2, /* 12kHz sample_rate */
+ I2S_SAMPLE_FREQUENCY_REG_VAL_16000 = 0x3, /* 16kHz sample_rate */
+ I2S_SAMPLE_FREQUENCY_REG_VAL_22050 = 0x4, /* 22.050kHz sample_rate */
+ I2S_SAMPLE_FREQUENCY_REG_VAL_24000 = 0x5, /* 24kHz sample_rate */
+ I2S_SAMPLE_FREQUENCY_REG_VAL_32000 = 0x6, /* 32kHz sample_rate */
+ I2S_SAMPLE_FREQUENCY_REG_VAL_44100 = 0x7, /* 44.1kHz sample_rate */
+ I2S_SAMPLE_FREQUENCY_REG_VAL_48000 = 0x8, /* 48kHz sample_rate */
+ I2S_SAMPLE_FREQUENCY_REG_VAL_64000 = 0x9, /* 64kHz sample_rate */
+ I2S_SAMPLE_FREQUENCY_REG_VAL_88200 = 0xA, /* 88.2kHz sample_rate */
+ I2S_SAMPLE_FREQUENCY_REG_VAL_96000 = 0xB /* 96kHz sample_rate */
+};
+
+enum I2sFormatRegVal {
+ I2S_SAMPLE_FORMAT_REG_VAL_MSB_24 = 0x2, /* MSB-justified data up to 24 bits */
+ I2S_SAMPLE_FORMAT_REG_VAL_24 = 0x3, /* I2S data up to 24 bits */
+ I2S_SAMPLE_FORMAT_REG_VAL_LSB_16 = 0x4, /* LSB-justified 16-bit data */
+ I2S_SAMPLE_FORMAT_REG_VAL_LSB_18 = 0x5, /* LSB-justified 18-bit data */
+ I2S_SAMPLE_FORMAT_REG_VAL_LSB_20 = 0x6, /* LSB-justified 20-bit data */
+ I2S_SAMPLE_FORMAT_REG_VAL_LSB_24 = 0x7, /* LSB-justified 24-bit data */
+};
+
+int32_t FormatToBitWidth(enum AudioFormat format, uint16_t *bitWidth);
+int32_t RateToFrequency(uint32_t rate, uint16_t *freq);
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif
+#endif /* __cplusplus */
+
+#endif
diff --git a/model/audio/common/include/audio_codec_base.h b/model/audio/common/include/audio_codec_base.h
new file mode 100755
index 0000000000000000000000000000000000000000..f4d5bf3b30c29715e1a8a722e4e83f3d166f6a5c
--- /dev/null
+++ b/model/audio/common/include/audio_codec_base.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 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 AUDIO_CODEC_BASE_H
+#define AUDIO_CODEC_BASE_H
+
+#include "audio_codec_if.h"
+#include "audio_core.h"
+#include "osal_io.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif
+#endif /* __cplusplus */
+
+int32_t CodecDeviceReadReg(const struct CodecDevice *codec, uint32_t reg, uint32_t *value);
+int32_t CodecDeviceWriteReg(const struct CodecDevice *codec, uint32_t reg, uint32_t value);
+int32_t CodecAiaoDeviceReadReg(const struct CodecDevice *codec, uint32_t reg, uint32_t *value);
+int32_t CodecAiaoDeviceWriteReg(const struct CodecDevice *codec, uint32_t reg, uint32_t value);
+int32_t CodecGetServiceName(const struct HdfDeviceObject *device, const char **drvCodecName);
+int32_t CodecGetDaiName(const struct HdfDeviceObject *device, const char **drvDaiName);
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif
+#endif /* __cplusplus */
+
+#endif
diff --git a/model/audio/common/include/audio_platform_base.h b/model/audio/common/include/audio_platform_base.h
new file mode 100755
index 0000000000000000000000000000000000000000..72a9608c00157409484e92cef17c85e62537003f
--- /dev/null
+++ b/model/audio/common/include/audio_platform_base.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 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 AUDIO_PLATFORM_BASE_H
+#define AUDIO_PLATFORM_BASE_H
+
+#include "audio_platform_if.h"
+#include "audio_host.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif
+#endif /* __cplusplus */
+
+enum DataBitWidth {
+ DATA_BIT_WIDTH8 = 8, /* 8 bit witdth */
+ DATA_BIT_WIDTH16 = 16, /* 16 bit witdth */
+ DATA_BIT_WIDTH18 = 18, /* 18 bit witdth */
+ DATA_BIT_WIDTH20 = 20, /* 20 bit witdth */
+ DATA_BIT_WIDTH24 = 24, /* 24 bit witdth */
+ DATA_BIT_WIDTH32 = 32, /* 32 bit witdth */
+};
+
+struct PlatformData *PlatformDataFromDevice(const struct AudioCard *card);
+int32_t PlatformCreatePlatformHost(const struct AudioCard *card, struct PlatformHost **platformHost);
+int32_t AudioDataBigEndianChange(char *srcData, uint32_t audioLen, enum DataBitWidth bitWidth);
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif
+#endif /* __cplusplus */
+
+#endif /* CODEC_CORE_H */
diff --git a/model/audio/common/src/audio_accessory_base.c b/model/audio/common/src/audio_accessory_base.c
new file mode 100755
index 0000000000000000000000000000000000000000..715440022f0330ad3440b6501ac106e6e1b1b32a
--- /dev/null
+++ b/model/audio/common/src/audio_accessory_base.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 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 "audio_accessory_base.h"
+#include "audio_device_log.h"
+
+#define HDF_LOG_TAG audio_accessory_base
+
+int32_t FormatToBitWidth(enum AudioFormat format, uint16_t *bitWidth)
+{
+ // current set default format(standard) for 16/24 bit
+ switch (format) {
+ case AUDIO_FORMAT_PCM_16_BIT:
+ *bitWidth = I2S_SAMPLE_FORMAT_REG_VAL_24;
+ break;
+ case AUDIO_FORMAT_PCM_24_BIT:
+ *bitWidth = I2S_SAMPLE_FORMAT_REG_VAL_24;
+ break;
+ default:
+ AUDIO_DEVICE_LOG_ERR("format: %d is not support.", format);
+ return HDF_ERR_NOT_SUPPORT;
+ }
+ return HDF_SUCCESS;
+}
+
+int32_t RateToFrequency(uint32_t rate, uint16_t *freq)
+{
+ switch (rate) {
+ case I2S_SAMPLE_FREQUENCY_8000:
+ *freq = I2S_SAMPLE_FREQUENCY_REG_VAL_8000;
+ break;
+ case I2S_SAMPLE_FREQUENCY_11025:
+ *freq = I2S_SAMPLE_FREQUENCY_REG_VAL_11025;
+ break;
+ case I2S_SAMPLE_FREQUENCY_12000:
+ *freq = I2S_SAMPLE_FREQUENCY_REG_VAL_12000;
+ break;
+ case I2S_SAMPLE_FREQUENCY_16000:
+ *freq = I2S_SAMPLE_FREQUENCY_REG_VAL_16000;
+ break;
+ case I2S_SAMPLE_FREQUENCY_22050:
+ *freq = I2S_SAMPLE_FREQUENCY_REG_VAL_22050;
+ break;
+ case I2S_SAMPLE_FREQUENCY_24000:
+ *freq = I2S_SAMPLE_FREQUENCY_REG_VAL_24000;
+ break;
+ case I2S_SAMPLE_FREQUENCY_32000:
+ *freq = I2S_SAMPLE_FREQUENCY_REG_VAL_32000;
+ break;
+ case I2S_SAMPLE_FREQUENCY_44100:
+ *freq = I2S_SAMPLE_FREQUENCY_REG_VAL_44100;
+ break;
+ case I2S_SAMPLE_FREQUENCY_48000:
+ *freq = I2S_SAMPLE_FREQUENCY_REG_VAL_48000;
+ break;
+ case I2S_SAMPLE_FREQUENCY_64000:
+ *freq = I2S_SAMPLE_FREQUENCY_REG_VAL_64000;
+ break;
+ case I2S_SAMPLE_FREQUENCY_88200:
+ *freq = I2S_SAMPLE_FREQUENCY_REG_VAL_88200;
+ break;
+ case I2S_SAMPLE_FREQUENCY_96000:
+ *freq = I2S_SAMPLE_FREQUENCY_REG_VAL_96000;
+ break;
+ default:
+ AUDIO_DEVICE_LOG_ERR("rate: %d is not support.", rate);
+ return HDF_ERR_NOT_SUPPORT;
+ }
+ return HDF_SUCCESS;
+}
diff --git a/model/audio/common/src/audio_codec_base.c b/model/audio/common/src/audio_codec_base.c
new file mode 100755
index 0000000000000000000000000000000000000000..0bef4037f82ace8998698a41b0fea4699b07c93e
--- /dev/null
+++ b/model/audio/common/src/audio_codec_base.c
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 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 "audio_codec_base.h"
+
+#define HDF_LOG_TAG audio_codec_base
+
+int32_t CodecDeviceReadReg(const struct CodecDevice *codec, uint32_t reg, uint32_t *val)
+{
+ unsigned long acodecVir;
+ struct VirtualAddress *virtualAdd = NULL;
+ AUDIO_DRIVER_LOG_DEBUG("entry");
+
+ if ((codec == NULL) || (codec->device == NULL) || (val == NULL)) {
+ AUDIO_DRIVER_LOG_ERR("input param codec or codec->device is NULL.");
+ return HDF_ERR_INVALID_OBJECT;
+ }
+ virtualAdd = (struct VirtualAddress *)((volatile uintptr_t)codec->device->priv);
+ if (virtualAdd == NULL) {
+ AUDIO_DRIVER_LOG_ERR("virtualAdd is NULL.");
+ return HDF_ERR_INVALID_OBJECT;
+ }
+ acodecVir = virtualAdd->acodecVir;
+ *val = OSAL_READL((void *)(volatile uintptr_t)(acodecVir + reg));
+
+ AUDIO_DRIVER_LOG_DEBUG("success");
+ return HDF_SUCCESS;
+}
+
+int32_t CodecDeviceWriteReg(const struct CodecDevice *codec, uint32_t reg, uint32_t value)
+{
+ unsigned long acodecVir;
+ struct VirtualAddress *virtualAdd = NULL;
+ AUDIO_DRIVER_LOG_DEBUG("entry");
+
+ if ((codec == NULL) || (codec->device == NULL)) {
+ AUDIO_DRIVER_LOG_ERR("param codec or codec->device is NULL.");
+ return HDF_ERR_INVALID_OBJECT;
+ }
+
+ virtualAdd = (struct VirtualAddress *)((volatile uintptr_t)codec->device->priv);
+ if (virtualAdd == NULL) {
+ AUDIO_DRIVER_LOG_ERR("virtualAdd is NULL.");
+ return HDF_ERR_INVALID_OBJECT;
+ }
+
+ acodecVir = virtualAdd->acodecVir;
+ OSAL_WRITEL(value, (void *)(volatile uintptr_t)(acodecVir + reg));
+
+ AUDIO_DRIVER_LOG_DEBUG("success");
+ return HDF_SUCCESS;
+}
+
+int32_t CodecAiaoDeviceReadReg(const struct CodecDevice *codec, uint32_t reg, uint32_t *val)
+{
+ unsigned long aiaoVir;
+ struct VirtualAddress *virtualAdd = NULL;
+ AUDIO_DRIVER_LOG_DEBUG("entry");
+
+ if ((codec == NULL) || (codec->device == NULL) || (val == NULL)) {
+ AUDIO_DRIVER_LOG_ERR("codec or codec->device is NULL.");
+ return HDF_ERR_INVALID_OBJECT;
+ }
+
+ virtualAdd = (struct VirtualAddress *)((volatile uintptr_t)codec->device->priv);
+ if (virtualAdd == NULL) {
+ AUDIO_DRIVER_LOG_ERR("virtualAdd is NULL.");
+ return HDF_ERR_INVALID_OBJECT;
+ }
+
+ aiaoVir = virtualAdd->aiaoVir;
+ *val = OSAL_READL((void *)(volatile uintptr_t)(aiaoVir + reg));
+
+ AUDIO_DRIVER_LOG_DEBUG("success");
+ return HDF_SUCCESS;
+}
+
+int32_t CodecAiaoDeviceWriteReg(const struct CodecDevice *codec, uint32_t reg, uint32_t value)
+{
+ unsigned long aiaoVir;
+ struct VirtualAddress *virtualAdd = NULL;
+ AUDIO_DRIVER_LOG_DEBUG("entry");
+
+ if ((codec == NULL) || (codec->device == NULL)) {
+ AUDIO_DRIVER_LOG_ERR("codec or codec->device is NULL.");
+ return HDF_ERR_INVALID_OBJECT;
+ }
+ virtualAdd = (struct VirtualAddress *)((volatile uintptr_t)codec->device->priv);
+ if (virtualAdd == NULL) {
+ AUDIO_DRIVER_LOG_ERR("virtualAdd is NULL.");
+ return HDF_ERR_INVALID_OBJECT;
+ }
+
+ aiaoVir = virtualAdd->aiaoVir;
+ OSAL_WRITEL(value, (void *)(volatile uintptr_t)(aiaoVir + reg));
+
+ AUDIO_DRIVER_LOG_DEBUG("success");
+ return HDF_SUCCESS;
+}
+
+int32_t CodecGetServiceName(const struct HdfDeviceObject *device, const char **drvCodecName)
+{
+ const struct DeviceResourceNode *node = NULL;
+ struct DeviceResourceIface *drsOps = NULL;
+ int32_t ret;
+
+ if (device == NULL) {
+ AUDIO_DRIVER_LOG_ERR("input device para is nullptr.");
+ return HDF_FAILURE;
+ }
+
+ node = device->property;
+ if (node == NULL) {
+ AUDIO_DRIVER_LOG_ERR("node instance is nullptr.");
+ return HDF_FAILURE;
+ }
+ drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
+ if (drsOps == NULL || drsOps->GetString == NULL) {
+ AUDIO_DRIVER_LOG_ERR("from resouce get drsOps fail!");
+ return HDF_FAILURE;
+ }
+
+ ret = drsOps->GetString(node, "serviceName", drvCodecName, 0);
+ if (ret != HDF_SUCCESS) {
+ AUDIO_DRIVER_LOG_ERR("read codecServiceName fail!");
+ return ret;
+ }
+
+ return HDF_SUCCESS;
+}
+
+int32_t CodecGetDaiName(const struct HdfDeviceObject *device, const char **drvDaiName)
+{
+ const struct DeviceResourceNode *node = NULL;
+ struct DeviceResourceIface *drsOps = NULL;
+ int32_t ret;
+
+ if (device == NULL) {
+ AUDIO_DRIVER_LOG_ERR("input para is NULL.");
+ return HDF_FAILURE;
+ }
+
+ node = device->property;
+ if (node == NULL) {
+ AUDIO_DRIVER_LOG_ERR("drs node is NULL.");
+ return HDF_FAILURE;
+ }
+ drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
+ if (drsOps == NULL || drsOps->GetString == NULL) {
+ AUDIO_DRIVER_LOG_ERR("drs ops failed!");
+ return HDF_FAILURE;
+ }
+
+ ret = drsOps->GetString(node, "codecDaiName", drvDaiName, 0);
+ if (ret != HDF_SUCCESS) {
+ AUDIO_DRIVER_LOG_ERR("read codecDaiName fail!");
+ return ret;
+ }
+
+ return HDF_SUCCESS;
+}
diff --git a/model/audio/common/src/audio_platform_base.c b/model/audio/common/src/audio_platform_base.c
new file mode 100755
index 0000000000000000000000000000000000000000..3f6747519579c1ef6ebfc3c4b1d4945d5568d813
--- /dev/null
+++ b/model/audio/common/src/audio_platform_base.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 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 "audio_platform_base.h"
+#include "audio_core.h"
+
+#define HDF_LOG_TAG audio_platform_base
+struct PlatformData *PlatformDataFromDevice(const struct AudioCard *card)
+{
+ if (card == NULL || card->rtd == NULL || card->rtd->platform == NULL) {
+ AUDIO_DRIVER_LOG_ERR("param is null.");
+ return NULL;
+ }
+ return card->rtd->platform->devData;
+}
+
+int32_t PlatformCreatePlatformHost(const struct AudioCard *card, struct PlatformHost **platformHost)
+{
+ if (platformHost == NULL) {
+ AUDIO_DRIVER_LOG_ERR("input param platformHost is invalid.");
+ return HDF_ERR_INVALID_PARAM;
+ }
+ if (card == NULL || card->rtd == NULL || card->rtd->platform == NULL) {
+ AUDIO_DRIVER_LOG_ERR("input para is NULL.");
+ return HDF_FAILURE;
+ }
+
+ *platformHost = PlatformHostFromDevice(card->rtd->platform->device);
+ if (*platformHost == NULL) {
+ AUDIO_DRIVER_LOG_ERR("PlatformHostFromDevice faile.");
+ return HDF_FAILURE;
+ }
+ return HDF_SUCCESS;
+}
+
+int32_t AudioDataBigEndianChange(char *srcData, uint32_t audioLen, enum DataBitWidth bitWidth)
+{
+ if (srcData == NULL) {
+ AUDIO_DRIVER_LOG_ERR("srcData is NULL.");
+ return HDF_FAILURE;
+ }
+ uint64_t i;
+ uint16_t framesize;
+ char *changeData = srcData;
+ uint32_t *pData = (uint32_t *)changeData;
+
+ switch (bitWidth) {
+ case DATA_BIT_WIDTH8:
+ return HDF_SUCCESS;
+ case DATA_BIT_WIDTH24:
+ framesize = 3; /* 3 byte , convert step is 3 byte */
+ for (i = 0; i < audioLen; i += framesize) {
+ // swap the first and the third byte, second and fourth unchanged
+ *pData = ((((*pData) >> 0x10) & 0x000000FF) |
+ ((*pData) & 0xFF00FF00) |
+ (((*pData) << 0x10) & 0x00FF0000));
+ changeData += framesize;
+ pData = (uint32_t *)changeData;
+ }
+ break;
+ case DATA_BIT_WIDTH16:
+ default:
+ framesize = 4; /* 2 byte, convert step is 4 byte */
+ for (i = 0; i < audioLen; i += framesize) {
+ // swap the first and second byte, swap the third and fourth byte
+ *pData = ((((*pData) << 0x08) & 0xFF00FF00) |
+ (((*pData) >> 0x08) & 0x00FF00FF));
+ pData++;
+ }
+ break;
+ }
+ AUDIO_DRIVER_LOG_DEBUG("audioLen = %d\n", audioLen);
+ return HDF_SUCCESS;
+}
diff --git a/model/audio/core/include/audio_control.h b/model/audio/core/include/audio_control.h
new file mode 100755
index 0000000000000000000000000000000000000000..76ec94c6aca6bd558f1abf6b50ceb94bbb939ca4
--- /dev/null
+++ b/model/audio/core/include/audio_control.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 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 AUDIO_CONTROL_H
+#define AUDIO_CONTROL_H
+
+#include "hdf_dlist.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif
+#endif /* __cplusplus */
+
+struct AudioCtrlElemId {
+ const char *cardServiceName;
+ int32_t iface;
+ const char *itemName; /* ASCII name of item */
+};
+
+struct AudioCtrlElemInfo {
+ struct AudioCtrlElemId id;
+ uint32_t count; /* count of values */
+ int32_t type; /* R: value type - AUDIODRV_CTL_ELEM_IFACE_MIXER_* */
+ int32_t min; /* R: minimum value */
+ int32_t max; /* R: maximum value */
+};
+
+struct AudioCtrlElemValue {
+ struct AudioCtrlElemId id;
+ uint32_t value[2];
+};
+
+struct AudioKcontrol;
+typedef int32_t (*KconfigInfo_t)(const struct AudioKcontrol *kcontrol, struct AudioCtrlElemInfo *elemInfo);
+typedef int32_t (*KconfigGet_t)(const struct AudioKcontrol *kcontrol, struct AudioCtrlElemValue *elemValue);
+typedef int32_t (*KconfigSet_t)(const struct AudioKcontrol *kcontrol, const struct AudioCtrlElemValue *elemValue);
+
+/* mixer control */
+struct AudioMixerControl {
+ int32_t min;
+ int32_t max;
+ int32_t platformMax;
+ uint32_t mask;
+ uint32_t reg;
+ uint32_t rreg; /* right sound channel reg */
+ uint32_t shift;
+ uint32_t rshift; /* right sound channel reg shift */
+ uint32_t invert;
+};
+
+struct AudioKcontrol {
+ const char *name; /* ASCII name of item */
+ int32_t iface;
+ KconfigInfo_t Info;
+ KconfigGet_t Get;
+ KconfigSet_t Set;
+ void *privateData;
+ void *pri;
+ unsigned long privateValue;
+ struct DListHead list; /* list of controls */
+};
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif
+#endif /* __cplusplus */
+
+#endif
diff --git a/model/audio/core/include/audio_core.h b/model/audio/core/include/audio_core.h
new file mode 100755
index 0000000000000000000000000000000000000000..32a2f860c47c93070e8dc952ddf5c2456deb9650
--- /dev/null
+++ b/model/audio/core/include/audio_core.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 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 AUDIO_CORE_H
+#define AUDIO_CORE_H
+
+#include "audio_host.h"
+#include "audio_control.h"
+#include "audio_codec_if.h"
+#include "audio_platform_if.h"
+#include "audio_dai_if.h"
+#include "audio_accessory_if.h"
+#include "audio_dsp_if.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif
+#endif /* __cplusplus */
+
+#define CHANNEL_MAX_NUM 2
+#define CHANNEL_MIN_NUM 1
+
+#define AUDIO_DAI_LINK_COMPLETE 1
+#define AUDIO_DAI_LINK_UNCOMPLETE 0
+
+#ifdef __LITEOS__
+#define AUDIO_DRIVER_LOG_DEBUG(fmt, arg...) do { \
+ } while (0)
+#else
+#define AUDIO_DRIVER_LOG_DEBUG(fmt, arg...) do { \
+ HDF_LOGD("[%s][line:%d]: " fmt, __func__, __LINE__, ##arg); \
+ } while (0)
+#endif
+
+#define AUDIO_DRIVER_LOG_ERR(fmt, arg...) do { \
+ HDF_LOGE("[%s][line:%d]: " fmt, __func__, __LINE__, ##arg); \
+ } while (0)
+
+#define AUDIO_DRIVER_LOG_INFO(fmt, arg...) do { \
+ HDF_LOGI("[%s][line:%d]: " fmt, __func__, __LINE__, ##arg); \
+ } while (0)
+
+#define AUDIO_DRIVER_LOG_WARNING(fmt, arg...) do { \
+ HDF_LOGW("[%s][line:%d]: " fmt, __func__, __LINE__, ##arg); \
+ } while (0)
+
+enum AudioDeviceType {
+ AUDIO_DAI_DEVICE,
+ AUDIO_DSP_DEVICE,
+ AUDIO_PLATFORM_DEVICE,
+ AUDIO_CODEC_DEVICE,
+ AUDIO_ACCESSORY_DEVICE,
+ AUDIO_DEVICE_BUTT,
+};
+
+enum PlayStatus {
+ STREAM_START = 4,
+ STREAM_STOP,
+};
+
+/* Dai registration interface */
+int32_t AudioSocRegisterDai(struct HdfDeviceObject *device, struct DaiData *data);
+/* Platform registration interface */
+int32_t AudioSocRegisterPlatform(struct HdfDeviceObject *device, struct PlatformData *data);
+/* Codec registration interface */
+int32_t AudioRegisterCodec(struct HdfDeviceObject *device, struct CodecData *codecData, struct DaiData *daiData);
+int32_t AudioBindDaiLink(struct AudioCard *audioCard, const struct AudioConfigData *configData);
+int32_t AudioSocDeviceRegister(struct HdfDeviceObject *device, void *data, enum AudioDeviceType deviceType);
+int32_t AudioSocRegisterDsp(struct HdfDeviceObject *device, struct DaiData *data);
+int32_t AudioRegisterAccessory(struct HdfDeviceObject *device, struct AccessoryData *data, struct DaiData *daiData);
+int32_t AudioUpdateCodecRegBits(struct CodecDevice *codec,
+ const struct AudioMixerControl *mixerControl, uint32_t value);
+int32_t AudioUpdateAccessoryRegBits(struct AccessoryDevice *accessory,
+ const struct AudioMixerControl *mixerControl, uint32_t value);
+int32_t AudioUpdateCodecAiaoRegBits(struct CodecDevice *codec, const struct AudioMixerControl *mixerControl,
+ uint32_t value);
+int32_t AudioUpdateAccessoryAiaoRegBits(struct AccessoryDevice *accessory,
+ const struct AudioMixerControl *mixerControl, uint32_t value);
+struct CodecDevice *AudioKcontrolGetCodec(const struct AudioKcontrol *kcontrol);
+struct AccessoryDevice *AudioKcontrolGetAccessory(const struct AudioKcontrol *kcontrol);
+int32_t AudioAddControls(struct AudioCard *audioCard,
+ const struct AudioKcontrol *controls, int32_t controlMaxNum);
+struct AudioKcontrol *AudioAddControl(const struct AudioCard *audioCard, const struct AudioKcontrol *ctl);
+
+int32_t AudioCodecReadReg(const struct CodecDevice *codec, uint32_t reg, uint32_t *val);
+int32_t AudioCodecWriteReg(const struct CodecDevice *codec, uint32_t reg, uint32_t val);
+int32_t AudioAccessoryReadReg(const struct AccessoryDevice *accessory, uint32_t reg, uint32_t *val);
+int32_t AudioAccessoryWriteReg(const struct AccessoryDevice *accessory, uint32_t reg, uint32_t val);
+int32_t AudioCodecAiaoReadReg(const struct CodecDevice *codec, uint32_t reg, uint32_t *val);
+int32_t AudioCodecAiaoWriteReg(const struct CodecDevice *codec, uint32_t reg, uint32_t val);
+int32_t AudioAccessoryAiaoReadReg(const struct AccessoryDevice *accessory, uint32_t reg, uint32_t *val);
+int32_t AudioAccessoryAiaoWriteReg(const struct AccessoryDevice *accessory, uint32_t reg, uint32_t val);
+
+int32_t AudioInfoCtrlOps(const struct AudioKcontrol *kcontrol, struct AudioCtrlElemInfo *elemInfo);
+int32_t AudioCodecGetCtrlOps(const struct AudioKcontrol *kcontrol, struct AudioCtrlElemValue *elemValue);
+int32_t AudioCodecSetCtrlOps(const struct AudioKcontrol *kcontrol, const struct AudioCtrlElemValue *elemValue);
+int32_t AudioAccessoryGetCtrlOps(const struct AudioKcontrol *kcontrol, struct AudioCtrlElemValue *elemValue);
+int32_t AudioAccessorySetCtrlOps(const struct AudioKcontrol *kcontrol, const struct AudioCtrlElemValue *elemValue);
+int32_t AudioCodecAiaoGetCtrlOps(const struct AudioKcontrol *kcontrol, struct AudioCtrlElemValue *elemValue);
+int32_t AudioCodecAiaoSetCtrlOps(const struct AudioKcontrol *kcontrol, const struct AudioCtrlElemValue *elemValue);
+int32_t AudioAccessoryAiaoGetCtrlOps(const struct AudioKcontrol *kcontrol, struct AudioCtrlElemValue *elemValue);
+int32_t AudioAccessoryAiaoSetCtrlOps(const struct AudioKcontrol *kcontrol, const struct AudioCtrlElemValue *elemValue);
+int32_t AudioRegisterDsp(struct HdfDeviceObject *device, struct DspData *dspData, struct DaiData *DaiData);
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif
+#endif /* __cplusplus */
+
+#endif /* AUDIO_CORE_H */
diff --git a/model/audio/core/include/audio_host.h b/model/audio/core/include/audio_host.h
new file mode 100755
index 0000000000000000000000000000000000000000..e49c6b0e5770285e9085915c69d2280e0131c429
--- /dev/null
+++ b/model/audio/core/include/audio_host.h
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 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 AUDIO_HOST_H
+#define AUDIO_HOST_H
+
+#include "hdf_base.h"
+#include "hdf_dlist.h"
+#include "hdf_device_desc.h"
+#include "hdf_log.h"
+#include "device_resource_if.h"
+#include "osal_mem.h"
+#include "osal_mutex.h"
+#include "securec.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif
+#endif /* __cplusplus */
+
+#ifdef __LITEOS__
+#define ADM_LOG_DEBUG(fmt, arg...) do { \
+ } while (0)
+#else
+#define ADM_LOG_DEBUG(fmt, arg...) do { \
+ HDF_LOGD("[%s][line:%d]: " fmt, __func__, __LINE__, ##arg); \
+ } while (0)
+#endif
+
+#define ADM_LOG_ERR(fmt, arg...) do { \
+ HDF_LOGE("[%s][line:%d]: " fmt, __func__, __LINE__, ##arg); \
+ } while (0)
+
+#define ADM_LOG_INFO(fmt, arg...) do { \
+ HDF_LOGI("[%s][line:%d]: " fmt, __func__, __LINE__, ##arg); \
+ } while (0)
+
+#define ADM_LOG_WARNING(fmt, arg...) do { \
+ HDF_LOGW("[%s][line:%d]: " fmt, __func__, __LINE__, ##arg); \
+ } while (0)
+
+#define BUFF_SIZE_MAX 64
+
+#define AUDIO_LIST_HEAD_INIT(name) { &(name), &(name) }
+
+#define AUDIO_LIST_HEAD(name) \
+ struct DListHead name = AUDIO_LIST_HEAD_INIT(name)
+
+enum AudioFormat {
+ AUDIO_FORMAT_PCM_8_BIT = 0x1u, /**< audio 8-bit PCM */
+ AUDIO_FORMAT_PCM_16_BIT = 0x2u, /**< audio16-bit PCM */
+ AUDIO_FORMAT_PCM_24_BIT = 0x3u, /**< audio 24-bit PCM */
+ AUDIO_FORMAT_PCM_32_BIT = 0x4u, /**< audio 32-bit PCM */
+ AUDIO_FORMAT_AAC_MAIN = 0x1000001u, /**< audio AAC main */
+ AUDIO_FORMAT_AAC_LC = 0x1000002u, /**< audio AAC LC */
+ AUDIO_FORMAT_AAC_LD = 0x1000003u, /**< audio AAC LD */
+ AUDIO_FORMAT_AAC_ELD = 0x1000004u, /**< audio AAC ELD */
+ AUDIO_FORMAT_AAC_HE_V1 = 0x1000005u, /**< audio AAC HE_V1 */
+ AUDIO_FORMAT_AAC_HE_V2 = 0x1000006u, /**< audio AAC HE_V2 */
+ AUDIO_FORMAT_G711A = 0x2000001u, /**< audio G711A */
+ AUDIO_FORMAT_G711U = 0x2000002u, /**< audio G711u */
+ AUDIO_FORMAT_G726 = 0x2000003u, /**< audio G726 */
+};
+
+struct AudioConfigData {
+ const char *cardServiceName;
+ const char *codecName;
+ const char *platformName;
+ const char *cpuDaiName;
+ const char *codecDaiName;
+ const char *accessoryName;
+ const char *accessoryDaiName;
+ const char *dspName;
+ const char *dspDaiName;
+};
+
+struct AudioCard {
+ struct AudioRuntimeDeivces *rtd;
+ struct AudioConfigData configData;
+
+ /* Card-specific routes and components. */
+ const struct AudioSapmComponent *sapmComponents;
+ int32_t sapmComponentsNum;
+ const struct AudioSapmRoute *sapmRoutes;
+ int32_t sapmRoutesNum;
+
+ struct DListHead list;
+ struct DListHead controls; /* all controls for this card */
+ struct DListHead components; /* all components for this card */
+ struct DListHead paths; /* all paths for this card */
+ struct DListHead sapmDirty; /* all dirty for this card */
+ bool sapmSleepState;
+ bool sapmStandbyState;
+ bool sapmMonitorState;
+};
+
+enum CriBuffStatus {
+ ENUM_CIR_BUFF_NORMAL = 1,
+ ENUM_CIR_BUFF_FULL,
+ ENUM_CIR_BUFF_EMPTY,
+};
+
+enum AudioStreamType {
+ AUDIO_CAPTURE_STREAM = 0,
+ AUDIO_RENDER_STREAM,
+};
+
+struct AudioPcmHwParams {
+ /* The stream type in a frame */
+ enum AudioStreamType streamType;
+ /* The number of channels in a frame */
+ uint32_t channels;
+ /* The number of frames per second */
+ uint32_t rate;
+ /* The number of frames in a period */
+ uint32_t periodSize;
+ /* The number of periods in a PCM */
+ uint32_t periodCount;
+ /* The sample format of a PCM */
+ enum AudioFormat format; /* < Audio data format. For details, see {@link AudioFormat}. */
+ const char *cardServiceName;
+ uint32_t period;
+ uint32_t frameSize;
+ bool isBigEndian;
+ bool isSignedData;
+ uint32_t startThreshold;
+ uint32_t stopThreshold;
+ uint32_t silenceThreshold;
+};
+
+struct AudioHost {
+ struct IDeviceIoService service;
+ struct HdfDeviceObject *device;
+ void *priv;
+};
+
+struct AudioTxData {
+ enum CriBuffStatus status;
+ char *buf; /* buf address */
+ unsigned long frames; /* frames number */
+};
+
+struct AudioRxData {
+ enum CriBuffStatus status;
+ char *buf;
+ unsigned long bufSize;
+ unsigned long frames; /* frames number */
+};
+
+struct AudioTxMmapData {
+ void *memoryAddress; /**< Pointer to the mmap buffer */
+ int32_t memoryFd; /**< File descriptor of the mmap buffer */
+ int32_t totalBufferFrames; /**< Total size of the mmap buffer (unit: frame )*/
+ int32_t transferFrameSize; /**< Transfer size (unit: frame) */
+ int32_t isShareable; /**< Whether the mmap buffer can be shared among processes */
+ uint32_t offset;
+};
+
+struct AudioRxMmapData {
+ void *memoryAddress; /**< Pointer to the mmap buffer */
+ int32_t memoryFd; /**< File descriptor of the mmap buffer */
+ int32_t totalBufferFrames; /**< Total size of the mmap buffer (unit: frame )*/
+ int32_t transferFrameSize; /**< Transfer size (unit: frame) */
+ int32_t isShareable; /**< Whether the mmap buffer can be shared among processes */
+ uint32_t offset;
+};
+
+struct AudioRuntimeDeivces {
+ /* runtime devices */
+ struct CodecDevice *codec;
+ struct PlatformDevice *platform;
+ struct DaiDevice *codecDai;
+ struct DaiDevice *cpuDai;
+ struct DaiDevice *accessoryDai;
+ struct AccessoryDevice *accessory;
+ struct DspDevice *dsp;
+ struct DaiDevice *dspDai;
+ uint8_t complete;
+ uint32_t frameBits;
+ uint8_t *dmaArea;
+ unsigned long bufferSize;
+};
+
+struct AudioHost *AudioHostCreateAndBind(struct HdfDeviceObject *device);
+
+static inline struct HdfDeviceObject *AudioHostToDevice(struct AudioHost *host)
+{
+ return (host == NULL) ? NULL : host->device;
+}
+
+static inline struct AudioHost *AudioHostFromDevice(struct HdfDeviceObject *device)
+{
+ return (device == NULL) ? NULL : (struct AudioHost *)device->service;
+}
+
+/* Get a sound card instance */
+struct AudioCard *GetCardInstance(const char *serviceName);
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif
+#endif /* __cplusplus */
+
+#endif /* AUDIO_HOST_H */
diff --git a/support/platform/include/common/platform.h b/model/audio/core/include/audio_parse.h
old mode 100644
new mode 100755
similarity index 59%
rename from support/platform/include/common/platform.h
rename to model/audio/core/include/audio_parse.h
index dd3a5563798380d6adb7f296e3f37839ea246ed5..9ded34ee9e85c0ed6ebd22d760a2f9c27a9e6a9a
--- a/support/platform/include/common/platform.h
+++ b/model/audio/core/include/audio_parse.h
@@ -1,17 +1,15 @@
/*
- * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
+ * Copyright (c) 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"
+#ifndef AUDIO_PARSE_H
+#define AUDIO_PARSE_H
+
+#include "audio_host.h"
#ifdef __cplusplus
#if __cplusplus
@@ -19,10 +17,12 @@ extern "C" {
#endif
#endif /* __cplusplus */
+int32_t AudioFillConfigData(const struct HdfDeviceObject *device, struct AudioConfigData *configData);
+
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */
-#endif /* PLATFORM_H */
+#endif /* AUDIO_PARSE_H */
diff --git a/model/audio/core/src/audio_core.c b/model/audio/core/src/audio_core.c
new file mode 100755
index 0000000000000000000000000000000000000000..f61a7341588dcbd4639bd5ea6a54dcd431e7201e
--- /dev/null
+++ b/model/audio/core/src/audio_core.c
@@ -0,0 +1,1132 @@
+/*
+ * Copyright (c) 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 "audio_core.h"
+
+#define HDF_LOG_TAG audio_core
+
+AUDIO_LIST_HEAD(daiController);
+AUDIO_LIST_HEAD(platformController);
+AUDIO_LIST_HEAD(codecController);
+AUDIO_LIST_HEAD(dspController);
+AUDIO_LIST_HEAD(accessoryController);
+
+int32_t AudioSocRegisterPlatform(struct HdfDeviceObject *device, struct PlatformData *data)
+{
+ struct PlatformDevice *platform = NULL;
+
+ if ((device == NULL) || (data == NULL)) {
+ ADM_LOG_ERR("Input params check error: device=%p, data=%p.", device, data);
+ return HDF_ERR_INVALID_OBJECT;
+ }
+
+ platform = (struct PlatformDevice *)OsalMemCalloc(sizeof(*platform));
+ if (platform == NULL) {
+ ADM_LOG_ERR("Malloc platform device fail!");
+ return HDF_ERR_MALLOC_FAIL;
+ }
+
+ platform->devPlatformName = data->drvPlatformName;
+ platform->devData = data;
+ platform->device = device;
+ DListInsertHead(&platform->list, &platformController);
+ ADM_LOG_INFO("Register [%s] success.", platform->devPlatformName);
+
+ return HDF_SUCCESS;
+}
+
+int32_t AudioSocRegisterDai(struct HdfDeviceObject *device, struct DaiData *data)
+{
+ struct DaiDevice *dai = NULL;
+
+ if ((device == NULL) || (data == NULL)) {
+ ADM_LOG_ERR("Input params check error: device=%p, data=%p.", device, data);
+ return HDF_ERR_INVALID_OBJECT;
+ }
+
+ dai = (struct DaiDevice *)OsalMemCalloc(sizeof(*dai));
+ if (dai == NULL) {
+ ADM_LOG_ERR("Malloc dai device fail!");
+ return HDF_ERR_MALLOC_FAIL;
+ }
+
+ dai->devDaiName = data->drvDaiName;
+ dai->devData = data;
+ dai->device = device;
+ DListInsertHead(&dai->list, &daiController);
+ ADM_LOG_INFO("Register [%s] success.", dai->devDaiName);
+
+ return HDF_SUCCESS;
+}
+
+int32_t AudioRegisterAccessory(struct HdfDeviceObject *device, struct AccessoryData *data, struct DaiData *daiData)
+{
+ struct AccessoryDevice *accessory = NULL;
+ int32_t ret;
+
+ if (device == NULL || data == NULL || daiData == NULL) {
+ ADM_LOG_ERR("Input params check error: device=%p, data=%p, daiData=%p.", device, data, daiData);
+ return HDF_ERR_INVALID_OBJECT;
+ }
+
+ accessory = (struct AccessoryDevice *)OsalMemCalloc(sizeof(*accessory));
+ if (accessory == NULL) {
+ ADM_LOG_ERR("Malloc accessory device fail!");
+ return HDF_ERR_MALLOC_FAIL;
+ }
+
+ OsalMutexInit(&accessory->mutex);
+ accessory->devAccessoryName = data->drvAccessoryName;
+ accessory->devData = data;
+ accessory->device = device;
+
+ ret = AudioSocDeviceRegister(device, (void *)daiData, AUDIO_DAI_DEVICE);
+ if (ret != HDF_SUCCESS) {
+ OsalMemFree(accessory);
+ ADM_LOG_ERR("Register accessory device fail ret=%d", ret);
+ return HDF_ERR_IO;
+ }
+ DListInsertHead(&accessory->list, &accessoryController);
+ ADM_LOG_INFO("Register [%s] success.", accessory->devAccessoryName);
+
+ return HDF_SUCCESS;
+}
+
+int32_t AudioRegisterCodec(struct HdfDeviceObject *device, struct CodecData *codecData, struct DaiData *daiData)
+{
+ struct CodecDevice *codec = NULL;
+ int32_t ret;
+
+ if ((device == NULL) || (codecData == NULL) || (daiData == NULL)) {
+ ADM_LOG_ERR("Input params check error: device=%p, codecData=%p, daiData=%p.",
+ device, codecData, daiData);
+ return HDF_ERR_INVALID_OBJECT;
+ }
+
+ codec = (struct CodecDevice *)OsalMemCalloc(sizeof(*codec));
+ if (codec == NULL) {
+ ADM_LOG_ERR("Malloc codec device fail!");
+ return HDF_ERR_MALLOC_FAIL;
+ }
+
+ OsalMutexInit(&codec->mutex);
+ codec->devCodecName = codecData->drvCodecName;
+ codec->devData = codecData;
+ codec->device = device;
+
+ ret = AudioSocDeviceRegister(device, (void *)daiData, AUDIO_DAI_DEVICE);
+ if (ret != HDF_SUCCESS) {
+ OsalMemFree(codec);
+ ADM_LOG_ERR("Register dai device fail ret=%d", ret);
+ return HDF_ERR_IO;
+ }
+ DListInsertHead(&codec->list, &codecController);
+ ADM_LOG_INFO("Register [%s] success.", codec->devCodecName);
+
+ return HDF_SUCCESS;
+}
+
+int32_t AudioRegisterDsp(struct HdfDeviceObject *device, struct DspData *dspData, struct DaiData *DaiData)
+{
+ struct DspDevice *dspDev = NULL;
+ int32_t ret;
+
+ if ((device == NULL) || (dspData == NULL) || (DaiData == NULL)) {
+ ADM_LOG_ERR("Input params check error: device=%p, dspData=%p, daiData=%p.",
+ device, dspData, DaiData);
+ return HDF_ERR_INVALID_OBJECT;
+ }
+
+ dspDev = (struct DspDevice *)OsalMemCalloc(sizeof(*dspDev));
+ if (dspDev == NULL) {
+ ADM_LOG_ERR("Malloc codec device fail!");
+ return HDF_ERR_MALLOC_FAIL;
+ }
+
+ dspDev->devDspName = dspData->drvDspName;
+ dspDev->devData = dspData;
+ dspDev->device = device;
+
+ ret = AudioSocDeviceRegister(device, (void *)DaiData, AUDIO_DAI_DEVICE);
+ if (ret != HDF_SUCCESS) {
+ OsalMemFree(dspDev);
+ ADM_LOG_ERR("Register dai device fail ret=%d", ret);
+ return HDF_ERR_IO;
+ }
+ DListInsertHead(&dspDev->list, &dspController);
+ ADM_LOG_INFO("Register [%s] success.", dspDev->devDspName);
+
+ return HDF_SUCCESS;
+}
+
+int32_t AudioSocDeviceRegister(struct HdfDeviceObject *device, void *data, enum AudioDeviceType deviceType)
+{
+ struct PlatformData *platformData = NULL;
+ struct DaiData *daiData = NULL;
+ int32_t ret;
+
+ if ((device == NULL) || (data == NULL) || (deviceType >= AUDIO_DEVICE_BUTT) || (deviceType < 0)) {
+ ADM_LOG_ERR("Input params check error: device=%p, data=%p, deviceType=%d.",
+ device, data, deviceType);
+ return HDF_ERR_INVALID_OBJECT;
+ }
+
+ switch (deviceType) {
+ case AUDIO_DAI_DEVICE: {
+ daiData = (struct DaiData *)data;
+ ret = AudioSocRegisterDai(device, daiData);
+ if (ret != HDF_SUCCESS) {
+ ADM_LOG_ERR("Register dai device fail ret=%d", ret);
+ return HDF_FAILURE;
+ }
+ break;
+ }
+ case AUDIO_PLATFORM_DEVICE: {
+ platformData = (struct PlatformData *)data;
+ ret = AudioSocRegisterPlatform(device, platformData);
+ if (ret != HDF_SUCCESS) {
+ ADM_LOG_ERR("Register dma device fail ret=%d", ret);
+ return HDF_FAILURE;
+ }
+ break;
+ }
+ default: {
+ ADM_LOG_ERR("Invalid device type.");
+ return HDF_FAILURE;
+ }
+ }
+
+ return HDF_SUCCESS;
+}
+
+int32_t AudioSeekPlatformDevice(struct AudioRuntimeDeivces *rtd, const struct AudioConfigData *configData)
+{
+ struct PlatformDevice *platform = NULL;
+ if (rtd == NULL || configData == NULL) {
+ ADM_LOG_ERR("Input params check error: rtd=%p, configData=%p.", rtd, configData);
+ return HDF_ERR_INVALID_OBJECT;
+ }
+ if (configData->platformName == NULL) {
+ ADM_LOG_ERR("Input devicesName check error: configData->platformName is NULL.");
+ return HDF_ERR_INVALID_OBJECT;
+ }
+
+ DLIST_FOR_EACH_ENTRY(platform, &platformController, struct PlatformDevice, list) {
+ if (platform->devPlatformName != NULL &&
+ strcmp(platform->devPlatformName, configData->platformName) == 0) {
+ rtd->platform = platform;
+ break;
+ }
+ }
+
+ return HDF_SUCCESS;
+}
+
+int32_t AudioSeekCpuDaiDevice(struct AudioRuntimeDeivces *rtd, const struct AudioConfigData *configData)
+{
+ struct DaiDevice *cpuDai = NULL;
+ if (rtd == NULL || configData == NULL) {
+ ADM_LOG_ERR("Input params check error: rtd=%p, configData=%p.", rtd, configData);
+ return HDF_ERR_INVALID_OBJECT;
+ }
+ if (configData->cpuDaiName == NULL) {
+ ADM_LOG_ERR("Input cpuDaiName check error: configData->cpuDaiName is NULL.");
+ return HDF_ERR_INVALID_OBJECT;
+ }
+
+ if (DListIsEmpty(&daiController)) {
+ ADM_LOG_ERR("daiController is empty.");
+ return HDF_FAILURE;
+ }
+ DLIST_FOR_EACH_ENTRY(cpuDai, &daiController, struct DaiDevice, list) {
+ if (cpuDai != NULL && cpuDai->devDaiName != NULL &&
+ strcmp(cpuDai->devDaiName, configData->cpuDaiName) == 0) {
+ rtd->cpuDai = cpuDai;
+ break;
+ }
+ }
+
+ return HDF_SUCCESS;
+}
+
+int32_t AudioSeekCodecDevice(struct AudioRuntimeDeivces *rtd, const struct AudioConfigData *configData)
+{
+ struct CodecDevice *codec = NULL;
+ struct DaiDevice *codecDai = NULL;
+ if ((rtd == NULL) || (configData == NULL)) {
+ ADM_LOG_ERR("Input params check error: rtd=%p, configData=%p.", rtd, configData);
+ return HDF_ERR_INVALID_OBJECT;
+ }
+ if (configData->codecName == NULL || configData->codecDaiName == NULL) {
+ ADM_LOG_ERR("Input devicesName check error: configData->codecName=%p, configData->codecDaiName=%p.",
+ configData->codecName, configData->codecDaiName);
+ return HDF_ERR_INVALID_OBJECT;
+ }
+
+ DLIST_FOR_EACH_ENTRY(codec, &codecController, struct CodecDevice, list) {
+ if (codec->devCodecName != NULL && strcmp(codec->devCodecName, configData->codecName) == 0) {
+ rtd->codec = codec;
+ DLIST_FOR_EACH_ENTRY(codecDai, &daiController, struct DaiDevice, list) {
+ if (codecDai != NULL && codecDai->device != NULL && codec->device == codecDai->device &&
+ codecDai->devDaiName != NULL && strcmp(codecDai->devDaiName, configData->codecDaiName) == 0) {
+ rtd->codecDai = codecDai;
+ break;
+ }
+ }
+ break;
+ }
+ }
+
+ return HDF_SUCCESS;
+}
+
+int32_t AudioSeekAccessoryDevice(struct AudioRuntimeDeivces *rtd, const struct AudioConfigData *configData)
+{
+ struct AccessoryDevice *accessory = NULL;
+ struct DaiDevice *accessoryDai = NULL;
+ if (rtd == NULL || configData == NULL) {
+ ADM_LOG_ERR("Input params check error: rtd=%p, configData=%p.", rtd, configData);
+ return HDF_ERR_INVALID_OBJECT;
+ }
+ if (configData->accessoryName == NULL || configData->accessoryDaiName == NULL) {
+ ADM_LOG_ERR("Input devicesName check error: configData->accessoryName or"
+ "configData->accessoryDaiName is NULL.");
+ return HDF_ERR_INVALID_OBJECT;
+ }
+
+ DLIST_FOR_EACH_ENTRY(accessory, &accessoryController, struct AccessoryDevice, list) {
+ if (accessory != NULL && accessory->devAccessoryName != NULL &&
+ strcmp(accessory->devAccessoryName, configData->accessoryName) == 0) {
+ rtd->accessory = accessory;
+ DLIST_FOR_EACH_ENTRY(accessoryDai, &daiController, struct DaiDevice, list) {
+ if (accessoryDai != NULL && accessoryDai->device != NULL &&
+ accessory->device == accessoryDai->device && accessoryDai->devDaiName != NULL &&
+ strcmp(accessoryDai->devDaiName, configData->accessoryDaiName) == 0) {
+ rtd->accessoryDai = accessoryDai;
+ break;
+ }
+ }
+ break;
+ }
+ }
+
+ return HDF_SUCCESS;
+}
+
+int32_t AudioSeekDspDevice(struct AudioRuntimeDeivces *rtd, const struct AudioConfigData *configData)
+{
+ struct DspDevice *dsp = NULL;
+ struct DaiDevice *dspDai = NULL;
+ if ((rtd == NULL) || (configData == NULL)) {
+ ADM_LOG_ERR("Input params check error: rtd=%p, configData=%p.", rtd, configData);
+ return HDF_ERR_INVALID_OBJECT;
+ }
+ if (configData->dspName == NULL || configData->dspDaiName == NULL) {
+ ADM_LOG_ERR("Input devicesName check error: configData->dspName=%p, configData->dspDaiName=%p.",
+ configData->dspName, configData->dspDaiName);
+ return HDF_ERR_INVALID_OBJECT;
+ }
+
+ DLIST_FOR_EACH_ENTRY(dsp, &dspController, struct DspDevice, list) {
+ if (dsp != NULL && dsp->devDspName != NULL && strcmp(dsp->devDspName, configData->dspName) == 0) {
+ rtd->dsp = dsp;
+ DLIST_FOR_EACH_ENTRY(dspDai, &daiController, struct DaiDevice, list) {
+ if (dspDai != NULL && dspDai->device != NULL && dsp->device == dspDai->device &&
+ dspDai->devDaiName != NULL && strcmp(dspDai->devDaiName, configData->dspDaiName) == 0) {
+ rtd->dspDai = dspDai;
+ break;
+ }
+ }
+ break;
+ }
+ }
+
+ return HDF_SUCCESS;
+}
+
+int32_t AudioBindDaiLink(struct AudioCard *audioCard, const struct AudioConfigData *configData)
+{
+ if ((audioCard == NULL) || (configData == NULL)) {
+ ADM_LOG_ERR("Input params check error: audioCard=%p, configData=%p.", audioCard, configData);
+ return HDF_ERR_INVALID_OBJECT;
+ }
+
+ audioCard->rtd = (struct AudioRuntimeDeivces *)OsalMemCalloc(sizeof(struct AudioRuntimeDeivces));
+ if (audioCard->rtd == NULL) {
+ ADM_LOG_ERR("Malloc audioCard->rtd fail!");
+ return HDF_ERR_MALLOC_FAIL;
+ }
+
+ audioCard->rtd->complete = AUDIO_DAI_LINK_UNCOMPLETE;
+ if (AudioSeekPlatformDevice(audioCard->rtd, configData) == HDF_SUCCESS) {
+ ADM_LOG_DEBUG("PLATFORM [%s] is registered!", configData->platformName);
+ }
+ if (AudioSeekCpuDaiDevice(audioCard->rtd, configData) == HDF_SUCCESS) {
+ ADM_LOG_DEBUG("CPU DAI [%s] is registered!", configData->cpuDaiName);
+ }
+ if (AudioSeekCodecDevice(audioCard->rtd, configData) == HDF_SUCCESS) {
+ ADM_LOG_DEBUG("CODEC [%s] is registered!", configData->codecName);
+ }
+ if (AudioSeekAccessoryDevice(audioCard->rtd, configData) == HDF_SUCCESS) {
+ ADM_LOG_DEBUG("CODEC [%s] is registered!", configData->accessoryName);
+ }
+ if (AudioSeekDspDevice(audioCard->rtd, configData) == HDF_SUCCESS) {
+ ADM_LOG_DEBUG("CODEC [%s] is registered!", configData->dspName);
+ }
+ audioCard->rtd->complete = AUDIO_DAI_LINK_COMPLETE;
+ ADM_LOG_DEBUG("All devices register complete!");
+
+ return HDF_SUCCESS;
+}
+
+int32_t AudioUpdateCodecRegBits(struct CodecDevice *codec,
+ const struct AudioMixerControl *mixerControl, uint32_t value)
+{
+ int32_t ret;
+ uint32_t curValue = 0;
+ uint32_t mixerControlMask;
+ if (codec == NULL || mixerControl == NULL) {
+ ADM_LOG_ERR("Invalid accessory param.");
+ return HDF_ERR_INVALID_OBJECT;
+ }
+
+ value = value << mixerControl->shift;
+ mixerControlMask = mixerControl->mask << mixerControl->shift;
+
+ OsalMutexLock(&codec->mutex);
+ ret = AudioCodecReadReg(codec, mixerControl->reg, &curValue);
+ if (ret != HDF_SUCCESS) {
+ OsalMutexUnlock(&codec->mutex);
+ ADM_LOG_ERR("Read reg fail ret=%d.", ret);
+ return HDF_FAILURE;
+ }
+
+ curValue = (curValue & ~mixerControlMask) | (value & mixerControlMask);
+ ret = AudioCodecWriteReg(codec, mixerControl->reg, curValue);
+ if (ret != HDF_SUCCESS) {
+ OsalMutexUnlock(&codec->mutex);
+ ADM_LOG_ERR("Write reg fail ret=%d", ret);
+ return HDF_FAILURE;
+ }
+ OsalMutexUnlock(&codec->mutex);
+
+ ADM_LOG_DEBUG("Success.");
+ return HDF_SUCCESS;
+}
+
+int32_t AudioUpdateAccessoryRegBits(struct AccessoryDevice *accessory,
+ const struct AudioMixerControl *mixerControl, uint32_t value)
+{
+ int32_t ret;
+ uint32_t curValue = 0;
+ uint32_t mixerControlMask;
+ if (accessory == NULL || mixerControl == NULL) {
+ ADM_LOG_ERR("Invalid accessory param.");
+ return HDF_ERR_INVALID_OBJECT;
+ }
+
+ value = value << mixerControl->shift;
+ mixerControlMask = mixerControl->mask << mixerControl->shift;
+
+ OsalMutexLock(&accessory->mutex);
+ ret = AudioAccessoryReadReg(accessory, mixerControl->reg, &curValue);
+ if (ret != HDF_SUCCESS) {
+ OsalMutexUnlock(&accessory->mutex);
+ ADM_LOG_ERR("Read reg fail ret=%d", ret);
+ return HDF_FAILURE;
+ }
+ curValue = (curValue & ~mixerControlMask) | (value & mixerControlMask);
+ ret = AudioAccessoryWriteReg(accessory, mixerControl->reg, curValue);
+ if (ret != HDF_SUCCESS) {
+ OsalMutexUnlock(&accessory->mutex);
+ ADM_LOG_ERR("Write reg fail ret=%d", ret);
+ return HDF_FAILURE;
+ }
+ OsalMutexUnlock(&accessory->mutex);
+
+ ADM_LOG_DEBUG("Success.");
+ return HDF_SUCCESS;
+}
+
+int32_t AudioUpdateCodecAiaoRegBits(struct CodecDevice *codec,
+ const struct AudioMixerControl *mixerControl, uint32_t value)
+{
+ int32_t ret;
+ uint32_t curValue = 0;
+ uint32_t mixerControlMask;
+ ADM_LOG_DEBUG("Entry to update AIAO codec reg bits.");
+
+ if (codec == NULL || mixerControl == NULL) {
+ ADM_LOG_ERR("Invalid AIAO codec param.");
+ return HDF_ERR_INVALID_OBJECT;
+ }
+
+ value = value << mixerControl->shift;
+ mixerControlMask = mixerControl->mask << mixerControl->shift;
+
+ OsalMutexLock(&codec->mutex);
+ ret = AudioCodecAiaoReadReg(codec, mixerControl->reg, &curValue);
+ if (ret != HDF_SUCCESS) {
+ OsalMutexUnlock(&codec->mutex);
+ ADM_LOG_ERR("Read AIAO codec reg fail ret=%d.", ret);
+ return HDF_FAILURE;
+ }
+ curValue = (curValue & ~mixerControlMask) | (value & mixerControlMask);
+ ret = AudioCodecAiaoWriteReg(codec, mixerControl->reg, curValue);
+ if (ret != HDF_SUCCESS) {
+ OsalMutexUnlock(&codec->mutex);
+ ADM_LOG_ERR("Write AIAO codec reg fail ret=%d", ret);
+ return HDF_FAILURE;
+ }
+ OsalMutexUnlock(&codec->mutex);
+
+ ADM_LOG_DEBUG("Update AIAO codec reg bits successful.");
+ return HDF_SUCCESS;
+}
+
+int32_t AudioUpdateAccessoryAiaoRegBits(struct AccessoryDevice *accessory,
+ const struct AudioMixerControl *mixerControl, uint32_t value)
+{
+ int32_t ret;
+ uint32_t curValue = 0;
+ uint32_t mixerControlMask;
+ ADM_LOG_DEBUG("Entry to update AIAO accessory reg bits.");
+
+ if (accessory == NULL || mixerControl == NULL) {
+ ADM_LOG_ERR("Invalid AIAO accessory param.");
+ return HDF_ERR_INVALID_OBJECT;
+ }
+
+ value = value << mixerControl->shift;
+ mixerControlMask = mixerControl->mask << mixerControl->shift;
+
+ OsalMutexLock(&accessory->mutex);
+ ret = AudioAccessoryAiaoReadReg(accessory, mixerControl->reg, &curValue);
+ if (ret != HDF_SUCCESS) {
+ OsalMutexUnlock(&accessory->mutex);
+ ADM_LOG_ERR("Read AIAO accessory reg fail ret=%d.", ret);
+ return HDF_FAILURE;
+ }
+ curValue = (curValue & ~mixerControlMask) | (value & mixerControlMask);
+ ret = AudioAccessoryAiaoWriteReg(accessory, mixerControl->reg, curValue);
+ if (ret != HDF_SUCCESS) {
+ OsalMutexUnlock(&accessory->mutex);
+ ADM_LOG_ERR("Write AIAO accessory reg fail ret=%d", ret);
+ return HDF_FAILURE;
+ }
+ OsalMutexUnlock(&accessory->mutex);
+
+ ADM_LOG_DEBUG("Update AIAO accessory reg bits successful.");
+ return HDF_SUCCESS;
+}
+
+struct CodecDevice *AudioKcontrolGetCodec(const struct AudioKcontrol *kcontrol)
+{
+ struct AudioCard *audioCard = NULL;
+ if (kcontrol == NULL || kcontrol->pri == NULL) {
+ ADM_LOG_ERR("Input param kcontrol is NULL.");
+ return NULL;
+ }
+
+ audioCard = (struct AudioCard *)((volatile uintptr_t)(kcontrol->pri));
+ if (audioCard == NULL || audioCard->rtd == NULL) {
+ ADM_LOG_ERR("Get codec or rtd fail.");
+ return NULL;
+ }
+
+ return audioCard->rtd->codec;
+}
+
+struct AccessoryDevice *AudioKcontrolGetAccessory(const struct AudioKcontrol *kcontrol)
+{
+ struct AudioCard *audioCard = NULL;
+ if (kcontrol == NULL || kcontrol->pri == NULL) {
+ ADM_LOG_ERR("Input param kcontrol is NULL.");
+ return NULL;
+ }
+
+ audioCard = (struct AudioCard *)((volatile uintptr_t)(kcontrol->pri));
+ if (audioCard == NULL || audioCard->rtd == NULL) {
+ ADM_LOG_ERR("Get accessory or rtd fail.");
+ return NULL;
+ }
+
+ return audioCard->rtd->accessory;
+}
+
+struct AudioKcontrol *AudioAddControl(const struct AudioCard *audioCard, const struct AudioKcontrol *ctrl)
+{
+ struct AudioKcontrol *control = NULL;
+
+ if ((audioCard == NULL) || (ctrl == NULL)) {
+ ADM_LOG_ERR("Input params check error: audioCard=%p, ctrl=%p.", audioCard, ctrl);
+ return NULL;
+ }
+
+ control = (struct AudioKcontrol *)OsalMemCalloc(sizeof(*control));
+ if (control == NULL) {
+ ADM_LOG_ERR("Malloc control fail!");
+ return NULL;
+ }
+ control->name = ctrl->name;
+ control->iface = ctrl->iface;
+ control->Info = ctrl->Info;
+ control->Get = ctrl->Get;
+ control->Set = ctrl->Set;
+ control->pri = (void *)audioCard;
+ control->privateValue = ctrl->privateValue;
+
+ return control;
+}
+
+int32_t AudioAddControls(struct AudioCard *audioCard, const struct AudioKcontrol *controls, int32_t controlMaxNum)
+{
+ struct AudioKcontrol *control = NULL;
+ int32_t i;
+ ADM_LOG_DEBUG("Entry.");
+
+ if ((audioCard == NULL) || (controls == NULL) || (controlMaxNum <= 0)) {
+ ADM_LOG_ERR("Input params check error: audioCard=%p, controls=%p, controlMaxNum=%d.",
+ audioCard, controls, controlMaxNum);
+ return HDF_FAILURE;
+ }
+
+ for (i = 0; i < controlMaxNum; i++) {
+ control = AudioAddControl(audioCard, &controls[i]);
+ if (control == NULL) {
+ ADM_LOG_ERR("Add control fail!");
+ return HDF_FAILURE;
+ }
+ DListInsertHead(&control->list, &audioCard->controls);
+ }
+ ADM_LOG_DEBUG("Success.");
+ return HDF_SUCCESS;
+}
+
+int32_t AudioCodecReadReg(const struct CodecDevice *codec, uint32_t reg, uint32_t *val)
+{
+ int32_t ret;
+ if (codec == NULL || codec->devData == NULL || codec->devData->Read == NULL || val == NULL) {
+ ADM_LOG_ERR("Input param codec is NULL.");
+ return HDF_FAILURE;
+ }
+ ret = codec->devData->Read(codec, reg, val);
+ if (ret != HDF_SUCCESS) {
+ ADM_LOG_ERR("Codec device read fail.");
+ return HDF_FAILURE;
+ }
+ return HDF_SUCCESS;
+}
+
+int32_t AudioAccessoryReadReg(const struct AccessoryDevice *accessory, uint32_t reg, uint32_t *val)
+{
+ int32_t ret;
+ if (accessory == NULL || accessory->devData == NULL || accessory->devData->Read == NULL || val == NULL) {
+ ADM_LOG_ERR("Input param accessory is NULL.");
+ return HDF_FAILURE;
+ }
+ ret = accessory->devData->Read(accessory, reg, val);
+ if (ret != HDF_SUCCESS) {
+ ADM_LOG_ERR("Accessory device read fail.");
+ return HDF_FAILURE;
+ }
+ return HDF_SUCCESS;
+}
+
+int32_t AudioCodecAiaoReadReg(const struct CodecDevice *codec, uint32_t reg, uint32_t *val)
+{
+ int32_t ret;
+ if (codec == NULL || codec->devData == NULL || codec->devData->AiaoRead == NULL || val == NULL) {
+ ADM_LOG_ERR("Input param codec is NULL.");
+ return HDF_FAILURE;
+ }
+ ret = codec->devData->AiaoRead(codec, reg, val);
+ if (ret != HDF_SUCCESS) {
+ ADM_LOG_ERR("Device read fail.");
+ return HDF_FAILURE;
+ }
+ return HDF_SUCCESS;
+}
+
+int32_t AudioAccessoryAiaoReadReg(const struct AccessoryDevice *accessory, uint32_t reg, uint32_t *val)
+{
+ int32_t ret;
+ if (accessory == NULL || accessory->devData == NULL || accessory->devData->AiaoRead == NULL || val == NULL) {
+ ADM_LOG_ERR("Input param accessory is NULL.");
+ return HDF_FAILURE;
+ }
+ ret = accessory->devData->AiaoRead(accessory, reg, val);
+ if (ret != HDF_SUCCESS) {
+ ADM_LOG_ERR("Device read fail.");
+ return HDF_FAILURE;
+ }
+ return HDF_SUCCESS;
+}
+
+int32_t AudioCodecWriteReg(const struct CodecDevice *codec, uint32_t reg, uint32_t val)
+{
+ int32_t ret;
+ if (codec == NULL || codec->devData == NULL || codec->devData->Write == NULL) {
+ ADM_LOG_ERR("Input param codec is NULL.");
+ return HDF_FAILURE;
+ }
+ ret = codec->devData->Write(codec, reg, val);
+ if (ret != HDF_SUCCESS) {
+ ADM_LOG_ERR("Codec device write fail.");
+ return HDF_FAILURE;
+ }
+ return HDF_SUCCESS;
+}
+
+int32_t AudioAccessoryWriteReg(const struct AccessoryDevice *accessory, uint32_t reg, uint32_t val)
+{
+ int32_t ret;
+ if (accessory == NULL || accessory->devData == NULL || accessory->devData->Write == NULL) {
+ ADM_LOG_ERR("Input param accessory is NULL.");
+ return HDF_FAILURE;
+ }
+ ret = accessory->devData->Write(accessory, reg, val);
+ if (ret != HDF_SUCCESS) {
+ ADM_LOG_ERR("Accessory device write fail.");
+ return HDF_FAILURE;
+ }
+ return HDF_SUCCESS;
+}
+
+int32_t AudioCodecAiaoWriteReg(const struct CodecDevice *codec, uint32_t reg, uint32_t val)
+{
+ int32_t ret;
+ if (codec == NULL || codec->devData == NULL || codec->devData->AiaoWrite == NULL) {
+ ADM_LOG_ERR("Input param codec aiao is NULL.");
+ return HDF_FAILURE;
+ }
+ ret = codec->devData->AiaoWrite(codec, reg, val);
+ if (ret != HDF_SUCCESS) {
+ ADM_LOG_ERR("Codec aiao device write fail.");
+ return HDF_FAILURE;
+ }
+ return HDF_SUCCESS;
+}
+
+int32_t AudioAccessoryAiaoWriteReg(const struct AccessoryDevice *accessory, uint32_t reg, uint32_t val)
+{
+ int32_t ret;
+ if (accessory == NULL || accessory->devData == NULL || accessory->devData->AiaoWrite == NULL) {
+ ADM_LOG_ERR("Input param accessory aiao is NULL.");
+ return HDF_FAILURE;
+ }
+ ret = accessory->devData->AiaoWrite(accessory, reg, val);
+ if (ret != HDF_SUCCESS) {
+ ADM_LOG_ERR("Accessory aiao device write fail.");
+ return HDF_FAILURE;
+ }
+ return HDF_SUCCESS;
+}
+
+int32_t AudioInfoCtrlOps(const struct AudioKcontrol *kcontrol, struct AudioCtrlElemInfo *elemInfo)
+{
+ struct AudioMixerControl *mixerCtrl = NULL;
+
+ if (kcontrol == NULL || kcontrol->privateValue <= 0 || elemInfo == NULL) {
+ ADM_LOG_ERR("Input param kcontrol is NULL.");
+ return HDF_ERR_INVALID_OBJECT;
+ }
+
+ elemInfo->count = CHANNEL_MIN_NUM;
+ mixerCtrl = (struct AudioMixerControl *)((volatile uintptr_t)(kcontrol->privateValue));
+ /* stereo */
+ if (mixerCtrl->reg != mixerCtrl->rreg || mixerCtrl->shift != mixerCtrl->rshift) {
+ elemInfo->count = CHANNEL_MAX_NUM;
+ }
+ elemInfo->type = 1; /* volume type */
+ elemInfo->min = mixerCtrl->min;
+ elemInfo->max = mixerCtrl->max;
+
+ return HDF_SUCCESS;
+}
+
+static int32_t AudioGetCtrlOpsRReg(struct AudioCtrlElemValue *elemValue,
+ const struct AudioMixerControl *mixerCtrl, uint32_t rcurValue)
+{
+ if (elemValue == NULL || mixerCtrl == NULL) {
+ ADM_LOG_ERR("Audio input param is NULL.");
+ return HDF_ERR_INVALID_OBJECT;
+ }
+
+ if (mixerCtrl->reg != mixerCtrl->rreg || mixerCtrl->shift != mixerCtrl->rshift) {
+ if (mixerCtrl->reg == mixerCtrl->rreg) {
+ rcurValue = (rcurValue >> mixerCtrl->rshift) & mixerCtrl->mask;
+ } else {
+ rcurValue = (rcurValue >> mixerCtrl->shift) & mixerCtrl->mask;
+ }
+ if (rcurValue > mixerCtrl->max || rcurValue < mixerCtrl->min) {
+ ADM_LOG_ERR("Audio invalid rcurValue=%d", rcurValue);
+ return HDF_FAILURE;
+ }
+ if (mixerCtrl->invert) {
+ rcurValue = mixerCtrl->max - rcurValue;
+ }
+ elemValue->value[1] = rcurValue;
+ }
+
+ return HDF_SUCCESS;
+}
+
+static int32_t AudioGetCtrlOpsReg(struct AudioCtrlElemValue *elemValue,
+ const struct AudioMixerControl *mixerCtrl, uint32_t curValue)
+{
+ if (elemValue == NULL || mixerCtrl == NULL) {
+ ADM_LOG_ERR("Audio input param is NULL.");
+ return HDF_ERR_INVALID_OBJECT;
+ }
+
+ curValue = (curValue >> mixerCtrl->shift) & mixerCtrl->mask;
+ if (curValue > mixerCtrl->max || curValue < mixerCtrl->min) {
+ ADM_LOG_ERR("Audio invalid curValue=%d", curValue);
+ return HDF_FAILURE;
+ }
+ if (mixerCtrl->invert) {
+ curValue = mixerCtrl->max - curValue;
+ }
+ elemValue->value[0] = curValue;
+
+ return HDF_SUCCESS;
+}
+
+int32_t AudioCodecGetCtrlOps(const struct AudioKcontrol *kcontrol, struct AudioCtrlElemValue *elemValue)
+{
+ uint32_t curValue = 0;
+ uint32_t rcurValue = 0;
+ struct AudioMixerControl *mixerCtrl = NULL;
+ struct CodecDevice *codec = NULL;
+ if (kcontrol == NULL || kcontrol->privateValue <= 0 || elemValue == NULL) {
+ ADM_LOG_ERR("Audio input param is NULL.");
+ return HDF_ERR_INVALID_OBJECT;
+ }
+ mixerCtrl = (struct AudioMixerControl *)((volatile uintptr_t)kcontrol->privateValue);
+ codec = AudioKcontrolGetCodec(kcontrol);
+ if (mixerCtrl == NULL || codec == NULL) {
+ ADM_LOG_ERR("mixerCtrl and codec is NULL.");
+ return HDF_FAILURE;
+ }
+ if (AudioCodecReadReg(codec, mixerCtrl->reg, &curValue) != HDF_SUCCESS ||
+ AudioCodecReadReg(codec, mixerCtrl->rreg, &rcurValue) != HDF_SUCCESS) {
+ ADM_LOG_ERR("Read Reg fail.");
+ return HDF_FAILURE;
+ }
+ if (AudioGetCtrlOpsReg(elemValue, mixerCtrl, curValue) != HDF_SUCCESS ||
+ AudioGetCtrlOpsRReg(elemValue, mixerCtrl, rcurValue) != HDF_SUCCESS) {
+ ADM_LOG_ERR("Audio codec get kcontrol reg and rreg fail.");
+ return HDF_FAILURE;
+ }
+
+ return HDF_SUCCESS;
+}
+
+int32_t AudioAccessoryGetCtrlOps(const struct AudioKcontrol *kcontrol, struct AudioCtrlElemValue *elemValue)
+{
+ uint32_t curValue = 0;
+ uint32_t rcurValue = 0;
+ struct AudioMixerControl *mixerCtrl = NULL;
+ struct AccessoryDevice *accessory = NULL;
+ if (kcontrol == NULL || kcontrol->privateValue <= 0 || elemValue == NULL) {
+ ADM_LOG_ERR("Audio input param is NULL.");
+ return HDF_ERR_INVALID_OBJECT;
+ }
+
+ mixerCtrl = (struct AudioMixerControl *)((volatile uintptr_t)kcontrol->privateValue);
+ accessory = AudioKcontrolGetAccessory(kcontrol);
+ if (mixerCtrl == NULL || accessory == NULL) {
+ ADM_LOG_ERR("mixerCtrl and accessory is NULL.");
+ return HDF_FAILURE;
+ }
+ if (AudioAccessoryReadReg(accessory, mixerCtrl->reg, &curValue) != HDF_SUCCESS ||
+ AudioAccessoryReadReg(accessory, mixerCtrl->rreg, &rcurValue) != HDF_SUCCESS) {
+ ADM_LOG_ERR("Read Reg fail.");
+ return HDF_FAILURE;
+ }
+ if (AudioGetCtrlOpsReg(elemValue, mixerCtrl, curValue) != HDF_SUCCESS ||
+ AudioGetCtrlOpsRReg(elemValue, mixerCtrl, rcurValue) != HDF_SUCCESS) {
+ ADM_LOG_ERR("Audio accessory get kcontrol reg and rreg fail.");
+ return HDF_FAILURE;
+ }
+
+ return HDF_SUCCESS;
+}
+
+int32_t AudioCodecAiaoGetCtrlOps(const struct AudioKcontrol *kcontrol, struct AudioCtrlElemValue *elemValue)
+{
+ uint32_t curValue = 0;
+ uint32_t rcurValue = 0;
+ struct CodecDevice *codec = NULL;
+ struct AudioMixerControl *mixerCtrl = NULL;
+ if (kcontrol == NULL || kcontrol->privateValue <= 0 || elemValue == NULL) {
+ ADM_LOG_ERR("CODECAIAO input param is NULL.");
+ return HDF_ERR_INVALID_OBJECT;
+ }
+
+ codec = AudioKcontrolGetCodec(kcontrol);
+ mixerCtrl = (struct AudioMixerControl *)((volatile uintptr_t)kcontrol->privateValue);
+ if (mixerCtrl == NULL || codec == NULL) {
+ ADM_LOG_ERR("mixerCtrl and codec is NULL.");
+ return HDF_FAILURE;
+ }
+ if (AudioCodecAiaoReadReg(codec, mixerCtrl->reg, &curValue) != HDF_SUCCESS ||
+ AudioCodecAiaoReadReg(codec, mixerCtrl->rreg, &rcurValue) != HDF_SUCCESS) {
+ ADM_LOG_ERR("Read Reg fail.");
+ return HDF_FAILURE;
+ }
+ if (AudioGetCtrlOpsReg(elemValue, mixerCtrl, curValue) != HDF_SUCCESS ||
+ AudioGetCtrlOpsRReg(elemValue, mixerCtrl, rcurValue) != HDF_SUCCESS) {
+ ADM_LOG_ERR("Audio CODECAIAO get kcontrol reg and rreg fail.");
+ return HDF_FAILURE;
+ }
+
+ ADM_LOG_DEBUG("Get CODECAIAO ctrl switch successful.");
+ return HDF_SUCCESS;
+}
+
+int32_t AudioAccessoryAiaoGetCtrlOps(const struct AudioKcontrol *kcontrol, struct AudioCtrlElemValue *elemValue)
+{
+ uint32_t curValue = 0;
+ uint32_t rcurValue = 0;
+ struct AccessoryDevice *accessory = NULL;
+ struct AudioMixerControl *mixerCtrl = NULL;
+ if (kcontrol == NULL || kcontrol->privateValue <= 0 || elemValue == NULL) {
+ ADM_LOG_ERR("ACCESSORYCAIAO input param is NULL.");
+ return HDF_ERR_INVALID_OBJECT;
+ }
+
+ accessory = AudioKcontrolGetAccessory(kcontrol);
+ mixerCtrl = (struct AudioMixerControl *)((volatile uintptr_t)kcontrol->privateValue);
+ if (mixerCtrl == NULL || accessory == NULL) {
+ ADM_LOG_ERR("mixerCtrl and accessory is NULL.");
+ return HDF_FAILURE;
+ }
+ if (AudioAccessoryAiaoReadReg(accessory, mixerCtrl->reg, &curValue) != HDF_SUCCESS ||
+ AudioAccessoryAiaoReadReg(accessory, mixerCtrl->rreg, &rcurValue) != HDF_SUCCESS) {
+ ADM_LOG_ERR("Read Reg fail.");
+ return HDF_FAILURE;
+ }
+ if (AudioGetCtrlOpsReg(elemValue, mixerCtrl, curValue) != HDF_SUCCESS ||
+ AudioGetCtrlOpsRReg(elemValue, mixerCtrl, rcurValue) != HDF_SUCCESS) {
+ ADM_LOG_ERR("Audio ACCESSORYCAIAO get kcontrol reg and rreg fail.");
+ return HDF_FAILURE;
+ }
+
+ ADM_LOG_DEBUG("Get ACCESSORYCAIAO ctrl switch successful.");
+ return HDF_SUCCESS;
+}
+
+static int32_t AudioSetCtrlOpsReg(const struct AudioKcontrol *kcontrol, const struct AudioCtrlElemValue *elemValue,
+ const struct AudioMixerControl *mixerCtrl, uint32_t *value)
+{
+ if (kcontrol == NULL || (kcontrol->privateValue <= 0) || elemValue == NULL ||
+ mixerCtrl == NULL || value == NULL) {
+ ADM_LOG_ERR("Audio input param is NULL.");
+ return HDF_ERR_INVALID_OBJECT;
+ }
+
+ *value = elemValue->value[0];
+ if (*value < mixerCtrl->min || *value > mixerCtrl->max) {
+ ADM_LOG_ERR("Audio invalid value=%d", *value);
+ return HDF_ERR_INVALID_OBJECT;
+ }
+ if (mixerCtrl->invert) {
+ *value = mixerCtrl->max - *value;
+ }
+
+ return HDF_SUCCESS;
+}
+
+static int32_t AudioSetCtrlOpsRReg(const struct AudioCtrlElemValue *elemValue,
+ struct AudioMixerControl *mixerCtrl, uint32_t *rvalue, bool *updateRReg)
+{
+ uint32_t rshift;
+ if (elemValue == NULL || mixerCtrl == NULL || rvalue == NULL || updateRReg == NULL) {
+ ADM_LOG_ERR("Audio input param is NULL.");
+ return HDF_ERR_INVALID_OBJECT;
+ }
+
+ if (mixerCtrl->reg != mixerCtrl->rreg || mixerCtrl->shift != mixerCtrl->rshift) {
+ *updateRReg = true;
+ *rvalue = elemValue->value[1];
+ if (*rvalue < mixerCtrl->min || *rvalue > mixerCtrl->max) {
+ ADM_LOG_ERR("Audio invalid fail.");
+ return HDF_FAILURE;
+ }
+ if (mixerCtrl->invert) {
+ *rvalue = mixerCtrl->max - *rvalue;
+ }
+ if (mixerCtrl->reg == mixerCtrl->rreg) {
+ rshift = mixerCtrl->rshift;
+ } else {
+ rshift = mixerCtrl->shift;
+ }
+ mixerCtrl->shift = rshift;
+ }
+
+ return HDF_SUCCESS;
+}
+
+int32_t AudioCodecSetCtrlOps(const struct AudioKcontrol *kcontrol, const struct AudioCtrlElemValue *elemValue)
+{
+ uint32_t value;
+ uint32_t rvalue;
+ bool updateRReg = false;
+ struct CodecDevice *codec = NULL;
+ struct AudioMixerControl *mixerCtrl = NULL;
+ if (kcontrol == NULL || (kcontrol->privateValue <= 0) || elemValue == NULL) {
+ ADM_LOG_ERR("Audio input param is NULL.");
+ return HDF_ERR_INVALID_OBJECT;
+ }
+
+ mixerCtrl = (struct AudioMixerControl *)((volatile uintptr_t)kcontrol->privateValue);
+ if (AudioSetCtrlOpsReg(kcontrol, elemValue, mixerCtrl, &value) != HDF_SUCCESS) {
+ ADM_LOG_ERR("AudioSetCtrlOpsReg is fail.");
+ return HDF_ERR_INVALID_OBJECT;
+ }
+ codec = AudioKcontrolGetCodec(kcontrol);
+ if (codec == NULL) {
+ ADM_LOG_ERR("AudioKcontrolGetCodec is fail.");
+ return HDF_ERR_INVALID_OBJECT;
+ }
+ if (AudioUpdateCodecRegBits(codec, mixerCtrl, value) != HDF_SUCCESS) {
+ ADM_LOG_ERR("Audio codec stereo update reg bits fail.");
+ return HDF_FAILURE;
+ }
+
+ if (AudioSetCtrlOpsRReg(elemValue, mixerCtrl, &rvalue, &updateRReg) != HDF_SUCCESS) {
+ ADM_LOG_ERR("AudioSetCtrlOpsRReg is fail.");
+ return HDF_ERR_INVALID_OBJECT;
+ }
+
+ if (updateRReg) {
+ if (AudioUpdateCodecRegBits(codec, mixerCtrl, rvalue) != HDF_SUCCESS) {
+ ADM_LOG_ERR("Audio codec stereo update reg bits fail.");
+ return HDF_FAILURE;
+ }
+ }
+ return HDF_SUCCESS;
+}
+
+int32_t AudioAccessorySetCtrlOps(const struct AudioKcontrol *kcontrol, const struct AudioCtrlElemValue *elemValue)
+{
+ uint32_t value;
+ uint32_t rvalue;
+ bool updateRReg = false;
+ struct AccessoryDevice *accessory = NULL;
+ struct AudioMixerControl *mixerCtrl = NULL;
+ if (kcontrol == NULL || (kcontrol->privateValue <= 0) || elemValue == NULL) {
+ ADM_LOG_ERR("Audio input param is NULL.");
+ return HDF_ERR_INVALID_OBJECT;
+ }
+
+ mixerCtrl = (struct AudioMixerControl *)((volatile uintptr_t)kcontrol->privateValue);
+ if (AudioSetCtrlOpsReg(kcontrol, elemValue, mixerCtrl, &value) != HDF_SUCCESS) {
+ ADM_LOG_ERR("AudioSetCtrlOpsReg fail.");
+ return HDF_FAILURE;
+ }
+
+ accessory = AudioKcontrolGetAccessory(kcontrol);
+ if (AudioUpdateAccessoryRegBits(accessory, mixerCtrl, value) != HDF_SUCCESS) {
+ ADM_LOG_ERR("Audio accessory stereo update reg bits fail.");
+ return HDF_FAILURE;
+ }
+
+ if (AudioSetCtrlOpsRReg(elemValue, mixerCtrl, &rvalue, &updateRReg) != HDF_SUCCESS) {
+ ADM_LOG_ERR("AudioSetCtrlOpsRReg fail.");
+ return HDF_FAILURE;
+ }
+
+ if (updateRReg) {
+ if (AudioUpdateAccessoryRegBits(accessory, mixerCtrl, rvalue) != HDF_SUCCESS) {
+ ADM_LOG_ERR("Audio accessory stereo update reg bits fail.");
+ return HDF_FAILURE;
+ }
+ }
+
+ return HDF_SUCCESS;
+}
+
+int32_t AudioCodecAiaoSetCtrlOps(const struct AudioKcontrol *kcontrol, const struct AudioCtrlElemValue *elemValue)
+{
+ uint32_t value;
+ uint32_t rvalue;
+ bool updateRReg = false;
+ struct CodecDevice *codec = NULL;
+ struct AudioMixerControl *mixerCtrl = NULL;
+ if (kcontrol == NULL || (kcontrol->privateValue <= 0) || elemValue == NULL) {
+ ADM_LOG_ERR("Audio codec aiao input param is NULL.");
+ return HDF_ERR_INVALID_OBJECT;
+ }
+
+ mixerCtrl = (struct AudioMixerControl *)((volatile uintptr_t)kcontrol->privateValue);
+ if (AudioSetCtrlOpsReg(kcontrol, elemValue, mixerCtrl, &value) != HDF_SUCCESS) {
+ ADM_LOG_ERR("AudioSetCtrlOpsReg fail.");
+ return HDF_FAILURE;
+ }
+
+ codec = AudioKcontrolGetCodec(kcontrol);
+ if (AudioUpdateCodecAiaoRegBits(codec, mixerCtrl, value) != HDF_SUCCESS) {
+ ADM_LOG_ERR("Audio codec aiao stereo update reg bits fail.");
+ return HDF_FAILURE;
+ }
+
+ if (AudioSetCtrlOpsRReg(elemValue, mixerCtrl, &rvalue, &updateRReg) != HDF_SUCCESS) {
+ ADM_LOG_ERR("AudioSetCtrlOpsRReg fail.");
+ return HDF_FAILURE;
+ }
+ if (updateRReg) {
+ if (AudioUpdateCodecAiaoRegBits(codec, mixerCtrl, rvalue) != HDF_SUCCESS) {
+ ADM_LOG_ERR("Audio codec aiao stereo update reg bits fail.");
+ return HDF_FAILURE;
+ }
+ }
+
+ return HDF_SUCCESS;
+}
+
+int32_t AudioAccessoryAiaoSetCtrlOps(const struct AudioKcontrol *kcontrol, const struct AudioCtrlElemValue *elemValue)
+{
+ uint32_t value;
+ uint32_t rvalue;
+ bool updateRReg = false;
+ struct AccessoryDevice *accessory = NULL;
+ struct AudioMixerControl *mixerCtrl = NULL;
+ if (kcontrol == NULL || (kcontrol->privateValue <= 0) || elemValue == NULL) {
+ ADM_LOG_ERR("Audio accessory aiao input param is NULL.");
+ return HDF_ERR_INVALID_OBJECT;
+ }
+
+ mixerCtrl = (struct AudioMixerControl *)((volatile uintptr_t)kcontrol->privateValue);
+ if (AudioSetCtrlOpsReg(kcontrol, elemValue, mixerCtrl, &value) != HDF_SUCCESS) {
+ ADM_LOG_ERR("AudioSetCtrlOpsReg fail.");
+ return HDF_FAILURE;
+ }
+
+ accessory = AudioKcontrolGetAccessory(kcontrol);
+ if (AudioUpdateAccessoryAiaoRegBits(accessory, mixerCtrl, value) != HDF_SUCCESS) {
+ ADM_LOG_ERR("Audio accessory aiao stereo update reg bits fail.");
+ return HDF_FAILURE;
+ }
+
+ if (AudioSetCtrlOpsRReg(elemValue, mixerCtrl, &rvalue, &updateRReg) != HDF_SUCCESS) {
+ ADM_LOG_ERR("AudioSetCtrlOpsRReg fail.");
+ return HDF_FAILURE;
+ }
+
+ if (updateRReg) {
+ if (AudioUpdateAccessoryAiaoRegBits(accessory, mixerCtrl, rvalue) != HDF_SUCCESS) {
+ ADM_LOG_ERR("Audio accessory aiao stereo update reg bits fail.");
+ return HDF_FAILURE;
+ }
+ }
+
+ return HDF_SUCCESS;
+}
diff --git a/model/audio/core/src/audio_host.c b/model/audio/core/src/audio_host.c
new file mode 100755
index 0000000000000000000000000000000000000000..5ef6da851b7a681919847ec1112db342548d3dcc
--- /dev/null
+++ b/model/audio/core/src/audio_host.c
@@ -0,0 +1,480 @@
+/*
+ * Copyright (c) 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 "audio_host.h"
+#include "audio_codec_if.h"
+#include "audio_core.h"
+#include "audio_parse.h"
+#include "audio_sapm.h"
+
+#define HDF_LOG_TAG audio_host
+
+AUDIO_LIST_HEAD(cardManager);
+
+/* Get a sound card instance */
+struct AudioCard *GetCardInstance(const char *serviceName)
+{
+ struct AudioCard *audioCard = NULL;
+
+ if (serviceName == NULL) {
+ ADM_LOG_ERR("serviceName is NULL.");
+ return NULL;
+ }
+
+ if (DListIsEmpty(&cardManager)) {
+ ADM_LOG_ERR("cardManager is empty.");
+ return NULL;
+ }
+
+ DLIST_FOR_EACH_ENTRY(audioCard, &cardManager, struct AudioCard, list) {
+ if (audioCard->configData.cardServiceName == NULL) {
+ ADM_LOG_ERR("cardServiceName is NULL.");
+ return NULL;
+ }
+
+ if (strcmp(audioCard->configData.cardServiceName, serviceName) == 0) {
+ return audioCard;
+ }
+ }
+ return NULL;
+}
+
+static int32_t AudioCodecDevInit(struct AudioCard *audioCard)
+{
+ if (audioCard == NULL) {
+ ADM_LOG_ERR("audioCard is NULL.");
+ return HDF_ERR_IO;
+ }
+
+ ADM_LOG_DEBUG("entry.");
+ struct AudioRuntimeDeivces *rtd = NULL;
+ struct CodecDevice *codec = NULL;
+ rtd = audioCard->rtd;
+ if (rtd == NULL) {
+ ADM_LOG_ERR("rtd is NULL.");
+ return HDF_ERR_IO;
+ }
+ codec = rtd->codec;
+ if (codec != NULL && codec->devData != NULL && codec->devData->Init != NULL) {
+ /* codec initialization */
+ int32_t ret = codec->devData->Init(audioCard, codec);
+ if (ret != HDF_SUCCESS) {
+ ADM_LOG_ERR("codec initialization fail ret=%d", ret);
+ return HDF_ERR_IO;
+ }
+ }
+
+ ADM_LOG_INFO("success.");
+ return HDF_SUCCESS;
+}
+
+static int32_t AudioAccessoryDevInit(struct AudioCard *audioCard)
+{
+ if (audioCard == NULL) {
+ ADM_LOG_ERR("audioCard is NULL.");
+ return HDF_ERR_IO;
+ }
+
+ ADM_LOG_DEBUG("entry.");
+ struct AudioRuntimeDeivces *rtd = NULL;
+ struct AccessoryDevice *accessory = NULL;
+ rtd = audioCard->rtd;
+ if (rtd == NULL) {
+ ADM_LOG_ERR("rtd is NULL.");
+ return HDF_ERR_IO;
+ }
+ accessory = rtd->accessory;
+ if (accessory != NULL && accessory->devData != NULL && accessory->devData->Init != NULL) {
+ /* codec initialization */
+ int32_t ret = accessory->devData->Init(audioCard, accessory);
+ if (ret != HDF_SUCCESS) {
+ ADM_LOG_ERR("accessory initialization fail ret=%d", ret);
+ return HDF_ERR_IO;
+ }
+ }
+
+ ADM_LOG_INFO("success.");
+ return HDF_SUCCESS;
+}
+
+static int32_t AudioPlatformDevInit(const struct AudioCard *audioCard)
+{
+ struct AudioRuntimeDeivces *rtd = NULL;
+ struct PlatformDevice *platform = NULL;
+
+ if (audioCard == NULL) {
+ ADM_LOG_ERR("input param is NULL.");
+ return HDF_ERR_IO;
+ }
+ ADM_LOG_DEBUG("entry.");
+
+ rtd = audioCard->rtd;
+ if (rtd == NULL) {
+ ADM_LOG_ERR("Platform rtd is NULL.");
+ return HDF_ERR_IO;
+ }
+ platform = rtd->platform;
+ if (platform != NULL && platform->devData != NULL && platform->devData->PlatformInit != NULL) {
+ /* platform initialization */
+ int32_t ret = platform->devData->PlatformInit(audioCard, platform);
+ if (ret != HDF_SUCCESS) {
+ ADM_LOG_ERR("platform initialization fail ret=%d", ret);
+ return HDF_ERR_IO;
+ }
+ }
+
+ ADM_LOG_INFO("success.");
+ return HDF_SUCCESS;
+}
+
+static int32_t AudioDspDevInit(const struct AudioCard *audioCard)
+{
+ struct AudioRuntimeDeivces *rtd = NULL;
+ struct DspDevice *dsp = NULL;
+
+ if (audioCard == NULL) {
+ ADM_LOG_ERR("audioCard is NULL.");
+ return HDF_ERR_IO;
+ }
+ ADM_LOG_DEBUG("entry.");
+
+ rtd = audioCard->rtd;
+ if (rtd == NULL) {
+ ADM_LOG_ERR("audioCard rtd object is NULL.");
+ return HDF_ERR_IO;
+ }
+
+ dsp = rtd->dsp;
+ if (dsp != NULL && dsp->devData != NULL && dsp->devData->DspInit != NULL) {
+ /* dsp initialization */
+ int32_t ret = dsp->devData->DspInit(dsp);
+ if (ret != HDF_SUCCESS) {
+ ADM_LOG_ERR("dsp initialization fail ret=%d", ret);
+ return HDF_ERR_IO;
+ }
+ }
+
+ ADM_LOG_INFO("success.");
+ return HDF_SUCCESS;
+}
+
+static int32_t AudioCodecDaiDevInit(const struct AudioCard *audioCard)
+{
+ struct AudioRuntimeDeivces *rtd = NULL;
+ struct DaiDevice *codecDai = NULL;
+
+ if (audioCard == NULL) {
+ ADM_LOG_ERR("audioCard is NULL.");
+ return HDF_ERR_IO;
+ }
+ ADM_LOG_DEBUG("entry.");
+
+ rtd = audioCard->rtd;
+ if (rtd == NULL) {
+ ADM_LOG_ERR("CodecDai rtd is NULL.");
+ return HDF_ERR_IO;
+ }
+ codecDai = rtd->codecDai;
+ if (codecDai != NULL && codecDai->devData != NULL && codecDai->devData->DaiInit != NULL) {
+ /* codec dai initialization */
+ int32_t ret = codecDai->devData->DaiInit(audioCard, codecDai);
+ if (ret != HDF_SUCCESS) {
+ ADM_LOG_ERR("codec dai initialization fail ret=%d", ret);
+ return HDF_ERR_IO;
+ }
+ }
+
+ ADM_LOG_INFO("success.");
+ return HDF_SUCCESS;
+}
+
+static int32_t AudioAccessoryDaiDevInit(const struct AudioCard *audioCard)
+{
+ struct AudioRuntimeDeivces *rtd = NULL;
+ struct DaiDevice *accessoryDai = NULL;
+
+ if (audioCard == NULL) {
+ ADM_LOG_ERR("audioCard is NULL.");
+ return HDF_ERR_IO;
+ }
+ ADM_LOG_DEBUG("entry.");
+
+ rtd = audioCard->rtd;
+ if (rtd == NULL) {
+ ADM_LOG_ERR("accessoryDai rtd is NULL.");
+ return HDF_ERR_IO;
+ }
+ accessoryDai = rtd->accessoryDai;
+ if (accessoryDai != NULL && accessoryDai->devData != NULL && accessoryDai->devData->DaiInit != NULL) {
+ /* codec dai initialization */
+ int32_t ret = accessoryDai->devData->DaiInit(audioCard, accessoryDai);
+ if (ret != HDF_SUCCESS) {
+ ADM_LOG_ERR("accessory dai initialization fail ret=%d", ret);
+ return HDF_ERR_IO;
+ }
+ }
+
+ ADM_LOG_INFO("success.");
+ return HDF_SUCCESS;
+}
+
+static int32_t AudioCpuDaiDevInit(const struct AudioCard *audioCard)
+{
+ struct AudioRuntimeDeivces *rtd = NULL;
+ struct DaiDevice *cpuDai = NULL;
+
+ if (audioCard == NULL) {
+ ADM_LOG_ERR("audioCard is NULL.");
+ return HDF_ERR_IO;
+ }
+ ADM_LOG_DEBUG("entry.");
+
+ rtd = audioCard->rtd;
+ if (rtd == NULL) {
+ ADM_LOG_ERR("cpuDai rtd is NULL.");
+ return HDF_ERR_IO;
+ }
+ cpuDai = rtd->cpuDai;
+ if (cpuDai != NULL && cpuDai->devData != NULL && cpuDai->devData->DaiInit != NULL) {
+ /* cpu dai initialization */
+ int32_t ret = cpuDai->devData->DaiInit(audioCard, cpuDai);
+ if (ret != HDF_SUCCESS) {
+ ADM_LOG_ERR("cpu dai initialization fail ret=%d", ret);
+ return HDF_ERR_IO;
+ }
+ }
+
+ ADM_LOG_INFO("success.");
+ return HDF_SUCCESS;
+}
+
+static int32_t AudioDspDaiDevInit(const struct AudioCard *audioCard)
+{
+ struct AudioRuntimeDeivces *rtd = NULL;
+ struct DaiDevice *dspDai = NULL;
+ int ret = HDF_SUCCESS;
+
+ if (audioCard == NULL) {
+ ADM_LOG_ERR("audioCard is NULL.");
+ return HDF_ERR_IO;
+ }
+ ADM_LOG_DEBUG("dsp init entry.");
+
+ rtd = audioCard->rtd;
+ if (rtd == NULL) {
+ ADM_LOG_ERR("dspDai rtd is NULL.");
+ return HDF_ERR_IO;
+ }
+
+ dspDai = rtd->dspDai;
+ if (dspDai != NULL && dspDai->devData != NULL && dspDai->devData->DaiInit != NULL) {
+ ret = dspDai->devData->DaiInit(audioCard, dspDai);
+ if (ret != HDF_SUCCESS) {
+ ADM_LOG_ERR("dsp dai initialization fail ret=%d", ret);
+ return HDF_ERR_IO;
+ }
+ }
+
+ ADM_LOG_INFO("success.");
+ return HDF_SUCCESS;
+}
+
+static int32_t AudioInitDaiLink(struct AudioCard *audioCard)
+{
+ if (audioCard == NULL) {
+ ADM_LOG_ERR("audioCard is NULL.");
+ return HDF_ERR_IO;
+ }
+ ADM_LOG_DEBUG("entry.");
+
+ if (AudioPlatformDevInit(audioCard) || AudioCpuDaiDevInit(audioCard)) {
+ ADM_LOG_ERR("Platform and CpuDai init fail.");
+ return HDF_ERR_IO;
+ }
+
+ if ((AudioCodecDevInit(audioCard) || AudioCodecDaiDevInit(audioCard))) {
+ ADM_LOG_ERR("codec init fail.");
+ return HDF_ERR_IO;
+ }
+
+ if (AudioAccessoryDevInit(audioCard) || AudioAccessoryDaiDevInit(audioCard)) {
+ ADM_LOG_ERR("Accessory init fail.");
+ return HDF_ERR_IO;
+ }
+
+ if (AudioDspDevInit(audioCard) || AudioDspDaiDevInit(audioCard)) {
+ ADM_LOG_ERR("Dsp Dai init fail.");
+ return HDF_ERR_IO;
+ }
+
+ ADM_LOG_DEBUG("success.");
+ return HDF_SUCCESS;
+}
+
+struct AudioHost *AudioHostCreateAndBind(struct HdfDeviceObject *device)
+{
+ struct AudioHost *audioHost = NULL;
+
+ if (device == NULL) {
+ ADM_LOG_ERR("device is NULL!");
+ return NULL;
+ }
+
+ audioHost = (struct AudioHost *)OsalMemCalloc(sizeof(*audioHost));
+ if (audioHost == NULL) {
+ ADM_LOG_ERR("Malloc audio host fail!");
+ return NULL;
+ }
+ audioHost->device = device;
+ device->service = &audioHost->service;
+ return audioHost;
+}
+
+/* HdfDriverEntry implementations */
+static int32_t AudioDriverBind(struct HdfDeviceObject *device)
+{
+ struct AudioHost *audioHost = NULL;
+
+ ADM_LOG_DEBUG("entry.");
+ if (device == NULL) {
+ ADM_LOG_ERR("device is NULL.");
+ return HDF_ERR_INVALID_OBJECT;
+ }
+
+ audioHost = AudioHostCreateAndBind(device);
+ if (audioHost == NULL) {
+ ADM_LOG_ERR("audioHost create failed!");
+ return HDF_FAILURE;
+ }
+
+ ADM_LOG_INFO("success.");
+ return HDF_SUCCESS;
+}
+
+static int32_t AudioDriverInit(struct HdfDeviceObject *device)
+{
+ struct AudioCard *audioCard = NULL;
+ struct AudioHost *audioHost = NULL;
+ int32_t ret;
+
+ ADM_LOG_DEBUG("entry.");
+ if (device == NULL) {
+ ADM_LOG_ERR("device is NULL.");
+ return HDF_ERR_INVALID_OBJECT;
+ }
+ audioHost = AudioHostFromDevice(device);
+ if (audioHost == NULL) {
+ ADM_LOG_ERR("audioHost is NULL.");
+ return HDF_FAILURE;
+ }
+
+ audioCard = (struct AudioCard *)OsalMemCalloc(sizeof(*audioCard));
+ if (audioCard == NULL) {
+ ADM_LOG_ERR("Malloc audioCard fail!");
+ return HDF_FAILURE;
+ }
+ audioHost->priv = audioCard;
+ /* Get node information through HCS file */
+ ret = AudioFillConfigData(device, &(audioCard->configData));
+ if (ret != HDF_SUCCESS) {
+ ADM_LOG_ERR("AudioFillConfigData fail ret=%d", ret);
+ return HDF_ERR_IO;
+ }
+
+ /* Bind specific codec、platform and dai device */
+ AudioBindDaiLink(audioCard, &(audioCard->configData));
+ if (!audioCard->rtd->complete) {
+ ADM_LOG_ERR("AudioBindDaiLink fail!");
+ return HDF_ERR_IO;
+ }
+
+ /* Initialize controls list */
+ DListHeadInit(&audioCard->controls);
+ DListHeadInit(&audioCard->components);
+ DListHeadInit(&audioCard->paths);
+ DListHeadInit(&audioCard->sapmDirty);
+ /* Initialize hardware device */
+ ret = AudioInitDaiLink(audioCard);
+ if (ret != HDF_SUCCESS) {
+ ADM_LOG_ERR("AudioInitDaiLink fail ret=%d", ret);
+ return HDF_ERR_IO;
+ }
+
+ /* sound card added to list */
+ DListInsertHead(&audioCard->list, &cardManager);
+
+ ADM_LOG_INFO("success.");
+ return HDF_SUCCESS;
+}
+
+static void AudioDriverRelease(struct HdfDeviceObject *device)
+{
+ struct AudioHost *audioHost = NULL;
+ struct AudioCard *audioCard = NULL;
+ struct DListHead *componentHead = NULL;
+ struct DListHead *controlHead = NULL;
+ struct AudioSapmComponent *componentReq = NULL;
+ struct AudioSapmComponent *componentTmp = NULL;
+ struct AudioKcontrol *ctrlReq = NULL;
+ struct AudioKcontrol *ctrlTmp = NULL;
+
+ ADM_LOG_DEBUG("entry.");
+ if (device == NULL) {
+ ADM_LOG_ERR("device is NULL.");
+ return;
+ }
+ audioHost = AudioHostFromDevice(device);
+ if (audioHost == NULL) {
+ ADM_LOG_ERR("audioHost is NULL.");
+ return;
+ }
+
+ if (audioHost->priv != NULL) {
+ audioCard = (struct AudioCard *)audioHost->priv;
+
+ componentHead = &audioCard->components;
+ DLIST_FOR_EACH_ENTRY_SAFE(componentReq, componentTmp, componentHead, struct AudioSapmComponent, list) {
+ DListRemove(&componentReq->list);
+ if (componentReq->componentName != NULL) {
+ OsalMemFree(componentReq->componentName);
+ }
+ OsalMemFree(componentReq);
+ }
+
+ controlHead = &audioCard->controls;
+ DLIST_FOR_EACH_ENTRY_SAFE(ctrlReq, ctrlTmp, controlHead, struct AudioKcontrol, list) {
+ DListRemove(&ctrlReq->list);
+ if (ctrlReq->pri != NULL) {
+ OsalMemFree(ctrlReq->pri);
+ }
+ if (ctrlReq->privateData != NULL) {
+ OsalMemFree(ctrlReq->privateData);
+ }
+ OsalMemFree(ctrlReq);
+ }
+
+ if (audioCard->rtd != NULL) {
+ OsalMemFree(audioCard->rtd);
+ }
+
+ OsalMemFree(audioHost->priv);
+ }
+ OsalMemFree(audioHost);
+
+ ADM_LOG_INFO("success.");
+}
+
+/* HdfDriverEntry definitions */
+struct HdfDriverEntry g_audioDriverEntry = {
+ .moduleVersion = 1,
+ .moduleName = "HDF_AUDIO",
+ .Bind = AudioDriverBind,
+ .Init = AudioDriverInit,
+ .Release = AudioDriverRelease,
+};
+HDF_INIT(g_audioDriverEntry);
diff --git a/model/audio/core/src/audio_parse.c b/model/audio/core/src/audio_parse.c
new file mode 100755
index 0000000000000000000000000000000000000000..b483b3c0b3fc1f329fb2caab4ed23212e8f8ce82
--- /dev/null
+++ b/model/audio/core/src/audio_parse.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 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 "audio_parse.h"
+
+#define HDF_LOG_TAG audio_parse
+
+int32_t AudioFillConfigData(const struct HdfDeviceObject *device, struct AudioConfigData *configData)
+{
+ const struct DeviceResourceNode *node = NULL;
+ struct DeviceResourceIface *drsOps = NULL;
+ ADM_LOG_DEBUG("Entry.");
+
+ if (device == NULL || configData == NULL) {
+ ADM_LOG_ERR("Input para check error: device=%p, configData=%p.", device, configData);
+ return HDF_FAILURE;
+ }
+
+ node = device->property;
+ if (node == NULL) {
+ ADM_LOG_ERR("drs node is NULL.");
+ return HDF_FAILURE;
+ }
+ drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
+ if (drsOps == NULL || drsOps->GetString == NULL) {
+ ADM_LOG_ERR("AudioFillConfigData: invalid drs ops fail!");
+ return HDF_FAILURE;
+ }
+
+ int32_t serviceRet = drsOps->GetString(node, "serviceName", &(configData->cardServiceName), 0);
+ int32_t codecRet = drsOps->GetString(node, "codecName", &(configData->codecName), 0);
+ int32_t platformRet = drsOps->GetString(node, "platformName", &(configData->platformName), 0);
+ int32_t cpuRet = drsOps->GetString(node, "cpuDaiName", &(configData->cpuDaiName), 0);
+ int32_t codeDaiRet = drsOps->GetString(node, "codecDaiName", &(configData->codecDaiName), 0);
+ int32_t dspRet = drsOps->GetString(node, "dspName", &(configData->dspName), 0);
+ int32_t dspDaiRet = drsOps->GetString(node, "dspDaiName", &(configData->dspDaiName), 0);
+ int32_t accessoryRet = drsOps->GetString(node, "accessoryName", &(configData->accessoryName), 0);
+ int32_t accessoryDaiRet = drsOps->GetString(node, "accessoryDaiName", &(configData->accessoryDaiName), 0);
+ if (serviceRet || codecRet || platformRet || cpuRet || codeDaiRet ||
+ dspRet || dspDaiRet || accessoryRet || accessoryDaiRet) {
+ ADM_LOG_ERR("Read audioDeviceName fail: serviceRet=%d, codecRet=%d, platformRet=%d, cpuRet=%d, codeDaiRet=%d,"
+ "dspRet=%d, dspDaiRet=%d, accessoryRet=%d, accessoryDaiRet=%d",
+ serviceRet, codecRet, platformRet, cpuRet, codeDaiRet, dspRet,
+ dspDaiRet, accessoryRet, accessoryDaiRet);
+ return HDF_FAILURE;
+ }
+
+ ADM_LOG_DEBUG("Success! codecName = %s, platformName = %s, cpuDaiName = %s, codecDaiName = %s, "
+ "dspName = %s, dspDaiName = %s, accessoryName = %s, accessoryDaiName = %s.",
+ configData->codecName, configData->platformName, configData->cpuDaiName,
+ configData->codecDaiName, configData->dspName, configData->dspDaiName,
+ configData->accessoryName, configData->accessoryDaiName);
+
+ return HDF_SUCCESS;
+}
diff --git a/model/audio/core/test/unittest/common/audio_common_test.h b/model/audio/core/test/unittest/common/audio_common_test.h
new file mode 100755
index 0000000000000000000000000000000000000000..74f213f15efc9be3adc311d3a2d6dc6d6d4f48c3
--- /dev/null
+++ b/model/audio/core/test/unittest/common/audio_common_test.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 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 AUDIO_COMMON_TEST_H
+#define AUDIO_COMMON_TEST_H
+
+#include "hdf_types.h"
+
+const int32_t g_testAudioType = 701; // 701 is TEST_AUDIO_TYPE
+
+enum {
+ TESTGETCODEC,
+ TESTGETCARDINSTANCE,
+ TESTGETCCNFIGDATA,
+
+ TESTREGISTERPLATFORM,
+ TESTREGISTERDAI,
+ TESTREGISTERACCESSORY,
+ TESTREGISTERCODEC,
+ TESTREGISTERDSP,
+ TESTSOCDEVICEREGISTER,
+ TESTBINDDAILINK,
+ TESTUPDATECODECREGBITS,
+ TESTUPDATEACCESSORYREGBITS,
+ TESTUPDATECODECAIAOREGBITS,
+ TESTUPDATEACCESSORYAIAOREGBITS,
+ TESTKCONTROLGETCODEC,
+ TESTKCONTROLGETACCESSORY,
+ TESTADDCONTROL,
+ TESTADDCONTROLS,
+ TESTCODECREADREG,
+ TESTACCESSORYREADREG,
+ TESTCODECAIAOREADREG,
+ TESTACCESSORYAIAOREADREG,
+ TESTCODECWRITEREG,
+ TESTACCESSORYWRITEREG,
+ TESTCODECAIAOWRITEREG,
+ TESTACCESSORYAIAOWRITEREG,
+ TESTINFOCTRLOPS,
+ TESTCODECGETCTRLOPS,
+ TESTACCESSORYGETCTRLOPS,
+ TESTCODECAIAOGETCTRLOPS,
+ TESTACCESSORYAIAOGETCTRLOPS,
+ TESTCODECSETCTRLOPS,
+ TESTACCESSORYSETCTRLOPS,
+ TESTCODECAIAOSETCTRLOPS,
+ TESTACCESSORYAIAOSETCTRLOPS,
+
+ TESTNEWCOMPONENT,
+ TESTADDROUTES,
+ TESTNEWCONTROLS,
+ TESTPOWERCOMPONET,
+ TESTREFRESHTIME,
+ TESTSTREAMDISPATCH,
+};
+
+#endif /* AUDIO_COMMON_TEST_H */
diff --git a/model/audio/core/test/unittest/common/audio_core_test.cpp b/model/audio/core/test/unittest/common/audio_core_test.cpp
new file mode 100755
index 0000000000000000000000000000000000000000..91f8f7900a11b3e70f40f53bb33a25e6333f0059
--- /dev/null
+++ b/model/audio/core/test/unittest/common/audio_core_test.cpp
@@ -0,0 +1,232 @@
+/*
+ * Copyright (c) 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 "audio_common_test.h"
+#include
+#include "hdf_uhdf_test.h"
+
+using namespace testing::ext;
+namespace {
+class AudioCoreTest : public testing::Test {
+public:
+ static void SetUpTestCase();
+ static void TearDownTestCase();
+ void SetUp();
+ void TearDown();
+};
+
+void AudioCoreTest::SetUpTestCase()
+{
+ HdfTestOpenService();
+}
+
+void AudioCoreTest::TearDownTestCase()
+{
+ HdfTestCloseService();
+}
+
+void AudioCoreTest::SetUp()
+{
+}
+
+void AudioCoreTest::TearDown()
+{
+}
+
+HWTEST_F(AudioCoreTest, AudioCoreTest_RegisterPlatform, TestSize.Level0)
+{
+ struct HdfTestMsg msg = {g_testAudioType, TESTREGISTERPLATFORM, -1};
+ EXPECT_EQ(0, HdfTestSendMsgToService(&msg));
+}
+
+HWTEST_F(AudioCoreTest, AudioCoreTest_RegisterDai, TestSize.Level0)
+{
+ struct HdfTestMsg msg = {g_testAudioType, TESTREGISTERDAI, -1};
+ EXPECT_EQ(0, HdfTestSendMsgToService(&msg));
+}
+
+HWTEST_F(AudioCoreTest, AudioCoreTest_RegisterAccessory, TestSize.Level0)
+{
+ struct HdfTestMsg msg = {g_testAudioType, TESTREGISTERACCESSORY, -1};
+ EXPECT_EQ(0, HdfTestSendMsgToService(&msg));
+}
+
+HWTEST_F(AudioCoreTest, AudioCoreTest_RegisterCodec, TestSize.Level0)
+{
+ struct HdfTestMsg msg = {g_testAudioType, TESTREGISTERCODEC, -1};
+ EXPECT_EQ(0, HdfTestSendMsgToService(&msg));
+}
+
+HWTEST_F(AudioCoreTest, AudioCoreTest_SocRegisterDsp, TestSize.Level0)
+{
+ struct HdfTestMsg msg = {g_testAudioType, TESTREGISTERDSP, -1};
+ EXPECT_EQ(0, HdfTestSendMsgToService(&msg));
+}
+
+HWTEST_F(AudioCoreTest, AudioCoreTest_SocDeviceRegister, TestSize.Level0)
+{
+ struct HdfTestMsg msg = {g_testAudioType, TESTSOCDEVICEREGISTER, -1};
+ EXPECT_EQ(0, HdfTestSendMsgToService(&msg));
+}
+
+HWTEST_F(AudioCoreTest, AudioCoreTest_BindDaiLink, TestSize.Level0)
+{
+ struct HdfTestMsg msg = {g_testAudioType, TESTBINDDAILINK, -1};
+ EXPECT_EQ(0, HdfTestSendMsgToService(&msg));
+}
+
+HWTEST_F(AudioCoreTest, AudioCoreTest_UpdateCodecRegBits, TestSize.Level0)
+{
+ struct HdfTestMsg msg = {g_testAudioType, TESTUPDATECODECREGBITS, -1};
+ EXPECT_EQ(0, HdfTestSendMsgToService(&msg));
+}
+
+HWTEST_F(AudioCoreTest, AudioCoreTest_UpdateAccessoryRegBits, TestSize.Level0)
+{
+ struct HdfTestMsg msg = {g_testAudioType, TESTUPDATEACCESSORYREGBITS, -1};
+ EXPECT_EQ(0, HdfTestSendMsgToService(&msg));
+}
+
+HWTEST_F(AudioCoreTest, AudioCoreTest_UpdateCodecAiaoRegBits, TestSize.Level0)
+{
+ struct HdfTestMsg msg = {g_testAudioType, TESTUPDATECODECAIAOREGBITS, -1};
+ EXPECT_EQ(0, HdfTestSendMsgToService(&msg));
+}
+
+HWTEST_F(AudioCoreTest, AudioCoreTest_UpdateAccessoryAiaoRegBits, TestSize.Level0)
+{
+ struct HdfTestMsg msg = {g_testAudioType, TESTUPDATEACCESSORYAIAOREGBITS, -1};
+ EXPECT_EQ(0, HdfTestSendMsgToService(&msg));
+}
+
+HWTEST_F(AudioCoreTest, AudioCoreTest_KcontrolGetCodec, TestSize.Level0)
+{
+ struct HdfTestMsg msg = {g_testAudioType, TESTKCONTROLGETCODEC, -1};
+ EXPECT_EQ(0, HdfTestSendMsgToService(&msg));
+}
+
+HWTEST_F(AudioCoreTest, AudioCoreTest_KcontrolGetAccessory, TestSize.Level0)
+{
+ struct HdfTestMsg msg = {g_testAudioType, TESTKCONTROLGETACCESSORY, -1};
+ EXPECT_EQ(0, HdfTestSendMsgToService(&msg));
+}
+
+HWTEST_F(AudioCoreTest, AudioCoreTest_AddControl, TestSize.Level0)
+{
+ struct HdfTestMsg msg = {g_testAudioType, TESTADDCONTROL, -1};
+ EXPECT_EQ(0, HdfTestSendMsgToService(&msg));
+}
+
+HWTEST_F(AudioCoreTest, AudioCoreTest_AddControls, TestSize.Level0)
+{
+ struct HdfTestMsg msg = {g_testAudioType, TESTADDCONTROLS, -1};
+ EXPECT_EQ(0, HdfTestSendMsgToService(&msg));
+}
+
+HWTEST_F(AudioCoreTest, AudioCoreTest_CodecReadReg, TestSize.Level0)
+{
+ struct HdfTestMsg msg = {g_testAudioType, TESTCODECREADREG, -1};
+ EXPECT_EQ(0, HdfTestSendMsgToService(&msg));
+}
+
+HWTEST_F(AudioCoreTest, AudioCoreTest_AccessoryReadReg, TestSize.Level0)
+{
+ struct HdfTestMsg msg = {g_testAudioType, TESTACCESSORYREADREG, -1};
+ EXPECT_EQ(0, HdfTestSendMsgToService(&msg));
+}
+
+HWTEST_F(AudioCoreTest, AudioCoreTest_CodecAiaoReadReg, TestSize.Level0)
+{
+ struct HdfTestMsg msg = {g_testAudioType, TESTCODECAIAOREADREG, -1};
+ EXPECT_EQ(0, HdfTestSendMsgToService(&msg));
+}
+
+HWTEST_F(AudioCoreTest, AudioCoreTest_AccessoryAiaoReadReg, TestSize.Level0)
+{
+ struct HdfTestMsg msg = {g_testAudioType, TESTACCESSORYAIAOREADREG, -1};
+ EXPECT_EQ(0, HdfTestSendMsgToService(&msg));
+}
+
+HWTEST_F(AudioCoreTest, AudioCoreTest_CodecWriteReg, TestSize.Level0)
+{
+ struct HdfTestMsg msg = {g_testAudioType, TESTCODECWRITEREG, -1};
+ EXPECT_EQ(0, HdfTestSendMsgToService(&msg));
+}
+
+HWTEST_F(AudioCoreTest, AudioCoreTest_AccessoryWriteReg, TestSize.Level0)
+{
+ struct HdfTestMsg msg = {g_testAudioType, TESTACCESSORYWRITEREG, -1};
+ EXPECT_EQ(0, HdfTestSendMsgToService(&msg));
+}
+
+HWTEST_F(AudioCoreTest, AudioCoreTest_CodecAiaoWriteReg, TestSize.Level0)
+{
+ struct HdfTestMsg msg = {g_testAudioType, TESTCODECAIAOWRITEREG, -1};
+ EXPECT_EQ(0, HdfTestSendMsgToService(&msg));
+}
+
+HWTEST_F(AudioCoreTest, AudioCoreTest_AccessoryAiaoWriteReg, TestSize.Level0)
+{
+ struct HdfTestMsg msg = {g_testAudioType, TESTACCESSORYAIAOWRITEREG, -1};
+ EXPECT_EQ(0, HdfTestSendMsgToService(&msg));
+}
+
+HWTEST_F(AudioCoreTest, AudioCoreTest_InfoCtrlOps, TestSize.Level0)
+{
+ struct HdfTestMsg msg = {g_testAudioType, TESTINFOCTRLOPS, -1};
+ EXPECT_EQ(0, HdfTestSendMsgToService(&msg));
+}
+
+HWTEST_F(AudioCoreTest, AudioCoreTest_CodecGetCtrlOps, TestSize.Level0)
+{
+ struct HdfTestMsg msg = {g_testAudioType, TESTCODECGETCTRLOPS, -1};
+ EXPECT_EQ(0, HdfTestSendMsgToService(&msg));
+}
+
+HWTEST_F(AudioCoreTest, AudioCoreTest_AccessoryGetCtrlOps, TestSize.Level0)
+{
+ struct HdfTestMsg msg = {g_testAudioType, TESTACCESSORYGETCTRLOPS, -1};
+ EXPECT_EQ(0, HdfTestSendMsgToService(&msg));
+}
+
+HWTEST_F(AudioCoreTest, AudioCoreTest_CodecAiaoGetCtrlOps, TestSize.Level0)
+{
+ struct HdfTestMsg msg = {g_testAudioType, TESTCODECAIAOGETCTRLOPS, -1};
+ EXPECT_EQ(0, HdfTestSendMsgToService(&msg));
+}
+
+HWTEST_F(AudioCoreTest, AudioCoreTest_AccessoryAiaoGetCtrlOps, TestSize.Level0)
+{
+ struct HdfTestMsg msg = {g_testAudioType, TESTACCESSORYAIAOGETCTRLOPS, -1};
+ EXPECT_EQ(0, HdfTestSendMsgToService(&msg));
+}
+
+HWTEST_F(AudioCoreTest, AudioCoreTest_CodecSetCtrlOps, TestSize.Level0)
+{
+ struct HdfTestMsg msg = {g_testAudioType, TESTCODECSETCTRLOPS, -1};
+ EXPECT_EQ(0, HdfTestSendMsgToService(&msg));
+}
+
+HWTEST_F(AudioCoreTest, AudioCoreTest_AccessorySetCtrlOps, TestSize.Level0)
+{
+ struct HdfTestMsg msg = {g_testAudioType, TESTACCESSORYSETCTRLOPS, -1};
+ EXPECT_EQ(0, HdfTestSendMsgToService(&msg));
+}
+
+HWTEST_F(AudioCoreTest, AudioCoreTest_CodecAiaoSetCtrlOps, TestSize.Level0)
+{
+ struct HdfTestMsg msg = {g_testAudioType, TESTCODECAIAOSETCTRLOPS, -1};
+ EXPECT_EQ(0, HdfTestSendMsgToService(&msg));
+}
+
+HWTEST_F(AudioCoreTest, AudioCoreTest_AccessoryAiaoSetCtrlOps, TestSize.Level0)
+{
+ struct HdfTestMsg msg = {g_testAudioType, TESTACCESSORYAIAOSETCTRLOPS, -1};
+ EXPECT_EQ(0, HdfTestSendMsgToService(&msg));
+}
+}
diff --git a/model/audio/core/test/unittest/common/audio_host_test.cpp b/model/audio/core/test/unittest/common/audio_host_test.cpp
new file mode 100755
index 0000000000000000000000000000000000000000..6632edb9a58cdf3e970428e231f97aa59db8e79b
--- /dev/null
+++ b/model/audio/core/test/unittest/common/audio_host_test.cpp
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 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 "audio_common_test.h"
+#include
+#include "hdf_uhdf_test.h"
+
+using namespace testing::ext;
+
+namespace {
+class AudioHostTest : public testing::Test {
+public:
+ static void SetUpTestCase();
+ static void TearDownTestCase();
+ void SetUp();
+ void TearDown();
+};
+
+void AudioHostTest::SetUpTestCase()
+{
+ HdfTestOpenService();
+}
+
+void AudioHostTest::TearDownTestCase()
+{
+ HdfTestCloseService();
+}
+
+void AudioHostTest::SetUp()
+{
+}
+
+void AudioHostTest::TearDown()
+{
+}
+
+HWTEST_F(AudioHostTest, AudioHostTest_GetCodec, TestSize.Level0)
+{
+ struct HdfTestMsg msg = {g_testAudioType, TESTGETCODEC, -1};
+ EXPECT_EQ(0, HdfTestSendMsgToService(&msg));
+}
+
+HWTEST_F(AudioHostTest, AudioHostTest_GetAudioServiceName, TestSize.Level0)
+{
+ struct HdfTestMsg msg = {g_testAudioType, TESTGETCARDINSTANCE, -1};
+ EXPECT_EQ(0, HdfTestSendMsgToService(&msg));
+}
+}
diff --git a/model/audio/core/test/unittest/common/audio_parse_test.cpp b/model/audio/core/test/unittest/common/audio_parse_test.cpp
new file mode 100755
index 0000000000000000000000000000000000000000..6b612d03a797fdd6e9103be128b94b2df82c223d
--- /dev/null
+++ b/model/audio/core/test/unittest/common/audio_parse_test.cpp
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 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 "audio_common_test.h"
+#include
+#include "hdf_uhdf_test.h"
+
+using namespace testing::ext;
+
+namespace {
+class AudioParseTest : public testing::Test {
+public:
+ static void SetUpTestCase();
+ static void TearDownTestCase();
+ void SetUp();
+ void TearDown();
+};
+
+void AudioParseTest::SetUpTestCase()
+{
+ HdfTestOpenService();
+}
+
+void AudioParseTest::TearDownTestCase()
+{
+ HdfTestCloseService();
+}
+
+void AudioParseTest::SetUp()
+{
+}
+
+void AudioParseTest::TearDown()
+{
+}
+
+HWTEST_F(AudioParseTest, AudioParseTest_GetConfigData, TestSize.Level0)
+{
+ struct HdfTestMsg msg = {g_testAudioType, TESTGETCCNFIGDATA, -1};
+ EXPECT_EQ(0, HdfTestSendMsgToService(&msg));
+}
+}
diff --git a/model/audio/dispatch/include/audio_control_dispatch.h b/model/audio/dispatch/include/audio_control_dispatch.h
new file mode 100755
index 0000000000000000000000000000000000000000..2d3959316440652bb4535aceb4148b08efbd817b
--- /dev/null
+++ b/model/audio/dispatch/include/audio_control_dispatch.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 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 AUDIO_CONTROL_DISPATCH_H
+#define AUDIO_CONTROL_DISPATCH_H
+
+#include "audio_host.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif
+#endif /* __cplusplus */
+
+
+#define AUDIODRV_CTRL_ELEM_TYPE_INTEGER 2 /* integer type */
+
+enum ControlDispMethodCmd {
+ AUDIODRV_CTRL_IOCTRL_ELEM_INFO,
+ AUDIODRV_CTRL_IOCTRL_ELEM_READ,
+ AUDIODRV_CTRL_IOCTRL_ELEM_WRITE,
+ AUDIODRV_CTRL_IOCTRL_ELEM_BUTT,
+};
+
+typedef int32_t (*ControlDispCmdHandle)(const struct HdfDeviceIoClient *client,
+ struct HdfSBuf *data, struct HdfSBuf *reply);
+
+struct ControlDispCmdHandleList {
+ enum ControlDispMethodCmd cmd;
+ ControlDispCmdHandle func;
+};
+
+struct ControlHost {
+ struct IDeviceIoService service;
+ struct HdfDeviceObject *device;
+ void *priv;
+};
+
+static inline struct ControlHost *ControlHostFromDevice(struct HdfDeviceObject *device)
+{
+ return (device == NULL) ? NULL : (struct ControlHost *)device->service;
+}
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif
+#endif /* __cplusplus */
+
+#endif /* AUDIO_CONTROL_H */
diff --git a/model/audio/dispatch/include/audio_stream_dispatch.h b/model/audio/dispatch/include/audio_stream_dispatch.h
new file mode 100755
index 0000000000000000000000000000000000000000..b1d4c75298ce9c17b8c283327d1a278eab08c955
--- /dev/null
+++ b/model/audio/dispatch/include/audio_stream_dispatch.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 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 AUDIO_STREAM_DISP_H
+#define AUDIO_STREAM_DISP_H
+
+#include "audio_host.h"
+#include "audio_codec_if.h"
+#include "audio_platform_if.h"
+#include "audio_dai_if.h"
+#include "audio_dsp_if.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif
+#endif /* __cplusplus */
+
+#define AUDIO_SERVICE_NAME_MAX_LEN 32
+
+enum StreamDispMethodCmd {
+ AUDIO_DRV_PCM_IOCTRL_HW_PARAMS,
+ AUDIO_DRV_PCM_IOCTRL_RENDER_PREPARE,
+ AUDIO_DRV_PCM_IOCTRL_CAPTURE_PREPARE,
+ AUDIO_DRV_PCM_IOCTRL_WRITE,
+ AUDIO_DRV_PCM_IOCTRL_READ,
+ AUDIO_DRV_PCM_IOCTRL_RENDER_START,
+ AUDIO_DRV_PCM_IOCTRL_RENDER_STOP,
+ AUDIO_DRV_PCM_IOCTRL_CAPTURE_START,
+ AUDIO_DRV_PCM_IOCTRL_CAPTURE_STOP,
+ AUDIO_DRV_PCM_IOCTRL_RENDER_PAUSE,
+ AUDIO_DRV_PCM_IOCTRL_CAPTURE_PAUSE,
+ AUDIO_DRV_PCM_IOCTRL_RENDER_RESUME,
+ AUDIO_DRV_PCM_IOCTRL_CAPTURE_RESUME,
+ AUDIO_DRV_PCM_IOCTL_MMAP_BUFFER,
+ AUDIO_DRV_PCM_IOCTL_MMAP_BUFFER_CAPTURE,
+ AUDIO_DRV_PCM_IOCTL_MMAP_POSITION,
+ AUDIO_DRV_PCM_IOCTL_MMAP_POSITION_CAPTURE,
+ AUDIO_DRV_PCM_IOCTRL_DSP_DECODE,
+ AUDIO_DRV_PCM_IOCTRL_DSP_ENCODE,
+ AUDIO_DRV_PCM_IOCTRL_DSP_EQUALIZER,
+ AUDIO_DRV_PCM_IOCTRL_BUTT,
+};
+
+typedef int32_t (*StreamDispCmdHandle)(const struct HdfDeviceIoClient *client,
+ struct HdfSBuf *data, struct HdfSBuf *reply);
+
+struct StreamDispCmdHandleList {
+ enum StreamDispMethodCmd cmd;
+ StreamDispCmdHandle func;
+};
+
+struct StreamHost {
+ struct IDeviceIoService service;
+ struct HdfDeviceObject *device;
+ void *priv;
+};
+
+static inline struct StreamHost *StreamHostFromDevice(struct HdfDeviceObject *device)
+{
+ return (device == NULL) ? NULL : (struct StreamHost *)device->service;
+}
+
+int32_t StreamDispatch(struct HdfDeviceIoClient *client, int cmdId,
+ struct HdfSBuf *data, struct HdfSBuf *reply);
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif
+#endif /* __cplusplus */
+
+#endif /* AUDIO_STREAM_DISP_H */
diff --git a/model/audio/dispatch/src/audio_control_dispatch.c b/model/audio/dispatch/src/audio_control_dispatch.c
new file mode 100755
index 0000000000000000000000000000000000000000..082e66a35ae88f92ddd44a396ea079d8ba27ce12
--- /dev/null
+++ b/model/audio/dispatch/src/audio_control_dispatch.c
@@ -0,0 +1,329 @@
+/*
+ * Copyright (c) 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 "audio_control_dispatch.h"
+#include "audio_control.h"
+
+#define HDF_LOG_TAG audio_control_dispatch
+
+static struct AudioKcontrol *AudioGetKctrlInstance(const struct AudioCtrlElemId *ctrlElemId)
+{
+ struct AudioKcontrol *kctrl = NULL;
+ struct AudioCard *audioCard = NULL;
+
+ if (ctrlElemId == NULL || ctrlElemId->itemName == NULL || ctrlElemId->cardServiceName == NULL) {
+ ADM_LOG_ERR("input params check error: ctrlElemId is NULL.");
+ return NULL;
+ }
+
+ audioCard = GetCardInstance(ctrlElemId->cardServiceName);
+ if (audioCard == NULL) {
+ ADM_LOG_ERR("get kcontrol instance fail!");
+ return NULL;
+ }
+
+ DLIST_FOR_EACH_ENTRY(kctrl, &audioCard->controls, struct AudioKcontrol, list) {
+ if (kctrl->name == NULL) {
+ continue;
+ }
+ if (strcmp(kctrl->name, ctrlElemId->itemName) != 0) {
+ continue;
+ }
+ if (kctrl->iface != ctrlElemId->iface) {
+ continue;
+ }
+ return kctrl;
+ }
+ return NULL;
+}
+
+static int32_t ControlHostElemInfoSub(struct HdfSBuf *rspData, const struct AudioCtrlElemId id)
+{
+ int32_t result;
+ struct AudioKcontrol *kctrl = NULL;
+ struct AudioCtrlElemInfo elemInfo;
+ if (rspData == NULL) {
+ ADM_LOG_ERR("Input rspData is null.");
+ return HDF_FAILURE;
+ }
+ kctrl = AudioGetKctrlInstance(&id);
+ if (kctrl == NULL || kctrl->Info == NULL) {
+ ADM_LOG_ERR("Find kctrl or Info fail!");
+ return HDF_FAILURE;
+ }
+
+ (void)memset_s(&elemInfo, sizeof(struct AudioCtrlElemInfo), 0, sizeof(struct AudioCtrlElemInfo));
+ result = kctrl->Info(kctrl, &elemInfo);
+ if (result != HDF_SUCCESS) {
+ ADM_LOG_ERR("Get control info fail result=%d", result);
+ return HDF_FAILURE;
+ }
+
+ if (!HdfSbufWriteInt32(rspData, elemInfo.type)) {
+ ADM_LOG_ERR("Write response data type failed!");
+ return HDF_FAILURE;
+ }
+ if (!HdfSbufWriteInt32(rspData, elemInfo.max)) {
+ ADM_LOG_ERR("Write response data max failed!");
+ return HDF_FAILURE;
+ }
+ if (!HdfSbufWriteInt32(rspData, elemInfo.min)) {
+ ADM_LOG_ERR("Write response data min failed!");
+ return HDF_FAILURE;
+ }
+ if (!HdfSbufWriteUint32(rspData, elemInfo.count)) {
+ ADM_LOG_ERR("Write response data count failed!");
+ return HDF_FAILURE;
+ }
+ ADM_LOG_DEBUG("success.");
+ return HDF_SUCCESS;
+}
+
+static int32_t ControlHostElemInfo(const struct HdfDeviceIoClient *client,
+ struct HdfSBuf *reqData, struct HdfSBuf *rspData)
+{
+ struct AudioCtrlElemId id;
+ ADM_LOG_DEBUG("entry.");
+
+ if ((client == NULL) || (reqData == NULL)) {
+ ADM_LOG_ERR("Input ElemInfo params check error: client=%p, reqData=%p.", client, reqData);
+ return HDF_FAILURE;
+ }
+
+ (void)memset_s(&id, sizeof(struct AudioCtrlElemId), 0, sizeof(struct AudioCtrlElemId));
+ if (!HdfSbufReadInt32(reqData, &id.iface)) {
+ ADM_LOG_ERR("Read ElemInfo request id failed!");
+ return HDF_FAILURE;
+ }
+
+ if (!(id.cardServiceName = HdfSbufReadString(reqData))) {
+ ADM_LOG_ERR("Read ElemInfo request cardServiceName failed!");
+ return HDF_FAILURE;
+ }
+
+ if (!(id.itemName = HdfSbufReadString(reqData))) {
+ ADM_LOG_ERR("Read ElemInfo request itemName failed!");
+ return HDF_FAILURE;
+ }
+
+ if (ControlHostElemInfoSub(rspData, id)) {
+ ADM_LOG_ERR("ControlHostElemInfoSub failed!");
+ return HDF_FAILURE;
+ }
+
+ return HDF_SUCCESS;
+}
+
+static int32_t ControlHostElemRead(const struct HdfDeviceIoClient *client, struct HdfSBuf *reqData,
+ struct HdfSBuf *rspData)
+{
+ struct AudioKcontrol *kctrl = NULL;
+ struct AudioCtrlElemValue elemValue;
+ struct AudioCtrlElemId id;
+ int32_t result;
+ ADM_LOG_DEBUG("entry.");
+
+ if ((client == NULL) || (reqData == NULL) || (rspData == NULL)) {
+ ADM_LOG_ERR("Input ElemRead params check error: client=%p, reqData=%p, rspData=%p.", client, reqData, rspData);
+ return HDF_FAILURE;
+ }
+
+ (void)memset_s(&id, sizeof(struct AudioCtrlElemId), 0, sizeof(struct AudioCtrlElemId));
+ if (!HdfSbufReadInt32(reqData, &id.iface)) {
+ ADM_LOG_ERR("ElemRead request id failed!");
+ return HDF_FAILURE;
+ }
+
+ if (!(id.cardServiceName = HdfSbufReadString(reqData))) {
+ ADM_LOG_ERR("ElemRead request cardServiceName failed!");
+ return HDF_FAILURE;
+ }
+
+ if (!(id.itemName = HdfSbufReadString(reqData))) {
+ ADM_LOG_ERR("ElemRead request itemName failed!");
+ return HDF_FAILURE;
+ }
+
+ kctrl = AudioGetKctrlInstance(&id);
+ if (kctrl == NULL || kctrl->Get == NULL) {
+ ADM_LOG_ERR("Find kctrl or Get fail.");
+ return HDF_FAILURE;
+ }
+
+ (void)memset_s(&elemValue, sizeof(struct AudioCtrlElemValue), 0, sizeof(struct AudioCtrlElemValue));
+ result = kctrl->Get(kctrl, &elemValue);
+ if (result != HDF_SUCCESS) {
+ ADM_LOG_ERR("Get elemValue fail result=%d", result);
+ return HDF_FAILURE;
+ }
+
+ if (!HdfSbufWriteInt32(rspData, elemValue.value[0])) {
+ ADM_LOG_ERR("Write response data value[0]=%d failed!", elemValue.value[0]);
+ return HDF_FAILURE;
+ }
+ if (!HdfSbufWriteInt32(rspData, elemValue.value[1])) {
+ ADM_LOG_ERR("Write response data value[1]=%d failed!", elemValue.value[1]);
+ return HDF_FAILURE;
+ }
+ ADM_LOG_DEBUG("success.");
+ return HDF_SUCCESS;
+}
+
+static int32_t ControlHostElemWrite(const struct HdfDeviceIoClient *client,
+ struct HdfSBuf *reqData, struct HdfSBuf *rspData)
+{
+ struct AudioKcontrol *kctrl = NULL;
+ struct AudioCtrlElemValue elemValue;
+ int32_t result;
+ ADM_LOG_DEBUG("entry.");
+
+ if ((client == NULL) || (reqData == NULL)) {
+ ADM_LOG_ERR("Input params check error: client=%p, reqData=%p.", client, reqData);
+ return HDF_FAILURE;
+ }
+ (void)rspData;
+
+ (void)memset_s(&elemValue, sizeof(struct AudioCtrlElemValue), 0, sizeof(struct AudioCtrlElemValue));
+ if (!HdfSbufReadInt32(reqData, &elemValue.value[0])) {
+ ADM_LOG_ERR("Read request elemValue failed!");
+ return HDF_FAILURE;
+ }
+
+ if (!HdfSbufReadInt32(reqData, &elemValue.id.iface)) {
+ ADM_LOG_ERR("Read request id failed!");
+ return HDF_FAILURE;
+ }
+
+ if (!(elemValue.id.cardServiceName = HdfSbufReadString(reqData))) {
+ ADM_LOG_ERR("Read request cardServiceName failed!");
+ return HDF_FAILURE;
+ }
+
+ if (!(elemValue.id.itemName = HdfSbufReadString(reqData))) {
+ ADM_LOG_ERR("Read request itemName failed!");
+ return HDF_FAILURE;
+ }
+
+ kctrl = AudioGetKctrlInstance(&elemValue.id);
+ if (kctrl == NULL || kctrl->Set == NULL) {
+ ADM_LOG_ERR("Find kctrl or Set fail!");
+ return HDF_FAILURE;
+ }
+
+ result = kctrl->Set(kctrl, &elemValue);
+ if (result != HDF_SUCCESS) {
+ ADM_LOG_ERR("Get control value fail result=%d", result);
+ return HDF_FAILURE;
+ }
+ ADM_LOG_DEBUG("success.");
+ return HDF_SUCCESS;
+}
+
+static struct ControlDispCmdHandleList g_controlDispCmdHandle[] = {
+ {AUDIODRV_CTRL_IOCTRL_ELEM_INFO, ControlHostElemInfo},
+ {AUDIODRV_CTRL_IOCTRL_ELEM_READ, ControlHostElemRead},
+ {AUDIODRV_CTRL_IOCTRL_ELEM_WRITE, ControlHostElemWrite},
+};
+
+static int32_t ControlDispatch(struct HdfDeviceIoClient *client, int cmdId,
+ struct HdfSBuf *data, struct HdfSBuf *reply)
+{
+ unsigned int i;
+
+ if ((client == NULL) || (data == NULL)) {
+ ADM_LOG_ERR("Input params check error: client=%p, data=%p.", client, data);
+ return HDF_FAILURE;
+ }
+
+ if (cmdId >= AUDIODRV_CTRL_IOCTRL_ELEM_BUTT || cmdId < 0) {
+ ADM_LOG_ERR("Invalid [cmdId=%d].", cmdId);
+ return HDF_FAILURE;
+ }
+
+ for (i = 0; i < HDF_ARRAY_SIZE(g_controlDispCmdHandle); ++i) {
+ if ((cmdId == (int)(g_controlDispCmdHandle[i].cmd)) && (g_controlDispCmdHandle[i].func != NULL)) {
+ return g_controlDispCmdHandle[i].func(client, data, reply);
+ }
+ }
+ return HDF_FAILURE;
+}
+
+static struct ControlHost *ControlHostCreateAndBind(struct HdfDeviceObject *device)
+{
+ struct ControlHost *controlHost = NULL;
+
+ if (device == NULL) {
+ ADM_LOG_ERR("Input params check error: device is NULL.");
+ return NULL;
+ }
+
+ controlHost = (struct ControlHost *)OsalMemCalloc(sizeof(*controlHost));
+ if (controlHost == NULL) {
+ ADM_LOG_ERR("Malloc controlHost fail!");
+ return NULL;
+ }
+ controlHost->device = device;
+ device->service = &controlHost->service;
+ return controlHost;
+}
+
+static int32_t AudioControlBind(struct HdfDeviceObject *device)
+{
+ struct ControlHost *controlHost = NULL;
+ ADM_LOG_DEBUG("entry.");
+
+ if (device == NULL) {
+ ADM_LOG_ERR("Input params check error: device is NULL.");
+ return HDF_FAILURE;
+ }
+
+ controlHost = ControlHostCreateAndBind(device);
+ if (controlHost == NULL) {
+ ADM_LOG_ERR("controlHost is NULL.");
+ return HDF_FAILURE;
+ }
+
+ controlHost->service.Dispatch = ControlDispatch;
+
+ ADM_LOG_INFO("success.");
+ return HDF_SUCCESS;
+}
+
+static int32_t AudioControlInit(struct HdfDeviceObject *device)
+{
+ (void)device;
+ ADM_LOG_INFO("success.");
+ return HDF_SUCCESS;
+}
+
+static void AudioControlRelease(struct HdfDeviceObject *device)
+{
+ struct ControlHost *controlHost = NULL;
+
+ if (device == NULL) {
+ ADM_LOG_ERR("Input params check error: device is NULL.");
+ return;
+ }
+
+ controlHost = ControlHostFromDevice(device);
+ if (controlHost == NULL) {
+ ADM_LOG_ERR("controlHost is NULL.");
+ return;
+ }
+ OsalMemFree(controlHost);
+}
+
+/* HdfDriverEntry definitions */
+struct HdfDriverEntry g_audioControlEntry = {
+ .moduleVersion = 1,
+ .moduleName = "HDF_AUDIO_CONTROL",
+ .Bind = AudioControlBind,
+ .Init = AudioControlInit,
+ .Release = AudioControlRelease,
+};
+HDF_INIT(g_audioControlEntry);
diff --git a/model/audio/dispatch/src/audio_stream_dispatch.c b/model/audio/dispatch/src/audio_stream_dispatch.c
new file mode 100755
index 0000000000000000000000000000000000000000..0bb697ed63469f763b45700488164273b05702bf
--- /dev/null
+++ b/model/audio/dispatch/src/audio_stream_dispatch.c
@@ -0,0 +1,1262 @@
+/*
+ * Copyright (c) 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 "audio_stream_dispatch.h"
+
+#define HDF_LOG_TAG audio_stream_dispatch
+
+int32_t HwCpuDaiDispatch(const struct AudioCard *audioCard, const struct AudioPcmHwParams *params)
+{
+ if ((audioCard == NULL) || (params == NULL)) {
+ ADM_LOG_ERR("CpuDai input param is NULL.");
+ return HDF_FAILURE;
+ }
+
+ struct AudioRuntimeDeivces *rtd = audioCard->rtd;
+ if (rtd == NULL) {
+ ADM_LOG_ERR("CpuDai audioCard rtd is NULL.");
+ return HDF_FAILURE;
+ }
+
+ struct DaiDevice *cpuDai = rtd->cpuDai;
+ if (cpuDai == NULL || cpuDai->devData == NULL || cpuDai->devData->ops == NULL) {
+ ADM_LOG_ERR("cpuDai param is NULL.");
+ return HDF_FAILURE;
+ }
+
+ /* If there are HwParams function, it will be executed directly.
+ * If not, skip the if statement and execute in sequence.
+ */
+ if (cpuDai->devData->ops->HwParams != NULL) {
+ int ret = cpuDai->devData->ops->HwParams(audioCard, params, cpuDai);
+ if (ret < 0) {
+ ADM_LOG_ERR("cpuDai hardware params fail ret=%d", ret);
+ return HDF_ERR_IO;
+ }
+ }
+
+ return HDF_SUCCESS;
+}
+
+int32_t HwCodecDaiDispatch(const struct AudioCard *audioCard, const struct AudioPcmHwParams *params)
+{
+ if ((audioCard == NULL) || (params == NULL)) {
+ ADM_LOG_ERR("CodecDai input param is NULL.");
+ return HDF_FAILURE;
+ }
+
+ struct AudioRuntimeDeivces *rtd = audioCard->rtd;
+ if (rtd == NULL) {
+ ADM_LOG_ERR("CodecDai audioCard rtd is NULL.");
+ return HDF_FAILURE;
+ }
+ struct DaiDevice *codecDai = rtd->codecDai;
+ if (codecDai == NULL) {
+ codecDai = rtd->accessoryDai;
+ }
+ if (codecDai == NULL || codecDai->devData == NULL || codecDai->devData->ops == NULL) {
+ ADM_LOG_ERR("codecDai param is NULL.");
+ return HDF_FAILURE;
+ }
+
+ /* If there are HwParams function, it will be executed directly.
+ * If not, skip the if statement and execute in sequence.
+ */
+ if (codecDai->devData->ops->HwParams != NULL) {
+ int ret = codecDai->devData->ops->HwParams(audioCard, params, codecDai);
+ if (ret < 0) {
+ ADM_LOG_ERR("codecDai hardware params fail ret=%d", ret);
+ return HDF_ERR_IO;
+ }
+ }
+
+ return HDF_SUCCESS;
+}
+
+int32_t HwPlatfromDispatch(const struct AudioCard *audioCard, const struct AudioPcmHwParams *params)
+{
+ if ((audioCard == NULL) || (params == NULL)) {
+ ADM_LOG_ERR("Platfrom input param is NULL.");
+ return HDF_FAILURE;
+ }
+
+ struct AudioRuntimeDeivces *rtd = audioCard->rtd;
+ if (rtd == NULL) {
+ ADM_LOG_ERR("audioCard rtd is NULL.");
+ return HDF_FAILURE;
+ }
+
+ struct PlatformDevice *platform = rtd->platform;
+ if (platform == NULL || platform->devData == NULL || platform->devData->ops == NULL) {
+ ADM_LOG_ERR("platform param is NULL.");
+ return HDF_FAILURE;
+ }
+
+ /* If there are HwParams function, it will be executed directly.
+ * If not, skip the if statement and execute in sequence.
+ */
+ if (platform->devData->ops->HwParams != NULL) {
+ int ret = platform->devData->ops->HwParams(audioCard, params);
+ if (ret < 0) {
+ ADM_LOG_ERR("platform hardware params fail ret=%d", ret);
+ return HDF_ERR_IO;
+ }
+ }
+
+ return HDF_SUCCESS;
+}
+
+int32_t HwParamsDispatch(const struct AudioCard *audioCard, const struct AudioPcmHwParams *params)
+{
+ if ((audioCard == NULL) || (params == NULL)) {
+ ADM_LOG_ERR("input param is NULL.");
+ return HDF_FAILURE;
+ }
+
+ /* Traverse through each driver method; Enter if you have, if not, exectue in order */
+ if (HwCodecDaiDispatch(audioCard, params) ||
+ HwCpuDaiDispatch(audioCard, params) ||
+ HwPlatfromDispatch(audioCard, params)) {
+ ADM_LOG_ERR("hardware params fail.");
+ return HDF_FAILURE;
+ }
+ return HDF_SUCCESS;
+}
+
+static int32_t HwParamsDataAnalysis(struct HdfSBuf *reqData, struct AudioPcmHwParams *params)
+{
+ if ((reqData == NULL) || (params == NULL)) {
+ ADM_LOG_ERR(" input param is NULL.");
+ return HDF_FAILURE;
+ }
+
+ if (!HdfSbufReadUint32(reqData, ¶ms->streamType)) {
+ ADM_LOG_ERR("read request streamType failed!");
+ return HDF_FAILURE;
+ }
+ if (!HdfSbufReadUint32(reqData, ¶ms->channels)) {
+ ADM_LOG_ERR("read request channels failed!");
+ return HDF_FAILURE;
+ }
+ if (!HdfSbufReadUint32(reqData, ¶ms->rate)) {
+ ADM_LOG_ERR("read request rate failed!");
+ return HDF_FAILURE;
+ }
+ if (!HdfSbufReadUint32(reqData, ¶ms->periodSize)) {
+ ADM_LOG_ERR("read request periodSize failed!");
+ return HDF_FAILURE;
+ }
+ if (!HdfSbufReadUint32(reqData, ¶ms->periodCount)) {
+ ADM_LOG_ERR("read request periodCount failed!");
+ return HDF_FAILURE;
+ }
+ if (!HdfSbufReadUint32(reqData, (uint32_t *)¶ms->format)) {
+ ADM_LOG_ERR("read request format failed!");
+ return HDF_FAILURE;
+ }
+ if (!(params->cardServiceName = HdfSbufReadString(reqData))) {
+ ADM_LOG_ERR("read request cardServiceName failed!");
+ return HDF_FAILURE;
+ }
+ if (!HdfSbufReadUint32(reqData, ¶ms->period)) {
+ HDF_LOGE("read request perid failed!");
+ return HDF_FAILURE;
+ }
+
+ if (!HdfSbufReadUint32(reqData, ¶ms->frameSize)) {
+ HDF_LOGE("read request frameSize failed!");
+ return HDF_FAILURE;
+ }
+
+ if (!HdfSbufReadUint32(reqData, (uint32_t *)¶ms->isBigEndian)) {
+ HDF_LOGE("read request isBigEndian failed!");
+ return HDF_FAILURE;
+ }
+
+ if (!HdfSbufReadUint32(reqData, (uint32_t *)¶ms->isSignedData)) {
+ HDF_LOGE("read request isSignedData failed!");
+ return HDF_FAILURE;
+ }
+
+ if (!HdfSbufReadUint32(reqData, ¶ms->startThreshold)) {
+ HDF_LOGE("read request startThreshold failed!");
+ return HDF_FAILURE;
+ }
+
+ if (!HdfSbufReadUint32(reqData, ¶ms->stopThreshold)) {
+ HDF_LOGE("read request stopThreshold failed!");
+ return HDF_FAILURE;
+ }
+
+ if (!HdfSbufReadUint32(reqData, ¶ms->silenceThreshold)) {
+ HDF_LOGE("read request silenceThreshold failed!");
+ return HDF_FAILURE;
+ }
+
+ return HDF_SUCCESS;
+}
+
+int32_t StreamHostHwParams(const struct HdfDeviceIoClient *client, struct HdfSBuf *data,
+ struct HdfSBuf *reply)
+{
+ struct AudioPcmHwParams params;
+ struct StreamHost *streamHost = NULL;
+ struct AudioCard *audioCard = NULL;
+ char *cardName = NULL;
+ int ret = HDF_SUCCESS;
+ ADM_LOG_DEBUG("entry.");
+
+ if ((client == NULL || client->device == NULL) || (data == NULL)) {
+ ADM_LOG_ERR("input param is NULL.");
+ return HDF_FAILURE;
+ }
+ (void)reply;
+
+ streamHost = StreamHostFromDevice(client->device);
+ if (streamHost == NULL) {
+ ADM_LOG_ERR("renderHost is NULL");
+ return HDF_FAILURE;
+ }
+
+ cardName = (char *)OsalMemCalloc(sizeof(char) * BUFF_SIZE_MAX);
+ if (cardName == NULL) {
+ ADM_LOG_ERR("malloc cardServiceName fail!");
+ return HDF_FAILURE;
+ }
+ streamHost->priv = cardName;
+
+ (void)memset_s(¶ms, sizeof(struct AudioPcmHwParams), 0, sizeof(struct AudioPcmHwParams));
+ ret = HwParamsDataAnalysis(data, ¶ms);
+ if (ret != HDF_SUCCESS) {
+ ADM_LOG_ERR("hwparams data analysis failed ret=%d", ret);
+ return HDF_FAILURE;
+ }
+
+ if (memcpy_s(cardName, BUFF_SIZE_MAX, params.cardServiceName, BUFF_SIZE_MAX) != EOK) {
+ ADM_LOG_ERR("memcpy cardName failed.");
+ return HDF_FAILURE;
+ }
+
+ audioCard = GetCardInstance(params.cardServiceName);
+ if (audioCard == NULL) {
+ ADM_LOG_ERR("get card instance fail.");
+ return HDF_FAILURE;
+ }
+
+ ret = HwParamsDispatch(audioCard, ¶ms);
+ if (ret != HDF_SUCCESS) {
+ ADM_LOG_ERR("hwparams dispatch failed ret=%d", ret);
+ return HDF_FAILURE;
+ }
+ ADM_LOG_DEBUG("success.");
+ return HDF_SUCCESS;
+}
+
+static struct AudioCard *StreamHostGetCardInstance(const struct HdfDeviceIoClient *client)
+{
+ char *cardName = NULL;
+ struct StreamHost *streamHost = NULL;
+ struct AudioCard *audioCard = NULL;
+
+ if (client == NULL || client->device == NULL) {
+ ADM_LOG_ERR("input param is NULL.");
+ return NULL;
+ }
+
+ streamHost = StreamHostFromDevice(client->device);
+ if (streamHost == NULL) {
+ ADM_LOG_ERR("streamHost is NULL");
+ return NULL;
+ }
+
+ cardName = (char *)streamHost->priv;
+ if (cardName == NULL) {
+ ADM_LOG_ERR("streamHost priv is NULL.");
+ return NULL;
+ }
+
+ audioCard = GetCardInstance(cardName);
+ if (audioCard == NULL) {
+ ADM_LOG_ERR("get card instance fail.");
+ return NULL;
+ }
+
+ return audioCard;
+}
+
+int32_t StreamHostCapturePrepare(const struct HdfDeviceIoClient *client, struct HdfSBuf *data,
+ struct HdfSBuf *reply)
+{
+ struct AudioRuntimeDeivces *rtd = NULL;
+ struct PlatformDevice *platform = NULL;
+ struct AudioCard *audioCard = NULL;
+ int ret = HDF_SUCCESS;
+ ADM_LOG_DEBUG("entry.");
+
+ if (client == NULL) {
+ ADM_LOG_ERR("CapturePrepare input param is NULL.");
+ return HDF_FAILURE;
+ }
+
+ (void)data;
+ (void)reply;
+
+ audioCard = StreamHostGetCardInstance(client);
+ if (audioCard == NULL || audioCard->rtd == NULL) {
+ ADM_LOG_ERR("CapturePrepare get card instance or rtd fail.");
+ return HDF_FAILURE;
+ }
+ rtd = audioCard->rtd;
+
+ platform = rtd->platform;
+ if (platform == NULL || platform->devData == NULL || platform->devData->ops == NULL ||
+ platform->devData->ops->CapturePrepare == NULL) {
+ ADM_LOG_ERR("audioCard rtd platform is NULL.");
+ return HDF_FAILURE;
+ }
+
+ ret = platform->devData->ops->CapturePrepare(audioCard);
+ if (ret != HDF_SUCCESS) {
+ ADM_LOG_ERR("platform CapturePrepare fail ret=%d", ret);
+ return HDF_ERR_IO;
+ }
+
+ ADM_LOG_DEBUG("success.");
+ return HDF_SUCCESS;
+}
+
+int32_t StreamHostRenderPrepare(const struct HdfDeviceIoClient *client, struct HdfSBuf *data,
+ struct HdfSBuf *reply)
+{
+ struct AudioRuntimeDeivces *rtd = NULL;
+ struct PlatformDevice *platform = NULL;
+ struct AudioCard *audioCard = NULL;
+ int ret = HDF_SUCCESS;
+ ADM_LOG_DEBUG("entry.");
+
+ if (client == NULL) {
+ ADM_LOG_ERR("RenderPrepare input param is NULL.");
+ return HDF_FAILURE;
+ }
+
+ (void)data;
+ (void)reply;
+
+ audioCard = StreamHostGetCardInstance(client);
+ if (audioCard == NULL || audioCard->rtd == NULL) {
+ ADM_LOG_ERR("RenderPrepare get card instance or rtd fail.");
+ return HDF_FAILURE;
+ }
+ rtd = audioCard->rtd;
+
+ platform = rtd->platform;
+ if (platform == NULL || platform->devData == NULL || platform->devData->ops == NULL ||
+ platform->devData->ops->RenderPrepare == NULL) {
+ ADM_LOG_ERR("audioCard rtd platform is NULL.");
+ return HDF_FAILURE;
+ }
+
+ ret = platform->devData->ops->RenderPrepare(audioCard);
+ if (ret != HDF_SUCCESS) {
+ ADM_LOG_ERR("platform RenderPrepare fail ret=%d", ret);
+ return HDF_ERR_IO;
+ }
+
+ ADM_LOG_DEBUG("success.");
+ return HDF_SUCCESS;
+}
+
+static int32_t StreamTransferWrite(const struct AudioCard *audioCard, struct AudioTxData *transfer)
+{
+ struct PlatformDevice *platform = NULL;
+ int32_t ret = HDF_SUCCESS;
+
+ if (audioCard == NULL || audioCard->rtd == NULL || transfer == NULL) {
+ ADM_LOG_ERR("input param is NULL.");
+ return HDF_FAILURE;
+ }
+
+ platform = audioCard->rtd->platform;
+ if (platform == NULL || platform->devData == NULL || platform->devData->ops == NULL ||
+ platform->devData->ops->Write == NULL) {
+ ADM_LOG_ERR("audioCard platform is NULL.");
+ return HDF_FAILURE;
+ }
+
+ ret = platform->devData->ops->Write(audioCard, transfer);
+ if (ret != HDF_SUCCESS) {
+ ADM_LOG_ERR("platform write fail ret=%d", ret);
+ return HDF_FAILURE;
+ }
+
+ return HDF_SUCCESS;
+}
+
+static int32_t StreamTransferMmapWrite(const struct AudioCard *audioCard, struct AudioTxMmapData *txMmapData)
+{
+ struct PlatformDevice *platform = NULL;
+ int32_t ret = HDF_SUCCESS;
+ ADM_LOG_DEBUG("entry.");
+
+ if (audioCard == NULL || audioCard->rtd == NULL || txMmapData == NULL) {
+ ADM_LOG_ERR("input param is NULL.");
+ return HDF_FAILURE;
+ }
+
+ platform = audioCard->rtd->platform;
+ if (platform == NULL || platform->devData == NULL || platform->devData->ops == NULL ||
+ platform->devData->ops->Write == NULL) {
+ ADM_LOG_ERR("audioCard platform is NULL.");
+ return HDF_FAILURE;
+ }
+
+ ret = platform->devData->ops->MmapWrite(audioCard, txMmapData);
+ if (ret != HDF_SUCCESS) {
+ ADM_LOG_ERR("platform write fail ret=%d", ret);
+ return HDF_FAILURE;
+ }
+
+ ADM_LOG_DEBUG("sucess.");
+ return HDF_SUCCESS;
+}
+
+static int32_t StreamTransferMmapRead(const struct AudioCard *audioCard, struct AudioRxMmapData *rxMmapData)
+{
+ struct PlatformDevice *platform = NULL;
+ int32_t ret = HDF_SUCCESS;
+ ADM_LOG_DEBUG("entry.");
+
+ if (audioCard == NULL || audioCard->rtd == NULL || rxMmapData == NULL) {
+ ADM_LOG_ERR("input param is NULL.");
+ return HDF_FAILURE;
+ }
+
+ platform = audioCard->rtd->platform;
+ if (platform == NULL || platform->devData == NULL || platform->devData->ops == NULL ||
+ platform->devData->ops->MmapRead == NULL) {
+ ADM_LOG_ERR("audioCard platform is NULL.");
+ return HDF_FAILURE;
+ }
+
+ ret = platform->devData->ops->MmapRead(audioCard, rxMmapData);
+ if (ret != HDF_SUCCESS) {
+ ADM_LOG_ERR("platform read fail ret=%d", ret);
+ return HDF_FAILURE;
+ }
+
+ ADM_LOG_DEBUG("sucess.");
+ return HDF_SUCCESS;
+}
+
+int32_t StreamHostWrite(const struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply)
+{
+ struct AudioTxData transfer;
+ struct AudioCard *audioCard = NULL;
+ int32_t ret = HDF_SUCCESS;
+ uint32_t dataSize = 0;
+ ADM_LOG_DEBUG("entry.");
+
+ if (client == NULL || reply == NULL) {
+ ADM_LOG_ERR("input param is NULL.");
+ return HDF_FAILURE;
+ }
+
+ if (!HdfSbufReadUint32(data, (uint32_t *)&(transfer.frames))) {
+ ADM_LOG_ERR("read request frames failed!");
+ return HDF_FAILURE;
+ }
+ if (!HdfSbufReadBuffer(data, (const void **)&(transfer.buf), &dataSize)) {
+ ADM_LOG_ERR("read request buf failed!");
+ return HDF_FAILURE;
+ }
+
+ audioCard = StreamHostGetCardInstance(client);
+ if (audioCard == NULL || audioCard->rtd == NULL) {
+ ADM_LOG_ERR("get card instance or rtd fail.");
+ return HDF_FAILURE;
+ }
+
+ ret = StreamTransferWrite(audioCard, &transfer);
+ if (ret != HDF_SUCCESS) {
+ ADM_LOG_ERR("write reg value fail ret=%d", ret);
+ return HDF_FAILURE;
+ }
+
+ if (!HdfSbufWriteUint32(reply, (uint32_t)(transfer.status))) {
+ ADM_LOG_ERR("read response status failed!");
+ return HDF_FAILURE;
+ }
+ ADM_LOG_DEBUG("success.");
+ return HDF_SUCCESS;
+}
+
+int32_t StreamHostRead(const struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply)
+{
+ struct AudioRuntimeDeivces *rtd = NULL;
+ struct PlatformDevice *platform = NULL;
+ struct AudioCard *audioCard = NULL;
+ struct AudioRxData rxData;
+ int ret = HDF_SUCCESS;
+ ADM_LOG_DEBUG("entry.");
+
+ if (client == NULL || reply == NULL) {
+ ADM_LOG_ERR("input param is NULL.");
+ return HDF_FAILURE;
+ }
+ (void)data;
+
+ audioCard = StreamHostGetCardInstance(client);
+ if (audioCard == NULL || audioCard->rtd == NULL) {
+ ADM_LOG_ERR("get card instance or rtd fail.");
+ return HDF_FAILURE;
+ }
+ rtd = audioCard->rtd;
+
+ platform = rtd->platform;
+ if (platform == NULL || platform->devData == NULL ||
+ platform->devData->ops == NULL || platform->devData->ops->Read == NULL) {
+ ADM_LOG_ERR("audioCard rtd platform is NULL.");
+ return HDF_FAILURE;
+ }
+
+ ret = platform->devData->ops->Read(audioCard, &rxData);
+ if (ret != HDF_SUCCESS) {
+ ADM_LOG_ERR("platform read fail ret=%d", ret);
+ return HDF_FAILURE;
+ }
+
+ if (!HdfSbufWriteUint32(reply, (uint32_t)(rxData.status))) {
+ ADM_LOG_ERR("write request data status failed!");
+ return HDF_FAILURE;
+ }
+
+ if (!HdfSbufWriteBuffer(reply, rxData.buf, (uint32_t)(rxData.bufSize))) {
+ ADM_LOG_ERR("write request data buf failed!");
+ return HDF_FAILURE;
+ }
+
+ if (!HdfSbufWriteUint32(reply, (uint32_t)(rxData.frames))) {
+ ADM_LOG_ERR("write frames failed!");
+ return HDF_FAILURE;
+ }
+
+ ADM_LOG_DEBUG("success.");
+ return HDF_SUCCESS;
+}
+
+int32_t StreamHostMmapWrite(const struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply)
+{
+ struct AudioTxMmapData txMmapData;
+ struct AudioCard *audioCard = NULL;
+ uint64_t mAddress = 0;
+ ADM_LOG_DEBUG("entry.");
+ if (client == NULL || reply == NULL) {
+ ADM_LOG_ERR("input param is NULL.");
+ return HDF_FAILURE;
+ }
+ if (!HdfSbufReadUint64(data, &mAddress)) {
+ ADM_LOG_ERR("render mmap read request memory address failed!");
+ return HDF_FAILURE;
+ }
+
+ txMmapData.memoryAddress = (void *)((uintptr_t)mAddress);
+
+ if (!HdfSbufReadInt32(data, (uint32_t *)&(txMmapData.memoryFd))) {
+ ADM_LOG_ERR("render mmap read request memory fd failed!");
+ return HDF_FAILURE;
+ }
+ if (!HdfSbufReadInt32(data, (uint32_t *)&(txMmapData.totalBufferFrames))) {
+ ADM_LOG_ERR("render mmap read request total buffer frames failed!");
+ return HDF_FAILURE;
+ }
+ if (!HdfSbufReadInt32(data, (uint32_t *)&(txMmapData.transferFrameSize))) {
+ ADM_LOG_ERR("render mmap read request transfer frame size failed!");
+ return HDF_FAILURE;
+ }
+ if (!HdfSbufReadInt32(data, (uint32_t *)&(txMmapData.isShareable))) {
+ ADM_LOG_ERR("render mmap read request is share able failed!");
+ return HDF_FAILURE;
+ }
+ if (!HdfSbufReadUint32(data, (uint32_t *)&(txMmapData.offset))) {
+ ADM_LOG_ERR("render mmap read request offset failed!");
+ return HDF_FAILURE;
+ }
+ audioCard = StreamHostGetCardInstance(client);
+ if (StreamTransferMmapWrite(audioCard, &txMmapData) != HDF_SUCCESS) {
+ ADM_LOG_ERR("render mmap write reg value fail!");
+ return HDF_FAILURE;
+ }
+ ADM_LOG_DEBUG("success.");
+ return HDF_SUCCESS;
+}
+int32_t StreamHostMmapPositionWrite(const struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply)
+{
+ struct AudioCard *audioCard = NULL;
+ ADM_LOG_DEBUG("entry.");
+ if (client == NULL || reply == NULL) {
+ ADM_LOG_ERR("input param is NULL.");
+ return HDF_FAILURE;
+ }
+ audioCard = StreamHostGetCardInstance(client);
+ if (audioCard == NULL || audioCard->rtd == NULL || audioCard->rtd->platform == NULL) {
+ ADM_LOG_ERR("audioCard instance is NULL.");
+ return HDF_FAILURE;
+ }
+ struct PlatformHost *platformHost = PlatformHostFromDevice(audioCard->rtd->platform->device);
+ if (platformHost == NULL) {
+ ADM_LOG_ERR("platformHost instance is NULL.");
+ return HDF_FAILURE;
+ }
+ if (!HdfSbufWriteUint64(reply, platformHost->renderBufInfo.framesPosition)) {
+ ADM_LOG_ERR("render mmap write position fail!");
+ return HDF_FAILURE;
+ }
+ ADM_LOG_DEBUG("success.");
+ return HDF_SUCCESS;
+}
+
+int32_t StreamHostMmapRead(const struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply)
+{
+ uint64_t mAddress = 0;
+ struct AudioCard *audioCard = NULL;
+ struct AudioRxMmapData rxMmapData;
+ ADM_LOG_DEBUG("entry.");
+ if (client == NULL || reply == NULL) {
+ ADM_LOG_ERR("input param is NULL.");
+ return HDF_FAILURE;
+ }
+ if (!HdfSbufReadUint64(data, &mAddress)) {
+ ADM_LOG_ERR("capture mmap read request memory address failed!");
+ return HDF_FAILURE;
+ }
+ rxMmapData.memoryAddress = (void *)((uintptr_t)mAddress);
+
+ if (!HdfSbufReadInt32(data, (uint32_t *)&(rxMmapData.memoryFd))) {
+ ADM_LOG_ERR("capture mmap read request memory fd failed!");
+ return HDF_FAILURE;
+ }
+ if (!HdfSbufReadInt32(data, (uint32_t *)&(rxMmapData.totalBufferFrames))) {
+ ADM_LOG_ERR("capture mmap read request total buffer frames failed!");
+ return HDF_FAILURE;
+ }
+ if (!HdfSbufReadInt32(data, (uint32_t *)&(rxMmapData.transferFrameSize))) {
+ ADM_LOG_ERR("capture mmap read request transfer frame size failed!");
+ return HDF_FAILURE;
+ }
+ if (!HdfSbufReadInt32(data, (uint32_t *)&(rxMmapData.isShareable))) {
+ ADM_LOG_ERR("capture mmap read request is share able failed!");
+ return HDF_FAILURE;
+ }
+ if (!HdfSbufReadUint32(data, (uint32_t *)&(rxMmapData.offset))) {
+ ADM_LOG_ERR("capture mmap read request offset failed!");
+ return HDF_FAILURE;
+ }
+ audioCard = StreamHostGetCardInstance(client);
+ if (StreamTransferMmapRead(audioCard, &rxMmapData) != HDF_SUCCESS) {
+ ADM_LOG_ERR("capture mmap read reg value fail!");
+ return HDF_FAILURE;
+ }
+ ADM_LOG_DEBUG("success.");
+ return HDF_SUCCESS;
+}
+
+int32_t StreamHostMmapPositionRead(const struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply)
+{
+ struct AudioCard *audioCard = NULL;
+ ADM_LOG_DEBUG("entry.");
+ if (client == NULL || reply == NULL) {
+ ADM_LOG_ERR("input param is NULL.");
+ return HDF_FAILURE;
+ }
+ audioCard = StreamHostGetCardInstance(client);
+ if (audioCard == NULL || audioCard->rtd == NULL || audioCard->rtd->platform == NULL) {
+ ADM_LOG_ERR("audioCard is NULL.");
+ return HDF_FAILURE;
+ }
+ struct PlatformHost *platformHost = PlatformHostFromDevice(audioCard->rtd->platform->device);
+ if (platformHost == NULL) {
+ ADM_LOG_ERR("platformHost is NULL.");
+ return HDF_FAILURE;
+ }
+ if (!HdfSbufWriteUint64(reply, platformHost->captureBufInfo.framesPosition)) {
+ ADM_LOG_ERR("render mmap write position fail!");
+ return HDF_FAILURE;
+ }
+ ADM_LOG_DEBUG("success.");
+ return HDF_SUCCESS;
+}
+
+int32_t StreamHostRenderStart(const struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply)
+{
+ struct AudioRuntimeDeivces *rtd = NULL;
+ struct PlatformDevice *platform = NULL;
+ struct AudioCard *audioCard = NULL;
+ int ret = HDF_SUCCESS;
+ ADM_LOG_DEBUG("entry.");
+
+ if (client == NULL) {
+ ADM_LOG_ERR("RenderStart input param is NULL.");
+ return HDF_FAILURE;
+ }
+
+ (void)data;
+ (void)reply;
+
+ audioCard = StreamHostGetCardInstance(client);
+ if (audioCard == NULL || audioCard->rtd == NULL) {
+ ADM_LOG_ERR("RenderStart get card instance or rtd fail.");
+ return HDF_FAILURE;
+ }
+ rtd = audioCard->rtd;
+
+ platform = rtd->platform;
+ if (platform == NULL || platform->devData == NULL || platform->devData->ops == NULL ||
+ platform->devData->ops->RenderStart == NULL) {
+ ADM_LOG_ERR("audioCard rtd platform is NULL.");
+ return HDF_FAILURE;
+ }
+
+ ret = platform->devData->ops->RenderStart(audioCard);
+ if (ret != HDF_SUCCESS) {
+ ADM_LOG_ERR("platform render start fail ret=%d", ret);
+ return HDF_ERR_IO;
+ }
+
+ ADM_LOG_DEBUG("success.");
+ return HDF_SUCCESS;
+}
+
+int32_t StreamHostCaptureStart(const struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply)
+{
+ struct AudioRuntimeDeivces *rtd = NULL;
+ struct PlatformDevice *platform = NULL;
+ struct AudioCard *audioCard = NULL;
+ int ret = HDF_SUCCESS;
+ ADM_LOG_DEBUG("entry.");
+
+ if (client == NULL) {
+ ADM_LOG_ERR("CaptureStart input param is NULL.");
+ return HDF_FAILURE;
+ }
+
+ (void)data;
+ (void)reply;
+
+ audioCard = StreamHostGetCardInstance(client);
+ if (audioCard == NULL || audioCard->rtd == NULL) {
+ ADM_LOG_ERR("CaptureStart get card instance or rtd fail.");
+ return HDF_FAILURE;
+ }
+ rtd = audioCard->rtd;
+
+ platform = rtd->platform;
+ if (platform == NULL || platform->devData == NULL || platform->devData->ops == NULL ||
+ platform->devData->ops->CaptureStart == NULL) {
+ ADM_LOG_ERR("audioCard rtd platform is NULL.");
+ return HDF_FAILURE;
+ }
+
+ ret = platform->devData->ops->CaptureStart(audioCard);
+ if (ret != HDF_SUCCESS) {
+ ADM_LOG_ERR("platform capture start fail ret=%d", ret);
+ return HDF_ERR_IO;
+ }
+
+ ADM_LOG_DEBUG("success.");
+ return HDF_SUCCESS;
+}
+
+int32_t StreamHostRenderStop(const struct HdfDeviceIoClient *client, struct HdfSBuf *data,
+ struct HdfSBuf *reply)
+{
+ struct AudioRuntimeDeivces *rtd = NULL;
+ struct PlatformDevice *platform = NULL;
+ struct AudioCard *audioCard = NULL;
+ int ret = HDF_SUCCESS;
+ ADM_LOG_DEBUG("entry.");
+
+ if (client == NULL) {
+ ADM_LOG_ERR("RenderStop input param is NULL.");
+ return HDF_FAILURE;
+ }
+
+ (void)data;
+ (void)reply;
+
+ audioCard = StreamHostGetCardInstance(client);
+ if (audioCard == NULL || audioCard->rtd == NULL) {
+ ADM_LOG_ERR("RenderStop get card instance or rtd fail.");
+ return HDF_FAILURE;
+ }
+ rtd = audioCard->rtd;
+
+ platform = rtd->platform;
+ if (platform == NULL || platform->devData == NULL || platform->devData->ops == NULL ||
+ platform->devData->ops->RenderStop == NULL) {
+ ADM_LOG_ERR("audioCard rtd platform is NULL.");
+ return HDF_FAILURE;
+ }
+
+ ret = platform->devData->ops->RenderStop(audioCard);
+ if (ret != HDF_SUCCESS) {
+ ADM_LOG_ERR("platform render stop fail ret=%d", ret);
+ return HDF_ERR_IO;
+ }
+
+ ADM_LOG_DEBUG("success.");
+ return HDF_SUCCESS;
+}
+
+int32_t StreamHostCaptureStop(const struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply)
+{
+ struct AudioRuntimeDeivces *rtd = NULL;
+ struct PlatformDevice *platform = NULL;
+ struct AudioCard *audioCard = NULL;
+ int ret = HDF_SUCCESS;
+ ADM_LOG_DEBUG("entry.");
+
+ if (client == NULL) {
+ ADM_LOG_ERR("CaptureStop input param is NULL.");
+ return HDF_FAILURE;
+ }
+
+ (void)data;
+ (void)reply;
+
+ audioCard = StreamHostGetCardInstance(client);
+ if (audioCard == NULL || audioCard->rtd == NULL) {
+ ADM_LOG_ERR("CaptureStop get card instance or rtd fail.");
+ return HDF_FAILURE;
+ }
+ rtd = audioCard->rtd;
+
+ platform = rtd->platform;
+ if (platform == NULL || platform->devData == NULL || platform->devData->ops == NULL ||
+ platform->devData->ops->CaptureStop == NULL) {
+ ADM_LOG_ERR("audioCard rtd platform is NULL.");
+ return HDF_FAILURE;
+ }
+
+ ret = platform->devData->ops->CaptureStop(audioCard);
+ if (ret != HDF_SUCCESS) {
+ ADM_LOG_ERR("platform capture stop fail ret=%d", ret);
+ return HDF_ERR_IO;
+ }
+
+ ADM_LOG_DEBUG("success.");
+ return HDF_SUCCESS;
+}
+
+int32_t StreamHostRenderPause(const struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply)
+{
+ struct AudioRuntimeDeivces *rtd = NULL;
+ struct PlatformDevice *platform = NULL;
+ struct AudioCard *audioCard = NULL;
+ int ret = HDF_SUCCESS;
+ ADM_LOG_DEBUG("entry.");
+
+ if (client == NULL) {
+ ADM_LOG_ERR("RenderPause input param is NULL.");
+ return HDF_FAILURE;
+ }
+
+ (void)data;
+ (void)reply;
+
+ audioCard = StreamHostGetCardInstance(client);
+ if (audioCard == NULL || audioCard->rtd == NULL) {
+ ADM_LOG_ERR("RenderPause get card instance or rtd fail.");
+ return HDF_FAILURE;
+ }
+ rtd = audioCard->rtd;
+
+ platform = rtd->platform;
+ if (platform == NULL || platform->devData == NULL || platform->devData->ops == NULL ||
+ platform->devData->ops->RenderPause == NULL) {
+ ADM_LOG_ERR("audioCard rtd platform is NULL.");
+ return HDF_FAILURE;
+ }
+
+ ret = platform->devData->ops->RenderPause(audioCard);
+ if (ret != HDF_SUCCESS) {
+ ADM_LOG_ERR("platform render pause fail ret=%d", ret);
+ return HDF_ERR_IO;
+ }
+
+ ADM_LOG_DEBUG("success.");
+ return HDF_SUCCESS;
+}
+
+int32_t StreamHostCapturePause(const struct HdfDeviceIoClient *client, struct HdfSBuf *data,
+ struct HdfSBuf *reply)
+{
+ struct AudioRuntimeDeivces *rtd = NULL;
+ struct PlatformDevice *platform = NULL;
+ struct AudioCard *audioCard = NULL;
+ int ret = HDF_SUCCESS;
+ ADM_LOG_DEBUG("entry.");
+
+ if (client == NULL) {
+ ADM_LOG_ERR("CapturePause input param is NULL.");
+ return HDF_FAILURE;
+ }
+
+ (void)data;
+ (void)reply;
+
+ audioCard = StreamHostGetCardInstance(client);
+ if (audioCard == NULL || audioCard->rtd == NULL) {
+ ADM_LOG_ERR("CapturePause get card instance or rtd fail.");
+ return HDF_FAILURE;
+ }
+ rtd = audioCard->rtd;
+
+ platform = rtd->platform;
+ if (platform == NULL || platform->devData == NULL || platform->devData->ops == NULL ||
+ platform->devData->ops->CapturePause == NULL) {
+ ADM_LOG_ERR("audioCard rtd platform is NULL.");
+ return HDF_FAILURE;
+ }
+
+ ret = platform->devData->ops->CapturePause(audioCard);
+ if (ret != HDF_SUCCESS) {
+ ADM_LOG_ERR("platform captur pause fail ret=%d", ret);
+ return HDF_ERR_IO;
+ }
+
+ ADM_LOG_DEBUG("success.");
+ return HDF_SUCCESS;
+}
+
+int32_t StreamHostRenderResume(const struct HdfDeviceIoClient *client, struct HdfSBuf *data,
+ struct HdfSBuf *reply)
+{
+ struct AudioRuntimeDeivces *rtd = NULL;
+ struct PlatformDevice *platform = NULL;
+ struct AudioCard *audioCard = NULL;
+ int ret = HDF_SUCCESS;
+ ADM_LOG_DEBUG("entry.");
+
+ if (client == NULL) {
+ ADM_LOG_ERR("RenderResume input param is NULL.");
+ return HDF_FAILURE;
+ }
+
+ (void)data;
+ (void)reply;
+
+ audioCard = StreamHostGetCardInstance(client);
+ if (audioCard == NULL || audioCard->rtd == NULL) {
+ ADM_LOG_ERR("RenderResume get card instance or rtd fail.");
+ return HDF_FAILURE;
+ }
+ rtd = audioCard->rtd;
+
+ platform = rtd->platform;
+ if (platform == NULL || platform->devData == NULL || platform->devData->ops == NULL ||
+ platform->devData->ops->RenderResume == NULL) {
+ ADM_LOG_ERR("audioCard rtd platform is NULL.");
+ return HDF_FAILURE;
+ }
+
+ ret = platform->devData->ops->RenderResume(audioCard);
+ if (ret != HDF_SUCCESS) {
+ ADM_LOG_ERR("platform RenderResume fail ret=%d", ret);
+ return HDF_ERR_IO;
+ }
+
+ ADM_LOG_DEBUG("success.");
+ return HDF_SUCCESS;
+}
+
+int32_t StreamHostCaptureResume(const struct HdfDeviceIoClient *client, struct HdfSBuf *data,
+ struct HdfSBuf *reply)
+{
+ struct AudioRuntimeDeivces *rtd = NULL;
+ struct PlatformDevice *platform = NULL;
+ struct AudioCard *audioCard = NULL;
+ int ret = HDF_SUCCESS;
+ ADM_LOG_DEBUG("entry.");
+
+ if (client == NULL) {
+ ADM_LOG_ERR("CaptureResume input param is NULL.");
+ return HDF_FAILURE;
+ }
+
+ (void)data;
+ (void)reply;
+
+ audioCard = StreamHostGetCardInstance(client);
+ if (audioCard == NULL || audioCard->rtd == NULL) {
+ ADM_LOG_ERR("CaptureResume get card instance or rtd fail.");
+ return HDF_FAILURE;
+ }
+ rtd = audioCard->rtd;
+
+ platform = rtd->platform;
+ if (platform == NULL || platform->devData == NULL || platform->devData->ops == NULL ||
+ platform->devData->ops->CaptureResume == NULL) {
+ ADM_LOG_ERR("audioCard rtd platform is NULL.");
+ return HDF_FAILURE;
+ }
+
+ ret = platform->devData->ops->CaptureResume(audioCard);
+ if (ret != HDF_SUCCESS) {
+ ADM_LOG_ERR("platform CaptureResume fail ret=%d", ret);
+ return HDF_ERR_IO;
+ }
+
+ ADM_LOG_DEBUG("success.");
+ return HDF_SUCCESS;
+}
+
+int32_t StreamHostDspDecode(const struct HdfDeviceIoClient *client, struct HdfSBuf *data,
+ struct HdfSBuf *reply)
+{
+ struct AudioRuntimeDeivces *rtd = NULL;
+ struct DspDevice *dspDev = NULL;
+ struct AudioCard *audioCard = NULL;
+ int ret = HDF_SUCCESS;
+ ADM_LOG_DEBUG("Dsp Decode Entry.");
+
+ if (client == NULL) {
+ ADM_LOG_ERR("DspDecode input param is NULL.");
+ return HDF_FAILURE;
+ }
+
+ (void)reply;
+
+ audioCard = StreamHostGetCardInstance(client);
+ if (audioCard == NULL || audioCard->rtd == NULL) {
+ ADM_LOG_ERR("DspDecode get card instance or rtd fail.");
+ return HDF_FAILURE;
+ }
+ rtd = audioCard->rtd;
+
+ dspDev = rtd->dsp;
+ if (dspDev == NULL || dspDev->devData == NULL || dspDev->devData->decode == NULL) {
+ ADM_LOG_ERR("audioCard rtd dsp is NULL.");
+ return HDF_FAILURE;
+ }
+
+ ret = dspDev->devData->decode(audioCard, (void*)data, dspDev);
+ if (ret != HDF_SUCCESS) {
+ ADM_LOG_ERR("DeCode render pause fail ret=%d", ret);
+ return HDF_ERR_IO;
+ }
+
+ ADM_LOG_DEBUG("Decode Success.");
+ return HDF_SUCCESS;
+}
+
+int32_t StreamHostDspEncode(const struct HdfDeviceIoClient *client, struct HdfSBuf *data,
+ struct HdfSBuf *reply)
+{
+ struct AudioRuntimeDeivces *rtd = NULL;
+ struct DspDevice *dspDev = NULL;
+ struct AudioCard *audioCard = NULL;
+ int ret = HDF_SUCCESS;
+ ADM_LOG_DEBUG("Dsp Encode Entry.");
+
+ if (client == NULL) {
+ ADM_LOG_ERR("DspEncode input param is NULL.");
+ return HDF_FAILURE;
+ }
+
+ (void)reply;
+
+ audioCard = StreamHostGetCardInstance(client);
+ if (audioCard == NULL || audioCard->rtd == NULL) {
+ ADM_LOG_ERR("DspEncode get card instance or rtd fail.");
+ return HDF_FAILURE;
+ }
+ rtd = audioCard->rtd;
+
+ dspDev = rtd->dsp;
+ if (dspDev == NULL || dspDev->devData == NULL || dspDev->devData->encode == NULL) {
+ ADM_LOG_ERR("audioCard rtd dsp is NULL.");
+ return HDF_FAILURE;
+ }
+
+ ret = dspDev->devData->encode(audioCard, (void*)data, dspDev);
+ if (ret != HDF_SUCCESS) {
+ ADM_LOG_ERR("EnCode render pause fail ret=%d", ret);
+ return HDF_ERR_IO;
+ }
+
+ ADM_LOG_DEBUG("Encode Success.");
+ return HDF_SUCCESS;
+}
+
+int32_t StreamHostDspEqualizer(const struct HdfDeviceIoClient *client, struct HdfSBuf *data,
+ struct HdfSBuf *reply)
+{
+ struct AudioRuntimeDeivces *rtd = NULL;
+ struct DspDevice *dspDev = NULL;
+ struct AudioCard *audioCard = NULL;
+ int ret = HDF_SUCCESS;
+ ADM_LOG_DEBUG("Dsp Equalizer Entry.");
+
+ if (client == NULL) {
+ ADM_LOG_ERR("DspEqualizer input param is NULL.");
+ return HDF_FAILURE;
+ }
+
+ (void)reply;
+
+ audioCard = StreamHostGetCardInstance(client);
+ if (audioCard == NULL || audioCard->rtd == NULL) {
+ ADM_LOG_ERR("DspEqualizer get card instance or rtd fail.");
+ return HDF_FAILURE;
+ }
+ rtd = audioCard->rtd;
+
+ dspDev = rtd->dsp;
+ if (dspDev == NULL || dspDev->devData == NULL || dspDev->devData->Equalizer == NULL) {
+ ADM_LOG_ERR("audioCard rtd dsp is NULL.");
+ return HDF_FAILURE;
+ }
+
+ ret = dspDev->devData->Equalizer(audioCard, (void*)data, dspDev);
+ if (ret != HDF_SUCCESS) {
+ ADM_LOG_ERR("Equalizer render pause fail ret=%d", ret);
+ return HDF_ERR_IO;
+ }
+
+ ADM_LOG_DEBUG("Equalizer Success.");
+ return HDF_SUCCESS;
+}
+
+static struct StreamDispCmdHandleList g_streamDispCmdHandle[] = {
+ {AUDIO_DRV_PCM_IOCTRL_HW_PARAMS, StreamHostHwParams},
+ {AUDIO_DRV_PCM_IOCTRL_RENDER_PREPARE, StreamHostRenderPrepare},
+ {AUDIO_DRV_PCM_IOCTRL_CAPTURE_PREPARE, StreamHostCapturePrepare},
+ {AUDIO_DRV_PCM_IOCTRL_WRITE, StreamHostWrite},
+ {AUDIO_DRV_PCM_IOCTRL_READ, StreamHostRead},
+ {AUDIO_DRV_PCM_IOCTRL_RENDER_START, StreamHostRenderStart},
+ {AUDIO_DRV_PCM_IOCTRL_RENDER_STOP, StreamHostRenderStop},
+ {AUDIO_DRV_PCM_IOCTRL_CAPTURE_START, StreamHostCaptureStart},
+ {AUDIO_DRV_PCM_IOCTRL_CAPTURE_STOP, StreamHostCaptureStop},
+ {AUDIO_DRV_PCM_IOCTRL_RENDER_PAUSE, StreamHostRenderPause},
+ {AUDIO_DRV_PCM_IOCTRL_CAPTURE_PAUSE, StreamHostCapturePause},
+ {AUDIO_DRV_PCM_IOCTRL_RENDER_RESUME, StreamHostRenderResume},
+ {AUDIO_DRV_PCM_IOCTRL_CAPTURE_RESUME, StreamHostCaptureResume},
+ {AUDIO_DRV_PCM_IOCTL_MMAP_BUFFER, StreamHostMmapWrite},
+ {AUDIO_DRV_PCM_IOCTL_MMAP_BUFFER_CAPTURE, StreamHostMmapRead},
+ {AUDIO_DRV_PCM_IOCTL_MMAP_POSITION, StreamHostMmapPositionWrite},
+ {AUDIO_DRV_PCM_IOCTL_MMAP_POSITION_CAPTURE, StreamHostMmapPositionRead},
+ {AUDIO_DRV_PCM_IOCTRL_DSP_DECODE, StreamHostDspDecode},
+ {AUDIO_DRV_PCM_IOCTRL_DSP_ENCODE, StreamHostDspEncode},
+ {AUDIO_DRV_PCM_IOCTRL_DSP_EQUALIZER, StreamHostDspEqualizer},
+};
+
+int32_t StreamDispatch(struct HdfDeviceIoClient *client, int cmdId,
+ struct HdfSBuf *data, struct HdfSBuf *reply)
+{
+ unsigned int i = 0;
+
+ if ((client == NULL) || (data == NULL) || (reply == NULL)) {
+ return HDF_ERR_INVALID_PARAM;
+ }
+
+ if (cmdId >= AUDIO_DRV_PCM_IOCTRL_BUTT || cmdId < 0) {
+ ADM_LOG_ERR("invalid [cmdId=%d]", cmdId);
+ return HDF_FAILURE;
+ }
+
+ for (i = 0; i < sizeof(g_streamDispCmdHandle) / sizeof(g_streamDispCmdHandle[0]); ++i) {
+ if ((cmdId == (int)(g_streamDispCmdHandle[i].cmd)) && (g_streamDispCmdHandle[i].func != NULL)) {
+ return g_streamDispCmdHandle[i].func(client, data, reply);
+ }
+ }
+ return HDF_FAILURE;
+}
+
+static struct StreamHost *StreamHostCreateAndBind(struct HdfDeviceObject *device)
+{
+ if (device == NULL) {
+ return NULL;
+ }
+
+ struct StreamHost *streamHost = (struct StreamHost *)OsalMemCalloc(sizeof(*streamHost));
+ if (streamHost == NULL) {
+ ADM_LOG_ERR("malloc host fail!");
+ return NULL;
+ }
+ streamHost->device = device;
+ device->service = &streamHost->service;
+ return streamHost;
+}
+
+static int32_t AudioStreamBind(struct HdfDeviceObject *device)
+{
+ ADM_LOG_DEBUG("entry!");
+ if (device == NULL) {
+ return HDF_ERR_INVALID_PARAM;
+ }
+
+ struct StreamHost *streamHost = StreamHostCreateAndBind(device);
+ if (streamHost == NULL || streamHost->device == NULL) {
+ ADM_LOG_ERR("StreamHostCreateAndBind failed");
+ return HDF_FAILURE;
+ }
+
+ streamHost->service.Dispatch = StreamDispatch;
+
+ ADM_LOG_INFO("success!");
+ return HDF_SUCCESS;
+}
+
+static int32_t AudioStreamInit(struct HdfDeviceObject *device)
+{
+ struct StreamHost *streamHost = NULL;
+
+ if (device == NULL) {
+ ADM_LOG_ERR("device is NULL");
+ return HDF_FAILURE;
+ }
+ ADM_LOG_DEBUG("entry.");
+
+ streamHost = StreamHostFromDevice(device);
+ if (streamHost == NULL) {
+ ADM_LOG_ERR("renderHost is NULL");
+ return HDF_FAILURE;
+ }
+
+ ADM_LOG_INFO("Success!");
+ return HDF_SUCCESS;
+}
+
+static void AudioStreamRelease(struct HdfDeviceObject *device)
+{
+ if (device == NULL) {
+ ADM_LOG_ERR("device is NULL");
+ return;
+ }
+
+ struct StreamHost *streamHost = StreamHostFromDevice(device);
+ if (streamHost == NULL) {
+ ADM_LOG_ERR("renderHost is NULL");
+ return;
+ }
+
+ if (streamHost->priv != NULL) {
+ OsalMemFree(streamHost->priv);
+ }
+ OsalMemFree(streamHost);
+}
+
+/* HdfDriverEntry definitions */
+struct HdfDriverEntry g_audioStreamEntry = {
+ .moduleVersion = 1,
+ .moduleName = "HDF_AUDIO_STREAM",
+ .Bind = AudioStreamBind,
+ .Init = AudioStreamInit,
+ .Release = AudioStreamRelease,
+};
+HDF_INIT(g_audioStreamEntry);
diff --git a/model/audio/dispatch/test/unittest/common/audio_stream_dispatch_test.cpp b/model/audio/dispatch/test/unittest/common/audio_stream_dispatch_test.cpp
new file mode 100755
index 0000000000000000000000000000000000000000..50bd21dcb33801432d9962cb098caeca6f0cd071
--- /dev/null
+++ b/model/audio/dispatch/test/unittest/common/audio_stream_dispatch_test.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 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 "audio_common_test.h"
+#include
+#include "hdf_uhdf_test.h"
+
+using namespace testing::ext;
+
+class AudioStreamDispatchTest : public testing::Test {
+public:
+ static void SetUpTestCase();
+ static void TearDownTestCase();
+ void SetUp();
+ void TearDown();
+};
+
+void AudioStreamDispatchTest::SetUpTestCase()
+{
+ HdfTestOpenService();
+}
+
+void AudioStreamDispatchTest::TearDownTestCase()
+{
+ HdfTestCloseService();
+}
+
+void AudioStreamDispatchTest::SetUp()
+{
+}
+
+void AudioStreamDispatchTest::TearDown()
+{
+}
+
+HWTEST_F(AudioStreamDispatchTest, AudioStreamDispatchTest001, TestSize.Level0)
+{
+ struct HdfTestMsg msg = {g_testAudioType, TESTSTREAMDISPATCH, -1};
+ EXPECT_EQ(0, HdfTestSendMsgToService(&msg));
+}
diff --git a/model/audio/sapm/include/audio_sapm.h b/model/audio/sapm/include/audio_sapm.h
new file mode 100755
index 0000000000000000000000000000000000000000..0eaa935cbdd0e776d4d93294158cb72dc3ac1578
--- /dev/null
+++ b/model/audio/sapm/include/audio_sapm.h
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 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 AUDIO_SAPM_H
+#define AUDIO_SAPM_H
+
+#include "audio_core.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif
+#endif /* __cplusplus */
+
+#define SAPM_POLL_TIME 10000 /* 10s */
+#define SAPM_SLEEP_TIME (3 * 60000) /* 3min */
+
+#define MIXER_REG_ADDR 10 /* mixer address -- Temporarily defined as this value */
+
+#define SAPM_POWER_DOWN 0
+#define SAPM_POWER_UP 1
+
+#define CONNECT_CODEC_PIN 1
+#define UNCONNECT_CODEC_PIN 0
+
+#define EXIST_EXTERNAL_WIDGET 1
+#define UNEXIST_EXTERNAL_WIDGET 1
+
+#define CONNECT_SINK_AND_SOURCE 1
+#define UNCONNECT_SINK_AND_SOURCE 0
+
+/* sapm widget types */
+enum AudioSapmType {
+ AUDIO_SAPM_INPUT = 0, /* input pin */
+ AUDIO_SAPM_OUTPUT, /* output pin */
+ AUDIO_SAPM_MUX, /* selects 1 analog signal from many inputs */
+ AUDIO_SAPM_VIRT_MUX, /* virtual version of snd_soc_dapm_mux */
+ AUDIO_SAPM_VALUE_MUX, /* selects 1 analog signal from many inputs */
+ AUDIO_SAPM_MIXER, /* mixes several analog signals together */
+ AUDIO_SAPM_MIXER_NAMED_CTRL, /* mixer with named controls */
+ AUDIO_SAPM_PGA, /* programmable gain/attenuation (volume) */
+ AUDIO_SAPM_OUT_DRV, /* output driver */
+ AUDIO_SAPM_ADC, /* analog to digital converter */
+ AUDIO_SAPM_DAC, /* digital to analog converter */
+ AUDIO_SAPM_MICBIAS, /* microphone bias (power) */
+ AUDIO_SAPM_MIC, /* microphone */
+ AUDIO_SAPM_HP, /* headphones */
+ AUDIO_SAPM_SPK, /* speaker */
+ AUDIO_SAPM_LINE, /* line input/output */
+ AUDIO_SAPM_ANALOG_SWITCH, /* analog switch */
+ AUDIO_SAPM_VMID, /* codec bias/vmid - to minimise pops */
+ AUDIO_SAPM_PRE, /* machine specific pre component - exec first */
+ AUDIO_SAPM_POST, /* machine specific post component - exec last */
+ AUDIO_SAPM_SUPPLY, /* power/clock supply */
+ AUDIO_SAPM_AIF_IN, /* audio interface input */
+ AUDIO_SAPM_AIF_OUT, /* audio interface output */
+};
+
+/* component has no PM register bit */
+#define AUDIO_SAPM_NOPM (-1)
+
+/* dapm stream operations */
+#define AUDIO_SAPM_STREAM_NOP 0x0
+#define AUDIO_SAPM_STREAM_START 0x1
+#define AUDIO_SAPM_STREAM_STOP 0x2
+#define AUDIO_SAPM_STREAM_SUSPEND 0x4
+#define AUDIO_SAPM_STREAM_RESUME 0x8
+#define AUDIO_SAPM_STREAM_PAUSE_PUSH 0x10
+#define AUDIO_SAPM_STREAM_PAUSE_RELEASE 0x20
+
+/* sapm event types */
+#define AUDIO_SAPM_PRE_PMU 0x1 /* before component power up */
+#define AUDIO_SAPM_POST_PMU 0x2 /* after component power up */
+#define AUDIO_SAPM_PRE_PMD 0x4 /* before component power down */
+#define AUDIO_SAPM_POST_PMD 0x8 /* after component power down */
+#define AUDIO_SAPM_PRE_REG 0x10 /* before audio path setup */
+#define AUDIO_SAPM_POST_REG 0x20 /* after audio path setup */
+#define AUDIO_SAPM_PRE_POST_PMD (AUDIO_SAPM_PRE_PMD | AUDIO_SAPM_POST_PMD)
+
+enum AudioBiasLevel {
+ AUDIO_BIAS_OFF = 0,
+ AUDIO_BIAS_STANDBY = 1,
+ AUDIO_BIAS_PREPARE = 2,
+ AUDIO_BIAS_ON = 3,
+};
+
+/* SAPM context */
+struct AudioSapmContext {
+ int32_t componentNum; /* number of components in this context */
+ enum AudioBiasLevel biasLevel;
+ enum AudioBiasLevel suspendBiasLevel;
+
+ struct CodecDevice *codec; /* parent codec */
+ struct PlatformDevice *platform; /* parent platform */
+ struct AudioCard *card; /* parent card */
+
+ /* used during SAPM updates */
+ enum AudioBiasLevel targetBiasLevel;
+ struct DListHead list;
+};
+
+/* enumerated kcontrol */
+struct AudioEnumKcontrol {
+ uint32_t reg;
+ uint32_t reg2;
+ uint8_t shiftLeft;
+ uint8_t shiftRight;
+ uint32_t max;
+ uint32_t mask;
+ const char * const *texts;
+ const uint32_t *values;
+ void *sapm;
+};
+
+/* sapm audio path between two components */
+struct AudioSapmpath {
+ char *name;
+
+ /* source (input) and sink (output) components */
+ struct AudioSapmComponent *source;
+ struct AudioSapmComponent *sink;
+ struct AudioKcontrol *kcontrol;
+
+ /* status */
+ uint8_t connect; /* source and sink components are connected */
+ uint8_t walked; /* path has been walked */
+ uint8_t weak; /* path ignored for power management */
+
+ int32_t (*connected)(struct AudioSapmComponent *source, struct AudioSapmComponent *sink);
+
+ struct DListHead listSource;
+ struct DListHead listSink;
+ struct DListHead list;
+};
+
+/* sapm component */
+struct AudioSapmComponent {
+ enum AudioSapmType sapmType;
+ char *componentName; /* component name */
+ char *streamName; /* stream name */
+ struct AudioSapmContext *sapm;
+ struct CodecDevice *codec; /* parent codec */
+ struct AccessoryDevice *accessory; /* parent accessory */
+ struct PlatformDevice *platform; /* parent platform */
+
+ /* sapm control */
+ int16_t reg; /* negative reg = no direct sapm */
+ uint8_t shift; /* bits to shift */
+ uint8_t invert; /* invert the power bit */
+ uint8_t mask;
+ uint8_t connected; /* connected codec pin */
+ uint8_t external; /* has external components */
+ uint8_t active; /* active stream on DAC, ADC's */
+ uint8_t newPower; /* power checked this run */
+ uint8_t power;
+ uint8_t newCpt;
+
+ /* external events */
+ uint16_t eventFlags; /* flags to specify event types */
+ int32_t (*Event)(struct AudioSapmComponent*, struct AudioKcontrol *, int32_t);
+
+ /* power check callback */
+ int32_t (*PowerCheck)(const struct AudioSapmComponent *);
+
+ /* kcontrols that relate to this component */
+ int32_t kcontrolsNum;
+ struct AudioKcontrol *kcontrolNews;
+ struct AudioKcontrol **kcontrols;
+
+ struct DListHead list;
+
+ /* component input and outputs */
+ struct DListHead sources;
+ struct DListHead sinks;
+
+ /* used during SAPM updates */
+ struct DListHead powerList;
+ struct DListHead dirty;
+
+ /* reserve clock interface */
+ int32_t (*PowerClockOp)(struct AudioSapmComponent *);
+};
+
+struct AudioSapmRoute {
+ const char *sink;
+ const char *control;
+ const char *source;
+
+ /* Note: currently only supported for links where source is a supply */
+ uint32_t (*Connected)(struct AudioSapmComponent *source,
+ struct AudioSapmComponent *sink);
+};
+
+int32_t AudioSapmNewComponents(struct AudioCard *audioCard,
+ const struct AudioSapmComponent *component, int32_t cptMaxNum);
+int32_t AudioSapmAddRoutes(struct AudioCard *audioCard,
+ const struct AudioSapmRoute *route, int32_t routeMaxNum);
+int32_t AudioSapmNewControls(struct AudioCard *audioCard);
+int AudioSapmPowerComponents(struct AudioCard *audioCard);
+int32_t AudioSapmSleep(const struct AudioCard *audioCard);
+uint64_t AudioSapmRefreshTime(bool bRefresh);
+int32_t AudioSampPowerUp(const struct AudioCard *card);
+int32_t AudioSampSetPowerMonitor(struct AudioCard *card, bool powerMonitorState);
+
+int32_t AudioCodecSapmSetCtrlOps(const struct AudioKcontrol *kcontrol, const struct AudioCtrlElemValue *elemValue);
+int32_t AudioCodecSapmGetCtrlOps(const struct AudioKcontrol *kcontrol, struct AudioCtrlElemValue *elemValue);
+int32_t AudioAccessorySapmSetCtrlOps(const struct AudioKcontrol *kcontrol, const struct AudioCtrlElemValue *elemValue);
+int32_t AudioAccessorySapmGetCtrlOps(const struct AudioKcontrol *kcontrol, struct AudioCtrlElemValue *elemValue);
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif
+#endif /* __cplusplus */
+
+#endif /* AUDIO_SAPM_H */
diff --git a/model/audio/sapm/src/audio_sapm.c b/model/audio/sapm/src/audio_sapm.c
new file mode 100755
index 0000000000000000000000000000000000000000..af58150257bbc8103c87d22638afa31a982177d3
--- /dev/null
+++ b/model/audio/sapm/src/audio_sapm.c
@@ -0,0 +1,1299 @@
+/*
+ * Copyright (c) 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 "audio_sapm.h"
+#include "osal_io.h"
+#include "osal_time.h"
+#include "osal_timer.h"
+
+#define HDF_LOG_TAG audio_sapm
+
+static void AudioSapmEnterSleep(uintptr_t para);
+
+/* power up sequences */
+static int32_t g_audioSapmPowerUpSeq[] = {
+ [AUDIO_SAPM_PRE] = 0, /* 0 is audio sapm power up sequences */
+ [AUDIO_SAPM_SUPPLY] = 1, /* 1 is audio sapm power up sequences */
+ [AUDIO_SAPM_MICBIAS] = 2, /* 2 is audio sapm power up sequences */
+ [AUDIO_SAPM_AIF_IN] = 3, /* 3 is audio sapm power up sequences */
+ [AUDIO_SAPM_AIF_OUT] = 3, /* 3 is audio sapm power up sequences */
+ [AUDIO_SAPM_MIC] = 4, /* 4 is audio sapm power up sequences */
+ [AUDIO_SAPM_MUX] = 5, /* 5 is audio sapm power up sequences */
+ [AUDIO_SAPM_VIRT_MUX] = 5, /* 5 is audio sapm power up sequences */
+ [AUDIO_SAPM_VALUE_MUX] = 5, /* 5 is audio sapm power up sequences */
+ [AUDIO_SAPM_DAC] = 6, /* 6 is audio sapm power up sequences */
+ [AUDIO_SAPM_MIXER] = 7, /* 7 is audio sapm power up sequences */
+ [AUDIO_SAPM_MIXER_NAMED_CTRL] = 7, /* 7 is audio sapm power up sequences */
+ [AUDIO_SAPM_PGA] = 8, /* 8 is audio sapm power up sequences */
+ [AUDIO_SAPM_ADC] = 9, /* 9 is audio sapm power up sequences */
+ [AUDIO_SAPM_OUT_DRV] = 10, /* 10 is audio sapm power up sequences */
+ [AUDIO_SAPM_HP] = 10, /* 10 is audio sapm power up sequences */
+ [AUDIO_SAPM_SPK] = 10, /* 10 is audio sapm power up sequences */
+ [AUDIO_SAPM_POST] = 11, /* 11 is audio sapm power up sequences */
+};
+
+/* power down sequences */
+static int32_t g_audioSapmPowerDownSeq[] = {
+ [AUDIO_SAPM_PRE] = 0, /* 0 is audio sapm power down sequences */
+ [AUDIO_SAPM_ADC] = 1, /* 1 is audio sapm power down sequences */
+ [AUDIO_SAPM_HP] = 2, /* 2 is audio sapm power down sequences */
+ [AUDIO_SAPM_SPK] = 2, /* 2 is audio sapm power down sequences */
+ [AUDIO_SAPM_OUT_DRV] = 2, /* 2 is audio sapm power down sequences */
+ [AUDIO_SAPM_PGA] = 4, /* 4 is audio sapm power down sequences */
+ [AUDIO_SAPM_MIXER_NAMED_CTRL] = 5, /* 5 is audio sapm power down sequences */
+ [AUDIO_SAPM_MIXER] = 5, /* 5 is audio sapm power down sequences */
+ [AUDIO_SAPM_DAC] = 6, /* 6 is audio sapm power down sequences */
+ [AUDIO_SAPM_MIC] = 7, /* 7 is audio sapm power down sequences */
+ [AUDIO_SAPM_MICBIAS] = 8, /* 8 is audio sapm power down sequences */
+ [AUDIO_SAPM_MUX] = 9, /* 9 is audio sapm power down sequences */
+ [AUDIO_SAPM_VIRT_MUX] = 9, /* 9 is audio sapm power down sequences */
+ [AUDIO_SAPM_VALUE_MUX] = 9, /* 9 is audio sapm power down sequences */
+ [AUDIO_SAPM_AIF_IN] = 10, /* 10 is audio sapm power down sequences */
+ [AUDIO_SAPM_AIF_OUT] = 10, /* 10 is audio sapm power down sequences */
+ [AUDIO_SAPM_SUPPLY] = 11, /* 11 is audio sapm power down sequences */
+ [AUDIO_SAPM_POST] = 12, /* 12 is audio sapm power down sequences */
+};
+
+static int32_t g_audioSapmIsSleep = 0;
+static int32_t g_audioSapmIsStandby = 0;
+OSAL_DECLARE_TIMER(g_sleepTimer);
+
+static int32_t ConnectedInputEndPoint(const struct AudioSapmComponent *sapmComponent)
+{
+ struct AudioSapmpath *path = NULL;
+ int32_t count = 0;
+ int32_t endPointVal = 1;
+
+ if (sapmComponent == NULL) {
+ ADM_LOG_ERR("input param sapmComponent is NULL.");
+ return HDF_FAILURE;
+ }
+
+ switch (sapmComponent->sapmType) {
+ case AUDIO_SAPM_DAC:
+ case AUDIO_SAPM_AIF_IN:
+ case AUDIO_SAPM_INPUT:
+ case AUDIO_SAPM_MIC:
+ case AUDIO_SAPM_LINE:
+ return endPointVal;
+ default:
+ break;
+ }
+
+ DLIST_FOR_EACH_ENTRY(path, &sapmComponent->sources, struct AudioSapmpath, listSink) {
+ if ((path->source != NULL) && (path->connect == CONNECT_SINK_AND_SOURCE)) {
+ count += ConnectedInputEndPoint(path->source);
+ }
+ }
+ return count;
+}
+
+static int32_t ConnectedOutputEndPoint(const struct AudioSapmComponent *sapmComponent)
+{
+ struct AudioSapmpath *path = NULL;
+ int32_t count = 0;
+ int32_t endPointVal = 1;
+
+ if (sapmComponent == NULL) {
+ ADM_LOG_ERR("input param sapmComponent is NULL.");
+ return HDF_FAILURE;
+ }
+
+ switch (sapmComponent->sapmType) {
+ case AUDIO_SAPM_ADC:
+ case AUDIO_SAPM_AIF_OUT:
+ case AUDIO_SAPM_OUTPUT:
+ case AUDIO_SAPM_HP:
+ case AUDIO_SAPM_SPK:
+ case AUDIO_SAPM_LINE:
+ return endPointVal;
+ default:
+ break;
+ }
+
+ DLIST_FOR_EACH_ENTRY(path, &sapmComponent->sinks, struct AudioSapmpath, listSource) {
+ if ((path->sink != NULL) && (path->connect == CONNECT_SINK_AND_SOURCE)) {
+ count += ConnectedOutputEndPoint(path->sink);
+ }
+ }
+ return count;
+}
+
+static int32_t AudioSapmGenericCheckPower(const struct AudioSapmComponent *sapmComponent)
+{
+ int32_t input;
+ int32_t output;
+
+ if (sapmComponent == NULL) {
+ ADM_LOG_ERR("input param cpt is NULL.");
+ return HDF_FAILURE;
+ }
+
+ input = ConnectedInputEndPoint(sapmComponent);
+ if (input == HDF_FAILURE) {
+ ADM_LOG_ERR("input endpoint fail!");
+ return HDF_FAILURE;
+ }
+ output = ConnectedOutputEndPoint(sapmComponent);
+ if (output == HDF_FAILURE) {
+ ADM_LOG_ERR("output endpoint fail!");
+ return HDF_FAILURE;
+ }
+
+ if ((input == 0) || (output == 0)) {
+ ADM_LOG_DEBUG("component is not in a complete path.");
+ return SAPM_POWER_DOWN;
+ }
+ return SAPM_POWER_UP;
+}
+
+static int32_t AudioSapmAdcCheckPower(const struct AudioSapmComponent *sapmComponent)
+{
+ int32_t input;
+
+ if (sapmComponent == NULL) {
+ ADM_LOG_ERR("input param sapmComponent is NULL.");
+ return HDF_FAILURE;
+ }
+
+ if (sapmComponent->active == 0) {
+ input = AudioSapmGenericCheckPower(sapmComponent);
+ } else {
+ input = ConnectedInputEndPoint(sapmComponent);
+ }
+ if (input == HDF_FAILURE) {
+ ADM_LOG_ERR("input endpoint fail!");
+ return HDF_FAILURE;
+ }
+ return input;
+}
+
+static int AudioSapmDacCheckPower(const struct AudioSapmComponent *sapmComponent)
+{
+ int32_t output;
+
+ if (sapmComponent == NULL) {
+ ADM_LOG_ERR("input sapmComponent cpt is NULL.");
+ return HDF_FAILURE;
+ }
+
+ if (sapmComponent->active == 0) {
+ output = AudioSapmGenericCheckPower(sapmComponent);
+ } else {
+ output = ConnectedOutputEndPoint(sapmComponent);
+ }
+ if (output == HDF_FAILURE) {
+ ADM_LOG_ERR("output endpoint fail!");
+ return HDF_FAILURE;
+ }
+ return output;
+}
+
+static void AudioSampCheckPowerCallback(struct AudioSapmComponent *sapmComponent)
+{
+ if (sapmComponent == NULL) {
+ ADM_LOG_ERR("input param cpt is NULL.");
+ return;
+ }
+
+ switch (sapmComponent->sapmType) {
+ case AUDIO_SAPM_ANALOG_SWITCH:
+ case AUDIO_SAPM_MIXER:
+ case AUDIO_SAPM_MIXER_NAMED_CTRL:
+ sapmComponent->PowerCheck = AudioSapmGenericCheckPower;
+ break;
+ case AUDIO_SAPM_MUX:
+ case AUDIO_SAPM_VIRT_MUX:
+ case AUDIO_SAPM_VALUE_MUX:
+ sapmComponent->PowerCheck = AudioSapmGenericCheckPower;
+ break;
+ case AUDIO_SAPM_ADC:
+ case AUDIO_SAPM_AIF_OUT:
+ sapmComponent->PowerCheck = AudioSapmAdcCheckPower;
+ break;
+ case AUDIO_SAPM_DAC:
+ case AUDIO_SAPM_AIF_IN:
+ sapmComponent->PowerCheck = AudioSapmDacCheckPower;
+ break;
+ case AUDIO_SAPM_PGA:
+ case AUDIO_SAPM_OUT_DRV:
+ case AUDIO_SAPM_INPUT:
+ case AUDIO_SAPM_OUTPUT:
+ case AUDIO_SAPM_MICBIAS:
+ case AUDIO_SAPM_SPK:
+ case AUDIO_SAPM_HP:
+ case AUDIO_SAPM_MIC:
+ case AUDIO_SAPM_LINE:
+ sapmComponent->PowerCheck = AudioSapmGenericCheckPower;
+ break;
+ default:
+ sapmComponent->PowerCheck = AudioSapmGenericCheckPower;
+ break;
+ }
+
+ return;
+}
+
+int32_t AudioSapmNewComponent(struct AudioCard *audioCard, const struct AudioSapmComponent *component)
+{
+ struct AudioSapmComponent *sapmComponent = NULL;
+
+ if ((audioCard == NULL || audioCard->rtd == NULL || audioCard->rtd->codec == NULL) || (component == NULL)) {
+ ADM_LOG_ERR("input params check error: audioCard=%p, component=%p.", audioCard, component);
+ return HDF_FAILURE;
+ }
+
+ if (component->componentName == NULL) {
+ ADM_LOG_ERR("component->componentName is NULL");
+ return HDF_FAILURE;
+ }
+
+ sapmComponent = (struct AudioSapmComponent *)OsalMemCalloc(sizeof(struct AudioSapmComponent));
+ if (sapmComponent == NULL) {
+ ADM_LOG_ERR("malloc cpt fail!");
+ return HDF_FAILURE;
+ }
+
+ if (memcpy_s(sapmComponent, sizeof(struct AudioSapmComponent),
+ component, sizeof(struct AudioSapmComponent)) != EOK) {
+ ADM_LOG_ERR("memcpy cpt fail!");
+ OsalMemFree(sapmComponent);
+ return HDF_FAILURE;
+ }
+
+ sapmComponent->componentName = (char *)OsalMemCalloc(strlen(component->componentName) + 1);
+ if (sapmComponent->componentName == NULL) {
+ ADM_LOG_ERR("malloc cpt->componentName fail!");
+ OsalMemFree(sapmComponent);
+ return HDF_FAILURE;
+ }
+ if (memcpy_s(sapmComponent->componentName, strlen(component->componentName) + 1,
+ component->componentName, strlen(component->componentName) + 1) != EOK) {
+ ADM_LOG_ERR("memcpy cpt->componentName fail!");
+ OsalMemFree(sapmComponent->componentName);
+ OsalMemFree(sapmComponent);
+ return HDF_FAILURE;
+ }
+ sapmComponent->codec = audioCard->rtd->codec;
+ sapmComponent->kcontrolsNum = component->kcontrolsNum;
+ sapmComponent->active = 0;
+ AudioSampCheckPowerCallback(sapmComponent);
+ sapmComponent->PowerClockOp = NULL;
+
+ DListHeadInit(&sapmComponent->sources);
+ DListHeadInit(&sapmComponent->sinks);
+ DListHeadInit(&sapmComponent->list);
+ DListHeadInit(&sapmComponent->dirty);
+ DListInsertHead(&sapmComponent->list, &audioCard->components);
+
+ sapmComponent->connected = CONNECT_CODEC_PIN;
+
+ return HDF_SUCCESS;
+}
+
+int32_t AudioSapmNewComponents(struct AudioCard *audioCard,
+ const struct AudioSapmComponent *component, int32_t cptMaxNum)
+{
+ int32_t i;
+ int32_t ret;
+
+ if ((audioCard == NULL) || (component == NULL)) {
+ ADM_LOG_ERR("input params check error: audioCard=%p, component=%p.", audioCard, component);
+ return HDF_FAILURE;
+ }
+
+ for (i = 0; i < cptMaxNum; i++) {
+ ret = AudioSapmNewComponent(audioCard, component);
+ if (ret != HDF_SUCCESS) {
+ ADM_LOG_ERR("AudioSapmNewComponent fail!");
+ return HDF_FAILURE;
+ }
+ component++;
+ }
+
+ return HDF_SUCCESS;
+}
+
+static void MuxSetPathStatus(const struct AudioSapmComponent *sapmComponent, struct AudioSapmpath *path,
+ const struct AudioEnumKcontrol *enumKtl, int32_t i)
+{
+ int32_t ret;
+ uint32_t val = 0;
+ int32_t item;
+ uint32_t reg = 0;
+ uint32_t shift;
+
+ if ((sapmComponent == NULL || sapmComponent->codec == NULL) || (path == NULL || path->name == NULL) ||
+ (enumKtl == NULL || enumKtl->texts == NULL)) {
+ ADM_LOG_ERR("input MuxSet params check error: sapmComponent=%p, path=%p, enumKtl=%p.",
+ sapmComponent, path, enumKtl);
+ return;
+ }
+
+ shift = enumKtl->shiftLeft;
+ ret = AudioCodecReadReg(sapmComponent->codec, reg, &val);
+ if (ret != HDF_SUCCESS) {
+ ADM_LOG_ERR("MuxSet read reg fail!");
+ return;
+ }
+
+ item = val >> shift;
+
+ path->connect = UNCONNECT_SINK_AND_SOURCE;
+ for (i = 0; i < enumKtl->max; i++) {
+ if (enumKtl->texts[i] == NULL) {
+ ADM_LOG_ERR("enumKtl->texts[%d] is NULL", i);
+ continue;
+ }
+
+ if ((strcmp(path->name, enumKtl->texts[i]) == 0) && item == i) {
+ path->connect = CONNECT_SINK_AND_SOURCE;
+ }
+ }
+ return;
+}
+
+static void MuxValueSetPathStatus(const struct AudioSapmComponent *sapmComponent, struct AudioSapmpath *path,
+ const struct AudioEnumKcontrol *enumKtl, int32_t i)
+{
+ int32_t ret;
+ uint32_t val = 0;
+ uint32_t item;
+ uint32_t reg = 0;
+ uint32_t shift;
+ if ((sapmComponent == NULL || sapmComponent->codec == NULL) || (path == NULL || path->name == NULL) ||
+ (enumKtl == NULL || enumKtl->texts == NULL)) {
+ ADM_LOG_ERR("input muxValueSet params check error: cpt=%p, path=%p, enumKtl=%p.",
+ sapmComponent, path, enumKtl);
+ return;
+ }
+
+ shift = enumKtl->shiftLeft;
+
+ ret = AudioCodecReadReg(sapmComponent->codec, reg, &val);
+ if (ret != HDF_SUCCESS) {
+ ADM_LOG_ERR("muxValueSet read reg fail!");
+ return;
+ }
+
+ val = val >> shift;
+ for (item = 0; item < enumKtl->max; item++) {
+ if (val == enumKtl->values[item]) {
+ break;
+ }
+ }
+
+ path->connect = UNCONNECT_SINK_AND_SOURCE;
+ for (i = 0; i < enumKtl->max; i++) {
+ if (enumKtl->texts[i] == NULL) {
+ continue;
+ }
+
+ if ((strcmp(path->name, enumKtl->texts[i]) == 0) && item == i) {
+ path->connect = CONNECT_SINK_AND_SOURCE;
+ }
+ }
+ return;
+}
+
+static void MixerSetPathStatus(const struct AudioSapmComponent *sapmComponent, struct AudioSapmpath *path,
+ const struct AudioMixerControl *mixerCtrl)
+{
+ int32_t ret;
+ uint32_t reg;
+ uint32_t mask;
+ uint32_t shift;
+ uint32_t invert;
+ uint32_t curValue = 0;
+
+ if ((sapmComponent == NULL || sapmComponent->codec == NULL) || (path == NULL) || (mixerCtrl == NULL)) {
+ ADM_LOG_ERR("input params check error: sapmComponent=%p, path=%p, mixerCtrl=%p.",
+ sapmComponent, path, mixerCtrl);
+ return;
+ }
+
+ reg = mixerCtrl->reg;
+ shift = mixerCtrl->shift;
+ mask = mixerCtrl->mask;
+ invert = mixerCtrl->invert;
+
+ ret = AudioCodecReadReg(sapmComponent->codec, reg, &curValue);
+ if (ret != HDF_SUCCESS) {
+ ADM_LOG_ERR("read reg fail!");
+ return;
+ }
+
+ curValue = (curValue >> shift) & mask;
+ if ((invert && !curValue) || (!invert && curValue)) {
+ path->connect = CONNECT_SINK_AND_SOURCE;
+ } else {
+ path->connect = UNCONNECT_SINK_AND_SOURCE;
+ }
+
+ return;
+}
+
+static int32_t AudioSapmSetPathStatus(const struct AudioSapmComponent *sapmComponent,
+ struct AudioSapmpath *path, int32_t i)
+{
+ if ((sapmComponent == NULL) || (path == NULL)) {
+ ADM_LOG_ERR("input params check error: sapmComponent=%p, path=%p.", sapmComponent, path);
+ return HDF_FAILURE;
+ }
+ switch (sapmComponent->sapmType) {
+ case AUDIO_SAPM_MIXER:
+ case AUDIO_SAPM_ANALOG_SWITCH:
+ case AUDIO_SAPM_MIXER_NAMED_CTRL: {
+ MixerSetPathStatus(sapmComponent, path,
+ (struct AudioMixerControl *)((volatile uintptr_t)sapmComponent->kcontrolNews[i].privateValue));
+ }
+ break;
+ case AUDIO_SAPM_MUX: {
+ MuxSetPathStatus(sapmComponent, path,
+ (struct AudioEnumKcontrol *)((volatile uintptr_t)sapmComponent->kcontrolNews[i].privateValue), i);
+ }
+ break;
+ case AUDIO_SAPM_VALUE_MUX: {
+ MuxValueSetPathStatus(sapmComponent, path,
+ (struct AudioEnumKcontrol *)((volatile uintptr_t)sapmComponent->kcontrolNews[i].privateValue), i);
+ }
+ break;
+ default: {
+ path->connect = CONNECT_SINK_AND_SOURCE;
+ break;
+ }
+ }
+
+ return HDF_SUCCESS;
+}
+
+static int32_t AudioSapmConnectMixer(struct AudioCard *audioCard,
+ struct AudioSapmComponent *source, struct AudioSapmComponent *sink,
+ struct AudioSapmpath *path, const char *controlName)
+{
+ int i = 0;
+
+ if ((audioCard == NULL) || (source == NULL) || (sink == NULL) ||
+ (path == NULL) || (controlName == NULL)) {
+ ADM_LOG_ERR("input params check error: audioCard=%p, source=%p, sink=%p, path=%p, controlName=%p.",
+ audioCard, source, sink, path, controlName);
+ return HDF_FAILURE;
+ }
+
+ for (i = 0; i < sink->kcontrolsNum; i++) {
+ if (sink->kcontrolNews[i].name == NULL) {
+ continue;
+ }
+
+ if (strcmp(controlName, sink->kcontrolNews[i].name) == 0) {
+ path->name = (char *)OsalMemCalloc(strlen(sink->kcontrolNews[i].name) + 1);
+ if (path->name == NULL) {
+ ADM_LOG_ERR("malloc path->name fail!");
+ return HDF_FAILURE;
+ }
+ if (memcpy_s(path->name, strlen(sink->kcontrolNews[i].name) + 1, sink->kcontrolNews[i].name,
+ strlen(sink->kcontrolNews[i].name) + 1) != EOK) {
+ OsalMemFree(path->name);
+ ADM_LOG_ERR("memcpy cpt->componentName fail!");
+ return HDF_FAILURE;
+ }
+ DListInsertHead(&path->list, &audioCard->paths);
+ DListInsertHead(&path->listSink, &sink->sources);
+ DListInsertHead(&path->listSource, &source->sinks);
+
+ AudioSapmSetPathStatus(sink, path, i);
+
+ return HDF_SUCCESS;
+ }
+ }
+
+ return HDF_FAILURE;
+}
+
+static int32_t AudioSampStaticOrDynamicPath(struct AudioCard *audioCard,
+ struct AudioSapmComponent *source, struct AudioSapmComponent *sink,
+ struct AudioSapmpath *path, const struct AudioSapmRoute *route)
+{
+ int32_t ret;
+
+ if ((audioCard == NULL) || (source == NULL) || (sink == NULL) || (path == NULL) || (route == NULL)) {
+ ADM_LOG_ERR("input params check error: audioCard=%p, source=%p, sink=%p, path=%p, route=%p.",
+ audioCard, source, sink, path, route);
+ return HDF_FAILURE;
+ }
+
+ if (route->control == NULL) {
+ DListInsertHead(&path->list, &audioCard->paths);
+ DListInsertHead(&path->listSink, &sink->sources);
+ DListInsertHead(&path->listSource, &source->sinks);
+ path->connect = CONNECT_SINK_AND_SOURCE;
+ return HDF_SUCCESS;
+ }
+
+ switch (sink->sapmType) {
+ case AUDIO_SAPM_MUX:
+ case AUDIO_SAPM_VIRT_MUX:
+ case AUDIO_SAPM_VALUE_MUX:
+ break;
+ case AUDIO_SAPM_ANALOG_SWITCH:
+ case AUDIO_SAPM_MIXER:
+ case AUDIO_SAPM_MIXER_NAMED_CTRL:
+ case AUDIO_SAPM_PGA:
+ case AUDIO_SAPM_SPK:
+ ret = AudioSapmConnectMixer(audioCard, source, sink, path, route->control);
+ if (ret != HDF_SUCCESS) {
+ ADM_LOG_ERR("connect mixer fail!");
+ return HDF_FAILURE;
+ }
+ break;
+ case AUDIO_SAPM_HP:
+ case AUDIO_SAPM_MIC:
+ case AUDIO_SAPM_LINE:
+ DListInsertHead(&path->list, &audioCard->paths);
+ DListInsertHead(&path->listSink, &sink->sources);
+ DListInsertHead(&path->listSource, &source->sinks);
+ path->connect = CONNECT_SINK_AND_SOURCE;
+ break;
+ default:
+ DListInsertHead(&path->list, &audioCard->paths);
+ DListInsertHead(&path->listSink, &sink->sources);
+ DListInsertHead(&path->listSource, &source->sinks);
+ path->connect = CONNECT_SINK_AND_SOURCE;
+ break;
+ }
+
+ return HDF_SUCCESS;
+}
+
+static void AudioSampExtComponentsCheck(struct AudioSapmComponent *cptSource, struct AudioSapmComponent *cptSink)
+{
+ if ((cptSource == NULL) || (cptSink == NULL)) {
+ ADM_LOG_ERR("input params check error: cptSource=%p, cptSink=%p.", cptSource, cptSink);
+ return;
+ }
+
+ /* check for external components */
+ if (cptSink->sapmType == AUDIO_SAPM_INPUT) {
+ if (cptSource->sapmType == AUDIO_SAPM_MICBIAS || cptSource->sapmType == AUDIO_SAPM_MIC ||
+ cptSource->sapmType == AUDIO_SAPM_LINE || cptSource->sapmType == AUDIO_SAPM_OUTPUT) {
+ cptSink->external = EXIST_EXTERNAL_WIDGET;
+ }
+ }
+ if (cptSource->sapmType == AUDIO_SAPM_OUTPUT) {
+ if (cptSink->sapmType == AUDIO_SAPM_SPK || cptSink->sapmType == AUDIO_SAPM_HP ||
+ cptSink->sapmType == AUDIO_SAPM_LINE || cptSink->sapmType == AUDIO_SAPM_INPUT) {
+ cptSource->external = EXIST_EXTERNAL_WIDGET;
+ }
+ }
+
+ return;
+}
+static int32_t AudioSapmAddRoute(struct AudioCard *audioCard, const struct AudioSapmRoute *route)
+{
+ struct AudioSapmpath *path = NULL;
+ struct AudioSapmComponent *cptSource = NULL;
+ struct AudioSapmComponent *cptSink = NULL;
+ struct AudioSapmComponent *sapmComponent = NULL;
+ int32_t ret;
+
+ if ((audioCard == NULL) || (route == NULL || route->source == NULL || route->sink == NULL)) {
+ ADM_LOG_ERR("input params check error: audioCard=%p, route=%p.", audioCard, route);
+ return HDF_FAILURE;
+ }
+
+ DLIST_FOR_EACH_ENTRY(sapmComponent, &audioCard->components, struct AudioSapmComponent, list) {
+ if (sapmComponent->componentName == NULL) {
+ continue;
+ }
+ if ((cptSource == NULL) && (strcmp(sapmComponent->componentName, route->source) == 0)) {
+ cptSource = sapmComponent;
+ continue;
+ }
+ if ((cptSink == NULL) && (strcmp(sapmComponent->componentName, route->sink) == 0)) {
+ cptSink = sapmComponent;
+ }
+ if ((cptSource != NULL) && (cptSink != NULL)) {
+ break;
+ }
+ }
+ if ((cptSource == NULL) || (cptSink == NULL)) {
+ ADM_LOG_ERR("find component fail!");
+ return HDF_FAILURE;
+ }
+
+ path = (struct AudioSapmpath *)OsalMemCalloc(sizeof(struct AudioSapmpath));
+ if (path == NULL) {
+ ADM_LOG_ERR("malloc path fail!");
+ return HDF_FAILURE;
+ }
+ path->source = cptSource;
+ path->sink = cptSink;
+ DListHeadInit(&path->list);
+ DListHeadInit(&path->listSink);
+ DListHeadInit(&path->listSource);
+
+ /* check for external components */
+ AudioSampExtComponentsCheck(cptSource, cptSink);
+
+ ret = AudioSampStaticOrDynamicPath(audioCard, cptSource, cptSink, path, route);
+ if (ret != HDF_SUCCESS) {
+ OsalMemFree(path);
+ ADM_LOG_ERR("static or dynamic path fail!");
+ return HDF_FAILURE;
+ }
+ return HDF_SUCCESS;
+}
+
+int32_t AudioSapmAddRoutes(struct AudioCard *audioCard, const struct AudioSapmRoute *route, int32_t routeMaxNum)
+{
+ int32_t i;
+ int32_t ret;
+
+ if ((audioCard == NULL) || (route == NULL)) {
+ ADM_LOG_ERR("input params check error: audioCard=%p, route=%p.", audioCard, route);
+ return HDF_FAILURE;
+ }
+
+ for (i = 0; i < routeMaxNum; i++) {
+ ret = AudioSapmAddRoute(audioCard, route);
+ if (ret != HDF_SUCCESS) {
+ ADM_LOG_ERR("AudioSapmAddRoute failed!");
+ return HDF_FAILURE;
+ }
+ route++;
+ }
+ return HDF_SUCCESS;
+}
+
+int32_t AudioSapmNewMixerControls(struct AudioSapmComponent *sapmComponent, struct AudioCard *audioCard)
+{
+ struct AudioSapmpath *path = NULL;
+ int32_t i;
+
+ if (sapmComponent == NULL || audioCard == NULL) {
+ ADM_LOG_ERR("input params check error: sapmComponent=%p, audioCard=%p.", sapmComponent, audioCard);
+ return HDF_FAILURE;
+ }
+
+ for (i = 0; i < sapmComponent->kcontrolsNum; i++) {
+ DLIST_FOR_EACH_ENTRY(path, &sapmComponent->sources, struct AudioSapmpath, listSink) {
+ if (path->name == NULL || sapmComponent->kcontrolNews[i].name == NULL) {
+ continue;
+ }
+
+ if (strcmp(path->name, sapmComponent->kcontrolNews[i].name) != 0) {
+ continue;
+ }
+
+ path->kcontrol = AudioAddControl(audioCard, &sapmComponent->kcontrolNews[i]);
+ if (path->kcontrol == NULL) {
+ ADM_LOG_ERR("add control fail!");
+ return HDF_FAILURE;
+ }
+ sapmComponent->kcontrols[i] = path->kcontrol;
+ DListInsertHead(&sapmComponent->kcontrols[i]->list, &audioCard->controls);
+ }
+ }
+
+ return HDF_SUCCESS;
+}
+
+int AudioSapmNewMuxControls(struct AudioSapmComponent *sapmComponent, struct AudioCard *audioCard)
+{
+ struct AudioKcontrol *kctrl = NULL;
+
+ if (sapmComponent == NULL || sapmComponent->kcontrolNews == NULL || audioCard == NULL) {
+ ADM_LOG_ERR("input param is NULL.");
+ return HDF_FAILURE;
+ }
+
+ if (sapmComponent->kcontrolsNum != 1) {
+ ADM_LOG_ERR("incorrect number of controls.");
+ return HDF_FAILURE;
+ }
+
+ kctrl = AudioAddControl(audioCard, &sapmComponent->kcontrolNews[0]);
+ if (kctrl == NULL) {
+ ADM_LOG_ERR("add control fail!");
+ return HDF_FAILURE;
+ }
+ sapmComponent->kcontrols[0] = kctrl;
+ DListInsertHead(&sapmComponent->kcontrols[0]->list, &audioCard->controls);
+
+ return HDF_SUCCESS;
+}
+
+static void AudioSapmPowerSeqInsert(struct AudioSapmComponent *newSapmComponent,
+ struct DListHead *list, int8_t isPowerUp)
+{
+ struct AudioSapmComponent *sapmComponent = NULL;
+ int32_t *seq = {0};
+
+ if (newSapmComponent == NULL || list == NULL || newSapmComponent->componentName == NULL) {
+ ADM_LOG_ERR("input param newCpt is NULL.");
+ return;
+ }
+
+ if (isPowerUp) {
+ seq = g_audioSapmPowerUpSeq;
+ } else {
+ seq = g_audioSapmPowerDownSeq;
+ }
+
+ DLIST_FOR_EACH_ENTRY(sapmComponent, list, struct AudioSapmComponent, powerList) {
+ if ((seq[newSapmComponent->sapmType] - seq[sapmComponent->sapmType]) < 0) {
+ DListInsertTail(&newSapmComponent->powerList, &sapmComponent->powerList);
+ return;
+ }
+ }
+ DListInsertTail(&newSapmComponent->powerList, list);
+
+ ADM_LOG_DEBUG("[%s] success.", newSapmComponent->componentName);
+ return;
+}
+
+static void AudioSapmSetPower(struct AudioCard *audioCard, struct AudioSapmComponent *sapmComponent,
+ uint8_t power, struct DListHead *upList, struct DListHead *downList)
+{
+ struct AudioSapmpath *path = NULL;
+
+ if (sapmComponent == NULL) {
+ ADM_LOG_ERR("input param sapmComponent is NULL.");
+ return;
+ }
+
+ DLIST_FOR_EACH_ENTRY(path, &sapmComponent->sources, struct AudioSapmpath, listSink) {
+ if (path->source != NULL) {
+ if ((path->source->power != power) && path->connect) {
+ if (DListIsEmpty(&path->source->dirty)) {
+ DListInsertTail(&path->source->dirty, &audioCard->sapmDirty);
+ }
+ }
+ }
+ }
+ DLIST_FOR_EACH_ENTRY(path, &sapmComponent->sinks, struct AudioSapmpath, listSource) {
+ if (path->sink != NULL) {
+ if ((path->sink->power != power) && path->connect) {
+ if (DListIsEmpty(&path->sink->dirty)) {
+ DListInsertTail(&path->sink->dirty, &audioCard->sapmDirty);
+ }
+ }
+ }
+ }
+
+ if (power) {
+ AudioSapmPowerSeqInsert(sapmComponent, upList, power);
+ } else {
+ AudioSapmPowerSeqInsert(sapmComponent, downList, power);
+ }
+
+ return;
+}
+
+static void AudioSapmPowerUpSeqRun(const struct DListHead *list)
+{
+ uint32_t val;
+ struct AudioMixerControl mixerControl;
+ struct AudioSapmComponent *sapmComponent = NULL;
+ if (list == NULL) {
+ ADM_LOG_ERR("input param list is NULL.");
+ return;
+ }
+
+ DLIST_FOR_EACH_ENTRY(sapmComponent, list, struct AudioSapmComponent, powerList) {
+ if ((sapmComponent->reg >= 0) && (sapmComponent->power == SAPM_POWER_DOWN)) {
+ val = SAPM_POWER_UP;
+ sapmComponent->power = SAPM_POWER_UP;
+ mixerControl.reg = sapmComponent->reg;
+ mixerControl.mask = sapmComponent->mask;
+ mixerControl.shift = sapmComponent->shift;
+ if (sapmComponent->invert) {
+ val = !val;
+ }
+ if (sapmComponent->codec != NULL) {
+ AudioUpdateCodecRegBits(sapmComponent->codec, &mixerControl, val);
+ ADM_LOG_DEBUG("Sapm Codec Power Up.");
+ }
+ if (sapmComponent->accessory != NULL) {
+ AudioUpdateAccessoryRegBits(sapmComponent->accessory, &mixerControl, val);
+ ADM_LOG_DEBUG("Sapm Accessory Power Up.");
+ }
+ }
+ }
+
+ return;
+}
+
+static void AudioSapmPowerDownSeqRun(const struct DListHead *list)
+{
+ uint32_t val;
+ struct AudioMixerControl mixerControl;
+ struct AudioSapmComponent *sapmComponent = NULL;
+ ADM_LOG_DEBUG("entry!");
+
+ if (list == NULL) {
+ ADM_LOG_ERR("input param list is NULL.");
+ return;
+ }
+
+ DLIST_FOR_EACH_ENTRY(sapmComponent, list, struct AudioSapmComponent, powerList) {
+ if ((sapmComponent->reg >= 0) && (sapmComponent->power == SAPM_POWER_UP)) {
+ val = SAPM_POWER_DOWN;
+ sapmComponent->power = SAPM_POWER_DOWN;
+ mixerControl.mask = sapmComponent->mask;
+ mixerControl.reg = sapmComponent->reg;
+ mixerControl.shift = sapmComponent->shift;
+ if (sapmComponent->invert) {
+ val = !val;
+ }
+ if (sapmComponent->codec != NULL) {
+ AudioUpdateCodecRegBits(sapmComponent->codec, &mixerControl, val);
+ ADM_LOG_DEBUG("Sapm Codec Power Down.");
+ }
+ if (sapmComponent->accessory != NULL) {
+ AudioUpdateAccessoryRegBits(sapmComponent->accessory, &mixerControl, val);
+ ADM_LOG_DEBUG("Sapm Accessory Power Down.");
+ }
+ }
+ }
+
+ return;
+}
+
+int AudioSapmPowerComponents(struct AudioCard *audioCard)
+{
+ struct AudioSapmComponent *sapmComponent = NULL;
+ struct DListHead upList;
+ struct DListHead downList;
+ ADM_LOG_DEBUG("entry!");
+
+ if (audioCard == NULL) {
+ ADM_LOG_ERR("input param audioCard is NULL.");
+ return HDF_FAILURE;
+ }
+
+ DListHeadInit(&upList);
+ DListHeadInit(&downList);
+
+ DLIST_FOR_EACH_ENTRY(sapmComponent, &audioCard->sapmDirty, struct AudioSapmComponent, dirty) {
+ sapmComponent->newPower = sapmComponent->PowerCheck(sapmComponent);
+ if (sapmComponent->newPower == sapmComponent->power) {
+ continue;
+ }
+
+ if (g_audioSapmIsStandby && sapmComponent->PowerClockOp != NULL) {
+ sapmComponent->PowerClockOp(sapmComponent);
+ }
+
+ AudioSapmSetPower(audioCard, sapmComponent, sapmComponent->newPower, &upList, &downList);
+ }
+
+ DLIST_FOR_EACH_ENTRY(sapmComponent, &audioCard->components, struct AudioSapmComponent, list) {
+ DListRemove(&sapmComponent->dirty);
+ DListHeadInit(&sapmComponent->dirty);
+ }
+
+ AudioSapmPowerDownSeqRun(&downList);
+ AudioSapmPowerUpSeqRun(&upList);
+
+ return HDF_SUCCESS;
+}
+
+static void ReadInitComponentPowerStatus(struct AudioSapmComponent *sapmComponent)
+{
+ int32_t ret;
+ uint32_t regVal = 0;
+
+ if (sapmComponent == NULL || sapmComponent->codec == NULL) {
+ ADM_LOG_ERR("input param sapmComponent is NULL.");
+ return;
+ }
+
+ if (sapmComponent->reg >= 0) {
+ ret = AudioCodecReadReg(sapmComponent->codec, sapmComponent->reg, ®Val);
+ if (ret != HDF_SUCCESS) {
+ ADM_LOG_ERR("read reg fail!");
+ return;
+ }
+ regVal &= 1 << sapmComponent->shift;
+
+ if (sapmComponent->invert) {
+ regVal = !regVal;
+ }
+
+ if (regVal) {
+ sapmComponent->power = SAPM_POWER_UP;
+ } else {
+ sapmComponent->power = SAPM_POWER_DOWN;
+ }
+ }
+
+ return;
+}
+
+int32_t AudioSapmSleep(const struct AudioCard *audioCard)
+{
+ if (audioCard == NULL) {
+ ADM_LOG_ERR("input param audioCard is NULL.");
+ return HDF_ERR_INVALID_OBJECT;
+ }
+
+ if (g_sleepTimer.realTimer != NULL) {
+ OsalTimerDelete(&g_sleepTimer);
+ }
+ OsalTimerCreate(&g_sleepTimer, SAPM_POLL_TIME, AudioSapmEnterSleep, (uintptr_t)audioCard);
+ OsalTimerStartLoop(&g_sleepTimer);
+ AudioSapmRefreshTime(true);
+
+ return HDF_SUCCESS;
+}
+
+int32_t AudioSapmNewControls(struct AudioCard *audioCard)
+{
+ struct AudioSapmComponent *sapmComponent = NULL;
+ int ret = HDF_SUCCESS;
+
+ if (audioCard == NULL) {
+ ADM_LOG_ERR("input param audioCard is NULL.");
+ return HDF_ERR_INVALID_OBJECT;
+ }
+
+ DLIST_FOR_EACH_ENTRY(sapmComponent, &audioCard->components, struct AudioSapmComponent, list) {
+ if (sapmComponent->newCpt) {
+ continue;
+ }
+ if (sapmComponent->kcontrolsNum > 0) {
+ sapmComponent->kcontrols = OsalMemCalloc(sizeof(struct AudioKcontrol*) * sapmComponent->kcontrolsNum);
+ if (sapmComponent->kcontrols == NULL) {
+ ADM_LOG_ERR("malloc kcontrols fail!");
+ return HDF_FAILURE;
+ }
+ }
+
+ switch (sapmComponent->sapmType) {
+ case AUDIO_SAPM_ANALOG_SWITCH:
+ case AUDIO_SAPM_MIXER:
+ case AUDIO_SAPM_MIXER_NAMED_CTRL:
+ case AUDIO_SAPM_SPK:
+ case AUDIO_SAPM_PGA:
+ ret = AudioSapmNewMixerControls(sapmComponent, audioCard);
+ break;
+ case AUDIO_SAPM_MUX:
+ case AUDIO_SAPM_VIRT_MUX:
+ case AUDIO_SAPM_VALUE_MUX:
+ ret = AudioSapmNewMuxControls(sapmComponent, audioCard);
+ break;
+ default:
+ ret = HDF_SUCCESS;
+ break;
+ }
+ if (ret != HDF_SUCCESS) {
+ OsalMemFree(sapmComponent->kcontrols);
+ ADM_LOG_ERR("sapm new mixer or mux controls fail!");
+ return HDF_FAILURE;
+ }
+
+ ReadInitComponentPowerStatus(sapmComponent);
+ sapmComponent->newCpt = 1;
+ DListInsertTail(&sapmComponent->dirty, &audioCard->sapmDirty);
+ }
+
+ ret = AudioSapmPowerComponents(audioCard);
+ if (ret != HDF_SUCCESS) {
+ ADM_LOG_ERR("sapm power component fail!");
+ return HDF_FAILURE;
+ }
+
+ return HDF_SUCCESS;
+}
+
+static int32_t MixerUpdatePowerStatus(const struct AudioKcontrol *kcontrol, uint32_t pathStatus)
+{
+ struct AudioCard *audioCard = NULL;
+ struct AudioSapmpath *path = NULL;
+ int ret = HDF_SUCCESS;
+
+ if (kcontrol == NULL || kcontrol->pri == NULL) {
+ ADM_LOG_ERR("input param kcontrol is NULL.");
+ return HDF_ERR_INVALID_OBJECT;
+ }
+ audioCard = (struct AudioCard *)((volatile uintptr_t)(kcontrol->pri));
+
+ DLIST_FOR_EACH_ENTRY(path, &audioCard->paths, struct AudioSapmpath, list) {
+ if (path->kcontrol != kcontrol) {
+ continue;
+ }
+ if (path->sink == NULL || path->source == NULL) {
+ ADM_LOG_ERR("get path sink or source fail!");
+ return HDF_FAILURE;
+ }
+ if (path->sink->sapmType != AUDIO_SAPM_MIXER &&
+ path->sink->sapmType != AUDIO_SAPM_MIXER_NAMED_CTRL &&
+ path->sink->sapmType != AUDIO_SAPM_PGA &&
+ path->sink->sapmType != AUDIO_SAPM_SPK &&
+ path->sink->sapmType != AUDIO_SAPM_ANALOG_SWITCH) {
+ ADM_LOG_DEBUG("no mixer device.");
+ return HDF_DEV_ERR_NO_DEVICE;
+ }
+ path->connect = pathStatus;
+ DListInsertTail(&path->source->dirty, &audioCard->sapmDirty);
+ DListInsertTail(&path->sink->dirty, &audioCard->sapmDirty);
+ break;
+ }
+
+ ret = AudioSapmPowerComponents(audioCard);
+ if (ret != HDF_SUCCESS) {
+ ADM_LOG_ERR("sapm power component fail!");
+ return HDF_FAILURE;
+ }
+
+ return HDF_SUCCESS;
+}
+
+int32_t AudioCodecSapmGetCtrlOps(const struct AudioKcontrol *kcontrol, struct AudioCtrlElemValue *elemValue)
+{
+ if (AudioCodecGetCtrlOps(kcontrol, elemValue) != HDF_SUCCESS) {
+ ADM_LOG_ERR("Audio codec sapm get control switch is fail!");
+ return HDF_FAILURE;
+ }
+
+ return HDF_SUCCESS;
+}
+
+int32_t AudioAccessorySapmGetCtrlOps(const struct AudioKcontrol *kcontrol, struct AudioCtrlElemValue *elemValue)
+{
+ if (AudioAccessoryGetCtrlOps(kcontrol, elemValue) != HDF_SUCCESS) {
+ ADM_LOG_ERR("Audio accessory sapm get control switch is fail!");
+ return HDF_FAILURE;
+ }
+
+ return HDF_SUCCESS;
+}
+
+/* 1.first user specify old component -- power down; 2.second user specify new component -- power up */
+static int32_t AudioSapmSetCtrlOps(const struct AudioKcontrol *kcontrol, const struct AudioCtrlElemValue *elemValue,
+ uint32_t *value, uint32_t *pathStatus)
+{
+ struct AudioMixerControl *mixerCtrl = NULL;
+ int iFlag = (kcontrol == NULL) || (kcontrol->privateValue <= 0) || (elemValue == NULL)
+ || (value == NULL) || (pathStatus == NULL);
+ if (iFlag) {
+ ADM_LOG_ERR("input params invalid.");
+ return HDF_ERR_INVALID_OBJECT;
+ }
+
+ mixerCtrl = (struct AudioMixerControl *)((volatile uintptr_t)kcontrol->privateValue);
+ *value = elemValue->value[0];
+ if (*value < mixerCtrl->min || *value > mixerCtrl->max) {
+ ADM_LOG_ERR("value is invalid.");
+ return HDF_ERR_INVALID_OBJECT;
+ }
+ if (mixerCtrl->invert) {
+ *value = mixerCtrl->max - *value;
+ }
+ if (*value) {
+ *pathStatus = CONNECT_SINK_AND_SOURCE;
+ } else {
+ *pathStatus = UNCONNECT_SINK_AND_SOURCE;
+ }
+
+ return HDF_SUCCESS;
+}
+
+int32_t AudioCodecSapmSetCtrlOps(const struct AudioKcontrol *kcontrol, const struct AudioCtrlElemValue *elemValue)
+{
+ uint32_t curValue = 0;
+ uint32_t value;
+ uint32_t pathStatus = 0;
+ struct CodecDevice *codec = NULL;
+ struct AudioMixerControl *mixerCtrl = NULL;
+ if ((kcontrol == NULL) || (kcontrol->privateValue <= 0) || (elemValue == NULL)) {
+ ADM_LOG_ERR("input params: kcontrol is NULL or elemValue=%p.", elemValue);
+ return HDF_ERR_INVALID_OBJECT;
+ }
+
+ mixerCtrl = (struct AudioMixerControl *)((volatile uintptr_t)kcontrol->privateValue);
+ if (AudioSapmSetCtrlOps(kcontrol, elemValue, &value, &pathStatus) != HDF_SUCCESS) {
+ ADM_LOG_ERR("Audio sapm put control switch fail!");
+ }
+ codec = AudioKcontrolGetCodec(kcontrol);
+ if (AudioCodecReadReg(codec, mixerCtrl->reg, &curValue) != HDF_SUCCESS) {
+ ADM_LOG_ERR("Device read register is failure!");
+ return HDF_FAILURE;
+ }
+ if (MixerUpdatePowerStatus(kcontrol, pathStatus) != HDF_SUCCESS) {
+ ADM_LOG_ERR("update power status is failure!");
+ return HDF_FAILURE;
+ }
+
+ curValue &= mixerCtrl->mask << mixerCtrl->shift;
+ value = (value & mixerCtrl->mask) << mixerCtrl->shift;
+ if (curValue != value) {
+ if (AudioUpdateCodecRegBits(codec, mixerCtrl, elemValue->value[0]) != HDF_SUCCESS) {
+ ADM_LOG_ERR("update reg bits fail!");
+ return HDF_FAILURE;
+ }
+ }
+ return HDF_SUCCESS;
+}
+
+/* 1.first user specify old component -- power down; 2.second user specify new component -- power up */
+int32_t AudioAccessorySapmSetCtrlOps(const struct AudioKcontrol *kcontrol, const struct AudioCtrlElemValue *elemValue)
+{
+ uint32_t curValue = 0;
+ uint32_t value = 0;
+ uint32_t pathStatus = 0;
+ struct AccessoryDevice *accessory = NULL;
+ struct AudioMixerControl *mixerCtrl = NULL;
+ if ((kcontrol == NULL) || (kcontrol->privateValue <= 0) || (elemValue == NULL)) {
+ ADM_LOG_ERR("input params: kcontrol is NULL or elemValue=%p.", elemValue);
+ return HDF_ERR_INVALID_OBJECT;
+ }
+
+ mixerCtrl = (struct AudioMixerControl *)((volatile uintptr_t)kcontrol->privateValue);
+ if (AudioSapmSetCtrlOps(kcontrol, elemValue, &value, &pathStatus) != HDF_SUCCESS) {
+ ADM_LOG_ERR("Audio sapm put control switch fail!");
+ }
+ accessory = AudioKcontrolGetAccessory(kcontrol);
+ if (AudioAccessoryReadReg(accessory, mixerCtrl->reg, &curValue) != HDF_SUCCESS) {
+ ADM_LOG_ERR("Device read fail!");
+ return HDF_FAILURE;
+ }
+ curValue &= mixerCtrl->mask << mixerCtrl->shift;
+ value = (value & mixerCtrl->mask) << mixerCtrl->shift;
+ if (curValue != value) {
+ if (MixerUpdatePowerStatus(kcontrol, pathStatus) != HDF_SUCCESS) {
+ ADM_LOG_ERR("update power status fail!");
+ return HDF_FAILURE;
+ }
+ if (AudioUpdateAccessoryRegBits(accessory, mixerCtrl, elemValue->value[0]) != HDF_SUCCESS) {
+ ADM_LOG_ERR("update reg bits fail!");
+ return HDF_FAILURE;
+ }
+ }
+
+ return HDF_SUCCESS;
+}
+
+uint64_t AudioSapmRefreshTime(bool bRefresh)
+{
+ static uint64_t time = 0;
+
+ if (bRefresh) {
+ time = OsalGetSysTimeMs();
+ g_audioSapmIsSleep = false;
+ }
+ return time;
+}
+
+static bool AudioSapmCheckTime(void)
+{
+ uint64_t diffTime = OsalGetSysTimeMs() - AudioSapmRefreshTime(false);
+ if (diffTime > SAPM_SLEEP_TIME) {
+ return true;
+ } else if (diffTime < 0) {
+ AudioSapmRefreshTime(true);
+ }
+ return false;
+}
+
+int32_t AudioSampPowerUp(const struct AudioCard *card)
+{
+ struct DListHead upList;
+ struct AudioSapmComponent *sapmComponent = NULL;
+
+ if (card == NULL) {
+ ADM_LOG_ERR("input params is null.");
+ return HDF_ERR_INVALID_OBJECT;
+ }
+
+ DListHeadInit(&upList);
+ DLIST_FOR_EACH_ENTRY(sapmComponent, &card->components, struct AudioSapmComponent, list) {
+ if (sapmComponent->power == SAPM_POWER_DOWN) {
+ AudioSapmPowerSeqInsert(sapmComponent, &upList, SAPM_POWER_UP);
+ }
+ }
+ AudioSapmPowerUpSeqRun(&upList);
+ return HDF_SUCCESS;
+}
+
+int32_t AudioSampSetPowerMonitor(struct AudioCard *card, bool powerMonitorState)
+{
+ if (card == NULL) {
+ ADM_LOG_ERR("input params is null.");
+ return HDF_ERR_INVALID_OBJECT;
+ }
+ AudioSapmRefreshTime(true);
+ card->sapmMonitorState = powerMonitorState;
+ return HDF_SUCCESS;
+}
+
+static void AudioSapmEnterSleepSub(uintptr_t para, struct AudioSapmComponent *sapmComponent)
+{
+ struct DListHead downList;
+ struct AudioCard *audioCard = (struct AudioCard *)para;
+ ADM_LOG_INFO("entry!");
+
+ DListHeadInit(&downList);
+ if (audioCard == NULL) {
+ ADM_LOG_ERR("audioCard is null.");
+ return;
+ }
+ DLIST_FOR_EACH_ENTRY(sapmComponent, &audioCard->components, struct AudioSapmComponent, list) {
+ if (sapmComponent == NULL) {
+ continue;
+ }
+ if (sapmComponent->power == SAPM_POWER_UP) {
+ AudioSapmPowerSeqInsert(sapmComponent, &downList, SAPM_POWER_DOWN);
+ }
+ }
+ AudioSapmPowerDownSeqRun(&downList);
+ g_audioSapmIsSleep = true;
+}
+
+static void AudioSapmEnterSleep(uintptr_t para)
+{
+ struct AudioSapmComponent *sapmComponent = NULL;
+ struct AudioCard *audioCard = (struct AudioCard *)para;
+#ifndef __LITEOS__
+ ADM_LOG_DEBUG("entry!");
+#endif
+
+ if (audioCard == NULL) {
+ return;
+ }
+ if (g_audioSapmIsSleep == true) {
+ return;
+ }
+
+ if (audioCard->sapmMonitorState == false) {
+ return;
+ }
+
+ if (!AudioSapmCheckTime()) {
+ return;
+ }
+
+ DLIST_FOR_EACH_ENTRY(sapmComponent, &audioCard->components, struct AudioSapmComponent, list) {
+ if (sapmComponent->PowerClockOp != NULL) {
+ if (g_audioSapmIsStandby == false) {
+ sapmComponent->PowerClockOp(sapmComponent);
+ g_audioSapmIsStandby = true;
+ AudioSapmRefreshTime(true);
+ }
+ }
+ }
+ if (g_audioSapmIsStandby == true) {
+ if (!AudioSapmCheckTime()) {
+ return;
+ }
+ g_audioSapmIsStandby = false;
+ }
+
+ AudioSapmEnterSleepSub(para, sapmComponent);
+}
diff --git a/model/audio/sapm/test/unittest/common/audio_sapm_test.cpp b/model/audio/sapm/test/unittest/common/audio_sapm_test.cpp
new file mode 100755
index 0000000000000000000000000000000000000000..7d700a9daad2029db9bf27da8cd7f4659d900f27
--- /dev/null
+++ b/model/audio/sapm/test/unittest/common/audio_sapm_test.cpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 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 "audio_common_test.h"
+#include
+#include "hdf_uhdf_test.h"
+
+using namespace testing::ext;
+
+class AudioSapmTest : public testing::Test {
+public:
+ static void SetUpTestCase();
+ static void TearDownTestCase();
+ void SetUp();
+ void TearDown();
+};
+
+void AudioSapmTest::SetUpTestCase()
+{
+ HdfTestOpenService();
+}
+
+void AudioSapmTest::TearDownTestCase()
+{
+ HdfTestCloseService();
+}
+
+void AudioSapmTest::SetUp()
+{
+}
+
+void AudioSapmTest::TearDown()
+{
+}
+
+HWTEST_F(AudioSapmTest, AudioSapmTest001, TestSize.Level0)
+{
+ struct HdfTestMsg msg = {g_testAudioType, TESTNEWCOMPONENT, -1};
+ EXPECT_EQ(0, HdfTestSendMsgToService(&msg));
+}
+
+HWTEST_F(AudioSapmTest, AudioSapmTest002, TestSize.Level0)
+{
+ struct HdfTestMsg msg = {g_testAudioType, TESTADDROUTES, -1};
+ EXPECT_EQ(0, HdfTestSendMsgToService(&msg));
+}
+
+HWTEST_F(AudioSapmTest, AudioSapmTest003, TestSize.Level0)
+{
+ struct HdfTestMsg msg = {g_testAudioType, TESTNEWCONTROLS, -1};
+ EXPECT_EQ(0, HdfTestSendMsgToService(&msg));
+}
+
+HWTEST_F(AudioSapmTest, AudioSapmTest004, TestSize.Level0)
+{
+ struct HdfTestMsg msg = {g_testAudioType, TESTPOWERCOMPONET, -1};
+ EXPECT_EQ(0, HdfTestSendMsgToService(&msg));
+}
+
+HWTEST_F(AudioSapmTest, AudioSapmTest005, TestSize.Level0)
+{
+ struct HdfTestMsg msg = {g_testAudioType, TESTREFRESHTIME, -1};
+ EXPECT_EQ(0, HdfTestSendMsgToService(&msg));
+}
diff --git a/model/display/driver/hi35xx_disp.c b/model/display/driver/adapter_soc/hi35xx_disp.c
similarity index 52%
rename from model/display/driver/hi35xx_disp.c
rename to model/display/driver/adapter_soc/hi35xx_disp.c
index 98ddc0e3e9bdf2c205d583ef1795054c527c30ee..7ab604b465e853b03347fe3a676ed3d68e246bfb 100644
--- a/model/display/driver/hi35xx_disp.c
+++ b/model/display/driver/adapter_soc/hi35xx_disp.c
@@ -12,20 +12,12 @@
#include "hdf_device_desc.h"
#include "hdf_disp.h"
#include "hdf_log.h"
-#include "lcd_abs_if.h"
#include "osal_io.h"
-#include "osal_mem.h"
#include "pwm_if.h"
#define TRANSFORM_KILO 1000
#define TRANSFORM_MILL 1000000
-struct Hi35xxDispCtrl {
- struct DispControl ctrl;
- unsigned long mipiCfgBase;
- unsigned long pwmCfgBase;
-};
-
static void MipiMuxCfg(unsigned long ioCfgBase)
{
/* config dsi data lane0 */
@@ -107,11 +99,11 @@ void Lcd24BitMuxCfg(unsigned long ioCfgBase)
OSAL_WRITEL(0x532, ioCfgBase + 0x0030);
}
-static void LcdPinMuxCfg(const struct Hi35xxDispCtrl *hi35xxCtrl, uint32_t intf)
+static void LcdPinMuxCfg(uint32_t intf)
{
unsigned long ioCfgBase;
- ioCfgBase = hi35xxCtrl->mipiCfgBase;
+ ioCfgBase = (unsigned long)OsalIoRemap(IO_CFG2_BASE, IO_CFG_SIZE);
if (intf == MIPI_DSI) {
MipiMuxCfg(ioCfgBase);
} else if (intf == LCD_6BIT) {
@@ -125,12 +117,11 @@ static void LcdPinMuxCfg(const struct Hi35xxDispCtrl *hi35xxCtrl, uint32_t intf)
}
}
-static void PwmPinMuxCfg(const struct Hi35xxDispCtrl *hi35xxCtrl, uint32_t dev)
+static void PwmPinMuxCfg(uint32_t dev)
{
/* pwm pin config */
unsigned long ioCfgBase;
-
- ioCfgBase = hi35xxCtrl->pwmCfgBase;
+ ioCfgBase = (unsigned long)OsalIoRemap(IO_CFG1_BASE, IO_CFG_SIZE);
switch (dev) {
case PWM_DEV0:
OSAL_WRITEL(0x601, ioCfgBase + 0x0024);
@@ -206,7 +197,7 @@ static uint32_t CalcDataRate(struct PanelInfo *info)
static int32_t MipiDsiInit(struct PanelInfo *info)
{
int32_t ret;
- struct DevHandle *mipiHandle = NULL;
+ DevHandle mipiHandle = NULL;
struct MipiCfg cfg;
mipiHandle = MipiDsiOpen(0);
@@ -240,86 +231,6 @@ static int32_t MipiDsiInit(struct PanelInfo *info)
return ret;
}
-static int32_t PwmInit(struct Hi35xxDispCtrl *hi35xxCtrl, struct PanelInfo *info)
-{
- int32_t ret;
-
- /* pwm pin config */
- PwmPinMuxCfg(hi35xxCtrl, info->pwm.dev);
- /* pwm config */
- struct DevHandle *pwmHandle = PwmOpen(info->pwm.dev);
- if (pwmHandle == NULL) {
- HDF_LOGE("%s: PwmOpen failed", __func__);
- return HDF_FAILURE;
- }
- struct PwmConfig config;
- (void)memset_s(&config, sizeof(struct PwmConfig), 0, sizeof(struct PwmConfig));
- config.duty = 1;
- config.period = info->pwm.period;
- config.status = 0;
- ret = PwmSetConfig(pwmHandle, &config);
- if (ret != HDF_SUCCESS) {
- HDF_LOGE("%s: PwmSetConfig err, ret %d", __func__, ret);
- PwmClose(pwmHandle);
- return HDF_FAILURE;
- }
- PwmClose(pwmHandle);
- return HDF_SUCCESS;
-}
-
-static int32_t Hi35xxHardwareInit(struct Hi35xxDispCtrl *hi35xxCtrl)
-{
- int32_t i;
- int32_t panelNum;
- int32_t ret = HDF_FAILURE;
- struct PanelData **panel = NULL;
- struct PanelInfo *info = NULL;
-
- if (hi35xxCtrl->ctrl.panelManager == NULL) {
- HDF_LOGE("%s: panelManager is null", __func__);
- return HDF_FAILURE;
- }
- if (hi35xxCtrl->ctrl.panelManager->panelNum <= 0) {
- HDF_LOGE("%s: none of panels registered", __func__);
- return HDF_FAILURE;
- }
- panelNum = hi35xxCtrl->ctrl.panelManager->panelNum;
- panel = hi35xxCtrl->ctrl.panelManager->panel;
- for (i = 0; i < panelNum; i++) {
- info = panel[i]->info;
- if (info == NULL) {
- HDF_LOGE("%s:get info failed", __func__);
- return HDF_FAILURE;
- }
- if (info->blk.type == BLK_PWM) {
- ret = PwmInit(hi35xxCtrl, info);
- if (ret) {
- HDF_LOGE("%s:PwmInit failed", __func__);
- return HDF_FAILURE;
- }
- }
- /* lcd pin mux config */
- LcdPinMuxCfg(hi35xxCtrl, info->intfType);
- if (info->intfType == MIPI_DSI) {
- /* mipi dsi init */
- ret = MipiDsiInit(info);
- if (ret) {
- HDF_LOGE("%s:MipiDsiInit failed", __func__);
- return HDF_FAILURE;
- }
- }
- if (panel[i]->init != NULL) {
- /* panel driver init */
- ret = panel[i]->init(panel[i]);
- if (ret != HDF_SUCCESS) {
- HDF_LOGE("%s: panelData->init failed", __func__);
- return HDF_FAILURE;
- }
- }
- }
- return ret;
-}
-
static int32_t GetLcdIntfType(enum LcdIntfType type, uint32_t *out)
{
int32_t ret = HDF_SUCCESS;
@@ -351,187 +262,60 @@ static int32_t GetLcdIntfType(enum LcdIntfType type, uint32_t *out)
return ret;
}
-static int32_t Hi35xxGetDispInfo(struct DispControl *dispCtrl, uint32_t devId)
-{
- struct PanelInfo *panelInfo = NULL;
- struct DispInfo *info = NULL;
- struct PanelData *panel = NULL;
-
- if (dispCtrl == NULL) {
- HDF_LOGE("%s:dispCtrl is null", __func__);
- return HDF_FAILURE;
- }
- if (dispCtrl->panelManager == NULL || (devId >= dispCtrl->panelManager->panelNum)) {
- HDF_LOGE("%s: get panel fail", __func__);
- return HDF_FAILURE;
- }
- panel = dispCtrl->panelManager->panel[devId];
- if (panel == NULL) {
- HDF_LOGE("%s:panel is null", __func__);
- return HDF_FAILURE;
- }
- panelInfo = panel->info;
- if (panelInfo == NULL) {
- HDF_LOGE("%s:get info failed", __func__);
- return HDF_FAILURE;
- }
- info = dispCtrl->info;
- if (info == NULL) {
- HDF_LOGE("%s:info is null", __func__);
- return HDF_FAILURE;
- }
- info->width = panelInfo->width;
- info->height = panelInfo->height;
- info->hbp = panelInfo->hbp;
- info->hfp = panelInfo->hfp;
- info->hsw = panelInfo->hsw;
- info->vbp = panelInfo->vbp;
- info->vfp = panelInfo->vfp;
- info->vsw = panelInfo->vsw;
- if (GetLcdIntfType(panelInfo->intfType, &info->intfType) != HDF_SUCCESS) {
- HDF_LOGE("%s:GetLcdIntfType failed", __func__);
- return HDF_FAILURE;
- }
- info->intfSync = panelInfo->intfSync;
- info->frameRate = panelInfo->frameRate;
- info->minLevel = panelInfo->blk.minLevel;
- info->maxLevel = panelInfo->blk.maxLevel;
- info->defLevel = panelInfo->blk.defLevel;
- HDF_LOGI("info->width = %d, info->height = %d", info->width, info->height);
- HDF_LOGI("info->hbp = %d, info->hfp = %d", info->hbp, info->hfp);
- HDF_LOGI("info->frameRate = %d, info->intfSync = %d", info->frameRate, info->intfSync);
- return HDF_SUCCESS;
-}
-
-static int32_t Hi35xxOn(struct DispControl *dispCtrl, uint32_t devId)
+static int32_t Hi35xxHardWareInit(void)
{
- int32_t ret = HDF_FAILURE;
+ int32_t i;
+ int32_t ret;
+ struct PanelManager *panelManager = NULL;
struct PanelData *panel = NULL;
+ struct PanelInfo *info = NULL;
- if (dispCtrl == NULL) {
- HDF_LOGE("%s: dispCtrl is null", __func__);
- return HDF_FAILURE;
- }
- if (dispCtrl->panelManager == NULL || (devId >= dispCtrl->panelManager->panelNum)) {
- HDF_LOGE("%s: get panel fail", __func__);
- return HDF_FAILURE;
- }
- panel = dispCtrl->panelManager->panel[devId];
- if (panel == NULL) {
- HDF_LOGE("%s: panel is null", __func__);
+ panelManager = GetPanelManager();
+ if (panelManager == NULL) {
+ HDF_LOGE("%s: panelManager is null", __func__);
return HDF_FAILURE;
}
- if (panel->on != NULL) {
- /* panel driver on */
- ret = panel->on(panel);
- if (ret != HDF_SUCCESS) {
- HDF_LOGE("%s: panel->on failed", __func__);
+ for (i = 0; i < panelManager->panelNum; i++) {
+ panel = panelManager->panel[i];
+ info = panel->info;
+ if (info == NULL) {
+ HDF_LOGE("%s:GetPanelInfo failed", __func__);
return HDF_FAILURE;
}
- }
- return ret;
-}
-
-static int32_t Hi35xxOff(struct DispControl *dispCtrl, uint32_t devId)
-{
- int32_t ret = HDF_FAILURE;
- struct PanelData *panel = NULL;
-
- if (dispCtrl == NULL) {
- HDF_LOGE("%s: dispCtrl is null", __func__);
- return HDF_FAILURE;
- }
- if (dispCtrl->panelManager == NULL || (devId >= dispCtrl->panelManager->panelNum)) {
- HDF_LOGE("%s: get panel fail", __func__);
- return HDF_FAILURE;
- }
- panel = dispCtrl->panelManager->panel[devId];
- if (panel == NULL) {
- HDF_LOGE("%s: panel is null", __func__);
- return HDF_FAILURE;
- }
- if (panel->off != NULL) {
- /* panel driver off */
- ret = panel->off(panel);
- if (ret != HDF_SUCCESS) {
- HDF_LOGE("%s: panel->off failed", __func__);
- return HDF_FAILURE;
+ if (info->blk.type == BLK_PWM) {
+ PwmPinMuxCfg(info->pwm.dev);
}
- }
- return ret;
-}
-
-static int32_t Hi35xxSetBacklight(struct DispControl *dispCtrl, uint32_t devId, uint32_t level)
-{
- int32_t ret = HDF_FAILURE;
- struct PanelData *panel = NULL;
-
- if (dispCtrl == NULL) {
- HDF_LOGE("%s: dispCtrl is null", __func__);
- return HDF_FAILURE;
- }
- if (dispCtrl->panelManager == NULL || (devId >= dispCtrl->panelManager->panelNum)) {
- HDF_LOGE("%s: get panel fail", __func__);
- return HDF_FAILURE;
- }
- panel = dispCtrl->panelManager->panel[devId];
- if (panel == NULL) {
- HDF_LOGE("%s: panel is null", __func__);
- return HDF_FAILURE;
- }
- if (panel->setBacklight != NULL) {
- /* panel driver set backlight */
- ret = panel->setBacklight(panel, level);
- if (ret != HDF_SUCCESS) {
- HDF_LOGE("%s: setBacklight failed", __func__);
+ /* lcd pin mux config */
+ LcdPinMuxCfg(info->intfType);
+ if (info->intfType == MIPI_DSI) {
+ /* mipi dsi init */
+ ret = MipiDsiInit(info);
+ if (ret) {
+ HDF_LOGE("%s:MipiDsiInit failed", __func__);
+ return HDF_FAILURE;
+ }
+ }
+ if (GetLcdIntfType(info->intfType, &info->intfType) != HDF_SUCCESS) {
+ HDF_LOGE("%s:GetLcdIntfType failed", __func__);
return HDF_FAILURE;
}
+ if (panel->init != NULL) {
+ if ((panel->init(panel)) != HDF_SUCCESS) {
+ HDF_LOGE("%s:panel[%d] init failed", __func__, i);
+ return HDF_FAILURE;
+ }
+ }
}
- return ret;
-}
-
-static int32_t Hi35xxResInit(struct Hi35xxDispCtrl *hi35xxCtrl, struct PanelManager *panelManager)
-{
- hi35xxCtrl->ctrl.ops.on = Hi35xxOn;
- hi35xxCtrl->ctrl.ops.off = Hi35xxOff;
- hi35xxCtrl->ctrl.ops.setBacklight = Hi35xxSetBacklight;
- hi35xxCtrl->ctrl.ops.getDispInfo = Hi35xxGetDispInfo;
- hi35xxCtrl->ctrl.panelManager = panelManager;
- hi35xxCtrl->mipiCfgBase = (unsigned long)OsalIoRemap(IO_CFG2_BASE, IO_CFG_SIZE);
- hi35xxCtrl->pwmCfgBase = (unsigned long)OsalIoRemap(IO_CFG1_BASE, IO_CFG_SIZE);
return HDF_SUCCESS;
}
static int32_t Hi35xxEntryInit(struct HdfDeviceObject *object)
{
- struct PanelManager *panelManager = NULL;
- struct Hi35xxDispCtrl *hi35xxCtrl = NULL;
-
if (object == NULL) {
- HDF_LOGE("%s: object is null!", __func__);
- return HDF_FAILURE;
- }
- hi35xxCtrl = (struct Hi35xxDispCtrl *)OsalMemCalloc(sizeof(struct Hi35xxDispCtrl));
- if (hi35xxCtrl == NULL) {
- HDF_LOGE("%s hi35xxCtrl malloc fail", __func__);
- return HDF_FAILURE;
- }
- panelManager = GetPanelManager();
- if (panelManager == NULL) {
- HDF_LOGE("%s: panelManager is null", __func__);
- return HDF_FAILURE;
- }
- if (Hi35xxResInit(hi35xxCtrl, panelManager) == HDF_FAILURE) {
- HDF_LOGE("%s Hi35xxResInit fail", __func__);
- return HDF_FAILURE;
- }
- if (Hi35xxHardwareInit(hi35xxCtrl) == HDF_FAILURE) {
- HDF_LOGE("%s Hi35xxHardwareInit fail", __func__);
+ HDF_LOGE("%s: object is null", __func__);
return HDF_FAILURE;
}
- hi35xxCtrl->ctrl.object = object;
- hi35xxCtrl->ctrl.object->priv = hi35xxCtrl;
- return RegisterDispCtrl(&hi35xxCtrl->ctrl);
+ return Hi35xxHardWareInit();
}
struct HdfDriverEntry g_hi35xxDevEntry = {
diff --git a/model/display/driver/lcd_abs_if.h b/model/display/driver/adapter_soc/hi35xx_disp.h
similarity index 59%
rename from model/display/driver/lcd_abs_if.h
rename to model/display/driver/adapter_soc/hi35xx_disp.h
index aa20f497fc5c981e051245ddd9d9227455a3d839..682546b9362df37c46c382001ebc4b998e9f67a0 100644
--- a/model/display/driver/lcd_abs_if.h
+++ b/model/display/driver/adapter_soc/hi35xx_disp.h
@@ -6,29 +6,24 @@
* See the LICENSE file in the root of this repository for complete details.
*/
-#ifndef LCD_ABS_IF_H
-#define LCD_ABS_IF_H
+#ifndef HI35XX_DISP_H
+#define HI35XX_DISP_H
#include "hdf_base.h"
-#include "hdf_device_desc.h"
-#include "hdf_log.h"
-#include "mipi_dsi_if.h"
-/* support max panel number */
-#define PANEL_MAX 2
+#define IO_CFG1_BASE 0x111F0000
+#define IO_CFG2_BASE 0x112F0000
+#define IO_CFG_SIZE 0x10000
-enum LcdIntfType {
- MIPI_DSI,
- LCD_6BIT,
- LCD_8BIT,
- LCD_16BIT,
- LCD_18BIT,
- LCD_24BIT,
-};
+#define PWM_DEV0 0
+#define PWM_DEV1 1
-enum BacklightType {
- BLK_PWM,
- BLK_MIPI,
-};
+/* output interface type */
+#define INTF_LCD_6BIT (0x01L << 9)
+#define INTF_LCD_8BIT (0x01L << 10)
+#define INTF_LCD_16BIT (0x01L << 11)
+#define INTF_LCD_18BIT (0x01L << 12)
+#define INTF_LCD_24BIT (0x01L << 13)
+#define INTF_MIPI (0x01L << 14)
/* output timing */
enum IntfSync {
@@ -82,83 +77,4 @@ enum IntfSync {
OUTPUT_7680X4320_30, /* For HDMI2.1 at 30 Hz */
};
-struct MipiDsiDesc {
- enum DsiLane lane;
- enum DsiMode mode; /* output mode: DSI_VIDEO/DSI_CMD */
- enum DsiBurstMode burstMode;
- enum DsiOutFormat format;
-};
-
-enum PowerStatus {
- POWER_STATUS_ON, /* The power status is on */
- POWER_STATUS_STANDBY, /* The power status is standby */
- POWER_STATUS_SUSPEND, /* The power status is suspend */
- POWER_STATUS_OFF, /* The power status is off */
- POWER_STATUS_BUTT
-};
-
-struct BlkDesc {
- uint32_t type;
- uint32_t minLevel;
- uint32_t maxLevel;
- uint32_t defLevel;
-};
-
-struct PwmCfg {
- uint32_t dev;
- uint32_t period;
-};
-
-struct PanelInfo {
- uint32_t width;
- uint32_t height;
- uint32_t hbp;
- uint32_t hfp;
- uint32_t hsw;
- uint32_t vbp;
- uint32_t vfp;
- uint32_t vsw;
- uint32_t frameRate;
- enum LcdIntfType intfType;
- enum IntfSync intfSync;
- struct MipiDsiDesc mipi;
- struct BlkDesc blk;
- struct PwmCfg pwm;
-};
-
-struct PanelStatus {
- enum PowerStatus powerStatus;
- uint32_t currLevel;
-};
-
-struct PanelData;
-struct PanelEsd {
- bool support;
- uint32_t interval;
- uint32_t state;
- uint32_t recoveryNum;
- uint32_t cmpMode;
- int32_t (*checkFunc)(struct PanelData *panel);
- void *expect_data;
-};
-
-struct PanelData {
- struct HdfDeviceObject *object;
- int32_t (*init)(struct PanelData *panel);
- int32_t (*on)(struct PanelData *panel);
- int32_t (*off)(struct PanelData *panel);
- int32_t (*setBacklight)(struct PanelData *panel, uint32_t level);
- struct PanelInfo *info;
- struct PanelStatus status;
- struct PanelEsd *esd;
-};
-
-struct PanelManager {
- struct PanelData *panel[PANEL_MAX];
- uint32_t panelNum;
-};
-
-int32_t RegisterPanel(struct PanelData *data);
-struct PanelManager *GetPanelManager(void);
-struct PanelData *GetPanel(int32_t index);
-#endif /* LCD_ABS_IF_H */
+#endif /* HI35XX_DISP_H */
diff --git a/model/display/driver/backlight/hdf_bl.c b/model/display/driver/backlight/hdf_bl.c
new file mode 100644
index 0000000000000000000000000000000000000000..8caa4f59bc8cdce5a3f251591ae1a483c3090383
--- /dev/null
+++ b/model/display/driver/backlight/hdf_bl.c
@@ -0,0 +1,440 @@
+/*
+ * 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_bl.h"
+#include
+#include "hdf_base.h"
+#include "hdf_log.h"
+#include "osal.h"
+
+#define OFFSET_TWO_BYTE 16
+#define MAX_BL_NAME_LEN 32
+#define MAX_BL_DEV 32
+#define NAME_BUFFER_LEN 1220 // 32 * 38
+#define MAX_DEST_STRING_LEN 38 // MAX_BL_NAME_LEN(32) + 6
+
+enum BrightnessType {
+ MIN_BRIGHTNESS,
+ CURRENT_BRIGHTNESS,
+ DEFAULT_BRIGHTNESS,
+ MAX_BRIGHTNESS,
+};
+
+typedef int32_t (*BlCmdHandle)(struct HdfDeviceObject *device,
+ struct HdfSBuf *reqData, struct HdfSBuf *rspData);
+
+struct BacklightDev {
+ char name[MAX_BL_NAME_LEN];
+ struct BacklightProperties props;
+ struct BacklightOps *ops;
+ struct OsalMutex mutex;
+ bool isRegister;
+ void *priv;
+};
+
+struct BlDevManager {
+ struct BacklightDev *blDev[MAX_BL_DEV];
+ int32_t devNum;
+};
+
+static struct BlDevManager g_blDevManager;
+
+static struct BlDevManager *GetBlDevManager(void)
+{
+ return &g_blDevManager;
+}
+
+static struct BacklightDev *BlDevInstance(const char *devName,
+ struct BacklightProperties *props, struct BacklightOps *ops)
+{
+ int32_t ret;
+ struct BacklightDev *blDev = NULL;
+
+ blDev = (struct BacklightDev *)OsalMemCalloc(sizeof(struct BacklightDev));
+ if (blDev == NULL) {
+ HDF_LOGE("%s blDev malloc fail", __func__);
+ return NULL;
+ }
+ blDev->ops = ops;
+ ret = memcpy_s(blDev->name, MAX_BL_NAME_LEN - 1, devName, strlen(devName) + 1);
+ if (ret != 0) {
+ HDF_LOGE("%s blDev->name %s", __func__, blDev->name);
+ goto FAIL;
+ }
+ ret = memcpy_s(&blDev->props, sizeof(struct BacklightProperties),
+ props, sizeof(struct BacklightProperties));
+ if (ret != 0) {
+ HDF_LOGE("%s props memcpy fail", __func__);
+ goto FAIL;
+ }
+ return blDev;
+FAIL:
+ OsalMemFree(blDev);
+ return NULL;
+}
+
+struct BacklightDev *RegisterBlDev(const char *name, struct BacklightProperties *props,
+ struct BacklightOps *ops, void *priv)
+{
+ int32_t devNum;
+ struct BacklightDev *blDev = NULL;
+ struct BlDevManager *blDevManager = NULL;
+
+ if ((name == NULL) || (ops == NULL) || (props == NULL)) {
+ HDF_LOGE("%s: name , ops or props is null", __func__);
+ return NULL;
+ }
+ blDevManager = GetBlDevManager();
+ devNum = blDevManager->devNum;
+ if (devNum >= MAX_BL_DEV) {
+ HDF_LOGE("%s: number of backlight device registrations exceeded", __func__);
+ return NULL;
+ }
+ for (int32_t i = 0; i < devNum; i++) {
+ if (strcmp(name, blDevManager->blDev[i]->name) == 0) {
+ HDF_LOGE("%s: backlight name should be unique", __func__);
+ return NULL;
+ }
+ }
+ blDev = BlDevInstance(name, props, ops);
+ if (blDev == NULL) {
+ HDF_LOGE("%s: BlDevInstance fail", __func__);
+ return NULL;
+ }
+ blDev->priv = priv;
+ blDevManager->blDev[devNum] = blDev;
+ blDevManager->devNum++;
+ OsalMutexInit(&blDev->mutex);
+ HDF_LOGE("%s: success", __func__);
+ return blDev;
+}
+
+void *ToBlDevPriv(struct BacklightDev *blDev)
+{
+ if (blDev == NULL) {
+ HDF_LOGE("%s blDev is null", __func__);
+ return NULL;
+ }
+ return blDev->priv;
+}
+
+struct BacklightDev *GetBacklightDev(const char *name)
+{
+ struct BlDevManager *blDevManager = NULL;
+
+ if (name == NULL) {
+ HDF_LOGE("%s name is null", __func__);
+ return NULL;
+ }
+ blDevManager = GetBlDevManager();
+ for (int32_t i = 0; i < blDevManager->devNum; i++) {
+ if (strcmp(name, blDevManager->blDev[i]->name) == 0) {
+ return blDevManager->blDev[i];
+ }
+ }
+ return NULL;
+}
+
+int32_t UpdateBacklightState(struct BacklightDev *blDev, enum FbPowerStatus status)
+{
+ if (blDev == NULL) {
+ HDF_LOGE("%s blDev is null", __func__);
+ return HDF_FAILURE;
+ }
+ if ((status < FB_POWER_ON) || (status > FB_POWER_OFF)) {
+ HDF_LOGE("%s the status is illegal", __func__);
+ return HDF_FAILURE;
+ }
+ OsalMutexLock(&blDev->mutex);
+ blDev->props.fbStatus = status;
+ OsalMutexUnlock(&blDev->mutex);
+ return HDF_SUCCESS;
+}
+
+int32_t UpdateBrightness(struct BacklightDev *blDev, uint32_t brightness)
+{
+ int32_t ret = HDF_FAILURE;
+
+ if (blDev == NULL) {
+ HDF_LOGE("%s blDev is null", __func__);
+ return HDF_FAILURE;
+ }
+ if (brightness > blDev->props.maxBrightness) {
+ brightness = blDev->props.maxBrightness;
+ }
+ if (brightness < blDev->props.minBrightness) {
+ brightness = blDev->props.minBrightness;
+ }
+ OsalMutexLock(&blDev->mutex);
+ if (brightness == blDev->props.brightness) {
+ HDF_LOGI("%s brightness does not change", __func__);
+ OsalMutexUnlock(&blDev->mutex);
+ return HDF_SUCCESS;
+ }
+ if ((blDev->props.fbStatus == FB_POWER_STANDBY) ||
+ (blDev->props.fbStatus == FB_POWER_SUSPEND) ||
+ (blDev->props.fbStatus == FB_POWER_OFF)) {
+ brightness = 0;
+ }
+ if (blDev->ops != NULL && blDev->ops->updateBrightness != NULL) {
+ ret = blDev->ops->updateBrightness(blDev, brightness);
+ if (ret == HDF_SUCCESS) {
+ blDev->props.brightness = brightness;
+ } else {
+ HDF_LOGE("%s: fail", __func__);
+ }
+ }
+ OsalMutexUnlock(&blDev->mutex);
+ return ret;
+}
+
+static int32_t GetBlDevBrightness(struct BacklightDev *blDev, enum BrightnessType type)
+{
+ uint32_t brightness;
+
+ OsalMutexLock(&blDev->mutex);
+ switch (type) {
+ case MIN_BRIGHTNESS:
+ brightness = blDev->props.minBrightness;
+ break;
+ case CURRENT_BRIGHTNESS:
+ if ((blDev->props.fbStatus == FB_POWER_STANDBY) ||
+ (blDev->props.fbStatus == FB_POWER_SUSPEND) ||
+ (blDev->props.fbStatus == FB_POWER_OFF)) {
+ blDev->props.brightness = 0;
+ }
+ if ((blDev->ops != NULL) && (blDev->ops->getBrightness != NULL)) {
+ brightness = blDev->ops->getBrightness(blDev);
+ } else {
+ brightness = blDev->props.brightness;
+ }
+ break;
+ case DEFAULT_BRIGHTNESS:
+ brightness = blDev->props.defBrightness;
+ break;
+ case MAX_BRIGHTNESS:
+ brightness = blDev->props.maxBrightness;
+ break;
+ }
+ OsalMutexUnlock(&blDev->mutex);
+ return brightness;
+}
+
+int32_t GetMinBrightness(struct BacklightDev *blDev, uint32_t *brightness)
+{
+ if (blDev == NULL || brightness == NULL) {
+ HDF_LOGE("%s: blDev or brightness is null", __func__);
+ return HDF_FAILURE;
+ }
+ *brightness = GetBlDevBrightness(blDev, MIN_BRIGHTNESS);
+ return HDF_SUCCESS;
+}
+
+int32_t GetCurrBrightness(struct BacklightDev *blDev, uint32_t *brightness)
+{
+ if (blDev == NULL || brightness == NULL) {
+ HDF_LOGE("%s: blDev or brightness is null", __func__);
+ return HDF_FAILURE;
+ }
+ *brightness = GetBlDevBrightness(blDev, CURRENT_BRIGHTNESS);
+ return HDF_SUCCESS;
+}
+
+int32_t GetDefBrightness(struct BacklightDev *blDev, uint32_t *brightness)
+{
+ if (blDev == NULL || brightness == NULL) {
+ HDF_LOGE("%s: blDev or brightness is null", __func__);
+ return HDF_FAILURE;
+ }
+ *brightness = GetBlDevBrightness(blDev, DEFAULT_BRIGHTNESS);
+ return HDF_SUCCESS;
+}
+
+int32_t GetMaxBrightness(struct BacklightDev *blDev, uint32_t *brightness)
+{
+ if (blDev == NULL || brightness == NULL) {
+ HDF_LOGE("%s: blDev or brightness is null", __func__);
+ return HDF_FAILURE;
+ }
+ *brightness = GetBlDevBrightness(blDev, MAX_BRIGHTNESS);
+ return HDF_SUCCESS;
+}
+
+static int32_t HdfGetBrightness(enum BrightnessType type,
+ struct HdfSBuf *reqData, struct HdfSBuf *rspData)
+{
+ uint32_t devId;
+ int32_t brightness;
+ struct BlDevManager *blDevManager = NULL;
+ struct BacklightDev *blDev = NULL;
+
+ if (reqData == NULL) {
+ return HDF_ERR_INVALID_PARAM;
+ }
+ if (!HdfSbufReadUint32(reqData, &devId)) {
+ HDF_LOGE("%s: HdfSbufReadBuffer failed", __func__);
+ return HDF_FAILURE;
+ }
+ blDevManager = GetBlDevManager();
+ if (devId >= blDevManager->devNum) {
+ HDF_LOGE("%s: devId is illegal", __func__);
+ return HDF_FAILURE;
+ }
+ blDev = blDevManager->blDev[devId];
+ brightness = GetBlDevBrightness(blDev, type);
+ if (!HdfSbufWriteUint32(rspData, brightness)) {
+ HDF_LOGE("%s: HdfSbufWriteUint32 failed", __func__);
+ return HDF_FAILURE;
+ }
+ return HDF_SUCCESS;
+}
+
+static int32_t HdfGetMinBrightness(struct HdfDeviceObject *device,
+ struct HdfSBuf *reqData, struct HdfSBuf *rspData)
+{
+ (void)device;
+ return HdfGetBrightness(MIN_BRIGHTNESS, reqData, rspData);
+}
+
+static int32_t HdfGetCurrBrightness(struct HdfDeviceObject *device,
+ struct HdfSBuf *reqData, struct HdfSBuf *rspData)
+{
+ (void)device;
+ return HdfGetBrightness(CURRENT_BRIGHTNESS, reqData, rspData);
+}
+
+static int32_t HdfGetDefBrightness(struct HdfDeviceObject *device,
+ struct HdfSBuf *reqData, struct HdfSBuf *rspData)
+{
+ (void)device;
+ return HdfGetBrightness(DEFAULT_BRIGHTNESS, reqData, rspData);
+}
+
+static int32_t HdfGetMaxBrightness(struct HdfDeviceObject *device,
+ struct HdfSBuf *reqData, struct HdfSBuf *rspData)
+{
+ (void)device;
+ return HdfGetBrightness(MAX_BRIGHTNESS, reqData, rspData);
+}
+
+static int32_t HdfSetBrightness(struct HdfDeviceObject *device,
+ struct HdfSBuf *reqData, struct HdfSBuf *rspData)
+{
+ struct BlDevManager *blDevManager = NULL;
+ struct BacklightDev *blDev = NULL;
+
+ (void)device;
+ (void)rspData;
+ if (reqData == NULL) {
+ return HDF_ERR_INVALID_PARAM;
+ }
+ uint32_t para = 0;
+ if (!HdfSbufReadUint32(reqData, ¶)) {
+ HDF_LOGE("%s: HdfSbufReadBuffer failed", __func__);
+ return HDF_FAILURE;
+ }
+ uint32_t devId = (para >> OFFSET_TWO_BYTE) & 0xffff;
+ uint32_t level = para & 0xffff;
+ blDevManager = GetBlDevManager();
+ if (devId >= blDevManager->devNum) {
+ HDF_LOGE("%s: devId is illegal", __func__);
+ return HDF_FAILURE;
+ }
+ blDev = blDevManager->blDev[devId];
+ return UpdateBrightness(blDev, level);
+}
+
+static int32_t HdfGetBlDevList(struct HdfDeviceObject *device,
+ struct HdfSBuf *reqData, struct HdfSBuf *rspData)
+{
+ (void)device;
+ (void)reqData;
+ int32_t ret;
+ char *devName = NULL;
+ char *tmp = NULL;
+ char buffer[NAME_BUFFER_LEN] = {0};
+ struct BlDevManager *blDevManager = NULL;
+
+ blDevManager = GetBlDevManager();
+ tmp = buffer;
+ for (int32_t i = 0; i < blDevManager->devNum; i++) {
+ devName = blDevManager->blDev[i]->name;
+ if ((tmp + MAX_DEST_STRING_LEN) > &buffer[NAME_BUFFER_LEN]) {
+ HDF_LOGE("%s: Memory out of bounds", __func__);
+ break;
+ }
+ // strlen("%d : \n") = 6
+ ret = snprintf_s(tmp, MAX_DEST_STRING_LEN, strlen(devName) + 6, "%d : %s\n", i, devName);
+ if (ret < 0) {
+ HDF_LOGE("%s: snprintf_s fail", __func__);
+ return HDF_FAILURE;
+ }
+ tmp = tmp + strlen(tmp) + 1;
+ }
+ if (!HdfSbufWriteBuffer(rspData, buffer, strlen(buffer) + 1) != 0) {
+ HDF_LOGE("%s: copy info failed", __func__);
+ return HDF_FAILURE;
+ }
+ return HDF_SUCCESS;
+}
+
+static BlCmdHandle g_blDevCmdHandle[] = {
+ HdfGetMinBrightness,
+ HdfGetCurrBrightness,
+ HdfGetDefBrightness,
+ HdfGetMaxBrightness,
+ HdfGetBlDevList,
+ HdfSetBrightness,
+};
+
+static int32_t BacklightDispatch(struct HdfDeviceIoClient *client, int cmd, struct HdfSBuf *data,
+ struct HdfSBuf *reply)
+{
+ BlCmdHandle blCmdHandle = NULL;
+
+ if (client == NULL) {
+ return HDF_ERR_INVALID_PARAM;
+ }
+ if ((cmd < 0) || (cmd >= sizeof(g_blDevCmdHandle) / sizeof(BlCmdHandle))) {
+ HDF_LOGE("%s: cmd is illegal", __func__);
+ return HDF_FAILURE;
+ }
+ blCmdHandle = g_blDevCmdHandle[cmd];
+ return blCmdHandle(client->device, data, reply);
+}
+
+static int BacklightBind(struct HdfDeviceObject *dev)
+{
+ if (dev == NULL) {
+ return HDF_FAILURE;
+ }
+ static struct IDeviceIoService blService = {
+ .Dispatch = BacklightDispatch,
+ };
+ dev->service = &blService;
+ return HDF_SUCCESS;
+}
+
+static int32_t BacklightInit(struct HdfDeviceObject *object)
+{
+ if (object == NULL) {
+ HDF_LOGE("%s: object is null!", __func__);
+ return HDF_FAILURE;
+ }
+ HDF_LOGI("%s success", __func__);
+ return HDF_SUCCESS;
+}
+
+struct HdfDriverEntry g_blDevEntry = {
+ .moduleVersion = 1,
+ .moduleName = "HDF_BL",
+ .Init = BacklightInit,
+ .Bind = BacklightBind,
+};
+
+HDF_INIT(g_blDevEntry);
diff --git a/model/display/driver/backlight/hdf_bl.h b/model/display/driver/backlight/hdf_bl.h
new file mode 100644
index 0000000000000000000000000000000000000000..cb20789347a104b03f92c3ad291ec11f320cd670
--- /dev/null
+++ b/model/display/driver/backlight/hdf_bl.h
@@ -0,0 +1,47 @@
+/*
+ * 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 HDF_BL_H
+#define HDF_BL_H
+
+#include "hdf_disp.h"
+#include "hdf_types.h"
+
+enum FbPowerStatus {
+ FB_POWER_ON,
+ FB_POWER_STANDBY,
+ FB_POWER_SUSPEND,
+ FB_POWER_OFF,
+};
+
+struct BacklightDev;
+struct BacklightOps {
+ int32_t (*updateBrightness)(struct BacklightDev *bl, uint32_t brightness);
+ int32_t (*getBrightness)(struct BacklightDev *bl);
+};
+
+struct BacklightProperties {
+ uint32_t brightness;
+ uint32_t maxBrightness;
+ uint32_t minBrightness;
+ uint32_t defBrightness;
+ enum FbPowerStatus fbStatus;
+};
+
+struct BacklightDev *RegisterBlDev(const char *name, struct BacklightProperties *props,
+ struct BacklightOps *ops, void *priv);
+void *ToBlDevPriv(struct BacklightDev *blDev);
+struct BacklightDev *GetBacklightDev(const char *name);
+int32_t UpdateBacklightState(struct BacklightDev *blDev, enum FbPowerStatus status);
+int32_t UpdateBrightness(struct BacklightDev *blDev, uint32_t brightness);
+int32_t GetMinBrightness(struct BacklightDev *blDev, uint32_t *brightness);
+int32_t GetCurrBrightness(struct BacklightDev *blDev, uint32_t *brightness);
+int32_t GetDefBrightness(struct BacklightDev *blDev, uint32_t *brightness);
+int32_t GetMaxBrightness(struct BacklightDev *blDev, uint32_t *brightness);
+#endif /* HDF_BL_H */
+
diff --git a/model/display/driver/backlight/pwm_bl.c b/model/display/driver/backlight/pwm_bl.c
new file mode 100644
index 0000000000000000000000000000000000000000..2532e0f4a5be89ed3e158bc2b23f4ebfe1b8fecf
--- /dev/null
+++ b/model/display/driver/backlight/pwm_bl.c
@@ -0,0 +1,186 @@
+/*
+ * 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 "device_resource_if.h"
+#include "hdf_base.h"
+#include "hdf_bl.h"
+#include "hdf_disp.h"
+#include "hdf_log.h"
+#include "hdf_types.h"
+#include "osal.h"
+#include "pwm_if.h"
+
+#define DEF_MIN_BRIGHTNESS 0
+#define DEF_MAX_BRIGHTNESS 255
+
+#define CHECK_PARSER_RET(ret, str) do { \
+ if ((ret) != HDF_SUCCESS) { \
+ HDF_LOGE("%s: %s failed, ret = %d", __func__, str, ret); \
+ return HDF_FAILURE; \
+ } \
+} while (0)
+
+struct BlPwmDev {
+ const char *name;
+ uint8_t pwmDevNum;
+ DevHandle pwmHandle;
+ struct PwmConfig config;
+ struct BacklightProperties props;
+};
+
+static int32_t BlPwmUpdateBrightness(struct BacklightDev *blDev, uint32_t brightness)
+{
+ int32_t ret;
+ uint32_t duty;
+ struct BlPwmDev *blPwmDev = NULL;
+
+ blPwmDev = ToBlDevPriv(blDev);
+ if (blPwmDev == NULL) {
+ HDF_LOGE("%s blPwmDev is null", __func__);
+ return HDF_FAILURE;
+ }
+ if (blPwmDev->props.maxBrightness == 0) {
+ HDF_LOGE("%s maxBrightness is 0", __func__);
+ return HDF_FAILURE;
+ }
+ duty = (brightness * blPwmDev->config.period) / blPwmDev->props.maxBrightness;
+ ret = PwmSetDuty(blPwmDev->pwmHandle, duty);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s: PwmSetDuty failed, ret %d", __func__, ret);
+ return HDF_FAILURE;
+ }
+ if (brightness != 0) {
+ ret = PwmEnable(blPwmDev->pwmHandle);
+ } else {
+ ret = PwmDisable(blPwmDev->pwmHandle);
+ }
+ return ret;
+}
+
+static struct BacklightOps g_blDevOps = {
+ .updateBrightness = BlPwmUpdateBrightness,
+};
+
+static int32_t ParsePwmNum(const struct DeviceResourceNode *node, uint8_t *pwmNum)
+{
+ int32_t ret;
+ struct DeviceResourceIface *parser = NULL;
+
+ if (node == NULL) {
+ HDF_LOGE("%s: node is null", __func__);
+ return HDF_FAILURE;
+ }
+ parser = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
+ if (parser == NULL) {
+ HDF_LOGE("%s: instance parser failed", __func__);
+ return HDF_FAILURE;
+ }
+ ret = parser->GetUint8(node, "pwmDevNum", pwmNum, 0);
+ CHECK_PARSER_RET(ret, "GetUint8");
+ return HDF_SUCCESS;
+}
+static int32_t ParseBlPwmCfg(const struct DeviceResourceNode *node, struct BlPwmDev *blPwmDev)
+{
+ int32_t ret;
+ uint32_t defBrightness;
+ struct DeviceResourceIface *parser = NULL;
+
+ if (node == NULL) {
+ HDF_LOGE("%s: node is null", __func__);
+ return HDF_FAILURE;
+ }
+ parser = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
+ if (parser == NULL) {
+ HDF_LOGE("%s: instance parser failed", __func__);
+ return HDF_FAILURE;
+ }
+ ret = parser->GetString(node, "backlightDevName", &blPwmDev->name, NULL);
+ CHECK_PARSER_RET(ret, "GetString");
+ ret = parser->GetUint32(node, "pwmMaxPeroid", &blPwmDev->config.period, 0);
+ CHECK_PARSER_RET(ret, "GetUint32");
+ ret = parser->GetUint32(node, "minBrightness", &blPwmDev->props.minBrightness, DEF_MIN_BRIGHTNESS);
+ CHECK_PARSER_RET(ret, "GetUint32");
+ ret = parser->GetUint32(node, "maxBrightness", &blPwmDev->props.maxBrightness, DEF_MAX_BRIGHTNESS);
+ CHECK_PARSER_RET(ret, "GetUint32");
+ // if not provided defBrightness, defBrightness = (min + max) / 2
+ defBrightness = (blPwmDev->props.minBrightness + blPwmDev->props.maxBrightness) / 2;
+ ret = parser->GetUint32(node, "defBrightness", &blPwmDev->props.defBrightness, defBrightness);
+ CHECK_PARSER_RET(ret, "GetUint32");
+ blPwmDev->config.duty = 1;
+ blPwmDev->config.status = 1;
+ return HDF_SUCCESS;
+}
+
+static int32_t BlPwmDevInit(struct HdfDeviceObject *object, struct BlPwmDev *blPwmDev)
+{
+ if (ParsePwmNum(object->property, &blPwmDev->pwmDevNum) != HDF_SUCCESS) {
+ HDF_LOGE("%s ParsePwmNum fail", __func__);
+ return HDF_FAILURE;
+ }
+ blPwmDev->pwmHandle = PwmOpen(blPwmDev->pwmDevNum);
+ if (blPwmDev->pwmHandle == NULL) {
+ HDF_LOGE("%s: PwmOpen failed", __func__);
+ return HDF_FAILURE;
+ }
+ if (PwmGetConfig(blPwmDev->pwmHandle, &blPwmDev->config) != HDF_SUCCESS) {
+ HDF_LOGE("%s: PwmGetConfig fail", __func__);
+ return HDF_FAILURE;
+ }
+ if (ParseBlPwmCfg(object->property, blPwmDev) != HDF_SUCCESS) {
+ HDF_LOGE("%s: ParseBlPwmCfg fail", __func__);
+ return HDF_FAILURE;
+ }
+ if (PwmSetConfig(blPwmDev->pwmHandle, &blPwmDev->config) != HDF_SUCCESS) {
+ HDF_LOGE("%s: PwmSetConfig fail", __func__);
+ return HDF_FAILURE;
+ }
+ return HDF_SUCCESS;
+}
+
+static int32_t BlPwmEntryInit(struct HdfDeviceObject *object)
+{
+ int32_t ret;
+ struct BacklightDev *blDev = NULL;
+ struct BlPwmDev *blPwmDev = NULL;
+
+ blPwmDev = (struct BlPwmDev *)OsalMemCalloc(sizeof(struct BlPwmDev));
+ if (blPwmDev == NULL) {
+ HDF_LOGE("%s blPwmDev malloc fail", __func__);
+ return HDF_FAILURE;
+ }
+ ret = BlPwmDevInit(object, blPwmDev);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s: BlPwmDevInit fail", __func__);
+ goto FAIL;
+ }
+ blDev = RegisterBlDev(blPwmDev->name, &blPwmDev->props, &g_blDevOps, blPwmDev);
+ if (blDev == NULL) {
+ HDF_LOGE("%s: RegisterBlDev fail", __func__);
+ goto FAIL;
+ }
+ if (UpdateBacklightState(blDev, FB_POWER_ON) != HDF_SUCCESS) {
+ HDF_LOGE("%s: UpdateBacklightState fail", __func__);
+ }
+ if (UpdateBrightness(blDev, blPwmDev->props.defBrightness) != HDF_SUCCESS) {
+ HDF_LOGE("%s: UpdateBrightness fail", __func__);
+ }
+ HDF_LOGI("%s: success", __func__);
+ return HDF_SUCCESS;
+
+FAIL:
+ OsalMemFree(blPwmDev);
+ return HDF_FAILURE;
+}
+
+struct HdfDriverEntry g_pwmBlDevEntry = {
+ .moduleVersion = 1,
+ .moduleName = "PWM_BL",
+ .Init = BlPwmEntryInit,
+};
+
+HDF_INIT(g_pwmBlDevEntry);
diff --git a/model/display/driver/hdf_disp.c b/model/display/driver/hdf_disp.c
index 77b80cb549ff586ab710216bd623239998767574..793ff99b72eae459c749232dfcc6fa1085e0a341 100644
--- a/model/display/driver/hdf_disp.c
+++ b/model/display/driver/hdf_disp.c
@@ -9,32 +9,51 @@
#include "hdf_disp.h"
#include
#include "hdf_base.h"
+#include "hdf_bl.h"
#include "hdf_log.h"
#include "osal.h"
#define OFFSET_TWO_BYTE 16
static struct DispManager *g_dispManager = NULL;
-
-int32_t RegisterDispCtrl(struct DispControl *dispCtrl)
+static struct PanelManager g_panelManager;
+int32_t RegisterPanel(struct PanelData *panel)
{
- if (dispCtrl == NULL) {
- HDF_LOGE("%s: dispCtrl is null", __func__);
+ int32_t panelNum;
+
+ if (panel == NULL) {
+ HDF_LOGE("%s: panel data is null", __func__);
+ return HDF_ERR_INVALID_PARAM;
+ }
+ if (panel->info == NULL) {
+ HDF_LOGE("%s panel info is null", __func__);
return HDF_FAILURE;
}
- if (g_dispManager == NULL) {
- g_dispManager = (struct DispManager *)OsalMemCalloc(sizeof(struct DispManager));
- if (g_dispManager == NULL) {
- HDF_LOGE("%s g_dispManager malloc fail", __func__);
- return HDF_FAILURE;
- }
- g_dispManager->dispCtrl = dispCtrl;
- g_dispManager->panelManager = dispCtrl->panelManager;
+ if ((panel->on == NULL) || (panel->off == NULL)) {
+ HDF_LOGE("%s on or off is null", __func__);
+ return HDF_FAILURE;
+ }
+ panel->powerStatus = POWER_STATUS_OFF;
+ panelNum = g_panelManager.panelNum;
+ if (panelNum >= PANEL_MAX) {
+ HDF_LOGE("%s registered panel up PANEL_MAX", __func__);
+ return HDF_FAILURE;
}
- HDF_LOGI("%s: success", __func__);
+ g_panelManager.panel[panelNum] = panel;
+ g_panelManager.panelNum++;
+ HDF_LOGI("%s: register success", __func__);
return HDF_SUCCESS;
}
-static struct DispManager *GetDispManager(void)
+struct PanelManager *GetPanelManager(void)
+{
+ if (g_panelManager.panelNum == 0) {
+ return NULL;
+ } else {
+ return &g_panelManager;
+ }
+}
+
+struct DispManager *GetDispManager(void)
{
if (g_dispManager != NULL && g_dispManager->initialzed) {
return g_dispManager;
@@ -84,60 +103,25 @@ static int32_t DispOff(uint32_t devId)
static int32_t SetDispBacklight(uint32_t devId, uint32_t level)
{
- int32_t ret = HDF_FAILURE;
struct DispManager *disp = NULL;
- struct PanelInfo *info = NULL;
- struct DispControlOps *ops = NULL;
struct PanelData *panel = NULL;
disp = GetDispManager();
if (disp && disp->panelManager && devId < disp->panelManager->panelNum) {
panel = disp->panelManager->panel[devId];
- info = panel->info;
- if (info == NULL) {
- HDF_LOGE("%s:get info failed", __func__);
- return HDF_FAILURE;
- }
}
- if (level > info->blk.maxLevel) {
- level = info->blk.maxLevel;
- } else if (level < info->blk.minLevel && level != 0) {
- level = info->blk.minLevel;
- }
- if (disp->dispCtrl == NULL) {
- HDF_LOGE("%s:dispCtrl is null", __func__);
+ if (UpdateBrightness(panel->blDev, level) != HDF_SUCCESS) {
+ HDF_LOGE("%s:UpdateBrightness failed", __func__);
return HDF_FAILURE;
}
- OsalMutexLock(&disp->dispMutex);
- if (panel->status.powerStatus != POWER_STATUS_ON) {
- HDF_LOGE("%s:devId[%d] not in power on mode", __func__, devId);
- OsalMutexUnlock(&disp->dispMutex);
- return HDF_FAILURE;
- }
- if (panel->status.currLevel == level) {
- HDF_LOGI("%s:devId[%d] currLevel equals : %d", __func__, devId, level);
- OsalMutexUnlock(&disp->dispMutex);
- return HDF_SUCCESS;
- }
- ops = &disp->dispCtrl->ops;
- if (ops->setBacklight) {
- ret = ops->setBacklight(disp->dispCtrl, devId, level);
- if (ret != HDF_SUCCESS) {
- HDF_LOGE("%s:setBacklight failed", __func__);
- OsalMutexUnlock(&disp->dispMutex);
- return HDF_FAILURE;
- }
- }
- OsalMutexUnlock(&disp->dispMutex);
HDF_LOGI("%s:level = %u", __func__, level);
- return ret;
+ return HDF_SUCCESS;
}
static int32_t GetDispInfo(uint32_t devId, struct DispInfo *info)
{
- int32_t ret = HDF_FAILURE;
- struct DispControlOps *ops = NULL;
struct DispManager *disp = NULL;
+ struct PanelData *panel = NULL;
if (info == NULL) {
HDF_LOGE("%s:info is null", __func__);
@@ -148,32 +132,37 @@ static int32_t GetDispInfo(uint32_t devId, struct DispInfo *info)
HDF_LOGE("%s: disp is null", __func__);
return HDF_FAILURE;
}
- if (disp->dispCtrl == NULL) {
- HDF_LOGE("%s: dispCtrl is null", __func__);
+ if (devId >= disp->panelManager->panelNum) {
+ HDF_LOGE("%s: devId exceed registered panelNum", __func__);
return HDF_FAILURE;
}
- disp->dispCtrl->info = info;
- ops = &disp->dispCtrl->ops;
- if (ops->getDispInfo != NULL) {
- ret = ops->getDispInfo(disp->dispCtrl, devId);
- if (ret != HDF_SUCCESS) {
- HDF_LOGE("%s: getDispInfo failed", __func__);
- return HDF_FAILURE;
- }
- }
- return ret;
+ panel = disp->panelManager->panel[devId];
+ info->width = panel->info->width;
+ info->height = panel->info->height;
+ info->hbp = panel->info->hbp;
+ info->hfp = panel->info->hfp;
+ info->hsw = panel->info->hsw;
+ info->vbp = panel->info->vbp;
+ info->vfp = panel->info->vfp;
+ info->vsw = panel->info->vsw;
+ info->intfType = panel->info->intfType;
+ info->intfSync = panel->info->intfSync;
+ info->frameRate = panel->info->frameRate;
+ info->minLevel = panel->info->blk.minLevel;
+ info->maxLevel = panel->info->blk.maxLevel;
+ info->defLevel = panel->info->blk.defLevel;
+ return HDF_SUCCESS;
}
static int32_t SetDispPower(uint32_t devId, uint32_t powerStatus)
{
int32_t ret = HDF_FAILURE;
- struct DispControlOps *ops = NULL;
struct DispManager *disp = NULL;
struct PanelData *panel = NULL;
disp = GetDispManager();
- if (disp == NULL || disp->dispCtrl == NULL) {
- HDF_LOGE("%s:disp or dispCtrl is null", __func__);
+ if (disp == NULL) {
+ HDF_LOGE("%s:disp is null", __func__);
return HDF_FAILURE;
}
if (devId >= disp->panelManager->panelNum) {
@@ -182,26 +171,25 @@ static int32_t SetDispPower(uint32_t devId, uint32_t powerStatus)
}
panel = disp->panelManager->panel[devId];
OsalMutexLock(&disp->dispMutex);
- if (panel->status.powerStatus == powerStatus) {
+ if (panel->powerStatus == powerStatus) {
OsalMutexUnlock(&disp->dispMutex);
- HDF_LOGE("%s:devId[%d] already in mode = %d", __func__, devId, powerStatus);
+ HDF_LOGE("%s: panel already in mode = %d", __func__, powerStatus);
return HDF_SUCCESS;
}
- ops = &disp->dispCtrl->ops;
switch (powerStatus) {
case POWER_STATUS_ON:
- if (ops->on) {
- ret = ops->on(disp->dispCtrl, devId);
- }
+ ret = panel->on(panel);
if (ret == HDF_SUCCESS) {
+ panel->powerStatus = POWER_STATUS_ON;
+ ret = UpdateBacklightState(panel->blDev, FB_POWER_ON);
EsdCheckStartUp(disp->esd, devId);
}
break;
case POWER_STATUS_OFF:
- if (ops->off) {
- ret = ops->off(disp->dispCtrl, devId);
- }
+ ret = panel->off(panel);
if (ret == HDF_SUCCESS) {
+ panel->powerStatus = POWER_STATUS_OFF;
+ ret = UpdateBacklightState(panel->blDev, FB_POWER_OFF);
EsdCheckEnd(disp->esd, devId);
}
break;
@@ -253,7 +241,7 @@ static int32_t GetPowerStatus(struct HdfDeviceObject *device, struct HdfSBuf *re
}
OsalMutexLock(&disp->dispMutex);
panel = disp->panelManager->panel[devId];
- powerStatus = panel->status.powerStatus;
+ powerStatus = panel->powerStatus;
OsalMutexUnlock(&disp->dispMutex);
if (!HdfSbufWriteUint32(rspData, powerStatus)) {
HDF_LOGE("%s: HdfSbufWriteUint32 failed", __func__);
@@ -302,10 +290,11 @@ static int32_t GetBacklight(struct HdfDeviceObject *device, struct HdfSBuf *reqD
HDF_LOGE("%s: get panel failed", __func__);
return HDF_FAILURE;
}
- OsalMutexLock(&disp->dispMutex);
panel = disp->panelManager->panel[devId];
- currLevel = panel->status.currLevel;
- OsalMutexUnlock(&disp->dispMutex);
+ if (GetCurrBrightness(panel->blDev, &currLevel) != HDF_SUCCESS) {
+ HDF_LOGE("%s: GetCurrBrightness failed", __func__);
+ return HDF_FAILURE;
+ }
if (!HdfSbufWriteUint32(rspData, currLevel)) {
HDF_LOGE("%s: HdfSbufWriteUint32 failed", __func__);
return HDF_FAILURE;
@@ -388,18 +377,15 @@ static int HdfDispBind(struct HdfDeviceObject *dev)
return HDF_SUCCESS;
}
-static void PanelRecovery(struct DispControl *dispCtrl, uint32_t devId)
+static void PanelRecovery(struct PanelData *panel)
{
- struct DispControlOps *ops = NULL;
-
HDF_LOGI("%s enter", __func__);
- ops = &dispCtrl->ops;
- if (ops->off) {
- ops->off(dispCtrl, devId);
+ if (panel->off) {
+ panel->off(panel);
}
OsalMSleep(150); // delay 150ms
- if (ops->on) {
- ops->on(dispCtrl, devId);
+ if (panel->on) {
+ panel->on(panel);
}
}
@@ -409,6 +395,10 @@ static void EsdTimerHandler(uintptr_t arg)
struct DispManager *disp = NULL;
disp = GetDispManager();
+ if ((disp == NULL) || (disp->esd == NULL)) {
+ HDF_LOGE("%s: disp or esd is null", __func__);
+ return;
+ }
if (devId >= disp->esd->panelNum) {
HDF_LOGE("%s: esd is null", __func__);
return;
@@ -425,18 +415,24 @@ static void EsdWorkHandler(void *arg)
struct DispManager *disp = NULL;
disp = GetDispManager();
- if ((disp->dispCtrl == NULL) || (devId >= disp->panelManager->panelNum)) {
+ if ((disp == NULL) || (disp->panelManager == NULL)) {
+ HDF_LOGE("%s: disp or panelManager is null", __func__);
+ return;
+ }
+ if (devId >= disp->panelManager->panelNum) {
HDF_LOGE("%s: dispCtrl is null or panel is null", __func__);
return;
}
panel = disp->panelManager->panel[devId];
- if ((panel->esd != NULL) && (panel->esd->checkFunc != NULL)) {
- ret = panel->esd->checkFunc(panel);
+ if ((panel->esd == NULL) || (panel->esd->checkFunc == NULL)) {
+ HDF_LOGE("%s: esd or checkFunc is null", __func__);
+ return;
}
+ ret = panel->esd->checkFunc(panel);
if (ret != HDF_SUCCESS) {
OsalMutexLock(&disp->dispMutex);
if (panel->esd->state == ESD_RUNNING) {
- PanelRecovery(disp->dispCtrl, devId);
+ PanelRecovery(panel);
} else {
HDF_LOGI("%s: esd check has disabled", __func__);
OsalMutexUnlock(&disp->dispMutex);
@@ -445,7 +441,7 @@ static void EsdWorkHandler(void *arg)
OsalMutexUnlock(&disp->dispMutex);
panel->esd->recoveryNum++;
}
- HDF_LOGD("%s devId[%d] recoveryNum = %d",__func__, devId, panel->esd->recoveryNum);
+ HDF_LOGD("%s recoveryNum = %d", __func__, panel->esd->recoveryNum);
if (panel->esd->recoveryNum >= ESD_MAX_RECOVERY) {
panel->esd->recoveryNum = 0;
OsalMutexLock(&disp->dispMutex);
@@ -475,7 +471,7 @@ static void EsdCheckStartUp(struct DispEsd *esd, uint32_t devId)
EsdTimerHandler, (uintptr_t)devId);
OsalTimerStartLoop(esd->timer[devId]);
esd->panelEsd[devId]->state = ESD_RUNNING;
- HDF_LOGI("%s , devId[%d] enable esd check", __func__, devId);
+ HDF_LOGI("%s panel enable esd check", __func__);
}
}
}
@@ -492,7 +488,7 @@ static void EsdCheckEnd(struct DispEsd *esd, uint32_t devId)
if (esd->panelEsd[devId]->state == ESD_RUNNING) {
OsalTimerDelete(esd->timer[devId]);
esd->panelEsd[devId]->state = ESD_READY;
- HDF_LOGI("%s devId[%d], disable esd check", __func__, devId);
+ HDF_LOGI("%s panel disable esd check", __func__);
}
}
}
@@ -633,18 +629,16 @@ static int32_t EsdCheckInit(struct DispManager *disp)
return HDF_SUCCESS;
}
-static int32_t HdfDispEntryInit(struct HdfDeviceObject *object)
+static int32_t DispManagerInit(struct PanelManager *panelManager)
{
int32_t ret;
- if (object == NULL) {
- HDF_LOGE("%s: object is null!", __func__);
- return HDF_FAILURE;
- }
+ g_dispManager = (struct DispManager *)OsalMemCalloc(sizeof(struct DispManager));
if (g_dispManager == NULL) {
- HDF_LOGE("%s: g_dispManager is null", __func__);
+ HDF_LOGE("%s g_dispManager malloc fail", __func__);
return HDF_FAILURE;
}
+ g_dispManager->panelManager = panelManager;
ret = HdfWorkQueueInit(&g_dispManager->dispWorkQueue, "dispWQ");
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s: HdfWorkQueueInit fail", __func__);
@@ -661,6 +655,29 @@ static int32_t HdfDispEntryInit(struct HdfDeviceObject *object)
return HDF_SUCCESS;
}
+static int32_t HdfDispEntryInit(struct HdfDeviceObject *object)
+{
+ int32_t ret;
+ struct PanelManager *panelManager = NULL;
+
+ if (object == NULL) {
+ HDF_LOGE("%s: object is null!", __func__);
+ return HDF_FAILURE;
+ }
+ panelManager = GetPanelManager();
+ if (panelManager == NULL) {
+ HDF_LOGE("%s: panelManager is null!", __func__);
+ return HDF_FAILURE;
+ }
+ ret = DispManagerInit(panelManager);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s: DispManagerInit fail", __func__);
+ return HDF_FAILURE;
+ }
+ HDF_LOGI("%s success", __func__);
+ return HDF_SUCCESS;
+}
+
struct HdfDriverEntry g_dispDevEntry = {
.moduleVersion = 1,
.moduleName = "HDF_DISP",
diff --git a/model/display/driver/hdf_disp.h b/model/display/driver/hdf_disp.h
index 4c9f2e8529a4da14a1b6bf132c8ad987dfe9d282..8f497d59634da7e43f19c63ba2b49476cab7e47a 100644
--- a/model/display/driver/hdf_disp.h
+++ b/model/display/driver/hdf_disp.h
@@ -8,11 +8,13 @@
#ifndef HDF_DISP_H
#define HDF_DISP_H
+
#include "hdf_base.h"
#include "hdf_device_desc.h"
+#include "hdf_log.h"
#include "hdf_sbuf.h"
#include "hdf_workqueue.h"
-#include "lcd_abs_if.h"
+#include "mipi_dsi_if.h"
#include "osal_mem.h"
#include "osal_mutex.h"
#include "osal_timer.h"
@@ -23,6 +25,97 @@
#define HDF_LOG_TAG HDF_DISP
#define ESD_DEFAULT_INTERVAL 5000
#define ESD_MAX_RECOVERY 10
+/* support max panel number */
+#define PANEL_MAX 2
+
+enum LcdIntfType {
+ MIPI_DSI,
+ LCD_6BIT,
+ LCD_8BIT,
+ LCD_16BIT,
+ LCD_18BIT,
+ LCD_24BIT,
+};
+
+enum BacklightType {
+ BLK_PWM,
+ BLK_MIPI,
+};
+
+struct MipiDsiDesc {
+ enum DsiLane lane;
+ enum DsiMode mode; /* output mode: DSI_VIDEO/DSI_CMD */
+ enum DsiBurstMode burstMode;
+ enum DsiOutFormat format;
+};
+
+enum PowerStatus {
+ POWER_STATUS_ON, /* The power status is on */
+ POWER_STATUS_STANDBY, /* The power status is standby */
+ POWER_STATUS_SUSPEND, /* The power status is suspend */
+ POWER_STATUS_OFF, /* The power status is off */
+ POWER_STATUS_BUTT
+};
+
+struct BlkDesc {
+ uint32_t type;
+ uint32_t minLevel;
+ uint32_t maxLevel;
+ uint32_t defLevel;
+};
+
+struct PwmCfg {
+ uint32_t dev;
+ uint32_t period;
+};
+
+struct PanelInfo {
+ uint32_t width;
+ uint32_t height;
+ uint32_t hbp;
+ uint32_t hfp;
+ uint32_t hsw;
+ uint32_t vbp;
+ uint32_t vfp;
+ uint32_t vsw;
+ uint32_t frameRate;
+ uint32_t clockFreq;
+ uint32_t pWidth;
+ uint32_t pHeight;
+ enum LcdIntfType intfType;
+ uint32_t intfSync;
+ struct MipiDsiDesc mipi;
+ struct BlkDesc blk;
+ struct PwmCfg pwm;
+};
+
+struct PanelData;
+struct PanelEsd {
+ bool support;
+ uint32_t interval;
+ uint32_t state;
+ uint32_t recoveryNum;
+ uint32_t cmpMode;
+ int32_t (*checkFunc)(struct PanelData *panel);
+ void *expect_data;
+};
+
+struct PanelData {
+ struct HdfDeviceObject *object;
+ int32_t (*init)(struct PanelData *panel);
+ int32_t (*on)(struct PanelData *panel);
+ int32_t (*off)(struct PanelData *panel);
+ struct PanelInfo *info;
+ enum PowerStatus powerStatus;
+ struct PanelEsd *esd;
+ struct BacklightDev *blDev;
+ void *priv;
+};
+
+struct PanelManager {
+ struct PanelData *panel[PANEL_MAX];
+ uint32_t panelNum;
+};
typedef int32_t (*DispCmdHandle)(struct HdfDeviceObject *device, struct HdfSBuf *reqData, struct HdfSBuf *rspData);
@@ -37,7 +130,7 @@ struct DispInfo {
uint32_t vsw;
uint32_t frameRate;
uint32_t intfType;
- enum IntfSync intfSync;
+ uint32_t intfSync;
uint32_t minLevel;
uint32_t maxLevel;
uint32_t defLevel;
@@ -64,23 +157,7 @@ struct DispEsd {
int32_t panelNum;
};
-struct DispControl;
-struct DispControlOps {
- int32_t (*on)(struct DispControl *dispCtrl, uint32_t devId);
- int32_t (*off)(struct DispControl *dispCtrl, uint32_t devId);
- int32_t (*setBacklight)(struct DispControl *dispCtrl, uint32_t devId, uint32_t level);
- int32_t (*getDispInfo)(struct DispControl *dispCtrl, uint32_t devId);
-};
-
-struct DispControl {
- struct HdfDeviceObject *object;
- struct PanelManager *panelManager;
- struct DispInfo *info;
- struct DispControlOps ops;
-};
-
struct DispManager {
- struct DispControl *dispCtrl;
struct PanelManager *panelManager;
struct OsalMutex dispMutex;
HdfWorkQueue dispWorkQueue;
@@ -88,5 +165,8 @@ struct DispManager {
struct DispEsd *esd;
};
-int32_t RegisterDispCtrl(struct DispControl *dispCtrl);
+int32_t RegisterPanel(struct PanelData *data);
+struct PanelManager *GetPanelManager(void);
+struct DispManager *GetDispManager(void);
+
#endif /* HDF_DISP_H */
diff --git a/model/display/driver/hdf_drm_panel.c b/model/display/driver/hdf_drm_panel.c
new file mode 100644
index 0000000000000000000000000000000000000000..acf0e564594b6382ad1988d7243e11482e02529d
--- /dev/null
+++ b/model/display/driver/hdf_drm_panel.c
@@ -0,0 +1,256 @@
+/*
+ * 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_drm_panel.h"
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include