static struct device_t * gpio_bcm2836_virt_probe(struct driver_t * drv, struct dtnode_t * n) { struct gpio_bcm2836_virt_pdata_t * pdat; struct gpiochip_t * chip; struct device_t * dev; int base = dt_read_int(n, "gpio-base", -1); int ngpio = dt_read_int(n, "gpio-count", -1); if((base < 0) || (ngpio <= 0)) return NULL; pdat = malloc(sizeof(struct gpio_bcm2836_virt_pdata_t)); if(!pdat) return NULL; chip = malloc(sizeof(struct gpiochip_t)); if(!chip) { free(pdat); return NULL; } pdat->base = base; pdat->ngpio = ngpio; pdat->oirq = dt_read_int(n, "interrupt-offset", -1); pdat->virtbuf = bcm2836_mbox_fb_get_gpiovirt(); pdat->status = malloc(sizeof(uint32_t) * pdat->ngpio); memset(pdat->status, 0, sizeof(uint32_t) * pdat->ngpio); chip->name = alloc_device_name(dt_read_name(n), -1); chip->base = pdat->base; chip->ngpio = pdat->ngpio; chip->set_cfg = gpio_bcm2836_virt_set_cfg; chip->get_cfg = gpio_bcm2836_virt_get_cfg; chip->set_pull = gpio_bcm2836_virt_set_pull; chip->get_pull = gpio_bcm2836_virt_get_pull; chip->set_drv = gpio_bcm2836_virt_set_drv; chip->get_drv = gpio_bcm2836_virt_get_drv; chip->set_rate = gpio_bcm2836_virt_set_rate; chip->get_rate = gpio_bcm2836_virt_get_rate; chip->set_dir = gpio_bcm2836_virt_set_dir; chip->get_dir = gpio_bcm2836_virt_get_dir; chip->set_value = gpio_bcm2836_virt_set_value; chip->get_value = gpio_bcm2836_virt_get_value; chip->to_irq = gpio_bcm2836_virt_to_irq; chip->priv = pdat; if(!register_gpiochip(&dev, chip)) { free(pdat->status); free_device_name(chip->name); free(chip->priv); free(chip); return NULL; } dev->driver = drv; return dev; }
static struct device_t * irq_pl192_probe(struct driver_t * drv, struct dtnode_t * n) { struct irq_pl192_pdata_t * pdat; struct irqchip_t * chip; struct device_t * dev; virtual_addr_t virt = phys_to_virt(dt_read_address(n)); u32_t id = (((read32(virt + 0xfec) & 0xff) << 24) | ((read32(virt + 0xfe8) & 0xff) << 16) | ((read32(virt + 0xfe4) & 0xff) << 8) | ((read32(virt + 0xfe0) & 0xff) << 0)); int base = dt_read_int(n, "interrupt-base", -1); int nirq = dt_read_int(n, "interrupt-count", -1); if(((id >> 12) & 0xff) != 0x41 || (id & 0xfff) != 0x192) return NULL; if((base < 0) || (nirq <= 0)) return NULL; pdat = malloc(sizeof(struct irq_pl192_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; 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_pl192_enable; chip->disable = irq_pl192_disable; chip->settype = irq_pl192_settype; chip->dispatch = irq_pl192_dispatch; chip->priv = pdat; pl192_ctrl_init(pdat->virt); arm64_interrupt_enable(); if(!register_irqchip(&dev, chip)) { free_device_name(chip->name); free(chip->handler); free(chip->priv); free(chip); return NULL; } dev->driver = drv; return dev; }
static struct device_t * led_pwm_bl_probe(struct driver_t * drv, struct dtnode_t * n) { struct led_pwm_bl_pdata_t * pdat; struct pwm_t * pwm; struct led_t * led; struct device_t * dev; if(!(pwm = search_pwm(dt_read_string(n, "pwm-name", NULL)))) return NULL; pdat = malloc(sizeof(struct led_pwm_bl_pdata_t)); if(!pdat) return NULL; led = malloc(sizeof(struct led_t)); if(!led) { free(pdat); return NULL; } pdat->pwm = pwm; pdat->regulator = strdup(dt_read_string(n, "regulator-name", NULL)); pdat->period = dt_read_int(n, "pwm-period-ns", 1000 * 1000); pdat->polarity = dt_read_bool(n, "pwm-polarity", 0); pdat->from = dt_read_int(n, "pwm-percent-from", 0) * pdat->period / 100; pdat->to = dt_read_int(n, "pwm-percent-to", 100) * pdat->period / 100; pdat->brightness = dt_read_int(n, "default-brightness", 0); led->name = alloc_device_name(dt_read_name(n), dt_read_id(n)); led->set = led_pwm_bl_set, led->get = led_pwm_bl_get, led->priv = pdat; if(pdat->brightness > 0) regulator_enable(pdat->regulator); else regulator_disable(pdat->regulator); led_pwm_bl_set_brightness(pdat, pdat->brightness); if(!register_led(&dev, led)) { regulator_disable(pdat->regulator); led_pwm_bl_set_brightness(pdat, 0); if(pdat->regulator) free(pdat->regulator); free_device_name(led->name); free(led->priv); free(led); return NULL; } dev->driver = drv; return dev; }
static struct device_t * pwm_v3s_probe(struct driver_t * drv, struct dtnode_t * n) { struct pwm_v3s_pdata_t * pdat; struct pwm_t * pwm; 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 channel = dt_read_int(n, "channel", -1); if(channel < 0 || channel > 1) return NULL; if(!search_clk(clk)) return NULL; pdat = malloc(sizeof(struct pwm_v3s_pdata_t)); if(!pdat) return NULL; pwm = malloc(sizeof(struct pwm_t)); if(!pwm) { free(pdat); return NULL; } pdat->virt = virt; pdat->clk = strdup(clk); pdat->channel = channel; pdat->pwm = dt_read_int(n, "pwm-gpio", -1); pdat->pwmcfg = dt_read_int(n, "pwm-gpio-config", -1); pwm->name = alloc_device_name(dt_read_name(n), -1); pwm->config = pwm_v3s_config; pwm->enable = pwm_v3s_enable; pwm->disable = pwm_v3s_disable; pwm->priv = pdat; write32(pdat->virt + PWM_CTRL, read32(pdat->virt + PWM_CTRL) &~(0x3fff << (pdat->channel * 15))); write32(pdat->virt + PWM_PERIOD(pdat->channel), 0); if(!register_pwm(&dev, pwm)) { free(pdat->clk); free_device_name(pwm->name); free(pwm->priv); free(pwm); return NULL; } dev->driver = drv; return dev; }
static struct device_t * irq_gic400_probe(struct driver_t * drv, struct dtnode_t * n) { struct irq_gic400_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); if((base < 0) || (nirq <= 0)) return NULL; pdat = malloc(sizeof(struct irq_gic400_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; 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_gic400_enable; chip->disable = irq_gic400_disable; chip->settype = irq_gic400_settype; chip->dispatch = irq_gic400_dispatch; chip->priv = pdat; gic400_dist_init(pdat->virt); gic400_cpu_init(pdat->virt); arm32_interrupt_enable(); if(!register_irqchip(&dev, chip)) { free_device_name(chip->name); free(chip->handler); free(chip->priv); free(chip); return NULL; } dev->driver = drv; return dev; }
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 struct device_t * fb_bcm2837_probe(struct driver_t * drv, struct dtnode_t * n) { struct fb_bcm2837_pdata_t * pdat; struct fb_t * fb; struct device_t * dev; pdat = malloc(sizeof(struct fb_bcm2837_pdata_t)); if(!pdat) return NULL; fb = malloc(sizeof(struct fb_t)); if(!fb) { free(pdat); return NULL; } pdat->width = dt_read_int(n, "width", 640); pdat->height = dt_read_int(n, "height", 480); pdat->xdpi = dt_read_int(n, "dots-per-inch-x", 160); pdat->ydpi = dt_read_int(n, "dots-per-inch-y", 160); pdat->bpp = dt_read_int(n, "bits-per-pixel", 32); pdat->index = 0; pdat->vram[0] = bcm2837_mbox_fb_alloc(pdat->width, pdat->height, pdat->bpp, 2); pdat->vram[1] = pdat->vram[0] + (pdat->width * pdat->height * (pdat->bpp / 8)); pdat->brightness = 0; fb->name = alloc_device_name(dt_read_name(n), dt_read_id(n)); fb->width = pdat->width; fb->height = pdat->height; fb->xdpi = pdat->xdpi; fb->ydpi = pdat->ydpi; fb->bpp = pdat->bpp; fb->setbl = fb_setbl, fb->getbl = fb_getbl, fb->create = fb_create, fb->destroy = fb_destroy, fb->present = fb_present, fb->priv = pdat; if(!register_fb(&dev, fb)) { free_device_name(fb->name); free(fb->priv); free(fb); return NULL; } dev->driver = drv; return dev; }
static struct device_t * uart_sandbox_probe(struct driver_t * drv, struct dtnode_t * n) { struct uart_sandbox_pdata_t * pdat; struct uart_t * uart; struct device_t * dev; int fd = sandbox_uart_open(dt_read_string(n, "device", NULL)); if(fd < 0) return NULL; pdat = malloc(sizeof(struct uart_sandbox_pdata_t)); if(!pdat) return NULL; uart = malloc(sizeof(struct uart_t)); if(!uart) { free(pdat); return NULL; } pdat->fd = fd; pdat->baud = dt_read_int(n, "baud-rates", 115200); pdat->data = dt_read_int(n, "data-bits", 8); pdat->parity = dt_read_int(n, "parity-bits", 0); pdat->stop = dt_read_int(n, "stop-bits", 1); uart->name = alloc_device_name(dt_read_name(n), dt_read_id(n)); uart->set = uart_sandbox_set; uart->get = uart_sandbox_get; uart->read = uart_sandbox_read; uart->write = uart_sandbox_write; uart->priv = pdat; uart_sandbox_set(uart, pdat->baud, pdat->data, pdat->parity, pdat->stop); if(!register_uart(&dev, uart)) { sandbox_uart_close(pdat->fd); free_device_name(uart->name); free(uart->priv); free(uart); return NULL; } dev->driver = drv; return dev; }
static struct device_t * servo_pwm_probe(struct driver_t * drv, struct dtnode_t * n) { struct servo_pwm_pdata_t * pdat; struct pwm_t * pwm; struct servo_t * m; struct device_t * dev; if(!(pwm = search_pwm(dt_read_string(n, "pwm-name", NULL)))) return NULL; pdat = malloc(sizeof(struct servo_pwm_pdata_t)); if(!pdat) return NULL; m = malloc(sizeof(struct servo_t)); if(!m) { free(pdat); return NULL; } pdat->pwm = pwm; pdat->period = dt_read_int(n, "pwm-period-ns", 20000 * 1000); pdat->polarity = dt_read_bool(n, "pwm-polarity", 0); pdat->from = dt_read_int(n, "pwm-duty-ns-from", 500 * 1000); pdat->to = dt_read_int(n, "pwm-duty-ns-to", 2500 * 1000); pdat->range = dt_read_int(n, "rotation-angle-range", 180); pdat->angle = -360; m->name = alloc_device_name(dt_read_name(n), dt_read_id(n)); m->enable = servo_pwm_enable; m->disable = servo_pwm_disable; m->set = servo_pwm_set; m->priv = pdat; servo_pwm_set(m, dt_read_int(n, "default-angle", 0)); if(!register_servo(&dev, m)) { free_device_name(m->name); free(m->priv); free(m); return NULL; } dev->driver = drv; return dev; }
static struct device_t * cs_samsung_timer_probe(struct driver_t * drv, struct dtnode_t * n) { struct cs_samsung_timer_pdata_t * pdat; struct clocksource_t * cs; 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 channel = dt_read_int(n, "timer-channel", -1); u64_t rate; if(!search_clk(clk)) return NULL; if(channel < 0 || channel > 3) return NULL; pdat = malloc(sizeof(struct cs_samsung_timer_pdata_t)); if(!pdat) return NULL; cs = malloc(sizeof(struct clocksource_t)); if(!cs) { free(pdat); return NULL; } pdat->virt = virt; pdat->clk = strdup(clk); pdat->channel = channel; clk_enable(pdat->clk); rate = samsung_timer_calc_tin(pdat->virt, pdat->clk, pdat->channel, 13); clocksource_calc_mult_shift(&cs->mult, &cs->shift, rate, 1000000000ULL, 10); cs->name = alloc_device_name(dt_read_name(n), -1); cs->mask = CLOCKSOURCE_MASK(32); cs->read = cs_samsung_timer_read; cs->priv = pdat; samsung_timer_enable(pdat->virt, pdat->channel, 0); samsung_timer_count(pdat->virt, pdat->channel, 0xffffffff); samsung_timer_start(pdat->virt, pdat->channel, 0); if(!register_clocksource(&dev, cs)) { samsung_timer_stop(pdat->virt, pdat->channel); samsung_timer_disable(pdat->virt, pdat->channel); clk_disable(pdat->clk); free(pdat->clk); free_device_name(cs->name); free(cs->priv); free(cs); return NULL; } dev->driver = drv; return dev; }
static struct device_t * battery_sbs_probe(struct driver_t * drv, struct dtnode_t * n) { struct battery_sbs_pdata_t * pdat; struct battery_t * bat; struct device_t * dev; struct i2c_device_t * i2cdev; u16_t val; i2cdev = i2c_device_alloc(dt_read_string(n, "i2c-bus", NULL), dt_read_int(n, "slave-address", 0x0b), 0); if(!i2cdev) return NULL; if(sbs_read_word(i2cdev, SBS_BATTERY_STATUS, &val)) { if(val & (0x1 << 7)) { } } else { i2c_device_free(i2cdev); return NULL; } pdat = malloc(sizeof(struct battery_sbs_pdata_t)); if(!pdat) { i2c_device_free(i2cdev); return NULL; } bat = malloc(sizeof(struct battery_t)); if(!bat) { i2c_device_free(i2cdev); free(pdat); return NULL; } pdat->dev = i2cdev; bat->name = alloc_device_name(dt_read_name(n), -1); bat->update = battery_sbs_update; bat->priv = pdat; if(!register_battery(&dev, bat)) { i2c_device_free(pdat->dev); free_device_name(bat->name); free(bat->priv); free(bat); return NULL; } dev->driver = drv; return dev; }
static struct device_t * gmeter_axdl345_probe(struct driver_t * drv, struct dtnode_t * n) { struct gmeter_axdl345_pdata_t * pdat; struct gmeter_t * g; struct device_t * dev; struct i2c_device_t * i2cdev; u8_t val; i2cdev = i2c_device_alloc(dt_read_string(n, "i2c-bus", NULL), dt_read_int(n, "slave-address", 0x53), 0); if(!i2cdev) return NULL; if(axdl345_read(i2cdev, REG_DEVID, &val) && (val == 0xe5)) { axdl345_write(i2cdev, REG_DATA_FORMAT, 0x0b); axdl345_write(i2cdev, REG_POWER_CTL, 0x08); axdl345_write(i2cdev, REG_INT_ENABLE, 0x80); } else { i2c_device_free(i2cdev); return NULL; } pdat = malloc(sizeof(struct gmeter_axdl345_pdata_t)); if(!pdat) { i2c_device_free(i2cdev); return NULL; } g = malloc(sizeof(struct gmeter_t)); if(!g) { i2c_device_free(i2cdev); free(pdat); return NULL; } pdat->dev = i2cdev; g->name = alloc_device_name(dt_read_name(n), -1); g->get = gmeter_axdl345_get; g->priv = pdat; if(!register_gmeter(&dev, g)) { i2c_device_free(pdat->dev); free_device_name(g->name); free(g->priv); free(g); return NULL; } dev->driver = drv; return dev; }
static struct device_t * reset_rk3128_probe(struct driver_t * drv, struct dtnode_t * n) { struct reset_rk3128_pdata_t * pdat; struct resetchip_t * chip; struct device_t * dev; virtual_addr_t virt = phys_to_virt(dt_read_address(n)); int base = dt_read_int(n, "reset-base", -1); int nreset = dt_read_int(n, "reset-count", -1); if((base < 0) || (nreset <= 0)) return NULL; pdat = malloc(sizeof(struct reset_rk3128_pdata_t)); if(!pdat) return NULL; chip = malloc(sizeof(struct resetchip_t)); if(!chip) { free(pdat); return NULL; } pdat->virt = virt; pdat->base = base; pdat->nreset = nreset; chip->name = alloc_device_name(dt_read_name(n), -1); chip->base = pdat->base; chip->nreset = pdat->nreset; chip->assert = reset_rk3128_assert; chip->deassert = reset_rk3128_deassert; chip->priv = pdat; if(!register_resetchip(&dev, chip)) { free_device_name(chip->name); free(chip->priv); free(chip); return NULL; } dev->driver = drv; return dev; }
static struct device_t * fb_rk3288_probe(struct driver_t * drv, struct dtnode_t * n) { struct fb_rk3288_pdata_t * pdat; struct fb_t * fb; struct device_t * dev; virtual_addr_t virt = phys_to_virt(dt_read_address(n)); char * clk = dt_read_string(n, "clock-name", NULL); if(!search_clk(clk)) return NULL; pdat = malloc(sizeof(struct fb_rk3288_pdata_t)); if(!pdat) return NULL; fb = malloc(sizeof(struct fb_t)); if(!fb) { free(pdat); return NULL; } pdat->virtvop = virt; pdat->virtgrf = phys_to_virt(RK3288_GRF_BASE); pdat->virtlvds = phys_to_virt(RK3288_LVDS_BASE); pdat->lcd_avdd_3v3 = strdup(dt_read_string(n, "regulator-lcd-avdd-3v3", NULL)); pdat->lcd_avdd_1v8 = strdup(dt_read_string(n, "regulator-lcd-avdd-1v8", NULL)); pdat->lcd_avdd_1v0 = strdup(dt_read_string(n, "regulator-lcd-avdd-1v0", NULL)); pdat->clk = strdup(clk); pdat->width = dt_read_int(n, "width", 1024); pdat->height = dt_read_int(n, "height", 600); pdat->xdpi = dt_read_int(n, "dots-per-inch-x", 160); pdat->ydpi = dt_read_int(n, "dots-per-inch-y", 160); pdat->bits_per_pixel = dt_read_int(n, "bits-per-pixel", 32); pdat->bytes_per_pixel = dt_read_int(n, "bytes-per-pixel", 4); pdat->index = 0; pdat->vram[0] = dma_alloc_noncoherent(pdat->width * pdat->height * pdat->bytes_per_pixel); pdat->vram[1] = dma_alloc_noncoherent(pdat->width * pdat->height * pdat->bytes_per_pixel); pdat->interface = RK3288_VOP_INTERFACE_RGB_LVDS; pdat->output = RK3288_LVDS_OUTPUT_RGB; pdat->format = RK3288_LVDS_FORMAT_JEIDA; pdat->mode.mirrorx = 0; pdat->mode.mirrory = 0; pdat->mode.swaprg = 0; pdat->mode.swaprb = 0; pdat->mode.swapbg = 0; pdat->timing.pixel_clock_hz = dt_read_long(n, "clock-frequency", 52000000); pdat->timing.h_front_porch = dt_read_int(n, "hfront-porch", 1); pdat->timing.h_back_porch = dt_read_int(n, "hback-porch", 1); pdat->timing.h_sync_len = dt_read_int(n, "hsync-len", 1); pdat->timing.v_front_porch = dt_read_int(n, "vfront-porch", 1); pdat->timing.v_back_porch = dt_read_int(n, "vback-porch", 1); pdat->timing.v_sync_len = dt_read_int(n, "vsync-len", 1); pdat->timing.h_sync_active = dt_read_bool(n, "hsync-active", 0); pdat->timing.v_sync_active = dt_read_bool(n, "vsync-active", 0); pdat->timing.den_active = dt_read_bool(n, "den-active", 0); pdat->timing.clk_active = dt_read_bool(n, "clk-active", 0); pdat->backlight = search_led(dt_read_string(n, "backlight", NULL)); fb->name = alloc_device_name(dt_read_name(n), -1); fb->width = pdat->width; fb->height = pdat->height; fb->xdpi = pdat->xdpi; fb->ydpi = pdat->ydpi; fb->bpp = pdat->bits_per_pixel; fb->setbl = fb_setbl, fb->getbl = fb_getbl, fb->create = fb_create, fb->destroy = fb_destroy, fb->present = fb_present, fb->priv = pdat; regulator_set_voltage(pdat->lcd_avdd_3v3, 3300000); regulator_enable(pdat->lcd_avdd_3v3); regulator_set_voltage(pdat->lcd_avdd_1v8, 1800000); regulator_enable(pdat->lcd_avdd_1v8); regulator_set_voltage(pdat->lcd_avdd_1v0, 1000000); regulator_enable(pdat->lcd_avdd_1v0); clk_enable(pdat->clk); rk3288_fb_init(pdat); if(!register_fb(&dev, fb)) { regulator_disable(pdat->lcd_avdd_3v3); free(pdat->lcd_avdd_3v3); regulator_disable(pdat->lcd_avdd_1v8); free(pdat->lcd_avdd_1v8); regulator_disable(pdat->lcd_avdd_1v0); free(pdat->lcd_avdd_1v0); clk_disable(pdat->clk); free(pdat->clk); dma_free_noncoherent(pdat->vram[0]); dma_free_noncoherent(pdat->vram[1]); free_device_name(fb->name); free(fb->priv); free(fb); 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; }
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 * sdhci_v3s_probe(struct driver_t * drv, struct dtnode_t * n) { struct sdhci_v3s_pdata_t * pdat; struct sdhci_t * sdhci; struct device_t * dev; virtual_addr_t virt = phys_to_virt(dt_read_address(n)); char * pclk = dt_read_string(n, "clock-name", NULL); if(!search_clk(pclk)) return NULL; pdat = malloc(sizeof(struct sdhci_v3s_pdata_t)); if(!pdat) return FALSE; sdhci = malloc(sizeof(struct sdhci_t)); if(!sdhci) { free(pdat); return FALSE; } pdat->virt = virt; pdat->pclk = strdup(pclk); pdat->reset = dt_read_int(n, "reset", -1); pdat->clk = dt_read_int(n, "clk-gpio", -1); pdat->clkcfg = dt_read_int(n, "clk-gpio-config", -1); pdat->cmd = dt_read_int(n, "cmd-gpio", -1); pdat->cmdcfg = dt_read_int(n, "cmd-gpio-config", -1); pdat->dat0 = dt_read_int(n, "dat0-gpio", -1); pdat->dat0cfg = dt_read_int(n, "dat0-gpio-config", -1); pdat->dat1 = dt_read_int(n, "dat1-gpio", -1); pdat->dat1cfg = dt_read_int(n, "dat1-gpio-config", -1); pdat->dat2 = dt_read_int(n, "dat2-gpio", -1); pdat->dat2cfg = dt_read_int(n, "dat2-gpio-config", -1); pdat->dat3 = dt_read_int(n, "dat3-gpio", -1); pdat->dat3cfg = dt_read_int(n, "dat3-gpio-config", -1); pdat->dat4 = dt_read_int(n, "dat4-gpio", -1); pdat->dat4cfg = dt_read_int(n, "dat4-gpio-config", -1); pdat->dat5 = dt_read_int(n, "dat5-gpio", -1); pdat->dat5cfg = dt_read_int(n, "dat5-gpio-config", -1); pdat->dat6 = dt_read_int(n, "dat6-gpio", -1); pdat->dat6cfg = dt_read_int(n, "dat6-gpio-config", -1); pdat->dat7 = dt_read_int(n, "dat7-gpio", -1); pdat->dat7cfg = dt_read_int(n, "dat7-gpio-config", -1); pdat->cd = dt_read_int(n, "cd-gpio", -1); pdat->cdcfg = dt_read_int(n, "cd-gpio-config", -1); sdhci->name = alloc_device_name(dt_read_name(n), -1); sdhci->voltage = MMC_VDD_27_36; sdhci->width = MMC_BUS_WIDTH_4; sdhci->clock = 52 * 1000 * 1000; sdhci->removable = TRUE; sdhci->detect = sdhci_v3s_detect; sdhci->setvoltage = sdhci_v3s_setvoltage; sdhci->setwidth = sdhci_v3s_setwidth; sdhci->setclock = sdhci_v3s_setclock; sdhci->transfer = sdhci_v3s_transfer; sdhci->priv = pdat; clk_enable(pdat->pclk); if(pdat->reset >= 0) reset_deassert(pdat->reset); if(pdat->clk >= 0) { if(pdat->clkcfg >= 0) gpio_set_cfg(pdat->clk, pdat->clkcfg); gpio_set_pull(pdat->clk, GPIO_PULL_UP); } if(pdat->cmd >= 0) { if(pdat->cmdcfg >= 0) gpio_set_cfg(pdat->cmd, pdat->cmdcfg); gpio_set_pull(pdat->cmd, GPIO_PULL_UP); } if(pdat->dat0 >= 0) { if(pdat->dat0cfg >= 0) gpio_set_cfg(pdat->dat0, pdat->dat0cfg); gpio_set_pull(pdat->dat0, GPIO_PULL_UP); } if(pdat->dat1 >= 0) { if(pdat->dat1cfg >= 0) gpio_set_cfg(pdat->dat1, pdat->dat1cfg); gpio_set_pull(pdat->dat1, GPIO_PULL_UP); } if(pdat->dat2 >= 0) { if(pdat->dat2cfg >= 0) gpio_set_cfg(pdat->dat2, pdat->dat2cfg); gpio_set_pull(pdat->dat2, GPIO_PULL_UP); } if(pdat->dat3 >= 0) { if(pdat->dat3cfg >= 0) gpio_set_cfg(pdat->dat3, pdat->dat3cfg); gpio_set_pull(pdat->dat3, GPIO_PULL_UP); } if(pdat->dat4 >= 0) { if(pdat->dat4cfg >= 0) gpio_set_cfg(pdat->dat4, pdat->dat4cfg); gpio_set_pull(pdat->dat4, GPIO_PULL_UP); } if(pdat->dat5 >= 0) { if(pdat->dat5cfg >= 0) gpio_set_cfg(pdat->dat5, pdat->dat5cfg); gpio_set_pull(pdat->dat5, GPIO_PULL_UP); } if(pdat->dat6 >= 0) { if(pdat->dat6cfg >= 0) gpio_set_cfg(pdat->dat6, pdat->dat6cfg); gpio_set_pull(pdat->dat6, GPIO_PULL_UP); } if(pdat->dat7 >= 0) { if(pdat->dat7cfg >= 0) gpio_set_cfg(pdat->dat7, pdat->dat7cfg); gpio_set_pull(pdat->dat7, GPIO_PULL_UP); } if(pdat->cd >= 0) { if(pdat->cdcfg >= 0) gpio_set_cfg(pdat->cd, pdat->cdcfg); gpio_set_pull(pdat->cd, GPIO_PULL_UP); } if(!register_sdhci(&dev, sdhci)) { clk_disable(pdat->pclk); free(pdat->pclk); free_device_name(sdhci->name); free(sdhci->priv); free(sdhci); return NULL; } dev->driver = drv; return dev; }
static struct device_t * clk_mux_probe(struct driver_t * drv, struct dtnode_t * n) { struct clk_mux_pdata_t * pdat; struct clk_mux_parent_t * parent; struct clk_t * clk; struct device_t * dev; struct dtnode_t o; virtual_addr_t virt = phys_to_virt(dt_read_address(n)); char * name = dt_read_string(n, "name", NULL); int nparent = dt_read_array_length(n, "parent"); int shift = dt_read_int(n, "shift", -1); int width = dt_read_int(n, "width", -1); int i; if(!name || (nparent <= 0) || (shift < 0) || (width <= 0)) return NULL; if(search_clk(name)) return NULL; pdat = malloc(sizeof(struct clk_mux_pdata_t)); if(!pdat) return NULL; parent = malloc(sizeof(struct clk_mux_parent_t) * nparent); if(!parent) { free(pdat); return NULL; } clk = malloc(sizeof(struct clk_t)); if(!clk) { free(pdat); free(parent); return NULL; } for(i = 0; i < nparent; i++) { dt_read_array_object(n, "parent", i, &o); parent[i].name = strdup(dt_read_string(&o, "name", NULL)); parent[i].value = dt_read_int(&o, "value", 0); } pdat->virt = virt; pdat->parent = parent; pdat->nparent = nparent; pdat->shift = shift; pdat->width = width; clk->name = strdup(name); clk->count = 0; clk->set_parent = clk_mux_set_parent; clk->get_parent = clk_mux_get_parent; clk->set_enable = clk_mux_set_enable; clk->get_enable = clk_mux_get_enable; clk->set_rate = clk_mux_set_rate; clk->get_rate = clk_mux_get_rate; clk->priv = pdat; if(!register_clk(&dev, clk)) { for(i = 0; i < pdat->nparent; i++) free(pdat->parent[i].name); free(pdat->parent); free(clk->name); free(clk->priv); free(clk); return NULL; } dev->driver = drv; if(dt_read_object(n, "default", &o)) { char * c = clk->name; char * p; u64_t r; int e; if((p = dt_read_string(&o, "parent", NULL)) && search_clk(p)) clk_set_parent(c, p); if((r = (u64_t)dt_read_long(&o, "rate", 0)) > 0) clk_set_rate(c, r); if((e = dt_read_bool(&o, "enable", -1)) != -1) { if(e > 0) clk_enable(c); else clk_disable(c); } } return dev; }
static struct device_t * i2c_gpio_probe(struct driver_t * drv, struct dtnode_t * n) { struct i2c_gpio_pdata_t * pdat; struct i2c_t * i2c; struct device_t * dev; int sda = dt_read_int(n, "sda-gpio", -1); int scl = dt_read_int(n, "scl-gpio", -1); if(!gpio_is_valid(sda) || !gpio_is_valid(scl)) return NULL; pdat = malloc(sizeof(struct i2c_gpio_pdata_t)); if(!pdat) return FALSE; i2c = malloc(sizeof(struct i2c_t)); if(!i2c) { free(pdat); return FALSE; } pdat->sda = sda; pdat->scl = scl; pdat->sda_open_drain = dt_read_bool(n, "sda-open-drain", 0); pdat->scl_open_drain = dt_read_bool(n, "scl-open-drain", 0); pdat->scl_output_only = dt_read_bool(n, "sda-output-only", 0); pdat->udelay = dt_read_int(n, "delay-us", 5); pdat->bdat.priv = pdat; if(pdat->sda_open_drain) { gpio_direction_output(pdat->sda, 1); pdat->bdat.setsda = i2c_gpio_setsda_val; } else { gpio_direction_input(pdat->sda); pdat->bdat.setsda = i2c_gpio_setsda_dir; } if(pdat->scl_open_drain || pdat->scl_output_only) { gpio_direction_output(pdat->scl, 1); pdat->bdat.setscl = i2c_gpio_setscl_val; } else { gpio_direction_input(pdat->scl); pdat->bdat.setscl = i2c_gpio_setscl_dir; } pdat->bdat.getsda = i2c_gpio_getsda; if(pdat->scl_output_only) pdat->bdat.getscl = 0; else pdat->bdat.getscl = i2c_gpio_getscl; if(pdat->udelay > 0) pdat->bdat.udelay = pdat->udelay; else if(pdat->scl_output_only) pdat->bdat.udelay = 50; else pdat->bdat.udelay = 5; i2c->name = alloc_device_name(dt_read_name(n), dt_read_id(n)); i2c->xfer = i2c_gpio_xfer, i2c->priv = pdat; if(!register_i2c(&dev, i2c)) { free_device_name(i2c->name); free(i2c->priv); free(i2c); return NULL; } dev->driver = drv; return dev; }
static struct device_t * spi_rk3128_probe(struct driver_t * drv, struct dtnode_t * n) { struct spi_rk3128_pdata_t * pdat; struct spi_t * spi; struct device_t * dev; virtual_addr_t virt = phys_to_virt(dt_read_address(n)); char * clk = dt_read_string(n, "clock-name", NULL); pdat = malloc(sizeof(struct spi_rk3128_pdata_t)); if(!pdat) return FALSE; spi = malloc(sizeof(struct spi_t)); if(!spi) { free(pdat); return FALSE; } pdat->virt = virt; pdat->clk = strdup(clk); pdat->sclk = dt_read_int(n, "sclk-gpio", -1); pdat->sclkcfg = dt_read_int(n, "sclk-gpio-config", -1); pdat->mosi = dt_read_int(n, "mosi-gpio", -1); pdat->mosicfg = dt_read_int(n, "mosi-gpio-config", -1); pdat->miso = dt_read_int(n, "miso-gpio", -1); pdat->misocfg = dt_read_int(n, "miso-gpio-config", -1); pdat->cs = dt_read_int(n, "cs-gpio", -1); pdat->cscfg = dt_read_int(n, "cs-gpio-config", -1); spi->name = alloc_device_name(dt_read_name(n), -1); spi->type = SPI_TYPE_SINGLE; spi->transfer = spi_rk3128_transfer; spi->select = spi_rk3128_select; spi->deselect = spi_rk3128_deselect; spi->priv = pdat; clk_enable(pdat->clk); if(pdat->sclk >= 0) { if(pdat->sclkcfg >= 0) gpio_set_cfg(pdat->sclk, pdat->sclkcfg); gpio_set_pull(pdat->sclk, GPIO_PULL_NONE); } if(pdat->mosi >= 0) { if(pdat->mosicfg >= 0) gpio_set_cfg(pdat->mosi, pdat->mosicfg); gpio_set_pull(pdat->mosi, GPIO_PULL_NONE); } if(pdat->miso >= 0) { if(pdat->misocfg >= 0) gpio_set_cfg(pdat->miso, pdat->misocfg); gpio_set_pull(pdat->miso, GPIO_PULL_NONE); } if(pdat->cs >= 0) { if(pdat->cscfg >= 0) gpio_set_cfg(pdat->cs, pdat->cscfg); gpio_set_pull(pdat->cs, GPIO_PULL_NONE); } rk3128_spi_enable_chip(pdat, 0); write32(pdat->virt + SPI_CTRLR0, (0 << 20) | (0 << 18) | (0 << 16) | (3 << 14) | (0 << 12) | (0 << 11) | (1 << 10) | (0 << 8) | (1 << 0)); write32(pdat->virt + SPI_TXFTLR, 32 / 2 - 1); write32(pdat->virt + SPI_RXFTLR, 32 / 2 - 1); if(!register_spi(&dev, spi)) { clk_disable(pdat->clk); free(pdat->clk); free_device_name(spi->name); free(spi->priv); free(spi); return NULL; } dev->driver = drv; return dev; }
static struct device_t * gpio_pl061_probe(struct driver_t * drv, struct dtnode_t * n) { struct gpio_pl061_pdata_t * pdat; struct gpiochip_t * chip; struct device_t * dev; virtual_addr_t virt = phys_to_virt(dt_read_address(n)); u32_t id = (((read32(virt + 0xfec) & 0xff) << 24) | ((read32(virt + 0xfe8) & 0xff) << 16) | ((read32(virt + 0xfe4) & 0xff) << 8) | ((read32(virt + 0xfe0) & 0xff) << 0)); int base = dt_read_int(n, "gpio-base", -1); int ngpio = dt_read_int(n, "gpio-count", -1); if(((id >> 12) & 0xff) != 0x41 || (id & 0xfff) != 0x061) return NULL; if((base < 0) || (ngpio <= 0)) return NULL; pdat = malloc(sizeof(struct gpio_pl061_pdata_t)); if(!pdat) return NULL; chip = malloc(sizeof(struct gpiochip_t)); if(!chip) { free(pdat); return NULL; } pdat->virt = virt; pdat->base = base; pdat->ngpio = ngpio; pdat->oirq = dt_read_int(n, "interrupt-offset", -1); chip->name = alloc_device_name(dt_read_name(n), -1); chip->base = pdat->base; chip->ngpio = pdat->ngpio; chip->set_cfg = gpio_pl061_set_cfg; chip->get_cfg = gpio_pl061_get_cfg; chip->set_pull = gpio_pl061_set_pull; chip->get_pull = gpio_pl061_get_pull; chip->set_drv = gpio_pl061_set_drv; chip->get_drv = gpio_pl061_get_drv; chip->set_rate = gpio_pl061_set_rate; chip->get_rate = gpio_pl061_get_rate; chip->set_dir = gpio_pl061_set_dir; chip->get_dir = gpio_pl061_get_dir; chip->set_value = gpio_pl061_set_value; chip->get_value = gpio_pl061_get_value; chip->to_irq = gpio_pl061_to_irq; chip->priv = pdat; if(!register_gpiochip(&dev, chip)) { free_device_name(chip->name); free(chip->priv); free(chip); return NULL; } dev->driver = drv; return dev; }
static struct device_t * fb_f1c500s_probe(struct driver_t * drv, struct dtnode_t * n) { struct fb_f1c500s_pdata_t * pdat; struct framebuffer_t * fb; struct device_t * dev; char * clkdefe = dt_read_string(n, "clock-name-defe", NULL); char * clkdebe = dt_read_string(n, "clock-name-debe", NULL); char * clktcon = dt_read_string(n, "clock-name-tcon", NULL); int i; if(!search_clk(clkdefe) || !search_clk(clkdebe) || !search_clk(clktcon)) return NULL; pdat = malloc(sizeof(struct fb_f1c500s_pdata_t)); if(!pdat) return NULL; fb = malloc(sizeof(struct framebuffer_t)); if(!fb) { free(pdat); return NULL; } pdat->virtdefe = phys_to_virt(F1C500S_DEFE_BASE); pdat->virtdebe = phys_to_virt(F1C500S_DEBE_BASE); pdat->virttcon = phys_to_virt(F1C500S_TCON_BASE); pdat->virtgpio = phys_to_virt(F1C500S_GPIO_BASE); pdat->clkdefe = strdup(clkdefe); pdat->clkdebe = strdup(clkdebe); pdat->clktcon = strdup(clktcon); pdat->rstdefe = dt_read_int(n, "reset-defe", -1); pdat->rstdebe = dt_read_int(n, "reset-debe", -1); pdat->rsttcon = dt_read_int(n, "reset-tcon", -1); pdat->width = dt_read_int(n, "width", 320); pdat->height = dt_read_int(n, "height", 240); pdat->pwidth = dt_read_int(n, "physical-width", 216); pdat->pheight = dt_read_int(n, "physical-height", 135); pdat->bits_per_pixel = dt_read_int(n, "bits-per-pixel", 18); pdat->bytes_per_pixel = dt_read_int(n, "bytes-per-pixel", 4); pdat->index = 0; pdat->vram[0] = dma_alloc_noncoherent(pdat->width * pdat->height * pdat->bytes_per_pixel); pdat->vram[1] = dma_alloc_noncoherent(pdat->width * pdat->height * pdat->bytes_per_pixel); pdat->nrl = region_list_alloc(0); pdat->orl = region_list_alloc(0); pdat->timing.pixel_clock_hz = dt_read_long(n, "clock-frequency", 8000000); pdat->timing.h_front_porch = dt_read_int(n, "hfront-porch", 40); pdat->timing.h_back_porch = dt_read_int(n, "hback-porch", 87); pdat->timing.h_sync_len = dt_read_int(n, "hsync-len", 1); pdat->timing.v_front_porch = dt_read_int(n, "vfront-porch", 13); pdat->timing.v_back_porch = dt_read_int(n, "vback-porch", 31); pdat->timing.v_sync_len = dt_read_int(n, "vsync-len", 1); pdat->timing.h_sync_active = dt_read_bool(n, "hsync-active", 0); pdat->timing.v_sync_active = dt_read_bool(n, "vsync-active", 0); pdat->timing.den_active = dt_read_bool(n, "den-active", 0); pdat->timing.clk_active = dt_read_bool(n, "clk-active", 0); pdat->backlight = search_led(dt_read_string(n, "backlight", NULL)); fb->name = alloc_device_name(dt_read_name(n), dt_read_id(n)); fb->width = pdat->width; fb->height = pdat->height; fb->pwidth = pdat->pwidth; fb->pheight = pdat->pheight; fb->bytes = pdat->bytes_per_pixel; fb->setbl = fb_setbl; fb->getbl = fb_getbl; fb->create = fb_create; fb->destroy = fb_destroy; fb->present = fb_present; fb->priv = pdat; clk_enable(pdat->clkdefe); clk_enable(pdat->clkdebe); clk_enable(pdat->clktcon); if(pdat->rstdefe >= 0) reset_deassert(pdat->rstdefe); if(pdat->rstdebe >= 0) reset_deassert(pdat->rstdebe); if(pdat->rsttcon >= 0) reset_deassert(pdat->rsttcon); for(i = 0x0800; i < 0x1000; i += 4) write32(pdat->virtdebe + i, 0); fb_f1c500s_init(pdat); if(!register_framebuffer(&dev, fb)) { clk_disable(pdat->clkdefe); clk_disable(pdat->clkdebe); clk_disable(pdat->clktcon); free(pdat->clkdefe); free(pdat->clkdebe); free(pdat->clktcon); dma_free_noncoherent(pdat->vram[0]); dma_free_noncoherent(pdat->vram[1]); region_list_free(pdat->nrl); region_list_free(pdat->orl); free_device_name(fb->name); free(fb->priv); free(fb); return NULL; } dev->driver = drv; return dev; }
static struct device_t * motor_gpio_probe(struct driver_t * drv, struct dtnode_t * n) { struct motor_gpio_pdata_t * pdat; struct motor_t * m; struct device_t * dev; int a = dt_read_int(n, "a-gpio", -1); int b = dt_read_int(n, "b-gpio", -1); int e = dt_read_int(n, "enable-gpio", -1); if(!gpio_is_valid(a) || !gpio_is_valid(b)) return NULL; pdat = malloc(sizeof(struct motor_gpio_pdata_t)); if(!pdat) return NULL; m = malloc(sizeof(struct motor_t)); if(!m) { free(pdat); return NULL; } timer_init(&pdat->timer, motor_gpio_timer_function, m); 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->e = e; pdat->ecfg = dt_read_int(n, "enable-gpio-config", -1); pdat->period = dt_read_int(n, "period-ns", 10 * 1000 * 1000); pdat->duty = pdat->period / 2; pdat->maxspeed = abs(dt_read_int(n, "max-speed-rpm", 1000)); pdat->speed = 0; pdat->flag = 0; m->name = alloc_device_name(dt_read_name(n), dt_read_id(n)); m->enable = motor_gpio_enable; m->disable = motor_gpio_disable; m->set = motor_gpio_set; m->priv = pdat; if(pdat->a >= 0) { if(pdat->acfg >= 0) gpio_set_cfg(pdat->a, pdat->acfg); gpio_set_pull(pdat->a, GPIO_PULL_UP); gpio_set_direction(pdat->a, GPIO_DIRECTION_OUTPUT); gpio_set_value(pdat->a, 0); } if(pdat->b >= 0) { if(pdat->bcfg >= 0) gpio_set_cfg(pdat->b, pdat->bcfg); gpio_set_pull(pdat->b, GPIO_PULL_UP); gpio_set_direction(pdat->b, GPIO_DIRECTION_OUTPUT); gpio_set_value(pdat->b, 0); } if(pdat->e >= 0) { if(pdat->ecfg >= 0) gpio_set_cfg(pdat->e, pdat->ecfg); gpio_set_pull(pdat->e, GPIO_PULL_UP); gpio_set_direction(pdat->e, GPIO_DIRECTION_OUTPUT); gpio_set_value(pdat->e, 0); } if(!register_motor(&dev, m)) { timer_cancel(&pdat->timer); free_device_name(m->name); free(m->priv); free(m); return NULL; } dev->driver = drv; return dev; }
static struct device_t * compass_hmc5883l_probe(struct driver_t * drv, struct dtnode_t * n) { struct compass_hmc5883l_pdata_t * pdat; struct compass_t * c; struct device_t * dev; struct i2c_device_t * i2cdev; u8_t ida, idb, idc; i2cdev = i2c_device_alloc(dt_read_string(n, "i2c-bus", NULL), dt_read_int(n, "slave-address", 0x1e), 0); if(!i2cdev) return NULL; if(hmc5883l_read(i2cdev, REG_IDA, &ida) && hmc5883l_read(i2cdev, REG_IDB, &idb) && hmc5883l_read(i2cdev, REG_IDC, &idc) && (ida == 0x48) && (idb == 0x34) && (idc == 0x33)) { hmc5883l_write(i2cdev, REG_CFGA, 0x70); hmc5883l_write(i2cdev, REG_CFGB, 0x20); hmc5883l_write(i2cdev, REG_MODE, 0x00); } else { i2c_device_free(i2cdev); return NULL; } pdat = malloc(sizeof(struct compass_hmc5883l_pdata_t)); if(!pdat) { i2c_device_free(i2cdev); return NULL; } c = malloc(sizeof(struct compass_t)); if(!c) { i2c_device_free(i2cdev); free(pdat); return NULL; } pdat->dev = i2cdev; c->name = alloc_device_name(dt_read_name(n), -1); c->ox = 0; c->oy = 0; c->oz = 0; c->get = compass_hmc5883l_get; c->priv = pdat; if(!register_compass(&dev, c)) { i2c_device_free(pdat->dev); free_device_name(c->name); free(c->priv); free(c); return NULL; } dev->driver = drv; return dev; }
static struct device_t * clk_rk3128_gate_probe(struct driver_t * drv, struct dtnode_t * n) { struct clk_rk3128_gate_pdata_t * pdat; struct clk_t * clk; struct device_t * dev; struct dtnode_t o; virtual_addr_t virt = phys_to_virt(dt_read_address(n)); char * parent = dt_read_string(n, "parent", NULL); char * name = dt_read_string(n, "name", NULL); int shift = dt_read_int(n, "shift", -1); if(!parent || !name || (shift < 0)) return NULL; if(!search_clk(parent) || search_clk(name)) return NULL; pdat = malloc(sizeof(struct clk_rk3128_gate_pdata_t)); if(!pdat) return NULL; clk = malloc(sizeof(struct clk_t)); if(!clk) { free(pdat); return NULL; } pdat->virt = virt; pdat->parent = strdup(parent); pdat->shift = shift; pdat->invert = dt_read_bool(n, "invert", 0); clk->name = strdup(name); clk->count = 0; clk->set_parent = clk_rk3128_gate_set_parent; clk->get_parent = clk_rk3128_gate_get_parent; clk->set_enable = clk_rk3128_gate_set_enable; clk->get_enable = clk_rk3128_gate_get_enable; clk->set_rate = clk_rk3128_gate_set_rate; clk->get_rate = clk_rk3128_gate_get_rate; clk->priv = pdat; if(!register_clk(&dev, clk)) { free(pdat->parent); free(clk->name); free(clk->priv); free(clk); return NULL; } dev->driver = drv; if(dt_read_object(n, "default", &o)) { char * c = clk->name; char * p; u64_t r; int e; if((p = dt_read_string(&o, "parent", NULL)) && search_clk(p)) clk_set_parent(c, p); if((r = (u64_t)dt_read_long(&o, "rate", 0)) > 0) clk_set_rate(c, r); if((e = dt_read_bool(&o, "enable", -1)) != -1) { if(e > 0) clk_enable(c); else clk_disable(c); } } 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; }