#define STANDARD_FILE_PATH FEEDBACK_BASE_PATH"vibration/"
#define VIBRATION_CONF_PATH FEEDBACK_BASE_PATH"vibration.conf"
+#define PATTERN_DEFAULT_MONOTONE "FEEDBACK_PATTERN_DEFAULT"
+
#define HAPTIC_CONF_PATH "/etc/feedbackd/haptic.conf"
#define SIGNAL_POWEROFF_STATE "ChangeState"
#define SIGNAL_VIBRATOR_INITIATED "InitiateVibrator"
struct duration_data {
int duration;
int intensity;
+ int frequency;
+ int overdrive;
int wait;
};
unsigned int handle;
int duration;
int level;
+ int intensity;
int priority;
};
};
static struct haptic_config haptic_conf;
+static struct duration_data haptic_default_data;
static int haptic_start(void);
static int haptic_stop(void);
memcpy(data, update, sizeof(struct duration_data));
/* insert vibration pattern data */
// to debug :
- // _D("%dD%dI%dF%dO%dW", data->duration, data->intensity, data->frequency, data->overdriving, data->wait);
+ // _D("%dD%dI%dF%dO%dW", data->duration, data->intensity, data->frequency, data->overdrive, data->wait);
DD_LIST_APPEND(*conf_data, data);
return 0;
}
get_pattern_property(&iter, 'I', &update.intensity);
if (update.intensity > INTENSITY_BASE_RATE)
update.intensity = INTENSITY_BASE_RATE;
+ get_pattern_property(&iter, 'F', &update.frequency);
get_pattern_property(&iter, 'W', &update.wait);
if (update.duration == 0 && update.wait == 0) {
get_pattern_property(&val, 'C', &value);
ret = count;
- if (count == 1) { //duration
+ switch (count) {
+ case 1: /* D */
duration = value;
*pattern_duration += duration;
if (*pattern_duration > VIB_LOCK_TIMEOUT_MAX) {
_D("Max pattern duration.");
*pattern_duration = VIB_LOCK_TIMEOUT_MAX;
}
- } else if (count == 2) {
- /* if intensity is 0, duration use for wait(off) time */
+ break;
+ case 2: /* I or W */
if (value > INTENSITY_BASE_RATE)
value = INTENSITY_BASE_RATE;
intensity = value;
if (*packed == false) {
update->duration = duration;
update->intensity = intensity;
+ break;
+ }
+ /* if intensity is 0, duration use for wait(off) time */
+ if (intensity == 0)
+ update->wait = duration;
+ else
+ update->wait = 0;
+ *packed = false;
+ duration = 0;
+ intensity = 0;
+ ret = -1;
+ break;
+ case 3: /* F */
+ if (intensity != 0)
+ update->frequency = value;
+ break;
+ case 4: /* O */
+ if (intensity != 0) {
+ update->overdrive = value;
*packed = true;
- } else {
- if (intensity == 0)
- update->wait = duration;
- else
- update->wait = 0;
- *packed = false;
- duration = 0;
- ret = -1;
}
- } else if (count == 4)
ret = 0;
-
+ break;
+ default:
+ break;
+ }
return ret;
}
/*
- duration, intensity, frequency, overdriving
- waiting duration, intensity=0, frequency, overdriving
+ duration, intensity, frequency, overdrive
+ waiting duration, intensity=0, frequency, overdrive
85,10000,
90,0,
105,10000,
load_standard_vibration_patterns();
}
+static void get_default_haptic_data()
+{
+ dd_list *elem;
+ struct vibration_config *conf;
+
+ memset(&haptic_default_data, 0, sizeof(struct duration_data));
+
+ DD_LIST_FOREACH(vib_conf_list, elem, conf) {
+ if (!conf->pattern)
+ continue;
+ if (strcmp(conf->pattern, PATTERN_DEFAULT_MONOTONE))
+ continue;
+
+ if (conf->data)
+ memcpy(&haptic_default_data, conf->data->data, sizeof(struct duration_data));
+
+ break;
+ }
+ _D("Default haptic data: intensity=%d, frequency=%d", haptic_default_data.intensity, haptic_default_data.frequency);
+}
+
static int haptic_module_load(void)
{
struct haptic_ops *ops;
int r;
pattern_config_parse();
+ get_default_haptic_data();
/* find valid plugin */
DD_LIST_FOREACH(h_head, elem, ops) {
if (ops->is_valid && ops->is_valid()) {
return 0;
}
+/*
static int convert_magnitude_by_conf(int level)
{
int i, step;
_D("Play default level.");
return DEFAULT_FEEDBACK_LEVEL * HAPTIC_FEEDBACK_STEP;
}
-
+*/
GVariant *hdbus_get_count(GDBusConnection *conn,
const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
if (ret != DEVICE_ERROR_NONE)
_E("Failed to request power lock.");
+ _D("Handle(%d) play=%dms, level=%d, intensity=%d, frequency=%d)",
+ cur_h_data.handle, vibrate_info->duration, cur_h_data.level,
+ vibrate_info->intensity, haptic_default_data.frequency);
+
duration_timer = g_timeout_add(vibrate_info->duration, _cb, NULL);
- h_ops->vibrate_monotone(cur_h_data.handle, vibrate_info->duration, cur_h_data.level, cur_h_data.priority);
+ h_ops->vibrate_monotone(cur_h_data.handle, vibrate_info->duration, haptic_default_data.frequency, 0, cur_h_data.level, vibrate_info->intensity, cur_h_data.priority);
free(vibrate_info);
}
{
struct vibrate_monotone_info *vibrate_info;
unsigned int handle;
- int duration, level, priority, ret = 0;
+ int duration, level, intensity, priority, ret = 0;
if (!CHECK_VALID_OPS(h_ops, ret))
goto exit;
if (haptic_disabled)
goto exit;
- g_variant_get(param, "(uiii)", &handle, &duration, &level, &priority);
+ g_variant_get(param, "(uiii)", &handle, &duration, &intensity, &priority);
- /* convert as per conf value */
- level = convert_magnitude_by_conf(level);
- if (level < 0) {
+ if (intensity < 0) {
ret = -EINVAL;
goto exit;
}
goto exit;
}
+ if (vconf_get_int(VCONFKEY_SETAPPL_NOTI_VIBRATION_LEVEL_INT, &level) < 0) {
+ _E("Failed to get '"VCONFKEY_SETAPPL_NOTI_VIBRATION_LEVEL_INT"' value.");
+ ret = -EINVAL;
+ goto exit;
+ }
+
vibrate_info = calloc(1, sizeof(struct vibrate_monotone_info));
if (!vibrate_info) {
_E("Failed to allocate memory for vibrate_info.");
vibrate_info->handle = handle;
vibrate_info->duration = duration;
- vibrate_info->level = level;
+ vibrate_info->level = (level/2) + 1;
+ vibrate_info->intensity = intensity * 100; // 1~100 (API spec)
vibrate_info->priority = priority;
ret = add_idle_request(vibrate_monotone_idler_cb, (void *)vibrate_info);
{
dd_list *head, *n, *next;
struct duration_data *node;
- int level;
int ret = 0;
if (duration_timer) {
}
DD_LIST_FOREACH_SAFE(head, n, next, node) {
- _D("Handle(%d) play=%dms and Wait=%dms %s type.",
+ _D("Handle(%d) play=%dms and Wait=%dms %s type. (level=%d, intensity=%d, frequency=%d)",
cur_h_data.handle, node->duration, node->wait,
- cur_h_data.unlimit ? "Unlimit" : "Once");
+ cur_h_data.unlimit ? "Unlimit" : "Once", cur_h_data.level, node->intensity, node->frequency);
if ((node->duration + node->wait) <= 0) {
if (!cur_h_data.unlimit) {
cur_h_data.handle = INVALID_HANDLE;
}
}
- if (node->intensity)
- level = (cur_h_data.level * node->intensity) / INTENSITY_BASE_RATE;
- else
- level = cur_h_data.level;
-
duration_timer = g_timeout_add((node->duration + node->wait), haptic_duration_play, (void *)next);
- ret = h_ops->vibrate_monotone(cur_h_data.handle, node->duration, level, cur_h_data.priority);
+ ret = h_ops->vibrate_monotone(cur_h_data.handle, node->duration, node->frequency, node->overdrive, cur_h_data.level, node->intensity, cur_h_data.priority);
break;
}
g_variant_get(param, "(usii)", &handle, &pattern, &level, &priority);
- /* convert as per conf value */
- level = convert_magnitude_by_conf(level);
if (level < 0) {
ret = -EINVAL;
goto exit;
}
+
if (priority < PRIORITY_MIN)
priority = PRIORITY_MIN;
else if (priority > PRIORITY_TOP)
gpointer data)
{
int type = POWER_OFF_NONE;
- int ret;
+ int ret, level;
struct timespec time = {0,};
g_variant_get(param, "(i)", &type);
if (!g_handle)
haptic_internal_init();
+ if (vconf_get_int(VCONFKEY_SETAPPL_NOTI_VIBRATION_LEVEL_INT, &level) < 0) {
+ _E("Failed to get '"VCONFKEY_SETAPPL_NOTI_VIBRATION_LEVEL_INT"' vconf value.");
+ return;
+ }
+ level = (level/2) + 1;
+
/* power off vibration */
- _I("Handle=%d dur=%dms pri=%d level=%d",
- g_handle, POWER_OFF_VIB_DURATION, PRIORITY_HIGH, POWER_VIB_FEEDBACK);
- ret = h_ops->vibrate_monotone(g_handle, POWER_OFF_VIB_DURATION,
- POWER_VIB_FEEDBACK, PRIORITY_HIGH);
+ _I("Handle=%d dur=%dms pri=%d level=%d intensity=%d frequency=%d",
+ g_handle, POWER_OFF_VIB_DURATION, PRIORITY_HIGH, level,
+ POWER_VIB_FEEDBACK * 100, haptic_default_data.frequency);
+ ret = h_ops->vibrate_monotone(g_handle, POWER_OFF_VIB_DURATION, haptic_default_data.frequency, 0,
+ level, POWER_VIB_FEEDBACK * 100, PRIORITY_HIGH);
if (ret < 0) {
_E("Failed to vibrate_monotone: %d", ret);
return;
#define MAX_DATA 16
#define FF_INFO_MAGIC 0xDEADFEED
+#define SET_OVERDRIVE_BIT(x,value) (x |= ((value > 0)? 1: 0)<<14)
+#define SET_LEVEL_BIT(x,value) (x |= (value<<13))
+
struct ff_info_header {
unsigned int magic;
int iteration;
_D("'%s' type: rumble", ev_path);
if (test_bit(FF_RUMBLE, features)) {
- memcpy(ff_path, ev_path, strlen(ev_path));
- ff_path[strlen(ev_path)] = '\0';
+ memcpy(ff_path, ev_path, strlen(ev_path)+1);
close(fd);
closedir(dir);
return 0;
if (!effect)
return -EINVAL;
- /*Only rumble supported as of now*/
effect->type = FF_RUMBLE;
effect->replay.length = 0;
effect->replay.delay = 0;
effect->id = -1;
effect->u.rumble.strong_magnitude = 0;
+ effect->u.rumble.weak_magnitude = 0;
return 0;
}
-static int ff_set_effect(struct ff_effect *effect, int length, int level)
+static int ff_set_effect(struct ff_effect *effect, int duration, int level, int intensity, int frequency, int overdrive)
{
- double magnitude;
-
if (!effect) {
_E("There is no valid effect.");
return -EINVAL;
}
- magnitude = (double)level/HAPTIC_MODULE_FEEDBACK_MAX;
- magnitude *= RUMBLE_MAX_MAGNITUDE;
+ /*
+ __u16 strong_magnitude; // strong_magnitude[15:15] = 0 (Reserved)
+ // strong_magnitude[14:14] = Overdrive : 0 (Off) or 1 (On)
+ // strong_magnitude[13:0] = Intensity Value : 0 (Stop) or 1 ~ 10000 (Intensity)
+ __u16 weak_magnitude; // weak_magnitude[15:13] = Intensity Level : 1 ~ 5
+ // weak_magnitude[12:0] = Frequency : 0 ~ 8191 (0 ~ 819.1 Hz)
+ */
+
+ effect->u.rumble.strong_magnitude = intensity;
+ SET_OVERDRIVE_BIT(effect->u.rumble.strong_magnitude, overdrive);
- _I("magnitude=%d length=%d", (int)magnitude, length);
+ effect->u.rumble.weak_magnitude = frequency;
+ SET_LEVEL_BIT(effect->u.rumble.weak_magnitude, level);
/* set member variables in effect struct */
- effect->u.rumble.strong_magnitude = (int)magnitude;
- effect->replay.length = length; /* length millisecond */
+ effect->replay.length = duration; /* length millisecond */
+ //_D("rumble data: strong_magnitude = 0x%x, weak_magnitude = 0x%x", effect->u.rumble.strong_magnitude, effect->u.rumble.weak_magnitude);
return 0;
}
return 0;
}
-static int vibrate_monotone(int device_handle, int duration, int feedback, int priority)
+static int vibrate_monotone(int device_handle, int duration, int frequency, int overdrive, int level, int intensity, int priority)
{
struct ff_info *info;
int ret;
info = read_from_list(device_handle);
if (!info) {
- _E("Handle %d failed to check list", device_handle);
+ _E("Handle %d failed to check list.", device_handle);
return -EINVAL;
}
if (!check_valid_handle(info)) {
- _E("Handle %d failed to check handle", device_handle);
+ _E("Handle %d failed to check handle.", device_handle);
return -EINVAL;
}
return -ENODEV;
if (duration <= 0) {
- _I("Handle %d skip requests with duration 0", device_handle);
+ _I("Handle %d skip requests with duration 0.", device_handle);
return 0;
}
/* set effect as per arguments */
ff_init_effect(&info->effect);
- ret = ff_set_effect(&info->effect, duration, feedback);
+ ret = ff_set_effect(&info->effect, duration, level, intensity, frequency, overdrive);
if (ret < 0) {
- _E("Handle %d fail to set effect(duration:%d, feedback:%d) : %d",
- device_handle, duration, feedback, ret);
+ _E("Handle %d fail to set effect(duration:%d, level:%d, intensity:%d, frequency:%d, overdrive:%d) : %d",
+ device_handle, duration, level, intensity, frequency, overdrive, ret);
return ret;
}