root/drivers/usb/typec/tcpm/tcpci_rt1711h.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. rt1711h_read16
  2. rt1711h_write16
  3. rt1711h_read8
  4. rt1711h_write8
  5. tdata_to_rt1711h
  6. rt1711h_init
  7. rt1711h_set_vconn
  8. rt1711h_start_drp_toggling
  9. rt1711h_irq
  10. rt1711h_init_alert
  11. rt1711h_sw_reset
  12. rt1711h_check_revision
  13. rt1711h_probe
  14. rt1711h_remove

   1 // SPDX-License-Identifier: GPL-2.0+
   2 /*
   3  * Copyright (C) 2018, Richtek Technology Corporation
   4  *
   5  * Richtek RT1711H Type-C Chip Driver
   6  */
   7 
   8 #include <linux/kernel.h>
   9 #include <linux/module.h>
  10 #include <linux/i2c.h>
  11 #include <linux/interrupt.h>
  12 #include <linux/gpio/consumer.h>
  13 #include <linux/usb/tcpm.h>
  14 #include <linux/regmap.h>
  15 #include "tcpci.h"
  16 
  17 #define RT1711H_VID             0x29CF
  18 #define RT1711H_PID             0x1711
  19 
  20 #define RT1711H_RTCTRL8         0x9B
  21 
  22 /* Autoidle timeout = (tout * 2 + 1) * 6.4ms */
  23 #define RT1711H_RTCTRL8_SET(ck300, ship_off, auto_idle, tout) \
  24                             (((ck300) << 7) | ((ship_off) << 5) | \
  25                             ((auto_idle) << 3) | ((tout) & 0x07))
  26 
  27 #define RT1711H_RTCTRL11        0x9E
  28 
  29 /* I2C timeout = (tout + 1) * 12.5ms */
  30 #define RT1711H_RTCTRL11_SET(en, tout) \
  31                              (((en) << 7) | ((tout) & 0x0F))
  32 
  33 #define RT1711H_RTCTRL13        0xA0
  34 #define RT1711H_RTCTRL14        0xA1
  35 #define RT1711H_RTCTRL15        0xA2
  36 #define RT1711H_RTCTRL16        0xA3
  37 
  38 struct rt1711h_chip {
  39         struct tcpci_data data;
  40         struct tcpci *tcpci;
  41         struct device *dev;
  42 };
  43 
  44 static int rt1711h_read16(struct rt1711h_chip *chip, unsigned int reg, u16 *val)
  45 {
  46         return regmap_raw_read(chip->data.regmap, reg, val, sizeof(u16));
  47 }
  48 
  49 static int rt1711h_write16(struct rt1711h_chip *chip, unsigned int reg, u16 val)
  50 {
  51         return regmap_raw_write(chip->data.regmap, reg, &val, sizeof(u16));
  52 }
  53 
  54 static int rt1711h_read8(struct rt1711h_chip *chip, unsigned int reg, u8 *val)
  55 {
  56         return regmap_raw_read(chip->data.regmap, reg, val, sizeof(u8));
  57 }
  58 
  59 static int rt1711h_write8(struct rt1711h_chip *chip, unsigned int reg, u8 val)
  60 {
  61         return regmap_raw_write(chip->data.regmap, reg, &val, sizeof(u8));
  62 }
  63 
  64 static const struct regmap_config rt1711h_regmap_config = {
  65         .reg_bits = 8,
  66         .val_bits = 8,
  67 
  68         .max_register = 0xFF, /* 0x80 .. 0xFF are vendor defined */
  69 };
  70 
  71 static struct rt1711h_chip *tdata_to_rt1711h(struct tcpci_data *tdata)
  72 {
  73         return container_of(tdata, struct rt1711h_chip, data);
  74 }
  75 
  76 static int rt1711h_init(struct tcpci *tcpci, struct tcpci_data *tdata)
  77 {
  78         int ret;
  79         struct rt1711h_chip *chip = tdata_to_rt1711h(tdata);
  80 
  81         /* CK 300K from 320K, shipping off, auto_idle enable, tout = 32ms */
  82         ret = rt1711h_write8(chip, RT1711H_RTCTRL8,
  83                              RT1711H_RTCTRL8_SET(0, 1, 1, 2));
  84         if (ret < 0)
  85                 return ret;
  86 
  87         /* I2C reset : (val + 1) * 12.5ms */
  88         ret = rt1711h_write8(chip, RT1711H_RTCTRL11,
  89                              RT1711H_RTCTRL11_SET(1, 0x0F));
  90         if (ret < 0)
  91                 return ret;
  92 
  93         /* tTCPCfilter : (26.7 * val) us */
  94         ret = rt1711h_write8(chip, RT1711H_RTCTRL14, 0x0F);
  95         if (ret < 0)
  96                 return ret;
  97 
  98         /*  tDRP : (51.2 + 6.4 * val) ms */
  99         ret = rt1711h_write8(chip, RT1711H_RTCTRL15, 0x04);
 100         if (ret < 0)
 101                 return ret;
 102 
 103         /* dcSRC.DRP : 33% */
 104         return rt1711h_write16(chip, RT1711H_RTCTRL16, 330);
 105 }
 106 
 107 static int rt1711h_set_vconn(struct tcpci *tcpci, struct tcpci_data *tdata,
 108                              bool enable)
 109 {
 110         struct rt1711h_chip *chip = tdata_to_rt1711h(tdata);
 111 
 112         return rt1711h_write8(chip, RT1711H_RTCTRL8,
 113                               RT1711H_RTCTRL8_SET(0, 1, !enable, 2));
 114 }
 115 
 116 static int rt1711h_start_drp_toggling(struct tcpci *tcpci,
 117                                       struct tcpci_data *tdata,
 118                                       enum typec_cc_status cc)
 119 {
 120         struct rt1711h_chip *chip = tdata_to_rt1711h(tdata);
 121         int ret;
 122         unsigned int reg = 0;
 123 
 124         switch (cc) {
 125         default:
 126         case TYPEC_CC_RP_DEF:
 127                 reg |= (TCPC_ROLE_CTRL_RP_VAL_DEF <<
 128                         TCPC_ROLE_CTRL_RP_VAL_SHIFT);
 129                 break;
 130         case TYPEC_CC_RP_1_5:
 131                 reg |= (TCPC_ROLE_CTRL_RP_VAL_1_5 <<
 132                         TCPC_ROLE_CTRL_RP_VAL_SHIFT);
 133                 break;
 134         case TYPEC_CC_RP_3_0:
 135                 reg |= (TCPC_ROLE_CTRL_RP_VAL_3_0 <<
 136                         TCPC_ROLE_CTRL_RP_VAL_SHIFT);
 137                 break;
 138         }
 139 
 140         if (cc == TYPEC_CC_RD)
 141                 reg |= (TCPC_ROLE_CTRL_CC_RD << TCPC_ROLE_CTRL_CC1_SHIFT) |
 142                            (TCPC_ROLE_CTRL_CC_RD << TCPC_ROLE_CTRL_CC2_SHIFT);
 143         else
 144                 reg |= (TCPC_ROLE_CTRL_CC_RP << TCPC_ROLE_CTRL_CC1_SHIFT) |
 145                            (TCPC_ROLE_CTRL_CC_RP << TCPC_ROLE_CTRL_CC2_SHIFT);
 146 
 147         ret = rt1711h_write8(chip, TCPC_ROLE_CTRL, reg);
 148         if (ret < 0)
 149                 return ret;
 150         usleep_range(500, 1000);
 151 
 152         return 0;
 153 }
 154 
 155 static irqreturn_t rt1711h_irq(int irq, void *dev_id)
 156 {
 157         int ret;
 158         u16 alert;
 159         u8 status;
 160         struct rt1711h_chip *chip = dev_id;
 161 
 162         if (!chip->tcpci)
 163                 return IRQ_HANDLED;
 164 
 165         ret = rt1711h_read16(chip, TCPC_ALERT, &alert);
 166         if (ret < 0)
 167                 goto out;
 168 
 169         if (alert & TCPC_ALERT_CC_STATUS) {
 170                 ret = rt1711h_read8(chip, TCPC_CC_STATUS, &status);
 171                 if (ret < 0)
 172                         goto out;
 173                 /* Clear cc change event triggered by starting toggling */
 174                 if (status & TCPC_CC_STATUS_TOGGLING)
 175                         rt1711h_write8(chip, TCPC_ALERT, TCPC_ALERT_CC_STATUS);
 176         }
 177 
 178 out:
 179         return tcpci_irq(chip->tcpci);
 180 }
 181 
 182 static int rt1711h_init_alert(struct rt1711h_chip *chip,
 183                               struct i2c_client *client)
 184 {
 185         int ret;
 186 
 187         /* Disable chip interrupts before requesting irq */
 188         ret = rt1711h_write16(chip, TCPC_ALERT_MASK, 0);
 189         if (ret < 0)
 190                 return ret;
 191 
 192         ret = devm_request_threaded_irq(chip->dev, client->irq, NULL,
 193                                         rt1711h_irq,
 194                                         IRQF_ONESHOT | IRQF_TRIGGER_LOW,
 195                                         dev_name(chip->dev), chip);
 196         if (ret < 0)
 197                 return ret;
 198         enable_irq_wake(client->irq);
 199         return 0;
 200 }
 201 
 202 static int rt1711h_sw_reset(struct rt1711h_chip *chip)
 203 {
 204         int ret;
 205 
 206         ret = rt1711h_write8(chip, RT1711H_RTCTRL13, 0x01);
 207         if (ret < 0)
 208                 return ret;
 209 
 210         usleep_range(1000, 2000);
 211         return 0;
 212 }
 213 
 214 static int rt1711h_check_revision(struct i2c_client *i2c)
 215 {
 216         int ret;
 217 
 218         ret = i2c_smbus_read_word_data(i2c, TCPC_VENDOR_ID);
 219         if (ret < 0)
 220                 return ret;
 221         if (ret != RT1711H_VID) {
 222                 dev_err(&i2c->dev, "vid is not correct, 0x%04x\n", ret);
 223                 return -ENODEV;
 224         }
 225         ret = i2c_smbus_read_word_data(i2c, TCPC_PRODUCT_ID);
 226         if (ret < 0)
 227                 return ret;
 228         if (ret != RT1711H_PID) {
 229                 dev_err(&i2c->dev, "pid is not correct, 0x%04x\n", ret);
 230                 return -ENODEV;
 231         }
 232         return 0;
 233 }
 234 
 235 static int rt1711h_probe(struct i2c_client *client,
 236                          const struct i2c_device_id *i2c_id)
 237 {
 238         int ret;
 239         struct rt1711h_chip *chip;
 240 
 241         ret = rt1711h_check_revision(client);
 242         if (ret < 0) {
 243                 dev_err(&client->dev, "check vid/pid fail\n");
 244                 return ret;
 245         }
 246 
 247         chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
 248         if (!chip)
 249                 return -ENOMEM;
 250 
 251         chip->data.regmap = devm_regmap_init_i2c(client,
 252                                                  &rt1711h_regmap_config);
 253         if (IS_ERR(chip->data.regmap))
 254                 return PTR_ERR(chip->data.regmap);
 255 
 256         chip->dev = &client->dev;
 257         i2c_set_clientdata(client, chip);
 258 
 259         ret = rt1711h_sw_reset(chip);
 260         if (ret < 0)
 261                 return ret;
 262 
 263         ret = rt1711h_init_alert(chip, client);
 264         if (ret < 0)
 265                 return ret;
 266 
 267         chip->data.init = rt1711h_init;
 268         chip->data.set_vconn = rt1711h_set_vconn;
 269         chip->data.start_drp_toggling = rt1711h_start_drp_toggling;
 270         chip->tcpci = tcpci_register_port(chip->dev, &chip->data);
 271         if (IS_ERR_OR_NULL(chip->tcpci))
 272                 return PTR_ERR(chip->tcpci);
 273 
 274         return 0;
 275 }
 276 
 277 static int rt1711h_remove(struct i2c_client *client)
 278 {
 279         struct rt1711h_chip *chip = i2c_get_clientdata(client);
 280 
 281         tcpci_unregister_port(chip->tcpci);
 282         return 0;
 283 }
 284 
 285 static const struct i2c_device_id rt1711h_id[] = {
 286         { "rt1711h", 0 },
 287         { }
 288 };
 289 MODULE_DEVICE_TABLE(i2c, rt1711h_id);
 290 
 291 #ifdef CONFIG_OF
 292 static const struct of_device_id rt1711h_of_match[] = {
 293         { .compatible = "richtek,rt1711h", },
 294         {},
 295 };
 296 MODULE_DEVICE_TABLE(of, rt1711h_of_match);
 297 #endif
 298 
 299 static struct i2c_driver rt1711h_i2c_driver = {
 300         .driver = {
 301                 .name = "rt1711h",
 302                 .of_match_table = of_match_ptr(rt1711h_of_match),
 303         },
 304         .probe = rt1711h_probe,
 305         .remove = rt1711h_remove,
 306         .id_table = rt1711h_id,
 307 };
 308 module_i2c_driver(rt1711h_i2c_driver);
 309 
 310 MODULE_AUTHOR("ShuFan Lee <shufan_lee@richtek.com>");
 311 MODULE_DESCRIPTION("RT1711H USB Type-C Port Controller Interface Driver");
 312 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */