cs42xx8.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696
  1. /*
  2. * Cirrus Logic CS42448/CS42888 Audio CODEC Digital Audio Interface (DAI) driver
  3. *
  4. * Copyright (C) 2014 Freescale Semiconductor, Inc.
  5. *
  6. * Author: Nicolin Chen <Guangyu.Chen@freescale.com>
  7. *
  8. * This file is licensed under the terms of the GNU General Public License
  9. * version 2. This program is licensed "as is" without any warranty of any
  10. * kind, whether express or implied.
  11. */
  12. #include <linux/clk.h>
  13. #include <linux/delay.h>
  14. #include <linux/module.h>
  15. #include <linux/of_device.h>
  16. #include <linux/gpio/consumer.h>
  17. #include <linux/pm_runtime.h>
  18. #include <linux/regulator/consumer.h>
  19. #include <sound/pcm_params.h>
  20. #include <sound/soc.h>
  21. #include <sound/tlv.h>
  22. #include "cs42xx8.h"
  23. #define CS42XX8_NUM_SUPPLIES 4
  24. static const char *const cs42xx8_supply_names[CS42XX8_NUM_SUPPLIES] = {
  25. "VA",
  26. "VD",
  27. "VLS",
  28. "VLC",
  29. };
  30. #define CS42XX8_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
  31. SNDRV_PCM_FMTBIT_S20_3LE | \
  32. SNDRV_PCM_FMTBIT_S24_LE | \
  33. SNDRV_PCM_FMTBIT_S32_LE)
  34. /* codec private data */
  35. struct cs42xx8_priv {
  36. struct regulator_bulk_data supplies[CS42XX8_NUM_SUPPLIES];
  37. const struct cs42xx8_driver_data *drvdata;
  38. struct regmap *regmap;
  39. struct clk *clk;
  40. bool slave_mode;
  41. unsigned long sysclk;
  42. u32 tx_channels;
  43. struct gpio_desc *gpiod_reset;
  44. u32 rate[2];
  45. };
  46. /* -127.5dB to 0dB with step of 0.5dB */
  47. static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1);
  48. /* -64dB to 24dB with step of 0.5dB */
  49. static const DECLARE_TLV_DB_SCALE(adc_tlv, -6400, 50, 0);
  50. static const char *const cs42xx8_adc_single[] = { "Differential", "Single-Ended" };
  51. static const char *const cs42xx8_szc[] = { "Immediate Change", "Zero Cross",
  52. "Soft Ramp", "Soft Ramp on Zero Cross" };
  53. static const struct soc_enum adc1_single_enum =
  54. SOC_ENUM_SINGLE(CS42XX8_ADCCTL, 4, 2, cs42xx8_adc_single);
  55. static const struct soc_enum adc2_single_enum =
  56. SOC_ENUM_SINGLE(CS42XX8_ADCCTL, 3, 2, cs42xx8_adc_single);
  57. static const struct soc_enum adc3_single_enum =
  58. SOC_ENUM_SINGLE(CS42XX8_ADCCTL, 2, 2, cs42xx8_adc_single);
  59. static const struct soc_enum dac_szc_enum =
  60. SOC_ENUM_SINGLE(CS42XX8_TXCTL, 5, 4, cs42xx8_szc);
  61. static const struct soc_enum adc_szc_enum =
  62. SOC_ENUM_SINGLE(CS42XX8_TXCTL, 0, 4, cs42xx8_szc);
  63. static const struct snd_kcontrol_new cs42xx8_snd_controls[] = {
  64. SOC_DOUBLE_R_TLV("DAC1 Playback Volume", CS42XX8_VOLAOUT1,
  65. CS42XX8_VOLAOUT2, 0, 0xff, 1, dac_tlv),
  66. SOC_DOUBLE_R_TLV("DAC2 Playback Volume", CS42XX8_VOLAOUT3,
  67. CS42XX8_VOLAOUT4, 0, 0xff, 1, dac_tlv),
  68. SOC_DOUBLE_R_TLV("DAC3 Playback Volume", CS42XX8_VOLAOUT5,
  69. CS42XX8_VOLAOUT6, 0, 0xff, 1, dac_tlv),
  70. SOC_DOUBLE_R_TLV("DAC4 Playback Volume", CS42XX8_VOLAOUT7,
  71. CS42XX8_VOLAOUT8, 0, 0xff, 1, dac_tlv),
  72. SOC_DOUBLE_R_S_TLV("ADC1 Capture Volume", CS42XX8_VOLAIN1,
  73. CS42XX8_VOLAIN2, 0, -0x80, 0x30, 7, 0, adc_tlv),
  74. SOC_DOUBLE_R_S_TLV("ADC2 Capture Volume", CS42XX8_VOLAIN3,
  75. CS42XX8_VOLAIN4, 0, -0x80, 0x30, 7, 0, adc_tlv),
  76. SOC_DOUBLE("DAC1 Invert Switch", CS42XX8_DACINV, 0, 1, 1, 0),
  77. SOC_DOUBLE("DAC2 Invert Switch", CS42XX8_DACINV, 2, 3, 1, 0),
  78. SOC_DOUBLE("DAC3 Invert Switch", CS42XX8_DACINV, 4, 5, 1, 0),
  79. SOC_DOUBLE("DAC4 Invert Switch", CS42XX8_DACINV, 6, 7, 1, 0),
  80. SOC_DOUBLE("ADC1 Invert Switch", CS42XX8_ADCINV, 0, 1, 1, 0),
  81. SOC_DOUBLE("ADC2 Invert Switch", CS42XX8_ADCINV, 2, 3, 1, 0),
  82. SOC_SINGLE("ADC High-Pass Filter Switch", CS42XX8_ADCCTL, 7, 1, 1),
  83. SOC_SINGLE("DAC De-emphasis Switch", CS42XX8_ADCCTL, 5, 1, 0),
  84. SOC_ENUM("ADC1 Single Ended Mode Switch", adc1_single_enum),
  85. SOC_ENUM("ADC2 Single Ended Mode Switch", adc2_single_enum),
  86. SOC_SINGLE("DAC Single Volume Control Switch", CS42XX8_TXCTL, 7, 1, 0),
  87. SOC_ENUM("DAC Soft Ramp & Zero Cross Control Switch", dac_szc_enum),
  88. SOC_SINGLE("DAC Auto Mute Switch", CS42XX8_TXCTL, 4, 1, 0),
  89. SOC_SINGLE("Mute ADC Serial Port Switch", CS42XX8_TXCTL, 3, 1, 0),
  90. SOC_SINGLE("ADC Single Volume Control Switch", CS42XX8_TXCTL, 2, 1, 0),
  91. SOC_ENUM("ADC Soft Ramp & Zero Cross Control Switch", adc_szc_enum),
  92. };
  93. static const struct snd_kcontrol_new cs42xx8_adc3_snd_controls[] = {
  94. SOC_DOUBLE_R_S_TLV("ADC3 Capture Volume", CS42XX8_VOLAIN5,
  95. CS42XX8_VOLAIN6, 0, -0x80, 0x30, 7, 0, adc_tlv),
  96. SOC_DOUBLE("ADC3 Invert Switch", CS42XX8_ADCINV, 4, 5, 1, 0),
  97. SOC_ENUM("ADC3 Single Ended Mode Switch", adc3_single_enum),
  98. };
  99. static const struct snd_soc_dapm_widget cs42xx8_dapm_widgets[] = {
  100. SND_SOC_DAPM_DAC("DAC1", "Playback", CS42XX8_PWRCTL, 1, 1),
  101. SND_SOC_DAPM_DAC("DAC2", "Playback", CS42XX8_PWRCTL, 2, 1),
  102. SND_SOC_DAPM_DAC("DAC3", "Playback", CS42XX8_PWRCTL, 3, 1),
  103. SND_SOC_DAPM_DAC("DAC4", "Playback", CS42XX8_PWRCTL, 4, 1),
  104. SND_SOC_DAPM_OUTPUT("AOUT1L"),
  105. SND_SOC_DAPM_OUTPUT("AOUT1R"),
  106. SND_SOC_DAPM_OUTPUT("AOUT2L"),
  107. SND_SOC_DAPM_OUTPUT("AOUT2R"),
  108. SND_SOC_DAPM_OUTPUT("AOUT3L"),
  109. SND_SOC_DAPM_OUTPUT("AOUT3R"),
  110. SND_SOC_DAPM_OUTPUT("AOUT4L"),
  111. SND_SOC_DAPM_OUTPUT("AOUT4R"),
  112. SND_SOC_DAPM_ADC("ADC1", "Capture", CS42XX8_PWRCTL, 5, 1),
  113. SND_SOC_DAPM_ADC("ADC2", "Capture", CS42XX8_PWRCTL, 6, 1),
  114. SND_SOC_DAPM_INPUT("AIN1L"),
  115. SND_SOC_DAPM_INPUT("AIN1R"),
  116. SND_SOC_DAPM_INPUT("AIN2L"),
  117. SND_SOC_DAPM_INPUT("AIN2R"),
  118. SND_SOC_DAPM_SUPPLY("PWR", CS42XX8_PWRCTL, 0, 1, NULL, 0),
  119. };
  120. static const struct snd_soc_dapm_widget cs42xx8_adc3_dapm_widgets[] = {
  121. SND_SOC_DAPM_ADC("ADC3", "Capture", CS42XX8_PWRCTL, 7, 1),
  122. SND_SOC_DAPM_INPUT("AIN3L"),
  123. SND_SOC_DAPM_INPUT("AIN3R"),
  124. };
  125. static const struct snd_soc_dapm_route cs42xx8_dapm_routes[] = {
  126. /* Playback */
  127. { "AOUT1L", NULL, "DAC1" },
  128. { "AOUT1R", NULL, "DAC1" },
  129. { "DAC1", NULL, "PWR" },
  130. { "AOUT2L", NULL, "DAC2" },
  131. { "AOUT2R", NULL, "DAC2" },
  132. { "DAC2", NULL, "PWR" },
  133. { "AOUT3L", NULL, "DAC3" },
  134. { "AOUT3R", NULL, "DAC3" },
  135. { "DAC3", NULL, "PWR" },
  136. { "AOUT4L", NULL, "DAC4" },
  137. { "AOUT4R", NULL, "DAC4" },
  138. { "DAC4", NULL, "PWR" },
  139. /* Capture */
  140. { "ADC1", NULL, "AIN1L" },
  141. { "ADC1", NULL, "AIN1R" },
  142. { "ADC1", NULL, "PWR" },
  143. { "ADC2", NULL, "AIN2L" },
  144. { "ADC2", NULL, "AIN2R" },
  145. { "ADC2", NULL, "PWR" },
  146. };
  147. static const struct snd_soc_dapm_route cs42xx8_adc3_dapm_routes[] = {
  148. /* Capture */
  149. { "ADC3", NULL, "AIN3L" },
  150. { "ADC3", NULL, "AIN3R" },
  151. { "ADC3", NULL, "PWR" },
  152. };
  153. struct cs42xx8_ratios {
  154. unsigned int mfreq;
  155. unsigned int min_mclk;
  156. unsigned int max_mclk;
  157. unsigned int ratio[3];
  158. };
  159. /*
  160. * According to reference mannual, define the cs42xx8_ratio struct
  161. * MFreq2 | MFreq1 | MFreq0 | Description | SSM | DSM | QSM |
  162. * 0 | 0 | 0 |1.029MHz to 12.8MHz | 256 | 128 | 64 |
  163. * 0 | 0 | 1 |1.536MHz to 19.2MHz | 384 | 192 | 96 |
  164. * 0 | 1 | 0 |2.048MHz to 25.6MHz | 512 | 256 | 128 |
  165. * 0 | 1 | 1 |3.072MHz to 38.4MHz | 768 | 384 | 192 |
  166. * 1 | x | x |4.096MHz to 51.2MHz |1024 | 512 | 256 |
  167. */
  168. static const struct cs42xx8_ratios cs42xx8_ratios[] = {
  169. { 0, 1029000, 12800000, {256, 128, 64} },
  170. { 2, 1536000, 19200000, {384, 192, 96} },
  171. { 4, 2048000, 25600000, {512, 256, 128} },
  172. { 6, 3072000, 38400000, {768, 384, 192} },
  173. { 8, 4096000, 51200000, {1024, 512, 256} },
  174. };
  175. static int cs42xx8_set_dai_sysclk(struct snd_soc_dai *codec_dai,
  176. int clk_id, unsigned int freq, int dir)
  177. {
  178. struct snd_soc_component *component = codec_dai->component;
  179. struct cs42xx8_priv *cs42xx8 = snd_soc_component_get_drvdata(component);
  180. cs42xx8->sysclk = freq;
  181. return 0;
  182. }
  183. static int cs42xx8_set_dai_fmt(struct snd_soc_dai *codec_dai,
  184. unsigned int format)
  185. {
  186. struct snd_soc_component *component = codec_dai->component;
  187. struct cs42xx8_priv *cs42xx8 = snd_soc_component_get_drvdata(component);
  188. u32 val;
  189. /* Set DAI format */
  190. switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
  191. case SND_SOC_DAIFMT_LEFT_J:
  192. val = CS42XX8_INTF_DAC_DIF_LEFTJ | CS42XX8_INTF_ADC_DIF_LEFTJ;
  193. break;
  194. case SND_SOC_DAIFMT_I2S:
  195. val = CS42XX8_INTF_DAC_DIF_I2S | CS42XX8_INTF_ADC_DIF_I2S;
  196. break;
  197. case SND_SOC_DAIFMT_RIGHT_J:
  198. val = CS42XX8_INTF_DAC_DIF_RIGHTJ | CS42XX8_INTF_ADC_DIF_RIGHTJ;
  199. break;
  200. case SND_SOC_DAIFMT_DSP_A:
  201. val = CS42XX8_INTF_DAC_DIF_TDM | CS42XX8_INTF_ADC_DIF_TDM;
  202. break;
  203. default:
  204. dev_err(component->dev, "unsupported dai format\n");
  205. return -EINVAL;
  206. }
  207. regmap_update_bits(cs42xx8->regmap, CS42XX8_INTF,
  208. CS42XX8_INTF_DAC_DIF_MASK |
  209. CS42XX8_INTF_ADC_DIF_MASK, val);
  210. /* Set master/slave audio interface */
  211. switch (format & SND_SOC_DAIFMT_MASTER_MASK) {
  212. case SND_SOC_DAIFMT_CBS_CFS:
  213. cs42xx8->slave_mode = true;
  214. break;
  215. case SND_SOC_DAIFMT_CBM_CFM:
  216. cs42xx8->slave_mode = false;
  217. break;
  218. default:
  219. dev_err(component->dev, "unsupported master/slave mode\n");
  220. return -EINVAL;
  221. }
  222. return 0;
  223. }
  224. static int cs42xx8_hw_params(struct snd_pcm_substream *substream,
  225. struct snd_pcm_hw_params *params,
  226. struct snd_soc_dai *dai)
  227. {
  228. struct snd_soc_component *component = dai->component;
  229. struct cs42xx8_priv *cs42xx8 = snd_soc_component_get_drvdata(component);
  230. bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
  231. u32 ratio[2];
  232. u32 rate[2];
  233. u32 fm[2];
  234. u32 i, val, mask;
  235. bool condition1, condition2;
  236. if (tx)
  237. cs42xx8->tx_channels = params_channels(params);
  238. rate[tx] = params_rate(params);
  239. rate[!tx] = cs42xx8->rate[!tx];
  240. ratio[tx] = rate[tx] > 0 ? cs42xx8->sysclk / rate[tx] : 0;
  241. ratio[!tx] = rate[!tx] > 0 ? cs42xx8->sysclk / rate[!tx] : 0;
  242. /* Get functional mode for tx and rx according to rate */
  243. for (i = 0; i < 2; i++) {
  244. if (cs42xx8->slave_mode) {
  245. fm[i] = CS42XX8_FM_AUTO;
  246. } else {
  247. if (rate[i] < 50000) {
  248. fm[i] = CS42XX8_FM_SINGLE;
  249. } else if (rate[i] > 50000 && rate[i] < 100000) {
  250. fm[i] = CS42XX8_FM_DOUBLE;
  251. } else if (rate[i] > 100000 && rate[i] < 200000) {
  252. fm[i] = CS42XX8_FM_QUAD;
  253. } else {
  254. dev_err(component->dev,
  255. "unsupported sample rate\n");
  256. return -EINVAL;
  257. }
  258. }
  259. }
  260. for (i = 0; i < ARRAY_SIZE(cs42xx8_ratios); i++) {
  261. /* Is the ratio[tx] valid ? */
  262. condition1 = ((fm[tx] == CS42XX8_FM_AUTO) ?
  263. (cs42xx8_ratios[i].ratio[0] == ratio[tx] ||
  264. cs42xx8_ratios[i].ratio[1] == ratio[tx] ||
  265. cs42xx8_ratios[i].ratio[2] == ratio[tx]) :
  266. (cs42xx8_ratios[i].ratio[fm[tx]] == ratio[tx])) &&
  267. cs42xx8->sysclk >= cs42xx8_ratios[i].min_mclk &&
  268. cs42xx8->sysclk <= cs42xx8_ratios[i].max_mclk;
  269. if (!ratio[tx])
  270. condition1 = true;
  271. /* Is the ratio[!tx] valid ? */
  272. condition2 = ((fm[!tx] == CS42XX8_FM_AUTO) ?
  273. (cs42xx8_ratios[i].ratio[0] == ratio[!tx] ||
  274. cs42xx8_ratios[i].ratio[1] == ratio[!tx] ||
  275. cs42xx8_ratios[i].ratio[2] == ratio[!tx]) :
  276. (cs42xx8_ratios[i].ratio[fm[!tx]] == ratio[!tx]));
  277. if (!ratio[!tx])
  278. condition2 = true;
  279. /*
  280. * Both ratio[tx] and ratio[!tx] is valid, then we get
  281. * a proper MFreq.
  282. */
  283. if (condition1 && condition2)
  284. break;
  285. }
  286. if (i == ARRAY_SIZE(cs42xx8_ratios)) {
  287. dev_err(component->dev, "unsupported sysclk ratio\n");
  288. return -EINVAL;
  289. }
  290. cs42xx8->rate[tx] = params_rate(params);
  291. mask = CS42XX8_FUNCMOD_MFREQ_MASK;
  292. val = cs42xx8_ratios[i].mfreq;
  293. regmap_update_bits(cs42xx8->regmap, CS42XX8_FUNCMOD,
  294. CS42XX8_FUNCMOD_xC_FM_MASK(tx) | mask,
  295. CS42XX8_FUNCMOD_xC_FM(tx, fm[tx]) | val);
  296. return 0;
  297. }
  298. static int cs42xx8_hw_free(struct snd_pcm_substream *substream,
  299. struct snd_soc_dai *dai)
  300. {
  301. struct snd_soc_component *component = dai->component;
  302. struct cs42xx8_priv *cs42xx8 = snd_soc_component_get_drvdata(component);
  303. bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
  304. /* Clear stored rate */
  305. cs42xx8->rate[tx] = 0;
  306. regmap_update_bits(cs42xx8->regmap, CS42XX8_FUNCMOD,
  307. CS42XX8_FUNCMOD_xC_FM_MASK(tx),
  308. CS42XX8_FUNCMOD_xC_FM(tx, CS42XX8_FM_AUTO));
  309. return 0;
  310. }
  311. static int cs42xx8_mute(struct snd_soc_dai *dai, int mute, int direction)
  312. {
  313. struct snd_soc_component *component = dai->component;
  314. struct cs42xx8_priv *cs42xx8 = snd_soc_component_get_drvdata(component);
  315. u8 dac_unmute = cs42xx8->tx_channels ?
  316. ~((0x1 << cs42xx8->tx_channels) - 1) : 0;
  317. regmap_write(cs42xx8->regmap, CS42XX8_DACMUTE,
  318. mute ? CS42XX8_DACMUTE_ALL : dac_unmute);
  319. return 0;
  320. }
  321. static const struct snd_soc_dai_ops cs42xx8_dai_ops = {
  322. .set_fmt = cs42xx8_set_dai_fmt,
  323. .set_sysclk = cs42xx8_set_dai_sysclk,
  324. .hw_params = cs42xx8_hw_params,
  325. .hw_free = cs42xx8_hw_free,
  326. .mute_stream = cs42xx8_mute,
  327. .no_capture_mute = 1,
  328. };
  329. static struct snd_soc_dai_driver cs42xx8_dai = {
  330. .playback = {
  331. .stream_name = "Playback",
  332. .channels_min = 1,
  333. .channels_max = 8,
  334. .rates = SNDRV_PCM_RATE_8000_192000,
  335. .formats = CS42XX8_FORMATS,
  336. },
  337. .capture = {
  338. .stream_name = "Capture",
  339. .channels_min = 1,
  340. .rates = SNDRV_PCM_RATE_8000_192000,
  341. .formats = CS42XX8_FORMATS,
  342. },
  343. .ops = &cs42xx8_dai_ops,
  344. };
  345. static const struct reg_default cs42xx8_reg[] = {
  346. { 0x02, 0x00 }, /* Power Control */
  347. { 0x03, 0xF0 }, /* Functional Mode */
  348. { 0x04, 0x46 }, /* Interface Formats */
  349. { 0x05, 0x00 }, /* ADC Control & DAC De-Emphasis */
  350. { 0x06, 0x10 }, /* Transition Control */
  351. { 0x07, 0x00 }, /* DAC Channel Mute */
  352. { 0x08, 0x00 }, /* Volume Control AOUT1 */
  353. { 0x09, 0x00 }, /* Volume Control AOUT2 */
  354. { 0x0a, 0x00 }, /* Volume Control AOUT3 */
  355. { 0x0b, 0x00 }, /* Volume Control AOUT4 */
  356. { 0x0c, 0x00 }, /* Volume Control AOUT5 */
  357. { 0x0d, 0x00 }, /* Volume Control AOUT6 */
  358. { 0x0e, 0x00 }, /* Volume Control AOUT7 */
  359. { 0x0f, 0x00 }, /* Volume Control AOUT8 */
  360. { 0x10, 0x00 }, /* DAC Channel Invert */
  361. { 0x11, 0x00 }, /* Volume Control AIN1 */
  362. { 0x12, 0x00 }, /* Volume Control AIN2 */
  363. { 0x13, 0x00 }, /* Volume Control AIN3 */
  364. { 0x14, 0x00 }, /* Volume Control AIN4 */
  365. { 0x15, 0x00 }, /* Volume Control AIN5 */
  366. { 0x16, 0x00 }, /* Volume Control AIN6 */
  367. { 0x17, 0x00 }, /* ADC Channel Invert */
  368. { 0x18, 0x00 }, /* Status Control */
  369. { 0x1a, 0x00 }, /* Status Mask */
  370. { 0x1b, 0x00 }, /* MUTEC Pin Control */
  371. };
  372. static bool cs42xx8_volatile_register(struct device *dev, unsigned int reg)
  373. {
  374. switch (reg) {
  375. case CS42XX8_STATUS:
  376. return true;
  377. default:
  378. return false;
  379. }
  380. }
  381. static bool cs42xx8_writeable_register(struct device *dev, unsigned int reg)
  382. {
  383. switch (reg) {
  384. case CS42XX8_CHIPID:
  385. case CS42XX8_STATUS:
  386. return false;
  387. default:
  388. return true;
  389. }
  390. }
  391. const struct regmap_config cs42xx8_regmap_config = {
  392. .reg_bits = 8,
  393. .val_bits = 8,
  394. .max_register = CS42XX8_LASTREG,
  395. .reg_defaults = cs42xx8_reg,
  396. .num_reg_defaults = ARRAY_SIZE(cs42xx8_reg),
  397. .volatile_reg = cs42xx8_volatile_register,
  398. .writeable_reg = cs42xx8_writeable_register,
  399. .cache_type = REGCACHE_RBTREE,
  400. };
  401. EXPORT_SYMBOL_GPL(cs42xx8_regmap_config);
  402. static int cs42xx8_component_probe(struct snd_soc_component *component)
  403. {
  404. struct cs42xx8_priv *cs42xx8 = snd_soc_component_get_drvdata(component);
  405. struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
  406. switch (cs42xx8->drvdata->num_adcs) {
  407. case 3:
  408. snd_soc_add_component_controls(component, cs42xx8_adc3_snd_controls,
  409. ARRAY_SIZE(cs42xx8_adc3_snd_controls));
  410. snd_soc_dapm_new_controls(dapm, cs42xx8_adc3_dapm_widgets,
  411. ARRAY_SIZE(cs42xx8_adc3_dapm_widgets));
  412. snd_soc_dapm_add_routes(dapm, cs42xx8_adc3_dapm_routes,
  413. ARRAY_SIZE(cs42xx8_adc3_dapm_routes));
  414. break;
  415. default:
  416. break;
  417. }
  418. /* Mute all DAC channels */
  419. regmap_write(cs42xx8->regmap, CS42XX8_DACMUTE, CS42XX8_DACMUTE_ALL);
  420. return 0;
  421. }
  422. static const struct snd_soc_component_driver cs42xx8_driver = {
  423. .probe = cs42xx8_component_probe,
  424. .controls = cs42xx8_snd_controls,
  425. .num_controls = ARRAY_SIZE(cs42xx8_snd_controls),
  426. .dapm_widgets = cs42xx8_dapm_widgets,
  427. .num_dapm_widgets = ARRAY_SIZE(cs42xx8_dapm_widgets),
  428. .dapm_routes = cs42xx8_dapm_routes,
  429. .num_dapm_routes = ARRAY_SIZE(cs42xx8_dapm_routes),
  430. .use_pmdown_time = 1,
  431. .endianness = 1,
  432. .non_legacy_dai_naming = 1,
  433. };
  434. const struct cs42xx8_driver_data cs42448_data = {
  435. .name = "cs42448",
  436. .num_adcs = 3,
  437. };
  438. EXPORT_SYMBOL_GPL(cs42448_data);
  439. const struct cs42xx8_driver_data cs42888_data = {
  440. .name = "cs42888",
  441. .num_adcs = 2,
  442. };
  443. EXPORT_SYMBOL_GPL(cs42888_data);
  444. const struct of_device_id cs42xx8_of_match[] = {
  445. { .compatible = "cirrus,cs42448", .data = &cs42448_data, },
  446. { .compatible = "cirrus,cs42888", .data = &cs42888_data, },
  447. { /* sentinel */ }
  448. };
  449. MODULE_DEVICE_TABLE(of, cs42xx8_of_match);
  450. EXPORT_SYMBOL_GPL(cs42xx8_of_match);
  451. int cs42xx8_probe(struct device *dev, struct regmap *regmap)
  452. {
  453. const struct of_device_id *of_id;
  454. struct cs42xx8_priv *cs42xx8;
  455. int ret, val, i;
  456. if (IS_ERR(regmap)) {
  457. ret = PTR_ERR(regmap);
  458. dev_err(dev, "failed to allocate regmap: %d\n", ret);
  459. return ret;
  460. }
  461. cs42xx8 = devm_kzalloc(dev, sizeof(*cs42xx8), GFP_KERNEL);
  462. if (cs42xx8 == NULL)
  463. return -ENOMEM;
  464. cs42xx8->regmap = regmap;
  465. dev_set_drvdata(dev, cs42xx8);
  466. of_id = of_match_device(cs42xx8_of_match, dev);
  467. if (of_id)
  468. cs42xx8->drvdata = of_id->data;
  469. if (!cs42xx8->drvdata) {
  470. dev_err(dev, "failed to find driver data\n");
  471. return -EINVAL;
  472. }
  473. cs42xx8->gpiod_reset = devm_gpiod_get_optional(dev, "reset",
  474. GPIOD_OUT_HIGH);
  475. if (IS_ERR(cs42xx8->gpiod_reset))
  476. return PTR_ERR(cs42xx8->gpiod_reset);
  477. gpiod_set_value_cansleep(cs42xx8->gpiod_reset, 0);
  478. cs42xx8->clk = devm_clk_get(dev, "mclk");
  479. if (IS_ERR(cs42xx8->clk)) {
  480. dev_err(dev, "failed to get the clock: %ld\n",
  481. PTR_ERR(cs42xx8->clk));
  482. return -EINVAL;
  483. }
  484. cs42xx8->sysclk = clk_get_rate(cs42xx8->clk);
  485. for (i = 0; i < ARRAY_SIZE(cs42xx8->supplies); i++)
  486. cs42xx8->supplies[i].supply = cs42xx8_supply_names[i];
  487. ret = devm_regulator_bulk_get(dev,
  488. ARRAY_SIZE(cs42xx8->supplies), cs42xx8->supplies);
  489. if (ret) {
  490. dev_err(dev, "failed to request supplies: %d\n", ret);
  491. return ret;
  492. }
  493. ret = regulator_bulk_enable(ARRAY_SIZE(cs42xx8->supplies),
  494. cs42xx8->supplies);
  495. if (ret) {
  496. dev_err(dev, "failed to enable supplies: %d\n", ret);
  497. return ret;
  498. }
  499. /* Make sure hardware reset done */
  500. msleep(5);
  501. /* Validate the chip ID */
  502. ret = regmap_read(cs42xx8->regmap, CS42XX8_CHIPID, &val);
  503. if (ret < 0) {
  504. dev_err(dev, "failed to get device ID, ret = %d", ret);
  505. goto err_enable;
  506. }
  507. /* The top four bits of the chip ID should be 0000 */
  508. if (((val & CS42XX8_CHIPID_CHIP_ID_MASK) >> 4) != 0x00) {
  509. dev_err(dev, "unmatched chip ID: %d\n",
  510. (val & CS42XX8_CHIPID_CHIP_ID_MASK) >> 4);
  511. ret = -EINVAL;
  512. goto err_enable;
  513. }
  514. dev_info(dev, "found device, revision %X\n",
  515. val & CS42XX8_CHIPID_REV_ID_MASK);
  516. cs42xx8_dai.name = cs42xx8->drvdata->name;
  517. /* Each adc supports stereo input */
  518. cs42xx8_dai.capture.channels_max = cs42xx8->drvdata->num_adcs * 2;
  519. ret = devm_snd_soc_register_component(dev, &cs42xx8_driver, &cs42xx8_dai, 1);
  520. if (ret) {
  521. dev_err(dev, "failed to register component:%d\n", ret);
  522. goto err_enable;
  523. }
  524. regcache_cache_only(cs42xx8->regmap, true);
  525. err_enable:
  526. regulator_bulk_disable(ARRAY_SIZE(cs42xx8->supplies),
  527. cs42xx8->supplies);
  528. return ret;
  529. }
  530. EXPORT_SYMBOL_GPL(cs42xx8_probe);
  531. #ifdef CONFIG_PM
  532. static int cs42xx8_runtime_resume(struct device *dev)
  533. {
  534. struct cs42xx8_priv *cs42xx8 = dev_get_drvdata(dev);
  535. int ret;
  536. ret = clk_prepare_enable(cs42xx8->clk);
  537. if (ret) {
  538. dev_err(dev, "failed to enable mclk: %d\n", ret);
  539. return ret;
  540. }
  541. gpiod_set_value_cansleep(cs42xx8->gpiod_reset, 0);
  542. ret = regulator_bulk_enable(ARRAY_SIZE(cs42xx8->supplies),
  543. cs42xx8->supplies);
  544. if (ret) {
  545. dev_err(dev, "failed to enable supplies: %d\n", ret);
  546. goto err_clk;
  547. }
  548. /* Make sure hardware reset done */
  549. msleep(5);
  550. regcache_cache_only(cs42xx8->regmap, false);
  551. regcache_mark_dirty(cs42xx8->regmap);
  552. ret = regcache_sync(cs42xx8->regmap);
  553. if (ret) {
  554. dev_err(dev, "failed to sync regmap: %d\n", ret);
  555. goto err_bulk;
  556. }
  557. return 0;
  558. err_bulk:
  559. regulator_bulk_disable(ARRAY_SIZE(cs42xx8->supplies),
  560. cs42xx8->supplies);
  561. err_clk:
  562. clk_disable_unprepare(cs42xx8->clk);
  563. return ret;
  564. }
  565. static int cs42xx8_runtime_suspend(struct device *dev)
  566. {
  567. struct cs42xx8_priv *cs42xx8 = dev_get_drvdata(dev);
  568. regcache_cache_only(cs42xx8->regmap, true);
  569. regulator_bulk_disable(ARRAY_SIZE(cs42xx8->supplies),
  570. cs42xx8->supplies);
  571. gpiod_set_value_cansleep(cs42xx8->gpiod_reset, 1);
  572. clk_disable_unprepare(cs42xx8->clk);
  573. return 0;
  574. }
  575. #endif
  576. const struct dev_pm_ops cs42xx8_pm = {
  577. SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
  578. pm_runtime_force_resume)
  579. SET_RUNTIME_PM_OPS(cs42xx8_runtime_suspend, cs42xx8_runtime_resume, NULL)
  580. };
  581. EXPORT_SYMBOL_GPL(cs42xx8_pm);
  582. MODULE_DESCRIPTION("Cirrus Logic CS42448/CS42888 ALSA SoC Codec Driver");
  583. MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  584. MODULE_LICENSE("GPL");