Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2)  * Copyright (C) 2014 Broadcom Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * This program is free software; you can redistribute it and/or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * modify it under the terms of the GNU General Public License as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * published by the Free Software Foundation version 2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * This program is distributed "as is" WITHOUT ANY WARRANTY of any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * kind, whether express or implied; without even the implied warranty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  * GNU General Public License for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/gfp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/input.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/input/matrix_keypad.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include <linux/stddef.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #define DEFAULT_CLK_HZ			31250
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #define MAX_ROWS			8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #define MAX_COLS			8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) /* Register/field definitions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #define KPCR_OFFSET			0x00000080
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #define KPCR_MODE			0x00000002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #define KPCR_MODE_SHIFT			1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #define KPCR_MODE_MASK			1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #define KPCR_ENABLE			0x00000001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #define KPCR_STATUSFILTERENABLE		0x00008000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #define KPCR_STATUSFILTERTYPE_SHIFT	12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #define KPCR_COLFILTERENABLE		0x00000800
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #define KPCR_COLFILTERTYPE_SHIFT	8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) #define KPCR_ROWWIDTH_SHIFT		20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) #define KPCR_COLUMNWIDTH_SHIFT		16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) #define KPIOR_OFFSET			0x00000084
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) #define KPIOR_ROWOCONTRL_SHIFT		24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) #define KPIOR_ROWOCONTRL_MASK		0xFF000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) #define KPIOR_COLUMNOCONTRL_SHIFT	16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) #define KPIOR_COLUMNOCONTRL_MASK	0x00FF0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) #define KPIOR_COLUMN_IO_DATA_SHIFT	0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) #define KPEMR0_OFFSET			0x00000090
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) #define KPEMR1_OFFSET			0x00000094
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) #define KPEMR2_OFFSET			0x00000098
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) #define KPEMR3_OFFSET			0x0000009C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) #define KPEMR_EDGETYPE_BOTH		3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) #define KPSSR0_OFFSET			0x000000A0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) #define KPSSR1_OFFSET			0x000000A4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) #define KPSSRN_OFFSET(reg_n)		(KPSSR0_OFFSET + 4 * (reg_n))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) #define KPIMR0_OFFSET			0x000000B0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) #define KPIMR1_OFFSET			0x000000B4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) #define KPICR0_OFFSET			0x000000B8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) #define KPICR1_OFFSET			0x000000BC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) #define KPICRN_OFFSET(reg_n)		(KPICR0_OFFSET + 4 * (reg_n))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) #define KPISR0_OFFSET			0x000000C0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) #define KPISR1_OFFSET			0x000000C4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) #define KPCR_STATUSFILTERTYPE_MAX	7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) #define KPCR_COLFILTERTYPE_MAX		7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) /* Macros to determine the row/column from a bit that is set in SSR0/1. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) #define BIT_TO_ROW_SSRN(bit_nr, reg_n)	(((bit_nr) >> 3) + 4 * (reg_n))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) #define BIT_TO_COL(bit_nr)		((bit_nr) % 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) /* Structure representing various run-time entities */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) struct bcm_kp {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	void __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	struct input_dev *input_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	unsigned long last_state[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	unsigned int n_rows;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	unsigned int n_cols;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	u32 kpcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	u32 kpior;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	u32 kpemr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	u32 imr0_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	u32 imr1_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92)  * Returns the keycode from the input device keymap given the row and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93)  * column.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) static int bcm_kp_get_keycode(struct bcm_kp *kp, int row, int col)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	unsigned int row_shift = get_count_order(kp->n_cols);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	unsigned short *keymap = kp->input_dev->keycode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	return keymap[MATRIX_SCAN_CODE(row, col, row_shift)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) static void bcm_kp_report_keys(struct bcm_kp *kp, int reg_num, int pull_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	unsigned long state, change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	int bit_nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	int key_press;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	int row, col;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	unsigned int keycode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	/* Clear interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	writel(0xFFFFFFFF, kp->base + KPICRN_OFFSET(reg_num));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	state = readl(kp->base + KPSSRN_OFFSET(reg_num));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	change = kp->last_state[reg_num] ^ state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	kp->last_state[reg_num] = state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	for_each_set_bit(bit_nr, &change, BITS_PER_LONG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		key_press = state & BIT(bit_nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		/* The meaning of SSR register depends on pull mode. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 		key_press = pull_mode ? !key_press : key_press;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 		row = BIT_TO_ROW_SSRN(bit_nr, reg_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 		col = BIT_TO_COL(bit_nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 		keycode = bcm_kp_get_keycode(kp, row, col);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 		input_report_key(kp->input_dev, keycode, key_press);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) static irqreturn_t bcm_kp_isr_thread(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	struct bcm_kp *kp = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	int pull_mode = (kp->kpcr >> KPCR_MODE_SHIFT) & KPCR_MODE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	int reg_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	for (reg_num = 0; reg_num <= 1; reg_num++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 		bcm_kp_report_keys(kp, reg_num, pull_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	input_sync(kp->input_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) static int bcm_kp_start(struct bcm_kp *kp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	if (kp->clk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 		error = clk_prepare_enable(kp->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 			return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	writel(kp->kpior, kp->base + KPIOR_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	writel(kp->imr0_val, kp->base + KPIMR0_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	writel(kp->imr1_val, kp->base + KPIMR1_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	writel(kp->kpemr, kp->base + KPEMR0_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	writel(kp->kpemr, kp->base + KPEMR1_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	writel(kp->kpemr, kp->base + KPEMR2_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	writel(kp->kpemr, kp->base + KPEMR3_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	writel(0xFFFFFFFF, kp->base + KPICR0_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	writel(0xFFFFFFFF, kp->base + KPICR1_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	kp->last_state[0] = readl(kp->base + KPSSR0_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	kp->last_state[0] = readl(kp->base + KPSSR1_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	writel(kp->kpcr | KPCR_ENABLE, kp->base + KPCR_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) static void bcm_kp_stop(const struct bcm_kp *kp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	val = readl(kp->base + KPCR_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	val &= ~KPCR_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	writel(0, kp->base + KPCR_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	writel(0, kp->base + KPIMR0_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	writel(0, kp->base + KPIMR1_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	writel(0xFFFFFFFF, kp->base + KPICR0_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	writel(0xFFFFFFFF, kp->base + KPICR1_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	if (kp->clk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 		clk_disable_unprepare(kp->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) static int bcm_kp_open(struct input_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	struct bcm_kp *kp = input_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	return bcm_kp_start(kp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) static void bcm_kp_close(struct input_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	struct bcm_kp *kp = input_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	bcm_kp_stop(kp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) static int bcm_kp_matrix_key_parse_dt(struct bcm_kp *kp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	struct device *dev = kp->input_dev->dev.parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	struct device_node *np = dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	unsigned int dt_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	unsigned int num_rows, col_mask, rows_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	/* Initialize the KPCR Keypad Configuration Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	kp->kpcr = KPCR_STATUSFILTERENABLE | KPCR_COLFILTERENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	error = matrix_keypad_parse_properties(dev, &kp->n_rows, &kp->n_cols);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 		dev_err(dev, "failed to parse kp params\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	/* Set row width for the ASIC block. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	kp->kpcr |= (kp->n_rows - 1) << KPCR_ROWWIDTH_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	/* Set column width for the ASIC block. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	kp->kpcr |= (kp->n_cols - 1) << KPCR_COLUMNWIDTH_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	/* Configure the IMR registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	 * IMR registers contain interrupt enable bits for 8x8 matrix
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	 * IMR0 register format: <row3> <row2> <row1> <row0>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	 * IMR1 register format: <row7> <row6> <row5> <row4>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	col_mask = (1 << (kp->n_cols)) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	num_rows = kp->n_rows;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	/* Set column bits in rows 0 to 3 in IMR0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	kp->imr0_val = col_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	rows_set = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	while (--num_rows && rows_set++ < 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 		kp->imr0_val |= kp->imr0_val << MAX_COLS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	/* Set column bits in rows 4 to 7 in IMR1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	kp->imr1_val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	if (num_rows) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 		kp->imr1_val = col_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 		while (--num_rows)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 			kp->imr1_val |= kp->imr1_val << MAX_COLS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	/* Initialize the KPEMR Keypress Edge Mode Registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	/* Trigger on both edges */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	kp->kpemr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	for (i = 0; i <= 30; i += 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 		kp->kpemr |= (KPEMR_EDGETYPE_BOTH << i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	 * Obtain the Status filter debounce value and verify against the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	 * possible values specified in the DT binding.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	of_property_read_u32(np, "status-debounce-filter-period", &dt_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	if (dt_val > KPCR_STATUSFILTERTYPE_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 		dev_err(dev, "Invalid Status filter debounce value %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 			dt_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	kp->kpcr |= dt_val << KPCR_STATUSFILTERTYPE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	 * Obtain the Column filter debounce value and verify against the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	 * possible values specified in the DT binding.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	of_property_read_u32(np, "col-debounce-filter-period", &dt_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	if (dt_val > KPCR_COLFILTERTYPE_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 		dev_err(dev, "Invalid Column filter debounce value %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 			dt_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	kp->kpcr |= dt_val << KPCR_COLFILTERTYPE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	 * Determine between the row and column,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	 * which should be configured as output.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	if (of_property_read_bool(np, "row-output-enabled")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 		* Set RowOContrl or ColumnOContrl in KPIOR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 		* to the number of pins to drive as outputs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 		*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 		kp->kpior = ((1 << kp->n_rows) - 1) <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 				KPIOR_ROWOCONTRL_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 		kp->kpior = ((1 << kp->n_cols) - 1) <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 				KPIOR_COLUMNOCONTRL_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	 * Determine if the scan pull up needs to be enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	if (of_property_read_bool(np, "pull-up-enabled"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 		kp->kpcr |= KPCR_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	dev_dbg(dev, "n_rows=%d n_col=%d kpcr=%x kpior=%x kpemr=%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 		kp->n_rows, kp->n_cols,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 		kp->kpcr, kp->kpior, kp->kpemr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) static int bcm_kp_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	struct bcm_kp *kp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	struct input_dev *input_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	kp = devm_kzalloc(&pdev->dev, sizeof(*kp), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	if (!kp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	input_dev = devm_input_allocate_device(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	if (!input_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 		dev_err(&pdev->dev, "failed to allocate the input device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	__set_bit(EV_KEY, input_dev->evbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	/* Enable auto repeat feature of Linux input subsystem */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 	if (of_property_read_bool(pdev->dev.of_node, "autorepeat"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 		__set_bit(EV_REP, input_dev->evbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	input_dev->name = pdev->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	input_dev->phys = "keypad/input0";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	input_dev->dev.parent = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	input_dev->open = bcm_kp_open;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	input_dev->close = bcm_kp_close;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	input_dev->id.bustype = BUS_HOST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	input_dev->id.vendor = 0x0001;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	input_dev->id.product = 0x0001;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	input_dev->id.version = 0x0100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	input_set_drvdata(input_dev, kp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	kp->input_dev = input_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	error = bcm_kp_matrix_key_parse_dt(kp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	error = matrix_keypad_build_keymap(NULL, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 					   kp->n_rows, kp->n_cols,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 					   NULL, input_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 		dev_err(&pdev->dev, "failed to build keymap\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	/* Get the KEYPAD base address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	if (!res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 		dev_err(&pdev->dev, "Missing keypad base address resource\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	kp->base = devm_ioremap_resource(&pdev->dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 	if (IS_ERR(kp->base))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 		return PTR_ERR(kp->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	/* Enable clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	kp->clk = devm_clk_get(&pdev->dev, "peri_clk");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	if (IS_ERR(kp->clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 		error = PTR_ERR(kp->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 		if (error != -ENOENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 			if (error != -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 				dev_err(&pdev->dev, "Failed to get clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 			return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 		dev_dbg(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 			"No clock specified. Assuming it's enabled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 		kp->clk = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 		unsigned int desired_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 		long actual_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 		error = of_property_read_u32(pdev->dev.of_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 					     "clock-frequency", &desired_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 		if (error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 			desired_rate = DEFAULT_CLK_HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 		actual_rate = clk_round_rate(kp->clk, desired_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 		if (actual_rate <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 		error = clk_set_rate(kp->clk, actual_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 			return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 		error = clk_prepare_enable(kp->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 			return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 	/* Put the kp into a known sane state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 	bcm_kp_stop(kp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 	kp->irq = platform_get_irq(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 	if (kp->irq < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 	error = devm_request_threaded_irq(&pdev->dev, kp->irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 					  NULL, bcm_kp_isr_thread,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 					  IRQF_ONESHOT, pdev->name, kp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 		dev_err(&pdev->dev, "failed to request IRQ\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	error = input_register_device(input_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 	if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 		dev_err(&pdev->dev, "failed to register input device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) static const struct of_device_id bcm_kp_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 	{ .compatible = "brcm,bcm-keypad" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	{ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) MODULE_DEVICE_TABLE(of, bcm_kp_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) static struct platform_driver bcm_kp_device_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	.probe		= bcm_kp_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 	.driver		= {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 		.name	= "bcm-keypad",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 		.of_match_table = of_match_ptr(bcm_kp_of_match),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) module_platform_driver(bcm_kp_device_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) MODULE_AUTHOR("Broadcom Corporation");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) MODULE_DESCRIPTION("BCM Keypad Driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) MODULE_LICENSE("GPL v2");