mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-03-06 06:09:10 +07:00
Tag/Merge point for adding typeC power supply support
This is a signed tag/merge point to handle the cross-tree merge of the USB and power supply subsystems for the patch series: Subject: [PATCH v8 0/6] typec: tcpm: Add sink side support for PPS It is based on the usb.git tree, in the usb-next branch, for merging in 4.18-rc1. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCWuGASg8cZ3JlZ0Brcm9h aC5jb20ACgkQMUfUDdst+ylqPACcDdrowGIQp0vVa7VrOJNMy9pL5K0An1cjnaUt 0sXkKK8YWC3EQSSYtr3Q =McRU -----END PGP SIGNATURE----- Merge tag 'tags/tcpm-pps-4.18' into psy-next Tag/Merge point for adding typeC power supply support This is a signed tag/merge point to handle the cross-tree merge of the USB and power supply subsystems for the patch series: Subject: [PATCH v8 0/6] typec: tcpm: Add sink side support for PPS It is based on the usb.git tree, in the usb-next branch, for merging in 4.18-rc1. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk>
This commit is contained in:
commit
1f140ff467
@ -236,3 +236,21 @@ Description:
|
||||
Supported values are 0 - 15.
|
||||
More information on how besl values map to microseconds can be found in
|
||||
USB 2.0 ECN Errata for Link Power Management, section 4.10)
|
||||
|
||||
What: /sys/bus/usb/devices/.../rx_lanes
|
||||
Date: March 2018
|
||||
Contact: Mathias Nyman <mathias.nyman@linux.intel.com>
|
||||
Description:
|
||||
Number of rx lanes the device is using.
|
||||
USB 3.2 adds Dual-lane support, 2 rx and 2 tx lanes over Type-C.
|
||||
Inter-Chip SSIC devices support asymmetric lanes up to 4 lanes per
|
||||
direction. Devices before USB 3.2 are single lane (rx_lanes = 1)
|
||||
|
||||
What: /sys/bus/usb/devices/.../tx_lanes
|
||||
Date: March 2018
|
||||
Contact: Mathias Nyman <mathias.nyman@linux.intel.com>
|
||||
Description:
|
||||
Number of tx lanes the device is using.
|
||||
USB 3.2 adds Dual-lane support, 2 rx and 2 tx -lanes over Type-C.
|
||||
Inter-Chip SSIC devices support asymmetric lanes up to 4 lanes per
|
||||
direction. Devices before USB 3.2 are single lane (tx_lanes = 1)
|
||||
|
@ -1,3 +1,458 @@
|
||||
===== General Properties =====
|
||||
|
||||
What: /sys/class/power_supply/<supply_name>/manufacturer
|
||||
Date: May 2007
|
||||
Contact: linux-pm@vger.kernel.org
|
||||
Description:
|
||||
Reports the name of the device manufacturer.
|
||||
|
||||
Access: Read
|
||||
Valid values: Represented as string
|
||||
|
||||
What: /sys/class/power_supply/<supply_name>/model_name
|
||||
Date: May 2007
|
||||
Contact: linux-pm@vger.kernel.org
|
||||
Description:
|
||||
Reports the name of the device model.
|
||||
|
||||
Access: Read
|
||||
Valid values: Represented as string
|
||||
|
||||
What: /sys/class/power_supply/<supply_name>/serial_number
|
||||
Date: January 2008
|
||||
Contact: linux-pm@vger.kernel.org
|
||||
Description:
|
||||
Reports the serial number of the device.
|
||||
|
||||
Access: Read
|
||||
Valid values: Represented as string
|
||||
|
||||
What: /sys/class/power_supply/<supply_name>/type
|
||||
Date: May 2010
|
||||
Contact: linux-pm@vger.kernel.org
|
||||
Description:
|
||||
Describes the main type of the supply.
|
||||
|
||||
Access: Read
|
||||
Valid values: "Battery", "UPS", "Mains", "USB"
|
||||
|
||||
===== Battery Properties =====
|
||||
|
||||
What: /sys/class/power_supply/<supply_name>/capacity
|
||||
Date: May 2007
|
||||
Contact: linux-pm@vger.kernel.org
|
||||
Description:
|
||||
Fine grain representation of battery capacity.
|
||||
Access: Read
|
||||
Valid values: 0 - 100 (percent)
|
||||
|
||||
What: /sys/class/power_supply/<supply_name>/capacity_alert_max
|
||||
Date: July 2012
|
||||
Contact: linux-pm@vger.kernel.org
|
||||
Description:
|
||||
Maximum battery capacity trip-wire value where the supply will
|
||||
notify user-space of the event. This is normally used for the
|
||||
battery discharging scenario where user-space needs to know the
|
||||
battery has dropped to an upper level so it can take
|
||||
appropriate action (e.g. warning user that battery level is
|
||||
low).
|
||||
|
||||
Access: Read, Write
|
||||
Valid values: 0 - 100 (percent)
|
||||
|
||||
What: /sys/class/power_supply/<supply_name>/capacity_alert_min
|
||||
Date: July 2012
|
||||
Contact: linux-pm@vger.kernel.org
|
||||
Description:
|
||||
Minimum battery capacity trip-wire value where the supply will
|
||||
notify user-space of the event. This is normally used for the
|
||||
battery discharging scenario where user-space needs to know the
|
||||
battery has dropped to a lower level so it can take
|
||||
appropriate action (e.g. warning user that battery level is
|
||||
critically low).
|
||||
|
||||
Access: Read, Write
|
||||
Valid values: 0 - 100 (percent)
|
||||
|
||||
What: /sys/class/power_supply/<supply_name>/capacity_level
|
||||
Date: June 2009
|
||||
Contact: linux-pm@vger.kernel.org
|
||||
Description:
|
||||
Coarse representation of battery capacity.
|
||||
|
||||
Access: Read
|
||||
Valid values: "Unknown", "Critical", "Low", "Normal", "High",
|
||||
"Full"
|
||||
|
||||
What: /sys/class/power_supply/<supply_name>/current_avg
|
||||
Date: May 2007
|
||||
Contact: linux-pm@vger.kernel.org
|
||||
Description:
|
||||
Reports an average IBAT current reading for the battery, over a
|
||||
fixed period. Normally devices will provide a fixed interval in
|
||||
which they average readings to smooth out the reported value.
|
||||
|
||||
Access: Read
|
||||
Valid values: Represented in microamps
|
||||
|
||||
What: /sys/class/power_supply/<supply_name>/current_max
|
||||
Date: October 2010
|
||||
Contact: linux-pm@vger.kernel.org
|
||||
Description:
|
||||
Reports the maximum IBAT current allowed into the battery.
|
||||
|
||||
Access: Read
|
||||
Valid values: Represented in microamps
|
||||
|
||||
What: /sys/class/power_supply/<supply_name>/current_now
|
||||
Date: May 2007
|
||||
Contact: linux-pm@vger.kernel.org
|
||||
Description:
|
||||
Reports an instant, single IBAT current reading for the battery.
|
||||
This value is not averaged/smoothed.
|
||||
|
||||
Access: Read
|
||||
Valid values: Represented in microamps
|
||||
|
||||
What: /sys/class/power_supply/<supply_name>/charge_type
|
||||
Date: July 2009
|
||||
Contact: linux-pm@vger.kernel.org
|
||||
Description:
|
||||
Represents the type of charging currently being applied to the
|
||||
battery.
|
||||
|
||||
Access: Read
|
||||
Valid values: "Unknown", "N/A", "Trickle", "Fast"
|
||||
|
||||
What: /sys/class/power_supply/<supply_name>/charge_term_current
|
||||
Date: July 2014
|
||||
Contact: linux-pm@vger.kernel.org
|
||||
Description:
|
||||
Reports the charging current value which is used to determine
|
||||
when the battery is considered full and charging should end.
|
||||
|
||||
Access: Read
|
||||
Valid values: Represented in microamps
|
||||
|
||||
What: /sys/class/power_supply/<supply_name>/health
|
||||
Date: May 2007
|
||||
Contact: linux-pm@vger.kernel.org
|
||||
Description:
|
||||
Reports the health of the battery or battery side of charger
|
||||
functionality.
|
||||
|
||||
Access: Read
|
||||
Valid values: "Unknown", "Good", "Overheat", "Dead",
|
||||
"Over voltage", "Unspecified failure", "Cold",
|
||||
"Watchdog timer expire", "Safety timer expire"
|
||||
|
||||
What: /sys/class/power_supply/<supply_name>/precharge_current
|
||||
Date: June 2017
|
||||
Contact: linux-pm@vger.kernel.org
|
||||
Description:
|
||||
Reports the charging current applied during pre-charging phase
|
||||
for a battery charge cycle.
|
||||
|
||||
Access: Read
|
||||
Valid values: Represented in microamps
|
||||
|
||||
What: /sys/class/power_supply/<supply_name>/present
|
||||
Date: May 2007
|
||||
Contact: linux-pm@vger.kernel.org
|
||||
Description:
|
||||
Reports whether a battery is present or not in the system.
|
||||
|
||||
Access: Read
|
||||
Valid values:
|
||||
0: Absent
|
||||
1: Present
|
||||
|
||||
What: /sys/class/power_supply/<supply_name>/status
|
||||
Date: May 2007
|
||||
Contact: linux-pm@vger.kernel.org
|
||||
Description:
|
||||
Represents the charging status of the battery. Normally this
|
||||
is read-only reporting although for some supplies this can be
|
||||
used to enable/disable charging to the battery.
|
||||
|
||||
Access: Read, Write
|
||||
Valid values: "Unknown", "Charging", "Discharging",
|
||||
"Not charging", "Full"
|
||||
|
||||
What: /sys/class/power_supply/<supply_name>/technology
|
||||
Date: May 2007
|
||||
Contact: linux-pm@vger.kernel.org
|
||||
Description:
|
||||
Describes the battery technology supported by the supply.
|
||||
|
||||
Access: Read
|
||||
Valid values: "Unknown", "NiMH", "Li-ion", "Li-poly", "LiFe",
|
||||
"NiCd", "LiMn"
|
||||
|
||||
What: /sys/class/power_supply/<supply_name>/temp
|
||||
Date: May 2007
|
||||
Contact: linux-pm@vger.kernel.org
|
||||
Description:
|
||||
Reports the current TBAT battery temperature reading.
|
||||
|
||||
Access: Read
|
||||
Valid values: Represented in 1/10 Degrees Celsius
|
||||
|
||||
What: /sys/class/power_supply/<supply_name>/temp_alert_max
|
||||
Date: July 2012
|
||||
Contact: linux-pm@vger.kernel.org
|
||||
Description:
|
||||
Maximum TBAT temperature trip-wire value where the supply will
|
||||
notify user-space of the event. This is normally used for the
|
||||
battery charging scenario where user-space needs to know the
|
||||
battery temperature has crossed an upper threshold so it can
|
||||
take appropriate action (e.g. warning user that battery level is
|
||||
critically high, and charging has stopped).
|
||||
|
||||
Access: Read
|
||||
Valid values: Represented in 1/10 Degrees Celsius
|
||||
|
||||
What: /sys/class/power_supply/<supply_name>/temp_alert_min
|
||||
Date: July 2012
|
||||
Contact: linux-pm@vger.kernel.org
|
||||
Description:
|
||||
Minimum TBAT temperature trip-wire value where the supply will
|
||||
notify user-space of the event. This is normally used for the
|
||||
battery charging scenario where user-space needs to know the
|
||||
battery temperature has crossed a lower threshold so it can take
|
||||
appropriate action (e.g. warning user that battery level is
|
||||
high, and charging current has been reduced accordingly to
|
||||
remedy the situation).
|
||||
|
||||
Access: Read
|
||||
Valid values: Represented in 1/10 Degrees Celsius
|
||||
|
||||
What: /sys/class/power_supply/<supply_name>/temp_max
|
||||
Date: July 2014
|
||||
Contact: linux-pm@vger.kernel.org
|
||||
Description:
|
||||
Reports the maximum allowed TBAT battery temperature for
|
||||
charging.
|
||||
|
||||
Access: Read
|
||||
Valid values: Represented in 1/10 Degrees Celsius
|
||||
|
||||
What: /sys/class/power_supply/<supply_name>/temp_min
|
||||
Date: July 2014
|
||||
Contact: linux-pm@vger.kernel.org
|
||||
Description:
|
||||
Reports the minimum allowed TBAT battery temperature for
|
||||
charging.
|
||||
|
||||
Access: Read
|
||||
Valid values: Represented in 1/10 Degrees Celsius
|
||||
|
||||
What: /sys/class/power_supply/<supply_name>/voltage_avg,
|
||||
Date: May 2007
|
||||
Contact: linux-pm@vger.kernel.org
|
||||
Description:
|
||||
Reports an average VBAT voltage reading for the battery, over a
|
||||
fixed period. Normally devices will provide a fixed interval in
|
||||
which they average readings to smooth out the reported value.
|
||||
|
||||
Access: Read
|
||||
Valid values: Represented in microvolts
|
||||
|
||||
What: /sys/class/power_supply/<supply_name>/voltage_max,
|
||||
Date: January 2008
|
||||
Contact: linux-pm@vger.kernel.org
|
||||
Description:
|
||||
Reports the maximum safe VBAT voltage permitted for the battery,
|
||||
during charging.
|
||||
|
||||
Access: Read
|
||||
Valid values: Represented in microvolts
|
||||
|
||||
What: /sys/class/power_supply/<supply_name>/voltage_min,
|
||||
Date: January 2008
|
||||
Contact: linux-pm@vger.kernel.org
|
||||
Description:
|
||||
Reports the minimum safe VBAT voltage permitted for the battery,
|
||||
during discharging.
|
||||
|
||||
Access: Read
|
||||
Valid values: Represented in microvolts
|
||||
|
||||
What: /sys/class/power_supply/<supply_name>/voltage_now,
|
||||
Date: May 2007
|
||||
Contact: linux-pm@vger.kernel.org
|
||||
Description:
|
||||
Reports an instant, single VBAT voltage reading for the battery.
|
||||
This value is not averaged/smoothed.
|
||||
|
||||
Access: Read
|
||||
Valid values: Represented in microvolts
|
||||
|
||||
===== USB Properties =====
|
||||
|
||||
What: /sys/class/power_supply/<supply_name>/current_avg
|
||||
Date: May 2007
|
||||
Contact: linux-pm@vger.kernel.org
|
||||
Description:
|
||||
Reports an average IBUS current reading over a fixed period.
|
||||
Normally devices will provide a fixed interval in which they
|
||||
average readings to smooth out the reported value.
|
||||
|
||||
Access: Read
|
||||
Valid values: Represented in microamps
|
||||
|
||||
|
||||
What: /sys/class/power_supply/<supply_name>/current_max
|
||||
Date: October 2010
|
||||
Contact: linux-pm@vger.kernel.org
|
||||
Description:
|
||||
Reports the maximum IBUS current the supply can support.
|
||||
|
||||
Access: Read
|
||||
Valid values: Represented in microamps
|
||||
|
||||
What: /sys/class/power_supply/<supply_name>/current_now
|
||||
Date: May 2007
|
||||
Contact: linux-pm@vger.kernel.org
|
||||
Description:
|
||||
Reports the IBUS current supplied now. This value is generally
|
||||
read-only reporting, unless the 'online' state of the supply
|
||||
is set to be programmable, in which case this value can be set
|
||||
within the reported min/max range.
|
||||
|
||||
Access: Read, Write
|
||||
Valid values: Represented in microamps
|
||||
|
||||
What: /sys/class/power_supply/<supply_name>/input_current_limit
|
||||
Date: July 2014
|
||||
Contact: linux-pm@vger.kernel.org
|
||||
Description:
|
||||
Details the incoming IBUS current limit currently set in the
|
||||
supply. Normally this is configured based on the type of
|
||||
connection made (e.g. A configured SDP should output a maximum
|
||||
of 500mA so the input current limit is set to the same value).
|
||||
|
||||
Access: Read, Write
|
||||
Valid values: Represented in microamps
|
||||
|
||||
What: /sys/class/power_supply/<supply_name>/online,
|
||||
Date: May 2007
|
||||
Contact: linux-pm@vger.kernel.org
|
||||
Description:
|
||||
Indicates if VBUS is present for the supply. When the supply is
|
||||
online, and the supply allows it, then it's possible to switch
|
||||
between online states (e.g. Fixed -> Programmable for a PD_PPS
|
||||
USB supply so voltage and current can be controlled).
|
||||
|
||||
Access: Read, Write
|
||||
Valid values:
|
||||
0: Offline
|
||||
1: Online Fixed - Fixed Voltage Supply
|
||||
2: Online Programmable - Programmable Voltage Supply
|
||||
|
||||
What: /sys/class/power_supply/<supply_name>/temp
|
||||
Date: May 2007
|
||||
Contact: linux-pm@vger.kernel.org
|
||||
Description:
|
||||
Reports the current supply temperature reading. This would
|
||||
normally be the internal temperature of the device itself (e.g
|
||||
TJUNC temperature of an IC)
|
||||
|
||||
Access: Read
|
||||
Valid values: Represented in 1/10 Degrees Celsius
|
||||
|
||||
What: /sys/class/power_supply/<supply_name>/temp_alert_max
|
||||
Date: July 2012
|
||||
Contact: linux-pm@vger.kernel.org
|
||||
Description:
|
||||
Maximum supply temperature trip-wire value where the supply will
|
||||
notify user-space of the event. This is normally used for the
|
||||
charging scenario where user-space needs to know the supply
|
||||
temperature has crossed an upper threshold so it can take
|
||||
appropriate action (e.g. warning user that the supply
|
||||
temperature is critically high, and charging has stopped to
|
||||
remedy the situation).
|
||||
|
||||
Access: Read
|
||||
Valid values: Represented in 1/10 Degrees Celsius
|
||||
|
||||
What: /sys/class/power_supply/<supply_name>/temp_alert_min
|
||||
Date: July 2012
|
||||
Contact: linux-pm@vger.kernel.org
|
||||
Description:
|
||||
Minimum supply temperature trip-wire value where the supply will
|
||||
notify user-space of the event. This is normally used for the
|
||||
charging scenario where user-space needs to know the supply
|
||||
temperature has crossed a lower threshold so it can take
|
||||
appropriate action (e.g. warning user that the supply
|
||||
temperature is high, and charging current has been reduced
|
||||
accordingly to remedy the situation).
|
||||
|
||||
Access: Read
|
||||
Valid values: Represented in 1/10 Degrees Celsius
|
||||
|
||||
What: /sys/class/power_supply/<supply_name>/temp_max
|
||||
Date: July 2014
|
||||
Contact: linux-pm@vger.kernel.org
|
||||
Description:
|
||||
Reports the maximum allowed supply temperature for operation.
|
||||
|
||||
Access: Read
|
||||
Valid values: Represented in 1/10 Degrees Celsius
|
||||
|
||||
What: /sys/class/power_supply/<supply_name>/temp_min
|
||||
Date: July 2014
|
||||
Contact: linux-pm@vger.kernel.org
|
||||
Description:
|
||||
Reports the mainimum allowed supply temperature for operation.
|
||||
|
||||
Access: Read
|
||||
Valid values: Represented in 1/10 Degrees Celsius
|
||||
|
||||
What: /sys/class/power_supply/<supply_name>/usb_type
|
||||
Date: March 2018
|
||||
Contact: linux-pm@vger.kernel.org
|
||||
Description:
|
||||
Reports what type of USB connection is currently active for
|
||||
the supply, for example it can show if USB-PD capable source
|
||||
is attached.
|
||||
|
||||
Access: Read-Only
|
||||
Valid values: "Unknown", "SDP", "DCP", "CDP", "ACA", "C", "PD",
|
||||
"PD_DRP", "PD_PPS", "BrickID"
|
||||
|
||||
What: /sys/class/power_supply/<supply_name>/voltage_max
|
||||
Date: January 2008
|
||||
Contact: linux-pm@vger.kernel.org
|
||||
Description:
|
||||
Reports the maximum VBUS voltage the supply can support.
|
||||
|
||||
Access: Read
|
||||
Valid values: Represented in microvolts
|
||||
|
||||
What: /sys/class/power_supply/<supply_name>/voltage_min
|
||||
Date: January 2008
|
||||
Contact: linux-pm@vger.kernel.org
|
||||
Description:
|
||||
Reports the minimum VBUS voltage the supply can support.
|
||||
|
||||
Access: Read
|
||||
Valid values: Represented in microvolts
|
||||
|
||||
What: /sys/class/power_supply/<supply_name>/voltage_now
|
||||
Date: May 2007
|
||||
Contact: linux-pm@vger.kernel.org
|
||||
Description:
|
||||
Reports the VBUS voltage supplied now. This value is generally
|
||||
read-only reporting, unless the 'online' state of the supply
|
||||
is set to be programmable, in which case this value can be set
|
||||
within the reported min/max range.
|
||||
|
||||
Access: Read, Write
|
||||
Valid values: Represented in microvolts
|
||||
|
||||
===== Device Specific Properties =====
|
||||
|
||||
What: /sys/class/power/ds2760-battery.*/charge_now
|
||||
Date: May 2010
|
||||
KernelVersion: 2.6.35
|
||||
|
@ -76,6 +76,10 @@ Optional properties:
|
||||
needs to make sure it does not send more than 90%
|
||||
maximum_periodic_data_per_frame. The use case is multiple transactions, but
|
||||
less frame rate.
|
||||
- mux-controls: The mux control for toggling host/device output of this
|
||||
controller. It's expected that a mux state of 0 indicates device mode and a
|
||||
mux state of 1 indicates host mode.
|
||||
- mux-control-names: Shall be "usb_switch" if mux-controls is specified.
|
||||
|
||||
i.mx specific properties
|
||||
- fsl,usbmisc: phandler of non-core register device, with one
|
||||
@ -102,4 +106,6 @@ Example:
|
||||
rx-burst-size-dword = <0x10>;
|
||||
extcon = <0>, <&usb_id>;
|
||||
phy-clkgate-delay-us = <400>;
|
||||
mux-controls = <&usb_switch>;
|
||||
mux-control-names = "usb_switch";
|
||||
};
|
||||
|
@ -6,12 +6,6 @@ Required properties :
|
||||
- interrupts : Interrupt specifier
|
||||
|
||||
Optional properties :
|
||||
- fcs,max-sink-microvolt : Maximum voltage to negotiate when configured as sink
|
||||
- fcs,max-sink-microamp : Maximum current to negotiate when configured as sink
|
||||
- fcs,max-sink-microwatt : Maximum power to negotiate when configured as sink
|
||||
If this is less then max-sink-microvolt *
|
||||
max-sink-microamp then the configured current will
|
||||
be clamped.
|
||||
- fcs,operating-sink-microwatt :
|
||||
Minimum amount of power accepted from a sink
|
||||
when negotiating
|
||||
|
17
Documentation/devicetree/bindings/usb/richtek,rt1711h.txt
Normal file
17
Documentation/devicetree/bindings/usb/richtek,rt1711h.txt
Normal file
@ -0,0 +1,17 @@
|
||||
Richtek RT1711H TypeC PD Controller.
|
||||
|
||||
Required properties:
|
||||
- compatible : Must be "richtek,rt1711h".
|
||||
- reg : Must be 0x4e, it's slave address of RT1711H.
|
||||
- interrupt-parent : the phandle for the interrupt controller that
|
||||
provides interrupts for this device.
|
||||
- interrupts : <a b> where a is the interrupt number and b represents an
|
||||
encoding of the sense and level information for the interrupt.
|
||||
|
||||
Example :
|
||||
rt1711h@4e {
|
||||
compatible = "richtek,rt1711h";
|
||||
reg = <0x4e>;
|
||||
interrupt-parent = <&gpio26>;
|
||||
interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
};
|
@ -28,7 +28,10 @@ Required properties:
|
||||
- interrupts: one XHCI interrupt should be described here.
|
||||
|
||||
Optional properties:
|
||||
- clocks: reference to a clock
|
||||
- clocks: reference to the clocks
|
||||
- clock-names: mandatory if there is a second clock, in this case
|
||||
the name must be "core" for the first clock and "reg" for the
|
||||
second one
|
||||
- usb2-lpm-disable: indicate if we don't want to enable USB2 HW LPM
|
||||
- usb3-lpm-capable: determines if platform is USB3 LPM capable
|
||||
- quirk-broken-port-ped: set if the controller has broken port disable mechanism
|
||||
|
@ -11270,6 +11270,7 @@ M: Sebastian Reichel <sre@kernel.org>
|
||||
L: linux-pm@vger.kernel.org
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply.git
|
||||
S: Maintained
|
||||
F: Documentation/ABI/testing/sysfs-class-power
|
||||
F: Documentation/devicetree/bindings/power/supply/
|
||||
F: include/linux/power_supply.h
|
||||
F: drivers/power/supply/
|
||||
|
@ -843,12 +843,21 @@ __power_supply_register(struct device *parent,
|
||||
{
|
||||
struct device *dev;
|
||||
struct power_supply *psy;
|
||||
int rc;
|
||||
int i, rc;
|
||||
|
||||
if (!parent)
|
||||
pr_warn("%s: Expected proper parent device for '%s'\n",
|
||||
__func__, desc->name);
|
||||
|
||||
if (!desc || !desc->name || !desc->properties || !desc->num_properties)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
for (i = 0; i < desc->num_properties; ++i) {
|
||||
if ((desc->properties[i] == POWER_SUPPLY_PROP_USB_TYPE) &&
|
||||
(!desc->usb_types || !desc->num_usb_types))
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
psy = kzalloc(sizeof(*psy), GFP_KERNEL);
|
||||
if (!psy)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
@ -46,6 +46,11 @@ static const char * const power_supply_type_text[] = {
|
||||
"USB_PD", "USB_PD_DRP", "BrickID"
|
||||
};
|
||||
|
||||
static const char * const power_supply_usb_type_text[] = {
|
||||
"Unknown", "SDP", "DCP", "CDP", "ACA", "C",
|
||||
"PD", "PD_DRP", "PD_PPS", "BrickID"
|
||||
};
|
||||
|
||||
static const char * const power_supply_status_text[] = {
|
||||
"Unknown", "Charging", "Discharging", "Not charging", "Full"
|
||||
};
|
||||
@ -73,6 +78,41 @@ static const char * const power_supply_scope_text[] = {
|
||||
"Unknown", "System", "Device"
|
||||
};
|
||||
|
||||
static ssize_t power_supply_show_usb_type(struct device *dev,
|
||||
enum power_supply_usb_type *usb_types,
|
||||
ssize_t num_usb_types,
|
||||
union power_supply_propval *value,
|
||||
char *buf)
|
||||
{
|
||||
enum power_supply_usb_type usb_type;
|
||||
ssize_t count = 0;
|
||||
bool match = false;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < num_usb_types; ++i) {
|
||||
usb_type = usb_types[i];
|
||||
|
||||
if (value->intval == usb_type) {
|
||||
count += sprintf(buf + count, "[%s] ",
|
||||
power_supply_usb_type_text[usb_type]);
|
||||
match = true;
|
||||
} else {
|
||||
count += sprintf(buf + count, "%s ",
|
||||
power_supply_usb_type_text[usb_type]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!match) {
|
||||
dev_warn(dev, "driver reporting unsupported connected type\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (count)
|
||||
buf[count - 1] = '\n';
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t power_supply_show_property(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf) {
|
||||
@ -122,6 +162,11 @@ static ssize_t power_supply_show_property(struct device *dev,
|
||||
ret = sprintf(buf, "%s\n",
|
||||
power_supply_type_text[value.intval]);
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_USB_TYPE:
|
||||
ret = power_supply_show_usb_type(dev, psy->desc->usb_types,
|
||||
psy->desc->num_usb_types,
|
||||
&value, buf);
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_SCOPE:
|
||||
ret = sprintf(buf, "%s\n",
|
||||
power_supply_scope_text[value.intval]);
|
||||
@ -252,6 +297,7 @@ static struct device_attribute power_supply_attrs[] = {
|
||||
POWER_SUPPLY_ATTR(time_to_full_now),
|
||||
POWER_SUPPLY_ATTR(time_to_full_avg),
|
||||
POWER_SUPPLY_ATTR(type),
|
||||
POWER_SUPPLY_ATTR(usb_type),
|
||||
POWER_SUPPLY_ATTR(scope),
|
||||
POWER_SUPPLY_ATTR(precharge_current),
|
||||
POWER_SUPPLY_ATTR(charge_term_current),
|
||||
|
@ -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
|
||||
|
@ -1 +1,2 @@
|
||||
obj-$(CONFIG_TYPEC_TCPCI) += tcpci.o
|
||||
obj-$(CONFIG_TYPEC_RT1711H) += tcpci_rt1711h.o
|
||||
|
@ -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
|
||||
|
312
drivers/staging/typec/tcpci_rt1711h.c
Normal file
312
drivers/staging/typec/tcpci_rt1711h.c
Normal file
@ -0,0 +1,312 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2018, Richtek Technology Corporation
|
||||
*
|
||||
* Richtek RT1711H Type-C Chip Driver
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/usb/tcpm.h>
|
||||
#include <linux/regmap.h>
|
||||
#include "tcpci.h"
|
||||
|
||||
#define RT1711H_VID 0x29CF
|
||||
#define RT1711H_PID 0x1711
|
||||
|
||||
#define RT1711H_RTCTRL8 0x9B
|
||||
|
||||
/* Autoidle timeout = (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 = (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;
|
||||
};
|
||||
|
||||
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, u8 *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 = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
|
||||
.max_register = 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 = tdata_to_rt1711h(tdata);
|
||||
|
||||
/* CK 300K from 320K, shipping off, auto_idle enable, tout = 32ms */
|
||||
ret = rt1711h_write8(chip, RT1711H_RTCTRL8,
|
||||
RT1711H_RTCTRL8_SET(0, 1, 1, 2));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* I2C reset : (val + 1) * 12.5ms */
|
||||
ret = rt1711h_write8(chip, RT1711H_RTCTRL11,
|
||||
RT1711H_RTCTRL11_SET(1, 0x0F));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* tTCPCfilter : (26.7 * val) us */
|
||||
ret = rt1711h_write8(chip, RT1711H_RTCTRL14, 0x0F);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* tDRP : (51.2 + 6.4 * val) ms */
|
||||
ret = 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 = tdata_to_rt1711h(tdata);
|
||||
|
||||
return rt1711h_write8(chip, RT1711H_RTCTRL8,
|
||||
RT1711H_RTCTRL8_SET(0, 1, !enable, 2));
|
||||
}
|
||||
|
||||
static int rt1711h_start_drp_toggling(struct tcpci *tcpci,
|
||||
struct tcpci_data *tdata,
|
||||
enum typec_cc_status cc)
|
||||
{
|
||||
struct rt1711h_chip *chip = tdata_to_rt1711h(tdata);
|
||||
int ret;
|
||||
unsigned int reg = 0;
|
||||
|
||||
switch (cc) {
|
||||
default:
|
||||
case TYPEC_CC_RP_DEF:
|
||||
reg |= (TCPC_ROLE_CTRL_RP_VAL_DEF <<
|
||||
TCPC_ROLE_CTRL_RP_VAL_SHIFT);
|
||||
break;
|
||||
case TYPEC_CC_RP_1_5:
|
||||
reg |= (TCPC_ROLE_CTRL_RP_VAL_1_5 <<
|
||||
TCPC_ROLE_CTRL_RP_VAL_SHIFT);
|
||||
break;
|
||||
case TYPEC_CC_RP_3_0:
|
||||
reg |= (TCPC_ROLE_CTRL_RP_VAL_3_0 <<
|
||||
TCPC_ROLE_CTRL_RP_VAL_SHIFT);
|
||||
break;
|
||||
}
|
||||
|
||||
if (cc == TYPEC_CC_RD)
|
||||
reg |= (TCPC_ROLE_CTRL_CC_RD << TCPC_ROLE_CTRL_CC1_SHIFT) |
|
||||
(TCPC_ROLE_CTRL_CC_RD << TCPC_ROLE_CTRL_CC2_SHIFT);
|
||||
else
|
||||
reg |= (TCPC_ROLE_CTRL_CC_RP << TCPC_ROLE_CTRL_CC1_SHIFT) |
|
||||
(TCPC_ROLE_CTRL_CC_RP << TCPC_ROLE_CTRL_CC2_SHIFT);
|
||||
|
||||
ret = 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 = dev_id;
|
||||
|
||||
if (!chip->tcpci)
|
||||
return IRQ_HANDLED;
|
||||
|
||||
ret = rt1711h_read16(chip, TCPC_ALERT, &alert);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
if (alert & TCPC_ALERT_CC_STATUS) {
|
||||
ret = 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_alert(struct rt1711h_chip *chip,
|
||||
struct i2c_client *client)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Disable chip interrupts before requesting irq */
|
||||
ret = rt1711h_write16(chip, TCPC_ALERT_MASK, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = devm_request_threaded_irq(chip->dev, client->irq, NULL,
|
||||
rt1711h_irq,
|
||||
IRQF_ONESHOT | IRQF_TRIGGER_LOW,
|
||||
dev_name(chip->dev), chip);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
enable_irq_wake(client->irq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rt1711h_sw_reset(struct rt1711h_chip *chip)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = 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 = i2c_smbus_read_word_data(i2c, TCPC_VENDOR_ID);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (ret != RT1711H_VID) {
|
||||
dev_err(&i2c->dev, "vid is not correct, 0x%04x\n", ret);
|
||||
return -ENODEV;
|
||||
}
|
||||
ret = i2c_smbus_read_word_data(i2c, TCPC_PRODUCT_ID);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (ret != RT1711H_PID) {
|
||||
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 = rt1711h_check_revision(client);
|
||||
if (ret < 0) {
|
||||
dev_err(&client->dev, "check vid/pid fail\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
|
||||
if (!chip)
|
||||
return -ENOMEM;
|
||||
|
||||
chip->data.regmap = devm_regmap_init_i2c(client,
|
||||
&rt1711h_regmap_config);
|
||||
if (IS_ERR(chip->data.regmap))
|
||||
return PTR_ERR(chip->data.regmap);
|
||||
|
||||
chip->dev = &client->dev;
|
||||
i2c_set_clientdata(client, chip);
|
||||
|
||||
ret = rt1711h_sw_reset(chip);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = rt1711h_init_alert(chip, client);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
chip->data.init = rt1711h_init;
|
||||
chip->data.set_vconn = rt1711h_set_vconn;
|
||||
chip->data.start_drp_toggling = rt1711h_start_drp_toggling;
|
||||
chip->tcpci = 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 = i2c_get_clientdata(client);
|
||||
|
||||
tcpci_unregister_port(chip->tcpci);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id rt1711h_id[] = {
|
||||
{ "rt1711h", 0 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, rt1711h_id);
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id rt1711h_of_match[] = {
|
||||
{ .compatible = "richtek,rt1711h", },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, rt1711h_of_match);
|
||||
#endif
|
||||
|
||||
static struct i2c_driver rt1711h_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "rt1711h",
|
||||
.of_match_table = of_match_ptr(rt1711h_of_match),
|
||||
},
|
||||
.probe = rt1711h_probe,
|
||||
.remove = rt1711h_remove,
|
||||
.id_table = rt1711h_id,
|
||||
};
|
||||
module_i2c_driver(rt1711h_i2c_driver);
|
||||
|
||||
MODULE_AUTHOR("ShuFan Lee <shufan_lee@richtek.com>");
|
||||
MODULE_DESCRIPTION("RT1711H USB Type-C Port Controller Interface Driver");
|
||||
MODULE_LICENSE("GPL");
|
@ -33,7 +33,6 @@
|
||||
#include <linux/phy/phy.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/usb/hcd.h>
|
||||
#include <linux/usb/phy.h>
|
||||
#include <linux/usb/otg.h>
|
||||
|
||||
#include "usb.h"
|
||||
@ -568,6 +567,7 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)
|
||||
switch (wValue & 0xff00) {
|
||||
case USB_DT_DEVICE << 8:
|
||||
switch (hcd->speed) {
|
||||
case HCD_USB32:
|
||||
case HCD_USB31:
|
||||
bufp = usb31_rh_dev_descriptor;
|
||||
break;
|
||||
@ -592,6 +592,7 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)
|
||||
break;
|
||||
case USB_DT_CONFIG << 8:
|
||||
switch (hcd->speed) {
|
||||
case HCD_USB32:
|
||||
case HCD_USB31:
|
||||
case HCD_USB3:
|
||||
bufp = ss_rh_config_descriptor;
|
||||
@ -2739,30 +2740,10 @@ int usb_add_hcd(struct usb_hcd *hcd,
|
||||
int retval;
|
||||
struct usb_device *rhdev;
|
||||
|
||||
if (IS_ENABLED(CONFIG_USB_PHY) && !hcd->skip_phy_initialization) {
|
||||
struct usb_phy *phy = usb_get_phy_dev(hcd->self.sysdev, 0);
|
||||
|
||||
if (IS_ERR(phy)) {
|
||||
retval = PTR_ERR(phy);
|
||||
if (retval == -EPROBE_DEFER)
|
||||
return retval;
|
||||
} else {
|
||||
retval = usb_phy_init(phy);
|
||||
if (retval) {
|
||||
usb_put_phy(phy);
|
||||
return retval;
|
||||
}
|
||||
hcd->usb_phy = phy;
|
||||
hcd->remove_phy = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hcd->skip_phy_initialization && usb_hcd_is_primary_hcd(hcd)) {
|
||||
hcd->phy_roothub = usb_phy_roothub_init(hcd->self.sysdev);
|
||||
if (IS_ERR(hcd->phy_roothub)) {
|
||||
retval = PTR_ERR(hcd->phy_roothub);
|
||||
goto err_phy_roothub_init;
|
||||
}
|
||||
if (IS_ERR(hcd->phy_roothub))
|
||||
return PTR_ERR(hcd->phy_roothub);
|
||||
|
||||
retval = usb_phy_roothub_power_on(hcd->phy_roothub);
|
||||
if (retval)
|
||||
@ -2812,6 +2793,9 @@ int usb_add_hcd(struct usb_hcd *hcd,
|
||||
hcd->self.root_hub = rhdev;
|
||||
mutex_unlock(&usb_port_peer_mutex);
|
||||
|
||||
rhdev->rx_lanes = 1;
|
||||
rhdev->tx_lanes = 1;
|
||||
|
||||
switch (hcd->speed) {
|
||||
case HCD_USB11:
|
||||
rhdev->speed = USB_SPEED_FULL;
|
||||
@ -2825,6 +2809,10 @@ int usb_add_hcd(struct usb_hcd *hcd,
|
||||
case HCD_USB3:
|
||||
rhdev->speed = USB_SPEED_SUPER;
|
||||
break;
|
||||
case HCD_USB32:
|
||||
rhdev->rx_lanes = 2;
|
||||
rhdev->tx_lanes = 2;
|
||||
/* fall through */
|
||||
case HCD_USB31:
|
||||
rhdev->speed = USB_SPEED_SUPER_PLUS;
|
||||
break;
|
||||
@ -2936,12 +2924,7 @@ int usb_add_hcd(struct usb_hcd *hcd,
|
||||
usb_phy_roothub_power_off(hcd->phy_roothub);
|
||||
err_usb_phy_roothub_power_on:
|
||||
usb_phy_roothub_exit(hcd->phy_roothub);
|
||||
err_phy_roothub_init:
|
||||
if (hcd->remove_phy && hcd->usb_phy) {
|
||||
usb_phy_shutdown(hcd->usb_phy);
|
||||
usb_put_phy(hcd->usb_phy);
|
||||
hcd->usb_phy = NULL;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(usb_add_hcd);
|
||||
@ -3017,12 +3000,6 @@ void usb_remove_hcd(struct usb_hcd *hcd)
|
||||
usb_phy_roothub_power_off(hcd->phy_roothub);
|
||||
usb_phy_roothub_exit(hcd->phy_roothub);
|
||||
|
||||
if (hcd->remove_phy && hcd->usb_phy) {
|
||||
usb_phy_shutdown(hcd->usb_phy);
|
||||
usb_put_phy(hcd->usb_phy);
|
||||
hcd->usb_phy = NULL;
|
||||
}
|
||||
|
||||
usb_put_invalidate_rhdev(hcd);
|
||||
hcd->flags = 0;
|
||||
}
|
||||
|
@ -2746,6 +2746,14 @@ static int hub_port_wait_reset(struct usb_hub *hub, int port1,
|
||||
if (!udev)
|
||||
return 0;
|
||||
|
||||
if (hub_is_superspeedplus(hub->hdev)) {
|
||||
/* extended portstatus Rx and Tx lane count are zero based */
|
||||
udev->rx_lanes = USB_EXT_PORT_RX_LANES(ext_portstatus) + 1;
|
||||
udev->tx_lanes = USB_EXT_PORT_TX_LANES(ext_portstatus) + 1;
|
||||
} else {
|
||||
udev->rx_lanes = 1;
|
||||
udev->tx_lanes = 1;
|
||||
}
|
||||
if (hub_is_wusb(hub))
|
||||
udev->speed = USB_SPEED_WIRELESS;
|
||||
else if (hub_is_superspeedplus(hub->hdev) &&
|
||||
@ -3371,6 +3379,10 @@ static int wait_for_connected(struct usb_device *udev,
|
||||
while (delay_ms < 2000) {
|
||||
if (status || *portstatus & USB_PORT_STAT_CONNECTION)
|
||||
break;
|
||||
if (!port_is_power_on(hub, *portstatus)) {
|
||||
status = -ENODEV;
|
||||
break;
|
||||
}
|
||||
msleep(20);
|
||||
delay_ms += 20;
|
||||
status = hub_port_status(hub, *port1, portstatus, portchange);
|
||||
@ -4543,7 +4555,9 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1,
|
||||
* reset. But only on the first attempt,
|
||||
* lest we get into a time out/reset loop
|
||||
*/
|
||||
if (r == 0 || (r == -ETIMEDOUT && retries == 0))
|
||||
if (r == 0 || (r == -ETIMEDOUT &&
|
||||
retries == 0 &&
|
||||
udev->speed > USB_SPEED_FULL))
|
||||
break;
|
||||
}
|
||||
udev->descriptor.bMaxPacketSize0 =
|
||||
@ -4590,9 +4604,12 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1,
|
||||
if (udev->speed >= USB_SPEED_SUPER) {
|
||||
devnum = udev->devnum;
|
||||
dev_info(&udev->dev,
|
||||
"%s SuperSpeed%s USB device number %d using %s\n",
|
||||
"%s SuperSpeed%s%s USB device number %d using %s\n",
|
||||
(udev->config) ? "reset" : "new",
|
||||
(udev->speed == USB_SPEED_SUPER_PLUS) ? "Plus" : "",
|
||||
(udev->speed == USB_SPEED_SUPER_PLUS) ?
|
||||
"Plus Gen 2" : " Gen 1",
|
||||
(udev->rx_lanes == 2 && udev->tx_lanes == 2) ?
|
||||
"x2" : "",
|
||||
devnum, driver_name);
|
||||
}
|
||||
|
||||
|
@ -175,6 +175,26 @@ static ssize_t speed_show(struct device *dev, struct device_attribute *attr,
|
||||
}
|
||||
static DEVICE_ATTR_RO(speed);
|
||||
|
||||
static ssize_t rx_lanes_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct usb_device *udev;
|
||||
|
||||
udev = to_usb_device(dev);
|
||||
return sprintf(buf, "%d\n", udev->rx_lanes);
|
||||
}
|
||||
static DEVICE_ATTR_RO(rx_lanes);
|
||||
|
||||
static ssize_t tx_lanes_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct usb_device *udev;
|
||||
|
||||
udev = to_usb_device(dev);
|
||||
return sprintf(buf, "%d\n", udev->tx_lanes);
|
||||
}
|
||||
static DEVICE_ATTR_RO(tx_lanes);
|
||||
|
||||
static ssize_t busnum_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
@ -790,6 +810,8 @@ static struct attribute *dev_attrs[] = {
|
||||
&dev_attr_bNumConfigurations.attr,
|
||||
&dev_attr_bMaxPacketSize0.attr,
|
||||
&dev_attr_speed.attr,
|
||||
&dev_attr_rx_lanes.attr,
|
||||
&dev_attr_tx_lanes.attr,
|
||||
&dev_attr_busnum.attr,
|
||||
&dev_attr_devnum.attr,
|
||||
&dev_attr_devpath.attr,
|
||||
|
@ -179,7 +179,7 @@ config USB_R8A66597
|
||||
|
||||
config USB_RENESAS_USBHS_UDC
|
||||
tristate 'Renesas USBHS controller'
|
||||
depends on USB_RENESAS_USBHS && HAS_DMA
|
||||
depends on USB_RENESAS_USBHS
|
||||
help
|
||||
Renesas USBHS is a discrete USB host and peripheral controller chip
|
||||
that supports both full and high speed USB 2.0 data transfers.
|
||||
@ -192,7 +192,7 @@ config USB_RENESAS_USBHS_UDC
|
||||
config USB_RENESAS_USB3
|
||||
tristate 'Renesas USB3.0 Peripheral controller'
|
||||
depends on ARCH_RENESAS || COMPILE_TEST
|
||||
depends on EXTCON && HAS_DMA
|
||||
depends on EXTCON
|
||||
help
|
||||
Renesas USB3.0 Peripheral controller is a USB peripheral controller
|
||||
that supports super, high, and full speed USB 3.0 data transfers.
|
||||
|
@ -234,9 +234,7 @@ config USB_EHCI_TEGRA
|
||||
tristate "NVIDIA Tegra HCD support"
|
||||
depends on ARCH_TEGRA
|
||||
select USB_EHCI_ROOT_HUB_TT
|
||||
select USB_PHY
|
||||
select USB_ULPI
|
||||
select USB_ULPI_VIEWPORT
|
||||
select USB_TEGRA_PHY
|
||||
help
|
||||
This driver enables support for the internal USB Host Controllers
|
||||
found in NVIDIA Tegra SoCs. The controllers are EHCI compliant.
|
||||
|
@ -157,10 +157,7 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)
|
||||
struct usb_phy *phy;
|
||||
|
||||
/* get the PHY device */
|
||||
if (dev->of_node)
|
||||
phy = devm_usb_get_phy_by_phandle(dev, "phys", i);
|
||||
else
|
||||
phy = devm_usb_get_phy_dev(dev, i);
|
||||
phy = devm_usb_get_phy_by_phandle(dev, "phys", i);
|
||||
if (IS_ERR(phy)) {
|
||||
/* Don't bail out if PHY is not absolutely necessary */
|
||||
if (pdata->port_mode[i] != OMAP_EHCI_PORT_MODE_PHY)
|
||||
|
@ -36,7 +36,6 @@
|
||||
#define DRV_NAME "tegra-ehci"
|
||||
|
||||
static struct hc_driver __read_mostly tegra_ehci_hc_driver;
|
||||
static bool usb1_reset_attempted;
|
||||
|
||||
struct tegra_ehci_soc_config {
|
||||
bool has_hostpc;
|
||||
@ -51,68 +50,55 @@ struct tegra_ehci_hcd {
|
||||
enum tegra_usb_phy_port_speed port_speed;
|
||||
};
|
||||
|
||||
/*
|
||||
* The 1st USB controller contains some UTMI pad registers that are global for
|
||||
* all the controllers on the chip. Those registers are also cleared when
|
||||
* reset is asserted to the 1st controller. This means that the 1st controller
|
||||
* can only be reset when no other controlled has finished probing. So we'll
|
||||
* reset the 1st controller before doing any other setup on any of the
|
||||
* controllers, and then never again.
|
||||
*
|
||||
* Since this is a PHY issue, the Tegra PHY driver should probably be doing
|
||||
* the resetting of the USB controllers. But to keep compatibility with old
|
||||
* device trees that don't have reset phandles in the PHYs, do it here.
|
||||
* Those old DTs will be vulnerable to total USB breakage if the 1st EHCI
|
||||
* device isn't the first one to finish probing, so warn them.
|
||||
*/
|
||||
static int tegra_reset_usb_controller(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *phy_np;
|
||||
struct usb_hcd *hcd = platform_get_drvdata(pdev);
|
||||
struct tegra_ehci_hcd *tegra =
|
||||
(struct tegra_ehci_hcd *)hcd_to_ehci(hcd)->priv;
|
||||
bool has_utmi_pad_registers = false;
|
||||
struct reset_control *rst;
|
||||
int err;
|
||||
|
||||
phy_np = of_parse_phandle(pdev->dev.of_node, "nvidia,phy", 0);
|
||||
if (!phy_np)
|
||||
return -ENOENT;
|
||||
|
||||
if (of_property_read_bool(phy_np, "nvidia,has-utmi-pad-registers"))
|
||||
has_utmi_pad_registers = true;
|
||||
|
||||
if (!usb1_reset_attempted) {
|
||||
struct reset_control *usb1_reset;
|
||||
|
||||
if (!has_utmi_pad_registers)
|
||||
usb1_reset = of_reset_control_get(phy_np, "utmi-pads");
|
||||
else
|
||||
usb1_reset = tegra->rst;
|
||||
|
||||
if (IS_ERR(usb1_reset)) {
|
||||
dev_warn(&pdev->dev,
|
||||
"can't get utmi-pads reset from the PHY\n");
|
||||
dev_warn(&pdev->dev,
|
||||
"continuing, but please update your DT\n");
|
||||
} else {
|
||||
reset_control_assert(usb1_reset);
|
||||
udelay(1);
|
||||
reset_control_deassert(usb1_reset);
|
||||
|
||||
if (!has_utmi_pad_registers)
|
||||
reset_control_put(usb1_reset);
|
||||
}
|
||||
|
||||
usb1_reset_attempted = true;
|
||||
}
|
||||
|
||||
if (!has_utmi_pad_registers) {
|
||||
reset_control_assert(tegra->rst);
|
||||
udelay(1);
|
||||
reset_control_deassert(tegra->rst);
|
||||
/*
|
||||
* The 1st USB controller contains some UTMI pad registers that are
|
||||
* global for all the controllers on the chip. Those registers are
|
||||
* also cleared when reset is asserted to the 1st controller.
|
||||
*/
|
||||
rst = of_reset_control_get_shared(phy_np, "utmi-pads");
|
||||
if (IS_ERR(rst)) {
|
||||
dev_warn(&pdev->dev,
|
||||
"can't get utmi-pads reset from the PHY\n");
|
||||
dev_warn(&pdev->dev,
|
||||
"continuing, but please update your DT\n");
|
||||
} else {
|
||||
/*
|
||||
* PHY driver performs UTMI-pads reset in a case of
|
||||
* non-legacy DT.
|
||||
*/
|
||||
reset_control_put(rst);
|
||||
}
|
||||
|
||||
of_node_put(phy_np);
|
||||
|
||||
/* reset control is shared, hence initialize it first */
|
||||
err = reset_control_deassert(tegra->rst);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = reset_control_assert(tegra->rst);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
udelay(1);
|
||||
|
||||
err = reset_control_deassert(tegra->rst);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -440,7 +426,7 @@ static int tegra_ehci_probe(struct platform_device *pdev)
|
||||
goto cleanup_hcd_create;
|
||||
}
|
||||
|
||||
tegra->rst = devm_reset_control_get(&pdev->dev, "usb");
|
||||
tegra->rst = devm_reset_control_get_shared(&pdev->dev, "usb");
|
||||
if (IS_ERR(tegra->rst)) {
|
||||
dev_err(&pdev->dev, "Can't get ehci reset\n");
|
||||
err = PTR_ERR(tegra->rst);
|
||||
@ -452,8 +438,10 @@ static int tegra_ehci_probe(struct platform_device *pdev)
|
||||
goto cleanup_hcd_create;
|
||||
|
||||
err = tegra_reset_usb_controller(pdev);
|
||||
if (err)
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "Failed to reset controller\n");
|
||||
goto cleanup_clk_en;
|
||||
}
|
||||
|
||||
u_phy = devm_usb_get_phy_by_phandle(&pdev->dev, "nvidia,phy", 0);
|
||||
if (IS_ERR(u_phy)) {
|
||||
@ -538,6 +526,9 @@ static int tegra_ehci_remove(struct platform_device *pdev)
|
||||
usb_phy_shutdown(hcd->usb_phy);
|
||||
usb_remove_hcd(hcd);
|
||||
|
||||
reset_control_assert(tegra->rst);
|
||||
udelay(1);
|
||||
|
||||
clk_disable_unprepare(tegra->clk);
|
||||
|
||||
usb_put_hcd(hcd);
|
||||
|
@ -157,6 +157,7 @@ static int xhci_plat_probe(struct platform_device *pdev)
|
||||
struct resource *res;
|
||||
struct usb_hcd *hcd;
|
||||
struct clk *clk;
|
||||
struct clk *reg_clk;
|
||||
int ret;
|
||||
int irq;
|
||||
|
||||
@ -226,17 +227,27 @@ static int xhci_plat_probe(struct platform_device *pdev)
|
||||
hcd->rsrc_len = resource_size(res);
|
||||
|
||||
/*
|
||||
* Not all platforms have a clk so it is not an error if the
|
||||
* clock does not exists.
|
||||
* Not all platforms have clks so it is not an error if the
|
||||
* clock do not exist.
|
||||
*/
|
||||
reg_clk = devm_clk_get(&pdev->dev, "reg");
|
||||
if (!IS_ERR(reg_clk)) {
|
||||
ret = clk_prepare_enable(reg_clk);
|
||||
if (ret)
|
||||
goto put_hcd;
|
||||
} else if (PTR_ERR(reg_clk) == -EPROBE_DEFER) {
|
||||
ret = -EPROBE_DEFER;
|
||||
goto put_hcd;
|
||||
}
|
||||
|
||||
clk = devm_clk_get(&pdev->dev, NULL);
|
||||
if (!IS_ERR(clk)) {
|
||||
ret = clk_prepare_enable(clk);
|
||||
if (ret)
|
||||
goto put_hcd;
|
||||
goto disable_reg_clk;
|
||||
} else if (PTR_ERR(clk) == -EPROBE_DEFER) {
|
||||
ret = -EPROBE_DEFER;
|
||||
goto put_hcd;
|
||||
goto disable_reg_clk;
|
||||
}
|
||||
|
||||
xhci = hcd_to_xhci(hcd);
|
||||
@ -252,6 +263,7 @@ static int xhci_plat_probe(struct platform_device *pdev)
|
||||
device_wakeup_enable(hcd->self.controller);
|
||||
|
||||
xhci->clk = clk;
|
||||
xhci->reg_clk = reg_clk;
|
||||
xhci->main_hcd = hcd;
|
||||
xhci->shared_hcd = __usb_create_hcd(driver, sysdev, &pdev->dev,
|
||||
dev_name(&pdev->dev), hcd);
|
||||
@ -320,8 +332,10 @@ static int xhci_plat_probe(struct platform_device *pdev)
|
||||
usb_put_hcd(xhci->shared_hcd);
|
||||
|
||||
disable_clk:
|
||||
if (!IS_ERR(clk))
|
||||
clk_disable_unprepare(clk);
|
||||
clk_disable_unprepare(clk);
|
||||
|
||||
disable_reg_clk:
|
||||
clk_disable_unprepare(reg_clk);
|
||||
|
||||
put_hcd:
|
||||
usb_put_hcd(hcd);
|
||||
@ -338,6 +352,7 @@ static int xhci_plat_remove(struct platform_device *dev)
|
||||
struct usb_hcd *hcd = platform_get_drvdata(dev);
|
||||
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
|
||||
struct clk *clk = xhci->clk;
|
||||
struct clk *reg_clk = xhci->reg_clk;
|
||||
|
||||
xhci->xhc_state |= XHCI_STATE_REMOVING;
|
||||
|
||||
@ -347,8 +362,8 @@ static int xhci_plat_remove(struct platform_device *dev)
|
||||
usb_remove_hcd(hcd);
|
||||
usb_put_hcd(xhci->shared_hcd);
|
||||
|
||||
if (!IS_ERR(clk))
|
||||
clk_disable_unprepare(clk);
|
||||
clk_disable_unprepare(clk);
|
||||
clk_disable_unprepare(reg_clk);
|
||||
usb_put_hcd(hcd);
|
||||
|
||||
pm_runtime_set_suspended(&dev->dev);
|
||||
|
@ -1729,8 +1729,9 @@ struct xhci_hcd {
|
||||
int page_shift;
|
||||
/* msi-x vectors */
|
||||
int msix_count;
|
||||
/* optional clock */
|
||||
/* optional clocks */
|
||||
struct clk *clk;
|
||||
struct clk *reg_clk;
|
||||
/* data structures */
|
||||
struct xhci_device_context_array *dcbaa;
|
||||
struct xhci_ring *cmd_ring;
|
||||
|
@ -31,7 +31,7 @@ static void isp1760_init_core(struct isp1760_device *isp)
|
||||
/* Low-level chip reset */
|
||||
if (isp->rst_gpio) {
|
||||
gpiod_set_value_cansleep(isp->rst_gpio, 1);
|
||||
mdelay(50);
|
||||
msleep(50);
|
||||
gpiod_set_value_cansleep(isp->rst_gpio, 0);
|
||||
}
|
||||
|
||||
|
@ -2093,7 +2093,7 @@ static void isp1760_stop(struct usb_hcd *hcd)
|
||||
|
||||
isp1760_hub_control(hcd, ClearPortFeature, USB_PORT_FEAT_POWER, 1,
|
||||
NULL, 0);
|
||||
mdelay(20);
|
||||
msleep(20);
|
||||
|
||||
spin_lock_irq(&priv->lock);
|
||||
ehci_reset(hcd);
|
||||
|
@ -1227,7 +1227,7 @@ static void mon_bin_vma_close(struct vm_area_struct *vma)
|
||||
/*
|
||||
* Map ring pages to user space.
|
||||
*/
|
||||
static int mon_bin_vma_fault(struct vm_fault *vmf)
|
||||
static vm_fault_t mon_bin_vma_fault(struct vm_fault *vmf)
|
||||
{
|
||||
struct mon_reader_bin *rp = vmf->vma->vm_private_data;
|
||||
unsigned long offset, chunk_idx;
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
config USB_MTU3
|
||||
tristate "MediaTek USB3 Dual Role controller"
|
||||
depends on EXTCON && (USB || USB_GADGET) && HAS_DMA
|
||||
depends on EXTCON && (USB || USB_GADGET)
|
||||
depends on ARCH_MEDIATEK || COMPILE_TEST
|
||||
select USB_XHCI_MTK if USB_SUPPORT && USB_XHCI_HCD
|
||||
help
|
||||
|
@ -447,8 +447,7 @@ static int mtu3_remove(struct platform_device *pdev)
|
||||
*/
|
||||
static int __maybe_unused mtu3_suspend(struct device *dev)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct ssusb_mtk *ssusb = platform_get_drvdata(pdev);
|
||||
struct ssusb_mtk *ssusb = dev_get_drvdata(dev);
|
||||
|
||||
dev_dbg(dev, "%s\n", __func__);
|
||||
|
||||
@ -466,8 +465,7 @@ static int __maybe_unused mtu3_suspend(struct device *dev)
|
||||
|
||||
static int __maybe_unused mtu3_resume(struct device *dev)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct ssusb_mtk *ssusb = platform_get_drvdata(pdev);
|
||||
struct ssusb_mtk *ssusb = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
|
||||
dev_dbg(dev, "%s\n", __func__);
|
||||
|
@ -239,21 +239,15 @@ static int omap2430_musb_init(struct musb *musb)
|
||||
* up through ULPI. TWL4030-family PMICs include one,
|
||||
* which needs a driver, drivers aren't always needed.
|
||||
*/
|
||||
if (dev->parent->of_node) {
|
||||
musb->phy = devm_phy_get(dev->parent, "usb2-phy");
|
||||
musb->phy = devm_phy_get(dev->parent, "usb2-phy");
|
||||
|
||||
/* We can't totally remove musb->xceiv as of now because
|
||||
* musb core uses xceiv.state and xceiv.otg. Once we have
|
||||
* a separate state machine to handle otg, these can be moved
|
||||
* out of xceiv and then we can start using the generic PHY
|
||||
* framework
|
||||
*/
|
||||
musb->xceiv = devm_usb_get_phy_by_phandle(dev->parent,
|
||||
"usb-phy", 0);
|
||||
} else {
|
||||
musb->xceiv = devm_usb_get_phy_dev(dev, 0);
|
||||
musb->phy = devm_phy_get(dev, "usb");
|
||||
}
|
||||
/* We can't totally remove musb->xceiv as of now because
|
||||
* musb core uses xceiv.state and xceiv.otg. Once we have
|
||||
* a separate state machine to handle otg, these can be moved
|
||||
* out of xceiv and then we can start using the generic PHY
|
||||
* framework
|
||||
*/
|
||||
musb->xceiv = devm_usb_get_phy_by_phandle(dev->parent, "usb-phy", 0);
|
||||
|
||||
if (IS_ERR(musb->xceiv)) {
|
||||
status = PTR_ERR(musb->xceiv);
|
||||
@ -391,8 +385,13 @@ static int omap2430_probe(struct platform_device *pdev)
|
||||
struct omap2430_glue *glue;
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct musb_hdrc_config *config;
|
||||
struct device_node *control_node;
|
||||
struct platform_device *control_pdev;
|
||||
int ret = -ENOMEM, val;
|
||||
|
||||
if (!np)
|
||||
return -ENODEV;
|
||||
|
||||
glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL);
|
||||
if (!glue)
|
||||
goto err0;
|
||||
@ -412,47 +411,43 @@ static int omap2430_probe(struct platform_device *pdev)
|
||||
glue->status = MUSB_UNKNOWN;
|
||||
glue->control_otghs = ERR_PTR(-ENODEV);
|
||||
|
||||
if (np) {
|
||||
struct device_node *control_node;
|
||||
struct platform_device *control_pdev;
|
||||
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
|
||||
if (!pdata)
|
||||
goto err2;
|
||||
|
||||
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
|
||||
if (!pdata)
|
||||
data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
|
||||
if (!data)
|
||||
goto err2;
|
||||
|
||||
config = devm_kzalloc(&pdev->dev, sizeof(*config), GFP_KERNEL);
|
||||
if (!config)
|
||||
goto err2;
|
||||
|
||||
of_property_read_u32(np, "mode", (u32 *)&pdata->mode);
|
||||
of_property_read_u32(np, "interface-type",
|
||||
(u32 *)&data->interface_type);
|
||||
of_property_read_u32(np, "num-eps", (u32 *)&config->num_eps);
|
||||
of_property_read_u32(np, "ram-bits", (u32 *)&config->ram_bits);
|
||||
of_property_read_u32(np, "power", (u32 *)&pdata->power);
|
||||
|
||||
ret = of_property_read_u32(np, "multipoint", &val);
|
||||
if (!ret && val)
|
||||
config->multipoint = true;
|
||||
|
||||
pdata->board_data = data;
|
||||
pdata->config = config;
|
||||
|
||||
control_node = of_parse_phandle(np, "ctrl-module", 0);
|
||||
if (control_node) {
|
||||
control_pdev = of_find_device_by_node(control_node);
|
||||
if (!control_pdev) {
|
||||
dev_err(&pdev->dev, "Failed to get control device\n");
|
||||
ret = -EINVAL;
|
||||
goto err2;
|
||||
|
||||
data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
|
||||
if (!data)
|
||||
goto err2;
|
||||
|
||||
config = devm_kzalloc(&pdev->dev, sizeof(*config), GFP_KERNEL);
|
||||
if (!config)
|
||||
goto err2;
|
||||
|
||||
of_property_read_u32(np, "mode", (u32 *)&pdata->mode);
|
||||
of_property_read_u32(np, "interface-type",
|
||||
(u32 *)&data->interface_type);
|
||||
of_property_read_u32(np, "num-eps", (u32 *)&config->num_eps);
|
||||
of_property_read_u32(np, "ram-bits", (u32 *)&config->ram_bits);
|
||||
of_property_read_u32(np, "power", (u32 *)&pdata->power);
|
||||
|
||||
ret = of_property_read_u32(np, "multipoint", &val);
|
||||
if (!ret && val)
|
||||
config->multipoint = true;
|
||||
|
||||
pdata->board_data = data;
|
||||
pdata->config = config;
|
||||
|
||||
control_node = of_parse_phandle(np, "ctrl-module", 0);
|
||||
if (control_node) {
|
||||
control_pdev = of_find_device_by_node(control_node);
|
||||
if (!control_pdev) {
|
||||
dev_err(&pdev->dev, "Failed to get control device\n");
|
||||
ret = -EINVAL;
|
||||
goto err2;
|
||||
}
|
||||
glue->control_otghs = &control_pdev->dev;
|
||||
}
|
||||
glue->control_otghs = &control_pdev->dev;
|
||||
}
|
||||
|
||||
pdata->platform_ops = &omap2430_ops;
|
||||
|
||||
platform_set_drvdata(pdev, glue);
|
||||
|
@ -159,6 +159,15 @@ config USB_MXS_PHY
|
||||
|
||||
MXS Phy is used by some of the i.MX SoCs, for example imx23/28/6x.
|
||||
|
||||
config USB_TEGRA_PHY
|
||||
tristate "NVIDIA Tegra USB PHY Driver"
|
||||
depends on ARCH_TEGRA
|
||||
select USB_PHY
|
||||
select USB_ULPI
|
||||
help
|
||||
This driver provides PHY support for the USB controllers found
|
||||
on NVIDIA Tegra SoC's.
|
||||
|
||||
config USB_ULPI
|
||||
bool "Generic ULPI Transceiver Driver"
|
||||
depends on ARM || ARM64
|
||||
|
@ -16,7 +16,7 @@ obj-$(CONFIG_AM335X_CONTROL_USB) += phy-am335x-control.o
|
||||
obj-$(CONFIG_AM335X_PHY_USB) += phy-am335x.o
|
||||
obj-$(CONFIG_OMAP_OTG) += phy-omap-otg.o
|
||||
obj-$(CONFIG_TWL6030_USB) += phy-twl6030-usb.o
|
||||
obj-$(CONFIG_USB_EHCI_TEGRA) += phy-tegra-usb.o
|
||||
obj-$(CONFIG_USB_TEGRA_PHY) += phy-tegra-usb.o
|
||||
obj-$(CONFIG_USB_GPIO_VBUS) += phy-gpio-vbus-usb.o
|
||||
obj-$(CONFIG_USB_ISP1301) += phy-isp1301.o
|
||||
obj-$(CONFIG_USB_MV_OTG) += phy-mv-usb.o
|
||||
|
@ -96,8 +96,7 @@ static int am335x_phy_remove(struct platform_device *pdev)
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int am335x_phy_suspend(struct device *dev)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct am335x_phy *am_phy = platform_get_drvdata(pdev);
|
||||
struct am335x_phy *am_phy = dev_get_drvdata(dev);
|
||||
|
||||
/*
|
||||
* Enable phy wakeup only if dev->power.can_wakeup is true.
|
||||
@ -117,8 +116,7 @@ static int am335x_phy_suspend(struct device *dev)
|
||||
|
||||
static int am335x_phy_resume(struct device *dev)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct am335x_phy *am_phy = platform_get_drvdata(pdev);
|
||||
struct am335x_phy *am_phy = dev_get_drvdata(dev);
|
||||
|
||||
phy_ctrl_power(am_phy->phy_ctrl, am_phy->id, am_phy->dr_mode, true);
|
||||
|
||||
|
@ -236,13 +236,83 @@ static void set_phcd(struct tegra_usb_phy *phy, bool enable)
|
||||
|
||||
static int utmip_pad_open(struct tegra_usb_phy *phy)
|
||||
{
|
||||
int ret;
|
||||
|
||||
phy->pad_clk = devm_clk_get(phy->u_phy.dev, "utmi-pads");
|
||||
if (IS_ERR(phy->pad_clk)) {
|
||||
pr_err("%s: can't get utmip pad clock\n", __func__);
|
||||
return PTR_ERR(phy->pad_clk);
|
||||
ret = PTR_ERR(phy->pad_clk);
|
||||
dev_err(phy->u_phy.dev,
|
||||
"Failed to get UTMIP pad clock: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
phy->pad_rst = devm_reset_control_get_optional_shared(
|
||||
phy->u_phy.dev, "utmi-pads");
|
||||
if (IS_ERR(phy->pad_rst)) {
|
||||
ret = PTR_ERR(phy->pad_rst);
|
||||
dev_err(phy->u_phy.dev,
|
||||
"Failed to get UTMI-pads reset: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(phy->pad_clk);
|
||||
if (ret) {
|
||||
dev_err(phy->u_phy.dev,
|
||||
"Failed to enable UTMI-pads clock: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
spin_lock(&utmip_pad_lock);
|
||||
|
||||
ret = reset_control_deassert(phy->pad_rst);
|
||||
if (ret) {
|
||||
dev_err(phy->u_phy.dev,
|
||||
"Failed to initialize UTMI-pads reset: %d\n", ret);
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
ret = reset_control_assert(phy->pad_rst);
|
||||
if (ret) {
|
||||
dev_err(phy->u_phy.dev,
|
||||
"Failed to assert UTMI-pads reset: %d\n", ret);
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
udelay(1);
|
||||
|
||||
ret = reset_control_deassert(phy->pad_rst);
|
||||
if (ret)
|
||||
dev_err(phy->u_phy.dev,
|
||||
"Failed to deassert UTMI-pads reset: %d\n", ret);
|
||||
unlock:
|
||||
spin_unlock(&utmip_pad_lock);
|
||||
|
||||
clk_disable_unprepare(phy->pad_clk);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int utmip_pad_close(struct tegra_usb_phy *phy)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = clk_prepare_enable(phy->pad_clk);
|
||||
if (ret) {
|
||||
dev_err(phy->u_phy.dev,
|
||||
"Failed to enable UTMI-pads clock: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = reset_control_assert(phy->pad_rst);
|
||||
if (ret)
|
||||
dev_err(phy->u_phy.dev,
|
||||
"Failed to assert UTMI-pads reset: %d\n", ret);
|
||||
|
||||
udelay(1);
|
||||
|
||||
clk_disable_unprepare(phy->pad_clk);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void utmip_pad_power_on(struct tegra_usb_phy *phy)
|
||||
@ -282,7 +352,7 @@ static int utmip_pad_power_off(struct tegra_usb_phy *phy)
|
||||
void __iomem *base = phy->pad_regs;
|
||||
|
||||
if (!utmip_pad_count) {
|
||||
pr_err("%s: utmip pad already powered off\n", __func__);
|
||||
dev_err(phy->u_phy.dev, "UTMIP pad already powered off\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -338,7 +408,8 @@ static void utmi_phy_clk_disable(struct tegra_usb_phy *phy)
|
||||
set_phcd(phy, true);
|
||||
|
||||
if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, 0) < 0)
|
||||
pr_err("%s: timeout waiting for phy to stabilize\n", __func__);
|
||||
dev_err(phy->u_phy.dev,
|
||||
"Timeout waiting for PHY to stabilize on disable\n");
|
||||
}
|
||||
|
||||
static void utmi_phy_clk_enable(struct tegra_usb_phy *phy)
|
||||
@ -370,7 +441,8 @@ static void utmi_phy_clk_enable(struct tegra_usb_phy *phy)
|
||||
|
||||
if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID,
|
||||
USB_PHY_CLK_VALID))
|
||||
pr_err("%s: timeout waiting for phy to stabilize\n", __func__);
|
||||
dev_err(phy->u_phy.dev,
|
||||
"Timeout waiting for PHY to stabilize on enable\n");
|
||||
}
|
||||
|
||||
static int utmi_phy_power_on(struct tegra_usb_phy *phy)
|
||||
@ -617,15 +689,15 @@ static int ulpi_phy_power_on(struct tegra_usb_phy *phy)
|
||||
|
||||
ret = gpio_direction_output(phy->reset_gpio, 0);
|
||||
if (ret < 0) {
|
||||
dev_err(phy->u_phy.dev, "gpio %d not set to 0\n",
|
||||
phy->reset_gpio);
|
||||
dev_err(phy->u_phy.dev, "GPIO %d not set to 0: %d\n",
|
||||
phy->reset_gpio, ret);
|
||||
return ret;
|
||||
}
|
||||
msleep(5);
|
||||
ret = gpio_direction_output(phy->reset_gpio, 1);
|
||||
if (ret < 0) {
|
||||
dev_err(phy->u_phy.dev, "gpio %d not set to 1\n",
|
||||
phy->reset_gpio);
|
||||
dev_err(phy->u_phy.dev, "GPIO %d not set to 1: %d\n",
|
||||
phy->reset_gpio, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -661,13 +733,13 @@ static int ulpi_phy_power_on(struct tegra_usb_phy *phy)
|
||||
/* Fix VbusInvalid due to floating VBUS */
|
||||
ret = usb_phy_io_write(phy->ulpi, 0x40, 0x08);
|
||||
if (ret) {
|
||||
pr_err("%s: ulpi write failed\n", __func__);
|
||||
dev_err(phy->u_phy.dev, "ULPI write failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = usb_phy_io_write(phy->ulpi, 0x80, 0x0B);
|
||||
if (ret) {
|
||||
pr_err("%s: ulpi write failed\n", __func__);
|
||||
dev_err(phy->u_phy.dev, "ULPI write failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -694,6 +766,9 @@ static void tegra_usb_phy_close(struct tegra_usb_phy *phy)
|
||||
if (!IS_ERR(phy->vbus))
|
||||
regulator_disable(phy->vbus);
|
||||
|
||||
if (!phy->is_ulpi_phy)
|
||||
utmip_pad_close(phy);
|
||||
|
||||
clk_disable_unprepare(phy->pll_u);
|
||||
}
|
||||
|
||||
@ -728,28 +803,30 @@ static int ulpi_open(struct tegra_usb_phy *phy)
|
||||
|
||||
phy->clk = devm_clk_get(phy->u_phy.dev, "ulpi-link");
|
||||
if (IS_ERR(phy->clk)) {
|
||||
pr_err("%s: can't get ulpi clock\n", __func__);
|
||||
return PTR_ERR(phy->clk);
|
||||
err = PTR_ERR(phy->clk);
|
||||
dev_err(phy->u_phy.dev, "Failed to get ULPI clock: %d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = devm_gpio_request(phy->u_phy.dev, phy->reset_gpio,
|
||||
"ulpi_phy_reset_b");
|
||||
if (err < 0) {
|
||||
dev_err(phy->u_phy.dev, "request failed for gpio: %d\n",
|
||||
phy->reset_gpio);
|
||||
dev_err(phy->u_phy.dev, "Request failed for GPIO %d: %d\n",
|
||||
phy->reset_gpio, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = gpio_direction_output(phy->reset_gpio, 0);
|
||||
if (err < 0) {
|
||||
dev_err(phy->u_phy.dev, "gpio %d direction not set to output\n",
|
||||
phy->reset_gpio);
|
||||
dev_err(phy->u_phy.dev,
|
||||
"GPIO %d direction not set to output: %d\n",
|
||||
phy->reset_gpio, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
phy->ulpi = otg_ulpi_create(&ulpi_viewport_access_ops, 0);
|
||||
if (!phy->ulpi) {
|
||||
dev_err(phy->u_phy.dev, "otg_ulpi_create returned NULL\n");
|
||||
dev_err(phy->u_phy.dev, "Failed to create ULPI OTG\n");
|
||||
err = -ENOMEM;
|
||||
return err;
|
||||
}
|
||||
@ -766,8 +843,10 @@ static int tegra_usb_phy_init(struct tegra_usb_phy *phy)
|
||||
|
||||
phy->pll_u = devm_clk_get(phy->u_phy.dev, "pll_u");
|
||||
if (IS_ERR(phy->pll_u)) {
|
||||
pr_err("Can't get pll_u clock\n");
|
||||
return PTR_ERR(phy->pll_u);
|
||||
err = PTR_ERR(phy->pll_u);
|
||||
dev_err(phy->u_phy.dev,
|
||||
"Failed to get pll_u clock: %d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = clk_prepare_enable(phy->pll_u);
|
||||
@ -782,7 +861,8 @@ static int tegra_usb_phy_init(struct tegra_usb_phy *phy)
|
||||
}
|
||||
}
|
||||
if (!phy->freq) {
|
||||
pr_err("invalid pll_u parent rate %ld\n", parent_rate);
|
||||
dev_err(phy->u_phy.dev, "Invalid pll_u parent rate %ld\n",
|
||||
parent_rate);
|
||||
err = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
@ -791,7 +871,7 @@ static int tegra_usb_phy_init(struct tegra_usb_phy *phy)
|
||||
err = regulator_enable(phy->vbus);
|
||||
if (err) {
|
||||
dev_err(phy->u_phy.dev,
|
||||
"failed to enable usb vbus regulator: %d\n",
|
||||
"Failed to enable USB VBUS regulator: %d\n",
|
||||
err);
|
||||
goto fail;
|
||||
}
|
||||
@ -855,7 +935,8 @@ static int read_utmi_param(struct platform_device *pdev, const char *param,
|
||||
int err = of_property_read_u32(pdev->dev.of_node, param, &value);
|
||||
*dest = (u8)value;
|
||||
if (err < 0)
|
||||
dev_err(&pdev->dev, "Failed to read USB UTMI parameter %s: %d\n",
|
||||
dev_err(&pdev->dev,
|
||||
"Failed to read USB UTMI parameter %s: %d\n",
|
||||
param, err);
|
||||
return err;
|
||||
}
|
||||
@ -871,14 +952,14 @@ static int utmi_phy_probe(struct tegra_usb_phy *tegra_phy,
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
||||
if (!res) {
|
||||
dev_err(&pdev->dev, "Failed to get UTMI Pad regs\n");
|
||||
dev_err(&pdev->dev, "Failed to get UTMI pad regs\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
tegra_phy->pad_regs = devm_ioremap(&pdev->dev, res->start,
|
||||
resource_size(res));
|
||||
if (!tegra_phy->pad_regs) {
|
||||
dev_err(&pdev->dev, "Failed to remap UTMI Pad regs\n");
|
||||
dev_err(&pdev->dev, "Failed to remap UTMI pad regs\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
@ -1020,15 +1101,16 @@ static int tegra_usb_phy_probe(struct platform_device *pdev)
|
||||
tegra_phy->reset_gpio =
|
||||
of_get_named_gpio(np, "nvidia,phy-reset-gpio", 0);
|
||||
if (!gpio_is_valid(tegra_phy->reset_gpio)) {
|
||||
dev_err(&pdev->dev, "invalid gpio: %d\n",
|
||||
tegra_phy->reset_gpio);
|
||||
dev_err(&pdev->dev,
|
||||
"Invalid GPIO: %d\n", tegra_phy->reset_gpio);
|
||||
return tegra_phy->reset_gpio;
|
||||
}
|
||||
tegra_phy->config = NULL;
|
||||
break;
|
||||
|
||||
default:
|
||||
dev_err(&pdev->dev, "phy_type is invalid or unsupported\n");
|
||||
dev_err(&pdev->dev, "phy_type %u is invalid or unsupported\n",
|
||||
phy_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,6 @@
|
||||
#define DEFAULT_ACA_CUR_MAX 5000
|
||||
|
||||
static LIST_HEAD(phy_list);
|
||||
static LIST_HEAD(phy_bind_list);
|
||||
static DEFINE_SPINLOCK(phy_lock);
|
||||
|
||||
struct phy_devm {
|
||||
@ -50,24 +49,6 @@ static struct usb_phy *__usb_find_phy(struct list_head *list,
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
static struct usb_phy *__usb_find_phy_dev(struct device *dev,
|
||||
struct list_head *list, u8 index)
|
||||
{
|
||||
struct usb_phy_bind *phy_bind = NULL;
|
||||
|
||||
list_for_each_entry(phy_bind, list, list) {
|
||||
if (!(strcmp(phy_bind->dev_name, dev_name(dev))) &&
|
||||
phy_bind->index == index) {
|
||||
if (phy_bind->phy)
|
||||
return phy_bind->phy;
|
||||
else
|
||||
return ERR_PTR(-EPROBE_DEFER);
|
||||
}
|
||||
}
|
||||
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
static struct usb_phy *__of_usb_find_phy(struct device_node *node)
|
||||
{
|
||||
struct usb_phy *phy;
|
||||
@ -584,72 +565,6 @@ struct usb_phy *devm_usb_get_phy_by_phandle(struct device *dev,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_usb_get_phy_by_phandle);
|
||||
|
||||
/**
|
||||
* usb_get_phy_dev - find the USB PHY
|
||||
* @dev - device that requests this phy
|
||||
* @index - the index of the phy
|
||||
*
|
||||
* Returns the phy driver, after getting a refcount to it; or
|
||||
* -ENODEV if there is no such phy. The caller is responsible for
|
||||
* calling usb_put_phy() to release that count.
|
||||
*
|
||||
* For use by USB host and peripheral drivers.
|
||||
*/
|
||||
struct usb_phy *usb_get_phy_dev(struct device *dev, u8 index)
|
||||
{
|
||||
struct usb_phy *phy = NULL;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&phy_lock, flags);
|
||||
|
||||
phy = __usb_find_phy_dev(dev, &phy_bind_list, index);
|
||||
if (IS_ERR(phy) || !try_module_get(phy->dev->driver->owner)) {
|
||||
dev_dbg(dev, "unable to find transceiver\n");
|
||||
if (!IS_ERR(phy))
|
||||
phy = ERR_PTR(-ENODEV);
|
||||
|
||||
goto err0;
|
||||
}
|
||||
|
||||
get_device(phy->dev);
|
||||
|
||||
err0:
|
||||
spin_unlock_irqrestore(&phy_lock, flags);
|
||||
|
||||
return phy;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(usb_get_phy_dev);
|
||||
|
||||
/**
|
||||
* devm_usb_get_phy_dev - find the USB PHY using device ptr and index
|
||||
* @dev - device that requests this phy
|
||||
* @index - the index of the phy
|
||||
*
|
||||
* Gets the phy using usb_get_phy_dev(), and associates a device with it using
|
||||
* devres. On driver detach, release function is invoked on the devres data,
|
||||
* then, devres data is freed.
|
||||
*
|
||||
* For use by USB host and peripheral drivers.
|
||||
*/
|
||||
struct usb_phy *devm_usb_get_phy_dev(struct device *dev, u8 index)
|
||||
{
|
||||
struct usb_phy **ptr, *phy;
|
||||
|
||||
ptr = devres_alloc(devm_usb_phy_release, sizeof(*ptr), GFP_KERNEL);
|
||||
if (!ptr)
|
||||
return NULL;
|
||||
|
||||
phy = usb_get_phy_dev(dev, index);
|
||||
if (!IS_ERR(phy)) {
|
||||
*ptr = phy;
|
||||
devres_add(dev, ptr);
|
||||
} else
|
||||
devres_free(ptr);
|
||||
|
||||
return phy;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_usb_get_phy_dev);
|
||||
|
||||
/**
|
||||
* devm_usb_put_phy - release the USB PHY
|
||||
* @dev - device that wants to release this phy
|
||||
@ -745,7 +660,6 @@ EXPORT_SYMBOL_GPL(usb_add_phy);
|
||||
*/
|
||||
int usb_add_phy_dev(struct usb_phy *x)
|
||||
{
|
||||
struct usb_phy_bind *phy_bind;
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
@ -762,13 +676,9 @@ int usb_add_phy_dev(struct usb_phy *x)
|
||||
ATOMIC_INIT_NOTIFIER_HEAD(&x->notifier);
|
||||
|
||||
spin_lock_irqsave(&phy_lock, flags);
|
||||
list_for_each_entry(phy_bind, &phy_bind_list, list)
|
||||
if (!(strcmp(phy_bind->phy_dev_name, dev_name(x->dev))))
|
||||
phy_bind->phy = x;
|
||||
|
||||
list_add_tail(&x->head, &phy_list);
|
||||
|
||||
spin_unlock_irqrestore(&phy_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(usb_add_phy_dev);
|
||||
@ -782,53 +692,14 @@ EXPORT_SYMBOL_GPL(usb_add_phy_dev);
|
||||
void usb_remove_phy(struct usb_phy *x)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct usb_phy_bind *phy_bind;
|
||||
|
||||
spin_lock_irqsave(&phy_lock, flags);
|
||||
if (x) {
|
||||
list_for_each_entry(phy_bind, &phy_bind_list, list)
|
||||
if (phy_bind->phy == x)
|
||||
phy_bind->phy = NULL;
|
||||
if (x)
|
||||
list_del(&x->head);
|
||||
}
|
||||
spin_unlock_irqrestore(&phy_lock, flags);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(usb_remove_phy);
|
||||
|
||||
/**
|
||||
* usb_bind_phy - bind the phy and the controller that uses the phy
|
||||
* @dev_name: the device name of the device that will bind to the phy
|
||||
* @index: index to specify the port number
|
||||
* @phy_dev_name: the device name of the phy
|
||||
*
|
||||
* Fills the phy_bind structure with the dev_name and phy_dev_name. This will
|
||||
* be used when the phy driver registers the phy and when the controller
|
||||
* requests this phy.
|
||||
*
|
||||
* To be used by platform specific initialization code.
|
||||
*/
|
||||
int usb_bind_phy(const char *dev_name, u8 index,
|
||||
const char *phy_dev_name)
|
||||
{
|
||||
struct usb_phy_bind *phy_bind;
|
||||
unsigned long flags;
|
||||
|
||||
phy_bind = kzalloc(sizeof(*phy_bind), GFP_KERNEL);
|
||||
if (!phy_bind)
|
||||
return -ENOMEM;
|
||||
|
||||
phy_bind->dev_name = dev_name;
|
||||
phy_bind->phy_dev_name = phy_dev_name;
|
||||
phy_bind->index = index;
|
||||
|
||||
spin_lock_irqsave(&phy_lock, flags);
|
||||
list_add_tail(&phy_bind->list, &phy_bind_list);
|
||||
spin_unlock_irqrestore(&phy_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(usb_bind_phy);
|
||||
|
||||
/**
|
||||
* usb_phy_set_event - set event to phy event
|
||||
* @x: the phy returned by usb_get_phy();
|
||||
|
@ -276,7 +276,6 @@ struct usbhs_priv {
|
||||
*/
|
||||
struct usbhs_fifo_info fifo_info;
|
||||
|
||||
struct usb_phy *usb_phy;
|
||||
struct phy *phy;
|
||||
};
|
||||
|
||||
|
@ -8,7 +8,6 @@
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/phy/phy.h>
|
||||
#include <linux/usb/phy.h>
|
||||
#include "common.h"
|
||||
#include "rcar2.h"
|
||||
|
||||
@ -26,16 +25,6 @@ static int usbhs_rcar2_hardware_init(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_USB_PHY)) {
|
||||
struct usb_phy *usb_phy = usb_get_phy_dev(&pdev->dev, 0);
|
||||
|
||||
if (IS_ERR(usb_phy))
|
||||
return PTR_ERR(usb_phy);
|
||||
|
||||
priv->usb_phy = usb_phy;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
@ -48,11 +37,6 @@ static int usbhs_rcar2_hardware_exit(struct platform_device *pdev)
|
||||
priv->phy = NULL;
|
||||
}
|
||||
|
||||
if (priv->usb_phy) {
|
||||
usb_put_phy(priv->usb_phy);
|
||||
priv->usb_phy = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -75,19 +59,6 @@ static int usbhs_rcar2_power_ctrl(struct platform_device *pdev,
|
||||
}
|
||||
}
|
||||
|
||||
if (priv->usb_phy) {
|
||||
if (enable) {
|
||||
retval = usb_phy_init(priv->usb_phy);
|
||||
|
||||
if (!retval)
|
||||
retval = usb_phy_set_suspend(priv->usb_phy, 0);
|
||||
} else {
|
||||
usb_phy_set_suspend(priv->usb_phy, 1);
|
||||
usb_phy_shutdown(priv->usb_phy);
|
||||
retval = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -144,6 +144,8 @@ static int intel_xhci_usb_probe(struct platform_device *pdev)
|
||||
return -ENOMEM;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res)
|
||||
return -EINVAL;
|
||||
data->base = devm_ioremap_nocache(dev, res->start, resource_size(res));
|
||||
if (!data->base)
|
||||
return -ENOMEM;
|
||||
|
@ -464,7 +464,7 @@ static int init_freecom(struct us_data *us)
|
||||
usb_stor_dbg(us, "result from activate reset is %d\n", result);
|
||||
|
||||
/* wait 250ms */
|
||||
mdelay(250);
|
||||
msleep(250);
|
||||
|
||||
/* clear reset */
|
||||
result = usb_stor_control_msg(us, us->send_ctrl_pipe,
|
||||
@ -472,7 +472,7 @@ static int init_freecom(struct us_data *us)
|
||||
usb_stor_dbg(us, "result from clear reset is %d\n", result);
|
||||
|
||||
/* wait 3 seconds */
|
||||
mdelay(3 * 1000);
|
||||
msleep(3 * 1000);
|
||||
|
||||
return USB_STOR_TRANSPORT_GOOD;
|
||||
}
|
||||
|
@ -49,6 +49,7 @@ config TYPEC_TCPM
|
||||
tristate "USB Type-C Port Controller Manager"
|
||||
depends on USB
|
||||
select USB_ROLE_SWITCH
|
||||
select POWER_SUPPLY
|
||||
help
|
||||
The Type-C Port Controller Manager provides a USB PD and USB Type-C
|
||||
state machine for use with Type-C Port Controllers.
|
||||
|
@ -1,6 +1,6 @@
|
||||
config TYPEC_FUSB302
|
||||
tristate "Fairchild FUSB302 Type-C chip driver"
|
||||
depends on I2C && POWER_SUPPLY
|
||||
depends on I2C
|
||||
help
|
||||
The Fairchild FUSB302 Type-C chip driver that works with
|
||||
Type-C Port Controller Manager to provide USB PD and USB
|
||||
|
@ -18,7 +18,6 @@
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
#include <linux/power_supply.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/sched/clock.h>
|
||||
@ -99,11 +98,6 @@ struct fusb302_chip {
|
||||
/* lock for sharing chip states */
|
||||
struct mutex lock;
|
||||
|
||||
/* psy + psy status */
|
||||
struct power_supply *psy;
|
||||
u32 current_limit;
|
||||
u32 supply_voltage;
|
||||
|
||||
/* chip status */
|
||||
enum toggling_mode toggling_mode;
|
||||
enum src_current_status src_current_status;
|
||||
@ -120,6 +114,7 @@ struct fusb302_chip {
|
||||
enum typec_cc_polarity cc_polarity;
|
||||
enum typec_cc_status cc1;
|
||||
enum typec_cc_status cc2;
|
||||
u32 snk_pdo[PDO_MAX_OBJECTS];
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
struct dentry *dentry;
|
||||
@ -861,13 +856,11 @@ static int tcpm_set_vbus(struct tcpc_dev *dev, bool on, bool charge)
|
||||
chip->vbus_on = on;
|
||||
fusb302_log(chip, "vbus := %s", on ? "On" : "Off");
|
||||
}
|
||||
if (chip->charge_on == charge) {
|
||||
if (chip->charge_on == charge)
|
||||
fusb302_log(chip, "charge is already %s",
|
||||
charge ? "On" : "Off");
|
||||
} else {
|
||||
else
|
||||
chip->charge_on = charge;
|
||||
power_supply_changed(chip->psy);
|
||||
}
|
||||
|
||||
done:
|
||||
mutex_unlock(&chip->lock);
|
||||
@ -883,11 +876,6 @@ static int tcpm_set_current_limit(struct tcpc_dev *dev, u32 max_ma, u32 mv)
|
||||
fusb302_log(chip, "current limit: %d ma, %d mv (not implemented)",
|
||||
max_ma, mv);
|
||||
|
||||
chip->supply_voltage = mv;
|
||||
chip->current_limit = max_ma;
|
||||
|
||||
power_supply_changed(chip->psy);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1212,11 +1200,6 @@ static const u32 snk_pdo[] = {
|
||||
static const struct tcpc_config fusb302_tcpc_config = {
|
||||
.src_pdo = src_pdo,
|
||||
.nr_src_pdo = ARRAY_SIZE(src_pdo),
|
||||
.snk_pdo = snk_pdo,
|
||||
.nr_snk_pdo = ARRAY_SIZE(snk_pdo),
|
||||
.max_snk_mv = 5000,
|
||||
.max_snk_ma = 3000,
|
||||
.max_snk_mw = 15000,
|
||||
.operating_snk_mw = 2500,
|
||||
.type = TYPEC_PORT_DRP,
|
||||
.data = TYPEC_PORT_DRD,
|
||||
@ -1686,43 +1669,6 @@ static irqreturn_t fusb302_irq_intn(int irq, void *dev_id)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int fusb302_psy_get_property(struct power_supply *psy,
|
||||
enum power_supply_property psp,
|
||||
union power_supply_propval *val)
|
||||
{
|
||||
struct fusb302_chip *chip = power_supply_get_drvdata(psy);
|
||||
|
||||
switch (psp) {
|
||||
case POWER_SUPPLY_PROP_ONLINE:
|
||||
val->intval = chip->charge_on;
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_VOLTAGE_NOW:
|
||||
val->intval = chip->supply_voltage * 1000; /* mV -> µV */
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_CURRENT_MAX:
|
||||
val->intval = chip->current_limit * 1000; /* mA -> µA */
|
||||
break;
|
||||
default:
|
||||
return -ENODATA;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static enum power_supply_property fusb302_psy_properties[] = {
|
||||
POWER_SUPPLY_PROP_ONLINE,
|
||||
POWER_SUPPLY_PROP_VOLTAGE_NOW,
|
||||
POWER_SUPPLY_PROP_CURRENT_MAX,
|
||||
};
|
||||
|
||||
static const struct power_supply_desc fusb302_psy_desc = {
|
||||
.name = "fusb302-typec-source",
|
||||
.type = POWER_SUPPLY_TYPE_USB_TYPE_C,
|
||||
.properties = fusb302_psy_properties,
|
||||
.num_properties = ARRAY_SIZE(fusb302_psy_properties),
|
||||
.get_property = fusb302_psy_get_property,
|
||||
};
|
||||
|
||||
static int init_gpio(struct fusb302_chip *chip)
|
||||
{
|
||||
struct device_node *node;
|
||||
@ -1756,13 +1702,35 @@ static int init_gpio(struct fusb302_chip *chip)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fusb302_composite_snk_pdo_array(struct fusb302_chip *chip)
|
||||
{
|
||||
struct device *dev = chip->dev;
|
||||
u32 max_uv, max_ua;
|
||||
|
||||
chip->snk_pdo[0] = PDO_FIXED(5000, 400, PDO_FIXED_FLAGS);
|
||||
|
||||
/*
|
||||
* As max_snk_ma/mv/mw is not needed for tcpc_config,
|
||||
* those settings should be passed in via sink PDO, so
|
||||
* "fcs, max-sink-*" properties will be deprecated, to
|
||||
* perserve compatibility with existing users of them,
|
||||
* we read those properties to convert them to be a var
|
||||
* PDO.
|
||||
*/
|
||||
if (device_property_read_u32(dev, "fcs,max-sink-microvolt", &max_uv) ||
|
||||
device_property_read_u32(dev, "fcs,max-sink-microamp", &max_ua))
|
||||
return 1;
|
||||
|
||||
chip->snk_pdo[1] = PDO_VAR(5000, max_uv / 1000, max_ua / 1000);
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int fusb302_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct fusb302_chip *chip;
|
||||
struct i2c_adapter *adapter;
|
||||
struct device *dev = &client->dev;
|
||||
struct power_supply_config cfg = {};
|
||||
const char *name;
|
||||
int ret = 0;
|
||||
u32 v;
|
||||
@ -1784,18 +1752,13 @@ static int fusb302_probe(struct i2c_client *client,
|
||||
chip->tcpc_dev.config = &chip->tcpc_config;
|
||||
mutex_init(&chip->lock);
|
||||
|
||||
if (!device_property_read_u32(dev, "fcs,max-sink-microvolt", &v))
|
||||
chip->tcpc_config.max_snk_mv = v / 1000;
|
||||
|
||||
if (!device_property_read_u32(dev, "fcs,max-sink-microamp", &v))
|
||||
chip->tcpc_config.max_snk_ma = v / 1000;
|
||||
|
||||
if (!device_property_read_u32(dev, "fcs,max-sink-microwatt", &v))
|
||||
chip->tcpc_config.max_snk_mw = v / 1000;
|
||||
|
||||
if (!device_property_read_u32(dev, "fcs,operating-sink-microwatt", &v))
|
||||
chip->tcpc_config.operating_snk_mw = v / 1000;
|
||||
|
||||
/* Composite sink PDO */
|
||||
chip->tcpc_config.nr_snk_pdo = fusb302_composite_snk_pdo_array(chip);
|
||||
chip->tcpc_config.snk_pdo = chip->snk_pdo;
|
||||
|
||||
/*
|
||||
* Devicetree platforms should get extcon via phandle (not yet
|
||||
* supported). On ACPI platforms, we get the name from a device prop.
|
||||
@ -1809,14 +1772,6 @@ static int fusb302_probe(struct i2c_client *client,
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
|
||||
cfg.drv_data = chip;
|
||||
chip->psy = devm_power_supply_register(dev, &fusb302_psy_desc, &cfg);
|
||||
if (IS_ERR(chip->psy)) {
|
||||
ret = PTR_ERR(chip->psy);
|
||||
dev_err(chip->dev, "Error registering power-supply: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = fusb302_debugfs_init(chip);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -558,6 +558,7 @@ static const u32 src_pdo[] = {
|
||||
static const u32 snk_pdo[] = {
|
||||
PDO_FIXED(5000, 500, PDO_FIXED_DUAL_ROLE | PDO_FIXED_DATA_SWAP |
|
||||
PDO_FIXED_USB_COMM),
|
||||
PDO_VAR(5000, 12000, 3000),
|
||||
};
|
||||
|
||||
static struct tcpc_config wcove_typec_config = {
|
||||
@ -566,9 +567,6 @@ static struct tcpc_config wcove_typec_config = {
|
||||
.snk_pdo = snk_pdo,
|
||||
.nr_snk_pdo = ARRAY_SIZE(snk_pdo),
|
||||
|
||||
.max_snk_mv = 12000,
|
||||
.max_snk_ma = 3000,
|
||||
.max_snk_mw = 36000,
|
||||
.operating_snk_mw = 15000,
|
||||
|
||||
.type = TYPEC_PORT_DRP,
|
||||
|
@ -302,7 +302,7 @@ static int stub_probe(struct usb_device *udev)
|
||||
struct bus_id_priv *busid_priv;
|
||||
int rc;
|
||||
|
||||
dev_dbg(&udev->dev, "Enter\n");
|
||||
dev_dbg(&udev->dev, "Enter probe\n");
|
||||
|
||||
/* check we should claim or not by busid_table */
|
||||
busid_priv = get_busid_priv(udev_busid);
|
||||
@ -404,7 +404,7 @@ static void stub_disconnect(struct usb_device *udev)
|
||||
struct bus_id_priv *busid_priv;
|
||||
int rc;
|
||||
|
||||
dev_dbg(&udev->dev, "Enter\n");
|
||||
dev_dbg(&udev->dev, "Enter disconnect\n");
|
||||
|
||||
busid_priv = get_busid_priv(udev_busid);
|
||||
if (!busid_priv) {
|
||||
|
@ -145,6 +145,7 @@ enum power_supply_property {
|
||||
POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,
|
||||
POWER_SUPPLY_PROP_TIME_TO_FULL_AVG,
|
||||
POWER_SUPPLY_PROP_TYPE, /* use power_supply.type instead */
|
||||
POWER_SUPPLY_PROP_USB_TYPE,
|
||||
POWER_SUPPLY_PROP_SCOPE,
|
||||
POWER_SUPPLY_PROP_PRECHARGE_CURRENT,
|
||||
POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT,
|
||||
@ -170,6 +171,19 @@ enum power_supply_type {
|
||||
POWER_SUPPLY_TYPE_APPLE_BRICK_ID, /* Apple Charging Method */
|
||||
};
|
||||
|
||||
enum power_supply_usb_type {
|
||||
POWER_SUPPLY_USB_TYPE_UNKNOWN = 0,
|
||||
POWER_SUPPLY_USB_TYPE_SDP, /* Standard Downstream Port */
|
||||
POWER_SUPPLY_USB_TYPE_DCP, /* Dedicated Charging Port */
|
||||
POWER_SUPPLY_USB_TYPE_CDP, /* Charging Downstream Port */
|
||||
POWER_SUPPLY_USB_TYPE_ACA, /* Accessory Charger Adapters */
|
||||
POWER_SUPPLY_USB_TYPE_C, /* Type C Port */
|
||||
POWER_SUPPLY_USB_TYPE_PD, /* Power Delivery Port */
|
||||
POWER_SUPPLY_USB_TYPE_PD_DRP, /* PD Dual Role Port */
|
||||
POWER_SUPPLY_USB_TYPE_PD_PPS, /* PD Programmable Power Supply */
|
||||
POWER_SUPPLY_USB_TYPE_APPLE_BRICK_ID, /* Apple Charging Method */
|
||||
};
|
||||
|
||||
enum power_supply_notifier_events {
|
||||
PSY_EVENT_PROP_CHANGED,
|
||||
};
|
||||
@ -196,6 +210,8 @@ struct power_supply_config {
|
||||
struct power_supply_desc {
|
||||
const char *name;
|
||||
enum power_supply_type type;
|
||||
enum power_supply_usb_type *usb_types;
|
||||
size_t num_usb_types;
|
||||
enum power_supply_property *properties;
|
||||
size_t num_properties;
|
||||
|
||||
|
@ -551,6 +551,8 @@ struct usb3_lpm_parameters {
|
||||
* @route: tree topology hex string for use with xHCI
|
||||
* @state: device state: configured, not attached, etc.
|
||||
* @speed: device speed: high/full/low (or error)
|
||||
* @rx_lanes: number of rx lanes in use, USB 3.2 adds dual-lane support
|
||||
* @tx_lanes: number of tx lanes in use, USB 3.2 adds dual-lane support
|
||||
* @tt: Transaction Translator info; used with low/full speed dev, highspeed hub
|
||||
* @ttport: device port on that tt hub
|
||||
* @toggle: one bit for each endpoint, with ([0] = IN, [1] = OUT) endpoints
|
||||
@ -624,6 +626,8 @@ struct usb_device {
|
||||
u32 route;
|
||||
enum usb_device_state state;
|
||||
enum usb_device_speed speed;
|
||||
unsigned int rx_lanes;
|
||||
unsigned int tx_lanes;
|
||||
|
||||
struct usb_tt *tt;
|
||||
int ttport;
|
||||
|
@ -94,7 +94,7 @@ struct uac_clock_selector_descriptor {
|
||||
__u8 bClockID;
|
||||
__u8 bNrInPins;
|
||||
__u8 baCSourceID[];
|
||||
/* bmControls, bAssocTerminal and iClockSource omitted */
|
||||
/* bmControls and iClockSource omitted */
|
||||
} __attribute__((packed));
|
||||
|
||||
/* 4.7.2.3 Clock Multiplier Descriptor */
|
||||
|
@ -150,7 +150,6 @@ struct usb_hcd {
|
||||
unsigned rh_pollable:1; /* may we poll the root hub? */
|
||||
unsigned msix_enabled:1; /* driver has MSI-X enabled? */
|
||||
unsigned msi_enabled:1; /* driver has MSI enabled? */
|
||||
unsigned remove_phy:1; /* auto-remove USB phy */
|
||||
/*
|
||||
* do not manage the PHY state in the HCD core, instead let the driver
|
||||
* handle this (for example if the PHY can only be turned on after a
|
||||
@ -261,6 +260,7 @@ struct hc_driver {
|
||||
#define HCD_USB25 0x0030 /* Wireless USB 1.0 (USB 2.5)*/
|
||||
#define HCD_USB3 0x0040 /* USB 3.0 */
|
||||
#define HCD_USB31 0x0050 /* USB 3.1 */
|
||||
#define HCD_USB32 0x0060 /* USB 3.2 */
|
||||
#define HCD_MASK 0x0070
|
||||
#define HCD_BH 0x0100 /* URB complete in BH context */
|
||||
|
||||
|
@ -103,8 +103,8 @@ enum pd_ext_msg_type {
|
||||
(((cnt) & PD_HEADER_CNT_MASK) << PD_HEADER_CNT_SHIFT) | \
|
||||
((ext_hdr) ? PD_HEADER_EXT_HDR : 0))
|
||||
|
||||
#define PD_HEADER_LE(type, pwr, data, id, cnt) \
|
||||
cpu_to_le16(PD_HEADER((type), (pwr), (data), PD_REV20, (id), (cnt), (0)))
|
||||
#define PD_HEADER_LE(type, pwr, data, rev, id, cnt) \
|
||||
cpu_to_le16(PD_HEADER((type), (pwr), (data), (rev), (id), (cnt), (0)))
|
||||
|
||||
static inline unsigned int pd_header_cnt(u16 header)
|
||||
{
|
||||
|
@ -157,22 +157,6 @@ struct usb_phy {
|
||||
enum usb_charger_type (*charger_detect)(struct usb_phy *x);
|
||||
};
|
||||
|
||||
/**
|
||||
* struct usb_phy_bind - represent the binding for the phy
|
||||
* @dev_name: the device name of the device that will bind to the phy
|
||||
* @phy_dev_name: the device name of the phy
|
||||
* @index: used if a single controller uses multiple phys
|
||||
* @phy: reference to the phy
|
||||
* @list: to maintain a linked list of the binding information
|
||||
*/
|
||||
struct usb_phy_bind {
|
||||
const char *dev_name;
|
||||
const char *phy_dev_name;
|
||||
u8 index;
|
||||
struct usb_phy *phy;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
/* for board-specific init logic */
|
||||
extern int usb_add_phy(struct usb_phy *, enum usb_phy_type type);
|
||||
extern int usb_add_phy_dev(struct usb_phy *);
|
||||
@ -234,16 +218,12 @@ usb_phy_vbus_off(struct usb_phy *x)
|
||||
extern struct usb_phy *usb_get_phy(enum usb_phy_type type);
|
||||
extern struct usb_phy *devm_usb_get_phy(struct device *dev,
|
||||
enum usb_phy_type type);
|
||||
extern struct usb_phy *usb_get_phy_dev(struct device *dev, u8 index);
|
||||
extern struct usb_phy *devm_usb_get_phy_dev(struct device *dev, u8 index);
|
||||
extern struct usb_phy *devm_usb_get_phy_by_phandle(struct device *dev,
|
||||
const char *phandle, u8 index);
|
||||
extern struct usb_phy *devm_usb_get_phy_by_node(struct device *dev,
|
||||
struct device_node *node, struct notifier_block *nb);
|
||||
extern void usb_put_phy(struct usb_phy *);
|
||||
extern void devm_usb_put_phy(struct device *dev, struct usb_phy *x);
|
||||
extern int usb_bind_phy(const char *dev_name, u8 index,
|
||||
const char *phy_dev_name);
|
||||
extern void usb_phy_set_event(struct usb_phy *x, unsigned long event);
|
||||
extern void usb_phy_set_charger_current(struct usb_phy *usb_phy,
|
||||
unsigned int mA);
|
||||
@ -263,16 +243,6 @@ static inline struct usb_phy *devm_usb_get_phy(struct device *dev,
|
||||
return ERR_PTR(-ENXIO);
|
||||
}
|
||||
|
||||
static inline struct usb_phy *usb_get_phy_dev(struct device *dev, u8 index)
|
||||
{
|
||||
return ERR_PTR(-ENXIO);
|
||||
}
|
||||
|
||||
static inline struct usb_phy *devm_usb_get_phy_dev(struct device *dev, u8 index)
|
||||
{
|
||||
return ERR_PTR(-ENXIO);
|
||||
}
|
||||
|
||||
static inline struct usb_phy *devm_usb_get_phy_by_phandle(struct device *dev,
|
||||
const char *phandle, u8 index)
|
||||
{
|
||||
@ -293,12 +263,6 @@ static inline void devm_usb_put_phy(struct device *dev, struct usb_phy *x)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int usb_bind_phy(const char *dev_name, u8 index,
|
||||
const char *phy_dev_name)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline void usb_phy_set_event(struct usb_phy *x, unsigned long event)
|
||||
{
|
||||
}
|
||||
|
@ -36,6 +36,7 @@ enum typec_cc_polarity {
|
||||
/* Time to wait for TCPC to complete transmit */
|
||||
#define PD_T_TCPC_TX_TIMEOUT 100 /* in ms */
|
||||
#define PD_ROLE_SWAP_TIMEOUT (MSEC_PER_SEC * 10)
|
||||
#define PD_PPS_CTRL_TIMEOUT (MSEC_PER_SEC * 10)
|
||||
|
||||
enum tcpm_transmit_status {
|
||||
TCPC_TX_SUCCESS = 0,
|
||||
@ -62,9 +63,6 @@ enum tcpm_transmit_type {
|
||||
* @snk_pdo: PDO parameters sent to partner as response to
|
||||
* PD_CTRL_GET_SINK_CAP message
|
||||
* @nr_snk_pdo: Number of entries in @snk_pdo
|
||||
* @max_snk_mv: Maximum acceptable sink voltage in mV
|
||||
* @max_snk_ma: Maximum sink current in mA
|
||||
* @max_snk_mw: Maximum required sink power in mW
|
||||
* @operating_snk_mw:
|
||||
* Required operating sink power in mW
|
||||
* @type: Port type (TYPEC_PORT_DFP, TYPEC_PORT_UFP, or
|
||||
@ -85,9 +83,6 @@ struct tcpc_config {
|
||||
const u32 *snk_vdo;
|
||||
unsigned int nr_snk_vdo;
|
||||
|
||||
unsigned int max_snk_mv;
|
||||
unsigned int max_snk_ma;
|
||||
unsigned int max_snk_mw;
|
||||
unsigned int operating_snk_mw;
|
||||
|
||||
enum typec_port_type type;
|
||||
@ -174,9 +169,6 @@ int tcpm_update_source_capabilities(struct tcpm_port *port, const u32 *pdo,
|
||||
unsigned int nr_pdo);
|
||||
int tcpm_update_sink_capabilities(struct tcpm_port *port, const u32 *pdo,
|
||||
unsigned int nr_pdo,
|
||||
unsigned int max_snk_mv,
|
||||
unsigned int max_snk_ma,
|
||||
unsigned int max_snk_mw,
|
||||
unsigned int operating_snk_mw);
|
||||
|
||||
void tcpm_vbus_change(struct tcpm_port *port);
|
||||
|
@ -17,6 +17,7 @@
|
||||
#define __TEGRA_USB_PHY_H
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/reset.h>
|
||||
#include <linux/usb/otg.h>
|
||||
|
||||
/*
|
||||
@ -76,6 +77,7 @@ struct tegra_usb_phy {
|
||||
bool is_legacy_phy;
|
||||
bool is_ulpi_phy;
|
||||
int reset_gpio;
|
||||
struct reset_control *pad_rst;
|
||||
};
|
||||
|
||||
void tegra_usb_phy_preresume(struct usb_phy *phy);
|
||||
|
@ -197,6 +197,11 @@ struct usb_port_status {
|
||||
#define USB_EXT_PORT_STAT_RX_LANES 0x00000f00
|
||||
#define USB_EXT_PORT_STAT_TX_LANES 0x0000f000
|
||||
|
||||
#define USB_EXT_PORT_RX_LANES(p) \
|
||||
(((p) & USB_EXT_PORT_STAT_RX_LANES) >> 8)
|
||||
#define USB_EXT_PORT_TX_LANES(p) \
|
||||
(((p) & USB_EXT_PORT_STAT_TX_LANES) >> 12)
|
||||
|
||||
/*
|
||||
* wHubCharacteristics (masks)
|
||||
* See USB 2.0 spec Table 11-13, offset 3
|
||||
|
Loading…
Reference in New Issue
Block a user