adau7118.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586
  1. // SPDX-License-Identifier: GPL-2.0
  2. //
  3. // Analog Devices ADAU7118 8 channel PDM-to-I2S/TDM Converter driver
  4. //
  5. // Copyright 2019 Analog Devices Inc.
  6. #include <linux/bitfield.h>
  7. #include <linux/module.h>
  8. #include <linux/regmap.h>
  9. #include <linux/regulator/consumer.h>
  10. #include <sound/pcm_params.h>
  11. #include <sound/soc.h>
  12. #include "adau7118.h"
  13. #define ADAU7118_DEC_RATIO_MASK GENMASK(1, 0)
  14. #define ADAU7118_DEC_RATIO(x) FIELD_PREP(ADAU7118_DEC_RATIO_MASK, x)
  15. #define ADAU7118_CLK_MAP_MASK GENMASK(7, 4)
  16. #define ADAU7118_SLOT_WIDTH_MASK GENMASK(5, 4)
  17. #define ADAU7118_SLOT_WIDTH(x) FIELD_PREP(ADAU7118_SLOT_WIDTH_MASK, x)
  18. #define ADAU7118_TRISTATE_MASK BIT(6)
  19. #define ADAU7118_TRISTATE(x) FIELD_PREP(ADAU7118_TRISTATE_MASK, x)
  20. #define ADAU7118_DATA_FMT_MASK GENMASK(3, 1)
  21. #define ADAU7118_DATA_FMT(x) FIELD_PREP(ADAU7118_DATA_FMT_MASK, x)
  22. #define ADAU7118_SAI_MODE_MASK BIT(0)
  23. #define ADAU7118_SAI_MODE(x) FIELD_PREP(ADAU7118_SAI_MODE_MASK, x)
  24. #define ADAU7118_LRCLK_BCLK_POL_MASK GENMASK(1, 0)
  25. #define ADAU7118_LRCLK_BCLK_POL(x) \
  26. FIELD_PREP(ADAU7118_LRCLK_BCLK_POL_MASK, x)
  27. #define ADAU7118_SPT_SLOT_MASK GENMASK(7, 4)
  28. #define ADAU7118_SPT_SLOT(x) FIELD_PREP(ADAU7118_SPT_SLOT_MASK, x)
  29. #define ADAU7118_FULL_SOFT_R_MASK BIT(1)
  30. #define ADAU7118_FULL_SOFT_R(x) FIELD_PREP(ADAU7118_FULL_SOFT_R_MASK, x)
  31. struct adau7118_data {
  32. struct regmap *map;
  33. struct device *dev;
  34. struct regulator *iovdd;
  35. struct regulator *dvdd;
  36. u32 slot_width;
  37. u32 slots;
  38. bool hw_mode;
  39. bool right_j;
  40. };
  41. /* Input Enable */
  42. static const struct snd_kcontrol_new adau7118_dapm_pdm_control[4] = {
  43. SOC_DAPM_SINGLE("Capture Switch", ADAU7118_REG_ENABLES, 0, 1, 0),
  44. SOC_DAPM_SINGLE("Capture Switch", ADAU7118_REG_ENABLES, 1, 1, 0),
  45. SOC_DAPM_SINGLE("Capture Switch", ADAU7118_REG_ENABLES, 2, 1, 0),
  46. SOC_DAPM_SINGLE("Capture Switch", ADAU7118_REG_ENABLES, 3, 1, 0),
  47. };
  48. static const struct snd_soc_dapm_widget adau7118_widgets_sw[] = {
  49. /* Input Enable Switches */
  50. SND_SOC_DAPM_SWITCH("PDM0", SND_SOC_NOPM, 0, 0,
  51. &adau7118_dapm_pdm_control[0]),
  52. SND_SOC_DAPM_SWITCH("PDM1", SND_SOC_NOPM, 0, 0,
  53. &adau7118_dapm_pdm_control[1]),
  54. SND_SOC_DAPM_SWITCH("PDM2", SND_SOC_NOPM, 0, 0,
  55. &adau7118_dapm_pdm_control[2]),
  56. SND_SOC_DAPM_SWITCH("PDM3", SND_SOC_NOPM, 0, 0,
  57. &adau7118_dapm_pdm_control[3]),
  58. /* PDM Clocks */
  59. SND_SOC_DAPM_SUPPLY("PDM_CLK0", ADAU7118_REG_ENABLES, 4, 0, NULL, 0),
  60. SND_SOC_DAPM_SUPPLY("PDM_CLK1", ADAU7118_REG_ENABLES, 5, 0, NULL, 0),
  61. /* Output channels */
  62. SND_SOC_DAPM_AIF_OUT("AIF1TX1", "Capture", 0, ADAU7118_REG_SPT_CX(0),
  63. 0, 0),
  64. SND_SOC_DAPM_AIF_OUT("AIF1TX2", "Capture", 0, ADAU7118_REG_SPT_CX(1),
  65. 0, 0),
  66. SND_SOC_DAPM_AIF_OUT("AIF1TX3", "Capture", 0, ADAU7118_REG_SPT_CX(2),
  67. 0, 0),
  68. SND_SOC_DAPM_AIF_OUT("AIF1TX4", "Capture", 0, ADAU7118_REG_SPT_CX(3),
  69. 0, 0),
  70. SND_SOC_DAPM_AIF_OUT("AIF1TX5", "Capture", 0, ADAU7118_REG_SPT_CX(4),
  71. 0, 0),
  72. SND_SOC_DAPM_AIF_OUT("AIF1TX6", "Capture", 0, ADAU7118_REG_SPT_CX(5),
  73. 0, 0),
  74. SND_SOC_DAPM_AIF_OUT("AIF1TX7", "Capture", 0, ADAU7118_REG_SPT_CX(6),
  75. 0, 0),
  76. SND_SOC_DAPM_AIF_OUT("AIF1TX8", "Capture", 0, ADAU7118_REG_SPT_CX(7),
  77. 0, 0),
  78. };
  79. static const struct snd_soc_dapm_route adau7118_routes_sw[] = {
  80. { "PDM0", "Capture Switch", "PDM_DAT0" },
  81. { "PDM1", "Capture Switch", "PDM_DAT1" },
  82. { "PDM2", "Capture Switch", "PDM_DAT2" },
  83. { "PDM3", "Capture Switch", "PDM_DAT3" },
  84. { "AIF1TX1", NULL, "PDM0" },
  85. { "AIF1TX2", NULL, "PDM0" },
  86. { "AIF1TX3", NULL, "PDM1" },
  87. { "AIF1TX4", NULL, "PDM1" },
  88. { "AIF1TX5", NULL, "PDM2" },
  89. { "AIF1TX6", NULL, "PDM2" },
  90. { "AIF1TX7", NULL, "PDM3" },
  91. { "AIF1TX8", NULL, "PDM3" },
  92. { "Capture", NULL, "PDM_CLK0" },
  93. { "Capture", NULL, "PDM_CLK1" },
  94. };
  95. static const struct snd_soc_dapm_widget adau7118_widgets_hw[] = {
  96. SND_SOC_DAPM_AIF_OUT("AIF1TX", "Capture", 0, SND_SOC_NOPM, 0, 0),
  97. };
  98. static const struct snd_soc_dapm_route adau7118_routes_hw[] = {
  99. { "AIF1TX", NULL, "PDM_DAT0" },
  100. { "AIF1TX", NULL, "PDM_DAT1" },
  101. { "AIF1TX", NULL, "PDM_DAT2" },
  102. { "AIF1TX", NULL, "PDM_DAT3" },
  103. };
  104. static const struct snd_soc_dapm_widget adau7118_widgets[] = {
  105. SND_SOC_DAPM_INPUT("PDM_DAT0"),
  106. SND_SOC_DAPM_INPUT("PDM_DAT1"),
  107. SND_SOC_DAPM_INPUT("PDM_DAT2"),
  108. SND_SOC_DAPM_INPUT("PDM_DAT3"),
  109. };
  110. static int adau7118_set_channel_map(struct snd_soc_dai *dai,
  111. unsigned int tx_num, unsigned int *tx_slot,
  112. unsigned int rx_num, unsigned int *rx_slot)
  113. {
  114. struct adau7118_data *st =
  115. snd_soc_component_get_drvdata(dai->component);
  116. int chan, ret;
  117. dev_dbg(st->dev, "Set channel map, %d", tx_num);
  118. for (chan = 0; chan < tx_num; chan++) {
  119. ret = snd_soc_component_update_bits(dai->component,
  120. ADAU7118_REG_SPT_CX(chan),
  121. ADAU7118_SPT_SLOT_MASK,
  122. ADAU7118_SPT_SLOT(tx_slot[chan]));
  123. if (ret < 0)
  124. return ret;
  125. }
  126. return 0;
  127. }
  128. static int adau7118_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
  129. {
  130. struct adau7118_data *st =
  131. snd_soc_component_get_drvdata(dai->component);
  132. int ret = 0;
  133. u32 regval;
  134. dev_dbg(st->dev, "Set format, fmt:%d\n", fmt);
  135. switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
  136. case SND_SOC_DAIFMT_I2S:
  137. ret = snd_soc_component_update_bits(dai->component,
  138. ADAU7118_REG_SPT_CTRL1,
  139. ADAU7118_DATA_FMT_MASK,
  140. ADAU7118_DATA_FMT(0));
  141. break;
  142. case SND_SOC_DAIFMT_LEFT_J:
  143. ret = snd_soc_component_update_bits(dai->component,
  144. ADAU7118_REG_SPT_CTRL1,
  145. ADAU7118_DATA_FMT_MASK,
  146. ADAU7118_DATA_FMT(1));
  147. break;
  148. case SND_SOC_DAIFMT_RIGHT_J:
  149. st->right_j = true;
  150. break;
  151. default:
  152. dev_err(st->dev, "Invalid format %d",
  153. fmt & SND_SOC_DAIFMT_FORMAT_MASK);
  154. return -EINVAL;
  155. }
  156. if (ret < 0)
  157. return ret;
  158. switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
  159. case SND_SOC_DAIFMT_NB_NF:
  160. regval = ADAU7118_LRCLK_BCLK_POL(0);
  161. break;
  162. case SND_SOC_DAIFMT_NB_IF:
  163. regval = ADAU7118_LRCLK_BCLK_POL(2);
  164. break;
  165. case SND_SOC_DAIFMT_IB_NF:
  166. regval = ADAU7118_LRCLK_BCLK_POL(1);
  167. break;
  168. case SND_SOC_DAIFMT_IB_IF:
  169. regval = ADAU7118_LRCLK_BCLK_POL(3);
  170. break;
  171. default:
  172. dev_err(st->dev, "Invalid Inv mask %d",
  173. fmt & SND_SOC_DAIFMT_INV_MASK);
  174. return -EINVAL;
  175. }
  176. ret = snd_soc_component_update_bits(dai->component,
  177. ADAU7118_REG_SPT_CTRL2,
  178. ADAU7118_LRCLK_BCLK_POL_MASK,
  179. regval);
  180. if (ret < 0)
  181. return ret;
  182. return 0;
  183. }
  184. static int adau7118_set_tristate(struct snd_soc_dai *dai, int tristate)
  185. {
  186. struct adau7118_data *st =
  187. snd_soc_component_get_drvdata(dai->component);
  188. int ret;
  189. dev_dbg(st->dev, "Set tristate, %d\n", tristate);
  190. ret = snd_soc_component_update_bits(dai->component,
  191. ADAU7118_REG_SPT_CTRL1,
  192. ADAU7118_TRISTATE_MASK,
  193. ADAU7118_TRISTATE(tristate));
  194. if (ret < 0)
  195. return ret;
  196. return 0;
  197. }
  198. static int adau7118_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
  199. unsigned int rx_mask, int slots,
  200. int slot_width)
  201. {
  202. struct adau7118_data *st =
  203. snd_soc_component_get_drvdata(dai->component);
  204. int ret = 0;
  205. u32 regval;
  206. dev_dbg(st->dev, "Set tdm, slots:%d width:%d\n", slots, slot_width);
  207. switch (slot_width) {
  208. case 32:
  209. regval = ADAU7118_SLOT_WIDTH(0);
  210. break;
  211. case 24:
  212. regval = ADAU7118_SLOT_WIDTH(2);
  213. break;
  214. case 16:
  215. regval = ADAU7118_SLOT_WIDTH(1);
  216. break;
  217. default:
  218. dev_err(st->dev, "Invalid slot width:%d\n", slot_width);
  219. return -EINVAL;
  220. }
  221. ret = snd_soc_component_update_bits(dai->component,
  222. ADAU7118_REG_SPT_CTRL1,
  223. ADAU7118_SLOT_WIDTH_MASK, regval);
  224. if (ret < 0)
  225. return ret;
  226. st->slot_width = slot_width;
  227. st->slots = slots;
  228. return 0;
  229. }
  230. static int adau7118_hw_params(struct snd_pcm_substream *substream,
  231. struct snd_pcm_hw_params *params,
  232. struct snd_soc_dai *dai)
  233. {
  234. struct adau7118_data *st =
  235. snd_soc_component_get_drvdata(dai->component);
  236. u32 data_width = params_width(params), slots_width;
  237. int ret;
  238. u32 regval;
  239. if (!st->slots) {
  240. /* set stereo mode */
  241. ret = snd_soc_component_update_bits(dai->component,
  242. ADAU7118_REG_SPT_CTRL1,
  243. ADAU7118_SAI_MODE_MASK,
  244. ADAU7118_SAI_MODE(0));
  245. if (ret < 0)
  246. return ret;
  247. slots_width = 32;
  248. } else {
  249. slots_width = st->slot_width;
  250. }
  251. if (data_width > slots_width) {
  252. dev_err(st->dev, "Invalid data_width:%d, slots_width:%d",
  253. data_width, slots_width);
  254. return -EINVAL;
  255. }
  256. if (st->right_j) {
  257. switch (slots_width - data_width) {
  258. case 8:
  259. /* delay bclck by 8 */
  260. regval = ADAU7118_DATA_FMT(2);
  261. break;
  262. case 12:
  263. /* delay bclck by 12 */
  264. regval = ADAU7118_DATA_FMT(3);
  265. break;
  266. case 16:
  267. /* delay bclck by 16 */
  268. regval = ADAU7118_DATA_FMT(4);
  269. break;
  270. default:
  271. dev_err(st->dev,
  272. "Cannot set right_j setting, slot_w:%d, data_w:%d\n",
  273. slots_width, data_width);
  274. return -EINVAL;
  275. }
  276. ret = snd_soc_component_update_bits(dai->component,
  277. ADAU7118_REG_SPT_CTRL1,
  278. ADAU7118_DATA_FMT_MASK,
  279. regval);
  280. if (ret < 0)
  281. return ret;
  282. }
  283. return 0;
  284. }
  285. static int adau7118_set_bias_level(struct snd_soc_component *component,
  286. enum snd_soc_bias_level level)
  287. {
  288. struct adau7118_data *st = snd_soc_component_get_drvdata(component);
  289. int ret = 0;
  290. dev_dbg(st->dev, "Set bias level %d\n", level);
  291. switch (level) {
  292. case SND_SOC_BIAS_ON:
  293. case SND_SOC_BIAS_PREPARE:
  294. break;
  295. case SND_SOC_BIAS_STANDBY:
  296. if (snd_soc_component_get_bias_level(component) ==
  297. SND_SOC_BIAS_OFF) {
  298. /* power on */
  299. ret = regulator_enable(st->iovdd);
  300. if (ret)
  301. return ret;
  302. /* there's no timing constraints before enabling dvdd */
  303. ret = regulator_enable(st->dvdd);
  304. if (ret) {
  305. regulator_disable(st->iovdd);
  306. return ret;
  307. }
  308. if (st->hw_mode)
  309. return 0;
  310. regcache_cache_only(st->map, false);
  311. /* sync cache */
  312. ret = snd_soc_component_cache_sync(component);
  313. }
  314. break;
  315. case SND_SOC_BIAS_OFF:
  316. /* power off */
  317. ret = regulator_disable(st->dvdd);
  318. if (ret)
  319. return ret;
  320. ret = regulator_disable(st->iovdd);
  321. if (ret)
  322. return ret;
  323. if (st->hw_mode)
  324. return 0;
  325. /* cache only */
  326. regcache_mark_dirty(st->map);
  327. regcache_cache_only(st->map, true);
  328. break;
  329. }
  330. return ret;
  331. }
  332. static int adau7118_component_probe(struct snd_soc_component *component)
  333. {
  334. struct adau7118_data *st = snd_soc_component_get_drvdata(component);
  335. struct snd_soc_dapm_context *dapm =
  336. snd_soc_component_get_dapm(component);
  337. int ret = 0;
  338. if (st->hw_mode) {
  339. ret = snd_soc_dapm_new_controls(dapm, adau7118_widgets_hw,
  340. ARRAY_SIZE(adau7118_widgets_hw));
  341. if (ret)
  342. return ret;
  343. ret = snd_soc_dapm_add_routes(dapm, adau7118_routes_hw,
  344. ARRAY_SIZE(adau7118_routes_hw));
  345. } else {
  346. snd_soc_component_init_regmap(component, st->map);
  347. ret = snd_soc_dapm_new_controls(dapm, adau7118_widgets_sw,
  348. ARRAY_SIZE(adau7118_widgets_sw));
  349. if (ret)
  350. return ret;
  351. ret = snd_soc_dapm_add_routes(dapm, adau7118_routes_sw,
  352. ARRAY_SIZE(adau7118_routes_sw));
  353. }
  354. return ret;
  355. }
  356. static const struct snd_soc_dai_ops adau7118_ops = {
  357. .hw_params = adau7118_hw_params,
  358. .set_channel_map = adau7118_set_channel_map,
  359. .set_fmt = adau7118_set_fmt,
  360. .set_tdm_slot = adau7118_set_tdm_slot,
  361. .set_tristate = adau7118_set_tristate,
  362. };
  363. static struct snd_soc_dai_driver adau7118_dai = {
  364. .name = "adau7118-hifi-capture",
  365. .capture = {
  366. .stream_name = "Capture",
  367. .channels_min = 1,
  368. .channels_max = 8,
  369. .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |
  370. SNDRV_PCM_FMTBIT_S20_LE | SNDRV_PCM_FMTBIT_S24_LE |
  371. SNDRV_PCM_FMTBIT_S24_3LE,
  372. .rates = SNDRV_PCM_RATE_CONTINUOUS,
  373. .rate_min = 4000,
  374. .rate_max = 192000,
  375. .sig_bits = 24,
  376. },
  377. };
  378. static const struct snd_soc_component_driver adau7118_component_driver = {
  379. .probe = adau7118_component_probe,
  380. .set_bias_level = adau7118_set_bias_level,
  381. .dapm_widgets = adau7118_widgets,
  382. .num_dapm_widgets = ARRAY_SIZE(adau7118_widgets),
  383. .use_pmdown_time = 1,
  384. .endianness = 1,
  385. .non_legacy_dai_naming = 1,
  386. };
  387. static void adau7118_regulator_disable(void *data)
  388. {
  389. struct adau7118_data *st = data;
  390. int ret;
  391. /*
  392. * If we fail to disable DVDD, don't bother in trying IOVDD. We
  393. * actually don't want to be left in the situation where DVDD
  394. * is enabled and IOVDD is disabled.
  395. */
  396. ret = regulator_disable(st->dvdd);
  397. if (ret)
  398. return;
  399. regulator_disable(st->iovdd);
  400. }
  401. static int adau7118_regulator_setup(struct adau7118_data *st)
  402. {
  403. st->iovdd = devm_regulator_get(st->dev, "iovdd");
  404. if (IS_ERR(st->iovdd)) {
  405. dev_err(st->dev, "Could not get iovdd: %ld\n",
  406. PTR_ERR(st->iovdd));
  407. return PTR_ERR(st->iovdd);
  408. }
  409. st->dvdd = devm_regulator_get(st->dev, "dvdd");
  410. if (IS_ERR(st->dvdd)) {
  411. dev_err(st->dev, "Could not get dvdd: %ld\n",
  412. PTR_ERR(st->dvdd));
  413. return PTR_ERR(st->dvdd);
  414. }
  415. /* just assume the device is in reset */
  416. if (!st->hw_mode) {
  417. regcache_mark_dirty(st->map);
  418. regcache_cache_only(st->map, true);
  419. }
  420. return devm_add_action_or_reset(st->dev, adau7118_regulator_disable,
  421. st);
  422. }
  423. static int adau7118_parset_dt(const struct adau7118_data *st)
  424. {
  425. int ret;
  426. u32 dec_ratio = 0;
  427. /* 4 inputs */
  428. u32 clk_map[4], regval;
  429. if (st->hw_mode)
  430. return 0;
  431. ret = device_property_read_u32(st->dev, "adi,decimation-ratio",
  432. &dec_ratio);
  433. if (!ret) {
  434. switch (dec_ratio) {
  435. case 64:
  436. regval = ADAU7118_DEC_RATIO(0);
  437. break;
  438. case 32:
  439. regval = ADAU7118_DEC_RATIO(1);
  440. break;
  441. case 16:
  442. regval = ADAU7118_DEC_RATIO(2);
  443. break;
  444. default:
  445. dev_err(st->dev, "Invalid dec ratio: %u", dec_ratio);
  446. return -EINVAL;
  447. }
  448. ret = regmap_update_bits(st->map,
  449. ADAU7118_REG_DEC_RATIO_CLK_MAP,
  450. ADAU7118_DEC_RATIO_MASK, regval);
  451. if (ret)
  452. return ret;
  453. }
  454. ret = device_property_read_u32_array(st->dev, "adi,pdm-clk-map",
  455. clk_map, ARRAY_SIZE(clk_map));
  456. if (!ret) {
  457. int pdm;
  458. u32 _clk_map = 0;
  459. for (pdm = 0; pdm < ARRAY_SIZE(clk_map); pdm++)
  460. _clk_map |= (clk_map[pdm] << (pdm + 4));
  461. ret = regmap_update_bits(st->map,
  462. ADAU7118_REG_DEC_RATIO_CLK_MAP,
  463. ADAU7118_CLK_MAP_MASK, _clk_map);
  464. if (ret)
  465. return ret;
  466. }
  467. return 0;
  468. }
  469. int adau7118_probe(struct device *dev, struct regmap *map, bool hw_mode)
  470. {
  471. struct adau7118_data *st;
  472. int ret;
  473. st = devm_kzalloc(dev, sizeof(*st), GFP_KERNEL);
  474. if (!st)
  475. return -ENOMEM;
  476. st->dev = dev;
  477. st->hw_mode = hw_mode;
  478. dev_set_drvdata(dev, st);
  479. if (!hw_mode) {
  480. st->map = map;
  481. adau7118_dai.ops = &adau7118_ops;
  482. /*
  483. * Perform a full soft reset. This will set all register's
  484. * with their reset values.
  485. */
  486. ret = regmap_update_bits(map, ADAU7118_REG_RESET,
  487. ADAU7118_FULL_SOFT_R_MASK,
  488. ADAU7118_FULL_SOFT_R(1));
  489. if (ret)
  490. return ret;
  491. }
  492. ret = adau7118_parset_dt(st);
  493. if (ret)
  494. return ret;
  495. ret = adau7118_regulator_setup(st);
  496. if (ret)
  497. return ret;
  498. return devm_snd_soc_register_component(dev,
  499. &adau7118_component_driver,
  500. &adau7118_dai, 1);
  501. }
  502. EXPORT_SYMBOL_GPL(adau7118_probe);
  503. MODULE_AUTHOR("Nuno Sa <nuno.sa@analog.com>");
  504. MODULE_DESCRIPTION("ADAU7118 8 channel PDM-to-I2S/TDM Converter driver");
  505. MODULE_LICENSE("GPL");