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);