~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/soc/fsl/fsl_xcvr.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 // Copyright 2019 NXP
  3 
  4 #include <linux/bitrev.h>
  5 #include <linux/clk.h>
  6 #include <linux/firmware.h>
  7 #include <linux/interrupt.h>
  8 #include <linux/module.h>
  9 #include <linux/of_platform.h>
 10 #include <linux/pm_runtime.h>
 11 #include <linux/regmap.h>
 12 #include <linux/reset.h>
 13 #include <sound/dmaengine_pcm.h>
 14 #include <sound/pcm_iec958.h>
 15 #include <sound/pcm_params.h>
 16 
 17 #include "fsl_xcvr.h"
 18 #include "fsl_utils.h"
 19 #include "imx-pcm.h"
 20 
 21 #define FSL_XCVR_CAPDS_SIZE     256
 22 
 23 enum fsl_xcvr_pll_verison {
 24         PLL_MX8MP,
 25         PLL_MX95,
 26 };
 27 
 28 struct fsl_xcvr_soc_data {
 29         const char *fw_name;
 30         bool spdif_only;
 31         bool use_edma;
 32         bool use_phy;
 33         enum fsl_xcvr_pll_verison pll_ver;
 34 };
 35 
 36 struct fsl_xcvr {
 37         const struct fsl_xcvr_soc_data *soc_data;
 38         struct platform_device *pdev;
 39         struct regmap *regmap;
 40         struct clk *ipg_clk;
 41         struct clk *pll_ipg_clk;
 42         struct clk *phy_clk;
 43         struct clk *spba_clk;
 44         struct clk *pll8k_clk;
 45         struct clk *pll11k_clk;
 46         struct reset_control *reset;
 47         u8 streams;
 48         u32 mode;
 49         u32 arc_mode;
 50         void __iomem *ram_addr;
 51         struct snd_dmaengine_dai_dma_data dma_prms_rx;
 52         struct snd_dmaengine_dai_dma_data dma_prms_tx;
 53         struct snd_aes_iec958 rx_iec958;
 54         struct snd_aes_iec958 tx_iec958;
 55         u8 cap_ds[FSL_XCVR_CAPDS_SIZE];
 56 };
 57 
 58 static const struct fsl_xcvr_pll_conf {
 59         u8 mfi;   /* min=0x18, max=0x38 */
 60         u32 mfn;  /* signed int, 2's compl., min=0x3FFF0000, max=0x00010000 */
 61         u32 mfd;  /* unsigned int */
 62         u32 fout; /* Fout = Fref*(MFI + MFN/MFD), Fref is 24MHz */
 63 } fsl_xcvr_pll_cfg[] = {
 64         { .mfi = 54, .mfn = 1,  .mfd = 6,   .fout = 1300000000, }, /* 1.3 GHz */
 65         { .mfi = 32, .mfn = 96, .mfd = 125, .fout = 786432000, },  /* 8000 Hz */
 66         { .mfi = 30, .mfn = 66, .mfd = 625, .fout = 722534400, },  /* 11025 Hz */
 67         { .mfi = 29, .mfn = 1,  .mfd = 6,   .fout = 700000000, },  /* 700 MHz */
 68 };
 69 
 70 /*
 71  * HDMI2.1 spec defines 6- and 12-channels layout for one bit audio
 72  * stream. Todo: to check how this case can be considered below
 73  */
 74 static const u32 fsl_xcvr_earc_channels[] = { 1, 2, 8, 16, 32, };
 75 static const struct snd_pcm_hw_constraint_list fsl_xcvr_earc_channels_constr = {
 76         .count = ARRAY_SIZE(fsl_xcvr_earc_channels),
 77         .list = fsl_xcvr_earc_channels,
 78 };
 79 
 80 static const u32 fsl_xcvr_earc_rates[] = {
 81         32000, 44100, 48000, 64000, 88200, 96000,
 82         128000, 176400, 192000, 256000, 352800, 384000,
 83         512000, 705600, 768000, 1024000, 1411200, 1536000,
 84 };
 85 static const struct snd_pcm_hw_constraint_list fsl_xcvr_earc_rates_constr = {
 86         .count = ARRAY_SIZE(fsl_xcvr_earc_rates),
 87         .list = fsl_xcvr_earc_rates,
 88 };
 89 
 90 static const u32 fsl_xcvr_spdif_channels[] = { 2, };
 91 static const struct snd_pcm_hw_constraint_list fsl_xcvr_spdif_channels_constr = {
 92         .count = ARRAY_SIZE(fsl_xcvr_spdif_channels),
 93         .list = fsl_xcvr_spdif_channels,
 94 };
 95 
 96 static const u32 fsl_xcvr_spdif_rates[] = {
 97         32000, 44100, 48000, 88200, 96000, 176400, 192000,
 98 };
 99 static const struct snd_pcm_hw_constraint_list fsl_xcvr_spdif_rates_constr = {
100         .count = ARRAY_SIZE(fsl_xcvr_spdif_rates),
101         .list = fsl_xcvr_spdif_rates,
102 };
103 
104 static int fsl_xcvr_arc_mode_put(struct snd_kcontrol *kcontrol,
105                                  struct snd_ctl_elem_value *ucontrol)
106 {
107         struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
108         struct fsl_xcvr *xcvr = snd_soc_dai_get_drvdata(dai);
109         struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
110         unsigned int *item = ucontrol->value.enumerated.item;
111 
112         xcvr->arc_mode = snd_soc_enum_item_to_val(e, item[0]);
113 
114         return 0;
115 }
116 
117 static int fsl_xcvr_arc_mode_get(struct snd_kcontrol *kcontrol,
118                                  struct snd_ctl_elem_value *ucontrol)
119 {
120         struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
121         struct fsl_xcvr *xcvr = snd_soc_dai_get_drvdata(dai);
122 
123         ucontrol->value.enumerated.item[0] = xcvr->arc_mode;
124 
125         return 0;
126 }
127 
128 static const u32 fsl_xcvr_phy_arc_cfg[] = {
129         FSL_XCVR_PHY_CTRL_ARC_MODE_SE_EN, FSL_XCVR_PHY_CTRL_ARC_MODE_CM_EN,
130 };
131 
132 static const char * const fsl_xcvr_arc_mode[] = { "Single Ended", "Common", };
133 static const struct soc_enum fsl_xcvr_arc_mode_enum =
134         SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(fsl_xcvr_arc_mode), fsl_xcvr_arc_mode);
135 static struct snd_kcontrol_new fsl_xcvr_arc_mode_kctl =
136         SOC_ENUM_EXT("ARC Mode", fsl_xcvr_arc_mode_enum,
137                      fsl_xcvr_arc_mode_get, fsl_xcvr_arc_mode_put);
138 
139 /* Capabilities data structure, bytes */
140 static int fsl_xcvr_type_capds_bytes_info(struct snd_kcontrol *kcontrol,
141                                           struct snd_ctl_elem_info *uinfo)
142 {
143         uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
144         uinfo->count = FSL_XCVR_CAPDS_SIZE;
145 
146         return 0;
147 }
148 
149 static int fsl_xcvr_capds_get(struct snd_kcontrol *kcontrol,
150                               struct snd_ctl_elem_value *ucontrol)
151 {
152         struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
153         struct fsl_xcvr *xcvr = snd_soc_dai_get_drvdata(dai);
154 
155         memcpy(ucontrol->value.bytes.data, xcvr->cap_ds, FSL_XCVR_CAPDS_SIZE);
156 
157         return 0;
158 }
159 
160 static int fsl_xcvr_capds_put(struct snd_kcontrol *kcontrol,
161                               struct snd_ctl_elem_value *ucontrol)
162 {
163         struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
164         struct fsl_xcvr *xcvr = snd_soc_dai_get_drvdata(dai);
165 
166         memcpy(xcvr->cap_ds, ucontrol->value.bytes.data, FSL_XCVR_CAPDS_SIZE);
167 
168         return 0;
169 }
170 
171 static struct snd_kcontrol_new fsl_xcvr_earc_capds_kctl = {
172         .iface = SNDRV_CTL_ELEM_IFACE_PCM,
173         .name = "Capabilities Data Structure",
174         .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
175         .info = fsl_xcvr_type_capds_bytes_info,
176         .get = fsl_xcvr_capds_get,
177         .put = fsl_xcvr_capds_put,
178 };
179 
180 static int fsl_xcvr_activate_ctl(struct snd_soc_dai *dai, const char *name,
181                                  bool active)
182 {
183         struct snd_soc_card *card = dai->component->card;
184         struct snd_kcontrol *kctl;
185         bool enabled;
186 
187         lockdep_assert_held(&card->snd_card->controls_rwsem);
188 
189         kctl = snd_soc_card_get_kcontrol_locked(card, name);
190         if (kctl == NULL)
191                 return -ENOENT;
192 
193         enabled = ((kctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_WRITE) != 0);
194         if (active == enabled)
195                 return 0; /* nothing to do */
196 
197         if (active)
198                 kctl->vd[0].access |=  SNDRV_CTL_ELEM_ACCESS_WRITE;
199         else
200                 kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_WRITE;
201 
202         snd_ctl_notify(card->snd_card, SNDRV_CTL_EVENT_MASK_INFO, &kctl->id);
203 
204         return 1;
205 }
206 
207 static int fsl_xcvr_mode_put(struct snd_kcontrol *kcontrol,
208                              struct snd_ctl_elem_value *ucontrol)
209 {
210         struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
211         struct fsl_xcvr *xcvr = snd_soc_dai_get_drvdata(dai);
212         struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
213         unsigned int *item = ucontrol->value.enumerated.item;
214         struct snd_soc_card *card = dai->component->card;
215         struct snd_soc_pcm_runtime *rtd;
216 
217         xcvr->mode = snd_soc_enum_item_to_val(e, item[0]);
218 
219         fsl_xcvr_activate_ctl(dai, fsl_xcvr_arc_mode_kctl.name,
220                               (xcvr->mode == FSL_XCVR_MODE_ARC));
221         fsl_xcvr_activate_ctl(dai, fsl_xcvr_earc_capds_kctl.name,
222                               (xcvr->mode == FSL_XCVR_MODE_EARC));
223         /* Allow playback for SPDIF only */
224         rtd = snd_soc_get_pcm_runtime(card, card->dai_link);
225         rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream_count =
226                 (xcvr->mode == FSL_XCVR_MODE_SPDIF ? 1 : 0);
227         return 0;
228 }
229 
230 static int fsl_xcvr_mode_get(struct snd_kcontrol *kcontrol,
231                              struct snd_ctl_elem_value *ucontrol)
232 {
233         struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
234         struct fsl_xcvr *xcvr = snd_soc_dai_get_drvdata(dai);
235 
236         ucontrol->value.enumerated.item[0] = xcvr->mode;
237 
238         return 0;
239 }
240 
241 static const char * const fsl_xcvr_mode[] = { "SPDIF", "ARC RX", "eARC", };
242 static const struct soc_enum fsl_xcvr_mode_enum =
243         SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(fsl_xcvr_mode), fsl_xcvr_mode);
244 static struct snd_kcontrol_new fsl_xcvr_mode_kctl =
245         SOC_ENUM_EXT("XCVR Mode", fsl_xcvr_mode_enum,
246                      fsl_xcvr_mode_get, fsl_xcvr_mode_put);
247 
248 /** phy: true => phy, false => pll */
249 static int fsl_xcvr_ai_write(struct fsl_xcvr *xcvr, u8 reg, u32 data, bool phy)
250 {
251         struct device *dev = &xcvr->pdev->dev;
252         u32 val, idx, tidx;
253         int ret;
254 
255         idx  = BIT(phy ? 26 : 24);
256         tidx = BIT(phy ? 27 : 25);
257 
258         regmap_write(xcvr->regmap, FSL_XCVR_PHY_AI_CTRL_CLR, 0xFF);
259         regmap_write(xcvr->regmap, FSL_XCVR_PHY_AI_CTRL_SET, reg);
260         regmap_write(xcvr->regmap, FSL_XCVR_PHY_AI_WDATA, data);
261         regmap_write(xcvr->regmap, FSL_XCVR_PHY_AI_CTRL_TOG, idx);
262 
263         ret = regmap_read_poll_timeout(xcvr->regmap, FSL_XCVR_PHY_AI_CTRL, val,
264                                        (val & idx) == ((val & tidx) >> 1),
265                                        10, 10000);
266         if (ret)
267                 dev_err(dev, "AI timeout: failed to set %s reg 0x%02x=0x%08x\n",
268                         phy ? "PHY" : "PLL", reg, data);
269         return ret;
270 }
271 
272 static int fsl_xcvr_en_phy_pll(struct fsl_xcvr *xcvr, u32 freq, bool tx)
273 {
274         struct device *dev = &xcvr->pdev->dev;
275         u32 i, div = 0, log2, val;
276         int ret;
277 
278         if (!xcvr->soc_data->use_phy)
279                 return 0;
280 
281         for (i = 0; i < ARRAY_SIZE(fsl_xcvr_pll_cfg); i++) {
282                 if (fsl_xcvr_pll_cfg[i].fout % freq == 0) {
283                         div = fsl_xcvr_pll_cfg[i].fout / freq;
284                         break;
285                 }
286         }
287 
288         if (!div || i >= ARRAY_SIZE(fsl_xcvr_pll_cfg))
289                 return -EINVAL;
290 
291         log2 = ilog2(div);
292 
293         /* Release AI interface from reset */
294         ret = regmap_write(xcvr->regmap, FSL_XCVR_PHY_AI_CTRL_SET,
295                            FSL_XCVR_PHY_AI_CTRL_AI_RESETN);
296         if (ret < 0) {
297                 dev_err(dev, "Error while setting IER0: %d\n", ret);
298                 return ret;
299         }
300 
301         switch (xcvr->soc_data->pll_ver) {
302         case PLL_MX8MP:
303                 /* PLL: BANDGAP_SET: EN_VBG (enable bandgap) */
304                 fsl_xcvr_ai_write(xcvr, FSL_XCVR_PLL_BANDGAP_SET,
305                                   FSL_XCVR_PLL_BANDGAP_EN_VBG, 0);
306 
307                 /* PLL: CTRL0: DIV_INTEGER */
308                 fsl_xcvr_ai_write(xcvr, FSL_XCVR_PLL_CTRL0, fsl_xcvr_pll_cfg[i].mfi, 0);
309                 /* PLL: NUMERATOR: MFN */
310                 fsl_xcvr_ai_write(xcvr, FSL_XCVR_PLL_NUM, fsl_xcvr_pll_cfg[i].mfn, 0);
311                 /* PLL: DENOMINATOR: MFD */
312                 fsl_xcvr_ai_write(xcvr, FSL_XCVR_PLL_DEN, fsl_xcvr_pll_cfg[i].mfd, 0);
313                 /* PLL: CTRL0_SET: HOLD_RING_OFF, POWER_UP */
314                 fsl_xcvr_ai_write(xcvr, FSL_XCVR_PLL_CTRL0_SET,
315                                   FSL_XCVR_PLL_CTRL0_HROFF | FSL_XCVR_PLL_CTRL0_PWP, 0);
316                 udelay(25);
317                 /* PLL: CTRL0: Clear Hold Ring Off */
318                 fsl_xcvr_ai_write(xcvr, FSL_XCVR_PLL_CTRL0_CLR,
319                                   FSL_XCVR_PLL_CTRL0_HROFF, 0);
320                 udelay(100);
321                 if (tx) { /* TX is enabled for SPDIF only */
322                         /* PLL: POSTDIV: PDIV0 */
323                         fsl_xcvr_ai_write(xcvr, FSL_XCVR_PLL_PDIV,
324                                           FSL_XCVR_PLL_PDIVx(log2, 0), 0);
325                         /* PLL: CTRL_SET: CLKMUX0_EN */
326                         fsl_xcvr_ai_write(xcvr, FSL_XCVR_PLL_CTRL0_SET,
327                                           FSL_XCVR_PLL_CTRL0_CM0_EN, 0);
328                 } else if (xcvr->mode == FSL_XCVR_MODE_EARC) { /* eARC RX */
329                         /* PLL: POSTDIV: PDIV1 */
330                         fsl_xcvr_ai_write(xcvr, FSL_XCVR_PLL_PDIV,
331                                           FSL_XCVR_PLL_PDIVx(log2, 1), 0);
332                         /* PLL: CTRL_SET: CLKMUX1_EN */
333                         fsl_xcvr_ai_write(xcvr, FSL_XCVR_PLL_CTRL0_SET,
334                                           FSL_XCVR_PLL_CTRL0_CM1_EN, 0);
335                 } else { /* SPDIF / ARC RX */
336                         /* PLL: POSTDIV: PDIV2 */
337                         fsl_xcvr_ai_write(xcvr, FSL_XCVR_PLL_PDIV,
338                                           FSL_XCVR_PLL_PDIVx(log2, 2), 0);
339                         /* PLL: CTRL_SET: CLKMUX2_EN */
340                         fsl_xcvr_ai_write(xcvr, FSL_XCVR_PLL_CTRL0_SET,
341                                           FSL_XCVR_PLL_CTRL0_CM2_EN, 0);
342                 }
343                 break;
344         case PLL_MX95:
345                 val = fsl_xcvr_pll_cfg[i].mfi << FSL_XCVR_GP_PLL_DIV_MFI_SHIFT | div;
346                 fsl_xcvr_ai_write(xcvr, FSL_XCVR_GP_PLL_DIV, val, 0);
347                 val = fsl_xcvr_pll_cfg[i].mfn << FSL_XCVR_GP_PLL_NUMERATOR_MFN_SHIFT;
348                 fsl_xcvr_ai_write(xcvr, FSL_XCVR_GP_PLL_NUMERATOR, val, 0);
349                 fsl_xcvr_ai_write(xcvr, FSL_XCVR_GP_PLL_DENOMINATOR,
350                                   fsl_xcvr_pll_cfg[i].mfd, 0);
351                 val = FSL_XCVR_GP_PLL_CTRL_POWERUP | FSL_XCVR_GP_PLL_CTRL_CLKMUX_EN;
352                 fsl_xcvr_ai_write(xcvr, FSL_XCVR_GP_PLL_CTRL, val, 0);
353                 break;
354         default:
355                 dev_err(dev, "Error for PLL version %d\n", xcvr->soc_data->pll_ver);
356                 return -EINVAL;
357         }
358 
359         if (xcvr->mode == FSL_XCVR_MODE_EARC) { /* eARC mode */
360                 /* PHY: CTRL_SET: TX_DIFF_OE, PHY_EN */
361                 fsl_xcvr_ai_write(xcvr, FSL_XCVR_PHY_CTRL_SET,
362                                   FSL_XCVR_PHY_CTRL_TSDIFF_OE |
363                                   FSL_XCVR_PHY_CTRL_PHY_EN, 1);
364                 /* PHY: CTRL2_SET: EARC_TX_MODE */
365                 fsl_xcvr_ai_write(xcvr, FSL_XCVR_PHY_CTRL2_SET,
366                                   FSL_XCVR_PHY_CTRL2_EARC_TXMS, 1);
367         } else if (!tx) { /* SPDIF / ARC RX mode */
368                 if (xcvr->mode == FSL_XCVR_MODE_SPDIF)
369                         /* PHY: CTRL_SET: SPDIF_EN */
370                         fsl_xcvr_ai_write(xcvr, FSL_XCVR_PHY_CTRL_SET,
371                                           FSL_XCVR_PHY_CTRL_SPDIF_EN, 1);
372                 else    /* PHY: CTRL_SET: ARC RX setup */
373                         fsl_xcvr_ai_write(xcvr, FSL_XCVR_PHY_CTRL_SET,
374                                           FSL_XCVR_PHY_CTRL_PHY_EN |
375                                           FSL_XCVR_PHY_CTRL_RX_CM_EN |
376                                           fsl_xcvr_phy_arc_cfg[xcvr->arc_mode], 1);
377         }
378 
379         dev_dbg(dev, "PLL Fexp: %u, Fout: %u, mfi: %u, mfn: %u, mfd: %d, div: %u, pdiv0: %u\n",
380                 freq, fsl_xcvr_pll_cfg[i].fout, fsl_xcvr_pll_cfg[i].mfi,
381                 fsl_xcvr_pll_cfg[i].mfn, fsl_xcvr_pll_cfg[i].mfd, div, log2);
382         return 0;
383 }
384 
385 static int fsl_xcvr_en_aud_pll(struct fsl_xcvr *xcvr, u32 freq)
386 {
387         struct device *dev = &xcvr->pdev->dev;
388         int ret;
389 
390         freq = xcvr->soc_data->spdif_only ? freq / 5 : freq;
391         clk_disable_unprepare(xcvr->phy_clk);
392         fsl_asoc_reparent_pll_clocks(dev, xcvr->phy_clk,
393                                      xcvr->pll8k_clk, xcvr->pll11k_clk, freq);
394         ret = clk_set_rate(xcvr->phy_clk, freq);
395         if (ret < 0) {
396                 dev_err(dev, "Error while setting AUD PLL rate: %d\n", ret);
397                 return ret;
398         }
399         ret = clk_prepare_enable(xcvr->phy_clk);
400         if (ret) {
401                 dev_err(dev, "failed to start PHY clock: %d\n", ret);
402                 return ret;
403         }
404 
405         if (!xcvr->soc_data->use_phy)
406                 return 0;
407         /* Release AI interface from reset */
408         ret = regmap_write(xcvr->regmap, FSL_XCVR_PHY_AI_CTRL_SET,
409                            FSL_XCVR_PHY_AI_CTRL_AI_RESETN);
410         if (ret < 0) {
411                 dev_err(dev, "Error while setting IER0: %d\n", ret);
412                 return ret;
413         }
414 
415         if (xcvr->mode == FSL_XCVR_MODE_EARC) { /* eARC mode */
416                 /* PHY: CTRL_SET: TX_DIFF_OE, PHY_EN */
417                 fsl_xcvr_ai_write(xcvr, FSL_XCVR_PHY_CTRL_SET,
418                                   FSL_XCVR_PHY_CTRL_TSDIFF_OE |
419                                   FSL_XCVR_PHY_CTRL_PHY_EN, 1);
420                 /* PHY: CTRL2_SET: EARC_TX_MODE */
421                 fsl_xcvr_ai_write(xcvr, FSL_XCVR_PHY_CTRL2_SET,
422                                   FSL_XCVR_PHY_CTRL2_EARC_TXMS, 1);
423         } else { /* SPDIF mode */
424                 /* PHY: CTRL_SET: TX_CLK_AUD_SS | SPDIF_EN */
425                 fsl_xcvr_ai_write(xcvr, FSL_XCVR_PHY_CTRL_SET,
426                                   FSL_XCVR_PHY_CTRL_TX_CLK_AUD_SS |
427                                   FSL_XCVR_PHY_CTRL_SPDIF_EN, 1);
428         }
429 
430         dev_dbg(dev, "PLL Fexp: %u\n", freq);
431 
432         return 0;
433 }
434 
435 #define FSL_XCVR_SPDIF_RX_FREQ  175000000
436 static int fsl_xcvr_prepare(struct snd_pcm_substream *substream,
437                             struct snd_soc_dai *dai)
438 {
439         struct fsl_xcvr *xcvr = snd_soc_dai_get_drvdata(dai);
440         bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
441         u32 m_ctl = 0, v_ctl = 0;
442         u32 r = substream->runtime->rate, ch = substream->runtime->channels;
443         u32 fout = 32 * r * ch * 10;
444         int ret = 0;
445 
446         switch (xcvr->mode) {
447         case FSL_XCVR_MODE_SPDIF:
448                 if (xcvr->soc_data->spdif_only && tx) {
449                         ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_TX_DPTH_CTRL_SET,
450                                                  FSL_XCVR_TX_DPTH_CTRL_BYPASS_FEM,
451                                                  FSL_XCVR_TX_DPTH_CTRL_BYPASS_FEM);
452                         if (ret < 0) {
453                                 dev_err(dai->dev, "Failed to set bypass fem: %d\n", ret);
454                                 return ret;
455                         }
456                 }
457                 fallthrough;
458         case FSL_XCVR_MODE_ARC:
459                 if (tx) {
460                         ret = fsl_xcvr_en_aud_pll(xcvr, fout);
461                         if (ret < 0) {
462                                 dev_err(dai->dev, "Failed to set TX freq %u: %d\n",
463                                         fout, ret);
464                                 return ret;
465                         }
466 
467                         ret = regmap_write(xcvr->regmap, FSL_XCVR_TX_DPTH_CTRL_SET,
468                                            FSL_XCVR_TX_DPTH_CTRL_FRM_FMT);
469                         if (ret < 0) {
470                                 dev_err(dai->dev, "Failed to set TX_DPTH: %d\n", ret);
471                                 return ret;
472                         }
473 
474                         /**
475                          * set SPDIF MODE - this flag is used to gate
476                          * SPDIF output, useless for SPDIF RX
477                          */
478                         m_ctl |= FSL_XCVR_EXT_CTRL_SPDIF_MODE;
479                         v_ctl |= FSL_XCVR_EXT_CTRL_SPDIF_MODE;
480                 } else {
481                         /**
482                          * Clear RX FIFO, flip RX FIFO bits,
483                          * disable eARC related HW mode detects
484                          */
485                         ret = regmap_write(xcvr->regmap, FSL_XCVR_RX_DPTH_CTRL_SET,
486                                            FSL_XCVR_RX_DPTH_CTRL_STORE_FMT |
487                                            FSL_XCVR_RX_DPTH_CTRL_CLR_RX_FIFO |
488                                            FSL_XCVR_RX_DPTH_CTRL_COMP |
489                                            FSL_XCVR_RX_DPTH_CTRL_LAYB_CTRL);
490                         if (ret < 0) {
491                                 dev_err(dai->dev, "Failed to set RX_DPTH: %d\n", ret);
492                                 return ret;
493                         }
494 
495                         ret = fsl_xcvr_en_phy_pll(xcvr, FSL_XCVR_SPDIF_RX_FREQ, tx);
496                         if (ret < 0) {
497                                 dev_err(dai->dev, "Failed to set RX freq %u: %d\n",
498                                         FSL_XCVR_SPDIF_RX_FREQ, ret);
499                                 return ret;
500                         }
501                 }
502                 break;
503         case FSL_XCVR_MODE_EARC:
504                 if (!tx) {
505                         /** Clear RX FIFO, flip RX FIFO bits */
506                         ret = regmap_write(xcvr->regmap, FSL_XCVR_RX_DPTH_CTRL_SET,
507                                            FSL_XCVR_RX_DPTH_CTRL_STORE_FMT |
508                                            FSL_XCVR_RX_DPTH_CTRL_CLR_RX_FIFO);
509                         if (ret < 0) {
510                                 dev_err(dai->dev, "Failed to set RX_DPTH: %d\n", ret);
511                                 return ret;
512                         }
513 
514                         /** Enable eARC related HW mode detects */
515                         ret = regmap_write(xcvr->regmap, FSL_XCVR_RX_DPTH_CTRL_CLR,
516                                            FSL_XCVR_RX_DPTH_CTRL_COMP |
517                                            FSL_XCVR_RX_DPTH_CTRL_LAYB_CTRL);
518                         if (ret < 0) {
519                                 dev_err(dai->dev, "Failed to clr TX_DPTH: %d\n", ret);
520                                 return ret;
521                         }
522                 }
523 
524                 /* clear CMDC RESET */
525                 m_ctl |= FSL_XCVR_EXT_CTRL_CMDC_RESET(tx);
526                 /* set TX_RX_MODE */
527                 m_ctl |= FSL_XCVR_EXT_CTRL_TX_RX_MODE;
528                 v_ctl |= (tx ? FSL_XCVR_EXT_CTRL_TX_RX_MODE : 0);
529                 break;
530         }
531 
532         ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_CTRL, m_ctl, v_ctl);
533         if (ret < 0) {
534                 dev_err(dai->dev, "Error while setting EXT_CTRL: %d\n", ret);
535                 return ret;
536         }
537 
538         return 0;
539 }
540 
541 static int fsl_xcvr_constr(const struct snd_pcm_substream *substream,
542                            const struct snd_pcm_hw_constraint_list *channels,
543                            const struct snd_pcm_hw_constraint_list *rates)
544 {
545         struct snd_pcm_runtime *rt = substream->runtime;
546         int ret;
547 
548         ret = snd_pcm_hw_constraint_list(rt, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
549                                          channels);
550         if (ret < 0)
551                 return ret;
552 
553         ret = snd_pcm_hw_constraint_list(rt, 0, SNDRV_PCM_HW_PARAM_RATE,
554                                          rates);
555         if (ret < 0)
556                 return ret;
557 
558         return 0;
559 }
560 
561 static int fsl_xcvr_startup(struct snd_pcm_substream *substream,
562                             struct snd_soc_dai *dai)
563 {
564         struct fsl_xcvr *xcvr = snd_soc_dai_get_drvdata(dai);
565         bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
566         int ret = 0;
567 
568         if (xcvr->streams & BIT(substream->stream)) {
569                 dev_err(dai->dev, "%sX busy\n", tx ? "T" : "R");
570                 return -EBUSY;
571         }
572 
573         /*
574          * EDMA controller needs period size to be a multiple of
575          * tx/rx maxburst
576          */
577         if (xcvr->soc_data->use_edma)
578                 snd_pcm_hw_constraint_step(substream->runtime, 0,
579                                            SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
580                                            tx ? xcvr->dma_prms_tx.maxburst :
581                                            xcvr->dma_prms_rx.maxburst);
582 
583         switch (xcvr->mode) {
584         case FSL_XCVR_MODE_SPDIF:
585         case FSL_XCVR_MODE_ARC:
586                 ret = fsl_xcvr_constr(substream, &fsl_xcvr_spdif_channels_constr,
587                                       &fsl_xcvr_spdif_rates_constr);
588                 break;
589         case FSL_XCVR_MODE_EARC:
590                 ret = fsl_xcvr_constr(substream, &fsl_xcvr_earc_channels_constr,
591                                       &fsl_xcvr_earc_rates_constr);
592                 break;
593         }
594         if (ret < 0)
595                 return ret;
596 
597         xcvr->streams |= BIT(substream->stream);
598 
599         if (!xcvr->soc_data->spdif_only) {
600                 struct snd_soc_card *card = dai->component->card;
601 
602                 /* Disable XCVR controls if there is stream started */
603                 down_read(&card->snd_card->controls_rwsem);
604                 fsl_xcvr_activate_ctl(dai, fsl_xcvr_mode_kctl.name, false);
605                 fsl_xcvr_activate_ctl(dai, fsl_xcvr_arc_mode_kctl.name, false);
606                 fsl_xcvr_activate_ctl(dai, fsl_xcvr_earc_capds_kctl.name, false);
607                 up_read(&card->snd_card->controls_rwsem);
608         }
609 
610         return 0;
611 }
612 
613 static void fsl_xcvr_shutdown(struct snd_pcm_substream *substream,
614                               struct snd_soc_dai *dai)
615 {
616         struct fsl_xcvr *xcvr = snd_soc_dai_get_drvdata(dai);
617         bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
618         u32 mask = 0, val = 0;
619         int ret;
620 
621         xcvr->streams &= ~BIT(substream->stream);
622 
623         /* Enable XCVR controls if there is no stream started */
624         if (!xcvr->streams) {
625                 if (!xcvr->soc_data->spdif_only) {
626                         struct snd_soc_card *card = dai->component->card;
627 
628                         down_read(&card->snd_card->controls_rwsem);
629                         fsl_xcvr_activate_ctl(dai, fsl_xcvr_mode_kctl.name, true);
630                         fsl_xcvr_activate_ctl(dai, fsl_xcvr_arc_mode_kctl.name,
631                                                 (xcvr->mode == FSL_XCVR_MODE_ARC));
632                         fsl_xcvr_activate_ctl(dai, fsl_xcvr_earc_capds_kctl.name,
633                                                 (xcvr->mode == FSL_XCVR_MODE_EARC));
634                         up_read(&card->snd_card->controls_rwsem);
635                 }
636                 ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_IER0,
637                                          FSL_XCVR_IRQ_EARC_ALL, 0);
638                 if (ret < 0) {
639                         dev_err(dai->dev, "Failed to set IER0: %d\n", ret);
640                         return;
641                 }
642 
643                 /* clear SPDIF MODE */
644                 if (xcvr->mode == FSL_XCVR_MODE_SPDIF)
645                         mask |= FSL_XCVR_EXT_CTRL_SPDIF_MODE;
646         }
647 
648         if (xcvr->mode == FSL_XCVR_MODE_EARC) {
649                 /* set CMDC RESET */
650                 mask |= FSL_XCVR_EXT_CTRL_CMDC_RESET(tx);
651                 val  |= FSL_XCVR_EXT_CTRL_CMDC_RESET(tx);
652         }
653 
654         ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_CTRL, mask, val);
655         if (ret < 0) {
656                 dev_err(dai->dev, "Err setting DPATH RESET: %d\n", ret);
657                 return;
658         }
659 }
660 
661 static int fsl_xcvr_trigger(struct snd_pcm_substream *substream, int cmd,
662                             struct snd_soc_dai *dai)
663 {
664         struct fsl_xcvr *xcvr = snd_soc_dai_get_drvdata(dai);
665         bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
666         int ret;
667 
668         switch (cmd) {
669         case SNDRV_PCM_TRIGGER_START:
670         case SNDRV_PCM_TRIGGER_RESUME:
671         case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
672                 /* set DPATH RESET */
673                 ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_CTRL,
674                                          FSL_XCVR_EXT_CTRL_DPTH_RESET(tx),
675                                          FSL_XCVR_EXT_CTRL_DPTH_RESET(tx));
676                 if (ret < 0) {
677                         dev_err(dai->dev, "Failed to set DPATH RESET: %d\n", ret);
678                         return ret;
679                 }
680 
681                 if (tx) {
682                         switch (xcvr->mode) {
683                         case FSL_XCVR_MODE_EARC:
684                                 /* set isr_cmdc_tx_en, w1c */
685                                 ret = regmap_write(xcvr->regmap,
686                                                    FSL_XCVR_ISR_SET,
687                                                    FSL_XCVR_ISR_CMDC_TX_EN);
688                                 if (ret < 0) {
689                                         dev_err(dai->dev, "err updating isr %d\n", ret);
690                                         return ret;
691                                 }
692                                 fallthrough;
693                         case FSL_XCVR_MODE_SPDIF:
694                                 ret = regmap_write(xcvr->regmap,
695                                          FSL_XCVR_TX_DPTH_CTRL_SET,
696                                          FSL_XCVR_TX_DPTH_CTRL_STRT_DATA_TX);
697                                 if (ret < 0) {
698                                         dev_err(dai->dev, "Failed to start DATA_TX: %d\n", ret);
699                                         return ret;
700                                 }
701                                 break;
702                         }
703                 }
704 
705                 /* enable DMA RD/WR */
706                 ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_CTRL,
707                                          FSL_XCVR_EXT_CTRL_DMA_DIS(tx), 0);
708                 if (ret < 0) {
709                         dev_err(dai->dev, "Failed to enable DMA: %d\n", ret);
710                         return ret;
711                 }
712 
713                 ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_IER0,
714                                          FSL_XCVR_IRQ_EARC_ALL, FSL_XCVR_IRQ_EARC_ALL);
715                 if (ret < 0) {
716                         dev_err(dai->dev, "Error while setting IER0: %d\n", ret);
717                         return ret;
718                 }
719 
720                 /* clear DPATH RESET */
721                 ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_CTRL,
722                                          FSL_XCVR_EXT_CTRL_DPTH_RESET(tx),
723                                          0);
724                 if (ret < 0) {
725                         dev_err(dai->dev, "Failed to clear DPATH RESET: %d\n", ret);
726                         return ret;
727                 }
728 
729                 break;
730         case SNDRV_PCM_TRIGGER_STOP:
731         case SNDRV_PCM_TRIGGER_SUSPEND:
732         case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
733                 /* disable DMA RD/WR */
734                 ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_CTRL,
735                                          FSL_XCVR_EXT_CTRL_DMA_DIS(tx),
736                                          FSL_XCVR_EXT_CTRL_DMA_DIS(tx));
737                 if (ret < 0) {
738                         dev_err(dai->dev, "Failed to disable DMA: %d\n", ret);
739                         return ret;
740                 }
741 
742                 ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_IER0,
743                                          FSL_XCVR_IRQ_EARC_ALL, 0);
744                 if (ret < 0) {
745                         dev_err(dai->dev, "Failed to clear IER0: %d\n", ret);
746                         return ret;
747                 }
748 
749                 if (tx) {
750                         switch (xcvr->mode) {
751                         case FSL_XCVR_MODE_SPDIF:
752                                 ret = regmap_write(xcvr->regmap,
753                                          FSL_XCVR_TX_DPTH_CTRL_CLR,
754                                          FSL_XCVR_TX_DPTH_CTRL_STRT_DATA_TX);
755                                 if (ret < 0) {
756                                         dev_err(dai->dev, "Failed to stop DATA_TX: %d\n", ret);
757                                         return ret;
758                                 }
759                                 if (xcvr->soc_data->spdif_only)
760                                         break;
761                                 else
762                                         fallthrough;
763                         case FSL_XCVR_MODE_EARC:
764                                 /* clear ISR_CMDC_TX_EN, W1C */
765                                 ret = regmap_write(xcvr->regmap,
766                                                    FSL_XCVR_ISR_CLR,
767                                                    FSL_XCVR_ISR_CMDC_TX_EN);
768                                 if (ret < 0) {
769                                         dev_err(dai->dev,
770                                                 "Err updating ISR %d\n", ret);
771                                         return ret;
772                                 }
773                                 break;
774                         }
775                 }
776                 break;
777         default:
778                 return -EINVAL;
779         }
780 
781         return 0;
782 }
783 
784 static int fsl_xcvr_load_firmware(struct fsl_xcvr *xcvr)
785 {
786         struct device *dev = &xcvr->pdev->dev;
787         const struct firmware *fw;
788         int ret = 0, rem, off, out, page = 0, size = FSL_XCVR_REG_OFFSET;
789         u32 mask, val;
790 
791         ret = request_firmware(&fw, xcvr->soc_data->fw_name, dev);
792         if (ret) {
793                 dev_err(dev, "failed to request firmware.\n");
794                 return ret;
795         }
796 
797         rem = fw->size;
798 
799         /* RAM is 20KiB = 16KiB code + 4KiB data => max 10 pages 2KiB each */
800         if (rem > 16384) {
801                 dev_err(dev, "FW size %d is bigger than 16KiB.\n", rem);
802                 release_firmware(fw);
803                 return -ENOMEM;
804         }
805 
806         for (page = 0; page < 10; page++) {
807                 ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_CTRL,
808                                          FSL_XCVR_EXT_CTRL_PAGE_MASK,
809                                          FSL_XCVR_EXT_CTRL_PAGE(page));
810                 if (ret < 0) {
811                         dev_err(dev, "FW: failed to set page %d, err=%d\n",
812                                 page, ret);
813                         goto err_firmware;
814                 }
815 
816                 off = page * size;
817                 out = min(rem, size);
818                 /* IPG clock is assumed to be running, otherwise it will hang */
819                 if (out > 0) {
820                         /* write firmware into code memory */
821                         memcpy_toio(xcvr->ram_addr, fw->data + off, out);
822                         rem -= out;
823                         if (rem == 0) {
824                                 /* last part of firmware written */
825                                 /* clean remaining part of code memory page */
826                                 memset_io(xcvr->ram_addr + out, 0, size - out);
827                         }
828                 } else {
829                         /* clean current page, including data memory */
830                         memset_io(xcvr->ram_addr, 0, size);
831                 }
832         }
833 
834 err_firmware:
835         release_firmware(fw);
836         if (ret < 0)
837                 return ret;
838 
839         /* configure watermarks */
840         mask = FSL_XCVR_EXT_CTRL_RX_FWM_MASK | FSL_XCVR_EXT_CTRL_TX_FWM_MASK;
841         val  = FSL_XCVR_EXT_CTRL_RX_FWM(FSL_XCVR_FIFO_WMK_RX);
842         val |= FSL_XCVR_EXT_CTRL_TX_FWM(FSL_XCVR_FIFO_WMK_TX);
843         /* disable DMA RD/WR */
844         mask |= FSL_XCVR_EXT_CTRL_DMA_RD_DIS | FSL_XCVR_EXT_CTRL_DMA_WR_DIS;
845         val  |= FSL_XCVR_EXT_CTRL_DMA_RD_DIS | FSL_XCVR_EXT_CTRL_DMA_WR_DIS;
846         /* Data RAM is 4KiB, last two pages: 8 and 9. Select page 8. */
847         mask |= FSL_XCVR_EXT_CTRL_PAGE_MASK;
848         val  |= FSL_XCVR_EXT_CTRL_PAGE(8);
849 
850         ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_CTRL, mask, val);
851         if (ret < 0) {
852                 dev_err(dev, "Failed to set watermarks: %d\n", ret);
853                 return ret;
854         }
855 
856         /* Store Capabilities Data Structure into Data RAM */
857         memcpy_toio(xcvr->ram_addr + FSL_XCVR_CAP_DATA_STR, xcvr->cap_ds,
858                     FSL_XCVR_CAPDS_SIZE);
859         return 0;
860 }
861 
862 static int fsl_xcvr_type_iec958_info(struct snd_kcontrol *kcontrol,
863                                      struct snd_ctl_elem_info *uinfo)
864 {
865         uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
866         uinfo->count = 1;
867 
868         return 0;
869 }
870 
871 static int fsl_xcvr_type_iec958_bytes_info(struct snd_kcontrol *kcontrol,
872                                            struct snd_ctl_elem_info *uinfo)
873 {
874         uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
875         uinfo->count = sizeof_field(struct snd_aes_iec958, status);
876 
877         return 0;
878 }
879 
880 static int fsl_xcvr_rx_cs_get(struct snd_kcontrol *kcontrol,
881                               struct snd_ctl_elem_value *ucontrol)
882 {
883         struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
884         struct fsl_xcvr *xcvr = snd_soc_dai_get_drvdata(dai);
885 
886         memcpy(ucontrol->value.iec958.status, xcvr->rx_iec958.status, 24);
887 
888         return 0;
889 }
890 
891 static int fsl_xcvr_tx_cs_get(struct snd_kcontrol *kcontrol,
892                               struct snd_ctl_elem_value *ucontrol)
893 {
894         struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
895         struct fsl_xcvr *xcvr = snd_soc_dai_get_drvdata(dai);
896 
897         memcpy(ucontrol->value.iec958.status, xcvr->tx_iec958.status, 24);
898 
899         return 0;
900 }
901 
902 static int fsl_xcvr_tx_cs_put(struct snd_kcontrol *kcontrol,
903                               struct snd_ctl_elem_value *ucontrol)
904 {
905         struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
906         struct fsl_xcvr *xcvr = snd_soc_dai_get_drvdata(dai);
907 
908         memcpy(xcvr->tx_iec958.status, ucontrol->value.iec958.status, 24);
909 
910         return 0;
911 }
912 
913 static struct snd_kcontrol_new fsl_xcvr_rx_ctls[] = {
914         /* Channel status controller */
915         {
916                 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
917                 .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, DEFAULT),
918                 .access = SNDRV_CTL_ELEM_ACCESS_READ,
919                 .info = fsl_xcvr_type_iec958_info,
920                 .get = fsl_xcvr_rx_cs_get,
921         },
922         /* Capture channel status, bytes */
923         {
924                 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
925                 .name = "Capture Channel Status",
926                 .access = SNDRV_CTL_ELEM_ACCESS_READ,
927                 .info = fsl_xcvr_type_iec958_bytes_info,
928                 .get = fsl_xcvr_rx_cs_get,
929         },
930 };
931 
932 static struct snd_kcontrol_new fsl_xcvr_tx_ctls[] = {
933         /* Channel status controller */
934         {
935                 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
936                 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
937                 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
938                 .info = fsl_xcvr_type_iec958_info,
939                 .get = fsl_xcvr_tx_cs_get,
940                 .put = fsl_xcvr_tx_cs_put,
941         },
942         /* Playback channel status, bytes */
943         {
944                 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
945                 .name = "Playback Channel Status",
946                 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
947                 .info = fsl_xcvr_type_iec958_bytes_info,
948                 .get = fsl_xcvr_tx_cs_get,
949                 .put = fsl_xcvr_tx_cs_put,
950         },
951 };
952 
953 static int fsl_xcvr_dai_probe(struct snd_soc_dai *dai)
954 {
955         struct fsl_xcvr *xcvr = snd_soc_dai_get_drvdata(dai);
956 
957         snd_soc_dai_init_dma_data(dai, &xcvr->dma_prms_tx, &xcvr->dma_prms_rx);
958 
959         if (xcvr->soc_data->spdif_only)
960                 xcvr->mode = FSL_XCVR_MODE_SPDIF;
961         else {
962                 snd_soc_add_dai_controls(dai, &fsl_xcvr_mode_kctl, 1);
963                 snd_soc_add_dai_controls(dai, &fsl_xcvr_arc_mode_kctl, 1);
964                 snd_soc_add_dai_controls(dai, &fsl_xcvr_earc_capds_kctl, 1);
965         }
966         snd_soc_add_dai_controls(dai, fsl_xcvr_tx_ctls,
967                                  ARRAY_SIZE(fsl_xcvr_tx_ctls));
968         snd_soc_add_dai_controls(dai, fsl_xcvr_rx_ctls,
969                                  ARRAY_SIZE(fsl_xcvr_rx_ctls));
970         return 0;
971 }
972 
973 static const struct snd_soc_dai_ops fsl_xcvr_dai_ops = {
974         .probe          = fsl_xcvr_dai_probe,
975         .prepare        = fsl_xcvr_prepare,
976         .startup        = fsl_xcvr_startup,
977         .shutdown       = fsl_xcvr_shutdown,
978         .trigger        = fsl_xcvr_trigger,
979 };
980 
981 static struct snd_soc_dai_driver fsl_xcvr_dai = {
982         .ops = &fsl_xcvr_dai_ops,
983         .playback = {
984                 .stream_name = "CPU-Playback",
985                 .channels_min = 1,
986                 .channels_max = 32,
987                 .rate_min = 32000,
988                 .rate_max = 1536000,
989                 .rates = SNDRV_PCM_RATE_KNOT,
990                 .formats = SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE,
991         },
992         .capture = {
993                 .stream_name = "CPU-Capture",
994                 .channels_min = 1,
995                 .channels_max = 32,
996                 .rate_min = 32000,
997                 .rate_max = 1536000,
998                 .rates = SNDRV_PCM_RATE_KNOT,
999                 .formats = SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE,
1000         },
1001 };
1002 
1003 static const struct snd_soc_component_driver fsl_xcvr_comp = {
1004         .name                   = "fsl-xcvr-dai",
1005         .legacy_dai_naming      = 1,
1006 };
1007 
1008 static const struct reg_default fsl_xcvr_reg_defaults[] = {
1009         { FSL_XCVR_VERSION,     0x00000000 },
1010         { FSL_XCVR_EXT_CTRL,    0xF8204040 },
1011         { FSL_XCVR_EXT_STATUS,  0x00000000 },
1012         { FSL_XCVR_EXT_IER0,    0x00000000 },
1013         { FSL_XCVR_EXT_IER1,    0x00000000 },
1014         { FSL_XCVR_EXT_ISR,     0x00000000 },
1015         { FSL_XCVR_EXT_ISR_SET, 0x00000000 },
1016         { FSL_XCVR_EXT_ISR_CLR, 0x00000000 },
1017         { FSL_XCVR_EXT_ISR_TOG, 0x00000000 },
1018         { FSL_XCVR_IER,         0x00000000 },
1019         { FSL_XCVR_ISR,         0x00000000 },
1020         { FSL_XCVR_ISR_SET,     0x00000000 },
1021         { FSL_XCVR_ISR_CLR,     0x00000000 },
1022         { FSL_XCVR_ISR_TOG,     0x00000000 },
1023         { FSL_XCVR_CLK_CTRL,    0x0000018F },
1024         { FSL_XCVR_RX_DPTH_CTRL,        0x00040CC1 },
1025         { FSL_XCVR_RX_DPTH_CTRL_SET,    0x00040CC1 },
1026         { FSL_XCVR_RX_DPTH_CTRL_CLR,    0x00040CC1 },
1027         { FSL_XCVR_RX_DPTH_CTRL_TOG,    0x00040CC1 },
1028         { FSL_XCVR_RX_DPTH_CNTR_CTRL,   0x00000000 },
1029         { FSL_XCVR_RX_DPTH_CNTR_CTRL_SET, 0x00000000 },
1030         { FSL_XCVR_RX_DPTH_CNTR_CTRL_CLR, 0x00000000 },
1031         { FSL_XCVR_RX_DPTH_CNTR_CTRL_TOG, 0x00000000 },
1032         { FSL_XCVR_RX_DPTH_TSCR, 0x00000000 },
1033         { FSL_XCVR_RX_DPTH_BCR,  0x00000000 },
1034         { FSL_XCVR_RX_DPTH_BCTR, 0x00000000 },
1035         { FSL_XCVR_RX_DPTH_BCRR, 0x00000000 },
1036         { FSL_XCVR_TX_DPTH_CTRL,        0x00000000 },
1037         { FSL_XCVR_TX_DPTH_CTRL_SET,    0x00000000 },
1038         { FSL_XCVR_TX_DPTH_CTRL_CLR,    0x00000000 },
1039         { FSL_XCVR_TX_DPTH_CTRL_TOG,    0x00000000 },
1040         { FSL_XCVR_TX_CS_DATA_0,        0x00000000 },
1041         { FSL_XCVR_TX_CS_DATA_1,        0x00000000 },
1042         { FSL_XCVR_TX_CS_DATA_2,        0x00000000 },
1043         { FSL_XCVR_TX_CS_DATA_3,        0x00000000 },
1044         { FSL_XCVR_TX_CS_DATA_4,        0x00000000 },
1045         { FSL_XCVR_TX_CS_DATA_5,        0x00000000 },
1046         { FSL_XCVR_TX_DPTH_CNTR_CTRL,   0x00000000 },
1047         { FSL_XCVR_TX_DPTH_CNTR_CTRL_SET, 0x00000000 },
1048         { FSL_XCVR_TX_DPTH_CNTR_CTRL_CLR, 0x00000000 },
1049         { FSL_XCVR_TX_DPTH_CNTR_CTRL_TOG, 0x00000000 },
1050         { FSL_XCVR_TX_DPTH_TSCR, 0x00000000 },
1051         { FSL_XCVR_TX_DPTH_BCR,  0x00000000 },
1052         { FSL_XCVR_TX_DPTH_BCTR, 0x00000000 },
1053         { FSL_XCVR_TX_DPTH_BCRR, 0x00000000 },
1054         { FSL_XCVR_DEBUG_REG_0,         0x00000000 },
1055         { FSL_XCVR_DEBUG_REG_1,         0x00000000 },
1056 };
1057 
1058 static bool fsl_xcvr_readable_reg(struct device *dev, unsigned int reg)
1059 {
1060         struct fsl_xcvr *xcvr = dev_get_drvdata(dev);
1061 
1062         if (!xcvr->soc_data->use_phy)
1063                 if ((reg >= FSL_XCVR_IER && reg <= FSL_XCVR_PHY_AI_RDATA) ||
1064                     reg > FSL_XCVR_TX_DPTH_BCRR)
1065                         return false;
1066         switch (reg) {
1067         case FSL_XCVR_VERSION:
1068         case FSL_XCVR_EXT_CTRL:
1069         case FSL_XCVR_EXT_STATUS:
1070         case FSL_XCVR_EXT_IER0:
1071         case FSL_XCVR_EXT_IER1:
1072         case FSL_XCVR_EXT_ISR:
1073         case FSL_XCVR_EXT_ISR_SET:
1074         case FSL_XCVR_EXT_ISR_CLR:
1075         case FSL_XCVR_EXT_ISR_TOG:
1076         case FSL_XCVR_IER:
1077         case FSL_XCVR_ISR:
1078         case FSL_XCVR_ISR_SET:
1079         case FSL_XCVR_ISR_CLR:
1080         case FSL_XCVR_ISR_TOG:
1081         case FSL_XCVR_PHY_AI_CTRL:
1082         case FSL_XCVR_PHY_AI_CTRL_SET:
1083         case FSL_XCVR_PHY_AI_CTRL_CLR:
1084         case FSL_XCVR_PHY_AI_CTRL_TOG:
1085         case FSL_XCVR_PHY_AI_RDATA:
1086         case FSL_XCVR_CLK_CTRL:
1087         case FSL_XCVR_RX_DPTH_CTRL:
1088         case FSL_XCVR_RX_DPTH_CTRL_SET:
1089         case FSL_XCVR_RX_DPTH_CTRL_CLR:
1090         case FSL_XCVR_RX_DPTH_CTRL_TOG:
1091         case FSL_XCVR_RX_CS_DATA_0:
1092         case FSL_XCVR_RX_CS_DATA_1:
1093         case FSL_XCVR_RX_CS_DATA_2:
1094         case FSL_XCVR_RX_CS_DATA_3:
1095         case FSL_XCVR_RX_CS_DATA_4:
1096         case FSL_XCVR_RX_CS_DATA_5:
1097         case FSL_XCVR_RX_DPTH_CNTR_CTRL:
1098         case FSL_XCVR_RX_DPTH_CNTR_CTRL_SET:
1099         case FSL_XCVR_RX_DPTH_CNTR_CTRL_CLR:
1100         case FSL_XCVR_RX_DPTH_CNTR_CTRL_TOG:
1101         case FSL_XCVR_RX_DPTH_TSCR:
1102         case FSL_XCVR_RX_DPTH_BCR:
1103         case FSL_XCVR_RX_DPTH_BCTR:
1104         case FSL_XCVR_RX_DPTH_BCRR:
1105         case FSL_XCVR_TX_DPTH_CTRL:
1106         case FSL_XCVR_TX_DPTH_CTRL_SET:
1107         case FSL_XCVR_TX_DPTH_CTRL_CLR:
1108         case FSL_XCVR_TX_DPTH_CTRL_TOG:
1109         case FSL_XCVR_TX_CS_DATA_0:
1110         case FSL_XCVR_TX_CS_DATA_1:
1111         case FSL_XCVR_TX_CS_DATA_2:
1112         case FSL_XCVR_TX_CS_DATA_3:
1113         case FSL_XCVR_TX_CS_DATA_4:
1114         case FSL_XCVR_TX_CS_DATA_5:
1115         case FSL_XCVR_TX_DPTH_CNTR_CTRL:
1116         case FSL_XCVR_TX_DPTH_CNTR_CTRL_SET:
1117         case FSL_XCVR_TX_DPTH_CNTR_CTRL_CLR:
1118         case FSL_XCVR_TX_DPTH_CNTR_CTRL_TOG:
1119         case FSL_XCVR_TX_DPTH_TSCR:
1120         case FSL_XCVR_TX_DPTH_BCR:
1121         case FSL_XCVR_TX_DPTH_BCTR:
1122         case FSL_XCVR_TX_DPTH_BCRR:
1123         case FSL_XCVR_DEBUG_REG_0:
1124         case FSL_XCVR_DEBUG_REG_1:
1125                 return true;
1126         default:
1127                 return false;
1128         }
1129 }
1130 
1131 static bool fsl_xcvr_writeable_reg(struct device *dev, unsigned int reg)
1132 {
1133         struct fsl_xcvr *xcvr = dev_get_drvdata(dev);
1134 
1135         if (!xcvr->soc_data->use_phy)
1136                 if (reg >= FSL_XCVR_IER && reg <= FSL_XCVR_PHY_AI_RDATA)
1137                         return false;
1138         switch (reg) {
1139         case FSL_XCVR_EXT_CTRL:
1140         case FSL_XCVR_EXT_IER0:
1141         case FSL_XCVR_EXT_IER1:
1142         case FSL_XCVR_EXT_ISR:
1143         case FSL_XCVR_EXT_ISR_SET:
1144         case FSL_XCVR_EXT_ISR_CLR:
1145         case FSL_XCVR_EXT_ISR_TOG:
1146         case FSL_XCVR_IER:
1147         case FSL_XCVR_ISR_SET:
1148         case FSL_XCVR_ISR_CLR:
1149         case FSL_XCVR_ISR_TOG:
1150         case FSL_XCVR_PHY_AI_CTRL:
1151         case FSL_XCVR_PHY_AI_CTRL_SET:
1152         case FSL_XCVR_PHY_AI_CTRL_CLR:
1153         case FSL_XCVR_PHY_AI_CTRL_TOG:
1154         case FSL_XCVR_PHY_AI_WDATA:
1155         case FSL_XCVR_CLK_CTRL:
1156         case FSL_XCVR_RX_DPTH_CTRL:
1157         case FSL_XCVR_RX_DPTH_CTRL_SET:
1158         case FSL_XCVR_RX_DPTH_CTRL_CLR:
1159         case FSL_XCVR_RX_DPTH_CTRL_TOG:
1160         case FSL_XCVR_RX_DPTH_CNTR_CTRL:
1161         case FSL_XCVR_RX_DPTH_CNTR_CTRL_SET:
1162         case FSL_XCVR_RX_DPTH_CNTR_CTRL_CLR:
1163         case FSL_XCVR_RX_DPTH_CNTR_CTRL_TOG:
1164         case FSL_XCVR_TX_DPTH_CTRL_SET:
1165         case FSL_XCVR_TX_DPTH_CTRL_CLR:
1166         case FSL_XCVR_TX_DPTH_CTRL_TOG:
1167         case FSL_XCVR_TX_CS_DATA_0:
1168         case FSL_XCVR_TX_CS_DATA_1:
1169         case FSL_XCVR_TX_CS_DATA_2:
1170         case FSL_XCVR_TX_CS_DATA_3:
1171         case FSL_XCVR_TX_CS_DATA_4:
1172         case FSL_XCVR_TX_CS_DATA_5:
1173         case FSL_XCVR_TX_DPTH_CNTR_CTRL:
1174         case FSL_XCVR_TX_DPTH_CNTR_CTRL_SET:
1175         case FSL_XCVR_TX_DPTH_CNTR_CTRL_CLR:
1176         case FSL_XCVR_TX_DPTH_CNTR_CTRL_TOG:
1177                 return true;
1178         default:
1179                 return false;
1180         }
1181 }
1182 
1183 static bool fsl_xcvr_volatile_reg(struct device *dev, unsigned int reg)
1184 {
1185         return fsl_xcvr_readable_reg(dev, reg);
1186 }
1187 
1188 static const struct regmap_config fsl_xcvr_regmap_cfg = {
1189         .reg_bits = 32,
1190         .reg_stride = 4,
1191         .val_bits = 32,
1192         .max_register = FSL_XCVR_MAX_REG,
1193         .reg_defaults = fsl_xcvr_reg_defaults,
1194         .num_reg_defaults = ARRAY_SIZE(fsl_xcvr_reg_defaults),
1195         .readable_reg = fsl_xcvr_readable_reg,
1196         .volatile_reg = fsl_xcvr_volatile_reg,
1197         .writeable_reg = fsl_xcvr_writeable_reg,
1198         .cache_type = REGCACHE_FLAT,
1199 };
1200 
1201 static irqreturn_t irq0_isr(int irq, void *devid)
1202 {
1203         struct fsl_xcvr *xcvr = (struct fsl_xcvr *)devid;
1204         struct device *dev = &xcvr->pdev->dev;
1205         struct regmap *regmap = xcvr->regmap;
1206         void __iomem *reg_ctrl, *reg_buff;
1207         u32 isr, isr_clr = 0, val, i;
1208 
1209         regmap_read(regmap, FSL_XCVR_EXT_ISR, &isr);
1210 
1211         if (isr & FSL_XCVR_IRQ_NEW_CS) {
1212                 dev_dbg(dev, "Received new CS block\n");
1213                 isr_clr |= FSL_XCVR_IRQ_NEW_CS;
1214                 if (!xcvr->soc_data->spdif_only) {
1215                         /* Data RAM is 4KiB, last two pages: 8 and 9. Select page 8. */
1216                         regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_CTRL,
1217                                            FSL_XCVR_EXT_CTRL_PAGE_MASK,
1218                                            FSL_XCVR_EXT_CTRL_PAGE(8));
1219 
1220                         /* Find updated CS buffer */
1221                         reg_ctrl = xcvr->ram_addr + FSL_XCVR_RX_CS_CTRL_0;
1222                         reg_buff = xcvr->ram_addr + FSL_XCVR_RX_CS_BUFF_0;
1223                         memcpy_fromio(&val, reg_ctrl, sizeof(val));
1224                         if (!val) {
1225                                 reg_ctrl = xcvr->ram_addr + FSL_XCVR_RX_CS_CTRL_1;
1226                                 reg_buff = xcvr->ram_addr + FSL_XCVR_RX_CS_BUFF_1;
1227                                 memcpy_fromio(&val, reg_ctrl, sizeof(val));
1228                         }
1229 
1230                         if (val) {
1231                                 /* copy CS buffer */
1232                                 memcpy_fromio(&xcvr->rx_iec958.status, reg_buff,
1233                                               sizeof(xcvr->rx_iec958.status));
1234                                 for (i = 0; i < 6; i++) {
1235                                         val = *(u32 *)(xcvr->rx_iec958.status + i*4);
1236                                         *(u32 *)(xcvr->rx_iec958.status + i*4) =
1237                                                 bitrev32(val);
1238                                 }
1239                                 /* clear CS control register */
1240                                 memset_io(reg_ctrl, 0, sizeof(val));
1241                         }
1242                 }
1243         }
1244         if (isr & FSL_XCVR_IRQ_NEW_UD) {
1245                 dev_dbg(dev, "Received new UD block\n");
1246                 isr_clr |= FSL_XCVR_IRQ_NEW_UD;
1247         }
1248         if (isr & FSL_XCVR_IRQ_MUTE) {
1249                 dev_dbg(dev, "HW mute bit detected\n");
1250                 isr_clr |= FSL_XCVR_IRQ_MUTE;
1251         }
1252         if (isr & FSL_XCVR_IRQ_FIFO_UOFL_ERR) {
1253                 dev_dbg(dev, "RX/TX FIFO full/empty\n");
1254                 isr_clr |= FSL_XCVR_IRQ_FIFO_UOFL_ERR;
1255         }
1256         if (isr & FSL_XCVR_IRQ_ARC_MODE) {
1257                 dev_dbg(dev, "CMDC SM falls out of eARC mode\n");
1258                 isr_clr |= FSL_XCVR_IRQ_ARC_MODE;
1259         }
1260         if (isr & FSL_XCVR_IRQ_DMA_RD_REQ) {
1261                 dev_dbg(dev, "DMA read request\n");
1262                 isr_clr |= FSL_XCVR_IRQ_DMA_RD_REQ;
1263         }
1264         if (isr & FSL_XCVR_IRQ_DMA_WR_REQ) {
1265                 dev_dbg(dev, "DMA write request\n");
1266                 isr_clr |= FSL_XCVR_IRQ_DMA_WR_REQ;
1267         }
1268 
1269         if (isr_clr) {
1270                 regmap_write(regmap, FSL_XCVR_EXT_ISR_CLR, isr_clr);
1271                 return IRQ_HANDLED;
1272         }
1273 
1274         return IRQ_NONE;
1275 }
1276 
1277 static const struct fsl_xcvr_soc_data fsl_xcvr_imx8mp_data = {
1278         .fw_name = "imx/xcvr/xcvr-imx8mp.bin",
1279         .use_phy = true,
1280         .pll_ver = PLL_MX8MP,
1281 };
1282 
1283 static const struct fsl_xcvr_soc_data fsl_xcvr_imx93_data = {
1284         .spdif_only = true,
1285         .use_edma = true,
1286 };
1287 
1288 static const struct fsl_xcvr_soc_data fsl_xcvr_imx95_data = {
1289         .spdif_only = true,
1290         .use_phy = true,
1291         .use_edma = true,
1292         .pll_ver = PLL_MX95,
1293 };
1294 
1295 static const struct of_device_id fsl_xcvr_dt_ids[] = {
1296         { .compatible = "fsl,imx8mp-xcvr", .data = &fsl_xcvr_imx8mp_data },
1297         { .compatible = "fsl,imx93-xcvr", .data = &fsl_xcvr_imx93_data},
1298         { .compatible = "fsl,imx95-xcvr", .data = &fsl_xcvr_imx95_data},
1299         { /* sentinel */ }
1300 };
1301 MODULE_DEVICE_TABLE(of, fsl_xcvr_dt_ids);
1302 
1303 static int fsl_xcvr_probe(struct platform_device *pdev)
1304 {
1305         struct device *dev = &pdev->dev;
1306         struct fsl_xcvr *xcvr;
1307         struct resource *rx_res, *tx_res;
1308         void __iomem *regs;
1309         int ret, irq;
1310 
1311         xcvr = devm_kzalloc(dev, sizeof(*xcvr), GFP_KERNEL);
1312         if (!xcvr)
1313                 return -ENOMEM;
1314 
1315         xcvr->pdev = pdev;
1316         xcvr->soc_data = of_device_get_match_data(&pdev->dev);
1317 
1318         xcvr->ipg_clk = devm_clk_get(dev, "ipg");
1319         if (IS_ERR(xcvr->ipg_clk)) {
1320                 dev_err(dev, "failed to get ipg clock\n");
1321                 return PTR_ERR(xcvr->ipg_clk);
1322         }
1323 
1324         xcvr->phy_clk = devm_clk_get(dev, "phy");
1325         if (IS_ERR(xcvr->phy_clk)) {
1326                 dev_err(dev, "failed to get phy clock\n");
1327                 return PTR_ERR(xcvr->phy_clk);
1328         }
1329 
1330         xcvr->spba_clk = devm_clk_get(dev, "spba");
1331         if (IS_ERR(xcvr->spba_clk)) {
1332                 dev_err(dev, "failed to get spba clock\n");
1333                 return PTR_ERR(xcvr->spba_clk);
1334         }
1335 
1336         xcvr->pll_ipg_clk = devm_clk_get(dev, "pll_ipg");
1337         if (IS_ERR(xcvr->pll_ipg_clk)) {
1338                 dev_err(dev, "failed to get pll_ipg clock\n");
1339                 return PTR_ERR(xcvr->pll_ipg_clk);
1340         }
1341 
1342         fsl_asoc_get_pll_clocks(dev, &xcvr->pll8k_clk,
1343                                 &xcvr->pll11k_clk);
1344 
1345         xcvr->ram_addr = devm_platform_ioremap_resource_byname(pdev, "ram");
1346         if (IS_ERR(xcvr->ram_addr))
1347                 return PTR_ERR(xcvr->ram_addr);
1348 
1349         regs = devm_platform_ioremap_resource_byname(pdev, "regs");
1350         if (IS_ERR(regs))
1351                 return PTR_ERR(regs);
1352 
1353         xcvr->regmap = devm_regmap_init_mmio_clk(dev, NULL, regs,
1354                                                  &fsl_xcvr_regmap_cfg);
1355         if (IS_ERR(xcvr->regmap)) {
1356                 dev_err(dev, "failed to init XCVR regmap: %ld\n",
1357                         PTR_ERR(xcvr->regmap));
1358                 return PTR_ERR(xcvr->regmap);
1359         }
1360 
1361         xcvr->reset = devm_reset_control_get_optional_exclusive(dev, NULL);
1362         if (IS_ERR(xcvr->reset)) {
1363                 dev_err(dev, "failed to get XCVR reset control\n");
1364                 return PTR_ERR(xcvr->reset);
1365         }
1366 
1367         /* get IRQs */
1368         irq = platform_get_irq(pdev, 0);
1369         if (irq < 0)
1370                 return irq;
1371 
1372         ret = devm_request_irq(dev, irq, irq0_isr, 0, pdev->name, xcvr);
1373         if (ret) {
1374                 dev_err(dev, "failed to claim IRQ0: %i\n", ret);
1375                 return ret;
1376         }
1377 
1378         rx_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rxfifo");
1379         tx_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "txfifo");
1380         if (!rx_res || !tx_res) {
1381                 dev_err(dev, "could not find rxfifo or txfifo resource\n");
1382                 return -EINVAL;
1383         }
1384         xcvr->dma_prms_rx.chan_name = "rx";
1385         xcvr->dma_prms_tx.chan_name = "tx";
1386         xcvr->dma_prms_rx.addr = rx_res->start;
1387         xcvr->dma_prms_tx.addr = tx_res->start;
1388         xcvr->dma_prms_rx.maxburst = FSL_XCVR_MAXBURST_RX;
1389         xcvr->dma_prms_tx.maxburst = FSL_XCVR_MAXBURST_TX;
1390 
1391         platform_set_drvdata(pdev, xcvr);
1392         pm_runtime_enable(dev);
1393         regcache_cache_only(xcvr->regmap, true);
1394 
1395         /*
1396          * Register platform component before registering cpu dai for there
1397          * is not defer probe for platform component in snd_soc_add_pcm_runtime().
1398          */
1399         ret = devm_snd_dmaengine_pcm_register(dev, NULL, 0);
1400         if (ret) {
1401                 pm_runtime_disable(dev);
1402                 dev_err(dev, "failed to pcm register\n");
1403                 return ret;
1404         }
1405 
1406         ret = devm_snd_soc_register_component(dev, &fsl_xcvr_comp,
1407                                               &fsl_xcvr_dai, 1);
1408         if (ret) {
1409                 pm_runtime_disable(dev);
1410                 dev_err(dev, "failed to register component %s\n",
1411                         fsl_xcvr_comp.name);
1412         }
1413 
1414         return ret;
1415 }
1416 
1417 static void fsl_xcvr_remove(struct platform_device *pdev)
1418 {
1419         pm_runtime_disable(&pdev->dev);
1420 }
1421 
1422 static int fsl_xcvr_runtime_suspend(struct device *dev)
1423 {
1424         struct fsl_xcvr *xcvr = dev_get_drvdata(dev);
1425         int ret;
1426 
1427         if (!xcvr->soc_data->spdif_only) {
1428                 /* Assert M0+ reset */
1429                 ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_CTRL,
1430                                         FSL_XCVR_EXT_CTRL_CORE_RESET,
1431                                         FSL_XCVR_EXT_CTRL_CORE_RESET);
1432                 if (ret < 0)
1433                         dev_err(dev, "Failed to assert M0+ core: %d\n", ret);
1434         }
1435 
1436         regcache_cache_only(xcvr->regmap, true);
1437 
1438         clk_disable_unprepare(xcvr->spba_clk);
1439         clk_disable_unprepare(xcvr->phy_clk);
1440         clk_disable_unprepare(xcvr->pll_ipg_clk);
1441         clk_disable_unprepare(xcvr->ipg_clk);
1442 
1443         return 0;
1444 }
1445 
1446 static int fsl_xcvr_runtime_resume(struct device *dev)
1447 {
1448         struct fsl_xcvr *xcvr = dev_get_drvdata(dev);
1449         int ret;
1450 
1451         ret = reset_control_assert(xcvr->reset);
1452         if (ret < 0) {
1453                 dev_err(dev, "Failed to assert M0+ reset: %d\n", ret);
1454                 return ret;
1455         }
1456 
1457         ret = clk_prepare_enable(xcvr->ipg_clk);
1458         if (ret) {
1459                 dev_err(dev, "failed to start IPG clock.\n");
1460                 return ret;
1461         }
1462 
1463         ret = clk_prepare_enable(xcvr->pll_ipg_clk);
1464         if (ret) {
1465                 dev_err(dev, "failed to start PLL IPG clock.\n");
1466                 goto stop_ipg_clk;
1467         }
1468 
1469         ret = clk_prepare_enable(xcvr->phy_clk);
1470         if (ret) {
1471                 dev_err(dev, "failed to start PHY clock: %d\n", ret);
1472                 goto stop_pll_ipg_clk;
1473         }
1474 
1475         ret = clk_prepare_enable(xcvr->spba_clk);
1476         if (ret) {
1477                 dev_err(dev, "failed to start SPBA clock.\n");
1478                 goto stop_phy_clk;
1479         }
1480 
1481         regcache_cache_only(xcvr->regmap, false);
1482         regcache_mark_dirty(xcvr->regmap);
1483         ret = regcache_sync(xcvr->regmap);
1484 
1485         if (ret) {
1486                 dev_err(dev, "failed to sync regcache.\n");
1487                 goto stop_spba_clk;
1488         }
1489 
1490         if (xcvr->soc_data->spdif_only)
1491                 return 0;
1492 
1493         ret = reset_control_deassert(xcvr->reset);
1494         if (ret) {
1495                 dev_err(dev, "failed to deassert M0+ reset.\n");
1496                 goto stop_spba_clk;
1497         }
1498 
1499         ret = fsl_xcvr_load_firmware(xcvr);
1500         if (ret) {
1501                 dev_err(dev, "failed to load firmware.\n");
1502                 goto stop_spba_clk;
1503         }
1504 
1505         /* Release M0+ reset */
1506         ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_CTRL,
1507                                  FSL_XCVR_EXT_CTRL_CORE_RESET, 0);
1508         if (ret < 0) {
1509                 dev_err(dev, "M0+ core release failed: %d\n", ret);
1510                 goto stop_spba_clk;
1511         }
1512 
1513         /* Let M0+ core complete firmware initialization */
1514         msleep(50);
1515 
1516         return 0;
1517 
1518 stop_spba_clk:
1519         clk_disable_unprepare(xcvr->spba_clk);
1520 stop_phy_clk:
1521         clk_disable_unprepare(xcvr->phy_clk);
1522 stop_pll_ipg_clk:
1523         clk_disable_unprepare(xcvr->pll_ipg_clk);
1524 stop_ipg_clk:
1525         clk_disable_unprepare(xcvr->ipg_clk);
1526 
1527         return ret;
1528 }
1529 
1530 static const struct dev_pm_ops fsl_xcvr_pm_ops = {
1531         RUNTIME_PM_OPS(fsl_xcvr_runtime_suspend, fsl_xcvr_runtime_resume, NULL)
1532         SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
1533                                 pm_runtime_force_resume)
1534 };
1535 
1536 static struct platform_driver fsl_xcvr_driver = {
1537         .probe = fsl_xcvr_probe,
1538         .driver = {
1539                 .name = "fsl,imx8mp-audio-xcvr",
1540                 .pm = pm_ptr(&fsl_xcvr_pm_ops),
1541                 .of_match_table = fsl_xcvr_dt_ids,
1542         },
1543         .remove_new = fsl_xcvr_remove,
1544 };
1545 module_platform_driver(fsl_xcvr_driver);
1546 
1547 MODULE_AUTHOR("Viorel Suman <viorel.suman@nxp.com>");
1548 MODULE_DESCRIPTION("NXP Audio Transceiver (XCVR) driver");
1549 MODULE_LICENSE("GPL v2");
1550 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php