2 * SMI PCIe driver for DVBSky cards.
4 * Copyright (C) 2014 Max nibble <nibble.max@gmail.com>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
19 static void smi_ir_enableInterrupt(struct smi_rc
*ir
)
21 struct smi_dev
*dev
= ir
->dev
;
23 smi_write(MSI_INT_ENA_SET
, IR_X_INT
);
26 static void smi_ir_disableInterrupt(struct smi_rc
*ir
)
28 struct smi_dev
*dev
= ir
->dev
;
30 smi_write(MSI_INT_ENA_CLR
, IR_X_INT
);
33 static void smi_ir_clearInterrupt(struct smi_rc
*ir
)
35 struct smi_dev
*dev
= ir
->dev
;
37 smi_write(MSI_INT_STATUS_CLR
, IR_X_INT
);
40 static void smi_ir_stop(struct smi_rc
*ir
)
42 struct smi_dev
*dev
= ir
->dev
;
44 smi_ir_disableInterrupt(ir
);
45 smi_clear(IR_Init_Reg
, 0x80);
48 #define BITS_PER_COMMAND 14
49 #define GROUPS_PER_BIT 2
50 #define IR_RC5_MIN_BIT 36
51 #define IR_RC5_MAX_BIT 52
52 static u32
smi_decode_rc5(u8
*pData
, u8 size
)
54 u8 index
, current_bit
, bit_count
;
55 u8 group_array
[BITS_PER_COMMAND
* GROUPS_PER_BIT
+ 4];
57 u32 command
= 0xFFFFFFFF;
59 group_array
[group_index
++] = 1;
61 for (index
= 0; index
< size
; index
++) {
63 current_bit
= (pData
[index
] & 0x80) ? 1 : 0;
64 bit_count
= pData
[index
] & 0x7f;
66 if ((current_bit
== 1) && (bit_count
>= 2*IR_RC5_MAX_BIT
+ 1)) {
68 } else if ((bit_count
>= IR_RC5_MIN_BIT
) &&
69 (bit_count
<= IR_RC5_MAX_BIT
)) {
70 group_array
[group_index
++] = current_bit
;
71 } else if ((bit_count
> IR_RC5_MAX_BIT
) &&
72 (bit_count
<= 2*IR_RC5_MAX_BIT
)) {
73 group_array
[group_index
++] = current_bit
;
74 group_array
[group_index
++] = current_bit
;
78 if (group_index
>= BITS_PER_COMMAND
*GROUPS_PER_BIT
)
81 if ((group_index
== BITS_PER_COMMAND
*GROUPS_PER_BIT
- 1)
82 && (group_array
[group_index
-1] == 0)) {
83 group_array
[group_index
++] = 1;
89 if (group_index
== (BITS_PER_COMMAND
*GROUPS_PER_BIT
-1))
90 group_array
[group_index
++] = 1;
92 if (group_index
== BITS_PER_COMMAND
*GROUPS_PER_BIT
) {
94 for (index
= 0; index
< (BITS_PER_COMMAND
*GROUPS_PER_BIT
);
96 if ((group_array
[index
] == 1) &&
97 (group_array
[index
+1] == 0)) {
98 command
|= (1 << (BITS_PER_COMMAND
-
100 } else if ((group_array
[index
] == 0) &&
101 (group_array
[index
+1] == 1)) {
104 command
= 0xFFFFFFFF;
114 static void smi_ir_decode(struct work_struct
*work
)
116 struct smi_rc
*ir
= container_of(work
, struct smi_rc
, work
);
117 struct smi_dev
*dev
= ir
->dev
;
118 struct rc_dev
*rc_dev
= ir
->rc_dev
;
119 u32 dwIRControl
, dwIRData
, dwIRCode
, scancode
;
120 u8 index
, ucIRCount
, readLoop
, rc5_command
, rc5_system
, toggle
;
122 dwIRControl
= smi_read(IR_Init_Reg
);
123 if (dwIRControl
& rbIRVld
) {
124 ucIRCount
= (u8
) smi_read(IR_Data_Cnt
);
129 readLoop
= ucIRCount
/4;
132 for (index
= 0; index
< readLoop
; index
++) {
133 dwIRData
= smi_read(IR_DATA_BUFFER_BASE
+ (index
*4));
135 ir
->irData
[index
*4 + 0] = (u8
)(dwIRData
);
136 ir
->irData
[index
*4 + 1] = (u8
)(dwIRData
>> 8);
137 ir
->irData
[index
*4 + 2] = (u8
)(dwIRData
>> 16);
138 ir
->irData
[index
*4 + 3] = (u8
)(dwIRData
>> 24);
140 dwIRCode
= smi_decode_rc5(ir
->irData
, ucIRCount
);
142 if (dwIRCode
!= 0xFFFFFFFF) {
143 rc5_command
= dwIRCode
& 0x3F;
144 rc5_system
= (dwIRCode
& 0x7C0) >> 6;
145 toggle
= (dwIRCode
& 0x800) ? 1 : 0;
146 scancode
= rc5_system
<< 8 | rc5_command
;
147 rc_keydown(rc_dev
, RC_TYPE_RC5
, scancode
, toggle
);
151 smi_set(IR_Init_Reg
, 0x04);
152 smi_ir_enableInterrupt(ir
);
155 /* ir functions call by main driver.*/
156 int smi_ir_irq(struct smi_rc
*ir
, u32 int_status
)
160 if (int_status
& IR_X_INT
) {
161 smi_ir_disableInterrupt(ir
);
162 smi_ir_clearInterrupt(ir
);
163 schedule_work(&ir
->work
);
169 void smi_ir_start(struct smi_rc
*ir
)
171 struct smi_dev
*dev
= ir
->dev
;
173 smi_write(IR_Idle_Cnt_Low
, 0x00140070);
175 smi_set(IR_Init_Reg
, 0x90);
177 smi_ir_enableInterrupt(ir
);
180 int smi_ir_init(struct smi_dev
*dev
)
183 struct rc_dev
*rc_dev
;
184 struct smi_rc
*ir
= &dev
->ir
;
186 rc_dev
= rc_allocate_device();
190 /* init input device */
191 snprintf(ir
->input_name
, sizeof(ir
->input_name
), "IR (%s)",
193 snprintf(ir
->input_phys
, sizeof(ir
->input_phys
), "pci-%s/ir0",
194 pci_name(dev
->pci_dev
));
196 rc_dev
->driver_name
= "SMI_PCIe";
197 rc_dev
->input_phys
= ir
->input_phys
;
198 rc_dev
->input_name
= ir
->input_name
;
199 rc_dev
->input_id
.bustype
= BUS_PCI
;
200 rc_dev
->input_id
.version
= 1;
201 rc_dev
->input_id
.vendor
= dev
->pci_dev
->subsystem_vendor
;
202 rc_dev
->input_id
.product
= dev
->pci_dev
->subsystem_device
;
203 rc_dev
->dev
.parent
= &dev
->pci_dev
->dev
;
205 rc_dev
->driver_type
= RC_DRIVER_SCANCODE
;
206 rc_dev
->map_name
= RC_MAP_DVBSKY
;
211 INIT_WORK(&ir
->work
, smi_ir_decode
);
212 smi_ir_disableInterrupt(ir
);
214 ret
= rc_register_device(rc_dev
);
220 rc_free_device(rc_dev
);
224 void smi_ir_exit(struct smi_dev
*dev
)
226 struct smi_rc
*ir
= &dev
->ir
;
227 struct rc_dev
*rc_dev
= ir
->rc_dev
;
230 rc_unregister_device(rc_dev
);