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); }
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; }
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); } }
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; }
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; }
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; }