/* Scan the hardware keyboard and push any changes up through the input layer */
static void tosakbd_scankeyboard(struct platform_device *dev)
{
	struct tosakbd *tosakbd = platform_get_drvdata(dev);
	unsigned int row, col, rowd;
	unsigned long flags;
	unsigned int num_pressed = 0;

	spin_lock_irqsave(&tosakbd->lock, flags);

	if (tosakbd->suspended)
		goto out;

	for (col = 0; col < TOSA_KEY_STROBE_NUM; col++) {
		/*
		 * Discharge the output driver capacitatance
		 * in the keyboard matrix. (Yes it is significant..)
		 */
		tosakbd_discharge_all();
		udelay(KB_DISCHARGE_DELAY);

		tosakbd_activate_col(col);
		udelay(KB_ACTIVATE_DELAY);

		rowd = GET_ROWS_STATUS(col);

		for (row = 0; row < TOSA_KEY_SENSE_NUM; row++) {
			unsigned int scancode, pressed;
			scancode = SCANCODE(row, col);
			pressed = rowd & KB_ROWMASK(row);

			if (pressed && !tosakbd->keycode[scancode])
				dev_warn(&dev->dev,
						"unhandled scancode: 0x%02x\n",
						scancode);

			input_report_key(tosakbd->input,
					tosakbd->keycode[scancode],
					pressed);
			if (pressed)
				num_pressed++;
		}

		tosakbd_reset_col(col);
	}

	tosakbd_activate_all();

	input_sync(tosakbd->input);

	/* if any keys are pressed, enable the timer */
	if (num_pressed)
		mod_timer(&tosakbd->timer, jiffies + SCAN_INTERVAL);

 out:
	spin_unlock_irqrestore(&tosakbd->lock, flags);
}
/* Scan the hardware keyboard and push any changes up through the input layer */
static void corgikbd_scankeyboard(struct corgikbd *corgikbd_data)
{
	unsigned int row, col, rowd;
	unsigned long flags;
	unsigned int num_pressed;

	if (corgikbd_data->suspended)
		return;

	spin_lock_irqsave(&corgikbd_data->lock, flags);

	num_pressed = 0;
	for (col = 0; col < KB_COLS; col++) {
		/*
		 * Discharge the output driver capacitatance
		 * in the keyboard matrix. (Yes it is significant..)
		 */

		corgikbd_discharge_all();
		udelay(KB_DISCHARGE_DELAY);

		corgikbd_activate_col(col);
		udelay(KB_ACTIVATE_DELAY);

		rowd = GET_ROWS_STATUS(col);
		for (row = 0; row < KB_ROWS; row++) {
			unsigned int scancode, pressed;

			scancode = SCANCODE(row, col);
			pressed = rowd & KB_ROWMASK(row);

			input_report_key(corgikbd_data->input, corgikbd_data->keycode[scancode], pressed);

			if (pressed)
				num_pressed++;

			if (pressed && (corgikbd_data->keycode[scancode] == CORGI_KEY_OFF)
					&& time_after(jiffies, corgikbd_data->suspend_jiffies + HZ)) {
				input_event(corgikbd_data->input, EV_PWR, CORGI_KEY_OFF, 1);
				corgikbd_data->suspend_jiffies=jiffies;
			}
		}
		corgikbd_reset_col(col);
	}

	corgikbd_activate_all();

	input_sync(corgikbd_data->input);

	/* if any keys are pressed, enable the timer */
	if (num_pressed)
		mod_timer(&corgikbd_data->timer, jiffies + msecs_to_jiffies(SCAN_INTERVAL));

	spin_unlock_irqrestore(&corgikbd_data->lock, flags);
}
示例#3
0
文件: locomokbd.c 项目: 020gzh/linux
/* Scan the hardware keyboard and push any changes up through the input layer */
static void locomokbd_scankeyboard(struct locomokbd *locomokbd)
{
	unsigned int row, col, rowd;
	unsigned long flags;
	unsigned int num_pressed;
	unsigned long membase = locomokbd->base;

	spin_lock_irqsave(&locomokbd->lock, flags);

	locomokbd_charge_all(membase);

	num_pressed = 0;
	for (col = 0; col < KB_COLS; col++) {

		locomokbd_activate_col(membase, col);
		udelay(KB_DELAY);

		rowd = ~locomo_readl(membase + LOCOMO_KIB);
		for (row = 0; row < KB_ROWS; row++) {
			unsigned int scancode, pressed, key;

			scancode = SCANCODE(col, row);
			pressed = rowd & KB_ROWMASK(row);
			key = locomokbd->keycode[scancode];

			input_report_key(locomokbd->input, key, pressed);
			if (likely(!pressed))
				continue;

			num_pressed++;

			/* The "Cancel/ESC" key is labeled "On/Off" on
			 * Collie and Poodle and should suspend the device
			 * if it was pressed for more than a second. */
			if (unlikely(key == KEY_ESC)) {
				if (!time_after(jiffies,
					locomokbd->suspend_jiffies + HZ))
					continue;
				if (locomokbd->count_cancel++
					!= (HZ/SCAN_INTERVAL + 1))
					continue;
				input_event(locomokbd->input, EV_PWR,
					KEY_SUSPEND, 1);
				locomokbd->suspend_jiffies = jiffies;
			} else
				locomokbd->count_cancel = 0;
		}
		locomokbd_reset_col(membase, col);
	}
	locomokbd_activate_all(membase);

	input_sync(locomokbd->input);

	/* if any keys are pressed, enable the timer */
	if (num_pressed)
		mod_timer(&locomokbd->timer, jiffies + SCAN_INTERVAL);
	else
		locomokbd->count_cancel = 0;

	spin_unlock_irqrestore(&locomokbd->lock, flags);
}