diff --git a/Documentation/devicetree/bindings/misc/atmel-ssc.txt b/Documentation/devicetree/bindings/misc/atmel-ssc.txt
index f9fb412642fe..89133c5b82cb 100644
--- a/Documentation/devicetree/bindings/misc/atmel-ssc.txt
+++ b/Documentation/devicetree/bindings/misc/atmel-ssc.txt
@@ -24,6 +24,10 @@ Optional properties:
        this parameter to choose where the clock from.
      - By default the clock is from TK pin, if the clock from RK pin, this
        property is needed.
+  - atmel,shared-fs-pin: bool property.
+     - When SSC works in slave mode, by default it gets separate LRCLK signals
+       from RF and TF. This property makes SSC use a single pin for both
+       RX and TX. TF is used unless atmel,clk-from-rk-pin is also present.
   - #sound-dai-cells: Should contain <0>.
      - This property makes the SSC into an automatically registered DAI.
 
diff --git a/drivers/misc/atmel-ssc.c b/drivers/misc/atmel-ssc.c
index ab4144ea1f11..da63eee1cdf5 100644
--- a/drivers/misc/atmel-ssc.c
+++ b/drivers/misc/atmel-ssc.c
@@ -210,6 +210,8 @@ static int ssc_probe(struct platform_device *pdev)
 		struct device_node *np = pdev->dev.of_node;
 		ssc->clk_from_rk_pin =
 			of_property_read_bool(np, "atmel,clk-from-rk-pin");
+		ssc->shared_fs_pin =
+			of_property_read_bool(np, "atmel,shared-fs-pin");
 	}
 
 	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
diff --git a/include/linux/atmel-ssc.h b/include/linux/atmel-ssc.h
index 6091d2abc1eb..46fdff2dfbb0 100644
--- a/include/linux/atmel-ssc.h
+++ b/include/linux/atmel-ssc.h
@@ -21,6 +21,7 @@ struct ssc_device {
 	int			user;
 	int			irq;
 	bool			clk_from_rk_pin;
+	bool			shared_fs_pin;
 	bool			sound_dai;
 };
 
diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c
index cf2cfc345676..6f595a748618 100644
--- a/sound/soc/atmel/atmel_ssc_dai.c
+++ b/sound/soc/atmel/atmel_ssc_dai.c
@@ -471,7 +471,7 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
 	int dir, channels, bits;
 	u32 tfmr, rfmr, tcmr, rcmr;
 	int ret;
-	int fslen, fslen_ext, fs_osync;
+	int fslen, fslen_ext, fs_osync, fs_edge;
 	u32 cmr_div;
 	u32 tcmr_period;
 	u32 rcmr_period;
@@ -567,24 +567,20 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
 	case SND_SOC_DAIFMT_LEFT_J:
 		/* left-justified format */
 		fs_osync = SSC_FSOS_POSITIVE;
+		fs_edge = SSC_START_RISING_TF;
 
-		rcmr =	  SSC_BF(RCMR_STTDLY, 0)
-			| SSC_BF(RCMR_START, SSC_START_RISING_RF);
-
-		tcmr =	  SSC_BF(TCMR_STTDLY, 0)
-			| SSC_BF(TCMR_START, SSC_START_RISING_TF);
+		rcmr =	  SSC_BF(RCMR_STTDLY, 0);
+		tcmr =	  SSC_BF(TCMR_STTDLY, 0);
 
 		break;
 
 	case SND_SOC_DAIFMT_I2S:
 		/* I2S format = left-justified with start bit and inverted LRCLK */
 		fs_osync = SSC_FSOS_NEGATIVE;
+		fs_edge = SSC_START_FALLING_TF;
 
-		rcmr =	  SSC_BF(RCMR_STTDLY, 1)
-			| SSC_BF(RCMR_START, SSC_START_FALLING_RF);
-
-		tcmr =	  SSC_BF(TCMR_STTDLY, 1)
-			| SSC_BF(TCMR_START, SSC_START_FALLING_TF);
+		rcmr =	  SSC_BF(RCMR_STTDLY, 1);
+		tcmr =	  SSC_BF(TCMR_STTDLY, 1);
 
 		break;
 
@@ -597,13 +593,11 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
 		 * the left channel data.
 		 */
 		fs_osync = SSC_FSOS_POSITIVE;
+		fs_edge = SSC_START_RISING_TF;
 		fslen = fslen_ext = 0;
 
-		rcmr =	  SSC_BF(RCMR_STTDLY, 1)
-			| SSC_BF(RCMR_START, SSC_START_RISING_RF);
-
-		tcmr =	  SSC_BF(TCMR_STTDLY, 1)
-			| SSC_BF(TCMR_START, SSC_START_RISING_TF);
+		rcmr =	  SSC_BF(RCMR_STTDLY, 1);
+		tcmr =	  SSC_BF(TCMR_STTDLY, 1);
 
 		break;
 
@@ -613,10 +607,30 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
 		return -EINVAL;
 	}
 
-	if (!atmel_ssc_cfs(ssc_p)) {
+	if (atmel_ssc_cfs(ssc_p)) {
+		/*
+		 * SSC provides LRCLK
+		 *
+		 * Both TF and RF are generated, so use them directly.
+		 */
+		rcmr |=	  SSC_BF(RCMR_START, fs_edge);
+		tcmr |=	  SSC_BF(TCMR_START, fs_edge);
+	} else {
 		fslen = fslen_ext = 0;
 		rcmr_period = tcmr_period = 0;
 		fs_osync = SSC_FSOS_NONE;
+		if (!ssc->shared_fs_pin) {
+			rcmr |=	  SSC_BF(RCMR_START, fs_edge);
+			tcmr |=	  SSC_BF(TCMR_START, fs_edge);
+		} else if (ssc->clk_from_rk_pin) {
+			/* assume RF is to be used when RK is used as BCLK input */
+			/* Note: won't work correctly on SAMA5D2 due to errata */
+			rcmr |=	  SSC_BF(RCMR_START, fs_edge);
+			tcmr |=	  SSC_BF(TCMR_START, SSC_START_RECEIVE);
+		} else {
+			rcmr |=	  SSC_BF(RCMR_START, SSC_START_TRANSMIT);
+			tcmr |=	  SSC_BF(TCMR_START, fs_edge);
+		}
 	}
 
 	if (atmel_ssc_cbs(ssc_p)) {
