31 #include <linux/module.h>
32 #include <linux/kernel.h>
33 #include <linux/errno.h>
34 #include <linux/string.h>
38 #include <linux/types.h>
40 #include <linux/device.h>
48 #include <asm/dma-mapping.h>
59 #define DMA_BUS_SIZE 16
60 #define LCD_CLK (12*1000*1000)
62 #define CLOCKS_PER_PIX 3
70 #define H_ACTPIX (LCD_X_RES * CLOCKS_PER_PIX)
71 #define H_PERIOD (408 * CLOCKS_PER_PIX)
75 #define V_LINES (LCD_Y_RES + U_LINE)
76 #define V_PULSE (3 * H_PERIOD)
77 #define V_PERIOD (H_PERIOD * V_LINES)
79 #define ACTIVE_VIDEO_MEM_OFFSET (U_LINE * H_ACTPIX)
81 #define BFIN_LCD_NBR_PALETTE_ENTRIES 256
83 #define DRIVER_NAME "bfin-t350mcqb"
101 #define PPI_TX_MODE 0x2
102 #define PPI_XFER_TYPE_11 0xC
103 #define PPI_PORT_CFG_01 0x10
104 #define PPI_PACK_EN 0x80
105 #define PPI_POLS_1 0x8000
120 static inline void bfin_t350mcqb_disable_ppi(
void)
125 static inline void bfin_t350mcqb_enable_ppi(
void)
130 static void bfin_t350mcqb_start_timers(
void)
140 static void bfin_t350mcqb_stop_timers(
void)
150 static void bfin_t350mcqb_init_timers(
void)
153 bfin_t350mcqb_stop_timers();
191 static int bfin_t350mcqb_request_ports(
int action)
208 spin_lock(&fbi->
lock);
213 bfin_t350mcqb_disable_ppi();
216 bfin_t350mcqb_config_dma(fbi);
217 bfin_t350mcqb_config_ppi(fbi);
218 bfin_t350mcqb_init_timers();
222 bfin_t350mcqb_enable_ppi();
223 bfin_t350mcqb_start_timers();
226 spin_unlock(&fbi->
lock);
231 static int bfin_t350mcqb_fb_release(
struct fb_info *info,
int user)
235 spin_lock(&fbi->
lock);
240 bfin_t350mcqb_disable_ppi();
243 bfin_t350mcqb_stop_timers();
246 spin_unlock(&fbi->
lock);
258 var->
green.offset = 8;
259 var->
blue.offset = 16;
260 var->
red.length = var->
green.length = var->
blue.length = 8;
263 var->
transp.msb_right = 0;
264 var->
red.msb_right = 0;
265 var->
green.msb_right = 0;
266 var->
blue.msb_right = 0;
269 pr_debug(
"%s: depth not supported: %u BPP\n", __func__,
277 pr_debug(
"%s: Resolution not supported: X%u x Y%u \n",
287 pr_debug(
"%s: Memory Limit requested yres_virtual = %u\n",
310 if (info->
var.grayscale) {
312 red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
322 red >>= (16 - info->
var.red.length);
323 green >>= (16 - info->
var.green.length);
324 blue >>= (16 - info->
var.blue.length);
326 value = (red << info->
var.red.offset) |
327 (green << info->
var.green.offset) |
328 (blue << info->
var.blue.offset);
338 static struct fb_ops bfin_t350mcqb_fb_ops = {
340 .fb_open = bfin_t350mcqb_fb_open,
341 .fb_release = bfin_t350mcqb_fb_release,
342 .fb_check_var = bfin_t350mcqb_fb_check_var,
347 .fb_setcolreg = bfin_t350mcqb_fb_setcolreg,
350 #ifndef NO_BL_SUPPORT
367 static int bfin_lcd_set_power(
struct lcd_device *
dev,
int power)
385 if (!fi || (fi == &bfin_t350mcqb_fb))
390 static struct lcd_ops bfin_lcd_ops = {
392 .set_power = bfin_lcd_set_power,
393 .get_contrast = bfin_lcd_get_contrast,
394 .set_contrast = bfin_lcd_set_contrast,
395 .check_fb = bfin_lcd_check_fb,
409 bfin_t350mcqb_disable_ppi();
414 bfin_t350mcqb_enable_ppi();
423 #ifndef NO_BL_SUPPORT
435 ": couldn't request CH_PPI DMA\n");
452 platform_set_drvdata(pdev, fbinfo);
457 fbinfo->
fix.type_aux = 0;
458 fbinfo->
fix.xpanstep = 0;
459 fbinfo->
fix.ypanstep = 0;
460 fbinfo->
fix.ywrapstep = 0;
464 fbinfo->
var.nonstd = 0;
466 fbinfo->
var.height = 53;
467 fbinfo->
var.width = 70;
468 fbinfo->
var.accel_flags = 0;
477 fbinfo->
var.red.offset = 0;
478 fbinfo->
var.green.offset = 8;
479 fbinfo->
var.blue.offset = 16;
480 fbinfo->
var.transp.offset = 0;
481 fbinfo->
var.red.length = 8;
482 fbinfo->
var.green.length = 8;
483 fbinfo->
var.blue.length = 8;
484 fbinfo->
var.transp.length = 0;
487 fbinfo->
fix.line_length = fbinfo->
var.xres_virtual *
488 fbinfo->
var.bits_per_pixel / 8;
491 fbinfo->
fbops = &bfin_t350mcqb_fb_ops;
500 ": couldn't allocate dma buffer.\n");
508 fbinfo->
fbops = &bfin_t350mcqb_fb_ops;
515 "Fail to allocate colormap (%d entries)\n",
521 if (bfin_t350mcqb_request_ports(1)) {
537 ": unable to request PPI ERROR IRQ\n");
543 ": unable to register framebuffer.\n");
547 #ifndef NO_BL_SUPPORT
550 props.max_brightness = 255;
552 &bfin_lq043fb_bl_ops, &props);
553 if (IS_ERR(bl_dev)) {
555 ": unable to register backlight.\n");
570 bfin_t350mcqb_request_ports(0);
581 platform_set_drvdata(pdev,
NULL);
589 struct fb_info *fbinfo = platform_get_drvdata(pdev);
604 #ifndef NO_BL_SUPPORT
609 bfin_t350mcqb_request_ports(0);
611 platform_set_drvdata(pdev,
NULL);
622 struct fb_info *fbinfo = platform_get_drvdata(pdev);
626 bfin_t350mcqb_disable_ppi();
628 bfin_t350mcqb_stop_timers();
638 struct fb_info *fbinfo = platform_get_drvdata(pdev);
642 bfin_t350mcqb_config_dma(fbi);
643 bfin_t350mcqb_config_ppi(fbi);
644 bfin_t350mcqb_init_timers();
648 bfin_t350mcqb_enable_ppi();
649 bfin_t350mcqb_start_timers();
655 #define bfin_t350mcqb_suspend NULL
656 #define bfin_t350mcqb_resume NULL
660 .probe = bfin_t350mcqb_probe,
670 static int __init bfin_t350mcqb_driver_init(
void)
675 static void __exit bfin_t350mcqb_driver_cleanup(
void)