• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (C) 2017 Sanechips Technology Co., Ltd.
4  * Copyright 2017 Linaro Ltd.
5  */
6 
7 #include <linux/device.h>
8 #include <linux/err.h>
9 #include <linux/interrupt.h>
10 #include <linux/io.h>
11 #include <linux/module.h>
12 #include <linux/of_platform.h>
13 #include <linux/platform_device.h>
14 
15 #include <media/rc-core.h>
16 
17 #define DRIVER_NAME		"zx-irdec"
18 
19 #define ZX_IR_ENABLE		0x04
20 #define ZX_IREN			BIT(0)
21 #define ZX_IR_CTRL		0x08
22 #define ZX_DEGL_MASK		GENMASK(21, 20)
23 #define ZX_DEGL_VALUE(x)	(((x) << 20) & ZX_DEGL_MASK)
24 #define ZX_WDBEGIN_MASK		GENMASK(18, 8)
25 #define ZX_WDBEGIN_VALUE(x)	(((x) << 8) & ZX_WDBEGIN_MASK)
26 #define ZX_IR_INTEN		0x10
27 #define ZX_IR_INTSTCLR		0x14
28 #define ZX_IR_CODE		0x30
29 #define ZX_IR_CNUM		0x34
30 #define ZX_NECRPT		BIT(16)
31 
32 struct zx_irdec {
33 	void __iomem *base;
34 	struct rc_dev *rcd;
35 };
36 
zx_irdec_set_mask(struct zx_irdec * irdec,unsigned int reg,u32 mask,u32 value)37 static void zx_irdec_set_mask(struct zx_irdec *irdec, unsigned int reg,
38 			      u32 mask, u32 value)
39 {
40 	u32 data;
41 
42 	data = readl(irdec->base + reg);
43 	data &= ~mask;
44 	data |= value & mask;
45 	writel(data, irdec->base + reg);
46 }
47 
zx_irdec_irq(int irq,void * dev_id)48 static irqreturn_t zx_irdec_irq(int irq, void *dev_id)
49 {
50 	struct zx_irdec *irdec = dev_id;
51 	u8 address, not_address;
52 	u8 command, not_command;
53 	u32 rawcode, scancode;
54 	enum rc_proto rc_proto;
55 
56 	/* Clear interrupt */
57 	writel(1, irdec->base + ZX_IR_INTSTCLR);
58 
59 	/* Check repeat frame */
60 	if (readl(irdec->base + ZX_IR_CNUM) & ZX_NECRPT) {
61 		rc_repeat(irdec->rcd);
62 		goto done;
63 	}
64 
65 	rawcode = readl(irdec->base + ZX_IR_CODE);
66 	not_command = (rawcode >> 24) & 0xff;
67 	command = (rawcode >> 16) & 0xff;
68 	not_address = (rawcode >> 8) & 0xff;
69 	address = rawcode & 0xff;
70 
71 	scancode = ir_nec_bytes_to_scancode(address, not_address,
72 					    command, not_command,
73 					    &rc_proto);
74 	rc_keydown(irdec->rcd, rc_proto, scancode, 0);
75 
76 done:
77 	return IRQ_HANDLED;
78 }
79 
zx_irdec_probe(struct platform_device * pdev)80 static int zx_irdec_probe(struct platform_device *pdev)
81 {
82 	struct device *dev = &pdev->dev;
83 	struct zx_irdec *irdec;
84 	struct resource *res;
85 	struct rc_dev *rcd;
86 	int irq;
87 	int ret;
88 
89 	irdec = devm_kzalloc(dev, sizeof(*irdec), GFP_KERNEL);
90 	if (!irdec)
91 		return -ENOMEM;
92 
93 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
94 	irdec->base = devm_ioremap_resource(dev, res);
95 	if (IS_ERR(irdec->base))
96 		return PTR_ERR(irdec->base);
97 
98 	irq = platform_get_irq(pdev, 0);
99 	if (irq < 0)
100 		return irq;
101 
102 	rcd = devm_rc_allocate_device(dev, RC_DRIVER_SCANCODE);
103 	if (!rcd) {
104 		dev_err(dev, "failed to allocate rc device\n");
105 		return -ENOMEM;
106 	}
107 
108 	irdec->rcd = rcd;
109 
110 	rcd->priv = irdec;
111 	rcd->input_phys = DRIVER_NAME "/input0";
112 	rcd->input_id.bustype = BUS_HOST;
113 	rcd->map_name = RC_MAP_ZX_IRDEC;
114 	rcd->allowed_protocols = RC_PROTO_BIT_NEC | RC_PROTO_BIT_NECX |
115 							RC_PROTO_BIT_NEC32;
116 	rcd->driver_name = DRIVER_NAME;
117 	rcd->device_name = DRIVER_NAME;
118 
119 	platform_set_drvdata(pdev, irdec);
120 
121 	ret = devm_rc_register_device(dev, rcd);
122 	if (ret) {
123 		dev_err(dev, "failed to register rc device\n");
124 		return ret;
125 	}
126 
127 	ret = devm_request_irq(dev, irq, zx_irdec_irq, 0, NULL, irdec);
128 	if (ret) {
129 		dev_err(dev, "failed to request irq\n");
130 		return ret;
131 	}
132 
133 	/*
134 	 * Initialize deglitch level and watchdog counter beginner as
135 	 * recommended by vendor BSP code.
136 	 */
137 	zx_irdec_set_mask(irdec, ZX_IR_CTRL, ZX_DEGL_MASK, ZX_DEGL_VALUE(0));
138 	zx_irdec_set_mask(irdec, ZX_IR_CTRL, ZX_WDBEGIN_MASK,
139 			  ZX_WDBEGIN_VALUE(0x21c));
140 
141 	/* Enable interrupt */
142 	writel(1, irdec->base + ZX_IR_INTEN);
143 
144 	/* Enable the decoder */
145 	zx_irdec_set_mask(irdec, ZX_IR_ENABLE, ZX_IREN, ZX_IREN);
146 
147 	return 0;
148 }
149 
zx_irdec_remove(struct platform_device * pdev)150 static int zx_irdec_remove(struct platform_device *pdev)
151 {
152 	struct zx_irdec *irdec = platform_get_drvdata(pdev);
153 
154 	/* Disable the decoder */
155 	zx_irdec_set_mask(irdec, ZX_IR_ENABLE, ZX_IREN, 0);
156 
157 	/* Disable interrupt */
158 	writel(0, irdec->base + ZX_IR_INTEN);
159 
160 	return 0;
161 }
162 
163 static const struct of_device_id zx_irdec_match[] = {
164 	{ .compatible = "zte,zx296718-irdec" },
165 	{ },
166 };
167 MODULE_DEVICE_TABLE(of, zx_irdec_match);
168 
169 static struct platform_driver zx_irdec_driver = {
170 	.probe = zx_irdec_probe,
171 	.remove = zx_irdec_remove,
172 	.driver = {
173 		.name = DRIVER_NAME,
174 		.of_match_table	= zx_irdec_match,
175 	},
176 };
177 module_platform_driver(zx_irdec_driver);
178 
179 MODULE_DESCRIPTION("ZTE ZX IR remote control driver");
180 MODULE_AUTHOR("Shawn Guo <shawn.guo@linaro.org>");
181 MODULE_LICENSE("GPL v2");
182