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);
}
示例#2
0
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;

}
示例#3
0
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;
}
示例#4
0
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);
}
示例#6
0
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;
}
示例#8
0
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;
}
示例#9
0
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);
}
示例#12
0
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);
}
示例#13
0
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();
	}
}