1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * Copyright 2020 Rockchip Electronics Co. LTD
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * Licensed under the Apache License, Version 2.0 (the "License");
5*4882a593Smuzhiyun * you may not use this file except in compliance with the License.
6*4882a593Smuzhiyun * You may obtain a copy of the License at
7*4882a593Smuzhiyun *
8*4882a593Smuzhiyun * http://www.apache.org/licenses/LICENSE-2.0
9*4882a593Smuzhiyun *
10*4882a593Smuzhiyun * Unless required by applicable law or agreed to in writing, software
11*4882a593Smuzhiyun * distributed under the License is distributed on an "AS IS" BASIS,
12*4882a593Smuzhiyun * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*4882a593Smuzhiyun * See the License for the specific language governing permissions and
14*4882a593Smuzhiyun * limitations under the License.
15*4882a593Smuzhiyun */
16*4882a593Smuzhiyun
17*4882a593Smuzhiyun #define MODULE_TAG "mpp_serivce"
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun #include <sys/ioctl.h>
20*4882a593Smuzhiyun #include <fcntl.h>
21*4882a593Smuzhiyun #include <errno.h>
22*4882a593Smuzhiyun #include <string.h>
23*4882a593Smuzhiyun
24*4882a593Smuzhiyun #include "mpp_env.h"
25*4882a593Smuzhiyun #include "mpp_mem.h"
26*4882a593Smuzhiyun #include "mpp_debug.h"
27*4882a593Smuzhiyun #include "mpp_common.h"
28*4882a593Smuzhiyun #include "osal_2str.h"
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun #include "mpp_device_debug.h"
31*4882a593Smuzhiyun #include "mpp_service_api.h"
32*4882a593Smuzhiyun #include "mpp_service_impl.h"
33*4882a593Smuzhiyun #include "mpp_server.h"
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun typedef struct MppServiceQueryCfg_t {
36*4882a593Smuzhiyun RK_U32 cmd_butt;
37*4882a593Smuzhiyun const char *name;
38*4882a593Smuzhiyun } MppServiceQueryCfg;
39*4882a593Smuzhiyun
40*4882a593Smuzhiyun static const MppServiceQueryCfg query_cfg[] = {
41*4882a593Smuzhiyun { MPP_CMD_QUERY_BASE, "query_cmd", },
42*4882a593Smuzhiyun { MPP_CMD_INIT_BASE, "init_cmd", },
43*4882a593Smuzhiyun { MPP_CMD_SEND_BASE, "send_cmd", },
44*4882a593Smuzhiyun { MPP_CMD_POLL_BASE, "poll_cmd", },
45*4882a593Smuzhiyun { MPP_CMD_CONTROL_BASE, "control_cmd", },
46*4882a593Smuzhiyun };
47*4882a593Smuzhiyun
48*4882a593Smuzhiyun static const RK_U32 query_count = MPP_ARRAY_ELEMS(query_cfg);
49*4882a593Smuzhiyun
mpp_get_mpp_service_name(void)50*4882a593Smuzhiyun const char *mpp_get_mpp_service_name(void)
51*4882a593Smuzhiyun {
52*4882a593Smuzhiyun static const char *mpp_service_name = NULL;
53*4882a593Smuzhiyun static const char *mpp_service_dev[] = {
54*4882a593Smuzhiyun "/dev/mpp_service",
55*4882a593Smuzhiyun "/dev/mpp-service",
56*4882a593Smuzhiyun };
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun if (mpp_service_name)
59*4882a593Smuzhiyun return mpp_service_name;
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun if (!access(mpp_service_dev[0], F_OK | R_OK | W_OK)) {
62*4882a593Smuzhiyun mpp_service_name = mpp_service_dev[0];
63*4882a593Smuzhiyun } else if (!access(mpp_service_dev[1], F_OK | R_OK | W_OK))
64*4882a593Smuzhiyun mpp_service_name = mpp_service_dev[1];
65*4882a593Smuzhiyun
66*4882a593Smuzhiyun return mpp_service_name;
67*4882a593Smuzhiyun }
68*4882a593Smuzhiyun
mpp_service_ioctl(RK_S32 fd,RK_U32 cmd,RK_U32 size,void * param)69*4882a593Smuzhiyun RK_S32 mpp_service_ioctl(RK_S32 fd, RK_U32 cmd, RK_U32 size, void *param)
70*4882a593Smuzhiyun {
71*4882a593Smuzhiyun MppReqV1 mpp_req;
72*4882a593Smuzhiyun
73*4882a593Smuzhiyun memset(&mpp_req, 0, sizeof(mpp_req));
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun mpp_req.cmd = cmd;
76*4882a593Smuzhiyun mpp_req.flag = 0;
77*4882a593Smuzhiyun mpp_req.size = size;
78*4882a593Smuzhiyun mpp_req.offset = 0;
79*4882a593Smuzhiyun mpp_req.data_ptr = REQ_DATA_PTR(param);
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun return (RK_S32)ioctl(fd, MPP_IOC_CFG_V1, &mpp_req);
82*4882a593Smuzhiyun }
83*4882a593Smuzhiyun
mpp_service_ioctl_request(RK_S32 fd,MppReqV1 * req)84*4882a593Smuzhiyun RK_S32 mpp_service_ioctl_request(RK_S32 fd, MppReqV1 *req)
85*4882a593Smuzhiyun {
86*4882a593Smuzhiyun return (RK_S32)ioctl(fd, MPP_IOC_CFG_V1, req);
87*4882a593Smuzhiyun }
88*4882a593Smuzhiyun
mpp_service_check_cmd_valid(RK_U32 cmd,const MppServiceCmdCap * cap)89*4882a593Smuzhiyun MPP_RET mpp_service_check_cmd_valid(RK_U32 cmd, const MppServiceCmdCap *cap)
90*4882a593Smuzhiyun {
91*4882a593Smuzhiyun RK_U32 found = 0;
92*4882a593Smuzhiyun
93*4882a593Smuzhiyun if (cap->support_cmd > 0) {
94*4882a593Smuzhiyun found = (cmd < cap->query_cmd) ? 1 : 0;
95*4882a593Smuzhiyun found = (cmd >= MPP_CMD_INIT_BASE && cmd < cap->init_cmd) ? 1 : found;
96*4882a593Smuzhiyun found = (cmd >= MPP_CMD_SEND_BASE && cmd < cap->send_cmd) ? 1 : found;
97*4882a593Smuzhiyun found = (cmd >= MPP_CMD_POLL_BASE && cmd < cap->poll_cmd) ? 1 : found;
98*4882a593Smuzhiyun found = (cmd >= MPP_CMD_CONTROL_BASE && cmd < cap->ctrl_cmd) ? 1 : found;
99*4882a593Smuzhiyun } else {
100*4882a593Smuzhiyun /* old kernel before support_cmd query is valid */
101*4882a593Smuzhiyun found = (cmd >= MPP_CMD_INIT_BASE && cmd <= MPP_CMD_INIT_TRANS_TABLE) ? 1 : found;
102*4882a593Smuzhiyun found = (cmd >= MPP_CMD_SEND_BASE && cmd <= MPP_CMD_SET_REG_ADDR_OFFSET) ? 1 : found;
103*4882a593Smuzhiyun found = (cmd >= MPP_CMD_POLL_BASE && cmd <= MPP_CMD_POLL_HW_FINISH) ? 1 : found;
104*4882a593Smuzhiyun found = (cmd >= MPP_CMD_CONTROL_BASE && cmd <= MPP_CMD_RELEASE_FD) ? 1 : found;
105*4882a593Smuzhiyun }
106*4882a593Smuzhiyun
107*4882a593Smuzhiyun return found ? MPP_OK : MPP_NOK;
108*4882a593Smuzhiyun }
109*4882a593Smuzhiyun
check_mpp_service_cap(RK_U32 * codec_type,RK_U32 * hw_ids,MppServiceCmdCap * cap)110*4882a593Smuzhiyun void check_mpp_service_cap(RK_U32 *codec_type, RK_U32 *hw_ids, MppServiceCmdCap *cap)
111*4882a593Smuzhiyun {
112*4882a593Smuzhiyun MppReqV1 mpp_req;
113*4882a593Smuzhiyun RK_S32 fd = -1;
114*4882a593Smuzhiyun RK_S32 ret = 0;
115*4882a593Smuzhiyun RK_U32 *cmd_butt = &cap->query_cmd;;
116*4882a593Smuzhiyun RK_U32 hw_support = 0;
117*4882a593Smuzhiyun RK_U32 val;
118*4882a593Smuzhiyun RK_U32 i;
119*4882a593Smuzhiyun
120*4882a593Smuzhiyun /* for device check on startup */
121*4882a593Smuzhiyun mpp_env_get_u32("mpp_device_debug", &mpp_device_debug, 0);
122*4882a593Smuzhiyun
123*4882a593Smuzhiyun *codec_type = 0;
124*4882a593Smuzhiyun memset(hw_ids, 0, sizeof(RK_U32) * 32);
125*4882a593Smuzhiyun
126*4882a593Smuzhiyun /* check hw_support flag for valid client type */
127*4882a593Smuzhiyun fd = open(mpp_get_mpp_service_name(), O_RDWR | O_CLOEXEC);
128*4882a593Smuzhiyun if (fd < 0) {
129*4882a593Smuzhiyun mpp_err("open mpp_service to check cmd capability failed\n");
130*4882a593Smuzhiyun memset(cap, 0, sizeof(*cap));
131*4882a593Smuzhiyun return ;
132*4882a593Smuzhiyun }
133*4882a593Smuzhiyun ret = mpp_service_ioctl(fd, MPP_CMD_PROBE_HW_SUPPORT, 0, &hw_support);
134*4882a593Smuzhiyun if (!ret) {
135*4882a593Smuzhiyun mpp_dev_dbg_probe("vcodec_support %08x\n", hw_support);
136*4882a593Smuzhiyun *codec_type = hw_support;
137*4882a593Smuzhiyun }
138*4882a593Smuzhiyun cap->support_cmd = !access("/proc/mpp_service/supports-cmd", F_OK) ||
139*4882a593Smuzhiyun !access("/proc/mpp_service/support_cmd", F_OK);
140*4882a593Smuzhiyun if (cap->support_cmd) {
141*4882a593Smuzhiyun for (i = 0; i < query_count; i++, cmd_butt++) {
142*4882a593Smuzhiyun const MppServiceQueryCfg *cfg = &query_cfg[i];
143*4882a593Smuzhiyun
144*4882a593Smuzhiyun memset(&mpp_req, 0, sizeof(mpp_req));
145*4882a593Smuzhiyun
146*4882a593Smuzhiyun val = cfg->cmd_butt;
147*4882a593Smuzhiyun mpp_req.cmd = MPP_CMD_QUERY_CMD_SUPPORT;
148*4882a593Smuzhiyun mpp_req.data_ptr = REQ_DATA_PTR(&val);
149*4882a593Smuzhiyun
150*4882a593Smuzhiyun ret = (RK_S32)ioctl(fd, MPP_IOC_CFG_V1, &mpp_req);
151*4882a593Smuzhiyun if (ret)
152*4882a593Smuzhiyun mpp_err_f("query %-11s support error %s.\n", cfg->name, strerror(errno));
153*4882a593Smuzhiyun else {
154*4882a593Smuzhiyun *cmd_butt = val;
155*4882a593Smuzhiyun mpp_dev_dbg_probe("query %-11s support %04x\n", cfg->name, val);
156*4882a593Smuzhiyun }
157*4882a593Smuzhiyun }
158*4882a593Smuzhiyun }
159*4882a593Smuzhiyun close(fd);
160*4882a593Smuzhiyun
161*4882a593Smuzhiyun /* check each valid client type for hw_id */
162*4882a593Smuzhiyun /* kernel need to set client type then get hw_id */
163*4882a593Smuzhiyun for (i = 0; i < 32; i++) {
164*4882a593Smuzhiyun if (hw_support & (1 << i)) {
165*4882a593Smuzhiyun val = i;
166*4882a593Smuzhiyun
167*4882a593Smuzhiyun fd = open(mpp_get_mpp_service_name(), O_RDWR | O_CLOEXEC);
168*4882a593Smuzhiyun if (fd < 0) {
169*4882a593Smuzhiyun mpp_err("open mpp_service to check cmd capability failed\n");
170*4882a593Smuzhiyun break;
171*4882a593Smuzhiyun }
172*4882a593Smuzhiyun /* set client type first */
173*4882a593Smuzhiyun ret = mpp_service_ioctl(fd, MPP_CMD_INIT_CLIENT_TYPE, sizeof(val), &val);
174*4882a593Smuzhiyun if (ret) {
175*4882a593Smuzhiyun mpp_err("check valid client type %d failed\n", i);
176*4882a593Smuzhiyun } else {
177*4882a593Smuzhiyun /* then get hw_id */
178*4882a593Smuzhiyun ret = mpp_service_ioctl(fd, MPP_CMD_QUERY_HW_ID, sizeof(val), &val);
179*4882a593Smuzhiyun if (!ret) {
180*4882a593Smuzhiyun mpp_dev_dbg_probe("client %-10s hw_id %08x\n",
181*4882a593Smuzhiyun strof_client_type((MppClientType)i), val);
182*4882a593Smuzhiyun hw_ids[i] = val;
183*4882a593Smuzhiyun } else
184*4882a593Smuzhiyun mpp_err("check valid client %-10s for hw_id failed\n",
185*4882a593Smuzhiyun strof_client_type((MppClientType)i));
186*4882a593Smuzhiyun }
187*4882a593Smuzhiyun close(fd);
188*4882a593Smuzhiyun }
189*4882a593Smuzhiyun }
190*4882a593Smuzhiyun }
191*4882a593Smuzhiyun
mpp_service_next_req(MppDevMppService * p)192*4882a593Smuzhiyun MppReqV1 *mpp_service_next_req(MppDevMppService *p)
193*4882a593Smuzhiyun {
194*4882a593Smuzhiyun MppReqV1 *mpp_req = NULL;
195*4882a593Smuzhiyun
196*4882a593Smuzhiyun if (p->req_cnt >= p->req_max) {
197*4882a593Smuzhiyun mpp_dev_dbg_msg("enlarge request count %d -> %d\n",
198*4882a593Smuzhiyun p->req_max, p->req_max * 2);
199*4882a593Smuzhiyun p->reqs = mpp_realloc(p->reqs, MppReqV1, p->req_max * 2);
200*4882a593Smuzhiyun if (NULL == p->reqs) {
201*4882a593Smuzhiyun mpp_err_f("failed to enlarge request buffer\n");
202*4882a593Smuzhiyun return NULL;
203*4882a593Smuzhiyun }
204*4882a593Smuzhiyun
205*4882a593Smuzhiyun p->req_max *= 2;
206*4882a593Smuzhiyun }
207*4882a593Smuzhiyun
208*4882a593Smuzhiyun mpp_req = &p->reqs[p->req_cnt++];
209*4882a593Smuzhiyun
210*4882a593Smuzhiyun return mpp_req;
211*4882a593Smuzhiyun }
212*4882a593Smuzhiyun
mpp_service_next_reg_offset(MppDevMppService * p)213*4882a593Smuzhiyun RegOffsetInfo *mpp_service_next_reg_offset(MppDevMppService *p)
214*4882a593Smuzhiyun {
215*4882a593Smuzhiyun RegOffsetInfo *info = NULL;
216*4882a593Smuzhiyun
217*4882a593Smuzhiyun if (p->reg_offset_count + p->reg_offset_pos >= p->reg_offset_max) {
218*4882a593Smuzhiyun RegOffsetInfo *orig = p->reg_offset_info;
219*4882a593Smuzhiyun
220*4882a593Smuzhiyun mpp_dev_dbg_msg("enlarge reg offset count %d -> %d\n",
221*4882a593Smuzhiyun p->reg_offset_max, p->reg_offset_max * 2);
222*4882a593Smuzhiyun p->reg_offset_info = mpp_realloc(p->reg_offset_info, RegOffsetInfo, p->reg_offset_max * 2);
223*4882a593Smuzhiyun if (NULL == p->reg_offset_info) {
224*4882a593Smuzhiyun mpp_err_f("failed to enlarge request buffer\n");
225*4882a593Smuzhiyun return NULL;
226*4882a593Smuzhiyun }
227*4882a593Smuzhiyun if (orig != p->reg_offset_info)
228*4882a593Smuzhiyun mpp_logw_f("enlarge reg offset buffer and get different pointer\n");
229*4882a593Smuzhiyun
230*4882a593Smuzhiyun p->reg_offset_max *= 2;
231*4882a593Smuzhiyun }
232*4882a593Smuzhiyun
233*4882a593Smuzhiyun info = &p->reg_offset_info[p->reg_offset_count + p->reg_offset_pos];
234*4882a593Smuzhiyun mpp_dev_dbg_msg("reg offset %d : %d\n", p->reg_offset_pos, p->reg_offset_count);
235*4882a593Smuzhiyun p->reg_offset_count++;
236*4882a593Smuzhiyun
237*4882a593Smuzhiyun return info;
238*4882a593Smuzhiyun }
239*4882a593Smuzhiyun
240*4882a593Smuzhiyun
mpp_service_next_rcb_info(MppDevMppService * p)241*4882a593Smuzhiyun RcbInfo *mpp_service_next_rcb_info(MppDevMppService *p)
242*4882a593Smuzhiyun {
243*4882a593Smuzhiyun RcbInfo *info = NULL;
244*4882a593Smuzhiyun
245*4882a593Smuzhiyun if (p->rcb_count + p->rcb_pos >= p->rcb_max) {
246*4882a593Smuzhiyun mpp_dev_dbg_msg("enlarge rcb info count %d -> %d\n",
247*4882a593Smuzhiyun p->rcb_max, p->rcb_max * 2);
248*4882a593Smuzhiyun p->rcb_info = mpp_realloc(p->rcb_info, RcbInfo, p->rcb_max * 2);
249*4882a593Smuzhiyun if (NULL == p->rcb_info) {
250*4882a593Smuzhiyun mpp_err_f("failed to enlarge request buffer\n");
251*4882a593Smuzhiyun return NULL;
252*4882a593Smuzhiyun }
253*4882a593Smuzhiyun
254*4882a593Smuzhiyun p->rcb_max *= 2;
255*4882a593Smuzhiyun }
256*4882a593Smuzhiyun
257*4882a593Smuzhiyun info = &p->rcb_info[p->rcb_count + p->rcb_pos];
258*4882a593Smuzhiyun mpp_dev_dbg_msg("rcb info %d : %d\n", p->rcb_pos, p->rcb_count);
259*4882a593Smuzhiyun p->rcb_count++;
260*4882a593Smuzhiyun
261*4882a593Smuzhiyun return info;
262*4882a593Smuzhiyun }
263*4882a593Smuzhiyun
mpp_service_init(void * ctx,MppClientType type)264*4882a593Smuzhiyun MPP_RET mpp_service_init(void *ctx, MppClientType type)
265*4882a593Smuzhiyun {
266*4882a593Smuzhiyun MppDevMppService *p = (MppDevMppService *)ctx;
267*4882a593Smuzhiyun MPP_RET ret = MPP_NOK;
268*4882a593Smuzhiyun
269*4882a593Smuzhiyun p->cap = mpp_get_mpp_service_cmd_cap();
270*4882a593Smuzhiyun p->client = open(mpp_get_mpp_service_name(), O_RDWR | O_CLOEXEC);
271*4882a593Smuzhiyun if (p->client < 0) {
272*4882a593Smuzhiyun mpp_err("open mpp_service failed\n");
273*4882a593Smuzhiyun return ret;
274*4882a593Smuzhiyun }
275*4882a593Smuzhiyun
276*4882a593Smuzhiyun /* set client type first */
277*4882a593Smuzhiyun ret = mpp_service_ioctl(p->client, MPP_CMD_INIT_CLIENT_TYPE, sizeof(type), &type);
278*4882a593Smuzhiyun if (ret)
279*4882a593Smuzhiyun mpp_err("set client type %d failed\n", type);
280*4882a593Smuzhiyun
281*4882a593Smuzhiyun mpp_assert(p->cap);
282*4882a593Smuzhiyun if (MPP_OK == mpp_service_check_cmd_valid(MPP_CMD_SEND_CODEC_INFO, p->cap))
283*4882a593Smuzhiyun p->support_set_info = 1;
284*4882a593Smuzhiyun if (MPP_OK == mpp_service_check_cmd_valid(MPP_CMD_SET_RCB_INFO, p->cap)) {
285*4882a593Smuzhiyun p->support_set_rcb_info = 1;
286*4882a593Smuzhiyun mpp_env_get_u32("disable_rcb_info", &p->support_set_rcb_info, 1);
287*4882a593Smuzhiyun }
288*4882a593Smuzhiyun if (MPP_OK == mpp_service_check_cmd_valid(MPP_CMD_POLL_HW_IRQ, p->cap))
289*4882a593Smuzhiyun p->support_hw_irq = 1;
290*4882a593Smuzhiyun
291*4882a593Smuzhiyun /* default server fd is the opened client fd */
292*4882a593Smuzhiyun p->client_type = type;
293*4882a593Smuzhiyun p->server = p->client;
294*4882a593Smuzhiyun p->batch_io = 0;
295*4882a593Smuzhiyun p->serv_ctx = NULL;
296*4882a593Smuzhiyun p->dev_cb = NULL;
297*4882a593Smuzhiyun
298*4882a593Smuzhiyun p->bat_cmd.flag = 0;
299*4882a593Smuzhiyun p->bat_cmd.client = p->client;
300*4882a593Smuzhiyun p->bat_cmd.ret = 0;
301*4882a593Smuzhiyun
302*4882a593Smuzhiyun p->req_max = MAX_REQ_NUM;
303*4882a593Smuzhiyun p->reqs = mpp_malloc(MppReqV1, p->req_max);
304*4882a593Smuzhiyun if (NULL == p->reqs) {
305*4882a593Smuzhiyun mpp_err("create request buffer failed\n");
306*4882a593Smuzhiyun ret = MPP_ERR_MALLOC;
307*4882a593Smuzhiyun }
308*4882a593Smuzhiyun
309*4882a593Smuzhiyun p->reg_offset_max = MAX_REG_OFFSET;
310*4882a593Smuzhiyun p->reg_offset_info = mpp_malloc(RegOffsetInfo, p->reg_offset_max);
311*4882a593Smuzhiyun if (NULL == p->reg_offset_info) {
312*4882a593Smuzhiyun mpp_err("create register offset buffer failed\n");
313*4882a593Smuzhiyun ret = MPP_ERR_MALLOC;
314*4882a593Smuzhiyun }
315*4882a593Smuzhiyun p->reg_offset_pos = 0;
316*4882a593Smuzhiyun p->reg_offset_count = 0;
317*4882a593Smuzhiyun
318*4882a593Smuzhiyun p->rcb_max = MAX_RCB_OFFSET;
319*4882a593Smuzhiyun p->rcb_info = mpp_malloc(RcbInfo, p->rcb_max);
320*4882a593Smuzhiyun if (NULL == p->rcb_info) {
321*4882a593Smuzhiyun mpp_err("create rcb info buffer failed\n");
322*4882a593Smuzhiyun ret = MPP_ERR_MALLOC;
323*4882a593Smuzhiyun }
324*4882a593Smuzhiyun p->rcb_pos = 0;
325*4882a593Smuzhiyun p->rcb_count = 0;
326*4882a593Smuzhiyun
327*4882a593Smuzhiyun return ret;
328*4882a593Smuzhiyun }
329*4882a593Smuzhiyun
mpp_service_deinit(void * ctx)330*4882a593Smuzhiyun MPP_RET mpp_service_deinit(void *ctx)
331*4882a593Smuzhiyun {
332*4882a593Smuzhiyun MppDevMppService *p = (MppDevMppService *)ctx;
333*4882a593Smuzhiyun
334*4882a593Smuzhiyun if (p->batch_io)
335*4882a593Smuzhiyun mpp_server_detach(p);
336*4882a593Smuzhiyun
337*4882a593Smuzhiyun if (p->client)
338*4882a593Smuzhiyun close(p->client);
339*4882a593Smuzhiyun
340*4882a593Smuzhiyun MPP_FREE(p->reqs);
341*4882a593Smuzhiyun MPP_FREE(p->reg_offset_info);
342*4882a593Smuzhiyun MPP_FREE(p->rcb_info);
343*4882a593Smuzhiyun
344*4882a593Smuzhiyun return MPP_OK;
345*4882a593Smuzhiyun }
346*4882a593Smuzhiyun
mpp_service_attach(void * ctx)347*4882a593Smuzhiyun MPP_RET mpp_service_attach(void *ctx)
348*4882a593Smuzhiyun {
349*4882a593Smuzhiyun MppDevMppService *p = (MppDevMppService *)ctx;
350*4882a593Smuzhiyun
351*4882a593Smuzhiyun if (p->req_cnt) {
352*4882a593Smuzhiyun mpp_err_f("can not switch on bat mode when service working\n");
353*4882a593Smuzhiyun return MPP_NOK;
354*4882a593Smuzhiyun }
355*4882a593Smuzhiyun
356*4882a593Smuzhiyun if (!p->batch_io)
357*4882a593Smuzhiyun mpp_server_attach(p);
358*4882a593Smuzhiyun
359*4882a593Smuzhiyun return MPP_OK;
360*4882a593Smuzhiyun }
361*4882a593Smuzhiyun
mpp_service_detach(void * ctx)362*4882a593Smuzhiyun MPP_RET mpp_service_detach(void *ctx)
363*4882a593Smuzhiyun {
364*4882a593Smuzhiyun MppDevMppService *p = (MppDevMppService *)ctx;
365*4882a593Smuzhiyun
366*4882a593Smuzhiyun if (p->req_cnt) {
367*4882a593Smuzhiyun mpp_err_f("can not switch off bat mode when service working\n");
368*4882a593Smuzhiyun return MPP_NOK;
369*4882a593Smuzhiyun }
370*4882a593Smuzhiyun
371*4882a593Smuzhiyun if (p->batch_io)
372*4882a593Smuzhiyun mpp_server_detach(p);
373*4882a593Smuzhiyun
374*4882a593Smuzhiyun return MPP_OK;
375*4882a593Smuzhiyun }
376*4882a593Smuzhiyun
mpp_service_delimit(void * ctx)377*4882a593Smuzhiyun MPP_RET mpp_service_delimit(void *ctx)
378*4882a593Smuzhiyun {
379*4882a593Smuzhiyun MppDevMppService *p = (MppDevMppService *)ctx;
380*4882a593Smuzhiyun MppReqV1 *mpp_req = NULL;
381*4882a593Smuzhiyun
382*4882a593Smuzhiyun /* set fd trans info if needed */
383*4882a593Smuzhiyun if (p->reg_offset_count) {
384*4882a593Smuzhiyun mpp_req = mpp_service_next_req(p);
385*4882a593Smuzhiyun
386*4882a593Smuzhiyun mpp_req->cmd = MPP_CMD_SET_REG_ADDR_OFFSET;
387*4882a593Smuzhiyun mpp_req->flag = MPP_FLAGS_REG_OFFSET_ALONE;
388*4882a593Smuzhiyun mpp_req->size = (p->reg_offset_count) * sizeof(RegOffsetInfo);
389*4882a593Smuzhiyun mpp_req->offset = 0;
390*4882a593Smuzhiyun mpp_req->data_ptr = REQ_DATA_PTR(&p->reg_offset_info[p->reg_offset_pos]);
391*4882a593Smuzhiyun p->reg_offset_pos += p->reg_offset_count;
392*4882a593Smuzhiyun p->reg_offset_count = 0;
393*4882a593Smuzhiyun }
394*4882a593Smuzhiyun
395*4882a593Smuzhiyun /* set rcb offst info if needed */
396*4882a593Smuzhiyun if (p->rcb_count) {
397*4882a593Smuzhiyun mpp_req = mpp_service_next_req(p);
398*4882a593Smuzhiyun
399*4882a593Smuzhiyun mpp_req->cmd = MPP_CMD_SET_RCB_INFO;
400*4882a593Smuzhiyun mpp_req->flag = 0;
401*4882a593Smuzhiyun mpp_req->size = p->rcb_count * sizeof(RcbInfo);
402*4882a593Smuzhiyun mpp_req->offset = 0;
403*4882a593Smuzhiyun mpp_req->data_ptr = REQ_DATA_PTR(&p->rcb_info[p->rcb_pos]);
404*4882a593Smuzhiyun p->rcb_pos += p->rcb_count;
405*4882a593Smuzhiyun p->rcb_count = 0;
406*4882a593Smuzhiyun }
407*4882a593Smuzhiyun
408*4882a593Smuzhiyun mpp_req = mpp_service_next_req(p);
409*4882a593Smuzhiyun mpp_req->cmd = MPP_CMD_SET_SESSION_FD;
410*4882a593Smuzhiyun mpp_req->flag = MPP_FLAGS_MULTI_MSG;
411*4882a593Smuzhiyun mpp_req->offset = 0;
412*4882a593Smuzhiyun mpp_req->size = sizeof(p->bat_cmd);
413*4882a593Smuzhiyun mpp_req->data_ptr = REQ_DATA_PTR(&p->bat_cmd);
414*4882a593Smuzhiyun
415*4882a593Smuzhiyun return MPP_OK;
416*4882a593Smuzhiyun }
417*4882a593Smuzhiyun
mpp_service_set_cb_ctx(void * ctx,MppCbCtx * cb_ctx)418*4882a593Smuzhiyun MPP_RET mpp_service_set_cb_ctx(void *ctx, MppCbCtx *cb_ctx)
419*4882a593Smuzhiyun {
420*4882a593Smuzhiyun MppDevMppService *p = (MppDevMppService *)ctx;
421*4882a593Smuzhiyun
422*4882a593Smuzhiyun p->dev_cb = cb_ctx;
423*4882a593Smuzhiyun
424*4882a593Smuzhiyun return MPP_OK;
425*4882a593Smuzhiyun }
426*4882a593Smuzhiyun
mpp_service_reg_wr(void * ctx,MppDevRegWrCfg * cfg)427*4882a593Smuzhiyun MPP_RET mpp_service_reg_wr(void *ctx, MppDevRegWrCfg *cfg)
428*4882a593Smuzhiyun {
429*4882a593Smuzhiyun MppDevMppService *p = (MppDevMppService *)ctx;
430*4882a593Smuzhiyun MppReqV1 *mpp_req = mpp_service_next_req(p);
431*4882a593Smuzhiyun
432*4882a593Smuzhiyun mpp_req->cmd = MPP_CMD_SET_REG_WRITE;
433*4882a593Smuzhiyun mpp_req->flag = 0;
434*4882a593Smuzhiyun mpp_req->size = cfg->size;
435*4882a593Smuzhiyun mpp_req->offset = cfg->offset;
436*4882a593Smuzhiyun mpp_req->data_ptr = REQ_DATA_PTR(cfg->reg);
437*4882a593Smuzhiyun
438*4882a593Smuzhiyun return MPP_OK;
439*4882a593Smuzhiyun }
440*4882a593Smuzhiyun
mpp_service_reg_rd(void * ctx,MppDevRegRdCfg * cfg)441*4882a593Smuzhiyun MPP_RET mpp_service_reg_rd(void *ctx, MppDevRegRdCfg *cfg)
442*4882a593Smuzhiyun {
443*4882a593Smuzhiyun MppDevMppService *p = (MppDevMppService *)ctx;
444*4882a593Smuzhiyun MppReqV1 *mpp_req = mpp_service_next_req(p);
445*4882a593Smuzhiyun
446*4882a593Smuzhiyun mpp_req->cmd = MPP_CMD_SET_REG_READ;
447*4882a593Smuzhiyun mpp_req->flag = 0;
448*4882a593Smuzhiyun mpp_req->size = cfg->size;
449*4882a593Smuzhiyun mpp_req->offset = cfg->offset;
450*4882a593Smuzhiyun mpp_req->data_ptr = REQ_DATA_PTR(cfg->reg);
451*4882a593Smuzhiyun
452*4882a593Smuzhiyun return MPP_OK;
453*4882a593Smuzhiyun }
454*4882a593Smuzhiyun
mpp_service_reg_offset(void * ctx,MppDevRegOffsetCfg * cfg)455*4882a593Smuzhiyun MPP_RET mpp_service_reg_offset(void *ctx, MppDevRegOffsetCfg *cfg)
456*4882a593Smuzhiyun {
457*4882a593Smuzhiyun MppDevMppService *p = (MppDevMppService *)ctx;
458*4882a593Smuzhiyun RegOffsetInfo *info;
459*4882a593Smuzhiyun RK_S32 i;
460*4882a593Smuzhiyun
461*4882a593Smuzhiyun if (!cfg->offset)
462*4882a593Smuzhiyun return MPP_OK;
463*4882a593Smuzhiyun
464*4882a593Smuzhiyun if (p->reg_offset_count >= MAX_REG_OFFSET) {
465*4882a593Smuzhiyun mpp_err_f("reach max offset definition\n", MAX_REG_OFFSET);
466*4882a593Smuzhiyun return MPP_NOK;
467*4882a593Smuzhiyun }
468*4882a593Smuzhiyun
469*4882a593Smuzhiyun for (i = 0; i < p->reg_offset_count; i++) {
470*4882a593Smuzhiyun info = &p->reg_offset_info[p->reg_offset_pos + i];
471*4882a593Smuzhiyun
472*4882a593Smuzhiyun if (info->reg_idx == cfg->reg_idx) {
473*4882a593Smuzhiyun mpp_err_f("reg[%d] offset has been set, cover old %d -> %d\n",
474*4882a593Smuzhiyun info->reg_idx, info->offset, cfg->offset);
475*4882a593Smuzhiyun info->offset = cfg->offset;
476*4882a593Smuzhiyun return MPP_OK;
477*4882a593Smuzhiyun }
478*4882a593Smuzhiyun }
479*4882a593Smuzhiyun
480*4882a593Smuzhiyun info = mpp_service_next_reg_offset(p);
481*4882a593Smuzhiyun info->reg_idx = cfg->reg_idx;
482*4882a593Smuzhiyun info->offset = cfg->offset;
483*4882a593Smuzhiyun
484*4882a593Smuzhiyun return MPP_OK;
485*4882a593Smuzhiyun }
486*4882a593Smuzhiyun
mpp_service_reg_offsets(void * ctx,MppDevRegOffCfgs * cfgs)487*4882a593Smuzhiyun MPP_RET mpp_service_reg_offsets(void *ctx, MppDevRegOffCfgs *cfgs)
488*4882a593Smuzhiyun {
489*4882a593Smuzhiyun MppDevMppService *p = (MppDevMppService *)ctx;
490*4882a593Smuzhiyun RegOffsetInfo *info;
491*4882a593Smuzhiyun RK_S32 i;
492*4882a593Smuzhiyun
493*4882a593Smuzhiyun if (cfgs->count <= 0)
494*4882a593Smuzhiyun return MPP_OK;
495*4882a593Smuzhiyun
496*4882a593Smuzhiyun if (p->reg_offset_count >= MAX_REG_OFFSET ||
497*4882a593Smuzhiyun p->reg_offset_count + cfgs->count >= MAX_REG_OFFSET) {
498*4882a593Smuzhiyun mpp_err_f("reach max offset definition\n", MAX_REG_OFFSET);
499*4882a593Smuzhiyun return MPP_NOK;
500*4882a593Smuzhiyun }
501*4882a593Smuzhiyun
502*4882a593Smuzhiyun for (i = 0; i < cfgs->count; i++) {
503*4882a593Smuzhiyun MppDevRegOffsetCfg *cfg = &cfgs->cfgs[i];
504*4882a593Smuzhiyun RK_S32 j;
505*4882a593Smuzhiyun
506*4882a593Smuzhiyun for (j = 0; j < p->reg_offset_count; j++) {
507*4882a593Smuzhiyun info = &p->reg_offset_info[p->reg_offset_pos + j];
508*4882a593Smuzhiyun
509*4882a593Smuzhiyun if (info->reg_idx == cfg->reg_idx) {
510*4882a593Smuzhiyun mpp_err_f("reg[%d] offset has been set, cover old %d -> %d\n",
511*4882a593Smuzhiyun info->reg_idx, info->offset, cfg->offset);
512*4882a593Smuzhiyun info->offset = cfg->offset;
513*4882a593Smuzhiyun continue;
514*4882a593Smuzhiyun }
515*4882a593Smuzhiyun }
516*4882a593Smuzhiyun
517*4882a593Smuzhiyun info = mpp_service_next_reg_offset(p);;
518*4882a593Smuzhiyun info->reg_idx = cfg->reg_idx;
519*4882a593Smuzhiyun info->offset = cfg->offset;
520*4882a593Smuzhiyun }
521*4882a593Smuzhiyun
522*4882a593Smuzhiyun return MPP_OK;
523*4882a593Smuzhiyun }
524*4882a593Smuzhiyun
mpp_service_rcb_info(void * ctx,MppDevRcbInfoCfg * cfg)525*4882a593Smuzhiyun MPP_RET mpp_service_rcb_info(void *ctx, MppDevRcbInfoCfg *cfg)
526*4882a593Smuzhiyun {
527*4882a593Smuzhiyun MppDevMppService *p = (MppDevMppService *)ctx;
528*4882a593Smuzhiyun
529*4882a593Smuzhiyun if (!p->support_set_rcb_info)
530*4882a593Smuzhiyun return MPP_OK;
531*4882a593Smuzhiyun
532*4882a593Smuzhiyun if (p->rcb_count >= MAX_RCB_OFFSET) {
533*4882a593Smuzhiyun mpp_err_f("reach max offset definition\n", MAX_RCB_OFFSET);
534*4882a593Smuzhiyun return MPP_NOK;
535*4882a593Smuzhiyun }
536*4882a593Smuzhiyun
537*4882a593Smuzhiyun RcbInfo *info = mpp_service_next_rcb_info(p);
538*4882a593Smuzhiyun
539*4882a593Smuzhiyun info->reg_idx = cfg->reg_idx;
540*4882a593Smuzhiyun info->size = cfg->size;
541*4882a593Smuzhiyun
542*4882a593Smuzhiyun return MPP_OK;
543*4882a593Smuzhiyun }
544*4882a593Smuzhiyun
mpp_service_set_info(void * ctx,MppDevInfoCfg * cfg)545*4882a593Smuzhiyun MPP_RET mpp_service_set_info(void *ctx, MppDevInfoCfg *cfg)
546*4882a593Smuzhiyun {
547*4882a593Smuzhiyun MppDevMppService *p = (MppDevMppService *)ctx;
548*4882a593Smuzhiyun
549*4882a593Smuzhiyun if (!p->support_set_info)
550*4882a593Smuzhiyun return MPP_OK;
551*4882a593Smuzhiyun
552*4882a593Smuzhiyun if (!p->info_count)
553*4882a593Smuzhiyun memset(p->info, 0, sizeof(p->info));
554*4882a593Smuzhiyun
555*4882a593Smuzhiyun memcpy(&p->info[p->info_count], cfg, sizeof(MppDevInfoCfg));
556*4882a593Smuzhiyun p->info_count++;
557*4882a593Smuzhiyun
558*4882a593Smuzhiyun return MPP_OK;
559*4882a593Smuzhiyun }
560*4882a593Smuzhiyun
mpp_service_set_err_ref_hack(void * ctx,RK_U32 * enable)561*4882a593Smuzhiyun MPP_RET mpp_service_set_err_ref_hack(void *ctx, RK_U32 *enable)
562*4882a593Smuzhiyun {
563*4882a593Smuzhiyun MppDevMppService *p = (MppDevMppService *)ctx;
564*4882a593Smuzhiyun MppReqV1 mpp_req;
565*4882a593Smuzhiyun
566*4882a593Smuzhiyun mpp_req.cmd = MPP_CMD_SET_ERR_REF_HACK;
567*4882a593Smuzhiyun mpp_req.flag = MPP_FLAGS_LAST_MSG;
568*4882a593Smuzhiyun mpp_req.size = sizeof(RK_U32);
569*4882a593Smuzhiyun mpp_req.offset = 0;
570*4882a593Smuzhiyun mpp_req.data_ptr = REQ_DATA_PTR(enable);
571*4882a593Smuzhiyun
572*4882a593Smuzhiyun return mpp_service_ioctl_request(p->client, &mpp_req);
573*4882a593Smuzhiyun }
574*4882a593Smuzhiyun
mpp_service_cmd_send(void * ctx)575*4882a593Smuzhiyun MPP_RET mpp_service_cmd_send(void *ctx)
576*4882a593Smuzhiyun {
577*4882a593Smuzhiyun MPP_RET ret = MPP_OK;
578*4882a593Smuzhiyun MppDevMppService *p = (MppDevMppService *)ctx;
579*4882a593Smuzhiyun
580*4882a593Smuzhiyun if (p->req_cnt <= 0 || p->req_cnt > p->req_max) {
581*4882a593Smuzhiyun mpp_err_f("ctx %p invalid request count %d\n", ctx, p->req_cnt);
582*4882a593Smuzhiyun return MPP_ERR_VALUE;
583*4882a593Smuzhiyun }
584*4882a593Smuzhiyun
585*4882a593Smuzhiyun if (p->info_count) {
586*4882a593Smuzhiyun if (p->support_set_info) {
587*4882a593Smuzhiyun MppReqV1 mpp_req;
588*4882a593Smuzhiyun
589*4882a593Smuzhiyun mpp_req.cmd = MPP_CMD_SEND_CODEC_INFO;
590*4882a593Smuzhiyun mpp_req.flag = MPP_FLAGS_LAST_MSG;
591*4882a593Smuzhiyun mpp_req.size = p->info_count * sizeof(p->info[0]);
592*4882a593Smuzhiyun mpp_req.offset = 0;
593*4882a593Smuzhiyun mpp_req.data_ptr = REQ_DATA_PTR(p->info);
594*4882a593Smuzhiyun
595*4882a593Smuzhiyun ret = mpp_service_ioctl_request(p->client, &mpp_req);
596*4882a593Smuzhiyun if (ret)
597*4882a593Smuzhiyun p->support_set_info = 0;
598*4882a593Smuzhiyun }
599*4882a593Smuzhiyun p->info_count = 0;
600*4882a593Smuzhiyun }
601*4882a593Smuzhiyun
602*4882a593Smuzhiyun /* set fd trans info if needed */
603*4882a593Smuzhiyun if (p->reg_offset_count) {
604*4882a593Smuzhiyun MppReqV1 *mpp_req = mpp_service_next_req(p);
605*4882a593Smuzhiyun
606*4882a593Smuzhiyun mpp_req->cmd = MPP_CMD_SET_REG_ADDR_OFFSET;
607*4882a593Smuzhiyun mpp_req->flag = MPP_FLAGS_REG_OFFSET_ALONE;
608*4882a593Smuzhiyun mpp_req->size = (p->reg_offset_count) * sizeof(RegOffsetInfo);
609*4882a593Smuzhiyun mpp_req->offset = 0;
610*4882a593Smuzhiyun mpp_req->data_ptr = REQ_DATA_PTR(&p->reg_offset_info[p->reg_offset_pos]);
611*4882a593Smuzhiyun p->reg_offset_pos += p->reg_offset_count;
612*4882a593Smuzhiyun }
613*4882a593Smuzhiyun
614*4882a593Smuzhiyun /* set rcb offst info if needed */
615*4882a593Smuzhiyun if (p->rcb_count) {
616*4882a593Smuzhiyun MppReqV1 *mpp_req = mpp_service_next_req(p);
617*4882a593Smuzhiyun
618*4882a593Smuzhiyun mpp_req->cmd = MPP_CMD_SET_RCB_INFO;
619*4882a593Smuzhiyun mpp_req->flag = 0;
620*4882a593Smuzhiyun mpp_req->size = p->rcb_count * sizeof(RcbInfo);
621*4882a593Smuzhiyun mpp_req->offset = 0;
622*4882a593Smuzhiyun mpp_req->data_ptr = REQ_DATA_PTR(&p->rcb_info[p->rcb_pos]);
623*4882a593Smuzhiyun p->rcb_pos += p->rcb_count;
624*4882a593Smuzhiyun }
625*4882a593Smuzhiyun
626*4882a593Smuzhiyun /* setup flag for multi message request */
627*4882a593Smuzhiyun if (p->req_cnt > 1) {
628*4882a593Smuzhiyun RK_S32 i;
629*4882a593Smuzhiyun
630*4882a593Smuzhiyun for (i = 0; i < p->req_cnt; i++)
631*4882a593Smuzhiyun p->reqs[i].flag |= MPP_FLAGS_MULTI_MSG;
632*4882a593Smuzhiyun }
633*4882a593Smuzhiyun p->reqs[p->req_cnt - 1].flag |= MPP_FLAGS_LAST_MSG | MPP_FLAGS_REG_OFFSET_ALONE;
634*4882a593Smuzhiyun
635*4882a593Smuzhiyun if (p->batch_io) {
636*4882a593Smuzhiyun ret = mpp_server_send_task(ctx);
637*4882a593Smuzhiyun if (ret)
638*4882a593Smuzhiyun mpp_err_f("send task to server ret %d\n", ret);
639*4882a593Smuzhiyun } else {
640*4882a593Smuzhiyun ret = mpp_service_ioctl_request(p->server, &p->reqs[0]);
641*4882a593Smuzhiyun if (ret) {
642*4882a593Smuzhiyun mpp_err_f("ioctl MPP_IOC_CFG_V1 failed ret %d errno %d %s\n",
643*4882a593Smuzhiyun ret, errno, strerror(errno));
644*4882a593Smuzhiyun ret = errno;
645*4882a593Smuzhiyun }
646*4882a593Smuzhiyun }
647*4882a593Smuzhiyun
648*4882a593Smuzhiyun p->req_cnt = 0;
649*4882a593Smuzhiyun p->reg_offset_count = 0;
650*4882a593Smuzhiyun p->reg_offset_pos = 0;
651*4882a593Smuzhiyun p->rcb_count = 0;
652*4882a593Smuzhiyun p->rcb_pos = 0;
653*4882a593Smuzhiyun p->rcb_count = 0;
654*4882a593Smuzhiyun return ret;
655*4882a593Smuzhiyun }
656*4882a593Smuzhiyun
mpp_service_cmd_poll(void * ctx,MppDevPollCfg * cfg)657*4882a593Smuzhiyun MPP_RET mpp_service_cmd_poll(void *ctx, MppDevPollCfg *cfg)
658*4882a593Smuzhiyun {
659*4882a593Smuzhiyun MppDevMppService *p = (MppDevMppService *)ctx;
660*4882a593Smuzhiyun MPP_RET ret = MPP_OK;
661*4882a593Smuzhiyun
662*4882a593Smuzhiyun if (p->batch_io) {
663*4882a593Smuzhiyun ret = mpp_server_wait_task(ctx, 0);
664*4882a593Smuzhiyun } else {
665*4882a593Smuzhiyun MppReqV1 dev_req;
666*4882a593Smuzhiyun
667*4882a593Smuzhiyun memset(&dev_req, 0, sizeof(dev_req));
668*4882a593Smuzhiyun
669*4882a593Smuzhiyun if (p->support_hw_irq && cfg) {
670*4882a593Smuzhiyun dev_req.cmd = MPP_CMD_POLL_HW_IRQ;
671*4882a593Smuzhiyun dev_req.flag |= MPP_FLAGS_LAST_MSG | MPP_FLAGS_REG_OFFSET_ALONE;
672*4882a593Smuzhiyun
673*4882a593Smuzhiyun dev_req.size = sizeof(*cfg) + cfg->count_max * sizeof(cfg->slice_info[0]);
674*4882a593Smuzhiyun dev_req.offset = 0;
675*4882a593Smuzhiyun dev_req.data_ptr = REQ_DATA_PTR(cfg);
676*4882a593Smuzhiyun } else {
677*4882a593Smuzhiyun dev_req.cmd = MPP_CMD_POLL_HW_FINISH;
678*4882a593Smuzhiyun dev_req.flag |= MPP_FLAGS_LAST_MSG | MPP_FLAGS_REG_OFFSET_ALONE;
679*4882a593Smuzhiyun
680*4882a593Smuzhiyun if (cfg) {
681*4882a593Smuzhiyun mpp_assert(cfg->count_max);
682*4882a593Smuzhiyun if (cfg->count_max) {
683*4882a593Smuzhiyun cfg->count_ret = 1;
684*4882a593Smuzhiyun cfg->slice_info[0].val = 0;
685*4882a593Smuzhiyun cfg->slice_info[0].last = 1;
686*4882a593Smuzhiyun }
687*4882a593Smuzhiyun }
688*4882a593Smuzhiyun }
689*4882a593Smuzhiyun
690*4882a593Smuzhiyun ret = mpp_service_ioctl_request(p->server, &dev_req);
691*4882a593Smuzhiyun if (ret) {
692*4882a593Smuzhiyun mpp_err_f("ioctl MPP_IOC_CFG_V1 failed ret %d errno %d %s\n",
693*4882a593Smuzhiyun ret, errno, strerror(errno));
694*4882a593Smuzhiyun ret = errno;
695*4882a593Smuzhiyun }
696*4882a593Smuzhiyun }
697*4882a593Smuzhiyun
698*4882a593Smuzhiyun return ret;
699*4882a593Smuzhiyun }
700*4882a593Smuzhiyun
701*4882a593Smuzhiyun const MppDevApi mpp_service_api = {
702*4882a593Smuzhiyun "mpp_service",
703*4882a593Smuzhiyun sizeof(MppDevMppService),
704*4882a593Smuzhiyun mpp_service_init,
705*4882a593Smuzhiyun mpp_service_deinit,
706*4882a593Smuzhiyun mpp_service_attach,
707*4882a593Smuzhiyun mpp_service_detach,
708*4882a593Smuzhiyun mpp_service_delimit,
709*4882a593Smuzhiyun mpp_service_set_cb_ctx,
710*4882a593Smuzhiyun mpp_service_reg_wr,
711*4882a593Smuzhiyun mpp_service_reg_rd,
712*4882a593Smuzhiyun mpp_service_reg_offset,
713*4882a593Smuzhiyun mpp_service_reg_offsets,
714*4882a593Smuzhiyun mpp_service_rcb_info,
715*4882a593Smuzhiyun mpp_service_set_info,
716*4882a593Smuzhiyun mpp_service_set_err_ref_hack,
717*4882a593Smuzhiyun mpp_service_cmd_send,
718*4882a593Smuzhiyun mpp_service_cmd_poll,
719*4882a593Smuzhiyun };
720