static ssize_t store_managers(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct platform_device *pdev = to_platform_device(dev); struct omapfb2_device *fbdev = platform_get_drvdata(pdev); struct omap_overlay_manager *mgr; struct omap_display *display = NULL; char displayname[10]; int r; char *s, *tok; char str[128]; struct omap_overlay_manager_info newinfo; int apply = 0; displayname[0] = '\0'; if (strlen(buf) > sizeof(str) - 1) return -EINVAL; strcpy(str, buf); /* remove trailing linefeeds */ s = str + strlen(str) - 1; while (s >= str && *s == '\n') { *s = 0; s--; } s = str; if ((tok = strsep(&s, " ")) == 0) return -EINVAL; omapfb_lock(fbdev); mgr = find_manager_by_name(fbdev, tok); if (!mgr) { dev_err(dev, "manager not found\n"); r = -EINVAL; goto err; } newinfo = mgr->info; while ((tok = strsep(&s, " "))) { if (strncmp(tok, "t:", 2) == 0) { r = sscanf(tok, "t:%9s", displayname); if (r != 1) { r = -EINVAL; goto err; } } else if(strncmp(tok, "trans:", 6) == 0) { newinfo.trans_enabled = simple_strtoul(tok+6, NULL, 0); } else if(strncmp(tok, "type:", 5) == 0) { newinfo.trans_key_type = simple_strtoul(tok+5, NULL, 0); } else if(strncmp(tok, "key:", 4) == 0) { newinfo.trans_key = simple_strtoul(tok+4, NULL, 0); } else if(strncmp(tok, "alpha:", 6) == 0) { newinfo.alpha_enabled = simple_strtoul(tok+6, NULL, 0); } else { dev_err(dev, "unknown option\n"); r = -EINVAL; goto err; } } if (memcmp(&newinfo, &mgr->info, sizeof(struct omap_overlay_manager_info)) != 0) { mgr->info = newinfo; mgr->info_dirty = 1; apply = 1; } if (displayname[0] != '\0') { if (strcmp(displayname, "none") == 0) { display = NULL; } else { display = find_display_by_name(fbdev, displayname); if (!display) { dev_err(dev, "display not found: [%s]\n", displayname); r = -EINVAL; goto err; } } if (mgr->display) { r = mgr->unset_display(mgr); if (r) { dev_err(dev, "failed to unset display\n"); goto err; } } if (display) { r = mgr->set_display(mgr, display); if (r) { dev_err(dev, "failed to set manager\n"); goto err; } } apply = 1; } if (apply) { r = mgr->apply(mgr); if (r) { dev_err(dev, "failed to apply dispc config\n"); goto err; } } omapfb_unlock(fbdev); return count; err: omapfb_unlock(fbdev); return r; }
static ssize_t store_displays(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct platform_device *pdev = to_platform_device(dev); struct omapfb2_device *fbdev = platform_get_drvdata(pdev); int enable; struct omap_video_timings old_timings; struct omap_video_timings new_timings; enum omap_dss_update_mode mode; enum omap_dss_venc_norm new_norm; enum omap_dss_venc_type new_type = OMAP_DSS_VENC_TYPE_COMPOSITE; struct omap_display *display = NULL; int r; int te, rot, mir; char str[128]; char *s, *tok; if (strlen(buf) > sizeof(str) - 1) return -EINVAL; strcpy(str, buf); /* remove trailing linefeeds */ s = str + strlen(str) - 1; while (s >= str && *s == '\n') { *s = 0; s--; } s = str; if ((tok = strsep(&s, " ")) == 0) return -EINVAL; omapfb_lock(fbdev); display = find_display_by_name(fbdev, tok); if (!display) { dev_err(dev, "display not found: [%s]\n", tok); r = -EINVAL; goto err; } enable = display->state != OMAP_DSS_DISPLAY_DISABLED; if (display->get_update_mode) mode = display->get_update_mode(display); else mode = 0; if (display->get_te) te = display->get_te(display); else te = 0; if (display->get_rotate) rot = display->get_rotate(display); else rot = 0; if (display->get_mirror) mir = display->get_mirror(display); else mir = 0; if (display->get_timings) display->get_timings(display, &old_timings); else memset(&old_timings, 0, sizeof(old_timings)); memcpy(&new_timings, &old_timings, sizeof(new_timings)); /* TV norm switching */ if (display->get_tv_norm) new_norm = display->get_tv_norm(display); else new_norm = -1; /* TV type switching */ if (display->get_tv_type) new_type = display->get_tv_type(display); while ((tok = strsep(&s, " "))) { char c, *o; if (strlen(tok) < 3 || tok[1] != ':') { dev_err(dev, "illegal option\n"); r = -EINVAL; goto err; } c = tok[0]; o = tok + 2; switch (c) { case 'e': enable = simple_strtoul(o, NULL, 0); break; case 'u': mode = simple_strtoul(o, NULL, 0); break; case 't': te = simple_strtoul(o, NULL, 0); break; case 'r': rot = simple_strtoul(o, NULL, 0); break; case 'i': mir = simple_strtoul(o, NULL, 0); break; case 'm': { unsigned bpp; if (omapfb_mode_to_timings(o, &new_timings, &bpp) != 0) memset(&new_timings, 0, sizeof(new_timings)); break; } case 'h': { unsigned xres, hfp, hbp, hsw; if (sscanf(o, "%u/%u/%u/%u", &xres, &hfp, &hbp, &hsw) != 4) { dev_err(dev, "illegal horizontal timings\n"); r = -EINVAL; goto err; } new_timings.x_res = xres; new_timings.hfp = hfp; new_timings.hbp = hbp; new_timings.hsw = hsw; break; } case 'v': { unsigned yres, vfp, vbp, vsw; if (sscanf(o, "%u/%u/%u/%u", &yres, &vfp, &vbp, &vsw) != 4) { dev_err(dev, "illegal vertical timings\n"); r = -EINVAL; goto err; } new_timings.y_res = yres; new_timings.vfp = vfp; new_timings.vbp = vbp; new_timings.vsw = vsw; break; } case 'p': new_timings.pixel_clock = simple_strtoul(o, NULL, 0); break; case 'l': new_timings.interlaced = simple_strtoul(o, NULL, 0); break; case 'n': new_norm = simple_strtoul(o, NULL, 0); break; case 's': new_type = simple_strtoul(o, NULL, 0); break; default: dev_err(dev, "unknown option %c\n", c); r = -EINVAL; goto err; } } if (memcmp(&new_timings, &old_timings, sizeof(new_timings)) != 0) { if (display->set_timings) display->set_timings(display, &new_timings); /* sigh, bpp is not a setting of the display, but * the overlay. */ //def_display->panel->bpp = bpp; } if (display->set_update_mode && display->get_update_mode) { if (mode != display->get_update_mode(display)) display->set_update_mode(display, mode); } if (display->enable_te && display->get_te) { if (te != display->get_te(display)) display->enable_te(display, te); } if (display->set_rotate && display->get_rotate) { if (rot != display->get_rotate(display)) display->set_rotate(display, rot); } if (display->set_mirror && display->get_mirror) { if (mir != display->get_mirror(display)) display->set_mirror(display, mir); } if (display->set_tv_norm) display->set_tv_norm(display, new_norm); if (display->set_tv_type) display->set_tv_type(display, new_type); /* enable display after all settings */ if (enable != (display->state != OMAP_DSS_DISPLAY_DISABLED)) { if (enable) { r = display->enable(display); if (r) dev_err(dev, "failed to enable display\n"); } else { display->disable(display); } } r = count; err: omapfb_unlock(fbdev); return r; }
static ssize_t store_managers(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct platform_device *pdev = to_platform_device(dev); struct omapfb2_device *fbdev = platform_get_drvdata(pdev); int idx; struct omap_overlay_manager *mgr; struct omap_display *display; char mgrname[10]; char displayname[10]; int r; idx = 0; while (idx < count && buf[idx] != ' ') ++idx; if (idx == count) return -EINVAL; if (idx >= sizeof(mgrname)) return -EINVAL; strncpy(mgrname, buf, idx); mgrname[idx] = 0; idx++; omapfb_lock(fbdev); mgr = find_manager_by_name(fbdev, mgrname); if (!mgr) { dev_err(dev, "manager not found\n"); r = -EINVAL; goto err; } r = sscanf(buf + idx, "t:%9s", displayname); if (r != 1) { r = -EINVAL; goto err; } if (strcmp(displayname, "none") == 0) { display = NULL; } else { display = find_display_by_name(fbdev, displayname); if (!display) { dev_err(dev, "display not found\n"); r = -EINVAL; goto err; } } if (mgr->display) { r = mgr->unset_display(mgr); if (r) { dev_err(dev, "failed to unset display\n"); goto err; } } if (display) { r = mgr->set_display(mgr, display); if (r) { dev_err(dev, "failed to set manager\n"); goto err; } r = mgr->apply(mgr); if (r) { dev_err(dev, "failed to apply dispc config\n"); goto err; } } omapfb_unlock(fbdev); return count; err: omapfb_unlock(fbdev); return r; }