99#include "atc.h"
1010#include "trace.h"
1111
12+ #include <asm-generic/errno.h>
1213#include <dt-bindings/phy/phy.h>
1314#include <linux/bitfield.h>
1415#include <linux/delay.h>
@@ -1776,12 +1777,55 @@ static const struct phy_ops apple_atc_usb2_phy_ops = {
17761777 .exit = atcphy_usb2_power_off ,
17771778};
17781779
1780+ static int atcphy_dpphy_mux_set (struct apple_atcphy * atcphy , enum atcphy_mode target )
1781+ {
1782+ int ret = 0 ;
1783+
1784+ // TODO:
1785+ flush_work (& atcphy -> mux_set_work );
1786+
1787+ mutex_lock (& atcphy -> lock );
1788+
1789+ if (atcphy -> mode == target )
1790+ goto out_unlock ;
1791+
1792+ atcphy -> target_mode = target ;
1793+
1794+ WARN_ON (!schedule_work (& atcphy -> mux_set_work ));
1795+ ret = wait_for_completion_timeout (& atcphy -> atcphy_online_event ,
1796+ msecs_to_jiffies (1000 ));
1797+ if (ret == 0 )
1798+ ret = - ETIMEDOUT ;
1799+ else if (ret > 0 )
1800+ ret = 0 ;
1801+
1802+ out_unlock :
1803+ mutex_unlock (& atcphy -> lock );
1804+ return ret ;
1805+ }
1806+
17791807static int atcphy_dpphy_set_mode (struct phy * phy , enum phy_mode mode ,
17801808 int submode )
17811809{
1782- /* nothing to do here since the setup already happened in mux_set */
1783- if (mode == PHY_MODE_DP && submode >= 0 && submode <= 5 )
1784- return 0 ;
1810+ struct apple_atcphy * atcphy = phy_get_drvdata (phy );
1811+
1812+ dev_info (atcphy -> dev , "%s(mode=%u, submode=%d)\n" , __func__ , mode , submode );
1813+
1814+ switch (mode ) {
1815+ case PHY_MODE_INVALID :
1816+ if (atcphy -> mode == APPLE_ATCPHY_MODE_OFF )
1817+ return 0 ;
1818+ return atcphy_dpphy_mux_set (atcphy , APPLE_ATCPHY_MODE_OFF );
1819+ case PHY_MODE_DP :
1820+ /* TODO: does this get called for DP-altmode? */
1821+ if (atcphy -> mode == APPLE_ATCPHY_MODE_USB3_DP ||
1822+ atcphy -> mode == APPLE_ATCPHY_MODE_DP )
1823+ return 0 ;
1824+ return atcphy_dpphy_mux_set (atcphy , APPLE_ATCPHY_MODE_DP );
1825+ default :
1826+ break ;
1827+ }
1828+
17851829 return - EINVAL ;
17861830}
17871831
@@ -1791,6 +1835,11 @@ static int atcphy_dpphy_validate(struct phy *phy, enum phy_mode mode,
17911835 struct phy_configure_opts_dp * opts = & opts_ -> dp ;
17921836 struct apple_atcphy * atcphy = phy_get_drvdata (phy );
17931837
1838+ if (mode == PHY_MODE_INVALID ) {
1839+ memset (opts , 0 , sizeof (* opts ));
1840+ return 0 ;
1841+ }
1842+
17941843 if (mode != PHY_MODE_DP )
17951844 return - EINVAL ;
17961845 if (submode != 0 )
@@ -1836,9 +1885,9 @@ static int atcphy_dpphy_configure(struct phy *phy,
18361885 if (opts -> set_lanes ) {
18371886 if (((atcphy -> mode == APPLE_ATCPHY_MODE_DP && opts -> lanes != 4 ) ||
18381887 (atcphy -> mode == APPLE_ATCPHY_MODE_USB3_DP && opts -> lanes != 2 )) &&
1839- opts -> lanes != 0 )
1840- dev_warn (atcphy -> dev , "Unexpected lane count %u for mode %u\n" ,
1841- opts -> lanes , atcphy -> mode );
1888+ ( atcphy -> mode == APPLE_ATCPHY_MODE_OFF && opts -> lanes != 0 ) )
1889+ dev_warn (atcphy -> dev , "Unexpected lane count %u for mode %u\n" ,
1890+ opts -> lanes , atcphy -> mode );
18421891
18431892 }
18441893
@@ -2429,13 +2478,6 @@ static int atcphy_probe(struct platform_device *pdev)
24292478 if (ret )
24302479 return ret ;
24312480
2432- if (atcphy -> dp_only ) {
2433- atcphy -> target_mode = APPLE_ATCPHY_MODE_DP ;
2434- WARN_ON (!schedule_work (& atcphy -> mux_set_work ));
2435- wait_for_completion_timeout (& atcphy -> atcphy_online_event ,
2436- msecs_to_jiffies (1000 ));
2437- }
2438-
24392481 return 0 ;
24402482}
24412483
0 commit comments