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

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. smi_ir_enableInterrupt
  2. smi_ir_disableInterrupt
  3. smi_ir_clearInterrupt
  4. smi_ir_stop
  5. smi_raw_process
  6. smi_ir_decode
  7. smi_ir_irq
  8. smi_ir_start
  9. smi_ir_init
  10. smi_ir_exit

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

/* [<][>][^][v][top][bottom][index][help] */