Received: by 10.213.65.68 with SMTP id h4csp164662imn; Fri, 16 Mar 2018 22:55:29 -0700 (PDT) X-Google-Smtp-Source: AG47ELvuWOTVKWP8N8aeC58EcjtltC/Pf9aFUH4Das16LPpsX+So6UjZKL7lRU8fSKdzkqUHSxc9 X-Received: by 2002:a17:902:b10f:: with SMTP id q15-v6mr2775865plr.263.1521266129442; Fri, 16 Mar 2018 22:55:29 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1521266129; cv=none; d=google.com; s=arc-20160816; b=gWGr1MUdMya5SD4dJmI9MWsik79OAGYxZqHf454SDYw8Vg6iqxvWQh5iEe6bvy+cUs eIlffAPYJPpRul23h9MXQSeAFwHksjzFuC+SGl6wxZQXVW7Ne7tcA0CUXLUNo9tubInZ 8YZVyhbe6dLuqtkkLXw0q6Af03EbZQjDKqOw5qO9Zr3vrOpSgYSuSywX0UbWfFVCyCBr 3vs+aBiPapxbA3LQ613duHNa+L2AH+x9jK1TTkrFkczA46JQHMFxGRMcFm71LywBjpl1 MjeXmSGMz6Kw0Y7nfU9ZP+ntfjtU8T66XvlOU+uCO2TZ6Ep+G/9EQXzthtLVf/jDPj/j C+jQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:cc:to:subject :message-id:date:from:references:in-reply-to:mime-version :dkim-signature:arc-authentication-results; bh=PayxYJgrmrXS5owTLxKEtCyW+ZD53YWMP2jj24sLzBQ=; b=D8e4pbF3s2Q+VOCIlhWmH4PhsC4kIPsSZwzO/uLiIFEC/DxLIKmalrrQPoz2bmC78Y ECz6G78cvXbqYs/z/lqTEl/2HZAXbGbvj2LPk+FG9ze0O2hY/2iXFcozcG4ko8KBPQlT l2z8us6wIMmq9Adv7SA0QaugZGKdStFwM/3jIzVRllx1aggCW8eOnyJDlDoqrIq8PPm+ ShblYElKqLsSl0RpOH6bnejw8zTuT60D4+PTEuW5fM7CXHmL906jgouNudAo9chYIjUC lx8zifncFiBFIL6A4JepjxoKq3tRavWsYsMSCb6sv0uix/cW7eJg/QYcKSO510C1YE5g V1LA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=Ajun9Ox5; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id e74si5666691pfd.97.2018.03.16.22.55.01; Fri, 16 Mar 2018 22:55:29 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=Ajun9Ox5; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751139AbeCQFwr (ORCPT + 99 others); Sat, 17 Mar 2018 01:52:47 -0400 Received: from mail-qk0-f195.google.com ([209.85.220.195]:46321 "EHLO mail-qk0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750746AbeCQFwp (ORCPT ); Sat, 17 Mar 2018 01:52:45 -0400 Received: by mail-qk0-f195.google.com with SMTP id o184so13310442qkd.13; Fri, 16 Mar 2018 22:52:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc:content-transfer-encoding; bh=PayxYJgrmrXS5owTLxKEtCyW+ZD53YWMP2jj24sLzBQ=; b=Ajun9Ox5O/HgjM0bRQRZ6U+G0GduSmNpEBL30OCE9LLwOCjJUUI589MGou4neWw2dv G0HrgcwVgybZfYLlcyv2AKigVfWUQB92AVZrNVrHGL3nCIp4RalGPuvk/FxmmXZTUjLi 1tWQLuJzwu+goP3rmqAA7aa0QtSG8usb32BaFd3pq5nnQzVq14q+kwwmDvfx1RlpFkQ4 5qZgOK+/GmhOx7Ibj5W85SqeUVgGcC7WiNnL08EJh6DXFMQfqZ2lNaLbZzRB9OHJc+xi ikditVMJtLFvrTnpkfZ/Mw6ckQ9aflT1PEMBr+vgztupM9ok8jJeJn/q1xrCS+/DWHdA Gvow== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc:content-transfer-encoding; bh=PayxYJgrmrXS5owTLxKEtCyW+ZD53YWMP2jj24sLzBQ=; b=lxl9EEqHe51iK0TA0g3XccWO8sVgJJVz89a4jZ6dXoFvyvJfbIMOO9EBUMqGhpDwHk n6WzsIAHS7QDj5TXXgz2qDqyAz5iCRhLZPVr2ryHJd+s/FJUr+K6AMOPwD04qC5KF4PI 5enKdn7cmvL11hdM2RzOBCaOTJCefUyK3KftSErsdnTAXbGqJ27XAWRCIY3T/5b5bXPN x2yvewh+6L2ITj8oBXXhSb8Pa1olbhD1d6O53cdsRlZ0oanIWEGBILcqI6tQHDDysHSK fu4vD91aqoU2ommbAnURxnHT50YwOOzxfEZ6iK9PJwjqg/17j4WUFE1zPsnlOY0IsnwY NqUQ== X-Gm-Message-State: AElRT7HjnA4jwg2e61dDlQU9JvM/E0vxFR08ZNSkiRR6or7f+vi5RU2+ QpLNMPupyXinCb+ooZXZBD13NyJFvvrzOEINmys= X-Received: by 10.55.148.1 with SMTP id w1mr6486585qkd.354.1521265964356; Fri, 16 Mar 2018 22:52:44 -0700 (PDT) MIME-Version: 1.0 Received: by 10.200.28.38 with HTTP; Fri, 16 Mar 2018 22:52:43 -0700 (PDT) In-Reply-To: <7ebc0dac-db70-3635-27c2-97ce0b5b9f4c@roeck-us.net> References: <1521222040-30349-1-git-send-email-leechu729@gmail.com> <7ebc0dac-db70-3635-27c2-97ce0b5b9f4c@roeck-us.net> From: =?UTF-8?B?5p2O5pu45biG?= Date: Sat, 17 Mar 2018 13:52:43 +0800 Message-ID: Subject: Re: [PATCH v2] staging: typec: rt1711h typec chip driver To: Guenter Roeck Cc: Greg KH , Heikki Krogerus , =?UTF-8?B?c2h1ZmFuX2xlZSjmnY7mm7jluIYp?= , =?UTF-8?B?Y3lfaHVhbmco6buD5ZWf5Y6fKQ==?= , Jun Li , linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Guenter, 2018-03-17 10:16 GMT+08:00 Guenter Roeck : > On 03/16/2018 10:40 AM, ShuFan Lee wrote: >> >> From: ShuFan Lee >> >> Richtek RT1711H Type-C chip driver that works with >> Type-C Port Controller Manager to provide USB PD and >> USB Type-C functionalities. >> Add definition of TCPC_CC_STATUS_TOGGLING. >> >> Signed-off-by: ShuFan Lee > > > Does this patch require DT review for the bindings ? I see Jun is also working on the properties of DTS for TCPCI/TCPM in his patches. So, I plan to upload the devicetree binding file when it is ready to move tcpci_rt1711h out of staging. Is it OK or should I upload a version first? > > Gueter > > >> --- >> drivers/staging/typec/Kconfig | 8 + >> drivers/staging/typec/Makefile | 1 + >> drivers/staging/typec/tcpci.h | 1 + >> drivers/staging/typec/tcpci_rt1711h.c | 329 >> ++++++++++++++++++++++++++++++++++ >> 4 files changed, 339 insertions(+) >> create mode 100644 drivers/staging/typec/tcpci_rt1711h.c >> >> changelogs between v1 and v2 >> - use gpiod_* instead of gpio_* >> >> diff --git a/drivers/staging/typec/Kconfig b/drivers/staging/typec/Kconf= ig >> index 5359f556d203..3aa981fbc8f5 100644 >> --- a/drivers/staging/typec/Kconfig >> +++ b/drivers/staging/typec/Kconfig >> @@ -9,6 +9,14 @@ config TYPEC_TCPCI >> help >> Type-C Port Controller driver for TCPCI-compliant controller. >> +config TYPEC_RT1711H >> + tristate "Richtek RT1711H Type-C chip driver" >> + select TYPEC_TCPCI >> + help >> + Richtek RT1711H Type-C chip driver that works with >> + Type-C Port Controller Manager to provide USB PD and USB >> + Type-C functionalities. >> + >> endif >> endmenu >> diff --git a/drivers/staging/typec/Makefile >> b/drivers/staging/typec/Makefile >> index 53d649abcb53..7803d485e1b3 100644 >> --- a/drivers/staging/typec/Makefile >> +++ b/drivers/staging/typec/Makefile >> @@ -1 +1,2 @@ >> obj-$(CONFIG_TYPEC_TCPCI) +=3D tcpci.o >> +obj-$(CONFIG_TYPEC_RT1711H) +=3D tcpci_rt1711h.o >> diff --git a/drivers/staging/typec/tcpci.h b/drivers/staging/typec/tcpci= .h >> index 34c865f0dcf6..303ebde26546 100644 >> --- a/drivers/staging/typec/tcpci.h >> +++ b/drivers/staging/typec/tcpci.h >> @@ -59,6 +59,7 @@ >> #define TCPC_POWER_CTRL_VCONN_ENABLE BIT(0) >> #define TCPC_CC_STATUS 0x1d >> +#define TCPC_CC_STATUS_TOGGLING BIT(5) >> #define TCPC_CC_STATUS_TERM BIT(4) >> #define TCPC_CC_STATUS_CC2_SHIFT 2 >> #define TCPC_CC_STATUS_CC2_MASK 0x3 >> diff --git a/drivers/staging/typec/tcpci_rt1711h.c >> b/drivers/staging/typec/tcpci_rt1711h.c >> new file mode 100644 >> index 000000000000..12afac363d6d >> --- /dev/null >> +++ b/drivers/staging/typec/tcpci_rt1711h.c >> @@ -0,0 +1,329 @@ >> +// SPDX-License-Identifier: GPL-2.0+ >> +/* >> + * Copyright (C) 2018, Richtek Technology Corporation >> + * >> + * Richtek RT1711H Type-C Chip Driver >> + */ >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include "tcpci.h" >> + >> +#define RT1711H_RTCTRL8 0x9B >> + >> +/* Autoidle timeout =3D (tout * 2 + 1) * 6.4ms */ >> +#define RT1711H_RTCTRL8_SET(ck300, ship_off, auto_idle, tout) \ >> + (((ck300) << 7) | ((ship_off) << 5) | \ >> + ((auto_idle) << 3) | ((tout) & 0x07)) >> + >> +#define RT1711H_RTCTRL11 0x9E >> + >> +/* I2C timeout =3D (tout + 1) * 12.5ms */ >> +#define RT1711H_RTCTRL11_SET(en, tout) \ >> + (((en) << 7) | ((tout) & 0x0F)) >> + >> +#define RT1711H_RTCTRL13 0xA0 >> +#define RT1711H_RTCTRL14 0xA1 >> +#define RT1711H_RTCTRL15 0xA2 >> +#define RT1711H_RTCTRL16 0xA3 >> + >> +struct rt1711h_chip { >> + struct tcpci_data data; >> + struct tcpci *tcpci; >> + struct device *dev; >> + int irq; >> +}; >> + >> +static int rt1711h_read16(struct rt1711h_chip *chip, unsigned int reg, >> u16 *val) >> +{ >> + return regmap_raw_read(chip->data.regmap, reg, val, sizeof(u16))= ; >> +} >> + >> +static int rt1711h_write16(struct rt1711h_chip *chip, unsigned int reg, >> u16 val) >> +{ >> + return regmap_raw_write(chip->data.regmap, reg, &val, >> sizeof(u16)); >> +} >> + >> +static int rt1711h_read8(struct rt1711h_chip *chip, unsigned int reg, u= 8 >> *val) >> +{ >> + return regmap_raw_read(chip->data.regmap, reg, val, sizeof(u8)); >> +} >> + >> +static int rt1711h_write8(struct rt1711h_chip *chip, unsigned int reg, = u8 >> val) >> +{ >> + return regmap_raw_write(chip->data.regmap, reg, &val, sizeof(u8)= ); >> +} >> + >> +static const struct regmap_config rt1711h_regmap_config =3D { >> + .reg_bits =3D 8, >> + .val_bits =3D 8, >> + >> + .max_register =3D 0xFF, /* 0x80 .. 0xFF are vendor defined */ >> +}; >> + >> +static struct rt1711h_chip *tdata_to_rt1711h(struct tcpci_data *tdata) >> +{ >> + return container_of(tdata, struct rt1711h_chip, data); >> +} >> + >> +static int rt1711h_init(struct tcpci *tcpci, struct tcpci_data *tdata) >> +{ >> + int ret; >> + struct rt1711h_chip *chip =3D tdata_to_rt1711h(tdata); >> + >> + /* CK 300K from 320K, shipping off, auto_idle enable, tout =3D 3= 2ms >> */ >> + ret =3D rt1711h_write8(chip, RT1711H_RTCTRL8, >> + RT1711H_RTCTRL8_SET(0, 1, 1, 2)); >> + if (ret < 0) >> + return ret; >> + >> + /* I2C reset : (val + 1) * 12.5ms */ >> + ret =3D rt1711h_write8(chip, RT1711H_RTCTRL11, >> + RT1711H_RTCTRL11_SET(1, 0x0F)); >> + if (ret < 0) >> + return ret; >> + >> + /* tTCPCfilter : (26.7 * val) us */ >> + ret =3D rt1711h_write8(chip, RT1711H_RTCTRL14, 0x0F); >> + if (ret < 0) >> + return ret; >> + >> + /* tDRP : (51.2 + 6.4 * val) ms */ >> + ret =3D rt1711h_write8(chip, RT1711H_RTCTRL15, 0x04); >> + if (ret < 0) >> + return ret; >> + >> + /* dcSRC.DRP : 33% */ >> + return rt1711h_write16(chip, RT1711H_RTCTRL16, 330); >> +} >> + >> +static int rt1711h_set_vconn(struct tcpci *tcpci, struct tcpci_data >> *tdata, >> + bool enable) >> +{ >> + struct rt1711h_chip *chip =3D tdata_to_rt1711h(tdata); >> + >> + return rt1711h_write8(chip, RT1711H_RTCTRL8, >> + RT1711H_RTCTRL8_SET(0, 1, enable ? 0 : 1, >> 2)); >> +} >> + >> +static int rt1711h_start_drp_toggling(struct tcpci *tcpci, >> + struct tcpci_data *tdata, >> + enum typec_cc_status cc) >> +{ >> + struct rt1711h_chip *chip =3D tdata_to_rt1711h(tdata); >> + int ret; >> + unsigned int reg =3D 0; >> + >> + switch (cc) { >> + default: >> + case TYPEC_CC_RP_DEF: >> + reg |=3D (TCPC_ROLE_CTRL_RP_VAL_DEF << >> + TCPC_ROLE_CTRL_RP_VAL_SHIFT); >> + break; >> + case TYPEC_CC_RP_1_5: >> + reg |=3D (TCPC_ROLE_CTRL_RP_VAL_1_5 << >> + TCPC_ROLE_CTRL_RP_VAL_SHIFT); >> + break; >> + case TYPEC_CC_RP_3_0: >> + reg |=3D (TCPC_ROLE_CTRL_RP_VAL_3_0 << >> + TCPC_ROLE_CTRL_RP_VAL_SHIFT); >> + break; >> + } >> + >> + if (cc =3D=3D TYPEC_CC_RD) >> + reg |=3D (TCPC_ROLE_CTRL_CC_RD << TCPC_ROLE_CTRL_CC1_SHI= FT) >> | >> + (TCPC_ROLE_CTRL_CC_RD << >> TCPC_ROLE_CTRL_CC2_SHIFT); >> + else >> + reg |=3D (TCPC_ROLE_CTRL_CC_RP << TCPC_ROLE_CTRL_CC1_SHI= FT) >> | >> + (TCPC_ROLE_CTRL_CC_RP << >> TCPC_ROLE_CTRL_CC2_SHIFT); >> + >> + ret =3D rt1711h_write8(chip, TCPC_ROLE_CTRL, reg); >> + if (ret < 0) >> + return ret; >> + usleep_range(500, 1000); >> + >> + return 0; >> +} >> + >> +static irqreturn_t rt1711h_irq(int irq, void *dev_id) >> +{ >> + int ret; >> + u16 alert; >> + u8 status; >> + struct rt1711h_chip *chip =3D dev_id; >> + >> + if (!chip->tcpci) >> + return IRQ_HANDLED; >> + >> + ret =3D rt1711h_read16(chip, TCPC_ALERT, &alert); >> + if (ret < 0) >> + goto out; >> + >> + if (alert & TCPC_ALERT_CC_STATUS) { >> + ret =3D rt1711h_read8(chip, TCPC_CC_STATUS, &status); >> + if (ret < 0) >> + goto out; >> + /* Clear cc change event triggered by starting toggling = */ >> + if (status & TCPC_CC_STATUS_TOGGLING) >> + rt1711h_write8(chip, TCPC_ALERT, >> TCPC_ALERT_CC_STATUS); >> + } >> + >> +out: >> + return tcpci_irq(chip->tcpci); >> +} >> + >> +static int rt1711h_init_gpio(struct rt1711h_chip *chip) >> +{ >> + struct gpio_desc *gpio; >> + >> + gpio =3D devm_gpiod_get(chip->dev, "rt,intr", GPIOD_IN); >> + if (IS_ERR(gpio)) >> + return PTR_ERR(gpio); >> + >> + chip->irq =3D gpiod_to_irq(gpio); >> + if (chip->irq < 0) >> + return chip->irq; >> + return 0; >> +} >> + >> +static int rt1711h_init_alert(struct rt1711h_chip *chip) >> +{ >> + int ret; >> + >> + /* Disable chip interrupts before requesting irq */ >> + ret =3D rt1711h_write16(chip, TCPC_ALERT_MASK, 0); >> + if (ret < 0) >> + return ret; >> + >> + if (!chip->irq) { >> + ret =3D rt1711h_init_gpio(chip); >> + if (ret < 0) >> + return ret; >> + } >> + ret =3D devm_request_threaded_irq(chip->dev, chip->irq, NULL, >> + rt1711h_irq, >> + IRQF_ONESHOT | IRQF_TRIGGER_LOW, >> + dev_name(chip->dev), chip); >> + if (ret < 0) >> + return ret; >> + enable_irq_wake(chip->irq); >> + return 0; >> +} >> + >> +static int rt1711h_sw_reset(struct rt1711h_chip *chip) >> +{ >> + int ret; >> + >> + ret =3D rt1711h_write8(chip, RT1711H_RTCTRL13, 0x01); >> + if (ret < 0) >> + return ret; >> + >> + usleep_range(1000, 2000); >> + return 0; >> +} >> + >> +static int rt1711h_check_revision(struct i2c_client *i2c) >> +{ >> + int ret; >> + >> + ret =3D i2c_smbus_read_word_data(i2c, TCPC_VENDOR_ID); >> + if (ret < 0) >> + return ret; >> + if (ret !=3D 0x29cf) { >> + dev_err(&i2c->dev, "vid is not correct, 0x%04x\n", ret); >> + return -ENODEV; >> + } >> + ret =3D i2c_smbus_read_word_data(i2c, TCPC_PRODUCT_ID); >> + if (ret < 0) >> + return ret; >> + if (ret !=3D 0x1711) { >> + dev_err(&i2c->dev, "pid is not correct, 0x%04x\n", ret); >> + return -ENODEV; >> + } >> + return 0; >> +} >> + >> +static int rt1711h_probe(struct i2c_client *client, >> + const struct i2c_device_id *i2c_id) >> +{ >> + int ret; >> + struct rt1711h_chip *chip; >> + >> + ret =3D rt1711h_check_revision(client); >> + if (ret < 0) { >> + dev_err(&client->dev, "check vid/pid fail\n"); >> + return ret; >> + } >> + >> + chip =3D devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); >> + if (!chip) >> + return -ENOMEM; >> + >> + chip->data.regmap =3D devm_regmap_init_i2c(client, >> + &rt1711h_regmap_config)= ; >> + if (IS_ERR(chip->data.regmap)) >> + return PTR_ERR(chip->data.regmap); >> + >> + chip->irq =3D client->irq; >> + chip->dev =3D &client->dev; >> + i2c_set_clientdata(client, chip); >> + >> + ret =3D rt1711h_sw_reset(chip); >> + if (ret < 0) >> + return ret; >> + >> + ret =3D rt1711h_init_alert(chip); >> + if (ret < 0) >> + return ret; >> + >> + chip->data.init =3D rt1711h_init; >> + chip->data.set_vconn =3D rt1711h_set_vconn; >> + chip->data.start_drp_toggling =3D rt1711h_start_drp_toggling; >> + chip->tcpci =3D tcpci_register_port(chip->dev, &chip->data); >> + if (IS_ERR_OR_NULL(chip->tcpci)) >> + return PTR_ERR(chip->tcpci); >> + >> + return 0; >> +} >> + >> +static int rt1711h_remove(struct i2c_client *client) >> +{ >> + struct rt1711h_chip *chip =3D i2c_get_clientdata(client); >> + >> + tcpci_unregister_port(chip->tcpci); >> + return 0; >> +} >> + >> +static const struct i2c_device_id rt1711h_id[] =3D { >> + { "rt1711h", 0 }, >> + { } >> +}; >> +MODULE_DEVICE_TABLE(i2c, rt1711h_id); >> + >> +#ifdef CONFIG_OF >> +static const struct of_device_id rt1711h_of_match[] =3D { >> + { .compatible =3D "richtek,rt1711h", }, >> + {}, >> +}; >> +MODULE_DEVICE_TABLE(of, rt1711h_of_match); >> +#endif >> + >> +static struct i2c_driver rt1711h_i2c_driver =3D { >> + .driver =3D { >> + .name =3D "rt1711h", >> + .of_match_table =3D of_match_ptr(rt1711h_of_match), >> + }, >> + .probe =3D rt1711h_probe, >> + .remove =3D rt1711h_remove, >> + .id_table =3D rt1711h_id, >> +}; >> +module_i2c_driver(rt1711h_i2c_driver); >> + >> +MODULE_AUTHOR("ShuFan Lee "); >> +MODULE_DESCRIPTION("RT1711H USB Type-C Port Controller Interface >> Driver"); >> +MODULE_LICENSE("GPL"); >> > --=20 Best Regards, =E6=9B=B8=E5=B8=86