Blame view
drivers/video/pmag-ba-fb.c
6.54 KB
1da177e4c Linux-2.6.12-rc2 |
1 |
/* |
af690a948 [PATCH] DEC PMAG ... |
2 |
* linux/drivers/video/pmag-ba-fb.c |
1da177e4c Linux-2.6.12-rc2 |
3 |
* |
af690a948 [PATCH] DEC PMAG ... |
4 5 |
* PMAG-BA TURBOchannel Color Frame Buffer (CFB) card support, * derived from: |
1da177e4c Linux-2.6.12-rc2 |
6 7 |
* "HP300 Topcat framebuffer support (derived from macfb of all things) * Phil Blundell <philb@gnu.org> 1998", the original code can be |
af690a948 [PATCH] DEC PMAG ... |
8 |
* found in the file hpfb.c in the same directory. |
1da177e4c Linux-2.6.12-rc2 |
9 10 11 12 13 |
* * Based on digital document: * "PMAG-BA TURBOchannel Color Frame Buffer * Functional Specification", Revision 1.2, August 27, 1990 * |
af690a948 [PATCH] DEC PMAG ... |
14 15 16 |
* DECstation related code Copyright (C) 1999, 2000, 2001 by * Michael Engel <engel@unix-ag.org>, * Karsten Merker <merker@linuxtag.org> and |
1da177e4c Linux-2.6.12-rc2 |
17 |
* Harald Koerfgen. |
335dc50ce [TC] mips: pmag-b... |
18 19 |
* Copyright (c) 2005, 2006 Maciej W. Rozycki * Copyright (c) 2005 James Simmons |
1da177e4c Linux-2.6.12-rc2 |
20 |
* |
af690a948 [PATCH] DEC PMAG ... |
21 22 23 |
* This file is subject to the terms and conditions of the GNU General * Public License. See the file COPYING in the main directory of this * archive for more details. |
1da177e4c Linux-2.6.12-rc2 |
24 |
*/ |
af690a948 [PATCH] DEC PMAG ... |
25 26 |
#include <linux/compiler.h> |
1da177e4c Linux-2.6.12-rc2 |
27 |
#include <linux/errno.h> |
1da177e4c Linux-2.6.12-rc2 |
28 |
#include <linux/fb.h> |
af690a948 [PATCH] DEC PMAG ... |
29 30 31 |
#include <linux/init.h> #include <linux/kernel.h> #include <linux/module.h> |
335dc50ce [TC] mips: pmag-b... |
32 |
#include <linux/tc.h> |
af690a948 [PATCH] DEC PMAG ... |
33 |
#include <linux/types.h> |
af690a948 [PATCH] DEC PMAG ... |
34 35 |
#include <asm/io.h> #include <asm/system.h> |
1da177e4c Linux-2.6.12-rc2 |
36 |
#include <video/pmag-ba-fb.h> |
af690a948 [PATCH] DEC PMAG ... |
37 38 |
struct pmagbafb_par { |
af690a948 [PATCH] DEC PMAG ... |
39 40 |
volatile void __iomem *mmio; volatile u32 __iomem *dac; |
1da177e4c Linux-2.6.12-rc2 |
41 |
}; |
1da177e4c Linux-2.6.12-rc2 |
42 |
|
9625b5135 VIDEO: PMAG-BA: F... |
43 |
static struct fb_var_screeninfo pmagbafb_defined __devinitdata = { |
1da177e4c Linux-2.6.12-rc2 |
44 45 46 47 48 49 50 51 52 |
.xres = 1024, .yres = 864, .xres_virtual = 1024, .yres_virtual = 864, .bits_per_pixel = 8, .red.length = 8, .green.length = 8, .blue.length = 8, .activate = FB_ACTIVATE_NOW, |
af690a948 [PATCH] DEC PMAG ... |
53 54 55 56 57 58 59 60 61 62 63 |
.height = -1, .width = -1, .accel_flags = FB_ACCEL_NONE, .pixclock = 14452, .left_margin = 116, .right_margin = 12, .upper_margin = 34, .lower_margin = 12, .hsync_len = 128, .vsync_len = 3, .sync = FB_SYNC_ON_GREEN, |
1da177e4c Linux-2.6.12-rc2 |
64 65 |
.vmode = FB_VMODE_NONINTERLACED, }; |
9625b5135 VIDEO: PMAG-BA: F... |
66 |
static struct fb_fix_screeninfo pmagbafb_fix __devinitdata = { |
1da177e4c Linux-2.6.12-rc2 |
67 |
.id = "PMAG-BA", |
af690a948 [PATCH] DEC PMAG ... |
68 |
.smem_len = (1024 * 1024), |
1da177e4c Linux-2.6.12-rc2 |
69 70 71 |
.type = FB_TYPE_PACKED_PIXELS, .visual = FB_VISUAL_PSEUDOCOLOR, .line_length = 1024, |
af690a948 [PATCH] DEC PMAG ... |
72 |
.mmio_len = PMAG_BA_SIZE - PMAG_BA_BT459, |
1da177e4c Linux-2.6.12-rc2 |
73 |
}; |
af690a948 [PATCH] DEC PMAG ... |
74 75 |
static inline void dac_write(struct pmagbafb_par *par, unsigned int reg, u8 v) |
1da177e4c Linux-2.6.12-rc2 |
76 |
{ |
af690a948 [PATCH] DEC PMAG ... |
77 |
writeb(v, par->dac + reg / 4); |
1da177e4c Linux-2.6.12-rc2 |
78 |
} |
af690a948 [PATCH] DEC PMAG ... |
79 80 81 82 |
static inline u8 dac_read(struct pmagbafb_par *par, unsigned int reg) { return readb(par->dac + reg / 4); } |
1da177e4c Linux-2.6.12-rc2 |
83 |
/* |
af690a948 [PATCH] DEC PMAG ... |
84 |
* Set the palette. |
1da177e4c Linux-2.6.12-rc2 |
85 |
*/ |
af690a948 [PATCH] DEC PMAG ... |
86 87 88 |
static int pmagbafb_setcolreg(unsigned int regno, unsigned int red, unsigned int green, unsigned int blue, unsigned int transp, struct fb_info *info) |
1da177e4c Linux-2.6.12-rc2 |
89 |
{ |
af690a948 [PATCH] DEC PMAG ... |
90 |
struct pmagbafb_par *par = info->par; |
1da177e4c Linux-2.6.12-rc2 |
91 |
|
2f390380c fbdev: add palett... |
92 93 |
if (regno >= info->cmap.len) return 1; |
1da177e4c Linux-2.6.12-rc2 |
94 95 |
red >>= 8; /* The cmap fields are 16 bits */ |
af690a948 [PATCH] DEC PMAG ... |
96 |
green >>= 8; /* wide, but the hardware colormap */ |
1da177e4c Linux-2.6.12-rc2 |
97 |
blue >>= 8; /* registers are only 8 bits wide */ |
af690a948 [PATCH] DEC PMAG ... |
98 99 100 101 102 103 104 105 106 |
mb(); dac_write(par, BT459_ADDR_LO, regno); dac_write(par, BT459_ADDR_HI, 0x00); wmb(); dac_write(par, BT459_CMAP, red); wmb(); dac_write(par, BT459_CMAP, green); wmb(); dac_write(par, BT459_CMAP, blue); |
1da177e4c Linux-2.6.12-rc2 |
107 108 109 110 111 |
return 0; } static struct fb_ops pmagbafb_ops = { .owner = THIS_MODULE, |
1da177e4c Linux-2.6.12-rc2 |
112 113 114 115 |
.fb_setcolreg = pmagbafb_setcolreg, .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, |
1da177e4c Linux-2.6.12-rc2 |
116 |
}; |
af690a948 [PATCH] DEC PMAG ... |
117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
/* * Turn the hardware cursor off. */ static void __init pmagbafb_erase_cursor(struct fb_info *info) { struct pmagbafb_par *par = info->par; mb(); dac_write(par, BT459_ADDR_LO, 0x00); dac_write(par, BT459_ADDR_HI, 0x03); wmb(); dac_write(par, BT459_DATA, 0x00); } |
9625b5135 VIDEO: PMAG-BA: F... |
131 |
static int __devinit pmagbafb_probe(struct device *dev) |
1da177e4c Linux-2.6.12-rc2 |
132 |
{ |
335dc50ce [TC] mips: pmag-b... |
133 134 |
struct tc_dev *tdev = to_tc_dev(dev); resource_size_t start, len; |
af690a948 [PATCH] DEC PMAG ... |
135 136 |
struct fb_info *info; struct pmagbafb_par *par; |
53ee1b5bb drivers/video/pma... |
137 |
int err; |
af690a948 [PATCH] DEC PMAG ... |
138 |
|
335dc50ce [TC] mips: pmag-b... |
139 |
info = framebuffer_alloc(sizeof(struct pmagbafb_par), dev); |
53ee1b5bb drivers/video/pma... |
140 |
if (!info) { |
7ad33e748 video: struct dev... |
141 142 |
printk(KERN_ERR "%s: Cannot allocate memory ", dev_name(dev)); |
af690a948 [PATCH] DEC PMAG ... |
143 |
return -ENOMEM; |
53ee1b5bb drivers/video/pma... |
144 |
} |
af690a948 [PATCH] DEC PMAG ... |
145 146 |
par = info->par; |
335dc50ce [TC] mips: pmag-b... |
147 |
dev_set_drvdata(dev, info); |
af690a948 [PATCH] DEC PMAG ... |
148 |
|
53ee1b5bb drivers/video/pma... |
149 150 151 |
if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) { printk(KERN_ERR "%s: Cannot allocate color map ", |
7ad33e748 video: struct dev... |
152 |
dev_name(dev)); |
53ee1b5bb drivers/video/pma... |
153 |
err = -ENOMEM; |
af690a948 [PATCH] DEC PMAG ... |
154 |
goto err_alloc; |
53ee1b5bb drivers/video/pma... |
155 |
} |
af690a948 [PATCH] DEC PMAG ... |
156 |
|
1da177e4c Linux-2.6.12-rc2 |
157 |
info->fbops = &pmagbafb_ops; |
af690a948 [PATCH] DEC PMAG ... |
158 |
info->fix = pmagbafb_fix; |
1da177e4c Linux-2.6.12-rc2 |
159 |
info->var = pmagbafb_defined; |
1da177e4c Linux-2.6.12-rc2 |
160 |
info->flags = FBINFO_DEFAULT; |
335dc50ce [TC] mips: pmag-b... |
161 162 163 |
/* Request the I/O MEM resource. */ start = tdev->resource.start; len = tdev->resource.end - start + 1; |
7ad33e748 video: struct dev... |
164 165 166 167 |
if (!request_mem_region(start, len, dev_name(dev))) { printk(KERN_ERR "%s: Cannot reserve FB region ", dev_name(dev)); |
53ee1b5bb drivers/video/pma... |
168 |
err = -EBUSY; |
335dc50ce [TC] mips: pmag-b... |
169 |
goto err_cmap; |
53ee1b5bb drivers/video/pma... |
170 |
} |
335dc50ce [TC] mips: pmag-b... |
171 |
|
af690a948 [PATCH] DEC PMAG ... |
172 |
/* MMIO mapping setup. */ |
335dc50ce [TC] mips: pmag-b... |
173 |
info->fix.mmio_start = start; |
af690a948 [PATCH] DEC PMAG ... |
174 |
par->mmio = ioremap_nocache(info->fix.mmio_start, info->fix.mmio_len); |
53ee1b5bb drivers/video/pma... |
175 |
if (!par->mmio) { |
7ad33e748 video: struct dev... |
176 177 |
printk(KERN_ERR "%s: Cannot map MMIO ", dev_name(dev)); |
53ee1b5bb drivers/video/pma... |
178 |
err = -ENOMEM; |
335dc50ce [TC] mips: pmag-b... |
179 |
goto err_resource; |
53ee1b5bb drivers/video/pma... |
180 |
} |
af690a948 [PATCH] DEC PMAG ... |
181 182 183 |
par->dac = par->mmio + PMAG_BA_BT459; /* Frame buffer mapping setup. */ |
335dc50ce [TC] mips: pmag-b... |
184 |
info->fix.smem_start = start + PMAG_BA_FBMEM; |
af690a948 [PATCH] DEC PMAG ... |
185 186 |
info->screen_base = ioremap_nocache(info->fix.smem_start, info->fix.smem_len); |
53ee1b5bb drivers/video/pma... |
187 |
if (!info->screen_base) { |
7ad33e748 video: struct dev... |
188 189 |
printk(KERN_ERR "%s: Cannot map FB ", dev_name(dev)); |
53ee1b5bb drivers/video/pma... |
190 |
err = -ENOMEM; |
af690a948 [PATCH] DEC PMAG ... |
191 |
goto err_mmio_map; |
53ee1b5bb drivers/video/pma... |
192 |
} |
af690a948 [PATCH] DEC PMAG ... |
193 194 195 |
info->screen_size = info->fix.smem_len; pmagbafb_erase_cursor(info); |
1da177e4c Linux-2.6.12-rc2 |
196 |
|
53ee1b5bb drivers/video/pma... |
197 198 199 200 |
err = register_framebuffer(info); if (err < 0) { printk(KERN_ERR "%s: Cannot register framebuffer ", |
7ad33e748 video: struct dev... |
201 |
dev_name(dev)); |
af690a948 [PATCH] DEC PMAG ... |
202 |
goto err_smem_map; |
53ee1b5bb drivers/video/pma... |
203 |
} |
af690a948 [PATCH] DEC PMAG ... |
204 |
|
335dc50ce [TC] mips: pmag-b... |
205 206 207 208 |
get_device(dev); pr_info("fb%d: %s frame buffer device at %s ", |
7ad33e748 video: struct dev... |
209 |
info->node, info->fix.id, dev_name(dev)); |
af690a948 [PATCH] DEC PMAG ... |
210 |
|
1da177e4c Linux-2.6.12-rc2 |
211 |
return 0; |
af690a948 [PATCH] DEC PMAG ... |
212 213 214 215 216 217 218 |
err_smem_map: iounmap(info->screen_base); err_mmio_map: iounmap(par->mmio); |
335dc50ce [TC] mips: pmag-b... |
219 220 |
err_resource: release_mem_region(start, len); |
af690a948 [PATCH] DEC PMAG ... |
221 222 223 224 |
err_cmap: fb_dealloc_cmap(&info->cmap); err_alloc: |
af690a948 [PATCH] DEC PMAG ... |
225 |
framebuffer_release(info); |
53ee1b5bb drivers/video/pma... |
226 |
return err; |
1da177e4c Linux-2.6.12-rc2 |
227 |
} |
335dc50ce [TC] mips: pmag-b... |
228 |
static int __exit pmagbafb_remove(struct device *dev) |
af690a948 [PATCH] DEC PMAG ... |
229 |
{ |
335dc50ce [TC] mips: pmag-b... |
230 231 |
struct tc_dev *tdev = to_tc_dev(dev); struct fb_info *info = dev_get_drvdata(dev); |
af690a948 [PATCH] DEC PMAG ... |
232 |
struct pmagbafb_par *par = info->par; |
335dc50ce [TC] mips: pmag-b... |
233 |
resource_size_t start, len; |
1da177e4c Linux-2.6.12-rc2 |
234 |
|
335dc50ce [TC] mips: pmag-b... |
235 |
put_device(dev); |
af690a948 [PATCH] DEC PMAG ... |
236 237 238 |
unregister_framebuffer(info); iounmap(info->screen_base); iounmap(par->mmio); |
335dc50ce [TC] mips: pmag-b... |
239 240 241 |
start = tdev->resource.start; len = tdev->resource.end - start + 1; release_mem_region(start, len); |
af690a948 [PATCH] DEC PMAG ... |
242 |
fb_dealloc_cmap(&info->cmap); |
af690a948 [PATCH] DEC PMAG ... |
243 |
framebuffer_release(info); |
335dc50ce [TC] mips: pmag-b... |
244 |
return 0; |
af690a948 [PATCH] DEC PMAG ... |
245 246 247 248 |
} /* |
335dc50ce [TC] mips: pmag-b... |
249 |
* Initialize the framebuffer. |
af690a948 [PATCH] DEC PMAG ... |
250 |
*/ |
335dc50ce [TC] mips: pmag-b... |
251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 |
static const struct tc_device_id pmagbafb_tc_table[] = { { "DEC ", "PMAG-BA " }, { } }; MODULE_DEVICE_TABLE(tc, pmagbafb_tc_table); static struct tc_driver pmagbafb_driver = { .id_table = pmagbafb_tc_table, .driver = { .name = "pmagbafb", .bus = &tc_bus_type, .probe = pmagbafb_probe, .remove = __exit_p(pmagbafb_remove), }, }; |
af690a948 [PATCH] DEC PMAG ... |
266 |
static int __init pmagbafb_init(void) |
1da177e4c Linux-2.6.12-rc2 |
267 |
{ |
335dc50ce [TC] mips: pmag-b... |
268 |
#ifndef MODULE |
1da177e4c Linux-2.6.12-rc2 |
269 |
if (fb_get_options("pmagbafb", NULL)) |
af690a948 [PATCH] DEC PMAG ... |
270 |
return -ENXIO; |
335dc50ce [TC] mips: pmag-b... |
271 272 |
#endif return tc_register_driver(&pmagbafb_driver); |
1da177e4c Linux-2.6.12-rc2 |
273 |
} |
af690a948 [PATCH] DEC PMAG ... |
274 275 |
static void __exit pmagbafb_exit(void) { |
335dc50ce [TC] mips: pmag-b... |
276 |
tc_unregister_driver(&pmagbafb_driver); |
af690a948 [PATCH] DEC PMAG ... |
277 |
} |
1da177e4c Linux-2.6.12-rc2 |
278 |
module_init(pmagbafb_init); |
af690a948 [PATCH] DEC PMAG ... |
279 |
module_exit(pmagbafb_exit); |
1da177e4c Linux-2.6.12-rc2 |
280 |
MODULE_LICENSE("GPL"); |