static int check_key_down(struct sci_keypad_t *sci_kpd, int key_status, int key_value)
{
	int col, row, key;
	unsigned short *keycodes = sci_kpd->input_dev->keycode;
	unsigned int row_shift = get_count_order(sci_kpd->cols);

	if((key_status & 0xff) != 0) {
		col = KPD_INT0_COL(key_status);
		row = KPD_INT0_ROW(key_status);
		key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)];
		if(key == key_value)
			return 1;
	}
	if((key_status & 0xff00) != 0) {
		col = KPD_INT1_COL(key_status);
		row = KPD_INT1_ROW(key_status);
		key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)];
		if(key == key_value)
			return 1;
	}
	return 0;
}
Beispiel #2
0
static irqreturn_t sci_keypad_isr(int irq, void *dev_id)
{
	unsigned short key = 0;
	unsigned long value;
	struct sci_keypad_t *sci_kpd = dev_id;
	unsigned long int_status = __raw_readl(KPD_INT_MASK_STATUS);
	unsigned long key_status = __raw_readl(KPD_KEY_STATUS);
	unsigned short *keycodes = sci_kpd->input_dev->keycode;
	unsigned int row_shift = get_count_order(sci_kpd->cols);
	int col, row;


	value = __raw_readl(KPD_INT_CLR);
	value |= KPD_INT_ALL;
	__raw_writel(value, KPD_INT_CLR);
	if ((int_status & KPD_PRESS_INT0)) {
		col = KPD_INT0_COL(key_status);
		row = KPD_INT0_ROW(key_status);
		key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)];

#if PRINT_KEY_LOG
		printk("%03dD\n", key);
#endif
		input_report_key(sci_kpd->input_dev, key, 1);
		input_sync(sci_kpd->input_dev);
	}
	if (int_status & KPD_RELEASE_INT0) {
		col = KPD_INT0_COL(key_status);
		row = KPD_INT0_ROW(key_status);
		key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)];

#if PRINT_KEY_LOG
		printk("%03dU\n", key);
#endif
		input_report_key(sci_kpd->input_dev, key, 0);
		input_sync(sci_kpd->input_dev);
	}

	if ((int_status & KPD_PRESS_INT1)) {
		col = KPD_INT1_COL(key_status);
		row = KPD_INT1_ROW(key_status);
		key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)];

#if PRINT_KEY_LOG
		printk("%03dD\n", key);
#endif
		input_report_key(sci_kpd->input_dev, key, 1);
		input_sync(sci_kpd->input_dev);
	}
	if (int_status & KPD_RELEASE_INT1) {
		col = KPD_INT1_COL(key_status);
		row = KPD_INT1_ROW(key_status);
		key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)];

#if PRINT_KEY_LOG
		printk("%03dU\n", key);
#endif
		input_report_key(sci_kpd->input_dev, key, 0);
		input_sync(sci_kpd->input_dev);
	}

	if ((int_status & KPD_PRESS_INT2)) {
		col = KPD_INT2_COL(key_status);
		row = KPD_INT2_ROW(key_status);
		key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)];

#if PRINT_KEY_LOG
		printk("%03d\n", key);
#endif
		input_report_key(sci_kpd->input_dev, key, 1);
		input_sync(sci_kpd->input_dev);
	}
	if (int_status & KPD_RELEASE_INT2) {
		col = KPD_INT2_COL(key_status);
		row = KPD_INT2_ROW(key_status);
		key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)];

#if PRINT_KEY_LOG
		printk("%03d\n", key);
#endif
		input_report_key(sci_kpd->input_dev, key, 0);
		input_sync(sci_kpd->input_dev);
	}

	if (int_status & KPD_PRESS_INT3) {
		col = KPD_INT3_COL(key_status);
		row = KPD_INT3_ROW(key_status);
		key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)];

#if PRINT_KEY_LOG
		printk("%03d\n", key);
#endif
		input_report_key(sci_kpd->input_dev, key, 1);
		input_sync(sci_kpd->input_dev);
	}
	if (int_status & KPD_RELEASE_INT3) {
		col = KPD_INT3_COL(key_status);
		row = KPD_INT3_ROW(key_status);
		key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)];

#if PRINT_KEY_LOG
		printk("%03d\n", key);
#endif
		input_report_key(sci_kpd->input_dev, key, 0);
		input_sync(sci_kpd->input_dev);
	}

	return IRQ_HANDLED;
}
static irqreturn_t sci_keypad_isr(int irq, void *dev_id)
{
	unsigned short key = 0;
	unsigned long value;
	struct sci_keypad_t *sci_kpd = dev_id;
	unsigned long int_status = keypad_readl(KPD_INT_MASK_STATUS);
	unsigned long key_status = keypad_readl(KPD_KEY_STATUS);
	unsigned short *keycodes = sci_kpd->input_dev->keycode;
	unsigned int row_shift = get_count_order(sci_kpd->cols);
	int col, row;

	value = keypad_readl(KPD_INT_CLR);
	value |= KPD_INT_ALL;
	keypad_writel(KPD_INT_CLR, value);

	if ((int_status & KPD_PRESS_INT0)) {
		col = KPD_INT0_COL(key_status);
		row = KPD_INT0_ROW(key_status);
		key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)];
		input_report_key(sci_kpd->input_dev, key, 1);
		input_sync(sci_kpd->input_dev);
		printk("%03dD\n", key);
	}
	if (int_status & KPD_RELEASE_INT0) {
		col = KPD_INT0_COL(key_status);
		row = KPD_INT0_ROW(key_status);
		key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)];

		input_report_key(sci_kpd->input_dev, key, 0);
		input_sync(sci_kpd->input_dev);
		printk("%03dU\n", key);
	}

	if ((int_status & KPD_PRESS_INT1)) {
		col = KPD_INT1_COL(key_status);
		row = KPD_INT1_ROW(key_status);
		key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)];

		input_report_key(sci_kpd->input_dev, key, 1);
		input_sync(sci_kpd->input_dev);
		printk("%03dD\n", key);
	}
	if (int_status & KPD_RELEASE_INT1) {
		col = KPD_INT1_COL(key_status);
		row = KPD_INT1_ROW(key_status);
		key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)];

		input_report_key(sci_kpd->input_dev, key, 0);
		input_sync(sci_kpd->input_dev);
		printk("%03dU\n", key);
	}

	if ((int_status & KPD_PRESS_INT2)) {
		col = KPD_INT2_COL(key_status);
		row = KPD_INT2_ROW(key_status);
		key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)];

		input_report_key(sci_kpd->input_dev, key, 1);
		input_sync(sci_kpd->input_dev);
		printk("%03d\n", key);
	}
	if (int_status & KPD_RELEASE_INT2) {
		col = KPD_INT2_COL(key_status);
		row = KPD_INT2_ROW(key_status);
		key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)];

		input_report_key(sci_kpd->input_dev, key, 0);
		input_sync(sci_kpd->input_dev);
		printk("%03d\n", key);
	}

	if (int_status & KPD_PRESS_INT3) {
		col = KPD_INT3_COL(key_status);
		row = KPD_INT3_ROW(key_status);
		key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)];

		input_report_key(sci_kpd->input_dev, key, 1);
		input_sync(sci_kpd->input_dev);
		printk("%03d\n", key);
	}
	if (int_status & KPD_RELEASE_INT3) {
		col = KPD_INT3_COL(key_status);
		row = KPD_INT3_ROW(key_status);
		key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)];

		input_report_key(sci_kpd->input_dev, key, 0);
		input_sync(sci_kpd->input_dev);
		printk("%03d\n", key);
	}

#ifdef CONFIG_MAGIC_SYSRQ
	{
		static unsigned long key_status_prev = 0;

		if (check_key_down(sci_kpd, key_status, SPRD_CAMERA_KEY) &&
			check_key_down(sci_kpd, key_status, SPRD_VOL_DOWN_KEY) && key_status != key_status_prev) {
			key_status_prev = key_status;
			panic("!!!! Combine key: vol_down + camera !!!!\n");
		}

		if (check_key_down(sci_kpd, key_status, SPRD_CAMERA_KEY) &&
			check_key_down(sci_kpd, key_status, SPRD_VOL_UP_KEY) && key_status != key_status_prev) {
			unsigned long flags;
			static int rebooted = 0;
			key_status_prev = key_status;
			local_irq_save(flags);
			if (rebooted == 0) {
				rebooted = 1;
				pr_warn("!!!!!! Combine Key : vol_up + camera is Down !!!!!!\n");
				/* handle_sysrq('t'); */
				handle_sysrq('m');
				handle_sysrq('w');
				handle_sysrq('b');
				pr_warn("!!!!!! /proc/sys/kernel/sysrq is disabled !!!!!!\n");
				rebooted = 0;
			}
			local_irq_restore(flags);
		}
	}
#endif
	return IRQ_HANDLED;
}
Beispiel #4
0
static irqreturn_t sci_keypad_isr(int irq, void *dev_id)
{
    unsigned short key = 0;
    unsigned long value;
    struct sci_keypad_t *sci_kpd = dev_id;
    unsigned long int_status = __raw_readl(KPD_INT_MASK_STATUS);
    unsigned long key_status = __raw_readl(KPD_KEY_STATUS);
    unsigned short *keycodes = sci_kpd->input_dev->keycode;
    unsigned int row_shift = get_count_order(sci_kpd->cols);
    int col, row;

    value = __raw_readl(KPD_INT_CLR);
    value |= KPD_INT_ALL;
    __raw_writel(value, KPD_INT_CLR);

    if ((int_status & KPD_PRESS_INT0)) {
        col = KPD_INT0_COL(key_status);
        row = KPD_INT0_ROW(key_status);
        key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)];
        input_report_key(sci_kpd->input_dev, key, 1);
        input_sync(sci_kpd->input_dev);
        printk("%03dD\n", key);
    }
    if (int_status & KPD_RELEASE_INT0) {
        col = KPD_INT0_COL(key_status);
        row = KPD_INT0_ROW(key_status);
        key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)];

        input_report_key(sci_kpd->input_dev, key, 0);
        input_sync(sci_kpd->input_dev);
        printk("%03dU\n", key);
    }

    if ((int_status & KPD_PRESS_INT1)) {
        col = KPD_INT1_COL(key_status);
        row = KPD_INT1_ROW(key_status);
        key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)];

        input_report_key(sci_kpd->input_dev, key, 1);
        input_sync(sci_kpd->input_dev);
        printk("%03dD\n", key);
    }
    if (int_status & KPD_RELEASE_INT1) {
        col = KPD_INT1_COL(key_status);
        row = KPD_INT1_ROW(key_status);
        key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)];

        input_report_key(sci_kpd->input_dev, key, 0);
        input_sync(sci_kpd->input_dev);
        printk("%03dU\n", key);
    }

    if ((int_status & KPD_PRESS_INT2)) {
        col = KPD_INT2_COL(key_status);
        row = KPD_INT2_ROW(key_status);
        key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)];

        input_report_key(sci_kpd->input_dev, key, 1);
        input_sync(sci_kpd->input_dev);
        printk("%03d\n", key);
    }
    if (int_status & KPD_RELEASE_INT2) {
        col = KPD_INT2_COL(key_status);
        row = KPD_INT2_ROW(key_status);
        key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)];

        input_report_key(sci_kpd->input_dev, key, 0);
        input_sync(sci_kpd->input_dev);
        printk("%03d\n", key);
    }

    if (int_status & KPD_PRESS_INT3) {
        col = KPD_INT3_COL(key_status);
        row = KPD_INT3_ROW(key_status);
        key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)];

        input_report_key(sci_kpd->input_dev, key, 1);
        input_sync(sci_kpd->input_dev);
        printk("%03d\n", key);
    }
    if (int_status & KPD_RELEASE_INT3) {
        col = KPD_INT3_COL(key_status);
        row = KPD_INT3_ROW(key_status);
        key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)];

        input_report_key(sci_kpd->input_dev, key, 0);
        input_sync(sci_kpd->input_dev);
        printk("%03d\n", key);
    }

#ifdef CONFIG_MAGIC_SYSRQ
    {
        static unsigned long key_status_prev = 0;
        static unsigned long key_panic_check_times = 0;
        struct task_struct *g, *p;
        int i;

        if (check_key_down(sci_kpd, key_status, SPRD_CAMERA_KEY) &&
                check_key_down(sci_kpd, key_status, SPRD_VOL_DOWN_KEY) && key_status != key_status_prev) {
            if(!key_panic_check_times) {
                printk("!!!! Combine key: vol_down + camera !!!! first dump important task\n");
                printk("current\n");
                printk("PID %d is %s\n",task_pid_nr(current),current->comm);
                show_stack(current,NULL);
                do_each_thread(g, p) {
                    for(i=0; i<(sizeof(tasks)/sizeof(tasks[0])); i++) {
                        if (!strncmp(p->comm,tasks[i].name,tasks[i].name_len)) {
                            printk("PID %d is %s\n",task_pid_nr(p),p->comm);
                            show_stack(p, NULL);
                        }
                    }
                }
                while_each_thread(g, p);
            }  else {

            }
            key_panic_check_times++;
        }