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