Date: Mon, 31 Dec 2018 08:09:53 +0900 (JST) From: SAITOU Toshihide <toshi@ruby.ocn.ne.jp> To: freebsd-arm@freebsd.org Subject: Re: SPI start bit (9 bit) for BBB Message-ID: <20181231.080953.1864031625387192599.toshi@ruby.ocn.ne.jp> In-Reply-To: <1546191759.78877.91.camel@freebsd.org> References: <20181231.003356.1147810385398844555.toshi@ruby.ocn.ne.jp> <1546191759.78877.91.camel@freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On Sun, 30 Dec 2018 10:42:39 -0700, Ian Lepore <ian@freebsd.org> wrote:= > On Mon, 2018-12-31 at 00:33 +0900, SAITOU Toshihide wrote: >> In 3-line serial protcol, there is a type using additional 1-bit to >> specify command or data.=A0=A0The BBB can handle this, so I can use = with >> the following patch (unskillful and maybe side effects exist).=A0=A0= I >> hope this will attract someones interest to implement this and also >> SPI frequency and mode. >> = >> = >> --- arm/ti/ti_spi.c.orig 2018-12-22 00:47:12.096034000 +0900 >> +++ arm/ti/ti_spi.c 2018-12-30 23:58:00.000000000 +0900 >> @@ -493,6 +493,7 @@ ti_spi_transfer(device_t dev, device_t child, >> struct s >> =A0 /* Disable the FIFO. */ >> =A0 TI_SPI_WRITE(sc, MCSPI_XFERLEVEL, 0); >> =A0 >> +#if 0 >> =A0 /* 8 bits word, d0 miso, d1 mosi, mode 0 and CS active low. >> */ >> =A0 reg =3D TI_SPI_READ(sc, MCSPI_CONF_CH(sc->sc_cs)); >> =A0 reg &=3D ~(MCSPI_CONF_FFER | MCSPI_CONF_FFEW | >> MCSPI_CONF_SBPOL | >> @@ -501,6 +502,7 @@ ti_spi_transfer(device_t dev, device_t child, >> struct s >> =A0 =A0=A0=A0=A0MCSPI_CONF_DMAW | MCSPI_CONF_EPOL); >> =A0 reg |=3D MCSPI_CONF_DPE0 | MCSPI_CONF_EPOL | >> MCSPI_CONF_WL8BITS; >> =A0 TI_SPI_WRITE(sc, MCSPI_CONF_CH(sc->sc_cs), reg); >> +#endif >> =A0 >> =A0#if 0 >> =A0 /* Enable channel interrupts. */ >> @@ -558,6 +560,70 @@ ti_spi_get_node(device_t bus, device_t dev) >> =A0 return (ofw_bus_get_node(bus)); >> =A0} >> =A0 >> +static int >> +ti_spi_sbe(device_t dev, device_t child, uint32_t *request) >> +{ >> + struct ti_spi_softc *sc; >> + uint32_t reg; >> + >> + sc =3D device_get_softc(dev); >> + >> + TI_SPI_LOCK(sc); >> + >> + /* If the controller is in use wait until it is available. >> */ >> + while (sc->sc_flags & TI_SPI_BUSY) >> + mtx_sleep(dev, &sc->sc_mtx, 0, "ti_spi", 0); >> + >> + /* Now we have control over SPI controller. */ >> + sc->sc_flags =3D TI_SPI_BUSY; >> + >> + reg =3D TI_SPI_READ(sc, MCSPI_CONF_CH(sc->sc_cs)); >> + if (*request) >> + reg |=3D MCSPI_CONF_SBE; >> + else >> + reg &=3D ~MCSPI_CONF_SBE; >> + TI_SPI_WRITE(sc, MCSPI_CONF_CH(sc->sc_cs), reg); >> + >> + /* Release the controller and wakeup the next thread waiting >> for it. */ >> + sc->sc_flags =3D 0; >> + wakeup_one(dev); >> + TI_SPI_UNLOCK(sc); >> + >> + return (0); >> +} >> + >> +static int >> +ti_spi_sbpol(device_t dev, device_t child, uint32_t *request) >> +{ >> + struct ti_spi_softc *sc; >> + uint32_t reg; >> + >> + sc =3D device_get_softc(dev); >> + >> + TI_SPI_LOCK(sc); >> + >> + /* If the controller is in use wait until it is available. >> */ >> + while (sc->sc_flags & TI_SPI_BUSY) >> + mtx_sleep(dev, &sc->sc_mtx, 0, "ti_spi", 0); >> + >> + /* Now we have control over SPI controller. */ >> + sc->sc_flags =3D TI_SPI_BUSY; >> + >> + reg =3D TI_SPI_READ(sc, MCSPI_CONF_CH(sc->sc_cs)); >> + if (*request) >> + reg |=3D MCSPI_CONF_SBPOL; >> + else >> + reg &=3D ~MCSPI_CONF_SBPOL; >> + TI_SPI_WRITE(sc, MCSPI_CONF_CH(sc->sc_cs), reg); >> + >> + /* Release the controller and wakeup the next thread waiting >> for it. */ >> + sc->sc_flags =3D 0; >> + wakeup_one(dev); >> + TI_SPI_UNLOCK(sc); >> + >> + return (0); >> +} >> + >> =A0static device_method_t ti_spi_methods[] =3D { >> =A0 /* Device interface */ >> =A0 DEVMETHOD(device_probe, ti_spi_probe), >> @@ -569,6 +635,10 @@ static device_method_t ti_spi_methods[] =3D { >> =A0 >> =A0 /* ofw_bus interface */ >> =A0 DEVMETHOD(ofw_bus_get_node, ti_spi_get_node), >> + >> + /* provisional chip register interface for SBE and SBPOL */ >> + DEVMETHOD(spibus_sbe, ti_spi_sbe), >> + DEVMETHOD(spibus_sbpol, ti_spi_sbpol), >> =A0 >> =A0 DEVMETHOD_END >> =A0}; >> --- dev/spibus/spibus.c.orig 2018-12-29 23:50:40.262296000 >> +0900 >> +++ dev/spibus/spibus.c 2018-12-30 23:58:00.000000000 +0900 >> @@ -226,6 +226,18 @@ spibus_transfer_impl(device_t dev, device_t >> child, str >> =A0 return (SPIBUS_TRANSFER(device_get_parent(dev), child, >> cmd)); >> =A0} >> =A0 >> +static int >> +spibus_sbe_impl(device_t dev, device_t child, uint32_t *request) >> +{ >> + return (SPIBUS_SBE(device_get_parent(dev), child, request)); >> +} >> + >> +static int >> +spibus_sbpol_impl(device_t dev, device_t child, uint32_t *request) >> +{ >> + return (SPIBUS_SBPOL(device_get_parent(dev), child, >> request)); >> +} >> + >> =A0static device_method_t spibus_methods[] =3D { >> =A0 /* Device interface */ >> =A0 DEVMETHOD(device_probe, spibus_probe), >> @@ -247,6 +259,9 @@ static device_method_t spibus_methods[] =3D { >> =A0 >> =A0 /* spibus interface */ >> =A0 DEVMETHOD(spibus_transfer, spibus_transfer_impl), >> + >> + DEVMETHOD(spibus_sbe, spibus_sbe_impl), >> + DEVMETHOD(spibus_sbpol, spibus_sbpol_impl), >> =A0 >> =A0 DEVMETHOD_END >> =A0}; >> --- dev/spibus/spibus_if.m.orig 2018-12-22 00:49:22.440211000 >> +0900 >> +++ dev/spibus/spibus_if.m 2018-12-30 23:58:00.000000000 +0900 >> @@ -39,3 +39,15 @@ METHOD int transfer { >> =A0 device_t child; >> =A0 struct spi_command *cmd; >> =A0}; >> + >> +METHOD int sbe { >> + device_t dev; >> + device_t child; >> + uint32_t *request; >> +}; >> + >> +METHOD int sbpol { >> + device_t dev; >> + device_t child; >> + uint32_t *request; >> +}; >> --- dev/spibus/spigen.c.orig 2018-12-29 20:19:20.584696000 >> +0900 >> +++ dev/spibus/spigen.c 2018-12-30 23:58:00.000000000 +0900 >> @@ -248,6 +248,28 @@ spigen_transfer_mmapped(struct cdev *cdev, >> struct spig >> =A0} >> =A0 >> =A0static int >> +spigen_sbe(struct cdev *cdev, uint32_t *request) >> +{ >> + device_t dev =3D cdev->si_drv1; >> + int error =3D 0; >> + >> + error =3D SPIBUS_SBE(device_get_parent(dev), dev, (uint32_t >> *)request); >> + >> + return (error); >> +} >> + >> +static int >> +spigen_sbpol(struct cdev *cdev, uint32_t *request) >> +{ >> + device_t dev =3D cdev->si_drv1; >> + int error =3D 0; >> + >> + error =3D SPIBUS_SBPOL(device_get_parent(dev), dev, (uint32_t >> *)request); >> + >> + return (error); >> +} >> + >> +static int >> =A0spigen_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int ffl= ag, >> =A0=A0=A0=A0=A0struct thread *td) >> =A0{ >> @@ -272,6 +294,12 @@ spigen_ioctl(struct cdev *cdev, u_long cmd, >> caddr_t da >> =A0 break; >> =A0 case SPIGENIOC_SET_SPI_MODE: >> =A0 error =3D spibus_set_mode(dev, *(uint32_t *)data); >> + break; >> + case SPIGENIOC_SBE: >> + error =3D spigen_sbe(cdev, (uint32_t *)data); >> + break; >> + case SPIGENIOC_SBPOL: >> + error =3D spigen_sbpol(cdev, (uint32_t *)data); >> =A0 break; >> =A0 default: >> =A0 error =3D ENOTTY; >> --- sys/spigenio.h.orig 2018-12-22 00:48:50.752200000 +0900 >> +++ sys/spigenio.h 2018-12-30 23:58:00.000000000 +0900 >> @@ -52,5 +52,7 @@ struct spigen_transfer_mmapped { >> =A0#define SPIGENIOC_SET_CLOCK_SPEED=A0=A0_IOW(SPIGENIOC_BASE, 3, ui= nt32_t) >> =A0#define SPIGENIOC_GET_SPI_MODE=A0=A0=A0=A0=A0_IOR(SPIGENIOC_BASE,= 4, uint32_t) >> =A0#define SPIGENIOC_SET_SPI_MODE=A0=A0=A0=A0=A0_IOW(SPIGENIOC_BASE,= 5, uint32_t) >> +#define SPIGENIOC_SBE=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0_IOW= (SPIGENIOC_BASE, 6, uint32_t) >> +#define SPIGENIOC_SBPOL=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0_IOW(SPI= GENIOC_BASE, 7, uint32_t) >> =A0 >> =A0#endif /* !_SYS_SPIGENIO_H_ */ >> = >> -- > = > I've been working with SPI devices for years, and I don't think I've > ever heard of this SBE and SBPOL stuff. Can you point me to a standar= ds > document or something else that describes it? > = > -- Ian Sure, here it is. Fig. 9.3.1, p. 30, https://www.crystalfontz.com/controllers/Sitroni= x/ST7735/ When the start bit is enabled, one extra clock is added, request =3D 1; ioctl(lcd->spi_fd, SPIGENIOC_SBE, &request); and the data porarity is controled by the start bit porarity. ioctl(h->spi_fd, SPIGENIOC_SBPOL, &request); By this patch, BeagleBone Mini Display Cape is usable. https://www.logicsupply.com/999-0004100/ -- SAITOU Toshihide
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20181231.080953.1864031625387192599.toshi>