ad193x.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * AD193X Audio Codec driver supporting AD1936/7/8/9
  4. *
  5. * Copyright 2010 Analog Devices Inc.
  6. */
  7. #include <linux/module.h>
  8. #include <linux/kernel.h>
  9. #include <linux/device.h>
  10. #include <linux/regmap.h>
  11. #include <linux/slab.h>
  12. #include <sound/core.h>
  13. #include <sound/pcm.h>
  14. #include <sound/pcm_params.h>
  15. #include <sound/initval.h>
  16. #include <sound/soc.h>
  17. #include <sound/tlv.h>
  18. #include "ad193x.h"
  19. /* codec private data */
  20. struct ad193x_priv {
  21. struct regmap *regmap;
  22. enum ad193x_type type;
  23. int sysclk;
  24. };
  25. /*
  26. * AD193X volume/mute/de-emphasis etc. controls
  27. */
  28. static const char * const ad193x_deemp[] = {"None", "48kHz", "44.1kHz", "32kHz"};
  29. static SOC_ENUM_SINGLE_DECL(ad193x_deemp_enum, AD193X_DAC_CTRL2, 1,
  30. ad193x_deemp);
  31. static const DECLARE_TLV_DB_MINMAX(adau193x_tlv, -9563, 0);
  32. static const unsigned int ad193x_sb[] = {32};
  33. static struct snd_pcm_hw_constraint_list constr = {
  34. .list = ad193x_sb,
  35. .count = ARRAY_SIZE(ad193x_sb),
  36. };
  37. static const struct snd_kcontrol_new ad193x_snd_controls[] = {
  38. /* DAC volume control */
  39. SOC_DOUBLE_R_TLV("DAC1 Volume", AD193X_DAC_L1_VOL,
  40. AD193X_DAC_R1_VOL, 0, 0xFF, 1, adau193x_tlv),
  41. SOC_DOUBLE_R_TLV("DAC2 Volume", AD193X_DAC_L2_VOL,
  42. AD193X_DAC_R2_VOL, 0, 0xFF, 1, adau193x_tlv),
  43. SOC_DOUBLE_R_TLV("DAC3 Volume", AD193X_DAC_L3_VOL,
  44. AD193X_DAC_R3_VOL, 0, 0xFF, 1, adau193x_tlv),
  45. SOC_DOUBLE_R_TLV("DAC4 Volume", AD193X_DAC_L4_VOL,
  46. AD193X_DAC_R4_VOL, 0, 0xFF, 1, adau193x_tlv),
  47. /* DAC switch control */
  48. SOC_DOUBLE("DAC1 Switch", AD193X_DAC_CHNL_MUTE, AD193X_DACL1_MUTE,
  49. AD193X_DACR1_MUTE, 1, 1),
  50. SOC_DOUBLE("DAC2 Switch", AD193X_DAC_CHNL_MUTE, AD193X_DACL2_MUTE,
  51. AD193X_DACR2_MUTE, 1, 1),
  52. SOC_DOUBLE("DAC3 Switch", AD193X_DAC_CHNL_MUTE, AD193X_DACL3_MUTE,
  53. AD193X_DACR3_MUTE, 1, 1),
  54. SOC_DOUBLE("DAC4 Switch", AD193X_DAC_CHNL_MUTE, AD193X_DACL4_MUTE,
  55. AD193X_DACR4_MUTE, 1, 1),
  56. /* DAC de-emphasis */
  57. SOC_ENUM("Playback Deemphasis", ad193x_deemp_enum),
  58. };
  59. static const struct snd_kcontrol_new ad193x_adc_snd_controls[] = {
  60. /* ADC switch control */
  61. SOC_DOUBLE("ADC1 Switch", AD193X_ADC_CTRL0, AD193X_ADCL1_MUTE,
  62. AD193X_ADCR1_MUTE, 1, 1),
  63. SOC_DOUBLE("ADC2 Switch", AD193X_ADC_CTRL0, AD193X_ADCL2_MUTE,
  64. AD193X_ADCR2_MUTE, 1, 1),
  65. /* ADC high-pass filter */
  66. SOC_SINGLE("ADC High Pass Filter Switch", AD193X_ADC_CTRL0,
  67. AD193X_ADC_HIGHPASS_FILTER, 1, 0),
  68. };
  69. static const struct snd_soc_dapm_widget ad193x_dapm_widgets[] = {
  70. SND_SOC_DAPM_DAC("DAC", "Playback", SND_SOC_NOPM, 0, 0),
  71. SND_SOC_DAPM_PGA("DAC Output", AD193X_DAC_CTRL0, 0, 1, NULL, 0),
  72. SND_SOC_DAPM_SUPPLY("PLL_PWR", AD193X_PLL_CLK_CTRL0, 0, 1, NULL, 0),
  73. SND_SOC_DAPM_SUPPLY("SYSCLK", AD193X_PLL_CLK_CTRL0, 7, 0, NULL, 0),
  74. SND_SOC_DAPM_VMID("VMID"),
  75. SND_SOC_DAPM_OUTPUT("DAC1OUT"),
  76. SND_SOC_DAPM_OUTPUT("DAC2OUT"),
  77. SND_SOC_DAPM_OUTPUT("DAC3OUT"),
  78. SND_SOC_DAPM_OUTPUT("DAC4OUT"),
  79. };
  80. static const struct snd_soc_dapm_widget ad193x_adc_widgets[] = {
  81. SND_SOC_DAPM_ADC("ADC", "Capture", SND_SOC_NOPM, 0, 0),
  82. SND_SOC_DAPM_SUPPLY("ADC_PWR", AD193X_ADC_CTRL0, 0, 1, NULL, 0),
  83. SND_SOC_DAPM_INPUT("ADC1IN"),
  84. SND_SOC_DAPM_INPUT("ADC2IN"),
  85. };
  86. static int ad193x_check_pll(struct snd_soc_dapm_widget *source,
  87. struct snd_soc_dapm_widget *sink)
  88. {
  89. struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
  90. struct ad193x_priv *ad193x = snd_soc_component_get_drvdata(component);
  91. return !!ad193x->sysclk;
  92. }
  93. static const struct snd_soc_dapm_route audio_paths[] = {
  94. { "DAC", NULL, "SYSCLK" },
  95. { "DAC Output", NULL, "DAC" },
  96. { "DAC Output", NULL, "VMID" },
  97. { "DAC1OUT", NULL, "DAC Output" },
  98. { "DAC2OUT", NULL, "DAC Output" },
  99. { "DAC3OUT", NULL, "DAC Output" },
  100. { "DAC4OUT", NULL, "DAC Output" },
  101. { "SYSCLK", NULL, "PLL_PWR", &ad193x_check_pll },
  102. };
  103. static const struct snd_soc_dapm_route ad193x_adc_audio_paths[] = {
  104. { "ADC", NULL, "SYSCLK" },
  105. { "ADC", NULL, "ADC_PWR" },
  106. { "ADC", NULL, "ADC1IN" },
  107. { "ADC", NULL, "ADC2IN" },
  108. };
  109. static inline bool ad193x_has_adc(const struct ad193x_priv *ad193x)
  110. {
  111. switch (ad193x->type) {
  112. case AD1933:
  113. case AD1934:
  114. return false;
  115. default:
  116. break;
  117. }
  118. return true;
  119. }
  120. /*
  121. * DAI ops entries
  122. */
  123. static int ad193x_mute(struct snd_soc_dai *dai, int mute, int direction)
  124. {
  125. struct ad193x_priv *ad193x = snd_soc_component_get_drvdata(dai->component);
  126. if (mute)
  127. regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL2,
  128. AD193X_DAC_MASTER_MUTE,
  129. AD193X_DAC_MASTER_MUTE);
  130. else
  131. regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL2,
  132. AD193X_DAC_MASTER_MUTE, 0);
  133. return 0;
  134. }
  135. static int ad193x_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
  136. unsigned int rx_mask, int slots, int width)
  137. {
  138. struct ad193x_priv *ad193x = snd_soc_component_get_drvdata(dai->component);
  139. unsigned int channels;
  140. switch (slots) {
  141. case 2:
  142. channels = AD193X_2_CHANNELS;
  143. break;
  144. case 4:
  145. channels = AD193X_4_CHANNELS;
  146. break;
  147. case 8:
  148. channels = AD193X_8_CHANNELS;
  149. break;
  150. case 16:
  151. channels = AD193X_16_CHANNELS;
  152. break;
  153. default:
  154. return -EINVAL;
  155. }
  156. regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL1,
  157. AD193X_DAC_CHAN_MASK, channels << AD193X_DAC_CHAN_SHFT);
  158. if (ad193x_has_adc(ad193x))
  159. regmap_update_bits(ad193x->regmap, AD193X_ADC_CTRL2,
  160. AD193X_ADC_CHAN_MASK,
  161. channels << AD193X_ADC_CHAN_SHFT);
  162. return 0;
  163. }
  164. static int ad193x_set_dai_fmt(struct snd_soc_dai *codec_dai,
  165. unsigned int fmt)
  166. {
  167. struct ad193x_priv *ad193x = snd_soc_component_get_drvdata(codec_dai->component);
  168. unsigned int adc_serfmt = 0;
  169. unsigned int dac_serfmt = 0;
  170. unsigned int adc_fmt = 0;
  171. unsigned int dac_fmt = 0;
  172. /* At present, the driver only support AUX ADC mode(SND_SOC_DAIFMT_I2S
  173. * with TDM), ADC&DAC TDM mode(SND_SOC_DAIFMT_DSP_A) and DAC I2S mode
  174. * (SND_SOC_DAIFMT_I2S)
  175. */
  176. switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
  177. case SND_SOC_DAIFMT_I2S:
  178. adc_serfmt |= AD193X_ADC_SERFMT_TDM;
  179. dac_serfmt |= AD193X_DAC_SERFMT_STEREO;
  180. break;
  181. case SND_SOC_DAIFMT_DSP_A:
  182. adc_serfmt |= AD193X_ADC_SERFMT_AUX;
  183. dac_serfmt |= AD193X_DAC_SERFMT_TDM;
  184. break;
  185. default:
  186. if (ad193x_has_adc(ad193x))
  187. return -EINVAL;
  188. }
  189. switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
  190. case SND_SOC_DAIFMT_NB_NF: /* normal bit clock + frame */
  191. break;
  192. case SND_SOC_DAIFMT_NB_IF: /* normal bclk + invert frm */
  193. adc_fmt |= AD193X_ADC_LEFT_HIGH;
  194. dac_fmt |= AD193X_DAC_LEFT_HIGH;
  195. break;
  196. case SND_SOC_DAIFMT_IB_NF: /* invert bclk + normal frm */
  197. adc_fmt |= AD193X_ADC_BCLK_INV;
  198. dac_fmt |= AD193X_DAC_BCLK_INV;
  199. break;
  200. case SND_SOC_DAIFMT_IB_IF: /* invert bclk + frm */
  201. adc_fmt |= AD193X_ADC_LEFT_HIGH;
  202. adc_fmt |= AD193X_ADC_BCLK_INV;
  203. dac_fmt |= AD193X_DAC_LEFT_HIGH;
  204. dac_fmt |= AD193X_DAC_BCLK_INV;
  205. break;
  206. default:
  207. return -EINVAL;
  208. }
  209. /* For DSP_*, LRCLK's polarity must be inverted */
  210. if (fmt & SND_SOC_DAIFMT_DSP_A)
  211. dac_fmt ^= AD193X_DAC_LEFT_HIGH;
  212. switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
  213. case SND_SOC_DAIFMT_CBP_CFP:
  214. adc_fmt |= AD193X_ADC_LCR_MASTER;
  215. adc_fmt |= AD193X_ADC_BCLK_MASTER;
  216. dac_fmt |= AD193X_DAC_LCR_MASTER;
  217. dac_fmt |= AD193X_DAC_BCLK_MASTER;
  218. break;
  219. case SND_SOC_DAIFMT_CBC_CFP:
  220. adc_fmt |= AD193X_ADC_LCR_MASTER;
  221. dac_fmt |= AD193X_DAC_LCR_MASTER;
  222. break;
  223. case SND_SOC_DAIFMT_CBP_CFC:
  224. adc_fmt |= AD193X_ADC_BCLK_MASTER;
  225. dac_fmt |= AD193X_DAC_BCLK_MASTER;
  226. break;
  227. case SND_SOC_DAIFMT_CBC_CFC:
  228. break;
  229. default:
  230. return -EINVAL;
  231. }
  232. if (ad193x_has_adc(ad193x)) {
  233. regmap_update_bits(ad193x->regmap, AD193X_ADC_CTRL1,
  234. AD193X_ADC_SERFMT_MASK, adc_serfmt);
  235. regmap_update_bits(ad193x->regmap, AD193X_ADC_CTRL2,
  236. AD193X_ADC_FMT_MASK, adc_fmt);
  237. }
  238. regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL0,
  239. AD193X_DAC_SERFMT_MASK, dac_serfmt);
  240. regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL1,
  241. AD193X_DAC_FMT_MASK, dac_fmt);
  242. return 0;
  243. }
  244. static int ad193x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
  245. int clk_id, unsigned int freq, int dir)
  246. {
  247. struct snd_soc_component *component = codec_dai->component;
  248. struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
  249. struct ad193x_priv *ad193x = snd_soc_component_get_drvdata(component);
  250. if (clk_id == AD193X_SYSCLK_MCLK) {
  251. /* MCLK must be 512 x fs */
  252. if (dir == SND_SOC_CLOCK_OUT || freq != 24576000)
  253. return -EINVAL;
  254. regmap_update_bits(ad193x->regmap, AD193X_PLL_CLK_CTRL1,
  255. AD193X_PLL_SRC_MASK,
  256. AD193X_PLL_DAC_SRC_MCLK |
  257. AD193X_PLL_CLK_SRC_MCLK);
  258. snd_soc_dapm_sync(dapm);
  259. return 0;
  260. }
  261. switch (freq) {
  262. case 12288000:
  263. case 18432000:
  264. case 24576000:
  265. case 36864000:
  266. ad193x->sysclk = freq;
  267. return 0;
  268. }
  269. return -EINVAL;
  270. }
  271. static int ad193x_hw_params(struct snd_pcm_substream *substream,
  272. struct snd_pcm_hw_params *params,
  273. struct snd_soc_dai *dai)
  274. {
  275. int word_len = 0, master_rate = 0;
  276. struct snd_soc_component *component = dai->component;
  277. struct ad193x_priv *ad193x = snd_soc_component_get_drvdata(component);
  278. bool is_playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
  279. u8 dacc0;
  280. dev_dbg(dai->dev, "%s() rate=%u format=%#x width=%u channels=%u\n",
  281. __func__, params_rate(params), params_format(params),
  282. params_width(params), params_channels(params));
  283. /* bit size */
  284. switch (params_width(params)) {
  285. case 16:
  286. word_len = 3;
  287. break;
  288. case 20:
  289. word_len = 1;
  290. break;
  291. case 24:
  292. case 32:
  293. word_len = 0;
  294. break;
  295. }
  296. switch (ad193x->sysclk) {
  297. case 12288000:
  298. master_rate = AD193X_PLL_INPUT_256;
  299. break;
  300. case 18432000:
  301. master_rate = AD193X_PLL_INPUT_384;
  302. break;
  303. case 24576000:
  304. master_rate = AD193X_PLL_INPUT_512;
  305. break;
  306. case 36864000:
  307. master_rate = AD193X_PLL_INPUT_768;
  308. break;
  309. }
  310. if (is_playback) {
  311. switch (params_rate(params)) {
  312. case 48000:
  313. dacc0 = AD193X_DAC_SR_48;
  314. break;
  315. case 96000:
  316. dacc0 = AD193X_DAC_SR_96;
  317. break;
  318. case 192000:
  319. dacc0 = AD193X_DAC_SR_192;
  320. break;
  321. default:
  322. dev_err(dai->dev, "invalid sampling rate: %d\n", params_rate(params));
  323. return -EINVAL;
  324. }
  325. regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL0, AD193X_DAC_SR_MASK, dacc0);
  326. }
  327. regmap_update_bits(ad193x->regmap, AD193X_PLL_CLK_CTRL0,
  328. AD193X_PLL_INPUT_MASK, master_rate);
  329. regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL2,
  330. AD193X_DAC_WORD_LEN_MASK,
  331. word_len << AD193X_DAC_WORD_LEN_SHFT);
  332. if (ad193x_has_adc(ad193x))
  333. regmap_update_bits(ad193x->regmap, AD193X_ADC_CTRL1,
  334. AD193X_ADC_WORD_LEN_MASK, word_len);
  335. return 0;
  336. }
  337. static int ad193x_startup(struct snd_pcm_substream *substream,
  338. struct snd_soc_dai *dai)
  339. {
  340. return snd_pcm_hw_constraint_list(substream->runtime, 0,
  341. SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
  342. &constr);
  343. }
  344. static const struct snd_soc_dai_ops ad193x_dai_ops = {
  345. .startup = ad193x_startup,
  346. .hw_params = ad193x_hw_params,
  347. .mute_stream = ad193x_mute,
  348. .set_tdm_slot = ad193x_set_tdm_slot,
  349. .set_sysclk = ad193x_set_dai_sysclk,
  350. .set_fmt = ad193x_set_dai_fmt,
  351. .no_capture_mute = 1,
  352. };
  353. /* codec DAI instance */
  354. static struct snd_soc_dai_driver ad193x_dai = {
  355. .name = "ad193x-hifi",
  356. .playback = {
  357. .stream_name = "Playback",
  358. .channels_min = 2,
  359. .channels_max = 8,
  360. .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000,
  361. .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE |
  362. SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE,
  363. },
  364. .capture = {
  365. .stream_name = "Capture",
  366. .channels_min = 2,
  367. .channels_max = 4,
  368. .rates = SNDRV_PCM_RATE_48000,
  369. .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE |
  370. SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE,
  371. },
  372. .ops = &ad193x_dai_ops,
  373. };
  374. /* codec DAI instance for DAC only */
  375. static struct snd_soc_dai_driver ad193x_no_adc_dai = {
  376. .name = "ad193x-hifi",
  377. .playback = {
  378. .stream_name = "Playback",
  379. .channels_min = 2,
  380. .channels_max = 8,
  381. .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000,
  382. .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE |
  383. SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE,
  384. },
  385. .ops = &ad193x_dai_ops,
  386. };
  387. /* codec register values to set after reset */
  388. static void ad193x_reg_default_init(struct ad193x_priv *ad193x)
  389. {
  390. static const struct reg_sequence reg_init[] = {
  391. { 0, 0x99 }, /* PLL_CLK_CTRL0: pll input: mclki/xi 12.288Mhz */
  392. { 1, 0x04 }, /* PLL_CLK_CTRL1: no on-chip Vref */
  393. { 2, 0x40 }, /* DAC_CTRL0: TDM mode */
  394. { 3, 0x00 }, /* DAC_CTRL1: reset */
  395. { 4, 0x1A }, /* DAC_CTRL2: 48kHz de-emphasis, unmute dac */
  396. { 5, 0x00 }, /* DAC_CHNL_MUTE: unmute DAC channels */
  397. { 6, 0x00 }, /* DAC_L1_VOL: no attenuation */
  398. { 7, 0x00 }, /* DAC_R1_VOL: no attenuation */
  399. { 8, 0x00 }, /* DAC_L2_VOL: no attenuation */
  400. { 9, 0x00 }, /* DAC_R2_VOL: no attenuation */
  401. { 10, 0x00 }, /* DAC_L3_VOL: no attenuation */
  402. { 11, 0x00 }, /* DAC_R3_VOL: no attenuation */
  403. { 12, 0x00 }, /* DAC_L4_VOL: no attenuation */
  404. { 13, 0x00 }, /* DAC_R4_VOL: no attenuation */
  405. };
  406. static const struct reg_sequence reg_adc_init[] = {
  407. { 14, 0x03 }, /* ADC_CTRL0: high-pass filter enable */
  408. { 15, 0x43 }, /* ADC_CTRL1: sata delay=1, adc aux mode */
  409. { 16, 0x00 }, /* ADC_CTRL2: reset */
  410. };
  411. regmap_multi_reg_write(ad193x->regmap, reg_init, ARRAY_SIZE(reg_init));
  412. if (ad193x_has_adc(ad193x)) {
  413. regmap_multi_reg_write(ad193x->regmap, reg_adc_init,
  414. ARRAY_SIZE(reg_adc_init));
  415. }
  416. }
  417. static int ad193x_component_probe(struct snd_soc_component *component)
  418. {
  419. struct ad193x_priv *ad193x = snd_soc_component_get_drvdata(component);
  420. struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
  421. int num, ret;
  422. /* default setting for ad193x */
  423. ad193x_reg_default_init(ad193x);
  424. /* adc only */
  425. if (ad193x_has_adc(ad193x)) {
  426. /* add adc controls */
  427. num = ARRAY_SIZE(ad193x_adc_snd_controls);
  428. ret = snd_soc_add_component_controls(component,
  429. ad193x_adc_snd_controls,
  430. num);
  431. if (ret)
  432. return ret;
  433. /* add adc widgets */
  434. num = ARRAY_SIZE(ad193x_adc_widgets);
  435. ret = snd_soc_dapm_new_controls(dapm,
  436. ad193x_adc_widgets,
  437. num);
  438. if (ret)
  439. return ret;
  440. /* add adc routes */
  441. num = ARRAY_SIZE(ad193x_adc_audio_paths);
  442. ret = snd_soc_dapm_add_routes(dapm,
  443. ad193x_adc_audio_paths,
  444. num);
  445. if (ret)
  446. return ret;
  447. }
  448. return 0;
  449. }
  450. static const struct snd_soc_component_driver soc_component_dev_ad193x = {
  451. .probe = ad193x_component_probe,
  452. .controls = ad193x_snd_controls,
  453. .num_controls = ARRAY_SIZE(ad193x_snd_controls),
  454. .dapm_widgets = ad193x_dapm_widgets,
  455. .num_dapm_widgets = ARRAY_SIZE(ad193x_dapm_widgets),
  456. .dapm_routes = audio_paths,
  457. .num_dapm_routes = ARRAY_SIZE(audio_paths),
  458. .idle_bias_on = 1,
  459. .use_pmdown_time = 1,
  460. .endianness = 1,
  461. };
  462. const struct regmap_config ad193x_regmap_config = {
  463. .max_register = AD193X_NUM_REGS - 1,
  464. };
  465. EXPORT_SYMBOL_GPL(ad193x_regmap_config);
  466. int ad193x_probe(struct device *dev, struct regmap *regmap,
  467. enum ad193x_type type)
  468. {
  469. struct ad193x_priv *ad193x;
  470. if (IS_ERR(regmap))
  471. return PTR_ERR(regmap);
  472. ad193x = devm_kzalloc(dev, sizeof(*ad193x), GFP_KERNEL);
  473. if (ad193x == NULL)
  474. return -ENOMEM;
  475. ad193x->regmap = regmap;
  476. ad193x->type = type;
  477. dev_set_drvdata(dev, ad193x);
  478. if (ad193x_has_adc(ad193x))
  479. return devm_snd_soc_register_component(dev, &soc_component_dev_ad193x,
  480. &ad193x_dai, 1);
  481. return devm_snd_soc_register_component(dev, &soc_component_dev_ad193x,
  482. &ad193x_no_adc_dai, 1);
  483. }
  484. EXPORT_SYMBOL_GPL(ad193x_probe);
  485. MODULE_DESCRIPTION("ASoC ad193x driver");
  486. MODULE_AUTHOR("Barry Song <[email protected]>");
  487. MODULE_LICENSE("GPL");