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/slab.h>
22 #include <linux/vmalloc.h>
23 #include <linux/delay.h>
24 #include <linux/interrupt.h>
26 #include <linux/init.h>
27 #include <linux/platform_device.h>
32 static u32 colreg
[16];
34 static struct fb_var_screeninfo rgbfb_var __initdata
= {
37 .xres_virtual
= LCD_X_RES
,
38 .yres_virtual
= LCD_Y_RES
,
50 .vmode
= FB_VMODE_NONINTERLACED
,
52 static struct fb_fix_screeninfo rgbfb_fix __initdata
= {
54 .line_length
= LCD_X_RES
* LCD_BBP
,
55 .type
= FB_TYPE_PACKED_PIXELS
,
56 .visual
= FB_VISUAL_TRUECOLOR
,
60 .accel
= FB_ACCEL_NONE
,
63 static int channel_owned
;
65 static int no_cursor(struct fb_info
*info
, struct fb_cursor
*cursor
)
70 static int rgbfb_setcolreg(u_int regno
, u_int red
, u_int green
, u_int blue
,
71 u_int transp
, struct fb_info
*info
)
76 colreg
[regno
] = ((red
& 0xff00) << 8) | (green
& 0xff00) |
77 ((blue
& 0xff00) >> 8);
81 static int rgbfb_mmap(struct fb_info
*info
, struct vm_area_struct
*vma
)
83 return pnx4008_sdum_mmap(info
, vma
, NULL
);
86 static struct fb_ops rgbfb_ops
= {
87 .fb_mmap
= rgbfb_mmap
,
88 .fb_setcolreg
= rgbfb_setcolreg
,
89 .fb_fillrect
= cfb_fillrect
,
90 .fb_copyarea
= cfb_copyarea
,
91 .fb_imageblit
= cfb_imageblit
,
94 static int rgbfb_remove(struct platform_device
*pdev
)
96 struct fb_info
*info
= platform_get_drvdata(pdev
);
99 unregister_framebuffer(info
);
100 fb_dealloc_cmap(&info
->cmap
);
101 framebuffer_release(info
);
102 platform_set_drvdata(pdev
, NULL
);
105 pnx4008_free_dum_channel(channel_owned
, pdev
->id
);
106 pnx4008_set_dum_exit_notification(pdev
->id
);
111 static int __devinit
rgbfb_probe(struct platform_device
*pdev
)
113 struct fb_info
*info
;
114 struct dumchannel_uf chan_uf
;
118 info
= framebuffer_alloc(sizeof(u32
) * 16, &pdev
->dev
);
124 pnx4008_get_fb_addresses(FB_TYPE_RGB
, (void **)&info
->screen_base
,
125 (dma_addr_t
*) &rgbfb_fix
.smem_start
,
126 &rgbfb_fix
.smem_len
);
128 if ((ret
= pnx4008_alloc_dum_channel(pdev
->id
)) < 0)
132 chan_uf
.channelnr
= channel_owned
;
133 chan_uf
.dirty
= (u32
*) NULL
;
134 chan_uf
.source
= (u32
*) rgbfb_fix
.smem_start
;
135 chan_uf
.x_offset
= 0;
136 chan_uf
.y_offset
= 0;
137 chan_uf
.width
= LCD_X_RES
;
138 chan_uf
.height
= LCD_Y_RES
;
140 if ((ret
= pnx4008_put_dum_channel_uf(chan_uf
, pdev
->id
))< 0)
144 pnx4008_set_dum_channel_sync(channel_owned
, CONF_SYNC_ON
,
149 pnx4008_set_dum_channel_dirty_detect(channel_owned
,
150 CONF_DIRTYDETECTION_ON
,
155 if (!fb_get_options("pnxrgbfb", &option
) && option
&&
156 !strcmp(option
, "nocursor"))
157 rgbfb_ops
.fb_cursor
= no_cursor
;
160 info
->flags
= FBINFO_FLAG_DEFAULT
;
161 info
->fbops
= &rgbfb_ops
;
162 info
->fix
= rgbfb_fix
;
163 info
->var
= rgbfb_var
;
164 info
->screen_size
= rgbfb_fix
.smem_len
;
165 info
->pseudo_palette
= info
->par
;
168 ret
= fb_alloc_cmap(&info
->cmap
, 256, 0);
172 ret
= register_framebuffer(info
);
175 platform_set_drvdata(pdev
, info
);
180 fb_dealloc_cmap(&info
->cmap
);
182 pnx4008_free_dum_channel(channel_owned
, pdev
->id
);
184 framebuffer_release(info
);
189 static struct platform_driver rgbfb_driver
= {
191 .name
= "pnx4008-rgbfb",
193 .probe
= rgbfb_probe
,
194 .remove
= rgbfb_remove
,
197 static int __init
rgbfb_init(void)
199 return platform_driver_register(&rgbfb_driver
);
202 static void __exit
rgbfb_exit(void)
204 platform_driver_unregister(&rgbfb_driver
);
207 module_init(rgbfb_init
);
208 module_exit(rgbfb_exit
);
210 MODULE_LICENSE("GPL");