Hi ARM list,

I got a pinephone pro for christmas and I put OpenBSD on it but it's not
ripe to even have on for lengthy periods of time.  The pinephone pro is
based on the Rockchip 3399.

I'm trying to adjust the /sys/dev/fdt/rkpmic.c driver but I'm running into
a problem and would like to get some help understanding why I'm getting
ETIMEOUT's on the i2c bus (iic), it's almost like the driver is getting the
wrong info about addresses and the i2c times out because of it?

Below my signature I have (a wrong) patch but it shows that on line 191 and
line 202, the error is 60 which I crosschecked with man errno it's ETIMEOUT.

So I hunted in the /sys/dev/fdt/rkiic.c code and made a delay loop longer
which doesn't do anything really, it just delays the messages in dmesg.

Could a advanced person give me a hint on this what could be happening here?
The pinephone pro has a rk818 pmic which is very much compatible to rk808 and
it gets detected as such from FDT.  I have coded some "variant" code in there
but even reading the registers for hi and lo bytes does not work.  This is
based off the linux driver, with changes.

When this works I believe I can put charging control and apmd on this phone.

Best Regards,
-peter

PS: use cut -c 8- to retrive the patch.


     1  Index: rkpmic.c
     2  ===================================================================
     3  RCS file: /cvs/src/sys/dev/fdt/rkpmic.c,v
     4  retrieving revision 1.9
     5  diff -u -p -u -r1.9 rkpmic.c
     6  --- rkpmic.c    24 Oct 2021 17:52:27 -0000      1.9
     7  +++ rkpmic.c    21 Apr 2022 15:06:26 -0000
     8  @@ -39,15 +39,39 @@ extern todr_chip_handle_t todr_handle;
     9   #define RK80X_WEEKS            0x06
    10   #define RK80X_NRTC_REGS        7
    11   
    12  +#define RK818_SECONDS          0x00
    13  +#define RK818_MINUTES          0x01
    14  +#define RK818_HOURS            0x02
    15  +#define RK818_DAYS             0x03
    16  +#define RK818_MONTHS           0x04
    17  +#define RK818_YEARS            0x05
    18  +#define RK818_WEEKS            0x06
    19  +#define RK818_ALARM_SECONDS    0x08
    20  +#define RK818_ALARM_MINUTES    0x09
    21  +#define RK818_ALARM_HOURS      0x0a
    22  +#define RK818_ALARM_DAYS       0x0b
    23  +#define RK818_ALARM_MONTHS     0x0c
    24  +#define RK818_ALARM_YEARS      0x0d
    25  +#define RK818_NRTC_REGS        13
    26  +
    27   #define RK805_RTC_CTRL         0x10
    28   #define RK808_RTC_CTRL         0x10
    29   #define RK809_RTC_CTRL         0x0d
    30  +#define RK818_RTC_CTRL         0x10
    31  +
    32   #define  RK80X_RTC_CTRL_STOP_RTC       0x01
    33  +#define  RK818_RTC_CTRL_STOP_RTC       0x01
    34   
    35   #define RK805_RTC_STATUS       0x11
    36   #define RK808_RTC_STATUS       0x11
    37   #define RK809_RTC_STATUS       0x0e
    38  +#define RK818_RTC_STATUS       0x11
    39  +
    40   #define  RK80X_RTC_STATUS_POWER_UP     0x80
    41  +#define  RK818_RTC_STATUS_POWER_UP     0x80
    42  +
    43  +#define RK808_ID_HI            0x17
    44  +#define RK808_ID_LO            0x18
    45   
    46   struct rkpmic_vsel_range {
    47          uint32_t base, delta;
    48  @@ -229,6 +253,72 @@ struct rkpmic_regdata rk809_regdata[] = 
    49          { }
    50   };
    51   
    52  +/*
    53  + * Used by RK818 for BUCK1 & BUCK2
    54  + *  0-63:      0.7125V-1.5V, step=12.5mV
    55  + */
    56  +struct rkpmic_vsel_range rk818_vsel_range1[] = {
    57  +       { 712500, 12500, 0, 63 },
    58  +       {}
    59  +};
    60  +
    61  +/*
    62  + * Used by RK818 for BUCK4
    63  + *  0-15:      1.8V-3.3V,step=100mV
    64  + */
    65  +struct rkpmic_vsel_range rk818_vsel_range2[] = {
    66  +       { 1800000, 100000, 0, 15 },
    67  +       {}
    68  +};
    69  +
    70  +/*
    71  + * Used by RK818 for LDO1-2, 4-5, 8
    72  + *  0-16:      1.8V-3.4V, step=100mV
    73  + */
    74  +struct rkpmic_vsel_range rk818_vsel_range3[] = {
    75  +       { 1800000, 100000, 0, 16 },
    76  +       {}
    77  +};
    78  +
    79  +/*
    80  + * Used by RK818 for LDO3
    81  + *   0-12:     0.8V~2.5V, step=100mV
    82  + *   13:       2.2V
    83  + *   15:       2.5V
    84  + */
    85  +struct rkpmic_vsel_range rk818_vsel_range4[] = {
    86  +       { 800000, 100000, 0, 15 },
    87  +       { 2200000, 0, 13, 13 },
    88  +       { 2500000, 0, 15, 15 },
    89  +       {}
    90  +};
    91  +
    92  +/*
    93  + * Used by RK818 for LDO6-7
    94  + *  0-17:      0.8V-2.5V,step=100mV
    95  + */
    96  +struct rkpmic_vsel_range rk818_vsel_range5[] = {
    97  +       { 800000, 100000, 0, 17 },
    98  +       {}
    99  +};
   100  +
   101  +/* comments for https://rockchip.fr/RK818%20datasheet%20V1.0.pdf */
   102  +struct rkpmic_regdata rk818_regdata[] = {
   103  +       { "DCDC_REG1", 0x2f, 0x3f, rk818_vsel_range1 }, /* pg. 58 */
   104  +       { "DCDC_REG2", 0x33, 0x3f, rk818_vsel_range1 }, /* pg. 59 */
   105  +       { "DCDC_REG4", 0x38, 0x0f, rk818_vsel_range2 }, /* pg. 61 */
   106  +       { "LDO_REG1", 0x3b, 0x1f, rk818_vsel_range3 },  /* pg. 63 */
   107  +       { "LDO_REG2", 0x3d, 0x1f, rk818_vsel_range3 },  /* pg. 63 */
   108  +       { "LDO_REG3", 0x3f, 0x0f, rk818_vsel_range4 },  /* pg. 64 */
   109  +       { "LDO_REG4", 0x41, 0x1f, rk818_vsel_range3 },  /* pg. 65 */
   110  +       { "LDO_REG5", 0x43, 0x1f, rk818_vsel_range3 },  /* pg. 66 */
   111  +       { "LDO_REG6", 0x45, 0x1f, rk818_vsel_range5 },  /* pg. 67 */
   112  +       { "LDO_REG7", 0x47, 0x1f, rk818_vsel_range5 },  /* pg. 67 */
   113  +       { "LDO_REG8", 0x49, 0x1f, rk818_vsel_range3 },  /* pg. 68 */
   114  +       { }
   115  +};
   116  +
   117  +
   118   struct rkpmic_softc {
   119          struct device sc_dev;
   120          i2c_tag_t sc_tag;
   121  @@ -237,6 +327,13 @@ struct rkpmic_softc {
   122          int sc_rtc_ctrl_reg, sc_rtc_status_reg;
   123          struct todr_chip_handle sc_todr;
   124          struct rkpmic_regdata *sc_regdata;
   125  +       
   126  +       uint16_t variant;
   127  +#define RK805_VARIANT          0x8050
   128  +#define RK808_VARIANT          0x0
   129  +#define RK809_VARIANT          0x8090
   130  +#define        RK818_VARIANT           0x8180
   131  +#define RK8XX_VARIANT_MASK     0xfff0
   132   };
   133   
   134   int    rkpmic_match(struct device *, void *, void *);
   135  @@ -275,6 +372,7 @@ rkpmic_attach(struct device *parent, str
   136          struct i2c_attach_args *ia = aux;
   137          int node = *(int *)ia->ia_cookie;
   138          const char *chip;
   139  +       uint8_t regs[2];
   140   
   141          sc->sc_tag = ia->ia_tag;
   142          sc->sc_addr = ia->ia_addr;
   143  @@ -290,17 +388,36 @@ rkpmic_attach(struct device *parent, str
   144                  sc->sc_rtc_ctrl_reg = RK805_RTC_CTRL;
   145                  sc->sc_rtc_status_reg = RK805_RTC_STATUS;
   146                  sc->sc_regdata = rk805_regdata;
   147  +               sc->variant = RK805_VARIANT;
   148          } else if (OF_is_compatible(node, "rockchip,rk808")) {
   149  -               chip = "RK808";
   150  -               sc->sc_rtc_ctrl_reg = RK808_RTC_CTRL;
   151  -               sc->sc_rtc_status_reg = RK808_RTC_STATUS;
   152  -               sc->sc_regdata = rk808_regdata;
   153  +               rkpmic_reg_write(sc, RK808_RTC_STATUS, 
RK80X_RTC_STATUS_POWER_UP);
   154  +               regs[0] = rkpmic_reg_read(sc, RK808_ID_HI);
   155  +               regs[1] = rkpmic_reg_read(sc, RK808_ID_LO);
   156  +               rkpmic_reg_write(sc, RK808_RTC_CTRL, 0);
   157  +
   158  +               sc->variant = ((regs[0] << 8) | regs[1]) & 
RK8XX_VARIANT_MASK;
   159  +                       
   160  +               switch (sc->variant) {
   161  +               case RK818_VARIANT:
   162  +                       chip = "RK818";
   163  +                       sc->sc_rtc_ctrl_reg = RK818_RTC_CTRL;
   164  +                       sc->sc_rtc_status_reg = RK818_RTC_STATUS;
   165  +                       sc->sc_regdata = rk818_regdata;
   166  +                       break;
   167  +               default:
   168  +                       chip = "RK808";
   169  +                       sc->sc_rtc_ctrl_reg = RK808_RTC_CTRL;
   170  +                       sc->sc_rtc_status_reg = RK808_RTC_STATUS;
   171  +                       sc->sc_regdata = rk808_regdata;
   172  +                       break;
   173  +               }
   174          } else {
   175                  chip = "RK809";
   176                  sc->sc_rtc_ctrl_reg = RK809_RTC_CTRL;
   177                  sc->sc_rtc_status_reg = RK809_RTC_STATUS;
   178                  sc->sc_regdata = rk809_regdata;
   179  -       }
   180  +       } 
   181  +               
   182          printf(": %s\n", chip);
   183   
   184          node = OF_getnodebyname(node, "regulators");
   185  @@ -496,8 +613,8 @@ rkpmic_reg_read(struct rkpmic_softc *sc,
   186          iic_release_bus(sc->sc_tag, I2C_F_POLL);
   187   
   188          if (error) {
   189  -               printf("%s: can't read register 0x%02x\n",
   190  -                   sc->sc_dev.dv_xname, reg);
   191  +               printf("%s: can't read register 0x%02x error=%d\n",
   192  +                   sc->sc_dev.dv_xname, reg, error);
   193                  val = 0xff;
   194          }
   195   
   196  @@ -516,22 +633,31 @@ rkpmic_reg_write(struct rkpmic_softc *sc
   197          iic_release_bus(sc->sc_tag, I2C_F_POLL);
   198   
   199          if (error) {
   200  -               printf("%s: can't write register 0x%02x\n",
   201  -                   sc->sc_dev.dv_xname, reg);
   202  +               printf("%s: can't write register 0x%02x error=%d\n",
   203  +                   sc->sc_dev.dv_xname, reg, error);
   204          }
   205   }
   206   
   207   int
   208   rkpmic_clock_read(struct rkpmic_softc *sc, struct clock_ymdhms *dt)
   209   {
   210  -       uint8_t regs[RK80X_NRTC_REGS];
   211  -       uint8_t cmd = RK80X_SECONDS;
   212  +       uint8_t regs[RK818_NRTC_REGS];
   213  +       uint8_t cmd;
   214          uint8_t status;
   215  +       int variant818 = 0;
   216          int error;
   217   
   218  +       if (sc->variant == RK818_VARIANT) {
   219  +               cmd =  RK818_SECONDS;
   220  +               variant818 = 1;
   221  +       } else {
   222  +               cmd = RK80X_SECONDS;
   223  +       }
   224  +
   225          iic_acquire_bus(sc->sc_tag, I2C_F_POLL);
   226          error = iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr,
   227  -           &cmd, sizeof(cmd), regs, RK80X_NRTC_REGS, I2C_F_POLL);
   228  +           &cmd, sizeof(cmd), regs, (variant818) ? 
   229  +               RK818_NRTC_REGS : RK80X_NRTC_REGS, I2C_F_POLL);
   230          iic_release_bus(sc->sc_tag, I2C_F_POLL);
   231   
   232          if (error) {
   233  @@ -560,10 +686,16 @@ rkpmic_clock_read(struct rkpmic_softc *s
   234   int
   235   rkpmic_clock_write(struct rkpmic_softc *sc, struct clock_ymdhms *dt)
   236   {
   237  -       uint8_t regs[RK80X_NRTC_REGS];
   238  +       uint8_t regs[RK818_NRTC_REGS];
   239          uint8_t cmd = RK80X_SECONDS;
   240  +       int variant818 = 0;
   241          int error;
   242   
   243  +       if (sc->variant == RK818_VARIANT) {
   244  +               cmd = RK818_SECONDS;
   245  +               variant818 = 1;
   246  +       }
   247  +
   248          /*
   249           * Convert our time representation into something the RK80x
   250           * can understand.
   251  @@ -577,11 +709,13 @@ rkpmic_clock_write(struct rkpmic_softc *
   252          regs[6] = TOBCD(dt->dt_wday);
   253   
   254          /* Stop RTC such that we can write to it. */
   255  -       rkpmic_reg_write(sc, sc->sc_rtc_ctrl_reg, 
RK80X_RTC_CTRL_STOP_RTC);
   256  +       rkpmic_reg_write(sc, sc->sc_rtc_ctrl_reg, (variant818) ? 
   257  +               RK818_RTC_CTRL_STOP_RTC : RK80X_RTC_CTRL_STOP_RTC);
   258   
   259          iic_acquire_bus(sc->sc_tag, I2C_F_POLL);
   260          error = iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP, 
sc->sc_addr,
   261  -           &cmd, sizeof(cmd), regs, RK80X_NRTC_REGS, I2C_F_POLL);
   262  +           &cmd, sizeof(cmd), regs, (variant818) ? 
   263  +               RK818_NRTC_REGS : RK80X_NRTC_REGS, I2C_F_POLL);
   264          iic_release_bus(sc->sc_tag, I2C_F_POLL);
   265   
   266          /* Restart RTC. */
   267  @@ -593,7 +727,8 @@ rkpmic_clock_write(struct rkpmic_softc *
   268          }
   269   
   270          /* Clear POWER_UP bit to indicate the time is now valid. */
   271  -       rkpmic_reg_write(sc, sc->sc_rtc_status_reg, 
RK80X_RTC_STATUS_POWER_UP);
   272  +       rkpmic_reg_write(sc, sc->sc_rtc_status_reg, (variant818) ?
   273  +               RK818_RTC_STATUS_POWER_UP : RK80X_RTC_STATUS_POWER_UP);
   274   
   275          return 0;
   276   }

Reply via email to