move manifest to packaging directory
[platform/adaptation/intel_mfld/device-manager-plugin-mfld-blackbay.git] / src / vibrator.c
1 #include <alsa/asoundlib.h>
2 #include <errno.h>
3 #include <string.h>
4 #include <iniparser.h>
5 #include <dlog.h>
6 #include <math.h>
7 #include <signal.h>
8 #include <sys/time.h>
9
10 #include "vibrator.h"
11
12 #define LOG_TAG         "slp_devman_plugin"
13 #define VIB_INFO_DEFAULT_PATH "/usr/etc/vibrator.ini"
14 #define MAX_VALUE_SIZE 64
15 #define VIB_INFO_NUM    9
16 #define SESSION "general"
17 #define MALLOC(type, num) (type*)malloc((num)*sizeof(type))
18 #define CYCLE_COUNT_TYPE 1
19 #define ON_TIME_TYPE 2
20
21
22 char *vib_ini_name[VIB_INFO_NUM][2] = {
23         {"Vibra1 Boost Time", "8"},
24         {"Vibra1 Duty Cycle", "50"},
25         {"Vibra1 Brake", "On"},
26         {"Vibra1 Direction", "Forward"},
27         {"Vibra1 On Time", "Infinite"},
28         {"Vibra1 Off Time", "0.00"},
29         {"Vibra1 Cycle Count", "Infinite"},
30         {"Vibra1 Enable Mux", "SPI"},
31         {"Vibra1 Start", "Off"}
32 };
33
34 typedef struct {
35         snd_ctl_elem_info_t *info;
36         snd_ctl_elem_id_t *id;
37         snd_ctl_elem_value_t *control;
38 }vib_stack_t;
39
40 static __thread int err;
41 static __thread char card[MAX_VALUE_SIZE] = "default";
42 static __thread char card_num[MAX_VALUE_SIZE];
43 static __thread char vib_info_value[VIB_INFO_NUM][MAX_VALUE_SIZE];
44 static __thread int init_flag = 0;
45
46 int read_ini_info()
47 {
48         char *tmp;
49         int i;
50         char name[64];
51         memset(vib_info_value, 0, sizeof(vib_info_value));
52         dictionary* dic = iniparser_load(VIB_INFO_DEFAULT_PATH);
53         if(!dic) {
54                 SLOGE("iniparser load err");
55                 return -1;
56         }
57
58         tmp = iniparser_getstring(dic, "general:Card", NULL);
59         if(tmp) {
60                 strncpy(card_num, tmp, strlen(tmp));
61                 card_num[strlen(tmp)] = '\0';
62         } else {
63                 SLOGE("iniparser get card err");
64                 iniparser_freedict(dic);
65                 return -1;
66         }
67
68         for(i = 0; i < VIB_INFO_NUM; i++) {
69                 sprintf(name, "%s:%s", SESSION, vib_ini_name[i][0]);
70                 name[strlen(name)] = '\0';
71                 tmp = iniparser_getstring(dic, name, vib_ini_name[i][1]);
72                 strncpy(vib_info_value[i], tmp, strlen(tmp));
73                 vib_info_value[i][63] = '\0';
74                 SLOGD("name: [%s], vib_info_value[%d]: %s\n", name, i, vib_info_value[i]);
75         }
76
77         if (dic) {
78                 iniparser_freedict(dic);
79                 dic = NULL;
80         }
81
82         return 0;
83 }
84
85 void print_vib_val()
86 {
87         int i;
88         for(i = 0; i < VIB_INFO_NUM; i++) {
89                 SLOGD("print_vid_val: %s", vib_info_value[i]);
90         }
91         SLOGD("card : %s", card_num);
92 }
93
94 int open_vib_hw(snd_ctl_t **handle)
95 {
96         int i;
97         //Get card number
98         i = snd_card_get_index(card_num);
99         if(i >= 0 && i < 32)
100         {
101                 memset(card, 0, sizeof(card));
102                 sprintf(card, "hw:%d", i);
103         } else {
104                 SLOGE("card number err:[%d]", i);
105                 return -1;
106         }
107
108         //Open handle
109         if((err = snd_ctl_open(handle, card, 0)) < 0)
110         {
111                 SLOGE("control %s open err: %s", card, snd_strerror(err));
112                 return -1;
113         }
114
115         return 0;
116 }
117
118 int prepare_snd_ctl(snd_ctl_t *handle, vib_stack_t *stack, 
119                         snd_ctl_elem_type_t *type, unsigned int *count, char *name)
120 {
121         memset(stack->id, 0, snd_ctl_elem_id_sizeof());
122         memset(stack->info, 0, snd_ctl_elem_info_sizeof());
123         memset(stack->control, 0, snd_ctl_elem_value_sizeof());
124
125         //Set interface
126         snd_ctl_elem_id_set_interface(stack->id, SND_CTL_ELEM_IFACE_MIXER);
127
128         //Set name test for Vibra1 Start
129         snd_ctl_elem_id_set_name(stack->id, name);
130
131         //init info id
132         snd_ctl_elem_info_set_id(stack->info, stack->id);
133
134         //get info
135         if((err = snd_ctl_elem_info(handle, stack->info)) < 0)
136         {
137                 SLOGE("get info err : %s", snd_strerror(err));
138                 return -1;
139         }
140
141         //get type
142         *type = snd_ctl_elem_info_get_type(stack->info);
143
144         //get count
145         *count = snd_ctl_elem_info_get_count(stack->info);
146
147         //set value id
148         snd_ctl_elem_value_set_id(stack->control, stack->id);
149
150         return 0;
151 }
152
153 int vib_hw_io(int set_flag, snd_ctl_t *handle, vib_stack_t *stack,
154                         snd_ctl_elem_type_t *type, unsigned int *count, int value, int *out_val)
155 {
156         unsigned int idx;
157         long tmp;
158
159         if(!set_flag) {
160                 //read element
161                 if((err = snd_ctl_elem_read(handle, stack->control)) < 0) {
162                         SLOGE("read element err :%s", snd_strerror(err));
163                         return -1;
164                 }
165
166                 for(idx = 0; idx < *count && idx < 128; idx++) {
167                         switch (*type) {
168                                 case SND_CTL_ELEM_TYPE_BOOLEAN:
169                                         *out_val = snd_ctl_elem_value_get_boolean(stack->control, idx);
170                                         break;
171                                 case SND_CTL_ELEM_TYPE_INTEGER:
172                                         *out_val = snd_ctl_elem_value_get_integer(stack->control, idx);
173                                         break;
174                                 case SND_CTL_ELEM_TYPE_INTEGER64:
175                                         *out_val = snd_ctl_elem_value_get_integer64(stack->control, idx);
176                                         break;
177                                 case SND_CTL_ELEM_TYPE_ENUMERATED:
178                                         *out_val = snd_ctl_elem_value_get_enumerated(stack->control, idx);
179                                         break;
180                                 case SND_CTL_ELEM_TYPE_BYTES:
181                                         *out_val = snd_ctl_elem_value_get_byte(stack->control, idx);
182                                         break;
183                                 default:
184                                         SLOGE("Unknown control element type");
185                                         return -1;
186                         }
187                 }
188         } else {
189                 //set value
190                 tmp = value;
191                 for(idx = 0; idx < *count && idx < 128; idx++)
192                 {
193                         switch (*type) {
194                                 case SND_CTL_ELEM_TYPE_BOOLEAN:
195                                         snd_ctl_elem_value_set_boolean(stack->control, idx, tmp);
196                                         break;
197                                 case SND_CTL_ELEM_TYPE_INTEGER:
198                                         snd_ctl_elem_value_set_integer(stack->control, idx, tmp);
199                                         break;
200                                 case SND_CTL_ELEM_TYPE_INTEGER64:
201                                         snd_ctl_elem_value_set_integer64(stack->control, idx, tmp);
202                                         break;
203                                 case SND_CTL_ELEM_TYPE_ENUMERATED:
204                                         snd_ctl_elem_value_set_enumerated(stack->control, idx, tmp);
205                                         break;
206                                 case SND_CTL_ELEM_TYPE_BYTES:
207                                         snd_ctl_elem_value_set_byte(stack->control, idx, tmp);
208                                         break;
209                                 default:
210                                         SLOGE("Unknown control element type");
211                                         return -1;
212                         }
213
214                         SLOGD("writing alsa element, index %u with value %ld\n", idx, tmp);
215                         // Write element
216                         if ((err = snd_ctl_elem_write(handle, stack->control)) < 0) {
217                                 SLOGE("snd_ctl_elem_write err: %s", snd_strerror(err));
218                                 // Close sound control
219                                 return -1;
220                         }
221                 }
222         }
223         return 0;
224 }
225
226 int translate_str_to_int(snd_ctl_t *handle, vib_stack_t *stack, char *str_val)
227 {
228         int items, i;
229         const char *name;
230
231         items = snd_ctl_elem_info_get_items(stack->info);
232         if (items <= 0)
233                 return -1;
234
235         SLOGD("trans name=[%s], value=[%s]", snd_ctl_elem_id_get_name(stack->id), str_val);
236         for (i = 0; i < items; i++) {
237                 snd_ctl_elem_info_set_item(stack->info, i);
238                 if (snd_ctl_elem_info(handle, stack->info) < 0)
239                         return -1;
240                 name = snd_ctl_elem_info_get_item_name(stack->info);
241                 SLOGE("item %d : %s", i, name);
242                 if(strcmp(name, str_val) == 0) {
243                         return i;
244                 }
245         }
246
247         SLOGD("%s can't find suit value", str_val);
248         return -1;
249 }
250
251
252 int translate_enum_to_value(snd_ctl_t *handle, vib_stack_t *stack, int *value)
253 {
254         int items;
255         char *name;
256
257         items = snd_ctl_elem_info_get_items(stack->info);
258         if (items <= 0)
259                 return -1;
260
261         snd_ctl_elem_info_set_item(stack->info, *value);
262
263         if (snd_ctl_elem_info(handle, stack->info) < 0)
264                 return -1;
265
266         name = snd_ctl_elem_info_get_item_name(stack->info);
267         if(name != NULL)
268                 *value = atoi(name);
269         else
270                 return -1;
271
272         return 0;
273 }
274
275
276 int get_literal_value(snd_ctl_t *handle, vib_stack_t *stack, char **str_val, int flag)
277 {
278         int items, i, j;
279         char *name;
280
281         items = snd_ctl_elem_info_get_items(stack->info);
282         if (items <= 0)
283                 return -1;
284
285         //cyclecount has "off" in the beginning and "infinite" at last
286         //on time has "infinite" at last
287         switch(flag) {
288                 case CYCLE_COUNT_TYPE:
289                         i = 1;
290                         items = items - 1;
291                         break;
292                 case ON_TIME_TYPE:
293                         i = 0;
294                         items = items - 1;
295                         break;
296                 default:
297                         i = 0;
298         }
299
300         for (j = 0; i < items; i++, j++) {
301                 name = NULL;
302                 snd_ctl_elem_info_set_item(stack->info, i);
303                 if (snd_ctl_elem_info(handle, stack->info) < 0)
304                         return -1;
305                 name = snd_ctl_elem_info_get_item_name(stack->info);
306
307                 SLOGE("item %d : %s", i, name);
308                 strncpy(str_val[j], name, strlen(name));
309                 str_val[j][strlen(name)] = '\0';
310         }
311
312         return 0;
313 }
314
315 int get_items_count(snd_ctl_t *handle, vib_stack_t *stack)
316 {
317         int items;
318
319         items = snd_ctl_elem_info_get_items(stack->info);
320
321         if (items <= 0)
322                 return -1;
323         else
324                 return items;
325 }
326
327 void print_array(int cycle_count_num, int ontime_num, double **array)
328 {
329         int pos_cycle_count, pos_ontime;
330         for(pos_cycle_count = 0;pos_cycle_count < cycle_count_num; pos_cycle_count++) {
331                 for(pos_ontime = 0;pos_ontime < ontime_num; pos_ontime++) {
332                         SLOGD("[%.2lf]", array[pos_cycle_count][pos_ontime]);
333                 }
334         }
335 }
336
337 void free_planar_array(void **p, int row)
338 {
339         int i;
340         if(p == NULL)
341                 return;
342         for(i = 0; i < row; i++) {
343                 free(p[i]);
344         }
345         free(p);
346 }
347
348 double **new_double_planar_array(int row, int column)
349 {
350         double **array;
351         int i,j;
352         //get on time literal value
353         array = MALLOC(double *, row);
354         if(array == NULL) {
355                 SLOGE("malloc err");
356                 return NULL;
357         }
358
359         for(i = 0; i < row; i++) {
360                 array[i] = MALLOC(double, column);
361                 if(array[i] == NULL) {
362                         SLOGE("malloc err");
363                         goto free_all;
364                 }
365         }
366         return array;
367
368 free_all:
369         for(j = 0; j < i; j++) {
370                 free(array[j]);
371         }
372         free(array);
373         return NULL;
374 }
375
376 char **new_char_planar_array(int row, int column)
377 {
378         char **array;
379         int i, j;
380
381         array = MALLOC(char *, row);
382         if(array == NULL) {
383                 SLOGE("malloc err");
384                 return NULL;
385         }
386
387         for(i = 0; i < row; i++) {
388                 array[i] = MALLOC(char, column);
389                 if(array[i] == NULL) {
390                         SLOGE("malloc err");
391                         goto free_all;
392                 }
393         }
394         return array;
395
396 free_all:
397         for(j = 0; j < i; j++) {
398                 free(array[j]);
399         }
400         free(array);
401         return NULL;
402 }
403
404 int init_value_array(int cycle_count_num, int ontime_num, double **array)
405 {
406         int pos_cycle_count,pos_ontime, ret;
407         char **p_cycle = NULL, **p_ontime = NULL;
408
409         //get literal value of cyclecount
410         if((p_cycle = new_char_planar_array(cycle_count_num, MAX_VALUE_SIZE)) == NULL) {
411                 SLOGE("new char planar array - cyclecount err");
412                 return -1;
413         }
414         if((ret = vib_hw_ctrl(VIBRA_GET_LITERAL_VALUE_CYCLECOUNT, 0, 0, NULL, p_cycle)) < 0) {
415                 SLOGE("get literal_value_cyclecount err");
416                 goto free_array;
417         }
418
419         //get literal value of on time
420         if((p_ontime = new_char_planar_array(ontime_num, MAX_VALUE_SIZE)) == NULL) {
421                 SLOGE("new char planar array - ontime err");
422                 goto free_array;
423         }
424         if((ret = vib_hw_ctrl(VIBRA_GET_LITERAL_VALUE_ON_TIME, 0, 0, NULL, p_ontime)) < 0) {
425                 SLOGE("get literal_value_ontime err");
426                 goto free_array;
427         }
428
429         //calculate all possible combinations
430         for(pos_cycle_count = 0;pos_cycle_count < cycle_count_num; pos_cycle_count++) {
431                 for(pos_ontime = 0;pos_ontime < ontime_num; pos_ontime++) {
432                         array[pos_cycle_count][pos_ontime] = atof(p_cycle[pos_cycle_count]) * atof(p_ontime[pos_ontime]);
433                         SLOGD("[%.2lf]", array[pos_cycle_count][pos_ontime]);
434                 }
435         }
436
437         free_planar_array(p_cycle, cycle_count_num);
438         free_planar_array(p_ontime, ontime_num);
439         return 0;
440
441 free_array:
442         free_planar_array(p_cycle, cycle_count_num);
443         free_planar_array(p_ontime, ontime_num);
444         return -1;
445 }
446
447 void find_cycle_and_ontime(double **p, int cycle_count_num, int ontime_num, int *out_cycle_pos, int *out_ontime_pos, double value)
448 {
449         double tmp = fabs(p[0][0] - value);
450         int pos_cycle_count, pos_ontime, i = 0, j = 0;
451
452         for(pos_cycle_count = 0; pos_cycle_count < cycle_count_num; pos_cycle_count++) {
453                 for(pos_ontime = 0; pos_ontime < ontime_num; pos_ontime++) {
454                         if(tmp > fabs(value - p[pos_cycle_count][pos_ontime])) {
455                                 i = pos_cycle_count;
456                                 j = pos_ontime;
457                                 tmp = fabs(value - p[pos_cycle_count][pos_ontime]);
458                                 SLOGD("tmp=[%.2lf], p[%d][%d]=[%.2lf]\n", tmp, pos_cycle_count, pos_ontime, p[pos_cycle_count][pos_ontime]);
459                         }
460                 }
461         }
462         *out_cycle_pos = i;
463         *out_ontime_pos = j;
464 }
465
466 int find_suit_value_and_set(int value)
467 {
468         int ret, cycle_count_num, ontime_num, pos_cycle_count = 0, pos_ontime = 0;
469         double **array = NULL;
470
471         if(value <= 0) {
472                 SLOGE("input value %d is not valid", value);
473                 return -1;
474         }
475
476         if((ret = vib_hw_ctrl(VIBRA_GET_NUM_CYCLECOUNT, 0, 0, &cycle_count_num, NULL)) < 0) {
477                 SLOGE("get num_cyclecount err");
478                 return -1;
479         }
480
481         if((ret = vib_hw_ctrl(VIBRA_GET_NUM_ON_TIME, 0, 0, &ontime_num, NULL)) < 0) {
482                 SLOGE("get num_ontime err");
483                 return -1;
484         }
485
486         //drop off, infinite
487         cycle_count_num = cycle_count_num - 2;
488
489         //drop infinite
490         ontime_num = ontime_num - 1;
491
492         if((array = new_double_planar_array(cycle_count_num, ontime_num)) == NULL) {
493                 return -1;
494         }
495
496         ret = init_value_array(cycle_count_num, ontime_num, array);
497         if(ret < 0) {
498                 SLOGE("init array failed");
499                 goto free_array;
500         }
501
502         find_cycle_and_ontime(array, cycle_count_num, ontime_num, &pos_cycle_count, &pos_ontime, (value / 1000.0));
503         SLOGD("find suit cyclecount [%d], onTime [%d]", pos_cycle_count, pos_ontime);
504
505         //set cyclecount , ontime and begin start
506         if(vib_hw_ctrl(VIBRA_CYCLE_COUNT, 1, pos_cycle_count + 1, NULL, NULL)) {
507                 SLOGE("SET Cycle Count %d err", pos_cycle_count + 1);
508                 goto free_array;
509         }
510         if(vib_hw_ctrl(VIBRA_ON_TIME, 1, pos_ontime, NULL, NULL)) {
511                 SLOGE("SET On Time %d err", pos_ontime);
512                 goto free_array;
513         }
514         if(vib_hw_ctrl(VIBRA_START, 1, 1, NULL, NULL)) {
515                 SLOGE("start vibrator err");
516                 goto free_array;
517         }
518
519         free_planar_array(array, cycle_count_num);
520         return 0;
521
522 free_array:
523         free_planar_array(array, cycle_count_num);
524         return -1;
525 }
526
527 int init_vib_value(snd_ctl_t *handle, vib_stack_t *stack, snd_ctl_elem_type_t *type, unsigned int *count)
528 {
529         int value, i;
530         for(i = 0; i < VIB_INFO_NUM; i++) {
531                 err = prepare_snd_ctl(handle, stack, type, count, vib_ini_name[i][0]);
532                 if(err < 0) {
533                         SLOGE("prepare vib hw err");
534                         return -1;
535                 }
536
537                 //in ini file,we define string value not enum value
538                 value = translate_str_to_int(handle, stack, vib_info_value[i]);
539                 if(value < 0) {
540                         SLOGE("[%s] translate err", vib_ini_name[i][0]);
541                         return -1;
542                 }
543
544                 err = vib_hw_io(1, handle, stack, type, count, value, NULL);
545                 if(err < 0) {
546                         SLOGE("ctl vib hw err");
547                         return -1;
548                 }
549         }
550         return 0;
551 }
552
553 int get_hw_name(int type, char *name)
554 {
555         memset(name, 0, sizeof(name));
556         switch(type) {
557                 case VIBRA_BOOST_TIME:
558                         strncpy(name, vib_ini_name[VIBRA_BOOST_TIME][0], strlen(vib_ini_name[VIBRA_BOOST_TIME][0]));
559                         name[strlen(vib_ini_name[VIBRA_BOOST_TIME][0])] = '\0';
560                         break;
561                 case VIBRA_DUTY_CYCLE:
562                 case VIBRA_GET_LEVEL_MAX:
563                         strncpy(name, vib_ini_name[VIBRA_DUTY_CYCLE][0], strlen(vib_ini_name[VIBRA_DUTY_CYCLE][0]));
564                         name[strlen(vib_ini_name[VIBRA_DUTY_CYCLE][0])] = '\0';
565                         break;
566                 case VIBRA_BRAKE:
567                         strncpy(name, vib_ini_name[VIBRA_BRAKE][0], strlen(vib_ini_name[VIBRA_BRAKE][0]));
568                         name[strlen(vib_ini_name[VIBRA_BRAKE][0])] = '\0';
569                         break;
570                 case VIBRA_DIRECTION:
571                         strncpy(name, vib_ini_name[VIBRA_DIRECTION][0], strlen(vib_ini_name[VIBRA_DIRECTION][0]));
572                         name[strlen(vib_ini_name[VIBRA_DIRECTION][0])] = '\0';
573                         break;
574                 case VIBRA_ON_TIME:
575                 case VIBRA_GET_NUM_ON_TIME: 
576                 case VIBRA_GET_LITERAL_VALUE_ON_TIME:
577                         strncpy(name, vib_ini_name[VIBRA_ON_TIME][0], strlen(vib_ini_name[VIBRA_ON_TIME][0]));
578                         name[strlen(vib_ini_name[VIBRA_ON_TIME][0])] = '\0';
579                         break;
580                 case VIBRA_OFF_TIME:
581                         strncpy(name, vib_ini_name[VIBRA_OFF_TIME][0], strlen(vib_ini_name[VIBRA_OFF_TIME][0]));
582                         name[strlen(vib_ini_name[VIBRA_OFF_TIME][0])] = '\0';
583                         break;
584                 case VIBRA_CYCLE_COUNT:
585                 case VIBRA_GET_NUM_CYCLECOUNT:
586                 case VIBRA_GET_LITERAL_VALUE_CYCLECOUNT:
587                         strncpy(name, vib_ini_name[VIBRA_CYCLE_COUNT][0], strlen(vib_ini_name[VIBRA_CYCLE_COUNT][0]));
588                         name[strlen(vib_ini_name[VIBRA_CYCLE_COUNT][0])] = '\0';
589                         break;
590                 case VIBRA_ENABLE_MUX:
591                         strncpy(name, vib_ini_name[VIBRA_ENABLE_MUX][0], strlen(vib_ini_name[VIBRA_ENABLE_MUX][0]));
592                         name[strlen(vib_ini_name[VIBRA_ENABLE_MUX][0])] = '\0';
593                         break;
594                 case VIBRA_START:
595                         strncpy(name, vib_ini_name[VIBRA_START][0], strlen(vib_ini_name[VIBRA_START][0]));
596                         name[strlen(vib_ini_name[VIBRA_START][0])] = '\0';
597                         break;
598                 default:
599                         SLOGE("can't find suit name, type: %d", type);
600                         return -1;
601         }
602         return 0;
603 }
604
605 void get_alarm_and_stop(int num)
606 {
607         if(vib_hw_ctrl(VIBRA_START, 1, 0, NULL, NULL)) {
608                 SLOGE("start vibrator err");
609                 return;
610         }
611 }
612
613 int settimer_and_vibrate(int value)
614 {
615         int sec = 0, usec = 0, ret;
616         struct itimerval tick;
617
618         if(value <= 0) {
619                 SLOGE("input value %d is not valid", value);
620                 return -1;
621         }
622
623         signal(SIGALRM, get_alarm_and_stop);
624         
625         sec = value / 1000;
626         usec = (value % 1000) * 1000;
627
628         tick.it_value.tv_sec = sec;
629         tick.it_value.tv_usec = usec;
630         tick.it_interval.tv_sec = 0; 
631         tick.it_interval.tv_usec = 0;
632         
633         ret = setitimer(ITIMER_REAL, &tick, NULL);
634         if (ret != 0)
635         {
636                 SLOGE("Settimer error.%s", strerror(errno));
637                 return -1 ;
638         }
639
640         if(vib_hw_ctrl(VIBRA_START, 1, 1, NULL, NULL)) {
641                 SLOGE("start vibrator err");
642                 return -1;
643         }
644         return 0;
645 }
646
647 int vib_hw_ctrl(int hw_ctl_type, int set_flag, int value, int *out_val, char **literal_value)
648 {
649         snd_ctl_t *handle = NULL;
650         vib_stack_t stack;
651         snd_ctl_elem_type_t type;
652         unsigned int count;
653         char hw_name[MAX_VALUE_SIZE];
654
655         //init default vib_info
656         if(!init_flag) {
657                 if((err = read_ini_info()) < 0) {
658                         SLOGE("init vib info err:%d", err);
659                         return -1;
660                 }
661                 print_vib_val();
662         }
663
664         //Allocate in stack
665         snd_ctl_elem_id_alloca(&(stack.id));
666         snd_ctl_elem_info_alloca(&(stack.info));
667         snd_ctl_elem_value_alloca(&(stack.control));
668
669         if((err = open_vib_hw(&handle)) < 0) {
670                 SLOGE("open vib hw err");
671                 return -1;
672         }
673
674         //init all values first
675         if(!init_flag) {
676                 err = init_vib_value(handle, &stack, &type, &count);
677                 if(err < 0) {
678                         SLOGE("prepare vib hw err");
679                         goto error;
680                 }
681                 init_flag = 1;
682         }
683
684         err = get_hw_name(hw_ctl_type, hw_name);
685         if(err < 0) {
686                 SLOGE("prepare vib hw err");
687                 goto error;
688         }
689
690         SLOGD("hw_name : [%s]", hw_name);
691         err = prepare_snd_ctl(handle, &stack, &type, &count, hw_name);
692         if(err < 0) {
693                 SLOGE("prepare vib hw err");
694                 goto error;
695         }
696
697         //set value
698         if(set_flag) {
699                 if(hw_ctl_type == VIBRA_DUTY_CYCLE) {
700                         char tmp[32];
701                         memset(tmp, 0, sizeof(tmp));
702                         sprintf(tmp, "%d", value);
703
704                         value = translate_str_to_int(handle, &stack, tmp);
705                         if(value < 0) {
706                                 SLOGE("[%s] translate err", tmp);
707                                 goto error;
708                         }
709                 }
710
711                 err = vib_hw_io(1, handle, &stack, &type, &count, value, NULL);
712                 if(err < 0) {
713                         SLOGE("ctl vib hw err");
714                         goto error;
715                 }
716         //or get value
717         } else {
718                 switch(hw_ctl_type) {
719                         case VIBRA_GET_LEVEL_MAX:
720                                 if((*out_val = get_items_count(handle, &stack)) < 0) {
721                                         SLOGE("get level max err");
722                                         goto error;
723                                 }
724         
725                                 (*out_val)--;
726                                 break;
727                         case VIBRA_GET_NUM_CYCLECOUNT:
728                         case VIBRA_GET_NUM_ON_TIME:
729                                 if((*out_val = get_items_count(handle, &stack)) < 0) {
730                                         SLOGE("get count num err");
731                                         goto error;
732                                 }
733                                 break;
734                         case VIBRA_GET_LITERAL_VALUE_CYCLECOUNT:
735                                 if((err = get_literal_value(handle, &stack, literal_value, CYCLE_COUNT_TYPE)) < 0) {
736                                         SLOGE("get cycle count literal value err");
737                                         goto error;
738                                 }
739                                 break;
740                         case VIBRA_GET_LITERAL_VALUE_ON_TIME:
741                                 if((err = get_literal_value(handle, &stack, literal_value, ON_TIME_TYPE)) < 0) {
742                                         SLOGE("get on time literal value err");
743                                         goto error;
744                                 }
745                                 break;
746                         default:
747                                 err = vib_hw_io(0, handle, &stack, &type, &count, 0, out_val);
748                                 if(err < 0) {
749                                         SLOGE("ctl vib hw err");
750                                         goto error;
751                                 }
752                                 break;
753                 }
754
755                 if(hw_ctl_type == VIBRA_DUTY_CYCLE 
756                         || hw_ctl_type == VIBRA_GET_LEVEL_MAX) {
757                         err = translate_enum_to_value(handle, &stack, out_val);
758                         if(err < 0) {
759                                 SLOGE("ctl vib hw err");
760                                 goto error;
761                         }
762                 }
763         }
764         snd_ctl_close(handle);
765         return 0;
766
767 error:
768         snd_ctl_close(handle);
769         return -1;
770 }