diff options
Diffstat (limited to 'sys/arm64/rockchip')
| -rw-r--r-- | sys/arm64/rockchip/rk_gpio.c | 204 | ||||
| -rw-r--r-- | sys/arm64/rockchip/rk_grf_gpio.c | 3 | ||||
| -rw-r--r-- | sys/arm64/rockchip/rk_tsadc.c | 2 | 
3 files changed, 143 insertions, 66 deletions
| diff --git a/sys/arm64/rockchip/rk_gpio.c b/sys/arm64/rockchip/rk_gpio.c index 847bc7394dd0..8da37d516802 100644 --- a/sys/arm64/rockchip/rk_gpio.c +++ b/sys/arm64/rockchip/rk_gpio.c @@ -90,6 +90,11 @@ struct rk_pin_irqsrc {  	uint32_t		mode;  }; +struct rk_gpio_reg { +        uint8_t single; +        uint8_t offset; +}; +  struct rk_gpio_softc {  	device_t		sc_dev;  	device_t		sc_busdev; @@ -103,7 +108,7 @@ struct rk_gpio_softc {  	uint32_t		swporta_ddr;  	uint32_t		version;  	struct pin_cached	pin_cached[RK_GPIO_MAX_PINS]; -	uint8_t			regs[RK_GPIO_REGNUM]; +	struct rk_gpio_reg	regs[RK_GPIO_REGNUM];  	void			*ihandle;  	struct rk_pin_irqsrc	isrcs[RK_GPIO_MAX_PINS];  }; @@ -138,14 +143,15 @@ static int rk_gpio_detach(device_t dev);  static int  rk_gpio_read_bit(struct rk_gpio_softc *sc, int reg, int bit)  { -	int offset = sc->regs[reg]; +	struct rk_gpio_reg *rk_reg = &sc->regs[reg];  	uint32_t value; -	if (sc->version == RK_GPIO_TYPE_V1) { -		value = RK_GPIO_READ(sc, offset); +	if (rk_reg->single) { +		value = RK_GPIO_READ(sc, rk_reg->offset);  		value >>= bit;  	} else { -		value = RK_GPIO_READ(sc, bit > 15 ? offset + 4 : offset); +		value = RK_GPIO_READ(sc, bit > 15 ? +		    rk_reg->offset + 4 : rk_reg->offset);  		value >>= (bit % 16);  	}  	return (value & 1); @@ -154,50 +160,53 @@ rk_gpio_read_bit(struct rk_gpio_softc *sc, int reg, int bit)  static void  rk_gpio_write_bit(struct rk_gpio_softc *sc, int reg, int bit, int data)  { -	int offset = sc->regs[reg]; +	struct rk_gpio_reg *rk_reg = &sc->regs[reg];  	uint32_t value; -	if (sc->version == RK_GPIO_TYPE_V1) { -		value = RK_GPIO_READ(sc, offset); +	if (rk_reg->single) { +		value = RK_GPIO_READ(sc, rk_reg->offset);  		if (data)  			value |= (1 << bit);  		else  			value &= ~(1 << bit); -		RK_GPIO_WRITE(sc, offset, value); +		RK_GPIO_WRITE(sc, rk_reg->offset, value);  	} else {  		if (data)  			value = (1 << (bit % 16));  		else  			value = 0;  		value |= (1 << ((bit % 16) + 16)); -		RK_GPIO_WRITE(sc, bit > 15 ? offset + 4 : offset, value); +		RK_GPIO_WRITE(sc, bit > 15 ? +		    rk_reg->offset + 4 : rk_reg->offset, value);  	}  }  static uint32_t  rk_gpio_read_4(struct rk_gpio_softc *sc, int reg)  { -	int offset = sc->regs[reg]; +	struct rk_gpio_reg *rk_reg = &sc->regs[reg];  	uint32_t value; -	if (sc->version == RK_GPIO_TYPE_V1) -		value = RK_GPIO_READ(sc, offset); +	if (rk_reg->single) +		value = RK_GPIO_READ(sc, rk_reg->offset);  	else -		value = (RK_GPIO_READ(sc, offset) & 0xffff) | -		    (RK_GPIO_READ(sc, offset + 4) << 16); +		value = (RK_GPIO_READ(sc, rk_reg->offset) & 0xffff) | +		    (RK_GPIO_READ(sc, rk_reg->offset + 4) << 16);  	return (value);  }  static void  rk_gpio_write_4(struct rk_gpio_softc *sc, int reg, uint32_t value)  { -	int offset = sc->regs[reg]; +	struct rk_gpio_reg *rk_reg = &sc->regs[reg]; -	if (sc->version == RK_GPIO_TYPE_V1) -		RK_GPIO_WRITE(sc, offset, value); +	if (rk_reg->single) +		RK_GPIO_WRITE(sc, rk_reg->offset, value);  	else { -		RK_GPIO_WRITE(sc, offset, (value & 0xffff) | 0xffff0000); -		RK_GPIO_WRITE(sc, offset + 4, (value >> 16) | 0xffff0000); +		RK_GPIO_WRITE(sc, rk_reg->offset, +		    (value & 0xffff) | 0xffff0000); +		RK_GPIO_WRITE(sc, rk_reg->offset + 4, +		    (value >> 16) | 0xffff0000);  	}  } @@ -313,31 +322,31 @@ rk_gpio_attach(device_t dev)  	switch (sc->version) {  	case RK_GPIO_TYPE_V1: -		sc->regs[RK_GPIO_SWPORTA_DR] = 0x00; -		sc->regs[RK_GPIO_SWPORTA_DDR] = 0x04; -		sc->regs[RK_GPIO_INTEN] = 0x30; -		sc->regs[RK_GPIO_INTMASK] = 0x34; -		sc->regs[RK_GPIO_INTTYPE_LEVEL] = 0x38; -		sc->regs[RK_GPIO_INT_POLARITY] = 0x3c; -		sc->regs[RK_GPIO_INT_STATUS] = 0x40; -		sc->regs[RK_GPIO_INT_RAWSTATUS] = 0x44; -		sc->regs[RK_GPIO_DEBOUNCE] = 0x48; -		sc->regs[RK_GPIO_PORTA_EOI] = 0x4c; -		sc->regs[RK_GPIO_EXT_PORTA] = 0x50; +		sc->regs[RK_GPIO_SWPORTA_DR] = (struct rk_gpio_reg){ 1, 0x00 }; +		sc->regs[RK_GPIO_SWPORTA_DDR] = (struct rk_gpio_reg){ 1, 0x04 }; +		sc->regs[RK_GPIO_INTEN] = (struct rk_gpio_reg){ 1, 0x30 }; +		sc->regs[RK_GPIO_INTMASK] = (struct rk_gpio_reg){ 1, 0x34 }; +		sc->regs[RK_GPIO_INTTYPE_LEVEL] = (struct rk_gpio_reg){ 1, 0x38 }; +		sc->regs[RK_GPIO_INT_POLARITY] = (struct rk_gpio_reg){ 1, 0x3c }; +		sc->regs[RK_GPIO_INT_STATUS] = (struct rk_gpio_reg){ 1, 0x40 }; +		sc->regs[RK_GPIO_INT_RAWSTATUS] = (struct rk_gpio_reg){ 1, 0x44 }; +		sc->regs[RK_GPIO_DEBOUNCE] = (struct rk_gpio_reg){ 1, 0x48 }; +		sc->regs[RK_GPIO_PORTA_EOI] = (struct rk_gpio_reg){ 1, 0x4c }; +		sc->regs[RK_GPIO_EXT_PORTA] = (struct rk_gpio_reg){ 1, 0x50 };  		break;  	case RK_GPIO_TYPE_V2: -		sc->regs[RK_GPIO_SWPORTA_DR] = 0x00; -		sc->regs[RK_GPIO_SWPORTA_DDR] = 0x08; -		sc->regs[RK_GPIO_INTEN] = 0x10; -		sc->regs[RK_GPIO_INTMASK] = 0x18; -		sc->regs[RK_GPIO_INTTYPE_LEVEL] = 0x20; -		sc->regs[RK_GPIO_INTTYPE_BOTH] = 0x30; -		sc->regs[RK_GPIO_INT_POLARITY] = 0x28; -		sc->regs[RK_GPIO_INT_STATUS] = 0x50; -		sc->regs[RK_GPIO_INT_RAWSTATUS] = 0x58; -		sc->regs[RK_GPIO_DEBOUNCE] = 0x38; -		sc->regs[RK_GPIO_PORTA_EOI] = 0x60; -		sc->regs[RK_GPIO_EXT_PORTA] = 0x70; +		sc->regs[RK_GPIO_SWPORTA_DR] = (struct rk_gpio_reg){ 0, 0x00 }; +		sc->regs[RK_GPIO_SWPORTA_DDR] = (struct rk_gpio_reg){ 0, 0x08 }; +		sc->regs[RK_GPIO_INTEN] = (struct rk_gpio_reg){ 0, 0x10 }; +		sc->regs[RK_GPIO_INTMASK] = (struct rk_gpio_reg){ 0, 0x18 }; +		sc->regs[RK_GPIO_INTTYPE_LEVEL] = (struct rk_gpio_reg){ 0, 0x20 }; +		sc->regs[RK_GPIO_INTTYPE_BOTH] = (struct rk_gpio_reg){ 0, 0x30 }; +		sc->regs[RK_GPIO_INT_POLARITY] = (struct rk_gpio_reg){ 0, 0x28 }; +		sc->regs[RK_GPIO_INT_STATUS] = (struct rk_gpio_reg){ 1, 0x50 }; +		sc->regs[RK_GPIO_INT_RAWSTATUS] = (struct rk_gpio_reg){ 1, 0x58 }; +		sc->regs[RK_GPIO_DEBOUNCE] = (struct rk_gpio_reg){ 0, 0x38 }; +		sc->regs[RK_GPIO_PORTA_EOI] = (struct rk_gpio_reg){ 0, 0x60 }; +		sc->regs[RK_GPIO_EXT_PORTA] = (struct rk_gpio_reg){ 1, 0x70 };  		break;  	default:  		device_printf(dev, "Unknown gpio version %08x\n", sc->version); @@ -371,12 +380,13 @@ rk_gpio_attach(device_t dev)  	sc->swporta_ddr = rk_gpio_read_4(sc, RK_GPIO_SWPORTA_DDR);  	RK_GPIO_UNLOCK(sc); -	sc->sc_busdev = gpiobus_attach_bus(dev); +	sc->sc_busdev = gpiobus_add_bus(dev);  	if (sc->sc_busdev == NULL) {  		rk_gpio_detach(dev);  		return (ENXIO);  	} +	bus_attach_children(dev);  	return (0);  } @@ -393,7 +403,7 @@ rk_gpio_detach(device_t dev)  	mtx_destroy(&sc->sc_mtx);  	clk_disable(sc->clk); -	return(0); +	return (0);  }  static device_t @@ -470,7 +480,7 @@ rk_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)  {  	if (pin >= RK_GPIO_MAX_PINS) -		return EINVAL; +		return (EINVAL);  	*caps = RK_GPIO_DEFAULT_CAPS;  	return (0); @@ -653,46 +663,108 @@ rk_gpio_get_node(device_t bus, device_t dev)  }  static int -rk_pic_map_intr(device_t dev, struct intr_map_data *data, -    struct intr_irqsrc **isrcp) +rk_gpio_pic_map_fdt(struct rk_gpio_softc *sc, +    struct intr_map_data_fdt *daf, +    u_int *irqp, uint32_t *modep)  { -	struct rk_gpio_softc *sc = device_get_softc(dev); -	struct intr_map_data_gpio *gdata;  	uint32_t irq; +	uint32_t mode; -	if (data->type != INTR_MAP_DATA_GPIO) { -		device_printf(dev, "Wrong type\n"); -		return (ENOTSUP); -	} -	gdata = (struct intr_map_data_gpio *)data; -	irq = gdata->gpio_pin_num; +	if (daf->ncells != 2) +		return (EINVAL); + +	irq = daf->cells[0]; +	if (irq >= RK_GPIO_MAX_PINS) +		return (EINVAL); + +	/* Only reasonable modes are supported. */ +	if (daf->cells[1] == 1) +		mode = GPIO_INTR_EDGE_RISING; +	else if (daf->cells[1] == 2) +		mode = GPIO_INTR_EDGE_FALLING; +	else if (daf->cells[1] == 3) +		mode = GPIO_INTR_EDGE_BOTH; +	else if (daf->cells[1] == 4) +		mode = GPIO_INTR_LEVEL_HIGH; +	else if (daf->cells[1] == 8) +		mode = GPIO_INTR_LEVEL_LOW; +	else +		return (EINVAL); + +	*irqp = irq; +	if (modep != NULL) +		*modep = mode; +	return (0); +} + +static int +rk_gpio_pic_map_gpio(struct rk_gpio_softc *sc, +    struct intr_map_data_gpio *dag, +    u_int *irqp, uint32_t *modep) +{ +	uint32_t irq; +	irq = dag->gpio_pin_num;  	if (irq >= RK_GPIO_MAX_PINS) { -		device_printf(dev, "Invalid interrupt %u\n", irq); +		device_printf(sc->sc_dev, "Invalid interrupt %u\n", +		    irq);  		return (EINVAL);  	} -	*isrcp = RK_GPIO_ISRC(sc, irq); + +	*irqp = irq; +	if (modep != NULL) +		*modep = dag->gpio_intr_mode;  	return (0);  }  static int +rk_gpio_pic_map(struct rk_gpio_softc *sc, struct intr_map_data *data, +    u_int *irqp, uint32_t *modep) +{ +	switch (data->type) { +	case INTR_MAP_DATA_FDT: +		return (rk_gpio_pic_map_fdt(sc, +		    (struct intr_map_data_fdt *)data, irqp, modep)); +	case INTR_MAP_DATA_GPIO: +		return (rk_gpio_pic_map_gpio(sc, +		    (struct intr_map_data_gpio *)data, irqp, modep)); +	default: +		device_printf(sc->sc_dev, "Wrong type\n"); +		return (ENOTSUP); +	} +} + +static int +rk_pic_map_intr(device_t dev, struct intr_map_data *data, +    struct intr_irqsrc **isrcp) +{ +	int error; +	struct rk_gpio_softc *sc = device_get_softc(dev); +	uint32_t irq; + +	error = rk_gpio_pic_map(sc, data, &irq, NULL); +	if (error == 0) +		*isrcp = RK_GPIO_ISRC(sc, irq); +	return (error); +} + +static int  rk_pic_setup_intr(device_t dev, struct intr_irqsrc *isrc,      struct resource *res, struct intr_map_data *data)  {  	struct rk_gpio_softc *sc = device_get_softc(dev);  	struct rk_pin_irqsrc *rkisrc = (struct rk_pin_irqsrc *)isrc; -	struct intr_map_data_gpio *gdata;  	uint32_t mode; -	uint8_t pin; +	uint32_t pin;  	if (!data) {  		device_printf(dev, "No map data\n");  		return (ENOTSUP);  	} -	gdata = (struct intr_map_data_gpio *)data; -	mode = gdata->gpio_intr_mode; -	pin = gdata->gpio_pin_num; -	if (rkisrc->irq != gdata->gpio_pin_num) { +	if (rk_gpio_pic_map(sc, data, &pin, &mode) != 0) +		return (EINVAL); + +	if (rkisrc->irq != pin) {  		device_printf(dev, "Interrupts don't match\n");  		return (EINVAL);  	} @@ -779,6 +851,10 @@ static device_method_t rk_gpio_methods[] = {  	DEVMETHOD(device_attach,	rk_gpio_attach),  	DEVMETHOD(device_detach,	rk_gpio_detach), +	/* Bus interface */ +	DEVMETHOD(bus_setup_intr,	bus_generic_setup_intr), +	DEVMETHOD(bus_teardown_intr,	bus_generic_teardown_intr), +  	/* GPIO protocol */  	DEVMETHOD(gpio_get_bus,		rk_gpio_get_bus),  	DEVMETHOD(gpio_pin_max,		rk_gpio_pin_max), diff --git a/sys/arm64/rockchip/rk_grf_gpio.c b/sys/arm64/rockchip/rk_grf_gpio.c index 6818bd85bb95..6ac419889614 100644 --- a/sys/arm64/rockchip/rk_grf_gpio.c +++ b/sys/arm64/rockchip/rk_grf_gpio.c @@ -181,11 +181,12 @@ rk_grf_gpio_attach(device_t dev)  		return (ENXIO);  	} -	sc->sc_busdev = gpiobus_attach_bus(dev); +	sc->sc_busdev = gpiobus_add_bus(dev);  	if (sc->sc_busdev == NULL) {  		return (ENXIO);  	} +	bus_attach_children(dev);  	return (0);  } diff --git a/sys/arm64/rockchip/rk_tsadc.c b/sys/arm64/rockchip/rk_tsadc.c index e6cbad36f697..d83b09480a0c 100644 --- a/sys/arm64/rockchip/rk_tsadc.c +++ b/sys/arm64/rockchip/rk_tsadc.c @@ -484,7 +484,7 @@ tsadc_init_tsensor(struct tsadc_softc *sc, struct tsensor *sensor)  	WR4(sc, TSADC_INT_EN, val);  	/* Shutdown temperature */ -	val =  tsadc_raw_to_temp(sc, sc->shutdown_temp); +	val =  tsadc_temp_to_raw(sc, sc->shutdown_temp);  	WR4(sc, TSADC_COMP_SHUT(sensor->channel), val);  	val = RD4(sc, TSADC_AUTO_CON);  	val |= TSADC_AUTO_SRC_EN(sensor->channel); | 
