1 /* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 *
15 * Author: liangkz @ https://ost.51cto.com/column/46
16 * Date : 2022.04.01
17 *
18 */
19 #include "device_resource_if.h"
20 #include "hdf_device_desc.h"
21 #include "hdf_log.h"
22 #include "gpio_if.h"
23
24 #define HDF_LOG_TAG led_drv
25 #define LED_RGB_WRITE 7
26 #define LED_R_BIT 0x01
27 #define LED_G_BIT 0x02
28 #define LED_B_BIT 0x04
29
30 #define LED_VERSION 2
31 #define LED_MODE_OFF 0
32 #define LED_MODE_ON 1
33 #define LED_MODE_FLIP (-1)
34
35 struct led_config {
36 uint32_t led_ver;
37 uint32_t led_R;
38 uint32_t led_G;
39 uint32_t led_B;
40 };
41 struct led_config g_ledcfg = {0};
42
LedGpioCtrl(uint16_t gpio,int32_t mode)43 static int32_t LedGpioCtrl(uint16_t gpio, int32_t mode)
44 {
45 uint16_t level = GPIO_VAL_HIGH;
46
47 if (HDF_SUCCESS != GpioSetDir(gpio, GPIO_DIR_OUT)) {
48 HDF_LOGE("LedGpioCtrl: GpioSetDir NG");
49 return HDF_FAILURE;
50 }
51
52 if (mode == LED_MODE_ON) {
53 level = GPIO_VAL_HIGH;
54 } else if (mode == LED_MODE_OFF) {
55 level = GPIO_VAL_LOW;
56 } else { /* default to LED_MODE_FLIP */
57 GpioRead(gpio, &level);
58 level = (level+1)&0x01;
59 }
60
61 if (HDF_SUCCESS != GpioWrite(gpio, level)) {
62 HDF_LOGE("LedGpioCtrl: GpioWrite NG");
63 return HDF_FAILURE;
64 }
65 return HDF_SUCCESS;
66 }
67
LedDriverDispatch(struct HdfDeviceIoClient * client,int32_t cmdId,struct HdfSBuf * dataBuf,struct HdfSBuf * replyBuf)68 int32_t LedDriverDispatch(struct HdfDeviceIoClient *client, int32_t cmdId, \
69 struct HdfSBuf *dataBuf, struct HdfSBuf *replyBuf)
70 {
71 int32_t result = HDF_FAILURE;
72 int32_t LedMode = LED_MODE_FLIP;
73
74 if (client == NULL || client->device == NULL) {
75 HDF_LOGE("Led driver device is NULL");
76 return HDF_ERR_INVALID_OBJECT;
77 }
78 if (g_ledcfg.led_ver != LED_VERSION) {
79 HDF_LOGE("Led driver g_ledcfg.led_ver NOT match");
80 return HDF_FAILURE;
81 }
82 switch (cmdId) {
83 case LED_RGB_WRITE:
84 result = HdfSbufReadInt32(dataBuf, &LedMode);
85 if (result) {
86 HDF_LOGI("LedDriverDispatch/RGB: LedMode[0x%X][%s%s%s]",
87 LedMode, (LedMode&LED_R_BIT)?"R":"-",
88 (LedMode&LED_G_BIT)?"G":"-", (LedMode&LED_B_BIT)?"B":"-");
89 LedGpioCtrl(g_ledcfg.led_R, (LedMode&LED_R_BIT)?1:0);
90 LedGpioCtrl(g_ledcfg.led_G, (LedMode&LED_G_BIT)?1:0);
91 LedGpioCtrl(g_ledcfg.led_B, (LedMode&LED_B_BIT)?1:0);
92 }
93 break;
94 default:
95 HDF_LOGE("LedDriverDispatch: receiving unknown cmdId, NG!!");
96 break;
97 }
98 return result;
99 }
100
HdfLedDriverBind(struct HdfDeviceObject * deviceObject)101 int32_t HdfLedDriverBind(struct HdfDeviceObject *deviceObject)
102 {
103 if (deviceObject == NULL) {
104 HDF_LOGE("HDF_INIT(g_ledDriverEntry): HdfLedDriverBind: NG!");
105 return HDF_ERR_INVALID_OBJECT;
106 }
107 static struct IDeviceIoService ledDriverServ = {
108 .Dispatch = LedDriverDispatch,
109 };
110 deviceObject->service = (struct IDeviceIoService *)(&ledDriverServ);
111 HDF_LOGI("HDF_INIT(g_ledDriverEntry): HdfLedDriverBind: OK! NodeName[%s]",
112 deviceObject->property->name);
113 return HDF_SUCCESS;
114 }
115
HdfLedDriverInit(struct HdfDeviceObject * deviceObject)116 int32_t HdfLedDriverInit(struct HdfDeviceObject *deviceObject)
117 {
118 if (deviceObject == NULL) {
119 HDF_LOGE("HDF_INIT(g_ledDriverEntry): HdfLedDriverInit: NG!");
120 return HDF_ERR_INVALID_OBJECT;
121 }
122 struct DeviceResourceIface *CfgOps = NULL;
123 CfgOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
124 if (CfgOps == NULL || CfgOps->GetUint32 == NULL) {
125 HDF_LOGE("%s: invalid CfgOps fail!", __func__);
126 return HDF_FAILURE;
127 }
128 if (CfgOps->GetUint32(deviceObject->property, "led_version", &g_ledcfg.led_ver, 0) != HDF_SUCCESS) {
129 HDF_LOGE("%s: read led_version fail!", __func__);
130 return HDF_FAILURE;
131 }
132 if (CfgOps->GetUint32(deviceObject->property, "led_R", &g_ledcfg.led_R, 0) != HDF_SUCCESS) {
133 g_ledcfg.led_ver = 0;
134 HDF_LOGE("%s: read led_R fail!", __func__);
135 return HDF_FAILURE;
136 }
137 if (CfgOps->GetUint32(deviceObject->property, "led_G", &g_ledcfg.led_G, 0) != HDF_SUCCESS) {
138 g_ledcfg.led_ver = 0;
139 HDF_LOGE("%s: read led_G fail!", __func__);
140 return HDF_FAILURE;
141 }
142 if (CfgOps->GetUint32(deviceObject->property, "led_B", &g_ledcfg.led_B, 0) != HDF_SUCCESS) {
143 g_ledcfg.led_ver = 0;
144 HDF_LOGE("%s: read led_B fail!", __func__);
145 return HDF_FAILURE;
146 }
147 HDF_LOGI("HDF_INIT(g_ledDriverEntry): HdfLedDriverInit: OK!");
148 return HDF_SUCCESS;
149 }
150
HdfLedDriverRelease(struct HdfDeviceObject * deviceObject)151 void HdfLedDriverRelease(struct HdfDeviceObject *deviceObject)
152 {
153 if (deviceObject == NULL) {
154 HDF_LOGE("HDF_INIT(g_ledDriverEntry): HdfLedDriverRelease: NG!");
155 return;
156 }
157 HDF_LOGI("HDF_INIT(g_ledDriverEntry): HdfLedDriverRelease: OK!");
158 return;
159 }
160
161 struct HdfDriverEntry g_ledDriverEntry = {
162 .moduleVersion = 1,
163 .moduleName = "led_driver",
164 .Bind = HdfLedDriverBind,
165 .Init = HdfLedDriverInit,
166 .Release = HdfLedDriverRelease,
167 };
168 HDF_INIT(g_ledDriverEntry);