示例#1
0
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;
}
示例#2
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);
}
示例#3
0
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);
}
示例#4
0
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;
}
示例#5
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;
}
示例#6
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;
}