source: rtems/c/src/lib/libbsp/i386/pc386/console/fb_vga.c @ 98db96e

4.115
Last change on this file since 98db96e was 61af4b0b, checked in by Ralf Corsépius <ralf.corsepius@…>, on 10/15/12 at 04:00:20

Include <rtems/framebuffer.h>.

  • Property mode set to 100644
File size: 6.7 KB
Line 
1/*
2 * Copyright (c) 2000 - Rosimildo da Silva ( rdasilva@connecttel.com )
3 *
4 * MODULE DESCRIPTION:
5 * This module implements FB driver for "Bare VGA". It uses the
6 * routines for "bare hardware" found in vgainit.c.
7 *
8 */
9
10#include <stdlib.h>
11#include <stdio.h>
12#include <errno.h>
13#include <sys/types.h>
14#include <pthread.h>
15
16#include <bsp.h>
17#include <bsp/irq.h>
18#include <rtems/libio.h>
19
20#include <rtems/fb.h>
21#include <rtems/framebuffer.h>
22
23/* these routines are defined in vgainit.c.*/
24extern void ega_hwinit( void );
25extern void ega_hwterm( void );
26
27/* mutex attribure */
28pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
29
30/* screen information for the VGA driver */
31static struct fb_var_screeninfo fb_var =
32{
33  .xres                = 640,
34  .yres                = 480,
35  .bits_per_pixel      = 4
36};
37
38static struct fb_fix_screeninfo fb_fix =
39{
40  .smem_start          = (volatile char *)0xA0000,     /* buffer pointer    */
41  .smem_len            = 0x10000,                      /* buffer size       */
42  .type                = FB_TYPE_VGA_PLANES,           /* type of dsplay    */
43  .visual              = FB_VISUAL_PSEUDOCOLOR,        /* color scheme used */
44  .line_length         = 80                            /* chars per line    */
45};
46
47
48static uint16_t red16[] = {
49   0x0000, 0x0000, 0x0000, 0x0000, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa,
50   0x5555, 0x5555, 0x5555, 0x5555, 0xffff, 0xffff, 0xffff, 0xffff
51};
52static uint16_t green16[] = {
53   0x0000, 0x0000, 0xaaaa, 0xaaaa, 0x0000, 0x0000, 0x5555, 0xaaaa,
54   0x5555, 0x5555, 0xffff, 0xffff, 0x5555, 0x5555, 0xffff, 0xffff
55};
56static uint16_t blue16[] = {
57   0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa,
58   0x5555, 0xffff, 0x5555, 0xffff, 0x5555, 0xffff, 0x5555, 0xffff
59};
60
61/* Functionality to support multiple VGA frame buffers can be added easily,
62 * but is not supported at this moment because there is no need for two or
63 * more "classic" VGA adapters.  Multiple frame buffer drivers may be
64 * implemented and If we had implement it they would be named as "/dev/fb0",
65 * "/dev/fb1", "/dev/fb2" and so on.
66 */
67/*
68 * fbvga device driver INITIALIZE entry point.
69 */
70rtems_device_driver frame_buffer_initialize(
71  rtems_device_major_number  major,
72  rtems_device_minor_number  minor,
73  void                      *arg
74)
75{
76  rtems_status_code status;
77
78  printk( "FBVGA -- driver initializing..\n" );
79
80  /*
81   * Register the device
82   */
83  status = rtems_io_register_name ("/dev/fb0", major, 0);
84  if (status != RTEMS_SUCCESSFUL) {
85    printk("Error registering /dev/fb0 FBVGA framebuffer device!\n");
86    rtems_fatal_error_occurred( status );
87  }
88
89  return RTEMS_SUCCESSFUL;
90}
91
92/*
93 * fbvga device driver OPEN entry point
94 */
95rtems_device_driver frame_buffer_open(
96  rtems_device_major_number  major,
97  rtems_device_minor_number  minor,
98  void                      *arg
99)
100{
101  if (pthread_mutex_trylock(&mutex)== 0){
102      /* restore previous state.  for VGA this means return to text mode.
103       * leave out if graphics hardware has been initialized in
104       * frame_buffer_initialize()
105       */
106      ega_hwinit();
107      printk( "FBVGA open called.\n" );
108      return RTEMS_SUCCESSFUL;
109  }
110
111  return RTEMS_UNSATISFIED;
112}
113
114/*
115 * fbvga device driver CLOSE entry point
116 */
117rtems_device_driver frame_buffer_close(
118  rtems_device_major_number  major,
119  rtems_device_minor_number  minor,
120  void                      *arg
121)
122{
123  if (pthread_mutex_unlock(&mutex) == 0){
124    /* restore previous state.  for VGA this means return to text mode.
125     * leave out if graphics hardware has been initialized in
126     * frame_buffer_initialize() */
127    ega_hwterm();
128    printk( "FBVGA close called.\n" );
129    return RTEMS_SUCCESSFUL;
130  }
131
132  return RTEMS_UNSATISFIED;
133}
134
135/*
136 * fbvga device driver READ entry point.
137 */
138rtems_device_driver frame_buffer_read(
139  rtems_device_major_number  major,
140  rtems_device_minor_number  minor,
141  void                      *arg
142)
143{
144  rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
145  rw_args->bytes_moved = ((rw_args->offset + rw_args->count) > fb_fix.smem_len ) ? (fb_fix.smem_len - rw_args->offset) : rw_args->count;
146  memcpy(rw_args->buffer, (const void *) (fb_fix.smem_start + rw_args->offset), rw_args->bytes_moved);
147  return RTEMS_SUCCESSFUL;
148}
149
150/*
151 * frame_buffer device driver WRITE entry point.
152 */
153rtems_device_driver frame_buffer_write(
154  rtems_device_major_number  major,
155  rtems_device_minor_number  minor,
156  void                      *arg
157)
158{
159  rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
160  rw_args->bytes_moved = ((rw_args->offset + rw_args->count) > fb_fix.smem_len ) ? (fb_fix.smem_len - rw_args->offset) : rw_args->count;
161  memcpy( (void *) (fb_fix.smem_start + rw_args->offset), rw_args->buffer, rw_args->bytes_moved);
162  return RTEMS_SUCCESSFUL;
163}
164
165static int get_fix_screen_info( struct fb_fix_screeninfo *info )
166{
167  *info = fb_fix;
168  return 0;
169}
170
171static int get_var_screen_info( struct fb_var_screeninfo *info )
172{
173  *info =  fb_var;
174  return 0;
175}
176
177static int get_palette( struct fb_cmap *cmap )
178{
179  uint32_t i;
180
181  if ( cmap->start + cmap->len >= 16 )
182    return 1;
183
184  for( i = 0; i < cmap->len; i++ ) {
185    cmap->red[ cmap->start + i ]   = red16[ cmap->start + i ];
186    cmap->green[ cmap->start + i ] = green16[ cmap->start + i ];
187    cmap->blue[ cmap->start + i ]  = blue16[ cmap->start + i ];
188  }
189  return 0;
190}
191
192static int set_palette( struct fb_cmap *cmap )
193{
194  uint32_t i;
195
196  if ( cmap->start + cmap->len >= 16 )
197    return 1;
198
199  for( i = 0; i < cmap->len; i++ ) {
200    red16[ cmap->start + i ] = cmap->red[ cmap->start + i ];
201    green16[ cmap->start + i ] = cmap->green[ cmap->start + i ];
202    blue16[ cmap->start + i ] = cmap->blue[ cmap->start + i ];
203  }
204  return 0;
205}
206
207/*
208 * IOCTL entry point -- This method is called to carry
209 * all services of this interface.
210 */
211rtems_device_driver frame_buffer_control(
212  rtems_device_major_number  major,
213  rtems_device_minor_number  minor,
214  void                      *arg
215)
216{
217  rtems_libio_ioctl_args_t *args = arg;
218
219  printk( "FBVGA ioctl called, cmd=%x\n", args->command  );
220
221  switch( args->command ) {
222    case FBIOGET_FSCREENINFO:
223      args->ioctl_return =  get_fix_screen_info( ( struct fb_fix_screeninfo * ) args->buffer );
224      break;
225    case FBIOGET_VSCREENINFO:
226      args->ioctl_return =  get_var_screen_info( ( struct fb_var_screeninfo * ) args->buffer );
227      break;
228    case FBIOPUT_VSCREENINFO:
229      /* not implemented yet*/
230      args->ioctl_return = -1;
231      return RTEMS_UNSATISFIED;
232    case FBIOGETCMAP:
233      args->ioctl_return =  get_palette( ( struct fb_cmap * ) args->buffer );
234      break;
235    case FBIOPUTCMAP:
236      args->ioctl_return =  set_palette( ( struct fb_cmap * ) args->buffer );
237      break;
238
239    default:
240     args->ioctl_return = 0;
241     break;
242  }
243  return RTEMS_SUCCESSFUL;
244}
Note: See TracBrowser for help on using the repository browser.