2 * Copyright (C) 2015 Mans Rullgard <mans@mansr.com>
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
10 #include <linux/input.h>
11 #include <linux/module.h>
12 #include <linux/platform_device.h>
13 #include <linux/interrupt.h>
15 #include <linux/clk.h>
17 #include <media/rc-core.h>
19 #define DRIVER_NAME "tango-ir"
21 #define IR_NEC_CTRL 0x00
22 #define IR_NEC_DATA 0x04
24 #define IR_RC5_CLK_DIV 0x0c
25 #define IR_RC5_DATA 0x10
28 #define NEC_TIME_BASE 560
29 #define RC5_TIME_BASE 1778
32 #define RC6_CLKDIV 0x04
33 #define RC6_DATA0 0x08
34 #define RC6_DATA1 0x0c
35 #define RC6_DATA2 0x10
36 #define RC6_DATA3 0x14
37 #define RC6_DATA4 0x18
39 #define RC6_CARRIER 36000
40 #define RC6_TIME_BASE 16
42 #define NEC_CAP(n) ((n) << 24)
43 #define GPIO_SEL(n) ((n) << 16)
44 #define DISABLE_NEC (BIT(4) | BIT(8))
45 #define ENABLE_RC5 (BIT(0) | BIT(9))
46 #define ENABLE_RC6 (BIT(0) | BIT(7))
47 #define ACK_IR_INT (BIT(0) | BIT(1))
48 #define ACK_RC6_INT (BIT(31))
50 #define NEC_ANY (RC_PROTO_BIT_NEC | RC_PROTO_BIT_NECX | RC_PROTO_BIT_NEC32)
53 void __iomem
*rc5_base
;
54 void __iomem
*rc6_base
;
59 static void tango_ir_handle_nec(struct tango_ir
*ir
)
64 v
= readl_relaxed(ir
->rc5_base
+ IR_NEC_DATA
);
70 code
= ir_nec_bytes_to_scancode(v
, v
>> 8, v
>> 16, v
>> 24, &proto
);
71 rc_keydown(ir
->rc
, proto
, code
, 0);
74 static void tango_ir_handle_rc5(struct tango_ir
*ir
)
76 u32 data
, field
, toggle
, addr
, cmd
, code
;
78 data
= readl_relaxed(ir
->rc5_base
+ IR_RC5_DATA
);
82 field
= data
>> 12 & 1;
83 toggle
= data
>> 11 & 1;
84 addr
= data
>> 6 & 0x1f;
85 cmd
= (data
& 0x3f) | (field
^ 1) << 6;
87 code
= RC_SCANCODE_RC5(addr
, cmd
);
88 rc_keydown(ir
->rc
, RC_PROTO_RC5
, code
, toggle
);
91 static void tango_ir_handle_rc6(struct tango_ir
*ir
)
93 u32 data0
, data1
, toggle
, mode
, addr
, cmd
, code
;
95 data0
= readl_relaxed(ir
->rc6_base
+ RC6_DATA0
);
96 data1
= readl_relaxed(ir
->rc6_base
+ RC6_DATA1
);
98 mode
= data0
>> 1 & 7;
106 code
= RC_SCANCODE_RC6_0(addr
, cmd
);
107 rc_keydown(ir
->rc
, RC_PROTO_RC6_0
, code
, toggle
);
110 static irqreturn_t
tango_ir_irq(int irq
, void *dev_id
)
112 struct tango_ir
*ir
= dev_id
;
113 unsigned int rc5_stat
;
114 unsigned int rc6_stat
;
116 rc5_stat
= readl_relaxed(ir
->rc5_base
+ IR_INT
);
117 writel_relaxed(rc5_stat
, ir
->rc5_base
+ IR_INT
);
119 rc6_stat
= readl_relaxed(ir
->rc6_base
+ RC6_CTRL
);
120 writel_relaxed(rc6_stat
, ir
->rc6_base
+ RC6_CTRL
);
122 if (!(rc5_stat
& 3) && !(rc6_stat
& BIT(31)))
125 if (rc5_stat
& BIT(0))
126 tango_ir_handle_rc5(ir
);
128 if (rc5_stat
& BIT(1))
129 tango_ir_handle_nec(ir
);
131 if (rc6_stat
& BIT(31))
132 tango_ir_handle_rc6(ir
);
137 static int tango_change_protocol(struct rc_dev
*dev
, u64
*rc_type
)
139 struct tango_ir
*ir
= dev
->priv
;
140 u32 rc5_ctrl
= DISABLE_NEC
;
143 if (*rc_type
& NEC_ANY
)
146 if (*rc_type
& RC_PROTO_BIT_RC5
)
147 rc5_ctrl
|= ENABLE_RC5
;
149 if (*rc_type
& RC_PROTO_BIT_RC6_0
)
150 rc6_ctrl
= ENABLE_RC6
;
152 writel_relaxed(rc5_ctrl
, ir
->rc5_base
+ IR_CTRL
);
153 writel_relaxed(rc6_ctrl
, ir
->rc6_base
+ RC6_CTRL
);
158 static int tango_ir_probe(struct platform_device
*pdev
)
160 const char *map_name
= RC_MAP_TANGO
;
161 struct device
*dev
= &pdev
->dev
;
164 struct resource
*rc5_res
;
165 struct resource
*rc6_res
;
170 rc5_res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
174 rc6_res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 1);
178 irq
= platform_get_irq(pdev
, 0);
182 ir
= devm_kzalloc(dev
, sizeof(*ir
), GFP_KERNEL
);
186 ir
->rc5_base
= devm_ioremap_resource(dev
, rc5_res
);
187 if (IS_ERR(ir
->rc5_base
))
188 return PTR_ERR(ir
->rc5_base
);
190 ir
->rc6_base
= devm_ioremap_resource(dev
, rc6_res
);
191 if (IS_ERR(ir
->rc6_base
))
192 return PTR_ERR(ir
->rc6_base
);
194 ir
->clk
= devm_clk_get(dev
, NULL
);
196 return PTR_ERR(ir
->clk
);
198 rc
= devm_rc_allocate_device(dev
, RC_DRIVER_SCANCODE
);
202 of_property_read_string(dev
->of_node
, "linux,rc-map-name", &map_name
);
204 rc
->device_name
= DRIVER_NAME
;
205 rc
->driver_name
= DRIVER_NAME
;
206 rc
->input_phys
= DRIVER_NAME
"/input0";
207 rc
->map_name
= map_name
;
208 rc
->allowed_protocols
= NEC_ANY
| RC_PROTO_BIT_RC5
| RC_PROTO_BIT_RC6_0
;
209 rc
->change_protocol
= tango_change_protocol
;
213 err
= clk_prepare_enable(ir
->clk
);
217 clkrate
= clk_get_rate(ir
->clk
);
219 clkdiv
= clkrate
* NEC_TIME_BASE
;
220 do_div(clkdiv
, 1000000);
222 val
= NEC_CAP(31) | GPIO_SEL(12) | clkdiv
;
223 writel_relaxed(val
, ir
->rc5_base
+ IR_NEC_CTRL
);
225 clkdiv
= clkrate
* RC5_TIME_BASE
;
226 do_div(clkdiv
, 1000000);
228 writel_relaxed(DISABLE_NEC
, ir
->rc5_base
+ IR_CTRL
);
229 writel_relaxed(clkdiv
, ir
->rc5_base
+ IR_RC5_CLK_DIV
);
230 writel_relaxed(ACK_IR_INT
, ir
->rc5_base
+ IR_INT
);
232 clkdiv
= clkrate
* RC6_TIME_BASE
;
233 do_div(clkdiv
, RC6_CARRIER
);
235 writel_relaxed(ACK_RC6_INT
, ir
->rc6_base
+ RC6_CTRL
);
236 writel_relaxed((clkdiv
>> 2) << 18 | clkdiv
, ir
->rc6_base
+ RC6_CLKDIV
);
238 err
= devm_request_irq(dev
, irq
, tango_ir_irq
, IRQF_SHARED
,
243 err
= devm_rc_register_device(dev
, rc
);
247 platform_set_drvdata(pdev
, ir
);
251 clk_disable_unprepare(ir
->clk
);
255 static int tango_ir_remove(struct platform_device
*pdev
)
257 struct tango_ir
*ir
= platform_get_drvdata(pdev
);
259 clk_disable_unprepare(ir
->clk
);
263 static const struct of_device_id tango_ir_dt_ids
[] = {
264 { .compatible
= "sigma,smp8642-ir" },
267 MODULE_DEVICE_TABLE(of
, tango_ir_dt_ids
);
269 static struct platform_driver tango_ir_driver
= {
270 .probe
= tango_ir_probe
,
271 .remove
= tango_ir_remove
,
274 .of_match_table
= tango_ir_dt_ids
,
277 module_platform_driver(tango_ir_driver
);
279 MODULE_DESCRIPTION("SMP86xx IR decoder driver");
280 MODULE_AUTHOR("Mans Rullgard <mans@mansr.com>");
281 MODULE_LICENSE("GPL");