示例#1
0
static void
ti_iic_attach(struct device *parent, struct device *self, void *args)
{
	struct ti_iic_softc *sc = (struct ti_iic_softc *)self;
	struct armv7_attach_args *aa = args;
	struct i2cbus_attach_args iba;
	uint16_t rev;
	const char *mode;
	u_int state;
	char buf[20];
	char *pin;
	/* BBB specific pin names */
	char *pins[6] = {"I2C0_SDA", "I2C0_SCL",
			"SPIO_D1", "SPI0_CS0",
			"UART1_CTSn", "UART1_RTSn"};

	sc->sc_iot = aa->aa_iot;
	rw_init(&sc->sc_buslock, "tiiilk");

	sc->sc_rxthres = sc->sc_txthres = 4;

	if (bus_space_map(sc->sc_iot, aa->aa_dev->mem[0].addr,
	    aa->aa_dev->mem[0].size, 0, &sc->sc_ioh))
		panic("%s: bus_space_map failed!");

	sc->sc_ih = arm_intr_establish(aa->aa_dev->irq[0], IPL_NET,
	    ti_iic_intr, sc, DEVNAME(sc));

	prcm_enablemodule(PRCM_I2C0 + aa->aa_dev->unit);

	if (board_id == BOARD_ID_AM335X_BEAGLEBONE) {
		pin = pins[aa->aa_dev->unit * 2];
		snprintf(buf, sizeof buf, "I2C%d_SDA", aa->aa_dev->unit);
		if (sitara_cm_padconf_set(pin, buf,
		    (0x01 << 4) | (0x01 << 5) | (0x01 << 6)) != 0) {
			printf(": can't switch %s pad\n", buf);
			return;
		}
		if (sitara_cm_padconf_get(pin, &mode, &state) == 0) {
			printf(": %s state %d ", mode, state);
		}

		pin = pins[aa->aa_dev->unit * 2 + 1];
		snprintf(buf, sizeof buf, "I2C%d_SCL", aa->aa_dev->unit);
		if (sitara_cm_padconf_set(pin, buf,
		    (0x01 << 4) | (0x01 << 5) | (0x01 << 6)) != 0) {
			printf(": can't switch %s pad\n", buf);
			return;
		}
		if (sitara_cm_padconf_get(pin, &mode, &state) == 0) {
			printf(": %s state %d ", mode, state);
		}
	}

	rev = I2C_READ_REG(sc, AM335X_I2C_REVNB_LO);
	printf(" rev %d.%d\n",
	    (int)I2C_REVNB_LO_MAJOR(rev),
	    (int)I2C_REVNB_LO_MINOR(rev));

	ti_iic_reset(sc);
	ti_iic_flush(sc);

	sc->sc_ic.ic_cookie = sc;
	sc->sc_ic.ic_acquire_bus = ti_iic_acquire_bus;
	sc->sc_ic.ic_release_bus = ti_iic_release_bus;
	sc->sc_ic.ic_exec = ti_iic_exec;

	bzero(&iba, sizeof iba);
	iba.iba_name = "iic";
	iba.iba_tag = &sc->sc_ic;
	(void) config_found(&sc->sc_dev, &iba, iicbus_print);
}
示例#2
0
void
omgpio_attach(struct device *parent, struct device *self, void *args)
{
	struct armv7_attach_args *aa = args;
	struct omgpio_softc *sc = (struct omgpio_softc *) self;
	struct gpiobus_attach_args gba;
	u_int32_t	rev;
	int		i;

	prcm_enablemodule(PRCM_GPIO0 + aa->aa_dev->unit);

	sc->sc_iot = aa->aa_iot;
	if (bus_space_map(sc->sc_iot, aa->aa_dev->mem[0].addr,
	    aa->aa_dev->mem[0].size, 0, &sc->sc_ioh))
		panic("%s: bus_space_map failed!", DEVNAME(sc));

	switch (board_id) {
	case BOARD_ID_OMAP3_BEAGLE:
	case BOARD_ID_OMAP3_OVERO:
		sc->sc_regs.revision = GPIO3_REVISION;
		sc->sc_regs.sysconfig = GPIO3_SYSCONFIG;
		sc->sc_regs.irqstatus_raw0 = -1;
		sc->sc_regs.irqstatus_raw1 = -1;
		sc->sc_regs.irqstatus0 = GPIO3_IRQSTATUS1;
		sc->sc_regs.irqstatus1 = GPIO3_IRQSTATUS2;
		sc->sc_regs.irqstatus_set0 = GPIO3_SETIRQENABLE1;
		sc->sc_regs.irqstatus_set1 = GPIO3_SETIRQENABLE2;
		sc->sc_regs.irqstatus_clear0 = GPIO3_CLEARIRQENABLE1;
		sc->sc_regs.irqstatus_clear1 = GPIO3_CLEARIRQENABLE2;
		sc->sc_regs.irqwaken0 = -1;
		sc->sc_regs.irqwaken1 = -1;
		sc->sc_regs.sysstatus = GPIO3_SYSSTATUS;
		sc->sc_regs.wakeupenable = GPIO3_WAKEUPENABLE;
		sc->sc_regs.ctrl = GPIO3_CTRL;
		sc->sc_regs.oe = GPIO3_OE;
		sc->sc_regs.datain = GPIO3_DATAIN;
		sc->sc_regs.dataout = GPIO3_DATAOUT;
		sc->sc_regs.leveldetect0 = GPIO3_LEVELDETECT0;
		sc->sc_regs.leveldetect1 = GPIO3_LEVELDETECT1;
		sc->sc_regs.risingdetect = GPIO3_RISINGDETECT;
		sc->sc_regs.fallingdetect = GPIO3_FALLINGDETECT;
		sc->sc_regs.debounceenable = GPIO3_DEBOUNCENABLE;
		sc->sc_regs.debouncingtime = GPIO3_DEBOUNCINGTIME;
		sc->sc_regs.clearwkupena = GPIO3_CLEARWKUENA;
		sc->sc_regs.setwkupena = GPIO3_SETWKUENA;
		sc->sc_regs.cleardataout = GPIO3_CLEARDATAOUT;
		sc->sc_regs.setdataout = GPIO3_SETDATAOUT;
		break;
	case BOARD_ID_OMAP4_PANDA:
		sc->sc_regs.revision = GPIO4_REVISION;
		sc->sc_regs.sysconfig = GPIO4_SYSCONFIG;
		sc->sc_regs.irqstatus_raw0 = GPIO4_IRQSTATUS_RAW_0;
		sc->sc_regs.irqstatus_raw1 = GPIO4_IRQSTATUS_RAW_1;
		sc->sc_regs.irqstatus0 = GPIO4_IRQSTATUS_0;
		sc->sc_regs.irqstatus1 = GPIO4_IRQSTATUS_1;
		sc->sc_regs.irqstatus_set0 = GPIO4_IRQSTATUS_SET_0;
		sc->sc_regs.irqstatus_set1 = GPIO4_IRQSTATUS_SET_1;
		sc->sc_regs.irqstatus_clear0 = GPIO4_IRQSTATUS_CLR_0;
		sc->sc_regs.irqstatus_clear1 = GPIO4_IRQSTATUS_CLR_1;
		sc->sc_regs.irqwaken0 = GPIO4_IRQWAKEN_0;
		sc->sc_regs.irqwaken1 = GPIO4_IRQWAKEN_1;
		sc->sc_regs.sysstatus = GPIO4_SYSSTATUS;
		sc->sc_regs.wakeupenable = GPIO4_WAKEUPENABLE;
		sc->sc_regs.ctrl = GPIO4_CTRL;
		sc->sc_regs.oe = GPIO4_OE;
		sc->sc_regs.datain = GPIO4_DATAIN;
		sc->sc_regs.dataout = GPIO4_DATAOUT;
		sc->sc_regs.leveldetect0 = GPIO4_LEVELDETECT0;
		sc->sc_regs.leveldetect1 = GPIO4_LEVELDETECT1;
		sc->sc_regs.risingdetect = GPIO4_RISINGDETECT;
		sc->sc_regs.fallingdetect = GPIO4_FALLINGDETECT;
		sc->sc_regs.debounceenable = GPIO4_DEBOUNCENABLE;
		sc->sc_regs.debouncingtime = GPIO4_DEBOUNCINGTIME;
		sc->sc_regs.clearwkupena = GPIO4_CLEARWKUPENA;
		sc->sc_regs.setwkupena = GPIO4_SETWKUENA;
		sc->sc_regs.cleardataout = GPIO4_CLEARDATAOUT;
		sc->sc_regs.setdataout = GPIO4_SETDATAOUT;
		break;
	case BOARD_ID_AM335X_BEAGLEBONE:
		sc->sc_regs.revision = GPIO_AM335X_REVISION;
		sc->sc_regs.sysconfig = GPIO_AM335X_SYSCONFIG;
		sc->sc_regs.irqstatus_raw0 = GPIO_AM335X_IRQSTATUS_RAW_0;
		sc->sc_regs.irqstatus_raw1 = GPIO_AM335X_IRQSTATUS_RAW_1;
		sc->sc_regs.irqstatus0 = GPIO_AM335X_IRQSTATUS_0;
		sc->sc_regs.irqstatus1 = GPIO_AM335X_IRQSTATUS_1;
		sc->sc_regs.irqstatus_set0 = GPIO_AM335X_IRQSTATUS_SET_0;
		sc->sc_regs.irqstatus_set1 = GPIO_AM335X_IRQSTATUS_SET_1;
		sc->sc_regs.irqstatus_clear0 = GPIO_AM335X_IRQSTATUS_CLR_0;
		sc->sc_regs.irqstatus_clear1 = GPIO_AM335X_IRQSTATUS_CLR_1;
		sc->sc_regs.irqwaken0 = GPIO_AM335X_IRQWAKEN_0;
		sc->sc_regs.irqwaken1 = GPIO_AM335X_IRQWAKEN_1;
		sc->sc_regs.sysstatus = GPIO_AM335X_SYSSTATUS;
		sc->sc_regs.wakeupenable = -1;
		sc->sc_regs.ctrl = GPIO_AM335X_CTRL;
		sc->sc_regs.oe = GPIO_AM335X_OE;
		sc->sc_regs.datain = GPIO_AM335X_DATAIN;
		sc->sc_regs.dataout = GPIO_AM335X_DATAOUT;
		sc->sc_regs.leveldetect0 = GPIO_AM335X_LEVELDETECT0;
		sc->sc_regs.leveldetect1 = GPIO_AM335X_LEVELDETECT1;
		sc->sc_regs.risingdetect = GPIO_AM335X_RISINGDETECT;
		sc->sc_regs.fallingdetect = GPIO_AM335X_FALLINGDETECT;
		sc->sc_regs.debounceenable = GPIO_AM335X_DEBOUNCENABLE;
		sc->sc_regs.debouncingtime = GPIO_AM335X_DEBOUNCINGTIME;
		sc->sc_regs.clearwkupena = -1;
		sc->sc_regs.setwkupena = -1;
		sc->sc_regs.cleardataout = GPIO_AM335X_CLEARDATAOUT;
		sc->sc_regs.setdataout = GPIO_AM335X_SETDATAOUT;
		break;
	}

	rev = READ4(sc, sc->sc_regs.revision);

	printf(": rev %d.%d\n", rev >> 4 & 0xf, rev & 0xf);

	sc->sc_irq = aa->aa_dev->irq[0];

	WRITE4(sc, sc->sc_regs.irqstatus_clear0, ~0);
	WRITE4(sc, sc->sc_regs.irqstatus_clear1, ~0);

	/* XXX - SYSCONFIG */
	/* XXX - CTRL */
	/* XXX - DEBOUNCE */

	for (i = 0; i < GPIO_NUM_PINS; i++) {
		sc->sc_gpio_pins[i].pin_num = i;
		sc->sc_gpio_pins[i].pin_caps = GPIO_PIN_INPUT |
		    GPIO_PIN_OUTPUT | GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN;
		sc->sc_gpio_pins[i].pin_state = omgpio_pin_read(sc, i) ?
		    GPIO_PIN_HIGH : GPIO_PIN_LOW;
		sc->sc_gpio_pins[i].pin_flags = GPIO_PIN_SET;
	}

	sc->sc_gpio_gc.gp_cookie = sc;
	sc->sc_gpio_gc.gp_pin_read = omgpio_pin_read;
	sc->sc_gpio_gc.gp_pin_write = omgpio_pin_write;
	sc->sc_gpio_gc.gp_pin_ctl = omgpio_pin_ctl;

	gba.gba_name = "gpio";
	gba.gba_gc = &sc->sc_gpio_gc;
	gba.gba_pins = sc->sc_gpio_pins;
	gba.gba_npins = GPIO_NUM_PINS;

#if NGPIO > 0
	config_found(&sc->sc_dev, &gba, gpiobus_print);
#endif
}
示例#3
0
int
omehci_init(struct omehci_softc *sc)
{
	uint32_t i = 0, reg;
	uint32_t reset_performed = 0;
	uint32_t timeout = 0;
	uint32_t tll_ch_mask = 0;

	/* enable high speed usb host clock */
	prcm_enablemodule(PRCM_USB);

	/* Hold the PHY in reset while configuring */
	for (i = 0; i < OMAP_HS_USB_PORTS; i++) {
		if (sc->phy_reset[i]) {
			/* Configure the GPIO to drive low (hold in reset) */
			if (sc->reset_gpio_pin[i] != -1) {
				omgpio_set_dir(sc->reset_gpio_pin[i],
				    OMGPIO_DIR_OUT);
				omgpio_clear_bit(sc->reset_gpio_pin[i]);
				reset_performed = 1;
			}
		}
	}

	/* Hold the PHY in RESET for enough time till DIR is high */
	if (reset_performed)
		delay(10);

	/* Read the UHH revision */
	sc->ehci_rev = bus_space_read_4(sc->sc.iot, sc->uhh_ioh,
	    OMAP_USBHOST_UHH_REVISION);

	/* Initilise the low level interface module(s) */
	if (sc->ehci_rev == OMAP_EHCI_REV1) {
		/* Enable the USB TLL */
		prcm_enablemodule(PRCM_USBTLL);

		/* Perform TLL soft reset, and wait until reset is complete */
		bus_space_write_4(sc->sc.iot, sc->tll_ioh,
		    OMAP_USBTLL_SYSCONFIG, TLL_SYSCONFIG_SOFTRESET);

		/* Set the timeout to 100ms*/
		timeout = (hz < 10) ? 1 : ((100 * hz) / 1000);

		/* Wait for TLL reset to complete */
		while ((bus_space_read_4(sc->sc.iot, sc->tll_ioh,
		    OMAP_USBTLL_SYSSTATUS) & TLL_SYSSTATUS_RESETDONE)
		    == 0x00) {

			/* Sleep for a tick */
			delay(10);

			if (timeout-- == 0) {
				return 1;
			}
		}

		bus_space_write_4(sc->sc.iot, sc->tll_ioh,
		    OMAP_USBTLL_SYSCONFIG,
		    TLL_SYSCONFIG_ENAWAKEUP | TLL_SYSCONFIG_AUTOIDLE |
		    TLL_SYSCONFIG_SIDLE_SMART_IDLE | TLL_SYSCONFIG_CACTIVITY);
	} else if (sc->ehci_rev == OMAP_EHCI_REV2) {
		/* For OMAP44xx devices you have to enable the per-port clocks:
		 *  PHY_MODE  - External ULPI clock
		 *  TTL_MODE  - Internal UTMI clock
		 *  HSIC_MODE - Internal 480Mhz and 60Mhz clocks
		 */
		if (sc->port_mode[0] == EHCI_HCD_OMAP_MODE_PHY) {
			//ti_prcm_clk_set_source(USBP1_PHY_CLK, EXT_CLK);
			prcm_enablemodule(PRCM_USBP1_PHY);
		} else if (sc->port_mode[0] == EHCI_HCD_OMAP_MODE_TLL)
			prcm_enablemodule(PRCM_USBP1_UTMI);
		else if (sc->port_mode[0] == EHCI_HCD_OMAP_MODE_HSIC)
			prcm_enablemodule(PRCM_USBP1_HSIC);

		if (sc->port_mode[1] == EHCI_HCD_OMAP_MODE_PHY) {
			//ti_prcm_clk_set_source(USBP2_PHY_CLK, EXT_CLK);
			prcm_enablemodule(PRCM_USBP2_PHY);
		} else if (sc->port_mode[1] == EHCI_HCD_OMAP_MODE_TLL)
			prcm_enablemodule(PRCM_USBP2_UTMI);
		else if (sc->port_mode[1] == EHCI_HCD_OMAP_MODE_HSIC)
			prcm_enablemodule(PRCM_USBP2_HSIC);
	}

	/* Put UHH in SmartIdle/SmartStandby mode */
	reg = bus_space_read_4(sc->sc.iot, sc->uhh_ioh,
	    OMAP_USBHOST_UHH_SYSCONFIG);
	if (sc->ehci_rev == OMAP_EHCI_REV1) {
		reg &= ~(UHH_SYSCONFIG_SIDLEMODE_MASK |
		         UHH_SYSCONFIG_MIDLEMODE_MASK);
		reg |= (UHH_SYSCONFIG_ENAWAKEUP |
		        UHH_SYSCONFIG_AUTOIDLE |
		        UHH_SYSCONFIG_CLOCKACTIVITY |
		        UHH_SYSCONFIG_SIDLEMODE_SMARTIDLE |
		        UHH_SYSCONFIG_MIDLEMODE_SMARTSTANDBY);
	} else if (sc->ehci_rev == OMAP_EHCI_REV2) {
		reg &= ~UHH_SYSCONFIG_IDLEMODE_MASK;
		reg |=  UHH_SYSCONFIG_IDLEMODE_NOIDLE;
		reg &= ~UHH_SYSCONFIG_STANDBYMODE_MASK;
		reg |=  UHH_SYSCONFIG_STANDBYMODE_NOSTDBY;
	}
	bus_space_write_4(sc->sc.iot, sc->uhh_ioh, OMAP_USBHOST_UHH_SYSCONFIG,
	    reg);

	reg = bus_space_read_4(sc->sc.iot, sc->uhh_ioh,
	    OMAP_USBHOST_UHH_HOSTCONFIG);

	/* Setup ULPI bypass and burst configurations */
	reg |= (UHH_HOSTCONFIG_ENA_INCR4 |
		UHH_HOSTCONFIG_ENA_INCR8 |
		UHH_HOSTCONFIG_ENA_INCR16);
	reg &= ~UHH_HOSTCONFIG_ENA_INCR_ALIGN;

	if (sc->ehci_rev == OMAP_EHCI_REV1) {
		if (sc->port_mode[0] == EHCI_HCD_OMAP_MODE_UNKNOWN)
			reg &= ~UHH_HOSTCONFIG_P1_CONNECT_STATUS;
		if (sc->port_mode[1] == EHCI_HCD_OMAP_MODE_UNKNOWN)
			reg &= ~UHH_HOSTCONFIG_P2_CONNECT_STATUS;
		if (sc->port_mode[2] == EHCI_HCD_OMAP_MODE_UNKNOWN)
			reg &= ~UHH_HOSTCONFIG_P3_CONNECT_STATUS;

		/* Bypass the TLL module for PHY mode operation */
		if ((sc->port_mode[0] == EHCI_HCD_OMAP_MODE_PHY) ||
		    (sc->port_mode[1] == EHCI_HCD_OMAP_MODE_PHY) ||
		    (sc->port_mode[2] == EHCI_HCD_OMAP_MODE_PHY))
			reg &= ~UHH_HOSTCONFIG_P1_ULPI_BYPASS;
		else
			reg |= UHH_HOSTCONFIG_P1_ULPI_BYPASS;
	} else if (sc->ehci_rev == OMAP_EHCI_REV2) {
		reg |=  UHH_HOSTCONFIG_APP_START_CLK;
		
		/* Clear port mode fields for PHY mode*/
		reg &= ~UHH_HOSTCONFIG_P1_MODE_MASK;
		reg &= ~UHH_HOSTCONFIG_P2_MODE_MASK;

		if (sc->port_mode[0] == EHCI_HCD_OMAP_MODE_TLL)
			reg |= UHH_HOSTCONFIG_P1_MODE_UTMI_PHY;
		else if (sc->port_mode[0] == EHCI_HCD_OMAP_MODE_HSIC)
			reg |= UHH_HOSTCONFIG_P1_MODE_HSIC;

		if (sc->port_mode[1] == EHCI_HCD_OMAP_MODE_TLL)
			reg |= UHH_HOSTCONFIG_P2_MODE_UTMI_PHY;
		else if (sc->port_mode[1] == EHCI_HCD_OMAP_MODE_HSIC)
			reg |= UHH_HOSTCONFIG_P2_MODE_HSIC;
	}

	bus_space_write_4(sc->sc.iot, sc->uhh_ioh, OMAP_USBHOST_UHH_HOSTCONFIG, reg);

	/* If any of the ports are configured in TLL mode, enable them */
	for (i = 0; i < OMAP_HS_USB_PORTS; i++)
		if (sc->port_mode[i] == EHCI_HCD_OMAP_MODE_PHY)
			tll_ch_mask |= 1 << i;

	/* Enable UTMI mode for required TLL channels */
#ifdef notyet
	if (tll_ch_mask)
		omap_ehci_utmi_init(sc, tll_ch_mask);
#endif

	/* Release the PHY reset signal now we have configured everything */
	if (reset_performed) {
		/* Delay for 10ms */
		delay(10000);

		/* Release reset */
		for (i = 0; i < 3; i++) {
			if (sc->phy_reset[i] && (sc->reset_gpio_pin[i] != -1))
				omgpio_set_bit(sc->reset_gpio_pin[i]);
		}
	}

	/* Set the interrupt threshold control, it controls the maximum rate at
	 * which the host controller issues interrupts.  We set it to 1 microframe
	 * at startup - the default is 8 mircoframes (equates to 1ms).
	 */
	reg = bus_space_read_4(sc->sc.iot, sc->sc.ioh, OMAP_USBHOST_USBCMD);
	reg &= 0xff00ffff;
	reg |= (1 << 16);
	bus_space_write_4(sc->sc.iot, sc->sc.ioh, OMAP_USBHOST_USBCMD, reg);

	/* Soft reset the PHY using PHY reset command over ULPI */
	for (i = 0; i < OMAP_HS_USB_PORTS; i++)
		if (sc->port_mode[i] == EHCI_HCD_OMAP_MODE_PHY)
			omehci_soft_phy_reset(sc, i);

	return(0);
}