| #if !defined(CONFIG_INPUT_BOOSTER) // Input Booster + |
| #ifndef _INPUT_BOOSTER_H_ |
| #define _INPUT_BOOSTER_H_ |
| |
| #include <linux/pm_qos.h> |
| #include <linux/of.h> |
| #include <linux/ems_service.h> |
| |
| #ifdef CONFIG_SCHED_HMP |
| #define USE_HMP_BOOST |
| #elif defined CONFIG_SCHED_EMS |
| #define USE_EHMP_BOOST |
| #endif |
| |
| #define pr_booster(format, ...) { \ |
| if (debug_flag) \ |
| printk(format, ## __VA_ARGS__); \ |
| } |
| |
| #define MAX_MULTI_TOUCH_EVENTS 3 |
| #define MAX_EVENTS (MAX_MULTI_TOUCH_EVENTS * 10) |
| |
| #define INPUT_BOOSTER_NULL 0 |
| #define INIT_ZERO 0 |
| |
| #define HEADGAGE "******" |
| #define TAILGAGE "**** " |
| |
| #define set_qos(req, pm_qos_class, value) { \ |
| if (value) { \ |
| if (pm_qos_request_active(req)) {\ |
| pr_booster("[Input Booster2] %s pm_qos_update_request : %d\n", glGage, value); \ |
| pm_qos_update_request(req, value); \ |
| } else { \ |
| pr_booster("[Input Booster2] %s pm_qos_add_request : %d\n", glGage, value); \ |
| pm_qos_add_request(req, pm_qos_class, value); \ |
| } \ |
| } else { \ |
| pr_booster("[Input Booster2] %s remove_qos\n", glGage); \ |
| remove_qos(req); \ |
| } \ |
| } |
| |
| #define set_qos_dma_latency(req, pm_qos_class, value) { \ |
| if(!value){ \ |
| if (pm_qos_request_active(req)) {\ |
| pr_booster("[Input Booster2] %s pm_qos_dma_latency_update_request : %d\n", glGage, value); \ |
| pm_qos_update_request(req, value); \ |
| } else { \ |
| pr_booster("[Input Booster2] %s pm_qos_dma_latency_add_request : %d\n", glGage, value); \ |
| pm_qos_add_request(req, pm_qos_class, value); \ |
| } \ |
| } else { \ |
| pr_booster("[Input Booster2] %s remove_qos_dma_latency\n", glGage); \ |
| remove_qos(req); \ |
| } \ |
| } |
| |
| #define remove_qos(req) { \ |
| if (pm_qos_request_active(req)) \ |
| pm_qos_remove_request(req); \ |
| } |
| |
| #ifdef USE_HMP_BOOST |
| #define set_hmp(enable) { \ |
| if (enable != current_hmp_boost) { \ |
| pr_booster("[Input Booster2] ****** set_hmp : %d ( %s )\n", enable, __FUNCTION__); \ |
| if (set_hmp_boost(enable) < 0) { \ |
| pr_booster("[Input Booster2] ****** !!! fail to HMP !!!\n"); \ |
| } \ |
| current_hmp_boost = enable; \ |
| } \ |
| } |
| #elif defined USE_EHMP_BOOST |
| #include <linux/ems.h> |
| |
| static DEFINE_MUTEX(input_lock); |
| int hmp_boost_value = INIT_ZERO; |
| |
| static struct kpp kpp_ta; |
| static struct kpp kpp_fg; |
| |
| #define set_hmp(enable) { \ |
| mutex_lock(&input_lock); \ |
| if (enable != current_hmp_boost) { \ |
| if (hmp_boost_value <= 0 && !enable) { \ |
| pr_booster("[Input Booster2] ****** ERROR : set_ehmp unexpected disable request happened ( %s )\n", __FUNCTION__); \ |
| } else if (hmp_boost_value >= 1 && enable) { \ |
| pr_booster("[Input Booster2] ****** ERROR : set_ehmp unexpected enable request happened ( %s )\n", __FUNCTION__); \ |
| } else { \ |
| pr_booster("[Input Booster2] ****** set_ehmp : %d ( %s )\n", enable, __FUNCTION__); \ |
| if (enable) { \ |
| hmp_boost_value++; \ |
| kpp_request(STUNE_TOPAPP, &kpp_ta, 1); \ |
| kpp_request(STUNE_FOREGROUND, &kpp_fg, 1); \ |
| } else { \ |
| hmp_boost_value--; \ |
| kpp_request(STUNE_TOPAPP, &kpp_ta, 0); \ |
| kpp_request(STUNE_FOREGROUND, &kpp_fg, 0); \ |
| } \ |
| current_hmp_boost = enable; \ |
| } \ |
| } \ |
| mutex_unlock(&input_lock); \ |
| } |
| #else |
| #define set_hmp(enable) |
| #endif |
| |
| #if defined(CONFIG_ARCH_EXYNOS) //______________________________________________________________________________ |
| #define SET_BOOSTER { \ |
| int value = INPUT_BOOSTER_NULL; \ |
| _this->level++; \ |
| MAX_T_INPUT_BOOSTER(value, hmp_boost); \ |
| if (value == INPUT_BOOSTER_NULL) { \ |
| value = 0; \ |
| } \ |
| set_hmp(value); \ |
| set_qos(&_this->cpu_qos, PM_QOS_CLUSTER1_FREQ_MIN/*PM_QOS_CPU_FREQ_MIN*/, _this->param[_this->index].cpu_freq); \ |
| set_qos(&_this->kfc_qos, PM_QOS_CLUSTER0_FREQ_MIN/*PM_QOS_KFC_FREQ_MIN*/, _this->param[_this->index].kfc_freq); \ |
| set_qos(&_this->mif_qos, PM_QOS_BUS_THROUGHPUT, _this->param[_this->index].mif_freq); \ |
| set_qos(&_this->int_qos, PM_QOS_DEVICE_THROUGHPUT, _this->param[_this->index].int_freq); \ |
| set_qos_dma_latency(&_this->dms_latency_qos, PM_QOS_CPU_DMA_LATENCY, _this->param[_this->index].dma_latency); \ |
| } |
| #define REMOVE_BOOSTER { \ |
| int value = INPUT_BOOSTER_NULL; \ |
| _this->level = -1; \ |
| MAX_T_INPUT_BOOSTER(value, hmp_boost); \ |
| if (value == INPUT_BOOSTER_NULL) { \ |
| value = 0; \ |
| } \ |
| set_hmp(value); \ |
| remove_qos(&_this->cpu_qos); \ |
| remove_qos(&_this->kfc_qos); \ |
| remove_qos(&_this->mif_qos); \ |
| remove_qos(&_this->int_qos); \ |
| remove_qos(&_this->dms_latency_qos); \ |
| } |
| #define PROPERTY_BOOSTER(_device_param_, _dt_param_, _time_) { \ |
| _device_param_.cpu_freq = _dt_param_.cpu_freq; \ |
| _device_param_.kfc_freq = _dt_param_.kfc_freq; \ |
| _device_param_.mif_freq = _dt_param_.mif_freq; \ |
| _device_param_.int_freq = _dt_param_.int_freq; \ |
| _device_param_.time = _dt_param_._time_; \ |
| _device_param_.hmp_boost = _dt_param_.hmp_boost; \ |
| _device_param_.dma_latency = _dt_param_.dma_latency; \ |
| } |
| #endif //______________________________________________________________________________ |
| #define GET_BOOSTER_PARAM(_GENDER_, _HEAD_PARAM_, _TAIL_PARAM_) { \ |
| int levels[][3] = { \ |
| {1, 2, 0}, \ |
| {2, 2, 3}, \ |
| {3, 1, 1}, \ |
| {4, 1, 2} }; \ |
| int j, k; \ |
| for (j = 0; j < (int)(sizeof(levels)/(3*sizeof(int))); j++) {\ |
| if ((_GENDER_->pDT->nlevels > 2 && levels[j][0] == _GENDER_->level) || (_GENDER_->pDT->nlevels == 1 && j == 2) || (_GENDER_->pDT->nlevels == 2 && j == 3)) { \ |
| if (levels[j][1] > 0) { \ |
| for (k = 0; k < _GENDER_->pDT->nlevels; k++) { \ |
| if (levels[j][1] == _GENDER_->pDT->param_tables[k].ilevels) { \ |
| _HEAD_PARAM_ = (_GENDER_->pDT->param_tables[k].head_time > 0) ? &_GENDER_->pDT->param_tables[k] : NULL; \ |
| break; \ |
| } \ |
| } \ |
| } \ |
| if (levels[j][2] > 0) { \ |
| for (k = 0; k < dt_gender->pDT->nlevels; k++) { \ |
| if (levels[j][2] == dt_gender->pDT->param_tables[k].ilevels) { \ |
| _TAIL_PARAM_ = &_GENDER_->pDT->param_tables[k]; \ |
| break; \ |
| } \ |
| } \ |
| } \ |
| break; \ |
| } \ |
| } \ |
| } |
| #define CHANGE_BOOSTER { \ |
| struct t_input_booster_device_tree_param *head_param = NULL, *tail_param = NULL; \ |
| GET_BOOSTER_PARAM(dt_gender, head_param, tail_param) \ |
| memset(dt_gender->pBooster->param, 0x00, sizeof(struct t_input_booster_param)*2); \ |
| if (head_param != NULL) { \ |
| PROPERTY_BOOSTER(dt_gender->pBooster->param[0], (*head_param), head_time) \ |
| } \ |
| if (tail_param != NULL) { \ |
| PROPERTY_BOOSTER(dt_gender->pBooster->param[1], (*tail_param), tail_time) \ |
| } \ |
| } |
| |
| #define INIT_BOOSTER(_DEVICE_) { \ |
| _DEVICE_##_booster.input_booster_state = input_booster_idle_state; \ |
| INIT_DELAYED_WORK(&_DEVICE_##_booster.input_booster_timeout_work[0], TIMEOUT_FUNC(_DEVICE_)); \ |
| INIT_DELAYED_WORK(&_DEVICE_##_booster.input_booster_timeout_work[1], TIMEOUT_FUNC(_DEVICE_)); \ |
| INIT_WORK(&_DEVICE_##_booster.input_booster_set_booster_work, SET_BOOSTER_FUNC(_DEVICE_)); \ |
| INIT_WORK(&_DEVICE_##_booster.input_booster_reset_booster_work, RESET_BOOSTER_FUNC(_DEVICE_)); \ |
| mutex_init(&_DEVICE_##_booster.lock); \ |
| _DEVICE_##_booster.change_on_release = 0; \ |
| _DEVICE_##_booster.multi_events = 0; \ |
| { \ |
| int i; \ |
| for (i = 0; i < sizeof(_DEVICE_##_booster.param)/sizeof(struct t_input_booster_param); i++) { \ |
| _DEVICE_##_booster.level = -1; \ |
| } \ |
| for (i = 0; i < ndevice_in_dt; i++) { \ |
| if (device_tree_infor[i].type == _DEVICE_##_booster_dt.type) { \ |
| struct t_input_booster_device_tree_gender *dt_gender = &_DEVICE_##_booster_dt; \ |
| dt_gender->pDT = &device_tree_infor[i]; \ |
| dt_gender->pBooster = &_DEVICE_##_booster; \ |
| CHANGE_BOOSTER \ |
| break; \ |
| } \ |
| } \ |
| } \ |
| } |
| |
| #define TIMEOUT_FUNC(_DEVICE_) input_booster_##_DEVICE_##_timeout_work_func |
| |
| #define DECLARE_TIMEOUT_FUNC(_DEVICE_) \ |
| static void input_booster_##_DEVICE_##_timeout_work_func(struct work_struct *work) \ |
| { \ |
| struct t_input_booster *_this = &_DEVICE_##_booster; \ |
| int param_max = sizeof(_this->param)/sizeof(struct t_input_booster_param), temp_index = -1; \ |
| mutex_lock(&_this->lock); \ |
| pr_booster("[Input Booster] %s Timeout : changed index : %d (%s)\n", HEADGAGE, _this->index, __FUNCTION__); \ |
| if (_this->index >= 2 && delayed_work_pending(&_this->input_booster_timeout_work[_this->index-2])) { \ |
| mutex_unlock(&_this->lock); \ |
| return; \ |
| } \ |
| if (_this->index == param_max && delayed_work_pending(&_this->input_booster_timeout_work[_this->index-1])) { \ |
| temp_index = _this->index; \ |
| _this->index = (_this->index) ? _this->index-1 : 0; \ |
| } \ |
| pr_booster("[Input Booster] %s Timeout : changed index : %d (%s)\n", HEADGAGE, _this->index, __FUNCTION__); \ |
| if (_this->index < param_max) { \ |
| pr_booster("[Input Booster] %s Timeout : changed index : %d, time : %d (%s)\n", HEADGAGE, _this->index, _this->param[_this->index].time, __FUNCTION__); \ |
| pr_booster("[Input Booster] %s hmp : %d dma_latency : %d cpu : %d (%s)\n", TAILGAGE, _this->param[_this->index].hmp_boost, _this->param[_this->index].dma_latency, _this->param[_this->index].cpu_freq, __FUNCTION__); \ |
| if (_this->param[(_this->index) ? _this->index-1 : 0].time > 0) { \ |
| SET_BOOSTER; \ |
| if (_this->change_on_release) { \ |
| schedule_delayed_work(&_this->input_booster_timeout_work[_this->index], msecs_to_jiffies(_this->param[_this->index].time)); \ |
| _this->index++; \ |
| CHANGE_STATE_TO(idle); \ |
| } \ |
| } \ |
| _this->index = (temp_index >= 0) ? temp_index : _this->index; \ |
| } else { \ |
| pr_booster("[Input Booster] Timeout : completed param_max : %d (%s)\n", param_max, __FUNCTION__); \ |
| pr_booster("[Input Booster]\n"); \ |
| REMOVE_BOOSTER; \ |
| _this->index = 0; \ |
| _this->multi_events = (_this->multi_events > 0) ? 0 : _this->multi_events; \ |
| CHANGE_STATE_TO(idle); \ |
| } \ |
| mutex_unlock(&_this->lock); \ |
| } |
| |
| #define SET_BOOSTER_FUNC(_DEVICE_) input_booster_##_DEVICE_##_set_booster_work_func |
| |
| #define DECLARE_SET_BOOSTER_FUNC(_DEVICE_) \ |
| static void input_booster_##_DEVICE_##_set_booster_work_func(struct work_struct *work) \ |
| { \ |
| struct t_input_booster *_this = (struct t_input_booster *)(&_DEVICE_##_booster); \ |
| mutex_lock(&_this->lock); \ |
| _this->input_booster_state(_this, _this->event_type); \ |
| mutex_unlock(&_this->lock); \ |
| } |
| |
| #define RESET_BOOSTER_FUNC(_DEVICE_) input_booster_##_DEVICE_##_reset_booster_work_func |
| |
| #define DECLARE_RESET_BOOSTER_FUNC(_DEVICE_) \ |
| static void input_booster_##_DEVICE_##_reset_booster_work_func(struct work_struct *work) \ |
| { \ |
| struct t_input_booster *_this = (struct t_input_booster *)(&_DEVICE_##_booster); \ |
| int i; \ |
| mutex_lock(&_this->lock); \ |
| _this->multi_events = 0; \ |
| _this->index = 0; \ |
| for (i = 0; i < 2; i++) { \ |
| if (delayed_work_pending(&_this->input_booster_timeout_work[i])) { \ |
| pr_booster("[Input Booster] **** cancel the pending workqueue for reset\n"); \ |
| cancel_delayed_work(&_this->input_booster_timeout_work[i]); \ |
| } \ |
| } \ |
| CHANGE_STATE_TO(idle); \ |
| REMOVE_BOOSTER; \ |
| mutex_unlock(&_this->lock); \ |
| } |
| |
| #define DECLARE_STATE_FUNC(_STATE_) void input_booster_##_STATE_##_state(void *__this, int input_booster_event) |
| |
| #define CHANGE_STATE_TO(_STATE_) {_this->input_booster_state = input_booster_##_STATE_##_state; } |
| |
| #define RUN_BOOSTER(_DEVICE_, _EVENT_) { \ |
| if (_DEVICE_##_booster_dt.level > 0) { \ |
| _DEVICE_##_booster.event_type = _EVENT_; \ |
| (_EVENT_ == BOOSTER_ON) ? _DEVICE_##_booster.multi_events++ : _DEVICE_##_booster.multi_events--; \ |
| schedule_work(&_DEVICE_##_booster.input_booster_set_booster_work); \ |
| } \ |
| } |
| |
| //+++++++++++++++++++++++++++++++++++++++++++++++ STRUCT & VARIABLE FOR SYSFS +++++++++++++++++++++++++++++++++++++++++++++++// |
| #define SYSFS_CLASS(_ATTR_, _ARGU_, _COUNT_) \ |
| static ssize_t input_booster_sysfs_class_show_##_ATTR_(struct class *dev, struct class_attribute *attr, char *buf) \ |
| { \ |
| struct t_input_booster_device_tree_gender *dt_gender = &touch_booster_dt; \ |
| ssize_t ret; int level; \ |
| unsigned int debug_level = 0, cpu_freq = 0, kfc_freq = 0, mif_freq = 0, int_freq = 0, hmp_boost = 0, dma_latency = 0, head_time = 0, tail_time = 0; \ |
| struct t_input_booster_device_tree_param *head_param = NULL, *tail_param = NULL; \ |
| GET_BOOSTER_PARAM(dt_gender, head_param, tail_param) \ |
| debug_level = debug_flag; \ |
| level = dt_gender->level; \ |
| if (strcmp(#_ATTR_, "head") == 0 && head_param != NULL) { \ |
| cpu_freq = head_param->cpu_freq; \ |
| kfc_freq = head_param->kfc_freq; \ |
| mif_freq = head_param->mif_freq; \ |
| int_freq = head_param->int_freq; \ |
| hmp_boost = head_param->hmp_boost; \ |
| dma_latency = head_param->dma_latency; \ |
| head_time = head_param->head_time; \ |
| tail_time = head_param->tail_time; \ |
| } \ |
| if (strcmp(#_ATTR_, "tail") == 0 && tail_param != NULL) { \ |
| cpu_freq = tail_param->cpu_freq; \ |
| kfc_freq = tail_param->kfc_freq; \ |
| mif_freq = tail_param->mif_freq; \ |
| int_freq = tail_param->int_freq; \ |
| hmp_boost = tail_param->hmp_boost; \ |
| dma_latency = tail_param->dma_latency; \ |
| head_time = tail_param->head_time; \ |
| tail_time = tail_param->tail_time; \ |
| } \ |
| ret = sprintf _ARGU_; \ |
| pr_booster("[Input Booster8] %s buf : %s\n", __FUNCTION__, buf); \ |
| return ret; \ |
| } \ |
| static ssize_t input_booster_sysfs_class_store_##_ATTR_(struct class *dev, struct class_attribute *attr, const char *buf, size_t count) \ |
| { \ |
| struct t_input_booster_device_tree_gender *dt_gender = &touch_booster_dt; \ |
| int level[1] = {-1}, len; \ |
| unsigned int debug_level[1] = {-1}, cpu_freq[1] = {-1}, kfc_freq[1] = {-1}, mif_freq[1] = {-1}, int_freq[1] = {-1}, hmp_boost[1] = {-1}, dma_latency[1] = {-1}, head_time[1] = {-1}, tail_time[1] = {-1}; \ |
| struct t_input_booster_device_tree_param *head_param = NULL, *tail_param = NULL; \ |
| GET_BOOSTER_PARAM(dt_gender, head_param, tail_param) \ |
| len = sscanf _ARGU_; \ |
| pr_booster("[Input Booster8] %s buf : %s\n", __FUNCTION__, buf); \ |
| if (sscanf _ARGU_ != _COUNT_) { \ |
| return count; \ |
| } \ |
| debug_flag = (*debug_level == (unsigned int)(-1)) ? debug_flag : *debug_level; \ |
| dt_gender->level = (*level == (unsigned int)(-1)) ? dt_gender->level : *level; \ |
| if (*head_time != (unsigned int)(-1) && head_param != NULL) { \ |
| head_param->cpu_freq = (*cpu_freq == (unsigned int)(-1)) ? head_param->cpu_freq : *cpu_freq; \ |
| head_param->kfc_freq = (*kfc_freq == (unsigned int)(-1)) ? head_param->kfc_freq : *kfc_freq; \ |
| head_param->mif_freq = (*mif_freq == (unsigned int)(-1)) ? head_param->mif_freq : *mif_freq; \ |
| head_param->int_freq = (*int_freq == (unsigned int)(-1)) ? head_param->int_freq : *int_freq; \ |
| head_param->hmp_boost = (*hmp_boost == (unsigned int)(-1)) ? head_param->hmp_boost : *hmp_boost; \ |
| head_param->dma_latency = (*dma_latency == (unsigned int)(-1)) ? head_param->dma_latency : *dma_latency; \ |
| head_param->head_time = (*head_time == (unsigned int)(-1)) ? head_param->head_time : *head_time; \ |
| head_param->tail_time = (*tail_time == (unsigned int)(-1)) ? head_param->tail_time : *tail_time; \ |
| } \ |
| if (*tail_time != (unsigned int)(-1) && tail_param != NULL) { \ |
| tail_param->cpu_freq = (*cpu_freq == (unsigned int)(-1)) ? tail_param->cpu_freq : *cpu_freq; \ |
| tail_param->kfc_freq = (*kfc_freq == (unsigned int)(-1)) ? tail_param->kfc_freq : *kfc_freq; \ |
| tail_param->mif_freq = (*mif_freq == (unsigned int)(-1)) ? tail_param->mif_freq : *mif_freq; \ |
| tail_param->int_freq = (*int_freq == (unsigned int)(-1)) ? tail_param->int_freq : *int_freq; \ |
| tail_param->hmp_boost = (*hmp_boost == (unsigned int)(-1)) ? tail_param->hmp_boost : *hmp_boost; \ |
| tail_param->dma_latency = (*dma_latency == (unsigned int)(-1)) ? tail_param->dma_latency : *dma_latency; \ |
| tail_param->head_time = (*head_time == (unsigned int)(-1)) ? tail_param->head_time : *head_time; \ |
| tail_param->tail_time = (*tail_time == (unsigned int)(-1)) ? tail_param->tail_time : *tail_time; \ |
| } \ |
| CHANGE_BOOSTER \ |
| return count; \ |
| } \ |
| static struct class_attribute class_attr_##_ATTR_ = __ATTR(_ATTR_, S_IRUGO | S_IWUSR, input_booster_sysfs_class_show_##_ATTR_, input_booster_sysfs_class_store_##_ATTR_); |
| #define SYSFS_DEVICE(_ATTR_, _ARGU_, _COUNT_) \ |
| static ssize_t input_booster_sysfs_device_show_##_ATTR_(struct device *dev, struct device_attribute *attr, char *buf) \ |
| { \ |
| struct t_input_booster_device_tree_gender *dt_gender = dev_get_drvdata(dev); \ |
| ssize_t ret = 0; \ |
| int level, Arg_count = _COUNT_; \ |
| unsigned int cpu_freq, kfc_freq, mif_freq, int_freq, hmp_boost, dma_latency, head_time, tail_time, phase_time; \ |
| struct t_input_booster_device_tree_param *head_param = NULL, *tail_param = NULL; \ |
| if (dt_gender == NULL) { \ |
| return ret; \ |
| } \ |
| GET_BOOSTER_PARAM(dt_gender, head_param, tail_param) \ |
| if (Arg_count == 1) { \ |
| level = dt_gender->level; \ |
| ret = sprintf _ARGU_; \ |
| pr_booster("[Input Booster8] %s buf : %s\n", __FUNCTION__, buf); \ |
| } else { \ |
| if (head_param != NULL) { \ |
| level = head_param->ilevels; \ |
| cpu_freq = head_param->cpu_freq; \ |
| kfc_freq = head_param->kfc_freq; \ |
| mif_freq = head_param->mif_freq; \ |
| int_freq = head_param->int_freq; \ |
| hmp_boost = head_param->hmp_boost; \ |
| dma_latency = head_param->dma_latency; \ |
| head_time = head_param->head_time; \ |
| tail_time = head_param->tail_time; \ |
| phase_time = head_param->phase_time; \ |
| ret = sprintf _ARGU_; \ |
| buf = buf + ret - 1; \ |
| } \ |
| *buf = '|'; \ |
| *(buf+1) = '\n';\ |
| if (tail_param != NULL) { \ |
| buf = buf + 1; \ |
| level = tail_param->ilevels; \ |
| cpu_freq = tail_param->cpu_freq; \ |
| kfc_freq = tail_param->kfc_freq; \ |
| mif_freq = tail_param->mif_freq; \ |
| int_freq = tail_param->int_freq; \ |
| hmp_boost = tail_param->hmp_boost; \ |
| dma_latency = tail_param->dma_latency; \ |
| head_time = tail_param->head_time; \ |
| tail_time = tail_param->tail_time; \ |
| phase_time = tail_param->phase_time; \ |
| ret += sprintf _ARGU_; \ |
| } \ |
| pr_booster("[Input Booster8] %s buf : %s\n", __FUNCTION__, buf); \ |
| } \ |
| return ret; \ |
| } \ |
| static ssize_t input_booster_sysfs_device_store_##_ATTR_(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \ |
| { \ |
| struct t_input_booster_device_tree_gender *dt_gender = dev_get_drvdata(dev); \ |
| struct t_input_booster_device_tree_infor *dt_infor = (dt_gender) ? dt_gender->pDT : NULL; \ |
| int level[1] = {-1}, len; \ |
| unsigned int cpu_freq[1] = {-1}, kfc_freq[1] = {-1}, mif_freq[1] = {-1}, int_freq[1] = {-1}, hmp_boost[1] = {-1}, dma_latency[1] = {-1}, head_time[1] = {-1}, tail_time[1] = {-1}, phase_time[1] = {-1}; \ |
| len = sscanf _ARGU_; \ |
| pr_booster("[Input Booster8] %s buf : %s\n", __FUNCTION__, buf); \ |
| if (dt_infor == NULL) { \ |
| return count; \ |
| } \ |
| if (len != _COUNT_) { \ |
| pr_booster("### Keep this format : [level cpu_freq kfc_freq mif_freq int_freq hmp_boost dma_latency] (Ex: 1 1600000 0 1500000 667000 333000 1###\n"); \ |
| pr_booster("### Keep this format : [level head_time tail_time phase_time] (Ex: 1 130 500 50 ###\n"); \ |
| pr_booster("### Keep this format : [type value] (Ex: 2 1 ###\n"); \ |
| return count; \ |
| } \ |
| if (level[0] >= 0) { \ |
| int Arg_count = _COUNT_; \ |
| if (Arg_count == 1) { \ |
| dt_gender->level = level[0]; \ |
| } else { \ |
| int k; \ |
| for (k = 0; k < dt_infor->nlevels; k++) { \ |
| if (level[0] == dt_infor->param_tables[k].ilevels) { \ |
| dt_infor->param_tables[k].cpu_freq = (*cpu_freq == (unsigned int)(-1)) ? dt_infor->param_tables[k].cpu_freq : *cpu_freq; \ |
| dt_infor->param_tables[k].kfc_freq = (*kfc_freq == (unsigned int)(-1)) ? dt_infor->param_tables[k].kfc_freq : *kfc_freq; \ |
| dt_infor->param_tables[k].mif_freq = (*mif_freq == (unsigned int)(-1)) ? dt_infor->param_tables[k].mif_freq : *mif_freq; \ |
| dt_infor->param_tables[k].int_freq = (*int_freq == (unsigned int)(-1)) ? dt_infor->param_tables[k].int_freq : *int_freq; \ |
| dt_infor->param_tables[k].hmp_boost = (*hmp_boost == (unsigned int)(-1)) ? dt_infor->param_tables[k].hmp_boost : *hmp_boost; \ |
| dt_infor->param_tables[k].dma_latency = (*dma_latency == (unsigned int)(-1)) ? dt_infor->param_tables[k].dma_latency : *dma_latency; \ |
| dt_infor->param_tables[k].head_time = (*head_time == (unsigned int)(-1)) ? dt_infor->param_tables[k].head_time : *head_time; \ |
| dt_infor->param_tables[k].tail_time = (*tail_time == (unsigned int)(-1)) ? dt_infor->param_tables[k].tail_time : *tail_time; \ |
| dt_infor->param_tables[k].phase_time = (*phase_time == (unsigned int)(-1)) ? dt_infor->param_tables[k].phase_time : *phase_time; \ |
| pr_booster("[Input Booster8] %s time : %d %d %d\n", __FUNCTION__, dt_infor->param_tables[*level].head_time, dt_infor->param_tables[k].tail_time, dt_infor->param_tables[*level].phase_time); \ |
| } \ |
| } \ |
| } \ |
| CHANGE_BOOSTER \ |
| } \ |
| return count; \ |
| } \ |
| static DEVICE_ATTR(_ATTR_, S_IRUGO | S_IWUSR, input_booster_sysfs_device_show_##_ATTR_, input_booster_sysfs_device_store_##_ATTR_); |
| #define INIT_SYSFS_CLASS(_CLASS_) { \ |
| int ret = class_create_file(sysfs_class, &class_attr_##_CLASS_); \ |
| if (ret) { \ |
| pr_booster("[Input Booster] Failed to create class\n"); \ |
| class_destroy(sysfs_class); \ |
| return; \ |
| } \ |
| } |
| #define INIT_SYSFS_DEVICE(_DEVICE_) { \ |
| struct device *sysfs_dev; int ret = 0;\ |
| sysfs_dev = device_create(sysfs_class, NULL, 0, &_DEVICE_##_booster_dt, #_DEVICE_); \ |
| if (IS_ERR(sysfs_dev)) { \ |
| ret = IS_ERR(sysfs_dev); \ |
| pr_booster("[Input Booster] Failed to create %s sysfs device[%d]\n", #_DEVICE_, ret); \ |
| return; \ |
| } \ |
| ret = sysfs_create_group(&sysfs_dev->kobj, &dvfs_attr_group); \ |
| if (ret) { \ |
| pr_booster("[Input Booster] Failed to create %s sysfs group\n", #_DEVICE_); \ |
| return; \ |
| } \ |
| } |
| //----------------------------------------------- STRUCT & VARIABLE FOR SYSFS -----------------------------------------------// |
| |
| enum booster_mode_on_off { |
| BOOSTER_OFF = 0, |
| BOOSTER_ON, |
| }; |
| |
| |
| struct input_value input_events[MAX_EVENTS+1]; |
| |
| struct t_input_booster_param { |
| u32 cpu_freq; |
| u32 kfc_freq; |
| u32 mif_freq; |
| u32 int_freq; |
| |
| u16 time; |
| |
| u8 hmp_boost; |
| u32 dma_latency; |
| u8 dummy; |
| }; |
| |
| struct t_input_booster { |
| struct mutex lock; |
| struct t_input_booster_param param[2]; |
| |
| struct pm_qos_request cpu_qos; |
| struct pm_qos_request kfc_qos; |
| struct pm_qos_request mif_qos; |
| struct pm_qos_request int_qos; |
| struct pm_qos_request dms_latency_qos; |
| |
| struct delayed_work input_booster_timeout_work[2]; |
| struct work_struct input_booster_set_booster_work; |
| struct work_struct input_booster_reset_booster_work; |
| |
| int index; |
| int multi_events; |
| int event_type; |
| int change_on_release; |
| int level; |
| |
| void (*input_booster_state)(void *__this, int input_booster_event); |
| }; |
| |
| //+++++++++++++++++++++++++++++++++++++++++++++++ STRUCT & VARIABLE FOR DEVICE TREE +++++++++++++++++++++++++++++++++++++++++++++++// |
| struct t_input_booster_device_tree_param { |
| u8 ilevels; |
| |
| u8 hmp_boost; |
| u32 dma_latency; |
| |
| u16 head_time; |
| u16 tail_time; |
| u16 phase_time; |
| |
| u32 cpu_freq; |
| u32 kfc_freq; |
| u32 mif_freq; |
| u32 int_freq; |
| }; |
| |
| struct t_input_booster_device_tree_infor { |
| const char *label; |
| int type; |
| int nlevels; |
| |
| struct t_input_booster_device_tree_param *param_tables; |
| }; |
| |
| struct t_input_booster_device_tree_gender { |
| int type; |
| int level; |
| struct t_input_booster *pBooster; |
| struct t_input_booster_device_tree_infor *pDT; |
| }; |
| |
| //______________________________________________________________________________ <<< in DTSI file >>> |
| //______________________________________________________________________________ input_booster,type = <4>; /* BOOSTER_DEVICE_KEYBOARD */ |
| //______________________________________________________________________________ |
| struct t_input_booster_device_tree_gender key_booster_dt = {0, 1,}; // type : 0, level : 1 |
| struct t_input_booster_device_tree_gender touchkey_booster_dt = {1, 1,}; // type : 1, level : 1 |
| struct t_input_booster_device_tree_gender touch_booster_dt = {2, 2,}; // type : 2, level : 2 |
| struct t_input_booster_device_tree_gender multitouch_booster_dt = {3, 1,}; // type : 3, level : 1 |
| struct t_input_booster_device_tree_gender keyboard_booster_dt = {4, 1,}; // type : 4, level : 1 |
| struct t_input_booster_device_tree_gender mouse_booster_dt = {5, 1,}; // type : 5, level : 1 |
| struct t_input_booster_device_tree_gender mouse_wheel_booster_dt = {6, 1,}; // type : 6, level : 1 |
| struct t_input_booster_device_tree_gender hover_booster_dt = {7, 1,}; // type : 7, level : 1 |
| struct t_input_booster_device_tree_gender pen_booster_dt = {8, 1,}; // type : 8, level : 1 |
| struct t_input_booster_device_tree_gender key_two_booster_dt = {9, 1,}; // type : 9, level : 1 |
| struct t_input_booster_device_tree_infor *device_tree_infor; |
| |
| int ndevice_in_dt; |
| //---------------------------------------------- STRUCT & VARIABLE FOR DEVICE TREE ----------------------------------------------// |
| |
| //+++++++++++++++++++++++++++++++++++++++++++++++ STRUCT & VARIABLE FOR SYSFS +++++++++++++++++++++++++++++++++++++++++++++++// |
| unsigned int debug_flag = INIT_ZERO; |
| |
| SYSFS_CLASS(debug_level, (buf, "%u\n", debug_level), 1) |
| SYSFS_CLASS(head, (buf, "%d %u %u %u %u %u %u\n", head_time, cpu_freq, kfc_freq, mif_freq, int_freq, hmp_boost, dma_latency), 7) |
| SYSFS_CLASS(tail, (buf, "%d %u %u %u %u %u %u\n", tail_time, cpu_freq, kfc_freq, mif_freq, int_freq, hmp_boost, dma_latency), 7) |
| SYSFS_CLASS(level, (buf, "%d\n", level), 1) |
| SYSFS_DEVICE(level, (buf, "%d\n", level), 1) |
| SYSFS_DEVICE(freq, (buf, "%d %u %u %u %u %u %u\n", level, cpu_freq, kfc_freq, mif_freq, int_freq, hmp_boost, dma_latency), 7) |
| SYSFS_DEVICE(time, (buf, "%d %u %u %u\n", level, head_time, tail_time, phase_time), 4) |
| static ssize_t input_booster_sysfs_device_store_control(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
| { |
| struct t_input_booster_device_tree_gender *dt_gender = dev_get_drvdata(dev); |
| struct t_input_booster *dt_booster = (dt_gender) ? dt_gender->pBooster : NULL; |
| int value; |
| unsigned int type; |
| |
| if (dt_booster == NULL) { |
| return count; |
| } |
| if (sscanf(buf, "%u %d", &type, &value) != 2) { |
| pr_booster("### Keep this format : [type value] (Ex: 2 1 ###\n"); |
| return count; |
| } |
| dt_booster->event_type = value; |
| schedule_work(&dt_booster->input_booster_set_booster_work); |
| |
| return count; |
| } |
| static DEVICE_ATTR(control, S_IRUGO | S_IWUSR, NULL, input_booster_sysfs_device_store_control); |
| |
| static struct attribute *dvfs_attributes[] = { |
| &dev_attr_level.attr, |
| &dev_attr_freq.attr, |
| &dev_attr_time.attr, |
| &dev_attr_control.attr, |
| NULL, |
| }; |
| |
| static struct attribute_group dvfs_attr_group = { |
| .attrs = dvfs_attributes, |
| }; |
| |
| //---------------------------------------------- STRUCT & VARIABLE FOR SYSFS ----------------------------------------------// |
| |
| int TouchIDs[MAX_MULTI_TOUCH_EVENTS]; |
| char *glGage = HEADGAGE; |
| bool current_hmp_boost = INIT_ZERO; |
| |
| struct t_input_booster touch_booster; |
| struct t_input_booster multitouch_booster; |
| struct t_input_booster key_booster; |
| struct t_input_booster touchkey_booster; |
| struct t_input_booster keyboard_booster; |
| struct t_input_booster mouse_booster; |
| struct t_input_booster mouse_wheel_booster; |
| struct t_input_booster pen_booster; |
| struct t_input_booster hover_booster; |
| struct t_input_booster key_two_booster; |
| |
| struct t_input_booster *t_input_boosters[] = { |
| &touch_booster, |
| &multitouch_booster, |
| &key_booster, |
| &touchkey_booster, |
| &keyboard_booster, |
| &mouse_booster, |
| &mouse_wheel_booster, |
| &pen_booster, |
| &hover_booster, |
| &key_two_booster |
| }; |
| |
| #define MAX_T_INPUT_BOOSTER(ref, _PARAM_) { \ |
| size_t i = 0; \ |
| int max = INPUT_BOOSTER_NULL; \ |
| for (i = 0; i < sizeof(t_input_boosters)/sizeof(struct t_input_booster *); i++) { \ |
| if (t_input_boosters[i]->level >= 0 && t_input_boosters[i]->level < (int)(sizeof(t_input_boosters[i]->param)/sizeof(struct t_input_booster_param))) { \ |
| pr_booster("[Input Booster3] %s booster type : %lu level : %d value : %d\n", #_PARAM_, i, t_input_boosters[i]->level, t_input_boosters[i]->param[t_input_boosters[i]->level]._PARAM_); \ |
| if (max < (int)(t_input_boosters[i]->param[t_input_boosters[i]->level]._PARAM_)) { \ |
| max = (int)(t_input_boosters[i]->param[t_input_boosters[i]->level]._PARAM_); \ |
| } \ |
| } \ |
| } \ |
| if (max == INPUT_BOOSTER_NULL) { \ |
| ref = INPUT_BOOSTER_NULL; \ |
| } else { \ |
| ref = max; \ |
| } \ |
| pr_booster("[Input Booster3] %s max value : %d\n", #_PARAM_, max); \ |
| } \ |
| |
| int input_count = 0, key_back = 0, key_home = 0, key_recent = 0; |
| |
| void input_booster_idle_state(void *__this, int input_booster_event); |
| void input_booster_press_state(void *__this, int input_booster_event); |
| void input_booster(struct input_dev *dev); |
| void input_booster_init(void); |
| #endif |
| #endif // Input Booster - |
| |
| |
| |