static int wbcir_set_carrier_report(struct rc_dev *dev, int enable) { struct wbcir_data *data = dev->priv; unsigned long flags; spin_lock_irqsave(&data->spinlock, flags); if (data->carrier_report_enabled == enable) { spin_unlock_irqrestore(&data->spinlock, flags); return 0; } data->pulse_duration = 0; wbcir_set_bits(data->ebase + WBCIR_REG_ECEIR_CCTL, WBCIR_CNTR_R, WBCIR_CNTR_EN | WBCIR_CNTR_R); if (enable && data->dev->idle) wbcir_set_bits(data->ebase + WBCIR_REG_ECEIR_CCTL, WBCIR_CNTR_EN, WBCIR_CNTR_EN | WBCIR_CNTR_R); data->carrier_report_enabled = enable; spin_unlock_irqrestore(&data->spinlock, flags); return 0; }
static void wbcir_led_brightness_set(struct led_classdev *led_cdev, enum led_brightness brightness) { struct wbcir_data *data = container_of(led_cdev, struct wbcir_data, led); wbcir_set_bits(data->ebase + WBCIR_REG_ECEIR_CTS, brightness == LED_OFF ? 0x00 : WBCIR_LED_ENABLE, WBCIR_LED_ENABLE); }
static void wbcir_carrier_report(struct wbcir_data *data) { unsigned counter = inb(data->ebase + WBCIR_REG_ECEIR_CNT_LO) | inb(data->ebase + WBCIR_REG_ECEIR_CNT_HI) << 8; if (counter > 0 && counter < 0xffff) { DEFINE_IR_RAW_EVENT(ev); ev.carrier_report = 1; ev.carrier = DIV_ROUND_CLOSEST(counter * 1000000u, data->pulse_duration); ir_raw_event_store(data->dev, &ev); } /* reset and restart the counter */ data->pulse_duration = 0; wbcir_set_bits(data->ebase + WBCIR_REG_ECEIR_CCTL, WBCIR_CNTR_R, WBCIR_CNTR_EN | WBCIR_CNTR_R); wbcir_set_bits(data->ebase + WBCIR_REG_ECEIR_CCTL, WBCIR_CNTR_EN, WBCIR_CNTR_EN | WBCIR_CNTR_R); }
static int wbcir_set_carrier_report(struct rc_dev *dev, int enable) { struct wbcir_data *data = dev->priv; unsigned long flags; spin_lock_irqsave(&data->spinlock, flags); if (data->carrier_report_enabled == enable) { spin_unlock_irqrestore(&data->spinlock, flags); return 0; } data->pulse_duration = 0; wbcir_set_bits(data->ebase + WBCIR_REG_ECEIR_CCTL, WBCIR_CNTR_R, WBCIR_CNTR_EN | WBCIR_CNTR_R); if (enable && data->dev->idle) wbcir_set_bits(data->ebase + WBCIR_REG_ECEIR_CCTL, WBCIR_CNTR_EN, WBCIR_CNTR_EN | WBCIR_CNTR_R); /* Set a higher sampling resolution if carrier reports are enabled */ wbcir_select_bank(data, WBCIR_BANK_2); data->dev->rx_resolution = US_TO_NS(enable ? 2 : 10); outb(enable ? 0x03 : 0x0f, data->sbase + WBCIR_REG_SP3_BGDL); outb(0x00, data->sbase + WBCIR_REG_SP3_BGDH); /* Enable oversampling if carrier reports are enabled */ wbcir_select_bank(data, WBCIR_BANK_7); wbcir_set_bits(data->sbase + WBCIR_REG_SP3_RCCFG, enable ? WBCIR_RX_T_OV : 0, WBCIR_RX_T_OV); data->carrier_report_enabled = enable; spin_unlock_irqrestore(&data->spinlock, flags); return 0; }
static int wbcir_txcarrier(struct rc_dev *dev, u32 carrier) { struct wbcir_data *data = dev->priv; unsigned long flags; u8 val; u32 freq; freq = DIV_ROUND_CLOSEST(carrier, 1000); if (freq < 30 || freq > 60) return -EINVAL; switch (freq) { case 58: case 59: case 60: val = freq - 58; freq *= 1000; break; case 57: val = freq - 27; freq = 56900; break; default: val = freq - 27; freq *= 1000; break; } spin_lock_irqsave(&data->spinlock, flags); if (data->txstate != WBCIR_TXSTATE_INACTIVE) { spin_unlock_irqrestore(&data->spinlock, flags); return -EBUSY; } if (data->txcarrier != freq) { wbcir_select_bank(data, WBCIR_BANK_7); wbcir_set_bits(data->sbase + WBCIR_REG_SP3_IRTXMC, val, 0x1F); data->txcarrier = freq; } spin_unlock_irqrestore(&data->spinlock, flags); return 0; }
static int wbcir_txmask(struct rc_dev *dev, u32 mask) { struct wbcir_data *data = dev->priv; unsigned long flags; u8 val; /* return the number of transmitters */ if (mask > 15) return 4; /* Four outputs, only one output can be enabled at a time */ switch (mask) { case 0x1: val = 0x0; break; case 0x2: val = 0x1; break; case 0x4: val = 0x2; break; case 0x8: val = 0x3; break; default: return -EINVAL; } spin_lock_irqsave(&data->spinlock, flags); if (data->txstate != WBCIR_TXSTATE_INACTIVE) { spin_unlock_irqrestore(&data->spinlock, flags); return -EBUSY; } if (data->txmask != mask) { wbcir_set_bits(data->ebase + WBCIR_REG_ECEIR_CTS, val, 0x0c); data->txmask = mask; } spin_unlock_irqrestore(&data->spinlock, flags); return 0; }
static int wbcir_txmask(struct rc_dev *dev, u32 mask) { struct wbcir_data *data = dev->priv; unsigned long flags; u8 val; switch (mask) { case 0x1: val = 0x0; break; case 0x2: val = 0x1; break; case 0x4: val = 0x2; break; case 0x8: val = 0x3; break; default: return -EINVAL; } spin_lock_irqsave(&data->spinlock, flags); if (data->txstate != WBCIR_TXSTATE_INACTIVE) { spin_unlock_irqrestore(&data->spinlock, flags); return -EBUSY; } if (data->txmask != mask) { wbcir_set_bits(data->ebase + WBCIR_REG_ECEIR_CTS, val, 0x0c); data->txmask = mask; } spin_unlock_irqrestore(&data->spinlock, flags); return 0; }