예제 #1
0
static int
parse_dts(struct ckb_softc *sc)
{
	phandle_t node;
	pcell_t dts_value;
	int len;

	if ((node = ofw_bus_get_node(sc->dev)) == -1)
		return (ENXIO);

	if ((len = OF_getproplen(node, "keypad,num-rows")) <= 0)
		return (ENXIO);
	OF_getprop(node, "keypad,num-rows", &dts_value, len);
	sc->rows = fdt32_to_cpu(dts_value);

	if ((len = OF_getproplen(node, "keypad,num-columns")) <= 0)
		return (ENXIO);
	OF_getprop(node, "keypad,num-columns", &dts_value, len);
	sc->cols = fdt32_to_cpu(dts_value);

	if ((sc->rows == 0) || (sc->cols == 0))
		return (ENXIO);

	return (0);
}
예제 #2
0
파일: micphy.c 프로젝트: Lxg1582/freebsd
static int
ksz9021_load_values(struct mii_softc *sc, phandle_t node, uint32_t reg,
			char *field1, char *field2,
			char *field3, char *field4)
{
	pcell_t dts_value[1];
	int len;
	int val;

	val = 0;

	if ((len = OF_getproplen(node, field1)) > 0) {
		OF_getencprop(node, field1, dts_value, len);
		val = PS_TO_REG(dts_value[0]);
	}

	if ((len = OF_getproplen(node, field2)) > 0) {
		OF_getencprop(node, field2, dts_value, len);
		val |= PS_TO_REG(dts_value[0]) << 4;
	}

	if ((len = OF_getproplen(node, field3)) > 0) {
		OF_getencprop(node, field3, dts_value, len);
		val |= PS_TO_REG(dts_value[0]) << 8;
	}

	if ((len = OF_getproplen(node, field4)) > 0) {
		OF_getencprop(node, field4, dts_value, len);
		val |= PS_TO_REG(dts_value[0]) << 12;
	}

	micphy_write(sc, reg, val);

	return (0);
}
예제 #3
0
파일: chrome_kb.c 프로젝트: Alkzndr/freebsd
static int
parse_dts(struct ckb_softc *sc)
{
	phandle_t node;
	pcell_t dts_value;
	pcell_t *keymap;
	int len, ret;
	const char *keymap_prop = NULL;

	if ((node = ofw_bus_get_node(sc->dev)) == -1)
		return (ENXIO);

	if ((len = OF_getproplen(node, "google,key-rows")) <= 0)
		return (ENXIO);
	OF_getencprop(node, "google,key-rows", &dts_value, len);
	sc->rows = dts_value;

	if ((len = OF_getproplen(node, "google,key-columns")) <= 0)
		return (ENXIO);
	OF_getencprop(node, "google,key-columns", &dts_value, len);
	sc->cols = dts_value;

	if ((len = OF_getproplen(node, "freebsd,intr-gpio")) <= 0)
		return (ENXIO);
	OF_getencprop(node, "freebsd,intr-gpio", &dts_value, len);
	sc->gpio = dts_value;

	if (OF_hasprop(node, "freebsd,keymap")) {
		keymap_prop = "freebsd,keymap";
		device_printf(sc->dev, "using FreeBSD-specific keymap from FDT\n");
	} else if (OF_hasprop(node, "linux,keymap")) {
		keymap_prop = "linux,keymap";
		device_printf(sc->dev, "using Linux keymap from FDT\n");
	} else {
		device_printf(sc->dev, "using built-in keymap\n");
	}

	if (keymap_prop != NULL) {
		if ((ret = read_keymap(node, keymap_prop, &keymap, &len))) {
			device_printf(sc->dev,
			     "failed to read keymap from FDT: %d\n", ret);
			return (ret);
		}
		ret = parse_keymap(sc, keymap, len);
		free(keymap, M_DEVBUF);
		if (ret) {
			return (ret);
		}
	} else {
		if ((ret = parse_keymap(sc, default_keymap, KEYMAP_LEN))) {
			return (ret);
		}
	}

	if ((sc->rows == 0) || (sc->cols == 0) || (sc->gpio == 0))
		return (ENXIO);

	return (0);
}
예제 #4
0
asmlinkage void ofw_init(ofw_handle_t o, int *nomr, int *pointer)
{
	int phandle,i,mem_len,buffer[32];
	char temp[12];
  
	temp[0]='/';
	temp[1]='m';
	temp[2]='e';
	temp[3]='m';
	temp[4]='o';
	temp[5]='r';
	temp[6]='y';
	temp[7]='\0';

	phandle=OF_finddevice(o,temp);

	temp[0]='r';
	temp[1]='e';
	temp[2]='g';
	temp[3]='\0';

	mem_len = OF_getproplen(o,phandle, temp);
	OF_getprop(o,phandle, temp, buffer, mem_len);
	*nomr=mem_len >> 3;

	for (i=0; i<=mem_len/4; i++) pointer[i]=of_decode_int((const unsigned char *)&buffer[i]);

	temp[0]='/';
	temp[1]='c';
	temp[2]='h';
	temp[3]='o';
	temp[4]='s';
	temp[5]='e';
	temp[6]='n';
	temp[7]='\0';

	phandle=OF_finddevice(o,temp);

	temp[0]='b';
	temp[1]='o';
	temp[2]='o';
	temp[3]='t';
	temp[4]='a';
	temp[5]='r';
	temp[6]='g';
	temp[7]='s';
	temp[8]='\0';

	mem_len = OF_getproplen(o,phandle, temp);
	OF_getprop(o,phandle, temp, buffer, mem_len);
	for (i=0; i<=mem_len/4; i++) pointer[i+32]=buffer[i];
  
}
예제 #5
0
int
ofw_bus_is_compatible(device_t dev, const char *onecompat)
{
	phandle_t node;
	const char *compat;
	int len, onelen, l;

	if ((compat = ofw_bus_get_compat(dev)) == NULL)
		return (0);

	if ((node = ofw_bus_get_node(dev)) == -1)
		return (0);

	/* Get total 'compatible' prop len */
	if ((len = OF_getproplen(node, "compatible")) <= 0)
		return (0);

	onelen = strlen(onecompat);

	while (len > 0) {
		if (strlen(compat) == onelen &&
		    strncasecmp(compat, onecompat, onelen) == 0)
			/* Found it. */
			return (1);

		/* Slide to the next sub-string. */
		l = strlen(compat) + 1;
		compat += l;
		len -= l;
	}
	return (0);
}
예제 #6
0
static int
opaldev_probe(device_t dev)
{
	phandle_t iparent;
	pcell_t *irqs;
	int i, n_irqs;

	if (!ofw_bus_is_compatible(dev, "ibm,opal-v3"))
		return (ENXIO);
	if (opal_check() != 0)
		return (ENXIO);

	device_set_desc(dev, "OPAL Abstraction Firmware");

	/* Manually add IRQs before attaching */
	if (OF_hasprop(ofw_bus_get_node(dev), "opal-interrupts")) {
		iparent = OF_finddevice("/interrupt-controller@0");
		iparent = OF_xref_from_node(iparent);

		n_irqs = OF_getproplen(ofw_bus_get_node(dev),
                    "opal-interrupts") / sizeof(*irqs);
		irqs = malloc(n_irqs * sizeof(*irqs), M_DEVBUF, M_WAITOK);
		OF_getencprop(ofw_bus_get_node(dev), "opal-interrupts", irqs,
		    n_irqs * sizeof(*irqs));
		for (i = 0; i < n_irqs; i++)
			bus_set_resource(dev, SYS_RES_IRQ, i,
			    ofw_bus_map_intr(dev, iparent, 1, &irqs[i]), 1);
		free(irqs, M_DEVBUF);
	}


	return (BUS_PROBE_SPECIFIC);
}
예제 #7
0
파일: ofwpci.c 프로젝트: 2asoft/freebsd
int
ofw_pci_nranges(phandle_t node, struct ofw_pci_cell_info *info)
{
	ssize_t nbase_ranges;

	if (info == NULL)
		return (-1);

	info->host_address_cells = 1;
	info->size_cells = 2;
	info->pci_address_cell = 3;

	OF_getencprop(OF_parent(node), "#address-cells",
	    &(info->host_address_cells), sizeof(info->host_address_cells));
	OF_getencprop(node, "#address-cells",
	    &(info->pci_address_cell), sizeof(info->pci_address_cell));
	OF_getencprop(node, "#size-cells", &(info->size_cells),
	    sizeof(info->size_cells));

	nbase_ranges = OF_getproplen(node, "ranges");
	if (nbase_ranges <= 0)
		return (-1);

	return (nbase_ranges / sizeof(cell_t) /
	    (info->pci_address_cell + info->host_address_cells +
	    info->size_cells));
}
예제 #8
0
static int
ofw_get_console_phandle_path(phandle_t node, phandle_t *result,
    const char *prop)
{
	union {
		char buf[64];
		phandle_t ref;
	} field;
	phandle_t output;
	ssize_t size;

	size = OF_getproplen(node, prop);
	if (size == -1)
		return (ENXIO);
	OF_getprop(node, prop, &field, sizeof(field));

	/* This property might be either a ihandle or path. Hooray. */

	output = -1;
	if (field.buf[size - 1] == 0)
		output = OF_finddevice(field.buf);
	if (output == -1 && size == 4)
		output = OF_instance_to_package(field.ref);
	
	if (output != -1) {
		*result = output;
		return (0);
	}

	return (ENXIO);
}
예제 #9
0
/*
 * This routine is an early-usage version of the ofw_bus_is_compatible() when
 * the ofw_bus I/F is not available (like early console routines and similar).
 * Note the buffer has to be on the stack since malloc() is usually not
 * available in such cases either.
 */
int
fdt_is_compatible(phandle_t node, const char *compatstr)
{
	char buf[FDT_COMPAT_LEN];
	char *compat;
	int len, onelen, l, rv;

	if ((len = OF_getproplen(node, "compatible")) <= 0)
		return (0);

	compat = (char *)&buf;
	bzero(compat, FDT_COMPAT_LEN);

	if (OF_getprop(node, "compatible", compat, FDT_COMPAT_LEN) < 0)
		return (0);

	onelen = strlen(compatstr);
	rv = 0;
	while (len > 0) {
		if (strncasecmp(compat, compatstr, onelen) == 0) {
			/* Found it. */
			rv = 1;
			break;
		}
		/* Slide to the next sub-string. */
		l = strlen(compat) + 1;
		compat += l;
		len -= l;
	}

	return (rv);
}
예제 #10
0
int
com_ebus_match(struct device *parent, void *match, void *aux)
{
	struct ebus_attach_args *ea = aux;
	int i;

	for (i=0; com_names[i]; i++)
		if (strcmp(ea->ea_name, com_names[i]) == 0)
			return (1);

	if (strcmp(ea->ea_name, "serial") == 0) {
		char compat[80];

		/* Could be anything. */
		if ((i = OF_getproplen(ea->ea_node, "compatible")) &&
			OF_getprop(ea->ea_node, "compatible", compat,
				sizeof(compat)) == i) {
			if (strcmp(compat, "su16552") == 0 ||
			    strcmp(compat, "su16550") == 0 ||
			    strcmp(compat, "FJSV,su") == 0 ||
			    strcmp(compat, "su") == 0) {
				return (1);
			}
		}
	}
	return (0);
}
예제 #11
0
static int
get_panel_info(struct fimd_softc *sc, struct panel_info *panel)
{
	phandle_t node;
	pcell_t dts_value[3];
	int len;

	if ((node = ofw_bus_get_node(sc->dev)) == -1)
		return (ENXIO);

	/* panel size */
	if ((len = OF_getproplen(node, "panel-size")) <= 0)
		return (ENXIO);
	OF_getprop(node, "panel-size", &dts_value, len);
	panel->width = fdt32_to_cpu(dts_value[0]);
	panel->height = fdt32_to_cpu(dts_value[1]);

	/* hsync */
	if ((len = OF_getproplen(node, "panel-hsync")) <= 0)
		return (ENXIO);
	OF_getprop(node, "panel-hsync", &dts_value, len);
	panel->h_back_porch = fdt32_to_cpu(dts_value[0]);
	panel->h_pulse_width = fdt32_to_cpu(dts_value[1]);
	panel->h_front_porch = fdt32_to_cpu(dts_value[2]);

	/* vsync */
	if ((len = OF_getproplen(node, "panel-vsync")) <= 0)
		return (ENXIO);
	OF_getprop(node, "panel-vsync", &dts_value, len);
	panel->v_back_porch = fdt32_to_cpu(dts_value[0]);
	panel->v_pulse_width = fdt32_to_cpu(dts_value[1]);
	panel->v_front_porch = fdt32_to_cpu(dts_value[2]);

	/* clk divider */
	if ((len = OF_getproplen(node, "panel-clk-div")) <= 0)
		return (ENXIO);
	OF_getprop(node, "panel-clk-div", &dts_value, len);
	panel->clk_div = fdt32_to_cpu(dts_value[0]);

	/* backlight pin */
	if ((len = OF_getproplen(node, "panel-backlight-pin")) <= 0)
		return (ENXIO);
	OF_getprop(node, "panel-backlight-pin", &dts_value, len);
	panel->backlight_pin = fdt32_to_cpu(dts_value[0]);

	return (0);
}
예제 #12
0
int
fdt_get_range(phandle_t node, int range_id, u_long *base, u_long *size)
{
	pcell_t ranges[6], *rangesptr;
	pcell_t addr_cells, size_cells, par_addr_cells;
	u_long par_bus_addr, pbase, psize;
	int err, len, tuple_size, tuples;

	if ((fdt_addrsize_cells(node, &addr_cells, &size_cells)) != 0)
		return (ENXIO);
	/*
	 * Process 'ranges' property.
	 */
	par_addr_cells = fdt_parent_addr_cells(node);
	if (par_addr_cells > 2)
		return (ERANGE);

	len = OF_getproplen(node, "ranges");
	if (len > sizeof(ranges))
		return (ENOMEM);
	if (len == 0) {
		*base = 0;
		*size = ULONG_MAX;
		return (0);
	}

	if (!(range_id < len))
		return (ERANGE);

	if (OF_getprop(node, "ranges", ranges, sizeof(ranges)) <= 0)
		return (EINVAL);

	tuple_size = sizeof(pcell_t) * (addr_cells + par_addr_cells +
	    size_cells);
	tuples = len / tuple_size;

	if (par_addr_cells > 2 || addr_cells > 2 || size_cells > 2)
		return (ERANGE);

	*base = 0;
	*size = 0;
	rangesptr = &ranges[range_id];

	*base = fdt_data_get((void *)rangesptr, addr_cells);
	rangesptr += addr_cells;

	par_bus_addr = fdt_data_get((void *)rangesptr, par_addr_cells);
	rangesptr += par_addr_cells;

	err = fdt_get_range_by_busaddr(OF_parent(node), par_bus_addr,
	   &pbase, &psize);
	if (err == 0)
		*base += pbase;
	else
		*base += par_bus_addr;

	*size = fdt_data_get((void *)rangesptr, size_cells);
	return (0);
}
예제 #13
0
파일: vbus.c 프로젝트: ajinkya93/OpenBSD
int
vbus_intr_map(int node, int ino, uint64_t *sysino)
{
	int *imap = NULL, nimap;
	int *reg = NULL, nreg;
	int *imap_mask;
	int parent;
	int address_cells, interrupt_cells;
	uint64_t devhandle;
	uint64_t devino;
	int len;
	int err;

	parent = OF_parent(node);

	address_cells = getpropint(parent, "#address-cells", 2);
	interrupt_cells = getpropint(parent, "#interrupt-cells", 1);
	KASSERT(interrupt_cells == 1);

	len = OF_getproplen(parent, "interrupt-map-mask");
	if (len < (address_cells + interrupt_cells) * sizeof(int))
		return (-1);
	imap_mask = malloc(len, M_DEVBUF, M_NOWAIT);
	if (imap_mask == NULL)
		return (-1);
	if (OF_getprop(parent, "interrupt-map-mask", imap_mask, len) != len)
		return (-1);

	getprop(parent, "interrupt-map", sizeof(int), &nimap, (void **)&imap);
	getprop(node, "reg", sizeof(*reg), &nreg, (void **)&reg);
	if (nreg < address_cells)
		return (-1);

	while (nimap >= address_cells + interrupt_cells + 2) {
		if (vbus_cmp_cells(imap, reg, imap_mask, address_cells) &&
		    vbus_cmp_cells(&imap[address_cells], &ino,
		    &imap_mask[address_cells], interrupt_cells)) {
			node = imap[address_cells + interrupt_cells];
			devino = imap[address_cells + interrupt_cells + 1];

			free(reg, M_DEVBUF, 0);
			reg = NULL;

			getprop(node, "reg", sizeof(*reg), &nreg, (void **)&reg);
			devhandle = reg[0] & 0x0fffffff;

			err = hv_intr_devino_to_sysino(devhandle, devino, sysino);
			if (err != H_EOK)
				return (-1);

			KASSERT(*sysino == INTVEC(*sysino));
			return (0);
		}
		imap += address_cells + interrupt_cells + 2;
		nimap -= address_cells + interrupt_cells + 2;
	}

	return (-1);
}
예제 #14
0
int
fdt_get_reserved_regions(struct mem_region *mr, int *mrcnt)
{
	pcell_t reserve[FDT_REG_CELLS * FDT_MEM_REGIONS];
	pcell_t *reservep;
	phandle_t memory, root;
	uint32_t memory_size;
	int addr_cells, size_cells;
	int i, max_size, res_len, rv, tuple_size, tuples;

	max_size = sizeof(reserve);
	root = OF_finddevice("/");
	memory = OF_finddevice("/memory");
	if (memory == -1) {
		rv = ENXIO;
		goto out;
	}

	if ((rv = fdt_addrsize_cells(OF_parent(memory), &addr_cells,
	    &size_cells)) != 0)
		goto out;

	if (addr_cells > 2) {
		rv = ERANGE;
		goto out;
	}

	tuple_size = sizeof(pcell_t) * (addr_cells + size_cells);

	res_len = OF_getproplen(root, "memreserve");
	if (res_len <= 0 || res_len > sizeof(reserve)) {
		rv = ERANGE;
		goto out;
	}

	if (OF_getprop(root, "memreserve", reserve, res_len) <= 0) {
		rv = ENXIO;
		goto out;
	}

	memory_size = 0;
	tuples = res_len / tuple_size;
	reservep = (pcell_t *)&reserve;
	for (i = 0; i < tuples; i++) {

		rv = fdt_data_to_res(reservep, addr_cells, size_cells,
			(u_long *)&mr[i].mr_start, (u_long *)&mr[i].mr_size);

		if (rv != 0)
			goto out;

		reservep += addr_cells + size_cells;
	}

	*mrcnt = i;
	rv = 0;
out:
	return (rv);
}
예제 #15
0
static int
vt_efb_probe(struct vt_device *vd)
{
	phandle_t node;

	node = vt_efb_get_fbnode();
	if (node == -1)
		return (CN_DEAD);

	if ((OF_getproplen(node, "height") <= 0) ||
	    (OF_getproplen(node, "width") <= 0) ||
	    (OF_getproplen(node, "depth") <= 0) ||
	    (OF_getproplen(node, "linebytes") <= 0))
		return (CN_DEAD);

	return (CN_INTERNAL);
}
예제 #16
0
파일: ti_scm.c 프로젝트: vkhromov/freebsd
/**
 *	ti_scm_padconf_init_from_hints - processes the hints for padconf
 *	@sc: the driver soft context
 *
 *	
 *
 *	LOCKING:
 *	Internally locks it's own context.
 *
 *	RETURNS:
 *	0 on success.
 *	EINVAL if pin requested is outside valid range or already in use.
 */
static int
ti_scm_padconf_init_from_fdt(struct ti_scm_softc *sc)
{
	const struct ti_scm_padconf *padconf;
	const struct ti_scm_padstate *padstates;
	int err;
	phandle_t node;
	int len;
	char *fdt_pad_config;
	int i;
	char *padname, *muxname, *padstate;

	node = ofw_bus_get_node(sc->sc_dev);
	len = OF_getproplen(node, "scm-pad-config");
        OF_getprop_alloc(node, "scm-pad-config", 1, (void **)&fdt_pad_config);

	i = len;
	while (i > 0) {
		padname = fdt_pad_config;
		fdt_pad_config += strlen(padname) + 1;
		i -= strlen(padname) + 1;
		if (i <= 0)
			break;

		muxname = fdt_pad_config;
		fdt_pad_config += strlen(muxname) + 1;
		i -= strlen(muxname) + 1;
		if (i <= 0)
			break;

		padstate = fdt_pad_config;
		fdt_pad_config += strlen(padstate) + 1;
		i -= strlen(padstate) + 1;
		if (i < 0)
			break;

		padconf = ti_scm_dev.padconf;

		while (padconf->ballname != NULL) {
			if (strcmp(padconf->ballname, padname) == 0) {
				padstates = ti_scm_dev.padstate;
				err = 1;
				while (padstates->state != NULL) {
					if (strcmp(padstates->state, padstate) == 0) {
						err = ti_scm_padconf_set_internal(sc,
							padconf, muxname, padstates->reg);
					}
					padstates++;
				}
				if (err)
					device_printf(sc->sc_dev, "err: failed to configure"
						"pin \"%s\"\n", padconf->ballname);
			}
			padconf++;
		}
	}
	return (0);
}
예제 #17
0
static void
ksz90x1_load_values(struct mii_softc *sc, phandle_t node,
    uint32_t dev, uint32_t reg, char *field1, uint32_t f1mask, int f1off,
    char *field2, uint32_t f2mask, int f2off, char *field3, uint32_t f3mask,
    int f3off, char *field4, uint32_t f4mask, int f4off)
{
	pcell_t dts_value[1];
	int len;
	int val;

	if (sc->mii_mpd_model == MII_MODEL_MICREL_KSZ9031)
		val = ksz9031_read(sc, dev, reg);
	else
		val = ksz9021_read(sc, reg);

	if ((len = OF_getproplen(node, field1)) > 0) {
		OF_getencprop(node, field1, dts_value, len);
		val &= ~(f1mask << f1off);
		val |= (PS_TO_REG(dts_value[0]) & f1mask) << f1off;
	}

	if (field2 != NULL && (len = OF_getproplen(node, field2)) > 0) {
		OF_getencprop(node, field2, dts_value, len);
		val &= ~(f2mask << f2off);
		val |= (PS_TO_REG(dts_value[0]) & f2mask) << f2off;
	}

	if (field3 != NULL && (len = OF_getproplen(node, field3)) > 0) {
		OF_getencprop(node, field3, dts_value, len);
		val &= ~(f3mask << f3off);
		val |= (PS_TO_REG(dts_value[0]) & f3mask) << f3off;
	}

	if (field4 != NULL && (len = OF_getproplen(node, field4)) > 0) {
		OF_getencprop(node, field4, dts_value, len);
		val &= ~(f4mask << f4off);
		val |= (PS_TO_REG(dts_value[0]) & f4mask) << f4off;
	}

	if (sc->mii_mpd_model == MII_MODEL_MICREL_KSZ9031)
		ksz9031_write(sc, dev, reg, val);
	else
		ksz9021_write(sc, reg, val);
}
예제 #18
0
파일: twl.c 프로젝트: ele7enxxh/dtrace-pf
/**
 *	twl_probe - 
 *	@dev: the twl device
 *
 *	Scans the FDT for a match for the device, possible compatible device
 *	strings are; "ti,twl6030", "ti,twl6025", "ti,twl4030".  
 *
 *	The FDT compat string also determines the type of device (it is currently
 *	not possible to dynamically determine the device type).
 *
 */
static int
twl_probe(device_t dev)
{
	phandle_t node;
	const char *compat;
	int len, l;
	struct twl_softc *sc;

	if ((compat = ofw_bus_get_compat(dev)) == NULL)
		return (ENXIO);

	if ((node = ofw_bus_get_node(dev)) == 0)
		return (ENXIO);

	/* Get total 'compatible' prop len */
	if ((len = OF_getproplen(node, "compatible")) <= 0)
		return (ENXIO);

	sc = device_get_softc(dev);
	sc->sc_dev = dev;
	sc->sc_type = TWL_DEVICE_UNKNOWN;

	while (len > 0) {
		if (strncasecmp(compat, "ti,twl6030", 10) == 0)
			sc->sc_type = TWL_DEVICE_6030;
		else if (strncasecmp(compat, "ti,twl6025", 10) == 0)
			sc->sc_type = TWL_DEVICE_6025;
		else if (strncasecmp(compat, "ti,twl4030", 10) == 0)
			sc->sc_type = TWL_DEVICE_4030;
		
		if (sc->sc_type != TWL_DEVICE_UNKNOWN)
			break;

		/* Slide to the next sub-string. */
		l = strlen(compat) + 1;
		compat += l;
		len -= l;
	}
	
	switch (sc->sc_type) {
	case TWL_DEVICE_4030:
		device_set_desc(dev, "TI TWL4030/TPS659x0 Companion IC");
		break;
	case TWL_DEVICE_6025:
		device_set_desc(dev, "TI TWL6025 Companion IC");
		break;
	case TWL_DEVICE_6030:
		device_set_desc(dev, "TI TWL6030 Companion IC");
		break;
	case TWL_DEVICE_UNKNOWN:
	default:
		return (ENXIO);
	}
	
	return (0);
}
예제 #19
0
파일: psci.c 프로젝트: fengsi/freebsd
static int
psci_v0_1_init(device_t dev)
{
    struct psci_softc *sc = device_get_softc(dev);
    int psci_fn;
    uint32_t psci_fnid;
    phandle_t node;
    int len;


    /* Zero out the function ID table - Is this needed ? */
    for (psci_fn = PSCI_FN_VERSION, psci_fnid = PSCI_FNID_VERSION;
            psci_fn < PSCI_FN_MAX; psci_fn++, psci_fnid++)
        sc->psci_fnids[psci_fn] = 0;

    /* PSCI v0.1 doesn't specify function IDs. Get them from DT */
    node = ofw_bus_get_node(dev);

    if ((len = OF_getproplen(node, "cpu_suspend")) > 0) {
        OF_getencprop(node, "cpu_suspend", &psci_fnid, len);
        sc->psci_fnids[PSCI_FN_CPU_SUSPEND] = psci_fnid;
    }

    if ((len = OF_getproplen(node, "cpu_on")) > 0) {
        OF_getencprop(node, "cpu_on", &psci_fnid, len);
        sc->psci_fnids[PSCI_FN_CPU_ON] = psci_fnid;
    }

    if ((len = OF_getproplen(node, "cpu_off")) > 0) {
        OF_getencprop(node, "cpu_off", &psci_fnid, len);
        sc->psci_fnids[PSCI_FN_CPU_OFF] = psci_fnid;
    }

    if ((len = OF_getproplen(node, "migrate")) > 0) {
        OF_getencprop(node, "migrate", &psci_fnid, len);
        sc->psci_fnids[PSCI_FN_MIGRATE] = psci_fnid;
    }

    if (bootverbose)
        device_printf(dev, "PSCI version 0.1 available\n");

    return(0);
}
예제 #20
0
static int
rk30_gpio_init(void)
{
	phandle_t child, parent, root, ctrl;
	pcell_t gpios[MAX_PINS_PER_NODE * GPIOS_PROP_CELLS];
	struct gpio_ctrl_entry *e;
	int len, rv;

	root = OF_finddevice("/");
	len = 0;
	parent = root;

	/* Traverse through entire tree to find nodes with 'gpios' prop */
	for (child = OF_child(parent); child != 0; child = OF_peer(child)) {

		/* Find a 'leaf'. Start the search from this node. */
		while (OF_child(child)) {
			parent = child;
			child = OF_child(child);
		}
		if ((len = OF_getproplen(child, "gpios")) > 0) {

			if (len > sizeof(gpios))
				return (ENXIO);

			/* Get 'gpios' property. */
			OF_getprop(child, "gpios", &gpios, len);

			e = (struct gpio_ctrl_entry *)&gpio_controllers;

			/* Find and call a handler. */
			for (; e->compat; e++) {
				/*
				 * First cell of 'gpios' property should
				 * contain a ref. to a node defining GPIO
				 * controller.
				 */
				ctrl = OF_node_from_xref(fdt32_to_cpu(gpios[0]));

				if (fdt_is_compatible(ctrl, e->compat))
					/* Call a handler. */
					if ((rv = e->handler(ctrl,
					    (pcell_t *)&gpios, len)))
						return (rv);
			}
		}

		if (OF_peer(child) == 0) {
			/* No more siblings. */
			child = parent;
			parent = OF_parent(child);
		}
	}
	return (0);
}
예제 #21
0
파일: vf_edma.c 프로젝트: coyizumi/cs111
static int
edma_attach(device_t dev)
{
	struct edma_softc *sc;
	phandle_t node;
	int dts_value;
	int len;

	sc = device_get_softc(dev);
	sc->dev = dev;

	if ((node = ofw_bus_get_node(sc->dev)) == -1)
		return (ENXIO);

	if ((len = OF_getproplen(node, "device-id")) <= 0)
		return (ENXIO);

	OF_getprop(node, "device-id", &dts_value, len);
	sc->device_id = fdt32_to_cpu(dts_value);

	sc->dma_stop = dma_stop;
	sc->dma_setup = dma_setup;
	sc->dma_request = dma_request;
	sc->channel_configure = channel_configure;
	sc->channel_free = channel_free;

	if (bus_alloc_resources(dev, edma_spec, sc->res)) {
		device_printf(dev, "could not allocate resources\n");
		return (ENXIO);
	}

	/* Memory interface */
	sc->bst = rman_get_bustag(sc->res[0]);
	sc->bsh = rman_get_bushandle(sc->res[0]);
	sc->bst_tcd = rman_get_bustag(sc->res[1]);
	sc->bsh_tcd = rman_get_bushandle(sc->res[1]);

	/* Setup interrupt handlers */
	if (bus_setup_intr(dev, sc->res[2], INTR_TYPE_BIO | INTR_MPSAFE,
		NULL, edma_transfer_complete_intr, sc, &sc->tc_ih)) {
		device_printf(dev, "Unable to alloc DMA intr resource.\n");
		return (ENXIO);
	}

	if (bus_setup_intr(dev, sc->res[3], INTR_TYPE_BIO | INTR_MPSAFE,
		NULL, edma_err_intr, sc, &sc->err_ih)) {
		device_printf(dev, "Unable to alloc DMA Err intr resource.\n");
		return (ENXIO);
	}

	return (0);
}
예제 #22
0
파일: vf_iomuxc.c 프로젝트: 2asoft/freebsd
static int
pinmux_set(struct iomuxc_softc *sc)
{
	phandle_t child, parent, root;
	pcell_t iomux_config[MAX_MUX_LEN];
	int len;
	int values;
	int pin;
	int pin_cfg;
	int i;

	root = OF_finddevice("/");
	len = 0;
	parent = root;

	/* Find 'iomux_config' prop in the nodes */
	for (child = OF_child(parent); child != 0; child = OF_peer(child)) {

		/* Find a 'leaf'. Start the search from this node. */
		while (OF_child(child)) {
			parent = child;
			child = OF_child(child);
		}

		if (!fdt_is_enabled(child))
			continue;

		if ((len = OF_getproplen(child, "iomux_config")) > 0) {
			OF_getprop(child, "iomux_config", &iomux_config, len);

			values = len / (sizeof(uint32_t));
			for (i = 0; i < values; i += 2) {
				pin = fdt32_to_cpu(iomux_config[i]);
				pin_cfg = fdt32_to_cpu(iomux_config[i+1]);
#if 0
				device_printf(sc->dev, "Set pin %d to 0x%08x\n",
				    pin, pin_cfg);
#endif
				WRITE4(sc, IOMUXC(pin), pin_cfg);
			}
		}

		if (OF_peer(child) == 0) {
			/* No more siblings. */
			child = parent;
			parent = OF_parent(child);
		}
	}

	return (0);
}
예제 #23
0
/*
 * This function replaces sys/dev/cninit.c
 * Determine which device is the console using
 * the PROM "input source" and "output sink".
 */
void
consinit()
{
	register int chosen;
	char buffer[128];
	extern int stdinnode, fbnode;
	char *consname = "unknown";
	
	DBPRINT(("consinit()\r\n"));
	if (cn_tab != &consdev_prom) return;
	
	DBPRINT(("setting up stdin\r\n"));
	chosen = OF_finddevice("/chosen");
	OF_getprop(chosen, "stdin",  &stdin, sizeof(stdin));
	DBPRINT(("stdin instance = %x\r\n", stdin));
	
	if ((stdinnode = OF_instance_to_package(stdin)) == 0) {
		printf("WARNING: no PROM stdin\n");
	}
#if NUKBD > 0
	else {
		if (OF_getprop(stdinnode, "compatible", buffer,
		    sizeof(buffer)) != -1 && strncmp("usb", buffer, 3) == 0)
			ukbd_cnattach();
	}
#endif

	DBPRINT(("setting up stdout\r\n"));
	OF_getprop(chosen, "stdout", &stdout, sizeof(stdout));
	
	DBPRINT(("stdout instance = %x\r\n", stdout));
	
	if ((fbnode = OF_instance_to_package(stdout)) == 0)
		printf("WARNING: no PROM stdout\n");
	
	DBPRINT(("stdout package = %x\r\n", fbnode));
	
	if (stdinnode && (OF_getproplen(stdinnode,"keyboard") >= 0)) {
		consname = "keyboard/display";
	} else if (fbnode && 
		   (OF_instance_to_path(stdin, buffer, sizeof(buffer)) >= 0)) {
		consname = buffer;
	}
	printf("console is %s\n", consname);
 
	/* Initialize PROM console */
	(*cn_tab->cn_probe)(cn_tab);
	(*cn_tab->cn_init)(cn_tab);
}
예제 #24
0
파일: chrome_kb.c 프로젝트: Alkzndr/freebsd
/* Allocates a new array for keymap and returns it in 'keymap'. */
static int
read_keymap(phandle_t node, const char *prop, pcell_t **keymap, size_t *len)
{

	if ((*len = OF_getproplen(node, prop)) <= 0) {
		return (ENXIO);
	}
	if ((*keymap = malloc(*len, M_DEVBUF, M_NOWAIT)) == NULL) {
		return (ENOMEM);
	}
	if (OF_getencprop(node, prop, *keymap, *len) != *len) {
		return (ENXIO);
	}
	return (0);
}
예제 #25
0
static int
simplebus_fill_ranges(phandle_t node, struct simplebus_softc *sc)
{
	int host_address_cells;
	cell_t *base_ranges;
	ssize_t nbase_ranges;
	int err;
	int i, j, k;

	err = OF_searchencprop(OF_parent(node), "#address-cells",
	    &host_address_cells, sizeof(host_address_cells));
	if (err <= 0)
		return (-1);

	nbase_ranges = OF_getproplen(node, "ranges");
	if (nbase_ranges < 0)
		return (-1);
	sc->nranges = nbase_ranges / sizeof(cell_t) /
	    (sc->acells + host_address_cells + sc->scells);
	if (sc->nranges == 0)
		return (0);

	sc->ranges = malloc(sc->nranges * sizeof(sc->ranges[0]),
	    M_DEVBUF, M_WAITOK);
	base_ranges = malloc(nbase_ranges, M_DEVBUF, M_WAITOK);
	OF_getencprop(node, "ranges", base_ranges, nbase_ranges);

	for (i = 0, j = 0; i < sc->nranges; i++) {
		sc->ranges[i].bus = 0;
		for (k = 0; k < sc->acells; k++) {
			sc->ranges[i].bus <<= 32;
			sc->ranges[i].bus |= base_ranges[j++];
		}
		sc->ranges[i].host = 0;
		for (k = 0; k < host_address_cells; k++) {
			sc->ranges[i].host <<= 32;
			sc->ranges[i].host |= base_ranges[j++];
		}
		sc->ranges[i].size = 0;
		for (k = 0; k < sc->scells; k++) {
			sc->ranges[i].size <<= 32;
			sc->ranges[i].size |= base_ranges[j++];
		}
	}

	free(base_ranges, M_DEVBUF);
	return (sc->nranges);
}
예제 #26
0
int
ofw_bus_node_status_okay(phandle_t node)
{
	char status[OFW_STATUS_LEN];
	int len;

	len = OF_getproplen(node, "status");
	if (len <= 0)
		return (1);

	OF_getprop(node, "status", status, OFW_STATUS_LEN);
	if ((len == 5 && (bcmp(status, "okay", len) == 0)) ||
	    (len == 3 && (bcmp(status, "ok", len))))
		return (1);

	return (0);
}
예제 #27
0
static int
ofw_pci_fill_ranges(phandle_t node, struct ofw_pci_range *ranges)
{
	int host_address_cells = 1, pci_address_cells = 3, size_cells = 2;
	cell_t *base_ranges;
	ssize_t nbase_ranges;
	int nranges;
	int i, j, k;

	OF_getprop(OF_parent(node), "#address-cells", &host_address_cells,
	    sizeof(host_address_cells));
	OF_getprop(node, "#address-cells", &pci_address_cells,
	    sizeof(pci_address_cells));
	OF_getprop(node, "#size-cells", &size_cells, sizeof(size_cells));

	nbase_ranges = OF_getproplen(node, "ranges");
	if (nbase_ranges <= 0)
		return (-1);
	nranges = nbase_ranges / sizeof(cell_t) /
	    (pci_address_cells + host_address_cells + size_cells);

	base_ranges = malloc(nbase_ranges, M_DEVBUF, M_WAITOK);
	OF_getprop(node, "ranges", base_ranges, nbase_ranges);

	for (i = 0, j = 0; i < nranges; i++) {
		ranges[i].pci_hi = base_ranges[j++];
		ranges[i].pci = 0;
		for (k = 0; k < pci_address_cells - 1; k++) {
			ranges[i].pci <<= 32;
			ranges[i].pci |= base_ranges[j++];
		}
		ranges[i].host = 0;
		for (k = 0; k < host_address_cells; k++) {
			ranges[i].host <<= 32;
			ranges[i].host |= base_ranges[j++];
		}
		ranges[i].size = 0;
		for (k = 0; k < size_cells; k++) {
			ranges[i].size <<= 32;
			ranges[i].size |= base_ranges[j++];
		}
	}

	free(base_ranges, M_DEVBUF);
	return (nranges);
}
예제 #28
0
int
fdt_is_compatible_strict(phandle_t node, const char *compatible)
{
	char compat[FDT_COMPAT_LEN];

	if (OF_getproplen(node, "compatible") <= 0)
		return (0);

	if (OF_getprop(node, "compatible", compat, FDT_COMPAT_LEN) < 0)
		return (0);

	if (strncasecmp(compat, compatible, FDT_COMPAT_LEN) == 0)
		/* This fits. */
		return (1);

	return (0);
}
예제 #29
0
int
fdt_is_type(phandle_t node, const char *typestr)
{
	char type[FDT_TYPE_LEN];

	if (OF_getproplen(node, "device_type") <= 0)
		return (0);

	if (OF_getprop(node, "device_type", type, FDT_TYPE_LEN) < 0)
		return (0);

	if (strncasecmp(type, typestr, FDT_TYPE_LEN) == 0)
		/* This fits. */
		return (1);

	return (0);
}
예제 #30
0
파일: rtas_pci.c 프로젝트: 2asoft/freebsd
static int
rtaspci_probe(device_t dev)
{
	const char	*type;

	if (!rtas_exists())
		return (ENXIO);

	type = ofw_bus_get_type(dev);

	if (OF_getproplen(ofw_bus_get_node(dev), "used-by-rtas") < 0)
		return (ENXIO);
	if (type == NULL || strcmp(type, "pci") != 0)
		return (ENXIO);

	device_set_desc(dev, "RTAS Host-PCI bridge");
	return (BUS_PROBE_GENERIC);
}