1 /* 2 * SMI PCIe driver for DVBSky cards. 3 * 4 * Copyright (C) 2014 Max nibble <nibble.max@gmail.com> 5 * 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. 10 * 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. 15 */ 16 17 #include "smipcie.h" 18 19 #define SMI_SAMPLE_PERIOD 83 20 #define SMI_SAMPLE_IDLEMIN (10000 / SMI_SAMPLE_PERIOD) 21 22 static void smi_ir_enableInterrupt(struct smi_rc *ir) 23 { 24 struct smi_dev *dev = ir->dev; 25 26 smi_write(MSI_INT_ENA_SET, IR_X_INT); 27 } 28 29 static void smi_ir_disableInterrupt(struct smi_rc *ir) 30 { 31 struct smi_dev *dev = ir->dev; 32 33 smi_write(MSI_INT_ENA_CLR, IR_X_INT); 34 } 35 36 static void smi_ir_clearInterrupt(struct smi_rc *ir) 37 { 38 struct smi_dev *dev = ir->dev; 39 40 smi_write(MSI_INT_STATUS_CLR, IR_X_INT); 41 } 42 43 static void smi_ir_stop(struct smi_rc *ir) 44 { 45 struct smi_dev *dev = ir->dev; 46 47 smi_ir_disableInterrupt(ir); 48 smi_clear(IR_Init_Reg, rbIRen); 49 } 50 51 static void smi_raw_process(struct rc_dev *rc_dev, const u8 *buffer, 52 const u8 length) 53 { 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); 64 } 65 } 66 } 67 68 static void smi_ir_decode(struct smi_rc *ir) 69 { 70 struct smi_dev *dev = ir->dev; 71 struct rc_dev *rc_dev = ir->rc_dev; 72 u32 dwIRControl, dwIRData; 73 u8 index, ucIRCount, readLoop; 74 75 dwIRControl = smi_read(IR_Init_Reg); 76 77 if (dwIRControl & rbIRVld) { 78 ucIRCount = (u8) smi_read(IR_Data_Cnt); 79 80 readLoop = ucIRCount/4; 81 if (ucIRCount % 4) 82 readLoop += 1; 83 for (index = 0; index < readLoop; index++) { 84 dwIRData = smi_read(IR_DATA_BUFFER_BASE + (index * 4)); 85 86 ir->irData[index*4 + 0] = (u8)(dwIRData); 87 ir->irData[index*4 + 1] = (u8)(dwIRData >> 8); 88 ir->irData[index*4 + 2] = (u8)(dwIRData >> 16); 89 ir->irData[index*4 + 3] = (u8)(dwIRData >> 24); 90 } 91 smi_raw_process(rc_dev, ir->irData, ucIRCount); 92 smi_set(IR_Init_Reg, rbIRVld); 93 } 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); 106 } 107 108 /* ir functions call by main driver.*/ 109 int smi_ir_irq(struct smi_rc *ir, u32 int_status) 110 { 111 int handled = 0; 112 113 if (int_status & IR_X_INT) { 114 smi_ir_disableInterrupt(ir); 115 smi_ir_clearInterrupt(ir); 116 smi_ir_decode(ir); 117 smi_ir_enableInterrupt(ir); 118 handled = 1; 119 } 120 return handled; 121 } 122 123 void smi_ir_start(struct smi_rc *ir) 124 { 125 struct smi_dev *dev = ir->dev; 126 127 smi_write(IR_Idle_Cnt_Low, 128 (((SMI_SAMPLE_PERIOD - 1) & 0xFFFF) << 16) | 129 (SMI_SAMPLE_IDLEMIN & 0xFFFF)); 130 msleep(20); 131 smi_set(IR_Init_Reg, rbIRen | rbIRhighidle); 132 133 smi_ir_enableInterrupt(ir); 134 } 135 136 int smi_ir_init(struct smi_dev *dev) 137 { 138 int ret; 139 struct rc_dev *rc_dev; 140 struct smi_rc *ir = &dev->ir; 141 142 rc_dev = rc_allocate_device(RC_DRIVER_IR_RAW); 143 if (!rc_dev) 144 return -ENOMEM; 145 146 /* init input device */ 147 snprintf(ir->device_name, sizeof(ir->device_name), "IR (%s)", 148 dev->info->name); 149 snprintf(ir->input_phys, sizeof(ir->input_phys), "pci-%s/ir0", 150 pci_name(dev->pci_dev)); 151 152 rc_dev->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; 153 rc_dev->driver_name = "SMI_PCIe"; 154 rc_dev->input_phys = ir->input_phys; 155 rc_dev->device_name = ir->device_name; 156 rc_dev->input_id.bustype = BUS_PCI; 157 rc_dev->input_id.version = 1; 158 rc_dev->input_id.vendor = dev->pci_dev->subsystem_vendor; 159 rc_dev->input_id.product = dev->pci_dev->subsystem_device; 160 rc_dev->dev.parent = &dev->pci_dev->dev; 161 162 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); 165 166 ir->rc_dev = rc_dev; 167 ir->dev = dev; 168 169 smi_ir_disableInterrupt(ir); 170 171 ret = rc_register_device(rc_dev); 172 if (ret) 173 goto ir_err; 174 175 return 0; 176 ir_err: 177 rc_free_device(rc_dev); 178 return ret; 179 } 180 181 void smi_ir_exit(struct smi_dev *dev) 182 { 183 struct smi_rc *ir = &dev->ir; 184 struct rc_dev *rc_dev = ir->rc_dev; 185 186 smi_ir_stop(ir); 187 rc_unregister_device(rc_dev); 188 ir->rc_dev = NULL; 189 } 190