1 /*
2 Copyright (c) 2012, The Linux Foundation. All rights reserved.
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are
6 met:
7 * Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above
10 copyright notice, this list of conditions and the following
11 disclaimer in the documentation and/or other materials provided
12 with the distribution.
13 * Neither the name of The Linux Foundation nor the names of its
14 contributors may be used to endorse or promote products derived
15 from this software without specific prior written permission.
16
17 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #include <pthread.h>
31 #include <errno.h>
32 #include <sys/ioctl.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <fcntl.h>
36 #include <semaphore.h>
37
38 #include "mm_jpeg_dbg.h"
39 #include "mm_jpeg_interface.h"
40 #include "mm_jpeg.h"
41
42 static pthread_mutex_t g_intf_lock = PTHREAD_MUTEX_INITIALIZER;
43 static mm_jpeg_obj* g_jpeg_obj = NULL;
44
45 static pthread_mutex_t g_handler_lock = PTHREAD_MUTEX_INITIALIZER;
46 static uint16_t g_handler_history_count = 0; /* history count for handler */
47
48 /* utility function to generate handler */
mm_jpeg_util_generate_handler(uint8_t index)49 uint32_t mm_jpeg_util_generate_handler(uint8_t index)
50 {
51 uint32_t handler = 0;
52 pthread_mutex_lock(&g_handler_lock);
53 g_handler_history_count++;
54 if (0 == g_handler_history_count) {
55 g_handler_history_count++;
56 }
57 handler = g_handler_history_count;
58 handler = (handler<<8) | index;
59 pthread_mutex_unlock(&g_handler_lock);
60 return handler;
61 }
62
mm_jpeg_util_get_index_by_handler(uint32_t handler)63 uint8_t mm_jpeg_util_get_index_by_handler(uint32_t handler)
64 {
65 return (handler&0x000000ff);
66 }
67
mm_jpeg_intf_start_job(uint32_t client_hdl,mm_jpeg_job * job,uint32_t * jobId)68 static int32_t mm_jpeg_intf_start_job(uint32_t client_hdl, mm_jpeg_job* job, uint32_t* jobId)
69 {
70 int32_t rc = -1;
71
72 if (0 == client_hdl ||
73 NULL == job ||
74 NULL == jobId) {
75 CDBG_ERROR("%s: invalid parameters for client_hdl, job or jobId", __func__);
76 return rc;
77 }
78
79 pthread_mutex_lock(&g_intf_lock);
80 if (NULL == g_jpeg_obj) {
81 /* mm_jpeg obj not exists, return error */
82 CDBG_ERROR("%s: mm_jpeg is not opened yet", __func__);
83 pthread_mutex_unlock(&g_intf_lock);
84 return rc;
85 }
86
87 rc = mm_jpeg_start_job(g_jpeg_obj, client_hdl, job, jobId);
88 pthread_mutex_unlock(&g_intf_lock);
89 return rc;
90 }
91
mm_jpeg_intf_abort_job(uint32_t client_hdl,uint32_t jobId)92 static int32_t mm_jpeg_intf_abort_job(uint32_t client_hdl, uint32_t jobId)
93 {
94 int32_t rc = -1;
95
96 if (0 == client_hdl || 0 == jobId) {
97 CDBG_ERROR("%s: invalid client_hdl or jobId", __func__);
98 return rc;
99 }
100
101 pthread_mutex_lock(&g_intf_lock);
102 if (NULL == g_jpeg_obj) {
103 /* mm_jpeg obj not exists, return error */
104 CDBG_ERROR("%s: mm_jpeg is not opened yet", __func__);
105 pthread_mutex_unlock(&g_intf_lock);
106 return rc;
107 }
108
109 rc = mm_jpeg_abort_job(g_jpeg_obj, client_hdl, jobId);
110 pthread_mutex_unlock(&g_intf_lock);
111 return rc;
112 }
113
mm_jpeg_intf_close(uint32_t client_hdl)114 static int32_t mm_jpeg_intf_close(uint32_t client_hdl)
115 {
116 int32_t rc = -1;
117
118 if (0 == client_hdl) {
119 CDBG_ERROR("%s: invalid client_hdl", __func__);
120 return rc;
121 }
122
123 pthread_mutex_lock(&g_intf_lock);
124 if (NULL == g_jpeg_obj) {
125 /* mm_jpeg obj not exists, return error */
126 CDBG_ERROR("%s: mm_jpeg is not opened yet", __func__);
127 pthread_mutex_unlock(&g_intf_lock);
128 return rc;
129 }
130
131 rc = mm_jpeg_close(g_jpeg_obj, client_hdl);
132
133 if(0 == rc) {
134 if (0 == g_jpeg_obj->num_clients) {
135 /* No client, close jpeg internally */
136 rc = mm_jpeg_deinit(g_jpeg_obj);
137 free(g_jpeg_obj);
138 g_jpeg_obj = NULL;
139 }
140 }
141
142 pthread_mutex_unlock(&g_intf_lock);
143 return rc;
144 }
145
146 /* open jpeg client */
jpeg_open(mm_jpeg_ops_t * ops)147 uint32_t jpeg_open(mm_jpeg_ops_t *ops)
148 {
149 int32_t rc = 0;
150 uint32_t clnt_hdl = 0;
151 mm_jpeg_obj* jpeg_obj = NULL;
152
153 pthread_mutex_lock(&g_intf_lock);
154 /* first time open */
155 if(NULL == g_jpeg_obj) {
156 jpeg_obj = (mm_jpeg_obj *)malloc(sizeof(mm_jpeg_obj));
157 if(NULL == jpeg_obj) {
158 CDBG_ERROR("%s: no mem", __func__);
159 pthread_mutex_unlock(&g_intf_lock);
160 return clnt_hdl;
161 }
162
163 /* initialize jpeg obj */
164 memset(jpeg_obj, 0, sizeof(mm_jpeg_obj));
165 rc = mm_jpeg_init(jpeg_obj);
166 if(0 != rc) {
167 CDBG_ERROR("%s: mm_jpeg_init err = %d", __func__, rc);
168 free(jpeg_obj);
169 pthread_mutex_unlock(&g_intf_lock);
170 return clnt_hdl;
171 }
172
173 /* remember in global variable */
174 g_jpeg_obj = jpeg_obj;
175 }
176
177 /* open new client */
178 clnt_hdl = mm_jpeg_new_client(g_jpeg_obj);
179 if (clnt_hdl > 0) {
180 /* valid client */
181 if (NULL != ops) {
182 /* fill in ops tbl if ptr not NULL */
183 ops->start_job = mm_jpeg_intf_start_job;
184 ops->abort_job = mm_jpeg_intf_abort_job;
185 //ops->abort_job_all = mm_jpeg_intf_close,
186 ops->close = mm_jpeg_intf_close;
187 }
188 } else {
189 /* failed new client */
190 CDBG_ERROR("%s: mm_jpeg_new_client failed", __func__);
191
192 if (0 == g_jpeg_obj->num_clients) {
193 /* no client, close jpeg */
194 mm_jpeg_deinit(g_jpeg_obj);
195 free(g_jpeg_obj);
196 g_jpeg_obj = NULL;
197 }
198 }
199
200 pthread_mutex_unlock(&g_intf_lock);
201 return clnt_hdl;
202 }
203