Skip to content

Commit a49a7a4

Browse files
Patrick Lerdamchehab
authored andcommitted
media: smipcie: add universal ir capability
smipcie: switch to RC_DRIVER_IR_RAW. Signed-off-by: Patrick Lerda <patrick9876@free.fr> Signed-off-by: Sean Young <sean@mess.org> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
1 parent b1f3775 commit a49a7a4

File tree

2 files changed

+45
-88
lines changed

2 files changed

+45
-88
lines changed

drivers/media/pci/smipcie/smipcie-ir.c

Lines changed: 45 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616

1717
#include "smipcie.h"
1818

19+
#define SMI_SAMPLE_PERIOD 83
20+
#define SMI_SAMPLE_IDLEMIN (10000 / SMI_SAMPLE_PERIOD)
21+
1922
static void smi_ir_enableInterrupt(struct smi_rc *ir)
2023
{
2124
struct smi_dev *dev = ir->dev;
@@ -42,114 +45,64 @@ static void smi_ir_stop(struct smi_rc *ir)
4245
struct smi_dev *dev = ir->dev;
4346

4447
smi_ir_disableInterrupt(ir);
45-
smi_clear(IR_Init_Reg, 0x80);
48+
smi_clear(IR_Init_Reg, rbIRen);
4649
}
4750

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)
51+
static void smi_raw_process(struct rc_dev *rc_dev, const u8 *buffer,
52+
const u8 length)
5353
{
54-
u8 index, current_bit, bit_count;
55-
u8 group_array[BITS_PER_COMMAND * GROUPS_PER_BIT + 4];
56-
u8 group_index = 0;
57-
u32 command = 0xFFFFFFFF;
58-
59-
group_array[group_index++] = 1;
60-
61-
for (index = 0; index < size; index++) {
62-
63-
current_bit = (pData[index] & 0x80) ? 1 : 0;
64-
bit_count = pData[index] & 0x7f;
65-
66-
if ((current_bit == 1) && (bit_count >= 2*IR_RC5_MAX_BIT + 1)) {
67-
goto process_code;
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;
75-
} else {
76-
goto invalid_timing;
77-
}
78-
if (group_index >= BITS_PER_COMMAND*GROUPS_PER_BIT)
79-
goto process_code;
80-
81-
if ((group_index == BITS_PER_COMMAND*GROUPS_PER_BIT - 1)
82-
&& (group_array[group_index-1] == 0)) {
83-
group_array[group_index++] = 1;
84-
goto process_code;
85-
}
86-
}
87-
88-
process_code:
89-
if (group_index == (BITS_PER_COMMAND*GROUPS_PER_BIT-1))
90-
group_array[group_index++] = 1;
91-
92-
if (group_index == BITS_PER_COMMAND*GROUPS_PER_BIT) {
93-
command = 0;
94-
for (index = 0; index < (BITS_PER_COMMAND*GROUPS_PER_BIT);
95-
index = index + 2) {
96-
if ((group_array[index] == 1) &&
97-
(group_array[index+1] == 0)) {
98-
command |= (1 << (BITS_PER_COMMAND -
99-
(index/2) - 1));
100-
} else if ((group_array[index] == 0) &&
101-
(group_array[index+1] == 1)) {
102-
/* */
103-
} else {
104-
command = 0xFFFFFFFF;
105-
goto invalid_timing;
106-
}
54+
struct ir_raw_event rawir = {};
55+
int cnt;
56+
57+
for (cnt = 0; cnt < length; cnt++) {
58+
if (buffer[cnt] & 0x7f) {
59+
rawir.pulse = (buffer[cnt] & 0x80) == 0;
60+
rawir.duration = ((buffer[cnt] & 0x7f) +
61+
(rawir.pulse ? 0 : -1)) *
62+
rc_dev->rx_resolution;
63+
ir_raw_event_store_with_filter(rc_dev, &rawir);
10764
}
10865
}
109-
110-
invalid_timing:
111-
return command;
11266
}
11367

114-
static void smi_ir_decode(struct work_struct *work)
68+
static void smi_ir_decode(struct smi_rc *ir)
11569
{
116-
struct smi_rc *ir = container_of(work, struct smi_rc, work);
11770
struct smi_dev *dev = ir->dev;
11871
struct rc_dev *rc_dev = ir->rc_dev;
119-
u32 dwIRControl, dwIRData, dwIRCode, scancode;
120-
u8 index, ucIRCount, readLoop, rc5_command, rc5_system, toggle;
72+
u32 dwIRControl, dwIRData;
73+
u8 index, ucIRCount, readLoop;
12174

12275
dwIRControl = smi_read(IR_Init_Reg);
76+
12377
if (dwIRControl & rbIRVld) {
12478
ucIRCount = (u8) smi_read(IR_Data_Cnt);
12579

126-
if (ucIRCount < 4)
127-
goto end_ir_decode;
128-
12980
readLoop = ucIRCount/4;
13081
if (ucIRCount % 4)
13182
readLoop += 1;
13283
for (index = 0; index < readLoop; index++) {
133-
dwIRData = smi_read(IR_DATA_BUFFER_BASE + (index*4));
84+
dwIRData = smi_read(IR_DATA_BUFFER_BASE + (index * 4));
13485

13586
ir->irData[index*4 + 0] = (u8)(dwIRData);
13687
ir->irData[index*4 + 1] = (u8)(dwIRData >> 8);
13788
ir->irData[index*4 + 2] = (u8)(dwIRData >> 16);
13889
ir->irData[index*4 + 3] = (u8)(dwIRData >> 24);
13990
}
140-
dwIRCode = smi_decode_rc5(ir->irData, ucIRCount);
141-
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_PROTO_RC5, scancode, toggle);
148-
}
91+
smi_raw_process(rc_dev, ir->irData, ucIRCount);
92+
smi_set(IR_Init_Reg, rbIRVld);
14993
}
150-
end_ir_decode:
151-
smi_set(IR_Init_Reg, 0x04);
152-
smi_ir_enableInterrupt(ir);
94+
95+
if (dwIRControl & rbIRhighidle) {
96+
struct ir_raw_event rawir = {};
97+
98+
rawir.pulse = 0;
99+
rawir.duration = US_TO_NS(SMI_SAMPLE_PERIOD *
100+
SMI_SAMPLE_IDLEMIN);
101+
ir_raw_event_store_with_filter(rc_dev, &rawir);
102+
smi_set(IR_Init_Reg, rbIRhighidle);
103+
}
104+
105+
ir_raw_event_handle(rc_dev);
153106
}
154107

155108
/* ir functions call by main driver.*/
@@ -160,7 +113,8 @@ int smi_ir_irq(struct smi_rc *ir, u32 int_status)
160113
if (int_status & IR_X_INT) {
161114
smi_ir_disableInterrupt(ir);
162115
smi_ir_clearInterrupt(ir);
163-
schedule_work(&ir->work);
116+
smi_ir_decode(ir);
117+
smi_ir_enableInterrupt(ir);
164118
handled = 1;
165119
}
166120
return handled;
@@ -170,9 +124,11 @@ void smi_ir_start(struct smi_rc *ir)
170124
{
171125
struct smi_dev *dev = ir->dev;
172126

173-
smi_write(IR_Idle_Cnt_Low, 0x00140070);
127+
smi_write(IR_Idle_Cnt_Low,
128+
(((SMI_SAMPLE_PERIOD - 1) & 0xFFFF) << 16) |
129+
(SMI_SAMPLE_IDLEMIN & 0xFFFF));
174130
msleep(20);
175-
smi_set(IR_Init_Reg, 0x90);
131+
smi_set(IR_Init_Reg, rbIRen | rbIRhighidle);
176132

177133
smi_ir_enableInterrupt(ir);
178134
}
@@ -183,7 +139,7 @@ int smi_ir_init(struct smi_dev *dev)
183139
struct rc_dev *rc_dev;
184140
struct smi_rc *ir = &dev->ir;
185141

186-
rc_dev = rc_allocate_device(RC_DRIVER_SCANCODE);
142+
rc_dev = rc_allocate_device(RC_DRIVER_IR_RAW);
187143
if (!rc_dev)
188144
return -ENOMEM;
189145

@@ -193,6 +149,7 @@ int smi_ir_init(struct smi_dev *dev)
193149
snprintf(ir->input_phys, sizeof(ir->input_phys), "pci-%s/ir0",
194150
pci_name(dev->pci_dev));
195151

152+
rc_dev->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER;
196153
rc_dev->driver_name = "SMI_PCIe";
197154
rc_dev->input_phys = ir->input_phys;
198155
rc_dev->device_name = ir->device_name;
@@ -203,11 +160,12 @@ int smi_ir_init(struct smi_dev *dev)
203160
rc_dev->dev.parent = &dev->pci_dev->dev;
204161

205162
rc_dev->map_name = dev->info->rc_map;
163+
rc_dev->timeout = MS_TO_NS(100);
164+
rc_dev->rx_resolution = US_TO_NS(SMI_SAMPLE_PERIOD);
206165

207166
ir->rc_dev = rc_dev;
208167
ir->dev = dev;
209168

210-
INIT_WORK(&ir->work, smi_ir_decode);
211169
smi_ir_disableInterrupt(ir);
212170

213171
ret = rc_register_device(rc_dev);

drivers/media/pci/smipcie/smipcie.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,6 @@ struct smi_rc {
241241
struct rc_dev *rc_dev;
242242
char input_phys[64];
243243
char device_name[64];
244-
struct work_struct work;
245244
u8 irData[256];
246245

247246
int users;

0 commit comments

Comments
 (0)