initial f200 touchscreen support
authornotaz <notasas@gmail.com>
Sun, 10 Jan 2016 23:53:22 +0000 (01:53 +0200)
committernotaz <notasas@gmail.com>
Sun, 10 Jan 2016 23:53:22 +0000 (01:53 +0200)
common/host_fb.c
common/host_fb.h
common/omapfb.h [new file with mode: 0644]
loader/emu.c
loader/header.h
loader/host.c
loader/llibc.c
loader/override.c

index a59e869..6be9526 100644 (file)
@@ -17,10 +17,31 @@ static int host_stride;
 #if defined(PND)
 
 #include "libpicofe/linux/fbdev.c"
+#include "omapfb.h"
 
 static struct vout_fbdev *fbdev;
 static unsigned short host_pal[256];
 
+static int get_layer_size(int *x, int *y, int *w, int *h)
+{
+  struct omapfb_plane_info pi;
+  int ret;
+
+  ret = ioctl(vout_fbdev_get_fd(fbdev), OMAPFB_QUERY_PLANE, &pi);
+  if (ret != 0) {
+    perror("OMAPFB_QUERY_PLANE");
+    return -1;
+  }
+
+  *x = pi.pos_x;
+  *y = pi.pos_y;
+  *w = pi.out_width;
+  *h = pi.out_height;
+  printf("layer: %d,%d %dx%d\n", *x, *y, *w, *h);
+
+  return 0;
+}
+
 void *host_video_flip(void)
 {
   host_screen = vout_fbdev_flip(fbdev);
@@ -120,6 +141,18 @@ void host_video_blit16(const unsigned short *src, int w, int h, int stride)
   host_video_flip();
 }
 
+void host_video_normalize_ts(int *x1024, int *y1024)
+{
+  static int lx, ly, lw = 800, lh = 480, checked;
+
+  if (!checked) {
+    get_layer_size(&lx, &ly, &lw, &lh);
+    checked = 1; // XXX: might change, so may need to recheck
+  }
+  *x1024 = (*x1024 - lx) * 1024 / lw;
+  *y1024 = (*y1024 - ly) * 1024 / lh;
+}
+
 #elif defined(WIZ)
 
 #include "warm/warm.c"
@@ -209,6 +242,12 @@ void host_video_blit16(const unsigned short *src, int w, int h, int stride)
 }
 #endif // LOADER
 
+void host_video_normalize_ts(int *x1024, int *y1024)
+{
+  *x1024 = *x1024 * 1024 / 320;
+  *y1024 = *y1024 * 1024 / 240;
+}
+
 #endif // WIZ
 
 // vim:shiftwidth=2:expandtab
index 9a1c1f8..cf69356 100644 (file)
@@ -10,3 +10,5 @@ void  host_video_update_pal32(unsigned int *pal);
 void host_video_blit4(const unsigned char *src, int w, int h, int stride);
 void host_video_blit8(const unsigned char *src, int w, int h, int stride);
 void host_video_blit16(const unsigned short *src, int w, int h, int stride);
+
+void host_video_normalize_ts(int *x1024, int *y1024);
diff --git a/common/omapfb.h b/common/omapfb.h
new file mode 100644 (file)
index 0000000..a73479d
--- /dev/null
@@ -0,0 +1,187 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ***   To edit the content of this header, modify the corresponding
+ ***   source file (e.g. under external/kernel-headers/original/) then
+ ***   run bionic/libc/kernel/tools/update_all.py
+ ***
+ ***   Any manual change here will be lost the next time this script will
+ ***   be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _UAPI__LINUX_OMAPFB_H__
+#define _UAPI__LINUX_OMAPFB_H__
+#include <linux/fb.h>
+#include <linux/ioctl.h>
+#include <linux/types.h>
+#define OMAP_IOW(num, dtype) _IOW('O', num, dtype)
+#define OMAP_IOR(num, dtype) _IOR('O', num, dtype)
+#define OMAP_IOWR(num, dtype) _IOWR('O', num, dtype)
+#define OMAP_IO(num) _IO('O', num)
+#define OMAPFB_MIRROR OMAP_IOW(31, int)
+#define OMAPFB_SYNC_GFX OMAP_IO(37)
+#define OMAPFB_VSYNC OMAP_IO(38)
+#define OMAPFB_SET_UPDATE_MODE OMAP_IOW(40, int)
+#define OMAPFB_GET_CAPS OMAP_IOR(42, struct omapfb_caps)
+#define OMAPFB_GET_UPDATE_MODE OMAP_IOW(43, int)
+#define OMAPFB_LCD_TEST OMAP_IOW(45, int)
+#define OMAPFB_CTRL_TEST OMAP_IOW(46, int)
+#define OMAPFB_UPDATE_WINDOW_OLD OMAP_IOW(47, struct omapfb_update_window_old)
+#define OMAPFB_SET_COLOR_KEY OMAP_IOW(50, struct omapfb_color_key)
+#define OMAPFB_GET_COLOR_KEY OMAP_IOW(51, struct omapfb_color_key)
+#define OMAPFB_SETUP_PLANE OMAP_IOW(52, struct omapfb_plane_info)
+#define OMAPFB_QUERY_PLANE OMAP_IOW(53, struct omapfb_plane_info)
+#define OMAPFB_UPDATE_WINDOW OMAP_IOW(54, struct omapfb_update_window)
+#define OMAPFB_SETUP_MEM OMAP_IOW(55, struct omapfb_mem_info)
+#define OMAPFB_QUERY_MEM OMAP_IOW(56, struct omapfb_mem_info)
+#define OMAPFB_WAITFORVSYNC OMAP_IO(57)
+#define OMAPFB_MEMORY_READ OMAP_IOR(58, struct omapfb_memory_read)
+#define OMAPFB_GET_OVERLAY_COLORMODE OMAP_IOR(59, struct omapfb_ovl_colormode)
+#define OMAPFB_WAITFORGO OMAP_IO(60)
+#define OMAPFB_GET_VRAM_INFO OMAP_IOR(61, struct omapfb_vram_info)
+#define OMAPFB_SET_TEARSYNC OMAP_IOW(62, struct omapfb_tearsync_info)
+#define OMAPFB_GET_DISPLAY_INFO OMAP_IOR(63, struct omapfb_display_info)
+#define OMAPFB_CAPS_GENERIC_MASK 0x00000fff
+#define OMAPFB_CAPS_LCDC_MASK 0x00fff000
+#define OMAPFB_CAPS_PANEL_MASK 0xff000000
+#define OMAPFB_CAPS_MANUAL_UPDATE 0x00001000
+#define OMAPFB_CAPS_TEARSYNC 0x00002000
+#define OMAPFB_CAPS_PLANE_RELOCATE_MEM 0x00004000
+#define OMAPFB_CAPS_PLANE_SCALE 0x00008000
+#define OMAPFB_CAPS_WINDOW_PIXEL_DOUBLE 0x00010000
+#define OMAPFB_CAPS_WINDOW_SCALE 0x00020000
+#define OMAPFB_CAPS_WINDOW_OVERLAY 0x00040000
+#define OMAPFB_CAPS_WINDOW_ROTATE 0x00080000
+#define OMAPFB_CAPS_SET_BACKLIGHT 0x01000000
+#define OMAPFB_FORMAT_MASK 0x00ff
+#define OMAPFB_FORMAT_FLAG_DOUBLE 0x0100
+#define OMAPFB_FORMAT_FLAG_TEARSYNC 0x0200
+#define OMAPFB_FORMAT_FLAG_FORCE_VSYNC 0x0400
+#define OMAPFB_FORMAT_FLAG_ENABLE_OVERLAY 0x0800
+#define OMAPFB_FORMAT_FLAG_DISABLE_OVERLAY 0x1000
+#define OMAPFB_MEMTYPE_SDRAM 0
+#define OMAPFB_MEMTYPE_SRAM 1
+#define OMAPFB_MEMTYPE_MAX 1
+#define OMAPFB_MEM_IDX_ENABLED 0x80
+#define OMAPFB_MEM_IDX_MASK 0x7f
+enum omapfb_color_format {
+ OMAPFB_COLOR_RGB565 = 0,
+ OMAPFB_COLOR_YUV422,
+ OMAPFB_COLOR_YUV420,
+ OMAPFB_COLOR_CLUT_8BPP,
+ OMAPFB_COLOR_CLUT_4BPP,
+ OMAPFB_COLOR_CLUT_2BPP,
+ OMAPFB_COLOR_CLUT_1BPP,
+ OMAPFB_COLOR_RGB444,
+ OMAPFB_COLOR_YUY422,
+ OMAPFB_COLOR_ARGB16,
+ OMAPFB_COLOR_RGB24U,
+ OMAPFB_COLOR_RGB24P,
+ OMAPFB_COLOR_ARGB32,
+ OMAPFB_COLOR_RGBA32,
+ OMAPFB_COLOR_RGBX32,
+};
+struct omapfb_update_window {
+ __u32 x, y;
+ __u32 width, height;
+ __u32 format;
+ __u32 out_x, out_y;
+ __u32 out_width, out_height;
+ __u32 reserved[8];
+};
+struct omapfb_update_window_old {
+ __u32 x, y;
+ __u32 width, height;
+ __u32 format;
+};
+enum omapfb_plane {
+ OMAPFB_PLANE_GFX = 0,
+ OMAPFB_PLANE_VID1,
+ OMAPFB_PLANE_VID2,
+};
+enum omapfb_channel_out {
+ OMAPFB_CHANNEL_OUT_LCD = 0,
+ OMAPFB_CHANNEL_OUT_DIGIT,
+};
+struct omapfb_plane_info {
+ __u32 pos_x;
+ __u32 pos_y;
+ __u8 enabled;
+ __u8 channel_out;
+ __u8 mirror;
+ __u8 mem_idx;
+ __u32 out_width;
+ __u32 out_height;
+ __u32 reserved2[12];
+};
+struct omapfb_mem_info {
+ __u32 size;
+ __u8 type;
+ __u8 reserved[3];
+};
+struct omapfb_caps {
+ __u32 ctrl;
+ __u32 plane_color;
+ __u32 wnd_color;
+};
+enum omapfb_color_key_type {
+ OMAPFB_COLOR_KEY_DISABLED = 0,
+ OMAPFB_COLOR_KEY_GFX_DST,
+ OMAPFB_COLOR_KEY_VID_SRC,
+};
+struct omapfb_color_key {
+ __u8 channel_out;
+ __u32 background;
+ __u32 trans_key;
+ __u8 key_type;
+};
+enum omapfb_update_mode {
+ OMAPFB_UPDATE_DISABLED = 0,
+ OMAPFB_AUTO_UPDATE,
+ OMAPFB_MANUAL_UPDATE
+};
+struct omapfb_memory_read {
+ __u16 x;
+ __u16 y;
+ __u16 w;
+ __u16 h;
+ size_t buffer_size;
+ void *buffer;
+};
+struct omapfb_ovl_colormode {
+ __u8 overlay_idx;
+ __u8 mode_idx;
+ __u32 bits_per_pixel;
+ __u32 nonstd;
+ struct fb_bitfield red;
+ struct fb_bitfield green;
+ struct fb_bitfield blue;
+ struct fb_bitfield transp;
+};
+struct omapfb_vram_info {
+ __u32 total;
+ __u32 free;
+ __u32 largest_free_block;
+ __u32 reserved[5];
+};
+struct omapfb_tearsync_info {
+ __u8 enabled;
+ __u8 reserved1[3];
+ __u16 line;
+ __u16 reserved2;
+};
+struct omapfb_display_info {
+ __u16 xres;
+ __u16 yres;
+ __u32 width;
+ __u32 height;
+ __u32 reserved[5];
+};
+#endif
index 38fea46..5adcc5d 100644 (file)
@@ -1059,20 +1059,6 @@ void emu_init(void *map_bottom)
   sigaction(SIGSEGV, &segv_action, NULL);
 }
 
-long emu_read_gpiodev(void *buf, int count)
-{
-  if (count <= 0) {
-    err("gpiodev read %d?\n", count);
-    return -EINVAL;
-  }
-  if (count > 4)
-    count = 4;
-
-  mmsp2.btn_state = host_read_btns();
-  memcpy(buf, &mmsp2.btn_state, count);
-  return count;
-}
-
 static long emu_mmap_dev(unsigned int length, int prot, int flags, unsigned int offset)
 {
   u8 *umem, *umem_end;
@@ -1273,6 +1259,56 @@ fail:
   return -EINVAL;
 }
 
+long emu_do_read(int fd, void *buf, int count)
+{
+  static const char wm97xx_p[] =
+    "5507 0 -831476 0 -4218 16450692 65536"; // from 4.0 fw
+  int ret, pressed = 0, x, y;
+  struct {
+    u16 pressure, x, y;
+  } wm97xx;
+
+  if (count < 0) {
+    err("read(%d, %d)\n", fd, count);
+    return -EINVAL;
+  }
+
+  switch (fd) {
+  case FAKEDEV_GPIO:
+    mmsp2.btn_state = host_read_btns();
+
+    if (count > 4)
+      count = 4;
+    memcpy(buf, &mmsp2.btn_state, count);
+    break;
+  case FAKEDEV_WM97XX:
+    ret = host_read_ts(&pressed, &x, &y);
+    if (ret == 0 && pressed) {
+      wm97xx.pressure = 1;
+      wm97xx.x =        x * 3750 / 1024 + 200;
+      wm97xx.y = 3750 - y * 3750 / 1024 + 200;
+    }
+    else {
+      wm97xx.pressure = 0;
+      wm97xx.x = wm97xx.y = 200;
+    }
+
+    if (count > sizeof(wm97xx))
+      count = sizeof(wm97xx);
+    memcpy(buf, &wm97xx, count);
+    break;
+  case FAKEDEV_WM97XX_P:
+    if (count < sizeof(wm97xx_p))
+      err("incomplete pointercal read\n");
+    strncpy(buf, wm97xx_p, count);
+    break;
+  default:
+    err("read(%d, %d)\n", fd, count);
+    return -EINVAL;
+  }
+  return count;
+}
+
 struct dev_fd_t emu_interesting_fds[] = {
   [IFD_SOUND] = { "/dev/dsp", -1, emu_sound_open },
   { NULL, 0, NULL },
index 0641878..7bff116 100644 (file)
@@ -34,6 +34,8 @@ enum {
   FAKEDEV_FB1,
   FAKEDEV_MMUHACK,
   FAKEDEV_TTY0,
+  FAKEDEV_WM97XX,
+  FAKEDEV_WM97XX_P,
   FAKEDEV_FD_BOUNDARY,
 };
 
@@ -46,13 +48,14 @@ void  emu_call_handle_op(struct op_context *op_ctx);
 long  emu_do_mmap(unsigned int length, int prot, int flags, int fd, unsigned int offset);
 long  emu_do_munmap(void *addr, unsigned int length);
 long  emu_do_ioctl(int fd, int request, void *argp);
-long  emu_read_gpiodev(void *buf, int count);
+long  emu_do_read(int fd, void *buf, int count);
 void *emu_do_fopen(const char *path, const char *mode);
 int   emu_do_system(const char *command);
 long  emu_do_execve(const char *filename, char *const argv[], char *const envp[]);
 
 int   host_init(void);
 int   host_read_btns(void);
+int   host_read_ts(int *pressed, int *x1024, int *y1024);
 void  host_forced_exit(int status);
 
 enum  { GP2X_UP = 0,      GP2X_LEFT = 2,      GP2X_DOWN = 4,  GP2X_RIGHT = 6,
index 796d980..9532347 100644 (file)
@@ -6,11 +6,18 @@
  */
 #define _GNU_SOURCE 1 // for plat.c
 #include <stdio.h>
+#include <stdlib.h>
 #include <stdarg.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
 #include <linux/input.h>
 
 #include "../common/libpicofe/input.h"
 #include "../common/libpicofe/linux/in_evdev.h"
+#include "../common/host_fb.h"
 
 #include "header.h"
 #include "realfuncs.h"
 #endif
 
 char **g_argv;
+static int ts_fd = -1;
+
+/* touscreen. Could just use tsblib, but it's LGPL... */
+static int tsc[7];
+
+static int host_ts_init(void)
+{
+  static const char name_def[] = "/dev/input/touchscreen0";
+  const char *name;
+  FILE *f;
+  int ret;
+
+  f = fopen("/etc/pointercal", "r");
+  if (f == NULL) {
+    perror("fopen pointercal");
+    return -1;
+  }
+  ret = fscanf(f, "%d %d %d %d %d %d %d", &tsc[0], &tsc[1],
+               &tsc[2], &tsc[3], &tsc[4], &tsc[5], &tsc[6]);
+  fclose(f);
+  if (ret != 7) {
+    fprintf(stderr, "could not parse pointercal\n");
+    return -1;
+  }
+
+  name = getenv("TSLIB_TSDEVICE");
+  if (name == NULL)
+    name = name_def;
+  ts_fd = open(name, O_RDONLY | O_NONBLOCK);
+  if (ts_fd == -1) {
+    fprintf(stderr, "open %s", name);
+    perror("");
+    return -1;
+  }
+  return 0;
+}
+
+// returns ranges 0-1023
+int host_read_ts(int *pressure, int *x1024, int *y1024)
+{
+  static int raw_x, raw_y, raw_p;
+  struct input_event ev;
+  ssize_t ret;
+
+  if (ts_fd == -1)
+    return -1;
+
+  for (;;) {
+    errno = 0;
+    ret = read(ts_fd, &ev, sizeof(ev));
+    if (ret != sizeof(ev)) {
+      if (errno == EAGAIN)
+        break;
+      perror("ts read");
+      return -1;
+    }
+    if (ev.type == EV_ABS) {
+      switch (ev.code) {
+      case ABS_X: raw_x = ev.value; break;
+      case ABS_Y: raw_y = ev.value; break;
+      case ABS_PRESSURE: raw_p = ev.value; break;
+      }
+    }
+  }
+
+  *pressure = raw_p;
+  *x1024 = (tsc[0] * raw_x + tsc[1] * raw_y + tsc[2]) / tsc[6];
+  *y1024 = (tsc[3] * raw_x + tsc[4] * raw_y + tsc[5]) / tsc[6];
+
+  host_video_normalize_ts(x1024, y1024);
+
+  return 0;
+}
 
 int host_init(void)
 {
   in_init();
   host_init_input();
   in_probe();
+  host_ts_init();
 
   return 0;
 }
index 7885372..3a0205f 100644 (file)
@@ -165,7 +165,7 @@ void g_fprintf(int fd, const char *fmt, ...)
 
     zeropad = *s == '0';
     justify = parse_dec(&s);
-    if (*s == 'l')
+    if (*s == 'l' || *s == 'z')
       s++; // ignore for now
     if (*s == 's') {
       char *ns = va_arg(ap, char *);
index c5b0a09..3d0d0cc 100644 (file)
@@ -41,6 +41,8 @@ static const struct dev_fd_t takeover_devs[] = {
   { "/dev/mmuhack", FAKEDEV_MMUHACK },
   { "/dev/tty",     FAKEDEV_TTY0 },
   { "/dev/tty0",    FAKEDEV_TTY0 },
+  { "/dev/touchscreen/wm97xx", FAKEDEV_WM97XX },
+  { "/etc/pointercal",         FAKEDEV_WM97XX_P },
 #ifdef PND
   { "/dev/input/event*", -1 }, // hide for now, may cause dupe events
 #endif
@@ -137,12 +139,12 @@ long w_read_raw(int fd, void *buf, size_t count)
 {
   long ret;
 
-  if (fd == FAKEDEV_GPIO)
-    ret = emu_read_gpiodev(buf, count);
+  if (FAKEDEV_MEM <= fd && fd < FAKEDEV_FD_BOUNDARY)
+    ret = emu_do_read(fd, buf, count);
   else
     ret = g_read_raw(fd, buf, count);
 
-  //strace("read(%d, %p, %ld) = %ld\n", fd, buf, count, ret);
+  //strace("read(%d, %p, %zd) = %ld\n", fd, buf, count, ret);
   return ret;
 }