1 /*
2 * Copyright (c) 2022-2023 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 "vibrator_drv2605l_driver.h"
10 #include <securec.h>
11 #include "device_resource_if.h"
12 #include "hdf_base.h"
13 #include "hdf_log.h"
14 #include "i2c_if.h"
15 #include "hdf_workqueue.h"
16 #include "osal_mutex.h"
17 #include "osal_mem.h"
18 #include "vibrator_driver.h"
19 #include "vibrator_parser.h"
20 #include "vibrator_driver_type.h"
21
22 #define HDF_LOG_TAG khdf_vibrator_driver
23
24 struct Drv2605lDriverData *g_drv2605lDrvData = NULL;
25
GetDrv2605lDrvData(void)26 static struct Drv2605lDriverData *GetDrv2605lDrvData(void)
27 {
28 return g_drv2605lDrvData;
29 }
30
GetDrv2605lI2cHandle(struct VibratorI2cCfg * busCfg)31 static int32_t GetDrv2605lI2cHandle(struct VibratorI2cCfg *busCfg)
32 {
33 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(busCfg, HDF_ERR_INVALID_PARAM);
34
35 busCfg->handle = I2cOpen(busCfg->busNum);
36 if (busCfg->handle == NULL) {
37 HDF_LOGE("%s: drv2605l i2c Handle invalid", __func__);
38 return HDF_FAILURE;
39 }
40
41 return HDF_SUCCESS;
42 }
43
ReleaseDrv2605lBusHandle(struct VibratorI2cCfg * busCfg)44 static void ReleaseDrv2605lBusHandle(struct VibratorI2cCfg *busCfg)
45 {
46 if (busCfg == NULL) {
47 HDF_LOGE("%s: drv2605l i2c config invalid", __func__);
48 return;
49 }
50
51 if (busCfg->handle != NULL) {
52 I2cClose(busCfg->handle);
53 busCfg->handle = NULL;
54 }
55 }
56
ReadDrv2605l(struct VibratorI2cCfg * busCfg,uint16_t regAddr,uint8_t * data,uint16_t dataLen)57 static int32_t ReadDrv2605l(struct VibratorI2cCfg *busCfg, uint16_t regAddr, uint8_t *data, uint16_t dataLen)
58 {
59 int32_t index = 0;
60 unsigned char regBuf[I2C_REG_BUF_LEN] = {0};
61 struct I2cMsg msg[I2C_READ_MSG_NUM];
62
63 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(busCfg, HDF_FAILURE);
64 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(data, HDF_FAILURE);
65 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(busCfg->handle, HDF_FAILURE);
66
67 msg[I2C_READ_MSG_ADDR_IDX].addr = busCfg->devAddr;
68 msg[I2C_READ_MSG_ADDR_IDX].flags = 0;
69 msg[I2C_READ_MSG_ADDR_IDX].len = busCfg->regWidth;
70 msg[I2C_READ_MSG_ADDR_IDX].buf = regBuf;
71
72 if (busCfg->regWidth == DRV2605L_ADDR_WIDTH_1_BYTE) {
73 regBuf[index++] = regAddr & I2C_BYTE_MASK;
74 } else if (busCfg->regWidth == DRV2605L_ADDR_WIDTH_2_BYTE) {
75 regBuf[index++] = (regAddr >> I2C_BYTE_OFFSET) & I2C_BYTE_MASK;
76 regBuf[index++] = regAddr & I2C_BYTE_MASK;
77 } else {
78 HDF_LOGE("%s: i2c regWidth[%u] failed", __func__, busCfg->regWidth);
79 return HDF_FAILURE;
80 }
81
82 msg[I2C_READ_MSG_VALUE_IDX].addr = busCfg->devAddr;
83 msg[I2C_READ_MSG_VALUE_IDX].flags = I2C_FLAG_READ;
84 msg[I2C_READ_MSG_VALUE_IDX].len = dataLen;
85 msg[I2C_READ_MSG_VALUE_IDX].buf = data;
86
87 if (I2cTransfer(busCfg->handle, msg, I2C_READ_MSG_NUM) != I2C_READ_MSG_NUM) {
88 HDF_LOGE("%s: i2c[%u] read failed", __func__, busCfg->busNum);
89 return HDF_FAILURE;
90 }
91
92 return HDF_SUCCESS;
93 }
94
WriteDrv2605l(struct VibratorI2cCfg * busCfg,uint8_t * writeData,uint16_t dataLen)95 static int32_t WriteDrv2605l(struct VibratorI2cCfg *busCfg, uint8_t *writeData, uint16_t dataLen)
96 {
97 struct I2cMsg msg[I2C_WRITE_MSG_NUM];
98 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(busCfg, HDF_FAILURE);
99 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(writeData, HDF_FAILURE);
100 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(busCfg->handle, HDF_FAILURE);
101
102 msg[0].addr = busCfg->devAddr;
103 msg[0].flags = 0;
104 msg[0].len = dataLen;
105 msg[0].buf = writeData;
106
107 if (I2cTransfer(busCfg->handle, msg, I2C_WRITE_MSG_NUM) != I2C_WRITE_MSG_NUM) {
108 HDF_LOGE("%s: i2c[%u] write failed", __func__, busCfg->busNum);
109 return HDF_FAILURE;
110 }
111
112 return HDF_SUCCESS;
113 }
114
DetectDrv2605lDevice(struct Drv2605lDriverData * drvData)115 static int32_t DetectDrv2605lDevice(struct Drv2605lDriverData *drvData)
116 {
117 uint8_t value;
118 uint16_t chipIdReg;
119 uint16_t chipIdValue;
120 int32_t ret;
121
122 chipIdReg = drvData->drv2605lCfgData->vibratorAttr.chipIdReg;
123 chipIdValue = drvData->drv2605lCfgData->vibratorAttr.chipIdValue;
124
125 ret = GetDrv2605lI2cHandle(&drvData->drv2605lCfgData->vibratorBus.i2cCfg);
126 if (ret != HDF_SUCCESS) {
127 HDF_LOGE("%s: get drv2605l bus handle failed", __func__);
128 ReleaseDrv2605lBusHandle(&drvData->drv2605lCfgData->vibratorBus.i2cCfg);
129 return HDF_FAILURE;
130 }
131
132 ret = ReadDrv2605l(&drvData->drv2605lCfgData->vibratorBus.i2cCfg, chipIdReg, &value, sizeof(value));
133 if (ret != HDF_SUCCESS) {
134 HDF_LOGE("%s: i2c read chip id failed", __func__);
135 ReleaseDrv2605lBusHandle(&drvData->drv2605lCfgData->vibratorBus.i2cCfg);
136 return HDF_FAILURE;
137 }
138
139 if (value != chipIdValue) {
140 HDF_LOGE("%s: drv2605l chip detect failed", __func__);
141 ReleaseDrv2605lBusHandle(&drvData->drv2605lCfgData->vibratorBus.i2cCfg);
142 return HDF_FAILURE;
143 }
144
145 HDF_LOGD("%s: drv2605l detect chip success", __func__);
146 return HDF_SUCCESS;
147 }
148
InitDrv2605lChip(struct VibratorCfgData * drv2605lCfgData)149 static int32_t InitDrv2605lChip(struct VibratorCfgData *drv2605lCfgData)
150 {
151 uint8_t value[DRV2605L_VALUE_BUTT];
152
153 value[DRV2605L_ADDR_INDEX] = (uint8_t)DRV2605_REG_CONTROL3;
154 value[DRV2605L_VALUE_INDEX] = (uint8_t)DRV2605_MODE_OPEN_LOOP;
155 if (WriteDrv2605l(&drv2605lCfgData->vibratorBus.i2cCfg, value, sizeof(value)) != HDF_SUCCESS) {
156 HDF_LOGE("%s: i2c addr [%0X] write failed", __func__, value[DRV2605L_ADDR_INDEX]);
157 return HDF_FAILURE;
158 }
159
160 value[DRV2605L_ADDR_INDEX] = (uint8_t)DRV2605_REG_FEEDBACK;
161 value[DRV2605L_VALUE_INDEX] = (uint8_t)DRV2605_MODE_LRA;
162 if (WriteDrv2605l(&drv2605lCfgData->vibratorBus.i2cCfg, value, sizeof(value)) != HDF_SUCCESS) {
163 HDF_LOGE("%s: i2c addr [%0X] write failed", __func__, value[DRV2605L_ADDR_INDEX]);
164 return HDF_FAILURE;
165 }
166
167 value[DRV2605L_ADDR_INDEX] = (uint8_t)DRV2605_REG_RTPIN;
168 value[DRV2605L_VALUE_INDEX] = (uint8_t)&drv2605lCfgData->vibratorAttr.defaultIntensity;
169 if (WriteDrv2605l(&drv2605lCfgData->vibratorBus.i2cCfg, value, sizeof(value)) != HDF_SUCCESS) {
170 HDF_LOGE("%s: i2c addr [%0X] write failed", __func__, value[DRV2605L_ADDR_INDEX]);
171 return HDF_FAILURE;
172 }
173
174 value[DRV2605L_ADDR_INDEX] = (uint8_t)DRV2605_REG_LRARESON;
175 value[DRV2605L_VALUE_INDEX] = (uint8_t)&drv2605lCfgData->vibratorAttr.defaultFrequency;
176 if (WriteDrv2605l(&drv2605lCfgData->vibratorBus.i2cCfg, value, sizeof(value)) != HDF_SUCCESS) {
177 HDF_LOGE("%s: i2c addr [%0X] write failed", __func__, value[DRV2605L_ADDR_INDEX]);
178 return HDF_FAILURE;
179 }
180
181 return HDF_SUCCESS;
182 }
183
SetModulationParameter(uint16_t intensity,int16_t frequency)184 static int32_t SetModulationParameter(uint16_t intensity, int16_t frequency)
185 {
186 uint8_t value[DRV2605L_VALUE_BUTT];
187 struct Drv2605lDriverData *drvData = NULL;
188 drvData = GetDrv2605lDrvData();
189
190 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(drvData, HDF_FAILURE);
191
192 if (intensity != 0) {
193 value[DRV2605L_ADDR_INDEX] = (uint8_t)DRV2605_REG_RTPIN;
194 value[DRV2605L_VALUE_INDEX] = (uint8_t)INTENSITY_MAPPING_VALUE(intensity);
195 if (WriteDrv2605l(&drvData->drv2605lCfgData->vibratorBus.i2cCfg, value, sizeof(value)) != HDF_SUCCESS) {
196 HDF_LOGE("%s: i2c addr [%0X] write failed", __func__, value[DRV2605L_ADDR_INDEX]);
197 return HDF_FAILURE;
198 }
199 } else {
200 HDF_LOGD("%s: the setting of intensity 0 is not supported and \
201 will be set as the system default intensity", __func__);
202 }
203
204 if (frequency != 0) {
205 value[DRV2605L_ADDR_INDEX] = (uint8_t)DRV2605_REG_LRARESON;
206 value[DRV2605L_VALUE_INDEX] = (uint8_t)FREQUENCY_MAPPING_VALUE(frequency);
207 if (WriteDrv2605l(&drvData->drv2605lCfgData->vibratorBus.i2cCfg, value, sizeof(value)) != HDF_SUCCESS) {
208 HDF_LOGE("%s: i2c addr [%0X] write failed", __func__, value[DRV2605L_ADDR_INDEX]);
209 return HDF_FAILURE;
210 }
211 } else {
212 HDF_LOGD("%s: the setting of frequency 0 is not supported and \
213 will be set as the system default frequency", __func__);
214 }
215
216 return HDF_SUCCESS;
217 }
218
StartModulationParameter(void)219 static int32_t StartModulationParameter(void)
220 {
221 uint8_t value[DRV2605L_VALUE_BUTT];
222 struct Drv2605lDriverData *drvData = NULL;
223 drvData = GetDrv2605lDrvData();
224
225 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(drvData, HDF_FAILURE);
226
227 value[DRV2605L_ADDR_INDEX] = (uint8_t)DRV2605_REG_MODE;
228 value[DRV2605L_VALUE_INDEX] = (uint8_t)DRV2605_MODE_REALTIME;
229 if (WriteDrv2605l(&drvData->drv2605lCfgData->vibratorBus.i2cCfg, value, sizeof(value)) != HDF_SUCCESS) {
230 HDF_LOGE("%s: i2c addr [%0X] write failed", __func__, value[DRV2605L_ADDR_INDEX]);
231 return HDF_FAILURE;
232 }
233
234 return HDF_SUCCESS;
235 }
236
StopModulationParameter(void)237 static int32_t StopModulationParameter(void)
238 {
239 uint8_t value[DRV2605L_VALUE_BUTT];
240 struct Drv2605lDriverData *drvData = NULL;
241 drvData = GetDrv2605lDrvData();
242
243 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(drvData, HDF_FAILURE);
244 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(drvData->drv2605lCfgData, HDF_FAILURE);
245
246 value[DRV2605L_ADDR_INDEX] = (uint8_t)DRV2605_REG_MODE;
247 value[DRV2605L_VALUE_INDEX] = (uint8_t)DRV2605_MODE_STANDBY;
248 if (WriteDrv2605l(&drvData->drv2605lCfgData->vibratorBus.i2cCfg, value, sizeof(value)) != HDF_SUCCESS) {
249 HDF_LOGE("%s: i2c addr [%0X] write failed", __func__, value[DRV2605L_ADDR_INDEX]);
250 return HDF_FAILURE;
251 }
252
253 value[DRV2605L_ADDR_INDEX] = (uint8_t)DRV2605_REG_RTPIN;
254 value[DRV2605L_VALUE_INDEX] = (uint8_t)&drvData->drv2605lCfgData->vibratorAttr.defaultIntensity;
255 if (WriteDrv2605l(&drvData->drv2605lCfgData->vibratorBus.i2cCfg, value, sizeof(value)) != HDF_SUCCESS) {
256 HDF_LOGE("%s: i2c addr [%0X] write failed", __func__, value[DRV2605L_ADDR_INDEX]);
257 return HDF_FAILURE;
258 }
259
260 value[DRV2605L_ADDR_INDEX] = (uint8_t)DRV2605_REG_LRARESON;
261 value[DRV2605L_VALUE_INDEX] = (uint8_t)&drvData->drv2605lCfgData->vibratorAttr.defaultFrequency;
262 if (WriteDrv2605l(&drvData->drv2605lCfgData->vibratorBus.i2cCfg, value, sizeof(value)) != HDF_SUCCESS) {
263 HDF_LOGE("%s: i2c addr [%0X] write failed", __func__, value[DRV2605L_ADDR_INDEX]);
264 return HDF_FAILURE;
265 }
266
267 return HDF_SUCCESS;
268 }
269
DispatchDrv2605l(struct HdfDeviceIoClient * client,int32_t cmd,struct HdfSBuf * data,struct HdfSBuf * reply)270 static int32_t DispatchDrv2605l(struct HdfDeviceIoClient *client,
271 int32_t cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
272 {
273 (void)client;
274 (void)cmd;
275 (void)data;
276 (void)reply;
277 return HDF_SUCCESS;
278 }
279
BindDrv2605lDriver(struct HdfDeviceObject * device)280 static int32_t BindDrv2605lDriver(struct HdfDeviceObject *device)
281 {
282 struct Drv2605lDriverData *drvData = NULL;
283
284 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(device, HDF_FAILURE);
285
286 drvData = (struct Drv2605lDriverData *)OsalMemCalloc(sizeof(*drvData));
287 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_MALLOC_FAIL);
288
289 drvData->ioService.Dispatch = DispatchDrv2605l;
290 drvData->device = device;
291 device->service = &drvData->ioService;
292 g_drv2605lDrvData = drvData;
293 return HDF_SUCCESS;
294 }
295
InitDrv2605lDriver(struct HdfDeviceObject * device)296 static int32_t InitDrv2605lDriver(struct HdfDeviceObject *device)
297 {
298 static struct VibratorOps ops;
299 struct Drv2605lDriverData *drvData = NULL;
300
301 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(device, HDF_FAILURE);
302 drvData = (struct Drv2605lDriverData *)device->service;
303 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(drvData, HDF_FAILURE);
304
305 ops.SetParameter = SetModulationParameter;
306 ops.Start = StartModulationParameter;
307 ops.Stop = StopModulationParameter;
308 ops.StartEffect = NULL;
309
310 drvData->drv2605lCfgData = (struct VibratorCfgData *)OsalMemCalloc(sizeof(*drvData->drv2605lCfgData));
311 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(drvData->drv2605lCfgData, HDF_ERR_MALLOC_FAIL);
312
313 if (GetVibratorBaseConfigData(device->property, drvData->drv2605lCfgData) != HDF_SUCCESS) {
314 HDF_LOGE("%s: get vibrator base config fail", __func__);
315 return HDF_FAILURE;
316 }
317
318 if (DetectDrv2605lDevice(drvData) != HDF_SUCCESS) {
319 HDF_LOGE("%s: drv2605l detect chip fail", __func__);
320 return HDF_FAILURE;
321 }
322
323 if (InitDrv2605lChip(drvData->drv2605lCfgData) != HDF_SUCCESS) {
324 HDF_LOGE("%s: init 2605l chip fail", __func__);
325 return HDF_FAILURE;
326 }
327
328 if (RegisterVibratorInfo(&drvData->drv2605lCfgData->vibratorInfo) != HDF_SUCCESS) {
329 HDF_LOGE("%s: register vibrator info fail", __func__);
330 return HDF_FAILURE;
331 }
332
333 if (RegisterVibratorOps(&ops) != HDF_SUCCESS) {
334 HDF_LOGE("%s: register vibrator ops fail", __func__);
335 return HDF_FAILURE;
336 }
337
338 return HDF_SUCCESS;
339 }
340
ReleaseDrv2605lDriver(struct HdfDeviceObject * device)341 static void ReleaseDrv2605lDriver(struct HdfDeviceObject *device)
342 {
343 struct Drv2605lDriverData *drvData = NULL;
344
345 if (device == NULL) {
346 HDF_LOGE("%s: device is null", __func__);
347 return;
348 }
349
350 drvData = (struct Drv2605lDriverData *)device->service;
351 if (drvData == NULL) {
352 HDF_LOGE("%s: drvData is null", __func__);
353 return;
354 }
355 ReleaseDrv2605lBusHandle(&drvData->drv2605lCfgData->vibratorBus.i2cCfg);
356 OsalMemFree(drvData->drv2605lCfgData);
357 OsalMemFree(drvData);
358 g_drv2605lDrvData = NULL;
359 }
360
361 struct HdfDriverEntry g_drv2605lDriverEntry = {
362 .moduleVersion = 1,
363 .moduleName = "HDF_DRV2605L_VIBRATOR",
364 .Bind = BindDrv2605lDriver,
365 .Init = InitDrv2605lDriver,
366 .Release = ReleaseDrv2605lDriver,
367 };
368
369 HDF_INIT(g_drv2605lDriverEntry);