source: rtems/c/src/lib/libbsp/i386/pc386/console/fb_vga.c @ 311ba73

4.115
Last change on this file since 311ba73 was 311ba73, checked in by Sebastian Huber <sebastian.huber@…>, on 06/23/13 at 15:50:55

framebuffer: Add and use FRAMEBUFFER_DEVICE_0_NAME

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