1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * SMI PCIe driver for DVBSky cards.
5 * Copyright (C) 2014 Max nibble <nibble.max@gmail.com>
10 #define SMI_SAMPLE_PERIOD 83
11 #define SMI_SAMPLE_IDLEMIN (10000 / SMI_SAMPLE_PERIOD)
13 static void smi_ir_enableInterrupt(struct smi_rc
*ir
)
15 struct smi_dev
*dev
= ir
->dev
;
17 smi_write(MSI_INT_ENA_SET
, IR_X_INT
);
20 static void smi_ir_disableInterrupt(struct smi_rc
*ir
)
22 struct smi_dev
*dev
= ir
->dev
;
24 smi_write(MSI_INT_ENA_CLR
, IR_X_INT
);
27 static void smi_ir_clearInterrupt(struct smi_rc
*ir
)
29 struct smi_dev
*dev
= ir
->dev
;
31 smi_write(MSI_INT_STATUS_CLR
, IR_X_INT
);
34 static void smi_ir_stop(struct smi_rc
*ir
)
36 struct smi_dev
*dev
= ir
->dev
;
38 smi_ir_disableInterrupt(ir
);
39 smi_clear(IR_Init_Reg
, rbIRen
);
42 static void smi_raw_process(struct rc_dev
*rc_dev
, const u8
*buffer
,
45 struct ir_raw_event rawir
= {};
48 for (cnt
= 0; cnt
< length
; cnt
++) {
49 if (buffer
[cnt
] & 0x7f) {
50 rawir
.pulse
= (buffer
[cnt
] & 0x80) == 0;
51 rawir
.duration
= ((buffer
[cnt
] & 0x7f) +
52 (rawir
.pulse
? 0 : -1)) *
53 rc_dev
->rx_resolution
;
54 ir_raw_event_store_with_filter(rc_dev
, &rawir
);
59 static void smi_ir_decode(struct smi_rc
*ir
)
61 struct smi_dev
*dev
= ir
->dev
;
62 struct rc_dev
*rc_dev
= ir
->rc_dev
;
63 u32 dwIRControl
, dwIRData
;
64 u8 index
, ucIRCount
, readLoop
;
66 dwIRControl
= smi_read(IR_Init_Reg
);
68 if (dwIRControl
& rbIRVld
) {
69 ucIRCount
= (u8
) smi_read(IR_Data_Cnt
);
71 readLoop
= ucIRCount
/4;
74 for (index
= 0; index
< readLoop
; index
++) {
75 dwIRData
= smi_read(IR_DATA_BUFFER_BASE
+ (index
* 4));
77 ir
->irData
[index
*4 + 0] = (u8
)(dwIRData
);
78 ir
->irData
[index
*4 + 1] = (u8
)(dwIRData
>> 8);
79 ir
->irData
[index
*4 + 2] = (u8
)(dwIRData
>> 16);
80 ir
->irData
[index
*4 + 3] = (u8
)(dwIRData
>> 24);
82 smi_raw_process(rc_dev
, ir
->irData
, ucIRCount
);
83 smi_set(IR_Init_Reg
, rbIRVld
);
86 if (dwIRControl
& rbIRhighidle
) {
87 struct ir_raw_event rawir
= {};
90 rawir
.duration
= SMI_SAMPLE_PERIOD
* SMI_SAMPLE_IDLEMIN
;
91 ir_raw_event_store_with_filter(rc_dev
, &rawir
);
92 smi_set(IR_Init_Reg
, rbIRhighidle
);
95 ir_raw_event_handle(rc_dev
);
98 /* ir functions call by main driver.*/
99 int smi_ir_irq(struct smi_rc
*ir
, u32 int_status
)
103 if (int_status
& IR_X_INT
) {
104 smi_ir_disableInterrupt(ir
);
105 smi_ir_clearInterrupt(ir
);
107 smi_ir_enableInterrupt(ir
);
113 void smi_ir_start(struct smi_rc
*ir
)
115 struct smi_dev
*dev
= ir
->dev
;
117 smi_write(IR_Idle_Cnt_Low
,
118 (((SMI_SAMPLE_PERIOD
- 1) & 0xFFFF) << 16) |
119 (SMI_SAMPLE_IDLEMIN
& 0xFFFF));
121 smi_set(IR_Init_Reg
, rbIRen
| rbIRhighidle
);
123 smi_ir_enableInterrupt(ir
);
126 int smi_ir_init(struct smi_dev
*dev
)
129 struct rc_dev
*rc_dev
;
130 struct smi_rc
*ir
= &dev
->ir
;
132 rc_dev
= rc_allocate_device(RC_DRIVER_IR_RAW
);
136 /* init input device */
137 snprintf(ir
->device_name
, sizeof(ir
->device_name
), "IR (%s)",
139 snprintf(ir
->input_phys
, sizeof(ir
->input_phys
), "pci-%s/ir0",
140 pci_name(dev
->pci_dev
));
142 rc_dev
->allowed_protocols
= RC_PROTO_BIT_ALL_IR_DECODER
;
143 rc_dev
->driver_name
= "SMI_PCIe";
144 rc_dev
->input_phys
= ir
->input_phys
;
145 rc_dev
->device_name
= ir
->device_name
;
146 rc_dev
->input_id
.bustype
= BUS_PCI
;
147 rc_dev
->input_id
.version
= 1;
148 rc_dev
->input_id
.vendor
= dev
->pci_dev
->subsystem_vendor
;
149 rc_dev
->input_id
.product
= dev
->pci_dev
->subsystem_device
;
150 rc_dev
->dev
.parent
= &dev
->pci_dev
->dev
;
152 rc_dev
->map_name
= dev
->info
->rc_map
;
153 rc_dev
->timeout
= MS_TO_US(100);
154 rc_dev
->rx_resolution
= SMI_SAMPLE_PERIOD
;
159 smi_ir_disableInterrupt(ir
);
161 ret
= rc_register_device(rc_dev
);
167 rc_free_device(rc_dev
);
171 void smi_ir_exit(struct smi_dev
*dev
)
173 struct smi_rc
*ir
= &dev
->ir
;
174 struct rc_dev
*rc_dev
= ir
->rc_dev
;
177 rc_unregister_device(rc_dev
);