void ssbi_keypad_init(struct qwerty_keypad_info *qwerty_kp) { unsigned int mach_id; int len; len = sizeof(struct gpio_qwerty_kp); qwerty_keypad = malloc(len); ASSERT(qwerty_keypad); memset(qwerty_keypad, 0, len); qwerty_keypad->keypad_info = qwerty_kp; event_init(&qwerty_keypad->full_scan, false, EVENT_FLAG_AUTOUNSIGNAL); timer_initialize(&qwerty_keypad->timer); mach_id = board_machtype(); ssbi_gpio_init(mach_id); if(mach_id == LINUX_MACHTYPE_8660_QT) { mdelay((qwerty_keypad->keypad_info)->settle_time); #ifdef QT_8660_KEYPAD_HW_BUG timer_set_oneshot(&qwerty_keypad->timer, 0, scan_qt_keypad, NULL); #endif } else timer_set_oneshot(&qwerty_keypad->timer, 0, scan_qwerty_keypad, NULL); /* wait for the keypad to complete one full scan */ event_wait(&qwerty_keypad->full_scan); }
static enum handler_return scan_qwerty_keypad(struct timer *timer, time_t now, void *arg) { unsigned int rows = (qwerty_keypad->keypad_info)->rows; unsigned int columns = (qwerty_keypad->keypad_info)->columns; unsigned int num_of_ssbi_reads = (qwerty_keypad->keypad_info)->num_of_reads; read_func rd_function = (qwerty_keypad->keypad_info)->rd_func; unsigned char column_new_keys = 0x00; unsigned char column_old_keys = 0x00; int shift = 0; static int key_detected = -1; if ((*rd_function)((qwerty_keypad->keypad_info)->rec_keys, num_of_ssbi_reads, SSBI_REG_KYPD_REC_DATA_ADDR)) dprintf (CRITICAL, "Error in initializing SSBI_REG_KYPD_CNTL register\n"); if ((*rd_function)((qwerty_keypad->keypad_info)->old_keys, num_of_ssbi_reads, SSBI_REG_KYPD_OLD_DATA_ADDR)) dprintf (CRITICAL, "Error in initializing SSBI_REG_KYPD_CNTL register\n"); while (rows--) { columns = qwerty_keypad->keypad_info->columns; if (((qwerty_keypad->keypad_info)->rec_keys[rows] != (qwerty_keypad->keypad_info)->old_keys[rows]) && ((qwerty_keypad->keypad_info)->rec_keys[rows] != 0x00) && ((qwerty_keypad->keypad_info)->old_keys[rows] != 0x00)) { while (columns--) { column_new_keys = ((qwerty_keypad->keypad_info)->rec_keys[rows]); column_old_keys = ((qwerty_keypad->keypad_info)->old_keys[rows]); if (((0x01 << columns) & (~column_new_keys)) && !((0x01 << columns) & (~column_old_keys))) { shift = (rows * 8) + columns; if ((qwerty_keypad->keypad_info)->keymap[shift]) { if (shift != key_detected) { key_detected = shift; keys_post_event((qwerty_keypad->keypad_info)->keymap[shift], 1); event_signal(&qwerty_keypad->full_scan, false); timer_set_oneshot(timer, (qwerty_keypad->keypad_info)->poll_time, scan_qwerty_keypad, NULL); return INT_RESCHEDULE; } } } } } } if (qwerty_keypad->num_of_scans < 10) { (qwerty_keypad->num_of_scans)++; timer_set_oneshot(timer, (qwerty_keypad->keypad_info)->settle_time, scan_qwerty_keypad, NULL); return INT_RESCHEDULE; } event_signal(&qwerty_keypad->full_scan, false); return INT_RESCHEDULE; }
static enum handler_return gpio_keypad_timer_func(struct timer *timer, time_t now, void *arg) { struct gpio_kp *kp = keypad; struct gpio_keypad_info *kpinfo = kp->keypad_info; int polarity = !!(kpinfo->flags & GPIOKPF_ACTIVE_HIGH); int out; int gpio; out = kp->current_output; if (out == kpinfo->noutputs) { out = 0; kp->some_keys_pressed = 0; } else { check_output(kp, out, polarity); out++; } kp->current_output = out; if (out < kpinfo->noutputs) { gpio = kpinfo->output_gpios[out]; if (kpinfo->flags & GPIOKPF_DRIVE_INACTIVE) gpio_set(gpio, polarity); else gpio_config(gpio, polarity ? GPIO_OUTPUT : 0); timer_set_oneshot(timer, kpinfo->settle_time, gpio_keypad_timer_func, NULL); goto done; } if (/*!kp->use_irq*/ 1 || kp->some_keys_pressed) { event_signal(&kp->full_scan, false); timer_set_oneshot(timer, kpinfo->poll_time, gpio_keypad_timer_func, NULL); goto done; } #if 0 /* No keys are pressed, reenable interrupt */ for (out = 0; out < kpinfo->noutputs; out++) { if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE) gpio_set(kpinfo->output_gpios[out], polarity); else gpio_config(kpinfo->output_gpios[out], polarity ? GPIO_OUTPUT : 0); } for (in = 0; in < kpinfo->ninputs; in++) enable_irq(gpio_to_irq(kpinfo->input_gpios[in])); return INT_RESCHEDULE; #endif done: return INT_RESCHEDULE; }
void gpio_keypad_init(struct gpio_keypad_info *kpinfo) { int key_count; int output_val; int output_cfg; int i; int len; ASSERT(kpinfo->keymap && kpinfo->input_gpios && kpinfo->output_gpios); key_count = kpinfo->ninputs * kpinfo->noutputs; len = sizeof(struct gpio_kp) + (sizeof(unsigned long) * BITMAP_NUM_WORDS(key_count)); keypad = malloc(len); ASSERT(keypad); memset(keypad, 0, len); keypad->keypad_info = kpinfo; output_val = (!!(kpinfo->flags & GPIOKPF_ACTIVE_HIGH))^(!!(kpinfo->flags & GPIOKPF_DRIVE_INACTIVE)); output_cfg = kpinfo->flags & GPIOKPF_DRIVE_INACTIVE ? GPIO_OUTPUT : 0; for (i = 0; i < kpinfo->noutputs; i++) { gpio_set(kpinfo->output_gpios[i], output_val); gpio_config(kpinfo->output_gpios[i], output_cfg); } for (i = 0; i < kpinfo->ninputs; i++) { gpio_config(kpinfo->input_gpios[i], GPIO_INPUT); } keypad->current_output = kpinfo->noutputs; timer_initialize(&keypad->timer); timer_set_oneshot(&keypad->timer, 0, gpio_keypad_timer_func, NULL); }
/* * Function to turn on vibrator. * vibrate_time - the time of phone vibrate. */ void vib_timed_turn_on(const uint32_t vibrate_time) { vib_turn_on(); vib_timeout=0; timer_initialize(&vib_timer); timer_set_oneshot(&vib_timer, vibrate_time, vib_timer_func, NULL); }
static enum handler_return threadload(struct timer *t, time_t now, void *arg) { static struct thread_stats old_stats; static bigtime_t last_idle_time; timer_set_oneshot(t, 1000, &threadload, NULL); bigtime_t idle_time = thread_stats.idle_time; if (current_thread == idle_thread) { idle_time += current_time_hires() - thread_stats.last_idle_timestamp; } bigtime_t busy_time = 1000000ULL - (idle_time - last_idle_time); uint busypercent = (busy_time * 10000) / (1000000); // printf("idle_time %lld, busytime %lld\n", idle_time - last_idle_time, busy_time); printf("LOAD: %d.%02d%%, cs %d, ints %d, timer ints %d, timers %d\n", busypercent / 100, busypercent % 100, thread_stats.context_switches - old_stats.context_switches, thread_stats.interrupts - old_stats.interrupts, thread_stats.timer_ints - old_stats.timer_ints, thread_stats.timers - old_stats.timers); old_stats = thread_stats; last_idle_time = idle_time; return INT_NO_RESCHEDULE; }
/* * Main timer handle: check every PWRKEY_DETECT_FREQUENCY to see * if power key is pressed. * Shutdown the device if power key is release before * (PWRKEY_LONG_PRESS_COUNT/MPM_SLEEP_TIMETICK_COUNT) seconds. */ static enum handler_return long_press_pwrkey_timer_func(struct timer *p_timer, void *arg) { uint32_t sclk_count = platform_get_sclk_count(); /* * The following condition is treated as the power key * is pressed long enough. * 1. if the power key is pressed last for PWRKEY_LONG_PRESS_COUNT. */ if (sclk_count > PWRKEY_LONG_PRESS_COUNT) { timer_cancel(p_timer); pon_timer_complete = 1; } else { if (pm8x41_get_pwrkey_is_pressed()) { /* * For normal man response is > 0.1 secs, so we use 0.05 secs default * for software to be safely detect if there is a key release action. */ timer_set_oneshot(p_timer, PWRKEY_DETECT_FREQUENCY, long_press_pwrkey_timer_func, NULL); } else { shutdown_device(); } } return INT_RESCHEDULE; }
static enum handler_return gpio_keys_poll_fn(struct timer *timer, time_t now, void *arg) { uint32_t i = 0; struct gpio_key *key = pdata->gpio_key; for(; ((i < pdata->nr_keys) && (key != NULL)); i++, key++) { int changed = 0; if (gpio_get(key->gpio_nr) ^ !!key->polarity) { changed = !bitmap_set(&gpio_keys_bitmap, i); } else { changed = bitmap_clear(&gpio_keys_bitmap, i); } if (changed) { int state = bitmap_test(&gpio_keys_bitmap, i); keys_post_event(key->key_code, state); if (key->notify_fn) { key->notify_fn(key->key_code, state); } if(state) { some_key_pressed++; } else if(some_key_pressed) { some_key_pressed--; } } } if (some_key_pressed) { timer_set_oneshot(timer, pdata->debounce_time, gpio_keys_poll_fn, NULL); } else { timer_set_oneshot(timer, pdata->poll_time, gpio_keys_poll_fn, NULL); } return 1; }
static enum handler_return gpio_keypad_timer_func(struct timer *timer, time_t now, void *arg) { struct gpio_kp *kp = keypad; struct gpio_keypad_info *kpinfo = kp->keypad_info; int polarity = ! !(kpinfo->flags & GPIOKPF_ACTIVE_HIGH); int out; int gpio; out = kp->current_output; if (out == kpinfo->noutputs) { out = 0; kp->some_keys_pressed = 0; } else { check_output(kp, out, polarity); out++; } kp->current_output = out; if (out < kpinfo->noutputs) { gpio = kpinfo->output_gpios[out]; if (kpinfo->flags & GPIOKPF_DRIVE_INACTIVE) { gpio_set(gpio, polarity); } else { gpio_config(gpio, polarity ? GPIO_OUTPUT : 0); } timer_set_oneshot(timer, kpinfo->settle_time, gpio_keypad_timer_func, NULL); goto done; } /*else*/ if (kp->some_keys_pressed || 1) { timer_set_oneshot(timer, kpinfo->poll_time, gpio_keypad_timer_func, NULL); goto done; } done: return INT_RESCHEDULE; }
static enum handler_return scan_qt_keypad(struct timer *timer, time_t now, void *arg) { unsigned int gpio; unsigned int last_state=0; unsigned int new_state=0; unsigned int bits_changed; static int key_detected=-1; /* Row GPIOs 8,9,10 are used for sensing here */ for (gpio=8;gpio<=10;gpio++) { bool status; status = pm8058_gpio_get(gpio); if (status == 0) new_state |= (1<<(gpio-8)); } bits_changed = last_state ^ new_state; if (bits_changed) { int shift = 0; for (unsigned int rows = 0; rows < (qwerty_keypad->keypad_info)->rows; rows++) { if ((bits_changed & (1<<rows)) == 0) continue; shift = rows * 8 + 3; } if ((qwerty_keypad->keypad_info)->keymap[shift]) { if (shift != key_detected) { key_detected = shift; keys_post_event((qwerty_keypad->keypad_info)->keymap[shift], 1); timer_set_oneshot(timer,(qwerty_keypad->keypad_info)->poll_time, scan_qt_keypad, NULL); return INT_RESCHEDULE; } } } event_signal(&qwerty_keypad->full_scan, false); return INT_RESCHEDULE; }
void ssbi_gpio_keypad_init(struct qwerty_keypad_info *qwerty_kp) { int len; len = sizeof(struct gpio_qwerty_kp); qwerty_keypad = malloc(len); ASSERT(qwerty_keypad); memset(qwerty_keypad, 0, len); qwerty_keypad->keypad_info = qwerty_kp; event_init(&qwerty_keypad->full_scan, false, EVENT_FLAG_AUTOUNSIGNAL); timer_initialize(&qwerty_keypad->timer); timer_set_oneshot(&qwerty_keypad->timer, 0, scan_qwerty_gpio_keypad, NULL); /* wait for the keypad to complete one full scan */ event_wait(&qwerty_keypad->full_scan); }
void gpio_keys_init(struct gpio_keys_pdata *kpdata) { if(kpdata == NULL) { printf("FAILED: platform data is NULL!\n"); return; } else if (pdata != NULL) { printf("FAILED: platform data is set already!\n"); return; } else if (!kpdata->nr_keys || (!(kpdata->nr_keys < BITMAP_BITS_PER_WORD)) ) { printf("WARN: %d keys not supported, First 32 keys will be served.\n", (unsigned)kpdata->nr_keys); kpdata->nr_keys = 32; } pdata = kpdata; some_key_pressed = 0; memset(&gpio_keys_bitmap, 0, sizeof(unsigned long)); timer_initialize(&gpio_keys_poll); timer_set_oneshot(&gpio_keys_poll, 0, gpio_keys_poll_fn, NULL); }
static int cmd_threadload(int argc, const cmd_args * argv) { static bool showthreadload = false; static timer_t tltimer; enter_critical_section(); if (showthreadload == false) { // start the display timer_initialize(&tltimer); timer_set_oneshot(&tltimer, 1000, &threadload, NULL); showthreadload = true; } else { timer_cancel(&tltimer); showthreadload = false; } exit_critical_section(); return 0; }
/* * Function to support for shutdown detection * If below condition is met, the function will shut down * the device. Otherwise it will do nothing and return to * normal boot. * condition: * 1. it is triggered by power key && * 2. the power key is released before * (PWRKEY_LONG_PRESS_COUNT/MPM_SLEEP_TIMETICK_COUNT) seconds. */ void shutdown_detect() { /* * If it is booted by power key tirigger. * Initialize pon_timer and call long_press_pwrkey_timer_func * function to check if the power key is last press long enough. */ if (is_pwrkey_pon_reason() && is_pwrkey_time_expired()) { timer_initialize(&pon_timer); timer_set_oneshot(&pon_timer, 0, long_press_pwrkey_timer_func, NULL); /* * Wait until long press power key timeout * * It will be confused to end users if we shutdown the device * after the splash screen displayed. But it can be moved the * wait here if the boot time is much more considered. */ wait_for_long_pwrkey_pressed(); } }