sirf-audio-codec.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580
  1. /*
  2. * SiRF audio codec driver
  3. *
  4. * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
  5. *
  6. * Licensed under GPLv2 or later.
  7. */
  8. #include <linux/module.h>
  9. #include <linux/platform_device.h>
  10. #include <linux/pm_runtime.h>
  11. #include <linux/of.h>
  12. #include <linux/of_device.h>
  13. #include <linux/clk.h>
  14. #include <linux/delay.h>
  15. #include <linux/io.h>
  16. #include <linux/regmap.h>
  17. #include <sound/core.h>
  18. #include <sound/pcm.h>
  19. #include <sound/pcm_params.h>
  20. #include <sound/initval.h>
  21. #include <sound/tlv.h>
  22. #include <sound/soc.h>
  23. #include <sound/dmaengine_pcm.h>
  24. #include "sirf-audio-codec.h"
  25. struct sirf_audio_codec {
  26. struct clk *clk;
  27. struct regmap *regmap;
  28. u32 reg_ctrl0, reg_ctrl1;
  29. };
  30. static const char * const input_mode_mux[] = {"Single-ended",
  31. "Differential"};
  32. static const struct soc_enum input_mode_mux_enum =
  33. SOC_ENUM_SINGLE(AUDIO_IC_CODEC_CTRL1, 4, 2, input_mode_mux);
  34. static const struct snd_kcontrol_new sirf_audio_codec_input_mode_control =
  35. SOC_DAPM_ENUM("Route", input_mode_mux_enum);
  36. static const DECLARE_TLV_DB_SCALE(playback_vol_tlv, -12400, 100, 0);
  37. static const DECLARE_TLV_DB_SCALE(capture_vol_tlv_prima2, 500, 100, 0);
  38. static const DECLARE_TLV_DB_RANGE(capture_vol_tlv_atlas6,
  39. 0, 7, TLV_DB_SCALE_ITEM(-100, 100, 0),
  40. 0x22, 0x3F, TLV_DB_SCALE_ITEM(700, 100, 0),
  41. );
  42. static struct snd_kcontrol_new volume_controls_atlas6[] = {
  43. SOC_DOUBLE_TLV("Playback Volume", AUDIO_IC_CODEC_CTRL0, 21, 14,
  44. 0x7F, 0, playback_vol_tlv),
  45. SOC_DOUBLE_TLV("Capture Volume", AUDIO_IC_CODEC_CTRL1, 16, 10,
  46. 0x3F, 0, capture_vol_tlv_atlas6),
  47. };
  48. static struct snd_kcontrol_new volume_controls_prima2[] = {
  49. SOC_DOUBLE_TLV("Speaker Volume", AUDIO_IC_CODEC_CTRL0, 21, 14,
  50. 0x7F, 0, playback_vol_tlv),
  51. SOC_DOUBLE_TLV("Capture Volume", AUDIO_IC_CODEC_CTRL1, 15, 10,
  52. 0x1F, 0, capture_vol_tlv_prima2),
  53. };
  54. static struct snd_kcontrol_new left_input_path_controls[] = {
  55. SOC_DAPM_SINGLE("Line Left Switch", AUDIO_IC_CODEC_CTRL1, 6, 1, 0),
  56. SOC_DAPM_SINGLE("Mic Left Switch", AUDIO_IC_CODEC_CTRL1, 3, 1, 0),
  57. };
  58. static struct snd_kcontrol_new right_input_path_controls[] = {
  59. SOC_DAPM_SINGLE("Line Right Switch", AUDIO_IC_CODEC_CTRL1, 5, 1, 0),
  60. SOC_DAPM_SINGLE("Mic Right Switch", AUDIO_IC_CODEC_CTRL1, 2, 1, 0),
  61. };
  62. static struct snd_kcontrol_new left_dac_to_hp_left_amp_switch_control =
  63. SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0, 9, 1, 0);
  64. static struct snd_kcontrol_new left_dac_to_hp_right_amp_switch_control =
  65. SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0, 8, 1, 0);
  66. static struct snd_kcontrol_new right_dac_to_hp_left_amp_switch_control =
  67. SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0, 7, 1, 0);
  68. static struct snd_kcontrol_new right_dac_to_hp_right_amp_switch_control =
  69. SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0, 6, 1, 0);
  70. static struct snd_kcontrol_new left_dac_to_speaker_lineout_switch_control =
  71. SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0, 11, 1, 0);
  72. static struct snd_kcontrol_new right_dac_to_speaker_lineout_switch_control =
  73. SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0, 10, 1, 0);
  74. /* After enable adc, Delay 200ms to avoid pop noise */
  75. static int adc_enable_delay_event(struct snd_soc_dapm_widget *w,
  76. struct snd_kcontrol *kcontrol, int event)
  77. {
  78. switch (event) {
  79. case SND_SOC_DAPM_POST_PMU:
  80. msleep(200);
  81. break;
  82. default:
  83. break;
  84. }
  85. return 0;
  86. }
  87. static void enable_and_reset_codec(struct regmap *regmap,
  88. u32 codec_enable_bits, u32 codec_reset_bits)
  89. {
  90. regmap_update_bits(regmap, AUDIO_IC_CODEC_CTRL1,
  91. codec_enable_bits | codec_reset_bits,
  92. codec_enable_bits);
  93. msleep(20);
  94. regmap_update_bits(regmap, AUDIO_IC_CODEC_CTRL1,
  95. codec_reset_bits, codec_reset_bits);
  96. }
  97. static int atlas6_codec_enable_and_reset_event(struct snd_soc_dapm_widget *w,
  98. struct snd_kcontrol *kcontrol, int event)
  99. {
  100. #define ATLAS6_CODEC_ENABLE_BITS (1 << 29)
  101. #define ATLAS6_CODEC_RESET_BITS (1 << 28)
  102. struct sirf_audio_codec *sirf_audio_codec = dev_get_drvdata(w->codec->dev);
  103. switch (event) {
  104. case SND_SOC_DAPM_PRE_PMU:
  105. enable_and_reset_codec(sirf_audio_codec->regmap,
  106. ATLAS6_CODEC_ENABLE_BITS, ATLAS6_CODEC_RESET_BITS);
  107. break;
  108. case SND_SOC_DAPM_POST_PMD:
  109. regmap_update_bits(sirf_audio_codec->regmap,
  110. AUDIO_IC_CODEC_CTRL1, ATLAS6_CODEC_ENABLE_BITS, 0);
  111. break;
  112. default:
  113. break;
  114. }
  115. return 0;
  116. }
  117. static int prima2_codec_enable_and_reset_event(struct snd_soc_dapm_widget *w,
  118. struct snd_kcontrol *kcontrol, int event)
  119. {
  120. #define PRIMA2_CODEC_ENABLE_BITS (1 << 27)
  121. #define PRIMA2_CODEC_RESET_BITS (1 << 26)
  122. struct sirf_audio_codec *sirf_audio_codec = dev_get_drvdata(w->codec->dev);
  123. switch (event) {
  124. case SND_SOC_DAPM_POST_PMU:
  125. enable_and_reset_codec(sirf_audio_codec->regmap,
  126. PRIMA2_CODEC_ENABLE_BITS, PRIMA2_CODEC_RESET_BITS);
  127. break;
  128. case SND_SOC_DAPM_POST_PMD:
  129. regmap_update_bits(sirf_audio_codec->regmap,
  130. AUDIO_IC_CODEC_CTRL1, PRIMA2_CODEC_ENABLE_BITS, 0);
  131. break;
  132. default:
  133. break;
  134. }
  135. return 0;
  136. }
  137. static const struct snd_soc_dapm_widget atlas6_output_driver_dapm_widgets[] = {
  138. SND_SOC_DAPM_OUT_DRV("HP Left Driver", AUDIO_IC_CODEC_CTRL1,
  139. 25, 0, NULL, 0),
  140. SND_SOC_DAPM_OUT_DRV("HP Right Driver", AUDIO_IC_CODEC_CTRL1,
  141. 26, 0, NULL, 0),
  142. SND_SOC_DAPM_OUT_DRV("Speaker Driver", AUDIO_IC_CODEC_CTRL1,
  143. 27, 0, NULL, 0),
  144. };
  145. static const struct snd_soc_dapm_widget prima2_output_driver_dapm_widgets[] = {
  146. SND_SOC_DAPM_OUT_DRV("HP Left Driver", AUDIO_IC_CODEC_CTRL1,
  147. 23, 0, NULL, 0),
  148. SND_SOC_DAPM_OUT_DRV("HP Right Driver", AUDIO_IC_CODEC_CTRL1,
  149. 24, 0, NULL, 0),
  150. SND_SOC_DAPM_OUT_DRV("Speaker Driver", AUDIO_IC_CODEC_CTRL1,
  151. 25, 0, NULL, 0),
  152. };
  153. static const struct snd_soc_dapm_widget atlas6_codec_clock_dapm_widget =
  154. SND_SOC_DAPM_SUPPLY("codecclk", SND_SOC_NOPM, 0, 0,
  155. atlas6_codec_enable_and_reset_event,
  156. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD);
  157. static const struct snd_soc_dapm_widget prima2_codec_clock_dapm_widget =
  158. SND_SOC_DAPM_SUPPLY("codecclk", SND_SOC_NOPM, 0, 0,
  159. prima2_codec_enable_and_reset_event,
  160. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD);
  161. static const struct snd_soc_dapm_widget sirf_audio_codec_dapm_widgets[] = {
  162. SND_SOC_DAPM_DAC("DAC left", NULL, AUDIO_IC_CODEC_CTRL0, 1, 0),
  163. SND_SOC_DAPM_DAC("DAC right", NULL, AUDIO_IC_CODEC_CTRL0, 0, 0),
  164. SND_SOC_DAPM_SWITCH("Left dac to hp left amp", SND_SOC_NOPM, 0, 0,
  165. &left_dac_to_hp_left_amp_switch_control),
  166. SND_SOC_DAPM_SWITCH("Left dac to hp right amp", SND_SOC_NOPM, 0, 0,
  167. &left_dac_to_hp_right_amp_switch_control),
  168. SND_SOC_DAPM_SWITCH("Right dac to hp left amp", SND_SOC_NOPM, 0, 0,
  169. &right_dac_to_hp_left_amp_switch_control),
  170. SND_SOC_DAPM_SWITCH("Right dac to hp right amp", SND_SOC_NOPM, 0, 0,
  171. &right_dac_to_hp_right_amp_switch_control),
  172. SND_SOC_DAPM_OUT_DRV("HP amp left driver", AUDIO_IC_CODEC_CTRL0, 3, 0,
  173. NULL, 0),
  174. SND_SOC_DAPM_OUT_DRV("HP amp right driver", AUDIO_IC_CODEC_CTRL0, 3, 0,
  175. NULL, 0),
  176. SND_SOC_DAPM_SWITCH("Left dac to speaker lineout", SND_SOC_NOPM, 0, 0,
  177. &left_dac_to_speaker_lineout_switch_control),
  178. SND_SOC_DAPM_SWITCH("Right dac to speaker lineout", SND_SOC_NOPM, 0, 0,
  179. &right_dac_to_speaker_lineout_switch_control),
  180. SND_SOC_DAPM_OUT_DRV("Speaker amp driver", AUDIO_IC_CODEC_CTRL0, 4, 0,
  181. NULL, 0),
  182. SND_SOC_DAPM_OUTPUT("HPOUTL"),
  183. SND_SOC_DAPM_OUTPUT("HPOUTR"),
  184. SND_SOC_DAPM_OUTPUT("SPKOUT"),
  185. SND_SOC_DAPM_ADC_E("ADC left", NULL, AUDIO_IC_CODEC_CTRL1, 8, 0,
  186. adc_enable_delay_event, SND_SOC_DAPM_POST_PMU),
  187. SND_SOC_DAPM_ADC_E("ADC right", NULL, AUDIO_IC_CODEC_CTRL1, 7, 0,
  188. adc_enable_delay_event, SND_SOC_DAPM_POST_PMU),
  189. SND_SOC_DAPM_MIXER("Left PGA mixer", AUDIO_IC_CODEC_CTRL1, 1, 0,
  190. &left_input_path_controls[0],
  191. ARRAY_SIZE(left_input_path_controls)),
  192. SND_SOC_DAPM_MIXER("Right PGA mixer", AUDIO_IC_CODEC_CTRL1, 0, 0,
  193. &right_input_path_controls[0],
  194. ARRAY_SIZE(right_input_path_controls)),
  195. SND_SOC_DAPM_MUX("Mic input mode mux", SND_SOC_NOPM, 0, 0,
  196. &sirf_audio_codec_input_mode_control),
  197. SND_SOC_DAPM_MICBIAS("Mic Bias", AUDIO_IC_CODEC_PWR, 3, 0),
  198. SND_SOC_DAPM_INPUT("MICIN1"),
  199. SND_SOC_DAPM_INPUT("MICIN2"),
  200. SND_SOC_DAPM_INPUT("LINEIN1"),
  201. SND_SOC_DAPM_INPUT("LINEIN2"),
  202. SND_SOC_DAPM_SUPPLY("HSL Phase Opposite", AUDIO_IC_CODEC_CTRL0,
  203. 30, 0, NULL, 0),
  204. };
  205. static const struct snd_soc_dapm_route sirf_audio_codec_map[] = {
  206. {"SPKOUT", NULL, "Speaker Driver"},
  207. {"Speaker Driver", NULL, "Speaker amp driver"},
  208. {"Speaker amp driver", NULL, "Left dac to speaker lineout"},
  209. {"Speaker amp driver", NULL, "Right dac to speaker lineout"},
  210. {"Left dac to speaker lineout", "Switch", "DAC left"},
  211. {"Right dac to speaker lineout", "Switch", "DAC right"},
  212. {"HPOUTL", NULL, "HP Left Driver"},
  213. {"HPOUTR", NULL, "HP Right Driver"},
  214. {"HP Left Driver", NULL, "HP amp left driver"},
  215. {"HP Right Driver", NULL, "HP amp right driver"},
  216. {"HP amp left driver", NULL, "Right dac to hp left amp"},
  217. {"HP amp right driver", NULL , "Right dac to hp right amp"},
  218. {"HP amp left driver", NULL, "Left dac to hp left amp"},
  219. {"HP amp right driver", NULL , "Right dac to hp right amp"},
  220. {"Right dac to hp left amp", "Switch", "DAC left"},
  221. {"Right dac to hp right amp", "Switch", "DAC right"},
  222. {"Left dac to hp left amp", "Switch", "DAC left"},
  223. {"Left dac to hp right amp", "Switch", "DAC right"},
  224. {"DAC left", NULL, "codecclk"},
  225. {"DAC right", NULL, "codecclk"},
  226. {"DAC left", NULL, "Playback"},
  227. {"DAC right", NULL, "Playback"},
  228. {"DAC left", NULL, "HSL Phase Opposite"},
  229. {"DAC right", NULL, "HSL Phase Opposite"},
  230. {"Capture", NULL, "ADC left"},
  231. {"Capture", NULL, "ADC right"},
  232. {"ADC left", NULL, "codecclk"},
  233. {"ADC right", NULL, "codecclk"},
  234. {"ADC left", NULL, "Left PGA mixer"},
  235. {"ADC right", NULL, "Right PGA mixer"},
  236. {"Left PGA mixer", "Line Left Switch", "LINEIN2"},
  237. {"Right PGA mixer", "Line Right Switch", "LINEIN1"},
  238. {"Left PGA mixer", "Mic Left Switch", "MICIN2"},
  239. {"Right PGA mixer", "Mic Right Switch", "Mic input mode mux"},
  240. {"Mic input mode mux", "Single-ended", "MICIN1"},
  241. {"Mic input mode mux", "Differential", "MICIN1"},
  242. };
  243. static void sirf_audio_codec_tx_enable(struct sirf_audio_codec *sirf_audio_codec)
  244. {
  245. regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP,
  246. AUDIO_FIFO_RESET, AUDIO_FIFO_RESET);
  247. regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP,
  248. AUDIO_FIFO_RESET, ~AUDIO_FIFO_RESET);
  249. regmap_write(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_INT_MSK, 0);
  250. regmap_write(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP, 0);
  251. regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP,
  252. AUDIO_FIFO_START, AUDIO_FIFO_START);
  253. regmap_update_bits(sirf_audio_codec->regmap,
  254. AUDIO_PORT_IC_CODEC_TX_CTRL, IC_TX_ENABLE, IC_TX_ENABLE);
  255. }
  256. static void sirf_audio_codec_tx_disable(struct sirf_audio_codec *sirf_audio_codec)
  257. {
  258. regmap_write(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP, 0);
  259. regmap_update_bits(sirf_audio_codec->regmap,
  260. AUDIO_PORT_IC_CODEC_TX_CTRL, IC_TX_ENABLE, ~IC_TX_ENABLE);
  261. }
  262. static void sirf_audio_codec_rx_enable(struct sirf_audio_codec *sirf_audio_codec,
  263. int channels)
  264. {
  265. regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_RXFIFO_OP,
  266. AUDIO_FIFO_RESET, AUDIO_FIFO_RESET);
  267. regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_RXFIFO_OP,
  268. AUDIO_FIFO_RESET, ~AUDIO_FIFO_RESET);
  269. regmap_write(sirf_audio_codec->regmap,
  270. AUDIO_PORT_IC_RXFIFO_INT_MSK, 0);
  271. regmap_write(sirf_audio_codec->regmap, AUDIO_PORT_IC_RXFIFO_OP, 0);
  272. regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_RXFIFO_OP,
  273. AUDIO_FIFO_START, AUDIO_FIFO_START);
  274. if (channels == 1)
  275. regmap_update_bits(sirf_audio_codec->regmap,
  276. AUDIO_PORT_IC_CODEC_RX_CTRL,
  277. IC_RX_ENABLE_MONO, IC_RX_ENABLE_MONO);
  278. else
  279. regmap_update_bits(sirf_audio_codec->regmap,
  280. AUDIO_PORT_IC_CODEC_RX_CTRL,
  281. IC_RX_ENABLE_STEREO, IC_RX_ENABLE_STEREO);
  282. }
  283. static void sirf_audio_codec_rx_disable(struct sirf_audio_codec *sirf_audio_codec)
  284. {
  285. regmap_update_bits(sirf_audio_codec->regmap,
  286. AUDIO_PORT_IC_CODEC_RX_CTRL,
  287. IC_RX_ENABLE_STEREO, ~IC_RX_ENABLE_STEREO);
  288. }
  289. static int sirf_audio_codec_trigger(struct snd_pcm_substream *substream,
  290. int cmd,
  291. struct snd_soc_dai *dai)
  292. {
  293. struct snd_soc_codec *codec = dai->codec;
  294. struct sirf_audio_codec *sirf_audio_codec = snd_soc_codec_get_drvdata(codec);
  295. int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
  296. /*
  297. * This is a workaround, When stop playback,
  298. * need disable HP amp, avoid the current noise.
  299. */
  300. switch (cmd) {
  301. case SNDRV_PCM_TRIGGER_STOP:
  302. case SNDRV_PCM_TRIGGER_SUSPEND:
  303. case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
  304. if (playback) {
  305. snd_soc_update_bits(codec, AUDIO_IC_CODEC_CTRL0,
  306. IC_HSLEN | IC_HSREN, 0);
  307. sirf_audio_codec_tx_disable(sirf_audio_codec);
  308. } else
  309. sirf_audio_codec_rx_disable(sirf_audio_codec);
  310. break;
  311. case SNDRV_PCM_TRIGGER_START:
  312. case SNDRV_PCM_TRIGGER_RESUME:
  313. case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
  314. if (playback) {
  315. sirf_audio_codec_tx_enable(sirf_audio_codec);
  316. snd_soc_update_bits(codec, AUDIO_IC_CODEC_CTRL0,
  317. IC_HSLEN | IC_HSREN, IC_HSLEN | IC_HSREN);
  318. } else
  319. sirf_audio_codec_rx_enable(sirf_audio_codec,
  320. substream->runtime->channels);
  321. break;
  322. default:
  323. return -EINVAL;
  324. }
  325. return 0;
  326. }
  327. struct snd_soc_dai_ops sirf_audio_codec_dai_ops = {
  328. .trigger = sirf_audio_codec_trigger,
  329. };
  330. struct snd_soc_dai_driver sirf_audio_codec_dai = {
  331. .name = "sirf-audio-codec",
  332. .playback = {
  333. .stream_name = "Playback",
  334. .channels_min = 2,
  335. .channels_max = 2,
  336. .rates = SNDRV_PCM_RATE_48000,
  337. .formats = SNDRV_PCM_FMTBIT_S16_LE,
  338. },
  339. .capture = {
  340. .stream_name = "Capture",
  341. .channels_min = 1,
  342. .channels_max = 2,
  343. .rates = SNDRV_PCM_RATE_48000,
  344. .formats = SNDRV_PCM_FMTBIT_S16_LE,
  345. },
  346. .ops = &sirf_audio_codec_dai_ops,
  347. };
  348. static int sirf_audio_codec_probe(struct snd_soc_codec *codec)
  349. {
  350. struct snd_soc_dapm_context *dapm = &codec->dapm;
  351. pm_runtime_enable(codec->dev);
  352. if (of_device_is_compatible(codec->dev->of_node, "sirf,prima2-audio-codec")) {
  353. snd_soc_dapm_new_controls(dapm,
  354. prima2_output_driver_dapm_widgets,
  355. ARRAY_SIZE(prima2_output_driver_dapm_widgets));
  356. snd_soc_dapm_new_controls(dapm,
  357. &prima2_codec_clock_dapm_widget, 1);
  358. return snd_soc_add_codec_controls(codec,
  359. volume_controls_prima2,
  360. ARRAY_SIZE(volume_controls_prima2));
  361. }
  362. if (of_device_is_compatible(codec->dev->of_node, "sirf,atlas6-audio-codec")) {
  363. snd_soc_dapm_new_controls(dapm,
  364. atlas6_output_driver_dapm_widgets,
  365. ARRAY_SIZE(atlas6_output_driver_dapm_widgets));
  366. snd_soc_dapm_new_controls(dapm,
  367. &atlas6_codec_clock_dapm_widget, 1);
  368. return snd_soc_add_codec_controls(codec,
  369. volume_controls_atlas6,
  370. ARRAY_SIZE(volume_controls_atlas6));
  371. }
  372. return -EINVAL;
  373. }
  374. static int sirf_audio_codec_remove(struct snd_soc_codec *codec)
  375. {
  376. pm_runtime_disable(codec->dev);
  377. return 0;
  378. }
  379. static struct snd_soc_codec_driver soc_codec_device_sirf_audio_codec = {
  380. .probe = sirf_audio_codec_probe,
  381. .remove = sirf_audio_codec_remove,
  382. .dapm_widgets = sirf_audio_codec_dapm_widgets,
  383. .num_dapm_widgets = ARRAY_SIZE(sirf_audio_codec_dapm_widgets),
  384. .dapm_routes = sirf_audio_codec_map,
  385. .num_dapm_routes = ARRAY_SIZE(sirf_audio_codec_map),
  386. .idle_bias_off = true,
  387. };
  388. static const struct of_device_id sirf_audio_codec_of_match[] = {
  389. { .compatible = "sirf,prima2-audio-codec" },
  390. { .compatible = "sirf,atlas6-audio-codec" },
  391. {}
  392. };
  393. MODULE_DEVICE_TABLE(of, sirf_audio_codec_of_match);
  394. static const struct regmap_config sirf_audio_codec_regmap_config = {
  395. .reg_bits = 32,
  396. .reg_stride = 4,
  397. .val_bits = 32,
  398. .max_register = AUDIO_PORT_IC_RXFIFO_INT_MSK,
  399. .cache_type = REGCACHE_NONE,
  400. };
  401. static int sirf_audio_codec_driver_probe(struct platform_device *pdev)
  402. {
  403. int ret;
  404. struct sirf_audio_codec *sirf_audio_codec;
  405. void __iomem *base;
  406. struct resource *mem_res;
  407. const struct of_device_id *match;
  408. match = of_match_node(sirf_audio_codec_of_match, pdev->dev.of_node);
  409. sirf_audio_codec = devm_kzalloc(&pdev->dev,
  410. sizeof(struct sirf_audio_codec), GFP_KERNEL);
  411. if (!sirf_audio_codec)
  412. return -ENOMEM;
  413. platform_set_drvdata(pdev, sirf_audio_codec);
  414. mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  415. base = devm_ioremap_resource(&pdev->dev, mem_res);
  416. if (IS_ERR(base))
  417. return PTR_ERR(base);
  418. sirf_audio_codec->regmap = devm_regmap_init_mmio(&pdev->dev, base,
  419. &sirf_audio_codec_regmap_config);
  420. if (IS_ERR(sirf_audio_codec->regmap))
  421. return PTR_ERR(sirf_audio_codec->regmap);
  422. sirf_audio_codec->clk = devm_clk_get(&pdev->dev, NULL);
  423. if (IS_ERR(sirf_audio_codec->clk)) {
  424. dev_err(&pdev->dev, "Get clock failed.\n");
  425. return PTR_ERR(sirf_audio_codec->clk);
  426. }
  427. ret = clk_prepare_enable(sirf_audio_codec->clk);
  428. if (ret) {
  429. dev_err(&pdev->dev, "Enable clock failed.\n");
  430. return ret;
  431. }
  432. ret = snd_soc_register_codec(&(pdev->dev),
  433. &soc_codec_device_sirf_audio_codec,
  434. &sirf_audio_codec_dai, 1);
  435. if (ret) {
  436. dev_err(&pdev->dev, "Register Audio Codec dai failed.\n");
  437. goto err_clk_put;
  438. }
  439. /*
  440. * Always open charge pump, if not, when the charge pump closed the
  441. * adc will not stable
  442. */
  443. regmap_update_bits(sirf_audio_codec->regmap, AUDIO_IC_CODEC_CTRL0,
  444. IC_CPFREQ, IC_CPFREQ);
  445. if (of_device_is_compatible(pdev->dev.of_node, "sirf,atlas6-audio-codec"))
  446. regmap_update_bits(sirf_audio_codec->regmap,
  447. AUDIO_IC_CODEC_CTRL0, IC_CPEN, IC_CPEN);
  448. return 0;
  449. err_clk_put:
  450. clk_disable_unprepare(sirf_audio_codec->clk);
  451. return ret;
  452. }
  453. static int sirf_audio_codec_driver_remove(struct platform_device *pdev)
  454. {
  455. struct sirf_audio_codec *sirf_audio_codec = platform_get_drvdata(pdev);
  456. clk_disable_unprepare(sirf_audio_codec->clk);
  457. snd_soc_unregister_codec(&(pdev->dev));
  458. return 0;
  459. }
  460. #ifdef CONFIG_PM_SLEEP
  461. static int sirf_audio_codec_suspend(struct device *dev)
  462. {
  463. struct sirf_audio_codec *sirf_audio_codec = dev_get_drvdata(dev);
  464. regmap_read(sirf_audio_codec->regmap, AUDIO_IC_CODEC_CTRL0,
  465. &sirf_audio_codec->reg_ctrl0);
  466. regmap_read(sirf_audio_codec->regmap, AUDIO_IC_CODEC_CTRL1,
  467. &sirf_audio_codec->reg_ctrl1);
  468. clk_disable_unprepare(sirf_audio_codec->clk);
  469. return 0;
  470. }
  471. static int sirf_audio_codec_resume(struct device *dev)
  472. {
  473. struct sirf_audio_codec *sirf_audio_codec = dev_get_drvdata(dev);
  474. int ret;
  475. ret = clk_prepare_enable(sirf_audio_codec->clk);
  476. if (ret)
  477. return ret;
  478. regmap_write(sirf_audio_codec->regmap, AUDIO_IC_CODEC_CTRL0,
  479. sirf_audio_codec->reg_ctrl0);
  480. regmap_write(sirf_audio_codec->regmap, AUDIO_IC_CODEC_CTRL1,
  481. sirf_audio_codec->reg_ctrl1);
  482. return 0;
  483. }
  484. #endif
  485. static const struct dev_pm_ops sirf_audio_codec_pm_ops = {
  486. SET_SYSTEM_SLEEP_PM_OPS(sirf_audio_codec_suspend, sirf_audio_codec_resume)
  487. };
  488. static struct platform_driver sirf_audio_codec_driver = {
  489. .driver = {
  490. .name = "sirf-audio-codec",
  491. .owner = THIS_MODULE,
  492. .of_match_table = sirf_audio_codec_of_match,
  493. .pm = &sirf_audio_codec_pm_ops,
  494. },
  495. .probe = sirf_audio_codec_driver_probe,
  496. .remove = sirf_audio_codec_driver_remove,
  497. };
  498. module_platform_driver(sirf_audio_codec_driver);
  499. MODULE_DESCRIPTION("SiRF audio codec driver");
  500. MODULE_AUTHOR("RongJun Ying <Rongjun.Ying@csr.com>");
  501. MODULE_LICENSE("GPL v2");