root/drivers/video/fbdev/pmag-aa-fb.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. aafb_cursor
  2. aafb_blank
  3. pmagaafb_probe
  4. pmagaafb_remove
  5. pmagaafb_init
  6. pmagaafb_exit

   1 /*
   2  *      linux/drivers/video/pmag-aa-fb.c
   3  *      Copyright 2002 Karsten Merker <merker@debian.org>
   4  *
   5  *      PMAG-AA TurboChannel framebuffer card support ... derived from
   6  *      pmag-ba-fb.c, which is Copyright (C) 1999, 2000, 2001 by
   7  *      Michael Engel <engel@unix-ag.org>, Karsten Merker <merker@debian.org>
   8  *      and Harald Koerfgen <hkoerfg@web.de>, which itself is derived from
   9  *      "HP300 Topcat framebuffer support (derived from macfb of all things)
  10  *      Phil Blundell <philb@gnu.org> 1998"
  11  *      Copyright (c) 2016  Maciej W. Rozycki
  12  *
  13  *      This file is subject to the terms and conditions of the GNU General
  14  *      Public License.  See the file COPYING in the main directory of this
  15  *      archive for more details.
  16  *
  17  *      2002-09-28  Karsten Merker <merker@linuxtag.org>
  18  *              Version 0.01: First try to get a PMAG-AA running.
  19  *
  20  *      2003-02-24  Thiemo Seufer  <seufer@csv.ica.uni-stuttgart.de>
  21  *              Version 0.02: Major code cleanup.
  22  *
  23  *      2003-09-21  Thiemo Seufer  <seufer@csv.ica.uni-stuttgart.de>
  24  *              Hardware cursor support.
  25  *
  26  *      2016-02-21  Maciej W. Rozycki  <macro@linux-mips.org>
  27  *              Version 0.03: Rewritten for the new FB and TC APIs.
  28  */
  29 
  30 #include <linux/compiler.h>
  31 #include <linux/errno.h>
  32 #include <linux/fb.h>
  33 #include <linux/init.h>
  34 #include <linux/io.h>
  35 #include <linux/kernel.h>
  36 #include <linux/module.h>
  37 #include <linux/tc.h>
  38 #include <linux/timer.h>
  39 
  40 #include "bt455.h"
  41 #include "bt431.h"
  42 
  43 /* Version information */
  44 #define DRIVER_VERSION "0.03"
  45 #define DRIVER_AUTHOR "Karsten Merker <merker@linuxtag.org>"
  46 #define DRIVER_DESCRIPTION "PMAG-AA Framebuffer Driver"
  47 
  48 /*
  49  * Bt455 RAM DAC register base offset (rel. to TC slot base address).
  50  */
  51 #define PMAG_AA_BT455_OFFSET            0x100000
  52 
  53 /*
  54  * Bt431 cursor generator offset (rel. to TC slot base address).
  55  */
  56 #define PMAG_AA_BT431_OFFSET            0x180000
  57 
  58 /*
  59  * Begin of PMAG-AA framebuffer memory relative to TC slot address,
  60  * resolution is 1280x1024x1 (8 bits deep, but only LSB is used).
  61  */
  62 #define PMAG_AA_ONBOARD_FBMEM_OFFSET    0x200000
  63 
  64 struct aafb_par {
  65         void __iomem *mmio;
  66         struct bt455_regs __iomem *bt455;
  67         struct bt431_regs __iomem *bt431;
  68 };
  69 
  70 static const struct fb_var_screeninfo aafb_defined = {
  71         .xres           = 1280,
  72         .yres           = 1024,
  73         .xres_virtual   = 2048,
  74         .yres_virtual   = 1024,
  75         .bits_per_pixel = 8,
  76         .grayscale      = 1,
  77         .red.length     = 0,
  78         .green.length   = 1,
  79         .blue.length    = 0,
  80         .activate       = FB_ACTIVATE_NOW,
  81         .accel_flags    = FB_ACCEL_NONE,
  82         .pixclock       = 7645,
  83         .left_margin    = 224,
  84         .right_margin   = 32,
  85         .upper_margin   = 33,
  86         .lower_margin   = 3,
  87         .hsync_len      = 160,
  88         .vsync_len      = 3,
  89         .sync           = FB_SYNC_ON_GREEN,
  90         .vmode          = FB_VMODE_NONINTERLACED,
  91 };
  92 
  93 static const struct fb_fix_screeninfo aafb_fix = {
  94         .id             = "PMAG-AA",
  95         .smem_len       = (2048 * 1024),
  96         .type           = FB_TYPE_PACKED_PIXELS,
  97         .visual         = FB_VISUAL_MONO10,
  98         .ypanstep       = 1,
  99         .ywrapstep      = 1,
 100         .line_length    = 2048,
 101         .mmio_len       = PMAG_AA_ONBOARD_FBMEM_OFFSET - PMAG_AA_BT455_OFFSET,
 102 };
 103 
 104 static int aafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
 105 {
 106         struct aafb_par *par = info->par;
 107 
 108         if (cursor->image.height > BT431_CURSOR_SIZE ||
 109             cursor->image.width > BT431_CURSOR_SIZE) {
 110                 bt431_erase_cursor(par->bt431);
 111                 return -EINVAL;
 112         }
 113 
 114         if (!cursor->enable)
 115                 bt431_erase_cursor(par->bt431);
 116 
 117         if (cursor->set & FB_CUR_SETPOS)
 118                 bt431_position_cursor(par->bt431,
 119                                       cursor->image.dx, cursor->image.dy);
 120         if (cursor->set & FB_CUR_SETCMAP) {
 121                 u8 fg = cursor->image.fg_color ? 0xf : 0x0;
 122                 u8 bg = cursor->image.bg_color ? 0xf : 0x0;
 123 
 124                 bt455_write_cmap_entry(par->bt455, 8, bg);
 125                 bt455_write_cmap_next(par->bt455, bg);
 126                 bt455_write_ovly_next(par->bt455, fg);
 127         }
 128         if (cursor->set & (FB_CUR_SETSIZE | FB_CUR_SETSHAPE | FB_CUR_SETIMAGE))
 129                 bt431_set_cursor(par->bt431,
 130                                  cursor->image.data, cursor->mask, cursor->rop,
 131                                  cursor->image.width, cursor->image.height);
 132 
 133         if (cursor->enable)
 134                 bt431_enable_cursor(par->bt431);
 135 
 136         return 0;
 137 }
 138 
 139 /* 0 unblanks, any other blanks. */
 140 
 141 static int aafb_blank(int blank, struct fb_info *info)
 142 {
 143         struct aafb_par *par = info->par;
 144         u8 val = blank ? 0x00 : 0x0f;
 145 
 146         bt455_write_cmap_entry(par->bt455, 1, val);
 147         return 0;
 148 }
 149 
 150 static struct fb_ops aafb_ops = {
 151         .owner          = THIS_MODULE,
 152         .fb_blank       = aafb_blank,
 153         .fb_fillrect    = cfb_fillrect,
 154         .fb_copyarea    = cfb_copyarea,
 155         .fb_imageblit   = cfb_imageblit,
 156         .fb_cursor      = aafb_cursor,
 157 };
 158 
 159 static int pmagaafb_probe(struct device *dev)
 160 {
 161         struct tc_dev *tdev = to_tc_dev(dev);
 162         resource_size_t start, len;
 163         struct fb_info *info;
 164         struct aafb_par *par;
 165         int err;
 166 
 167         info = framebuffer_alloc(sizeof(struct aafb_par), dev);
 168         if (!info)
 169                 return -ENOMEM;
 170 
 171         par = info->par;
 172         dev_set_drvdata(dev, info);
 173 
 174         info->fbops = &aafb_ops;
 175         info->fix = aafb_fix;
 176         info->var = aafb_defined;
 177         info->flags = FBINFO_DEFAULT;
 178 
 179         /* Request the I/O MEM resource. */
 180         start = tdev->resource.start;
 181         len = tdev->resource.end - start + 1;
 182         if (!request_mem_region(start, len, dev_name(dev))) {
 183                 printk(KERN_ERR "%s: Cannot reserve FB region\n",
 184                        dev_name(dev));
 185                 err = -EBUSY;
 186                 goto err_alloc;
 187         }
 188 
 189         /* MMIO mapping setup. */
 190         info->fix.mmio_start = start + PMAG_AA_BT455_OFFSET;
 191         par->mmio = ioremap_nocache(info->fix.mmio_start, info->fix.mmio_len);
 192         if (!par->mmio) {
 193                 printk(KERN_ERR "%s: Cannot map MMIO\n", dev_name(dev));
 194                 err = -ENOMEM;
 195                 goto err_resource;
 196         }
 197         par->bt455 = par->mmio - PMAG_AA_BT455_OFFSET + PMAG_AA_BT455_OFFSET;
 198         par->bt431 = par->mmio - PMAG_AA_BT455_OFFSET + PMAG_AA_BT431_OFFSET;
 199 
 200         /* Frame buffer mapping setup. */
 201         info->fix.smem_start = start + PMAG_AA_ONBOARD_FBMEM_OFFSET;
 202         info->screen_base = ioremap_nocache(info->fix.smem_start,
 203                                             info->fix.smem_len);
 204         if (!info->screen_base) {
 205                 printk(KERN_ERR "%s: Cannot map FB\n", dev_name(dev));
 206                 err = -ENOMEM;
 207                 goto err_mmio_map;
 208         }
 209         info->screen_size = info->fix.smem_len;
 210 
 211         /* Init colormap. */
 212         bt455_write_cmap_entry(par->bt455, 0, 0x0);
 213         bt455_write_cmap_next(par->bt455, 0xf);
 214 
 215         /* Init hardware cursor. */
 216         bt431_erase_cursor(par->bt431);
 217         bt431_init_cursor(par->bt431);
 218 
 219         err = register_framebuffer(info);
 220         if (err < 0) {
 221                 printk(KERN_ERR "%s: Cannot register framebuffer\n",
 222                        dev_name(dev));
 223                 goto err_smem_map;
 224         }
 225 
 226         get_device(dev);
 227 
 228         pr_info("fb%d: %s frame buffer device at %s\n",
 229                 info->node, info->fix.id, dev_name(dev));
 230 
 231         return 0;
 232 
 233 
 234 err_smem_map:
 235         iounmap(info->screen_base);
 236 
 237 err_mmio_map:
 238         iounmap(par->mmio);
 239 
 240 err_resource:
 241         release_mem_region(start, len);
 242 
 243 err_alloc:
 244         framebuffer_release(info);
 245         return err;
 246 }
 247 
 248 static int pmagaafb_remove(struct device *dev)
 249 {
 250         struct tc_dev *tdev = to_tc_dev(dev);
 251         struct fb_info *info = dev_get_drvdata(dev);
 252         struct aafb_par *par = info->par;
 253         resource_size_t start, len;
 254 
 255         put_device(dev);
 256         unregister_framebuffer(info);
 257         iounmap(info->screen_base);
 258         iounmap(par->mmio);
 259         start = tdev->resource.start;
 260         len = tdev->resource.end - start + 1;
 261         release_mem_region(start, len);
 262         framebuffer_release(info);
 263         return 0;
 264 }
 265 
 266 /*
 267  * Initialise the framebuffer.
 268  */
 269 static const struct tc_device_id pmagaafb_tc_table[] = {
 270         { "DEC     ", "PMAG-AA " },
 271         { }
 272 };
 273 MODULE_DEVICE_TABLE(tc, pmagaafb_tc_table);
 274 
 275 static struct tc_driver pmagaafb_driver = {
 276         .id_table       = pmagaafb_tc_table,
 277         .driver         = {
 278                 .name   = "pmagaafb",
 279                 .bus    = &tc_bus_type,
 280                 .probe  = pmagaafb_probe,
 281                 .remove = pmagaafb_remove,
 282         },
 283 };
 284 
 285 static int __init pmagaafb_init(void)
 286 {
 287 #ifndef MODULE
 288         if (fb_get_options("pmagaafb", NULL))
 289                 return -ENXIO;
 290 #endif
 291         return tc_register_driver(&pmagaafb_driver);
 292 }
 293 
 294 static void __exit pmagaafb_exit(void)
 295 {
 296         tc_unregister_driver(&pmagaafb_driver);
 297 }
 298 
 299 module_init(pmagaafb_init);
 300 module_exit(pmagaafb_exit);
 301 
 302 MODULE_AUTHOR(DRIVER_AUTHOR);
 303 MODULE_DESCRIPTION(DRIVER_DESCRIPTION);
 304 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */