Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src-draft/trunk]: src/sys/dev/i2c WIP: goodixts(4): New driver for Goodix to...



details:   https://anonhg.NetBSD.org/src-all/rev/f7ed97d7313b
branches:  trunk
changeset: 949386:f7ed97d7313b
user:      Taylor R Campbell <riastradh%NetBSD.org@localhost>
date:      Mon Dec 21 16:39:27 2020 +0000

description:
WIP: goodixts(4): New driver for Goodix touchscreens.

Found on the pinephone.  Doesn't work yet.

diffstat:

 sys/arch/evbarm/conf/GENERIC64 |    1 +
 sys/dev/i2c/axppmic.c          |    6 +
 sys/dev/i2c/files.i2c          |    5 +
 sys/dev/i2c/goodixts.c         |  725 +++++++++++++++++++++++++++++++++++++++++
 4 files changed, 737 insertions(+), 0 deletions(-)

diffs (truncated from 775 to 300 lines):

diff -r cc8aea39bf2e -r f7ed97d7313b sys/arch/evbarm/conf/GENERIC64
--- a/sys/arch/evbarm/conf/GENERIC64    Tue Dec 01 06:55:48 2020 +0000
+++ b/sys/arch/evbarm/conf/GENERIC64    Mon Dec 21 16:39:27 2020 +0000
@@ -317,6 +317,7 @@
 rkpmic*                at iic?                 # Rockchip Power Management IC
 rkreg*         at rkpmic?
 tcagpio*       at iic?
+goodixts*      at iic?                 # Goodix touchscreen
 
 # Random number generators
 amdccp*                at fdt?                 # AMD Cryptograhic Coprocessor RNG
diff -r cc8aea39bf2e -r f7ed97d7313b sys/dev/i2c/axppmic.c
--- a/sys/dev/i2c/axppmic.c     Tue Dec 01 06:55:48 2020 +0000
+++ b/sys/dev/i2c/axppmic.c     Mon Dec 21 16:39:27 2020 +0000
@@ -164,6 +164,8 @@
          .c_enable_reg = (ereg), .c_enable_mask = (emask),             \
          .c_enable_val = (emask), .c_disable_val = 0 }
 
+/* https://files.pine64.org/doc/datasheet/pine64/AXP803_Datasheet_V1.0.pdf */
+
 static const struct axppmic_ctrl axp803_ctrls[] = {
        AXP_CTRL("dldo1", 700, 3300, 100,
                0x12, __BIT(3), 0x15, __BITS(4,0)),
@@ -201,6 +203,10 @@
                0x13, __BIT(6), 0x29, __BITS(4,0)),
        AXP_CTRL("aldo3", 700, 3300, 100,
                0x13, __BIT(7), 0x2a, __BITS(4,0)),
+       AXP_CTRL_IO("ldo-io0", 700, 3300, 100,
+               0x90, __BITS(2,0), 0x3, 0x7, 0x91, __BITS(4,0)),
+       AXP_CTRL_IO("ldo-io1", 700, 3300, 100,
+               0x92, __BITS(2,0), 0x3, 0x7, 0x93, __BITS(4,0)),
 };
 
 static const struct axppmic_ctrl axp805_ctrls[] = {
diff -r cc8aea39bf2e -r f7ed97d7313b sys/dev/i2c/files.i2c
--- a/sys/dev/i2c/files.i2c     Tue Dec 01 06:55:48 2020 +0000
+++ b/sys/dev/i2c/files.i2c     Mon Dec 21 16:39:27 2020 +0000
@@ -400,3 +400,8 @@
 device pcf8574io: leds, sysmon_envsys
 attach pcf8574io at iic
 file   dev/i2c/pcf8574.c                       pcf8574io
+
+# Goodix touchscreen driver
+device goodixts: fdt, wsmousedev, tpcalib
+attach goodixts at iic
+file   dev/i2c/goodixts.c                      goodixts
diff -r cc8aea39bf2e -r f7ed97d7313b sys/dev/i2c/goodixts.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/dev/i2c/goodixts.c    Mon Dec 21 16:39:27 2020 +0000
@@ -0,0 +1,725 @@
+/*     $NetBSD$        */
+
+/*-
+ * Copyright (c) 2020 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Goodix touchscreen driver
+ *
+ * https://files.pine64.org/doc/datasheet/pinephone/GT917S-Datasheet.pdf
+ * http://dl.linux-sunxi.org/touchscreen/GT928%20Datashet%20English.pdf
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD$");
+
+#include <sys/param.h>
+#include <sys/types.h>
+
+#include <sys/atomic.h>
+#include <sys/kernel.h>
+#include <sys/proc.h>
+#include <sys/sysctl.h>
+#include <sys/workqueue.h>
+
+#include <dev/fdt/fdtvar.h>
+
+#include <dev/i2c/i2cvar.h>
+
+#include <dev/wscons/tpcalibvar.h>
+#include <dev/wscons/wsconsio.h>
+#include <dev/wscons/wsmousevar.h>
+
+#define        GOODIXTS_CMD            0x8040
+#define         GOODIXTS_CMD_READ_COORD        0
+#define         GOODIXTS_CMD_READ_DIFF_RAW     1
+#define         GOODIXTS_CMD_SOFTWARE_RESET    2
+#define         GOODIXTS_CMD_BASELINE_UPDATE   3
+#define         GOODIXTS_CMD_BASELINE_CALIB    4
+#define         GOODIXTS_CMD_SCREEN_OFF        5
+#define        GOODIXTS_PROXIMITY_EN   0x8042
+#define        GOODIXTS_GT9X_CONFIG    0x8047
+#define        GOODIXTS_GT1X_CONFIG    0x8050
+#define         GOODIXTS_CONFIG_LEN_GT917S     240
+#define         GOODIXTS_CONFIG_MAX_LEN        240
+#define        GOODIXTS_ID             0x8140
+#define         GOODIXTS_ID_LEN                6
+#define        GOODIXTS_REPORT         0x814e
+
+struct goodixts_config {
+       uint8_t version;
+       uint8_t x_max_le[2];
+       uint8_t y_max_le[2];
+       uint8_t touch_number;
+#define        TOUCH_NUMBER_TOUCHNO            __BITS(0,3)
+       uint8_t module_switch1;
+#define        MODULE_SWITCH1_TRIGGER          __BITS(0,1)
+#define         MODULE_SWITCH1_TRIGGER_RISING          0
+#define         MODULE_SWITCH1_TRIGGER_FALLING         1
+#define         MODULE_SWITCH1_TRIGGER_LOW             2
+#define         MODULE_SWITCH1_TRIGGER_HIGH            3
+#define        MODULE_SWITCH1_SITO             __BIT(2)
+#define        MODULE_SWITCH1_X2Y              __BIT(3)
+#define        MODULE_SWITCH1_STRETCH_RANK     __BITS(3,4)
+       uint8_t module_switch2;
+#define        MODULE_SWITCH2_TOUCHKEY         __BIT(0)
+       uint8_t shake_count;
+#define        SHAKE_COUNT_FINGERSHAKECOUNT    __BITS(0,3)
+       uint8_t filter;
+#define        FILTER_NORMAL                   __BITS(0,5)
+#define        FILTER_FIRST                    __BITS(6,7)
+       uint8_t large_touch;
+       uint8_t noise_reduction;
+#define        NOISE_REDUCTION_VALUE           __BITS(0,4)
+       uint8_t screen_touch_level;
+       uint8_t screen_leave_level;
+       uint8_t low_power_control;
+#define        LOW_POWER_CONTROL_TIME          __BITS(0,3)
+       uint8_t refresh_rate;
+#define        REFRESH_RATE_P5MS               __BITS(0,3)
+       uint8_t x_threshold_reserved;
+       uint8_t y_threshold_reserved;
+       uint8_t x_speed_limit_reserved;
+       uint8_t y_speed_limit_reserved;
+       uint8_t spacev;
+#define        SPACEV_BLANK_BOTTOM             __BITS(0,3)
+#define        SPACEV_BLANK_TOP                __BITS(4,7)
+       uint8_t spaceh;
+#define        SPACEH_BLANK_RIGHT              __BITS(0,3)
+#define        SPACEH_BLANK_LEFT               __BITS(4,7)
+       uint8_t stretch_rate_reserved;
+       uint8_t stretch_r0;
+       uint8_t stretch_r1;
+       uint8_t stretch_r2;
+       uint8_t stretch_rm;
+       uint8_t drv_groupA_num;
+#define        DRV_GROUPA_NUM_NUM              __BITS(0,4)
+#define        DRV_GROUPA_NUM_ALL              __BIT(7)
+       uint8_t drv_groupB_num;
+#define        DRV_GROUPB_NUM_NUM              __BITS(0,4)
+#define        DRV_GROUPB_NUM_DUAL_FREQ        __BIT(5)
+       uint8_t sensor_num;
+#define        SENSOR_NUM_GROUPA               __BITS(0,3)
+#define        SENSOR_NUM_GROUPB               __BITS(4,7)
+       uint8_t freqA_factor;
+       uint8_t freqB_factor;
+       uint8_t panel_bitfreq_le[2];
+       uint8_t panel_sensor_time_reserved[2];
+       uint8_t panel_tx_gain;
+#define        PANEL_TX_GAIN_DAC_GAIN          __BITS(0,2)
+#define        PANEL_TX_GAIN_DRV_OUTPUT_R      __BITS(3,4)
+       /* ok, I'm bored transcribing these, several pages more */
+};
+CTASSERT(sizeof(struct goodixts_config) == 0x806c - 0x8047);
+CTASSERT(sizeof(struct goodixts_config) <= GOODIXTS_CONFIG_MAX_LEN);
+
+static const struct {
+       int     type;
+       char    name[12];
+} intr_trigger[] = {
+       [0] = { FDT_INTR_TYPE_POS_EDGE, "pos-edge" },
+       [1] = { FDT_INTR_TYPE_NEG_EDGE, "neg-edge" },
+       [2] = { FDT_INTR_TYPE_LOW_LEVEL, "low-level" },
+       [3] = { FDT_INTR_TYPE_HIGH_LEVEL, "high-level" },
+};
+
+struct goodixts_softc {
+       device_t                sc_dev;
+       i2c_tag_t               sc_i2c;
+       i2c_addr_t              sc_addr;
+       int                     sc_phandle;
+
+       struct fdtbus_regulator *sc_avdd28;
+       struct fdtbus_regulator *sc_vddio;
+       uint32_t                sc_x, sc_y;
+
+       char                    sc_id[4 + 1];
+       uint16_t                sc_version;
+       const struct goodixts_model *sc_model;
+       union {
+               struct goodixts_config  c;
+               uint8_t                 buf[GOODIXTS_CONFIG_MAX_LEN];
+       }                       sc_config;
+
+       struct workqueue        *sc_wq;
+       struct work             sc_work;
+       volatile unsigned       sc_work_pending;
+
+       unsigned                sc_intr_specifier[2];
+       void                    *sc_ih;
+
+       struct {
+               struct sysctllog        *log;
+               const struct sysctlnode *root;
+       }                       sc_sysctl;
+
+       struct tpcalib_softc    sc_tpcalib;
+       device_t                sc_wsmousedev;
+};
+
+static const struct goodixts_model {
+       const char      gm_id[4 + 1];
+       uint8_t         gm_config_len;
+       uint16_t        gm_config_reg;
+} goodixts_models[] = {
+       { "917S", 240, GOODIXTS_GT9X_CONFIG },
+};
+
+static int goodixts_match(device_t, cfdata_t, void *);
+static void goodixts_attach(device_t, device_t, void *);
+static int goodixts_detach(device_t, int);
+static void goodixts_childdet(device_t, device_t);
+
+static int goodixts_read(struct goodixts_softc *, uint16_t, void *, size_t);
+static int goodixts_write_8(struct goodixts_softc *, uint16_t, uint8_t);
+
+static int goodixts_reset(struct goodixts_softc *);
+
+static void goodixts_sysctl_attach(struct goodixts_softc *);
+static void goodixts_sysctl_detach(struct goodixts_softc *);
+
+static int goodixts_enable(void *);
+static void goodixts_disable(void *);
+static int goodixts_ioctl(void *, unsigned long, void *, int, struct lwp *);
+
+static uint8_t goodixts_keycode(const uint8_t *, unsigned);
+
+static int goodixts_intr(void *);
+static void goodixts_work(struct work *, void *);
+
+static const struct wsmouse_accessops goodixts_accessops = {
+       .enable = goodixts_enable,
+       .disable = goodixts_disable,
+       .ioctl = goodixts_ioctl,
+};
+
+CFATTACH_DECL2_NEW(goodixts, sizeof(struct goodixts_softc),
+    goodixts_match, goodixts_attach, goodixts_detach, NULL, NULL,
+    goodixts_childdet);
+
+static const struct device_compatible_entry compat_data[] = {
+       { "goodix,gt917s", 0 },
+       { NULL, 0 },
+};
+
+static int
+goodixts_match(device_t parent, cfdata_t match, void *aux)
+{
+       const struct i2c_attach_args *ia = aux;
+       int match_result;
+
+       if (iic_use_direct_match(ia, match, compat_data, &match_result))
+               return match_result;
+       return 0;
+}
+
+static void
+goodixts_attach(device_t parent, device_t self, void *aux)
+{
+       struct goodixts_softc *sc = device_private(self);
+       struct i2c_attach_args *ia = aux;
+       struct wsmousedev_attach_args a;
+       uint8_t idbuf[12];
+       char intrstr[128];
+       unsigned i;
+       int error;
+
+       sc->sc_dev = self;



Home | Main Index | Thread Index | Old Index