示例#1
0
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;
}
示例#2
0
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;
}
示例#3
0
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;
}
示例#4
0
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;
}
示例#5
0
文件: battery-sbs.c 项目: xboot/xboot
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;
}
示例#6
0
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;
}
示例#7
0
文件: pwm-v3s.c 项目: xboot/xboot
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;
}
示例#8
0
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;
}
示例#9
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;
}
示例#10
0
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;
}
示例#11
0
文件: wdg-s5pv210.c 项目: xboot/xboot
static struct device_t * wdg_s5pv210_probe(struct driver_t * drv, struct dtnode_t * n)
{
	struct wdg_s5pv210_pdata_t * pdat;
	struct watchdog_t * wdg;
	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 wdg_s5pv210_pdata_t));
	if(!pdat)
		return NULL;

	wdg = malloc(sizeof(struct watchdog_t));
	if(!wdg)
	{
		free(pdat);
		return NULL;
	}

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

	wdg->name = alloc_device_name(dt_read_name(n), -1);
	wdg->set = wdg_s5pv210_set;
	wdg->get = wdg_s5pv210_get;
	wdg->priv = pdat;

	clk_enable(pdat->clk);
	write32(pdat->virt + WTCON, 0x0);
	write32(pdat->virt + WTDAT, 0x0);
	write32(pdat->virt + WTCNT, 0x0);

	if(!register_watchdog(&dev, wdg))
	{
		clk_disable(pdat->clk);
		free(pdat->clk);

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

	return dev;
}
示例#12
0
文件: buzzer-pwm.c 项目: xboot/xboot
static struct device_t * buzzer_pwm_probe(struct driver_t * drv, struct dtnode_t * n)
{
	struct buzzer_pwm_pdata_t * pdat;
	struct pwm_t * pwm;
	struct buzzer_t * buzzer;
	struct device_t * dev;

	if(!(pwm = search_pwm(dt_read_string(n, "pwm-name", NULL))))
		return NULL;

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

	buzzer = malloc(sizeof(struct buzzer_t));
	if(!buzzer)
	{
		free(pdat);
		return NULL;
	}

	timer_init(&pdat->timer, buzzer_pwm_timer_function, buzzer);
	pdat->queue = queue_alloc();
	pdat->pwm = pwm;
	pdat->polarity = dt_read_bool(n, "pwm-polarity", 0);
	pdat->frequency = -1;

	buzzer->name = alloc_device_name(dt_read_name(n), dt_read_id(n));
	buzzer->set = buzzer_pwm_set;
	buzzer->get = buzzer_pwm_get;
	buzzer->beep = buzzer_pwm_beep;
	buzzer->priv = pdat;

	buzzer_pwm_set(buzzer, 0);

	if(!register_buzzer(&dev, buzzer))
	{
		timer_cancel(&pdat->timer);
		queue_free(pdat->queue, iter_queue_node);

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

	return dev;
}
示例#13
0
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;
}
示例#14
0
文件: servo-pwm.c 项目: xboot/xboot
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;
}
示例#15
0
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;
}
示例#16
0
文件: romdisk.c 项目: xboot/xboot
static struct device_t * romdisk_probe(struct driver_t * drv, struct dtnode_t * n)
{
	struct romdisk_pdata_t * pdat;
	struct block_t * blk;
	struct device_t * dev;
	virtual_addr_t addr = strtoull(dt_read_string(n, "address", "0"), NULL, 0);
	virtual_size_t size = strtoull(dt_read_string(n, "size", "0"), NULL, 0);

	if(size <= 0)
		return NULL;
	size = (size + SZ_512) / SZ_512;

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

	blk = malloc(sizeof(struct block_t));
	if(!blk)
	{
		free(pdat);
		return NULL;
	}

	pdat->addr = addr;
	pdat->size = size;

	blk->name = alloc_device_name(dt_read_name(n), dt_read_id(n));
	blk->blksz	= SZ_512;
	blk->blkcnt	= (u64_t)size;
	blk->read = romdisk_read;
	blk->write = romdisk_write;
	blk->sync = romdisk_sync;
	blk->priv = pdat;

	if(!register_block(&dev, blk))
	{
		free_device_name(blk->name);
		free(blk->priv);
		free(blk);
		return NULL;
	}
	dev->driver = drv;

	return dev;
}
示例#17
0
static struct device_t * ledtrig_general_probe(struct driver_t * drv, struct dtnode_t * n)
{
	struct ledtrig_general_pdata_t * pdat;
	struct ledtrig_t * ledtrig;
	struct device_t * dev;
	struct led_t * led;

	led = search_led(dt_read_string(n, "led-name", NULL));
	if(!led)
		return NULL;

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

	ledtrig = malloc(sizeof(struct ledtrig_t));
	if(!ledtrig)
	{
		free(pdat);
		return NULL;
	}

	timer_init(&pdat->timer, ledtrig_general_timer_function, ledtrig);
	pdat->led = led;
	pdat->activity = 0;
	pdat->last_activity = 0;

	ledtrig->name = alloc_device_name(dt_read_name(n), dt_read_id(n));
	ledtrig->activity = ledtrig_general_activity;
	ledtrig->priv = pdat;

	if(!register_ledtrig(&dev, ledtrig))
	{
		timer_cancel(&pdat->timer);

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

	return dev;
}
示例#18
0
static struct device_t * wdog_bcm2836_probe(struct driver_t * drv, struct dtnode_t * n)
{
    struct wdog_bcm2836_pdata_t * pdat;
    struct watchdog_t * wdog;
    struct device_t * dev;
    virtual_addr_t virt = phys_to_virt(dt_read_address(n));

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

    wdog = malloc(sizeof(struct watchdog_t));
    if(!wdog)
    {
        free(pdat);
        return NULL;
    }

    pdat->virt = virt;
    pdat->start = 0;

    wdog->name = alloc_device_name(dt_read_name(n), -1);
    wdog->set = wdog_bcm2836_set;
    wdog->get = wdog_bcm2836_get,
          wdog->priv = pdat;

    if(!register_watchdog(&dev, wdog))
    {
        free_device_name(wdog->name);
        free(wdog->priv);
        free(wdog);
        return NULL;
    }
    dev->driver = drv;

    return dev;
}
示例#19
0
static struct device_t * console_sandbox_probe(struct driver_t * drv, struct dtnode_t * n)
{
	struct console_t * console;
	struct device_t * dev;

	console = malloc(sizeof(struct console_t));
	if(!console)
		return NULL;

	console->name = alloc_device_name(dt_read_name(n), dt_read_id(n));
	console->read = console_sandbox_read;
	console->write = console_sandbox_write;
	console->priv = NULL;

	if(!register_console(&dev, console))
	{
		free_device_name(console->name);
		free(console);
		return NULL;
	}
	dev->driver = drv;

	return dev;
}
示例#20
0
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;
}
示例#21
0
文件: motor-gpio.c 项目: xboot/xboot
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;
}
示例#22
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;
}
示例#23
0
文件: gpio-pl061.c 项目: xboot/xboot
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;
}
示例#24
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;
}
示例#25
0
文件: sdhci-v3s.c 项目: xboot/xboot
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;
}
示例#26
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;
}
示例#27
0
文件: fb-f1c500s.c 项目: xboot/xboot
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;
}
示例#28
0
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;
}
示例#29
0
文件: spi-rk3128.c 项目: xboot/xboot
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;
}
示例#30
0
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;
}