1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 *
4 * HDF is dual licensed: you can use it either under the terms of
5 * the GPL, or the BSD license, at your option.
6 * See the LICENSE file in the root of this repository for complete details.
7 */
8
9 #include "hall_ak8789.h"
10 #include <securec.h>
11 #include "osal_irq.h"
12 #include "osal_mem.h"
13 #include "osal_time.h"
14 #include "sensor_config_controller.h"
15 #include "sensor_device_manager.h"
16 #include "sensor_hall_driver.h"
17
18 #define HDF_LOG_TAG hall_ak8789_c
19
20 static struct Ak8789DrvData *g_ak8789DrvData = NULL;
21
Ak8789GetDrvData(void)22 struct Ak8789DrvData *Ak8789GetDrvData(void)
23 {
24 return g_ak8789DrvData;
25 }
26
27 /* IO config for int-pin and Gpio-pin */
28 #define SENSOR_HALL_DATA_REG_ADDR 0x114f0040
29 #define SENSOR_HALL_CLK_REG_ADDR 0x114f0044
30 #define SENSOR_HALL_REG_CFG 0x400
31
ReadAk8789Data(struct SensorCfgData * data)32 int32_t ReadAk8789Data(struct SensorCfgData *data)
33 {
34 int32_t ret;
35 uint8_t tmp = 1;
36 OsalTimespec time;
37 struct SensorReportEvent event;
38
39 CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM);
40
41 (void)memset_s(&event, sizeof(event), 0, sizeof(event));
42 (void)memset_s(&time, sizeof(time), 0, sizeof(time));
43 if (OsalGetTime(&time) != HDF_SUCCESS) {
44 HDF_LOGE("%s: Get time failed", __func__);
45 return HDF_FAILURE;
46 }
47
48 event.timestamp = time.sec * SENSOR_SECOND_CONVERT_NANOSECOND + time.usec *
49 SENSOR_CONVERT_UNIT; /* unit nanosecond */
50 event.sensorId = SENSOR_TAG_HALL;
51 event.version = 0;
52 event.option = 0;
53 event.mode = SENSOR_WORK_MODE_ON_CHANGE;
54 event.dataLen = sizeof(tmp);
55 event.data = (uint8_t *)&tmp;
56 ret = ReportSensorEvent(&event);
57 if (ret != HDF_SUCCESS) {
58 HDF_LOGE("%s: AK8789 report data failed", __func__);
59 }
60 return ret;
61 }
62
InitHallPreConfig(void)63 static int32_t InitHallPreConfig(void)
64 {
65 if (SetSensorPinMux(SENSOR_HALL_DATA_REG_ADDR, SENSOR_ADDR_WIDTH_4_BYTE, SENSOR_HALL_REG_CFG) != HDF_SUCCESS) {
66 HDF_LOGE("%s: Data write mux pin failed", __func__);
67 return HDF_FAILURE;
68 }
69 if (SetSensorPinMux(SENSOR_HALL_CLK_REG_ADDR, SENSOR_ADDR_WIDTH_4_BYTE, SENSOR_HALL_REG_CFG) != HDF_SUCCESS) {
70 HDF_LOGE("%s: Clk write mux pin failed", __func__);
71 return HDF_FAILURE;
72 }
73 return HDF_SUCCESS;
74 }
75
DispatchAK8789(struct HdfDeviceIoClient * client,int cmd,struct HdfSBuf * data,struct HdfSBuf * reply)76 static int32_t DispatchAK8789(struct HdfDeviceIoClient *client,
77 int cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
78 {
79 (void)client;
80 (void)cmd;
81 (void)data;
82 (void)reply;
83
84 return HDF_SUCCESS;
85 }
86
Ak8789BindDriver(struct HdfDeviceObject * device)87 int32_t Ak8789BindDriver(struct HdfDeviceObject *device)
88 {
89 CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM);
90
91 struct Ak8789DrvData *drvData = (struct Ak8789DrvData *)OsalMemCalloc(sizeof(*drvData));
92 if (drvData == NULL) {
93 HDF_LOGE("%s: Malloc Ak8789 drv data fail", __func__);
94 return HDF_ERR_MALLOC_FAIL;
95 }
96
97 drvData->ioService.Dispatch = DispatchAK8789;
98 drvData->device = device;
99 device->service = &drvData->ioService;
100 g_ak8789DrvData = drvData;
101
102 return HDF_SUCCESS;
103 }
104
AK8789InitDriver(struct HdfDeviceObject * device)105 int32_t AK8789InitDriver(struct HdfDeviceObject *device)
106 {
107 int32_t ret;
108 struct HallOpsCall ops;
109 CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM);
110 struct Ak8789DrvData *drvData = (struct Ak8789DrvData *)device->service;
111 CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM);
112
113 ret = InitHallPreConfig();
114 if (ret != HDF_SUCCESS) {
115 HDF_LOGE("%s: Init AK8789 bus mux config", __func__);
116 return HDF_FAILURE;
117 }
118
119 drvData->sensorCfg = HallCreateCfgData(device->property);
120 if (drvData->sensorCfg == NULL) {
121 return HDF_ERR_NOT_SUPPORT;
122 }
123
124 ops.Init = NULL;
125 ops.ReadData = ReadAk8789Data;
126 ret = HallRegisterChipOps(&ops);
127 if (ret != HDF_SUCCESS) {
128 HDF_LOGE("%s: Register AK8789 hall failed", __func__);
129 return HDF_FAILURE;
130 }
131
132 return HDF_SUCCESS;
133 }
134
Ak8789ReleaseDriver(struct HdfDeviceObject * device)135 void Ak8789ReleaseDriver(struct HdfDeviceObject *device)
136 {
137 CHECK_NULL_PTR_RETURN(device);
138
139 struct Ak8789DrvData *drvData = (struct Ak8789DrvData *)device->service;
140 CHECK_NULL_PTR_RETURN(drvData);
141
142 HallReleaseCfgData(drvData->sensorCfg);
143 drvData->sensorCfg = NULL;
144 OsalMemFree(drvData);
145 }
146
147 struct HdfDriverEntry g_hallAk8789DevEntry = {
148 .moduleVersion = 1,
149 .moduleName = "HDF_SENSOR_HALL_AK8789",
150 .Bind = Ak8789BindDriver,
151 .Init = AK8789InitDriver,
152 .Release = Ak8789ReleaseDriver,
153 };
154
155 HDF_INIT(g_hallAk8789DevEntry);