2 * drivers/video/pnx4008/pnxrgbfb.c
4 * PNX4008's framebuffer support
6 * Author: Grigory Tolstolytkin <gtolstolytkin@ru.mvista.com>
7 * Based on Philips Semiconductors's code
9 * Copyrght (c) 2005 MontaVista Software, Inc.
10 * Copyright (c) 2005 Philips Semiconductors
11 * This file is licensed under the terms of the GNU General Public License
12 * version 2. This program is licensed "as is" without any warranty of any
13 * kind, whether express or implied.
16 #include <linux/module.h>
17 #include <linux/kernel.h>
18 #include <linux/errno.h>
19 #include <linux/string.h>
21 #include <linux/vmalloc.h>
22 #include <linux/delay.h>
23 #include <linux/interrupt.h>
25 #include <linux/init.h>
26 #include <linux/platform_device.h>
31 static u32 colreg
[16];
33 static struct fb_var_screeninfo rgbfb_var __initdata
= {
36 .xres_virtual
= LCD_X_RES
,
37 .yres_virtual
= LCD_Y_RES
,
49 .vmode
= FB_VMODE_NONINTERLACED
,
51 static struct fb_fix_screeninfo rgbfb_fix __initdata
= {
53 .line_length
= LCD_X_RES
* LCD_BBP
,
54 .type
= FB_TYPE_PACKED_PIXELS
,
55 .visual
= FB_VISUAL_TRUECOLOR
,
59 .accel
= FB_ACCEL_NONE
,
62 static int channel_owned
;
64 static int no_cursor(struct fb_info
*info
, struct fb_cursor
*cursor
)
69 static int rgbfb_setcolreg(u_int regno
, u_int red
, u_int green
, u_int blue
,
70 u_int transp
, struct fb_info
*info
)
75 colreg
[regno
] = ((red
& 0xff00) << 8) | (green
& 0xff00) |
76 ((blue
& 0xff00) >> 8);
80 static int rgbfb_mmap(struct fb_info
*info
, struct vm_area_struct
*vma
)
82 return pnx4008_sdum_mmap(info
, vma
, NULL
);
85 static struct fb_ops rgbfb_ops
= {
86 .fb_mmap
= rgbfb_mmap
,
87 .fb_setcolreg
= rgbfb_setcolreg
,
88 .fb_fillrect
= cfb_fillrect
,
89 .fb_copyarea
= cfb_copyarea
,
90 .fb_imageblit
= cfb_imageblit
,
93 static int rgbfb_remove(struct platform_device
*pdev
)
95 struct fb_info
*info
= platform_get_drvdata(pdev
);
98 unregister_framebuffer(info
);
99 fb_dealloc_cmap(&info
->cmap
);
100 framebuffer_release(info
);
101 platform_set_drvdata(pdev
, NULL
);
104 pnx4008_free_dum_channel(channel_owned
, pdev
->id
);
105 pnx4008_set_dum_exit_notification(pdev
->id
);
110 static int __devinit
rgbfb_probe(struct platform_device
*pdev
)
112 struct fb_info
*info
;
113 struct dumchannel_uf chan_uf
;
117 info
= framebuffer_alloc(sizeof(u32
) * 16, &pdev
->dev
);
123 pnx4008_get_fb_addresses(FB_TYPE_RGB
, (void **)&info
->screen_base
,
124 (dma_addr_t
*) &rgbfb_fix
.smem_start
,
125 &rgbfb_fix
.smem_len
);
127 if ((ret
= pnx4008_alloc_dum_channel(pdev
->id
)) < 0)
131 chan_uf
.channelnr
= channel_owned
;
132 chan_uf
.dirty
= (u32
*) NULL
;
133 chan_uf
.source
= (u32
*) rgbfb_fix
.smem_start
;
134 chan_uf
.x_offset
= 0;
135 chan_uf
.y_offset
= 0;
136 chan_uf
.width
= LCD_X_RES
;
137 chan_uf
.height
= LCD_Y_RES
;
139 if ((ret
= pnx4008_put_dum_channel_uf(chan_uf
, pdev
->id
))< 0)
143 pnx4008_set_dum_channel_sync(channel_owned
, CONF_SYNC_ON
,
148 pnx4008_set_dum_channel_dirty_detect(channel_owned
,
149 CONF_DIRTYDETECTION_ON
,
154 if (!fb_get_options("pnxrgbfb", &option
) && option
&&
155 !strcmp(option
, "nocursor"))
156 rgbfb_ops
.fb_cursor
= no_cursor
;
159 info
->flags
= FBINFO_FLAG_DEFAULT
;
160 info
->fbops
= &rgbfb_ops
;
161 info
->fix
= rgbfb_fix
;
162 info
->var
= rgbfb_var
;
163 info
->screen_size
= rgbfb_fix
.smem_len
;
164 info
->pseudo_palette
= info
->par
;
167 ret
= fb_alloc_cmap(&info
->cmap
, 256, 0);
171 ret
= register_framebuffer(info
);
174 platform_set_drvdata(pdev
, info
);
179 fb_dealloc_cmap(&info
->cmap
);
181 pnx4008_free_dum_channel(channel_owned
, pdev
->id
);
183 framebuffer_release(info
);
188 static struct platform_driver rgbfb_driver
= {
190 .name
= "pnx4008-rgbfb",
192 .probe
= rgbfb_probe
,
193 .remove
= rgbfb_remove
,
196 static int __init
rgbfb_init(void)
198 return platform_driver_register(&rgbfb_driver
);
201 static void __exit
rgbfb_exit(void)
203 platform_driver_unregister(&rgbfb_driver
);
206 module_init(rgbfb_init
);
207 module_exit(rgbfb_exit
);
209 MODULE_LICENSE("GPL");