The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/hpc/bivideo.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: bivideo.c,v 1.28 2008/04/06 20:28:36 cegger Exp $      */
    2 
    3 /*-
    4  * Copyright (c) 1999-2001
    5  *         Shin Takemura and PocketBSD Project. All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  * 3. All advertising materials mentioning features or use of this software
   16  *    must display the following acknowledgement:
   17  *      This product includes software developed by the PocketBSD project
   18  *      and its contributors.
   19  * 4. Neither the name of the project nor the names of its contributors
   20  *    may be used to endorse or promote products derived from this software
   21  *    without specific prior written permission.
   22  *
   23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   33  * SUCH DAMAGE.
   34  *
   35  */
   36 
   37 #include <sys/cdefs.h>
   38 __KERNEL_RCSID(0, "$NetBSD: bivideo.c,v 1.28 2008/04/06 20:28:36 cegger Exp $");
   39 
   40 #ifdef _KERNEL_OPT
   41 #include "opt_hpcfb.h"
   42 #endif
   43 
   44 #include <sys/param.h>
   45 #include <sys/systm.h>
   46 #include <sys/device.h>
   47 #include <sys/buf.h>
   48 #include <sys/ioctl.h>
   49 #include <sys/reboot.h>
   50 
   51 #include <uvm/uvm_extern.h>
   52 
   53 #include <sys/bus.h>
   54 #include <machine/autoconf.h>
   55 #include <machine/bootinfo.h>
   56 #include <machine/config_hook.h>
   57 
   58 #include <dev/wscons/wsconsio.h>
   59 #include <dev/wscons/wsdisplayvar.h>
   60 
   61 #include <dev/rasops/rasops.h>
   62 
   63 #include <dev/hpc/hpcfbvar.h>
   64 #include <dev/hpc/hpcfbio.h>
   65 #include <dev/hpc/bivideovar.h>
   66 #include <dev/hpc/hpccmapvar.h>
   67 
   68 #ifdef FBDEBUG
   69 #define VPRINTF(arg)    do { if (bootverbose) printf arg; } while (0)
   70 #else
   71 #define VPRINTF(arg)    /* nothing */
   72 #endif
   73 
   74 /*
   75  *  global variables
   76  */
   77 int bivideo_dont_attach = 0;
   78 
   79 /*
   80  *  function prototypes
   81  */
   82 int     bivideomatch(struct device *, struct cfdata *, void *);
   83 void    bivideoattach(struct device *, struct device *, void *);
   84 int     bivideo_ioctl(void *, u_long, void *, int, struct lwp *);
   85 paddr_t bivideo_mmap(void *, off_t, int);
   86 
   87 struct bivideo_softc {
   88         struct device           sc_dev;
   89         struct hpcfb_fbconf     sc_fbconf;
   90         struct hpcfb_dspconf    sc_dspconf;
   91         void                    *sc_powerhook;  /* power management hook */
   92         int                     sc_powerstate;
   93 #define PWRSTAT_SUSPEND         (1<<0)
   94 #define PWRSTAT_VIDEOOFF        (1<<1)
   95 #define PWRSTAT_LCD             (1<<2)
   96 #define PWRSTAT_BACKLIGHT       (1<<3)
   97 #define PWRSTAT_ALL             (0xffffffff)
   98         int                     sc_lcd_inited;
   99 #define BACKLIGHT_INITED        (1<<0)
  100 #define BRIGHTNESS_INITED       (1<<1)
  101 #define CONTRAST_INITED         (1<<2)
  102         int                     sc_brightness;
  103         int                     sc_brightness_save;
  104         int                     sc_max_brightness;
  105         int                     sc_contrast;
  106         int                     sc_max_contrast;
  107 
  108 };
  109 
  110 static int bivideo_init(struct hpcfb_fbconf *);
  111 static void bivideo_power(int, void *);
  112 static void bivideo_update_powerstate(struct bivideo_softc *, int);
  113 void    bivideo_init_backlight(struct bivideo_softc *, int);
  114 void    bivideo_init_brightness(struct bivideo_softc *, int);
  115 void    bivideo_init_contrast(struct bivideo_softc *, int);
  116 void    bivideo_set_brightness(struct bivideo_softc *, int);
  117 void    bivideo_set_contrast(struct bivideo_softc *, int);
  118 
  119 #if defined __mips__ || defined __sh__ || defined __arm__
  120 #define __BTOP(x)               ((paddr_t)(x) >> PGSHIFT)
  121 #define __PTOB(x)               ((paddr_t)(x) << PGSHIFT)
  122 #else
  123 #error "define btop, ptob."
  124 #endif
  125 
  126 /*
  127  *  static variables
  128  */
  129 CFATTACH_DECL(bivideo, sizeof(struct bivideo_softc),
  130     bivideomatch, bivideoattach, NULL, NULL);
  131 
  132 struct hpcfb_accessops bivideo_ha = {
  133         bivideo_ioctl, bivideo_mmap
  134 };
  135 
  136 static int console_flag = 0;
  137 static int attach_flag = 0;
  138 
  139 /*
  140  *  function bodies
  141  */
  142 int
  143 bivideomatch(struct device *parent, struct cfdata *match, void *aux)
  144 {
  145         struct mainbus_attach_args *ma = aux;
  146 
  147         if (bivideo_dont_attach ||
  148             strcmp(ma->ma_name, match->cf_name))
  149                 return 0;
  150 
  151         return (1);
  152 }
  153 
  154 void
  155 bivideoattach(struct device *parent, struct device *self, void *aux)
  156 {
  157         struct bivideo_softc *sc = device_private(self);
  158         struct hpcfb_attach_args ha;
  159 
  160         if (attach_flag) {
  161                 panic("%s(%d): bivideo attached twice", __FILE__, __LINE__);
  162         }
  163         attach_flag = 1;
  164 
  165         printf(": ");
  166         if (bivideo_init(&sc->sc_fbconf) != 0) {
  167                 /* just return so that hpcfb will not be attached */
  168                 return;
  169         }
  170 
  171         printf("pseudo video controller");
  172         if (console_flag) {
  173                 printf(", console");
  174         }
  175         printf("\n");
  176         printf("%s: framebuffer address: 0x%08lx\n",
  177                 device_xname(&sc->sc_dev), (u_long)bootinfo->fb_addr);
  178 
  179         /* Add a suspend hook to power saving */
  180         sc->sc_powerstate = 0;
  181         sc->sc_powerhook = powerhook_establish(device_xname(&sc->sc_dev),
  182             bivideo_power, sc);
  183         if (sc->sc_powerhook == NULL)
  184                 aprint_error_dev(&sc->sc_dev, "WARNING: unable to establish power hook\n");
  185 
  186         /* initialize backlight brightness and lcd contrast */
  187         sc->sc_lcd_inited = 0;
  188         bivideo_init_brightness(sc, 1);
  189         bivideo_init_contrast(sc, 1);
  190         bivideo_init_backlight(sc, 1);
  191 
  192         ha.ha_console = console_flag;
  193         ha.ha_accessops = &bivideo_ha;
  194         ha.ha_accessctx = sc;
  195         ha.ha_curfbconf = 0;
  196         ha.ha_nfbconf = 1;
  197         ha.ha_fbconflist = &sc->sc_fbconf;
  198         ha.ha_curdspconf = 0;
  199         ha.ha_ndspconf = 1;
  200         ha.ha_dspconflist = &sc->sc_dspconf;
  201 
  202         config_found(self, &ha, hpcfbprint);
  203 }
  204 
  205 int
  206 bivideo_getcnfb(struct hpcfb_fbconf *fb)
  207 {
  208         console_flag = 1;
  209 
  210         return bivideo_init(fb);
  211 }
  212 
  213 static int
  214 bivideo_init(struct hpcfb_fbconf *fb)
  215 {
  216         /*
  217          * get fb settings from bootinfo
  218          */
  219         if (bootinfo == NULL ||
  220             bootinfo->fb_addr == 0 ||
  221             bootinfo->fb_line_bytes == 0 ||
  222             bootinfo->fb_width == 0 ||
  223             bootinfo->fb_height == 0) {
  224                 printf("no frame buffer information.\n");
  225                 return (-1);
  226         }
  227 
  228         /* zero fill */
  229         memset(fb, 0, sizeof(*fb));
  230 
  231         fb->hf_conf_index       = 0;    /* configuration index          */
  232         fb->hf_nconfs           = 1;    /* how many configurations      */
  233         strcpy(fb->hf_name, "built-in video");
  234                                         /* frame buffer name            */
  235         strcpy(fb->hf_conf_name, "default");
  236                                         /* configuration name           */
  237         fb->hf_height           = bootinfo->fb_height;
  238         fb->hf_width            = bootinfo->fb_width;
  239         fb->hf_baseaddr         = (u_long)bootinfo->fb_addr;
  240         fb->hf_offset           = (u_long)bootinfo->fb_addr -
  241                                       __PTOB(__BTOP(bootinfo->fb_addr));
  242                                         /* frame buffer start offset    */
  243         fb->hf_bytes_per_line   = bootinfo->fb_line_bytes;
  244         fb->hf_nplanes          = 1;
  245         fb->hf_bytes_per_plane  = bootinfo->fb_height *
  246                                         bootinfo->fb_line_bytes;
  247 
  248         fb->hf_access_flags |= HPCFB_ACCESS_BYTE;
  249         fb->hf_access_flags |= HPCFB_ACCESS_WORD;
  250         fb->hf_access_flags |= HPCFB_ACCESS_DWORD;
  251 
  252         switch (bootinfo->fb_type) {
  253                 /*
  254                  * gray scale
  255                  */
  256         case BIFB_D2_M2L_3:
  257         case BIFB_D2_M2L_3x2:
  258                 fb->hf_access_flags |= HPCFB_ACCESS_REVERSE;
  259                 /* fall through */
  260         case BIFB_D2_M2L_0:
  261         case BIFB_D2_M2L_0x2:
  262                 fb->hf_class = HPCFB_CLASS_GRAYSCALE;
  263                 fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
  264                 fb->hf_pack_width = 8;
  265                 fb->hf_pixels_per_pack = 4;
  266                 fb->hf_pixel_width = 2;
  267                 fb->hf_class_data_length = sizeof(struct hf_gray_tag);
  268                 fb->hf_u.hf_gray.hf_flags = 0;  /* reserved for future use */
  269                 break;
  270 
  271         case BIFB_D4_M2L_F:
  272         case BIFB_D4_M2L_Fx2:
  273                 fb->hf_access_flags |= HPCFB_ACCESS_REVERSE;
  274                 /* fall through */
  275         case BIFB_D4_M2L_0:
  276         case BIFB_D4_M2L_0x2:
  277                 fb->hf_class = HPCFB_CLASS_GRAYSCALE;
  278                 fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
  279                 fb->hf_pack_width = 8;
  280                 fb->hf_pixels_per_pack = 2;
  281                 fb->hf_pixel_width = 4;
  282                 fb->hf_class_data_length = sizeof(struct hf_gray_tag);
  283                 fb->hf_u.hf_gray.hf_flags = 0;  /* reserved for future use */
  284                 break;
  285 
  286                 /*
  287                  * indexed color
  288                  */
  289         case BIFB_D8_FF:
  290                 fb->hf_access_flags |= HPCFB_ACCESS_REVERSE;
  291                 /* fall through */
  292         case BIFB_D8_00:
  293                 fb->hf_class = HPCFB_CLASS_INDEXCOLOR;
  294                 fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
  295                 fb->hf_pack_width = 8;
  296                 fb->hf_pixels_per_pack = 1;
  297                 fb->hf_pixel_width = 8;
  298                 fb->hf_class_data_length = sizeof(struct hf_indexed_tag);
  299                 fb->hf_u.hf_indexed.hf_flags = 0; /* reserved for future use */
  300                 break;
  301 
  302                 /*
  303                  * RGB color
  304                  */
  305         case BIFB_D16_FFFF:
  306                 fb->hf_access_flags |= HPCFB_ACCESS_REVERSE;
  307                 /* fall through */
  308         case BIFB_D16_0000:
  309                 fb->hf_class = HPCFB_CLASS_RGBCOLOR;
  310                 fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
  311 #if BYTE_ORDER == LITTLE_ENDIAN
  312                 fb->hf_order_flags = HPCFB_REVORDER_BYTE;
  313 #endif
  314                 fb->hf_pack_width = 16;
  315                 fb->hf_pixels_per_pack = 1;
  316                 fb->hf_pixel_width = 16;
  317 
  318                 fb->hf_class_data_length = sizeof(struct hf_rgb_tag);
  319                 fb->hf_u.hf_rgb.hf_flags = 0;   /* reserved for future use */
  320 
  321                 fb->hf_u.hf_rgb.hf_red_width = 5;
  322                 fb->hf_u.hf_rgb.hf_red_shift = 11;
  323                 fb->hf_u.hf_rgb.hf_green_width = 6;
  324                 fb->hf_u.hf_rgb.hf_green_shift = 5;
  325                 fb->hf_u.hf_rgb.hf_blue_width = 5;
  326                 fb->hf_u.hf_rgb.hf_blue_shift = 0;
  327                 fb->hf_u.hf_rgb.hf_alpha_width = 0;
  328                 fb->hf_u.hf_rgb.hf_alpha_shift = 0;
  329                 break;
  330 
  331         default:
  332                 printf("unsupported type %d.\n", bootinfo->fb_type);
  333                 return (-1);
  334                 break;
  335         }
  336 
  337         return (0); /* no error */
  338 }
  339 
  340 static void
  341 bivideo_power(int why, void *arg)
  342 {
  343         struct bivideo_softc *sc = arg;
  344 
  345         switch (why) {
  346         case PWR_SUSPEND:
  347         case PWR_STANDBY:
  348                 sc->sc_powerstate |= PWRSTAT_SUSPEND;
  349                 bivideo_update_powerstate(sc, PWRSTAT_ALL);
  350                 break;
  351         case PWR_RESUME:
  352                 sc->sc_powerstate &= ~PWRSTAT_SUSPEND;
  353                 bivideo_update_powerstate(sc, PWRSTAT_ALL);
  354                 break;
  355         }
  356 }
  357 
  358 static void
  359 bivideo_update_powerstate(struct bivideo_softc *sc, int updates)
  360 {
  361         if (updates & PWRSTAT_LCD)
  362                 config_hook_call(CONFIG_HOOK_POWERCONTROL,
  363                     CONFIG_HOOK_POWERCONTROL_LCD,
  364                     (void*)!(sc->sc_powerstate &
  365                                 (PWRSTAT_VIDEOOFF|PWRSTAT_SUSPEND)));
  366 
  367         if (updates & PWRSTAT_BACKLIGHT)
  368                 config_hook_call(CONFIG_HOOK_POWERCONTROL,
  369                     CONFIG_HOOK_POWERCONTROL_LCDLIGHT,
  370                     (void*)(!(sc->sc_powerstate &
  371                                 (PWRSTAT_VIDEOOFF|PWRSTAT_SUSPEND)) &&
  372                              (sc->sc_powerstate & PWRSTAT_BACKLIGHT)));
  373 }
  374 
  375 int
  376 bivideo_ioctl(void *v, u_long cmd, void *data, int flag, struct lwp *l)
  377 {
  378         struct bivideo_softc *sc = (struct bivideo_softc *)v;
  379         struct hpcfb_fbconf *fbconf;
  380         struct hpcfb_dspconf *dspconf;
  381         struct wsdisplay_cmap *cmap;
  382         struct wsdisplay_param *dispparam;
  383         int error;
  384 
  385         switch (cmd) {
  386         case WSDISPLAYIO_GETCMAP:
  387                 cmap = (struct wsdisplay_cmap *)data;
  388 
  389                 if (sc->sc_fbconf.hf_class != HPCFB_CLASS_INDEXCOLOR ||
  390                     sc->sc_fbconf.hf_pack_width != 8 ||
  391                     256 <= cmap->index ||
  392                     256 < (cmap->index + cmap->count))
  393                         return (EINVAL);
  394 
  395                 error = copyout(&bivideo_cmap_r[cmap->index], cmap->red,
  396                                 cmap->count);
  397                 if (error)
  398                         return error;
  399                 error = copyout(&bivideo_cmap_g[cmap->index], cmap->green,
  400                                 cmap->count);
  401                 if (error)
  402                         return error;
  403                 error = copyout(&bivideo_cmap_b[cmap->index], cmap->blue,
  404                                 cmap->count);
  405                 return error;
  406 
  407         case WSDISPLAYIO_PUTCMAP:
  408                 /*
  409                  * This driver can't set color map.
  410                  */
  411                 return (EINVAL);
  412 
  413         case WSDISPLAYIO_SVIDEO:
  414                 if (*(int *)data == WSDISPLAYIO_VIDEO_OFF)
  415                         sc->sc_powerstate |= PWRSTAT_VIDEOOFF;
  416                 else
  417                         sc->sc_powerstate &= ~PWRSTAT_VIDEOOFF;
  418                 bivideo_update_powerstate(sc, PWRSTAT_ALL);
  419                 return 0;
  420 
  421         case WSDISPLAYIO_GVIDEO:
  422                 *(int *)data = (sc->sc_powerstate&PWRSTAT_VIDEOOFF) ?
  423                                 WSDISPLAYIO_VIDEO_OFF:WSDISPLAYIO_VIDEO_ON;
  424                 return 0;
  425 
  426 
  427         case WSDISPLAYIO_GETPARAM:
  428                 dispparam = (struct wsdisplay_param*)data;
  429                 switch (dispparam->param) {
  430                 case WSDISPLAYIO_PARAM_BACKLIGHT:
  431                         VPRINTF(("bivideo_ioctl: GET:BACKLIGHT\n"));
  432                         bivideo_init_brightness(sc, 0);
  433                         bivideo_init_backlight(sc, 0);
  434                         VPRINTF(("bivideo_ioctl: GET:(real)BACKLIGHT %d\n",
  435                                  (sc->sc_powerstate&PWRSTAT_BACKLIGHT)? 1: 0));
  436                         dispparam->min = 0;
  437                         dispparam->max = 1;
  438                         if (sc->sc_max_brightness > 0)
  439                                 dispparam->curval = sc->sc_brightness > 0? 1: 0;
  440                         else
  441                                 dispparam->curval =
  442                                     (sc->sc_powerstate&PWRSTAT_BACKLIGHT) ? 1: 0;
  443                         VPRINTF(("bivideo_ioctl: GET:BACKLIGHT:%d(%s)\n",
  444                                 dispparam->curval,
  445                                 sc->sc_max_brightness > 0? "brightness": "light"));
  446                         return 0;
  447                         break;
  448                 case WSDISPLAYIO_PARAM_CONTRAST:
  449                         VPRINTF(("bivideo_ioctl: GET:CONTRAST\n"));
  450                         bivideo_init_contrast(sc, 0);
  451                         if (sc->sc_max_contrast > 0) {
  452                                 dispparam->min = 0;
  453                                 dispparam->max = sc->sc_max_contrast;
  454                                 dispparam->curval = sc->sc_contrast;
  455                                 VPRINTF(("bivideo_ioctl: GET:CONTRAST max=%d, current=%d\n", sc->sc_max_contrast, sc->sc_contrast));
  456                                 return 0;
  457                         } else {
  458                                 VPRINTF(("bivideo_ioctl: GET:CONTRAST EINVAL\n"));
  459                                 return (EINVAL);
  460                         }
  461                         break;
  462                 case WSDISPLAYIO_PARAM_BRIGHTNESS:
  463                         VPRINTF(("bivideo_ioctl: GET:BRIGHTNESS\n"));
  464                         bivideo_init_brightness(sc, 0);
  465                         if (sc->sc_max_brightness > 0) {
  466                                 dispparam->min = 0;
  467                                 dispparam->max = sc->sc_max_brightness;
  468                                 dispparam->curval = sc->sc_brightness;
  469                                 VPRINTF(("bivideo_ioctl: GET:BRIGHTNESS max=%d, current=%d\n", sc->sc_max_brightness, sc->sc_brightness));
  470                                 return 0;
  471                         } else {
  472                                 VPRINTF(("bivideo_ioctl: GET:BRIGHTNESS EINVAL\n"));
  473                                 return (EINVAL);
  474                         }
  475                         return (EINVAL);
  476                 default:
  477                         return (EINVAL);
  478                 }
  479                 return (0);
  480 
  481         case WSDISPLAYIO_SETPARAM:
  482                 dispparam = (struct wsdisplay_param*)data;
  483                 switch (dispparam->param) {
  484                 case WSDISPLAYIO_PARAM_BACKLIGHT:
  485                         VPRINTF(("bivideo_ioctl: SET:BACKLIGHT\n"));
  486                         if (dispparam->curval < 0 ||
  487                             1 < dispparam->curval)
  488                                 return (EINVAL);
  489                         bivideo_init_brightness(sc, 0);
  490                         VPRINTF(("bivideo_ioctl: SET:max brightness=%d\n", sc->sc_max_brightness));
  491                         if (sc->sc_max_brightness > 0) { /* dimmer */
  492                                 if (dispparam->curval == 0){
  493                                         sc->sc_brightness_save = sc->sc_brightness;
  494                                         bivideo_set_brightness(sc, 0);  /* min */
  495                                 } else {
  496                                         if (sc->sc_brightness_save == 0)
  497                                                 sc->sc_brightness_save = sc->sc_max_brightness;
  498                                         bivideo_set_brightness(sc, sc->sc_brightness_save);
  499                                 }
  500                                 VPRINTF(("bivideo_ioctl: SET:BACKLIGHT:brightness=%d\n", sc->sc_brightness));
  501                         } else { /* off */
  502                                 if (dispparam->curval == 0)
  503                                         sc->sc_powerstate &= ~PWRSTAT_BACKLIGHT;
  504                                 else
  505                                         sc->sc_powerstate |= PWRSTAT_BACKLIGHT;
  506                                 VPRINTF(("bivideo_ioctl: SET:BACKLIGHT:powerstate %d\n",
  507                                                 (sc->sc_powerstate & PWRSTAT_BACKLIGHT)?1:0));
  508                                 bivideo_update_powerstate(sc, PWRSTAT_BACKLIGHT);
  509                                 VPRINTF(("bivideo_ioctl: SET:BACKLIGHT:%d\n",
  510                                         (sc->sc_powerstate & PWRSTAT_BACKLIGHT)?1:0));
  511                         }
  512                         return 0;
  513                         break;
  514                 case WSDISPLAYIO_PARAM_CONTRAST:
  515                         VPRINTF(("bivideo_ioctl: SET:CONTRAST\n"));
  516                         bivideo_init_contrast(sc, 0);
  517                         if (dispparam->curval < 0 ||
  518                             sc->sc_max_contrast < dispparam->curval)
  519                                 return (EINVAL);
  520                         if (sc->sc_max_contrast > 0) {
  521 #ifdef FBDEBUG
  522                                 int org = sc->sc_contrast;
  523 #endif
  524                                 bivideo_set_contrast(sc, dispparam->curval);
  525                                 VPRINTF(("bivideo_ioctl: SET:CONTRAST org=%d, current=%d\n", org, sc->sc_contrast));
  526                                 return 0;
  527                         } else {
  528                                 VPRINTF(("bivideo_ioctl: SET:CONTRAST EINVAL\n"));
  529                                 return (EINVAL);
  530                         }
  531                         break;
  532                 case WSDISPLAYIO_PARAM_BRIGHTNESS:
  533                         VPRINTF(("bivideo_ioctl: SET:BRIGHTNESS\n"));
  534                         bivideo_init_brightness(sc, 0);
  535                         if (dispparam->curval < 0 ||
  536                             sc->sc_max_brightness < dispparam->curval)
  537                                 return (EINVAL);
  538                         if (sc->sc_max_brightness > 0) {
  539 #ifdef FBDEBUG
  540                                 int org = sc->sc_brightness;
  541 #endif
  542                                 bivideo_set_brightness(sc, dispparam->curval);
  543                                 VPRINTF(("bivideo_ioctl: SET:BRIGHTNESS org=%d, current=%d\n", org, sc->sc_brightness));
  544                                 return 0;
  545                         } else {
  546                                 VPRINTF(("bivideo_ioctl: SET:BRIGHTNESS EINVAL\n"));
  547                                 return (EINVAL);
  548                         }
  549                         break;
  550                 default:
  551                         return (EINVAL);
  552                 }
  553                 return (0);
  554 
  555         case HPCFBIO_GCONF:
  556                 fbconf = (struct hpcfb_fbconf *)data;
  557                 if (fbconf->hf_conf_index != 0 &&
  558                     fbconf->hf_conf_index != HPCFB_CURRENT_CONFIG) {
  559                         return (EINVAL);
  560                 }
  561                 *fbconf = sc->sc_fbconf;        /* structure assignment */
  562                 return (0);
  563         case HPCFBIO_SCONF:
  564                 fbconf = (struct hpcfb_fbconf *)data;
  565                 if (fbconf->hf_conf_index != 0 &&
  566                     fbconf->hf_conf_index != HPCFB_CURRENT_CONFIG) {
  567                         return (EINVAL);
  568                 }
  569                 /*
  570                  * nothing to do because we have only one configuration
  571                  */
  572                 return (0);
  573         case HPCFBIO_GDSPCONF:
  574                 dspconf = (struct hpcfb_dspconf *)data;
  575                 if ((dspconf->hd_unit_index != 0 &&
  576                      dspconf->hd_unit_index != HPCFB_CURRENT_UNIT) ||
  577                     (dspconf->hd_conf_index != 0 &&
  578                      dspconf->hd_conf_index != HPCFB_CURRENT_CONFIG)) {
  579                         return (EINVAL);
  580                 }
  581                 *dspconf = sc->sc_dspconf;      /* structure assignment */
  582                 return (0);
  583         case HPCFBIO_SDSPCONF:
  584                 dspconf = (struct hpcfb_dspconf *)data;
  585                 if ((dspconf->hd_unit_index != 0 &&
  586                      dspconf->hd_unit_index != HPCFB_CURRENT_UNIT) ||
  587                     (dspconf->hd_conf_index != 0 &&
  588                      dspconf->hd_conf_index != HPCFB_CURRENT_CONFIG)) {
  589                         return (EINVAL);
  590                 }
  591                 /*
  592                  * nothing to do
  593                  * because we have only one unit and one configuration
  594                  */
  595                 return (0);
  596         case HPCFBIO_GOP:
  597         case HPCFBIO_SOP:
  598                 /*
  599                  * curently not implemented...
  600                  */
  601                 return (EINVAL);
  602         }
  603 
  604         return (EPASSTHROUGH);
  605 }
  606 
  607 paddr_t
  608 bivideo_mmap(void *ctx, off_t offset, int prot)
  609 {
  610         struct bivideo_softc *sc = (struct bivideo_softc *)ctx;
  611 
  612         if (offset < 0 ||
  613             (sc->sc_fbconf.hf_bytes_per_plane +
  614                 sc->sc_fbconf.hf_offset) <  offset)
  615                 return -1;
  616 
  617         return __BTOP((u_long)bootinfo->fb_addr + offset);
  618 }
  619 
  620 
  621 void
  622 bivideo_init_backlight(struct bivideo_softc *sc, int inattach)
  623 {
  624         int val = -1;
  625 
  626         if (sc->sc_lcd_inited&BACKLIGHT_INITED)
  627                 return;
  628 
  629         if (config_hook_call(CONFIG_HOOK_GET,
  630              CONFIG_HOOK_POWER_LCDLIGHT, &val) != -1) {
  631                 /* we can get real light state */
  632                 VPRINTF(("bivideo_init_backlight: real backlight=%d\n", val));
  633                 if (val == 0)
  634                         sc->sc_powerstate &= ~PWRSTAT_BACKLIGHT;
  635                 else
  636                         sc->sc_powerstate |= PWRSTAT_BACKLIGHT;
  637                 sc->sc_lcd_inited |= BACKLIGHT_INITED;
  638         } else if (inattach) {
  639                 /*
  640                    we cannot get real light state in attach time
  641                    because light device not yet attached.
  642                    we will retry in !inattach.
  643                    temporary assume light is on.
  644                  */
  645                 sc->sc_powerstate |= PWRSTAT_BACKLIGHT;
  646         } else {
  647                 /* we cannot get real light state, so work by myself state */
  648                 sc->sc_lcd_inited |= BACKLIGHT_INITED;
  649         }
  650 }
  651 
  652 void
  653 bivideo_init_brightness(struct bivideo_softc *sc, int inattach)
  654 {
  655         int val = -1;
  656 
  657         if (sc->sc_lcd_inited&BRIGHTNESS_INITED)
  658                 return;
  659 
  660         VPRINTF(("bivideo_init_brightness\n"));
  661         if (config_hook_call(CONFIG_HOOK_GET,
  662              CONFIG_HOOK_BRIGHTNESS_MAX, &val) != -1) {
  663                 /* we can get real brightness max */
  664                 VPRINTF(("bivideo_init_brightness: real brightness max=%d\n", val));
  665                 sc->sc_max_brightness = val;
  666                 val = -1;
  667                 if (config_hook_call(CONFIG_HOOK_GET,
  668                      CONFIG_HOOK_BRIGHTNESS, &val) != -1) {
  669                         /* we can get real brightness */
  670                         VPRINTF(("bivideo_init_brightness: real brightness=%d\n", val));
  671                         sc->sc_brightness_save = sc->sc_brightness = val;
  672                 } else {
  673                         sc->sc_brightness_save =
  674                         sc->sc_brightness = sc->sc_max_brightness;
  675                 }
  676                 sc->sc_lcd_inited |= BRIGHTNESS_INITED;
  677         } else if (inattach) {
  678                 /*
  679                    we cannot get real brightness in attach time
  680                    because brightness device not yet attached.
  681                    we will retry in !inattach.
  682                  */
  683                 sc->sc_max_brightness = -1;
  684                 sc->sc_brightness = -1;
  685                 sc->sc_brightness_save = -1;
  686         } else {
  687                 /* we cannot get real brightness */
  688                 sc->sc_lcd_inited |= BRIGHTNESS_INITED;
  689         }
  690 
  691         return;
  692 }
  693 
  694 void
  695 bivideo_init_contrast(struct bivideo_softc *sc, int inattach)
  696 {
  697         int val = -1;
  698 
  699         if (sc->sc_lcd_inited&CONTRAST_INITED)
  700                 return;
  701 
  702         VPRINTF(("bivideo_init_contrast\n"));
  703         if (config_hook_call(CONFIG_HOOK_GET,
  704              CONFIG_HOOK_CONTRAST_MAX, &val) != -1) {
  705                 /* we can get real contrast max */
  706                 VPRINTF(("bivideo_init_contrast: real contrast max=%d\n", val));
  707                 sc->sc_max_contrast = val;
  708                 val = -1;
  709                 if (config_hook_call(CONFIG_HOOK_GET,
  710                      CONFIG_HOOK_CONTRAST, &val) != -1) {
  711                         /* we can get real contrast */
  712                         VPRINTF(("bivideo_init_contrast: real contrast=%d\n", val));
  713                         sc->sc_contrast = val;
  714                 } else {
  715                         sc->sc_contrast = sc->sc_max_contrast;
  716                 }
  717                 sc->sc_lcd_inited |= CONTRAST_INITED;
  718         } else if (inattach) {
  719                 /*
  720                    we cannot get real contrast in attach time
  721                    because contrast device not yet attached.
  722                    we will retry in !inattach.
  723                  */
  724                 sc->sc_max_contrast = -1;
  725                 sc->sc_contrast = -1;
  726         } else {
  727                 /* we cannot get real contrast */
  728                 sc->sc_lcd_inited |= CONTRAST_INITED;
  729         }
  730 
  731         return;
  732 }
  733 
  734 void
  735 bivideo_set_brightness(struct bivideo_softc *sc, int val)
  736 {
  737         sc->sc_brightness = val;
  738 
  739         config_hook_call(CONFIG_HOOK_SET, CONFIG_HOOK_BRIGHTNESS, &val);
  740         if (config_hook_call(CONFIG_HOOK_GET,
  741              CONFIG_HOOK_BRIGHTNESS, &val) != -1) {
  742                 sc->sc_brightness = val;
  743         }
  744 }
  745 
  746 void
  747 bivideo_set_contrast(struct bivideo_softc *sc, int val)
  748 {
  749         sc->sc_contrast = val;
  750 
  751         config_hook_call(CONFIG_HOOK_SET, CONFIG_HOOK_CONTRAST, &val);
  752         if (config_hook_call(CONFIG_HOOK_GET,
  753              CONFIG_HOOK_CONTRAST, &val) != -1) {
  754                 sc->sc_contrast = val;
  755         }
  756 }

Cache object: 05bce6eb9f26c22a68837f91e61ae310


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.