mirror of
https://github.com/openharmony/device_soc_hpmicro.git
synced 2026-07-01 21:45:24 -04:00
@@ -36,6 +36,8 @@ hdf_driver(module_name) {
|
||||
special_visibility = [ ".." ]
|
||||
sources = [ ]
|
||||
|
||||
cflags = [ "-Wall", "-Werror"]
|
||||
|
||||
if (defined(LOSCFG_DRIVERS_HDF_PLATFORM_GPIO)) {
|
||||
sources += [
|
||||
"gpio.c"
|
||||
@@ -59,4 +61,10 @@ hdf_driver(module_name) {
|
||||
"watchdog.c"
|
||||
]
|
||||
}
|
||||
|
||||
if (defined(LOSCFG_DRIVERS_HDF_PLATFORM_SPI)) {
|
||||
sources += [
|
||||
"spi.c"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "device_resource_if.h"
|
||||
#include "hdf_device_desc.h"
|
||||
#include "hdf_log.h"
|
||||
#include "osal_mem.h"
|
||||
#include "gpio_if.h"
|
||||
#include "gpio_core.h"
|
||||
#include <hpm_gpio_drv.h>
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright (c) 2022 HPMicro.
|
||||
*
|
||||
* This file 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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "device_resource_if.h"
|
||||
#include "hdf_device_desc.h"
|
||||
#include "osal_sem.h"
|
||||
#include "osal_mem.h"
|
||||
#include "hdf_log.h"
|
||||
#include "i2c_if.h"
|
||||
#include "i2c_core.h"
|
||||
#include "hpm_i2c_drv.h"
|
||||
#include <los_interrupt.h>
|
||||
|
||||
#define HDF_LOG_TAG HPMICRO_I2C_HDF
|
||||
|
||||
struct HPMI2cDevice {
|
||||
uint32_t id;
|
||||
uint32_t base;
|
||||
uint32_t clkFreq;
|
||||
};
|
||||
|
||||
static int32_t hpmTransfer(struct I2cCntlr *cntlr, struct I2cMsg *msgs, int16_t count)
|
||||
{
|
||||
struct HPMI2cDevice *hpmI2cDev = (struct HPMI2cDevice *)cntlr->priv;
|
||||
I2C_Type *base = (I2C_Type *)hpmI2cDev->base;
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (msgs[i].flags & I2C_FLAG_ADDR_10BIT) {
|
||||
i2c_enable_10bit_address_mode(base, 1);
|
||||
} else {
|
||||
i2c_enable_10bit_address_mode(base, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: Another flags: I2C_FLAG_NO_START, I2C_FLAG_STOP, I2C_FLAG_READ_NO_ACK
|
||||
*/
|
||||
if (msgs[i].flags & I2C_FLAG_READ) {
|
||||
if (i2c_master_read(base, msgs[i].addr, msgs[i].buf, msgs[i].len) != status_success) {
|
||||
HDF_LOGI("i2c read: Failed!!!\n");
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
} else {
|
||||
if (i2c_master_write(base, msgs[i].addr, msgs[i].buf, msgs[i].len) != status_success) {
|
||||
HDF_LOGI("i2c write: Failed!!!\n");
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct I2cMethod hpmI2cMethod = {
|
||||
.transfer = hpmTransfer,
|
||||
};
|
||||
|
||||
|
||||
static int32_t I2cDriverBind(struct HdfDeviceObject *device)
|
||||
{
|
||||
int32_t ret = HDF_SUCCESS;
|
||||
|
||||
HDF_LOGI("Bind: successed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t I2cDriverInit(struct HdfDeviceObject *device)
|
||||
{
|
||||
int32_t ret = HDF_SUCCESS;
|
||||
|
||||
struct I2cCntlr *cntlr = (struct I2cCntlr *)OsalMemCalloc(
|
||||
sizeof(struct I2cCntlr) + sizeof(struct HPMI2cDevice));
|
||||
if (cntlr == NULL) {
|
||||
ret = HDF_FAILURE;
|
||||
HDF_LOGE("Init: cntlr alloc Failed!!!\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct HPMI2cDevice *hpmI2cDev = (struct HPMI2cDevice *)((char *)cntlr + sizeof(struct I2cCntlr));
|
||||
cntlr->priv = hpmI2cDev;
|
||||
device->priv = cntlr;
|
||||
|
||||
struct DeviceResourceIface *dri = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
|
||||
if (dri == NULL) {
|
||||
ret = HDF_FAILURE;
|
||||
HDF_LOGE("Init: get DeviceResourceIface Failed!!!\n");
|
||||
goto ERROR1;
|
||||
}
|
||||
|
||||
dri->GetUint32(device->property, "id", &hpmI2cDev->id, 0);
|
||||
dri->GetUint32(device->property, "base", &hpmI2cDev->base, 0);
|
||||
dri->GetUint32(device->property, "clk_freq", &hpmI2cDev->clkFreq, 0);
|
||||
HDF_LOGI("Init: hpmI2cDev->id: %u\n", hpmI2cDev->id);
|
||||
HDF_LOGI("Init: hpmI2cDev->base: 0x%X\n", hpmI2cDev->base);
|
||||
HDF_LOGI("Init: hpmI2cDev->clkFreq: %u\n", hpmI2cDev->clkFreq);
|
||||
|
||||
cntlr->busId = hpmI2cDev->id;
|
||||
cntlr->ops = &hpmI2cMethod;
|
||||
ret = I2cCntlrAdd(cntlr);
|
||||
if (ret) {
|
||||
HDF_LOGE("Init: I2cCntlrAdd Failed!!!\n");
|
||||
ret = HDF_FAILURE;
|
||||
goto ERROR1;
|
||||
}
|
||||
|
||||
I2C_Type *base = (I2C_Type *)hpmI2cDev->base;
|
||||
i2c_config_t i2cConfig;
|
||||
i2cConfig.i2c_mode = i2c_mode_normal;
|
||||
i2cConfig.is_10bit_addressing = 0;
|
||||
i2c_init_master(base, hpmI2cDev->clkFreq, &i2cConfig);
|
||||
|
||||
return ret;
|
||||
ERROR1:
|
||||
OsalMemFree(cntlr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void I2cDriverRelease(struct HdfDeviceObject *device)
|
||||
{
|
||||
if (device == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct I2cCntlr *cntlr = (struct I2cCntlr *)device->priv;
|
||||
if (cntlr == NULL) {
|
||||
HDF_LOGE("Release: cntlr null\n");
|
||||
return;
|
||||
}
|
||||
|
||||
I2cCntlrRemove(cntlr);
|
||||
OsalMemFree(cntlr);
|
||||
|
||||
HDF_LOGI("Release");
|
||||
return;
|
||||
}
|
||||
|
||||
struct HdfDriverEntry g_i2cDriverEntry = {
|
||||
.moduleVersion = 1,
|
||||
.moduleName = "HPMICRO_I2C_MODULE_HDF",
|
||||
.Bind = I2cDriverBind,
|
||||
.Init = I2cDriverInit,
|
||||
.Release = I2cDriverRelease,
|
||||
};
|
||||
|
||||
HDF_INIT(g_i2cDriverEntry);
|
||||
@@ -0,0 +1,240 @@
|
||||
/*
|
||||
* Copyright (c) 2022 HPMicro.
|
||||
*
|
||||
* This file 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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "device_resource_if.h"
|
||||
#include "hdf_device_desc.h"
|
||||
#include "osal_sem.h"
|
||||
#include "osal_mem.h"
|
||||
#include "hdf_log.h"
|
||||
#include "spi_if.h"
|
||||
#include "spi_core.h"
|
||||
#include "hpm_common.h"
|
||||
#include "hpm_spi_drv.h"
|
||||
#include <los_interrupt.h>
|
||||
|
||||
#define HDF_LOG_TAG HPMICRO_SPI_HDF
|
||||
|
||||
|
||||
struct HPMSpiDevice {
|
||||
uint32_t id;
|
||||
uint32_t base;
|
||||
uint32_t clkFreq;
|
||||
struct SpiCfg cfg;
|
||||
};
|
||||
|
||||
static void HpmSpiConfig(struct SpiCntlr *cntlr)
|
||||
{
|
||||
struct HPMSpiDevice *hpmSpiDev = (struct HPMSpiDevice *)cntlr->priv;
|
||||
SPI_Type *base = (SPI_Type *)hpmSpiDev->base;
|
||||
struct SpiCfg *cfg = &hpmSpiDev->cfg;
|
||||
spi_timing_config_t timing_config = {0};
|
||||
spi_format_config_t format_config = {0};
|
||||
|
||||
spi_master_get_default_timing_config(&timing_config);
|
||||
spi_master_get_default_format_config(&format_config);
|
||||
|
||||
format_config.common_config.data_len_in_bits = 8;
|
||||
format_config.common_config.mode = spi_master_mode;
|
||||
|
||||
if (cfg->mode & SPI_CLK_POLARITY) {
|
||||
format_config.common_config.cpol = spi_sclk_high_idle;
|
||||
} else {
|
||||
format_config.common_config.cpol = spi_sclk_low_idle;
|
||||
}
|
||||
|
||||
if (cfg->mode & SPI_CLK_PHASE) {
|
||||
format_config.common_config.cpha = spi_sclk_sampling_even_clk_edges;
|
||||
} else {
|
||||
format_config.common_config.cpha = spi_sclk_sampling_odd_clk_edges;
|
||||
}
|
||||
|
||||
if (cfg->mode & SPI_MODE_LSBFE) {
|
||||
format_config.common_config.lsb = 1;
|
||||
} else {
|
||||
format_config.common_config.lsb = 0;
|
||||
}
|
||||
|
||||
timing_config.master_config.clk_src_freq_in_hz = hpmSpiDev->clkFreq;
|
||||
timing_config.master_config.sclk_freq_in_hz = cfg->maxSpeedHz;
|
||||
|
||||
spi_master_timing_init(base, &timing_config);
|
||||
spi_format_init(base, &format_config);
|
||||
}
|
||||
|
||||
|
||||
static int32_t HpmSpiGetCfg(struct SpiCntlr *cntlr, struct SpiCfg *cfg)
|
||||
{
|
||||
struct HPMSpiDevice *hpmSpiDev = (struct HPMSpiDevice *)cntlr->priv;
|
||||
*cfg = hpmSpiDev->cfg;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t HpmSpiSetCfg(struct SpiCntlr *cntlr, struct SpiCfg *cfg)
|
||||
{
|
||||
struct HPMSpiDevice *hpmSpiDev = (struct HPMSpiDevice *)cntlr->priv;
|
||||
hpmSpiDev->cfg = *cfg;
|
||||
|
||||
HpmSpiConfig(cntlr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t HpmSpiTransfer(struct SpiCntlr *cntlr, struct SpiMsg *msg, uint32_t count)
|
||||
{
|
||||
int ret;
|
||||
struct HPMSpiDevice *hpmSpiDev = (struct HPMSpiDevice *)cntlr->priv;
|
||||
SPI_Type *base = (SPI_Type *)hpmSpiDev->base;
|
||||
|
||||
spi_control_config_t config;
|
||||
spi_master_get_default_control_config(&config);
|
||||
uint32_t rLen;
|
||||
uint32_t wLen;
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (msg[i].wbuf && msg[i].rbuf) {
|
||||
config.common_config.trans_mode = spi_trans_write_read_together;
|
||||
rLen = msg[i].len;
|
||||
wLen = msg[i].len;
|
||||
|
||||
} else if (msg[i].wbuf && !msg[i].rbuf) {
|
||||
config.common_config.trans_mode = spi_trans_write_only;
|
||||
rLen = 0;
|
||||
wLen = msg[i].len;
|
||||
} else if (!msg[i].wbuf && msg[i].rbuf) {
|
||||
config.common_config.trans_mode = spi_trans_read_only;
|
||||
rLen = msg[i].len;
|
||||
wLen = 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = spi_transfer(base, &config, NULL, NULL,
|
||||
msg[i].wbuf, wLen, msg[i].rbuf, rLen);
|
||||
if (ret != status_success) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t HpmSpiOpen(struct SpiCntlr *cntlr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t HpmSpiClose(struct SpiCntlr *cntlr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct SpiCntlrMethod spiCntlrMethod = {
|
||||
.GetCfg = HpmSpiGetCfg,
|
||||
.SetCfg = HpmSpiSetCfg,
|
||||
.Transfer = HpmSpiTransfer,
|
||||
.Open = HpmSpiOpen,
|
||||
.Close = HpmSpiClose,
|
||||
};
|
||||
|
||||
|
||||
static int32_t SpiDriverBind(struct HdfDeviceObject *device)
|
||||
{
|
||||
int32_t ret = HDF_SUCCESS;
|
||||
|
||||
struct SpiCntlr *cntlr = SpiCntlrCreate(device);
|
||||
if (cntlr == NULL) {
|
||||
ret = HDF_FAILURE;
|
||||
HDF_LOGE("Bind: SpiCntlrCreate null\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
HDF_LOGI("Bind: successed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t SpiDriverInit(struct HdfDeviceObject *device)
|
||||
{
|
||||
int32_t ret = HDF_SUCCESS;
|
||||
|
||||
struct SpiCntlr *cntlr = SpiCntlrFromDevice(device);
|
||||
if (cntlr == NULL) {
|
||||
ret = HDF_FAILURE;
|
||||
HDF_LOGE("Init: SpiCntlrFromDevice null\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct HPMSpiDevice *hpmSpiDev = (struct HPMSpiDevice *)OsalMemCalloc(
|
||||
sizeof(struct HPMSpiDevice));
|
||||
if (hpmSpiDev == NULL) {
|
||||
ret = HDF_ERR_MALLOC_FAIL;
|
||||
HDF_LOGE("Init: HPMSpiDevice malloc Failed!!!\n");
|
||||
goto ERROR1;
|
||||
}
|
||||
|
||||
struct DeviceResourceIface *dri = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
|
||||
if (dri == NULL) {
|
||||
ret = HDF_FAILURE;
|
||||
HDF_LOGE("Init: get DeviceResourceIface Failed!!!\n");
|
||||
goto ERROR2;
|
||||
}
|
||||
|
||||
dri->GetUint32(device->property, "id", &hpmSpiDev->id, 0);
|
||||
dri->GetUint32(device->property, "base", &hpmSpiDev->base, 0);
|
||||
dri->GetUint32(device->property, "clk_freq", &hpmSpiDev->clkFreq, 0);
|
||||
HDF_LOGI("Init: hpmSpiDev->id: %u\n", hpmSpiDev->id);
|
||||
HDF_LOGI("Init: hpmSpiDev->base: 0x%X\n", hpmSpiDev->base);
|
||||
HDF_LOGI("Init: hpmSpiDev->clkFreq: %u\n", hpmSpiDev->clkFreq);
|
||||
|
||||
cntlr->busNum = hpmSpiDev->id;
|
||||
cntlr->priv = hpmSpiDev;
|
||||
cntlr->method = &spiCntlrMethod;
|
||||
|
||||
return ret;
|
||||
|
||||
ERROR2:
|
||||
OsalMemFree(hpmSpiDev);
|
||||
ERROR1:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void SpiDriverRelease(struct HdfDeviceObject *device)
|
||||
{
|
||||
if (device == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct SpiCntlr *cntlr = SpiCntlrFromDevice(device);
|
||||
if (cntlr == NULL) {
|
||||
HDF_LOGE("Release: SpiCntlrFromDevice null\n");
|
||||
return;
|
||||
}
|
||||
|
||||
struct HPMSpiDevice *hpmSpiDev = (struct HPMSpiDevice *)cntlr->priv;
|
||||
|
||||
if (hpmSpiDev) {
|
||||
OsalMemFree(hpmSpiDev);
|
||||
}
|
||||
|
||||
SpiCntlrDestroy(cntlr);
|
||||
|
||||
HDF_LOGI("Release");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
struct HdfDriverEntry g_spiDriverEntry = {
|
||||
.moduleVersion = 1,
|
||||
.moduleName = "HPMICRO_SPI_MODULE_HDF",
|
||||
.Bind = SpiDriverBind,
|
||||
.Init = SpiDriverInit,
|
||||
.Release = SpiDriverRelease,
|
||||
};
|
||||
|
||||
HDF_INIT(g_spiDriverEntry);
|
||||
@@ -35,7 +35,6 @@ struct HPMUartDevice {
|
||||
uint32_t irq;
|
||||
uint32_t clkFreq;
|
||||
struct UartAttribute attribute;
|
||||
uint8_t isInited;
|
||||
uint32_t baudRate;
|
||||
uint8_t isRxBlock;
|
||||
uint8_t isRxDmaEn;
|
||||
@@ -292,8 +291,8 @@ static int32_t UartDriverInit(struct HdfDeviceObject *device)
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct HPMUartDevice *hpmUartDev = (struct HPMUartDevice *)OsalMemCalloc(
|
||||
sizeof(struct HPMUartDevice ));
|
||||
struct HPMUartDevice *hpmUartDev = (struct HPMUartDevice *)OsalMemCalloc(
|
||||
sizeof(struct HPMUartDevice));
|
||||
if (hpmUartDev == NULL) {
|
||||
ret = HDF_ERR_MALLOC_FAIL;
|
||||
HDF_LOGE("Init: HPMUartDevice malloc Failed!!!\n");
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "device_resource_if.h"
|
||||
#include "hdf_device_desc.h"
|
||||
#include "hdf_log.h"
|
||||
#include "osal_mem.h"
|
||||
#include "watchdog_if.h"
|
||||
#include "watchdog_core.h"
|
||||
#include "hpm_wdg_drv.h"
|
||||
@@ -19,7 +20,7 @@
|
||||
|
||||
struct HPMWatchdogDevice {
|
||||
uint32_t id;
|
||||
void *base;
|
||||
uint32_t base;
|
||||
int32_t status;
|
||||
uint32_t timeoutSeconds;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
root {
|
||||
platform {
|
||||
template config_i2c {
|
||||
match_attr = "";
|
||||
id = 0;
|
||||
base = 0; /* register base address */
|
||||
clk_freq = 24000000; /* spi controler ip frequency in HZ */
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
root {
|
||||
platform {
|
||||
template config_spi {
|
||||
match_attr = "";
|
||||
id = 0;
|
||||
base = 0; /* register base address */
|
||||
clk_freq = 24000000; /* spi controler ip frequency in HZ */
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
#include "../config_template/watchdog.hcs"
|
||||
#include "../config_template/gpio.hcs"
|
||||
#include "../config_template/uart.hcs"
|
||||
#include "../config_template/i2c.hcs"
|
||||
#include "../config_template/spi.hcs"
|
||||
|
||||
|
||||
@@ -28,6 +28,8 @@ kernel_module(module_name) {
|
||||
"${hpm_sdk_path}/drivers/src/hpm_pmp_drv.c",
|
||||
"${hpm_sdk_path}/drivers/src/hpm_can_drv.c",
|
||||
"${hpm_sdk_path}/drivers/src/hpm_wdg_drv.c",
|
||||
"${hpm_sdk_path}/drivers/src/hpm_i2c_drv.c",
|
||||
"${hpm_sdk_path}/drivers/src/hpm_spi_drv.c",
|
||||
]
|
||||
|
||||
if (defined(LOSCFG_SOC_HPM6750)) {
|
||||
|
||||
Reference in New Issue
Block a user