* [RFC PATCH 0/2] usb: typec: Add driver for Microchip sama7g5 tcpc
@ 2021-03-29 21:33 ` cristian.birsan
0 siblings, 0 replies; 9+ messages in thread
From: cristian.birsan @ 2021-03-29 21:33 UTC (permalink / raw)
To: linux, heikki.krogerus, gregkh, robh+dt
Cc: linux-usb, linux-kernel, linux-arm-kernel, devicetree, Cristian Birsan
From: Cristian Birsan <cristian.birsan@microchip.com>
This patch set adds initial driver support for Microchip USB Type-C Port
Controller (TCPC) embedded in sama7g5 SoC.
The controller does not implement power delivery and the driver uses dummy
functions to register the port with TCPM. The current silicon version is
not able to trigger interrupts so the driver will poll for changes on
CC1/CC2 lines.
Support for sink is implemented and tested with an USB device. The plan is
to extend the driver and add source support.
Cristian Birsan (2):
dt-bindings: usb: Add DT bindings for Microchip sama7g5 tcpc
usb: typec: sama7g5_tcpc: add driver for Microchip sama7g5 tcpc
.../bindings/usb/microchip,sama7g5-tcpc.yaml | 80 +++
drivers/usb/typec/tcpm/Kconfig | 8 +
drivers/usb/typec/tcpm/Makefile | 1 +
drivers/usb/typec/tcpm/sama7g5_tcpc.c | 602 ++++++++++++++++++
4 files changed, 691 insertions(+)
create mode 100644 Documentation/devicetree/bindings/usb/microchip,sama7g5-tcpc.yaml
create mode 100644 drivers/usb/typec/tcpm/sama7g5_tcpc.c
--
2.25.1
^ permalink raw reply [flat|nested] 9+ messages in thread
* [RFC PATCH 0/2] usb: typec: Add driver for Microchip sama7g5 tcpc
@ 2021-03-29 21:33 ` cristian.birsan
0 siblings, 0 replies; 9+ messages in thread
From: cristian.birsan @ 2021-03-29 21:33 UTC (permalink / raw)
To: linux, heikki.krogerus, gregkh, robh+dt
Cc: linux-usb, linux-kernel, linux-arm-kernel, devicetree, Cristian Birsan
From: Cristian Birsan <cristian.birsan@microchip.com>
This patch set adds initial driver support for Microchip USB Type-C Port
Controller (TCPC) embedded in sama7g5 SoC.
The controller does not implement power delivery and the driver uses dummy
functions to register the port with TCPM. The current silicon version is
not able to trigger interrupts so the driver will poll for changes on
CC1/CC2 lines.
Support for sink is implemented and tested with an USB device. The plan is
to extend the driver and add source support.
Cristian Birsan (2):
dt-bindings: usb: Add DT bindings for Microchip sama7g5 tcpc
usb: typec: sama7g5_tcpc: add driver for Microchip sama7g5 tcpc
.../bindings/usb/microchip,sama7g5-tcpc.yaml | 80 +++
drivers/usb/typec/tcpm/Kconfig | 8 +
drivers/usb/typec/tcpm/Makefile | 1 +
drivers/usb/typec/tcpm/sama7g5_tcpc.c | 602 ++++++++++++++++++
4 files changed, 691 insertions(+)
create mode 100644 Documentation/devicetree/bindings/usb/microchip,sama7g5-tcpc.yaml
create mode 100644 drivers/usb/typec/tcpm/sama7g5_tcpc.c
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 9+ messages in thread
* [RFC PATCH 1/2] dt-bindings: usb: Add DT bindings for Microchip sama7g5 tcpc
2021-03-29 21:33 ` cristian.birsan
@ 2021-03-29 21:33 ` cristian.birsan
-1 siblings, 0 replies; 9+ messages in thread
From: cristian.birsan @ 2021-03-29 21:33 UTC (permalink / raw)
To: linux, heikki.krogerus, gregkh, robh+dt
Cc: linux-usb, linux-kernel, linux-arm-kernel, devicetree, Cristian Birsan
From: Cristian Birsan <cristian.birsan@microchip.com>
This patch adds DT bindings for the new Microchip USB Type-C Port
Controller (TCPC) embedded in sama7g5 SoC.
Signed-off-by: Cristian Birsan <cristian.birsan@microchip.com>
---
.../bindings/usb/microchip,sama7g5-tcpc.yaml | 80 +++++++++++++++++++
1 file changed, 80 insertions(+)
create mode 100644 Documentation/devicetree/bindings/usb/microchip,sama7g5-tcpc.yaml
diff --git a/Documentation/devicetree/bindings/usb/microchip,sama7g5-tcpc.yaml b/Documentation/devicetree/bindings/usb/microchip,sama7g5-tcpc.yaml
new file mode 100644
index 000000000000..e1b80957e111
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/microchip,sama7g5-tcpc.yaml
@@ -0,0 +1,80 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/usb/microchip,sama7g5-tcpc.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Microchip SAMA7G5 Type-C port controller bindings
+
+maintainers:
+ - Cristian Birsan <cristian.birsan@microchip.com>
+
+properties:
+ compatible:
+ enum:
+ - microchip,sama7g5-tcpc
+
+ reg:
+ maxItems: 1
+
+ vbus-supply:
+ description: vbus power supply (5V) phandle
+
+ microchip,vbus-gpio:
+ description: vbus detect gpio
+
+ connector:
+ type: object
+
+ allOf:
+ - $ref: ../connector/usb-connector.yaml
+
+ properties:
+ compatible:
+ const: usb-c-connector
+
+ power-role: true
+
+ required:
+ - compatible
+
+required:
+ - compatible
+ - reg
+ - connector
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/at91.h>
+ #include <dt-bindings/usb/pd.h>
+ tcpcb: tcpcb@e0844000 {
+ compatible = "microchip,sama7g5-typec";
+ reg = <0xe0844000 0x3fff>;
+ clocks = <&pmc PMC_TYPE_PERIPHERAL 95>, <&pmc PMC_TYPE_GCK 95>;
+ clock-names = "pclk", "gclk";
+
+ usb_con: connector {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "usb-c-connector";
+ label = "USB-C";
+ data-role = "device";
+ power-role = "sink";
+ try-power-role = "sink";
+ source-pdos = <PDO_FIXED(5000, 500,
+ PDO_FIXED_USB_COMM)>;
+ sink-pdos = <PDO_FIXED(5000, 500,
+ PDO_FIXED_USB_COMM)>;
+ op-sink-microwatt = <2500000>;
+
+ port@1 {
+ reg = <1>;
+ usb_con_hs: endpoint {
+ remote-endpoint = <&usb_phy1>;
+ };
+ };
+ };
+ };
+...
--
2.25.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [RFC PATCH 1/2] dt-bindings: usb: Add DT bindings for Microchip sama7g5 tcpc
@ 2021-03-29 21:33 ` cristian.birsan
0 siblings, 0 replies; 9+ messages in thread
From: cristian.birsan @ 2021-03-29 21:33 UTC (permalink / raw)
To: linux, heikki.krogerus, gregkh, robh+dt
Cc: linux-usb, linux-kernel, linux-arm-kernel, devicetree, Cristian Birsan
From: Cristian Birsan <cristian.birsan@microchip.com>
This patch adds DT bindings for the new Microchip USB Type-C Port
Controller (TCPC) embedded in sama7g5 SoC.
Signed-off-by: Cristian Birsan <cristian.birsan@microchip.com>
---
.../bindings/usb/microchip,sama7g5-tcpc.yaml | 80 +++++++++++++++++++
1 file changed, 80 insertions(+)
create mode 100644 Documentation/devicetree/bindings/usb/microchip,sama7g5-tcpc.yaml
diff --git a/Documentation/devicetree/bindings/usb/microchip,sama7g5-tcpc.yaml b/Documentation/devicetree/bindings/usb/microchip,sama7g5-tcpc.yaml
new file mode 100644
index 000000000000..e1b80957e111
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/microchip,sama7g5-tcpc.yaml
@@ -0,0 +1,80 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/usb/microchip,sama7g5-tcpc.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Microchip SAMA7G5 Type-C port controller bindings
+
+maintainers:
+ - Cristian Birsan <cristian.birsan@microchip.com>
+
+properties:
+ compatible:
+ enum:
+ - microchip,sama7g5-tcpc
+
+ reg:
+ maxItems: 1
+
+ vbus-supply:
+ description: vbus power supply (5V) phandle
+
+ microchip,vbus-gpio:
+ description: vbus detect gpio
+
+ connector:
+ type: object
+
+ allOf:
+ - $ref: ../connector/usb-connector.yaml
+
+ properties:
+ compatible:
+ const: usb-c-connector
+
+ power-role: true
+
+ required:
+ - compatible
+
+required:
+ - compatible
+ - reg
+ - connector
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/at91.h>
+ #include <dt-bindings/usb/pd.h>
+ tcpcb: tcpcb@e0844000 {
+ compatible = "microchip,sama7g5-typec";
+ reg = <0xe0844000 0x3fff>;
+ clocks = <&pmc PMC_TYPE_PERIPHERAL 95>, <&pmc PMC_TYPE_GCK 95>;
+ clock-names = "pclk", "gclk";
+
+ usb_con: connector {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "usb-c-connector";
+ label = "USB-C";
+ data-role = "device";
+ power-role = "sink";
+ try-power-role = "sink";
+ source-pdos = <PDO_FIXED(5000, 500,
+ PDO_FIXED_USB_COMM)>;
+ sink-pdos = <PDO_FIXED(5000, 500,
+ PDO_FIXED_USB_COMM)>;
+ op-sink-microwatt = <2500000>;
+
+ port@1 {
+ reg = <1>;
+ usb_con_hs: endpoint {
+ remote-endpoint = <&usb_phy1>;
+ };
+ };
+ };
+ };
+...
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [RFC PATCH 2/2] usb: typec: sama7g5_tcpc: add driver for Microchip sama7g5 tcpc
2021-03-29 21:33 ` cristian.birsan
@ 2021-03-29 21:33 ` cristian.birsan
-1 siblings, 0 replies; 9+ messages in thread
From: cristian.birsan @ 2021-03-29 21:33 UTC (permalink / raw)
To: linux, heikki.krogerus, gregkh, robh+dt
Cc: linux-usb, linux-kernel, linux-arm-kernel, devicetree, Cristian Birsan
From: Cristian Birsan <cristian.birsan@microchip.com>
This patch adds initial driver support for the new Microchip USB
Type-C Port Controller (TCPC) embedded in sama7g5 SoC.
Signed-off-by: Cristian Birsan <cristian.birsan@microchip.com>
---
drivers/usb/typec/tcpm/Kconfig | 8 +
drivers/usb/typec/tcpm/Makefile | 1 +
drivers/usb/typec/tcpm/sama7g5_tcpc.c | 602 ++++++++++++++++++++++++++
3 files changed, 611 insertions(+)
create mode 100644 drivers/usb/typec/tcpm/sama7g5_tcpc.c
diff --git a/drivers/usb/typec/tcpm/Kconfig b/drivers/usb/typec/tcpm/Kconfig
index 557f392fe24d..8ba0fd85741f 100644
--- a/drivers/usb/typec/tcpm/Kconfig
+++ b/drivers/usb/typec/tcpm/Kconfig
@@ -52,6 +52,14 @@ config TYPEC_FUSB302
Type-C Port Controller Manager to provide USB PD and USB
Type-C functionalities.
+config TYPEC_SAMA7G5
+ tristate "Microchip SAMA7G5 Type-C Port Controller driver"
+ select REGMAP_MMIO
+ help
+ Say Y or M here if your system has SAMA7G5 TCPC controller.
+ It works with Type-C Port Controller Manager to provide USB
+ Type-C functionalities.
+
config TYPEC_WCOVE
tristate "Intel WhiskeyCove PMIC USB Type-C PHY driver"
depends on ACPI
diff --git a/drivers/usb/typec/tcpm/Makefile b/drivers/usb/typec/tcpm/Makefile
index 7d499f3569fd..9abe8a7ae1cc 100644
--- a/drivers/usb/typec/tcpm/Makefile
+++ b/drivers/usb/typec/tcpm/Makefile
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_TYPEC_TCPM) += tcpm.o
obj-$(CONFIG_TYPEC_FUSB302) += fusb302.o
+obj-$(CONFIG_TYPEC_SAMA7G5) += sama7g5_tcpc.o
obj-$(CONFIG_TYPEC_WCOVE) += typec_wcove.o
typec_wcove-y := wcove.o
obj-$(CONFIG_TYPEC_TCPCI) += tcpci.o
diff --git a/drivers/usb/typec/tcpm/sama7g5_tcpc.c b/drivers/usb/typec/tcpm/sama7g5_tcpc.c
new file mode 100644
index 000000000000..d1a912976418
--- /dev/null
+++ b/drivers/usb/typec/tcpm/sama7g5_tcpc.c
@@ -0,0 +1,602 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Microchip SAMA7G5 Type-C Port Controller Driver
+ *
+ * Copyright (C) 2021 Microchip Technology, Inc. and its subsidiaries
+ */
+
+#include <linux/clk.h>
+#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_gpio.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <linux/usb/pd.h>
+#include <linux/usb/tcpm.h>
+#include <linux/usb/typec.h>
+
+#define SAMA7G5_TCPC_GCLK 32000
+
+/* TCPC registers offsets */
+#define TCPC_CR 0x80 /* TCPC Control Register */
+#define TCPC_UPC 0xA0 /* TCPC PHY Control Register */
+#define TCPC_UPS 0xA4 /* TCPC PHY Status Register */
+
+#define TCPC_CR_RESET 0x54434301 /* Magic value */
+
+/* TCPC PHY Control Register */
+#define TCPC_UPC_BCDETE BIT(29)
+#define TCPC_UPC_BCVSRCE BIT(28)
+#define TCPC_UPC_BCDETSEL BIT(27)
+#define TCPC_UPC_BCIDPSRCE BIT(26)
+#define TCPC_UPC_DMPDFE BIT(25)
+#define TCPC_UPC_DMPDFD BIT(24)
+#define TCPC_UPC_IP_OFF (0 << 12)
+#define TCPC_UPC_IP_0P5 (1 << 12)
+#define TCPC_UPC_IP_1P5 (2 << 12)
+#define TCPC_UPC_IP_3P0 (3 << 12)
+#define TCPC_UPC_THRESHOLD0 (0 << 8)
+#define TCPC_UPC_THRESHOLD2 (2 << 8)
+#define TCPC_UPC_THRESHOLD4 (4 << 8)
+#define TCPC_UPC_THRESHOLD6 (6 << 8)
+
+/* TCPC PHY Status Register */
+#define TCPC_UPS_CC2RDT BIT(4)
+#define TCPC_UPS_CC1ID BIT(3)
+#define TCPC_UPS_CC_MASK GENMASK(4, 3)
+#define TCPC_UPS_CHGDCP BIT(2)
+#define TCPC_UPS_DM BIT(1)
+#define TCPC_UPS_DP BIT(0)
+
+#define TCPC_VERSION 0xFC
+
+/* USB Type-C measurement timings */
+#define T_CC_MEASURE 100 /* 100 ms */
+
+#define SAMA7G5_TCPC_VBUS_IRQFLAGS (IRQF_ONESHOT \
+ | IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING)
+
+struct sama7g5_tcpc {
+ struct device *dev;
+
+ struct workqueue_struct *wq;
+ struct delayed_work measure_work;
+
+ struct regmap *regmap;
+ void __iomem *base;
+
+ struct clk *pclk;
+ struct clk *gclk;
+
+ struct gpio_desc *vbus_pin;
+ struct regulator *vbus;
+
+ /* lock for sharing states */
+ struct mutex lock;
+
+ /* port status */
+ enum typec_cc_polarity cc_polarity;
+ enum typec_cc_status cc1_status;
+ enum typec_cc_status cc2_status;
+ enum typec_cc_status cc1_status_prev;
+ enum typec_cc_status cc2_status_prev;
+
+ /* mutex used for VBUS detection */
+ struct mutex vbus_mutex;
+ int vbus_present;
+ int vbus_present_prev;
+
+ unsigned int phy_status;
+ unsigned int phy_status_old;
+
+ struct tcpc_dev tcpc;
+ struct tcpm_port *tcpm;
+};
+
+#define tcpc_to_sama7g5_tcpc(_tcpc_) \
+ container_of(_tcpc_, struct sama7g5_tcpc, tcpc)
+
+static bool sama7g5_tcpc_readable_reg(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case TCPC_CR:
+ case TCPC_UPC:
+ case TCPC_UPS:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool sama7g5_tcpc_writeable_reg(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case TCPC_CR:
+ case TCPC_UPC:
+ case TCPC_UPS:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static const struct regmap_config sama7g5_tcpc_regmap_config = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+ .max_register = TCPC_VERSION,
+ .readable_reg = sama7g5_tcpc_readable_reg,
+ .writeable_reg = sama7g5_tcpc_writeable_reg,
+};
+
+static int sama7g5_tcpc_get_vbus(struct tcpc_dev *tcpc)
+{
+ struct sama7g5_tcpc *sama7g5_tcpc = tcpc_to_sama7g5_tcpc(tcpc);
+ int ret;
+
+ mutex_lock(&sama7g5_tcpc->vbus_mutex);
+ ret = sama7g5_tcpc->vbus_present ? 1 : 0;
+ mutex_unlock(&sama7g5_tcpc->vbus_mutex);
+
+ return ret;
+}
+
+static int sama7g5_tcpc_set_vbus(struct tcpc_dev *tcpc, bool on, bool sink)
+{
+ struct sama7g5_tcpc *sama7g5_tcpc = tcpc_to_sama7g5_tcpc(tcpc);
+ int ret;
+
+ mutex_lock(&sama7g5_tcpc->vbus_mutex);
+ if (on)
+ ret = regulator_enable(sama7g5_tcpc->vbus);
+ else
+ ret = regulator_disable(sama7g5_tcpc->vbus);
+ mutex_unlock(&sama7g5_tcpc->vbus_mutex);
+
+ return ret;
+}
+
+static int sama7g5_tcpc_set_vconn(struct tcpc_dev *tcpc, bool on)
+{
+ /* VCONN is not supported */
+ return -EPERM;
+}
+
+static int sama7g5_tcpc_get_cc(struct tcpc_dev *tcpc, enum typec_cc_status *cc1,
+ enum typec_cc_status *cc2)
+{
+ struct sama7g5_tcpc *sama7g5_tcpc = tcpc_to_sama7g5_tcpc(tcpc);
+
+ mutex_lock(&sama7g5_tcpc->lock);
+ *cc1 = sama7g5_tcpc->cc1_status;
+ *cc2 = sama7g5_tcpc->cc2_status;
+ mutex_unlock(&sama7g5_tcpc->lock);
+
+ return 0;
+}
+
+static int sama7g5_tcpc_set_cc(struct tcpc_dev *tcpc, enum typec_cc_status cc)
+{
+ struct sama7g5_tcpc *sama7g5_tcpc = tcpc_to_sama7g5_tcpc(tcpc);
+ unsigned int ctrl;
+ int ret = 0;
+
+ mutex_lock(&sama7g5_tcpc->lock);
+ switch (cc) {
+ case TYPEC_CC_RD:
+ ctrl = TCPC_UPC_IP_OFF;
+ break;
+ case TYPEC_CC_RP_DEF:
+ ctrl = TCPC_UPC_IP_0P5;
+ break;
+ default:
+ ret = -EINVAL;
+ goto done;
+ }
+ ret = regmap_write(sama7g5_tcpc->regmap, TCPC_UPC, ctrl);
+done:
+ mutex_unlock(&sama7g5_tcpc->lock);
+ return ret;
+}
+
+static int sama7g5_tcpc_set_polarity(struct tcpc_dev *tcpc,
+ enum typec_cc_polarity pol)
+{
+ return 0;
+}
+
+static int sama7g5_tcpc_set_roles(struct tcpc_dev *tcpc, bool attached,
+ enum typec_role role, enum typec_data_role data)
+{
+ return 0;
+}
+
+static int sama7g5_tcpc_set_pd_rx(struct tcpc_dev *tcpc, bool on)
+{
+ return -EPERM;
+}
+
+static int sama7g5_tcpc_pd_transmit(struct tcpc_dev *tcpc,
+ enum tcpm_transmit_type type,
+ const struct pd_message *msg)
+{
+ return -EPERM;
+}
+
+static int sama7g5_tcpc_start_toggling(struct tcpc_dev *tcpc,
+ enum typec_port_type port_type,
+ enum typec_cc_status cc)
+{
+ return -EOPNOTSUPP;
+}
+
+static void _sama7g5_tcpc_measure_snk(struct sama7g5_tcpc *sama7g5_tcpc)
+{
+ int ret;
+
+ /* Save previous CC1/CC2 state */
+ sama7g5_tcpc->cc1_status_prev = sama7g5_tcpc->cc1_status;
+ sama7g5_tcpc->cc2_status_prev = sama7g5_tcpc->cc2_status;
+
+ /* Comparator Threshold 2 */
+ ret = regmap_write(sama7g5_tcpc->regmap, TCPC_UPC, TCPC_UPC_IP_OFF |
+ TCPC_UPC_THRESHOLD2);
+ if (ret)
+ dev_err(sama7g5_tcpc->dev, "failed to wite register: %d\n",
+ ret);
+
+ usleep_range(560, 1000);
+
+ ret = regmap_read(sama7g5_tcpc->regmap, TCPC_UPS,
+ &sama7g5_tcpc->phy_status);
+ if (ret)
+ dev_err(sama7g5_tcpc->dev, "failed to read register: %d\n",
+ ret);
+
+ if (!(sama7g5_tcpc->phy_status & TCPC_UPS_CC_MASK)) {
+ /* VRa*/
+ sama7g5_tcpc->cc1_status = TYPEC_CC_OPEN;
+ sama7g5_tcpc->cc2_status = TYPEC_CC_OPEN;
+ return;
+ }
+
+ /* CC1 or CC2 is connected wait for PD messages to end ~ 30ms */
+ usleep_range(30000, 35000);
+
+ /* Comparator Threshold 4 */
+ sama7g5_tcpc->phy_status_old = sama7g5_tcpc->phy_status;
+
+ ret = regmap_write(sama7g5_tcpc->regmap, TCPC_UPC, TCPC_UPC_IP_OFF |
+ TCPC_UPC_THRESHOLD4);
+ if (ret)
+ dev_err(sama7g5_tcpc->dev, "failed to wite register: %d\n",
+ ret);
+
+ usleep_range(560, 1000);
+ ret = regmap_read(sama7g5_tcpc->regmap, TCPC_UPS,
+ &sama7g5_tcpc->phy_status);
+ if (ret)
+ dev_err(sama7g5_tcpc->dev, "failed to read register: %d\n",
+ ret);
+
+ if ((sama7g5_tcpc->phy_status_old & TCPC_UPS_CC1ID) &&
+ (!(sama7g5_tcpc->phy_status & TCPC_UPS_CC1ID))) {
+ sama7g5_tcpc->cc1_status = TYPEC_CC_RP_DEF;
+ sama7g5_tcpc->cc2_status = TYPEC_CC_OPEN;
+ return;
+ }
+
+ if ((sama7g5_tcpc->phy_status_old & TCPC_UPS_CC2RDT) &&
+ (!(sama7g5_tcpc->phy_status & TCPC_UPS_CC2RDT))) {
+ sama7g5_tcpc->cc1_status = TYPEC_CC_OPEN;
+ sama7g5_tcpc->cc2_status = TYPEC_CC_RP_DEF;
+ return;
+ }
+
+ /* Comparator Threshold 6 */
+ sama7g5_tcpc->phy_status_old = sama7g5_tcpc->phy_status;
+
+ ret = regmap_write(sama7g5_tcpc->regmap, TCPC_UPC, TCPC_UPC_IP_OFF |
+ TCPC_UPC_THRESHOLD6);
+ if (ret)
+ dev_err(sama7g5_tcpc->dev, "failed to wite register: %d\n",
+ ret);
+
+ usleep_range(560, 1000);
+ ret = regmap_read(sama7g5_tcpc->regmap, TCPC_UPS,
+ &sama7g5_tcpc->phy_status);
+ if (ret)
+ dev_err(sama7g5_tcpc->dev, "failed to read register: %d\n",
+ ret);
+
+ if ((sama7g5_tcpc->phy_status_old & TCPC_UPS_CC1ID) &&
+ (!(sama7g5_tcpc->phy_status & TCPC_UPS_CC1ID))) {
+ sama7g5_tcpc->cc1_status = TYPEC_CC_RP_1_5;
+ sama7g5_tcpc->cc2_status = TYPEC_CC_OPEN;
+ return;
+ }
+
+ if ((sama7g5_tcpc->phy_status_old & TCPC_UPS_CC1ID) &&
+ ((sama7g5_tcpc->phy_status & TCPC_UPS_CC1ID))) {
+ sama7g5_tcpc->cc1_status = TYPEC_CC_RP_3_0;
+ sama7g5_tcpc->cc2_status = TYPEC_CC_OPEN;
+ return;
+ }
+
+ if ((sama7g5_tcpc->phy_status_old & TCPC_UPS_CC2RDT) &&
+ (!(sama7g5_tcpc->phy_status & TCPC_UPS_CC2RDT))) {
+ sama7g5_tcpc->cc1_status = TYPEC_CC_OPEN;
+ sama7g5_tcpc->cc2_status = TYPEC_CC_RP_1_5;
+ return;
+ }
+
+ if ((sama7g5_tcpc->phy_status_old & TCPC_UPS_CC2RDT) &&
+ ((sama7g5_tcpc->phy_status & TCPC_UPS_CC2RDT))) {
+ sama7g5_tcpc->cc1_status = TYPEC_CC_OPEN;
+ sama7g5_tcpc->cc2_status = TYPEC_CC_RP_3_0;
+ return;
+ }
+}
+
+static void sama7g5_tcpc_measure_work(struct work_struct *work)
+{
+ struct sama7g5_tcpc *port = container_of(work, struct sama7g5_tcpc,
+ measure_work.work);
+
+ mutex_lock(&port->lock);
+
+ _sama7g5_tcpc_measure_snk(port);
+
+ /* Check if the state has changed and notify TCPM */
+ if (port->cc1_status != port->cc1_status_prev ||
+ port->cc2_status != port->cc2_status_prev)
+ tcpm_cc_change(port->tcpm);
+
+ mod_delayed_work(port->wq, &port->measure_work,
+ msecs_to_jiffies(T_CC_MEASURE));
+
+ mutex_unlock(&port->lock);
+}
+
+static int sama7g5_tcpc_init(struct tcpc_dev *tcpc)
+{
+ struct sama7g5_tcpc *sama7g5_tcpc = tcpc_to_sama7g5_tcpc(tcpc);
+ int ret;
+
+ ret = regmap_write(sama7g5_tcpc->regmap, TCPC_CR, TCPC_CR_RESET);
+ if (ret)
+ return ret;
+
+ sama7g5_tcpc->wq =
+ create_singlethread_workqueue(dev_name(sama7g5_tcpc->dev));
+ if (!sama7g5_tcpc->wq)
+ return -ENOMEM;
+
+ INIT_DELAYED_WORK(&sama7g5_tcpc->measure_work,
+ sama7g5_tcpc_measure_work);
+
+ sama7g5_tcpc->cc1_status = TYPEC_CC_OPEN;
+ sama7g5_tcpc->cc2_status = TYPEC_CC_OPEN;
+ sama7g5_tcpc->cc1_status_prev = TYPEC_CC_OPEN;
+ sama7g5_tcpc->cc2_status_prev = TYPEC_CC_OPEN;
+ sama7g5_tcpc->cc_polarity = TYPEC_POLARITY_CC1;
+
+ /* We do not have an interrupt so polling only */
+ mod_delayed_work(sama7g5_tcpc->wq, &sama7g5_tcpc->measure_work,
+ msecs_to_jiffies(T_CC_MEASURE));
+
+ /* Enable VBUS detection */
+ if (sama7g5_tcpc->vbus_pin)
+ enable_irq(gpiod_to_irq(sama7g5_tcpc->vbus_pin));
+
+ return 0;
+}
+
+static int vbus_is_present(struct sama7g5_tcpc *sama7g5_tcpc)
+{
+ if (sama7g5_tcpc->vbus_pin)
+ return gpiod_get_value(sama7g5_tcpc->vbus_pin);
+
+ /* No Vbus detection: Assume always present */
+ return 1;
+}
+
+static irqreturn_t sama7g5_vbus_irq_thread(int irq, void *devid)
+{
+ struct sama7g5_tcpc *sama7g5_tcpc = devid;
+
+ /* debounce */
+ udelay(10);
+
+ mutex_lock(&sama7g5_tcpc->vbus_mutex);
+
+ sama7g5_tcpc->vbus_present = vbus_is_present(sama7g5_tcpc);
+ if (sama7g5_tcpc->vbus_present != sama7g5_tcpc->vbus_present_prev) {
+ /* VBUS changed, notify TCPM */
+ tcpm_vbus_change(sama7g5_tcpc->tcpm);
+ sama7g5_tcpc->vbus_present_prev = sama7g5_tcpc->vbus_present;
+ }
+
+ mutex_unlock(&sama7g5_tcpc->vbus_mutex);
+ return IRQ_HANDLED;
+}
+
+static int sama7g5_tcpc_probe(struct platform_device *pdev)
+{
+ int ret;
+ struct sama7g5_tcpc *sama7g5_tcpc;
+
+ struct resource *mem;
+ void __iomem *base;
+
+ sama7g5_tcpc = devm_kzalloc(&pdev->dev, sizeof(*sama7g5_tcpc),
+ GFP_KERNEL);
+ if (!sama7g5_tcpc)
+ return -ENOMEM;
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ base = devm_ioremap_resource(&pdev->dev, mem);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+ sama7g5_tcpc->base = base;
+
+ sama7g5_tcpc->regmap = devm_regmap_init_mmio(&pdev->dev, base,
+ &sama7g5_tcpc_regmap_config);
+ if (IS_ERR(sama7g5_tcpc->regmap)) {
+ dev_err(&pdev->dev, "Regmap init failed\n");
+ return PTR_ERR(sama7g5_tcpc->regmap);
+ }
+
+ /* Get the peripheral clock */
+ sama7g5_tcpc->pclk = devm_clk_get(&pdev->dev, "pclk");
+ if (IS_ERR(sama7g5_tcpc->pclk)) {
+ ret = PTR_ERR(sama7g5_tcpc->pclk);
+ dev_err(&pdev->dev,
+ "failed to get the peripheral clock: %d\n", ret);
+ return ret;
+ }
+
+ ret = clk_prepare_enable(sama7g5_tcpc->pclk);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "failed to enable the peripheral clock: %d\n", ret);
+ return ret;
+ }
+
+ /* Get the generic clock */
+ sama7g5_tcpc->gclk = devm_clk_get(&pdev->dev, "gclk");
+ if (IS_ERR(sama7g5_tcpc->gclk)) {
+ ret = PTR_ERR(sama7g5_tcpc->gclk);
+ dev_err(&pdev->dev,
+ "failed to get the PMC generic clock: %d\n", ret);
+ return ret;
+ }
+
+ ret = clk_set_rate(sama7g5_tcpc->gclk, SAMA7G5_TCPC_GCLK);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "unable to change gclk rate to: %u\n",
+ SAMA7G5_TCPC_GCLK);
+ return ret;
+ }
+
+ ret = clk_prepare_enable(sama7g5_tcpc->gclk);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "failed to enable the generic clock: %d\n", ret);
+ return ret;
+ }
+
+ mutex_init(&sama7g5_tcpc->lock);
+ mutex_init(&sama7g5_tcpc->vbus_mutex);
+
+ sama7g5_tcpc->vbus_pin = devm_gpiod_get_optional(&pdev->dev,
+ "microchip,vbus", GPIOD_IN);
+
+ if (IS_ERR(sama7g5_tcpc->vbus_pin)) {
+ ret = PTR_ERR(sama7g5_tcpc->vbus_pin);
+ dev_err(&pdev->dev, "unable to claim vbus-gpio: %d\n", ret);
+ }
+
+ sama7g5_tcpc->vbus = devm_regulator_get_optional(&pdev->dev, "vbus");
+
+ if (IS_ERR(sama7g5_tcpc->vbus)) {
+ ret = PTR_ERR(sama7g5_tcpc->vbus);
+ dev_err(&pdev->dev, "unable to claim vbus-supply: %d\n", ret);
+ }
+
+ if (sama7g5_tcpc->vbus_pin) {
+ irq_set_status_flags(gpiod_to_irq(sama7g5_tcpc->vbus_pin),
+ IRQ_NOAUTOEN);
+ ret = devm_request_threaded_irq(&pdev->dev,
+ gpiod_to_irq(sama7g5_tcpc->vbus_pin), NULL,
+ sama7g5_vbus_irq_thread,
+ SAMA7G5_TCPC_VBUS_IRQFLAGS,
+ "sama7g5_tcpc", sama7g5_tcpc);
+ if (ret) {
+ sama7g5_tcpc->vbus_pin = NULL;
+ dev_warn(&pdev->dev,
+ "failed to request vbus irq; "
+ "assuming always on\n");
+ }
+ }
+
+ sama7g5_tcpc->dev = &pdev->dev;
+ platform_set_drvdata(pdev, sama7g5_tcpc);
+
+ sama7g5_tcpc->tcpc.init = sama7g5_tcpc_init;
+ sama7g5_tcpc->tcpc.get_vbus = sama7g5_tcpc_get_vbus;
+ sama7g5_tcpc->tcpc.set_vbus = sama7g5_tcpc_set_vbus;
+ sama7g5_tcpc->tcpc.set_cc = sama7g5_tcpc_set_cc;
+ sama7g5_tcpc->tcpc.get_cc = sama7g5_tcpc_get_cc;
+ sama7g5_tcpc->tcpc.set_polarity = sama7g5_tcpc_set_polarity;
+ sama7g5_tcpc->tcpc.set_vconn = sama7g5_tcpc_set_vconn;
+ sama7g5_tcpc->tcpc.start_toggling = sama7g5_tcpc_start_toggling;
+ sama7g5_tcpc->tcpc.set_pd_rx = sama7g5_tcpc_set_pd_rx;
+ sama7g5_tcpc->tcpc.set_roles = sama7g5_tcpc_set_roles;
+ sama7g5_tcpc->tcpc.pd_transmit = sama7g5_tcpc_pd_transmit;
+
+ sama7g5_tcpc->tcpc.fwnode = device_get_named_child_node(&pdev->dev,
+ "connector");
+ if (!sama7g5_tcpc->tcpc.fwnode) {
+ dev_err(&pdev->dev, "Can't find connector node.\n");
+ return -EINVAL;
+ }
+
+ sama7g5_tcpc->tcpm = tcpm_register_port(sama7g5_tcpc->dev,
+ &sama7g5_tcpc->tcpc);
+ if (IS_ERR(sama7g5_tcpc->tcpm)) {
+ fwnode_remove_software_node(sama7g5_tcpc->tcpc.fwnode);
+ return PTR_ERR(sama7g5_tcpc->tcpm);
+ }
+
+ return 0;
+}
+
+static int sama7g5_tcpc_remove(struct platform_device *pdev)
+{
+ struct sama7g5_tcpc *sama7g5_tcpc;
+
+ sama7g5_tcpc = platform_get_drvdata(pdev);
+
+ /* Mask everything */
+ if (sama7g5_tcpc->vbus_pin)
+ disable_irq(gpiod_to_irq(sama7g5_tcpc->vbus_pin));
+
+
+ if (!IS_ERR_OR_NULL(sama7g5_tcpc->tcpm))
+ tcpm_unregister_port(sama7g5_tcpc->tcpm);
+
+ destroy_workqueue(sama7g5_tcpc->wq);
+
+ clk_disable_unprepare(sama7g5_tcpc->gclk);
+ clk_disable_unprepare(sama7g5_tcpc->pclk);
+
+ return 0;
+}
+
+static const struct of_device_id sama7g5_tcpc_dt_ids[] = {
+ {
+ .compatible = "microchip,sama7g5-tcpc",
+ },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, sama7g5_tcpc_dt_ids);
+
+static struct platform_driver sama7g5_tcpc_driver = {
+ .probe = sama7g5_tcpc_probe,
+ .remove = sama7g5_tcpc_remove,
+ .driver = {
+ .name = "microchip,sama7g5-tcpc",
+ .of_match_table = sama7g5_tcpc_dt_ids,
+ },
+};
+module_platform_driver(sama7g5_tcpc_driver);
+
+MODULE_AUTHOR("Cristian Birsan <cristian.birsan@microchip.com>");
+MODULE_DESCRIPTION("Microchip SAMA7G5 Type-C Port Controller Driver");
+MODULE_LICENSE("GPL");
--
2.25.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [RFC PATCH 2/2] usb: typec: sama7g5_tcpc: add driver for Microchip sama7g5 tcpc
@ 2021-03-29 21:33 ` cristian.birsan
0 siblings, 0 replies; 9+ messages in thread
From: cristian.birsan @ 2021-03-29 21:33 UTC (permalink / raw)
To: linux, heikki.krogerus, gregkh, robh+dt
Cc: linux-usb, linux-kernel, linux-arm-kernel, devicetree, Cristian Birsan
From: Cristian Birsan <cristian.birsan@microchip.com>
This patch adds initial driver support for the new Microchip USB
Type-C Port Controller (TCPC) embedded in sama7g5 SoC.
Signed-off-by: Cristian Birsan <cristian.birsan@microchip.com>
---
drivers/usb/typec/tcpm/Kconfig | 8 +
drivers/usb/typec/tcpm/Makefile | 1 +
drivers/usb/typec/tcpm/sama7g5_tcpc.c | 602 ++++++++++++++++++++++++++
3 files changed, 611 insertions(+)
create mode 100644 drivers/usb/typec/tcpm/sama7g5_tcpc.c
diff --git a/drivers/usb/typec/tcpm/Kconfig b/drivers/usb/typec/tcpm/Kconfig
index 557f392fe24d..8ba0fd85741f 100644
--- a/drivers/usb/typec/tcpm/Kconfig
+++ b/drivers/usb/typec/tcpm/Kconfig
@@ -52,6 +52,14 @@ config TYPEC_FUSB302
Type-C Port Controller Manager to provide USB PD and USB
Type-C functionalities.
+config TYPEC_SAMA7G5
+ tristate "Microchip SAMA7G5 Type-C Port Controller driver"
+ select REGMAP_MMIO
+ help
+ Say Y or M here if your system has SAMA7G5 TCPC controller.
+ It works with Type-C Port Controller Manager to provide USB
+ Type-C functionalities.
+
config TYPEC_WCOVE
tristate "Intel WhiskeyCove PMIC USB Type-C PHY driver"
depends on ACPI
diff --git a/drivers/usb/typec/tcpm/Makefile b/drivers/usb/typec/tcpm/Makefile
index 7d499f3569fd..9abe8a7ae1cc 100644
--- a/drivers/usb/typec/tcpm/Makefile
+++ b/drivers/usb/typec/tcpm/Makefile
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_TYPEC_TCPM) += tcpm.o
obj-$(CONFIG_TYPEC_FUSB302) += fusb302.o
+obj-$(CONFIG_TYPEC_SAMA7G5) += sama7g5_tcpc.o
obj-$(CONFIG_TYPEC_WCOVE) += typec_wcove.o
typec_wcove-y := wcove.o
obj-$(CONFIG_TYPEC_TCPCI) += tcpci.o
diff --git a/drivers/usb/typec/tcpm/sama7g5_tcpc.c b/drivers/usb/typec/tcpm/sama7g5_tcpc.c
new file mode 100644
index 000000000000..d1a912976418
--- /dev/null
+++ b/drivers/usb/typec/tcpm/sama7g5_tcpc.c
@@ -0,0 +1,602 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Microchip SAMA7G5 Type-C Port Controller Driver
+ *
+ * Copyright (C) 2021 Microchip Technology, Inc. and its subsidiaries
+ */
+
+#include <linux/clk.h>
+#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_gpio.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <linux/usb/pd.h>
+#include <linux/usb/tcpm.h>
+#include <linux/usb/typec.h>
+
+#define SAMA7G5_TCPC_GCLK 32000
+
+/* TCPC registers offsets */
+#define TCPC_CR 0x80 /* TCPC Control Register */
+#define TCPC_UPC 0xA0 /* TCPC PHY Control Register */
+#define TCPC_UPS 0xA4 /* TCPC PHY Status Register */
+
+#define TCPC_CR_RESET 0x54434301 /* Magic value */
+
+/* TCPC PHY Control Register */
+#define TCPC_UPC_BCDETE BIT(29)
+#define TCPC_UPC_BCVSRCE BIT(28)
+#define TCPC_UPC_BCDETSEL BIT(27)
+#define TCPC_UPC_BCIDPSRCE BIT(26)
+#define TCPC_UPC_DMPDFE BIT(25)
+#define TCPC_UPC_DMPDFD BIT(24)
+#define TCPC_UPC_IP_OFF (0 << 12)
+#define TCPC_UPC_IP_0P5 (1 << 12)
+#define TCPC_UPC_IP_1P5 (2 << 12)
+#define TCPC_UPC_IP_3P0 (3 << 12)
+#define TCPC_UPC_THRESHOLD0 (0 << 8)
+#define TCPC_UPC_THRESHOLD2 (2 << 8)
+#define TCPC_UPC_THRESHOLD4 (4 << 8)
+#define TCPC_UPC_THRESHOLD6 (6 << 8)
+
+/* TCPC PHY Status Register */
+#define TCPC_UPS_CC2RDT BIT(4)
+#define TCPC_UPS_CC1ID BIT(3)
+#define TCPC_UPS_CC_MASK GENMASK(4, 3)
+#define TCPC_UPS_CHGDCP BIT(2)
+#define TCPC_UPS_DM BIT(1)
+#define TCPC_UPS_DP BIT(0)
+
+#define TCPC_VERSION 0xFC
+
+/* USB Type-C measurement timings */
+#define T_CC_MEASURE 100 /* 100 ms */
+
+#define SAMA7G5_TCPC_VBUS_IRQFLAGS (IRQF_ONESHOT \
+ | IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING)
+
+struct sama7g5_tcpc {
+ struct device *dev;
+
+ struct workqueue_struct *wq;
+ struct delayed_work measure_work;
+
+ struct regmap *regmap;
+ void __iomem *base;
+
+ struct clk *pclk;
+ struct clk *gclk;
+
+ struct gpio_desc *vbus_pin;
+ struct regulator *vbus;
+
+ /* lock for sharing states */
+ struct mutex lock;
+
+ /* port status */
+ enum typec_cc_polarity cc_polarity;
+ enum typec_cc_status cc1_status;
+ enum typec_cc_status cc2_status;
+ enum typec_cc_status cc1_status_prev;
+ enum typec_cc_status cc2_status_prev;
+
+ /* mutex used for VBUS detection */
+ struct mutex vbus_mutex;
+ int vbus_present;
+ int vbus_present_prev;
+
+ unsigned int phy_status;
+ unsigned int phy_status_old;
+
+ struct tcpc_dev tcpc;
+ struct tcpm_port *tcpm;
+};
+
+#define tcpc_to_sama7g5_tcpc(_tcpc_) \
+ container_of(_tcpc_, struct sama7g5_tcpc, tcpc)
+
+static bool sama7g5_tcpc_readable_reg(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case TCPC_CR:
+ case TCPC_UPC:
+ case TCPC_UPS:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool sama7g5_tcpc_writeable_reg(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case TCPC_CR:
+ case TCPC_UPC:
+ case TCPC_UPS:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static const struct regmap_config sama7g5_tcpc_regmap_config = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+ .max_register = TCPC_VERSION,
+ .readable_reg = sama7g5_tcpc_readable_reg,
+ .writeable_reg = sama7g5_tcpc_writeable_reg,
+};
+
+static int sama7g5_tcpc_get_vbus(struct tcpc_dev *tcpc)
+{
+ struct sama7g5_tcpc *sama7g5_tcpc = tcpc_to_sama7g5_tcpc(tcpc);
+ int ret;
+
+ mutex_lock(&sama7g5_tcpc->vbus_mutex);
+ ret = sama7g5_tcpc->vbus_present ? 1 : 0;
+ mutex_unlock(&sama7g5_tcpc->vbus_mutex);
+
+ return ret;
+}
+
+static int sama7g5_tcpc_set_vbus(struct tcpc_dev *tcpc, bool on, bool sink)
+{
+ struct sama7g5_tcpc *sama7g5_tcpc = tcpc_to_sama7g5_tcpc(tcpc);
+ int ret;
+
+ mutex_lock(&sama7g5_tcpc->vbus_mutex);
+ if (on)
+ ret = regulator_enable(sama7g5_tcpc->vbus);
+ else
+ ret = regulator_disable(sama7g5_tcpc->vbus);
+ mutex_unlock(&sama7g5_tcpc->vbus_mutex);
+
+ return ret;
+}
+
+static int sama7g5_tcpc_set_vconn(struct tcpc_dev *tcpc, bool on)
+{
+ /* VCONN is not supported */
+ return -EPERM;
+}
+
+static int sama7g5_tcpc_get_cc(struct tcpc_dev *tcpc, enum typec_cc_status *cc1,
+ enum typec_cc_status *cc2)
+{
+ struct sama7g5_tcpc *sama7g5_tcpc = tcpc_to_sama7g5_tcpc(tcpc);
+
+ mutex_lock(&sama7g5_tcpc->lock);
+ *cc1 = sama7g5_tcpc->cc1_status;
+ *cc2 = sama7g5_tcpc->cc2_status;
+ mutex_unlock(&sama7g5_tcpc->lock);
+
+ return 0;
+}
+
+static int sama7g5_tcpc_set_cc(struct tcpc_dev *tcpc, enum typec_cc_status cc)
+{
+ struct sama7g5_tcpc *sama7g5_tcpc = tcpc_to_sama7g5_tcpc(tcpc);
+ unsigned int ctrl;
+ int ret = 0;
+
+ mutex_lock(&sama7g5_tcpc->lock);
+ switch (cc) {
+ case TYPEC_CC_RD:
+ ctrl = TCPC_UPC_IP_OFF;
+ break;
+ case TYPEC_CC_RP_DEF:
+ ctrl = TCPC_UPC_IP_0P5;
+ break;
+ default:
+ ret = -EINVAL;
+ goto done;
+ }
+ ret = regmap_write(sama7g5_tcpc->regmap, TCPC_UPC, ctrl);
+done:
+ mutex_unlock(&sama7g5_tcpc->lock);
+ return ret;
+}
+
+static int sama7g5_tcpc_set_polarity(struct tcpc_dev *tcpc,
+ enum typec_cc_polarity pol)
+{
+ return 0;
+}
+
+static int sama7g5_tcpc_set_roles(struct tcpc_dev *tcpc, bool attached,
+ enum typec_role role, enum typec_data_role data)
+{
+ return 0;
+}
+
+static int sama7g5_tcpc_set_pd_rx(struct tcpc_dev *tcpc, bool on)
+{
+ return -EPERM;
+}
+
+static int sama7g5_tcpc_pd_transmit(struct tcpc_dev *tcpc,
+ enum tcpm_transmit_type type,
+ const struct pd_message *msg)
+{
+ return -EPERM;
+}
+
+static int sama7g5_tcpc_start_toggling(struct tcpc_dev *tcpc,
+ enum typec_port_type port_type,
+ enum typec_cc_status cc)
+{
+ return -EOPNOTSUPP;
+}
+
+static void _sama7g5_tcpc_measure_snk(struct sama7g5_tcpc *sama7g5_tcpc)
+{
+ int ret;
+
+ /* Save previous CC1/CC2 state */
+ sama7g5_tcpc->cc1_status_prev = sama7g5_tcpc->cc1_status;
+ sama7g5_tcpc->cc2_status_prev = sama7g5_tcpc->cc2_status;
+
+ /* Comparator Threshold 2 */
+ ret = regmap_write(sama7g5_tcpc->regmap, TCPC_UPC, TCPC_UPC_IP_OFF |
+ TCPC_UPC_THRESHOLD2);
+ if (ret)
+ dev_err(sama7g5_tcpc->dev, "failed to wite register: %d\n",
+ ret);
+
+ usleep_range(560, 1000);
+
+ ret = regmap_read(sama7g5_tcpc->regmap, TCPC_UPS,
+ &sama7g5_tcpc->phy_status);
+ if (ret)
+ dev_err(sama7g5_tcpc->dev, "failed to read register: %d\n",
+ ret);
+
+ if (!(sama7g5_tcpc->phy_status & TCPC_UPS_CC_MASK)) {
+ /* VRa*/
+ sama7g5_tcpc->cc1_status = TYPEC_CC_OPEN;
+ sama7g5_tcpc->cc2_status = TYPEC_CC_OPEN;
+ return;
+ }
+
+ /* CC1 or CC2 is connected wait for PD messages to end ~ 30ms */
+ usleep_range(30000, 35000);
+
+ /* Comparator Threshold 4 */
+ sama7g5_tcpc->phy_status_old = sama7g5_tcpc->phy_status;
+
+ ret = regmap_write(sama7g5_tcpc->regmap, TCPC_UPC, TCPC_UPC_IP_OFF |
+ TCPC_UPC_THRESHOLD4);
+ if (ret)
+ dev_err(sama7g5_tcpc->dev, "failed to wite register: %d\n",
+ ret);
+
+ usleep_range(560, 1000);
+ ret = regmap_read(sama7g5_tcpc->regmap, TCPC_UPS,
+ &sama7g5_tcpc->phy_status);
+ if (ret)
+ dev_err(sama7g5_tcpc->dev, "failed to read register: %d\n",
+ ret);
+
+ if ((sama7g5_tcpc->phy_status_old & TCPC_UPS_CC1ID) &&
+ (!(sama7g5_tcpc->phy_status & TCPC_UPS_CC1ID))) {
+ sama7g5_tcpc->cc1_status = TYPEC_CC_RP_DEF;
+ sama7g5_tcpc->cc2_status = TYPEC_CC_OPEN;
+ return;
+ }
+
+ if ((sama7g5_tcpc->phy_status_old & TCPC_UPS_CC2RDT) &&
+ (!(sama7g5_tcpc->phy_status & TCPC_UPS_CC2RDT))) {
+ sama7g5_tcpc->cc1_status = TYPEC_CC_OPEN;
+ sama7g5_tcpc->cc2_status = TYPEC_CC_RP_DEF;
+ return;
+ }
+
+ /* Comparator Threshold 6 */
+ sama7g5_tcpc->phy_status_old = sama7g5_tcpc->phy_status;
+
+ ret = regmap_write(sama7g5_tcpc->regmap, TCPC_UPC, TCPC_UPC_IP_OFF |
+ TCPC_UPC_THRESHOLD6);
+ if (ret)
+ dev_err(sama7g5_tcpc->dev, "failed to wite register: %d\n",
+ ret);
+
+ usleep_range(560, 1000);
+ ret = regmap_read(sama7g5_tcpc->regmap, TCPC_UPS,
+ &sama7g5_tcpc->phy_status);
+ if (ret)
+ dev_err(sama7g5_tcpc->dev, "failed to read register: %d\n",
+ ret);
+
+ if ((sama7g5_tcpc->phy_status_old & TCPC_UPS_CC1ID) &&
+ (!(sama7g5_tcpc->phy_status & TCPC_UPS_CC1ID))) {
+ sama7g5_tcpc->cc1_status = TYPEC_CC_RP_1_5;
+ sama7g5_tcpc->cc2_status = TYPEC_CC_OPEN;
+ return;
+ }
+
+ if ((sama7g5_tcpc->phy_status_old & TCPC_UPS_CC1ID) &&
+ ((sama7g5_tcpc->phy_status & TCPC_UPS_CC1ID))) {
+ sama7g5_tcpc->cc1_status = TYPEC_CC_RP_3_0;
+ sama7g5_tcpc->cc2_status = TYPEC_CC_OPEN;
+ return;
+ }
+
+ if ((sama7g5_tcpc->phy_status_old & TCPC_UPS_CC2RDT) &&
+ (!(sama7g5_tcpc->phy_status & TCPC_UPS_CC2RDT))) {
+ sama7g5_tcpc->cc1_status = TYPEC_CC_OPEN;
+ sama7g5_tcpc->cc2_status = TYPEC_CC_RP_1_5;
+ return;
+ }
+
+ if ((sama7g5_tcpc->phy_status_old & TCPC_UPS_CC2RDT) &&
+ ((sama7g5_tcpc->phy_status & TCPC_UPS_CC2RDT))) {
+ sama7g5_tcpc->cc1_status = TYPEC_CC_OPEN;
+ sama7g5_tcpc->cc2_status = TYPEC_CC_RP_3_0;
+ return;
+ }
+}
+
+static void sama7g5_tcpc_measure_work(struct work_struct *work)
+{
+ struct sama7g5_tcpc *port = container_of(work, struct sama7g5_tcpc,
+ measure_work.work);
+
+ mutex_lock(&port->lock);
+
+ _sama7g5_tcpc_measure_snk(port);
+
+ /* Check if the state has changed and notify TCPM */
+ if (port->cc1_status != port->cc1_status_prev ||
+ port->cc2_status != port->cc2_status_prev)
+ tcpm_cc_change(port->tcpm);
+
+ mod_delayed_work(port->wq, &port->measure_work,
+ msecs_to_jiffies(T_CC_MEASURE));
+
+ mutex_unlock(&port->lock);
+}
+
+static int sama7g5_tcpc_init(struct tcpc_dev *tcpc)
+{
+ struct sama7g5_tcpc *sama7g5_tcpc = tcpc_to_sama7g5_tcpc(tcpc);
+ int ret;
+
+ ret = regmap_write(sama7g5_tcpc->regmap, TCPC_CR, TCPC_CR_RESET);
+ if (ret)
+ return ret;
+
+ sama7g5_tcpc->wq =
+ create_singlethread_workqueue(dev_name(sama7g5_tcpc->dev));
+ if (!sama7g5_tcpc->wq)
+ return -ENOMEM;
+
+ INIT_DELAYED_WORK(&sama7g5_tcpc->measure_work,
+ sama7g5_tcpc_measure_work);
+
+ sama7g5_tcpc->cc1_status = TYPEC_CC_OPEN;
+ sama7g5_tcpc->cc2_status = TYPEC_CC_OPEN;
+ sama7g5_tcpc->cc1_status_prev = TYPEC_CC_OPEN;
+ sama7g5_tcpc->cc2_status_prev = TYPEC_CC_OPEN;
+ sama7g5_tcpc->cc_polarity = TYPEC_POLARITY_CC1;
+
+ /* We do not have an interrupt so polling only */
+ mod_delayed_work(sama7g5_tcpc->wq, &sama7g5_tcpc->measure_work,
+ msecs_to_jiffies(T_CC_MEASURE));
+
+ /* Enable VBUS detection */
+ if (sama7g5_tcpc->vbus_pin)
+ enable_irq(gpiod_to_irq(sama7g5_tcpc->vbus_pin));
+
+ return 0;
+}
+
+static int vbus_is_present(struct sama7g5_tcpc *sama7g5_tcpc)
+{
+ if (sama7g5_tcpc->vbus_pin)
+ return gpiod_get_value(sama7g5_tcpc->vbus_pin);
+
+ /* No Vbus detection: Assume always present */
+ return 1;
+}
+
+static irqreturn_t sama7g5_vbus_irq_thread(int irq, void *devid)
+{
+ struct sama7g5_tcpc *sama7g5_tcpc = devid;
+
+ /* debounce */
+ udelay(10);
+
+ mutex_lock(&sama7g5_tcpc->vbus_mutex);
+
+ sama7g5_tcpc->vbus_present = vbus_is_present(sama7g5_tcpc);
+ if (sama7g5_tcpc->vbus_present != sama7g5_tcpc->vbus_present_prev) {
+ /* VBUS changed, notify TCPM */
+ tcpm_vbus_change(sama7g5_tcpc->tcpm);
+ sama7g5_tcpc->vbus_present_prev = sama7g5_tcpc->vbus_present;
+ }
+
+ mutex_unlock(&sama7g5_tcpc->vbus_mutex);
+ return IRQ_HANDLED;
+}
+
+static int sama7g5_tcpc_probe(struct platform_device *pdev)
+{
+ int ret;
+ struct sama7g5_tcpc *sama7g5_tcpc;
+
+ struct resource *mem;
+ void __iomem *base;
+
+ sama7g5_tcpc = devm_kzalloc(&pdev->dev, sizeof(*sama7g5_tcpc),
+ GFP_KERNEL);
+ if (!sama7g5_tcpc)
+ return -ENOMEM;
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ base = devm_ioremap_resource(&pdev->dev, mem);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+ sama7g5_tcpc->base = base;
+
+ sama7g5_tcpc->regmap = devm_regmap_init_mmio(&pdev->dev, base,
+ &sama7g5_tcpc_regmap_config);
+ if (IS_ERR(sama7g5_tcpc->regmap)) {
+ dev_err(&pdev->dev, "Regmap init failed\n");
+ return PTR_ERR(sama7g5_tcpc->regmap);
+ }
+
+ /* Get the peripheral clock */
+ sama7g5_tcpc->pclk = devm_clk_get(&pdev->dev, "pclk");
+ if (IS_ERR(sama7g5_tcpc->pclk)) {
+ ret = PTR_ERR(sama7g5_tcpc->pclk);
+ dev_err(&pdev->dev,
+ "failed to get the peripheral clock: %d\n", ret);
+ return ret;
+ }
+
+ ret = clk_prepare_enable(sama7g5_tcpc->pclk);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "failed to enable the peripheral clock: %d\n", ret);
+ return ret;
+ }
+
+ /* Get the generic clock */
+ sama7g5_tcpc->gclk = devm_clk_get(&pdev->dev, "gclk");
+ if (IS_ERR(sama7g5_tcpc->gclk)) {
+ ret = PTR_ERR(sama7g5_tcpc->gclk);
+ dev_err(&pdev->dev,
+ "failed to get the PMC generic clock: %d\n", ret);
+ return ret;
+ }
+
+ ret = clk_set_rate(sama7g5_tcpc->gclk, SAMA7G5_TCPC_GCLK);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "unable to change gclk rate to: %u\n",
+ SAMA7G5_TCPC_GCLK);
+ return ret;
+ }
+
+ ret = clk_prepare_enable(sama7g5_tcpc->gclk);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "failed to enable the generic clock: %d\n", ret);
+ return ret;
+ }
+
+ mutex_init(&sama7g5_tcpc->lock);
+ mutex_init(&sama7g5_tcpc->vbus_mutex);
+
+ sama7g5_tcpc->vbus_pin = devm_gpiod_get_optional(&pdev->dev,
+ "microchip,vbus", GPIOD_IN);
+
+ if (IS_ERR(sama7g5_tcpc->vbus_pin)) {
+ ret = PTR_ERR(sama7g5_tcpc->vbus_pin);
+ dev_err(&pdev->dev, "unable to claim vbus-gpio: %d\n", ret);
+ }
+
+ sama7g5_tcpc->vbus = devm_regulator_get_optional(&pdev->dev, "vbus");
+
+ if (IS_ERR(sama7g5_tcpc->vbus)) {
+ ret = PTR_ERR(sama7g5_tcpc->vbus);
+ dev_err(&pdev->dev, "unable to claim vbus-supply: %d\n", ret);
+ }
+
+ if (sama7g5_tcpc->vbus_pin) {
+ irq_set_status_flags(gpiod_to_irq(sama7g5_tcpc->vbus_pin),
+ IRQ_NOAUTOEN);
+ ret = devm_request_threaded_irq(&pdev->dev,
+ gpiod_to_irq(sama7g5_tcpc->vbus_pin), NULL,
+ sama7g5_vbus_irq_thread,
+ SAMA7G5_TCPC_VBUS_IRQFLAGS,
+ "sama7g5_tcpc", sama7g5_tcpc);
+ if (ret) {
+ sama7g5_tcpc->vbus_pin = NULL;
+ dev_warn(&pdev->dev,
+ "failed to request vbus irq; "
+ "assuming always on\n");
+ }
+ }
+
+ sama7g5_tcpc->dev = &pdev->dev;
+ platform_set_drvdata(pdev, sama7g5_tcpc);
+
+ sama7g5_tcpc->tcpc.init = sama7g5_tcpc_init;
+ sama7g5_tcpc->tcpc.get_vbus = sama7g5_tcpc_get_vbus;
+ sama7g5_tcpc->tcpc.set_vbus = sama7g5_tcpc_set_vbus;
+ sama7g5_tcpc->tcpc.set_cc = sama7g5_tcpc_set_cc;
+ sama7g5_tcpc->tcpc.get_cc = sama7g5_tcpc_get_cc;
+ sama7g5_tcpc->tcpc.set_polarity = sama7g5_tcpc_set_polarity;
+ sama7g5_tcpc->tcpc.set_vconn = sama7g5_tcpc_set_vconn;
+ sama7g5_tcpc->tcpc.start_toggling = sama7g5_tcpc_start_toggling;
+ sama7g5_tcpc->tcpc.set_pd_rx = sama7g5_tcpc_set_pd_rx;
+ sama7g5_tcpc->tcpc.set_roles = sama7g5_tcpc_set_roles;
+ sama7g5_tcpc->tcpc.pd_transmit = sama7g5_tcpc_pd_transmit;
+
+ sama7g5_tcpc->tcpc.fwnode = device_get_named_child_node(&pdev->dev,
+ "connector");
+ if (!sama7g5_tcpc->tcpc.fwnode) {
+ dev_err(&pdev->dev, "Can't find connector node.\n");
+ return -EINVAL;
+ }
+
+ sama7g5_tcpc->tcpm = tcpm_register_port(sama7g5_tcpc->dev,
+ &sama7g5_tcpc->tcpc);
+ if (IS_ERR(sama7g5_tcpc->tcpm)) {
+ fwnode_remove_software_node(sama7g5_tcpc->tcpc.fwnode);
+ return PTR_ERR(sama7g5_tcpc->tcpm);
+ }
+
+ return 0;
+}
+
+static int sama7g5_tcpc_remove(struct platform_device *pdev)
+{
+ struct sama7g5_tcpc *sama7g5_tcpc;
+
+ sama7g5_tcpc = platform_get_drvdata(pdev);
+
+ /* Mask everything */
+ if (sama7g5_tcpc->vbus_pin)
+ disable_irq(gpiod_to_irq(sama7g5_tcpc->vbus_pin));
+
+
+ if (!IS_ERR_OR_NULL(sama7g5_tcpc->tcpm))
+ tcpm_unregister_port(sama7g5_tcpc->tcpm);
+
+ destroy_workqueue(sama7g5_tcpc->wq);
+
+ clk_disable_unprepare(sama7g5_tcpc->gclk);
+ clk_disable_unprepare(sama7g5_tcpc->pclk);
+
+ return 0;
+}
+
+static const struct of_device_id sama7g5_tcpc_dt_ids[] = {
+ {
+ .compatible = "microchip,sama7g5-tcpc",
+ },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, sama7g5_tcpc_dt_ids);
+
+static struct platform_driver sama7g5_tcpc_driver = {
+ .probe = sama7g5_tcpc_probe,
+ .remove = sama7g5_tcpc_remove,
+ .driver = {
+ .name = "microchip,sama7g5-tcpc",
+ .of_match_table = sama7g5_tcpc_dt_ids,
+ },
+};
+module_platform_driver(sama7g5_tcpc_driver);
+
+MODULE_AUTHOR("Cristian Birsan <cristian.birsan@microchip.com>");
+MODULE_DESCRIPTION("Microchip SAMA7G5 Type-C Port Controller Driver");
+MODULE_LICENSE("GPL");
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [RFC PATCH 2/2] usb: typec: sama7g5_tcpc: add driver for Microchip sama7g5 tcpc
2021-03-29 21:33 ` cristian.birsan
(?)
@ 2021-03-29 23:58 ` kernel test robot
-1 siblings, 0 replies; 9+ messages in thread
From: kernel test robot @ 2021-03-29 23:58 UTC (permalink / raw)
To: kbuild-all
[-- Attachment #1: Type: text/plain, Size: 7443 bytes --]
Hi,
[FYI, it's a private test report for your RFC patch.]
[auto build test ERROR on usb/usb-testing]
[also build test ERROR on v5.12-rc5 next-20210329]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/cristian-birsan-microchip-com/usb-typec-Add-driver-for-Microchip-sama7g5-tcpc/20210330-053602
base: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git usb-testing
config: sh-allmodconfig (attached as .config)
compiler: sh4-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/0day-ci/linux/commit/bbd4056cf2868abe6b27e9acf07f46423ac3510e
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review cristian-birsan-microchip-com/usb-typec-Add-driver-for-Microchip-sama7g5-tcpc/20210330-053602
git checkout bbd4056cf2868abe6b27e9acf07f46423ac3510e
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=sh
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All errors (new ones prefixed by >>):
drivers/usb/typec/tcpm/sama7g5_tcpc.c: In function 'sama7g5_tcpc_probe':
>> drivers/usb/typec/tcpm/sama7g5_tcpc.c:541:33: error: assignment to 'int (*)(struct tcpc_dev *, enum tcpm_transmit_type, const struct pd_message *, unsigned int)' from incompatible pointer type 'int (*)(struct tcpc_dev *, enum tcpm_transmit_type, const struct pd_message *)' [-Werror=incompatible-pointer-types]
541 | sama7g5_tcpc->tcpc.pd_transmit = sama7g5_tcpc_pd_transmit;
| ^
cc1: some warnings being treated as errors
Kconfig warnings: (for reference only)
WARNING: unmet direct dependencies detected for SND_ATMEL_SOC_PDC
Depends on SOUND && !UML && SND && SND_SOC && SND_ATMEL_SOC && HAS_DMA
Selected by
- SND_ATMEL_SOC_SSC && SOUND && !UML && SND && SND_SOC && SND_ATMEL_SOC
- SND_ATMEL_SOC_SSC_PDC && SOUND && !UML && SND && SND_SOC && SND_ATMEL_SOC && ATMEL_SSC
vim +541 drivers/usb/typec/tcpm/sama7g5_tcpc.c
427
428 static int sama7g5_tcpc_probe(struct platform_device *pdev)
429 {
430 int ret;
431 struct sama7g5_tcpc *sama7g5_tcpc;
432
433 struct resource *mem;
434 void __iomem *base;
435
436 sama7g5_tcpc = devm_kzalloc(&pdev->dev, sizeof(*sama7g5_tcpc),
437 GFP_KERNEL);
438 if (!sama7g5_tcpc)
439 return -ENOMEM;
440
441 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
442 base = devm_ioremap_resource(&pdev->dev, mem);
443 if (IS_ERR(base))
444 return PTR_ERR(base);
445 sama7g5_tcpc->base = base;
446
447 sama7g5_tcpc->regmap = devm_regmap_init_mmio(&pdev->dev, base,
448 &sama7g5_tcpc_regmap_config);
449 if (IS_ERR(sama7g5_tcpc->regmap)) {
450 dev_err(&pdev->dev, "Regmap init failed\n");
451 return PTR_ERR(sama7g5_tcpc->regmap);
452 }
453
454 /* Get the peripheral clock */
455 sama7g5_tcpc->pclk = devm_clk_get(&pdev->dev, "pclk");
456 if (IS_ERR(sama7g5_tcpc->pclk)) {
457 ret = PTR_ERR(sama7g5_tcpc->pclk);
458 dev_err(&pdev->dev,
459 "failed to get the peripheral clock: %d\n", ret);
460 return ret;
461 }
462
463 ret = clk_prepare_enable(sama7g5_tcpc->pclk);
464 if (ret) {
465 dev_err(&pdev->dev,
466 "failed to enable the peripheral clock: %d\n", ret);
467 return ret;
468 }
469
470 /* Get the generic clock */
471 sama7g5_tcpc->gclk = devm_clk_get(&pdev->dev, "gclk");
472 if (IS_ERR(sama7g5_tcpc->gclk)) {
473 ret = PTR_ERR(sama7g5_tcpc->gclk);
474 dev_err(&pdev->dev,
475 "failed to get the PMC generic clock: %d\n", ret);
476 return ret;
477 }
478
479 ret = clk_set_rate(sama7g5_tcpc->gclk, SAMA7G5_TCPC_GCLK);
480 if (ret) {
481 dev_err(&pdev->dev,
482 "unable to change gclk rate to: %u\n",
483 SAMA7G5_TCPC_GCLK);
484 return ret;
485 }
486
487 ret = clk_prepare_enable(sama7g5_tcpc->gclk);
488 if (ret) {
489 dev_err(&pdev->dev,
490 "failed to enable the generic clock: %d\n", ret);
491 return ret;
492 }
493
494 mutex_init(&sama7g5_tcpc->lock);
495 mutex_init(&sama7g5_tcpc->vbus_mutex);
496
497 sama7g5_tcpc->vbus_pin = devm_gpiod_get_optional(&pdev->dev,
498 "microchip,vbus", GPIOD_IN);
499
500 if (IS_ERR(sama7g5_tcpc->vbus_pin)) {
501 ret = PTR_ERR(sama7g5_tcpc->vbus_pin);
502 dev_err(&pdev->dev, "unable to claim vbus-gpio: %d\n", ret);
503 }
504
505 sama7g5_tcpc->vbus = devm_regulator_get_optional(&pdev->dev, "vbus");
506
507 if (IS_ERR(sama7g5_tcpc->vbus)) {
508 ret = PTR_ERR(sama7g5_tcpc->vbus);
509 dev_err(&pdev->dev, "unable to claim vbus-supply: %d\n", ret);
510 }
511
512 if (sama7g5_tcpc->vbus_pin) {
513 irq_set_status_flags(gpiod_to_irq(sama7g5_tcpc->vbus_pin),
514 IRQ_NOAUTOEN);
515 ret = devm_request_threaded_irq(&pdev->dev,
516 gpiod_to_irq(sama7g5_tcpc->vbus_pin), NULL,
517 sama7g5_vbus_irq_thread,
518 SAMA7G5_TCPC_VBUS_IRQFLAGS,
519 "sama7g5_tcpc", sama7g5_tcpc);
520 if (ret) {
521 sama7g5_tcpc->vbus_pin = NULL;
522 dev_warn(&pdev->dev,
523 "failed to request vbus irq; "
524 "assuming always on\n");
525 }
526 }
527
528 sama7g5_tcpc->dev = &pdev->dev;
529 platform_set_drvdata(pdev, sama7g5_tcpc);
530
531 sama7g5_tcpc->tcpc.init = sama7g5_tcpc_init;
532 sama7g5_tcpc->tcpc.get_vbus = sama7g5_tcpc_get_vbus;
533 sama7g5_tcpc->tcpc.set_vbus = sama7g5_tcpc_set_vbus;
534 sama7g5_tcpc->tcpc.set_cc = sama7g5_tcpc_set_cc;
535 sama7g5_tcpc->tcpc.get_cc = sama7g5_tcpc_get_cc;
536 sama7g5_tcpc->tcpc.set_polarity = sama7g5_tcpc_set_polarity;
537 sama7g5_tcpc->tcpc.set_vconn = sama7g5_tcpc_set_vconn;
538 sama7g5_tcpc->tcpc.start_toggling = sama7g5_tcpc_start_toggling;
539 sama7g5_tcpc->tcpc.set_pd_rx = sama7g5_tcpc_set_pd_rx;
540 sama7g5_tcpc->tcpc.set_roles = sama7g5_tcpc_set_roles;
> 541 sama7g5_tcpc->tcpc.pd_transmit = sama7g5_tcpc_pd_transmit;
542
543 sama7g5_tcpc->tcpc.fwnode = device_get_named_child_node(&pdev->dev,
544 "connector");
545 if (!sama7g5_tcpc->tcpc.fwnode) {
546 dev_err(&pdev->dev, "Can't find connector node.\n");
547 return -EINVAL;
548 }
549
550 sama7g5_tcpc->tcpm = tcpm_register_port(sama7g5_tcpc->dev,
551 &sama7g5_tcpc->tcpc);
552 if (IS_ERR(sama7g5_tcpc->tcpm)) {
553 fwnode_remove_software_node(sama7g5_tcpc->tcpc.fwnode);
554 return PTR_ERR(sama7g5_tcpc->tcpm);
555 }
556
557 return 0;
558 }
559
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org
[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 54254 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [RFC PATCH 1/2] dt-bindings: usb: Add DT bindings for Microchip sama7g5 tcpc
2021-03-29 21:33 ` cristian.birsan
@ 2021-03-30 13:08 ` Rob Herring
-1 siblings, 0 replies; 9+ messages in thread
From: Rob Herring @ 2021-03-30 13:08 UTC (permalink / raw)
To: cristian.birsan
Cc: linux, gregkh, linux-usb, linux-arm-kernel, devicetree, robh+dt,
heikki.krogerus, linux-kernel
On Tue, 30 Mar 2021 00:33:56 +0300, cristian.birsan@microchip.com wrote:
> From: Cristian Birsan <cristian.birsan@microchip.com>
>
> This patch adds DT bindings for the new Microchip USB Type-C Port
> Controller (TCPC) embedded in sama7g5 SoC.
>
> Signed-off-by: Cristian Birsan <cristian.birsan@microchip.com>
> ---
> .../bindings/usb/microchip,sama7g5-tcpc.yaml | 80 +++++++++++++++++++
> 1 file changed, 80 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/usb/microchip,sama7g5-tcpc.yaml
>
My bot found errors running 'make dt_binding_check' on your patch:
yamllint warnings/errors:
dtschema/dtc warnings/errors:
Documentation/devicetree/bindings/usb/microchip,sama7g5-tcpc.example.dt.yaml:0:0: /example-0/tcpcb@e0844000: failed to match any schema with compatible: ['microchip,sama7g5-typec']
See https://patchwork.ozlabs.org/patch/1459823
This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.
If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:
pip3 install dtschema --upgrade
Please check and re-submit.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [RFC PATCH 1/2] dt-bindings: usb: Add DT bindings for Microchip sama7g5 tcpc
@ 2021-03-30 13:08 ` Rob Herring
0 siblings, 0 replies; 9+ messages in thread
From: Rob Herring @ 2021-03-30 13:08 UTC (permalink / raw)
To: cristian.birsan
Cc: linux, gregkh, linux-usb, linux-arm-kernel, devicetree, robh+dt,
heikki.krogerus, linux-kernel
On Tue, 30 Mar 2021 00:33:56 +0300, cristian.birsan@microchip.com wrote:
> From: Cristian Birsan <cristian.birsan@microchip.com>
>
> This patch adds DT bindings for the new Microchip USB Type-C Port
> Controller (TCPC) embedded in sama7g5 SoC.
>
> Signed-off-by: Cristian Birsan <cristian.birsan@microchip.com>
> ---
> .../bindings/usb/microchip,sama7g5-tcpc.yaml | 80 +++++++++++++++++++
> 1 file changed, 80 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/usb/microchip,sama7g5-tcpc.yaml
>
My bot found errors running 'make dt_binding_check' on your patch:
yamllint warnings/errors:
dtschema/dtc warnings/errors:
Documentation/devicetree/bindings/usb/microchip,sama7g5-tcpc.example.dt.yaml:0:0: /example-0/tcpcb@e0844000: failed to match any schema with compatible: ['microchip,sama7g5-typec']
See https://patchwork.ozlabs.org/patch/1459823
This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.
If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:
pip3 install dtschema --upgrade
Please check and re-submit.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2021-03-30 13:10 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-29 21:33 [RFC PATCH 0/2] usb: typec: Add driver for Microchip sama7g5 tcpc cristian.birsan
2021-03-29 21:33 ` cristian.birsan
2021-03-29 21:33 ` [RFC PATCH 1/2] dt-bindings: usb: Add DT bindings " cristian.birsan
2021-03-29 21:33 ` cristian.birsan
2021-03-30 13:08 ` Rob Herring
2021-03-30 13:08 ` Rob Herring
2021-03-29 21:33 ` [RFC PATCH 2/2] usb: typec: sama7g5_tcpc: add driver " cristian.birsan
2021-03-29 21:33 ` cristian.birsan
2021-03-29 23:58 ` kernel test robot
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.