sirf-audio-codec.c 19 KB

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