/* 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); }
/* 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); }