13
13
#include <linux/pm_runtime.h>
14
14
#include <linux/regmap.h>
15
15
#include <linux/regulator/consumer.h>
16
+ #include <linux/reset.h>
16
17
#include <linux/slab.h>
17
18
#include <linux/soundwire/sdw.h>
18
19
#include <linux/soundwire/sdw_registers.h>
@@ -699,6 +700,7 @@ struct wsa884x_priv {
699
700
struct sdw_stream_runtime * sruntime ;
700
701
struct sdw_port_config port_config [WSA884X_MAX_SWR_PORTS ];
701
702
struct gpio_desc * sd_n ;
703
+ struct reset_control * sd_reset ;
702
704
bool port_prepared [WSA884X_MAX_SWR_PORTS ];
703
705
bool port_enable [WSA884X_MAX_SWR_PORTS ];
704
706
unsigned int variant ;
@@ -1799,16 +1801,50 @@ static struct snd_soc_dai_driver wsa884x_dais[] = {
1799
1801
},
1800
1802
};
1801
1803
1802
- static void wsa884x_gpio_powerdown (void * data )
1804
+ static void wsa884x_reset_powerdown (void * data )
1803
1805
{
1804
- gpiod_direction_output (data , 1 );
1806
+ struct wsa884x_priv * wsa884x = data ;
1807
+
1808
+ if (wsa884x -> sd_reset )
1809
+ reset_control_assert (wsa884x -> sd_reset );
1810
+ else
1811
+ gpiod_direction_output (wsa884x -> sd_n , 1 );
1812
+ }
1813
+
1814
+ static void wsa884x_reset_deassert (struct wsa884x_priv * wsa884x )
1815
+ {
1816
+ if (wsa884x -> sd_reset )
1817
+ reset_control_deassert (wsa884x -> sd_reset );
1818
+ else
1819
+ gpiod_direction_output (wsa884x -> sd_n , 0 );
1805
1820
}
1806
1821
1807
1822
static void wsa884x_regulator_disable (void * data )
1808
1823
{
1809
1824
regulator_bulk_disable (WSA884X_SUPPLIES_NUM , data );
1810
1825
}
1811
1826
1827
+ static int wsa884x_get_reset (struct device * dev , struct wsa884x_priv * wsa884x )
1828
+ {
1829
+ wsa884x -> sd_reset = devm_reset_control_get_optional_shared (dev , NULL );
1830
+ if (IS_ERR (wsa884x -> sd_reset ))
1831
+ return dev_err_probe (dev , PTR_ERR (wsa884x -> sd_reset ),
1832
+ "Failed to get reset\n" );
1833
+ else if (wsa884x -> sd_reset )
1834
+ return 0 ;
1835
+ /*
1836
+ * else: NULL, so use the backwards compatible way for powerdown-gpios,
1837
+ * which does not handle sharing GPIO properly.
1838
+ */
1839
+ wsa884x -> sd_n = devm_gpiod_get_optional (dev , "powerdown" ,
1840
+ GPIOD_OUT_HIGH );
1841
+ if (IS_ERR (wsa884x -> sd_n ))
1842
+ return dev_err_probe (dev , PTR_ERR (wsa884x -> sd_n ),
1843
+ "Shutdown Control GPIO not found\n" );
1844
+
1845
+ return 0 ;
1846
+ }
1847
+
1812
1848
static int wsa884x_probe (struct sdw_slave * pdev ,
1813
1849
const struct sdw_device_id * id )
1814
1850
{
@@ -1838,11 +1874,9 @@ static int wsa884x_probe(struct sdw_slave *pdev,
1838
1874
if (ret )
1839
1875
return ret ;
1840
1876
1841
- wsa884x -> sd_n = devm_gpiod_get_optional (dev , "powerdown" ,
1842
- GPIOD_OUT_HIGH );
1843
- if (IS_ERR (wsa884x -> sd_n ))
1844
- return dev_err_probe (dev , PTR_ERR (wsa884x -> sd_n ),
1845
- "Shutdown Control GPIO not found\n" );
1877
+ ret = wsa884x_get_reset (dev , wsa884x );
1878
+ if (ret )
1879
+ return ret ;
1846
1880
1847
1881
dev_set_drvdata (dev , wsa884x );
1848
1882
wsa884x -> slave = pdev ;
@@ -1858,9 +1892,8 @@ static int wsa884x_probe(struct sdw_slave *pdev,
1858
1892
pdev -> prop .sink_dpn_prop = wsa884x_sink_dpn_prop ;
1859
1893
pdev -> prop .scp_int1_mask = SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY ;
1860
1894
1861
- /* Bring out of reset */
1862
- gpiod_direction_output (wsa884x -> sd_n , 0 );
1863
- ret = devm_add_action_or_reset (dev , wsa884x_gpio_powerdown , wsa884x -> sd_n );
1895
+ wsa884x_reset_deassert (wsa884x );
1896
+ ret = devm_add_action_or_reset (dev , wsa884x_reset_powerdown , wsa884x );
1864
1897
if (ret )
1865
1898
return ret ;
1866
1899
0 commit comments