static struct fb_videomode *vga_find_best_mode(void)
{
	int res = -1,i;
	struct fb_videomode *mode = NULL, *best = NULL;

	res = vga_parse_edid();
    for(i = 0; i < 2 && res != 0; i++) {
	    mdelay(30);
	    res = vga_parse_edid();
    }
    
	if (res == 0) {
		mode = vga_find_max_mode();
		if (mode) {
			 vga_set_modelist();
			 best = (struct fb_videomode *)fb_find_nearest_mode(mode, &ddev->modelist);
		}
	} else {
	    vga_set_default_modelist();
		printk("vga-ddc: read and parse edid failed errno:%d.\n", res);
	}
	

	return best;
}
Exemplo n.º 2
0
static const struct fb_videomode *atmel_lcdfb_choose_mode(struct fb_var_screeninfo *var,
						     struct fb_info *info)
{
	struct fb_videomode varfbmode;
	const struct fb_videomode *fbmode = NULL;

	fb_var_to_videomode(&varfbmode, var);
	fbmode = fb_find_nearest_mode(&varfbmode, &info->modelist);
	if (fbmode)
		fb_videomode_to_var(var, fbmode);
	return fbmode;
}
Exemplo n.º 3
0
static int tegra_fb_set_par(struct fb_info *info)
{
	struct tegra_fb_info *tegra_fb = info->par;
	struct fb_var_screeninfo *var = &info->var;
	struct tegra_dc *dc = tegra_fb->win->dc;

	if (var->bits_per_pixel) {
		/* we only support RGB ordering for now */
		switch (var->bits_per_pixel) {
		case 32:
			var->red.offset = 0;
			var->red.length = 8;
			var->green.offset = 8;
			var->green.length = 8;
			var->blue.offset = 16;
			var->blue.length = 8;
			var->transp.offset = 24;
			var->transp.length = 8;
			tegra_fb->win->fmt = TEGRA_WIN_FMT_R8G8B8A8;
			break;
		case 16:
			var->red.offset = 11;
			var->red.length = 5;
			var->green.offset = 5;
			var->green.length = 6;
			var->blue.offset = 0;
			var->blue.length = 5;
			tegra_fb->win->fmt = TEGRA_WIN_FMT_B5G6R5;
			break;

		default:
			return -EINVAL;
		}
		/* if line_length unset, then pad the stride */
		if (!info->fix.line_length) {
			info->fix.line_length = var->xres * var->bits_per_pixel
				/ 8;
			info->fix.line_length = round_up(info->fix.line_length,
						TEGRA_LINEAR_PITCH_ALIGNMENT);
		}
		tegra_fb->win->stride = info->fix.line_length;
		tegra_fb->win->stride_uv = 0;
		tegra_fb->win->phys_addr_u = 0;
		tegra_fb->win->phys_addr_v = 0;
	}

	if (var->pixclock) {
		bool stereo;
		unsigned old_len = 0;
		struct fb_videomode m;
		struct fb_videomode *old_mode = NULL;

		fb_var_to_videomode(&m, var);

		/* Load framebuffer info with new mode details*/
		old_mode = info->mode;
		old_len  = info->fix.line_length;

		info->mode = (struct fb_videomode *)
			fb_find_nearest_mode(&m, &info->modelist);
		if (!info->mode) {
			dev_warn(&tegra_fb->ndev->dev, "can't match video mode\n");
			info->mode = old_mode;
			return -EINVAL;
		}

		/* Update fix line_length and window stride as per new mode */
		info->fix.line_length = var->xres * var->bits_per_pixel / 8;
		info->fix.line_length = round_up(info->fix.line_length,
			TEGRA_LINEAR_PITCH_ALIGNMENT);
		tegra_fb->win->stride = info->fix.line_length;

		/*
		 * only enable stereo if the mode supports it and
		 * client requests it
		 */
		stereo = !!(var->vmode & info->mode->vmode &
#ifndef CONFIG_TEGRA_HDMI_74MHZ_LIMIT
					FB_VMODE_STEREO_FRAME_PACK);
#else
					FB_VMODE_STEREO_LEFT_RIGHT);
#endif

		/* Configure DC with new mode */
		if (tegra_dc_set_fb_mode(dc, info->mode, stereo)) {
			/* Error while configuring DC, fallback to old mode */
			dev_warn(&tegra_fb->ndev->dev, "can't configure dc with mode %ux%u\n",
				info->mode->xres, info->mode->yres);
			info->mode = old_mode;
			info->fix.line_length = old_len;
			tegra_fb->win->stride = old_len;
			return -EINVAL;
		}

		tegra_fb->win->w.full = dfixed_const(info->mode->xres);
		tegra_fb->win->h.full = dfixed_const(info->mode->yres);
		tegra_fb->win->out_w = info->mode->xres;
		tegra_fb->win->out_h = info->mode->yres;
	}
Exemplo n.º 4
0
static int tegra_fb_set_par(struct fb_info *info)
{
	struct tegra_fb_info *tegra_fb = info->par;
	struct fb_var_screeninfo *var = &info->var;

	if (var->bits_per_pixel) {
		/* we only support RGB ordering for now */
		switch (var->bits_per_pixel) {
		case 32:
			var->red.offset = 0;
			var->red.length = 8;
			var->green.offset = 8;
			var->green.length = 8;
			var->blue.offset = 16;
			var->blue.length = 8;
			var->transp.offset = 24;
			var->transp.length = 8;
			tegra_fb->win->fmt = TEGRA_WIN_FMT_R8G8B8A8;
			break;
		case 16:
			var->red.offset = 11;
			var->red.length = 5;
			var->green.offset = 5;
			var->green.length = 6;
			var->blue.offset = 0;
			var->blue.length = 5;
			tegra_fb->win->fmt = TEGRA_WIN_FMT_B5G6R5;
			break;

		default:
			return -EINVAL;
		}
		/* if line_length unset, then pad the stride */
		if (!info->fix.line_length) {
			info->fix.line_length = var->xres * var->bits_per_pixel
				/ 8;
			info->fix.line_length = round_up(info->fix.line_length,
						TEGRA_LINEAR_PITCH_ALIGNMENT);
		}
		tegra_fb->win->stride = info->fix.line_length;
		tegra_fb->win->stride_uv = 0;
		tegra_fb->win->phys_addr_u = 0;
		tegra_fb->win->phys_addr_v = 0;
	}

	if (var->pixclock) {
		bool stereo;
		struct fb_videomode m;

		fb_var_to_videomode(&m, var);

		info->mode = (struct fb_videomode *)
			fb_find_nearest_mode(&m, &info->modelist);
		if (!info->mode) {
			dev_warn(&tegra_fb->ndev->dev, "can't match video mode\n");
			return -EINVAL;
		}

		/*
		 * only enable stereo if the mode supports it and
		 * client requests it
		 */
		stereo = !!(var->vmode & info->mode->vmode &
#ifndef CONFIG_TEGRA_HDMI_74MHZ_LIMIT
					FB_VMODE_STEREO_FRAME_PACK);
#else
					FB_VMODE_STEREO_LEFT_RIGHT);
#endif

		tegra_dc_set_fb_mode(tegra_fb->win->dc, info->mode, stereo);

		tegra_fb->win->w.full = dfixed_const(info->mode->xres);
		tegra_fb->win->h.full = dfixed_const(info->mode->yres);
		tegra_fb->win->out_w = info->mode->xres;
		tegra_fb->win->out_h = info->mode->yres;
	}
Exemplo n.º 5
0
static void det_worker(struct work_struct *work)
{
	BYTE HPD, HPDChange ;
	char event_string[16];
	char *envp[] = { event_string, NULL };

	CheckHDMITX(&HPD, &HPDChange);
	if (HPDChange) {
		/* cable connection changes */
		if (HPD) {
			ite661x.cable_plugin = 1;
			sprintf(event_string, "EVENT=plugin");

			/* make sure fb is powerdown */
			acquire_console_sem();
			fb_blank(ite661x.fbi, FB_BLANK_POWERDOWN);
			release_console_sem();

			if (ite661x_read_edid(ite661x.fbi) < 0)
				dev_err(&ite661x.client->dev,
					"ite661x: read edid fail\n");
			else {
				ParseEDID(ite661x.edid + 128);
				if (ite661x.fbi->monspecs.modedb_len > 0) {
					int i;
					const struct fb_videomode *mode;
					struct fb_videomode m;

					fb_destroy_modelist(&ite661x.fbi->modelist);

					for (i = 0; i < ite661x.fbi->monspecs.modedb_len; i++) {
						/*FIXME now we do not support interlaced mode */
						if (!(ite661x.fbi->monspecs.modedb[i].vmode & FB_VMODE_INTERLACED))
							fb_add_videomode(&ite661x.fbi->monspecs.modedb[i],
									&ite661x.fbi->modelist);
					}

					fb_var_to_videomode(&m, &ite661x.fbi->var);
					mode = fb_find_nearest_mode(&m,
							&ite661x.fbi->modelist);

					fb_videomode_to_var(&ite661x.fbi->var, mode);

					ite661x.fbi->var.activate |= FB_ACTIVATE_FORCE;
					acquire_console_sem();
					ite661x.fbi->flags |= FBINFO_MISC_USEREVENT;
					fb_set_var(ite661x.fbi, &ite661x.fbi->var);
					ite661x.fbi->flags &= ~FBINFO_MISC_USEREVENT;
					release_console_sem();
				}

				acquire_console_sem();
				fb_blank(ite661x.fbi, FB_BLANK_UNBLANK);
				release_console_sem();
				HDMITX_SetOutput();
			}
		} else {
			ite661x.cable_plugin = 0;
			sprintf(event_string, "EVENT=plugout");
			acquire_console_sem();
			fb_blank(ite661x.fbi, FB_BLANK_POWERDOWN);
			release_console_sem();
			DisableAudioOutput();
			DisableVideoOutput();
		}
		kobject_uevent_env(&ite661x.pdev->dev.kobj, KOBJ_CHANGE, envp);
	}
	enable_irq(ite661x.client->irq);
}
static void det_worker(struct work_struct *work)
{
	int dat;
	char event_string[16];
	char *envp[] = { event_string, NULL };

	dev_dbg(&sii902x.pdev->dev, "%s\n", __func__);

	dat = i2c_smbus_read_byte_data(sii902x.client, 0x3D);
	if (dat & 0x1) {
		/* cable connection changes */
		if (dat & 0x4) {
			sii902x.cable_plugin = 1;
			dev_dbg(&sii902x.pdev->dev, "EVENT=plugin\n");
			sprintf(event_string, "EVENT=plugin");

			if (sii902x_read_edid(sii902x.fbi) < 0)
				dev_err(&sii902x.client->dev,
					"Sii902x: read edid fail\n");
			else {
				if (sii902x.fbi->monspecs.modedb_len > 0) {

					int i;
					const struct fb_videomode *mode;
					struct fb_videomode m;

					fb_destroy_modelist(&sii902x.fbi->modelist);

					for (i = 0; i < sii902x.fbi->monspecs.modedb_len; i++) {
						/*FIXME now we do not support interlaced mode */
						mode = &sii902x.fbi->monspecs.modedb[i];

						if (!(mode->vmode & FB_VMODE_INTERLACED)) {

							dev_dbg(&sii902x.pdev->dev, "Added mode %d:", i);
							dev_dbg(&sii902x.pdev->dev,
								"xres = %d, yres = %d, freq = %d, vmode = %d, flag = %d\n",
								mode->xres, mode->yres, mode->refresh,
								mode->vmode, mode->flag);

							fb_add_videomode(mode, &sii902x.fbi->modelist);
						}
					}

					fb_var_to_videomode(&m, &sii902x.fbi->var);
					dump_fb_videomode(&m);

					mode = fb_find_nearest_mode(&m,
							&sii902x.fbi->modelist);

					fb_videomode_to_var(&sii902x.fbi->var, mode);

					sii902x.fbi->var.activate |= FB_ACTIVATE_FORCE;
					console_lock();
					sii902x.fbi->flags |= FBINFO_MISC_USEREVENT;
					fb_set_var(sii902x.fbi, &sii902x.fbi->var);
					sii902x.fbi->flags &= ~FBINFO_MISC_USEREVENT;
					console_unlock();
				}
				/* Power on sii902x */
				sii902x_poweron();
			}
		} else {
			sii902x.cable_plugin = 0;
			dev_dbg(&sii902x.pdev->dev, "EVENT=plugout\n");
			sprintf(event_string, "EVENT=plugout");
			/* Power off sii902x */
			sii902x_poweroff();
		}
		kobject_uevent_env(&sii902x.pdev->dev.kobj, KOBJ_CHANGE, envp);
	}
	i2c_smbus_write_byte_data(sii902x.client, 0x3D, dat);

	dev_dbg(&sii902x.pdev->dev, "exit %s\n", __func__);

}
Exemplo n.º 7
0
static int mxc_elcdif_fb_probe(struct platform_device *pdev)
{
	int ret = 0;
	struct mxc_elcdif_fb_data *data;
	struct resource *res;
	struct fb_info *fbi;
	struct mxc_fb_platform_data *pdata = pdev->dev.platform_data;
	const struct fb_videomode *mode;
	struct fb_videomode m;
	int num;

	fbi = framebuffer_alloc(sizeof(struct mxc_elcdif_fb_data), &pdev->dev);
	if (fbi == NULL) {
		ret = -ENOMEM;
		goto out;
	}

	data = (struct mxc_elcdif_fb_data *)fbi->par;
	data->cur_blank = data->next_blank = FB_BLANK_UNBLANK;

	fbi->var.activate = FB_ACTIVATE_NOW;
	fbi->fbops = &mxc_elcdif_fb_ops;
	fbi->flags = FBINFO_FLAG_DEFAULT;
	fbi->pseudo_palette = data->pseudo_palette;

	ret = fb_alloc_cmap(&fbi->cmap, 16, 0);
	if (ret)
		goto out;

	g_elcdif_dev = &pdev->dev;

	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (res == NULL) {
		dev_err(&pdev->dev, "cannot get IRQ resource\n");
		ret = -ENODEV;
		goto err0;
	}
	data->dma_irq = res->start;

	ret = request_irq(data->dma_irq, lcd_irq_handler, 0,
			  "mxc_elcdif_fb", data);
	if (ret) {
		dev_err(&pdev->dev, "request_irq (%d) failed with error %d\n",
				data->dma_irq, ret);
		goto err0;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (res == NULL) {
		ret = -ENODEV;
		goto err1;
	}
	elcdif_base = ioremap(res->start, SZ_4K);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	if (res) {
		fbi->fix.smem_len = res->end - res->start + 1;
		fbi->fix.smem_start = res->start;
		fbi->screen_base = ioremap(fbi->fix.smem_start,
					   fbi->fix.smem_len);
	}

	strcpy(fbi->fix.id, "mxc_elcdif_fb");

	fbi->var.xres = 800;
	fbi->var.yres = 480;

	if (pdata && !data->output_pix_fmt)
		data->output_pix_fmt = pdata->interface_pix_fmt;

	INIT_LIST_HEAD(&fbi->modelist);

	if (pdata && pdata->mode && pdata->num_modes)
		fb_videomode_to_modelist(pdata->mode, pdata->num_modes,
				&fbi->modelist);

	if (mxc_disp_mode.num_modes) {
		int i;
		mode = mxc_disp_mode.mode;
		num = mxc_disp_mode.num_modes;

		for (i = 0; i < num; i++) {
			/*
			 * FIXME now we do not support interlaced
			 * mode for ddc mode
			 */
			if ((mxc_disp_mode.dev_mode
				& MXC_DISP_DDC_DEV) &&
				(mode[i].vmode & FB_VMODE_INTERLACED))
				continue;
			else {
				dev_dbg(&pdev->dev, "Added mode %d:", i);
				dev_dbg(&pdev->dev,
					"xres = %d, yres = %d, freq = %d, vmode = %d, flag = %d\n",
					mode[i].xres, mode[i].yres,	mode[i].refresh, mode[i].vmode,
					mode[i].flag);
				fb_add_videomode(&mode[i], &fbi->modelist);
			}
		}
	}

	if (!fb_mode && pdata && pdata->mode_str)
		fb_mode = pdata->mode_str;

	if (fb_mode) {
		dev_dbg(&pdev->dev, "default video mode %s\n", fb_mode);
		ret = fb_find_mode(&fbi->var, fbi, fb_mode, NULL, 0, NULL,
				   default_bpp);
		if ((ret == 1) || (ret == 2)) {
			fb_var_to_videomode(&m, &fbi->var);
			dump_fb_videomode(&m);
			mode = fb_find_nearest_mode(&m,
				&fbi->modelist);
			fb_videomode_to_var(&fbi->var, mode);
		} else if (pdata && pdata->mode && pdata->num_modes) {
			ret = fb_find_mode(&fbi->var, fbi, fb_mode, pdata->mode,
					pdata->num_modes, NULL, default_bpp);
			if (!ret) {
				dev_err(fbi->device,
					"No valid video mode found");
				goto err2;
			}
		} else {
			dev_err(fbi->device,
				"No valid video mode found");
			goto err2;
		}
	}

	mxc_elcdif_fb_check_var(&fbi->var, fbi);

	fbi->var.xres_virtual = fbi->var.xres;
	fbi->var.yres_virtual = fbi->var.yres * 3;

	mxc_elcdif_fb_set_fix(fbi);

	if (!res || !res->end)
		if (mxc_elcdif_fb_map_video_memory(fbi) < 0) {
			ret = -ENOMEM;
			goto err2;
		}

	g_elcdif_axi_clk = clk_get(g_elcdif_dev, "elcdif_axi");
	if (g_elcdif_axi_clk == NULL) {
		dev_err(&pdev->dev, "can't get ELCDIF axi clk\n");
		ret = -ENODEV;
		goto err3;
	}
	g_elcdif_pix_clk = clk_get(g_elcdif_dev, "elcdif_pix");
	if (g_elcdif_pix_clk == NULL) {
		dev_err(&pdev->dev, "can't get ELCDIF pix clk\n");
		ret = -ENODEV;
		goto err3;
	}
	/*
	 * Set an appropriate pixel clk rate first, so that we can
	 * access ELCDIF registers.
	 */
	clk_set_rate(g_elcdif_pix_clk, 25000000);

	fbi->var.activate |= FB_ACTIVATE_FORCE;
	console_lock();
	fbi->flags |= FBINFO_MISC_USEREVENT;
	ret = fb_set_var(fbi, &fbi->var);
	fbi->flags &= ~FBINFO_MISC_USEREVENT;
	console_unlock();

	if (data->cur_blank == FB_BLANK_UNBLANK) {
		console_lock();
		fb_blank(fbi, FB_BLANK_UNBLANK);
		console_unlock();
	}

	ret = register_framebuffer(fbi);
	if (ret)
		goto err3;

	platform_set_drvdata(pdev, fbi);

	return 0;
err3:
	mxc_elcdif_fb_unmap_video_memory(fbi);
err2:
	iounmap(elcdif_base);
err1:
	free_irq(data->dma_irq, data);
err0:
	fb_dealloc_cmap(&fbi->cmap);
	framebuffer_release(fbi);
out:
	return ret;
}