static int panel_probe(struct platform_device *pdev) { struct device_node *node = pdev->dev.of_node; struct panel_module *panel_mod; struct tilcdc_module *mod; struct pinctrl *pinctrl; int ret = -EINVAL; /* bail out early if no DT data: */ if (!node) { dev_err(&pdev->dev, "device-tree data is missing\n"); return -ENXIO; } panel_mod = kzalloc(sizeof(*panel_mod), GFP_KERNEL); if (!panel_mod) return -ENOMEM; mod = &panel_mod->base; tilcdc_module_init(mod, "panel", &panel_module_ops); pinctrl = devm_pinctrl_get_select_default(&pdev->dev); if (IS_ERR(pinctrl)) dev_warn(&pdev->dev, "pins are not configured\n"); panel_mod->timings = of_get_display_timings(node); if (!panel_mod->timings) { dev_err(&pdev->dev, "could not get panel timings\n"); goto fail; } panel_mod->info = of_get_panel_info(node); if (!panel_mod->info) { dev_err(&pdev->dev, "could not get panel info\n"); goto fail; } mod->preferred_bpp = panel_mod->info->bpp; panel_mod->backlight = of_find_backlight_by_node(node); if (panel_mod->backlight) dev_info(&pdev->dev, "found backlight\n"); return 0; fail: panel_destroy(mod); return ret; }
static int wm8505fb_probe(struct platform_device *pdev) { struct wm8505fb_info *fbi; struct resource *res; struct display_timings *disp_timing; void *addr; int ret; struct fb_videomode mode; u32 bpp; dma_addr_t fb_mem_phys; unsigned long fb_mem_len; void *fb_mem_virt; fbi = devm_kzalloc(&pdev->dev, sizeof(struct wm8505fb_info) + sizeof(u32) * 16, GFP_KERNEL); if (!fbi) { dev_err(&pdev->dev, "Failed to initialize framebuffer device\n"); return -ENOMEM; } strcpy(fbi->fb.fix.id, DRIVER_NAME); fbi->fb.fix.type = FB_TYPE_PACKED_PIXELS; fbi->fb.fix.xpanstep = 1; fbi->fb.fix.ypanstep = 1; fbi->fb.fix.ywrapstep = 0; fbi->fb.fix.accel = FB_ACCEL_NONE; fbi->fb.fbops = &wm8505fb_ops; fbi->fb.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT | FBINFO_HWACCEL_XPAN | FBINFO_HWACCEL_YPAN | FBINFO_VIRTFB | FBINFO_PARTIAL_PAN_OK; fbi->fb.node = -1; addr = fbi; addr = addr + sizeof(struct wm8505fb_info); fbi->fb.pseudo_palette = addr; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); fbi->regbase = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(fbi->regbase)) return PTR_ERR(fbi->regbase); disp_timing = of_get_display_timings(pdev->dev.of_node); if (!disp_timing) return -EINVAL; ret = of_get_fb_videomode(pdev->dev.of_node, &mode, OF_USE_NATIVE_MODE); if (ret) return ret; ret = of_property_read_u32(pdev->dev.of_node, "bits-per-pixel", &bpp); if (ret) return ret; fb_videomode_to_var(&fbi->fb.var, &mode); fbi->fb.var.nonstd = 0; fbi->fb.var.activate = FB_ACTIVATE_NOW; fbi->fb.var.height = -1; fbi->fb.var.width = -1; /* try allocating the framebuffer */ fb_mem_len = mode.xres * mode.yres * 2 * (bpp / 8); fb_mem_virt = dmam_alloc_coherent(&pdev->dev, fb_mem_len, &fb_mem_phys, GFP_KERNEL); if (!fb_mem_virt) { pr_err("%s: Failed to allocate framebuffer\n", __func__); return -ENOMEM; } fbi->fb.var.xres_virtual = mode.xres; fbi->fb.var.yres_virtual = mode.yres * 2; fbi->fb.var.bits_per_pixel = bpp; fbi->fb.fix.smem_start = fb_mem_phys; fbi->fb.fix.smem_len = fb_mem_len; fbi->fb.screen_base = fb_mem_virt; fbi->fb.screen_size = fb_mem_len; fbi->contrast = 0x10; ret = wm8505fb_set_par(&fbi->fb); if (ret) { dev_err(&pdev->dev, "Failed to set parameters\n"); return ret; } if (fb_alloc_cmap(&fbi->fb.cmap, 256, 0) < 0) { dev_err(&pdev->dev, "Failed to allocate color map\n"); return -ENOMEM; } wm8505fb_init_hw(&fbi->fb); platform_set_drvdata(pdev, fbi); ret = register_framebuffer(&fbi->fb); if (ret < 0) { dev_err(&pdev->dev, "Failed to register framebuffer device: %d\n", ret); if (fbi->fb.cmap.len) fb_dealloc_cmap(&fbi->fb.cmap); return ret; } ret = device_create_file(&pdev->dev, &dev_attr_contrast); if (ret < 0) { printk(KERN_WARNING "fb%d: failed to register attributes (%d)\n", fbi->fb.node, ret); } printk(KERN_INFO "fb%d: %s frame buffer at 0x%lx-0x%lx\n", fbi->fb.node, fbi->fb.fix.id, fbi->fb.fix.smem_start, fbi->fb.fix.smem_start + fbi->fb.fix.smem_len - 1); return 0; }
static int panel_probe(struct platform_device *pdev) { struct device_node *bl_node, *node = pdev->dev.of_node; struct panel_module *panel_mod; struct tilcdc_module *mod; struct pinctrl *pinctrl; int ret; /* bail out early if no DT data: */ if (!node) { dev_err(&pdev->dev, "device-tree data is missing\n"); return -ENXIO; } panel_mod = devm_kzalloc(&pdev->dev, sizeof(*panel_mod), GFP_KERNEL); if (!panel_mod) return -ENOMEM; bl_node = of_parse_phandle(node, "backlight", 0); if (bl_node) { panel_mod->backlight = of_find_backlight_by_node(bl_node); of_node_put(bl_node); if (!panel_mod->backlight) return -EPROBE_DEFER; dev_info(&pdev->dev, "found backlight\n"); } panel_mod->enable_gpio = devm_gpiod_get_optional(&pdev->dev, "enable", GPIOD_OUT_LOW); if (IS_ERR(panel_mod->enable_gpio)) { ret = PTR_ERR(panel_mod->enable_gpio); dev_err(&pdev->dev, "failed to request enable GPIO\n"); goto fail_backlight; } if (panel_mod->enable_gpio) dev_info(&pdev->dev, "found enable GPIO\n"); mod = &panel_mod->base; pdev->dev.platform_data = mod; tilcdc_module_init(mod, "panel", &panel_module_ops); pinctrl = devm_pinctrl_get_select_default(&pdev->dev); if (IS_ERR(pinctrl)) dev_warn(&pdev->dev, "pins are not configured\n"); panel_mod->timings = of_get_display_timings(node); if (!panel_mod->timings) { dev_err(&pdev->dev, "could not get panel timings\n"); ret = -EINVAL; goto fail_free; } panel_mod->info = of_get_panel_info(node); if (!panel_mod->info) { dev_err(&pdev->dev, "could not get panel info\n"); ret = -EINVAL; goto fail_timings; } mod->preferred_bpp = panel_mod->info->bpp; return 0; fail_timings: display_timings_release(panel_mod->timings); fail_free: tilcdc_module_cleanup(mod); fail_backlight: if (panel_mod->backlight) put_device(&panel_mod->backlight->dev); return ret; }