1 #include <alsa/asoundlib.h>
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
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"}
35 snd_ctl_elem_info_t *info;
36 snd_ctl_elem_id_t *id;
37 snd_ctl_elem_value_t *control;
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;
51 memset(vib_info_value, 0, sizeof(vib_info_value));
52 dictionary* dic = iniparser_load(VIB_INFO_DEFAULT_PATH);
54 SLOGE("iniparser load err");
58 tmp = iniparser_getstring(dic, "general:Card", NULL);
60 strncpy(card_num, tmp, strlen(tmp));
61 card_num[strlen(tmp)] = '\0';
63 SLOGE("iniparser get card err");
64 iniparser_freedict(dic);
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]);
78 iniparser_freedict(dic);
88 for(i = 0; i < VIB_INFO_NUM; i++) {
89 SLOGD("print_vid_val: %s", vib_info_value[i]);
91 SLOGD("card : %s", card_num);
94 int open_vib_hw(snd_ctl_t **handle)
98 i = snd_card_get_index(card_num);
101 memset(card, 0, sizeof(card));
102 sprintf(card, "hw:%d", i);
104 SLOGE("card number err:[%d]", i);
109 if((err = snd_ctl_open(handle, card, 0)) < 0)
111 SLOGE("control %s open err: %s", card, snd_strerror(err));
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)
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());
126 snd_ctl_elem_id_set_interface(stack->id, SND_CTL_ELEM_IFACE_MIXER);
128 //Set name test for Vibra1 Start
129 snd_ctl_elem_id_set_name(stack->id, name);
132 snd_ctl_elem_info_set_id(stack->info, stack->id);
135 if((err = snd_ctl_elem_info(handle, stack->info)) < 0)
137 SLOGE("get info err : %s", snd_strerror(err));
142 *type = snd_ctl_elem_info_get_type(stack->info);
145 *count = snd_ctl_elem_info_get_count(stack->info);
148 snd_ctl_elem_value_set_id(stack->control, stack->id);
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)
161 if((err = snd_ctl_elem_read(handle, stack->control)) < 0) {
162 SLOGE("read element err :%s", snd_strerror(err));
166 for(idx = 0; idx < *count && idx < 128; idx++) {
168 case SND_CTL_ELEM_TYPE_BOOLEAN:
169 *out_val = snd_ctl_elem_value_get_boolean(stack->control, idx);
171 case SND_CTL_ELEM_TYPE_INTEGER:
172 *out_val = snd_ctl_elem_value_get_integer(stack->control, idx);
174 case SND_CTL_ELEM_TYPE_INTEGER64:
175 *out_val = snd_ctl_elem_value_get_integer64(stack->control, idx);
177 case SND_CTL_ELEM_TYPE_ENUMERATED:
178 *out_val = snd_ctl_elem_value_get_enumerated(stack->control, idx);
180 case SND_CTL_ELEM_TYPE_BYTES:
181 *out_val = snd_ctl_elem_value_get_byte(stack->control, idx);
184 SLOGE("Unknown control element type");
191 for(idx = 0; idx < *count && idx < 128; idx++)
194 case SND_CTL_ELEM_TYPE_BOOLEAN:
195 snd_ctl_elem_value_set_boolean(stack->control, idx, tmp);
197 case SND_CTL_ELEM_TYPE_INTEGER:
198 snd_ctl_elem_value_set_integer(stack->control, idx, tmp);
200 case SND_CTL_ELEM_TYPE_INTEGER64:
201 snd_ctl_elem_value_set_integer64(stack->control, idx, tmp);
203 case SND_CTL_ELEM_TYPE_ENUMERATED:
204 snd_ctl_elem_value_set_enumerated(stack->control, idx, tmp);
206 case SND_CTL_ELEM_TYPE_BYTES:
207 snd_ctl_elem_value_set_byte(stack->control, idx, tmp);
210 SLOGE("Unknown control element type");
214 SLOGD("writing alsa element, index %u with value %ld\n", idx, tmp);
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
226 int translate_str_to_int(snd_ctl_t *handle, vib_stack_t *stack, char *str_val)
231 items = snd_ctl_elem_info_get_items(stack->info);
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)
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) {
247 SLOGD("%s can't find suit value", str_val);
252 int translate_enum_to_value(snd_ctl_t *handle, vib_stack_t *stack, int *value)
257 items = snd_ctl_elem_info_get_items(stack->info);
261 snd_ctl_elem_info_set_item(stack->info, *value);
263 if (snd_ctl_elem_info(handle, stack->info) < 0)
266 name = snd_ctl_elem_info_get_item_name(stack->info);
276 int get_literal_value(snd_ctl_t *handle, vib_stack_t *stack, char **str_val, int flag)
281 items = snd_ctl_elem_info_get_items(stack->info);
285 //cyclecount has "off" in the beginning and "infinite" at last
286 //on time has "infinite" at last
288 case CYCLE_COUNT_TYPE:
300 for (j = 0; i < items; i++, j++) {
302 snd_ctl_elem_info_set_item(stack->info, i);
303 if (snd_ctl_elem_info(handle, stack->info) < 0)
305 name = snd_ctl_elem_info_get_item_name(stack->info);
307 SLOGE("item %d : %s", i, name);
308 strncpy(str_val[j], name, strlen(name));
309 str_val[j][strlen(name)] = '\0';
315 int get_items_count(snd_ctl_t *handle, vib_stack_t *stack)
319 items = snd_ctl_elem_info_get_items(stack->info);
327 void print_array(int cycle_count_num, int ontime_num, double **array)
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]);
337 void free_planar_array(void **p, int row)
342 for(i = 0; i < row; i++) {
348 double **new_double_planar_array(int row, int column)
352 //get on time literal value
353 array = MALLOC(double *, row);
359 for(i = 0; i < row; i++) {
360 array[i] = MALLOC(double, column);
361 if(array[i] == NULL) {
369 for(j = 0; j < i; j++) {
376 char **new_char_planar_array(int row, int column)
381 array = MALLOC(char *, row);
387 for(i = 0; i < row; i++) {
388 array[i] = MALLOC(char, column);
389 if(array[i] == NULL) {
397 for(j = 0; j < i; j++) {
404 int init_value_array(int cycle_count_num, int ontime_num, double **array)
406 int pos_cycle_count,pos_ontime, ret;
407 char **p_cycle = NULL, **p_ontime = NULL;
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");
414 if((ret = vib_hw_ctrl(VIBRA_GET_LITERAL_VALUE_CYCLECOUNT, 0, 0, NULL, p_cycle)) < 0) {
415 SLOGE("get literal_value_cyclecount err");
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");
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");
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]);
437 free_planar_array(p_cycle, cycle_count_num);
438 free_planar_array(p_ontime, ontime_num);
442 free_planar_array(p_cycle, cycle_count_num);
443 free_planar_array(p_ontime, ontime_num);
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)
449 double tmp = fabs(p[0][0] - value);
450 int pos_cycle_count, pos_ontime, i = 0, j = 0;
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])) {
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]);
466 int find_suit_value_and_set(int value)
468 int ret, cycle_count_num, ontime_num, pos_cycle_count = 0, pos_ontime = 0;
469 double **array = NULL;
472 SLOGE("input value %d is not valid", value);
476 if((ret = vib_hw_ctrl(VIBRA_GET_NUM_CYCLECOUNT, 0, 0, &cycle_count_num, NULL)) < 0) {
477 SLOGE("get num_cyclecount err");
481 if((ret = vib_hw_ctrl(VIBRA_GET_NUM_ON_TIME, 0, 0, &ontime_num, NULL)) < 0) {
482 SLOGE("get num_ontime err");
487 cycle_count_num = cycle_count_num - 2;
490 ontime_num = ontime_num - 1;
492 if((array = new_double_planar_array(cycle_count_num, ontime_num)) == NULL) {
496 ret = init_value_array(cycle_count_num, ontime_num, array);
498 SLOGE("init array failed");
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);
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);
510 if(vib_hw_ctrl(VIBRA_ON_TIME, 1, pos_ontime, NULL, NULL)) {
511 SLOGE("SET On Time %d err", pos_ontime);
514 if(vib_hw_ctrl(VIBRA_START, 1, 1, NULL, NULL)) {
515 SLOGE("start vibrator err");
519 free_planar_array(array, cycle_count_num);
523 free_planar_array(array, cycle_count_num);
527 int init_vib_value(snd_ctl_t *handle, vib_stack_t *stack, snd_ctl_elem_type_t *type, unsigned int *count)
530 for(i = 0; i < VIB_INFO_NUM; i++) {
531 err = prepare_snd_ctl(handle, stack, type, count, vib_ini_name[i][0]);
533 SLOGE("prepare vib hw err");
537 //in ini file,we define string value not enum value
538 value = translate_str_to_int(handle, stack, vib_info_value[i]);
540 SLOGE("[%s] translate err", vib_ini_name[i][0]);
544 err = vib_hw_io(1, handle, stack, type, count, value, NULL);
546 SLOGE("ctl vib hw err");
553 int get_hw_name(int type, char *name)
555 memset(name, 0, sizeof(name));
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';
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';
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';
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';
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';
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';
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';
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';
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';
599 SLOGE("can't find suit name, type: %d", type);
605 void get_alarm_and_stop(int num)
607 if(vib_hw_ctrl(VIBRA_START, 1, 0, NULL, NULL)) {
608 SLOGE("start vibrator err");
613 int settimer_and_vibrate(int value)
615 int sec = 0, usec = 0, ret;
616 struct itimerval tick;
619 SLOGE("input value %d is not valid", value);
623 signal(SIGALRM, get_alarm_and_stop);
626 usec = (value % 1000) * 1000;
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;
633 ret = setitimer(ITIMER_REAL, &tick, NULL);
636 SLOGE("Settimer error.%s", strerror(errno));
640 if(vib_hw_ctrl(VIBRA_START, 1, 1, NULL, NULL)) {
641 SLOGE("start vibrator err");
647 int vib_hw_ctrl(int hw_ctl_type, int set_flag, int value, int *out_val, char **literal_value)
649 snd_ctl_t *handle = NULL;
651 snd_ctl_elem_type_t type;
653 char hw_name[MAX_VALUE_SIZE];
655 //init default vib_info
657 if((err = read_ini_info()) < 0) {
658 SLOGE("init vib info err:%d", err);
665 snd_ctl_elem_id_alloca(&(stack.id));
666 snd_ctl_elem_info_alloca(&(stack.info));
667 snd_ctl_elem_value_alloca(&(stack.control));
669 if((err = open_vib_hw(&handle)) < 0) {
670 SLOGE("open vib hw err");
674 //init all values first
676 err = init_vib_value(handle, &stack, &type, &count);
678 SLOGE("prepare vib hw err");
684 err = get_hw_name(hw_ctl_type, hw_name);
686 SLOGE("prepare vib hw err");
690 SLOGD("hw_name : [%s]", hw_name);
691 err = prepare_snd_ctl(handle, &stack, &type, &count, hw_name);
693 SLOGE("prepare vib hw err");
699 if(hw_ctl_type == VIBRA_DUTY_CYCLE) {
701 memset(tmp, 0, sizeof(tmp));
702 sprintf(tmp, "%d", value);
704 value = translate_str_to_int(handle, &stack, tmp);
706 SLOGE("[%s] translate err", tmp);
711 err = vib_hw_io(1, handle, &stack, &type, &count, value, NULL);
713 SLOGE("ctl vib hw err");
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");
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");
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");
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");
747 err = vib_hw_io(0, handle, &stack, &type, &count, 0, out_val);
749 SLOGE("ctl vib hw err");
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);
759 SLOGE("ctl vib hw err");
764 snd_ctl_close(handle);
768 snd_ctl_close(handle);