{
        struct snd_soc_component *component = dai->component;
        struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
-       u8 dai_bclks_per_wclk;
-       __le16 offset;
+       unsigned int ch_mask;
+       u8 dai_bclks_per_wclk, slot_offset;
+       u16 offset;
+       __le16 dai_offset;
        u32 frame_size;
 
        /* No channels enabled so disable TDM */
        }
 
        /* Check we have valid slots */
-       if (fls(tx_mask) > DA7219_DAI_TDM_MAX_SLOTS) {
-               dev_err(component->dev, "Invalid number of slots, max = %d\n",
+       slot_offset = ffs(tx_mask) - 1;
+       ch_mask = (tx_mask >> slot_offset);
+       if (fls(ch_mask) > DA7219_DAI_TDM_MAX_SLOTS) {
+               dev_err(component->dev,
+                       "Invalid number of slots, max = %d\n",
                        DA7219_DAI_TDM_MAX_SLOTS);
                return -EINVAL;
        }
 
-       /* Check we have a valid offset given */
-       if (rx_mask > DA7219_DAI_OFFSET_MAX) {
-               dev_err(component->dev, "Invalid slot offset, max = %d\n",
-                       DA7219_DAI_OFFSET_MAX);
+       /*
+        * Ensure we have a valid offset into the frame, based on slot width
+        * and slot offset of first slot we're interested in.
+        */
+       offset = slot_offset * slot_width;
+       if (offset > DA7219_DAI_OFFSET_MAX) {
+               dev_err(component->dev, "Invalid frame offset %d\n", offset);
                return -EINVAL;
        }
 
-       /* Calculate & validate frame size based on slot info provided. */
-       frame_size = slots * slot_width;
-       switch (frame_size) {
-       case 32:
-               dai_bclks_per_wclk = DA7219_DAI_BCLKS_PER_WCLK_32;
-               break;
-       case 64:
-               dai_bclks_per_wclk = DA7219_DAI_BCLKS_PER_WCLK_64;
-               break;
-       case 128:
-               dai_bclks_per_wclk = DA7219_DAI_BCLKS_PER_WCLK_128;
-               break;
-       case 256:
-               dai_bclks_per_wclk = DA7219_DAI_BCLKS_PER_WCLK_256;
-               break;
-       default:
-               dev_err(component->dev, "Invalid frame size %d\n", frame_size);
-               return -EINVAL;
-       }
+       /*
+        * If we're master, calculate & validate frame size based on slot info
+        * provided as we have a limited set of rates available.
+        */
+       if (da7219->master) {
+               frame_size = slots * slot_width;
+               switch (frame_size) {
+               case 32:
+                       dai_bclks_per_wclk = DA7219_DAI_BCLKS_PER_WCLK_32;
+                       break;
+               case 64:
+                       dai_bclks_per_wclk = DA7219_DAI_BCLKS_PER_WCLK_64;
+                       break;
+               case 128:
+                       dai_bclks_per_wclk = DA7219_DAI_BCLKS_PER_WCLK_128;
+                       break;
+               case 256:
+                       dai_bclks_per_wclk = DA7219_DAI_BCLKS_PER_WCLK_256;
+                       break;
+               default:
+                       dev_err(component->dev, "Invalid frame size %d\n",
+                               frame_size);
+                       return -EINVAL;
+               }
 
-       snd_soc_component_update_bits(component, DA7219_DAI_CLK_MODE,
-                           DA7219_DAI_BCLKS_PER_WCLK_MASK,
-                           dai_bclks_per_wclk);
+               snd_soc_component_update_bits(component, DA7219_DAI_CLK_MODE,
+                               DA7219_DAI_BCLKS_PER_WCLK_MASK,
+                               dai_bclks_per_wclk);
+       }
 
-       offset = cpu_to_le16(rx_mask);
+       dai_offset = cpu_to_le16(offset);
        regmap_bulk_write(da7219->regmap, DA7219_DAI_OFFSET_LOWER,
-                         &offset, sizeof(offset));
+                         &dai_offset, sizeof(dai_offset));
 
        snd_soc_component_update_bits(component, DA7219_DAI_TDM_CTRL,
                            DA7219_DAI_TDM_CH_EN_MASK |
                            DA7219_DAI_TDM_MODE_EN_MASK,
-                           (tx_mask << DA7219_DAI_TDM_CH_EN_SHIFT) |
+                           (ch_mask << DA7219_DAI_TDM_CH_EN_SHIFT) |
                            DA7219_DAI_TDM_MODE_EN_MASK);
 
        da7219->tdm_en = true;