2 * Copyright (C) 2017 Sanechips Technology Co., Ltd.
3 * Copyright 2017 Linaro Ltd.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
10 #include <linux/device.h>
11 #include <linux/err.h>
12 #include <linux/interrupt.h>
14 #include <linux/module.h>
15 #include <linux/of_platform.h>
16 #include <linux/platform_device.h>
18 #include <media/rc-core.h>
20 #define DRIVER_NAME "zx-irdec"
22 #define ZX_IR_ENABLE 0x04
23 #define ZX_IREN BIT(0)
24 #define ZX_IR_CTRL 0x08
25 #define ZX_DEGL_MASK GENMASK(21, 20)
26 #define ZX_DEGL_VALUE(x) (((x) << 20) & ZX_DEGL_MASK)
27 #define ZX_WDBEGIN_MASK GENMASK(18, 8)
28 #define ZX_WDBEGIN_VALUE(x) (((x) << 8) & ZX_WDBEGIN_MASK)
29 #define ZX_IR_INTEN 0x10
30 #define ZX_IR_INTSTCLR 0x14
31 #define ZX_IR_CODE 0x30
32 #define ZX_IR_CNUM 0x34
33 #define ZX_NECRPT BIT(16)
40 static void zx_irdec_set_mask(struct zx_irdec
*irdec
, unsigned int reg
,
45 data
= readl(irdec
->base
+ reg
);
48 writel(data
, irdec
->base
+ reg
);
51 static irqreturn_t
zx_irdec_irq(int irq
, void *dev_id
)
53 struct zx_irdec
*irdec
= dev_id
;
54 u8 address
, not_address
;
55 u8 command
, not_command
;
56 u32 rawcode
, scancode
;
57 enum rc_proto rc_proto
;
60 writel(1, irdec
->base
+ ZX_IR_INTSTCLR
);
62 /* Check repeat frame */
63 if (readl(irdec
->base
+ ZX_IR_CNUM
) & ZX_NECRPT
) {
64 rc_repeat(irdec
->rcd
);
68 rawcode
= readl(irdec
->base
+ ZX_IR_CODE
);
69 not_command
= (rawcode
>> 24) & 0xff;
70 command
= (rawcode
>> 16) & 0xff;
71 not_address
= (rawcode
>> 8) & 0xff;
72 address
= rawcode
& 0xff;
74 scancode
= ir_nec_bytes_to_scancode(address
, not_address
,
77 rc_keydown(irdec
->rcd
, rc_proto
, scancode
, 0);
83 static int zx_irdec_probe(struct platform_device
*pdev
)
85 struct device
*dev
= &pdev
->dev
;
86 struct zx_irdec
*irdec
;
92 irdec
= devm_kzalloc(dev
, sizeof(*irdec
), GFP_KERNEL
);
96 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
97 irdec
->base
= devm_ioremap_resource(dev
, res
);
98 if (IS_ERR(irdec
->base
))
99 return PTR_ERR(irdec
->base
);
101 irq
= platform_get_irq(pdev
, 0);
105 rcd
= devm_rc_allocate_device(dev
, RC_DRIVER_SCANCODE
);
107 dev_err(dev
, "failed to allocate rc device\n");
114 rcd
->input_phys
= DRIVER_NAME
"/input0";
115 rcd
->input_id
.bustype
= BUS_HOST
;
116 rcd
->map_name
= RC_MAP_ZX_IRDEC
;
117 rcd
->allowed_protocols
= RC_PROTO_BIT_NEC
| RC_PROTO_BIT_NECX
|
119 rcd
->driver_name
= DRIVER_NAME
;
120 rcd
->device_name
= DRIVER_NAME
;
122 platform_set_drvdata(pdev
, irdec
);
124 ret
= devm_rc_register_device(dev
, rcd
);
126 dev_err(dev
, "failed to register rc device\n");
130 ret
= devm_request_irq(dev
, irq
, zx_irdec_irq
, 0, NULL
, irdec
);
132 dev_err(dev
, "failed to request irq\n");
137 * Initialize deglitch level and watchdog counter beginner as
138 * recommended by vendor BSP code.
140 zx_irdec_set_mask(irdec
, ZX_IR_CTRL
, ZX_DEGL_MASK
, ZX_DEGL_VALUE(0));
141 zx_irdec_set_mask(irdec
, ZX_IR_CTRL
, ZX_WDBEGIN_MASK
,
142 ZX_WDBEGIN_VALUE(0x21c));
144 /* Enable interrupt */
145 writel(1, irdec
->base
+ ZX_IR_INTEN
);
147 /* Enable the decoder */
148 zx_irdec_set_mask(irdec
, ZX_IR_ENABLE
, ZX_IREN
, ZX_IREN
);
153 static int zx_irdec_remove(struct platform_device
*pdev
)
155 struct zx_irdec
*irdec
= platform_get_drvdata(pdev
);
157 /* Disable the decoder */
158 zx_irdec_set_mask(irdec
, ZX_IR_ENABLE
, ZX_IREN
, 0);
160 /* Disable interrupt */
161 writel(0, irdec
->base
+ ZX_IR_INTEN
);
166 static const struct of_device_id zx_irdec_match
[] = {
167 { .compatible
= "zte,zx296718-irdec" },
170 MODULE_DEVICE_TABLE(of
, zx_irdec_match
);
172 static struct platform_driver zx_irdec_driver
= {
173 .probe
= zx_irdec_probe
,
174 .remove
= zx_irdec_remove
,
177 .of_match_table
= zx_irdec_match
,
180 module_platform_driver(zx_irdec_driver
);
182 MODULE_DESCRIPTION("ZTE ZX IR remote control driver");
183 MODULE_AUTHOR("Shawn Guo <shawn.guo@linaro.org>");
184 MODULE_LICENSE("GPL v2");