1 /*
2  * Copyright (C) 2018 Knowles Electronics
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "oslo_iaxxx_sensor_control"
18 
19 #include "oslo_iaxxx_sensor_control.h"
20 
21 #include <log/log.h>
22 
23 #include "cvq_ioctl.h"
24 #include <linux/mfd/adnc/iaxxx-module.h>
25 
26 #define IAXXX_DEV_NODE "/dev/iaxxx-module-celldrv"
27 
iaxxx_sensor_mgr_init(void)28 struct ia_sensor_mgr *iaxxx_sensor_mgr_init(void) {
29     struct ia_sensor_mgr *smd = NULL;
30 
31     smd = (struct ia_sensor_mgr *)malloc(sizeof(struct ia_sensor_mgr));
32     if (NULL == smd) {
33         ALOGE("%s: ERROR Failed to allocated memory for ia_sensor_mgr", __func__);
34         return NULL;
35     }
36 
37     if ((smd->dev_node = fopen(IAXXX_DEV_NODE, "rw")) == NULL) {
38         ALOGE("%s: ERROR file %s open for write error: %s\n", __func__, IAXXX_DEV_NODE,
39               strerror(errno));
40         free(smd);
41         return NULL;
42     }
43 
44     return smd;
45 }
46 
iaxxx_sensor_mgr_deinit(struct ia_sensor_mgr * smd)47 int iaxxx_sensor_mgr_deinit(struct ia_sensor_mgr *smd) {
48     if (smd == NULL) {
49         ALOGE("%s: ERROR: Invalid handle to ia_sensor_mgr", __func__);
50         return -1;
51     }
52 
53     if (smd->dev_node) {
54         fclose(smd->dev_node);
55     }
56 
57     free(smd);
58 
59     return 0;
60 }
61 
oslo_driver_set_param(struct ia_sensor_mgr * smd,int param_id,float param_val)62 void oslo_driver_set_param(struct ia_sensor_mgr *smd, int param_id, float param_val) {
63     int err = 0;
64     struct iaxxx_sensor_param sp;
65 
66     if (NULL == smd) {
67         ALOGE("%s: NULL handle passed", __func__);
68         return;
69     }
70 
71     sp.inst_id = 0;
72     sp.block_id = 0;
73 
74     sp.param_id = param_id;
75     sp.param_val = param_val;
76 
77     ALOGD("Set sensor param 0x%X with value %f", param_id, param_val);
78     fprintf(stdout, "Set sensor param 0x%X with value %f\n", param_id, param_val);
79 
80     err = ioctl(fileno(smd->dev_node), MODULE_SENSOR_SET_PARAM, (unsigned long)&sp);
81     if (-1 == err) {
82         ALOGE("%s: ERROR: MODULE_SENSOR_SET_PARAM IOCTL failed with error %d(%s)", __func__, errno,
83               strerror(errno));
84         return;
85     }
86 }
87 
oslo_driver_get_param(struct ia_sensor_mgr * smd,int param_id)88 uint32_t oslo_driver_get_param(struct ia_sensor_mgr *smd, int param_id) {
89     struct iaxxx_sensor_param sp;
90     int err = 0;
91     ALOGD("Get param - param_id 0x%X", param_id);
92 
93     if (NULL == smd) {
94         ALOGE("%s: NULL handle passed", __func__);
95         return 0;
96     }
97 
98     sp.inst_id = 0;
99     sp.block_id = 0;
100 
101     sp.param_id = param_id;
102     sp.param_val = 0;
103     err = ioctl(fileno(smd->dev_node), MODULE_SENSOR_GET_PARAM, (unsigned long)&sp);
104     if (-1 == err) {
105         ALOGE("%s: ERROR: MODULE_SENSOR_GET_PARAM IOCTL failed with error %d(%s)", __func__, errno,
106               strerror(errno));
107         return 0;
108     } else {
109         ALOGD("Value of param 0x%X is %u", sp.param_id, sp.param_val);
110         fprintf(stdout, "Value of param 0x%X is %u\n", sp.param_id, sp.param_val);
111     }
112 
113     return sp.param_val;
114 }
115 
oslo_driver_set_param_blk(struct ia_sensor_mgr * smd,uint32_t param_blk_id,const void * blk_data,uint32_t blk_size)116 size_t oslo_driver_set_param_blk(struct ia_sensor_mgr *smd, uint32_t param_blk_id,
117                                  const void *blk_data, uint32_t blk_size) {
118     size_t bytes_written = 0;
119     struct iaxxx_sensor_param_blk spb;
120     int err;
121 
122     if (NULL == smd) {
123         ALOGE("%s: NULL handle passed", __func__);
124         return 0;
125     }
126 
127     spb.inst_id = 0;
128     spb.block_id = 0;
129     spb.param_blk_id = param_blk_id;
130 
131     spb.blk_data = (uintptr_t)blk_data;
132     spb.blk_size = MIN(blk_size, SENSOR_MAX_PARAMBLK_SIZE);
133 
134     ALOGD("Set sensor param blk with size %d", blk_size);
135 
136     err = ioctl(fileno(smd->dev_node), MODULE_SENSOR_WRITE_PARAM_BLK, (unsigned long)&spb);
137     if (-1 == err) {
138         ALOGE("%s: ERROR: MODULE_SENSOR_WRITE_PARAM_BLK failed with error %d(%s)", __func__, errno,
139               strerror(errno));
140     } else {
141         bytes_written = spb.blk_size;
142     }
143 
144     return bytes_written;
145 }
146 
oslo_driver_get_stats(struct ia_sensor_mgr * smd,struct iaxxx_sensor_mode_stats stats[])147 int oslo_driver_get_stats(struct ia_sensor_mgr *smd, struct iaxxx_sensor_mode_stats stats[]) {
148     int rc = 0;
149 
150     if (NULL == smd || NULL == stats) {
151         ALOGE("%s: NULL argument passed", __func__);
152         return -EINVAL;
153     }
154 
155     rc = ioctl(fileno(smd->dev_node), IAXXX_SENSOR_MODE_STATS, (unsigned long)stats);
156     if (rc != 0) {
157         ALOGE("%s: ERROR: IAXXX_SENSOR_MODE_STATS failed with error %d(%s)", __func__, errno,
158               strerror(errno));
159     }
160 
161     return rc;
162 }
163 
oslo_plugin_set_param(int param_id,uint32_t param_val)164 void oslo_plugin_set_param(int param_id, uint32_t param_val) {
165     struct iaxxx_odsp_hw *ioh = NULL;
166     int err = 0;
167 
168     ioh = iaxxx_odsp_init();
169     if (ioh == NULL) {
170         ALOGE("ERROR: Failed to init odsp HAL");
171         return;
172     }
173 
174     err = iaxxx_odsp_plugin_set_parameter(ioh, SENSOR_INSTANCE_ID, param_id, param_val,
175                                           IAXXX_HMD_BLOCK_ID);
176     if (err != 0) {
177         ALOGE("Failed to set param_id %d with error %d", param_id, err);
178     } else {
179         ALOGD("Set param_id %d with value %" PRIu32, param_id, param_val);
180     }
181 
182     if (ioh) {
183         err = iaxxx_odsp_deinit(ioh);
184         if (err != 0) {
185             ALOGE("Failed to deinit the odsp HAL");
186         }
187     }
188 }
189 
oslo_plugin_get_param(int param_id)190 uint32_t oslo_plugin_get_param(int param_id) {
191     struct iaxxx_odsp_hw *ioh = NULL;
192     int err = 0;
193     uint32_t param_val;
194 
195     ioh = iaxxx_odsp_init();
196     if (ioh == NULL) {
197         ALOGE("ERROR: Failed to init odsp HAL");
198         return 0;
199     }
200 
201     err = iaxxx_odsp_plugin_get_parameter(ioh, SENSOR_INSTANCE_ID, param_id, IAXXX_HMD_BLOCK_ID,
202                                           &param_val);
203     if (err != 0) {
204         ALOGE("Failed to get param_id %u with error %d", param_id, err);
205     } else {
206         ALOGD("Value of param 0x%X is %u", param_id, param_val);
207         fprintf(stdout, "Value of param 0x%X is %u\n", param_id, param_val);
208     }
209 
210     if (ioh) {
211         err = iaxxx_odsp_deinit(ioh);
212         if (err != 0) {
213             ALOGE("Failed to deinit the odsp HAL");
214         }
215     }
216 
217     return param_val;
218 }
219