From acce7d8e05ac38776d6340342f6a7868df4f7f28 Mon Sep 17 00:00:00 2001
From: Uros Majstorovic <majstor@majstor.org>
Date: Sun, 28 Nov 2021 23:53:05 +0100
Subject: lcd driver added; fixed startup code;

---
 fw/fe310/eos/eve/eve.c          | 209 ++++++++++++++++++++++------------------
 fw/fe310/eos/eve/eve.h          |   9 +-
 fw/fe310/eos/eve/eve_config.h   |  63 ++++++------
 fw/fe310/eos/eve/eve_def.h      |   2 +-
 fw/fe310/eos/eve/eve_platform.h |   5 +
 fw/fe310/eos/eve/eve_touch.c    |  30 +++---
 fw/fe310/eos/eve/eve_touch.h    |   5 +-
 7 files changed, 172 insertions(+), 151 deletions(-)

(limited to 'fw/fe310/eos/eve')

diff --git a/fw/fe310/eos/eve/eve.c b/fw/fe310/eos/eve/eve.c
index 3447d6b..8cca34b 100644
--- a/fw/fe310/eos/eve/eve.c
+++ b/fw/fe310/eos/eve/eve.c
@@ -254,15 +254,23 @@ void eve_cmd_dl(uint32_t dl) {
 
 int eve_cmd_done(void) {
     uint16_t r = eve_read16(REG_CMD_READ);
+
     if (r == 0xfff) {
+        uint16_t ptr;
+
         cmd_offset = 0;
+        ptr = eve_read16(REG_COPRO_PATCH_PTR);
         eve_write8(REG_CPURESET, 1);
         eve_write16(REG_CMD_READ, 0);
         eve_write16(REG_CMD_WRITE, 0);
         eve_write16(REG_CMD_DL, 0);
         eve_write8(REG_CPURESET, 0);
-        return -1;
+        eve_write16(REG_COPRO_PATCH_PTR, ptr);
+        eve_write8(REG_PCLK, EVE_PCLK);
+
+        return EVE_ERR;
     }
+
     return (r == cmd_offset);
 }
 
@@ -270,8 +278,10 @@ int eve_cmd_exec(int w) {
     eve_write16(REG_CMD_WRITE, cmd_offset);
     if (w) {
         int r;
+
         do {
             r = eve_cmd_done();
+            if (r < 0) break;
         } while (!r);
         if (r < 0) return EVE_ERR;
     }
@@ -293,92 +303,17 @@ void eve_cmd_burst_end(void) {
     cmd_burst = 0;
 }
 
-int eve_gpio_get(int gpio) {
-    uint16_t reg = eve_read16(REG_GPIOX);
-    return !!(reg & (1 << gpio));
-}
-
-void eve_gpio_set(int gpio, int val) {
-    uint16_t reg = eve_read16(REG_GPIOX);
-    uint16_t reg_val = (1 << gpio);
-    if (val) {
-        reg |= reg_val;
-    } else {
-        reg &= ~reg_val;
-    }
-    eve_write16(REG_GPIOX, reg);
-}
-
-uint8_t eve_gpio_get_dir(void) {
-    uint16_t reg = eve_read16(REG_GPIOX_DIR);
-    return reg & 0x000f;
-}
-
-void eve_gpio_set_dir(uint8_t dir) {
-    uint16_t reg = eve_read16(REG_GPIOX_DIR);
-    reg &= 0xfff0;
-    reg |= dir & 0x0f;
-    eve_write16(REG_GPIOX_DIR, reg);
-}
-
-void eve_active(void) {
-    uint16_t gpiox;
-
-    eve_command(EVE_ACTIVE, 0);
-
-    if (power_state == EVE_PSTATE_SLEEP) {
-        eve_time_sleep(40);
-        eve_touch_active();
-    }
-
-    gpiox = eve_read16(REG_GPIOX) | 0x8000;
-    eve_write16(REG_GPIOX, gpiox);
-
-    power_state = EVE_PSTATE_ACTIVE;
-}
-
-void eve_standby(void) {
-    uint16_t gpiox;
-
-    if (power_state != EVE_PSTATE_ACTIVE) return;
-
-    gpiox = eve_read16(REG_GPIOX) & ~0x8000;
-    eve_write16(REG_GPIOX, gpiox);
-
-    eve_command(EVE_STANDBY, 0);
-
-    power_state = EVE_PSTATE_STANDBY;
-}
-
-void eve_sleep(void) {
-    uint16_t gpiox;
-
-    if (power_state != EVE_PSTATE_ACTIVE) return;
-
-    gpiox = eve_read16(REG_GPIOX) & ~0x8000;
-    eve_write16(REG_GPIOX, gpiox);
-
-    eve_touch_sleep();
-
-    eve_command(EVE_SLEEP, 0);
-
-    power_state = EVE_PSTATE_SLEEP;
-}
-
-void eve_brightness(uint8_t b) {
-    eve_write8(REG_PWM_DUTY, b);
-}
-
-static int _init(int touch_calibrate, uint32_t *touch_matrix, uint8_t gpio_dir) {
+static int _init(uint8_t gpio_dir) {
     uint8_t chipid = 0;
     uint8_t reset = 0x07;
     uint16_t timeout;
 
-    eve_command(EVE_CORERST, 0);
+    eve_command(EVE_CORERST, 0);        /* reset */
+
     eve_command(EVE_CLKEXT, 0);
     eve_command(EVE_CLKSEL, 0x46);      /* set clock to 72 MHz */
     eve_command(EVE_ACTIVE, 0);         /* start EVE */
-    eve_time_sleep(40);
+    eve_time_sleep(4);
 
     timeout = 0;
     while (chipid != 0x7c) {            /* if chipid is not 0x7c, continue to read it until it is, EVE needs a moment for it's power on self-test and configuration */
@@ -399,23 +334,23 @@ static int _init(int touch_calibrate, uint32_t *touch_matrix, uint8_t gpio_dir)
     eve_write32(REG_FREQUENCY, 72000000);   /* tell EVE that we changed the frequency from default to 72MHz for BT8xx */
 
     eve_write8(REG_PWM_DUTY, 0x00);
+    eve_write16(REG_GPIOX, 0x0000);
     eve_write16(REG_GPIOX_DIR, 0x8000 | (gpio_dir & 0x0f));
-    eve_write16(REG_GPIOX, 0x8000);
 
     /* initialize display */
     eve_write16(REG_HCYCLE,  EVE_HCYCLE);   /* total number of clocks per line, incl front/back porch */
     eve_write16(REG_HOFFSET, EVE_HOFFSET);  /* start of active line */
     eve_write16(REG_HSYNC0,  EVE_HSYNC0);   /* start of horizontal sync pulse */
     eve_write16(REG_HSYNC1,  EVE_HSYNC1);   /* end of horizontal sync pulse */
+    eve_write16(REG_HSIZE,   EVE_HSIZE);    /* active display width */
     eve_write16(REG_VCYCLE,  EVE_VCYCLE);   /* total number of lines per screen, including pre/post */
     eve_write16(REG_VOFFSET, EVE_VOFFSET);  /* start of active screen */
     eve_write16(REG_VSYNC0,  EVE_VSYNC0);   /* start of vertical sync pulse */
     eve_write16(REG_VSYNC1,  EVE_VSYNC1);   /* end of vertical sync pulse */
+    eve_write16(REG_VSIZE,   EVE_VSIZE);    /* active display height */
     eve_write8(REG_SWIZZLE,  EVE_SWIZZLE);  /* FT8xx output to LCD - pin order */
     eve_write8(REG_PCLK_POL, EVE_PCLKPOL);  /* LCD data is clocked in on this PCLK edge */
     eve_write8(REG_CSPREAD,  EVE_CSPREAD);  /* helps with noise, when set to 1 fewer signals are changed simultaneously, reset-default: 1 */
-    eve_write16(REG_HSIZE,   EVE_HSIZE);    /* active display width */
-    eve_write16(REG_VSIZE,   EVE_VSIZE);    /* active display height */
 
     /* do not set PCLK yet - wait for just after the first display list */
 
@@ -431,33 +366,115 @@ static int _init(int touch_calibrate, uint32_t *touch_matrix, uint8_t gpio_dir)
     eve_dl_write(DISPLAY());
     eve_dl_swap();
 
-    /* nothing is being displayed yet... the pixel clock is still 0x00 */
-    eve_write16(REG_GPIOX, 0x8000);         /* enable the DISP signal to the LCD panel, it is set to output in REG_GPIOX_DIR by default */
-    eve_write8(REG_PCLK, EVE_PCLK);         /* now start clocking data to the LCD panel */
-
-    eve_cmd(CMD_SETROTATE, "w", 2);
+#ifdef EVE_PCLK_FREQ
+    eve_cmd(CMD_PCLKFREQ, "www", EVE_PCLK_FREQ, 0, 0);
     eve_cmd_exec(1);
+#endif
+    /* nothing is being displayed yet... the pixel clock is still 0x00 */
 
     return EVE_OK;
 }
 
 int eve_init(uint8_t wakeup_cause, int touch_calibrate, uint32_t *touch_matrix, uint8_t gpio_dir) {
-    int rst = (wakeup_cause == EOS_PWR_WAKE_RST);
-
-    eve_spi_start();
+    int rst = (wakeup_cause == EVE_INIT_RST);
 
     if (rst) {
-        int rv = _init(touch_calibrate, touch_matrix, gpio_dir);
+        int rv = _init(gpio_dir);
         if (rv) return rv;
     } else {
-        power_state = EVE_PSTATE_SLEEP;
-        eve_active();
+        eve_command(EVE_ACTIVE, 0);
+        eve_time_sleep(40);
     }
 
     eve_touch_init(wakeup_cause, touch_calibrate, touch_matrix);
     eve_platform_init();
 
-    eve_spi_stop();
-
     return EVE_OK;
 }
+
+void eve_start(uint8_t wakeup_cause) {
+    uint16_t gpiox;
+
+    gpiox = eve_read16(REG_GPIOX) | 0x8000;
+    eve_write16(REG_GPIOX, gpiox);          /* enable the DISP signal to the LCD panel, it is set to output in REG_GPIOX_DIR by default */
+    eve_write8(REG_PCLK, EVE_PCLK);         /* now start clocking data to the LCD panel */
+
+    eve_touch_start(wakeup_cause);
+}
+
+void eve_stop(void) {
+    uint16_t gpiox;
+
+    eve_touch_stop();
+
+    gpiox = eve_read16(REG_GPIOX) & ~0x8000;
+    eve_write16(REG_GPIOX, gpiox);
+    eve_write8(REG_PCLK, 0);
+}
+
+int eve_gpio_get(int gpio) {
+    uint16_t reg = eve_read16(REG_GPIOX);
+    return !!(reg & (1 << gpio));
+}
+
+void eve_gpio_set(int gpio, int val) {
+    uint16_t reg = eve_read16(REG_GPIOX);
+    uint16_t reg_val = (1 << gpio);
+    if (val) {
+        reg |= reg_val;
+    } else {
+        reg &= ~reg_val;
+    }
+    eve_write16(REG_GPIOX, reg);
+}
+
+uint8_t eve_gpio_get_dir(void) {
+    uint16_t reg = eve_read16(REG_GPIOX_DIR);
+    return reg & 0x000f;
+}
+
+void eve_gpio_set_dir(uint8_t dir) {
+    uint16_t reg = eve_read16(REG_GPIOX_DIR);
+    reg &= 0xfff0;
+    reg |= dir & 0x0f;
+    eve_write16(REG_GPIOX_DIR, reg);
+}
+
+void eve_standby(void) {
+    uint16_t gpiox;
+
+    if (power_state != EVE_PSTATE_ACTIVE) return;
+
+    eve_command(EVE_STANDBY, 0);
+
+    power_state = EVE_PSTATE_STANDBY;
+}
+
+void eve_sleep(void) {
+    uint16_t gpiox;
+
+    if (power_state != EVE_PSTATE_ACTIVE) return;
+
+    eve_stop();
+
+    eve_command(EVE_SLEEP, 0);
+
+    power_state = EVE_PSTATE_SLEEP;
+}
+
+void eve_active(void) {
+    uint16_t gpiox;
+
+    eve_command(EVE_ACTIVE, 0);
+
+    if (power_state == EVE_PSTATE_SLEEP) {
+        eve_time_sleep(40);
+        eve_start(0);
+    }
+
+    power_state = EVE_PSTATE_ACTIVE;
+}
+
+void eve_brightness(uint8_t b) {
+    eve_write8(REG_PWM_DUTY, b);
+}
diff --git a/fw/fe310/eos/eve/eve.h b/fw/fe310/eos/eve/eve.h
index 11d59cd..363905c 100644
--- a/fw/fe310/eos/eve/eve.h
+++ b/fw/fe310/eos/eve/eve.h
@@ -56,15 +56,16 @@ int eve_cmd_exec(int w);
 void eve_cmd_burst_start(void);
 void eve_cmd_burst_end(void);
 
+int eve_init(uint8_t wakeup_cause, int touch_calibrate, uint32_t *touch_matrix, uint8_t gpio_dir);
+void eve_start(uint8_t wakeup_cause);
+void eve_stop(void);
+
 int eve_gpio_get(int gpio);
 void eve_gpio_set(int gpio, int val);
 uint8_t eve_gpio_get_dir(void);
 void eve_gpio_set_dir(uint8_t dir);
 
-void eve_active(void);
 void eve_standby(void);
 void eve_sleep(void);
-void eve_wake(void);
+void eve_active(void);
 void eve_brightness(uint8_t b);
-
-int eve_init(uint8_t wakeup_cause, int touch_calibrate, uint32_t *touch_matrix, uint8_t gpio_dir);
diff --git a/fw/fe310/eos/eve/eve_config.h b/fw/fe310/eos/eve/eve_config.h
index b0dd1a4..b151c63 100755
--- a/fw/fe310/eos/eve/eve_config.h
+++ b/fw/fe310/eos/eve/eve_config.h
@@ -1,37 +1,38 @@
 #ifndef EVE_CONFIG_H_
 #define EVE_CONFIG_H_
 
-/* my display */
-
-#define EVE_TH      1200L
-#define EVE_THD     800L
-#define EVE_THF     210L
-#define EVE_THP     20L
-#define EVE_THB     46L
-
-#define EVE_TV      650L
-#define EVE_TVD     480L
-#define EVE_TVF     22L
-#define EVE_TVP     12L
-#define EVE_TVB     23L
-
-
-#define EVE_HSIZE           (EVE_THD)                       /* Thd Length of visible part of line (in PCLKs) - display width */
-#define EVE_HSYNC0          (EVE_THF)                       /* Thf Horizontal Front Porch */
-#define EVE_HSYNC1          (EVE_THF + EVE_THP)             /* Thf + Thp Horizontal Front Porch plus Hsync Pulse width */
-#define EVE_HOFFSET         (EVE_THF + EVE_THP + EVE_THB)   /* Thf + Thp + Thb Length of non-visible part of line (in PCLK cycles) */
-#define EVE_HCYCLE          (EVE_TH)                        /* Th Total length of line (visible and non-visible) (in PCLKs) */
-
-#define EVE_VSIZE           (EVE_TVD)                       /* Tvd Number of visible lines (in lines) - display height */
-#define EVE_VSYNC0          (EVE_TVF)                       /* Tvf Vertical Front Porch */
-#define EVE_VSYNC1          (EVE_TVF + EVE_TVP)             /* Tvf + Tvp Vertical Front Porch plus Vsync Pulse width */
-#define EVE_VOFFSET         (EVE_TVF + EVE_TVP + EVE_TVB)   /* Tvf + Tvp + Tvb Number of non-visible lines (in lines) */
-#define EVE_VCYCLE          (EVE_TV)                        /* Tv Total number of lines (visible and non-visible) (in lines) */
-
-#define EVE_PCLKPOL         (1L)                            /* PCLK polarity (0 = rising edge, 1 = falling edge) */
-#define EVE_SWIZZLE         (0L)                            /* Defines the arrangement of the RGB pins of the FT800 */
-#define EVE_PCLK            (1L)                            /* 60MHz / REG_PCLK = PCLK frequency - 30 MHz */
-#define EVE_CSPREAD         (0L)                            /* helps with noise, when set to 1 fewer signals are changed simultaneously, reset-default: 1 */
+/* FocusLCDs E50RG84885LWAM520-CA */
+
+#define EVE_HLPW    20      /* horizontal low pulse width */
+#define EVE_HBP     60      /* horizontal back porch */
+#define EVE_HFP     40      /* horizontal front porch */
+#define EVE_HACT    480     /* horizontal active pixels */
+#define EVE_HTOT    (EVE_HLPW + EVE_HBP + EVE_HFP + EVE_HACT + 10)
+
+
+#define EVE_VLPW    26      /* vertical low pulse width */
+#define EVE_VBP     50      /* vertical back porch */
+#define EVE_VFP     30      /* vertical front porch */
+#define EVE_VACT    854     /* vertical active pixels */
+#define EVE_VTOT    (EVE_VLPW + EVE_VBP + EVE_VFP + EVE_VACT + 10)
+
+#define EVE_HCYCLE          (EVE_HTOT)                      /* Th Total length of line (visible and non-visible) (in PCLKs) */
+#define EVE_HSIZE           (EVE_HACT)                      /* Length of visible part of line (in PCLKs) - display width */
+#define EVE_HOFFSET         (EVE_HFP + EVE_HLPW + EVE_HBP)  /* Length of non-visible part of line (in PCLK cycles) */
+#define EVE_HSYNC0          (EVE_HFP)                       /* Horizontal Front Porch */
+#define EVE_HSYNC1          (EVE_HFP + EVE_HLPW)            /* Horizontal Front Porch plus Hsync Pulse width */
+
+#define EVE_VCYCLE          (EVE_VTOT)                      /* Total number of lines (visible and non-visible) (in lines) */
+#define EVE_VSIZE           (EVE_VACT)                      /* Number of visible lines (in lines) - display height */
+#define EVE_VOFFSET         (EVE_VFP + EVE_VLPW + EVE_VBP)  /* Number of non-visible lines (in lines) */
+#define EVE_VSYNC0          (EVE_VFP)                       /* Vertical Front Porch */
+#define EVE_VSYNC1          (EVE_VFP + EVE_VLPW)            /* Vertical Front Porch plus Vsync Pulse width */
+
+#define EVE_PCLKPOL         1                               /* PCLK polarity (0 = rising edge, 1 = falling edge) */
+#define EVE_SWIZZLE         0                               /* Defines the arrangement of the RGB pins */
+#define EVE_CSPREAD         0                               /* helps with noise, when set to 1 fewer signals are changed simultaneously, reset-default: 1 */
+
+#define EVE_PCLK            2                               /* 36 MHz */
 
 #define EVE_GEN             4
 
diff --git a/fw/fe310/eos/eve/eve_def.h b/fw/fe310/eos/eve/eve_def.h
index e607320..2f7e0b7 100755
--- a/fw/fe310/eos/eve/eve_def.h
+++ b/fw/fe310/eos/eve/eve_def.h
@@ -695,7 +695,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH
 #define REG_FLASH_STATUS        0x3025f0UL
 #define REG_FLASH_SIZE          0x309024UL
 #define REG_PLAY_CONTROL        0x30914eUL
-#define REG_COPRO_PATCH_DTR     0x309162UL
+#define REG_COPRO_PATCH_PTR     0x309162UL
 
 
 /* BT81x graphics engine specific macros */
diff --git a/fw/fe310/eos/eve/eve_platform.h b/fw/fe310/eos/eve/eve_platform.h
index 83c1799..587e1cf 100644
--- a/fw/fe310/eos/eve/eve_platform.h
+++ b/fw/fe310/eos/eve/eve_platform.h
@@ -2,6 +2,7 @@
 
 #include "spi.h"
 #include "spi_dev.h"
+#include "power.h"
 #include "timer.h"
 
 #define EVE_ETYPE_INTR      1
@@ -11,6 +12,10 @@
 #define EVE_SPI_FLAG_BSWAP  EOS_SPI_FLAG_BSWAP
 #define EVE_SPI_FLAG_TX     EOS_SPI_FLAG_TX
 
+#define EVE_INIT_RST        EOS_INIT_RST
+#define EVE_INIT_RTC        EOS_INIT_RTC
+#define EVE_INIT_BTN        EOS_INIT_BTN
+
 void *eve_malloc(size_t);
 void eve_free(void *);
 
diff --git a/fw/fe310/eos/eve/eve_touch.c b/fw/fe310/eos/eve/eve_touch.c
index 035e122..fc9d040 100644
--- a/fw/fe310/eos/eve/eve_touch.c
+++ b/fw/fe310/eos/eve/eve_touch.c
@@ -300,28 +300,16 @@ void eve_handle_time(void) {
     }
 }
 
-void eve_touch_active(void) {
-    eve_write8(REG_TOUCH_MODE, EVE_TMODE_CONTINUOUS);
-}
-
-void eve_touch_sleep(void) {
-    eve_write8(REG_TOUCH_MODE, EVE_TMODE_OFF);
-}
-
 static void _init(int touch_calibrate, uint32_t *touch_matrix) {
     /* configure touch */
-    eve_write16(REG_TOUCH_CONFIG, 0x381);                   /* default */
-    eve_write8(REG_TOUCH_MODE, EVE_TMODE_CONTINUOUS);       /* enable touch */
+    eve_write8(REG_CPURESET, 2);                            /* touch engine reset */
+    eve_write16(REG_TOUCH_CONFIG, 0x4000);                  /* host mode multi touch */
+    eve_write8(REG_CPURESET, 0);                            /* clear reset */
 
     if (touch_calibrate) {
         eve_write8(REG_PWM_DUTY, 0x40);
-        eve_cmd_dl(CMD_DLSTART);
-        eve_cmd_dl(CLEAR_COLOR_RGB(0,0,0));
-        eve_cmd_dl(CLEAR(1,1,1));
         eve_cmd(CMD_TEXT, "hhhhs", EVE_HSIZE/2, EVE_VSIZE/2, 27, EVE_OPT_CENTER, "Please tap on the dot.");
         eve_cmd(CMD_CALIBRATE, "w", 0);
-        eve_cmd_dl(DISPLAY());
-        eve_cmd_dl(CMD_SWAP);
         eve_cmd_exec(1);
         eve_write8(REG_PWM_DUTY, 0);
 
@@ -340,7 +328,7 @@ static void _init(int touch_calibrate, uint32_t *touch_matrix) {
         eve_write32(REG_TOUCH_TRANSFORM_F, touch_matrix[5]);
     }
 
-    eve_write8(REG_CTOUCH_EXTENDED, 0x00);
+    eve_write8(REG_CTOUCH_EXTENDED, 0x00);                  /* set extended mode */
 
     /* configure interrupts */
     eve_write8(REG_INT_MASK, touch_intr_mask);
@@ -349,7 +337,7 @@ static void _init(int touch_calibrate, uint32_t *touch_matrix) {
 }
 
 void eve_touch_init(uint8_t wakeup_cause, int touch_calibrate, uint32_t *touch_matrix) {
-    int rst = (wakeup_cause == EOS_PWR_WAKE_RST);
+    int rst = (wakeup_cause == EVE_INIT_RST);
     int i;
 
     eve_vtrack_init();
@@ -362,6 +350,14 @@ void eve_touch_init(uint8_t wakeup_cause, int touch_calibrate, uint32_t *touch_m
     if (rst) _init(touch_calibrate, touch_matrix);
 }
 
+void eve_touch_start(uint8_t wakeup_cause) {
+    eve_write8(REG_TOUCH_MODE, EVE_TMODE_CONTINUOUS);
+}
+
+void eve_touch_stop(void) {
+    eve_write8(REG_TOUCH_MODE, EVE_TMODE_OFF);
+}
+
 void eve_touch_set_handler(eve_touch_handler_t handler, void *param) {
     touch_handler = handler;
     touch_handler_param = param;
diff --git a/fw/fe310/eos/eve/eve_touch.h b/fw/fe310/eos/eve/eve_touch.h
index 074d37a..b6ca6d9 100644
--- a/fw/fe310/eos/eve/eve_touch.h
+++ b/fw/fe310/eos/eve/eve_touch.h
@@ -101,9 +101,10 @@ typedef void (*eve_touch_handler_t) (EVETouch *, uint16_t, uint8_t, void *);
 void eve_handle_touch(void);
 void eve_handle_time(void);
 
-void eve_touch_active(void);
-void eve_touch_sleep(void);
 void eve_touch_init(uint8_t wakeup_cause, int touch_calibrate, uint32_t *touch_matrix);
+void eve_touch_start(uint8_t wakeup_cause);
+void eve_touch_stop(void);
+
 void eve_touch_set_handler(eve_touch_handler_t handler, void *handler_param);
 EVETouch *eve_touch_get(int i);
 int8_t eve_touch_get_idx(EVETouch *touch);
-- 
cgit v1.2.3