diff --git a/model/sensor/driver/chipset/hall/hall_ak8789.c b/model/sensor/driver/chipset/hall/hall_ak8789.c index f33fb01cd45745e60424d0318ee793666646dba6..adbd7838b506f8042219477d9a77f7ea673565aa 100755 --- a/model/sensor/driver/chipset/hall/hall_ak8789.c +++ b/model/sensor/driver/chipset/hall/hall_ak8789.c @@ -1,88 +1,155 @@ -/* - * 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 "hall_ak8789.h" -#include -#include "osal_irq.h" -#include "osal_time.h" -#include "sensor_config_controller.h" -#include "sensor_device_manager.h" -#include "sensor_hall_driver.h" - -#define HDF_LOG_TAG hall_ak8789_c - -/* IO config for int-pin and Gpio-pin */ -#define SENSOR_HALL_DATA_REG_ADDR 0x114f0040 -#define SENSOR_HALL_CLK_REG_ADDR 0x114f0044 -#define SENSOR_HALL_REG_CFG 0x400 - -int32_t ReadAk8789Data(struct SensorCfgData *data) -{ - int32_t ret; - uint8_t tmp = 1; - OsalTimespec time; - struct SensorReportEvent event; - - CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM); - - (void)memset_s(&event, sizeof(event), 0, sizeof(event)); - (void)memset_s(&time, sizeof(time), 0, sizeof(time)); - if (OsalGetTime(&time) != HDF_SUCCESS) { - HDF_LOGE("%s: Get time failed", __func__); - return HDF_FAILURE; - } - - event.timestamp = time.sec * SENSOR_SECOND_CONVERT_NANOSECOND + time.usec * - SENSOR_CONVERT_UNIT; /* unit nanosecond */ - event.sensorId = SENSOR_TAG_HALL; - event.version = 0; - event.option = 0; - event.mode = SENSOR_WORK_MODE_ON_CHANGE; - event.dataLen = sizeof(tmp); - event.data = (uint8_t *)&tmp; - ret = ReportSensorEvent(&event); - return ret; -} - -static int32_t InitHallPreConfig(void) -{ - if (SetSensorPinMux(SENSOR_HALL_DATA_REG_ADDR, SENSOR_ADDR_WIDTH_4_BYTE, SENSOR_HALL_REG_CFG) != HDF_SUCCESS) { - HDF_LOGE("%s: Data write mux pin failed", __func__); - return HDF_FAILURE; - } - if (SetSensorPinMux(SENSOR_HALL_CLK_REG_ADDR, SENSOR_ADDR_WIDTH_4_BYTE, SENSOR_HALL_REG_CFG) != HDF_SUCCESS) { - HDF_LOGE("%s: Clk write mux pin failed", __func__); - return HDF_FAILURE; - } - return HDF_SUCCESS; -} - -int32_t DetectHallAk8789Chip(struct SensorCfgData *data) -{ - int32_t ret; - struct HallOpsCall ops; - - CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM); - - if (strcmp(HALL_CHIP_NAME_AK8789, data->sensorAttr.chipName) != 0) { - return HDF_SUCCESS; - } - ret = InitHallPreConfig(); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: init AK8789 bus mux config", __func__); - return HDF_FAILURE; - } - ops.Init = NULL; - ops.ReadData = ReadAk8789Data; - ret = RegisterHallChipOps(&ops); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: register AK8789 hall failed", __func__); - return HDF_FAILURE; - } - return HDF_SUCCESS; -} \ No newline at end of file +/* + * 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 "hall_ak8789.h" +#include +#include "osal_irq.h" +#include "osal_mem.h" +#include "osal_time.h" +#include "sensor_config_controller.h" +#include "sensor_device_manager.h" +#include "sensor_hall_driver.h" + +#define HDF_LOG_TAG hall_ak8789_c + +static struct Ak8789DrvData *g_ak8789DrvData = NULL; + +struct Ak8789DrvData *Ak8789GetDrvData(void) +{ + return g_ak8789DrvData; +} + +/* IO config for int-pin and Gpio-pin */ +#define SENSOR_HALL_DATA_REG_ADDR 0x114f0040 +#define SENSOR_HALL_CLK_REG_ADDR 0x114f0044 +#define SENSOR_HALL_REG_CFG 0x400 + +int32_t ReadAk8789Data(struct SensorCfgData *data) +{ + int32_t ret; + uint8_t tmp = 1; + OsalTimespec time; + struct SensorReportEvent event; + + CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM); + + (void)memset_s(&event, sizeof(event), 0, sizeof(event)); + (void)memset_s(&time, sizeof(time), 0, sizeof(time)); + if (OsalGetTime(&time) != HDF_SUCCESS) { + HDF_LOGE("%s: Get time failed", __func__); + return HDF_FAILURE; + } + + event.timestamp = time.sec * SENSOR_SECOND_CONVERT_NANOSECOND + time.usec * + SENSOR_CONVERT_UNIT; /* unit nanosecond */ + event.sensorId = SENSOR_TAG_HALL; + event.version = 0; + event.option = 0; + event.mode = SENSOR_WORK_MODE_ON_CHANGE; + event.dataLen = sizeof(tmp); + event.data = (uint8_t *)&tmp; + ret = ReportSensorEvent(&event); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: AK8789 report data failed", __func__); + } + return ret; +} + +static int32_t InitHallPreConfig(void) +{ + if (SetSensorPinMux(SENSOR_HALL_DATA_REG_ADDR, SENSOR_ADDR_WIDTH_4_BYTE, SENSOR_HALL_REG_CFG) != HDF_SUCCESS) { + HDF_LOGE("%s: Data write mux pin failed", __func__); + return HDF_FAILURE; + } + if (SetSensorPinMux(SENSOR_HALL_CLK_REG_ADDR, SENSOR_ADDR_WIDTH_4_BYTE, SENSOR_HALL_REG_CFG) != HDF_SUCCESS) { + HDF_LOGE("%s: Clk write mux pin failed", __func__); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +static int32_t DispatchAK8789(struct HdfDeviceIoClient *client, + int cmd, struct HdfSBuf *data, struct HdfSBuf *reply) +{ + (void)client; + (void)cmd; + (void)data; + (void)reply; + + return HDF_SUCCESS; +} + +int32_t Ak8789BindDriver(struct HdfDeviceObject *device) +{ + CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM); + + struct Ak8789DrvData *drvData = (struct Ak8789DrvData *)OsalMemCalloc(sizeof(*drvData)); + if (drvData == NULL) { + HDF_LOGE("%s: Malloc Ak8789 drv data fail", __func__); + return HDF_ERR_MALLOC_FAIL; + } + + drvData->ioService.Dispatch = DispatchAK8789; + drvData->device = device; + device->service = &drvData->ioService; + g_ak8789DrvData = drvData; + + return HDF_SUCCESS; +} + +int32_t AK8789InitDriver(struct HdfDeviceObject *device) +{ + int32_t ret; + struct HallOpsCall ops; + CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM); + struct Ak8789DrvData *drvData = (struct Ak8789DrvData *)device->service; + CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM); + + ret = InitHallPreConfig(); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: Init AK8789 bus mux config", __func__); + return HDF_FAILURE; + } + + drvData->sensorCfg = HallCreateCfgData(device->property); + if (drvData->sensorCfg == NULL) { + return HDF_ERR_NOT_SUPPORT; + } + + ops.Init = NULL; + ops.ReadData = ReadAk8789Data; + ret = HallRegisterChipOps(&ops); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: Register AK8789 hall failed", __func__); + return HDF_FAILURE; + } + + return HDF_SUCCESS; +} + +void Ak8789ReleaseDriver(struct HdfDeviceObject *device) +{ + CHECK_NULL_PTR_RETURN(device); + + struct Ak8789DrvData *drvData = (struct Ak8789DrvData *)device->service; + CHECK_NULL_PTR_RETURN(drvData); + + HallReleaseCfgData(drvData->sensorCfg); + drvData->sensorCfg = NULL; + OsalMemFree(drvData); +} + +struct HdfDriverEntry g_hallAk8789DevEntry = { + .moduleVersion = 1, + .moduleName = "HDF_SENSOR_HALL_AK8789", + .Bind = Ak8789BindDriver, + .Init = AK8789InitDriver, + .Release = Ak8789ReleaseDriver, +}; + +HDF_INIT(g_hallAk8789DevEntry); \ No newline at end of file diff --git a/model/sensor/driver/chipset/hall/hall_ak8789.h b/model/sensor/driver/chipset/hall/hall_ak8789.h index 003c89fb48182cb14c4e64800f597ee5b0ce2982..57af06e19b5c1124af675441d99d155835ecab7f 100755 --- a/model/sensor/driver/chipset/hall/hall_ak8789.h +++ b/model/sensor/driver/chipset/hall/hall_ak8789.h @@ -1,17 +1,24 @@ -/* - * 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 HALL_AK8789_H -#define HALL_AK8789_H - -#include "sensor_config_parser.h" - -int32_t DetectHallAk8789Chip(struct SensorCfgData *data); -int32_t ReadAk8789Data(struct SensorCfgData *data); - -#endif /* HALL_AK8789_H */ +/* + * 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 HALL_AK8789_H +#define HALL_AK8789_H + +#include "sensor_config_parser.h" +#include "sensor_hall_driver.h" + +int32_t DetectHallAk8789Chip(struct SensorCfgData *data); +int32_t ReadAk8789Data(struct SensorCfgData *data); + +struct Ak8789DrvData { + struct IDeviceIoService ioService; + struct HdfDeviceObject *device; + struct SensorCfgData *sensorCfg; +}; + +#endif /* HALL_AK8789_H */ \ No newline at end of file diff --git a/model/sensor/driver/hall/sensor_hall_driver.c b/model/sensor/driver/hall/sensor_hall_driver.c index f27476036e18090a05f49f0e0efd52d9dcae882d..f8383e40a370c6f2c4b9f6084aaaa46da846b1d9 100755 --- a/model/sensor/driver/hall/sensor_hall_driver.c +++ b/model/sensor/driver/hall/sensor_hall_driver.c @@ -1,439 +1,428 @@ -/* - * 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 "sensor_hall_driver.h" -#include -#include "gpio_if.h" -#include "hall_ak8789.h" -#include "hdf_base.h" -#include "hdf_device_desc.h" -#include "osal_irq.h" -#include "osal_math.h" -#include "osal_mem.h" -#include "sensor_config_controller.h" -#include "sensor_device_manager.h" -#include "sensor_platform_if.h" - -#define HDF_LOG_TAG sensor_hall_driver_c -#define HDF_HALL_WORK_QUEUE_NAME "hdf_hall_work_queue" - -static struct HallDetectIfList g_hallDetectIfList[] = { - {HALL_CHIP_NAME_AK8789, DetectHallAk8789Chip}, -}; - -static struct HallDrvData *g_hallDrvData = NULL; - -static struct HallDrvData *HallGetDrvData(void) -{ - return g_hallDrvData; -} - -int32_t RegisterHallChipOps(const struct HallOpsCall *ops) -{ - struct HallDrvData *drvData = NULL; - - CHECK_NULL_PTR_RETURN_VALUE(ops, HDF_ERR_INVALID_PARAM); - drvData = HallGetDrvData(); - CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM); - drvData->ops.Init = ops->Init; - drvData->ops.ReadData = ops->ReadData; - return HDF_SUCCESS; -} - -static void HallDataWorkEntry(void *arg) -{ - int32_t ret; - struct HallDrvData *drvData = (struct HallDrvData *)arg; - CHECK_NULL_PTR_RETURN(drvData); - CHECK_NULL_PTR_RETURN(drvData->ops.ReadData); - - ret = drvData->ops.ReadData(drvData->hallCfg); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: hall read data failed", __func__); - return; - } -} - -static int32_t HallNorthPolarityIrqFunc(uint16_t gpio, void *data) -{ - (void)gpio; - - struct HallDrvData *drvData = (struct HallDrvData *)data; - CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM); - - if (!HdfAddWork(&drvData->hallWorkQueue, &drvData->hallWork)) { - HDF_LOGE("%s: hall add work queue failed", __func__); - } - - return HDF_SUCCESS; -} - -static int32_t HallSouthPolarityIrqFunc(uint16_t gpio, void *data) -{ - (void)gpio; - - struct HallDrvData *drvData = (struct HallDrvData *)data; - CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM); - - if (!HdfAddWork(&drvData->hallWorkQueue, &drvData->hallWork)) { - HDF_LOGE("%s: hall add work queue failed", __func__); - } - - return HDF_SUCCESS; -} - -static int32_t InitHallData(void) -{ - struct HallDrvData *drvData = HallGetDrvData(); - CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM); - - if (drvData->initStatus) { - return HDF_SUCCESS; - } - - if (HdfWorkQueueInit(&drvData->hallWorkQueue, HDF_HALL_WORK_QUEUE_NAME) != HDF_SUCCESS) { - HDF_LOGE("%s: hall init work queue failed", __func__); - return HDF_FAILURE; - } - - if (HdfWorkInit(&drvData->hallWork, HallDataWorkEntry, drvData) != HDF_SUCCESS) { - HDF_LOGE("%s: hall create thread failed", __func__); - return HDF_FAILURE; - } - - drvData->interval = SENSOR_TIMER_MIN_TIME; - drvData->initStatus = true; - drvData->enable = false; - - return HDF_SUCCESS; -} - -static int32_t SetHallEnable(void) -{ - int32_t ret; - struct HallDrvData *drvData = HallGetDrvData(); - CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM); - - if (drvData->enable) { - HDF_LOGE("%s: hall sensor is enabled", __func__); - return HDF_SUCCESS; - } - - if (drvData->GpioIrq[HALL_NORTH_POLARITY_GPIO] >= 0) { - ret = GpioSetIrq(drvData->GpioIrq[HALL_NORTH_POLARITY_GPIO], OSAL_IRQF_TRIGGER_FALLING, - HallNorthPolarityIrqFunc, drvData); - if (ret != 0) { - HDF_LOGE("gpio set north irq failed: %d", ret); - } - ret = GpioEnableIrq(drvData->GpioIrq[HALL_NORTH_POLARITY_GPIO]); - if (ret != 0) { - HDF_LOGE("gpio enable north irq failed: %d", ret); - } - } - - if (drvData->GpioIrq[HALL_SOUTH_POLARITY_GPIO] >= 0) { - ret = GpioSetIrq(drvData->GpioIrq[HALL_SOUTH_POLARITY_GPIO], OSAL_IRQF_TRIGGER_FALLING, - HallSouthPolarityIrqFunc, drvData); - if (ret != 0) { - HDF_LOGE("%s: gpio set south irq failed", __func__); - } - ret = GpioEnableIrq(drvData->GpioIrq[HALL_SOUTH_POLARITY_GPIO]); - if (ret != 0) { - HDF_LOGE("%s: gpio enable south irq failed", __func__); - } - } - - drvData->enable = true; - return HDF_SUCCESS; -} - -static int32_t SetHallDisable(void) -{ - int32_t ret; - struct HallDrvData *drvData = HallGetDrvData(); - CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM); - - if (!drvData->enable) { - HDF_LOGE("%s: hall sensor had disable", __func__); - return HDF_SUCCESS; - } - - if (drvData->GpioIrq[HALL_NORTH_POLARITY_GPIO] >= 0) { - ret = GpioUnSetIrq(drvData->GpioIrq[HALL_NORTH_POLARITY_GPIO]); - if (ret != 0) { - HDF_LOGE("%s: gpio unset north irq failed", __func__); - } - - ret = GpioDisableIrq(drvData->GpioIrq[HALL_NORTH_POLARITY_GPIO]); - if (ret != 0) { - HDF_LOGE("%s: gpio disable north irq failed", __func__); - } - } - - if (drvData->GpioIrq[HALL_SOUTH_POLARITY_GPIO] >= 0) { - ret = GpioUnSetIrq(drvData->GpioIrq[HALL_SOUTH_POLARITY_GPIO]); - if (ret != 0) { - HDF_LOGE("%s: gpio unset south irq failed", __func__); - } - - ret = GpioDisableIrq(drvData->GpioIrq[HALL_SOUTH_POLARITY_GPIO]); - if (ret != 0) { - HDF_LOGE("%s: gpio disable south irq failed", __func__); - } - } - - drvData->enable = false; - return HDF_SUCCESS; -} - -static int32_t SetHallBatch(int64_t samplingInterval, int64_t interval) -{ - return HDF_SUCCESS; -} - -static int32_t SetHallMode(int32_t mode) -{ - return (mode == SENSOR_WORK_MODE_ON_CHANGE) ? HDF_SUCCESS : HDF_FAILURE; -} - -static int32_t SetHallOption(uint32_t option) -{ - (void)option; - return HDF_SUCCESS; -} - -static int32_t DispatchHall(struct HdfDeviceIoClient *client, - int cmd, struct HdfSBuf *data, struct HdfSBuf *reply) -{ - (void)client; - (void)cmd; - (void)data; - (void)reply; - - return HDF_SUCCESS; -} - -int32_t BindHallDriver(struct HdfDeviceObject *device) -{ - CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM); - - struct HallDrvData *drvData = (struct HallDrvData *)OsalMemCalloc(sizeof(*drvData)); - if (drvData == NULL) { - HDF_LOGE("%s: malloc hall drv data fail!", __func__); - return HDF_ERR_MALLOC_FAIL; - } - - drvData->ioService.Dispatch = DispatchHall; - drvData->device = device; - device->service = &drvData->ioService; - g_hallDrvData = drvData; - return HDF_SUCCESS; -} - -static int32_t InitHallOps(struct SensorDeviceInfo *deviceInfo) -{ - struct HallDrvData *drvData = HallGetDrvData(); - CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM); - - deviceInfo->ops.Enable = SetHallEnable; - deviceInfo->ops.Disable = SetHallDisable; - deviceInfo->ops.SetBatch = SetHallBatch; - deviceInfo->ops.SetMode = SetHallMode; - deviceInfo->ops.SetOption = SetHallOption; - - if (memcpy_s(&deviceInfo->sensorInfo, sizeof(deviceInfo->sensorInfo), - &drvData->hallCfg->sensorInfo, sizeof(drvData->hallCfg->sensorInfo)) != EOK) { - HDF_LOGE("%s: copy sensor info failed", __func__); - return HDF_FAILURE; - } - - return HDF_SUCCESS; -} - -static int32_t InitHallAfterConfig(void) -{ - struct SensorDeviceInfo deviceInfo; - - if (InitHallData() != HDF_SUCCESS) { - HDF_LOGE("%s: init hall config failed", __func__); - return HDF_FAILURE; - } - - if (InitHallOps(&deviceInfo) != HDF_SUCCESS) { - HDF_LOGE("%s: init hall ops failed", __func__); - return HDF_FAILURE; - } - - if (AddSensorDevice(&deviceInfo) != HDF_SUCCESS) { - HDF_LOGE("%s: add hall device failed", __func__); - return HDF_FAILURE; - } - - return HDF_SUCCESS; -} - -static int32_t DetectHallChip(void) -{ - int32_t num; - int32_t ret; - int32_t loop; - struct HallDrvData *drvData = HallGetDrvData(); - - CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM); - CHECK_NULL_PTR_RETURN_VALUE(drvData->hallCfg, HDF_ERR_INVALID_PARAM); - - num = sizeof(g_hallDetectIfList) / sizeof(g_hallDetectIfList[0]); - for (loop = 0; loop < num; ++loop) { - if (g_hallDetectIfList[loop].DetectChip != NULL) { - ret = g_hallDetectIfList[loop].DetectChip(drvData->hallCfg); - if (ret == HDF_SUCCESS) { - drvData->detectFlag = true; - return HDF_SUCCESS; - } - } - } - - HDF_LOGE("%s: detect hall device failed", __func__); - drvData->detectFlag = false; - return HDF_FAILURE; -} - -static int32_t ParserHallPinConfigData(const struct DeviceResourceNode *node, struct HallDrvData *drvData) -{ - int32_t ret; - struct DeviceResourceIface *parser = NULL; - - CHECK_NULL_PTR_RETURN_VALUE(node, HDF_ERR_INVALID_PARAM); - CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM); - - parser = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); - CHECK_NULL_PTR_RETURN_VALUE(parser, HDF_ERR_INVALID_PARAM); - - CHECK_NULL_PTR_RETURN_VALUE(parser->GetChildNode, HDF_ERR_INVALID_PARAM); - - const struct DeviceResourceNode *pinNode = parser->GetChildNode(node, "hallPinConfig"); - CHECK_NULL_PTR_RETURN_VALUE(pinNode, HDF_ERR_INVALID_PARAM); - - ret = parser->GetUint32(pinNode, "NorthPolarityGpio", (uint32_t *)&drvData->GpioIrq[HALL_NORTH_POLARITY_GPIO], 0); - CHECK_PARSER_RESULT_RETURN_VALUE(ret, "NorthPolarityGpio"); - ret = parser->GetUint32(pinNode, "SouthPolarityGpio", (uint32_t *)&drvData->GpioIrq[HALL_SOUTH_POLARITY_GPIO], 0); - CHECK_PARSER_RESULT_RETURN_VALUE(ret, "SouthPolarityGpio"); - - return HDF_SUCCESS; -} - -static int32_t SetHallGpioPin(const struct DeviceResourceNode *node, struct HallDrvData *drvData) -{ - if (ParserHallPinConfigData(node, drvData) != HDF_SUCCESS) { - HDF_LOGE("%s: get hall pin config failed", __func__); - return HDF_FAILURE; - } - - if (drvData->GpioIrq[HALL_NORTH_POLARITY_GPIO] >= 0) { - int ret = GpioSetDir(drvData->GpioIrq[HALL_NORTH_POLARITY_GPIO], GPIO_DIR_IN); - if (ret != 0) { - HDF_LOGE("%s:%d set north gpio dir failed", __func__, __LINE__); - return HDF_FAILURE; - } - } - - if (drvData->GpioIrq[HALL_SOUTH_POLARITY_GPIO] >= 0) { - int ret = GpioSetDir(drvData->GpioIrq[HALL_SOUTH_POLARITY_GPIO], GPIO_DIR_IN); - if (ret != 0) { - HDF_LOGE("%s:%d south south gpio dir failed", __func__, __LINE__); - return HDF_FAILURE; - } - } - - return HDF_SUCCESS; -} - -int32_t InitHallDriver(struct HdfDeviceObject *device) -{ - struct HallDrvData *drvData = NULL; - - CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM); - drvData = (struct HallDrvData *)device->service; - CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM); - - if (drvData->detectFlag) { - HDF_LOGE("%s: hall sensor have detected", __func__); - return HDF_SUCCESS; - } - - drvData->hallCfg = (struct SensorCfgData *)OsalMemCalloc(sizeof(*drvData->hallCfg)); - if (drvData->hallCfg == NULL) { - HDF_LOGE("%s: malloc sensor config data failed", __func__); - return HDF_FAILURE; - } - - if (GetSensorBaseConfigData(device->property, drvData->hallCfg) != HDF_SUCCESS) { - HDF_LOGE("%s: get sensor base config failed", __func__); - goto BASE_CONFIG_EXIT; - } - - if (SetHallGpioPin(device->property, drvData) != HDF_SUCCESS) { - HDF_LOGE("%s: set hall gpio pin failed", __func__); - goto BASE_CONFIG_EXIT; - } - - if (DetectHallChip() != HDF_SUCCESS) { - HDF_LOGE("%s: hall sensor detect device no exist", __func__); - goto DETECT_CHIP_EXIT; - } - - drvData->detectFlag = true; - - if (InitHallAfterConfig() != HDF_SUCCESS) { - HDF_LOGE("%s: init hall after config failed", __func__); - goto INIT_EXIT; - } - - HDF_LOGI("%s: init hall driver success", __func__); - return HDF_SUCCESS; - -INIT_EXIT: - (void)DeleteSensorDevice(&drvData->hallCfg->sensorInfo); -DETECT_CHIP_EXIT: - drvData->detectFlag = false; -BASE_CONFIG_EXIT: - drvData->hallCfg->root = NULL; - OsalMemFree(drvData->hallCfg); - drvData->hallCfg = NULL; - return HDF_FAILURE; -} - -void ReleaseHallDriver(struct HdfDeviceObject *device) -{ - struct HallDrvData *drvData = NULL; - CHECK_NULL_PTR_RETURN(device); - - drvData = (struct HallDrvData *)device->service; - CHECK_NULL_PTR_RETURN(drvData); - - (void)DeleteSensorDevice(&drvData->hallCfg->sensorInfo); - drvData->detectFlag = false; - - if (drvData->hallCfg != NULL) { - drvData->hallCfg->root = NULL; - OsalMemFree(drvData->hallCfg); - drvData->hallCfg = NULL; - } - - drvData->initStatus = false; -} - -struct HdfDriverEntry g_sensorHallDevEntry = { - .moduleVersion = 1, - .moduleName = "HDF_SENSOR_HALL", - .Bind = BindHallDriver, - .Init = InitHallDriver, - .Release = ReleaseHallDriver, -}; - +/* + * 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 "sensor_hall_driver.h" +#include +#include "gpio_if.h" +#include "hall_ak8789.h" +#include "hdf_base.h" +#include "hdf_device_desc.h" +#include "osal_irq.h" +#include "osal_math.h" +#include "osal_mem.h" +#include "sensor_config_controller.h" +#include "sensor_device_manager.h" +#include "sensor_platform_if.h" + +#define HDF_LOG_TAG sensor_hall_driver_c +#define HDF_HALL_WORK_QUEUE_NAME "hdf_hall_work_queue" + +static struct HallDrvData *g_hallDrvData = NULL; + +static struct HallDrvData *HallGetDrvData(void) +{ + return g_hallDrvData; +} + +int32_t HallRegisterChipOps(const struct HallOpsCall *ops) +{ + struct HallDrvData *drvData = HallGetDrvData(); + + CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM); + CHECK_NULL_PTR_RETURN_VALUE(ops, HDF_ERR_INVALID_PARAM); + + drvData->ops.Init = ops->Init; + drvData->ops.ReadData = ops->ReadData; + return HDF_SUCCESS; +} + +static void HallDataWorkEntry(void *arg) +{ + struct HallDrvData *drvData = NULL; + + drvData = (struct HallDrvData *)arg; + CHECK_NULL_PTR_RETURN(drvData); + + if (drvData->ops.ReadData == NULL) { + HDF_LOGI("%s: Hall ReadData function NULL", __func__); + return; + } + if (drvData->ops.ReadData(drvData->hallCfg) != HDF_SUCCESS) { + HDF_LOGE("%s: Hall read data failed", __func__); + } +} + +static int32_t HallNorthPolarityIrqFunc(uint16_t gpio, void *data) +{ + (void)gpio; + + struct HallDrvData *drvData = (struct HallDrvData *)data; + CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM); + + if (!HdfAddWork(&drvData->hallWorkQueue, &drvData->hallWork)) { + HDF_LOGE("%s: Hall add work queue failed", __func__); + } + + return HDF_SUCCESS; +} + +static int32_t HallSouthPolarityIrqFunc(uint16_t gpio, void *data) +{ + (void)gpio; + + struct HallDrvData *drvData = (struct HallDrvData *)data; + CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM); + + if (!HdfAddWork(&drvData->hallWorkQueue, &drvData->hallWork)) { + HDF_LOGE("%s: Hall add work queue failed", __func__); + } + + return HDF_SUCCESS; +} + +static int32_t InitHallData(struct HallDrvData *drvData) +{ + if (HdfWorkQueueInit(&drvData->hallWorkQueue, HDF_HALL_WORK_QUEUE_NAME) != HDF_SUCCESS) { + HDF_LOGE("%s: Hall init work queue failed", __func__); + return HDF_FAILURE; + } + + if (HdfWorkInit(&drvData->hallWork, HallDataWorkEntry, drvData) != HDF_SUCCESS) { + HDF_LOGE("%s: Hall create thread failed", __func__); + return HDF_FAILURE; + } + + drvData->interval = SENSOR_TIMER_MIN_TIME; + drvData->enable = false; + drvData->detectFlag = false; + + return HDF_SUCCESS; +} + +static int32_t SetHallEnable(void) +{ + int32_t ret; + struct HallDrvData *drvData = HallGetDrvData(); + CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM); + + if (drvData->enable) { + HDF_LOGE("%s: Hall sensor is enabled", __func__); + return HDF_SUCCESS; + } + + if (drvData->GpioIrq[HALL_NORTH_POLARITY_GPIO] >= 0) { + ret = GpioSetIrq(drvData->GpioIrq[HALL_NORTH_POLARITY_GPIO], OSAL_IRQF_TRIGGER_FALLING, + HallNorthPolarityIrqFunc, drvData); + if (ret != 0) { + HDF_LOGE("Gpio set north irq failed: %d", ret); + } + ret = GpioEnableIrq(drvData->GpioIrq[HALL_NORTH_POLARITY_GPIO]); + if (ret != 0) { + HDF_LOGE("Gpio enable north irq failed: %d", ret); + } + } + + if (drvData->GpioIrq[HALL_SOUTH_POLARITY_GPIO] >= 0) { + ret = GpioSetIrq(drvData->GpioIrq[HALL_SOUTH_POLARITY_GPIO], OSAL_IRQF_TRIGGER_FALLING, + HallSouthPolarityIrqFunc, drvData); + if (ret != 0) { + HDF_LOGE("%s: Gpio set south irq failed", __func__); + } + ret = GpioEnableIrq(drvData->GpioIrq[HALL_SOUTH_POLARITY_GPIO]); + if (ret != 0) { + HDF_LOGE("%s: Gpio enable south irq failed", __func__); + } + } + + drvData->enable = true; + return HDF_SUCCESS; +} + +static int32_t SetHallDisable(void) +{ + int32_t ret; + struct HallDrvData *drvData = HallGetDrvData(); + CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM); + + if (!drvData->enable) { + HDF_LOGE("%s: Hall sensor had disable", __func__); + return HDF_SUCCESS; + } + + if (drvData->GpioIrq[HALL_NORTH_POLARITY_GPIO] >= 0) { + ret = GpioUnSetIrq(drvData->GpioIrq[HALL_NORTH_POLARITY_GPIO]); + if (ret != 0) { + HDF_LOGE("%s: Gpio unset north irq failed", __func__); + } + + ret = GpioDisableIrq(drvData->GpioIrq[HALL_NORTH_POLARITY_GPIO]); + if (ret != 0) { + HDF_LOGE("%s: Gpio disable north irq failed", __func__); + } + } + + if (drvData->GpioIrq[HALL_SOUTH_POLARITY_GPIO] >= 0) { + ret = GpioUnSetIrq(drvData->GpioIrq[HALL_SOUTH_POLARITY_GPIO]); + if (ret != 0) { + HDF_LOGE("%s: Gpio unset south irq failed", __func__); + } + + ret = GpioDisableIrq(drvData->GpioIrq[HALL_SOUTH_POLARITY_GPIO]); + if (ret != 0) { + HDF_LOGE("%s: Gpio disable south irq failed", __func__); + } + } + drvData->enable = false; + + return HDF_SUCCESS; +} + +static int32_t SetHallBatch(int64_t samplingInterval, int64_t interval) +{ + return HDF_SUCCESS; +} + +static int32_t SetHallMode(int32_t mode) +{ + return (mode == SENSOR_WORK_MODE_ON_CHANGE) ? HDF_SUCCESS : HDF_FAILURE; +} + +static int32_t SetHallOption(uint32_t option) +{ + (void)option; + return HDF_SUCCESS; +} + +static int32_t DispatchHall(struct HdfDeviceIoClient *client, + int cmd, struct HdfSBuf *data, struct HdfSBuf *reply) +{ + (void)client; + (void)cmd; + (void)data; + (void)reply; + + return HDF_SUCCESS; +} + +int32_t HallBindDriver(struct HdfDeviceObject *device) +{ + CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM); + + struct HallDrvData *drvData = (struct HallDrvData *)OsalMemCalloc(sizeof(*drvData)); + if (drvData == NULL) { + HDF_LOGE("%s: Malloc hall drv data fail!", __func__); + return HDF_ERR_MALLOC_FAIL; + } + + drvData->ioService.Dispatch = DispatchHall; + drvData->device = device; + device->service = &drvData->ioService; + g_hallDrvData = drvData; + return HDF_SUCCESS; +} + +static int32_t InitHallOps(struct SensorCfgData *config, struct SensorDeviceInfo *deviceInfo) +{ + CHECK_NULL_PTR_RETURN_VALUE(config, HDF_ERR_INVALID_PARAM); + + deviceInfo->ops.Enable = SetHallEnable; + deviceInfo->ops.Disable = SetHallDisable; + deviceInfo->ops.SetBatch = SetHallBatch; + deviceInfo->ops.SetMode = SetHallMode; + deviceInfo->ops.SetOption = SetHallOption; + + if (memcpy_s(&deviceInfo->sensorInfo, sizeof(deviceInfo->sensorInfo), + &config->sensorInfo, sizeof(config->sensorInfo)) != EOK) { + HDF_LOGE("%s: Copy sensor info failed", __func__); + return HDF_FAILURE; + } + + return HDF_SUCCESS; +} + +static int32_t ParserHallPinConfigData(const struct DeviceResourceNode *node, struct HallDrvData *drvData) +{ + int32_t ret; + struct DeviceResourceIface *parser = NULL; + + CHECK_NULL_PTR_RETURN_VALUE(node, HDF_ERR_INVALID_PARAM); + CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM); + + parser = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); + CHECK_NULL_PTR_RETURN_VALUE(parser, HDF_ERR_INVALID_PARAM); + + CHECK_NULL_PTR_RETURN_VALUE(parser->GetChildNode, HDF_ERR_INVALID_PARAM); + + const struct DeviceResourceNode *pinNode = parser->GetChildNode(node, "hallPinConfig"); + CHECK_NULL_PTR_RETURN_VALUE(pinNode, HDF_ERR_INVALID_PARAM); + + ret = parser->GetUint32(pinNode, "NorthPolarityGpio", (uint32_t *)&drvData->GpioIrq[HALL_NORTH_POLARITY_GPIO], 0); + CHECK_PARSER_RESULT_RETURN_VALUE(ret, "NorthPolarityGpio"); + ret = parser->GetUint32(pinNode, "SouthPolarityGpio", (uint32_t *)&drvData->GpioIrq[HALL_SOUTH_POLARITY_GPIO], 0); + CHECK_PARSER_RESULT_RETURN_VALUE(ret, "SouthPolarityGpio"); + + return HDF_SUCCESS; +} + +static int32_t InitHallAfterDetected(const struct DeviceResourceNode *node, struct HallDrvData *drvData) +{ + struct SensorDeviceInfo deviceInfo; + CHECK_NULL_PTR_RETURN_VALUE(node, HDF_ERR_INVALID_PARAM); + CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM); + + if (InitHallOps(drvData->hallCfg, &deviceInfo) != HDF_SUCCESS) { + HDF_LOGE("%s: Init hall ops failed", __func__); + return HDF_FAILURE; + } + + if (AddSensorDevice(&deviceInfo) != HDF_SUCCESS) { + HDF_LOGE("%s: Add hall device failed", __func__); + return HDF_FAILURE; + } + + if (ParserHallPinConfigData(node, drvData) != HDF_SUCCESS) { + HDF_LOGE("%s: get hall pin config failed", __func__); + (void)DeleteSensorDevice(&drvData->hallCfg->sensorInfo); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +static int32_t SetHallGpioPin(struct HallDrvData *drvData) +{ + if (drvData->GpioIrq[HALL_NORTH_POLARITY_GPIO] >= 0) { + int ret = GpioSetDir(drvData->GpioIrq[HALL_NORTH_POLARITY_GPIO], GPIO_DIR_IN); + if (ret != 0) { + HDF_LOGE("%s:%d set north gpio dir failed", __func__, __LINE__); + return HDF_FAILURE; + } + } + + if (drvData->GpioIrq[HALL_SOUTH_POLARITY_GPIO] >= 0) { + int ret = GpioSetDir(drvData->GpioIrq[HALL_SOUTH_POLARITY_GPIO], GPIO_DIR_IN); + if (ret != 0) { + HDF_LOGE("%s:%d south south gpio dir failed", __func__, __LINE__); + return HDF_FAILURE; + } + } + + return HDF_SUCCESS; +} + +struct SensorCfgData *HallCreateCfgData(const struct DeviceResourceNode *node) +{ + struct HallDrvData *drvData = HallGetDrvData(); + + if (drvData == NULL || node == NULL) { + HDF_LOGE("%s: Hall node pointer NULL", __func__); + return NULL; + } + + if (drvData->detectFlag) { + HDF_LOGE("%s: Hall sensor have detected", __func__); + return NULL; + } + + if (drvData->hallCfg == NULL) { + HDF_LOGE("%s: Hall hallCfg pointer NULL", __func__); + return NULL; + } + + if (GetSensorBaseConfigData(node, drvData->hallCfg) != HDF_SUCCESS) { + HDF_LOGE("%s: Get sensor base config failed", __func__); + goto BASE_CONFIG_EXIT; + } + + if (SetHallGpioPin(drvData) != HDF_SUCCESS) { + HDF_LOGE("%s: set hall gpio pin failed", __func__); + goto BASE_CONFIG_EXIT; + } + + if (DetectSensorDevice(drvData->hallCfg) != HDF_SUCCESS) { + HDF_LOGI("%s: Hall sensor detect device no exist", __func__); + drvData->detectFlag = false; + goto BASE_CONFIG_EXIT; + } + + drvData->detectFlag = true; + if (InitHallAfterDetected(node, drvData) != HDF_SUCCESS) { + HDF_LOGE("%s: Hall sensor detect device no exist", __func__); + goto BASE_CONFIG_EXIT; + } + + return drvData->hallCfg; + +BASE_CONFIG_EXIT: + drvData->hallCfg->root = NULL; + (void)memset_s(&drvData->hallCfg->sensorInfo, sizeof(struct SensorBasicInfo), 0, sizeof(struct SensorBasicInfo)); + (void)memset_s(&drvData->hallCfg->sensorAttr, sizeof(struct SensorAttr), 0, sizeof(struct SensorAttr)); + return NULL; +} + +void HallReleaseCfgData(struct SensorCfgData *hallCfg) +{ + CHECK_NULL_PTR_RETURN(hallCfg); + + (void)DeleteSensorDevice(&hallCfg->sensorInfo); + + hallCfg->root = NULL; + (void)memset_s(&hallCfg->sensorInfo, sizeof(struct SensorBasicInfo), 0, sizeof(struct SensorBasicInfo)); + (void)memset_s(&hallCfg->sensorAttr, sizeof(struct SensorAttr), 0, sizeof(struct SensorAttr)); +} + +int32_t HallInitDriver(struct HdfDeviceObject *device) +{ + CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM); + + struct HallDrvData *drvData = (struct HallDrvData *)device->service; + CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM); + + if (InitHallData(drvData) != HDF_SUCCESS) { + HDF_LOGE("%s: Init hall config failed", __func__); + return HDF_FAILURE; + } + + drvData->hallCfg = (struct SensorCfgData *)OsalMemCalloc(sizeof(*drvData->hallCfg)); + if (drvData->hallCfg == NULL) { + HDF_LOGE("%s: Malloc hall config data failed", __func__); + return HDF_FAILURE; + } + + HDF_LOGI("%s: Init hall driver success", __func__); + return HDF_SUCCESS; +} + +void HallReleaseDriver(struct HdfDeviceObject *device) +{ + struct HallDrvData *drvData = NULL; + CHECK_NULL_PTR_RETURN(device); + + drvData = (struct HallDrvData *)device->service; + CHECK_NULL_PTR_RETURN(drvData); + + if (drvData->detectFlag) { + HallReleaseCfgData(drvData->hallCfg); + } + + OsalMemFree(drvData->hallCfg); + drvData->hallCfg = NULL; + + HdfWorkDestroy(&drvData->hallWork); + HdfWorkQueueDestroy(&drvData->hallWorkQueue); + OsalMemFree(drvData); +} + +struct HdfDriverEntry g_sensorHallDevEntry = { + .moduleVersion = 1, + .moduleName = "HDF_SENSOR_HALL", + .Bind = HallBindDriver, + .Init = HallInitDriver, + .Release = HallReleaseDriver, +}; + HDF_INIT(g_sensorHallDevEntry); \ No newline at end of file diff --git a/model/sensor/driver/hall/sensor_hall_driver.h b/model/sensor/driver/hall/sensor_hall_driver.h index 6c0c0b7d9f49dae270ec5c81166106453ba857f2..3b706dcc3937c62c8c64f5a529b3a0f20d7d0a3c 100755 --- a/model/sensor/driver/hall/sensor_hall_driver.h +++ b/model/sensor/driver/hall/sensor_hall_driver.h @@ -1,50 +1,46 @@ -/* - * 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 SENSOR_HALL_DRIVER_H -#define SENSOR_HALL_DRIVER_H - -#include "hdf_workqueue.h" -#include "sensor_config_parser.h" -#include "sensor_platform_if.h" - -#define HALL_CHIP_NAME_AK8789 "ak8789" - -enum HallGpioIrq { - HALL_NORTH_POLARITY_GPIO = 0, - HALL_SOUTH_POLARITY_GPIO = 1, - HALL_POLARITY_GPIO_MAX = 2, -}; - -struct HallDetectIfList { - char *chipName; - int32_t (*DetectChip)(struct SensorCfgData *data); -}; - -struct HallOpsCall { - int32_t (*Init)(struct SensorCfgData *data); - int32_t (*ReadData)(struct SensorCfgData *data); -}; - -struct HallDrvData { - struct IDeviceIoService ioService; - struct HdfDeviceObject *device; - HdfWorkQueue hallWorkQueue; - HdfWork hallWork; - bool detectFlag; - bool enable; - bool initStatus; - int64_t interval; - struct SensorCfgData *hallCfg; - struct HallOpsCall ops; - int32_t GpioIrq[HALL_POLARITY_GPIO_MAX]; -}; - -int32_t RegisterHallChipOps(const struct HallOpsCall *ops); - -#endif /* SENSOR_HALL_DRIVER_H */ +/* + * 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 SENSOR_HALL_DRIVER_H +#define SENSOR_HALL_DRIVER_H + +#include "hdf_workqueue.h" +#include "sensor_config_parser.h" +#include "sensor_platform_if.h" + +#define HALL_CHIP_NAME_AK8789 "ak8789" + +enum HallGpioIrq { + HALL_NORTH_POLARITY_GPIO = 0, + HALL_SOUTH_POLARITY_GPIO = 1, + HALL_POLARITY_GPIO_MAX = 2, +}; + +struct HallOpsCall { + int32_t (*Init)(struct SensorCfgData *data); + int32_t (*ReadData)(struct SensorCfgData *data); +}; + +struct HallDrvData { + struct IDeviceIoService ioService; + struct HdfDeviceObject *device; + HdfWorkQueue hallWorkQueue; + HdfWork hallWork; + bool detectFlag; + bool enable; + int64_t interval; + struct SensorCfgData *hallCfg; + struct HallOpsCall ops; + int32_t GpioIrq[HALL_POLARITY_GPIO_MAX]; +}; + +int32_t HallRegisterChipOps(const struct HallOpsCall *ops); +struct SensorCfgData *HallCreateCfgData(const struct DeviceResourceNode *node); +void HallReleaseCfgData(struct SensorCfgData *sensorCfgData); + +#endif /* SENSOR_HALL_DRIVER_H */ \ No newline at end of file