Emulator Brightness control routine is added.
authorfredrick.kim <fredrick.kim@samsung.com>
Thu, 4 Aug 2011 02:07:49 +0000 (11:07 +0900)
committerfredrick.kim <fredrick.kim@samsung.com>
Thu, 4 Aug 2011 02:07:49 +0000 (11:07 +0900)
Makefile.objs
hw/brightness.c [new file with mode: 0755]
hw/pc.c
hw/pc.h
hw/vga.c

index 9449ae6..6765044 100644 (file)
@@ -254,7 +254,7 @@ hw-obj-y += dma-helpers.o sysbus.o isa-bus.o
 hw-obj-y += qdev-addr.o
 
 # VGA
-hw-obj-$(CONFIG_VGA_PCI) += vga-pci.o overlay.o
+hw-obj-$(CONFIG_VGA_PCI) += vga-pci.o overlay.o brightness.o
 hw-obj-$(CONFIG_VGA_ISA) += vga-isa.o
 hw-obj-$(CONFIG_VGA_ISA_MM) += vga-isa-mm.o
 hw-obj-$(CONFIG_VMWARE_VGA) += vmware_vga.o
diff --git a/hw/brightness.c b/hw/brightness.c
new file mode 100755 (executable)
index 0000000..d1e5a9d
--- /dev/null
@@ -0,0 +1,174 @@
+/* 
+ * Qemu brightness emulator
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved 
+ *
+ * Authors:
+ *  Yuyeon Oh  yuyeon.oh@samsung.com
+ *
+ * PROPRIETARY/CONFIDENTIAL
+ * This software is the confidential and proprietary information of SAMSUNG ELECTRONICS ("Confidential Information").  
+ * You shall not disclose such Confidential Information and shall use it only in accordance with the terms of the license agreement 
+ * you entered into with SAMSUNG ELECTRONICS.  SAMSUNG make no representations or warranties about the suitability 
+ * of the software, either express or implied, including but not limited to the implied warranties of merchantability, fitness for 
+ * a particular purpose, or non-infringement. SAMSUNG shall not be liable for any damages suffered by licensee as 
+ * a result of using, modifying or distributing this software or its derivatives.
+ */
+
+#include "pc.h"
+#include "pci.h"
+#include "pci_ids.h"
+
+#define PCI_VENDOR_ID_SAMSUNG                          0x144d
+#define PCI_DEVICE_ID_VIRTUAL_BRIGHTNESS    0x1014
+#define QEMU_DEV_NAME                                          "brightness"
+
+#define BRIGHTNESS_MEM_SIZE                    (4 * 1024)              /* 4KB */
+#define BRIGHTNESS_REG_SIZE                    256
+
+#define BRIGHTNESS_MIN                         (0)
+#define BRIGHTNESS_MAX                         (10)
+
+typedef struct BrightnessState {
+    PCIDevice dev;
+    
+    ram_addr_t offset;
+    int brightness_mmio_io_addr;
+
+    uint32_t ioport_addr;      // guest addr
+    uint32_t mmio_addr;                // guest addr
+} BrightnessState;
+
+enum {
+       BRIGHTNESS_LEVEL        = 0x00,
+};
+
+//uint8_t* brightness_ptr;     // pointer in qemu space
+uint32_t brightness_level = 10;
+
+//#define DEBUG_BRIGHTNESS
+
+#if defined (DEBUG_BRIGHTNESS)
+#  define DEBUG_PRINT(x) do { printf x ; } while (0)
+#else
+#  define DEBUG_PRINT(x)
+#endif
+
+static uint32_t brightness_reg_read(void *opaque, target_phys_addr_t addr)
+{
+    switch (addr & 0xFF) {
+    case BRIGHTNESS_LEVEL:
+       DEBUG_PRINT(("brightness_reg_read: brightness_level = %d\n", brightness_level));
+        return brightness_level;
+
+    default:
+        fprintf(stderr, "wrong brightness register read - addr : %d\n", addr);
+    }
+
+    return 0;
+}
+
+static void brightness_reg_write(void *opaque, target_phys_addr_t addr, uint32_t val)
+{
+       DEBUG_PRINT(("brightness_reg_write: addr = %d, val = %d\n", addr, val));
+
+       if (val < BRIGHTNESS_MIN || val > BRIGHTNESS_MAX) {
+               fprintf(stderr, "brightness_reg_write: Invalide brightness level.\n");
+       }
+
+    switch (addr & 0xFF) {
+    case BRIGHTNESS_LEVEL:
+       brightness_level = val;
+        return;
+    default:
+        fprintf(stderr, "wrong brightness register write - addr : %d\n", addr);
+    }
+}
+
+static CPUReadMemoryFunc * const brightness_reg_readfn[3] = {
+       brightness_reg_read,
+       brightness_reg_read,
+       brightness_reg_read,
+};
+
+static CPUWriteMemoryFunc * const brightness_reg_writefn[3] = {
+       brightness_reg_write,
+       brightness_reg_write,
+       brightness_reg_write,
+};
+
+static void brightness_ioport_map(PCIDevice *dev, int region_num,
+                              pcibus_t addr, pcibus_t size, int type)
+{
+       //BrightnessState *s = DO_UPCAST(BrightnessState, dev, dev);
+
+    //cpu_register_physical_memory(addr, BRIGHTNESS_MEM_SIZE,
+       //                       s->offset);
+
+    //s->ioport_addr = addr;
+}
+
+static void brightness_mmio_map(PCIDevice *dev, int region_num,
+                              pcibus_t addr, pcibus_t size, int type)
+{
+       BrightnessState *s = DO_UPCAST(BrightnessState, dev, dev);
+    
+    cpu_register_physical_memory(addr, BRIGHTNESS_REG_SIZE,
+                                 s->brightness_mmio_io_addr);
+    
+    s->mmio_addr = addr;
+}
+
+static int brightness_initfn(PCIDevice *dev)
+{
+       BrightnessState *s = DO_UPCAST(BrightnessState, dev, dev);
+    uint8_t *pci_conf = s->dev.config;
+
+    pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_SAMSUNG);
+    pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_VIRTUAL_BRIGHTNESS);
+    pci_config_set_class(pci_conf, PCI_CLASS_DISPLAY_OTHER);
+
+    //s->offset = qemu_ram_alloc(NULL, "brightness", BRIGHTNESS_MEM_SIZE);
+    //brightness_ptr = qemu_get_ram_ptr(s->offset);
+
+    s->brightness_mmio_io_addr = cpu_register_io_memory(brightness_reg_readfn,
+                                             brightness_reg_writefn, s,
+                                             DEVICE_LITTLE_ENDIAN);
+    /* setup memory space */
+    /* memory #0 device memory (overlay surface) */
+    /* memory #1 memory-mapped I/O */
+    //pci_register_bar(&s->dev, 0, BRIGHTNESS_MEM_SIZE,
+    //         PCI_BASE_ADDRESS_SPACE_IO, brightness_ioport_map);
+
+    pci_register_bar(&s->dev, 1, BRIGHTNESS_REG_SIZE,
+                     PCI_BASE_ADDRESS_SPACE_MEMORY, brightness_mmio_map);
+
+    return 0;
+}
+
+/* external interface */
+int pci_get_brightness(void)
+{
+       return brightness_level;
+}
+
+int pci_brightness_init(PCIBus *bus)
+{
+    pci_create_simple(bus, -1, QEMU_DEV_NAME);
+    return 0;
+}
+
+static PCIDeviceInfo brightness_info = {
+    .qdev.name    = QEMU_DEV_NAME,
+    .qdev.size    = sizeof(BrightnessState),
+    .no_hotplug   = 1,
+    .init         = brightness_initfn,
+};
+
+static void brightness_register(void)
+{
+    pci_qdev_register(&brightness_info);
+}
+
+device_init(brightness_register);
diff --git a/hw/pc.c b/hw/pc.c
index 0a3d3e1..94004e9 100755 (executable)
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -1068,6 +1068,7 @@ void pc_vga_init(PCIBus *pci_bus)
         if (pci_bus) {
             pci_vga_init(pci_bus);
             pci_overlay_init(pci_bus);
+            pci_brightness_init(pci_bus);
         } else {
             isa_vga_init();
         }
@@ -1075,6 +1076,7 @@ void pc_vga_init(PCIBus *pci_bus)
         if (pci_bus) {
             pci_slp_vga_init(pci_bus);
             pci_overlay_init(pci_bus);
+            pci_brightness_init(pci_bus);
         } else {
             isa_vga_init();
         }
diff --git a/hw/pc.h b/hw/pc.h
index d2f20c2..478229e 100755 (executable)
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -153,6 +153,9 @@ extern enum vga_retrace_method vga_retrace_method;
 int isa_vga_init(void);
 int pci_vga_init(PCIBus *bus);
 int pci_overlay_init(PCIBus *bus);
+int pci_brightness_init(PCIBus *bus);
+int pci_get_brightness(void);
+
 int isa_vga_mm_init(target_phys_addr_t vram_base,
                     target_phys_addr_t ctrl_base, int it_shift);
 
index 5273407..9742e78 100755 (executable)
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -1628,6 +1628,8 @@ extern uint16_t overlay1_width;
 extern uint16_t overlay1_height;
        
 extern uint8_t* overlay_ptr;   // pointer in qemu space
+
+extern uint32_t brightness_level;
 #endif
 
 static void vga_draw_graphic(VGACommonState *s, int full_update)
@@ -1815,7 +1817,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
            int i;
            uint8_t *fb_sub;
            uint8_t *over_sub;
-           uint8_t alpha, c_alpha;
+           uint8_t alpha, c_alpha, delta;
            uint32_t *dst;
            uint16_t overlay_bottom;
 
@@ -1831,11 +1833,16 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
                         //alpha = 0x80;
                         alpha = fb_sub[3];
                         c_alpha = 0xff - alpha;
+                        delta = (brightness_level + 1) * 9;
                         //fprintf(stderr, "alpha = %d\n", alpha);
                         
-                        *dst = ((c_alpha * over_sub[0] + alpha * fb_sub[0]) >> 8) |
-                               ((c_alpha * over_sub[1] + alpha * fb_sub[1]) & 0xFF00) |
-                               ((c_alpha * over_sub[2] + alpha * fb_sub[2]) & 0xFF00) << 8;
+                        //*dst = ((c_alpha * over_sub[0] + alpha * fb_sub[0]) >> 8) |
+                        //       ((c_alpha * over_sub[1] + alpha * fb_sub[1]) & 0xFF00) |
+                        //       ((c_alpha * over_sub[2] + alpha * fb_sub[2]) & 0xFF00) << 8;
+
+                        *dst = (((c_alpha * over_sub[0] + alpha * fb_sub[0]) * delta / 99) >> 8)  |
+                               (((c_alpha * over_sub[1] + alpha * fb_sub[1]) * delta / 99) & 0xFF00)  |
+                               ((((c_alpha * over_sub[2] + alpha * fb_sub[2]) * delta / 99) & 0xFF00) << 8);
                     }
                 }
             }
@@ -1852,15 +1859,41 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
                         //alpha = 0x80;
                         alpha = fb_sub[3];
                         c_alpha = 0xff - alpha;
+                        delta = (brightness_level+1) * 9;
                         //fprintf(stderr, "alpha = %d\n", alpha);
                         
-                        *dst = ((c_alpha * over_sub[0] + alpha * fb_sub[0]) >> 8) |
-                               ((c_alpha * over_sub[1] + alpha * fb_sub[1]) & 0xFF00) |
-                               ((c_alpha * over_sub[2] + alpha * fb_sub[2]) & 0xFF00) << 8;
+                        //*dst = ((c_alpha * over_sub[0] + alpha * fb_sub[0]) >> 8) |
+                        //       ((c_alpha * over_sub[1] + alpha * fb_sub[1]) & 0xFF00) |
+                        //       ((c_alpha * over_sub[2] + alpha * fb_sub[2]) & 0xFF00) << 8;
+
+                        *dst = (((c_alpha * over_sub[0] + alpha * fb_sub[0]) * delta / 99) >> 8)  |
+                               (((c_alpha * over_sub[1] + alpha * fb_sub[1]) * delta / 99) & 0xFF00)  |
+                               ((((c_alpha * over_sub[2] + alpha * fb_sub[2]) * delta / 99) & 0xFF00) << 8);
                     }
                 }
             }
 #endif
+#if defined (TARGET_I386)
+           uint8_t *framebuffer;
+           uint32_t *dest;
+
+           if (!overlay0_power && !overlay1_power) {
+
+                               if (brightness_level >= 0 && brightness_level <= 10) {
+                                       framebuffer = s->vram_ptr + addr;
+                                       dest = (uint32_t*)(s->ds->surface->data + addr);
+                                       alpha = (brightness_level + 1) * 9;
+
+                                       //printf("addr = alpha = %d, disp_width = %d\n", alpha, disp_width);
+                                       for (i=0; i < disp_width; i++, framebuffer += 4, dest++) {
+                                               *dest = ((alpha * framebuffer[0] / 99) & 0xFF) |
+                                                               ((alpha * framebuffer[1] / 99) & 0xFF) << 8 |
+                                                               ((alpha * framebuffer[2] / 99) & 0xFF) << 16;
+                                       }
+                               }
+           }
+#endif /* TARGET_I386 */
+
         } else {
             if (y_start >= 0) {
                 /* flush to display */