Exemplo n.º 1
0
static void rotary_encoder_resume(struct device_t * dev)
{
	struct input_t * input = (struct input_t *)dev->priv;
	struct rotary_encoder_pdata_t * pdat = (struct rotary_encoder_pdata_t *)input->priv;

	enable_irq(pdat->irqa);
	enable_irq(pdat->irqb);
	if(gpio_is_valid(pdat->c) && irq_is_valid(pdat->irqc))
		enable_irq(pdat->irqc);
}
Exemplo n.º 2
0
static struct device_t * irq_rk3288_gpio_probe(struct driver_t * drv, struct dtnode_t * n)
{
	struct irq_rk3288_gpio_pdata_t * pdat;
	struct irqchip_t * chip;
	struct device_t * dev;
	virtual_addr_t virt = phys_to_virt(dt_read_address(n));
	int base = dt_read_int(n, "interrupt-base", -1);
	int nirq = dt_read_int(n, "interrupt-count", -1);
	int parent = dt_read_int(n, "interrupt-parent", -1);

	if((base < 0) || (nirq <= 0) || !irq_is_valid(parent))
		return NULL;

	pdat = malloc(sizeof(struct irq_rk3288_gpio_pdata_t));
	if(!pdat)
		return NULL;

	chip = malloc(sizeof(struct irqchip_t));
	if(!chip)
	{
		free(pdat);
		return NULL;
	}

	pdat->virt = virt;
	pdat->base = base;
	pdat->nirq = nirq;
	pdat->parent = parent;
	pdat->both = 0;

	chip->name = alloc_device_name(dt_read_name(n), -1);
	chip->base = pdat->base;
	chip->nirq = pdat->nirq;
	chip->handler = malloc(sizeof(struct irq_handler_t) * pdat->nirq);
	chip->enable = irq_rk3288_gpio_enable;
	chip->disable = irq_rk3288_gpio_disable;
	chip->settype = irq_rk3288_gpio_settype;
	chip->dispatch = irq_rk3288_gpio_dispatch;
	chip->priv = pdat;

	if(!register_sub_irqchip(&dev, pdat->parent, chip))
	{
		free_device_name(chip->name);
		free(chip->handler);
		free(chip->priv);
		free(chip);
		return NULL;
	}
	dev->driver = drv;

	return dev;
}
Exemplo n.º 3
0
static void rotary_encoder_remove(struct device_t * dev)
{
	struct input_t * input = (struct input_t *)dev->priv;
	struct rotary_encoder_pdata_t * pdat = (struct rotary_encoder_pdata_t *)input->priv;

	if(input && unregister_input(input))
	{
		free_irq(pdat->irqa);
		free_irq(pdat->irqb);
		if(gpio_is_valid(pdat->c) && irq_is_valid(pdat->irqc))
			free_irq(pdat->irqc);

		free_device_name(input->name);
		free(input->priv);
		free(input);
	}
}
Exemplo n.º 4
0
static struct device_t * ce_samsung_timer_probe(struct driver_t * drv, struct dtnode_t * n)
{
	struct ce_samsung_timer_pdata_t * pdat;
	struct clockevent_t * ce;
	struct device_t * dev;
	virtual_addr_t virt = phys_to_virt(dt_read_address(n));
	char * clk = dt_read_string(n, "clock-name", NULL);
	int irq = dt_read_int(n, "interrupt", -1);
	int channel = dt_read_int(n, "timer-channel", -1);
	u64_t rate;

	if(!search_clk(clk))
		return NULL;

	if(!irq_is_valid(irq))
		return NULL;

	if(channel < 0 || channel > 3)
		return NULL;

	pdat = malloc(sizeof(struct ce_samsung_timer_pdata_t));
	if(!pdat)
		return NULL;

	ce = malloc(sizeof(struct clockevent_t));
	if(!ce)
	{
		free(pdat);
		return NULL;
	}

	pdat->virt = virt;
	pdat->clk = strdup(clk);
	pdat->irq = irq;
	pdat->channel = channel;

	clk_enable(pdat->clk);
	rate = samsung_timer_calc_tin(pdat->virt, pdat->clk, pdat->channel, 107);
	clockevent_calc_mult_shift(ce, rate, 10);
	ce->name = alloc_device_name(dt_read_name(n), -1);
	ce->min_delta_ns = clockevent_delta2ns(ce, 0x1);
	ce->max_delta_ns = clockevent_delta2ns(ce, 0xffffffff);
	ce->next = ce_samsung_timer_next,
	ce->priv = pdat;

	if(!request_irq(pdat->irq, ce_samsung_timer_interrupt, IRQ_TYPE_NONE, ce))
	{
		clk_disable(pdat->clk);
		free(pdat->clk);

		free(ce->priv);
		free(ce);
		return NULL;
	}
	samsung_timer_enable(pdat->virt, pdat->channel, 1);
	samsung_timer_count(pdat->virt, pdat->channel, 0);
	samsung_timer_stop(pdat->virt, pdat->channel);

	if(!register_clockevent(&dev, ce))
	{
		samsung_timer_irq_clear(pdat->virt, pdat->channel);
		samsung_timer_stop(pdat->virt, pdat->channel);
		samsung_timer_disable(pdat->virt, pdat->channel);
		clk_disable(pdat->clk);
		free_irq(pdat->irq);
		free(pdat->clk);

		free_device_name(ce->name);
		free(ce->priv);
		free(ce);
		return NULL;
	}
	dev->driver = drv;

	return dev;
}
Exemplo n.º 5
0
static struct device_t * rotary_encoder_probe(struct driver_t * drv, struct dtnode_t * n)
{
	struct rotary_encoder_pdata_t * pdat;
	struct input_t * input;
	struct device_t * dev;
	int a = dt_read_int(n, "a-gpio", -1);
	int b = dt_read_int(n, "b-gpio", -1);

	if(!gpio_is_valid(a) || !gpio_is_valid(b)
			|| !irq_is_valid(gpio_to_irq(a))
			|| !irq_is_valid(gpio_to_irq(b)))
		return NULL;

	pdat = malloc(sizeof(struct rotary_encoder_pdata_t));
	if(!pdat)
		return NULL;

	input = malloc(sizeof(struct input_t));
	if(!input)
	{
		free(pdat);
		return NULL;
	}

	pdat->a = a;
	pdat->acfg = dt_read_int(n, "a-gpio-config", -1);
	pdat->b = b;
	pdat->bcfg = dt_read_int(n, "b-gpio-config", -1);
	pdat->c = dt_read_int(n, "c-gpio", -1);
	pdat->ccfg = dt_read_int(n, "c-gpio-config", -1);
	pdat->irqa = gpio_to_irq(pdat->a);
	pdat->irqb = gpio_to_irq(pdat->b);
	pdat->irqc = gpio_to_irq(pdat->c);
	pdat->inva = dt_read_bool(n, "a-inverted", 0);
	pdat->invb = dt_read_bool(n, "b-inverted", 0);
	pdat->invc = dt_read_bool(n, "c-inverted", 0);

	input->name = alloc_device_name(dt_read_name(n), dt_read_id(n));
	input->ioctl = rotary_encoder_ioctl;
	input->priv = pdat;

	if(pdat->acfg >= 0)
		gpio_set_cfg(pdat->a, pdat->acfg);
	gpio_set_pull(pdat->a, pdat->inva ? GPIO_PULL_DOWN : GPIO_PULL_UP);
	gpio_direction_input(pdat->a);

	if(pdat->bcfg >= 0)
		gpio_set_cfg(pdat->b, pdat->bcfg);
	gpio_set_pull(pdat->b, pdat->invb ? GPIO_PULL_DOWN : GPIO_PULL_UP);
	gpio_direction_input(pdat->b);

	switch(dt_read_int(n, "step-per-period", 1))
	{
	case 4:
		request_irq(pdat->irqa, rotary_encoder_quarter_period_irq, IRQ_TYPE_EDGE_BOTH, input);
		request_irq(pdat->irqb, rotary_encoder_quarter_period_irq, IRQ_TYPE_EDGE_BOTH, input);
		pdat->state = rotary_encoder_get_state(pdat);
		break;

	case 2:
		request_irq(pdat->irqa, rotary_encoder_half_period_irq, IRQ_TYPE_EDGE_BOTH, input);
		request_irq(pdat->irqb, rotary_encoder_half_period_irq, IRQ_TYPE_EDGE_BOTH, input);
		pdat->state = rotary_encoder_get_state(pdat);
		break;

	case 1:
		request_irq(pdat->irqa, rotary_encoder_irq, IRQ_TYPE_EDGE_BOTH, input);
		request_irq(pdat->irqb, rotary_encoder_irq, IRQ_TYPE_EDGE_BOTH, input);
		pdat->state = 0;
		break;

	default:
		request_irq(pdat->irqa, rotary_encoder_irq, IRQ_TYPE_EDGE_BOTH, input);
		request_irq(pdat->irqb, rotary_encoder_irq, IRQ_TYPE_EDGE_BOTH, input);
		pdat->state = 0;
		break;
	}

	if(gpio_is_valid(pdat->c) && irq_is_valid(pdat->irqc))
	{
		if(pdat->ccfg >= 0)
			gpio_set_cfg(pdat->c, pdat->ccfg);
		gpio_set_pull(pdat->c, pdat->invc ? GPIO_PULL_DOWN : GPIO_PULL_UP);
		gpio_direction_input(pdat->c);
		request_irq(pdat->irqc, rotary_encoder_c_irq, IRQ_TYPE_EDGE_BOTH, input);
	}

	if(!register_input(&dev, input))
	{
		free_irq(pdat->irqa);
		free_irq(pdat->irqb);
		if(gpio_is_valid(pdat->c) && irq_is_valid(pdat->irqc))
			free_irq(pdat->irqc);

		free_device_name(input->name);
		free(input->priv);
		free(input);
		return NULL;
	}
	dev->driver = drv;

	return dev;
}
Exemplo n.º 6
0
static struct device_t * key_rc5t620_probe(struct driver_t * drv, struct dtnode_t * n)
{
	struct key_rc5t620_pdata_t * pdat;
	struct input_t * input;
	struct device_t * dev;
	struct i2c_device_t * i2cdev;
	int gpio = dt_read_int(n, "interrupt-gpio", -1);
	int irq = gpio_to_irq(gpio);
	u8_t val;

	if(!gpio_is_valid(gpio) || !irq_is_valid(irq))
		return NULL;

	i2cdev = i2c_device_alloc(dt_read_string(n, "i2c-bus", NULL), dt_read_int(n, "slave-address", 0x32), 0);
	if(!i2cdev)
		return NULL;

	if(rc5t620_read(i2cdev, RC5T620_LSIVER, &val) && (val == 0x03))
	{
		rc5t620_write(i2cdev, RC5T620_PWRIRQ, 0x00);
		rc5t620_write(i2cdev, RC5T620_PWRIRSEL, 0x01);
		rc5t620_write(i2cdev, RC5T620_INTEN, 0x01);
		rc5t620_write(i2cdev, RC5T620_PWRIREN, 0x01);
	}
	else
	{
		i2c_device_free(i2cdev);
		return NULL;
	}

	pdat = malloc(sizeof(struct key_rc5t620_pdata_t));
	if(!pdat)
	{
		i2c_device_free(i2cdev);
		return NULL;
	}

	input = malloc(sizeof(struct input_t));
	if(!input)
	{
		i2c_device_free(i2cdev);
		free(pdat);
		return NULL;
	}

	pdat->dev = i2cdev;
	pdat->irq = irq;

	input->name = alloc_device_name(dt_read_name(n), dt_read_id(n));
	input->type = INPUT_TYPE_KEYBOARD;
	input->ioctl = key_rc5t620_ioctl;
	input->priv = pdat;

	gpio_set_pull(gpio, GPIO_PULL_UP);
	gpio_direction_input(gpio);
	request_irq(pdat->irq, key_rc5t620_interrupt, IRQ_TYPE_EDGE_FALLING, input);

	if(!register_input(&dev, input))
	{
		free_irq(pdat->irq);
		i2c_device_free(pdat->dev);

		free_device_name(input->name);
		free(input->priv);
		free(input);
		return NULL;
	}
	dev->driver = drv;

	return dev;
}