コード例 #1
0
static ssize_t sysfs_write_fps(struct device *dev,
			struct device_attribute *attr,
			const char *buf, size_t count)
{
	int ret, fps;
	struct fb_info *fbi = dev_get_drvdata(dev);
	struct sprdfb_device *fb_dev = (struct sprdfb_device *)fbi->par;
	struct attr_info *attr_info = fb_dev->priv1;
	struct panel_spec* panel = fb_dev->panel;

	if (!panel) {
		pr_err("panel doesn't exist.");
		return -ENXIO;
	}
	ret = kstrtoint(buf, 10, &fps);

	fps = fps > 0 ? fps : attr_info->origin_fps;

	if (panel->fps == fps) {
		/* Do nothing */
		pr_warn("new fps is the same as current fps\n");
		return count;
	}

	ret = sprdfb_chg_clk_intf(fb_dev, SPRDFB_DYNAMIC_FPS, (u32)fps);
	if (ret) {
		pr_err("%s: failed to change dpi clock. ret=%d\n",
				__func__, ret);
		return ret;
	}
	attr_info->curr_fps = fps;

	return count;
}
コード例 #2
0
static ssize_t sysfs_write_mipi_clk(struct device *dev,
			struct device_attribute *attr,
			const char *buf, size_t count)
{
	int ret = 0;
	u32 dphy_freq;
	struct fb_info *fbi = dev_get_drvdata(dev);
	struct sprdfb_device *fb_dev = (struct sprdfb_device *)fbi->par;
	struct attr_info *attr_info = fb_dev->priv1;
	struct panel_spec* panel = fb_dev->panel;

	if (!panel) {
		pr_err("panel doesn't exist.");
		return -ENXIO;
	}
	if (panel->type != LCD_MODE_DSI) {
		pr_err("sys write failure. Current panel is not mipi dsi\n");
		return count;
	}
	ret = kstrtoint(buf, 10, &dphy_freq);
	if (ret) {
		pr_err("Invalid input for dphy_freq\n");
		return -EINVAL;
	}

	if (dphy_freq > 0) {
		/*
		 * because of double edge trigger,
		 * the rule is actual freq * 10 / 2,
		 * Eg: Required freq is 500M
		 * Equation: 2500*2*1000/10=500*1000=2500*200=500M
		 */
		dphy_freq *= 200;
	} else
		dphy_freq = attr_info->origin_mipi_clk;

	/* dphy supported freq ranges is 90M-1500M*/
	pr_debug("input dphy_freq is %d\n", dphy_freq);

	if (dphy_freq == attr_info->curr_mipi_clk) {
		/* Do nothing */
		pr_warn("new dphy_freq is the same as current freq\n");
		return count;
	}

	if (dphy_freq <= 1500000 && dphy_freq >= 90000) {
		ret = sprdfb_chg_clk_intf(fb_dev, SPRDFB_DYNAMIC_MIPI_CLK, dphy_freq);
		if (ret) {
			pr_err("sprdfb_chg_clk_intf change d-phy freq fail.\n");
			return count;
		}
		attr_info->curr_mipi_clk = dphy_freq;
	} else {
		pr_warn("input mipi frequency:%d is out of range.\n",
				dphy_freq);
	}

	return count;
}
コード例 #3
0
static ssize_t sysfs_write_pclk(struct device *dev,
			struct device_attribute *attr,
			const char *buf, size_t count)
{
	int ret;
	int divider;
	u32 dpi_clk_src, new_pclk;
	struct fb_info *fbi = dev_get_drvdata(dev);
	struct sprdfb_device *fb_dev = (struct sprdfb_device *)fbi->par;
	struct attr_info *attr_info = fb_dev->priv1;

	sscanf(buf, "%u,%d\n", &dpi_clk_src, &divider);

	if (divider == 0 && dpi_clk_src == 0) {
		new_pclk = attr_info->origin_pclk;
		goto DIRECT_GO;
	}

	if (divider < 1 || divider > 0xff || dpi_clk_src < 1) {
		pr_err("divider:[%d], clk_src:[%d] is invalid\n",
				divider, dpi_clk_src);
		return count;
	}

	if (dpi_clk_src < 1000)
		dpi_clk_src *= 1000000; /* MHz */

	new_pclk = dpi_clk_src / divider;

DIRECT_GO:
	if (new_pclk == fb_dev->dpi_clock) {
		/* Do nothing */
		pr_warn("new pclk is the same as current pclk\n");
		return count;
	}

	ret = sprdfb_chg_clk_intf(fb_dev, SPRDFB_DYNAMIC_PCLK, new_pclk);
	if (ret) {
		pr_err("%s: failed to change dpi clock. ret=%d\n",
				__func__, ret);
		return ret;
	}
	attr_info->curr_pclk = new_pclk;

	return count;
}
コード例 #4
0
ファイル: sprdfb_main.c プロジェクト: ShinySide/SM-G361H
static int sprdfb_ioctl(struct fb_info *info, unsigned int cmd,
			unsigned long arg)
{
	int result = -1;
	struct sprdfb_device *dev = NULL;
#ifdef CONFIG_FB_LCD_OVERLAY_SUPPORT
	overlay_info local_overlay_info;
	overlay_display local_overlay_display;
#endif
	int power_mode;
	void __user *argp = (void __user *)arg;

	if(NULL == info){
		printk(KERN_ERR "sprdfb: sprdfb_ioctl error. (Invalid Parameter)");
		return -1;
	}

	dev = info->par;

	switch(cmd){
#ifdef CONFIG_FB_LCD_OVERLAY_SUPPORT
	case SPRD_FB_SET_OVERLAY:
		pr_debug(KERN_INFO "sprdfb: [%s]: SPRD_FB_SET_OVERLAY\n", __FUNCTION__);
		memset(&local_overlay_info,0,sizeof(local_overlay_info));
		if (copy_from_user(&local_overlay_info, argp, sizeof(local_overlay_info))){
			printk("sprdfb: SET_OVERLAY copy failed!\n");
			return -EFAULT;
		}
		if(NULL != dev->ctrl->enable_overlay){
			result = dev->ctrl->enable_overlay(dev, &local_overlay_info, 1);
		}
		break;
	case SPRD_FB_DISPLAY_OVERLAY:
		pr_debug(KERN_INFO "sprdfb: [%s]: SPRD_FB_DISPLAY_OVERLAY\n", __FUNCTION__);
		memset(&local_overlay_display,0,sizeof(local_overlay_display));
		if (copy_from_user(&local_overlay_display, argp, sizeof(local_overlay_display))){
			printk("sprdfb: DISPLAY_OVERLAY copy failed!\n");
			return -EFAULT;
		}
		if(NULL != dev->ctrl->display_overlay){
			result = dev->ctrl->display_overlay(dev, &local_overlay_display);
		}
		break;
#endif
#ifdef CONFIG_FB_VSYNC_SUPPORT
	case FBIO_WAITFORVSYNC:
		pr_debug(KERN_INFO "sprdfb: [%s]: FBIO_WAITFORVSYNC\n", __FUNCTION__);
		if(NULL != dev->ctrl->wait_for_vsync){
			result = dev->ctrl->wait_for_vsync(dev);
		}
		break;
#endif

#ifdef CONFIG_FB_DYNAMIC_FREQ_SCALING
	case SPRD_FB_CHANGE_FPS:
		{
			int fps;
			result = copy_from_user(&fps, argp, sizeof(fps));
			if (result) {
				pr_err("%s: copy_from_user failed", __func__);
				return result;
			}
			pr_info("%s: fps will be changed to %d via ioctl\n",
					__func__, fps);
			result = sprdfb_chg_clk_intf(dev,
					SPRDFB_DYNAMIC_FPS, fps);
			if (result) {
				pr_err("%s: fps is set fail. fps=%d, ret=%d\n",
						__func__, fps, result);
				return result;
			}
			break;
		}
#endif

	case SPRD_FB_IS_REFRESH_DONE:
		pr_debug(KERN_INFO "sprdfb: [%s]: SPRD_FB_IS_REFRESH_DONE\n", __FUNCTION__);
		if(NULL != dev->ctrl->is_refresh_done){
			result = dev->ctrl->is_refresh_done(dev);
		}
		break;

	case SPRD_FB_SET_POWER_MODE:
		result = copy_from_user(&power_mode, argp, sizeof(power_mode));
		printk("sprdfb: [%s] : SPRD_FB_SET_POWER_MODE (%d)\n", __FUNCTION__, power_mode);
		break;

	default:
		printk(KERN_INFO "sprdfb: [%s]: unknown cmd(%d)\n", __FUNCTION__, cmd);
		break;
	}

	pr_debug(KERN_INFO "sprdfb: [%s]: return %d\n",__FUNCTION__, result);
	return result;
}