static int lpc_spi_attach(device_t dev) { struct lpc_spi_softc *sc = device_get_softc(dev); int rid; sc->ls_dev = dev; rid = 0; sc->ls_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); if (!sc->ls_mem_res) { device_printf(dev, "cannot allocate memory window\n"); return (ENXIO); } sc->ls_bst = rman_get_bustag(sc->ls_mem_res); sc->ls_bsh = rman_get_bushandle(sc->ls_mem_res); rid = 0; sc->ls_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE); if (!sc->ls_irq_res) { device_printf(dev, "cannot allocate interrupt\n"); return (ENXIO); } bus_space_write_4(sc->ls_bst, 0xd0028100, 0, (1<<12)|(1<<10)|(1<<9)|(1<<8)|(1<<6)|(1<<5)); lpc_pwr_write(dev, LPC_CLKPWR_SSP_CTRL, LPC_CLKPWR_SSP_CTRL_SSP0EN); lpc_spi_write_4(sc, LPC_SSP_CR0, LPC_SSP_CR0_DSS(8)); lpc_spi_write_4(sc, LPC_SSP_CR1, LPC_SSP_CR1_SSE); lpc_spi_write_4(sc, LPC_SSP_CPSR, 128); device_add_child(dev, "spibus", 0); return (bus_generic_attach(dev)); }
static int lpc_fb_attach(device_t dev) { struct lpc_fb_softc *sc = device_get_softc(dev); struct lpc_fb_dmamap_arg ctx; phandle_t node; int mode, rid, err = 0; sc->lf_dev = dev; mtx_init(&sc->lf_mtx, "lpcfb", "fb", MTX_DEF); rid = 0; sc->lf_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); if (!sc->lf_mem_res) { device_printf(dev, "cannot allocate memory window\n"); return (ENXIO); } sc->lf_bst = rman_get_bustag(sc->lf_mem_res); sc->lf_bsh = rman_get_bushandle(sc->lf_mem_res); rid = 0; sc->lf_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE); if (!sc->lf_irq_res) { device_printf(dev, "cannot allocate interrupt\n"); bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->lf_mem_res); return (ENXIO); } if (bus_setup_intr(dev, sc->lf_irq_res, INTR_TYPE_MISC | INTR_MPSAFE, NULL, lpc_fb_intr, sc, &sc->lf_intrhand)) { bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->lf_mem_res); bus_release_resource(dev, SYS_RES_IRQ, 1, sc->lf_irq_res); device_printf(dev, "cannot setup interrupt handler\n"); return (ENXIO); } node = ofw_bus_get_node(dev); err = lpc_fb_read_lcd_config(node, &sc->lf_lcd_config); if (err) { device_printf(dev, "cannot read LCD configuration\n"); goto fail; } sc->lf_buffer_size = sc->lf_lcd_config.lc_xres * sc->lf_lcd_config.lc_yres * (sc->lf_lcd_config.lc_bpp == 24 ? 3 : 2); device_printf(dev, "%dx%d LCD, %d bits per pixel, %dkHz pixel clock\n", sc->lf_lcd_config.lc_xres, sc->lf_lcd_config.lc_yres, sc->lf_lcd_config.lc_bpp, sc->lf_lcd_config.lc_pixelclock / 1000); err = bus_dma_tag_create( bus_get_dma_tag(sc->lf_dev), 4, 0, /* alignment, boundary */ BUS_SPACE_MAXADDR_32BIT, /* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ NULL, NULL, /* filter, filterarg */ sc->lf_buffer_size, 1, /* maxsize, nsegments */ sc->lf_buffer_size, 0, /* maxsegsize, flags */ NULL, NULL, /* lockfunc, lockarg */ &sc->lf_dma_tag); err = bus_dmamem_alloc(sc->lf_dma_tag, (void **)&sc->lf_buffer, 0, &sc->lf_dma_map); if (err) { device_printf(dev, "cannot allocate framebuffer\n"); goto fail; } err = bus_dmamap_load(sc->lf_dma_tag, sc->lf_dma_map, sc->lf_buffer, sc->lf_buffer_size, lpc_fb_dmamap_cb, &ctx, BUS_DMA_NOWAIT); if (err) { device_printf(dev, "cannot load DMA map\n"); goto fail; } switch (sc->lf_lcd_config.lc_bpp) { case 12: mode = LPC_CLKPWR_LCDCLK_CTRL_MODE_12; break; case 15: mode = LPC_CLKPWR_LCDCLK_CTRL_MODE_15; break; case 16: mode = LPC_CLKPWR_LCDCLK_CTRL_MODE_16; break; case 24: mode = LPC_CLKPWR_LCDCLK_CTRL_MODE_24; break; default: panic("unsupported bpp"); } lpc_pwr_write(sc->lf_dev, LPC_CLKPWR_LCDCLK_CTRL, LPC_CLKPWR_LCDCLK_CTRL_MODE(mode) | LPC_CLKPWR_LCDCLK_CTRL_HCLKEN); sc->lf_buffer_phys = ctx.lf_dma_busaddr; sc->lf_cdev = make_dev(&lpc_fb_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600, "lpcfb"); sc->lf_cdev->si_drv1 = sc; return (0); fail: return (ENXIO); }