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__); }
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; }