Exemple #1
0
static void tegra_kbc_report_keys(struct tegra_kbc *kbc)
{
	unsigned char scancodes[KBC_MAX_KPENT];
	unsigned short keycodes[KBC_MAX_KPENT];
	u32 val = 0;
	unsigned int i;
	unsigned int num_down = 0;
	bool fn_keypress = false;
	bool key_in_same_row = false;
	bool key_in_same_col = false;

	for (i = 0; i < KBC_MAX_KPENT; i++) {
		if ((i % 4) == 0)
			val = readl(kbc->mmio + KBC_KP_ENT0_0 + i);

		if (val & 0x80) {
			unsigned int col = val & 0x07;
			unsigned int row = (val >> 3) & 0x0f;
			unsigned char scancode =
				MATRIX_SCAN_CODE(row, col, KBC_ROW_SHIFT);

			scancodes[num_down] = scancode;
			keycodes[num_down] = kbc->keycode[scancode];
			/* If driver uses Fn map, do not report the Fn key. */
			if ((keycodes[num_down] == KEY_FN) && kbc->use_fn_map)
				fn_keypress = true;
			else
				num_down++;
		}

		val >>= 8;
	}
Exemple #2
0
static void __pmic8xxx_kp_scan_matrix(struct pmic8xxx_kp *kp, u16 *new_state,
                                      u16 *old_state)
{
    int row, col, code;

    for (row = 0; row < kp->pdata->num_rows; row++) {
        int bits_changed = new_state[row] ^ old_state[row];

        if (!bits_changed)
            continue;

        for (col = 0; col < kp->pdata->num_cols; col++) {
            if (!(bits_changed & (1 << col)))
                continue;

            dev_dbg(kp->dev, "key [%d:%d] %s\n", row, col,
                    !(new_state[row] & (1 << col)) ?
                    "pressed" : "released");

            code = MATRIX_SCAN_CODE(row, col, PM8XXX_ROW_SHIFT);

            input_event(kp->input, EV_MSC, MSC_SCAN, code);
            input_report_key(kp->input,
                             kp->keycodes[code],
                             !(new_state[row] & (1 << col)));

            input_sync(kp->input);
        }
    }
}
Exemple #3
0
static void tca8418_read_keypad(struct tca8418_keypad *keypad_data)
{
	struct input_dev *input = keypad_data->input;
	unsigned short *keymap = input->keycode;
	int error, col, row;
	u8 reg, state, code;

	/* Initial read of the key event FIFO */
	error = tca8418_read_byte(keypad_data, REG_KEY_EVENT_A, &reg);

	/* Assume that key code 0 signifies empty FIFO */
	while (error >= 0 && reg > 0) {
		state = reg & KEY_EVENT_VALUE;
		code  = reg & KEY_EVENT_CODE;

		row = code / TCA8418_MAX_COLS;
		col = code % TCA8418_MAX_COLS;

		row = (col) ? row : row - 1;
		col = (col) ? col - 1 : TCA8418_MAX_COLS - 1;

		code = MATRIX_SCAN_CODE(row, col, keypad_data->row_shift);
		input_event(input, EV_MSC, MSC_SCAN, code);
		input_report_key(input, keymap[code], state);

		/* Read for next loop */
		error = tca8418_read_byte(keypad_data, REG_KEY_EVENT_A, &reg);
	}

	if (error < 0)
		dev_err(&keypad_data->client->dev,
			"unable to read REG_KEY_EVENT_A\n");

	input_sync(input);
}
Exemple #4
0
static int __stmpe1801_get_keycode_entries(u32 mask_row, u32 mask_col)
{
	int col, row;
	int i, j, comp;

	row = mask_row & 0xff;
	col = mask_col & 0x3ff;

	for (i = 8; i > 0; i--) {
		comp = 1 << (i - 1);
		printk(" row: %d, comp: %d\n", row, comp);
		if (row & comp) break;
	}

	for (j = 10; j > 0; j--) {
		comp = 1 << (j - 1);
		printk(" col: %d, comp: %d\n", col, comp);
		if (col & comp) break;
	}
#ifdef DBG_PRN
	printk(" row: %d, col: %d\n", i, j);
#endif

	return (MATRIX_SCAN_CODE(i - 1, j - 1, STMPE1801_KPC_ROW_SHIFT)+1);
}
Exemple #5
0
static int __pmic8058_kp_scan_matrix(struct pmic8058_kp *kp, u16 *new_state,
					 u16 *old_state)
{
	int row, col, code;

	for (row = 0; row < kp->pdata->num_rows; row++) {
		int bits_changed = new_state[row] ^ old_state[row];

		if (!bits_changed)
			continue;

		for (col = 0; col < kp->pdata->num_cols; col++) {
			if (!(bits_changed & (1 << col)))
				continue;

			dev_dbg(kp->dev, "key [%d:%d] %s\n", row, col,
					!(new_state[row] & (1 << col)) ?
					"pressed" : "released");
			printk("key [%d:%d] %s\n", row, col,
				!(new_state[row] & (1 << col)) ?
				"pressed" : "released"); // qiukj add for  test

			code = MATRIX_SCAN_CODE(row, col, PM8058_ROW_SHIFT);
			input_event(kp->input, EV_MSC, MSC_SCAN, code);
			input_report_key(kp->input,
					kp->keycodes[code],
					!(new_state[row] & (1 << col)));
			printk("keypad [%s] keycode %d\n",__func__,kp->keycodes[code]); // qiukj add for test

			input_sync(kp->input);
		}
	}

	return 0;
}
Exemple #6
0
static void ske_keypad_report(struct ske_keypad *keypad, u8 status, int col)
{
	int row = 0, code, pos;
	struct input_dev *input = keypad->input;
	u32 ske_ris;
	int key_pressed;
	int num_of_rows;

	/* find out the row */
	num_of_rows = hweight8(status);
	do {
		pos = __ffs(status);
		row = pos;
		status &= ~(1 << pos);

		code = MATRIX_SCAN_CODE(row, col, SKE_KEYPAD_ROW_SHIFT);
		ske_ris = readl(keypad->reg_base + SKE_RIS);
		key_pressed = ske_ris & SKE_KPRISA;

		input_event(input, EV_MSC, MSC_SCAN, code);
		input_report_key(input, keypad->keymap[code], key_pressed);
		input_sync(input);
		num_of_rows--;
	} while (num_of_rows);
}
Exemple #7
0
static void __pmic8xxx_kp_scan_matrix(struct pmic8xxx_kp *kp, u16 *new_state,
					 u16 *old_state)
{
	int row, col, code;

	for (row = 0; row < kp->pdata->num_rows; row++) {
		int bits_changed = new_state[row] ^ old_state[row];

		if (!bits_changed)
			continue;

		for (col = 0; col < kp->pdata->num_cols; col++) {
			if (!(bits_changed & (1 << col)))
				continue;

			if (!col && !row) pm8xxx_tactickle_key_to_touch = 1;
			code = MATRIX_SCAN_CODE(row, col, PM8XXX_ROW_SHIFT);

			input_event(kp->input, EV_MSC, MSC_SCAN, code);
			input_report_key(kp->input,
					kp->keycodes[code],
					!(new_state[row] & (1 << col)));

			input_sync(kp->input);
		}
	}
}
Exemple #8
0
/******************************************************************************
 * interrupt handler
 *****************************************************************************/
static irqreturn_t ftkbc010_interrupt(int irq, void *dev_id)
{
	struct ftkbc010 *ftkbc010 = dev_id;
	struct input_dev *input = ftkbc010->input;
	unsigned int status;
	unsigned int cr;

	status = ioread32(ftkbc010->base + FTKBC010_OFFSET_ISR);

	/*
	 * The clear interrupt bits are inside control register,
	 * so we need to read it out and then modify it -
	 * completely brain-dead design.
	 */
	cr = ioread32(ftkbc010->base + FTKBC010_OFFSET_CR);

	if (status & FTKBC010_ISR_RXINT) {
		dev_dbg(&input->dev, "RXINT\n");
		cr |= FTKBC010_CR_CL_RXINT;
	}

	if (status & FTKBC010_ISR_TXINT) {
		dev_dbg(&input->dev, "TXINT\n");
		cr |= FTKBC010_CR_CL_TXINT;
	}

	if (status & FTKBC010_ISR_PADINT) {
		unsigned int data;
		unsigned int row, col;
		unsigned int scancode;
		unsigned int keycode;

		data = ioread32(ftkbc010->base + FTKBC010_OFFSET_XC);
		col = ffs(0xff - FTKBC010_XC_L(data)) - 1;

		data = ioread32(ftkbc010->base + FTKBC010_OFFSET_YC);
		row = ffs(0xff - FTKBC010_YC_L(data)) - 1;

		scancode = MATRIX_SCAN_CODE(row, col, ftkbc010->row_shift);

		keycode = ftkbc010->keycode[scancode];

		input_report_key(input, keycode, 1);
		input_sync(input);

		/* We cannot tell key release - simulate one */
		input_report_key(input, keycode, 0);
		input_sync(input);

		dev_info(&input->dev, "(%x, %x) scancode %d, keycode %d\n",
			row, col, scancode, keycode);

		cr |= FTKBC010_CR_CL_PADINT;
	}

	iowrite32(cr, ftkbc010->base + FTKBC010_OFFSET_CR);

	return IRQ_HANDLED;
}
Exemple #9
0
/*
 * This gets the keys from keyboard and reports it to input subsystem
 */
static void matrix_keypad_scan(struct work_struct *work)
{
	struct matrix_keypad *keypad =
		container_of(work, struct matrix_keypad, work.work);
	struct input_dev *input_dev = keypad->input_dev;
	const unsigned short *keycodes = input_dev->keycode;
	const struct matrix_keypad_platform_data *pdata = keypad->pdata;
	uint32_t new_state[MATRIX_MAX_COLS];
	int row, col, code;

	/* de-activate all columns for scanning */
	activate_all_cols(pdata, false);

	memset(new_state, 0, sizeof(new_state));

	/* assert each column and read the row status out */
	for (col = 0; col < pdata->num_col_gpios; col++) {

		activate_col(pdata, col, true);

		for (row = 0; row < pdata->num_row_gpios; row++)
			new_state[col] |=
				row_asserted(pdata, row) ? (1 << row) : 0;

		activate_col(pdata, col, false);
	}

	for (col = 0; col < pdata->num_col_gpios; col++) {
		uint32_t bits_changed;

		bits_changed = keypad->last_key_state[col] ^ new_state[col];
		if (bits_changed == 0)
			continue;

		for (row = 0; row < pdata->num_row_gpios; row++) {
			if ((bits_changed & (1 << row)) == 0)
				continue;

			code = MATRIX_SCAN_CODE(row, col, keypad->row_shift);
			input_event(input_dev, EV_MSC, MSC_SCAN, code);
			input_report_key(input_dev,
					 keycodes[code],
					 new_state[col] & (1 << row));
		}
	}
	input_sync(input_dev);

	memcpy(keypad->last_key_state, new_state, sizeof(new_state));

	activate_all_cols(pdata, true);

	/* Enable IRQs again */
	spin_lock_irq(&keypad->lock);
	keypad->scan_pending = false;
	enable_row_irqs(keypad);
	spin_unlock_irq(&keypad->lock);
}
Exemple #10
0
static void omap_kp_tasklet(unsigned long data)
{
	struct omap_kp *omap_kp_data = (struct omap_kp *) data;
	unsigned short *keycodes = omap_kp_data->input->keycode;
	unsigned int row_shift = get_count_order(omap_kp_data->cols);
	unsigned char new_state[8], changed, key_down = 0;
	int col, row;
	int spurious = 0;

	/* check for any changes */
	omap_kp_scan_keypad(omap_kp_data, new_state);

	/* check for changes and print those */
	for (col = 0; col < omap_kp_data->cols; col++) {
		changed = new_state[col] ^ keypad_state[col];
		key_down |= new_state[col];
		if (changed == 0)
			continue;

		for (row = 0; row < omap_kp_data->rows; row++) {
			int key;
			if (!(changed & (1 << row)))
				continue;
#ifdef NEW_BOARD_LEARNING_MODE
			printk(KERN_INFO "omap-keypad: key %d-%d %s\n", col,
			       row, (new_state[col] & (1 << row)) ?
			       "pressed" : "released");
#else
			key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)];

			if (!(kp_cur_group == (key & GROUP_MASK) ||
			      kp_cur_group == -1))
				continue;

			kp_cur_group = key & GROUP_MASK;
			input_report_key(omap_kp_data->input, key & ~GROUP_MASK,
					 new_state[col] & (1 << row));
#endif
		}
	}
	input_sync(omap_kp_data->input);
	memcpy(keypad_state, new_state, sizeof(keypad_state));

	if (key_down) {
		int delay = HZ / 20;
		/* some key is pressed - keep irq disabled and use timer
		 * to poll the keypad */
		if (spurious)
			delay = 2 * HZ;
		mod_timer(&omap_kp_data->timer, jiffies + delay);
	} else {
		/* enable interrupts */
		omap_writew(0, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
		kp_cur_group = -1;
	}
}
Exemple #11
0
static int __pmic8058_kp_scan_matrix(struct pmic8058_kp *kp, u16 *new_state,
					 u16 *old_state)
{
	int row, col, code;

	for (row = 0; row < kp->pdata->num_rows; row++) {
		int bits_changed = new_state[row] ^ old_state[row];

		if (!bits_changed)
			continue;

		for (col = 0; col < kp->pdata->num_cols; col++) {
			if (!(bits_changed & (1 << col)))
				continue;

			dev_dbg(kp->dev, "key [%d:%d] %s\n", row, col,
					!(new_state[row] & (1 << col)) ?
					"pressed" : "released");

			code = MATRIX_SCAN_CODE(row, col, PM8058_ROW_SHIFT);
			input_event(kp->input, EV_MSC, MSC_SCAN, code);
			input_report_key(kp->input,
					kp->keycodes[code],
					!(new_state[row] & (1 << col)));

			input_sync(kp->input);
#if defined (CONFIG_TARGET_LOCALE_USA)
			pr_info("key [%d:%d] %s\n", row, col,
					!(new_state[row] & (1 << col)) ?
					"pressed" : "released");
#else
			pr_info("key [%d:%d] %s keycode [%d]\n", row, col,
					!(new_state[row] & (1 << col)) ?
					"pressed" : "released", kp->keycodes[code]);
#endif

#if defined (CONFIG_TOUCHSCREEN_MELFAS)
#if defined (CONFIG_KOR_MODEL_SHV_E120L) || defined (CONFIG_KOR_MODEL_SHV_E120S) || defined (CONFIG_KOR_MODEL_SHV_E120K) || defined(CONFIG_KOR_MODEL_SHV_E160S) || defined(CONFIG_KOR_MODEL_SHV_E160K) || defined(CONFIG_KOR_MODEL_SHV_E160L)
			if(!(new_state[row] & (1 << col)) && (kp->keycodes[code] == KEY_HOME)){
				TSP_force_released();
			}
#endif
#endif 

#if defined(CONFIG_SEC_DEBUG)
			sec_debug_check_crash_key(kp->keycodes[code], !(new_state[row] & (1 << col)));
#endif
		}
	}

	return 0;
}
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;
}
Exemple #13
0
//LGE_CHANGE_E:<*****@*****.**><03/06/2012><Slate feature porting from LS840 GB>
static void __pmic8xxx_kp_scan_matrix(struct pmic8xxx_kp *kp, u16 *new_state,
					 u16 *old_state)
{
	int row, col, code;

	for (row = 0; row < kp->pdata->num_rows; row++) {
		int bits_changed = new_state[row] ^ old_state[row];

		if (!bits_changed)
			continue;

		for (col = 0; col < kp->pdata->num_cols; col++) {
			if (!(bits_changed & (1 << col)))
				continue;

			dev_dbg(kp->dev, "key [%d:%d] %s\n", row, col,
					!(new_state[row] & (1 << col)) ?
					"pressed" : "released");

			code = MATRIX_SCAN_CODE(row, col, PM8XXX_ROW_SHIFT);

			input_event(kp->input, EV_MSC, MSC_SCAN, code);
#if defined (CONFIG_MACH_LGE_C1_BOARD_SPR)			
			if(lgf_key_lock != 0x55){
#endif			
			input_report_key(kp->input,
					kp->keycodes[code],
					!(new_state[row] & (1 << col)));

			input_sync(kp->input);
//LGE_CHANGE_S:<*****@*****.**><03/06/2012><Slate feature porting from LS840 GB>			
// LGE_CHANGE_S [[email protected]] [2011.10.21] [CAYMAN] enable or disable key logging status of slate [START]
#if defined (CONFIG_MACH_LGE_C1_BOARD_SPR)
#ifdef CONFIG_LGE_DIAG_ICD
			if(key_touch_logging_status == 1)
			{
				printk(KERN_INFO "%s(), key_touch_logging_status 1 start key logging \n",__func__);
				if(key_logging_count == 0)
					slate_send_key_log_packet((unsigned long)kp->keycodes[code], (unsigned long)!col);
				key_logging_count++;
				if(key_logging_count > 1)
					key_logging_count = 0;
			}
#endif
// LGE_CHANGE_E [[email protected]] [2011.10.21] [CAYMAN] enable or disable key logging status of slate [END]
//LGE_CHANGE_E:<*****@*****.**><03/06/2012><Slate feature porting from LS840 GB>
			}
#endif			
		}
	}
}
Exemple #14
0
static void stmpe1601_message_read(void)
{
    u8 val, data, key_fifo[STMPE1601_KPC_DATA_LEN];
    int row, col, kcode;
    bool up;
    int slide_state;
    int i, ret;

    /* Key LED ON */
    if (!key_led_stat) {
        slide_state = gpio_get_value(KEYPAD_SLIDE_SW);
        if (slide_state) {
            key_led_onoff(true);
            key_led_stat = true;
        }
    }

    /* Key Read */
    val = stmpe1601_read(gkpad, STMPE1601_REG_INT_STA_LSB);

    if (val & STPME1601_KPC_FIFO_OVR_EN)
        dev_err(&gkpad->i2c->dev, "[Q-KEY] Keypad FIFO Overflow\n");

    if (val & STPME1601_KPC_INT_EN) {
        ret = stmpe1601_kpad_read_data(gkpad, key_fifo);
        if (ret < 0)
            dev_err(&gkpad->i2c->dev, "[Q-KEY] Keypad data read failed\n");

        for (i = 0; i < STMPE1601_KPC_DATA_LEN-2; i++) {
            data = key_fifo[i];
            row = (data & STMPE1601_KPC_DATA_ROW) >> 3;
            col = data & STMPE1601_KPC_DATA_COL;
            kcode = MATRIX_SCAN_CODE(row, col, STMPE1601_KPAD_ROW_SHIFT);
            up = data & STMPE1601_KPC_DATA_UP;
            keypress = up;

            if ((data & STMPE1601_KPC_DATA_NOKEY_MASK) ==
                    STMPE1601_KPC_DATA_NOKEY_MASK)
                continue;
#if 0
            dprintk(KERN_DEBUG"[Q-KEY] Row = %d, Col = %d, UP = %d\n",
                    row, col, up);
#else
            printk(KERN_ERR"[Q-KEY] code:%d, row=%d, col=%d, up=%d\n",
                   gkpad->keycode[kcode], row, col, up);
#endif
            input_event(gkpad->input, EV_MSC, MSC_SCAN, kcode);
            input_report_key(gkpad->input, gkpad->keycode[kcode], !up);
            input_sync(gkpad->input);
        }
    }
static void db5500_gpio_release_work(struct work_struct *work)
{
	int code;
	struct db5500_keypad *keypad = container_of(work,
					struct db5500_keypad, gpio_work.work);
	struct input_dev *input = keypad->input;

	code = MATRIX_SCAN_CODE(keypad->gpio_col, keypad->gpio_row,
						KEYPAD_ROW_SHIFT);
	input_event(input, EV_MSC, MSC_SCAN, code);
	input_report_key(input, keypad->keymap[code], 1);
	input_sync(input);
	input_report_key(input, keypad->keymap[code], 0);
	input_sync(input);
}
Exemple #16
0
/* Interrupt handler */
static irqreturn_t omap4_keypad_interrupt(int irq, void *dev_id)
{
	struct omap4_keypad *keypad_data = dev_id;
	struct input_dev *input_dev = keypad_data->input;
	unsigned char key_state[ARRAY_SIZE(keypad_data->key_state)];
	unsigned int col, row, code, changed;
	u32 *new_state = (u32 *) key_state;

	/* Disable interrupts */
	__raw_writel(OMAP4_VAL_IRQDISABLE,
		     keypad_data->base + OMAP4_KBD_IRQENABLE);

	*new_state = __raw_readl(keypad_data->base + OMAP4_KBD_FULLCODE31_0);
	*(new_state + 1) = __raw_readl(keypad_data->base
						+ OMAP4_KBD_FULLCODE63_32);

	for (row = 0; row < keypad_data->rows; row++) {
		changed = key_state[row] ^ keypad_data->key_state[row];
		if (!changed)
			continue;

		for (col = 0; col < keypad_data->cols; col++) {
			if (changed & (1 << col)) {
				code = MATRIX_SCAN_CODE(row, col,
						keypad_data->row_shift);
				input_event(input_dev, EV_MSC, MSC_SCAN, code);
				input_report_key(input_dev,
						 keypad_data->keymap[code],
						 key_state[row] & (1 << col));
			}
		}
	}

	input_sync(input_dev);

	memcpy(keypad_data->key_state, key_state,
		sizeof(keypad_data->key_state));

	/* clear pending interrupts */
	__raw_writel(__raw_readl(keypad_data->base + OMAP4_KBD_IRQSTATUS),
			keypad_data->base + OMAP4_KBD_IRQSTATUS);

	/* enable interrupts */
	__raw_writel(OMAP4_DEF_IRQENABLE_EVENTEN | OMAP4_DEF_IRQENABLE_LONGKEY,
			keypad_data->base + OMAP4_KBD_IRQENABLE);

	return IRQ_HANDLED;
}
Exemple #17
0
static void w90p910_keypad_scan_matrix(struct w90p910_keypad *keypad,
							unsigned int status)
{
	struct input_dev *input_dev = keypad->input_dev;
	unsigned int row = KGET_RAW(status);
	unsigned int col = KGET_COLUMN(status);
	unsigned int code = MATRIX_SCAN_CODE(row, col, W90P910_ROW_SHIFT);
	unsigned int key = keypad->keymap[code];

	input_event(input_dev, EV_MSC, MSC_SCAN, code);
	input_report_key(input_dev, key, 1);
	input_sync(input_dev);

	input_event(input_dev, EV_MSC, MSC_SCAN, code);
	input_report_key(input_dev, key, 0);
	input_sync(input_dev);
}
Exemple #18
0
/*
 * Compares the new keyboard state to the old one and produces key
 * press/release events accordingly.  The keyboard state is 13 bytes (one byte
 * per column)
 */
static void cros_ec_keyb_process(struct cros_ec_keyb *ckdev,
			 uint8_t *kb_state, int len)
{
	struct input_dev *idev = ckdev->idev;
	struct cros_ec_device *ec = ckdev->ec;
	int col, row;
	int new_state;
	int old_state;
	int num_cols;
	num_cols = len;

	if (ckdev->ghost_filter && cros_ec_keyb_has_ghosting(ckdev, kb_state)) {
		/*
		 * Simple-minded solution: ignore this state. The obvious
		 * improvement is to only ignore changes to keys involved in
		 * the ghosting, but process the other changes.
		 */
		dev_dbg(ckdev->dev, "ghosting found\n");
		return;
	}

	for (col = 0; col < ckdev->cols; col++) {
		for (row = 0; row < ckdev->rows; row++) {
			int pos = MATRIX_SCAN_CODE(row, col, ckdev->row_shift);
			const unsigned short *keycodes = idev->keycode;
			int code;

			code = keycodes[pos];
			new_state = kb_state[col] & (1 << row);
			old_state = ckdev->old_kb_state[col] & (1 << row);
			if (new_state != old_state) {
				dev_dbg(ckdev->dev,
					"changed: [r%d c%d]: byte %02x\n",
					row, col, new_state);
				/* Change to power supply status */
				if ((ec->charger && code == KEY_BATTERY)) {
					power_supply_changed(ec->charger);
					continue;
				}
				input_report_key(idev, code, new_state);
			}
		}
		ckdev->old_kb_state[col] = kb_state[col];
	}
	input_sync(ckdev->idev);
}
/**
 * db5500_keypad_report() - reports the keypad event
 * @keypad: pointer to device structure
 * @row: row value of keypad
 * @curr: current event
 * @previous: previous event
 *
 * This function uses to reports the event of the keypad
 * and returns NONE.
 *
 * By default all column reads are 1111 1111b.  Any press will pull the column
 * down, leading to a 0 in any of these locations.  We invert these values so
 * that a 1 means means "column pressed". *
 * If curr changes from the previous from 0 to 1, we report it as a key press.
 * If curr changes from the previous from 1 to 0, we report it as a key
 * release.
 */
static void db5500_keypad_report(struct db5500_keypad *keypad, int row,
				 u8 curr, u8 previous)
{
	struct input_dev *input = keypad->input;
	u8 changed  = curr ^ previous;

	while (changed) {
		int col = __ffs(changed);
		bool press = curr & BIT(col);
		int code = MATRIX_SCAN_CODE(row, col, KEYPAD_ROW_SHIFT);

		input_event(input, EV_MSC, MSC_SCAN, code);
		input_report_key(input, keypad->keymap[code], press);
		input_sync(input);

		changed &= ~BIT(col);
	}
}
Exemple #20
0
/*
 * Walks keycodes flipping bit in buffer COLUMNS deep where bit is ROW.  Used by
 * ghosting logic to ignore NULL or virtual keys.
 */
static void cros_ec_keyb_compute_valid_keys(struct cros_ec_keyb *ckdev)
{
	int row, col;
	int row_shift = ckdev->row_shift;
	unsigned short *keymap = ckdev->idev->keycode;
	unsigned short code;

	BUG_ON(ckdev->idev->keycodesize != sizeof(*keymap));

	for (col = 0; col < ckdev->cols; col++) {
		for (row = 0; row < ckdev->rows; row++) {
			code = keymap[MATRIX_SCAN_CODE(row, col, row_shift)];
			if (code && (code != KEY_BATTERY))
				ckdev->valid_keys[col] |= 1 << row;
		}
		dev_dbg(ckdev->dev, "valid_keys[%02d] = 0x%02x\n",
			col, ckdev->valid_keys[col]);
	}
}
static void __pmic8xxx_kp_scan_matrix(struct pmic8xxx_kp *kp, u16 *new_state,
                                      u16 *old_state)
{
    int row, col, code;

    for (row = 0; row < kp->pdata->num_rows; row++) {
        int bits_changed = new_state[row] ^ old_state[row];

        if (!bits_changed)
            continue;

        for (col = 0; col < kp->pdata->num_cols; col++) {
            if (!(bits_changed & (1 << col)))
                continue;

            dev_dbg(kp->dev, "key [%d:%d] %s\n", row, col,
                    !(new_state[row] & (1 << col)) ?
                    "pressed" : "released");

            code = MATRIX_SCAN_CODE(row, col, PM8XXX_ROW_SHIFT);

            input_event(kp->input, EV_MSC, MSC_SCAN, code);
            input_report_key(kp->input,
                             kp->keycodes[code],
                             !(new_state[row] & (1 << col)));

            input_sync(kp->input);

#if defined (DSEC_KEYBOARD_CODE_DEBUG)
            pr_info("key [%d:%d] %s keycode [%d]\n", row, col,
                    !(new_state[row] & (1 << col)) ?
                    "pressed" : "released", kp->keycodes[code]);
#else
            pr_info("key %s\n",
                    !(new_state[row] & (1 << col)) ? "pressed" : "released");
#endif

#if defined(CONFIG_SEC_DEBUG)
            sec_debug_check_crash_key(kp->keycodes[code], !(new_state[row] & (1 << col)));
#endif
        }
    }
}
static int __pmic8058_kp_scan_matrix(struct pmic8058_kp *kp, u16 *new_state,
					 u16 *old_state)
{
	int row, col, code;

	for (row = 0; row < kp->pdata->num_rows; row++) {
		int bits_changed = new_state[row] ^ old_state[row];

		if (!bits_changed)
			continue;

		for (col = 0; col < kp->pdata->num_cols; col++) {
			if (!(bits_changed & (1 << col)))
				continue;

			dev_dbg(kp->dev, "key [%d:%d] %s\n", row, col,
					!(new_state[row] & (1 << col)) ?
					"pressed" : "released");

			code = MATRIX_SCAN_CODE(row, col, PM8058_ROW_SHIFT);

/* in order to avoid reporting unvalid codes to input system, we should check the key's value not the index */
/* report the event only if the key is in the map.  */
#ifdef CONFIG_HUAWEI_KERNEL	
            if (kp->keycodes[code])
            {
#endif	
			input_event(kp->input, EV_MSC, MSC_SCAN, code);
			input_report_key(kp->input,
					kp->keycodes[code],
					!(new_state[row] & (1 << col)));

			input_sync(kp->input);
#ifdef CONFIG_HUAWEI_KERNEL		
            }
#endif	
		}
	}

	return 0;
}
static bool matrix_keypad_map_key(struct input_dev *input_dev,
				  unsigned int rows, unsigned int cols,
				  unsigned int row_shift, unsigned int key)
{
	unsigned short *keymap = input_dev->keycode;
	unsigned int row = KEY_ROW(key);
	unsigned int col = KEY_COL(key);
	unsigned short code = KEY_VAL(key);

	if (row >= rows || col >= cols) {
		dev_err(input_dev->dev.parent,
			"%s: invalid keymap entry 0x%x (row: %d, col: %d, rows: %d, cols: %d)\n",
			__func__, key, row, col, rows, cols);
		return false;
	}

	keymap[MATRIX_SCAN_CODE(row, col, row_shift)] = code;
	__set_bit(code, input_dev->keybit);

	return true;
}
static void ske_keypad_read_data(struct ske_keypad *keypad)
{
	struct input_dev *input = keypad->input;
	u16 status;
	int col = 0, row = 0, code;
	int ske_asr, ske_ris, key_pressed, i;

	/*
	 * Read the auto scan registers
	 *
	 * Each SKE_ASRx (x=0 to x=3) contains two row values.
	 * lower byte contains row value for column 2*x,
	 * upper byte contains row value for column 2*x + 1
	 */
	for (i = 0; i < SKE_NUM_ASRX_REGISTERS; i++) {
		ske_asr = readl(keypad->reg_base + SKE_ASR0 + (4 * i));
		if (!ske_asr)
			continue;

		/* now that ASRx is zero, find out the column x and row y*/
		if (ske_asr & 0xff) {
			col = i * 2;
			status = ske_asr & 0xff;
		} else {
			col = (i * 2) + 1;
			status = (ske_asr & 0xff00) >> 8;
		}

		/* find out the row */
		row = __ffs(status);

		code = MATRIX_SCAN_CODE(row, col, SKE_KEYPAD_ROW_SHIFT);
		ske_ris = readl(keypad->reg_base + SKE_RIS);
		key_pressed = ske_ris & SKE_KPRISA;

		input_event(input, EV_MSC, MSC_SCAN, code);
		input_report_key(input, keypad->keymap[code], key_pressed);
		input_sync(input);
	}
}
static void __pmic8xxx_kp_scan_matrix(struct pmic8xxx_kp *kp, u16 *new_state,
					 u16 *old_state)
{
	int row, col, code;

	for (row = 0; row < kp->pdata->num_rows; row++) {
		int bits_changed = new_state[row] ^ old_state[row];

		if (!bits_changed)
			continue;

		for (col = 0; col < kp->pdata->num_cols; col++) {
			if (!(bits_changed & (1 << col)))
				continue;

			dev_dbg(kp->dev, "key [%d:%d] %s\n", row, col,
					!(new_state[row] & (1 << col)) ?
					"pressed" : "released");
#if defined(CONFIG_MACH_APQ8064_GKKT)||defined(CONFIG_MACH_APQ8064_GKU) || defined(CONFIG_MACH_APQ8064_GKSK)
			if(!row && !col)
				pr_info("[key] Volume Down %s\n",!(new_state[row] & (1 << col)) ? "pressed" : "released");
			else if(!row && col)
				pr_info("[key] Volume Up %s\n",!(new_state[row] & (1 << col)) ? "pressed" : "released");
			else if(row && !col)
				pr_info("[key] Quick Memo %s\n",!(new_state[row] & (1 << col)) ? "pressed" : "released");
			else
				pr_info("[key] Home %s\n",!(new_state[row] & (1 << col)) ? "pressed" : "released");
#endif

			code = MATRIX_SCAN_CODE(row, col, PM8XXX_ROW_SHIFT);

			input_event(kp->input, EV_MSC, MSC_SCAN, code);
			input_report_key(kp->input,
					kp->keycodes[code],
					!(new_state[row] & (1 << col)));

			input_sync(kp->input);
		}
	}
}
/* Update the new_keycode_state*/
static void k3v2_keypad_update_keycode(struct k3v2_keypad *keypad,
	unsigned char *new_scancode_state,
	uint16_t *new_keycode_state)
{
	int row = 0;
	int col = 0;
	int r = 0;
	int c = 0;
	int index = 0;
	uint8_t keycode = 0;

	for (row = 0; row < KPC_MAX_ROWS; row++) {
		for (col = 0; col < KPC_MAX_COLS; col++) {
			if (new_scancode_state[row] & (1 << col)) {
				index = MATRIX_SCAN_CODE(row, col, keypad->row_shift);
				keycode = keypad->keycodes[index];
				c = keycode & 0x0F;
				r = keycode >> 4;
				new_keycode_state[r] |= (1 << c);
			}
		}
	}
static void __pmic8xxx_kp_scan_matrix(struct pmic8xxx_kp *kp, u16 *new_state,
					 u16 *old_state)
{
	int row, col, code;

	for (row = 0; row < kp->pdata->num_rows; row++) {
		int bits_changed = new_state[row] ^ old_state[row];

		if (!bits_changed)
			continue;

		for (col = 0; col < kp->pdata->num_cols; col++) {
			if (!(bits_changed & (1 << col)))
				continue;

			dev_dbg(kp->dev, "key [%d:%d] %s\n", row, col,
					!(new_state[row] & (1 << col)) ?
					"pressed" : "released");

			code = MATRIX_SCAN_CODE(row, col, PM8XXX_ROW_SHIFT);

			/*reduce invalid input event*/
#ifdef CONFIG_HUAWEI_KERNEL	
            if (kp->keycodes[code])
            {
#endif	
				input_event(kp->input, EV_MSC, MSC_SCAN, code);
				input_report_key(kp->input,
						kp->keycodes[code],
						!(new_state[row] & (1 << col)));
				/* use mmi_keystate save the key state */
	       		mmi_keystate[kp->keycodes[code]] = (!(new_state[row]&(1<<col)))? MMI_KEY_DOWN :MMI_KEY_UP ;
				input_sync(kp->input);
#ifdef CONFIG_HUAWEI_KERNEL		
             }
#endif	
		}
	}
}
static bool samsung_keypad_report(struct samsung_keypad *keypad,
				  unsigned int *row_state)
{
	struct input_dev *input_dev = keypad->input_dev;
	unsigned int changed;
	unsigned int pressed;
	unsigned int key_down = 0;
	unsigned int val;
	unsigned int col, row;

	for (col = 0; col < keypad->cols; col++) {
		changed = row_state[col] ^ keypad->row_state[col];
		key_down |= row_state[col];
		if (!changed)
			continue;

		for (row = 0; row < keypad->rows; row++) {
			if (!(changed & (1 << row)))
				continue;

			pressed = row_state[col] & (1 << row);

			dev_dbg(&keypad->input_dev->dev,
				"key %s, row: %d, col: %d\n",
				pressed ? "pressed" : "released", row, col);

			val = MATRIX_SCAN_CODE(row, col, keypad->row_shift);

			input_event(input_dev, EV_MSC, MSC_SCAN, val);
			input_report_key(input_dev,
					keypad->keycodes[val], pressed);
		}
		input_sync(keypad->input_dev);
	}

	memcpy(keypad->row_state, row_state, sizeof(keypad->row_state));

	return key_down;
}
static void __pmic8xxx_kp_scan_matrix(struct pmic8xxx_kp *kp, u16 *new_state,
					 u16 *old_state)
{
	int row, col, code;

	for (row = 0; row < kp->pdata->num_rows; row++) {
		int bits_changed = new_state[row] ^ old_state[row];

		if (!bits_changed)
			continue;

		for (col = 0; col < kp->pdata->num_cols; col++) {
			if (!(bits_changed & (1 << col)))
				continue;
#if !defined(CONFIG_SAMSUNG_PRODUCT_SHIP)
			dev_err(kp->dev, "key [%d:%d] %s\n", row, col,
					!(new_state[row] & (1 << col)) ?
					"pressed" : "released");
#endif
#if defined(CONFIG_MACH_KS02)
			if(!(new_state[row] & (1 << col)))
				key_state = 1;
			else
				key_state = 0;
#endif
			code = MATRIX_SCAN_CODE(row, col, PM8XXX_ROW_SHIFT);

			input_event(kp->input, EV_MSC, MSC_SCAN, code);
			input_report_key(kp->input,
					kp->keycodes[code],
					!(new_state[row] & (1 << col)));

			input_sync(kp->input);
		}
	}
}
Exemple #30
0
/*
 * Compare the new matrix state (volatile) with the stable one stored in
 * keypad->matrix_stable_state and fire events if changes are detected.
 */
static void imx_keypad_fire_events(struct imx_keypad *keypad,
				   unsigned short *matrix_volatile_state)
{
	struct input_dev *input_dev = keypad->input_dev;
	int row, col;

	for (col = 0; col < MAX_MATRIX_KEY_COLS; col++) {
		unsigned short bits_changed;
		int code;

		if ((keypad->cols_en_mask & (1 << col)) == 0)
			continue; /* Column is not enabled */

		bits_changed = keypad->matrix_stable_state[col] ^
						matrix_volatile_state[col];

		if (bits_changed == 0)
			continue; /* Column does not contain changes */

		for (row = 0; row < MAX_MATRIX_KEY_ROWS; row++) {
			if ((keypad->rows_en_mask & (1 << row)) == 0)
				continue; /* Row is not enabled */
			if ((bits_changed & (1 << row)) == 0)
				continue; /* Row does not contain changes */

			code = MATRIX_SCAN_CODE(row, col, MATRIX_ROW_SHIFT);
			input_event(input_dev, EV_MSC, MSC_SCAN, code);
			input_report_key(input_dev, keypad->keycodes[code],
				matrix_volatile_state[col] & (1 << row));
			dev_dbg(&input_dev->dev, "Event code: %d, val: %d",
				keypad->keycodes[code],
				matrix_volatile_state[col] & (1 << row));
		}
	}
	input_sync(input_dev);
}