Пример #1
0
int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
{
	struct omapfb_info *ofbi = FB2OFB(fbi);
	struct omapfb2_device *fbdev = ofbi->fbdev;
	struct omap_display *display = fb2display(fbi);

	union {
		struct omapfb_update_window_old	uwnd_o;
		struct omapfb_update_window	uwnd;
		struct omapfb_plane_info	plane_info;
		struct omapfb_caps		caps;
		struct omapfb_mem_info          mem_info;
		enum omapfb_update_mode		update_mode;
		int test_num;
	} p;

	int r = 0;

	DBG("ioctl %x (%d)\n", cmd, cmd & 0xff);

	switch (cmd) {
	case OMAPFB_SYNC_GFX:
		if (!display || !display->sync) {
			/* DSS1 never returns an error here, so we neither */
			/*r = -EINVAL;*/
			break;
		}

		omapfb_lock(fbdev);
		r = display->sync(display);
		omapfb_unlock(fbdev);
		break;

	case OMAPFB_UPDATE_WINDOW_OLD:
		if (!display || !display->update) {
			r = -EINVAL;
			break;
		}

		if (copy_from_user(&p.uwnd_o,
					(void __user *)arg,
					sizeof(p.uwnd_o))) {
			r = -EFAULT;
			break;
		}

		r = omapfb_update_window(fbi, p.uwnd_o.x, p.uwnd_o.y,
				p.uwnd_o.width, p.uwnd_o.height);
		break;

	case OMAPFB_UPDATE_WINDOW:
		if (!display || !display->update) {
			r = -EINVAL;
			break;
		}

		if (copy_from_user(&p.uwnd, (void __user *)arg,
					sizeof(p.uwnd))) {
			r = -EFAULT;
			break;
		}

		r = omapfb_update_window(fbi, p.uwnd.x, p.uwnd.y,
				p.uwnd.width, p.uwnd.height);
		break;

	case OMAPFB_SETUP_PLANE:
		if (copy_from_user(&p.plane_info, (void __user *)arg,
					sizeof(p.plane_info)))
			r = -EFAULT;
		else
			r = omapfb_setup_plane(fbi, &p.plane_info);
		break;
	
	case OMAPFB_CROP_PLANE:
		if (copy_from_user(&p.plane_info, (void __user *)arg,
					sizeof(p.plane_info)))
			r = -EFAULT;
		else
			r = omapfb_crop_plane(fbi, &p.plane_info);
		break;

	case OMAPFB_QUERY_PLANE:
		r = omapfb_query_plane(fbi, &p.plane_info);
		if (r < 0)
			break;
		if (copy_to_user((void __user *)arg, &p.plane_info,
					sizeof(p.plane_info)))
			r = -EFAULT;
		break;

	case OMAPFB_SETUP_MEM:
		if (copy_from_user(&p.mem_info, (void __user *)arg,
					sizeof(p.mem_info)))
			r = -EFAULT;
		else
			r = omapfb_setup_mem(fbi, &p.mem_info);
		break;

	case OMAPFB_QUERY_MEM:
		r = omapfb_query_mem(fbi, &p.mem_info);
		if (r < 0)
			break;
		if (copy_to_user((void __user *)arg, &p.mem_info,
					sizeof(p.mem_info)))
			r = -EFAULT;
		break;

	case OMAPFB_GET_CAPS:
		if (!display) {
			r = -EINVAL;
			break;
		}

		p.caps.ctrl = display->caps;

		if (copy_to_user((void __user *)arg, &p.caps, sizeof(p.caps)))
			r = -EFAULT;
		break;

	case OMAPFB_SET_UPDATE_MODE:
		if (get_user(p.update_mode, (int __user *)arg))
			r = -EFAULT;
		else
			r = omapfb_set_update_mode(fbi, p.update_mode);
		break;

	case OMAPFB_GET_UPDATE_MODE:
		r = omapfb_get_update_mode(fbi, &p.update_mode);
		if (r)
			break;
		if (put_user(p.update_mode,
					(enum omapfb_update_mode __user *)arg))
			r = -EFAULT;
		break;

	/* LCD and CTRL tests do the same thing for backward
	 * compatibility */
	case OMAPFB_LCD_TEST:
		if (get_user(p.test_num, (int __user *)arg)) {
			r = -EFAULT;
			break;
		}
		if (!display || !display->run_test) {
			r = -EINVAL;
			break;
		}

		r = display->run_test(display, p.test_num);

		break;

	case OMAPFB_CTRL_TEST:
		if (get_user(p.test_num, (int __user *)arg)) {
			r = -EFAULT;
			break;
		}
		if (!display || !display->run_test) {
			r = -EINVAL;
			break;
		}

		r = display->run_test(display, p.test_num);

		break;
	case OMAPFB_WAIT_FOR_VSYNC:
		return omapfb_wait_for_vsync(fbi);
		break;
        case OMAPFB_VRFB_ROTATE_CCW:
		ofbi->rotation_type = OMAPFB_ROT_VRFB;
  		ofbi->rotation = FB_ROTATE_CCW;
		set_fb_fix(fbi);
		omapfb_apply_changes(fbi, 0);
		
		break;
	default:
		DBG("ioctl unhandled\n");
		r = -EINVAL;
	}

	return r;
}
Пример #2
0
int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
{
    struct omapfb_info *ofbi = FB2OFB(fbi);
    struct omapfb2_device *fbdev = ofbi->fbdev;
    struct omap_dss_device *display = fb2display(fbi);
    struct omap_overlay_manager *mgr;

    union {
        struct omapfb_update_window_old	uwnd_o;
        struct omapfb_update_window	uwnd;
        struct omapfb_plane_info	plane_info;
        struct omapfb_caps		caps;
        struct omapfb_mem_info          mem_info;
        struct omapfb_color_key		color_key;
        struct omapfb_ovl_colormode	ovl_colormode;
        enum omapfb_update_mode		update_mode;
        int test_num;
        struct omapfb_memory_read	memory_read;
        struct omapfb_vram_info		vram_info;
        struct omapfb_tearsync_info	tearsync_info;
        struct omapfb_display_info	display_info;
        u32				crt;
    } p;

    int r = 0;

    switch (cmd) {
    case OMAPFB_SYNC_GFX:
        DBG("ioctl SYNC_GFX\n");
        if (!display || !display->driver->sync) {
            /* DSS1 never returns an error here, so we neither */
            /*r = -EINVAL;*/
            break;
        }

        r = display->driver->sync(display);
        break;

    case OMAPFB_UPDATE_WINDOW_OLD:
        DBG("ioctl UPDATE_WINDOW_OLD\n");
        if (!display || !display->driver->update) {
            r = -EINVAL;
            break;
        }

        if (copy_from_user(&p.uwnd_o,
                           (void __user *)arg,
                           sizeof(p.uwnd_o))) {
            r = -EFAULT;
            break;
        }

        r = omapfb_update_window(fbi, p.uwnd_o.x, p.uwnd_o.y,
                                 p.uwnd_o.width, p.uwnd_o.height);
        break;

    case OMAPFB_UPDATE_WINDOW:
        DBG("ioctl UPDATE_WINDOW\n");
        if (!display || !display->driver->update) {
            r = -EINVAL;
            break;
        }

        if (copy_from_user(&p.uwnd, (void __user *)arg,
                           sizeof(p.uwnd))) {
            r = -EFAULT;
            break;
        }

        r = omapfb_update_window(fbi, p.uwnd.x, p.uwnd.y,
                                 p.uwnd.width, p.uwnd.height);
        break;

    case OMAPFB_SETUP_PLANE:
        DBG("ioctl SETUP_PLANE\n");
        if (copy_from_user(&p.plane_info, (void __user *)arg,
                           sizeof(p.plane_info)))
            r = -EFAULT;
        else
            r = omapfb_setup_plane(fbi, &p.plane_info);
        break;

    case OMAPFB_QUERY_PLANE:
        DBG("ioctl QUERY_PLANE\n");
        r = omapfb_query_plane(fbi, &p.plane_info);
        if (r < 0)
            break;
        if (copy_to_user((void __user *)arg, &p.plane_info,
                         sizeof(p.plane_info)))
            r = -EFAULT;
        break;

    case OMAPFB_SETUP_MEM:
        DBG("ioctl SETUP_MEM\n");
        if (copy_from_user(&p.mem_info, (void __user *)arg,
                           sizeof(p.mem_info)))
            r = -EFAULT;
        else
            r = omapfb_setup_mem(fbi, &p.mem_info);
        break;

    case OMAPFB_QUERY_MEM:
        DBG("ioctl QUERY_MEM\n");
        r = omapfb_query_mem(fbi, &p.mem_info);
        if (r < 0)
            break;
        if (copy_to_user((void __user *)arg, &p.mem_info,
                         sizeof(p.mem_info)))
            r = -EFAULT;
        break;

    case OMAPFB_GET_CAPS:
        DBG("ioctl GET_CAPS\n");
        if (!display) {
            r = -EINVAL;
            break;
        }

        memset(&p.caps, 0, sizeof(p.caps));
        if (display->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE)
            p.caps.ctrl |= OMAPFB_CAPS_MANUAL_UPDATE;
        if (display->caps & OMAP_DSS_DISPLAY_CAP_TEAR_ELIM)
            p.caps.ctrl |= OMAPFB_CAPS_TEARSYNC;

        if (copy_to_user((void __user *)arg, &p.caps, sizeof(p.caps)))
            r = -EFAULT;
        break;

    case OMAPFB_GET_OVERLAY_COLORMODE:
        DBG("ioctl GET_OVERLAY_COLORMODE\n");
        if (copy_from_user(&p.ovl_colormode, (void __user *)arg,
                           sizeof(p.ovl_colormode))) {
            r = -EFAULT;
            break;
        }
        r = omapfb_get_ovl_colormode(fbdev, &p.ovl_colormode);
        if (r < 0)
            break;
        if (copy_to_user((void __user *)arg, &p.ovl_colormode,
                         sizeof(p.ovl_colormode)))
            r = -EFAULT;
        break;

    case OMAPFB_SET_UPDATE_MODE:
        DBG("ioctl SET_UPDATE_MODE\n");
        if (get_user(p.update_mode, (int __user *)arg))
            r = -EFAULT;
        else
            r = omapfb_set_update_mode(fbi, p.update_mode);
        break;

    case OMAPFB_GET_UPDATE_MODE:
        DBG("ioctl GET_UPDATE_MODE\n");
        r = omapfb_get_update_mode(fbi, &p.update_mode);
        if (r)
            break;
        if (put_user(p.update_mode,
                     (enum omapfb_update_mode __user *)arg))
            r = -EFAULT;
        break;

    case OMAPFB_SET_COLOR_KEY:
        DBG("ioctl SET_COLOR_KEY\n");
        if (copy_from_user(&p.color_key, (void __user *)arg,
                           sizeof(p.color_key)))
            r = -EFAULT;
        else
            r = omapfb_set_color_key(fbi, &p.color_key);
        break;

    case OMAPFB_GET_COLOR_KEY:
        DBG("ioctl GET_COLOR_KEY\n");
        r = omapfb_get_color_key(fbi, &p.color_key);
        if (r)
            break;
        if (copy_to_user((void __user *)arg, &p.color_key,
                         sizeof(p.color_key)))
            r = -EFAULT;
        break;

    case FBIO_WAITFORVSYNC:
        if (get_user(p.crt, (__u32 __user *)arg)) {
            r = -EFAULT;
            break;
        }
        if (p.crt != 0) {
            r = -ENODEV;
            break;
        }
    /* FALLTHROUGH */

    case OMAPFB_WAITFORVSYNC:
        DBG("ioctl WAITFORVSYNC\n");

        if (!display) {
            r = -EINVAL;
            break;
        }

        mgr = omapdss_find_mgr_from_display(display);
        if (!mgr) {
            r = -EINVAL;
            break;
        }

        r = mgr->wait_for_vsync(mgr);
        break;

    case OMAPFB_WAITFORGO:
        DBG("ioctl WAITFORGO\n");
        if (!display) {
            r = -EINVAL;
            break;
        }

        r = omapfb_wait_for_go(fbi);
        break;

    /* LCD and CTRL tests do the same thing for backward
     * compatibility */
    case OMAPFB_LCD_TEST:
        DBG("ioctl LCD_TEST\n");
        if (get_user(p.test_num, (int __user *)arg)) {
            r = -EFAULT;
            break;
        }
        if (!display || !display->driver->run_test) {
            r = -EINVAL;
            break;
        }

        r = display->driver->run_test(display, p.test_num);

        break;

    case OMAPFB_CTRL_TEST:
        DBG("ioctl CTRL_TEST\n");
        if (get_user(p.test_num, (int __user *)arg)) {
            r = -EFAULT;
            break;
        }
        if (!display || !display->driver->run_test) {
            r = -EINVAL;
            break;
        }

        r = display->driver->run_test(display, p.test_num);

        break;

    case OMAPFB_MEMORY_READ:
        DBG("ioctl MEMORY_READ\n");

        if (copy_from_user(&p.memory_read, (void __user *)arg,
                           sizeof(p.memory_read))) {
            r = -EFAULT;
            break;
        }

        r = omapfb_memory_read(fbi, &p.memory_read);

        break;

    case OMAPFB_GET_VRAM_INFO: {
        DBG("ioctl GET_VRAM_INFO\n");

        /*
         * We don't have the ability to get this vram info anymore.
         * Fill in something that should keep the applications working.
         */
        p.vram_info.total = SZ_1M * 64;
        p.vram_info.free = SZ_1M * 64;
        p.vram_info.largest_free_block = SZ_1M * 64;

        if (copy_to_user((void __user *)arg, &p.vram_info,
                         sizeof(p.vram_info)))
            r = -EFAULT;
        break;
    }

    case OMAPFB_SET_TEARSYNC: {
        DBG("ioctl SET_TEARSYNC\n");

        if (copy_from_user(&p.tearsync_info, (void __user *)arg,
                           sizeof(p.tearsync_info))) {
            r = -EFAULT;
            break;
        }

        if (!display || !display->driver->enable_te) {
            r = -ENODEV;
            break;
        }

        r = display->driver->enable_te(display,
                                       !!p.tearsync_info.enabled);

        break;
    }

    case OMAPFB_GET_DISPLAY_INFO: {
        u16 xres, yres;

        DBG("ioctl GET_DISPLAY_INFO\n");

        if (display == NULL) {
            r = -ENODEV;
            break;
        }

        display->driver->get_resolution(display, &xres, &yres);

        p.display_info.xres = xres;
        p.display_info.yres = yres;

        if (display->driver->get_dimensions) {
            u32 w, h;
            display->driver->get_dimensions(display, &w, &h);
            p.display_info.width = w;
            p.display_info.height = h;
        } else {
            p.display_info.width = 0;
            p.display_info.height = 0;
        }

        if (copy_to_user((void __user *)arg, &p.display_info,
                         sizeof(p.display_info)))
            r = -EFAULT;
        break;
    }

    default:
        dev_err(fbdev->dev, "Unknown ioctl 0x%x\n", cmd);
        r = -EINVAL;
    }

    if (r < 0)
        DBG("ioctl failed: %d\n", r);

    return r;
}
int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
{
	struct omapfb_info *ofbi = FB2OFB(fbi);
	struct omapfb2_device *fbdev = ofbi->fbdev;
	struct omap_dss_device *display = fb2display(fbi);

	union {
		struct omapfb_update_window_old	uwnd_o;
		struct omapfb_update_window	uwnd;
		struct omapfb_plane_info	plane_info;
		struct omapfb_caps		caps;
		struct omapfb_mem_info          mem_info;
		struct omapfb_color_key		color_key;
		struct omapfb_ovl_colormode	ovl_colormode;
		enum omapfb_update_mode		update_mode;
		int test_num;
		struct omapfb_memory_read	memory_read;
	} p;

	int r = 0;

	switch (cmd) {
	case OMAPFB_SYNC_GFX:
		DBG("ioctl SYNC_GFX\n");
		if (!display || !display->sync) {
			/* DSS1 never returns an error here, so we neither */
			/*r = -EINVAL;*/
			break;
		}

		r = display->sync(display);
		break;

	case OMAPFB_UPDATE_WINDOW_OLD:
		DBG("ioctl UPDATE_WINDOW_OLD\n");
		if (!display || !display->update) {
			r = -EINVAL;
			break;
		}

		if (copy_from_user(&p.uwnd_o,
					(void __user *)arg,
					sizeof(p.uwnd_o))) {
			r = -EFAULT;
			break;
		}

		r = omapfb_update_window(fbi, p.uwnd_o.x, p.uwnd_o.y,
				p.uwnd_o.width, p.uwnd_o.height);
		break;

	case OMAPFB_UPDATE_WINDOW:
		DBG("ioctl UPDATE_WINDOW\n");
		if (!display || !display->update) {
			r = -EINVAL;
			break;
		}

		if (copy_from_user(&p.uwnd, (void __user *)arg,
					sizeof(p.uwnd))) {
			r = -EFAULT;
			break;
		}

		r = omapfb_update_window(fbi, p.uwnd.x, p.uwnd.y,
				p.uwnd.width, p.uwnd.height);
		break;

	case OMAPFB_SETUP_PLANE:
		DBG("ioctl SETUP_PLANE\n");
		if (copy_from_user(&p.plane_info, (void __user *)arg,
					sizeof(p.plane_info)))
			r = -EFAULT;
		else
			r = omapfb_setup_plane(fbi, &p.plane_info);
		break;

	case OMAPFB_QUERY_PLANE:
		DBG("ioctl QUERY_PLANE\n");
		r = omapfb_query_plane(fbi, &p.plane_info);
		if (r < 0)
			break;
		if (copy_to_user((void __user *)arg, &p.plane_info,
					sizeof(p.plane_info)))
			r = -EFAULT;
		break;

	case OMAPFB_SETUP_MEM:
		DBG("ioctl SETUP_MEM\n");
		if (copy_from_user(&p.mem_info, (void __user *)arg,
					sizeof(p.mem_info)))
			r = -EFAULT;
		else
			r = omapfb_setup_mem(fbi, &p.mem_info);
		break;

	case OMAPFB_QUERY_MEM:
		DBG("ioctl QUERY_MEM\n");
		r = omapfb_query_mem(fbi, &p.mem_info);
		if (r < 0)
			break;
		if (copy_to_user((void __user *)arg, &p.mem_info,
					sizeof(p.mem_info)))
			r = -EFAULT;
		break;

	case OMAPFB_GET_CAPS:
		DBG("ioctl GET_CAPS\n");
		if (!display) {
			r = -EINVAL;
			break;
		}

		memset(&p.caps, 0, sizeof(p.caps));
		p.caps.ctrl = display->caps;

		if (copy_to_user((void __user *)arg, &p.caps, sizeof(p.caps)))
			r = -EFAULT;
		break;

	case OMAPFB_GET_OVERLAY_COLORMODE:
		DBG("ioctl GET_OVERLAY_COLORMODE\n");
		if (copy_from_user(&p.ovl_colormode, (void __user *)arg,
				   sizeof(p.ovl_colormode))) {
			r = -EFAULT;
			break;
		}
		r = omapfb_get_ovl_colormode(fbdev, &p.ovl_colormode);
		if (r < 0)
			break;
		if (copy_to_user((void __user *)arg, &p.ovl_colormode,
				 sizeof(p.ovl_colormode)))
			r = -EFAULT;
		break;

	case OMAPFB_SET_UPDATE_MODE:
		DBG("ioctl SET_UPDATE_MODE\n");
		if (get_user(p.update_mode, (int __user *)arg))
			r = -EFAULT;
		else
			r = omapfb_set_update_mode(fbi, p.update_mode);
		break;

	case OMAPFB_GET_UPDATE_MODE:
		DBG("ioctl GET_UPDATE_MODE\n");
		r = omapfb_get_update_mode(fbi, &p.update_mode);
		if (r)
			break;
		if (put_user(p.update_mode,
					(enum omapfb_update_mode __user *)arg))
			r = -EFAULT;
		break;

	case OMAPFB_SET_COLOR_KEY:
		DBG("ioctl SET_COLOR_KEY\n");
		if (copy_from_user(&p.color_key, (void __user *)arg,
				   sizeof(p.color_key)))
			r = -EFAULT;
		else
			r = omapfb_set_color_key(fbi, &p.color_key);
		break;

	case OMAPFB_GET_COLOR_KEY:
		DBG("ioctl GET_COLOR_KEY\n");
		r = omapfb_get_color_key(fbi, &p.color_key);
		if (r)
			break;
		if (copy_to_user((void __user *)arg, &p.color_key,
				 sizeof(p.color_key)))
			r = -EFAULT;
		break;

	case OMAPFB_WAITFORVSYNC:
		DBG("ioctl WAITFORVSYNC\n");
		if (!display) {
			r = -EINVAL;
			break;
		}

		r = display->wait_vsync(display);
		break;

	case OMAPFB_WAITFORGO:
		DBG("ioctl WAITFORGO\n");
		if (!display) {
			r = -EINVAL;
			break;
		}

		r = omapfb_wait_for_go(fbi);
		break;

	/* LCD and CTRL tests do the same thing for backward
	 * compatibility */
	case OMAPFB_LCD_TEST:
		DBG("ioctl LCD_TEST\n");
		if (get_user(p.test_num, (int __user *)arg)) {
			r = -EFAULT;
			break;
		}
		if (!display || !display->run_test) {
			r = -EINVAL;
			break;
		}

		r = display->run_test(display, p.test_num);

		break;

	case OMAPFB_CTRL_TEST:
		DBG("ioctl CTRL_TEST\n");
		if (get_user(p.test_num, (int __user *)arg)) {
			r = -EFAULT;
			break;
		}
		if (!display || !display->run_test) {
			r = -EINVAL;
			break;
		}

		r = display->run_test(display, p.test_num);

		break;

	case OMAPFB_MEMORY_READ:
		DBG("ioctl MEMORY_READ\n");

		if (copy_from_user(&p.memory_read, (void __user *)arg,
					sizeof(p.memory_read))) {
			r = -EFAULT;
			break;
		}

		r = omapfb_memory_read(fbi, &p.memory_read);

		break;

	default:
		dev_err(fbdev->dev, "Unknown ioctl 0x%x\n", cmd);
		r = -EINVAL;
	}

	if (r < 0)
		DBG("ioctl failed: %d\n", r);

	return r;
}